tango-9.2.5a/0000755023471100065110000000000013034745262010014 500000000000000tango-9.2.5a/config/0000755023471100065110000000000013034745255011263 500000000000000tango-9.2.5a/config/config.guess0000755023471100065110000012753413034744704013535 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-01-23' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tango-9.2.5a/config/config.sub0000755023471100065110000010115313034744704013165 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-01-16' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tango-9.2.5a/config/depcomp0000755023471100065110000003554513034744704012572 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2004-05-31.23 # Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit 0 ;; -v | --v*) echo "depcomp $scriptversion" exit 0 ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # Dependencies are output in .lo.d with libtool 1.4. # With libtool 1.5 they are output both in $dir.libs/$base.o.d # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the # latter, because the former will be cleaned when $dir.libs is # erased. tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir$base.o.d" tmpdepfile3="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" tmpdepfile3="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" elif test -f "$tmpdepfile2"; then tmpdepfile="$tmpdepfile2" else tmpdepfile="$tmpdepfile3" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/config/install-sh0000755023471100065110000002176613034744704013221 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2004-09-10.20 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/config/ltmain.sh0000644023471100065110000105202613034745117013026 00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1.1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 tango-9.2.5a/config/missing0000755023471100065110000002453313034744704012607 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2004-09-07.08 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit 0 ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit 0 ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/m4/0000755023471100065110000000000013034745255010336 500000000000000tango-9.2.5a/m4/RSSH_CHECK_OMNIORB.m40000644023471100065110000002032613034744702013360 00000000000000dnl@synposis RSSH_CHECK_CORBA_ORB dnl dnl set CORBA support for omniORB v3-pr2 or highter dnl ( http://www.uk.research.att.com/omniORB/omniORB.html) dnl dnl@author (C) Ruslan Shevchenko , 1999, 2000 dnl@id $Id: RSSH_CHECK_OMNIORB.m4,v 1.20 2002/01/16 16:33:28 yad Exp $ dnl AC_DEFUN([RSSH_CHECK_OMNIORB],[ AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([AC_PROG_CPP]) AC_REQUIRE([AC_PROG_CXXCPP]) AC_ARG_WITH(omni, AC_HELP_STRING([--with-omni],[prefix to omniORB installation (default: $OMNI_ROOT)]) ,\ OMNI_PREFIX=${with_omni} , OMNI_PREFIX=/usr/local ) if test "x$OMNI_ROOT" = "x" then if test "x$OMNI_PREFIX" = "x" then OMNI_ROOT="/usr/local" else OMNI_ROOT="$OMNI_PREFIX" fi fi if test "x$OMNI_PREFIX" = "xno" then dnl OMNI NOT SET AC_MSG_RESULT(omniORB is disabled) omni=no else AC_LANG_SAVE AC_LANG_CPLUSPLUS svCXXCPPFLAGS=$CXXCPPFLAGS svCXXFLAGS=$CXXFLAGS svCPPFLAGS=$CPPFLAGS svLIBS=$LIBS svLDFLAGS=$LDFLAGS svRSSH_ROLLBACK=$rssh_rollback rssh_rollback="true" ORB_INCLUDES="-I$OMNI_ROOT/include" CXXCPPFLAGS="$CXXCPPFLAGS -I$OMNI_ROOT/include " CPPFLAGS="$CPPFLAGS -I$OMNI_ROOT/include " RSSH_ENABLE_PTHREADS case $build_cpu in sparc*) AC_DEFINE(__sparc__,1,Needed by omniorb) IDLCXXFLAGS="$IDLCXXFLAGS -D__sparc__" ;; "i686"|"i586"|"i486"|"i386") AC_DEFINE(__x86__,1,Needed by omniorb") IDLCXXFLAGS="$IDLCXXFLAGS -D__x86__" ;; esac SL_SUFFIX=so case $build_os in darwin*) AC_DEFINE(__darwin__,1,If we're running on darwin/MacOsX) IDLCXXFLAGS="$IDLCXXFLAGS -D__darwin__" SL_SUFFIX=dylib ;; solaris*) AC_DEFINE(__sunos__,1,If we're running on solaris) IDLCXXFLAGS="$IDLCXXFLAGS -D__sunos__" __OSVERSION__=5 AC_DEFINE_UNQUOTED(__OSVERSION__, $__OSVERSION__,Needed by omniorb) IDLCXXFLAGS="$IDLCXXFLAGS -D__OSVERSION__=5" ;; freebsd*) AC_DEFINE(__freebsd__,1,If we're running on freebsd) IDLCXXFLAGS="$IDLCXXFLAGS -D__freebsd__" ;; hpux*) AC_DEFINE(__hpux__,1,If we're running on hpux) IDLCXXFLAGS="$IDLCXXFLAGS -AA -mt -D__hpux__ -D__hppa__ -D__OMNIORB4__" __OSVERSION__=11 AC_DEFINE_UNQUOTED(__OSVERSION__, $__OSVERSION__,Needed by omniorb) IDLCXXFLAGS="$IDLCXXFLAGS -D__OSVERSION__=11" SL_SUFFIX=sl ;; esac AC_SUBST(IDLCXXFLAGS) CXXCPPFLAGS="$CXXCPPFLAGS $IDLCXXFLAGS" AC_CHECK_HEADER( omniORB4/CORBA.h, omni=yes , omni=no, ) if test "x$omni" = "xyes" then ORB_LIBDIR="$OMNI_ROOT/lib" if test ! -r "$ORB_LIBDIR/libomniORB4.$SL_SUFFIX" then for i in $OMNI_ROOT/lib/*/lib*.$SL_SUFFIX do ORB_LIBDIR=`dirname $i` break; done fi LIBS="$LIBS -lomnithread" svLIBS=$LIBS LIBS="-L$ORB_LIBDIR $LIBS" AC_CACHE_CHECK([for omnithreads], rssh_cv_check_omnithreads, rssh_enable_pthreads_done="" RSSH_ENABLE_PTHREADS AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_LINK( #include ,omni_mutex my_mutex, rssh_cv_check_omnithreads=yes,rssh_cv_check_omnithreads=no) AC_LANG_RESTORE ) if test ! $rssh_cv_check_omnithreads = yes then AC_MSG_RESULT("omnithreads not found") omni_lib=no fi AC_CHECK_LIB(socket,socket, LIBS="-lsocket $LIBS",,) AC_CHECK_LIB(nsl,gethostbyname, LIBS="-lnsl $LIBS",,) ORB_LDFLAGS="-L$ORB_LIBDIR" LIBS="$ORB_LDFLAGS -lomniORB4 -lomniDynamic4 -lCOS4 $svLIBS $LIBS" AC_CACHE_CHECK([whether we can link with omniORB4], rssh_cv_check_omniORBlib, AC_TRY_LINK( #include ,CORBA::ORB_var orb, rssh_cv_check_omniORBlib=yes,rssh_cv_check_omniORBlib=no ) ) if test ! $rssh_cv_check_omniORBlib = yes then AC_MSG_RESULT("omniORB libs not found") omni_lib=no fi ORB_LIBS="$ORB_LDFLAGS -lomniORB4 -lomnithread" fi if test "x$omni_lib" = "xno" then AC_MSG_RESULT(omniORB library linking failed) omni="no" fi fi dnl omniorb_AC_HAVE_OMNIORB_VERSION($OMNI_ROOT/include/omniORB4,4,1,0) dnl if test "x$ac_cv_omniorb_version_4_1_0" = "xno"; then dnl AC_MSG_ERROR([Not supported omniORB release. Should be 4.1.0 or above. Please update !],-1) dnl fi dnl dnl The following tests are only to reject omniORB release 4.1.1 dnl which has some annoying bugs fixed in omniORB 4.1.2 dnl export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$OMNI_ROOT/lib/pkgconfig PKG_CHECK_MODULES([omniORB4], [omniORB4 >= 4.1.2]) PKG_CHECK_MODULES([omniCOS4], [omniCOS4 >= 4.1.2]) dnl omniorb_AC_HAVE_OMNIORB_VERSION($OMNI_ROOT/include/omniORB4,4,1,1) dnl omniorb_AC_HAVE_OMNIORB_VERSION($OMNI_ROOT/include/omniORB4,4,1,2) dnl if test "x$ac_cv_omniorb_version_4_1_1" = "xyes"; then dnl if test "x$ac_cv_omniorb_version_4_1_2" = "xno"; then dnl AC_MSG_ERROR([omniORB release 4.1.1 is not supported. Should be 4.1.0 or 4.1.2 and above. Please update !],-1) dnl fi dnl fi if test -x $OMNI_ROOT/include/omniORB4 then VERS=`grep VERSION $OMNI_ROOT/include/omniORB4/acconfig.h 2>&1 | cut -d ' ' -f 3` OMNI_VERSION=$VERS fi if test "x$omni" = "x" -o "x$omni" = "xno" then CXXCPPFLAGS=$svCXXCPPFLAGS CPPFLAGS=$svCPPFLAGS LIBS=$svLIBS LDFLAGS=$svLDFLAGS ORB=unknown omni=no eval "$rssh_rollback" rssh_rollback=$svRSSH_ROLLBACK else AC_SUBST(CORBA_INCLUDES) ORB_PREFIX=$OMNI_ROOT AC_SUBST(ORB_PREFIX) ORB=omniORB AC_SUBST(ORB) IDL=omniidl if test -x $OMNI_ROOT/bin/omniidl then IDL=$OMNI_ROOT/bin/omniidl else for i in $OMNI_ROOT/bin/*/omniidl do if test "$i" != $OMNI_ROOT'/bin/*/omniidl' then IDL=$i break fi done fi AC_SUBST(IDL) IDLCXX=$IDL AC_SUBST(IDLCXX) IDLFLAGS="$IDLFLAGS -bcxx -I$OMNI_ROOT/idl" AC_SUBST(IDLFLAGS) ORB_INCLUDE_PREFIX=$ORB_INCLUDES AC_SUBST(ORB_INCLUDE_PREFIX) IDL_H_SUFFIX=.hh AC_SUBST(IDL_H_SUFFIX) IDL_H1_SUFFIX=no AC_SUBST(IDL_H1_SUFFIX) IDL_CLN_H=.hh IDL_CLN_H_SUFFIX=.hh IDL_CLN_H1_SUFFIX=no AC_SUBST(IDL_CLN_H,$IDL_CLN_H) AC_SUBST(IDL_CLN_H_SUFFIX,$IDL_CLN_H_SUFFIX) AC_SUBST(IDL_CLN_H1_SUFFIX,$IDL_CLN_H1_SUFFIX) AC_DEFINE_UNQUOTED(IDL_CLN_H_SUFFIX,$IDL_CLN_H_SUFFIX,1,"") IDL_CLN_CPP=SK.cc IDL_CLN_CPP_SUFFIX=SK.cc AC_SUBST(IDL_CLN_CPP,$IDL_CLN_CPP) AC_SUBST(IDL_CLN_CPP_SUFFIX,$IDL_CLN_CPP_SUFFIX) AC_DEFINE_UNQUOTED(IDL_CLN_CPP_SUFFIX,$IDL_CLN_CPP,1,"") IDL_CLN_O=SK.o IDL_CLN_OBJ_SUFFIX=SK.o AC_SUBST(IDL_CLN_O,$IDL_CLN_O) AC_SUBST(IDL_CLN_OBJ_SUFFIX,$IDL_CLN_OBJ_SUFFIX) IDL_SRV_H=.hh IDL_SRV_H_SUFFIX=.hh IDL_SRV_H1_SUFFIX=no AC_SUBST(IDL_SRV_H,$IDL_SRV_H) AC_SUBST(IDL_SRV_H_SUFFIX,$IDL_SRV_H_SUFFIX) AC_SUBST(IDL_SRV_H1_SUFFIX,$IDL_SRV_H1_SUFFIX) AC_DEFINE_UNQUOTED(IDL_SRV_H_SUFFIX,$IDL_SRV_H_SUFFIX,1,"") IDL_SRV_CPP=SK.cc IDL_SRV_CPP_SUFFIX=SK.cc AC_SUBST(IDL_SRV_CPP,$IDL_SRV_CPP) AC_SUBST(IDL_SRV_CPP_SUFFIX,$IDL_SRV_CPP_SUFFIX) AC_DEFINE_UNQUOTED(IDL_SRV_H_SUFFIX,$IDL_SRV_H_SUFFIX,1,"") IDL_SRV_O=SK.o IDL_SRV_OBJ_SUFFIX=SK.o AC_SUBST(IDL_SRV_O,$IDL_SRV_O) AC_SUBST(IDL_SRV_OBJ_SUFFIX,$IDL_SRV_OBJ_SUFFIX) IDL_TIE_H_SUFFIX=no IDL_TIE_H1_SUFFIX=no IDL_TIE_CPP_SUFFIX=no AC_SUBST(IDL_TIE_H_SUFFIX,$IDL_TIE_H_SUFFIX) AC_SUBST(IDL_TIE_H1_SUFFIX,$IDL_TIE_H1_SUFFIX) AC_SUBST(IDL_TIE_CPP_SUFFIX,$IDL_TIE_CPP_SUFFIX) CORBA_H='omniORB4/CORBA.h' AC_DEFINE_UNQUOTED(CORBA_H,<$CORBA_H>, "") COSNAMING_H='omniORB4/Naming.hh' AC_DEFINE_UNQUOTED(COSNAMING_H,<$COSNAMING_H>, "") ORB_COSNAMING_LIB= AC_SUBST(ORB_COSNAMING_LIB) dnl i. e. it's build into ORB lib HAVE_ORB_IDL=1 AC_SUBST(HAVE_ORB_IDL) AC_CACHE_CHECK([whether CORBA modules mapped to namespaces], rssh_cv_corba_namespaces, AC_TRY_COMPILE(#include <$CORBA_H> , [ #ifndef HAS_Cplusplus_Namespace #error "we have no namespaces" we have no namespaces -- $$$$ #else return 0; #endif ], rssh_cv_corba_namespaces=yes, rssh_cv_corba_namespaces=no) ) if test "$rssh_cv_corba_namespaces" = "yes" then AC_DEFINE(CORBA_MODULE_NAMESPACE_MAPPING,1, "") else AC_DEFINE(CORBA_MODULE_CLASS_MAPPING,1,"") fi AC_DEFINE(OMNIORB,1,"if we're working with omniorb") CORBA_HAVE_POA=1 AC_DEFINE(CORBA_HAVE_POA,1, "if our orb has a poa") CORBA_ORB_INIT_HAVE_3_ARGS=1 AC_DEFINE(CORBA_ORB_INIT_HAVE_3_ARGS,1,"if our orb-init has 3 args") CORBA_ORB_INIT_THIRD_ARG='"omniORB4"' AC_DEFINE(CORBA_ORB_INIT_THIRD_ARG, "omniORB4", "what the third argument is") AC_DEFINE(CORBA_ORB_HAVE_DESTROY,1,"") fi AC_LANG_RESTORE ])dnl dnl tango-9.2.5a/m4/RSSH_CHECK_PTHREADS.m40000644023471100065110000000212313034744702013460 00000000000000#@synonpsis RSSH_CHECK_PTHREADS # check for pthreads system interfaces. # set CFLAGS_PTHREADS, CXXFLAGS_PTHREADS and LIBS_PTHREADS to # flags to compiler option, which denote multithread program compilation # (if one exists), # and multithread library, if one required. # #@author (C) Ruslan Shevchenko , 1998 #@id $Id: RSSH_CHECK_PTHREADS.m4,v 1.6 2001/05/07 19:21:22 rssh Exp $ # AC_DEFUN([RSSH_CHECK_PTHREADS],[ dnl AC_REQUIRE([RSSH_CHECK_SUNPRO_C])dnl AC_REQUIRE([RSSH_CHECK_SUNPRO_CC])dnl AC_CHECK_HEADER(pthread.h,AC_DEFINE(HAVE_PTHREAD_H,1,If pthreads are present)) if test x$rssh_cv_check_sunpro_c = xyes then CFLAGS_PTHREADS="-mt" fi if test x$rssh_cv_check_sunpro_cc = xyes then CXXFLAGS_PTHREADS="-mt" fi case $build_os in freebsd*) CFLAGS_PTHREADS="-pthread" CXXFLAGS_PTHREADS="-pthread" freebsd_pthreads=yes ;; *) freebsd_pthreads=no ;; esac if test x$freebsd_pthreads = xno then AC_CHECK_LIB(pthread,pthread_create, LIBS_PTHREADS="-lpthread") fi AC_CHECK_LIB(posix4,nanosleep, LIBS_PTHREADS="$LIBS_PTHREADS -lposix4") ])dnl tango-9.2.5a/m4/RSSH_CHECK_SUNPRO_CC.m40000644023471100065110000000162413034744702013646 00000000000000# RSSH_CHECK_SUNPROC_CC([ACTION-IF-YES], [ACTION-IF-NOT]) # ------------------------------------------------------ # check : are we using SUN workshop C++ compiler. # Corresponding cache value: rssh_cv_check_sunpro_cc is set to yes or no # #@author Ruslan Shevchenko , 1998, 2000 #@version $Id: RSSH_CHECK_SUNPRO_CC.m4,v 1.3 2000/07/12 08:06:52 rssh Exp $ # # RSSH_CHECK_SUNPRO_CC([ACTION-IF-YES],[ACTION-IF-NOT]) # AC_DEFUN([RSSH_CHECK_SUNPRO_CC], [AC_CACHE_CHECK([whether using Sun Worckshop C++ compiler], [rssh_cv_check_sunpro_cc], [AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([], [#ifndef __SUNPRO_CC # include "error: this is not Sun Workshop." #endif ], rssh_cv_check_sunpro_cc=yes, rssh_cv_check_sunpro_cc=no) AC_LANG_RESTORE]) if test ${rssh_cv_check_sunpro_cc} = yes then $2 : else $3 : fi ])# RSSH_CHECK_SUNPROC_CC tango-9.2.5a/m4/RSSH_ENABLE_PTHREADS.m40000644023471100065110000000112413034744702013571 00000000000000dnl@synopsis RSSH_ENABLE_PTHREADS dnl dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. dnl dnl@author (C) Ruslan Shevchenko , 1998, 2000 dnl@id $Id: RSSH_ENABLE_PTHREADS.m4,v 1.7 2001/03/28 12:20:12 rssh Exp $ dnl dnl AC_DEFUN([RSSH_ENABLE_PTHREADS],[ AC_REQUIRE([RSSH_CHECK_PTHREADS]) if test -z "$rssh_enable_pthreads_done" then CFLAGS="$CFLAGS $CFLAGS_PTHREADS" CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" LIBS="$LIBS $LIBS_PTHREADS" fi rssh_enable_pthreads_done=yes rssh_rollback="$rssh_rollback; rssh_enable_pthreads_done=" ])dnl dnl tango-9.2.5a/m4/ac_cxx_have_class_strstream.m40000644023471100065110000000150413034744702016255 00000000000000dnl @synopsis AC_CXX_HAVE_CLASS STRSTREAM dnl If the C++ library has a working s strstream, dnl define HAVE_CLASS_STRSTREAM dnl @author Unknown dnl @version $Id$ AC_DEFUN([AC_CXX_HAVE_CLASS_STRSTREAM], [AC_CACHE_CHECK(whether the library defines class strstream, ac_cv_cxx_have_class_strstream, [AC_REQUIRE([AC_CXX_NAMESPACES]) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([ #if HAVE_STRSTREAM # include #else # include #endif #ifdef HAVE_NAMESPACES using namespace std; #endif],[ostrstream message; message << "Hello"; return 0;], ac_cv_cxx_have_class_strstream=yes, ac_cv_cxx_have_class_strstream=no) AC_LANG_RESTORE ]) if test "$ac_cv_cxx_have_class_strstream" = yes; then AC_DEFINE(HAVE_CLASS_STRSTREAM,1,[define if the library defines strstream]) fi ])tango-9.2.5a/m4/ac_cxx_have_sstream.m40000644023471100065110000000134313034744702014523 00000000000000dnl @synopsis AC_CXX_HAVE_SSTREAM dnl dnl If the C++ library has a working stringstream, define HAVE_SSTREAM. dnl dnl @author Ben Stanley dnl @version $Id: ac_cxx_have_sstream.m4,v 1.1 2001/03/16 13:47:06 simons Exp $ dnl AC_DEFUN([AC_CXX_HAVE_SSTREAM], [AC_CACHE_CHECK(whether the compiler has stringstream, ac_cv_cxx_have_sstream, [AC_REQUIRE([AC_CXX_NAMESPACES]) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([#include #ifdef HAVE_NAMESPACES using namespace std; #endif],[stringstream message; message << "Hello"; return 0;], ac_cv_cxx_have_sstream=yes, ac_cv_cxx_have_sstream=no) AC_LANG_RESTORE ]) if test "$ac_cv_cxx_have_sstream" = yes; then AC_DEFINE(HAVE_SSTREAM,,[define if the compiler has stringstream]) fi ]) tango-9.2.5a/m4/ac_cxx_namespaces.m40000644023471100065110000000113413034744702014157 00000000000000dnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_namespaces.html dnl AC_DEFUN([AC_CXX_NAMESPACES], [AC_CACHE_CHECK(whether the compiler implements namespaces, ac_cv_cxx_namespaces, [AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}], [using namespace Outer::Inner; return i;], ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no) AC_LANG_RESTORE ]) if test "$ac_cv_cxx_namespaces" = yes; then AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces]) fi ]) tango-9.2.5a/m4/ac_path_mariadb.m40000644023471100065110000001147213034744702013577 00000000000000# Markus Fischer <>, 23.9.1999 # URL : http://josefine.ben.tuwien.ac.at/~mfischer/m4/mariadb-client.m4 # Last Modified : Thu Sep 23 14:24:15 CEST 1999 # # written from scratch dnl Test for libmariadbclient and dnl define MARIADBCLIENT_CFLAGS, MARIADBCLIENT_LDFLAGS and MARIADBCLIENT_LIBS dnl usage: dnl AM_PATH_MARIADBCLIENT( dnl [MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND ]]]) dnl AC_DEFUN([AM_PATH_MARIADBCLIENT], [ AC_ARG_WITH(mariadbclient-prefix, AC_HELP_STRING([--with-mariadbclient-prefix=PFX],[Prefix where mariadbclient is installed]), mariadbclient_prefix="$withval", mariadbclient_prefix="") AC_ARG_WITH(mariadbclient-include, AC_HELP_STRING([--with-mariadbclient-include=DIR],[Directory pointing to mariadbclient include files]), mariadbclient_include="$withval", mariadbclient_include="") AC_ARG_WITH(mariadbclient-lib,AC_HELP_STRING([--with-mariadbclient-lib=LIB],[Directory pointing to mariadbclient library (Note: -include and -lib do override paths found with -prefix)]), mariadbclient_lib="$withval", mariadbclient_lib="") AC_MSG_CHECKING([for mariadbclient ifelse([$1], , ,[>= v$1])]) MARIADBCLIENT_LDFLAGS="" MARIADBCLIENT_CFLAGS="" MARIADBCLIENT_LIBS="-lmariadb" mariadbclient_fail="" dnl test --with-mariadbclient-prefix for tryprefix in /usr /usr/local /usr/mysql /usr/local/mysql /usr/pkg $mariadbclient_prefix ; do for hloc in lib/mariadb lib ; do if test -f "$tryprefix/$hloc/libmariadb.so"; then MARIADBCLIENT_LDFLAGS="-L$tryprefix/$hloc" elif test -f "$tryprefix/$hloc/libmariadb.a"; then MARIADBCLIENT_LDFLAGS="-L$tryprefix/$hloc" fi done for iloc in include/mariadb include; do if test -f "$tryprefix/$iloc/mysql.h"; then MARIADBCLIENT_CFLAGS="-I$tryprefix/$iloc" fi done # testloop done dnl test --with-mariadbclient-include if test "x$mariadbclient_include" != "x" ; then echo "checking for mariadb includes... " if test -d "$mariadbclient_include/mariadb" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include" echo " found $MARIADBCLIENT_CFLAGS" elif test -d "$mariadbclient_include/include/mariadb" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include/include" echo " found $MARIADBCLIENT_CFLAGS" elif test -d "$mariadbclient_include" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include" echo "found $MARIADBCLIENT_CFLAGS" else echo "not found! no include dir found in $mariadbclient_include" fi fi dnl test --with-mariadbclient-lib if test "x$mariadbclient_lib" != "x" ; then echo "checking for mariadb libx... " if test -d "$mariadbclient_lib/lib/mariadb" ; then MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib/lib/mariadb" echo "found $MARIADBCLIENT_LDFLAGS" elif test -d "$mariadbclient_lib/lin" ; then MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib/lib" echo "found $MARIADBCLIENT_LDFLAGS" else MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib" echo "defaultd to $MARIADBCLIENT_LDFLAGS" fi fi ac_save_CFLAGS="$CFLAGS" ac_save_LDFLAGS="$LDFLAGS" ac_save_LIBS="$LIBS" CFLAGS="-v $CFLAGS $MARIADBCLIENT_CFLAGS" LDFLAGS="$LDFLAGS $MARIADBCLIENT_LDFLAGS" LIBS="$LIBS $MARIADBCLIENT_LIBS" dnl if no minimum version is given, just try to compile dnl else try to compile AND run AC_TRY_LINK([ #include #include ],[ mysql_init( 0 ); ], [AC_MSG_RESULT(yes $MARIADBCLIENT_CFLAGS $MARIADBCLIENT_LDFLAGS) CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" ifelse([$2], ,:,[$2]) ],[ echo "no" echo "can't compile a simple app with mysql_connnect in it. bad." mariadbclient_fail="yes" ]) if test "x$mariadbclient_fail" != "x" ; then dnl AC_MSG_RESULT(no) echo echo "***" echo "*** mariadbclient test source had problems, check your config.log ." echo "*** Also try one of the following switches :" echo "*** --with-mariadbclient-prefix=PFX" echo "*** --with-mariadbclient-include=DIR" echo "*** --with-mariadbclient-lib=DIR" echo "***" CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" MARIADBCLIENT_LIBS="" MARIADBCLIENT_CFLAGS="" ifelse([$3], ,:,[$3]) fi CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" AC_SUBST(MARIADBCLIENT_LDFLAGS) AC_SUBST(MARIADBCLIENT_CFLAGS) AC_SUBST(MARIADBCLIENT_LIBS) ]) tango-9.2.5a/m4/ac_path_mysqlclient.m40000644023471100065110000001123613034744702014542 00000000000000# Markus Fischer <>, 23.9.1999 # URL : http://josefine.ben.tuwien.ac.at/~mfischer/m4/mysql-client.m4 # Last Modified : Thu Sep 23 14:24:15 CEST 1999 # # written from scratch dnl Test for libmysqlclient and dnl define MYSQLCLIENT_CFLAGS, MYSQLCLIENT_LDFLAGS and MYSQLCLIENT_LIBS dnl usage: dnl AM_PATH_MYSQLCLIENT( dnl [MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND ]]]) dnl AC_DEFUN([AM_PATH_MYSQLCLIENT], [ AC_ARG_WITH(mysqlclient-prefix, AC_HELP_STRING([--with-mysqlclient-prefix=PFX],[Prefix where mysqlclient is installed]), mysqlclient_prefix="$withval", mysqlclient_prefix="") AC_ARG_WITH(mysqlclient-include, AC_HELP_STRING([--with-mysqlclient-include=DIR],[Directory pointing to mysqlclient include files]), mysqlclient_include="$withval", mysqlclient_include="") AC_ARG_WITH(mysqlclient-lib,AC_HELP_STRING([--with-mysqlclient-lib=LIB],[Directory pointing to mysqlclient library (Note: -include and -lib do override paths found with -prefix)]), mysqlclient_lib="$withval", mysqlclient_lib="") AC_MSG_CHECKING([for mysqlclient ifelse([$1], , ,[>= v$1])]) MYSQLCLIENT_LDFLAGS="" MYSQLCLIENT_CFLAGS="" MYSQLCLIENT_LIBS="-lmysqlclient" mysqlclient_fail="" dnl test --with-mysqlclient-prefix for tryprefix in /usr /usr/local /usr/mysql /usr/local/mysql /usr/pkg $mysqlclient_prefix ; do for hloc in lib/mysql lib ; do if test -f "$tryprefix/$hloc/libmysqlclient.so"; then MYSQLCLIENT_LDFLAGS="-L$tryprefix/$hloc" elif test -f "$tryprefix/$hloc/libmysqlclient.a"; then MYSQLCLIENT_LDFLAGS="-L$tryprefix/$hloc" fi done for iloc in include/mysql include; do if test -f "$tryprefix/$iloc/mysql.h"; then MYSQLCLIENT_CFLAGS="-I$tryprefix/$iloc" fi done # testloop done dnl test --with-mysqlclient-include if test "x$mysqlclient_include" != "x" ; then echo "checking for mysql includes... " if test -d "$mysqlclient_include/mysql" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include" echo " found $MYSQLCLIENT_CFLAGS" elif test -d "$mysqlclient_include/include/mysql" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include/include" echo " found $MYSQLCLIENT_CFLAGS" elif test -d "$mysqlclient_include" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include" echo "found $MYSQLCLIENT_CFLAGS" else echo "not found! no include dir found in $mysqlclient_include" fi fi dnl test --with-mysqlclient-lib if test "x$mysqlclient_lib" != "x" ; then echo "checking for mysql libx... " if test -d "$mysqlclient_lib/lib/mysql" ; then MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib/lib/mysql" echo "found $MYSQLCLIENT_LDFLAGS" elif test -d "$mysqlclient_lib/lin" ; then MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib/lib" echo "found $MYSQLCLIENT_LDFLAGS" else MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib" echo "defaultd to $MYSQLCLIENT_LDFLAGS" fi fi ac_save_CFLAGS="$CFLAGS" ac_save_LDFLAGS="$LDFLAGS" ac_save_LIBS="$LIBS" CFLAGS="-v $CFLAGS $MYSQLCLIENT_CFLAGS" LDFLAGS="$LDFLAGS $MYSQLCLIENT_LDFLAGS" LIBS="$LIBS $MYSQLCLIENT_LIBS" dnl if no minimum version is given, just try to compile dnl else try to compile AND run AC_TRY_LINK([ #include #include ],[ mysql_init( 0 ); ], [AC_MSG_RESULT(yes $MYSQLCLIENT_CFLAGS $MYSQLCLIENT_LDFLAGS) CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" ifelse([$2], ,:,[$2]) ],[ echo "no" echo "can't compile a simple app with mysql_connnect in it. bad." mysqlclient_fail="yes" ]) if test "x$mysqlclient_fail" != "x" ; then dnl AC_MSG_RESULT(no) echo echo "***" echo "*** mysqlclient test source had problems, check your config.log ." echo "*** Also try one of the following switches :" echo "*** --with-mysqlclient-prefix=PFX" echo "*** --with-mysqlclient-include=DIR" echo "*** --with-mysqlclient-lib=DIR" echo "***" CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" MYSQLCLIENT_LIBS="" MYSQLCLIENT_CFLAGS="" ifelse([$3], ,:,[$3]) fi CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" AC_SUBST(MYSQLCLIENT_LDFLAGS) AC_SUBST(MYSQLCLIENT_CFLAGS) AC_SUBST(MYSQLCLIENT_LIBS) ]) tango-9.2.5a/m4/ac_prog_mysql.m40000644023471100065110000000476113034744702013363 00000000000000dnl @synopsis AC_PROG_MYSQL dnl dnl Check for the program 'mysql' dnl let script continue if exists & works dnl pops up error message if not. dnl dnl Testing of functionality is by invoking it with root password '' dnl and a 'SELECT * FROM user' SQL statement. dnl The user and passwd can be controlled with the --with-mysql-admin and dnl the --with-mysql-admin-passwd dnl We can also control the host with the --with-mysql-host switch. dnl That SQL statement will select all user information from the 'user' dnl privileges table, dnl and should work on every proper MySQL server. dnl dnl Besides checking mysql, this macro also set these environmentb dnl variables upon completion: dnl dnl MYSQL = which mysql dnl dnl @version $Id: ac_prog_mysql.m4,v 1.2 2002/04/11 14:20:17 simons Exp $ dnl @author Gleen Salmon dnl AC_DEFUN([AC_PROG_MYSQL],[ AC_REQUIRE([AC_EXEEXT])dnl AC_PATH_PROG(MYSQL, mysql$EXEEXT, nocommand) if test "$MYSQL" = nocommand; then AC_MSG_WARN([mysql not found in $PATH]) enable_db_schema_create=no else AC_ARG_WITH(mysql-ho, AC_HELP_STRING([--with-mysql-ho],[the host of the mysql database (default: )]), MYSQL_HOST=${with_mysql_ho}, MYSQL_HOST="") AC_ARG_WITH(mysql-admin,AC_HELP_STRING([--with-mysql-admin],[super user of your mysql database (default: )]), MYSQL_ADMIN=${with_mysql_admin}, MYSQL_ADMIN="") AC_ARG_WITH(mysql-admin-passwd, AC_HELP_STRING([--with-mysql-admin-passwd],[super user password of your mysql database (default: )]), MYSQL_ADMIN_PASSWD=${with_mysql_admin_passwd}, MYSQL_ADMIN_PASSWD="") if test "x$MYSQL_ADMIN" = "x"; then user_switch=""; else user_switch="-u$MYSQL_ADMIN"; fi if test "x$MYSQL_ADMIN_PASSWD" = "x"; then passwd_switch=""; else passwd_switch="-p$MYSQL_ADMIN_PASSWD"; fi if test "x$MYSQL_HOST" = "x"; then host_switch=""; else host_switch="-h$MYSQL_HOST"; fi AC_MSG_CHECKING([if mysql works]) if echo 'SELECT * FROM user' | $MYSQL $user_switch $passwd_switch $host_switch mysql> /dev/null; then AC_MSG_RESULT([yes]) AC_SUBST(MYSQL_ADMIN) AC_SUBST(MYSQL_ADMIN_PASSWD) AC_SUBST(MYSQL) AC_SUBST(MYSQL_HOST) MYSQL_CONNECTION=OK else AC_MSG_WARN([mysql cannot execute SELECT with user=$MYSQL_ADMIN, passwd=$MYSQL_ADMIN_PASSWD, and host=$MYSQL_HOST. Please check your my.cnf file or configure options!]) MYSQL_CONNECTION=failed enable_db_schema_create=no fi;dnl AC_DEFINE_UNQUOTED(MYSQL_HOST,"$MYSQL_HOST", "the host running mysql") fi ]) tango-9.2.5a/m4/ax_cxx_compile_stdcxx_11.m40000644023471100065110000001104513034744702015415 00000000000000# ============================================================================ # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html # ============================================================================ # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXXFLAGS to enable support. # # The first argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The second argument, if specified 'mandatory' or if left unspecified, # indicates that baseline C++11 support is required and that the macro # should error out if no mode with that support is found. If specified # 'optional', then configuration proceeds regardless, after defining # HAVE_CXX11 if and only if a supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 3 m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; ]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl m4_if([$1], [], [], [$1], [ext], [], [$1], [noext], [], [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], [$2], [optional], [ax_cxx_compile_cxx11_required=false], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++11 features by default, ax_cv_cxx_compile_cxx11, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [ax_cv_cxx_compile_cxx11=yes], [ax_cv_cxx_compile_cxx11=no])]) if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi m4_if([$1], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++11 -std=gnu++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) m4_if([$1], [ext], [], [dnl if test x$ac_success = xno; then for switch in -std=c++11 -std=c++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) fi else if test x$ac_success = xno; then HAVE_CXX11=0 AC_MSG_NOTICE([No compiler with C++11 support was found]) else HAVE_CXX11=1 CPP_ELEVEN=$switch AC_DEFINE(HAVE_CXX11,1, [define if the compiler supports basic C++11 syntax]) fi AC_SUBST(HAVE_CXX11) AC_SUBST(CPP_ELEVEN) fi ]) tango-9.2.5a/m4/check_zlib.m40000644023471100065110000000552013034744702012613 00000000000000dnl @synopsis CHECK_ZLIB() dnl dnl This macro searches for an installed zlib library. If nothing dnl was specified when calling configure, it searches first in /usr/local dnl and then in /usr. If the --with-zlib=DIR is specified, it will try dnl to find it in DIR/include/zlib.h and DIR/lib/libz.a. If --without-zlib dnl is specified, the library is not searched at all. dnl dnl If either the header file (zlib.h) or the library (libz) is not dnl found, the configuration exits on error, asking for a valid dnl zlib installation directory or --without-zlib. dnl dnl The macro defines the symbol HAVE_LIBZ if the library is found. You should dnl use autoheader to include a definition for this symbol in a config.h dnl file. Sample usage in a C/C++ source is as follows: dnl dnl #ifdef HAVE_LIBZ dnl #include dnl #endif /* HAVE_LIBZ */ dnl dnl @version $Id: check_zlib.m4,v 1.2 2000/07/19 13:03:32 simons Exp $ dnl @author Loic Dachary dnl AC_DEFUN([CHECK_ZLIB], # # Handle user hints # [AC_MSG_CHECKING(if zlib is wanted) AC_ARG_WITH(zlib, AC_HELP_STRING([--with-zlib=DIR],[root directory path of zlib installation defaults to /usr/local or /usr if not found in /usr/local]), [if test "$withval" != no ; then AC_MSG_RESULT(yes) ZLIB_HOME="$withval" else AC_MSG_RESULT(no) fi], [ AC_MSG_RESULT(yes) ZLIB_HOME=/usr/local if test ! -f "${ZLIB_HOME}/include/zlib.h" then ZLIB_HOME=/usr fi ]) # # Locate zlib, if wanted # if test -n "${ZLIB_HOME}" then ZLIB_OLD_LDFLAGS=$LDFLAGS ZLIB_OLD_LIBS=$LIBS ZLIB_OLD_CPPFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" AC_LANG_SAVE AC_LANG_C AC_CHECK_LIB(z, inflateEnd, [zlib_cv_libz=yes], [zlib_cv_libz=no]) AC_CHECK_HEADER(zlib.h, [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) AC_LANG_RESTORE if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes" then # # If both library and header were found, use them # # AC_CHECK_LIB(z, inflateEnd) # AC_MSG_CHECKING(zlib in ${ZLIB_HOME}) # AC_MSG_RESULT(ok) ZLIB_CPPFLAGS="-I${ZLIB_HOME}/include" ZLIB_LDFLAGS="-L${ZLIB_HOME}/lib" ZLIB_LIBS="-lz" AC_SUBST(ZLIB_LDFLAGS) AC_SUBST(ZLIB_LIBS) AC_SUBST(ZLIB_CPPFLAGS) else # # If either header or library was not found, revert and bomb # AC_MSG_ERROR(either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib) fi LDFLAGS="$ZLIB_OLD_LDFLAGS" CPPFLAGS="$ZLIB_OLD_CPPFLAGS" LIBS="$ZLIB_OLD_LIBS" fi ]) tango-9.2.5a/m4/gcc_release.m40000644023471100065110000000267213034744702012757 00000000000000dnl Determine whether we have gcc of a particular version or later, dnl based on major, minor, patchlevel versions and date. dnl dnl gcc_AC_HAVE_GCC_VERSION(MAJOR_VERSION, MINOR_VERSION, PATCH_LEVEL) dnl AC_DEFUN([gcc_AC_HAVE_GCC_VERSION], [AC_CACHE_CHECK([for gcc compiler release (at least version $1.$2.$3)], ac_cv_gcc_version_$1_$2_$3, [if test x$GCC = x ; then ac_cv_gcc_version_$1_$2_$3=no else ac_gcc_date=0 ; AC_EGREP_CPP(yes, [#define HAVE_GCC_VERSION(MAJOR, MINOR, MICRO, DATE) \ (__GNUC__ > (MAJOR) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ > (MINOR)) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ == (MINOR) \ && __GNUC_PATCHLEVEL__ > (MICRO)) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ == (MINOR) \ && __GNUC_PATCHLEVEL__ == (MICRO) && ${ac_gcc_date}L >= (DATE))) #if HAVE_GCC_VERSION($1,$2,$3,0) yes #endif], ac_cv_gcc_version_$1_$2_$3=yes, ac_cv_gcc_version_$1_$2_$3=no) fi ]) if test x$ac_cv_gcc_version_$1_$2_$3 = xyes; then AC_DEFINE_UNQUOTED(HAVE_GCC_VERSION_$1_$2_$3, 1, [Define to 1 if we have gcc $1.$2.$3 ]) fi ]) tango-9.2.5a/m4/java_release.m40000644023471100065110000000216213034744702013136 00000000000000dnl Determine whether we have java of a particular version or later, dnl based on major, minor, patchlevel versions and date. dnl dnl java_AC_HAVE_JAVA_VERSION(JAVA_PATH, dnl MAJOR_VERSION, dnl MINOR_VERSION) dnl AC_DEFUN([java_AC_HAVE_JAVA_VERSION], [AC_CACHE_CHECK([for java release (at least version $2.$3)], ac_cv_java_version_$2_$3, [ if test -x $1 -a -f $1; then VERS=`$1 -version 2>&1 | grep version | cut -d '"' -f 2` JAVA_VERSION=$VERS JAVA_MAJOR=`echo $VERS | cut -d '.' -f 1` JAVA_MINOR=`echo $VERS | cut -d '.' -f 2` JAVA_MICRO=`echo $VERS | cut -d '.' -f 3` dnl echo "JAVA MAJOR = $JAVA_MAJOR" dnl echo "JAVA MINOR = $JAVA_MINOR" dnl echo "JAVA MICRO = $JAVA_MICRO" if test $JAVA_MAJOR -lt $2; then ac_cv_java_version_$2_$3=no else if test $JAVA_MINOR -lt $3; then ac_cv_java_version_$2_$3=no else ac_cv_java_version_$2_$3=yes fi fi else ac_cv_java_version_$2_$3=no fi ]) ]) tango-9.2.5a/m4/libtool.m40000644023471100065110000105754213034745117012177 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS tango-9.2.5a/m4/ltoptions.m40000644023471100065110000003007313034745117012553 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) tango-9.2.5a/m4/ltsugar.m40000644023471100065110000001042413034745117012177 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) tango-9.2.5a/m4/ltversion.m40000644023471100065110000000126213034745117012543 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) tango-9.2.5a/m4/lt~obsolete.m40000644023471100065110000001375613034745117013103 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) tango-9.2.5a/m4/mariadb_release.m40000644023471100065110000000231113034744702013610 00000000000000dnl Determine whether we have mariadb of a particular version or later, dnl based on major, minor, patchlevel versions and date. dnl dnl mariadb_AC_HAVE_MARIADB_VERSION(MARIADB_PATH, dnl MAJOR_VERSION, dnl MINOR_VERSION) dnl AC_DEFUN([mariadb_AC_HAVE_MARIADB_VERSION], [AC_CACHE_CHECK([for mariadb release (at least version $2.$3)], ac_cv_mariadb_version_$2_$3, [ if test -x $1; then VERS=`$1 --version 2>&1 | cut -d ' ' -f 6 | cut -d ',' -f 1` MARIADB_VERSION=$VERS MARIADB_MAJOR=`echo $VERS | cut -d '.' -f 1` MARIADB_MINOR=`echo $VERS | cut -d '.' -f 2` MARIADB_MICRO=`echo $VERS | cut -d '.' -f 3` MARIA=`echo $MARIADB_MICRO | cut -d '-' -f 2` if test $MARIADB_MAJOR -lt $2; then ac_cv_mariadb_version_$2_$3=no MARIADB_VERSION=not_found else if test $MARIADB_MINOR -lt $3; then ac_cv_mariadb_version_$2_$3=no MARIADB_VERSION=not_found else ac_cv_mariadb_version_$2_$3=yes fi fi else ac_cv_mariadb_version_$2_$3=no MARIADB_VERSION=not_found fi ]) ]) tango-9.2.5a/m4/mysql_release.m40000644023471100065110000000230613034744702013362 00000000000000dnl Determine whether we have mysql of a particular version or later, dnl based on major, minor, patchlevel versions and date. dnl dnl mysql_AC_HAVE_MYSQL_VERSION(MYSQL_PATH, dnl MAJOR_VERSION, dnl MINOR_VERSION) dnl AC_DEFUN([mysql_AC_HAVE_MYSQL_VERSION], [AC_CACHE_CHECK([for mysql release (at least version $2.$3)], ac_cv_mysql_version_$2_$3, [ if test -x $1; then VERS=`$1 --version 2>&1 | cut -d ' ' -f 6 | cut -d ',' -f 1` MYSQL_VERSION=$VERS MYSQL_MAJOR=`echo $VERS | cut -d '.' -f 1` MYSQL_MINOR=`echo $VERS | cut -d '.' -f 2` MYSQL_MICRO=`echo $VERS | cut -d '.' -f 3` MARIA=`echo $MYSQL_MICRO | cut -d '-' -f 2` if [[ "$MARIA" == *aria* ]]; then MYSQL_VERSION=not_found ac_cv_mysql_version_$2_$3=no else if test $MYSQL_MAJOR -lt $2; then ac_cv_mysql_version_$2_$3=no else if test $MYSQL_MINOR -lt $3; then ac_cv_mysql_version_$2_$3=no else ac_cv_mysql_version_$2_$3=yes fi fi fi else ac_cv_mysql_version_$2_$3=no fi ]) ]) tango-9.2.5a/m4/ac_cxx_have_strstream.m40000644023471100065110000000112513034744702015067 00000000000000dnl @synopsis AC_CXX_HAVE_STRSTREAM dnl dnl If the C++ library has a working strstream, define HAVE_CLASS_STRSTREAM. dnl dnl Adapted from ac_cxx_have_sstream.m4 by Steve Robbins dnl AC_DEFUN([AC_CXX_HAVE_STRSTREAM], [AC_CACHE_CHECK(whether the library defines strstream, ac_cv_cxx_have_strstream, [AC_REQUIRE([AC_CXX_NAMESPACES])] AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_HEADER(strstream, ac_cv_cxx_have_strstream=yes, ac_cv_cxx_have_strstream=no) AC_LANG_RESTORE if test "$ac_cv_cxx_have_strstream" = yes; then AC_DEFINE(HAVE_STRSTREAM,1,[define if the library defines strstream]) fi ])tango-9.2.5a/m4/RSSH_CHECK_OMNINOTIFY.m40000644023471100065110000000664413034744702013755 00000000000000dnl@synposis RSSH_CHECK_CORBA_NOTIFICATION_SERVICE dnl dnl set CORBA support for omniORB v3-pr2 or highter dnl ( http://www.uk.research.att.com/omniORB/omniORB.html) dnl dnl@author Emmanuel Taurel 2003 dnl@id $Id$ dnl AC_DEFUN([RSSH_CHECK_OMNINOTIFY],[ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CXX])dnl AC_REQUIRE([AC_PROG_CPP])dnl AC_REQUIRE([AC_PROG_CXXCPP])dnl AC_REQUIRE([RSSH_CHECK_OMNIORB])dnl AC_ARG_WITH(omninotify, AC_HELP_STRING([--with-omniNotify],[prefix to omniNotify installation (default: $OMNI_ROOT)]) ,\ OMNINOTIFY_PREFIX=${with_omninotify} , OMNINOTIFY_PREFIX=/usr/local ) if test "x$OMNI_ROOT" = "x" then if test "x$OMNINOTIFY_PREFIX" = "x" then OMNI_ROOT="/usr/local" else OMNI_ROOT="$OMNINOTIFY_PREFIX" fi fi if test "x$OMNINOTIFY_PREFIX" = "xno" then dnl OMNINOTIFY NOT SET AC_MSG_RESULT(omniNotify is disabled) omninotify=no else AC_LANG_SAVE AC_LANG_CPLUSPLUS svCXXCPPFLAGS=$CXXCPPFLAGS svCXXFLAGS=$CXXFLAGS svCPPFLAGS=$CPPFLAGS svLIBS=$LIBS svLDFLAGS=$LDFLAGS svRSSH_ROLLBACK=$rssh_rollback rssh_rollback="true" ORB_INCLUDES="-I$OMNI_ROOT/include" CXXCPPFLAGS="$CXXCPPFLAGS -I$OMNI_ROOT/include " CPPFLAGS="$CPPFLAGS -I$OMNI_ROOT/include " RSSH_ENABLE_PTHREADS case $build_cpu in sparc*) AC_DEFINE(__sparc__,1,Needed by omniorb) IDLCXXFLAGS="$IDLCXXFLAGS -D__sparc__" ;; "i686"|"i586"|"i486"|"i386") AC_DEFINE(__x86__,1,Needed by omniorb") IDLCXXFLAGS="$IDLCXXFLAGS -D__x86__" ;; esac case $build_os in solaris*) AC_DEFINE(__sunos__,1,If we're running on solaris) IDLCXXFLAGS="$IDLCXXFLAGS -D__sunos__" __OSVERSION__=5 AC_DEFINE_UNQUOTED(__OSVERSION__, $__OSVERSION__,Needed by omniorb) IDLCXXFLAGS="$IDLCXXFLAGS -D__OSVERSION__=5" ;; freebsd*) AC_DEFINE(__freebsd__,1,If we're running on freebsd) IDLCXXFLAGS="$IDLCXXFLAGS -D__freebsd__" ;; esac AC_SUBST(IDLCXXFLAGS) CXXCPPFLAGS="$CXXCPPFLAGS $IDLCXXFLAGS" AC_CHECK_HEADER( omniNotify/omniNotify.h, omninotify=yes , omninotify=no, ) if test "x$omninotify" = "xyes" then OMNI_LIBDIR="$OMNI_ROOT/lib" if test ! -r "$ORB_LIBDIR/libCOSNotify4.so" then for i in $OMNI_ROOT/lib/*/lib*.so do OMNI_LIBDIR=`dirname $i` break; done fi LIBS="$LIBS -lomnithread" svLIBS=$LIBS LIBS="-L$OMNI_LIBDIR $LIBS" AC_CACHE_CHECK([for omnithreads], rssh_cv_check_omnithreads, rssh_enable_pthreads_done="" RSSH_ENABLE_PTHREADS AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_LINK( #include ,omni_mutex my_mutex, rssh_cv_check_omnithreads=yes,rssh_cv_check_omnithreads=no) AC_LANG_RESTORE ) if test ! $rssh_cv_check_omnithreads = yes then AC_MSG_RESULT("omnithreads not found") omninotify_lib=no fi AC_CHECK_LIB(socket,socket, LIBS="-lsocket $LIBS",,) AC_CHECK_LIB(nsl,gethostbyname, LIBS="-lnsl $LIBS",,) OMNI_LDFLAGS="-L$OMNI_LIBDIR" LIBS="$OMNI_LDFLAGS -lomniORB4 -lomniDynamic4 $svLIBS $LIBS" AC_CACHE_CHECK([whether we can link with omniNotify], rssh_cv_check_omniNotifylib, AC_TRY_LINK( #include ,CosNotifyChannelAdmin::EventChannelFactory_var eventChannelFactory, rssh_cv_check_omniNotifylib=yes,rssh_cv_check_omniNotifylib=no ) ) if test ! $rssh_cv_check_omniNotifylib = yes then AC_MSG_RESULT("omniNotify libs not found") omninotify_lib=no fi OMNI_LIBS="$OMNI_LDFLAGS -lomniORB4 -lomnithread" fi fi AC_LANG_RESTORE ])dnl dnl tango-9.2.5a/m4/omniorb_release.m40000644023471100065110000000251013034744702013657 00000000000000dnl Determine whether we have omniORB of a particular version or later, dnl based on major, minor, patchlevel versions and date. dnl dnl omniorb_AC_HAVE_OMNIORB_VERSION(OMNI_INCL_PATH, dnl MAJOR_VERSION, dnl MINOR_VERSION, dnl MICRO_VERSION) dnl AC_DEFUN([omniorb_AC_HAVE_OMNIORB_VERSION], [AC_CACHE_CHECK([for omniORB release (at least version $2.$3.$4)], ac_cv_omniorb_version_$2_$3_$4, [ if test -x $1; then VERS=`grep VERSION $1/acconfig.h 2>&1 | cut -d ' ' -f 3` OMNI_VERSION=$VERS OMNIORB_MAJOR=`echo $VERS | cut -b 2` OMNIORB_MINOR=`echo $VERS | cut -b 4` OMNIORB_MICRO=`echo $VERS | cut -b 6` dnl echo "OMNIORB MAJOR = $OMNIORB_MAJOR" dnl echo "OMNIORB MINOR = $OMNIORB_MINOR" dnl echo "OMNIORB MICRO = $OMNIORB_MICRO" if test $OMNIORB_MAJOR -lt $2; then ac_cv_omniorb_version_$2_$3_$4=no else if test $OMNIORB_MINOR -lt $3; then ac_cv_omniorb_version_$2_$3_$4=no else if test $OMNIORB_MICRO -lt $4; then ac_cv_omniorb_version_$2_$3_$4=no else ac_cv_omniorb_version_$2_$3_$4=yes fi fi fi else ac_cv_omniorb_version_$2_$3_$4=no fi ]) ]) tango-9.2.5a/pogo/0000755023471100065110000000000013034745266010764 500000000000000tango-9.2.5a/pogo/templates/0000755023471100065110000000000013034745266012762 500000000000000tango-9.2.5a/pogo/templates/cpp/0000755023471100065110000000000013034745266013544 500000000000000tango-9.2.5a/pogo/templates/cpp/Makefile.in0000644023471100065110000001016113034744726015530 00000000000000#============================================================================= # # file : Makefile # # description : Include for the TemplateDevServ class. # # project : Makefile to generate a Tango server # # $Author: $ # # $Revision: $ # # # copyleft : European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # #============================================================================= # This file is generated by POGO # (Program Obviously used to Generate tango Object) # # (c) - Software Engineering Group - ESRF #============================================================================= # CLASS = TemplateDevServ MAJOR_VERS = 1 MINOR_VERS = 0 RELEASE = Release_$(MAJOR_VERS)_$(MINOR_VERS) #----------------------------------------- # Set default home directories #----------------------------------------- TANGO_HOME = @prefix@ CPP_SERVERS = $(TANGO_HOME)/cppserver ifdef no_debug DEBUG = -O else DEBUG = -g endif ifdef _solaris CC = CC AR_SL = $(CC) -mt -G VERS_OPT = -h SL_EXT = so endif ifdef linux CC = c++ CC_SHLIB = $(CC) -fPIC AR = ar AR_SL = $(CC) -fPIC -shared SL_EXT = so VERS_OPT = -Wl,-soname, endif INCLUDE_DIRS = -I$(TANGO_HOME)/include/tango \ -I@ORB_PREFIX@/include \ -I. \ -I$(CPP_SERVERS)/include OBJS_DIR = obj LIB_DIRS = -L $(TANGO_HOME)/lib \ -L @ORB_PREFIX@/lib TARGET_LIB = $(CPP_SERVERS)/lib/libtgclasses.a #----------------------------------------- # Set CXXFLAGS and LFLAGS #----------------------------------------- ifdef _solaris CXXFLAGS = $(DEBUG) -mt -D_PTHREADS $(INCLUDE_DIRS) LFLAGS = $(DEBUG) $(LIB_DIRS) \ -ltango \ -llog4tango \ -lomniORB4 \ -lomniDynamic4 \ -lomnithread \ -lCOS4 \ -lpthread \ -lposix4 -lsocket -lnsl endif ifdef linux CXXFLAGS = $(DEBUG) -D_REENTRANT $(INCLUDE_DIRS) LFLAGS = $(DEBUG) $(LIB_DIRS) \ -ltango \ -llog4tango \ -lomniORB4 \ -lomniDynamic4 \ -lomnithread \ -lCOS4 \ -ldl -lpthread endif #----------------------------------------- # Set dependences #----------------------------------------- SVC_OBJS = $(OBJS_DIR)/main.o \ $(OBJS_DIR)/ClassFactory.o \ $(OBJS_DIR)/$(CLASS)Class.o \ $(OBJS_DIR)/$(CLASS)StateMachine.o \ $(OBJS_DIR)/$(CLASS).o SHLIB_OBJS = $(OBJS_DIR)/$(CLASS)Class.so.o \ $(OBJS_DIR)/$(CLASS)StateMachine.so.o \ $(OBJS_DIR)/$(CLASS).so.o SVC_INC = $(CLASS)Class.h \ $(CLASS).h $(OBJS_DIR)/%.o: %.cpp $(SVC_INC) $(CC) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.o $(OBJS_DIR)/%.so.o: %.cpp $(SVC_INC) $(CC_SHLIB) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.so.o #----------------------------------------- # Make Entry #----------------------------------------- all: $(CLASS) $(CLASS): make_obj_dir make_bin_dir $(SVC_OBJS) $(CC) $(SVC_OBJS) -o $(CLASS) $(LFLAGS) @mv $(CLASS) bin/$(CLASS) shlib: make_obj_dir make_shlib_dir $(SHLIB_OBJS) $(AR_SL) -o \ shlib/$(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) \ $(VERS_OPT)$(CLASS).$(SL_EXT).$(MAJOR_VERS) \ $(SHLIB_OBJS) $(LFLAGS) @rm -f shlib/$(CLASS).$(SL_EXT) @cd shlib; \ ln -s $(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) $(CLASS).$(SL_EXT) clean: rm -f $(OBJS_DIR)/*.o \ $(OBJS_DIR)/*.so.o \ bin/$(CLASS) \ core make_obj_dir: @mkdir -p obj make_bin_dir: @mkdir -p bin make_shlib_dir: @mkdir -p shlib #----------------------------------------- # Install binary file #----------------------------------------- install: cp bin/$(CLASS) $(TANGO_HOME)/bin #----------------------------------------- # Update class library and header files # recompile without debug mode. #----------------------------------------- lib: clean @make no_debug=1 cp *.h $(CPP_SERVERS)/include ar ruv $(TARGET_LIB) $(CLASS).o ar ruv $(TARGET_LIB) $(CLASS)Class.o ar ruv $(TARGET_LIB) $(CLASS)StateMachine.o ident $(TARGET_LIB) | grep $(CLASS) #---------------------------------------------------- # Tag the CVS module corresponding to this class #---------------------------------------------------- tag: @cvstag "$(CLASS)-$(RELEASE)" @make $(CLASS) @make show_tag show_tag: @cvstag -d tango-9.2.5a/pogo/templates/cpp/vc8_project/0000755023471100065110000000000013034745266015772 500000000000000tango-9.2.5a/pogo/templates/cpp/vc8_project/Class_dll.vcproj0000644023471100065110000001252313034744726021042 00000000000000 tango-9.2.5a/pogo/templates/cpp/vc8_project/Class_lib.vcproj0000644023471100065110000001115313034744726021033 00000000000000 tango-9.2.5a/pogo/templates/cpp/vc8_project/DevServ.sln0000644023471100065110000000473513034744726020017 00000000000000Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server_shared", "Server_shared.vcproj", "{570AF151-36FC-4638-A23A-673975792A19}" ProjectSection(ProjectDependencies) = postProject {F513547B-028B-42F8-BE76-A50FD3A3BA3F} = {F513547B-028B-42F8-BE76-A50FD3A3BA3F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server_static", "Server_static.vcproj", "{A52909BB-E783-4522-BF2D-D9786023881D}" ProjectSection(ProjectDependencies) = postProject {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4} = {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Class_lib", "Class_lib.vcproj", "{4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Class_dll", "Class_dll.vcproj", "{F513547B-028B-42F8-BE76-A50FD3A3BA3F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {570AF151-36FC-4638-A23A-673975792A19}.Debug|Win32.ActiveCfg = Debug|Win32 {570AF151-36FC-4638-A23A-673975792A19}.Debug|Win32.Build.0 = Debug|Win32 {570AF151-36FC-4638-A23A-673975792A19}.Release|Win32.ActiveCfg = Release|Win32 {570AF151-36FC-4638-A23A-673975792A19}.Release|Win32.Build.0 = Release|Win32 {A52909BB-E783-4522-BF2D-D9786023881D}.Debug|Win32.ActiveCfg = Debug|Win32 {A52909BB-E783-4522-BF2D-D9786023881D}.Debug|Win32.Build.0 = Debug|Win32 {A52909BB-E783-4522-BF2D-D9786023881D}.Release|Win32.ActiveCfg = Release|Win32 {A52909BB-E783-4522-BF2D-D9786023881D}.Release|Win32.Build.0 = Release|Win32 {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4}.Debug|Win32.ActiveCfg = Debug|Win32 {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4}.Debug|Win32.Build.0 = Debug|Win32 {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4}.Release|Win32.ActiveCfg = Release|Win32 {4C40E24A-E85F-4DD1-9E6D-F8B19CD7D2D4}.Release|Win32.Build.0 = Release|Win32 {F513547B-028B-42F8-BE76-A50FD3A3BA3F}.Debug|Win32.ActiveCfg = Debug|Win32 {F513547B-028B-42F8-BE76-A50FD3A3BA3F}.Debug|Win32.Build.0 = Debug|Win32 {F513547B-028B-42F8-BE76-A50FD3A3BA3F}.Release|Win32.ActiveCfg = Release|Win32 {F513547B-028B-42F8-BE76-A50FD3A3BA3F}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal tango-9.2.5a/pogo/templates/cpp/vc8_project/Server_shared.vcproj0000644023471100065110000001303013034744726021730 00000000000000 tango-9.2.5a/pogo/templates/cpp/vc8_project/Server_static.vcproj0000644023471100065110000001274213034744726021762 00000000000000 tango-9.2.5a/pogo/templates/cpp/Allowed.cpp0000644023471100065110000000332013034744726015555 00000000000000static const char *RcsId = "$Header$"; //+============================================================================= // // file : TemplateDevServ.cpp // // description : C++ source for the TemplateDevServ and its alowed. // method for commands and attributes // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 10062 $ // // $Log$ // Revision 1.1 2004/09/06 08:22:57 pascal_verdier // *** empty log message *** // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include #include #include /*==================================================================== * This file contains the methods to allow commands and attributes * read or write execution. * * If you wand to add your own code, add it between * the "End/Re-Start of Generated Code" comments. * * If you want, you can also add your own methods. *==================================================================== */ namespace TemplateDevServ_ns { //================================================= // Attributes Allowed Methods //================================================= //================================================= // Commands Allowed Methods //================================================= } // namespace TemplateDevServ_ns tango-9.2.5a/pogo/templates/cpp/ClassFactory.cpp0000644023471100065110000000333113034744726016565 00000000000000static const char *RcsId = "$Id: ClassFactory.cpp 13293 2009-04-07 10:53:56Z pascal_verdier $"; //+============================================================================= // // file : ClassFactory.cpp // // description : C++ source for the class_factory method of the DServer // device class. This method is responsible for the creation of // all class singleton for a device server. It is called // at device server startup // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 13293 $ // $Date: 2009-04-07 12:53:56 +0200 (Tue, 07 Apr 2009) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.4 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.3 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.2 2004/10/25 14:12:00 pascal_verdier // Minor changes. // // Revision 3.1 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include #include /** * Create TemplateDevServClass singleton and store it in DServer object. */ void Tango::DServer::class_factory() { add_class(TemplateDevServ_ns::TemplateDevServClass::init("TemplateDevServ")); } tango-9.2.5a/pogo/templates/cpp/DevServClass.cpp0000644023471100065110000002231413034744726016536 00000000000000static const char *ClassId = "$Id: DevServClass.cpp 13293 2009-04-07 10:53:56Z pascal_verdier $"; static const char *TagName = "$Name$"; static const char *CvsPath = "$Source$"; static const char *SvnPath = "$HeadURL: $"; static const char *HttpServer = "http://www.esrf.fr/computing/cs/tango/tango_doc/ds_doc/"; //+============================================================================= // // file : TemplateDevServClass.cpp // // description : C++ source for the TemplateDevServClass. A singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the TemplateDevServ once per process. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 13293 $ // // $Log$ // Revision 3.11 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.10 2006/11/15 14:17:10 pascal_verdier // Remove warnings from compiler. // // Revision 3.9 2006/06/26 09:31:03 pascal_verdier // Tango-5.5 compatiblity. // extern C method added to be used as shared library. // VCC 6 project file generated if running on Win32. // .obj, .so, executable files generated in separated directories. // // Revision 3.8 2005/09/08 08:45:23 pascal_verdier // For Pogo-4.4.0 and above. // // Revision 3.7 2005/06/17 08:53:21 pascal_verdier // CVS tags management added. // // Revision 3.6 2005/05/19 13:11:18 pascal_verdier // *** empty log message *** // // Revision 3.5 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.4 2004/12/10 13:23:27 pascal_verdier // Pogo-4.0.0 (Ready for Tango5). // // Revision 3.3 2004/11/08 14:27:21 pascal_verdier // *** empty log message *** // // Revision 3.2 2004/11/08 11:33:16 pascal_verdier // if device property not found in database, it takes class property value if exists. // // Revision 3.1 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include #include #include //+---------------------------------------------------------------------------- /** * Create TemplateDevServClass singleton and return it in a C function for Python usage */ //+---------------------------------------------------------------------------- extern "C" { #ifdef WIN32 __declspec(dllexport) #endif Tango::DeviceClass *_create_TemplateDevServ_class(const char *name) { return TemplateDevServ_ns::TemplateDevServClass::init(name); } } namespace TemplateDevServ_ns { TemplateBlock //+---------------------------------------------------------------------------- // // method : DevTemplateCmd::execute() // // description : method to trigger the execution of the command. // PLEASE DO NOT MODIFY this method core without pogo // // in : - device : The device on which the command must be executed // - in_any : The command input data // // returns : The command output data (packed in the Any object) // //----------------------------------------------------------------------------- CORBA::Any *DevTemplateCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any) { cout2 << "DevTemplateCmd::execute(): arrived" << endl; extract(in_any, argin); return insert((static_cast(device))->dev_template_cmd(argin)); } TemplateBlock // //---------------------------------------------------------------- // Initialize pointer for singleton pattern //---------------------------------------------------------------- // TemplateDevServClass *TemplateDevServClass::_instance = NULL; //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::TemplateDevServClass(string &s) // // description : constructor for the TemplateDevServClass // // in : - s : The class name // //----------------------------------------------------------------------------- TemplateDevServClass::TemplateDevServClass(string &s):DeviceClass(s) { cout2 << "Entering TemplateDevServClass constructor" << endl; cout2 << "Leaving TemplateDevServClass constructor" << endl; } //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::~TemplateDevServClass() // // description : destructor for the TemplateDevServClass // //----------------------------------------------------------------------------- TemplateDevServClass::~TemplateDevServClass() { _instance = NULL; } //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::instance // // description : Create the object if not already done. Otherwise, just // return a pointer to the object // // in : - name : The class name // //----------------------------------------------------------------------------- TemplateDevServClass *TemplateDevServClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new TemplateDevServClass(s); } catch (bad_alloc) { throw; } } return _instance; } TemplateDevServClass *TemplateDevServClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::command_factory // // description : Create the command object(s) and store them in the // command list // //----------------------------------------------------------------------------- void TemplateDevServClass::command_factory() { command_list.push_back(new DevTemplateCmd("DevReadPosition", Tango::DEV_LONG, Tango::DEV_LONG, "Motor number (0-7)", "Motor position")); } //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::get_class_property // // description : Get the class property for specified name. // // in : string name : The property name // //+---------------------------------------------------------------------------- Tango::DbDatum TemplateDevServClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; ilength() ; i++) { cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; // Create devices and add it into the device list //---------------------------------------------------- device_list.push_back(new TemplateDevServ(this, (*devlist_ptr)[i])); // Export device to the outside world // Check before if database used. //--------------------------------------------- if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) export_device(device_list.back()); else export_device(device_list.back(), (*devlist_ptr)[i]); } // End of Automatic code generation //------------------------------------------------------------- } } // namespace TemplateDevServ_ns tango-9.2.5a/pogo/templates/cpp/DevServClass.h0000644023471100065110000001056113034744726016204 00000000000000//============================================================================= // // file : TemplateDevServClass.h // // description : Include for the TemplateDevServClass root class. // This class is the singleton class for // the TemplateDevServ device class. // It contains all properties and methods which the // TemplateDevServ requires only once e.g. the commands. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 14110 $ // $Date: 2010-02-10 08:47:17 +0100 (Wed, 10 Feb 2010) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.8 2009/04/07 10:53:56 pascal_verdier // Tango-7 release. // SVN tags added // // Revision 3.7 2008/04/07 12:01:57 pascal_verdier // CVS put property modified. // // Revision 3.6 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.5 2007/09/14 14:36:08 pascal_verdier // Add an ifdef WIN32 for dll generation // // Revision 3.4 2005/09/08 08:45:23 pascal_verdier // For Pogo-4.4.0 and above. // // Revision 3.3 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.2 2004/11/08 11:33:16 pascal_verdier // if device property not found in database, it takes class property value if exists. // // Revision 3.1 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #ifndef _TEMPLATEDEVSERVCLASS_H #define _TEMPLATEDEVSERVCLASS_H #include #include namespace TemplateDevServ_ns { //===================================== // Define classes for attributes //===================================== class ATTRIBUTEAttrib: public Tango::Attr { public: ATTRIBUTEAttrib():Attr("ATTRIBUTE", DATA_TYPE, RW_TYPE) {}; ~ATTRIBUTEAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ATTRIBUTE(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ATTRIBUTE(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ATTRIBUTE_allowed(ty);} }; //========================================= // Define classes for commands //========================================= class DevTemplateCmd : public Tango::Command { public: DevTemplateCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevTemplateCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevTemplateCmd() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_COMMAND_allowed(any);} }; // // The TemplateDevServClass singleton definition // class #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif TemplateDevServClass : public Tango::DeviceClass { public: // add your own data members here //------------------------------------ public: Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static TemplateDevServClass *init(const char *); static TemplateDevServClass *instance(); ~TemplateDevServClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: TemplateDevServClass(string &); static TemplateDevServClass *_instance; void command_factory(); void write_class_property(); void set_default_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); }; } // namespace TemplateDevServ_ns #endif // _TEMPLATEDEVSERVCLASS_H tango-9.2.5a/pogo/templates/cpp/DevServ.cpp0000644023471100065110000001013613034744726015547 00000000000000static const char *RcsId = "$Id: DevServ.cpp 13293 2009-04-07 10:53:56Z pascal_verdier $"; //+============================================================================= // // file : TemplateDevServ.cpp // // description : C++ source for the TemplateDevServ and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // TemplateDevServ are implemented in this file. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 13293 $ // // $Revision: 13293 $ // $Date: 2009-04-07 12:53:56 +0200 (Tue, 07 Apr 2009) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.5 2007/10/24 12:07:35 pascal_verdier // Another spelling mistake correction // // Revision 3.4 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.3 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.2 2004/11/08 11:33:16 pascal_verdier // if device property not found in database, it takes class property value if exists. // // Revision 3.1 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= //=================================================================== // // The following table gives the correspondence // between command and method names. // // Command name | Method name // ---------------------------------------- // //=================================================================== #include #include #include namespace TemplateDevServ_ns { //+---------------------------------------------------------------------------- // // method : TemplateDevServ::TemplateDevServ(string &s) // // description : constructor for simulated TemplateDevServ // // in : - cl : Pointer to the DeviceClass object // - s : Device name // //----------------------------------------------------------------------------- TemplateDevServ::TemplateDevServ(Tango::DeviceClass *cl,string &s) :Tango::Device_4Impl(cl,s.c_str()) { init_device(); } TemplateDevServ::TemplateDevServ(Tango::DeviceClass *cl,const char *s) :Tango::Device_4Impl(cl,s) { init_device(); } TemplateDevServ::TemplateDevServ(Tango::DeviceClass *cl,const char *s,const char *d) :Tango::Device_4Impl(cl,s,d) { init_device(); } //+---------------------------------------------------------------------------- // // method : TemplateDevServ::delete_device() // // description : will be called at device destruction or at init command. // //----------------------------------------------------------------------------- void TemplateDevServ::delete_device() { // Delete device allocated objects } //+---------------------------------------------------------------------------- // // method : TemplateDevServ::init_device() // // description : will be called at device initialization. // //----------------------------------------------------------------------------- void TemplateDevServ::init_device() { INFO_STREAM << "TemplateDevServ::TemplateDevServ() create device " << device_name << endl; // Initialise variables to default values //-------------------------------------------- } //+---------------------------------------------------------------------------- // // method : TemplateDevServ::always_executed_hook() // // description : method always executed before any command is executed // //----------------------------------------------------------------------------- void TemplateDevServ::always_executed_hook() { } } // namespace TemplateDevServ_ns tango-9.2.5a/pogo/templates/cpp/DevServ.dsp0000644023471100065110000001130013034744726015545 00000000000000# Microsoft Developer Studio Project File - Name="TemplateDevServ" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=TemplateDevServ - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "TemplateDevServ.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "TemplateDevServ.mak" CFG="TemplateDevServ - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "TemplateDevServ - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "TemplateDevServ - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "TemplateDevServ - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "TemplateDevServ - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "debug" # PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(TANGO_HOME)\include\win32" /I "." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WINSTATIC" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 tangod.lib log4tangod.lib COS4d.lib omniDynamic4d.lib omniORB4d.lib omnithreadd.lib mswsock.lib ws2_32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"$(TANGO_HOME)\lib\win32\debug" !ENDIF # Begin Target # Name "TemplateDevServ - Win32 Release" # Name "TemplateDevServ - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=ClassFactory.cpp # End Source File # Begin Source File SOURCE=main.cpp # End Source File # Begin Source File SOURCE=TemplateDevServ.cpp # End Source File # Begin Source File SOURCE=TemplateDevServClass.cpp # End Source File # Begin Source File SOURCE=TemplateDevServStateMachine.cpp # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=TemplateDevServ.h # End Source File # Begin Source File SOURCE=TemplateDevServClass.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project tango-9.2.5a/pogo/templates/cpp/DevServ.h0000644023471100065110000000622313034744726015216 00000000000000//============================================================================= // // file : TemplateDevServ.h // // description : Include for the TemplateDevServ class. // // project : TANGO // // $Author: pascal_verdier $ // // $Revision: 13293 $ // $Date: 2009-04-07 12:53:56 +0200 (Tue, 07 Apr 2009) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.5 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.4 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.3 2004/10/25 14:12:00 pascal_verdier // Minor changes. // // Revision 3.2 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #ifndef _TEMPLATEDEVSERV_H #define _TEMPLATEDEVSERV_H #include //using namespace Tango; /** * @author $Author: pascal_verdier $ * @version $Revision: 13293 $ */ // Add your own constant definitions here. //----------------------------------------------- namespace TemplateDevServ_ns { class TemplateDevServ: public Tango::Device_4Impl { public : // Add your own data members here //----------------------------------------- // Here is the Start of the automatic code generation part //------------------------------------------------------------- /** * @name attributes * Attribute member data. */ //@{ //@} /** * @name Device properties * Device property member data. */ //@{ //@} /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Command object. * * @param cl Class. * @param s Device Name */ TemplateDevServ(Tango::DeviceClass *cl,string &s); /** * Constructs a newly allocated Command object. * * @param cl Class. * @param s Device Name */ TemplateDevServ(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly allocated Command object. * * @param cl Class. * @param s Device name * @param d Device description. */ TemplateDevServ(Tango::DeviceClass *cl,const char *s,const char *d); //@} /**@name Destructor * Only one destructor is defined for this class */ //@{ /** * The object destructor. */ ~TemplateDevServ() {delete_device();}; /** * will be called at device destruction or at init command. */ void delete_device(); //@} /**@name Miscellaneous methods */ //@{ /** * Initialize the device */ virtual void init_device(); /** * Always executed method before execution command method. */ virtual void always_executed_hook(); //@} // Here is the end of the automatic code generation part //------------------------------------------------------------- protected : // Add your own data members here //----------------------------------------- }; } // namespace_ns #endif // _TEMPLATEDEVSERV_H tango-9.2.5a/pogo/templates/cpp/MachineState.cpp0000644023471100065110000000401713034744726016537 00000000000000static const char *RcsId = "$Id $"; //+============================================================================= // // file : TemplateDevServStateMachine.cpp // // description : C++ source for the TemplateDevServ and its alowed // methods for commands and attributes // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 13293 $ // $Date: 2009-04-07 12:53:56 +0200 (Tue, 07 Apr 2009) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.3 2007/10/23 14:04:30 pascal_verdier // Spelling mistakes correction // // Revision 3.2 2005/03/02 14:06:15 pascal_verdier // namespace is different than class name. // // Revision 3.1 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include #include #include /*==================================================================== * This file contains the methods to allow commands and attributes * read or write execution. * * If you wand to add your own code, add it between * the "End/Re-Start of Generated Code" comments. * * If you want, you can also add your own methods. *==================================================================== */ namespace TemplateDevServ_ns { //================================================= // Attributes Allowed Methods //================================================= //================================================= // Commands Allowed Methods //================================================= } // namespace TemplateDevServ_ns tango-9.2.5a/pogo/templates/cpp/main.cpp0000644023471100065110000000366713034744726015130 00000000000000static const char *RcsId = "$Id $"; //+============================================================================= // // file : main.cpp // // description : C++ source for a TANGO device server main. // The main rule is to initialise (and create) the Tango // system and to create the DServerClass singleton. // The main should be the same for every Tango device server. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // $Revision: 13293 $ $ // $Date: 2009-04-07 12:53:56 +0200 (Tue, 07 Apr 2009) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 3.2 2004/09/06 09:27:05 pascal_verdier // Modified for Tango 5 compatibility. // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include int main(int argc,char *argv[]) { Tango::Util *tg; try { // Initialise the device server //---------------------------------------- tg = Tango::Util::init(argc,argv); // Create the device server singleton // which will create everything //---------------------------------------- tg->server_init(false); // Run the endless loop //---------------------------------------- cout << "Ready to accept request" << endl; tg->server_run(); } catch (bad_alloc) { cout << "Can't allocate memory to store device object !!!" << endl; cout << "Exiting" << endl; } catch (CORBA::Exception &e) { Tango::Except::print_exception(e); cout << "Received a CORBA_Exception" << endl; cout << "Exiting" << endl; } tg->server_cleanup(); return(0); } tango-9.2.5a/pogo/templates/cpp/Makefile0000644023471100065110000001031113034745217015114 00000000000000#============================================================================= # # file : Makefile # # description : Include for the TemplateDevServ class. # # project : Makefile to generate a Tango server # # $Author: $ # # $Revision: $ # # # copyleft : European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # #============================================================================= # This file is generated by POGO # (Program Obviously used to Generate tango Object) # # (c) - Software Engineering Group - ESRF #============================================================================= # CLASS = TemplateDevServ MAJOR_VERS = 1 MINOR_VERS = 0 RELEASE = Release_$(MAJOR_VERS)_$(MINOR_VERS) #----------------------------------------- # Set default home directories #----------------------------------------- TANGO_HOME = /segfs/tango/tmp/Reynald/install/debian7 CPP_SERVERS = $(TANGO_HOME)/cppserver ifdef no_debug DEBUG = -O else DEBUG = -g endif ifdef _solaris CC = CC AR_SL = $(CC) -mt -G VERS_OPT = -h SL_EXT = so endif ifdef linux CC = c++ CC_SHLIB = $(CC) -fPIC AR = ar AR_SL = $(CC) -fPIC -shared SL_EXT = so VERS_OPT = -Wl,-soname, endif INCLUDE_DIRS = -I$(TANGO_HOME)/include/tango \ -I/segfs/tango/ORB/omniORB4.2.1_p1/debian7/include \ -I. \ -I$(CPP_SERVERS)/include OBJS_DIR = obj LIB_DIRS = -L $(TANGO_HOME)/lib \ -L /segfs/tango/ORB/omniORB4.2.1_p1/debian7/lib TARGET_LIB = $(CPP_SERVERS)/lib/libtgclasses.a #----------------------------------------- # Set CXXFLAGS and LFLAGS #----------------------------------------- ifdef _solaris CXXFLAGS = $(DEBUG) -mt -D_PTHREADS $(INCLUDE_DIRS) LFLAGS = $(DEBUG) $(LIB_DIRS) \ -ltango \ -llog4tango \ -lomniORB4 \ -lomniDynamic4 \ -lomnithread \ -lCOS4 \ -lpthread \ -lposix4 -lsocket -lnsl endif ifdef linux CXXFLAGS = $(DEBUG) -D_REENTRANT $(INCLUDE_DIRS) LFLAGS = $(DEBUG) $(LIB_DIRS) \ -ltango \ -llog4tango \ -lomniORB4 \ -lomniDynamic4 \ -lomnithread \ -lCOS4 \ -ldl -lpthread endif #----------------------------------------- # Set dependences #----------------------------------------- SVC_OBJS = $(OBJS_DIR)/main.o \ $(OBJS_DIR)/ClassFactory.o \ $(OBJS_DIR)/$(CLASS)Class.o \ $(OBJS_DIR)/$(CLASS)StateMachine.o \ $(OBJS_DIR)/$(CLASS).o SHLIB_OBJS = $(OBJS_DIR)/$(CLASS)Class.so.o \ $(OBJS_DIR)/$(CLASS)StateMachine.so.o \ $(OBJS_DIR)/$(CLASS).so.o SVC_INC = $(CLASS)Class.h \ $(CLASS).h $(OBJS_DIR)/%.o: %.cpp $(SVC_INC) $(CC) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.o $(OBJS_DIR)/%.so.o: %.cpp $(SVC_INC) $(CC_SHLIB) $(CXXFLAGS) -c $< -o $(OBJS_DIR)/$*.so.o #----------------------------------------- # Make Entry #----------------------------------------- all: $(CLASS) $(CLASS): make_obj_dir make_bin_dir $(SVC_OBJS) $(CC) $(SVC_OBJS) -o $(CLASS) $(LFLAGS) @mv $(CLASS) bin/$(CLASS) shlib: make_obj_dir make_shlib_dir $(SHLIB_OBJS) $(AR_SL) -o \ shlib/$(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) \ $(VERS_OPT)$(CLASS).$(SL_EXT).$(MAJOR_VERS) \ $(SHLIB_OBJS) $(LFLAGS) @rm -f shlib/$(CLASS).$(SL_EXT) @cd shlib; \ ln -s $(CLASS).$(SL_EXT).$(MAJOR_VERS).$(MINOR_VERS) $(CLASS).$(SL_EXT) clean: rm -f $(OBJS_DIR)/*.o \ $(OBJS_DIR)/*.so.o \ bin/$(CLASS) \ core make_obj_dir: @mkdir -p obj make_bin_dir: @mkdir -p bin make_shlib_dir: @mkdir -p shlib #----------------------------------------- # Install binary file #----------------------------------------- install: cp bin/$(CLASS) $(TANGO_HOME)/bin #----------------------------------------- # Update class library and header files # recompile without debug mode. #----------------------------------------- lib: clean @make no_debug=1 cp *.h $(CPP_SERVERS)/include ar ruv $(TARGET_LIB) $(CLASS).o ar ruv $(TARGET_LIB) $(CLASS)Class.o ar ruv $(TARGET_LIB) $(CLASS)StateMachine.o ident $(TARGET_LIB) | grep $(CLASS) #---------------------------------------------------- # Tag the CVS module corresponding to this class #---------------------------------------------------- tag: @cvstag "$(CLASS)-$(RELEASE)" @make $(CLASS) @make show_tag show_tag: @cvstag -d tango-9.2.5a/pogo/templates/cpp/ReadHardwareAttr.cpp0000644023471100065110000000101213034744726017346 00000000000000//+---------------------------------------------------------------------------- // // method : TemplateDevServ::read_attr_hardware() // // description : Hardware acquisition for attributes. // //----------------------------------------------------------------------------- void TemplateDevServ::read_attr_hardware(vector &attr_list) { DEBUG_STREAM << "In read_attr_hardware for " << attr_list.size() << " attribute(s)" << endl; // Add your own code here //--------------------------------- } tango-9.2.5a/pogo/templates/cpp/README0000644023471100065110000000375613034744726014357 00000000000000//-============================================================ // // This class has been generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================= Files generated: =============== TemplateDevServ.cpp: Source code for the TemplateDevServ class and its commands. This class is derived from DeviceImpl_2 class. It represents the CORBA servant obbject which will be accessed from the network. All commands which can be executed on the TemplateDevServ are implemented in this file. TemplateDevServ.h: Include for the TemplateDevServ class. Server class prototypes and descriptions. TemplateDevServClass.cpp: A singleton class derived fromTemplateDevServ. It implements the command list and all properties and methods required by the TemplateDevServ once per process TemplateDevServClass.h: Include for the TemplateDevServClass root class. This class is represents the singleton class for the TemplateDevServ device class. It contains all properties and methods which the TemplateDevServ requires only once e.g. the commands. main.cpp: C++ source for a TANGO device server main. The main rule is to initialise (and create) the Tango system and to create the DServerClass singleton. The main should be the same for every Tango device server. ClassFactory.cpp: C++ source for the class_factory method of the DServer device class. This method is responsible to create all class singletin for a device server. It is called at device server startup tango-9.2.5a/pogo/templates/cpp/readPropMethodName.cpp0000644023471100065110000000131513034744726017706 00000000000000 //+---------------------------------------------------------------------------- // // method : TemplateDevServ::get_target_property() // // description : Read the target properties from database. // //----------------------------------------------------------------------------- void TemplateDevServ::get_target_property() { // Initialize your default values here (if not done with POGO). //------------------------------------------------------------------ // Read target properties from database.(Automatic code generation) //------------------------------------------------------------------ // End of Automatic code generation //------------------------------------------------------------------ } tango-9.2.5a/pogo/templates/cpp/ReadWriteAttr.cpp0000644023471100065110000000346013034744726016714 00000000000000//+---------------------------------------------------------------------------- // // method : TemplateDevServ::read_attr_hardware() // // description : Hardware acquisition for attributes. // //----------------------------------------------------------------------------- void TemplateDevServ::read_attr_hardware(vector &attr_list) { DEBUG_STREAM << "In read_attr_hardware for " << attr_list.size() << " attribute(s)" << endl; // Add your own code here //--------------------------------- } //+---------------------------------------------------------------------------- // // method : TemplateDevServ::read_attr() // // description : Extract real attribute values from // hardware acquisition result. // //----------------------------------------------------------------------------- void TemplateDevServ::read_attr(Tango::Attribute &attr) { string &attr_name = attr.get_name(); DEBUG_STREAM << "In read_attr for attribute " << attr_name << endl; // Switch on attribute name //--------------------------------- } //-------- WRITE ATTRIBUTE ----------- //+---------------------------------------------------------------------------- // // method : TemplateDevServ::write_attr_hardware() // // description : Write attribute values to hardware. // //----------------------------------------------------------------------------- void TemplateDevServ::write_attr_hardware(vector &attr_list) { DEBUG_STREAM << "In write_attr_hardware for " << attr_list.size(); DEBUG_STREAM << " attribute(s)" << endl; for (long i=0 ; i < attr_list.size() ; i++) { Tango::WAttribute &att = dev_attr->get_w_attr_by_ind(attr_list[i]); string attr_name = att.get_name(); DEBUG_STREAM << "Attribute name = " << attr_name; // Switch on attribute name //--------------------------------- } } tango-9.2.5a/pogo/templates/cpp/set_default_property.cpp0000644023471100065110000000113113034744726020427 00000000000000 //+---------------------------------------------------------------------------- // // method : TemplateDevServClass::set_default_property // // description: Set default property (class and device) for wizard. // For each property, add to wizard property name and description // If default value has been set, add it to wizard property and // store it in a DbDatum. // //----------------------------------------------------------------------------- void TemplateDevServClass::set_default_property() { string prop_name; string prop_desc; string prop_def; } tango-9.2.5a/pogo/templates/cpp/state.cpp0000644023471100065110000000234513034744726015314 00000000000000/*********** DevState Overriding method ********************/ /** * Read The device state. *
Command DevState * * @return the device state read. */ virtual Tango_DevState state_cmd(); //+---------------------------------------------------------------------------- // // method : TemplateDevServ::state_cmd() // // description : command to read the device state // // out : device state // //----------------------------------------------------------------------------- Tango_DevState TemplateDevServ::state_cmd() { DEBUG_STREAM << "In TemplateDevServ state command" << endl; return dev_state; } /*********** DevStatus Overriding method ********************/ /** * Read The device status. *
Command DevStatus * * @return A String containing the device state read. */ virtual string &status_cmd(); //+---------------------------------------------------------------------------- // // method : TemplateDevServ::status_cmd() // // description : command to read the device status // // out : device status // //----------------------------------------------------------------------------- string &TemplateDevServ::status_cmd() { DEBUG_STREAM << "In TemplateDevServ status command" << endl; return dev_status; } tango-9.2.5a/pogo/templates/cpp/write_property.cpp0000644023471100065110000000630113034744726017266 00000000000000//+---------------------------------------------------------------------------- // // method : TemplateDevServClass::write_class_property // // description : Set class description as property in database // //----------------------------------------------------------------------------- void TemplateDevServClass::write_class_property() { // First time, check if database used //-------------------------------------------- if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title(PogoProjectTitle); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); PogoClassDescription; description << str_desc; data.push_back(description); // put cvs or svn location string filename(classname); filename += "Class.cpp"; // Create a string with the class ID to // get the string into the binary string class_id(ClassId); // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Call database and and values //-------------------------------------------- get_db_class()->put_property(data); } tango-9.2.5a/pogo/templates/html/0000755023471100065110000000000013034745266013726 500000000000000tango-9.2.5a/pogo/templates/html/Doxyfile0000644023471100065110000007775213034744726015376 00000000000000# Doxyfile 1.2.10 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = POGO_TITLE # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = POGO_OUT_DOC # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, # German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, # Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish. OUTPUT_LANGUAGE = English # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these class will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. It is allowed to use relative paths in the argument list. STRIP_FROM_PATH = # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a class diagram (in Html and LaTeX) for classes with base or # super classes. Setting the tag to NO turns the diagrams off. CLASS_DIAGRAMS = YES # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower case letters. If set to YES upper case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # users are adviced to set this option to NO. CASE_SENSE_NAMES = YES # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explict @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # reimplements. INHERIT_DOCS = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consist of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. # For instance some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = POGO_SRC_FILES # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. FILE_PATTERNS = *.h *.cpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. INPUT_FILTER = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse. FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = /segfs/tango/templates/pogo/html/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = /segfs/tango/templates/pogo/html/footer.html # The HTML_STYLESHEET tag can be used to specify a user defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the Html help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript and frames is required (for instance Netscape 4.0+ # or Internet explorer 4.0+). GENERATE_TREEVIEW = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 200 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimised for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = YES # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assigments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_XML = NO #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = #--------------------------------------------------------------------------- # Configuration::addtions related to external references #--------------------------------------------------------------------------- # The TAGFILES tag can be used to specify one or more tagfiles. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermedate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::addtions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO # The CGI_NAME tag should be the name of the CGI script that # starts the search engine (doxysearch) with the correct parameters. # A script with this name will be generated by doxygen. CGI_NAME = # The CGI_URL tag should be the absolute URL to the directory where the # cgi binaries are located. See the documentation of your http daemon for # details. CGI_URL = # The DOC_URL tag should be the absolute URL to the directory where the # documentation is located. If left blank the absolute path to the # documentation, with file:// prepended to it, will be used. DOC_URL = # The DOC_ABSPATH tag should be the absolute path to the directory where the # documentation is located. If left blank the directory on the local machine # will be used. DOC_ABSPATH = # The BIN_ABSPATH tag must point to the directory where the doxysearch binary # is installed. BIN_ABSPATH = # The EXT_DOC_PATHS tag can be used to specify one or more paths to # documentation generated for other projects. This allows doxysearch to search # the documentation for these projects as well. EXT_DOC_PATHS = tango-9.2.5a/pogo/templates/html/footer.html0000644023471100065110000000203113034744726016026 00000000000000


TANGO is an open source project hosted by :
Sourceforge logo small
Core and Tools : CVS repository on tango-cs project
Device Servers : CVS repository on tango-ds project
tango-9.2.5a/pogo/templates/html/frame.html0000644023471100065110000000101513034744726015623 00000000000000 Tango Device Server User's Guide <H2> Frame Alert</H2> <P> This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. <BR> Link to <A HREF="DevCommands.html">Non-frame version.</A> tango-9.2.5a/pogo/templates/html/header.html0000644023471100065110000000424313034744726015767 00000000000000 Tango Device Server User s Guide


TANGO

Device Servers


tango-9.2.5a/pogo/templates/html/HowIsGenerated.html0000644023471100065110000000237613034744726017414 00000000000000 Tango Device Server User's Guide



Device Servers List
Automatic Generation Pages



The
TANGO device servers list is automaticly generated by POGO classes.
These POGO classes scan a CVS repository and check out all classes under directories named "cppserver" ou "jserver".
Load each class as POGO itself and regenerate the documentation to be up to date.

They analyse the CVSROOT module file to check comments for this class.
If this comments start with a keyword (found in "ModuleFamilies" POGO property), it sorts the class in an array titled by this keyword.
If no keyword is found, the device server is sorted in a section called Miscellaneous.




The Keywords could be seen in CVS repository browsing as follow:

tango-9.2.5a/pogo/templates/html/index.html0000644023471100065110000000424213034744726015645 00000000000000 Tango Device Server User's Guide

TANGO
Device Server


project :
User's Guide

ClassName Class

Revision: 1.0 - Author: Verdier
Implemented in Language




Introduction:

    Class Description:


Class Description:




Conclusion:

    The device server is ready for distribution application programmers.
    The author will be interested in any feedback which arise from their usage of this device server.

tango-9.2.5a/pogo/templates/html/Inheritance.html0000644023471100065110000000111313034744726016761 00000000000000

Class Inheritance:

tango-9.2.5a/pogo/templates/html/page.html0000644023471100065110000000276513034744726015462 00000000000000 Tango Device Server User's Guide

TANGO
Device Server



project :
Page Title

ClassName Class

Revision: 1.0 - Author: Verdier
tango-9.2.5a/pogo/templates/html/SearchItem.html0000644023471100065110000000721313034744726016563 00000000000000 Tango Device Server User's Guide DS User's Guide

TANGO
Device Server





Search Class in ESRF list      


Search Class in Soleil list      

Search Class in Elettra list     





TANGO is an open source project hosted by Sourceforge logo small

Tango core and tools CVS repository on tango-cs project
Tango device servers CVS repository on tango-ds project
tango-9.2.5a/pogo/templates/html/ServersList.html0000644023471100065110000000303113034744726017016 00000000000000 TANGO Servers page

TANGO
Device Server




The source files of following class could be downloaded by clicking on it.
WARNING: These source files have been developped for a specific usage and are not guaranteed for all platforms.


tango-9.2.5a/pogo/templates/html/TangoProgrammerGuide.html0000644023471100065110000000424313034744726020621 00000000000000 Tango Programer's Guide
EUROPEAN SYNCHROTRON RADIATION FACILITY
INSTALLATION EUROPEENNE DE RAYONNEMENT SYNCHROTRON

TANGO Programmer's Guide



The goal of this Programemr's Guide is to define some conventions and
to specify some customs to stadardize Tango device servers writing style.
It specify the Tango naming conventions


Tango project collaboration is based on CVS.
There are 2 main repositories:
  • cvs.sourceforge.net:/cvsroot/tango-cs for kernel modules.
  • cvs.sourceforge.net:/cvsroot/tango-ds for device servers modules.
In addition each institute has is own repository for specific device servers.
A new device server must be added to the apropriate CVS repository in a new CVS module

When a stable version has been developped and tested, the module must be tagged.
It allows to check out this stable version and to know which version is running.
tango-9.2.5a/pogo/templates/html/tkcvs_browser.jpg0000644023471100065110000051367513034744726017266 00000000000000ÿØÿàJFIF``ÿÛC     ÿÛC   ÿÀù "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ú«ÆºÞ—áíu­ßÃú}Ü“Ì#‰cÒšæy¤1™åK…rN:k#þ«_údÿÂNóÿUŸÉHÑÿëæý5ÜÕ:ü¶.­9;Î[¾¶Ùú3ôÊ8JU"­ìº_uê‡ÿÂUkÿB,ŸøIÞñª†tÜêí2ø-ãÓ­´ù¤–6ð½Âù“í–<‹{­1ÂvÉ#!õB?ùcÿ°5ßþ•XÔÓÇT“·4¶kÉùSN1¿,w]<×™¥ÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ+/¯Ôþià_ð >¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãTÊ(úýOæ—þÿ>¡Oùcÿ€ÿÁÿ U¯ý²á'yÿƨÿ„ª×þ„Y?ð“¼ÿãUgFÓ¿µõ‹3ÊûTñÁæmÝ·sœqœf¦ñ&‡7†µÛÝ2s¹íäÚ½O*Øã*AÆxÍiõºÜžÒòµíñ-þã?ªQçöví…í÷”?á*µÿ¡Oü$ï?øÕð•ZÿЋ'þwŸüj¶ücá)¼yekq/™<ö‰s"mÊf, d õïX4TÅÖ¥7 ¹&¿¼¿È)á(ÕŠœZÝæ?þ«_údÿÂNóÿQÿ U¯ý²á'yÿÆ«WÃ~ÿ„ƒûSý#ìÿa°–÷înß³/QŒç¯?JǤñ•£&ågýåþCX:2“ŠQºþëÿ1ÿð•ZÿЋ'þwŸüjøJ­èE“ÿ ;Ïþ5Z¿ðÅý»öùûÙöÓ=û·gðÆ?Ç¢XÊз3–ªÿÿ ŽŒïÊ£¦Ÿ ÿ1ÿð•ZÿЋ'þwŸüjøJ­èE“ÿ ;Ïþ5Z¾ð÷ü%^"´ÒþÑö_?ïvoÛµºdgîã­YƒÃVz½üÚEü÷7Q™mî­D%¡}•„Œ \Ž2Æ+Xb1<\­¯Ú]Þ–¿S9áðð—$”o§Ù}]–··Cþ«_údÿÂNóÿQÿ U¯ý²á'yÿÆ©”W?×ê4¿ð/øÿP§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÂUkÿB,ŸøIÞñªe}~§óKÿÿ€P§ü±ÿÀàŽOÚF®«àGUw2°¼¹URÇ÷]v¢Œú(…/ü%V¿ô"Éÿ„çÿ¦QG×ê4¿ð/øõ ËüþÿøJ­èE“ÿ ;Ïþ5K‹míQV˨p<)x ,\qñr}Kõ5}~§óKÿÿ€P§ü±ÿÀàÿ„ª×þ„Y?ð“¼ÿãTÃâK™f>c*)EøJïpRA +¡Ú¹úJ(£ëõ?š_øüú…?åþÿ‚÷VÒ5Xm®þ¥Õ¼(fðuÓ¤aWj… /OËðÇý»/ü"n?øÍiÑWδ~ÉÛßðêÿ–?øü3ËðÇý»/ü"n?øÍ_†?è•ÙáqÿÆkNНí\GüüŸþÿ>¡Oùcÿ€ÿÁ3<¿ Ñ+²ÿÂ&ãÿŒÑåøcþ‰]—þ7üf´è£ûWÿ?'ÿÀ¨SþXÿà?ðLÏ/ÃôJì¿ð‰¸ÿã4y~ÿ¢Weÿ„MÇÿ­:(þÕÄÏÉÿà_ðêÿ–?øü3ËðÇý»/ü"n?øÍ_†?è•ÙáqÿÆkN¨Gÿ#lö»ÿÒ«Òž"nÞÒ{?µÙ_±ÁS‚¿,w_g»·r¿Ù<'¶Aÿ žÃgxÿ„ãæúþãšX­¼)a#øQaŠž¸~EkQYÿjb?çäÿð/øýBŸòÇÿÿ‚cZiÚ#Ýê·’ü1±ûig¼'Á’dcre`¾Nó û£#¡nfòü1ÿD®Ëÿ›þ3Ri¿òñý{iŸúýt—Ñé¶W·ÿfº*FwÚTgÇ—]ÌqOÚÉh¾×üàéÝ®H½_OþØäá³ð¾ï+á6Ÿã–Ùà{“ïûŠƒ[ ØxsWÔ"øk [Ígi,ñ®¥áv¶WeF`˜‰¸ds·¦GLŠÜ×u?I°Y’ÆæG{ˆ-Ô5ÒàeH÷ÝóùÇÆ2:×+âùüÿ_Ÿúm´¥~%«Æ¬´þ÷š]—qË J6R‚û¼›îûÇ¿ä¤hÿõó?þšîj†¥ªxm¬ZF­›m [9mä”»—f-•™á€ÆN¼à;Çw·ƒÇ^O¥Ëgig5Ëù·¶kç§ÜF¡Ïß–,nUÂä¶Ð9oøXÿÐ:Oüéÿü“CÁck7<=9I^Z¥~·0úö…¡‰«»EÙ´ºXÛþÑñ¿ý öŸø?ÿ$Õm"Ú{=nÆ «¹/îbÐ.R[¹‰/3‹›]²IÉ9'$õëY¿ð°!ÿ tŸø1Óÿù&£¶ñ„/¬K~ö‹LšÝc}Fļ²=Å«¸œŽ'$±ŽäNffß¿B{?²û?"g›eI{˜ˆn¾Òî¼ÎºŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&¹±óúŸþÎ¯í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüΪŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&ì|Çþçÿ€°þÛË?è&øÿ3ª¢¹_øXÿÐ:Oüéÿü“Gü,è'þ tÿþI£û1ÿ yÿà,?¶òÏú ‡þ¿ÌꨮWþ?ô“ÿ:ÿ$Ñÿ úIÿƒ?ÿ’hþÇÌèø í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüΪŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&ì|Çþçÿ€°þÛË?è&øÿ3ª¢¹_øXÿÐ:Oüéÿü“Gü,è'þ tÿþI£û1ÿ yÿà,?¶òÏú ‡þ¿ÌꨮWþ?ô“ÿ:ÿ$Ñÿ úIÿƒ?ÿ’hþÇÌèø í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüΪŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&ì|Çþçÿ€°þÛË?è&øÿ3ª¢¹_øXÿÐ:Oüéÿü“Gü,è'þ tÿþI£û1ÿ yÿà,?¶òÏú ‡þ¿ÌꨮWþ?ô“ÿ:ÿ$Ñÿ úIÿƒ?ÿ’hþÇÌèø í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüΪŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&ì|Çþçÿ€°þÛË?è&øÿ3ª¢¹_øXÿÐ:Oüéÿü“Gü,è'þ tÿþI£û1ÿ yÿà,?¶òÏú ‡þ¿ÌꨮWþ?ô“ÿ:ÿ$Ñÿ úIÿƒ?ÿ’hþÇÌèø í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüΪŠåá`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&ì|Çþçÿ€°þÛË?è&øÿ3ª¢¹_øXÿÐ:Oüéÿü“Gü,è'þ tÿþI£û1ÿ yÿà,?¶òÏú ‡þ¿ÌꨮWþ?ô“ÿ:ÿ$Ñÿ úIÿƒ?ÿ’hþÇÌèø í¼³þ‚aÿ/ó:ª+•ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäš?±óúŸþÃûo,ÿ ˜àKüÏBðgüŽýÁÿ£»­WX°›YÕ5[ùÔêž½¸Kh$$›°ecÿX"’v¹´v¯ÿ…ý¤ÿÁŽŸÿÉ4ÂÀ‡þÒàÇOÿäšï£Ì¨ÓpXi=oð¿—N_Ãc†¶c•Ö¨¦ñPZ[â_>½VŸŽçÑMψô)®$Yui<3éò\w^Æ2K|¥‰Î7qœwÅb_ìþÂÐá.ó´ÿ´†~Õ»íÙÿÇ¿67îÆï›®Þ+Ä¿á`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&·ž2šì²×ÉÛ¦êÚ½?«ðÆe‘ký®y_®Îú-O¢âþ×þÑñ—Ú¿äý“uýŸ÷<¯' åùþ ›wlã;wsŠ¡>›u©ø‡ÀÖ°´Ö0ÙX¤—Kþ¥d;”¿Ý sœ1’xü,è'þ tÿþI£þ?ô“ÿ:ÿ$Õ¼>a-{߯{ÿ)1Åå±Õbéím×k1ïúÏÙ?±ï¿´?ãÃþ9>Ñ×ý^Ó»§=3Óš›Ä÷ö?­ÝŒ¿ØÞXRÝÞ¯Ùsôsh‰]½•±Œ‡=ëç¯øXÿÐ:Oüéÿü“Gü,è'þ tÿþI¤èfM4°³×Éùï¦ÚùÅåi¦ñpÓûËËo{}<ÿÖþÿÉDÒí·þ‰zÒ´MDxkÄx†Ëû"Á V†E³[6–åI1G„Uóù²`1œ¯Zñ/øXÿÐ:Oüéÿü“Gü,è'þ tÿþI®zXÆ•%OêÓÞ]Ÿ2KUn–îtUÌrʵ]O­ChõWVmèïÖç¸x¯RX®¼ey3G£Ë¥Øµäi•G¸çvß™€ sƒ’0IÍýWíñUÿmÿȹäì­Øò<Ïùuû>ßö3œc;ëÀ?á`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&µú¶dÜ›ÃO_'ÚÖzjºÛN¦_\ÊÒŠX¨iæ»§u®¥õ>‚}[M¶†ÛÄzŒ³ÈÞ$²]6ãæÑû»™€T#deGS¹¸ì!’kßëö~±¶mJ]/K–9%HæYe_2Y-Ÿ·ÊÊ[†:šð?øXÿÐ:Oüéÿü“Gü,è'þ tÿþIªx|ÍÿÌ4ÓÓ[;÷}ò³òó%bò¥ÿ1Pk]9•».«hÝyùó=­¼>,ðÄž"½–çK—Î+³K¸3lõ,…ðAc·¸5Œ..ßÃWë­ØÜÃrnÿÑ_U½L$Èó|…H—1íÆy ÷vó^ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ52ÂæN2ŠÂÏÞòo¢ZÝkk]mfTq¹b”dñpÓÍ.­ég¥ïg½ÑìŸu+©cÿ@óÿÀYÑý·–ÐL?ð%þgUEr¿ð°!ÿ tŸø1Óÿù&øXÿÐ:Oüéÿü“Gö>cÿ@óÿÀXmåŸôü ™ÕQ\¯ü,è'þ tÿþI£þ?ô“ÿ:ÿ$Ñý˜ÿÐ<ÿðÛygýÃÿ_æuTW+ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ4cæ?ô?ü‡öÞYÿA0ÿÀ—ùUÊÿÂÀ‡þÒàÇOÿäš?á`Cÿ@é?ðc§ÿòMØùýÏÿaý·–ÐL?ð%þgUEr¿ð°!ÿ tŸø1Óÿù&øXÿÐ:Oüéÿü“Gö>cÿ@óÿÀXmåŸôü ™ÕQ\¯ü,è'þ tÿþI£þ?ô“ÿ:ÿ$Ñý˜ÿÐ<ÿðÛygýÃÿ_æuTW+ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ4cæ?ô?ü‡öÞYÿA0ÿÀ—ùUÊÿÂÀ‡þÒàÇOÿäš?á`Cÿ@é?ðc§ÿòMØùýÏÿaý·–ÐL?ð%þgUEr¿ð°!ÿ tŸø1Óÿù&øXÿÐ:Oüéÿü“Gö>cÿ@óÿÀXmåŸôü ™ÕQ\¯ü,è'þ tÿþI£þ?ô“ÿ:ÿ$Ñý˜ÿÐ<ÿðÛygýÃÿ_æuTW+ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ4cæ?ô?ü‡öÞYÿA0ÿÀ—ùUÊÿÂÀ‡þÒàÇOÿäš?á`Cÿ@é?ðc§ÿòMØùýÏÿaý·–ÐL?ð%þgUEr¿ð°!ÿ tŸø1Óÿù&øXÿÐ:Oüéÿü“Gö>cÿ@óÿÀXmåŸôü ™ÕQ\¯ü,è'þ tÿþI£þ?ô“ÿ:ÿ$Ñý˜ÿÐ<ÿðÛygýÃÿ_æuTW+ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ4cæ?ô?ü‡öÞYÿA0ÿÀ—ùUÊÿÂÀ‡þÒàÇOÿäš?á`Cÿ@é?ðc§ÿòMØùýÏÿaý·–ÐL?ð%þgUEr¿ð°!ÿ tŸø1Óÿù&øXÿÐ:Oüéÿü“Gö>cÿ@óÿÀXmåŸôü ™ÕQ\¯ü,è'þ tÿþI£þ?ô“ÿ:ÿ$Ñý˜ÿÐ<ÿðÛygýÃÿ_æuTW+ÿ úIÿƒ?ÿ’hÿ…ý¤ÿÁŽŸÿÉ4cæ?ô?ü‡öÞYÿA0ÿÀ—ùUÊÿÂÀ‡þÒàÇOÿäš?á`Cÿ@é?ðc§ÿòMØùýÏÿaý·–ÐL?ð%þgUT#ÿ‘¶?û]ÿéUbÂÀ‡þÒàÇOÿäšŽÛÆ¾±-ûÛR-2kuõòÈ÷¬âr8Xœ’Ä;’mK(Ì®ðóÙý—Ù˜ÕβÙE%ˆ†ëí.ëÌìíîç±i%µqÏ•"E#B;!PÄ Á àœuk?K†ú LjZƒêw­$’Irá†w;0P˜…PB“€¢°?á`Cÿ@é?ðc§ÿòMð°!ÿ tŸø1Óÿù&£û'3åäö¶ÿ ÿ"ÿ¶2®n¬Bû|Küͽ7þC¾!ÿ¯m3ÿB¿­ÝsþCz‡ý|Iÿ¡àì¼a 7ÍóÛnÆ­ÿ´l|ÆòÍÙvÿ_´(óc¶In#6ÿZÓõ+당íõs=Ä,†?Aîc“…[ÐdôØVóÊqî){ ì¾Ëó1†s—)7õˆnþÒò:?ÿÈ"ßþÂ6úW Pñüˆ~?ÿ¯‹Ïý6ÚV ¼ÑüÈìuI¼©eIüI‰¹2’­zAÃy«Rê[½kÀ+{K‘o®ï±ÔìBÛ Ú¦ec>ÑО !pHìü^UiJ+»Muù³,&j4«FO²’ogþgIñÓþC±¿qÿ¦Ëšùøéÿ!ؿ߸ÿÓeÍ|÷_ªp§û¥_úù/É‹ñ¿ûíú÷Í…î4ðL>Ð<+}¤|7\±¹ðå®§¨j“.¡"$ÌŒe,ÑN¨€Œ gÓ7„¾èºÅŸ†Ú6©¡ÛŦëŽþâ {ùäûS'q+1cbȤƄ¨Çä×Õýf®VïÛ§Ìø¿¨ÔçPº»iuë·CÂh®›Ãž»×ôkíf{Û=D³u…õ-HÈ"y›†1;ÈøËªv¨Ë`c5<_á GÁËiÚŠÆÌQf‚æÝüÈ.¡nRhœpèÃG¸8 ºœ[å¾§¥5v´1(¢½Â^Òôßj9×-µíôé:RÈѬ—M™æNêU„H¼…C¹›•’JJ ì)Óu—¯Èóú+Ð<+{ xÇÅ^Ñ¦ðŽŸ§}¯Z³ŠYì.®ÆøÊK,“?Þܤ2•#iëž4<[ð|ŸxÚQÒåÝÞ6ò¼ðYÇ63æ11Te%|ÒãFðTGµŠ—,´6XiÊði­¿^¶<¾Šìb@ šöN×!PªÒ|¿Öÿ-5סÄÑ^— x'E›á¯Ä­Iå·Ö/toìϰê6­:F¾tÅdº¡<|¿:pAÇ©æ“áö«q¬éº%˜ŽÿÄ7Žcm"ßyžÕÆÙ‰PŠq’À1Ùµ„› «ÚíþIþ£• ÅEï~Þ­}÷]fŠí¯¾Ü-†±s¤ëº?‰›Hùï­ô‰&i"ˆeD‚H”¹ã,e'å9«_ð¥5Ïø[?ð¯~Õ§ÿmÏ1þÏþ£ÏûÛ7}Þ>ï_nhö°îW«¥£»KæïoÉžEz7€¾é+øsã~û[K»ÑÞÑ!‰LH%“ii‚BìCt]‡!ÜÁ9:·Ãy|=£i÷º¾·¥é·:†žº®›(¸yå…·yg1ÂÑ‚ûx ã¶óƒÚÆî=VŸ¨<=E>_uÞßš8ú(¢µ9Šô½oCÑ~øo@ŽoâM]²‹WÝw4ñÚÚZÈG¤žVÁ,Ìv®¨9-RÝü;²ñ¾áßxfôUÔõh¼;u¦O+¼PÞ²)Ybs¹Ì,Hl²6@.1Œ=´wéÜëú¬õI®e­ºÿ—ãúž_EwzÏÁýWJ^Xu/V¾Ð]†¥§éÓ¼“Áb¦l è0»¶34{ÆõB/Kgð“EÃÿ 5xõ+}B÷ÄW¦+.æYâŽçQÅåFécÚ‰PL{¸ÈëA$ïýZá-Y6­kkøÛóÓ<~ŠîîþÝê¾4ñ}­¬vz“¡Ý\}®êââG´±E‘•#óJo’ ]ÏðõŽàv³âmOB·Ñõ-/T±Öh`Õ`y…´SD#Ã.èÄ‘¾ÄÜ'Ì##$S­®ßõ¹+ VNÑú~6üô<æŠì.¾ÝÇá}W\³Õt½Z !áR†ÊYí ¬UrÌ‹ƒzíÌNãA+óQ«|7—ÃÚ6Ÿ{«ëz^›s¨ië©Ú鲋‡žX[w–s-/·€Î1‘»o8~Ò=Éö­yþŸž‡EV†E}„¼-cã?†ÿ„&ßX‹Ä:-…åôËwx·Iƒ‰%]’í »|Â6c¹QÈóõøe§ë>*»ÓtèñE.µ6•¦Ey4²Írªê±É˜au û×J‚Cc€kž5ã.ÓÁÔ†Í=mù>¶îyýêøEe}àïÞëš¼z.±á»«{C¥Þ(]¦1¹›ËŠBÀU|²~e%°¸'ŸO†òÚhÚn£­kz_†×RC5¶¢.yamÃ!Tc¥±»i##šµV µýms'†¨’mn¯¿µí©ÇÑ^­«|:Ñ[á7€5žÓô½Gû@^Þ_Í;ý¡’p±*ÅÈÜ(l² QÆã–PxOxCQðŠ5 UXÖúÉÂ9…÷£¡•”ú2²‘<€r(…XÍÙyþ©Bt•ÞÚ~*ëúòf%Wmð¶]+PñV…¡j~ÓõXµN y.®%ºI’9…òæEã$‚Tœžr0*å.U{Ó‡´’ís‰¢»oŠRéZŠµÝ LðE§jsÛÇuo-ÓÌñÆî€7™3¯8 äq‘F«ð¶âÏAÖõ}?]ÑüAi¢Í:Ó$˜ù>c2#†’$Y²ã1–êNjUEdÞ—-Ð’”£m½¿àëÐâh¯KѾk𯽦è'SÑìÿ²\y?bûNÜù¸Îß/ø÷tç=ë_ø^_ÄÞ4¸‚âÏÃÞÑõiì#½ÔžSq3,pGµ^I Ü@ 2Ädg^ ÚçT°•b›k­¾î¾‡œÑ^·Âtð÷€>$\k–qϪiI¦M¥êó³A,3ÎÊf‰”…‘GƒŒÃ?að’îãþ×/5íGÓµ×–+I5 ‰‡Ž_,‡ äïûŠÎÊJ‚Õh;ëÖß…ÿ!<-XÙ[uMyuùœ%wžÿ’-ãúü¿ÿÓu¥r~ ðþ£á]fïIÕ­$±ÔmËš G*zŽGAdA‚+¬ð‡ü‘o×åÿþ›­+帥§–6¿š?™ö\œstžü²üHøéÿ!ؿ߸ÿÓeÍ|÷_B|tÿì_ïÜ鲿¼Òî{ ¨n­f’ÚæY"š*ñ¸9 ¤r EcŸîuëä¿$tq¿ûõú÷Í×Åïé~(ÿ„+û2ëí?ÙÞ²Óî¿vÉåÏýéóœdr2c^¡|RðÅŸÅŸ…ºÌÚžÍ7EðÌ:}üÿg”ù3¬¡M¡rß3¨Ê‚9ëÖ¼«þÏŽ?èrñþ 'ÿâ딯«ö Qä—šûþGÅým§´†­´õ]¶ë÷ž¡àˆ¶–_ ®|!,¶zeÛêÃSƒPÔôèïíò|·ŽDhähÏÊ º#’NÓ´e«Ÿø™®Ï¯ê:T—#³ñ–úz[ 4ûiª,’lÅ@R;7íÛšãè­U(Æ\ËúýNyb':j›ÙzþW·àèñN—©xPð6¹uý‘h÷§W±ÕV6‘cºX¼¿.tPÌbuà2 ÊØ$0$?®ƒJø‡â­Â+7ÄÚÆŸe|»k[ùb2I8U`I'êM:‘æVDѨ©Êïo¾ÿŠ6ü/‡àÏx_T—ÄözœvÚµ¬ó>Úçd0¤¤w2Çg…E|üÙ+… Òè~>ÐlüñoRšûe–»¦jöút¾L‡Ï’iCD0+¸w`ïŠóýWâŠµË lu/k…”¸ó-®¯å–7ÁeYˆ8 ¨ÏÖn—>³þ¿e‰övTÖ—¿ánìõ½'âE¦¥ðçÃ^z^‰}¢=Ù7æ“¡mq² ÆòexœFЛX —­x÷Oñφ5¿ k~.·ŸR}NÛ[‹Ä2XÊ–·r Hà’ÜÇ[ãØ3µü¼>Ùø¥}^ºõéÞãúåN^Wªµºì•–—·ëøßÙ¾øûHøMáßA¦ë6zÆ©+ékKa)‚æH¥ó']® ¨BÄmŒv†]­ŒCá¯ø+áçŽü9ãêâk:O¶x^Xßíz¼Mys‘²e˜®J±ä³/ÑIЋ»m뿞–ŒšQI/wmôÖýüí®–µõW=[ÃÚ§‡>XxÎk?[øžãVÓ'Ñ,­¬ín o.b7\LeBmT"—$¶2Ý]Õ§Ä?ÍûDÃñGo¥ÎŠE²¸k˜ÙyDL6lÃ1´œíãi,¿7ÑJXxÊí·v­Ógòò.éÓQQвi¥®êþwêz7ïéxǾÔuô›q,^Öîæ)^`œ»«yHî ÆŽHã=‡|{¥izm¾—âßiþ-ð_Ø·É¡^ØÝI{m1¶ ÙÚ-±²6cR&³ ¤ñá4UN„g{½ÿÊÆtñs§Ëd½Õn»]»=lõaEWAÄz^·®h¿¼7 GX·ðÞ¿¡YE¤m»†y-níc c‘ QÈÉ*ä†V[!”Œ®ƒÂ~)ÒôÝWáï´;¯í{Dñ5–¯}ª´mÉtÌ‘ùp#a/œnfÉ@ùÿü-ŸÐåâüOÿÅÕMCâеo³}»ÄÚÅçÙ¦[˜>Ñ,žT«².[åa“†Œ×#¢Úåéëÿõ=5‰Œ_:ßK»n—ý½oÃõ=[Ä>!Ð|ã‹éªÿjjZ×ö†’–ÒE$ 4ÍæË,„ …>PŒÅÃ.D|…ÏÐ|oáù|7ðnuhì.|#«K5õ´ðLÏ,R^E/™De!T6C2·ÊpF|~îî{û©®®¦’ææwi%šg,ò99,ÄòI$’MCMaÕ•Þ¿ð,CÆË™¸¥nÚ÷RïÝ#Ø#ñöƒ©j_4Yï¾Å¦ø¶ôÝYë mËÍ’5]ád ·p©#*yÇMðŸâg…~Ÿ hwÜz´ZµÎµªÛ[N ¶-g-´pª´bI ÈbÛ.àîHùæŠ%†„¢âÛ³ÿ+ê”䦒ºõïÍmûßÏ]ö=Áž)ÒôŸ„ß´k«¯+RÕ¿³¾Å–ÇÍò§g“æ … üÄg¶k¶ð/t­/M·Òü[âí?ž ûù4+Û©/m¦6ÁB[;E¶6FÌjDÁ–a´ž<&Š©PŒïw¾¿‚_¡<\éòÙ/u[®×o]uÜ(¢Šè8VøñVãRÒ¼'¦x{Äz‚i¶þ´Óõ;y¦†:«¬¨Èpå* Áq“Z|cá xwÂ÷¶ÿÙvZõŽ nu¶Ôl$º»»Š9wÄ–lRH¢%©9‰·¢À Ç„ÿ…³ãú¼AÿƒIÿøºæ®î翺šêêi.ngv’Y¦rÏ#“’ÌO$’I$×* œy‹óõÐô^-ªžÖ.ïÍm¶Ú¾ß™ì³øÇ×Ò|aÒ?·mà‹Å°^éúœ–÷g*—M1G3"¶Ù1÷1•nq‚r¼Cªxsâ}‡ƒ&¼ñ%¿†.42 öÚòÖâvòá'mÄ&(Ø>åsò1B ã$Õå4U* :¦ïÿß¡ÅÊJÒŠkçÝË¿vÏ@ñŸŠt½[á7ÃÖëÍÔ´Ÿí¶Áå°ò¼ÙÕãùˆÃeA?)8ïŠ>=ø§Kñ¯ÅwYÑ®¾Ù¦ÜùTþ[G»l£|¬e#‘Ú¼þŠ¸ÒŒ]ןâîe_|@ðö›ªhpXêilth´Í2xJGm0aÄ‘æ‘0C3:îeŸ$Õ~!ø«\°–ÇRñ6±¨YK2ÚêþYc|FU˜ƒ‚ú\ý`èó[›§éò:Ö)ÓräWæ½î­ºi­öÔú›Áz®‘âÿÚ'OñÛ_ɦÉ.žoot››IUôð,Š%™€‹ìå6:Í»'ÍŒl,>Y­»ŸxŽ÷FEÆ¿ªO¤ª$bÂ[Ù‰‹å–Û…Ú01Æ:V%:T6Ýú%òWÿ1bq ºI.­¿6í~ý¿à ¢Š+ á (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ è>j¶ºü3©_KäYYêv×Ë´¶ÈÒUf8“€f¹ú·¥j×ÚüWÚmíÆŸ{|»›YZ) ƒ†RÈ$} ¥%tÑp—$”»¯ü%:_ü/ßøI>Õÿ_øI¿´>Óå·úµy›öãwÝç϶k°»øµ¥_Úø¿A¶º³³[ÿ\k–:®§¦%í¤‘8eÛ$O¼GJ²ÆÍ–ÚB µy×ü-ŸÐåâüOÿÅ×?ªê×Úåü·Ú•íÆ¡{.<Ë›©ZY–bIÀ}®ob¥ne·õØîX§M?f÷m½-¿Ïúî{.³ñÊçῌ4OÅ–zö­}§évÖ)§ékiÜÌ`AäÆ0‘•l•_¿´gm摤k?þŪëñø~0ú¡3Ïk,ècûZ‡ÀŒÞ>Rª@Vù²ë»ÃêÝέ}yagc=íÄöV{þÍm$¬ÑÁ¼åö)8]Ç“Ž§­Á+r»k~­Ø>¸äŸ´ýÛuþnmu¿~§KñwÇ|Gø­xŠÖÚK;kÇAS0.#XÁlp  8Î2q“sÂòE¼qÿ_—ÿún´®»ÏÉñÇý~_ÿéºÒ¾cŠ"¡•ò­“æ}wNUsžynã7÷£½ý¡ÌÞ!Ñìí'KYõ^ 4\<~`ˆ\[Ip¹*$$q3Åyü*åÿ¡óTÿÁ ¿ÿ¯døéÿ#׃¿ìjÓ?•aøOÂsxžâwyÓNÒlK©N ŽÚ<àp9gc å¹9’V©N…E YsËô>ã<ÂЯ^œªÁ7Éþg›ÿ®_ú5OüÛÿñú?áW/ýš§þmÿøýzŒ:O….NÕñ¡lwÆ ]é*i‘UÈÙ;œª³>1ÎÂ3’*?øPмsqáu_´_­ÒÛAʯ¼)¾ñ ¸2œÆpzú­Wþv|çövþ}/¸ó/øUËÿCæ©ÿ‚þ?Gü*åÿ¡óTÿÁ ¿ÿ¯f¸øu¦YéÚ¶±7ˆ·èwí¦AqmiæÏw8 Ä¢ Ê—`æNBôÉ£Òü £jz_‰5d׮ޓ£¥£y‘éÀÍ)Ÿ‚»U Q¾SópH=2}j¿ó°þÎÂÏ¥÷;ÿ ¹è|Õ?ðCoÿÇèÿ…\¿ô>jŸø!·ÿãõë>(ð é6¿Ò/ß[³×‘Ų‹VŠq*8FŒÇ–ÉÜÀ ÉÎ8Á2Þø;AÐu4ÍoÄs[jcjÞ-‚ÝAfäà£Éç)fQÛ°rb(úÕçaý„ÿŸKî<‡þrÿÐùªà†ßÿÑÿ ¹è|Õ?ðCoÿÇë× ø[©Ç®\Úê3Ca¥YÄ·W:Ö|ËQlßrXجßÑycÇlEcà½;Ķ÷IáÍVêÿV<ÕÓo,–ÞK˜À%ü’²ÈÔvpHÉ\ã}j¿ó°þÎÂÏ¥÷Mÿ ¹è|Õ?ðCoÿÇèÿ…\¿ô>jŸø!·ÿãõìÚ_¼=«øs\Ö¡×õ5µÒ<=IŒ;y®QvrAÁ䯏ÍB;H¯$[æ¹µÙ-Ä"'nrÜsüG׎”}j¿ó°þÎÂÏ¥÷gü*åÿ¡óTÿÁ ¿ÿ£þrÿÐùªà†ßÿ×WEZ¯üì?³°Ÿóé}Ç)ÿ ¹è|Õ?ðCoÿÇèÿ…\¿ô>jŸø!·ÿãõÕÑGÖ«ÿ;ìì'üú_qÊ®_ú5OüÛÿñú?áW/ýš§þmÿøýutQõªÿÎÃû; ÿ>—ÜrŸð«—þ‡ÍSÿ6ÿü~øUËÿCæ©ÿ‚þ?]]}j¿ó°þÎÂÏ¥÷Vúm·Ú® ƒÄ¾+¼û4ÏÉmá{gMÊpFEÇùÍÙKÿA¿á'oÿÉÑø;þcÿö¹ÿÙkØ|þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½×Tøk&žÚœkú>¡©é÷ i&—jóýªYLž^È‘â_4†ÎvÀ÷5O…Ú–m©˜¯´íFûJE“QÓ¬fi.-™›å áÌlÛ ç&µä©ÿ?ŸÝÿçu(/ù…_zÿ/#¿²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯ ôo‚úƵ{¢X¦¡¥Úê:½ ¿‚ÎæwY¹VBB9Ù÷T³Œä¨ŠÝø}àÍ ïÂÞ1Öµ½:õô—‚qvnÖÔ—oœâ%Y`@9;Ôpj\j%lß˾ˌ¨I¤ðÑ[îû+¾›ÿ²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯l°ðdšÞ‹wâ9nôíFûwØãkƒ;§šTÉå E‘ð«Ž_ÔrNj]3áÝÆ©ñÓÂvºŽ¡,Ò¢í:Q4 wV;wl]ÄŽ2TÍ_³«­ë=?®æj®ÚØU®Ú÷Û¡áßÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$WÓ>ð÷„üsñÈéÖ¶i…Ýæöo4äÜ*DÁJ¿ßˆópÄ`erNà%Ñ,ãÕa´]N–ÞDÜ×éÏ“çå`ažD#æõÂP¬Ý½«ÚûÁ*Up±7ÕâÕÚßµ¼¶Ôò_ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+ÝOÃÖ¾ðÜQjztÖ~!wŠÃPC0…¤WòÊ01‰îÚ2S0ç ÖþjZ&Ÿ®]}»N¾:%Â[ê0ZLÌöûÝ‘’¡X½‹.àT†ä©ÿ?Ÿõ§~âö”,ßÕWßå~ݵô<+û)è7ã/ü$íÿù"ì¥ÿ ßŒ¿ð“·ÿäŠú|ÕWPÔ¬gÕô{[Í.ÇíúŒÍ){Hö+à…Œï;[¬{Ôc‚T5/øTºÇüzý¦ÇûìŸmÿ„Ì·y}q·fß3gÏånß·øsÅ.ZŸóýÿ_2œ¨¯ù„_ü üþÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½ëᧇ4ëïí­{]·ûV¡Ú§·ÞÉö‰¤ÊAä;“sœî·ž QÑ>ÜêšU¶¥y©iÚ ÝÇÙm&Õdt/üE6£ŠpFÂ@Îs†áU6g§õÜ•W Òk µóéßm¯§©âÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$W¿_üÕt›O}§ZK ¤ {jï+H¦dVT¬eX’Û>ö)ÉÛ†2ÏðkS†öÖÕt¹â›Imqîci„pY‘+ƒc» UVoP4¹jÏ÷ý|Êæ£ÿ@‹ï]íÛº>|þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½Æ?‡ÂëRÐlìüI¢_6³+A Á,ÇÉpB¨• AÓs•篚/þ_ÚëÃA¶½±Õuÿµµ¡ÓlI$R7eË”…Âäüù\üÁJ°WÉWþ?»þ >׿ÕWÞ¿Èðïì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Üu†×ðYÉu¥ÞØø–nÅ”çFi%0ÊÄò¬ŠJ¹ÈWPUˆÀ9À2jŸ µ-:ÛS1_iÚö”‹&£§XÌÒ\Z)37ÊÂ+˜Ù¶ÎM•?çóþ¾aí(Ð*ûÿàý”¿ôñ—þvÿü‘GöRÿÐoÆ_øIÛÿòE}âOè¶_ ü¬C¨ØÚj7±^IpÒ}¥Û$€,heU“îíRNrÃæ¯7§ u¦®ª¿»þ 5+ai4ž;'¿u~Çÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^‰E_°¯ÿ?_õó2úÞþ—ßÿó¿ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Ñ(£ØWÿŸ¯úù‡ÖðŸô ¾ÿøÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^‰E¿üý×Ì>·„ÿ e÷ÿÀ<ïû)è7ã/ü$íÿù"ì¥ÿ ßŒ¿ð“·ÿäŠôJ(öÿçëþ¾aõ¼'ý/¿þçÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$W¢QG°¯ÿ?_õó­á?è}ÿð;þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½Š=…ùúÿ¯˜}o ÿ@Ëïÿ€yßöRÿÐoÆ_øIÛÿòEÙKÿA¿á'oÿÉè”Qì+ÿÏ×ý|ÃëxOú_üÎÿ²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯D¢a_þ~¿ëæ[ÂÐ2ûÿàwý”¿ôñ—þvÿü‘GöRÿÐoÆ_øIÛÿòEz%{ ÿóõÿ_0úÞþ—ßÿó¿ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Ñ(£ØWÿŸ¯úù‡ÖðŸô ¾ÿøÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^‰E¿üý×Ì>·„ÿ e÷ÿÀ<ïû)è7ã/ü$íÿù"ì¥ÿ ßŒ¿ð“·ÿäŠôJ(öÿçëþ¾aõ¼'ý/¿þçÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$W¢QG°¯ÿ?_õó­á?è}ÿð;þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½Š=…ùúÿ¯˜}o ÿ@Ëïÿ€yßöRÿÐoÆ_øIÛÿòEÙKÿA¿á'oÿÉè”Qì+ÿÏ×ý|ÃëxOú_üÎÿ²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯D¢a_þ~¿ëæ[ÂÐ2ûÿàwý”¿ôñ—þvÿü‘GöRÿÐoÆ_øIÛÿòEz%{ ÿóõÿ_0úÞþ—ßÿó¿ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Ñ(£ØWÿŸ¯úù‡ÖðŸô ¾ÿøÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^‰E¿üý×Ì>·„ÿ e÷ÿÀ<ïû)è7ã/ü$íÿù"ì¥ÿ ßŒ¿ð“·ÿäŠôJ(öÿçëþ¾aõ¼'ý/¿þçÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$W¢QG°¯ÿ?_õó­á?è}ÿð;þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½Š=…ùúÿ¯˜}o ÿ@Ëïÿ€yßöRÿÐoÆ_øIÛÿòEÙKÿA¿á'oÿÉè”Qì+ÿÏ×ý|ÃëxOú_üÎÿ²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯D¢a_þ~¿ëæ[ÂÐ2ûÿàwý”¿ôñ—þvÿü‘GöRÿÐoÆ_øIÛÿòEz%{ ÿóõÿ_0úÞþ—ßÿó¿ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Ñ(£ØWÿŸ¯úù‡ÖðŸô ¾ÿøÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^‰E¿üý×Ì>·„ÿ e÷ÿÀ<ïû)è7ã/ü$íÿù"ì¥ÿ ßŒ¿ð“·ÿäŠôJ(öÿçëþ¾aõ¼'ý/¿þçÙKÿA¿á'oÿÉe/ýüeÿ„¿ÿ$W¢QG°¯ÿ?_õó­á?è}ÿð;þÊ_ú øËÿ ;þH£û)è7ã/ü$íÿù"½Š=…ùúÿ¯˜}o ÿ@Ëïÿ€yßöRÿÐoÆ_øIÛÿòEÙKÿA¿á'oÿÉè”Qì+ÿÏ×ý|ÃëxOú_üÎÿ²—þƒ~2ÿÂNßÿ’(þÊ_ú øËÿ ;þH¯D¢a_þ~¿ëæ[ÂÐ2ûÿàwý”¿ôñ—þvÿü‘GöRÿÐoÆ_øIÛÿòEz%{ ÿóõÿ_0úÞþ—ßÿó¿ì¥ÿ ßŒ¿ð“·ÿäŠ?²—þƒ~2ÿÂNßÿ’+Ñ(£ØWÿŸ¯úù‡ÖðŸô ¾ÿøÿe/ýüeÿ„¿ÿ$Qý”¿ôñ—þvÿü‘^ɦ_jƒuy4˹¬®ÍݸY!r¤“½zV§ÂؼEã½b?¶xÇT´Ñ­­ä¿Ôn!b^xÆ_h'$ç  ÙÚ@Åyuk×§7w¡ô40˜Jô£SÙ%sÈt?O®ZÏvQ@íßCv|ã]Öê?è·Cq¦G†þÍ™$W‘@À $˜I,Ç TíQ…ã‡ú÷ˆüe{¨èštÚÖ™¬Ý=åõŒlð2K#ðl¤•`øÚTçŽkÎè wÔªú.™¥Û\îÛkusk#»¤rïoÚ…€ GQ•'˜ø_¢j?€),G/¢€=Á?òH~%Ü3ÿJ¼îŠ(¢Š(¢Š(¢Š(¢Š(?ÙûQÑ´?ëšÆµ'î´ÍNòöÖ×kÿ¥\ C [—;>l6âùpF Mý±öïÿjêðÿiù×j¼‡w•öŒ¾é*>MÙ# qž*Aáÿ XÞGy¢>¯uwy-ä“ÉxÑ\ðªª8Ô’NO€7¿·|-ÿB‚ÿàÆOð¯N†*¡f›g…‹Ëêb*9FI-ÿµû][ãLÓé÷PØ[ê?h–ú ëyõPê?`h~Î0Tä€KÊ‚sš—]øÚÚæ›¬$–Z ½ÔâÁõû“gnÄbC¸ÇÊÙc±ÝÔp0T8¿Û¾ÿ¡Aðc'øQý»áoúÿ2…_Ö¨ÿ#ûÌ¿³ñOþ^¯»úîwß ¼wa{â kºÍ½‚è{i’_KªF¸†8dØÉiÄ­!Þ©]N[ 6ùß„üo¦è>ñ…{¤Ý_&²ð§·¾X ,M½ƒ󸜓œŒ2fþÝð·ý ÿƒ?Âíß Р¿ø1“ü),U+¿uôü5Ë«´’šº¿Né'ø"xæÓÂú-Å¢Ûk_Mp%}CGÖžÉÞ0¸X™6:°³gù±œg=ïÄ:ãMñ®½o>%ñ¢Á,mã`¶¶lM!b HÒ Ü+nËŒg‹ý»áoúÿ2…Û¾ÿ¡Aðc'øU<]&ïÊþò#–â#U5oOë]Lx¾ox»N×`·K·´v& PêÊQ†GCµŽ888=+o@øƒ¤xSUŠçIðãÛ§Øn-%¸“P/zZ\:9¶‰ÐaT¬} g;²ý»áoúÿ2…Û¾ÿ¡Aðc'øUKJNî/ï"]x$£Qi®ÞŸämjíõi|!-î‘}q7‡.Þâ9¤ÕL’\‚áÔHÏÙHòAႪ‚¡(ÝüOÓntÿÛ.‡t‡Å rîu?ges"€<Ÿ˜yŒÄò2¤/4ÿ·|-ÿB‚ÿàÆOð£ûwÂßô(/þ dÿ …Š¢¶ƒûüïùš<¿÷¨¾ï+~ZõŽì5¸¼eâNÞÇK½ÖÏý«öŸÜy›|¿?ìû1æy_.7lÏͳµgnø[þ…ÿÁŒŸáGöï…¿èP_üÉþ+Ioÿ±rÀb­5ßn½ý{uóÅ>#Ó¡ð‡<1£\}¦Ω©Í±“}ã¡0Ã-Ü©ÚÙÎ2*µ¯lï<)c kÚdú¶›+Éa=ض–æXÛ1ºº³ma•Ü<ààZþÝð·ý ÿƒ?Âíß Р¿ø1“ü+E§kr¾æ/+®ÝÔÖÖÛK_ޤ>ñí§†ü]¨j6Ú"G¡ßÛÍe>‹Ëáíä\ló›sƒ¬X`’6ƒgþjß|@ÖÕ´«=vÏíšÞ¢²Þ¡¹jA «FGV‘Ü’, `óº5ÿ (ã }5)—þ ÿÐ¥ÿ•)¼z³ö“s]O¥ÃÒtiF›w±áÛ¸/¾ëSÛMÄ-âUÛ$LN,a{ÖŒ¿òoÿ¹®éDÔýkÅ7Ú iZ~‘ý™¹Dý¥¥Ël+üCÐŽý©’ÿɼKþæ¹ÿ¥Wœº?Uù£è²÷µèÿ&l|tÿ‘ëÁßö5iŸÊ¹¿øWUñeÅ;‘d÷ÓÛÛµÔ‘FFï-H€NXå€Ú2NxºOŽŸò=x;þÆ­3ùS~x‚o Üëš¼Ùì졘¤rÌŠ/­w&áÐ2åO‚x5žOüŸã—èVoüh‚';០ê¾1ÕNѬžúð¡“b¡Tuff (è2HäԊʯ¤<¤Z|>ø³›¥Ë öºÝÔ¯o"¨%lVÔÌ–-¼ª7‚2m\¾]¡ÚÛh? .üM¥­Ö­>®ºZ½õº\GB/4²Fà®ò@˜˜É5ïÀVü#Ú‡ü#ßÛŸgÿ‰WÚ¾Åöëþ»fý»s»îóœcÞ½‡Fð¦¬èšGŒ.tË_¶®‡¨êØÅŽÎyí$Hãg‰p0Á²ê¥UˆXwUÕWø³Éoko7ü$Á\ÚB°¬„Zœ1E©ÆÊ;A ’IòúÑÿ„{Pÿ„{ûsìÿñ*ûWؾѽ×lß·nw}ÞsŒ{׳Â9¤ÿÃRÿdÿeÙeÏÙÓÈÿßs~÷=:ó\güÛ×ýÍ?ûi@wE{¿ˆtxWÅ÷Õ.ô[_Aj¶ò/Øf}Q]£ üõ„æMì8³g;W„PEPEPEPEPEPœ?†tßxóÄßÚßhò~˳÷Œ¸Ì\ýÒ=_ÿ…gá¿úÿäyøª“Gÿ‘óÅ¿öéÿ¢t•õxÅÒ‹k¡ðÙÉbf“êrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQEtrG±Åí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó3—ÿ…gá¿úÿäyøª?áYøoþ¿ù_þ*ºŠ(ä`ö“þfrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQE‘ìÒÌÎ_þŸ†ÿèÿ‘åÿâ¨ÿ…gá¿úÿäyøªê(£’=ƒÚOù™Ëÿ³ðßýò<¿üUð¬ü7ÿ@ßü/ÿ]ErG°{Iÿ39øV~ÿ oþG—ÿŠ£þŸ†ÿèÿ‘åÿ⫨¢ŽHöi?æg/ÿ ÏÃô ÿÈòÿñT³ðßýò<¿üUuQÉÁí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó3—ÿ…gá¿úÿäyøª?áYøoþ¿ù_þ*ºŠ(ä`ö“þfrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQE‘ìÒÌÎ_þŸ†ÿèÿ‘åÿâ¨ÿ…gá¿úÿäyøªê(£’=ƒÚOù™Ëÿ³ðßýò<¿üUð¬ü7ÿ@ßü/ÿ]ErG°{Iÿ39øV~ÿ oþG—ÿŠ£þŸ†ÿèÿ‘åÿ⫨¢ŽHöi?æg/ÿ ÏÃô ÿÈòÿñT³ðßýò<¿üUuQÉÁí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó3—ÿ…gá¿úÿäyøª?áYøoþ¿ù_þ*ºŠ(ä`ö“þfrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQE‘ìÒÌÎ_þŸ†ÿèÿ‘åÿâ¨ÿ…gá¿úÿäyøªê(£’=ƒÚOù™Ëÿ³ðßýò<¿üUð¬ü7ÿ@ßü/ÿ]ErG°{Iÿ39øV~ÿ oþG—ÿŠ£þŸ†ÿèÿ‘åÿ⫨¢ŽHöi?æg/ÿ ÏÃô ÿÈòÿñT³ðßýò<¿üUuQÉÁí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó3—ÿ…gá¿úÿäyøª?áYøoþ¿ù_þ*ºŠ(ä`ö“þfrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQE‘ìÒÌÎ_þŸ†ÿèÿ‘åÿâ¨ÿ…gá¿úÿäyøªê(£’=ƒÚOù™Ëÿ³ðßýò<¿üUð¬ü7ÿ@ßü/ÿ]ErG°{Iÿ39øV~ÿ oþG—ÿŠ£þŸ†ÿèÿ‘åÿ⫨¢ŽHöi?æg/ÿ ÏÃô ÿÈòÿñT³ðßýò<¿üUuQÉÁí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó3—ÿ…gá¿úÿäyøª?áYøoþ¿ù_þ*ºŠ(ä`ö“þfrÿð¬ü7ÿ@ßü/ÿGü+? ÿÐ7ÿ#ËÿÅWQE‘ìÒÌÎ_þŸ†ÿèÿ‘åÿâ¨ÿ…gá¿úÿäyøªê(£’=ƒÚOù™Ëÿ³ðßýò<¿üUð¬ü7ÿ@ßü/ÿ]ErG°{Iÿ39øV~ÿ oþG—ÿŠ£þŸ†ÿèÿ‘åÿ⫨¢ŽHöi?æg/ÿ ÏÃô ÿÈòÿñT³ðßýò<¿üUuQÉÁí'üÌåÿáYøoþ¿ù_þ*øV~ÿ oþG—ÿŠ®¢Š9#Ø=¤ÿ™œ¿ü+? ÿÐ7ÿ#ËÿÅQÿ ÏÃô ÿÈòÿñUÔQG${´Ÿó2÷€þxsKð÷‰õk}.5ÔmRÞ8'ww1“´1  ŽpHÎ Ïa¢Ûèö> }WPÒ´æ:µí/Ë ü>àöïTü'ÿ"/Œ?íÏÿFšŸþiwýÆö…x8ô•Unß«>Ç(nXvßwù ÿ„‡Ã?ô)åJ_ðª³øßÁvÒ´sxzÞ)ª>®êGàk'LÒ¯õÍB .ͯï¦Ý²Ý%Ž6`ªY°de*“ŒçŠ÷o x—Pð¿„4Ý ÓÁ×GUÓmmm®£}BÂ(~Ôê»Ùggd…Ÿ; 6ìà“_'™fK/Œ\R”›ÙÉGNúôè}- ³{Ùy\òKoxJñ Ûøb9ÐT‘€>œ —þ ÿÐ¥ÿ•)½CÆ:7ü$²Åw­xWÚ­üqJ°Egâ{È®§d¼H#·Ì*r±Â–<®âkʾ$èÚ&‰âëtðì-“w¤ZÞÆ¦æiÃ’œ]ˆÊªp8éS‚ÍiâÜ`Õ¦ï¢jI[ÍÀü®Tµé÷j¾/ðΙ¥Þ^Âæýž›göœ£vÕ'Ç*¾Ÿ¨6­û2A|ñGÜÛk3¢ÎÄ-4§ ¸“ž2I÷5Éø«þE}cþ¼æÿÐ t^ÿ“PÓ?ì«èÉ*³÷Gê¿4z?ûÚô“:ÏŽŸò=x;þÆ­3ùWk¨\YAy 2lŽî!ë´è$žŸ4hxôô&»ŽŸò=x;þÆ­3ùW YäÿÁ©þ9~…fÿƇø"lé~2ÖômbÃT¶Ô¦û}„^E¬³7“Ö]Š ( À `gŠCñF¥áĻޯt]¢¥Å¼ðG<2…m˺9”FAÆG8êk*Š÷ Ý“ÇZìž ³ÖÆ ñêVh‘ÛI ,k (¢"€ª˜È*NAÉɪøçZÖ´eÒn®é‰p.’Òx¢Ž96•Ê*( 0I*0 bØÉ&°¨ ºÛâÏŠ­/⿇RDÔfôZAçÊ¡6–M›¥‡-ʩꠌ/øHuøG¿°þÑÿ¯µ}·ìûývÍ›·cwÝãǵgQ@›ñ\ÒþÊb¹†y-6 i¯lá¹–¸Ø±¼¨ÌЏÈU ’$×;EQEQEQEQEQE„ü;¡Zkzþ§®O¨3ß¼"tô‘Ç´–g<’Iàƒ“œ/Qö_úø‡ÿ WÜÜëÚ·‹u»+-oû6ÚËÈØŸdŽ\ï'“ÏP}zÖÅ÷|s¦èÚ^«sâO.ÃSó~É7Ø >g–Û_€Ù'žÙ¯j“ĨG–Öè|¾#ê.¬ý¢w[žö_úø‡ÿ Qö_úø‡ÿ W“ÿcø£þ†ßü¦Åþ4cø£þ†ßü¦Åþ5¿ûg‘ËÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈç7ÞñΛ£iz­Ï‰<» OÍû$ß`€ùž[m~d`œr{f£Ñ<ã?ê¶ÚmŠ’KË—òâI,íâÝ—s°=Ï$€9"¦ø»^è»e×åå•ÿÌô¯²ø×Ä?ù²ø×Ä?ù¸-?áŸÄSÅoá»_yºÒË,×ìVãbãqm¼mnsÎ8¬OìÐÛÿ”ؿƄñof„ÿ³–®2=cì¾õñþ@£ì¾õñþ@¯'þÇñGý ¿ùM‹ühþÇñGý ¿ùM‹üj¿Û<‰æË;3Ö>Ëà__ÿä >Ëà__ÿä òìÐÛÿ”ؿƴ¼Gà_øOY¸Òµ_}–þßo›Ø }»”0åXƒÃÁïJø»ÛB¿á6×´¬z7Ù| ëâüGÙ| ëâü^scà_êZ6©ªÛx“̰Ó<¯µÍö—æ6Ôà¶NHÇã¾+7ûÅô6ÿå6/ñ¡<[ÚÀÿ³U›RÔõ²ø×Ä?ù²ø×Ä?ù¼ŸûÅô6ÿå6/ñ£ûÅô6ÿå6/ñ§þÙäO6YÙž±ö_úø‡ÿ Qö_úø‡ÿ W“ÿcø£þ†ßü¦Åþ5-·‡¼]{s½¿‰Þ{‰œGQiq³»€ I'Œ _ížC¾[ÚG©ý—À¾¾!ÿÈ}—À¾¾!ÿÈçÞ"ø}ã ÜýŸQñeª\oxÚ+x­.6R+ˆÝŠN0Øè} dcø£þ†ßü¦Åþ4'‹jé¡Ëû:.ÒRLõ²ø×Ä?ù²ø×Ä?ù¼çþ_ÿÂ9ý½ÿ 'üJ~×ö´}‚õÛ7íÛ»wÝç8ǽß|sáß°hx“ìÿn´Žúßýß çc|¬qœµ.l^×C¶\•ùdz7Ù| ëâüGÙ| ëâü^Oýâúò›øÑýâúò›øÕ¶yÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±ik~ñχ~Áý¡âO³ýºÒ;ëô|/ò±Æpx8>Ô¯‹ÛB—ökWJG£}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±?öÏ"y²ÎÌõ²ø×Ä?ù²ø×Ä?ù¼ŸûÅô6ÿå6/ñ£ûÅô6ÿå6/ñ£ý³È9²ÎÌõ²ø×Ä?ù²ø×Ä?ù¼ŸûÅô6ÿå6/ñ£ûÅô6ÿå6/ñ£ý³È9²ÎÌõ²ø×Ä?ù²ø×Ä?ù¼ŸûÅô6ÿå6/ñ£ûÅô6ÿå6/ñ£ý³È9²ÎÌõ²ø×Ä?ù²ø×Ä?ù¼ŸûÅô6ÿå6/ñ£ûÅô6ÿå6/ñ£ý³È9²ÎÌõ²ø×Ä?ù²ø×Ä?ù¼çþ_ÿÂ9ý½ÿ 'üJ~×ö´}‚õÛ7íÛ»wÝç8ǽfÿcø£þ†ßü¦Åþ4“ެSþÍ[©±ö_úø‡ÿ Qö_úø‡ÿ W“ÿcø£þ†ßü¦Åþ4cø£þ†ßü¦Åþ4ÿÛ<‰æË;3Ö>Ëà__ÿä >Ëà__ÿä òìÐÛÿ”Ø¿ÆìÐÛÿ”Ø¿ÆöÏ æË;3Ö>Ëà__ÿä >Ëà__ÿä òìÐÛÿ”Ø¿ÆìÐÛÿ”Ø¿ÆöÏ æË;3Ö>Ëà__ÿä >Ëà__ÿä ó›ïøçMÑ´½VçÄž]†§æý’o°@|Ï-¶¿²0N9=³Y¿Øþ(ÿ¡·ÿ)±$ñokÿ³c£R=cì¾õñþ@£ì¾õñþ@¯'þÇñGý ¿ùM‹ühþÇñGý ¿ùM‹üiÿ¶yÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg¬}—À¾¾!ÿÈ}—À¾¾!ÿÈäÿØþ(ÿ¡·ÿ)±Øþ(ÿ¡·ÿ)±ížAÍ–vg°IªøoLðÞ¯§é+ª4×þNZôFTl}ßÂ} ì{S?æ—ÜgÿhWàïjóéºÞ­©x–Kè´äˆ%¢YE‘ä}¹f87$s€Aìÿæ—ÜgÿhW•Šö¼ëÚïcè0ƒ¤þ¯{_¯Èç´ÍV}T²ÕmÌ»°™nbL¼©å2zSìÆ½:O iÚÅöý©]nÓÄ2] ¹ŒµÄWpÀÑç$¤Ñ#dð´ñ^S\çƒ<âߊþ9Öt}U¿ûZ_ß$VÿÛ6z]¥µµ­–!ùŸH¾–I]UÏ%T,uóžWÉFòåqëkŸK‚ÇÔÀ¹8kÍlÏeÑ|7¨[XhZÍÄ~_É©Ü]ÞZiÆðÙnÚàíb~dÞÎù\82cæËüAm|}g±\iÖ¶±%œ°ÈL-,ò…ã¦Ã# ˆ+ˆøÃðSâOÂï–ºñ<­ä35£OãK)ã¶HÀó¯gCᘇÙmÃ£ÊÆXó”XË4Hô<¨_jÉ«]Í}}y`/f´u[ev’Á#Ásº ªÐFfÄpIæJŠ?y+³ÍËòÈ`1–U9¥kµm»6ï§T—]{6º1Ù…L|9§¬ßã­¾_ðæ¿Š¿äWÖ?ëÎoý×Eá¯ù5 3þÁú·þŒ’¹ßȯ¬לßú®‹Ã_òjgýƒõoý%zyÇû£õ_šOþö½äγã§ü^ÿ±«LþU7Ã{htÏ x³ÅiK«hikö=CÇ“JPË´ð]Êç H8‡ã§ü^ÿ±«LþU‡á?MዉÑàMGI½Aþ›9";˜ó‘Èå]O*ã•<Žàç“ÿ§øåú›ÿàˆ]ø÷Äš…Õæ»¨_YÜ Ia»¸i”€êã‰ÁÜ«ÈÁê:žãþV“ÿ Ûþ¯´^ÿeÏméçÿǯ›×nß½ÇÝéùר_h-g"iÚEì/ç^ê 8AIUH£ù¸ÆX‘‚Ügvößl¢ñô^2—ï>´P,àßíƒ>G”Z$å ÀûÌã†2C/¼xfƒ|)¤êÞñV·ªIz¿Øÿd1ÅfÈ<ß6FR§p8ÎÜ>îIÚøÚlYxcÃÃáäþ*»MLãZm>(n#£òw¨i |0É%‚vãhݹq´OcxCĺÙ<ïퟳ¤y›|Ÿ&BÿwvsŽ£ôÂ]ÿóþ²ÌSûKí~gý1òölÇãœûb€;}àä2[ørËvö}nÝnN¥¦BÎÁe„H äšO™6©ÏSâ_h~ðî‹w«h_êWWÖ³Áep‘BÞsõvˆ}Ò§vìåvá°n|ei¯Ùé°ø‡MšöM6Õ,­®,.…³˜T’« häVÛœ¡O]ÅŽ<[ã[h:&‘i¥ÿfZéRÞ<+öƒ/É4¾b§*È\’s׊ï<%à='ô8ðÍÜ?Û6ùžHºT+ó[™WÌR¤>#¿0 Æ6×êZKy#XÁ5µ©ÆÈ®&ºð3—€óŸáœõ®ÞãâÜÍñlxâ 5#}êMŒ“|‘ àJ䃎 sÄjZKy#XÁ5µ©ÆÈ®&ºð3—€óŸáœõ YøÕãßx{âÞ­®ê[½»ÅoÃy*|˜Ûý^vNI`äç9­øG-­µM^÷MwÑÆ©àI5‹‹k%O'|˜ß««ˆ‘œ‘Ð0Wãh>2ñÞ»uáëÕ¿¸ØLGTSnJ"ª†Qr¤(Ȥó‚¼_Nø—qm¬x“Q¹±†Y5.],Emˆ"¶FTTØ •B÷“žHšW…´4øhÞ(ÔΡ4ë«=mm%HÖEòCò̬P‚IÎ8 ´gpè´ƒÉoáÈo,uÛÙõ»u¹:–™k;”b (K~i>dÚ¤c=Oÿ wü[ÏøEþÉÿ1Oí/µùŸôÇËÙ³Žs튱sã+M~ÏM‡Ä:lײi¶©emqat-œÂ¤•YG"¶Üà zî,p@®±à-;Àš$~"ûV£yy{sko™p°Æ‹o!ŽWwxØ’_T(àNNßZxzãáǯnô‰®>Ë-™…Ä~|Q¼Ä*¤†µ¸;˜ 8ÀÚ¸Íc\xçLÕ4tÒ5-gÓ,®¦ŸKK;ï*[8¥bÏ vÄ‹§qPÙœ´Ùi–¾(ÓHs¡ë}𠽓[ˆå/¬¬ŽJœ®O#¸Ûï x{Â~újw×Z­¬zŒ¦ÜG[ÛÈp€Œ’aX‘”'–­[…w‡Çc[¼º¸=™ˆØmAp³7ƒƒ´•*2 ØI8|p›Ç:f³g¢§ˆôIµ[&%µŠk[ï³ ­”å"‘|¶Îܰ܅I ÎHÍIñR÷X°ñ”z²Oyâ7µgž6òÖÜ@ùU ƒ¸mÂòsÆI&€.ËðÚÓÄøFçÃfôéšÜ¿c¸ó±s-·ïìUB|뜪ÌBŠãZK;à‘ª±žqɯyð¥õÄÿŽPXE¦¥ï„ ±“L‚ !óVQDÂ7ÞÊ }¬à¸]Þ¾AðÏI×-|Uã›û-WOÑ-u;xt×}BdSsˆyªªC}ѸÎ@9 ÿøVïÿC'‡¿ð;ÿ±¯ ¤”©+ÊÚY™ñ¸‡(W“Œ÷®üí²üïÿõ½oÁöÚ—./t¿ZÜkƒGÑ5xVËOFv¹•äIˆW#‹_¶ä’lø“Ápê;øƒ¢[øJÖ-.ßA7v?cÓB»]lŒÄÉ ,²(D![cåIÞOÿ·ú<=ÿßýð­ßþ†OàwÿcV©%öÿ­<ü¿7ZM ÿWòóüòõ5¯|ðE¶‰ec|°Å©C+YÛìÕX^W]¶ìcù·nVn’pjÏÃÝ!#Ñ>Þi:M矫Ký³y$(Æ[ˆ¼Óš ´¢]äµ÷Þuÿ Ýÿèdð÷þö4·ú<=ÿßý[„me%»}üüÿ5R¢’“¦Û²_u¶Ó­µõ='ÁZÝÿíâ +Ý /´‰5;©/~Û¦¤é°™ábî„Æí ‚7q׊Àø;áK϶øÖÇTðÇÛåµÑ%”Yßéå¤Kœ ƒ"3)|*[¨åA¯ü+wÿ¡“ÃßøÿØÑÿ Ýÿèdð÷þö48+5̶_‡ÌJSM?fômýý6þµ:ïéÑêÚ¯ˆ—ÄjAâÛ+v”º, XÍ+‹LD’ʨÁ•X䃯´ÐOá?èm£ý_¸ÒfšÛN¿†ÞÎÛQ¼P¢Ô=´r¿•¿æ ¬cWtK)óøVïÿC'‡¿ð;ÿ±£þ»ÿÐÉáïüÿìhpMÝNß×ä8ÎqŠN“ðþ›ô¹±â™µm?Áú|Úǃ,t]Pj åêRZCk%ÂF®ÞY³((2Îka Vÿí i¬jž$Ö5XìíO†UíßSðFnKÀ»|¹ðq÷¸V`ÉÀQŽ#þ»ÿÐÉáïüÿìjÎ™à‹½R´¿³ñG‡¡»µ•'†O¶†ÚêC)ÁB®X¦¤šº¿éæCu%goÂþZïÿ¿ñ/þ(Ïh¾幵Ʃ¬{ÞJƒjw»ˆªåknÎæõÜê~»Ö5+»ûÏxzk»©^y¤ûh]Îijd“À­¿³êßôðþ ìù®-B6ºo®¦S§*“mÅ¥ÓN†çïI}áo y>xÝô¢]I´;}^Þí|Ô@fgpöȘe c 9ÅïxLºÒÖçG°±Ö5©u¹“TMÑáÔ­¡ýëy1F²Ë“jë’$^¸Á‘v^ksðþ[»™gøm^W.Â+±NNPÀ;Tð­ßþ†OàwÿcX¸'wÎŽ˜Ô”R^Ééÿm4Ûñ×¹ÞZø_L²ºø™‡ô_´kcf›y:Œð«Jʬ`È´áIù™ –«º½€Ó~+ü*µÒ´:Ô½ÔÐéÖÑÌ…È™÷Æ@¨™Y¶íÞ9jóý;ÀKc{ójþÔ"\æÚçPFùrSkq׆=8­/h—Þ0½´žëÄ·ŠÎÒ+kÖà c  °f=IË1<õÆ\ž÷ÅýZÝþe)IGJm;þ­öù|–†Åî{ûE5_ ÿiÄÚ…ÄéßgŠÏíVêò²Ë’eÆ nr|Í›Kj/øgPºðžn–±__ëe‚+ÝR‘¼° G*ðeðXã ·$Žœü+wÿ¡“ÃßøÿØÖ—‡<5©øOY·Õt¯xzÖþßw•7ÚÕöîR§†B G#½W*VjKDfœŸ2”¯ó·–¿?ÀgÅíFÞ×RÓü%§Iæé~‰¬„›Hó®IÝs.æ\ɯܰ2§ºßЉ­xŸÃ^½°²±ŸEÃ6²Þj gmqHŽÁâIÊŒ äÆÀò@^H®þ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û®X.[IhG5WÏx;K·Kl¶ÚÚ¯¥ü5_ìi‘A®K‡ÚâÆ[MÚç˜GÆö×(|뤅'nï›–«hú$«áÿ„n<+c4Ú¥ÛÁs&‘³Û‰”¨`SoÍ —óßµƒ\·˜ÿ·ú<=ÿßýð­ßþ†OàwÿcQìÓÞkúVîmí$¶¤ÿ¦Ÿo+|Ï@¿ðt:‡üU‘ ZÝjvÞ){Y`½„J`Ó<§hÙÚC˜"n¾xd8ßÀ#oâek«ø¹<-¡i×¾$²¸µ4ÈôØeû5ƒC´ÑA³lŽf}¬ä;*‘÷F yŽ‘àx´Û––ãQ𦪅 ˆnõ•ä|ÃÊ(sÆ98äñÓ|YáýGÆž"½Öµ/xm¯.Ü3ˆ¯6¢€ª· P9ÔôÝTÒ­¼Yáèì5?+ípý­O™å¶ää¦F Ïg¾k7þ»ÿÐÉáïüÿìkEfœºY_ÖÆ-Î鯛Þí[îû—âÞ–;}!5¹ðŒ> ð>¦]]kÖö¯}qe »ÝA– ´(Ÿ™U@â0~eSW¼_£Á¥èŸ®î´-/M‹NÕ­ÿ°%ŽÒ!ö‰Нƒçü ï‰‹*`®Ä µxÏ øNo ëÖ´Z߅•gŠ+›çò÷¯*NݧƒƒŒöç# É­øbM{Ä÷:ÕΫáE{›´Íiü¢brã©päœ0ÆãŒqˆä\Û«Áõ4RŸ%¹ÿàZûw×½ÏJñ¿…l-¼Kñ ÞoivµÑ{[¨-c@·Á!18s„œAPÀƒ°ï,Ô|5áÉ †Œ^µÒ¡þÇ72ˬhv÷ºmÃl–O>{ÝþdAÆÓ´“‚½xÏéWž>ñÚÕî³áKKÉÑQi{ G*6†!÷`í 8ÀùGÉ8ð­ßþ†OàwÿcS~âNjÿð=M'UûG(Óm}ÝoÛðüÏRð„ôkÝÂk£èÏâ»w:©I‚åÞà¯ï¢{™&­J y{BŽC!&±<áÑ/‚~"¾—áÔ× ô ¤IqcÜÙóˆ|I"B¨#bªZ?PUÈn#þ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û¾E¯¿ý^ýþF^ÒZ~éèšûÕ»|ýN—À2Iâ¹Ì,A’k­Û®$) <4ƒ eù8à׮ɣi¾Ôü{•£ÿdjÚe½®•¦*–÷äȲ€Æ2IˆÇ#–e &à¹ù¼·þ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û Ò\Û~=Â5+)Iò=vòè¾åÓÓ±êú_ÃUþÈñ‘yä°ø}®,e´Ñ-¡Žy„q¼omr‡Î¹ÚHRvàîù¹`ŸÓtVM+ÂÂÞµñv‘{o·V‘íVIšñþY¡yñºØ (Q†À3¿/É®#þ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û•Ökúù–ç--I¯Ï{õLìîl—Ä¿¯ï4KMbËÅnæ;Xm¥–…ÔK(]npÞÿ»!zíPQãÿÛ5ÏÄý#Nðõ¯Û4˽"ÚÓOAqå±gx6®ò™\6ß”Ý 9òOøVïÿC'‡¿ð;ÿ±£þ»ÿÐÉáïüÿìhöj÷S_ÓO¿—â ¤ùlé¿é5ÛÏðG¿§ƒôó¦é7W~ÑÉú ý¢>ÜÃ,óÜ´WXd]’޼ ¨Ê2àí5ÄøçáD:õçƒl´M5,MÖ§©isÝÛÄ$0\¸ˆ¿ 3¬I!É;ßaÉb+Í¿á[¿ý žÿÀïþÆ´´_ j~ûö‹<=oöëI,n?ÒÕ·ÂøÞ¿2g‘ƒïP©8;Æjÿð=~f²«í,è»~;ß·È_ø‹Hñ¯Å}"7Ù„­.-t»d–Bˆ–¸\—;X >Xî]ØÏ蚟† i?’óCÑ4ibÔ-ìô»ë«mü›i.Ú øÛòǵŽ' “ó|ìc<£þ»ÿÐÉáïüÿìk¤}Õ¿…/4 OÂuµ÷‘öÙྕ¥ºò‰)»ÌfUùŽã±WŸn*çî¨Ëk~fT¥;ÉÔƒ»¿Né¥Ó§àu^'ð§€|r·6_lÕ4‰`ki—A¶ÓdT²É*¼²;œù *Ût¼3á‹]sâ'€oãÐô» ÿÃè5 ŒÖ[­“3¨vyÁÕr©ó€­ÀPÕãÿð­ßþ†OàwÿcGü+wÿ¡“ÃßøÿØÒöi¦¹×ô­ßæR«%%/dô·àïÛäz/„<*‘èŸc‹ÃÖ7ž~­qˆõª1Öâ5Ž9doš ±n]ä€U÷•m·ðö“5Õìš•¡ªOk¨[[è6׫l‘ÊÉo ä‰a…£\´ª>ftŠF+μ)áãáMJ+ô¿ð†£w±Ïo%æ¡7î]àTFÈ8ÈlôùÍÔüw¬jWw÷ž(ðô×wR¼óIöл‰f8É'IÓ¼Ÿ½ý}ÿÖ…*Ž0KÙ»þVIon¿=ßs³Ò¼-cgâ?A¤x^úâO³Ç¿gµÕ§Ó]œìæB’ä‡]Á™£ Ï%«øÃ`Úoˆ´è-:þÌ·vŽÆÅl¥RÀ±ûL HŽ~~`1³è*ÿ·ú<=ÿßýð­ßþ†Oàwÿc[E(Ë™É_3š|ó‡"¦×ü;{[úôÐãè®Ãþ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿ûßž=Î?cWù_ÜqôWaÿ Ýÿèdð÷þö4·ú<=ÿßýñîƯò¿¸ãè®Ãþ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û9ãÜ=_åqÇÑ]‡ü+wÿ¡“ÃßøÿØÑÿ Ýÿèdð÷þö4sǸ{¿Êþ㢻øVïÿC'‡¿ð;ÿ±£þ»ÿÐÉáïüÿìhçpö5•ýÇEvð­ßþ†OàwÿcGü+wÿ¡“ÃßøÿØÑÏáìjÿ+ûŽ>Šì?á[¿ý žÿÀïþÆøVïÿC'‡¿ð;ÿ±£ž=ÃØÕþW÷}Ø·ú<=ÿßýð­ßþ†OàwÿcG<{‡±«ü¯î8ú+°ÿ…nÿô2x{ÿ¿û?á[¿ý žÿÀïþÆŽx÷cWù_ÜqôWaÿ Ýÿèdð÷þö4·ú<=ÿßýñîƯò¿¸ãè®Ãþ»ÿÐÉáïüÿìhÿ…nÿô2x{ÿ¿û9ãÜ=_åqÇÑ]‡ü+wÿ¡“ÃßøÿØÑÿ Ýÿèdð÷þö4sǸ{¿Êþ㢻øVïÿC'‡¿ð;ÿ±£þ»ÿÐÉáïüÿìhçpö5•ýÇEvð­ßþ†OàwÿcGü+wÿ¡“ÃßøÿØÑÏáìjÿ+ûŽ>Šì?á[¿ý žÿÀïþÆøVïÿC'‡¿ð;ÿ±£ž=ÃØÕþW÷}Ø·ú<=ÿßýð­ßþ†OàwÿcG<{‡±«ü¯î8ú+°ÿ…nÿô2x{ÿ¿û?á[¿ý žÿÀïþÆŽx÷cWù_Ü;Âò"øÃþÜÿôi©ÿæ—ÜgÿhU»} ø3ÄpK¬iw³^}›ÊŽÊèHÇd™<`v=½ `kž(Ò¼7ðº©^Çlóë-åFrÎá`ˆP n\œ`n¢¼{Nª·oÕŸ_”ÆPõ%mDeT ŒëyñtÛh÷"¸?‹¼½"Òæšù¿²|+ˆ9!™Ÿî…x¥RXŽ SÎÿÂÎðÏý¿ò¿üMbiÞ;Ó¼%âýO_ðÞ¯£9Ötû½7XÒ¼Q¤Þêºuäw hŽE°¸‰š;(£r(Ú¸óOlì>økÅÚ¿Žü¬ø&ûEÑÿ¶4èºh¶–æêÎxˆí—D–Ú;‘ŠÚBò@‘«Ë3È·Eæ…úgü†|mÿcŸ‰ôõy\½Å‹ 2ÿI¾³ð×ÀÛKÝ!•ôë˜>Ü$–L²TÂÂû1‘#3‚¸Ã1n§4ÏøûG°·¿“S×mïµ-CS¿Õn¦´Óæ·„Ëuw-˪FÆBª­1P ±À5ÍB„0ñ厭êÛݾïÏðJÉ$’EÊNnìéüUÿ"¾±ÿ^sèº/ ɨiŸöÕ¿ôd•ç^ ø‰áëíR¶ƒPß4ÖÒÆ‹äÈ2ÅH%}kÑ|5ÿ&¡¦Ø?VÿÑ’Wœº?Uù£×ÉÿÞ×£ü™Ö|wù(Èó©ÿÛ/ý•žOüŸã—èVoüh‚!ÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ^ñáOü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-V?³nÿ³¾ßöY¾ÁæùjòÏ•æcvÍØÆìsޏ ‡þÿ‰¿çûÿ)Qòuð§üMÿ?ßùJ‹ÿ“«žƒM»¹³¹»†Öimmvùó¤e’-Ç ½€Âäð3Ö«ÐSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËU‹Ý6ïNò>×k5¯ŸÏO26û®¹©ÁÁèáOø›þ¿ò•ÿ'Qÿ Äßóýÿ”¨¿ù:¹j±{¦ÝéÞGÚífµóâYáó£)æFßu×#•88#ƒ@ü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÒ\ü)×ì£\j‘ÁtŒ4ºd* ³EÉ¿êY€¹ w¢…:ýēǩ²@â9•4ÈIö«`/ø;YNf½púü>ÿ±–ÃÿC5Ôéßò+xëþÇëÿýP§ü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-V/tÛ½;Èû]¬Ö¾|K<>te<ÈÛîºär§ph¡ÿ…?âoùþÿÊT_üGü)ÿÏ÷þR¢ÿäêå«fê’èk¬¡·ÓßÌò¥ººŠ7—þZ;“äž:ñ@ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËT–ÖÓ^\EooÏ<®#Ž(Ô³;€ I'ŒPKÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕÍ\ÛMgq-½ÄOñ9ŽH¤R¬Œ y1QÐSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Oü)ÿÏ÷þR¢ÿäê?áOø›þ¿ò•ÿ'W-Eu?ð§üMÿ?ßùJ‹ÿ“¨ÿ…?âoùþÿÊT_ü\µÔÿŸñ7üÿå*/þN£þÿ‰¿çûÿ)QòurÔPSÿ Äßóýÿ”¨¿ù:øSþ&ÿŸïü¥EÿÉÕËQ@Z×ÃÝ[ö«q©kÚDî#BúTyw ªöXà€:z^ilî¢Ya¹Ö&‰º<~ §·Q}V´à¹_ È8#þ?»EzŒÛ‡ìòÀÛ_À†×U•Qµ[Y&—xˆI!UË76H\ô Ÿ.Õ®žë)(d·Õn%Ô­w¶í¥Ü´±nÀ‚rOZ÷_ˆòCì¿ì7þ“%x¹Çû£õ_š=¬Ÿýíz?É”¾>ÈŦØEôŽZ¡ñCþGOþÙ褫ÿ?äbÓ?ì"¿úG-Pø¡ÿ#Χÿl¿ôRVy?ðjŽ_¡Y¿ñ¡þœµQ^ñá…Q@Q@Q@Q@{ÛÄ>ÿ„<Ìñ&¿q¨,;B…0Åg4LìA!>Wh$îéЭ[?^éÖú\v̾›z÷öóË XEÉÎAÉB=sžÀ«i*Ø|ñ^†°¢=µ¾›q*–>l·3 É="Ýpùƒõàžg[Óô?Yø^+­ ~mFÂVê{«‰¢;%$ê×Ú‰«ˆ|Am©J·Ûê[Ê †È…Z6 6|¤ ¿) 2üXÖßž‘ÙA£Ú¥œ ¸Hž5 d!Ø»@å @…¼=§ê?Õµ·Ò|=©Y\#ZZXkI|o!v Q—Ír>xÀ Ÿ”c#ÍëvïÅ]X]@ÇQв[yœPË-+EñÃÏjpé ¦Üè¯fm¥Šy^IVIM¹Š±ÆQS‘À宋T·ƒÄ?¾èßcµ·}JâæÑ.ÿzÍlMÔhΫæKg,#û»{y¾—⻽#Ãšæ‹ pµ®¯äyîêK¯”å×a’yÈ?…IwãMFëDðö˜¥-“Cy¤´¸·Ü“’A!bÙê (¼Ó<5áß|H¾ð4:"X"¼öVú²ÜÍ%ÊK ±ó]KynÆÙ@‹€üŒœ]kJÑt?†Ô×HK[WKä–æYåÚ»%Ú®X àƒ¿{r¶AZr|R¾ûeÞ£o¦i–:íÔF9u‹h¤KŒ°äQ¿ËI—Dæb0Mbêž+»Õü9¡è³G Úéè¤;y®·’H8#ŒøÐ¬Üø'²|n—Àðè)Ÿ*nÜíŠûCÖWVð¼:–š—öòµë‹÷š- »ÀòFì²Ë Î Ñ‚âÚï­N…~Ó,Bx¦%‡‘†hÙdgä’s‚~MœcŒ“âþ¥>§w©M¥é“jö¦ËP¹e˜ÈLb2®¢P«ªsC• v›ñûOÓ4;6³²¼þĺû^Ÿ<ë x ‘$eùU•™9Ü ùŽã4ÞÓWWø—®_@ú” ëG „Óɉž[‡Iwo!1¸Œ‚ÇaÎv¾øþ=>Õ§Ò’Æ 5+*óN‚yŒ3‘k$é*³9t#Jî à9Îí¾ j0k:ÝóÃks´ò=þ:1¶›{(`À«« ¤py9ÑÒ¾-jš þ‘6—c§éözcË,Zt)!‚IdFF–MÒwÚØ·03 ZV‹â?‡ž,ÔáÒM¹Ñ^ÌÛKò¼’¬’20›scŒ¢§#€Ë\lé~+»Ò<9®h°Ç ZêþGžî¤ºùN]v@'œƒøV5QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQErÞ ÿ‘ãÂö÷ÿ¢…^øw®éôÛOøOR×¥Õd’këÈÇ$s:Ç ’yÈ.XŒ…ËrÈñá?û{ÿÑB»Oj×Ú_ÀßýŽòâÓÛ÷ù²nÅËc8<õ?pž"ðï5ØíY>êv·v²‰aœØìÊFÐJ°à€GoJ÷ˆÑËÁ+Hç†KiÓA™d†Q‡…²eXv ðkÎüKã zj²Å­ê1È–’²º]È ‡ðk³ñü›Žÿb¹ÿÒ8ëÅÎ?ݪüÑídÿïkÑþLgí ?Ùµ½:M»¶ê)Æqÿ.r×”xË_ñ‹„ ú¿þxÓ¿ÑVÏÁ,ºMáF‘Ûofk²ÌN9$’{“[æ9•<¶1•E¿õÙž].³i!y^&ÿ¡›ÿ$"£Êñ7ý ßù!}a'ìÛ ê³Ës©]Kep䆠ŽÂÔ(åH'ÃuÉVU<|¹ÜÍà¼7màïëz%”×7vrD±=ã#JCA‡%Aùœöb–6Âfä£+Ê×jÏO›Vê(T¤¯%¡Åù^&ÿ¡›ÿ$"£Êñ7ý ßù!v_ð„jÿÙŸnò`Ùäý£ìÿl‡í^VÝÛþÏ¿ÍÛ³çÎÜlùþï4?õ¸í%¹k,E)qÌ©ºDh–lÆ»³&ØÂQXÚ+Ø9Î7Êñ7ý ßù!W‰¿èfÿÉ«²°ð>·©ÛÁ=µ–ø®!BÆT_4$Q2ÃtŒñJ!—m„ª*-ÂZ޹j×6ÿd†Ý\Æ&¾¾‚Ñ€ª]C ’8ܹÆáKÊñ7ý ßù!W‰¿èfÿÉ«­‡Â:¬Ú¼úh‚8î A,¯5ÄqÀ‘œmÌÌ#Û“kîÚÛÓi;—$þÕmõ/°˜#’cm%â´ËÆŽîé"±GG ;Iå~ð"€9/+Äßô3ä„Ty^&ÿ¡›ÿ$"®ÞïáïˆtõƒíZd–¯2\ºÃ;¢J¢„²ïŒÈDe\°e*Fq£Ó.eÓ.56pM¼’n+È®È1œœˆŸ1òóÔdÊñ7ý ßù!W‰¿èfÿÉ«²Ôü«é2]\ÃXqçÃä2Ïo’÷У™"çzŒ1 pH,?|C<κd‚ÞatÓ»¢ÆSÈW$%„žZ’ûrvðpÄy^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«EOá˜üGªÉ†î|K"éÚÅõ¤wRÛZ¤W5“òä¶s‚r£¶àܵ߇.añ>¬–šÝø¹Ñu{Û'½qs˜”„_”€cvãÐåpo=ß‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôegù^&ÿ¡›ÿ$"£Êñ7ý ßù!j×OªxgIÑ~×§ÞëÃâ Mé5·ØwZ¤«ÑyÂBņ dG·ñlýåp~W‰¿èfÿɨò¼MÿC7þHE[Ñé—2é—‚G›8&ŽÞI7•äWdÎNDOÈùyê2Yé—7ö÷ÓÁø¬¡ ¸ ˆdHÁäóóȃ'œô€0|¯ÐÍÿ’Qåx›þ†oüеjö¢^k×MšFJ!’I'™!Š%ÈžG!Pdª‚Äd²É€sžW‰¿èfÿɨò¼MÿC7þHE^ƒ®øãNŸÃ¶VÆ;«ýFÁî¦ònáš"yБ*8ƒ3ÂáÉ Š>Õín#‹É‚ã̆yÖ[KÈn"+ fIG™²nTŠgv ñó.@8ß+Äßô3ä„Ty^&ÿ¡›ÿ$"­èôË™tËA#ÍœGo$›‡Êò+² g'"'ä |¼õÙñ„¤ðî…¦ÜÜyoqssqšÖúÞêܪ,$(1;àÈŃc†Lw #Êñ7ý ßù!W‰¿èfÿÉ«²ÿ„#WþÌûw“Ï'ígûd?jò¶îßö}þnÝŸ>vãgÏ÷y£LðF¯«ØÇum fÏ‘ ·Å=Æ _ÜÂî$—, ŠrÀ¨ÉPåx›þ†oüŠ+Äßô3ä„U«[7„µrÕ®mþÉ º¹ŒM}}¢; T2º‡ $.q¹sà —•âoú¿òB*<¯ÐÍÿ’W[„uYµyôÑqÜ@‚Y^kˆã#8Û!™˜F·&×ݵ·¦Òw.Iü#ªÛê_a0G$ÆÚKÅh.#–)!ÝÒEbŽŽ@v“Ê2ýàEr^W‰¿èfÿɨò¼MÿC7þHE]½ßÃßéëÚ´É-^d¹u†wD•D eß;ˆÊ¸ `ÊTŒãG¦\˦\j làš;y$Ü>W‘]c99? cåç¨È•âoú¿òB*<¯ÐÍÿ’We©ø#WÒ,dº¹†°ãφ+Èežß$/ï¡G2E†!Nõbà*X~ø†x'tɼ6Âé§wEŒ§.0®H þK <µ%öäíààˆò¼MÿC7þHEG•âoú¿òB*íí|­^ZÃ4qZo™Åi&¡n—RM¶í •‹‚ €¹pÊTÃ<íey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«Eey^&ÿ¡›ÿ$"£Êñ7ý ßù!jÑ@^W‰¿èfÿɨò¼MÿC7þHEZ´PW•âoú¿òB*<¯ÐÍÿ’V­•åx›þ†oüŠ+Äßô3ä„U«EeZiÚŸö柨ê:·öØüÏ.?³,_}vžWðíÚ»ß É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“9¿Û/B¸ñG†õMÕãŽëQólây‰¯&Ÿ:)b dŒà¥r_~ ÚøßAñ´:wìñð×þ-ñ&—¨Ù?Šíµ`o¡–ö a–àȺR»±¹oœÜÀŸ˜×¤þÑÿò±ÿ°Šé$µä«þ½ÿÝ_æk<Ÿø5?Ç/Ð¬ßøÐÿJÚ”:èˆÔó´zý Ôä!sÿ][ùšüþe¥XR0AUÈ4Í:Ò{«¨í-­`F–YæUDe™˜ð’OJ3|«ûV‡?/+¾×ýQæÐ¯ìv½ÏÐzøóãoü•ß×[ý$‚¼@|Møqæ·üUžÛ´cþ&6ØïþÕvdC§ÛJéÇåcP3ÿÖ®,§"þË®ë{^k«ZÖêŸwØÒ¾+ÛG—–Ço⑤x—SÕüIý»³êMyý“öyšê9]‹yyØ"*ã˜Ï›nïÝ×O¬ÞZh¾+ðLjouè._HÓt‰áÑBÜ5ÇÉk‹&?)œ–$9Àvm¬ß!¡Á¨Ì)ö{U·¸Ú<ØSÁz”‹wPÄ)`*¹ô*¬ŸüWw<§C°›[°R]Ïén[`ºtqŒýåܧûÙÜ«ìS̰µfà¥gæšüZHçtg{kšƒ<5Á§ZÛ鳸°xî%”æúç{Īž^æ «ó:d ÜTh·ñ\^!ÔõËéõM'MƒPÔ§½“J×l¤ºˆ,­’"–8шù]“Êl,d1 láõÿÃšÅæ•ªZ›-BÑ•f„Ë›K"¸ù£fSòºž \¹ðgˆ,ôªÜhZ”YD_Ig"ÀU±µ·‘·#<äz×¤š’ºØÄë4¿é:]Æ»¤é“ØXÙßMkqî£aöÛD’(ä ŽHä‘cfšO-Ê™ª+ÙHëJºk\›W…ŸF³tòãŽeo0´d»æHðÌýþFãº/ üDŸÃš¯§ýšÂO>ÌClÒiV³6ÿ´Å)ó]г®Ô|,Ù€6‚¼}-ÕËÞ]Mq ^W.Â(Ö4œª *@°­ß^ÙÜèZ–…yw˜/.mîã¾âF…f]ŽY€a;Ê­‚ªÃZx[Y†úöÊM"ý/,¡7VílâH"î¸Ê¨ §'zÖezt/Òt3¦éÖ:Œ‘¶„ÚT×÷:›AîwdVó#ávî áöo_.±¼GâËË;­K=wM¾¸ÓnZöÝ´%--à˜ðØ0Ä]ɉrS Ù!xømf¸Žy"†IRJȤˆ×p]Ì{ Ì£'»Þ¤ÒôËkS´Óì£ó¯.æKxcÜ{³Q’@$rN({ƺޛ{ö; ³hðo»Xw³íž}­"åÆãåªÅz7‘¼`¹ª·š´¾Ò4ô“7jW·G´ü©$Vª‡8Áɉø?/=Fp¨ ÃÅ#Hñ.§«ø“ûv gÔ&šóû'ìó5Ôr»òó°DT9Æÿ0Ÿ6Ýß»®ŽËÇ¢át½F kEÑ&Óí­ 0Üè1]_‚$A$2ù °@ËæIÖ;rCŸ,¢€ ì<¨Å™-¬úÖ“kœZK wO’â'VUÅ$qÈñ³Úå<¶ÂÆC1g[> ñž5[ RƒK(’ é,äX ¶6¶ò6àä`çœZë4¿é:]Æ»¤é“ØXÙßMkqî£aöÛD’(ä ŽHä‘cfšO-Ê™ª+ÙHö?&òÒg·š=Á¶:±Vƒ‚ â€+QEQVu2çI¸H.ãò¥xb¸UÜRHÖD<èêqÔg«PEPE±„µ}f/²Ke % }ž5ó{šþ`ÙFJÿ=hŠ*[[Y¯®¡¶¶†K‹‰œG1)gv'TI$à@QEQEQEQEQVu2çI¸H.ãò¥xb¸UÜRHÖD<èêqÔg«PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP]G„¿ä†øþâúRÕË×Qá/ù!¾ÿ¸‡þ”µex«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^iâ¯ùõúó›ÿ@5é~#ÿ“qÐ?ìW?úGx¹Çû£õ_š=¬Ÿýíz?É•ÿhÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5ë_´ü…lì"ŸúI-y*ÿ¯÷WùšÏ'þ OñËô+7þ4?ÁJä~0É%ñ·ý€ï¿ôC×]E{džw?¾;[êÖþ>|/Ö¼©ü?¹²Ò´M>ú¸¸œÃ«·F¦ûnG›iæMäp H‰ŒšóHIýu—R<§þè}êÊÿ¯÷WùšK˜~Óm,YÛæ!\ã8ÈÅ~‚ê?ò¹ÿ®­üÍW¯œã¯Å=MEä>Šâæ¤ÐhÏ«rXHARA‚+:çöŽñåÌ–÷Z~‘isH.t눤B@#r´ÀŒ‚#¡½~CS ÆV­7MÅêßÄ»žúÅSŒUï÷çÆßù+¾(ÿ®¶ÿúIQÔ?ä™èöÔôMdxľ,ñ¡­j"Ü^^º4‹k$cliÀfcÑ~¤Õ‹Ÿø‚óHUÆ»©O¥„HÅŒ—’4WWa;p001Æ¥~¥ƒ¥*jT§¼b“õJljRJS”—VvÞÿ‘‹áNÿøõûú^ï¹ö_í ¿´y¼¿+Ìߟ—fìñšóÓÿ„§YþÄþÆþ׿þÇÿ Ú_ìÿ{ú¼íûß7N¼õ¬Êì3 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(èxŽÊø®(ßþ'ÿmXܸ+æ´Vðê/‰wÊÏf©ž ´#D™à4Û;U×ü?á±ei'‡õ;kYîïžÚ6Ÿl‘«\η$nA GÊB/ÙÈ‘[÷»¼ýµKÖ¾žôÝÎo'ó<ëƒ+y’y€‰76rw`sÔ1ÏZ–{S·Ò'Ò¢ÔnâÒçq$¶);$n>fLí'å^Hþé@3ñæ4«wRŸK‘‹/$h®6®Âvà``cŒJôM6ëL¶ø…ám?é²Ùj–ÚU¾£ö«u‘¦óí`VhÛ¡#Ì. ÅË33 ª¸^Õìlt >ص¦…{*<‚ãVÐa¾¶»ýã8Ìèò ÂùA#—tY$r¼Jê—«}軜^Aåù7Vó#òÀíläm  c QŽ•FñŸˆ<;jÖÚV»©i–ìæF†ÎòHP±!HÀ>€;m:ÇKð®™©^êqÿfk «Üi÷ðé0jÑY**•Œ,ómMÌeÎöaÚÀ+ïŠ?ì6Õ|c}ý‹$öPè¶·PÛÞ@-æi¬”"òÒFwm±°ýÜ…QG £kÚŸ‡nšçJÔnôˆCMg;BåI©*AÆ@8öš¥ìÓ^Ë%Üï-î~Ôí+Ÿ.ï9ù²ê­Îyõ³7î üVÚ^‹da¶6«iË'˜\YUÃ8/˜~rª2Ä–'c⿈®çø™®nŠÀgê÷^NÍ>Ýwbc7<ïº?ÖnÏ9êsÂÕíC^Ôõ{[;kíFîöÞÍ<»hn'iÀPBŒ*ŒAé@Ž¥ˆµ‡­©ý“L·Ôí‘u ‹8!³@¦þâ&„PŠDj>b?„g5VéßZѼDº¦•i¤>Œˆ-VÞÍm^)ÌéµvÆé—æ¶%-'î ÝÄ›¸ù®¦¸ŽåšIR1ĮĈ×qmª; Ìǻެêö§«ÚÙÛ_j7w¶öiåÛCq;H.Ú€’aT`zJôíZëL“â¼5oáý6%V)ºÝLñÍsL’G( ÈDª#\ N ³vò:²Ú¥ë_Oznç7“ùžuÁ•¼É<ÀD››9;ƒ09êç­V ÖÖkFðïö&Ÿi¨]jèþsÜiÐß;\‰Þ5·A"8RÊ}ª<$Âö>"&®ø¿XºžHïåñ5ý¤Ž4{}Q!Œ0hÁI¤UŒÈL¸b·’B• û¼ŸO×µ="ÖòÚÇQ»²·¼O.æyÚ4pF׀à ÃÔúÔ¶>)Öt½NãR²Õïí5ÞuÜ.’˹·6ç'$ry#4Ö^[éšþ³¬i6|–’ß[[^iïqh¶óIre¥‚%ÀyY"!­ÂáEcëÚŒˆm ÒRÂát˜~ÈnZÞ+˜®åùŒ²ÊRU.î#b¹òÖ.23X?Ú—¿ÚÚ_kŸûGÎûGÚüÖó|ÝÛ·ïÎwgœç9æ«P¢j]–¯ñ"Ö)­ >‘mv¶VÑ,Ü]1&H‚FlØ]©†%ÈR ²ôÝA¼i©éVÚÕ­…–’u+{{RÊÆ /³$ŒCxÑcåU˜å07甹ºšòA%ÄÒNá0Ò1bT*®O` ;j½­ø§Yñ/“ý¯«ßê¾Nï+í·/7—œgnâqœ ãÐPmâMCD¸ÑµËí.ÞîÍCn<7oaýžËô/…¬lµOiZ•ÇÙ4ë‹Èa¹¸Þ©åDζæà`rxæ»oj%Æ®XGiv÷vh¢qá»{ìöYãBe™&y˜-%-–u,KkÍ«NûÅ:Ω¦[é·º½ýÞo·É´žåÞ(¶®ÕÚ„à`â€='VºÓ$øão [øM‡IDÕŠn·Sɪ…Ö®ôïµÞA òGl »e1ƒ.e;ö弓°¨ŽÓõíOHµ¼¶±Ônì­ï˹†Þv'\µÀ 0Ã0Áõ>´hÚö§áÛ¦¹Òµ½2áÆÓYÎйRA*Jq=…zƵmck®k𶏒Yêö64gM"¡oæY ™ÚÑÚ4P¬±Ç’ ¡” »Š2ãÚ Wñ……Çöt÷6/¡jÜ´¶éâíÒ ²$†4ó#hDPÊßb7g>k¯jv:”:…¶£wo ⺊vYQByaUÁÈÐéÇJ.µíNûR›P¹Ônî/æC·RÎÍ+©O,«99 ¡ÚA=8é@µß&³kkm‘¦éPÛ<±…ƒá2¯#³;€T‘½‰Ø·h\z( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“+þÑÿò±ÿ°Šé$µä«þ½ÿÝ_ækÖ¿hÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5žOüŸã—èVoüh‚$•Î|HÕ®ô‡~)Ôì%ò/¬´««›yv†Ù"BÌ­‚8 Etu›âM ßÅÕ4k§’;]FÖ[9^ªH…© €pN2Ò½ãÃ7>'|=ðß…n¾-èÚ7>,{ÁÞŸ]´½Ô¼? XÜ\Ç¢Æ9\èè‹6 ²4$þk,LYr5)”é×C þ©ÿ€új·âü@ñžŸâ=7Xø›­][øƒJ:>¨ë¤h±MwfDËä4©`hÏ· 6™\® Pê ^ÂåTcÉ'€>Þ½øk£Åy:%Ö¼deþ-C€ýw¤‹áφBŸµè–šÌ™â}q?´¦QýÑ%Æ÷ Ôíh$œdœàÞþÑå¼ÓZœ«HÌöeß ŸúåPÿÃCøþƒ3ÿà²ïÿWã(æ°­'J5®ÖRÚþGÑFTW3_óßÅÝ:ÏIø¥â[K ;m>Ò9`Ùmg ÃfÖpŠ$žRM?S“Kÿ…q¥\Å XA¨ÜÞ\Y½òKrdÄ1Û0p­)MÌepß.0Fâ©üL×ì|Sñ_Õ´É^{ ™a1JñÿÄz5Ï‚ì´Xt›ø¯-f’ånßPGŒË"²f1;qÚ7ä9-_­`yþ«KÚß›–7¾÷²½üûž KsË—k³bÃÃúWöþ‰á)tøæ¸Õ’ȶ²dO—QÇ"l@Þ^ÄóPef}¯‡MËåðÖYøÞy,µ94ù%ñ-‚E¥ø¸ ùJ« ¼;çEU‡U;r¿Ï¿“®Ó0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(gÁ_ò9h?õÿoÿ£°n?ärñÇýŒWßú2·¼ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£(Z(¢€ (¢€; NM/þÆ•sa£syqf÷É-É“ÇlÁ´¥71•Ã|¸Á Š¿eðÊÂmgKÒ.¼G®£«Û[K`‰mæ§™< "$å_1î#n ²ª•-â=çÁvZ,:MüW–³Ir·o¨#Æe‘aY3€¸„mò –¢ù>6ÐüCö<ÿfgÿ£y¿ë~ËI÷¶ñ»ÊÏCÝñÈ«àË ]FÔu-v;ÕmžH#X<×IòÅûÅVܱ(& |øD“kí¡®xJçÃÚdsÞ·—x5+½6k\å=ºÂXï†É˜Ž8ùs“ž6.¼Cá§ð÷†b¹ÓnõMJÂÂHœ-ï‘n­ö»‰$O(³ŒH¤”‘r©ÔKãÛmOLºƒÄ:GöÍãêSj±]%É·ýôª¢e•HxÜÇÂyl6®3Àÿ x3C4=[½»•/L‘!·´ “ ˜â‘£vó•£Ì ¹CÉÀÀÇk0é]*éW—w¶åi/-VÝÃdäY$cç¹ãŒ›ï\ÜøÛNñ4V°Cyeö'Hv{xâ@v PªÆ,í\LÔVZ§‡ì¼Ki}—v¶ÈÒýŽúxîüéÔ1Œ>#Œ‹ùa×Û¿$`a|9du 3÷ ²{;­OT’ «3J¶ævµFWlp¤d2“­? 0(Ò|;cñì/ig‡e}^ËH‘- ³DÂçÍÛ.Ùdf žSdoÃ\*KówˆïtýmõV¶]K拃tYþв«$ªç!¾uw ó85³oãxt ­=¼=§Éeok¦ñêéçžÞVæTŒPÏò¨ïl±ùBci'ö®Ÿ­ÝyÞWömšÝìÙŸ37÷9ãývìó÷qß#§Õ4Aàk-B×SÕžò[ËÈRI4È×Í1ÅnË´Š ‡ç‰ÞÙ_”f­çt˜4ýzÃEð÷öež­Fóî¾Ó,D\E*…¢Ÿ-DeBu%÷;>Ô ™k¯Ù7†²5 î<‰¦¹³šÚåaòå•#VóFþbþæ2”?{“‘´bo‡PÅy§éÃXŽMcT¶µŸO³Hƒi¡ŽA®÷D³ìLƒ’78‰\󺾉ý•§è—^w›ý¥f×{6cËÅÄÐíÎyÿS»<}ìvÉë5èvš¦›ªivWsë¶VzÅ}%Øû4wZÄ›¼$1(Èq™ –PHe;Nd^3°:“ms¡Gs«i)$6w¯>`hÚF  e"B$…pʧp® ‚±¢x+Ö¾0ñ‰¬j7òϦÿiÄ¢ÞÁLn ‚R²îóÔ† Á¨°ÄŽSŽÊ+éO¸žêÌcd·0,279Ewœ¼xÁã Þ—ƾo5_TÈÜÅÝ –*»˜v'Á–^#Ð|3cᆞþêïRÔVK›»‚]±ÁjämågT]ìËÌI#w ëØó\¤°ýªÂö³^[‡ØÒE½_å|¬ÁQ˹Nì¾=¶²´Ò­4m#ìVÖ3^; Ë“p×IsqJ’©Œ¢2å¬1†Rì[ø\š%­ýܺ֓¥½ü6W7æŠÖ;y‘ ‘üЫ–R>@3»Žv_ \Ø[ø…õûº<ËfñàI¾é¤+äåO$s¾îW÷XÎYj-fûCšÕbÒt›»7.Iï¯ÅËà¦È£Prrü«‚¿6é|CâÛŸéš=œËµl!ØÍ|×Ú±‡à ¸†xñÈýÎî¬Ù¿&›¦‡—w–7R\Ü-ý”w+u§¬o47'lR‰˜²ep(»¶ÆxÆ*%ðΓa ë:Äúv©q wÅŸI"ˆÍ 2åY\„IV[(2íõ¿#Ã7úG“»íW–×~vÿ»å$ë·ç>~sž6÷Ï‹âm&þ&ÖtyõRÞíã–+ï" R4 š1fª¡(ñ’ª:6\€iøkáeî³¢[j·šì–·›±Ñ4v¿Ê«fsæ"§Ì¤Éo”’-ÉëÚ4Þ×u*å£{‹™-eh‰(Y©*Hd Ô²ñ™s§ZYëºmÝø±FŠÒ[Õµt¤(û¢0îÀ€ÞÀ–Bá]L—SKÛ#¹e‚"Å#ä*î%°: ’}I ‹Á^ ÿ„·íºþO³leÒl~Ûvû·|â-éûµÛ†}Ü3Æ0wdK£x êz}…è¹¶Ö­õ;ingi4†]9|´i~Ô_“µJ‚#*Ï€©y?ø¶çÄ:fg2í[v3d5ö¬aøn!†Þg›ûÝøÛ¿ž_îëNÇâ.›¤6—‡s¦XMzÓ[ÝÞ´’]Åupʯ"ªmmˆÁY åIR\Ót׋Bº×ã–=öö°,À²£™gƒeHF • î禧ŽçÖ>¾k{K{‹½-¤Ÿìv±[#°¼¹@Å#U\íEÇðŠ‹Rñm”¾¹ÐtÝ'ì62^Ax²Í2ËpYeo2@‹¿>pÀUBp¥™Ù²õ}oûWOÑ-|Ÿ+û6Í­7ïÏ™›‰¦ÝŒqþ»n9û¹ï€Û^|Ôôû Ñsm­[ê6vÒÜÎÒi ºrùhÒ:ý¨¿'j•FUŸ1RåÉà+ ÆÿPÔu+d¼Dò¯¢Ò|Ý4Hë¸!¹†%y6edm¼ÑÕ'ðçÄiþ#Ôµ†ZÕ­¿‡ô£¬jˆº¾‹,Ö–`LÞ{D—åö‘ûp§q‰Âä©äÆÞÒyTÈŒÀ™5¡ñ;â†üUuñoYѼñ`kÞ1ð”ú¥–¥â^ÆÞæHõ2J‡Xth ¿]yE ò™¢PÎq‘©B£Nº9oõOügÐûÐÒ«ð+5óx7Jºš!å¼ïâÛõipX…¶Už~UÐÅS“öaþÕž[…Ô¡ð´d€º| &ª€>a4 Œœü¤6:†Á ¿Bj?ò¹ÿ®­üÍW¯Æåc0ÕçÉ-›Z¹>½›hú†§8«¯ÈøƒÆ¾oø¿VКôj"ÅãQr ò7††9>æ÷Æ7ão¼-¬éze¾¥{¤_Úi×|›¹í"—rî]®F@$`òk¢øÛÿ%wÅõÖßÿI ®žk- /ĺ^–¾µMFÙm´›ÏíBn¯cK¨eÝ>ùŒP[˜H°’Ä*¯ÞQúƬ«á©UžòŠoÕ«žH¨ÎQ]Åx#áæ³ãNÂ+-:ýôéï#´›Q‚ÍæŠßs(fb8ùC ‘Ç¥cC êw1ÛIw*\ºG$ D¬ìꊤ˜³G u(Àt5è¾K]SÇ ×UÓtíM}:)Ròò8^ÙâòüÐ!ÎâPòoE)ûâÎÊ|ͱA⟳x ,¡Õü¦O Kn¶és‚%“XD Þx@,:”9ØfqÞð~¡ã N(-,ïæ³Y£K»«+).¾ÊŒØÞÈ€“€Ôí V]ž—{¨íû%¤÷[¦ŽÝ|˜™ó+çb ¼Û[©ÚqÒ»¿íK/øhoí/µÁýÿ OÚ>׿¯•å}¯výùÆÜsœãÖ>‡®¾“ðóÄvö÷QÁuwd›2¾kCä݉6gææUb¸âB¤áÈ æ§¥Þè·ÒYj“Ø^Eö÷14r&@#*ÀAúU«§ñŽ©ý©£ø;ußÚç·Ò ¼™—{E¶îçbr1LÑJãŒW1@Q@Q@Q@Q@Q@Q@Q@Q@> ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ•½à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý@ÑEQEÖ_xÚËB]Tx¯E¸·‘把;ÍóI£2(kpÄ‘à±æëÁÆ7ü"ÚÏö'öÏöEÿö?ý>ÌÿgûÛ?ÖcoÞùzõã­_¾º…þh–Ë4mq©#ÂoUhl±@%ßiô5Úøn=L¶W‚= ºÒ&µ‹S¹ÔíÏy=›ÆÑ„»bQ3ºy’ĈA.IV`;Ó<-¬ëSGŸ¤_ßË,&áÚÙägˆ9Bà(9Pà®zd֢ѴOÄWMm¥i×z¡‘¡³¦p €X…ã$ ûŠéüQ¯^iº„4ËMF8ßN¶’I>Á:1Žåonб’2rUX2…—É;>3žÇÄ:Ÿˆí¿´ ÒlåñýäZ¤©,–š€,¡S|(ä´a·/ 6ܹÊdy€'ü"ÚÏößö7öEÿöÇýþÌÿhû»ÿÕãwÝùºtç¥QºµšÆêkk˜d·¸…ÌrÃ*•t`pUäF5éÞ*·WÚ߇ìnãƒP’ÛH‰%¿xí7Çof©=¼¬Ï¶7ó<¶hݶî·#%ÕqÞ2º†VÑíhî¯4û´¼º‰ƒ¤² d*A÷ÂFÑD§î°¤ R@0­mf¾º†ÚÚ..&qPĥ؜P9$“€YÖtO÷Kmªé×zeà ‘a¼¡r¤ã Œûµák ½~µ#ÙÊJQ&“ËŽI„laß#j4›+…bw.7þöëI²±ð»ÜYèI‹«½î«¤éW¿iV†Cj/3‰Ù„/•‰ÙTmß´æ€8ûo‡šÉðæ§­Þé×ú~kgÜ73ÙºÅs¾h£UW8‰K‚3¾ù×Z§bÓ-ÎwnaC$¢Xv(—Ê,Ù ØIþ/—¯ØÃ§>—¡øÎ÷Q×tÛëJÁ»G~³ÏxÆöÚF“nK)–+(Gäü¿+íì|Aã8oµme_]ŽâÞmSÄÒבÔéë«uÁHÏÕWÒ€<²ÏÁú„Þ¾×'³¿·Ó"„=½çؤkyßÎHÊy m\ns’q”ÛÔŠ«¦x[YÖ¦Ž-?H¿¿–XMÂ%µ³ÈÏr…ÀPr¡Á\ôÈ#­_ð½Ô6ú‹ã–hâyô¸ã‰]€27Ûm[jŽçj±Àì¤ö«Ú÷‰î`ðׂ­,5+ìvmpâÕÂÉÀ½º(Y—æÜªÁ”ò‰ \o$€fxCÁú‡Œ58 ´³¿šÍf.¤ºû*3c{"NbS´T4mSñÓ[iZuÞ§p¨dhlàiœ( !A8É>â»oíK/øhoí/µÁýÿ OÚ>׿¯•å}¯výùÆÜsœãÖ?‚$šk]BÅbÑoíäx¦}?Z¼6ˆìÂʲy‘  ‘—o™Ï›­´”ˇÁž ¸ÕçҢе)uHI-ŠYÈgxù™1¸™y#ø‡­Zñ/ÃïxS]þʾҮÖâK—µ¶e·“eã+Ì$¨2JãËëGí-l/ìí¬îäš(­€û+ÞÇz,ɑϔ³ÆrŸ3(R§æV'¬™àƒãž›â¾°:>¡â1 Ê^ÄÛ`7JáåPÅ¡ùXHŽr2<ëû.÷û3ûKì“ÿgyßgû_”ÞW›·vÍøÆìsŒçÕ­oÂÚφ¼Ÿí}"ÿJó·y_m¶x|Ìc;wœdg¢¯Ûø†oëº|>$Õî×F’æ¹òØì‚f»Œªd“bªáw+¬Öà¶ojzdvÞÒu3yo¨]3U3yE³y#-ºU 7˜~c°¦€9Ûï…^-Ót%Õn|?©Co¾e•^Êex5F2H áP‡á‰þôª~Ô&ðåö¹=ý¾™!íï>Å#[ÎþrFSÍjãsœ“Œ¦Þ¤UøàÇÃËKk{‹E¸Óoïnî!¸ºŠò䆨!A#)“ ƒjn##æ\Õð½Ô6ú‹ã–hâyô¸ã‰]€27Ûm[jŽçj±Àì¤ö  ½?AÔõ{[Ë›:îöÞÍ<Ë™­àiÁ;œ€BŒ+ŸCéF êz¼–ñØi×w¯rï+oHedPΪ9*¬¤ÐOZéíQõ­í¥ê¶šCèÈæé®/ÕâœÎò ¤\îù~Ræ Ò~à ¼Gº×‹üWkyáYíôfŽÆÂÿÄ•ɰD$ŽÙ…«BŒ%S+÷AÚZ!Ô  …ºµšÆêkk˜d·¸…ÌrÃ*•t`pUäF4ZÚÍ}u µ´2\\Lâ8¡‰K;±8  rI' è¾#jŸÛ^%ŽôÝý¾YtÝ?θ2ùŒò‹(D››',09ç çš‹Á·PÄÚÅ£M­æ¡`Ö–wR°DŠC,eƒH~àxÖX‹týî„,@Y¼;6…«Áiâk]KBGC#o±&}¼…eŽFp,1ÿ\bèPøwYû%µÔ—¶ímmuÒÂ!r³AÀ2``áJ5Ý*óCµµ´ºÔm.ù%KK;äºH²-4`¾Ð0wîÆàÂv5é4SÇ ¾½Ù£µž“ åͳoh‘m-Òl`7̸qŒ ‘Œñ@Zß…µŸ y?ÚúEþ•çnò¾Ûlðù˜Ævî8ÈÎ=EKsàÏYéU¸Ðµ(4²‰ ¾’ÎE€«cko#nFyÈõ®Û[‚Ù¼ ©é‘ÛxkIÔÍå¾ mtÍTÍæAW Ìdy䌶éT,HÞaùŽÂ6š5hcÔ!Ôõ}Bm&ÊúHg”kZ.²†Kבw›hdi?|NͨˆÄ¬]6©Uâm¼â Í ê¶ú¥>–ä7ÑÙÈÐ\îmàmÀÁÉÏ>•‰ámgľwöF‘ªù;|ß±[<Þ^sÛAÆpqŸC]Þ“ z¼:eî¥6“mäCÏØk)ol"ED-lòn%T ‘Ä!‰JÈs¹âÑïlõ è¶6º?‡¯åÓÒUº]kS{ó^Va"´ÄŽ?)7 ¸ò°ØQ@8ÂÚω|ïì"ÿUòvù¿b¶y¼¼ç¶ƒŒàã>†¨ÝZÍcu5µÌ2[ÜBæ9a•Jº08*Àò#ôHu¼[u¬5âx{Y·›T¹»håÔŽœð4Å|É­šgŒáhq.Ï(nA»Çxº8a×çŠÞúMBÒ(ÖI&ñ'Ì,‚xàDèò¯9ÔŒŸÙ×YEÊâ>‡Ú€=2/]B“ÉñgFäPíþ6œÈ„òCmÜ»‡|1èOZ«%—Ä'žUÓuøžÞ2ßøkR½ÔmK`¾ddá†FU‚°àãIû/Qÿ…Ïýuoæj½~VøƒØÖ’©EI&×E×ü'·õ^h«Jßשð~©¡­xšºê)ª‡_´®ª%!¶.ÝþoÍ÷6c=±ŠeÕ¬Ö7S[\Ã%½Ä.c–T«£‚¬ ‚0A®Ããoü•ß×[ý$‚·¼o•âOˆ¾2ÒbÒc±¸‚çS»]LO$“¼‰¦uu-å”mŽ *+.P–}­¿ô¬-U_NªVRIÛµÕìxó,Ü{YEz—†ü#¢®—e¬ê..­­®¯n.F£öèx’B!X“ÉQÆÝûòÃ-€v-_‡~Óu6Ñl5¥Ñ`:ÝÊ­¼—/{öæ…¥òwCäæC¤|Ñ÷†Xl#=DmZz'…µŸùßÙEþ«äíó~ÅlóyyÎ7mÁÆ} v>ðö¨xVÒ]KOžâêâmUšâÞèÄË­œW ª ²†-•ÜA]ò¬v4=2ÛJøÕáí#ò žóH¼†,±™– ™’NÕ22IÀ$ä;©nmf³Gq 9D,ŠT•e ­ƒØ©àƒÞ¤Ó/"°¾Žyì`ÔbLæÚ夾A˜Ù[Œç†Ôq^s£éZ¿Äqì2[é¯áô¼háy&0¤ —g™&æÀmF|aBçæÔW¢i:‰ãÍ2Æ 3ûðk¶ZPºK‡¸óa¹Y@iQŽ ˆaÎSËVÞFÅÀÄ^ µðˆÐ5iu¢‹¨Q ösj/u3yˆ¤LÓÆ±å™”TË*à• ŠôMRÇB½Ó.Î…¥é:¬p»‰ »º‹U’,r·—#7Kä#  '1‚®<î€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(¢½›]Ö¦žÐéVÚÎ¥2øfцw•Ó•FÉ"~ñƒº&ù”»ƒ3*¤™–^ðŽŠº]–³¨h¸º¶¶º½¸¹Û YâI…bO$GwïË ¶Ø YZz'ŠuŸ yßÙ½þ•çmó~Årðù˜Î7m#8ÉÆ}Mvßü)¦êm¢ØkK¢Àu»•[y.^÷íÍ Käî‡É̇Iù£ï °ØFbðw‡´ C¶’êZ|÷Wj¬×÷F&X­lâ¸UPU”1l®â ï•c° ¢x[Yñ/ý‘¤_ê¾Nß7ìVÏ7—œãvÐqœgÐÖez&‡¦[i_¼!¤~DÞi‚Å–32Á3"’IÚ¦BI8$œ“Âi—‘X_G<ö0j1&smrÒß ŽLl­ÆsÃ@ê8 îmf³Gq 9D,ŠT•e ­ƒØ©àƒÞ¢¯I¹Ñô­_â8‚ö-ô×ðú^4p¼“Ò˳̓s`6£>0¡sŠ‹IÐtOi–0XiŸØƒ]²Ò…Ò\=Ç› ÊÊJŒpdCržZ¶ò6.<îŠïüAká jÒëEP¢ìæÔ^êfóH™§b#Ë21(©–UÀ+\§ÿ¶³ý‰ý³ý‘ýÿA³?ÙþöÏõ˜Û÷¾^½xë]?ˆ|O«xBêÏKѵ ôý/û6ÆâKŸ÷¼¶±K)š3ò˹Â}Õ 3<#ÿ"ÿ¿ìþ—ÚP1EvÓ,âÓ%Ô5hô!g<ÆÞÞMm¯¾gU¤-F±ä¸ÇÌ6ôl_]Þñ‡Št«Æ´sc%­›k†äÛ˜’GV,m@“Íâ‹„¯e‚;×–Ê=º³¸ž!dæUòɉeˆ9 6þåÂ䤪FÄnsƒÒ€=êïöÂ2]Líá‹(Ù‰C­r§=?ÔRÇûXÜÌãð»¡èË«’þ@¯`ÿ„ûJÿB´ñ–·okmû˜bŽÛNUD^@˜eÜüð¾³u5çˆ-î™ã}_H±ŽÖÚhß"ilá–{|’ß¹™ÐÉ–a‰a‚I£LñÆ·£XÇme{öo'" ˜âAs$’±O·ÌI,J£w¾GÌÙ4ï ®­¦<öš½„·é · ¥bqp5gs¸ÇåpˆÏ3$ ·ËF™áU»±ŽîÿW°Ð Ÿ&Øß‰Ù®$3*Å ‚»˜H`¤•`½DÞ7Õå`DÐ@£íŽÚÎc_>‚l" Qº4QÀë’0I&ªx›R[±ÕÖçÙþÏ7–¿'¨±qŒ¢4ƒœsœšè£ð*OàûKé&´ÓÌZ¥íî©4Í%º„ŽØÄ€Äy,ò•òÛî!e̽ðiÒfÉ7õyX4(ûF#¶³†×Ï`›ˆnp:äŒI<9áUñ.È`Õì Ôæ˜[Ûi³‰Ä·p+,f1¹ŽÐ]Ôך4Ÿ ®¡¦ BóW°Ñlä™íá’ôNÞs¢£HC„mG’À¼c88ªž&Ô£Öìuu¹Æ£cö³Íå¯Éä*,\ch çç&³+¢µðišKç›XÓmtëGŠ3©;Ë$4ªÏ¨Ž7|²£œ2 »J¾Öùj/øD¤—Sû=¶£ayf!ûLš”.âÞƒmg2‰ òíd ĨEm鸯ü$Ú—ö‡Û¾Óþ•ö?°yžZÿ¨û?ÙöcÿUòç¯|çš«§s™q§¤˜³žhî$hùž5uCœd`Jü›žƒÇÀsÍqeö-JÃQ±ºóÿâaš±EäF%ŸrÉÉòFÊçjƒ…ÜÙQCYðý¾›j·ºæ›¬&ðŽ,ÌÈñ’ Y£˜7* Än\€K©øßWÕìdµ¹š³cÏš+8bžã7ï¦DK–Žö9`ä€k ŠôOÁCÃ~²vÓ¼=¨\]ØKu=寻šÍ$w*²±©$™rËÎ6OLñ¾¯¤XÇkm4aÏ‘4¶pË=¾IoÜÌèd‹ K Œ0İÁ$Ö]ž§sao}lŠöop»AÞ‚DGÞd™”±ȯY%ùß÷¬ ÍórkT±þËÔîì¾ÑßÙæx~Ñjûâ—k¹ºœdàŠéü!àë/xOÄ·²K:jv^_Ø‚²ˆN!¸¸—ÌàŸõV®n>b¹à’3?á7Õÿ´þÝçA¿Éû?ÙþÇÙ|­Û¶}Ÿg•·ϸßóýîj-CÅÚ®¥ugpÓÇhöoæÛ>Þ;4ŠLƒæ*ª¡þUùñ¸ì^~QŽ‹Ç^Ó|1¯hú\z—ØüÛ7ûmÞ¡¹âK¨§ž vyQ—òËÀv|¥°À¶9Æ烯aÔìm-%ƒSKèMÅ­Õ³2E,JήäÈ¢¡Ž@Å€›îáˆ}ã}^ûìøš "e¸û2Î/Þ¯Üsä¢neÉÚNJîlcqÉ©ø×TÕld´X[A.¢ÃM¶´i …fŠ5,¹ ÛI#*§PFdžü§\xÃÃVͬiºõ…Þ©miu ›Ï…yÁÇFá¹3·Œ•,¹£wà Û=þù¯lëNòÍþ”%awh®Û:• pÅ•™Àp§ sWO7‡m-ü >©冣?Û-#sÜ,¶{âŒL£n)Ë+6 X š½gðŸSº¼²³’ÿM³½Ôm¢¹Ó­î¦hÚûÌ…eUŒíÚÌ#Ê«>åVb­€*ŠÝÓ<*·v1ÝßêöäÛñ;5À†eX£s´Ws ’¬/TÓ.t]NïO½É¼´™íæpmެU†A àƒÈ8  ÔVî¤Y>™}¬ê‚y´ë9¡¶6Ö’,RË,«#'ÎÊÁd$íc«˜²ŸÙZö§Oebù×/©È®¶jk3JŠ7¯+Œ bÎU›ip *+§¶ø}¨jz­½–™4²]Cq-­Õ˜‘£¸0ÄÒI‚Ę\le,‡îº±/¼ %Ž™o¨lé76fñlnä¶äû ¬»€Ë) &!"·–ÛIã ÅØx«ÁZ^…¡iÖ¾$°¾žêÌÜ5¼isºcö™bÌ[ PAʾ2 æ;Ÿ†÷ö ïï´Ý:),þØÝ\ìk•hꑦ7Ad @BèÈvä變×ÁWV°ÿ¦ZEª\ –×GÉö«„a•*‡*ŒÊî6íVÞ›­hK§j~ñRèÖ‹{§X%ÔZ’I8˜ÞA|Ï,’°á@zò@9:+cFðÙÔíZîëP´Ñ¬˜’îøJRI¢,hìÄ !p¹]Ä@Õu½mQ{9Ú9HåIb$¤±È‹$n¹€ÈÊÀ0g(ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWQá/ù!¾ÿ¸‡þ”µrõÔxKþHo€?î!ÿ¥-@^*ÿ‘_Xÿ¯9¿ô^—â?ù7þÅsÿ¤qךx«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^.qþèýWæk'ÿ{^òeÚ?þB¶?öOý$–¼•׿û«üÍz×íÿ![û§þ’K^J¿ëßýÕþf³ÉÿƒSürý ÍÿðD’²Šì øŸ„¬ôIb¼Ö­K}Òét¢ ]M¼æ“ÌšMܬ±b}Ë Ã?&_‡õÝ#Ãò^Ãeâ?éöò:îhlb’;Øö’{c8\)2 3H®¯‚«‚“³Ó.oíï§‚=ñYB..pÈ‘ƒÉçç‘O9è V ÖÇÅ:e¯‰uëGZð¸™#»ÑQUäÀ]Ь‘„8mY6Ç€0Ã-¨~!Zé>"žãI{½>+»aw©éðGarOš$G MåÆWdhQ[*6YBËÀQ@®±âøu_H’ãÄž(ÖÑÞAy(Ií˜ãkC’LeO˜»ø_ÝíÞbñ‰týkLŠ%¾¿×µ?89Õ5;(í®°(βÈÓîÊ`ÈÙŒDxcŽ>Š+c]ÖaÔô¿ÛD²+éÖk)pf7S˕瑶Uã~§Šíl¼_¦G©i~"˜]iil°YÇ›YÚÝ!v¸d VÜU°é¼yxWZÌ3ø?LÒ•d·÷wNÄ …eŽÝTœç0¶xî:óŠº7ˆµÝ;J¶hÒâúæ;XšRBv  ÆO8¨Ð]?†Ì]ÜévÖÚ˜[‰âXç–{»CJeD]± ncö~`‹…k¬Ãƒõ=)–CquitŒØ(î9Îs2ãŽÇ§Ç¢€:-GTÓ5o iqK-ݾ©¥Û5¤P%º¼©¸’mí'˜ï˜mßpüß-_ë0뺤6ë""XYZ‘ î†Ö(˜ðO£${c§JÇ¢€;[/é‘êZ_ˆ¦cÄZ[,qĦÖv·DH]¤.#BÈ·l:o^…¬Ã¦i~"¶•dgÔlÖ"€¬. —-ÏlL8Ï$}F=ÚøCdzhúÑ›\Ö¼=n—/v—Z%ägTFI#óc 1•mß/Î0ÛÁNwÄÚ§öÖ·swö»ýC~ÕûV§/™q.Õ ¹ŽN3Œ…Ëm]ÍÇ2Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+¨ð—üßÜCÿJZ¹zê<%ÿ$7À÷ÿÒ–  ¯ȯ¬לßú¯Kñü›Žÿb¹ÿÒ8ëÍñWÃ_‰ÖºWʼnZýƳáýbÒÃÂW>’+–âÒxà€J4xæUW‘v³OŸ•w³ ÙòÍJ6u×ïþéøÀô>Õe׿û«üÍÂ. ’&$+©RG\ŠýÔä!sÿ][ùš¯_IñÃâ²3¿Šg,ı?b´äŸûcQþ?22ÿÂQ6þ<­=ÿéµ~][…±µ*Jjq³mîÿùÚŽ6šIYÿ_1ÿ䮸£þºÛÿé$é>*ÔeÔu~ „‚HåÔ¼Qnãìñ‚b·´YaL…ÎÕ•Œ¸èd>aËüÕá:Ʊ{­êwš®«x×—·%^k‰;QPpŠª0¨;v®¦ßà׎î­âž/ Ýyr(uó.-ãl‘”yC)ö`è@5÷ÔgK/ÃR¥ˆ©µµvM¤“µìyrR«9J ½N›HûoÚ4_³ùÿð­¼›Oí}›¾ÅŸ->Ùçöó¼Ï3fïÞ©ò¸òk3Ὴ|Mýâ HÕõo?û4giöW2îó~׿“œîòüæ;Fvï'Œ× â-&÷“iÚå¹Ò¯‚‡òn9SÑ•”•aÔeIu 0Ï–ŠD‘AÆQ¯BH©ÁÝ>¨É¦™è µïi´›gÔu++‹ÍjÚ=JžHÞvóÀu˜d9g7«g©ªûoöf©ÿÿŸÿ gÙ>Å»í_fÛ/ŸäãÙò3³çÙ¿ø<Êãè«êñßfA¯Ý\ÛÁu¯ÇáÄ:¬wi¼}³ûR­*ýÖGä3+g.J¼Àyßk·þ&ð†ïõk©5øïïìÅåÁß;B©k"£H~f ÓHFâq¼ÇÅQ@Q@Q@Q@Q@Q@Q@Q@Q@> ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ•½à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý@ÑEQEïÚÿ‹m®üGâ]ý2)µä‘r~TŠND~˜;Íó®ÊýŸ';ÆÞcHûoÚ4_³ùÿð­¼›Oí}›¾ÅŸ->Ùçöó¼Ï3fïÞ©ò¸òkÊ( DøoâŸcøƒFÒ5}[ÏþÍÙÚ}•Ì»¼ßµÀï䯧;¼¿9ŽÑ»Éã4hßð“f\ÿ`kÂeý¥qý±ö?7ûCÊÛ—»¼ÛæyûñÆížg>UyÝéÖ·ÖZf£ã‹«{ ¡…jdŒ"½·ÚþÑcç2ªüŒ¢1‚ŒÄp ‡…<_âwÄK/“w«ÞC`Ö¶é¥È–·¶ðù¾f- ¡*Af]¨ˆZEPex (ºø¡o«'ödúµÞ­$²ù»-|EÝBÜ|‡Ûæ’pŽv‚Ë1¡ÝžOAÓáÕõÝ:Ææò=:Þêæ8%¼— V` ’œ‘Ó¨ª4P°øÖÓV×< z/t¿ZÖò”ƒÄ:‡Ûnâ´OçL‘˜’H¡Ýår63ÊTºÇŠïîþ&ø÷B :©­ tÔLÁ$‘Å<«3+g2ù‘£ùŸx`*•@ª²»¿ð7ˆã²ðÏü%RKOcgåÜI°yWŸ¼Ä­Æ@äãæéœQgu¨xCÂ~+gÒ¿±µEÕôóE"I`ZÆVŒ9Ü)³n 0`waçtP«Ï©Üë‡EÔå“í>.ºðæl.Š<÷i¨I¶ì|Ó hÙQŽ\²¦ÒdÙY‹ý¿ÿ ™ÿ ןçù7_bÿ„‡oäŸ#Ìó~o'Ïòñæ~ë>oo6¼îŠôé<ÿø•ÿÂÊûÚ¿µí6ÿky¿kþÏýçÚ³ÿ-<¼ù[sü^g—Ï™V]¼kÿgŒGˆg¿]$é±H&›Ž~Ýkµ­cËhÂð QU”.|¢Š÷jO†°4Ä7 6×ÙK&ª£DeŠO,Àz’¬ŸÍó€ L¹Ï'wãMKÂ>ð4š9‚Êù4ט_ˆî/î°¡˜‹Ãd.7‡e}Ë€<îŠõÜxŽãÂÖVÚe§‹,íWzÿhøJF–,ïf&{tÆù¹Û––2#òŽÒßæÚô/o®ê1I=¥Ë¥ÌŠÓØòÄ‹h °õ\1ŒTh Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“+þÑÿò±ÿ°Šé$µä«þ½ÿÝ_ækÖ¿hÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5žOüŸã—èVoüh‚$”QE{džF¿ëßýÕþf¤¨×ý{ÿº¿ÌÔ”Ë|T¼¸Ó¾x¾êÖy-® Ñï%Šx\£Æë•eaÈ €A+Ûþ9~ÏÞð¯Ã_‰×ZW‰ZÆáýbîÃÅ·>9’[–ÞÒy œD5‰&egv«AŸ™wªØòÝcI´×ô‹í2þ/>Æö¶¸‹q]ñº•eÈ Œ‚FA«jº]î¿§ßéZ§‹¼q¨é—–íosewãM^Xg‰Ã+Æè×$2²’ Aƒ@5)é×_»aû§ç#Ðû×Ü—ÿ ¼—× ¾ÐDŒdÿ»_ßFÓY\Fƒ.ñ²êH¯§®¿j¿ Ou4‹¡ëá]Ë ÅmžOýw¯‘â*ªô©¬*m¦ïoC¿ (FOœõ}J²ð­›Úh¶vú=«Èeh,"Xœ€ @8P3ì=+äŽ2<¿ÁæQƒMÑ´M+M»Ö­¯õu8Zæ¬.ÒÙa‰ex¾fx¤ÜÅã~@S–,BEkã{«[XÐí%Õ-ÐEk¬H$ûUº(Â…!£…vVtv²ìM±iž-’ÆÆ;k:ÃUû>Mœ—èîÖ„’Ä( ×qÝåÈ2Xíùßpâ/[j^0ñ~³åÜ[Éâ ûHmF±k¦¹d;¹’ã €$@Tç$’›T?:<£lø– 5o*ÃMÓa¿K‹yì#<–Á¡ÝË+/žñ‚¥A%8̛Ǔßêz¥Ö§¦Øj°_ÞK~ÖW>jÅ ò6Yã1È®¹» î QJÐoÌYÚÚ[E©Û%£ÃeR(ÖX¤Pœç9…f,[,X–%¨-{ûζ/ÛÌB³µþÀÏ(v”'ÝR›ÒIRXn`Ãz'ü$ªÚ¾ÏÃ5ÌÒ„ÞËQ<²m\ͱ À$FeYÓ5;ú;»I<©ãȨe`A ¬¤ÊÀ•*A H  ètÝÅZž—¥è6×ún£yy¢ Fí.b1¶†.‘FSiÛÆ×Èb~]¸b}#FÕ´­J}_Ã.• Ï;ßÈŒ·QRꨣÊmò!òËH0Íóåú·Þ*Y>ÎtÍ"ÃÃòÃ2Ü ôã9—zýÂ$–GdÛ’p…A8'%W§âÙ/¬d¶·Ó¬4¯´`ÞI`ŽvA ÅQw Þ\a!Nß‘6€ušŸ‚<-iâ_øn ÍJ}GOKé­¯”§ ¸y<‰¢³.&U*œeš®’Þ?5› Ršâûe™5(UÙš¢LdÛˆJd¡ÝŸ“æùyçeñì¾)ÕuãóRûgœ[Ë_´¤‰&ÑœŒ ['3žñh^$:=­Õ¤Ú}¦«arñÊö—†UO1„pÑ:6@’AØ;ÎA ©§øCÁöZæ©{v-ýͯحP3Î#ŽÝÔ8XÇï\3äe1a°eø~ÊÖmfxµ+ÍæþâÓNµŽâ8.6Æ#róHcu,± ª§$¹Ê…ðfÖfŸB³Ò™cö·3]#w–•bVçÄ+Ž;ž¼bÖâC¦Zµ¥ÖŸi¬Ø2¥¥ñ”$rthÝIa°»(…@;É©ø'âLJôÍ?W»ŠÊþÿM–A¹‚S‘‰P6 Ù. å€%€$rxM^Ôü;t×:V£w¦\2Úk9Ú*H%IR2ǰ«V~+¿µñU—ˆY£¸¿´¹Šæ1"b<ÆT¢m\@T*à +€;ÿøqüYñ¯ÄÚjÜGjTÔ&’i@Hãids–e\íFÆæUÎ2Ê2E_øSJÓ4!}fÑÙÜ-ÊAö3¯Yêo2²¹2 )Œ!Ep;¼Ñ‚6ó…yâ»û¯^ø…Z;{û»™nd¦cÌ…‹¦ÖÈd!™J¶ARAÈ&gÄú•ªÛÚèznŽ›Ã¹³;È@ e¦’FP2Ü)Pr7µp»ãoø[š¯ˆ´ˆ/u-CQ´¹’ i ˆ¤ÀmŸšCåîË* WLêÛ…­wÂ:%†‘uqeg©_ÚŸ.¹g¨ÛÝ@;Fó[$aíħ$²]Çï”*xí{Y›ÄZܬiq}s%Ô«!;!A$ã'Œ“[-ã…Hgk]I°Ôg†HdÔ-–u‰¤¸ŒÊa]êθXÀPÇh\ sQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÔxKþHo€?î!ÿ¥-\½uÿ’àûˆéKPWŠ¿äWÖ?ëÎoý×¥øþMÇ@ÿ±\ÿéuæž*ÿ‘_Xÿ¯9¿ô^—â?ù7þÅsÿ¤q׋œº?Uù£ÚÉÿÞ×£ü™_öÿ­ý„SÿI%¯%_õïþêÿ3^µûGÿÈVÇþÂ)ÿ¤’×’¯ú÷ÿu™¬òàÔÿ¿B³ãCü$¢Š+Þ<25ÿ^ÿî¯ó5%F¿ëßýÕþf¤ £_õïþêÿ3RTkþ½ÿÝ_æhJ(¢€#_õïþêÿ3Qê RÂ唕aAÁ¥h‘ÎY©ªº”:èˆÔó´zõo©ðÓàw†íu=OAÔu+›ë²YiöZŒÞlÒlg$—˜E w?8ÈeSÃ~Ïß>|lñ¾½ðuJ–ïv°m\]Zϲ‚#›r1p1Cñ’ mlwµÇìÿªülÐt+ß Mm‰t9fòVòfŽ9­¦Uó£‡- Iù%CnMû%þÉ^0ð—Ä›?xòδØg~—öÅšén &I E¢Ùå< ìIpH]¼úu£Yœ)Ó£am]—Ï^žKú]x8püø^¶#‰šÇ©>Xó;[KYu¾·wÓóê|w¢ÚxwÆúÞ›aÅeo,B(ÞW¨h"có1'«×½\Õ>x£Eû_Ûtiá›ÄÇ*Á ä²ä– ›G>_ï1åüÔïŠßòS|Gÿ]`ÿÒhk®Õ|q¢\ë¤ñÞîŠmKÄ··”ã)uh±ÛŸ»ünÇQÕ°+ŽºJ¬Òîÿ3Ì÷*0o{/Èâ´ï IqáSY—Ë–-–H…µõ¹’6ûDqîšþhL3BýæC÷Nj׆þÞø“FÔ5¯tØÚÛÏŽ9õ+XÝÏŸD:¼ªÑœÎ8P>úÕjvÖ?Š`žM’Þé©on»IÞâîÚB8|‘¹ÉÀãH©|{g:îŸyw€Õ,¬wS£´Q2ÜA6_b³`ˆYFÕ<²ç$`twÚ%æj·3$fÝ®f´Y¢™$G’ …•$ˆCî æ·¼/ðãQñ‰lt™f´ÓÃÚn{‹¸ÄwY¤S)ØÁ¶&O *ͺh7þM*ïÄÙ\iz¥ÅÀe´–D¼‚XáRМ¼~Q>bå—Ýø·I¶ø£ kÖ‹;é:öS´yß(Aºd„ ÀÆËœ($d`çf𖣯˜¿d¹º™ ‹öKè.#U,Ï$nÈB³1b6¨Üp9¢ê¶ú—ØLÉ1¶’ñZ ˆåŠHcGwt‘X£€#¤òŒ¿xZšsiÚ ú¦–ÚÍ¥õ®¯`¶­¨ÚG?—lÂxåRë$häf ´+äo+°ÈÚ´šWü#šO‡®¿µu=;R’þ Û8¬—ù(ä@Ï·ÈNYFYÊí!C81™s.™q¨$y³‚híä“pù^EvAŒääDü—ž£7õŸêºªÜ^Á!q‚;ˆåx$ ‘ÊŒZù[ä+|ÇÊØë¯l–±ÇDöщ☴Û×hÝ*쌺üÎwü«¼“¢Š(¢Š(¢Š(¢Š(gÁ_ò9h?õÿoÿ£°n?ärñÇýŒWßú2·¼ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£(Z(¢€ (¢€ (¢€ (¢€ (¢€=;Sø+ý›­ø†Ôë;ôí6Îy­¯þ˶OÎZ/~cæÒíwœÜçéž&ÛÂ:­Þu( ŒÛìyU Äk<‘®wÈ–ókåÕJ“ò6;ýWâ¶¡â=v?þ%2ͬ¼[ï’hnŪlÛ¹q%Ôç'“öŒ6.1ìúÔ^ðTþ!ñ4Z{˜%Š+Èíî#ƒRµŽYA}¤[™$ +¥K •ìFbð}íœPëº}åÜvT°±ÝNŽÑDËqÙ}ŠÍ‚!eTòËœ x2öÏÿô+»›¸ÞÂÇT‚YnâG(cI”—U*¨>Ùâ€2ômó^ºh,Ò2Q ’I<É Q.@Üò9 ƒ%T#%”HÒx?X–þòÊ+ 'º´Hä’(HrÊòGl˜'ÌÓE´¦wdsV¼={gs¡jZåÜz`¼¹·»Žútw‰™v8Ef„ìC*¶ ¨# YwGŒ,ôý'SÓlïäÿcÁwtûc6 —íÊ¡G•FìnUä)}€˜ñ„u_ Çe.¡kozŒö×6÷ÜA0V*Ûd™IR0Fr229™sk5œ‚;ˆdÊ$dR¤«(elÅH ÷õ±y©ÛKàm#OI3y¥{q${OÊ’Ej¨sŒ˜Ÿ€sòóÔf†´È÷‘”Ô$ÔÇÙ­ÇŸ"²•"/˜çœÆBÆ(zv§ðWû7[ñ ©ÖwéÚmœó[_ý—lž%œ´>^üÇÍ¥Úï9¹Ï;Ó>c^¯ªüS¶Ô"ñ-Ž“,Öšq¸{MÏqw8Žà+#¢4Še;6ÄÉä‚EY·MÿÁé¥]ø‚;+/T¸¸ ¶’È—K*Z€wƒoÂÊ#Ì\²àâ[¿é6ßt zÑg}'OþÊv;å WL˜Ùs…ŒŒ@ìÞÔbÕàÓì—7S!‘~É}Äj£%™äÙ(Vf,FÕŽ4OáVßRû ‚9&6Ò^+Aq±I hîî’+pr´žQ—ï+SNm;AŸTÒÛY´¾µÕìÕµHçòí˜Oª]dŒÂ¡¶ƒ…|åvV“Jÿ„sIðõ×ö®§§jR_Á{g•’â_ "Eˆöù Ë(Ë9]¤(gæ#Ó.eÓ.56pM¼’n+È®È1œœˆŸ1òóÔfþ³áW@µ[‹Ø#D."Gq¯„#™Q‹Bÿ+|’o‘øù[gˆ|Emàßèööw‘gáÝKíÒéþyl]Uæ‹Ì ŸG¾á•o#Ìç5ŽÒé^ѵ˜¬µhõ‡Õí’Ö8ã‚HžÚ1Fr$#çîœPÔ<;qáÛ«7ÔáŽâÊWåôûØfI‘½ḧ®•ܤ®ÏOªê ×Ä[}õKË-Væòí!x%cc$Úp× #¡eO4Œ8 1ã=fÃYð­•’ëmÅþ™s<î,t¿±Ar&(„‰í*Æyw€ axÃKÓ,aЮô¨®ííõ+tÐÞ\,îŒ.'„€ëˆ»Ü×;[¾#Ôí¯ô A›å²Ó^Þáv‘±ÍÝÌ€r9ù$C‘‘Î:ƒXTºþÖ㴖嬱p¥Ç2¦é¢Y³îÌ›btw E`_h¨´o j:ý«McöIHsÛµô q#`±ÂÎ$œ€©ÜxyŽ`#»a#“ÈVäc)œä æ?áÔ¿¶ÿ²~Íþ×o˜»6mßæy™ÙåìùüÌìÙógo5jojðêzm‚ÃÌúŒÂÞÕí/!¸ŠYK*ìócv@À²dRpÓéž7²ÒncÒàš¶H:8Õ.lÖx ›Ãuæ˜$FÌ{ÎÎT¸\I·pòêX|Y ŸŒ<%ßXiº¢^ÊÚF’--àS$[Û LîD\‡S Ä uçƒõ;BX»°’ÖÂGæ!üÅf¸£}¯§cr cÔ·WS_]Mss4—9’Y¥bÎìNK1<’IÉ&¢ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“+þÑÿò±ÿ°Šé$µä«þ½ÿÝ_ækÖ¿hÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5žOüŸã—èVoüh‚$”QE{džF¿ëßýÕþf¤¨×ý{ÿº¿ÌÔ” åå¾i=ÕÔñÛZÀ,³Ìá4Q–fcÀI=+“üç9ÿ„ÛøÚ9þÕƒÔÿ·R|`ÿ’Kãoûß臯¤hÚCÖ¾üZµOÚàþ·¢ßxg[‚ÏÃúZ Õ&ó,§[xRãûREyw4`‘oóà…T,6€xÄó x$•*ŠX×f½2ƒQ˜Sí:ö«oq´y°§‚õ)6RÀ2Usè:W•jBOì묺‘å?ðŸCï_¡ºü„.ë«3_+Ÿãë`)Ó)5vÖ–ýS;°´£Uµ$|{'ÀÿÝÏ)Ðì&Öì…sƺ[–À$.c?yw)þöw*ñzæ‰}áýZ÷HÕ­>É}lU'·i#” È®>dfS•uè{â¾î¯>6ÿÉ]ñGýu·ÿÒH+›$Îêæ5 ‘Ú7¿Wª]’ëщÃFŒy“êp?Ù–óéýûáGöeŸüúAÿ~ÇøW¼ø›LÑî5MrÝ4 6Õ~ßâDkxŠã³µÂæÀ>k-ŒàÁ~î¹6ÎÕuÿølYZIáýNÚÖ{»ç¶§Û$j×3­É@ÂQò‹ör$Výîï³<ãÍí4æògk[SåB¾lÆþXÔ²®æÇA¹•r{;ŠJïü â»Û x®Þ(4ÖK]-^3>—k+±7öÀïgŒ´ƒç8H\µqB×Pm/Ã?Ûö¶¶Þ¥5½ÓOcñ[&ÈÞ0°²ãó¦ÁÛœA„Ú†ãè¯IJÑômWÆ>v•ÜVš-­×Ø$³]<ÖFH·º„’I#eÈ“hd.–®'^×·f¶q§ØiËo±ØAå«(ve-É.À0]ìK‹¸±Ë Ê(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(¢Š(­9<-¬Ã}{e&‘~—–P›‹«v¶q$ w\eTS“‚=k2¾ˆñˆì§ñŠâÿâq?öÕË‚¾kEo¢øçqŒ¬öj™à›B0IêXmf¸Žy"†IRJȤˆ×p]Ì{ Ì£'»Þ½M³µ]ÃþV’xS¶µžîùí£iöɵÌërFä0”|¤"ýœ‰¿{º¯BÇa–¬¡Ù”·$»Áw±,B.âÇ,u>ÿÈÖ›?ãëìwŸdÛ÷þÕöY~Ïå÷ó<ß/f>mûqÎ(/[ð¶³á¯'û_H¿Ò¼íÞWÛmž3ÎÝÀgǨ¬ÊÝð•ö¦§ae}q=§‡®5+XoîöEæ`˜ü‚Š–èöÍl];ëZ7ˆ—TÒ­4‡Ñ‘ªÛÙ­«Å9#6®ØÝ!òüÖÄ¥¤ýÁ;¸“pR­¬Ïk%ÊÃ#[ÆëÌìV`ÅTž€Œ@ï´úõ}ZëL“â¼5oáý6%V)ºÝLñÍsL’G( ÈDª#\ N ³vÇÑüi¨Zü3Õv[é-ö}KO<ÍÑò¦Î_tG{|ƒçl·-ÏÌÙóº+µ³¼°Ñ>iWí£Ú_ê’ê—±Åqt7$j°Ú0%<¬ÙPä Ë†FÝÁýª,ô)¼Ie§i¢þûT¸Šæ&±Š{{(öÇ$IR+,aËL œA… 7axkÂZ‹n¶›öG¸.‘¬7Ð[¼Œä…T:—$ŒasÔzŠ«£h·íÓ[ÛIiª&òòTÆ@á¥eRyèzñÁ®ÛEÓ-´þ¶µìê5-2Im·öyŸÉy¡ä–\Œé†%†Ü1$^w@uM2çEÔîôûØü›ËIžÞh÷ØêÅXd<ƒŠ­^“¨iV×ÇŸZjbGµmSQ*%ÜóH¦gŽ%PÊ\»ª EefݵYIPñn­£ë>y-{ËÈo"Qxº®™É.èØÛ»g*…wŒí<¶@8Z+¿ø•­Xiž(ñv‡¥ø{M²µ7óÀgh¼ÉÔ¥Æàcn 6²…Tl}­¼€Âþ­u±§§évÖ²ÛÃ;K ê:V×6ë32Åt€É#B¨ÌÍ+FÏ匬…Ù(Ìh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+¨ð—üßÜCÿJZ¹zê<%ÿ$7À÷ÿÒ–  ¯ȯ¬לßú¯Kñü›Žÿb¹ÿÒ8ëÍO¿…ãïU7ÁÖ×>¶×ou˜4ë7¼žÕãt/)1¤/ˆ‘N]˜Jß{b€3®õ¬ÍNbŠì<=à{oêzÄO®êÖvsl†ëDÑ ßš…˜+ºPŸ( ž£ŒsY¼ý™©ëqk7Ÿd±Ñ¯ …ÕÍœ^{<å¤UH²nÏ•#eŠ€¨yÜUX˜¢» ÏY+ØÝZj“ˢ˦RâîæÍb–…ËÛ"Y;BÀ"î(¡˜ÃøõÍBÔiz—›¦^CxÐ]ÞF–ì%¶·3–#2^HÐ\m]„íÀÀÀÇ•±yàk%{«MRytYtÓª\]ÜÙ¬RÁ¹{bK#‡c"¨Q¸d]Å3Oø¹¨Z/RótËÈo »ÈÒÝ„¶ÖægŠU2Oùgóï*@sÊ }ÓêþÓ`ðÉÕô½oûOì÷‰cy Ú4]ÑÚ9"$ñ·•(Ëq´eî9Š(¯u×¾xnÇ[ñUÔZnÝ8YÝÃcaçÈ~Éž‹%òÉkä Bë’,L‰½Ô|Ëüèv}ý›º—Ã+ ;Wñˆ|Gšæ˜—SE[n‚hàÜÌ­*¹Ù)öme Îr¨EwZ^á ü {¨]jz²^Eyg É™yFH®£AöIŒ|ä) ófi¾¶¹ðͶ»{¬Á§Y½äö¯¡yI!|DŠrìÂVûÛw­sWN¾ÒmþÕ{y¬N4?¶MgcyicæËxcÚKùO"lP;›9‘@ ‡+±à;k|KÑ´;¨4Ûû]BþÅe70ܤÖò²22P²Ž@xÚÜÀ€ÀQW´mjãBºk‹hí%vB„^YÃt˜È<,ªÊ@Ï^y5Óø‹ÂSkßµý F¶Ž2uKĆ£!"Ž7‘ŽÔ@I ŠHTRN0 œÅQ]¯‹þMá­j«µon·)jë®i&ÁÙ]”Æ<lj·r1”ë¸â/øMðÞ¹asâH.5Kž+{Kkv7l¡‘ÁÙ;©|merŒ }Wa¨#Âmk¦\èPjí5µÜ÷ÒÜMëçÀ’í‡cˆÓbÈ.’ecB(EvÔÿÁž)±žÖÁâ²ÓRâÞo°À.Íõ²“çóË#Œ#ªÞ ðwü%ŸlÿG×gû>ÏùioÆíß÷©³îñ×<ôÇ ÅÚé &»×uí2æ[¹î4‹“i-¾‡do®$`ΦEˆ´gÊ0\ž Æ1óq[Fð}‡ˆuÖµÓu;»ëQlnA§î¿†cK3k¸ÎòBa›9R€“¢¶J.ŽTofÚ®ÜnÚËÄÿeÞÿiÿfý’í;ìÿdò›Íówmٳݞ1ŒçŠ—YÐu?Ý-¶«§]é— ‚E†ò…Ê’@`Œ‚3ìkžss“›ë¨S‚§²V:{_ØC47³h’\j†Àiwݱ}›ìÿf&(Âe%17;H¹,|¾@\-K]†ëBµÒ­­d‚ÞÚþêî&–a#í•aPŒB¨%D°;º TWÞ½Ð5;{MzÊÿFó6»¬ö¬²ˆ‹`º£•ÝѱÈŒdU¯hZ*éé÷ÓßÙê6fíæÙmäLO,%J¬Ž:ÄNwt5’é~$°‡B‹MÕ4©5´¹–îÐGuä§™"Æ®³¥?sÑ·ßù¹wmüQ§x‡]Õ¯n¥´ÓF¤âêúÇYóç±¹œ³³:tÂUœl'i4¸%_˜¹ðgˆ,ôªÜhZ”YD_Ig"ÀU±µ·‘·#<äzÖ=wZ÷-¤Ôm­`µ‚ãGƒMþɸŠÑ ¼w}¡§ÌYÓk”Ú﹘į %Ý*Œ>7‡Oš(tý>H4˜-¯¢†Ú{$¾eÕ¹†I^@г F#QŹ:(Nß[ò<3¤y;¾Õymwçoû¾RN»qŽsçç9ão|ñ™EQEQEQEQE³à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý[Þ ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ”-Q@Q@Ñ]x4ØÚÌ.u6ßU… ˤJò­Â`d£1Êd¡“v~Loù*Öðö]JÏGuÖtدõt-c¦H'óç>s«¸DcRϹÀèI€9:+¢ð߃ãñ¨^6»¦é‚Å<Ùâ¼[‚â2ñÆyp¸ ¼ª¸Îzœcš‹@ðªëZeö¡>¯a¤YÚM »Iz'mï"ÈÊEž‘>Itõ  **ö·£M ê/g;G! ©,D”–9d× XŒà€rk[Y¯®¡¶¶†K‹‰œG1)gv'TI$à@]×Ä‹›¿꺃Ûÿ¡ÞMª\Ge¼~åïahœïÛ–ÀÙÁ;8Û’j;?Ão%–§&Ÿ$¾%°H£´¿`_)Uaw‡aÜ誠ê§bnWù÷ãk~Ö|5äÿkéúW»Êûm³ÃæcÛ¸ ã#8õ.¡àÏiVv×Ú¥eqxþ]´7rFó¶@Ú€€Xå”`zZ<7®Ã£¶¡ ݬ—–…·Ùnc‚a »D±Ê¥«;âLå[#pàA ë°øwÆv³mk#ÛØßÇw¬³åR@á@ g‚\vª³h:¾‘«.w—;˜â¾xA#sò«ãi?+pðŸJ—þmgûûgû"ÿûþ‚f³ýíŸë1·ï|½zñÖ€%еØl-n´ýBÖKí&éã–h ˜C(’0â7I ° H*À‡n7me¿?wÚêVQYùVi«¥ÙÂeÜÖÑ ¤¹Ë6ßÞ3:¹'åà*…Ae êz•Õ¥µ¦wuqx%´0@Îó¨,–£‚G÷[ÐÕÿø?P×m.ïÖÎüi6°ÎòêYIãÀ  ·ߟᛠ#ÉÛö[Ë›¿;ÞóRÛŒq#9Ï;»cšºÅµÍÂ=¥§ØâĘdˬj®ù?ßpÏŽƒv¥Ñ´OÄWMm¥i×z¡‘¡³¦p €X…ã$ ûŠ­uk5ÔÖ×0Éoq ˜å†U*èÀà«È Œh*Óñ·ý¿¨Euäù]­¦Íû³äÛÇìà}ï/v;gã5FÖÖkë¨m­¡’ââgÅ JY݉ÀU’I8Vïˆ| ©ø[BÓoµ[K½6âöæâ³¼¶h\,K  Ø$1”Žœl<œð§kãûf†ömKPØ .âc{¶/³}ŸìÄÅL¤¦ çi%—È …©k°ÝhVºUµ¬[Û_Ý]ÄÒÌ$}²¬*ˆU¨ƒ–gwAŠ5xƒHº³¶¾Ðµ++‹Çòí¡¸³’7²ÔÇ,£ÔzÖd6³\G<‘C$© %dRDk¸.æ=†æQ“Ý€ï@º_‰,!ТÓuM*ME-.e»´Ýy)æH±«¬À)gOÜÇÂ4m÷þnA]ÛiÞ!×ukÛ©m4Ñ©8º¾±Ö|ùìng,ìΆÝ°•gÉÚd . Wçn¼¨i¾þØ¿³¿±ŠY¡KC=”‹Ê:HåÖR6ñ±0:°|ŽÕ[ k:¦™q©Yi÷zu¾ï:î gx¢Ú»›s€A9<šéõï[I¨ÛZÁkÆ›ý“q¢xî"ûCO˜² ¦×)µßs1‰^@KºU|oŸ4Péú|i0[_E ´÷I|Ë«s ’¼1f*ŒF£‹;chžÖ|Kçdiú¯“·Íû³Íåç8Ý´gô5™@vúß‘á›ý#ÉÝö«Ëk¿;Ýò’uÛŒsŸ?9Ï{çŒÊ½£h:Ÿˆ®šÛJÓ®õ;…C#CgLáA± ÆH÷\è:ž®4«:î PºF,d–rÍ«°Ù9ç#Ö€:+¯‰7~#Õu·ÿC¼›T¸ŽËxýËÞÂÑ9ß·-³‚0vq·$Ôv~7†ÞK-NM>I|K`‘Gi~.À¾RªÂïùÑU@!ÕNÄܯóïÆ¾ð¶³¥êvúmî‘i¨Ümòm'¶t–]͵v¡9 ɨ­tNúÖ›m:îâÞk‘gÑ@Ì9)È9 9ö  ^×aÑÛP†îÖKË BÛì·1Á0†]¢XåRŽU‚ñ&r­‘¸pH"ÕŸˆtϲɦêmÝÞŒ—2]YÅ êÅqnÎXLL®R0ÙAÊ)]€°l(mf¸Žy"†IRJȤˆ×p]Ì{ Ì£'»Þ¯Â-¬ÿblÿd_ÿcÿÐCìÏö½³ýf6ýï—¯^:Ðùµ£xu´½VÓH}Ý5ÅâÚ¼S™ÞAt‹Ò/Ê\ÄOÜ·ˆ÷Sÿ…Sã?ú'ÿÀ»oþ;\î¡§ÝéÍ…ý³ÙÞÛ2¬°»#%Ç*H<0ï]s¥R ó‹^¨Ê©Ôv„“~Lë´­gLºø‘¬ÞZ,zn›¨&©œR……"óíçŽl¨3")9Ú½If¢ÒôöƒL×|8n¬-õ‹™­dIþÝÙå…F’´òùg†L L8ÎõE<}‘±èŸÚ–[ÿ²~×öÏööOöŸš¾WÚ~Ó¿oŸŸ»öoô_3;1òîò~z¡¢£ø3YÓ×TÕm6l»0-âÝ¥Œò@cŠè´%ÕH“Ël¡2 ¼G»¶µšòC¼2NáB±©bT³6` ’{OjÖdµŽå¡‘mäv&*v3(RÊB@u$vÜ=Etú¤Ãþ—G½¸´º¿šþ+»d³ºŠí-ãȲ’ñ³*™ ‡å'È€=Õ|Qu Ƈáâš9^ .HåT`LmöÛ¦ÚñÚÊp{0=뢀=;V†=BOWÔ&Òl¯¤†yFµ¢ë(d½y·y¶†F“÷ÄìÚ‰ŒJÅÓj•_1¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÙðWüŽZýÛÿèŬù¼qÿc÷þŒ­ïÈå ÿ×ý¿þŒZÁ¸ÿ‘ËÇö1_èÊ–Š( Š( IÔ4{ø·Ä^%šïM}ù5B—S†+…‘â™áF€È%Þ²”RHà²M CÅÑi^ð”v¶«[鲩‡‘®lÜÞܪùjÁX0b…×xe …#…¢€;_hò_x{ÅenôÛsw`¶%æ§olï »¶”€²H§Žìcå#9â­xêå<â m>mo俱C­5žÆcºÊ.¾RAtÞ„×Enøá­ŸÅ7²[Oö7d³¸˜Ì¢á‘ZuY %Õe2(m͸w6w|r6±‚HæÁ­ÛRŽ6°–0dm °FÿRÄs¶vÀ|ìnv¬éš¥î‹}îŸw=…äYÙqm+G"dpÊA¡4éÚ]Þ‘à½;Áí-üš­æ«8ŸÉš8Uä·‚(&_»1eL™UÃE @L`™t]I4wÃV÷~ЬŸÄ}äÇLÕíØDÎ7»}¢dJÙÜT¶ß,ÔõKÝjúKÝBî{ûÉq¾âæV’GÀe˜’p@*µv?‰îot íC ¦Àâ4•ã»¶Ø©Âü‘‡ ª0¨]gˆÃÃWX,Ë ŽZ¥Ìàíg¶Žú?ÅwV>iý…üi®i?lü+¢}¦o ^Y]=µ±UPâí!ÎÕc/—*~Ñóg }ø­ÿ%7ÄõÖý&†¡øg¯xKàõ´±xGá¶Ÿ¤¼Ãl·GU–{©W9 óËHÊ!K;Y¾%×dñG‰5-b[d³kÇFòS(@±"}í«œìÏNõ`°ØaNy'~»|μçã:«™Rê0𵕷Ó[-.Îö×AÒ×]×|:ž‚þ 7M¾¸Ù’äÍ ŽÙäŠçåD#wòÊ|„m‘ç'sDÞðô¾'Ð|5Ÿ'Ú5›m5e¾y9§·„î‰wã|…ßPÛE·{eÏñ оÁ¥Á©Y‚’"ÛÜj­qcl%WY|‹rƒa+$Š ¼„,ÉrVÖ¾#ê:œÛÛÃic Ø[Ø#´ƒí,±À·ú@ŒK‡ r7}Ö)ÊõÀã$ø{si4º…„ºdNún£2j"kˆî"Ûe+%T*Jà†CÌAÀµk©Øé ôw»ÑàÖ%m_PXÒîiR$M–ã¶&F-÷pwà ÙRH+ÇiÚΓpóÚIåJðËnÍ´¤‘´n9ÑØg¨ÎF ji>5Õ4]0ið ¬Ög¸XïtÛk­ŽÊŠÅL±±¦@8ùEEâÝYû=³HÖòÛ[]Ä% º,ÐG0F ÅD›K3ŒásRÝ]M}u5ÍÌÒ\\LæIf•‹;±9,ÄòI'$šŠ€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(¢Š(¯\ñ_‰¥Òm †ëÄrjø~ÊÞ? ‰')’iÑ*ÈêÊ!¼àT³o Â’Y<ެê:έp“ÝÉæÊÅn­´ $q¬h8‘g©ÆNMv;g;Wcsšf§s£ßGwi'•»§ÞéúµÜº¥·Ùå×c–H缓t„ɸáðA–;ŠF¹ ‹—¨x»UÔç}ý´Vw+xâF†3UB LXÚÝ÷9¡¦j2é7ÑÝÀ<±ç soñœ‚9I”õîQ@}ª^ꟴͿÛnç»û?ŠVÞ>V*%½ùQrxQ“€8¬ëSkÞ¦³©xšÞôY¯uÌ‹‹FhÜÇhd*HBÄ9Üa@U6)“¾ñ¾¯¨øšßÄ2ÍkL· sœ0æU}áÙQ»n9%'¾EE¬ø·Q×-VÚãìÛ«‰ 660Z#°q(r` g›Ür^k ék®ë¾OA›¦ß\ lÉrfGlòEsòÈ"»ùe>B6ȃs“¹¼Æ»Yþ"¤Ø4¸5+0RD[{U®,m„ªë/‘nPl%d‘Aw…‘¹.C€ ë/ øGE].ËYÔ4\][[]^Ü\GíÐ,ñ$„B±'’ £»÷å†[ì\løoÃ:?„ï®ô/í»«û6šîÚ{‰!ˆ¢ÝΛ•‘ÃyŒ±ªŽˆ¡2VBÿ&™ã}_H±ŽÖÚhß"ilá–{|’ß¹™ÐÉ–a‰a‚I¬»ÍNæþÞÆ äß”&ÞÝv± !~yääóŽ€P¥MàÂ÷ZÔ·wšl‰µ{¤ÚÁ¯Íž]¹B_ý73Ÿ5%Ta¾VÜ6eÁ£xVãUñdÊÒ^i6:\q5‘q9šÕdHŒ 0MÒK´ŠÅT†!ØsÎÃã}^OR¿i ¹ŸQ˜Ü]%Ýœ7K)fmþTˆÈ| €ìjÏâmJæmJI.rÚŒ+opjÄ®Žˆ  "©Š<ÀŒ(Õæ·¤NÆâÏÃGko Š[;«©¥[–Üø‘ÙY6Ò™UK!!T6ÑÑkZ%žµãøád’ÖËûßQx!™Ü…LK†‰Rì í(¥·lpB⸠½>»q©[ê u"^Û$ ñ-㢤[JãU¯Îy  Zγ§j–ª¶ú¦‘pŽ’ÆyÊ:àä:Êòs·JãæÈl‚¸õ±¬ø·Q×-VÚãìÛ«‰ 660Z#°q(r` g›Üs@§¥®áßøƒÃVú5¤“iöÅ¡Õä’´ÈÑÙÜ}¢A Távª@Ë0ÞK/ øGE].ËYÔ4\][[]^Ü\GíÐ,ñ$„B±'’ £»÷å†[ì^:Ûâ½i`m!¼Ž4kg³’QmŸ, ŒÄòíÞ耘…Ú˜bâ-3Æú¾‘c­´Ð‡>DÒÙÃ,öù%¿s3¡’,1,60ÃÓ@z/„­¼U¦i3Ú·ØVÞg¶Ö'Á“Ê@²N.¶’7~å'Zsþ‹ž²V¾j]×ÄÍ:Ð`zޝ[«Ý܉l¦ÀIˆK(aó0'(玳Ôîl-ï ‚M‘^Â-îh;ÐH’ÈãçFèM^§s¢êvš…”žMå¤Éq ›Clu`ÊpAÅløzÊÎÛBÔµÛËHõ1gsoiŒîé´Ë3orŒ¬BˆV\–RN«iøoNÑ|Uªêó[ÚhVZm‡Úæ¶’[‡µ’O:8•r¢I‘ • Y‰V£ |Æ­Þh7M=›Æ ¡ŽHç…&ŠUÈ;^7\d+ÀઑÈZ›ÅÚ¬Ú¼‘ž8î CI ¼qÀ‘œîŒBª#ÛŸrmÚÛßp;› ž7‡@[]>]&}5¯Yå[˜4yötŒ1·úPß¼“(8%p©À9Ï9¥ý‹ûNÓûKÏþÎó“í?eÛæù[†ý›¸ÝŒã žR’qu´‘»÷)8òÓŸô\õ æ/5;›û{'“|VP›{uÚÄ2<„p9ùäs““Î:Ež§sao}lŠöop»AÞ‚DG.ð‘ký¤ð^Øh0[øTÓÖ[Ùf|Å‘䯍‹#œ—ÛŽ@fÉ@yˆ5}VÒ´Ø5£ ºT- a2ÝDey¶3;)·ÈãÌ Ã/É”;÷|E⟠øÃûCí·z¶›ækº†©‘§Åqº+'hlΛXyG dsÖ€9;ß _éÖ…ÕÊDz¹·¶‘7î.fI$ÐŒ«!X‰ e# æ­Yx"êêK™o-,ì§°mFK©Ì…-á l „FbLª­÷Ôœ ØØ_èÚí¦µa¬Å§ÚÜý¬§±T¸x~ÉAÈŒcn‰ÎYY>p\ “ÆzLÚŽ%›jÞM3M{8îtÙ<Éàsq4›ò] ›£—ka¢ˆT!æ5½-'É{}ZÃW‚]ÃͲiÖʲJˆã‚m»NH•`3+§ñ®»§ë_cû,“ßÞG¼Üj—VqÚKpݪé¸v;™‹¹”†û€žb€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(¢Š(®þïžS&Ÿ”°è°ê’ês^FÖÈÍh“ì1y €îë æO½"}âvžºøÞ÷Ä©ed·÷í£ÚÙÙÄó1Š9b¶H–=ÅFX9s†ç‘@éß ïï¬ô{éï´Ý/MÔдWº…Ï“Ÿ9áÚF71 €¶ÀÁDg*E 3ÂR_XÇsq¨Øi_hȳŽýÝì‚T•!J¢î|É &C ß#í‹]ÖaÔô¿ÛD²+éÖk)pf7S˕瑶Uã~¦ü¾«iZlÑ¿†]*‚°n¢2¼Û‡”Ûäqæa—äÊà|à[MoP¾´Õµˆ4k«Xo ØÜÅp· ðÛ¼››l,¡C/̤‡Â°;s™oáUº¾»Xõ{¥Úìë '[`XeT˜XÀ(B~WlmVajÇÆ>wµwR‹Úm[‘j¿ê¾Õ±»"±çošX)a È,õ-ÞKD{›ù4;¹ ¹[õ´E¹ŽX’@¹‡Í*Ê|é0¸Ùà£Uÿ„:÷ûOìÞldò~Õý§¹¾ËömÛ|ýØÎÜü»q¿îöùŸ%‘¯­-´ÍFÃ\ûFð$³wEŒ ÜæA2ÆÈª¿1‘€L;¾GÛ§ÿ –ÿì¿*ììßì;jý«ÊûOÚ|í¹Û»ÎçËÎ6|›óûÚ­m«èÞÕmçÒMþ©CqÓÞF–¬ñMBÉ«Iµ‚;‘!feù0§x[ítO³êÜØx‹LI•$’ÛÏoûÞT–9rƒ‚ mbQ¶Úñ¬?eðÝõŽ›•ý¡¦µÄÖöÏ+G¼]\E‘æ;°ÊÄœgÍEªjše–….£KwyossÝÅÕõºÀû£Y4HÖG,„±cœ¨v’õuÝfOKðí´K"¾`ö²—cu<¹^yeQÎ9ê@/êž]#ípM¯é?ÚÖ›Ö}/të*:gÌ{D",¸n’Äa  àǦ\˦\j làš;y$Ü>W‘]c99? cåç¨Ïmuâý"] kIµ=kZ„[m4­VÒ)ȕ®¼Òè#;ùq —ÊUeU8^&?±f\yžö“·o•åm3w}Ùò¶ãŒoÏj­]—¥é–ZZγÝå½Í̶–ö¶7 îcyähܱ€¡NrÄ•ÚóµÑiz¦™{¡E£k2ÝÙÛÛ\Ëwoucn³¾é4‘6‘E c mÀ Vú ¶³}w5•Ïön‹Â÷š®vÀ\|±±XÈÙ ÄËg(Šmø~jwÓΚ|öšŒ)`5(îavHæƒÏ3ƒ"©@Ž[q ¶vàÕø— ¦©m¦êšÖ‘¥Ý[iÐÿiX¨Šð5­¨„Ê‘òùO0`”mÇiVËÕ-þÚÓ"´ÿ„£Ä¾"ýð—n²|¸¢Â°ÈO:]Ìw}ì®ÐÃnù@#ñÃ{ÿ ¶¯©}¦ÚÝiîTYµÏïî@”FZ8ñ¸™\y !Ü¡€$E7‡m-ü >©冣?Û-#sÜ,¶{âŒL£n)Ë+6 X š¡ã=fxÃ]Õm–D·¾¿žê%”á^F`FpyÁ4Zë0ÁàýOJeÜ]_Ú]#6Š;…`NsœÌ¸ã±éÆ@-Zø4Ëk ]ën•yp‚K{ ç•%•Xf6,#1ƨ2ºpC#+vºÉõOømïu‰u+{û{h-ZÒÆÞ7Šáa‰cB%iˆ²"©ù$Á†A¼lhÞ:«]Ýjš5€s]ß JI ”E˜€A$.+¸‚èwÀº~tÝ RÓ´ßZêö¶ßjÏ…ŽGtf9«ƒ‰•#T†™¥êšeî…¬Ëwgoms-ݽպÎû¤XÒDxÚDd0aŒ0!·‡‡õ3þ=ÑõKu»“KÓïíî˜Ï‘cufm …¶’'n@ÜØÜ@1´Ë8¯ï£‚{è4èŸ9¹¹Y i€O"5fçáO$tÖËø"èêövp^Z][ÝÛI{¡@Öñùžl¸džL¹7‡hl®Ox†ßÞI,÷vql`‹RÓÔ5Í“yˆþdcrd²£FpëòÊÜŸºw|Aã]3Ä7úíÆ§â½ÒÐZ Ù^æEK*Ýy…ò®¯ ÄáP;?0“Á¦âêÆÛHÖ4Ýzâîå-7–'9Â'Ž2A9—!xÜWræ-OÃV–V2\ZxIÕš,‚ÛíÈ74Q†ä•Ilq€ÄlxŸÄúF¯kh“Ýj^#º[”’]BúÖ+;¯$3*¼Í1l¦\ùb Ä |MâÝ?UÑ.`ŸWÕ¼Q~ûE½Î³cRÚÀ–‰¥‘—huòI ™KýåÌoΰÏÔ¬±2O6Š|ߴƱ¡’@ÇËòƒ*+1C&á´©ÆÊæ+ÒuïŠ3xŠ×Qº¹ñGŠâù$ótH¦"Ä3‚ ¬†R|¬Â3ùw»þZW›Pàωü+{®Ëi¢ên.`¶†×TÖ"¶UÄåÙÀž'WÌ(3 ÊÎB¶2¸Qø`ßÝ_\Ý]i¾°[—…&’If·2“&1+Hw À››.›ªÚë0ÁàýOJeÜ]_Ú]#6Š;…`NsœÌ¸ã±éÆmiz¦™{¡E£k2ÝÙÛÛ\Ëwoucn³¾é4‘6‘E c mÀ §xXÔïõK(¡n´ëe»•@¢2F¾b¿Ü)‰VO0°M€¾ìu¡¯h_Ø3[Fu A¦‡Íca?š°¶öFŽ1¸<®T‚¬¬Á;3øÎÆñ#Im$"ÿK¶Ó-#Vå¬ÚìóŒŸ.Û–e  àrt±àÍxÃBÒ®ZD·¾¿‚ÖVˆ€á^ERTFpxÈ5WÓtkŸ _K¶¿Ó<»Ä´ßÝ¥ÇÚw#³´eb^ØÃ 7úôû¼n¡àÍføÃBÕnVG·±¿‚êUˆåREbp8ÉWY×µ?]-Ϋ¨Ýêw ‚5šòv™Â‚HPX“Œ’qîh׌ôh|;ã wJ¶iÞÆþ{XšR •IAbÀçV¦½¥ø÷Zއs¤úÍ‹Éo.¡ÄfÜ΄‚«Œ6ÍÃ`c 8ùöç÷u'Žï¼3â g[Ö´ýGV7—÷’Ý¥¥Î›q¯™!b¦E¸cÀcÎÎH3Äzö©áÿ]j:å̺’k7Ï%ĺ|Vñ‹q;’K,æBÛ7áLdãäÝŸÞP']—à[ýWB‹YY­-t¶¹–Ú[«©¼´…£XÜç#æ%eÊ¢nvØûTí®v¶.µ˜gð~™¥*È.-oîîˆ Ëº¨9ÎalñÜuç£ðiWÂëXÓl¬-®^Ñ59Y-îdSȇËÙÆ0Û‚àMÄ@׬¾êÚ…ÅÜ0ÜX†kHbß>ϵ¨Ùí¼ @'Ì ¼ ïÂ…r’øCdzhúÑ›\Ö¼=n—/v—Z%ägTFI#óc 1•mß/Î0ÛÁKúGÄ[+ l]ÝÏ«j{uÝ/Rk«×Yn&ŠÕfW,KpÍæ)TÉ >Rçnæçfð-üð@óZ}žKcx×é6ûh¡ÝÙÔ…‘Z?”ì~ôÝÇ…VÖúÑdÕì—u¼E¬(­‰Q–R~``J‚¥ù‘±µ•Žœ1²þÍÓtÉ¢œY!´«é#U2&ožédˆ†Áò²­À:årfkú½“é–:6–g›N³šk‘swÅ,²Ê±«üŠÌ@†0æ9 Ùù‚¨ŸŒ| i¢jVšN±³uu ™Kh®ážkt“rî…T©fùTøegv(Þø4Ûé×w6ÚÆ›©Ëd‹%å­›ÊÏn¥Ö2ÅÚ1€î‹˜Ýó¸•Ë ×^-²UмGbósNû ›‹e6ßèÑ$jÞh3nò•ظÞFã´kÄÞ9þ×Ñ.mÿá*ñf©ö¿ñ-Ôçͼ?0o™üÖó¶ã÷qäÿ.Ý„…®Š×Á¦[XZïXÓt«Ë„[Ø_<©,ªÃ1±aŽ0ýA•Ó‚áXóµÖOªxÄ o{¬K©[ßÛÛAjÖ–6ñ¼W K+H E‘OÉ&,2E¡¦xJKëîn5 +íqß»£]J’¤)T]Ão™!DÈa»ä}¶­~j¦hßMaäÖ7߉ìÓF±’ŽªŒÛ›Ì*†o’B@Tf¾«iZlÑ¿†]*‚°n¢2¼Û‡”Ûäqæa—äÊçŠ|cÿ N˜¾|^^£.¯ª\ykˆ¿Ò É'ƒð{äó€ =á¤RüA·ðÞ³­XYî¼µ„4I/Û"˜©V·tÓæFR¥ösüXÇ´ð\ºÆ¿‘£j6šåÄ–Ó\#YG>ÇÈc ñ+">R eë‹Mã8müu ø‚ÞÚI“LM4˜$`†F¶†a‘œÑB;TZf¥£xo]’{›ýBÎM6òؽŢA –ki¡_”Jà¨.„ÙÆxàd+¯ÞA%ŒÞ麅íËÊkex“mŠ®^YòÂlmÛÕ_qRŒWÚ èŸgÔ!¹°ñ˜“*I%·ž"ß÷¼©,r.åÚÄ£m«á½oþýUnÌ?h‰¡šÚhƒìfŠXž)6¶ÖØí‚AàGþ©ªi–Zº6-Ýå½ÍÌWwWÖëîdHÑ#Y²ÅŽr ÚK€KãX,~Ëá»ë6 +ûCMk‰­ížVxº¸‹#Ìwa•‰8Î3šÀs¬3Äu+¬A “Í¢Ÿ7í1¬hd1òü ÊŠÌPɸm*Fñ²¨kºÌ:ž—áÛh–E}:Áíe. Æêyr¼ò6Ê£œrÔö:÷żEk¨Ý\ø£Å q|’yº$SbÁVC)>VNáˆü¿»Ýÿ-(ͪö££M¦Yéw2´lš³]D’UDÒE†ãƒº&‚v^ðåï‡4!}m.­£Ã-²Ú ¿d¼C3Ì…ä ²G†™Ã*†,ªhÉÜ#¸ø{.›u¨Eªë:n’–—óéË=ÀÒy¡ JʉØÞ‡,;Æ3†Æ\>·:¼öWæ›gh/œÍ,ƒ‚»|¨Ý!³†U+‚+ µÖÂs§ÏâoêQk:î…©©Mtaµ·Žæ+¨]Ù’9áiQNÝÌc"°r0;øï_YjZÝÍΟoökWۅرï` <›å{-ITݵI (vÿÀwº§Œ|[§iv°[ÿdM‰gk½ÕÝý½áÙ«E©>Èãùa ‚ePüH\àÇ\vº•Ÿ„¢ð}®«m¥kQÜ^\ÝZD²êкDÑG `-`Lü¨+÷zóÅiô¿ø}m쵈µ+‹û‹h.šîÆâ4ŠÝf‰d@"hÉ”ª:±ùãÉ%FÙwZÌ3ø?LÒ•d·÷wNÄ …eŽÝTœç0¶xî:óIõOømïu‰u+{û{h-ZÒÆÞ7Šáa‰cB%iˆ²"©ù$Á†A hš&ÿΙ{{¦jÚ¾£¨êW0Ûé׉ú´·*˜$,Ìg#ŒtsX÷^wñ„Ú•q®æüØÚO*¥Ñó6#)ÜTà›õïWáñ½îŸàh4>þþË}åÜ׉ÍWKªÁ[æÇ—&C a»äÕ_jvÚ.™¬]‰?âm,?aµiùeež\à©Ä`Å´óþ‘¸R€6À©âÝGQo Íh4ûK›m6¸™£{Ù¤GHÝÆA™áfÙühÎ×2oßÁ5§Ùä¶7~“o¶Š!ÝAÈY£ùAÞÀ÷ïM×¼ã/ }—íqO'•®éº£y*§÷Vþ~ð2GÌ|ÕÀéÁÉÈÁ™w4 {-æÚ¸sò2±ì|#à= ëû7ÍÔ¬ävîÖ„ ±*×qÛæF]2TnùÓu¿ É ðýÄ?ô¥©'Ô´mJÔ­4[›ýF]N¶ž[ûD¶XbYR_•RY71xÓ’@Pa‹‹á/ù!¾ÿ¸‡þ”µex«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^iâ¯ùõúó›ÿ@5é~#ÿ“qÐ?ìW?úGx¹Çû£õ_š=¬Ÿýíz?É•ÿhÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5ë_´ü…lì"ŸúI-y*ÿ¯÷WùšÏ'þ OñËô+7þ4?ÁJ(¢½ãÃ#_õïþêÿ3RTkþ½ÿÝ_æjJ§¬jÖš‘}©ßËäXÙ@÷7í-²4RÌØ“€ ÀÕmWT½Ð4ûýWTðŽ4í2ÎÝ®.onü«Å  fyÚØUPIb@k/â¥Æ£ðÃÅö¶°Isu>yPB…ÞGh*ªŽI$€ë^ßñËöðwоüNµÒ¾+üJ×î5Ÿë–¹ð4‘X¼·“ÇQ£Ç2ª¼‹µš|ü«½˜nÈš\ÍökieÆï- c8ÎkÛcø 1¬wz/ÚéYL7B!q÷¶©•ˆÎfÇ©ë^©FÃNºýãÝ?‡Ú¿Cuù\ÿ×Vþf¾Gˆ±µ°T©Ê‹µÛïúXïÂSI5#åÉ?fÝQžYt©"Ól x–áVë89µIceÎpr§¨+ÀfóOøvóÂ$ÔtK÷¶–îÉÑ^K7g‰·F’ U=@äûš¾<øÛÿ%wÅõÖßÿI ®L‡9ÄæÞ²VQ½Õï£K]_sLV£ÍçEz¾¯öß´k_hóÿá[y7Ù÷}‹>[ýÈíçyž^ý¿¼ÿ]æñçV¥Ü:ÌzÆ€÷z\ö~“MÒŽ¯xmÝmnà YÊXÕNUÀòÀ•‰o¹<ÃÅ(¯DÑá&ÿ„sIÿ„û[’ÿÚߨ^o›öŸ:Mžo—ómò|­™ù3æmù¼Úá5O7ûNïÏò<ÿ9üϲù~VíÇ;<¿“nzlùqŒqŠ­EPEPEPEPEPEPEPEPÏ‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôeox+þG-þ¿íÿôbÖ ÇüŽ^8ÿ±ŠûÿFP´QEQEQEÑ\øZµ°o£l—ŸgP·{Ÿ%HÈY ˜ØCŸ—…ËMsµèž4×ì´kÛ°ØÎšÔº…´·Ó\«Ä"“N…Ë„F ±Še†ˆ¶”á/4Ë› {çdW°›‹vÜôa€…¢½s]Óžj:…¼‹}{¥ÛìJ·h¿T¶&;…9§¹ùד)Êþð¥c¯öÿü$zgü'^ŸäÝ}‹þy¾w’|3Íù¼Ÿ?ËÇ™û¬ù½¼Úóº+Ñ.?á&þÓÐÿáck`ÿiAæÿnù¾o•»÷¾VÿÞíÙþWò÷såÖÇŒµ-TøKTŠûAñ Z|©ÚÜjÚ¬siП5ZÍãbP2¯’p#g*6@GE{6¼Þ%Õt-FKˆüC Ø-´’®ßíZË´áN€/›–h‚²š x—Tдè-ãñ‡`-£Q{hÿhÐB…&x°#-;³É†î$ª€xÍWaàë{oi’øvúïì+o1Ô­î¼³'”T^ ƒ¿r‚^NÑv(Ì”ÇÕRÇû/S»²ûDg™áûE«ïŠ]¬Fänêq{‚+f÷Ç:˜ñ-Þ­¤]ÝèFD[xRÎå‘â¶@«%פq®O-°Ív7s\|iñ­Å¤š—Ûìïïg¶µÑ§0ÞÝ1¹òÚ8œ+BHîp­”Æ%€–Q^‰ñnÂæuÑ5V³¿\Ùýšþæúä^L—byȆâuUa—ò0ŠHùk˜ð§m¢øçú…ìžM¦¥mq4›KlE•YŽ$àÀ µŸêºªÜ^Á!q‚;ˆåx$ ‘ÊŒZù[ä+|ÇÊØµsà jÖÀ]¼VŒ ²^}ž=BÝî|–A !d2ca~^,p5§k¡_øCÃÞ&mbÖKÔl#µ±’A”»µÛÊL,2$M‘3y‹”å>o7_ñ¦¿e£^Ûý†Æt֥Ь-¥¾šå^!št(þ\"0UŒlS,ì0Ì@ ´ 1¦x#WÕìcº¶†³gȆ[Èbžã¯îawK–FÅ9`Td‚+ »¯øcVñ}Õž©£ióê_öm¼—Ñ'î x­bŠQ4‡å‹k#\¨ ‡û¬ð´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWQá/ù!¾ÿ¸‡þ”µrõÔxKþHo€?î!ÿ¥-@^*ÿ‘_Xÿ¯9¿ô^—â?ù7þÅsÿ¤qךx«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^.qþèýWæk'ÿ{^òeÚ?þB¶?öOý$–¼•׿û«üÍz×íÿ![û§þ’K^J¿ëßýÕþf³ÉÿƒSürý ÍÿðD’Š(¯xðÈ×ý{ÿº¿ÌÔ•ÿ¯÷Wùš’€ ׿û«üÍIQ¯ú÷ÿu™ xEÄDÄ…u*Hë‚1]ÜŸ> K#;ø¦rÌKö+NIÿ¶5ÄQ\õ°ôq *ÐRKºOó*3”>c²ü~deÿ„¢lüyZ{ÿÓjå5­jóXÔou}Zñï/.’{‡DRv¢ ùQ@áPtª™Ü²³, Æ=ýýê¾¥#:ë÷l?tüäzzŠXL6\ÔiÆ/ºI~EJ¤ä­&Ù»ÿÞ¹ÿBþµÿ‚Ëþ"¬ê:w‰uk„žïCÖ¥•!ŠÝ[û*a„Ž5öDQž§95»ûj|eñà Ã:W‡o.4[n{†¸Ö!‰ʆPaRÊÁ$‘¦B ˜ÁÃýŽ>?ø¾ãâý‚5]kVñFƒ©Áp":„w-”É›Ík‰3!Œ„xö³¹ãÛ·Þ•Z˜JXèåòrævÖÚk²;ðÙ&kŠÈ*q=ŒVr÷Ý·iZÖ^m7Ñ3°–)mç– àšÚâ"Hn"h †U€#‚ãI]OÅoù)¾#ÿ®°é45r÷Âdz–©áØMØñ–—-=ä’©µ­ÑÞdXÂAˆÜ+–mÅW(›Ï—5aìêJ £hñéOÚSŒßT™ÅQ]üžÐÿ¶t˹u}bÚÅ­älæžœ, ¦\3ÈGÈG–…[2¶PcÁ¦èÚ&•¦ÝëV×úŒºœ-sVil°Ä²¼_3 ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ•½à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý@ÑEQEQEQEQEQ^¯â%‡J±‰/àГC“Bµ0Ám ŸÛ互Â6F%ž¸™¼Æg*¥U†[r£ó°øÂÚV—á­GZ½Ô¤³O5Žž‰æ.¦…˜HøTcR«‡,Êà˜ÁV *ŠéàÒ4m'JÓgÖ…üÒê°´ð=„ˆ«k•áÞÊê|Öߟ,4c ¿>\ìÝðŽ‰£h¾+×4={LŸRÔtøuHÞ[kÄ[ÜÚͨð1Ý”b¯‘ƒ´íùp@<îŠéìôÝâK[{køô;I ¶[»F¹’YRB¹›Ê ª<™Ÿ,Ÿ¸¸äºÙÿ„:Ëö§›?ööoö¿“¹~Õå}§ìÞNìmÝçqæc>}™ýÕqôWOm¤hÞ&ÕmàÒEþ—Ãq=Ò^H—L‘CLÏ*ǹŠ#UUùðÇaukd4ÏøH¼;öý/ìÀñÜÝ,²¤®²¶öZÄZ•ÅýÅ´MwcqEn³D² 4dÊUXüñä’£`NŠïü?à+6Ð4ýKRXï¢40§ˆ,´Ãk#Ç–†g,Èý( >f,Bg‚ôCu«[$ÒxšâÖþkXa°Ôíì^Xб Cpe;‚¤Y+°}ï1h€¢»]Ã:%Þ¯«Áp—höΉ•}¨[铦sæïže(LLmÚ¬û÷a6²Œ/é°é:»[Ea©i.¨¦[ X><à¶ÔÜ í`J'ÞÆ70=§á«-S[¶²¿¸û$¡[†uDŠVR"ið#.z„ ŽqVµbøxO¨¤öº´÷ ’ Œ‘E¹fi€a™ ¢‘Æbœ…Ev'þÏ—ÀÚúTWö–m©_!µ½ºŽãkˆ­ uu†3óPAÈùÉÍýCÀÐøKQ¼ki4ÝKL¶Š{„—Yµºwc,p¼mjвÀCK“¼»v0ÉÈà(¢» /cð–… { Ïík7»¼û}ªLÎÌЈՈÝí‹9Œ«åØïá6qôW«ÙøqôøO,´dÒeŸM×`±†ã_G¶\€›˜Ç;pNÞ˜±ï'Ó- ×|E¥[Ú\Mmsae–Õ^ÔÉ$›‰’]¸i bŠÊ¬‡¬`E^ÖuwÖî–æ[kKi¶ÙÀ°$„†1¦N0>EPv‚AbÄÑ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“+þÑÿò±ÿ°Šé$µä«þ½ÿÝ_ækÖ¿hÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5žOüŸã—èVoüh‚$”QE{džF¿ëßýÕþf¤¨×ý{ÿº¿ÌÔ”Tkþ½ÿÝ_æjJ׿û«üÍIEWÔ¥…Ë)*Â& ƒ‚ zÆÔøið;Ãvºž§ ê:•ÍõÇÙ,´û-Fo6i63’KÌ¢…;Ÿœd 2©Þ¹¡:²’Œc«lÍ9ν<5rJŽÑŒUÛ}’îîyµA}Meq »ÆÊ©"µÿgï‰>6x‚_ Þø:÷Ã^%Kw»X?¶®.­gYA͹¸ ¡xɶ¶-øïE´ðïõ½6Â7ŠÊÞX„Q¼¯!PÐDÇæbOV'¯zJœeEb)ÍJ/K«ÿ‘®"ðxÉà1t¥N¬wRVýYÕ|Pñ—ÃïŒ^Š|1­ÞÙG0º£h¢’ •YVDeœÀ;rb y‚Z7Â߀÷W†‡¡ø£Q×.!kYuVKi.áÌaRDWr©ùPµw‹w^Ö¬ífšH­7Â…å´P·{¨ÂŒ¾ëuÊ¥%\ V,Óˆ´Ïjú½ŒwVÐÀVlùËy SÜ`•ýÌ.âIrÀ¨Ø§, ŒElñR•EYÅs.¶×ï9aFTðòÁ¤•);¸ó>VûµµÈld•€Û‘¹ê3Í99ÉÉîÍ¡¨-–…câ¼³ZO¦hÖ–Ú…½…²jò¾Ô’EoLê<Ó ¡ÚÁµ†×Œ}3ÅKic¥þ‘a®ÁE°¿3«[‚IeVŠD;I%¶± Å@,ŨhÚ-Æ»tÖöÒZDê…ɼ¼†Õ18iYTžzž¼pjÔ6Vº¯=·ˆ4û»€ˆ1•äp’N\Hc‘] œ‚£ X6:ÁfÄ>8±_ Ácw Xj׃R»½sr²ÃbT€ÛËÄÙ\` »qȬ{?ßÚøªËÄ,ÑÜ_Ú\Ås‘1c*Q6®  ªp€xÏF‡Ã¾0×t«f‘íìo絉¥ ¹T‘” œpcÐíY›Eºi#XæŠT1\ZÎ Šâ2A(àq ‚¤+)VPDºÞµ­ä¥¾“a¤AãåY,‡se™åwsÀ.í£€ 19”PEPEPEPEPEPÏ‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôeox+þG-þ¿íÿôbÖ ÇüŽ^8ÿ±ŠûÿFP´QEQEQEQ]­Ï4Å"ÊßX»—[þËMPÁ%‚¥°_² ¶O4L["<û¾XÀ9UÑhß|Câ²û™$éxŠñM½,4¯o‘ˆT-$NŠ‚ÄÈÍ]Â:®¿j×PFèÅ’â8žyÇ »™þeù# ß:qó.@*ëZÌÚíäw7 :[[Ú m†‰O$òV0O¾zt£QÖfÔìô»iV5M:Ù­b(,¦i%ËsÉÝ+1ÀS³àß]øÉ¦0ÞXZÅ7fâúÞ9 EJ–ò+m;@/ª $áMP‡ÂZƯ>›Ù%šK2_@m£^>fŸ”YW%¾óûÇ.™âÙ,lc¶¸Ó¬5_³äÙÉ~ŽíhI,B€Á]wÞ\Ó%Žß÷UÓ¼G{§ëoª³ý²ê_4\¢Ïö…•Y%W9 ó«¸,o˜AÁ£þKûoû'ìßéÝvù‹³fÝþg™ž^ÏŸÌÎÍŸ6vóRêÕtÛ«;v‚;·¼*Üé÷Þ$²d-Ze/ó/ÉÃzñó €Ko⥵¾»hô‹¥Ýl2èìgkbTaX'˜Ä0p~g\ífRÂc{ý§öŸ*²y?eþÌÚßeû6íÞFÜçn~mÙß¿÷›¼Ïž¢Ô<;qáÛ«7ÔáŽâÊWåôûØfI‘½ḧ®•ܤ®ͯizeŒ:Þ•ݽ¾¥`nšË…Ñ…Äðc@A÷{šŠãŲ-õ¥Î™§XhgÞDvhî²\HfiÕ—å1±)‚ÃoÎû¢Ö|Hu;U´µÓí4kâW´±2”’@í#»1l.[hܵ«¯kVv³M$V›áBòÚG¨[½ÔaF_uºÈeR€À®P+iÆÚÌö²\¬25¼n±¼ÁNÅf UIè ÄûO¡  :޳6§g¥ÛJ±ªiÖÍk@Ae3I.[žNéXqŽú–ñ¤3µ®¤Øj3Ã$2jË:ÈDˆR\Fe0®õg\,`(c´.9Šè´¿i‡B‹UÖu+»+{‹™mmÖÆÉn]š%¤.XÂŒM0[?6q hï¼½2âËìð74s}¡“2¦Åqµ[²·™–Ê'¥V­ˆ|8ú¦¯=¦qõ¼h&û\춨‘œs+HÁc ²¡ËÞB«6T’ê¶ú—ØLÉ1¶’ñZ ˆåŠHcGwt‘X£€#¤òŒ¿x@aÖfƒB¼Ò•c6÷W0Ý;w†‰eUçÄÍž;œæ×†üH|:Ú‚¶Ÿi©Ûß[}–{{Ã(B¢XåÝÑ/Z—Rð>·¢ÿgFËû9¯¦kx’òT…‘×fDªÌ \IfM£k†èsGм6Þ]"9÷÷6fâY#º‚âŸ*ÄÌ6áNwíŠ?á*X5?´Ùi}³Ãö{>;ÛÜ¦ì‘ ’Fnp¼«¥—k(j«­ëQjÞJ[é6Dn>U’Èw1ÆYžWw<îÚ0H³.³á-GCµ[›²MnÎ#3XßAvˆÄÌNÁ ˆ ŒílgiÅÿéº7ü#:N¯¤[_Ùý¦òêÒXonÒãýR[°e+xÏœA‚€0t½NçEÔí5 )<›ËI’â6†ØêÁ”à‚ŠÞ¸ñÂ˦]i‘hM¦™>$6°¬ÿ,áYRq#Jd,ªì3þbvd’yŠÓ¸Ñ< Øjþvïµ^\Úy;>ï”6ìçœùøÆ8Ûß<_ºñ‘¾µ˜ÜèúmÆ«2—W•%k‡ÈÁvS'”\©ÁsìüùßóÑkã#¬+w£éº­åºíïï’W–%QˆÔ¨G N€JÀ rŠªxJOë¶–ÃË{ss s·Öö÷+¶ Â&uää®zŠ¡¤xgR×aylm¼è£™ w2*ª3$Ž #j„†V.~UK(֙⥴±ŽÒÿH°×`ƒ"Ø_™Õ­Á$²«E"¤’ÛX b bÅŠ"ƒínÐt[Í™§|RAå3}à¿gx¾S„9UÇÊ-’ûÀúÞ›­Ûé7[/.![˜H•)!eÞ&†1˜Â‚KîÚ¶HÚqW[ðÝ÷‡ü“v°DÍo'öä6_½_¾ƒÎtÜË‘¸ •ܹÆá *ÝÓ<[%Œv×u†«ö|›9/ÑÝ­ %ˆP+®ã»Ë:d±Ûó¾ì½OL¹Ñ老»Êž<V¬¬ ¬`ÀÀ‚ ­@rxŽö}3Q²þÓý¡yõÅÄÅšV•P byÏžäç$œs×&‰¯I£ùÑ=´„ûLö7{ü© çc|Œ¬¬¹8e`p̹ÚÌe{YÕVºY"°´ÓaD µš°E$器’I˳€¡@£EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWQá/ù!¾ÿ¸‡þ”µrõÔxKþHo€?î!ÿ¥-@^*ÿ‘_Xÿ¯9¿ô^—â?ù7þÅsÿ¤qךx«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^.qþèýWæk'ÿ{^òeÚ?þB¶?öOý$–¼•׿û«üÍz×íÿ![û§þ’K^J¿ëßýÕþf³ÉÿƒSürý ÍÿðD’Š*ËË}:Ò{«©ã¶µYg™Â$h£,ÌÇ€’zW¼xc—ý{ÿº¿ÌÔ•Æ‹þóœÿÂmáÜmÿjÁêÛ®ºy…¼JÀ•E,@ë€3@S$s–EcêFkÒáø5…>Ó¯j¶÷G› x/R‘cnê…,ã%W>ƒ¥U“àŠîç”èvkv B‹¹ã]-Ë` NŽ1Ÿ¼»”ÿ{;•|Êy–¬Ü¬üÓ_‹I:3н4Ô Œi×DF ˆŸ£Ð׬~׳þ«ñ³AЯ|55´>%Ðå›É[Éš8æ¶™WÎŒ´0$cä • ¸yö¹¢_xV½Ò5kO²_[IíÚHår+™”å]zø¬ÏìË?ùôƒþýð¯f)NŒèÔ4f—SU18Lev§%JNéÚú‘~ɲWŒ<%ñ&ÏÇž<³‡Gm6ÆŸ¥ý±fº[‡C ’Ch¶yO(;\o=¿Åoù)¾#ÿ®°é45ÆÿfYÿϤ÷ì…K Û©X£HԜᚠèÑÃ,-Y'}ïú#l~+šæ̱Õ9êI[Eeo½ž‘ªj:F¥¦]˪ëZN²æki Óæ¶ÕD¥NÃ+,kŒ_gše’S&Æ,r×ì¼z.KÔ`Ö´]m>ÚÚ ΃Õðh"DC/ÁË ¾d‘íc·!T9òÊ+¢º×Q¾iš4wRoMRîò{PX! ºDçøIùf¸ç¦îbð§m¢øçú…ìžM¦¥mq4›KlE•YŽ$àÀ¬*(¬ðEõ…¥® ’]iº~¨ï‚óW±û]¸„ócÙåK‡f0Û8ãpÎøªXxƒY‡V°¾Žá'¶‚·û/Ù¥„Ãqñ¨ò9Bʱ»0Þ•ÉÑ@¾=Ôíµ¯ø‹P²“γ»Ô®n!“i]èÒ³)ÁŒ‚8#5…EQEQEQEQEQEQE³à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý[Þ ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ”-Q@Q@e´»Õ¾žÈÚN/ ó<ësy‘ù`™7.26…bsÐ)ÏJ­@v4ñ¼ºª[ØXÍöré¶ò¼6qÅ,´*é$¡’(‘ ÅrŠGÝR8ú(¢ñ.ºš—‡¼'§Åu$©§XJ’ÀKŠg»Îã% Y#®'Œ K.•âMFŠ÷VG}"ÙídŽH$•îc3Ë0hv.Òÿ½eÙ!EùPïù›g'Ev^-¶Ô>"kÝÚý‚ [ûENI‘mÍÔ3"– dª™A$)8 NGbÚt6·†¥Öm776×qjéæÛtI(ØËå‰@"vù‚™ÆÖÞ¼ÝÂM¦ù_ØiÿAþÈþÇþÕòÛfÿ¶ý¯Íòñ¿Ëßû¾›ö|ûw~ê¨é²é^Ö`•uhõ¤žÚêÖâM> CÐ<;—ÎXÙÝ|Æm˜U;ToùŽÎN¶5ß j>µµ¹»û#Ûܼ‘Å5ôHYRbv"}á@õ)ìtO Üè¶š”Ì··^Ish’¤Pˆ’dTýê#37žÄü (UÁbÄ%_êv×ú?… ‚MòÙi¯op»HØæîæ@9ü’!ÈÈçA¬*(Ñ5MGHԴ˹u]kIÖ\Âím$|ÖÚ¨”©Øeeb‘‹ìóL²Jp$ØÅŽ[‰…hWŠu "ss xVÙ0Û.e';AL…ò|㎆¨Ñ@už ½6V·>OŠ-4S#qcªZË=­Òû²Qb•d*KœHƒiÚT’NÞNŠô›Oé–ךæa6›a ûÙÎ/ïtŸ³3à ¬ÄBÑ9$ydt+Tm]ˆ¬vEŒÿ³üam{&»íc¤^ÚÛÞiV?b†^ )aTDoõ’©ÞQfnÊùÝWY&³£Ï/Vùd½°Óí„Z•¼@«•ûuÄ®Šr¹&9âê8äè I×uË CÁ÷ú4Úö‹5ë\èG.›£}ŽÝ–(æO'r@ŽÒ±”(ëb'y©ÛKàm#OI3y¥{q${OÊ’Ej¨sŒ˜Ÿ€sòóÔg Š+°±KÖ¼ §ióëöE妥wpÑÞÅrÛÒH­•J˜¢qÖ'È$žµÇÑ@ƒ/lü;ñB»¹»ì,uH%–î$r†4™IuR¡± ƒíž(ÓuԲ𽥥ÔÜ__Ù9 41¥ÉmØà€ïÁï‚s´P¢h¾7²Ól´›Dšyt'ÒçžêÍnbµ”ê2\©xH¸‚@b¡ËÌ›N?õ—¾µÓìα¦ê‰Ë0M#K[+x‹„ÿª‰™Ï–3”À ˜c’“¢€4ü-­ÿÂ5âm#Wò~ÓýŸy ß“¿o™±ÃmÎ3Œg­jz&‘ec%Í·ˆàÔ±äZEk2N2Gúíê#L.s±äù°A.0¨  ÛÍNÚ_izI›È5+Û‰#Ú~T’+UCœ`äÄüŸ—ž£=¶‰âN²EPÓlì®t¹4ÿ² I{̶­ “KpbÜ"óYäÌrHÛ ¨ªùeßè—vQéÉcuâ^Ù@òFmu:èäb Å ™b$‡µ˜ÚìOk³jÖñ»H™ÆÅf €Î!ßhôún”¨a©RžñŠOÕ+5I)NR]Yë~Ñ-“w¡Þ·Û.aЧÕ^(4r±´70³_Œ‹9\nýß*ryƒ¨7„ü9¡\é–¶ ¨Ã,—w7¶0^m™&tòWÍFTÛ‰È1óbA@¼Ì~;¾†ÆÊÊ?\%”ÂâÖÝoXG ’vf99'Ö­é>:Öì'½»ÓµØft·‡.®<§Kƒ%µëø‚úÆH ·¼ríLVÇv_ ù¡Q‰o½Ôæ¶|eáˆì¼;¯4ø ¶ð™g´D‘biòy­æ&F×”¡,Šœ’EyþŸ¯jzE­åµŽ£weoxž]Ì6ó´i:ஆ†©õ©tÿë:Mñ½±Õïìï +nn-î^9 J*n;@DtG  DþÆÂš›w£Ø>§máo´´WP¤ž]ÁÖ|°îü´D!J¶q´£©’³>+én›¼iútzZ뺞•Á»˜ û9qbK6e–bOÍŽUW„þÔ½û?‘ö¹ü'ìþWšÛ|¯3ÌÙŒão™óã¦îzóEæ©{¨îû]Ü÷[¦’á¼éYó+ã{œŸ¼ÛW'©Ú3Ò€+QEQEQEQEQEQEQEQE³à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý[Þ ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ”-Q@Q@“ªÝC®«ã%š3q¬Ø-´X`eÒ—ÌÉ÷@*—‚òÜ…]Ãeïè–‡I»Ðï[í—0èSê¯ ¹XƒZ˜Y¯ƒ Æ Åœ®7~ï•9>Z×S=¬vÍ4o´‰ c±Y‚†`:B('¾Ñè*ô~)Öa±²²W¿K;)…Å­ºÜ¸Ž A$:.p¬ 1ÈÁÉ>´ºuðŸ‡4+2ÖÂáµe’îæöÆ Í³$ΞJù¨Ê›c9>p,H(][×WÓ¥ƒA’ÚõüA}c$[È^9 v¦+c»/|ШķÞêsXZŒüA¤]^\Øëº••Åãù—3[ÞIÎÙ'sAc–c“ê}j®Ÿ¯jzE­åµŽ£weoxž]Ì6ó´i:ஆ†©õ @ñ—†#²ðî¼`Óà2ØÂ>ežÑEˆI§Éæ·˜™^R„°8f*rIgû? h~mÞ`ú·…¾ÒÑ]B’ywYòøòÑ…*ÙÆÒŽ¤Jó½?Å:Γ|olu{û;à ۛ‹{—ŽC… ›ÎÐQè*¯ö¥ïÙüµÏäy?gò¼ÖÛåyžfÌg|ÏŸ7sךîþ+én›¼iútzZ뺞•Á»˜ û9qbK6e–bOÍŽUWŽðµ–©âm"ËR¸û&qy 77Õ<¨™ÀvÜÜ NOÕ[ÍR÷QÝö»¹î·M%ÃyÒ³æWÆ÷9?y¶®OS´g¥V ŸWÖµ+ë}GNŸA°µŽËïذËa¶EOšEC‚DgÎgÉ~rûX‡ü“=þÂúþ‰±¬»ïë:¦™o¦Þê÷÷zu¾ß&Ò{—x¢Ú»Wj€HŠ¢×S=¬vÍ4o´‰ c±Y‚†`:B('¾Ñè(Ô¼?¢Z&ïC½o¶\áOª¼Ph6åb hnaf¾ '/r¸Ýû¾TäãøW±±Ð4ûbÖšì¨ò [A†úÚï÷Ž<ã3£Êƒ åŽ6]ÑdYÊòqø§Y†ÆÊÊ=^ý,즶ërâ8%è¹Â°,Ç#$úÕ«ø›KûGؼE«Z}¢f¸›È¾•<Ù[ï;a¹c’y8 ŸNž iYjx{QþÒ¸·ûDÚDZ¥¦ôÚ ¦.cXIÉhüÇe”d6ÔÝkNÓtý2ãÄZ®® ‚þ×ìOöv™í¹†xÙж•ÑU[÷?xmCpFŒSËá4Oë>ó¿²5{ý+ÎÛæýŠåáó1œnÚFq“ŒúšŠÛ^ÔìõsªÛê7pj…ÞC}ì³–lîmàîÉÉÉÏ9>´Ýͪh‹­A©Å¦]½¹ÒËË©¾ƒn¨’}¤§ÚVËy“nÛ~X ä¿ßáxÜ=Ý®Ÿ¨£i·vS¼±C{a`¶.J„c °¢ªA"Ê4#…q¿á)Ö¶ÿ¶µïÿ¶?è!ö—ûGÝÙþ³;¾ïË×§*-g^ÔüEt·:®£w©Ü*ÖkÉÚg !AbN2Iǹ  4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÔxKþHo€?î!ÿ¥-\½uÿ’àûˆéKPWŠ¿äWÖ?ëÎoý×¥øþMÇ@ÿ±\ÿéuæž*ÿ‘_Xÿ¯9¿ô^—â?ù7þÅsÿ¤q׋œº?Uù£ÚÉÿÞ×£ü™_öÿ­ý„SÿI%¯%_õïþêÿ3^µûGÿÈVÇþÂ)ÿ¤’×’¯ú÷ÿu™¬òàÔÿ¿B³ãCü$¢Š+Þ<0¢Š(¨K„²*:)=Ï¥MQ¯ú÷ÿu™  Ú”Êt롆ÿTÿÀ}µzßícñûQø-£h6ÙÄ:ì³ùS_ÂÒE´*¾t€Pd,  œ|åˆ`»O”ê ^ÂåTcÉ'½;㤠>=xZÛHÕõÝGOšÎãívwöZ|þlRleÁÝ ŒæN3€ATŽêN§Õ«F„ÔfÒ³}õ3¢ðtó,%\Æ‹«B2¼â¯¬tÓOøèÖç˜~ÊŸµŸŠ|Wñ2ÏÀ~4Ô ×¥ çOÔÅ¢Etn#C1ŽAX¶yI)"P[wËÙ|Vÿ’›â?úëþ“CX³·ÂuÉ|Ewãïx‘íÞÑnqmk lÁ‰Ž®ÁÈP¥Ì‡Œ€3gGÇzÕ§ˆ¼o­êV<¶WÄb‘âxË‚%?+z©;TÓu々ö;dîê^²ðî§«G¬ê“Á§ZjW\–k4·2ÂÃyò̈@d$—ÎdP¡°ÅI|k¤¾•§Áÿ÷™}¥yÑi÷7^db•¥Ež"›fdi$ ŠÄ€èÊ Kiþ&ÔõËíJçI‚ íJ{õÒµØîÞ(šVÎø¥µ÷c*àìV !ÈXVÿ æ¿Öoc±}KRÒmm¬î^âÇL3]´À²Ä¢Ýd#8-’\(~mÅU‰¾Íoâ(4ù_R‰'°:„V¯¦©È¾i‹bÚyœ¾ågÀ“ýR—Ïj®µãë]gYÔÝŒ—Z%ÚZ#ÁŽÎRöÐb™6«$Dùk 2Œ•W\íMûO?ØSÿey>W•öóö­Û·yžnÍ›³òãÊÛ³»ÿy@x—I°Òn¼›+Û¹ÝḷÔ,¾ÉqŠ@!;®9ÇÞÝ•`Up c×Eâ¿ïÚé¶–Ö÷qÛØ#$Rj7‚îà) B@ˆHäŒ/Ê^CŸ› Š( Š( Š( Š( Š( Š(  ŸÈå ÿ×ý¿þŒZÁ¸ÿ‘ËÇö1_èÊÞðWüŽZýÛÿèŬù¼qÿc÷þŒ  h¢Š(¢Š(¢Š+º½ðΛoâŸÎ-±¡Ûi¯ª[[ ÌŽ+”Af3žYêܸ,Fù~pµ»yâÛ›ÏØè,¸ŠÚbæLv‰1Ž6<÷Mœå¼ìp±¢ü6›]𬚭¼ZÒ:[\]¤ÒHӶ˜}¨Hy+äûø^>õfYx{L¶Ó­/5ÝJîÀ_#Ki’Ý;Ʈї}ÒÆGP$ìbB¥´í|a ÐÞÍ¢Iqª¥ÜLovÅöo³ý˜˜£ ””ÄÜí"ä±òùh§ˆôkËx­u]&þêÖË|zy¶Ôb¤i<©ÀË&؆ ‡.ÙÈÚ†¥áô°Ð­u(ïc»IïČ„+ ¶ çp ‚6ó×þµà¯ì}&êûížw‘ý™û¿+nïµÚ=Ç]ÇîlÛþÖsÇJ–ÏÆQФÓuÇt‘_ɨX‹{É!HZEUx\Í$GË‹€ÊãiÄŸ6jõÇÄ{-eµXµíVz„6K+•µ’í`¬‘‘Œ+)—1ùdãm€UÓ<mu¦Çy«ýŠ×û êòld`ñµò”åŽ7p2B’£.+xÏÀÒx;hkø/Ù/.tùͺ¸T¸ƒË2*–²* Ę8€¬Öu?ˆÚZl–ƒJ‚Ñ[HJ­³lŽ5ÂéX. 8'ÌK—f$œÖñá,ûGúÙ|Ý^ûUÿ[¿iò¿w÷GÝò¾÷}Ý9ÁÔl³®/´Auº¦ßlûÔo_i?Þ]ÛXveaÚ«UFâÚæáÒÓìqbFÌ2eÖ5W|Ÿï¸gÇA»U¨º½ðΛoâŸÎ-±¡Ûi¯ª[[ ÌŽ+”Af3žYêܸ,Fù~E¢ü6›]𬚭¼ZÒ:[\]¤ÒHӶ˜}¨Hy+äûø^>õcÞx¶æóÂ6: ."¶˜¹“#ç@]¢Lc=Óg9o;„\lZøþ¡½›D’ãT6K¸˜Þí‹ìßgû11F))ˆ¹ÚEÉcåò€fYx{L¶Ó­/5ÝJîÀ_#Ki’Ý;Ʈї}ÒÆGP$ìbB¥ªê^K ×RŽö;´žþêÉLHÁB°°‘Ka°Þw¨#o=p/§ˆôkËx­u]&þêÖË|zy¶Ôb¤i<©ÀË&؆ ‡.ÙÈÚ[?iGB“MÔ|;ÒE&¡b-ï$…!iUápw4‘..+§|Ù µ¯cé7Wßló¼ìÏÝù[w}®Ñî:î?sfßö³ž:U3ÀV×Zlw÷š¿Ø­²¯!ÆF__)@nXãp'$)*2âÕÇÄ{-eµXµíVz„6K+•µ’í`¬‘‘Œ+)—1ùdãmÕÔþ!ÿii²Z * Em i*¶Í²8Ô_ ¥`¸$àŸ1,N]˜’r[Æ~“ÁÛC_Á~Éys§ÎmÕÂ¥ÄY‘T°” Pn |ÁÀfÁÒôËkS´Óì£ó¯.æKxcÜ{³Q’@$rN+{Æ>5ÿ„³íèeóu{íWýnü}§ÊýßÝwÊûÝ÷tçK¸û&§i?Ú§²ò¦GûM¨Ì°áÞƒrå‡Qó@äu ¼/¡ÜèÚÍÆŸ®]Þ^évÉq*6œ#·”â„ùrw‘™A£R@ä)â¬Ýü6š/ɯEµ Am Ô¯¨é&ÚÕÕÝÏæ7˜wH¤eW*¸Æ ýkÄš^™áÍZÊÑ´+ËÍ^‚itK[˜¹Y£”ÈæuP™1àEªä¾\jjÜüAÒo.õ›‰ô Ú]{sj².¡†$ʳ‘mû¬D¦TRD‚S´±Ì‡Á^w´?}³ÚÙÿé>Wú¯µGýÝÜíóqÔgolñ—‡´Ëm:Òó]Ô®ìò4¶‘XÙ-Ó¼jíwÝ,aAtuNÆ$(Ú[wMø›a§jþÖLJ#“\ÓÖg{ÐMUYbd;%1¢&ýÌ£•íe‹ÃZ––º%·öŽ£¤ÌÖ›ŒPj–73\Úň·þêU9 #‚o. ¨fgµoðvõõ=r2šµö§jSékq£éMy,²Äß11‡Qà©Ë>rà(l9^OÅÞ›Â:üúeÇ™¾4ŠP&ˆÅ Y#Y:ìp®.N“ŒKÇ6^"Ôõi5.yôë½JãT‚ÞÒña–ÚY˜oaé €‚™ÌjT®X71©Ü[]_I%§Ø­xXà2Ë1êÇ$2NFjx;Ãð•jrÚù“¯— ›É²·ûMÔØe]°Ã¹|Æ·¸aÛ¸7ÛÁö:̶ZØx-¯e¸‡PÓþÍq –ð<¥1#®fÜïÜl¨À݃£]XZÝ7ö•Œ—ö®…JAqäJ‡ †GÚÊ;•†¸ ½b|I¶¶ÕtYcÒ§¾Ó´øfµx5kó<òÛË’ð ‘#)Ç»b…ùݹ݀Ì[螆oõ;oÙo-­<Ÿ{ÍIÛvsÆ<ŒcîíŽw|Wà}7Â7zå…ω ¸Õ,fx­í-­Ùüݲ„"GdlPï ¥ñµ•Ê0ÖÔ¼[e/†nt7Iû Œ—^,³L²ÜD™[Ì"ïÏœ0UPœ)fvl¿ëð’ø›WÕüŸ³h^MwäïÝåïrÛsœgÀ  KŸ}›[ÖmZó:vŸf×ëå­•M³ù{²¾i–Ç%<ܰù[ƒðOSÕítá-¶µÞ¤‘Ém%¶Óآʦ¹Þ ÌQ_jž~`ȼç‹no<#c ²â+i‹™2>tÚ$Æ8ØóÝ6s–ó°xEÅ¥ñ6“ k:<úŽ©o vñË÷‘©ˆMŒ³aUP”xÉU.@*Åá+›û>œßm—X™¬Ò<ö],|œ±çä’ÝÂþ÷ʵeê–öÖšÜWo³ŠgHn¼³œˆWØy\ŒFq]‡<@žð~¸#Ô#7·î¶ÑXÛ|`Ç"=Ár»Hò¥š™ÉóËàÔžN€64- û[­CPº’ÇIµxâšx!Jd92Ê "7bK(ÛU¥þЃÃŸŸ¢]AªA,8Χ¥ÄìŸ7*ÑJ$El®C#7ÊÃK(‹B×a°µºÓõ Y/´›§ŽY ‚a ¢HÈÝ$*À$u «¸Ýµ–®³uaut¿Ù¶2XZ¢ =ÇŸ+œ’Yßj©<àmUUàœ³oxÏI…þ+kºeµ¼‘[j{h °·ê¾{(X¢C8Tg‘V|GðÒmëCV–ïN·ÕnZÑ$ñ‘Óž&Séw8*üùþàmїƾo5_c¯8Ãàp9Ýl&W‰u¨%tÛO]4ºÑÛº)Ýx?PÓ|3ý±gc³B–†{)+”t‘ˬ¤mãb`u`ù)ª¶þÖná»– "þh­!K‹‡ŽÙÙa‰“z;>U)óx#ž•~Æêøy­Û4Ñ­Äš¥„‰ a½•a¼ Àu POmÃÔWcgã‹â¯$]Z84Ý=4„2Å*Ç@Û[¥Æö\ à29c¨œ(˜æ<ÆkY­ã‚Ia’$ ‘3©EÜWržãr°Èî¤v­=?Áž Õî¯-¬t-JöâÍü»˜mìä‘àl‘µÀ©Ê°Áô>•»áMgL}![XXç›@v½²†`¬·JÜ}™Ãæò×#ݶwRøj;OLŸP¼IÕµio%{ù3·±¾°[R]JÊå¯bŽ9¬üÉÙ¡y b&bÐÉåJS˜F@pŠÜÄž ñ¥2YÙ[Ïâ'²…UÓHÝ}˜wvXËǹNçù c“¸0íµ¬×’íá’wòKª¥™°;“Ø{T—Ú]î—ö¶ÚOiöˆVâ>&O6&û®¹©ÁÁW |>ðg‰|;┹¾Ð®ôÀÖŒpÍ«Yù6æCapUXÌxà’Œž3XÚû˧xfîÃV¾ƒRÖ/5$¿à½Ž÷Ê]’¬ÎÒ£2†•š,€Å‘—Ës­ êi¡#i×jšsˆïXÀÀZ±b¡d8ù `FŒT¿ð‹k?ØŸÛ?ÙÿØÿôû3ýŸïlÿY¿{åë׎µÑ|Rñþ·ã_Ç­%Æ’oî’Þ+yqla3ïùU~R¢9 |Ì[šéüAâ {«Íc^Ò´¿ ÚØÝ[\Cmw&£7Û"‚HZ‹ì¿h%\#y@¼µ Ä`5yÝ·ƒf1»€Î23QY•Úø¿Nµ°Ðƒ¡´Ò®§¹C&—¥êñßÚÎ\ @Gvˆ¦@ÄŽåŒÌShVZ⨢Š(gÁ_ò9h?õÿoÿ£°n?ärñÇýŒWßú2·¼ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£(Z(¢€ (¢€ (¢€ Ý—Á×±x§UÐL°Í7ížs†o-¾Ì’<›N2r"ldHÎ;aWuªxŽÊo½ìocS³·Ñ®mò»bŠÔÆ|À¹Ü7,VaXä[® €cþmgûûgû"ÿûþ‚f³ýíŸë1·ï|½zñÖÂÚω|ïì"ÿUòvù¿b¶y¼¼ç¶ƒŒàã>†½Ãqèše²¼èIÖ‘5¬ZΠÿn{ÉìÞ6ˆÄ%Û‰ÓÌ–$@Š rJ³s·z<ž Ñ´:ÂïM†]%&‚öÞãS··F§‘¼ôg$¡£ò“z3Ü€p¢2À{ZÌ–±Ü´2-¼ŽÑ¤ÅNÆe YAèH¤ŽÛ‡¨©'Òïm¡yf´ž(“ÊÜïb$ã@Y}@$dWm%Šx£Áëñ›%펵yqw=õÓFóE4prž`(̪ ¿2ü„µlk‘iþ%±×4½+Y°2ˆt+‹oí ˆí~ÐØ42(fcÈ­*å ämp +@mk êwÍ Ûi×wdD"›z™| ËÈ2€âùzñU¦µšÞ8$–"IÐÉ:$]Åw)î7+ ŽêGjôë­^ÃIðÌÖÚf¹î¾6>tOä´’6±ºHÕI݃rÍÜʹ Uø½¯C®Éy"j1ê|M«ÈŒ³‰OVÕa`r~B±§¦¥yµ§â).eÔ"k»Ø/åvª²Û0*¨-ã À2 Tnû•²IäæPE{àøìü+m® wM.¢ŽÎ5¸óÌŠ#2'0„Ê “»¥±T-ü-¬ÝÃw,EüÑZB—³²Ã&ôw |ªSæðG=+¢Õty"ø_£±»Ó]Ὼ»’õ;wcš;EŒùBBù&7Êã+´î·¬übñ|Uð$‹«G›§¦†X¥Xãˆkt¸ÞËœG,sµ“…yŒÖ³[Ç’Ã$I:"gR‹¸®å=Æåa‘ÝHíZzƒG»lî"¥ðÔv:ž™>¡y“«jÒÞJ÷òx‡P–&-¨Ë*–9&fc>à¢Fù àv™¥ÞëWÑÙiö“ßÞK–öÑ4’>'  “€ úRÞè:ž›uwmw§]ÚÜY¢És ð2< J…geA.€ýåõè%x5gÆvö7Ö q¯êK©Y\µìQÇ5Ÿ™;4/!lDÌZ<©JsÈZ‡‡ôçˆkž½×tÕ»¹ÑLžeú½´N·q\yx&%,±Èà ³t€ X& .öæ–Iå‰üÝ®‘1Så y0@þ!›ÐNš]î»ív“ÚíšKvó¢dÄ©èr>òî\Ž£pÏZôïßYxSKÑb·×`þÓ´þß’YmçUó¾Ä#7Í—Pªãœ0BÀj>4סÔ|)wl5îŒiáøà‡Ï±cÓ§ª ðG!€èÎsÉ 6«×Z§ck5ÍÎwoo ɳ–i`eDœ ˜˜‘€à •<ûUöˆw¦|AñŽ¥¬ßXK¦Éý£aµí¼®û̾JxØ”Û)Yظ\:3e 0–Yh:ž¥uimi§]Ý\^#Im 3¼ê de€(à‘ýÖô5.‰ámgľwöF‘ªù;|ß±[<Þ^sÛAÆpqŸC]±ãû xFÃKÕ¤µH¬îÊ_-ÄËq$~a\1+ò:†?.íÊâN¦{g¬xOE±µÑü=.ž’­ÒëZ›Ø¿šò³ }¦$pÑùI¸eÇ•†ÂˆòÄèžÖ|Kçdiú¯“·Íû³Íåç8Ý´gô4Xø[YÕ5;6ËH¿»Ôm÷yÖ[;ËÖÚÛ ŒÈàœWm£7‹nµ†¼Ok6ój—7mº‘Óž˜¯™5³Lñ‚"í%Ùå È7aâ¶ÿ®±¦ZÜé:ý‡ú+›={Rò”4qP—H–O#{ ¸W2¡P q7º§¦Ý]Û]é×v·h²\Ã< ’¡YÁPK ÿy}EEo¥ÞÝý—È´žoµLmíü¸™¼éFÜ¢`|Íó§Ÿ™}Ez,x¹Ö´;}f w»Ð¼›h5N9á¶•o#¸6âé„ïXš@FÕ .ÂwL¾“Lðý×ëgÕí&–ËÄÒ\_ºÈ¾U¾M—;÷aaæp¤«í,ª€<×û.÷û3ûKì“ÿgyßgû_”ÞW›·vÍøÆìsŒçÕ«ï k:^™o©^éöšuÆß&î{gH¥Ü»—k‘ƒ <šÔÓ|kssâm*ïÄêzM½å¼· †'$DœF+Ȫ€È×EâMJXtmrqgáxFªŠ’_Xê“Ý]]ƒ û]Sµ·G…%}n-6úÕ|Ç“Ê_9ÂYÙ÷¤È”¨`F[í>Ûľ’ X]Ka®ßO=Ö§9·–â ’·A-&|‡,‹º@YFÒMp¥ÞÇæï´|˜RâLÄÃdO·cž8Vóðw®:Š–çAÔìã\i×p!¶KÀÒ@Ê ÁV\‘÷ t$žkÑnüKk¤jþ'ºÒ5HÉÿ„gL·²¹qÈÒ/öx;W,Uç K#! å28íų&º“ëw7z…ÂIkz²He‘ •™¤*à¸w2®î¡\äŠÂkY’Ö;–†E·‘Ú4˜©ØÌ¡K(= Ô‘Ûpõ§¨x3ÄEÕµö…©Y\^?—m Åœ‘¼í6  9e£ÖºËé¾ñ¶—e¾ +E†{hîf†KÇÃ]*'*VHñ'• XùÐT^#Ô®´ -ílü=¡;ßÁx‡AÕ$»¸i"YB>áq2ÆÍ=J±,»wmm ,6³\G<‘C$© %dRDk¸.æ=†æQ“Ý€ïQWuãKë+ 0®Ÿoö¯yz庢Æ-¢Ú Àм¤m)’Pc[6ÎA®€4ì|-¬êšeÆ¥e¤_ÝéÖû¼ë¸-â‹jîmÎäðjþáí3SðÆ©}¥vº¦l·RÙ½’ˆMÄpáfówûÕnc÷;v’ë÷N­¤êÖ]¥…¬ ϨGm-Œ±F¾k,[¼Ã™Ì *匙²Œ ÝCo¡ø¾9fŽ'ŸKŽ8•Ø#}¶Õ¶¨îv«ÊOj¡¢x[Yñ/ý‘¤_ê¾Nß7ìVÏ7—œãvÐqœgÐÔZ6ƒ©øŠé­´­:ïS¸T246p4Î  œdŸq]?„,t©t#pöº-õè¹qv5Ëé-ÒÚÜ*äc–7”’fܨ$oݦ÷µIžÿÆ+{fðö±¥ê÷çU†ÏRÔ–• “yRïYcØê²01;«þ÷&3·(çÿð‹k?ÛØßÙÿÛôû3ý£îïÿWßwæéÓž•³ ê~º[mWN»Ó.‹ ä •$€À0gØ×måǦëßÙÚuå…å´Úo“.“¬ê‰-º?Íû8»‰£ŒüÊ·VŒd”%›*øþ7±µÓítø­æŽÝÝå–]*ÛRŽþÞ݈OÞÇ$dª‡Á_-‹:ˆT³6å4ÉÖÆ¯¡C¢X[ ›©?µçH® šB qÁ${ãf—wß*Q¶… +Œ°`È1ë¬øk6««Þø¦Ú%Ò5{“r.QIŽåÌ’[3vtb냂ʡÂíe q´»Õ¾žÈÚN/ ó<ësy‘ù`™7.26…bsÐ)ÏJ¿màÏ^iU·Ðµ)ô°!¾ŽÎF€*çsonNxÁô¯DÔ­tËoˆ^)×äñ›-–©mªÜiße¸Yo>ÖvU‘r<À„8 \ªª°ÜËGI†=^2÷R›I¶ò!ƒgˆl5”·¿¶"¢¶y7?’ªÈâGÄ¥d9Üàw‡ü¨k¶—wëg~4›Xgyu,¤ž$xâ2fQ…ÉØ ' qàU ;AÔõy-ã°Ó®ï^åÞ8VÞÊÈ¡TrUYI  žµ©à;¨lõË™.&Ž:^¥i(,ÖSª®OrÄ;’zµ6ºöÿ ôý.Þê43j—uó ~]™MßIJºÍ8%0m´NóW:U¾w>¨ã61ÀÍ8eÎåØìŒŒqƒéF³ ê~º[mWN»Ó.‹ ä •$€À0gØ× xƒW‹Ä2ê©q¨ù_o³Ñ„úüždñ RÉKÛÎñ†Ô±á™l¹^ &ÄK{k_ Ù[]ý³ìÚFׯc9{«‰Úß0VYаRÈèÅWv; èÓx‹]Ó´«f./®cµ‰¥$ g` ±œdó€jþ¯áUÓôèYêöÕœs%¼ÒY ×ÉwWhà £ŒÂ90T6ã#2ü8º†Çâ…înfŽÞÞRÖIf•‚¢(™If'€$Õ]gćSµ[K]>ÓF°%{K)I$€îÒ;³ Âå¶€]ËU×´i¼;®ê:UËF÷72ZÊÑP²1RT28È©uàÓck0¹Ö4Û}V/.‘+Ê· ’ŒÆ?(8Q’†MÙù1¿ä­ŠžOxŸ[†óIºÓ§Ô®."km^ÖibTˆÒBç†rsŒ‹ÆzPñ»®øšÛQÓSJ¾¹žú!-ôBàofq[†2ïÜv!\üÛ¶|ôÌ6ƒ©¢ÆÍ§]¨‘D&ù•bYY‡«“ÙX7B ~ƒ©êö·—6:uÝí½šy—3[ÀÒ$ ‚w9…V9>‡Ò½‹Fñœ1jšDo®Æ–©áHÝZðX!µv™HÎ$¤ù85ÂZ£ëZ7‡[KÕm4‡Ñ‘ÍÓ\^-«Å9äH¹Ý!òü¥ÌA¤ýÀxp1£h:Ÿˆ®šÛJÓ®õ;…C#CgLáA± ÆH÷Óê_ 5;3wooÝæ©nú|gNŽÍ¼ò×6’\²í°1ùeHÇ<Ÿ—«Z¤ö>3µÔ­4²iAµ«½Gì—“Ãb’[8An¡™„dʼnFÍÙ_8ì •ÝÖ€Õ´iZF¹¦ÌdMŽ¥¬WQÃ`ë& Ì›‚ÉååHÈ d8òÉ4»Øf½ŠKIÒ[,ý©& !Þ1òáÙWœr@êh·ÒïnþËäZO7Ú¦6öþ\LÞt£nQ0>fùÓÏ̾¢½Îk-N+íê–j¿ðŽ =¯nnmî.b½K…ŒN~S¶Öv!3ª±MŒb‚Ht-ÃV:¾›s¨¥þ¦—‘Ï ß½¶¶ŒÂdVåCÇçevò®D´Äë~Ö|5äÿkéúW»Êûm³ÃæcÛ¸ ã#8õ™]¯‹ôë[ :M*ê{”2iz^¯ý¬áUÀ”whŠd HîXÌÅ6…e®*€4ÿáÖ±?¶²/ÿ±ÿè!ögû?ÞÙþ³~÷ËׯjýLJ´Çð{ë6:•Ü÷÷6ö·6·K+KÏ”JÅ€0°åW9Ž•±â›IuMoWñ.›«XZi7s[/ö„iq»)Dµû:·š0„A´&ÀÊùëÆêøy­Û4Ñ­Äš¥„‰ a½•a¼ Àu POmÃÔP  k:¦™q©Yi÷zu¾ï:î gx¢Ú»›s€A9<š4O k>%ó¿²4‹ýWÉÛæýŠÙæòóœnÚ3ƒŒúô†òh:þÖ'‹Exm®RçR¾Ôo%V’$ç ¼rykåH7;nmªÁ2ô=2á,%ѯ¢ðö­omrÒf×!·’ØÈ‘î’ „«—TAÿ-‚4_2.pà…µSS¸Ól´‹û½Fßwi³¼±mm­¹ÈÁ Ž ÅØÿÙZߨÕÖ~ß7ñ…ü/á=;Ož÷MÐõKÉ×PÔ,.ZwH³¡*AÛ i¤ E¶Tzc(QÃÕÄT½ “´wcÃa+fyŽ- â¥Z\·žËm_ôÛ驵ÿwÄÿîxƒÿËÿÉÇj¶š…†±}o«-Êꑺ‹µÜyòcB¹}ÍŸ§~:W‘þÂþ4×4ŸŽ6~Ñ>Ó7…¯,®ž÷LYŠÚت¨qvçj±—ˈ•?hù³…ǾüVÿ’›â?úëþ“CSJ­<^ 8¨s+»Y»þ‡Nm•×Èsz™]iBn*üÑM];wÛÐæÖÖgµ’åa‘­ãuæ v+0bªO@HF wÚ} E]ƒ\Ú_ü3¿h´È4ùíu+^[i®ÚwCw–‘VMÙL‚ª¸ÜÀ`WG§èþÆžðôº,—£Y¶Ó£¹¸{™"{I.-¡ùàÃHy „È„ w>)å”Wa¢øJÛÅZf“=«}…mæ{mb|<¤ $âëi#wîRqå§?è¹ë kB´Ò¦þÐÕîl4-?G¼¼’;u¹¯åò¶aš$6¿1Ú²Ä H9ÈÛÎìp´Wu©xgMð¦§â뇶þÖµÑuq¥[ÙÞHʲnkŒI+FUŽÜüªW,àç U¹=fúÏPºY¬ôèô°P -à•Þ-Ù<¦òÌ ¹ ÍÎâ*€V¶ºšÎC%¼Ò@å2ѱRU”«.Gb¤‚;‚GzЬ闑X_G<ö0j1&smrÒß ŽLl­ÆsÃ@ê8¯Eñdvž1ñLJ4t« "[øtx~ßnn$‘KH.ט©UÞ1Àbe‰$1¢»ÿZøDh€´ºÑEÔ(†Çû9µº™¼ÄR&iãXˆòÌŒJ*e•pÊ×Eâ?ø]u bÚËJžÌÇy­ÙÂßlg‹qp¯‚9fv ÉÀŒc !óhǨ¯Ioøz_è>ƒO“íͶš²ß<Ž œÓÛÂwD»ˆq¾B│mˆ"Û½¢ÑtIðæ“{¨ÜèS^j½Ï•­ÿh)i"P‚ÕprbbY˜“®ÒÎçtWu‘á8tÏ߸¿Ôtë-^ÞÛN’ 2Ï­Ö73) ‘9&69M .âDZ,Zn­©_ëIÑt­$‚Ý Ôç½’Þ;‡LžC²æ˜%Td¹â¨®ÃÄði~ñ„ñæØk62ÙÛ\$3=ÈLÐE11•xäÚ ¡É;HÝ–æº?.â?‹~*³—F´µ¯­ÊÒÛÉ>û‰#†yßtŒl PrA`,¢º+] áæ§¬Ék&ôÕ-,àº!‚ÐÜ<¨?„Ÿ–{Ž:nçcâx_ú÷Š4M3EžYb¼šÞ뛦f)?8Ær¡ÆLŒå¾WYÊŠõ?xoÂ>“XÑ.5 I´ô¸€]F5í.cVÚ0P[€Ò¨R0B¡#{0ó .ÇBÔtËH4Í/IÖ.šÛOwuoª—*žQ,-Ý·’"DYƒcrP)à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý[Þ ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ”-Q@Q@Q@W§j¿¸¾ñå–©¦ù¶îÕ½åèxncÛ÷‚®ÝCa= –`Fð1¢½'Eð¦›>‹&Ÿ©.‹oª.ãQAÞDl÷0œóm†P™v8~˜Jºw…´mâãF´×.5[g»&úIÑ UžXB ŠD$“1f';”»IpNŠèµm:Á|§jV–ò@÷:¥ô–_1Ä)«F¬@ Hó_,g=:»ã/Ùè>ªM„–wö¢FÉ)pñ´öËp¬¬x&D‚>\``q@é6¾Ò´CSѤžeðÈÕ|‰e’2fÕ<˜Ý°s°ÄS!q¹NT«â‡Ä¿ i>ÈÒáž¶Õõ !ÄÞcL-ü’%bÄÌà ¨0Hf`г¨ý‹í ö?ÈòbÝö»¼ß-|Üc¾fý½öíÏ9ªÔQ]Ö¯âfçá.‡e6¯-›êW¶ín÷.c1G‘ “¨I*:N1[:~áXüiáßK¢Éz5›m:;›‡¹’'´’âÚž 1‡ÈLÈ@¨s€yeØh¾¶ñV™¤Ïjßa[yžÛXŸO)É8ºÚHÝû”œyiÏú.zÈZЭ4©¿´5{› OÑï/$ŽÂnkù|­˜f‰ ¯Ìv¬±Òr6ó»-Ýj^Ó|)©øºáí¿µ­t]\iVöw’2¬›šãJÑ•c…·?*•Ë89•j6±iZý‰¯bÒcÓžÏKŽxá‚y$›í–ñ–@ìX„v~KGÊ“¢½Â~ÓfÐôKý[MžX®ÿ¶åb²´-Cy6Ÿ¼MÓœ·Ì8mËò/Ë÷²çtW©ÙxoÂ:*évZΡ¢âêÚÚêöâäj?ng‰$"‰…¶y®.&Ôo¤›Ï·D7œP'±Ìs« \e€9:+ºñŽ™£Xišµ§Ç¤Ý,×—ó[i­z-B°8 ö‚% |æ U€Û·nãRøï]²ºð·…"‹Ãºm›Ï¥³G<]·þäMó2v’w†?;`—ßÉàû9>&øÇL‚ÂI4½)5y4.†)¼–fÎpD2Ç’@9Î [b4W,Ï„+y{Ä`ìâEÃ)âk>mæãMÒô+ˆ!ÚZûA»»n÷°Ý1s áw¼`Iœ¡ájÍŽ—{ª}£ìV“Ýýž¸›È‰ŸÊ‰~ó¶ 22O5Zº}oý Á>‚×›[Ï:îîUþ+¥‘£1.%ÕOÌ¿isœHsWE¬hH,|"º}¬’Þêv ïAæ›í—.Õç’±¢€:ã¦I®²óIðΓâoé‘Úé&òÛWº¶·µ×g»HŒ*ûaH¤…ÔÈpí;Ë!‡ÎhÏôm{SðíÓ\éZÞ™pÈci¬çh\© •%H8È¢Õ>Ûý§wý¥çÿhùÏöŸµnó|ÝÇ~ýÜîÎsžsœÖÍìÖþñ-ßÚ|9i"\i÷wI e‚¶ø¤ŠDfCÕ f|ÏÞŸRÑ4vñÏÄÏíD»š×K{‰¡1Ì^rÃP†07¹9,®Ê]÷ãqm®@ͨ¯D‡AÑ<[iá»Û}3û[™¯ín,ìnÖííâŽh’4»$’ù¢2ãvÒ“´ÐÔ!²Õþ^ë1xjÓFx5Kk8®¬Þ褡á¸yù²º’6DxÁ†zÐEëž+ñ4ºM¤ÝxŽMBÂ_Ù[Çá‘$å#’M:%YYD #7œ –má8RK ‘Ñ]?‹¿ä_ðOý‚$ÿÒûº½u¯j~ð÷†F…¨ÝèÇP°’îíìgh^yÝÄ@»)€‘ NÌ@Ø*ŠôŸ hÚ¹áøou]6I¯onuydžÊam²;k8®BF ),Jƒ·j«¸ÚN•u_éZ Ôu£§Çyoi†-.i$ /-á²ÊÂB‰±ÕWpnP³¶ÖÀU˜4»Û˜RXm'–'óvºDÅO–äÁø†o@A8ØÿÂ3¦ù_ÛÿfÿAþÈþØþÊófÿ¶ý“Êó3¿Ëßûλö|›·~öº êv:†‹¡ÏýfŸð‘¬¶ºtÒ0 ."Ä<Í)V ã<€vžrãÔW¢xWEÒVüæ€8 +ºÔ,t‹}oJžÿK°²Ò¦óBÜéWsOcpBƒðYæL3!•7 n¸ªøÆÆÐi‘]ØézJZùÁQЮî&ʶRX®¤‰S³p!$ H0ÊÌjz]î‹}%–¡i=…äXßosG"d2¬¡¿á/ù!¾ÿ¸‡þ”µ$Ÿé¿[¯–[Imì]¾ô±I¼è 걺DÀ.›—'™/„¿ä†øþâúRÔ•â¯ùõúó›ÿ@5é~#ÿ“qÐ?ìW?úGy§Š¿äWÖ?ëÎoý×¥øþMÇ@ÿ±\ÿéuâçîÕ~hö²÷µèÿ&Wý£ÿä+cÿaÿÒIkÉWý{ÿº¿Ì×­~Ñÿò±ÿ°Šé$µä«þ½ÿÝ_æk<Ÿø5?Ç/Ð¬ßøÐÿI(¢Š÷ (¢Š*5ÿ^ÿî¯ó5%BdT·0\¨êqÜÐy ¸´ž% 3£('¦HÅzG‹>-iÞ<ÑeÒ ÿ‘ËAÿ¯ûýµƒqÿ#—Ž?ìb¾ÿÑ•½à¯ù´úÿ·ÿÑ‹X7ò9xãþÆ+ïý@ÑEQEQEU™5;™tË}=äÍœIq{GÊò*+œã'"$àœ|¼u9­]…׃¬­¼Sâ<Ùÿ°ì,æ¿‚ä²ù 6NÃòÑæ¶m Bà•£kñ^²µ†/#ŒF‚# ¶‹Íš 0!–M»¥‹/•!d¨ۅEcã]SOû@ŒXKó5Á‚çM¶ž(ݾñŽ7Œ¬Y‚(!TtUÁ§xUum1ç´Õì%¿He¸m+‹€‘«;Æ?+„F|y™ `e¾Z4Ï ­ÝŒwwú½†…ù6ÆüNÍp!™V(ÜíÜÀC$«—Oø…â2ÖòÞNGK»Ÿ¶Èn&u¹Áz3‚ÑËóÞ! Óž ˆ:ö›%ÓEy‰wm¥ÄÑM±Âª°†‰Ô¡(pÄdsÏ'45\éšd7ÒÉÅ-åÅÊ$ùáX‹Ë•e>rá”p{`›Z§ƒ¯t:{Ù¥¢‡ì;‚3?j·kˆñ‘Ù†ô8ÆG4׌5‹èfŠæþK5±´•¥ã7i!˜Œ’f;ËžÙDZâmK_ó>ßsçù—“ß·îÕs<Û<×à½å§8&µ4Ï^êV±ÝÛ KfÓNªÒÜÊȱÀ.³gå9`à¶ÕÉ#rÄ)«âê^òÆ  ÞÓKm"Á:ËäÏÓ$LT‘¹D‘“´7ã;••@2õNçV¸IîäóeHb·VÚ8Ö4ÈŠ3Ôã'&«UGL¹Òn ¸ü©^®w”’5‘º:œuÁÁªÔ»wã]R÷ÃÑh’‹ìè¹EM6Ù$SòÂEŒ>æ fÝ– 2MUOjQëv:ºÜãQ±û?Ùæò×äò.1ƒ´FƒsŽs“[·^²¶ñOˆ ógþð³šþ ’Ëæ4€Ù; ËGšØ´$9 ‚W3NðªêÚcÏi«ØK~ËpÚV'#Vw;Œ~WŒøó2@ÀË|´—g©ÜØ[ßA›"½„[Ü.Ðw ‘$‘ÇÏŒ1К¿£x»UÐ-ZÞÊxÑ ™c2[Ç+Á!!gRпʿXÔÚim¤X'Y|™ãÚd‰Š’7(’2v’ügr²®^—cý©©ÚY}¢ O´Lý¢éöEæs·eÉ=€4Z´ì|I}§é—|m¶sî&;›X§òË.ÖhË©11rÈT«Ïʸ׿gÕå>Åý—µnè4mæ™@#ýgßm§lRá5iü*¯¢K¨Ùêö‹[—V Ö[dfTË#T8yHFc–ÈÈ€Lñ¾¯¤XÇkm4aÏ‘4¶pË=¾IoÜÌèd‹ K Œ0İÁ$Õ_øIµ/ìÿ°ý§ýì`òüµÿQö´lÎ3þ·æÏ^Ùdz"éÚ—ÃË»´Ñ­,oìoì­~×o$åçY!¹.]^F\“ •W¿n+ü9{ö}"Xí¿Ú›–Ý-CHÞh¡„€?Ö}ÆÚ2vËþ!@­ñCTm1 x,.o&Ô®µ+‹«Ý>ÚçÌy– B¤‘0˜‰;pà1òŠÂ±ñ6¥§êw‚\ù÷W;¾Ðo#[…¸ÜÛš’Y>`ææº€jü~ "êø]km•…µËÚ&§#Ë%½ÌŠyùq»8Æp\ɸ‚è/[ѦÐu³£„ŽT–"JKˆ²Fë Œ¬Fp@9Ôþ.Õn5/·ãŽam%š¬ñÅpÈŽŽ‰¨DI!;@åÙ¾ñ&¨išÎ}ݤžTñäT2° †VRe`J• †‚$Tº66µtÑÆÑÃHe¸ºœ‘¼`€]Èã$%‰UPÌÀ÷‘¯­-´ÍFÃ\ûFð$³wEŒ ÜæA2ÆÈª¿1‘€L;¾GÚj~7Õõ‹,®æ‚K6ÆËu³…#·ää* n òöï?{5WþKã¢d»A5˜á Ö±I,Cvý±ÊÊdEÝ“µX ³qó6u!ð÷úž—k¦jV¬÷‘X-í·š±C<…I‘«®G íÃÛK`¥ß€/lôKûæ½°k­;Ë7úP•…Ý¢»l êT)ÃVTfdgœ€jüIª0{­KÍ”ÂÐI/‘’u04™ÂæV;¨w,ʰA$Ö æ§socòoŠÊon»@؆GŽ?<ŽrryÇ@+¬Ô¼ ¤Ùx>×U‹ÅzmÅÄ—7QmHîöMåÇ *F ¸!ó!ÉræL´ï†÷÷Öz=ô÷Ún—¦êhZ+ÝBçÉOœðí#˜†@[``‹"3• /Fñn£¡Úµµ¿Ù&·g2o¬`»Db,‚T`„€ •Æv®s´c2êêkë©®nf’ââg2K4¬Y݉Éf'’I9$ÖÆ™á)/¬c¹¸Ôl4¯´dYÇ~îvA*J¥Qw ¾d…!†ï‘öéøBÎÑîµ]VÐ`{Ȭõ ÍÃ\Gsm,6²º®Ñ"§ÊñŒ†By öÀ‰âKïùÂÑ x¦Úd‚îÖ+˜˜®v·—*²î˜Æ@fáŽoÛ|A׬õs©[ÞGÆÙìÌ1ÛD¶ÆÎè¼€¾VÂIb»pX–Æãšçjö§[êwMΩi¤ BÂ{Å™‘Ž@Ú<¨Ý³ÎyàóÓ ßÇÛßX]›ßߨ^}ºÔˆ,2⠮ܔ&6¨@ŠÂ¯I—áÆiñ#Sðý•ì~ ¦«vë?Ú#’yŒ*ù>õ^#Ü R:žvûÀ¶úe½í•톷æ^.Ÿ%¾™+K,7,¹HÊí÷a¼{ÑŠ6ñ ÍNæþÞÆ äß”&ÞÝv± !~yääóŽ€V§ü&ú¿ögØ|è6y?gûGØáûW•·nÏ´lóvìù1»>O»ÅŸ„¤±±’æßQ°Õ~Ïyƒ»µ¡$(,J…uÜvù‘—L•¾tÜKàëØ¼Sªè&X æ›öÏ9Ã7–ßfIM§962$g€"›]„xV ÖÖHîMÕõÃÌ\²‚°…]£Ë¯/s¸ÈIè c×Y ü=—[ºÓ¬æÖtÝ'QÔ^5µ±¾™d#cåÄê²ÞTCck+ßð€E¨hþ»¶ ›¾Ôå‘bžçísÇ´mV#¬{›m,Tºîæ4O_xÎÅ6Ó$v±\ÄÅsµ¼¹U—pÜÀ620 r/‰µ%ñ عƧÑÏ ¢5ÛG,*chUÚ  @PÀÅUÕ4ËS»Óïcòo-&{y£Üc«aH8 ò*]N·Ôîš+RÓH@…„÷‹3#´yQ»gœò1Áç¦@ [¼Ðnš{7ŒC‘Ï M«v¼n ¸ÈVÁU#Ô›â½q$Ky¯–‰žÚ"cM¥|…;xƒk0òî°Älæ²õ½mQ{9Ú9HåIb$¤±È‹$n¹€ÈÊÀ0g-x3F‡Ä^0д«–‘-ï¯àµ•¢ 8W‘T•$œ2 K}ã}^ûìøš "e¸û2Î/Þ¯Üsä¢neÉÚNJîlcqÉ©ø×TÕld´X[A.¢ÃM¶´i …fŠ5,¹ ÛI#*§PE­_MÑ®|2u}.ÚÿLòïÐCv—iÜŽÎÑ•ŠÜþî¹:݃ÇÝ¿‡“DKßø—G戕¢F’&«…wÆ®U€`[ î9–?ëKu}q,¶—¯{r÷’‹í>ÞåÎrî‹$l¨[Œì;W?tc¢€,êzα}%ÝÜžlò`*¨UPUP…U«ŸjWwzÍÔ·;çÖ7}¹üµvéVcÀ_Þ"·ËŽ˜é‘Y”P†·åÃge}Û´›y¥›ìü¶Ý*";+ØÎåU`v|_ãÙ¼Kj-õ'·gIf“WÔ õÄŒÄcÌ(QD²aBŽdrK|¡y:(«:ާs«\$÷ry²¤1[«m kdEêq““U¨ ŠËÇÚµŽib«¦Ü[Ú#GÛ4›K—E.ÎT<‘3cs±ÆˆÕ]ÅºŽ‡jÖÖÿdšÝœÈ!¾±‚툲 Q‚‚WÚ¹ÎÑŒz(a7‹ÏÊ1kYøƒ¯kízo/#azŒ— ´P¤»¥I]Ê¢½ž(Ë>76Å1\íÑ]xÿZ¼µš%´ß2–î=>Ý.¤ 0û®1+†%²á˜1;ŽyÚ(  ÅºŽ‡jÖÖÿdšÝœÈ!¾±‚툲 Q‚‚WÚ¹ÎÑŠ°k·öú•Æ ·R=íÊN“O)óA22K¸¶rY]²zóœçš£Eièž$¾ðÿœ-Šm¦H.íb¹‰Šçkyr«.á¹€ld`æû|A×¥ºŽæ{Èï.9&¼¶Šw¹RT휺“8¨—vÝ‹·çh  Ûê÷Ö—Bh-Úו ­œ0Aó²n…FÛÔmÊw( Ù ‹Yñn£®Z­µÇÙ!·Wll`´G` â$PäÀÎ761¸çŠÓÖõé5&$¶ƒN°ƒq‚ÆÓ•loo™™›,ÌNW;U@Õð—üßÜCÿJZ¹zê<%ÿ$7À÷ÿÒ–  ¯ȯ¬לßú¯Kñü›Žÿb¹ÿÒ8ëÍ^™o{öˆΚH~ί™Sb¡ÜËÙ[ÌžåÒ¥ÑtiµÛÉ-­Ú4t¶¸º&B@Û /+ä¬d|të@¦|M²³Ó£·:†» œºiÒæÑ-™VÆ Öæ .@ó1+Zo,¤yw9“Œ·¦jöZM¯Š-#3Ï¡f--ehÕâê C:î;r‘7¶ ‘ÍeÙØý®Þú_´AÙal™ö´Ù‘lcø›çÝî«ÔYé—7ö÷ÓÁø¬¡ ¸ ˆdHÁäóóȃ'œô€6|âx|;ur·¶±ê ÚÍ–3±«ißÚ“Gsqªi²±»§™Ùtó¼×Ü )ݵ²v•n>ŠÝñ޹ý½©Å7ö®­­yPˆ¾Ù¬¾e™›w>ű·{d‚Ù¶®PEPEPÏ‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôeox+þG-þ¿íÿôbÖ ÇüŽ^8ÿ±ŠûÿFP´QEQEQEÓßxÇí~·ÓD[u¶ÞêïnkXŽè¾rܹ Û¶ÞÔ yuÌV›øgR[¾ÒÛÚ>ј¿'®Òóœ¢7<œqœŠîôω¶VztvçP×a³—M:\Ú%³*ØÁºÜÁ%Èf%bKMå”.ç2q–ç_Pðþ±ggg©^êVi¥¤–¶w¶Ìn i¤”#i—ËpÒ>pîel,üØZë~»ðÏö^¡­mö=Jkë1lñKçE*F­ ŽÁv0ò#ά>f>YÀ©ã_x5‹;û{ý.Îî-íäÓâY¾Ï5­·Èc’@Z2L&áµ ÎH¯;¢€;­OÇ:MÖ‹%„öIý„4¨â-æãR[™ÉÉÌc’ÉÂ*ã|{ã/ý«ì‘O›®êZ¢ùÊ£÷WFÀpOÌ<¦ÈéÈÁ=¸ú(Σö/´'Ø<ÿ#É‹wÚvîó|µóqŽ6ù›ö÷Û·<æ«QEt÷Þ1û_„môÑÝDí·º»Û†šÖ#º/œ·.C6í·µ]túgÄÛ+=:;s¨k°Ù˦.mÙ•l`Ýn`’ä3±%¦òÊG—s™8ËpáJ=nûHklj6?hûD>büžB»KÎpvˆÜðNqÆr+2€:ÇÔõãWÚO÷—vÖ™Xv£QÓ.t›„‚î?*W†+…]Àå$dCÁFpph{Å>1ÿ„ƒL±"ò§oôJP»MÕÐ_-]ŽIÝ |·ÍæOpz>+¬Ô~%éšµž±aqªx„izÂU­tuY’eŽL»e`NaÚ¹;Nv,¢€6-u˜`ð~§¥2Èn.¯í.‘€Å°'9Îf\qØôã7ü-ãøGôËè/6uÿHÓe+¸ÚÝòÙÔäýÛ—ÊüÞdç¢b²ìt.ôËBk˜,,ãÜ‘És¿ý"P»¼¨Â«Ø#$€«¹w2ï\æPkáÍ£èGFmsZðõº\½Ú]hd—‘Q$ÍŒ0ÄjU·|¿8Ão9ßjŸÛZÝÍßÚïõ ûWíZœ¾eÄ»T.æ98Î2-´aw67Ê(cÃzÌ:cj·k!°Ô­¾Érðe|ØåW@H‡‰ RFá¹r¤†[öÚ¾áVÞ}$ßê‘47]=äijÏÑ4,‘ª´›X#¹a–_“ wózmh4+=Uš3ous5ª('xh–&bF1ŒL¸ç±éÆ@:Íź7„5="==ïõ :-^ÏU¼¸¹¶He?ggÛq¬Ž:I!,Ïó£ ´—çt-f3Kñ´«#>£`–±…au¹nxbaÆy#ê1è ŠßTÓ/<šUô·v·W7vÍon³$í,p®Ç&D1€`_˜ÎóÀÛóU×u˜u=/öÑ,ŠúuƒÚÊ\Ôòåyäm•G8ä©Ç¢€:x5}VÒ´Ø5£ ºT- a2ÝDey¶3;)·ÈãÌ Ã/É”;Ë/ù¾0Ö5íB,K©C¨ïKeùV[˜&A€Ç…(îNêzÕÒ|ªkZ`Ô 6Ù´Ïn²^êVÖ»ÝU‚‰dRp$L1ó ¡6…mk{q5¬%•ÊY܉FÇŠfFSóû©3ÇyÆEQ¢¯hÚ%æ½tÐY¤d¢$’y’¢\¹ärJ¨,FK( ¬è—š ÒÁx‘‚è$ŽH&I¢•rFä‘ W ¤©8*Àòe÷‹tgñŽ¥â(ýåÕaÔÚâÒKdU¶–æ QH|Å/,U;rp3<-ãøE´Æò"ó5µ{ RßÌ\Åþ޳ä><™SØ7#ŒàéÚeέpðZGæÊËp˸ $q´Žy=‘ã©ÆMK.…„ײÚÉ ¼/;H6fF’/”òC"31ŽyÙŸWÑ´+RƒE7óKªÂ°N—ñ¢­¬BT›b²1ó[|h<±Œ+|™q³¢¿ñ¿…‰õ½~ÖÏR–ïZ¶½CtmŒ×ò+yl®<Ðd“™Wjnùˆ+æÔP«øVÿOÓï´ë1Ø_I¦}•ÅÔÄhÍ!#Y`LÓ QR2Q·&÷~]ÖaÔô¿ÛD²+éÖk)pf7S˕瑶Uã~§´ìt5=2âæÖæ ®`Üï§ÿhò•rÒ·k(ç 1`˜®Õ,%ñž³ˆ¼a®ê¶Ë"[ß_ÏuÊp¯#0 #8<àšÔðGŠaðý®¡j:–…qpñ:jºB¸U@á¡Ç™ØåÕÏÖùOy:(§ñ÷ˆì¼]ªÅ«À÷âòhb†ââ²²ùQ$HÞx ÊÎs‰‚qóuª ÖaðïŒ4-Våd{{ø.¥X€.U$V!A gŒ‘Uum2ÏK¹•£dÔmšê „’ª&’,7Ñ1ã<ôhö³¯j~"º[WQ»Ôîk5äí3… ±'$ãÜ×Eã»ï øƒYÖõ­?QÕåýä·iis¦ÅkæHX©‘nðó³’LñÇÕ™,|½2Þ÷í74ý_2¦ÅC¹—²·™…=Ê?¥tzö©áÿ]j:å̺’k7Ï%ĺ|Vñ‹q;’K,æBÛ7áLdãäÝŸÞW9Ø¿³.<Ï?ûGÎÉÛ·Êò¶¿™»¾ìù[qÆ7çµV¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ê<%ÿ$7À÷ÿÒ–®^º É ðýÄ?ô¥¨+Å_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:óOȯ¬לßú¯Kñü›Žÿb¹ÿÒ8ëÅÎ?ݪüÑídÿïkÑþL¯ûGÿÈVÇþÂ)ÿ¤’×’¯ú÷ÿu™¯Zý£ÿä+cÿaÿÒIkÉWý{ÿº¿ÌÖy?ðjŽ_¡Y¿ñ¡þ’QEïQET%KNØr¿(éSëSTkþ½ÿÝ_æh¶¥ :ë÷Œtü`zjë?o øŸZð¿„õ}ÖïVÒ´‹ÉÚÿM³·i™^H±Ù ¬ÈH œœHæ¯mi8•ŠÄQƒ°ê9®ÿþ‰ÿßñþWÿ‘ë¦1§[W U;M% ðØÊù^c†Ì°Ü¼ôeÌ”¶oOëËt|ãû xkÄž&øßeâÝ2;‹_ YÙ]%椰k|¬¡¢KÑ›Íòå!s g\û÷Åoù)¾#ÿ®°é45¡ÿ Äÿïøƒÿ+ÿÈõÇj·z…þ±}q«5Ëj’:›µÛù#@¹M«'nzÔÓ¥K‚ŽŸ6Ž÷jߩӛf˜œÿ7©šâ¹T¤­h»ío-}NóTÔí—L»ñŒrgV×!{Óû»¦R·òçNèÙNÝ¡GÛð‡0éü7§\ÃáµÒÙuÝCG¹Ò&kiåÔ€Òg»–ÕäH!¶hÈ’eÂI ù‘—Ú •)E`rž“§Úø¶ÇFÓ­¼µow K·³-Â]‰äg ó€" ògÌÛóyµçú§›ý§wçùœþgÙ|¿+vãž_É·=6|¸Æ8ÅV­Ý3Ǿ&Ñlc²ÓüE«XYÅ–ö×ÒÇd’pªÀ ’OÔšØð¶³6…ðóÄ7V«»¦œ°Ü0%íÛɽýä|à8€Ä¹Ü¸`¬½güL¼q¥ÐGÄ:¯„?Ù¯«ød[{»ûšòÍg^ÔüEt·:®£w©Ü*ÖkÉÚg !AbN2Iǹª4ì>Óî|-¢èk1€ßÃÿ ²[: |‡\_º•J–ä íl0e~ \½ÿ…/Zq¼¡J’yjÉq§K-ÄŒÀežW Îí–m‰’v®<²Ší|S¯j~"øyáëWQ»ÔîTÔcY¯'iœ(†È…‰8É'æ»kFñÖ5ñ§ÏÃÓ¦ê£ND™£°–²Oäª)!^NŒËÌ›–Fq¹\¢€;_ ëÚÇ‚<_¥K¨ÝË¥Á¥Ç$V/;#oí _™S;Aù›?ˆúÕÿ†þ)ñ7ö?ˆ4m#WÕ¼ÿìÑý§Ù\Ë»Íû\þLjs»Ëó˜íÛ¼ž3^wEwZ¼ž*þÐðïˆ.籿·¼“R7WQ¼’ÄFøtà³yIæÇ9µ(£t†¹kðëw7ËÙ`m±ÛÛoßä@Š(·`Ù¢î<¹<“QXëwšv¨ØÛ¼io¨"Gs˜QÕ:¨r (ܪHR3´g8F€ (¢€ (¢€ (¢€6|ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£+{Á_ò9h?õÿoÿ£°n?ärñÇýŒWßú2€%¢Š(¢Š(¢Š(¯DÕµ;aáë¯$™Ôu«8ô­¡H’;„Ø/&ó1–g#/ÓxÔnm»Îè kðÞs†×Ke×u çH™­§—RIžî[W‘ †Ù£"I–w$/æF_h*Tsº}¯‹ltm:ÛÁ°ëV÷p¤±ëpé 2Ü%Øž@pŸ8!Pß&|Í¿7›^mEz$ÞÕüQàh¾Åmäöíñ¿ûˆ­D±[m‘¶‰ 0ˉ# b·|GáËÝ{K×ô½?¶¯-áðíÈŠÈ3I4 §4m,q$e ,Yùr‚@ç=E{™sáO î´½ï-¼!…¹µa"Æç\䣑ÈIEÈ ¡‘Ž«3ãÆ|аAÚøWÓàKxR%ŠÞ/³yq*¨(.íüR;Y‰ó(OÄQÜŨD·vPXJlíYb¶PÛÆRC‚~gB®Ý÷3dÀÌ¢ŠömW]²Ÿâ¯ìÓúm½ÀMu´#’èÎH¶¹Ëa¦1å°sòc“€8Á£øRþïâo€µÒ±Ã¡Êš)‹RwÌIPDЫ.s/™§—÷† 0T ÃÆh \²Öï4ï‡Ö‚ÝãŒÚxe¯-ßÉBñNu¦ˆJ¬FCª<9MîP©bLZ&©{á¯Úm7H»ŸJÓ¦ñJÛËie+C‘ ²¡€T@cŠòŠ(°ð7Û³5OøGüÿøK<è>Éö-ßjû6Ù|ÿ'îÏ‘Ÿ>ÍÿÁæV§Ä[Äz=σoo5;ø|CâK³vÆæ2o.×k8mÁ‚…IÊà©‚Ñ@¯5íNÏÆöÚ­¾£w¨t½6C}ì³–m> ͼÙ999ç'Ö¶|}âý«B×F¡«\èðæÜZ^NòMgöÔµyRÙ¤,»‡'ppyÝ^cEw^&þÍðþ‰s&‘ò'‰¶Í?1û-аc[;ÿÒPǼíoô-ßvjájö·­Þx‹R{ëçî#÷P¤(QQUU@•F€:}oý7Á>ž×‹[?:Òî%þ¦‘¤°2&ÌßfqŒF iÚø†çÃß ôy,£/WÔ^Åw=§Ú!ky¼‰Y<Ø›ï#`ò§ ðqU¨Õü­Üêzeþ¡ci®êž-¼Ô§¸Ô$ðÝà´»òYQ°ÈÆ3!›"0ªfüæ,K`/î¼[¯j¶>!·ÕáK[Y4} RÆ¢á¢ýìóJ‘1b%2ƒ>dãqVo#¢€=s]Óžj:…¼‹}{¥ÛìJ·h¿T¶&;…9§¹ùד)Êþð¥cüAoŸxpx¢{ùµ1©j&§3IqyVxVV%“»l0`0ÀŸ;¢€4ü-ý›ÿ 6‘ý³ÿ ¶Cöß½þ£xó>ïÍ÷s÷yôæ»kûþÍ[þ?ÈòSûíò¼ï:<ýoËäùn|¯ÝcÊïåWÑ@ͬx®þïâot ÑáʚЗMDÌISʳ2¶s/™?™÷†©T £Æh¢€;«[Í&Ëណú–›>¥(Õõ·D»òbCe‘*„,ê~^Ðã8`H"].Ï\ñçƒü[qmew¬ê—:ÕåÀ³¶29-ég*ƒ¹»EpPk¦è:›xw^ðÏöuÚøˆßÙ]®”ð2ܼiÈr±‘¹ˆóãm ´–ÆÕb1ÿ²#ð¾§öi7ášâΤµ¸Œ–àÈ9 ð ÚÊ ¬8#8TPuàû÷ÆÚ=Ž‘aaý¥çiRÉ{|—;~Õ[‰,1ýÏ4±SØ+Ö·u­nËÇ&’­ µÖõÑi$åÔ¥¤Vìåœ(*‘j)¨T´P8`Ê( añ­¦­®xô^é~%µ­ä7)ˆu¶ÝÅh"ŸÎ™#1$‘C»Ê älf 3”©t­JþæûY:wˆ#ƒÁ’éz§Ø4Xõb?±ÎR&µV,®˜%Ô+23orêÏã5»©øßWÕìdµ¹š³cÏš+8bžã7ï¦DK–Žö9`ä€hºÒ>Ûöìþü+o&Óû_fï±gËO¶yý¼ï3ÌÙ»÷Ÿê|®<šãþþãÅÖwòñ§iù»¿ÏÝ{U½ˆö>h>HV»J¨OÍ\ÅYþÔ½þÌþÍû\ÿÙÞwÚ>Éæ·•æíÛ¿fq»gÇZ»}·û3Tÿ„Ïÿ„³ÎƒìŸbÝö¯³m—ÏòqÎìùÙóìßüeqôPµÉ5ÊjšøŒ_ê^'qf¢ô Ówý£0 ²:Èe‹ÌYK«¨U (Lcø³Åú>¥ \êÚµ нÊÜ/ˆõ:úòÒTHäƒq‰8Š™B¶Ò7K)S¹[YEv1·¶ð®™‡lnþÜ· JâëË1ù¨U…˜Øs·÷.eàçý+c ÇRø§^ÔüEðóÃ×:®£w©Ü.©¨Æ³^NÓ8Q ‘ q’N=ÍqTP§x§þÏø›ÿc}¿þ÷ï¾Å×û/ìœù{÷~f1÷¿{çuýõt^ÔžÊÃG} Añ§ Gmn×¢ÇUX4©¦©¹[Å00P_x9ÿÕí ˆ¶cÃè ½'áµÖ¹ý…=¶“câ†åŒ—Þ¸+q* }¢$RÒ¢ã1©hÁ&`–+æÔP®hÊú~¿âE#RÖ¼]¾ÔÛ>‘2Ùê^QŒÿòÎB'ÉY•s.|ì»(”±ý¥3üB¶—QÑ®í®­ü?© ‹}nðÜ]ÝbÖí¹eXÜ¥P¼µŒƒ‚¦¼ŽŠë-¾$ê­©i’j;Í:ÉæÙÐE´FÐGqÐĈ%G™ÇÌI;ú'…u=÷wnÑn5(5-VëËxüÛRØ·YÑÝåùïô­Œ7F+Îè \ñ–¥ªŸ j‘_h>!‹O•#[[[UŽm:æ£+Y¢ÁlJUòNlåFÀkÆž4Ô´[Û{4ÁaÚ„2ÙnRM:u’FŠí`6V ¼n¯;¢€,Ǧ\˦\j làš;y$Ü>W‘]c99? cåç¨Íj( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“+þÑÿò±ÿ°Šé$µä«þ½ÿÝ_ækÖ¿hÿù ØÿØE?ô’ZòUÿ^ÿî¯ó5žOüŸã—èVoüh‚$”QE{džQEܲ³, Æ=ýýêZ(–¥#:ë÷l?tüäzzô?ÛSã/ˆ>è^Ò¼;yq¢ÜksÜ5Ʊ HþT0¢ƒ –V $2ØÈX¤ÆpWÑ´ÖW Ë¼l z’+Ó>(xËá÷Æ/ Å>Öïl£˜]@Ñ´QIʬ«"2Î`‡91H=”Ü¥†­JNIÉ+?¼œ=JlË ŠÅÐöÔ¡+ÊÖšyúuÙžû|ñ}ÇÅûjºÖ­âS‚àDu î[)’37š×fCñíf#sÇ·o;½câ·ü”ßÿ×X?ôšÍø%£|-øuq¨hzŠ5râµ—XÕd¶’á¡.Æ$HÕw*Ÿ•;Wq8OkÑx£ÅÚ¶¯[[ÝÉGÆÐà,1¡ÎÖaÕzŠJ¥(W«Ï4ûßK>¯s¯8Å`óî¶7.Ã{ 2ZFÉ+é­•Òô]«ßYZ_jצYÿáŠÏívW—Ì›Î[E»@ùªô÷I)Wô_[j~‘î-¤±ÔVÂâüO&³k–Xây—ý¨ŸŠ;º0“•àòw#½¹ðõ¦Œï›;ižeå·ýÕ<ãj#(ÇiOñšÙµø‹uj°¸ÒôÙoE°±šúXäin-D^O’Ã~Ô ¼j’`}ü³ÌsA¦èÚ&•¦ÝëV×úŒºœ-sVil°Ä²¼_3¥q#»Ë%Ž£¬–'ä‹ì¬@À8ã€÷ˆôk¯èvš¾>£öJÖ(•."”%F‰üÅ9(+À#<ðh>Òüa¬Ü:ôí2ÂÏíw1_êpy’âE@«3¤Q¦æ’1–hÜFó„8òk6ºf»c©xv ½1ìÝ'ˆÞ\Çtë26àÀˆ‘qÂü¥OCÉοð•,ŸÚl´‹ >Ùáû=ÆŸ íîSvHI#78^URŠËµ”5uà ]RÁZîK+y­µn-­uK]VxE½©™%ßÕܯ–ÛOîÛæùY`øg£^jº<]߈®u-& „&äŠþ#2"0´h˜2ËýÄ óògÆF Å›OÑôÝ-µÍ±†Ù%`Þ|- ±y$g'kp7mR2æmÚzÄ™¬õý*æþÍ•½þ•u0·C汌ÄrØÉBÄç«cGF}I¼Òµ&Ò®gžëH…n.®eâ ´iR"a]¡ÓkÊ€Éu%”G–z}[᎙¢C©Ø^]A£a æM@kö-M3ykf?}ó2ùC,$1Eæ1Çj~*[»-,4‹ ð.Ešà «4²9Ú µH…, U+-׌õ¬ÆçGÓn5Y¤º¼©+\>F ²™<¢åN ˜÷gçÎÿž€4áðÿ…´­/ÃZ޵{©H5fžk=Ì]M 0‘ð¨6Æ¥WY•Á1‚­V¾øÛÅQÙ[Þ[Io6£r ¶½}fÖØ*³-¬«æN÷}ÆŠ”05Çj:ÌÚž—m*Æ©§[5¬E”Í$¹ny;¥aÆ8êvtÞè¶úq†ÊÂMGLãOÔ§‰¤–Ñ|Æ“j¡o)¾w‘ƒ:3üµv€^øf¾¸¾º‡UÒ®ï2¼wq¤ARÎVcBçx*J¾ï”í;NÞs.t½2óúƱaݪ[_ÙÚÃoqp³²ÅpÎY„i“ºÆÀ$õª¶Þ$6ùÔìtûK$dxšÆ3+@Ѽf9.ìøugïÈÜv•ÀÅý?Ç §ÿjÀš“.“¨ùM&—2ÎÑFñçd‘¿›æ« ÏÒL#1€/hþ°Ô®¼=×’Z¦£¢ßj3O!ÊE$&ð)ùQ›gú:3¶:ŒE¦økBñF«§iZ%ÝúN~Ñ-åÃC^näMøFe\<›IT%Ð3­uñV¾¾³»¹ò&ž×M¸ÒИö¯“0œµH ´\2 PB  ƒƒ¦jw:=ôwv’ySÇ PÊÀ‚YH!•*T‚ ‘@¶·àÝÚÖÎàÞÇ¢#_Ãk0:Õ®°þK‡/8[`¬¢=ƒ ƒ»Ì#Õñ_†tÝ/Hk›}#R´Õ#¿MVÛT³y;ÂÒC*>ܾ73aGɇÜ1ï¼Qÿgûƒ¤é>TË9ò"’5—î†ûCËòŒœ Â¶~`Ø\K{ãåÓ®ìôý MÑEâ,Wٵü±‡Y6:iÑ òœ;EPÏ‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôeox+þG-þ¿íÿôbÖ ÇüŽ^8ÿ±ŠûÿFP´QEQEQE蚎—eo­øÄ"ңͦ›Û;o)E¿›x»ÛK@ÒLFI²~ƒ³ÎëNãÄw·>´Ñógm3̼¶ãŸº§œmBdeàÍ)þ3@f‹à mOò=Å´–:ŠØ\_‰äÖmrËO2ÿ •áÑ@wFr¼x4ÝDÒ´Û½jÚÿQ—S…®`ŠÂí-––W‹ægŠMÌ^7à9bÄ$¶¿n­V^›-è¶3_K-Ũ‹ÉòXoÚ€ÄRL¿–bjÛxÂ4ŒÃy¡iºª;µ­½Ó\f¬ÅŒq²L®S'!]›q.å€"Õ4K+_ Ùj–“O7Ú5+ËE3"¦b‰-Ù 'k9²70àÓ'OÄ>²Òt;ËØe¥‡û#hvR§íV2\Iœ΀/ ÎryªÖ>>¹µÓ.,n4½'Q‰ïP€ÜÙöIÙpÍ¡UÚv¦b`ÑŸ-~L -ñ?P¼¸ÔßU±°×"ÔaµŽæAdmïoŽ9„Šë “hlà7˜ù8´Ïhߨ±êz„·æ!¡Uã¶d òHÚˆÁaò©L|Ü•$¶ †¯üeá.,¯'¼òu+Í*gž%|¶þQiCª|à¡I'÷{²7ìJÚŸÄM[Xµ’ ¿"_3MYqÒ°‹¡r¡@!Wk€P 0 Uñ/Œo|Sç}®(#óu+½Q¼•aûÛ/x'åRàuääžÀz½µµÂ%¥ßÛ"0Äí'–côjΘ?ÜrÉž‡nG«UFûûFá%û<»aŠ–ɱNÈÕ7ýæÛ¹vf=êµwú·Šngøy§\›.//ï­&š-Î71¤6¥B•ˆ Ë! ¸<õàbþ“ðÇLXtË}Vê§¿† ‡¿:ý´vI2+©ki3,›QÕˆÌeŽUxÛÏæÖfŸB³Ò™cö·3]#w–•bVçÄ+Ž;ž¼cRׯF+XVïGÓu[ËtÛßß$¯,J£©Q Ž@•€åTnÙx3Ãÿð‹Zjww:—Ú–ÚµÌ0,{EûZ¬HÇ•.Jä›í“xT5h~µº›T¼»¾{MjÿIû-©½Ð€CµÃuˆ1Ëgy?"…åyßøLo±ÿ³|¨<ìßì½Û[w•ö¿µç®7yœgÛÆ3Ínß|H´Õ4É?´|?aªê7½ö©7ÚMÂEž°q•2±¶Cg.Z—LøiÛ5)®ncºÓlÒÑãF¾ƒN’à]Bf‡2NJFD`–Ì;†Ð&EÀzDþ-´ÓÓPŽÚÖãK»¾-üWßb’(®VI R®?rŽv `²mÆFO;oãß·]Í}µ½ÞÏ>ÊéY`}ƒmXÊöË+µrƒäfRɪ׶zu†žŸcžÉ-mÑüµIb’79f.͉\†vbÝP ×öf…¨ßivZ$z¶£?œæñ®šU–·/. Ú»™ÙÔH•ox¿Âzo‡ít]N8¤Ww3A5œZ½µóâ!1[ˆSb–`)BWnã¸0˜Ñ5™´E/ Xä!$‰â”’Ç"4r#`‚#2’¤œ‚ÔÕ|du] é‡GÓml¢s%¤vé*›Fm¾k+ H_b‚f2`hPÇáÃ^m?F¿´¼¹ÓZTšKøx½¸Re n¦FÂràl;y«qàë(¾"xAÎlôßíO%Ë/˜ßf†gqÆLKœÁ8Çly¼Hn´4Ë>ÒåíÅk|æQ=¼fC!E á,ò²1ùÏ<.7o>,jwW—·‘Øi¶wº´¶ÚŬ-_y´LÒ ÛAùŒ„ UgÚ̬UpCáÿ iZ_†µj÷Rj6Í<Ö:z'˜ºša#áPmJ®³+‚cZ­xÀVm iú–¤±ÞEhaOYi†(ÖG,' ÎY‘ú(P|ÌX„ãµfmNÏK¶•cTÓ­šÖ"€‚Êf’\·<Ò°ãõ7ôÏ-¥Œv—úE†»Âüέn %•Z)í$–ÚÄ€K³è´Ïè†ëV¶I¤ñ5Å­üÖ°Ãa©Ûؼ±¡9b,†àÊwH²W`ûÞb×®ÚÃc«Ý[ÛÃwl‘>Óo|¡g…‡ÞñŒ•l®p¹Æv®v‹ö>(Š´}»AÒuo6fœyñI”Í÷‚ýâùNåW(\¶hkzÌÚö¢÷“¬q’‘Ä‘DH£8ÑrI!QUAbIÆI'$€_ðVƒmâ]tØÝÜýޱÝ܃±˜­¤•KaXíÊ € ÆqÎ+OMðÖ…âWNÒ´K»ôœý¢[ËÝMa†6†8¼ÝÈ›ðŒʸy6’¨K f ÎèºÌÚä—6ë»Û\Z‘ $mš‰rBG¾:ô¨´ÍNçG¾ŽîÒO*xò*XC+)2°%JCA(±ñ/‚¬"Ó —JËÔd¼ŠÒ-:=rÓV–ëÌW;[ª”ÚQWÆUÆ1ÉâßXiÞ}^Æ?²y7‘Z› ÜZ\¥ÚMf’ÊæD9BLòH@'jà7ƒm\Kqã…—LºÓ"Ð4›M2|HmaYþY²¤âF”ÈYUØf1üÄìÉ$€tú›£xoĺވm¯î5Ë7V¶šü]¢ÛRÊàI¶(±Q†PL€œ!s°yu|Eºn&þËÓeÕ.­§µºÕeŽF¸%‰£bÙ}ðÙ2*‡b2ÌÛŸ'@“à‹­3Dð«©E¯ëZ.©öûH%ºÒì”ɲ])$ûB3#ìVlíÃFœ7Qc¢é:æ™âsTÖ¯Ñmõ(#[§·ón.„ËpÅŒeðd&%cºPó9c´vfh4+Í)V3ous Ó±xh–UPqŒLÙã°éÎHu™ Ð¯4¥XͽÕÌ7NÄá¢YU@9Æ13gŽÃ§9ÞM/Ãó.£­G¤|?höÖâÉ®#O<±;ó|²¡Å1ݰ’ £qd½gàíʾÕ.¥¿þÇþȽ¤0²}£þ?RØÃ#·ïyƒÌ¦×ÙœÅ\Ɖ¯I£ùÑ=´„ûLö7{ü© çc|Œ¬¬¹8e`p̹ÚÌ ©üc{:êQˆ ŠÚòÍlÚ5a´ :L©Ï·W¹°µk]JîÒæçÎBªÓ}Žʬ*¸Fâ®-åÌ*Ýø^ÒïÅsC.™ºÎÏM°ŠåbÔ­ôµ†ïì± ä™Jy›ÖmÑà9esü-\L:ÌÐhWšR¬fÞêæ§bðÑ,ª ã™³ÇaÓœì·'ºÔõ»«ý6ÃRƒW¼7÷Sù©Ÿt…]Lr+¢YˆÃr € ÚŸmtŸêÑM4¥é–úœÉÑÉ+G0ƒl)*‚ŒC\"@Û€Îð†Qá-Äv‘{¤¥þ—ój t/.Rí–+[x®£ÛYbŽà)à¿2‚H«oãˆõMnÖÿV_ìûÈ¡1KK¶FgU$¶fX^1˜¼µ‚­–ß‚­/‰>"Ü\É¥C¦\ÈÖúcÍ$3Mg °c2¢Ê‚Ú<Ä‘@ 0rÒ³gÌ* 𦗦^èRë:4Wvvö×1Z\Zß\,ïºE‘ãt‘c@AH •Â[q ÎÖÆ³âC©Ú­¥®Ÿi£X½¥‰”¤’@wiÙˆ€ arÛ@.å¨^_}®ÞÆ/³ÁÙa0ï…6´Ù‘ßt‡ø›ç۟ÔZŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( º É ðýÄ?ô¥«—®£Â_òC|ÿqý)jÊñWüŠúÇýyÍÿ ô¿ÿɸèö+Ÿý#޼ÓÅ_ò+ëõç7þ€kÒüGÿ&ã Ø®ôŽ:ñs÷Gê¿4{Y?ûÚô“0?kýþM÷[ò>Õýšï{äoÙæyv>ÝØ8ÎÜgé\‡Ž~|Nðã‹Ûë?Ý\xGÃÃĺ…§ˆ¯ÌÂÈ‹¢… iŠŒÎlî.ñ‚ƒvÐÀž«öËЮ«§| ð.…âßxzãE}j-t;YK\îfð?ˆ^¶ðwŽõ½Êk›‹;9"Xžñ‘¥! ŽC’Š üÎ{1_l×ÇŸ䮸£þºÛÿé$ÃÙ–/ˆt+NñQºV]Òè¯Ô×F8sEks2ãÂRXø=õ‰ü¹ ÜÛÇ Úß[̈²G3•̈çbí ÝqQižÕõ{î­¡€¬Ùò!–ò§¸Á+û˜]Ä’åQ±NX ŠÓ¾Òï|+àmGMÖm'ÒõÝJÒâ K¸š9^(¢¹W}„d.f@ 1Ü; 45®§s®Á¤46vÖ“ØËo4³·‘Eºˆc}ë ;dž%NߢI[HÓtmWšܿf¿‹XÓlÖïíkCo&n¡‹o•ån,Ý|ÃÊú¼ á)<[®Ú[-íÍÌ1Ï ß[ÛÜH®Ø+™Ô;g’¹ê*/jvÖ?Š`žM’Þé©on»IÞâîÚB8|‘¹ÉÀãH£ÀZ¶‹ãŸê²y6vš•µÄÒm-±Uf8“€f€(hÚ%æ½tÐY¤d¢$’y’¢\¹ärJ¨,FK( ÷ð>¶.å¶ŽËíRÇ \±Ê“¬¨ò¬*bdb%Ì®©„,wduVÆŸ¼O—¦jšKÏab×ÓAp—º‚^Û¡‰e6ŽB»„ǪH*veÔ¼ñŸ“½ k°]O&„4Ûit»±[×±JðÆ¨ˆv˜Ì¥‹¢d³¯#€9ÛïkZmÖ ÌV‘&¢Žö—gP·6²„$>.žVA ¶A c‘™|eà+¿´&kË ¨¥†ÞLÛß[É i`YHòÒFm£qñµ€0ª·š´¾Ò4ô“7jW·G´ü©$Vª‡8Áɉø?/=FmxÆ{a,µ[]J”ÙÙÙ¾œRQq†Ù!g'g–T´DŒ98eÈ sQEQEQEQEQEQEQEQEQElø+þG-þ¿íÿôbÖ ÇüŽ^8ÿ±ŠûÿFV÷‚¿ärÐëþßÿF-`ÜÈåãû¯¿ôeK]LJ´Çð{ë6:•Ü÷÷6ö·6·K+KÏ”JÅ€0°åW9Ž•Î×O©Oc¢xfçE´Ô Öe½¼‚òK›D•"„D“"§ïQ™¼ö'åB® !([xKQ¼Ò¥oöIáòc¾®B®w7ÍÀ±;xP[îŒÕ Í2æÂÞÆyãÙì&âÝ·½<>xÜ`àñž„W¥hž(Ðôë$Xõ 6ÎÊçK“Oû Ò—±\ËjÐÉ4·-Â/5žLÇ$°ªˆðJ®†vãgÏ÷y«ZÃOjŒR×Móe0¬ñÅçÆ$L >!BÙ•„NŒQ2†\€HÖxƒÇ£Y“XÖ-õ­Àj)pNƒÔSÎVV‹Ï ï*eóC%±¼ùu—Œ,äø›àíN{ù$Òô¤Ò#y;¡ó•WÀq)ÂŽI$g9 žøs{âMPÔb½Ó`Kko>8çÔ­cw>|qêò«D>rC8á@ûëT,|ªjh1›¢‚f·3ÜêVÐE#¯ÞÈò—RJ2žŒ¹—Á÷¶qC®é÷—qØ RÀZÇu:;E-Äeö+6…”mSË.p2FŸ†.íìínì$ñ‹öT¹}Öú¾4öó¡KÀë Ëp¸bO…Œ†$|€ž§¦\è÷ÒZ]ÇåO ƒ+VV†V0`H`A‚ V­?fÿmÜÿdÿÇË·ní›ö3Ëßóù{÷lßóìÛ»æÍfPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP]G„¿ä†øþâúRÕË×Qá/ù!¾ÿ¸‡þ”µex«þE}cþ¼æÿÐ z_ˆÿäÜtûÏþ‘Ç^iâ¯ùõúó›ÿ@5é~#ÿ“qÐ?ìW?úGx¹Çû£õ_š=¬Ÿýíz?É”¿i»Ë}:æÞêêxí­`¾Yežg‘¢ÙÊY™ $ô¯ŸÅÿùÎá6ðî6޵`õ?í×­~ÝßòN|Qÿ^·_úm¸®ïöˆý¡t=kàÿÅ«Tý ~ëz-÷†u¸,ü?¥ª Ro2Êu·….?µ$W—sF ÿ>UBÃny?ðjŽ_¡Y¿ñ¡þž/ré´¯"ïP–\g#ŠôH~ØSí:õ½ÆÑæÂžÔ$XÛº†*¥€‡Þ¿Cuù\ÿ×Vþf¸óü}l:s¥&®ÚÒߪg”j¶¤$ýŸ5û¹å:‹ý·`¤(»žÙ4·-€H0]28Æ~òîSýìîUäµOÝøSV¼Ò/ìWN¾µu[«ÆàEpwF̧*ËÐûv¯¼+ãÏ¿òW|Qÿ]mÿô’ æÉ3º¹gB¤vïÕê—dºôEâpÑ£dúœœze̺eÆ ‘æÎ £·’MÃåyÙ3“‘ò>^zŒÖ®ÁµÕ¾ß›‹[-†¥aoðXÁ ¡½Á¤D ùòÐ’Ä’W=k{Iº‚þ3E°¶°³Ôæ†Æ‘¬hq2Þ3¢à%è}Ó–¤ùj‚L,ŠIû3Î<ÆŠômÃ^ÑnÞæH®µ•îe>µÕH’²ƒO"ˆÊ Ê*îýðffÄÃDÒôÏ]Ÿ ù±[ë¶ÐYXêEã{de¼ýÜ»[ÌáP¡ÔïE$°RÎè®ÃO½Ç­Œ¶šì1KdlmR×FG”ª£9<Ï‘Ï1‡³¥Øø|øŠþÙÚ9aðö–Âìí£»ûmÊJ¦i¼²è·¾dî¹ yPÆ\2««yµêv2èž#ñ‡€Ì6’^‰µ¤·º¹ŸE·Óíî#ó Ä"(]£r»œ±#$J äÇ«ø’Ú÷L:m–‰a§Y‰’T˜)’ì•W_žf9;ƒ)eP©¹TL¶@0¨¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÙðWüŽZýÛÿèŬù¼qÿc÷þŒ­ïÈå ÿ×ý¿þŒZÁ¸ÿ‘ËÇö1_èÊ–´ï¼-¬éze¾¥{¤_Úi×|›¹í"—rî]®F@$`òk2º{?Üü3ÕüÏ“í½—“»7ˆëÌÛë·Í‹v:y‰Ÿ¼2ÌQ^¯áýÐé7zë}²æ }UâƒA·+kCs 5ða8Áx³•ÆïÝò§'ðþ¦x£HÓæ¹hìSFw]PÂV9&³;åY î—w™æÂî’Ñ?ˆšâ¨¯DðÔÊþ~³2Ágý¹©Kok§éþ¶Ôñ*lvH㇖¿éª„,[m\ó=Ó-´_ø‹O²É³´Ô®máqmˆ²²¨É$œ9'4…VdÓ.bÓ-õsÍ%¼rn3ƨÎ1œŒ S’1óqÐãgÁ¶°ÊÚÅÛCÕæŸ`×vv²¨t–A,a‹F~øHÚYJôýÖX u¦Ä<_¢ø/þ X൞ÿW’ìtø­…ÞËks$q„¥åO/ C1ù)ÁGEz&³âM]2ÛP´´þؼ±Ô­ä\xr×O´TÛ#42‹y—Ì(˜3¶7ÚF[4‹o§ÛÜGæAˆDP»Fåw9bFH•AÈ ŽM¼gmÙa²ðæ“­ä7h·0›‰e1îf‘Ž]\ÞŠ @US-bŠí|A£ižÒ5 ­š;äÖ]K3’HlÆÉZGÀeÝåùr»£»OẠi7šÇ‡­RïP¶·¶¸¶ñøzÛ|˜…ž+Ÿ¶‰LÌ™Û9p²g ± Èè®þmjÃÂzƒ. ðö›}©K`óË>¡›{r¸1p¬J©VgÜvìÙå”ÜOêö6:ŸlZÓB½•Aq«h0ß[]þñÇœftyPa| ‘ÆËº,’ 9Pн¯YM¦ëº¥Í¤v÷2E-¤N] eb +bB‘€KOZ£@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@uÿ’àûˆéKW/]G„¿ä†øþâúRÔ•â¯ùõúó›ÿ@5é~#ÿ“qÐ?ìW?úGy§Š¿äWÖ?ëÎoý×¥øþMÇ@ÿ±\ÿéuâçîÕ~hö²÷µèÿ&Wý£ÿä+cÿaÿÒIkÉWý{ÿº¿Ì×­~Ñÿò±ÿ°Šé$µä«þ½ÿÝ_æk<Ÿø5?Ç/Ð¬ßøÐÿD¹‡í6ÒžbÎ3ŒŒW®MûNøÚy¤‘­´ÎÅŽ,§Ç?öÞ¼¢Šôñ8J´£^ Iw_…ÂMÎ…5¶‡:³¨­'ssYñ½¦§j¶–±iº5€q+ÚXÊå$»I#³ Âå¶€]ËßuK= éVþ'¼ƒK(ñ›õX ¶w.ÀÛprr1ÎO­wÿµÇíGà¶ Øhd_ë²ÏåM IЪùÒA<°*‚qó–!‚í>Qû*~Ö~)ñ_ÄË?øÓRƒ\”3?S‰Ѹ Æ9AbÙå$¤ŠA@ mß/¯Sê´±‘ÀJ«çÝÓ]µ¹Ó‡Ê³lNI> §A}^ ¦ù•ôÝ¥k´º¿òvÙðÿŒ5] gm[¼ÓÖb§O»xƒ•Î7l#8Üqž™>µQn¦KY-–iÞGYÇc2† Ät$`mÇÔ×Iñ[þJoˆÿë¬úM t+Ñìô-·ð÷‡žÒì¥7rjÎo¼É­¢f³‹ rB@ò±Œ梤=œåÎÇ™J~ÒœgÝ&yÝ­ÔÖ7PÜÛM%½Ä.$Šh˜«£ÊG ‚2¢Öêk¨nm¦’ÞâE4LUÑÈe#AWVÚƒjß ïÍÅ­€–ÃR°·‚x,`†P ÞàÒ"|ùhIbI+žµkÃ_ /uÛU¸´×dµ¼Ümމ£µþUX£3Ÿ1>e .K|¤ ¡lÍNbûÅ:Ω©ÛêWº½ýÞ£o·É»žåÞX¶¶åÚää`’Fæ³+¬¸ðD:Ö ¾!Ô$²·µ¿ŸLI4ûqtóÏ nÕgŒPÉó1ï\)ùŠE§èšl¶¾-x¦þÑŠËMŽæÎà£DÊÍulŸ2g† +©eÎpXbÌQZz‰ý±5ËË7Ùl,¡ûMåÀMí[Õ>TÈÜÅÝ –*»˜j}¾âÊM"óíZUߟ¶òò/!¡ò#\y±«9#!þBû•†2ùEæ(®Á|§ëZbÏá½FÿR¼mJ×M[[Ûíw¼ë)B®'qÖ"p>`sQ·…ô;Y¸ÓõË»ËÝ.Ù.%FÓ„vòƒ|¬þTK÷QrxQ“€8¯JÖ¼-e§i±›¯ G¦hÏ¢ÛÜÇânƒÍvöI*¢Äå§m¥U ¼ü¡ ¯1gàˆn$²Ó$Ô$‹Ä·é––Ü4 檴(óo]Õ”€”oMÌŸ>ÀbÖêk¨nm¦’ÞâE4LUÑÈe#AUW^ÔõÙ š–£w¨9s&ë©ÚS¸ª©l±<•}Ga['ÀW²èVú¥³ùñ>šu Ë`W3Cå©ÜÛ ’SÓäŽCÑ ;¶ÿo_S×#)«_iÚv¥>–·>”×’Ë,Móu® œ³ç.†Ã•㵿ë>%òµõ{ýWÉÝå}¶åæòóŒíÜN3œz £5Ô×Á³I*@†8•Ø‘î-µGa¹˜àwb{×a'à×uí6âþ=<évê&KøÌ8ŽFƒ *ä”uK€YyÜ…9 žw^ÓôÝ>kdÓu_íehwO ¶hV9C²•]ܲªÁˆRCŒªTQ[©’ÖKešE·‘ÖG„1ØÌ¡‚± ØÛqõ5zÇÅ:Η¦\i¶Z½ý¦q»Î´‚åÒ)w.ÖÜ€àäG b¥ðµ…Þ¿Z‘ìå%(“IåÇ$Â60Æï‘µ@ŠÍ•±;—‡OuáiumwÃú=×…£ð£ê—ñ[[ê6†y-çØ+:ù²:ÌäehÜ. ûÛ”¨'¢x§Yð×ý‘«ßé^vß7ìW/™ŒãvÒ3ŒœgÔÖeié'ö®Ÿ­ÝyÞWömšÝìÙŸ37÷9ãývìó÷qß#¢ñètm_XÑ­õˆïõ­9îÛǼî,|Àä B!Ç‚‚»üÁåÐ1£kÚŸ‡nšçJÔnôˆCMg;BåI©*AÆ@8ö\ëÚæ®5[Fî}P:H/¤špË­¼Ù9ãÒºy¾C柧 b95RÚÖ}>Í" ¦†9r¸Ýϱ2HÜâ$es‡5¿ðgŠlgµ°x¬´Ô¸·›ì0 „s}l¤ùÁ<ÃòÈãˆÁÇ@( ûÅ:Ω©ÛêWº½ýÞ£o·É»žåÞX¶¶åÚää`’Fæ³+Oû†µâ›Ìòï>ÉsÌy;“t-œüÛöN0Ëås÷–­j>û‹“Ãí}S¬ÑZÜ\]*+iÈQ*»r6Ç!u.2BÂ(k©®#‚9f’T q+±"5Ü[jŽÃs1ÀîÄ÷«ßð”ë?ØŸØßÚ÷ÿØÿôûKýŸïoÿW¿{æéמµ™[¾Ó-µ¯øwO½Î³»Ô­­æq]èÒª°È Œ‚y45Ô×Á³I*@†8•Ø‘î-µGa¹˜àwb{Öžã?xvÕ­´­wRÓ-ÙÌ ä¡b,B3€}…PÒôËkS´Óì£ó¯.æKxcÜ{³Q’@$rN+f÷Ãvi×w:>«&¨úz,—Ë%¯ ¬bHX±2&÷Qó,oó¡Ù÷ös´Wk4żÔ4‹bî/XÛ]K=¬v öÉ$É+Åçƒ<²…„dnÎ .žð&™}«èú>«¬]éú¾¨öâmlâ8–}¦#™“««¡°¬¹;·*€qTWuᯅ—ºÎ‰mªÜZk²ZÞn6ÇDÑÚÿ*¬Q™Ï˜ŠŸ2%¾RHPPµUøq$_ð‘­ö¯a§6‡©G§\K9sóÁeÚ¦Fù *¡8}ÇhV ¢¯kv¶z“Ŧ_I©Yl’â[!ÉdVedÜØ*Ä©Á íÈ$[? 4øçEÓõ+˜ ³šò’9üÑö€eU1)I ÀœTì8 bŠíu«)¼Q¨ØYÁ¬xzü„žW—JÓ ’[ƉæHòâÚ"à"3¡ÏÊÀ WÐ,“L:¦}>¡§E2[Nní–ÚX¥uvOHà«ß6rŒ/ÊX Šì¶×ou˜4ë7¼žÕãt/)1¤/ˆ‘N]˜Jß{b€3®õ bŠé×Ã:M¿Ú¯o5‰Æ‡öɬìo-,|Ùo {I)äMŠã'sg2(°ålÅðóÉ´ÕnõV ;]:k=ò¢ïóชIc’%%Y™•ldû̹Œ#ÇÑ]†™ðûûKYŽ®ç¸°¸³7ömgiç^]Åæ¶Ço¼fEpû×vÅ#u [ĺM†“uäÙ^ÝÎèï ž¡eöKˆ$R ÝqÎ>öì««€XŠ+°ñ_ôßÝë–>$‚ãT±™â·´¶·góvʉ‘±C¼*—ÆÖW(ÀÇÑ^“yðOSÓì/EͶµo¨ÙÛKs;I¤2éËå£Hëö¢üªTV|ÅHsί†t›`‡YÖ'ÓµKˆc¸Ž(¬|ø"IX%wúŒŠÉñ†ƒ…ü]«iO5ͽ¤‘¬r\m.CCœíU\ö®’ûàî³§ëzî›-Õþȳ’íîÖGû=ÆÅfh¡}Ÿ4ƒË˜mÀæ F~C^unoi.mîî]_eM¬­÷ž·äxfÿHòw}ªòÚïÎß÷|¤vãçÏÎsÆÞùâý—ˆtË:ÒÏ]ÓnïÅŠ4V’ØÞ­«¤lí!GÝ€wvFö°Ú+?êxrû\žÎþßLŠö÷Ÿb‘­ç9#)æµq¹ÎIÆSoR*®™ámgZš8´ý"þþYa7–ÖÏ#)Òôí2ÛIÓ&°´WÔ­õ½ðä7#ìÆ%‘C+\²Ë$Ÿ½È]ʉå®Ó™©­x“KÓ<9«YZ6…yy«ÂM.‰ks+4r™Ϊ&< UC¼“·ËO¬è:Ÿ‡n–ÛUÓ®ôˆA"ÃyBåI 0 ÆAö46ƒ©¤z„§]ªiÎ#½cjÅŠ…ãä%lr1@:§‰´kíz…î<Þ »Þó\ý»m«ÊÙÝ/’# ä¾›wÿÏÝÖ^¯­ÿjéú%¯“åfÙµ¦ýùó3q4Û±Ž?×mÇ?w=ð"ºÐu;™ntë»s %À˱D¾QfÈà ÂOñ|½x«VÞ ñæu[} RŸKòèìäh®w6ð6à`äçŒJÇ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(gÁ_ò9h?õÿoÿ£°n?ärñÇýŒWßú2·¼ÿ#–ƒÿ_öÿú1kãþG/ØÅ}ÿ£(Z(¢€ (¢€4üE­ÿoê]y>G—gki³~ìù6ñû8{ËÝŽÙÇ8ÍlÙøÞy,µ94ù%ñ-‚E¥ø¸ ùJ« ¼;çEU‡U;r¿Ï¾õ÷ÁÝgOÖõÝ6[«ý‘g%Ûݬö{ŠÌÑBû>i—0ÛÌŒü†°¬ü¨MáËír{;û}2(CÛÞ}ŠF·ü䌧šÕÆç9'M½H  úæÑ­tg‚K›}6ýîf…§!.à`£ìÌ0FÌ‘ƒ‘þ•/Ëó6ê¶~)†îÖKOÛÝëææKÔ’Á ÂÏ Q+$ "n ¤å†\°jº7ƒ¨ã61ÀÍ8eÎåØìŒŒqƒéV¡ÑaÓ5yì|Mý¥¡¼H F–IÕŽ †ŽI#À*sœúqÎ@ 2âÚÖú9/->ÛkÊÉÆÄFU‡FÈ$2¬2§§µñÍ—‡¾Çÿî—=¯“©[jý§x·[å·ßå²8¶¯ï_p䟗ps™«h^ñ¦§¢êÓ‹; ÉíîÚÙd‘¼¶e #irTq¿€O\s‹t(|;¬ý’ÚêKÛv¶¶ºŠia¹Y Ž`0 0pÇ¥l^x×IƒO׬4_fYêЄo>ëí2ÄEÄR¨Y )òÔFT'R_s³í@·üiã= üUâMKöWbïP¹»Q¨]]‰#hf.²4pù(Pº9Q½›j»q»k/'­ø[Yðדý¯¤_é^vï+í¶Ï™Œgnà3ŒŒãÔQ'…µ˜loodÒ/ÒÎÊcoupÖÎ#‚P@(íŒ+Ê0prG­uš¿Œô;MSMÕ4»+¹õÛ+ =b¾’ì}š;ˆ­bMÞG’”d8Ì…K($2§“Ò5¿ì­?[µò|ßí+5´ß¿^.!›v1Ïú¸ãïg¶ cámgTÓ.5+-"þïN·Ýç]Álï[Wsnp00''€sQiú§«ÚÞ\Øé×w¶öiæ\ÍoH. ÜäaXäúJÞðˆ­«jƒPŽ ¨­•m¬ŒlÏs7šÚUDRGÇq¼°˜!Ûæ—qmi©ÚO{iöû8¦Gš×Ì1ùÈMã•ÈÈÈäg5ZÌ–±Ü´2-¼ŽÑ¤ÅNÆe YAèH¤ŽÛ‡¨«Ú…µZøÙXé÷—‚¸6ööÏ$‚& Uö¤:zÃÔPeiø[[ÿ„kÄÚF¯äý§û>ò¿'~ß3c†ÛœgÎ UÔô»ÝúK-BÒ{ ȱ¾Þæ&ŽDÈeX2?B*µtRkºF™ucáÛ KLÕ,îRâ+‹Ëø®‘JÃ-ÓÁNI#‚0sÁ{âKôë»mJ“K}A;æ’ëÏBÖA*TÓz)ùšGùoûûùÚ½¯hÓxw]Ôt«–î,ndµ•¢$¡db¤© dq(ÐÅš^“i}~.ôgS½³¸´7Ú\¦¡0š'uÁ“÷²† ïçv]¥˜I$„ð·‹4¿dkw7zN«¦ù2D—6—?Ú@GŒ@6åAVW,éR 2$kÂÂ-¬ÿblÿd_ÿcÿÐCìÏö½³ýf6ýï—¯^:Ôº7ƒ‡Ò¨ÐZ~Öÿáñ6‘«ù?iþϼ†ïÉß·ÌØá¶çÆ3ƒTaµšâ9äŠ%HI+"’#]Áw1ì72Œžìz³&ƒ©Ãucm&v—È’ZBÐ0{…s„hÆ2áŒçµ&³6ƒ¨¥ä „$‘Æ€%ñN·ÿ /‰µ}_Éû7ö…ä×~NýÞ^÷-·8Æqœ ̫چƒ©é¶w7ÚuÝ•½ây–Ó\@Ѥë€w! e9£Ö·¯¾x·MЗU¹ðþ¥ ¾ù–U{)•àXÕÉ +…B†'øÒ€,øÇöf¯£ëZމ&§¬éon"”^ù0I;V=ñ„$º¢… ¬«ò!ds¿;q­ùþ°Ò<¿e¼¹»ó·ýï5 ]¸Çò3œó»¶9Ì­=ÂÚω|ïì"ÿUòvù¿b¶y¼¼ç¶ƒŒàã>†€-i:ý’iƒKÖlgÔ4è¦{˜¥ÊÛK®¨¯ó˜ÜadÎQJ•ùƒnÛxÇIÔ´q5ûiç–æóOkk-:ãìÞ\PAq€ï¹TF0ß1È%‰ Ne÷ÃÍgþmwHÒ4ëýwû&òKIf²³wû®Ê‚îÛ»a ØõÅ`ÙéwºŽß²ZOuºhí×ɉŸ2¾v Àû͵°:§(foX_ßÀ—ÚT’èÖ¶ÆÒÖÒ¯.x#ó „¥Hg.ÎX²>c…T6+ñL:ý®›imow½‚2E&£x.î D$€D>HÂü¥ä9ù°2îtNÏWUÆw¨]#2@Ë9fÆÕØF윌 s‘ëRßx[YÒõ;}6÷H¿´Ôn6ù6“Û:K.æÚ»PŒœ@ÀäŒPeiø§[ÿ„—ÄÚ¾¯äý›ûBòk¿'~ï/{–Ûœ ã8ÎZÖ¼¨h·zM„¶wé«_BéóÙI ¨í+ƈªÃ2n ¤ËíꦨM êvúD¬ºuÜZ\îcŠùàaÏʯ¤ü­À?Â}(gTñ6“­}¯P½Ñç›Ä{ÞkŸ·mµy[;¥òDaƒ—À“nÿáÙûºÄÚMü0M¬èóê:¥¼1ÛÇ,WÞD¤h!4b2Í…UBQã%Ttl¹¡màÏ^iU·Ðµ)ô°!¾ŽÎF€*çsonNxÁô¬z謼Ia&im¬iRj§£GbÑÝy»Hc™B“"ov?+Fÿ;ÿsdWž-¹ÔôÍn ÕûEæ«©C©Mu¿:,á†À1ó‚xÀqŽxµ ü4ñ7‰t«KOÑoî,â‡ÎIc´•–ã÷«XŠ©À±$g€Ž{b¨iþ ñ¯uymc¡jW·oåÜÃog$d®%NU†¡ô B×a°µºÓõ Y/´›§ŽY ‚a ¢HÈÝ$*À$u «¸Ýµ–_xŠÛ^]"=;û6×M³6qÆg2³>Yw³>cæó€ «—g¥Þê;~Éi=Ö飷_&&|Êù؃ï6ÖÀêvœt©ntNÏWUÆw¨]#2@Ë9fÆÕØF윌 s‘ë@?ðšÿÅAý§ö?ù„ey^oý8}ÌÎßøÜ{g½UÐüGý™¦I§ïžÏÎÔ­/¾ßjs-¿’³.Qr¹oßn2òƒžr*ë~Ö|5äÿkéúW»Êûm³ÃæcÛ¸ ã#8õ³ ê~º[mWN»Ó.‹ ä •$€À0gØÐm­x“KÓ<9«YZ6…yy«ÂM.‰ks+4r™Ϊ&< UC¼“·ËO %ųi–ð%¦ËÄšG’ëÌ'ÌFT›: ¥\är|̺*µQEQEQEQEQEQEQEQEQEQEQEQEQEQEU?‡ÖuiךEõÕ»ù›e†ÙÝ08 `ò«•Ò~ΚÅÕÏ‚dðݽÌÖ×7+%Õ‹Ã!Cç£6äÈǃ« ¹ÆMTÿ„+Ä_ôÔÿðOþ&½câT[|¶†hÚ)£Ð§GÔ«+ ez^Cã_ø…žËG²×µ8n®ßÌ–Xo$W†9f6T“…ŒEzÇãH~Ø"(D_ʪª0©€x¹Çû£õ_š=¬Ÿýíz?É™_´ü…lì"ŸúI-y*ÿ¯÷Wùšöö_øÃ–×0Çqm7‰ôèå†U ’!\`x ‚A¨hßü'ÿo†µmnþ;;V¢±hYMí3…Ɉ¿?g“ÿ§øåú›ÿà‰æTW©Âðçþƒùné¿üGü!?è7ÿ–î›ÿÈïåM³n9ሪº”*4룖ÿTÿÆ}½zÿü!?è7ÿ–î›ÿÈ›àÿ‡š½Öµ¶©#Ç£¥»]Î|=¥„S1`бÜOÊ ÀÇÌ9ë€ oÛcàÿŠ~$hÕü%o>«¨hsγi1ÊŠ%†d]Ó(rɉ@PrVY1“…>1û|ñÈø¹aãGÕ|/¡é\—PŒÚÍy3¡„Böî‚0®ÒnerGÜ‘ô/ü!?è7ÿ–î›ÿÈÂðçþƒùné¿üWVj¸èãåέ×M6èz¸lç4ÂäU8zUì&ÛøuWÝ/zÚù¦û3–ø­ÿ%7ÄõÖý&†½ Zø‹eâ?é«<G­í»¾T±y7ím±÷a™ä½œ0G’ÙÆÿ„'áÏýÿòÝÓù±uí+áæ“¨hz}µôšŽ¡«ßÃc ) éq…"«HÌÖ†$’,IûIÊ}ÝÏ”=8òHÉð½Ô6ú‹ã–hâyô¸ã‰]€27Ûm[jŽçj±Àì¤ö«Ú÷‰î`ðׂ­,5+ìvmpâÕÂÉÀ½º(Y—æÜªÁ”ò‰ \o$×òl?è à’ÓÿQäØÐ@ÿÁ%§ÿ¬ÍN›Æo‹µ?Øi7Ö ?ü$w÷ò<÷±[Åy²¬.²»*>Â%À-'Ê …e¿¹K­röÂÊkö`ÒwA¨_5¬I ’GæÇ)xNP´ŠQœ7ï9BT”å<›úèø$´ÿãTy6ôÐ?ðIiÿƨÚZØ_ÙÛYÝÉ4Q[öW½ŽôY“#Ÿ)gŒä>fP ¥O̬OO«ÞZéÿõ½í¡Óµ[B{ Ë{˜æ{v•dû<î‘“$%HäåC®Ó…,¸®{ɰÿ ÿ‚KOþ5G“aÿ@ÿ–Ÿüj€$Õ ð|º=íÅ¥Õü×ñ]Û%ÔWioŽE”—™TÈL?(9>@,î³ñKÆ7úß|Gz´—I¿ºKx­åű„Ï¿åUùHbˆäó0 Inj—“aÿ@ÿ–Ÿüj&Ãþ€:þ -?øÕzGˆã™• ÂEu~#Ó/4;Y‚òò-^æò{ÝFá,¿´¢eE†bÓ0”‰Ž×mÃíhlÈW7ɰÿ ÿ‚KOþ5[^ ð>ƒâM'_Õõsg¥ÛX_‹U[- M(ÃCZ;ZSßÒ€áËø­!×´[³¤ëšµÇØãŽ]FúHíšQ·Û‹…–1òŸ'¿”ßgùKì/ÞÉ=Þ›jðé6«cgöt¶Ñîâ(–I0ei$ÄÈ[*ì`8!”uð„ü9ÿ ßþ[ºoÿ QÿOßú ÿ廦ÿòqÿø‡â‹›i£¸·›Tº’)¢`ÈêfbHà‚A{^“IÕ[¢ H·8ù@S‘V¯ïa¿×/lôÙ4]oKk $ý—Z»BVŠÉ#oY‘UÓs£Gæžd?+l,–uO†¾Ño¥³¼Õü›˜ñ½?áÓŽE‰ª¿ð„ü9ÿ ßþ[ºoÿ Pã{K[ û;k;¹&Š+`>Ê÷±Þ‹2dså,ñ€çÌÊ”©ù•‰¡â™.fñ6¯%íìãÞLÓ^Z°1NåÎé€V9# À®ÿþŸ‡?ôÿËwMÿä ?á øsÿA¿ü·tßþ@ -®ë⇇§“Åž'Öá¼Òn´éõ+‹ˆšÛWµšGG˜•"4¹áÆÜœã´ô¿ü<Õ¼=c­GªIŸ|ó­´’ø{KÌ¢) lØ$€HÈÎÈ KÿOßú ÿ廦ÿòZñˆ-î¯5{JÒü/kcumq µÜšŒßlŠ !hV/²ý •på"òÔ€W€Õƒâ±Ô¼yàÝBïPþÇþÍûm&[iLˆ‘*HÓ¡Ú#¸Íû2JÛ_¤‹þŸ‡?ôÿËwMÿä ?á øsÿA¿ü·tßþ@  +T}kFðëiz­¦ú29ºk‹Åµx§3¼‚é;¤>_”¹ˆ4Ÿ¸oîç|S}eªx›W½Ómþɧ\^M5µ¾ÅO*&rQv¯ÀÇÝi¾øy«ÝkQ[j’@,îɰÿ ÿ‚KOþ5G“aÿ@ÿ–Ÿüj€9z+¨òl?è à’ÓÿQäØÐ@ÿÁ%§ÿ ^Šê<›úèø$´ÿãTy6ôÐ?ðIiÿƨ—¢º&Ãþ€:þ -?øÕM‡ýtüZñªå讣ɰÿ ÿ‚KOþ5G“aÿ@ÿ–Ÿüj€9z+¨òl?è à’ÓÿQäØÐ@ÿÁ%§ÿ ^Šê<›úèø$´ÿãTy6ôÐ?ðIiÿƨ—¢º&Ãþ€:þ -?øÕM‡ýtüZñªå讣ɰÿ ÿ‚KOþ5G“aÿ@ÿ–Ÿüj€9z+¨òl?è à’ÓÿQäØÐ@ÿÁ%§ÿ ^Šê<›úèø$´ÿãTy6ôÐ?ðIiÿƨ—¢º&Ãþ€:þ -?øÕM‡ýtüZñªåè¯MѾøOþß jÚÝüvw:­„7EbÐ4²›Ú4g “~2:—þŸ‡?ôÿËwMÿä òÚ+Ô¿á øsÿA¿ü·tßþ@£þŸ‡?ôÿËwMÿä òÚ+Ô¿á øsÿA¿ü·tßþ@£þŸ‡?ôÿËwMÿä òÚ+Ô¿á øsÿA¿ü·tßþ@£þŸ‡?ôÿËwMÿä òÚÓøOð߯ á= VÓô¹#çí6ÒJñ¡ÿXYkpx##y»ÿøB~ÿÐoÿ-Ý7ÿ+V°ðŸ‰4ÝK›û[Rº†â䬚™1G2H7ÿ¡)mÍÜ)ŽFà ó|ñÆ­â{^¾Ññqw+C¼ü˜7’ˆáë“ëÁ<æ½'âœÚwÁÈ­.˸ƒDž) íe·PFG‘Ú¼Ïɰÿ ÿ‚KOþ5] ÂÂ~]O¥›ÌšÏ˜¶V±Û£‘ãRV5UÎÈÑsŒ£5âçîÕ~hö²÷µèÿ&l|tÿ‘ëÁßö5iŸÊ³õ¿ù%ÿ ?ì þˆ‚­|c°ŠÏÇ~’æûT¿š_éÞLrËn°BK†*À€MÈ|ò $ŽjëòKþØýNP­Fzý§ú6w« >Ê8m_Óü/£Ýjš¥ÒÙØ[.é%`ORª¨³1!UTÄ€$ ãÇÆ;[[«£¬x_Å>ÑíÜ#kš¾’ñYÒC#ZÙÎé–0¸Ãtø³ÿpŸýš±|¦j:/ƒt?W»û~­iaooyuæ4žtˬ½€fËrFNrkká÷O‹?÷ ÿÙ«Í4|9¡7‰oî­ÅÍÍ”vÑ$=¾s¨òå‚®ØGËŽrÌ: ä®ìÿ î|¼iúþ§zÌ«¤¾¾²YI `Ï&R>½_ ýæQ–§ìÑÿž2ÿ®zoó¼¯Í¯ˆ'ñߎµ}âµo®Ç«hZ¤Ð^_GzÀøjá‹Z[·˜%‡Â>A±¥+æ+7Êâ1Ùc¥GäÔRvI>¾—¶š»úU”eT3M×ÄS¢¢¾*’åM¶£®í·ÚÉ]¿?¸5ÿ‡þ+ð®—&¥«hÙØFñÇ$ÿm´“iwT_•&f?3(àógþJ‡Ã_û Ãÿ£à¯bð¯‹|Aã¯ØŸÃ:çŠ"‘5›¨,|ÉemÏußFܱèLÑ,sqûÞ8¯Öä¨|5ÿ°Ì?ú> ô²ÌlñÔêJ¤Rq“ŽžVÿ3ÀÄÐú¼ù/s©¢Š+Ø9Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ºŸÿÉ.ñÏý†cÿÑuËWSàÿù%Þ9ÿ°Ìú"΀<¯ÄÚ®²ž%Óô½&á-üë&Ÿbi+¨\\Îú–›§ÛÁ=í¤iº]IK;Ê \¯ü,vÿ¢ƒáŸÏÃü××gÿ5‹Â÷ ÿÔ¿Âõèší5ª|ø;ð7F·Ö|9ceqð×F»û>¨t•¸35¡Dpךõƒùa‘ QÚàJ‘Š|<ø½eâbo jº¦ŠÞ$tÐ7TÓî"¾¥ŸÊhÖÒöè,¢(CK‘Š%J±ôŸÉrðýÄ?ô™«³øóã;ÿøáäÚŸ‰ü;â«ûˆÓXM?†­’ÞgMQ-¨·×˜•KÙ‘NAAÍÆxCþK—€?î!ÿ¤Í@y7Äo‘x?Z»Ñ´õÍJÉ]´÷"ÒÚÈ&ý®ìû^&ÀM˜¾¯Y¯—àø+­kß“"þÃ…z•ø†¤¡‡§/wvî’[>·mldøUñwNø¥kz°Z\iº¦ž"ûeœä8]á¶¼r/…’@ ß&Y#:¿äGÔ¿í—þJðïÙsÁšxëÄž$º22À]èv—Okä ò.†ùK±P¢Ú<ಖ•”6ca^ãñ;þD}KþÙèÔ­)*ª<µÕ¦®Ÿªv<ìÉ`V*O-›g÷³IÙù«Ûäz—Åùu?ûeÿ¢’¼ëĚΣ§ßh:~“gcw«ÞKkö•ä–°F#´¸ºfgŽ›%mŠ€« 2kÑ~(Èó©ÿÛ/ý•æzÿü?¿ì/yÿ¦mJ»ð´ãZ½:RÚM/½ž.¬¨aêUŽñ‹kä®T²ñN¹mã«? kzv·zmÆ£ÚN©=ÖѰFUÖ[Xq»ÏÈ ·Ü9"ºêá5Ÿù8=þÅ}CÿJì«»®üã OŽ©‡¥ð«oçÿSÍÈñµs ¾ž&µ¹¥Í¶ÚI¯É„¿ä†øþâúRÕçþ(ø·§x#ƶzgˆ.mt}2û÷6÷Wò-¸óo)”Hϱâ!LL>WŽAU–â6_@ð—üßÜCÿJZ¸ÏˆxqµÏIâýF] ÃK­ÉÞ»ÊÚL“i×°[]‰v°ã¹šÝ’vb“ËrFܵOeNU-{&íÞÇ¿ÌÒ4ü?ñ ¾,½{=ÄÚ>³v‘™Z >þ)äTÅQ‰,£>ãÖº öÿг^‘ñ/ῇ´ µ­NøbÞ5Ð|kpâãTµ¸HÖ34®@‰B9¸ñï‡.®o!µû^Ÿq¥Í}¦HeÓµö5Í”§™-Ü‚UˆìËÎÜŸ+Í©f‘—*´£ºßNŽúèJƒWÙŸÃîŸîÿ³T·ZÛ<±[KxëŒC @íÏmì£ß’:Tÿº|Yÿ¸OþÍE{]Xäjê×8ÿ üDĺ͆‹Ç+ØÜ\ß«I—ÓåŽXãH¥P82˜©m¤ˆó¶ÖƒñIñü}«Jº›Ç$³XH Mhˆû L>^[A;›’ å|ÃöAø¯üSø‰¯xsSø¢öWZcK}¬iÚ3ØG{%Û]^ÛOp­%£™£Col<©v¥ä$:ùQ¤ž“gáÍGàçŽ/üâÅ–oëwwz¼:Ü0²Xêñ† †]Ìm O9Bƒ%Ä‘É/ t!a*T´ÒWVÞöÛ§ËÌŸgR”#R¤¯¶Ýè“ò×eçc¬ð‡ü—/ÜCÿIšŠ'¦zµwml®Ï¡~'È©Û/ý•ê_?äyÔÿí—þŠJòˆ7¶ú—ë»Ë;ˆ®­.#†XgÃÇ"4ˆU•‡AuÍzÇÅùu?ûeÿ¢’¾„ùSðõŸŒvçÊm»ãâ/¿h?x³áŸ,ô¿†^;ñEߎ<;{¥Ùj×:ÅìZk¥úY®•Ω{ ºªÞÌvNÑo€È­r¶¹Î¤)ürKÔ¸ÂSøUÏ@®[áü’øì3yÿ¢-+[Âþ ·ñg†trÍ%ŽÓS´†öœ"¤ˆCH 3‚~¦²~ÿÉ/‡þÃ7Ÿú"Ò´ êh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šêu¿ù%ÿ ?ì þˆ‚¹jêu¿ù%ÿ ?ì þˆ‚¹j¹¥hšŽ½pÖúe…Ö£:¡‘¢´…¥`¹q ÆH÷vx†ÚòÚÒmSŠêëw‘Ùȯ.Ñ–Ø¥rØœt®¯Ä_ñ$ø9áìÑ—[–òmD§[¦†P±=v¨' ÷sÎ3ÍIû?\Ìß¼;nÒ¹êDˆ±Ú¬Öî€è  žûG¥y½Ûèz›¦|9»ñUõŠj󾤺U½œòI1/Íi[Ëeg$ ¡r d“»€:m?Â^šk×â&Û[°º[}:æi¢ßDë—”"ÄÅ‹[åÛ÷Èâ€<ŠŠõ …—:·ÄEÔtû]MÔ‘Þ­"Wž ¨‘]Ì‘¼’?, u<RWžkøÃÚÏ„õmAmôŸjVWÖ––Ò_È]‚”eó\‡†Þ0'åÈóz嬿ä¸éö½ÿÒkªêk–²ÿ’ã¤Ø÷ÿI®¨©®†_ù7‰Ü×?ô¢jç«¡6öòü†[©õ¶„ëm%½ŒÐÅç¯Úe%Y¤†B2\c'¯ñ³u|#MÛUù£ÙÊ]±I¥}äÍŽŸò=x;þÆ­3ùV~·ÿ$¿á§ý¡ÿÑV‡ÇOù¼ÿcV™ü«Œñg‰uøAþéú/„5½y­t;fžæÚÎ_!KÁUWÁÎN8$ä ²àÔÿ¿BóãCü!®{Hðž›âÝQtË y䢊æ(£3„y^YWzÄ„+ÈÞaR[çf$“ɯý³ãoú&ºÿþOÿÆhþÙñ·ý]ÿ§ÿã5ôQ¨ãEuò󾞕59FNþµ]~gSGÃîŸîÿ³W-ý³ãoú&ºÿþOÿÆkC—þ%Ñto\\xÄgPÖŸO[[4Ó§#oó¤òðvÉ,1’35;_øë[ðÆ¥&Žtö]A`Y–úÙå#Ê2í*VDÆ|æÎsÐWÎ:×¼KàOxÛŠž(ñ‰md”hºÀðÛ\Gr’ZA i$Š*Y完’HÝÝšFff5é?Û>6ÿ¢k¯ÿà4ÿüfíŸÑ5×ÿðþ3]X D²ìD±Tç’³zíòknžg˜`ift»|©§¥ºz§¾ÏÈé¼-¨k¾øI¦ü;}R=SF±(#»½·cwå­Çž‘†Wª&4UŒ*Fª s:Ïü•†¿ö‡ÿGÁGöÏ¿èšëÿø ?ÿ¨ôÍ3Åþ#øà‹›Ÿkz]µ†­’Í-œÅ Ñ’ÌL`(I$ןJ:<ÞÍ[™¶üÛÝž“m¤ŸM¶Š(­„QEQEQEQEQEQEQEQEQEQEQEQEQEQEÔø?þIwŽì3þˆ³®Z´,5ë½'á—Ší´ýS×õ ÝqV+}:ÖIB…¶´fiT„É<  ˆñFƒªI¯ø{ÄšÇüM4[ÛIÎ<ë ®£Z•óÁ,žL¯_O„«Æs¹K)é<ñ?Ãmðÿá½ÇŽ6ÿ¢k¯ÿà4ÿüf€76ÿ¢k¯ÿà4ÿüf´<â[o‰~×µOxŽÆÇJKÆq<Ï!{vUUXä¶Ð3ÇÍÉ@5ÉÈ–¾ñ6±â›½2ÿ[[ûFµ[¨îîãLSä3E ¢9¢•­bË$FD‘˜¹xßu³ÿ¶|mÿD×_ÿÀiÿøÍÛ>6ÿ¢k¯ÿà4ÿüfºp؉ákF¼7‹¾§.+ e áê^ÒVvÜËøUàk ¦¯9º°½ÁºM ï^æ83É!³2‰]¥fÇ„ÎÐ7m2>§Äïùõ/ûeÿ£RíŸÑ5×ÿðþ3Y~'_xC¹Ó¿á]ëöþvßÞ}ŽvÆ7O(zzÖujJµIT–íß·àiFŒpô£JEY]ßo6{7Åùu?ûeÿ¢’¼ÖûFMÅ‘xÇOѬ5MjSc*ÜZA%Ë[("ÖiF`˜ æÆ@å$*|¹ Üøâ¿êÞ5Õ.t¯‡¾#¼ÓÙÕa¸–ÆxŒ¡QT¶Ó  çÈÍÿløÛþ‰®¿ÿ€Óÿñš)T•ªÝj:´£^œ©Of¬Ìÿ Ú|\ñn•¯_èÿfÑ´üÝ6kë&‚úîuua&Ùe‚tR…yr@Œb_G®[ûgÆßôMuÿüŸÿŒÑý³ãoú&ºÿþOÿÆk§Œ«¬ëÖz¿»ÐãÀ`(å´‚÷W}ÛîΧÂ_òC|ÿqý)j‚öÊßR²¸³¼·ŠêÒâ6Šh'@ñÈŒ0ÊÊx ‚A®k6ÞÿĺÃOè6Þñýõ‚]µÙ:tñ$fK†dPLgqÛ‚qÀÜ9' gÿløÛþ‰®¿ÿ€Óÿñšá='þ¿Â)ÿ »þø³}~Ë™¶~ËŒd}«wüxÿµþ·ËýÎíœ×qeeo¦Ù[ÙÙÛÅkioÅ  HãEUUÓÎÿløÛþ‰®¿ÿ€Óÿñš?¶|mÿD×_ÿÀiÿøÍaJ…*7öqJîîÝ_r¥'-ÙÔü>éñgþá?û5yïÆo ø³ÄúF—oá]^};7±Å¨G þAkg82‡]²n‰¶I±%z ’YEu>¿ñ.‹£xòâãÀž#:†´úzÚÙ¦9‹˜Í'—€¶I`1Œ‘Ÿý³ãoú&ºÿþOÿÆkf®¬ÄÑ™àÏ‚žøyö{¿Ú¶—âfY`ñ[N£ ªŠ’FRJ¨¢¥ÆQ™ËéÞ#ñ·Ž›ÆßõK=sÄ«%¦k§@ðiÚE©á¼.îÂi€ ,ŒÌ܈ն Ì?Û>6ÿ¢k¯ÿà4ÿüfíŸÑ5×ÿðþ3Xû N¢«Ê¹’²vÕ"¹äÓWÜê|!ÿ%ËÀ÷ÿÒf®WâŸâ OJÓâÐ-tköMFÞ{ÛvIÚîÚ6óÝö#îIR9”‡‰å^74|â[o‰~×µOxŽÆÇJKÆq<Ï!{vUUXä¶Ð3ÇÍÉYÿÛ>6ÿ¢k¯ÿà4ÿüf¶jêÄ´7ˆ>5|{ð†™¬è¾ t­Eux²u£<Ò,3DcÄÑ;’yË Ý´–À üŸ¼{âZM"ÓÂú•¥ê’O¨Û´ÁK™›ä‘A9ýÑrÀ¡‡5õïöÏ¿èšëÿø ?ÿ£ûgÆßôMuÿüŸÿŒ×в|Zä­æßçsí2¾/Ír|-\K’nú­’º³ZÙ-îfx›ÃöþøC‡fòÉi¦ZZÙBódd£E,@œ(Îú ö_Šò<êöËÿE%xÏ‰×ÆÞ#ÐîtïøWzý¿·÷Ÿc±† ÓÊžµÜ|Fñ_‰uoê—:WÃßÞiìê°ÜKc=Ôü7w >ÚÐÄæÊܳ.mÙ°e*w)+•¾xð}æ­á?èž½øOâ[™llaÒ®nà´ÑdÉŒE+©hYXí{Â71 öq¼â[â¾Óý³ãoú&ºÿþOÿÆhþÙñ·ý]ÿ§ÿã5Í_O’©ÐÞ•iÑmÀ«ðgÂSøáW…´+¸ü›Û;–æ-±.f¤_ݧÌ7r[ff%¯„?òKáÿ°Íçþˆ´£ûgÆßôMuÿüŸÿŒÖ‡Ã¿êžøsmm«i·š]Ëê×r,7°<.PÃjÀdŸc]&ÍQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@N·ÿ$¿á§ý¡ÿÑW-Sx³ÄºÇü ÿtýÂÞ¼Öº³Osmg/¥àˆª«„`ç' ’r!ý³ãoú&ºÿþOÿÆhÑ´?\èÚ]Þ—-­®«¤ÜºÊÖ7ÁÌi*ô• 2²>2¤« ƒƒž1wEøƒ?†üG§kV‘¦XIcæ·D•ÑÙУgÈx#~ÑŒ€ lùgöÏ¿èšëÿø ?ÿ£ûgÆßôMuÿüŸÿŒÐ£h~0¹Ñ´»½.[[]WI¹u•¬oƒ˜ÒUé*ed|eIV6ÿ¢k¯ÿà4ÿüfíŸÑ5×ÿðþ3@MrÖ_ò\tû^ÿé5ÕÛ>6ÿ¢k¯ÿà4ÿüf—ÂzGŠ5?‰öZΣá_E³·Ó/a’[«IDkþ‹q‚]‘@Ép>¸õ ¢ºäÞ%ÿs\ÿÒ‰«ž®†_ù7‰Ü×?ô¢jñs÷Gê¿4{Y?ûÚô“-üTøàXþ!,Z¦©×:.¡ÚÃJè.#3F9ØÇ%AûˆèTàÿÂÓøCÿ@ àÿøŠðoùÂïùÿ¡Ž½/Ä¿ò>þߟö)iŸúa¹¬#•NýyE7}<ÍåšBvö”"ÚIjußð´þÿÐÂßø þ"‹‰Ÿ ®/fLJ¼"¶PÙI3»è…\Ëç@ˆŠ 岯)!A?&xçã¿Û÷þM¯öGÿ±I¿ôL¯Ký•æÅÿîzÿÚբ˫¯ùˆ‘›Ì(½>¯Þáiü!ÿ …¿ð@ÿüEð´þÿÐÂßø þ"·¾<ÉèþË÷4ÿéº:ó?Û÷þNSöGÿ±µ¿ô³L¥ý›_þ‚dWö…ú‰×ÂÓøCÿ@ àÿøŠ?áiü!ÿ …¿ð@ÿüE{Oí;ÿ&×ñgþÅ-[ÿHå¯Í/ÚþD-+þÍßÃú~°£û6¿ýÈaEÌKÿ…§ð‡þ€ÿÁÿñÂÓøCÿ@ àÿøŠúÒŠ?³kÿÐLƒëôè'Éð´þÿÐÂßø þ"øZèáoü?ÿ_ZQGömú }~ýÄù/þŸÂúx[ÿÿÄQÿ Oáý<-ÿ‚ÿâ+ëJ(þͯÿA2¯Ñÿ xŸ%ÿÂÓøCÿ@ àÿøŠ?áiü!ÿ …¿ð@ÿüE}iEÙµÿè&Aõú?ôä¿øZèáoü?ÿGü-?„?ôð·þÿˆ®¿ö¯ÿ‘zïþ¼/?ôRÖ·ìóÿ"…ÏýÃÿôÑaGömú ‘Ú4è'ÂÓøCÿ@ àÿøŠ?áiü!ÿ …¿ð@ÿüE}/EÙµÿè&Aý£Gþ¢|Ñÿ Oáý<-ÿ‚ÿâ(ÿ…§ð‡þ€ÿÁÿñô½f×ÿ ™öú‰óGü-?„?ôð·þÿˆ£þŸÂúx[ÿÿÄWÒôQý›_þ‚dÚ4è'Íð´þÿÐÂßø þ"øZèáoü?ÿ^ÝñCþDmOþÙèÔ¯›&ÿ‘¶Óþ¼fÿÑ‘VsÀW…¿Ú%«HÒê3¿ûHu¤ð÷„VÒ³$û‰ßÏ2|›wQ\€_ò(ÿ…§ð‡þ€ÿÁÿñôçÀ¯ùøþÁz¿þ–Á^wà?ù:Ÿû j_ú ôÞ]]ÿÌD„³ +þaây?ü-?„?ôð·þÿˆªþ2øÕà­OÀ·ú.—5•„Kes­…„°Ç¾E<·hËsÛ’I®ûÁ?òH~%Ü3ÿJ¼î³žUR¢å©^MvfÍiÓ|СüÿÙtango-9.2.5a/pogo/templates/html/TPG_CvsModule.html0000644023471100065110000001067213034744726017155 00000000000000 Tango Programer's Guide
EUROPEAN SYNCHROTRON RADIATION FACILITY
INSTALLATION EUROPEENNE DE RAYONNEMENT SYNCHROTRON

TANGO Programmer's Guide


Create a CVS Module:
    (To create a new module   my_module for MyDServer  class in MyDsFamily.)
  • Module creation:
    1. export the CVSROOT   environment variable.
    2. cd   {anywhere}
    3. cvs checkout  CVSROOT/modules
    4. cd  CVSROOT
    5. nedit  modules
    6.    #-----> add your module with editor   (see for specific repository)
    7. cvs commit -m "module  my_module   added"
    8. cd ..
    9. cvs  release  -d  CVSROOT
    10. cd   ../../my_module
    11. cvs import -m "Initial Revision" ../../ my_module    vendortag   releasetag
    12. cd  ..
    13. mv   my_module   my_module.org
    14. cvs  co   my_module
    15. cd  my_module

  • On Tango DS repository:
    • This repository is located at (CVSROOT=my_loggin@cvs.sourceforge.net:/cvsroot/tango-ds)
      Inside the edited modules file, search the line:
      • #    MyDsFamily
      And add the following line:
      • my_module        MyDsFamily/../../my_module

      Where MyDsFamily could be:
      • Acquisition
      • Application
      • Beamdiag
      • Calculation
      • Communication
      • Inputoutput
      • Instrumentation
      • Motion
      • Process
      • Miscellaneous
      • Radiation protection
      • Vacuum

  • On ESRF repository:
    • This repository is located at (CVSROOT=/segfs/tango/cvsroot)
      Inside the edited modules file, add the following lines:
      • #M    my_module     MyDsFamily :   This class is able to bla bla bla....
      • my_module       cppserver/../../my_module

      Where MyDsFamily could be:
      • Archiving
      • Beamlines
      • Input/Output
      • Linac
      • Measures
      • Motion
      • Power Supply
      • Protocols
      • TACO Interfaces
      • Vacuum


tango-9.2.5a/pogo/templates/html/TPG_CvsTags.html0000644023471100065110000000631613034744726016626 00000000000000 Tango Programer's Guide
EUROPEAN SYNCHROTRON RADIATION FACILITY
INSTALLATION EUROPEENNE DE RAYONNEMENT SYNCHROTRON

TANGO Programmer's Guide



CVS Tag Management:
  • Tag a Device Server:
    1. First time, don't forget to commit your source files (cvs commit -m..., tkcvs, ...).
    2. Then increase the release number in Makefile.
        The line to be modified looks like:
          RELEASE = Release_1_3
        Change it to:
          RELEASE = Release_1_4
               or
          RELEASE = Release_2_0
    3. Then type:
        linuxmake tag
            or
        solmake tag.

        This command needs /segfs/tango/bin/cvstag script using Pogo java classes. It will make a CVS tag on the current module. It will patch the MyDServerClass.cpp file like:
          static const char *TagName = "$Name$";
        And then it will re-build the executable file.
    4. And finally you can install the device serer.


  • See last Tags of a Device Server:
    • Type    make show_tag to display the last tag used for this module.


  • CVS tag goal:
    • The goal of the CVS tag usage is to know which version is running. There is 2 ways to know it.
      1. The server is running.
        Use the command info on a device proxy or
        with Device Panel, on tab admin click on Device Info.
      2. The server is NOT running.
        Use the shell command :
        ident {dserver filename} |grep Name It will display:
          $Name$
tango-9.2.5a/pogo/templates/html/TPG_NamingConventions.html0000644023471100065110000000520513034744726020707 00000000000000 Tango Programer's Guide
EUROPEAN SYNCHROTRON RADIATION FACILITY
INSTALLATION EUROPEENNE DE RAYONNEMENT SYNCHROTRON

TANGO Programmer's Guide



Tango Naming Conventions:
    Commands and Attributes:
      Between clients and servers, they are case unsensitive.
      But by convention it is recommended to build it by appending all words
      starting with capital letter.
      (i.e. ReadValues,  StartCounter, .......)

      Commands will be executed in a method where words will be splited by underscore char.
      (i.e. read_values,  start_counter, .......)
      Attributes will be read or write in a method where attribute name is preceded by read or write key.
      (i.e. read_Counter,  write_CounterLimits, .......)
        NOTE: the method read_attr_hardware(vector &attr_list) will be called before the above method.

    Class and Device Properties:
      They are case sensitive:
      By convention it is recommended to build it by appending all words
      starting with capital letter.
      (i.e. DefaultValue,  ReadDeviceName, .......)


tango-9.2.5a/pogo/templates/java/0000755023471100065110000000000013034745266013703 500000000000000tango-9.2.5a/pogo/templates/java/DevServClass.java0000644023471100065110000001100613034744725017027 00000000000000//+====================================================================== // $Source$ // // Project: Tango Device Server // // Description: java source code for the TemplateDevServ class . // This class is a singleton class and implements everything // which exists only once for all the TemplateDevServ object // It inherits from the DeviceClass class. // // $Author: pascal_verdier $ // // $Revision: 9951 $ // // $Log$ // Revision 3.1 2004/09/06 09:29:17 pascal_verdier // *** empty log message *** // // // copyleft : European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // //-====================================================================== // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= package TemplateDevServ; import java.util.*; import org.omg.CORBA.*; import fr.esrf.Tango.*; import fr.esrf.TangoDs.*; import fr.esrf.TangoApi.*; public class TemplateDevServClass extends DeviceClass implements TangoConst { /** * TemplateDevServClass class instance (it is a singleton). */ private static TemplateDevServClass _instance = null; /** * Class properties array. */ private DbDatum[] cl_prop = null; //--------- Start of properties data members ---------- //--------- End of properties data members ---------- //=================================================================== // // method : instance() // // description : static method to retrieve the TemplateDevServClass object // once it has been initialised // //=================================================================== public static TemplateDevServClass instance() { if (_instance == null) { System.err.println("TemplateDevServClass is not initialised !!!"); System.err.println("Exiting"); System.exit(-1); } return _instance; } //=================================================================== // // method : Init() // // description : static method to create/retrieve the TemplateDevServClass // object. This method is the only one which enables a // user to create the object // // in : - class_name : The class name // //=================================================================== public static TemplateDevServClass init(String class_name) throws DevFailed { if (_instance == null) { _instance = new TemplateDevServClass(class_name); } return _instance; } //=================================================================== // // method : TemplateDevServClass() // // description : constructor for the TemplateDevServClass class // // argument : in : - name : The class name // //=================================================================== protected TemplateDevServClass(String name) throws DevFailed { super(name); Util.out2.println("Entering TemplateDevServClass constructor"); Util.out2.println("Leaving TemplateDevServClass constructor"); } //=================================================================== // // method : command_factory() // // description : Create the command object(s) and store them in the // command list //=================================================================== public void command_factory() { Util.out2.println("Entering TemplateDevServClass command_factory"); command_list.addElement(new DevReadTimeCmd(new String("DevReadTime"), Tango_ARGIN_TYPE, Tango_ARGOUT_TYPE)); } //=================================================================== // // method : device_factory() // // description : Create the device object(s) and store them in the // device list // // argument : in : String[] devlist : The device name list // //=================================================================== public void device_factory(String[] devlist) throws DevFailed { for (int i=0 ; i Received a DevFailed exception:',e except Exception,e: print '-------> An unforeseen exception occured....',e tango-9.2.5a/pogo/templates/txt/0000755023471100065110000000000013034745266013601 500000000000000tango-9.2.5a/pogo/templates/txt/Shortcuts.txt0000644023471100065110000000260113034744725016256 00000000000000POGO Shortcuts Help: ------------------- Edit an item: A double click on left button on an item, will start a dialog to edit this item. Create a new item: A double click on left button on a collection(commands, states, ..), will start a dialog to create a new item of this collection. You can use right click on an item to popup a menu to: - Edit item. - Edit source code. - Clone item. - Delete item. - Move item up or down You can use right click on a collection to popup a menu to: - Create a new item (attribute, property, command,....) - Sort items in the collection. - Edit comments for all items in the collection. Edit source code (available only on unix like machine): - On a command item, will fork an editor and set the cursor to the command execution method. - On an attribute item, will fork an editor and set the cursor to the read attribute method. - On a device property will fork an editor and set the cursor to the get_device_property() method. - On a class property will fork an editor and set the cursor to the get_class_property() method. - On a state will fork an editor on state mechine file and set the cursor to the "how to" comments . The default editor used is nedit. You can change it with shell command: export POGO_EDITOR=vi or setenv POGO_EDITOR vi tango-9.2.5a/pogo/templates/txt/WhatIsNew.txt0000644023471100065110000000050613034744725016133 00000000000000Since revision 5.0.0: - The device server can be generated in python. - In ServerClass.h: class declarations can be added just after namespace. - In ServerClass.cpp: a user code part has been added at the end of attribute_factory method. see: http://www.esrf.fr/tango/tango_doc/tools_doc/pogo_doc/ tango-9.2.5a/pogo/templates/Makefile.am0000644023471100065110000000351213034744726014737 00000000000000cpp_templatedir = $(datadir)/pogo/templates/cpp html_templatedir = $(datadir)/pogo/templates/html java_templatedir = $(datadir)/pogo/templates/java python_templatedir = $(datadir)/pogo/templates/python txt_templatedir = $(datadir)/pogo/templates/txt dist_cpp_template_DATA = cpp/Allowed.cpp \ cpp/ClassFactory.cpp \ cpp/DevServClass.cpp \ cpp/DevServClass.h \ cpp/DevServ.cpp \ cpp/DevServ.dsp \ cpp/DevServ.h \ cpp/MachineState.cpp \ cpp/main.cpp \ cpp/Makefile \ cpp/ReadHardwareAttr.cpp \ cpp/README \ cpp/readPropMethodName.cpp \ cpp/ReadWriteAttr.cpp \ cpp/set_default_property.cpp \ cpp/state.cpp \ cpp/write_property.cpp \ cpp/vc8_project/Class_dll.vcproj \ cpp/vc8_project/Class_lib.vcproj \ cpp/vc8_project/DevServ.sln \ cpp/vc8_project/Server_shared.vcproj \ cpp/vc8_project/Server_static.vcproj EXTRA_DIST = cpp/Makefile.in dist_html_template_DATA = html/Doxyfile \ html/footer.html \ html/frame.html \ html/header.html \ html/HowIsGenerated.html \ html/index.html \ html/Inheritance.html \ html/page.html \ html/SearchItem.html \ html/ServersList.html \ html/TangoProgrammerGuide.html \ html/tkcvs_browser.jpg \ html/TPG_CvsModule.html \ html/TPG_CvsTags.html \ html/TPG_NamingConventions.html dist_java_template_DATA = java/DevServClass.java \ java/DevServCmd.java \ java/DevServ.java \ java/Makefile \ java/README \ java/readPropMethodName.java \ java/ReadWriteAttr.java \ java/states.java \ java/TangoclassProxy.java \ java/write_property.java dist_python_template_DATA = python/Attribute.py \ python/Command.py \ python/DevServ.py dist_txt_template_DATA = txt/Shortcuts.txt \ txt/WhatIsNew.txt tango-9.2.5a/pogo/templates/Makefile.in0000644023471100065110000005363313034745123014751 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pogo/templates DIST_COMMON = $(dist_cpp_template_DATA) $(dist_html_template_DATA) \ $(dist_java_template_DATA) $(dist_python_template_DATA) \ $(dist_txt_template_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(cpp_templatedir)" \ "$(DESTDIR)$(html_templatedir)" \ "$(DESTDIR)$(java_templatedir)" \ "$(DESTDIR)$(python_templatedir)" \ "$(DESTDIR)$(txt_templatedir)" DATA = $(dist_cpp_template_DATA) $(dist_html_template_DATA) \ $(dist_java_template_DATA) $(dist_python_template_DATA) \ $(dist_txt_template_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ cpp_templatedir = $(datadir)/pogo/templates/cpp html_templatedir = $(datadir)/pogo/templates/html java_templatedir = $(datadir)/pogo/templates/java python_templatedir = $(datadir)/pogo/templates/python txt_templatedir = $(datadir)/pogo/templates/txt dist_cpp_template_DATA = cpp/Allowed.cpp \ cpp/ClassFactory.cpp \ cpp/DevServClass.cpp \ cpp/DevServClass.h \ cpp/DevServ.cpp \ cpp/DevServ.dsp \ cpp/DevServ.h \ cpp/MachineState.cpp \ cpp/main.cpp \ cpp/Makefile \ cpp/ReadHardwareAttr.cpp \ cpp/README \ cpp/readPropMethodName.cpp \ cpp/ReadWriteAttr.cpp \ cpp/set_default_property.cpp \ cpp/state.cpp \ cpp/write_property.cpp \ cpp/vc8_project/Class_dll.vcproj \ cpp/vc8_project/Class_lib.vcproj \ cpp/vc8_project/DevServ.sln \ cpp/vc8_project/Server_shared.vcproj \ cpp/vc8_project/Server_static.vcproj EXTRA_DIST = cpp/Makefile.in dist_html_template_DATA = html/Doxyfile \ html/footer.html \ html/frame.html \ html/header.html \ html/HowIsGenerated.html \ html/index.html \ html/Inheritance.html \ html/page.html \ html/SearchItem.html \ html/ServersList.html \ html/TangoProgrammerGuide.html \ html/tkcvs_browser.jpg \ html/TPG_CvsModule.html \ html/TPG_CvsTags.html \ html/TPG_NamingConventions.html dist_java_template_DATA = java/DevServClass.java \ java/DevServCmd.java \ java/DevServ.java \ java/Makefile \ java/README \ java/readPropMethodName.java \ java/ReadWriteAttr.java \ java/states.java \ java/TangoclassProxy.java \ java/write_property.java dist_python_template_DATA = python/Attribute.py \ python/Command.py \ python/DevServ.py dist_txt_template_DATA = txt/Shortcuts.txt \ txt/WhatIsNew.txt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pogo/templates/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pogo/templates/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_cpp_templateDATA: $(dist_cpp_template_DATA) @$(NORMAL_INSTALL) @list='$(dist_cpp_template_DATA)'; test -n "$(cpp_templatedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(cpp_templatedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(cpp_templatedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(cpp_templatedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(cpp_templatedir)" || exit $$?; \ done uninstall-dist_cpp_templateDATA: @$(NORMAL_UNINSTALL) @list='$(dist_cpp_template_DATA)'; test -n "$(cpp_templatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(cpp_templatedir)'; $(am__uninstall_files_from_dir) install-dist_html_templateDATA: $(dist_html_template_DATA) @$(NORMAL_INSTALL) @list='$(dist_html_template_DATA)'; test -n "$(html_templatedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(html_templatedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(html_templatedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(html_templatedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(html_templatedir)" || exit $$?; \ done uninstall-dist_html_templateDATA: @$(NORMAL_UNINSTALL) @list='$(dist_html_template_DATA)'; test -n "$(html_templatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(html_templatedir)'; $(am__uninstall_files_from_dir) install-dist_java_templateDATA: $(dist_java_template_DATA) @$(NORMAL_INSTALL) @list='$(dist_java_template_DATA)'; test -n "$(java_templatedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(java_templatedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(java_templatedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(java_templatedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(java_templatedir)" || exit $$?; \ done uninstall-dist_java_templateDATA: @$(NORMAL_UNINSTALL) @list='$(dist_java_template_DATA)'; test -n "$(java_templatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(java_templatedir)'; $(am__uninstall_files_from_dir) install-dist_python_templateDATA: $(dist_python_template_DATA) @$(NORMAL_INSTALL) @list='$(dist_python_template_DATA)'; test -n "$(python_templatedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(python_templatedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(python_templatedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(python_templatedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(python_templatedir)" || exit $$?; \ done uninstall-dist_python_templateDATA: @$(NORMAL_UNINSTALL) @list='$(dist_python_template_DATA)'; test -n "$(python_templatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(python_templatedir)'; $(am__uninstall_files_from_dir) install-dist_txt_templateDATA: $(dist_txt_template_DATA) @$(NORMAL_INSTALL) @list='$(dist_txt_template_DATA)'; test -n "$(txt_templatedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(txt_templatedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(txt_templatedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(txt_templatedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(txt_templatedir)" || exit $$?; \ done uninstall-dist_txt_templateDATA: @$(NORMAL_UNINSTALL) @list='$(dist_txt_template_DATA)'; test -n "$(txt_templatedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(txt_templatedir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(cpp_templatedir)" "$(DESTDIR)$(html_templatedir)" "$(DESTDIR)$(java_templatedir)" "$(DESTDIR)$(python_templatedir)" "$(DESTDIR)$(txt_templatedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_cpp_templateDATA \ install-dist_html_templateDATA install-dist_java_templateDATA \ install-dist_python_templateDATA install-dist_txt_templateDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_cpp_templateDATA \ uninstall-dist_html_templateDATA \ uninstall-dist_java_templateDATA \ uninstall-dist_python_templateDATA \ uninstall-dist_txt_templateDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dist_cpp_templateDATA \ install-dist_html_templateDATA install-dist_java_templateDATA \ install-dist_python_templateDATA install-dist_txt_templateDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am \ uninstall-dist_cpp_templateDATA \ uninstall-dist_html_templateDATA \ uninstall-dist_java_templateDATA \ uninstall-dist_python_templateDATA \ uninstall-dist_txt_templateDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/pogo/Makefile.am0000644023471100065110000000004113034744702012725 00000000000000 SUBDIRS = templates preferences tango-9.2.5a/pogo/Makefile.in0000644023471100065110000005035713034745123012753 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pogo DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = templates preferences all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pogo/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pogo/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/pogo/preferences/0000755023471100065110000000000013034745266013265 500000000000000tango-9.2.5a/pogo/preferences/common_target.opt0000644023471100065110000001600113034744702016557 00000000000000INSTALL_DIR=$(TANGO_HOME)/bin # create all directories directories := $(shell mkdir -p $(OUTPUT_DIR); for FILE in $(SVC_OBJS); do mkdir -p `dirname $$FILE`; done) #------------------------------------------------------------------------------ #-- rule: ./*.cpp #------------------------------------------------------------------------------ $(OBJDIR)/%.o: %.cpp $(SVC_INCL) @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: ./*.cpp #------------------------------------------------------------------------------ $(OBJDIR)/%.so.o: %.cpp $(SVC_INCL) @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: ./*.cpp #------------------------------------------------------------------------------ $(OBJDIR)/%.a.o: %.cpp $(SVC_INCL) @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: $(CPPDIRUSER)/*.cpp #------------------------------------------------------------------------------ $(OBJDIR)/%.o: $(CPPDIRUSER)/%.cpp $(SVC_INCL) @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: ./*.cxx #------------------------------------------------------------------------------ $(OBJDIR)/%.o: %.cxx @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: $(CPPDIRUSER)/*.cxx #------------------------------------------------------------------------------ $(OBJDIR)/%.o: $(CPPDIRUSER)/%.cxx @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: ./*.cc #------------------------------------------------------------------------------ $(OBJDIR)/%.o: %.cc @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: $(CPPDIRUSER)/*.cc #------------------------------------------------------------------------------ $(OBJDIR)/%.o: $(CPPDIRUSER)/%.cxx @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: ./*.c #------------------------------------------------------------------------------ $(OBJDIR)/%.o: %.c $(SVC_INCL) @echo "Compiling $< ..." $(CC) $(CFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- rule: $(CPPDIRUSER)/*.c #------------------------------------------------------------------------------ $(OBJDIR)/%.o: $(CPPDIRUSER)/%.c @echo "Compiling $< ..." $(CXX) $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------------------ #-- all: #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),DEVICE) all: $(SPECIFIC_ALL_TARGET) $(OUTPUT_DIR)/$(PROJECT_NAME) endif ifeq ($(PROJECT_TYPE),SIMPLE_EXE) all: $(SPECIFIC_ALL_TARGET) $(OUTPUT_DIR)/$(PROJECT_NAME) endif ifeq ($(PROJECT_TYPE),STATIC_LIB) all: $(SPECIFIC_ALL_TARGET) $(OUTPUT_DIR)/lib$(PROJECT_NAME).a endif ifeq ($(PROJECT_TYPE),SHARED_LIB) all: $(SPECIFIC_ALL_TARGET) $(OUTPUT_DIR)/lib$(PROJECT_NAME).so endif #------------------------------------------------------------------------------ #-- $(PROJECT_NAME) for DEVICE: #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),DEVICE) $(OUTPUT_DIR)/$(PROJECT_NAME): $(SVC_OBJS) @echo "Linking TANGO device server $(OUTPUT_DIR)/$(PROJECT_NAME) ..." $(CXX) $(SVC_OBJS) $(LDFLAGS) -o $(OUTPUT_DIR)/$(PROJECT_NAME) $(POST_PROCESSING) endif #------------------------------------------------------------------------------ #-- $(PROJECT_NAME) for SIMPLE_EXE: #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),SIMPLE_EXE) $(OUTPUT_DIR)/$(PROJECT_NAME): $(SVC_OBJS) @echo "Linking executable $(OUTPUT_DIR)/$(PROJECT_NAME) ..." $(CXX) $(SVC_OBJS) $(LDFLAGS) -o $(OUTPUT_DIR)/$(PROJECT_NAME) $(POST_PROCESSING) endif #------------------------------------------------------------------------------ #-- $(PROJECT_NAME) for STATIC_LIB: #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),STATIC_LIB) $(OUTPUT_DIR)/lib$(PROJECT_NAME).a: $(LIB_OBJS) @echo "Creating static library "$(OUTPUT_DIR)/lib$(PROJECT_NAME).a ifdef EXTERNAL_LIBS mkdir -p $(OBJ_DIR)/external_libs cd $(OBJ_DIR)/external_libs && \ for EXTERNAL_LIB in $(EXTERNAL_LIBS); do ar x $$EXTERNAL_LIB; done && \ cd - ar rcs $(OUTPUT_DIR)/lib$(PROJECT_NAME).a $(LIB_OBJS) $(OBJ_DIR)/external_libs/*.o rm -f $(OBJ_DIR)/external_libs/* else ar rcs $(OUTPUT_DIR)/lib$(PROJECT_NAME).a $(LIB_OBJS) endif endif #------------------------------------------------------------------------------ #-- $(PROJECT_NAME) for SHARED_LIB: #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),SHARED_LIB) $(OUTPUT_DIR)/lib$(PROJECT_NAME).so: $(LIB_OBJS) @echo "Linking shared library "$(OUTPUT_DIR)/lib$(PROJECT_NAME).so $(CXX) $(LIB_OBJS) $(LDFLAGS) -o $(OUTPUT_DIR)/lib$(PROJECT_NAME).so @echo "Link successfull" endif #------------------------------------------------------------------------------ #-- clean: #------------------------------------------------------------------------------ clean: $(SPECIFIC_CLEAN_TARGET) @echo "Cleaning "$(PROJECT_NAME) ifdef OBJDIR ifneq ($(OBJDIR),/tmp) rm -rf $(OBJDIR) endif endif ifeq ($(PROJECT_TYPE),SIMPLE_EXE) rm -f $(OUTPUT_DIR)/$(PROJECT_NAME) endif ifeq ($(PROJECT_TYPE),DEVICE) rm -f $(OUTPUT_DIR)/$(PROJECT_NAME) $(OUTPUT_DIR)/core endif ifeq ($(PROJECT_TYPE),STATIC_LIB) rm -f $(OUTPUT_DIR)/lib$(PROJECT_NAME).a endif ifeq ($(PROJECT_TYPE),SHARED_LIB) rm -f $(OUTPUT_DIR)/lib$(PROJECT_NAME).so endif #------------------------------------------------------------------------------ #-- install: #------------------------------------------------------------------------------ install: @echo "Installing $(OUTPUT_DIR)/$(PROJECT_NAME) to $(INSTALL_DIR)" ifeq ($(PROJECT_TYPE),DEVICE) mv $(OUTPUT_DIR)/$(PROJECT_NAME) $(INSTALL_DIR) ls -l $(INSTALL_DIR)/$(PROJECT_NAME) endif #------------------------------------------------------ # Tag the CVS/SVN module corresponding to this class #------------------------------------------------------ svn_tag: svn copy ../trunk ../tags/$(RELEASE) svn commit ../tags/$(RELEASE) \ -m "Tagging the $(RELEASE) of the $(PACKAGE_NAME) project." cvs_tag: @cvstag "$(PACKAGE_NAME)-$(RELEASE)" @make $(PACKAGE_NAME) @make show_cvs_tag show_cvs_tag: @cvstag -d tango-9.2.5a/pogo/preferences/Makefile.am0000644023471100065110000000133613034744702015236 00000000000000edit = sed \ -e 's|@bindir[@]|$(bindir)|g' \ -e 's|@datadir[@]|$(datadir)|g' \ -e 's|@prefix[@]|$(prefix)|g' \ -e 's|@ZMQ_PREFIX[@]|$(ZMQ_PREFIX)|g' \ -e 's|@ORB_PREFIX[@]|$(ORB_PREFIX)|g' preferencesdir = $(datadir)/pogo/preferences dist_preferences_DATA = common_target.opt nodist_preferences_DATA = Pogo.site_properties \ tango.opt $(nodist_preferences_DATA): Makefile rm -f $@ $@.tmp srcdir=''; \ test -f ./$@.in || srcdir=$(srcdir)/; \ $(edit) $${srcdir}$@.in >$@.tmp chmod a-w $@.tmp mv $@.tmp $@ CLEANFILES = $(nodist_preferences_DATA) Pogo.site_properties: $(srcdir)/Pogo.site_properties.in tango.opt: $(srcdir)/tango.opt.in EXTRA_DIST = \ Pogo.site_properties.in \ tango.opt.in tango-9.2.5a/pogo/preferences/Makefile.in0000644023471100065110000004263713034745123015256 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pogo/preferences DIST_COMMON = $(dist_preferences_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(preferencesdir)" \ "$(DESTDIR)$(preferencesdir)" DATA = $(dist_preferences_DATA) $(nodist_preferences_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ edit = sed \ -e 's|@bindir[@]|$(bindir)|g' \ -e 's|@datadir[@]|$(datadir)|g' \ -e 's|@prefix[@]|$(prefix)|g' \ -e 's|@ZMQ_PREFIX[@]|$(ZMQ_PREFIX)|g' \ -e 's|@ORB_PREFIX[@]|$(ORB_PREFIX)|g' preferencesdir = $(datadir)/pogo/preferences dist_preferences_DATA = common_target.opt nodist_preferences_DATA = Pogo.site_properties \ tango.opt CLEANFILES = $(nodist_preferences_DATA) EXTRA_DIST = \ Pogo.site_properties.in \ tango.opt.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pogo/preferences/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pogo/preferences/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_preferencesDATA: $(dist_preferences_DATA) @$(NORMAL_INSTALL) @list='$(dist_preferences_DATA)'; test -n "$(preferencesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(preferencesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(preferencesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(preferencesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(preferencesdir)" || exit $$?; \ done uninstall-dist_preferencesDATA: @$(NORMAL_UNINSTALL) @list='$(dist_preferences_DATA)'; test -n "$(preferencesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(preferencesdir)'; $(am__uninstall_files_from_dir) install-nodist_preferencesDATA: $(nodist_preferences_DATA) @$(NORMAL_INSTALL) @list='$(nodist_preferences_DATA)'; test -n "$(preferencesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(preferencesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(preferencesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(preferencesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(preferencesdir)" || exit $$?; \ done uninstall-nodist_preferencesDATA: @$(NORMAL_UNINSTALL) @list='$(nodist_preferences_DATA)'; test -n "$(preferencesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(preferencesdir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(preferencesdir)" "$(DESTDIR)$(preferencesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_preferencesDATA \ install-nodist_preferencesDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_preferencesDATA \ uninstall-nodist_preferencesDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dist_preferencesDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-nodist_preferencesDATA install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ uninstall-dist_preferencesDATA \ uninstall-nodist_preferencesDATA $(nodist_preferences_DATA): Makefile rm -f $@ $@.tmp srcdir=''; \ test -f ./$@.in || srcdir=$(srcdir)/; \ $(edit) $${srcdir}$@.in >$@.tmp chmod a-w $@.tmp mv $@.tmp $@ Pogo.site_properties: $(srcdir)/Pogo.site_properties.in tango.opt: $(srcdir)/tango.opt.in # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/pogo/preferences/Pogo.site_properties.in0000644023471100065110000000250613034744702017655 00000000000000# # This is the Pogo site specific properties file. # # # Site or Institute name # org.tango.pogo.site.name: # # Site specific class families. # org.tango.pogo.site.class_families: Miscellaneous AbstractClasses Acquisition Application BeamDiag Beamlines Calculation Communication Controllers InputOutput Instrumentation Interlock Linac Motion Power Supply Radio Frequency Radio Protection Sequencer Simulators Vacuum # # Directory for html documentation code generation # org.tango.pogo.doc_home: ./doc_html # # Directory for generic makefiles (common_target.opt and tango.opt) # org.tango.pogo.makefile_home: @datadir@/pogo/preferences tango-9.2.5a/pogo/preferences/tango.opt.in0000644023471100065110000001411213034744702015437 00000000000000#------------------------------------------------------------------------------ #-- gcc version #------------------------------------------------------------------------------ GCC_MAJOR_VERSION_GT4 := $(shell expr `c++ -dumpversion | cut -f1 -d.` \> 4) GCC_MAJOR_VERSION_EQ4 := $(shell expr `c++ -dumpversion | cut -f1 -d.` \== 4) GCC_MINOR_VERSION_GTEQ3 := $(shell expr `c++ -dumpversion | cut -f2 -d.` \>= 3) ifeq ($(GCC_MAJOR_VERSION_GT4),1) CXX11 = -std=c++0x else ifeq ($(GCC_MAJOR_VERSION_EQ4),1) ifeq ($(GCC_MINOR_VERSION_GTEQ3),1) CXX11 = -std=c++0x endif endif endif #------------------------------------------------------------------------------ #-- TANGO_HOME #------------------------------------------------------------------------------ ifndef TANGO_HOME TANGO_HOME = @prefix@ endif #------------------------------------------------------------------------------ #-- OMNI_HOME #------------------------------------------------------------------------------ ifndef OMNI_HOME OMNI_HOME = @ORB_PREFIX@ endif #------------------------------------------------------------------------------ #-- ZMQ_HOME #------------------------------------------------------------------------------ ifndef ZMQ_HOME ZMQ_HOME = @ZMQ_PREFIX@ endif #------------------------------------------------------------------------------ #-- CXX #------------------------------------------------------------------------------ ifndef CXX CXX = gcc endif #------------------------------------------------------------------------------ #-- CC #------------------------------------------------------------------------------ ifndef CC CC = gcc endif #------------------------------------------------------------------------------ #-- AR #------------------------------------------------------------------------------ ifndef AR AR = ar rv endif #------------------------------------------------------------------------------ #-- OUTPUT_TYPE (BACKWARD COMPATIBILITY) #------------------------------------------------------------------------------ ifdef OUTPUT_TYPE PROJECT_TYPE = $(OUTPUT_TYPE) endif #------------------------------------------------------------------------------ #-- LDFLAGS_USER (BACKWARD COMPATIBILITY) #------------------------------------------------------------------------------ ifdef LFLAGS_USR LDFLAGS_USER = $(LFLAGS_USR) endif #------------------------------------------------------------------------------ #-- PROJECT_TYPE (BACKWARD COMPATIBILITY) #------------------------------------------------------------------------------ ifeq ($(PROJECT_TYPE),DYNAMIC_LIB) PROJECT_TYPE = $(SHARED_LIB) endif #------------------------------------------------------------------------------ #-- PACKAGE_NAME (BACKWARD COMPATIBILITY) #------------------------------------------------------------------------------ ifdef PACKAGE_NAME PROJECT_NAME = $(PACKAGE_NAME) endif #------------------------------------------------------------------------------ #-- TANGO_REQUIRED #------------------------------------------------------------------------------ ifndef TANGO_REQUIRED ifeq ($(PROJECT_TYPE),DEVICE) TANGO_REQUIRED = TRUE else TANGO_REQUIRED = FALSE endif endif #------------------------------------------------------------------------------ #-- INCLUDE_DIRS #------------------------------------------------------------------------------ INCLUDE_DIRS = $(INC_DIR_USER) INCLUDE_DIRS += -I../include -I. ifeq ($(TANGO_REQUIRED),TRUE) INCLUDE_DIRS += -I$(TANGO_HOME)/include/tango -I$(OMNI_HOME)/include -I$(ZMQ_HOME)/include endif #------------------------------------------------------------------------------ #-- OBJDIR #------------------------------------------------------------------------------ ifndef OBJDIR OBJDIR = ./obj endif #------------------------------------------------------------------------------ #-- OUTPUT_DIR #------------------------------------------------------------------------------ ifndef OUTPUT_DIR ifeq ($(PROJECT_TYPE),DEVICE) OUTPUT_DIR= $(HOME)/DeviceServers else ifeq ($(PROJECT_TYPE),STATIC_LIB) OUTPUT_DIR= lib else ifeq ($(PROJECT_TYPE),SHARED_LIB) OUTPUT_DIR= lib else OUTPUT_DIR= bin endif endif endif endif #------------------------------------------------------------------------------ #-- RELEASE_TYPE #------------------------------------------------------------------------------ ifndef RELEASE_TYPE RELEASE_TYPE = OPTIMIZED endif #------------------------------------------------------------------------------ #-- CXXFLAGS #------------------------------------------------------------------------------ CXXFLAGS = ifeq ($(RELEASE_TYPE),DEBUG) CXXFLAGS += -g -D_DEBUG else CXXFLAGS += -O2 endif ifeq ($(PROJECT_TYPE),SHARED_LIB) CXXFLAGS += -fPIC endif ifdef CXXFLAGS_USR CXXFLAGS_USER = $(CXXFLAGS_USR) endif CXXFLAGS += -D_REENTRANT -W $(INCLUDE_DIRS) $(CXXFLAGS_USER) $(CXX11) -Dlinux #------------------------------------------------------------------------------ #-- CFLAGS #------------------------------------------------------------------------------ CFLAGS = ifeq ($(RELEASE_TYPE),DEBUG) CFLAGS += -g -D_DEBUG else CFLAGS += -O2 endif ifeq ($(PROJECT_TYPE),SHARED_LIB) CFLAGS += -fPIC endif ifdef CFLAGS_USR CFLAGS_USER = $(CFLAGS_USR) endif CFLAGS += -D_REENTRANT -W -pipe $(INCLUDE_DIRS) $(CFLAGS_USER) #------------------------------------------------------------------------------ #-- LDFLAGS #------------------------------------------------------------------------------ LDFLAGS = ifeq ($(PROJECT_TYPE),SHARED_LIB) LDFLAGS += -shared -O -Wl,-soname,lib$(PROJECT_NAME).so endif ifdef LDFLAGS_USR LDFLAGS_USER = $(LDFLAGS_USR) endif LDFLAGS += $(LDFLAGS_USER) $(LIB_DIR_USER) ifeq ($(TANGO_REQUIRED),TRUE) OMNI_LIB = $(shell pkg-config --libs-only-L omniORB4) ZMQ_LIB = $(shell pkg-config --libs-only-L libzmq) TANGO_LIB = $(shell pkg-config --libs tango) LDFLAGS += $(OMNI_LIB) $(ZMQ_LIB) $(TANGO_LIB) endif LDFLAGS += -ldl -lpthread -lstdc++ tango-9.2.5a/README0000644023471100065110000007665313034744715010637 00000000000000 TANGO source code release version 9.2.5a - README (01/2017) ========================================================== TABLE OF CONTENTS ----------------- 1 - Introduction 2 - What's inside 3 - Prerequisites 4 - Installing 5 - Compiling 6 - Running 7 - Updating from previous Tango releases 8 - Documentation 9 - Remarks 10 - Questions 11 - URL 12 - Changes 1 - INTRODUCTION ---------------- This is the README for the TANGO source code release. TANGO is a toolkit for building object oriented control systems based on CORBA ans ZMQ. TANGO is a joint effort of the several European research institutes. This source code release is based on the latest version of TANGO 9 (9.2.5a) and is intended for Unix platforms. A binary version for Windows of TANGO is available. The source code contained in this package runs on Windows but the Makefile don't. Tango 9 and above is compliant to the 64 bit architecture. This package is foreseen (and was tested) to run with omniORB4.2.1 even if it works as well with omniORB 4.1.6, 4.1.7 and 4.2.0, zmq 4.0.5 and Java 1.7 The default Pogo application in this package can generate source code for C++, Python and Java device servers. The database server delivered with this package do not force the database user to be root. You have to use the my.cnf configuration files or the MYSQL_USER and MYSQL_PASSWORD environment variables to specify the database account to be used by the database server. The TangoTest device server delivered with this package is an example implementation of all possible Tango data types. The displayed data is animated what creates some CPU load when running the server. Starting an atkpanel (generic Tango client) on a device of this server is CPU and memory consuming, because all possible data are read and displayed. In the case of upgrading an alreay running Tango system, please follow the instructions in the chapter UPGRADING FROM PREVIOUS TANGO RELEASES. 2 - WHAT'S INSIDE ----------------- This source code release contains : (1) Tango C++ library source files and java library and application jar files (2) The Tango database device server source files and the database configuration files (.my.cnf). (3) The Jive application. (4) The Astor application and its associated Starter device server source files. (5) The Pogo application. (6) The tg_devtest application (7) A test device server called TangoTest with its source files (8) The atk graphical toolkit for writing tango applications in java (9) The atkpanel application as a generic test client (10 The atktuning application for tuning attributes in a device (11) The logviewer application for visualising logging messages (12) The DeviceTree application to display tango device attribute and/or command (13) The atkmoni application to monitor scalar attribute values in time (14) The jdraw synoptic editor to create synoptic applications (15) The synopticAppli to run and test synoptics created with jdraw (16) The Tango controlled access device server source file It is used if you want to run Tango with its controlled access feature The Jive application is a Tango database browsing tool written in Java. It also allows device testing. Its documentation is at http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/jive_doc/index.html The Astor application is also a Java application. With the help of the Tango starter device server, it allows full remote Tango control system administration. Its documentation is at : http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/astor_doc/index.html The Pogo application is a graphical Tango device server code generator. Its documentation is at : http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/pogo_doc/index.html tg_devtest is a device testing application for device server which do not use the database. It is a sub-part of Jive. 3 - PREREQUISITES ----------------- Before compiling and installing TANGO you need to install : (1) omniORB available from http://sourceforge.net/projects/omniorb (Preferably version 4.2.1 but 4.2.0/4.1.7/4.1.6 is fine). OmniORB is mandatory to build the Tango libraries and the delivered Tango device servers. (2) zmq available from http://www.zeromq.org (version >= 4.0.5). Zmq is mandatory to build the Tango libraries and the delivered Tango device servers. (3) mysql available from http://mysql.org (version >= 5.5) or MariaDB from https://mariadb.org (version >= 10.0) One of these two databases is mandatory to install a Tango database. The default database is still mysql. If you want to use MariaDB, use the --enable-mariadb configure option. (4) doxygen available from http://www.doxygen.org Remark : doxygen is not mandatory to run Tango. It is just used by our code generator (called Pogo) to automatically generates some part of the Tango device server documentation. If you don't install it, this part of the documenetaion will simply not be generated. But in all cases, some HTML pages documenting Tango device server will allways be generated. Also check the tools you are using (1) If you are using gcc, you need to have gcc release 3.2.0 or above. You can download gcc from http://gcc/gnu.org (2) Only java release 1.7.0 or above is supported, you can download java from http://java.sun.com/j2se. Java is mandatory to install and run the Tango tools. 4 - INSTALLING -------------- Once you have installed the packages in prerequisites you can think about configuring and compiling TANGO. To configure TANGO you need to tell it where to find omniORB, ZMQ and mysql (if it is in a non-standard place) and where to install TANGO. The main options for configure are: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --enable-static[=PKGS] build static libraries [default=no] --enable-mariadb MariaDb database instead of mysql. Build database server using mariadb instead of mysql --disable-java disable installation of Java applications --disable-dbserver disable installation of Tango database server. --disable-dbcreate enable an creation of the Tango database schema --disable-jpegmmx disable jpeg mmx optimization --with-java path to java interpreter --with-doxygen path to doxygen utility --with-lyx path to LyX utility --with-zlib=DIR root directory path of zlib installation defaults to /usr/local or /usr if not found in /usr/local --with-omni prefix to omniORB installation (default: $OMNI_ROOT) --with-zmq prefix to ZMQLIB installation --with-tango-db-name Name of the database created in mysql (default: tango) --with-tango-rc-file Location/name of the tango rc file (default: /etc/tangorc) --with-mysqlclient-prefix=PFX Prefix where mysqlclient is installed --with-mysqlclient-include=DIR Directory pointing to mysqlclient include files --with-mysqlclient-lib=LIB Directory pointing to mysqlclient library (Note: -include and -lib do override paths found with -prefix) --with-mysql-ho the host of the database (mysql or mariadb) (default: ) --with-mysql-admin super user of your database (mysql or mariadb) (default: ) --with-mysql-admin-passwd super user password of your database (mysql or mariadb) (default: ) The last three options can be replaced with a .my.cnf file in your home directory with the following content: [client] user = [db login name] password = [password] host = [host name] At the end of the configure script, a status is displayed indicating pathes and versions of found software and the parts of the Tango package which are ready to be installed. Example (using mysql): Source code location: ../.. Version: 9.2.5a Compiler: gcc,g++ OMNIORB PATH: /segfs/tango/ORB/omniORB4.2.1/ubuntu1404 OMNIORB VERSION: "4.2.1" ZMQ PATH: /segfs/tango/transport/zmq4.0.5/ubuntu1404 ZMQ VERSION: 4.0.5 JAVA PATH: /usr/bin/java JAVA VERSION: 1.7.0_79 MYSQL CLIENT LIB: -L/usr/local/mysql/lib/mysql -lmysqlclient MYSQL VERSION: 5.7.13 MYSQL CONNECTION: OK build: libraries: yes java application: yes event java interface: yes access control server: yes database server: yes database schema create: yes Hints to configure: The Tango database server ------------------------- To disable the compilation and installation of the database server, use --disable-dbserver. Create the Tango database ------------------------- To allow the configure script to create the Tango database in your database, make sure that the mysql version is > 5.5 (or 10.0 for mariadb) and the mysqld is running before doing configure. Also check that the mysql client (called mysql) is in your path. If you are not running the configure script on the same host where the mysql server is running, use the "--with-mysql-ho" configure option or the host entry in the my.cnf file. The configure script will try to connect to the database. Make sure that privileges are granted to the user used by configure running on the host where you run configure. The configure options "--with-mysql-admin" and "--with-mysql-admin-passwd" allow you to select which database user configure will use. You can also use the user and password entries of the my.cnf file to set-up your connection to the database. To disable any access to the database use the --disable-dbcreate option. Database server, mysql and libz ------------------------------- Depending on how MySql has been installed, the Tango database server may need the compress/uncompress library (called "libz"). By default, configure try to find this compress/uncompress stuff. If you don't need it, use the configure "--without-zlib". Java applications ----------------- Tango arrives with many Java applications. Each java applications has its own script (in $prefix/bin) where the CLASSPATH is set before starting the java interpreter. These scripts will be modified by the configure script to set a correct path to the java interpreter found in your PATH when configure was run. You can also use the "--with-java=xxx" to define a path to the java interpreter. It is not mandatory to find the java interpreter in your PATH. You can use the "--disable-java" configure option to build Tango. When java was not found, disabled, or found with un unsufficient version, the installation of the java applications is disabled. lyx --- LyX is a document processor used to generate the tango manual documentation. One already generated manual is provided in this distribution. Nevertheless, if you want to re-generate it, you can use the command "make pdf" but this requires LyX to be installed on your host. You can used the "--with-lyx=xxx" configure command line to define a path to the LyX utility on your host. doxygen ------- Doxygen is a documentation generator from C++ source files. It is used by the Tango code generator (called Pogo) to generate Tango device server documentation. The script used to start Pogo will be modified by the configure script to set a correct path to the doxygen command found in your PATH when configure was run. You can also used the "--with-doxygen=xxx" to define a path to the doxygen command. It is not mandatory to find the doxygen command in your PATH or to use the "--with-doxygen" configure option to build and run Tango. This will only prevent some part of Tango device server documentation to be generated by Pogo. You can type "configure --help" to get a print of all the options supported by the configure script. Here is an example of running configure for TANGO telling it where to install (--prefix) TANGO and where omniORB and ZMQ are installed: cd $directory_where_tango_has_been_installed mkdir build cd build export CC=gcc export CXX=g++ ../configure --prefix=/home/tango/release/install_dir_linux \ --with-omni=/segfs/tango/ORB/omniORB4.2.1/ubuntu1404 \ --with-zmq=/segfs/tango/transport/zmq4.0.5/ubuntu1404 During the configure procedure the access to the database is tested. Please prepare your my.cnf (database configuration file) or use the configure options --with-mysql-admin --with-mysql-admin-passwd --with-mysql-ho to specify the access to the database. 5 - COMPILING ------------- Once configure has run successfully you can compile and install the executables, include files, libraries and scripts. Do this by typing : make all make install 6 - RUNNING ----------- To test wether the TANGO build worked do the following : (1) start the database on port 10000 by typing : TANGO_INSTALL_DIR/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 Specify the database account to be used by the database server. Two possibilities are available: - set the following environment variables to the account and password to be used MYSQL_USER to specify the database login name MYSQL_PASSWORD to specify the password MYSQL_HOST if required - configure the database client with the database configuration file my.cnf [client] user = [database login name] password = [password] (2) Configure the TANGO_HOST environment variable with the hostname the database server is running on and the port number used. setenv TANGO_HOST hostname:10000 (3) start the test device server tangoTest : TANGO_INSTALL_DIR/bin/TangoTest test (4) start jive by typing for example : TANGO_INSTALL_DIR/bin/jive (See chapter 4 java sub-chapter to check the jive script) (5) test your device using the test device in jive (6) write new device servers using pogo : TANGO_INSTALL_DIR/bin/pogo (See chapter 4 java sub-chapter to check the pogo script) 7 - UPDATING FROM PREVIOUS TANGO RELEASES ----------------------------------------- WARNINGS: To update the Tango database, the distribution provides some scripts. The "make install" command will create these database related scripts in /share/tango/db ONLY if the database connection test done at configure time is successfull ("database schema create" reported as yes at the end of the configure script execution) 7-2 - UPDATING FROM A TANGO 9 DATABASE -------------------------------------- Tango 9.2 includes an update of the database. This is one update of the stored procedure (release 1.12). To update your database, follow these instructions: a - Stop your control system and your database server(s) b - Backup your database (Recommended, not mandatory) c - Cd to the /share/tango/db directory d - Run the update script: ./update_db.sh e - Restart your database server(s) 7-2 - UPDATING FROM A TANGO 8 DATABASE -------------------------------------- Tango 9.1 requires an update of the database. This is one update of the stored procedure (release 1.11), some new commands in the list of allowed commands for the Database class (for Tango Access Control system) and some new tables related to the new pipe feature. To update your database, follow these instructions: a - Stop your control system and your database server(s) b - Backup your database (Recommended, not mandatory) c - Cd to the /share/tango/db directory d - Run the update script: mysql -u[user] -p[password] < ./update_db8.sql e - Restart your database server(s) 7-2 - UPDATING FROM A TANGO 7 DATABASE -------------------------------------- Tango 9.1 needs an update of the data in the database. This is one update of the stored procedure (release 1.9), some more commands definition for the Tango control access and new tables dedicated to pipe. To update your database, follow these instructions: a - Stop your control system and your database server(s) b - Backup your database (Recommended, not mandatory) c - Cd to the /share/tango/db directory d - Run the update script: mysql -u[user] -p[password] < ./update_db7.sql e - Restart your database server(s) 8 - DOCUMENTATION ----------------- Don't forget to READ THE MANUAL (in doc/tango.pdf) ! 9 - REMARKS ----------- TANGO 9.0: Tango 9.0 is a major release. Recompiling a device server with Tango 8.0 means recompiling ALL classes of the device server. You need to work with coherent include files. TANGO 8.0: Tango 8.0 is a major release. Recompiling a device server with Tango 8.0 means recompiling ALL classes of the device server. You need to work with coherent include files. TANGO 7.0: Tango 7.0 is a major release. Recompiling a device server with Tango 7.0 means recompiling ALL classes of the device server. You need to work with coherent include files. TANGO 6.1: The database server in this package uses stored procedures. To make it reliably work the MySQL version must be >5.0. To exploit the full performance of the new database server, on an already installed Tango system, the the chapter UPDATING FROM PREVIOUS TANGO RELEASES. TANGO 6.0: Tango 6.0 is a major release, because it uses omniORB 4.1 which is a major release of omniORB. The code generated from the with the IDL compiler is not compatible with the code gernerated with omniORB 4.0.x! To avoid any confusion with new and old libraries we decided to make also a major Tango release. Recompiling a device server with Tango 6.0 and omniORB 4.1 means recompiling ALL classes of the device server. You need to work with coherent include files. 10 - QUESTIONS -------------- You will definitely have some ! Send questions to info@tango-controls.org or on the forum: http://www.tango-controls.org/community/forum 11 - URL -------- Visit the TANGO website http://www.tango-controls.org for online documentation, news and to download add-on packages. 12 - CHANGES ------------ See the file TANGO_CHANGES to get an overview of all modification between the different Tango library versions. Changes between Tango distribution 9.2.5 and 9.2.5a -------------------------------------------------- - Updated Jive to Release 7.10 - Updated JSSHTerminal to Release 1.10 - Updated Astor to Release 7.0.9 - Added DBBench Release 1.3 Changes between Tango distribution 9.2.2 and 9.2.5 -------------------------------------------------- - Updated C++ library to Release 9.2.5 - Updated Jive to Release 7.8 - Updated atkpanel to Release 5.5 - Updated Pogo to Release 9.4.5 - Updated DbServer to Release 5.6 (stored procedure release 1.13) - Updated JTango to Release 9.1.2 - Updated ATK to Release 9.1.22 - Updated Astor to Release 7.0.7 - Updated Starter to Release 6.9 - Updated LogViewer to Release 2.0.4 - Updated TangoAccessControl to Release 2.13 Changes between Tango distribution 9.1.0 and 9.2.2 -------------------------------------------------- - Updated C++ library to Release 9.2.2 - Updated Jive to Release 6.9 - Updated atkpanel to Release 5.4 - Updated Pogo to Release 9.2.4 - Updated DbServer to Release 5.4 (stored procedure release 1.11) - Updated JTango to Release 9.0.7 - Updated ATK to Release 9.1.13 - Updated Astor to Release 6.7.0 - Updated Starter to Release 6.8 - Updated TangoTest to Release 2.1 - Updated TangoAccessControl to Release 2.12 - SourceForge bug 755 : DBserver and TAC : Passing database name at run time - SourceForge bug 762 : TangoTest : SegFault writing to long_spectrum attribute - SourceForge bug 763 : DBserver : NULL insertion in NOT NULL columns - SourceForge bug 766 : Starter : memory leak - SourceForge bug 772 : Makefile dependencies to prevent unnecessary rebuilt - SourceForge bug 778 : tango.opt defines wrong LDFLAGS - SourceForge bug 782 : Bug in common_target.opt file - TangoTest : Memory not freed in delete_device() method - DBserver : Add command DbGetForwardedAttributeForDevice - DBserver : Change default value for accessed columns in 2 tables - DBserver : Change variable data type in Stored procedure Changes between Tango distribution 8.1.2 and 9.1.0 -------------------------------------------------- - Updated C++ library to Release 9.1.0 - Updated Log4Tango to Release 5.0.1 - Updated Jive to Release 6.7 - Updated atkpanel to Release 5.2 - Updated Pogo to Release 9.1.7 - Updated Astor to Release 6.6.6 - Updated DbServer to Release 5.2 - Replacing TangORB with JTango Release 9.0.5 - Updated ATK to Release 9.1.3 - Updated LogViewer to Release 2.0.1 - Updated Starter to Release 6.6 - Updated TangoTest to Release 2.0 - Updated TangoAccessControl to Release 2.11 - Updated tango_admin to Release 1.13 - Updated AccessControl abstract class to Release 2.7 - notifd2db removed from distribution - jzmq removed from distribution - removed notify_daemon script - SourceForge bug 661: DbServer : Wrong initialization of device table int and date columns (created_db script) - SourceForge bug 669: Jive : File written with escaped " character - SourceForge bug 670: TangoTest : Crash with value < 1 given to attribute float_scalar - SourceForge bug 671: DbServer : Attribute alias not deleted during delete_device - SourceForge bug 713: DbServer : History ID on 64 bits value - DbServer: Characters / and " " forbidden in alias name - DbServer: Small memory leak in DbGetInstanceNameList command - DbServer: Memory leak when trying to get event from it - DbServer: Change the way memorized attribute property (__value) is managed - DbServer: Remove history memorization for memorized attribute (including already stored history) - DbServer: Replace NULL insertion in not null table colums by actual date (now()) - Tango_admin: Add options --server-list and --server-instance-list (FR 99) - Distribution: Doc images source files (.fig) added to distribution - Distribution: Idl file compiled during the package compilation Changes between Tango distribution 8.0.5 and 8.1.2 --------------------------------------------------- - Updated C++ library to Release 8.1.2 - Updated Log4Tango to Release 4.0.8 - Updated Jive to Release 4.31 - Updated atkpanel to Release 4.8 - Updated Pogo to Release 8.1.14 - Updated Astor to Release 6.3.6 - Updated DbServer to Release 4.23 - Updated TangORB to Release 8.3.0 - Updated ATK to Release 4.5.3 - Updated Starter to Release 5.12 - Updated TangoTest to Release 1.9 - Updated TangoAccessControl to Release 2.9 - Updated DeviceTree to Release 1.9.6 - Updated notifd2db to Release 1.14 - Updated tango_admin to Release 1.11 - Updated AccessControl abstract class to Release 2.6 - SourceForge bug 88 (1497526) - Updating property with character \ - SourceForge bug 520 (3543407) - Bug in DbGetDeviceAttributeProperty2 - SourceForge bug 525 (3559224) - Missing -lzmq for libtango - SourceForge bug 555 - Not possible to launch atkpanel from Jdraw - New attribute alias related commands in Database server - New DbRenameServer command in database server - The DbDeleteServer command now also delete device properties - Improvement in TAC device filter (sr/v-*/* allowed) - Add jzmq in source distribution - "make pdf" command now generates the Tango book with a new --with-lyx configure command line option Changes between Tango distribution 7.2.6a and 8.0.5 --------------------------------------------------- - Updated C++ library to Release 8.0.5 - Updated Log4Tango to Release 4.0.7 - Updated Jive to Release 4.24 - Updated atkpanel to Release 4.5 - Updated Pogo to Release 8.0.7 - Updated Astor to Release 6.0.4 - Updated notifd2db to Release 1.13 - Updated tango_admin to Release 1.10 - Updated DbServer to Release 4.17 - Updated TangORB to Release 8.0.0 - Updated ATK to Release 4.3.9 - Updated Starter to Release 5.5 - Updated TangoTest to Release 1.7.0 - Updated TangoAccessControl to Release 2.5 - Updated AccessControl to Release 2.5 - SourceForge bug 3308848: Fix build on kfreebsd system - SourceForge bug 3383197: Jpeg mmx option to configure - SourceForge bug 3409434: Memory leaks in Database server - SourceForge bug 3515206: Bug in PutServerInfo command (Database server) - Add command DbGetCSDbServerList to database server - The database server now unregister itself from database when it is killed - Add 3 db commands (DbImportEvent, DbGetDeviceAlias and DbGetCSDbServerList) in allowed command list (For TAC) - The database server and TAC server supports a MYSQL_HOST environment variable - Add messages around MySQL connection in database server (to ease debugging) - New and faster algorithm in database command DbGetDeviceAttributeProperty2 - Fix two bugs in database stored procedure (release 1.8) - Try to prevent SQL injection in command DbMySqlSelect - All database class commands now have their arguments description field initialized - Database server, TAC server and Tango Test are now compiled with Debian hardenning flags Changes between Tango distribution 7.2.1 and 7.2.6a --------------------------------------------------- - SourceForge bug 3312284: Could not start jive, astor,... Changes between Tango distribution 7.2.1 and 7.2.6 --------------------------------------------------- - Updated C++ library to Release 7.2.6 - Updated Jive to Release 4.19 - Updated LogViewer to Release 1.2.3 - Updated Pogo to Release 7.2.1 - Updated Astor to Release 5.4.1 - Updated notifd2db to Release 1.12 - Updated tango_admin to Release 1.8 - Updated DbServer to Release 4.12 - Updated TangORB to Release 7.4.3 - Updated ATK to Release 4.2.10 - Updated Starter to Release 5.2 - Updated TangoTest to Release 1.4.5 - Updated TangoAccessControl to Release 2.4 - Updated AccessControl to Release 2.4 - SourceForge bug 3158150: Architecture issue in configure.in - SourceForge bug 3152384: Db Server crash when reading timing attributes - SourceForge bug 3138228: A new parameter in tango_admin when pinging database - SourceForge bug 3137921: Pogo 7 does not create some output arguments - SourceForge bug 3129852: Fix SQL script to update a Tango database from release 6 to 7.2 - Update crate_db_tables.sql script to support MySQL >= 5.1 CREATE TABLE sql statement - Implement a retry to MySQl connection in DB server. Needed for binary install Changes between Tango distribution 7.2.0 and 7.2.1 -------------------------------------------------- - Updated C++ library Release 7.2.1 - Fix SourceForge bugs number 3092110 and 3092764 - Split lib/cpp/server/jpeg directory in order to optimize compilation options Changes between Tango distribution 7.1.1 and 7.2.0 -------------------------------------------------- - Added tango_admin Release 1.0 - Updated database device server Release 4.8 - Updated TangoAccessControl device server Release 1.5 - Updated TangoTest to Release 1.4.4 - Updated ATKCore and ATKWidget to Release 4.2.3 - Updated atkpanel to Release 4.3 - Updated Jive to Release 4.12 - Updated Pogo Release 7.0 - Updated Astor to Release 5.2.9 - Updated TangORB to Release 7.3.5 - Updated Jdraw to Release 1.13 - Updated Starter to Release 4.14 - Fix SourceForge bugs number 3000308 - 3000310 - 3000329 - After installation, the doc and man folders are now under the "share" folder - A new doc/src folder added in the source package. This folder contains all the necessary files (lyx format) to generate the Tango bible (tango.pdf). If lyx is installed on your computer, to re-generate the bible, go to doc/src and type " lyx -e pdf tango.lyx" - Pogo release 6 and 7 are available in this release. If you want to start pogo release 6, simply use the pogo-6 script available in the bin directory after the install - After installation, all Pogo code generation related files are in a pogo directory - Java jar files are now in /share/java - Include files are now in /include/tango Changes between Tango distribution 7.0.2 and 7.1.1 -------------------------------------------------- - Updated database device server Release 4.5 - Updated TangoAccessControl device server Release 1.4 - Updated ATKCore and ATKWidget to Release 4.0.6 - Updated atkpanel to Release 4.2 - Updated Jive to Release 4.0 - Updated Pogo Release 6.2.0 - Updated Astor to Release 5.2.3 - Updated TangORB to release 7.1.0 - A new option --with-tango-rc-file allowing the user to select the Tango rc file location has been added to the configure script - The value passed to the configure script option --with-tango-db-name is now also taken into account by the database server and the controlled access server - Man pages for binaries have been added - omniORB detection done using pkg-config - Pictures used in the Tango pdf documentation has been changed in order to clarify their licences - In case TANGO_HOST is not defined as a variable environment, scripts to start the provided tools use the rc file if defined - Fix bug in MySQL detection - Fix bug in case doxygen is not available on the host where the installation is performed Changes between Tango distribution 6.1.1.b and 7.0.2 ---------------------------------------------------- - Added the Tango controlled access server Release 1.3 - Updated Notifd2db.cpp file Release 1.7 - Updated database device server Release 4.3 - Updated starter device server Release 4.8 - Updated TangoTest device server Release 1.3 - Updated Astor to Release 5.2 - Updated ATKCore and ATKWidget to Release 4.0.2 - Updated Jive Release 3.21 - Updated Pogo Release 6.0.0 - Updated TangoORB Release 7.0.2 - Updated atkpanel to Release 4.1 Added a tango_wca script to start/stop a Tango control system when used with its controlled access Changes between Tango distribution 6.1.1.a and 6.1.1.b ------------------------------------------------------ - Updated ATKPanel to release 3.5 - Added the log4j jar file (used by LogViewer and Java device server) Changes between Tango distribution 6.1.1 and 6.1.1.a ---------------------------------------------------- - Notifd2db.cpp file updated to release 1.6 - Fix bug in the database update script in the history ids tables update - Add TangORB.jar file to the CLASSPATH in the jdraw script file - Updated TangoORB.jar file to release 6.0.2 - Added the tool_panels jar file - Update TangoTest device server (slower data refresh frequency) tango-9.2.5a/configure.ac0000644023471100065110000003547213034744715012237 00000000000000# Process this file with autoconf to produce a configure script. # This is the configuration file for the tango system. # To process this file into a runnable shell-script, please run # the script `bootstrap' which is found in the same directory as # this file. # For extensive help on autoconf, automake, and libtool, please # consult the infofiles by running the `info' program, or by typing # M-x info in your favourite editor (emacs) # For information on how to build and use an autoconfiscated # project, please consult # http://sources.redhat.com/autobook/autobook/autobook.html # which is an online version of the Gnu Autoconf, Automake, and Libtool # book by Vaughan, Elliston, Tromey, and Taylor # What follows is the configuration, and comments to the macros used # AC_INIT initializes autoconf, The first argument is the # packagename, the second is the version used for the tar file, # the third is an email address for bug reports (shouldn't be necessary), # and the fourth argument is AC_INIT(Tango,9.2.5a,info@tango-controls.org,tango) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR([m4]) # Tells autoconf that we want at least version 2.53 of autoconf to # create configure from configure.ac AC_PREREQ(2.53) AM_MAINTAINER_MODE() AC_CANONICAL_HOST() # Lets the revision tag from cvs or rcs propagate into the # configure script, handy for debugging. AC_REVISION($Revision$) # AM_INIT_AUTOMAKE sets up automake which is used to generate # Makefile.in from Makefile.am AM_INIT_AUTOMAKE AM_SILENT_RULES([yes]) # Tells automake to use `ac_config.h.tmp' to stash all the #defines # that result from a run of configure. # The name is .tmp since I must change the PACKAGE_ definitions because # of omniORBS installation of their version of this file. AC_CONFIG_HEADERS(ac_config.h.tmp) # -version-info CURRENT[:REVISION[:AGE]] # From the libtool documentation (info libtool) # So, libtool library versions are described by three integers: # CURRENT # The most recent interface number that this library implements. # REVISION # The implementation number of the CURRENT interface. # AGE # The difference between the newest and oldest interfaces that this # library implements. In other words, the library implements all the # interface numbers in the range from number `CURRENT - AGE' to # `CURRENT'. VERSION_INFO=11:5:2 # Checks for programs. AC_PROG_CXX AC_PROG_CXXCPP AC_PROG_CPP AC_PROG_AWK AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET # Check gcc release if test "$CXX" = "c++" -o "$CXX" = "g++" then gcc_AC_HAVE_GCC_VERSION(3,2,0) if test "x$ac_cv_gcc_version_3_2_0" = "xno"; then AC_MSG_ERROR([Not supported gcc release. Should be 3.2.0 or above. Please update !],-1) fi fi # Check if compiler support C++11 AX_CXX_COMPILE_STDCXX_11([noext],[optional]) # Check if Java interpreter is there AC_ARG_ENABLE([java],AC_HELP_STRING([--enable-java],[enable installation of Java applications]), [],[enable_java=yes]) AC_ARG_ENABLE([mariadb],AC_HELP_STRING([--enable-mariadb],[enable mariadb instead of mysql]), [enable_mariadb=yes],[enable_mariadb=no]) AC_ARG_WITH([java], AC_HELP_STRING([--with-java],[path to java interpreter]), [JAVA=${with_java}], [with_java=yes]) if test "x$enable_java" = "xyes" ; then if test "x$with_java" = "xno" -o -z "$with_java"; then with_java= enable_java=no else if test "x$with_java" = "xyes"; then AC_PATH_PROG(JAVA,java,"notfound") fi if test "x$JAVA" != "xnotfound"; then java_AC_HAVE_JAVA_VERSION($JAVA,1,7) if test "x$ac_cv_java_version_1_7" = "xno"; then AC_MSG_WARN([Not supported java release. Should be 1.7.x or above. Java will be disabled for this build!]) with_java= enable_java=no else with_java=$JAVA fi else with_java= enable_java=no fi fi else with_java= fi # Define a conditional variable to enable or disable installation # of java applications. The variable is used in the Makefiles. # AM_CONDITIONAL(TANGO_JAVA_ENABLED, test x"$enable_java" != x"no") # Check if doxygen is there AC_ARG_WITH([doxygen], AC_HELP_STRING([--with-doxygen],[path to doxygen utility]), [DOXYGEN=${with_doxygen}], [AC_PATH_PROG(DOXYGEN,doxygen)]) if test -z "$DOXYGEN"; then DOXYGEN=NOT_INSTALLED fi # Check if lyx is there AC_ARG_WITH([lyx], AC_HELP_STRING([--with-lyx],[path to LyX utility]), [LYX=${with_lyx}], [AC_PATH_PROG(LYX,lyx)]) if test -z "$LYX"; then LYX="false" fi AM_CONDITIONAL(TANGO_LYX_ENABLED, test x"$LYX" != x"false") # Check if fig2dev is there AC_ARG_WITH([fig2dev], AC_HELP_STRING([--with-fig2dev],[path to fig2dev utility]), [FIG2DEV=${with_fig2dev}], [AC_PATH_PROG(FIG2DEV,fig2dev)]) if test -z "$FIG2DEV"; then FIG2DEV="false" fi AM_CONDITIONAL(TANGO_FIG2DEV_ENABLED, test x"$FIG2DEV" != x"false") AM_CONDITIONAL(TANGO_DOC_ENABLED, test x"$LYX" != x"false" && test x"$FIG2DEV" != x"false") # Use libtool which facilitates the creation of shared libraries LT_INIT() # check for the presence of zlib CHECK_ZLIB # This macro checks for omniorb and sets various defines, please # consult config/RSSH_CHECK_OMNIORB for more details RSSH_CHECK_OMNIORB enable_lib=yes # ZMQ dependency AC_ARG_WITH(zmq, AC_HELP_STRING([--with-zmq],[prefix to ZMQ installation]) ,\ ZMQ_PREFIX=${with_zmq} , ZMQ_PREFIX=/usr/local ) PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${ZMQ_PREFIX}/lib/pkgconfig PKG_CHECK_MODULES([LIBZMQ], [libzmq >= 4.0.5],[],AC_MSG_ERROR(Missing ZMQ library - Use --with-zmq configure option or add directory containing libzmq.pc to PKG_CONFIG_PATH environment variable)) ZMQ_VERSION=`eval pkg-config --modversion libzmq` ZMQ_ROOT=`eval pkg-config --variable=prefix libzmq` AC_SUBST(ZMQ_PREFIX) # We need to define some stuff for threads and stubs case $build_os in linux*) AC_DEFINE(_REENTRANT,1,"Needed for threads on Linux") CXXFLAGS="$CXXFLAGS -D_REENTRANT" ;; darwin*) AC_DEFINE(_REENTRANT,1,"Needed for threads on darwin") CXXFLAGS="$CXXFLAGS -D_REENTRANT -D__darwin__" DARWIN=yes esac # condition used in the Makefile of the Tango library AM_CONDITIONAL(DARWIN_ENABLED,test x"$DARWIN" = x"yes" ) # we want to include the omniORB stubs into the tango library CXXFLAGS="$CXXFLAGS -DOMNI_UNLOADABLE_STUBS" # checks for libdl AC_CHECK_LIB(dl, dlopen) # checks for libnsl AC_CHECK_LIB(nsl, svc_pollfd) # checks for libposix4 AC_CHECK_LIB(posix4, nanosleep) # checks for libpthread AC_CHECK_LIB(pthread, pthread_create) # checks for libsocket AC_CHECK_LIB(socket, getprotobyname) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h strings.h sys/time.h unistd.h) # Some hack for testing if we have sstream or not. use_sstream=yes; if test "x$GCC" = "xyes"; then case `$CC --version 2>/dev/null` in [[12]].*) use_sstream=no ;; *) use_sstream=yes ;; esac fi if test "x$use_sstream" = "xyes"; then AC_CXX_HAVE_SSTREAM fi # This needs to be worked on!! if test "x$use_sstream" = "xno"; then AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_HEADER(strstream, AC_DEFINE(HAVE_STRSTREAM,1,"")) AC_LANG_RESTORE fi # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_PID_T AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM # Checks for library functions. AC_FUNC_ALLOCA AC_HEADER_MAJOR AC_TYPE_SIGNAL AC_CHECK_FUNCS(gethostname gettimeofday exit tolower) AC_CXX_HAVE_CLASS_STRSTREAM # check for the presence of the mysql program, needed when doing the # install of the DataBaseds server. You can tweak the connection # with some --with variables. ./configure --help will, uhm, help you. AC_ARG_ENABLE([dbserver],AC_HELP_STRING([--enable-dbserver],[enable installation of Tango database server]), [],[enable_dbserver=yes]) enable_db_schema_create=no AC_ARG_WITH(tango-rc-file, AC_HELP_STRING([--with-tango-rc-file],[location of the tango rc file (default /etc/tangorc)]), TANGO_RC_FILE=${with_tango_rc_file}, TANGO_RC_FILE=/etc/tangorc) AC_DEFINE_UNQUOTED(TANGO_RC_FILE, "$TANGO_RC_FILE", The tango rc file name and location) AC_SUBST(TANGO_RC_FILE) # Hacks to provide the name for the tango # database. I havent found any other way to provide these arguments. AC_ARG_WITH(tango-db-name, AC_HELP_STRING([--with-tango-db-name],[the name of the tango database (default tango)]), TANGO_DB_NAME=${with_tango_db_name}, TANGO_DB_NAME=tango) # Here we define these constants so that they're reachable from c programs AC_DEFINE_UNQUOTED(TANGO_DB_NAME, "$TANGO_DB_NAME", The tango database name) # Here we propagate the constants into the makefiles. AC_SUBST(TANGO_DB_NAME) if test "x$enable_mariadb" != "xyes" ; then DB_NAME=MYSQL AS_IF([test "x$enable_dbserver" = "xyes"], [ # We need libmysqlclient to compile # finds it for us. Abort if no mysqlclientlibs are found AM_PATH_MYSQLCLIENT if test "x$MYSQLCLIENT_CFLAGS" = "x" then AC_MSG_WARN(No libmysqlclient libs found) enable_dbserver=no fi DB_LDFLAGS=${MYSQLCLIENT_LDFLAGS} DB_LDLIBS=${MYSQLCLIENT_LIBS} DB_CFLAGS=${MYSQLCLIENT_CFLAGS} AC_PATH_PROG(MYSQL, mysql, nocommand) MYSQL_VERSION=not_found if test "x$MYSQL" != "xnocommand"; then mysql_AC_HAVE_MYSQL_VERSION($MYSQL,5,5) if test "x$ac_cv_mysql_version_5_5" = "xno"; then AC_MSG_WARN([Not supported mysql release. Should be 5.5.x or above. Please update !],-1) enable_db_schema_create=no enable_dbserver=no else enable_db_schema_create=yes fi else enable_db_schema_create=no fi # check for a database schema update AS_IF([test "x$enable_db_schema_create" = "xyes"], [ AC_ARG_ENABLE([dbcreate],AC_HELP_STRING([--enable-dbcreate],[enable an creation of the Tango database schema]), [],[enable_dbcreate=yes]) enable_db_schema_create=$enable_dbcreate AS_IF([test "x$enable_db_schema_create" = "xyes"], [ AC_PROG_MYSQL ]) ]) ]) if test "x$MYSQL_VERSION" != "xnot_found"; then DB_VERSION=${MYSQL_VERSION} fi else DB_NAME=MARIADB AS_IF([test "x$enable_dbserver" = "xyes"], [ # We need libmysqlclient to compile # finds it for us. Abort if no mysqlclientlibs are found AM_PATH_MARIADBCLIENT if test "x$MARIADBCLIENT_CFLAGS" = "x" then AC_MSG_WARN(No libmariadbclient libs found) enable_dbserver=no fi DB_LDFLAGS=${MARIADBCLIENT_LDFLAGS} DB_LDLIBS=${MARIADBCLIENT_LIBS} DB_CFLAGS=${MARIADBCLIENT_CFLAGS} AC_PATH_PROG(MYSQL, mysql, nocommand) MARIADB_VERSION=not_found if test "x$MYSQL" != "xnocommand"; then mariadb_AC_HAVE_MARIADB_VERSION($MYSQL,10,0) if test "x$ac_cv_mariadb_version_10_0" = "xno"; then AC_MSG_WARN([Not supported mariadb release. Should be 10.0.x or above. Please update !],-1) enable_db_schema_create=no enable_dbserver=no else enable_db_schema_create=yes fi else enable_db_schema_create=no fi # check for a database schema update AS_IF([test "x$enable_db_schema_create" = "xyes"], [ AC_ARG_ENABLE([dbcreate],AC_HELP_STRING([--enable-dbcreate],[enable an creation of the Tango database schema]), [],[enable_dbcreate=yes]) enable_db_schema_create=$enable_dbcreate AS_IF([test "x$enable_db_schema_create" = "xyes"], [ AC_PROG_MYSQL ]) ]) ]) if test "x$MARIADB_VERSION" != "xnot_found"; then DB_VERSION=${MARIADB_VERSION} fi fi AC_SUBST(DB_LDFLAGS) AC_SUBST(DB_CFLAGS) AC_SUBST(DB_LDLIBS) # # Build the jpeg library compilation option # AC_ARG_ENABLE([jpegmmx], [AS_HELP_STRING([--disable-jpegmmx],[disable jpeg mmx optimization])], [],[enable_jpegmmx=yes]) JPEG_LIB_CXXFLAGS="-D_TANGO_LIB" JPEG_MMX_LIB_CXXFLAGS="-D_TANGO_LIB" if test "x$enable_jpegmmx" != xno; then case $host_cpu in i*86 ) JPEG_LIB_CXXFLAGS="-D_TANGO_LIB -DJPG_USE_ASM" JPEG_MMX_LIB_CXXFLAGS="-D_TANGO_LIB -mmmx -DJPG_USE_ASM" ;; esac fi AC_SUBST(JPEG_LIB_CXXFLAGS) AC_SUBST(JPEG_MMX_LIB_CXXFLAGS) # Define a conditional variables to enable or disable installation # of the database server and the database schema creation. # The variables are used in the Makefiles. # AM_CONDITIONAL(TANGO_DB_SERVER_ENABLED, test x"$enable_dbserver" = x"yes") AM_CONDITIONAL(TANGO_DB_CREATE_ENABLED, test x"$enable_db_schema_create" = x"yes") AC_SUBST(ac_aux_dir) AC_SUBST(VERSION_INFO) DATADIR=`eval echo $datadir` DATADIR=`eval echo $DATADIR` AC_SUBST(DATADIR) AC_SUBST(JAVA) AC_SUBST(DOXYGEN) AC_SUBST(LYX) AC_SUBST(FIG2DEV) AC_SUBST(JNI_INCL_DIRS) # This is a hack to change PACKAGE_ #defines into TANGO_PACKAGE AC_CONFIG_COMMANDS(ac_config.h, sed s/PACKAGE/TANGO_PACKAGE/g ac_config.h) # configure log4tango sub-package AC_CONFIG_SUBDIRS(lib/cpp/log4tango) # All the Makefiles to be generated. AC_OUTPUT(Makefile lib/Makefile lib/idl/Makefile lib/cpp/tango.pc lib/cpp/Makefile lib/cpp/server/Makefile lib/cpp/server/idl/Makefile lib/cpp/server/jpeg/Makefile lib/cpp/server/jpeg_mmx/Makefile lib/cpp/client/Makefile lib/cpp/client/helpers/Makefile lib/java/Makefile cppserver/Makefile cppserver/database/Makefile cppserver/database/create_db.sql cppserver/database/create_db.sh cppserver/database/my.cnf cppserver/database/stored_proc.sql cppserver/database/create_db_tables.sql cppserver/database/update_db.sh cppserver/database/update_db.sql cppserver/database/update_db8.sql cppserver/database/update_db7.sql cppserver/database/rem_history.sql cppserver/starter/Makefile cppserver/tangotest/Makefile cppserver/AbstractClass/Makefile cppserver/AbstractClass/AccessControl/Makefile cppserver/tangoaccesscontrol/Makefile utils/Makefile utils/tango_admin/Makefile scripts/Makefile scripts/tango scripts/tango_wca doc/Makefile doc/man/Makefile doc/src/Makefile doc/src/ds_writing/Makefile doc/src/ds_model/Makefile doc/src/dance/Makefile doc/src/java_api/Makefile doc/src/java_api/picture/Makefile doc/src/gen_api/Makefile doc/src/advanced/Makefile pogo/Makefile pogo/templates/Makefile pogo/preferences/Makefile pogo/templates/cpp/Makefile) AC_MSG_RESULT([ Configuration ($PACKAGE): Source code location: ${srcdir} Version: ${VERSION} Compiler: ${ac_ct_CC},${ac_ct_CXX} OMNIORB PATH: ${OMNI_ROOT} OMNIORB VERSION: ${OMNI_VERSION} ZMQ PATH: ${ZMQ_ROOT} ZMQ VERSION: ${ZMQ_VERSION} JAVA PATH: ${with_java} JAVA VERSION: ${JAVA_VERSION} ${DB_NAME} CLIENT LIB: ${DB_LDFLAGS} ${DB_LDLIBS} ${DB_NAME} VERSION: ${DB_VERSION} ${DB_NAME} CONNECTION: ${MYSQL_CONNECTION} build: libraries: ${enable_lib} java application: ${enable_java} access control server: ${enable_dbserver} database server: ${enable_dbserver} database schema create: ${enable_db_schema_create} Please check whether the configuration I detected matches what you would like to have. ]) tango-9.2.5a/aclocal.m40000644023471100065110000012753513034745117011610 00000000000000# generated automatically by aclocal 1.11.6 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, # Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.6], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.6])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, # 2010, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, # 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless `enable' is passed literally. # For symmetry, `disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful (and sometimes confusing) to the casual installer], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2009, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # (`yes' being less verbose, `no' or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [ --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0')]) case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few `make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using `$V' instead of `$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/RSSH_CHECK_OMNIORB.m4]) m4_include([m4/RSSH_CHECK_PTHREADS.m4]) m4_include([m4/RSSH_CHECK_SUNPRO_CC.m4]) m4_include([m4/RSSH_ENABLE_PTHREADS.m4]) m4_include([m4/ac_cxx_have_class_strstream.m4]) m4_include([m4/ac_cxx_have_sstream.m4]) m4_include([m4/ac_cxx_namespaces.m4]) m4_include([m4/ac_path_mariadb.m4]) m4_include([m4/ac_path_mysqlclient.m4]) m4_include([m4/ac_prog_mysql.m4]) m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) m4_include([m4/check_zlib.m4]) m4_include([m4/gcc_release.m4]) m4_include([m4/java_release.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/mariadb_release.m4]) m4_include([m4/mysql_release.m4]) tango-9.2.5a/Makefile.am0000644023471100065110000000305213034744715011772 00000000000000# This is the top-level Makefile # The subdirs variable tells automake which subdirs should be # traversed on a make. SUBDIRS = lib utils cppserver scripts doc if TANGO_JAVA_ENABLED SUBDIRS += pogo endif ACLOCAL_AMFLAGS = -I m4 AUX_DIST = config/config.guess \ config/config.sub \ config/install-sh \ config/ltmain.sh \ config/missing AUX_DIST_EXTRA = m4/ac_cxx_have_strstream.m4 \ m4/ac_cxx_have_sstream.m4 \ m4/ac_cxx_have_class_strstream.m4 \ m4/ac_cxx_namespaces.m4 \ m4/RSSH_CHECK_OMNINOTIFY.m4 \ m4/RSSH_CHECK_OMNIORB.m4 \ m4/RSSH_CHECK_SUNPRO_CC.m4 \ m4/RSSH_CHECK_PTHREADS.m4 \ m4/RSSH_ENABLE_PTHREADS.m4 \ m4/ac_path_mysqlclient.m4 \ m4/ac_prog_mysql.m4 \ m4/check_zlib.m4 \ m4/gcc_release.m4 \ m4/java_release.m4 \ m4/mysql_release.m4 \ m4/omniorb_release.m4 \ m4/libtool.m4 EXTRA_DIST = bootstrap \ TANGO_CHANGES \ $(AUX_DIST) $(AUX_DIST_EXTRA) MAINTAINERCLEANFILES = bootstrap Makefile.in aclocal.m4 configure $(AUX_DIST) DISTCLEANFILES = ac_config.h tango-9.2.5a/Makefile.in0000644023471100065110000007114413034745123012004 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # This is the top-level Makefile VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @TANGO_JAVA_ENABLED_TRUE@am__append_1 = pogo subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/ac_config.h.tmp.in \ $(top_srcdir)/configure \ $(top_srcdir)/pogo/templates/cpp/Makefile.in AUTHORS COPYING \ COPYING.LESSER ChangeLog INSTALL NEWS config/config.guess \ config/config.sub config/depcomp config/install-sh \ config/ltmain.sh config/missing install-sh missing \ mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = ac_config.h.tmp CONFIG_CLEAN_FILES = pogo/templates/cpp/Makefile CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = lib utils cppserver scripts doc pogo DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # The subdirs variable tells automake which subdirs should be # traversed on a make. SUBDIRS = lib utils cppserver scripts doc $(am__append_1) ACLOCAL_AMFLAGS = -I m4 AUX_DIST = config/config.guess \ config/config.sub \ config/install-sh \ config/ltmain.sh \ config/missing AUX_DIST_EXTRA = m4/ac_cxx_have_strstream.m4 \ m4/ac_cxx_have_sstream.m4 \ m4/ac_cxx_have_class_strstream.m4 \ m4/ac_cxx_namespaces.m4 \ m4/RSSH_CHECK_OMNINOTIFY.m4 \ m4/RSSH_CHECK_OMNIORB.m4 \ m4/RSSH_CHECK_SUNPRO_CC.m4 \ m4/RSSH_CHECK_PTHREADS.m4 \ m4/RSSH_ENABLE_PTHREADS.m4 \ m4/ac_path_mysqlclient.m4 \ m4/ac_prog_mysql.m4 \ m4/check_zlib.m4 \ m4/gcc_release.m4 \ m4/java_release.m4 \ m4/mysql_release.m4 \ m4/omniorb_release.m4 \ m4/libtool.m4 EXTRA_DIST = bootstrap \ TANGO_CHANGES \ $(AUX_DIST) $(AUX_DIST_EXTRA) MAINTAINERCLEANFILES = bootstrap Makefile.in aclocal.m4 configure $(AUX_DIST) DISTCLEANFILES = ac_config.h all: ac_config.h.tmp $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): ac_config.h.tmp: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/ac_config.h.tmp.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status ac_config.h.tmp $(srcdir)/ac_config.h.tmp.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f ac_config.h.tmp stamp-h1 pogo/templates/cpp/Makefile: $(top_builddir)/config.status $(top_srcdir)/pogo/templates/cpp/Makefile.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) ac_config.h.tmp.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) ac_config.h.tmp.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) ac_config.h.tmp.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) ac_config.h.tmp.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod u+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile ac_config.h.tmp installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/ac_config.h.tmp.in0000644023471100065110000001316513034745120013220 00000000000000/* ac_config.h.tmp.in. Generated from configure.ac by autoheader. */ /* "" */ #undef CORBA_H /* "if our orb has a poa" */ #undef CORBA_HAVE_POA /* "" */ #undef CORBA_MODULE_CLASS_MAPPING /* "" */ #undef CORBA_MODULE_NAMESPACE_MAPPING /* "" */ #undef CORBA_ORB_HAVE_DESTROY /* "if our orb-init has 3 args" */ #undef CORBA_ORB_INIT_HAVE_3_ARGS /* "what the third argument is" */ #undef CORBA_ORB_INIT_THIRD_ARG /* "" */ #undef COSNAMING_H /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* define if the library defines strstream */ #undef HAVE_CLASS_STRSTREAM /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `exit' function. */ #undef HAVE_EXIT /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if we have gcc 3.2.0 */ #undef HAVE_GCC_VERSION_3_2_0 /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `posix4' library (-lposix4). */ #undef HAVE_LIBPOSIX4 /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* define if the compiler implements namespaces */ #undef HAVE_NAMESPACES /* If pthreads are present */ #undef HAVE_PTHREAD_H /* define if the compiler has stringstream */ #undef HAVE_SSTREAM /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* "" */ #undef HAVE_STRSTREAM /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the `tolower' function. */ #undef HAVE_TOLOWER /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* 1 */ #undef IDL_CLN_CPP_SUFFIX /* 1 */ #undef IDL_CLN_H_SUFFIX /* 1 */ #undef IDL_SRV_H_SUFFIX /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #undef MAJOR_IN_MKDEV /* Define to 1 if `major', `minor', and `makedev' are declared in . */ #undef MAJOR_IN_SYSMACROS /* "the host running mysql" */ #undef MYSQL_HOST /* "if we're working with omniorb" */ #undef OMNIORB /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* The tango database name */ #undef TANGO_DB_NAME /* The tango rc file name and location */ #undef TANGO_RC_FILE /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Version number of package */ #undef VERSION /* "Needed for threads on darwin" */ #undef _REENTRANT /* Needed by omniorb */ #undef __OSVERSION__ /* If we're running on darwin/MacOsX */ #undef __darwin__ /* If we're running on freebsd */ #undef __freebsd__ /* If we're running on hpux */ #undef __hpux__ /* Needed by omniorb */ #undef __sparc__ /* If we're running on solaris */ #undef __sunos__ /* Needed by omniorb" */ #undef __x86__ /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t tango-9.2.5a/configure0000755023471100065110000244737013034745123011660 00000000000000#! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Tango 9.2.5a. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: info@tango-controls.org about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Tango' PACKAGE_TARNAME='tango' PACKAGE_VERSION='9.2.5a' PACKAGE_STRING='Tango 9.2.5a' PACKAGE_BUGREPORT='info@tango-controls.org' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" enable_option_checking=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS subdirs JNI_INCL_DIRS DATADIR VERSION_INFO ac_aux_dir TANGO_DB_CREATE_ENABLED_FALSE TANGO_DB_CREATE_ENABLED_TRUE TANGO_DB_SERVER_ENABLED_FALSE TANGO_DB_SERVER_ENABLED_TRUE JPEG_MMX_LIB_CXXFLAGS JPEG_LIB_CXXFLAGS DB_LDLIBS DB_CFLAGS DB_LDFLAGS MARIADBCLIENT_LIBS MARIADBCLIENT_CFLAGS MARIADBCLIENT_LDFLAGS MYSQL_HOST MYSQL_ADMIN_PASSWD MYSQL_ADMIN MYSQL MYSQLCLIENT_LIBS MYSQLCLIENT_CFLAGS MYSQLCLIENT_LDFLAGS TANGO_DB_NAME TANGO_RC_FILE ALLOCA DARWIN_ENABLED_FALSE DARWIN_ENABLED_TRUE ZMQ_PREFIX LIBZMQ_LIBS LIBZMQ_CFLAGS HAVE_ORB_IDL ORB_COSNAMING_LIB IDL_TIE_CPP_SUFFIX IDL_TIE_H1_SUFFIX IDL_TIE_H_SUFFIX IDL_SRV_OBJ_SUFFIX IDL_SRV_O IDL_SRV_CPP_SUFFIX IDL_SRV_CPP IDL_SRV_H1_SUFFIX IDL_SRV_H_SUFFIX IDL_SRV_H IDL_CLN_OBJ_SUFFIX IDL_CLN_O IDL_CLN_CPP_SUFFIX IDL_CLN_CPP IDL_CLN_H1_SUFFIX IDL_CLN_H_SUFFIX IDL_CLN_H IDL_H1_SUFFIX IDL_H_SUFFIX ORB_INCLUDE_PREFIX IDLFLAGS IDLCXX IDL ORB ORB_PREFIX CORBA_INCLUDES omniCOS4_LIBS omniCOS4_CFLAGS omniORB4_LIBS omniORB4_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG IDLCXXFLAGS ZLIB_CPPFLAGS ZLIB_LIBS ZLIB_LDFLAGS OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED LIBTOOL TANGO_DOC_ENABLED_FALSE TANGO_DOC_ENABLED_TRUE TANGO_FIG2DEV_ENABLED_FALSE TANGO_FIG2DEV_ENABLED_TRUE FIG2DEV TANGO_LYX_ENABLED_FALSE TANGO_LYX_ENABLED_TRUE LYX DOXYGEN TANGO_JAVA_ENABLED_FALSE TANGO_JAVA_ENABLED_TRUE JAVA CPP_ELEVEN HAVE_CXX11 EGREP GREP LN_S CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM host_os host_vendor host_cpu host build_os build_vendor build_cpu build MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_silent_rules enable_dependency_tracking enable_java enable_mariadb with_java with_doxygen with_lyx with_fig2dev enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock with_zlib with_omni with_zmq enable_dbserver with_tango_rc_file with_tango_db_name with_mysqlclient_prefix with_mysqlclient_include with_mysqlclient_lib enable_dbcreate with_mysql_ho with_mysql_admin with_mysql_admin_passwd with_mariadbclient_prefix with_mariadbclient_include with_mariadbclient_lib enable_jpegmmx ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CXXCPP CC CFLAGS CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR omniORB4_CFLAGS omniORB4_LIBS omniCOS4_CFLAGS omniCOS4_LIBS LIBZMQ_CFLAGS LIBZMQ_LIBS' ac_subdirs_all='lib/cpp/log4tango' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Tango 9.2.5a to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/tango] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Tango 9.2.5a:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0') --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-java enable installation of Java applications --enable-mariadb enable mariadb instead of mysql --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-dbserver enable installation of Tango database server --enable-dbcreate enable an creation of the Tango database schema --disable-jpegmmx disable jpeg mmx optimization Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-java path to java interpreter --with-doxygen path to doxygen utility --with-lyx path to LyX utility --with-fig2dev path to fig2dev utility --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-zlib=DIR root directory path of zlib installation defaults to /usr/local or /usr if not found in /usr/local --with-omni prefix to omniORB installation (default: $OMNI_ROOT) --with-zmq prefix to ZMQ installation --with-tango-rc-file location of the tango rc file (default /etc/tangorc) --with-tango-db-name the name of the tango database (default tango) --with-mysqlclient-prefix=PFX Prefix where mysqlclient is installed --with-mysqlclient-include=DIR Directory pointing to mysqlclient include files --with-mysqlclient-lib=LIB Directory pointing to mysqlclient library (Note: -include and -lib do override paths found with -prefix) --with-mysql-ho the host of the mysql database (default: ) --with-mysql-admin super user of your mysql database (default: ) --with-mysql-admin-passwd super user password of your mysql database (default: ) --with-mariadbclient-prefix=PFX Prefix where mariadbclient is installed --with-mariadbclient-include=DIR Directory pointing to mariadbclient include files --with-mariadbclient-lib=LIB Directory pointing to mariadbclient library (Note: -include and -lib do override paths found with -prefix) Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXXCPP C++ preprocessor CC C compiler command CFLAGS C compiler flags CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path omniORB4_CFLAGS C compiler flags for omniORB4, overriding pkg-config omniORB4_LIBS linker flags for omniORB4, overriding pkg-config omniCOS4_CFLAGS C compiler flags for omniCOS4, overriding pkg-config omniCOS4_LIBS linker flags for omniCOS4, overriding pkg-config LIBZMQ_CFLAGS C compiler flags for LIBZMQ, overriding pkg-config LIBZMQ_LIBS linker flags for LIBZMQ, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Tango configure 9.2.5a generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------------- ## ## Report this to info@tango-controls.org ## ## -------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------------- ## ## Report this to info@tango-controls.org ## ## -------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Tango $as_me 9.2.5a, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Tells autoconf that we want at least version 2.53 of autoconf to # create configure from configure.ac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Lets the revision tag from cvs or rcs propagate into the # configure script, handy for debugging. # AM_INIT_AUTOMAKE sets up automake which is used to generate # Makefile.in from Makefile.am am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='tango' VERSION='9.2.5a' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # Tells automake to use `ac_config.h.tmp' to stash all the #defines # that result from a run of configure. # The name is .tmp since I must change the PACKAGE_ definitions because # of omniORBS installation of their version of this file. ac_config_headers="$ac_config_headers ac_config.h.tmp" # -version-info CURRENT[:REVISION[:AGE]] # From the libtool documentation (info libtool) # So, libtool library versions are described by three integers: # CURRENT # The most recent interface number that this library implements. # REVISION # The implementation number of the CURRENT interface. # AGE # The difference between the newest and oldest interfaces that this # library implements. In other words, the library implements all the # interface numbers in the range from number `CURRENT - AGE' to # `CURRENT'. VERSION_INFO=11:5:2 # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi # Check gcc release if test "$CXX" = "c++" -o "$CXX" = "g++" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc compiler release (at least version 3.2.0)" >&5 $as_echo_n "checking for gcc compiler release (at least version 3.2.0)... " >&6; } if ${ac_cv_gcc_version_3_2_0+:} false; then : $as_echo_n "(cached) " >&6 else if test x$GCC = x ; then ac_cv_gcc_version_3_2_0=no else ac_gcc_date=0 ; cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define HAVE_GCC_VERSION(MAJOR, MINOR, MICRO, DATE) \ (__GNUC__ > (MAJOR) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ > (MINOR)) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ == (MINOR) \ && __GNUC_PATCHLEVEL__ > (MICRO)) \ || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ == (MINOR) \ && __GNUC_PATCHLEVEL__ == (MICRO) && ${ac_gcc_date}L >= (DATE))) #if HAVE_GCC_VERSION(3,2,0,0) yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then : ac_cv_gcc_version_3_2_0=yes else ac_cv_gcc_version_3_2_0=no fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_version_3_2_0" >&5 $as_echo "$ac_cv_gcc_version_3_2_0" >&6; } if test x$ac_cv_gcc_version_3_2_0 = xyes; then cat >>confdefs.h <<_ACEOF #define HAVE_GCC_VERSION_3_2_0 1 _ACEOF fi if test "x$ac_cv_gcc_version_3_2_0" = "xno"; then as_fn_error -1 "Not supported gcc release. Should be 3.2.0 or above. Please update !" "$LINENO" 5 fi fi # Check if compiler support C++11 ax_cxx_compile_cxx11_required=falsednl ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 $as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } if ${ax_cv_cxx_compile_cxx11+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_cxx_compile_cxx11=yes else ax_cv_cxx_compile_cxx11=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 $as_echo "$ax_cv_cxx_compile_cxx11" >&6; } if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for switch in -std=c++11 -std=c++0x; do cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 $as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval \${$cachevar+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval $cachevar=yes else eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS="$ac_save_CXXFLAGS" fi eval ac_res=\$$cachevar { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 fi else if test x$ac_success = xno; then HAVE_CXX11=0 { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 $as_echo "$as_me: No compiler with C++11 support was found" >&6;} else HAVE_CXX11=1 CPP_ELEVEN=$switch $as_echo "#define HAVE_CXX11 1" >>confdefs.h fi fi # Check if Java interpreter is there # Check whether --enable-java was given. if test "${enable_java+set}" = set; then : enableval=$enable_java; else enable_java=yes fi # Check whether --enable-mariadb was given. if test "${enable_mariadb+set}" = set; then : enableval=$enable_mariadb; enable_mariadb=yes else enable_mariadb=no fi # Check whether --with-java was given. if test "${with_java+set}" = set; then : withval=$with_java; JAVA=${with_java} else with_java=yes fi if test "x$enable_java" = "xyes" ; then if test "x$with_java" = "xno" -o -z "$with_java"; then with_java= enable_java=no else if test "x$with_java" = "xyes"; then # Extract the first word of "java", so it can be a program name with args. set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_JAVA+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVA in [\\/]* | ?:[\\/]*) ac_cv_path_JAVA="$JAVA" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_JAVA="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_JAVA" && ac_cv_path_JAVA=""notfound"" ;; esac fi JAVA=$ac_cv_path_JAVA if test -n "$JAVA"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5 $as_echo "$JAVA" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$JAVA" != "xnotfound"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for java release (at least version 1.7)" >&5 $as_echo_n "checking for java release (at least version 1.7)... " >&6; } if ${ac_cv_java_version_1_7+:} false; then : $as_echo_n "(cached) " >&6 else if test -x $JAVA -a -f $JAVA; then VERS=`$JAVA -version 2>&1 | grep version | cut -d '"' -f 2` JAVA_VERSION=$VERS JAVA_MAJOR=`echo $VERS | cut -d '.' -f 1` JAVA_MINOR=`echo $VERS | cut -d '.' -f 2` JAVA_MICRO=`echo $VERS | cut -d '.' -f 3` if test $JAVA_MAJOR -lt 1; then ac_cv_java_version_1_7=no else if test $JAVA_MINOR -lt 7; then ac_cv_java_version_1_7=no else ac_cv_java_version_1_7=yes fi fi else ac_cv_java_version_1_7=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_java_version_1_7" >&5 $as_echo "$ac_cv_java_version_1_7" >&6; } if test "x$ac_cv_java_version_1_7" = "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not supported java release. Should be 1.7.x or above. Java will be disabled for this build!" >&5 $as_echo "$as_me: WARNING: Not supported java release. Should be 1.7.x or above. Java will be disabled for this build!" >&2;} with_java= enable_java=no else with_java=$JAVA fi else with_java= enable_java=no fi fi else with_java= fi # Define a conditional variable to enable or disable installation # of java applications. The variable is used in the Makefiles. # if test x"$enable_java" != x"no"; then TANGO_JAVA_ENABLED_TRUE= TANGO_JAVA_ENABLED_FALSE='#' else TANGO_JAVA_ENABLED_TRUE='#' TANGO_JAVA_ENABLED_FALSE= fi # Check if doxygen is there # Check whether --with-doxygen was given. if test "${with_doxygen+set}" = set; then : withval=$with_doxygen; DOXYGEN=${with_doxygen} else # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 $as_echo "$DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$DOXYGEN"; then DOXYGEN=NOT_INSTALLED fi # Check if lyx is there # Check whether --with-lyx was given. if test "${with_lyx+set}" = set; then : withval=$with_lyx; LYX=${with_lyx} else # Extract the first word of "lyx", so it can be a program name with args. set dummy lyx; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LYX+:} false; then : $as_echo_n "(cached) " >&6 else case $LYX in [\\/]* | ?:[\\/]*) ac_cv_path_LYX="$LYX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LYX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LYX=$ac_cv_path_LYX if test -n "$LYX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LYX" >&5 $as_echo "$LYX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$LYX"; then LYX="false" fi if test x"$LYX" != x"false"; then TANGO_LYX_ENABLED_TRUE= TANGO_LYX_ENABLED_FALSE='#' else TANGO_LYX_ENABLED_TRUE='#' TANGO_LYX_ENABLED_FALSE= fi # Check if fig2dev is there # Check whether --with-fig2dev was given. if test "${with_fig2dev+set}" = set; then : withval=$with_fig2dev; FIG2DEV=${with_fig2dev} else # Extract the first word of "fig2dev", so it can be a program name with args. set dummy fig2dev; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_FIG2DEV+:} false; then : $as_echo_n "(cached) " >&6 else case $FIG2DEV in [\\/]* | ?:[\\/]*) ac_cv_path_FIG2DEV="$FIG2DEV" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_FIG2DEV="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi FIG2DEV=$ac_cv_path_FIG2DEV if test -n "$FIG2DEV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FIG2DEV" >&5 $as_echo "$FIG2DEV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$FIG2DEV"; then FIG2DEV="false" fi if test x"$FIG2DEV" != x"false"; then TANGO_FIG2DEV_ENABLED_TRUE= TANGO_FIG2DEV_ENABLED_FALSE='#' else TANGO_FIG2DEV_ENABLED_TRUE='#' TANGO_FIG2DEV_ENABLED_FALSE= fi if test x"$LYX" != x"false" && test x"$FIG2DEV" != x"false"; then TANGO_DOC_ENABLED_TRUE= TANGO_DOC_ENABLED_FALSE='#' else TANGO_DOC_ENABLED_TRUE='#' TANGO_DOC_ENABLED_FALSE= fi # Use libtool which facilitates the creation of shared libraries case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: # check for the presence of zlib # # Handle user hints # { $as_echo "$as_me:${as_lineno-$LINENO}: checking if zlib is wanted" >&5 $as_echo_n "checking if zlib is wanted... " >&6; } # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; if test "$withval" != no ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ZLIB_HOME="$withval" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ZLIB_HOME=/usr/local if test ! -f "${ZLIB_HOME}/include/zlib.h" then ZLIB_HOME=/usr fi fi # # Locate zlib, if wanted # if test -n "${ZLIB_HOME}" then ZLIB_OLD_LDFLAGS=$LDFLAGS ZLIB_OLD_LIBS=$LIBS ZLIB_OLD_CPPFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateEnd in -lz" >&5 $as_echo_n "checking for inflateEnd in -lz... " >&6; } if ${ac_cv_lib_z_inflateEnd+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflateEnd (); int main () { return inflateEnd (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_inflateEnd=yes else ac_cv_lib_z_inflateEnd=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateEnd" >&5 $as_echo "$ac_cv_lib_z_inflateEnd" >&6; } if test "x$ac_cv_lib_z_inflateEnd" = xyes; then : zlib_cv_libz=yes else zlib_cv_libz=no fi ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : zlib_cv_zlib_h=yes else zlib_cv_zlib_h=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes" then # # If both library and header were found, use them # # AC_CHECK_LIB(z, inflateEnd) # AC_MSG_CHECKING(zlib in ${ZLIB_HOME}) # AC_MSG_RESULT(ok) ZLIB_CPPFLAGS="-I${ZLIB_HOME}/include" ZLIB_LDFLAGS="-L${ZLIB_HOME}/lib" ZLIB_LIBS="-lz" else # # If either header or library was not found, revert and bomb # as_fn_error $? "either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib" "$LINENO" 5 fi LDFLAGS="$ZLIB_OLD_LDFLAGS" CPPFLAGS="$ZLIB_OLD_CPPFLAGS" LIBS="$ZLIB_OLD_LIBS" fi # This macro checks for omniorb and sets various defines, please # consult config/RSSH_CHECK_OMNIORB for more details { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether using Sun Worckshop C++ compiler" >&5 $as_echo_n "checking whether using Sun Worckshop C++ compiler... " >&6; } if ${rssh_cv_check_sunpro_cc+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __SUNPRO_CC # include "error: this is not Sun Workshop." #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : rssh_cv_check_sunpro_cc=yes else rssh_cv_check_sunpro_cc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rssh_cv_check_sunpro_cc" >&5 $as_echo "$rssh_cv_check_sunpro_cc" >&6; } if test ${rssh_cv_check_sunpro_cc} = yes then : else : fi ac_fn_cxx_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = xyes; then : $as_echo "#define HAVE_PTHREAD_H 1" >>confdefs.h fi if test x$rssh_cv_check_sunpro_c = xyes then CFLAGS_PTHREADS="-mt" fi if test x$rssh_cv_check_sunpro_cc = xyes then CXXFLAGS_PTHREADS="-mt" fi case $build_os in freebsd*) CFLAGS_PTHREADS="-pthread" CXXFLAGS_PTHREADS="-pthread" freebsd_pthreads=yes ;; *) freebsd_pthreads=no ;; esac if test x$freebsd_pthreads = xno then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : LIBS_PTHREADS="-lpthread" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lposix4" >&5 $as_echo_n "checking for nanosleep in -lposix4... " >&6; } if ${ac_cv_lib_posix4_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix4 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_posix4_nanosleep=yes else ac_cv_lib_posix4_nanosleep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix4_nanosleep" >&5 $as_echo "$ac_cv_lib_posix4_nanosleep" >&6; } if test "x$ac_cv_lib_posix4_nanosleep" = xyes; then : LIBS_PTHREADS="$LIBS_PTHREADS -lposix4" fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi # Check whether --with-omni was given. if test "${with_omni+set}" = set; then : withval=$with_omni; \ OMNI_PREFIX=${with_omni} else OMNI_PREFIX=/usr/local fi if test "x$OMNI_ROOT" = "x" then if test "x$OMNI_PREFIX" = "x" then OMNI_ROOT="/usr/local" else OMNI_ROOT="$OMNI_PREFIX" fi fi if test "x$OMNI_PREFIX" = "xno" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: omniORB is disabled" >&5 $as_echo "omniORB is disabled" >&6; } omni=no else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu svCXXCPPFLAGS=$CXXCPPFLAGS svCXXFLAGS=$CXXFLAGS svCPPFLAGS=$CPPFLAGS svLIBS=$LIBS svLDFLAGS=$LDFLAGS svRSSH_ROLLBACK=$rssh_rollback rssh_rollback="true" ORB_INCLUDES="-I$OMNI_ROOT/include" CXXCPPFLAGS="$CXXCPPFLAGS -I$OMNI_ROOT/include " CPPFLAGS="$CPPFLAGS -I$OMNI_ROOT/include " if test -z "$rssh_enable_pthreads_done" then CFLAGS="$CFLAGS $CFLAGS_PTHREADS" CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" LIBS="$LIBS $LIBS_PTHREADS" fi rssh_enable_pthreads_done=yes rssh_rollback="$rssh_rollback; rssh_enable_pthreads_done=" case $build_cpu in sparc*) $as_echo "#define __sparc__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -D__sparc__" ;; "i686"|"i586"|"i486"|"i386") $as_echo "#define __x86__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -D__x86__" ;; esac SL_SUFFIX=so case $build_os in darwin*) $as_echo "#define __darwin__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -D__darwin__" SL_SUFFIX=dylib ;; solaris*) $as_echo "#define __sunos__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -D__sunos__" __OSVERSION__=5 cat >>confdefs.h <<_ACEOF #define __OSVERSION__ $__OSVERSION__ _ACEOF IDLCXXFLAGS="$IDLCXXFLAGS -D__OSVERSION__=5" ;; freebsd*) $as_echo "#define __freebsd__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -D__freebsd__" ;; hpux*) $as_echo "#define __hpux__ 1" >>confdefs.h IDLCXXFLAGS="$IDLCXXFLAGS -AA -mt -D__hpux__ -D__hppa__ -D__OMNIORB4__" __OSVERSION__=11 cat >>confdefs.h <<_ACEOF #define __OSVERSION__ $__OSVERSION__ _ACEOF IDLCXXFLAGS="$IDLCXXFLAGS -D__OSVERSION__=11" SL_SUFFIX=sl ;; esac CXXCPPFLAGS="$CXXCPPFLAGS $IDLCXXFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "omniORB4/CORBA.h" "ac_cv_header_omniORB4_CORBA_h" "$ac_includes_default" if test "x$ac_cv_header_omniORB4_CORBA_h" = xyes; then : omni=yes else omni=no fi if test "x$omni" = "xyes" then ORB_LIBDIR="$OMNI_ROOT/lib" if test ! -r "$ORB_LIBDIR/libomniORB4.$SL_SUFFIX" then for i in $OMNI_ROOT/lib/*/lib*.$SL_SUFFIX do ORB_LIBDIR=`dirname $i` break; done fi LIBS="$LIBS -lomnithread" svLIBS=$LIBS LIBS="-L$ORB_LIBDIR $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for omnithreads" >&5 $as_echo_n "checking for omnithreads... " >&6; } if ${rssh_cv_check_omnithreads+:} false; then : $as_echo_n "(cached) " >&6 else rssh_enable_pthreads_done="" if test -z "$rssh_enable_pthreads_done" then CFLAGS="$CFLAGS $CFLAGS_PTHREADS" CXXFLAGS="$CXXFLAGS $CXXFLAGS_PTHREADS" LIBS="$LIBS $LIBS_PTHREADS" fi rssh_enable_pthreads_done=yes rssh_rollback="$rssh_rollback; rssh_enable_pthreads_done=" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { omni_mutex my_mutex ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : rssh_cv_check_omnithreads=yes else rssh_cv_check_omnithreads=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rssh_cv_check_omnithreads" >&5 $as_echo "$rssh_cv_check_omnithreads" >&6; } if test ! $rssh_cv_check_omnithreads = yes then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"omnithreads not found\"" >&5 $as_echo "\"omnithreads not found\"" >&6; } omni_lib=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 $as_echo_n "checking for socket in -lsocket... " >&6; } if ${ac_cv_lib_socket_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_socket_socket=yes else ac_cv_lib_socket_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 $as_echo "$ac_cv_lib_socket_socket" >&6; } if test "x$ac_cv_lib_socket_socket" = xyes; then : LIBS="-lsocket $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : LIBS="-lnsl $LIBS" fi ORB_LDFLAGS="-L$ORB_LIBDIR" LIBS="$ORB_LDFLAGS -lomniORB4 -lomniDynamic4 -lCOS4 $svLIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can link with omniORB4" >&5 $as_echo_n "checking whether we can link with omniORB4... " >&6; } if ${rssh_cv_check_omniORBlib+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CORBA::ORB_var orb ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : rssh_cv_check_omniORBlib=yes else rssh_cv_check_omniORBlib=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rssh_cv_check_omniORBlib" >&5 $as_echo "$rssh_cv_check_omniORBlib" >&6; } if test ! $rssh_cv_check_omniORBlib = yes then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"omniORB libs not found\"" >&5 $as_echo "\"omniORB libs not found\"" >&6; } omni_lib=no fi ORB_LIBS="$ORB_LDFLAGS -lomniORB4 -lomnithread" fi if test "x$omni_lib" = "xno" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: omniORB library linking failed" >&5 $as_echo "omniORB library linking failed" >&6; } omni="no" fi fi export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$OMNI_ROOT/lib/pkgconfig pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for omniORB4" >&5 $as_echo_n "checking for omniORB4... " >&6; } if test -n "$omniORB4_CFLAGS"; then pkg_cv_omniORB4_CFLAGS="$omniORB4_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"omniORB4 >= 4.1.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "omniORB4 >= 4.1.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_omniORB4_CFLAGS=`$PKG_CONFIG --cflags "omniORB4 >= 4.1.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$omniORB4_LIBS"; then pkg_cv_omniORB4_LIBS="$omniORB4_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"omniORB4 >= 4.1.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "omniORB4 >= 4.1.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_omniORB4_LIBS=`$PKG_CONFIG --libs "omniORB4 >= 4.1.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then omniORB4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "omniORB4 >= 4.1.2" 2>&1` else omniORB4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "omniORB4 >= 4.1.2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$omniORB4_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (omniORB4 >= 4.1.2) were not met: $omniORB4_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables omniORB4_CFLAGS and omniORB4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables omniORB4_CFLAGS and omniORB4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else omniORB4_CFLAGS=$pkg_cv_omniORB4_CFLAGS omniORB4_LIBS=$pkg_cv_omniORB4_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for omniCOS4" >&5 $as_echo_n "checking for omniCOS4... " >&6; } if test -n "$omniCOS4_CFLAGS"; then pkg_cv_omniCOS4_CFLAGS="$omniCOS4_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"omniCOS4 >= 4.1.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "omniCOS4 >= 4.1.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_omniCOS4_CFLAGS=`$PKG_CONFIG --cflags "omniCOS4 >= 4.1.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$omniCOS4_LIBS"; then pkg_cv_omniCOS4_LIBS="$omniCOS4_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"omniCOS4 >= 4.1.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "omniCOS4 >= 4.1.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_omniCOS4_LIBS=`$PKG_CONFIG --libs "omniCOS4 >= 4.1.2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then omniCOS4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "omniCOS4 >= 4.1.2" 2>&1` else omniCOS4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "omniCOS4 >= 4.1.2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$omniCOS4_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (omniCOS4 >= 4.1.2) were not met: $omniCOS4_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables omniCOS4_CFLAGS and omniCOS4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables omniCOS4_CFLAGS and omniCOS4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else omniCOS4_CFLAGS=$pkg_cv_omniCOS4_CFLAGS omniCOS4_LIBS=$pkg_cv_omniCOS4_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi if test -x $OMNI_ROOT/include/omniORB4 then VERS=`grep VERSION $OMNI_ROOT/include/omniORB4/acconfig.h 2>&1 | cut -d ' ' -f 3` OMNI_VERSION=$VERS fi if test "x$omni" = "x" -o "x$omni" = "xno" then CXXCPPFLAGS=$svCXXCPPFLAGS CPPFLAGS=$svCPPFLAGS LIBS=$svLIBS LDFLAGS=$svLDFLAGS ORB=unknown omni=no eval "$rssh_rollback" rssh_rollback=$svRSSH_ROLLBACK else ORB_PREFIX=$OMNI_ROOT ORB=omniORB IDL=omniidl if test -x $OMNI_ROOT/bin/omniidl then IDL=$OMNI_ROOT/bin/omniidl else for i in $OMNI_ROOT/bin/*/omniidl do if test "$i" != $OMNI_ROOT'/bin/*/omniidl' then IDL=$i break fi done fi IDLCXX=$IDL IDLFLAGS="$IDLFLAGS -bcxx -I$OMNI_ROOT/idl" ORB_INCLUDE_PREFIX=$ORB_INCLUDES IDL_H_SUFFIX=.hh IDL_H1_SUFFIX=no IDL_CLN_H=.hh IDL_CLN_H_SUFFIX=.hh IDL_CLN_H1_SUFFIX=no IDL_CLN_H=$IDL_CLN_H IDL_CLN_H_SUFFIX=$IDL_CLN_H_SUFFIX IDL_CLN_H1_SUFFIX=$IDL_CLN_H1_SUFFIX cat >>confdefs.h <<_ACEOF #define IDL_CLN_H_SUFFIX $IDL_CLN_H_SUFFIX _ACEOF IDL_CLN_CPP=SK.cc IDL_CLN_CPP_SUFFIX=SK.cc IDL_CLN_CPP=$IDL_CLN_CPP IDL_CLN_CPP_SUFFIX=$IDL_CLN_CPP_SUFFIX cat >>confdefs.h <<_ACEOF #define IDL_CLN_CPP_SUFFIX $IDL_CLN_CPP _ACEOF IDL_CLN_O=SK.o IDL_CLN_OBJ_SUFFIX=SK.o IDL_CLN_O=$IDL_CLN_O IDL_CLN_OBJ_SUFFIX=$IDL_CLN_OBJ_SUFFIX IDL_SRV_H=.hh IDL_SRV_H_SUFFIX=.hh IDL_SRV_H1_SUFFIX=no IDL_SRV_H=$IDL_SRV_H IDL_SRV_H_SUFFIX=$IDL_SRV_H_SUFFIX IDL_SRV_H1_SUFFIX=$IDL_SRV_H1_SUFFIX cat >>confdefs.h <<_ACEOF #define IDL_SRV_H_SUFFIX $IDL_SRV_H_SUFFIX _ACEOF IDL_SRV_CPP=SK.cc IDL_SRV_CPP_SUFFIX=SK.cc IDL_SRV_CPP=$IDL_SRV_CPP IDL_SRV_CPP_SUFFIX=$IDL_SRV_CPP_SUFFIX cat >>confdefs.h <<_ACEOF #define IDL_SRV_H_SUFFIX $IDL_SRV_H_SUFFIX _ACEOF IDL_SRV_O=SK.o IDL_SRV_OBJ_SUFFIX=SK.o IDL_SRV_O=$IDL_SRV_O IDL_SRV_OBJ_SUFFIX=$IDL_SRV_OBJ_SUFFIX IDL_TIE_H_SUFFIX=no IDL_TIE_H1_SUFFIX=no IDL_TIE_CPP_SUFFIX=no IDL_TIE_H_SUFFIX=$IDL_TIE_H_SUFFIX IDL_TIE_H1_SUFFIX=$IDL_TIE_H1_SUFFIX IDL_TIE_CPP_SUFFIX=$IDL_TIE_CPP_SUFFIX CORBA_H='omniORB4/CORBA.h' cat >>confdefs.h <<_ACEOF #define CORBA_H <$CORBA_H> _ACEOF COSNAMING_H='omniORB4/Naming.hh' cat >>confdefs.h <<_ACEOF #define COSNAMING_H <$COSNAMING_H> _ACEOF ORB_COSNAMING_LIB= HAVE_ORB_IDL=1 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CORBA modules mapped to namespaces" >&5 $as_echo_n "checking whether CORBA modules mapped to namespaces... " >&6; } if ${rssh_cv_corba_namespaces+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$CORBA_H> int main () { #ifndef HAS_Cplusplus_Namespace #error "we have no namespaces" we have no namespaces -- $$$$ #else return 0; #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : rssh_cv_corba_namespaces=yes else rssh_cv_corba_namespaces=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rssh_cv_corba_namespaces" >&5 $as_echo "$rssh_cv_corba_namespaces" >&6; } if test "$rssh_cv_corba_namespaces" = "yes" then $as_echo "#define CORBA_MODULE_NAMESPACE_MAPPING 1" >>confdefs.h else $as_echo "#define CORBA_MODULE_CLASS_MAPPING 1" >>confdefs.h fi $as_echo "#define OMNIORB 1" >>confdefs.h CORBA_HAVE_POA=1 $as_echo "#define CORBA_HAVE_POA 1" >>confdefs.h CORBA_ORB_INIT_HAVE_3_ARGS=1 $as_echo "#define CORBA_ORB_INIT_HAVE_3_ARGS 1" >>confdefs.h CORBA_ORB_INIT_THIRD_ARG='"omniORB4"' $as_echo "#define CORBA_ORB_INIT_THIRD_ARG \"omniORB4\"" >>confdefs.h $as_echo "#define CORBA_ORB_HAVE_DESTROY 1" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu enable_lib=yes # ZMQ dependency # Check whether --with-zmq was given. if test "${with_zmq+set}" = set; then : withval=$with_zmq; \ ZMQ_PREFIX=${with_zmq} else ZMQ_PREFIX=/usr/local fi PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${ZMQ_PREFIX}/lib/pkgconfig pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBZMQ" >&5 $as_echo_n "checking for LIBZMQ... " >&6; } if test -n "$LIBZMQ_CFLAGS"; then pkg_cv_LIBZMQ_CFLAGS="$LIBZMQ_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzmq >= 4.0.5\""; } >&5 ($PKG_CONFIG --exists --print-errors "libzmq >= 4.0.5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBZMQ_CFLAGS=`$PKG_CONFIG --cflags "libzmq >= 4.0.5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBZMQ_LIBS"; then pkg_cv_LIBZMQ_LIBS="$LIBZMQ_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzmq >= 4.0.5\""; } >&5 ($PKG_CONFIG --exists --print-errors "libzmq >= 4.0.5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBZMQ_LIBS=`$PKG_CONFIG --libs "libzmq >= 4.0.5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBZMQ_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzmq >= 4.0.5" 2>&1` else LIBZMQ_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzmq >= 4.0.5" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBZMQ_PKG_ERRORS" >&5 as_fn_error $? "Missing ZMQ library - Use --with-zmq configure option or add directory containing libzmq.pc to PKG_CONFIG_PATH environment variable" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Missing ZMQ library - Use --with-zmq configure option or add directory containing libzmq.pc to PKG_CONFIG_PATH environment variable" "$LINENO" 5 else LIBZMQ_CFLAGS=$pkg_cv_LIBZMQ_CFLAGS LIBZMQ_LIBS=$pkg_cv_LIBZMQ_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi ZMQ_VERSION=`eval pkg-config --modversion libzmq` ZMQ_ROOT=`eval pkg-config --variable=prefix libzmq` # We need to define some stuff for threads and stubs case $build_os in linux*) $as_echo "#define _REENTRANT 1" >>confdefs.h CXXFLAGS="$CXXFLAGS -D_REENTRANT" ;; darwin*) $as_echo "#define _REENTRANT 1" >>confdefs.h CXXFLAGS="$CXXFLAGS -D_REENTRANT -D__darwin__" DARWIN=yes esac # condition used in the Makefile of the Tango library if test x"$DARWIN" = x"yes" ; then DARWIN_ENABLED_TRUE= DARWIN_ENABLED_FALSE='#' else DARWIN_ENABLED_TRUE='#' DARWIN_ENABLED_FALSE= fi # we want to include the omniORB stubs into the tango library CXXFLAGS="$CXXFLAGS -DOMNI_UNLOADABLE_STUBS" # checks for libdl { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi # checks for libnsl { $as_echo "$as_me:${as_lineno-$LINENO}: checking for svc_pollfd in -lnsl" >&5 $as_echo_n "checking for svc_pollfd in -lnsl... " >&6; } if ${ac_cv_lib_nsl_svc_pollfd+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char svc_pollfd (); int main () { return svc_pollfd (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_svc_pollfd=yes else ac_cv_lib_nsl_svc_pollfd=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_svc_pollfd" >&5 $as_echo "$ac_cv_lib_nsl_svc_pollfd" >&6; } if test "x$ac_cv_lib_nsl_svc_pollfd" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi # checks for libposix4 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lposix4" >&5 $as_echo_n "checking for nanosleep in -lposix4... " >&6; } if ${ac_cv_lib_posix4_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix4 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nanosleep (); int main () { return nanosleep (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_posix4_nanosleep=yes else ac_cv_lib_posix4_nanosleep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix4_nanosleep" >&5 $as_echo "$ac_cv_lib_posix4_nanosleep" >&6; } if test "x$ac_cv_lib_posix4_nanosleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPOSIX4 1 _ACEOF LIBS="-lposix4 $LIBS" fi # checks for libpthread { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi # checks for libsocket { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getprotobyname in -lsocket" >&5 $as_echo_n "checking for getprotobyname in -lsocket... " >&6; } if ${ac_cv_lib_socket_getprotobyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getprotobyname (); int main () { return getprotobyname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_getprotobyname=yes else ac_cv_lib_socket_getprotobyname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getprotobyname" >&5 $as_echo "$ac_cv_lib_socket_getprotobyname" >&6; } if test "x$ac_cv_lib_socket_getprotobyname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in fcntl.h strings.h sys/time.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Some hack for testing if we have sstream or not. use_sstream=yes; if test "x$GCC" = "xyes"; then case `$CC --version 2>/dev/null` in [12].*) use_sstream=no ;; *) use_sstream=yes ;; esac fi if test "x$use_sstream" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler implements namespaces" >&5 $as_echo_n "checking whether the compiler implements namespaces... " >&6; } if ${ac_cv_cxx_namespaces+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace Outer { namespace Inner { int i = 0; }} int main () { using namespace Outer::Inner; return i; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxx_namespaces=yes else ac_cv_cxx_namespaces=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_namespaces" >&5 $as_echo "$ac_cv_cxx_namespaces" >&6; } if test "$ac_cv_cxx_namespaces" = yes; then $as_echo "#define HAVE_NAMESPACES /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler has stringstream" >&5 $as_echo_n "checking whether the compiler has stringstream... " >&6; } if ${ac_cv_cxx_have_sstream+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_NAMESPACES using namespace std; #endif int main () { stringstream message; message << "Hello"; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxx_have_sstream=yes else ac_cv_cxx_have_sstream=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_have_sstream" >&5 $as_echo "$ac_cv_cxx_have_sstream" >&6; } if test "$ac_cv_cxx_have_sstream" = yes; then $as_echo "#define HAVE_SSTREAM /**/" >>confdefs.h fi fi # This needs to be worked on!! if test "x$use_sstream" = "xno"; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_header_mongrel "$LINENO" "strstream" "ac_cv_header_strstream" "$ac_includes_default" if test "x$ac_cv_header_strstream" = xyes; then : $as_echo "#define HAVE_STRSTREAM 1" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi # Checks for library functions. # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5 $as_echo_n "checking whether sys/types.h defines makedev... " >&6; } if ${ac_cv_header_sys_types_h_makedev+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return makedev(0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_header_sys_types_h_makedev=yes else ac_cv_header_sys_types_h_makedev=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5 $as_echo "$ac_cv_header_sys_types_h_makedev" >&6; } if test $ac_cv_header_sys_types_h_makedev = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mkdev_h" = xyes; then : $as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h fi if test $ac_cv_header_sys_mkdev_h = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then : $as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_func in gethostname gettimeofday exit tolower do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the library defines class strstream" >&5 $as_echo_n "checking whether the library defines class strstream... " >&6; } if ${ac_cv_cxx_have_class_strstream+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STRSTREAM # include #else # include #endif #ifdef HAVE_NAMESPACES using namespace std; #endif int main () { ostrstream message; message << "Hello"; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxx_have_class_strstream=yes else ac_cv_cxx_have_class_strstream=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_have_class_strstream" >&5 $as_echo "$ac_cv_cxx_have_class_strstream" >&6; } if test "$ac_cv_cxx_have_class_strstream" = yes; then $as_echo "#define HAVE_CLASS_STRSTREAM 1" >>confdefs.h fi # check for the presence of the mysql program, needed when doing the # install of the DataBaseds server. You can tweak the connection # with some --with variables. ./configure --help will, uhm, help you. # Check whether --enable-dbserver was given. if test "${enable_dbserver+set}" = set; then : enableval=$enable_dbserver; else enable_dbserver=yes fi enable_db_schema_create=no # Check whether --with-tango-rc-file was given. if test "${with_tango_rc_file+set}" = set; then : withval=$with_tango_rc_file; TANGO_RC_FILE=${with_tango_rc_file} else TANGO_RC_FILE=/etc/tangorc fi cat >>confdefs.h <<_ACEOF #define TANGO_RC_FILE "$TANGO_RC_FILE" _ACEOF # Hacks to provide the name for the tango # database. I havent found any other way to provide these arguments. # Check whether --with-tango-db-name was given. if test "${with_tango_db_name+set}" = set; then : withval=$with_tango_db_name; TANGO_DB_NAME=${with_tango_db_name} else TANGO_DB_NAME=tango fi # Here we define these constants so that they're reachable from c programs cat >>confdefs.h <<_ACEOF #define TANGO_DB_NAME "$TANGO_DB_NAME" _ACEOF # Here we propagate the constants into the makefiles. if test "x$enable_mariadb" != "xyes" ; then DB_NAME=MYSQL if test "x$enable_dbserver" = "xyes"; then : # We need libmysqlclient to compile # finds it for us. Abort if no mysqlclientlibs are found # Check whether --with-mysqlclient-prefix was given. if test "${with_mysqlclient_prefix+set}" = set; then : withval=$with_mysqlclient_prefix; mysqlclient_prefix="$withval" else mysqlclient_prefix="" fi # Check whether --with-mysqlclient-include was given. if test "${with_mysqlclient_include+set}" = set; then : withval=$with_mysqlclient_include; mysqlclient_include="$withval" else mysqlclient_include="" fi # Check whether --with-mysqlclient-lib was given. if test "${with_mysqlclient_lib+set}" = set; then : withval=$with_mysqlclient_lib; mysqlclient_lib="$withval" else mysqlclient_lib="" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysqlclient " >&5 $as_echo_n "checking for mysqlclient ... " >&6; } MYSQLCLIENT_LDFLAGS="" MYSQLCLIENT_CFLAGS="" MYSQLCLIENT_LIBS="-lmysqlclient" mysqlclient_fail="" for tryprefix in /usr /usr/local /usr/mysql /usr/local/mysql /usr/pkg $mysqlclient_prefix ; do for hloc in lib/mysql lib ; do if test -f "$tryprefix/$hloc/libmysqlclient.so"; then MYSQLCLIENT_LDFLAGS="-L$tryprefix/$hloc" elif test -f "$tryprefix/$hloc/libmysqlclient.a"; then MYSQLCLIENT_LDFLAGS="-L$tryprefix/$hloc" fi done for iloc in include/mysql include; do if test -f "$tryprefix/$iloc/mysql.h"; then MYSQLCLIENT_CFLAGS="-I$tryprefix/$iloc" fi done # testloop done if test "x$mysqlclient_include" != "x" ; then echo "checking for mysql includes... " if test -d "$mysqlclient_include/mysql" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include" echo " found $MYSQLCLIENT_CFLAGS" elif test -d "$mysqlclient_include/include/mysql" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include/include" echo " found $MYSQLCLIENT_CFLAGS" elif test -d "$mysqlclient_include" ; then MYSQLCLIENT_CFLAGS="-I$mysqlclient_include" echo "found $MYSQLCLIENT_CFLAGS" else echo "not found! no include dir found in $mysqlclient_include" fi fi if test "x$mysqlclient_lib" != "x" ; then echo "checking for mysql libx... " if test -d "$mysqlclient_lib/lib/mysql" ; then MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib/lib/mysql" echo "found $MYSQLCLIENT_LDFLAGS" elif test -d "$mysqlclient_lib/lin" ; then MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib/lib" echo "found $MYSQLCLIENT_LDFLAGS" else MYSQLCLIENT_LDFLAGS="-L$mysqlclient_lib" echo "defaultd to $MYSQLCLIENT_LDFLAGS" fi fi ac_save_CFLAGS="$CFLAGS" ac_save_LDFLAGS="$LDFLAGS" ac_save_LIBS="$LIBS" CFLAGS="-v $CFLAGS $MYSQLCLIENT_CFLAGS" LDFLAGS="$LDFLAGS $MYSQLCLIENT_LDFLAGS" LIBS="$LIBS $MYSQLCLIENT_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { mysql_init( 0 ); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes $MYSQLCLIENT_CFLAGS $MYSQLCLIENT_LDFLAGS" >&5 $as_echo "yes $MYSQLCLIENT_CFLAGS $MYSQLCLIENT_LDFLAGS" >&6; } CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" : else echo "no" echo "can't compile a simple app with mysql_connnect in it. bad." mysqlclient_fail="yes" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$mysqlclient_fail" != "x" ; then echo echo "***" echo "*** mysqlclient test source had problems, check your config.log ." echo "*** Also try one of the following switches :" echo "*** --with-mysqlclient-prefix=PFX" echo "*** --with-mysqlclient-include=DIR" echo "*** --with-mysqlclient-lib=DIR" echo "***" CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" MYSQLCLIENT_LIBS="" MYSQLCLIENT_CFLAGS="" : fi CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" if test "x$MYSQLCLIENT_CFLAGS" = "x" then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No libmysqlclient libs found" >&5 $as_echo "$as_me: WARNING: No libmysqlclient libs found" >&2;} enable_dbserver=no fi DB_LDFLAGS=${MYSQLCLIENT_LDFLAGS} DB_LDLIBS=${MYSQLCLIENT_LIBS} DB_CFLAGS=${MYSQLCLIENT_CFLAGS} # Extract the first word of "mysql", so it can be a program name with args. set dummy mysql; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MYSQL+:} false; then : $as_echo_n "(cached) " >&6 else case $MYSQL in [\\/]* | ?:[\\/]*) ac_cv_path_MYSQL="$MYSQL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MYSQL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MYSQL" && ac_cv_path_MYSQL="nocommand" ;; esac fi MYSQL=$ac_cv_path_MYSQL if test -n "$MYSQL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL" >&5 $as_echo "$MYSQL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi MYSQL_VERSION=not_found if test "x$MYSQL" != "xnocommand"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql release (at least version 5.5)" >&5 $as_echo_n "checking for mysql release (at least version 5.5)... " >&6; } if ${ac_cv_mysql_version_5_5+:} false; then : $as_echo_n "(cached) " >&6 else if test -x $MYSQL; then VERS=`$MYSQL --version 2>&1 | cut -d ' ' -f 6 | cut -d ',' -f 1` MYSQL_VERSION=$VERS MYSQL_MAJOR=`echo $VERS | cut -d '.' -f 1` MYSQL_MINOR=`echo $VERS | cut -d '.' -f 2` MYSQL_MICRO=`echo $VERS | cut -d '.' -f 3` MARIA=`echo $MYSQL_MICRO | cut -d '-' -f 2` if [ "$MARIA" == *aria* ]; then MYSQL_VERSION=not_found ac_cv_mysql_version_5_5=no else if test $MYSQL_MAJOR -lt 5; then ac_cv_mysql_version_5_5=no else if test $MYSQL_MINOR -lt 5; then ac_cv_mysql_version_5_5=no else ac_cv_mysql_version_5_5=yes fi fi fi else ac_cv_mysql_version_5_5=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mysql_version_5_5" >&5 $as_echo "$ac_cv_mysql_version_5_5" >&6; } if test "x$ac_cv_mysql_version_5_5" = "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not supported mysql release. Should be 5.5.x or above. Please update !" >&5 $as_echo "$as_me: WARNING: Not supported mysql release. Should be 5.5.x or above. Please update !" >&2;} enable_db_schema_create=no enable_dbserver=no else enable_db_schema_create=yes fi else enable_db_schema_create=no fi # check for a database schema update if test "x$enable_db_schema_create" = "xyes"; then : # Check whether --enable-dbcreate was given. if test "${enable_dbcreate+set}" = set; then : enableval=$enable_dbcreate; else enable_dbcreate=yes fi enable_db_schema_create=$enable_dbcreate if test "x$enable_db_schema_create" = "xyes"; then : # Extract the first word of "mysql$EXEEXT", so it can be a program name with args. set dummy mysql$EXEEXT; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MYSQL+:} false; then : $as_echo_n "(cached) " >&6 else case $MYSQL in [\\/]* | ?:[\\/]*) ac_cv_path_MYSQL="$MYSQL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MYSQL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MYSQL" && ac_cv_path_MYSQL="nocommand" ;; esac fi MYSQL=$ac_cv_path_MYSQL if test -n "$MYSQL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL" >&5 $as_echo "$MYSQL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MYSQL" = nocommand; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mysql not found in $PATH" >&5 $as_echo "$as_me: WARNING: mysql not found in $PATH" >&2;} enable_db_schema_create=no else # Check whether --with-mysql-ho was given. if test "${with_mysql_ho+set}" = set; then : withval=$with_mysql_ho; MYSQL_HOST=${with_mysql_ho} else MYSQL_HOST="" fi # Check whether --with-mysql-admin was given. if test "${with_mysql_admin+set}" = set; then : withval=$with_mysql_admin; MYSQL_ADMIN=${with_mysql_admin} else MYSQL_ADMIN="" fi # Check whether --with-mysql-admin-passwd was given. if test "${with_mysql_admin_passwd+set}" = set; then : withval=$with_mysql_admin_passwd; MYSQL_ADMIN_PASSWD=${with_mysql_admin_passwd} else MYSQL_ADMIN_PASSWD="" fi if test "x$MYSQL_ADMIN" = "x"; then user_switch=""; else user_switch="-u$MYSQL_ADMIN"; fi if test "x$MYSQL_ADMIN_PASSWD" = "x"; then passwd_switch=""; else passwd_switch="-p$MYSQL_ADMIN_PASSWD"; fi if test "x$MYSQL_HOST" = "x"; then host_switch=""; else host_switch="-h$MYSQL_HOST"; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mysql works" >&5 $as_echo_n "checking if mysql works... " >&6; } if echo 'SELECT * FROM user' | $MYSQL $user_switch $passwd_switch $host_switch mysql> /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } MYSQL_CONNECTION=OK else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mysql cannot execute SELECT with user=$MYSQL_ADMIN, passwd=$MYSQL_ADMIN_PASSWD, and host=$MYSQL_HOST. Please check your my.cnf file or configure options!" >&5 $as_echo "$as_me: WARNING: mysql cannot execute SELECT with user=$MYSQL_ADMIN, passwd=$MYSQL_ADMIN_PASSWD, and host=$MYSQL_HOST. Please check your my.cnf file or configure options!" >&2;} MYSQL_CONNECTION=failed enable_db_schema_create=no fi; cat >>confdefs.h <<_ACEOF #define MYSQL_HOST "$MYSQL_HOST" _ACEOF fi fi fi fi if test "x$MYSQL_VERSION" != "xnot_found"; then DB_VERSION=${MYSQL_VERSION} fi else DB_NAME=MARIADB if test "x$enable_dbserver" = "xyes"; then : # We need libmysqlclient to compile # finds it for us. Abort if no mysqlclientlibs are found # Check whether --with-mariadbclient-prefix was given. if test "${with_mariadbclient_prefix+set}" = set; then : withval=$with_mariadbclient_prefix; mariadbclient_prefix="$withval" else mariadbclient_prefix="" fi # Check whether --with-mariadbclient-include was given. if test "${with_mariadbclient_include+set}" = set; then : withval=$with_mariadbclient_include; mariadbclient_include="$withval" else mariadbclient_include="" fi # Check whether --with-mariadbclient-lib was given. if test "${with_mariadbclient_lib+set}" = set; then : withval=$with_mariadbclient_lib; mariadbclient_lib="$withval" else mariadbclient_lib="" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mariadbclient " >&5 $as_echo_n "checking for mariadbclient ... " >&6; } MARIADBCLIENT_LDFLAGS="" MARIADBCLIENT_CFLAGS="" MARIADBCLIENT_LIBS="-lmariadb" mariadbclient_fail="" for tryprefix in /usr /usr/local /usr/mysql /usr/local/mysql /usr/pkg $mariadbclient_prefix ; do for hloc in lib/mariadb lib ; do if test -f "$tryprefix/$hloc/libmariadb.so"; then MARIADBCLIENT_LDFLAGS="-L$tryprefix/$hloc" elif test -f "$tryprefix/$hloc/libmariadb.a"; then MARIADBCLIENT_LDFLAGS="-L$tryprefix/$hloc" fi done for iloc in include/mariadb include; do if test -f "$tryprefix/$iloc/mysql.h"; then MARIADBCLIENT_CFLAGS="-I$tryprefix/$iloc" fi done # testloop done if test "x$mariadbclient_include" != "x" ; then echo "checking for mariadb includes... " if test -d "$mariadbclient_include/mariadb" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include" echo " found $MARIADBCLIENT_CFLAGS" elif test -d "$mariadbclient_include/include/mariadb" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include/include" echo " found $MARIADBCLIENT_CFLAGS" elif test -d "$mariadbclient_include" ; then MARIADBCLIENT_CFLAGS="-I$mariadbclient_include" echo "found $MARIADBCLIENT_CFLAGS" else echo "not found! no include dir found in $mariadbclient_include" fi fi if test "x$mariadbclient_lib" != "x" ; then echo "checking for mariadb libx... " if test -d "$mariadbclient_lib/lib/mariadb" ; then MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib/lib/mariadb" echo "found $MARIADBCLIENT_LDFLAGS" elif test -d "$mariadbclient_lib/lin" ; then MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib/lib" echo "found $MARIADBCLIENT_LDFLAGS" else MARIADBCLIENT_LDFLAGS="-L$mariadbclient_lib" echo "defaultd to $MARIADBCLIENT_LDFLAGS" fi fi ac_save_CFLAGS="$CFLAGS" ac_save_LDFLAGS="$LDFLAGS" ac_save_LIBS="$LIBS" CFLAGS="-v $CFLAGS $MARIADBCLIENT_CFLAGS" LDFLAGS="$LDFLAGS $MARIADBCLIENT_LDFLAGS" LIBS="$LIBS $MARIADBCLIENT_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { mysql_init( 0 ); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes $MARIADBCLIENT_CFLAGS $MARIADBCLIENT_LDFLAGS" >&5 $as_echo "yes $MARIADBCLIENT_CFLAGS $MARIADBCLIENT_LDFLAGS" >&6; } CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" : else echo "no" echo "can't compile a simple app with mysql_connnect in it. bad." mariadbclient_fail="yes" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x$mariadbclient_fail" != "x" ; then echo echo "***" echo "*** mariadbclient test source had problems, check your config.log ." echo "*** Also try one of the following switches :" echo "*** --with-mariadbclient-prefix=PFX" echo "*** --with-mariadbclient-include=DIR" echo "*** --with-mariadbclient-lib=DIR" echo "***" CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" MARIADBCLIENT_LIBS="" MARIADBCLIENT_CFLAGS="" : fi CFLAGS="$ac_save_CFLAGS" LDFLAGS="$ac_save_LDFLAGS" LIBS="$ac_save_LIBS" if test "x$MARIADBCLIENT_CFLAGS" = "x" then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No libmariadbclient libs found" >&5 $as_echo "$as_me: WARNING: No libmariadbclient libs found" >&2;} enable_dbserver=no fi DB_LDFLAGS=${MARIADBCLIENT_LDFLAGS} DB_LDLIBS=${MARIADBCLIENT_LIBS} DB_CFLAGS=${MARIADBCLIENT_CFLAGS} # Extract the first word of "mysql", so it can be a program name with args. set dummy mysql; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MYSQL+:} false; then : $as_echo_n "(cached) " >&6 else case $MYSQL in [\\/]* | ?:[\\/]*) ac_cv_path_MYSQL="$MYSQL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MYSQL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MYSQL" && ac_cv_path_MYSQL="nocommand" ;; esac fi MYSQL=$ac_cv_path_MYSQL if test -n "$MYSQL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL" >&5 $as_echo "$MYSQL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi MARIADB_VERSION=not_found if test "x$MYSQL" != "xnocommand"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mariadb release (at least version 10.0)" >&5 $as_echo_n "checking for mariadb release (at least version 10.0)... " >&6; } if ${ac_cv_mariadb_version_10_0+:} false; then : $as_echo_n "(cached) " >&6 else if test -x $MYSQL; then VERS=`$MYSQL --version 2>&1 | cut -d ' ' -f 6 | cut -d ',' -f 1` MARIADB_VERSION=$VERS MARIADB_MAJOR=`echo $VERS | cut -d '.' -f 1` MARIADB_MINOR=`echo $VERS | cut -d '.' -f 2` MARIADB_MICRO=`echo $VERS | cut -d '.' -f 3` MARIA=`echo $MARIADB_MICRO | cut -d '-' -f 2` if test $MARIADB_MAJOR -lt 10; then ac_cv_mariadb_version_10_0=no MARIADB_VERSION=not_found else if test $MARIADB_MINOR -lt 0; then ac_cv_mariadb_version_10_0=no MARIADB_VERSION=not_found else ac_cv_mariadb_version_10_0=yes fi fi else ac_cv_mariadb_version_10_0=no MARIADB_VERSION=not_found fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mariadb_version_10_0" >&5 $as_echo "$ac_cv_mariadb_version_10_0" >&6; } if test "x$ac_cv_mariadb_version_10_0" = "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not supported mariadb release. Should be 10.0.x or above. Please update !" >&5 $as_echo "$as_me: WARNING: Not supported mariadb release. Should be 10.0.x or above. Please update !" >&2;} enable_db_schema_create=no enable_dbserver=no else enable_db_schema_create=yes fi else enable_db_schema_create=no fi # check for a database schema update if test "x$enable_db_schema_create" = "xyes"; then : # Check whether --enable-dbcreate was given. if test "${enable_dbcreate+set}" = set; then : enableval=$enable_dbcreate; else enable_dbcreate=yes fi enable_db_schema_create=$enable_dbcreate if test "x$enable_db_schema_create" = "xyes"; then : # Extract the first word of "mysql$EXEEXT", so it can be a program name with args. set dummy mysql$EXEEXT; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MYSQL+:} false; then : $as_echo_n "(cached) " >&6 else case $MYSQL in [\\/]* | ?:[\\/]*) ac_cv_path_MYSQL="$MYSQL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MYSQL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MYSQL" && ac_cv_path_MYSQL="nocommand" ;; esac fi MYSQL=$ac_cv_path_MYSQL if test -n "$MYSQL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL" >&5 $as_echo "$MYSQL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MYSQL" = nocommand; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mysql not found in $PATH" >&5 $as_echo "$as_me: WARNING: mysql not found in $PATH" >&2;} enable_db_schema_create=no else # Check whether --with-mysql-ho was given. if test "${with_mysql_ho+set}" = set; then : withval=$with_mysql_ho; MYSQL_HOST=${with_mysql_ho} else MYSQL_HOST="" fi # Check whether --with-mysql-admin was given. if test "${with_mysql_admin+set}" = set; then : withval=$with_mysql_admin; MYSQL_ADMIN=${with_mysql_admin} else MYSQL_ADMIN="" fi # Check whether --with-mysql-admin-passwd was given. if test "${with_mysql_admin_passwd+set}" = set; then : withval=$with_mysql_admin_passwd; MYSQL_ADMIN_PASSWD=${with_mysql_admin_passwd} else MYSQL_ADMIN_PASSWD="" fi if test "x$MYSQL_ADMIN" = "x"; then user_switch=""; else user_switch="-u$MYSQL_ADMIN"; fi if test "x$MYSQL_ADMIN_PASSWD" = "x"; then passwd_switch=""; else passwd_switch="-p$MYSQL_ADMIN_PASSWD"; fi if test "x$MYSQL_HOST" = "x"; then host_switch=""; else host_switch="-h$MYSQL_HOST"; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mysql works" >&5 $as_echo_n "checking if mysql works... " >&6; } if echo 'SELECT * FROM user' | $MYSQL $user_switch $passwd_switch $host_switch mysql> /dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } MYSQL_CONNECTION=OK else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mysql cannot execute SELECT with user=$MYSQL_ADMIN, passwd=$MYSQL_ADMIN_PASSWD, and host=$MYSQL_HOST. Please check your my.cnf file or configure options!" >&5 $as_echo "$as_me: WARNING: mysql cannot execute SELECT with user=$MYSQL_ADMIN, passwd=$MYSQL_ADMIN_PASSWD, and host=$MYSQL_HOST. Please check your my.cnf file or configure options!" >&2;} MYSQL_CONNECTION=failed enable_db_schema_create=no fi; cat >>confdefs.h <<_ACEOF #define MYSQL_HOST "$MYSQL_HOST" _ACEOF fi fi fi fi if test "x$MARIADB_VERSION" != "xnot_found"; then DB_VERSION=${MARIADB_VERSION} fi fi # # Build the jpeg library compilation option # # Check whether --enable-jpegmmx was given. if test "${enable_jpegmmx+set}" = set; then : enableval=$enable_jpegmmx; else enable_jpegmmx=yes fi JPEG_LIB_CXXFLAGS="-D_TANGO_LIB" JPEG_MMX_LIB_CXXFLAGS="-D_TANGO_LIB" if test "x$enable_jpegmmx" != xno; then case $host_cpu in i*86 ) JPEG_LIB_CXXFLAGS="-D_TANGO_LIB -DJPG_USE_ASM" JPEG_MMX_LIB_CXXFLAGS="-D_TANGO_LIB -mmmx -DJPG_USE_ASM" ;; esac fi # Define a conditional variables to enable or disable installation # of the database server and the database schema creation. # The variables are used in the Makefiles. # if test x"$enable_dbserver" = x"yes"; then TANGO_DB_SERVER_ENABLED_TRUE= TANGO_DB_SERVER_ENABLED_FALSE='#' else TANGO_DB_SERVER_ENABLED_TRUE='#' TANGO_DB_SERVER_ENABLED_FALSE= fi if test x"$enable_db_schema_create" = x"yes"; then TANGO_DB_CREATE_ENABLED_TRUE= TANGO_DB_CREATE_ENABLED_FALSE='#' else TANGO_DB_CREATE_ENABLED_TRUE='#' TANGO_DB_CREATE_ENABLED_FALSE= fi DATADIR=`eval echo $datadir` DATADIR=`eval echo $DATADIR` # This is a hack to change PACKAGE_ #defines into TANGO_PACKAGE ac_config_commands="$ac_config_commands ac_config.h" # configure log4tango sub-package subdirs="$subdirs lib/cpp/log4tango" # All the Makefiles to be generated. ac_config_files="$ac_config_files Makefile lib/Makefile lib/idl/Makefile lib/cpp/tango.pc lib/cpp/Makefile lib/cpp/server/Makefile lib/cpp/server/idl/Makefile lib/cpp/server/jpeg/Makefile lib/cpp/server/jpeg_mmx/Makefile lib/cpp/client/Makefile lib/cpp/client/helpers/Makefile lib/java/Makefile cppserver/Makefile cppserver/database/Makefile cppserver/database/create_db.sql cppserver/database/create_db.sh cppserver/database/my.cnf cppserver/database/stored_proc.sql cppserver/database/create_db_tables.sql cppserver/database/update_db.sh cppserver/database/update_db.sql cppserver/database/update_db8.sql cppserver/database/update_db7.sql cppserver/database/rem_history.sql cppserver/starter/Makefile cppserver/tangotest/Makefile cppserver/AbstractClass/Makefile cppserver/AbstractClass/AccessControl/Makefile cppserver/tangoaccesscontrol/Makefile utils/Makefile utils/tango_admin/Makefile scripts/Makefile scripts/tango scripts/tango_wca doc/Makefile doc/man/Makefile doc/src/Makefile doc/src/ds_writing/Makefile doc/src/ds_model/Makefile doc/src/dance/Makefile doc/src/java_api/Makefile doc/src/java_api/picture/Makefile doc/src/gen_api/Makefile doc/src/advanced/Makefile pogo/Makefile pogo/templates/Makefile pogo/preferences/Makefile pogo/templates/cpp/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_JAVA_ENABLED_TRUE}" && test -z "${TANGO_JAVA_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_JAVA_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_LYX_ENABLED_TRUE}" && test -z "${TANGO_LYX_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_LYX_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_FIG2DEV_ENABLED_TRUE}" && test -z "${TANGO_FIG2DEV_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_FIG2DEV_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_DOC_ENABLED_TRUE}" && test -z "${TANGO_DOC_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_DOC_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DARWIN_ENABLED_TRUE}" && test -z "${DARWIN_ENABLED_FALSE}"; then as_fn_error $? "conditional \"DARWIN_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_DB_SERVER_ENABLED_TRUE}" && test -z "${TANGO_DB_SERVER_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_DB_SERVER_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TANGO_DB_CREATE_ENABLED_TRUE}" && test -z "${TANGO_DB_CREATE_ENABLED_FALSE}"; then as_fn_error $? "conditional \"TANGO_DB_CREATE_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Tango $as_me 9.2.5a, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Tango config.status 9.2.5a configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "ac_config.h.tmp") CONFIG_HEADERS="$CONFIG_HEADERS ac_config.h.tmp" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "ac_config.h") CONFIG_COMMANDS="$CONFIG_COMMANDS ac_config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/idl/Makefile") CONFIG_FILES="$CONFIG_FILES lib/idl/Makefile" ;; "lib/cpp/tango.pc") CONFIG_FILES="$CONFIG_FILES lib/cpp/tango.pc" ;; "lib/cpp/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/Makefile" ;; "lib/cpp/server/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/server/Makefile" ;; "lib/cpp/server/idl/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/server/idl/Makefile" ;; "lib/cpp/server/jpeg/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/server/jpeg/Makefile" ;; "lib/cpp/server/jpeg_mmx/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/server/jpeg_mmx/Makefile" ;; "lib/cpp/client/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/client/Makefile" ;; "lib/cpp/client/helpers/Makefile") CONFIG_FILES="$CONFIG_FILES lib/cpp/client/helpers/Makefile" ;; "lib/java/Makefile") CONFIG_FILES="$CONFIG_FILES lib/java/Makefile" ;; "cppserver/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/Makefile" ;; "cppserver/database/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/database/Makefile" ;; "cppserver/database/create_db.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/create_db.sql" ;; "cppserver/database/create_db.sh") CONFIG_FILES="$CONFIG_FILES cppserver/database/create_db.sh" ;; "cppserver/database/my.cnf") CONFIG_FILES="$CONFIG_FILES cppserver/database/my.cnf" ;; "cppserver/database/stored_proc.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/stored_proc.sql" ;; "cppserver/database/create_db_tables.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/create_db_tables.sql" ;; "cppserver/database/update_db.sh") CONFIG_FILES="$CONFIG_FILES cppserver/database/update_db.sh" ;; "cppserver/database/update_db.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/update_db.sql" ;; "cppserver/database/update_db8.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/update_db8.sql" ;; "cppserver/database/update_db7.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/update_db7.sql" ;; "cppserver/database/rem_history.sql") CONFIG_FILES="$CONFIG_FILES cppserver/database/rem_history.sql" ;; "cppserver/starter/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/starter/Makefile" ;; "cppserver/tangotest/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/tangotest/Makefile" ;; "cppserver/AbstractClass/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/AbstractClass/Makefile" ;; "cppserver/AbstractClass/AccessControl/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/AbstractClass/AccessControl/Makefile" ;; "cppserver/tangoaccesscontrol/Makefile") CONFIG_FILES="$CONFIG_FILES cppserver/tangoaccesscontrol/Makefile" ;; "utils/Makefile") CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;; "utils/tango_admin/Makefile") CONFIG_FILES="$CONFIG_FILES utils/tango_admin/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "scripts/tango") CONFIG_FILES="$CONFIG_FILES scripts/tango" ;; "scripts/tango_wca") CONFIG_FILES="$CONFIG_FILES scripts/tango_wca" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/man/Makefile") CONFIG_FILES="$CONFIG_FILES doc/man/Makefile" ;; "doc/src/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/Makefile" ;; "doc/src/ds_writing/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/ds_writing/Makefile" ;; "doc/src/ds_model/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/ds_model/Makefile" ;; "doc/src/dance/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/dance/Makefile" ;; "doc/src/java_api/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/java_api/Makefile" ;; "doc/src/java_api/picture/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/java_api/picture/Makefile" ;; "doc/src/gen_api/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/gen_api/Makefile" ;; "doc/src/advanced/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/advanced/Makefile" ;; "pogo/Makefile") CONFIG_FILES="$CONFIG_FILES pogo/Makefile" ;; "pogo/templates/Makefile") CONFIG_FILES="$CONFIG_FILES pogo/templates/Makefile" ;; "pogo/preferences/Makefile") CONFIG_FILES="$CONFIG_FILES pogo/preferences/Makefile" ;; "pogo/templates/cpp/Makefile") CONFIG_FILES="$CONFIG_FILES pogo/templates/cpp/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; "ac_config.h":C) sed s/PACKAGE/TANGO_PACKAGE/g ac_config.h ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi # # CONFIG_SUBDIRS section. # if test "$no_recursion" != yes; then # Remove --cache-file, --srcdir, and --disable-option-checking arguments # so they do not pile up. ac_sub_configure_args= ac_prev= eval "set x $ac_configure_args" shift for ac_arg do if test -n "$ac_prev"; then ac_prev= continue fi case $ac_arg in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ | --c=*) ;; --config-cache | -C) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ;; --disable-option-checking) ;; *) case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_sub_configure_args " '$ac_arg'" ;; esac done # Always prepend --prefix to ensure using the same prefix # in subdir configurations. ac_arg="--prefix=$prefix" case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" # Pass --silent if test "$silent" = yes; then ac_sub_configure_args="--silent $ac_sub_configure_args" fi # Always prepend --disable-option-checking to silence warnings, since # different subdirs can have different --enable and --with options. ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. test -d "$srcdir/$ac_dir" || continue ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 $as_echo "$ac_msg" >&6 as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" # Check for guested configure; otherwise get Cygnus style configure. if test -f "$ac_srcdir/configure.gnu"; then ac_sub_configure=$ac_srcdir/configure.gnu elif test -f "$ac_srcdir/configure"; then ac_sub_configure=$ac_srcdir/configure elif test -f "$ac_srcdir/configure.in"; then # This should be Cygnus configure. ac_sub_configure=$ac_aux_dir/configure else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative name. ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 fi cd "$ac_popdir" done fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: Configuration ($PACKAGE): Source code location: ${srcdir} Version: ${VERSION} Compiler: ${ac_ct_CC},${ac_ct_CXX} OMNIORB PATH: ${OMNI_ROOT} OMNIORB VERSION: ${OMNI_VERSION} ZMQ PATH: ${ZMQ_ROOT} ZMQ VERSION: ${ZMQ_VERSION} JAVA PATH: ${with_java} JAVA VERSION: ${JAVA_VERSION} ${DB_NAME} CLIENT LIB: ${DB_LDFLAGS} ${DB_LDLIBS} ${DB_NAME} VERSION: ${DB_VERSION} ${DB_NAME} CONNECTION: ${MYSQL_CONNECTION} build: libraries: ${enable_lib} java application: ${enable_java} access control server: ${enable_dbserver} database server: ${enable_dbserver} database schema create: ${enable_db_schema_create} Please check whether the configuration I detected matches what you would like to have. " >&5 $as_echo " Configuration ($PACKAGE): Source code location: ${srcdir} Version: ${VERSION} Compiler: ${ac_ct_CC},${ac_ct_CXX} OMNIORB PATH: ${OMNI_ROOT} OMNIORB VERSION: ${OMNI_VERSION} ZMQ PATH: ${ZMQ_ROOT} ZMQ VERSION: ${ZMQ_VERSION} JAVA PATH: ${with_java} JAVA VERSION: ${JAVA_VERSION} ${DB_NAME} CLIENT LIB: ${DB_LDFLAGS} ${DB_LDLIBS} ${DB_NAME} VERSION: ${DB_VERSION} ${DB_NAME} CONNECTION: ${MYSQL_CONNECTION} build: libraries: ${enable_lib} java application: ${enable_java} access control server: ${enable_dbserver} database server: ${enable_dbserver} database schema create: ${enable_db_schema_create} Please check whether the configuration I detected matches what you would like to have. " >&6; } tango-9.2.5a/AUTHORS0000644023471100065110000000005113034744715011002 00000000000000The Tango team (info@tango-controls.org) tango-9.2.5a/COPYING0000644023471100065110000010451313034744715010775 00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . tango-9.2.5a/COPYING.LESSER0000644023471100065110000001672713034744715012002 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. tango-9.2.5a/ChangeLog0000644023471100065110000000000013034744715011476 00000000000000tango-9.2.5a/INSTALL0000644023471100065110000002207113034744715010771 00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PREFIX', the package will use PREFIX as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. tango-9.2.5a/NEWS0000644023471100065110000000000013034744716010424 00000000000000tango-9.2.5a/install-sh0000755023471100065110000001273613034744716011754 00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 tango-9.2.5a/missing0000755023471100065110000002402613034744715011341 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch]" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing 0.4 - GNU automake" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then # We have makeinfo, but it failed. exit 1 fi echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 fi # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 tango-9.2.5a/mkinstalldirs0000755023471100065110000000132213034744715012542 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here tango-9.2.5a/bootstrap0000755023471100065110000000363413034744716011710 00000000000000#! /bin/sh # $Id$ # This script is used to bootstrap the build process, that is, to # create the aclocal, the ac_config.h.tmp.in, the Makefile.in, and the # configure files # It must be run in order to let changes in configure.in be reflected # in configure. # from the info file for autoconf aclocal # The `aclocal' program will automatically generate `aclocal.m4' files # based on the contents of `configure.in'. This provides a convenient # way to get Automake-provided macros, without having to search around. # Also, the `aclocal' mechanism is extensible for use by other packages. echo "running aclocal -I m4" aclocal -I m4 echo "running libtoolize --copy --force " libtoolize --copy --force # from the info file for autoconf # The `autoheader' program can create a template file of C `#define' # statements for `configure' to use. If `configure.ac' invokes # `AC_CONFIG_HEADERS(FILE)', `autoheader' creates `FILE.in'; if multiple # file arguments are given, the first one is used. Otherwise, # `autoheader' creates `config.h.in'. echo "running autoheader" autoheader # from the info file for automake # Automake is a tool for automatically generating `Makefile.in's from # files called `Makefile.am'. Each `Makefile.am' is basically a series # of `make' macro definitions (with rules being thrown in occasionally). # The generated `Makefile.in's are compliant with the GNU Makefile # standards. # # creates the Makefile.ins echo "running automake --gnu --add-missing" automake --gnu --add-missing # from the info file for autoconf # Autoconf is a tool for producing shell scripts that automatically # configure software source code packages to adapt to many kinds of # UNIX-like systems. The configuration scripts produced by Autoconf are # independent of Autoconf when they are run, so their users do not need # to have Autoconf. # # creates the configure script echo "running autoconf" autoconf tango-9.2.5a/TANGO_CHANGES0000644023471100065110000024706613034744715011700 00000000000000TANGO history file 01/2016 ******************************************************* * * * Tango release 9.2.5a : Changes since version 9.2.5 * * * ******************************************************* Bug fixes --------- - Jive: Fix bug when creating free property New Features ------------ - Astor: Added DBBench feature 12/2016 ******************************************************* * * * Tango release 9.2.5 : Changes since version 9.2.2 * * * ******************************************************* - Add automatic event unsubscription in DeviceProxy class destructor Bug fixes --------- Bugs recorded in SourceForge: - 787 : Event errors persisting after server restart - 788 : Dead lock in event system - 789 : Device not switching to ALARM - 790 : Wrong full name passed to event callback - 791 : Wrong usage of omni_mutex - 792 : Calls to asynchronous methods not thread safe - 793 : API_AsynReplyNotArrived exception thrown when asyn call response is received in the last 20 ms before the timeout expiration - 795 : Compilation pb with gcc >= 5.3 - 798 : memory leak in DeviceData for old compiler (not supporting C++11) - 799 : read value for attribute xxx has not been updated - 801 : Memory leak for R/W spectrum string attribute - 802 : DevicePipeBlob - 804 : init_device & DeviceProxy to an external device with same name - 805 : Missing check in Dserver::zmq_event_subscription_change() method - 813 : Segfault when pushing a change event with invalid quality - 814 : Segmentation fault when reading attribute - 816 : DevShort attribute change event has wrong data_type - 822 : Swapped origin and desc in some versions of Tango::Except::throw_exception - 825 : Event relative change filter does nothing - 828 : Crash when client receives att conf change event for enum att - 829 (github 312): Compatibility with Zmq 4.2.0 - github 313 : Improve doc for AttributeProxy::subscribe_event() method - github 314 : DServer class ZmqEventSubscriptionChange cmd arg. check Other bugs - Dynamic attributes polled by code when created after classical DS startup sequence - Polled attributes changing their own polling period 03/2016 ******************************************************* * * * Tango release 9.2.2 : Changes since version 9.2.1 * * * ******************************************************* Bug fixes --------- Bug recorded in SourceForge: - 784 : DevULong memorized attribute - 785 : Db and DS crash in case no DNS is available 03/2016 ******************************************************* * * * Tango release 9.2.1 : Changes since version 9.1.0 * * * ******************************************************* Tango 9.2 has been developed and tested using: - omniORB 4.2.1 - zmq 4.0.5 - log4tango 5.0.1 Changes in Tango itself ----------------------- - Apply changes sent by Szeged university for better code - Improve way TANGO_HOST is used when the host name specified in TANGO_HOST is a host alias name - Method DeviceClass::get_pipe_list() with device name as arg. is now case independant Bug fixes --------- Bug recorded in SourceForge: - 741 : Device_4Impl and Tango 9 compatibility - 745 : Missing method for data ready event - 748 : Memory leak in DeviceProxy assignment operator - 749 : User dev_state() method not called + hide att exception in state method - 752 : ZmqEventSupplier::push_event() from multiple threads - 753 : Server crash when polling thread is late and IDL 4 clients - 761 : Crash when pushing events from my own thread - 765 : Asyn re-connection after admin device DevRestart command - 767 : push_change_event("State") crashes device server process - 783 : Tango server NO_SYNC serial mode Other bugs - Crash using asyn calls when returning error using omniORB 4.2.1 - Memory leak in DeviceProxy::get_command_config() - It's now possible to read write only attribute of type DevState even before any value has been written - Bug in DeviceProxy::write_attribute() family methods in case of DeviceProxy created while the DS is not running and write_attribute being the first call - Bug in case of forwarded enumerated attribute (enum labels not forwarded) - Several pipe related bugs (get_data_elt_nb() method crashing process - Pipe defined at class level instead of device level - Not possible to insert data in pipe/blob using DataElement class if no previous call to set_data_elt_nb() method) 09/2015 ******************************************************* * * * Tango release 9.1.0 : Changes since version 8.1.2 * * * ******************************************************* Tango 9.1 has been developed and tested using: - omniORB 4.2.0 - zmq 4.0.5 - log4tango 5.0.1 Please note that omniORB 4.2.0 on Windows has a bug preventing timeout to work correctly. There is a required change described in http://www.omniorb-support.com/pipermail/omniorb-list/2014-November/031621.html Do not use the omniORB libraries distributed from omniORB site. Use those provided by Tango Windows binary distribution (which include the bug fix) Changes between Log4tango 5.0.0 and Log4Tango 5.0.1 --------------------------------------------------- - Small Windows specific change to support new Windows compiler Changes in Tango itself ----------------------- - Add device pipe - Add forwarded attribute - Add enumeration data type for attribute - Add device interface change event (FR 90) - Add dynamic command (FR 44) - New polling algorithm - Add memorized attribute information in attribute config (FR 20) - New method DeviceProxy::write_read_attributes(). Note the ending s meaning plurial. - Attribute "unit" property library default value is now an empty string - Only one reference doc generated for all Tango classes (client and server). Tango book chapter 6 is removed. - Add method DeviceImpl::is_there_subscriber() (FR 89) - Change logging system maximum and default logging file size (FR 112) - Use template explicit instantiation - Code re-factoring for . attribute configuration storage in DB . Event compatibility . KeepAliveThread (on client) - Solve memory pb due to event re-connection when nothing is sent on ZMQ sockets between re-connection - Optimize group calls in case of disconnected group members - Replace many "#define" by "const int" or "const char *" in Tango namespace - Added a Tango::string_free() call - Windows: Add a WSAStartup() call for pure client - Event: During bind action, ask for ephemeral port number to ZMQ - In Attribute::set_value() method family: Add test on data size before testing given pointer validity - If not already installed, install SIGINT and SIGTERM signal handler in pure client for faster device unlocking (in case some device is locked) - Messsage "Failed to narrow the EventChannelfactory..." printed by DS to cout5 (FR 91) - Better management of the admin device in Util::get_device_by_name() - svr_starting flag now reset in Util::server_run() (instead of end of admin device creation) - Better support of host alias when used in device fqdn - Better support of DS without db when they embed several Tango classes - Add methods DeviceProxy::get_command_list() and DeviceProxy::get_command_config() for better compatibility between command an attribute - Client using event: ORB shutdown an destroyed at process exit - Remove possible deadlock in server side when using DeviceImpl class polling related methods - Increase ORB maxGIOPConnectionPerServer to 128 - Change in attribute name passed to event callback in case of CS with multiple DB servers and in case of CS with TANGO_HOST defined using a host alias - It's supported to specify a host name When using ORBendPoint command line option - Added DeviceData and DeviceAttribute state() methods - First sync. event also for periodic event - Also manage alternate address(es) for events for DS running on host with several NIC - Databaase::add_server() method also manages the admin device Bug fixes --------- Bug recorded in sourceForge: - 620 : IP address specification from omniORB configuration file - 621 : INcompatibility between ZMQ events - 627 : DeviceAttribute data format field when using event - 631 : Event reconnection - 632 : Seg fault during event reconnection (with Tango 7/8 devices) - 633 : DevRestart with dynamic attribute when polling is configured via code - 638 : Missing events after two consecutive re-connection - 642 : Client crash during re-connection - 643 : Compilation clash on Windows (about NO_DATA) - 646 : ZMQ event for device name when using FQDN - 652 : Bug in signal managementwhen using your own signal handler - 667 : Subscribing to event does not report error when polling is stopped on server side - 668 : Inconsistency between stateless and non-stateless event subscription - 676 : Event notification stopped after a while - 682 : AttributeProxy created by alias and put_property() method - 699 : Memory leak in callback calls when using asynchronous PUSH methods - 707 : Wron dates from attribute_history() call - 720 : Event with no-db device - 725 : Hang in client when doing event subscription within the event callback - 732 : GCC 5.2 compatibility Other bugs - In DbServerData class: Device attribute properties were not correctly copied - In admin device polling_threads_pool_conf property when property size is > 255 chars - Memory leak in server side during command ZmqEventSubscriptionChange in case of wrongly configured event - In polling thread tuning algorithm - Server side: In case one ORB is already created, also destroy db related objects stored in ApiUtil - When using C++11: No event in case of CS with multiple DB servers if the server is started with TANGO_HOST set to one DB server while the client is started with TANGO_HOST set to other DB server - Fix valgrind complaining about uninitialized bytes when pushing events - For float or double attribute: bug preventing events to be fired when attribute value is NaN - During re-connection when remote device has alternate address(es) in its IOR 06/2013 ******************************************************* * * * Tango release 8.1.2 : Changes since version 8.0.5 * * * ******************************************************* Tango 8.1 has been developed and tested using: - omniORB 4.1.6 - zmq 3.2.2 - log4tango 5.0.0 Changes between Log4tango 4.0.7 and Log4Tango 5.0.0 --------------------------------------------------- - Small changes to allow Tango doc generation with a "make pdf" command - Created a release 5 to handle a compatibility problem of timestamp buggy in release < 4.0.6 (SF Bug 613) Changes in Tango itself ----------------------- - Add event propagation using multicasting - Add a DeviceImpl::write_attr_hardware() method (Feature request 68) - Add a new EventConfirmSubscription command to admin device to optimize event heartbeat system - Add a new define (TANGO_BASE_CLASS) to make next Tango inheritance change transparent - Add class DbServerData with methods to ease moving device server from one CS to another - Improve TAC device filters. It is now possible to use one wildcard per field (sr/v-*/*) - Memorize error for memorized attribute which failed during device server startup sequence - Change the way Tango device server retrieve host IP address(es) - New methods in Database class: get_device_from_alias(), get_alias_from_device(), get_attribute_from_alias() and get_alias_from_attribute(). Deprecate get_alias(), get_device_alias() and get_attribute_alias() Also add a new rename_server() method - Add DeviceProxy::get_tango_lib_version() method - Add DeviceAttribute::set_error_list() method - Remove CORBA methods throw clause - Add Database::get_device_info() method - Coherent inserters/extracters method set between DeviceData and DeviceAttribute for DevEncoded data type - Change format define for DevEncoded attribute data type to prevent compilation error when used with Lima - Add a check against NULL pointer in Attribute::set_value() method - Message "Failed to narrow the EventChannelFactory... is printed on console only during DS startup - Reduce min polling period to 5 mS Bug fixes --------- Bug recorded in sourceForge: - 178 (2027829) and 219 (2668010) : Database::get_services() method - 529 (3563183) : Group command_inout fails between server restart - 530 (3564392) : Database::get_info() method returns a string with extra '\0' - 531 (3564930) : DeviceImpl::stop_poll_attribute and stop_poll_command - 533 (3564995) : Memory leak in DbDatum class - 534 (3565021) : Archive event subscription with only relative change - 536 (3566280) : Device right in init_device() method when using a device running in another CS - 537 (3568781) : Memorized attribute and device monitor - 545 (3577835) : Event subscription by different threads - 546 (3577837) : Attribute name given to user callback - 552 (3586344) : Polling thread out of sync error and event - 554 (3592399) : Seg fault in Attribute::set_value() - 559 (3601231) : Limit in event number - 560 (3601232) : Open file leak - 561 (3601267) : Access right exception - 563 (3601471) : exit() call in library - 570 (3604715) : Default format of DevULong (Feature Request 22) - 572 (3605540) : DevUChar memorized attribute - 593 (3606931) : DeviceImpl class polling methods - 602 : Tango lock mechanism - 603 : Open file leak (duplicate of 560) - 604 : Polling with long period - 608 : Missing include for FreeBSD - 609 : FreeBSD and DServerSignal::get_sig_thread_pid() method Other bugs - In notifd event system in case of slow DS generating event - In state/status management when attribute are wrongly configured - Small bug in returned value of GroupAttrReply::operator>> - In event reconnection in the DS is re-started with the instance name given with different letter cases - In admin device RestartDevice command when the device name is defined with upper case letters - Double free in case of event system reconnection when events are sent to queue - Safer memory management in Deviceproxy::read_attributes() method 05/2012 ******************************************************* * * * Tango release 8.0.5 : Changes since version 7.2.6 * * * ******************************************************* Tango 8 has been developed and tested using: - omniORB 4.1.6 - zmq 3.1 - log4tango 4.0.7 Changes between Log4tango 4.0.3 and Log4Tango 4.0.7 --------------------------------------------------- - SourceForge bug 3156197 - Fix warnings when Tango is compiled -Wall -Wextra - Add Windows port for Windows 64 bits VC10 - Add ACLOCAL_AMFALGS in main Makefile.am - Update Doxyfile file - Apply Alessio's patch: - Re-enable Thread's name PatternComponent - Add Thread's id PatternComponent - Add missing conversion patterns (%t and %T) Changes in Tango itself ----------------------- - New event system based on ZMQ - New methods to manage polling in DeviceImpl class (is_attribute_polled()/is_command_polled, get_attribute_poll_period()/get_command_poll_period(), poll_attribute()/poll_command(), stop_poll_attribute()/stop_poll_command()) - DevEncoded data type supported for commands - New Attribute class setter/getter methods for min_alarm, max_alarm, min_warning and max_warning attribute properties - New Attribute set_properties/get_properties to set/get several attribute properties in one call - Cleaner way to reset kernel attribute properties to lib/user/class default value - Add some C++11 features when compiler support them (Lambda functions - unique_ptr for extension classes - Move contructor and assignement for DeviceData and DeviceAttribute classes) This requires a new compilation option (-std=c++0x) - The DeviceProxy and DeviceAttribute classes copy constructor and assignement operator now really copy the data - Add device log messages when any device attribute(s) quality factor changes (ATTR_INVALID -> error stream, ATTR_CHANGING -> info stream, ATTR_VALID -> info stream ATTR_ALARM: min/max alarm -> error stream, min/max warning + rds -> warning stream) - Add a clean_db parameter to the DeviceImpl::remove_attribute() method. Default is true - New DeviceProxy::get_access_right() method - New Util::is_svr_starting(), Util::is_svr_shutting_down() and Util::is_device_restarting() methods - New DeviceClass::get_cmd_by_name() method - New DServer::_create_cpp_class() method (For PyTango) - Remove warnings compilation (Tango is now compiled with -Wall and -Wextra) - Add Group::command_inout(), Group::command_inout_asynch(), Group::write_attribute() and Group::write_attribute_asynch() with vector to carry the data. - Improvements in event management for notifd events (link to bug 3293671) - For writable and memorized attribute(s), check coherency of new min/max_value with memorized value when the attribute configuration is modified. - State computation for device with alarmed attributes: If the attribute is polled, the attribute value is read from the polling buffer (also true when reading the state as a CORBA attribute) - Add pre-processor define for Tango release number management (TANGO_VERSION_MAJOR, TANGO_VERSION_MINOR and TANGO_VERSION_PATCH) - Host IP address(es) is(are) now retrieved from network interface(s) - Add a check during set_attribute_config() call for users trying to change hard coded properties - Optimization in DeviceProxy methods to get asynchronous call replies when caller uses a timeout in case the reply is already there - Remove some "cerr" messages in AttributeProxy class - Uil::get_host_name() always returns host name in lower case letters - The caller PID is now reported in black-box also when UNIX socket is used as transport - write_attribute() called during device server startup sequence due to memorized attribute(s) is reported in black box with a specific message - It's now possible to poll command/attribute in a device server started without database for command/attributes with polling defined in code - Add a polling thread tuning after the execution of UpdObjPollingPeriod command - Remove all Solaris specific code - Remove all old stream specific code - Signals SIGUSR1 and SIGUSR2 can now be used within a device server process - Optimize database calls during device server startup and shutdown sequence (When TAC is used or when dynamic attributes are used) - Added Database class copy constructor and assignment operator - Restore user signal handler for SIGPIPE after CORBA::ORB_init() call - Tango is now compiled with Debian hardenning flags on. Bug fixes --------- Bug recorded in sourceForge: - 3129849 : TANGO_HOST case sensitive for some event usage - 3151801 : Missing some attribute properties in UserDefaultAttrProp class - 3165120 : Yet another type in doc - 3206916 : Another type in doc - 3213730 : Device server add wrong ',0' in attribute abs_change property - 3259442 : Macos compilation on x86 - 3267364 : Typo in documentation - 3277453 : Database class and Tango Access Control - 3280851 : Wrong state computation - 3285370 : Printing operator for DeviceData class - 3285372 : Wrong lock removal of last locked device from a locking thread (Windows specific) - 3285674 : NaN in write_attribute() call (With a control system prop. to allow/disallow NaN) - 3313211 : Polling threads pool management - 3399975 : ULong data type and memorized writable attribute - 3400550 : State computation with alarmed attributes - 3413944 : Memorized attribute written at init - 3460080 : Device server crash during event reconnection (event between devices within the same DS) - 3468928 : Does not compile with gcc 3.3 - 3480524 : Write attribute (SCALAR) when throwing exception - 3495592 : Logging directory - 3505226 : Tango misses ORB parameters Other bugs - When user pushes event, pushes first event when it is inited (when the event detection is done by the lib) - In case of consecutive signal installations and removals. - Bug in error message and in inserters in DbDatum class for unsigned char data type - Bug when updating database due to one attribute configuration change - Bug when using the WAttribute::set_min_value() methods family: The attribute was not flagged as attribute with minimun value defined - Doc: Fix bug in Database::get_device_attribute_property() method usage example - Bug in WAttribute::set_min_value() and Wattribute::set_max_value() methods for unsigned char data type. The data was stored in database as ascii characters - Device server crashes when you kill it if there are some long running actions when the signal is received. - It's now possible to define in code that state and status has to be polled - It's now possible to define an archive event period or a periodic event period for state or status attributes - Possible device server process crash (depending how you are lucky) when trying to start one with an instance name not defined in database - Bug when reading attribute from CACHE when the attribute is not polled. The returned exception was not correct - Wrong printed date (and reported in blackbox) when used on 64 bits computer - Bug in attribute property management for dynamique attribute when the property is an array - Fix bug in logging for devices not using database when the logging level is specified on the command line 03/2011 ******************************************************* * * * Tango release 7.2.6 : Changes since version 7.2.1 * * * ******************************************************* Note: Tango 7.2.2 to 7.2.5 have never been officially released outside ESRF. - Replace the deprecated gethosybyname() and gethostbyaddr()calls. This allows running Tango on OS like Ubuntu 10.10 with the default /etc/hosts file - Optimize database call retries number during device server startup sequence. - Added a DeviceProxy::get_access_right() method - Add a check on empty device name in DeviceProxy ctor methods - Add a encoded_format.h file for DevEncoded string definition - Reset SIGINT and SIGQUIT to their default behavior during DS startup sequence. This is needed in case of Tango class using signals and started as background process by a shell script Bug fixes --------- Bugs recorded in SourceForge - 3110842 : Memory allocation in state command - 3118520 : Windows: DS freeze when using event - 3119664 : Windows: Stream inserter for DeviceAttribute fails - 3122125 : Windows: DS crash at exit - 3165232 : TAC and multi TANGO_HOST - 3206383 : Double free in DeviceProxy::read_attributes() Other bugs - Two bugs related to controlled access on the database device - Wrong synchronisation for periodic and archive (periodic part) events with non constant attribute reading time - TAC and re-connection (all commands allowed after a re-connection!!) 11/2010 ******************************************************* * * * Tango release 7.2.1 : Changes since version 7.2.0 * * * ******************************************************* Bug fixes --------- Bugs recorded in SourceForge - 3092967 : Tango 7.2 DS crash when reading a string scalar R/W attribute Other bugs - DS crash in dynamic_cast when using C++ and Python Tango classes within the same process - Windows: Reduce timeout for DS trying to connect to a non running notifd 10/2010 ******************************************************* * * * Tango release 7.2.0 : Changes since version 7.1.1 * * * ******************************************************* Tango 7.2.0 has been developed and tested with omniORB 4.1.4 Remarks about omniORB 4.1.4 --------------------------- - SourceForge bug number 3054292 (client hangs on ping) is solved by a omniORB patch available in the SourceForge bug tracker - SourceForge bug number 3011742 (memory leak) is also solved by 2 omniORB patches available in the SourceForge bug tracker New / Optimized features ------------------------ - The client API is now thread-safe: This means that you can share a pointer to a DeviceProxy class instance between several thread. Note that if one thread changes data like the device time-out, this change will be seen by all the other threads using this device. In next major release (Tango 8), a new mechanism will be implemented allowing the user to choose if he want a thread safe or unsafe device proxy. For compatibility reason, it was not possible to include this change in a non major release. - It's now possible for applications to subscribe several times to the same event (with or without the same callback object) - Add check on attribute dimension when using AttrData class to fill polling buffer hsitory - Subscribe to a data ready event fails if the Attr::set_data_ready_event() method has not been called (in the server side). This allows application to be aware that the device could/couldn't fire data ready event - Added insertion operators (<<) in the DeviceAttribute class for const char * and Tango::DevString - Polling and logging related commands allowed only for the device lock owner when the device is locked - Add a way to externally fill-up the polling buffer for R/W attribute when specifying the attribute written part - No more database call executed by DeviceProxy constructor if it is called in a device server and the device is in the same process - Better management of device server started on host with several network interface (ORBendPoint option not needed any more) - Added a ApiUtil::get_env_var() method (static) - Better timeout management during re-connection in case of device server running on a host switched off - Add a new way to write class_factory() as a function instead of a DServer class method. Needed for PyTango on Windows using DLL - NaN is now taken into account in RDS alarm for float/double (and array of) attributes SourceForge features request ---------------------------- - 2721963 : Implemented a much faster device server shutdown sequence - 3004584 : Add a way to define a minimum polling period using properties Bug fixes --------- Bugs recorded in SourceForge - 2894469 : "localhost" correctly managed in TANGO_HOST environment variable - 2908860 : Applications seg. fault at exit if notifd is dead - 2910028 : Attribute history not correctly initilised (written part y dimension) - 2916280 : Accessing a device in a non-db device server - 2917038 : Seg fault if you start a device server from a thread which is not the main thread - 2934375 : Polling thread out of sync for very slow polling - 2934862 : Possible seg fault in device server - 2954995 : Seg fault in device server for scalar, R/W attribute with quality factor set to invalid - 2977091 : Memory leak in DeviceProxy::get_attribute_list() method - 2979781 : Polling properties management - 2988115 : DeviceProxy::read_attributes() call with several times the same attribute - 2993423 : Dead lock in DeviceProxy unsubscribe_event() method - 2996669 : Tango group and device defined using full Tango device name - 3015443 : Inconsistency in event error management - 3016953 : State command/attribute throws exception in case of attribute with alarm level defined and quality set to invalid - 3017075 : Same bug than 3016953 - 3019067 : Dead lock in device server - 3033465 : File name for device server using database in a file - 3068607 : Memory leak for scalar, R/W string attribute - 3079309 : Wrong error messages - 3080885 : Double free for some DB calls in case of communication problem Bugs not recorded in SourceForge (Shame on us) - Events from device server using a file as database - Some cases of re-connection with device running on Windows - DeviceImpl::remove_attribute() does not correctly manage main attribute vecor indexes preventing nice implementation of dynamic attributes - The value set by a WAttribute::set_write_value() if used in the attribute write method (write_MyAttribute) was overwritten with the caller value Documentation ------------- - Add property file syntax description (Appendix F) - Add Group::read_attributes() method documentation - Add / Update doc related to new / modified features - Fix some typos 11/2009 ******************************************************* * * * Tango release 7.1.1 : Changes since version 7.1.0 * * * ******************************************************* - Change in the way polling thread(s) starts - Support of events in Tango system with multiple db servers - Attribute name passed to the event callback is now the fully qualified attribute name Bug fixes --------- Bugs recorded in SourceForge - 2880372: Change of attribute config setting lost if DevRestart is done - 2881841: Attribute quality factor is set incorrectly in Tango 7.1 ******************************************************* * * * Tango release 7.1.0 : Changes since version 7.0.2 * * * ******************************************************* Tango 7.1.0 has been developed and tested with omniORB 4.1.4 - On Unix like OS, the communication between devices on the same host uses Unix domain socket - Database server host names stored with its FQDN - Configurable attribute serialization model added - Comment character (#) supported in the Tango rc file - A Tango rc file is also supported on Windows platform ($TANGO_ROOT/tangorc) - Call to DeviceImpl::stop_polling() method silently ignored if the polling is already stopped - Added optimized DeviceProxy::read_attribute() call (Not yet virtual) Bug fixes --------- Bugs recorded in SourceForge - 2787140: Wrong value returned from DeviceProxy::get_logging_level() - 2788358: Typos in exception fields - 2801558: Stateless timeout - 2803392: Event in multi Tango host system - 2810110: Pushing change event with quality factor set to INVALID - 2811351: Change event for state attribute - 2812775: No more events after a double subscription - 2814404: Wrong string comparison in polling threads pool init - 2821229: Client crash at exit if using device locking and event - 2821898: AttrConfEventData, EventData copy ctor and assignment operator - 2826552: Event abs_change and rel_change attribute property resetting failed - 2836943: Unsubscribe_event locks - 2836238: Non PIC code - 2840364: Missing ctors for DeviceAttribute class - 2861309: Race condition in EventConsumerKeepAlive thread - 2871262: Unsubscribe_event seg fault Bugs not recorded in SourceForge - Server crash when reading several attributes with the DeviceProxy::read_attributes() call with one of the attribute being the State and other attributes being scalar with alarm threshold defined 05/2009 ******************************************************* * * * Tango release 7.0.2 : Changes since version 6.1.1 * * * ******************************************************* Tango 7 is using Log4Tango 4.0.3. This new release of Log4Tango does not add any new feature to Log4Tango.It simply allows smooth compilation with gcc 4.3 Tango 7 has been developed and tested using omniORB 4.1.3 - Control access in C++ (It was already available for Java) - New DevEncoded attribute data type - New attribute data transfer (Using IDL union instead of Any) - Optimized image transfer using attribute DevEncoded data type in compressed (JPEG encoder/decoder) or uncompressed format - Event queues - Multiple polling threads - Fast polling buffer history retrieval - write_read_attribute() call - Data ready event - Device dependency tree - User main event loop - Cancel asynchronous request (local to the client) - Attribute data format transferred when reading attribute(s) - Add some new constructor for class DbDatum and DeviceProxy (from const char *) - Add some equality operators for miscellaneous classes - C - New management of env. variable (Unix only) including conf. files ($HOME/.tangorc an /etc/tangorc) Small changes: -------------- - Increase default blackbox depth to 50 - Support for gcc 4.3 Windows specific: - Support VS8 (VC8) and VS9 (VC9) Bug fixes: ---------- Bugs recorded in SourceForge - 1969687: Possible crash for device server started without database - 1982044: Crash in "new DeviceProxy" in case of multi-threaded application - 2019405: Memory leak in DeviceProxy::read_attributes in case of exception - 2092748: Memorized attribute after an Init command - 2119141: const parameters for Util::trigger_xxx_polling() methods - 2150859: Wrong management in admin DeviceProxy instance admin device in case of multi TANGO_HOST - 2157328: Double memory free in DeviceProxy::command_inout_reply() method - 2182565: Removing dynamic attribute in init_device() method - 2489781: Type in database command name - 2633201: const parameters in DeviceProxy::get_attribute_config() - 2761379: DeviceProxy::alias() method for default constructed device - 2784265: Bug in doc - 2784267: Wrong output format in DeviceData/AttributeDataHistory Bugs not recorded in SourceForge ! - Fix small memory leaks in - server Db cache (16 bytes) - Database::unexport_event() method - Attribute::set_value_date_quality() methods family when attribute quality is set to ATTR_INVALID - Remove the server ORB endPoint defined in code before the call to ORB_init() - Fix bug when starting a DS with "database on file" - Clean shutdown of signal thread when a DS is killed - Remove the "was only XYZ ms ago" in the error description in case of too frequent re-connection attempt. - Change event on attribute using the DevState data type required the change property to be set! 04/2008 ******************************************************* * * * Tango release 6.1.1 : Changes since version 6.0.0 * * * ******************************************************* - Bug fixes: - Compatibility problem between release 6.0 and 6.1 ******************************************************* * * * Tango release 6.1.0 : Changes since version 6.0.0 * * * ******************************************************* - Stateless event subscription : an event subscription is possible now, even when the device server is not running. The subscribe_event method takes a new boolean parameter to trigger stateless event subscription. - Attribute::set_write_value methods have been added for spectrum and image data types. - Added extratction methods to DeviceAttribute to individually extract read and set point values. Added methods to read the data dimensions which are compatible with the Java API. - Ported to MacOSX - Class dlls for Windows can be created and can be used as for UNIX now. - Device server now uses a database cache to get all their data during their starting sequence. This cache is filled in by a new Database server command and destroyed at the end of the startup sequence. When possible, all data are fetched from this cache instead of from the database. If it is not possible to fill in this cache for any reason, the device server process starts using the traditional way. - Optimize network calls during connection establishment between client and server - Implement a new timeout management for database object access. The timeout used has a different value when the device server is in its starting phase - Automatic management of a TCP connection establishment timeout for the database object - Add new Database class methods to interface the two new database server commands (DbGetDataForServerCache and DbDeleteAllDeviceAttributeProperty) - Change the way the DB is cleanup up due to dynamic attribute deletion during device server shutdown - Default value for the "doc_url" part of the info() network call changed to "http://www.tango-controls.org" - Add new methods allowing a better way to set the CVS tag and CVS location info returned by the info() network call - Add 2 new Attribute::set_properties() methods which can be used in a Tango class init_device() method - Bug fixes: - Solved deadlock when subscribing events from different threads. - Initialisation of memorized attributes during the init command. - Correction of client and server shutdown procedures when using the event client part. - Corrected the event synchronisation when a client is using another threading package than omnithreads. - Fix client multi-threading issue when a CORBA exception was received during a re-connection - Name letters case bug in polling thread command and in polled objects name stored in database - One re-connection case was not "transparent" - Clarify some exception messages - Polling thread synchronisation bug for internal commands start-polling, stop-polling and rem-obj-polling - Bug in the admin device RemObjPolling command related to polling properties management (When the removed object was last polled object) - Bug in asynchronous call in PUSH_CALLBACK mode when used intensively - Polling configuration mismatch after an Init command on the admin device - The DbGetDeviceList database command now has the same wildcard for its two parameters ("*") - Bug in the remote "info" call for devices implementing IDL3 (missing CVS Tag and CVS location) - Bug when getting the State history using the command_history() calls - Windows specific: Device server configured as "daemon" correctly starts on a windows host with netowrk connection unavailable when the DS starts 06/2007 ***************************************************** * * * Tango release 6.0 : Changes since version 5.5.2 * * * ***************************************************** - Ported to OmniORB 4.1, which is a major release of omniORB and changes the generated code from the IDL. - Ported to 64 bit architectures (Linux and Windows (x64)) - Add an attribute configuration event which is pushed every time an attribute property changes. This allows to synchronize all client displays of an attribute. - Added new filterable fields "quality" and "delta-t" (sine last archive_event) to the archive event - Events with quality invalid are only send once as long as the quality stays invalid. - Events with exceptions are only send once as long as the exception does not change. - Modified the synchronisation between the event consumer and the keep alive thread. Exchanged the global mutexes on the channel and the callback maps by individual monitors for every channel and every callback. The monitor can time-out and will not block the event reception for a long time in case of problems. To synchronise with subscribe or unsubscribe requests, added a global reader writer lock around the two maps. The subscribe thread is the writer and the event consumer and the keep alive thread are the readers. - When removing dynamic attributes all their configuration will be deleted now from the database. Polling configuration and event configuration properties will be deleted. - Events are available for devices servers running with a file database or without database. - Filling polling buffer using Util::fill_attr_polling_buffer() now possible also for R/W attribute - Add get/set min/max_value methods family in the WAttribute class - A bunch of new methods was added to the C++ database API to implement the same functionality as the Java database API. get_host_list, get_services, register_service, unregister_service, get_class_for_device, get_class_inheritance_for_device, get_device_exported_for_class, put_device_alias, delete_device_alias, put_server_info, delete_server_info, get_server_class_list, get_server_name_list, get_instance_name_list, get_server_list, get_host_server_list, get_device_class_list, get_device_property_history, get_device_property_list, get_device_attribute_property_history, get_class_property_history, get_class_list, get_class_property_list, get_class_attribute_property_history, get_class_attribute_list, get_attribute_alias, put_attribute_alias, ... - Methods to change timeouts for groups (common or individual) - New Util::get_tango_lib_release() method - Add the DeviceClass::device_destoyer() method (opposite of the device_factory) - The polling thread is now configured without creating a separate thread (new argument in its ADD_OBJ_POLLING command) - Add omni_thread::ensure_self object in AutoTangoMonitor and NoSyncModelTangoMonitor classes in order to use these objects in threads not created by omni_thread (Python thread for instance) - Add device name in Tango monitor print messages - MAX_TRANSFER_SIZE is now 256 Mbytes - Removed all #ifdef for HP-aCC compiler - The Tango database server do not use the root account for MySQL any more. You can configure any account to be used via the my.cnf configuration files or via the environment variables MYSQL_USER and MYSQL_PASSWORD. - Bug fixes: - Polling did not restart correctly after an Init command on a device server admin device - Bug in re-connection after a device server admin device Init, Restart or Devrestart command - Two small memory leaks when dealing with dynamic attributes - Admin device did not handle device alias in its DevPollStatus command - Bug in add_attribute() method if you try to add an attribute with the same name but a different definition (different data type, data format, ...) - Several bugs when removing dynamic attributes - Bug when removing a CORBA servant for non-exported device - Bug in Util::get_device_list_by_class() in some specific cases - Bug in the forced event without criteria checking. Some flag init. was missing - Bug in re-connection in case of asynchronous call - Bug in the subsribe_event() method when the DeviceProxy has been created using a syntax like "host:port/a/b/c" with host and port not the same than the one defined by the TANGO_HOST environment variable - In the case of a too long delivery time for events the notifd closes the connection to a client. Now this case is detected in the client and the client will reconnect. ***************************************************** * * * Tango release 5.5.2 : Changes since version 5.5 * * * ***************************************************** - Contains a new version of the Tango database which keeps a history of the last changes for every property. This needs the creation of new tables in MySQL and a new database server. - Corrected the reconnection to the notification daemon in the case of network cuts. - Increased the maximum data size to be transferred between server and client from 8Mbytes to 16Mbytes. - Since release 5.5 a server under windows could no longer be installed as a windows service. Corrected the problem. ***************************************************** * * * Tango release 5.5 : Changes since version 5.4 * * * ***************************************************** - Change and archive Events can be pushed manually from the code now without polling. Two ways are possible: 1.) Push events but check the event configuration (as the polling thread). Events are fired exactly under the same conditions as with the polling. 2.) Push events without configuration check. The event is fired without any value checking. - The quality event was removed and integrated as filter "quality" to the change event. - The user event was adapted to follow the structure of pushing change or archive events. - Event reconnection will follow now when a server was moved to a different host. The connection will be rebuild to the new notifd. - Polling configuration for attributes and commands specified in the code with Pogo are written to the database at server start-up. The polling will start immediately and no longer on a first reading request. - The transparent reconnection is now the default reconnection mode. - Naming requests to the database are cached for a DeviceProxy. A reconnection request will be emitted only once a second for a DeviceProxy connection. The same feature is implemented in the Java api. - Debugging is now possible with the Linux 2.6 kernel. - Support of gcc 4.0 - Support of VC7 and VC8 under Windos. - Integration of code for device servers written in Python. - Bug fixes: - Corrected event priod handling for periodic events. - Corrected rounding errors when checking the conditions. of change and archive events. - Corrected constructor for the class GroupReply. ***************************************************** * * * Tango release 5.4 : Changes since version 5.3 * * * ***************************************************** - Stopped the automatic polling startup of attributes at event subscription. All polling has be be configured manually! Subscription to events is only possible if the event properties for an attribute are properly configured and the polling is started! - An exception during initialisation of memorized attributes will no longer result in an exit of the server. - Memorized attributes can be used in two ways now. 1) The setpoint gets initialised during a server startup. No write happens on the attribute. 2.) The setpoint gets initialised during a server startup and is written to the attribute. The initialisation mode can be triggered by Attr::set_memorized_init(bool write_on_init) method during attribute creation. The two options are supported by Pogo. - The archive event behavior has changed. The archive period is no longer set to 10 seconds as default. If no period is specified, no periodic archive event is send. - Bug fixes: - Corrected the wrong archive period reading after a server restart. - Changed DServerClass::instance() to return an exception in the case of a not initialised object. The exit() killed the server during a startup when a client sends requests to early. - Changed the clean-up mechanism when shutting down the ORB. Destroy ORB when returning from run(). In 5.3 This was done in the main and when missing caused some threads to hang-up with the Linux kernel 2.4.x. - Avoid calling Device_3Impl::status2attr() during attribute reading when an error was detected. Avoids segmentation fault in status2attr(). ***************************************************** * * * Tango release 5.3 : Changes since version 5.2 * * * ***************************************************** - Fix bug in server part which prevents using object files compiled with 5.1 to link with 5.2 - Changed the clean-up mechanism when shutting down the ORB. Destroy ORB when returning from run(). - Fix bug for reading and applying the period of archive events. ***************************************************** * * * Tango release 5.2 : Changes since version 5.1 * * * ***************************************************** Small changes : --------------- - Support for gcc 3.4.x compilers - Support for Solaris computer with gcc (Compiled and Tested on Solaris 7 with gcc 3.3.2 and Solaris 9 with gcc 3.3) WARNING : The support of gcc on Solaris needs log4tango release 4.0.2 ------- - The host name stored in database is now the Fully Qualified Domain Name WARNING : For those using events, you now need "notifd2db" release 1.4 ------- - Events are now available also for device server started with the "-file" option. Needs "notifd2db" release 1.4 - Added attribute quality change event firing by the Attribute::set_quality() and Attribute::set_value_date_quality() methods via a new method argument - New method DeviceAttribute::get_type() and DeviceData::get_type() - Add a AttrManip class constructor from a C++ string - Add a DeviceImpl::remove_attribute() method - A new Tango::string_dup() method to replace the CORBA::string_dup() - Management of two new class properties called "CVS_tag" and "CVS_location" - Add a method Command::set_name() - Change parameters for omniORB server threading strategy. Server switches from thread per client to thread pool at 50 connections and max number of threads is now 100 - When events are used, add a new error "API_PollThreadOutOfSync" if polling thread discards work item because it is late. - Add two new commands in device server admin. device for device creation wizard - Start a device server with "-v5" if you want to see Tango library messages. The "-v4" now put only classical devices in DEBUG mode. Bug fixes : ----------- - Review exception thrown by the DeviceProxy::subscribe_event() and DeviceProxy::unsubscribe_event() - No more "Class not initialised" at device server startup (It was a bug introduced by V5) - Fix bug for device server started with the "-file" option in the get device property and get class property features - No more "seg faults" in the DeviceAttribute::has_failed() method - For Solaris : Reset SIGINT and SIGQUIT signals handler to default value. - Fix deadlock in device server introduced in V5 in some specific cases when device server manage device with commands or attribute polled at startup and by first reading - Correctly initialise fileds "attr_name" and "event" in the EventData structure passed to client when the event hartbeat is missing - Fix incoherency between C++ and Java API for the Database::delete_device_attribute_proerty() and Database::delete_class_attribute_property() - Fix bug which generates a "core dumped" when killing device server on Debian Linux system - Fix bug in the archive event period returned to the client with the get_attribute_config call - Fix bug in the date stored in Attribute history when using polling buffer externally filled and exception - Fix bug in event reconnection (one attribute name was still case dependant) - Fix bug when asking polling thread to poll state or status attribute. Polled them as attributes only for device server implementing IDL 3 - Fix bug in device server startup phase for device server with polled objects at startup and at first reading. ***************************************************** * * * Tango release 5.1 : Changes since version 5.0 * * * ***************************************************** Small changes : --------------- - Remove device name from library default value from attribute label property - An empty string for string attribute properties will now return their values to the default one (from lib or from a user defined one) - Some improvements in error management when parsing database file with the device server -file option Bug fixes : ----------- - Fix bug when setting R/W attribute write value with the WAttribute::set_write_value() method in device server startup phase - Fix bug when polling a Device_2Impl device's attribute which throws an exception (crashed the device server) - Library default value for the attribute label property not stored in database any more - Fix bug in Database::get_class_attribute_property() and Database::get_device_attribute_property(). Could generate stange behaviour (even core dumped) when reading attribute configuration on a Device_2Impl device or when creating on AttributeProxy object on a Device_2Impl - Fix bug when reading R/W Device_2Impl attribute. The last written value was always 0. - Fix bug which crashes a device server when a client linked with Tango V4 tryed to get attribute history from a Device_3Impl - Fix some tables in the HTML doc which appears with only one row. ***************************************************** * * * Tango release 5 : Changes since version 4.3 * * * ***************************************************** Main changes : -------------- - A new way to code attribute inside a device server. - It is now possible to read several attributes with the read_attributes call even if one of them failed. - It is now possible to write several attributes with the write_attributes call even if one of them failed. - Four new attribute data type which are : Boolean, float, unsigned char and unsigned short. - It now supports image and spectrum attributes as READ_WRITE or READ_WITH_WRITE attribute. - Device state and status can be read as attributes. - Added memorized attributes (only for scalar attribute). - Each attributes now support a four thresholds level alarm (instead of two) - Each attribute implements a Read Different than Set (RDS) alarms. - New attribute configuration set (including alarm and event parameters). - External triggering of the polling thread. - Add methods to set the attribute or command polling buffer. - A new device server command line option (-file=) allowing a device server to run using a file to get/store properties instead of the database. - Four monitors per device in a server instead of one allowing a better concurrency model. - Auto tuning of the polling thread and configuration at device server startup time by a separate thread Small changes : --------------- - It now uses omniORB 4.0.5 - Exception thrown if you subscribed two (or more) times to the same event. - AttributeProxy class constructor suppports attribute name syntax like "device alias/attribute name". - Added calls in Database and DeviceProxy classes to get alias name from device name. - It is now possible to defined command or attribute polling buffer depth individually. - Added copy constructor, assignement operator and destructor for the EventData class. - DeviceProxy and AttributeProxy classes constructor allow device or attribute name specified like "//host:port/....". - Added the "source" parameter value in device black box for command_inout and read_attribute calls. - Only one line stored in device black box for command_inout or read_attribute calls when used from IDL release 2 or 3. - When killing a device server, it now waits for last request to be ended. - Added insertor/extractor for Boolean type to the DbDatum class. - The admin device command "QueryDevice" now returns device name in the following syntax : ::. - Add some methods in the DeviceDataHistory and DeviceAttributeHistory classes for compatibility reasons. - Added many new Attribute::set_date and Attribute::set_value_date_quality methods. - The dev_type of the info call in now a string instead of a numer. - Added DeviceClass methods to set/get the info device type field. - If a server is not able to connect to the notifd on its host, it now unexports its event channel from the database. - The event heartbeat is now manage in the polling thread as a separate object. This allows to have periodic event of any period even greater than 10 seconds. - DeviceProxy::subsribe_event now throws exception in case of change event without any related attribute configuration parameters set. - New construcor in TangoMonitor class with a name to ease debugging. - Device and class attribute properties can now be array. Needs datbase device server release 2.4.0 or above. Compatibility with older database release is supported. - Remove all direct access to database device in a server. Now, always uses method of the Database class. - Change library default value for attribute label and format configuration set. - By default, DeviceAttribute and DeviceData now throws exception if trying to extract data from empty instance. - WIN 32 specific : The polling thread uses WIndows Performance Counter to measure command or read attribute execution time Bug fixes : ----------- - When getting attribute history from polling buffer and attribute has a quality factor set to ATTR_INVALID. - In the Database::get_class_property method. Could generate some strange "core dump/seg fault" in DeviceClass initialization. - In the admin device "DevRestart" command. The device name passed as parameter was still case dependant. - If date not set by the user, attribute date automatically set when attribute quality factor is ATTR_INVALID. - In the asynchronous PUSH_CALLBACK model. The callback thread ate all CPU power. - When inserting vector into DbDatum object. Still a stream problem. - Fix order in which device server classes are destroyed (opposite order than the one used during device server startup phase) - In Database::get_info() method for WIN32. A call to CORBA in() method was missing - In DeviceProxy::adm_name() method. It now returns full admin device name with host/port in case of non database device. - In device exit sequence if an exception was thrown during the Util::init method. ***************************************************** * * * Tango release 4.3 : Changes since version 4.2 * * * ***************************************************** - Fix bug in server part which prevents a device server compiled with Tango release 4.2 to run using Tango 4.1 shared library ***************************************************** * * * Tango release 4.2 : Changes since version 4.1 * * * ***************************************************** - Add full reconnection between clients/servers and the CORBA notification service daemon. - Add SA_RESTART flag when signals are installed in the operation system - DeviceImpl::get_db_device() method now throws exception in case of non database device - DeviceProxy constructor from string does not "lowercase" the passed string any more - Add a default setting for attribute quality factor at Attribute object creation time - Fix bug in event generation if device name stored in database contains upper case letters - Fix bug when reading attribute from CACHE and attribute quality factor set to INVALID - Fix bug when modifying attribute properties max_value, min_alarm or max_alarm without any change on the min_value property - Fix bug in read_attributes() call when source is not DEVICE and some of the device attributes/commands are polled and "AllAttr" used as attribute name - Windows service : Fix bug which prevents device server used as service with polled attributes or commands to start correctly. ***************************************************** * * * Tango release 4.1 : Changes since version 4.0 * * * ***************************************************** - Fix bug in some Database class methods when used with gcc 3.2 - Remove unecessary call to "connect(this)" in DeviceProxy::unsubscribe_event() method - Fix bug if several strings used in the filter string(s) passed to the DeviceProxy::subscribe_event() method - Add a way to send command to the KeepAliveThread event thread This allows the ApiUtil::cleanup method to work properly - Fix bug in the change detection for change event when the attribute is a string - Add a call to the event callback for event when the client re-connect to a server which has been re-started - Change the order of include files in the master tango include file - Fix bug when defining attribute min_value, max_value, min_alarm or max_alarm in scientific notation for long attribute - Add a check on the exception minor code of the CORBA::IMP_LIMIT exception before adding error description in the exeception message - The Group::get_device() methods now throw an exception if the device is not reachable - Windows DLL : Don't ask anything to be done by "atexit" call due to a deadlock in omniORB ORB shutdown in this case. - Windows DLL : Add some import/export declarartions. ***************************************************** * * * Tango release 4 : Changes since version 3.0.2 * * * ***************************************************** - Added the event system - Added the Group class - Added the AttributeProxy class - It's now possible to have a Tango device server using the Tango lib as a Windows DLL - Doc and Tango WEB pages updated - Device destructor are now called when a device server exits - The library versionning now uses the classical way of doing - Fix memory leaks - In the Database::get_device_exported() call - In the DeviceProxy::is_polled() method if nothing is polled - In the DeviceProxy::command_inout_asyn() call using fire and forget mode - In the State command for devices with attributes with an alarm level set and with one of these attribute throwing exception - The Win32 device server graphical window "Debug" menu has been updated to take logging into account - Added Attribute::set_write_value() methods - Clean-up the way a device server is killed. The "kill" command of the administration device will generate the Valgrind report file if the server is started using Valgrind. If you want to benefit from this change, add the Util::server_cleanup() call at the end of your device server main function. See Tango V4 doc chapter 8.4.6 for example. - Fix some gcc compiler warnings when used with its -Wall option - Fix bug in the DeviceProxy copy constructor and assignement operator - Change the way DeviceProxy::write_attribute() method is written - Added DeviceAttribute constructors from a "const char *" - Split all "str().c_str()" in a two lines code (for Win32 compiler) - Add a check on polling property number when server starts - Add a new command to the polling thread to kill it - Fix bug when updating (via set_attribute_config) attribute properties and the min_value attribute property was set to either "NaN" or "Not specified" - Device state switches to ALARM if one of the device attribute does not have alarm level defined but have its quality factor set to ALARM - Fix bug in DeviceProxy::poll_command(const char *...) and in DeviceProxy::poll_attribute(const char *...) - Fix bug for device server started without database and a device name given on command line mixing upper and lower case letters - It's now possible to send command to the polling thread from itself - Added DeviceProxy::set_transparency_reconnection() and DeviceProxy::get_transparency_reconnection() methods to silently handle device reconnection - Added the ATTR_CHANGING attribute quality factor - In the BY_CLASS and BY_PROCESS device server process serialization model, the class (or process) monitor is taken during device(s) creation - Fix bug when inserting/extracting vector in a DbDatum object. This bug appaers only for vector with element of different size (for instance, a vector with first element set to 1.2345 and the second element set to 2.3) - Change in polling strategy: - Add a random number of milli seconds (between 0 and 500) before the first polling of each object (command or attribute) to be polled - Take command execution time into account in the "Data not updated since " polling status string ********************************************************* * * * Tango release 3.0.1 : Changes since version 3.0.0 * * * ********************************************************* - C++ Tango now uses omniORB 4.0.1 - C++ client classes : - Device timeout are back - It is now possible to have several Tango database servers within one control system - Added some functions to easily print DeviceData, DeviceDataHistory, DeviceAttribute and DeviceAttributeHistory instances - It is now possible to create a DeviceProxy instance from the device alias name - Command and Attribute names are case insensitive - Change in parameters of some DeviceProxy class logging methods - Change in parameters of the DeviceProxy asynchronous replies methods - The asynchronous calls now support device_2 and device IDL interfaces - Bug fixes : - In reconnection algorithm - Memory leak in DeviceProxy constructor in case of device not defined in database - C++ server classes : - Attributes names are now stored in black-box - Remove check if a class without any device defined in database is embedded in a server - Tango device server used as Win 2000 service does not exit anymore at logoff - Clarify message displayed when a server is not able to connect to database - New serialization model in device server - Bug fixes : - No message when killing a DS with the admin device kill command (Solaris only) - Some DevVarStringArray element printing (Win32) - RestartServer admin command now start a thread to do its job - In polling thread for heavily loaded servers with command with a long response time ********************************************************* * * * Tango release 3.0.0 : Changes since version 2.2.0 * * * ********************************************************* - C++ client classes : - Added asynchronous calls to execute commands, read_attribute or write_attribute - Added ApiUtil::cleanup method and destructors method - Fix bug in the return value of the DeviceAttribute class extraction methods when extracting data into C++ vectors - C++ server classes : - Added logging features - The client host name is now stored in the device black-box - Added three serialization models (by device, by class and by process) - Change the way how TangoMonitor was implemented - The "always_executed_hook" method is now also called when getting the deice state or status as CORBA attributes - The date returned when reading attributes is now also correct with Win32 - All C++ classes : - Ported to gcc 3.2.x - Some internal cleanups - Java server classes : - Minor bug fixes - Java client classes : - Added asynchronous calls to execute commands, read_attribute or write_attribute Changes since version 2.1.2 --------------------------- - C++ client classes : - Adapted to omniORB use - C++ server classes : - Adapted to omniORB use - Add a new get_device_list() method in the Util class - Modified the Util::get_class_list() method in order to takes the DServer class into account - Modified the Util::get_device_by_name() method in order to takes the DServer device into account - Modified the Util::get_device_list_by_class mrthod to take into account the DServer device. - Added a new parameter to the Attribute::set_value() methods to ask CORBA to free memory allocated for the attribute - Java server classes : - Adapted to JacORB use - Java client classes : - Adapted to JacORB use - Update of the Database.delete_device_attribute_property and Database.delete_class_attribute_property methods. - Added a DeviceProxy.set_transparency_reconnection() and DeviceProxy.get_transparency_reconnection() methods - Added a -DTANGO_TIMEOUT option for client timeout on the java interpreter command line - Merge of the three Tango packages (Tango, TangoDs and TangoApi) and the CORBA classes within the same jar file called TangORB.jar Changes since version 2.1.1 --------------------------- - C++ client classes : - Fix bug in data extraction from the DeviceAttribute class when the read_attributes call was local to the process - Add re-connection to the set_timeout() DeviceProxy class method - Fix bug when device is marked as non-exported in the database during DeviceProxy class constructor - C++ server classes : - Fix bug which allows concurrent access between state or status when requested as CORBA attributes and any commands or attributes - Add a string with library release number called "TgLibVers" (Also available for clients) Changes since version 2.1.0 --------------------------- - C++ client classes : - Fix bug in DeviceProxy::write_attributes() method which prevent writing more than one attribute in one call - C++ server classes : - Fix bug in polling algorithm. In some condition, the polling thread enters an infinite loop. - Fix bug for Win32 device when trying to set attribute config - Remove HP-UX specific code in source files Changes since version 2.0.2 --------------------------- - C++ client classes : - Support all Tango device name syntax (using TANGO_HOST environment variable, without environment variable but with database server parameters specified in device name and non database device) - Database object managed as a singleton per control system - No more data copy during command_inout or read_attribute calls - Support all Tango device IDL interface release 2 features (data/attributes read from polling buffer, commmand/attribute result history, polling related methods added to the DeviceProxy class) - Build an exception class hierarchy for exception thrown by these classes - Add management of device time-out - Added some missing methods (copy constructor, assignement operator...) - C++ server classes : - Kernel classes reference documentation now generated using doxygen instead of doc++ - A little file added to the library which summarizes version number. The RCS/CVS "ident" command will now tells you that release library x.y.z is composed by C++ client classes set release a.b and C++ server classes set release c.d - Fix incorrect field setting for DevFailed exception re-thrown from a CORBA exception - It's now not possible to poll the Init command - It's now possible to define a default class doc. per control system instance (using property) - The test done to check if attribute value has been set before it is returned to caller is done only if the attribute quality is set to VALID - The JTCInitialize object is now stored in the Util class - Windows : The Tango master include file (tango.h) now also include winsock.h Changes since version 2.0.0 --------------------------- - C++ client classes : - Fix bug in Database::delete_device_attribute_property() method. This method now allows deleting device attribute property for one device at a time - C++ server classes : - For writable attribute: When writing new value, the check done between this new value and the attribute property min_value or max_value is not strict anymore (only < or > instead of <= or >=) - It's now possible to reset an attribute property value to its "unspecified value" by sending it the "NaN" string. - For attribute with a min_alarm or max_alarm property defined : If the attribute quality factor is set to INVALID, the attribute value will not be checked against the alarm level during default state or status command. Changes since version 1.6 ------------------------- - Supported OS : - Suse 7.2 (and above) with gcc 2.95.3 - Solaris 7 with its Natif compiler (Forte C++ 6 Update 2) - Windows NT with VC++ 6 Note that HP-UX is not supported any more and solaris with gcc also (Waiting for gcc 3.1) - ORB : ORBacus 4.1.1 is used (All OS) - C++ client classes : - More insertors and extractors operators in the DeviceData class - Added support for attributes - Minor changes for compatibility with the Java classes client set - C++ server classes : - A polling thread is created within each device server (See documentation for all details about polling) - The documentation has been re-organized - A full library versionning is used - Implemented commands name do not start with Devxxx (DevState is now State, DevStatus is Status...) - Option -h,-?,-help for each device server - Command name, attribute name and device server name are now case sensitive name - The POA Manager is now activated earlier in server startup sequence allowing command_inout call in the init_device method - A new Init command automatically added to all devices (like the State and Status command) - No more exception when the list of supported attributes is requested to a device without attribute. The sequence length is set to 0. - The always_executed_hook method is now executed once during the read_attributes and write_attributes CORBA calls - The default class documentation URL has been modified and it is now possible to define one default value per Tango control system installation - The -d option for Tango device server used as Windows service is now replaced by a -dbg option - Fix bug which could prevent a Tango device server used as Windows service to start Changes since version 1.5 ------------------------- - DS API : Fix bug in the DeviceImpl class add_attribute() method - DS API : Command and attributes now support a command display types. This is used by the future Tango Application Toolkit for generic display software - DS API : Now, with two new options (-nodb and -dlist), it is possible to run a Tango device server without a database server. Obviously, some Tango device server features are lost if these options are used (See doc for more details) - DS API : Windows NT specific : - To use the operator between sequence and vector, it is now necessary to add a "using namespace Tango;" line in your source code - A window is now displayed if device creation failed - Tango has been generated as a DLL. WARNING : This is only for client. Some work is still necessary for server. - DB and DEV API : Re-connection now fully operational - DB and DEV API : Correct management of exception. - Java specific --------------- - DSAPI : Change the db call used to get device server class list to DbGetDserverClassList - DEV API : Add attribute management Changes since version 1.4 ------------------------- - Client API classes added to the library - New re_throw_exception() methods in the Except class - Read_attributes now support "AllAttr" as attribute name to read all attributes value within a single call - Add a add_attribute() method to the DeviceImpl class to dynamically add attribute to the device attribute list - New way to define attribute properties 1 - From a Tango lib default value (lowest priority) 2 - From user default value (with a new class called UserDefaultAttrProp) 3 - From the database (highest priority) - A new "pattern" to prevent full re-compile of C++ servers when new data members are added to classes used by programmer - For multi-classes device server, it is now possible to use the Util::get_device_by_name() method in the device constructor - Added "<<" operator overloading functions between DevVarxxxArray types and C++ vector - Added "<<" operator overloading functions between DevVarxxxArray types and ostream (for easy printing) - Correct print of exception data members when device constructor throw exception during device server startup sequence Changes since version 1.3 ------------------------- - Fix bug in the Tango::DServer::restart() method preventing a correct device restart - Fix a bug in the Tango::Util::get_device_by_name() method preventing the method to find the correct device in the device server device list Changes since version 1.2 ------------------------- - The Tango lib now include the user classes to easily access the Tango database - For linux : Add the possibility to have the signal handler executed in the calling thread (instead of the signal management thread) - For linux : Change the way how a server is killed in order to also destroy user thread(s) - Add a new CORBA attribute in the Tango IDL definition to retrieve the name of the administration device associated to the server hosting the device - Change the DevRestart command philosophy. It is not any more a command automatically added to every device but a command on the device server administration device (with device name to be restarted as input parameter). A command to restart the whole device server has also been added to this administration device. Changes since version 1.1 ------------------------- - Fix bug in the Tango::MultiClassAttribute::init_class_attributes() method - Remove database specific error codes Changes since the Tango alpha release (installed as version 1.1) ---------------------------------------------------------------- - Support CORBA 2.3 - Everything in a Tango namespace (C++ specific) - Remove all assert from library (C++ specific) - Main attributes properties (format, type, name..) now hard-coded in user code - Change in the DevFailed exception definition - Complete new handling of signals. Now, all servers are automatically threaded and one thread is dedicated to signal handling. This allow user code to do what they want in signal handler - All exceptions related methods are now grouped in a "Except" class - New method to generate DevFailed exception from a CORBA exception - Change name of the main include file (tango.h instead of tango_ds.h) - DevRestart now delete and completely re-create device. The client has to reconnect. - Server can start even if the database server is not there (for the starter device server) - Include and lib directories re-organized - Tango device server running on NT may now run as NT service - Add a completely new graphical user interface for device server running on Windows NT tango-9.2.5a/lib/0000755023471100065110000000000013034745260010560 500000000000000tango-9.2.5a/lib/Makefile.am0000644023471100065110000000016113034744715012536 00000000000000# We want to continue traversing into cpp and idl SUBDIRS = cpp idl if TANGO_JAVA_ENABLED SUBDIRS += java endif tango-9.2.5a/lib/Makefile.in0000644023471100065110000005052013034745122012544 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @TANGO_JAVA_ENABLED_TRUE@am__append_1 = java subdir = lib DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = cpp idl java DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # We want to continue traversing into cpp and idl SUBDIRS = cpp idl $(am__append_1) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/0000755023471100065110000000000013034745257011350 500000000000000tango-9.2.5a/lib/cpp/Makefile.am0000644023471100065110000000017113034744715013321 00000000000000 SUBDIRS=log4tango server client EXTRA_DIST = tango.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = tango.pc tango-9.2.5a/lib/cpp/Makefile.in0000644023471100065110000005532513034745122013336 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/tango.pc.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = tango.pc CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = log4tango server client EXTRA_DIST = tango.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = tango.pc all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tango.pc: $(top_builddir)/config.status $(srcdir)/tango.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pkgconfigDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-pkgconfigDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/tango.pc.in0000644023471100065110000000044313034744715013330 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: tango Description: The tango constrol system library Requires: omniDynamic4 >= 4.1.6, omniCOS4, log4tango, libzmq Version: @VERSION@ Libs: -L${libdir} -ltango Cflags: @CPP_ELEVEN@ -I${includedir}/tango tango-9.2.5a/lib/cpp/log4tango/0000755023471100065110000000000013034745255013244 500000000000000tango-9.2.5a/lib/cpp/log4tango/m4/0000755023471100065110000000000013034745255013564 500000000000000tango-9.2.5a/lib/cpp/log4tango/m4/AC_CREATE_PREFIX_CONFIG_H.m40000755023471100065110000001172113034744756017637 00000000000000dnl @synopsis AC_CREATE_PREFIX_CONFIG_H [(OUTPUT-HEADER [,PREFIX [,ORIG-HEADER]])] dnl dnl this is a new variant from ac_prefix_config_ dnl this one will use a lowercase-prefix if dnl the config-define was starting with a lowercase-char, e.g. dnl #define const or #define restrict or #define off_t dnl (and this one can live in another directory, e.g. testpkg/config.h dnl therefore I decided to move the output-header to be the first arg) dnl dnl takes the usual config.h generated header file; looks for each of dnl the generated "#define SOMEDEF" lines, and prefixes the defined name dnl (ie. makes it "#define PREFIX_SOMEDEF". The result is written to dnl the output config.header file. The PREFIX is converted to uppercase dnl for the conversions. dnl dnl default OUTPUT-HEADER = $PACKAGE-config.h dnl default PREFIX = $PACKAGE dnl default ORIG-HEADER, derived from OUTPUT-HEADER dnl if OUTPUT-HEADER has a "/", use the basename dnl if OUTPUT-HEADER has a "-", use the section after it. dnl otherwise, just config.h dnl dnl In most cases, the configure.in will contain a line saying dnl AC_CONFIG_HEADER(config.h) dnl somewhere *before* AC_OUTPUT and a simple line saying dnl AC_PREFIX_CONFIG_HEADER dnl somewhere *after* AC_OUTPUT. dnl dnl example: dnl AC_INIT(config.h.in) # config.h.in as created by "autoheader" dnl AM_INIT_AUTOMAKE(testpkg, 0.1.1) # "#undef VERSION" and "PACKAGE" dnl AM_CONFIG_HEADER(config.h) # in config.h.in dnl AC_MEMORY_H # "#undef NEED_MEMORY_H" dnl AC_C_CONST_H # "#undef const" dnl AC_OUTPUT(Makefile) # creates the "config.h" now dnl AC_CREATE_PREFIX_CONFIG_H # creates "testpkg-config.h" dnl and the resulting "testpkg-config.h" contains lines like dnl #ifndef TESTPKG_VERSION dnl #define TESTPKG_VERSION "0.1.1" dnl #endif dnl #ifndef TESTPKG_NEED_MEMORY_H dnl #define TESTPKG_NEED_MEMORY_H 1 dnl #endif dnl #ifndef _testpkg_const dnl #define _testpkg_const const dnl #endif dnl dnl and this "testpkg-config.h" can be installed along with other dnl header-files, which is most convenient when creating a shared dnl library (that has some headers) where some functionality is dnl dependent on the OS-features detected at compile-time. No dnl need to invent some "testpkg-confdefs.h.in" manually. :-) dnl dnl @version $Id: AC_CREATE_PREFIX_CONFIG_H.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl @author Guido Draheim AC_DEFUN([AC_CREATE_PREFIX_CONFIG_H], [changequote({, })dnl ac_prefix_conf_OUT=`echo ifelse($1, , ${PACKAGE_TARNAME}-config.h, $1)` ac_prefix_conf_DEF=`echo _$ac_prefix_conf_OUT | sed -e 'y:abcdefghijklmnopqrstuvwxyz./,-:ABCDEFGHIJKLMNOPQRSTUVWXYZ____:'` ac_prefix_conf_PKG=`echo ifelse($2, , ${PACKAGE_TARNAME}, $2)` ac_prefix_conf_LOW=`echo _$ac_prefix_conf_PKG | sed -e 'y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:'` ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e 'y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:' -e '/^[0-9]/s/^/_/'` ac_prefix_conf_INP=`echo ifelse($3, , _, $3)` if test "$ac_prefix_conf_INP" = "_"; then case $ac_prefix_conf_OUT in */*) ac_prefix_conf_INP=`basename $ac_prefix_conf_OUT` ;; *-*) ac_prefix_conf_INP=`echo $ac_prefix_conf_OUT | sed -e 's/[a-zA-Z0-9_]*-//'` ;; *) ac_prefix_conf_INP=config.h ;; esac fi changequote([, ])dnl if test -z "$ac_prefix_conf_PKG" ; then AC_MSG_ERROR([no prefix for _PREFIX_PKG_CONFIG_H]) else AC_MSG_RESULT(creating $ac_prefix_conf_OUT - prefix $ac_prefix_conf_UPP for $ac_prefix_conf_INP defines) if test -f $ac_prefix_conf_INP ; then AS_DIRNAME([/* automatically generated */], $ac_prefix_conf_OUT) changequote({, })dnl echo '#ifndef '$ac_prefix_conf_DEF >$ac_prefix_conf_OUT echo '#define '$ac_prefix_conf_DEF' 1' >>$ac_prefix_conf_OUT echo ' ' >>$ac_prefix_conf_OUT echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$ac_prefix_conf_OUT echo 's/#undef *\([A-Z_]\)/#undef '$ac_prefix_conf_UPP'_\1/' >conftest.sed echo 's/#undef *\([a-z]\)/#undef '$ac_prefix_conf_LOW'_\1/' >>conftest.sed echo 's/#define *\([A-Z_][A-Za-z0-9_]*\)\(.*\)/#ifndef '$ac_prefix_conf_UPP"_\\1 \\" >>conftest.sed echo '#define '$ac_prefix_conf_UPP"_\\1 \\2 \\" >>conftest.sed echo '#endif/' >>conftest.sed echo 's/#define *\([a-z][A-Za-z0-9_]*\)\(.*\)/#ifndef '$ac_prefix_conf_LOW"_\\1 \\" >>conftest.sed echo '#define '$ac_prefix_conf_LOW"_\\1 \\2 \\" >>conftest.sed echo '#endif/' >>conftest.sed sed -f conftest.sed $ac_prefix_conf_INP >>$ac_prefix_conf_OUT echo ' ' >>$ac_prefix_conf_OUT echo '/*' $ac_prefix_conf_DEF '*/' >>$ac_prefix_conf_OUT echo '#endif' >>$ac_prefix_conf_OUT changequote([, ])dnl else AC_MSG_ERROR([input file $ac_prefix_conf_IN does not exist, dnl skip generating $ac_prefix_conf_OUT]) fi rm -f conftest.* fi]) tango-9.2.5a/lib/cpp/log4tango/m4/AC_CXX_HAVE_SSTREAM.m40000755023471100065110000000132513034744756016765 00000000000000dnl @synopsis AC_CXX_HAVE_SSTREAM dnl dnl If the C++ library has a working stringstream, define HAVE_SSTREAM. dnl dnl @author Ben Stanley dnl @version $Id: AC_CXX_HAVE_SSTREAM.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl AC_DEFUN([AC_CXX_HAVE_SSTREAM], [AC_CACHE_CHECK(whether the compiler has stringstream, ac_cv_cxx_have_sstream, [AC_REQUIRE([AC_CXX_NAMESPACES]) AC_LANG_PUSH(C++) AC_TRY_COMPILE([#include #ifdef HAVE_NAMESPACES using namespace std; #endif],[stringstream message; message << "Hello"; return 0;], ac_cv_cxx_have_sstream=yes, ac_cv_cxx_have_sstream=no) AC_LANG_POP(C++) ]) if test "$ac_cv_cxx_have_sstream" = yes; then AC_DEFINE(HAVE_SSTREAM,,[define if the compiler has stringstream]) fi ]) tango-9.2.5a/lib/cpp/log4tango/m4/AC_CXX_NAMESPACES.m40000755023471100065110000000127213034744756016464 00000000000000dnl @synopsis AC_CXX_NAMESPACES dnl dnl If the compiler can prevent names clashes using namespaces, define dnl HAVE_NAMESPACES. dnl dnl @version $Id: AC_CXX_NAMESPACES.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl @author Luc Maisonobe dnl AC_DEFUN([AC_CXX_NAMESPACES], [AC_CACHE_CHECK(whether the compiler implements namespaces, ac_cv_cxx_namespaces, [AC_LANG_PUSH(C++) AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}], [using namespace Outer::Inner; return i;], ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no) AC_LANG_POP(C++) ]) if test "$ac_cv_cxx_namespaces" = yes; then AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces]) fi ]) tango-9.2.5a/lib/cpp/log4tango/m4/AC_C_INT64_T.m40000755023471100065110000000126713034744756015660 00000000000000dnl @synopsis AC_C_INT64_T dnl dnl Provides a test for the existance of the int64_t type and dnl defines HAVE_INT64_T if it is found. Adapted from AC_C_LONG_LONG by dnl Caolan McNamara dnl dnl @version $Id: AC_C_INT64_T.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl @author Bastiaan Bakker dnl AC_DEFUN([AC_C_INT64_T], [AC_CACHE_CHECK(for int64_t, ac_cv_c_int64_t, [AC_TRY_COMPILE([#include ],[int64_t i;], ac_cv_c_int64_t=yes, ac_cv_c_int64_t=no) ]) if test $ac_cv_c_int64_t = yes; then AC_DEFINE(HAVE_INT64_T,,[define if the compiler has int64_t]) AC_DEFINE(HAVE_STDINT_H,,[define if you have the header file.]) fi ]) tango-9.2.5a/lib/cpp/log4tango/m4/AC_FUNC_SNPRINTF.m40000755023471100065110000000163313034744756016402 00000000000000dnl @synopsis AC_FUNC_SNPRINTF dnl dnl Provides a test for a working snprintf function. dnl unlike the original AC_FUNC_SNPRINTF test this one will also dnl accept snprintf implementations which return -1 if the string does dnl not fit in the buffer, e.g. snprintf on Solaris and glibc <= 2.0.6. dnl defines HAVE_SNPRINTF if it is found, and dnl sets ac_cv_func_snprintf to yes, otherwise to no. dnl dnl @version $Id: AC_FUNC_SNPRINTF.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl @author Caolan McNamara dnl AC_DEFUN([AC_FUNC_SNPRINTF], [AC_CACHE_CHECK(for working snprintf, ac_cv_func_snprintf, [AC_TRY_RUN([#include int main () { int l = snprintf(NULL,0,"%d",100); exit (!((3 <= l) || (-1 == l))); } ], ac_cv_func_snprintf=yes, ac_cv_func_snprintf=no, ac_cv_func_snprintf=no)]) if test $ac_cv_func_snprintf = yes; then AC_DEFINE(HAVE_SNPRINTF,,[define if the C library has snprintf]) fi ]) tango-9.2.5a/lib/cpp/log4tango/m4/BB_CHECK_PTHREADS.m40000755023471100065110000000137513034744756016436 00000000000000AC_DEFUN([BB_CHECK_PTHREADS], [AC_SEARCH_LIBS(pthread_key_create,pthread, [AC_DEFINE(HAVE_THREADING,,[define if threading is enabled]) AC_DEFINE(USE_PTHREADS,,[define if pthread library is available]) case $host_os in linux*) CFLAGS="$CFLAGS -D_REENTRANT" CXXFLAGS="$CXXFLAGS -D_REENTRANT" ;; solaris*) if test x$GCC = x ; then CFLAGS="$CFLAGS -mt -D_POSIX_PTHREAD_SEMANTICS" CXXFLAGS="$CXXFLAGS -mt -D_POSIX_PTHREAD_SEMANTICS" else CFLAGS="$CFLAGS -D_REENTRANT" CXXFLAGS="$CXXFLAGS -D_REENTRANT" fi ;; hpux*) CFLAGS="$CFLAGS -AA -mt +inst_close" CXXFLAGS="$CXXFLAGS -AA -mt +inst_close" ;; esac], AC_MSG_ERROR([pthreads not found])) ]) tango-9.2.5a/lib/cpp/log4tango/m4/BB_ENABLE_DOXYGEN.m40000755023471100065110000000237013034744756016446 00000000000000AC_DEFUN([BB_ENABLE_DOXYGEN], [ AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)]) AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no]) if test "x$enable_doxygen" = xno; then enable_doc=no else AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) if test x$DOXYGEN = x; then if test "x$enable_doxygen" = xyes; then AC_MSG_ERROR([could not find doxygen]) fi enable_doc=no else enable_doc=yes AC_PATH_PROG(DOT, dot, , $PATH) fi fi AM_CONDITIONAL(DOC, test x$enable_doc = xyes) if test x$DOT = x; then if test "x$enable_dot" = xyes; then AC_MSG_ERROR([could not find dot]) fi enable_dot=no else enable_dot=yes fi AC_SUBST(enable_dot) AC_SUBST(enable_html_docs) AC_SUBST(enable_latex_docs) ]) tango-9.2.5a/lib/cpp/log4tango/m4/CREATE_GENERIC_CONFIG.m40000755023471100065110000001543313034744756017110 00000000000000dnl @synopsis AC_CREATE_GENERIC_CONFIG [(PACKAGEnlibs [, VERSION])] dnl dnl Creates a generic PACKAGE-config file that has all the dnl things that you want, hmm, well, atleast it has dnl --cflags, --version, --libs. Ahhm, did you see ac_path_generic dnl in the autoconf-archive? ;-) dnl dnl this macros saves you all the typing for a pkg-config.in script, dnl you don't even need to distribute one along. Place this macro dnl in your configure.ac, et voila, you got one that you want to install. dnl dnl oh, btw, if the first arg looks like "mylib -lwhat' then it dnl will go to be added to the --libs, and mylib is extracted. dnl dnl the defaults: $1 = $PACKAGE_TARNAME $LIBS $2 = $VERSION dnl there is also an AC_SUBST(GENERIC_CONFIG) that will be set to dnl the name of the file that we did output in this macro. Use as: dnl dnl install-exec-local: install-generic-config dnl install-generic-config: dnl $(mkinstalldirs) $(DESTDIR)$(bindir) dnl $(INSTALL_SCRIPT) @GENERIC_CONFIG@ $(DESTDIR)$(bindir) dnl dnl @version $Id: CREATE_GENERIC_CONFIG.m4 9222 2003-03-11 17:21:15Z nleclercq $ dnl @author Guido Draheim AC_DEFUN([AC_CREATE_GENERIC_CONFIG],[# create a generic PACKAGE-config file L=`echo ifelse($1, , $PACKAGE_TARNAME $LIBS, $1)` P=`echo $L | sed -e 's/ -.*//'` P=`echo $P` V=`echo ifelse($1, , $VERSION, $1)` F=`echo $P-config` AC_MSG_RESULT(creating $F - generic $V of $L) test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' echo '#! /bin/sh' >$F echo ' ' >>$F echo 'package="'$P'"' >>$F echo 'version="'$V'"' >>$F echo 'libs="'$L'"' >>$F echo ' ' >>$F # in the order of occurence a standard automake Makefile echo 'prefix="'$prefix'"' >>$F echo 'exec_prefix="'$exec_prefix'"' >>$F echo 'bindir="'$bindir'"' >>$F echo 'sbindir="'$sbindir'"' >>$F echo 'libexecdir="'$libexecdir'"' >>$F echo 'datadir="'$datadir'"' >>$F echo 'sysconfdir="'$sysconfdir'"' >>$F echo 'sharedstatedir="'$sharedstatedir'"' >>$F echo 'localstatedir="'$localstatedir'"' >>$F echo 'libdir="'$libdir'"' >>$F echo 'infodir="'$infodir'"' >>$F echo 'mandir="'$mandir'"' >>$F echo 'includedir="'$includedir'"' >>$F echo 'target="'$target'"' >>$F echo 'host="'$host'"' >>$F echo 'build="'$build'"' >>$F echo ' ' >>$F echo 'if test "'"\$""#"'" -eq 0; then' >>$F echo ' cat <>$F echo 'Usage: $package-config [OPTIONS]' >>$F echo 'Options:' >>$F echo ' --prefix[=DIR]) : \$prefix' >>$F echo ' --package) : \$package' >>$F echo ' --version) : \$version' >>$F echo ' --cflags) : -I\$includedir' >>$F echo ' --libs) : -L\$libdir -l\$package' >>$F echo ' --help) print all the options (not just these)' >>$F echo 'EOF' >>$F echo 'fi' >>$F echo ' ' >>$F echo 'o=""' >>$F echo 'h=""' >>$F echo 'for i in '"\$""*"' ; do' >>$F echo ' case $i in' >>$F echo ' --prefix=*) prefix=`echo $i | sed -e "s/--prefix=//"` ;;' >>$F echo ' --prefix) o="$o $prefix" ;;' >>$F echo ' --package) o="$o $package" ;;' >>$F echo ' --version) o="$o $version" ;;' >>$F echo ' --cflags) if test "_$includedir" != "_/usr/include"' >>$F echo ' then o="$o -I$includedir" ; fi' >>$F echo ' ;;' >>$F echo ' --libs) o="$o -L$libdir -l$libs" ;;' >>$F echo ' --exec_prefix|--eprefix) o="$o $exec_prefix" ;;' >>$F echo ' --bindir) o="$o $bindir" ;;' >>$F echo ' --sbindir) o="$o $sbindir" ;;' >>$F echo ' --libexecdir) o="$o $libexecdir" ;;' >>$F echo ' --datadir) o="$o $datadir" ;;' >>$F echo ' --datainc) o="$o -I$datadir" ;;' >>$F echo ' --datalib) o="$o -L$datadir" ;;' >>$F echo ' --sysconfdir) o="$o $sysconfdir" ;;' >>$F echo ' --sharedstatedir) o="$o $sharedstatedir" ;;' >>$F echo ' --localstatedir) o="$o $localstatedir" ;;' >>$F echo ' --libdir) o="$o $libdir" ;;' >>$F echo ' --libadd) o="$o -L$libdir" ;;' >>$F echo ' --infodir) o="$o $infodir" ;;' >>$F echo ' --mandir) o="$o $mandir" ;;' >>$F echo ' --target) o="$o $target" ;;' >>$F echo ' --host) o="$o $host" ;;' >>$F echo ' --build) o="$o $build" ;;' >>$F echo ' --data) o="$o -I$datadir/$package" ;;' >>$F echo ' --pkgdatadir) o="$o $datadir/$package" ;;' >>$F echo ' --pkgdatainc) o="$o -I$datadir/$package" ;;' >>$F echo ' --pkgdatalib) o="$o -L$datadir/$package" ;;' >>$F echo ' --pkglibdir) o="$o $libdir/$package" ;;' >>$F echo ' --pkglibinc) o="$o -I$libinc/$package" ;;' >>$F echo ' --pkglibadd) o="$o -L$libadd/$package" ;;' >>$F echo ' --pkgincludedir) o="$o $includedir/$package" ;;' >>$F echo ' --help) h="1" ;;' >>$F echo ' -?//*|-?/*//*|-?./*//*|//*|/*//*|./*//*) ' >>$F echo ' v=`echo $i | sed -e s://:\$:g`' >>$F echo ' v=`eval "echo $v"` ' >>$F echo ' o="$o $v" ;; ' >>$F echo ' esac' >>$F echo 'done' >>$F echo ' ' >>$F echo 'o=`eval "echo $o"`' >>$F echo 'o=`eval "echo $o"`' >>$F echo 'eval "echo $o"' >>$F echo ' ' >>$F echo 'if test ! -z "$h" ; then ' >>$F echo 'cat <>$F echo ' --prefix=xxx) (what is that for anyway?)' >>$F echo ' --prefix) \$prefix $prefix' >>$F echo ' --package) \$package $package' >>$F echo ' --version) \$version $version' >>$F echo ' --cflags) -I\$includedir unless it is /usr/include' >>$F echo ' --libs) -L\$libdir -l\$PACKAGE_TARNAME \$LIBS' >>$F echo ' --exec_prefix) or... ' >>$F echo ' --eprefix) \$exec_prefix $exec_prefix' >>$F echo ' --bindir) \$bindir $bindir' >>$F echo ' --sbindir) \$sbindir $sbindir' >>$F echo ' --libexecdir) \$libexecdir $libexecdir' >>$F echo ' --datadir) \$datadir $datadir' >>$F echo ' --sysconfdir) \$sysconfdir $sysconfdir' >>$F echo ' --sharedstatedir) \$sharedstatedir$sharedstatedir' >>$F echo ' --localstatedir) \$localstatedir $localstatedir' >>$F echo ' --libdir) \$libdir $libdir' >>$F echo ' --infodir) \$infodir $infodir' >>$F echo ' --mandir) \$mandir $mandir' >>$F echo ' --target) \$target $target' >>$F echo ' --host) \$host $host' >>$F echo ' --build) \$build $build' >>$F echo ' --data) -I\$datadir/\$package' >>$F echo ' --pkgdatadir) \$datadir/\$package' >>$F echo ' --pkglibdir) \$libdir/\$package' >>$F echo ' --pkgincludedir) \$includedir/\$package' >>$F echo ' --help) generated by ac_create_generic_config.m4' >>$F echo ' -I//varname and other inc-targets like --pkgdatainc supported' >>$F echo ' -L//varname and other lib-targets, e.g. --pkgdatalib or --libadd' >>$F echo 'EOF' >>$F echo 'fi' >>$F GENERIC_CONFIG="$F" AC_SUBST(GENERIC_CONFIG) ]) tango-9.2.5a/lib/cpp/log4tango/m4/PETI_PEDANTIC_GCC.m40000755023471100065110000000255213034744756016446 00000000000000dnl @synopsis PETI_PEDANTIC_GCC dnl dnl For development purposes, it is desirable to have autoconf dnl automatically enable warnings when compiling C or C++ sources. In dnl case the underlying compiler is a gcc, the appropriate flags are dnl "-Wall -pedantic". This macro will add them to $CFLAGS and dnl $CXXFLAGS if $CC is found to be a gcc. dnl dnl @author Peter Simons dnl original version: peti_pedantic_gcc.m4,v 1.4 2000/12/31 10:18:09 simons dnl @version $Id: PETI_PEDANTIC_GCC.m4 9222 2003-03-11 17:21:15Z nleclercq $ AC_DEFUN([PETI_PEDANTIC_GCC], [ if test "$GCC" = yes; then if test "$host" = x86-pc-nto-qnx; then CFLAGS="$CXXFLAGS -Wno-unused -O0" CXXFLAGS="$CXXFLAGS -Wno-unused -DLOG4TANGO_MISSING_INT64_OSTREAM_OP -O0" else case `$CXX --version` in *2.97*) CFLAGS="$CFLAGS -Wall -Wno-unused -pedantic -D_ISOC99_SOURCE" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused -pedantic -D_ISOC99_SOURCE" ;; *2.96*) CFLAGS="$CFLAGS -Wall -Wno-unused" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused" ;; *) CFLAGS="$CFLAGS -Wall -Wno-unused -pedantic" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused -pedantic" ;; esac fi fi ]) tango-9.2.5a/lib/cpp/log4tango/m4/RSSH_CHECK_SUNPRO_CC.m40000755023471100065110000000162213034744756017106 00000000000000# RSSH_CHECK_SUNPROC_CC([ACTION-IF-YES], [ACTION-IF-NOT]) # ------------------------------------------------------ # check : are we using SUN workshop C++ compiler. # Corresponding cache value: rssh_cv_check_sunpro_cc is set to yes or no # #@author Ruslan Shevchenko , 1998, 2000 #@version $Id: RSSH_CHECK_SUNPRO_CC.m4 9976 2005-01-14 15:06:09Z taurel $ # # RSSH_CHECK_SUNPRO_CC([ACTION-IF-YES],[ACTION-IF-NOT]) # AC_DEFUN([RSSH_CHECK_SUNPRO_CC], [AC_CACHE_CHECK([whether using Sun Worckshop C++ compiler], [rssh_cv_check_sunpro_cc], [AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([], [#ifndef __SUNPRO_CC # include "error: this is not Sun Workshop." #endif ], rssh_cv_check_sunpro_cc=yes, rssh_cv_check_sunpro_cc=no) AC_LANG_RESTORE]) if test ${rssh_cv_check_sunpro_cc} = yes then $2 : else $3 : fi ])# RSSH_CHECK_SUNPROC_CC tango-9.2.5a/lib/cpp/log4tango/m4/libtool.m40000644023471100065110000106043413034744756015427 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS tango-9.2.5a/lib/cpp/log4tango/m4/ltoptions.m40000644023471100065110000003007313034744756016011 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) tango-9.2.5a/lib/cpp/log4tango/m4/ltsugar.m40000644023471100065110000001042413034744756015435 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) tango-9.2.5a/lib/cpp/log4tango/m4/ltversion.m40000644023471100065110000000126213034744756016001 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) tango-9.2.5a/lib/cpp/log4tango/m4/lt~obsolete.m40000644023471100065110000001375613034744756016341 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) tango-9.2.5a/lib/cpp/log4tango/README0000644023471100065110000000102113034744765014043 00000000000000Log4Tango is a light and custom version of log4tango for Tango. See doc/html/index.html for details. The log4tango library port from the LOG4J Java library was initiated by Bastiaan Bakker. Log for C++ (short name: log4tango), a C++ library for flexible logging. Copyright (C) 2000-2002 LifeLine Networks bv Copyright (C) 2000-2002 Bastiaan Bakker Portions Copyright others. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public. See COPYING for details. tango-9.2.5a/lib/cpp/log4tango/configure.in0000644023471100065110000000544213034744764015506 00000000000000AC_INIT(log4tango, 5.0.1, nicolas.leclercq@synchrotron-soleil.fr) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE() # autoconf 2.50 or higher to rebuild aclocal.m4, because the # AC_CREATE_PREFIX_CONFIG_H macro needs the AS_DIRNAME macro. AC_PREREQ(2.50) # # +1 : ? : +1 == new interface that does not break old one # +1 : ? : 0 == new interface that breaks old one # ? : ? : 0 == no new interfaces, but breaks apps # ? :+1 : ? == just some internal changes, nothing breaks but might work # better # CURRENT : REVISION : AGE LT_VERSION=5:1:0 AC_SUBST(LT_VERSION) AM_CONFIG_HEADER(include/config.h) # Checks for programs # ---------------------------------------------------------------------------- AC_CANONICAL_HOST dnl Change ld and ar if we're using sunpro compiler dnl Might as well disable static compiling on solaris dnl since it doesn't work with sunpro at the moment. RSSH_CHECK_SUNPRO_CC if test "x$rssh_cv_check_sunpro_cc" = "xyes"; then AR="$CXX -xar" AR_FLAGS="-o" LD="$CXX -pta -G" AC_DISABLE_STATIC fi AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_CXX([g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC QCC]) AC_PROG_CXXCPP AC_LANG(C++) PETI_PEDANTIC_GCC # Checks header files # ---------------------------------------------------------------------------- AC_CHECK_HEADERS([unistd.h]) AC_CHECK_HEADERS([io.h]) # Check for pthreads # ---------------------------------------------------------------------------- BB_CHECK_PTHREADS # Checks local idioms # ---------------------------------------------------------------------------- AC_C_INT64_T AC_CXX_HAVE_SSTREAM AC_FUNC_SNPRINTF # Misc. func tests # ---------------------------------------------------------------------------- AC_CHECK_FUNCS([gettimeofday]) AC_CHECK_FUNCS([ftime]) # Check for doxygen # ---------------------------------------------------------------------------- BB_ENABLE_DOXYGEN # To build on MacOSX define __darwin__ # ---------------------------------------------------------------------------- case $build_os in darwin*) AC_DEFINE(__darwin__,1,If we're running on darwin/MacOsX) CXXFLAGS="$CXXFLAGS -D__darwin__" ;; freebsd*) AC_DEFINE(__freebsd__,1,If we're running on FreeBSD) CXXFLAGS="$CXXFLAGS -D__freebsd__" ;; esac # Create files # ---------------------------------------------------------------------------- AC_CREATE_GENERIC_CONFIG AC_CONFIG_FILES([ Makefile log4tango.pc config/Makefile src/Makefile include/Makefile include/log4tango/Makefile include/log4tango/threading/Makefile tests/Makefile ]) if test "x$enable_doc" = xyes; then AC_CONFIG_FILES([ doc/Makefile doc/Doxyfile doc/html/Makefile ]) fi AC_OUTPUT AC_CREATE_PREFIX_CONFIG_H(include/log4tango/config.h,$PACKAGE_TARNAME,include/config.h) tango-9.2.5a/lib/cpp/log4tango/aclocal.m40000644023471100065110000011141713034744765015036 00000000000000# generated automatically by aclocal 1.11.3 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, # Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, [m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, # 2010, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 12 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, # 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless `enable' is passed literally. # For symmetry, `disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful (and sometimes confusing) to the casual installer], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, # Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software # Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 1 # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/AC_CREATE_PREFIX_CONFIG_H.m4]) m4_include([m4/AC_CXX_HAVE_SSTREAM.m4]) m4_include([m4/AC_CXX_NAMESPACES.m4]) m4_include([m4/AC_C_INT64_T.m4]) m4_include([m4/AC_FUNC_SNPRINTF.m4]) m4_include([m4/BB_CHECK_PTHREADS.m4]) m4_include([m4/BB_ENABLE_DOXYGEN.m4]) m4_include([m4/CREATE_GENERIC_CONFIG.m4]) m4_include([m4/PETI_PEDANTIC_GCC.m4]) m4_include([m4/RSSH_CHECK_SUNPRO_CC.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) tango-9.2.5a/lib/cpp/log4tango/Makefile.am0000644023471100065110000000244413034744765015231 00000000000000SUBDIRS = config src include tests ACLOCAL_AMFLAGS = -I m4 if DOC SUBDIRS += doc endif DIST_SUBDIRS = config src include tests if DOC DIST_SUBDIRS += doc endif EXTRA_DIST = log4tango.pc.in \ log4tango.m4 \ m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ m4/BB_ENABLE_DOXYGEN.m4 \ m4/AC_CXX_HAVE_SSTREAM.m4 \ m4/CREATE_GENERIC_CONFIG.m4 \ m4/AC_CXX_NAMESPACES.m4 \ m4/PETI_PEDANTIC_GCC.m4 \ m4/AC_FUNC_SNPRINTF.m4 \ m4/AC_C_INT64_T.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = log4tango.pc .PHONY: check rpm docs doc-dist distclean-local: $(RM) CONTENTS TAGS log4tango-config CONTENTS:: find $(top_srcdir) \( ! -type l -a -name '*.cpp' -o -name '*.hh' -o -name Makefile.am \) > $@ TAGS:: CONTENTS etags `cat $<` rpm: dist rpm -ta $(PACKAGE)-$(VERSION).tar.gz mv -f /usr/src/redhat/SRPMS/$(PACKAGE)-$(VERSION)-*.rpm $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-$(VERSION)-*.rpm $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-devel-$(VERSION)-*.rpm \ $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-doc-$(VERSION)-*.rpm \ $(top_srcdir) debian: chmod a+x $(top_srcdir)/debian/rules dpkg-buildpackage -rfakeroot -sa -us -uc -tc docs: $(MAKE) -C doc doc-dist: docs tar -zcf $(PACKAGE)-docs-$(VERSION).tar.gz -C $(top_srcdir)/doc/html --exclude CVS . tango-9.2.5a/lib/cpp/log4tango/Makefile.in0000644023471100065110000006304013034744764015240 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @DOC_TRUE@am__append_1 = doc @DOC_TRUE@am__append_2 = doc subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/log4tango.pc.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ THANKS ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = log4tango.pc CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = config src include tests $(am__append_1) ACLOCAL_AMFLAGS = -I m4 DIST_SUBDIRS = config src include tests $(am__append_2) EXTRA_DIST = log4tango.pc.in \ log4tango.m4 \ m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ m4/BB_ENABLE_DOXYGEN.m4 \ m4/AC_CXX_HAVE_SSTREAM.m4 \ m4/CREATE_GENERIC_CONFIG.m4 \ m4/AC_CXX_NAMESPACES.m4 \ m4/PETI_PEDANTIC_GCC.m4 \ m4/AC_FUNC_SNPRINTF.m4 \ m4/AC_C_INT64_T.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = log4tango.pc all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): log4tango.pc: $(top_builddir)/config.status $(srcdir)/log4tango.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-local distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pkgconfigDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ dist-zip distcheck distclean distclean-generic \ distclean-libtool distclean-local distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-pkgconfigDATA .PHONY: check rpm docs doc-dist distclean-local: $(RM) CONTENTS TAGS log4tango-config CONTENTS:: find $(top_srcdir) \( ! -type l -a -name '*.cpp' -o -name '*.hh' -o -name Makefile.am \) > $@ TAGS:: CONTENTS etags `cat $<` rpm: dist rpm -ta $(PACKAGE)-$(VERSION).tar.gz mv -f /usr/src/redhat/SRPMS/$(PACKAGE)-$(VERSION)-*.rpm $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-$(VERSION)-*.rpm $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-devel-$(VERSION)-*.rpm \ $(top_srcdir) mv -f /usr/src/redhat/RPMS/*/$(PACKAGE)-doc-$(VERSION)-*.rpm \ $(top_srcdir) debian: chmod a+x $(top_srcdir)/debian/rules dpkg-buildpackage -rfakeroot -sa -us -uc -tc docs: $(MAKE) -C doc doc-dist: docs tar -zcf $(PACKAGE)-docs-$(VERSION).tar.gz -C $(top_srcdir)/doc/html --exclude CVS . # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/log4tango.pc.in0000644023471100065110000000035513034744765016023 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: log4tango Description: Logging library for the tango constrol system Version: @VERSION@ Libs: -L${libdir} -llog4tango Cflags: -I${includedir}/tango tango-9.2.5a/lib/cpp/log4tango/configure0000644023471100065110000220551413034744764015105 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for log4tango 5.0.1. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: nicolas.leclercq@synchrotron-soleil.fr about your $0: system, including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='log4tango' PACKAGE_TARNAME='log4tango' PACKAGE_VERSION='5.0.1' PACKAGE_STRING='log4tango 5.0.1' PACKAGE_BUGREPORT='nicolas.leclercq@synchrotron-soleil.fr' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS GENERIC_CONFIG enable_latex_docs enable_html_docs enable_dot DOC_FALSE DOC_TRUE DOT DOXYGEN CXXCPP CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC LIBTOOL am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX host_os host_vendor host_cpu host build_os build_vendor build_cpu build LT_VERSION MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_dependency_tracking enable_static enable_shared with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_doxygen enable_dot enable_html_docs enable_latex_docs ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CPP CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures log4tango 5.0.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/log4tango] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of log4tango 5.0.1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-doxygen enable documentation generation with doxygen (auto) --enable-dot use 'dot' to generate graphs in doxygen (auto) --enable-html-docs enable HTML generation with doxygen (yes) --enable-latex-docs enable LaTeX documentation generation with doxygen (no) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF log4tango configure 5.0.1 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------------------------------- ## ## Report this to nicolas.leclercq@synchrotron-soleil.fr ## ## ----------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by log4tango $as_me 5.0.1, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in config "$srcdir"/config; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='log4tango' VERSION='5.0.1' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # autoconf 2.50 or higher to rebuild aclocal.m4, because the # AC_CREATE_PREFIX_CONFIG_H macro needs the AS_DIRNAME macro. # # +1 : ? : +1 == new interface that does not break old one # +1 : ? : 0 == new interface that breaks old one # ? : ? : 0 == no new interfaces, but breaks apps # ? :+1 : ? == just some internal changes, nothing breaks but might work # better # CURRENT : REVISION : AGE LT_VERSION=5:1:0 ac_config_headers="$ac_config_headers include/config.h" # Checks for programs # ---------------------------------------------------------------------------- # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether using Sun Worckshop C++ compiler" >&5 $as_echo_n "checking whether using Sun Worckshop C++ compiler... " >&6; } if ${rssh_cv_check_sunpro_cc+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __SUNPRO_CC # include "error: this is not Sun Workshop." #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : rssh_cv_check_sunpro_cc=yes else rssh_cv_check_sunpro_cc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rssh_cv_check_sunpro_cc" >&5 $as_echo "$rssh_cv_check_sunpro_cc" >&6; } if test ${rssh_cv_check_sunpro_cc} = yes then : else : fi if test "x$rssh_cv_check_sunpro_cc" = "xyes"; then AR="$CXX -xar" AR_FLAGS="-o" LD="$CXX -pta -G" # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=no fi fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC QCC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC QCC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "$GCC" = yes; then if test "$host" = x86-pc-nto-qnx; then CFLAGS="$CXXFLAGS -Wno-unused -O0" CXXFLAGS="$CXXFLAGS -Wno-unused -DLOG4TANGO_MISSING_INT64_OSTREAM_OP -O0" else case `$CXX --version` in *2.97*) CFLAGS="$CFLAGS -Wall -Wno-unused -pedantic -D_ISOC99_SOURCE" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused -pedantic -D_ISOC99_SOURCE" ;; *2.96*) CFLAGS="$CFLAGS -Wall -Wno-unused" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused" ;; *) CFLAGS="$CFLAGS -Wall -Wno-unused -pedantic" CXXFLAGS="$CXXFLAGS -Wall -Wno-unused -pedantic" ;; esac fi fi # Checks header files # ---------------------------------------------------------------------------- for ac_header in unistd.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTD_H 1 _ACEOF fi done for ac_header in io.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" if test "x$ac_cv_header_io_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IO_H 1 _ACEOF fi done # Check for pthreads # ---------------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_key_create" >&5 $as_echo_n "checking for library containing pthread_key_create... " >&6; } if ${ac_cv_search_pthread_key_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_key_create (); int main () { return pthread_key_create (); ; return 0; } _ACEOF for ac_lib in '' pthread; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_pthread_key_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_pthread_key_create+:} false; then : break fi done if ${ac_cv_search_pthread_key_create+:} false; then : else ac_cv_search_pthread_key_create=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_key_create" >&5 $as_echo "$ac_cv_search_pthread_key_create" >&6; } ac_res=$ac_cv_search_pthread_key_create if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_THREADING /**/" >>confdefs.h $as_echo "#define USE_PTHREADS /**/" >>confdefs.h case $host_os in linux*) CFLAGS="$CFLAGS -D_REENTRANT" CXXFLAGS="$CXXFLAGS -D_REENTRANT" ;; solaris*) if test x$GCC = x ; then CFLAGS="$CFLAGS -mt -D_POSIX_PTHREAD_SEMANTICS" CXXFLAGS="$CXXFLAGS -mt -D_POSIX_PTHREAD_SEMANTICS" else CFLAGS="$CFLAGS -D_REENTRANT" CXXFLAGS="$CXXFLAGS -D_REENTRANT" fi ;; hpux*) CFLAGS="$CFLAGS -AA -mt +inst_close" CXXFLAGS="$CXXFLAGS -AA -mt +inst_close" ;; esac else as_fn_error $? "pthreads not found" "$LINENO" 5 fi # Checks local idioms # ---------------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int64_t" >&5 $as_echo_n "checking for int64_t... " >&6; } if ${ac_cv_c_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int64_t i; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_int64_t=yes else ac_cv_c_int64_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_int64_t" >&5 $as_echo "$ac_cv_c_int64_t" >&6; } if test $ac_cv_c_int64_t = yes; then $as_echo "#define HAVE_INT64_T /**/" >>confdefs.h $as_echo "#define HAVE_STDINT_H /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler implements namespaces" >&5 $as_echo_n "checking whether the compiler implements namespaces... " >&6; } if ${ac_cv_cxx_namespaces+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace Outer { namespace Inner { int i = 0; }} int main () { using namespace Outer::Inner; return i; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxx_namespaces=yes else ac_cv_cxx_namespaces=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_namespaces" >&5 $as_echo "$ac_cv_cxx_namespaces" >&6; } if test "$ac_cv_cxx_namespaces" = yes; then $as_echo "#define HAVE_NAMESPACES /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler has stringstream" >&5 $as_echo_n "checking whether the compiler has stringstream... " >&6; } if ${ac_cv_cxx_have_sstream+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifdef HAVE_NAMESPACES using namespace std; #endif int main () { stringstream message; message << "Hello"; return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_cxx_have_sstream=yes else ac_cv_cxx_have_sstream=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_have_sstream" >&5 $as_echo "$ac_cv_cxx_have_sstream" >&6; } if test "$ac_cv_cxx_have_sstream" = yes; then $as_echo "#define HAVE_SSTREAM /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working snprintf" >&5 $as_echo_n "checking for working snprintf... " >&6; } if ${ac_cv_func_snprintf+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_snprintf=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int l = snprintf(NULL,0,"%d",100); exit (!((3 <= l) || (-1 == l))); } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_func_snprintf=yes else ac_cv_func_snprintf=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_snprintf" >&5 $as_echo "$ac_cv_func_snprintf" >&6; } if test $ac_cv_func_snprintf = yes; then $as_echo "#define HAVE_SNPRINTF /**/" >>confdefs.h fi # Misc. func tests # ---------------------------------------------------------------------------- for ac_func in gettimeofday do : ac_fn_cxx_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETTIMEOFDAY 1 _ACEOF fi done for ac_func in ftime do : ac_fn_cxx_check_func "$LINENO" "ftime" "ac_cv_func_ftime" if test "x$ac_cv_func_ftime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FTIME 1 _ACEOF fi done # Check for doxygen # ---------------------------------------------------------------------------- # Check whether --enable-doxygen was given. if test "${enable_doxygen+set}" = set; then : enableval=$enable_doxygen; fi # Check whether --enable-dot was given. if test "${enable_dot+set}" = set; then : enableval=$enable_dot; fi # Check whether --enable-html-docs was given. if test "${enable_html_docs+set}" = set; then : enableval=$enable_html_docs; else enable_html_docs=yes fi # Check whether --enable-latex-docs was given. if test "${enable_latex_docs+set}" = set; then : enableval=$enable_latex_docs; else enable_latex_docs=no fi if test "x$enable_doxygen" = xno; then enable_doc=no else # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 $as_echo "$DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$DOXYGEN = x; then if test "x$enable_doxygen" = xyes; then as_fn_error $? "could not find doxygen" "$LINENO" 5 fi enable_doc=no else enable_doc=yes # Extract the first word of "dot", so it can be a program name with args. set dummy dot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DOT="$DOT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DOT=$ac_cv_path_DOT if test -n "$DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 $as_echo "$DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test x$enable_doc = xyes; then DOC_TRUE= DOC_FALSE='#' else DOC_TRUE='#' DOC_FALSE= fi if test x$DOT = x; then if test "x$enable_dot" = xyes; then as_fn_error $? "could not find dot" "$LINENO" 5 fi enable_dot=no else enable_dot=yes fi # To build on MacOSX define __darwin__ # ---------------------------------------------------------------------------- case $build_os in darwin*) $as_echo "#define __darwin__ 1" >>confdefs.h CXXFLAGS="$CXXFLAGS -D__darwin__" ;; freebsd*) $as_echo "#define __freebsd__ 1" >>confdefs.h CXXFLAGS="$CXXFLAGS -D__freebsd__" ;; esac # Create files # ---------------------------------------------------------------------------- # create a generic PACKAGE-config file L=`echo $PACKAGE_TARNAME $LIBS` P=`echo $L | sed -e 's/ -.*//'` P=`echo $P` V=`echo $VERSION` F=`echo $P-config` { $as_echo "$as_me:${as_lineno-$LINENO}: result: creating $F - generic $V of $L" >&5 $as_echo "creating $F - generic $V of $L" >&6; } test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' echo '#! /bin/sh' >$F echo ' ' >>$F echo 'package="'$P'"' >>$F echo 'version="'$V'"' >>$F echo 'libs="'$L'"' >>$F echo ' ' >>$F # in the order of occurence a standard automake Makefile echo 'prefix="'$prefix'"' >>$F echo 'exec_prefix="'$exec_prefix'"' >>$F echo 'bindir="'$bindir'"' >>$F echo 'sbindir="'$sbindir'"' >>$F echo 'libexecdir="'$libexecdir'"' >>$F echo 'datadir="'$datadir'"' >>$F echo 'sysconfdir="'$sysconfdir'"' >>$F echo 'sharedstatedir="'$sharedstatedir'"' >>$F echo 'localstatedir="'$localstatedir'"' >>$F echo 'libdir="'$libdir'"' >>$F echo 'infodir="'$infodir'"' >>$F echo 'mandir="'$mandir'"' >>$F echo 'includedir="'$includedir'"' >>$F echo 'target="'$target'"' >>$F echo 'host="'$host'"' >>$F echo 'build="'$build'"' >>$F echo ' ' >>$F echo 'if test "'"\$""#"'" -eq 0; then' >>$F echo ' cat <>$F echo 'Usage: $package-config OPTIONS' >>$F echo 'Options:' >>$F echo ' --prefix=DIR) : \$prefix' >>$F echo ' --package) : \$package' >>$F echo ' --version) : \$version' >>$F echo ' --cflags) : -I\$includedir' >>$F echo ' --libs) : -L\$libdir -l\$package' >>$F echo ' --help) print all the options (not just these)' >>$F echo 'EOF' >>$F echo 'fi' >>$F echo ' ' >>$F echo 'o=""' >>$F echo 'h=""' >>$F echo 'for i in '"\$""*"' ; do' >>$F echo ' case $i in' >>$F echo ' --prefix=*) prefix=`echo $i | sed -e "s/--prefix=//"` ;;' >>$F echo ' --prefix) o="$o $prefix" ;;' >>$F echo ' --package) o="$o $package" ;;' >>$F echo ' --version) o="$o $version" ;;' >>$F echo ' --cflags) if test "_$includedir" != "_/usr/include"' >>$F echo ' then o="$o -I$includedir" ; fi' >>$F echo ' ;;' >>$F echo ' --libs) o="$o -L$libdir -l$libs" ;;' >>$F echo ' --exec_prefix|--eprefix) o="$o $exec_prefix" ;;' >>$F echo ' --bindir) o="$o $bindir" ;;' >>$F echo ' --sbindir) o="$o $sbindir" ;;' >>$F echo ' --libexecdir) o="$o $libexecdir" ;;' >>$F echo ' --datadir) o="$o $datadir" ;;' >>$F echo ' --datainc) o="$o -I$datadir" ;;' >>$F echo ' --datalib) o="$o -L$datadir" ;;' >>$F echo ' --sysconfdir) o="$o $sysconfdir" ;;' >>$F echo ' --sharedstatedir) o="$o $sharedstatedir" ;;' >>$F echo ' --localstatedir) o="$o $localstatedir" ;;' >>$F echo ' --libdir) o="$o $libdir" ;;' >>$F echo ' --libadd) o="$o -L$libdir" ;;' >>$F echo ' --infodir) o="$o $infodir" ;;' >>$F echo ' --mandir) o="$o $mandir" ;;' >>$F echo ' --target) o="$o $target" ;;' >>$F echo ' --host) o="$o $host" ;;' >>$F echo ' --build) o="$o $build" ;;' >>$F echo ' --data) o="$o -I$datadir/$package" ;;' >>$F echo ' --pkgdatadir) o="$o $datadir/$package" ;;' >>$F echo ' --pkgdatainc) o="$o -I$datadir/$package" ;;' >>$F echo ' --pkgdatalib) o="$o -L$datadir/$package" ;;' >>$F echo ' --pkglibdir) o="$o $libdir/$package" ;;' >>$F echo ' --pkglibinc) o="$o -I$libinc/$package" ;;' >>$F echo ' --pkglibadd) o="$o -L$libadd/$package" ;;' >>$F echo ' --pkgincludedir) o="$o $includedir/$package" ;;' >>$F echo ' --help) h="1" ;;' >>$F echo ' -?//*|-?/*//*|-?./*//*|//*|/*//*|./*//*) ' >>$F echo ' v=`echo $i | sed -e s://:\$:g`' >>$F echo ' v=`eval "echo $v"` ' >>$F echo ' o="$o $v" ;; ' >>$F echo ' esac' >>$F echo 'done' >>$F echo ' ' >>$F echo 'o=`eval "echo $o"`' >>$F echo 'o=`eval "echo $o"`' >>$F echo 'eval "echo $o"' >>$F echo ' ' >>$F echo 'if test ! -z "$h" ; then ' >>$F echo 'cat <>$F echo ' --prefix=xxx) (what is that for anyway?)' >>$F echo ' --prefix) \$prefix $prefix' >>$F echo ' --package) \$package $package' >>$F echo ' --version) \$version $version' >>$F echo ' --cflags) -I\$includedir unless it is /usr/include' >>$F echo ' --libs) -L\$libdir -l\$PACKAGE_TARNAME \$LIBS' >>$F echo ' --exec_prefix) or... ' >>$F echo ' --eprefix) \$exec_prefix $exec_prefix' >>$F echo ' --bindir) \$bindir $bindir' >>$F echo ' --sbindir) \$sbindir $sbindir' >>$F echo ' --libexecdir) \$libexecdir $libexecdir' >>$F echo ' --datadir) \$datadir $datadir' >>$F echo ' --sysconfdir) \$sysconfdir $sysconfdir' >>$F echo ' --sharedstatedir) \$sharedstatedir$sharedstatedir' >>$F echo ' --localstatedir) \$localstatedir $localstatedir' >>$F echo ' --libdir) \$libdir $libdir' >>$F echo ' --infodir) \$infodir $infodir' >>$F echo ' --mandir) \$mandir $mandir' >>$F echo ' --target) \$target $target' >>$F echo ' --host) \$host $host' >>$F echo ' --build) \$build $build' >>$F echo ' --data) -I\$datadir/\$package' >>$F echo ' --pkgdatadir) \$datadir/\$package' >>$F echo ' --pkglibdir) \$libdir/\$package' >>$F echo ' --pkgincludedir) \$includedir/\$package' >>$F echo ' --help) generated by ac_create_generic_config.m4' >>$F echo ' -I//varname and other inc-targets like --pkgdatainc supported' >>$F echo ' -L//varname and other lib-targets, e.g. --pkgdatalib or --libadd' >>$F echo 'EOF' >>$F echo 'fi' >>$F GENERIC_CONFIG="$F" ac_config_files="$ac_config_files Makefile log4tango.pc config/Makefile src/Makefile include/Makefile include/log4tango/Makefile include/log4tango/threading/Makefile tests/Makefile" if test "x$enable_doc" = xyes; then ac_config_files="$ac_config_files doc/Makefile doc/Doxyfile doc/html/Makefile" fi cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DOC_TRUE}" && test -z "${DOC_FALSE}"; then as_fn_error $? "conditional \"DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by log4tango $as_me 5.0.1, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ log4tango config.status 5.0.1 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "log4tango.pc") CONFIG_FILES="$CONFIG_FILES log4tango.pc" ;; "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "include/log4tango/Makefile") CONFIG_FILES="$CONFIG_FILES include/log4tango/Makefile" ;; "include/log4tango/threading/Makefile") CONFIG_FILES="$CONFIG_FILES include/log4tango/threading/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "doc/html/Makefile") CONFIG_FILES="$CONFIG_FILES doc/html/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Whether or not to build static libraries. build_old_libs=$enable_static # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi ac_prefix_conf_OUT=`echo include/log4tango/config.h` ac_prefix_conf_DEF=`echo _$ac_prefix_conf_OUT | sed -e 'y:abcdefghijklmnopqrstuvwxyz./,-:ABCDEFGHIJKLMNOPQRSTUVWXYZ____:'` ac_prefix_conf_PKG=`echo $PACKAGE_TARNAME` ac_prefix_conf_LOW=`echo _$ac_prefix_conf_PKG | sed -e 'y:ABCDEFGHIJKLMNOPQRSTUVWXYZ-:abcdefghijklmnopqrstuvwxyz_:'` ac_prefix_conf_UPP=`echo $ac_prefix_conf_PKG | sed -e 'y:abcdefghijklmnopqrstuvwxyz-:ABCDEFGHIJKLMNOPQRSTUVWXYZ_:' -e '/^[0-9]/s/^/_/'` ac_prefix_conf_INP=`echo include/config.h` if test "$ac_prefix_conf_INP" = "_"; then case $ac_prefix_conf_OUT in */*) ac_prefix_conf_INP=`basename $ac_prefix_conf_OUT` ;; *-*) ac_prefix_conf_INP=`echo $ac_prefix_conf_OUT | sed -e 's/[a-zA-Z0-9_]*-//'` ;; *) ac_prefix_conf_INP=config.h ;; esac fi if test -z "$ac_prefix_conf_PKG" ; then as_fn_error $? "no prefix for _PREFIX_PKG_CONFIG_H" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: creating $ac_prefix_conf_OUT - prefix $ac_prefix_conf_UPP for $ac_prefix_conf_INP defines" >&5 $as_echo "creating $ac_prefix_conf_OUT - prefix $ac_prefix_conf_UPP for $ac_prefix_conf_INP defines" >&6; } if test -f $ac_prefix_conf_INP ; then $as_dirname -- /* automatically generated */ || $as_expr X/* automatically generated */ : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X/* automatically generated */ : 'X\(//\)[^/]' \| \ X/* automatically generated */ : 'X\(//\)$' \| \ X/* automatically generated */ : 'X\(/\)' \| . 2>/dev/null || $as_echo X/* automatically generated */ | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' echo '#ifndef '$ac_prefix_conf_DEF >$ac_prefix_conf_OUT echo '#define '$ac_prefix_conf_DEF' 1' >>$ac_prefix_conf_OUT echo ' ' >>$ac_prefix_conf_OUT echo /'*' $ac_prefix_conf_OUT. Generated automatically at end of configure. '*'/ >>$ac_prefix_conf_OUT echo 's/#undef *\([A-Z_]\)/#undef '$ac_prefix_conf_UPP'_\1/' >conftest.sed echo 's/#undef *\([a-z]\)/#undef '$ac_prefix_conf_LOW'_\1/' >>conftest.sed echo 's/#define *\([A-Z_][A-Za-z0-9_]*\)\(.*\)/#ifndef '$ac_prefix_conf_UPP"_\\1 \\" >>conftest.sed echo '#define '$ac_prefix_conf_UPP"_\\1 \\2 \\" >>conftest.sed echo '#endif/' >>conftest.sed echo 's/#define *\([a-z][A-Za-z0-9_]*\)\(.*\)/#ifndef '$ac_prefix_conf_LOW"_\\1 \\" >>conftest.sed echo '#define '$ac_prefix_conf_LOW"_\\1 \\2 \\" >>conftest.sed echo '#endif/' >>conftest.sed sed -f conftest.sed $ac_prefix_conf_INP >>$ac_prefix_conf_OUT echo ' ' >>$ac_prefix_conf_OUT echo '/*' $ac_prefix_conf_DEF '*/' >>$ac_prefix_conf_OUT echo '#endif' >>$ac_prefix_conf_OUT else as_fn_error $? "input file $ac_prefix_conf_IN does not exist, skip generating $ac_prefix_conf_OUT" "$LINENO" 5 fi rm -f conftest.* fi tango-9.2.5a/lib/cpp/log4tango/AUTHORS0000644023471100065110000000005613034744764014241 00000000000000Bastiaan Bakker tango-9.2.5a/lib/cpp/log4tango/COPYING0000644023471100065110000001672713034744765014241 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. tango-9.2.5a/lib/cpp/log4tango/ChangeLog0000644023471100065110000012417413034744764014753 00000000000000This file describes the changes to the Log for C++ library. See the CVS repository for more detailed descriptions. 2002-10-29 Bastiaan Bakker * Release as 0.3.4b * include/log4cp/config-win32.h, src/PortabilityImpl.hh: added workarounds for abs() and strftime() and localtime() not being defined in std:: on MSVC6. See bug report #630334. 2002-10-28 Bastiaan Bakker * Release as 0.3.4. * tests/testPattern.cpp: added missing 'std::'. * src/StringUtil.hh, src/StringUtil.cpp: fixed signed-vs-unsigned comparison warning. Let both trim() implementations return unsigned int. 2002-10-27 Bastiaan Bakker * include/log4tango/OstringStream.hh, src/OstringStream.cpp: removed * src/StringUtil.hh, src/StringUtil.cpp: added vform() method. * PortabilityImpl.cpp: added. * include/log4tango/Appender.hh, include/log4tango/HierachyMaintainer.hh, include/log4tango/Log4cppCleanup.hh, src/Appender.cpp, src/HierrachyMaintainer.cpp, src/log4tangoCleanup.cpp: removed Log4cppCleanup, it was kinda broken anyway. * msvc6/log4tango/log4tango.dsp, msvc6/log4tangoDLL/log4tangoDLL.dsp, bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak: added BasicConfigurator. * src/PatternLayout.cpp: define static constant strings in TimeStampComponent outside class declaration. 2002-10-26 Bastiaan Bakker * Release as 0.3.3. * include/log4tango/config-win32.h, src/PortabilityImpl.hh, src/Makefile.am: worked around header definition bug in MSVC by aliasing cstdlib/cstring functions in 'std::'. See #628211. * src/NDC.cpp: added parentheses to return statement in _get() as suggested by Derrick Hastings to fix #415160. * include/log4tango/PattenLayout.hh, src/PatternLayout.cpp: added default conversion patterns. * msvc6/log4tangoDLL/Makefile.in: removed. 2002-10-19 Bastiaan Bakker * include/log4tango/PatternLayout.hh, src/PatternLayout.cpp: replaced PatternLayout implementation: it now preparses the message format for quicker layouting and implements format specifiers, e.g. '%-5p'. * tests/testPattern.cpp: added tests for format specifiers and more. 2002-10-10 Bastiaan Bakker * include/log4tango/threading/MSThreads.hh: added #include 2002-10-05 Bastiaan Bakker * log4tango.spec.in: don't require log4tango for log4tango-doc. * doc/Makefile.am: fix install location. * Makefile.am: use 'rpmbuild' instead of 'rpm'. 2002-10-05 Bastiaan Bakker * release as 0.3.2 * doc/html/index.html: added notes for 0.3.2 and 0.3.2rc5 * configure.in, msvc6/Makefile.am, msvc6/testDLL/Makefile.am, msvc6/testMain/Makefile.am, msvc6/testNTEventLog/Makefile.am, msvc6/testPattern/Makefile.am: added missing makefiles. 2002-09-26 Bastiaan Bakker * src/StringUtil.hh: fix compilation problem on Sun CC 5.3 (bug #614903). 2002-09-18 Bastiaan Bakker * src/RemoteSyslogAppender.cpp: fixed log facility in _append(), as reported by Derek Atkins. * src/PropertyConfiguratorImpl.cpp, src/SimpleConfigurator.cpp: multiply syslog facility value by 8. 2002-09-17 Bastiaan Bakker * log4tango.spec.in: fix relocatability of log4tango-devel by patching lib/liblog4tango.la and bin/log4tango-config in %post. Unfortunately this results in 'rpm --verify' reporting these files as modified. 2002-09-15 Bastiaan Bakker * release as 0.3.25rc5 * include/threading/DummyThreads.hh, include/threading/MSThreads.hh, include/threading/OmniThreads.hh, include/threading/Pthreads.hh, src/DummyThreads.cpp, src/MSThreads.cpp, src/OmniThreads.cpp, src/Pthreads.cpp: moved bodies of getThreadId() to .cpp files. * src/Makefile.am, msvc6/log4tango/log4tango.dsp, msvc6/log4tangoDLL/log4tangoDLL.dsp, bcb5/log4tango/log4tango.mak, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.bpf: added *Threads.cpp files * configure.in, include/log4tango/Appender.hh, include/log4tango/AppenderSkeleton.hh, m4/BB_CHECK_PTHREADS.m4, m4/PETI_PEDANTIC_GCC.m4, src/FileAppender.cpp, src/Level.cpp, src/Properties.cpp, src/PropertyConfiguratorImpl.hh, src/RemoteSyslogAppender.cpp,src/StringUtil.hh, tests/Clock.cpp, tests/Clock.hh, tests/testConfig.cpp, tests/testPropertyConfig.cpp, tests/testbench.cpp: Merged patch #605143, contributed by Harald Wellman: support for compilation in QNX Neutrino. 2002-09-05 Bastiaan Bakker * src/PropertyConfiguratorImpl.cpp, tests/testConfig.log4tango.properties: Merged patch #604991, contributed by Richard Brodie: support for setting additivity via properties file using 'log4j.addivity.=[true|false]'. 2002-08-16 Bastiaan Bakker * include/log4tango/threading/Makefile.am: added MSThreads.hh 2002-08-16 Bastiaan Bakker * Release as 0.3.2rc3 * src/SimpleConfigurator.cpp, src/PropertyConfiguratorImpl.cpp: put #ifdef WIN32 around #include of NTEventLogAppender and Win32DebugAppender. * include/log4tango/threading/PThreads.hh: use reinterpret_cast<>. * tests/testProperties.cpp: add std::. 2002-08-14 Bastiaan Bakker * Release as 0.3.2rc2 * Makefile.am, include/log4tango/Makefile.am, tests/Makefile.am: added distclean-local targets. * doc/Doxyfile.in: predefine 'WIN32' as suggested by David Resnick. * include/log4tango/NTEventLogAppender.hh, include/log4tango/Win32DebugAppender.hh: added warnings about platform dependency. 2002-08-13 David Resnick * include/log4tango/PatternLayout.hh: documentation fixes. 2002-08-09 Bastiaan Bakker * msvc6/log4tangoDLL/log4tangoDLL.rc: update version and product info. * include/log4tango/Portability.hh: added comments. * src/Category.cpp: added lock to getAllAppenders(). * doc/html/index.html: more documentation updates. * tests/testCategory.cpp, tests/testConfig.cpp, tests/testDLL.cpp, tests/testFilter.cpp, tests/testPropConfig.cpp, tests/testbench.cpp: Replaced #include "log4tango/X" with #include * tests/testProperties.cpp, tests/testPropertyConfig.cpp: added. * configure.in, doc/Makefile.am, doc/html/Makefile.am: added doc/html to automake. 2002-08-09 Bastiaan Bakker * include/log4tango/RollingFileAppender.hh: correct constness of constructor parameters, as pointed out by James Emery. 2002-08-06 Bastiaan Bakker * configure.ac, configure.in: renamed configure.ac back to configure.in due to bug in libtoolize 1.4.2 * NEWS, README, INSTALL, doc/html/index.html: converted most documentation to HTML. * m4/CREATE_GENERIC_CONFIG.m4: fix log4tango-config creation (use PACKAGE_TARNAME instead of PACKAGE). 2002-08-06 David Resnick * msvc6/log4tangoDLL/log4tangoDLL.rc: Cleanup. * msvc6/log4tangoDLL/resource.h deleted: Unnecessary. 2002-08-05 David Resnick * msvc6/log4tangoDLL/log4tangoDLL.rc, msvc6/log4tangoDLL/resource.h: Version property sheet added to DLL. 2002-08-04 David Resnick * src/PropertyConfiguratorImpl.cpp: added RollingFileAppender, NTEventLogAppender. Threshold attrib added for appenders. Invalid level in configureCategory prints message of invalid_argument exception. * src/Level.cpp: surrounding quotes added around invalid level in thrown invalid_argument exception. * tests/testPropConfig.cpp, tests/log4tango.property, msvc6\testPropConfig\testPropConfig.dsp: test for PropertyConfigurator added. 2002-08-02 Bastiaan Bakker * doc/Makefile.am, doc/Doxyfile.in, doc/html/index.html, doc/html/default.css: added new index page and move Doxygen generated docs to api subdirectory. 2002-08-01 Bastiaan Bakker * include/log4tango/threading/PThreads.hh: added POSIX threads support file contributed by Emiliano Martin. * include/log4tango/threading/Makefile.am, include/log4tango/threading/Threading.hh: add PThreads.hh * configure.ac: added test for POSIX threads * m4/BB_CHECK_PTHREADS.m4: added. Crude initial pthreads check. Need to nick a good macro somewhere else :-) * m4/BB_CHECK_OMNITHREADS.m4: added 'thread safity' defines, needed at least for STL. * THANKS: added Emiliano. 2002-07-30 Bastiaan Bakker * include/log4tango/TimeStatemp.hh: added some doxygen comments * m4/AC_CREATE_PREFIX_CONFIG_H.m4: removed a debug print statement. * src/PropertyConfgiruratorImpl.cpp: added 'append' property for FileAppender. * src/LoggingEvent.cpp: fill in the thread Id. 2002-07-22 Bastiaan Bakker * configure.in, configure.ac: renamed configure.in to configure.ac. * configure.ac, log4tango.spec.in, doc/Doxyfile.in, doc/Makefile.am, m4/AC_CREATE_PREFIX_CONFIG_H.m4, m4/AC_CXX_HAVE_SSTREAM.m4, m4/AC_CXX_NAMESPACES.m4, m4/BB_CHECK_OMNITHREADS.m4: updated AC macros and variables to autoconf 2.50. * src/Level.cpp: put names[] in anonymous namespace instead of declaring it static. This should solve Solaris 8 dynamic library problem (see patch #583905). 2002-07-11 Bastiaan Bakker * src/PatternLayout.cpp: use std::string::size_type instead of int. * src/PropertyConfiguratorImpl.cpp: use map.lower_bound() to determine begin and end for appender and logger properties. 2002-07-10 David Resnick * src/PatternLayout.cpp, include/log4tango/PatternLayout.hh, tests/testPattern.cpp, msvc6/testPattern/testPattern.dsp: added support for formatting date and testing that new support. * tests/testDLL.cpp, msvc6/testDLL/testDLL.dsp: added project that tests log4tango DLL (on win32 platform), including export of container object. * msvc6/log4tango/log4tango.dsp, msvc6/log4tangoDLL/log4tangoDLL.dsp: fixed so that PropertyConfigurator and attendant files are compiled in MSVC6. 2002-07-09 Bastiaan Bakker * src/StringUtil.hh, src/StringUtil.cpp: added a more generic split() method taking an output_iterator instead of a vector to store the result. * src/PropertyConfiguratorImpl.hh, src/PropertyConfiguratorImpl.cpp: renamed addAppenders() to configureCategory(). fixed configureCategory(): had a nested loop for priorities and appenders. replaced find(property, '.') with StringUtil::split() in several places. * src/PropertyConfiguratorImpl.cpp: fixed configureCategory() fix. 2002-07-05 Bastiaan Bakker * src/StringUtil.hh, src/StringUtil.cpp: added split() method. * src/PropertyConfiguratorImpl.hh, src/PropertyConfiguratorImpl.hh: changed the way configuration is done: first instantatiate all Appenders defined in the config, then add them to Categories where necessary. Multiple Appenders per Category are now supported. Currently doConfigure() leaks all Appenders, as they will be not be owned by any Categories. This will be fixed in the future by having the LoggerRepository maintain ownership of all Categories, Appenders, etc. 2002-07-04 Bastiaan Bakker * include/log4tango/BasicConfigurator.hh, src/BasicConfigurator.cpp: added. * src/Properties.hh, src/Properties.cpp: added Log4j style variable substitution: ${NAME} will be substituted with environment variable NAME or if not found with property NAME. '${${}' denotes a literal '${' sequence. 2002-07-03 Bastiaan Bakker * src/SyslogAppender.cpp (SysLogAppender()): accept '-1' for facility and portNumber, implying the 'default value'. * src/ConfiguratorSkeleton.cpp: changed property names to JavaBeans/log4j style. Use the appender name as name (duh) instead of the 'name' property. Don't set a layout if none have been specified. Use std::string::size_type where applicable. Made some exception messages clearer. Compacted the code a bit. * src/Properties.hh, src/Properties.cpp: added, moved PropertyConfigurator::parseConfig() to load(). * src/PropertyConfiguratorImpl.hh, src/PropertyConfiguratorImpl.cpp: added. This class is a merge of PropertyConfigurator and ConfiguratorSkeleton. ConfiguratorSkeleton is not generic enough to be exposed in the API. * include/log4tango/PropertyConfigurator.hh, src/PropertyConfigurator.cpp: leave only 2 static configure() methods, like SimpleConfigurator. The actual implementation is now in PropertyConfiguratorImpl. * include/log4tango/ConfiguratorSkeleton.hh, src/ConfiguratorSkeleton.cpp: removed. * src/StringUtil.hh, src/StringUtil.cpp: added, contains ConfiguratorSkeleton::trim(). * src/RollingFileAppender.cpp: fix signed/unsigned comparison warning. * m4/PETI_PEDANTIC_GCC.m4: remove -pedantic flag for g++ 2.96 to get rid of those iritating warnings about std IOstreams code. * src/TimeStamp.cpp: replaced #include with . * src/PropertyConfiguratorImpl.cpp: use getString(), etc. to get properties. * include/log4tango/Category.hh, include/log4tango/FixedContextCategory.hh, include/log4tango/CategoryStream.hh: fixed documentation buglets. 2002-07-02 Bastiaan Bakker * include/log4tango/HierarchyMaintainer.hh, include/log4tango/Category.hh, src/HierarchyMaintainer.cpp, src/Category.cpp: Changed return type of getCurrentCategories() to std:vector. vector<> is more efficient than set<> and works around MSVC++ DLL export brain damage, see Microsoft Q168958. * include/log4tango/Configurator.hh, include/log4tango/ConfiguratorSkeleton.hh, include/log4tango/SimpleConfigurator.hh, include/log4tango/PropertyConfigurator.hh, src/Configurator.cpp, src/ConfiguratorSkeleton.cpp, src/SimpleConfigurator.cpp, src/PropertyConfigurator.cpp: integrated PropertyConfigurator contributed by Alan Anderson . * msvc6/log4tango/log4tango.dsp, bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak: added PropertyConfigurator files. 2002-06-19 Bastiaan Bakker * src/Makefile.am: added NTEventlog.cpp and DllMain.cpp to sources. * src/DllMan.cpp: enclosed in #ifdef LOG4TANGO_SUPPLY_DLLMAIN * include/log4tango/config-win32.h: #define LOG4TANGO_SUPPLY_DLLMAIN * include/log4tango/Makefile.am: added NTEventLog.hh * msvc6/Makefile.am: added NTEventLogCategories. 2002-06-18 Bastiaan Bakker * src/NDC.cpp: fix top level context falling off, if depth > 2. (reported by Hong Yang ) * tests/testNDC.cpp: push 3 contexts to test for bug above. 2002-06-17 Aaron Ingram * Fixed default port for syslog in SimpleConfigurator.cpp * Added a sample configuration file: log4tango.cfg 2002-06-17 David Resnick * Merge of MS Threads & DLL Build support patch by Aaron Ingram with these changes: * src/main.cpp renamed to src/DllMain.cpp * Run-time library used for log4tangoDLL changed to Multithreaded DLL (fixed need for #pragma warning(disable:4275)) * pragma directives moved from various headers to include/log4tango/Portability.hh. * include/log4tango/threading/MSThreads.hh: reset(): TlsSetValue uses parameter value instead of deleted one. * include/log4tango/NTEventLogAppender.hh, src/NTEventLogAppender.cpp, msvc/NTEventLogAppender.mc, tests/testNTEventLog.cpp: added NTEventLogAppender. * msvc/testMain/testMain.dsp, msvc/testNTEventLog/testNTEventLog.dsp added. 2002-06-03 Cedric Le Goater * Makefile.am: added log4tango.m4 installation * log4tango.m4: added aclocal support * tests/Clock.cpp: fixed rdtscl() support on linux 2002-05-22 Bastiaan Bakker * include/log4tango/config-win32.h: fix compilation in Visual .NET. 2002-05-12 Bastiaan Bakker * src/RollingFileAppender.cpp: explicitly remove oldest file in rollOver() because win98 cannot rename() to existing files. (Paulo Pizarro) * Makefile.am: convert *.bpg files to CRLF in dist.(Paulo Pizarro) * bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak, include/log4tango/Makefile.am, msvc6/log4tango/log4tango.dsp, src/Makefile.am, include/log4tango/Win32DebugAppender.hh, src/Win32DebugAppender.cpp: added Win32DebugAppender contributed by Alan Anderson. 2002-04-21 Bastiaan Bakker * include/log4tango/config-win32.h: added mode_t typedef. * m4/AC_C_INT64_T.m4: added #define of HAVE_STDINT_H. * src/PatternLaout.cpp: #include only if available. 2002-04-09 Bastiaan Bakker * tests/Clock.cpp: test for i386 architecture on linux (patch #541608) 2002-04-04 Bastiaan Bakker * Release as 0.3.1 * src/Category.cpp: fix previous fix for bug #527467. * m4/PETI_PEDANTIC_GCC.m4: add -Wno-unused to g++ options. * configure.in: increment version to 0.3.1. * msvc6/log4tango/log4tango.dsp: Added RollingFileAppender and threading files. * bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak: Added RollingFileAppender 2002-03-31 Bastiaan Bakker * include/log4tango/Portability.hh: Disable exception specifier warnings (issue #536668) 2002-03-27 Bastiaan Bakker * m4/AC_C_INT64_T.m4: #include and remove $GCC check. * src/PatternLayout.cpp: #include * configure.in, include/log4tango/Portability.hh: back out strcasecmp() stuff. 2002-03-22 Bastiaan Bakker * include/log4tango/FileAppender.hh, src/FileAppender.cpp: added 'append' and 'mode' options. * include/log4tango/RollingFileAppender.hh, include/log4tango/Makefile.am, src/RollingFileAppender.cpp, src/SimpleConfigurator.cpp, src/Makefile.am: added RollingFileAppender contributed by Paulo Pizarro 2002-03-20 Bastiaan Bakker * include/log4tango/SimpleConfigurator.hh, src/SimpleConfigurator.cpp: added configure(std::istream&) method. (feature request #527760) * src/Log4cppCleanup.cpp: set variable to NULL after delete. (feature request #527393) * include/log4cp/Category.hh, include/log4tango/FixedContextCategory.hh, src/Category.hh, src/Category.cpp: added getAllAppenders() method. (feature request #527381) * src/Category.cpp: removeAllAppenders(): fix invalidated iterator usage. (bug #527467) 2002-03-17 Bastiaan Bakker * tests/testbench.cpp: added missing 'std::' specifiers. (bug #530332) * src/SyslogAppender.cpp: fix format string bug. (bug #527475) 2002-02-18 Bastiaan Bakker * Release as 0.3.0 * INSTALL: added some platform specific build instructions. * tests/Clock.hh: replaced "long long" with int64_t. * src/OstringStream.cpp: fix typo. * src/Appender.cpp: added missing Mutex. * include/log4tango/threading/OmniThreads.hh: added Doxygen comments. * NEWS: release 0.3.0. * configure.in: upped release to 0.3.0 and LT version to 4.0.0 2002-02-11 Bastiaan Bakker * configure.in: integrated check of omnithreads. * m4/BB_CHECK_OMNITHREADS.m4: added * include/log4tango/threading/DummyThreads.hh: scoped lock is now an integer. * include/log4tango/Category.hh, include/log4tango/FixedContextCategory.hh, include/log4tango/HierarchyMaintainer.hh, include/log4tango/NDC.hh, src/Category.cpp, src/FixedContextCategory.cpp, src/HierarchyMaintainer.cpp, src/NDC.cpp: added threadsafety provisions. * include/log4tango/*.hh: replaced #include"" with #include<> * src/*.cpp: replaced #include"" with #include<> * include/log4tango/Appender.hh, src/Appender.cpp: added Mutex for _allAppender map. 2002-02-08 Bastiaan Bakker * include/log4tango/threading/Threading.hh, include/log4tango/threading/OmniThreads.hh, include/log4tango/threading/DummyThreads.hh, include/log4tango/threading/BoostThreads.hh, include/log4tango/threading/Makefile.am: added 2002-02-05 Bastiaan Bakker * src/AppenderSkeleton.cpp: doAppend(): correct comparison of _threshold against event level (bug #513481). * tests/Clock.cpp: add missing 'std::'. 2002-01-27 Bastiaan Bakker * Release as 0.2.7 * configure.in: upped version to 0.2.7. * testbench.cpp: added more measurements, using crude cut&paste of code. * NEWS: set release date for 0.2.7, added bug #506907 fixed. * bcb5/testPattern/Makefile.am: set EXTRA_DIST. 2002-01-25 Bastiaan Bakker * configure.in: added bcb5/testConfig/Makefile to AC_OUTPUT * include/log4tango/FixedContextCategory.hh: removed superfluous class qualification for ownsAppender(). 2002-01-25 Uwe Jäger * src/SimpleConfigurator.cpp: Replaced STDOUT_FILENO and STDERR_FILENO with fileno(stdout) and fileno(stderr) which seems to be more portable. * tests/testConfig.cpp: Replace ?-:-operator with if/else because of compiler problems; retabbed file. * bcb5/Makefile.am, bcb5/bcb5.bpg, bcb5/bcb5.mak: Added testConfig * bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak: Added new files. * bcb5/testConfig/Makefile.am, bcb5/testConfig/testConfig.bpf, bcb5/testConfig/testConfig.bpr, bcb5/testConfig/testConfig.mak: Added testConfig. * bcb5/testCategory/testCategory.bpr, bcb5/testFixedContextCategory/testFixedContextCategory.bpr, bcb5/testNDC/testNDC.bpr, bcb5/testPattern/testPattern.bpr bcb5/testPattern/testPattern.mak, bcb5/testmain/testmain.bpr: Adjusted makefiles/project files for BCB. 2002-01-23 Bastiaan Bakker * src/SimpleConfigurator.cpp: try to fix bug #506907 (MSVC++ compile failure) with ::dup(fileno(stdout)) * configure.in: upped version to 0.2.7rc2 2002-01-21 Bastiaan Bakker * src/Category.cpp: fix ownsAppender() methods. * tests/testCategory.cpp: rename appender 'default' to 'default2'. * configure.in: upped version to 0.2.7rc1 and LT_VERSION to 3:1:2 * src/SimpleConfigurator.cpp, tests/testFixedContextCategory.cpp, tests/testPattern.cpp, tests/testbench.cpp, tests/testmain.cpp: replaced setAppender() with addAppender(). * include/log4tango/Category.hh: update doxygen comments. * include/log4tango/FixedContextCategory.hh, src/FixedContextCategory.cpp: sync methods for multiple Appender support. * NEWS: added summary for 0.2.7 release 2002-01-20 Bastiaan Bakker * include/log4tango/Category.hh, src/Category.cpp, tests/testCategory.cpp: merged in support for multiple Appenders, contributed by Brendan B. Boerner. * THANKS: Added Brendan. 2002-01-17 Bastiaan Bakker * include/log4tango/HierarchyMaintainer.hh, src/HierarchyMaintainer.cpp: added getExistingInstance(std::string). * include/log4tango/Category.hh, src/Category.cpp: added exists(std::string). * include/log4tango/RollingFileAppender.hh, include/log4tango/Makefile.am, src/RollingFileAppender.cpp, src/MakeFile.am: removed RollingFileAppender, to be replaced with DailyRollingFileAppender. 2002-01-16 Bastiaan Bakker * include/log4tango/Category.hh, src/Category.cpp: fix bug #504314: added missing log methods for level 'fatal'. * src/SimpleConfigurator.cpp: added 'stdout' and 'stderr' appenders. 2002-01-10 Bastiaan Bakker * configure.in: added check for strcasecmp() and stricmp(). * include/log4tango/config-win32.h: have stricmp() but not strcasecmp(). * include/log4tango/Portability.hh: use stricmp() if strcasecmp() is not available. * include/log4tango/RemoteSyslogAppender.hh: added SyslogFacility type. 2002-01-09 Bastiaan Bakker * src/SimpleConfigurator.cpp: skip all whitespace before PatternLayout pattern, not just one. * include/log4tango/RollingFileAppender.cpp, include/log4tango/Makefile.am, src/RollingFileAppender.cpp, src/MakeFile.am: added RollingFileAppender contributed by Alex Tapaccos. 2002-01-08 Bastiaan Bakker * src/SimpleConfigurator.cpp: skip space before PatternLayout pattern (Bug #500766). * src/SimpleConfigurator.cpp: fix screwy fix for Bug #500766, now using Alex' method. (Obsoletes Patch #500832). 2002-01-04 Bastiaan Bakker * include/log4tango/config-openvms.h: #include for int64_t. * src/PatternLayout.cpp(doFormat): removed superfluous return statement. * include/log4tango/config-win32.h: fix int64_t for Borland compiler. * include/log4tango/SyslogAppender.hh, include/log4tango/RemoteSyslogAppender.hh, src/SyslogAppender.cpp, src/RemoteSyslogAppender.cpp: inherit from LayoutApppender instead of AppenderSkeleton (Bug #499524). 2002-01-03 Bastiaan Bakker * include/log4tango/Filter.hh: decide() is NOT abstract. * tests/testFilter.cpp: added * tests/Makefile.am: added testFilter.cpp to tests. 2001-12-21 Bastiaan Bakker * Release as 0.2.6b * configure.in: upped release to 0.2.6b * src/Level.cpp: getLevelValue(): fix bug in numerical input handling. * tests/Makefile.am: added very simple test for Level. * tests/testLevel.cpp: added. 2001-12-13 Bastiaan Bakker * src/OstringStream.cpp: use portable_vsnprintf(), not portable_snprintf(). 2001-12-11 Bastiaan Bakker * Release as 0.2.6 * TODO: Mark PatternLayout and SimpleConfigurator as done. * NEWS: release 0.2.6 * Makefile.am: exclude CVS subdir from doc-dist tar ball. * include/log4tango/config-win32.h: #define int64_t as __int64, #define LOG4TANGO_MISSING_INT64_OSTREAM_OP * src/PatternLatout.cpp: workaround missing << operator for int64_t on MSVC. * src/TimeStamp.cpp: fix ref typo for timeb struct. * include/log4tango/config-win32.h: #define LOG4TANGO_USE_CLEANUP. 2001-11-30 Bastiaan Bakker * tests/testbench.cpp: use TimeStamp instead of ::time() * include/log4tango/Makefile.am: added config-openvms.h to headers. * include/log4tango/Appender.hh, include/log4tango/HierarchyMaintainer.hh, include/log4tango/Log4cpCleanup.hh, src/Appender.cpp, src/HierarchyMaintainer.cpp, src/Log4cppCleanup.cpp: conditionally use Log4cppCleanup, depending on #define LOG4TANGO_USE_CLEANUP. The new default is NOT to use it, because it causes segfaults on some platforms (e.g. Solaris). 2001-11-29 Bastiaan Bakker * include/log4tango/Portability.hh: use config-openvms.h based on __OPENVMS__ flag. * src/snprintf.c: replaced static_cast with C-style cast: this file should remain C only. * configure.in, Makefile.am: added openvms subdirectory. * openvms/Makefile.am: added empty Makefile template. * THANKS: added Tony Cheung. * src/Makefile.am: added snprintf.c to noinst_HEADERS. * include/log4tango/TimeStamp.hh: moved class description to the correct location. 2001-11-28 Bastiaan Bakker * src/snprintf.c: added portable snprintf 2.2 from http://www.ijs.si/software/snprintf/ * src/OstringStream.cpp: replace alternative snprintf with one in snprintf.c. * src/snprintf.c: add static cast from void* to const char*. * include/log4tango/config-openvms.h: added. 2001-11-26 Bastiaan Bakker * include/log4tango/TimeStamp.hh, include/log4tango/Makefile.am, src/TimeStamp.cpp, src/Makefile.am: added micro second precise time stamp. * configure.in: added test for 'ftime()' function. * include/log4tango/LoggingEvent.hh, include/log4tango/PatternLayout.hh, src/LoggingEvent.cpp, src/BasicLayout.cpp, src/PatternLayout.cpp: Use new TimeStamp class. * tests/testPattern.cpp: included '%r' in test pattern. * src/SimpleConfigurator.cpp: added support for RemoteSyslogAppender. * bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.bpf: Added TimeStamp class. * msvc6/log4tango/log4tango.dsp: Added TimeStamp, PatternLayout and SimpleConfigurator classes. * include/log4tango/RemoteSyslogAppender.hh: replaced #defines with enum. * include/log4tango/config-win32.h: sync with #defines in include/log4tango/config.h. * tests/Makefile.am: made log4tango.init check_DATA. * tests/testConfig.cpp: read $srcdir for location of log4tango.init in order to fix distcheck target. 2001-11-23 Bastiaan Bakker * tests/testConfig.cpp, tests/log4tango.init: added test for SimpleConfigurator. * include/log4tango/Makefile.am, src/Makefile.am, tests/Makefile.am: integrated SimpleConfigurator in autoconf. * src/SimpleConfigurator.cpp: added support for comments in config file (starting with a '#'). added support for SyslogAppender. use Level::getLevelValue() to convert priorities. 2001-11-09 Bastiaan Bakker * m4/CREATE_GENERIC_CONFIG.m4: escape $* * tests/testFixedContextCategory.cpp: Use contructor for FixedContextCategory instead of assignment. 2001-11-05 Bastiaan Bakker * m4/CREATE_GENERIC_CONFIG.m4: fix /bin/sh incompatibility on Solaris. * include/log4tango/Category.hh: Added private copy constructor and assignment operator (pointed out by Shane Baker). 2001-11-01 Bastiaan Bakker * src/Category.cpp: in setAppender(Appender*) allow NULL Appender. * include/log4tango/Category.hh: in setAppender(Appender*) document allowing NULL Appender parameter. 2001-10-24 Bastiaan Bakker * configure.in: Added bcb5/testPattern/Makefile to AC_OUTPUT. * include/log4tango/Level.hh, src/Level.cpp: Added getLevelValue() method. * src/PatternLatout.cpp: Added support for sstream predating c++ stream libraries. 2001-10-05 Uwe Jäger * bcb5/Makefile.am, bcb5/bcb5.bpg, bcb5/bcb5.mak: Added testPattern. * bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.mak: Added PatternLayout and SimpleConfigurator. * bcb5/testPattern/testPattern.bpf, bcb5/testPattern/testPattern.bpr, bcb5/testPattern/testPattern.mak: Added project file and makefile for pattern test. * include/log4tango/config-win32.h: Added support for PatternLayout. * include/log4tango/SimpleConfigurator.hh, src/SimpleConfigurator.cpp: Make it compile with Borland C++. * src/PatternLayout.cpp, src/RemoteSyslogAppender.cpp, tests/testPattern.cpp: Port to Borland C++. 2001-10-04 Bastiaan Bakker * src/SimpleConfigurator.cpp, include/log4tango/SimpleConfigurator.hh: Added simple configurator class contributed by Glenn Scott. Not usable yet. * src/Level.cpp: fix conversion from LevelLevel to LevelName. * include/log4tango/Makefile.am, src/Makefile.am, tests/Makefile.am: Added PatternLayout files * configure.in, Makefile.am, m4/C_C_INT64_T: Added check for int64_t. * configure.in: Added check for gettimeofday. * src/PatternLayout.cpp: use LOG4TANGO_HAVE_TIMEOFDAY and LOG4TANGO_HAVE_INT64_T * include/log4tango/LoggingEvent.hh: made strings real member variables. 2001-09-18 Bastiaan Bakker * include/log4tango/PatternLayout.hh, src/PatternLayout.cpp, tests/testPattern.cpp: Added PatternLayout contributed by Glenn Scott. Is not in autoconf setup yet. 2001-09-17 Bastiaan Bakker * configure.in: Added checks for -lsocket and -lnsl * m4/AC_FUNC_SNPRINTF.m4: Relax snprintf() check: full C99 compliancy is not needed. * include/log4tango/Level.hh: Fix workaround for #define DEBUG * config/Makefile.am: Added newline to keep broken tar utilities happy * include/log4tango/FixedContextCategory.hh: Added default value for context parameter in constructor. * include/log4tango/LayoutAppender.hh: Made BasicLayout the DefaultLayoutType * configure.in: Set requirement for Autoconf 2.50 Bumped version to 0.2.6 Incremented LT_VERSION to 2:0:1 * Makefile.am: Fix EXTRA_DIST m4 inclusion. * bcb5/log4tango/log4tango.bpf, bcb5/log4tango/log4tango.bpr, bcb5/log4tango/log4tango.mak: Added RemoteSyslogAppender. 2001-08-23 Bastiaan Bakker * include/log4tango/Level.hh: Added workaround for #define DEBUG in EDK.h on Win32. 2001-07-17 Walter Stroebel * include/log4tango/RemoteSyslogAppender.hh, src/RemoteSyslogAppender: Added. 2001-07-16 Uwe Jäger * bcb5/log4tango.bpf, bcb5/log4tango.bpr: Adjusted project files to compile CategoryStream.cpp. * bcb5/bcb5.mak, bcb5/log4tango/log4tango.mak, bcb5/log4tango/testCategory/testCategory.mak, bcb5/log4tango/testFixedContextCategory/testFixedContextCategory.mak, bcb5/log4tango/testmain/testmain.mak, bcb5/log4tango/testNDC/testNDC.mak: Added makefiles for Borland make to build without IDE. 2001-06-17 Bastiaan Bakker * include/log4tango/Category.hh, include/log4tango/CategoryStream.hh, include/log4tango/Makefile.am, src/Category.cpp, src/CategoryStream.cpp, src/Makefile.am: Put CategoryStream class into its own files. 2001-06-11 Bastiaan Bakker * m4/AC_CREATE_PREFIX_CONFIG_H.m4: fix to overwrite include/log4tango/config.h instead of append to it. * include/log4tango/Makefile.am: remove config.h from dist. 2001-06-11 Bastiaan Bakker * Release as 0.2.5 * NEWS: inclusion of Borland C++ Builder support. * Makefile.am: only include *.m4 files in m4/ in dist. * Makefile.am: fix typos in debian and doc-dir targets. 2001-06-07 Bastiaan Bakker * include/log4tango/LayoutAppender.hh: set SimpleLayout as DefaultLayoutType. * src/LayoutAppender.cpp (LayoutAppender, setLayout): use DefaultLayoutType to construct new Layouts. * src/LayoutAppender.cpp (setLayout): check whether old Layout and new Layout are the same object. * src/Category.cpp (setAppender): check whether old and new Appender are the same object. * src/Filter.cpp (setChainedFilter): check whether old and new Filter are the same object. * include/log4tango/Config.hh, include/log4tango/Portability.hh, include/log4tango/OstringStream.hh, include/log4tango/Makefile.am, src/Appender.cpp, src/AppenderSkeleton.cpp, src/BasicLayout.cpp, src/Category.cpp, src/FileAppender.cpp, src/Filter.cpp, src/FixedContextCategory.cpp, src/HierarchyMaintainer.cpp, src/IdsaAppender.cpp, src/LayoutAppender.cpp, src/Log4cppCleanup.cpp, src/LoggingEvent.cpp, src/Log4cppCleanup.cpp, src/LoggingEvent.cpp, src/NDC.cpp, src/OstreamAppender.cpp, src/OstringStream.cpp, src/Level.cpp, src/SimpleLayout.cpp, src/StringQueueAppender.cpp, src/SyslogAppender.cpp, msvc6/log4tango/log4tango.dsp, tests/testmain.cpp: renamed Config.hh to Portability.hh * m4/AC_AS_DIRNAME.m4, m4/AC_AS_MKDIR_P.m4, m4/AC_ECHO_MKFILE.m4: removed * m4/AC_CREATE_PREFIX_CONFIG_H.m4: replaced AC_ECHO_MKFILE with AS_DIRNAME. This means autoconf >= 2.4 required. * configure.in, include/log4tango/config-win32.h: upped version number to 0.2.5. * configure.in: upped LT_VERSION to 1:0:0. 2001-06-06 Bastiaan Bakker * include/log4tango/AppenderSkeleton.hh, include/log4tango/BasicLayout.hh, include/log4tango/HierarchyMaintainer.hh, include/log4tango/IdsaAppender.hh, include/log4tango/Log4cppCleanup.hh, include/log4tango/LoggingEvent.hh, include/log4tango/OstreamAppender.hh, include/log4tango/OstringStream.hh, include/log4tango/Level.hh, include/log4tango/SimpleLayout.hh, include/log4tango/SyslogAppender.hh: Documentation updates. 2001-06-06 Uwe Jäger * include/log4tango/config-win32.h: LOG4TANGO_HAVE_SNPRINTF, WIN32, LOG4TANGO_FIX_ERROR_COLLISION are defined for win32 * tests/testmain.cpp: added #ifdef's to make it compile with Borland C++ Builder 2001-06-05 Bastiaan Bakker * include/log4tango/Config.hh, include/log4tango/config-win32.h: Added * include/log4tango/Makefile.am: added Export.hh and config-win32.h to liblog4tangoinclude_HEADERS. * include/log4tango/Config-win32.hh: removed 2001-06-04 Bastiaan Bakker * Makefile.am: removed config.h copy from dist-hook * m4/AC_CREATE_GENERIC_CONFIG.m4: added * log4tango-config.in: removed (obsoleted by AC_CREATE_GENERIC_CONFIG) * Configure.in: added AC_CREATE_GENERIC_CONFIG, removed log4tango-config from AC_OUTPUT 2001-06-03 Bastiaan Bakker * configure.in: added AC_CREATE_PREFIX_CONFIG_H for creation of include/log4tango/config.h (which has been removed from AM_CONFIG_HEADER) * Config.hh.in: removed * Config.hh: copied from Config.hh.in. include and remove LOG4TANGO_* defines. * include/log4tango/Makefile.am: added config.h, removed Config.hh.in * Appender.cpp, AppenderSkeleton.cpp, BasicLayout.cpp, Category.cpp, FileAppender.cpp, Filter.cpp, FixedContextCategory.cpp, HierarchyMaintainer.cpp, IdsaAppender.cpp, LayoutAppender.cpp, Log4cppCleanup.cpp, LoggingEvent.cpp, NDC.cpp, OstreamAppender.cpp, OstringStream.cpp, Level.cpp, SimpleLayout.cpp, StringQueueAppender.cpp,SyslogAppender.cpp: added inclusion of , prefixed autoconf #ifdefs with LOG4TANGO_ * AC_AS_DIRNAME.m4, AC_AS_MKDIR_P.m4, AC_CREATE_PREFIX_CONFIG_H.m4, AC_ECHO_MKFILE.m4: added 2001-06-01 Bastiaan Bakker * Level.hh: #define ERROR workaround try 3, put fix inside LOG4TANGO_FIX_ERROR_COLLISION switch. * tests/testErrorCollision.cpp, tests/Makefile.am: added test for #define ERROR workaround. 2001-05-29 Bastiaan Bakker * Level.hh: #define ERROR workaround try 2. * Merge of Borland support patch by Uwe Jäger . 2001-05-28 Bastiaan Bakker * Level.hh: included workaround for #define ERROR rudeness in windows.h on Win32. 2001-05-23 Bastiaan Bakker * log4tango.spec.in: run ldconfig after install or uninstall. Upped release# to 3. * Makefile.am: in rpm target corrected top_srcdir variable name. 2001-05-19 Bastiaan Bakker * Fixed distcheck target. * Fixed check target. It runs testNDC, testCategory and testFixedContextCategory as tests. * Added subdir m4 with (common) autoconf macros. * Started adding throw() specifiers to methods. 2001-04-21 Bastiaan Bakker Rereleased as 0.2.4b MSVC++: Stripped '\r' characters from .dsp and .dsw files. MSVC++: Added StringQueueAppender and FixedContextCategory to log4tango.dsp. 2001-04-20 Steve Ostlind MSVC++: build log4tango library with multithreaded DLL. 2001-04-19 Bastiaan Bakker Now also added the files in debian and msvc6 to EXTRA_DIST, so they finally get into the dist tar ball. Sigh. 2001-04-18 Bastiaan Bakker Released as 0.2.4 Added debian and msvc6 subdirs to autoconf configuration: they were missing from the dist target. 2001-04-17 Bastiaan Bakker Made Category subclassable. Added FixedContextCategory class. 2001-04-12 Bastiaan Bakker Merged Marcel Harkema's patch for Debian package support. 2001-04-11 Bastiaan Bakker Added StringQueueAppender class. Separated API docs from devel RPM, into a doc RPM. 2001-04-10 Bastiaan Bakker Rerelease as 0.2.3b Fixed bugs: #415056 Win32: log4tango project file broken #415059 Win32: problem with 'using namespace std' 2001-04-09 Bastiaan Bakker Release 0.2.3 Fixed and resolved Bugs: #411711 missing Clock.hh #411902 invalid AppenderMap iterator #412008 memory leak in OstringStream::str() #412232 _append problem #414958 printf style logging kaputt 2001-04-06 Bastiaan Bakker Added class Filter, with which Appenders can filter out LoggingEvents Added class AppenderSkeleton, base class for Appender implementations Modified the Layout interface: it now returns a std::string instead of a char*. 2001-03-?? Cedric Le Goater Cleanup of Hints and StreamUtil to OstringStream. 2001-03-11 Bastiaan Bakker Added LayoutAppender. Changed Layout ownership for Appenders: they now own their Appender. 2001-03-07 Bastiaan Bakker Moved to new iostreams. 2001-03-04 Bastiaan Bakker Release 0.2.2 Added doc-dist make target Added testCategory to tests 2001-02-25 Bastiaan Bakker Merged in Win32 / MSVC++6.0 support patches from Lynn Owen 2001-02-15 Bastiaan Bakker Release 0.2.1 Changed license to the GNU Lesser General Public License (LGPL). 2001-01-25 Cedric Le Goater Added EMER, ALERT, CRIT and NOTICE shortcuts methods to Category. 2000-12-22 Bastiaan Bakker Merged more patches from Cedric Le Goater, including an RPMS spec file and a testbench. 2000-12-18 Bastiaan Bakker Added IdsaAppender contributed by Marc Welz. Merged Tru64 support patches from Cedric Le Goater. 2000-12-10 Bastiaan Bakker Release 0.2.0 Integrated autoconf setup contributed by Cedric Le Goater. Fixed compilation problem in NDC on platforms with g++-2 library (instead of g++-3). (Reported by Louis Bayle .) Added CategoryStream. 2000-12-07 Bastiaan Bakker Release 0.1 Added Doxygen generated API documentation. Most of it has been copied verbatim from LOG4J. Added NDC (Nested Diagnostic Context) class. Added OstreamAppender. Added SyslogAppender. Fixed bug in HierarchyMaintainer: getInstance should NOT set the Appender of a newly instantiated Category. 2000-12-03 Bastiaan Bakker Release 0.0 First CVS import at SourceForge. tango-9.2.5a/lib/cpp/log4tango/INSTALL0000644023471100065110000002207113034744765014224 00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PREFIX', the package will use PREFIX as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. tango-9.2.5a/lib/cpp/log4tango/NEWS0000644023471100065110000000005713034744765013672 00000000000000See 'Releases' section of HTML documentation. tango-9.2.5a/lib/cpp/log4tango/THANKS0000644023471100065110000000027113034744764014103 00000000000000Log4Tango is a light and custom version of log4tango for TANGO. The log4tango library port from the LOG4J Java library was initiated by Bastiaan Bakker . tango-9.2.5a/lib/cpp/log4tango/log4tango.m40000644023471100065110000001624313034744765015337 00000000000000# Configure paths for LOG4TANGO # Owen Taylor 97-11-3 dnl AM_PATH_LOG4TANGO([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for LOG4TANGO, and define LOG4TANGO_CFLAGS and LOG4TANGO_LIBS dnl AC_DEFUN(AM_PATH_LOG4TANGO, [dnl dnl Get the cflags and libraries from the log4tango-config script dnl AC_ARG_WITH(log4tango-prefix,[ --with-log4tango-prefix=PFX Prefix where LOG4TANGO is installed (optional)], log4tango_config_prefix="$withval", log4tango_config_prefix="") AC_ARG_WITH(log4tango-exec-prefix,[ --with-log4tango-exec-prefix=PFX Exec prefix where LOG4TANGO is installed (optional)], log4tango_config_exec_prefix="$withval", log4tango_config_exec_prefix="") AC_ARG_ENABLE(log4tangotest, [ --disable-log4tangotest Do not try to compile and run a test LOG4TANGO program], , enable_log4tangotest=yes) if test x$log4tango_config_exec_prefix != x ; then log4tango_config_args="$log4tango_config_args --exec-prefix=$log4tango_config_exec_prefix" if test x${LOG4TANGO_CONFIG+set} != xset ; then LOG4TANGO_CONFIG=$log4tango_config_exec_prefix/bin/log4tango-config fi fi if test x$log4tango_config_prefix != x ; then log4tango_config_args="$log4tango_config_args --prefix=$log4tango_config_prefix" if test x${LOG4TANGO_CONFIG+set} != xset ; then LOG4TANGO_CONFIG=$log4tango_config_prefix/bin/log4tango-config fi fi AC_PATH_PROG(LOG4TANGO_CONFIG, log4tango-config, no) min_log4tango_version=ifelse([$1], ,0.99.7,$1) AC_MSG_CHECKING(for LOG4TANGO - version >= $min_log4tango_version) no_log4tango="" if test "$LOG4TANGO_CONFIG" = "no" ; then no_log4tango=yes else LOG4TANGO_CFLAGS=`$LOG4TANGO_CONFIG $log4tango_config_args --cflags` LOG4TANGO_LIBS=`$LOG4TANGO_CONFIG $log4tango_config_args --libs` log4tango_config_major_version=`$LOG4TANGO_CONFIG $log4tango_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` log4tango_config_minor_version=`$LOG4TANGO_CONFIG $log4tango_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` log4tango_config_micro_version=`$LOG4TANGO_CONFIG $log4tango_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x$enable_log4tangotest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_CXXFLAGS="$CXXFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $LOG4TANGO_CFLAGS" CXXFLAGS="$CXXFLAGS $LOG4TANGO_CFLAGS" LIBS="$LOG4TANGO_LIBS $LIBS" dnl dnl Now check if the installed LOG4TANGO is sufficiently new. (Also sanity dnl checks the results of log4tango-config to some extent dnl rm -f conf.log4tangotest AC_TRY_RUN([ #include #include #include int main () { int log4tango_major, log4tango_minor, log4tango_micro; int major, minor, micro; char *tmp_version; char *tmp_log4tango_version; system ("touch conf.log4tangotest"); /* HP/UX 9 (%@#!) writes to sscanf strings */ tmp_version = strdup("$min_log4tango_version"); if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_log4tango_version"); exit(1); } /* HP/UX 9 (%@#!) writes to sscanf strings */ tmp_log4tango_version = strdup(LOG4TANGO_VERSION); if (sscanf(tmp_log4tango_version, "%d.%d.%d", &log4tango_major, &log4tango_minor, &log4tango_micro) != 3) { printf("%s, bad log4tango version string\n", LOG4TANGO_VERSION); exit(1); } if ((log4tango_major > major) || ((log4tango_major == major) && (log4tango_minor > minor)) || ((log4tango_major == major) && (log4tango_minor == minor) && (log4tango_micro >= micro))) { return 0; } else { printf("\n*** An old version of LOG4TANGO (%d.%d.%d) was found.\n", log4tango_major, log4tango_minor, log4tango_micro); printf("*** You need a version of LOG4TANGO newer than %d.%d.%d. The latest version of\n", major, minor, micro); printf("***\n"); printf("*** If you have already installed a sufficiently new version, this error\n"); printf("*** probably means that the wrong copy of the log4tango-config shell script is\n"); printf("*** being found. The easiest way to fix this is to remove the old version\n"); printf("*** of LOG4TANGO, but you can also set the LOG4TANGO_CONFIG environment to point to the\n"); printf("*** correct copy of log4tango-config. (In this case, you will have to\n"); printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); printf("*** so that the correct libraries are found at run-time))\n"); } log4tango::Category& log = log4tango::Category::getRoot(); return 1; } ],, no_log4tango=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" fi fi if test "x$no_log4tango" = x ; then AC_MSG_RESULT(yes) ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "$LOG4TANGO_CONFIG" = "no" ; then echo "*** The log4tango-config script installed by LOG4TANGO could not be found" echo "*** If LOG4TANGO was installed in PREFIX, make sure PREFIX/bin is in" echo "*** your path, or set the LOG4TANGO_CONFIG environment variable to the" echo "*** full path to log4tango-config." else if test -f conf.log4tangotest ; then : else echo "*** Could not run LOG4TANGO test program, checking why..." CFLAGS="$CFLAGS $LOG4TANGO_CFLAGS" CXXFLAGS="$CXXFLAGS $LOG4TANGO_CFLAGS" LIBS="$LIBS $LOG4TANGO_LIBS" AC_TRY_LINK([ #include ], [ log4tango::Category cat("a_cat"); return 0; ], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding LOG4TANGO or finding the wrong" echo "*** version of LOG4TANGO. If it is not finding LOG4TANGO, you'll need to set your" echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" echo "*** to the installed location Also, make sure you have run ldconfig if that" echo "*** is required on your system" echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" echo "***" ], [ echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means LOG4TANGO was incorrectly installed" echo "*** or that you have moved LOG4TANGO since it was installed. In the latter case, you" echo "*** may want to edit the log4tango-config script: $LOG4TANGO_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" fi fi LOG4TANGO_CFLAGS="" LOG4TANGO_LIBS="" ifelse([$3], , :, [$3]) fi AC_SUBST(LOG4TANGO_CFLAGS) AC_SUBST(LOG4TANGO_LIBS) rm -f conf.log4tangotest ]) tango-9.2.5a/lib/cpp/log4tango/config/0000755023471100065110000000000013034745255014511 500000000000000tango-9.2.5a/lib/cpp/log4tango/config/Makefile.am0000755023471100065110000000000213034744763016463 00000000000000 tango-9.2.5a/lib/cpp/log4tango/config/Makefile.in0000644023471100065110000002452013034744763016504 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = config DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in config.guess \ config.sub depcomp install-sh ltmain.sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu config/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu config/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/config/config.guess0000755023471100065110000012206513034744763016762 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2003-06-17' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown ## for Red Hat Linux if test -f /etc/redhat-release ; then VENDOR=redhat ; else VENDOR= ; fi # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mipseb-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit 0 ;; Alpha*:OpenVMS:*:*) echo alpha-hp-vms exit 0 ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit 0;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit 0 ;; *:OS/390:*:*) echo i370-ibm-openedition exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit 0 ;; DRS?6000:UNIX_SV:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7 && exit 0 ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit 0 ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit 0 ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c \ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && exit 0 echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit 0 ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; *:UNICOS/mp:*:*) echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) # Determine whether the default compiler uses glibc. eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #if __GLIBC__ >= 2 LIBC=gnu #else LIBC= #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit 0 ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit 0 ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit 0 ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit 0 ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit 0 ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit 0 ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu exit 0 ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ;; ppc:Linux:*:*) echo powerpc-${VENDOR:-unknown}-linux-gnu exit 0 ;; ppc64:Linux:*:*) echo powerpc64-${VENDOR:-unknown}-linux-gnu exit 0 ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit 0 ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit 0 ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit 0 ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu exit 0 ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit 0 ;; x86_64:Linux:*:*) echo x86_64-${VENDOR:-unknown}-linux-gnu exit 0 ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit 0 ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit 0 ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit 0 ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0 test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit 0 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit 0 ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit 0 ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit 0 ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit 0 ;; i*86:*:5:[78]*) case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit 0 ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit 0 ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit 0 ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit 0 ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit 0 ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) case `uname -p` in *86) UNAME_PROCESSOR=i686 ;; powerpc) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit 0 ;; *:QNX:*:4*) echo i386-pc-qnx exit 0 ;; NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit 0 ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit 0 ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit 0 ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit 0 ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit 0 ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit 0 ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit 0 ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit 0 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit 0 ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit 0 ;; *:ITS:*:*) echo pdp10-unknown-its exit 0 ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tango-9.2.5a/lib/cpp/log4tango/config/config.sub0000755023471100065110000007301513034744763016425 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003 Free Software Foundation, Inc. timestamp='2003-06-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit 0 ;; --version | -v ) echo "$version" ; exit 0 ;; --help | --h* | -h ) echo "$usage"; exit 0 ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit 0;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k \ | m32r | m68000 | m68k | m88k | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | s390 | s390x \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* \ | m32r-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | msp430-* \ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | s390-* | s390x-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; mmix*) basic_machine=mmix-knuth os=-mmixware ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nv1) basic_machine=nv1-cray os=-unicosmp ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tango-9.2.5a/lib/cpp/log4tango/config/depcomp0000755023471100065110000003554513034744763016025 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2004-05-31.23 # Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit 0 ;; -v | --v*) echo "depcomp $scriptversion" exit 0 ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` tmpdepfile="$stripped.u" if test "$libtool" = yes; then "$@" -Wc,-M else "$@" -M fi stat=$? if test -f "$tmpdepfile"; then : else stripped=`echo "$stripped" | sed 's,^.*/,,'` tmpdepfile="$stripped.u" fi if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi if test -f "$tmpdepfile"; then outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # Dependencies are output in .lo.d with libtool 1.4. # With libtool 1.5 they are output both in $dir.libs/$base.o.d # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the # latter, because the former will be cleaned when $dir.libs is # erased. tmpdepfile1="$dir.libs/$base.lo.d" tmpdepfile2="$dir$base.o.d" tmpdepfile3="$dir.libs/$base.d" "$@" -Wc,-MD else tmpdepfile1="$dir$base.o.d" tmpdepfile2="$dir$base.d" tmpdepfile3="$dir$base.d" "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi if test -f "$tmpdepfile1"; then tmpdepfile="$tmpdepfile1" elif test -f "$tmpdepfile2"; then tmpdepfile="$tmpdepfile2" else tmpdepfile="$tmpdepfile3" fi if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/lib/cpp/log4tango/config/install-sh0000755023471100065110000002176613034744763016454 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2004-09-10.20 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/lib/cpp/log4tango/config/ltmain.sh0000755023471100065110000105204013034744763016261 00000000000000 # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 tango-9.2.5a/lib/cpp/log4tango/config/missing0000755023471100065110000002453313034744763016042 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2004-09-07.08 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit 0 ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit 0 ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/lib/cpp/log4tango/config/mkinstalldirs0000755023471100065110000000653513034744763017253 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2004-02-15.20 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . errstatus=0 dirmode="" usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit 0 ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit 0 ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr="" chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp="$pathcomp/" done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: tango-9.2.5a/lib/cpp/log4tango/src/0000755023471100065110000000000013034745255014033 500000000000000tango-9.2.5a/lib/cpp/log4tango/src/snprintf.c0000644023471100065110000012251213034744761015766 00000000000000// // snprintf.c - a portable implementation of snprintf // // AUTHOR // Mark Martinec , April 1999. // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . /* * FEATURES * - careful adherence to specs regarding flags, field width and precision; * - good performance for large string handling (large format, large * argument or large paddings). Performance is similar to system's sprintf * and in several cases significantly better (make sure you compile with * optimizations turned on, tell the compiler the code is strict ANSI * if necessary to give it more freedom for optimizations); * - return value semantics per ISO/IEC 9899:1999 ("ISO C99"); * - written in standard ISO/ANSI C - requires an ANSI C compiler. * * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES * * This snprintf only supports the following conversion specifiers: * s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below) * with flags: '-', '+', ' ', '0' and '#'. * An asterisk is supported for field width as well as precision. * * Length modifiers 'h' (short int), 'l' (long int), * and 'll' (long long int) are supported. * NOTE: * If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the * length modifier 'll' is recognized but treated the same as 'l', * which may cause argument value truncation! Defining * SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also * handles length modifier 'll'. long long int is a language extension * which may not be portable. * * Conversion of numeric data (conversion specifiers d, u, o, x, X, p) * with length modifiers (none or h, l, ll) is left to the system routine * sprintf, but all handling of flags, field width and precision as well as * c and s conversions is done very carefully by this portable routine. * If a string precision (truncation) is specified (e.g. %.8s) it is * guaranteed the string beyond the specified precision will not be referenced. * * Length modifiers h, l and ll are ignored for c and s conversions (data * types wint_t and wchar_t are not supported). * * The following common synonyms for conversion characters are supported: * - i is a synonym for d * - D is a synonym for ld, explicit length modifiers are ignored * - U is a synonym for lu, explicit length modifiers are ignored * - O is a synonym for lo, explicit length modifiers are ignored * The D, O and U conversion characters are nonstandard, they are supported * for backward compatibility only, and should not be used for new code. * * The following is specifically NOT supported: * - flag ' (thousands' grouping character) is recognized but ignored * - numeric conversion specifiers: f, e, E, g, G and synonym F, * as well as the new a and A conversion specifiers * - length modifier 'L' (long double) and 'q' (quad - use 'll' instead) * - wide character/string conversions: lc, ls, and nonstandard * synonyms C and S * - writeback of converted string length: conversion character n * - the n$ specification for direct reference to n-th argument * - locales * * It is permitted for str_m to be zero, and it is permitted to specify NULL * pointer for resulting string argument if str_m is zero (as per ISO C99). * * The return value is the number of characters which would be generated * for the given input, excluding the trailing null. If this value * is greater or equal to str_m, not all characters from the result * have been stored in str, output bytes beyond the (str_m-1) -th character * are discarded. If str_m is greater than zero it is guaranteed * the resulting string will be null-terminated. * * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1, * but is different from some older and vendor implementations, * and is also different from XPG, XSH5, SUSv2 specifications. * For historical discussion on changes in the semantics and standards * of snprintf see printf(3) man page in the Linux programmers manual. * * Routines asprintf and vasprintf return a pointer (in the ptr argument) * to a buffer sufficiently large to hold the resulting string. This pointer * should be passed to free(3) to release the allocated storage when it is * no longer needed. If sufficient space cannot be allocated, these functions * will return -1 and set ptr to be a NULL pointer. These two routines are a * GNU C library extensions (glibc). * * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf, * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1 * characters into the allocated output string, the last character in the * allocated buffer then gets the terminating null. If the formatted string * length (the return value) is greater than or equal to the str_m argument, * the resulting string was truncated and some of the formatted characters * were discarded. These routines present a handy way to limit the amount * of allocated memory to some sane value. * * AVAILABILITY * http://www.ijs.si/software/snprintf/ * * REVISION HISTORY * 1999-04 V0.9 Mark Martinec * - initial version, some modifications after comparing printf * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, * and checking how Perl handles sprintf (differently!); * 1999-04-09 V1.0 Mark Martinec * - added main test program, fixed remaining inconsistencies, * added optional (long long int) support; * 1999-04-12 V1.1 Mark Martinec * - support the 'p' conversion (pointer to void); * - if a string precision is specified * make sure the string beyond the specified precision * will not be referenced (e.g. by strlen); * 1999-04-13 V1.2 Mark Martinec * - support synonyms %D=%ld, %U=%lu, %O=%lo; * - speed up the case of long format string with few conversions; * 1999-06-30 V1.3 Mark Martinec * - fixed runaway loop (eventually crashing when str_l wraps * beyond 2^31) while copying format string without * conversion specifiers to a buffer that is too short * (thanks to Edwin Young for * spotting the problem); * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) * to snprintf.h * 2000-02-14 V2.0 (never released) Mark Martinec * - relaxed license terms: The Artistic License now applies. * You may still apply the GNU GENERAL PUBLIC LICENSE * as was distributed with previous versions, if you prefer; * - changed REVISION HISTORY dates to use ISO 8601 date format; * - added vsnprintf (patch also independently proposed by * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) * 2000-06-27 V2.1 Mark Martinec * - removed POSIX check for str_m<1; value 0 for str_m is * allowed by ISO C99 (and GNU C library 2.1) - (pointed out * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). * Besides relaxed license this change in standards adherence * is the main reason to bump up the major version number; * - added nonstandard routines asnprintf, vasnprintf, asprintf, * vasprintf that dynamically allocate storage for the * resulting string; these routines are not compiled by default, * see comments where NEED_V?ASN?PRINTF macros are defined; * - autoconf contributed by Caolan McNamara * 2000-10-06 V2.2 Mark Martinec * - BUG FIX: the %c conversion used a temporary variable * that was no longer in scope when referenced, * possibly causing incorrect resulting character; * - BUG FIX: make precision and minimal field width unsigned * to handle huge values (2^31 <= n < 2^32) correctly; * also be more careful in the use of signed/unsigned/size_t * internal variables - probably more careful than many * vendor implementations, but there may still be a case * where huge values of str_m, precision or minimal field * could cause incorrect behaviour; * - use separate variables for signed/unsigned arguments, * and for short/int, long, and long long argument lengths * to avoid possible incompatibilities on certain * computer architectures. Also use separate variable * arg_sign to hold sign of a numeric argument, * to make code more transparent; * - some fiddling with zero padding and "0x" to make it * Linux compatible; * - systematically use macros fast_memcpy and fast_memset * instead of case-by-case hand optimization; determine some * breakeven string lengths for different architectures; * - terminology change: 'format' -> 'conversion specifier', * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', * 'alternative form' -> 'alternate form', * 'data type modifier' -> 'length modifier'; * - several comments rephrased and new ones added; * - make compiler not complain about 'credits' defined but * not used; */ /* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf. * * If HAVE_SNPRINTF is defined this module will not produce code for * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, * causing this portable version of snprintf to be called portable_snprintf * (and portable_vsnprintf). */ /* #define HAVE_SNPRINTF */ /* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and * vsnprintf but you would prefer to use the portable routine(s) instead. * In this case the portable routine is declared as portable_snprintf * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') * is defined to expand to 'portable_v?snprintf' - see file snprintf.h . * Defining this macro is only useful if HAVE_SNPRINTF is also defined, * but does does no harm if defined nevertheless. */ /* #define PREFER_PORTABLE_SNPRINTF */ /* Define SNPRINTF_LONGLONG_SUPPORT if you want to support * data type (long long int) and length modifier 'll' (e.g. %lld). * If undefined, 'll' is recognized but treated as a single 'l'. * * If the system's sprintf does not handle 'll' * the SNPRINTF_LONGLONG_SUPPORT must not be defined! * * This is off by default as (long long int) is a language extension. */ /* #define SNPRINTF_LONGLONG_SUPPORT */ /* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf. * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly, * otherwise both snprintf and vsnprintf routines will be defined * and snprintf will be a simple wrapper around vsnprintf, at the expense * of an extra procedure call. */ /* #define NEED_SNPRINTF_ONLY */ /* Define NEED_V?ASN?PRINTF macros if you need library extension * routines asprintf, vasprintf, asnprintf, vasnprintf respectively, * and your system library does not provide them. They are all small * wrapper routines around portable_vsnprintf. Defining any of the four * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY * and turns on PREFER_PORTABLE_SNPRINTF. * * Watch for name conflicts with the system library if these routines * are already present there. * * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as * specified by C99, to be able to traverse the same list of arguments twice. * I don't know of any other standard and portable way of achieving the same. * With some versions of gcc you may use __va_copy(). You might even get away * with "ap2 = ap", in this case you must not call va_end(ap2) ! * #define va_copy(ap2,ap) ap2 = ap */ /* #define NEED_ASPRINTF */ /* #define NEED_ASNPRINTF */ /* #define NEED_VASPRINTF */ /* #define NEED_VASNPRINTF */ /* Define the following macros if desired: * SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE, * HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE, * DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE, * PERL_COMPATIBLE, PERL_BUG_COMPATIBLE, * * - For portable applications it is best not to rely on peculiarities * of a given implementation so it may be best not to define any * of the macros that select compatibility and to avoid features * that vary among the systems. * * - Selecting compatibility with more than one operating system * is not strictly forbidden but is not recommended. * * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE . * * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is * documented in a sprintf man page on a given operating system * and actually adhered to by the system's sprintf (but not on * most other operating systems). It may also refer to and enable * a behaviour that is declared 'undefined' or 'implementation specific' * in the man page but a given implementation behaves predictably * in a certain way. * * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf * that contradicts the sprintf man page on the same operating system. * * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE * conditionals take into account all idiosyncrasies of a particular * implementation, there may be other incompatibilities. */ /* ============================================= */ /* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */ /* ============================================= */ #define PORTABLE_SNPRINTF_VERSION_MAJOR 2 #define PORTABLE_SNPRINTF_VERSION_MINOR 2 #if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) # if defined(NEED_SNPRINTF_ONLY) # undef NEED_SNPRINTF_ONLY # endif # if !defined(PREFER_PORTABLE_SNPRINTF) # define PREFER_PORTABLE_SNPRINTF # endif #endif #if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) #define SOLARIS_COMPATIBLE #endif #if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) #define HPUX_COMPATIBLE #endif #if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) #define DIGITAL_UNIX_COMPATIBLE #endif #if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) #define PERL_COMPATIBLE #endif #if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) #define LINUX_COMPATIBLE #endif #include #include #include #include #include #include #include #ifdef isdigit #undef isdigit #endif #define isdigit(c) ((c) >= '0' && (c) <= '9') /* For copying strings longer or equal to 'breakeven_point' * it is more efficient to call memcpy() than to do it inline. * The value depends mostly on the processor architecture, * but also on the compiler and its optimization capabilities. * The value is not critical, some small value greater than zero * will be just fine if you don't care to squeeze every drop * of performance out of the code. * * Small values favor memcpy, large values favor inline code. */ #if defined(__alpha__) || defined(__alpha) # define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */ #endif #if defined(__i386__) || defined(__i386) # define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */ #endif #if defined(__hppa) # define breakeven_point 10 /* HP-PA - gcc */ #endif #if defined(__sparc__) || defined(__sparc) # define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ #endif /* some other values of possible interest: */ /* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ /* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ #ifndef breakeven_point # define breakeven_point 6 /* some reasonable one-size-fits-all value */ #endif #define fast_memcpy(d,s,n) \ { register size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memcpy((d), (s), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ register char *dd; register const char *ss; \ for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } #define fast_memset(d,c,n) \ { register size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memset((d), (int)(c), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ register char *dd; register const int cc=(int)(c); \ for (dd=(d); nn>0; nn--) *dd++ = cc; } } /* prototypes */ #if defined(NEED_ASPRINTF) int asprintf (char **ptr, const char *fmt, /*args*/ ...); #endif #if defined(NEED_VASPRINTF) int vasprintf (char **ptr, const char *fmt, va_list ap); #endif #if defined(NEED_ASNPRINTF) int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); #endif #if defined(NEED_VASNPRINTF) int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); #endif #if defined(HAVE_SNPRINTF) /* declare our portable snprintf routine under name portable_snprintf */ /* declare our portable vsnprintf routine under name portable_vsnprintf */ #else /* declare our portable routines under names snprintf and vsnprintf */ #define portable_snprintf snprintf #if !defined(NEED_SNPRINTF_ONLY) #define portable_vsnprintf vsnprintf #endif #endif #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); #if !defined(NEED_SNPRINTF_ONLY) int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); #endif #endif /* declarations */ static char credits[] = "\n\ @(#)snprintf.c, v2.2: Mark Martinec, \n\ @(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ @(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; #if defined(NEED_ASPRINTF) int asprintf(char **ptr, const char *fmt, /*args*/ ...) { va_list ap; size_t str_m; int str_l; *ptr = NULL; va_start(ap, fmt); /* measure the required size */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); va_end(ap); assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ *ptr = (char *) malloc(str_m = (size_t)str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2; va_start(ap, fmt); str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); va_end(ap); assert(str_l2 == str_l); } return str_l; } #endif #if defined(NEED_VASPRINTF) int vasprintf(char **ptr, const char *fmt, va_list ap) { size_t str_m; int str_l; *ptr = NULL; { va_list ap2; va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ va_end(ap2); } assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ *ptr = (char *) malloc(str_m = (size_t)str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); assert(str_l2 == str_l); } return str_l; } #endif #if defined(NEED_ASNPRINTF) int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { va_list ap; int str_l; *ptr = NULL; va_start(ap, fmt); /* measure the required size */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); va_end(ap); assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { *ptr = (char *) malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2; va_start(ap, fmt); str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); va_end(ap); assert(str_l2 == str_l); } } return str_l; } #endif #if defined(NEED_VASNPRINTF) int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) { int str_l; *ptr = NULL; { va_list ap2; va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ va_end(ap2); } assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { *ptr = (char *) malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); assert(str_l2 == str_l); } } return str_l; } #endif /* * If the system does have snprintf and the portable routine is not * specifically required, this module produces no code for snprintf/vsnprintf. */ #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) #if !defined(NEED_SNPRINTF_ONLY) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { va_list ap; int str_l; va_start(ap, fmt); str_l = portable_vsnprintf(str, str_m, fmt, ap); va_end(ap); return str_l; } #endif #if defined(NEED_SNPRINTF_ONLY) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { #else int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { #endif #if defined(NEED_SNPRINTF_ONLY) va_list ap; #endif size_t str_l = 0; const char *p = fmt; /* In contrast with POSIX, the ISO C99 now says * that str can be NULL and str_m can be 0. * This is more useful than the old: if (str_m < 1) return -1; */ #if defined(NEED_SNPRINTF_ONLY) va_start(ap, fmt); #endif if (!p) p = ""; while (*p) { if (*p != '%') { /* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */ /* but the following code achieves better performance for cases * where format string is long and contains few conversions */ const char *q = strchr(p+1,'%'); size_t n = !q ? strlen(p) : (q-p); if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, p, (n>avail?avail:n)); } p += n; str_l += n; } else { const char *starting_p; size_t min_field_width = 0, precision = 0; int zero_padding = 0, precision_specified = 0, justify_left = 0; int alternate_form = 0, force_sign = 0; int space_for_positive = 1; /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored. */ char length_modifier = '\0'; /* allowed values: \0, h, l, L */ char tmp[32];/* temporary buffer for simple numeric->string conversion */ const char *str_arg; /* string address in case of string argument */ size_t str_arg_l; /* natural field width of arg without padding and sign */ unsigned char uchar_arg; /* unsigned char argument value - only defined for c conversion. N.B. standard explicitly states the char argument for the c conversion is unsigned */ size_t number_of_zeros_to_pad = 0; /* number of zeros to be inserted for numeric conversions as required by the precision or minimal field width */ size_t zero_padding_insertion_ind = 0; /* index into tmp where zero padding is to be inserted */ char fmt_spec = '\0'; /* current conversion specifier character */ str_arg = credits;/* just to make compiler happy (defined but not used)*/ str_arg = NULL; starting_p = p; p++; /* skip '%' */ /* parse flags */ while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '\'') { switch (*p) { case '0': zero_padding = 1; break; case '-': justify_left = 1; break; case '+': force_sign = 1; space_for_positive = 0; break; case ' ': force_sign = 1; /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ #ifdef PERL_COMPATIBLE /* ... but in Perl the last of ' ' and '+' applies */ space_for_positive = 1; #endif break; case '#': alternate_form = 1; break; case '\'': break; } p++; } /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ /* parse field width */ if (*p == '*') { int j; p++; j = va_arg(ap, int); if (j >= 0) min_field_width = j; else { min_field_width = -j; justify_left = 1; } } else if (isdigit((int)(*p))) { /* size_t could be wider than unsigned int; make sure we treat argument like common implementations do */ unsigned int uj = *p++ - '0'; while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); min_field_width = uj; } /* parse precision */ if (*p == '.') { p++; precision_specified = 1; if (*p == '*') { int j = va_arg(ap, int); p++; if (j >= 0) precision = j; else { precision_specified = 0; precision = 0; /* NOTE: * Solaris 2.6 man page claims that in this case the precision * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page * claim that this case should be treated as unspecified precision, * which is what we do here. */ } } else if (isdigit((int)(*p))) { /* size_t could be wider than unsigned int; make sure we treat argument like common implementations do */ unsigned int uj = *p++ - '0'; while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); precision = uj; } } /* parse 'h', 'l' and 'll' length modifiers */ if (*p == 'h' || *p == 'l') { length_modifier = *p; p++; if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ #ifdef SNPRINTF_LONGLONG_SUPPORT length_modifier = '2'; /* double l encoded as '2' */ #else length_modifier = 'l'; /* treat it as a single 'l' */ #endif p++; } } fmt_spec = *p; /* common synonyms: */ switch (fmt_spec) { case 'i': fmt_spec = 'd'; break; case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; default: break; } /* get parameter value, do initial processing */ switch (fmt_spec) { case '%': /* % behaves similar to 's' regarding flags and field widths */ case 'c': /* c behaves similar to 's' regarding flags and field widths */ case 's': length_modifier = '\0'; /* wint_t and wchar_t not supported */ /* the result of zero padding flag with non-numeric conversion specifier*/ /* is undefined. Solaris and HPUX 10 does zero padding in this case, */ /* Digital Unix and Linux does not. */ #if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) zero_padding = 0; /* turn zero padding off for string conversions */ #endif str_arg_l = 1; switch (fmt_spec) { case '%': str_arg = p; break; case 'c': { int j = va_arg(ap, int); uchar_arg = (unsigned char) j; /* standard demands unsigned char */ str_arg = (const char *) &uchar_arg; break; } case 's': str_arg = va_arg(ap, const char *); if (!str_arg) str_arg_l = 0; /* make sure not to address string beyond the specified precision !!! */ else if (!precision_specified) str_arg_l = strlen(str_arg); /* truncate string if necessary as requested by precision */ else if (precision == 0) str_arg_l = 0; else { /* memchr on HP does not like n > 2^31 !!! */ const char *q = (const char*)(memchr(str_arg, '\0', precision <= 0x7fffffff ? precision : 0x7fffffff)); str_arg_l = !q ? precision : (q-str_arg); } break; default: break; } break; case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { /* NOTE: the u, o, x, X and p conversion specifiers imply the value is unsigned; d implies a signed value */ int arg_sign = 0; /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), +1 if greater than zero (or nonzero for unsigned arguments), -1 if negative (unsigned argument is never negative) */ int int_arg = 0; unsigned int uint_arg = 0; /* only defined for length modifier h, or for no length modifiers */ long int long_arg = 0; unsigned long int ulong_arg = 0; /* only defined for length modifier l */ void *ptr_arg = NULL; /* pointer argument value -only defined for p conversion */ #ifdef SNPRINTF_LONGLONG_SUPPORT long long int long_long_arg = 0; unsigned long long int ulong_long_arg = 0; /* only defined for length modifier ll */ #endif if (fmt_spec == 'p') { /* HPUX 10: An l, h, ll or L before any other conversion character * (other than d, i, u, o, x, or X) is ignored. * Digital Unix: * not specified, but seems to behave as HPUX does. * Solaris: If an h, l, or L appears before any other conversion * specifier (other than d, i, u, o, x, or X), the behavior * is undefined. (Actually %hp converts only 16-bits of address * and %llp treats address as 64-bit data which is incompatible * with (void *) argument on a 32-bit system). */ #ifdef SOLARIS_COMPATIBLE # ifdef SOLARIS_BUG_COMPATIBLE /* keep length modifiers even if it represents 'll' */ # else if (length_modifier == '2') length_modifier = '\0'; # endif #else length_modifier = '\0'; #endif ptr_arg = va_arg(ap, void *); if (ptr_arg != NULL) arg_sign = 1; } else if (fmt_spec == 'd') { /* signed */ switch (length_modifier) { case '\0': case 'h': /* It is non-portable to specify a second argument of char or short * to va_arg, because arguments seen by the called function * are not char or short. C converts char and short arguments * to int before passing them to a function. */ int_arg = va_arg(ap, int); if (int_arg > 0) arg_sign = 1; else if (int_arg < 0) arg_sign = -1; break; case 'l': long_arg = va_arg(ap, long int); if (long_arg > 0) arg_sign = 1; else if (long_arg < 0) arg_sign = -1; break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': long_long_arg = va_arg(ap, long long int); if (long_long_arg > 0) arg_sign = 1; else if (long_long_arg < 0) arg_sign = -1; break; #endif } } else { /* unsigned */ switch (length_modifier) { case '\0': case 'h': uint_arg = va_arg(ap, unsigned int); if (uint_arg) arg_sign = 1; break; case 'l': ulong_arg = va_arg(ap, unsigned long int); if (ulong_arg) arg_sign = 1; break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': ulong_long_arg = va_arg(ap, unsigned long long int); if (ulong_long_arg) arg_sign = 1; break; #endif } } str_arg = tmp; str_arg_l = 0; /* NOTE: * For d, i, u, o, x, and X conversions, if precision is specified, * the '0' flag should be ignored. This is so with Solaris 2.6, * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. */ #ifndef PERL_COMPATIBLE if (precision_specified) zero_padding = 0; #endif if (fmt_spec == 'd') { if (force_sign && arg_sign >= 0) tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; /* leave negative numbers for sprintf to handle, to avoid handling tricky cases like (short int)(-32768) */ #ifdef LINUX_COMPATIBLE } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; #endif } else if (alternate_form) { if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } /* alternate form should have no effect for p conversion, but ... */ #ifdef HPUX_COMPATIBLE else if (fmt_spec == 'p' /* HPUX 10: for an alternate form of p conversion, * a nonzero result is prefixed by 0x. */ #ifndef HPUX_BUG_COMPATIBLE /* Actually it uses 0x prefix even for a zero value. */ && arg_sign != 0 #endif ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } #endif } zero_padding_insertion_ind = str_arg_l; if (!precision_specified) precision = 1; /* default precision is 1 */ if (precision == 0 && arg_sign == 0 #if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) && fmt_spec != 'p' /* HPUX 10 man page claims: With conversion character p the result of * converting a zero value with a precision of zero is a null string. * Actually HP returns all zeroes, and Linux returns "(nil)". */ #endif ) { /* converted to null string */ /* When zero value is formatted with an explicit precision 0, the resulting formatted string is empty (d, i, u, o, x, X, p). */ } else { char f[5]; int f_l = 0; f[f_l++] = '%'; /* construct a simple format string for sprintf */ if (!length_modifier) { } else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } else f[f_l++] = length_modifier; f[f_l++] = fmt_spec; f[f_l++] = '\0'; if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); else if (fmt_spec == 'd') { /* signed */ switch (length_modifier) { case '\0': case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break; case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; #endif } } else { /* unsigned */ switch (length_modifier) { case '\0': case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break; case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; #endif } } /* include the optional minus sign and possible "0x" in the region before the zero padding insertion point */ if (zero_padding_insertion_ind < str_arg_l && tmp[zero_padding_insertion_ind] == '-') { zero_padding_insertion_ind++; } if (zero_padding_insertion_ind+1 < str_arg_l && tmp[zero_padding_insertion_ind] == '0' && (tmp[zero_padding_insertion_ind+1] == 'x' || tmp[zero_padding_insertion_ind+1] == 'X') ) { zero_padding_insertion_ind += 2; } } { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; if (alternate_form && fmt_spec == 'o' #ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ && (str_arg_l > 0) #endif #ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ #else /* unless zero is already the first character */ && !(zero_padding_insertion_ind < str_arg_l && tmp[zero_padding_insertion_ind] == '0') #endif ) { /* assure leading zero for alternate-form octal numbers */ if (!precision_specified || precision < num_of_digits+1) { /* precision is increased to force the first character to be zero, except if a zero value is formatted with an explicit precision of zero */ precision = num_of_digits+1; precision_specified = 1; } } /* zero padding to specified precision? */ if (num_of_digits < precision) number_of_zeros_to_pad = precision - num_of_digits; } /* zero padding to specified minimal field width? */ if (!justify_left && zero_padding) { int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) number_of_zeros_to_pad += n; } break; } default: /* unrecognized conversion specifier, keep format string as-is*/ zero_padding = 0; /* turn zero padding off for non-numeric convers. */ #ifndef DIGITAL_UNIX_COMPATIBLE justify_left = 1; min_field_width = 0; /* reset flags */ #endif #if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) /* keep the entire format string unchanged */ str_arg = starting_p; str_arg_l = p - starting_p; /* well, not exactly so for Linux, which does something inbetween, * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ #else /* discard the unrecognized conversion, just keep * * the unrecognized conversion character */ str_arg = p; str_arg_l = 0; #endif if (*p) str_arg_l++; /* include invalid conversion specifier unchanged if not at end-of-string */ break; } if (*p) p++; /* step over the just processed conversion specifier */ /* insert padding to the left as requested by min_field_width; this does not include the zero padding in case of numerical conversions*/ if (!justify_left) { /* left padding with blank or zero */ unsigned int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); } str_l += n; } } /* zero padding as requested by the precision or by the minimal field width * for numeric conversions required? */ if (number_of_zeros_to_pad <= 0) { /* will not copy first part of numeric right now, * * force it to be copied later in its entirety */ zero_padding_insertion_ind = 0; } else { /* insert first part of numerics (sign or '0x') before zero padding */ unsigned int n = zero_padding_insertion_ind; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); } str_l += n; } /* insert zero padding as requested by the precision or min field width */ n = number_of_zeros_to_pad; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, '0', (n>avail?avail:n)); } str_l += n; } } /* insert formatted string * (or as-is conversion specifier for unknown conversions) */ { unsigned int n = str_arg_l - zero_padding_insertion_ind; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, (n>avail?avail:n)); } str_l += n; } } /* insert right padding */ if (justify_left) { /* right blank padding to the field width */ unsigned int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, ' ', (n>avail?avail:n)); } str_l += n; } } } } #if defined(NEED_SNPRINTF_ONLY) va_end(ap); #endif if (str_m > 0) { /* make sure the string is null-terminated even at the expense of overwriting the last character (shouldn't happen, but just in case) */ str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; } /* Return the number of characters formatted (excluding trailing null * character), that is, the number of characters that would have been * written to the buffer if it were large enough. * * The value of str_l should be returned, but str_l is of unsigned type * size_t, and snprintf is int, possibly leading to an undetected * integer overflow, resulting in a negative return value, which is illegal. * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. * Should errno be set to EOVERFLOW and EOF returned in this case??? */ return (int) str_l; } #endif tango-9.2.5a/lib/cpp/log4tango/src/Makefile.am0000644023471100065110000000123413034744761016010 00000000000000lib_LTLIBRARIES = liblog4tango.la INCLUDES = -I$(top_srcdir)/include noinst_HEADERS = snprintf.c liblog4tango_la_SOURCES = \ Appender.cpp \ AppenderAttachable.cpp \ LayoutAppender.cpp \ FileAppender.cpp \ RollingFileAppender.cpp \ OstreamAppender.cpp \ Layout.cpp \ PatternLayout.cpp \ XmlLayout.cpp \ Logger.cpp \ LogSeparator.cpp \ LoggerStream.cpp \ LoggingEvent.cpp \ Level.cpp \ NDC.cpp \ Filter.cpp \ TimeStamp.cpp \ StringUtil.hh \ StringUtil.cpp \ DllMain.cpp \ DummyThreads.cpp \ MSThreads.cpp \ PThreads.cpp \ PortabilityImpl.hh \ PortabilityImpl.cpp liblog4tango_la_LDFLAGS = -version-info @LT_VERSION@ tango-9.2.5a/lib/cpp/log4tango/src/Makefile.in0000644023471100065110000005071513034744761016031 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) liblog4tango_la_LIBADD = am_liblog4tango_la_OBJECTS = Appender.lo AppenderAttachable.lo \ LayoutAppender.lo FileAppender.lo RollingFileAppender.lo \ OstreamAppender.lo Layout.lo PatternLayout.lo XmlLayout.lo \ Logger.lo LogSeparator.lo LoggerStream.lo LoggingEvent.lo \ Level.lo NDC.lo Filter.lo TimeStamp.lo StringUtil.lo \ DllMain.lo DummyThreads.lo MSThreads.lo PThreads.lo \ PortabilityImpl.lo liblog4tango_la_OBJECTS = $(am_liblog4tango_la_OBJECTS) liblog4tango_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(liblog4tango_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(liblog4tango_la_SOURCES) DIST_SOURCES = $(liblog4tango_la_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = liblog4tango.la INCLUDES = -I$(top_srcdir)/include noinst_HEADERS = snprintf.c liblog4tango_la_SOURCES = \ Appender.cpp \ AppenderAttachable.cpp \ LayoutAppender.cpp \ FileAppender.cpp \ RollingFileAppender.cpp \ OstreamAppender.cpp \ Layout.cpp \ PatternLayout.cpp \ XmlLayout.cpp \ Logger.cpp \ LogSeparator.cpp \ LoggerStream.cpp \ LoggingEvent.cpp \ Level.cpp \ NDC.cpp \ Filter.cpp \ TimeStamp.cpp \ StringUtil.hh \ StringUtil.cpp \ DllMain.cpp \ DummyThreads.cpp \ MSThreads.cpp \ PThreads.cpp \ PortabilityImpl.hh \ PortabilityImpl.cpp liblog4tango_la_LDFLAGS = -version-info @LT_VERSION@ all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done liblog4tango.la: $(liblog4tango_la_OBJECTS) $(liblog4tango_la_DEPENDENCIES) $(EXTRA_liblog4tango_la_DEPENDENCIES) $(liblog4tango_la_LINK) -rpath $(libdir) $(liblog4tango_la_OBJECTS) $(liblog4tango_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Appender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AppenderAttachable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DllMain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DummyThreads.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileAppender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Filter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Layout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LayoutAppender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Level.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogSeparator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LoggerStream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LoggingEvent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSThreads.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NDC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OstreamAppender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PThreads.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PatternLayout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PortabilityImpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RollingFileAppender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringUtil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeStamp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlLayout.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/src/Appender.cpp0000644023471100065110000000515213034744761016221 00000000000000// // Appender.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . // #include "PortabilityImpl.hh" #include namespace log4tango { Appender::Appender (const std::string& name) : _name(name) #if APPENDERS_HAVE_LEVEL_THRESHOLD ,_level(Level::DEBUG) #endif #if APPENDERS_HAVE_FILTERS ,_filter(0) #endif { //no-op } Appender::~Appender() { #if APPENDERS_HAVE_FILTERS if (_filter) { delete _filter; } #endif } bool Appender::is_valid (void) const { return true; } bool Appender::reopen (void) { return true; } #if defined(APPENDERS_HAVE_LEVEL_THRESHOLD) || defined(APPENDERS_HAVE_FILTERS) int Appender::append (const LoggingEvent& event) { # if APPENDERS_HAVE_LEVEL_THRESHOLD if (event.level <= _level) { # endif # if APPENDERS_HAVE_FILTERS if (!_filter || (_filter->decide(event) != Filter::DENY)) { # endif return _append(event); # if APPENDERS_HAVE_FILTERS } # endif # if APPENDERS_HAVE_LEVEL_THRESHOLD } # endif return 0; } #endif // APPENDERS_HAVE_LEVEL_THRESHOLD || APPENDERS_HAVE_FILTERS #if APPENDERS_HAVE_LEVEL_THRESHOLD void Appender::set_level (Level::Value level) { _level = level; } Level::Value Appender::get_level (void) const { return _level; } #endif // APPENDERS_HAVE_LEVEL_THRESHOLD #if APPENDERS_HAVE_FILTERS void Appender::set_filter (Filter* filter) { if (_filter != filter) { if (_filter) { delete _filter; } _filter = filter; } } Filter* Appender::get_filter (void) { return _filter; } #endif // APPENDERS_HAVE_FILTERS void Appender::level_changed (Level::Value new_level) { //--noop } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/AppenderAttachable.cpp0000644023471100065110000000577513034744761020205 00000000000000// // AppenderAttachable.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . // #include "PortabilityImpl.hh" #include namespace log4tango { typedef AppenderMap::value_type AppenderMapValue; AppenderAttachable::AppenderAttachable () { // no-op ctor. } AppenderAttachable::~AppenderAttachable () { remove_all_appenders(); } void AppenderAttachable::add_appender (Appender* appender) { if (appender) { threading::ScopedLock guard(_appendersMutex); AppenderMapValue pair(appender->get_name(), appender); _appenders.insert(pair); } } AppenderList AppenderAttachable::get_all_appenders (void) { threading::ScopedLock guard(_appendersMutex); AppenderList al(0); AppenderMapIterator it = _appenders.begin(); AppenderMapIterator end = _appenders.end(); for (; it != end ; ++it) { al.push_back(it->second); } return al; } Appender* AppenderAttachable::get_appender (const std::string& name) { threading::ScopedLock guard(_appendersMutex); Appender* appender = 0; AppenderMapIterator it = _appenders.find(name); if (it != _appenders.end()) { return it->second; } return 0; } bool AppenderAttachable::is_attached (Appender* appender) { threading::ScopedLock guard(_appendersMutex); if (appender && _appenders.find(appender->get_name()) != _appenders.end()) { return true; } return false; } void AppenderAttachable::remove_all_appenders (void) { threading::ScopedLock guard(_appendersMutex); AppenderMapIterator it = _appenders.begin(); AppenderMapIterator end = _appenders.end(); for (; it != end ; ++it) { delete it->second; } _appenders.clear(); } void AppenderAttachable::remove_appender(Appender* appender) { if (appender) { remove_appender(appender->get_name()); } } void AppenderAttachable::remove_appender(const std::string& name) { threading::ScopedLock guard(_appendersMutex); AppenderMapIterator it = _appenders.find(name); if (it != _appenders.end()) { delete it->second; _appenders.erase(it); } } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/LayoutAppender.cpp0000644023471100065110000000332313034744761017415 00000000000000// // LayoutAppender.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010.2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include namespace log4tango { LayoutAppender::LayoutAppender(const std::string& name) : Appender(name), _layout(new DefaultLayoutType()) { // no-op } LayoutAppender::~LayoutAppender() { if (_layout) { delete _layout; _layout = 0; } } bool LayoutAppender::requires_layout (void) const { return true; } void LayoutAppender::set_layout (Layout* layout) { if (layout != _layout) { if (_layout) { delete _layout; _layout = 0; } _layout = (layout == 0) ? new DefaultLayoutType() : layout; } } Layout& LayoutAppender::get_layout (void) { return *_layout; } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/FileAppender.cpp0000644023471100065110000000555413034744761017027 00000000000000// // FileAppender.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . // #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_IO_H # include #endif #ifdef LOG4TANGO_HAVE_UNISTD_H # include #endif #include #include namespace log4tango { FileAppender::FileAppender(const std::string& name, const std::string& file_name, bool append, mode_t mode) : LayoutAppender(name), _file_name(file_name), _flags(O_CREAT | O_APPEND | O_WRONLY), _mode(mode) { if (!append) { _flags |= O_TRUNC; } _fd = ::open(_file_name.c_str(), _flags, _mode); } FileAppender::FileAppender (const std::string& name, int fd) : LayoutAppender(name), _file_name(""), _fd(fd), _flags(O_CREAT | O_APPEND | O_WRONLY), _mode(00644) { //no-op } FileAppender::~FileAppender() { close(); } void FileAppender::close (void) { if (_fd != -1) { ::close(_fd); _fd = -1; } } bool FileAppender::is_valid (void) const { return (_fd < 0) ? false : true; } void FileAppender::set_append (bool append) { if (append) { _flags &= ~O_TRUNC; } else { _flags |= O_TRUNC; } } bool FileAppender::get_append (void) const { return (_flags & O_TRUNC) == 0; } void FileAppender::set_mode (mode_t mode) { _mode = mode; } mode_t FileAppender::get_mode (void) const { return _mode; } int FileAppender::_append (const LoggingEvent& event) { std::string message(get_layout().format(event)); if (!::write(_fd, message.data(), message.length())) { return -1; } return 0; } bool FileAppender::reopen (void) { if (_file_name != "") { int fd = ::open(_file_name.c_str(), _flags, _mode); if (fd < 0) { return false; } else { if (_fd != -1) { ::close(_fd); } _fd = fd; } } return true; } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/RollingFileAppender.cpp0000644023471100065110000000665313034744761020357 00000000000000// // RollingFileAppender.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_IO_H # include #endif #ifdef LOG4TANGO_HAVE_UNISTD_H # include #endif #include #include #include #include #include #ifdef LOG4TANGO_HAVE_SSTREAM #include #endif namespace log4tango { RollingFileAppender::RollingFileAppender(const std::string& name, const std::string& file_name, size_t max_fs, unsigned int max_bi, bool append, mode_t mode) : FileAppender(name, file_name, append, mode), _max_backup_index(max_bi), _max_file_size(max_fs) { } void RollingFileAppender::set_max_backup_index (unsigned int max_bi) { _max_backup_index = max_bi; } unsigned int RollingFileAppender::get_max_backup_index() const { return _max_backup_index; } void RollingFileAppender::set_maximum_file_size (size_t max_fs) { _max_file_size = max_fs; } size_t RollingFileAppender::get_max_file_size() const { return _max_file_size; } void RollingFileAppender::roll_over() { ::close(_fd); if (_max_backup_index > 0) { std::ostringstream old_name; old_name << _file_name << "." << _max_backup_index << std::ends; ::remove(old_name.str().c_str()); size_t n = _file_name.length() + 1; for(unsigned int i = _max_backup_index; i > 1; i--) { std::string newName = old_name.str(); old_name.seekp(n, std::ios::beg); old_name << i-1 << std::ends; ::rename(old_name.str().c_str(), newName.c_str()); } ::rename(_file_name.c_str(), old_name.str().c_str()); } _fd = ::open(_file_name.c_str(), _flags, _mode); } int RollingFileAppender::_append(const LoggingEvent& event) { FileAppender::_append(event); off_t offset = ::lseek(_fd, 0, SEEK_END); if (offset < 0) { return -1; } else { if(static_cast(offset) >= _max_file_size) { roll_over(); } } return 0; } } tango-9.2.5a/lib/cpp/log4tango/src/OstreamAppender.cpp0000644023471100065110000000350413034744761017553 00000000000000// // OstreamAppender.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_UNISTD_H # include #endif #include #include #include #include namespace log4tango { OstreamAppender::OstreamAppender(const std::string& name, std::ostream* stream) : LayoutAppender(name), _stream(stream) { } OstreamAppender::~OstreamAppender() { close(); } void OstreamAppender::close() { // empty } int OstreamAppender::_append (const LoggingEvent& event) { (*_stream) << get_layout().format(event); (*_stream) << std::endl; if (!_stream->good()) { return -1; } return 0; } bool OstreamAppender::reopen() { return true; } } tango-9.2.5a/lib/cpp/log4tango/src/Layout.cpp0000644023471100065110000000336413034744761015743 00000000000000// // Layout.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_SSTREAM # include #endif #include #include namespace log4tango { std::string Layout::format (const LoggingEvent& event) { const char sep = ' '; std::ostringstream message; message << event.timestamp.get_seconds() << sep << "[" << event.thread_id << "]" << sep << Level::get_name(event.level) << sep << event.logger_name << sep #ifdef LOG4TANGO_HAS_NDC << event.ndc << sep #endif << event.message << std::ends; return message.str(); } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/PatternLayout.cpp0000644023471100065110000003256713034744761017310 00000000000000// // PatternLayout.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include #include #include #include #ifdef LOG4TANGO_HAVE_SSTREAM # include #else # include #endif #include #include #include #ifdef LOG4TANGO_HAVE_INT64_T # ifdef LOG4TANGO_HAVE_STDINT_H # include # endif // LOG4TANGO_HAVE_STDINT_H # ifdef LOG4TANGO_MISSING_INT64_OSTREAM_OP // workaround suggested at: // http://support.microsoft.com/default.aspx?scid=kb;EN-US;q168440 #include std::ostream& operator<<(std::ostream& os, int64_t i) { char buf[20]; ::sprintf(buf,"%I64d", i); return os << buf; } # endif // LOG4TANGO_MISSING_INT64_OSTREAM_OP #endif // LOG4TANGO_HAVE_INT64_T namespace log4tango { struct StringLiteralComponent : public PatternLayout::PatternComponent { StringLiteralComponent(const std::string& literal) : _literal(literal) { //no-op } virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << _literal; } private: std::string _literal; }; struct LoggerNameComponent : public PatternLayout::PatternComponent { LoggerNameComponent(std::string specifier) { if (specifier == "") { _precision = -1; } else { #ifdef LOG4TANGO_HAVE_SSTREAM std::istringstream s(specifier); #else std::istrstream s(specifier.c_str()); #endif s >> _precision; } } virtual void append(std::ostringstream& out, const LoggingEvent& event) { if (_precision == -1) { out << event.logger_name; } else { std::string::size_type begin = std::string::npos; for(int i = 0; i < _precision; i++) { begin = event.logger_name.rfind('.', begin - 2); if (begin == std::string::npos) { begin = 0; break; } begin++; } out << event.logger_name.substr(begin); } } private: int _precision; }; struct MessageComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << event.message; } }; #ifdef LOG4TANGO_HAS_NDC struct NDCComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << event.ndc; } }; #endif struct LevelComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << Level::get_name(event.level); } }; struct ThreadNameComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << event.thread_name; } }; struct ThreadIdComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << event.thread_id; } }; struct ProcessorTimeComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << ::clock(); } }; struct TimeStampComponent : public PatternLayout::PatternComponent { static const char* const FORMAT_ISO8601; static const char* const FORMAT_ABSOLUTE; static const char* const FORMAT_DATE; TimeStampComponent(std::string timeFormat) { if ((timeFormat == "") || (timeFormat == "ISO8601")) { timeFormat = FORMAT_ISO8601; } else if (timeFormat == "ABSOLUTE") { timeFormat = FORMAT_ABSOLUTE; } else if (timeFormat == "DATE") { timeFormat = FORMAT_DATE; } std::string::size_type pos = timeFormat.find("%l"); if (pos == std::string::npos) { _printMillis = false; _timeFormat1 = timeFormat; } else { _printMillis = true; _timeFormat1 = timeFormat.substr(0, pos); _timeFormat2 = timeFormat.substr(pos + 2); } } virtual void append(std::ostringstream& out, const LoggingEvent& event) { struct tm *currentTime; time_t t = event.timestamp.get_seconds(); currentTime = std::localtime(&t); char formatted[100]; std::string timeFormat; if (_printMillis) { std::ostringstream formatStream; formatStream << _timeFormat1 << std::setw(3) << std::setfill('0') << event.timestamp.get_milliseconds() << _timeFormat2; timeFormat = formatStream.str(); } else { timeFormat = _timeFormat1; } std::strftime(formatted, sizeof(formatted), timeFormat.c_str(), currentTime); out << formatted; } private: std::string _timeFormat1; std::string _timeFormat2; bool _printMillis; }; const char* const TimeStampComponent::FORMAT_ISO8601 = "%Y-%m-%d %H:%M:%S,%l"; const char* const TimeStampComponent::FORMAT_ABSOLUTE = "%H:%M:%S,%l"; const char* const TimeStampComponent::FORMAT_DATE = "%d %b %Y %H:%M:%S,%l"; struct SecondsSinceEpochComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { out << event.timestamp.get_seconds(); } }; struct MillisSinceEpochComponent : public PatternLayout::PatternComponent { virtual void append(std::ostringstream& out, const LoggingEvent& event) { #ifdef LOG4TANGO_HAVE_INT64_T int64_t t = event.timestamp.get_seconds() - TimeStamp::get_start_time().get_seconds(); t *= 1000; t += event.timestamp.get_milliseconds() - TimeStamp::get_start_time().get_milliseconds(); out << t; #else double t = event.timestamp.get_seconds() - TimeStamp::get_start_time().get_seconds(); t *= 1000; t += event.timestamp.get_milliseconds() - TimeStamp::get_start_time().get_milliseconds(); out << std::setiosflags(std::ios::fixed) << std::setprecision(0) << t; #endif } }; struct FormatModifierComponent : public PatternLayout::PatternComponent { FormatModifierComponent(PatternLayout::PatternComponent* component, int minWidth, int maxWidth) : _component(component) , _minWidth(minWidth < 0 ? -minWidth : minWidth), _maxWidth(maxWidth), _alignLeft(minWidth < 0) { } virtual ~FormatModifierComponent() { delete _component; } virtual void append(std::ostringstream& out, const LoggingEvent& event) { std::ostringstream s; _component->append(s, event); std::string msg = s.str(); if (_maxWidth > 0) { msg.erase(_maxWidth); } int fillCount = _minWidth - msg.length(); if (fillCount > 0) { if (_alignLeft) { out << msg << std::string(fillCount, ' '); } else { out << std::string(fillCount, ' ') << msg; } } else { out << msg; } } private: PatternLayout::PatternComponent* _component; int _minWidth; int _maxWidth; bool _alignLeft; }; #ifdef LOG4TANGO_HAS_NDC const char* PatternLayout::BASIC_CONVERSION_PATTERN = "%R %p %c %x: %m%n"; #else const char* PatternLayout::BASIC_CONVERSION_PATTERN = "%R %p %c %m%n"; #endif PatternLayout::PatternLayout() { set_conversion_pattern(BASIC_CONVERSION_PATTERN); } PatternLayout::~PatternLayout() { clear_conversion_pattern(); } void PatternLayout::clear_conversion_pattern() { for(ComponentVector::const_iterator i = _components.begin(); i != _components.end(); ++i) { delete (*i); } _components.clear(); _conversionPattern = ""; } int PatternLayout::set_conversion_pattern (const std::string& conversionPattern) { #ifdef LOG4TANGO_HAVE_SSTREAM std::istringstream conversionStream(conversionPattern); #else std::istrstream conversionStream(conversionPattern.c_str()); #endif std::string literal; char ch; PatternLayout::PatternComponent* component = NULL; int minWidth = 0; int maxWidth = 0; clear_conversion_pattern(); while (conversionStream.get(ch)) { if (ch == '%') { // readPrefix; { char ch2; conversionStream.get(ch2); if ((ch2 == '-') || ((ch2 >= '0') && (ch2 <= '9'))) { conversionStream.putback(ch2); conversionStream >> minWidth; conversionStream.get(ch2); } if (ch2 == '.') { conversionStream >> maxWidth; } else { conversionStream.putback(ch2); } } if (!conversionStream.get(ch)) { return -1; } std::string specPostfix = ""; // read postfix { char ch2; if (conversionStream.get(ch2)) { if (ch2 == '{') { while(conversionStream.get(ch2) && (ch2 != '}')) specPostfix += ch2; } else { conversionStream.putback(ch2); } } } switch (ch) { case '%': literal += ch; break; case 'm': component = new MessageComponent(); break; case 'n': { std::ostringstream endline; endline << std::endl; literal += endline.str(); } break; case 'c': component = new LoggerNameComponent(specPostfix); break; case 'd': component = new TimeStampComponent(specPostfix); break; case 'p': component = new LevelComponent(); break; case 't': component = new ThreadIdComponent(); break; case 'T': component = new ThreadNameComponent(); break; case 'r': component = new MillisSinceEpochComponent(); break; case 'R': component = new SecondsSinceEpochComponent(); break; case 'u': component = new ProcessorTimeComponent(); break; #ifdef LOG4TANGO_HAS_NDC case 'x': component = new NDCComponent(); break; #endif default: return -1; } if (component) { if (!literal.empty()) { _components.push_back(new StringLiteralComponent(literal)); literal = ""; } if ((minWidth != 0) || (maxWidth != 0)) { component = new FormatModifierComponent(component, minWidth, maxWidth); minWidth = maxWidth = 0; } _components.push_back(component); component = NULL; } } else { literal += ch; } } if (!literal.empty()) { _components.push_back(new StringLiteralComponent(literal)); } _conversionPattern = conversionPattern; return 0; } std::string PatternLayout::get_conversion_pattern() const { return _conversionPattern; } std::string PatternLayout::format(const LoggingEvent& event) { std::ostringstream message; for(ComponentVector::const_iterator i = _components.begin(); i != _components.end(); ++i) { (*i)->append(message, event); } return message.str(); } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/XmlLayout.cpp0000644023471100065110000000720313034744761016420 00000000000000// // XMLLayout.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include #include #include #include namespace log4tango { XMLLayout::XMLLayout() { // no-op } XMLLayout::~XMLLayout() { // no-op } std::string XMLLayout::format (const LoggingEvent& event) { std::string buf; buf.append("\r\n"); buf.append("\r\n"); buf.append("\r\n"); buf.append("\r\n\r\n"); return buf; } /* * Ensures that embeded CDEnd strings (]]>) are handled properly * within message, NDC and throwable tag text. * * @param buf StringBuffer holding the XML data to this point. The * initial CDStart () of the CDATA * section are the responsibility of the calling method. * @param str The String that is inserted into an existing CDATA Section within buf. */ void XMLLayout::appendEscapingCDATA(std::string buf, std::string str) { const std::string CDATA_START(""); const std::string CDATA_PSEUDO_END("]]>"); const std::string CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START; const int CDATA_END_LEN = CDATA_END.size(); std::string::size_type end = str.find(CDATA_END); if (end == std::string::npos) { buf.append(str); return; } unsigned int start = 0; while (end != std::string::npos) { buf.append(str.substr(start, end - start)); buf.append(CDATA_EMBEDED_END); start = end + CDATA_END_LEN; if (start < str.size()) { end = str.find(CDATA_END, start); } else { return; } } buf.append(str.substr(start)); } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/Logger.cpp0000644023471100065110000001307513034744761015705 00000000000000// // Logger.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_UNISTD_H # include #endif #include #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM # include #endif #ifdef LOG4TANGO_HAS_NDC # include #endif #include "StringUtil.hh" namespace log4tango { Logger::Logger(const std::string& name, Level::Value level) : _name(name), _level(level) { #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM LogStreamBuf* stream_buf; stream_buf = new LogStreamBuf(this, Level::DEBUG); _log_streams[_DEBUG_STREAM_ID] = new LogStream(stream_buf); stream_buf = new LogStreamBuf(this, Level::INFO); _log_streams[_INFO_STREAM_ID] = new LogStream(stream_buf); stream_buf = new LogStreamBuf(this, Level::WARN); _log_streams[_WARN_STREAM_ID] = new LogStream(stream_buf); stream_buf = new LogStreamBuf(this, Level::ERROR); _log_streams[_ERROR_STREAM_ID] = new LogStream(stream_buf); stream_buf = new LogStreamBuf(this, Level::FATAL); _log_streams[_FATAL_STREAM_ID] = new LogStream(stream_buf); #else //no-op #endif // LOG4TANGO_LOGGERS_USE_LOGSTREAM } Logger::~Logger() { #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM for (int i = _FATAL_STREAM_ID; i <= _DEBUG_STREAM_ID; i++) { if (_log_streams[i]) delete _log_streams[i]; _log_streams[i] = 0; } #endif } void Logger::set_level (Level::Value level) { if ((level >= Level::OFF) && (level <= Level::DEBUG)) { _level = level; { //-- Begin critical section ----------------------------- threading::ScopedLock guard(_appendersMutex); if (!_appenders.empty()) { AppenderMapIterator i = _appenders.begin(); AppenderMapIterator e = _appenders.end(); for (; i != e ; ++i) { i->second->level_changed(_level); } } } //-- End critical section ------------------------------ } } void Logger::call_appenders (const LoggingEvent& event) { std::vector *bad_appenders = 0; { //-- Begin critical section ----------------------------- threading::ScopedLock guard(_appendersMutex); if (!_appenders.empty()) { AppenderMapIterator i = _appenders.begin(); AppenderMapIterator e = _appenders.end(); for (; i != e ; ++i) { if (i->second->append(event) == -1) { if (!bad_appenders) { bad_appenders = new std::vector; } if (bad_appenders) { bad_appenders->push_back(i->second->get_name()); } } } } } //-- End critical section ------------------------------ if (bad_appenders) { for (unsigned int a = 0; a < bad_appenders->size(); a++) { remove_appender((*bad_appenders)[a]); } delete bad_appenders; } } void Logger::log_unconditionally(Level::Value level, const char* format, ...) { va_list va; va_start(va, format); log_unconditionally(level, StringUtil::vform(format, va)); va_end(va); } void Logger::log_unconditionally(Level::Value level, const std::string& message) { #ifdef LOG4TANGO_HAS_NDC LoggingEvent event(get_name(), message, NDC::get(), level); #else LoggingEvent event(get_name(), message, level); #endif call_appenders(event); } void Logger::log (Level::Value level, const char* format, ...) { if (is_level_enabled(level)) { va_list va; va_start(va, format); log_unconditionally(level, StringUtil::vform(format, va)); va_end(va); } } void Logger::debug (const char* format, ...) { if (is_level_enabled(Level::DEBUG)) { va_list va; va_start(va,format); log_unconditionally(Level::DEBUG, StringUtil::vform(format, va)); va_end(va); } } void Logger::info (const char* format, ...) { if (is_level_enabled(Level::INFO)) { va_list va; va_start(va,format); log_unconditionally(Level::INFO, StringUtil::vform(format, va)); va_end(va); } } void Logger::warn (const char* format, ...) { if (is_level_enabled(Level::WARN)) { va_list va; va_start(va,format); log_unconditionally(Level::WARN, StringUtil::vform(format, va)); va_end(va); } } void Logger::error (const char* format, ...) { if (is_level_enabled(Level::ERROR)) { va_list va; va_start(va,format); log_unconditionally(Level::ERROR, StringUtil::vform(format, va)); va_end(va); } } void Logger::fatal (const char* format, ...) { if (is_level_enabled(Level::FATAL)) { va_list va; va_start(va,format); log_unconditionally(Level::FATAL, StringUtil::vform(format, va)); va_end(va); } } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/LogSeparator.cpp0000644023471100065110000000230213034744761017057 00000000000000// // LogSeparator.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include namespace log4tango { LogInitiator LogInitiator::_begin_log; LogSeparator LogSeparator::_end_log; } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/LoggerStream.cpp0000644023471100065110000000370413034744761017057 00000000000000// // LoggerStream.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifdef LOG4TANGO_HAVE_UNISTD_H # include #endif #include #include namespace log4tango { LoggerStream::LoggerStream (Logger& logger, Level::Value level, bool filter) : _logger(logger), _level(level), _filter(filter), _buffer(new std::ostringstream) { } LoggerStream::~LoggerStream() { flush(); #ifdef LOG4TANGO_HAVE_SSTREAM if (_buffer) { delete _buffer; _buffer = 0; } #endif } void LoggerStream::flush (void) { #ifdef LOG4TANGO_HAVE_SSTREAM if (_buffer && _buffer->tellp() > 0) #else if (_buffer && _buffer->pcount()) #endif { if (_filter) { _logger.log(_level, _buffer->str()); } else { _logger.log_unconditionally(_level, _buffer->str()); } #ifdef LOG4TANGO_HAVE_SSTREAM _buffer->str(""); #else delete _buffer; _buffer = 0; #endif } } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/LoggingEvent.cpp0000644023471100065110000000362613034744761017057 00000000000000// // LoggingEvent.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include #include namespace log4tango { LoggingEvent::LoggingEvent (const std::string& _logger_name, const std::string& _message, #ifdef LOG4TANGO_HAS_NDC const std::string& _ndc, #endif Level::Value _level) : logger_name(_logger_name), message(_message), #ifdef LOG4TANGO_HAS_NDC ndc(_ndc), #endif level(_level) { //-- thread_name = threading::get_thread_id(); thread_id = threading::thread_id(); } LoggingEvent::LoggingEvent (const LoggingEvent& _src) : logger_name(_src.logger_name), message(_src.message), #ifdef LOG4TANGO_HAS_NDC ndc(_src.ndc), #endif level(_src.level), thread_id(_src.thread_id), timestamp(_src.timestamp) { //--noop } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/Level.cpp0000644023471100065110000000564413034744761015540 00000000000000// // Level.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include #include namespace log4tango { #define NUM_LEVELS 7 #define kMAX_LEVEL DEBUG /*static const std::string names[NUM_LEVELS] = { std::string("OFF"), std::string("FATAL"), std::string("ERROR"), std::string("WARN"), std::string("INFO"), std::string("DEBUG"), std::string("UNKNOWN") };*/ //----------------------------------------------------------------- // // WARNING // ------- // // With gcc and Solaris, the above static array is not initialised !!! // That's why it is copied within the two methods get_name and // get_value. It is an horible hack but it works.... // //------------------------------------------------------------------ const std::string& Level::get_name (Value level) { static const std::string names[NUM_LEVELS] = { std::string("OFF"), std::string("FATAL"), std::string("ERROR"), std::string("WARN"), std::string("INFO"), std::string("DEBUG"), std::string("UNKNOWN") }; level /= 100; level--; int max = NUM_LEVELS - 1; return names[((level < 0) || (level > max)) ? max : level]; } Level::Value Level::get_value(const std::string& level_name) throw(std::invalid_argument) { static const std::string names[NUM_LEVELS] = { std::string("OFF"), std::string("FATAL"), std::string("ERROR"), std::string("WARN"), std::string("INFO"), std::string("DEBUG"), std::string("UNKNOWN") }; Level::Value value = -1; for (unsigned int i = 0; i < NUM_LEVELS; i++) { if (level_name == names[i]) { value = i * 100; break; } } if (value == -1) { char* end_pointer; value = std::strtoul(level_name.c_str(), &end_pointer, 10); if (*end_pointer != 0) { throw std::invalid_argument(std::string("unknown level name: '") + level_name + "'"); } } return value; } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/NDC.cpp0000644023471100065110000000623513034744761015072 00000000000000// // NDC.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifdef LOG4TANGO_HAS_NDC #include "PortabilityImpl.hh" #include #include namespace log4tango { NDC::DiagnosticContext::DiagnosticContext (const std::string& message) : message(message), full_msg(message) { //no-op } NDC::DiagnosticContext::DiagnosticContext (const std::string& message, const DiagnosticContext& parent) : message(message), full_msg(parent.full_msg + " " + message) { //no-op } namespace { threading::ThreadLocalDataHolder _nDC; } void NDC::clear() { get_ndc()._clear(); } NDC::ContextStack* NDC::clone_stack() { return get_ndc()._clone_stack(); } const std::string& NDC::get (void) { return get_ndc()._get(); } int NDC::get_depth (void) { return get_ndc()._get_depth(); } void NDC::inherit (NDC::ContextStack* stack) { get_ndc()._inherit(stack); } std::string NDC::pop (void) { return get_ndc()._pop(); } void NDC::push (const std::string& message) { get_ndc()._push(message); } void NDC::set_max_depth(int max_depth) { get_ndc()._set_max_depth(max_depth); } NDC& NDC::get_ndc (void) { NDC* nDC = _nDC.get(); if (!nDC) { nDC = new NDC(); _nDC.reset(nDC); } return *nDC; } NDC::NDC () { //no-op } NDC::~NDC () { //no-op } void NDC::_clear (void) { _stack.clear(); } NDC::ContextStack* NDC::_clone_stack (void) { return new ContextStack(_stack); } const std::string& NDC::_get (void) const { static std::string empty = ""; return (_stack.empty() ? empty : _stack.back().full_msg); } int NDC::_get_depth (void) const { return _stack.size(); } void NDC::_inherit (NDC::ContextStack* stack) { _stack = *stack; } std::string NDC::_pop (void) { std::string result = _stack.back().message; _stack.pop_back(); return result; } void NDC::_push (const std::string& message) { if (_stack.empty()) { _stack.push_back(DiagnosticContext(message)); } else { _stack.push_back(DiagnosticContext(message, _stack.back())); } } void NDC::_set_max_depth (int max_depth) { // no maximum } } // namespace log4tango #endif // LOG4TANGO_HAS_NDC tango-9.2.5a/lib/cpp/log4tango/src/Filter.cpp0000644023471100065110000000376713034744761015722 00000000000000// // Filter.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifdef APPENDERS_HAVE_FILTERS #include "PortabilityImpl.hh" #include namespace log4tango { Filter::Filter() : _chain(0) { //no-op } Filter::~Filter() { if (_chain) { delete _chain; _chain = 0; } } void Filter::set_chained_filter (Filter* filter) { if (filter != _chain) { if (_chain) { delete _chain; } _chain = filter; } } Filter* Filter::get_end_of_chain (void) { Filter* end = this; while(end->get_chained_filter()) { end = end->get_chained_filter(); } return end; } void Filter::append_chained_filter (Filter* filter) { Filter* end = get_end_of_chain(); end->set_chained_filter(filter); } Filter::Decision Filter::decide (const LoggingEvent& event) { Filter::Decision decision = _decide(event); if ((Filter::NEUTRAL == decision) && get_chained_filter()) { decision = get_chained_filter()->decide(event); } return decision; } } // namespace log4tango #endif // APPENDERS_HAVE_FILTERS tango-9.2.5a/lib/cpp/log4tango/src/TimeStamp.cpp0000644023471100065110000000330413034744761016363 00000000000000// // TimeStamp.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #include #ifdef LOG4TANGO_HAVE_GETTIMEOFDAY # include #else # ifdef LOG4TANGO_HAVE_FTIME # include # else # include # endif #endif namespace log4tango { TimeStamp TimeStamp::_start_stamp; TimeStamp::TimeStamp() { #ifdef LOG4TANGO_HAVE_GETTIMEOFDAY struct timeval tv; ::gettimeofday(&tv, NULL); _seconds = tv.tv_sec; _micro_seconds = tv.tv_usec; #else # ifdef LOG4TANGO_HAVE_FTIME struct timeb tb; ::ftime(&tb); _seconds = tb.time; _micro_seconds = 1000 * tb.millitm; # else _seconds = ::time(NULL); _micro_seconds = 0; # endif #endif } } // namespace log4tango tango-9.2.5a/lib/cpp/log4tango/src/StringUtil.hh0000644023471100065110000000674513034744761016415 00000000000000// // StringUtil.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_STRINGUTIL_H #define _LOG4TANGO_STRINGUTIL_H #include "PortabilityImpl.hh" #include #include #include #include namespace log4tango { class StringUtil { public: /** Returns a string contructed from the a format specifier and a va_list of arguments, analogously to vprintf(3). @param format the format specifier. @param args the va_list of arguments. **/ static std::string vform(const char* format, va_list args); /** Returns a string identical to the given string but without leading or trailing HTABs or spaces. **/ static std::string trim(const std::string& s); /** splits a string into a vector of string segments based on the given delimiter. @param v The vector in which the segments will be stored. The vector will be emptied before storing the segments @param s The string to split into segments. @param delimiter The delimiter character @param maxSegments the maximum number of segments. Upon return v.size() <= maxSegments. The string is scanned from left to right so v[maxSegments - 1] may contain a string containing the delimiter character. @return The actual number of segments (limited by maxSegments). **/ static unsigned int split(std::vector& v, const std::string& s, char delimiter, unsigned int maxSegments = INT_MAX); /** splits a string into string segments based on the given delimiter and assigns the segments through an output_iterator. @param output The output_iterator through which to assign the string segments. Typically this will be a back_insertion_iterator. @param s The string to split into segments. @param delimiter The delimiter character @param maxSegments The maximum number of segments. @return The actual number of segments (limited by maxSegments). **/ template static unsigned int split(T& output, const std::string& s, char delimiter, unsigned int maxSegments = INT_MAX) { std::string::size_type left = 0; unsigned int i; for (i = 1; i < maxSegments; i++) { std::string::size_type right = s.find(delimiter, left); if (right == std::string::npos) { break; } *output++ = s.substr(left, right - left); left = right + 1; } *output++ = s.substr(left); return i; } }; } // namespace log4tango #endif // _LOG4TANGO_STRINGUTIL_HH tango-9.2.5a/lib/cpp/log4tango/src/StringUtil.cpp0000644023471100065110000000571013034744761016567 00000000000000// // StringUtil.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "StringUtil.hh" #include #include #if defined(_MSC_VER) #define VSNPRINTF _vsnprintf #else #ifdef LOG4TANGO_HAVE_SNPRINTF #define VSNPRINTF vsnprintf #else /* use alternative snprintf() from http://www.ijs.si/software/snprintf/ */ #define HAVE_SNPRINTF #define PREFER_PORTABLE_SNPRINTF #include #include extern "C" { #include "snprintf.c" } #define VSNPRINTF portable_vsnprintf #endif // LOG4TANGO_HAVE_SNPRINTF #endif // _MSC_VER namespace log4tango { std::string StringUtil::vform(const char* format, va_list args) { size_t size = 1024; char* buffer = new char[size]; while (1) { int n = VSNPRINTF(buffer, size, format, args); // If that worked, return a string. if ((n > -1) && (static_cast(n) < size)) { std::string s(buffer); delete [] buffer; return s; } // Else try again with more space. size = (n > -1) ? n + 1 : // ISO/IEC 9899:1999 size * 2; // twice the old size delete [] buffer; buffer = new char[size]; } } std::string StringUtil::trim(const std::string& s) { // test for null string if(s.empty()) return s; // find first non-space character std::string::size_type b = s.find_first_not_of(" \t"); if(b == std::string::npos) // No non-spaces return ""; // find last non-space character std::string::size_type e = s.find_last_not_of(" \t"); // return the remaining characters return std::string(s, b, e - b + 1); } unsigned int StringUtil::split(std::vector& v, const std::string& s, char delimiter, unsigned int maxSegments) { v.clear(); std::back_insert_iterator > it(v); return split(it, s, delimiter, maxSegments); } } tango-9.2.5a/lib/cpp/log4tango/src/DllMain.cpp0000644023471100065110000000304013034744761015775 00000000000000// // DllMain.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . // #ifdef LOG4TANGO_SUPPLY_DLLMAIN #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #endif // LOG4TANGO_SUPPLY_DLLMAIN tango-9.2.5a/lib/cpp/log4tango/src/DummyThreads.cpp0000644023471100065110000000247313034744761017074 00000000000000// // DummyThreads.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . // #include #ifndef LOG4TANGO_HAVE_THREADING namespace log4tango { namespace threading { std::string get_thread_id (void) { return std::string("unknown"); } } // namespace threading } // namespace log4tango #endif // LOG4TANGO_HAVE_THREADING tango-9.2.5a/lib/cpp/log4tango/src/MSThreads.cpp0000644023471100065110000000357313034744761016322 00000000000000// // MSThreads.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #if defined(LOG4TANGO_HAVE_THREADING) && defined(LOG4TANGO_USE_MSTHREADS) namespace log4tango { namespace threading { //+---------------------------------------------------------------------------- // method : get_thread_id //----------------------------------------------------------------------------- std::string get_thread_id (void) { char buffer[16]; sprintf(buffer, "%lu", ::GetCurrentThreadId()); return std::string(buffer); } //+---------------------------------------------------------------------------- // method : thread_id //----------------------------------------------------------------------------- long thread_id (void) { return static_cast(::GetCurrentThreadId()); } } // namespace threading } // namespace log4tango #endif // LOG4TANGO_HAVE_THREADING && LOG4TANGO_USE_MSTHREADS tango-9.2.5a/lib/cpp/log4tango/src/PThreads.cpp0000644023471100065110000001334313034744761016176 00000000000000// // PThreads.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #include #ifdef LOG4TANGO_HAVE_SSTREAM # include #endif #if defined(LOG4TANGO_HAVE_THREADING) && defined(LOG4TANGO_USE_PTHREADS) namespace log4tango { namespace threading { //+---------------------------------------------------------------------------- // method : get_thread_id //----------------------------------------------------------------------------- std::string get_thread_id (void) { std::ostringstream oss; oss << ::pthread_self(); return oss.str(); } //+---------------------------------------------------------------------------- // method : thread_id //----------------------------------------------------------------------------- long thread_id (void) { #ifndef __darwin__ #ifndef __freebsd__ return static_cast(::pthread_self()); #else return reinterpret_cast(::pthread_self()); #endif #else pthread_t thread = ::pthread_self(); return thread->__sig; #endif } //+---------------------------------------------------------------------------- // method : RecursiveMutex::RecursiveMutex //----------------------------------------------------------------------------- RecursiveMutex::RecursiveMutex (void) : recursion_level_(0), owner_id_(0) { ::pthread_mutex_init(&guard_, NULL); #if (PthreadDraftVersion == 4) ::pthread_cond_init(&mutex_available_, pthread_condattr_default); #else ::pthread_cond_init(&mutex_available_, 0); #endif } //+---------------------------------------------------------------------------- // method : RecursiveMutex::~RecursiveMutex //----------------------------------------------------------------------------- RecursiveMutex::~RecursiveMutex (void) { ::pthread_cond_destroy(&mutex_available_); ::pthread_mutex_destroy(&guard_); } //+---------------------------------------------------------------------------- // method : RecursiveMutex::lock //----------------------------------------------------------------------------- int RecursiveMutex::lock (long timeout) { // Get current thread id pthread_t t_id = ::pthread_self(); // Lock the guard ::pthread_mutex_lock(&guard_); // Is recursive_mutex free? if (recursion_level_ == 0) { // Yes it is, get ownership owner_id_ = t_id; } else if (t_id != owner_id_) { // No it isn't and is not the current owner. // Wait until the nesting level has dropped to zero, // at which point we can get ownership while (recursion_level_ > 0) { // Note: is unlocked by following call if (timeout) { //--TODO::a la omnithread timedwait impl (see Duncan's code) ::pthread_cond_wait(&mutex_available_, &guard_); } else { ::pthread_cond_wait(&mutex_available_, &guard_); } } // At this point the is held and // recursive_mutex free. Get ownership ... owner_id_ = t_id; } // At this point, we can safely increment the recursion // level no matter how we got here! recursion_level_++; // Unlock the guard ::pthread_mutex_unlock(&guard_); // Return true (success - no timeout on wait) return 1; } //+---------------------------------------------------------------------------- // method : RecursiveMutex::unlock //----------------------------------------------------------------------------- void RecursiveMutex::unlock(void) { // Get current thread id pthread_t t_id = ::pthread_self(); // Lock the guard ::pthread_mutex_lock(&guard_); // must be the current owner if (recursion_level_ == 0 || (t_id != owner_id_)) { ::pthread_mutex_unlock(&guard_); return; } // Decrement the recursion level recursion_level_--; // Is recursive_mutex free now? if (recursion_level_ == 0) { // Release ownership owner_id_ = 0; // Inform a waiter ::pthread_cond_signal(&mutex_available_); } // Unlock the guard ::pthread_mutex_unlock(&guard_); } //+---------------------------------------------------------------------------- // method : RecursiveMutex::unlockn //----------------------------------------------------------------------------- void RecursiveMutex::unlockn (void) { // Get current thread id pthread_t t_id = ::pthread_self(); // Lock the guard ::pthread_mutex_lock(&guard_); // must be the current owner if (recursion_level_ == 0 || (t_id != owner_id_)) { ::pthread_mutex_unlock(&guard_); return; } // Reset the recursion level recursion_level_ = 0; // Release ownership owner_id_ = 0; // Inform a waiter ::pthread_cond_signal(&mutex_available_); // Unlock the guard ::pthread_mutex_unlock(&guard_); } } // namespace threading } // namespace log4tango #endif // LOG4TANGO_HAVE_THREADING && LOG4TANGO_USE_PTHREADS tango-9.2.5a/lib/cpp/log4tango/src/PortabilityImpl.hh0000644023471100065110000000427713034744761017433 00000000000000// // PortabilityImpl.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_PORTABILITYIMPL_H #define _LOG4TANGO_PORTABILITYIMPL_H #include #ifdef LOG4TANGO_CSTDLIB_NOT_IN_STD #include namespace std { static inline char *getenv(const char *name) { return ::getenv(name); }; static inline int atoi(const char *nptr) { return ::atoi(nptr); }; static inline unsigned long int strtoul(const char *nptr, char **endptr, int base) { return ::strtol(nptr, endptr, base); }; } #endif #ifdef LOG4TANGO_CSTRING_NOT_IN_STD #include namespace std { static inline void *memmove(void *dest, const void *src, size_t n) { return ::memmove(dest, src, n); }; } #endif #ifdef LOG4TANGO_CTIME_NOT_IN_STD #include namespace std { static inline size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr ) { return ::strftime(strDest,maxsize,format,timeptr); } static inline struct tm *localtime( const time_t *timer ) { return ::localtime(timer); } } #endif #ifdef LOG4TANGO_CMATH_NOT_IN_STD #include namespace std { static inline int abs(int i) { return ::abs(i); } } #endif #endif // _LOG4TANGO_PORTABILITYIMPL_H tango-9.2.5a/lib/cpp/log4tango/src/PortabilityImpl.cpp0000644023471100065110000000267013034744761017611 00000000000000// // PortabilityImpl.cpp // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include "PortabilityImpl.hh" #ifndef LOG4TANGO_HAVE_SSTREAM namespace std { std::string ostringstream::str() { (*this) << '\0'; std::string msg(ostrstream::str()); ostrstream::freeze(false); //unfreeze stream return msg; } void ostringstream::str (const char* s) { //TODO -> release current content, set content to s } } #endif // LOG4TANGO_HAVE_SSTREAM tango-9.2.5a/lib/cpp/log4tango/include/0000755023471100065110000000000013034745256014670 500000000000000tango-9.2.5a/lib/cpp/log4tango/include/Makefile.am0000644023471100065110000000002413034744760016637 00000000000000SUBDIRS = log4tango tango-9.2.5a/lib/cpp/log4tango/include/Makefile.in0000644023471100065110000004366113034744760016666 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = log4tango all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu include/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status include/config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/include/config.h.in0000644023471100065110000000446413034744760016642 00000000000000/* include/config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* define if the compiler has int64_t */ #undef HAVE_INT64_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_IO_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* define if the compiler implements namespaces */ #undef HAVE_NAMESPACES /* define if the C library has snprintf */ #undef HAVE_SNPRINTF /* define if the compiler has stringstream */ #undef HAVE_SSTREAM /* define if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* define if threading is enabled */ #undef HAVE_THREADING /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* define if pthread library is available */ #undef USE_PTHREADS /* Version number of package */ #undef VERSION /* If we're running on darwin/MacOsX */ #undef __darwin__ /* If we're running on FreeBSD */ #undef __freebsd__ tango-9.2.5a/lib/cpp/log4tango/include/log4tango/0000755023471100065110000000000013034745256016566 500000000000000tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Appender.hh0000644023471100065110000001150213034744760020563 00000000000000// // Appender.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #include #include #include #include #include #include #include #ifndef _LOG4TANGO_APPENDER_H #define _LOG4TANGO_APPENDER_H namespace log4tango { //----------------------------------------------------------------------------- // class : Appender //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Appender { friend class Logger; protected: /** * Constructor for Appender. Will only be used in * getAppender() (and in derived classes of course). * @param name The name of this Appender. **/ Appender (const std::string& name); /** * Inform an appender that its Logger's logging level has changed. * The default implementation does nothing. * * @param new_level The new Logger's level. **/ virtual void level_changed (Level::Value new_level); public: /** * Destructor for Appender. **/ virtual ~Appender (); /** * Log in Appender specific way. Returns -1 on error, 0 otherwise. * @param event The LoggingEvent to log. **/ #if defined(APPENDERS_HAVE_LEVEL_THRESHOLD) || defined(APPENDERS_HAVE_FILTERS) int append (const LoggingEvent& event); #else inline int append (const LoggingEvent& event) { return _append(event); } #endif /** * Reopens the output destination of this Appender, e.g. the logfile * or TCP socket. * @returns false if an error occured during reopening, true otherwise. **/ virtual bool reopen (void); /** * Release any resources allocated within the appender such as file * handles, network connections, etc. **/ virtual void close (void) = 0; /** * Check if the appender uses a layout. * * @returns true if the appender implementation requires a layout. **/ virtual bool requires_layout (void) const = 0; /** * Change the layout. **/ virtual void set_layout (Layout* layout = 0) = 0; /** * Returns this appender name. **/ inline const std::string& get_name (void) const { return _name; } /** * Check if the appender is valid (for instance the underlying connection is ok) * This default implementation always return true. Overload to define your own * behaviour. * * @returns true if the appender is valid, false otherwise. **/ virtual bool is_valid (void) const; #ifdef APPENDERS_HAVE_LEVEL_THRESHOLD /** * Set the threshold level of this Appender. The Appender will not * appender LoggingEvents with a level lower than the threshold. * Use Level::NOTSET to disable level checking. * @param level The level to set. **/ void set_level (Level::Value level); /** * Get the threshold level of this Appender. * @returns the threshold **/ Level::Value get_level (void) const; #endif // APPENDERS_HAVE_LEVEL_THRESHOLD #ifdef APPENDERS_HAVE_FILTERS /** * Set a Filter for this appender. **/ virtual void set_filter (Filter* filter); /** * Get the Filter for this appender. * @returns the filter, or NULL if no filter has been set. **/ virtual Filter* get_filter (void); #endif // APPENDERS_HAVE_FILTERS protected: /** * Log in Appender specific way. Subclasses of Appender should * implement this method to perform actual logging. * @param event The LoggingEvent to log. **/ virtual int _append(const LoggingEvent& event) = 0; private: /** * The appender name **/ const std::string _name; #ifdef APPENDERS_HAVE_LEVEL_THRESHOLD /** * The appender logging level **/ Level::Value _level; #endif #ifdef APPENDERS_HAVE_FILTERS /** * The appender filter list **/ Filter* _filter; #endif }; } // namespace log4tango #endif // _LOG4TANGO_APPENDER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/AppenderAttachable.hh0000644023471100065110000000716013034744760022541 00000000000000// // AppenderAttachable.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_APPENDER_ATTACHABLE_H #define _LOG4TANGO_APPENDER_ATTACHABLE_H #include #include #include #include #include namespace log4tango { /** * A map of appenders **/ typedef std::map AppenderMap; /** * A map of appenders iterator **/ typedef AppenderMap::iterator AppenderMapIterator; /** * Define what is a list of appenders **/ typedef std::vector AppenderList; //----------------------------------------------------------------------------- // class : AppenderAttachable //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT AppenderAttachable { public: /** * Constructor. **/ AppenderAttachable (); /** * Destructor. **/ virtual ~AppenderAttachable (); /** * Adds an Appender. Does nothing if the appender is NULL * or already attached. **/ void add_appender (Appender* appender); /** * Get all previously added appenders as a vector. * The caller must call "release" on each Appender in * the returned list when it is no longer needed (the * Appender class is ref-counted). **/ AppenderList get_all_appenders (void); /** * Get an appender by name. * The caller must call "release" on the returned Appender * when it is no longer needed (the Appender class is * ref-counted). Returns 0 if there is no Appender named * "name" currently attached. **/ Appender* get_appender (const std::string& name); /** * Returns true if the specified appender is in list of * attached appanders, false otherwise. **/ bool is_attached (Appender* appender); /** * Removes all appenders for this Logger. **/ void remove_all_appenders(); /** * Remove the appender passed as parameter from the list of appenders. **/ void remove_appender(Appender* appender); /** * Remove the appender with the name passed as parameter from the * list of appenders. **/ void remove_appender(const std::string& name); protected: /** * Appenders repository. **/ AppenderMap _appenders; /** * A mutex to protect the repository against race conditions. **/ threading::Mutex _appendersMutex; AppenderAttachable (const AppenderAttachable& other); AppenderAttachable& operator=(const AppenderAttachable& other); }; } // namespace log4tango #endif // _LOG4TANGO_APPENDER_ATTACHABLE_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LayoutAppender.hh0000644023471100065110000000356613034744760021774 00000000000000// // LayoutAppender.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LAYOUTAPPENDER_H #define _LOG4TANGO_LAYOUTAPPENDER_H #include #include #include #include namespace log4tango { //----------------------------------------------------------------------------- // class : LayoutAppender (superclass for appenders that require a Layout) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT LayoutAppender : public Appender { public: typedef Layout DefaultLayoutType; LayoutAppender(const std::string& name); virtual ~LayoutAppender(); virtual bool requires_layout() const; virtual void set_layout (Layout* layout = 0); protected: Layout& get_layout(); private: Layout* _layout; }; } // namespace log4tango #endif // _LOG4TANGO_LAYOUTAPPENDER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/FileAppender.hh0000644023471100065110000000676313034744760021400 00000000000000// // FileAppender.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_FILEAPPENDER_H #define _LOG4TANGO_FILEAPPENDER_H #include #include namespace log4tango { //----------------------------------------------------------------------------- // class : FileAppender //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT FileAppender : public LayoutAppender { public: /** Constructs a FileAppender. @param name the name of the Appender. @param fileName the name of the file to which the Appender has to log. @param append whether the Appender has to truncate the file or just append to it if it already exists. Defaults to 'true'. @param mode file mode to open the logfile with. Defaults to 00644. **/ FileAppender(const std::string& name, const std::string& fileName, bool append = true, mode_t mode = 00644); /** Constructs a FileAppender to an already open file descriptor. @param name the name of the Appender. @param fd the file descriptor to which the Appender has to log. **/ FileAppender(const std::string& name, int fd); /** Destructor **/ virtual ~FileAppender(); /** Reopens the logfile. This can be useful for logfiles that are rotated externally, e.g. by logrotate. This method is a NOOP for FileAppenders that have been constructed with a file descriptor. @returns true if the reopen succeeded. **/ virtual bool reopen (void); /** Closes the logfile. **/ virtual void close (void); /** * Check if the appender is valid. * * @returns true if the appender is valid, false otherwise. **/ virtual bool is_valid (void) const; /** Sets the append vs truncate flag. NB. currently the FileAppender opens the logfile in the constructor. Therefore this method is too late to influence the first file opening. We'll need something similar to log4j's activateOptions(). @param append false to truncate, true to append **/ virtual void set_append (bool append); /** Gets the value of the 'append' option. **/ virtual bool get_append (void) const; /** Sets the file open mode. **/ virtual void set_mode (mode_t mode); /** Gets the file open mode. **/ virtual mode_t get_mode() const; protected: virtual int _append (const LoggingEvent& event); const std::string _file_name; int _fd; int _flags; mode_t _mode; }; } // namespace log4tango #endif // _LOG4TANGO_FILEAPPENDER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/RollingFileAppender.hh0000644023471100065110000000435413034744760022721 00000000000000// // RollingFileAppender.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_ROLLINGFILEAPPENDER_H #define _LOG4TANGO_ROLLINGFILEAPPENDER_H #include #include namespace log4tango { //----------------------------------------------------------------------------- // class RollingFileAppender (olls over the logfile) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT RollingFileAppender : public FileAppender { public: RollingFileAppender(const std::string& name, const std::string& file_name, size_t max_fs = 10*1024*1024, unsigned int max_bi = 1, bool append = true, mode_t mode = 00644); virtual void set_max_backup_index(unsigned int maxBackups); virtual unsigned int get_max_backup_index() const; virtual void set_maximum_file_size (size_t max_fs); virtual size_t get_max_file_size() const; virtual void roll_over(); protected: virtual int _append (const LoggingEvent& event); unsigned int _max_backup_index; size_t _max_file_size; }; } // namespace log4tango #endif // _LOG4TANGO_ROLLINGFILEAPPENDER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/OstreamAppender.hh0000644023471100065110000000351313034744760022121 00000000000000// // OstreamAppender.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_OSTREAMAPPENDER_H #define _LOG4TANGO_OSTREAMAPPENDER_H #include #include #include #include namespace log4tango { //----------------------------------------------------------------------------- // class : OstreamAppender (appends LoggingEvents to ostreams) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT OstreamAppender : public LayoutAppender { public: OstreamAppender(const std::string& name, std::ostream* stream); virtual ~OstreamAppender(); virtual bool reopen(); virtual void close(); protected: virtual int _append (const LoggingEvent& event); std::ostream* _stream; }; } // namespace log4tango #endif // _LOG4TANGO_OSTREAMAPPENDER_HH tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Layout.hh0000644023471100065110000000365313034744760020312 00000000000000// // Layout.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LAYOUT_H #define _LOG4TANGO_LAYOUT_H #include #include #include #include namespace log4tango { //----------------------------------------------------------------------------- // class : Appender (abstract class) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Layout { public: /** * Constructor for Layout. **/ Layout() {}; /** * Destructor for Layout. **/ virtual ~Layout() {}; /** * Formats the LoggingEvent data to a string that appenders can log. * Overload this method to create your own layout format. * @param event The LoggingEvent. * @returns an appendable string. **/ virtual std::string format (const LoggingEvent& event); }; } // namespace log4tango #endif // _LOG4TANGO_LAYOUT_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/PatternLayout.hh0000644023471100065110000000767113034744760021654 00000000000000// // PatternLayout.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_PATTERNLAYOUT_H #define _LOG4TANGO_PATTERNLAYOUT_H #include #include #include #ifdef LOG4TANGO_HAVE_SSTREAM # include #endif namespace log4tango { //----------------------------------------------------------------------------- // class : PatternLayout (a simple fixed format Layout implementation) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT PatternLayout : public Layout { public: /** A conversion pattern equivalent to the BasicLayout. **/ static const char* BASIC_CONVERSION_PATTERN; PatternLayout(); virtual ~PatternLayout(); // NOTE: // All double percentage signs ('%%') followed by a character // in the following comments should actually be a single char. // The doubles are included so that doxygen will print them correctly. /** * Formats the LoggingEvent in the style set by * the set_conversion_pattern call. By default, set * to "%%m%%n" **/ virtual std::string format(const LoggingEvent& event); /** * Sets the format of log lines handled by this * PatternLayout. By default, set to "%%m%%n".
* Format characters are as follows:
*
    *
  • %%%% - a single percent sign
  • *
  • %%c - the logger
  • *
  • %%d - the date\n * Date format: The date format character may be followed by a date format * specifier enclosed between braces. For example, %%d{%%H:%%M:%%S,%%l} or %%d{%%d %%m %%Y %%H:%%M:%%S,%%l}. * If no date format specifier is given then the following format is used: * "Wed Jan 02 02:03:55 1980". The date format specifier admits the same syntax * as the ANSI C function strftime, with 1 addition. The addition is the specifier * %%l for milliseconds, padded with zeros to make 3 digits.
  • *
  • %%m - the message
  • *
  • %%n - the platform specific line separator
  • *
  • %%p - the level
  • *
  • %%r - milliseconds since this layout was created.
  • *
  • %%R - seconds since Jan 1, 1970
  • *
  • %%u - clock ticks since process start
  • *
  • %%x - the NDC
  • *
* @param conversionPattern the conversion pattern * @exception ConfigureFailure if the pattern is invalid **/ virtual int set_conversion_pattern (const std::string& conversionPattern); virtual std::string get_conversion_pattern() const; virtual void clear_conversion_pattern(); class LOG4TANGO_EXPORT PatternComponent { public: inline virtual ~PatternComponent() {}; virtual void append(std::ostringstream& out, const LoggingEvent& event) = 0; }; private: typedef std::vector ComponentVector; ComponentVector _components; std::string _conversionPattern; }; } // namespace log4tango #endif // _LOG4TANGO_PATTERNLAYOUT_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/XmlLayout.hh0000644023471100065110000000332113034744760020763 00000000000000// // XMLLayout.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_XML_LAYOUT_H #define _LOG4TANGO_XML_LAYOUT_H #include #include namespace log4tango { /** * XMLLayout is a simple fixed format Layout implementation. **/ class LOG4TANGO_EXPORT XMLLayout : public Layout { public: /** * Ctor. **/ XMLLayout (); /** * Dtor. **/ virtual ~XMLLayout (); /** * Formats the LoggingEvent in XML **/ virtual std::string format (const LoggingEvent& event); private: /** * Ensures that embeded CDEnd strings (]]>) are handled properly **/ void appendEscapingCDATA(std::string buf, std::string str); }; } // namespace log4tango #endif // _LOG4TANGO_XML_LAYOUT_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Logger.hh0000644023471100065110000002552413034744760020255 00000000000000// // Logger.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LOGGER_H #define _LOG4TANGO_LOGGER_H //----------------------------------------------------------------------------- // IMPL. OPTION //----------------------------------------------------------------------------- //#define LOG4TANGO_LOGGERS_USE_LOGSTREAM #include #include #include #include #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM # include #endif namespace log4tango { #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM //----------------------------------------------------------------------------- // FORWARD DECL. //----------------------------------------------------------------------------- class LogStream; #endif //----------------------------------------------------------------------------- // class : Logger //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Logger : public AppenderAttachable { public: /** * Constructor * @param name the fully qualified name of this Logger * @param level the level for this Logger. Defaults to Level::OFF **/ Logger(const std::string& name, Level::Value level = Level::OFF); /** * Destructor **/ virtual ~Logger(); /** * Return the logger name. * @returns The logger name. */ inline const std::string& get_name() const { return _name; } /** * Set the level of this Logger (silently ignores invalid values) * @param level The level to set. **/ void set_level (Level::Value level); /** * Returns the assigned Level, if any, for this Logger. * @return Level - the assigned Level, can be Level::NOTSET **/ inline Level::Value get_level() const { return _level; } /** * Returns true if the level of the Logger is equal to * or higher than given level. * @param level The level to compare with. * @returns whether logging is enable for this level. **/ bool is_level_enabled (Level::Value level) const { return _level >= level; } /** * Log a message with the specified level. * @param level The level of this log message. * @param string_format Format specifier for the log . * @param ... The arguments for string_format **/ void log (Level::Value level, const char* string_format, ...); /** * Log a message with the specified level. * @param level The level of this log message. * @param message string to write in the log file **/ inline void log (Level::Value level, const std::string& message) { if (is_level_enabled(level)) { log_unconditionally(level, message); } } /** * Log a message with the specified level without level checking. * @param level The level of this log message. * @param string_format Format specifier for the log . * @param ... The arguments for string_format **/ void log_unconditionally (Level::Value level, const char* string_format, ...); /** * Log a message with the specified level without level checking. * @param level The level of this log message. * @param message string to write in the log file **/ void log_unconditionally (Level::Value level, const std::string& message); /** * Log a message with debug level. * @param string_format Format specifier for the log. * @param ... The arguments for string_format **/ void debug (const char* string_format, ...); /** * Log a message with debug level. * @param message string to write in the log file **/ inline void debug (const std::string& message) { if (is_level_enabled(Level::DEBUG)) { log_unconditionally(Level::DEBUG, message); } } /** * Return true if the Logger will log messages with level DEBUG. * @returns Whether the Logger will log. **/ inline bool is_debug_enabled (void) const { return is_level_enabled (Level::DEBUG); }; #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with level DEBUG. * @returns The LoggerStream. **/ inline LoggerStream debug_stream (void) { return LoggerStream(*this, Level::DEBUG, true); } #else /** * Return the DEBUG LogStream. * @returns The DEBUG LogStream. **/ inline LogStream& debug_stream (void) { return *_log_streams[_DEBUG_STREAM_ID]; } #endif /** * Log a message with info level. * @param string_format Format specifier for the log. * @param ... The arguments for string_format **/ void info (const char* string_format, ...); /** * Log a message with info level. * @param message string to write in the log file **/ inline void info (const std::string& message) { if (is_level_enabled(Level::INFO)) { log_unconditionally(Level::INFO, message); } } /** * Return true if the Logger will log messages with level INFO. * @returns Whether the Logger will log. **/ inline bool is_info_enabled (void) const { return is_level_enabled(Level::INFO); }; #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with level INFO. * @returns The LoggerStream. **/ inline LoggerStream info_stream (void) { return LoggerStream(*this, Level::INFO, true); } #else /** * Return the INFO LogStream. * @returns The INFO LogStream. **/ inline LogStream& info_stream (void) { return *_log_streams[_INFO_STREAM_ID]; } #endif /** * Log a message with warn level. * @param string_format Format specifier for the log. * @param ... The arguments for string_format **/ void warn (const char* string_format, ...); /** * Log a message with warn level. * @param message string to write in the log file **/ inline void warn (const std::string& message) { if (is_level_enabled(Level::WARN)) { log_unconditionally(Level::WARN, message); } } /** * Return true if the Logger will log messages with level WARN. * @returns Whether the Logger will log. **/ inline bool is_warn_enabled (void) const { return is_level_enabled(Level::WARN); }; #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with level WARN. * @returns The LoggerStream. **/ inline LoggerStream warn_stream (void) { return LoggerStream(*this, Level::WARN, true); }; #else /** * Return the WARN LogStream. * @returns The WARN LogStream. **/ inline LogStream& warn_stream (void) { return *_log_streams[_WARN_STREAM_ID]; } #endif /** * Log a message with error level. * @param string_format Format specifier for the log. * @param ... The arguments for string_format **/ void error (const char* string_format, ...); /** * Log a message with error level. * @param message string to write in the log file **/ inline void error (const std::string& message) { if (is_level_enabled(Level::ERROR)) { log_unconditionally(Level::ERROR, message); } } /** * Return true if the Logger will log messages with level ERROR. * @returns Whether the Logger will log. **/ inline bool is_error_enabled (void) const { return is_level_enabled(Level::ERROR); }; #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with level ERROR. * @returns The LoggerStream. **/ inline LoggerStream error_stream (void) { return LoggerStream(*this, Level::ERROR, true); }; #else /** * Return the ERROR LogStream. * @returns The ERROR LogStream. **/ inline LogStream& error_stream (void) { return *_log_streams[_ERROR_STREAM_ID]; } #endif /** * Log a message with fatal level. * @param string_format Format specifier for the log. * @param ... The arguments for string_format **/ void fatal(const char* string_format, ...); /** * Log a message with fatal level. * @param message string to write in the log file **/ inline void fatal (const std::string& message) { if (is_level_enabled(Level::FATAL)) { log_unconditionally(Level::FATAL, message); } } /** * Return true if the Logger will log messages with level FATAL. * @returns Whether the Logger will log. **/ inline bool is_fatal_enabled (void) const { return is_level_enabled(Level::FATAL); }; #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with level FATAL. * @returns The LoggerStream. **/ inline LoggerStream fatal_stream (void) { return LoggerStream(*this, Level::FATAL, true); }; #else /** * Return the FATAL LogStream. * @returns The FATAL LogStream. **/ inline LogStream& fatal_stream (void) { return *_log_streams[_FATAL_STREAM_ID]; } #endif #ifndef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** * Return a LoggerStream with given Level. * @param level The Level of the LoggerStream. * @param filter The filter flag * @returns The requested LoggerStream. **/ inline LoggerStream get_stream (Level::Value level, bool filter = true) { return LoggerStream(*this, level, filter); } #endif protected: /** * Call the appenders. * * @param event the LogginEvent to log. **/ void call_appenders (const LoggingEvent& event); private: #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** Stream ids. */ enum { _FATAL_STREAM_ID = 0, _ERROR_STREAM_ID = 1, _WARN_STREAM_ID = 2, _INFO_STREAM_ID = 3, _DEBUG_STREAM_ID = 4 }; #endif /** The name of this logger. */ const std::string _name; /** The assigned level of this logger. */ Level::Value _level; #ifdef LOG4TANGO_LOGGERS_USE_LOGSTREAM /** The thread-safe streams of this logger. */ LogStream *_log_streams[5]; #endif /* prevent copying and assignment */ Logger (const Logger&); Logger& operator= (const Logger&); }; } // namespace log4tango #endif // _LOG4TANGO_LOGGER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LogSeparator.hh0000644023471100065110000000336013034744760021432 00000000000000// // LogSeparator.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LOG_SEPARATOR_H #define _LOG4TANGO_LOG_SEPARATOR_H #include namespace log4tango { //----------------------------------------------------------------------------- // Class : LogInitiator //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT LogInitiator { public: static LogInitiator _begin_log; }; //----------------------------------------------------------------------------- // Class : LogSeparator //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT LogSeparator { public: static LogSeparator _end_log; }; } // namespace log4tango #endif // _LOG4TANGO_LOG_SEPARATOR_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LoggerStream.hh0000644023471100065110000001222513034744760021423 00000000000000// // LoggerStream.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LOGGER_STREAM_H #define _LOG4TANGO_LOGGER_STREAM_H #include #include #ifdef LOG4TANGO_HAVE_SSTREAM # include #endif #include namespace log4tango { //----------------------------------------------------------------------------- // FORWARD DECLARATION //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Logger; class LoggerStream; //----------------------------------------------------------------------------- // DEFINE WHAT IS A LS_TERMINATOR //----------------------------------------------------------------------------- typedef LoggerStream& (*ls_terminator) (LoggerStream&); typedef class std::ios_base&(*StdIosFlag)(class std::ios_base&); //----------------------------------------------------------------------------- // class : LoggerStream //----------------------------------------------------------------------------- class LoggerStream { public: /** * Construct a LoggerStream for given Logger with given level. * @param logger The logger this stream will send log messages to. * @param level The level the log messages will get or * Level::NOTSET to silently discard any streamed in messages. * @param filter The filter flag **/ LOG4TANGO_EXPORT LoggerStream(Logger& logger, Level::Value level, bool filter = true); /** * Destructor for LoggerStream&) **/ LOG4TANGO_EXPORT ~LoggerStream(); /** * Returns the destination Logger for this stream. * @returns The Logger. **/ inline LOG4TANGO_EXPORT Logger& get_logger (void) const { return _logger; }; /** * Returns the level for this stream. * @returns The level. **/ inline LOG4TANGO_EXPORT Level::Value get_level (void) const { return _level; }; /** * Streams in a Initiator. Just a trick to return a ref to self. * @param i The log initiator * @returns A reference to itself. **/ inline LOG4TANGO_EXPORT LoggerStream& operator<< (LOG4TANGO_UNUSED(LogInitiator& i)) { return *this; } /** * Streams in a Separator.Sends the contents of the stream buffer * to the Logger with set level and empties the buffer. * @param s The log separator * @returns A reference to itself. **/ inline LOG4TANGO_EXPORT LoggerStream& operator<< (LOG4TANGO_UNUSED(LogSeparator& s)) { flush(); return *this; } /** * Streams in a ls_manipulator. Sends the contents of the stream buffer * to the Logger with set level and empties the buffer. * @param endoflog The log terminator * @returns A reference to itself. **/ inline LOG4TANGO_EXPORT LoggerStream& operator<< (LOG4TANGO_UNUSED(ls_terminator endoflog)) { flush(); return *this; } /** * Flush the contents of the stream buffer to the Logger and * empties the buffer. **/ LOG4TANGO_EXPORT void flush (void); /** * Streams in a std stream manipulator. * @param _F the manipulator function * @returns a reference to self. **/ #ifdef WIN32 inline LOG4TANGO_EXPORT LoggerStream& operator<< (std::ios_base&(_cdecl *_F)(std::ios_base&)) { #else inline LOG4TANGO_EXPORT LoggerStream& operator<< (std::ios_base&(*_F)(std::ios_base&)) { #endif #ifndef LOG4TANGO_HAVE_SSTREAM if (!_buffer) _buffer = new std::ostringstream; #endif if (_buffer) (*_F)(*(std::ios_base *)(_buffer)); return *this; } /** * Stream in arbitrary types and objects. * @param t The value or object to stream in. * @returns A reference to itself. **/ template LoggerStream& operator<< (const T& t) { if (_level != Level::OFF) { #ifndef LOG4TANGO_HAVE_SSTREAM if (!_buffer) _buffer = new std::ostringstream; #endif if (_buffer) (*_buffer) << t; } return *this; } private: Logger& _logger; Level::Value _level; bool _filter; std::ostringstream* _buffer; }; } // namespace log4tango namespace std { //-- A dummy inline log4tango::LoggerStream& endl (log4tango::LoggerStream& ls) { return ls; } } // namespace std #endif // _LOG4TANGO_LOGGER_STREAM_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LogStream.hh0000644023471100065110000000431513034744760020726 00000000000000// // LogStream.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LOG_STREAM_H #define _LOG4TANGO_LOG_STREAM_H #include #ifdef LOG4TANGO_HAVE_SSTREAM # include #else # include #endif #include #include #include namespace log4tango { //----------------------------------------------------------------------------- // Class : LogStream //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT LogStream { protected: threading::RecursiveMutex _rmutex; std::ostream _ostream; public: LogStream(LogStreamBuf* stream_buf); virtual ~LogStream(); inline LogStream& operator<< (const LogInitiator&) { return *this; } template LogStream& operator<< (const T& t) { _rmutex.lock(); _ostream << t; return *this; } inline LogStream& operator<< (LogSeparator&) { _rmutex.lock(); _ostream.flush(); _rmutex.unlockn(); return *this; } }; inline std::ostream& operator<< (std::ostream& o_str, LogSeparator&) { o_str.flush(); return o_str; } } // namespace log4tango #endif // _LOG4TANGO_LOG_STREAM_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LogStreambuf.hh0000644023471100065110000000420513034744760021421 00000000000000// // LogStreambuf.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_STREAM_BUFFER_H #define _LOG4TANGO_STREAM_BUFFER_H #include #include //----------------------------------------------------------------------------- // #DEFINES //----------------------------------------------------------------------------- #define kDEFAULT_BUFFER_SIZE 512 namespace log4tango { //----------------------------------------------------------------------------- // Class : LogStreamBuf //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT LogStreamBuf : public std::streambuf { friend class LogStream; public: LogStreamBuf (Logger* logger, Level::Value level, bool filter = true, size_t bsize = kDEFAULT_BUFFER_SIZE); virtual ~LogStreamBuf(); protected: virtual std::streamsize xsputn (const char*, std::streamsize); virtual int sync (void); private: int flush_buffer (void); char *_buffer; Logger* _logger; Level::Value _level; bool _filter; }; } // namespace log4tango #endif // _LOG4TANGO_STREAM_BUFFER_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/LoggingEvent.hh0000644023471100065110000000647613034744760021433 00000000000000// // LoggingEvent.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LOGGINGEVENT_H #define _LOG4TANGO_LOGGINGEVENT_H #include #include #include #include namespace log4tango { /** * The internal representation of logging events. When a affirmative * logging decision is made a LoggingEvent instance is * created. This instance is passed around the different log4tango * components. * *

This class is of concern to those wishing to extend log4tango. **/ //----------------------------------------------------------------------------- // struct : LoggingEvent //----------------------------------------------------------------------------- struct LOG4TANGO_EXPORT LoggingEvent { public: /** * Instantiate a LoggingEvent from the supplied parameters. * *

Except timeStamp all the other fields of * LoggingEvent are filled when actually needed. *

* @param logger The logger of this event. * @param message The message of this event. * @param level The level of this event. **/ #ifdef LOG4TANGO_HAS_NDC LoggingEvent(const std::string& logger, const std::string& message, const std::string& ndc, Level::Value level); #else LoggingEvent(const std::string& logger, const std::string& message, Level::Value level); #endif // LOG4TANGO_HAS_NDC /** Copy constructor */ LoggingEvent(const LoggingEvent& event); /** The logger name. */ const std::string logger_name; /** The application supplied message of logging event. */ const std::string message; #ifdef LOG4TANGO_HAS_NDC /** The nested diagnostic context (NDC) of logging event. */ const std::string ndc; #endif /** Level of logging event. */ Level::Value level; /** Name of thread in which this logging event was generated */ std::string thread_name; /** id of thread in which this logging event was generated */ long thread_id; /** The number of seconds elapsed since the epoch (1/1/1970 00:00:00 UTC) until logging event was created. */ TimeStamp timestamp; private: /** Prevent implicit copy */ const LoggingEvent& operator= (const LoggingEvent&); }; } // namespace log4tango #endif // _LOG4TANGO_LOGGINGEVENT_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Level.hh0000644023471100065110000000654713034744760020111 00000000000000// // Level.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_LEVEL_H #define _LOG4TANGO_LEVEL_H #include #include #include /* * Optionally work around rudeness in windows.h on Win32. */ #ifdef ERROR #ifdef LOG4TANGO_FIX_ERROR_COLLISION namespace log4tango { static const int _tmpERRORValue = ERROR; } #undef ERROR static const int ERROR = log4tango::_tmpERRORValue; #define ERROR ERROR #else // LOG4TANGO_FIX_ERROR_COLLISION #error Naming collision for 'ERROR' detected. Please read the FAQ for a \ workaround. #endif // LOG4TANGO_FIX_ERROR_COLLISION #endif // ERROR /* * Other Win32 rudeness in EDK.h */ #ifdef DEBUG #ifdef LOG4TANGO_FIX_ERROR_COLLISION #undef DEBUG #define DEBUG DEBUG #else // LOG4TANGO_FIX_ERROR_COLLISION #error Naming collision for 'DEBUG' detected. Please read the FAQ for a \ workaround. #endif // LOG4TANGO_FIX_ERROR_COLLISION #endif // DEBUG namespace log4tango { //----------------------------------------------------------------------------- // class : Level //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Level { public: /** * Levels of Priorities. **/ typedef enum { OFF = 100, FATAL = 200, ERROR = 300, WARN = 400, INFO = 500, DEBUG = 600 } LevelLevel; /** * The type of Level Values **/ typedef int Value; /** * Returns the name of the given level value. * Currently, if the value is not one of the LevelLevel values, * the method returns the name of the largest level smaller * the given value. * @param level the numeric value of the level. * @returns a string representing the name of the level. **/ static const std::string& get_name (Value level); /** * Returns the value of the given level name. * This can be either one of "OFF", "ERRROR", ... or a * decimal string representation of the value, e.g. '500' for DEBUG. * @param level_name the string containing the the of the level * @return the value corresponding with the level name * @throw std::invalid_argument if the level_name does not * correspond with a known Level name or a number **/ static Value get_value (const std::string& level_name) throw(std::invalid_argument); }; } // namespace log4tango #endif // _LOG4TANGO_LEVEL_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/NDC.hh0000644023471100065110000001436013034744760017436 00000000000000// // NDC.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_NDC_H #define _LOG4TANGO_NDC_H #ifdef LOG4TANGO_HAS_NDC #include #include #include namespace log4tango { /** The NDC class implements nested diagnostic contexts as defined by Neil Harrison in the article "Patterns for Logging Diagnostic Messages" part of the book "Pattern Languages of Program Design 3" edited by Martin et al.

A Nested Diagnostic Context, or NDC in short, is an instrument to distinguish interleaved log output from different sources. Log output is typically interleaved when a server handles multiple clients near-simulatanously.

Interleaved log output can still be meaningful if each log entry from different contexts had a distinctive stamp. This is where NDCs come into play.

Note that NDCs are managed on a per thread basis. NDC operations such as push, pop, clear, get_depth and set_max_depth affect the NDC of the current thread only. NDCs of other threads remain unaffected.

To build an NDC one uses the push operation. Simply put,

  • Contexts can be nested.

  • When entering a context, call NDC.push. As a side effect, if there is no nested diagnostic context for the current thread, this method will create it.

  • When leaving a context, call NDC.pop.

There is no penalty for forgetting to match each push operation with a corresponding pop, except the obvious mismatch between the real application context and the context set in the NDC.

Custom Layouts may include the nested diagnostic context for the current thread in log messages, without any user intervention. Hence, even if a server is serving multiple clients simultaneously, the logs emanating from the same code (belonging to the same logger) can still be distinguished because each client request will have a different NDC tag.

Unfortunately, unlike Java, C++ does not have platform independent multithreading support. Therefore, currently log4tango is not multithread aware, it implicitly assumes only one thread exists, the main process thread. **/ class LOG4TANGO_EXPORT NDC { public: struct DiagnosticContext { DiagnosticContext(const std::string& message); DiagnosticContext(const std::string& message, const DiagnosticContext& parent); std::string message; std::string full_msg; }; typedef std::vector ContextStack; /** Clear any nested disgnostic information if any. This method is useful in cases where the same thread can be potentially used over and over in different unrelated contexts.

This method is equivalent to calling the set_max_depth method with a zero max_depth argument. **/ static void clear (void); /** Clone the diagnostic context for the current thread.

Internally a diagnostic context is represented as a stack. A given thread can supply the stack (i.e. diagnostic context) to a child thread so that the child can inherit the parent thread's diagnostic context.

The child thread uses the inherit method to inherit the parent's diagnostic context. @return Stack A clone of the current thread's diagnostic context. **/ static ContextStack* clone_stack (void); /** Get the current diagnostic context string. @return the context string. **/ static const std::string& get (void); /** Get the current nesting depth of this diagnostic context. @return the nesting depth **/ static int get_depth (void); static void inherit (ContextStack* stack); /** Clients should call this method before leaving a diagnostic context.

The returned value is the value that was pushed last. If no context is available, then the empty string "" is returned. @return String The innermost diagnostic context. **/ static std::string pop (void); /** Push new diagnostic context information for the current thread.

The contents of the message parameter is determined solely by the client. @param message The new diagnostic context information. **/ static void push (const std::string& message); /** Set the maximum nesting depth for the current NDC. Curently NDCs do not enforce a maximum depth and consequentially this method has no effect. @param max_depth the maximum nesting depth **/ static void set_max_depth (int max_depth); /** Return the NDC for the current thread. @return the NDC for the current thread **/ static NDC& get_ndc(); NDC(); virtual ~NDC(); public: virtual void _clear (void); virtual ContextStack* _clone_stack (void); virtual const std::string& _get (void) const; virtual int _get_depth (void) const; virtual void _inherit (ContextStack* stack); virtual std::string _pop (void); virtual void _push (const std::string& message); virtual void _set_max_depth (int max_depth); ContextStack _stack; }; } // namespace log4tango #endif // LOG4TANGO_HAS_NDC #endif // _LOG4TANGO_NDC_HH tango-9.2.5a/lib/cpp/log4tango/include/log4tango/TimeStamp.hh0000644023471100065110000000577413034744760020746 00000000000000// // TimeStamp.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_TIMESTAMP_H #define _LOG4TANGO_TIMESTAMP_H #include namespace log4tango { //----------------------------------------------------------------------------- // Class : TimeStamp (timestamp abstraction) //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT TimeStamp { public: /** Constructs a TimeStamp representing 'now'. **/ TimeStamp(); /** Copy Constructor. **/ inline TimeStamp (const TimeStamp& t) : _seconds(t._seconds), _micro_seconds(t._micro_seconds) { //--noop }; /** Constructs a TimeStamp representing the given offset since the epoch ( 00:00:00 1970/1/1 UTC). **/ inline TimeStamp(unsigned int seconds, unsigned int microseconds = 0) : _seconds(seconds), _micro_seconds(microseconds) { //--noop }; /** Returns the 'seconds' part of the TimeStamp. **/ inline int get_seconds (void) const { return _seconds; }; /** Returns the 'subseconds' part of the TimeStamp in milliseconds, get_milliseconds() == get_microseconds() / 1000. **/ inline int get_milliseconds (void) const { return _micro_seconds / 1000; }; /** Returns the subsecond part of the TimeStamp in microseconds. The actual precision of this value depends on the platform and may be in the order of milliseconds rather than microseconds. **/ inline int get_microseconds (void) const { return _micro_seconds; }; /** Returns a TimeStamp representing the time at which the application started. **/ static inline const TimeStamp& get_start_time (void) { return _start_stamp; }; /** Operator= **/ inline void operator= (const TimeStamp& t) { _seconds = t._seconds; _micro_seconds = t._micro_seconds; }; protected: static TimeStamp _start_stamp; int _seconds; int _micro_seconds; }; } // namespace log4tango #endif // _LOG4TANGO_TIMESTAMP_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Filter.hh0000644023471100065110000001060713034744760020257 00000000000000// // Filter.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_FILTER_HH #define _LOG4TANGO_FILTER_HH #ifdef APPENDERS_HAVE_FILTERS #include #include namespace log4tango { /** Users should extend this class to implement customized logging event filtering. Note that {@link log4tango::Logger} and {@link log4tango::Appender} have built-in filtering rules. It is suggested that you first use and understand the built-in rules before rushing to write your own custom filters.

This abstract class assumes and also imposes that filters be organized in a linear chain. The decide(LoggingEvent) method of each filter is called sequentially, in the order of their addition to the chain.

The decide(LoggingEvent) method must return a Decision value, either DENY, NEUTRAL or ACCCEPT.

If the value DENY is returned, then the log event is dropped immediately without consulting with the remaining filters.

If the value NEUTRAL is returned, then the next filter in the chain is consulted. If there are no more filters in the chain, then the log event is logged. Thus, in the presence of no filters, the default behaviour is to log all logging events.

If the value ACCEPT is returned, then the log event is logged without consulting the remaining filters.

The philosophy of log4tango filters is largely inspired from the Linux ipchains. **/ //----------------------------------------------------------------------------- // class : Filter //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Filter { public: typedef enum { DENY = -1, NEUTRAL = 0, ACCEPT = 1 } Decision; /** * Default Constructor for Filter **/ Filter (); /** * Destructor for Filter **/ virtual ~Filter (); /** * Set the next Filter in the Filter chain * @param filter The filter to chain **/ void set_chained_filter (Filter* filter); /** * Get the next Filter in the Filter chain * @return The next Filter or NULL if the current filter * is the last in the chain **/ inline Filter* Filter::get_chained_filter (void) { return _chain; } /** * Get the last Filter in the Filter chain * @return The last Filter in the Filter chain **/ virtual Filter* get_end_of_chain (void); /** * Add a Filter to the end of the Filter chain. Convience method for * getEndOfChain()->set_chained_filter(filter). * @param filter The filter to add to the end of the chain. **/ virtual void append_chained_filter (Filter* filter); /** * Decide whether to accept or deny a LoggingEvent. This method will * walk the entire chain until a non neutral decision has been made * or the end of the chain has been reached. * @param event The LoggingEvent to decide on. * @return The Decision **/ virtual Decision decide (const LoggingEvent& event); protected: /** * Decide whether this Filter accepts or denies the given * LoggingEvent. Actual implementation of Filter should override this * method and not decide(LoggingEvent&). * @param event The LoggingEvent to decide on. * @return The Decision **/ virtual Decision _decide (const LoggingEvent& event) = 0; private: Filter* _chain; }; } // namespace log4tango #endif // APPENDERS_HAVE_FILTERS #endif // _LOG4TANGO_FILTER_HH tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Export.hh0000644023471100065110000000247113034744760020313 00000000000000// // Export.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_EXPORT_H #define _LOG4TANGO_EXPORT_H #ifdef LOG4TANGO_HAS_DLL # ifdef LOG4TANGO_BUILD_DLL # define LOG4TANGO_EXPORT __declspec(dllexport) # else # define LOG4TANGO_EXPORT __declspec(dllimport) # endif #else # define LOG4TANGO_EXPORT #endif #endif // _LOG4TANGO_EXPORT_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Portability.hh0000644023471100065110000000364113034744760021334 00000000000000// // Portability.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_PORTABILITY_H #define _LOG4TANGO_PORTABILITY_H #if defined (_MSC_VER) || defined(__BORLANDC__) # include #else # include #endif #include #if defined(_MSC_VER) # pragma warning( disable : 4786 ) // 255 char debug symbol limit # pragma warning( disable : 4290 ) // throw specifier not implemented # pragma warning( disable : 4251 ) // "class XXX should be exported" #define LOG4TANGO_UNUSED(var) var #else #ifdef __GNUC__ #define LOG4TANGO_UNUSED(var) var __attribute__ ((unused)) #else #define LOG4TANGO_UNUSED(var) var #endif #endif #ifndef LOG4TANGO_HAVE_SSTREAM #include namespace std { class LOG4TANGO_EXPORT ostringstream : public ostrstream { public: std::string str(); void str (const char*); }; } #endif // LOG4TANGO_HAVE_SSTREAM #endif // _LOG4TANGO_PORTABILITY_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/config-win32.h0000644023471100065110000000774613034744760021101 00000000000000// // config-win32.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _INCLUDE_LOG4TANGO_CONFIG_WIN32_H #define _INCLUDE_LOG4TANGO_CONFIG_WIN32_H 1 /* manually edited from include/log4tango/config.h */ /* Define if you have the syslog function. */ /* #undef LOG4TANGO_HAVE_SYSLOG */ /* Define if you have the `ftime' function. */ #ifndef LOG4TANGO_HAVE_FTIME # define LOG4TANGO_HAVE_FTIME 1 #endif /* Define if you have the `gettimeofday' function. */ /* #undef LOG4TANGO_HAVE_GETTIMEOFDAY */ /* define if the compiler has int64_t */ #ifndef LOG4TANGO_HAVE_INT64_T #define LOG4TANGO_HAVE_INT64_T //#define int64_t __int64 typedef __int64 int64_t; #if defined(_MSC_VER) && _MSC_VER < 1300 # define LOG4TANGO_MISSING_INT64_OSTREAM_OP #endif #endif /* Define if you have the header file. */ #ifndef LOG4TANGO_HAVE_IO_H # define LOG4TANGO_HAVE_IO_H 1 #endif /* Define if you have the header file. */ /* #undef LOG4TANGO_HAVE_UNISTD_H */ /* Define if you have the idsa library (-lidsa). */ /* #undef LOG4TANGO_HAVE_LIBIDSA */ /* Define if you have the `strcasecmp' function. */ /* #undef LOG4TANGO_HAVE_STRCASECMP */ /* Name of package */ #ifndef LOG4TANGO_PACKAGE # define LOG4TANGO_PACKAGE "log4tango" #endif /* Version number of package */ #ifndef LOG4TANGO_VERSION # define LOG4TANGO_VERSION "0.3.4" #endif /* define if the compiler implements namespaces */ #ifndef LOG4TANGO_HAVE_NAMESPACES # define LOG4TANGO_HAVE_NAMESPACES 1 #endif /* define if the compiler has stringstream */ #ifndef LOG4TANGO_HAVE_SSTREAM # define LOG4TANGO_HAVE_SSTREAM 1 #endif /* define if the C library has snprintf */ #ifndef LOG4TANGO_HAVE_SNPRINTF # define LOG4TANGO_HAVE_SNPRINTF 1 #endif /* define to get around problems with ERROR in windows.h */ #ifndef LOG4TANGO_FIX_ERROR_COLLISION # define LOG4TANGO_FIX_ERROR_COLLISION 1 #endif /* define WIN32 for Borland */ #ifndef WIN32 # define WIN32 #endif /* use threads */ #ifndef LOG4TANGO_HAVE_THREADING # define LOG4TANGO_HAVE_THREADING #endif /* use ms threads */ #ifndef LOG4TANGO_USE_MSTHREADS # define LOG4TANGO_USE_MSTHREADS #endif /* supply DLL main */ #ifndef LOG4TANGO_SUPPLY_DLLMAIN # define LOG4TANGO_SUPPLY_DLLMAIN #endif /* MSVCs and headers are broken in the sense that they put functions in the global namespace instead of std:: The #defines below enable a workaround for MSVC 6 and lower. If MSVC 7 is still broken please adjust the _MSC_VER version check and report it. See also bug report #628211. */ #if defined(_MSC_VER) && _MSC_VER < 1300 #ifndef LOG4TANGO_CSTDLIB_NOT_IN_STD # define LOG4TANGO_CSTDLIB_NOT_IN_STD #endif #ifndef LOG4TANGO_CSTRING_NOT_IN_STD # define LOG4TANGO_CSTRING_NOT_IN_STD #endif #ifndef LOG4TANGO_CTIME_NOT_IN_STD # define LOG4TANGO_CTIME_NOT_IN_STD #endif #ifndef LOG4TANGO_CMATH_NOT_IN_STD # define LOG4TANGO_CMATH_NOT_IN_STD #endif #endif /* define mode_t. Move to Portability.hh if more platforms need it */ namespace log4tango { typedef unsigned short mode_t; } /* _INCLUDE_LOG4TANGO_CONFIG_WIN32_H */ #endif tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Makefile.am0000644023471100065110000000110113034744760020532 00000000000000SUBDIRS = threading liblog4tangoincludedir = $(includedir)/tango/log4tango liblog4tangoinclude_HEADERS = \ Appender.hh \ AppenderAttachable.hh \ LayoutAppender.hh \ FileAppender.hh \ RollingFileAppender.hh \ OstreamAppender.hh \ Layout.hh \ PatternLayout.hh \ XmlLayout.hh \ Logger.hh \ LogSeparator.hh \ LoggerStream.hh \ LogStream.hh \ LogStreambuf.hh \ LoggingEvent.hh \ Level.hh \ NDC.hh \ TimeStamp.hh \ Filter.hh \ Export.hh \ Portability.hh \ config.h \ config-win32.h dist-hook: rm -f $(distdir)/config.h distclean-local: rm config.h tango-9.2.5a/lib/cpp/log4tango/include/log4tango/Makefile.in0000644023471100065110000005074213034744760020562 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include/log4tango DIST_COMMON = $(liblog4tangoinclude_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(liblog4tangoincludedir)" HEADERS = $(liblog4tangoinclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = threading liblog4tangoincludedir = $(includedir)/tango/log4tango liblog4tangoinclude_HEADERS = \ Appender.hh \ AppenderAttachable.hh \ LayoutAppender.hh \ FileAppender.hh \ RollingFileAppender.hh \ OstreamAppender.hh \ Layout.hh \ PatternLayout.hh \ XmlLayout.hh \ Logger.hh \ LogSeparator.hh \ LoggerStream.hh \ LogStream.hh \ LogStreambuf.hh \ LoggingEvent.hh \ Level.hh \ NDC.hh \ TimeStamp.hh \ Filter.hh \ Export.hh \ Portability.hh \ config.h \ config-win32.h all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/log4tango/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu include/log4tango/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-liblog4tangoincludeHEADERS: $(liblog4tangoinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(liblog4tangoincludedir)" || $(MKDIR_P) "$(DESTDIR)$(liblog4tangoincludedir)" @list='$(liblog4tangoinclude_HEADERS)'; test -n "$(liblog4tangoincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(liblog4tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(liblog4tangoincludedir)" || exit $$?; \ done uninstall-liblog4tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(liblog4tangoinclude_HEADERS)'; test -n "$(liblog4tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(liblog4tangoincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-recursive all-am: Makefile $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(liblog4tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-liblog4tangoincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-liblog4tangoincludeHEADERS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive dist-hook distclean distclean-generic \ distclean-libtool distclean-local distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am \ install-liblog4tangoincludeHEADERS install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-liblog4tangoincludeHEADERS dist-hook: rm -f $(distdir)/config.h distclean-local: rm config.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/0000755023471100065110000000000013034745256020533 500000000000000tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/DummyThreads.hh0000644023471100065110000000415213034744760023403 00000000000000// // DummyThreads.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_THREADING_DUMMY_THREADS_H #define _LOG4TANGO_THREADING_DUMMY_THREADS_H #include #include #include namespace log4tango { namespace threading { std::string get_thread_id (void); typedef int Mutex; typedef int ScopedLock; #ifdef LOG4TANGO_HAS_NDC template class ThreadLocalDataHolder { public: typedef T data_type; inline ThreadLocalDataHolder () : _data(0) { //no-op }; inline ~ThreadLocalDataHolder () { if (_data) { delete _data; } }; inline T* get (void) const { return _data; }; inline T* operator->() const { return get(); }; inline T& operator*() const { return *get(); }; inline T* release() { T* result = _data; _data = 0; return result; }; inline void reset (T* p = 0) { if (_data) { delete _data; } _data = p; }; private: T* _data; }; #endif // #ifdef LOG4TANGO_HAS_NDC } // namespace threading } // namespace log4tango #endif // _LOG4TANGO_THREADING_DUMMY_THREADS_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/PThreads.hh0000644023471100065110000001140713034744760022510 00000000000000// // PThreads.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_THREADING_PTHREADS_H #define _LOG4TANGO_THREADING_PTHREADS_H #include #include #include #include #include namespace log4tango { namespace threading { std::string get_thread_id (void); long thread_id (void); //----------------------------------------------------------------------------- // Class : Mutex //----------------------------------------------------------------------------- class Mutex { private: pthread_mutex_t mutex; public: inline Mutex() { ::pthread_mutex_init(&mutex, NULL); } inline ~Mutex() { ::pthread_mutex_destroy(&mutex); } inline void lock() { ::pthread_mutex_lock(&mutex); } inline void unlock() { ::pthread_mutex_unlock(&mutex); } }; //----------------------------------------------------------------------------- // Class : ScopedLock //----------------------------------------------------------------------------- class ScopedLock { private: Mutex& _mutex; public: inline ScopedLock(Mutex &m) : _mutex(m) { _mutex.lock(); } inline ~ScopedLock() { _mutex.unlock(); } }; //----------------------------------------------------------------------------- // Class : RecursiveMutex //----------------------------------------------------------------------------- class RecursiveMutex { public: // ctor RecursiveMutex (void); // dtor ~RecursiveMutex (void); // Locking an RecursiveMutex: // If is null (the default), blocks until // the mutex is acquired and returns 1 (true). Otherwise, // blocks until the mutex is acquired or times out // after milliseconds in which case 0 (false) is // returned. int lock (long timeout_ = 0); // Releasing an RecursiveMutex: // Call unlock times (i.e. one call for // each previous call to lock) or call unlockn just once. // These two methods do nothing if the caller is not the // current owner of the mutex. void unlock (void); void unlockn (void); protected: // guards the and pthread_mutex_t guard_; // this condition variable suspends other waiting threads // until the mutex is available pthread_cond_t mutex_available_; private: // current level of the recursion long recursion_level_; // current owner of the lock. pthread_t owner_id_; // dummy copy constructor and operator= to prevent copying RecursiveMutex (const RecursiveMutex&); RecursiveMutex& operator= (const RecursiveMutex&); }; //----------------------------------------------------------------------------- // Class : ThreadLocalDataHolder //----------------------------------------------------------------------------- #ifdef LOG4TANGO_HAS_NDC template class ThreadLocalDataHolder { private: pthread_key_t _key; public: typedef T data_type; inline ThreadLocalDataHolder() { ::pthread_key_create(&_key, freeHolder); } inline static void freeHolder(void *p) { assert(p != NULL); delete reinterpret_cast(p); } inline ~ThreadLocalDataHolder() { T *data = get(); if (data != NULL) { delete data; } ::pthread_key_delete(_key); } inline T* get() const { return reinterpret_cast(::pthread_getspecific(_key)); } inline T* operator->() const { return get(); } inline T& operator*() const { return *get(); } inline T* release() { T* result = get(); ::pthread_setspecific(_key, NULL); return result; } inline void reset(T* p = NULL) { T *data = get(); if (data != NULL) { delete data; } ::pthread_setspecific(_key, p); } }; #endif //LOG4TANGO_HAS_NDC } // namespace threading } // namespace log4tango #endif // _LOG4TANGO_THREADING_PTHREADS_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/MSThreads.hh0000644023471100065110000001541313034744760022631 00000000000000// // MSThreads.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_THREADING_MSTHREADS_H #define _LOG4TANGO_THREADING_MSTHREADS_H #include // deal with ERROR #define // This #includes windows.h with NOGDI and WIN32_LEAN_AND_MEAN // #defined. If this is not what the user wants, #include // windows.h before this file. #ifndef _WINDOWS_ # ifndef NOGDI # define NOGDI // circumvent the ERROR #define in windows.h # define LOG4TANGO_UNDEFINE_NOGDI # endif # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # define LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN # endif # include # ifdef LOG4TANGO_UNDEFINE_NOGDI # undef NOGDI # endif # ifdef LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN # undef WIN32_LEAN_AND_MEAN # endif #endif // done dealing with ERROR #define namespace log4tango { namespace threading { std::string get_thread_id (void); long thread_id (void); //----------------------------------------------------------------------------- // Class : MSMutex //----------------------------------------------------------------------------- class LOG4TANGO_EXPORT Mutex { public: Mutex() { InitializeCriticalSection(&_criticalSection); } ~Mutex() { DeleteCriticalSection(&_criticalSection); } inline LPCRITICAL_SECTION get_critical_section (void) { return &_criticalSection; } private: Mutex(const Mutex&); Mutex operator=(const Mutex&); CRITICAL_SECTION _criticalSection; }; //----------------------------------------------------------------------------- // Class : ScopedLock //----------------------------------------------------------------------------- class ScopedLock { public: ScopedLock (Mutex& mutex) { _criticalSection = mutex.get_critical_section(); EnterCriticalSection(_criticalSection); } ~ScopedLock() { LeaveCriticalSection(_criticalSection); } private: ScopedLock(const ScopedLock&); ScopedLock operator=(const ScopedLock&); LPCRITICAL_SECTION _criticalSection; }; //----------------------------------------------------------------------------- // Class : RecursiveMutex //----------------------------------------------------------------------------- class RecursiveMutex { public: // ctor RecursiveMutex (void) : recursion_level_(0) { ::InitializeCriticalSection(&guard_); } // dtor ~RecursiveMutex (void) { ::DeleteCriticalSection(&guard_); } // Locking an RecursiveMutex: // If is null (the default), blocks until // the mutex is acquired and returns 1 (true). Otherwise, // blocks until the mutex is acquired or times out // after milliseconds in which case 0 (false) is // returned. inline int lock (long timeout_ = 0) { ::EnterCriticalSection(&guard_); recursion_level_++; return 0; } // Releasing an RecursiveMutex: // Call unlock times (i.e. one call for // each previous call to lock) or call unlockn just once. // These two methods do nothing if the caller is not the // current owner of the mutex. inline void unlock (void) { //-should work if called by owner recursion_level_--; ::LeaveCriticalSection(&guard_); } inline void unlockn (void) { //-should work if called by owner while (recursion_level_ > 0) { recursion_level_--; ::LeaveCriticalSection(&guard_); } } protected: // guards the CRITICAL_SECTION guard_; private: // current level of the recursion unsigned long recursion_level_; // dummy copy constructor and operator= to prevent copying RecursiveMutex (const RecursiveMutex&); RecursiveMutex& operator= (const RecursiveMutex&); }; //----------------------------------------------------------------------------- // Class : ThreadLocalDataHolder //----------------------------------------------------------------------------- /** * This class holds Thread local data of type T, i.e. for each * thread a ThreadLocalDataHolder holds 0 or 1 instance of T. * The held object must be heap allocated and will be deleted * upon termination of the thread to which it belongs. **/ #ifdef LOG4TANGO_HAS_NDC template class ThreadLocalDataHolder { public: inline ThreadLocalDataHolder() : _key(TlsAlloc()) { }; inline ~ThreadLocalDataHolder() { TlsFree(_key); }; /** * Obtains the Object held for the current thread. * @return a pointer to the held Object or NULL if no * Object has been set for the current thread. **/ inline T* get (void) const { return (T*)TlsGetValue(_key); }; /** * Obtains the Object held for the current thread. * Initially each thread holds NULL. * @return a pointer to the held Object or NULL if no * Object has been set for the current thread. **/ inline T* operator->() const { return get(); }; /** * Obtains the Object held for the current thread. * @pre get() != NULL * @return a reference to the held Object. **/ inline T& operator*() const { return *get(); }; /** * Releases the Object held for the current thread. * @post get() == NULL * @return a pointer to the Object thas was held for * the current thread or NULL if no Object was held. **/ inline T* release() { T* result = (T*)TlsGetValue(_key); TlsSetValue(_key, NULL); return result; }; /** * Sets a new Object to be held for the current thread. A * previously set Object will be deleted. * @param p the new object to hold. * @post get() == p **/ inline void reset(T* p = NULL) { T* thing = (T*)TlsGetValue(_key); delete thing; TlsSetValue(_key, p); }; private: DWORD _key; }; #endif // LOG4TANGO_HAS_NDC } // namespace threading } // namespace log4tango #endif // _LOG4TANGO_THREADING_MSTHREADS_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/Threading.hh0000644023471100065110000000270713034744760022706 00000000000000// // Threading.hh // // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010,2011,2012 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef _LOG4TANGO_THREADING_THREADING_H #define _LOG4TANGO_THREADING_THREADING_H #include #ifdef LOG4TANGO_HAVE_THREADING # ifdef LOG4TANGO_USE_MSTHREADS # include # endif # ifdef LOG4TANGO_USE_PTHREADS # include # endif #else # include #endif #endif // _LOG4TANGO_THREADING_THREADING_H tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/Makefile.am0000644023471100065110000000024713034744760022511 00000000000000liblog4tangoincludedir = $(includedir)/tango/log4tango/threading liblog4tangoinclude_HEADERS = \ DummyThreads.hh \ PThreads.hh \ MSThreads.hh \ Threading.hh tango-9.2.5a/lib/cpp/log4tango/include/log4tango/threading/Makefile.in0000644023471100065110000003520713034744760022526 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include/log4tango/threading DIST_COMMON = $(liblog4tangoinclude_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(liblog4tangoincludedir)" HEADERS = $(liblog4tangoinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ liblog4tangoincludedir = $(includedir)/tango/log4tango/threading liblog4tangoinclude_HEADERS = \ DummyThreads.hh \ PThreads.hh \ MSThreads.hh \ Threading.hh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/log4tango/threading/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu include/log4tango/threading/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-liblog4tangoincludeHEADERS: $(liblog4tangoinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(liblog4tangoincludedir)" || $(MKDIR_P) "$(DESTDIR)$(liblog4tangoincludedir)" @list='$(liblog4tangoinclude_HEADERS)'; test -n "$(liblog4tangoincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(liblog4tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(liblog4tangoincludedir)" || exit $$?; \ done uninstall-liblog4tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(liblog4tangoinclude_HEADERS)'; test -n "$(liblog4tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(liblog4tangoincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(liblog4tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-liblog4tangoincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-liblog4tangoincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool ctags distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-liblog4tangoincludeHEADERS install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am \ uninstall-liblog4tangoincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/tests/0000755023471100065110000000000013034745256014407 500000000000000tango-9.2.5a/lib/cpp/log4tango/tests/Makefile.am0000644023471100065110000000064013034744762016364 00000000000000TESTS = test_log4tango test_bench check_PROGRAMS = $(TESTS) #check_DATA = #EXTRA_DIST = #noinst_PROGRAMS = INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src test_log4tango_SOURCES = test_log4tango.cpp test_log4tango_LDADD = $(top_builddir)/src/liblog4tango.la test_bench_SOURCES = clock.cpp clock.hh test_bench.cpp test_bench_LDADD = $(top_builddir)/src/liblog4tango.la distclean-local: $(RM) -f *.log tango-9.2.5a/lib/cpp/log4tango/tests/Makefile.in0000644023471100065110000004634113034744762016405 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = test_log4tango$(EXEEXT) test_bench$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) subdir = tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = test_log4tango$(EXEEXT) test_bench$(EXEEXT) am_test_bench_OBJECTS = clock.$(OBJEXT) test_bench.$(OBJEXT) test_bench_OBJECTS = $(am_test_bench_OBJECTS) test_bench_DEPENDENCIES = $(top_builddir)/src/liblog4tango.la am_test_log4tango_OBJECTS = test_log4tango.$(OBJEXT) test_log4tango_OBJECTS = $(am_test_log4tango_OBJECTS) test_log4tango_DEPENDENCIES = $(top_builddir)/src/liblog4tango.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(test_bench_SOURCES) $(test_log4tango_SOURCES) DIST_SOURCES = $(test_bench_SOURCES) $(test_log4tango_SOURCES) ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #check_DATA = #EXTRA_DIST = #noinst_PROGRAMS = INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src test_log4tango_SOURCES = test_log4tango.cpp test_log4tango_LDADD = $(top_builddir)/src/liblog4tango.la test_bench_SOURCES = clock.cpp clock.hh test_bench.cpp test_bench_LDADD = $(top_builddir)/src/liblog4tango.la all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list test_bench$(EXEEXT): $(test_bench_OBJECTS) $(test_bench_DEPENDENCIES) $(EXTRA_test_bench_DEPENDENCIES) @rm -f test_bench$(EXEEXT) $(CXXLINK) $(test_bench_OBJECTS) $(test_bench_LDADD) $(LIBS) test_log4tango$(EXEEXT): $(test_log4tango_OBJECTS) $(test_log4tango_DEPENDENCIES) $(EXTRA_test_log4tango_DEPENDENCIES) @rm -f test_log4tango$(EXEEXT) $(CXXLINK) $(test_log4tango_OBJECTS) $(test_log4tango_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bench.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_log4tango.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-local distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-local distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am distclean-local: $(RM) -f *.log # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/tests/clock.cpp0000644023471100065110000000550413034744762016133 00000000000000static const char rcsid[] = "$Id: clock.cpp 16153 2011-03-21 08:57:31Z taurel $"; // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #include // for struct timeval #ifdef __osf__ # include // for __RPCC() #elif __linux__ && __i386__ # define rdtscl(low) \ __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") #endif #include #include "clock.hh" namespace { const usec_t UsecPerSec = INT64_CONSTANT(1000000); } bool Clock::UsingCPU = std::getenv("CLOCK_USE_CPU") ? true : false; // ----------------------------------------------------------------------------- usec_t Clock::time(void) { if (UsingCPU) { static bool warn = true; if (warn) { std::cout << "Using CPU clock." << std::endl; warn = false; } #ifdef __osf__ return (usec_t) __RPCC(); #elif __linux__ && __i386__ { unsigned long tsc; rdtscl(tsc); return (usec_t) tsc; } #else { std::cerr << "CPU clock not implemented for this architecture" << std::endl; UsingCPU = false; return Clock::time(); } #endif } else { struct timeval tv; gettimeofday(&tv, NULL); return (usec_t) (tv.tv_sec * UsecPerSec + tv.tv_usec); } } // ----------------------------------------------------------------------------- Clock::Clock(void) : _start(0), _elapsed(0), _active(false) { start(); } // ----------------------------------------------------------------------------- Clock::~Clock(void) { ; } // ----------------------------------------------------------------------------- usec_t Clock::elapsed(void) const { if (!active()) return _elapsed; return time() - _start; } // ----------------------------------------------------------------------------- usec_t Clock::start(void) { _active = true; return _start = time(); } // ----------------------------------------------------------------------------- usec_t Clock::stop(void) { _elapsed = elapsed(); _active = false; return _elapsed; } tango-9.2.5a/lib/cpp/log4tango/tests/clock.hh0000644023471100065110000000331113034744762015742 00000000000000// // Copyright (C) : 2000 - 2002 // LifeLine Networks BV (www.lifeline.nl). All rights reserved. // Bastiaan Bakker. All rights reserved. // // 2004,2005,2006,2007,2008,2009,2010 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #ifndef __CLOCK_H #define __CLOCK_H #ifdef LOG4TANGO_HAVE_STDINT_H #include #endif // LOG4TANGO_HAVE_STDINT_H #ifdef __osf__ typedef long usec_t; /* number of microseconds since 1970/01/01 */ # define INT64_CONSTANT(val) (val##L) #else typedef int64_t usec_t; # define INT64_CONSTANT(val) (val##LL) #endif class Clock { public: static bool UsingCPU; static usec_t time(void); Clock(void); ~Clock(void); bool active(void) const { return _active; } usec_t elapsed(void) const; usec_t start(void); usec_t reset(void) { return start(); } usec_t stop(void); private: usec_t _start; usec_t _elapsed; bool _active; }; #endif tango-9.2.5a/lib/cpp/log4tango/tests/test_bench.cpp0000644023471100065110000001003413034744762017150 00000000000000// // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #include #include #include #include #include #include #include #include #include #include "clock.hh" // ----------------------------------------------------------------------------- int main(int argc, char* argv[]) { log4tango::Level::Value pv; pv = argc > 1 ? std::atoi(argv[1]) : log4tango::Level::DEBUG; int count; count = argc > 2 ? std::atoi(argv[2]) : 100; size_t size; size = argc > 3 ? std::atoi(argv[3]) : 128; std::cout << " level: " << log4tango::Level::get_name(pv) << " count: " << count << std::endl << " iterations" << " size: " << size << std::endl << " bytes" << std::endl; log4tango::Logger log("cat"); log.set_level(pv - 100); log4tango::OstreamAppender *ostreamAppender = new log4tango::OstreamAppender("cerr", &std::cerr); log.add_appender(ostreamAppender); Clock clock; char* buffer = new char[size + 1]; std::memset(buffer, 'X', size + 1); buffer[size] = '\0'; const int num_tests = 7; const char* tests[num_tests] = { " layout::log.error(buffer) : ", " layout::log.error_stream << std:string : ", " layout::log.error(std:string) : ", " patternlayout::log.error(buffer) : ", " patternlayout::log.error_stream << std:string : ", " patternlayout::log.error(std:string) : ", " patternlayout::if cat.is_p_enabled(p) log.error_stream << std:string : ", }; float results[num_tests]; ::memset(results, 0, num_tests * sizeof(float)); { clock.start(); for (int i = 0; i < count; i++) log.error("%s", buffer); clock.stop(); results[0] = ((float)clock.elapsed()) / count; } { std::string str(size, 'X'); clock.start(); for (int i = 0; i < count; i++) log.error_stream() << str; clock.stop(); results[1] = ((float)clock.elapsed()) / count; } { std::string str(size, 'X'); clock.start(); for (int i = 0; i < count; i++) log.error(str); clock.stop(); results[2] = ((float)clock.elapsed()) / count; } { log4tango::PatternLayout* patternLayout = new log4tango::PatternLayout(); patternLayout->set_conversion_pattern("%R %p %c %m\n"); ostreamAppender->set_layout(patternLayout); } { clock.start(); for (int i = 0; i < count; i++) log.error("%s", buffer); clock.stop(); results[3] = ((float)clock.elapsed()) / count; } { std::string str(size, 'X'); clock.start(); for (int i = 0; i < count; i++) log.error_stream() << str; clock.stop(); results[4] = ((float)clock.elapsed()) / count; } { std::string str(size, 'X'); clock.start(); for (int i = 0; i < count; i++) if (log.is_level_enabled(pv)) log.error_stream() << str; clock.stop(); results[6] = ((float)clock.elapsed()) / count; } { std::string str(size, 'X'); clock.start(); for (int i = 0; i < count; i++) log.error(str); clock.stop(); results[5] = ((float)clock.elapsed()) / count; } for (int i = 0; i < num_tests; i++) std::cout << tests[i] << results[i] << " us" << std::endl; return 0; } tango-9.2.5a/lib/cpp/log4tango/tests/test_log4tango.cpp0000644023471100065110000001604313034744762017775 00000000000000// // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of log4tango. // // Log4ango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Log4tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Log4Tango. If not, see . #include #include #include #include #include #include #include #ifdef LOG4TANGO_HAS_NDC # include #endif int test_get_appender (log4tango::Logger& logger, log4tango::Appender* appender_1, log4tango::Appender* appender_2, log4tango::Appender* appender_3) { log4tango::Appender *tmp; tmp = logger.get_appender("appender_1"); if (tmp == appender_1) { std::cout << "OK: tmp == appender_1" << std::endl; } else { std::cout << "KO: tmp != appender_1" << std::endl; return -1; } tmp = logger.get_appender("appender_2"); if (tmp == appender_2) { std::cout << "OK: tmp == appender_2" << std::endl; } else { std::cout << "KO: tmp != appender_2" << std::endl; return -1; } tmp = logger.get_appender("appender_3"); if (tmp == appender_3) { std::cout << "OK: tmp == appender_3" << std::endl; } else { std::cout << "OK: tmp != appender_3" << std::endl; return -1; } return 0; } void test_level() { log4tango::Logger cat_1("cat_1"); cat_1.set_level(log4tango::Level::ERROR); cat_1.remove_all_appenders(); log4tango::Appender* appender_1 = new log4tango::OstreamAppender("appender_1", &std::cout); appender_1->set_layout(new log4tango::Layout()); cat_1.add_appender(appender_1); std::cout << "level is OFF: no message should be printed" << std::endl; cat_1.set_level(log4tango::Level::OFF); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); std::cout << "level is FATAL: 1 messages should be printed" << std::endl; cat_1.set_level(log4tango::Level::FATAL); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); std::cout << "level is ERROR: 2 messages should be printed" << std::endl; cat_1.set_level(log4tango::Level::ERROR); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); std::cout << "level is WARN: 3 messages should be printed" << std::endl; cat_1.set_level(log4tango::Level::WARN); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); std::cout << "level is INFO: 4 messages should be printed" << std::endl; cat_1.set_level(log4tango::Level::INFO); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); std::cout << "level is DEBUG: 5 messages should be printed" << std::endl; cat_1.set_level(log4tango::Level::DEBUG); cat_1.fatal("fatal log"); cat_1.error("error log"); cat_1.warn ("warn log"); cat_1.info ("info log"); cat_1.debug("debug log"); cat_1.remove_all_appenders(); appender_1 = new log4tango::OstreamAppender("appender_1", &std::cout); appender_1->set_layout(new log4tango::Layout()); cat_1.add_appender(appender_1); log4tango::Appender* appender_2 = new log4tango::OstreamAppender("appender_2", &std::cout); appender_2->set_layout(new log4tango::Layout()); cat_1.add_appender(appender_2); log4tango::Appender* appender_3 = new log4tango::OstreamAppender("appender_3", &std::cout); appender_3->set_layout(new log4tango::Layout()); cat_1.add_appender(appender_3); std::cout << std::endl; unsigned int i; log4tango::AppenderList al = cat_1.get_all_appenders(); std::cout << "cat_1 has " << al.size() << " appenders" << std::endl; for (i = 0; i < al.size(); i++) { std::cout << "`-> appender#" << i << ": " << al[i]->get_name() << std::endl; } std::cout << std::endl; std::cout << "Following test should work" << std::endl; test_get_appender(cat_1, appender_1, appender_2, appender_3); cat_1.remove_all_appenders(); std::cout << std::endl; std::cout << "Following test should fail" << std::endl; test_get_appender(cat_1, appender_1, appender_2, appender_3); appender_1 = new log4tango::OstreamAppender("appender_1", &std::cout); appender_2 = new log4tango::OstreamAppender("appender_2", &std::cout); cat_1.add_appender(appender_1); cat_1.add_appender(appender_2); std::cout << std::endl; al = cat_1.get_all_appenders(); std::cout << "cat_1 has " << al.size() << " appenders" << std::endl; for (i = 0; i < al.size(); i++) { std::cout << "`-> appender#" << i << ": " << al[i]->get_name() << std::endl; } cat_1.remove_appender(appender_1); std::cout << std::endl; al = cat_1.get_all_appenders(); std::cout << "cat_1 has " << al.size() << " appenders" << std::endl; for (i = 0; i < al.size(); i++) { std::cout << "`-> appender#" << i << ": " << al[i]->get_name() << std::endl; } cat_1.remove_appender(appender_2); std::cout << std::endl; al = cat_1.get_all_appenders(); std::cout << "cat_1 has " << al.size() << " appenders" << std::endl; for (i = 0; i < al.size(); i++) { std::cout << "`-> appender#" << i << ": " << al[i]->get_name() << std::endl; } cat_1.remove_appender(appender_3); } /* end test_level() */ int main(int argc, char** argv) { test_level(); log4tango::Logger cat_1("cat_1"); log4tango::Appender* appender_1 = new log4tango::OstreamAppender("appender_1", &std::cout); appender_1->set_layout(new log4tango::Layout()); cat_1.add_appender(appender_1); cat_1.set_level(log4tango::Level::ERROR); log4tango::Logger cat_2("cat_2"); log4tango::Appender* appender_2 = new log4tango::OstreamAppender("appender_2", &std::cout); appender_2->set_layout(new log4tango::Layout()); cat_2.add_appender(appender_2); cat_2.set_level(log4tango::Level::INFO); std::cout << std::endl; std::cout << "cat_1 level: " << cat_1.get_level() << " - " << log4tango::Level::get_name(cat_1.get_level()) << std::endl; std::cout << "cat_2 level: " << cat_2.get_level() << " - " << log4tango::Level::get_name(cat_2.get_level()) << std::endl; return 0; } tango-9.2.5a/lib/cpp/log4tango/doc/0000755023471100065110000000000013034745256014012 500000000000000tango-9.2.5a/lib/cpp/log4tango/doc/Doxyfile.in0000644023471100065110000017424313034744763016062 00000000000000# Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = . # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. #SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @top_srcdir@/include \ @top_srcdir@/src \ @top_srcdir@/doc/mainPage.txt # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp \ *.hh # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = @enable_html_docs@ # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/api # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. #HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NONE # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = @enable_latex_docs@ # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = @enable_dot@ # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO tango-9.2.5a/lib/cpp/log4tango/doc/Makefile.am0000644023471100065110000000174213034744763015774 00000000000000SUBDIRS = html man3dir = $(mandir)/man3 docdir_log = $(docdir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ EXTRA_DIST = \ mainPage.txt .PHONY: dox pdf all-local: dox dox: html html/api/index.html html/api/index.html: Doxyfile @DOXYGEN@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(man3dir) @for i in ./man/man3/log4tango.3 ./man/man3/log4tango_*.3; do \ inst=`basename $$i | sed 's/_/::/g'`; \ echo "$(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst; \ done $(mkinstalldirs) $(DESTDIR)$(docdir_log) cp -r html/. $(DESTDIR)$(docdir_log) $(RM) -r -f $(DESTDIR)$(docdir_log)/CVS \ $(DESTDIR)$(docdir_log)/Makefile.am \ $(DESTDIR)$(docdir_log)/Makefile.in \ $(DESTDIR)$(docdir_log)/Makefile uninstall-local: $(RM) $(DESTDIR)$(man3dir)/log4tango.3 $(RM) $(DESTDIR)$(man3dir)/log4tango::*.3 $(RM) -r -f $(DESTDIR)$(docdir_log) clean-local: $(RM) -r latex $(RM) -r html/api man @PACKAGE_TARNAME@.ps @PACKAGE_TARNAME@.pdf tango-9.2.5a/lib/cpp/log4tango/doc/Makefile.in0000644023471100065110000004507113034744763016010 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = Doxyfile CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = html man3dir = $(mandir)/man3 docdir_log = $(docdir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ EXTRA_DIST = \ mainPage.txt all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local ctags ctags-recursive distclean \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local .PHONY: dox pdf all-local: dox dox: html html/api/index.html html/api/index.html: Doxyfile @DOXYGEN@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(man3dir) @for i in ./man/man3/log4tango.3 ./man/man3/log4tango_*.3; do \ inst=`basename $$i | sed 's/_/::/g'`; \ echo "$(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst; \ done $(mkinstalldirs) $(DESTDIR)$(docdir_log) cp -r html/. $(DESTDIR)$(docdir_log) $(RM) -r -f $(DESTDIR)$(docdir_log)/CVS \ $(DESTDIR)$(docdir_log)/Makefile.am \ $(DESTDIR)$(docdir_log)/Makefile.in \ $(DESTDIR)$(docdir_log)/Makefile uninstall-local: $(RM) $(DESTDIR)$(man3dir)/log4tango.3 $(RM) $(DESTDIR)$(man3dir)/log4tango::*.3 $(RM) -r -f $(DESTDIR)$(docdir_log) clean-local: $(RM) -r latex $(RM) -r html/api man @PACKAGE_TARNAME@.ps @PACKAGE_TARNAME@.pdf # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/doc/mainPage.txt0000644023471100065110000000017113034744763016215 00000000000000/** @mainpage This is the Doxygen generated API documentation of Log4Tango. **/ tango-9.2.5a/lib/cpp/log4tango/doc/html/0000755023471100065110000000000013034745256014756 500000000000000tango-9.2.5a/lib/cpp/log4tango/doc/html/Makefile.am0000644023471100065110000000007113034744762016731 00000000000000EXTRA_DIST = \ index.html \ default.css \ sflogo.png tango-9.2.5a/lib/cpp/log4tango/doc/html/Makefile.in0000644023471100065110000002450213034744762016747 00000000000000# Makefile.in generated by automake 1.11.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/html DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/AC_CREATE_PREFIX_CONFIG_H.m4 \ $(top_srcdir)/m4/AC_CXX_HAVE_SSTREAM.m4 \ $(top_srcdir)/m4/AC_CXX_NAMESPACES.m4 \ $(top_srcdir)/m4/AC_C_INT64_T.m4 \ $(top_srcdir)/m4/AC_FUNC_SNPRINTF.m4 \ $(top_srcdir)/m4/BB_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/BB_ENABLE_DOXYGEN.m4 \ $(top_srcdir)/m4/CREATE_GENERIC_CONFIG.m4 \ $(top_srcdir)/m4/PETI_PEDANTIC_GCC.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOT = @DOT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GENERIC_CONFIG = @GENERIC_CONFIG@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_VERSION = @LT_VERSION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_dot = @enable_dot@ enable_html_docs = @enable_html_docs@ enable_latex_docs = @enable_latex_docs@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = \ index.html \ default.css \ sflogo.png all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/html/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/html/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/log4tango/doc/html/index.html0000644023471100065110000002754713034744762016713 00000000000000 Log for Tango

Log4Tango

Introduction

"Log4Tango" is a light and custom version of Log4cpp for Tango. Log4cpp is library of C++ classes for flexible logging to miscelaneous destinations. It is modeled after the Log4j Java library.

Download

log4tango is part of the TANGO distribution. There is no way to obtain log4tango individually.

Building Log4Tango

The pthread (i.e. POSIX thread) library is required to compile log4tango.

log4tango can be build using autoconf on platforms that support it. Simply do:

./configure
make
make check
make install

This will install log4tango under /usr/local. To install in another localation specify --prefix=<location> when running configure.

Options for ./configure

Besides the usual ./configure options like --prefix a few others are available:
--enable-doxyen
Enables generation of API documentation by Dimitri van Heeschs Doxygen tool (http://www.doxygen.org/). Defaults to yes if doxygen can be found in the search path.
--enable-html-docs
If doxygen is enabled, have it generate HTML formatted documentation.
--enable-latex-docs
If doxygen is enabled, have it generate LaTeX formatted documentation.
--enable-dot
Let Doxygen use the 'dot' tool of GraphViz (http://www.graphviz.org) todraw its graphs.

Build notes for specific platforms

*nix (including Linux) - g++ compiler
Log4cpp should build whitout modification on any decent *nix system with g++ and GNU make. The primary development platform is RedHat Linux 7.3, which has g++ 2.96-rh, but the aim is to be compatible with from g++ 2.95 and up. When g++ 3.x has been widely adopted we may drop support for older g++ versions.
Solaris - Sun CC compiler
Compilation with Suns CC compiler requires setting some enviroment variables. Also static libraries appear not to work. In short do:
CC=CC CXX=CC LD="CC -KPIC" ./configure --disable-static
Win32 - MSVC++ 6
Use the workspace and project files in subdirectory msvc6. You may need to adjust include/log4cpp/config-win32.h and the project files to your particular needs.

Releases

2.2.0 - based on log4cpp-0.3.4b (24 February 2003)

Documentation

API Documentation generated by Doxygen can be found here.

FAQ

1. GENERAL

1.1. What is Log for C++?

Log for C++ is a library of C++ classes for flexible logging to misc. destinations. It is modeled after the Log for Java library (http://jakarta.apache.org/log4j/).

1.2. How is Log for C++ related to Log4j? Is it a straight port?

Log for C++ strives to supply a similar interface for logging in C++ as Log4j provides in Java. However the implementation is not a translation of the Java code. So in that sense it is not a 'port' of Log4j. Of course Log for C++ does owe many of its concepts to log4j.

1.3. What is the name of this project, 'Log for C++' or 'log4cpp'?

The 'official' long name of the project is 'Log for C++', but in practice, the short name, 'log4cpp' has proven more convinient.

1.4. Under which license is Log for C++ available?

As of version 0.2.1 Log for C++ is released under the GNU Lesser General Public License (LGPL). Versions before that have been released under the GPL. See the license discussion on the forum at SourceForge for the motivations behind switching from GPL to LGPL.

1.5. Our legal department doesn't like the LGPL, can you release Log for C++ under license XYZ?

No.
Long answer: Technically it may be possible if every contributor agrees, which due to their growing number has become increasingly difficult. But even if that could be overcome it will not happen.
Of course the LGPL does grant you the opportunity to choose the GPL instead of the LGPL, but I bet XYZ != GPL.

2. COMPILATION AND INSTALLATION

3. USAGE

3.1. I've succesfully compiled log4cpp, now how do I use this stuff?

For some small examples using log4cpp, see the 'tests' subdirectory. Also see the documentation section for a pointer for API documentation and more usage information.

3.2. Is log4cpp thread-safe?

4. PROBLEMS AND ERROR MESSAGES

4.1. I get 'Naming collision for 'ERROR' detected. Please read the FAQ for a workaround.'

This is caused by the rudeness of some platforms, which mutilate the namespace with some blunt #defines. To be more precise, the Win32 API includes #defines of 'ERROR' and 'DEBUG'. Since the preprocessor is unaware of C++ naming scopes this results in reserving the words ERROR and DEBUG litterally everywhere. In particular this conflicts with log4cpp::Prioritiy::ERROR and log4cpp::Priority::DEBUG. These latter two names come from log4j, so they are not something we made up ourselves.
They Win32 authors should not have rudelessly claimed these generic names through the preprocessor. There are much better alternatives:
  1. If they use it as an integer constant, declare it using a language construct. Either 'enum {ERROR=1};' or 'static const int ERROR=1;' would do fine.
  2. Use a less generic name like WIN32API_ERROR to make naming conflicts less likely
  3. In case they use it as a flag for conditional compilation, use '#define DEBUG DEBUG' and '#if defined(DEBUG)'. In that case the preprocessor would simply replace all occurrences of 'DEBUG' in the source code with 'DEBUG', in effect leaving everything intact.

Of course the proper solution would be if the offending party would use one of the above methods, but we could have to wait some time for this to actually happen. As an alternative log4cpp can workaround these #defines. The workaround code is enabled by doing #define LOG4CPP_FIX_ERROR_COLLISION 1 before #including any log4cpp header files and after #including all platform headers. For Win32 platforms this #define has already been included in log4cpp/config-win32.h.

Once log4cpp has been updated to the log4j 1.2 API we can get rid of this problem by adopting the new names for log levels.

4.2. I am trying to compile/link the log4cpp package using the SunWorkshop compiler (CC) on a Solaris 7 machine. The library builds, but the testmain code fails to link properly.

A proper solution for this problem has not been found yet (suggestions are welcome), but James Emery reported success with the following workaround:
  • Disable building of the static library
  • Change the linker from /usr/ucb/ld to CC and enable 'place independent code' (pic).
In short, configure with:
export LD="CC -Kpic" && ./configure --disable-static

4.3. ./configure fails to detect 'snprintf()' on platform XYZ.

./configure does not just check for the presence of a snprintf() function but for C99 compliancy as well. In particular, snprintf() should strictly honour the 'string size' parameter to avoid potential buffer overflow problems. log4cpp falls back to an alternative snprintf() implementation if the OS does not provide a correct one.

Status

As of version 0.3.0 log4cpp has a separate 'stable' and 'development' branches. Releases x.y.z where y is even are considered stable and those where y is odd are experimental (which means that some or all features may be broken).

The latest stable release 0.2.7. New releases of 0.2.x are for bug fixes only, new features will go into 0.3.x and eventually 0.4.x.

People

Coding on Log4cpp was initiated by me (Bastiaan Bakker) late 2000. Since then other people have joined the project or contributed code:
Cedric Le Goater <cedric(at)legoater.com>autoconf setup, various improvements
Marc Welz <marc(at)jade.cs.uct.ac.za>IdsaAppender
Lynn Owen <opl(at)agoby.com>MSVC++ support
Steve Ostlind <s.ostlind(at)pentasafe.com>MSVC++ support, various fixes
Marcel Harkema <marcel(at)debian.org>Debian packaging
Uwe J�er <jaeger(at)varial.de>Borland C++ Builder support
Walter Stroebel <walter.stroebel(at)lifeline.nl>RemoteSyslogAppender
Glen Scott <glen_s(at)yahoo.com>PatternLayout, SimpleConfigurator
Tony Cheung <dragonman(at)asiayeah.com>OpenVMS support
Alex Tapaccos <ATapaccos(at)redfig.com>DailyRollingFileAppender
Brendan B. Boerner <bboerner(at)texas.net>Multiple Appender support for Categories
Paulo Pizarro <paulo.pizarro(at)digitro.com.br>RollingFileAppender
David Resnick <dresnick(at)mobilespear.com>NTEventAppender, integration work
Aaron Ingram <ai8(at)yahoo.com>MSThreads support
Alan Anderson <alan(at)rushmore.com>Win32DebugAppender, PropertyConfigurator
Emiliano Martin <emilianomc(at)terra.es>PThreads support

Project Pages

SourceForge Logo Log4cpp is hosted on SourceForge at http://sourceforge.net/projects/log4cpp/.

Related Projects

Log4cpp is but one of many ports/implementations of the Log4j API. Here's an incomplete list:
log4cAn implementation in C by Cedric Legoater
log4cplusAn indepent C++ implementation by Tad Smith. Worth checking out if you don't like Log4cpp for some reason.

License

As of version 0.2.1 this library is licensed under the Lesser General Public License instead of the General Public License. No further license changes are planned :-).

Log for C++ (short name: log4cpp), a C++ library for flexible logging.
Copyright (C) 2000-2002 LifeLine Networks bv
Copyright (C) 2000-2002 Bastiaan Bakker
Portions Copyright others, see file THANKS and source code.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
tango-9.2.5a/lib/cpp/log4tango/doc/html/default.css0000644023471100065110000000030313034744762017031 00000000000000BODY { BACKGROUND-COLOR: white } H2 { color: white; background-color: darkBlue; font-family: arial,helvetica,sanserif; } H3 { text-decoration: underline; } DT { font-weight: bold; } tango-9.2.5a/lib/cpp/log4tango/doc/html/sflogo.png0000644023471100065110000000407713034744762016706 00000000000000‰PNG  IHDRX쪷gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ÎIDATxÚbTSRf ÄÄ7ïÞá¡ ®¬@L£iˆeºëÖa†·×Xÿ3È[1°±1ð«£éٳ眜‚‚‚dX@gΞ۴eË÷ï?3ÒR”ÄÅO¨fSãfðÈcà‡úðÁõ•ë·?{ùÂzUZJÒØÈHG[ È4êêµk@qNÎwïßeâ@0hÐìuuq¾yõê©“'5µ´\\]ÌÌÍ!âÄ,,(”›ŸGÿ€’’½xéÝÝÑææâÌÉÁññÉ+‰‹X5ä˜c*ØyàŠyD5ÔÕÏœ;'/'WU^ÊÉɹÿÀA ^e%E ÏgÌž}óÖíàÀ 216216>|ô(cnV&0t>þô|fZ*Ð ˆi*ÊJ@rÛÖ­.®®Ò22@ö”I“ˆ9]õíxÿþ}|l $Ò€IJJE€ ®\½(ncmŒ   „ ô<à•”M€1Œ% i?~üàààªJÙÈñïçã LÆÈAôÀËšÿÞ}cKÎÅ 8A!!? “À*V®^dܽw(´]YI (Q 46#5uÕ`0!t0™Zô¢°\°x Ð& û \ MÀP $P|Ó–­@[þüþã;$A ‚€A´¥€ èç鳿= Œ%`À¥€ÚN|ÿþ0%ß½w¨ˆ\]œ0½ ôûÆ«l®ö¸‘6Ø^ €„,ØŸ ÑÖÒD3 —h X  DŠšô9ÐÑ@×] ´œ9 æº:;/\¼ÄÖÆ9Œ1‹% v Æ3gÏBØA ÝÏ´ž#Ç?Ä5@[ Ü]{öÉ{÷î{?|Ãf¤‰+ €Þ" bˆçŽ‘—T‰'Mê&IPÚIÄ ¹ÀTt0þïÞ;Žp„?!©³ìAÀ„t"ГW¯]G x áoÃÈûð E ÞçÏŸ,Y8À¡ IÀL‡©h>Ðp[æ~`²ZÇ ˆ 9Ó `¢hïêZ&€¡Ì–À€€ä”ïß¿cUt ÁÓ6<˜˜YäE~»Ž3 üf1`º‚q÷ž½ðä ‡t PêÈÑ£ÚZZð” ktÂe8@1!g  R`1‰y B.Û®\½ Z\Ë O€ö­\³¨ -øá>ZDá¡!X áN°þµû .+®‚ÝJ_ÖÖx–Ç Ïe—€2‹¤f\Ɇ˜ €QÌl@4ÈØ½¡çÈÑcÀä tÐJˆ¯€ÁL>À´ƒl\xh0DH>r À²9X!™p)ž\7&!®_s'c:ôý»w vÇïð2 R¯£ÈLç *‘Q+@g 9]Æ(Â0ÅÁ 9*^Ooà1Ü\=‹[« .‚>| ‚[i’¦m’ÿ“„¡ËY£ª@ú´KÁ úäÁø³ª9 ,ô¿Q؈P@żw",n’½$¶ã4“e† ò´_ ‚tíûÙV)ìþi¨Žuéú!ÄÍPY}€7æx„ðõ6T„ŠEYä!Æ?¨=FöŸ5n„ˆÁŸgxu õ Rº ŒÿˆlbSÒé ÁÚ×5!jƒÊ²òÀà x³Ðê}îÙ½{ÝÚµ¸dhèÄÓ'O€Âöp)J}úô ™ LxŒ –!Nö ÈÉu-Xñj|bbUM5D P¤½¥õäÉ“ÒÒÒ7®_×ÐÔ¬ª©¹~ý<b£¢!  !ÈÝ €b–ÿ‡¨(-:ØÄÀ0+=ãÉãÇ'Oœð÷ñЬ]³(ûñãG 7&2 ¢Â*ªrâ@•@-˜ÆÅhˆe )ii ,í¦Î˜ìAÔ±w÷P…:Áõk×áñÌÇÇ”¦‘… 4 €qÖ¸¹›áÞñÿŸÿüSñf6B)ç Îú’#€äúuë€ä䉓ಟ?ƒÄ¯_»FÐ6€¬q|Ã—Ë ‚ÂŒný[rú×½|ÎbÊQ L,Ð! РÌï_2\߯ gÌ Å .ÉÌÿ÷ÛÌuÄë–‘dØ @ƒ1 þ¿yÅðéÃóË w70¼}ýï ÓŸ'߸AP£&xxf¸¼ Ð` ˆÌ|?o°1œ¹Ìplÿ¿Ë¯¾Þâÿý„™EAœç?ãÑ)8ׯ] ,2á‚À⣭¥^šÀË xchÀoñEŽ ÀÇÅWÝüñëÛ—«¼ßϰ³iò¸E³fÎüüéÐK¢¢¢ÀZèá•Ë—_¿~@JÊ ‘È_¿~•mÛºõçÏŸŒŒ ÀEQAaDT¤’²2PX¹\¼pÈØ°nÝ©“§\\]!6N™4 €i§ë×…GJ–ÿ/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/server DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(tangoinclude_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libserver_la_LIBADD = am_libserver_la_OBJECTS = attrdesc.lo attrgetsetprop.lo attribute.lo \ attrsetval.lo attrmanip.lo basiccommand.lo blackbox.lo \ class_factory.lo classattribute.lo command.lo coutappender.lo \ classpipe.lo dev_event.lo dev_poll.lo device.lo device_2.lo \ device_3.lo device_4.lo device_5.lo deviceclass.lo \ devicelog.lo devintr.lo dintrthread.lo dserver.lo \ dserverclass.lo dserverlock.lo dserverlog.lo dserverpoll.lo \ dserversignal.lo encoded_attribute.lo eventcmds.lo \ eventsupplier.lo except.lo fwdattrdesc.lo fwdattribute.lo \ logcmds.lo logging.lo logstream.lo multiattribute.lo \ notifdeventsupplier.lo pipe.lo pollcmds.lo pollobj.lo \ pollring.lo pollthread.lo rootattreg.lo seqvec.lo \ subdev_diag.lo tangoappender.lo tangorollingfileappender.lo \ templ_inst.lo thsig.lo utils.lo utils_polling.lo utils_shut.lo \ w_attribute.lo w_pipe.lo zmqeventsupplier.lo libserver_la_OBJECTS = $(am_libserver_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libserver_la_SOURCES) DIST_SOURCES = $(libserver_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(tangoincludedir)" HEADERS = $(tangoinclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = idl jpeg jpeg_mmx . # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libserver.la AM_CXXFLAGS = -D_TANGO_LIB # The sources libserver_la_SOURCES = attrdesc.cpp \ attrgetsetprop.cpp \ attribute.cpp \ attrsetval.cpp \ attrmanip.cpp \ basiccommand.cpp \ blackbox.cpp \ class_factory.cpp \ classattribute.cpp \ command.cpp \ coutappender.cpp \ classpipe.cpp \ dev_event.cpp \ dev_poll.cpp \ device.cpp \ device_2.cpp \ device_3.cpp \ device_4.cpp \ device_5.cpp \ deviceclass.cpp \ devicelog.cpp \ devintr.cpp \ dintrthread.cpp \ dserver.cpp \ dserverclass.cpp \ dserverlock.cpp \ dserverlog.cpp \ dserverpoll.cpp \ dserversignal.cpp \ encoded_attribute.cpp \ eventcmds.cpp \ eventsupplier.cpp \ except.cpp \ fwdattrdesc.cpp \ fwdattribute.cpp \ logcmds.cpp \ logging.cpp \ logstream.cpp \ multiattribute.cpp \ notifdeventsupplier.cpp \ pipe.cpp \ pollcmds.cpp \ pollobj.cpp \ pollring.cpp \ pollthread.cpp \ rootattreg.cpp \ seqvec.cpp \ subdev_diag.cpp \ tangoappender.cpp \ tangorollingfileappender.cpp \ templ_inst.cpp \ thsig.cpp \ utils.cpp \ utils_polling.cpp \ utils_shut.cpp \ w_attribute.cpp \ w_pipe.cpp \ zmqeventsupplier.cpp tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = attrdesc.h \ attribute.h \ attrmanip.h \ attrprop.h \ auto_tango_monitor.h \ basiccommand.h \ blackbox.h \ classattribute.h \ classpipe.h \ command.h \ coutappender.h \ coutbuf.h \ device.h \ device_2.h \ device_3.h \ device_4.h \ device_5.h \ deviceclass.h \ devintr.h \ dintrthread.h \ dserver.h \ dserverclass.h \ dserversignal.h \ encoded_attribute.h \ encoded_format.h \ eventsupplier.h \ except.h \ fwdattrdesc.h \ fwdattribute.h \ log4tango.h \ logcmds.h \ logging.h \ logstream.h \ multiattribute.h \ ntservice.h \ pipe.h \ pipedesc.h \ pollcmds.h \ pollext.h \ pollobj.h \ pollring.h \ pollthread.h \ readers_writers_lock.h \ rootattreg.h \ seqvec.h \ subdev_diag.h \ tango.h \ tango_config.h \ tango_const.h \ tango_monitor.h \ tangoappender.h \ tangorollingfileappender.h \ utils.h \ w_attribute.h \ w_pipe.h \ attribute.tpp \ attribute_spec.tpp \ attrprop.tpp \ attrsetval.tpp \ device_3.tpp \ fwdattribute.tpp \ fwdattribute_spec.tpp \ pipe.tpp \ pollext.tpp \ pollring.tpp \ pollthread.tpp \ utils.tpp \ utils_spec.tpp \ w_attribute.tpp \ w_attribute_spec.tpp \ w_attrsetval.tpp \ w_pipe.tpp all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/server/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/server/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libserver.la: $(libserver_la_OBJECTS) $(libserver_la_DEPENDENCIES) $(EXTRA_libserver_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libserver_la_OBJECTS) $(libserver_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attrdesc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attrgetsetprop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attrmanip.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attrsetval.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basiccommand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blackbox.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class_factory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classattribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classpipe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coutappender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dev_event.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dev_poll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device_2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device_3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device_4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device_5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deviceclass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devicelog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devintr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dintrthread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserverclass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserverlock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserverlog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserverpoll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dserversignal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoded_attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventcmds.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventsupplier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fwdattrdesc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fwdattribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logcmds.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logstream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multiattribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notifdeventsupplier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pollcmds.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pollobj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pollring.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pollthread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rootattreg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subdev_diag.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tangoappender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tangorollingfileappender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/templ_inst.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thsig.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils_polling.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils_shut.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/w_attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/w_pipe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmqeventsupplier.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tangoincludeHEADERS: $(tangoinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tangoincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tangoincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(tangoincludedir)" || exit $$?; \ done uninstall-tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(tangoincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-tangoincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-tangoincludeHEADERS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ clean-noinstLTLIBRARIES ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip install-tangoincludeHEADERS installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-tangoincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/server/attrdesc.h0000644023471100065110000005172513034745001014555 00000000000000//=================================================================================================================== // // file : attrdesc.h // // description : Include file for the Attr classes hierarchy. Three classes are declared in this file : // The Attr class // The SpectrumAttr class // The ImageAttr class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28373 $ // //=================================================================================================================== #ifndef _ATTRDESC_H #define _ATTRDESC_H #include namespace Tango { class AttrProperty; class WAttribute; /** * User class to set attribute default properties. * * This class is used to set attribute default properties. Three levels of * attributes properties setting are implemented within Tango. The highest * property setting level is the database. Then the user default (set using * this UserDefaultAttrProp class) and finally a Tango library default * value * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class UserDefaultAttrProp { public: /**@name Constructor * Only one constructor is defined for this class */ //@{ /** * Constructs a newly allocated UserDefaultAttrProp object. */ UserDefaultAttrProp():ext(Tango_nullptr) {} //@} /**@name Set default property methods */ //@{ /** * Set default label property * * @param def_label The user default label property */ void set_label(const char *def_label) { label = def_label; } /** * Set default description property * * @param def_desc The user default description property */ void set_description(const char *def_desc) { description = def_desc; } /** * Set default unit property * * @param def_unit The user default unit property */ void set_unit(const char *def_unit) { unit = def_unit; } /** * Set default standard unit property * * @param def_std_unit The user default standard unit property */ void set_standard_unit(const char *def_std_unit) { standard_unit = def_std_unit; } /** * Set default display unit property * * @param def_disp_unit The user default display unit property */ void set_display_unit(const char *def_disp_unit) { display_unit = def_disp_unit; } /** * Set default format property * * @param def_format The user default format property */ void set_format(const char *def_format) { format = def_format; } /** * Set default min_value property * * @param def_min_value The user default min_value property */ void set_min_value(const char *def_min_value) { min_value = def_min_value; } /** * Set default max_value property * * @param def_max_value The user default max_value property */ void set_max_value(const char *def_max_value) { max_value = def_max_value; } /** * Set default min_alarm property * * @param def_min_alarm The user default min_alarm property */ void set_min_alarm(const char *def_min_alarm) { min_alarm = def_min_alarm; } /** * Set default max_alarm property * * @param def_max_alarm The user default max_alarm property */ void set_max_alarm(const char *def_max_alarm) { max_alarm = def_max_alarm; } /** * Set default min_warning property * * @param def_min_warning The user default min_warning property */ void set_min_warning(const char *def_min_warning) { min_warning = def_min_warning; } /** * Set default max_warning property * * @param def_max_warning The user default max_warning property */ void set_max_warning(const char *def_max_warning) { max_warning = def_max_warning; } /** * Set default RDS alarm delta_t property * * @param def_delta_t The user default RDS alarm delta_t property */ void set_delta_t(const char *def_delta_t) { delta_t = def_delta_t; } /** * Set default RDS alarm delta_val property * * @param def_delta_val The user default RDS alarm delta_val property */ void set_delta_val(const char *def_delta_val) { delta_val = def_delta_val; } /** * Set default change event abs_change property * * @param def_abs_change The user default change event abs_change property */ void set_event_abs_change(const char *def_abs_change) { abs_change = def_abs_change; } /** * Set default change event rel_change property * * @param def_rel_change The user default change event rel_change property */ void set_event_rel_change(const char *def_rel_change) { rel_change = def_rel_change; } /** * Set default periodic event period property * * @param def_period The user default periodic event period property */ void set_event_period(const char *def_period) { period = def_period; } /** * Set default archive event abs_change property * * @param def_archive_abs_change The user default archive event abs_change property */ void set_archive_event_abs_change(const char *def_archive_abs_change) { archive_abs_change = def_archive_abs_change; } /** * Set default archive event rel_change property * * @param def_archive_rel_change The user default archive event rel_change property */ void set_archive_event_rel_change(const char *def_archive_rel_change) { archive_rel_change = def_archive_rel_change; } /** * Set default archive event period property * * @param def_archive_period The user default archive event period property */ void set_archive_event_period(const char *def_archive_period) { archive_period = def_archive_period; } /** * Set default enumeration labels * * @param def_enum_labels The enumeration labels */ void set_enum_labels(vector &def_enum_labels) { for (size_t loop = 0;loop < def_enum_labels.size();loop++) { enum_labels = enum_labels + def_enum_labels[loop]; if (loop != def_enum_labels.size() - 1) enum_labels = enum_labels + ','; } } //@} /// @privatesection ~UserDefaultAttrProp() {} void set_abs_change(const char *def_abs_change) { set_event_abs_change(def_abs_change); } void set_rel_change(const char *def_rel_change) { set_event_rel_change(def_rel_change); } void set_period(const char *def_period) { set_event_period(def_period); } void set_archive_abs_change(const char *def_archive_abs_change) { set_archive_event_abs_change(def_archive_abs_change); } void set_archive_rel_change(const char *def_archive_rel_change) { set_archive_event_rel_change(def_archive_rel_change); } void set_archive_period(const char *def_archive_period) { set_archive_event_period(def_archive_period); } string label; string description; string unit; string standard_unit; string display_unit; string format; string min_value; string max_value; string min_alarm; string max_alarm; string min_warning; string max_warning; string delta_val; string delta_t; string abs_change; string rel_change; string period; string archive_abs_change; string archive_rel_change; string archive_period; string enum_labels; private: class UserDefaultAttrPropExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else UserDefaultAttrPropExt *ext; #endif }; /** * User class to create a no dimension attribute object. * * Information from this class and information fetched out from the Tango * database allows the Tango core software to create the Attribute object * for the attribute created by the user. * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class Attr { public: /**@name Constructors * Two constructor are defined for this class */ //@{ /** * Constructs a newly allocated Attr object. * The attribute display level is set to OPERATOR. * * @param name The attribute name * @param data_type The attribute data type * @param w_type The attribute type (read, write, read with write ...) * @param assoc Name of the associated writable attribute. This is used * only the read with write attribute * */ Attr(const char *name,long data_type, Tango::AttrWriteType w_type = Tango::READ, const char *assoc = AssocWritNotSpec); /** * Constructs a newly allocated Attr object. * * @param name The attribute name * @param data_type The attribute data type * @param disp The attribute display level * @param w_type The attribute type (read, write, read with write ...) * @param assoc Name of the associated writable attribute. This is used * only the read with write attribute * */ Attr(const char *name,long data_type,Tango::DispLevel disp, Tango::AttrWriteType w_type = Tango::READ, const char *assoc = AssocWritNotSpec); Attr(const char *name,Tango::DispLevel disp = Tango::OPERATOR); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The object desctructor. */ virtual ~Attr(); //@} /**@name Miscellaneous methods*/ //@{ /** * Set default attribute properties * * @param prop The user default property class */ void set_default_properties(UserDefaultAttrProp &prop); /** * Set the attribute display level * * @param level The attribute display level */ void set_disp_level(Tango::DispLevel level) {disp_level = level;} /** * Set the attribute polling update period * * @param update The attribute polling period (in mS) */ void set_polling_period(long update) {poll_period = update;} /** * Set the attribute as memorized in database (only for scalar and writable * attribute) * By default the setpoint will be written to the attribute during initialisation! * Use method set_memorized_init() with false as argument if you don't want this feature */ void set_memorized(); /** * Set the initialisation flag for memorized attributes * true = the setpoint value will be written to the attribute on initialisation * false = only the attribute setpoint is initialised. No action is taken on the attribute * * @param write_on_init If true the setpoint value will be written to the attribute on initialisation */ void set_memorized_init(bool write_on_init) {mem_init = write_on_init;} /** * Set a flag to indicate that the server fires change events manually without * the polling to be started for the attribute. * If the detect parameter is set to true, the criteria specified for the change * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without checking! * * @param implemented True when the server fires change events manually. * @param detect Triggers the verification of the change event properties when set to true. */ void set_change_event(bool implemented, bool detect) { fire_change_event = implemented;check_change_event = detect; } /** * Check if the change event is fired manually for this attribute. * * @return A boolean set to true if a manual fire change event is implemented. */ bool is_change_event() {return fire_change_event;} /** * Check if the change event criteria should be checked when firing * the event manually. * * @return A boolean set to true if a change event criteria will be checked. */ bool is_check_change_criteria() {return check_change_event;} /** * Set a flag to indicate that the server fires archive events manually without * the polling to be started for the attribute * If the detect parameter is set to true, the criteria specified for the archive * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without checking! * * @param implemented True when the server fires archive events manually. * @param detect Triggers the verification of the archive event properties when set to true. */ void set_archive_event(bool implemented, bool detect) { fire_archive_event = implemented;check_archive_event = detect; } /** * Check if the archive event is fired manually for this attribute. * * @return A boolean set to true if a manual fire archive event is implemented. */ bool is_archive_event() {return fire_archive_event;} /** * Check if the archive event criteria should be checked when firing * the event manually. * * @return A boolean set to true if a archive event criteria will be checked. */ bool is_check_archive_criteria() {return check_archive_event;} /** * Set a flag to indicate that the server fires data ready events * * @param implemented True when the server fires data ready events */ void set_data_ready_event(bool implemented) { fire_dr_event = implemented;} /** * Check if the data ready event is fired for this attribute. * * @return A boolean set to true if firing data ready event is implemented. */ bool is_data_ready_event() {return fire_dr_event;} //@} /// @privatesection Attr(const Attr &); string &get_name() {return name;} Tango::AttrDataFormat get_format() {return format;} Tango::AttrWriteType get_writable() {return writable;} long get_type() {return type;} Tango::DispLevel get_disp_level() {return disp_level;} long get_polling_period() {return poll_period;} bool get_memorized() {return mem;} bool get_memorized_init() {return mem_init;} string &get_assoc() {return assoc_name;} const string &get_cl_name() {return cl_name;} void set_cl_name(const string &cl) {cl_name = cl;} bool is_assoc() {if (assoc_name != AssocWritNotSpec)return true;else return false;} vector &get_class_properties() {return class_properties;} vector &get_user_default_properties() {return user_default_properties;} void set_class_properties(vector &in_prop) {class_properties=in_prop;} void check_type(); virtual bool is_fwd() {return false;} virtual void read(DeviceImpl *,Attribute &) {}; virtual void write(DeviceImpl *,WAttribute &) {}; virtual bool is_allowed(DeviceImpl *,AttReqType) {return true;} virtual bool same_type(const type_info &) {return false;} virtual string get_enum_type() {return string("Unknown");} #ifndef TANGO_HAS_LOG4TANGO friend ostream &operator<<(ostream &,const Attr &); #endif protected: /// @privatesection string name; Tango::AttrDataFormat format; Tango::AttrWriteType writable; long type; string assoc_name; bool mem; bool mem_init; // // Ported from the extension class // Tango::DispLevel disp_level; // Display level long poll_period; // Polling period bool fire_change_event; bool fire_archive_event; bool check_change_event; bool check_archive_event; bool fire_dr_event; vector class_properties; vector user_default_properties; void convert_def_prop(const string &, double &); void validate_def_prop(const string &, const char *); void validate_def_change_prop(const string &, const char *); void throw_incoherent_def_prop(const char *, const char *); void throw_invalid_def_prop(const char *, const char *); private: class AttrExt { public: AttrExt() {} }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else AttrExt *ext; #endif string cl_name; }; /** * User class to create a one dimension attribute object. * * Information from this class and information fetched out from the Tango * database allows the Tango core software to create the Attribute object * for the attribute created by the user. * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class SpectrumAttr: public Attr { public: /**@name Constructors * Two constructors are defined for this class */ //@{ /** * Constructs a newly allocated SpectrumAttr object. * The attribute display level is set to OPERATOR. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param max_x The attribute maximum x dimension * */ SpectrumAttr(const char *name,long data_type,long max_x); /** * Constructs a newly allocated SpectrumAttr object. * The attribute display level is set to OPERATOR. * * @param name The attribute name * @param data_type The attribute data type * @param w_type The attribute write type (READ, WRITE, READ_WRITE) * @param max_x The attribute maximum x dimension * */ SpectrumAttr(const char *name,long data_type,Tango::AttrWriteType w_type,long max_x); /** * Constructs a newly allocated SpectrumAttr object. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param max_x The attribute maximum x dimension * @param level The attribute display type * */ SpectrumAttr(const char *name,long data_type,long max_x,DispLevel level); /** * Constructs a newly allocated SpectrumAttr object. * * @param name The attribute name * @param data_type The attribute data type * @param w_type The attribute write type (READ, WRITE, READ_WRITE) * @param max_x The attribute maximum x dimension * @param level The attribute display type * */ SpectrumAttr(const char *name,long data_type,Tango::AttrWriteType w_type,long max_x,DispLevel level); SpectrumAttr(const char *_n):Attr(_n) {} //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The object desctructor. */ ~SpectrumAttr() {} //@} /// @privatesection SpectrumAttr(const SpectrumAttr &); long get_max_x() {return max_x;} protected: long max_x; private: class SpectrumAttrExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else SpectrumAttrExt *ext; #endif }; /** * User class to create a two dimensions attribute object. * * Information from this class and information fetched out from the Tango * database allows the Tango core software to create the Attribute object * for the attribute created by the user. * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class ImageAttr: public SpectrumAttr { public: /**@name Constructors * Two constructors are defined for this class */ //@{ /** * Constructs a newly allocated ImageAttr object. * The attribute display level is set to OPERATOR. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param max_x The attribute maximum x dimension * @param max_y The attribute maximum y dimension * */ ImageAttr(const char *name,long data_type,long max_x, long max_y); /** * Constructs a newly allocated ImageAttr object. * The attribute display level is set to OPERATOR. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param w_type The attribute write type (READ, WRITE, READ_WRITE) * @param max_x The attribute maximum x dimension * @param max_y The attribute maximum y dimension * */ ImageAttr(const char *name,long data_type,Tango::AttrWriteType w_type,long max_x, long max_y); /** * Constructs a newly allocated ImageAttr object. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param max_x The attribute maximum x dimension * @param max_y The attribute maximum y dimension * @param level The attribute display type * */ ImageAttr(const char *name,long data_type,long max_x, long max_y, Tango::DispLevel level); /** * Constructs a newly allocated ImageAttr object. * The attribute write type is set to READ * * @param name The attribute name * @param data_type The attribute data type * @param w_type The attribute write type (READ, WRITE, READ_WRITE) * @param max_x The attribute maximum x dimension * @param max_y The attribute maximum y dimension * @param level The attribute display type * */ ImageAttr(const char *name,long data_type,Tango::AttrWriteType w_type, long max_x, long max_y, Tango::DispLevel level); ImageAttr(const char *name):SpectrumAttr(name) {} //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The object desctructor. */ ~ImageAttr() {} //@} /// @privatesection ImageAttr(const ImageAttr &); long get_max_y() {return max_y;} protected: /// @privatesection long max_y; private: class ImageAttrExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else ImageAttrExt *ext; #endif }; } // End of Tango namespace #endif /* _ATTRDESC_H */ tango-9.2.5a/lib/cpp/server/attribute.h0000644023471100065110000030347013034745002014745 00000000000000 //=================================================================================================================== // // file : Attribute.h // // description : Include file for the Attribute classes. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28853 $ // //==================================================================================================================== #ifndef _ATTRIBUTE_H #define _ATTRIBUTE_H #include #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #endif namespace Tango { // // Binary function objects to be used by the find_if algorithm. // The find_if algo. want to have a predicate, this means that the return value // must be a boolean (R is its name). // The test is done between a AttrProperty object (name A1) and a string (name A2) // The find_if algo. needs a unary predicate. This function object is a binary // function object. It must be used with the bind2nd function adapter // template struct WantedProp : public binary_function { R operator() (A1 att,A2 name_str) const { return att.get_name() == name_str; } }; template struct WantedAttr : public binary_function { R operator() (A1 attr_ptr, A2 name) const { string st(name); if (st.size() != attr_ptr->get_name_size()) return false; transform(st.begin(),st.end(),st.begin(),::tolower); return attr_ptr->get_name_lower() == st; } }; class AttrProperty; class DeviceClass; typedef union _Attr_CheckVal { short sh; DevLong lg; double db; float fl; unsigned short ush; unsigned char uch; DevLong64 lg64; DevULong ulg; DevULong64 ulg64; DevState d_sta; }Attr_CheckVal; typedef union _Attr_Value { DevVarShortArray *sh_seq; DevVarLongArray *lg_seq; DevVarFloatArray *fl_seq; DevVarDoubleArray *db_seq; DevVarStringArray *str_seq; DevVarUShortArray *ush_seq; DevVarBooleanArray *boo_seq; DevVarCharArray *cha_seq; DevVarLong64Array *lg64_seq; DevVarULongArray *ulg_seq; DevVarULong64Array *ulg64_seq; DevVarStateArray *state_seq; DevVarEncodedArray *enc_seq; }Attr_Value; typedef struct last_attr_value { bool inited; Tango::AttrQuality quality; CORBA::Any value; bool err; DevFailed except; AttrValUnion value_4; } LastAttrValue; typedef enum prop_type { MIN_VALUE = 0, MAX_VALUE, MIN_WARNING, MAX_WARNING, MIN_ALARM, MAX_ALARM } PropType; class EventSupplier; //============================================================================= // // The Attribute class // // // description : There is one instance of this class for each attribute // for each device. This class stores the attribute // properties and the attribute value. // //============================================================================= /** * This class represents a Tango attribute. * * $Author: taurel $ * $Revision: 28853 $ * * @headerfile tango.h * @ingroup Server */ class Attribute { public: /// @privatesection enum alarm_flags { min_level, max_level, rds, min_warn, max_warn, numFlags }; struct CheckOneStrProp { DbData *db_d; long *prop_to_update; DbData *db_del; long *prop_to_delete; vector *def_user_prop; vector *def_class_prop; }; enum _DbAction { UPD = 0, UPD_FROM_DB, UPD_FROM_VECT_STR, DEL }; typedef _DbAction DbAction; struct _AttPropDb { string name; DbAction dba; string db_value; vector db_value_db; vector db_value_v_str; }; typedef _AttPropDb AttPropDb; /// @publicsection /**@name Constructors * Miscellaneous constructors */ //@{ /** * Create a new Attribute object. * * @param prop_list The attribute properties list. Each property is an object * of the AttrProperty class * @param tmp_attr Temporary attribute object built from user parameters * @param dev_name The device name * @param idx The index of the related Attr object in the MultiClassAttribute * vector of Attr object */ Attribute(vector &prop_list,Attr &tmp_attr,string &dev_name,long idx); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The attribute destructor. */ virtual ~Attribute(); //@} /**@name Check attribute methods * Miscellaneous method returning boolean flag according to attribute state */ //@{ /** * Check if the attribute has an associated writable attribute. * * This method returns a boolean set to true if the attribute has a writable * attribute associated to it. * * @return A boolean set to true if there is an associated writable attribute */ bool is_writ_associated(); /** * Check if the attribute is in minimum alarm condition . * * @return A boolean set to true if the attribute is in alarm condition (read * value below the min. alarm). */ bool is_min_alarm() {return alarm.test(min_level);} /** * Check if the attribute is in maximum alarm condition . * * @return A boolean set to true if the attribute is in alarm condition (read * value above the max. alarm). */ bool is_max_alarm() {return alarm.test(max_level);} /** * Check if the attribute is in minimum warning condition . * * @return A boolean set to true if the attribute is in warning condition (read * value below the min. warning). */ bool is_min_warning() {return alarm.test(min_warn);} /** * Check if the attribute is in maximum warning condition . * * @return A boolean set to true if the attribute is in warning condition (read * value above the max. warning). */ bool is_max_warning() {return alarm.test(max_warn);} /** * Check if the attribute is in RDS alarm condition . * * @return A boolean set to true if the attribute is in RDS condition (Read * Different than Set). */ bool is_rds_alarm() {return alarm.test(rds);} /** * Check if the attribute has an alarm defined. * * This method returns a set of bits. Each alarm type is defined by one * bit. * * @return A bitset. Each bit is set if the coresponding alarm is on */ bitset &is_alarmed() {return alarm_conf;} /** * Check if the attribute is polled . * * @return A boolean set to true if the attribute is polled. */ bool is_polled(); /** * Check if the attribute read value is below/above the alarm level. * * @return A boolean set to true if the attribute is in alarm condition. * @exception DevFailed If no alarm level is defined. * Click here to read * DevFailed exception specification */ bool check_alarm(); //@} /**@name Get/Set object members. * These methods allow the external world to get/set DeviceImpl instance * data members */ //@{ /** * Get the attribute writable type (RO/WO/RW). * * @return The attribute write type. */ Tango::AttrWriteType get_writable() {return writable;} /** * Get attribute name * * @return The attribute name */ string &get_name() {return name;} /** * Get attribute data type * * @return The attribute data type */ long get_data_type() {return data_type;} /** * Get attribute data format * * @return The attribute data format */ Tango::AttrDataFormat get_data_format() {return data_format;} /** * Get name of the associated writable attribute * * @return The associated writable attribute name */ string &get_assoc_name() {return writable_attr_name;} /** * Get index of the associated writable attribute * * @return The index in the main attribute vector of the associated writable * attribute */ long get_assoc_ind() {return assoc_ind;} /** * Set index of the associated writable attribute * * @param val The new index in the main attribute vector of the associated writable * attribute */ void set_assoc_ind(long val) {assoc_ind = val;} /** * Get attribute date * * @return The attribute date */ Tango::TimeVal &get_date() {return when;} /** * Set attribute date * * @param new_date The attribute date */ void set_date(Tango::TimeVal &new_date) {when = new_date;} #ifdef _TG_WINDOWS_ /** * Set attribute date * * @param The attribute date */ void set_date(struct _timeb &t) {when.tv_sec=(long)t.time;when.tv_usec=(t.millitm*1000);when.tv_nsec=0;} #endif /** * Set attribute date * * @param t The attribute date */ void set_date(struct timeval &t) {when.tv_sec=t.tv_sec;when.tv_usec=t.tv_usec;when.tv_nsec=0;} /** * Set attribute date * * @param new_date The attribute date */ void set_date(time_t new_date) {when.tv_sec=(long)new_date;when.tv_usec=0;when.tv_nsec=0;} /** * Get attribute label property * * @return The attribute label */ string &get_label() {return label;} /** * Get attribute data quality * * @return The attribute data quality */ Tango::AttrQuality &get_quality() {return quality;} /** * Set attribute data quality * * @param qua The new attribute data quality * @param send_event Boolean set to true if a change event should be sent */ void set_quality(Tango::AttrQuality qua, bool send_event=false); /** * Get attribute data size * * @return The attribute data size */ long get_data_size() {return data_size;} /** * Get attribute data size in x dimension * * @return The attribute data size in x dimension. Set to 1 for scalar attribute */ long get_x() {return dim_x;} /** * Get attribute maximum data size in x dimension * * @return The attribute maximum data size in x dimension. Set to 1 for scalar attribute */ long get_max_dim_x() {return max_x;} /** * Get attribute data size in y dimension * * @return The attribute data size in y dimension. Set to 0 for scalar and * spectrum attribute */ long get_y() {return dim_y;} /** * Get attribute maximum data size in y dimension * * @return The attribute maximum data size in y dimension. Set to 0 for scalar and * spectrum attribute */ long get_max_dim_y() {return max_y;} /** * Get attribute polling period * * @return The attribute polling period in mS. Set to 0 when the attribute is * not polled */ long get_polling_period() {return poll_period;} /** * Get all modifiable attribute properties in one call * * This method initializes the members of a MultiAttrProp object with the modifiable * attribute properties values * * @param props A MultiAttrProp object. */ template void get_properties(Tango::MultiAttrProp &props); /** * Set all modifiable attribute properties in one call * * This method sets the modifiable attribute properties with the values * provided as members of MultiAttrProps object * * @param props A MultiAttrProp object. */ template void set_properties(Tango::MultiAttrProp &props); /** * Set attribute serialization model * * This method allows the user to choose the attribute serialization * model. * * @param ser_model The new serialisation model. The serialization model must be * one of ATTR_BY_KERNEL, ATTR_BY_USER or ATTR_NO_SYNC */ void set_attr_serial_model(AttrSerialModel ser_model); /** * Get attribute serialization model * * Get the attribute serialization model * * @return The attribute serialization model */ AttrSerialModel get_attr_serial_model() {return attr_serial_model;} /** * Set attribute user mutex * * This method allows the user to give to the attribute object the pointer to * the omni_mutex used to protect its buffer. The mutex has to be locked when passed * to this method. The Tango kernel will unlock it when the data will be transferred * to the client. * * @param mut_ptr The user mutex pointer */ void set_user_attr_mutex(omni_mutex *mut_ptr) {ext->user_attr_mutex = mut_ptr;} //@} /**@name Set attribute value methods. * These methods allows the external world to set attribute object internal * value */ //@{ /** * Set internal attribute value (for Tango::DevShort attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevShort *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevLong attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevLong *p_data,long x = 1, long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevLong64 attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevLong64 *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevFloat attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevFloat *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevDouble attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevDouble *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevString attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevString *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevBoolean attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevBoolean *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevUShort attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevUShort *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevUChar attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevUChar *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevULong attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevULong *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevULong64 attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevULong64 *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevState attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevState *p_data,long x = 1,long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevEncoded attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data The attribute read value * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevEncoded *p_data,long x = 1, long y = 0,bool release = false); /** * Set internal attribute value (for Tango::DevEncoded attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param p_data_str The attribute string part read value * @param p_data The attribute raw data part read value * @param size Size of the attribute raw data part * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::DevString *p_data_str,Tango::DevUChar *p_data,long size,bool release = false); /** * Set internal attribute value (for Tango::DevEncoded attribute data type). * * This method stores the attribute read value inside the object. This data will be * returned to the caller. This method also stores the date when it is called * and initialise the attribute quality factor. * * @param attr Handle to EncodedAttribute object * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value(Tango::EncodedAttribute *attr); //--------------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevShort attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevShort *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevShort attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevLong attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevLong *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevLong attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevLong64 attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevLong64 *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevLong64 attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevFloat attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevFloat *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevFloat attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevDouble attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevDouble *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevDouble attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevString attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevString *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevString attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevBoolean attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevBoolean *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevBoolean attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevUShort attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevUShort *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevUShort attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevUChar attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevUChar *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevUChar attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevULong attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevULong *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevULong attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevULong64 attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevULong64 *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevULong64 attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevState attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevState *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevState attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); #endif //----------------------------------------------------------------------- /** * Set internal attribute value, date and quality factor (for Tango::DevEncoded attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevEncoded *p_data, time_t t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); /** * Set internal attribute value, date and quality factor (for Tango::DevEncoded attribute data type * when splitted in format and data). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * @param p_data_str The attribute coded format string * @param p_data The attribute raw data * @param size Size of the attribute raw data part * @param t The date * @param qual The attribute quality factor * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevString *p_data_str, Tango::DevUChar *p_data, long size, time_t t, Tango::AttrQuality qual, bool release = false); #ifdef _TG_WINDOWS_ void set_value_date_quality(Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); void set_value_date_quality(Tango::DevString *p_data_str, Tango::DevUChar *p_data, long size, struct _timeb &t, Tango::AttrQuality qual, bool release = false); #else /** * Set internal attribute value, date and quality factor (for Tango::DevEncoded attribute data type). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data The attribute read value * @param t The date * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0, bool release = false); /** * Set internal attribute value, date and quality factor (for Tango::DevEncoded attribute data type * when splitted in data format and data themselves). * * This method stores the attribute read value, the date and the attribute * quality factor inside the object. This data will be * returned to the caller. * * Please note that for Win32 user, the same method is defined using a * "_timeb" structure instead of a "timeval" structure to set date. * * @param p_data_str The attribute format string * @param p_data The attribute raw data * @param size Size of the attribute raw data part * @param t The date * @param qual The attribute quality factor * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void set_value_date_quality(Tango::DevString *p_data_str, Tango::DevUChar *p_data, long size, struct timeval &t, Tango::AttrQuality qual, bool release = false); #endif /** * Fire a change event for the attribute value. The event is pushed to the notification * daemon. * The attibute data must be set with one of the Attribute::set_value or * Attribute::setvalue_date_quality methods before fireing the event. * The event is triggered with or without the change event criteria depending * on the configuration choosen with set_change_event(). * ATTENTION: The couple set_value() and fire_change_event() needs to be protected * against concurrent accesses to the same attribute. Such an access might happen during * a synchronous read or by a reading from the polling thread. * Inside all methods reading or writing commands and attributes this protection is * automatically done by the Tango serialisation monitor. * When fireing change events in your own code, you should use the push_change_event * methods of the DeviceImpl class or protect your code with the * Tango::AutoTangoMonitor on your device. * Example: * * { * Tango::AutoTangoMonitor synch(this); * att_temp_seq.set_value (temp_seq, 100); * att_temp_seq.fire_archive_event (); * } * * @param except A pointer to a DevFailed exception to be thrown as archive event. */ void fire_change_event(DevFailed *except = NULL); /** * Set a flag to indicate that the server fires change events manually, without * the polling to be started for the attribute. * If the detect parameter is set to true, the criteria specified for the change * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without any value checking! * * @param implemented True when the server fires change events manually. * @param detect Triggers the verification of the change event properties when set to true. */ void set_change_event(bool implemented, bool detect = true) { change_event_implmented = implemented; check_change_event_criteria = detect; if(detect==false){ prev_change_event.err=false; prev_change_event.quality=Tango::ATTR_VALID;}} /** * Check if the change event is fired manually (without polling) for this attribute. * * @return A boolean set to true if a manual fire change event is implemented. */ bool is_change_event() {return change_event_implmented;} /** * Check if the change event criteria should be checked when firing * the event manually. * * @return A boolean set to true if a change event criteria will be checked. */ bool is_check_change_criteria() {return check_change_event_criteria;} /** * Fire an archive event for the attribute value. The event is pushed to the notification * daemon. * The attibute data must be set with one of the Attribute::set_value or * Attribute::setvalue_date_quality methods before fireing the event. * The event is triggered with or without the archive event criteria depending * on the configuration choosen with set_archive_event(). * ATTENTION: The couple set_value() and fire_archive_event() needs to be protected * against concurrent accesses to the same attribute. Such an access might happen during * a synchronous read or by a reading from the polling thread. * Inside all methods reading or writing commands and attributes this protection is * automatically done by the Tango serialisation monitor. * When fireing archive events in your own code, you should use the push_archive_event * methods of the DeviceImpl class or protect your code with the * Tango::AutoTangoMonitor on your device. * Example: * * { * Tango::AutoTangoMonitor synch(this); * att_temp_seq.set_value (temp_seq, 100); * att_temp_seq.fire_archive_event (); * } * * @param except A pointer to a DevFailed exception to be thrown as archive event. */ void fire_archive_event(DevFailed *except = NULL); /** * Set a flag to indicate that the server fires archive events manually, without * the polling to be started for the attribute * If the detect parameter is set to true, the criteria specified for the archive * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without any value checking! * * @param implemented True when the server fires archive events manually. * @param detect Triggers the verification of the archive event properties when set to true. */ void set_archive_event(bool implemented, bool detect = true) {archive_event_implmented = implemented; check_archive_event_criteria = detect; if(detect==false){ prev_archive_event.err=false; prev_archive_event.quality=Tango::ATTR_VALID;}} /** * Check if the archive event is fired manually for this attribute. * * @return A boolean set to true if a manual fire archive event is implemented. */ bool is_archive_event() {return archive_event_implmented;} /** * Check if the archive event criteria should be checked when firing * the event manually. * * @return A boolean set to true if a archive event criteria will be checked. */ bool is_check_archive_criteria() {return check_archive_event_criteria;} /** * Set a flag to indicate that the server fires data ready events * * @param implemented True when the server fires change events manually. */ void set_data_ready_event(bool implemented) {dr_event_implmented = implemented;} /** * Check if the data ready event is fired for this attribute. * * @return A boolean set to true if a fire data ready event is implemented. */ bool is_data_ready_event() {return dr_event_implmented;} /** * Fire a user event for the attribute value. The event is pushed to the notification * daemon. * The attibute data must be set with one of the Attribute::set_value or * Attribute::setvalue_date_quality methods before fireing the event. * ATTENTION: The couple set_value() and fire_event() needs to be protected * against concurrent accesses to the same attribute. Such an access might happen during * a synchronous read or by a reading from the polling thread. * Inside all methods reading or writing commands and attributes this protection is * automatically done by the Tango serialisation monitor. * When fireing archive events in your own code, you should use the push_event * methods of the DeviceImpl class or protect your code with the * Tango::AutoTangoMonitor on your device. * Example: * * { * Tango::AutoTangoMonitor synch(this); * att_temp_seq.set_value (temp_seq, 100); * att_temp_seq.fire_event (); * } * * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param except A pointer to a DevFailed exception to be thrown as archive event. */ void fire_event(vector &filt_names,vector &filt_vals,DevFailed *except = NULL); /** * Remove the attribute configuration from the database. * This method can be used to clean-up all the configuration of an attribute to come back to * its default values or the remove all configuration of a dynamic attribute before deleting it. * * The method removes all configured attribute properties and removes the attribute from the * list of polled attributes. * * @exception DevFailed In case of database access problems. * Click here to read * DevFailed exception specification */ void remove_configuration(); //@} /**@name Set/Get attribute ranges (min_alarm, min_warning, max_warning, max_alarm) methods. * These methods allow the external world to set attribute object min_alarm, min_warning, * max_warning and max_alarm values */ //@{ /** * Set attribute minimum alarm. * * This method sets the attribute minimum alarm. * * @param new_min_alarm The new attribute minimum alarm value * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ template void set_min_alarm(const T &new_min_alarm); void set_min_alarm(char *new_min_alarm); void set_min_alarm(const char *new_min_alarm); /** * Get attribute minimum alarm or throw an exception if the attribute * does not have the minimum alarm * * @param min_al Reference to a variable which value will be set to the attribute's * minimum alarm */ template void get_min_alarm(T &min_al); /** * Set attribute maximum alarm. * * This method sets the attribute maximum alarm. * * @param new_max_alarm The new attribute maximum alarm value * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ template void set_max_alarm(const T &new_max_alarm); void set_max_alarm(char *new_max_alarm); void set_max_alarm(const char *new_max_alarm); /** * Get attribute maximum alarm or throw an exception if the attribute * does not have the maximum alarm set * * @param max_al Reference to a variable which value will be set to the attribute's * maximum alarm */ template void get_max_alarm(T &max_al); /** * Set attribute minimum warning. * * This method sets the attribute minimum warning. * * @param new_min_warning The new attribute minimum warning value * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ template void set_min_warning(const T &new_min_warning); void set_min_warning(char *new_min_warning); void set_min_warning(const char *new_min_warning); /** * Get attribute minimum warning or throw an exception if the attribute * does not have the minimum warning set * * @param min_war Reference to a variable which value will be set to the attribute's * minimum warning */ template void get_min_warning(T &min_war); /** * Set attribute maximum warning. * * This method sets the attribute maximum warning. * * @param new_max_warning The new attribute maximum warning value * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ template void set_max_warning(const T &new_max_warning); void set_max_warning(char *new_max_warning); void set_max_warning(const char *new_max_warning); /** * Get attribute maximum warning or throw an exception if the attribute * does not have the maximum warning set * * @param max_war Reference to a variable which value will be set to the attribute's * maximum warning */ template void get_max_warning(T &max_war); //@} protected: /**@name Class data members */ //@{ /** * A flag set to true if the attribute value has been updated */ bool value_flag; /** * The date when attribute was read */ Tango::TimeVal when; /** * Flag set to true if the date must be set */ bool date; /** * The attribute quality factor */ Tango::AttrQuality quality; /** * The attribute name */ string name; /** * The attribute writable flag */ Tango::AttrWriteType writable; /** * The attribute data type. * * Forteen types are suported. They are Tango::DevShort, Tango::DevUShort, Tango::DevLong, Tango::DevULong, * Tango::DevLong64, Tango::DevULong64, Tango::DevDouble, Tango::DevString, , Tango::DevUChar, * Tango::DevFloat, Tango::DevBoolean, Tango::DevState, Tango::DevEncoded and Tango::DevEnum */ long data_type; /** * The attribute data format. * * Three data formats are supported. They are SCALAR, SPECTRUM and IMAGE */ Tango::AttrDataFormat data_format; /** * The attribute maximum x dimension. * * It is needed for SPECTRUM or IMAGE data format */ long max_x; /** * The attribute maximum y dimension. * * It is necessary only for IMAGE data format */ long max_y; /** * The attribute label */ string label; /** * The attribute description */ string description; /** * The attribute unit */ string unit; /** * The attribute standard unit */ string standard_unit; /** * The attribute display unit */ string display_unit; /** * The attribute format. * * This string specifies how an attribute value must be printed */ string format; /** * The name of the associated writable attribute */ string writable_attr_name; /** * The attribute minimum alarm level */ string min_alarm_str; /** * The attribute maximun alarm level */ string max_alarm_str; /** * The attribute minimum value */ string min_value_str; /** * The attribute maximum value */ string max_value_str; /** * The attribute minimun warning */ string min_warning_str; /** * The attribute maximum warning */ string max_warning_str; /** * The attribute delta value RDS alarm */ string delta_val_str; /** * The attribute delta time RDS alarm */ string delta_t_str; /** * Index in the main attribute vector of the associated writable attribute (if any) */ long assoc_ind; /** * The attribute minimum alarm in binary format */ Tango::Attr_CheckVal min_alarm; /** * The attribute maximum alarm in binary format */ Tango::Attr_CheckVal max_alarm; /** * The attribute minimum warning in binary format */ Tango::Attr_CheckVal min_warning; /** * The attribute maximum warning in binary format */ Tango::Attr_CheckVal max_warning; /** * The attribute minimum value in binary format */ Tango::Attr_CheckVal min_value; /** * The attribute maximum value in binary format */ Tango::Attr_CheckVal max_value; /** * The attribute value */ Tango::Attr_Value value; /** * The attribute data size */ long data_size; /** * Flag set to true if a minimum value is defined */ bool check_min_value; /** * Flag set to true if a maximum alarm is defined */ bool check_max_value; /** * Authorized delta between the last written value and the * actual read. Used if the attribute has an alarm on * Read Different Than Set (RDS) */ Tango::Attr_CheckVal delta_val; /** * Delta time after which the read value must be checked again the * last written value if the attribute has an alarm on * Read Different Than Set (RDS) */ long delta_t; /** * Enumeration labels when the attribute data type is DevEnum */ vector enum_labels; //@} public: /// @privatesection template void set_value(T *,long x = 1,long y = 0,bool release = false); template void set_value_date_quality(T *,time_t,Tango::AttrQuality,long x=1,long y=0,bool rel=false); #ifdef _TG_WINDOWS_ template void set_value_date_quality(T *,struct _timeb &,Tango::AttrQuality,long x=1,long y=1,bool rel=false); #else template void set_value_date_quality(T *,struct timeval &,Tango::AttrQuality,long x=1,long y=1,bool rel=false); #endif // // methods not usable for the external world (outside the lib) // void get_properties(Tango::AttributeConfig &); void get_properties(Tango::AttributeConfig_2 &); void get_properties(Tango::AttributeConfig_3 &); void get_properties(Tango::AttributeConfig_5 &); void set_properties(const Tango::AttributeConfig &,string &,bool,vector &); void set_properties(const Tango::AttributeConfig_3 &,string &,bool,vector &); void set_properties(const Tango::AttributeConfig_5 &,string &,bool,vector &); void upd_database(vector &); void get_prop(Tango::AttributeConfig_3 &_a) {get_properties(_a);} void get_prop(Tango::AttributeConfig_5 &_a) {get_properties(_a);} vector &get_enum_labels() {return enum_labels;} template void set_upd_properties(const T &_c) {set_upd_properties(_c,d_name);} template void set_upd_properties(const T &,string &,bool f_s=false); virtual void set_rvalue() {}; void delete_seq(); bool check_scalar_wattribute(); void wanted_date(bool flag) {date = flag;} bool get_wanted_date() {return date;} Tango::TimeVal &get_when() {return when;} void set_time(); Tango::DevVarShortArray *get_short_value() {return value.sh_seq;} Tango::DevVarLongArray *get_long_value() {return value.lg_seq;} Tango::DevVarDoubleArray *get_double_value() {return value.db_seq;} Tango::DevVarStringArray *get_string_value() {return value.str_seq;} Tango::DevVarFloatArray *get_float_value() {return value.fl_seq;} Tango::DevVarBooleanArray *get_boolean_value() {return value.boo_seq;} Tango::DevVarUShortArray *get_ushort_value() {return value.ush_seq;} Tango::DevVarCharArray *get_uchar_value() {return value.cha_seq;} Tango::DevVarLong64Array *get_long64_value() {return value.lg64_seq;} Tango::DevVarULongArray *get_ulong_value() {return value.ulg_seq;} Tango::DevVarULong64Array *get_ulong64_value() {return value.ulg64_seq;} Tango::DevVarStateArray *get_state_value() {return value.state_seq;} Tango::DevVarEncodedArray *get_encoded_value() {return value.enc_seq;} Tango::DevLong64 *get_tmp_scalar_long64() {return tmp_lo64;} Tango::DevULong *get_tmp_scalar_ulong() {return tmp_ulo;} Tango::DevULong64 *get_tmp_scalar_ulong64() {return tmp_ulo64;} Tango::DevState *get_tmp_scalar_state() {return tmp_state;} void add_write_value(Tango::DevVarShortArray *); void add_write_value(Tango::DevVarLongArray *); void add_write_value(Tango::DevVarDoubleArray *); void add_write_value(Tango::DevVarStringArray *); void add_write_value(Tango::DevVarFloatArray *); void add_write_value(Tango::DevVarBooleanArray *); void add_write_value(Tango::DevVarUShortArray *); void add_write_value(Tango::DevVarCharArray *); void add_write_value(Tango::DevVarLong64Array *); void add_write_value(Tango::DevVarULongArray *); void add_write_value(Tango::DevVarULong64Array *); void add_write_value(Tango::DevVarStateArray *); void add_write_value(Tango::DevEncoded &); unsigned long get_name_size() {return name_size;} string &get_name_lower() {return name_lower;} void set_value_flag(bool val) {value_flag = val;} bool get_value_flag() {return value_flag;} DispLevel get_disp_level() {return disp_level;} omni_mutex *get_attr_mutex() {return &(ext->attr_mutex);} omni_mutex *get_user_attr_mutex() {return ext->user_attr_mutex;} bool change_event_subscribed(); bool periodic_event_subscribed(); bool archive_event_subscribed(); bool quality_event_subscribed(); bool user_event_subscribed(); bool attr_conf_event_subscribed(); bool data_ready_event_subscribed(); bool use_notifd_event() {return notifd_event;} bool use_zmq_event() {return zmq_event;} // // Warning, methods below are not protected ! // void set_change_event_sub(int); time_t get_change5_event_sub() {return event_change5_subscription;} void set_periodic_event_sub(int); time_t get_periodic5_event_sub() {return event_periodic5_subscription;} void set_archive_event_sub(int); time_t get_archive5_event_sub() {return event_archive5_subscription;} void set_quality_event_sub() {event_quality_subscription=time(NULL);} time_t get_quality_event_sub() {return event_quality_subscription;} void set_user_event_sub(int); time_t get_user5_event_sub() {return event_user5_subscription;} void set_att_conf_event_sub(int); void set_data_ready_event_sub() {event_data_ready_subscription=time(NULL);} time_t get_data_ready_event_sub() {return event_data_ready_subscription;} // End of warning void set_use_notifd_event() {notifd_event = true;} void set_use_zmq_event() {zmq_event = true;} long get_attr_idx() {return idx_in_attr;} void set_attr_idx(long new_idx) {idx_in_attr=new_idx;} DeviceImpl *get_att_device(); template void Attribute_2_AttributeValue_base(T *,Tango::DeviceImpl *); void Attribute_2_AttributeValue(Tango::AttributeValue_3 *,DeviceImpl *); void Attribute_2_AttributeValue(Tango::AttributeValue_4 *,DeviceImpl *); void Attribute_2_AttributeValue(Tango::AttributeValue_5 *,DeviceImpl *); template void AttrValUnion_fake_copy(const T *,V *); template void AttrValUnion_2_Any(const T *,CORBA::Any &); void AttributeValue_4_2_AttributeValue_3(const Tango::AttributeValue_4 *,Tango::AttributeValue_3 *); void AttributeValue_5_2_AttributeValue_3(const Tango::AttributeValue_5 *,Tango::AttributeValue_3 *); void AttributeValue_3_2_AttributeValue_4(const Tango::AttributeValue_3 *,Tango::AttributeValue_4 *); void AttributeValue_5_2_AttributeValue_4(const Tango::AttributeValue_5 *,Tango::AttributeValue_4 *); void AttributeValue_3_2_AttributeValue_5(const Tango::AttributeValue_3 *,Tango::AttributeValue_5 *); void AttributeValue_4_2_AttributeValue_5(const Tango::AttributeValue_4 *,Tango::AttributeValue_5 *); void AttributeConfig_5_2_AttributeConfig_3(const Tango::AttributeConfig_5 &,Tango::AttributeConfig_3 &); void AttributeConfig_3_2_AttributeConfig_5(const Tango::AttributeConfig_3 &,Tango::AttributeConfig_5 &); void AttributeConfig_5_2_AttributeConfig_3(const Tango::AttributeConfig_3 &,Tango::AttributeConfig_3 &) {} // Templ void AttributeConfig_3_2_AttributeConfig_5(const Tango::AttributeConfig_5 &,Tango::AttributeConfig_5 &) {} // Templ void set_mcast_event(vector &vs) {mcast_event.clear();copy(vs.begin(),vs.end(),back_inserter(mcast_event));} bool is_polled(DeviceImpl *); void set_polling_period(long per) {poll_period = per;} void save_alarm_quality() {old_quality=quality;old_alarm=alarm;} bool is_startup_exception() {return check_startup_exceptions;} void throw_startup_exception(const char*); bool is_mem_exception() {return att_mem_exception;} virtual bool is_fwd_att() {return false;} void set_client_lib(int,string &); vector &get_client_lib(EventType _et) {return client_lib[_et];} void remove_client_lib(int,const string &); void add_config_5_specific(AttributeConfig_5 &); void add_startup_exception(string,const DevFailed &); void fire_error_periodic_event(DevFailed *); #ifndef TANGO_HAS_LOG4TANGO friend ostream &operator<<(ostream &,Attribute &); #endif // TANGO_HAS_LOG4TANGO friend class EventSupplier; friend class ZmqEventSupplier; friend class DServer; private: void set_data_size(); void throw_min_max_value(string &,string &,MinMaxValueCheck); void log_quality(); inline void init_string_prop(vector &prop_list, string& attr, const char* attr_name) { try { attr = get_attr_value(prop_list, attr_name); } catch (DevFailed &e) { add_startup_exception(attr_name,e); } } inline bool is_value_set(const char* attr_name) { if (!strcmp(attr_name,"min_alarm")) return alarm_conf.test(max_level); else if (!strcmp(attr_name,"max_alarm")) return alarm_conf.test(min_level); else if (!strcmp(attr_name,"min_value")) return check_max_value; else if (!strcmp(attr_name,"max_value")) return check_min_value; else if (!strcmp(attr_name,"min_warning")) return alarm_conf.test(max_warn); else if (!strcmp(attr_name,"max_warning")) return alarm_conf.test(min_warn); else return false; } bool init_check_val_prop(vector &,string &,const char *,string &,Tango::Attr_CheckVal &,Tango::Attr_CheckVal &); unsigned long name_size; string name_lower; DevEncoded enc_help; protected: /// @privatesection // // The extension class // class AttributeExt { public: AttributeExt() : user_attr_mutex(NULL) {} omni_mutex attr_mutex; // Mutex to protect the attributes shared data buffer omni_mutex *user_attr_mutex; // Ptr for user mutex in case he manages exclusion }; AttributeExt *ext; virtual void init_opt_prop(vector &,string &); virtual void init_event_prop(vector &,const string &,Attr &); void init_enum_prop(vector &); string &get_attr_value(vector &,const char *); long get_lg_attr_value(vector &,const char *); virtual bool check_rds_alarm() {return false;} bool check_level_alarm(); bool check_warn_alarm(); void upd_att_prop_db(Tango::Attr_CheckVal &,const char *); DeviceClass *get_att_device_class(string &); template void check_hard_coded_properties(const T &); template void set_hard_coded_properties(const T &); void check_hard_coded(const AttributeConfig_5 &); void delete_startup_exception(string,string str=string("None")); void throw_hard_coded_prop(const char *); void throw_err_format(const char *,const string &,const char *); void throw_incoherent_val_err(const char *,const char *,const string &,const char *); void throw_err_data_type(const char *,const string &,const char *); void validate_change_properties(const string &,const char *,string &,vector &,vector &,vector &); void validate_change_properties(const string &,const char *,string &,vector &); bool prop_in_list(const char *,string &,size_t,vector &); void set_format_notspec(); bool is_format_notspec(const char *); void def_format_in_dbdatum(DbDatum &); void avns_in_db(const char *,string &); void avns_in_att(prop_type); void convert_prop_value(const char *,string &,Attr_CheckVal &,const string &); void check_range_coherency(string &); void db_access(struct CheckOneStrProp &,string &); void set_prop_5_specific(const AttributeConfig_5 &,string &,bool,vector &); void build_check_enum_labels(string &); void set_one_str_prop(const char *,const CORBA::String_member &,string &,vector &,vector &,vector &,const char *); void set_one_alarm_prop(const char *,const CORBA::String_member &,string &,Tango::Attr_CheckVal &, vector &,vector &,vector &,bool &); void set_rds_prop(const AttributeAlarm &,string &,vector &,vector &,vector &); void set_rds_prop_val(const AttributeAlarm &,string &,vector &,vector &); void set_rds_prop_db(const AttributeAlarm &,vector &,vector &,vector &); void set_one_event_prop(const char *,const CORBA::String_member &,double *,vector &,vector &,vector &); void event_prop_db_xxx(vector &,vector &,vector &,AttPropDb &); void set_one_event_period(const char *,const CORBA::String_member &,int &,const int &,vector &,vector &,vector &); bitset alarm_conf; bitset alarm; long dim_x; long dim_y; Tango::DevShort tmp_sh[2]; Tango::DevLong tmp_lo[2]; Tango::DevFloat tmp_fl[2]; Tango::DevDouble tmp_db[2]; Tango::DevString tmp_str[2]; Tango::DevUShort tmp_ush[2]; Tango::DevBoolean tmp_boo[2]; Tango::DevUChar tmp_cha[2]; Tango::DevEncoded tmp_enc[2]; vector::iterator pos_end; int enum_nb; // For enum attribute short *loc_enum_ptr; // For enum attribute // // Ported from the extension class // Tango::DispLevel disp_level; // Display level long poll_period; // Polling period double rel_change[2]; // Delta for relative change events in % double abs_change[2]; // Delta for absolute change events double archive_rel_change[2]; // Delta for relative archive change events in % double archive_abs_change[2]; // Delta for absolute change events int event_period; // Delta for periodic events in ms int archive_period; // Delta for archive periodic events in ms double last_periodic; // Last time a periodic event was detected double archive_last_periodic; // Last time an archive periodic event was detected long periodic_counter; // Number of periodic events sent so far long archive_periodic_counter; // Number of periodic events sent so far LastAttrValue prev_change_event; // Last change attribute LastAttrValue prev_quality_event; // Last quality attribute LastAttrValue prev_archive_event; // Last archive attribute time_t event_change3_subscription; // Last time() a subscription was made time_t event_change4_subscription; time_t event_change5_subscription; time_t event_quality_subscription; // Last time() a subscription was made time_t event_periodic3_subscription; // Last time() a subscription was made time_t event_periodic4_subscription; time_t event_periodic5_subscription; time_t event_archive3_subscription; // Last time() a subscription was made time_t event_archive4_subscription; time_t event_archive5_subscription; time_t event_user3_subscription; // Last time() a subscription was made time_t event_user4_subscription; time_t event_user5_subscription; time_t event_attr_conf_subscription; // Last time() a subscription was made time_t event_attr_conf5_subscription; // Last time() a subscription was made time_t event_data_ready_subscription; // Last time() a subscription was made double archive_last_event; // Last time an archive event was detected (periodic or not) long idx_in_attr; // Index in MultiClassAttribute vector string d_name; // The device name DeviceImpl *dev; // The device object bool change_event_implmented; // Flag true if a manual fire change event is implemented. bool archive_event_implmented; // Flag true if a manual fire archive event is implemented. bool check_change_event_criteria; // True if change event criteria should be checked when sending the event bool check_archive_event_criteria; // True if change event criteria should be checked when sending the event Tango::DevLong64 tmp_lo64[2]; Tango::DevULong tmp_ulo[2]; Tango::DevULong64 tmp_ulo64[2]; Tango::DevState tmp_state[2]; AttrSerialModel attr_serial_model; // Flag for attribute serialization model bool dr_event_implmented; // Flag true if fire data ready event is implemented bool scalar_str_attr_release; // Need memory freeing (scalar string attr, R/W att) bool notifd_event; // Set to true if event required using notifd bool zmq_event; // Set to true if event required using ZMQ vector mcast_event; // In case of multicasting used for event transport AttrQuality old_quality; // Previous attribute quality bitset old_alarm; // Previous attribute alarm map startup_exceptions; // Map containing exceptions related to attribute configuration raised during the server startup sequence bool check_startup_exceptions; // Flag set to true if there is at least one exception in startup_exceptions map bool startup_exceptions_clear; // Flag set to true when the cause for the device startup exceptions has been fixed bool att_mem_exception; // Flag set to true if the attribute is writable and // memorized and if it failed at init vector client_lib[numEventType]; // Clients lib used (for event sending and compat) }; // // Some inline methods // //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::throw_hard_coded_prop // // description : // Throw a "Hard coded properties can't be changed" exception // // args: // in : // - prop_name : The name of the property which should be modified // //-------------------------------------------------------------------------------------------------------------------- inline void Attribute::throw_hard_coded_prop(const char *prop_name) { TangoSys_OMemStream desc; desc << "Attribute property " << prop_name << " is not changeable at run time" << ends; Except::throw_exception((const char *)API_AttrNotAllowed,desc.str(), (const char *)"Attribute::check_hard_coded_properties()"); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::throw_startup_exception // // description : // Throw a startup exception // // args: // in : // - origin : The method name where this method is called from // //------------------------------------------------------------------------------------------------------------------- inline void Attribute::throw_startup_exception(const char* origin) { if(check_startup_exceptions) { string err_msg; vector event_exceptions; vector opt_exceptions; for(map::iterator it = startup_exceptions.begin(); it != startup_exceptions.end(); ++it) { if(it->first == "event_period" || it->first == "archive_period" || it->first == "rel_change" || it->first == "abs_change" || it->first == "archive_rel_change" || it->first == "archive_abs_change") event_exceptions.push_back(it->first); else opt_exceptions.push_back(it->first); for(CORBA::ULong i = 0 ; i < it->second.errors.length(); i++) { string tmp_msg = string(it->second.errors[i].desc); size_t pos = tmp_msg.rfind('\n'); if(pos != string::npos) tmp_msg.erase(0,pos+1); err_msg += "\n" + tmp_msg; } } err_msg = "\nDevice " + d_name + "-> Attribute : " + name + err_msg; if(event_exceptions.size() == startup_exceptions.size()) { if(event_exceptions.size() == 1) err_msg += "\nSetting a valid value (also 'NaN', 'Not specified' and '' - empty string) for any property for this attribute will automatically bring the above-mentioned property to its library defaults"; else err_msg += "\nSetting a valid value (also 'NaN', 'Not specified' and '' - empty string) for any property for this attribute will automatically bring the above-listed properties to their library defaults"; err_msg += "\nHint : Check also class level attribute properties"; } else if(event_exceptions.empty() == false) { if(opt_exceptions.size() == 1) err_msg += "\nSetting valid value (also 'NaN', 'Not specified' and '' - empty string) for " + opt_exceptions[0] + " "; else { err_msg += "\nSetting valid values (also 'NaN', 'Not specified' and '' - empty string) for "; for(size_t i = 0; i < opt_exceptions.size(); i++) err_msg += ((i == (opt_exceptions.size() - 1) && i != 0) ? "and " : "") + opt_exceptions[i] + ((i != (opt_exceptions.size() - 1) && i != (opt_exceptions.size() - 2)) ? "," : "") + " "; } err_msg += "will automatically bring "; for(size_t i = 0; i < event_exceptions.size(); i++) err_msg += ((i == (event_exceptions.size() - 1) && i != 0) ? "and " : "") + event_exceptions[i] + ((i != (event_exceptions.size() - 1) && i != (event_exceptions.size() - 2)) ? "," : "") + " "; if(event_exceptions.size() == 1) err_msg += "to its library defaults"; else err_msg += "to their library defaults"; err_msg += "\nHint : Check also class level attribute properties"; } Except::throw_exception(API_AttrConfig,err_msg,origin); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::prop_in_list // // description : // Search for a property in a list // // args: // in : // - prop_name : The property name // - list_size : The size list // - list : The list // out : // - prop_str : String initialized with prop. value (if found) // //------------------------------------------------------------------------------------------------------------------ inline bool Attribute::prop_in_list(const char *prop_name,string &prop_str,size_t list_size,vector &list) { bool ret = false; if (list_size != 0) { size_t i; for (i = 0;i < list_size;i++) { if (list[i].get_name() == prop_name) break; } if (i != list_size) { prop_str = list[i].get_value(); ret = true; } } return ret; } inline void Attribute::set_change_event_sub(int cl_lib) { switch (cl_lib) { case 5: event_change5_subscription = time(NULL); break; case 4: event_change4_subscription = time(NULL); break; default: event_change3_subscription = time(NULL); break; } } inline void Attribute::set_periodic_event_sub(int cl_lib) { switch (cl_lib) { case 5: event_periodic5_subscription = time(NULL); break; case 4: event_periodic4_subscription = time(NULL); break; default: event_periodic3_subscription = time(NULL); break; } } inline void Attribute::set_archive_event_sub(int cl_lib) { switch (cl_lib) { case 5: event_archive5_subscription = time(NULL); break; case 4: event_archive4_subscription = time(NULL); break; default: event_archive3_subscription = time(NULL); break; } } inline void Attribute::set_user_event_sub(int cl_lib) { switch (cl_lib) { case 5: event_user5_subscription = time(NULL); break; case 4: event_user4_subscription = time(NULL); break; default: event_user3_subscription = time(NULL); break; } } inline void Attribute::set_att_conf_event_sub(int cl_lib) { switch (cl_lib) { case 5: event_attr_conf5_subscription = time(NULL); break; default: event_attr_conf_subscription = time(NULL); break; } } // // Macro to help coding // #define MEM_STREAM_2_CORBA(A,B) \ if (true) \ { \ string s = B.str(); \ A = CORBA::string_dup(s.c_str()); \ B.str(""); \ B.clear(); \ } \ else \ (void)0 // // Throw exception if pointer is null // #define CHECK_PTR(A,B) \ if (A == NULL) \ { \ stringstream o; \ o << "Data pointer for attribute " << B << " is NULL!"; \ Except::throw_exception(API_AttrOptProp,o.str(),"Attribute::set_value()"); \ } \ else \ (void)0 // // Yet another macros !! // Arg list : A : The sequence pointer // B : Index in sequence // C : Attribute reference // #define GIVE_ATT_MUTEX(A,B,C) \ if (true) \ {\ Tango::AttributeValue_4 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->set_attr_mutex(C.get_attr_mutex()); \ } \ else \ (void)0 #define GIVE_ATT_MUTEX_5(A,B,C) \ if (true) \ {\ Tango::AttributeValue_5 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->set_attr_mutex(C.get_attr_mutex()); \ } \ else \ (void)0 #define GIVE_USER_ATT_MUTEX(A,B,C) \ if (true) \ { \ Tango::AttributeValue_4 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->set_attr_mutex(C.get_user_attr_mutex()); \ } \ else \ (void)0 #define GIVE_USER_ATT_MUTEX_5(A,B,C) \ if (true) \ { \ Tango::AttributeValue_5 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->set_attr_mutex(C.get_user_attr_mutex()); \ } \ else \ (void)0 // // Yet another macro !! // Arg list : A : The sequence pointer // B : Index in sequence // C : Attribute reference // #define REL_ATT_MUTEX(A,B,C) \ if (C.get_attr_serial_model() != ATTR_NO_SYNC) \ { \ Tango::AttributeValue_4 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->rel_attr_mutex(); \ } \ else \ (void)0 #define REL_ATT_MUTEX_5(A,B,C) \ if (C.get_attr_serial_model() != ATTR_NO_SYNC) \ { \ Tango::AttributeValue_5 *tmp_ptr = &((*A)[B]); \ (tmp_ptr)->rel_attr_mutex(); \ } \ else \ (void)0 // // Again a macro for clean pointer delete // #define SAFE_DELETE(ptr) \ if (release == true) \ { \ if (is_fwd_att() == true) \ delete [] ptr; \ else \ delete ptr; \ } \ else \ (void)0 } // End of Tango namespace #endif // _ATTRIBUTE_H tango-9.2.5a/lib/cpp/server/attrmanip.h0000644023471100065110000000351113034745001014731 00000000000000//============================================================================= // // file : attrmanip.h // // description : Include for the Tango attribute manipulator // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _ATTRMANIP_H #define _ATTRMANIP_H #include #include namespace Tango { class AttrManip { //#ifndef TANGO_HAS_LOG4TANGO friend ostream &operator<<(ostream &,const AttrManip&); friend void execute_manip(ostream &,string &str); //#endif public: AttrManip(const char *f):format(f) { transform(format.begin(),format.end(),format.begin(),::tolower); } AttrManip(const string &str):format(str) { transform(format.begin(),format.end(),format.begin(),::tolower); } inline const string& to_string (void) const { return format; } private: string format; }; } // End of Tango namespace #endif tango-9.2.5a/lib/cpp/server/attrprop.h0000644023471100065110000004017613034745001014615 00000000000000//================================================================================================================== // // file : AttrProp.h // // description : Include file for the AttrProp, DoubleAttrProp and MultiAttrProp classes. // Three classes are declared in this file : // The AttrProp class // The DoubleAttrProp class // The MultiAttrProp class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 19431 $ // //================================================================================================================== #ifndef _ATTRPROP_H #define _ATTRPROP_H #include namespace Tango { //================================================================================================================= // // The AttrProp class // // description : // This is a template class which holds a value of attribute property and its string representation. // //================================================================================================================= /** * This class represents a Tango attribute property. * * $Author: trogucki $ * $Revision: 19431 $ * * @headerfile tango.h * @ingroup Server */ template class AttrProp { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Default constructor. */ AttrProp() : is_value(false),ext(Tango_nullptr) {} /** * Create a new AttrProp object. * * @param value The attribute property value. */ AttrProp(const T &value) : val(value), is_value(true), ext(Tango_nullptr) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << value; str = st.str(); } /** * Create a new AttrProp object. * * @param value_str The 'C string' representation of attribute property. */ AttrProp(const char *value_str) : str(string(value_str)), is_value(false), ext(Tango_nullptr) {} /** * Create a new AttrProp object. * * @param value_str The string representation of attribute property value. */ AttrProp(const string &value_str) : str(value_str), is_value(false), ext(Tango_nullptr) {} //@} /**@name Assignment operators * These operators allow to assign the value of the property by providing * the value or its string representation. */ //@{ /** * Assign the value of the attribute property. * * @param value A value of the attribute property. * * @return AttrProp object with both value and its string representation set. */ AttrProp &operator=(const T &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << value; str = st.str(); val = value; is_value = true; return *this; } /** * Assign the string representation of the attribute property value. * * @param value_str A 'C string' representation of the attribute property value. * * @return AttrProp object with the string representation of its value set. */ AttrProp &operator=(const char *value_str) { str = value_str; is_value = false; return *this; } /** * Assign the string representation of the attribute property value. * * @param value_str A string representation of the attribute property value. * * @return AttrProp object with the string representation of its value set. */ AttrProp &operator=(const string &value_str) { str = value_str; is_value = false; return *this; } //@} /**@name Get/Set object members. * These methods allow the external world to get/set AttrProp instance * data members */ //@{ /** * Get the attribute property value. * * @return The attribute property value. */ T get_val() { if(is_value == false) { string err_msg = "Numeric representation of the property's value (" + str + ") has not been set"; Tango::Except::throw_exception(API_AttrPropValueNotSet,err_msg,"AttrProp::get_val",Tango::ERR); } return val; } /** * Get string representation of the attribute property value. * * @return The string representation of the attribute property value. */ string &get_str() {return str;} /** * Set the attribute property value. * * The value is automatically converted to its string representation. * * @param value The value of the attribute property. */ void set_val(const T &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << value; str = st.str(); val = value; is_value = true; } /** * Set string representation of the attribute property value. * * @param value_str The the 'C string' representation of the attribute property value. */ void set_str(const char *value_str) {str = string(value_str); is_value = false;} /** * Set string representation of the attribute property value. * * @param value_str The the string representation of the attribute property value. */ void set_str(const string &value_str) {str = value_str; is_value = false;} //@} /**@name Check method * A method returning a boolean flag set to true if * the attribute property value has been assigned. */ //@{ /** * Check if the attribute property value has been assigned. * * This method returns a boolean set to true if the attribute property value has been assigned. * * @return A boolean set to true if the attribute property value has been assigned */ bool is_val() {return is_value;} //@} /// @privatesection operator string() { return str; } operator const char *() { return str.c_str(); } private: T val; string str; bool is_value; // // The extension class // class AttrPropExt {}; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else AttrPropExt *ext; #endif }; //=================================================================================================================== // // The DoubleAttrProp class // // description : This is a template class which holds values of a compound attribute property (like rel_change, // abs_change, archive_rel_change, archive_abs_change) which consists of two values, and its string // representation. // //================================================================================================================== /** * This class represents a Tango compound attribute property which consists of * two values. * * $Author: trogucki $ * $Revision: 19431 $ * * @headerfile tango.h * @ingroup Server */ template class DoubleAttrProp { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Default constructor. */ DoubleAttrProp() : is_value(false) {} /** * Create a new DoubleAttrProp object. * * @param values A vector containing two values of * the compound attribute property. */ DoubleAttrProp(const vector &values) : val(values), is_value(true) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << values[i]; } str = st.str(); } /** * Create a new DoubleAttrProp object. * * @param value The figure assigned to both values of the compound attribute property. */ DoubleAttrProp(const T &value) : is_value(true) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << value; str = st.str(); val.push_back(value); } /** * Create a new DoubleAttrProp object. * * @param value_str The 'C string' representation of values of the compound attribute property. */ DoubleAttrProp(const char *value_str) : str(string(value_str)), is_value(false) {} /** * Create a new DoubleAttrProp object. * * @param value_str The string representation of values of the compound attribute property. */ DoubleAttrProp(const string &value_str) : str(value_str), is_value(false) {} //@} /**@name Assignment operators * These operators allow to assign the values of the compound attribute property * by providing the values or their string representations. */ //@{ /** * Assign the values of the compound attribute property. * * @param values A vector containing compound attribute property values. * * @return DoubleAttrProp object with both values of the compound attribute property * and their string representation set. */ DoubleAttrProp & operator=(const vector &values) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << values[i]; } str = st.str(); val = values; is_value = true; return *this; } /** * Assign the values of the compound attribute property. * * @param value A figure representing both values of the compound attribute property. * * @return DoubleAttrProp object with both values of the compound attribute property * and their string representation set. */ DoubleAttrProp & operator=(const T &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) st << (short)value; // to represent the numeric value else st << value; str = st.str(); val.push_back(value); is_value = true; return *this; } /** * Assign the values of the compound attribute property. * * @param value_str A 'C string' representation of values of the compound attribute property. * * @return DoubleAttrProp object with string representation of values of * the compound attribute property set. */ DoubleAttrProp & operator=(const char *value_str) { str = value_str; is_value = false; return *this; } /** * Assign the values of the compound attribute property. * * @param value_str A string representation of values of the compound attribute property. * * @return DoubleAttrProp object with string representation of values of * the compound attribute property set. */ DoubleAttrProp & operator=(const string &value_str) { str = value_str; is_value = false; return *this; } //@} /**@name Get/Set object members. * These methods allow the external world to get/set DoubleAttrProp instance * data members */ //@{ /** * Get the vector containing the compound attribute property values. * * @return The vector containing the compound attribute property values. */ vector get_val() { if(is_value == false) { string err_msg = "Numeric representation of the property's value (" + str + ") has not been set"; Tango::Except::throw_exception(API_AttrPropValueNotSet,err_msg,"AttrProp::get_val",Tango::ERR); } return val; } /** * Get string representation of the compound attribute property values. * * @return The string representation of the compound attribute property values. */ string &get_str() {return str;} /** * Set the compound attribute property values. * * The values are automatically converted to their string representation. * * @param values The vector containing the compound attribute property values. */ void set_val(const vector &values) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << values[i]; } str = st.str(); val = values; is_value = true; } /** * Set the compound attribute property values. * * The figure provided is set for both values of the compound attribute property * and is automatically converted to its string representation. * * @param value The figure representing both values of the compound attribute property. */ void set_val(const T &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << value; str = st.str(); val.push_back(value); is_value = true; } /** * Set string representation of the compound attribute property values. * * @param value_str The 'C string' representation of the compound attribute property values. */ void set_str(const char *value_str) {str = string(value_str); is_value = false;} /** * Set string representation of the compound attribute property values. * * @param value_str The string representation of the compound attribute property values. */ void set_str(const string &value_str) {str = value_str; is_value = false;} //@} /**@name Check method * A method returning a boolean flag set to true if * the compound attribute property values have been assigned. */ //@{ /** * Check if the compound attribute property values have been assigned. * * This method returns a boolean set to true if the compound attribute property values * have been assigned. * * @return A boolean set to true if the compound attribute property values have been assigned */ bool is_val() {return is_value;} //@} /// @privatesection operator string() { return str; } operator const char *() { return str.c_str(); } private: vector val; string str; bool is_value; // // The extension class // class DoubleAttrPropExt {}; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else DoubleAttrPropExt *ext; #endif }; //================================================================================================================== // // The MultiAttrProp class // // description : This is a template class which holds values of modifiable attribute properties. // //================================================================================================================= /** * This class represents Tango modifiable attribute properties grouped in * one object to facilitate setting and getting attribute properties in one go. * * $Author: trogucki $ * $Revision: 19431 $ * * @headerfile tango.h * @ingroup Server */ template class MultiAttrProp { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Default constructor. */ MultiAttrProp() { CmdArgType type = ranges_type2const::enu; // restricts template initialisation to supported types if(type){}; // prevents compiler warning about unused variable type } //@} /**@name Class data members */ //@{ /** * Attribute label */ string label; /** * Attribute description */ string description; /** * Attribute unit */ string unit; /** * Attribute standard_unit */ string standard_unit; /** * Attribute display_unit */ string display_unit; /** * Attribute format */ string format; /** * Attribute min_value */ AttrProp min_value; /** * Attribute max_value */ AttrProp max_value; /** * Attribute min_alarm */ AttrProp min_alarm; /** * Attribute max_alarm */ AttrProp max_alarm; /** * Attribute min_warning */ AttrProp min_warning; /** * Attribute max_warning */ AttrProp max_warning; /** * Attribute delta_t */ AttrProp delta_t; /** * Attribute delta_val */ AttrProp delta_val; /** * Attribute event_period */ AttrProp event_period; /** * Attribute archive_period */ AttrProp archive_period; /** * Attribute rel_change */ DoubleAttrProp rel_change; /** * Attribute abs_change */ DoubleAttrProp abs_change; /** * Attribute archive_rel_change */ DoubleAttrProp archive_rel_change; /** * Attribute archive_abs_change */ DoubleAttrProp archive_abs_change; /** * Enumeration labels (For DevEnum data type) */ vector enum_labels; //@} private: // // The extension class // class MultiAttrPropExt {}; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else MultiAttrPropExt *ext; #endif }; } // End of Tango namespace #endif // _ATTRPROP_H tango-9.2.5a/lib/cpp/server/auto_tango_monitor.h0000644023471100065110000000757313034745001016655 00000000000000//===================================================================================================================== // // file : auto_tango_monitor.h // // description : Include file for two utility classes related to monitor // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //==================================================================================================================== #ifndef _AUTO_TANGO_MONITOR_H #define _AUTO_TANGO_MONITOR_H namespace Tango { //------------------------------------------------------------------------------------------------------------------- // // class : // AutoTangoMonitor // // description : // This class is only a helper class used to get a TangoMonitor object during its construction and to // it during its destruction. It makes developer life easier. // //------------------------------------------------------------------------------------------------------------------- class AutoTangoMonitor { public: AutoTangoMonitor(Tango::DeviceImpl *dev, bool force = false) { SerialModel ser = Util::instance()->get_serial_model(); switch(ser) { case NO_SYNC: if (force == true) { mon = &(dev->only_one); } else mon = NULL; break; case BY_DEVICE: mon = &(dev->only_one); break; case BY_CLASS: mon = &(dev->device_class->only_one); break; case BY_PROCESS: mon = &(Util::instance()->only_one); break; } if (mon) mon->get_monitor(); } AutoTangoMonitor(Tango::DeviceClass *dev_cl) { SerialModel ser = Util::instance()->get_serial_model(); switch(ser) { case NO_SYNC: case BY_DEVICE: mon = NULL; break; case BY_CLASS: mon = &(dev_cl->only_one); mon->get_monitor(); break; case BY_PROCESS: mon = &(Util::instance()->only_one); mon->get_monitor(); break; } } AutoTangoMonitor(Tango::TangoMonitor *m):mon(m) { if (mon) mon->get_monitor(); } ~AutoTangoMonitor() {if (mon)mon->rel_monitor();} private: TangoMonitor *mon; omni_thread::ensure_self auto_self; }; //--------------------------------------------------------------------------------------------------------------------- // // class : // NoSyncModelTangoMonitor // // description : // This class is only a helper class used to get a TangoMonitor object during its construction and to // it during its destruction only if the device server process is in NO_SYNC synchronisation model // //-------------------------------------------------------------------------------------------------------------------- class NoSyncModelTangoMonitor { public: NoSyncModelTangoMonitor(Tango::DeviceImpl *dev) { SerialModel ser = Util::instance()->get_serial_model(); if (ser == NO_SYNC) { mon = &(dev->only_one); mon->get_monitor(); } else mon = NULL; } ~NoSyncModelTangoMonitor() {if (mon)mon->rel_monitor();} private: TangoMonitor *mon; omni_thread::ensure_self auto_self; }; } // End of Tango namespace #endif /* AUTO_TANGO_MONITOR */ tango-9.2.5a/lib/cpp/server/basiccommand.h0000644023471100065110000000653013034745001015356 00000000000000//============================================================================= // // file : BasicCommand.h // // description : Include for commands which are implemented in all // classes. Classes for 2 commands are defined here: // DevStatus for the DevStatus command // DevState for the DevState command // All these classes inherits from the Command class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _BASICCOMMAND_H #define _BASICCOMMAND_H #include namespace Tango { //============================================================================= // // The DevStatusCmd class // // description : Class to implement the DevStatus command. This command // does not take any input argument and return the device // state as a string // //============================================================================= class DevStatusCmd : public Command { public: DevStatusCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~DevStatusCmd() {}; virtual CORBA::Any * execute(DeviceImpl *device,const CORBA::Any &in_any); }; //============================================================================= // // The DevState class // // description : Class to implement the DevState command. This command // does not take any input argument and return the device // state as an enumerated type // //============================================================================= class DevStateCmd : public Command { public: DevStateCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~DevStateCmd() {}; virtual CORBA::Any * execute(DeviceImpl *device,const CORBA::Any &in_any); }; //============================================================================= // // The DevInit class // // description : Class to implement the Init command. This command // does not take any input argument and output argument. // It will call the device delete_device method and its // init_device method. // //============================================================================= class DevInitCmd : public Command { public: DevInitCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~DevInitCmd() {}; virtual CORBA::Any * execute(DeviceImpl *device,const CORBA::Any &in_any); }; } // End of Tango namespace #endif // _BASICCOMMAND_H tango-9.2.5a/lib/cpp/server/blackbox.h0000644023471100065110000001513613034745001014525 00000000000000//==================================================================================================================== // // file : BlackBox.h // // description : Include for the BlackBox object. This class implements the black box objects which keep tracks // of all operation invoke on a device or attribute retrieved. // This black box is managed as a circular buffer // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //==================================================================================================================== #ifndef _BLACKBOX_H #define _BLACKBOX_H #include #ifdef _TG_WINDOWS_ #include #endif #include #include namespace Tango { #define IP_ADDR_BUFFER_SIZE 80 CORBA::Boolean get_client_addr(omni::omniInterceptors::serverReceiveRequest_T::info_T &); class client_addr: public omni_thread::value_t { public: client_addr():client_ident(false),client_pid(0) {client_ip[0]='\0';::memset(java_ident,0,sizeof(DevULong64)<<1);} client_addr(const char *addr):client_ident(false),client_pid(0) {strcpy(client_ip,addr);} ~client_addr() {}; client_addr(const client_addr &); client_addr & operator=(const client_addr &); bool operator==(const client_addr &); bool operator!=(const client_addr &); bool client_ident; char client_ip[IP_ADDR_BUFFER_SIZE]; LockerLanguage client_lang; TangoSys_Pid client_pid; string java_main_class; DevULong64 java_ident[2]; int client_ip_2_client_name(string &) const; friend ostream &operator<<(ostream &o_str,const client_addr &ca); }; //================================================================================================================== // // The BlackBoxElt class // // description : // Class to store all the necessary information which will be stored and returned to client on request // //================================================================================================================== #define DEFAULT_ATTR_NB 10 enum BlackBoxElt_ReqType { Req_Unknown, Req_Operation, Req_Attribute }; enum BlackBoxElt_AttrType { Attr_Unknown, Attr_Name, Attr_Description, Attr_State, Attr_Status, Attr_AdmName }; enum BlackBoxElt_OpType { Op_Unknown, Op_Command_inout, Op_BlackBox, Op_Ping, Op_Info, Op_Command_list, Op_Command, Op_Get_Attr_Config, Op_Set_Attr_Config, Op_Read_Attr, Op_Write_Attr, Op_Command_inout_2, Op_Command_list_2, Op_Command_2, Op_Get_Attr_Config_2, Op_Read_Attr_2, Op_Command_inout_history_2, Op_Read_Attr_history_2, Op_Read_Attr_3, Op_Write_Attr_3, Op_Read_Attr_history_3, Op_Info_3, Op_Get_Attr_Config_3, Op_Set_Attr_Config_3, Op_Read_Attr_history_4, Op_Command_inout_history_4, Op_Command_inout_4, Op_Write_Attr_4, Op_Read_Attr_4, Op_Set_Attr_Config_4, Op_Write_Read_Attributes_4, Op_Get_Attr_Config_5, Op_Set_Attr_Config_5, Op_Read_Attr_5, Op_Write_Read_Attributes_5, Op_Read_Attr_history_5, Op_Get_Pipe_Config_5, Op_Set_Pipe_Config_5, Op_Read_Pipe_5, Op_Write_Pipe_5, Op_Write_Read_Pipe_5 }; class BlackBoxElt { public: BlackBoxElt(); ~BlackBoxElt(); BlackBoxElt_ReqType req_type; BlackBoxElt_AttrType attr_type; BlackBoxElt_OpType op_type; string cmd_name; vector attr_names; struct timeval when; char host_ip_str[IP_ADDR_BUFFER_SIZE]; DevSource source; bool client_ident; LockerLanguage client_lang; TangoSys_Pid client_pid; string java_main_class; }; inline bool operator<(const BlackBoxElt &,const BlackBoxElt &) { return true; } inline bool operator==(const BlackBoxElt &,const BlackBoxElt &) { return true; } //================================================================================================================== // // The BlackBox class // // description : // Class to implement the black box itself. This is mainly a vector of BlackBoxElt managed as a circular vector // //=================================================================================================================== class BlackBox { public: BlackBox(); BlackBox(long); void insert_corba_attr(BlackBoxElt_AttrType); void insert_cmd(const char *,long vers=1,DevSource=Tango::DEV); void insert_attr(const Tango::DevVarStringArray &,long vers=1,DevSource=Tango::DEV); void insert_attr(const Tango::DevVarStringArray &,const ClntIdent &,long vers=1,DevSource=Tango::DEV); void insert_attr(const char *,const ClntIdent &,long); void insert_attr(const Tango::AttributeValueList &,long vers=1); void insert_attr(const Tango::AttributeValueList_4 &,const ClntIdent &,long vers); void insert_attr(const Tango::DevPipeData &,const ClntIdent &,long vers); void insert_wr_attr(const Tango::AttributeValueList_4 &,const Tango::DevVarStringArray &,const ClntIdent &,long vers); void insert_op(BlackBoxElt_OpType); void insert_op(BlackBoxElt_OpType,const ClntIdent &); void insert_cmd_nl(const char *,long,DevSource); void insert_cmd_cl_ident(const char *,const ClntIdent &,long vers=1,DevSource=Tango::DEV); void add_cl_ident(const ClntIdent &,client_addr *); void update_client_host(client_addr *); Tango::DevVarStringArray *read(long); private: void inc_indexes(); void get_client_host(); void build_info_as_str(long); void date_ux_to_str(struct timeval &,char *); void add_source(long); void insert_op_nl(BlackBoxElt_OpType); void insert_attr_nl(const Tango::AttributeValueList &,long); void insert_attr_nl_4(const Tango::AttributeValueList_4 &); void insert_attr_wr_nl(const Tango::AttributeValueList_4 &,const Tango::DevVarStringArray &,long); vector box; long insert_elt; long nb_elt; long max_elt; omni_mutex sync; string elt_str; }; } // End of Tango namespace #endif /* _BLACKBOX_ */ tango-9.2.5a/lib/cpp/server/classattribute.h0000644023471100065110000001043413034745002015766 00000000000000//============================================================================= // // file : ClassAttribute.h // // description : Include file for the Tango attribute. // Three classes are declared in this file : // // AttrProperty : A helper class. This class stored a couple // property name, property value as strings // ClassAttribute : A class for each attribute with all // its properties defined at the class // level. The properties are still stored // as string // MultiClassAttribute : A class to manage all the class // level definition of attributes. // There is one instance of this class // for each tango device pattern // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27976 $ // //============================================================================= #ifndef _CLASS_ATTRIBUTE_H #define _CLASS_ATTRIBUTE_H #include //#include #include namespace Tango { //============================================================================= // // The AttrProperty class // // // description : This class is used to store a pair of attribute name, // attribute value. Both name and value are stored as // string // //============================================================================= class AttrProperty { public: AttrProperty(const char *name,const char *value); AttrProperty(string &name,string &value); AttrProperty(const char *name,long value); AttrProperty(const char *name,string &value); ~AttrProperty() {}; string &get_value() {return attr_value;} long get_lg_value() {return attr_lg;} string &get_name() {return attr_name;} void convert(const char *); #ifndef TANGO_HAS_LOG4TANGO friend ostream &operator<<(ostream &,const AttrProperty &); #endif private: string attr_name; string attr_value; long attr_lg; }; //============================================================================= // // The MultiClassAttribute class // // // description : This class is a holder for all the ClassAttribute // instance. There is one instance of this class for each // Tango device pattern implementation. This instance is // stored in the DeviceClass object of the pattern // //============================================================================= class MultiClassAttribute { public: MultiClassAttribute(); ~MultiClassAttribute(); void init_class_attribute(string &class_name,long base = 0); vector &get_attr_list() {return attr_list;} Attr &get_attr(string &attr_name); void remove_attr(const string &,const string &); protected: vector attr_list; }; //============================================================================= // // A binary function object // // // description : This binary function object is used by the find_if // std C++ find_if algorithm. It checks if the // ClassAttribute object passed as argument (A1) stored // all the properties for the atribute name passed as // second argument (A2). // This function object is a predicate and therefore // returns a boolean (R) // //============================================================================= template struct WantedClassAttr : public binary_function { R operator() (A1 att,A2 name_str) const { return att->get_name() == name_str; } }; } // End of Tango namespace #endif // _CLASS_ATTRIBUTE_H tango-9.2.5a/lib/cpp/server/classpipe.h0000644023471100065110000000546413034745002014727 00000000000000//================================================================================================================= // // file : ClassPipe.h // // description : Include file for the Tango pipe. // MultiClassAttribute : A class to manage all the class level definition of pipes. // There is one instance of this class for each Tango class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #ifndef _CLASS_PIPE_H #define _CLASS_PIPE_H #include namespace Tango { //================================================================================================================= // // The PipeProperty class // // // description : This class is used to store a pair of pipe prop name, pipe prop value. Both name and value are // stored as strings // //================================================================================================================= class PipeProperty { public: PipeProperty(const string &name,const string &value):prop_name(name),prop_value(value) {} ~PipeProperty() {}; const string &get_value() {return prop_value;} const string &get_name() {return prop_name;} private: string prop_name; string prop_value; }; //================================================================================================================= // // The MultiClassPipe class // // // description : // //================================================================================================================= class DeviceClass; class MultiClassPipe { public: MultiClassPipe(); ~MultiClassPipe(); void init_class_pipe(DeviceClass *); vector &get_prop_list(const string &); /* PipeProperty &get_prop(const string &prop_name);*/ protected: map > pipe_prop_list; // pipe_name - prop list }; } // End of Tango namespace #endif // _CLASS_ATTRIBUTE_H tango-9.2.5a/lib/cpp/server/command.h0000644023471100065110000034052513034745002014362 00000000000000//============================================================================= // // file : Command.h // // description : Include for the Device root classes. // One class is declared in this file : // The Command class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _COMMAND_H #define _COMMAND_H #include namespace Tango { #ifndef HAS_LAMBDA_FUNC // // Binary function objects to be used by the find_if algorithm. // The find_if algo. want to have a predicate, this means that the return value // must be a boolean (R is its name). // The find_if algo. needs a unary predicate. This function object is a binary // function object. It must be used with the bind2nd function adapter // template struct WantedCmd : public binary_function { R operator() (A1 cmd_ptr, A2 name) const { if (::strlen(name) != cmd_ptr->get_lower_name().size()) return false; string tmp_name(name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); return cmd_ptr->get_lower_name() == tmp_name; } }; #endif typedef bool (DeviceImpl::*ALLO_PTR)(const CORBA::Any &); /** * This class is a class representing a command in the TANGO device server * pattern. it is an abstract class. It is the root class for all command * related classes for command implemented with the inheritance model or * with the template command model * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class Command { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Command object. * * The default constructor */ Command():ext(new CommandExt) {} /** * Constructs a newly allocated Command object for a command from its * name and its input and output parameter types. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * */ Command(const char *s,Tango::CmdArgType in,Tango::CmdArgType out); /** * Constructs a newly allocated Command object for a command from its * name and its input and output parameter types. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * */ Command(string &s,Tango::CmdArgType in,Tango::CmdArgType out); /** * Constructs a newly allocated Command object for a command from its * name, its input and output parameter types plus parameters description * The command display level is set to OPERATOR. * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param in_desc The input parameter description * @param out_desc The output parameter description * */ Command(const char *s,Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc); /** * Constructs a newly allocated Command object for a command from its * name, its input and output parameter types plus parameters description * The command display level is set to OPERATOR. * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param in_desc The input parameter description * @param out_desc The output parameter description * */ Command(string &s,Tango::CmdArgType in,Tango::CmdArgType out, string &in_desc,string &out_desc); /** * Constructs a newly allocated Command object for a command from its * name and its input and output parameter types. * The input and output parameter description are set to the default String * "Uninitialised". * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param level The command display level * */ Command(const char *s,Tango::CmdArgType in,Tango::CmdArgType out, Tango::DispLevel level); /** * Constructs a newly allocated Command object for a command from its * name and its input and output parameter types. * The input and output parameter description are set to the default String * "Uninitialised". * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param level The command display level * */ Command(string &s,Tango::CmdArgType in,Tango::CmdArgType out, Tango::DispLevel level); /** * Constructs a newly allocated Command object for a command from its * name, its input and output parameter types plus parameters description * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param in_desc The input parameter description * @param out_desc The output parameter description * @param level The command display level * */ Command(const char *s,Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated Command object for a command from its * name, its input and output parameter types plus parameters description * * @param s The command name * @param in The command input parameter type * @param out The command output parameter type * @param in_desc The input parameter description * @param out_desc The output parameter description * @param level The command display level * */ Command(string &s,Tango::CmdArgType in,Tango::CmdArgType out, string &in_desc,string &out_desc, Tango::DispLevel level); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The object desctructor. */ #ifdef HAS_UNIQUE_PTR virtual ~Command() {} #else virtual ~Command() {delete ext;} #endif //@} /**@name Miscellaneous methods */ //@{ /** * Execute the command. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client. This method is abstract and must be redefined * in each sub-class * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. * @return The CORBA Any object returned to the client. * @exception DevFailed If the execution method failed. * Click here to read * DevFailed exception specification */ virtual CORBA::Any *execute (DeviceImpl *dev, const CORBA::Any &in_any) = 0; /** * Check if the command is allowed in the actual device state. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client to check if the command is allowed * in the actual device state. This method is the default is_allowed method which * always allows the command to be executed. It is possible to re-define it * if this default behaviour does not fulfill the device needs. * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. This * data is passed to this method in case it is necessary to take the command * allowed decision * @return A boolean set to true is the command is allowed. Otherwise, the * return value is false. */ virtual bool is_allowed (DeviceImpl *dev, const CORBA::Any &in_any) {(void)dev;(void)in_any;return true;} /** * Init command parameters type. * * This method is used only for command implemented using the Tango template * command model. In this base class, it does nothing and is re-define in * sub-classes. * */ virtual void init_types() {}; //@} /**@name Get/Set object members. * These methods allows the external world to get/set DeviceImpl instance * data members */ //@{ /** * Return the command name. * * @return The command name */ string &get_name() {return name;} /** * Set the command name. * * @param new_name The new command name */ void set_name(string &new_name) {name=new_name;} /** * Return the command name in lower case letters. * * @return The command name */ string &get_lower_name() {return lower_name;} /** * Return the input parameter type. * * @return The input parameter type */ Tango::CmdArgType get_in_type() {return in_type;} /** * Return the output parameter type. * * @return The output parameter type */ Tango::CmdArgType get_out_type() {return out_type;} /** * Return the input parameter description. * * @return The input parameter description */ string &get_in_type_desc() {return in_type_desc;} /** * Return the output parameter description. * * @return The output parameter description */ string &get_out_type_desc() {return out_type_desc;} /** * Return the command display level. * * @return The command display level */ Tango::DispLevel get_disp_level() {return cmd_disp_level;} /** * Set the input parameter description field. * * @param desc The input parameter description */ void set_in_type_desc(const char *desc) {in_type_desc = desc;} /** * Set the input parameter description field. * * @param desc The input parameter description */ void set_in_type_desc(string &desc) {in_type_desc = desc;} /** * Set the output parameter description field. * * @param desc The output parameter description */ void set_out_type_desc(const char *desc) {out_type_desc = desc;} /** * Set the output parameter description field. * * @param desc The output parameter description */ void set_out_type_desc(string &desc) {out_type_desc = desc;} /** * Set the command display level. * * @param level The command display level */ void set_disp_level(Tango::DispLevel level) {cmd_disp_level = level;} /** * Set the command polling period. * * @param per The command polling period (in mS) */ void set_polling_period(long per) {poll_period = per;} /** * Get the command polling period. * * @return The command polling period (in mS) */ long get_polling_period() {return poll_period;} //@} /**@name Extract methods. * All these methods extract data from the CORBA Any object received as * command input data */ //@{ /** * Extract a boolean data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted boolean data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevBoolean &data); /** * Extract a short data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted short data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevShort &data); /** * Extract a long data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted long data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevLong &data); /** * Extract a 64 bits long data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted 64 bits long data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevLong64 &data); /** * Extract a float data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted float data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevFloat &data); /** * Extract a double data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted double data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevDouble &data); /** * Extract an unsigned short data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned short data * @exception DevFailed If the Any object does not contanis a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevUShort &data); /** * Extract an unsigned long data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned long data * @exception DevFailed If the Any object does not contanis a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevULong &data); /** * Extract an unsigned 64 bits long data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned 64 bits long data * @exception DevFailed If the Any object does not contanis a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevULong64 &data); /** * Extract a string from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted string data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevString &data); /** * Extract a const string from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted string data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const char *&data); /** * Extract a char array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted char array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarCharArray *&data); /** * Extract a short array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted short array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarShortArray *&data); /** * Extract a long array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted long array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarLongArray *&data); /** * Extract a 64 bits long array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted 64 bits long array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarLong64Array *&data); /** * Extract a float array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted float array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarFloatArray *&data); /** * Extract a double array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted double array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarDoubleArray *&data); /** * Extract a unsigned short array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned char array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarUShortArray *&data); /** * Extract a unsigned long array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned long array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarULongArray *&data); /** * Extract a unsigned 64 bits long array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted unsigned 64 bits long array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarULong64Array *&data); /** * Extract a string array from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted string array * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarStringArray *&data); /** * Extract a DevVarLongStringArray data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted DevVarLongStringArray data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarLongStringArray *&data); /** * Extract a DevVarDoubleStringArray data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted DevVarDoubleStringArray data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevVarDoubleStringArray *&data); /** * Extract a Tango device state data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted device state data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,Tango::DevState &data); /** * Extract a Tango DevEncoded data from a CORBA Any object. * * @param in The CORBA Any object * @param data Reference to the extracted DevEncoded data * @exception DevFailed If the Any object does not contains a data of the * waited type. * Click here to read * DevFailed exception specification */ void extract(const CORBA::Any &in,const Tango::DevEncoded *&data); //@} /**@name Insert methods. * All these methods create a CORBA Any object and insert data into this object */ //@{ /** * Create an empty CORBA Any object. * * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(); /** * Create a CORBA Any object and insert a Tango::DevBoolean data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevBoolean data); /** * Create a CORBA Any object and insert a Tango::DevShort data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevShort data); /** * Create a CORBA Any object and insert a Tango::DevLong data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevLong data); /** * Create a CORBA Any object and insert a Tango::DevLong64 data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevLong64 data); /** * Create a CORBA Any object and insert a Tango::DevFloat data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevFloat data); /** * Create a CORBA Any object and insert a Tango::DevDouble data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevDouble data); /** * Create a CORBA Any object and insert a Tango::DevUShort data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevUShort data); /** * Create a CORBA Any object and insert a Tango::DevULong data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevULong data); /** * Create a CORBA Any object and insert a Tango::DevULong64 data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevULong64 data); /** * Create a CORBA Any object and insert a Tango::DevString data in it. * * This method will also de-allocate the string passed as parameter. * * @param data The string to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevString data); /** * Create a CORBA Any object and insert a Tango::DevString data in it. * Te parameter type is char * and not Tango::DevString because the const * C++ modifier applied to a Tango::DevString make the pointer constant and * not the pointed to characters to be constant. * * @param data The string to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(const char *data); /** * Create a CORBA Any object and insert a Tango::DevVarCharArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarCharArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarCharArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarCharArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarCharArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarShortArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarShortArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarShortArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarShortArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarShortArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarLongArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLongArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarLongArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarLongArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLongArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarLong64Array data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLong64Array &data); /** * Create a CORBA Any object and insert a Tango::DevVarLong64Array data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarLongArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLong64Array *data); /** * Create a CORBA Any object and insert a Tango::DevVarFloatArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarFloatArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarFloatArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarFloatArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarFloatArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarDoubleArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarDoubleArray &data); /** * Create a CORBA CORBA::Any object and insert a Tango::DevVarDoubleArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarDoubleArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarDoubleArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarUShortArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarUShortArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarUShortArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarUShortArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarUShortArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarULongArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarULongArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarULongArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarULongArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarULongArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarULong64Array data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarULong64Array &data); /** * Create a CORBA Any object and insert a Tango::DevVarULong64Array data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarULongArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarULong64Array *data); /** * Create a CORBA Any object and insert a Tango::DevVarStringArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarStringArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarStringArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarStringArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarStringArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarLongStringArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLongStringArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarLongStringArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarLongStringArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarLongStringArray *data); /** * Create a CORBA Any object and insert a Tango::DevVarDoubleStringArray data in it. * * This method will do a deep copy of the array into the Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarDoubleStringArray &data); /** * Create a CORBA Any object and insert a Tango::DevVarDoubleStringArray data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarDoubleStringArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevVarDoubleStringArray *data); /** * Create a CORBA Any object and insert a Tango::DevState data in it. * * @param data The data to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevState data); /** * Create a CORBA Any object and insert a Tango::DevEncoded data in it. * * This method consumes the memory used by the array. * When the CORBA layer will destroy the Any object, the memory alloacted * for the array will also be freed. This is the recommended method to * insert Tango::DevVarDoubleStringArray data type into a CORBA Any object. * * @param data The array to be inserted into the Any object * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ CORBA::Any *insert(Tango::DevEncoded *data); //@} protected: /**@name Class data members */ //@{ /** * The command name */ string name; /** * The command name in lower case */ string lower_name; /** * The command input parameter type */ Tango::CmdArgType in_type; /** * The command output parameter type */ Tango::CmdArgType out_type; /** * The command input parameter description */ string in_type_desc; /** * The command output parameter type */ string out_type_desc; //@} private: class CommandExt { public: CommandExt() {} }; void alloc_any(CORBA::Any *&); void throw_bad_type(const char *); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else CommandExt *ext; #endif // // Ported from the extension class // Tango::DispLevel cmd_disp_level; // Display level long poll_period; // Polling period }; //============================================================================= // // The TemplCommand class // // // description : This class is a derived class of the Command class. // It is used to create a command from a pointer to a // object method which will execute the command. // This class is for command without inout nor output // paremeters. // This class is also a base class for the template Command // class // //============================================================================= /** * This class is a class representing a command in the template command model * without input or output parameter * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class TemplCommand:public Command { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Command object. * * The default constructor */ TemplCommand():ext(Tango_nullptr) {} /** * Constructs a newly allocated TemplCommand object for a command with a * name and an execution method. * This constructor set the command input and output type to Tango::DEV_VOID. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)()); /** * Constructs a newly allocated TemplCommand object for a command with a * name and an execution method. * This constructor set the command input and output type to Tango::DEV_VOID. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)()); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a command allowed method. * This constructor set the command input and output type to Tango::DEV_VOID * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a command allowed method. * This constructor set the command input and output type to Tango::DEV_VOID * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a description for the * input and output command parameters. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a description for the * input and output command parameters. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * This constructor set the command input and output type to Tango::DEV_VOID. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * This constructor set the command input and output type to Tango::DEV_VOID. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommand object for a command with a * name and an execution method. * This constructor set the command input and output type to Tango::DEV_VOID. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name and an execution method. * This constructor set the command input and output type to Tango::DEV_VOID. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a command allowed method. * This constructor set the command input and output type to Tango::DEV_VOID * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a command allowed method. * This constructor set the command input and output type to Tango::DEV_VOID * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a description for the * input and output command parameters. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method and a description for the * input and output command parameters. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), string &in_desc,string &out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * This constructor set the command input and output type to Tango::DEV_VOID. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommand(const char *cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommand object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * This constructor set the command input and output type to Tango::DEV_VOID. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommand(string &cmd_name,void (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc, Tango::DispLevel level); //@} TemplCommand(const char *); TemplCommand(string &); TemplCommand(const char *,Tango::DispLevel); TemplCommand(string &,Tango::DispLevel); TemplCommand(const char *,const char *,const char *); TemplCommand(string &,string &,string &); TemplCommand(const char *,const char *,const char *,DispLevel); TemplCommand(string &,string &,string &,DispLevel); /**@name Miscellaneous methods */ //@{ /** * Choose the correct TANGO data type constant according to data type * * The TANGO constant is determined using the type_info object passed * as first argument of the method. This data is compared to each defined * Tango type. * * @param data_type The type to be analysed * @param type A reference where Tango data type constant must be stored * @exception DevFailed If the type is not a Tango data type * Click here to read * DevFailed exception specification */ void set_type(const type_info &data_type,Tango::CmdArgType &type); /** * Invoke the command execution method given at object creation time. * * This method is automatically called by the TANGO core classes when the * associated command is requested by a client. * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. For * command created with this TemplCommand class, this Any object does not * contain usefull data * @return The CORBA Any object returned to the client. For command created with * this TemplCommand class, this any object does not contain data. * @exception DevFailed If the execution method failed * Click here to read * DevFailed exception specification */ CORBA::Any *execute (DeviceImpl *dev, const CORBA::Any &in_any); /** * Invoke the command allowed method given at object creation time. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client to check if the command is allowed * in the actual device state. If the user give a command allowed method * at object creation time, this method will be invoked. * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. For * command created with this TemplCommand class, this Any object does not * contain data * @return A boolean set to true is the command is allowed. Otherwise, the * return value is false. This return value is always set to true if the user * does not supply a method to be excuted. If a method has been supplied, the * return value is the value returned by the user supplied mehod. */ bool is_allowed (DeviceImpl *dev, const CORBA::Any &in_any); //@} private: class TemplCommandExt { }; void (DeviceImpl::*exe_ptr)(); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else TemplCommandExt *ext; #endif protected: /**@name Class data members */ //@{ /** * The command allowed method object reference */ bool (DeviceImpl::*allowed_ptr)(const CORBA::Any &); //@} }; //============================================================================= // // The TemplCommandInOut class // // // description : This class is a derived class of the Command class. // It is used to create a command from a pointer to a // object method which will execute the command. // This class is for command without inout nor output // paremeters. // This class is also a base class for the template Command // class // //============================================================================= /** * This class is a class representing a command in the template command model * with output and input parameters. The class template * parameters (called INARG and OUTARG) are the command input parameter type * and the command output parameter type. *

Synopsis : template class TemplCommandInOut:public TemplCommand;

*

Usage : new TemplCommandInOut(...);

* * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class TemplCommandInOut:public TemplCommand { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG)); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG)); /** * Constructs a newly allocated TemplCommandInout object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInout object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), string &in_desc,string &out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandInOut(const char *cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandInOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandInOut(string &cmd_name, OUTARG (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc, Tango::DispLevel level); //@} ~TemplCommandInOut() {} /**@name Miscellaneous methods */ //@{ /** * Initialise command input and output types. * * Set the command output type to Tango::DEV_VOID. The command input type is * automatically determined from the class template specialisation * */ void init_types(); /** * Invoke the command execution method given at object creation time. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client. It first unpacks the incoming * data. Then, it invokes the user supplied * command execution method and packs the returned data into the outgoing * CORBA Any object * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. * @return The CORBA Any object returned to the client. * @exception DevFailed If the execution method failed * Click here to read * DevFailed exception specification */ CORBA::Any *execute (DeviceImpl *dev, const CORBA::Any &in_any); //@} private: class TemplCommandInOutExt { }; OUTARG (DeviceImpl::*exe_ptr_inout)(INARG); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else TemplCommandInOutExt *ext; #endif }; //+------------------------------------------------------------------------- // // method : TempCommandInOut class constructors // // description : instance constructor // //-------------------------------------------------------------------------- template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG)) :TemplCommand(s),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG)) :TemplCommand(s),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(const char *s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandInOut::TemplCommandInOut(string &s,OUTARG (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_inout(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } //+------------------------------------------------------------------------- // // method : init_types // // description : Initialise input and output type from the template // class specialisation parameters. // //-------------------------------------------------------------------------- template void TemplCommandInOut::init_types() { // // Set intput type // set_type(typeid(INARG),in_type); // // Set output type // set_type(typeid(OUTARG),out_type); } //+------------------------------------------------------------------------- // // method : execute // // description : Execute the method associated with the command // (stored in the exe_ptr data) // // input : - dev_ptr : pointer to the device on which the command must be // executed // - in_any : Incoming command data // // This method returns a pointer to an Any object with the command outing // data. // //-------------------------------------------------------------------------- template CORBA::Any *TemplCommandInOut::execute(DeviceImpl *dev_ptr,const CORBA::Any &in_any) { // // Execute the command associated method // INARG in_data; extract(in_any,in_data); OUTARG out_data = (dev_ptr->*exe_ptr_inout)(in_data); return insert(out_data); } //============================================================================= // // The TemplCommandIn class // // // description : This class is a derived class of the Command class. // It is used to create a command from a pointer to a // object method which will execute the command. // This class is for command without inout nor output // paremeters. // This class is also a base class for the template Command // class // //============================================================================= /** * This class is a class representing a command in the template command model * with input parameter but without output parameter. The class template * parameter (called INARG) is the command input parameter type. *

Synopsis : template class TemplCommandIn:public TemplCommand;

*

Usage : new TemplCommandIn(...);

* * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class TemplCommandIn:public TemplCommand { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated TemplCommandIn object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG)); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG)); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), string &in_desc,string &out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandIn(const char *cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandIn(string &cmd_name, void (DeviceImpl::*exe_method)(INARG), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc, Tango::DispLevel level); //@} ~TemplCommandIn() {} /**@name Miscellaneous methods */ //@{ /** * Initialise command input and output types. * * Set the command output type to Tango::DEV_VOID. The command input type is * automatically determined from the class template specialisation * */ void init_types(); /** * Invoke the command execution method given at object creation time. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client. It unpacks the data stored in * the CORBA Any object and invoke the user supplied command execution * method * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. * @return The CORBA Any object returned to the client. For command created with * this TemplCommandIn class, this any object does not contain data. * @exception DevFailed If the execution method failed * Click here to read * DevFailed exception specification */ CORBA::Any *execute (DeviceImpl *dev, const CORBA::Any &in_any); //@} private: class TemplCommandInExt { }; void (DeviceImpl::*exe_ptr_in)(INARG); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else TemplCommandInExt *ext; #endif }; //+------------------------------------------------------------------------- // // method : TempCommandIn class constructors // // description : instance constructor // //-------------------------------------------------------------------------- template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG)) :TemplCommand(s),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG)) :TemplCommand(s),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(const char *s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandIn::TemplCommandIn(string &s,void (DeviceImpl::*f)(INARG),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_in(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } //+------------------------------------------------------------------------- // // method : init_types // // description : Initialise input and output type from the template // class specialisation parameters. // //-------------------------------------------------------------------------- template void TemplCommandIn::init_types() { out_type = Tango::DEV_VOID; // // Set intput type // set_type(typeid(INARG),in_type); } //+------------------------------------------------------------------------- // // method : execute // // description : Execute the method associated with the command // (stored in the exe_ptr data) // // input : - dev_ptr : pointer to the device on which the command must be // executed // - in_any : Incoming command data // // This method returns a pointer to an Any object with the command outing // data. // //-------------------------------------------------------------------------- template CORBA::Any *TemplCommandIn::execute(DeviceImpl *dev_ptr,const CORBA::Any &in_any) { // // Execute the command associated method // INARG in_data; extract(in_any,in_data); (dev_ptr->*exe_ptr_in)(in_data); return insert(); } //============================================================================= // // The TemplCommandOut class // // // description : This class is a derived class of the Command class. // It is used to create a command from a pointer to a // object method which will execute the command. // This class is for command without inout nor output // paremeters. // This class is also a base class for the template Command // class // //============================================================================= /** * This class is a class representing a command in the template command model * with output parameter but without input parameter. The class template * parameter (called OUTARG) is the command output parameter type. *

Synopsis : template class TemplCommandOut:public TemplCommand;

*

Usage : new TemplCommandOut(...);

* * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class TemplCommandOut:public TemplCommand { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated TemplCommandOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)()); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)()); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &)); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * The command display level is set to OPERATOR. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name and an execution method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param level The command display level * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a command allowed method. * The input and output command data type are automatically determined. * The input and output parameter description are set to the default String * "Uninitialised". * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param level The command display level * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), string &in_desc,string &out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandOut object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandOut(const char *cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), const char *in_desc,const char *out_desc, Tango::DispLevel level); /** * Constructs a newly allocated TemplCommandIn object for a command with a * name, an execution method, a command allowed method and a description for the * input and output command parameters. * The input and output command data type are automatically determined. * * @param cmd_name The command name * @param exe_method Pointer to the command execution method * @param state_method Pointer to the command allowed method * @param in_desc The command input parameter description * @param out_desc The command output parameter description * @param level The command display level * */ TemplCommandOut(string &cmd_name,OUTARG (DeviceImpl::*exe_method)(), bool (DeviceImpl::*state_method)(const CORBA::Any &), string &in_desc,string &out_desc, Tango::DispLevel level); //@} ~TemplCommandOut() {} /**@name Miscellaneous methods */ //@{ /** * Initialise command input and output types. * * Set the command output type to Tango::DEV_VOID. The command input type is * automatically determined from the class template specialisation * */ void init_types(); /** * Invoke the command execution method given at object creation time. * * This method is automtically called by the TANGO core classes when the * associated command is requested by a client. It invokes the user supplied * command execution method and packs the returned data into the outgoing * CORBA Any object * * @param dev The device on which the command must be executed * @param in_any The incoming data still packed in a CORBA Any object. For * command created with this TemplCommandOut class, this Any object does not * contain usefull data * @return The CORBA Any object returned to the client. * @exception DevFailed If the execution method failed * Click here to read * DevFailed exception specification */ CORBA::Any *execute (DeviceImpl *dev, const CORBA::Any &in_any); //@} private: class TemplCommandOutExt { }; OUTARG (DeviceImpl::*exe_ptr_out)(); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else TemplCommandOutExt *ext; #endif }; //+------------------------------------------------------------------------- // // method : TempCommandOut class constructors // // description : instance constructor // //-------------------------------------------------------------------------- template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)()) :TemplCommand(s),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)()) :TemplCommand(s),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &)) :TemplCommand(s),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc) :TemplCommand(s,in_desc,out_desc),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :TemplCommand(s,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(const char *s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = NULL; init_types(); } template TemplCommandOut::TemplCommandOut(string &s,OUTARG (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc,Tango::DispLevel level) :TemplCommand(s,in_desc,out_desc,level),exe_ptr_out(f),ext(Tango_nullptr) { allowed_ptr = a; init_types(); } //+------------------------------------------------------------------------- // // method : init_types // // description : Initialise input and output type from the template // class specialisation parameters. // //-------------------------------------------------------------------------- template void TemplCommandOut::init_types() { in_type = Tango::DEV_VOID; // // Set output type // set_type(typeid(OUTARG),out_type); } //+------------------------------------------------------------------------- // // method : execute // // description : Execute the method associated with the command // (stored in the exe_ptr data) // // input : - dev_ptr : pointer to the device on which the command must be // executed // - in_any : Incoming command data // // This method returns a pointer to an Any object with the command outing // data. // //-------------------------------------------------------------------------- template CORBA::Any *TemplCommandOut::execute(DeviceImpl *dev_ptr,const CORBA::Any &in_any) { // // Execute the command associated method // return insert((dev_ptr->*exe_ptr_out)()); } } // End of Tango namespace #endif // _COMMAND_H tango-9.2.5a/lib/cpp/server/coutappender.h0000644023471100065110000000305013034745001015421 00000000000000/* * Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 * European Synchrotron Radiation Facility * BP 220, Grenoble 38043 * FRANCE * * This file is part of Tango. * * Tango is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tango is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Tango. If not, see . * * coutappender.h * * by NL - SOLEIL - 01/2003. * * $Revision: 27410 $ * */ #ifndef _COUT_APPENDER_H_ #define _COUT_APPENDER_H_ #if defined(TANGO_HAS_LOG4TANGO) namespace Tango { class CoutAppender : public log4tango::LayoutAppender { public: /** * **/ CoutAppender (const std::string& name); /** * **/ virtual ~CoutAppender (); /** * **/ inline virtual bool reopen() { return true; } /** * **/ inline virtual void close() { //no-op } protected: /** * **/ virtual int _append (const log4tango::LoggingEvent& event); }; } // namespace tango #endif // _COUT_APPENDER_H_ #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/coutbuf.h0000644023471100065110000000467513034745001014415 00000000000000//============================================================================= // // file : coutbuf.h // // description : Include for Windows NT debug output class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _COUTBUF_H #define _COUTBUF_H #include #ifndef TANGO_HAS_LOG4TANGO # include #endif namespace Tango { // // Some defines // #define IDC_LIST -777 #define MAXLISTLINES 200 #ifndef TANGO_HAS_LOG4TANGO #define bufferSize 512 #endif #ifndef TANGO_HAS_LOG4TANGO class CoutBuf: public streambuf #else class CoutBuf #endif { public: CoutBuf(HINSTANCE,int,HWND,LPCSTR); virtual ~CoutBuf(); HWND get_debug_window() {return DbgWin;} void clear_debug_window() {DbgWin = NULL;} void CreateWin(LPCSTR); #ifdef TANGO_HAS_LOG4TANGO int dbg_out (LPCSTR); #endif protected: #ifndef TANGO_HAS_LOG4TANGO char buffer[bufferSize]; long nb_critical; #endif HWND DbgWin; HWND parent_window; #ifndef TANGO_HAS_LOG4TANGO int dbg_out(LPCSTR); virtual int_type overflow(int_type); int flushBuffer(); virtual int sync(); virtual streamsize xsputn(const char_type *,streamsize); #endif }; // // Some functions for windows window management!!! // LRESULT CALLBACK DebugWndProc(HWND, UINT, WPARAM, LPARAM ); void DrawDebugItem(HWND, LPDRAWITEMSTRUCT ); void MeasureDebugItem(HWND, LPMEASUREITEMSTRUCT); } // End of Tango namespace #endif /* _COUTBUF_H */ tango-9.2.5a/lib/cpp/server/device.h0000644023471100065110000050445113034745001014202 00000000000000//=================================================================================================================== // // file : Device.h // // description : Include for the Device root classes called DeviceImpl // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28627 $ // //=================================================================================================================== #ifndef _DEVICE_H #define _DEVICE_H #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Tango { class Command; class DeviceClass; class AutoTangoMonitor; class NoSyncModelTangoMonitor; class EventSupplier; class EventSubscriptionChangeCmd; class Util; class FwdWrongConf; /** @defgroup Server Server classes */ //============================================================================= // // The DeviceImpl class // // // description : This class is derived directly from the Tango::Device_skel // class generated by CORBA. It represents the CORBA // servant which will be accessed by the client. // It implements all the methods // and attributes defined in the IDL interface for Device. // //============================================================================= /** * Base class for all TANGO device. * * This class inherits from CORBA classes where all the network layer is * implemented. * * $Author: taurel $ * $Revision: 28627 $ * * @headerfile tango.h * @ingroup Server */ class DeviceImpl : public virtual POA_Tango::Device { public: friend class Tango::AutoTangoMonitor; friend class Tango::NoSyncModelTangoMonitor; friend class Tango::EventSupplier; friend class Tango::EventSubscriptionChangeCmd; /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated DeviceImpl object from its name. * * The device description field is set to A Tango device. The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * */ DeviceImpl(DeviceClass *device_class,string &dev_name); /** * Constructs a newly allocated DeviceImpl object from its name and its description. * * The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * */ DeviceImpl(DeviceClass *device_class,string &dev_name,string &desc); /** * Constructs a newly allocated DeviceImpl object from all its creation * parameters. * * The device is constructed from its name, its description, an original state * and status * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * @param dev_state The device initial state * @param dev_status The device initial status * */ DeviceImpl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status); /** * Constructs a newly allocated DeviceImpl object from all its creation * parameters with some default values. * * The device is constructed from its name, its description, an original state * and status. This constructor defined default values for the description, * state and status parameters. The default device description is A TANGO device. * The default device state is UNKNOWN and the default device status * is Not initialised. * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device desc * @param dev_state The device initial state * @param dev_status The device initial status * */ DeviceImpl(DeviceClass *device_class, const char *dev_name,const char *desc = "A TANGO device", Tango::DevState dev_state = Tango::UNKNOWN, const char *dev_status = StatusNotSet); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device desctructor. */ virtual ~DeviceImpl(); //@} /**@name Get/Set object members. * These methods allows the external world to get/set DeviceImpl instance * data members */ //@{ /** * Get device status. * * Return the device dev_status field. This method does the same thing than the * default status_cmd method. * * @return Device status */ string &get_status() {return device_status;} /** * Set device status. * * @param new_status The new device status */ void set_status(const string &new_status) {device_status = new_status;} /** * Appends a string to the device status. * * @param stat The string to be appened to the device status * @param new_line If true, appends a new line character before the string */ void append_status(const string &stat,bool new_line=false) {if(new_line==true)device_status.append(1,'\n');device_status.append(stat);} /** * Get device state. * * Return the device dev_state field. This method does the same thing than the * default state_cmd method. * * @return Device state */ Tango::DevState &get_state() {return device_state;} /** * Get device's previous state. * * Return the device dev_prev_state field. This method is used for the on_state_change event * * @return Device previous state */ Tango::DevState &get_prev_state() {return device_prev_state;} /** * Set device state. * * @param new_state The new device state */ void set_state (const Tango::DevState &new_state); /** * Get device name. * * Return the device name (dev_name field) * * @return Device name */ string &get_name() {return device_name;} /** * Get device class singleton. * * Return the device class singleton (device_class field) * * @return Pointer to the device class singleton */ DeviceClass *get_device_class() {return device_class;} /** * Get device multi attribute object. * * Return a pointer to the device multi attribute object * * @return Pointer to the device multi attribute object */ MultiAttribute *get_device_attr() {return dev_attr;} /** * Set device multi attribute object. * * Set the pointer to the device multi attribute object * * @return Pointer to the device multi attribute object */ void set_device_attr(MultiAttribute *ptr) {dev_attr = ptr;} /** * Get a pointer to the associated DbDevice object. * * Return a pointer to DbDevice object associated with the device * * @return Pointer to the DbDevice object */ DbDevice *get_db_device(); /** * Set the associated CORBA object reference. * * Set the associated CORBA object reference. Tango supports only a one to * one servant-CORBA object link. * * @param d The CORBA object reference */ void set_d_var(Tango::Device_ptr d) {d_var = d;} /** * Get the associated CORBA object reference. * * Get the associated CORBA object reference. Tango supports only a one to * one servant-CORBA object link. * * @return The CORBA object reference */ Tango::Device_var get_d_var() {return d_var;} /** * Set the associated CORBA object identifier. * * Set the associated CORBA object identifier. * * @param o The CORBA object identifier */ void set_obj_id(PortableServer::ObjectId_var o) {obj_id = o;} /** * Get the associated CORBA object identifier. * * Return the CORBA object identifier as a _var type variable * * @return The CORBA object identifier */ PortableServer::ObjectId_var &get_obj_id() {return obj_id;} /** * Return device POA. * * Return a pointer to the device POA. This method is necessary for the * CORBA object implicit activation by the _this() method. * * @return Pointer to the device POA */ virtual PortableServer::POA_ptr _default_POA(); //@} protected: /**@name Polling related methods */ //@{ /** * Check if attribute is polled. * * Returns true if attribute with name given as parameter is polled. * * @param att_name The attribute name * @return Boolean set to true if attribute is polled */ bool is_attribute_polled(const string &att_name); /** * Check if command is polled. * * Returns true if command with name given as parameter is polled. * * @param cmd_name The command name * @return Boolean set to true if command is polled */ bool is_command_polled(const string &cmd_name); /** * Get attribute polling period. * * Returns attribute polling period (in mS) or 0 if the attribute is not polled * * @param att_name The attribute name * @return The attribute polling period in mS */ int get_attribute_poll_period(const string &att_name); /** * Get command polling period. * * Returns command polling period (in mS) or 0 if the command is not polled * * @param cmd_name The command name * @return The command polling period in mS */ int get_command_poll_period(const string &cmd_name); /** * Start polling one attribute. * * Ask Tango polling system to poll one attribute * * @param att_name The attribute name * @param period The polling period (mS) */ void poll_attribute(const string &att_name,int period); /** * Start polling a command. * * Ask Tango polling system to poll a command * * @param cmd_name The command name * @param period The polling period (mS) */ void poll_command(const string &cmd_name,int period); /** * Stop polling one attribute. * * Ask Tango polling system to stop polling one attribute * * @param att_name The attribute name */ void stop_poll_attribute(const string &att_name); /** * Stop polling one command. * * Ask Tango polling system to stop polling one command * * @param cmd_name The command name */ void stop_poll_command(const string &cmd_name); //@} public: /**@name Miscellaneous methods */ //@{ /** * Intialise a device. * * In the DeviceImpl class, this method is pure abstract and must be defined * in sub-class. Its rule is to initialise a device. This method is called * during device creation by the device constructor. * * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void init_device() = 0; /** * Delete a device. * * In the DeviceImpl class, this method is virtual and can be defined * in sub-class. Its rule is to delete memory allocated in the init_device * method. This method is called by the device destructor and by the * device Init command. * * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void delete_device() {}; /** * Hook method. * * Default method to implement an action necessary on a device before any * command is executed. This method can be redefined in * sub-classes in case of the default behaviour does not fulfill the needs * * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void always_executed_hook(void) {}; /** * Read the hardware to return attribute value(s). * * Default method to implement an action necessary on a device to read the * hardware involved in a a read attribute CORBA call. * This method must be redefined in sub-classes in order to support attribute * reading * * @param attr_list Reference to a vector with Integer object. Each element in * this vector * is the index in the device object attribute vector of an attribute to be read. * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void read_attr_hardware(vector &attr_list) {(void)attr_list;}; /** * Set the attribute read value. * * Default method to set an attribute read value. * This method must be redefined in sub-classes when attributes are needed * * @param attr The attribute object * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void read_attr(Attribute &attr) {(void)attr;}; /** * Write the hardware for attributes. * * Default method to implement an action necessary on a device to write the * hardware involved in a a write attribute. * This method must be redefined in sub-classes in order to support writable * attribute * * @param attr_list Reference to a vector of Integer objects. Each element in * this vector * is the index in the main attribute vector of an attribute to be written. * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void write_attr_hardware(vector &attr_list) {(void)attr_list;}; /** * Get device state. * * Default method to get device state. The behaviour of this method depends * on the device state. If the device state is ON or ALARM, it reads * the attribute(s) with an alarm level defined, check if the read value is * above/below the alarm and eventually change the state to ALARM, return the * device state. For all the other device state, this method simply returns * the state * This method can be redefined in * sub-classes in case of the default behaviour does not fulfill the needs * * @return The device state * @exception DevFailed If it is necessary to read attribute(s) and a problem * occurs during the reading. * Click here to read * DevFailed exception specification */ virtual Tango::DevState dev_state(); /** * Get device status. * * Default method to get device status. It returns the contents of the device * dev_status field. If the device state is ALARM, alarm messages are * added to the device status. This method can be redefined in * sub-classes in case of the default behaviour does not fulfill the needs * * @return The device status * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual Tango::ConstDevString dev_status(); /** * Add a new attribute to the device attribute list. * * Attributes are normally * constructed in the DeviceClass::attribute_factory() method. Nevertheless, it * is still possible to add a new attribute to a device with this method. * Please, note that if you add an attribute to a device at device creation * time, this attribute will * be added to the device class attribute list. Therefore, all devices * belonging to the same class created after this attribute addition * will also have this attribute. * * @param new_attr Pointer to the new attribute to be added to the list. This pointer * must point to "heap" allocated memory (or to static memory) and not to "stack" * allocated memory * @exception DevFailed * Click here to read * DevFailed exception specification */ void add_attribute(Attr *new_attr); /** * Remove one attribute from the device attribute list. * * Attributes are normally * constructed in the DeviceClass::attribute_factory() method. Nevertheless, it * is still possible to add a new attribute to a device with the DeviceImpl::add_attribute method. * This remove_attribute method delete the attribute from the * device attribute list. * * @param rem_attr Pointer to the attribute to be removed * @param free_it Boolean set to true if the object passed as first argument * must be freed. Default value is false. * @param clean_db Clean all attributes related information (included polling * info if the attribute is polled) from database. Default value is true * @exception DevFailed * Click here to read * DevFailed exception specification */ void remove_attribute(Attr *rem_attr,bool free_it = false, bool clean_db = true); /** * Remove one attribute from the device attribute list. * * Attributes are normally * constructed in the DeviceClass::attribute_factory() method. Nevertheless, it * is still possible to add a new attribute to a device with the DeviceImpl::add_attribute method. * This remove_attribute method delete the attribute from the * device attribute list. * * @param rem_attr_name The name of the attribute to be removed * @param free_it Boolean set to true if the attribute object * must be freed. Default value is false. * @param clean_db Clean all attributes related information (included polling * info if the attribute is polled) from database. Default value is true * @exception DevFailed * Click here to read * DevFailed exception specification */ void remove_attribute(string &rem_attr_name,bool free_it = false,bool clean_db = true); /** * Add a new command to the device command list. * * Commands are normally * constructed in the DeviceClass::command_factory() method. Nevertheless, it * is still possible to add a new command to a device with this method. * Please, note that if you add a command to a device at device creation * time, this command will * be added to the device class command list. Therefore, all devices * belonging to the same class created after this command addition * will also have this command. * * @param new_cmd Pointer to the new command to be added to the list. This pointer * must point to "heap" allocated memory (or to static memory) and not to "stack" * allocated memory * @param device Set this flag to true if the command must be added for only this device * Default is false (command added for the device class) * @exception DevFailed * Click here to read * DevFailed exception specification */ void add_command(Command *new_cmd, bool device = false); /** * Remove one command from the device command list. * * Commands are normally * constructed in the DeviceClass::command_factory() method. Nevertheless, it * is still possible to add a new command to a device with the DeviceImpl::add_command method. * This remove_command method delete the command from the * device command list. * * @param rem_cmd Pointer to the command to be removed * @param free_it Boolean set to true if the object passed as first argument * must be freed. Default value is false. * @param clean_db Clean command related information (included polling * info if the command is polled) from database. Default value is true * @exception DevFailed * Click here to read * DevFailed exception specification */ void remove_command(Command *rem_cmd,bool free_it = false,bool clean_db = true); /** * Remove one command from the device command list. * * Commands are normally * constructed in the DeviceClass::command_factory() method. Nevertheless, it * is still possible to add a new command to a device with the DeviceImpl::add_command method. * This remove_command method delete the command from the * device command list. * * @param rem_cmd_name The name of the command to be removed * @param free_it Boolean set to true if the command object * must be freed. Default value is false. * @param clean_db Clean command related information (included polling * info if the command is polled) from database. Default value is true * @exception DevFailed * Click here to read * DevFailed exception specification */ void remove_command(const string &rem_cmd_name,bool free_it = false,bool clean_db = true); /** * Retrieve a polled object from the polled object list. * * Retrieve in the device polled object list, the specified polled object * (command or attribute). * * @param obj_type The object type (command or attribute) * @param obj_name The object name * @return An iterator pointing to the polled object in the polled object list * @exception DevFailed Thrown if the object is not found. * Click here to read * DevFailed exception specification */ vector::iterator get_polled_obj_by_type_name(Tango::PollObjType obj_type,const string &obj_name); /** * Check if there is subscriber(s) listening for the event * * This method returns a boolean set to true if there are some subscriber(s) listening on the event specified * by the two method arguments. Be aware that there is some delay (up to 600 sec) between this method returning false * and the last subscriber unsubscription or crash... The device interface change event is not supported * by this method. * * @param att_name The attribute name * @param event_type The event type * @return A boolean set to true if there are some subscriber listening on this event * @exception DevFailed Thrown if the attribute is not found. * Click here to read * DevFailed exception specification */ bool is_there_subscriber(const string &att_name,EventType event_type); //@} /**@name Methods to build Tango array types. * These methods are helper methods to build Tango array types from an already * existing buffer (Tango array types are CORBA sequences) */ //@{ /** * Create a DevVarCharArray type. * * Create a DevVarCharArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarCharArray type data */ inline Tango::DevVarCharArray *create_DevVarCharArray(unsigned char *ptr,long length) { return new Tango::DevVarCharArray(length,length,ptr,false); } /** * Create a DevVarShortArray type. * * Create a DevVarShortArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarShortArray type data */ inline Tango::DevVarShortArray *create_DevVarShortArray(short *ptr,long length) { return new Tango::DevVarShortArray(length,length,ptr,false); } /** * Create a DevVarLongArray type. * * Create a DevVarLongArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarLongArray type data */ inline Tango::DevVarLongArray *create_DevVarLongArray(DevLong *ptr,long length) { return new Tango::DevVarLongArray(length,length,ptr,false); } /** * Create a DevVarLong64Array type. * * Create a DevVarLong64Array type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarLong64Array type data */ inline Tango::DevVarLong64Array *create_DevVarLong64Array(DevLong64 *ptr,long length) { return new Tango::DevVarLong64Array(length,length,ptr,false); } /** * Create a DevVarFloatArray type. * * Create a DevVarFloatArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarFloatArray type data */ inline Tango::DevVarFloatArray *create_DevVarFloatArray(float *ptr,long length) { return new Tango::DevVarFloatArray(length,length,ptr,false); } /** * Create a DevVarDoubleArray type. * * Create a DevVarDoubleArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarDoubleArray type data */ inline Tango::DevVarDoubleArray *create_DevVarDoubleArray(double *ptr,long length) { return new Tango::DevVarDoubleArray(length,length,ptr,false); } /** * Create a DevVarUShortArray type. * * Create a DevVarUShortArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarUShortArray type data */ inline Tango::DevVarUShortArray *create_DevVarUShortArray(unsigned short *ptr,long length) { return new Tango::DevVarUShortArray(length,length,ptr,false); } /** * Create a DevVarULongArray type. * * Create a DevVarULongArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarULongArray type data */ inline Tango::DevVarULongArray *create_DevVarULongArray(DevULong *ptr,long length) { return new Tango::DevVarULongArray(length,length,ptr,false); } /** * Create a DevVarULong64Array type. * * Create a DevVarULong64Array type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarULong64Array type data */ inline Tango::DevVarULong64Array *create_DevVarULong64Array(DevULong64 *ptr,long length) { return new Tango::DevVarULong64Array(length,length,ptr,false); } /** * Create a DevVarStringArray type. * * Create a DevVarStringArray type data and return a pointer to it. The array is * build using the input pointer with the given length * * @param ptr Pointer to the basic type data buffer * @param length Number of element in the previous buffer * * @return Pointer to the created DevVarStringArray type data */ inline Tango::DevVarStringArray *create_DevVarStringArray(char **ptr,long length) { return new Tango::DevVarStringArray(length,length,ptr,false); } //@} /**@name Push change event methods. * These methods allow to fire change events for attributes manually, * without the polling to be started. */ //@{ /** * Set an implemented flag for the attribute to indicate that the server fires change events manually, * without the polling to be started. * If the detect parameter is set to true, the criteria specified for the change * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without any value checking! * * @param attr_name The name of the attribute * @param implemented True when the server fires change events manually. * @param detect Triggers the verification of the change event properties when set to true. Default value is true. */ void set_change_event (string attr_name, bool implemented, bool detect = true); /** * Push a change event for a state or status attribute or return an exception as change * event for any attribute. * The event is pushed to the event system. * * The method needs the attribue name as input. * For the state and status attributes the actual state and status values are pushed. * In case of an exception, the exception is pushed as a change event for the attribute. * * @param attr_name The name of the attribute * @param except Pointer to a Tango::DevFailed exception. Default value is NULL. */ void push_change_event (string attr_name, DevFailed *except = NULL); /** * Push a change event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevLong *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevLong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevFloat *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevDouble *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevString *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevBoolean *p_data, long x = 1,long y = 0,bool release = false); /**void push_change_event (string attr_name, Tango::DevBoolea * Push a change event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevUShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevUChar *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevULong *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevULong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevULong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevState *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevEncoded *p_data, long x = 1,long y = 0,bool release = false); /** * Push a change event for an attribute with Tango::DevEncoded attribute data type * when the DevEncoded data are specified by two pointers. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_str_data Pointer to the data string part to be pushed * @param p_data Pointer to the data to be pushed * @param size The data number (pointed to by p_data) * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_change_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size,bool release = false); /** * Push a change event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevULong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_change_event (string attr_name, Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a change event for an attribute with Tango::DevEncoded attribute data type * when the data rea specified with two pointers. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the change event criteria depending * on the configuration choosen with set_change_event(). * * @param attr_name The name of the attribute * @param p_str_data Pointer to the data string part to be pushed * @param p_data Pointer to the data to be pushed * @param size Size of the data to be ushed (pointed to be p_data * @param t The time stamp * @param qual The attribute quality factor * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_change_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, struct _timeb &t, Tango::AttrQuality qual, bool release = false); #else void push_change_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, struct timeval &t, Tango::AttrQuality qual, bool release = false); #endif //@} /**@name Push archive event methods. * These methods allow to fire archive events for attributes manually, * without the polling to be started. */ //@{ /** * Set an implemented flag for the attribute to indicate that the server fires archive events manually, * without the polling to be started. * If the detect parameter is set to true, the criteria specified for the archive * event are verified and the event is only pushed if they are fulfilled. * If detect is set to false the event is fired without any value checking! * * @param attr_name The name of the attribute * @param implemented True when the server fires archive events manually. * @param detect Triggers the verification of the archive event properties when set to true. Default value is true. */ void set_archive_event (string attr_name, bool implemented, bool detect = true); /** * Push an archive event for state or status attribute or push an exception as archive * event for any attribute. * The event is pushed to the event system. * * The method needs the attribue name as input. * For the state and status attributes the actual state and status values are pushed. * In case of an exception, the exception is pushed as an archive event for the attribute. * * @param attr_name The name of the attribute * @param except Pointer to a Tango::DevFailed exception. Default value is NULL. */ void push_archive_event (string attr_name, DevFailed *except = NULL); /** * Push an archive event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevLong *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevLong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevFloat *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevDouble *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevString *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevBoolean *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevUShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevUChar *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevULong *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevULong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevState *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevEncoded *p_data, long x = 1,long y = 0,bool release = false); /** * Push an archive event for an attribute with Tango::DevEncoded attribute data type * when the data are specified using two pointers. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_str_data Pointer to the data string part to be pushed * @param p_data Pointer to the data part to be pushed * @param size Size of the data to be pushed (Pointed to by p_data) * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, bool release = false); /** * Push an archive event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevULong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_archive_event (string attr_name, Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push an archive event for an attribute with Tango::DevEncoded attribute data type * when it is specified using two pointers. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * The event is triggered with or without checking of the archive event criteria depending * on the configuration choosen with set_archive_event(). * * @param attr_name The name of the attribute * @param p_str_data Pointer to the data string part to be pushed * @param p_data Pointer to the data to be pushed * @param size Size of the data to be pushed (Pointed to by p_data) * @param t The time stamp * @param qual The attribute quality factor * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, struct _timeb &t, Tango::AttrQuality qual, bool release = false); #else void push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, struct timeval &t, Tango::AttrQuality qual, bool release = false); #endif //@} /**@name Push user event methods. * These methods allow to fire user events for attributes manually, * without the polling to be started. */ //@{ /** * Push a user event for a state or status attribute or return an exception as user * event for any attribute. * The event is pushed to the event system. * * The method needs the attribue name as input. * For the state and status attributes the actual state and status values are pushed. * In case of an exception, the exception is pushed as a user event for the attribute. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param except Pointer to a Tango::DevFailed exception. Default value is NULL. */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,DevFailed *except = NULL); /** * Push a user event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevFloat *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevDouble *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevBoolean *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUShort *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUChar *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevULong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong64 *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevState *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevEncoded *p_data, long x = 1,long y = 0,bool release = false); /** * Push a user event for an attribute with Tango::DevEncoded attribute data type * when the attribute data are specified with 2 pointers. * The event is pushed to the event system. * * The method needs the attribue name and a pointer to the data to be pushed as input. * Depending on the attribute type the dimensions x and why need to be given. * The time stamp of the event is set to the actual time and the attribute quality * is set to valid. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_str_data Pointer to the string sent with the data * @param p_data Pointer to the data to be pushed * @param size The data number (pointed to by p_data) * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, bool release = false); /** * Push a user event for an attribute with Tango::DevShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevLong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevLong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevFloat attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevDouble attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevString attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevBoolean attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevUShort attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevUChar attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevULong attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevULong64 attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevState attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevEncoded attribute data type. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param qual The attribute quality factor * @param x The attribute x length. Default value is 1 * @param y The attribute y length. Default value is 0 * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x = 1,long y = 0,bool release = false); #endif /** * Push a user event for an attribute with Tango::DevEncoded attribute data type * when the string part and the data part of the DevEncoded data are specified * separately. * The event is pushed to the event system. * * The method needs the attribue name, a pointer to the data to be pushed, the time stamp * for the data and the attribute quality factor as input. * Depending on the attribute type the dimensions x and why need to be given. * * @param attr_name The name of the attribute * @param filt_names The filterable fields name * @param filt_vals The filterable fields value (as double) * @param p_str_data Pointer to the data string part * @param p_data Pointer to the data to be pushed * @param size The data number (pointed to by p_data) * @param t The time stamp * @param qual The attribute quality factor * @param release The release flag. If true, memory pointed to by p_data will be * freed after being send to the client. Default value is false. * @exception DevFailed If the attribute data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_str_data,Tango::DevUChar *p_data, long size, struct _timeb &t, Tango::AttrQuality qual,bool release = false); #else void push_event (string attr_name,vector &filt_names,vector &filt_vals,Tango::DevString *p_str_data,Tango::DevUChar *p_data, long size, struct timeval &t, Tango::AttrQuality qual,bool release = false); #endif //@} /**@name Push data ready event methods * This method allows the user to push a data ready event */ //@{ /** * Set an implemented flag for the attribute to indicate that the server fires data ready event * for this attribute. * * @param attr_name The name of the attribute * @param implemented True when the server fires data ready event. */ void set_data_ready_event (string attr_name, bool implemented); /** * Push a data ready event for the attribute with name specified as the first * parameter. * The event is pushed to the event system. * * The method needs only the attribue name and an optional "counter" which * will be passed unchanged within the event * * @param attr_name The name of the attribute * @param ctr The user counter * * @exception DevFailed If the attribute name is unknown. * Click here to read * DevFailed exception specification */ void push_data_ready_event (const string &attr_name,Tango::DevLong ctr = 0); //@} /**@name Push pipe event methods. * These methods allow to fire pipe events */ //@{ /** * Push a pipe event with exception data as value * The method needs the pipe name as input. * * @param pipe_name The name of the pipe * @param except Pointer to a Tango::DevFailed exception. */ void push_pipe_event (const string &pipe_name, DevFailed *except); /** * Push a pipe event. * * The method needs the pipe name and a pointer to the pipe blob to be pushed as input. * The time stamp of the event is set to the actual time. * * @param pipe_name The name of the pipe * @param p_data Pointer to the Pipe blob to be sent with the event * @param reuse_it Flag set to true if you don want the push_pipe_event to consume Pipe internal memory. Default value * is false which covers 95% of use cases * @exception DevFailed If the pipe data type is not coherent. * Click here to read * DevFailed exception specification */ void push_pipe_event (const string &pipe_name,Tango::DevicePipeBlob *p_data,bool reuse_it=false); /** * Push a pipe event with a specified timestamp. * * The method needs the pipe name, a pointer to the pipe blob to be pushed and the time stamp * for the data as input. * * @param pipe_name The name of the pipe * @param p_data Pointer to the data to be pushed * @param t The time stamp * @param reuse_it Flag set to true if you don want the push_pipe_event to consume Pipe internal memory. Default value * is false which covers 95% of use cases * @exception DevFailed If the pipe data type is not coherent. * Click here to read * DevFailed exception specification */ #ifdef _TG_WINDOWS_ void push_pipe_event (const string &pipe_name, Tango::DevicePipeBlob *p_data, struct _timeb &t,bool reuse_it=false); #else void push_pipe_event (const string &pipe_name, Tango::DevicePipeBlob *p_data, struct timeval &t,bool reuse_it=false); #endif //@} /**@name Signal related methods * These methods allow a signal management at device level */ //@{ #ifndef _TG_WINDOWS_ /** * Register a signal to be executed in a signal handler. * * Register this device as device to be informed when signal signo is sent to * to the device server process. This method is available only under Linux. * * @param signo The signal number * @param own_handler A boolean set to true if you want the device signal handler * to be executed in its own handler instead of being executed by the signal * thread. If this parameter is set to true, care should be taken on how the * handler is written. A default false value is provided * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to register a signal for the process. * Click here to read * DevFailed exception specification */ void register_signal(long signo,bool own_handler = false); #else /** * Register a signal. * * Register this device as device to be informed when signal signo is sent to * to the device server process * * @param signo The signal number * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to register a signal for the process. * Click here to read * DevFailed exception specification */ void register_signal(long signo); #endif /** * Unregister a signal. * * Unregister this device as device to be informed when signal signo is sent to * to the device server process * * @param signo The signal number * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to unregister a signal for the process. Unregister * a device for a signal number for a device not previously registered is not * an error. This simply will do nothing. * Click here to read * DevFailed exception specification */ void unregister_signal(long signo); /** * Signal handler. * * The method executed when the signal arrived in the device server process. * This method is defined as virtual and then, can be redefined following * device needs. * * @param signo The signal number */ virtual void signal_handler(long signo); //@} // // Device class data members // protected: /**@name Class data members */ //@{ /** * The device black box pointer */ BlackBox *blackbox_ptr; /** * The device black box depth */ long blackbox_depth; /** * The device name */ string device_name; /** * The device description */ string desc; /** * The device status */ string device_status; /** * The device state */ Tango::DevState device_state; /** * The device version */ long version; /** * Pointer to the device-class object associated with the device */ DeviceClass *device_class; /** * Pointer to the multi attribute object */ MultiAttribute *dev_attr; /** * Pointer to the associated DbDevice object */ DbDevice *db_dev; /** * The administration device name */ string adm_device_name; //@} public: /// @privatesection typedef struct _FwdWrongConf { string att_name; string full_root_att_name; FwdAttError fae; }FwdWrongConf; virtual char *name(); virtual char *adm_name(); virtual char *description(); virtual char *status(); virtual Tango::DevState state(); virtual CORBA::Any *command_inout(const char *in_cmd,const CORBA::Any &in_data); virtual Tango::DevVarStringArray *black_box(CORBA::Long n); virtual Tango::DevCmdInfoList *command_list_query(); virtual Tango::DevCmdInfo *command_query(const char *command); virtual Tango::DevInfo *info(); virtual void ping(); virtual Tango::AttributeConfigList* get_attribute_config(const Tango::DevVarStringArray& names); virtual void set_attribute_config(const Tango::AttributeConfigList& new_conf); virtual Tango::AttributeValueList* read_attributes(const Tango::DevVarStringArray& names); virtual void write_attributes(const Tango::AttributeValueList& values); void set_exported_flag(bool exp) {exported = exp;} bool get_exported_flag() {return exported;} void set_poll_ring_depth(long depth) {poll_ring_depth = depth;} long get_poll_ring_depth() {return poll_ring_depth;} void set_poll_old_factor(long fact) {poll_old_factor = fact;} long get_poll_old_factor() {return poll_old_factor;} void is_polled(bool poll) {polled = poll;} bool is_polled() {return polled;} vector &get_polled_cmd() {return polled_cmd;} vector &get_polled_attr() {return polled_attr;} vector &get_non_auto_polled_cmd() {return non_auto_polled_cmd;} vector &get_non_auto_polled_attr() {return non_auto_polled_attr;} vector &get_poll_obj_list() {return poll_obj_list;} void stop_polling(bool); void stop_polling() {stop_polling(true);} void check_command_exists(const string &); Command *get_command(const string &); string &get_name_lower() {return device_name_lower;} TangoMonitor &get_dev_monitor() {return only_one;} TangoMonitor &get_poll_monitor() {return poll_mon;} TangoMonitor &get_att_conf_monitor() {return att_conf_mon;} TangoMonitor &get_pipe_conf_monitor() {return pipe_conf_mon;} long get_dev_idl_version() {return idl_version;} long get_cmd_poll_ring_depth(string &); long get_attr_poll_ring_depth(string &); vector &get_alarmed_not_read() {return alrmd_not_read;} void poll_lists_2_v5(); bool is_py_device() {return py_device;} void set_py_device(bool py) {py_device=py;} Tango::client_addr *get_client_ident(); void lock(client_addr *,int); void relock(client_addr *); Tango::DevLong unlock(bool); void basic_unlock(bool forced = false); bool valid_lock(); Tango::DevVarLongStringArray *lock_status(); bool is_device_locked() {return device_locked;} client_addr *get_locker() {return locker_client;} client_addr *get_old_locker() {return old_locker_client;} time_t get_locking_date() {return locking_date;} Tango::DevLong get_locking_ctr() {return lock_ctr;} Tango::DevLong get_lock_validity() {return lock_validity;} void clean_locker_ptrs() {locker_client=NULL;old_locker_client=NULL;} void set_locking_param(client_addr *,client_addr *,time_t,DevLong,DevLong); void set_alias_name_lower(string &al) {alias_name_lower = al;} string &get_alias_name_lower() {return alias_name_lower;} void push_att_conf_event(Attribute *); void data_into_net_object(Attribute &,AttributeIdlData &,long,AttrWriteType,bool); void polled_data_into_net_object(AttributeIdlData &,long,long,long,PollObj *,const DevVarStringArray &); int get_min_poll_period() {return min_poll_period;} vector &get_cmd_min_poll_period() {return cmd_min_poll_period;} vector &get_attr_min_poll_period() {return attr_min_poll_period;} void init_cmd_poll_ext_trig (string cmd_name); void init_attr_poll_ext_trig (string cmd_name); void set_run_att_conf_loop(bool val) {run_att_conf_loop=val;} vector &get_att_wrong_db_conf() {return att_wrong_db_conf;} void check_att_conf(); bool is_alarm_state_forced() {return force_alarm_state;} vector &get_att_mem_failed() {return att_mem_failed;} vector &get_fwd_att_wrong_conf() {return fwd_att_wrong_conf;} void rem_wrong_fwd_att(const string &); void update_wrong_conf_att(const string &,FwdAttError); void set_with_fwd_att(bool _b) {with_fwd_att=_b;} bool get_with_fwd_att() {return with_fwd_att;} void set_call_source(DevSource _s) {call_source=_s;} DevSource get_call_source() {return call_source;} vector &get_local_command_list() {return command_list;} Command &get_local_cmd_by_name(const string &); void remove_local_command(const string &); void set_event_intr_change_subscription(time_t _t) {event_intr_change_subscription=_t;} time_t get_event_intr_change_subscription() {return event_intr_change_subscription;} void enable_intr_change_ev() {intr_change_ev = true;} void disable_intr_change_ev() {intr_change_ev = false;} bool is_intr_change_ev_enable() {return intr_change_ev;} void get_event_param(vector &); void set_event_param(vector &); void set_client_lib(int _l) {if (count(client_lib.begin(),client_lib.end(),_l)==0)client_lib.push_back(_l);} #ifdef TANGO_HAS_LOG4TANGO inline log4tango::Logger *get_logger(void) {return logger ? logger : get_logger_i();} void init_logger(void); void start_logging(void); void stop_logging(void); #endif // TANGO_HAS_LOG4TANGO private: // // The extension class // class DeviceImplExt { public: DeviceImplExt():alarm_state_user(0),alarm_state_kernel(0) {}; time_t alarm_state_user; time_t alarm_state_kernel; }; protected: /// @privatesection void check_lock(const char *,const char *cmd = NULL); void throw_locked_exception(const char *meth); void init_cmd_poll_period(); void init_attr_poll_period(); void init_poll_no_db(); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else DeviceImplExt *ext; #endif DevVarShortArray dummy_short_att_value; DevVarLongArray dummy_long_att_value; DevVarLong64Array dummy_long64_att_value; DevVarFloatArray dummy_float_att_value; DevVarDoubleArray dummy_double_att_value; DevVarStringArray dummy_string_att_value; DevVarBooleanArray dummy_boolean_att_value; DevVarUShortArray dummy_ushort_att_value; DevVarCharArray dummy_uchar_att_value; DevVarULongArray dummy_ulong_att_value; DevVarULong64Array dummy_ulong64_att_value; DevVarStateArray dummy_state_att_value; DevVarEncodedArray dummy_encoded_att_value; // // Ported from the extension class // #ifdef TANGO_HAS_LOG4TANGO log4tango::Logger* logger; log4tango::Level::Value saved_log_level; size_t rft; #endif long poll_old_factor; long idl_version; bool exported; bool polled; long poll_ring_depth; vector polled_cmd; vector polled_attr; vector non_auto_polled_cmd; vector non_auto_polled_attr; vector poll_obj_list; TangoMonitor only_one; // Device monitor Tango::DevState device_prev_state; // Device previous state string device_name_lower; vector cmd_poll_ring_depth; vector attr_poll_ring_depth; bool store_in_bb; TangoMonitor poll_mon; // Polling list monitor TangoMonitor att_conf_mon; // Attribute config monitor TangoMonitor pipe_conf_mon; // Pipe config monitor bool state_from_read; vector alrmd_not_read; bool py_device; string alias_name_lower; // Alias name (if any) bool device_locked; client_addr *locker_client; client_addr *old_locker_client; DevLong lock_validity; time_t locking_date; string lock_stat; DevLong lock_ctr; long min_poll_period; vector cmd_min_poll_period; vector attr_min_poll_period; bool run_att_conf_loop; bool force_alarm_state; vector att_wrong_db_conf; vector att_mem_failed; vector fwd_att_wrong_conf; bool with_fwd_att; DevSource call_source; vector command_list; time_t event_intr_change_subscription; bool intr_change_ev; TangoMonitor devintr_mon; ShDevIntrTh devintr_shared; DevIntrThread *devintr_thread; vector client_lib; // Dev Intr change event client(s) IDL private: // // Private enum // typedef enum _AttErrorType { CONF = 0, MEM, FWD }AttErrorType; typedef enum _PipePropType { LABEL = 0, DESCRIPTION }PipePropType; // // Some private methods and variables // void get_dev_system_resource(); void black_box_create(); void real_ctor(); void poll_object(const string &,int,PollObjType); void stop_poll_object(const string &,PollObjType); void att_conf_loop(); void build_att_list_in_status_mess(size_t,AttErrorType); void lock_root_devices(int,bool); void push_dev_intr(bool); void end_pipe_config(); void set_pipe_prop(vector &,Pipe *,PipePropType); #ifdef TANGO_HAS_LOG4TANGO log4tango::Logger *get_logger_i (void); #endif string alarm_status; Tango::Device_var d_var; PortableServer::ObjectId_var obj_id; protected: }; inline void DeviceImpl::set_state(const Tango::DevState &new_state) { device_prev_state = device_state; device_state = new_state; if (new_state == Tango::ALARM) ext->alarm_state_user = time(NULL); else ext->alarm_state_user = 0; } #define DATA_IN_NET_OBJECT(A,B,C,D,E) \ do \ { \ if (aid.data_5 != Tango_nullptr) \ { \ AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); \ (*aid.data_5)[index].value.A(att_val.value.A()); \ } \ else if (aid.data_4 != Tango_nullptr) \ { \ if (vers >= 5) \ { \ AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); \ (*aid.data_4)[index].value.A(att_val.value.A()); \ } \ else \ { \ AttributeValue_4 &att_val = polled_att->get_last_attr_value_4(false); \ (*aid.data_4)[index].value.A(att_val.value.A()); \ } \ } \ else \ { \ if (vers >= 5) \ { \ AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); \ B &union_seq = att_val.value.A(); \ D = new B(union_seq.length(), \ union_seq.length(), \ const_cast(union_seq.get_buffer()), \ false); \ } \ else if (vers == 4) \ { \ AttributeValue_4 &att_val = polled_att->get_last_attr_value_4(false); \ B &union_seq = att_val.value.A(); \ D = new B(union_seq.length(), \ union_seq.length(), \ const_cast(union_seq.get_buffer()), \ false); \ } \ else \ { \ AttributeValue_3 &att_val = polled_att->get_last_attr_value_3(false); \ att_val.value >>= E; \ D = new B(E->length(), \ E->length(), \ const_cast(E->get_buffer()), \ false); \ } \ (*aid.data_3)[index].value <<= D; \ } \ } \ while (false) #define DATA_IN_OBJECT(A,B,C,D) \ do \ { \ Tango::A *ptr = att.B(); \ if (aid.data_5 != Tango_nullptr) \ { \ (*aid.data_5)[index].value.D(C); \ A &the_seq = (*aid.data_5)[index].value.D(); \ the_seq.replace(ptr->length(),ptr->length(),ptr->get_buffer(),ptr->release()); \ if (ptr->release() == true) \ ptr->get_buffer(true); \ } \ else if (aid.data_4 != Tango_nullptr) \ { \ (*aid.data_4)[index].value.D(C); \ A &the_seq = (*aid.data_4)[index].value.D(); \ the_seq.replace(ptr->length(),ptr->length(),ptr->get_buffer(),ptr->release()); \ if (ptr->release() == true) \ ptr->get_buffer(true); \ } \ else \ { \ (*aid.data_3)[index].value <<= *ptr; \ } \ \ if (del_seq == true) \ delete ptr; \ } \ while (false) } // End of Tango namespace #endif // _DEVICE_H tango-9.2.5a/lib/cpp/server/device_2.h0000644023471100065110000003005013034745001014410 00000000000000//============================================================================= // // file : Device.h // // description : Include for the Device root classes. // Three classes are declared in this file : // The Device class // The DeviceClass class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _DEVICE_2_H #define _DEVICE_2_H #include namespace Tango { class DeviceClass; //============================================================================= // // The Device_2Impl class // // // description : This class is derived directly from the Tango::Device_skel // class generated by CORBA. It represents the CORBA // servant which will be accessed by the client. // It implements all the methods // and attributes defined in the IDL interface for Device. // //============================================================================= /** * Base class for all TANGO device since version 2. * * This class inherits from DeviceImpl class which itself inherits from * CORBA classes where all the network layer is implemented. * This class has been created since release 2 of Tango library where the IDL * Tango module has been modified in order to create a Device_2 interface * which inherits from the original Device interface * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class Device_2Impl : public virtual POA_Tango::Device_2, public DeviceImpl { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Device_2Impl object from its name. * * The device description field is set to A Tango device. The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * */ Device_2Impl(DeviceClass *device_class,string &dev_name); /** * Constructs a newly allocated Device_2Impl object from its name and its description. * * The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * */ Device_2Impl(DeviceClass *device_class,string &dev_name,string &desc); /** * Constructs a newly allocated Device_2Impl object from all its creation * parameters. * * The device is constructed from its name, its description, an original state * and status * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_2Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status); /** * Constructs a newly allocated Device_2Impl object from all its creation * parameters with some default values. * * The device is constructed from its name, its description, an original state * and status. This constructor defined default values for the description, * state and status parameters. The default device description is A TANGO device. * The default device state is UNKNOWN and the default device status * is Not initialised. * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device desc * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_2Impl(DeviceClass *device_class, const char *dev_name,const char *desc = "A TANGO device", Tango::DevState dev_state = Tango::UNKNOWN, const char *dev_status = StatusNotSet); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device desctructor. */ virtual ~Device_2Impl() {} //@} /**@name CORBA operation methods * Method defined to implement TANGO device CORBA operation */ //@{ /** * Execute a command. * * It's the master method executed when a "command_inout_2" CORBA operation is * requested by a client. It updates the device black-box, call the * TANGO command handler and returned the output Any * * @param in_cmd The command name * @param in_data The command input data packed in a CORBA Any * @param source The data source. This parameter is new in Tango release 2. It * allows a client to choose the data source between the device itself or the * data cache for polled command. * @return The command output data packed in a CORBA Any object * @exception DevFailed Re-throw of the exception thrown by the command_handler * method. * Click here to read * DevFailed exception specification */ virtual CORBA::Any *command_inout_2(const char *in_cmd, const CORBA::Any &in_data, Tango::DevSource source); /** * Get device command list. * * Invoked when the client request the command_list_query_2 CORBA operation. * It updates the device black box and returns an array of DevCmdInfo_2 object * with one object for each command. * * @return The device command list. One DevCmdInfo_2 is initialised for each * device command. Since Tango release 2, the command display level field has * been added to this structure */ virtual Tango::DevCmdInfoList_2 *command_list_query_2(); /** * Get command info. * * Invoked when the client request the command_query_2 CORBA operation. * It updates the device black box and returns a DevCmdInfo_2 object for the * command with name passed * to the method as parameter. * * @param command The command name * @return A DevCmdInfo_2 initialised for the wanted command. * @exception DevFailed Thrown if the command does not exist. * Since Tango release 2, the command display level field has * been added to this structure. * Click here to read * DevFailed exception specification */ virtual Tango::DevCmdInfo_2 *command_query_2(const char *command); /** * Read attribute(s) value. * * Invoked when the client request the read_attributes_2 CORBA operation. * It returns to the client one AttributeValue structure for each wanted * attribute. * * @param names The attribute(s) name list * @param source The data source. This parameter is new in Tango release 2. It * allows a client to choose the data source between the device itself or the * data cache for polled attribute. * @return A sequence of AttributeValue structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList *read_attributes_2(const Tango::DevVarStringArray& names, Tango::DevSource source); /** * Get attribute(s) configuration. * * Invoked when the client request the get_attribute_config_2 CORBA operation. * It returns to the client one AttributeConfig_2 structure for each wanted * attribute. All the attribute properties value are returned in this * AttributeConfig_2 structure. Since Tango release 2, the attribute display * level field has been added to this structure. * * @param names The attribute(s) name list * @return A sequence of AttributeConfig_2 structure. One structure is initialised * for each wanted attribute. Click here * to read AttributeConfig_2 structure specification. * * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeConfigList_2 *get_attribute_config_2(const Tango::DevVarStringArray& names) throw(Tango::DevFailed, CORBA::SystemException); /** * Read attribute value history. * * Invoked when the client request the read_attribute_history_2 CORBA operation. * This operation allows a client to retrieve attribute value history for * polled attribute. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevAttrHistory structure for each record. * * @param name The attribute name * @param n The record number. * @return A sequence of DevAttrHistory structure. One structure is initialised * for each record with the attribute value, the date and in case of the attribute * returns an error when it was read, the DevErrors data. * Click here * to read DevAttrHistory structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevAttrHistoryList *read_attribute_history_2(const char* name, CORBA::Long n) throw(Tango::DevFailed, CORBA::SystemException); /** * Read command value history. * * Invoked when the client request the command_inout_history_2 CORBA operation. * This operation allows a client to retrieve command return value history for * polled command. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevCmdHistory structure for each record. * * @param command The command name * @param n The record number. * @return A sequence of DevCmdHistory structure. One structure is initialised * for each record with the command return value (in an Any), the date * and in case of the command returns an error when it was read, the * DevErrors data. * Click here * to read DevCmdHistory structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevCmdHistoryList *command_inout_history_2(const char* command, CORBA::Long n) throw(Tango::DevFailed, CORBA::SystemException); //@} private: CORBA::Any *attr2cmd(AttributeValue_3 &,bool,bool); CORBA::Any *attr2cmd(AttributeValue_4 &,bool,bool); CORBA::Any *attr2cmd(AttributeValue_5 &,bool,bool); void Hist_32Hist(DevAttrHistoryList_3 *,DevAttrHistoryList *); void Polled_2_Live(long,Tango::AttrValUnion &,CORBA::Any &); void Polled_2_Live(long,CORBA::Any &,CORBA::Any &); class Device_2ImplExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_2; // Class extension #else Device_2ImplExt *ext_2; #endif }; } // End of Tango namespace #endif // _DEVICE_H tango-9.2.5a/lib/cpp/server/device_3.h0000644023471100065110000003075513034745001014425 00000000000000//============================================================================= // // file : Device.h // // description : Include for the Device root classes. // Three classes are declared in this file : // The Device class // The DeviceClass class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 18607 // //============================================================================= #ifndef _DEVICE_3_H #define _DEVICE_3_H #include namespace Tango { class DeviceClass; class AttributeValueList_4; //============================================================================= // // The Device_3Impl class // // // description : This class is derived directly from the Tango::Device_skel // class generated by CORBA. It represents the CORBA // servant which will be accessed by the client. // It implements all the methods // and attributes defined in the IDL interface for Device. // //============================================================================= struct AttIdx { long idx_in_names; long idx_in_multi_attr; bool failed; }; /** * Base class for all TANGO device since version 3. * * This class inherits from DeviceImpl class which itself inherits from * CORBA classes where all the network layer is implemented. * This class has been created since release 3 of Tango library where the IDL * Tango module has been modified in order to create a Device_3 interface * which inherits from the original Device interface * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class Device_3Impl : public virtual POA_Tango::Device_3, public Device_2Impl { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Device_3Impl object from its name. * * The device description field is set to A Tango device. The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * */ Device_3Impl(DeviceClass *device_class,string &dev_name); /** * Constructs a newly allocated Device_3Impl object from its name and its description. * * The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * */ Device_3Impl(DeviceClass *device_class,string &dev_name,string &desc); /** * Constructs a newly allocated Device_3Impl object from all its creation * parameters. * * The device is constructed from its name, its description, an original state * and status * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_3Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status); /** * Constructs a newly allocated Device_3Impl object from all its creation * parameters with some default values. * * The device is constructed from its name, its description, an original state * and status. This constructor defined default values for the description, * state and status parameters. The default device description is A TANGO device. * The default device state is UNKNOWN and the default device status * is Not initialised. * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device desc * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_3Impl(DeviceClass *device_class, const char *dev_name,const char *desc = "A TANGO device", Tango::DevState dev_state = Tango::UNKNOWN, const char *dev_status = StatusNotSet); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device desctructor. */ #ifdef HAS_UNIQUE_PTR virtual ~Device_3Impl() {} #else virtual ~Device_3Impl() {delete ext_3;} #endif //@} /**@name CORBA operation methods * Method defined to implement TANGO device CORBA operation */ //@{ /** * Read attribute(s) value. * * Invoked when the client request the read_attributes_2 CORBA operation. * It returns to the client one AttributeValue structure for each wanted * attribute. * * @param names The attribute(s) name list * @param source The data source. This parameter is new in Tango release 2. It * allows a client to choose the data source between the device itself or the * data cache for polled attribute. * @return A sequence of AttributeValue structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue_3 structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList_3 *read_attributes_3(const Tango::DevVarStringArray& names, Tango::DevSource source); /** * Write attribute(s) value. * * Invoked when the client request the write_attributes CORBA operation. * It sets the attribute(s) with the new value(s) passed as parameter. * * @param values The attribute(s) new value(s). One structure is initialised * for each wanted attribute with the attribute value. The attribute quality and * date are not used by this method. * Click here * to read AttributeValue structure definition. * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void write_attributes_3(const Tango::AttributeValueList& values); /** * Read attribute value history. * * Invoked when the client request the read_attribute_history_3 CORBA operation. * This operation allows a client to retrieve attribute value history for * polled attribute. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevAttrHistory structure for each record. * * @param name The attribute name * @param n The record number. * @return A sequence of DevAttrHistory structure. One structure is initialised * for each record with the attribute value, the date and in case of the attribute * returns an error when it was read, the DevErrors data. * Click here * to read DevAttrHistory_3 structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevAttrHistoryList_3 *read_attribute_history_3(const char* name, CORBA::Long n); /** * Get device info. * * Invoked when the client request the info CORBA operation. * It updates the black box and returns a DevInfo object * with miscellaneous device info * * @return A DevInfo object */ virtual Tango::DevInfo_3 *info_3(); /** * Get attribute(s) configuration. * * Invoked when the client request the get_attribute_config_3 CORBA operation. * It returns to the client one AttributeConfig_3 structure for each wanted * attribute. All the attribute properties value are returned in this * AttributeConfig_3 structure. Since Tango release 3, the attribute event * related, the attribute warning alarm and attribute rds alarm properties * have been added to the returned structures. * * @param names The attribute(s) name list * @return A sequence of AttributeConfig_3 structure. One structure is initialised * for each wanted attribute. Click here * to read AttributeConfig_3 structure specification. * * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeConfigList_3 *get_attribute_config_3(const Tango::DevVarStringArray& names); /** * Set attribute(s) configuration. * * Invoked when the client request the set_attribute_config_3 CORBA operation. * It updates the device attribute configuration actually used by the device but * this method also updates the Tango database. One structure of the * AttributeConfig_3 type is needed for each attribute to update configuration. * Click here * to read AttributeConfig_3 structure specification. * * @param new_conf The attribute(s) new configuration structure sequence * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void set_attribute_config_3(const Tango::AttributeConfigList_3& new_conf); //@} /// @privatesection void write_attributes_in_db(vector &,vector &); void add_state_status_attrs(); void read_attributes_from_cache(const Tango::DevVarStringArray&,Tango::AttributeIdlData &); void delete_dev() {ext_3->delete_dev();} void get_attr_props(const char *,vector &); protected: /// @privatesection void read_attributes_no_except(const Tango::DevVarStringArray&,Tango::AttributeIdlData &,bool,vector &); void write_attributes_in_db(vector &,vector &); void add_alarmed(vector &); long reading_state_necessary(vector &); void state2attr(Tango::DevState,Tango::AttributeValue_3 &); void state2attr(Tango::DevState,Tango::AttributeValue_4 &); void state2attr(Tango::DevState,Tango::AttributeValue_5 &); void status2attr(Tango::ConstDevString,Tango::AttributeValue_3 &); void status2attr(Tango::ConstDevString,Tango::AttributeValue_4 &); void status2attr(Tango::ConstDevString,Tango::AttributeValue_5 &); void alarmed_not_read(vector &); void write_attributes_34(const Tango::AttributeValueList *,const Tango::AttributeValueList_4 *); template void set_attribute_config_3_local(const T &,const V &,bool,int); template void error_from_devfailed(T &,DevFailed &,const char *); template void error_from_errorlist(T &,DevErrorList &,const char *); template void one_error(T &,const char *,const char *,string &,Attribute &); template void one_error(T &,const char *,const char *,string &,const char *); template void init_polled_out_data(T &,V &); template void init_out_data(T &,Attribute &,AttrWriteType &); template void init_out_data_quality(T &,Attribute &,AttrQuality); template void base_state2attr(T &); template void base_status2attr(T &); private: class Device_3ImplExt { public: Device_3ImplExt() {} virtual ~Device_3ImplExt() {} virtual void delete_dev() {} }; void real_ctor(); #ifdef HAS_UNIQUE_PTR unique_ptr ext_3; // Class extension #else Device_3ImplExt *ext_3; #endif }; } // End of Tango namespace #endif // _DEVICE_H tango-9.2.5a/lib/cpp/server/device_4.h0000644023471100065110000003250013034745002014415 00000000000000//============================================================================= // // file : Device.h // // description : Include for the Device root classes. // Three classes are declared in this file : // The Device class // The DeviceClass class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // //============================================================================= #ifndef _DEVICE_4_H #define _DEVICE_4_H #include namespace Tango { //============================================================================= // // The Device_4Impl class // // // description : This class is derived directly from the Tango::Device_skel // class generated by CORBA. It represents the CORBA // servant which will be accessed by the client. // It implements all the methods // and attributes defined in the IDL interface for Device. // //============================================================================= /** * Base class for all TANGO device since version 4. * * This class inherits from DeviceImpl class which itself inherits from * CORBA classes where all the network layer is implemented. * This class has been created since release 7 of Tango library where the IDL * Tango module has been modified in order to create a Device_4 interface * which inherits from the original Device interface * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class Device_4Impl : public virtual POA_Tango::Device_4, public Device_3Impl { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Device_4Impl object from its name. * * The device description field is set to A Tango device. The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * */ Device_4Impl(DeviceClass *device_class,string &dev_name); /** * Constructs a newly allocated Device_4Impl object from its name and its description. * * The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * */ Device_4Impl(DeviceClass *device_class,string &dev_name,string &desc); /** * Constructs a newly allocated Device_4Impl object from all its creation * parameters. * * The device is constructed from its name, its description, an original state * and status * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_4Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status); /** * Constructs a newly allocated Device_4Impl object from all its creation * parameters with some default values. * * The device is constructed from its name, its description, an original state * and status. This constructor defined default values for the description, * state and status parameters. The default device description is A TANGO device. * The default device state is UNKNOWN and the default device status * is Not initialised. * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device desc * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_4Impl(DeviceClass *device_class, const char *dev_name,const char *desc = "A TANGO device", Tango::DevState dev_state = Tango::UNKNOWN, const char *dev_status = StatusNotSet); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device desctructor. */ virtual ~Device_4Impl() {} //@} /**@name CORBA operation methods * Method defined to implement TANGO device CORBA operation */ //@{ /** * Read attribute value history. * * Invoked when the client request the read_attribute_history_3 CORBA operation. * This operation allows a client to retrieve attribute value history for * polled attribute. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevAttrHistory structure for each record. * * @param name The attribute name * @param n The record number. * @return A DevAttrHistory_4 structure. This strucure contains all the element * allowing a client to retrieve for each history record the attribute value, * the date and in case of the attribute * returns an error when it was read, the DevErrors data. * Click here * to read DevAttrHistory structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevAttrHistory_4 *read_attribute_history_4(const char* name, CORBA::Long n); /** * Read command value history. * * Invoked when the client request the command_inout_history_2 CORBA operation. * This operation allows a client to retrieve command return value history for * polled command. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevCmdHistory structure for each record. * * @param command The command name * @param n The record number. * @return A DevCmdHistory_4 structure. This strucure contains all the element * allowing a client to retrieve for each history record the command return value * (in an Any), the date and in case of the command returns an error when it was read, the * DevErrors data. * Click here * to read DevCmdHistory structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevCmdHistory_4 *command_inout_history_4(const char* command, CORBA::Long n); /** * Execute a command. * * It's the master method executed when a "command_inout_4" CORBA operation is * requested by a client. It checks the device lock, updates the device black-box, call the * TANGO command handler and returned the output Any * * @param in_cmd The command name * @param in_data The command input data packed in a CORBA Any * @param source The data source. This parameter is new in Tango release 2. It * allows a client to choose the data source between the device itself or the * data cache for polled command. * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return The command output data packed in a CORBA Any object * @exception DevFailed Re-throw of the exception thrown by the command_handler * method. * Click here to read * DevFailed exception specification */ virtual CORBA::Any *command_inout_4(const char *in_cmd, const CORBA::Any &in_data, Tango::DevSource source, const Tango::ClntIdent &cl_ident); /** * Read attribute(s) value. * * Invoked when the client request the read_attributes_2 CORBA operation. * It returns to the client one AttributeValue structure for each wanted * attribute. * * @param names The attribute(s) name list * @param source The data source. This parameter is new in Tango release 2. It * allows a client to choose the data source between the device itself or the * data cache for polled attribute. * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A sequence of AttributeValue_4 structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList_4 *read_attributes_4(const Tango::DevVarStringArray& names, Tango::DevSource source, const Tango::ClntIdent &cl_ident); /** * Write attribute(s) value. * * Invoked when the client request the write_attributes CORBA operation. * It sets the attribute(s) with the new value(s) passed as parameter. * * @param values The attribute(s) new value(s). One structure is initialised * for each wanted attribute with the attribute value. The attribute quality and * date are not used by this method. * Click here * to read AttributeValue_4 structure definition. * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void write_attributes_4(const Tango::AttributeValueList_4 &values, const Tango::ClntIdent &cl_ident); /** * Set attribute(s) configuration. * * Invoked when the client request the set_attribute_config_3 CORBA operation. * It updates the device attribute configuration actually used by the device but * this method also updates the Tango database. One structure of the * AttributeConfig_3 type is needed for each attribute to update configuration. * Click here * to read AttributeConfig_3 structure specification. * * @param new_conf The attribute(s) new configuration structure sequence * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void set_attribute_config_4(const Tango::AttributeConfigList_3& new_conf, const Tango::ClntIdent &cl_ident); /** * Write then read attribute(s) value. * * Invoked when the client request the write_read_attributes CORBA operation. * It sets the attribute(s) with the new value(s) passed as parameter * and then read the attribute(s) and return the read value to the caller. * * @param values The attribute(s) new value(s). One structure is initialised * for each wanted attribute with the attribute value. The attribute quality and * date are not used by this method. * Click here * to read AttributeValue structure definition. * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A sequence of AttributeValue_4 structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue_4 structure definition. * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList_4* write_read_attributes_4(const Tango::AttributeValueList_4 &values, const Tango::ClntIdent &cl_ident); //@} private: class Device_4ImplExt { public: Device_4ImplExt() {} ~Device_4ImplExt() {} }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_4; // Class extension #else Device_4ImplExt *ext_4; #endif }; } // End of Tango namespace #endif // _DEVICE_4_H tango-9.2.5a/lib/cpp/server/device_5.h0000644023471100065110000003652013034745001014423 00000000000000//=================================================================================================================== // // file : Device_5.h // // description : Include for the Device root classes in its release 5 (IDL release 5, Tango release 9) // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 20742 $ // //=================================================================================================================== #ifndef _DEVICE_5_H #define _DEVICE_5_H #include namespace Tango { class WPipe; //================================================================================================================== // // The Device_5Impl class // // // description : // This class is derived directly from the Tango::Device_skel class generated by CORBA. It represents the CORBA // servant which will be accessed by the client. It implements all the methods and attributes defined in the // IDL interface for Device. // //================================================================================================================== /** * Base class for all TANGO device since version 5. * * This class inherits from DeviceImpl class which itself inherits from * CORBA classes where all the network layer is implemented. * This class has been created since release 7 of Tango library where the IDL * Tango module has been modified in order to create a Device_4 interface * which inherits from the original Device interface * * $Author: taurel $ * $Revision: 20742 $ * * @headerfile tango.h * @ingroup Server */ class Device_5Impl : public virtual POA_Tango::Device_5, public Device_4Impl { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Device_5Impl object from its name. * * The device description field is set to A Tango device. The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * */ Device_5Impl(DeviceClass *device_class,string &dev_name); /** * Constructs a newly allocated Device_5Impl object from its name and its description. * * The device * state is set to unknown and the device status is set to * Not Initialised * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * */ Device_5Impl(DeviceClass *device_class,string &dev_name,string &desc); /** * Constructs a newly allocated Device_5Impl object from all its creation * parameters. * * The device is constructed from its name, its description, an original state * and status * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device description * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_5Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status); /** * Constructs a newly allocated Device_5Impl object from all its creation * parameters with some default values. * * The device is constructed from its name, its description, an original state * and status. This constructor defined default values for the description, * state and status parameters. The default device description is A TANGO device. * The default device state is UNKNOWN and the default device status * is Not initialised. * * @param device_class Pointer to the device class object * @param dev_name The device name * @param desc The device desc * @param dev_state The device initial state * @param dev_status The device initial status * */ Device_5Impl(DeviceClass *device_class, const char *dev_name,const char *desc = "A TANGO device", Tango::DevState dev_state = Tango::UNKNOWN, const char *dev_status = StatusNotSet); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device desctructor. */ virtual ~Device_5Impl() {} //@} /**@name CORBA operation methods * Method defined to implement TANGO device CORBA operation */ //@{ /** * Read attribute(s) value. * * Invoked when the client request the read_attributes_5 CORBA operation. * It returns to the client one AttributeValue structure for each wanted * attribute. * * @param names The attribute(s) name list * @param source The data source. This parameter is new in Tango release 5. It * allows a client to choose the data source between the device itself or the * data cache for polled attribute. * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A sequence of AttributeValue_5 structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList_5 *read_attributes_5(const Tango::DevVarStringArray& names, Tango::DevSource source, const Tango::ClntIdent &cl_ident); /** * Write then read attribute(s) value. * * Invoked when the client request the write_read_attributes CORBA operation. * It sets the attribute(s) with the new value(s) passed as parameter * and then read the attribute(s) and return the read value to the caller. * * @param values The attribute(s) new value(s). One structure is initialised * for each wanted attribute with the attribute value. The attribute quality and * date are not used by this method. * Click here * to read AttributeValue structure definition. * @param r_names Names of the attribute(s) to be read * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A sequence of AttributeValue_5 structure. One structure is initialised * for each wanted attribute with the attribute value, the date and the attribute * value quality. Click here * to read AttributeValue_5 structure definition. * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeValueList_5* write_read_attributes_5(const Tango::AttributeValueList_4 &values, const Tango::DevVarStringArray &r_names, const Tango::ClntIdent &cl_ident); /** * Get attribute(s) configuration. * * Invoked when the client request the get_attribute_config_5 CORBA operation. * It returns to the client one AttributeConfig_5 structure for each wanted * attribute. All the attribute properties value are returned in this * AttributeConfig_5 structure. Since Tango release V5, the attribute event * related, the attribute warning alarm and attribute rds alarm properties * have been added to the returned structures. * * @param names The attribute(s) name list * @return A sequence of AttributeConfig_5 structure. One structure is initialised * for each wanted attribute. Click here * to read AttributeConfig_5 structure specification. * * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::AttributeConfigList_5 *get_attribute_config_5(const Tango::DevVarStringArray& names); /** * Set attribute(s) configuration. * * Invoked when the client request the set_attribute_config_5 CORBA operation. * It updates the device attribute configuration actually used by the device but * this method also updates the Tango database. One structure of the * AttributeConfig_3 type is needed for each attribute to update configuration. * Click here * to read AttributeConfig_5 structure specification. * * @param new_conf The attribute(s) new configuration structure sequence * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void set_attribute_config_5(const Tango::AttributeConfigList_5& new_conf, const Tango::ClntIdent &cl_ident); /** * Read attribute value history. * * Invoked when the client request the read_attribute_history_5 CORBA operation. * This operation allows a client to retrieve attribute value history for * polled attribute. The depth of the history is limited to the depth of * the device server internal polling buffer. * It returns to the client one DevAttrHistory structure for each record. * * @param name The attribute name * @param n The record number. * @return A DevAttrHistory_5 structure. This strucure contains all the element * allowing a client to retrieve for each history record the attribute value, * the date and in case of the attribute * returns an error when it was read, the DevErrors data. * Click here * to read DevAttrHistory structure definition. * @exception DevFailed Thrown if the attribute does not exist or is not polled. * Click here to read * DevFailed exception specification */ virtual Tango::DevAttrHistory_5 *read_attribute_history_5(const char* name,CORBA::Long n); /** * Get pipe(s) configuration. * * Invoked when the client request the get_pipe_config_5 CORBA operation. * It returns to the client one PipeConfig_5 structure for each wanted * pipe. All the pipe description is returned in this * PipeConfig_5 structure. * * @param names The pipe(s) name list * @return A sequence of PipeConfig_5 structure. One structure is initialised * for each wanted pipe. Click here * to read PipeConfig_5 structure specification. * * @exception DevFailed Thrown if the pipe does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::PipeConfigList *get_pipe_config_5(const Tango::DevVarStringArray& names); /** * Set pipe(s) configuration. * * Invoked when the client request the set_pipe_config_5 CORBA operation. * It updates the device pipe configuration actually used by the device but * this method also updates the Tango database. One structure of the * PipeConfig type is needed for each pipe to update configuration. * Click here * to read PipeConfig structure specification. * * @param new_conf The pipe(s) new configuration structure sequence * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @exception DevFailed Thrown if the command does not exist. * Click here to read * DevFailed exception specification */ virtual void set_pipe_config_5(const Tango::PipeConfigList& new_conf, const Tango::ClntIdent &cl_ident); /** * Read pipe value. * * Invoked when the client request the read_pipe_5 CORBA operation. * It returns to the client a DevPipeData structure. * * @param name The pipe name * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A DevPipeData structure. Click here * to read DevPipeData structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::DevPipeData *read_pipe_5(const char *name,const Tango::ClntIdent &cl_ident); /** * Write pipe value. * * Invoked when the client request the write_pipe_5 CORBA operation. * It allows a client to send data to a device through a pipe. * * @param pipe_value The new pipe value * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual void write_pipe_5(const Tango::DevPipeData &pipe_value,const Tango::ClntIdent& cl_ident); /** * Write then read pipe value. * * Invoked when the client request the write_read_pipe_5 CORBA operation. * It allows a client to send data to a device through a pipe then to read data from the device through * the same pipe. * * @param pipe_value The new pipe value * @param cl_ident The client identificator. This parameter is new in release 4. * It allows device locking feature implemented in Tango V7 * @return A DevPipeData structure. Click here * to read DevPipeData structure definition. * @exception DevFailed Thrown if the attribute does not exist. * Click here to read * DevFailed exception specification */ virtual Tango::DevPipeData *write_read_pipe_5(const Tango::DevPipeData &pipe_value,const Tango::ClntIdent& cl_ident); //@} /// @privatesection private: class Device_5ImplExt { public: Device_5ImplExt() {} ~Device_5ImplExt() {} }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_5; // Class extension #else Device_5ImplExt *ext_5; #endif }; } // End of Tango namespace #endif // _DEVICE_5_H tango-9.2.5a/lib/cpp/server/deviceclass.h0000644023471100065110000003533713034745002015233 00000000000000//============================================================================= // // file : Deviceclass.h // // description : Include file for the DeviceClass root class. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28932 $ // // //============================================================================= #ifndef _DEVICECLASS_H #define _DEVICECLASS_H namespace Tango { class Command; class Pipe; class DeviceClass; class AutoTangoMonitor; class NoSyncModelTangoMonitor; class EventSupplier; class Util; class DServer; //============================================================================= // // The DeviceClass class // // // description : This class will act as root class for all other // DeviceClass classes. Its job is to define all Device // class related properties and methods which exist only // once e.g. the command list. // //============================================================================= /** * Base class for all TANGO device-class class. A TANGO device-class class is * a class where is stored all data/method common to all devices of a TANGO * device class * * $Author: taurel $ * $Revision: 28932 $ * * @headerfile tango.h * @ingroup Server */ class #ifdef _TG_WINDOWS_ #ifndef _TANGO_LIB __declspec(dllexport) #endif #endif DeviceClass { friend class Tango::AutoTangoMonitor; public: /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The device destructor. */ virtual ~DeviceClass(); //@} /**@name Miscellaneous methods */ //@{ /** * Execute a command. * * It looks for the correct command object in the command object vector. * If the command is found, it invoke the always_executed_hook method. * Check if the command is allowed by invoking the is_allowed method * If the command is allowed, invokes the execute method. * * @param device The device on which the command must be executed * @param command The command name * @param in_any The command input data still packed in a CORBA Any object * @return A CORBA Any object with the output data packed in * @exception DevFailed If the command is not found, if the command is not allowed * in the actual device state and re-throws of all the exception thrown by the * always_executed_hook, is_alloed and execute methods. * Click here to read * DevFailed exception specification * */ CORBA::Any *command_handler(DeviceImpl *device, string &command,const CORBA::Any &in_any); /** * Create command objects for all command supported by this class of device. * * In the DeviceClass class, this method is pure abstract and must be defined * in sub-class. Its rule is to create the command object and to store them * in a vector of command objects * */ virtual void command_factory() = 0; /** * Create all the attributes name supported by this class of device. * * In the DeviceClass class, this method does nothing and must be re-defined * in sub-class if the sub-class supports attributes. Its rule is to * create and store the supported attributes in a vector. * */ virtual void attribute_factory(vector &) {}; /** * Create all the pipes supported by this class of device. * * In the DeviceClass class, this method does nothing and must be re-defined * in sub-class if the sub-class supports pipes. Its rule is to * create and store the supported pipes in a vector. * */ virtual void pipe_factory() {}; /** * Create device(s). * * In the DeviceClass class, this method is pure abstract and must be defined * in sub-class. Its rule is to create all the class devices and to store them * in a vector of device * * @param dev_list The device name list * @exception DevFailed This method does not throw exception but a * redefined method can. * Click here to read * DevFailed exception specification */ virtual void device_factory(const Tango::DevVarStringArray *dev_list) = 0; /** * Create device(s) name list (for no database device server). * * This method can be re-defined in DeviceClass sub-class for device server * started without database. Its rule is to initialise class device name. * The default method does nothing. * * @param list Reference to the device name list */ virtual void device_name_factory(vector &list) {(void)list;}; /** * Delete device. * * The rule of this method is to delete a device from the running * server belonging to the Tango class. It does change anything in the * database * * @param dev_name Reference to the device name */ void device_destroyer(const string &dev_name); /** * Delete device. * * The rule of this method is to delete a device from the running * device belonging to the Tango class. It does change anything in the * database * * @param dev_name Reference to the device name */ void device_destroyer(const char *dev_name); //@} /**@name Get/Set object members. * These methods allows the external world to get/set DeviceImpl instance * data members */ //@{ /** * Get the TANGO device class name. * * @return The TANGO device class name */ string &get_name() {return name;} /** * Get the TANGO device class documentation URL. * * @return The TANGO device class documentation */ string &get_doc_url() {return doc_url;} /** * Get the TANGO device type name. * * @return The TANGO device type name */ string &get_type() {return type;} /** * Get the device object vector. * * @return A reference to the device vector */ vector &get_device_list() {return device_list;} /** * Get the command object vector. * * @return A reference to the command vector */ vector &get_command_list() {return command_list;} /** * Get the pipe object vector. * * @param dev_name The device name * * @return A reference to the pipe vector containing all device pipes */ vector &get_pipe_list(const string &dev_name); /** * Get a reference to a command object. * * @return A reference to the command object */ Command &get_cmd_by_name(const string &); /** * Get a reference to a pipe object. * * @param pipe_name The pipe name * @param dev_name The device name * * @return A reference to the pipe object */ Pipe &get_pipe_by_name(const string &pipe_name,const string &dev_name); /** * Get a pointer to the associated DbClass object. * * @return Pointer to the DbClas object */ DbClass *get_db_class() {return db_class;} /** * Get a pointer to the class attributes object * * @return A pointer to the instance of the MultiClassAttribute */ MultiClassAttribute *get_class_attr() {return class_attr;} /** * Get a pointer to the class pipes object * * @return A pointer to the instance of the MultiClassPipe */ MultiClassPipe *get_class_pipe() {return class_pipe;} /** * Set the TANGO device type name. * * @param dev_type The new TANGO device type name */ void set_type(string &dev_type) {type = dev_type;} /** * Set the TANGO device type name. * * @param dev_type The new TANGO device type name */ void set_type(const char *dev_type) {type = dev_type;} //@} /**@name Signal related methods * These methods allow a signal management at device level */ //@{ #if defined _TG_WINDOWS_ /** * Register a signal. * * Register this class as class to be informed when signal signo is sent to * to the device server process * * @param signo The signal number * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to register a signal for the process. * Click here to read * DevFailed exception specification */ void register_signal(long signo); #else /** * Register a signal. * * Register this class as class to be informed when signal signo is sent to * to the device server process. This method is available only under Linux. * * @param signo The signal number * @param own_handler A boolean set to true if you want the device signal handler * to be executed in its own handler instead of being executed by the signal * thread. If this parameter is set to true, care should be taken on how the * handler is written. A default false value is provided * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to register a signal for the process. * Click here to read * DevFailed exception specification */ void register_signal(long signo,bool own_handler = false); #endif /** * Unregister a signal. * * Unregister this class as class to be informed when signal signo is sent to * to the device server process * * @param signo The signal number * @exception DevFailed Thrown if the signal number is out of range or if the * operating system failed to unregister a signal for the process. Unregister * a device for a signal number for a device not previously registered is not * an error. This simply will do nothing. * Click here to read * DevFailed exception specification */ void unregister_signal(long signo); /** * Signal handler. * * The method executed when the signal arrived in the device server process. * This method is defined as virtual and then, can be redefined following * device class needs. * * @param signo The signal number */ virtual void signal_handler(long signo); //@} protected: /**@name Constructor Only one constructot for this class which is a singleton */ //@{ /** * Construct a newly allocated DeviceClass object. * * @param s The Tango device class name * */ DeviceClass(string &s); //@} /**@name Miscellaneous protected methods */ //@{ /** * Export a device. * * Associate the servant to a CORBA object and send device network parameter * to TANGO database. The main parameter sent to database is the CORBA * object stringified device IOR. * * @param dev The device to be exported (CORBA servant) * @param corba_dev_name The name to be used in the CORBA object key. This * parameter does not need to be set in most of cases and has a default value. * It is used for special device server like the database device server. * @exception DevFailed If the command sent to the database failed. * Click here to read * DevFailed exception specification */ void export_device(DeviceImpl *dev,const char* corba_dev_name = "Unused"); /** * Set a Tango classs default command * * Define one command to be the Tango class default command * The default command is the command which will be exceuted when * an unknown command is sent to one of the Tango class device * By default, there is no default class * * @param cmd The command object */ void set_default_command(Command *cmd) {default_cmd = cmd;} //@} /**@name Class data members */ //@{ /** * The TANGO device class name */ string name; /** * The TANGO device class documentation URL */ string doc_url; /** * The TANGO device type name */ string type; /** * The command(s) list */ vector command_list; /** * The device(s) list */ vector device_list; /** * The associated DbClass object */ DbClass *db_class; /** * Pointer to the class multi attribute object */ MultiClassAttribute *class_attr; /** * Pointer to the class multi pipe object */ MultiClassPipe *class_pipe; /** * The pipe(s) list */ vector pipe_list; //@} public: /// @privatesection vector &get_nodb_name_list() {return nodb_name_list;} void set_memorized_values(bool flag, long idx = 0,bool from_init = false); void add_wiz_dev_prop(string &name,string &desc,string &def); void add_wiz_dev_prop(string &name,string &desc); void add_wiz_class_prop(string &name,string &desc,string &def); void add_wiz_class_prop(string &name,string &desc); vector &get_wiz_class_prop() {return wiz_class_prop;} vector &get_wiz_dev_prop() {return wiz_dev_prop;} string &get_cvs_tag() {return cvs_tag;} string &get_cvs_location() {return cvs_location;} string &get_svn_tag() {return svn_tag;} string &get_svn_location() {return svn_location;} void set_cvs_tag(string &str) {cvs_tag=str;} void set_cvs_location(string &str) {cvs_location=str;} void add_device(DeviceImpl *dev) {device_list.push_back(dev);} void delete_dev(long idx,Tango::Util *tg,PortableServer::POA_ptr r_poa); bool is_py_class() {return py_class;} void set_py_class(bool py) {py_class=py;} virtual void delete_class() {} void get_mcast_event(DServer *); bool is_command_allowed(const char *); bool get_device_factory_done() {return device_factory_done;} void set_device_factory_done(bool val) {device_factory_done = val;} void check_att_conf(); void release_devices_mon(); void remove_command(const string &); void create_device_pipe(DeviceClass *,DeviceImpl *); vector &get_pipe_list() {return pipe_list;} protected: /// @privatesection Command *get_default_command() {return default_cmd;} private: class DeviceClassExt { public: DeviceClassExt() {}; map > dev_pipe_list; }; void get_class_system_resource(); void throw_mem_value(DeviceImpl *,Attribute &); vector wiz_class_prop; vector wiz_dev_prop; vector allowed_cmds; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else DeviceClassExt *ext; #endif // // Ported from the extension class // vector nodb_name_list; TangoMonitor only_one; string cvs_tag; string cvs_location; Command * default_cmd; bool py_class; string svn_tag; string svn_location; bool device_factory_done; }; } // End of Tango namespace #endif // _DEVICECLASS_H tango-9.2.5a/lib/cpp/server/devintr.h0000644023471100065110000000444213034745002014412 00000000000000//=================================================================================================================== // // file : devintr.h // // description : Include file for the DevIntr class // This class is used for the device interface change event generation // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #ifndef _DEVINTR_H #define _DEVINTR_H #include namespace Tango { class DevIntr { public: DevIntr() {} void get_interface(DeviceImpl *); bool has_changed(DeviceImpl *); protected: private: struct CmdIntr { string name; CmdArgType in_type; CmdArgType out_type; bool operator<(const struct CmdIntr &rhs) const {return name < rhs.name;} bool operator==(const struct CmdIntr &) const; }; struct AttrIntr { string name; AttrWriteType writable; long data_type; AttrDataFormat data_format; long max_x; long max_y; bool mem; bool mem_init; string writable_attr_name; vector enum_labels; bool operator<(const struct AttrIntr &rhs) const {return name < rhs.name;} bool operator==(const struct AttrIntr &) const; }; vector cmds; vector atts; void build_cmd_interfaces(DeviceImpl *,vector &); void build_att_interfaces(DeviceImpl *,vector &); }; } // End of Tango namespace #endif /* _DEVINTR_H */ tango-9.2.5a/lib/cpp/server/dintrthread.h0000644023471100065110000000577513034745002015261 00000000000000//================================================================================================================== // // file : dintrthread.h // // description : Include for the DevIntrThread object. This class implements the thread used to push device // interface change event // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 24813 $ // //================================================================================================================== #ifndef _DINTRTHREAD_H #define _DINTRTHREAD_H namespace Tango { class DevIntr; //================================================================================================================= // // The DevIntrThCmd structure // // description : // This structure is used to shared data between the Device interface change thread and the main thread. // //================================================================================================================ enum DevIntrCmdCode { DEV_INTR_SLEEP = 0, DEV_INTR_EXIT }; struct _ShDevIntrTh { bool cmd_pending; // The new command flag DevIntrCmdCode cmd_code; // The command code bool th_running; // Thread running flag DevIntr interface; // Device interface }; typedef struct _ShDevIntrTh ShDevIntrTh; enum DevIntrCmdType { DEV_INTR_TIME_OUT = 0, DEV_INTR_COMMAND }; //================================================================================================================= // // The DevIntrThread class // // description : // Class to store all the necessary information for the device interface change event thread. // It's run() method is the thread code // This is a detached thread // //================================================================================================================= class TangoMonitor; class DevIntrThread: public omni_thread { public: DevIntrThread(ShDevIntrTh &,TangoMonitor &,DeviceImpl *); void run(void *); void execute_cmd(); DevIntrCmdType get_command(DevLong); void push_event(); protected: ShDevIntrTh &shared_data; TangoMonitor &p_mon; DeviceImpl *dev; ShDevIntrTh local_cmd; }; } // End of Tango namespace #endif /* _DINTRTHREAD_ */ tango-9.2.5a/lib/cpp/server/dserver.h0000644023471100065110000001664513034745001014420 00000000000000//============================================================================= // // file : DServer.h // // description : Include for the DServer class. This class implements // all the commands which are available for device // of the DServer class. There is one device of the // DServer class for each device server process // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27976 $ // //============================================================================= #ifndef _DSERVER_H #define _DSERVER_H #include namespace Tango { //============================================================================= // // The DServer class // // description : Class to implement all data members and commands for // device of the DServer class // //============================================================================= typedef Tango::DeviceClass *(*Cpp_creator_ptr)(const char *); typedef void (*ClassFactoryFuncPtr)(DServer *); class DServer: public TANGO_BASE_CLASS { public : DServer(DeviceClass *,const char *,const char *,Tango::DevState,const char *); ~DServer(); Tango::DevVarStringArray *query_class(); Tango::DevVarStringArray *query_device(); Tango::DevVarStringArray *query_sub_device(); void kill(); void restart(string &); void restart_server(); Tango::DevVarStringArray *query_class_prop(string &); Tango::DevVarStringArray *query_dev_prop(string &); Tango::DevVarStringArray *polled_device(); Tango::DevVarStringArray *dev_poll_status(string &); void add_obj_polling(const Tango::DevVarLongStringArray *,bool with_db_upd = true,int delta_ms = 0); void upd_obj_polling_period(const Tango::DevVarLongStringArray *,bool with_db_upd = true); void rem_obj_polling(const Tango::DevVarStringArray *,bool with_db_upd = true); void stop_polling(); void start_polling(); void start_polling(PollingThreadInfo *); void add_event_heartbeat(); void rem_event_heartbeat(); void lock_device(const Tango::DevVarLongStringArray *); Tango::DevLong un_lock_device(const Tango::DevVarLongStringArray *); void re_lock_devices(const Tango::DevVarStringArray *); Tango::DevVarLongStringArray *dev_lock_status(Tango::ConstDevString); Tango::DevLong event_subscription_change(const Tango::DevVarStringArray *); Tango::DevVarLongStringArray *zmq_event_subscription_change(const Tango::DevVarStringArray *); void event_confirm_subscription(const Tango::DevVarStringArray *); void delete_devices(); #ifdef TANGO_HAS_LOG4TANGO void add_logging_target (const Tango::DevVarStringArray *argin); void remove_logging_target (const Tango::DevVarStringArray *argin); Tango::DevVarStringArray* get_logging_target (const std::string& dev_name); void set_logging_level (const Tango::DevVarLongStringArray *argin); Tango::DevVarLongStringArray* get_logging_level (const Tango::DevVarStringArray *argin); void stop_logging (void); void start_logging (void); #endif string &get_process_name() {return process_name;} string &get_personal_name() {return instance_name;} string &get_instance_name() {return instance_name;} string &get_full_name() {return full_name;} string &get_fqdn() {return fqdn;} bool get_heartbeat_started() {return heartbeat_started;} void set_heartbeat_started(bool val) {heartbeat_started = val;} vector &get_class_list() {return class_list;} virtual void init_device(); unsigned long get_poll_th_pool_size() {return polling_th_pool_size;} void set_poll_th_pool_size(unsigned long val) {polling_th_pool_size = val;} bool get_opt_pool_usage() {return optimize_pool_usage;} vector get_poll_th_conf() {return polling_th_pool_conf;} void check_lock_owner(DeviceImpl *,const char *,const char *); void check_upd_authorized(DeviceImpl *,int,PollObjType,string &); TANGO_IMP_EXP static void register_class_factory(ClassFactoryFuncPtr f_ptr) {class_factory_func_ptr = f_ptr;} void _add_class(DeviceClass *dc) {this->add_class(dc);} void _create_cpp_class(const char *c1,const char *c2) {this->create_cpp_class(c1,c2);} void mcast_event_for_att(string &,string &,vector &); void mem_event_par(map > &); void apply_event_par(map > &); void mem_devices_interface(map &); void changed_devices_interface(map &); bool is_polling_bef_9_def() {return polling_bef_9_def;} bool get_polling_bef_9() {return polling_bef_9;} friend class NotifdEventSupplier; friend class ZmqEventSupplier; protected : string process_name; string instance_name; string full_name; string fqdn; vector class_list; time_t last_heartbeat; time_t last_heartbeat_zmq; bool heartbeat_started; unsigned long polling_th_pool_size; vector polling_th_pool_conf; bool optimize_pool_usage; static ClassFactoryFuncPtr class_factory_func_ptr; private: #if ((defined _TG_WINDOWS_) && (defined TANGO_HAS_DLL) && !(defined _TANGO_LIB)) __declspec(dllexport) void class_factory(); #else void class_factory(); #endif void add_class(DeviceClass *); void create_cpp_class(const char *,const char *); void get_dev_prop(Tango::Util *); void event_subscription(string &,string &,string &,string &,string &,ChannelType,string &,int &,int &,DeviceImpl *,int l=0); void get_event_misc_prop(Tango::Util *); bool is_event_name(string &); bool is_ip_address(string &); bool from_constructor; vector mcast_event_prop; DevLong mcast_hops; DevLong mcast_rate; DevLong mcast_ivl; DevLong zmq_pub_event_hwm; DevLong zmq_sub_event_hwm; bool polling_bef_9_def; bool polling_bef_9; }; class KillThread: public omni_thread { public: void *run_undetached(void *); void start() {start_undetached();} }; class ServRestartThread: public omni_thread { public: ServRestartThread(DServer *dev):omni_thread(dev) {} void run(void *); }; struct Pol { PollObjType type; long upd; string name; }; /****************************************************************************** * * Some inline methods * ******************************************************************************/ inline bool DServer::is_event_name(string &str) { if (count(str.begin(),str.end(),'/') != 3) return false; if (count(str.begin(),str.end(),'.') != 1) return false; return true; } inline bool DServer::is_ip_address(string &str) { if (count(str.begin(),str.end(),'.') != 3) return false; return true; } } // End of namespace Tango #endif tango-9.2.5a/lib/cpp/server/dserverclass.h0000644023471100065110000004005213034745001015433 00000000000000//============================================================================= // // file : DServerClass.h // // description : Include for the DServerClass class. This class is a // singleton class i.e only one object of this class // can be created. // It contains all properties and methods // which the DServer requires only once e.g. the // commands. // This file also includes class declaration for all the // commands available on device of the DServer class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _DSERVERCLASS_H #define _DSERVERCLASS_H #include namespace Tango { //============================================================================= // // The DevRestart class // // description : Class to implement the DevRestart command. This command // needs one input argument and no outout argument. // The input argument is the name of the device to be // re-started. // This class delete and re-create a device // //============================================================================= class DevRestartCmd : public Command { public: DevRestartCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevRestartCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevRestartServerCmd class // // description : Class to implement the DevKill command. This // command does not take any input argument. It simply // kills the device server. // //============================================================================= class DevRestartServerCmd : public Command { public: DevRestartServerCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out); ~DevRestartServerCmd() {}; virtual CORBA::Any *execute (DeviceImpl *, const CORBA::Any &); }; //============================================================================= // // The DevQueryClassCmd class // // description : Class to implement the DevQueryClass command. This // command does not take any input argument and return a // list of all the classes created inside the device // server process // //============================================================================= class DevQueryClassCmd : public Command { public: DevQueryClassCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevQueryClassCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevQueryDeviceCmd class // // description : Class to implement the DevQueryDevice command. This // command does not take any input argument and return a // list of all the devices created inside the device // server process // //============================================================================= class DevQueryDeviceCmd : public Command { public: DevQueryDeviceCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *desc); ~DevQueryDeviceCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevQuerySubDeviceCmd class // // description : Class to implement the DevQuerySubDevice command. This // command does not take any input argument and returns a // list of all the sub devices connections opened inside the device // server process // //============================================================================= class DevQuerySubDeviceCmd : public Command { public: DevQuerySubDeviceCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *desc); ~DevQuerySubDeviceCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevKillCmd class // // description : Class to implement the DevKill command. This // command does not take any input argument. It simply // kills the device server. // //============================================================================= class DevKillCmd : public Command { public: DevKillCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out); ~DevKillCmd() {}; virtual CORBA::Any *execute (DeviceImpl *, const CORBA::Any &); }; //============================================================================= // // The DevSetTraceLevelCmd class // // description : Class to implement the DevSetTracelevel command. // It updates device server trace level with the input // argument // //============================================================================= class DevSetTraceLevelCmd : public Command { public: DevSetTraceLevelCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevSetTraceLevelCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevGetTraceLevel class // // description : Class to implement the DevGetTracelevel command. // It simply returns the device server trace level // //============================================================================= class DevGetTraceLevelCmd : public Command { public: DevGetTraceLevelCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevGetTraceLevelCmd() {}; virtual CORBA::Any *execute (DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevSetTraceOutputCmd class // // description : Class to implement the DevSetTraceOutput command. // It set the server output to the input parameter // //============================================================================= class DevSetTraceOutputCmd : public Command { public: DevSetTraceOutputCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevSetTraceOutputCmd() {}; virtual CORBA::Any *execute (DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevGetTraceOutputCmd class // // description : Class to implement the DevGetTracelevel command. // It simply returns the device server trace level // //============================================================================= class DevGetTraceOutputCmd : public Command { public: DevGetTraceOutputCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~DevGetTraceOutputCmd() {}; virtual CORBA::Any *execute (DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The QueryWizardClassPropertyCmd class // // description : Class to implement the QueryWizardClassProperty command. // This command takes one input argument which is // the class name and return a // list of all the class properties definition registered // in the wizard for the specified class. // //============================================================================= class QueryWizardClassPropertyCmd : public Command { public: QueryWizardClassPropertyCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc); ~QueryWizardClassPropertyCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The QueryWizardDevPropertyCmd class // // description : Class to implement the QueryWizardDevProperty command. // This command takes one input argument which is // the class name and return a // list of all the device properties definition registered // in the wizard for the specified class. // //============================================================================= class QueryWizardDevPropertyCmd : public Command { public: QueryWizardDevPropertyCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc); ~QueryWizardDevPropertyCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The QueryEventChannelIOR class // // description : Class to implement the QueryEventChannelIOR command. // This command does not take any input argument and return // the event channel IOR. This command only exits foe DS // started with the -file option // //============================================================================= class QueryEventChannelIORCmd : public Command { public: QueryEventChannelIORCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~QueryEventChannelIORCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The LockDeviceCmd class // // description : Class to implement the LockDevice command. // This command takes one input argument which is // the device names and return an // integer which is the client locking thread period // //============================================================================= class LockDeviceCmd : public Command { public: LockDeviceCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc); ~LockDeviceCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The ReLockDevicesCmd class // // description : Class to implement the ReLockDevices command. // This command takes one input argument which is // the vector with device names to be re-locked // //============================================================================= class ReLockDevicesCmd : public Command { public: ReLockDevicesCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc); ~ReLockDevicesCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The UnLockDeviceCmd class // // description : Class to implement the UnLockDevice command. // This command takes one input argument which is // the device name to be unlocked // //============================================================================= class UnLockDeviceCmd : public Command { public: UnLockDeviceCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc); ~UnLockDeviceCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevLockStatusCmd class // // description : Class to implement the DevLockStatus command. // This command takes one input argument which is // the device name for which you want to retrieve locking status // //============================================================================= class DevLockStatusCmd : public Command { public: DevLockStatusCmd(const char *cmd_name, Tango::CmdArgType in,Tango::CmdArgType out, const char *in_desc,const char *out_desc); ~DevLockStatusCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The EventSubscriptionChangeCmd class // // description : Class to implement the EventSubscriptionChange command. // This command takes one arguments which are // the event for which the user subscribe to // //============================================================================= class EventSubscriptionChangeCmd : public Tango::Command { public: EventSubscriptionChangeCmd(const char *,Tango::CmdArgType, Tango::CmdArgType,const char *,const char *); EventSubscriptionChangeCmd(const char *,Tango::CmdArgType, Tango::CmdArgType); ~EventSubscriptionChangeCmd() {}; virtual bool is_allowed (Tango::DeviceImpl *, const CORBA::Any &); virtual CORBA::Any *execute (Tango::DeviceImpl *, const CORBA::Any &); }; //============================================================================= // // The ZmqEventSubscriptionChangeCmd class // // description : Class to implement the ZmqEventSubscriptionChange command. // This command takes one arguments which are // the event for which the user subscribe to // //============================================================================= class ZmqEventSubscriptionChangeCmd : public Tango::Command { public: ZmqEventSubscriptionChangeCmd(const char *,Tango::CmdArgType, Tango::CmdArgType,const char *,const char *); ZmqEventSubscriptionChangeCmd(const char *,Tango::CmdArgType, Tango::CmdArgType); ~ZmqEventSubscriptionChangeCmd() {}; virtual bool is_allowed (Tango::DeviceImpl *, const CORBA::Any &); virtual CORBA::Any *execute (Tango::DeviceImpl *, const CORBA::Any &); }; //============================================================================= // // The EventConfirmSubscriptionCmd class // // description : Class to implement the EventConfirmSubscription command. // This command takes a list of event for which the client confirm // the subscription. This command returns nothing // //============================================================================= class EventConfirmSubscriptionCmd : public Tango::Command { public: EventConfirmSubscriptionCmd(const char *,Tango::CmdArgType, Tango::CmdArgType,const char *); EventConfirmSubscriptionCmd(const char *,Tango::CmdArgType, Tango::CmdArgType); ~EventConfirmSubscriptionCmd() {}; virtual bool is_allowed (Tango::DeviceImpl *, const CORBA::Any &); virtual CORBA::Any *execute (Tango::DeviceImpl *, const CORBA::Any &); }; //============================================================================= // // The DServerClass class // // description : This class is a singleton ( The constructor is // protected and the _instance data member is static) // It contains all properties and methods // which the DServer objects requires only once e.g. the // commands. // //============================================================================= class DServerClass : public DeviceClass { public: TANGO_IMP_EXP static DServerClass *instance(); TANGO_IMP_EXP static DServerClass *init(); ~DServerClass() {}; void command_factory(); void device_factory(const Tango::DevVarStringArray *devlist); protected: DServerClass(string &); TANGO_IMP static DServerClass *_instance; }; } // End of Tango namespace #endif // _DSERVERCLASS_H tango-9.2.5a/lib/cpp/server/dserversignal.h0000644023471100065110000001051413034745001015603 00000000000000//============================================================================= // // file : DServerSignal.h // // description : Include for the DServer class. This class implements // all the commands which are available for device // of the DServer class. There is one device of the // DServer class for each device server process // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _DSERVERSIGNAL_H #define _DSERVERSIGNAL_H #include #include namespace Tango { //============================================================================= // // The DServerSignal class // // description : Class to implement all data members and commands for // signal management in a TANGO device server. // //============================================================================= #if (defined (_TG_WINDOWS_) || (defined __darwin__) || (defined __freebsd__)) #define _NSIG NSIG #endif typedef struct { vector registered_classes; vector registered_devices; bool own_handler; } DevSigAction; class DServerSignal:public TangoMonitor { public : TANGO_IMP_EXP static DServerSignal *instance(); ~DServerSignal() {}; #ifndef _TG_WINDOWS_ void register_class_signal(long, bool, DeviceClass *); void register_dev_signal(long, bool, DeviceImpl *); void register_handler(long,bool); pid_t get_sig_thread_pid(); #else void register_class_signal(long, DeviceClass *); void register_dev_signal(long, DeviceImpl *); void register_handler(long); #endif void unregister_class_signal(long, DeviceClass *); void unregister_class_signal(DeviceClass *); void unregister_dev_signal(long, DeviceImpl *); void unregister_dev_signal(DeviceImpl *); void unregister_handler(long); static void main_sig_handler(int); class ThSig: public omni_thread { DServerSignal *ds; public: ThSig(DServerSignal *d):ds(d),my_pid(0),th_data_created(false) {} virtual ~ThSig() {} TangoSys_Pid my_pid; bool th_data_created; #ifndef _TG_WINDOWS_ pthread_t my_thread; #endif void *run_undetached(void *); void start() {start_undetached();} }; friend class ThSig; ThSig *sig_th; protected : DServerSignal(); static DevSigAction reg_sig[_NSIG]; bool sig_to_install; bool sig_to_remove; int inst_sig; int rem_sig; #ifdef _TG_WINDOWS_ static HANDLE win_ev; static int win_signo; #endif private: static DServerSignal *_instance; vector::iterator find_device(long, DeviceImpl *); vector::iterator find_delayed_device(long, DeviceImpl *); vector::iterator find_class(long, DeviceClass *); vector::iterator find_delayed_class(long, DeviceClass *); #ifdef _TG_WINDOWS_ static inline bool auto_signal(long s) { if ((s==SIGINT) || (s==SIGTERM) || (s==SIGABRT) || (s==SIGBREAK)) return true; else return false; } #else static inline bool auto_signal(long s) { if ((s==SIGQUIT) || (s==SIGINT) || (s==SIGHUP) || (s==SIGTERM)) return true; else return false; } #endif #if (defined __GLIBC__ || defined __darwin__ || defined __freebsd__) static inline bool auth_signal(TANGO_UNUSED(long s)) {return true;} #endif #ifdef _TG_WINDOWS_ static inline bool auth_signal(long s) {return true;} #endif static string sig_name[_NSIG]; }; } // End of namespace Tango #endif tango-9.2.5a/lib/cpp/server/encoded_attribute.h0000644023471100065110000001500413034745002016417 00000000000000///============================================================================= // // file : encoded_attribute.h // // description : Include file for the management of Tango::DevEncoded format // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // //============================================================================= #include #ifndef _ENCODED_ATT_H #define _ENCODED_ATT_H #include namespace Tango { /** * This class provides method to deal with Tango::DevEncoded attribute format. * * @headerfile tango.h * @ingroup Server */ class EncodedAttribute { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Create a new EncodedAttribute object. * */ EncodedAttribute(); /** * Create a new EncodedAttribute object with a user defined buffer pool. * * This constructor allows the user to define the size of the buffer pool used to * store the encoded images. This buffer pool is managed as a circular pool. * A different buffer is used each time an image is encoded. The last used buffer is then * passed to the attribute with the attribute::set_value() method * * @param buf_pool_size Buffer pool size * @param serialization Set to true if the instance manage the data buffer serialization * */ EncodedAttribute(int buf_pool_size,bool serialization = false); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The attribute desctructor. */ ~EncodedAttribute(); //@} /**@name Image Encoding Methods */ //@{ /** * Encode a 8 bit grayscale image as JPEG format * * @param gray8 Array of 8bit gray sample * @param width The image width * @param height The image height * @param quality Quality of JPEG (0=poor quality 100=max quality) * */ void encode_jpeg_gray8(unsigned char *gray8,int width,int height,double quality); /** * Encode a 32 bit rgb color image as JPEG format * * @param rgb32 Array of 32bit RGB sample (RGB0RGB0...) * @param width The image width * @param height The image height * @param quality Quality of JPEG (0=poor quality 100=max quality) * */ void encode_jpeg_rgb32(unsigned char *rgb32,int width,int height,double quality); /** * Encode a 24 bit rgb color image as JPEG format * * @param rgb24 Array of 32bit RGB sample (RGBRGB...) * @param width The image width * @param height The image height * @param quality Quality of JPEG (0=poor quality 100=max quality) * */ void encode_jpeg_rgb24(unsigned char *rgb24,int width,int height,double quality); /** * Encode a 8 bit grayscale image (no compression) * * @param gray8 Array of 8bit gray sample * @param width The image width * @param height The image height * */ void encode_gray8(unsigned char *gray8,int width,int height); /** * Encode a 16 bit grayscale image (no compression) * * @param gray16 Array of 16bit gray sample * @param width The image width * @param height The image height * */ void encode_gray16(unsigned short *gray16,int width,int height); /** * Encode a 24 bit color image (no compression) * * @param rgb24 Array of 24bit RGB sample * @param width The image width * @param height The image height * */ void encode_rgb24(unsigned char *rgb24,int width,int height); //@} /**@name Image Decoding Methods */ //@{ /** * Decode a color image (JPEG_RGB or RGB24) and returns a 32 bits RGB image. * Throws DevFailed in case of failure. * * @param attr DeviceAttribute that contains the image * @param width Width of the image * @param height Height of the image * @param rgb32 Image (memory allocated by the function) */ void decode_rgb32(DeviceAttribute *attr,int *width,int *height,unsigned char **rgb32); /** * Decode a 8 bits grayscale image (JPEG_GRAY8 or GRAY8) and returns a 8 bits gray scale image. * Throws DevFailed in case of failure. * * @param attr DeviceAttribute that contains the image * @param width Width of the image * @param height Height of the image * @param gray8 Image (memory allocated by the function) */ void decode_gray8(DeviceAttribute *attr,int *width,int *height,unsigned char **gray8); /** * Decode a 16 bits grayscale image (GRAY16) and returns a 16 bits gray scale image. * Throws DevFailed in case of failure. * * @param attr DeviceAttribute that contains the image * @param width Width of the image * @param height Height of the image * @param gray16 Image (memory allocated by the function) */ void decode_gray16(DeviceAttribute *attr,int *width,int *height,unsigned short **gray16); //@} /// @privatesection DevUChar *get_data() {if (index==0) return (DevUChar *)buffer_array[buf_elt_nb-1]; else return (DevUChar *)buffer_array[index-1];} long get_size() {if (index==0) return (long)buffSize_array[buf_elt_nb-1]; else return (long)buffSize_array[index-1];} DevString *get_format() {return &format;} bool get_exclusion() {return manage_exclusion;} omni_mutex *get_mutex() {if (index==0) return &(mutex_array[buf_elt_nb-1]); else return &(mutex_array[index-1]);} private: class EncodedAttributeExt { }; unsigned char **buffer_array; int *buffSize_array; omni_mutex *mutex_array; char *format; int index; int buf_elt_nb; bool manage_exclusion; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else EncodedAttributeExt *ext; #endif }; #define INC_INDEX() \ index++; \ if (index == buf_elt_nb) \ index = 0; } // End of Tango namespace #endif // _ENCODED_ATT_H tango-9.2.5a/lib/cpp/server/encoded_format.h0000644023471100065110000000307713034745001015712 00000000000000///============================================================================= // // file : encoded_format.h // // description : Include file for the defined Tango::DevEncoded format // string // // project : TANGO // // author(s) : E. Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // // //============================================================================= #ifndef _ENCODED_FORMAT_H #define _ENCODED_FORMAT_H namespace Tango { // // Jpeg encoding // #define JPEG_GRAY_8 "JPEG_GRAY8" #define JPEG_RGB "JPEG_RGB" // // Gray encoding // #define GRAY_8 "GRAY8" #define GRAY_16 "GRAY16" // // RGB // #define RGB_24 "RGB24" } // End of Tango namespace #endif // _ENCODED_FORMAT_H tango-9.2.5a/lib/cpp/server/eventsupplier.h0000644023471100065110000003422313034745002015644 00000000000000//////////////////////////////////////////////////////////////////////////////// /// /// file eventsupplier.h /// /// C++ include file for implementing the TANGO event server and /// client singleton classes - EventSupplier and EventConsumer. /// These classes are used to send events from the server /// to the notification service and to receive events from /// the notification service. /// /// author(s) : A.Gotz (goetz@esrf.fr) /// /// original : 7 April 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . /// /// $Revision: 29692 $ /// /// copyright : European Synchrotron Radiation Facility /// BP 220, Grenoble 38043 /// FRANCE /// //////////////////////////////////////////////////////////////////////////////// #ifndef _EVENT_SUPPLIER_API_H #define _EVENT_SUPPLIER_API_H #include #if defined (_TG_WINDOWS_) && defined (_USRDLL) && !defined(_TANGO_LIB) #define USE_stub_in_nt_dll #endif #include #include #include #include #if defined (_TG_WINDOWS_) && defined (_USRDLL) && !defined(_TANGO_LIB) #undef USE_stub_in_nt_dll #endif #include #include #ifndef _TG_WINDOWS_ #include #endif namespace Tango { typedef struct _NotifService { CosNotifyChannelAdmin::SupplierAdmin_var SupAdm; CosNotifyChannelAdmin::ProxyID pID; CosNotifyChannelAdmin::ProxyConsumer_var ProCon; CosNotifyChannelAdmin::StructuredProxyPushConsumer_var StrProPush; CosNotifyChannelAdmin::EventChannelFactory_var EveChaFac; CosNotifyChannelAdmin::EventChannel_var EveCha; string ec_ior; } NotifService; //--------------------------------------------------------------------- // // EventSupplier base class // //--------------------------------------------------------------------- class EventSupplier { public : EventSupplier(Util *); virtual ~EventSupplier() {} void push_att_data_ready_event(DeviceImpl *,const string &,long,DevLong); void push_dev_intr_change_event(DeviceImpl *,bool,DevCmdInfoList_2 *,AttributeConfigList_5 *); bool any_dev_intr_client(DeviceImpl *); struct SuppliedEventData { const AttributeValue *attr_val; const AttributeValue_3 *attr_val_3; const AttributeValue_4 *attr_val_4; const AttributeValue_5 *attr_val_5; const AttributeConfig_2 *attr_conf_2; const AttributeConfig_3 *attr_conf_3; const AttributeConfig_5 *attr_conf_5; const AttDataReady *attr_dat_ready; const DevIntrChange *dev_intr_change; DevPipeData *pipe_val; zmq::message_t *zmq_mess; }; SendEventType detect_and_push_events(DeviceImpl *,struct SuppliedEventData &,DevFailed *,string &,struct timeval *); //------------------ Change event --------------------------- bool detect_change(Attribute &,struct SuppliedEventData &,bool,double &,double &,DevFailed *,bool &,DeviceImpl *); //------------------ Detect, push change event -------------- bool detect_and_push_change_event(DeviceImpl *,struct SuppliedEventData &,Attribute &,string &,DevFailed *,bool user_push = false); //------------------ Detect, push archive event -------------- bool detect_and_push_archive_event(DeviceImpl *,struct SuppliedEventData &,Attribute &,string &,DevFailed *,struct timeval *,bool user_push = false); //------------------ Detect, push periodic event ------------- bool detect_and_push_periodic_event(DeviceImpl *,struct SuppliedEventData &,Attribute &,string &,DevFailed *,struct timeval *); //------------------ Push event ------------------------------- virtual void push_event(DeviceImpl *,string,vector &,vector &,vector &,vector &,struct SuppliedEventData &,string &,DevFailed *,bool) = 0; virtual void push_event_loop(DeviceImpl *,EventType,vector &,vector &,vector &,vector &,struct SuppliedEventData &,Attribute &,DevFailed *) = 0; virtual void push_heartbeat_event() = 0; //------------------- Attribute conf change event --------------------- void push_att_conf_events(DeviceImpl *device_impl,SuppliedEventData &,DevFailed *,string &); omni_mutex &get_push_mutex() {return push_mutex;} omni_condition &get_push_cond() {return push_cond;} static omni_mutex &get_event_mutex() {return event_mutex;} string &get_fqdn_prefix() {return fqdn_prefix;} void convert_att_event_to_5(struct SuppliedEventData &,struct SuppliedEventData &,bool &,Attribute &); void convert_att_event_to_4(struct SuppliedEventData &,struct SuppliedEventData &,bool &,Attribute &); void convert_att_event_to_3(struct SuppliedEventData &,struct SuppliedEventData &,bool &,Attribute &); bool get_one_subscription_cmd() {return one_subscription_cmd;} void set_one_subscription_cmd(bool val) {one_subscription_cmd = val;} protected : inline int timeval_diff(TimeVal before, TimeVal after) { return ((after.tv_sec-before.tv_sec)*1000000 + after.tv_usec - before.tv_usec); } static string fqdn_prefix; // Added a mutex to synchronize the access to // detect_and_push_change_event and // detect_and_push_archive_event which are used // from different threads static omni_mutex event_mutex; // Added a semaphore to synchronize the access to // push_event which is used // from different threads. Do not use a simple mutex because in some cases // it is taken by Tango threads and released by ZMQ threads static omni_mutex push_mutex; static omni_condition push_cond; // Added a mutex to synchronize the access to // detect_event which is used // from different threads static omni_mutex detect_mutex; private: bool one_subscription_cmd; }; //--------------------------------------------------------------------- // // NotifdEventSupplier class // //--------------------------------------------------------------------- class NotifdEventSupplier : public EventSupplier, public POA_CosNotifyComm::StructuredPushSupplier { public : TANGO_IMP_EXP static NotifdEventSupplier *create(CORBA::ORB_var,string,Util *); void connect(); void disconnect_structured_push_supplier(); void disconnect_from_notifd(); void subscription_change(const CosNotification::EventTypeSeq& added,const CosNotification::EventTypeSeq& deled); void push_heartbeat_event(); string &get_event_channel_ior() {return event_channel_ior;} void file_db_svr(); //------------------ Push event ------------------------------- virtual void push_event(DeviceImpl *,string,vector &,vector &,vector &,vector &,struct SuppliedEventData &,string &,DevFailed *,bool); virtual void push_event_loop(DeviceImpl *,EventType,vector &,vector &,vector &,vector &,struct SuppliedEventData &,Attribute &,DevFailed *) {} protected : NotifdEventSupplier(CORBA::ORB_var, CosNotifyChannelAdmin::SupplierAdmin_var, CosNotifyChannelAdmin::ProxyID, CosNotifyChannelAdmin::ProxyConsumer_var, CosNotifyChannelAdmin::StructuredProxyPushConsumer_var, CosNotifyChannelAdmin::EventChannelFactory_var, CosNotifyChannelAdmin::EventChannel_var, string &, Util *); private : static NotifdEventSupplier *_instance; CosNotifyChannelAdmin::EventChannel_var eventChannel; CosNotifyChannelAdmin::SupplierAdmin_var supplierAdmin; CosNotifyChannelAdmin::ProxyID proxyId; CosNotifyChannelAdmin::ProxyConsumer_var proxyConsumer; CosNotifyChannelAdmin::StructuredProxyPushConsumer_var structuredProxyPushConsumer; CosNotifyChannelAdmin::EventChannelFactory_var eventChannelFactory; CORBA::ORB_var orb_; string event_channel_ior; void reconnect_notifd(); TANGO_IMP_EXP static void connect_to_notifd(NotifService &,CORBA::ORB_var &,string &,Util *); }; //--------------------------------------------------------------------- // // ZmqEventSupplier class // //--------------------------------------------------------------------- #define LARGE_DATA_THRESHOLD 2048 #define LARGE_DATA_THRESHOLD_ENCODED LARGE_DATA_THRESHOLD * 4 #ifndef HAS_LAMBDA_FUNC template struct WantedClient : public binary_function { R operator() (A1 conn_client, A2 client) const { return conn_client.clnt == client; } }; template struct OldClient : public binary_function { R operator() (A1 conn_client, A2 ti) const { if (ti > (conn_client.date + 500)) { return true; } else return false; } }; #endif class ZmqEventSupplier : public EventSupplier { public : TANGO_IMP_EXP static ZmqEventSupplier *create(Util *); virtual ~ZmqEventSupplier(); //------------------ Push event ------------------------------- void push_heartbeat_event(); virtual void push_event(DeviceImpl *,string,vector &,vector &,vector &,vector &,struct SuppliedEventData &,string &,DevFailed *,bool); virtual void push_event_loop(DeviceImpl *,EventType,vector &,vector &,vector &,vector &,struct SuppliedEventData &,Attribute &,DevFailed *); string &get_heartbeat_endpoint() {return heartbeat_endpoint;} string &get_event_endpoint() {return event_endpoint;} vector &get_alternate_heartbeat_endpoint() {return alternate_h_endpoint;} vector &get_alternate_event_endpoint() {return alternate_e_endpoint;} void create_event_socket(); void create_mcast_event_socket(string &,string &,int,bool); bool is_event_mcast(string &); string &get_mcast_event_endpoint(string &); void init_event_cptr(string &event_name); size_t get_mcast_event_nb() {return event_mcast.size();} bool update_connected_client(client_addr *); void set_double_send() {double_send++;double_send_heartbeat=true;} int get_zmq_release() {return zmq_release;} int get_calling_th() {return calling_th;} void set_require_wait(bool bo) {require_wait=bo;} protected : ZmqEventSupplier(Util *); private : static ZmqEventSupplier *_instance; struct McastSocketPub { string endpoint; zmq::socket_t *pub_socket; bool local_client; bool double_send; }; struct ConnectedClient { client_addr clnt; time_t date; }; zmq::context_t zmq_context; // ZMQ context zmq::socket_t *heartbeat_pub_sock; // heartbeat publisher socket zmq::socket_t *event_pub_sock; // events publisher socket map event_mcast; // multicast socket(s) map // The key is the full event name // ie: tango://kidiboo.esrf.fr:1000/dev/test/10/att.change string heartbeat_endpoint; // heartbeat publisher endpoint string host_ip; // Host IP address vector alt_ip; // Host alternate IP addresses string heartbeat_event_name; // The event name used for the heartbeat ZmqCallInfo heartbeat_call; // The heartbeat call info cdrMemoryStream heartbeat_call_cdr; // TangoCdrMemoryStream data_call_cdr; string event_name; vector alternate_h_endpoint; // Alternate heartbeat endpoint (host with several NIC) zmq::message_t endian_mess; // Zmq messages zmq::message_t endian_mess_2; // zmq::message_t endian_mess_heartbeat; // zmq::message_t endian_mess_heartbeat_2;// zmq::message_t heartbeat_call_mess; // zmq::message_t heartbeat_call_mess_2; // unsigned char host_endian; // the host endianess bool heartbeat_name_init; bool ip_specified; // The user has specified an IP address bool name_specified; // The user has specified a name as IP address string user_ip; // The specified IP address string event_endpoint; // event publisher endpoint vector alternate_e_endpoint; // Alternate event endpoint (host with several NIC) map event_cptr; // event counter map list con_client; // Connected clients int double_send; // Double send ctr bool double_send_heartbeat; int zmq_release; // ZMQ lib release int calling_th; bool require_wait; void tango_bind(zmq::socket_t *,string &); unsigned char test_endian(); void create_mcast_socket(string &,int,McastSocketPub &); size_t get_blob_data_nb(DevVarPipeDataEltArray &); size_t get_data_elt_data_nb(DevPipeDataElt &); }; // // Yet another evil macro! But sometimes quite usefull // #define GET_SEQ(A,B,C,D,E) \ do \ { \ A = true; \ B = &E->value.C(); \ if (archive == true) \ D = &attr.prev_archive_event.value_4.C(); \ else \ D = &attr.prev_change_event.value_4.C(); \ } \ while (false) } // End of namespace #endif // _EVENT_SUPPLIER_API_H tango-9.2.5a/lib/cpp/server/except.h0000644023471100065110000020433313034745001014227 00000000000000//=================================================================================================================== // // file : except.h // // description : Include for exception related utilities // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30238 $ // //================================================================================================================== #ifndef _EXCEPT_H #define _EXCEPT_H #include #include using namespace std; namespace Tango { class DeviceImpl; //================================================================================================================== // // Class : // Except // // description : // This class is a container for all exceptions related methods to be used in aa Tango device server/client. // Most of these methods are static. // //================================================================================================================== #define NOSPACEINDOC_EXCEPT /** * Container class for all exception related methods. Most of these methods are * static methods * * $Author: bourtemb $ * $Revision: 30238 $ * * @headerfile tango.h * @ingroup Server * @ingroup Client */ class Except { public: /**@name Exception related method */ //@{ /** * Print a TANGO exception. * * Print all the details of a TANGO exception. * * @param ex The exception object reference */ static void print_exception(const CORBA::Exception &ex); //@} /**@name Error stack related method */ //@{ /** * Print a TANGO error stack. * * Print all the details of a TANGO error stack. * * @param ex The error stack reference */ static void print_error_stack(const Tango::DevErrorList &ex); //@} /**@name Throw exception inline methods (static) */ //@{ /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].desc = CORBA::string_dup(desc); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the origin parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, const char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].desc = CORBA::string_dup(desc); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin); delete[] origin; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].desc = CORBA::string_dup(desc); delete[] desc; errors[0].origin = CORBA::string_dup(origin); errors[0].reason = CORBA::string_dup(reason); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc); delete[] desc; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin); errors[0].desc = CORBA::string_dup(desc); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason and origin parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, const char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin); errors[0].desc = CORBA::string_dup(desc); delete[] desc; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the origin, reason and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc); delete[] desc; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, const string &desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin); errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, const char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin); errors[0].desc = CORBA::string_dup(desc); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, const string &desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin); errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const char *reason, const char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the origin parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, const string &desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc); delete[] desc; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(const string &reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason.c_str()); errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc); delete desc; throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason and origin parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, const string &desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin); delete[] origin; errors[0].desc = CORBA::string_dup(desc.c_str()); throw Tango::DevFailed(errors); } /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A default value "Tango::ERR" is defined for the DevError * severity field. * The memory used by the reason and desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void throw_exception(char *reason, char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = sever; errors[0].reason = CORBA::string_dup(reason); delete[] reason; errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].desc = CORBA::string_dup(desc); delete[] desc; throw Tango::DevFailed(errors); } //@} /**@name Re-throw exception inline methods (static) */ //@{ /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].desc = CORBA::string_dup(desc); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the origin parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, const char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].desc = CORBA::string_dup(desc); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].reason = CORBA::string_dup(reason); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].desc = CORBA::string_dup(desc); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason and origin parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, const char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the origin, reason and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, const string &desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, const char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, const char *desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].desc = CORBA::string_dup(desc); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, const string &desc, const char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin); ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const char *reason, const char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the origin parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, const string &desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, const string &reason, char *desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason.c_str()); ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc); delete desc; throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, const string &desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason and origin parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, const string &desc, char *origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin); delete[] origin; ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str()); throw ex; } /** * Re-throw a TANGO DevFailed exception with one more error. * * The exception is re-thrown with one more DevError * object. A default value "Tango::ERR" is defined for the new DevError * severity field. * The memory used by the reason and desc parameter will be freed by this method * Click here to read * DevFailed exception specification * * @param ex The DevFailed exception * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static inline void re_throw_exception(Tango::DevFailed &ex, char *reason, char *desc, const string &origin, Tango::ErrSeverity sever = Tango::ERR) { long nb_err = ex.errors.length(); ex.errors.length(nb_err + 1); ex.errors[nb_err].severity = sever; ex.errors[nb_err].reason = CORBA::string_dup(reason); delete[] reason; ex.errors[nb_err].origin = CORBA::string_dup(origin.c_str()); ex.errors[nb_err].desc = CORBA::string_dup(desc); delete[] desc; throw ex; } //@} /**@name Other throw exception methods */ //@{ /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex A CORBA System Exception. The reason and desc fields of the * DevError object will be set according to the data in this exception. * The desc field is always set to API_CorbaSysException and the reason flag is * different depending on the exact type of the CORBA system exception. * @param origin The exception DevError object origin field * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static void throw_exception(const CORBA::SystemException &ex,const char *origin); /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex A CORBA System Exception. The reason and desc fields of the * DevError object will be set according to the data in this exception. * The desc field is always set to API_CorbaSysException and the reason flag is * different depending on the exact type of the CORBA system exception. * @param origin The exception DevError object origin field. The memory * allocated for this parameter will be freed by this method. * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static void throw_exception(const CORBA::SystemException &ex,char *origin); /** * Generate and throw a TANGO DevFailed exception. * * The exception is created with a single DevError * object. A value "Tango::ERR" is defined for the DevError * severity field. * Click here to read * DevFailed exception specification * * @param ex A CORBA System Exception. The reason and desc fields of the * DevError object will be set according to the data in this exception. * The desc field is always set to API_CorbaSysException and the reason flag is * different depending on the exact type of the CORBA system exception. * @param origin The exception DevError object origin field. The memory * allocated for this parameter will be freed by this method. * @exception DevFailed The thrown exception. * Click here to read * DevFailed exception specification */ static void throw_exception(const CORBA::SystemException &ex,const string &origin); /** * Throw a TANGO MultiDevFailed exception. * * Throw a MultiDevFailed exception with one more DevError * object for the attribute with name given as first parameter. * A default value "Tango::ERR" is defined for the new DevError * severity field. * Note that throwing MultiDevFailed exception is allowed only in attribute writing methods. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param att_name The attribute name * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception MultiDevFailed The thrown exception. * Click here to read * MultiDevFailed exception specification */ static inline void throw_named_exception(const char *att_name,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever = Tango::ERR) { Tango::NamedDevErrorList errors(1); errors.length(1); errors[0].name = CORBA::string_dup(att_name); errors[0].index_in_call = 999; errors[0].err_list.length(1); errors[0].err_list[0].desc = CORBA::string_dup(desc); errors[0].err_list[0].severity = sever; errors[0].err_list[0].reason = CORBA::string_dup(reason); errors[0].err_list[0].origin = CORBA::string_dup(origin); throw Tango::MultiDevFailed(errors); } /** * Throw a TANGO MultiDevFailed exception. * * Throw a MultiDevFailed exception with one more DevError * object for the attribute list with names given as first parameter. * A default value "Tango::ERR" is defined for the new DevError * severity field. * Note that throwing MultiDevFailed exception is allowed only in attribute writing methods. * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param atts The attributes name vector * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception MultiDevFailed The thrown exception. * Click here to read * MultiDevFailed exception specification */ static inline void throw_named_exception(vector &atts,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever = Tango::ERR) { unsigned int a_size = (unsigned int)atts.size(); Tango::NamedDevErrorList errors(a_size); errors.length(a_size); for (unsigned int loop = 0;loop < a_size;loop++) { errors[loop].name = CORBA::string_dup(atts[loop].c_str()); errors[loop].index_in_call = 999; errors[loop].err_list.length(1); errors[loop].err_list[0].desc = CORBA::string_dup(desc); errors[loop].err_list[0].severity = sever; errors[loop].err_list[0].reason = CORBA::string_dup(reason); errors[loop].err_list[0].origin = CORBA::string_dup(origin); } throw Tango::MultiDevFailed(errors); } /** * Throw a TANGO MultiDevFailed exception. * * Throw a MultiDevFailed exception with one more DevError * object for one attribute with index given as second parameter. * The attributes index is the index received by the write_attr_hardware() method. * A default value "Tango::ERR" is defined for the new DevError * severity field. * Note that throwing MultiDevFailed exception is allowed only in attribute writing methods. * * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param d The device pointer * @param att_idx The attributes index * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception MultiDevFailed The thrown exception. * Click here to read * MultiDevFailed exception specification */ static void throw_named_exception(Tango::DeviceImpl *d,long att_idx,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever = Tango::ERR); /** * Throw a TANGO MultiDevFailed exception. * * Throw a MultiDevFailed exception with one more DevError * object for the attribute list with indexes given as second parameter. * The attributes indexes are the index received by the write_attr_hardware() method. * A default value "Tango::ERR" is defined for the new DevError * severity field. * Note that throwing MultiDevFailed exception is allowed only in attribute writing methods. * * The memory used by the origin and desc parameters will be freed by this method * Click here to read * DevFailed exception specification * * @param d The device pointer * @param atts The attributes indexes vector * @param reason The exception DevError object reason field * @param desc The exception DevError object desc field * @param origin The exception DevError object origin field * @param sever The exception DevError object severity field * @exception MultiDevFailed The thrown exception. * Click here to read * MultiDevFailed exception specification */ static void throw_named_exception(Tango::DeviceImpl *d,vector &atts,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever = Tango::ERR); /** * Compare two Tango DevFailed exceptions for equality * * The two DevFailed exceptions are verified by comparing the * reason, origin, description and severity of all exceptions in the error stack. * The strings reason, origin and description are compared literally. * Click here to read * DevFailed exception specification * * @param ex1 The first DevFailed exception * @param ex2 The second DevFailed exception * @return A boolean set to true if the two exceptions are equal */ static bool compare_exception(Tango::DevFailed &ex1, Tango::DevFailed &ex2); //@} /// @privatesection static char *print_CORBA_SystemException(const CORBA::SystemException *); static char *print_CORBA_SystemException_r(const CORBA::SystemException *, char * err_msg); // reentrant version static omni_mutex the_mutex; protected: /// @privatesection static char mess[256]; }; } // End of Tango namespace #endif /* EXCEPT */ tango-9.2.5a/lib/cpp/server/fwdattrdesc.h0000644023471100065110000001147013034745001015247 00000000000000//=================================================================================================================== // // file : fwdattrdesc.h // // description : Include file for the FwdAttr classes hierarchy. Three classes are declared in this file : // The FwdAttr class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28373 $ // //=================================================================================================================== #ifndef _FWDATTRDESC_H #define _FWDATTRDESC_H #include namespace Tango { /** * User class to set forwarded attribute default properties. * * This class is used to set forwarded attribute default properties. Three levels of * attributes properties setting are implemented within Tango. The highest * property setting level is the database. Then the user default (set using * this UserDefaultFwdAttrProp class) and finally a Tango library default * value * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class UserDefaultFwdAttrProp { public: /**@name Constructor * Only one constructor is defined for this class */ //@{ /** * Constructs a newly allocated UserDefaultAttrProp object. */ UserDefaultFwdAttrProp():ext(Tango_nullptr) {} //@} /**@name Set default property methods */ //@{ /** * Set default label property * * @param def_label The user default label property */ void set_label(const string &def_label) { label = def_label; } //@} /// @privatesection ~UserDefaultFwdAttrProp() {} string label; private: class UserDefaultFwdAttrPropExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else UserDefaultFwdAttrPropExt *ext; #endif }; class MultiAttribute; /** * User class to create a forwarded attribute object. * * Information from this class and information fetched out from the Tango * database allows the Tango core software to create the FwdAttribute object * for the forwarded attribute created by the user. * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class FwdAttr: public ImageAttr { public: /**@name Constructors * Only one constructor is defined for this class */ //@{ /** * Constructs a newly allocated FwdAttr object. * * @param name The attribute name * @param root_attribute The root attribute name (FQAN) * */ FwdAttr(const string &name,const string &root_attribute=RootAttNotDef); //@} /**@name Miscellaneous methods*/ //@{ /** * Set default attribute properties * * @param prop The user default property class */ void set_default_properties(UserDefaultFwdAttrProp &prop); //@} /// @privatesection FwdAttr(const FwdAttr &); virtual bool is_fwd() {return true;} string &get_fwd_root_att() {return fwd_root_att;} string &get_fwd_dev_name() {return fwd_dev_name;} string &get_full_root_att() {return full_root_att;} bool is_correctly_configured() {return fwd_wrongly_conf;} FwdAttError get_err_kind() {return err_kind;} void set_err_kind(FwdAttError _e) {err_kind = _e;} virtual void read(DeviceImpl *,Attribute &); virtual void write(DeviceImpl *,WAttribute &); virtual bool is_allowed(DeviceImpl *,AttReqType) {return true;} virtual void init_conf(AttrConfEventData *); bool validate_fwd_att(vector &,const string &); void get_root_conf(string &,DeviceImpl *); void remove_useless_prop(vector &,string &,MultiAttribute *); string &get_label_from_default_properties(); protected: /// @privatesection string full_root_att; // Root att (dev_name/att_name) string fwd_dev_name; // Root att device name (lower case) string fwd_root_att; // Root att (lower case) bool fwd_wrongly_conf; FwdAttError err_kind; private: class FwdAttrExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else FwdAttrExt *ext; #endif }; } // End of Tango namespace #endif /* _FWDATTRDESC_H */ tango-9.2.5a/lib/cpp/server/fwdattribute.h0000644023471100065110000000550113034745002015440 00000000000000 //=================================================================================================================== // // file : fwdattribute.h // // description : Include file for the FwdAttribute classes. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //==================================================================================================================== #ifndef _FWDATTRIBUTE_H #define _FWDATTRIBUTE_H #include #ifdef _TG_WINDOWS_ #include #include #endif namespace Tango { class FwdAttribute: public WAttribute { public: FwdAttribute(vector &,Attr &,string &,long); ~FwdAttribute(); virtual bool is_fwd_att() {return true;} string &get_fwd_dev_name() {return fwd_dev_name;} string &get_fwd_att_name() {return fwd_att_name;} void set_att_config(const Tango::AttributeConfig_5 &); void set_att_config(const Tango::AttributeConfig_3 &) {} void set_att_config(AttributeInfoEx *); void upd_att_config_base(const char *); void upd_att_config(const Tango::AttributeConfig_5 &); void upd_att_config(const Tango::AttributeConfig_3 &); void upd_att_label(const char *); bool new_att_conf(const Tango::AttributeConfig_3 *,const Tango::AttributeConfig_5 *); Attr_Value &get_root_ptr() {return r_val;} template void set_local_attribute(DeviceAttribute &, T* &); template void propagate_writen_data(DeviceAttribute &da,WAttribute &attr,T *&,V *&); template bool new_att_conf_base(const T&); DevAttrHistory_5 *read_root_att_history(long n); AttributeValueList_5 *write_read_root_att(AttributeValueList_4&); protected: void convert_event_prop(string &,double *); string fwd_dev_name; // Root dev name for fwd attribute string fwd_att_name; // Root att name for fwd attribute AttrQuality qual; #ifdef _TG_WINDOWS_ struct _timeb tv; #else timeval tv; #endif Attr_Value r_val; }; } // End of Tango namespace #endif // _FWDATTRIBUTE_H tango-9.2.5a/lib/cpp/server/log4tango.h0000644023471100065110000000627213034745001014637 00000000000000/* * * Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 * European Synchrotron Radiation Facility * BP 220, Grenoble 38043 * FRANCE * * This file is part of Tango. * * Tango is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tango is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Tango. If not, see . * * log4tango.h * * NL - SOLEIL. * */ #ifndef _LOG4TANGO_H_ #define _LOG4TANGO_H_ #ifdef TANGO_HAS_LOG4TANGO //------------------------------------------------------------- // REQUIRED LOG4TANGO STUFFS //------------------------------------------------------------- #include #include #include #include #include //------------------------------------------------------------- // REQUIRED TANGO LOGGING STUFFS //------------------------------------------------------------- #include #include //------------------------------------------------------------- // LOGGING MACROS (FOR DEVICE DEVELOPERS) //------------------------------------------------------------- #define LOG_FATAL(X) \ get_logger()->fatal X #define LOG_ERROR(X) \ get_logger()->error X #define LOG_WARN(X) \ get_logger()->warn X #define LOG_INFO(X) \ get_logger()->info X #define LOG_DEBUG(X) \ get_logger()->debug X #define FATAL_STREAM \ if (get_logger()->is_fatal_enabled()) \ get_logger()->fatal_stream() \ << log4tango::LogInitiator::_begin_log #define ERROR_STREAM \ if (get_logger()->is_error_enabled()) \ get_logger()->error_stream() \ << log4tango::LogInitiator::_begin_log #define WARN_STREAM \ if (get_logger()->is_warn_enabled()) \ get_logger()->warn_stream() \ << log4tango::LogInitiator::_begin_log #define INFO_STREAM \ if (get_logger()->is_info_enabled()) \ get_logger()->info_stream() \ << log4tango::LogInitiator::_begin_log #define DEBUG_STREAM \ if (get_logger()->is_debug_enabled()) \ get_logger()->debug_stream() \ << log4tango::LogInitiator::_begin_log #define ENDLOG \ log4tango::LogSeparator::_end_log //------------------------------------------------------------- // A CLASS TO LOG IN THE NAME OF DEVICE (USING DEV'S LOGGER) //------------------------------------------------------------- namespace Tango { class LogAdapter { public: LogAdapter(Tango::DeviceImpl *dev); virtual ~LogAdapter(); inline log4tango::Logger* get_logger (void) { return logger_; } private: log4tango::Logger* logger_; }; } // namespace Tango #endif // TANGO_HAS_LOG4TANGO #endif // _LOG4TANGO_H_ tango-9.2.5a/lib/cpp/server/logcmds.h0000644023471100065110000001333713034745001014371 00000000000000//============================================================================= // // file : LogCmds.h // // description : Logging oriented commands of the DServerClass. // // project : TANGO // // author(s) : N.Leclercq // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifdef TANGO_HAS_LOG4TANGO #ifndef _LOG_CMDS_H #define _LOG_CMDS_H #include namespace Tango { //============================================================================= // // The AddLoggingTarget class // // description : Class implementing the AddLoggingTarget command. // This command adds one (or more) logging target to one (or more) // device(s) running within the same Device server. // //============================================================================= class AddLoggingTarget : public Command { public: AddLoggingTarget (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc); ~AddLoggingTarget() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The RemoveLoggingTarget class // // description : Class implementing the RemoveLoggingTarget command. // This command removes one (or more) logging target to one (or more) // device(s) running within the same Device server. // //============================================================================= class RemoveLoggingTarget : public Command { public: RemoveLoggingTarget (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc); ~RemoveLoggingTarget() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The GetLoggingTarget class // // description : Class implementing the GetLoggingTarget command. // This command returns the logging target list of a device. // //============================================================================= class GetLoggingTarget : public Command { public: GetLoggingTarget (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc, const std::string &out_desc); ~GetLoggingTarget() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The SetLoggingLevel class // // description : Class implementing the SetLoggingLevel command. // This command set the logging level of one or more device(s). // //============================================================================= class SetLoggingLevel : public Command { public: SetLoggingLevel (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc); ~SetLoggingLevel() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The GetLoggingLevel class // // description : Class implementing the GetLoggingLevel command. // This command returns the logging level of one or more device(s). // //============================================================================= class GetLoggingLevel : public Command { public: GetLoggingLevel (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc, const std::string &out_desc); ~GetLoggingLevel() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The StopLogging class // // description : Class implementing the StopLogging command. // This command disable the logging for all the devices. // //============================================================================= class StopLogging : public Command { public: StopLogging (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~StopLogging() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The StartLogging class // // description : Class implementing the StartLogging command. // This command enable the logging for all the devices. // //============================================================================= class StartLogging : public Command { public: StartLogging (const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~StartLogging() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; } // End of Tango namespace #endif // _LOG_CMDS_H #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/logging.h0000644023471100065110000001411313034745001014360 00000000000000//+============================================================================= // // file : Logging.h // // description : TLS helper class (pseudo-singleton) // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #ifndef _LOGGING_H_ #define _LOGGING_H_ #ifdef TANGO_HAS_LOG4TANGO // A shortcut to the core logger ------------------------------ #define API_LOGGER Tango::Logging::get_core_logger() #ifdef _TANGO_LIB //== compiling TANGO lib ==================== //-- Overwrite std::cout ------------------------------------- #define cout \ if (API_LOGGER) \ API_LOGGER->get_stream(log4tango::Level::INFO, false) \ << log4tango::LogInitiator::_begin_log #endif //== compiling TANGO lib =============================== // Map. cout1..2 to INFO level -------------------------------- #define cout1 \ if (API_LOGGER && API_LOGGER->is_info_enabled()) \ API_LOGGER->info_stream() \ << log4tango::LogInitiator::_begin_log #define cout2 cout1 // Map. cout3..5 to DEBUG level ------------------------------- #define cout3 \ if (API_LOGGER && API_LOGGER->is_debug_enabled()) \ API_LOGGER->debug_stream() \ << log4tango::LogInitiator::_begin_log #define cout4 cout3 #define cout5 cout4 namespace Tango { class Util; #if defined (_TG_WINDOWS_) && !defined(_TANGO_LIB) && defined(TANGO_HAS_DLL) extern __declspec(dllimport) log4tango::Logger* _core_logger; #else extern log4tango::Logger* _core_logger; #endif class Logging { public: /** * Initializes the Tango Logging service (TLS) **/ static void init (const std::string& ds_name, int cmd_line_level, bool use_tango_db, Database &db, Util *tg); /** * Shutdown the Tango Logging service **/ static void cleanup (void); /** * Returns the core logger substitute **/ inline static log4tango::Logger* get_core_logger (void) { return _core_logger; } /** * Implementation of the DServer AddLoggingTarget Tango command **/ static void add_logging_target (const DevVarStringArray *argin); /** * Implementation of the DServer AddLoggingTarget Tango command **/ static void add_logging_target (log4tango::Logger* logger, const std::string& tg_type, const std::string& tg_name, int throw_exception = 1); /** * Implementation of the DServer AddLoggingTarget Tango command **/ static void add_logging_target (log4tango::Logger* logger, const std::string& tg_type_name, int throw_exception = 1); /** * Implementation of the DServer RemoveLoggingTarget Tango command **/ static void remove_logging_target (const DevVarStringArray *argin); /** * Implementation of the DServer GetLoggingTarget Tango command **/ static DevVarStringArray* get_logging_target (const std::string& dev_name); /** * Implementation of the DServer SetLoggingLevel Tango command **/ static void set_logging_level (const DevVarLongStringArray *argin); /** * Implementation of the DServer GetLoggingLevel Tango command **/ static DevVarLongStringArray* get_logging_level (const DevVarStringArray *argin); /** * Implementation of the DServer StartLogging Tango command **/ static void start_logging (void); /** * Implementation of the DServer StopLogging Tango command **/ static void stop_logging (void); /** * Converts a Tango logging level into a log4tango level **/ static log4tango::Level::Value tango_to_log4tango_level (Tango::LogLevel tango_level, bool throw_exception = true); /** * Converts a Tango logging level into a log4tango level **/ static log4tango::Level::Value tango_to_log4tango_level (const std::string& tango_level, bool throw_exception = true); /** * Converts a log4tango level into a Tango logging level **/ static Tango::LogLevel log4tango_to_tango_level (log4tango::Level::Value log4tango_level); /** * Modify the rolling file threshold of the given Logger **/ static void set_rolling_file_threshold(log4tango::Logger* logger, size_t rtf); private: /** * **/ static void kill_zombie_appenders (void); /** * **/ static std::string dev_to_file_name (const std::string& _dev_name); /** * **/ static int get_target_type_and_name (const std::string& input, std::string& type, std::string& name); /** * **/ static int create_log_dir (const std::string& full_path); /** * Protect the Logging class against instanciation and copy **/ Logging (const Logging&); ~Logging(); const Logging& operator= (const Logging&); /** * **/ static std::string _log_path; /** * **/ static size_t _rft; /** * **/ static int _cmd_line_level; }; } // namespace tango #endif // TANGO_HAS_LOG4TANGO #endif // _LOGGING_H_ tango-9.2.5a/lib/cpp/server/logstream.h0000644023471100065110000000637413034745001014741 00000000000000//+============================================================================= // // file : logstream.h // // description : A TLS helper class // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // //-============================================================================= #ifndef _LOG_STREAM_H #define _LOG_STREAM_H #ifdef TANGO_HAS_LOG4TANGO //----------------------------------------------------------------------------- // FORWARD DECLARATIONS //----------------------------------------------------------------------------- namespace log4tango { class LoggerStream; } // namespace log4tango namespace Tango { class Attr; class DevFailed; class Attribute; class AttrManip; class AttrProperty; class DevVarCharArray; class DevVarShortArray; class DevVarLongArray; class DevVarFloatArray; class DevVarDoubleArray; class DevVarUShortArray; class DevVarULongArray; class DevVarStringArray; } // namespace Tango //----------------------------------------------------------------------------- // MISC. OPERATORS TO PUSH TANGO TYPES INTO LOG4TANGO STREAMS //----------------------------------------------------------------------------- namespace Tango { log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevFailed&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarCharArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarShortArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarLongArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarFloatArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarDoubleArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarUShortArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarULongArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const DevVarStringArray&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const Attribute&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const Attr&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const AttrManip&); log4tango::LoggerStream& operator<< (log4tango::LoggerStream&, const AttrProperty&); } // Tango namespace #endif // TANGO_HAS_LOG4TANGO #endif // _LOG_STREAM_H tango-9.2.5a/lib/cpp/server/multiattribute.h0000644023471100065110000002312613034745001016014 00000000000000//============================================================================= // // file : MultiAttribute.h // // description : Include file for the MultiAttribute class. // Each device has one object of this class. All device // attribute objects are stored in this class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28373 $ // // //============================================================================= #ifndef _MULTIATTRIBUTE_H #define _MULTIATTRIBUTE_H #include namespace Tango { class AttrProperty; class DeviceClass; struct EventPar { long attr_id; vector change; vector archive; bool quality; vector periodic; vector user; vector att_conf; bool data_ready; bool dev_intr_change; bool notifd; bool zmq; }; //============================================================================= // // The MultiAttribute class // // // description : There is one instance of this class for each device. // This is mainly a helper class. It maintains a vector // of all the attribute for the device // //============================================================================= /** * There is one instance of this class for each device. This class is mainly * an aggregate of Attribute or WAttribute objects. It eases management of * multiple attributes * * $Author: taurel $ * $Revision: 28373 $ * * @headerfile tango.h * @ingroup Server */ class MultiAttribute { public: /**@name Constructor * Only one constructor is defined for this class */ //@{ /** * Create a new MultiAttribute object. * * This constructor will in-turn call the constructor of the Attribute or * WAttribute class of all the device class attributes. * * @param dev_name The device name * @param dev_class Reference to the device DeviceClass object * @param dev The device pointer * @exception DevFailed If the command sent to the database failed. * Click here to read * DevFailed exception specification */ MultiAttribute(string &dev_name,DeviceClass *dev_class,DeviceImpl *dev); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The MultiAttribute desctructor. */ ~MultiAttribute(); //@} /**@name Miscellaneous methods */ //@{ /** * Get Attribute object from its name. * * This method returns a reference to the Attribute object with a name passed * as parameter. The equality on attribute name is case independant. * * @param attr_name The attribute name * @return A reference to the Attribute object * @exception DevFailed If the attribute is not defined. * Click here to read * DevFailed exception specification */ Attribute &get_attr_by_name(const char *attr_name); /** * Get Attribute object from its index. * * This method returns a reference to the Attribute object from the index in the * main attribute vector * * @param ind The attribute index * @return A reference to the Attribute object */ Attribute &get_attr_by_ind(const long ind) {return *(attr_list[ind]);} /** * Get Writable Attribute object from its name. * * This method returns a reference to the WAttribute object with a name passed * as parameter. The equality on attribute name is case independant. * * @param attr_name The attribute name * @return A reference to the writable attribute object * @exception DevFailed If the attribute is not defined. * Click here to read * DevFailed exception specification */ WAttribute &get_w_attr_by_name(const char *attr_name); /** * Get Writable Attribute object from its index. * * This method returns a reference to the Writable Attribute object from the * index in the main attribute vector * * @param ind The attribute index * @return A reference to the WAttribute object */ WAttribute &get_w_attr_by_ind(const long ind) {return static_cast(*(attr_list[ind]));} /** * Get Attribute index into the main attribute vector from its name. * * This method returns the index in the Attribute vector (stored in the * MultiAttribute object) of an attribute with a given name. The name equality * is case independant * * @param attr_name The attribute name * @return The index in the main attributes vector * @exception DevFailed If the attribute is not found in the vector. * Click here to read * DevFailed exception specification */ long get_attr_ind_by_name(const char *attr_name); /** * Get list of attribute with an alarm level defined. * * @return A vector of long data. Each object is the index in the main * attribute vector of attribute with alarm level defined */ vector &get_alarm_list() {return alarm_attr_list;} /** * Get attribute number. * * @return The attribute number */ unsigned long get_attr_nb() {return (unsigned long)attr_list.size();} /** * Check alarm for one attribute with a given name. * * This method returns a boolean set to true if the attribute with the given * name is in alarm condition * * @param attr_name The attribute name * @return A boolean set to true if the attribute is in alarm * @exception DevFailed If the attribute does not have any alarm level defined. * Click here to read * DevFailed exception specification * */ bool check_alarm(const char *attr_name) {return get_attr_by_name(attr_name).check_alarm();} /** * Check alarm for one attribute from its index in the main attributes vector. * * This method returns a boolean set to true if the attribute with the given * index in the attrobite object vector is in alarm condition * * @param ind The attribute index * @return A boolean set to true if the attribute is in alarm * @exception DevFailed If the attribute does not have any alarm level defined. * Click here to read * DevFailed exception specification * */ bool check_alarm(const long ind) {return get_attr_by_ind(ind).check_alarm();} /** * Check alarm on all attribute(s) with an alarm defined. * * This method returns a boolean set to true if one of the attribute with an * alarm level defined is in alarm condition. * * @return A boolean set to true if one attribute is in alarm * @exception DevFailed If the alarm level are not defined for one of the * attribute in the list of alarmable one * Click here to read * DevFailed exception specification * */ bool check_alarm(); /** * Add alarm message to device status. * * This method add alarm mesage to the string passed as parameter. A message * is added for each attribute which is in alarm condition * * @param status The string (should be the device status) */ void read_alarm(string &status); /** * Get the vector of attribute objects. * * Returns the vector of attribute objects. * */ vector &get_attribute_list(){return attr_list;} //@} protected: /**@name Class data members */ //@{ /** * The Attribute objects vector. * * This vector is often referred as the main attributes vector */ vector attr_list; /** * The list of writable attribute. * * It is a vector of index in the main attribute vector */ vector writable_attr_list; /** * The list of attribute with an alarm level defined. * * It is a vector of index in the main attribute vector */ vector alarm_attr_list; //@} public: /// @privatesection void add_write_value(Attribute &); void add_attribute(string &,DeviceClass *,long); void add_fwd_attribute(string &,DeviceClass *,long,Attr *); void remove_attribute(string &,bool); vector &get_w_attr_list() {return writable_attr_list;} bool is_att_quality_alarmed(); void get_event_param(vector &); void set_event_param(vector &); void add_alarmed_quality_factor(string &); void add_default(vector &,string &,string &,long); void add_attr(Attribute *att) {attr_list.push_back(att);} void update(Attribute &,string &); void check_idl_release(DeviceImpl *); bool is_opt_prop(const string &); private: class MultiAttributeExt { }; void concat(vector &,vector &,vector &); void add_user_default(vector &,vector &); void check_associated(long,string &); #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else MultiAttributeExt *ext; #endif }; } // End of Tango namespace #endif // _MULTIATTRIBUTE_H tango-9.2.5a/lib/cpp/server/ntservice.h0000644023471100065110000000610213034745001014733 00000000000000// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef _NTSERVICE_H #define _NTSERVICE_H #include using namespace std; namespace Tango { // // This is a custom message logger that is used to dump messages to // the NT system log -- the user must ensure that this logger is // used for NT native services // //class NTEventLogger : public OB::Logger, // public OBCORBA::RefCountLocalObject class NTEventLogger { private: HANDLE eventSource_; // The event source string service_; // Service name DWORD eventId_; // The event ID void emitMessage(int, const char*); bool installValues(HKEY); public: NTEventLogger(const char*, DWORD); virtual ~NTEventLogger(); bool install(); bool uninstall(); virtual void info(const char*); virtual void error(const char*); virtual void warning(const char*); virtual void trace(const char*, const char*); }; // // This class represents an NT service. // class NTService { private: static NTService* instance_; // The one and only instance string full_exec_name_; // Full executable name string exec_name_; // Executable name string name_; // The name string title_; // The title bool debug_; // Are we debugging? DWORD checkPoint_; // Check point value SERVICE_STATUS status_; // Status of the service SERVICE_STATUS_HANDLE statusHandle_; // Status handle virtual void start(int, char**, Tango::NTEventLogger *ptr) = 0; void control(DWORD); void main(int argc, char** argv); friend void WINAPI _OB_serviceCtrl(DWORD); friend void WINAPI _OB_serviceMain(DWORD, LPTSTR*); friend class Util; protected: void statusUpdate(DWORD, DWORD = NO_ERROR, DWORD = 0); bool stopped_; public: Tango::NTEventLogger *logger_; // The service logger bool is_installed(); NTService(const char *name); virtual ~NTService(); static NTService* instance(); bool install(char *,bool = false); bool uninstall(char *); void run(int, char**); virtual void stop(); int options(int,char **); void usage(const char *); void setDebug() { debug_ = true; } bool getDebug() const { return debug_; } }; } // End of Tango namespace #endif tango-9.2.5a/lib/cpp/server/pipe.h0000644023471100065110000003507113034745002013676 00000000000000//=================================================================================================================== // // file : Pipe.h // // description : Include file for the Pipe class. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28947 $ // //=================================================================================================================== #ifndef _PIPE_H #define _PIPE_H #include #include namespace Tango { #ifndef HAS_LAMBDA_FUNC // // Binary function objects to be used by the find_if algorithm. // The find_if algo. want to have a predicate, this means that the return value must be a boolean (R is its name). // The find_if algo. needs a unary predicate. This function object is a binary function object. // It must be used with the bind2nd function adapter // template struct WantedPipe : public binary_function { R operator() (A1 pipe_ptr, A2 name) const { if (::strlen(name) != pipe_ptr->get_lower_name().size()) return false; string tmp_name(name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); return pipe_ptr->get_lower_name() == tmp_name; } }; #endif /** * This class is a class representing a pipe in the TANGO device server pattern. It is an abstract class. * It is the root class for all pipe related classes. * * $Author: taurel $ * $Revision: 28947 $ * * @headerfile tango.h * @ingroup Server */ class Pipe { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated Pipe object. * * The default constructor */ Pipe():ext(new PipeExt) {} /** * Constructs a newly allocated Pipe object from its * name and its display level * * @param name The pipe name * @param level The pipe display level * @param pwt The pipe R/W type (default to READ) * */ Pipe(const string &name,const Tango::DispLevel level,const PipeWriteType pwt=PIPE_READ); //@} /**@name Destructor * Only one destructor is defined for this class */ //@{ /** * The object desctructor. */ #ifdef HAS_UNIQUE_PTR virtual ~Pipe() {} #else virtual ~Pipe() {delete ext;} #endif //@} /**@name Miscellaneous methods */ //@{ //@} /**@name Get/Set object members. * These methods allows the external world to get/set Pipe instance * data members */ //@{ /** * Return the pipe name. * * @return The pipe name */ string &get_name() {return name;} /** * Set the pipe name. * * @param new_name The new pipe name */ void set_name(string &new_name) {name=new_name;} /** * Set default attribute properties * * @param prop The user default property class */ void set_default_properties(UserDefaultPipeProp &prop); /** * Return the pipe name in lower case letters. * * @return The pipe name */ string &get_lower_name() {return lower_name;} /** * Return the root data blob name. * * @return The data blob name */ const string &get_root_blob_name() {return the_blob.get_name();} /** * Set the root data blob name. * * @param [in] name The root data blob name */ void set_root_blob_name(const string &name) {the_blob.set_name(name);} /** * Return the pipe description. * * @return The pipe description */ string &get_desc() {return desc;} /** * Return the pipe label. * * @return The pipe label */ string &get_label() {return label;} /** * Return the pipe display level. * * @return The pipe display level */ Tango::DispLevel get_disp_level() {return disp_level;} /** * Get the pipe writable type (RO/RW). * * @return The pipe write type. */ Tango::PipeWriteType get_writable() {return writable;} /** * Set pipe serialization model * * This method allows the user to choose the pipe serialization model. * * @param [in] ser_model The new serialisation model. The serialization model must be * one of PIPE_BY_KERNEL, PIPE_BY_USER or PIPE_NO_SYNC */ void set_pipe_serial_model(PipeSerialModel ser_model); /** * Get pipe serialization model * * Get the pipe serialization model * * @return The pipe serialization model */ PipeSerialModel get_pipe_serial_model() {return pipe_serial_model;} /** * Set pipe user mutex * * This method allows the user to give to the pipe object the pointer to * the omni_mutex used to protect its buffer. The mutex has to be locked when passed * to this method. The Tango kernel will unlock it when the data will be transferred * to the client. * * @param [in] mut_ptr The user mutex pointer */ void set_user_pipe_mutex(omni_mutex *mut_ptr) {user_pipe_mutex = mut_ptr;} //@} /**@name Inserting data into a DevicePipe */ //@{ #ifdef GEN_DOC /** * Insert data into a device pipe * * Inserting data into a Pipe instance is simlar to inserting data into a DevicePipeBlob class instance. * See doc of DevicePipeBlob class insertion methods (DevicePipeBlob::operator<<) to get a complete documentation on * how to insert data into a Pipe object * * @param [in] datum The data to be inserted into the Pipe object * @exception WrongData if requested */ Pipe & operator << (short &datum); #endif /** * Set blob data element number * * Set the blob data element number * * @param [in] nb The blob data element number */ void set_data_elt_nb(size_t nb) {the_blob.set_data_elt_nb(nb);} /** * Set blob data element number and names * * Set the blob data element number and names. The data element number is the number of names in the input * parameter. * * @param [in] names The blob data element names */ void set_data_elt_names(vector &names) {the_blob.set_data_elt_names(names);} /** * Get blob data element number * * Get the blob data element number * * @return The blob data element number */ size_t get_data_elt_nb() {return the_blob.get_data_elt_nb();} //@} /**@name Exception and error related methods methods */ //@{ /** * Set exception flag * * It's a method which allows the user to switch on/off exception throwing when trying to insert/extract data from a * Pipe object. The following flags are supported : * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user * tries to extract data from one empty blob data element. By default, this flag * is set * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion. By default, this flag * is set * @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user * tries to extract data from a DevicePipeBlob for a data element which does not exist. By default, this flag * is set * @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to * insert data into the blob while the name or number of data element has not been set with methods * set_data_elt_nb() or set_data_elt_names() * @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix * insertion/extraction method (<< or >>) with operator[] * * @param [in] fl The exception flag */ void exceptions(bitset fl) {the_blob.exceptions(fl);} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * Pipe pi; * * bitset bs = pi.exceptions(); * cout << "bs = " << bs << endl; * * pi.set_exceptions(DevicePipeBlob::wrongtype_flag); * bs = pi.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return the_blob.exceptions();} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(DevicePipeBlob::except_flags fl) {the_blob.reset_exceptions(fl);} /** * Set one exception flag * * Sets one exception flag. See DevicePipeBlob::exceptions() for a usage example. * * @param [in] fl The exception flag */ void set_exceptions(DevicePipeBlob::except_flags fl) {the_blob.set_exceptions(fl);} /** * Check insertion/extraction success * * Allow the user to check if insertion/extraction into/from Pipe instance was successfull. This * method has to be used when exceptions are disabled. * * @return True if insertion/extraction has failed */ bool has_failed() {return the_blob.has_failed();} /** * Get instance insertion/extraction state * * Allow the user to find out what was the reason of insertion/extraction into/from Pipe failure. This * method has to be used when exceptions are disabled. * Here is an example of how methods has_failed() and state() could be used * @code * Pipe dpb = .... * * bitset bs; * bs.reset(); * dpb.exceptions(bs); * * DevLong dl; * dpb >> dl; * * if (dpb.has_failed() == true) * { * bitset bs_err = dpb.state(); * if (dpb.test(DevicePipeBlob::isempty_flag) == true) * ..... * } * @endcode * * @return The error bit set. */ bitset state() {return the_blob.state();} //@} /**@name set_value methods. * Methods to set the value of the data blob to be transported by the pipe */ //@{ //@} /// @privatesection virtual bool is_allowed (DeviceImpl *dev,PipeReqType) {(void)dev;return true;} virtual void read(DeviceImpl *) {} Pipe &operator[](const string &); bool get_value_flag() {return value_flag;} void set_value_flag(bool val) {value_flag = val;} void set_time(); Tango::TimeVal &get_when() {return when;} void set_returned_data_ptr(DevPipeData *_p) {ret_data=_p;} void set_label(const string &_lab) {label=_lab;} void set_desc(const string &_desc) {desc=_desc;} bool is_label_lib_default() {return label==name;} bool is_desc_lib_default() {return desc==DescNotSpec;} void set_upd_properties(const PipeConfig &,DeviceImpl *); void set_properties(const Tango::PipeConfig &,DeviceImpl *,vector &); void upd_database(vector &,string &); vector &get_user_default_properties() {return user_def_prop;} void set_one_str_prop(const char *,const CORBA::String_member &,string &,vector &,vector &,vector &,const char *); bool prop_in_list(const char *,string &,size_t,vector &); DevicePipeBlob &get_blob() {return the_blob;} omni_mutex *get_pipe_mutex() {return &pipe_mutex;} omni_mutex *get_user_pipe_mutex() {return user_pipe_mutex;} void fire_event(DeviceImpl *,DevFailed *); #ifdef _TG_WINDOWS_ void fire_event(DeviceImpl *,DevicePipeBlob *,bool); #else void fire_event(DeviceImpl *_dev,DevicePipeBlob *_dat,bool bo) {struct timeval now;gettimeofday(&now,NULL);fire_event(_dev,_dat,now,bo);} #endif void fire_event(DeviceImpl *,DevicePipeBlob *,struct timeval &,bool); void set_event_subscription(time_t _t) {event_subscription = _t;} friend class EventSupplier; friend class ZmqEventSupplier; protected: /**@name Class data members */ //@{ /** * The pipe name */ string name; /** * The pipe name in lower case */ string lower_name; /** * The pipe description */ string desc; /** * The pipe label */ string label; /** * The pipe display level */ Tango::DispLevel disp_level; /** * The pipe R/W type */ Tango::PipeWriteType writable; //@} DevicePipeBlob the_blob; private: class PipeExt { public: PipeExt() {} }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else PipeExt *ext; #endif bool value_flag; // Flag set when pipe value is set Tango::TimeVal when; // Date associated to the pipe Tango::DevPipeData *ret_data; // Pointer for read data vector pe_out_names; // Data elements name int rec_count; // Data elements ctr PipeSerialModel pipe_serial_model; // Flag for attribute serialization model omni_mutex pipe_mutex; // Mutex to protect the pipe shared data buffer omni_mutex *user_pipe_mutex; // Ptr for user mutex in case he manages exclusion time_t event_subscription; // Last time() a subscription was made vector user_def_prop; // User default properties }; template Pipe &operator<<(Pipe &,T &); template Pipe &operator<<(Pipe &,T *); template Pipe &operator<<(Pipe &, DataElement &); // // Throw exception if pointer is null // #define PIPE_CHECK_PTR(A,B,C) \ if (A == NULL) \ { \ stringstream o; \ o << "Data pointer for pipe " << B << ", data element " << C << " is NULL!"; \ Except::throw_exception(API_PipeOptProp,o.str(),"Pipe::set_value()"); \ } \ else \ (void)0 // // Some inline methods // //+------------------------------------------------------------------------------------------------------------------ // // method : // Pipe::prop_in_list // // description : // Search for a property in a list // A similar method exists in Attribute class!! // // args: // in : // - prop_name : The property name // - list_size : The size list // - list : The list // out : // - prop_str : String initialized with prop. value (if found) // //------------------------------------------------------------------------------------------------------------------ inline bool Pipe::prop_in_list(const char *prop_name,string &prop_str,size_t list_size,vector &list) { bool ret = false; if (list_size != 0) { size_t i; for (i = 0;i < list_size;i++) { if (list[i].get_name() == prop_name) break; } if (i != list_size) { prop_str = list[i].get_value(); ret = true; } } return ret; } } // End of Tango namespace #endif // _PIPE_H tango-9.2.5a/lib/cpp/server/pipedesc.h0000644023471100065110000000530213034745001014526 00000000000000//=================================================================================================================== // // file : pipedesc.h // // description : Include file for the Pipe user configuration // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 26082 $ // //=================================================================================================================== #ifndef _PIPEDESC_H #define _PIPEDESC_H #include namespace Tango { /** * User class to set pipe default properties. * * This class is used to set pipe default properties. Three levels of * pipes properties setting are implemented within Tango. The highest * property setting level is the database. Then the user default (set using * this UserDefaultPipeProp class) and finally a Tango library default * value * * $Author: taurel $ * $Revision: 26082 $ * * @headerfile tango.h * @ingroup Server */ class UserDefaultPipeProp { public: /**@name Constructor * Only one constructor is defined for this class */ //@{ /** * Constructs a newly allocated UserDefaultPipeProp object. */ UserDefaultPipeProp():ext(Tango_nullptr) {} //@} /**@name Set default property methods */ //@{ /** * Set default label property * * @param def_label The user default label property */ void set_label(const string &def_label) { label = def_label; } /** * Set default description property * * @param def_desc The user default description property */ void set_description(const string &def_desc) { description = def_desc; } //@} /// @privatesection ~UserDefaultPipeProp() {} string label; string description; private: class UserDefaultPipePropExt { }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else UserDefaultPipePropExt *ext; #endif }; } // End of Tango namespace #endif /* _PIPEDESC_H */ tango-9.2.5a/lib/cpp/server/pollcmds.h0000644023471100065110000001364213034745002014556 00000000000000//============================================================================= // // file : PollCmds.h // // description : Include for the DServerClass class. This class is a // singleton class i.e only one object of this class // can be created. // It contains all properties and methods // which the DServer requires only once e.g. the // commands. // This file also includes class declaration for all the // commands available on device of the DServer class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // //============================================================================= #ifndef _POLLCMDS_H #define _POLLCMDS_H #include namespace Tango { //============================================================================= // // The PolledDevice class // // description : Class to implement the PolledDevice command. // This class returns the name list of device actually // polled // //============================================================================= class PolledDeviceCmd : public Command { public: PolledDeviceCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *desc); ~PolledDeviceCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The DevPollStatus class // // description : Class to implement the DevPollStatus command. // This class returns status of all commands and/or // attribute polled for a device // //============================================================================= class DevPollStatusCmd : public Command { public: DevPollStatusCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc); ~DevPollStatusCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The AddObjPolling class // // description : Class to implement the AddObjPolling command. // This command add a new command/attribute in the list // of command/attribute to be polled // //============================================================================= class AddObjPollingCmd : public Command { public: AddObjPollingCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc); ~AddObjPollingCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The UpdObjPollingPeriod class // // description : Class to implement the UpdObjPollingPeriod command. // This command updates an object update period // //============================================================================= class UpdObjPollingPeriodCmd : public Command { public: UpdObjPollingPeriodCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc); ~UpdObjPollingPeriodCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The RemObjPolling class // // description : Class to implement the RemObjPolling command. // This command removes one object of the device polling // list // //============================================================================= class RemObjPollingCmd : public Command { public: RemObjPollingCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc); ~RemObjPollingCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The StopPolling class // // description : Class to implement the StopPolling command. // This command stops the polling thread // //============================================================================= class StopPollingCmd : public Command { public: StopPollingCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~StopPollingCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; //============================================================================= // // The StartPolling class // // description : Class to implement the StartPolling command. // This command starts the polling thread // //============================================================================= class StartPollingCmd : public Command { public: StartPollingCmd(const char *cmd_name, Tango::CmdArgType in, Tango::CmdArgType out); ~StartPollingCmd() {}; virtual CORBA::Any *execute(DeviceImpl *device, const CORBA::Any &in_any); }; } // End of Tango namespace #endif // _POLLCMDS_H tango-9.2.5a/lib/cpp/server/pollext.h0000644023471100065110000007067713034745001014442 00000000000000//============================================================================= // // file : PollExt.h // // description : Include for classes used by the method dedicated // to fill the polling buffer for command or // attributes. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 15556 // //============================================================================= #ifndef _POLLEXT_H #define _POLLEXT_H #include namespace Tango { //============================================================================= // // Attribute related class // // description : These classes are used when the user want to fill // attribute polling buffer // //============================================================================= //============================================================================= // // The AttrData class // // // description : This class is used to store all the data needed to build // an attribute value. // //============================================================================= #define __CHECK_DIM() \ if ((x == 0) || (y == 0)) \ { \ Except::throw_exception((const char *)API_AttrOptProp, \ (const char *)"X or Y dimension cannot be 0 for image attribute", \ (const char *)"AttrData::AttrData"); \ } \ else \ (void)0 #define __CHECK_DIM_X() \ if (x == 0) \ { \ Except::throw_exception((const char *)API_AttrOptProp, \ (const char *)"X dimension cannot be 0 for spectrum or image attribute", \ (const char *)"AttrData::AttrData"); \ } \ else \ (void)0 template class AttrData { public: const T *ptr; Tango::AttrQuality qual; long x; long y; bool release; DevErrorList err; long wr_x; long wr_y; const T *wr_ptr; AttrData(const T *); AttrData(const T *,Tango::AttrQuality); AttrData(const T *,Tango::AttrQuality,bool); AttrData(const T *,const T *); AttrData(const T *,const T *,Tango::AttrQuality); AttrData(const T *,const T *,Tango::AttrQuality,bool); // For spectrum AttrData(const T *,long); AttrData(const T *,long,Tango::AttrQuality); AttrData(const T *,long,Tango::AttrQuality,bool); AttrData(const T *,long,const T *,long); AttrData(const T *,long,const T *,long,Tango::AttrQuality); AttrData(const T *,long,const T *,long,Tango::AttrQuality,bool); // For image AttrData(const T *,long,long); AttrData(const T *,long,long,Tango::AttrQuality); AttrData(const T *,long,long,Tango::AttrQuality,bool); AttrData(const T *,long,long,const T *,long,long); AttrData(const T *,long,long,const T *,long,long,Tango::AttrQuality); AttrData(const T *,long,long,const T *,long,long,Tango::AttrQuality,bool); // For error AttrData(DevErrorList &e): ptr(NULL),x(0),y(0),release(false),err(e),wr_x(0),wr_y(0),wr_ptr(NULL) {} }; //============================================================================= // // The TimedAttrData class // // // description : This class inherits from the AttrData class and adds // a date to all the data contains in the AttrData // class // //============================================================================= /** * This class is used to store one element of an attribute history stack. * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class TimedAttrData:public Tango::AttrData { public: /**@name Miscellaneous constructors for scalar attribute */ //@{ /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param when The date */ TimedAttrData(const T *p_data,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data and p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param when The date */ TimedAttrData(const T *p_data,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,struct timeval when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,Tango::AttrQuality qual,bool rel,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param p_wr_data Pointer to the written part of the attribute value * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data and p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,bool rel,struct timeval when); //@} // For spectrum /**@name Miscellaneous constructors for spectrum attribute */ //@{ /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param when The date */ TimedAttrData(const T *p_data,long x,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data and p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param when The date */ TimedAttrData(const T *p_data,long x,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,struct timeval when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,bool rel,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data and p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,bool rel,struct timeval when); //@} // For image /**@name Miscellaneous constructors for image attribute */ //@{ /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param when The date */ TimedAttrData(const T *p_data,long x,long y,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,time_t when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data and p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,bool rel,time_t when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param when The date */ TimedAttrData(const T *p_data,long x,long y,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * The attribute quality factor will be set to ATTR_VALID * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,struct timeval when); /** * Create a new TimedAttrData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * The memory pointed to by the p_data and p_wr_data parameters will not be freed * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param qual The attribute quality factor * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,struct timeval when); /** * Create a new TimedAttrData object. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,bool rel,struct timeval when); /** * Create a new TimedAttrData object for a R/W attribute. * * @param p_data Pointer to the attribute value * @param x The attribute x length * @param y The attribute y length * @param p_wr_data Pointer to the written part of the attribute value * @param x_wr The attribute written part x length * @param y_wr The attribute written part y length * @param qual The attribute quality factor * @param rel Set to true if the memory pointed to by the p_data abd p_wr_data parameters must be freed * @param when The date */ TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,bool rel,struct timeval when); //@} // For error /**@name Miscellaneous constructors for errors */ //@{ /** * Create a new TimedAttrData object for errors. * * The created TimedAttrData is used to store attribute errors * in the attribute history stack * * @param errs The error stack * @param when The date */ TimedAttrData(DevErrorList &errs,time_t when); /** * Create a new TimedAttrData object for errors. * * The created TimedAttrData is used to store attribute errors * in the attribute history stack * * @param errs The error stack * @param when The date */ TimedAttrData(DevErrorList &errs,timeval when); //@} /// @privatesection struct timeval t_val; #ifdef _TG_WINDOWS_ TimedAttrData(const T *p,struct _timeb t); TimedAttrData(const T *p,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,Tango::AttrQuality q,bool rel,struct _timeb t); TimedAttrData(const T *p,const T *p_wr_data,struct _timeb t); TimedAttrData(const T *p,const T *p_wr_data,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,const T *p_wr_data,Tango::AttrQuality q,bool rel,struct _timeb t); TimedAttrData(const T *p,long nb,struct _timeb t); TimedAttrData(const T *p,long nb,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,long nb,Tango::AttrQuality q,bool rel,struct _timeb t); TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,struct _timeb t); TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,Tango::AttrQuality q,bool rel,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,Tango::AttrQuality q,bool rel,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,Tango::AttrQuality q,struct _timeb t); TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,Tango::AttrQuality q,bool rel,struct _timeb t); #endif }; //============================================================================= // // The AttrHistoryStack class // // // description : This class is simply a wrapper above a vector of // TimedAttrData class. It is used to pass an attribute // value history which will be stored in the polling // buffer // //============================================================================= /** * This class is a used to pass an attribute value history when the user * directly fills the attribute polling buffer. Each element in this stack * will be used to store one element of the attribute polling buffer * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class AttrHistoryStack { public: /** * Store a new element in the stack * * This method stores a new element in the stack * * @param elt The new element */ void push(TimedAttrData const &elt); /** * Get stack depth * * @return The stack depth */ size_t length() {return hist.size();} /** * Reserve memory for stack elements * * @param nb The stack element number */ void length(long nb) {hist.reserve(nb);} /** * Clear the stack */ void clear() {hist.clear();} /** * Get stack data * * @return The stack itself */ vector > &get_data(); /// @privatesection AttrHistoryStack() {}; vector > hist; }; //============================================================================= // // Command related class // // description : These classes are used when the user want to fill // command polling buffer // //============================================================================= //============================================================================= // // The TimedCmdData class // // // description : This class is used to store all the data needed to build // a command value plus a date. // //============================================================================= /** * This class is used to store one element of a command history stack. * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class TimedCmdData { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Create a new TimedCmdData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the command result data * @param when The date */ TimedCmdData(T *p_data,time_t when); /** * Create a new TimedCmdData object with memory management. * * @param p_data Pointer to the command result data * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedCmdData(T *p_data,bool rel,time_t when); /** * Create a new TimedCmdData object. * * The memory pointed to by the p_data parameter will not be freed * * @param p_data Pointer to the command result data * @param when The date */ TimedCmdData(T *p_data,struct timeval when); /** * Create a new TimedCmdData object with memory management. * * @param p_data Pointer to the command result data * @param rel Set to true if the memory pointed to by the p_data parameter must be freed * @param when The date */ TimedCmdData(T *p_data,bool rel,struct timeval when); /** * Create a new TimedCmdData object for errors. * * The created TimedCmdData is used to store command errors * in the command history stack * * @param errs The error stack * @param when The date */ TimedCmdData(DevErrorList errs,time_t when): ptr(NULL),err(errs),release(false) {t_val.tv_sec = when;t_val.tv_usec = 0;} /** * Create a new TimedCmdData object for errors. * * The created TimedCmdData is used to store command errors * in the command history stack * * @param errs The error stack * @param when The date */ TimedCmdData(DevErrorList errs,timeval when): ptr(NULL),err(errs),t_val(when),release(false) {} //@} /// @privatesection T *ptr; DevErrorList err; struct timeval t_val; bool release; #ifdef _TG_WINDOWS_ TimedCmdData(T *p,struct _timeb t); TimedCmdData(T *p,bool rel,struct _timeb t); #endif }; //============================================================================= // // The CmdHistoryStack class // // // description : This class is simply a wrapper above a vector of // TimedCmdData class. It is used to pass a command // value history which will be stored in the polling // buffer // //============================================================================= /** * This class is a used to pass a command result history when the user * directly fills the command polling buffer. Each element in this stack * will be used to store one element of the command polling buffer * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ template class CmdHistoryStack { public: /** * Store a new element in the stack * * This method stores a new element in the stack * * @param elt The new element */ void push(Tango::TimedCmdData const &elt); /** * Get stack depth * * @return The stack depth */ size_t length() {return hist.size();} /** * Reserve memory for stack elements * * @param nb The stack element number */ void length(long nb) {hist.reserve(nb);} /** * Clear the stack */ void clear() {hist.clear();} /** * Get stack data * * @return The stack itself */ vector > &get_data(); /// @privatesection CmdHistoryStack() {}; vector > hist; }; } // End of Tango namespace #endif /* _POLLOBJ_ */ tango-9.2.5a/lib/cpp/server/pollobj.h0000644023471100065110000001312113034745001014371 00000000000000//============================================================================= // // file : PollObj.h // // description : Include for the PollObj object. This class implements // the polling ring buffer. Command result or attribute // values are stored in this buffer manages as a ring // buffer. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 29627 $ // //============================================================================= #ifndef _POLLOBJ_H #define _POLLOBJ_H #include #include namespace Tango { //============================================================================= // // The PollObj class // // description : Class to store all the necessary information which will // be stored and returned to client on request // // This class is protected against concurrent access by a // omni_mutex. We use the Thread-Safe interface pattern // to avoid "self-deadlock". This is why several methods // are splitted in two: One method called "meth" and // another one called "meth_i" (which is also sometimes // public !!) // //============================================================================= class PollObj: public omni_mutex { public: PollObj(DeviceImpl *,PollObjType,const string &,int); PollObj(DeviceImpl *,PollObjType,const string &,int,long); void insert_data(CORBA::Any *,struct timeval &,struct timeval &); void insert_data(Tango::AttributeValueList *,struct timeval &,struct timeval &); void insert_data(Tango::AttributeValueList_3 *,struct timeval &,struct timeval &); void insert_data(Tango::AttributeValueList_4 *,struct timeval &,struct timeval &); void insert_data(Tango::AttributeValueList_5 *,struct timeval &,struct timeval &); void insert_except(Tango::DevFailed *,struct timeval &,struct timeval &); double get_authorized_delta() {return max_delta_t;} void update_upd(int); CORBA::Any *get_last_cmd_result(); Tango::AttributeValue &get_last_attr_value(bool); Tango::AttributeValue_3 &get_last_attr_value_3(bool); Tango::AttributeValue_4 &get_last_attr_value_4(bool); Tango::AttributeValue_5 &get_last_attr_value_5(bool); bool is_ring_empty() {omni_mutex_lock sync(*this);return is_ring_empty_i();} bool is_ring_empty_i() {return ring.is_empty();} long get_upd() {omni_mutex_lock sync(*this);return get_upd_i();} long get_upd_i() {return ((upd.tv_sec * 1000) + (upd.tv_usec / 1000));} string &get_name() {omni_mutex_lock sync(*this);return get_name_i();} string &get_name_i() {return name;} inline double get_needed_time() {omni_mutex_lock sync(*this);return get_needed_time_i();} inline double get_needed_time_i() { return ((needed_time.tv_sec * 1000) + (needed_time.tv_usec / 1000.0)); } inline PollObjType get_type() {omni_mutex_lock sync(*this);return get_type_i();} inline PollObjType get_type_i() {return type;} double get_last_insert_date() {omni_mutex_lock sync(*this);return get_last_insert_date_i();} double get_last_insert_date_i(); bool is_last_an_error() {omni_mutex_lock sync(*this);return is_last_an_error_i();} bool is_last_an_error_i() {return ring.is_last_an_error();} bool is_last_an_error_i_3() {if (type==POLL_CMD)return ring.is_last_cmd_an_error();else return ring.is_last_attr_an_error();} Tango::DevFailed *get_last_except() {omni_mutex_lock sync(*this);return get_last_except_i();} Tango::DevFailed *get_last_except_i() {return ring.get_last_except();} Tango::DevErrorList &get_last_attr_error_i() {return ring.get_last_attr_error();} void get_delta_t(vector &vd, long nb) {omni_mutex_lock sync(*this);get_delta_t_i(vd,nb);} void get_delta_t_i(vector &vd,long nb) {ring.get_delta_t(vd,nb);} long get_elt_nb_in_buffer() {omni_mutex_lock sync(*this);return get_elt_nb_in_buffer_i();} long get_elt_nb_in_buffer_i() {return ring.get_nb_elt();} void get_cmd_history(long,Tango::DevCmdHistoryList *); void get_cmd_history(long,Tango::DevCmdHistory_4 *,Tango::CmdArgType &); void get_attr_history(long,Tango::DevAttrHistoryList *,long); void get_attr_history(long,Tango::DevAttrHistoryList_3 *,long); void get_attr_history(long,Tango::DevAttrHistory_4 *,long,AttrDataFormat); void get_attr_history(long,Tango::DevAttrHistory_5 *,long,AttrDataFormat); void get_attr_history_43(long n,Tango::DevAttrHistoryList_3 *ptr,long type); bool is_fwd_att() {return fwd;} protected: DeviceImpl *dev; PollObjType type; string name; struct timeval upd; struct timeval needed_time; double max_delta_t; PollRing ring; bool fwd; }; inline bool operator<(const PollObj &,const PollObj &) { return true; } inline bool operator==(const PollObj &,const PollObj &) { return true; } } // End of Tango namespace #endif /* _POLLOBJ_ */ tango-9.2.5a/lib/cpp/server/pollring.h0000644023471100065110000001473213034745002014570 00000000000000//==================================================================================================================== // // file : PollRing.h // // description : Include for the PollRing object. This class implements the polling ring buffer. // Command result or attribute values are stored in this buffer manages as a ring // buffer. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //==================================================================================================================== #ifndef _POLLRING_H #define _POLLRING_H #include namespace Tango { //=================================================================================================================== // // The RingElt class // // description : // Class to store all the necessary information which will be stored and returned to client on request // //=================================================================================================================== class RingElt { public: RingElt(); CORBA::Any *cmd_result; Tango::AttributeValueList *attr_value; Tango::AttributeValueList_3 *attr_value_3; Tango::AttributeValueList_4 *attr_value_4; Tango::AttributeValueList_5 *attr_value_5; Tango::DevFailed *except; struct timeval when; }; inline bool operator<(const RingElt &,const RingElt &) { return true; } inline bool operator==(const RingElt &,const RingElt &) { return true; } //=================================================================================================================== // // The PollRing class // // description : // Class to implement the ring buffer itself. This is mainly a vector of RingElt managed as a circular buffer // //================================================================================================================== class PollRing { public: PollRing(); PollRing(long); ~PollRing(); void insert_data(CORBA::Any *,struct timeval &); void insert_data(Tango::AttributeValueList *,struct timeval &); void insert_data(Tango::AttributeValueList_3 *,struct timeval &); void insert_data(Tango::AttributeValueList_4 *,struct timeval &,bool); void insert_data(Tango::AttributeValueList_5 *,struct timeval &,bool); void insert_except(Tango::DevFailed *,struct timeval &); template void force_copy_data(T *); void get_delta_t(vector &,long nb); struct timeval get_last_insert_date(); bool is_empty() {if (nb_elt == 0) return true;else return false;} bool is_last_an_error(); bool is_last_cmd_an_error(); bool is_last_attr_an_error(); Tango::DevFailed *get_last_except(); Tango::DevErrorList &get_last_attr_error(); CORBA::Any *get_last_cmd_result(); Tango::AttributeValue &get_last_attr_value(); Tango::AttributeValue_3 &get_last_attr_value_3(); Tango::AttributeValue_4 &get_last_attr_value_4(); Tango::AttributeValue_5 &get_last_attr_value_5(); long get_nb_elt() {return nb_elt;} void get_cmd_history(long,Tango::DevCmdHistoryList *); void get_cmd_history(long,Tango::DevCmdHistory_4 *,Tango::CmdArgType &); void get_attr_history(long,Tango::DevAttrHistoryList *,long); void get_attr_history(long,Tango::DevAttrHistoryList_3 *,long); template void get_attr_history(long,T *,long); void get_attr_history_43(long,Tango::DevAttrHistoryList_3 *,long); private: void inc_indexes(); vector ring; long insert_elt; long nb_elt; long max_elt; }; #define ADD_ELT_DATA_TO_GLOBAL_SEQ(GLOB,ELT,IND) \ {\ unsigned int elt_data_length = ELT->length(); \ for (unsigned int k = 0;k < elt_data_length;k++) \ (*GLOB)[IND + k] = (*ELT)[k]; \ IND = IND + elt_data_length; \ } #define ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_REF(GLOB,ELT,IND) \ {\ unsigned int elt_data_length = ELT.length(); \ for (unsigned int k = 0;k < elt_data_length;k++) \ GLOB[IND + k] = ELT[k]; \ IND = IND + elt_data_length; \ } #define ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(GLOB,ELT,IND) \ {\ unsigned int elt_data_length = ELT.length(); \ for (unsigned int k = 0;k < elt_data_length;k++) \ (*GLOB)[IND + k] = ELT[k]; \ IND = IND + elt_data_length; \ } #define MANAGE_DIM_ARRAY(LENGTH) \ if (last_dim.dim_x == LENGTH) \ { \ ptr->dims_array[dims_length - 2].nb_elt++; \ } \ else \ { \ last_dim.dim_x = LENGTH; \ last_dim.dim_y = 0; \ ptr->dims.length(dims_length); \ ptr->dims[dims_length - 1] = last_dim; \ ptr->dims_array.length(dims_length); \ ptr->dims_array[dims_length - 1].start = n - (i + 1); \ ptr->dims_array[dims_length - 1].nb_elt = 1; \ dims_length++; \ } #define ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(GLOB,ELT,IND) \ (*GLOB)[IND] = ELT; \ IND = IND + 1; #define MANAGE_DIM_SIMPLE() \ if (last_dim.dim_x == 1) \ { \ ptr->dims_array[dims_length - 2].nb_elt++; \ } \ else \ { \ last_dim.dim_x = 1; \ last_dim.dim_y = 0; \ ptr->dims.length(dims_length); \ ptr->dims[dims_length - 1] = last_dim; \ ptr->dims_array.length(dims_length); \ ptr->dims_array[dims_length - 1].start = n - (i + 1); \ ptr->dims_array[dims_length - 1].nb_elt = 1; \ dims_length++; \ } #define MANAGE_DIM_ARRAY_SEQ(LENGTH_STR,LENGTH_NUM) \ if ((last_dim.dim_x == LENGTH_STR) && (last_dim.dim_y == LENGTH_NUM))\ { \ ptr->dims_array[dims_length - 2].nb_elt++; \ } \ else \ { \ last_dim.dim_x = LENGTH_STR; \ last_dim.dim_y = LENGTH_NUM; \ ptr->dims.length(dims_length); \ ptr->dims[dims_length - 1] = last_dim; \ ptr->dims_array.length(dims_length); \ ptr->dims_array[dims_length - 1].start = n - (i + 1); \ ptr->dims_array[dims_length - 1].nb_elt = 1; \ dims_length++; \ } } // End of Tango namespace #endif /* _POLLRING_ */ tango-9.2.5a/lib/cpp/server/pollthread.h0000644023471100065110000001256213034745001015076 00000000000000//============================================================================= // // file : PollThread.h // // description : Include for the PollThread object. This class implements // the polling thread // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 29812 $ // //============================================================================= #ifndef _POLLTHREAD_H #define _POLLTHREAD_H #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #endif namespace Tango { //============================================================================= // // The PollThCmd structure // // description : This structure is used to shared data between the polling // thread and the main thread. // //============================================================================= struct PollThCmd { bool cmd_pending; // The new command flag bool trigger; // The external trigger flag PollCmdCode cmd_code; // The command code DeviceImpl *dev; // The device pointer (servant) long index; // Index in the device poll_list string name; // Object name PollObjType type; // Object type (cmd/attr) int new_upd; // New update period (For upd period com.) }; struct WorkItem { DeviceImpl *dev; // The device pointer (servant) vector *poll_list; // The device poll list struct timeval wake_up_date; // The next wake up date int update; // The update period (mS) PollObjType type; // Object type (command/attr) vector name; // Object name(s) struct timeval needed_time; // Time needed to execute action }; enum PollCmdType { POLL_TIME_OUT, POLL_COMMAND, POLL_TRIGGER }; //============================================================================= // // The PollThread class // // description : Class to store all the necessary information for the // polling thread. It's run() method is the thread code // //============================================================================= class TangoMonitor; class PollThread: public omni_thread { public: PollThread(PollThCmd &,TangoMonitor &,bool); void *run_undetached(void *); void start() {start_undetached();} void execute_cmd(); void set_local_cmd(PollThCmd &cmd) {local_cmd = cmd;} void set_polling_bef_9(bool _v) {polling_bef_9 = _v;} protected: PollCmdType get_command(long); void one_more_poll(); void one_more_trigg(); void compute_new_date(struct timeval &,int); void compute_sleep_time(); void time_diff(struct timeval &,struct timeval &,struct timeval &); void poll_cmd(WorkItem &); void poll_attr(WorkItem &); void eve_heartbeat(); void store_subdev(); void auto_unsub(); void print_list(); void insert_in_list(WorkItem &); void add_insert_in_list(WorkItem &); void tune_list(bool,long); void err_out_of_sync(WorkItem &); template void robb_data(T &,T &); template void copy_remaining(T &,T &); PollThCmd &shared_cmd; TangoMonitor &p_mon; list works; vector ext_trig_works; PollThCmd local_cmd; #ifdef _TG_WINDOWS_ struct _timeb now_win; struct _timeb after_win; double ctr_frequency; #endif struct timeval now; struct timeval after; long sleep; bool polling_stop; private: CORBA::Any in_any; DevVarStringArray attr_names; AttributeValue dummy_att; AttributeValue_3 dummy_att3; AttributeValue_4 dummy_att4; AttributeValue_5 dummy_att5; long tune_ctr; bool need_two_tuning; vector auto_upd; vector auto_name; vector rem_upd; vector rem_name; bool send_heartbeat; u_int heartbeat_ctr; u_int previous_nb_late; bool polling_bef_9; ClntIdent dummy_cl_id; CppClntIdent cci; public: static DeviceImpl *dev_to_del; static string name_to_del; static PollObjType type_to_del; }; // // Three macros // #define T_DIFF(A,B,C) \ long delta_sec = B.tv_sec - A.tv_sec; \ if (delta_sec == 0) \ C = B.tv_usec - A.tv_usec; \ else \ { \ C = ((delta_sec - 1) * 1000000) + (1000000 - A.tv_usec) + B.tv_usec; \ } #define T_ADD(A,B) \ A.tv_usec = A.tv_usec + B; \ while (A.tv_usec > 1000000) \ { \ A.tv_sec++; \ A.tv_usec = A.tv_usec - 1000000; \ } #define T_DEC(A,B) \ A.tv_usec = A.tv_usec - B; \ if (A.tv_usec < 0) \ { \ A.tv_sec--; \ A.tv_usec = 1000000 + A.tv_usec; \ } } // End of Tango namespace #endif /* _POLLTHREAD_ */ tango-9.2.5a/lib/cpp/server/readers_writers_lock.h0000644023471100065110000001070413034745001017150 00000000000000// -*- Mode: C++; -*- // // ReadersWritersLock.h Author : Tristan Richardson (tjr) // Jens Meyer // Emmanuel Taurel // // Copyright (C) : 1997-1999 AT&T Laboratories Cambridge // 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef _ReadersWritersLock_h_ #define _ReadersWritersLock_h_ #include class ReadersWritersLock { public: omni_mutex mut; omni_condition cond; int n; // 0 means no-one active, > 0 means n readers, < 0 means writer // (-n times). int writerId; ReadersWritersLock(void) : cond(&mut), n(0), writerId(0), auto_self(NULL) {} void readerIn(void) { mut.lock(); // In the case of usage with another threading library, omni_thread::self() might // return a NULL pointer! int threadId = 0; omni_thread *th = omni_thread::self(); if ( th != NULL ) { threadId = th->id(); } if ((n < 0) && (writerId == threadId)) { // this thread already has lock as writer, simply decrement n n--; mut.unlock(); return; } while (n < 0) cond.wait(); n++; mut.unlock(); } void readerOut(void) { mut.lock(); if (n < 0) { // this thread already had lock as writer, simply increment n n++; mut.unlock(); return; } n--; if (n == 0) cond.signal(); mut.unlock(); } void writerIn(void) { mut.lock(); // In the case of usage with another threading library, omni_thread::self() might // return a NULL pointer! int threadId = 0; omni_thread *th = omni_thread::self(); if ( th != NULL ) { threadId = th->id(); } if ((n < 0) && (writerId == threadId)) { // this thread already has lock as writer, simply decrement n n--; mut.unlock(); return; } while (n != 0) cond.wait(); n--; // Now the writer lock was taken. // Make sure we get a correct thread ID // With the class ensure_self it should return always a thread ID. // Create the ensure_self object only for the thread which takes the writer lock! if (th == NULL) auto_self = new omni_thread::ensure_self(); writerId = omni_thread::self()->id(); mut.unlock(); } void writerOut(void) { mut.lock(); n++; if (n == 0) { // delete the dummy thread when it was created. if (auto_self != NULL) { delete auto_self; auto_self = NULL; } cond.broadcast(); // might as well wake up all readers } mut.unlock(); } private: // in the case of usage with another threading library, omni_thread::self() might // return a NULL pointer! // To avoid this problem we use the class ensure_self to get a dummy thread ID! // // The class ensure_self should be created on the stack. If created in // a thread without an associated omni_thread, it creates a dummy // thread which is released when the ensure_self object is deleted. omni_thread::ensure_self *auto_self; }; // // As an alternative to: // { // lock.readerIn(); // ..... // lock.readerOut(); // } // // you can use a single instance of the ReaderLock class: // // { // ReaderLock r(lock); // .... // } // // This has the advantage that lock.readerOut() will be called automatically // when an exception is thrown. // class ReaderLock { ReadersWritersLock& rwl; public: ReaderLock(ReadersWritersLock& l) : rwl(l) { rwl.readerIn(); } ~ReaderLock(void) { rwl.readerOut(); } }; // // Similarly the WriterLock class can be used instead of lock.writerIn() and // lock.writerOut(). // class WriterLock { ReadersWritersLock& rwl; public: WriterLock(ReadersWritersLock& l) : rwl(l) { rwl.writerIn(); } ~WriterLock(void) { rwl.writerOut(); } }; #endif tango-9.2.5a/lib/cpp/server/rootattreg.h0000644023471100065110000001103313034745001015122 00000000000000//=================================================================================================================== // // file : rootattreg.h // // description : Include file for the RootAttRegistry and RootAttConfCallBack classes hierarchy. // These classes are used for the forwarded attribute feature // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28373 $ // //=================================================================================================================== #ifndef _ROOTATTREG_H #define _ROOTATTREG_H #include namespace Tango { struct NameFwdAttr { string local_name; // Local device name string local_att_name; // Local attribute name string local_label; // Local attribute label FwdAttr *fwd_attr; FwdAttr *fwd_attr_cl; }; struct UserEvent { EventType event_type; // Event type int event_id; // }; class RootAttRegistry { public: RootAttRegistry():cbp(this),cbu(this) {} void add_root_att(string &,string &,string &,string &,FwdAttr *,DeviceImpl *); void remove_root_att(string &,string &); DeviceProxy *get_root_att_dp(string &); DeviceImpl *get_local_dev(string &_s) {return cbp.get_local_dev(_s);} string get_local_att_name(const string &_s) {return cbp.get_local_att_name(_s);} void update_label(string &_d,string &_a,string &_l) {string s(_d+'/'+_a);cbp.update_label(s,_l);} void update_device_impl(string &_n,DeviceImpl *_d) {cbp.update_device_impl(_n,_d);} void clear_attrdesc(string &,string &); bool check_root_dev_release(string &); bool is_event_subscribed(string &,EventType); void subscribe_user_event(string &,string &,EventType); void unsubscribe_user_event(string &,string &,EventType); void auto_unsub(); bool is_root_attribute(string &_s) {return cbp.is_root_att_in_map(_s);} bool empty() {return dps.empty();} bool is_root_dev_not_started_err() {return cbp.is_root_dev_not_started_err();} protected: bool check_loop(string &,string &,string &,string &); private: class RootAttConfCallBack: public Tango::CallBack { public: RootAttConfCallBack(RootAttRegistry *_r):Tango::CallBack(),rar(_r) {ci.cpp_clnt(0);} virtual void push_event(Tango::AttrConfEventData *); void add_att(string &,string &,string &,FwdAttr *,DeviceImpl *); void remove_att(string &); void clear_attrdesc(string &); bool is_root_att_in_map(string &); int count_root_dev(string &); string get_local_att_name(const string &); DeviceImpl *get_local_dev(string &); void update_label(string &,string &); void update_device_impl(string &,DeviceImpl *); void update_err_kind(string &,FwdAttError); void device_restarting(string &); bool is_root_dev_not_started_err(); private: ClntIdent ci; omni_mutex the_lock; map map_attrdesc; // Key is root attribute device_name/att_name map local_dis; // Key is local device name RootAttRegistry *rar; }; class RootAttUserCallBack: public Tango::CallBack { public: RootAttUserCallBack(RootAttRegistry *_r):Tango::CallBack(),rar(_r) {} virtual void push_event(Tango::EventData *); virtual void push_event(Tango::DataReadyEventData *); private: RootAttRegistry *rar; vector dummy_vs; vector dummy_vd; vector dummy_vl; }; map dps; // Key is root attribute device name map map_event_id; // Key is root attribute device_name/att_name map > map_event_id_user; // Key is root attribute device name/att_name ReadersWritersLock id_user_lock; RootAttConfCallBack cbp; RootAttUserCallBack cbu; }; } // End of Tango namespace #endif /* _ROOTATTREG_H */ tango-9.2.5a/lib/cpp/server/seqvec.h0000644023471100065110000004447213034745001014233 00000000000000//============================================================================= // // file : SeqVec.h // // description : Include for the utilities function to ease CORBA // sequences from standard C++ vector or in the // oposite way. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // //============================================================================= #ifndef _SECVEC_H #define _SECVEC_H #include namespace Tango { // // These functions are not defined within the tango namespace because the VC++ // is not able to understand that the operator overloading functions is defined // within a namespace x from the operand namespace (c++ or aCC is able to // do it) // //============================================================================= // // Operator for the unsigned char array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarCharArray) and C++ vectors // //============================================================================= //#define NOSPACEINDOC_SEQVEC /** @defgroup Ope Operator overloading functions * Overloading of the << operator between C++ vector and Tango types */ //@{ /** * * Init a DevVarCharArray from a C++ vector of char(s). * * @param lval The DevVarCharArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarCharArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of char from a DevVarCharArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarCharArray */ inline void operator<<(vector &lval,const DevVarCharArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Short array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarShortArray) and C++ vectors // //============================================================================= /** * Init a DevVarShortArray from a C++ vector of short(s). * * @param lval The DevVarShortArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarShortArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of short from a DevVarShortArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarShortArray */ inline void operator<<(vector &lval,const DevVarShortArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Long array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarLongArray) and C++ vectors // //============================================================================= /** * Init a DevVarLongArray from a C++ vector of DevLong(s). * * @param lval The DevVarLongArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarLongArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of DevLong from a DevVarLongArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarLongArray */ inline void operator<<(vector &lval,const DevVarLongArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Long Long array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarLong64Array) and C++ vectors // //============================================================================= /** * Init a DevVarLongArray from a C++ vector of DevLong64(s). * * @param lval The DevVarLong64Array to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarLong64Array &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarLong64Array. * * @param lval The C++ vector to be initialised * @param rval The DevVarLong64Array */ inline void operator<<(vector &lval,const DevVarLong64Array &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Float array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarLongArray) and C++ vectors // //============================================================================= /** * Init a DevVarFloatArray from a C++ vector of float(s). * * @param lval The DevVarFloatArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarFloatArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarFloatArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarFloatArray */ inline void operator<<(vector &lval,const DevVarFloatArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Double array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarDoubleArray) and C++ vectors // //============================================================================= /** * Init a DevVarDoubleArray from a C++ vector of double(s). * * @param lval The DevVarDoubleArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarDoubleArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarDoubleArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarDoubleArray */ inline void operator<<(vector &lval,const DevVarDoubleArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Boolean array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarBooleanArray) and C++ vectors // //============================================================================= /** * Init a DevVarBooleanArray from a C++ vector of bool(s). * * @param lval The DevVarBooleanArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarBooleanArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarBooleanArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarBooleanArray */ inline void operator<<(vector &lval,const DevVarBooleanArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Unsigned short array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarUShortArray) and C++ vectors // //============================================================================= /** * Init a DevVarUShortArray from a C++ vector of unsigned short(s). * * @param lval The DevVarUShortArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarUShortArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarUShortArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarUShortArray */ inline void operator<<(vector &lval,const DevVarUShortArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Unsigned long array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarUShortArray) and C++ vectors // //============================================================================= /** * Init a DevVarULongArray from a C++ vector of DevULong(s). * * @param lval The DevVarULongArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarULongArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarULongArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarULongArray */ inline void operator<<(vector &lval,const DevVarULongArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the Unsigned long long array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarULong64Array) and C++ vectors // //============================================================================= /** * Init a DevVarULong64Array from a C++ vector of DevULong64(s). * * @param lval The DevVarULong64Array to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarULong64Array &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarULong64Array. * * @param lval The C++ vector to be initialised * @param rval The DevVarULong64Array */ inline void operator<<(vector &lval,const DevVarULong64Array &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //============================================================================= // // Operator for the string array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarStringArray) and C++ vectors // //============================================================================= /** * Init a DevVarStringArray from a C++ vector of string(s). * * @param lval The DevVarStringArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarStringArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = CORBA::string_dup(rval[i].c_str()); } /** * Init a C++ vector of long from a DevVarStringArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarStringArray */ inline void operator<<(vector &lval,const DevVarStringArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); string str; for (long i = 0;i < nb_elt;i++) { str = rval[i]; lval.push_back(str); } } //============================================================================= // // Operator for the DevState array types // // description : These two operators allow simple insertion between // Tango sequence (DevVarStateArray) and C++ vectors // //============================================================================= /** * Init a DevVarStateArray from a C++ vector of state(s). * * @param lval The DevVarStateArray to be initialised * @param rval The C++ vector */ inline void operator<<(DevVarStateArray &lval,const vector &rval) { size_t nb_elt = rval.size(); lval.length((CORBA::ULong)nb_elt); for (unsigned long i = 0;i < nb_elt;i++) lval[i] = rval[i]; } /** * Init a C++ vector of long from a DevVarStateArray. * * @param lval The C++ vector to be initialised * @param rval The DevVarStateArray */ inline void operator<<(vector &lval,const DevVarStateArray &rval) { long nb_elt = rval.length(); if (lval.empty() == false) lval.clear(); for (long i = 0;i < nb_elt;i++) lval.push_back(rval[i]); } //@} //============================================================================= // // Print operator for sequence types // // description : These operators allow simple printing of sequences // //============================================================================= //#ifndef TANGO_HAS_LOG4TANGO /** @defgroup Eas Easy printing operator overloading functions * Overloading of the << operator between C++ ostream and some Tango types */ //@{ /** * Print a DevVarCharArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarCharArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarCharArray &rval); /** * Print a DevVarShortArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarShortArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarShortArray &rval); /** * Print a DevVarLongArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarLongArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarLongArray &rval); /** * Print a DevVarLong64Array. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarLong64Array sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarLong64Array &rval); /** * Print a DevVarFloatArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarFloatArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarFloatArray &rval); /** * Print a DevVarDoubleArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarDoubleArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarDoubleArray &rval); /** * Print a DevVarBooleanArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarBooleanArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarBooleanArray &rval); /** * Print a DevVarUShortArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarUShortArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarUShortArray &rval); /** * Print a DevVarULongArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarULongArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarULongArray &rval); /** * Print a DevVarULong64Array. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarULong64Array sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarULong64Array &rval); /** * Print a DevVarStringArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarStringArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarStringArray &rval); /** * Print a DevVarStateArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarStateArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarStateArray &rval); /** * Print a DevVarEncodedArray. * * One line is printed for each sequence element. * * @param lval The C++ stream used for printing * @param rval The DevVarEncodedArray sequence to be printed */ ostream &operator<<(ostream &lval,const DevVarEncodedArray &rval); //@} //#endif // TANGO_HAS_LOG4TANGO } // End of Tango namespace #endif /* _SECVEC_ */ tango-9.2.5a/lib/cpp/server/subdev_diag.h0000644023471100065110000000603413034745002015212 00000000000000//============================================================================= // // file : subdev_diag.h // // description : Collect information on all used sub devices // in a device server. // // project : TANGO // // author(s) : J.Meyer // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _SUBDEV_DIAG_H #define _SUBDEV_DIAG_H #include namespace Tango { class SubDevDiag { private: // Type definition and map to keep the // list of accessed sub devices in a device server. // List structure to store every device // and its sub devices. typedef struct sub_dev_list { bool modified; // was the list modified? vector sub_devices; // list of sub devices } SubDeviceList; // map and mutex to keep a list of sub devices per device map sub_device_map; omni_mutex sub_dev_map_mutex; // map to keep a list of sub devices per device as read from // the database cache map sub_device_startup_map; public: // Constructor SubDevDiag() {}; // destructor to free map data ~SubDevDiag(); // Set the device name that should be asscociated to a thread // in the device server void set_associated_device(string dev_name); // Get the device name that is asscociated // with the current thread of the device server string get_associated_device(); // Register a sub device for an associated device // in the list of sub devices of the device server void register_sub_device (string dev_name, string sub_dev_name); // Remove all sub devices for a device of the server void remove_sub_devices (string dev_name); // Remove all sub devices void remove_sub_devices(); // Read the list of registered sub devices Tango::DevVarStringArray *get_sub_devices(); // Store the list of sub devices when modified into the database void store_sub_devices(); // Store the list sub devices at server start-up from the DB cache. void get_sub_devices_from_cache(); }; } // End of Tango namespace #endif /* SUBDEV_DIAG */ tango-9.2.5a/lib/cpp/server/tango.h0000644023471100065110000000634613034745001014053 00000000000000//==================================================================================================================== // // file : Tango.h // // description : Main include for Tango device server // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29692 $ // //=================================================================================================================== #ifndef _TANGO_H #define _TANGO_H // // Include the Tango config file // #include // // Include IDL generated files which includes CORBA include files // #include // // Some Windows specific include (necessary when used with MFC) // #ifdef _TG_WINDOWS_ #if (_WIN32_WINNT >= 0x0400) #include #include #else #include #endif #endif // // Include stream header files // #include #include #include // // Include some stdc++ library headers // #include #include #include #include #include // // Include API files (device and database) // #include #include #include #include #include #include #include // // Include Tango utility files // #include #include #include #include #if !defined(TANGO_CLIENT) && defined TANGO_HAS_LOG4TANGO #include #endif // // Include Tango files in order to simplfy device server developer include // file list // #ifndef TANGO_CLIENT #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #include // // minor is also defined (Linux) in sysmacros.h. We want the compiler to // use the SystemException::minor() method !! // #ifdef minor # undef minor #endif // // Default std namespace // using namespace std; #endif /* TANGO_H */ tango-9.2.5a/lib/cpp/server/tango_config.h0000644023471100065110000002043113034745002015370 00000000000000 //=================================================================================================================== // // file : Tango_config.h // // description : Include file where all the system dependant types are defined. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28447 $ // //=================================================================================================================== #ifndef _TANGO_CONFIG_H #define _TANGO_CONFIG_H // // Add some define for Win32 and omniORB // !!!!!!!!!! In some cases, VC++ wizard generates Stdafx.h file which include // windows.h file as their first include. Stdafx.h file is the first // file which should be in included by the include files list. Therefore, in // this case, it is not possible to define anything before windows.h file is // included (except by modying stdafx.h file by hand...). In order to include // Windows socket release 2 software, _WIN32_WINNT must be defined and set // to something >= 0x0400. Therefore, in this case, define it in the project // setting in the preprocessor definitions.... // // Windows: // The Windows VC compilers family defined _WIN32 (always) and _WIN64 // (when compiled as 64 bits) // The Windows windef.h include file defines the preprocessor WIN32 on top of the // _WIN32 one defined by the compiler itself. // // This means that on Windows 64 bits, we will have BOTH // _WIN32 // WIN32 // _WIN64 // // Within Tango, Windows include files are included by the "idl/tango.h" include file // included by tango.h after this file // #ifdef _WIN32 #define __WIN32__ #define __x86__ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif #define __NT__ #define __OSVERSION 4 #endif // // Check Win32 VC release // #ifdef _WIN32 #ifdef _MSC_VER #if ((_MSC_VER >= 1400) && (_MSC_VER < 1500)) #define WIN32_VC8 #elif ((_MSC_VER >= 1500) && (_MSC_VER < 1600)) #define WIN32_VC9 #elif ((_MSC_VER >= 1600) && (_MSC_VER < 1700)) #define WIN32_VC10 #elif ((_MSC_VER >= 1700) && (_MSC_VER < 1800)) #define WIN32_VC11 #elif (_MSC_VER >= 1800) #define WIN32_VC12 #endif // VC8+/VC9/VC10/VC11/VC12 #endif #endif // // Define a common preprocessor macros for all Windows (32 or 64 bits) // #ifdef _WIN32 #define _TG_WINDOWS_ #endif // // For Windows DLL (import and export nightmare) // #ifdef _TG_WINDOWS_ #if ((defined _USRDLL) || (defined TANGO_HAS_DLL)) #if (defined _TANGO_LIB) #define TANGO_IMP_EXP __declspec(dllexport) #define TANGO_IMP #else #define TANGO_IMP_EXP __declspec(dllimport) #define TANGO_IMP __declspec(dllimport) #endif #else #define TANGO_IMP_EXP #define TANGO_IMP #endif #else #define TANGO_IMP_EXP #define TANGO_IMP #endif /* _WINDOWS_ */ // // Check GCC release // #ifndef _TG_WINDOWS_ #if __GNUC__ < 3 #error "Gcc too old to use Tango!" #endif #endif // // Some C++11 feature // Unique_ptr -> gcc 4.3 // rvalues -> gcc 4.3 // Lambda function -> gcc 4.5 // nullptr -> gcc 4.6 // #ifndef _TG_WINDOWS_ #if defined(__GNUC__) #if __GNUC__ == 4 #if __GNUC_MINOR__ > 3 #define HAS_UNIQUE_PTR #define HAS_RVALUE #define HAS_THREAD #define HAS_TYPE_TRAITS #define HAS_VARIADIC_TEMPLATE #endif #if __GNUC_MINOR__ > 4 #define HAS_LAMBDA_FUNC #define HAS_ISNAN_IN_STD #endif #if __GNUC_MINOR__ > 5 #define HAS_NULLPTR #define HAS_RANGE_BASE_FOR #define INIT_LIST #endif #if __GNUC_MINOR__ > 7 #define HAS_UNDERLYING #endif #elif __GNUC__ > 4 #define HAS_UNIQUE_PTR #define HAS_RVALUE #define HAS_LAMBDA_FUNC #define HAS_ISNAN_IN_STD #define HAS_NULLPTR #define HAS_RANGE_BASE_FOR #define INIT_LIST #define HAS_THREAD #define HAS_TYPE_TRAITS #define HAS_UNDERLYING #define HAS_VARIADIC_TEMPLATE #endif #endif #else #ifdef WIN32_VC10 #define HAS_UNIQUE_PTR #define HAS_LAMBDA_FUNC #define HAS_NULLPTR #define HAS_RVALUE #define HAS_TYPE_TRAITS #endif #ifdef WIN32_VC11 #define HAS_UNIQUE_PTR #define HAS_LAMBDA_FUNC #define HAS_NULLPTR #define HAS_RVALUE #define HAS_RANGE_BASE_FOR #define HAS_TYPE_TRAITS #define HAS_UNDERLYING #endif #ifdef WIN32_VC12 #define HAS_UNIQUE_PTR #define HAS_LAMBDA_FUNC #define HAS_NULLPTR #define HAS_RVALUE #define HAS_RANGE_BASE_FOR #define HAS_TYPE_TRAITS #define HAS_UNDERLYING #define HAS_VARIADIC_TEMPLATE #endif #endif // // For gcc 5 new ABI // #ifdef _GLIBCXX_USE_CXX11_ABI #define TANGO_CXX11_ABI __attribute((abi_tag("cxx11"))) #else #define TANGO_CXX11_ABI #endif // // Some helper define // #define TangoSys_OMemStream ostringstream #define TangoSys_MemStream stringstream #define TangoSys_Pid int #define TangoSys_Cout ostream // // For Microsoft compilers // #ifdef _TG_WINDOWS_ #pragma warning(disable : 4355) #pragma warning(disable : 4715) #pragma warning(disable : 4786) #if (_MSC_VER >= 1400) // VC8+ #pragma warning(disable : 4996) // disable all deprecation warnings #endif // VC8+ #endif // // Define a common isnan call // #ifndef _TG_WINDOWS_ #ifdef HAS_ISNAN_IN_STD #define Tango_isnan(A) std::isnan(A) #else #define Tango_isnan(A) isnan(A) #endif #else #define Tango_isnan(A) _isnan(A) #endif // // Define a common NULL constant // #ifdef HAS_NULLPTR #define Tango_nullptr nullptr #else #define Tango_nullptr NULL #endif // // Define a common sleep call // #ifndef _TG_WINDOWS_ #define Tango_sleep(A) sleep(A) #else #define Tango_sleep(A) Sleep(A * 1000) #endif // // Define a time_t to long casting // #ifndef _TG_WINDOWS_ #define time_t_2_long(A) A #else #define time_t_2_long(A) (long)A #endif // // Define a common strcasecmp function // #ifndef _TG_WINDOWS_ #define TG_strcasecmp ::strcasecmp #define TG_strncasecmp ::strncasecmp #else #define TG_strcasecmp ::stricmp #define TG_strncasecmp ::strnicmp #endif // // ACTIVATE (or DEACTIVATE) THE TANGO LOGGING MECHANISM // #define TANGO_HAS_LOG4TANGO // // USE DSERVER'S LOGGER TO LOG TANGO CORE MESSAGES (cout1..4) // #define TANGO_HAS_CORE_LOGGER // // Define a macro for unused parameter warning // #ifdef _TG_WINDOWS_ #define TANGO_UNUSED(var) var #else #if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #elif __GNUC__ > 3 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #else #define TANGO_UNUSED(var) var #endif #endif // // Is it a 32 or 64 bits computer // #ifndef _TG_WINDOWS_ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #if SIZEOF_LONG == 8 #define TANGO_LONG64 #else #define TANGO_LONG32 #endif #else #define TANGO_LONG32 #endif #endif /* _TANGO_CONFIG_H */ tango-9.2.5a/lib/cpp/server/tango_const.h0000644023471100065110000015633713034745001015267 00000000000000//==================================================================================================================== // // file : Tango_const.h // // description : Include for Tango system constant definition // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29799 $ // //===================================================================================================================== #ifndef _TANGO_CONST_H #define _TANGO_CONST_H namespace Tango { // // Some general interest define // #define TANGO_VERSION_MAJOR 9 #define TANGO_VERSION_MINOR 2 #define TANGO_VERSION_PATCH 5 #define TANGO_BASE_CLASS Tango::Device_5Impl #define TBS(s) #s #define XTBS(s) TBS(s) const char * const TgLibVers = XTBS(TANGO_VERSION_MAJOR.TANGO_VERSION_MINOR.TANGO_VERSION_PATCH); const char * const TgLibMajorVers = XTBS(TANGO_VERSION_MAJOR); const int TgLibVersNb = TANGO_VERSION_MAJOR*10000 + TANGO_VERSION_MINOR*100 + TANGO_VERSION_PATCH; const int DevVersion = 5; // IDL version number const int DefaultMaxSeq = 20; const int DefaultBlackBoxDepth = 50; const int DefaultPollRingDepth = 10; const char* const InitialOutput = "Initial Output"; const char* const DSDeviceDomain = "dserver"; const char* const DefaultDocUrl = "http://www.tango-controls.org"; const char* const EnvVariable = "TANGO_HOST"; const char* const WindowsEnvVariable = "TANGO_ROOT"; const char* const DbObjName = "database"; const char* const NotSet = "Uninitialised"; const char* const ResNotDefined = "0"; const char* const MessBoxTitle = "Tango Device Server"; const char* const StatusNotSet = "Not initialised"; const char* const TangoHostNotSet = "Undef"; const char* const RootAttNotDef = "Not defined"; const bool DefaultWritAttrProp = false; const char* const AllAttr = "All attributes"; const char* const AllAttr_3 = "All attributes_3"; const char* const AllPipe = "All pipes"; const char* const AllCmd = "All commands"; const char* const PollCommand = "command"; const char* const PollAttribute = "attribute"; const char* const LOCAL_POLL_REQUEST = "_local"; const int LOCAL_REQUEST_STR_SIZE = 6; const int MIN_POLL_PERIOD = 5; const int DELTA_T = 1002000000; const int MIN_DELTA_WORK = 20000; const int TIME_HEARTBEAT = 2000; const int POLL_LOOP_NB = 500; const int ONE_SECOND = 1000000; const double DISCARD_THRESHOLD = 0.02; const int DEFAULT_TIMEOUT = 3200; const int DEFAULT_POLL_OLD_FACTOR = 4; const int TG_IMP_MINOR_TO = 10; const int TG_IMP_MINOR_DEVFAILED = 11; const int TG_IMP_MINOR_NON_DEVFAILED = 12; const char* const TANGO_PY_MOD_NAME = "_PyTango.pyd"; const char* const DATABASE_CLASS = "DataBase"; const int TANGO_FLOAT_PRECISION = 15; const char * const NoClass = "noclass"; const char * const SCALAR_PIPE = "Scalar"; const char * const ARRAY_PIPE = "Array"; // // omniORB default configuration file // #ifdef _TG_WINDOWS_ const char* const DEFAULT_OMNI_CONF_FILE = "C:\\OMNIORB.CFG"; #else const char* const DEFAULT_OMNI_CONF_FILE = "/etc/omniORB.cfg"; #endif // // Event related define // const int EVENT_HEARTBEAT_PERIOD = 10; const int EVENT_RESUBSCRIBE_PERIOD = 600; const int DEFAULT_EVENT_PERIOD = 1000; const double DELTA_PERIODIC = 0.98; // Using a delta of 2% only for times < 5000 ms const int DELTA_PERIODIC_LONG = 100; // For times > 5000ms only keep a delta of 100ms const char* const HEARTBEAT = "Event heartbeat"; // // ZMQ event system related define // const int ZMQ_EVENT_PROT_VERSION = 1; const char* const HEARTBEAT_METHOD_NAME = "push_heartbeat_event"; const char* const EVENT_METHOD_NAME = "push_zmq_event"; const char* const HEARTBEAT_EVENT_NAME = "heartbeat"; const char* const CTRL_SOCK_ENDPOINT = "inproc://control"; const char* const MCAST_PROT = "epgm://"; const int MCAST_HOPS = 5; const int PGM_RATE = 80 * 1024; const int PGM_IVL = 20 * 1000; const int MAX_SOCKET_SUB = 10; const int PUB_HWM = 1000; const int SUB_HWM = 1000; const int SUB_SEND_HWM = 10000; // // Event when using a file as database stuff // const char* const NOTIFD_CHANNEL = "notifd_channel"; // // Locking feature related defines // const int DEFAULT_LOCK_VALIDITY = 10; const char* const DEVICE_UNLOCKED_REASON = "API_DeviceUnlocked"; const int MIN_LOCK_VALIDITY = 2; const char* const TG_LOCAL_HOST = "localhost"; // // Client timeout as defined by omniORB4.0.0 // const char* const CLNT_TIMEOUT_STR = "3000"; const int CLNT_TIMEOUT = 3000; const int NARROW_CLNT_TIMEOUT = 100; // // Connection and call timeout for database device // const int DB_CONNECT_TIMEOUT = 25000; const int DB_RECONNECT_TIMEOUT = 20000; const int DB_TIMEOUT = 13000; const int DB_START_PHASE_RETRIES = 3; // // Time to wait before trying to reconnect after // a connevtion failure // const int RECONNECTION_DELAY = 1000; //ms. Only try to reconnect every second // // Access Control related defines // WARNING: these string are also used within the Db stored procedure // introduced in Tango V6.1. If you chang eit here, don't forget to // also update the stored procedure // const char* const CONTROL_SYSTEM = "CtrlSystem"; const char* const SERVICE_PROP_NAME = "Services"; const char* const ACCESS_SERVICE = "AccessControl"; // // Polling threads pool related defines // const int DEFAULT_POLLING_THREADS_POOL_SIZE = 1; // // Max transfer size 256 MBytes (in byte). Needed by omniORB // const char* const MAX_TRANSFER_SIZE = "268435456"; // // Max GIOP connection per server . Needed by omniORB // const char* const MAX_GIOP_PER_SERVER = "128"; // // Tango name length // const unsigned int MaxServerNameLength = 255; const int MaxDevPropLength = 255; // // For forwarded attribute implementation // const int MIN_IDL_CONF5 = 5; const int MIN_IDL_DEV_INTR = 5; const int ALL_EVENTS = 0; // // For event compatibility // const int ATT_CONF_REL_NB = 1; // Number of att. conf release on top of original one const char* const EVENT_COMPAT = "idl"; const char* const EVENT_COMPAT_IDL5 = "idl5_"; const int EVENT_COMPAT_IDL5_SIZE = 5; // strlen of previsou string // // For device interface change event // const int DEV_INTR_THREAD_SLEEP_TIME = 50; // // For pipe // const int MAX_DATA_ELT_IN_PIPE_BLOB = 20; // // Files used to retrieve env. variables // const char* const USER_ENV_VAR_FILE = ".tangorc"; #ifndef HAVE_CONFIG_H const char* const TANGO_RC_FILE = "/etc/tangorc"; #endif const char* const WINDOWS_ENV_VAR_FILE = "tangorc"; #ifdef TANGO_HAS_LOG4TANGO // // Logging targets (as string) // const char* const kLogTargetConsole = "console"; const char* const kLogTargetFile = "file"; const char* const kLogTargetDevice = "device"; // // Logging target [type/name] separator // const char* const kLogTargetSep = "::"; // // TANGO threshold // // Min RollingFileAppender threshold (~500kB) const size_t kMinRollingThreshold = 500; // Default RollingFileAppender threshold (~20MB) const size_t kDefaultRollingThreshold = 20 * 1024; // Max RollingFileAppender threshold (~1GB) const size_t kMaxRollingThreshold = 1024 * 1024; #endif // TANGO_HAS_LOG4TANGO // // The optional attribute properties // const char* const AlrmValueNotSpec = "Not specified"; const char* const AssocWritNotSpec = "None"; const char* const LabelNotSpec = "No label"; const char* const DescNotSpec = "No description"; const char* const UnitNotSpec = ""; const char* const StdUnitNotSpec = "No standard unit"; const char* const DispUnitNotSpec = "No display unit"; const char* const FormatNotSpec_FL = "%6.2f"; const char* const FormatNotSpec_INT = "%d"; const char* const FormatNotSpec_STR = "%s"; const char* const FormatNotSpec = FormatNotSpec_FL; const char* const NotANumber = "NaN"; const char* const MemNotUsed = "Not used yet"; const char* const MemAttrPropName = "__value"; const char* const RootAttrPropName = "__root_att"; // For DevEnum data type typedef DevShort DevEnum; /* * List of strings used by the API as the DevError reason field. * This list is given here only for API writers to re-use (if possible) * strings already used. * */ const char* const API_AlreadyPolled = "API_AlreadyPolled"; const char* const API_AsynReplyNotArrived = "API_AsynReplyNotArrived"; const char* const API_AttrConfig = "API_AttrConfig"; const char* const API_AttrEventProp = "API_AttrEventProp"; const char* const API_AttributeFailed = "API_AttributeFailed"; const char* const API_AttributeNotDataReadyEnabled = "API_AttributeNotDataReadyEnabled"; const char* const API_AttributePollingNotStarted = "API_AttributePollingNotStarted"; const char* const API_AttrIncorrectDataNumber = "API_AttrIncorrectDataNumber"; const char* const API_AttrNoAlarm = "API_AttrNoAlarm"; const char* const API_AttrNotAllowed = "API_AttrNotAllowed"; const char* const API_AttrNotFound = "API_AttrNotFound"; const char* const API_AttrNotPolled = "API_AttrNotPolled"; const char* const API_AttrNotWritable = "API_AttrNotWritable"; const char* const API_AttrOptProp = "API_AttrOptProp"; const char* const API_AttrPropValueNotSet = "API_AttrPropValueNotSet"; const char* const API_AttrValueNotSet = "API_AttrValueNotSet"; const char* const API_AttrWrongDefined = "API_AttrWrongDefined"; const char* const API_AttrWrongMemValue = "API_AttrWrongMemValue"; const char* const API_BadAsynReqType = "API_BadAsynReqType"; const char* const API_BadConfigurationProperty = "API_BadConfigurationProperty"; const char* const API_BlackBoxArgument = "API_BlackBoxArgument"; const char* const API_BlackBoxEmpty = "API_BlackBoxEmpty"; const char* const API_CannotCheckAccessControl = "API_CannotCheckAccessControl"; const char* const API_CannotOpenFile = "API_CannotOpenFile"; const char* const API_CantActivatePOAManager = "API_CantActivatePOAManager"; const char* const API_CantConnectToDevice = "API_CantConnectToDevice"; const char* const API_CantCreateClassPoa = "API_CantCreateClassPoa"; const char* const API_CantCreateLockingThread = "API_CantCreateLockingThread"; const char* const API_CantDestroyDevice = "API_CantDestroyDevice"; const char* const API_CantFindLockingThread = "API_CantFindLockingThread"; const char* const API_CantGetClientIdent = "API_CantGetClientIdent"; const char* const API_CantGetDevObjectId = "API_CantGetDevObjectId"; const char* const API_CantInstallSignal = "API_CantInstallSignal"; const char* const API_CantRetrieveClass = "API_CantRetrieveClass"; const char* const API_CantRetrieveClassList = "API_CantRetrieveClassList"; const char* const API_CantStoreDeviceClass = "API_CantStoreDeviceClass"; const char* const API_ClassNotFound = "API_ClassNotFound"; const char* const API_CmdArgumentTypeNotSupported = "API_CmdArgumentTypeNotSupported"; const char* const API_CmdNotPolled = "API_CmdNotPolled"; const char* const API_CommandFailed = "API_CommandFailed"; const char* const API_CommandNotAllowed = "API_CommandNotAllowed"; const char* const API_CommandNotFound = "API_CommandNotFound"; const char* const API_CommandTimedOut = "API_CommandTimedOut"; const char* const API_ConnectionFailed = "API_ConnectionFailed"; const char* const API_CorbaSysException = "API_CorbaSysException"; const char* const API_CorruptedDatabase = "API_CorruptedDatabase"; const char* const API_DatabaseAccess = "API_DatabaseAccess"; const char* const API_DatabaseCacheAccess = "API_DatabaseCacheAccess"; const char* const API_DatabaseFileError = "API_DatabaseFileError"; const char* const API_DecodeErr = "API_DecodeErr"; const char* const API_DeprecatedCommand = "API_DeprecatedCommand"; const char* const API_DeviceLocked = "API_DeviceLocked"; const char* const API_DeviceNotExported = "API_DeviceNotExported"; const char* const API_DeviceNotFound = "API_DeviceNotFound"; const char* const API_DeviceNotLocked = "API_DeviceNotLocked"; const char* const API_DeviceNotPolled = "API_DeviceNotPolled"; const char* const API_DeviceUnlockable = "API_DeviceUnlockable"; const char* const API_DeviceUnlocked = "API_DeviceUnlocked"; const char* const API_DServerClassNotInitialised = "API_DServerClassNotInitialised"; const char* const API_DSFailedRegisteringEvent = "API_DSFailedRegisteringEvent"; const char* const API_EmptyDataElement = "API_EmptyDataElement"; const char* const API_EmptyDeviceAttribute = "API_EmptyDeviceAttribute"; const char* const API_EventConsumer = "API_EventConsumer"; const char* const API_EventPropertiesNotSet = "API_EventPropertiesNotSet"; const char* const API_EventQueues = "API_EventQueues"; const char* const API_EventSupplierNotConstructed = "API_EventSupplierNotConstructed"; const char* const API_FwdAttrNotConfigured = "API_FwdAttrNotConfigured"; const char* const API_FwdAttrInconsistency = "API_FwdAttrInconsistency"; const char* const API_IncoherentDbData = "API_IncoherentDbData"; const char* const API_IncoherentDevData = "API_IncoherentDevData"; const char* const API_IncoherentValues = "API_IncoherentValues"; const char* const API_IncompatibleArgumentType = "API_IncompatibleArgumentType"; const char* const API_IncompatibleAttrDataType = "API_IncompatibleAttrDataType"; const char* const API_IncompatibleCmdArgumentType = "API_IncompatibleCmdArgumentType"; const char* const API_InitMethodNotFound = "API_InitMethodNotFound"; const char* const API_InitNotPublic = "API_InitNotPublic"; const char* const API_InitThrowsException = "API_InitThrowsException"; const char* const API_InternalError = "API_InternalError"; const char* const API_InvalidArgs = "API_InvalidArgs"; const char* const API_JavaRuntimeSecurityException = "API_JavaRuntimeSecurityException"; const char* const API_MemAttFailedDuringInit = "API_MemAttFailedDuringInit"; const char* const API_MemoryAllocation = "API_MemoryAllocation"; const char* const API_MethodArgument = "API_MethodArgument"; const char* const API_MethodNotFound = "API_MethodNotFound"; const char* const API_MissedEvents = "API_MissedEvents"; const char* const API_NoDataYet = "API_NoDataYet"; const char* const API_NonDatabaseDevice = "API_NonDatabaseDevice"; const char* const API_NotificationServiceFailed = "API_NotificationServiceFailed"; const char* const API_NotSupported = "API_NotSupported"; const char* const API_NotSupportedFeature = "API_NotSupportedFeature"; const char* const API_NotUpdatedAnyMore = "API_NotUpdatedAnyMore"; const char* const API_NtDebugWindowError = "API_NtDebugWindowError"; const char* const API_OverloadingNotSupported = "API_OverloadingNotSupported"; const char* const API_PipeDataEltNotFound = "API_PipeDataEltNotFound"; const char* const API_PipeDuplicateDEName = "API_PipeDuplicateDEName"; const char* const API_PipeFailed = "API_PipeFailed"; const char* const API_PipeNoDataElement = "API_PipeNoDataElement"; const char* const API_PipeNotAllowed = "API_PipeNotAllowed"; const char* const API_PipeNotFound = "API_PipeNotFound"; const char* const API_PipeNotWritable = "API_PipeNotWritable"; const char* const API_PipeOptProp = "API_PipeOptProp"; const char* const API_PipeValueNotSet = "API_PipeValueNotSet"; const char* const API_PipeWrongArgNumber = "API_PipeWrongArgNumber"; const char* const API_PipeWrongArg = "API_PipeWrongArg"; const char* const API_PolledDeviceNotInPoolConf = "API_PolledDeviceNotInPoolConf"; const char* const API_PolledDeviceNotInPoolMap = "API_PolledDeviceNotInPoolMap"; const char* const API_PollingThreadNotFound = "API_PollingThreadNotFound"; const char* const API_PollObjNotFound = "API_PollObjNotFound"; const char* const API_PollRingBufferEmpty = "API_PollRingBufferEmpty"; const char* const API_ReadOnlyMode = "API_ReadOnlyMode"; const char* const API_RootAttrFailed = "API_RootAttrFailed"; const char* const API_ShutdownInProgress = "API_ShutdownInProgress"; const char* const API_SignalOutOfRange = "API_SignalOutOfRange"; const char* const API_StartupSequence = "API_StartupSequence"; const char* const API_StdException = "API_StdException"; const char* const API_SystemCallFailed = "API_SystemCallFailed"; const char* const API_TangoHostNotSet = "API_TangoHostNotSet"; const char* const API_UnsupportedFeature = "API_UnsupportedFeature"; const char* const API_WAttrOutsideLimit = "API_WAttrOutsideLimit"; const char* const API_WizardConfError = "API_WizardConfError"; const char* const API_WrongAttributeNameSyntax = "API_WrongAttributeNameSyntax"; const char* const API_WrongCmdLineArgs = "API_WrongCmdLineArgs"; const char* const API_WrongDeviceNameSyntax = "API_WrongDeviceNameSyntax"; const char* const API_WrongEventData = "API_WrongEventData"; const char* const API_WrongFormat = "API_WrongFormat"; const char* const API_WrongHistoryDataBuffer = "API_WrongHistoryDataBuffer"; const char* const API_WrongLockingStatus = "API_WrongLockingStatus"; const char* const API_WrongNumberOfArgs = "API_WrongNumberOfArgs"; const char* const API_ZmqFailed = "API_ZmqFailed"; const char* const API_ZmqInitFailed = "API_ZmqInitFailed"; // // A short inline function to hide the CORBA::string_dup function // inline char * string_dup(char *s) {return CORBA::string_dup(s);} inline char * string_dup(const char *s) {return CORBA::string_dup(s);} // // Many, many typedef // typedef const char * ConstDevString; // Pseudo Tango type to ease POGO job typedef DevVarCharArray DevVarUCharArray; class DeviceImpl; typedef bool (DeviceImpl::*StateMethPtr)(const CORBA::Any &); typedef void (DeviceImpl::*CmdMethPtr)(); typedef void (DeviceImpl::*CmdMethPtr_Bo)(DevBoolean); typedef void (DeviceImpl::*CmdMethPtr_Sh)(DevShort); typedef void (DeviceImpl::*CmdMethPtr_Lg)(DevLong); typedef void (DeviceImpl::*CmdMethPtr_Fl)(DevFloat); typedef void (DeviceImpl::*CmdMethPtr_Db)(DevDouble); typedef void (DeviceImpl::*CmdMethPtr_US)(DevUShort); typedef void (DeviceImpl::*CmdMethPtr_UL)(DevULong); typedef void (DeviceImpl::*CmdMethPtr_Str)(DevString); typedef void (DeviceImpl::*CmdMethPtr_ChA)(const DevVarCharArray *); typedef void (DeviceImpl::*CmdMethPtr_ShA)(const DevVarShortArray *); typedef void (DeviceImpl::*CmdMethPtr_LgA)(const DevVarLongArray *); typedef void (DeviceImpl::*CmdMethPtr_FlA)(const DevVarFloatArray *); typedef void (DeviceImpl::*CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef void (DeviceImpl::*CmdMethPtr_USA)(const DevVarUShortArray *); typedef void (DeviceImpl::*CmdMethPtr_ULA)(const DevVarULongArray *); typedef void (DeviceImpl::*CmdMethPtr_StrA)(const DevVarStringArray *); typedef void (DeviceImpl::*CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef void (DeviceImpl::*CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef void (DeviceImpl::*CmdMethPtr_Sta)(DevState); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr)(); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr)(); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr)(); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr)(); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr)(); typedef DevUShort (DeviceImpl::*US_CmdMethPtr)(); typedef DevULong (DeviceImpl::*UL_CmdMethPtr)(); typedef DevString (DeviceImpl::*Str_CmdMethPtr)(); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr)(); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr)(); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr)(); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr)(); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr)(); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr)(); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr)(); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr)(); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr)(); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr)(); typedef DevState (DeviceImpl::*Sta_CmdMethPtr)(); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Bo)(DevBoolean); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Sh)(DevShort); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Lg)(DevLong); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Fl)(DevFloat); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Db)(DevDouble); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_US)(DevUShort); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_UL)(DevULong); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Str)(DevString); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevBoolean (DeviceImpl::*Bo_CmdMethPtr_Sta)(DevState); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Bo)(DevBoolean); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Sh)(DevShort); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Lg)(DevLong); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Fl)(DevFloat); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Db)(DevDouble); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_US)(DevUShort); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_UL)(DevULong); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Str)(DevString); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevShort (DeviceImpl::*Sh_CmdMethPtr_Sta)(DevState); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Bo)(DevBoolean); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Sh)(DevShort); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Lg)(DevLong); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Fl)(DevFloat); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Db)(DevDouble); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_US)(DevUShort); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_UL)(DevULong); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Str)(DevString); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevLong (DeviceImpl::*Lg_CmdMethPtr_Sta)(DevState); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Bo)(DevBoolean); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Sh)(DevShort); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Lg)(DevLong); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Fl)(DevFloat); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Db)(DevDouble); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_US)(DevUShort); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_UL)(DevULong); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Str)(DevString); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevFloat (DeviceImpl::*Fl_CmdMethPtr_Sta)(DevState); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Bo)(DevBoolean); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Sh)(DevShort); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Lg)(DevLong); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Fl)(DevFloat); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Db)(DevDouble); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_US)(DevUShort); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_UL)(DevULong); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Str)(DevString); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevDouble (DeviceImpl::*Db_CmdMethPtr_Sta)(DevState); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Bo)(DevBoolean); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Sh)(DevShort); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Lg)(DevLong); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Fl)(DevFloat); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Db)(DevDouble); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_US)(DevUShort); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_UL)(DevULong); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Str)(DevString); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevUShort (DeviceImpl::*US_CmdMethPtr_Sta)(DevState); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Bo)(DevBoolean); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Sh)(DevShort); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Lg)(DevLong); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Fl)(DevFloat); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Db)(DevDouble); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_US)(DevUShort); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_UL)(DevULong); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Str)(DevString); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevULong (DeviceImpl::*UL_CmdMethPtr_Sta)(DevState); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Bo)(DevBoolean); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Sh)(DevShort); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Lg)(DevLong); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Fl)(DevFloat); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Db)(DevDouble); typedef DevString (DeviceImpl::*Str_CmdMethPtr_US)(DevUShort); typedef DevString (DeviceImpl::*Str_CmdMethPtr_UL)(DevULong); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Str)(DevString); typedef DevString (DeviceImpl::*Str_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevString (DeviceImpl::*Str_CmdMethPtr_Sta)(DevState); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Sh)(DevShort); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Lg)(DevLong); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Fl)(DevFloat); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Db)(DevDouble); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_US)(DevUShort); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_UL)(DevULong); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Str)(DevString); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarCharArray *(DeviceImpl::*ChA_CmdMethPtr_Sta)(DevState); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Sh)(DevShort); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Lg)(DevLong); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Fl)(DevFloat); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Db)(DevDouble); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_US)(DevUShort); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_UL)(DevULong); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Str)(DevString); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarShortArray *(DeviceImpl::*ShA_CmdMethPtr_Sta)(DevState); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Sh)(DevShort); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Lg)(DevLong); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Fl)(DevFloat); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Db)(DevDouble); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_US)(DevUShort); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_UL)(DevULong); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Str)(DevString); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarLongArray *(DeviceImpl::*LgA_CmdMethPtr_Sta)(DevState); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Sh)(DevShort); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Lg)(DevLong); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Fl)(DevFloat); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Db)(DevDouble); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_US)(DevUShort); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_UL)(DevULong); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Str)(DevString); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarFloatArray *(DeviceImpl::*FlA_CmdMethPtr_Sta)(DevState); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Sh)(DevShort); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Lg)(DevLong); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Fl)(DevFloat); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Db)(DevDouble); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_US)(DevUShort); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_UL)(DevULong); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Str)(DevString); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarDoubleArray *(DeviceImpl::*DbA_CmdMethPtr_Sta)(DevState); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Sh)(DevShort); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Lg)(DevLong); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Fl)(DevFloat); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Db)(DevDouble); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_US)(DevUShort); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_UL)(DevULong); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Str)(DevString); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarUShortArray *(DeviceImpl::*USA_CmdMethPtr_Sta)(DevState); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Sh)(DevShort); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Lg)(DevLong); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Fl)(DevFloat); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Db)(DevDouble); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_US)(DevUShort); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_UL)(DevULong); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Str)(DevString); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarULongArray *(DeviceImpl::*ULA_CmdMethPtr_Sta)(DevState); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Sh)(DevShort); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Lg)(DevLong); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Fl)(DevFloat); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Db)(DevDouble); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_US)(DevUShort); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_UL)(DevULong); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Str)(DevString); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarStringArray *(DeviceImpl::*StrA_CmdMethPtr_Sta)(DevState); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Sh)(DevShort); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Lg)(DevLong); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Fl)(DevFloat); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Db)(DevDouble); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_US)(DevUShort); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_UL)(DevULong); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Str)(DevString); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarLongStringArray *(DeviceImpl::*LSA_CmdMethPtr_Sta)(DevState); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Bo)(DevBoolean); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Sh)(DevShort); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Lg)(DevLong); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Fl)(DevFloat); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Db)(DevDouble); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_US)(DevUShort); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_UL)(DevULong); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Str)(DevString); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevVarDoubleStringArray *(DeviceImpl::*DSA_CmdMethPtr_Sta)(DevState); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Bo)(DevBoolean); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Sh)(DevShort); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Lg)(DevLong); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Fl)(DevFloat); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Db)(DevDouble); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_US)(DevUShort); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_UL)(DevULong); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Str)(DevString); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_ChA)(const DevVarCharArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_ShA)(const DevVarShortArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_LgA)(const DevVarLongArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_FlA)(const DevVarFloatArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_DbA)(const DevVarDoubleArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_USA)(const DevVarUShortArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_ULA)(const DevVarULongArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_StrA)(const DevVarStringArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_LSA)(const DevVarLongStringArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_DSA)(const DevVarDoubleStringArray *); typedef DevState *(DeviceImpl::*Sta_CmdMethPtr_Sta)(DevState); // // Some enum and structures // enum CmdArgType { DEV_VOID = 0, DEV_BOOLEAN, DEV_SHORT, DEV_LONG, DEV_FLOAT, DEV_DOUBLE, DEV_USHORT, DEV_ULONG, DEV_STRING, DEVVAR_CHARARRAY, DEVVAR_SHORTARRAY, DEVVAR_LONGARRAY, DEVVAR_FLOATARRAY, DEVVAR_DOUBLEARRAY, DEVVAR_USHORTARRAY, DEVVAR_ULONGARRAY, DEVVAR_STRINGARRAY, DEVVAR_LONGSTRINGARRAY, DEVVAR_DOUBLESTRINGARRAY, DEV_STATE, CONST_DEV_STRING, DEVVAR_BOOLEANARRAY, DEV_UCHAR, DEV_LONG64, DEV_ULONG64, DEVVAR_LONG64ARRAY, DEVVAR_ULONG64ARRAY, DEV_INT, DEV_ENCODED, DEV_ENUM, DEV_PIPE_BLOB, DEVVAR_STATEARRAY, DATA_TYPE_UNKNOWN = 100 }; enum MessBoxType { STOP = 0, INFO }; enum PollObjType { POLL_CMD = 0, POLL_ATTR, EVENT_HEARTBEAT, STORE_SUBDEV }; enum PollCmdCode { POLL_ADD_OBJ = 0, POLL_REM_OBJ, POLL_START, POLL_STOP, POLL_UPD_PERIOD, POLL_REM_DEV, POLL_EXIT, POLL_REM_EXT_TRIG_OBJ, POLL_ADD_HEARTBEAT, POLL_REM_HEARTBEAT }; enum SerialModel { BY_DEVICE = 0, BY_CLASS, BY_PROCESS, NO_SYNC }; enum AttReqType { READ_REQ = 0, WRITE_REQ }; typedef AttReqType PipeReqType; enum LockCmdCode { LOCK_ADD_DEV = 0, LOCK_REM_DEV, LOCK_UNLOCK_ALL_EXIT, LOCK_EXIT }; // // The polled device structure // typedef struct _PollDevice { string dev_name; vector ind_list; }PollDevice; #ifdef TANGO_HAS_LOG4TANGO // // Logging levels // enum LogLevel { LOG_OFF = 0, LOG_FATAL, LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG } ; // // Logging targets // enum LogTarget { LOG_CONSOLE = 0, LOG_FILE, LOG_DEVICE }; #endif // TANGO_HAS_LOG4TANGO // // The command argument name // const char * const CmdArgTypeName[] = { "DevVoid", "DevBoolean", "DevShort", "DevLong", "DevFloat", "DevDouble", "DevUShort", "DevULong", "DevString", "DevVarCharArray", "DevVarShortArray", "DevVarLongArray", "DevVarFloatArray", "DevVarDoubleArray", "DevVarUShortArray", "DevVarULongArray", "DevVarStringArray", "DevVarLongStringArray", "DevVarDoubleStringArray", "DevState", "ConstDevString", "DevVarBooleanArray", "DevUChar", "DevLong64", "DevULong64", "DevVarLong64Array", "DevVarULong64Array", "DevInt", "DevEncoded", "DevEnum", "DevPipeBlob", "DevVarStateArray", "Unknown" }; // // The state name // const char * const DevStateName[] = { "ON", "OFF", "CLOSE", "OPEN", "INSERT", "EXTRACT", "MOVING", "STANDBY", "FAULT", "INIT", "RUNNING", "ALARM", "DISABLE", "UNKNOWN" }; /** * Possible event type * * @ingroup Client * @headerfile tango.h */ enum EventType { CHANGE_EVENT=0, ///< Change event QUALITY_EVENT, ///< Quality change event (deprecated - do not use) PERIODIC_EVENT, ///< Periodic event ARCHIVE_EVENT, ///< Archive event USER_EVENT, ///< User event ATTR_CONF_EVENT, ///< Attribute configuration change event DATA_READY_EVENT, ///< Data ready event INTERFACE_CHANGE_EVENT, ///< Device interface change event PIPE_EVENT, ///< Device pipe event numEventType }; const char * const EventName[] = { "change", "quality", "periodic", "archive", "user_event", "attr_conf", "data_ready", "intr_change", "pipe" }; const char *const CONF_TYPE_EVENT = EventName[ATTR_CONF_EVENT]; const char* const DATA_READY_TYPE_EVENT = EventName[DATA_READY_EVENT]; enum AttrSerialModel { ATTR_NO_SYNC=0, ATTR_BY_KERNEL, ATTR_BY_USER }; enum PipeSerialModel { PIPE_NO_SYNC=0, PIPE_BY_KERNEL, PIPE_BY_USER }; /** * Possible error management with write_read_attribute call * * @ingroup Client * @headerfile tango.h */ enum ErrorManagementType { ABORT_ON_ERROR=0, ///< Do not read attribute(s) if one of the written attribute(s) failed CONTINUE_ON_ERROR, ///< Read attribute(s) even if one of the written attribute(s) failed numErrorManagementType }; enum KeepAliveCmdCode { EXIT_TH = 0 }; enum AccessControlType { ACCESS_READ = 0, ACCESS_WRITE }; enum MinMaxValueCheck { MIN = 0, MAX }; enum ChannelType { ZMQ = 0, NOTIFD }; enum ZmqCmdCode { ZMQ_END = 0, ZMQ_CONNECT_HEARTBEAT, ZMQ_DISCONNECT_HEARTBEAT, ZMQ_CONNECT_EVENT, ZMQ_DISCONNECT_EVENT, ZMQ_CONNECT_MCAST_EVENT, ZMQ_DELAY_EVENT, ZMQ_RELEASE_EVENT, }; typedef struct _SendEventType { _SendEventType() : change(false), archive(false), periodic(false) { }; bool change; bool archive; bool periodic; }SendEventType; typedef struct _OptAttrProp { const char *name; const char *default_value; }OptAttrProp; typedef enum _FwdAttError { FWD_NO_ERROR = 0, FWD_WRONG_ATTR, FWD_WRONG_DEV, FWD_ROOT_DEV_LOCAL_DEV, FWD_MISSING_ROOT, FWD_WRONG_SYNTAX, FWD_ROOT_DEV_NOT_STARTED, FWD_DOUBLE_USED, FWD_TOO_OLD_LOCAL_DEVICE, FWD_TOO_OLD_ROOT_DEVICE, FWD_CONF_LOOP, FWD_ERR_UNKNOWN }FwdAttError; typedef struct _AttributeIdlData { AttributeValueList_3 *data_3; AttributeValueList_4 *data_4; AttributeValueList_5 *data_5; _AttributeIdlData() { data_3 = Tango_nullptr; data_4 = Tango_nullptr; data_5 = Tango_nullptr; } }AttributeIdlData; // Ranges type-enum-string conversions template struct ranges_type2const { static CmdArgType enu; static TANGO_CXX11_ABI string str; }; template struct ranges_const2type { static TANGO_CXX11_ABI string str; }; #define RANGES_TYPE2CONST(type,constant) \ template <> \ struct ranges_type2const \ { \ static CmdArgType enu; \ TANGO_CXX11_ABI static string str; \ }; \ CmdArgType ranges_type2const::enu = constant; \ TANGO_CXX11_ABI string ranges_type2const::str = #type; \ template<> \ struct ranges_const2type \ { \ typedef type Type; \ TANGO_CXX11_ABI static string str; \ }; \ TANGO_CXX11_ABI string ranges_const2type::str = #type; } // End of Tango namespace #endif /* TANGO_CONST_H */ tango-9.2.5a/lib/cpp/server/tango_monitor.h0000644023471100065110000001344213034745001015615 00000000000000//=================================================================================================================== // // file : tango_monitor.h // // description : Include file for the Tango_monitor class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #ifndef _TANGO_MONITOR_H #define _TANGO_MONITOR_H namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // class : // TangoMonitor // // description : // This class is used to synchronise device access between polling thread and CORBA request. It is used only for // the command_inout and read_attribute calls // //-------------------------------------------------------------------------------------------------------------------- class TangoMonitor: public omni_mutex { public : TangoMonitor(const char *na):_timeout(DEFAULT_TIMEOUT),cond(this), locking_thread(NULL),locked_ctr(0),name(na) {}; TangoMonitor():_timeout(DEFAULT_TIMEOUT),cond(this),locking_thread(NULL), locked_ctr(0),name("unknown") {}; ~TangoMonitor() {}; void get_monitor(); void rel_monitor(); void timeout(long new_to) {_timeout = new_to;} long timeout() {return _timeout;} void wait() {cond.wait();} int wait(long); void signal() {cond.signal();} int get_locking_thread_id(); long get_locking_ctr(); string &get_name() {return name;} void set_name(const string &na) {name = na;} private : long _timeout; omni_condition cond; omni_thread *locking_thread; long locked_ctr; string name; }; //-------------------------------------------------------------------------------------------------------------------- // // methods : // TangoMonitor::get_locking_thread_id // TangoMonitor::get_locking_ctr // //------------------------------------------------------------------------------------------------------------------- inline int TangoMonitor::get_locking_thread_id() { if (locking_thread != NULL) return locking_thread->id(); else return 0; } inline long TangoMonitor::get_locking_ctr() { omni_mutex_lock guard(*this); return locked_ctr; } //-------------------------------------------------------------------------------------------------------------------- // // method : // TangoMonitor::get_monitor // // description : // Get a monitor. The thread will wait (with timeout) if the monitor is already locked. If the thread is already // the monitor owner thread, simply increment the locking counter // //-------------------------------------------------------------------------------------------------------------------- inline void TangoMonitor::get_monitor() { omni_thread *th = omni_thread::self(); omni_mutex_lock synchronized(*this); #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "In get_monitor() " << name << ", thread = " << th->id() << ", ctr = " << locked_ctr << endl; #endif if (locked_ctr == 0) { locking_thread = th; } else if (th != locking_thread) { while(locked_ctr > 0) { #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "Thread " << th->id() << ": waiting !!" << endl; #endif int interupted; interupted = wait(_timeout); if (interupted == false) { #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "TIME OUT for thread " << th->id() << endl; #endif Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Not able to acquire serialization (dev, class or process) monitor", (const char *)"TangoMonitor::get_monitor"); } } locking_thread = th; } else { #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "owner_thread !!" << endl; #endif } locked_ctr++; } //-------------------------------------------------------------------------------------------------------------------- // // method : // TangoMonitor::rel_monitor // // description : // Release a monitor if the caller thread is the locking thread. Signal other threads if the locking counter // goes down to zero // //-------------------------------------------------------------------------------------------------------------------- inline void TangoMonitor::rel_monitor() { omni_thread *th = omni_thread::self(); omni_mutex_lock synchronized(*this); #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "In rel_monitor() " << name << ", ctr = " << locked_ctr << ", thread = " << th->id() << endl; #endif if ((locked_ctr == 0) || (th != locking_thread)) return; locked_ctr--; if (locked_ctr == 0) { #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER >= 1300) cout4 << "Signalling !" << endl; #endif locking_thread = NULL; cond.signal(); } } } // End of Tango namespace #endif /* TANGO_MONITOR */ tango-9.2.5a/lib/cpp/server/tangoappender.h0000644023471100065110000000377313034745002015574 00000000000000/* * tangoappender.h * * by NL - SOLEIL - 09/2002. * * Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 * European Synchrotron Radiation Facility * BP 220, Grenoble 38043 * FRANCE * * This file is part of Tango. * * Tango is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tango is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Tango. If not, see . * * $Revision: 28424 $ * */ #ifndef _TANGO_APPENDER_H_ #define _TANGO_APPENDER_H_ #ifdef TANGO_HAS_LOG4TANGO namespace Tango { class TangoAppender : public log4tango::Appender { public: /** * **/ TangoAppender (const std::string& src_name, const std::string& name, const std::string& dev_name, bool open_connection = true); /** * **/ virtual ~TangoAppender (); /** * **/ virtual bool requires_layout (void) const; /** * **/ virtual void set_layout(log4tango::Layout* layout); /** * **/ virtual void close (void); /** * **/ virtual bool reopen (void); /** * **/ virtual bool is_valid (void) const; protected: /** * **/ virtual int _append (const log4tango::LoggingEvent& event); private: /** * **/ const std::string _dev_name; /** * **/ const std::string _src_name; /** * **/ DeviceProxy *_dev_proxy; DevULong _req_ctr; }; } // namespace tango #endif // _TANGO_APPENDER_H_ #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/tangorollingfileappender.h0000644023471100065110000000317413034745001020015 00000000000000/* * tango_rolling_file_appender.h * * by NL - SOLEIL - 09/2002. * * Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 * European Synchrotron Radiation Facility * BP 220, Grenoble 38043 * FRANCE * * This file is part of Tango. * * Tango is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Tango is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Tango. If not, see . * * $Revision: 27410 $ * * */ #ifndef _LOG4TANGO_TANGO_ROLLING_FILE_APPENDER_H_ #define _LOG4TANGO_TANGO_ROLLING_FILE_APPENDER_H_ #ifdef TANGO_HAS_LOG4TANGO namespace Tango { class TangoRollingFileAppender : public log4tango::RollingFileAppender { public: /** * **/ TangoRollingFileAppender (const std::string& name, const std::string& fileName, size_t maxFileSize); /** * **/ virtual ~TangoRollingFileAppender (); /** * **/ virtual bool isValid (void) const; }; } // namespace tango #endif // _LOG4TANGO_TANGO_ROLLING_FILE_APPENDER_H_ #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/utils.h0000644023471100065110000011233613034745001014100 00000000000000//============================================================================= // // file : utils.h // // description : Include for utility functions or classes // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //============================================================================= #ifndef _UTILS_H #define _UTILS_H #include #include #include #include #include #include #ifndef _TG_WINDOWS_ #include #else #include #include #endif /* _TG_WINDOWS_ */ // // For debug purpose // #ifndef TANGO_HAS_LOG4TANGO #define cout1 if ((Tango::Util::_tracelevel >= 1) && \ (Tango::Util::_tracelevel < 5)) cout #define cout2 if ((Tango::Util::_tracelevel >= 2) && \ (Tango::Util::_tracelevel < 5)) cout #define cout3 if ((Tango::Util::_tracelevel >= 3) && \ (Tango::Util::_tracelevel < 5)) cout #define cout4 if ((Tango::Util::_tracelevel >= 4) && \ (Tango::Util::_tracelevel < 5)) cout #define cout5 if (Tango::Util::_tracelevel >= 5) cout #endif //TANGO_HAS_LOG4TANGO namespace Tango { class DeviceImpl; class DeviceClass; class DServer; class AutoTangoMonitor; class Util; class NotifdEventSupplier; class ZmqEventSupplier; class PyLock; class CreatePyLock; class DbServerCache; class SubDevDiag; struct PollingThreadInfo; struct DevDbUpd; #ifdef _TG_WINDOWS_ class CoutBuf; class W32Win; #endif class PyLock { public: PyLock() {} virtual ~PyLock() {} virtual void Get() {} virtual void Release() {} }; class CreatePyLock { public: CreatePyLock() {} virtual ~CreatePyLock() {} virtual PyLock *create() {return new PyLock();} }; class Interceptors { public: Interceptors() {} virtual ~Interceptors() {} virtual void create_thread() {} virtual void delete_thread() {} }; //============================================================================= // // The Util class // // description : This class contains all properties and methods // which a device server process requires only once e.g. // the orb and boa pointers.... // This class is a singleton ( The constructor is // protected and the _instance data member is static) // // This class must be created at the beginning of each // device server process // //============================================================================= /** * This class is a used to store TANGO device server process data and to provide * the user with a set of utilities method. This class is implemented using * the singleton design pattern. Therefore a device server process can have only * one instance of this class and its constructor is not public. * * $Author: taurel $ * $Revision: 28853 $ * * @headerfile tango.h * @ingroup Server */ class Util { friend class Tango::AutoTangoMonitor; friend class Tango::ApiUtil; public: /**@name Singleton related methods * These methods follow the singleton design pattern (only one instance * of a class) */ //@{ /** * Create and get the singleton object reference. * * This method returns a reference to the object of the Util class. * If the class singleton object has not been created, it will be * instanciated * * @param argc The process command line argument number * @param argv The process commandline arguments * @return The Util object reference */ static Util *init(int argc,char *argv[]); #ifdef _TG_WINDOWS_ /** * Create and get the singleton object reference. * * This method returns a reference to the object of the Util class. * If the class singleton object has not been created, it will be * instanciated. This method must be used only for non-console mode windows * device server * * @param AppInst The application instance * @param CmdShow The display window flag * @return The Util object reference */ TANGO_IMP_EXP static Util *init(HINSTANCE AppInst,int CmdShow); #endif /** * Get the singleton object reference. * * This method returns a reference to the object of the Util class. * If the class has not been initialised with it's init method, this method * print a message and abort the device server process * * @return The Util object reference */ TANGO_IMP_EXP static Util *instance(bool exit = true); //@} /**@name Destructor * Only one destructor is defined for this class */ //@{ /** * The class destructor. */ ~Util(); //@} /**@name Get/Set instance data */ //@{ /** * Get a reference to the CORBA ORB * * This is a CORBA _duplicate of the original reference * * @return The CORBA ORB */ CORBA::ORB_ptr get_orb() {return CORBA::ORB::_duplicate(orb);} /** * Get a reference to the CORBA Portable Object Adapter (POA) * * This is a CORBA _dupilcate of the original reference to the object POA. * For classical device server, thisis the root POA. For no database device * server, this is a specific POA with the USER_ID policy. * * @return The CORBA root POA */ PortableServer::POA_ptr get_poa() {return PortableServer::POA::_duplicate(_poa);} /** * Set the process trace level. * * @param level The new process level */ void set_trace_level(int level) {_tracelevel = level;} /** * Get the process trace level. * * @return The process trace level */ int get_trace_level() {return _tracelevel;} #ifndef TANGO_HAS_LOG4TANGO /** * Set the process trace output . * * @param level The new process output */ void set_trace_output(string &trace) {trace_output = trace;} /** * Get the process trace output. * * @return The process trace output */ string &get_trace_output() {return trace_output;} /** * Get the temporary process output print stream * * @return The process output print stream */ TangoSys_Cout &get_out() {return cout_tmp;} /** * Set the process trace output stream. * * @param in The new process output stream */ void set_trace_output_stream(ofstream *in) {file_stream = in;} /** * Get the process output print stream * * @return The process output print stream */ ofstream *get_trace_output_stream() {return file_stream;} #endif //TANGO_HAS_LOG4TANGO /** * Get the device server instance name. * * @return The device server instance name */ string &get_ds_inst_name() {return ds_instance_name;} /** * Get the device server executable name. * * @return The device server executable name */ string &get_ds_exec_name() {return ds_exec_name;} /** * Get the device server name. * * The device server name is the device server executable name/the device * server instance name * @return The device server name */ string &get_ds_name() {return ds_name;} /** * Get the host name where the device server process is running. * * @return The host name */ string &get_host_name() {return hostname;} /** * Get the device server process identifier as a String * * @return The device server process identifier as a string */ string &get_pid_str() {return pid_str;} /** * Get the device server process identifier * * @return The device server process identifier */ TangoSys_Pid get_pid() {return pid;} /** * Get the TANGO library version number. * * @return The Tango library release number coded in 3 digits * (for instance 550,551,552,600,....) */ long get_tango_lib_release(); /** * Get the IDL TANGO version. * * @return The device server version */ string &get_version_str() {return version_str;} /** * Get the device server version. * * @return The device server version */ string &get_server_version() {return server_version;} /** * Set the device server version. * * @param vers The device server version */ void set_server_version(const char *vers) {server_version = vers;} /** * Set the DeviceClass list pointer * * @param list The DeviceClass ptr vector address */ void set_class_list(vector *list) {cl_list_ptr = list;cl_list = *list;} /** * Add a DeviceClass to the DeviceClass list pointer * * @param cl The DeviceClass ptr */ void add_class_to_list(DeviceClass * cl) {cl_list.push_back(cl);} /** * Get the DeviceClass list pointer * * @return The DeviceClass ptr vector address */ const vector *get_class_list() {return &cl_list;} /** * Set the serialization model * * @param ser The new serialization model. The serialization model must be one * of BY_DEVICE, BY_CLASS, BY_PROCESS or NO_SYNC */ void set_serial_model(SerialModel ser) {ser_model = ser;} /** * Get the serialization model * * @return The serialization model. This serialization model is one of * BY_DEVICE, BY_CLASS, BY_PROCESS or NO_SYNC */ SerialModel get_serial_model() {return ser_model;} /** * Get a reference to the notifd TANGO EventSupplier object * * @return The notifd EventSupplier object */ NotifdEventSupplier *get_notifd_event_supplier() {return nd_event_supplier;} /** * Get a reference to the ZMQ TANGO EventSupplier object * * @return The zmq EventSupplier object */ ZmqEventSupplier *get_zmq_event_supplier() {return zmq_event_supplier;} /** * Set device server process event buffer high water mark (HWM) * * @param val The new event buffer high water mark in number of events */ void set_ds_event_buffer_hwm(DevLong val) {if (user_pub_hwm == -1)user_pub_hwm = val;} //@} /** @name Polling related methods */ //@{ /** * Trigger polling for polled command. * * This method send the order to the polling thread to poll one object * registered with an update period defined as "externally triggerred" * * @param dev The TANGO device * @param name The command name which must be polled * @exception DevFailed If the call failed * Click here to read * DevFailed exception specification */ void trigger_cmd_polling(DeviceImpl *dev,const string &name); /** * Trigger polling for polled attribute. * * This method send the order to the polling thread to poll one object * registered with an update period defined as "externally triggerred" * * @param dev The TANGO device * @param name The attribute name which must be polled * @exception DevFailed If the call failed * Click here to read * DevFailed exception specification */ void trigger_attr_polling(DeviceImpl *dev,const string &name); /** * Fill polling buffer for polled attribute. * * This method fills the polling buffer for one polled attribute * registered with an update period defined as "externally triggerred" * (polling period set to 0) * * @param dev The TANGO device * @param att_name The attribute name which must be polled * @param data The data stack with one element for each history element * @exception DevFailed If the call failed * Click here to read * DevFailed exception specification */ template void fill_attr_polling_buffer(DeviceImpl *dev, string &att_name, AttrHistoryStack &data); /** * Fill polling buffer for polled command. * * This method fills the polling buffer for one polled command * registered with an update period defined as "externally triggerred" * (polling period set to 0) * * @param dev The TANGO device * @param cmd_name The command name which must be polled * @param data The data stack with one element for each history element * @exception DevFailed If the call failed * Click here to read * DevFailed exception specification */ template void fill_cmd_polling_buffer(DeviceImpl *dev, string &cmd_name, CmdHistoryStack &data); /** * Set the polling threads pool size * * @param thread_nb The maximun number of threads in the polling threads pool */ void set_polling_threads_pool_size(unsigned long thread_nb) {poll_pool_size = thread_nb;} /** * Get the polling threads pool size * * @return The maximun number of threads in the polling threads pool */ unsigned long get_polling_threads_pool_size() {return poll_pool_size;} /** * Set the polling thread algorithm to the algorithum used before Tango 9 * * @param val Polling algorithm flag */ void set_polling_before_9(bool val) {polling_bef_9_def=true;polling_bef_9=val;} //@} /**@name Miscellaneous methods */ //@{ /** * Check if the device server process is in its starting phase * * @return A boolean set to true if the server is in its starting phase. */ bool is_svr_starting() {return svr_starting;} /** * Check if the device server process is in its shutting down sequence * * @return A boolean set to true if the server is in its shutting down phase. */ bool is_svr_shutting_down() {return svr_stopping;} /** * Check if the device is actually restarted by the device server * process admin device with its DevRestart command * * @return A boolean set to true if the device is restarting. */ bool is_device_restarting(string &d_name); //@} /**@name Database related methods */ //@{ /** * Connect the process to the TANGO database. * * If the connection to the database failed, a message is displayed on the * screen and the process is aborted */ void connect_db(); /** * Reread the file database */ void reset_filedatabase(); /** * Get a reference to the TANGO database object * * @return The database object */ Database *get_database() {return db;} /** * Unregister a device server process from the TANGO database. * * If the database call fails, a message is displayed on the screen and the * process is aborted */ void unregister_server(); //@} /** @name Device reference related methods */ //@{ /** * Get the list of device references for a given TANGO class. * * Return the list of references for all devices served by one implementation * of the TANGO device pattern implemented in the process * * @param class_name The TANGO device class name * @return The device reference list * @exception DevFailed If in the device server process there is no TANGO * device pattern implemented the TANGO device class given as parameter * Click here to read * DevFailed exception specification */ vector &get_device_list_by_class(const string &class_name); /** * Get the list of device references for a given TANGO class. * * Return the list of references for all devices served by one implementation * of the TANGO device pattern implemented in the process * * @param class_name The TANGO device class name * @return The device reference list * @exception DevFailed If in the device server process there is no TANGO * device pattern implemented the TANGO device class given as parameter * Click here to read * DevFailed exception specification */ vector &get_device_list_by_class(const char *class_name); /** * Get a device reference from its name * * @param dev_name The TANGO device name * @return The device reference * @exception DevFailed If in the device is not served by one device pattern * implemented in this process. * Click here to read * DevFailed exception specification */ DeviceImpl *get_device_by_name(const string &dev_name); /** * Get a device reference from its name * * @param dev_name The TANGO device name * @return The device reference * @exception DevFailed If in the device is not served by one device pattern * implemented in this process. * Click here to read * DevFailed exception specification */ DeviceImpl *get_device_by_name(const char *dev_name); /** * Get a reference to the dserver device attached to the device server process * * @return A reference to the dserver device */ DServer *get_dserver_device(); /** * Get DeviceList from name. * * It is possible to use a wild card ('*') in the name parameter * (e.g. "*", "/tango/tangotest/n*", ...) * * @param name The device name * @return The DeviceClass ptr vector address */ vector get_device_list(const string &name); //@} /** @name Device pattern related methods */ //@{ /** * Initialise all the device server pattern(s) embedded in a device server * process. * * @exception DevFailed If the device pattern initialisation failed * Click here to read * DevFailed exception specification */ void server_init(bool with_window = false); /** * Run the CORBA event loop * * This method runs the CORBA event loop. For UNIX or Linux operating system, * this method does not return. For Windows in a non-console mode, * this method start a thread which enter the CORBA event loop. */ void server_run(); /** * Cleanup a Tango device server process before exit * * This method cleanup a Tango device server and relinquish all computer * resources before the process exit */ void server_cleanup(); /** * Set the server event loop * * This method registers an event loop function in a Tango server. * This function will be called by the process main thread in an infinite loop * The process will not use the classical ORB blocking event loop. * It is the user responsability to code this function in a way that it implements * some kind of blocking in order not to load the computer CPU * * @param f_ptr The event loop function pointer. This function will not receive * any argument. It returns a boolean value. If this boolean is set to true, * the device server process exit. */ void server_set_event_loop(bool (*f_ptr)()) {ev_loop_func = f_ptr;} //@} /**@name Class data members */ //@{ /** * The process trace level */ static int _tracelevel; /** * The database use flag (Use with extreme care). Implemented for device * server started without database usage. */ TANGO_IMP static bool _UseDb; /** * A daemon process flag. If this flag is set to true, the server * process will not exit if it not able to connect to the database. * Instead, it will loop until the connection suceeds. The default * value is false. */ TANGO_IMP static bool _daemon; /** * The loop sleeping time in case of the _daemon flag set to true. * This sleeping time is the number of seconds the process will * sleep before it tries again to connect to the database. The default * value is 60 seconds. */ TANGO_IMP static long _sleep_between_connect; //@} /// @privatesection TANGO_IMP static bool _FileDb; /// @publicsection #ifdef _TG_WINDOWS_ /**@name Windows specific methods */ //@{ /** * Get the console window instance * * @return The device server graphical interface console window instance */ HWND get_console_window(); /** * Get the main window instance * * @return The device server graphical interface main window instance */ HWND get_ds_main_window(); /** * Get a pointer to the debug object * * @return A pointer to the debug object */ CoutBuf *get_debug_object(); TANGO_IMP static bool _service; /** * Get the text displayed on main server window. * * @return The text to be displayed */ string &get_main_window_text() {return main_win_text;} /** * Set the text displayed on main server window. * * @param txt The new text to be displayed at the bottom of the * main window */ void set_main_window_text(string &txt) {main_win_text = txt;} //@} #endif protected: /** * Constructs a newly allocated Util object. * * This constructor is protected following the singleton pattern * * @param argc The process command line argument number * @param argv The process commandline arguments * */ Util(int argc,char *argv[]); #ifdef _TG_WINDOWS_ /** * Constructs a newly allocated Util object for Windows non-console * device server. * * This constructor is protected following the singleton pattern * * @param AppInst The applicationinstance * @param CmdShow The display window flag * */ Util(HINSTANCE AppInst,int CmdShow); #endif // // The extension class // private: class UtilExt { public: UtilExt() {} ~UtilExt() {} }; public: /// @privatesection void set_interceptors(Interceptors *in) {inter = in;} Interceptors *get_interceptors() {return inter;} map > &get_cmd_line_name_list() {return cmd_line_name_list;} void get_cmd_line_name_list(const string &,vector &); TangoMonitor &get_heartbeat_monitor() {return poll_mon;} PollThCmd &get_heartbeat_shared_cmd() {return shared_data;} bool poll_status() {return poll_on;} void poll_status(bool status) {poll_on = status;} // // Some methods are duplicated here (with different names). It is for compatibility reason // void polling_configure(); PollThread *get_polling_thread_object() {return heartbeat_th;} PollThread *get_heartbeat_thread_object() {return heartbeat_th;} void clr_poll_th_ptr() {heartbeat_th = NULL;} void clr_heartbeat_th_ptr() {heartbeat_th = NULL;} int get_polling_thread_id() {return heartbeat_th_id;} int get_heartbeat_thread_id() {return heartbeat_th_id;} void stop_heartbeat_thread(); string &get_svr_port_num() {return svr_port_num;} void create_notifd_event_supplier(); void create_zmq_event_supplier(); void *get_py_interp() {return py_interp;} void set_py_interp(void *ptr) {py_interp = ptr;} bool is_py_ds() {return py_ds;} void set_py_ds() {py_ds=true;} bool is_py_dbg() {return py_dbg;} void set_py_dbg() {py_dbg=true;} void set_py_lock_creator(CreatePyLock *py) {cr_py_lock = py;} CreatePyLock *get_py_lock_creator() {return cr_py_lock;} DbServerCache *get_db_cache() {return db_cache;} void unvalidate_db_cache() {if (db_cache!=NULL){delete db_cache;db_cache = NULL;}} void set_svr_starting(bool val) {svr_starting = val;} void set_svr_shutting_down(bool val) {svr_stopping = val;} vector &get_polled_dyn_attr_names() {return polled_dyn_attr_names;} vector &get_polled_dyn_cmd_names() {return polled_dyn_cmd_names;} vector &get_full_polled_att_list() {return polled_att_list;} vector &get_full_polled_cmd_list() {return polled_cmd_list;} string &get_dyn_att_dev_name() {return dyn_att_dev_name;} string &get_dyn_cmd_dev_name() {return dyn_cmd_dev_name;} vector &get_all_dyn_attr_names() {return all_dyn_attr;} void clean_attr_polled_prop(); void clean_cmd_polled_prop(); void clean_dyn_attr_prop(); int create_poll_thread(const char *,bool,bool,int smallest_upd = -1); void stop_all_polling_threads(); vector &get_polling_threads_info() {return poll_ths;} PollingThreadInfo *get_polling_thread_info_by_id(int); int get_polling_thread_id_by_name(const char *); void check_pool_conf(DServer *,unsigned long); int check_dev_poll(vector &,vector &,DeviceImpl *); void split_string(string &,char,vector &); void upd_polling_prop(vector &,DServer *); int get_th_polled_devs(string &,vector &); void get_th_polled_devs(long,vector &); void build_first_pool_conf(vector &); bool is_dev_already_in_pool_conf(string &,vector&,int); vector &get_poll_pool_conf() {return poll_pool_conf;} int get_dev_entry_in_pool_conf(string &); void remove_dev_from_polling_map(string &dev_name); void remove_polling_thread_info_by_id(int); bool is_server_event_loop_set() {if (ev_loop_func != NULL)return true;else return false;} void set_shutdown_server(bool val) {shutdown_server = val;} void shutdown_ds(); SubDevDiag &get_sub_dev_diag() {return sub_dev_diag;} bool get_endpoint_specified() {return endpoint_specified;} void set_endpoint_specified(bool val) {endpoint_specified = val;} string &get_specified_ip() {return specified_ip;} void set_specified_ip(string &val) {specified_ip = val;} DevLong get_user_pub_hwm() {return user_pub_hwm;} void add_restarting_device(string &d_name) {restarting_devices.push_back(d_name);} void delete_restarting_device(string &d_name); bool is_wattr_nan_allowed() {return wattr_nan_allowed;} void set_wattr_nan_allowed(bool val) {wattr_nan_allowed=val;} RootAttRegistry &get_root_att_reg() {return root_att_reg;} void event_name_2_event_type(string &,EventType &); void validate_cmd_line_classes(); static void tango_host_from_fqan(string &,string &); static void tango_host_from_fqan(string &,string &,int &); bool is_polling_bef_9_def() {return polling_bef_9_def;} bool get_polling_bef_9() {return polling_bef_9;} private: TANGO_IMP static Util *_instance; static bool _constructed; #ifdef _TG_WINDOWS_ static bool _win; int argc; char **argv; int nCmd; CoutBuf *pcb; W32Win *ds_window; string main_win_text; bool go; TangoMonitor mon; void build_argc_argv(); void install_cons_handler(); class ORBWin32Loop: public omni_thread { Util *util; public: ORBWin32Loop(Util *u):util(u) {} virtual ~ORBWin32Loop() {} void *run_undetached(void *); void start() {start_undetached();} private: void wait_for_go(); }; friend class ORBWin32Loop; ORBWin32Loop *loop_th; #endif CORBA::ORB_var orb; PortableServer::POA_var _poa; string ds_instance_name; // The instance name string ds_exec_name; // The server exec. name string ds_name; // The server name string hostname; // The host name string pid_str; // The process PID (as string) TangoSys_Pid pid; // The process PID string version_str; // Tango version string server_version; // Device server version string database_file_name; #ifndef TANGO_HAS_LOG4TANGO string trace_output; TangoSys_Cout cout_tmp; ofstream *file_stream; #endif //TANGO_HAS_LOG4TANGO Database *db; // The db proxy void effective_job(int,char *[]); void create_CORBA_objects(); void misc_init(); void init_host_name(); void server_already_running(); void print_usage(char *); static void print_err_message(const char *,Tango::MessBoxType type = Tango::STOP); void print_err_message(const string &mess,Tango::MessBoxType type = Tango::STOP) { print_err_message(mess.c_str(),type); } void check_args(int, char *[]); void display_help_message(); DeviceImpl *find_device_name_core(string &); void check_orb_endpoint(int,char **); void validate_sort(vector &); void check_end_point_specified(int,char **); bool display_help; // display help message flag const vector *cl_list_ptr; // Ptr to server device class list #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else Util::UtilExt *ext; // Class extension #endif vector cl_list; // Full class list ptr // // Ported from the extension class // map > cmd_line_name_list; // Command line map PollThread *heartbeat_th; // The heartbeat thread object int heartbeat_th_id; // The heartbeat thread identifier PollThCmd shared_data; // The shared buffer TangoMonitor poll_mon; // The monitor bool poll_on; // Polling on flag SerialModel ser_model; // The serialization model TangoMonitor only_one; // Serialization monitor NotifdEventSupplier *nd_event_supplier; // The notifd event supplier object void *py_interp; // The Python interpreter bool py_ds; // The Python DS flag CreatePyLock *cr_py_lock; // The python lock creator pointer bool py_dbg; // Badly written Python dbg flag DbServerCache *db_cache; // The db cache Interceptors *inter; // The user interceptors bool svr_starting; // Server is starting flag bool svr_stopping; // Server is shutting down flag vector polled_dyn_attr_names; // Dynamic att. names (used for polling clean-up) vector polled_dyn_cmd_names; // Dynamic cmd. names (used for polling clean-up) vector polled_att_list; // Full polled att list vector polled_cmd_list; // Full polled cmd list vector all_dyn_attr; // All dynamic attr name list string dyn_att_dev_name; // Device name (use for dyn att clean-up) string dyn_cmd_dev_name; // Device name (use for dyn cmd clean-up) unsigned long poll_pool_size; // Polling threads pool size vector poll_pool_conf; // Polling threads pool conf. map dev_poll_th_map; // Link between device name and polling thread id vector poll_ths; // Polling threads bool conf_needs_db_upd; // Polling conf needs to be udated in db bool (*ev_loop_func)(void); // Ptr to user event loop bool shutdown_server; // Flag to exit the manual event loop SubDevDiag sub_dev_diag; // Object to handle sub device diagnostics bool _dummy_thread; // The main DS thread is not the process main thread string svr_port_num; // Server port when using file as database ZmqEventSupplier *zmq_event_supplier; // The zmq event supplier object bool endpoint_specified; // Endpoint specified on cmd line string specified_ip; // IP address specified in the endpoint DevLong user_pub_hwm; // User defined pub HWM vector restarting_devices; // Restarting devices name bool wattr_nan_allowed; // NaN allowed when writing attribute RootAttRegistry root_att_reg; // Root attribute(s) registry bool polling_bef_9_def; // Is polling algo requirement defined bool polling_bef_9; // use Tango < 9 polling algo. flag }; //*************************************************************************** // // Some inline methods // //*************************************************************************** //----------------------------------------------------------------------------- // // method : Util::is_device_restarting() // // description : Return a boolean if the device with name given as parameter // is actually executing a RestartDevice command // // args: - d_name : - The device name // // Returns true if the devce is restarting. False otherwise // //----------------------------------------------------------------------------- inline bool Util::is_device_restarting(string &d_name) { bool ret = false; if (restarting_devices.empty() == false) { vector::iterator pos; pos = find(restarting_devices.begin(),restarting_devices.end(),d_name); if (pos != restarting_devices.end()) ret = true; } return ret; } //----------------------------------------------------------------------------- // // method : Util::check_orb_endpoint() // // description : // // args: - argc : // - argv // // //----------------------------------------------------------------------------- inline void Util::check_orb_endpoint(int argc, char *argv[]) { long arg_nb; for (arg_nb = 2;arg_nb < argc;arg_nb++) { if (::strcmp(argv[arg_nb],"-ORBendPoint") == 0) { arg_nb++; string endpoint = argv[arg_nb]; string::size_type pos; if ((pos = endpoint.rfind(':')) == string::npos) { cerr << "Strange ORB endPoint specification" << endl; print_usage(argv[0]); } svr_port_num = endpoint.substr(++pos); break; } } if (arg_nb == argc) { cerr << "Missing ORB endPoint specification" << endl; print_usage(argv[0]); } } //----------------------------------------------------------------------------- // // method : Util::event_name_2_event_type() // // description : // // args: - event_name : // - et // // //----------------------------------------------------------------------------- inline void Util::event_name_2_event_type(string &event_name,EventType &et) { if (event_name == "change") et = CHANGE_EVENT; else if (event_name == "quality") et = QUALITY_EVENT; else if (event_name == "periodic") et = PERIODIC_EVENT; else if (event_name == "archive") et = ARCHIVE_EVENT; else if (event_name == "user_event") et = USER_EVENT; else if (event_name == "attr_conf" || event_name == "attr_conf_5") et = ATTR_CONF_EVENT; else et = DATA_READY_EVENT; } //+------------------------------------------------------------------------- // // function : return_empty_any // // description : Return from a command when the command does not have // any output argument // // arguments : in : - cmd : The command name // //-------------------------------------------------------------------------- /** * Create and return an empty CORBA Any object. * * Create an empty CORBA Any object. Could be used by command which does * not return anything to the client. This method also prints a message on * screen (level 4) before it returns * * @param cmd The cmd name which use this empty Any. Only used to create the * thrown exception (in case of) and in the displayed message * @return The empty CORBA Any * @exception DevFailed If the Any object creation failed. * Click here to read * DevFailed exception specification */ inline CORBA::Any *return_empty_any(const char *cmd) { CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { TangoSys_MemStream o; o << cmd << "::execute"; Tango::Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", o.str()); } return(out_any); } inline DbDevice *DeviceImpl::get_db_device() { if (Tango::Util::_UseDb == false) { TangoSys_OMemStream desc_mess; desc_mess << "Method not available for device "; desc_mess << device_name; desc_mess << " which is a non database device"; Except::throw_exception((const char *)API_NonDatabaseDevice, desc_mess.str(), (const char *)"DeviceImpl::get_db_device"); } return db_dev; } void clear_att_dim(Tango::AttributeValue_3 &att_val); void clear_att_dim(Tango::AttributeValue_4 &att_val); void clear_att_dim(Tango::AttributeValue_5 &att_val); //----------------------------------------------------------------------- // // Polling threads pool related class/struct // //----------------------------------------------------------------------- struct PollingThreadInfo { int thread_id; // The polling thread identifier PollThread *poll_th; // The polling thread object PollThCmd shared_data; // The shared buffer TangoMonitor poll_mon; // The monitor vector polled_devices; // Polled devices for this thread int nb_polled_objects; // Polled objects number in this thread int smallest_upd; // Smallest thread update period vector v_poll_cmd; // Command(s) to send PollingThreadInfo():thread_id(0),poll_th(NULL),poll_mon("Polling_thread_mon"),nb_polled_objects(0),smallest_upd(0) {shared_data.cmd_pending = false;shared_data.trigger=false;} }; struct DevDbUpd { unsigned long class_ind; unsigned long dev_ind; int mod_prop; }; //------------------------------------------------------------------------ // // Python device server classes // //----------------------------------------------------------------------- // // For thread creation interceptor (Python device servers) // void create_PyPerThData(omni::omniInterceptors::createThread_T::info_T &); class PyData: public omni_thread::value_t { public: PyData():rec_state(false),rec_status(false) { device_name = "No associated device name!"; try { Util *tg = Util::instance(false); CreatePyLock *Creator = tg->get_py_lock_creator(); PerTh_py_lock = Creator->create(); } catch(Tango::DevFailed &) {PerTh_py_lock=NULL;} } ~PyData() { if (PerTh_py_lock != NULL) delete PerTh_py_lock; } DevVarCharArray PerTh_dvca; DevVarShortArray PerTh_dvsha; DevVarLongArray PerTh_dvla; DevVarFloatArray PerTh_dvfa; DevVarDoubleArray PerTh_dvda; DevVarUShortArray PerTh_dvusa; DevVarULongArray PerTh_dvula; DevVarStringArray PerTh_dvsa; DevVarLongStringArray PerTh_dvlsa; DevVarDoubleStringArray PerTh_dvdsa; DevVarLong64Array PerTh_dvl64a; DevVarULong64Array PerTh_dvul64a; DevVarEncodedArray PerTh_dvea; string PerTh_string; DevFailed PerTh_df; vector PerTh_vec_str; vector PerTh_vec_db; DevErrorList PerTh_del; bool rec_state; bool rec_status; // name of the associated device to a thread // used to sub device referencing string device_name; PyLock *PerTh_py_lock; }; class AutoPyLock { public: AutoPyLock(); ~AutoPyLock(); }; long _convert_tango_lib_release(); } // End of Tango namespace #endif /* UTILS */ tango-9.2.5a/lib/cpp/server/w_attribute.h0000644023471100065110000007637213034745002015303 00000000000000//============================================================================= // // file : w_attribute.h // // description : Include file for the WAttribute classes. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28855 $ // //============================================================================= #ifndef _WATTRIBUTE_H #define _WATTRIBUTE_H #include #include #include #include namespace Tango { //============================================================================= // // The WAttribute class // // // description : This class inherits the Attribute class. There is one // instance of this class for each writable attribute // //============================================================================= /** * This class represents a writable attribute. It inherits from the Attribute * class and only add what is specific to writable attribute. * * $Author: taurel $ * $Revision: 28855 $ * * @headerfile tango.h * @ingroup Server */ class WAttribute:public Attribute { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Create a new Writable Attribute object. * * @param prop_list The attribute properties list. Each property is an object * of the AttrProperty class * @param tmp_attr The temporary attribute object built from user parameters * @param dev_name The device name * @param idx The index of the related Attr object in the MultiClassAttribute * vector of Attr object */ WAttribute(vector &prop_list,Attr &tmp_attr,string &dev_name,long idx); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The WAttribute desctructor. */ ~WAttribute(); //@} /**@name Attribute configuration methods * Miscellaneous methods dealing with attribute min and max value property */ //@{ /** * Check if the attribute has a minimum value. * * @return A boolean set to true if the attribute has a minimum value * defined */ bool is_min_value() {return check_min_value;} /** * Set attribute minimum value * * @param min_value Reference to a variable which represents the new min value */ template void set_min_value(const T &min_value); void set_min_value(char *min_value); void set_min_value(const char *min_value); /** * Gets attribute minimum value or throws an exception if the * attribute does not have a minimum value * * @param min_value Reference to a variable which value will be set to the attribute's * minimum value */ template void get_min_value(T &min_value); /** * Check if the attribute has a maximum value. * * @return check_max_value A boolean set to true if the attribute has a maximum value * defined */ bool is_max_value() {return check_max_value;} /** * Set attribute maximum value * * @param max_value Reference to a variable which represents the new max value */ template void set_max_value(const T &max_value); void set_max_value(char *max_value); void set_max_value(const char *max_value); /** * Get attribute maximum value or throws an exception if the * attribute does not have a maximum value * * @param max_value Reference to a variable which value will be set to the attribute's * maximum value */ template void get_max_value(T &max_value); //@} /**@name Get new value for attribute * Miscellaneous method to retrieve from the WAttribute object the new value * for the attribute. */ //@{ /** * Retrieve the new value length (data number) for writable attribute. * * @return The new value data length */ long get_write_value_length(); /** * Retrieve the date of the last attribute writing. This is set only * if the attribute has a read different than set alarm. Otherwise, * date is set to 0. * * @return The written date */ struct timeval &get_write_date() {return write_date;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevShort. * * @param val A reference to a Tango::DevShort data which will be initialised * with the new value */ void get_write_value(Tango::DevShort &val) {val = short_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevShort and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer wich will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevShort *&ptr) {ptr = short_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong. * * @param val A reference to a Tango::DevLong data which will be initialised * with the new value */ void get_write_value(Tango::DevLong &val) {val = long_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevLong *&ptr) {ptr = long_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong64. * * @param val A reference to a Tango::DevLong64 data which will be initialised * with the new value */ void get_write_value(Tango::DevLong64 &val) {val = long64_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong64 and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevLong64 *&ptr) {ptr = long64_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevFloat. * * @param val A reference to a Tango::DevFloat data which will be initialised * with the new value */ void get_write_value(Tango::DevFloat &val) {val = float_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevFloat and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevFloat *&ptr) {ptr = float_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevDouble. * * @param val A reference to a Tango::DevDouble data which will be initialised * with the new value */ void get_write_value(Tango::DevDouble &val) {val = double_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevDouble and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevDouble *&ptr) {ptr = double_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevString. * * @param val A reference to a Tango::DevString data which will be initialised * with the new value */ void get_write_value(Tango::DevString &val) {val = str_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevString and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::ConstDevString *&ptr) {ptr = str_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevBoolean. * * @param val A reference to a Tango::DevBoolean data which will be initialised * with the new value */ void get_write_value(Tango::DevBoolean &val) {val = boolean_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevBoolean and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevBoolean *&ptr) {ptr = boolean_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevUShort. * * @param val A reference to a Tango::DevUShort data which will be initialised * with the new value */ void get_write_value(Tango::DevUShort &val) {val = ushort_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevUShort and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevUShort *&ptr) {ptr = ushort_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevUChar. * * @param val A reference to a Tango::DevUChar data which will be initialised * with the new value */ void get_write_value(Tango::DevUChar &val) {val = uchar_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevUChar and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevUChar *&ptr) {ptr = uchar_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevULong. * * @param val A reference to a Tango::DevULong data which will be initialised * with the new value */ void get_write_value(Tango::DevULong &val) {val = ulong_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevULong and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevULong *&ptr) {ptr = ulong_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevULong64. * * @param val A reference to a Tango::DevULong64 data which will be initialised * with the new value */ void get_write_value(Tango::DevULong64 &val) {val = ulong64_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong64 and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevULong64 *&ptr) {ptr = ulong64_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevState. * * @param val A reference to a Tango::DevState data which will be initialised * with the new value */ void get_write_value(Tango::DevState &val) {val = dev_state_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevLong64 and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevState *&ptr) {ptr = state_ptr;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevEncoded. * * @param val A reference to a Tango::DevEncoded data which will be initialised * with the new value */ void get_write_value(Tango::DevEncoded &val) {val = encoded_val;} /** * Retrieve the new value for writable attribute when attribute data type is * Tango::DevEncoded and the attribute is SPECTRUM or IMAGE. * * @param ptr Reference to a pointer which will be set to point to the data * to be written into the attribute. This pointer points into attribute * internal memory which must not be freed. */ void get_write_value(const Tango::DevEncoded *&ptr) {ptr = encoded_ptr;} //@} /**@name Set new value for attribute * Miscellaneous method to set a WAttribute value */ //@{ /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevShort. * * @param val A reference to a Tango::DevShort data */ void set_write_value(Tango::DevShort val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevShort. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevShort *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevShort. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevLong. * * @param val A reference to a Tango::DevLong data */ void set_write_value(Tango::DevLong val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevLong. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevLong *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevLong. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevLong64. * * @param val A reference to a Tango::DevLong64 data */ void set_write_value(Tango::DevLong64 val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevLong64. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevLong64 *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevLong64. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevDouble. * * @param val A reference to a Tango::DevDouble */ void set_write_value(Tango::DevDouble val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevDouble. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevDouble *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevDouble. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevString. * * @param val A reference to a Tango::DevString */ void set_write_value(Tango::DevString val); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevString. * * @param val A reference to a std::string */ void set_write_value(string &val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevString. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevString *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevString. * * @param val A vector of string containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevFloat. * * @param val A reference to a Tango::DevFloat */ void set_write_value(Tango::DevFloat val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevFloat. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevFloat *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevFloat. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevBoolean. * * @param val A reference to a Tango::DevBoolean */ void set_write_value(Tango::DevBoolean val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevBoolean. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevBoolean *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevBoolean. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevUShort. * * @param val A reference to a Tango::DevUShort */ void set_write_value(Tango::DevUShort val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevUShort. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevUShort *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevUShort. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevUChar. * * @param val A reference to a Tango::DevUChar */ void set_write_value(Tango::DevUChar val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevUChar. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevUChar *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevUChar. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevULong. * * @param val A reference to a Tango::DevULong data */ void set_write_value(Tango::DevULong val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevULong. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevULong *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevULong. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevULong64. * * @param val A reference to a Tango::DevULong64 data */ void set_write_value(Tango::DevULong64 val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevULong64. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevULong64 *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevULong64. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); /** * Set the writable scalar attribute value when the attribute data type is * Tango::DevState. * * @param val A reference to a Tango::DevState data */ void set_write_value(Tango::DevState val); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevState. * * @param val A reference to the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(Tango::DevState *val, long x = 1, long y = 0); /** * Set the writable spectrum or image attribute value when the attribute * data type is Tango::DevState. * * @param val A vector containing the attribute set value * @param x The attribute set value x length. Default value is 1 * @param y The attribute set value y length. Default value is 0 */ void set_write_value(vector &val, long x = 1, long y = 0); //@} /// @privatesection template void get_write_value(T &); template void get_write_value(const T *&); template void check_type(T &,const string &); template void set_write_value(T); template void set_write_value(T *,long,long); template void set_write_value(vector &,long,long); void set_write_value(Tango::DevEncoded *, long x = 1,long y = 0); // Dummy method for compiler virtual void set_rvalue(); void rollback(); void check_written_value(const CORBA::Any &,unsigned long,unsigned long); void check_written_value(const DevVarEncodedArray &,unsigned long,unsigned long); void check_written_value(const AttrValUnion &,unsigned long,unsigned long); void copy_data(const CORBA::Any &); void copy_data(const Tango::AttrValUnion &); long get_w_dim_x() {return w_dim_x;} long get_w_dim_y() {return w_dim_y;} void set_user_set_write_value(bool val) {uswv = val;} bool get_user_set_write_value() {return uswv;} Tango::DevVarShortArray *get_last_written_sh() {return &short_array_val;} Tango::DevVarLongArray *get_last_written_lg() {return &long_array_val;} Tango::DevVarDoubleArray *get_last_written_db() {return &double_array_val;} Tango::DevVarStringArray *get_last_written_str() {return &str_array_val;} Tango::DevVarFloatArray *get_last_written_fl() {return &float_array_val;} Tango::DevVarBooleanArray *get_last_written_boo() {return &boolean_array_val;} Tango::DevVarUShortArray *get_last_written_ush() {return &ushort_array_val;} Tango::DevVarCharArray *get_last_written_uch() {return &uchar_array_val;} Tango::DevVarLong64Array *get_last_written_lg64() {return &long64_array_val;} Tango::DevVarULong64Array *get_last_written_ulg64() {return &ulong64_array_val;} Tango::DevVarULongArray *get_last_written_ulg() {return &ulong_array_val;} Tango::DevVarStateArray *get_last_written_state() {return &state_array_val;} Tango::DevEncoded &get_last_written_encoded() {return encoded_val;} bool is_memorized() {return memorized;} bool get_memorized() {return memorized;} void set_memorized(bool mem) {memorized = mem;} bool is_memorized_init() {return memorized_init;} bool get_memorized_init() {return memorized_init;} void set_memorized_init(bool mem_init) {memorized_init = mem_init;} string &get_mem_value() {return mem_value;} void set_mem_value(const string &new_val) {mem_value = new_val;} void set_written_date(); bool mem_value_below_above(MinMaxValueCheck,string &); void set_mem_exception(const DevErrorList &df) { mem_exception = df; mem_write_failed = true; att_mem_exception = true; } DevErrorList &get_mem_exception() {return mem_exception;} void clear_mem_exception() { mem_exception.length(0); mem_write_failed = false; att_mem_exception = false; } void set_mem_write_failed(bool bo) {mem_write_failed=bo;} bool get_mem_write_failed() {return mem_write_failed;} protected: /// @privatesection virtual bool check_rds_alarm(); private: inline void check_length(const unsigned int nb_data, unsigned long x, unsigned long y) { if ((!y && nb_data != x ) || (y && nb_data != (x * y))) Except::throw_exception(API_AttrIncorrectDataNumber,"Incorrect data number","WAttribute::check_written_value()"); } template void check_min_max(const unsigned int,const T1 &,const T2 &,const T2 &); // // The extension class // class WAttributeExt { public: WAttributeExt() {} }; // Defined prior to Tango IDL release 3 Tango::DevShort short_val; Tango::DevShort old_short_val; Tango::DevLong long_val; Tango::DevLong old_long_val; Tango::DevDouble double_val; Tango::DevDouble old_double_val; Tango::DevString str_val; Tango::DevString old_str_val; Tango::DevFloat float_val; Tango::DevFloat old_float_val; Tango::DevBoolean boolean_val; Tango::DevBoolean old_boolean_val; Tango::DevUShort ushort_val; Tango::DevUShort old_ushort_val; Tango::DevUChar uchar_val; Tango::DevUChar old_uchar_val; Tango::DevEncoded encoded_val; Tango::DevEncoded old_encoded_val; // Added for Tango IDL release 3 long w_dim_y; long w_dim_x; Tango::DevVarShortArray short_array_val; Tango::DevVarLongArray long_array_val; Tango::DevVarDoubleArray double_array_val; Tango::DevVarStringArray str_array_val; Tango::DevVarFloatArray float_array_val; Tango::DevVarBooleanArray boolean_array_val; Tango::DevVarUShortArray ushort_array_val; Tango::DevVarCharArray uchar_array_val; const Tango::DevShort *short_ptr; const Tango::DevLong *long_ptr; const Tango::DevDouble *double_ptr; const Tango::ConstDevString *str_ptr; const Tango::DevFloat *float_ptr; const Tango::DevBoolean *boolean_ptr; const Tango::DevUShort *ushort_ptr; const Tango::DevUChar *uchar_ptr; const Tango::DevEncoded *encoded_ptr; bool string_allocated; bool memorized; bool memorized_init; string mem_value; struct timeval write_date; #ifdef HAS_UNIQUE_PTR unique_ptr w_ext; // Class extension #else WAttributeExt *w_ext; #endif // // Ported from the extension class // Tango::DevLong64 long64_val; Tango::DevLong64 old_long64_val; Tango::DevULong ulong_val; Tango::DevULong old_ulong_val; Tango::DevULong64 ulong64_val; Tango::DevULong64 old_ulong64_val; Tango::DevState dev_state_val; Tango::DevState old_dev_state_val; Tango::DevVarLong64Array long64_array_val; Tango::DevVarULongArray ulong_array_val; Tango::DevVarULong64Array ulong64_array_val; Tango::DevVarStateArray state_array_val; const Tango::DevLong64 *long64_ptr; const Tango::DevULong *ulong_ptr; const Tango::DevULong64 *ulong64_ptr; const Tango::DevState *state_ptr; bool uswv; // User set_write_value DevErrorList mem_exception; // Exception received at start-up in case writing the // memorized att. failed bool mem_write_failed; // Flag set to true if the memorized att setting failed }; #define COMPUTE_TIME_DIFF(RESULT,BEFORE,AFTER) \ long bef = ((BEFORE.tv_sec - 1095000000) * 1000) + (BEFORE.tv_usec / 1000); \ long after = ((AFTER.tv_sec - 1095000000) * 1000) + (AFTER.tv_usec / 1000); \ RESULT = after - bef; } // End of Tango namespace #endif // _WATTRIBUTE_H tango-9.2.5a/lib/cpp/server/w_pipe.h0000644023471100065110000001071513034745002014222 00000000000000//=================================================================================================================== // // file : w_pipe.h // // description : Include file for the WPipe class. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #ifndef _W_PIPE_H #define _W_PIPE_H #include namespace Tango { /** * This class is a class representing a writable pipe in the TANGO device server pattern. It is an base class. * It is the a root class for pipe related classes. * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Server */ class WPipe: public Pipe { public: /**@name Constructors * Miscellaneous constructors */ //@{ /** * Constructs a newly allocated WPipe object. * * The default constructor */ WPipe():w_ext(new WPipeExt) {} /** * Constructs a newly allocated WPipe object from its * name, its description, its label and its display level * * @param na The pipe name * @param level The pipe display level * */ WPipe(const string &na,const Tango::DispLevel level); //@} /**@name Destructor * Only one desctructor is defined for this class */ //@{ /** * The object desctructor. */ #ifdef HAS_UNIQUE_PTR virtual ~WPipe() {} #else virtual ~WPipe() {delete w_ext;} #endif //@} /**@name Get/Set methods. * Methods to get the value of the data blob transported by the pipe */ //@{ /** * Get root blob name * * Get the root blob name * * @return The root blob name */ string get_root_blob_name() {return the_blob.get_name();} //@} /**@name Extracting data from a WPipe */ //@{ #ifdef GEN_DOC /** * Extract data from a device pipe * * Extracting data from a WPipe instance is simlar to extracting data from a DevicePipeBlob class instance. * See doc of DevicePipeBlob class extraction methods (DevicePipeBlob::operator>>) to get a complete documentation on * how to extract data from a WPipe * * @param [in] datum The pipe data * @exception WrongData if requested */ WPipe & operator >> (short &datum); #endif /** * Get root blob data element number * * Get the root blob data element number * * @return The root blob data element number */ size_t get_data_elt_nb() {return the_blob.get_data_elt_nb();} /** * Get root blob data elements name * * Get the root blob data elements name * * @return The root blob data elements name */ vector get_data_elt_names() {return the_blob.get_data_elt_names();} /** * Get root blob data element name * * Get the root blob data element name for a single data element * * @param [in] ind The data element index within the root blob * @return The root blob data element name */ string get_data_elt_name(size_t ind) {return the_blob.get_data_elt_name(ind);} /** * Get root blob data element value type * * Get the root blob data element value type for a single data element * * @param [in] ind The data element index within the root blob * @return The blob data element value type */ int get_data_elt_type(size_t ind) {return the_blob.get_data_elt_type(ind);} //@} /// @privatesection virtual void write(DeviceImpl *) {} WPipe &operator[](const string &); private: class WPipeExt { public: WPipeExt() {} }; #ifdef HAS_UNIQUE_PTR unique_ptr w_ext; // Class extension #else WPipeExt *w_ext; #endif }; template WPipe &operator>>(WPipe &,T &); template WPipe &operator>>(WPipe &,T *); template WPipe &operator>>(WPipe &, DataElement &); } // End of Tango namespace #endif // _W_PIPE_H tango-9.2.5a/lib/cpp/server/attribute.tpp0000644023471100065110000013300513034745001015313 00000000000000//+=================================================================================================================== // // file : Attribute.tpp // // description : C++ source code for the Attribute class template methods when they are not specialized // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _ATTRIBUTE_TPP #define _ATTRIBUTE_TPP namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::check_hard_coded_properties() // // description : // Check if the user tries to change attribute properties considered as hard coded // Throw exception in case of // // args : // in : // - user_conf : The attribute configuration sent by the user // //------------------------------------------------------------------------------------------------------------------ template void Attribute::check_hard_coded_properties(const T &user_conf) { // // Check attribute name // string user_att_name(user_conf.name.in()); transform(user_att_name.begin(),user_att_name.end(),user_att_name.begin(),::tolower); if (user_att_name != get_name_lower()) { throw_hard_coded_prop("name"); } // // Check data type // if (user_conf.data_type != data_type) { throw_hard_coded_prop("data_type"); } // // Check data format // if (user_conf.data_format != data_format) { throw_hard_coded_prop("data_format"); } // // Check writable // if (user_conf.writable != writable) { throw_hard_coded_prop("writable"); } // // Check max_dim_x // if (user_conf.max_dim_x != max_x) { throw_hard_coded_prop("max_dim_x"); } // // Check max_dim_y // if (user_conf.max_dim_y != max_y) { throw_hard_coded_prop("max_dim_y"); } // // Check writable_attr_name // string local_w_name(writable_attr_name); transform(local_w_name.begin(),local_w_name.end(),local_w_name.begin(),::tolower); string user_w_name(user_conf.writable_attr_name.in()); transform(user_w_name.begin(),user_w_name.end(),user_w_name.begin(),::tolower); if (user_w_name != local_w_name) { throw_hard_coded_prop("writable_attr_name"); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_hard_coded_properties() // // description : // Set some "hard coded" attribute properties. This method is used only in case of forwarded attribute // // args : // in : // - user_conf : The attribute configuration sent by the user // //------------------------------------------------------------------------------------------------------------------ template void Attribute::set_hard_coded_properties(const T &user_conf) { data_type = user_conf.data_type; data_format = user_conf.data_format; writable = user_conf.writable; max_x = user_conf.max_dim_x; max_y = user_conf.max_dim_y; writable_attr_name = user_conf.writable_attr_name; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_min_alarm() // // description : // Sets minimum alarm attribute property. Throws exception in case the data type of provided property does not // match the attribute data type // // args : // in : // - new_min_alarm : The minimum alarm property to be set // //------------------------------------------------------------------------------------------------------------------- template void Attribute::set_min_alarm(const T &new_min_alarm) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) throw_err_data_type("min_alarm",d_name,"Attribute::set_min_alarm()"); else if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"Attribute::set_min_alarm()"); } // // Check coherence with max_alarm // if(alarm_conf.test(max_level)) { T max_alarm_tmp; memcpy((void *) &max_alarm_tmp, (const void *) &max_alarm, sizeof(T)); if(new_min_alarm >= max_alarm_tmp) throw_incoherent_val_err("min_alarm","max_alarm",d_name,"Attribute::set_min_alarm()"); } // // Store new min alarm as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_min_alarm; // to represent the numeric value else str << new_min_alarm; string min_alarm_tmp_str; min_alarm_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new alarm locally // Attr_CheckVal old_min_alarm; memcpy((void *)&old_min_alarm, (void *)&min_alarm, sizeof(T)); memcpy((void *)&min_alarm, (void *)&new_min_alarm, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "min_alarm") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && min_alarm_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("min_alarm"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(min_alarm,"min_alarm"); } catch (Tango::DevFailed &) { memcpy((void *)&min_alarm, (void *)&old_min_alarm, sizeof(T)); throw; } } } // // Set the min_alarm flag // alarm_conf.set(min_level); // // Store new alarm as a string // min_alarm_str = min_alarm_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to min_alarm if there is any // delete_startup_exception("min_alarm",d_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_min_alarm() // // description : // Gets attribute's minimum alarm value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if minimum alarm is not defined // // args : // out : // - min_al : The variable to be assigned the attribute's minimum alarm value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::get_min_alarm(T &min_al) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"Attribute::get_min_alarm()"); } else if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) { string err_msg = "Minimum alarm has no meaning for the attribute's (" + name + ") data type : " + ranges_type2const::str; Except::throw_exception((const char *)API_AttrOptProp, err_msg.c_str(), (const char *)"Attribute::get_min_alarm()"); } if (!alarm_conf[min_level]) { Except::throw_exception((const char *)API_AttrNotAllowed, (const char *)"Minimum alarm not defined for this attribute", (const char *)"Attribute::get_min_alarm()"); } memcpy((void *)&min_al,(void *)&min_alarm,sizeof(T)); } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_max_alarm() // // description : // Sets maximum alarm attribute property // Throws exception in case the data type of provided property does not match the attribute data type // // args : // in : // - new_max_alarm : The maximum alarm property to be set // //------------------------------------------------------------------------------------------------------------------ template void Attribute::set_max_alarm(const T &new_max_alarm) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) throw_err_data_type("max_alarm",d_name,"Attribute::set_max_alarm()"); else if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"Attribute::set_max_alarm()"); } // // Check coherence with min_alarm // if(alarm_conf.test(min_level)) { T min_alarm_tmp; memcpy((void *) &min_alarm_tmp, (const void *) &min_alarm, sizeof(T)); if(new_max_alarm <= min_alarm_tmp) throw_incoherent_val_err("min_alarm","max_alarm",d_name,"Attribute::set_max_alarm()"); } // // Store new max alarm as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_max_alarm; // to represent the numeric value else str << new_max_alarm; string max_alarm_tmp_str; max_alarm_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new alarm locally // Attr_CheckVal old_max_alarm; memcpy((void *)&old_max_alarm, (void *)&max_alarm, sizeof(T)); memcpy((void *)&max_alarm, (void *)&new_max_alarm, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "max_alarm") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && max_alarm_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("max_alarm"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(max_alarm,"max_alarm"); } catch (Tango::DevFailed &) { memcpy((void *)&max_alarm, (void *)&old_max_alarm, sizeof(T)); throw; } } } // // Set the max_alarm flag // alarm_conf.set(max_level); // // Store new alarm as a string // max_alarm_str = max_alarm_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to max_alarm if there is any // delete_startup_exception("max_alarm",d_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_max_alarm() // // description : // Gets attribute's maximum alarm value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if maximum alarm is not defined // // args : // out : // - max_al : The variable to be assigned the attribute's maximum alarm value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::get_max_alarm(T &max_al) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::get_max_alarm()"); } else if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) { string err_msg = "Maximum alarm has no meaning for the attribute's (" + name + ") data type : " + ranges_type2const::str; Except::throw_exception(API_AttrOptProp,err_msg.c_str(),"Attribute::get_max_alarm()"); } if (!alarm_conf[max_level]) { Except::throw_exception(API_AttrNotAllowed,"Maximum alarm not defined for this attribute","Attribute::get_max_alarm()"); } memcpy((void *)&max_al,(void *)&max_alarm,sizeof(T)); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_min_warning() // // description : // Sets minimum warning attribute property // Throws exception in case the data type of provided property does not match the attribute data type // // args : // in : // - new_min_warning : The minimum warning property to be set // //------------------------------------------------------------------------------------------------------------------- template void Attribute::set_min_warning(const T &new_min_warning) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) throw_err_data_type("min_warning",d_name,"Attribute::set_min_warning()"); else if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::set_min_warning()"); } // // Check coherence with max_warning // if(alarm_conf.test(max_warn)) { T max_warning_tmp; memcpy((void *) &max_warning_tmp, (const void *) &max_warning, sizeof(T)); if(new_min_warning >= max_warning_tmp) throw_incoherent_val_err("min_warning","max_warning",d_name,"Attribute::set_min_warning()"); } // // Store new min warning as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_min_warning; // to represent the numeric value else str << new_min_warning; string min_warning_tmp_str; min_warning_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new warning locally // Attr_CheckVal old_min_warning; memcpy((void *)&old_min_warning, (void *)&min_warning, sizeof(T)); memcpy((void *)&min_warning, (void *)&new_min_warning, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "min_warning") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && min_warning_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("min_warning"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(min_warning,"min_warning"); } catch (Tango::DevFailed &) { memcpy((void *)&min_warning, (void *)&old_min_warning, sizeof(T)); throw; } } } // // Set the min_warn flag // alarm_conf.set(min_warn); // // Store new warning as a string // min_warning_str = min_warning_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to min_warning if there is any // delete_startup_exception("min_warning",d_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_min_warning() // // description : // Gets attribute's minimum warning value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if minimum warning is not defined // // args : // out : // - min_war : The variable to be assigned the attribute's minimum warning value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::get_min_warning(T &min_war) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::get_min_warning()"); } else if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) { string err_msg = "Minimum warning has no meaning for the attribute's (" + name + ") data type : " + ranges_type2const::str; Except::throw_exception(API_AttrOptProp,err_msg.c_str(),"Attribute::get_min_warning()"); } if (!alarm_conf[min_warn]) { Except::throw_exception(API_AttrNotAllowed,"Minimum warning not defined for this attribute","Attribute::get_min_warning()"); } memcpy((void *)&min_war,(void *)&min_warning,sizeof(T)); } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_max_warning() // // description : // Sets maximum warning attribute property // Throws exception in case the data type of provided property does not match the attribute data type // // args : // in : // - new_max_warning : The maximum warning property to be set // //----------------------------------------------------------------------------------------------------------------- template void Attribute::set_max_warning(const T &new_max_warning) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) throw_err_data_type("max_warning",d_name,"Attribute::set_max_warning()"); else if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::set_max_warning()"); } // // Check coherence with min_warning // if(alarm_conf.test(min_warn)) { T min_warning_tmp; memcpy((void *) &min_warning_tmp, (const void *) &min_warning, sizeof(T)); if(new_max_warning <= min_warning_tmp) throw_incoherent_val_err("min_warning","max_warning",d_name,"Attribute::set_max_warning()"); } // // Store new max warning as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_max_warning; // to represent the numeric value else str << new_max_warning; string max_warning_tmp_str; max_warning_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new warning locally // Attr_CheckVal old_max_warning; memcpy((void *)&old_max_warning, (void *)&max_warning, sizeof(T)); memcpy((void *)&max_warning, (void *)&new_max_warning, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "max_warning") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && max_warning_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("max_warning"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(max_warning,"max_warning"); } catch (Tango::DevFailed &) { memcpy((void *)&max_warning, (void *)&old_max_warning, sizeof(T)); throw; } } } // // Set the max_warn flag // alarm_conf.set(max_warn); // // Store new warning as a string // max_warning_str = max_warning_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to max_warning if there is any // delete_startup_exception("max_warning",d_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_max_warning() // // description : // Gets attribute's maximum warning value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if maximum warning is not defined // // args : // out : // - max_war : The variable to be assigned the attribute's maximum warning value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::get_max_warning(T &max_war) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::get_max_warning()"); } else if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) { string err_msg = "Maximum warning has no meaning for the attribute's (" + name + ") data type : " + ranges_type2const::str; Except::throw_exception(API_AttrOptProp,err_msg.c_str(),"Attribute::get_max_warning()"); } if (!alarm_conf[max_warn]) { Except::throw_exception(API_AttrNotAllowed,"Maximum warning not defined for this attribute","Attribute::get_max_warning()"); } memcpy((void *)&max_war,(void *)&max_warning,sizeof(T)); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_properties() // // description : // Gets attribute's properties in one call // // args : // out : // - props : The variable to be assigned the attribute's properties value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::get_properties(Tango::MultiAttrProp &props) { // // Check data type // if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && !(data_type == DEV_ENUM && ranges_type2const::enu == DEV_SHORT) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::get_properties()"); } // // Get the monitor protecting device att config // If the server is in its starting phase, gives a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); AttributeConfig_5 conf; get_properties(conf); props.label = conf.label; props.description = conf.description; props.unit = conf.unit; props.standard_unit = conf.standard_unit; props.display_unit = conf.display_unit; props.format = conf.format; props.min_alarm = conf.att_alarm.min_alarm; props.max_alarm = conf.att_alarm.max_alarm; props.min_value = conf.min_value; props.max_value = conf.max_value; props.min_warning = conf.att_alarm.min_warning; props.max_warning = conf.att_alarm.max_warning; props.delta_t = conf.att_alarm.delta_t; props.delta_val = conf.att_alarm.delta_val; props.event_period = conf.event_prop.per_event.period; props.archive_period = conf.event_prop.arch_event.period; props.rel_change = conf.event_prop.ch_event.rel_change; props.abs_change = conf.event_prop.ch_event.abs_change; props.archive_rel_change = conf.event_prop.arch_event.rel_change; props.archive_abs_change = conf.event_prop.arch_event.abs_change; props.enum_labels = enum_labels; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_properties() // // description : // Sets attribute's properties in one call // // args : // in : // - props : The new attribute's properties value // //------------------------------------------------------------------------------------------------------------------- template void Attribute::set_properties(Tango::MultiAttrProp &props) { // // Check data type // if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && !(data_type == DEV_ENUM && ranges_type2const::enu == DEV_SHORT) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception(API_IncompatibleAttrDataType,err_msg.c_str(),"Attribute::set_properties()"); } // // Check if the user set values of properties which do not have any meaning for particular attribute data types // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) { if(TG_strcasecmp(props.min_alarm,AlrmValueNotSpec) != 0) throw_err_data_type("min_alarm",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.max_alarm,AlrmValueNotSpec) != 0) throw_err_data_type("max_alarm",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.min_value,AlrmValueNotSpec) != 0) throw_err_data_type("min_value",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.max_value,AlrmValueNotSpec) != 0) throw_err_data_type("max_value",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.min_warning,AlrmValueNotSpec) != 0) throw_err_data_type("min_warning",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.max_warning,AlrmValueNotSpec) != 0) throw_err_data_type("max_warning",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.delta_t,AlrmValueNotSpec) != 0) throw_err_data_type("delta_t",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.delta_val,AlrmValueNotSpec) != 0) throw_err_data_type("delta_val",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.rel_change,AlrmValueNotSpec) != 0) throw_err_data_type("rel_change",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.abs_change,AlrmValueNotSpec) != 0) throw_err_data_type("abs_change",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.archive_rel_change,AlrmValueNotSpec) != 0) throw_err_data_type("archive_rel_change",d_name,"Attribute::set_properties()"); if(TG_strcasecmp(props.archive_abs_change,AlrmValueNotSpec) != 0) throw_err_data_type("archive_abs_change",d_name,"Attribute::set_properties()"); } // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Get current attribute configuration (to retrieve un-mutable properties) and update properties with provided values // AttributeConfig_5 conf; get_properties(conf); conf.label = CORBA::string_dup(props.label.c_str()); conf.description = CORBA::string_dup(props.description.c_str()); conf.unit = CORBA::string_dup(props.unit.c_str()); conf.standard_unit = CORBA::string_dup(props.standard_unit.c_str()); conf.display_unit = CORBA::string_dup(props.display_unit.c_str()); conf.format = CORBA::string_dup(props.format.c_str()); conf.att_alarm.min_alarm = CORBA::string_dup(props.min_alarm); conf.att_alarm.max_alarm = CORBA::string_dup(props.max_alarm); conf.min_value = CORBA::string_dup(props.min_value); conf.max_value = CORBA::string_dup(props.max_value); conf.att_alarm.min_warning = CORBA::string_dup(props.min_warning); conf.att_alarm.max_warning = CORBA::string_dup(props.max_warning); conf.att_alarm.delta_t = CORBA::string_dup(props.delta_t); conf.att_alarm.delta_val = CORBA::string_dup(props.delta_val); conf.event_prop.per_event.period = CORBA::string_dup(props.event_period); conf.event_prop.arch_event.period = CORBA::string_dup(props.archive_period); conf.event_prop.ch_event.rel_change = CORBA::string_dup(props.rel_change); conf.event_prop.ch_event.abs_change = CORBA::string_dup(props.abs_change); conf.event_prop.arch_event.rel_change = CORBA::string_dup(props.archive_rel_change); conf.event_prop.arch_event.abs_change = CORBA::string_dup(props.archive_abs_change); conf.enum_labels.length(props.enum_labels.size()); for (size_t loop = 0;loop < props.enum_labels.size();loop++) conf.enum_labels[loop] = CORBA::string_dup(props.enum_labels[loop].c_str()); // // Set properties and update database // if (is_fwd_att() == true) { FwdAttribute *fwd_attr = static_cast(this); fwd_attr->upd_att_config_base(conf.label.in()); fwd_attr->upd_att_config(conf); } else set_upd_properties(conf,d_name,true); // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_upd_properties() // // description : // Set new attribute configuration AND update database (if required) // // args : // in : // - conf : The new attribute configuration // - dev_name : The device name // - from_ds : Flag set to true if the call is from a DS process // //------------------------------------------------------------------------------------------------------------------- template void Attribute::set_upd_properties(const T &conf,string &dev_name,bool from_ds) { // // Backup current configuration // T old_conf; if (is_fwd_att() == false) get_properties(old_conf); // // Set flags which disable attribute configuration roll back in case there are some device startup exceptions // bool is_startup_exception = check_startup_exceptions; if(is_startup_exception == true) startup_exceptions_clear = false; try { // // Set properties locally. In case of exception bring the backed-up values // vector v_db; set_properties(conf,dev_name,from_ds,v_db); // // Check ranges coherence for min and max properties (min-max alarm / min-max value ...) // check_range_coherency(dev_name); // // At this point the attribute configuration is correct. Clear the device startup exceptions flag // startup_exceptions_clear = true; // // Update database // try { upd_database(v_db); } catch(DevFailed &) { // // In case of exception, try to store old properties in the database and inform the user about the error // try { v_db.clear(); set_properties(old_conf,dev_name,from_ds,v_db); upd_database(v_db); } catch(DevFailed &) { // // If the old values could not be restored, notify the user about possible database corruption // TangoSys_OMemStream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nDatabase error occurred whilst setting attribute properties. The database may be corrupted." << ends; Except::throw_exception(API_CorruptedDatabase,o.str(),"Attribute::set_upd_properties()"); } throw; } } catch(DevFailed &) { // // If there are any device startup exceptions, do not roll back the attribute configuration unless the new // configuration is correct // if(is_startup_exception == false && startup_exceptions_clear == true && is_fwd_att() == false) { vector v_db; set_properties(old_conf,dev_name,true,v_db); } throw; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::Attribute_2_AttributeValue_base // // description : // Build an AttributeValue_X object (the base part) from the Attribute object content // // arguments // in : // - d : The device to which the attribute belongs to // out : // - ptr : Pointer to the AttributeValue_X object to be filled in // //-------------------------------------------------------------------------------------------------------------------- template void Attribute::Attribute_2_AttributeValue_base(T *ptr,Tango::DeviceImpl *d) { if ((name_lower == "state") || (name_lower == "status")) { ptr->quality = Tango::ATTR_VALID; if (name_lower == "state") { ptr->value.dev_state_att(d->get_state()); } else { Tango::DevVarStringArray str_seq(1); str_seq.length(1); str_seq[0] = CORBA::string_dup(d->get_status().c_str()); ptr->value.string_att_value(str_seq); } #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); ptr->time.tv_sec = (long)t.time; ptr->time.tv_usec = (long)(t.millitm * 1000); ptr->time.tv_nsec = 0; #else struct timeval after; gettimeofday(&after,NULL); ptr->time.tv_sec = after.tv_sec; ptr->time.tv_usec = after.tv_usec; ptr->time.tv_nsec = 0; #endif ptr->r_dim.dim_x = 1; ptr->r_dim.dim_y = 0; ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; ptr->name = CORBA::string_dup(name.c_str()); ptr->data_format = data_format; } else { if (quality != Tango::ATTR_INVALID) { MultiAttribute *m_attr = d->get_device_attr(); // Add the attribute setpoint to the value sequence if ((writable == Tango::READ_WRITE) || (writable == Tango::READ_WITH_WRITE)) { m_attr->add_write_value(*this); } // check for alarms to position the data quality value. if ( is_alarmed().any() == true ) { check_alarm(); } ptr->r_dim.dim_x = dim_x; ptr->r_dim.dim_y = dim_y; if ((writable == Tango::READ_WRITE) || (writable == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = m_attr->get_w_attr_by_ind(get_assoc_ind()); ptr->w_dim.dim_x = assoc_att.get_w_dim_x(); ptr->w_dim.dim_y = assoc_att.get_w_dim_y(); } else { ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; } } else { ptr->r_dim.dim_x = 0; ptr->r_dim.dim_y = 0; ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; ptr->value.union_no_data(true); } ptr->time = when; ptr->quality = quality; ptr->data_format = data_format; ptr->name = CORBA::string_dup(name.c_str()); } } template void Attribute::AttrValUnion_fake_copy(const T *src,V *dst) { switch (src->value._d()) { case ATT_BOOL: { const DevVarBooleanArray &tmp_seq = src->value.bool_att_value(); DevVarBooleanArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.bool_att_value(tmp_seq_4); } break; case ATT_SHORT: { const DevVarShortArray &tmp_seq = src->value.short_att_value(); DevVarShortArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.short_att_value(tmp_seq_4); } break; case ATT_LONG: { const DevVarLongArray &tmp_seq = src->value.long_att_value(); DevVarLongArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.long_att_value(tmp_seq_4); } break; case ATT_LONG64: { const DevVarLong64Array &tmp_seq = src->value.long64_att_value(); DevVarLong64Array tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.long64_att_value(tmp_seq_4); } break; case ATT_FLOAT: { const DevVarFloatArray &tmp_seq = src->value.float_att_value(); DevVarFloatArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.float_att_value(tmp_seq_4); } break; case ATT_DOUBLE: { const DevVarDoubleArray &tmp_seq = src->value.double_att_value(); DevVarDoubleArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.double_att_value(tmp_seq_4); } break; case ATT_UCHAR: { const DevVarCharArray &tmp_seq = src->value.uchar_att_value(); DevVarCharArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.uchar_att_value(tmp_seq_4); } break; case ATT_USHORT: { const DevVarUShortArray &tmp_seq = src->value.ushort_att_value(); DevVarUShortArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.ushort_att_value(tmp_seq_4); } break; case ATT_ULONG: { const DevVarULongArray &tmp_seq = src->value.ulong_att_value(); DevVarULongArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.ulong_att_value(tmp_seq_4); } break; case ATT_ULONG64: { const DevVarULong64Array &tmp_seq = src->value.ulong64_att_value(); DevVarULong64Array tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.ulong64_att_value(tmp_seq_4); } break; case ATT_STRING: { const DevVarStringArray &tmp_seq = src->value.string_att_value(); DevVarStringArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.string_att_value(tmp_seq_4); } break; case ATT_STATE: { const DevVarStateArray &tmp_seq = src->value.state_att_value(); DevVarStateArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.state_att_value(tmp_seq_4); } break; case DEVICE_STATE: { const DevState &sta = src->value.dev_state_att(); dst->value.dev_state_att(sta); } break; case ATT_ENCODED: { const DevVarEncodedArray &tmp_seq = src->value.encoded_att_value(); DevVarEncodedArray tmp_seq_4(tmp_seq.length(),tmp_seq.length(),const_cast(tmp_seq.get_buffer()),false); dst->value.encoded_att_value(tmp_seq_4); } break; case ATT_NO_DATA: break; } } template void Attribute::AttrValUnion_2_Any(const T *src,CORBA::Any &dst) { switch (src->value._d()) { case ATT_BOOL: { const DevVarBooleanArray &tmp_seq = src->value.bool_att_value(); dst <<= tmp_seq; } break; case ATT_SHORT: { const DevVarShortArray &tmp_seq = src->value.short_att_value(); dst <<= tmp_seq; } break; case ATT_LONG: { const DevVarLongArray &tmp_seq = src->value.long_att_value(); dst <<= tmp_seq; } break; case ATT_LONG64: { const DevVarLong64Array &tmp_seq = src->value.long64_att_value(); dst <<= tmp_seq; } break; case ATT_FLOAT: { const DevVarFloatArray &tmp_seq = src->value.float_att_value(); dst <<= tmp_seq; } break; case ATT_DOUBLE: { const DevVarDoubleArray &tmp_seq = src->value.double_att_value(); dst <<= tmp_seq; } break; case ATT_UCHAR: { const DevVarCharArray &tmp_seq = src->value.uchar_att_value(); dst <<= tmp_seq; } break; case ATT_USHORT: { const DevVarUShortArray &tmp_seq = src->value.ushort_att_value(); dst <<= tmp_seq; } break; case ATT_ULONG: { const DevVarULongArray &tmp_seq = src->value.ulong_att_value(); dst <<= tmp_seq; } break; case ATT_ULONG64: { const DevVarULong64Array &tmp_seq = src->value.ulong64_att_value(); dst <<= tmp_seq; } break; case ATT_STRING: { const DevVarStringArray &tmp_seq = src->value.string_att_value(); dst <<= tmp_seq; } break; case ATT_STATE: { const DevVarStateArray &tmp_seq = src->value.state_att_value(); dst <<= tmp_seq; } break; case DEVICE_STATE: { const DevState &sta = src->value.dev_state_att(); dst <<= sta; } break; case ATT_ENCODED: { const DevVarEncodedArray &tmp_seq = src->value.encoded_att_value(); dst <<= tmp_seq; } break; case ATT_NO_DATA: break; } } } // End of Tango namespace #endif // _ATTRIBUTE_TPP tango-9.2.5a/lib/cpp/server/attribute_spec.tpp0000644023471100065110000006251413034745001016333 00000000000000//+================================================================================================================== // // file : attribute_spec.tpp // // description : C++ source code for the Attribute class template methods when they are specialized // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-================================================================================================================= #ifndef _ATTRIBUTE_SPEC_TPP #define _ATTRIBUTE_SPEC_TPP // // These methods are in a sepearte files because I did not find a way to explicitely instanciate specialized // templates. Therefore, for template management we have three files: // 1 - A file with explicit template instanciation (templ_inst.cpp) // 2 - A file with template method definition (attribute.tpp for Attribute class) // 3 - A file with template specialization defnition (attribute_spec.tpp (this file)) // // We did this in order to have explicit instanciation of templates method except for specialized templates // for which we have instanciation following the inclusion model // See C++ template book chapter 6 // namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_min_alarm() // Template specialization for data type DevEncoded and string // // description : // Sets minimum alarm attribute property. Throws exception in case the data type of provided property does not // match the attribute data type // // args : // in : // - new_min_alarm : The minimum alarm property to be set // //------------------------------------------------------------------------------------------------------------------- template <> inline void Attribute::set_min_alarm(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"Attribute::set_min_alarm()"); } template <> inline void Attribute::set_min_alarm(const string &new_min_alarm_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("min_alarm",d_name,"Attribute::set_min_alarm()"); string min_alarm_str_tmp = new_min_alarm_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("min_alarm",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("min_alarm",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_min_alarm_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_alarm",dev_name); avns_in_att(MIN_ALARM); } else if ((TG_strcasecmp(new_min_alarm_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_alarm_str.c_str(),class_def_val.c_str()) == 0)) { min_alarm_str_tmp = class_def_val; } else if (strlen(new_min_alarm_str.c_str()) == 0) { if (user_defaults) { min_alarm_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("min_alarm",dev_name); avns_in_att(MIN_ALARM); } } } else if(user_defaults) { if(TG_strcasecmp(new_min_alarm_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_alarm",dev_name); avns_in_att(MIN_ALARM); } else if ((TG_strcasecmp(new_min_alarm_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_alarm_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_min_alarm_str.c_str()) == 0)) min_alarm_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_min_alarm_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_min_alarm_str.c_str(),NotANumber) == 0) || (strlen(new_min_alarm_str.c_str()) == 0)) { set_value = false; avns_in_db("min_alarm",dev_name); avns_in_att(MIN_ALARM); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << min_alarm_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); set_min_alarm((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); set_min_alarm((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); set_min_alarm((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); set_min_alarm(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); set_min_alarm(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); (db < 0.0) ? set_min_alarm((DevUShort)(-db)) : set_min_alarm((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); (db < 0.0) ? set_min_alarm((DevUChar)(-db)) : set_min_alarm((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); (db < 0.0) ? set_min_alarm((DevULong)(-db)) : set_min_alarm((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); (db < 0.0) ? set_min_alarm((DevULong64)(-db)) : set_min_alarm((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("min_alarm",dev_name,"Attribute::set_min_alarm()"); (db < 0.0) ? set_min_alarm((DevUChar)(-db)) : set_min_alarm((DevUChar)db); break; } } else throw_err_data_type("min_alarm",dev_name,"Attribute::set_min_alarm()"); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_max_alarm() // Template specialization for data type DevEncoded and string // // description : // Sets maximum alarm attribute property. Throws exception in case the data type of provided property does not // match the attribute data type // // args : // in : // - new_min_alarm : The minimum alarm property to be set // //------------------------------------------------------------------------------------------------------------------- template <> inline void Attribute::set_max_alarm(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"Attribute::set_max_alarm()"); } template <> inline void Attribute::set_max_alarm(const string &new_max_alarm_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("max_alarm",d_name,"Attribute::set_max_alarm()"); string max_alarm_str_tmp = new_max_alarm_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("max_alarm",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("max_alarm",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_max_alarm_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_alarm",dev_name); avns_in_att(MAX_ALARM); } else if ((TG_strcasecmp(new_max_alarm_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_alarm_str.c_str(),class_def_val.c_str()) == 0)) { max_alarm_str_tmp = class_def_val; } else if (strlen(new_max_alarm_str.c_str()) == 0) { if (user_defaults) { max_alarm_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("max_alarm",dev_name); avns_in_att(MAX_ALARM); } } } else if(user_defaults) { if(TG_strcasecmp(new_max_alarm_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_alarm",dev_name); avns_in_att(MAX_ALARM); } else if ((TG_strcasecmp(new_max_alarm_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_alarm_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_max_alarm_str.c_str()) == 0)) max_alarm_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_max_alarm_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_max_alarm_str.c_str(),NotANumber) == 0) || (strlen(new_max_alarm_str.c_str()) == 0)) { set_value = false; avns_in_db("max_alarm",dev_name); avns_in_att(MAX_ALARM); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << max_alarm_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); set_max_alarm((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); set_max_alarm((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); set_max_alarm((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); set_max_alarm(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); set_max_alarm(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); (db < 0.0) ? set_max_alarm((DevUShort)(-db)) : set_max_alarm((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); (db < 0.0) ? set_max_alarm((DevUChar)(-db)) : set_max_alarm((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); (db < 0.0) ? set_max_alarm((DevULong)(-db)) : set_max_alarm((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); (db < 0.0) ? set_max_alarm((DevULong64)(-db)) : set_max_alarm((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("max_alarm",dev_name,"Attribute::set_max_alarm()"); (db < 0.0) ? set_max_alarm((DevUChar)(-db)) : set_max_alarm((DevUChar)db); break; } } else throw_err_data_type("max_alarm",dev_name,"Attribute::set_max_alarm()"); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_min_warning() // Template specialization for data type DevEncoded and string // // description : // Sets minimum warning attribute property. Throws exception in case the data type of provided property does not // match the attribute data type // // args : // in : // - new_min_alarm : The minimum alarm property to be set // //------------------------------------------------------------------------------------------------------------------- template <> inline void Attribute::set_min_warning(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"Attribute::set_min_warning()"); } template <> inline void Attribute::set_min_warning(const string &new_min_warning_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("min_warning",d_name,"Attribute::set_min_warning()"); string min_warning_str_tmp = new_min_warning_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("min_warning",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("min_warning",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_min_warning_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_warning",dev_name); avns_in_att(MIN_WARNING); } else if ((TG_strcasecmp(new_min_warning_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_warning_str.c_str(),class_def_val.c_str()) == 0)) { min_warning_str_tmp = class_def_val; } else if (strlen(new_min_warning_str.c_str()) == 0) { if (user_defaults) { min_warning_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("min_warning",dev_name); avns_in_att(MIN_WARNING); } } } else if(user_defaults) { if(TG_strcasecmp(new_min_warning_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_warning",dev_name); avns_in_att(MIN_WARNING); } else if ((TG_strcasecmp(new_min_warning_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_warning_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_min_warning_str.c_str()) == 0)) min_warning_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_min_warning_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_min_warning_str.c_str(),NotANumber) == 0) || (strlen(new_min_warning_str.c_str()) == 0)) { set_value = false; avns_in_db("min_warning",dev_name); avns_in_att(MIN_WARNING); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << min_warning_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); set_min_warning((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); set_min_warning((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); set_min_warning((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); set_min_warning(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); set_min_warning(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); (db < 0.0) ? set_min_warning((DevUShort)(-db)) : set_min_warning((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); (db < 0.0) ? set_min_warning((DevUChar)(-db)) : set_min_warning((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); (db < 0.0) ? set_min_warning((DevULong)(-db)) : set_min_warning((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); (db < 0.0) ? set_min_warning((DevULong64)(-db)) : set_min_warning((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("min_warning",dev_name,"Attribute::set_min_warning()"); (db < 0.0) ? set_min_warning((DevUChar)(-db)) : set_min_warning((DevUChar)db); break; } } else throw_err_data_type("min_warning",dev_name,"Attribute::set_min_warning()"); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_max_warning() // Template specialization for data type DevEncoded and string // // description : // Sets maximum warning attribute property. Throws exception in case the data type of provided property does not // match the attribute data type // // args : // in : // - new_min_alarm : The minimum alarm property to be set // //------------------------------------------------------------------------------------------------------------------- template <> inline void Attribute::set_max_warning(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"Attribute::set_max_warning()"); } template <> inline void Attribute::set_max_warning(const string &new_max_warning_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("max_warning",d_name,"Attribute::set_max_warning()"); string max_warning_str_tmp = new_max_warning_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("max_warning",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("max_warning",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_max_warning_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_warning",dev_name); avns_in_att(MAX_WARNING); } else if ((TG_strcasecmp(new_max_warning_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_warning_str.c_str(),class_def_val.c_str()) == 0)) { max_warning_str_tmp = class_def_val; } else if (strlen(new_max_warning_str.c_str()) == 0) { if (user_defaults) { max_warning_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("max_warning",dev_name); avns_in_att(MAX_WARNING); } } } else if(user_defaults) { if(TG_strcasecmp(new_max_warning_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_warning",dev_name); avns_in_att(MAX_WARNING); } else if ((TG_strcasecmp(new_max_warning_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_warning_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_max_warning_str.c_str()) == 0)) max_warning_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_max_warning_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_max_warning_str.c_str(),NotANumber) == 0) || (strlen(new_max_warning_str.c_str()) == 0)) { set_value = false; avns_in_db("max_warning",dev_name); avns_in_att(MAX_WARNING); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << max_warning_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); set_max_warning((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); set_max_warning((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); set_max_warning((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); set_max_warning(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); set_max_warning(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); (db < 0.0) ? set_max_warning((DevUShort)(-db)) : set_max_warning((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); (db < 0.0) ? set_max_warning((DevUChar)(-db)) : set_max_warning((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); (db < 0.0) ? set_max_warning((DevULong)(-db)) : set_max_warning((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); (db < 0.0) ? set_max_warning((DevULong64)(-db)) : set_max_warning((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("max_warning",dev_name,"Attribute::set_max_warning()"); (db < 0.0) ? set_max_warning((DevUChar)(-db)) : set_max_warning((DevUChar)db); break; } } else throw_err_data_type("max_warning",dev_name,"Attribute::set_max_warning()"); } } } // End of Tango namespace #endif // _ATTRIBUTE_SPEC_TPP tango-9.2.5a/lib/cpp/server/attrprop.tpp0000644023471100065110000001272713034745002015173 00000000000000//+================================================================================================================== // // file : AttrProp.tpp // // description : C++ source code for the MultiAttrProp class template methods // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-================================================================================================================== #ifndef _ATTRPROP_TPP #define _ATTRPROP_TPP namespace Tango { // // AttrProp template specialisation for DevUChar // template<> inline AttrProp::AttrProp(const DevUChar &value) : val(value), is_value(true), ext(Tango_nullptr) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); } template<> inline AttrProp& AttrProp::operator=(const DevUChar &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); val = value; is_value = true; return *this; } template<> inline void AttrProp::set_val(const DevUChar &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); val = value; is_value = true; } // // DoubleAttrProp template specialisation for DevUChar // template<> inline DoubleAttrProp::DoubleAttrProp(const vector &values) : val(values), is_value(true) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << (short)values[i]; // to represent the numeric value } str = st.str(); } template<> inline DoubleAttrProp::DoubleAttrProp(const DevUChar &value) : is_value(true) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); val.push_back(value); } template<> inline DoubleAttrProp& DoubleAttrProp::operator=(const vector &values) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << (short)values[i]; // to represent the numeric value } str = st.str(); val = values; is_value = true; return *this; } template<> inline DoubleAttrProp& DoubleAttrProp::operator=(const DevUChar &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); val.push_back(value); is_value = true; return *this; } template<> inline void DoubleAttrProp::set_val(const vector &values) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); for(size_t i = 0; i < values.size(); i++) { if(i > 0) st << ","; st << (short)values[i]; // to represent the numeric value } str = st.str(); val = values; is_value = true; } template<> inline void DoubleAttrProp::set_val(const DevUChar &value) { TangoSys_MemStream st; st.precision(TANGO_FLOAT_PRECISION); st << (short)value; // to represent the numeric value str = st.str(); val.push_back(value); is_value = true; } // // MultiAttrProp template specialisation for DevEncoded // template <> class MultiAttrProp { public: MultiAttrProp() {} string label; string description; string unit; string standard_unit; string display_unit; string format; AttrProp min_value; AttrProp max_value; AttrProp min_alarm; AttrProp max_alarm; AttrProp min_warning; AttrProp max_warning; AttrProp delta_t; AttrProp delta_val; AttrProp event_period; AttrProp archive_period; DoubleAttrProp rel_change; DoubleAttrProp abs_change; DoubleAttrProp archive_rel_change; DoubleAttrProp archive_abs_change; vector enum_labels; private: // // The extension class // class MultiAttrPropExt {}; #ifdef HAS_UNIQUE_PTR unique_ptr ext; // Class extension #else MultiAttrPropExt *ext; #endif }; } // End of Tango namespace #endif // _ATTRPROP_TPP tango-9.2.5a/lib/cpp/server/attrsetval.tpp0000644023471100065110000001742413034745001015507 00000000000000//+=================================================================================================================== // // file : attsetval.tpp // // description : C++ source code for the Attribute class template methods when they are not specialized and // related to attribute value setting // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _ATTRSETVAL_TPP #define _ATTRSETVAL_TPP #ifdef HAS_TYPE_TRAITS #include #endif namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_value // // description : // Set the attribute read value and quality. This method automatically set the date when it has been called // // This method is overloaded several times for all the supported attribute data type. Nevertheless, one // template method is defined (this one) which will be called for all data types with no overload. // This is the case for enumeration data type // // argument : // in : // - enum_ptr : The attribute read value // - x : The attribute x dimension (default is 1) // - y : The atttribute y dimension (default is 0) // - release : A flag set to true if memory must be de-allocated (default is false) // //------------------------------------------------------------------------------------------------------------------- template void Attribute::set_value(T *enum_ptr,long x,long y,bool release) { // // Throw exception if attribute data type is not correct // if (data_type != Tango::DEV_ENUM) { SAFE_DELETE(enum_ptr); stringstream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception(API_AttrOptProp,o.str(),"Attribute::set_value()"); } #ifdef HAS_UNDERLYING bool short_enum = is_same::type>::value; bool uns_int_enum = is_same::type>::value; if (short_enum == false && uns_int_enum == false) { SAFE_DELETE(enum_ptr); stringstream ss; ss << "Invalid enumeration type. Supported types are C++11 scoped enum with short as underlying data type\n"; ss << "or old enum"; Except::throw_exception(API_IncompatibleArgumentType,ss.str(),"Attribute::set_value()"); } #endif // HAS_UNDERLYING // // Check if the input type is an enum and if it is from the valid type // #ifdef HAS_TYPE_TRAITS if (is_enum::value == false) { SAFE_DELETE(enum_ptr); Except::throw_exception(API_IncompatibleArgumentType, "The input argument data type is not an enumeration", "Attribute::set_value()"); } #endif // HAS_TYPE_TRAITS // // Check if enum labels are defined // if (enum_labels.size() == 0) { SAFE_DELETE(enum_ptr); stringstream ss; ss << "Attribute " << name << " data type is enum but no enum labels are defined!"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } // // Check enum type // DeviceImpl *dev = get_att_device(); Tango::DeviceClass *dev_class = dev->get_device_class(); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); if (att.same_type(typeid(T)) == false) { SAFE_DELETE(enum_ptr); stringstream ss; ss << "Invalid enumeration type. Requested enum type is " << att.get_enum_type(); Except::throw_exception(API_IncompatibleArgumentType,ss.str(),"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(enum_ptr); stringstream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception(API_AttrOptProp,o.str(),"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(enum_ptr,name); } // // If the data is wanted from the DevState command, store it in a sequence. If the attribute has an associated // writable attribute, store data in a temporary buffer (the write value must be added before the data is sent // back to the caller) // if (data_size > enum_nb) { if (enum_nb != 0) delete [] loc_enum_ptr; loc_enum_ptr = new short [data_size]; enum_nb = data_size; } short max_val = (short)enum_labels.size() - 1; for (int i = 0;i < data_size;i++) { loc_enum_ptr[i] = (short)enum_ptr[i]; if (loc_enum_ptr[i] < 0 || loc_enum_ptr[i] > max_val) { SAFE_DELETE(enum_ptr); enum_nb = 0; stringstream ss; ss << "Wrong value for attribute " << name; ss << ". Element " << i << " (value = " << loc_enum_ptr[i] << ") is negative or above the limit defined by the enum (" << max_val << ")."; delete [] loc_enum_ptr; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } } SAFE_DELETE(enum_ptr); if (date == false) { value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,loc_enum_ptr,false); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_sh[0] = *loc_enum_ptr; } else { value.sh_seq = new Tango::DevVarShortArray(data_size); value.sh_seq->length(data_size); ::memcpy(value.sh_seq->get_buffer(false),loc_enum_ptr,data_size * sizeof(Tango::DevShort)); } } else { if ((data_format == Tango::SCALAR) && (release == true)) { value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,loc_enum_ptr,false); } else value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,loc_enum_ptr,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } template void Attribute::set_value_date_quality(T *p_data,time_t t,Tango::AttrQuality qual,long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ template void Attribute::set_value_date_quality(T *p_data,struct _timeb &t,Tango::AttrQuality qual,long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else template void Attribute::set_value_date_quality(T *p_data,struct timeval &t,Tango::AttrQuality qual,long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif } // End of Tango namespace #endif // _ATTRSETVAL_TPP tango-9.2.5a/lib/cpp/server/device_3.tpp0000644023471100065110000002753313034745001015001 00000000000000//=================================================================================================================== // // file : device_3.tpp // // description : C++ source code for the Device_3Impl class template methods // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //================================================================================================================== #ifndef _DEVICE_3_TPP #define _DEVICE_3_TPP namespace Tango { //+--------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::set_attribute_config_3_local // // description : // Set attribute configuration for both AttributeConfig_3 and AttributeConfig_5 // // args : // in : // - new_conf : The new attribute configuration // - dummy_arg : Dummy and unnused arg. Just to help template coding // - fwd_cb : Set to true if called from fwd att call back // - caller_idl : IDL release used by caller // //---------------------------------------------------------------------------------------------------------------- template void Device_3Impl::set_attribute_config_3_local(const T &new_conf,TANGO_UNUSED(const V &dummy_arg), bool fwd_cb,int caller_idl) { cout4 << "Entering Device_3Impl::set_attribute_config_3_local" << endl; // // Return exception if the device does not have any attribute // long nb_dev_attr = dev_attr->get_attr_nb(); if (nb_dev_attr == 0) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"The device does not have any attribute", (const char *)"Device_3Impl::set_attribute_config_3_local"); } // // Get some event related data // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; Tango::Util *tg = Tango::Util::instance(); // // Update attribute config first locally then in database // long nb_attr = new_conf.length(); long i; EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); try { for (i = 0;i < nb_attr;i++) { Attribute &attr = dev_attr->get_attr_by_name(new_conf[i].name); bool old_alarm = attr.is_alarmed().any(); // // Special case for forwarded attributes // if (attr.is_fwd_att() == true) { FwdAttribute &fwd_attr = static_cast(attr); if (fwd_cb == true) fwd_attr.set_att_config(new_conf[i]); else { fwd_attr.upd_att_config_base(new_conf[i].label.in()); fwd_attr.upd_att_config(new_conf[i]); } } else { attr.set_upd_properties(new_conf[i],device_name); } // // In case the attribute quality factor was set to ALARM, reset it to VALID // if ((attr.get_quality() == Tango::ATTR_ALARM) && (old_alarm == true) && (attr.is_alarmed().any() == false)) attr.set_quality(Tango::ATTR_VALID); // // Send the event // if (attr.use_notifd_event() == true) event_supplier_nd = tg->get_notifd_event_supplier(); else event_supplier_nd = NULL; if (attr.use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); else event_supplier_zmq = NULL; if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL)) { string tmp_name(new_conf[i].name); // // The event data has to be the new attribute conf which could be different than the one we received (in case some // of the parameters are reset to lib/user/class default value) // V mod_conf; attr.get_prop(mod_conf); const V *tmp_ptr = &mod_conf; Tango::AttributeConfig_3 conf3; Tango::AttributeConfig_5 conf5; AttributeConfig_3 *tmp_conf_ptr; AttributeConfig_5 *tmp_conf_ptr5; if (get_dev_idl_version() > 4) { vector cl_lib = attr.get_client_lib(ATTR_CONF_EVENT); if (caller_idl <= 4) { // // Even if device is IDL 5, the change has been done from one old client (IDL4) thus with AttributeConfig_3. // If a new client is listening to event, don't forget to send it. // for (size_t i = 0;i < cl_lib.size();i++) { if (cl_lib[i] == 5) { attr.AttributeConfig_3_2_AttributeConfig_5(mod_conf,conf5); attr.add_config_5_specific(conf5); tmp_conf_ptr5 = &conf5; ::memcpy(&(ad.attr_conf_5),&(tmp_conf_ptr5),sizeof(V *)); } else { ::memcpy(&(ad.attr_conf_3),&(tmp_ptr),sizeof(V *)); } if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (cl_lib[i] == 5) ad.attr_conf_5 = NULL; else ad.attr_conf_3 = NULL; } } else { for (size_t i = 0;i < cl_lib.size();i++) { if (cl_lib[i] < 5) { attr.AttributeConfig_5_2_AttributeConfig_3(mod_conf,conf3); tmp_conf_ptr = &conf3; ::memcpy(&(ad.attr_conf_3),&(tmp_conf_ptr),sizeof(V *)); } else { ::memcpy(&(ad.attr_conf_5),&(tmp_ptr),sizeof(V *)); } if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (cl_lib[i] == 5) ad.attr_conf_5 = NULL; else ad.attr_conf_3 = NULL; } } } else { ::memcpy(&(ad.attr_conf_3),&(tmp_ptr),sizeof(V *)); if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); } } } } catch (Tango::DevFailed &e) { // // Re build the list of "alarmable" attribute // dev_attr->get_alarm_list().clear(); for (long j = 0;j < nb_dev_attr;j++) { Attribute &att = dev_attr->get_attr_by_ind(j); if (att.is_alarmed().any() == true) { if (att.get_writable() != Tango::WRITE) dev_attr->get_alarm_list().push_back(j); } } // // Change the exception reason flag // TangoSys_OMemStream o; o << e.errors[0].reason; if (i != 0) o << "\nAll previous attribute(s) have been successfully updated"; if (i != (nb_attr - 1)) o << "\nAll remaining attribute(s) have not been updated"; o << ends; string s = o.str(); e.errors[0].reason = CORBA::string_dup(s.c_str()); throw; } // // Re build the list of "alarmable" attribute // dev_attr->get_alarm_list().clear(); for (i = 0;i < nb_dev_attr;i++) { Tango::Attribute &attr = dev_attr->get_attr_by_ind(i); Tango::AttrWriteType w_type = attr.get_writable(); if (attr.is_alarmed().any() == true) { if (w_type != Tango::WRITE) dev_attr->get_alarm_list().push_back(i); } } // // Return to caller // cout4 << "Leaving Device_3Impl::set_attribute_config_3_local" << endl; } template inline void Device_3Impl::error_from_devfailed(T &back,DevFailed &e,const char *na) { back.err_list = e.errors; back.quality = ATTR_INVALID; back.name = CORBA::string_dup(na); clear_att_dim(back); } template inline void Device_3Impl::error_from_errorlist(T &back,DevErrorList &e,const char *na) { back.err_list = e; back.quality = ATTR_INVALID; back.name = CORBA::string_dup(na); clear_att_dim(back); } template inline void Device_3Impl::one_error(T &back,const char *reas,const char *ori,string &mess,Attribute &att) { back.err_list.length(1); back.err_list[0].severity = Tango::ERR; back.err_list[0].reason = CORBA::string_dup(reas); back.err_list[0].origin = CORBA::string_dup(ori); back.err_list[0].desc = CORBA::string_dup(mess.c_str()); back.quality = Tango::ATTR_INVALID; back.name = CORBA::string_dup(att.get_name().c_str()); clear_att_dim(back); } template inline void Device_3Impl::one_error(T &back,const char *reas,const char *ori,string &mess,const char *na) { back.err_list.length(1); back.err_list[0].severity = Tango::ERR; back.err_list[0].reason = CORBA::string_dup(reas); back.err_list[0].origin = CORBA::string_dup(ori); back.err_list[0].desc = CORBA::string_dup(mess.c_str()); back.quality = Tango::ATTR_INVALID; back.name = CORBA::string_dup(na); clear_att_dim(back); } template inline void Device_3Impl::init_polled_out_data(T &back,V &att_val) { back.quality = att_val.quality; back.time = att_val.time; back.r_dim = att_val.r_dim; back.w_dim = att_val.w_dim; back.name = CORBA::string_dup(att_val.name); } template inline void Device_3Impl::init_out_data(T &back,Attribute &att,AttrWriteType &w_type) { back.time = att.get_when(); back.quality = att.get_quality(); back.name = CORBA::string_dup(att.get_name().c_str()); back.r_dim.dim_x = att.get_x(); back.r_dim.dim_y = att.get_y(); if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = dev_attr->get_w_attr_by_ind(att.get_assoc_ind()); back.w_dim.dim_x = assoc_att.get_w_dim_x(); back.w_dim.dim_y = assoc_att.get_w_dim_y(); } else { if ( w_type == Tango::WRITE) { // for write only attributes read and set value are the same! back.w_dim.dim_x = att.get_x(); back.w_dim.dim_y = att.get_y(); } else { // Tango::Read : read only attributes back.w_dim.dim_x = 0; back.w_dim.dim_y = 0; } } } template inline void Device_3Impl::init_out_data_quality(T &back,Attribute &att,AttrQuality qual) { back.time = att.get_when(); back.quality = qual; back.name = CORBA::string_dup(att.get_name().c_str()); back.r_dim.dim_x = att.get_x(); back.r_dim.dim_y = att.get_y(); back.r_dim.dim_x = 0; back.r_dim.dim_y = 0; back.w_dim.dim_x = 0; back.w_dim.dim_y = 0; } template inline void Device_3Impl::base_state2attr(T &back) { #ifdef _TG_WINDOWS_ struct _timeb after_win; _ftime(&after_win); back.time.tv_sec = (long)after_win.time; back.time.tv_usec = (long)after_win.millitm * 1000; back.time.tv_nsec = 0; #else struct timeval after; gettimeofday(&after,NULL); back.time.tv_sec = after.tv_sec; back.time.tv_usec = after.tv_usec; back.time.tv_nsec = 0; #endif back.quality = Tango::ATTR_VALID; back.name = CORBA::string_dup("State"); back.r_dim.dim_x = 1; back.r_dim.dim_y = 0; back.w_dim.dim_x = 0; back.w_dim.dim_y = 0; } template inline void Device_3Impl::base_status2attr(T &back) { #ifdef _TG_WINDOWS_ struct _timeb after_win; _ftime(&after_win); back.time.tv_sec = (long)after_win.time; back.time.tv_usec = (long)after_win.millitm * 1000; back.time.tv_nsec = 0; #else struct timeval after; gettimeofday(&after,NULL); back.time.tv_sec = after.tv_sec; back.time.tv_usec = after.tv_usec; back.time.tv_nsec = 0; #endif back.quality = Tango::ATTR_VALID; back.name = CORBA::string_dup("Status"); back.r_dim.dim_x = 1; back.r_dim.dim_y = 0; back.w_dim.dim_x = 0; back.w_dim.dim_y = 0; } } // End of Tango namespace #endif /* DEVICE_3_TPP */ tango-9.2.5a/lib/cpp/server/fwdattribute.tpp0000644023471100065110000002012113034745001016006 00000000000000//+=================================================================================================================== // // file : FWdAttribute.tpp // // description : C++ source code for the FwdAttribute class template methods when they are not specialized // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _FWDATTRIBUTE_TPP #define _FWDATTRIBUTE_TPP namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::set_local_attribute // // description : // Set value in the local attribute // // argument : // in : // - da : The DeviceAttribute coming from the root device read_attribute() // //-------------------------------------------------------------------------------------------------------------------- template void FwdAttribute::set_local_attribute(DeviceAttribute &da,T* &seq_ptr) { qual = da.get_quality(); TimeVal local_tv = da.get_date(); #ifdef _TG_WINDOWS_ tv.time = local_tv.tv_sec; tv.millitm = local_tv.tv_usec / 1000; #else tv.tv_sec = local_tv.tv_sec; tv.tv_usec = local_tv.tv_usec; #endif da >> seq_ptr; if (writable == READ_WRITE || writable == READ_WITH_WRITE) { set_write_value(seq_ptr->get_buffer() + da.get_nb_read(),da.get_written_dim_x(),da.get_written_dim_y()); } if (seq_ptr->release() == true) set_value_date_quality(seq_ptr->get_buffer(true),tv,qual,da.get_dim_x(),da.get_dim_y(),true); else set_value_date_quality(seq_ptr->get_buffer(),tv,qual,da.get_dim_x(),da.get_dim_y()); delete seq_ptr; } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::propagate_writen_data // // description : // Pass the data received by a writable attribute into a DeviceAttribute used to write another attribute // // argument : // in : // - attr : The attribute // - ptr : Intermediate pointer // - seq_ptr : Poniter to sequence used to fill in the DeviceAttribute // out : // - da : The DeviceAttribute coming from the root device read_attribute() // //-------------------------------------------------------------------------------------------------------------------- template void FwdAttribute::propagate_writen_data(DeviceAttribute &da,WAttribute &attr,T *&ptr,V *&seq_ptr) { attr.get_write_value(const_cast(ptr)); int data_length = attr.get_write_value_length(); long w_dim_x = attr.get_w_dim_x(); long w_dim_y = attr.get_w_dim_y(); seq_ptr = new V(data_length,data_length,ptr,false); da.insert(seq_ptr,w_dim_x,w_dim_y); } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::new_att_conf_base // // description : // // // argument : // in : // - conf : The new attribute configuration // // return : // True if the new configuration is not the same than the actual one. Return false otherwise // //-------------------------------------------------------------------------------------------------------------------- template bool FwdAttribute::new_att_conf_base(const T &conf) { if (string(conf.name.in()) != name) return true; if (conf.writable != writable) return true; if (conf.data_format != data_format) return true; if (conf.data_type != data_type) return true; if (string(conf.description.in()) != description) return true; if (string(conf.unit.in()) != unit) return true; if (string(conf.standard_unit.in()) != standard_unit) return true; if (string(conf.display_unit.in()) != display_unit) return true; if (string(conf.format.in()) != format) return true; if (string(conf.min_value.in()) != min_value_str) return true; if (string(conf.max_value.in()) != max_value_str) return true; if (conf.level != disp_level) return true; if (conf.writable_attr_name.in() != writable_attr_name) return true; if (string(conf.att_alarm.min_alarm.in()) != min_alarm_str) return true; if (string(conf.att_alarm.max_alarm.in()) != max_alarm_str) return true; if (string(conf.att_alarm.min_warning.in()) != min_warning_str) return true; if (string(conf.att_alarm.max_warning.in()) != max_warning_str) return true; string tmp_prop(conf.att_alarm.delta_t); if (tmp_prop == AlrmValueNotSpec) { if (delta_t_str != "0") return true; } else { if (tmp_prop != delta_t_str) return true; } tmp_prop = conf.att_alarm.delta_val; if (tmp_prop == AlrmValueNotSpec) { if (delta_val_str != AlrmValueNotSpec) return true; } else { if (tmp_prop != delta_val_str) return true; } double tmp_array[2]; // // rel_change // tmp_prop = conf.event_prop.ch_event.rel_change; if (tmp_prop == AlrmValueNotSpec) { if (rel_change[0] != INT_MAX || rel_change[1] != INT_MAX) return true; } else { if (rel_change[0] == INT_MAX && rel_change[1] == INT_MAX) return true; else { convert_event_prop(tmp_prop,tmp_array); if (tmp_array[0] != rel_change[0] || tmp_array[1] != rel_change[1]) return true; } } // // abs_change // tmp_prop = conf.event_prop.ch_event.abs_change; if (tmp_prop == AlrmValueNotSpec) { if (abs_change[0] != INT_MAX || abs_change[1] != INT_MAX) return true; } else { if (abs_change[0] == INT_MAX && abs_change[1] == INT_MAX) return true; else { convert_event_prop(tmp_prop,tmp_array); if (tmp_array[0] != abs_change[0] || tmp_array[1] != abs_change[1]) return true; } } // // archive rel_change // tmp_prop = conf.event_prop.arch_event.rel_change; if (tmp_prop == AlrmValueNotSpec) { if (archive_rel_change[0] != INT_MAX || archive_rel_change[1] != INT_MAX) return true; } else { if (archive_rel_change[0] == INT_MAX && archive_rel_change[1] == INT_MAX) return true; else { convert_event_prop(tmp_prop,tmp_array); if (tmp_array[0] != archive_rel_change[0] || tmp_array[1] != archive_rel_change[1]) return true; } } // // archive abs_change // tmp_prop = conf.event_prop.arch_event.abs_change; if (tmp_prop == AlrmValueNotSpec) { if (archive_abs_change[0] != INT_MAX || archive_abs_change[1] != INT_MAX) return true; } else { if (archive_abs_change[0] == INT_MAX && archive_abs_change[1] == INT_MAX) return true; else { convert_event_prop(tmp_prop,tmp_array); if (tmp_array[0] != archive_abs_change[0] || tmp_array[1] != archive_abs_change[1]) return true; } } // // event period // tmp_prop = conf.event_prop.per_event.period; if (tmp_prop == AlrmValueNotSpec) { if (event_period != DEFAULT_EVENT_PERIOD) return true; } else { stringstream ss; int tmp_per; ss << tmp_prop; ss >> tmp_per; if (tmp_per != event_period) return true; } // // archive event period // tmp_prop = conf.event_prop.arch_event.period; if (tmp_prop == AlrmValueNotSpec) { if (archive_period != INT_MAX) return true; } else { stringstream ss; int tmp_per; ss << tmp_prop; ss >> tmp_per; if (tmp_per != archive_period) return true; } return false; } } // End of Tango namespace #endif // _FWDATTRIBUTE_TPP tango-9.2.5a/lib/cpp/server/fwdattribute_spec.tpp0000644023471100065110000000573213034745001017033 00000000000000//+=================================================================================================================== // // file : fwdattribute_spec.tpp // // description : C++ source code for the FwdAttribute class template methods specialization // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _FWDATTRIBUTE_SPEC_TPP #define _FWDATTRIBUTE_SPEC_TPP namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::propagate_writen_data // // description : // Pass the data received by a writable attribute into a DeviceAttribute used to write another attribute // Specialization for string data type. // // argument : // in : // - attr : The attribute // - ptr : Intermediate pointer // - seq_ptr : Poniter to sequence used to fill in the DeviceAttribute // out : // - da : The DeviceAttribute coming from the root device read_attribute() // //-------------------------------------------------------------------------------------------------------------------- template<> void FwdAttribute::propagate_writen_data(DeviceAttribute &da,WAttribute &attr,ConstDevString *&ptr,DevVarStringArray *&seq_ptr) { const ConstDevString *tmp_ptr = const_cast(ptr); attr.get_write_value(tmp_ptr); long data_length = attr.get_write_value_length(); long w_dim_x = attr.get_w_dim_x(); long w_dim_y = attr.get_w_dim_y(); seq_ptr = new DevVarStringArray(data_length,data_length,const_cast(tmp_ptr),false); da.insert(seq_ptr,w_dim_x,w_dim_y); } template<> void FwdAttribute::propagate_writen_data(DeviceAttribute &da,WAttribute &attr,DevEncoded *&ptr,DevVarEncodedArray *&seq_ptr) { attr.get_write_value(const_cast(ptr)); int data_length = attr.get_write_value_length(); seq_ptr = new DevVarEncodedArray(data_length,data_length,ptr,false); da << seq_ptr; } } // End of Tango namespace #endif // _FWDATTRIBUTE_SPEC_TPP tango-9.2.5a/lib/cpp/server/pipe.tpp0000644023471100065110000000432313034745001014245 00000000000000 //+================================================================================================================== // // file : Pipe.tpp // // description : C++ source code for the template methods of the Pipe class. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 25781 $ // //-================================================================================================================== #ifndef _PIPE_TPP #define _PIPE_TPP namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : << // // description : // Helper function to ease data insertion into Pipe root blob // //------------------------------------------------------------------------------------------------------------------- template Pipe &operator<<(Pipe &_dp,T &datum) { _dp.get_blob().operator<<(datum); _dp.set_value_flag(true); return _dp; } template Pipe &operator<<(Pipe &_dp,T *datum) { _dp.get_blob().operator<<(datum); _dp.set_value_flag(true); return _dp; } template Pipe &operator<<(Pipe &_dp,DataElement &datum) { _dp.get_blob().set_current_delt_name(datum.name); _dp.get_blob().operator<<(datum.value); _dp.set_value_flag(true); return _dp; } } // End of Tango namespace #endif // _PIPE_TPP tango-9.2.5a/lib/cpp/server/pollext.tpp0000644023471100065110000005061213034745002015002 00000000000000//==================================================================================================================== // // file : PollExt.tpp // // description : Template method decleration for classes used by the method dedicated // to fill the polling buffer for command or attributes. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //=================================================================================================================== #ifndef _POLLEXT_TPP #define _POLLEXT_TPP #include namespace Tango { //============================================================================= // // Attribute related class // // description : These classes are used when the user want to fill // attribute polling buffer // //============================================================================= //============================================================================= // // The AttrData class // // // description : This class is used to store all the data needed to build // an attribute value. // //============================================================================= template inline AttrData::AttrData(const T *p): ptr(p),wr_x(0),wr_y(0),wr_ptr(NULL) { qual = Tango::ATTR_VALID; x = 1; y = 0; release = false; } template inline AttrData::AttrData(const T *p,Tango::AttrQuality q): ptr(p),qual(q),wr_x(0),wr_y(0),wr_ptr(NULL) { x = 1; y = 0; release = false; } template inline AttrData::AttrData(const T *p,Tango::AttrQuality q,bool rel): ptr(p),qual(q),release(rel),wr_x(0),wr_y(0),wr_ptr(NULL) { x = 1; y = 0; } template inline AttrData::AttrData(const T *p,const T *wr_p): ptr(p),wr_y(0),wr_ptr(wr_p) { qual = Tango::ATTR_VALID; x = 1; y = 0; wr_x =1 ; release = false; } template inline AttrData::AttrData(const T *p,const T *wr_p,Tango::AttrQuality q): ptr(p),qual(q),wr_y(0),wr_ptr(wr_p) { x = 1; y = 0; wr_x = 1; release = false; } template inline AttrData::AttrData(const T *p,const T *wr_p,Tango::AttrQuality q,bool rel): ptr(p),qual(q),release(rel),wr_y(0),wr_ptr(wr_p) { x = 1; y = 0; wr_x = 1; } // For spectrum template inline AttrData::AttrData(const T *p,long nb): ptr(p),x(nb),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM_X(); qual = Tango::ATTR_VALID; y = 0; release = false; } template inline AttrData::AttrData(const T *p,long nb,Tango::AttrQuality q): ptr(p),qual(q),x(nb),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM_X(); y = 0; release = false; } template inline AttrData::AttrData(const T *p,long nb,Tango::AttrQuality q,bool rel): ptr(p),qual(q),x(nb),release(rel),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM_X(); y = 0; } template inline AttrData::AttrData(const T *p,long nb,const T *wr_p,long wr_nb): ptr(p),x(nb),wr_x(wr_nb),wr_y(0),wr_ptr(wr_p) { __CHECK_DIM_X(); qual = Tango::ATTR_VALID; y = 0; release = false; } template inline AttrData::AttrData(const T *p,long nb,const T *wr_p,long wr_nb,Tango::AttrQuality q): ptr(p),qual(q),x(nb),wr_x(wr_nb),wr_y(0),wr_ptr(wr_p) { __CHECK_DIM_X(); y = 0; release = false; } template inline AttrData::AttrData(const T *p,long nb,const T *wr_p,long wr_nb,Tango::AttrQuality q,bool rel): ptr(p),qual(q),x(nb),release(rel),wr_x(wr_nb),wr_y(0),wr_ptr(wr_p) { __CHECK_DIM_X(); y = 0; } // For image template inline AttrData::AttrData(const T *p,long nb,long nb2): ptr(p),x(nb),y(nb2),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM(); qual = Tango::ATTR_VALID; release = false; } template inline AttrData::AttrData(const T *p,long nb,long nb2,Tango::AttrQuality q): ptr(p),qual(q),x(nb),y(nb2),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM(); release = false; } template inline AttrData::AttrData(const T *p,long nb,long nb2,Tango::AttrQuality q,bool rel): ptr(p),qual(q), x(nb),y(nb2),release(rel),wr_x(0),wr_y(0),wr_ptr(NULL) { __CHECK_DIM(); } template inline AttrData::AttrData(const T *p,long nb,long nb2,const T *wr_p,long wr_nb,long wr_nb2): ptr(p),x(nb),y(nb2),wr_x(wr_nb),wr_y(wr_nb2),wr_ptr(wr_p) { __CHECK_DIM(); qual = Tango::ATTR_VALID; release = false; } template inline AttrData::AttrData(const T *p,long nb,long nb2,const T *wr_p,long wr_nb,long wr_nb2,Tango::AttrQuality q): ptr(p),qual(q),x(nb),y(nb2),wr_x(wr_nb),wr_y(wr_nb2),wr_ptr(wr_p) { __CHECK_DIM(); release = false; } template inline AttrData::AttrData(const T *p,long nb,long nb2,const T *wr_p,long wr_nb,long wr_nb2,Tango::AttrQuality q,bool rel): ptr(p),qual(q), x(nb),y(nb2),release(rel),wr_x(wr_nb),wr_y(wr_nb2),wr_ptr(wr_p) { __CHECK_DIM(); } //============================================================================= // // The TimedAttrData class // // // description : This class inherits from the AttrData class and adds // a date to all the data contains in the AttrData // class // //============================================================================= template inline TimedAttrData::TimedAttrData(const T *p_data,time_t when): AttrData(p_data) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,const T *p_wr_data,time_t when): AttrData(p_data,p_wr_data) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,Tango::AttrQuality qual,time_t when): AttrData(p_data,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,time_t when): AttrData(p_data,p_wr_data,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,p_wr_data,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,struct timeval when): AttrData(p_data),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,const T *p_wr_data,struct timeval when): AttrData(p_data,p_wr_data),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,Tango::AttrQuality qual,struct timeval when): AttrData(p_data,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,TANGO_UNUSED(const T *p_wr_data),Tango::AttrQuality qual,struct timeval when): AttrData(p_data,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,qual,rel),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,const T *p_wr_data,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,p_wr_data,qual,rel),t_val(when) {} // For spectrum template inline TimedAttrData::TimedAttrData(const T *p_data,long x,time_t when): AttrData(p_data,x) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,time_t when): AttrData(p_data,x,p_wr_data,x_wr) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,time_t when): AttrData(p_data,x,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,time_t when): AttrData(p_data,x,p_wr_data,x_wr,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,x,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,x,p_wr_data,x_wr,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,struct timeval when): AttrData(p_data,x),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,struct timeval when): AttrData(p_data,x,p_wr_data,x_wr),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,struct timeval when): AttrData(p_data,x,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,struct timeval when): AttrData(p_data,x,p_wr_data,x_wr,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,x,qual,rel),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,const T *p_wr_data,long x_wr,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,x,p_wr_data,x_wr,qual,rel),t_val(when) {} // For image template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,time_t when): AttrData(p_data,x,y) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,time_t when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,time_t when): AttrData(p_data,x,y,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,time_t when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr,qual) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,x,y,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,bool rel,time_t when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr,qual,rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,struct timeval when): AttrData(p_data,x,y),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,struct timeval when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,struct timeval when): AttrData(p_data,x,y,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,struct timeval when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr,qual),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,x,y,qual,rel),t_val(when) {} template inline TimedAttrData::TimedAttrData(const T *p_data,long x,long y,const T *p_wr_data,long x_wr,long y_wr,Tango::AttrQuality qual,bool rel,struct timeval when): AttrData(p_data,x,y,p_wr_data,x_wr,y_wr,qual,rel),t_val(when) {} // For error template inline TimedAttrData::TimedAttrData(DevErrorList &errs,time_t when): AttrData(errs) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedAttrData::TimedAttrData(DevErrorList &errs,timeval when): AttrData(errs),t_val(when) {} #ifdef _TG_WINDOWS_ template inline TimedAttrData::TimedAttrData(const T *p,struct _timeb t): AttrData(p) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,Tango::AttrQuality q,struct _timeb t): AttrData(p,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,const T *p_wr_data,struct _timeb t): AttrData(p,p_wr_data) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,const T *p_wr_data,Tango::AttrQuality q,struct _timeb t): AttrData(p,p_wr_data,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,const T *p_wr_data,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,p_wr_data,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,struct _timeb t): AttrData(p,nb) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,Tango::AttrQuality q,struct _timeb t): AttrData(p,nb,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,nb,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,struct _timeb t): AttrData(p,nb,p_wr_data,nb_wr) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,Tango::AttrQuality q,struct _timeb t): AttrData(p,nb,p_wr_data,nb_wr,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,const T *p_wr_data,long nb_wr,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,nb,p_wr_data,nb_wr,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,struct _timeb t): AttrData(p,nb,nb2) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,Tango::AttrQuality q,struct _timeb t): AttrData(p,nb,nb2,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,nb,nb2,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,struct _timeb t): AttrData(p,nb,nb2,p_wr_data,nb_wr,nb2_wr) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,Tango::AttrQuality q,struct _timeb t): AttrData(p,nb,nb2,p_wr_data,nb_wr,nb2_wr,q) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } template inline TimedAttrData::TimedAttrData(const T *p,long nb,long nb2,const T *p_wr_data,long nb_wr,long nb2_wr,Tango::AttrQuality q,bool rel,struct _timeb t): AttrData(p,nb,nb2,p_wr_data,nb_wr,nb2_wr,q,rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm*1000; } #endif //============================================================================= // // The AttrHistoryStack class // // // description : This class is simply a wrapper above a vector of // TimedAttrData class. It is used to pass an attribute // value history which will be stored in the polling // buffer // //============================================================================= template inline void AttrHistoryStack::push(TimedAttrData const &elt) { hist.push_back(elt); } template inline vector > &AttrHistoryStack::get_data() { return hist; } //============================================================================= // // Command related class // // description : These classes are used when the user want to fill // command polling buffer // //============================================================================= //============================================================================= // // The TimedCmdData class // // // description : This class is used to store all the data needed to build // a command value plus a date. // //============================================================================= template inline TimedCmdData::TimedCmdData(T *p_data,time_t when): ptr(p_data),release(false) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedCmdData::TimedCmdData(T *p_data,bool rel,time_t when): ptr(p_data),release(rel) { t_val.tv_sec = time_t_2_long(when); t_val.tv_usec = 0; } template inline TimedCmdData::TimedCmdData(T *p_data,struct timeval when): ptr(p_data),t_val(when),release(false) {} template inline TimedCmdData::TimedCmdData(T *p_data,bool rel,struct timeval when): ptr(p_data),t_val(when),release(rel) {} #ifdef _TG_WINDOWS_ template inline TimedCmdData::TimedCmdData(T *p,struct _timeb t): ptr(p),release(false) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm * 1000; } template inline TimedCmdData::TimedCmdData(T *p,bool rel,struct _timeb t): ptr(p),release(rel) { t_val.tv_sec = t.time; t_val.tv_usec = t.millitm * 1000; } #endif //============================================================================= // // The CmdHistoryStack class // // // description : This class is simply a wrapper above a vector of // TimedCmdData class. It is used to pass a command // value history which will be stored in the polling // buffer // //============================================================================= template inline void CmdHistoryStack::push(Tango::TimedCmdData const &elt) { hist.push_back(elt); } template inline vector > & CmdHistoryStack::get_data() { return hist; } } // End of Tango namespace #endif /* _POLLOBJ_ */ tango-9.2.5a/lib/cpp/server/pollring.tpp0000644023471100065110000005642713034745001015152 00000000000000//+================================================================================================================== // // file : PollRing.tpp // // description : C++ source code for the PollRing class template methods // // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-================================================================================================================== namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method : // PollRing::force_copy_data // // description : // Since IDL 4, attributes are transferred on the net using a IDL union. In some cases, the sequence within the // union simply points to the user data (no copy), therefore, this method force the user data to be copied // To do this copy we: // 1 - Really copy the data within a temporary sequence // 2 - Force memory freeing (if required by user) using the // union sequence replace call // 3 - Transfer the data from the temporary sequence within the // union sequence using again the sequence replace call // in order not to trigger a real data copy // // argument : // in : // - attr_value : The attribute value // //------------------------------------------------------------------------------------------------------------------ template void PollRing::force_copy_data(T *attr_value) { for (unsigned long loop = 0;loop < attr_value->length();loop++) { switch ((*attr_value)[loop].value._d()) { case ATT_BOOL: { DevVarBooleanArray &union_seq = (*attr_value)[loop].value.bool_att_value(); DevVarBooleanArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_SHORT: { DevVarShortArray &union_seq = (*attr_value)[loop].value.short_att_value(); DevVarShortArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_LONG: { DevVarLongArray &union_seq = (*attr_value)[loop].value.long_att_value(); DevVarLongArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_LONG64: { DevVarLong64Array &union_seq = (*attr_value)[loop].value.long64_att_value(); DevVarLong64Array tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_FLOAT: { DevVarFloatArray &union_seq = (*attr_value)[loop].value.float_att_value(); DevVarFloatArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_DOUBLE: { DevVarDoubleArray &union_seq = (*attr_value)[loop].value.double_att_value(); DevVarDoubleArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_UCHAR: { DevVarCharArray &union_seq = (*attr_value)[loop].value.uchar_att_value(); DevVarCharArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_USHORT: { DevVarUShortArray &union_seq = (*attr_value)[loop].value.ushort_att_value(); DevVarUShortArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_ULONG: { DevVarULongArray &union_seq = (*attr_value)[loop].value.ulong_att_value(); DevVarULongArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_ULONG64: { DevVarULong64Array &union_seq = (*attr_value)[loop].value.ulong64_att_value(); DevVarULong64Array tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case ATT_STRING: { const DevVarStringArray &union_seq = (*attr_value)[loop].value.string_att_value(); DevVarStringArray tmp_seq = union_seq; (const_cast(union_seq)).replace(0,0,NULL,true); (*attr_value)[loop].value.string_att_value(tmp_seq); } break; case ATT_STATE: { DevVarStateArray &union_seq = (*attr_value)[loop].value.state_att_value(); DevVarStateArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); unsigned long len = tmp_seq.length(); union_seq.replace(len,len,tmp_seq.get_buffer(true),true); } break; case DEVICE_STATE: case ATT_NO_DATA: break; case ATT_ENCODED: { DevVarEncodedArray &union_seq = (*attr_value)[loop].value.encoded_att_value(); DevVarEncodedArray tmp_seq(union_seq); union_seq.replace(0,0,NULL,true); union_seq.length(tmp_seq.length()); union_seq[0].encoded_format = CORBA::string_dup(tmp_seq[0].encoded_format); unsigned long nb_data = tmp_seq[0].encoded_data.length(); union_seq[0].encoded_data.replace(nb_data,nb_data,tmp_seq[0].encoded_data.get_buffer(true),true); if (tmp_seq.length() == 2) { union_seq[1].encoded_format = CORBA::string_dup(tmp_seq[1].encoded_format); unsigned long nb_data = tmp_seq[1].encoded_data.length(); union_seq[1].encoded_data.replace(nb_data,nb_data,tmp_seq[1].encoded_data.get_buffer(true),true); } } break; } } } template void PollRing::get_attr_history(long n,T *ptr,long type) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; // // Compute the size of the global sequence and the error numbers // long seq_size = 0; long error_nb = 0; long vers; if (ring[index].attr_value_4 == Tango_nullptr) vers = 5; else vers = 4; for (i = 0;i < n;i++) { if (ring[index].except == NULL) { if(vers == 4) { int r_dim_x = (*ring[index].attr_value_4)[0].r_dim.dim_x; int r_dim_y = (*ring[index].attr_value_4)[0].r_dim.dim_y; int w_dim_x = (*ring[index].attr_value_4)[0].w_dim.dim_x; int w_dim_y = (*ring[index].attr_value_4)[0].w_dim.dim_y; int data_length; (r_dim_y == 0) ? data_length = r_dim_x : data_length = r_dim_x * r_dim_y; (w_dim_y == 0) ? data_length += w_dim_x : data_length += (w_dim_x * w_dim_y); seq_size = seq_size + data_length; } else { int r_dim_x = (*ring[index].attr_value_5)[0].r_dim.dim_x; int r_dim_y = (*ring[index].attr_value_5)[0].r_dim.dim_y; int w_dim_x = (*ring[index].attr_value_5)[0].w_dim.dim_x; int w_dim_y = (*ring[index].attr_value_5)[0].w_dim.dim_y; int data_length; (r_dim_y == 0) ? data_length = r_dim_x : data_length = r_dim_x * r_dim_y; (w_dim_y == 0) ? data_length += w_dim_x : data_length += (w_dim_x * w_dim_y); seq_size = seq_size + data_length; } } else error_nb++; if (index == 0) index = max_elt; index--; } // // Now, we need to build the data transfer structure // AttrQuality last_quality; int quals_length = 1; AttributeDim last_dim_read; int read_dims_length = 1; AttributeDim last_dim_write; int write_dims_length = 1; DevErrorList last_err_list; int errors_length = 1; last_dim_read.dim_x = -1; last_dim_read.dim_y = -1; last_dim_write.dim_x = -1; last_dim_write.dim_y = -1; unsigned int ind_in_seq = 0; Tango::DevVarDoubleArray *new_tmp_db = NULL; Tango::DevVarShortArray *new_tmp_sh = NULL; Tango::DevVarLongArray *new_tmp_lg = NULL; Tango::DevVarLong64Array *new_tmp_lg64 = NULL; Tango::DevVarStringArray *new_tmp_str = NULL; Tango::DevVarFloatArray *new_tmp_fl = NULL; Tango::DevVarBooleanArray *new_tmp_boo = NULL; Tango::DevVarUShortArray *new_tmp_ush = NULL; Tango::DevVarCharArray *new_tmp_uch = NULL; Tango::DevVarULongArray *new_tmp_ulg = NULL; Tango::DevVarULong64Array *new_tmp_ulg64 = NULL; Tango::DevVarStateArray *new_tmp_state = NULL; Tango::DevVarEncodedArray *new_tmp_enc = NULL; // // Read buffer // bool previous_no_data = true; bool no_data = true; last_quality = Tango::ATTR_VALID; index = insert_elt; if (index == 0) index = max_elt; index--; for (i = 0;i < n;i++) { previous_no_data = no_data; no_data = false; // // Copy date in output structure // In no error case, we take date from the attr_valie_X stucture and here the date is not biased // if (ring[index].except == NULL) { if (vers == 4) { ptr->dates[seq_index].tv_sec = (*ring[index].attr_value_4)[0].time.tv_sec; ptr->dates[seq_index].tv_usec = (*ring[index].attr_value_4)[0].time.tv_usec; } else { ptr->dates[seq_index].tv_sec = (*ring[index].attr_value_5)[0].time.tv_sec; ptr->dates[seq_index].tv_usec = (*ring[index].attr_value_5)[0].time.tv_usec; } } else { ptr->dates[seq_index].tv_sec = ring[index].when.tv_sec + DELTA_T; ptr->dates[seq_index].tv_usec = ring[index].when.tv_usec; } ptr->dates[seq_index].tv_nsec = 0; // // Copy element only if they are different than the previous one // First, for quality factor // if (ring[index].except == NULL) { AttrQuality qu; if (vers == 4) qu = (*ring[index].attr_value_4)[0].quality; else qu = (*ring[index].attr_value_5)[0].quality; if ((quals_length == 1) || (qu != last_quality)) { if (vers == 4) last_quality = (*ring[index].attr_value_4)[0].quality; else last_quality = (*ring[index].attr_value_5)[0].quality; ptr->quals.length(quals_length); ptr->quals[quals_length - 1] = last_quality; ptr->quals_array.length(quals_length); ptr->quals_array[quals_length - 1].start = n - (i + 1); ptr->quals_array[quals_length - 1].nb_elt = 1; quals_length++; if (last_quality == Tango::ATTR_INVALID) { previous_no_data = no_data; no_data = true; } } else { ptr->quals_array[quals_length - 2].nb_elt++; if (last_quality == Tango::ATTR_INVALID) { previous_no_data = no_data; no_data = true; } } // // The read dimension // bool check = false; if (vers == 4) { if (((*ring[index].attr_value_4)[0].r_dim.dim_x == last_dim_read.dim_x) && ((*ring[index].attr_value_4)[0].r_dim.dim_y == last_dim_read.dim_y)) check = true; } else { if (((*ring[index].attr_value_5)[0].r_dim.dim_x == last_dim_read.dim_x) && ((*ring[index].attr_value_5)[0].r_dim.dim_y == last_dim_read.dim_y)) check = true; } if (check == true) { ptr->r_dims_array[read_dims_length - 2].nb_elt++; } else { if (vers == 4) last_dim_read = (*ring[index].attr_value_4)[0].r_dim; else last_dim_read = (*ring[index].attr_value_5)[0].r_dim; ptr->r_dims.length(read_dims_length); ptr->r_dims[read_dims_length - 1] = last_dim_read; ptr->r_dims_array.length(read_dims_length); ptr->r_dims_array[read_dims_length - 1].start = n - (i + 1); ptr->r_dims_array[read_dims_length - 1].nb_elt = 1; read_dims_length++; } // // The write dimension // check = false; if (vers == 4) { if (((*ring[index].attr_value_4)[0].w_dim.dim_x == last_dim_write.dim_x) && ((*ring[index].attr_value_4)[0].w_dim.dim_y == last_dim_write.dim_y)) check = true; } else { if (((*ring[index].attr_value_5)[0].w_dim.dim_x == last_dim_write.dim_x) && ((*ring[index].attr_value_5)[0].w_dim.dim_y == last_dim_write.dim_y)) check = true; } if (check == true) { ptr->w_dims_array[write_dims_length - 2].nb_elt++; } else { if (vers == 4) last_dim_write = (*ring[index].attr_value_4)[0].w_dim; else last_dim_write = (*ring[index].attr_value_5)[0].w_dim; ptr->w_dims.length(write_dims_length); ptr->w_dims[write_dims_length - 1] = last_dim_write; ptr->w_dims_array.length(write_dims_length); ptr->w_dims_array[write_dims_length - 1].start = n - (i + 1); ptr->w_dims_array[write_dims_length - 1].nb_elt = 1; write_dims_length++; } } else no_data = true; // // Error treatement // if (ring[index].except != NULL) { bool new_err = false; if (previous_no_data == true) { if (ring[index].except->errors.length() != last_err_list.length()) new_err = true; else { for (unsigned int k = 0;k < last_err_list.length();k++) { if (::strcmp(ring[index].except->errors[k].reason.in(),last_err_list[k].reason.in()) != 0) { new_err = true; break; } if (::strcmp(ring[index].except->errors[k].desc.in(),last_err_list[k].desc.in()) != 0) { new_err = true; break; } if (::strcmp(ring[index].except->errors[k].origin.in(),last_err_list[k].origin.in()) != 0) { new_err = true; break; } if (ring[index].except->errors[k].severity != last_err_list[k].severity) { new_err = true; break; } } } } else new_err = true; if (new_err == true) { if (ptr->errors.length() == 0) ptr->errors.length(error_nb); if (ptr->errors_array.length() == 0) ptr->errors_array.length(error_nb); last_err_list = ring[index].except->errors; ptr->errors[errors_length - 1] = last_err_list; ptr->errors_array[errors_length - 1].start = n - (i + 1); ptr->errors_array[errors_length - 1].nb_elt = 1; errors_length++; previous_no_data = no_data; no_data = true; } else { ptr->errors_array[errors_length - 2].nb_elt++; previous_no_data = no_data; no_data = true; } // // Due to compatibility with the old release, the polling thread stores the error // got when reading the attribute as an exception (same behaviour that what we had before IDL3) // This means that we have to manually add entry for the management of quality factor (set to INVALID), // r_dim and w_dim (set to 0) // if ((quals_length == 1) || (last_quality != Tango::ATTR_INVALID)) { last_quality = Tango::ATTR_INVALID; ptr->quals.length(quals_length); ptr->quals[quals_length - 1] = last_quality; ptr->quals_array.length(quals_length); ptr->quals_array[quals_length - 1].start = n - (i + 1); ptr->quals_array[quals_length - 1].nb_elt = 1; quals_length++; } else { ptr->quals_array[quals_length - 2].nb_elt++; } if ((last_dim_read.dim_x == 0) && (last_dim_read.dim_y == 0)) { ptr->r_dims_array[read_dims_length - 2].nb_elt++; } else { last_dim_read.dim_x = last_dim_read.dim_y = 0; ptr->r_dims.length(read_dims_length); ptr->r_dims[read_dims_length - 1] = last_dim_read; ptr->r_dims_array.length(read_dims_length); ptr->r_dims_array[read_dims_length - 1].start = n - (i + 1); ptr->r_dims_array[read_dims_length - 1].nb_elt = 1; read_dims_length++; } if ((last_dim_write.dim_x == 0) && (last_dim_write.dim_y == 0)) { ptr->w_dims_array[write_dims_length - 2].nb_elt++; } else { last_dim_write.dim_x = last_dim_write.dim_y = 0; ptr->w_dims.length(write_dims_length); ptr->w_dims[write_dims_length - 1] = last_dim_write; ptr->w_dims_array.length(write_dims_length); ptr->w_dims_array[write_dims_length - 1].start = n - (i + 1); ptr->w_dims_array[write_dims_length - 1].nb_elt = 1; write_dims_length++; } } // // Now, the data themselves // if (no_data == false) { // // Trick: The state when read as an attribute is not store within the Any as a sequence // To cover this case, we use the "type" data set to DEV_VOID when we are dealing with // the state as an attribute // AttrValUnion *union_ptr; if (vers == 4) union_ptr = &((*ring[index].attr_value_4)[0].value); else union_ptr = &((*ring[index].attr_value_5)[0].value); switch (type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { DevVarShortArray &tmp_seq = union_ptr->short_att_value(); if (new_tmp_sh == NULL) { new_tmp_sh = new DevVarShortArray(); new_tmp_sh->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_sh,tmp_seq,ind_in_seq); break; } case Tango::DEV_DOUBLE : { DevVarDoubleArray &tmp_seq = union_ptr->double_att_value(); if (new_tmp_db == NULL) { new_tmp_db = new DevVarDoubleArray(); new_tmp_db->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_db,tmp_seq,ind_in_seq); break; } case Tango::DEV_LONG : { DevVarLongArray &tmp_seq = union_ptr->long_att_value(); if (new_tmp_lg == NULL) { new_tmp_lg = new DevVarLongArray(); new_tmp_lg->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_lg,tmp_seq,ind_in_seq); break; } case Tango::DEV_LONG64 : { DevVarLong64Array &tmp_seq = union_ptr->long64_att_value(); if (new_tmp_lg64 == NULL) { new_tmp_lg64 = new DevVarLong64Array(); new_tmp_lg64->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_lg64,tmp_seq,ind_in_seq); break; } case Tango::DEV_STRING : { DevVarStringArray &tmp_seq = union_ptr->string_att_value(); if (new_tmp_str == NULL) { new_tmp_str = new DevVarStringArray(); new_tmp_str->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_str,tmp_seq,ind_in_seq); break; } case Tango::DEV_FLOAT : { DevVarFloatArray &tmp_seq = union_ptr->float_att_value(); if (new_tmp_fl == NULL) { new_tmp_fl = new DevVarFloatArray(); new_tmp_fl->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_fl,tmp_seq,ind_in_seq); break; } case Tango::DEV_BOOLEAN : { DevVarBooleanArray &tmp_seq = union_ptr->bool_att_value(); if (new_tmp_boo == NULL) { new_tmp_boo = new DevVarBooleanArray(); new_tmp_boo->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_boo,tmp_seq,ind_in_seq); break; } case Tango::DEV_USHORT : { DevVarUShortArray &tmp_seq = union_ptr->ushort_att_value(); if (new_tmp_ush == NULL) { new_tmp_ush = new DevVarUShortArray(); new_tmp_ush->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_ush,tmp_seq,ind_in_seq); break; } case Tango::DEV_UCHAR : { DevVarCharArray &tmp_seq = union_ptr->uchar_att_value(); if (new_tmp_uch == NULL) { new_tmp_uch = new DevVarUCharArray(); new_tmp_uch->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_uch,tmp_seq,ind_in_seq); break; } case Tango::DEV_ULONG : { DevVarULongArray &tmp_seq = union_ptr->ulong_att_value(); if (new_tmp_ulg == NULL) { new_tmp_ulg = new DevVarULongArray(); new_tmp_ulg->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_ulg,tmp_seq,ind_in_seq); break; } case Tango::DEV_ULONG64 : { DevVarULong64Array &tmp_seq = union_ptr->ulong64_att_value(); if (new_tmp_ulg64 == NULL) { new_tmp_ulg64 = new DevVarULong64Array(); new_tmp_ulg64->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_ulg64,tmp_seq,ind_in_seq); break; } case Tango::DEV_STATE : { DevVarStateArray &tmp_seq = union_ptr->state_att_value(); if (new_tmp_state == NULL) { new_tmp_state = new DevVarStateArray(); new_tmp_state->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_state,tmp_seq,ind_in_seq); break; } case Tango::DEV_VOID : { DevState tmp_state = union_ptr->dev_state_att(); if (new_tmp_state == NULL) { new_tmp_state = new DevVarStateArray(); new_tmp_state->length(seq_size); } ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_state,tmp_state,ind_in_seq); break; } case Tango::DEV_ENCODED : { DevVarEncodedArray &tmp_seq = union_ptr->encoded_att_value(); if (new_tmp_enc == NULL) { new_tmp_enc = new DevVarEncodedArray(); new_tmp_enc->length(seq_size); } ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_PTR_REF(new_tmp_enc,tmp_seq,ind_in_seq); break; } } } // // If it is the last point, insert the global sequence into the Any // if (i == (n - 1)) { if (errors_length != (error_nb + 1)) { ptr->errors.length(errors_length - 1); ptr->errors_array.length(errors_length - 1); } switch(type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if (new_tmp_sh != NULL) ptr->value <<= new_tmp_sh; break; case Tango::DEV_DOUBLE: if (new_tmp_db != NULL) ptr->value <<= new_tmp_db; break; case Tango::DEV_LONG: if (new_tmp_lg != NULL) ptr->value <<= new_tmp_lg; break; case Tango::DEV_LONG64: if (new_tmp_lg64 != NULL) ptr->value <<= new_tmp_lg64; break; case Tango::DEV_STRING: if (new_tmp_str != NULL) ptr->value <<= new_tmp_str; break; case Tango::DEV_FLOAT: if (new_tmp_fl != NULL) ptr->value <<= new_tmp_fl; break; case Tango::DEV_BOOLEAN: if (new_tmp_boo != NULL) ptr->value <<= new_tmp_boo; break; case Tango::DEV_USHORT: if (new_tmp_ush != NULL) ptr->value <<= new_tmp_ush; break; case Tango::DEV_UCHAR: if (new_tmp_uch != NULL) ptr->value <<= new_tmp_uch; break; case Tango::DEV_ULONG: if (new_tmp_ulg != NULL) ptr->value <<= new_tmp_ulg; break; case Tango::DEV_ULONG64: if (new_tmp_ulg64 != NULL) ptr->value <<= new_tmp_ulg64; break; case Tango::DEV_ENCODED: if (new_tmp_enc != NULL) ptr->value <<= new_tmp_enc; break; case Tango::DEV_STATE: case Tango::DEV_VOID: if (new_tmp_state != NULL) ptr->value <<= new_tmp_state; break; } } // // Manage indexes // if (index == 0) index = max_elt; index--; seq_index--; } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/pollthread.tpp0000644023471100065110000002232013034745001015443 00000000000000//+================================================================================================================== // // file : PollThread.tpp // // description : C++ source code for the Pollthread class template methods // // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-================================================================================================================== namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method : // PollThread::robb_data // // description : // // argument : // in : // - attr_value : The poor attribute value on which we are going to robb data // - new_attr_value : The robber // //------------------------------------------------------------------------------------------------------------------ template void PollThread::robb_data(T &attr_value,T &new_attr_value) { switch (attr_value.value._d()) { case ATT_BOOL: { DevVarBooleanArray &union_seq = attr_value.value.bool_att_value(); DevVarBooleanArray tmp_seq(1); new_attr_value.value.bool_att_value(tmp_seq); DevVarBooleanArray &new_union_seq = new_attr_value.value.bool_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_SHORT: { DevVarShortArray &union_seq = attr_value.value.short_att_value(); DevVarShortArray tmp_seq(1); new_attr_value.value.short_att_value(tmp_seq); DevVarShortArray &new_union_seq = new_attr_value.value.short_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_LONG: { DevVarLongArray &union_seq = attr_value.value.long_att_value(); DevVarLongArray tmp_seq(1); new_attr_value.value.long_att_value(tmp_seq); DevVarLongArray &new_union_seq = new_attr_value.value.long_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_LONG64: { DevVarLong64Array &union_seq = attr_value.value.long64_att_value(); DevVarLong64Array tmp_seq(1); new_attr_value.value.long64_att_value(tmp_seq); DevVarLong64Array &new_union_seq = new_attr_value.value.long64_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_FLOAT: { DevVarFloatArray &union_seq = attr_value.value.float_att_value(); DevVarFloatArray tmp_seq(1); new_attr_value.value.float_att_value(tmp_seq); DevVarFloatArray &new_union_seq = new_attr_value.value.float_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_DOUBLE: { DevVarDoubleArray &union_seq = attr_value.value.double_att_value(); DevVarDoubleArray tmp_seq(1); new_attr_value.value.double_att_value(tmp_seq); DevVarDoubleArray &new_union_seq = new_attr_value.value.double_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_UCHAR: { DevVarUCharArray &union_seq = attr_value.value.uchar_att_value(); DevVarUCharArray tmp_seq(1); new_attr_value.value.uchar_att_value(tmp_seq); DevVarUCharArray &new_union_seq = new_attr_value.value.uchar_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_USHORT: { DevVarUShortArray &union_seq = attr_value.value.ushort_att_value(); DevVarUShortArray tmp_seq(1); new_attr_value.value.ushort_att_value(tmp_seq); DevVarUShortArray &new_union_seq = new_attr_value.value.ushort_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_ULONG: { DevVarULongArray &union_seq = attr_value.value.ulong_att_value(); DevVarULongArray tmp_seq(1); new_attr_value.value.ulong_att_value(tmp_seq); DevVarULongArray &new_union_seq = new_attr_value.value.ulong_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_ULONG64: { DevVarULong64Array &union_seq = attr_value.value.ulong64_att_value(); DevVarULong64Array tmp_seq(1); new_attr_value.value.ulong64_att_value(tmp_seq); DevVarULong64Array &new_union_seq = new_attr_value.value.ulong64_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_STRING: { DevVarStringArray &union_seq = attr_value.value.string_att_value(); DevVarStringArray tmp_seq(1); new_attr_value.value.string_att_value(tmp_seq); DevVarStringArray &new_union_seq = new_attr_value.value.string_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case ATT_STATE: { DevVarStateArray &union_seq = attr_value.value.state_att_value(); DevVarStateArray tmp_seq(1); new_attr_value.value.state_att_value(tmp_seq); DevVarStateArray &new_union_seq = new_attr_value.value.state_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; case DEVICE_STATE: { DevState union_state = attr_value.value.dev_state_att(); new_attr_value.value.dev_state_att(union_state); } break; case ATT_NO_DATA: { new_attr_value.value.union_no_data(true); } break; case ATT_ENCODED: { DevVarEncodedArray &union_seq = attr_value.value.encoded_att_value(); DevVarEncodedArray tmp_seq(1); new_attr_value.value.encoded_att_value(tmp_seq); DevVarEncodedArray &new_union_seq = new_attr_value.value.encoded_att_value(); unsigned long len = union_seq.length(); new_union_seq.replace(len,len,union_seq.get_buffer(false),false); } break; } } //------------------------------------------------------------------------------------------------------------------ // // method : // PollThread::copy_remaining // // description : // Copy from one AttributeValue_X structure to another one data elements which are not the data themselves // // argument : // in : // - attr_value : The origin attribute value // out : // - new_attr_value : The new attribute value // //------------------------------------------------------------------------------------------------------------------ template void PollThread::copy_remaining(T &old_attr_value,T &new_attr_value) { new_attr_value.quality = old_attr_value.quality; new_attr_value.data_format = old_attr_value.data_format; new_attr_value.time = old_attr_value.time; new_attr_value.r_dim = old_attr_value.r_dim; new_attr_value.w_dim = old_attr_value.w_dim; new_attr_value.err_list = old_attr_value.err_list; char *tmp_ptr = old_attr_value.name._retn(); new_attr_value.name = tmp_ptr; omni_mutex *tmp_mut = old_attr_value.get_attr_mutex(); if (tmp_mut != NULL) { new_attr_value.set_attr_mutex(tmp_mut); old_attr_value.set_attr_mutex(NULL); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/utils.tpp0000644023471100065110000004753613034745001014465 00000000000000//=================================================================================================================== // // file : utils.tpp // // description : C++ source code for the Attribute class template methods // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //================================================================================================================== #ifndef _UTILS_TPP #define _UTILS_TPP namespace Tango { //+--------------------------------------------------------------------------------------------------------------- // // method : // Util::fill_attr_polling_buffer // // description : // Fill attribute polling buffer with your own data // // args : // in : // - dev : The device // - att_name : The attribute name // - data : The attribute data to be stored in the polling buffer // //---------------------------------------------------------------------------------------------------------------- template void Util::fill_attr_polling_buffer(DeviceImpl *dev,string &att_name,AttrHistoryStack &data) { // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception(API_DeviceNotPolled,o.str(),"Util::fill_attr_polling_buffer"); } // // Attribute name in lower case letters and check that it is marked as polled // string obj_name(att_name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); dev->get_polled_obj_by_type_name(Tango::POLL_ATTR,obj_name); // // Get a reference on the Attribute object // Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); Tango::WAttribute *w_att_ptr = NULL; Tango::AttrWriteType w_type = att.get_writable(); if (w_type == Tango::READ_WRITE) w_att_ptr = &(dev->get_device_attr()->get_w_attr_by_name(att_name.c_str())); // // Check that it is not a WRITE only attribute // if (w_type == Tango::WRITE) { TangoSys_OMemStream o; o << "Attribute " << att_name; o << " of device " << dev->get_name() << " is WRITE only" << ends; Except::throw_exception(API_DeviceNotPolled,o.str(),"Util::fill_attr_polling_buffer"); } // // If the attribute is not READ_WRITE, the ptr to written part should always be NULL // size_t nb_elt = data.length(); if (w_type != READ_WRITE) { for (size_t i = 0;i < nb_elt;i++) { if ((data.get_data())[i].wr_ptr != NULL) { TangoSys_OMemStream o; o << "The attribute " << att_name; o << " for device " << dev->get_name(); o << " is not a READ_WRITE attribute. You can't set the attribute written part."; o << "It is defined for record number " << i + 1 << ends; Except::throw_exception(API_NotSupportedFeature,o.str(),"Util::fill_attr_polling_buffer"); } } } // // For device implementing IDL 3, DevEncoded data type is not supported // long idl_vers = dev->get_dev_idl_version(); if ((att.get_data_type() == DEV_ENCODED) && (idl_vers == 3)) { TangoSys_OMemStream o; o << "The attribute " << att_name; o << " for device " << dev->get_name(); o << " is of type DEV_ENCODED. Your device supports only IDL V3."; o << " DEV_ENCODED data type is supported starting with IDL V4" << ends; Except::throw_exception(API_NotSupportedFeature,o.str(),"Util::fill_attr_polling_buffer"); } // // DevEncoded data type is not supported for spectrum or image attribute // Paranoid code? This case should never happens! // if ((att.get_data_type() == DEV_ENCODED) && (att.get_data_format() != Tango::SCALAR) && (w_type == Tango::READ_WRITE)) { for (size_t i = 0;i < nb_elt;i++) { if ((data.get_data())[i].wr_ptr != NULL) { TangoSys_OMemStream o; o << "The attribute " << att_name; o << " for device " << dev->get_name(); o << " is of type DEV_ENCODED. Only Scalar attribute are supported for DEV_ENCODED"; o << "It is defined for record number " << i + 1 << ends; Except::throw_exception(API_NotSupportedFeature,o.str(),"Util::fill_attr_polling_buffer"); } } } // // Check that the device IDL is at least 3 // if (idl_vers <= 2) { TangoSys_OMemStream o; o << "The device " << dev->get_name() << " is too old to support this feature. "; o << "Please update your device to IDL 3 or more" << ends; Except::throw_exception(API_NotSupportedFeature,o.str(),"Util::fill_attr_polling_buffer"); } // // Check that history is not larger than polling buffer // unsigned long nb_poll = dev->get_attr_poll_ring_depth(att_name); if (nb_elt > nb_poll) { TangoSys_OMemStream o; o << "The polling buffer depth for attribute " << att_name; o << " for device " << dev->get_name(); o << " is only " << nb_poll; o << " which is less than " << nb_elt << "!" << ends; Except::throw_exception(API_DeviceNotPolled,o.str(),"Util::fill_attr_polling_buffer"); } // // A loop on each record // unsigned long i; Tango::DevFailed *save_except; AttributeIdlData aid; bool attr_failed; struct timeval zero,when; zero.tv_sec = zero.tv_usec = 0; // // Take the device monitor before the loop // In case of large element number, it is time cousuming to take/release the monitor in the loop // dev->get_poll_monitor().get_monitor(); // // The loop for each element // for (i = 0;i < nb_elt;i++) { save_except = NULL; attr_failed = false; if ((data.get_data())[i].err.length() != 0) { attr_failed = true; try { save_except = new Tango::DevFailed((data.get_data())[i].err); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server", "Util::fill_attr_polling_buffer"); } } else { // // Allocate memory for the AttributeValueList sequence // try { if (idl_vers >= 5) { aid.data_5 = new Tango::AttributeValueList_5(1); aid.data_5->length(1); (*aid.data_5)[0].value.union_no_data(true); } else if (idl_vers == 4) { aid.data_4 = new Tango::AttributeValueList_4(1); aid.data_4->length(1); (*aid.data_4)[0].value.union_no_data(true); } else { aid.data_3 = new Tango::AttributeValueList_3(1); aid.data_3->length(1); } } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server","Util::fill_attr_polling_buffer"); } // // Init name,date and quality factor // Tango::AttrQuality qu = (data.get_data())[i].qual; if (idl_vers >= 5) { (*aid.data_5)[0].time.tv_sec = (data.get_data())[i].t_val.tv_sec; (*aid.data_5)[0].time.tv_usec = (data.get_data())[i].t_val.tv_usec; (*aid.data_5)[0].time.tv_nsec = 0; (*aid.data_5)[0].quality = qu; (*aid.data_5)[0].name = CORBA::string_dup(att_name.c_str()); (*aid.data_5)[0].w_dim.dim_x = 0; (*aid.data_5)[0].w_dim.dim_y = 0; (*aid.data_5)[0].r_dim.dim_x = 0; (*aid.data_5)[0].r_dim.dim_y = 0; (*aid.data_5)[0].data_format = att.get_data_format(); (*aid.data_5)[0].data_type = att.get_data_type(); } else if (idl_vers == 4) { (*aid.data_4)[0].time.tv_sec = (data.get_data())[i].t_val.tv_sec; (*aid.data_4)[0].time.tv_usec = (data.get_data())[i].t_val.tv_usec; (*aid.data_4)[0].time.tv_nsec = 0; (*aid.data_4)[0].quality = qu; (*aid.data_4)[0].name = CORBA::string_dup(att_name.c_str()); (*aid.data_4)[0].w_dim.dim_x = 0; (*aid.data_4)[0].w_dim.dim_y = 0; (*aid.data_4)[0].r_dim.dim_x = 0; (*aid.data_4)[0].r_dim.dim_y = 0; (*aid.data_4)[0].data_format = att.get_data_format(); } else { (*aid.data_3)[0].time.tv_sec = (data.get_data())[i].t_val.tv_sec; (*aid.data_3)[0].time.tv_usec = (data.get_data())[i].t_val.tv_usec; (*aid.data_3)[0].time.tv_nsec = 0; (*aid.data_3)[0].quality = qu; (*aid.data_3)[0].name = CORBA::string_dup(att_name.c_str()); (*aid.data_3)[0].w_dim.dim_x = 0; (*aid.data_3)[0].w_dim.dim_y = 0; (*aid.data_3)[0].r_dim.dim_x = 0; (*aid.data_3)[0].r_dim.dim_y = 0; } if ((qu == Tango::ATTR_VALID) || (qu == Tango::ATTR_ALARM) || (qu == Tango::ATTR_WARNING) || (qu == Tango::ATTR_CHANGING)) { // // Set Attribute object value // att.set_value((T *)(data.get_data())[i].ptr, (data.get_data())[i].x, (data.get_data())[i].y, (data.get_data())[i].release); att.set_date((data.get_data())[i].t_val); att.set_quality(qu,false); // // Init remaining fields in AttributeValueList // if (w_type == Tango::READ_WITH_WRITE) dev->get_device_attr()->add_write_value(att); else if (w_type == Tango::READ_WRITE) { if ((data.get_data())[i].wr_ptr != NULL) { w_att_ptr->set_write_value((T *)(data.get_data())[i].wr_ptr, (data.get_data())[i].wr_x, (data.get_data())[i].wr_y); dev->get_device_attr()->add_write_value(att); if ((data.get_data())[i].release == true) { if (att.get_data_format() == Tango::SCALAR) delete (data.get_data())[i].wr_ptr; else delete [] (data.get_data())[i].wr_ptr; } } else { dev->get_device_attr()->add_write_value(att); } } // // Insert data into the AttributeValue object // dev->data_into_net_object(att,aid,0,w_type,true); // // Init remaining fields // if (idl_vers >= 5) { (*aid.data_5)[0].r_dim.dim_x = (data.get_data())[i].x; (*aid.data_5)[0].r_dim.dim_y = (data.get_data())[i].y; if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = dev->get_device_attr()->get_w_attr_by_ind(att.get_assoc_ind()); (*aid.data_5)[0].w_dim.dim_x = assoc_att.get_w_dim_x(); (*aid.data_5)[0].w_dim.dim_y = assoc_att.get_w_dim_y(); } } else if (idl_vers == 4) { (*aid.data_4)[0].r_dim.dim_x = (data.get_data())[i].x; (*aid.data_4)[0].r_dim.dim_y = (data.get_data())[i].y; if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = dev->get_device_attr()->get_w_attr_by_ind(att.get_assoc_ind()); (*aid.data_4)[0].w_dim.dim_x = assoc_att.get_w_dim_x(); (*aid.data_4)[0].w_dim.dim_y = assoc_att.get_w_dim_y(); } } else { (*aid.data_3)[0].r_dim.dim_x = (data.get_data())[i].x; (*aid.data_3)[0].r_dim.dim_y = (data.get_data())[i].y; if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = dev->get_device_attr()->get_w_attr_by_ind(att.get_assoc_ind()); (*aid.data_3)[0].w_dim.dim_x = assoc_att.get_w_dim_x(); (*aid.data_3)[0].w_dim.dim_y = assoc_att.get_w_dim_y(); } } } } // // Fill one slot of polling buffer // try { vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_ATTR,obj_name); if (attr_failed == false) { if (idl_vers >= 5) { when.tv_sec = (*aid.data_5)[0].time.tv_sec - DELTA_T; when.tv_usec = (*aid.data_5)[0].time.tv_usec; (*ite)->insert_data(aid.data_5,when,zero); } else if (idl_vers == 4) { when.tv_sec = (*aid.data_4)[0].time.tv_sec - DELTA_T; when.tv_usec = (*aid.data_4)[0].time.tv_usec; (*ite)->insert_data(aid.data_4,when,zero); } else { when.tv_sec = (*aid.data_3)[0].time.tv_sec - DELTA_T; when.tv_usec = (*aid.data_3)[0].time.tv_usec; (*ite)->insert_data(aid.data_3,when,zero); } } else { when = (data.get_data())[i].t_val; when.tv_sec = when.tv_sec - DELTA_T; (*ite)->insert_except(save_except,when,zero); } } catch (Tango::DevFailed &) { if (attr_failed == false) { if (idl_vers >= 5) delete aid.data_5; else if (idl_vers == 4) delete aid.data_4; else delete aid.data_3; } else delete save_except; } } dev->get_poll_monitor().rel_monitor(); } //+--------------------------------------------------------------------------------------------------------------- // // method : // Util::fill_cmd_polling_buffer // // description : // Fill command polling buffer with your own data // // args : // in : // - dev : The device // - cmd_name : The command name // - data : The command data to be stored in the polling buffer // //---------------------------------------------------------------------------------------------------------------- template void Util::fill_cmd_polling_buffer(DeviceImpl *dev,string &cmd_name,CmdHistoryStack &data) { // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Command name in lower case letters and check that it is marked as polled // string obj_name(cmd_name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); // // Check that history is not larger than polling buffer // size_t nb_elt = data.length(); long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name); if (nb_elt > (size_t)nb_poll) { TangoSys_OMemStream o; o << "The polling buffer depth for command " << cmd_name; o << " for device " << dev->get_name(); o << " is only " << nb_poll; o << " which is less than " << nb_elt << "!" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Take the device monitor before the loop // In case of large element number, it is time cousuming to take/release the monitor in the loop // In case of large element number, it is time cousuming to take/release the monitor in the loop // dev->get_poll_monitor().get_monitor(); // // A loop on each record // size_t i; Tango::DevFailed *save_except; bool cmd_failed; CORBA::Any *any_ptr; struct timeval zero,when; zero.tv_sec = zero.tv_usec = 0; for (i = 0;i < nb_elt;i++) { save_except = NULL; cmd_failed = false; if ((data.get_data())[i].err.length() != 0) { cmd_failed = true; try { save_except = new Tango::DevFailed((data.get_data())[i].err); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } } else { // // Allocate memory for the Any object // try { any_ptr = new CORBA::Any(); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } // // Set command value in Any object // T *tmp_ptr = (data.get_data())[i].ptr; (*any_ptr) <<= (*tmp_ptr); if ((data.get_data())[i].release == true) delete tmp_ptr; } // // Fill one slot of polling buffer // try { vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); when.tv_sec = (data.get_data())[i].t_val.tv_sec - DELTA_T; when.tv_usec = (data.get_data())[i].t_val.tv_usec; if (cmd_failed == false) (*ite)->insert_data(any_ptr,when,zero); else (*ite)->insert_except(save_except,when,zero); } catch (Tango::DevFailed &) { if (cmd_failed == false) delete any_ptr; else delete save_except; } } dev->get_poll_monitor().rel_monitor(); } } // End of Tango namespace #endif /* UTILS_TPP */ tango-9.2.5a/lib/cpp/server/utils_spec.tpp0000644023471100065110000002315013034745001015461 00000000000000//=================================================================================================================== // // file : utils_spec.tpp // // description : C++ source code for the Util::fill_cmd_polling_buffer method template specialization // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General // Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //================================================================================================================== #ifndef _UTILS_SPEC_TPP #define _UTILS_SPEC_TPP namespace Tango { //+--------------------------------------------------------------------------------------------------------------- // // method : // Util::fill_cmd_polling_buffer // // description : // Fill attribute polling buffer with your own data // These are template specialization for data type // DevBoolean // DevUChar // This is required because the insertion of these data type in a CORBA Any object requires specific code // // args : // in : // - dev : The device // - cmd_name : The command name // - data : The command data to be stored in the polling buffer // //---------------------------------------------------------------------------------------------------------------- template <> inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev,string &cmd_name,CmdHistoryStack &data) { // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Command name in lower case letters and check that it is marked as polled // string obj_name(cmd_name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); // // Check that history is not larger than polling buffer // size_t nb_elt = data.length(); long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name); if (nb_elt > (size_t)nb_poll) { TangoSys_OMemStream o; o << "The polling buffer depth for command " << cmd_name; o << " for device " << dev->get_name(); o << " is only " << nb_poll; o << " which is less than " << nb_elt << "!" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Take the device monitor before the loop // In case of large element number, it is time cousuming to take/release // the monitor in the loop // dev->get_poll_monitor().get_monitor(); // // A loop on each record // size_t i; Tango::DevFailed *save_except; bool cmd_failed; CORBA::Any *any_ptr; struct timeval zero,when; zero.tv_sec = zero.tv_usec = 0; for (i = 0;i < nb_elt;i++) { save_except = NULL; cmd_failed = false; if ((data.get_data())[i].err.length() != 0) { cmd_failed = true; try { save_except = new Tango::DevFailed((data.get_data())[i].err); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } } else { // // Allocate memory for the Any object // try { any_ptr = new CORBA::Any(); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } // // Set command value in Any object // DevBoolean *tmp_ptr = (data.get_data())[i].ptr; CORBA::Any::from_boolean tmp(*tmp_ptr); (*any_ptr) <<= tmp; if ((data.get_data())[i].release == true) delete tmp_ptr; } // // Fill one slot of polling buffer // try { vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); when.tv_sec = (data.get_data())[i].t_val.tv_sec - DELTA_T; when.tv_usec = (data.get_data())[i].t_val.tv_usec; if (cmd_failed == false) (*ite)->insert_data(any_ptr,when,zero); else (*ite)->insert_except(save_except,when,zero); } catch (Tango::DevFailed &) { if (cmd_failed == false) delete any_ptr; else delete save_except; } } dev->get_poll_monitor().rel_monitor(); } template <> inline void Util::fill_cmd_polling_buffer(DeviceImpl *dev,string &cmd_name,CmdHistoryStack &data) { // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Command name in lower case letters and check that it is marked as polled // string obj_name(cmd_name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); // // Check that history is not larger than polling buffer // size_t nb_elt = data.length(); long nb_poll = dev->get_cmd_poll_ring_depth(cmd_name); if (nb_elt > (size_t)nb_poll) { TangoSys_OMemStream o; o << "The polling buffer depth for command " << cmd_name; o << " for device " << dev->get_name(); o << " is only " << nb_poll; o << " which is less than " << nb_elt << "!" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::fill_cmd_polling_buffer"); } // // Take the device monitor before the loop // In case of large element number, it is time cousuming to take/release // the monitor in the loop // dev->get_poll_monitor().get_monitor(); // // A loop on each record // size_t i; Tango::DevFailed *save_except; bool cmd_failed; CORBA::Any *any_ptr; struct timeval zero,when; zero.tv_sec = zero.tv_usec = 0; for (i = 0;i < nb_elt;i++) { save_except = NULL; cmd_failed = false; if ((data.get_data())[i].err.length() != 0) { cmd_failed = true; try { save_except = new Tango::DevFailed((data.get_data())[i].err); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } } else { // // Allocate memory for the Any object // try { any_ptr = new CORBA::Any(); } catch (bad_alloc &) { dev->get_poll_monitor().rel_monitor(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Util::fill_cmd_polling_buffer"); } // // Set command value in Any object // DevUChar *tmp_ptr = (data.get_data())[i].ptr; CORBA::Any::from_octet tmp(*tmp_ptr); (*any_ptr) <<= tmp; if ((data.get_data())[i].release == true) delete tmp_ptr; } // // Fill one slot of polling buffer // try { vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); when.tv_sec = (data.get_data())[i].t_val.tv_sec - DELTA_T; when.tv_usec = (data.get_data())[i].t_val.tv_usec; if (cmd_failed == false) (*ite)->insert_data(any_ptr,when,zero); else (*ite)->insert_except(save_except,when,zero); } catch (Tango::DevFailed &) { if (cmd_failed == false) delete any_ptr; else delete save_except; } } dev->get_poll_monitor().rel_monitor(); } } // End of Tango namespace #endif /* UTILS_SPEC_TPP */ tango-9.2.5a/lib/cpp/server/w_attribute.tpp0000644023471100065110000003402313034745002015642 00000000000000//+=================================================================================================================== // // file : w_attribute.tpp // // description : C++ source code for the WAttribute class template methods // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _WATTRIBUTE_TPP #define _WATTRIBUTE_TPP namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::set_min_value() // // description : // Sets minimum value attribute property. Throws exception in case the data type of provided // property does not match the attribute data type // // args : // in : // - new_min_value : The minimum value property to be set // //----------------------------------------------------------------------------------------------------------------- template void WAttribute::set_min_value(const T &new_min_value) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("min_value",d_name,"WAttribute::set_min_value()"); if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"WAttribute::set_min_value()"); } // // Check coherence with max_value // if(check_max_value) { T max_value_tmp; memcpy((void *) &max_value_tmp, (const void *) &max_value, sizeof(T)); if(new_min_value >= max_value_tmp) throw_incoherent_val_err("min_value","max_value",d_name,"WAttribute::set_min_value()"); } // // Store new min value as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_min_value; // to represent the numeric value else str << new_min_value; string min_value_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new value locally // Attr_CheckVal old_min_value; memcpy((void *)&old_min_value, (void *)&min_value, sizeof(T)); memcpy((void *)&min_value, (void *)&new_min_value, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "min_value") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && min_value_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("min_value"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(min_value,"min_value"); } catch (Tango::DevFailed &) { memcpy((void *)&min_value, (void *)&old_min_value, sizeof(T)); throw; } } } // // Set the min_value flag // check_min_value = true; // // Store new value as a string // min_value_str = min_value_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to min_value if there is any // delete_startup_exception("min_value",d_name); } //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::get_min_value() // // description : // Gets attribute's minimum value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if minimum value is not defined // // args : // in : // - min_val : The variable to be assigned the attribute's minimum value // //------------------------------------------------------------------------------------------------------------------ template void WAttribute::get_min_value(T &min_val) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"WAttribute::get_min_value()"); } if (check_min_value == false) { Except::throw_exception((const char *)API_AttrNotAllowed, (const char *)"Minimum value not defined for this attribute", (const char *)"WAttribute::get_min_value()"); } memcpy((void *)&min_val,(void *)&min_value,sizeof(T)); } //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::set_max_value() // // description : // Sets maximum value attribute property // Throws exception in case the data type of provided property does not match the attribute data type // // args : // in : // - new_max_value : The maximum value property to be set // //------------------------------------------------------------------------------------------------------------------- template void WAttribute::set_max_value(const T &new_max_value) { // // Check type validity // if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("max_value",d_name,"WAttribute::set_max_value()"); if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"WAttribute::set_max_value()"); } // // Check coherence with max_value // if(check_min_value) { T min_value_tmp; memcpy((void *) &min_value_tmp, (const void *) &min_value, sizeof(T)); if(new_max_value <= min_value_tmp) throw_incoherent_val_err("min_value","max_value",d_name,"WAttribute::set_max_value()"); } // // Store new max value as a string // TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); if(ranges_type2const::enu == Tango::DEV_UCHAR) str << (short)new_max_value; // to represent the numeric value else str << new_max_value; string max_value_tmp_str = str.str(); // // Get the monitor protecting device att config // If the server is in its starting phase, give a NULL ptr to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); AutoTangoMonitor sync1(mon_ptr); // // Store the new value locally // Attr_CheckVal old_max_value; memcpy((void *)&old_max_value, (void *)&max_value, sizeof(T)); memcpy((void *)&max_value, (void *)&new_max_value, sizeof(T)); // // Then, update database // Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); string usr_def_val; bool user_defaults = false; if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "max_value") break; } if (i != nb_user) // user defaults defined { user_defaults = true; usr_def_val = def_user_prop[i].get_value(); } } if (Tango::Util::_UseDb == true) { if(user_defaults && max_value_tmp_str == usr_def_val) { DbDatum attr_dd(name), prop_dd("max_value"); DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } else { try { upd_att_prop_db(max_value,"max_value"); } catch (Tango::DevFailed &) { memcpy((void *)&max_value, (void *)&old_max_value, sizeof(T)); throw; } } } // // Set the max_value flag // check_max_value = true; // // Store new value as a string // max_value_str = max_value_tmp_str; // // Push a att conf event // if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); // // Delete device startup exception related to max_value if there is any // delete_startup_exception("max_value",d_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // WAttribute::get_max_value() // // description : // Gets attribute's maximum value and assigns it to the variable provided as a parameter // Throws exception in case the data type of provided parameter does not match the attribute data type // or if maximum value is not defined // // args : // in : // - max_val : The variable to be assigned the attribute's maximum value // //------------------------------------------------------------------------------------------------------------------ template void WAttribute::get_max_value(T &max_val) { if (!(data_type == DEV_ENCODED && ranges_type2const::enu == DEV_UCHAR) && (data_type != ranges_type2const::enu)) { string err_msg = "Attribute (" + name + ") data type does not match the type provided : " + ranges_type2const::str; Except::throw_exception((const char *)API_IncompatibleAttrDataType, (const char *)err_msg.c_str(), (const char *)"WAttribute::get_max_value()"); } if (check_max_value == false) { Except::throw_exception((const char *)API_AttrNotAllowed, (const char *)"Minimum value not defined for this attribute", (const char *)"WAttribute::get_max_value()"); } memcpy((void *)&max_val,(void *)&max_value,sizeof(T)); } //+------------------------------------------------------------------------------------------------------------------ // // method : // WAttribute::check_min_max() // // description : // Check if the data received from client is not below the min (if one defined) or above the max // (if one defined). This method throws exception in case of threshold violation. // // args : // in : // - nb_data : Data number // - seq : The received data // - min_value : The min allowed value // - max_value : The max allowed value // //------------------------------------------------------------------------------------------------------------------ template void WAttribute::check_min_max(const unsigned int nb_data,const T1 &seq, const T2 &min_value, const T2 &max_value) { if (check_min_value == true) { for (unsigned int i = 0; i < nb_data; i++) { if (seq[i] < min_value) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit,o.str(),"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (unsigned int i = 0; i < nb_data; i++) { if (seq[i] > max_value) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit,o.str(),"WAttribute::check_written_value()"); } } } } } // End of Tango namespace #endif // _WATTRIBUTE_TPP tango-9.2.5a/lib/cpp/server/w_attribute_spec.tpp0000644023471100065110000003155013034745001016655 00000000000000//+=================================================================================================================== // // file : w_attribute_spec.tpp // // description : C++ source code for the WAttribute class template methods specialization // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-================================================================================================================== #ifndef _WATTRIBUTE_SPEC_TPP #define _WATTRIBUTE_SPEC_TPP namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::set_min_value() // // description : // Sets minimum value attribute property. Throws exception in case the data type of provided // property does not match the attribute data type // // args : // in : // - new_min_value_str : The minimum value property to be set // //------------------------------------------------------------------------------------------------------------------- template <> inline void WAttribute::set_min_value(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"WAttribute::set_min_value()"); } template <> inline void WAttribute::set_min_value(const string &new_min_value_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE) || (data_type == Tango::DEV_ENUM)) throw_err_data_type("min_value",d_name,"WAttribute::set_min_value()"); string min_value_str_tmp = new_min_value_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("min_value",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("min_value",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_min_value_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_value",dev_name); avns_in_att(MIN_VALUE); } else if ((TG_strcasecmp(new_min_value_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_value_str.c_str(),class_def_val.c_str()) == 0)) { min_value_str_tmp = class_def_val; } else if (strlen(new_min_value_str.c_str()) == 0) { if (user_defaults) { min_value_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("min_value",dev_name); avns_in_att(MIN_VALUE); } } } else if(user_defaults) { if(TG_strcasecmp(new_min_value_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("min_value",dev_name); avns_in_att(MIN_VALUE); } else if ((TG_strcasecmp(new_min_value_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_min_value_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_min_value_str.c_str()) == 0)) min_value_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_min_value_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_min_value_str.c_str(),NotANumber) == 0) || (strlen(new_min_value_str.c_str()) == 0)) { set_value = false; avns_in_db("min_value",dev_name); avns_in_att(MIN_VALUE); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << min_value_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); set_min_value((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); set_min_value((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); set_min_value((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); set_min_value(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); set_min_value(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); (db < 0.0) ? set_min_value((DevUShort)(-db)) : set_min_value((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); (db < 0.0) ? set_min_value((DevUChar)(-db)) : set_min_value((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); (db < 0.0) ? set_min_value((DevULong)(-db)) : set_min_value((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); (db < 0.0) ? set_min_value((DevULong64)(-db)) : set_min_value((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("min_value",dev_name,"WAttribute::set_min_value()"); (db < 0.0) ? set_min_value((DevUChar)(-db)) : set_min_value((DevUChar)db); break; } } else throw_err_data_type("min_value",dev_name,"WAttribute::set_min_value()"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // WAttribute::set_max_value() // // description : // Sets maximum value attribute property. Throws exception in case the data type of provided // property does not match the attribute data type // // args : // in : // - new_max_value_str : The maximum value property to be set // //------------------------------------------------------------------------------------------------------------------ template <> inline void WAttribute::set_max_value(const Tango::DevEncoded &) { string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type"; Except::throw_exception((const char *)API_MethodArgument, (const char *)err_msg.c_str(), (const char *)"WAttribute::set_max_value()"); } template <> inline void WAttribute::set_max_value(const string &new_max_value_str) { if((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) throw_err_data_type("max_value",d_name,"WAttribute::set_max_value()"); string max_value_str_tmp = new_max_value_str; string dev_name = d_name; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); size_t nb_user = def_user_prop.size(); string usr_def_val; string class_def_val; bool user_defaults = false; bool class_defaults = false; user_defaults = prop_in_list("max_value",usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list("max_value",class_def_val,nb_class,def_class_prop); bool set_value = true; if (class_defaults) { if(TG_strcasecmp(new_max_value_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_value",dev_name); avns_in_att(MAX_VALUE); } else if ((TG_strcasecmp(new_max_value_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_value_str.c_str(),class_def_val.c_str()) == 0)) { max_value_str_tmp = class_def_val; } else if (strlen(new_max_value_str.c_str()) == 0) { if (user_defaults) { max_value_str_tmp = usr_def_val; } else { set_value = false; avns_in_db("max_value",dev_name); avns_in_att(MAX_VALUE); } } } else if(user_defaults) { if(TG_strcasecmp(new_max_value_str.c_str(),AlrmValueNotSpec) == 0) { set_value = false; avns_in_db("max_value",dev_name); avns_in_att(MAX_VALUE); } else if ((TG_strcasecmp(new_max_value_str.c_str(),NotANumber) == 0) || (TG_strcasecmp(new_max_value_str.c_str(),usr_def_val.c_str()) == 0) || (strlen(new_max_value_str.c_str()) == 0)) max_value_str_tmp = usr_def_val; } else { if ((TG_strcasecmp(new_max_value_str.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(new_max_value_str.c_str(),NotANumber) == 0) || (strlen(new_max_value_str.c_str()) == 0)) { set_value = false; avns_in_db("max_value",dev_name); avns_in_att(MAX_VALUE); } } if(set_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; float fl; TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << max_value_str_tmp; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); set_max_value((DevShort)db); break; case Tango::DEV_LONG: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); set_max_value((DevLong)db); break; case Tango::DEV_LONG64: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); set_max_value((DevLong64)db); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); set_max_value(db); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); set_max_value(fl); break; case Tango::DEV_USHORT: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); (db < 0.0) ? set_max_value((DevUShort)(-db)) : set_max_value((DevUShort)db); break; case Tango::DEV_UCHAR: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); (db < 0.0) ? set_max_value((DevUChar)(-db)) : set_max_value((DevUChar)db); break; case Tango::DEV_ULONG: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); (db < 0.0) ? set_max_value((DevULong)(-db)) : set_max_value((DevULong)db); break; case Tango::DEV_ULONG64: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); (db < 0.0) ? set_max_value((DevULong64)(-db)) : set_max_value((DevULong64)db); break; case Tango::DEV_ENCODED: if (!(str >> db && str.eof())) throw_err_format("max_value",dev_name,"WAttribute::set_max_value()"); (db < 0.0) ? set_max_value((DevUChar)(-db)) : set_max_value((DevUChar)db); break; } } else throw_err_data_type("max_value",dev_name,"WAttribute::set_max_value()"); } } } // End of Tango namespace #endif // _WATTRIBUTE_SPEC_TPP tango-9.2.5a/lib/cpp/server/w_attrsetval.tpp0000644023471100065110000001447613034745002016042 00000000000000//+=================================================================================================================== // // file : w_attrsetval.tpp // // description : C++ source code for the WAttribute class template methods // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _WATTRSETVAL_TPP #define _WATTRSETVAL_TPP #ifdef HAS_TYPE_TRAITS #include #endif namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::get_write_value() // // description : // Get value written by the client. These two templated methods are used for enumerated attribute // // args : // out : // - data : User data to be initialized // //----------------------------------------------------------------------------------------------------------------- template void WAttribute::get_write_value(T &data) { // // First some check on user type // T dum; check_type(dum,"WAttribute::get_write_value"); // // Then, init user data // data = static_cast(short_val); } template void WAttribute::get_write_value(const T *&ptr) { // // First some check on user type // T dum; check_type(dum,"WAttribute::get_write_value"); // // Then, init user data // ptr = (const T *)short_ptr; } //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::check_type() // // description : // Check user type given to the template get_write_value() method // // args : // in : // - dummy : Dummy data used to pass type // - origin : Calling method name (for exception) // //----------------------------------------------------------------------------------------------------------------- template void WAttribute::check_type(T &dummy,const string &origin) { #ifdef HAS_UNDERLYING bool short_enum = is_same::type>::value; bool uns_int_enum = is_same::type>::value; if (short_enum == false && uns_int_enum == false) { stringstream ss; ss << "Invalid enumeration type. Supported types are C++11 scoped enum with short as underlying data type\n"; ss << "or old enum"; Except::throw_exception(API_IncompatibleArgumentType,ss.str(),origin); } #endif // HAS_UNDERLYING // // Check if the input type is an enum and if it is from the valid type // #ifdef HAS_TYPE_TRAITS if (is_enum::value == false) { Except::throw_exception(API_IncompatibleArgumentType, "The input argument data type is not an enumeration",origin); } #endif // HAS_TYPE_TRAITS Tango::DeviceClass *dev_class; try { DeviceImpl *dev = get_att_device(); dev_class = dev->get_device_class(); } catch (Tango::DevFailed &e) { string reas = e.errors[0].reason.in(); if (reas == API_DeviceNotFound) { Util *tg = Util::instance(); const vector *cl_list_ptr = tg->get_class_list(); dev_class = (*cl_list_ptr)[cl_list_ptr->size() - 2]; } else throw; } Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); if (att.same_type(typeid(T)) == false) { stringstream ss; ss << "Invalid enumeration type. Requested enum type is " << att.get_enum_type(); Except::throw_exception(API_IncompatibleArgumentType,ss.str(),origin); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::set_write_value() // // description : // Set written part of a WAttribute. These two templated methods are used for enumerated attribute // // args : // in : // - val : Data to be set as written value // //----------------------------------------------------------------------------------------------------------------- template void WAttribute::set_write_value(T val) { check_type(val,"WAttribute::set_write_value"); CORBA::Any tmp_any; Tango::DevVarShortArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = (short)val; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } template void WAttribute::set_write_value(T *val, long x, long y) { T dum; check_type(dum,"WAttribute::set_write_value"); long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; short *ptr = new short [nb_data]; for (int i = 0;i < nb_data;i++) ptr[i] = (short)val[i]; try { Tango::DevVarShortArray tmp_seq(nb_data,nb_data,ptr,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); delete [] ptr; } catch (...) { delete [] ptr; throw; } } template void WAttribute::set_write_value(vector &val, long x, long y) { T dum; check_type(dum,"WAttribute::set_write_value"); short *ptr = new short [val.size()]; for (unsigned int i = 0;i < val.size();i++) ptr[i] = (short)val[i]; try { Tango::DevVarShortArray tmp_seq(val.size(),val.size(),ptr,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); delete [] ptr; } catch (...) { delete [] ptr; throw; } } } // End of Tango namespace #endif // _WATTRSETVAL_TPP tango-9.2.5a/lib/cpp/server/w_pipe.tpp0000644023471100065110000000423113034745001014571 00000000000000//+=================================================================================================================== // // file : w_pipe.tpp // // description : C++ source code for the WPipe class template methods/functions // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _W_PIPE_TPP #define _W_PIPE_TPP namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : >> // // description : // Helper function to ease data extraction from WPipe root blob // //------------------------------------------------------------------------------------------------------------------- template WPipe &operator>>(WPipe &_dp,T &datum) { _dp.get_blob().operator>>(datum); return _dp; } template WPipe &operator>>(WPipe &_dp,T *datum) { _dp.get_blob().operator>>(datum); return _dp; } template WPipe &operator>>(WPipe &_dp,DataElement &datum) { datum.name = _dp.get_blob().get_current_delt_name(); _dp.get_blob().operator>>(datum.value); return _dp; } } // End of Tango namespace #endif // _W_PIPE_TPP tango-9.2.5a/lib/cpp/server/attrdesc.cpp0000644023471100065110000007030313034745001015101 00000000000000static const char *RcsId = "$Id: attrdesc.cpp 28373 2015-08-13 13:58:07Z taurel $\n$Name$"; //+=================================================================================================================== // // file : attrdesc.cpp // // description : C++ source code for the Attr, SpectrumAttr and ImageAttr classes. Those classes are used // by DS devcelopper to define their attributes (Scalar, Spectrum and Image) // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28373 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::Attr // // description : // Constructor for the Attr class. This constructor simply set the internal values // //------------------------------------------------------------------------------------------------------------------ Attr::Attr(const char *att_name,long att_type,AttrWriteType att_writable, const char *assoc) :name(att_name),writable(att_writable),type(att_type),assoc_name(assoc), mem(false),mem_init(true),poll_period(0),fire_change_event(false), fire_archive_event(false),check_change_event(false),check_archive_event(false), fire_dr_event(false),ext(new AttrExt),cl_name("Attr") { format = Tango::SCALAR; disp_level = Tango::OPERATOR; fire_change_event = false; check_change_event = true; fire_archive_event = false; check_archive_event = true; fire_dr_event = false; if (name != "State") check_type(); if ((writable == Tango::WRITE) && (assoc_name != AssocWritNotSpec)) { cout3 << "Attr::Attr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Associated attribute is not supported" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::Attr"); } if ((writable == Tango::READ_WITH_WRITE) && (assoc_name == AssocWritNotSpec)) { cout3 << "Attr::Attr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Associated attribute not defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::Attr"); } if (writable == READ_WRITE) assoc_name = name; } Attr::Attr(const char *att_name,long att_type,DispLevel level, AttrWriteType att_writable, const char *assoc) :name(att_name),writable(att_writable),type(att_type),assoc_name(assoc),mem(false), poll_period(0),ext(new AttrExt) { format = Tango::SCALAR; disp_level = level; fire_change_event = false; check_change_event = true; fire_archive_event = false; check_archive_event = true; fire_dr_event = false; if (name != "State") check_type(); if ((writable == Tango::WRITE) && (assoc_name != AssocWritNotSpec)) { cout3 << "Attr::Attr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Associated attribute is not supported" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::Attr"); } if ((writable == Tango::READ_WITH_WRITE) && (assoc_name == AssocWritNotSpec)) { cout3 << "Attr::Attr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Associated attribute not defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::Attr"); } if (writable == READ_WRITE) assoc_name = name; } Attr::Attr(const char *att_name,Tango::DispLevel disp) :name(att_name),mem(false),disp_level(disp),poll_period(0),ext(new AttrExt) { fire_change_event = false; check_change_event = true; fire_archive_event = false; check_archive_event = true; fire_dr_event = false; } Attr::Attr(const Attr &sou) { name = sou.name; format = sou.format; writable = sou.writable; type = sou.type; assoc_name = sou.assoc_name; mem = sou.mem; mem_init = sou.mem_init; disp_level = sou.disp_level; poll_period = sou.poll_period; fire_change_event = sou.fire_change_event; fire_archive_event = sou.fire_archive_event; check_change_event = sou.check_change_event; check_archive_event = sou.check_archive_event; fire_dr_event = sou.fire_dr_event; class_properties = sou.class_properties; user_default_properties = sou.user_default_properties; } Attr::~Attr() { #ifndef HAS_UNIQUE_PTR delete ext; #endif } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::check_type // // description : // This method checks data type and throws an exception in case of unsupported data type // //-------------------------------------------------------------------------------------------------------------------- void Attr::check_type() { bool unsuported = true; if (type == Tango::DEV_SHORT || type == Tango::DEV_LONG || type == Tango::DEV_LONG64 || type == Tango::DEV_DOUBLE || type == Tango::DEV_STRING || type == Tango::DEV_FLOAT || type == Tango::DEV_BOOLEAN || type == Tango::DEV_USHORT || type == Tango::DEV_UCHAR || type == Tango::DEV_ULONG || type == Tango::DEV_ULONG64 || type == Tango::DEV_STATE || type == Tango::DEV_ENCODED || type == Tango::DEV_ENUM) unsuported = false; if (unsuported == true) { cout3 << "Attr::check_type throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Data type is not supported" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::check_type"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::set_default_properties // // description : // This method set the default user properties in the Attr object. At this level, each attribute property // is represented by one instance of the Attrproperty class. // // arguments : // in : // - prop_list : The user property list // //------------------------------------------------------------------------------------------------------------------- void Attr::set_default_properties(UserDefaultAttrProp &prop_list) { enum ranges_names { min_value, max_value, min_alarm, max_alarm, min_warning, max_warning, delta_val, delta_t, num_ranges }; bitset ranges; if ((prop_list.label.empty() == false) && (TG_strcasecmp(prop_list.label.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.label.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("label",prop_list.label)); if (prop_list.description.empty() == false && (TG_strcasecmp(prop_list.description.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.description.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("description",prop_list.description)); if (prop_list.unit.empty() == false && (TG_strcasecmp(prop_list.unit.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.unit.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("unit",prop_list.unit)); if (prop_list.standard_unit.empty() == false && (TG_strcasecmp(prop_list.standard_unit.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.standard_unit.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("standard_unit",prop_list.standard_unit)); if (prop_list.display_unit.empty() == false && (TG_strcasecmp(prop_list.display_unit.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.display_unit.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("display_unit",prop_list.display_unit)); if (prop_list.format.empty() == false && (TG_strcasecmp(prop_list.format.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.format.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("format",prop_list.format)); if (prop_list.min_value.empty() == false && (TG_strcasecmp(prop_list.min_value.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.min_value.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.min_value, "min_value"); user_default_properties.push_back(AttrProperty("min_value",prop_list.min_value)); ranges.set(min_value); } if (prop_list.max_value.empty() == false && (TG_strcasecmp(prop_list.max_value.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.max_value.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.max_value, "max_value"); user_default_properties.push_back(AttrProperty("max_value",prop_list.max_value)); ranges.set(max_value); } if (prop_list.min_alarm.empty() == false && (TG_strcasecmp(prop_list.min_alarm.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.min_alarm.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.min_alarm, "min_alarm"); user_default_properties.push_back(AttrProperty("min_alarm",prop_list.min_alarm)); ranges.set(min_alarm); } if (prop_list.max_alarm.empty() == false && (TG_strcasecmp(prop_list.max_alarm.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.max_alarm.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.max_alarm, "max_alarm"); user_default_properties.push_back(AttrProperty("max_alarm",prop_list.max_alarm)); ranges.set(max_alarm); } if (prop_list.min_warning.empty() == false && (TG_strcasecmp(prop_list.min_warning.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.min_warning.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.min_warning, "min_warning"); user_default_properties.push_back(AttrProperty("min_warning",prop_list.min_warning)); ranges.set(min_warning); } if (prop_list.max_warning.empty() == false && (TG_strcasecmp(prop_list.max_warning.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.max_warning.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.max_warning, "max_warning"); user_default_properties.push_back(AttrProperty("max_warning",prop_list.max_warning)); ranges.set(max_warning); } if (prop_list.delta_val.empty() == false && (TG_strcasecmp(prop_list.delta_val.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.delta_val.c_str(),NotANumber) != 0)) { validate_def_prop(prop_list.delta_val, "delta_val"); user_default_properties.push_back(AttrProperty("delta_val",prop_list.delta_val)); ranges.set(delta_val); } if (prop_list.delta_t.empty() == false && (TG_strcasecmp(prop_list.delta_t.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.delta_t.c_str(),"0") != 0) && (TG_strcasecmp(prop_list.delta_t.c_str(),NotANumber) != 0)) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); long lg; str << prop_list.delta_t; if(!(str >> lg && str.eof())) throw_invalid_def_prop("delta_t","DevLong"); user_default_properties.push_back(AttrProperty("delta_t",prop_list.delta_t)); ranges.set(delta_t); } if (prop_list.abs_change.empty() == false && (TG_strcasecmp(prop_list.abs_change.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.abs_change.c_str(),NotANumber) != 0)) { validate_def_change_prop(prop_list.abs_change,"abs_change"); user_default_properties.push_back(AttrProperty("abs_change",prop_list.abs_change)); } if (prop_list.rel_change.empty() == false && (TG_strcasecmp(prop_list.rel_change.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.rel_change.c_str(),NotANumber) != 0)) { validate_def_change_prop(prop_list.rel_change,"rel_change"); user_default_properties.push_back(AttrProperty("rel_change",prop_list.rel_change)); } TangoSys_MemStream def_event_period; def_event_period << (int)(DEFAULT_EVENT_PERIOD); if (prop_list.period.empty() == false && (TG_strcasecmp(prop_list.period.c_str(),AlrmValueNotSpec) != 0) && (prop_list.period != def_event_period.str()) && (TG_strcasecmp(prop_list.period.c_str(),NotANumber) != 0)) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); int i; str << prop_list.period; if(!(str >> i && str.eof())) throw_invalid_def_prop("event_period","DevLong"); user_default_properties.push_back(AttrProperty("event_period",prop_list.period)); } if (prop_list.archive_abs_change.empty() == false && (TG_strcasecmp(prop_list.archive_abs_change.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.archive_abs_change.c_str(),NotANumber) != 0)) { validate_def_change_prop(prop_list.archive_abs_change,"archive_abs_change"); user_default_properties.push_back(AttrProperty("archive_abs_change",prop_list.archive_abs_change)); } if (prop_list.archive_rel_change.empty() == false && (TG_strcasecmp(prop_list.archive_rel_change.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.archive_rel_change.c_str(),NotANumber) != 0)) { validate_def_change_prop(prop_list.archive_rel_change,"archive_rel_change"); user_default_properties.push_back(AttrProperty("archive_rel_change",prop_list.archive_rel_change)); } TangoSys_MemStream def_archive_period; def_archive_period << (int)(INT_MAX); if (prop_list.archive_period.empty() == false && (TG_strcasecmp(prop_list.archive_period.c_str(),AlrmValueNotSpec) != 0) && (prop_list.archive_period != def_archive_period.str()) && (TG_strcasecmp(prop_list.archive_period.c_str(),NotANumber) != 0)) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); int i; str << prop_list.archive_period; if(!(str >> i && str.eof())) throw_invalid_def_prop("archive_period","DevLong"); user_default_properties.push_back(AttrProperty("archive_period",prop_list.archive_period)); } if (prop_list.enum_labels.empty() == false) user_default_properties.push_back(AttrProperty("enum_labels",prop_list.enum_labels)); if(ranges.test(min_value) && ranges.test(max_value)) { double min = 0.0, max = 0.0; convert_def_prop(prop_list.min_value, min); convert_def_prop(prop_list.max_value, max); if(min >= max) throw_incoherent_def_prop("min_value","max_value"); } if(ranges.test(min_alarm) && ranges.test(max_alarm)) { double min = 0.0, max = 0.0; convert_def_prop(prop_list.min_alarm, min); convert_def_prop(prop_list.max_alarm, max); if(min >= max) throw_incoherent_def_prop("min_alarm","max_alarm"); } if(ranges.test(min_warning) && ranges.test(max_warning)) { double min = 0.0, max = 0.0; convert_def_prop(prop_list.min_warning, min); convert_def_prop(prop_list.max_warning, max); if(min >= max) throw_incoherent_def_prop("min_warning","max_warning"); } if(ranges.test(delta_val) ^ ranges.test(delta_t)) { string err_msg = "Just one of the user default properties : delta_val or delta_t is set. Both or none of the values have to be set"; Except::throw_exception(API_IncoherentValues,err_msg,"Attr::set_default_properties()"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::convert_def_prop // // description : // Convert a property froma string to a double with a defined precision // // arguments : // in : // - val : The property as a string // out : // - db : The double data // //------------------------------------------------------------------------------------------------------------------- void Attr::convert_def_prop(const string &val, double &db) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str << val; str >> db; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::validate_def_prop // // description : // Validate the property string definition // // arguments : // in : // - val : The property as a string // - prop : The property name for a correct error message // //------------------------------------------------------------------------------------------------------------------- void Attr::validate_def_prop(const string &val, const char* prop) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); str.str(""); str.clear(); str << val; DevShort sh; DevLong lg; DevLong64 lg64; DevDouble db; DevFloat fl; DevUShort ush; DevULong ulg; DevULong64 ulg64; switch (type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if (!(str >> sh && str.eof())) throw_invalid_def_prop(prop,"DevShort"); break; case Tango::DEV_LONG: if (!(str >> lg && str.eof())) throw_invalid_def_prop(prop,"DevLong"); break; case Tango::DEV_LONG64: if (!(str >> lg64 && str.eof())) throw_invalid_def_prop(prop,"DevLong64"); break; case Tango::DEV_DOUBLE: if (!(str >> db && str.eof())) throw_invalid_def_prop(prop,"DevDouble"); break; case Tango::DEV_FLOAT: if (!(str >> fl && str.eof())) throw_invalid_def_prop(prop,"DevFloat"); break; case Tango::DEV_USHORT: if (!(str >> ush && str.eof())) throw_invalid_def_prop(prop,"DevUShort"); break; case Tango::DEV_UCHAR: if (!(str >> sh && str.eof())) throw_invalid_def_prop(prop,"DevUChar"); break; case Tango::DEV_ULONG: if (!(str >> ulg && str.eof())) throw_invalid_def_prop(prop,"DevULong"); break; case Tango::DEV_ULONG64: if (!(str >> ulg64 && str.eof())) throw_invalid_def_prop(prop,"DevULong64"); break; case Tango::DEV_ENCODED: if (!(str >> sh && str.eof())) throw_invalid_def_prop(prop,"DevUChar"); break; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attr::validate_def_change_prop // // description : // Validate event change property (defined as negative delta,positive delta) // // arguments : // in : // - val : The property as a string // - prop : The property name for a correct error message // //------------------------------------------------------------------------------------------------------------------- void Attr::validate_def_change_prop(const string &val, const char * prop) { TangoSys_MemStream str; str.precision(TANGO_FLOAT_PRECISION); string change_prop_str = val; double db; size_t pos = change_prop_str.find(','); if(pos != string::npos) { string prop_min = change_prop_str.substr(0,pos); string prop_max = change_prop_str.erase(0,pos+1); str << prop_min; if (!(str >> db && str.eof())) throw_invalid_def_prop(prop,"DevDouble or \"DevDouble,DevDouble\""); str.str(""); str.clear(); str << prop_max; if (!(str >> db && str.eof())) throw_invalid_def_prop(prop,"DevDouble or \"DevDouble,DevDouble\""); } else { str.str(""); str.clear(); str << change_prop_str; if (!(str >> db && str.eof())) throw_invalid_def_prop(prop,"DevDouble or \"DevDouble,DevDouble\""); } } void Attr::throw_incoherent_def_prop(const char* min, const char* max) { string err_msg = "User default property " + string(min) + " for attribute : " + get_name() + " is greater then or equal " + string(max); Except::throw_exception(API_IncoherentValues,err_msg,"Attr::set_default_properties()"); } void Attr::throw_invalid_def_prop(const char* prop, const char* type) { string err_msg = "User default property " + string(prop) + " for attribute : " + get_name() + " is defined in unsupported format. Expected " + string(type); Except::throw_exception(API_IncompatibleAttrDataType,err_msg,"Attr::set_default_properties()"); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attr::set_memorized // // description : // This method set the attribute as memorized in database. This is allowed only for scalar attribute and for // writable one // //------------------------------------------------------------------------------------------------------------------ void Attr::set_memorized() { if (format != Tango::SCALAR) { cout3 << "Attr::set_memorized() throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name; o << " is not scalar and can not be memorized" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::set_memorized"); } if ((type == DEV_STATE) || (type == DEV_ENCODED)) { cout3 << "Attr::set_memorized() throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name; o << " can not be memorized" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::set_memorized"); } if ((writable == READ) || (writable == READ_WITH_WRITE)) { cout3 << "Attr::set_memorized() throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name; o << " is not writable and therefore can not be memorized" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"Attr::set_memorized"); } mem = true; } //+----------------------------------------------------------------------------------------------------------------- // // method : // SpectrumAttr::SpectrumAttr // // description : // Constructor for the SpectrumAttr class. This constructor simply set the internal values // //------------------------------------------------------------------------------------------------------------------- SpectrumAttr::SpectrumAttr(const char *att_name,long att_type,long x) :Attr(att_name,att_type),ext(Tango_nullptr) { format = Tango::SPECTRUM; if (x <= 0) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum x dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } if (type == DEV_ENCODED) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute: " << name << ": "; o << "DevEncode data type allowed only for SCALAR attribute" << ends; Except::throw_exception((const char *)API_AttrWrongDefined,o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } max_x = x; } SpectrumAttr::SpectrumAttr(const char *att_name,long att_type,Tango::AttrWriteType w_type,long x) :Attr(att_name,att_type,w_type),ext(Tango_nullptr) { format = Tango::SPECTRUM; if (x <= 0) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum x dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } if (type == DEV_ENCODED) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute: " << name << ": "; o << "DevEncode data type allowed only for SCALAR attribute" << ends; Except::throw_exception((const char *)API_AttrWrongDefined,o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } max_x = x; } SpectrumAttr::SpectrumAttr(const char *att_name,long att_type,long x,DispLevel level) :Attr(att_name,att_type,level),ext(Tango_nullptr) { format = Tango::SPECTRUM; if (x <= 0) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum x dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } if (type == DEV_ENCODED) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute: " << name << ": "; o << "DevEncode data type allowed only for SCALAR attribute" << ends; Except::throw_exception((const char *)API_AttrWrongDefined,o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } max_x = x; } SpectrumAttr::SpectrumAttr(const char *att_name,long att_type,Tango::AttrWriteType w_type,long x,DispLevel level) :Attr(att_name,att_type,level,w_type),ext(Tango_nullptr) { format = Tango::SPECTRUM; if (x <= 0) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum x dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } if (type == DEV_ENCODED) { cout3 << "SpectrumAttr::SpectrumAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute: " << name << ": "; o << "DevEncode data type allowed only for SCALAR attribute" << ends; Except::throw_exception((const char *)API_AttrWrongDefined,o.str(), (const char *)"SpectrumAttr::SpectrumAttr"); } max_x = x; } SpectrumAttr::SpectrumAttr(const SpectrumAttr &sou):Attr(sou) { max_x = sou.max_x; } //+------------------------------------------------------------------------------------------------------------------- // // method : // ImageAttr::ImageAttr // // description : // Constructor for the ImageAttr class. This constructor simply set the internal values // //------------------------------------------------------------------------------------------------------------------- ImageAttr::ImageAttr(const char *att_name,long att_type,long x,long y) :SpectrumAttr(att_name,att_type,x),ext(Tango_nullptr) { format = Tango::IMAGE; if (y <= 0) { cout3 << "ImageAttr::ImageAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum y dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"ImageAttr::ImageAttr"); } max_y = y; } ImageAttr::ImageAttr(const char *att_name,long att_type,Tango::AttrWriteType w_type, long x,long y) :SpectrumAttr(att_name,att_type,w_type,x),ext(Tango_nullptr) { format = Tango::IMAGE; if (y <= 0) { cout3 << "ImageAttr::ImageAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum y dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"ImageAttr::ImageAttr"); } max_y = y; } ImageAttr::ImageAttr(const char *att_name,long att_type,long x, long y,DispLevel level) :SpectrumAttr(att_name,att_type,x,level),ext(Tango_nullptr) { format = Tango::IMAGE; if (y <= 0) { cout3 << "ImageAttr::ImageAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum y dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"ImageAttr::ImageAttr"); } max_y = y; } ImageAttr::ImageAttr(const char *att_name,long att_type,Tango::AttrWriteType w_type, long x, long y,DispLevel level) :SpectrumAttr(att_name,att_type,w_type,x,level),ext(Tango_nullptr) { format = Tango::IMAGE; if (y <= 0) { cout3 << "ImageAttr::ImageAttr throwing exception" << endl; TangoSys_OMemStream o; o << "Attribute : " << name << ": "; o << " Maximum y dim. wrongly defined" << ends; Except::throw_exception((const char *)API_AttrWrongDefined, o.str(), (const char *)"ImageAttr::ImageAttr"); } max_y = y; } ImageAttr::ImageAttr(const ImageAttr &sou):SpectrumAttr(sou) { max_y = sou.max_y; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/attrgetsetprop.cpp0000644023471100065110000027206313034745001016366 00000000000000static const char *RcsId = "$Id: attrgetsetprop.cpp 30256 2016-11-03 13:14:37Z taurel $"; //==================================================================================================================== // // file : attrgetsetprop.cpp // // description : C++ source code for the Attribute class methods erlated to set/get attribute properties // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30256 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_properties // // description : // Init the Tango::AttributeConfig with all the attribute properties value // // argument : // out : // - conf : Structure in which attribute configuration must be stored // //------------------------------------------------------------------------------------------------------------------ void Attribute::get_properties(Tango::AttributeConfig &conf) { // // Copy mandatory properties // conf.writable = writable; conf.data_format = data_format; conf.max_dim_x = max_x; conf.max_dim_y = max_y; conf.data_type = data_type; conf.name = CORBA::string_dup(name.c_str()); // // Copy optional properties // conf.label = CORBA::string_dup(label.c_str()); conf.description = CORBA::string_dup(description.c_str()); conf.unit = CORBA::string_dup(unit.c_str()); conf.standard_unit = CORBA::string_dup(standard_unit.c_str()); conf.display_unit = CORBA::string_dup(display_unit.c_str()); conf.format = CORBA::string_dup(format.c_str()); conf.writable_attr_name = CORBA::string_dup(writable_attr_name.c_str()); conf.min_alarm = CORBA::string_dup(min_alarm_str.c_str()); conf.max_alarm = CORBA::string_dup(max_alarm_str.c_str()); conf.min_value = CORBA::string_dup(min_value_str.c_str()); conf.max_value = CORBA::string_dup(max_value_str.c_str()); } void Attribute::get_properties(Tango::AttributeConfig_2 &conf) { // // Copy mandatory properties // conf.writable = writable; conf.data_format = data_format; conf.max_dim_x = max_x; conf.max_dim_y = max_y; conf.data_type = data_type; conf.name = CORBA::string_dup(name.c_str()); // // Copy optional properties // conf.label = CORBA::string_dup(label.c_str()); conf.description = CORBA::string_dup(description.c_str()); conf.unit = CORBA::string_dup(unit.c_str()); conf.standard_unit = CORBA::string_dup(standard_unit.c_str()); conf.display_unit = CORBA::string_dup(display_unit.c_str()); conf.format = CORBA::string_dup(format.c_str()); conf.writable_attr_name = CORBA::string_dup(writable_attr_name.c_str()); conf.min_alarm = CORBA::string_dup(min_alarm_str.c_str()); conf.max_alarm = CORBA::string_dup(max_alarm_str.c_str()); conf.min_value = CORBA::string_dup(min_value_str.c_str()); conf.max_value = CORBA::string_dup(max_value_str.c_str()); conf.level = disp_level; } void Attribute::get_properties(Tango::AttributeConfig_3 &conf) { // // Throw exception in case of Fwd attribute and the att configuration is not yet received // if (data_type == DATA_TYPE_UNKNOWN) { string desc("Attribute "); FwdAttribute *fwd = static_cast(this); desc = desc + get_name() + " is a forwarded attribute and its root device ("; desc = desc + fwd->get_fwd_dev_name(); desc = desc + ") is not yet available"; Tango::Except::throw_exception(API_AttrConfig,desc,"Attribute::get_properties"); } // // Copy mandatory properties // conf.writable = writable; conf.data_format = data_format; conf.max_dim_x = max_x; conf.max_dim_y = max_y; conf.data_type = data_type; conf.name = CORBA::string_dup(name.c_str()); // // Copy optional properties // conf.label = CORBA::string_dup(label.c_str()); conf.description = CORBA::string_dup(description.c_str()); conf.unit = CORBA::string_dup(unit.c_str()); conf.standard_unit = CORBA::string_dup(standard_unit.c_str()); conf.display_unit = CORBA::string_dup(display_unit.c_str()); conf.format = CORBA::string_dup(format.c_str()); conf.writable_attr_name = CORBA::string_dup(writable_attr_name.c_str()); conf.min_value = CORBA::string_dup(min_value_str.c_str()); conf.max_value = CORBA::string_dup(max_value_str.c_str()); conf.level = disp_level; // // Copy alarm properties // conf.att_alarm.min_alarm = CORBA::string_dup(min_alarm_str.c_str()); conf.att_alarm.max_alarm = CORBA::string_dup(max_alarm_str.c_str()); conf.att_alarm.min_warning = CORBA::string_dup(min_warning_str.c_str()); conf.att_alarm.max_warning = CORBA::string_dup(max_warning_str.c_str()); if (delta_t == 0) conf.att_alarm.delta_t = CORBA::string_dup(AlrmValueNotSpec); else conf.att_alarm.delta_t = CORBA::string_dup(delta_t_str.c_str()); conf.att_alarm.delta_val = CORBA::string_dup(delta_val_str.c_str()); // // Copy periodic event property // TangoSys_OMemStream str; str.precision(TANGO_FLOAT_PRECISION); if (event_period == INT_MAX) conf.event_prop.per_event.period = CORBA::string_dup((const char *)(DEFAULT_EVENT_PERIOD)); else { int per = (int)((double)event_period); str << per; MEM_STREAM_2_CORBA(conf.event_prop.per_event.period,str); } // // Copy change event properties // if (fabs(rel_change[0]) == fabs(rel_change[1])) { if (rel_change[0] == INT_MAX) conf.event_prop.ch_event.rel_change = CORBA::string_dup(AlrmValueNotSpec); else { str << fabs(rel_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.ch_event.rel_change,str); } } else { if (rel_change[0] == INT_MAX) str << AlrmValueNotSpec << ","; else str << fabs(rel_change[0]) << ","; if (rel_change[1] == INT_MAX) str << AlrmValueNotSpec; else str << fabs(rel_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.ch_event.rel_change,str); } if (fabs(abs_change[0]) == fabs(abs_change[1])) { if (abs_change[0] == INT_MAX) conf.event_prop.ch_event.abs_change = CORBA::string_dup(AlrmValueNotSpec); else { str << fabs(abs_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.ch_event.abs_change,str); } } else { if (abs_change[0] == INT_MAX) str << AlrmValueNotSpec << ","; else str << fabs(abs_change[0]) << ","; if (abs_change[1] == INT_MAX) str << AlrmValueNotSpec; else str << fabs(abs_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.ch_event.abs_change,str); } // // Copy archive event properties // if (archive_period == INT_MAX) conf.event_prop.arch_event.period = CORBA::string_dup(AlrmValueNotSpec); else { int per = (int)((double)archive_period); str << per; MEM_STREAM_2_CORBA(conf.event_prop.arch_event.period,str); } if (fabs(archive_rel_change[0]) == fabs(archive_rel_change[1])) { if (archive_rel_change[0] == INT_MAX) conf.event_prop.arch_event.rel_change = CORBA::string_dup(AlrmValueNotSpec); else { str << fabs(archive_rel_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.arch_event.rel_change,str); } } else { if (archive_rel_change[0] == INT_MAX) str << AlrmValueNotSpec << ","; else str << fabs(archive_rel_change[0]) << ","; if (archive_rel_change[1] == INT_MAX) str << AlrmValueNotSpec; else str << fabs(archive_rel_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.arch_event.rel_change,str); } if (fabs(archive_abs_change[0]) == fabs(archive_abs_change[1])) { if (archive_abs_change[0] == INT_MAX) conf.event_prop.arch_event.abs_change = CORBA::string_dup(AlrmValueNotSpec); else { str << fabs(archive_abs_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.arch_event.abs_change,str); } } else { if (archive_abs_change[0] == INT_MAX) str << AlrmValueNotSpec << ","; else str << fabs(archive_abs_change[0]) << ","; if (archive_abs_change[1] == INT_MAX) str << AlrmValueNotSpec; else str << fabs(archive_abs_change[1]); MEM_STREAM_2_CORBA(conf.event_prop.arch_event.abs_change,str); } } void Attribute::get_properties(Tango::AttributeConfig_5 &conf) { // // Get config // Tango::AttributeConfig_3 conf3; get_properties(conf3); conf.name = conf3.name; conf.writable = conf3.writable; conf.data_format = conf3.data_format; conf.data_type = conf3.data_type; conf.max_dim_x = conf3.max_dim_x; conf.max_dim_y = conf3.max_dim_y; conf.description = conf3.description; conf.label = conf3.label; conf.unit = conf3.unit; conf.standard_unit = conf3.standard_unit; conf.display_unit = conf3.display_unit; conf.format = conf3.format; conf.min_value = conf3.min_value; conf.max_value = conf3.max_value; conf.writable_attr_name = conf3.writable_attr_name; conf.level = conf3.level; conf.att_alarm = conf3.att_alarm; conf.event_prop = conf3.event_prop; conf.extensions = conf3.extensions; conf.sys_extensions = conf3.sys_extensions; // // Add AttributeConfig_5 specific data // add_config_5_specific(conf); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::add_config_5_specific // // description : // Add into the received structure configuration release 5 specific data (root att, mem info,...) // // argument : // out : // - conf : The attribute config. structure // //-------------------------------------------------------------------------------------------------------------------- void Attribute::add_config_5_specific(AttributeConfig_5 &conf) { // // Root attribute // if (is_fwd_att() == true) { FwdAttribute *fwd = static_cast(this); string str(fwd->get_fwd_dev_name() + '/' + fwd->get_fwd_att_name()); conf.root_attr_name = CORBA::string_dup(str.c_str()); } else conf.root_attr_name = CORBA::string_dup(AlrmValueNotSpec); // // Memorized info // if (writable == WRITE || writable == READ_WRITE) { WAttribute *watt = static_cast(this); conf.memorized = watt->is_memorized(); conf.mem_init = watt->is_memorized_init(); } else { conf.memorized = false; conf.mem_init = false; } // // Enum labels // if (enum_labels.empty() == false) { conf.enum_labels.length(enum_labels.size()); for (size_t loop = 0;loop < enum_labels.size();loop++) conf.enum_labels[loop] = CORBA::string_dup(enum_labels[loop].c_str()); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_properties // // description : // Set the attribute properties value for AttributeConfig // // argument : // in : // - conf : The new properties sent by client // - dev_name : The device name // - from_ds : // out : // - v_db : Vector of data used for database update/delete // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_properties(const Tango::AttributeConfig &conf,string &dev_name,TANGO_UNUSED(bool from_ds),vector &v_db) { if (name_lower == "state" || name_lower == "status") return; // // Check if the caller try to change "hard coded" properties. Throw exception in case of // if (is_fwd_att() == true) set_hard_coded_properties(conf); else check_hard_coded_properties(conf); // // Copy only a sub-set of the new properties // For each "string" property, an empty string means returns to its default value which could be the library default // value or the user defined default value // Tango::DeviceClass *dev_class = get_att_device_class(dev_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); vector &def_class_prop = att.get_class_properties(); // // First the string properties // set_one_str_prop("description",conf.description,description,v_db,def_user_prop,def_class_prop,DescNotSpec); delete_startup_exception("description",dev_name); set_one_str_prop("label",conf.label,label,v_db,def_user_prop,def_class_prop,name.c_str()); delete_startup_exception("label",dev_name); set_one_str_prop("unit",conf.unit,unit,v_db,def_user_prop,def_class_prop,UnitNotSpec); delete_startup_exception("unit",dev_name); set_one_str_prop("standard_unit",conf.standard_unit,standard_unit,v_db,def_user_prop,def_class_prop,StdUnitNotSpec); delete_startup_exception("standard_unit",dev_name); set_one_str_prop("display_unit",conf.display_unit,display_unit,v_db,def_user_prop,def_class_prop,DispUnitNotSpec); delete_startup_exception("display_unit",dev_name); set_one_str_prop("format",conf.format,format,v_db,def_user_prop,def_class_prop,FormatNotSpec); delete_startup_exception("format",dev_name); // // Min, max and most of the alarm related properties // set_one_alarm_prop("min_value",conf.min_value,min_value_str,min_value,v_db,def_user_prop,def_class_prop,check_min_value); delete_startup_exception("min_value",dev_name); set_one_alarm_prop("max_value",conf.max_value,max_value_str,max_value,v_db,def_user_prop,def_class_prop,check_max_value); delete_startup_exception("max_value",dev_name); bool alrm_set; set_one_alarm_prop("min_alarm",conf.min_alarm,min_alarm_str,min_alarm,v_db,def_user_prop,def_class_prop,alrm_set); if (alrm_set == false) alarm_conf.reset(min_level); else alarm_conf.set(min_level); delete_startup_exception("min_alarm",dev_name); set_one_alarm_prop("max_alarm",conf.max_alarm,max_alarm_str,max_alarm,v_db,def_user_prop,def_class_prop,alrm_set); if (alrm_set == false) alarm_conf.reset(max_level); else alarm_conf.set(max_level); delete_startup_exception("max_alarm",dev_name); } void Attribute::set_properties(const Tango::AttributeConfig_3 &conf,string &dev_name,bool from_ds,vector &v_db) { // // First, do all the job done by old set_property(ies) // AttributeConfig tmp_conf; tmp_conf.name = conf.name; tmp_conf.data_type = conf.data_type; tmp_conf.data_format = conf.data_format; tmp_conf.writable = conf.writable; tmp_conf.writable_attr_name = conf.writable_attr_name; tmp_conf.max_dim_x = conf.max_dim_x; tmp_conf.max_dim_y = conf.max_dim_y; tmp_conf.description = conf.description; tmp_conf.label = conf.label; tmp_conf.unit = conf.unit; tmp_conf.standard_unit = conf.standard_unit; tmp_conf.display_unit = conf.display_unit; tmp_conf.format = conf.format; tmp_conf.min_value = conf.min_value; tmp_conf.max_value = conf.max_value; tmp_conf.min_alarm = conf.att_alarm.min_alarm; tmp_conf.max_alarm = conf.att_alarm.max_alarm; set_properties(tmp_conf,dev_name,from_ds,v_db); // // Add a check of the display level property because it is not checked by the check_hard_coded_properties() template // method called by the set_properties() method. // Display level is available only in AttributeConfig_3 // if (is_fwd_att() == true) set_hard_coded_properties(conf); else check_hard_coded_properties(conf); if (conf.level != get_disp_level()) { throw_hard_coded_prop("level"); } // // For Config 3 specific properties // bool state_or_status = false; vector fake_attr_prop; if (name_lower == "state" || name_lower == "status") state_or_status = true; // // Copy only a sub-set of the new properties // For each "string" property, an empty string means returns to its default value which could be the library default // value or the user defined default value // Tango::DeviceClass *dev_class = get_att_device_class(dev_name); Tango::Attr *att_ptr; if (state_or_status == false) { Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); att_ptr = &(mca->get_attr(name)); } vector &def_user_prop = state_or_status == false ? att_ptr->get_user_default_properties() : fake_attr_prop; vector &def_class_prop = state_or_status == false ? att_ptr->get_class_properties() : fake_attr_prop; if ((state_or_status == false) && ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE))) { // // Alarm related properties // bool alrm_set; set_one_alarm_prop("min_warning",conf.att_alarm.min_warning,min_warning_str,min_warning,v_db,def_user_prop,def_class_prop,alrm_set); if (alrm_set == false) alarm_conf.reset(min_warn); else alarm_conf.set(min_warn); delete_startup_exception("min_warning",dev_name); set_one_alarm_prop("max_warning",conf.att_alarm.max_warning,max_warning_str,max_warning,v_db,def_user_prop,def_class_prop,alrm_set); if (alrm_set == false) alarm_conf.reset(max_warn); else alarm_conf.set(max_warn); delete_startup_exception("max_warning",dev_name); // // RDS related properties // set_rds_prop(conf.att_alarm,dev_name,v_db,def_user_prop,def_class_prop); // // Event related properties (except period) // set_one_event_prop("rel_change",conf.event_prop.ch_event.rel_change,rel_change,v_db,def_user_prop,def_class_prop); delete_startup_exception("rel_change",dev_name); set_one_event_prop("abs_change",conf.event_prop.ch_event.abs_change,abs_change,v_db,def_user_prop,def_class_prop); delete_startup_exception("rel_change",dev_name); set_one_event_prop("archive_rel_change",conf.event_prop.arch_event.rel_change,archive_rel_change,v_db,def_user_prop,def_class_prop); delete_startup_exception("archive_rel_change",dev_name); set_one_event_prop("archive_abs_change",conf.event_prop.arch_event.abs_change,archive_abs_change,v_db,def_user_prop,def_class_prop); delete_startup_exception("archive_abs_change",dev_name); } // // Event periods // set_one_event_period("event_period",conf.event_prop.per_event.period,event_period,DEFAULT_EVENT_PERIOD,v_db,def_user_prop,def_class_prop); delete_startup_exception("event_period",dev_name); set_one_event_period("archive_period",conf.event_prop.arch_event.period,archive_period,INT_MAX,v_db,def_user_prop,def_class_prop); delete_startup_exception("archive_period",dev_name); } void Attribute::set_properties(const Tango::AttributeConfig_5 &conf,string &dev_name,bool from_ds,vector &v_db) { // // Check that the request is not to change some unmutable properties added in IDL 5 // check_hard_coded(conf); // // Do all the job done by old set_property(ies) // AttributeConfig_3 tmp_conf; tmp_conf.name = conf.name; tmp_conf.data_type = conf.data_type; tmp_conf.data_format = conf.data_format; tmp_conf.writable = conf.writable; tmp_conf.writable_attr_name = conf.writable_attr_name; tmp_conf.max_dim_x = conf.max_dim_x; tmp_conf.max_dim_y = conf.max_dim_y; tmp_conf.description = conf.description; tmp_conf.label = conf.label; tmp_conf.unit = conf.unit; tmp_conf.standard_unit = conf.standard_unit; tmp_conf.display_unit = conf.display_unit; tmp_conf.format = conf.format; tmp_conf.min_value = conf.min_value; tmp_conf.max_value = conf.max_value; tmp_conf.level = conf.level; tmp_conf.att_alarm = conf.att_alarm; tmp_conf.event_prop = conf.event_prop; set_properties(tmp_conf,dev_name,from_ds,v_db); // // Now some IDL 5 specific properties // set_prop_5_specific(conf,dev_name,from_ds,v_db); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_one_str_prop // // description : // Analyse one of the string properties. String properties are description, label, unit, standard_unit, // display_unit and format // // argument : // in : // - prop_name : The property name // - conf_val : The new property value // - def_user_prop : The set of user defined default values // - def_class_prop : The set of class defined default values // - lib_def : The property library default value // out : // - att_conf : The new property in Attribute object // - v_db : Vector of data used for database update/delete // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_one_str_prop(const char *prop_name,const CORBA::String_member &conf_val, string &att_conf,vector &v_db,vector &def_user_prop, vector &def_class_prop,const char *lib_def) { AttPropDb apd; apd.name = prop_name; bool user_defaults, class_defaults; string usr_def_val, class_def_val; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); user_defaults = prop_in_list(prop_name,usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list(prop_name,class_def_val,nb_class,def_class_prop); if (TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0) { // // Return to lib default. If something defined as user default or class default, put entry in DB to overwrite // these defaults // string old_val = att_conf; bool fmt_changed = false; if (strcmp(prop_name,"format") == 0) { set_format_notspec(); if (format != old_val) fmt_changed = true; } else att_conf = lib_def; if (old_val != att_conf || fmt_changed == true) { if (user_defaults == true || class_defaults == true) { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } } else if (strlen(conf_val) == 0) { // // Return to user default or lib default. If something defined as class default, put entry in DB in order to // overwrite this default value. // string old_val = att_conf; bool fmt_changed = false; if (user_defaults == true) att_conf = usr_def_val; else { if (strcmp(prop_name,"format") == 0) { set_format_notspec(); if (format != old_val) fmt_changed = true; } else att_conf = lib_def; } if (old_val != att_conf || fmt_changed == true) { if (class_defaults == true) { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } } else if (TG_strcasecmp(conf_val,NotANumber) == 0) { // // Return to class default or user default or lib default // string old_val = att_conf; bool fmt_changed = false; if (class_defaults == true) att_conf = class_def_val; else if (user_defaults == true) att_conf = usr_def_val; else { if (strcmp(prop_name,"format") == 0) { set_format_notspec(); if (format != old_val) fmt_changed = true; } else att_conf = lib_def; } if (old_val != att_conf || fmt_changed == true) { apd.dba = DEL; v_db.push_back(apd); } } else { // // Set property // string old_val = att_conf; att_conf = conf_val; if (user_defaults == true && att_conf == usr_def_val) { // // Property value is the same than the user default value // if (old_val != att_conf) { if (class_defaults == true) { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } } else if (class_defaults == true && att_conf == class_def_val) { // // Property value is the same than the class default value // if (old_val != att_conf) { apd.dba = DEL; v_db.push_back(apd); } } else if (class_defaults == false && TG_strcasecmp(att_conf.c_str(),lib_def) == 0) { // // Property value is the same than the lib default value // if (old_val != att_conf) { apd.dba = DEL; v_db.push_back(apd); } } else if (class_defaults == false && strcmp(prop_name,"label") == 0) { // // Property Label: Property value is the same than the lib default value // if (old_val != att_conf) { if (TG_strcasecmp(att_conf.c_str(),LabelNotSpec) == 0) { apd.dba = DEL; v_db.push_back(apd); } else { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } } } else if (class_defaults == false && strcmp(prop_name,"format") == 0) { // // Property Format: Property value is the same than the lib default value // if (old_val != att_conf) { if (is_format_notspec(conf_val) == true) { apd.dba = DEL; v_db.push_back(apd); } else { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } } } else { if (old_val != att_conf) { apd.dba = UPD; apd.db_value = att_conf; v_db.push_back(apd); } } } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_one_alarm_prop() // // description : // Comment 1: If the user input value is equal to user default value do not store it in the database. // // Comment 2: User default value (if defined) has to be converted to double before it is compared with the user // input to determine if to store the new value in the database. String comparison is not appropriate in case of // floating point numbers, e.g. "5.0" is numerically equal to "5.00" but the strings differ. // // Comment 3: If user defaults are defined - at first place the input string is converted to double to determine // if it is a number. If so, the double value is cast to the type corresponding with the type of the attribute and // further compared with the double representation of the user default value. // The purpose of casting is as follows. Lets take an example of an attribute of DevShort data type with user // default value for min_alarm set to 5. Now, if the user inputs "5.678" as a new value for min_alarm // it would normally be cast to DevShort and stored in the database as "5" (this is the standard behaviour if the // user inputs a floating point value for a property of non-floating point type). But now the outcome "5" is equal // to the user default value 5 and should not be stored in the database. This is why there is the cast of the // user input value to the attribute data type before comparison with the user default value. // // Arguments: // in : // - prop_name : Property name // - conf_val : User value // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // out : // - att_conf_str : New prop value as a string // - att_conf : New prop value converted as att data type // - v_db : Vector of info for db update/delete // - check_it : Flag set to true for alarm bits management // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_one_alarm_prop(const char *prop_name,const CORBA::String_member &conf_val, string &att_conf_str,Tango::Attr_CheckVal &att_conf, vector &v_db, vector &def_user_prop, vector &def_class_prop,bool &check_it) { if (((data_type == Tango::DEV_STRING) || (data_type == Tango::DEV_BOOLEAN) || (data_type == Tango::DEV_STATE)) && (TG_strcasecmp(conf_val,AlrmValueNotSpec) != 0 && strlen(conf_val) != 0 && TG_strcasecmp(conf_val,NotANumber) != 0)) throw_err_data_type(prop_name,d_name,"Attribute::set_one_alarm_prop()"); AttPropDb apd; apd.name = prop_name; bool user_defaults, class_defaults; string usr_def_val, class_def_val; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); user_defaults = prop_in_list(prop_name,usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list(prop_name,class_def_val,nb_class,def_class_prop); stringstream str; str.precision(TANGO_FLOAT_PRECISION); double alrm_usr_def_db; string alrm_class_def; double alrm_class_def_db; bool store_in_db = false; bool del_from_db = false; bool avns = false; bool user_val = false; if(TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0) { // // Return to lib default. If something defined as user default or class default, put entry in DB to overwrite // these defaults // string old_val = att_conf_str; att_conf_str = AlrmValueNotSpec; if (old_val != att_conf_str) { if (user_defaults == true || class_defaults == true) { store_in_db = true; avns = true; } else { del_from_db = true; } } } else if (strlen(conf_val) == 0) { // // Return to user default or lib default. If something defined as class default, put entry in DB in order to // overwrite this default value. // string old_val = att_conf_str; if (user_defaults == false) att_conf_str = AlrmValueNotSpec; else { str.str(""); str.clear(); str << usr_def_val; str >> alrm_usr_def_db; att_conf_str = usr_def_val; } if (old_val != att_conf_str) { if (class_defaults == true) { store_in_db = true; if (user_defaults) user_val = true; else avns = true; } else { del_from_db = true; } } } else if(TG_strcasecmp(conf_val,NotANumber) == 0) { // set class default if defined, user default value if defined, otherwise use the library defaults string old_val = att_conf_str; if (class_defaults == false) { if (user_defaults == false) att_conf_str = AlrmValueNotSpec; else { str.str(""); str.clear(); str << usr_def_val; str >> alrm_usr_def_db; att_conf_str = usr_def_val; } } else { str.str(""); str.clear(); str << class_def_val; str >> alrm_class_def_db; att_conf_str = class_def_val; } if (old_val != att_conf_str) del_from_db = true; } else { // // Set property // string old_val = att_conf_str; att_conf_str = conf_val; bool equal_class_def = false; bool equal_user_def = false; if (old_val != att_conf_str) { // // Equal to user default? // if (user_defaults == true) { stringstream ss1; ss1 << usr_def_val; ss1 >> alrm_usr_def_db; double db; stringstream ss; ss.precision(TANGO_FLOAT_PRECISION); ss << conf_val; if (ss >> db && ss.eof()) { switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if((DevShort)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_LONG: if((DevLong)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_LONG64: if((DevLong64)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_DOUBLE: if (db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_FLOAT: if(db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_USHORT: if((DevUShort)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_UCHAR: if((DevUChar)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_ULONG: if((DevULong)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_ULONG64: if((DevULong64)db == alrm_usr_def_db) equal_user_def = true; break; case Tango::DEV_ENCODED: if((DevUChar)db == alrm_usr_def_db) equal_user_def = true; break; } } } // // Equal to class default? // if (class_defaults == true) { stringstream ss1; ss1 << class_def_val; ss1 >> alrm_class_def_db; double db; stringstream ss; ss.precision(TANGO_FLOAT_PRECISION); ss << conf_val; if (ss >> db && ss.eof()) { switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if((DevShort)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_LONG: if((DevLong)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_LONG64: if((DevLong64)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_DOUBLE: if(db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_FLOAT: if(db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_USHORT: if((DevUShort)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_UCHAR: if((DevUChar)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_ULONG: if((DevULong)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_ULONG64: if((DevULong64)db == alrm_class_def_db) equal_class_def = true; break; case Tango::DEV_ENCODED: if((DevUChar)db == alrm_class_def_db) equal_class_def = true; break; } } } if (user_defaults == true && equal_user_def == true) { if (class_defaults == true) { store_in_db = true; user_val = true; } else { del_from_db = true; } } else if (class_defaults == true && equal_class_def == true) { del_from_db = true; } else store_in_db = true; } } // // Convert prop to attribute data type // if (att_conf_str == AlrmValueNotSpec) check_it = false; else { convert_prop_value(prop_name,att_conf_str,att_conf,d_name); check_it = true; // // If the attribute is READ_WRITE or WRITE and memorized, check that the new min_value is not above the already // memorized value // Tango::AttrWriteType w_type = get_writable(); if ((w_type == Tango::READ_WRITE) || (w_type == Tango::WRITE)) { WAttribute *w_att = static_cast(this); string mem_value; if (strcmp(prop_name,"min_value") == 0 || strcmp(prop_name,"min_alarm") == 0) { if ((w_att->is_memorized() == true) && (w_att->mem_value_below_above(MIN,mem_value) == true)) throw_min_max_value(d_name,mem_value,MIN); } else if (strcmp(prop_name,"max_value") == 0 || strcmp(prop_name,"max_alarm") == 0) { if ((w_att->is_memorized() == true) && (w_att->mem_value_below_above(MAX,mem_value) == true)) throw_min_max_value(d_name,mem_value,MAX); } } } // // For string representation: If there is a default (class or user) and if the user // entered a value equal to the default but with a different precision (3.2 and 3.20), take the // default one instead of the user one // if(class_defaults && att_conf_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << att_conf_str; if(str >> db && str.eof() && db == alrm_class_def_db) att_conf_str = class_def_val; } else if(user_defaults && att_conf_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << att_conf_str; if(str >> db && str.eof() && db == alrm_usr_def_db) att_conf_str = usr_def_val; } // // Get info to be stored in DB // if (store_in_db == true) { string tmp = conf_val.in(); if (user_val == true) tmp = usr_def_val.c_str(); else if (avns == true) tmp = AlrmValueNotSpec; else { double db; stringstream ss; ss.precision(TANGO_FLOAT_PRECISION); ss << conf_val; if (!(ss >> db && ss.eof())) { throw_err_format(prop_name,d_name,"Attribute::set_one_alarm_prop()"); } ss.str(""); ss.clear(); switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: ss << (DevShort)db; break; case Tango::DEV_LONG: ss << (DevLong)db; break; case Tango::DEV_LONG64: ss << (DevLong64)db; break; case Tango::DEV_DOUBLE: break; case Tango::DEV_FLOAT: break; case Tango::DEV_USHORT: (db < 0.0) ? ss << (DevUShort)(-db) : ss << (DevUShort)db; break; case Tango::DEV_UCHAR: (db < 0.0) ? ss << (short)((DevUChar)(-db)) : ss << (short)((DevUChar)db); break; case Tango::DEV_ULONG: (db < 0.0) ? ss << (DevULong)(-db) : ss << (DevULong)db; break; case Tango::DEV_ULONG64: (db < 0.0) ? ss << (DevULong64)(-db) : ss << (DevULong64)db; break; } if (data_type != Tango::DEV_FLOAT && data_type != Tango::DEV_DOUBLE) tmp = ss.str(); } apd.dba = UPD; apd.db_value = tmp; v_db.push_back(apd); } if (del_from_db == true) { apd.dba = DEL; v_db.push_back(apd); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_rds_prop() // // description : // Manage RDS related properties (delta_val and delta_t) // // Arguments: // in : // - att_alarm : New properties value // - dev_name : The device name // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // out : // - v_db : Vector of info for db update/delete // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_rds_prop(const AttributeAlarm &att_alarm, string &dev_name, vector &v_db, vector &def_user_prop, vector &def_class_prop) { Tango::Attr_CheckVal old_delta_val = delta_val; long old_delta_t = delta_t; set_rds_prop_val(att_alarm,dev_name,def_user_prop,def_class_prop); bool delta_val_changed = false; switch(data_type) { case Tango::DEV_SHORT: if (old_delta_val.sh != delta_val.sh) delta_val_changed = true; break; case Tango::DEV_LONG: if (old_delta_val.lg != delta_val.lg) delta_val_changed = true; break; case Tango::DEV_LONG64: if (old_delta_val.lg64 != delta_val.lg64) delta_val_changed = true; break; case Tango::DEV_DOUBLE: if (old_delta_val.db != delta_val.db) delta_val_changed = true; break; case Tango::DEV_FLOAT: if (old_delta_val.fl != delta_val.fl) delta_val_changed = true; break; case Tango::DEV_USHORT: if (old_delta_val.ush != delta_val.ush) delta_val_changed = true; break; case Tango::DEV_UCHAR: if (old_delta_val.uch != delta_val.uch) delta_val_changed = true; break; case Tango::DEV_ULONG: if (old_delta_val.ulg != delta_val.ulg) delta_val_changed = true; break; case Tango::DEV_ULONG64: if (old_delta_val.ulg64 != delta_val.ulg64) delta_val_changed = true; break; case Tango::DEV_STATE: if (old_delta_val.d_sta != delta_val.d_sta) delta_val_changed = true; break; } if (old_delta_t != delta_t || delta_val_changed == true) set_rds_prop_db(att_alarm,v_db,def_user_prop,def_class_prop); } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_rds_prop_val() // // description : // Write into the attribute object the properties related to rds (delta_val and delta_t) // // Arguments: // in : // - att_alarm : New attribute properties // - dev_name : The device name // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_rds_prop_val(const AttributeAlarm &att_alarm, string &dev_name, vector &def_user_prop, vector &def_class_prop) { stringstream str; str.precision(TANGO_FLOAT_PRECISION); bool delta_val_defined = false; string delta_val_usr_def; double delta_val_usr_def_db; string delta_val_class_def; double delta_val_class_def_db; bool usr_defaults = false; bool class_defaults = false; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); if(TG_strcasecmp(att_alarm.delta_val,AlrmValueNotSpec) == 0) { // force library defaults (even if user defaults defined) delta_val_str = AlrmValueNotSpec; } else if(TG_strcasecmp(att_alarm.delta_val,NotANumber) == 0) { // set class default if defined, user default value if defined, otherwise use the library defaults class_defaults = prop_in_list("delta_val",delta_val_class_def,nb_class,def_class_prop); if (class_defaults == false) { usr_defaults = prop_in_list("delta_val",delta_val_usr_def,nb_user,def_user_prop); if (usr_defaults == false) delta_val_str = AlrmValueNotSpec; else { str.str(""); str.clear(); str << delta_val_usr_def; str >> delta_val_usr_def_db; delta_val_str = delta_val_usr_def; } } else { str.str(""); str.clear(); str << delta_val_class_def; str >> delta_val_class_def_db; delta_val_str = delta_val_class_def; } } else if (strlen(att_alarm.delta_val) == 0) { // set user default value if defined, otherwise use the library defaults usr_defaults = prop_in_list("delta_val",delta_val_usr_def,nb_user,def_user_prop); if (usr_defaults == false) delta_val_str = AlrmValueNotSpec; else { str.str(""); str.clear(); str << delta_val_usr_def; str >> delta_val_usr_def_db; delta_val_str = delta_val_usr_def; } } else { // set property delta_val_str = att_alarm.delta_val; } if (delta_val_str != AlrmValueNotSpec) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { convert_prop_value("delta_val",delta_val_str,delta_val,d_name); delta_val_defined = true; } else throw_err_data_type("delta_val",d_name,"Attribute::set_rds_prop_val()"); } // // For string representation: If there is a default (class or user) and if the user // entered a value equal to the default but with a different precision (3.2 and 3.20), take the // default one instead of the user one // if(class_defaults && delta_val_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << delta_val_str; if(str >> db && str.eof() && db == delta_val_class_def_db) delta_val_str = delta_val_class_def; } else if(usr_defaults && delta_val_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << delta_val_str; if(str >> db && str.eof() && db == delta_val_usr_def_db) delta_val_str = delta_val_usr_def; } delete_startup_exception("delta_val",dev_name); // // And the delta_t // bool delta_t_defined = false; string delta_t_usr_def; double delta_t_usr_def_db = 0.0; string delta_t_class_def; double delta_t_class_def_db = 0.0; usr_defaults = false; class_defaults = false; if(TG_strcasecmp(att_alarm.delta_t,AlrmValueNotSpec) == 0 || TG_strcasecmp(att_alarm.delta_t,"0") == 0 || TG_strcasecmp(att_alarm.delta_t,"0.0") == 0) { // force library defaults (even if user defaults defined) delta_t_str = "0"; } else if (TG_strcasecmp(att_alarm.delta_t,NotANumber) == 0) { // set class default if defined, user default value if defined, otherwise use the library defaults class_defaults = prop_in_list("delta_t",delta_t_class_def,nb_class,def_class_prop); if (class_defaults == false) { usr_defaults = prop_in_list("delta_t",delta_t_usr_def,nb_user,def_user_prop); if (usr_defaults == false) delta_t_str = "0"; else { str.str(""); str.clear(); str << delta_t_usr_def; str >> delta_t_usr_def_db; delta_t_str = delta_t_usr_def; } } else { str.str(""); str.clear(); str << delta_t_class_def; str >> delta_t_class_def_db; delta_t_str = delta_t_class_def; } } else if (strlen(att_alarm.delta_t) == 0) { // set user default value if defined, otherwise use the library defaults usr_defaults = prop_in_list("delta_t",delta_t_usr_def,nb_user,def_user_prop); if (usr_defaults == false) delta_t_str = "0"; else { str.str(""); str.clear(); str << delta_t_usr_def; str >> delta_t_usr_def_db; delta_t_str = delta_t_usr_def; } } else { // set property delta_t_str = att_alarm.delta_t; } if(delta_t_str != "0") { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { str.str(""); str.clear(); str << delta_t_str; double db; if (!(str >> db && str.eof())) throw_err_format("delta_t",d_name,"Attribute::set_rds_prop_val"); delta_t = (long)db; str.str(""); str.clear(); str << delta_t; delta_t_str = str.str(); delta_t_defined = true; } else throw_err_data_type("delta_t",d_name,"Attribute::set_rds_prop_val"); } else delta_t = 0; if(class_defaults && delta_t_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << delta_t_str; if(str >> db && str.eof() && db == delta_t_class_def_db) delta_t_str = delta_t_class_def; } else if(usr_defaults && delta_t_str != AlrmValueNotSpec) { double db; str.str(""); str.clear(); str << delta_t_str; if(str >> db && str.eof() && db == delta_t_usr_def_db) delta_t_str = delta_t_usr_def; } delete_startup_exception("delta_t",dev_name); // // Set RDS alarm flag only if both delta_t and delta_val are defined // if(delta_t_defined && delta_val_defined) { alarm_conf.set(rds); delete_startup_exception("rds_alarm",dev_name); } else if(delta_t_defined || delta_val_defined) { alarm_conf.reset(rds); // // Set device if not already done // try { if (dev == NULL) { // TODO: check how to make cerr quiet cerr.setstate(ios::failbit); Tango::Util *tg = Tango::Util::instance(); dev = tg->get_device_by_name(d_name); cerr.clear(); } if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "RDS (Read Different Set) incoherent in attribute " << name << " (only " << (delta_t_defined ? "delta_t" : "delta_val") << " is set) " << endl; } catch(...) { cerr.clear(); } } else { alarm_conf.reset(rds); delete_startup_exception("rds_alarm",dev_name); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_rds_prop_db() // // description : // Check which of the two properties related to RDS (delta_val, delta_t) has to be updated/deleted in Db // // Arguments: // in : // - att_alarm : New attribute properties // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // out : // - v_db : Info for database update/delete // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_rds_prop_db(const AttributeAlarm &att_alarm, vector &v_db, vector &def_user_prop, vector &def_class_prop) { stringstream str; str.precision(TANGO_FLOAT_PRECISION); string delta_val_usr_def_val, delta_val_class_def_val; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); bool delta_val_user_defaults; bool delta_val_class_defaults; // // RDS alarm values (delta_val and delta_t) are stored in or deleted from the database only if both are set or both not // specified. // // // delta_val // string delta_val_tmp_str = att_alarm.delta_val.in(); bool delta_val_is_number = true; delta_val_user_defaults = prop_in_list("delta_val",delta_val_usr_def_val,nb_user,def_user_prop); delta_val_class_defaults = prop_in_list("delta_val",delta_val_class_def_val,nb_class,def_class_prop); if (delta_val_class_defaults) { if ((TG_strcasecmp(att_alarm.delta_val,NotANumber) == 0) || (strcmp(att_alarm.delta_val,delta_val_class_def_val.c_str()) == 0)) { delta_val_tmp_str = delta_val_class_def_val; delta_val_is_number = false; } else if (strlen(att_alarm.delta_val) == 0) { if (delta_val_user_defaults) { delta_val_tmp_str = delta_val_usr_def_val; delta_val_is_number = false; } else { delta_val_tmp_str = AlrmValueNotSpec; delta_val_is_number = false; } } else if(TG_strcasecmp(att_alarm.delta_val,AlrmValueNotSpec) == 0) { delta_val_tmp_str = AlrmValueNotSpec; delta_val_is_number = false; } } else if(delta_val_user_defaults) { if ((TG_strcasecmp(att_alarm.delta_val,NotANumber) == 0) || (strcmp(att_alarm.delta_val,delta_val_usr_def_val.c_str()) == 0) || (strlen(att_alarm.delta_val) == 0)) { delta_val_tmp_str = delta_val_usr_def_val; delta_val_is_number = false; } else if(TG_strcasecmp(att_alarm.delta_val,AlrmValueNotSpec) == 0) { delta_val_tmp_str = AlrmValueNotSpec; delta_val_is_number = false; } } else if ((TG_strcasecmp(att_alarm.delta_val,AlrmValueNotSpec) == 0) || (TG_strcasecmp(att_alarm.delta_val,NotANumber) == 0) || (strlen(att_alarm.delta_val) == 0)) { delta_val_tmp_str = AlrmValueNotSpec; delta_val_is_number = false; } if(delta_val_is_number) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { double db; str.str(""); str.clear(); str << att_alarm.delta_val; if (!(str >> db && str.eof())) throw_err_format("delta_val",d_name,"Attribute::set_rds_prop_db)"); switch (data_type) { case Tango::DEV_SHORT: str.str(""); str.clear(); str << (DevShort)db; break; case Tango::DEV_LONG: str.str(""); str.clear(); str << (DevLong)db; break; case Tango::DEV_LONG64: str.str(""); str.clear(); str << (DevLong64)db; break; case Tango::DEV_DOUBLE: break; case Tango::DEV_FLOAT: break; case Tango::DEV_USHORT: str.str(""); str.clear(); (db < 0.0) ? str << (DevUShort)(-db) : str << (DevUShort)db; break; case Tango::DEV_UCHAR: str.str(""); str.clear(); (db < 0.0) ? str << (short)((DevUChar)(-db)) : str << (short)((DevUChar)db); break; case Tango::DEV_ULONG: str.str(""); str.clear(); (db < 0.0) ? str << (DevULong)(-db) : str << (DevULong)db; break; case Tango::DEV_ULONG64: str.str(""); str.clear(); (db < 0.0) ? str << (DevULong64)(-db) : str << (DevULong64)db; break; case Tango::DEV_ENCODED: str.str(""); str.clear(); (db < 0.0) ? str << (short)(DevUChar)(-db) : str << (short)(DevUChar)db; break; } if (data_type != Tango::DEV_FLOAT && data_type != Tango::DEV_DOUBLE) delta_val_tmp_str = str.str(); } else throw_err_data_type("delta_val",d_name,"Attribute::set_rds_prop_db()"); } // // delta_t // string delta_t_tmp_str = att_alarm.delta_t.in(); string delta_t_usr_def_val; string delta_t_class_def_val; bool delta_t_user_defaults; bool delta_t_class_defaults; bool delta_t_is_number = true; delta_t_user_defaults = prop_in_list("delta_t",delta_t_usr_def_val,nb_user,def_user_prop); delta_t_class_defaults = prop_in_list("delta_t",delta_t_class_def_val,nb_class,def_class_prop); if (delta_t_class_defaults) { if ((TG_strcasecmp(att_alarm.delta_t,NotANumber) == 0) || (strcmp(att_alarm.delta_t,delta_val_class_def_val.c_str()) == 0)) { delta_t_tmp_str = delta_t_class_def_val; delta_t_is_number = false; } else if (strlen(att_alarm.delta_t) == 0) { if (delta_t_user_defaults) { delta_t_tmp_str = delta_t_usr_def_val; delta_t_is_number = false; } else { delta_t_tmp_str = "0"; delta_t_is_number = false; } } else if(TG_strcasecmp(att_alarm.delta_t,AlrmValueNotSpec) == 0) { delta_t_tmp_str = "0"; delta_t_is_number = false; } } else if(delta_t_user_defaults) { if ((TG_strcasecmp(att_alarm.delta_t,NotANumber) == 0) || (strcmp(att_alarm.delta_t,delta_t_usr_def_val.c_str()) == 0) || (strlen(att_alarm.delta_t) == 0)) { delta_t_tmp_str = delta_t_usr_def_val; delta_t_is_number = false; } else if((TG_strcasecmp(att_alarm.delta_t,AlrmValueNotSpec) == 0) || (TG_strcasecmp(att_alarm.delta_t,"0") == 0) || (TG_strcasecmp(att_alarm.delta_t,"0.0") == 0)) { delta_t_tmp_str = "0"; delta_t_is_number = false; } } else if ((TG_strcasecmp(att_alarm.delta_t,AlrmValueNotSpec) == 0) || (TG_strcasecmp(att_alarm.delta_t,"0") == 0) || (TG_strcasecmp(att_alarm.delta_t,"0.0") == 0) || (TG_strcasecmp(att_alarm.delta_t,NotANumber) == 0) || (strlen(att_alarm.delta_t) == 0)) { delta_t_tmp_str = "0"; delta_t_is_number = false; } if(delta_t_is_number) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { str.str(""); str.clear(); str << att_alarm.delta_t; double db; if (!(str >> db && str.eof())) throw_err_format("delta_t",d_name,"Attribute::set_rds_prop_db()"); str.str(""); str.clear(); str << (long)db; delta_t_tmp_str = str.str(); } else throw_err_data_type("delta_t",d_name,"Attribute::set_rds_prop_db()"); } // // Check if to store both delta_val and delta_t in database, delete or do nothing // bool rds_store_both = false; bool rds_delete_both = false; if(delta_val_class_defaults || delta_t_class_defaults) { if((TG_strcasecmp(delta_val_tmp_str.c_str(),delta_val_class_def_val.c_str()) == 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),delta_t_class_def_val.c_str()) == 0)) rds_delete_both = true; else if(((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) == 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") == 0)) || ((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") != 0))) rds_store_both = true; } else if(delta_val_user_defaults || delta_t_user_defaults) { if((TG_strcasecmp(delta_val_tmp_str.c_str(),delta_val_usr_def_val.c_str()) == 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),delta_t_usr_def_val.c_str()) == 0)) rds_delete_both = true; else if(((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) == 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") == 0)) || ((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") != 0))) rds_store_both = true; } else if((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") != 0)) rds_store_both = true; else if((TG_strcasecmp(delta_val_tmp_str.c_str(),AlrmValueNotSpec) == 0) && (TG_strcasecmp(delta_t_tmp_str.c_str(),"0") == 0)) rds_delete_both = true; if(rds_store_both) { AttPropDb apd; apd.name = "delta_val"; apd.dba = UPD; apd.db_value = delta_val_tmp_str.c_str(); v_db.push_back(apd); apd.name = "delta_t"; apd.db_value = delta_t_tmp_str.c_str(); v_db.push_back(apd); } if(rds_delete_both) { AttPropDb apd; apd.name = "delta_val"; apd.dba = DEL; v_db.push_back(apd); apd.name = "delta_t"; v_db.push_back(apd); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_one_event_prop() // // description : // Analyse new property when they are related to event. We have four of these properties: rel_change, abs_change, // archive_rel_change, archive_abs_change // // Arguments: // in : // - prop_name : The property name // - conf_val : The new property value // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // out : // - prop_val : The new property in Attribute object // - v_db : Info for database update/delete // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_one_event_prop(const char *prop_name,const CORBA::String_member &conf_val,double *prop_val, vector &v_db,vector &def_user_prop, vector &def_class_prop) { AttPropDb apd; apd.name = prop_name; string rel_change_str(conf_val); // provided, comma separated min and/or max values for the property string rel_change_usr_str; // user default, comma separated min and/or max values for the property, if defined string rel_change_class_str; // class default, comma separated min and/or max values for the property, if defined vector rel_change_tmp; // vector containing min and max values of the property vector rel_change_usr; // vector containing user default min and max values of the property vector rel_change_class; // vector containing class default min and max values of the property bool rel_change_usr_def; // true if there are user defaults defined for the property bool rel_change_class_def; // true if there are class defaults defined for the property vector rel_change_set_usr_def; // vector indicating if to use provided values for the property or the user defaults if defined vector rel_change_set_class_def; // vector indicating if to use provided values for the property or the class defaults if defined size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); rel_change_usr_def = prop_in_list(prop_name,rel_change_usr_str,nb_user,def_user_prop); rel_change_class_def = prop_in_list(prop_name,rel_change_class_str,nb_class,def_class_prop); // // Validate user or class default properties // if(rel_change_usr_def) validate_change_properties(d_name,prop_name,rel_change_usr_str,rel_change_usr); if(rel_change_class_def) validate_change_properties(d_name,prop_name,rel_change_class_str,rel_change_class); // // Validate user provided values // validate_change_properties(d_name,prop_name,rel_change_str,rel_change_tmp,rel_change_set_usr_def,rel_change_set_class_def); // // Set values // double old_val[2]; old_val[0] = prop_val[0]; old_val[1] = prop_val[1]; if (rel_change_class_def) { if (rel_change_set_class_def[0] == true) prop_val[0] = rel_change_class[0]; else if (rel_change_usr_def) { if (rel_change_set_usr_def[0] == true) prop_val[0] = rel_change_usr[0]; else prop_val[0] = rel_change_tmp[0]; } else prop_val[0] = rel_change_tmp[0]; if (rel_change_set_class_def[1] == true) prop_val[1] = rel_change_class[1]; else if (rel_change_usr_def) { if (rel_change_set_usr_def[1] == true) prop_val[1] = rel_change_usr[1]; else prop_val[1] = rel_change_tmp[1]; } else prop_val[1] = rel_change_tmp[1]; } else if(rel_change_usr_def) { prop_val[0] = (rel_change_set_class_def[0]) ? rel_change_usr[0] : ((rel_change_set_usr_def[0]) ? rel_change_usr[0] : rel_change_tmp[0]); prop_val[1] = (rel_change_set_class_def[1]) ? rel_change_usr[1] : ((rel_change_set_usr_def[1]) ? rel_change_usr[1] : rel_change_tmp[1]); } else { prop_val[0] = rel_change_tmp[0]; prop_val[1] = rel_change_tmp[1]; } // // Manage db // if (old_val[0] != prop_val[0] || old_val[1] != prop_val[1]) { if (prop_val[0] == prop_val[1]) { if (prop_val[0] == INT_MAX) { if (rel_change_usr_def == true || rel_change_class_def == true) { apd.dba = UPD_FROM_DB; apd.db_value_db.clear(); apd.db_value_db.push_back(prop_val[0]); v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } else if (rel_change_usr_def == true && prop_val[0] == fabs(rel_change_usr[0])) { if (rel_change_class_def == true) { apd.dba = UPD_FROM_DB; apd.db_value_db.clear(); apd.db_value_db.push_back(prop_val[0]); v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } else if (rel_change_class_def == true && prop_val[0] == fabs(rel_change_class[0])) { apd.dba = DEL; v_db.push_back(apd); } else { apd.dba = UPD_FROM_DB; apd.db_value_db.clear(); apd.db_value_db.push_back(prop_val[0]); v_db.push_back(apd); } } else { if (rel_change_class_def) { rel_change_tmp.clear(); rel_change_tmp.push_back(prop_val[0]); rel_change_tmp.push_back(prop_val[1]); event_prop_db_xxx(rel_change_tmp,rel_change_class,v_db,apd); } else if(rel_change_usr_def) { rel_change_tmp.clear(); rel_change_tmp.push_back(prop_val[0]); rel_change_tmp.push_back(prop_val[1]); event_prop_db_xxx(rel_change_tmp,rel_change_usr,v_db,apd); } else { apd.dba = UPD_FROM_DB; apd.db_value_db = rel_change_tmp; v_db.push_back(apd); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::set_prop_5_specific // // description : // Set IDl 5 specific attribute configuration. It's only the enum labels for attribute of the DEV_ENUM data type. // The other IDL 5 specific attribute properties are non-mutable. // // argument : // in : // - conf : The new attribute configuration // - dev_name: The device name // - from_ds : Flag set to true if the request comes from a DS code // out : // - v_db : Info for Db update/delete // //------------------------------------------------------------------------------------------------------------------- void Attribute::set_prop_5_specific(const AttributeConfig_5 &conf,string &dev_name,bool from_ds,vector &v_db) { if (data_type == Tango::DEV_ENUM) { AttPropDb apd; apd.name = "enum_labels"; // // Some error cases: Zero length in labels vector // if (conf.enum_labels.length() == 0) { stringstream ss; ss << "Device " << dev_name << "- Attribute : " << name; ss << "- No value defined for the property enum_labels"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_prop_5_specific()"); } if (from_ds == false) { if (!(conf.enum_labels.length() == 1 && (TG_strcasecmp(conf.enum_labels[0],AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.enum_labels[0],NotANumber) == 0 || strlen(conf.enum_labels[0]) == 0))) { if (conf.enum_labels.length() != enum_labels.size()) { stringstream ss; ss << "Device " << dev_name << "-> Attribute : " << name; ss << "\nIt's not supported to change enumeration labels number from outside the Tango device class code"; Except::throw_exception(API_NotSupportedFeature,ss.str(),"Attribute::set_prop_5_specific()"); } } } // // Set some data used by the algo like the user or class properties // Tango::DeviceClass *dev_class = get_att_device_class(dev_name); Tango::Attr *att_ptr; Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); att_ptr = &(mca->get_attr(name)); vector &def_user_prop = att_ptr->get_user_default_properties(); size_t nb_user = def_user_prop.size(); vector &def_class_prop = att_ptr->get_class_properties(); size_t nb_class = def_class_prop.size(); // // Set the enum labels // string enum_labels_usr_def; string enum_labels_class_def; bool usr_defaults = false; bool class_defaults = false; usr_defaults = prop_in_list("enum_labels",enum_labels_usr_def,nb_user,def_user_prop); class_defaults = prop_in_list("enum_labels",enum_labels_class_def,nb_class,def_class_prop); vector old_labels = enum_labels; if(TG_strcasecmp(conf.enum_labels[0],AlrmValueNotSpec) == 0) { // no library defaults for enum stringstream ss; ss << "Device " << dev_name << "-> Attribute : " << name; ss << "\nNo enumeration label(s) default library value for attribute of the Tango::DEV_ENUM data type"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_prop_5_specific()"); } else if (strlen(conf.enum_labels[0]) == 0) { // set user default value if defined, otherwise use the library defaults if (usr_defaults == false) { stringstream ss; ss << "Device " << dev_name << "-> Attribute : " << name; ss << "\nNo enumeration labels default library value for attribute of the Tango::DEV_ENUM data type"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_prop_5_specific()"); } else { build_check_enum_labels(enum_labels_usr_def); if (enum_labels != old_labels) { apd.dba = DEL; v_db.push_back(apd); } } } else if(TG_strcasecmp(conf.enum_labels[0],NotANumber) == 0) { // set class default if defined, user default value if defined, otherwise use the library defaults if (class_defaults == false) { if (usr_defaults == false) { stringstream ss; ss << "Device " << dev_name << "-> Attribute : " << name; ss << "\nNo enumeration labels default library value for attribute of the Tango::DEV_ENUM data type"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_prop_5_specific()"); } else { build_check_enum_labels(enum_labels_usr_def); if (enum_labels != old_labels) { apd.dba = DEL; v_db.push_back(apd); } } } else { build_check_enum_labels(enum_labels_class_def); if (enum_labels != old_labels) { apd.dba = DEL; v_db.push_back(apd); } } } else { // set property string labs; for (size_t loop = 0;loop < conf.enum_labels.length();loop++) { labs = labs + conf.enum_labels[loop].in(); if (loop != conf.enum_labels.length() - 1) labs = labs + ','; } build_check_enum_labels(labs); if (enum_labels != old_labels) { if (usr_defaults == true && labs == enum_labels_usr_def) { if (class_defaults == true) { apd.dba = UPD_FROM_VECT_STR; apd.db_value_v_str = enum_labels; } else { apd.dba = DEL; } v_db.push_back(apd); } else if (class_defaults == true && labs == enum_labels_class_def) { apd.dba = DEL; v_db.push_back(apd); } else { apd.dba = UPD_FROM_VECT_STR; apd.db_value_v_str = enum_labels; v_db.push_back(apd); } } } delete_startup_exception("enum_labels",dev_name); } } void Attribute::set_min_alarm(char *new_min_alarm_str) { set_min_alarm(string(new_min_alarm_str)); } void Attribute::set_min_alarm(const char *new_min_alarm_str) { set_min_alarm(string(new_min_alarm_str)); } void Attribute::set_max_alarm(char *new_max_alarm_str) { set_max_alarm(string(new_max_alarm_str)); } void Attribute::set_max_alarm(const char *new_max_alarm_str) { set_max_alarm(string(new_max_alarm_str)); } void Attribute::set_min_warning(char *new_min_warning_str) { set_min_warning(string(new_min_warning_str)); } void Attribute::set_min_warning(const char *new_min_warning_str) { set_min_warning(string(new_min_warning_str)); } void Attribute::set_max_warning(char *new_max_warning_str) { set_max_warning(string(new_max_warning_str)); } void Attribute::set_max_warning(const char *new_max_warning_str) { set_max_warning(string(new_max_warning_str)); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::check_range_coherency // // description : // Check coherency between min and max value for properties where a min and a max is used // // argument : // in : // - dev_name: The device name // //------------------------------------------------------------------------------------------------------------------- void Attribute::check_range_coherency(string &dev_name) { // // Check ranges coherence for min and max value // if(check_min_value && check_max_value) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { switch (data_type) { case Tango::DEV_SHORT: if(min_value.sh >= max_value.sh) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG: if(min_value.lg >= max_value.lg) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG64: if(min_value.lg64 >= max_value.lg64) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_DOUBLE: if(min_value.db >= max_value.db) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_FLOAT: if(min_value.fl >= max_value.fl) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_USHORT: if(min_value.ush >= max_value.ush) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_UCHAR: if(min_value.uch >= max_value.uch) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG: if(min_value.ulg >= max_value.ulg) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG64: if(min_value.ulg64 >= max_value.ulg64) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ENCODED: if(min_value.uch >= max_value.uch) throw_incoherent_val_err("min_value","max_value",dev_name,"Attribute::set_upd_properties()"); break; } } else throw_err_data_type("min_value",dev_name,"Attribute::set_upd_properties()"); } // // Check ranges coherence for min and max alarm // if(alarm_conf.test(min_level) && alarm_conf.test(max_level)) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { switch (data_type) { case Tango::DEV_SHORT: if(min_alarm.sh >= max_alarm.sh) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG: if(min_alarm.lg >= max_alarm.lg) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG64: if(min_alarm.lg64 >= max_alarm.lg64) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_DOUBLE: if(min_alarm.db >= max_alarm.db) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_FLOAT: if(min_alarm.fl >= max_alarm.fl) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_USHORT: if(min_alarm.ush >= max_alarm.ush) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_UCHAR: if(min_alarm.uch >= max_alarm.uch) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG: if(min_alarm.ulg >= max_alarm.ulg) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG64: if(min_alarm.ulg64 >= max_alarm.ulg64) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ENCODED: if(min_alarm.uch >= max_alarm.uch) throw_incoherent_val_err("min_alarm","max_alarm",dev_name,"Attribute::set_upd_properties()"); break; } } else throw_err_data_type("min_alarm",dev_name,"Attribute::set_upd_properties()"); } // // Check ranges coherence for min and max warning // if(alarm_conf.test(min_warn) && alarm_conf.test(max_warn)) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { switch (data_type) { case Tango::DEV_SHORT: if(min_warning.sh >= max_warning.sh) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG: if(min_warning.lg >= max_warning.lg) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_LONG64: if(min_warning.lg64 >= max_warning.lg64) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_DOUBLE: if(min_warning.db >= max_warning.db) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_FLOAT: if(min_warning.fl >= max_warning.fl) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_USHORT: if(min_warning.ush >= max_warning.ush) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_UCHAR: if(min_warning.uch >= max_warning.uch) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG: if(min_warning.ulg >= max_warning.ulg) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ULONG64: if(min_warning.ulg64 >= max_warning.ulg64) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; case Tango::DEV_ENCODED: if(min_warning.uch >= max_warning.uch) throw_incoherent_val_err("min_warning","max_warning",dev_name,"Attribute::set_upd_properties()"); break; } } else throw_err_data_type("min_warning",dev_name,"Attribute::set_upd_properties()"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::db_access // // description : // Update / Delete info in database // // argument : // in : // - cosp : The structure with all infos needed to access the database // - dev_name : The device name // //-------------------------------------------------------------------------------------------------------------------- void Attribute::db_access(Attribute::CheckOneStrProp &cosp,string &dev_name) { // // Update db only if needed // if (*cosp.prop_to_update != 0) { cout4 << *cosp.prop_to_update << " properties to update in db" << endl; (*cosp.db_d)[0] << *cosp.prop_to_update; //for (const auto &elem: *cosp.db_d) // cout << "prop_to_update name = " << elem.name << endl; Tango::Util *tg = Tango::Util::instance(); // // Implement a reconnection schema. The first exception received if the db server is down is a COMM_FAILURE exception. // Following exception received from following calls are TRANSIENT exception // bool retry = true; while (retry == true) { try { tg->get_database()->put_device_attribute_property(dev_name,*cosp.db_d); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } if (*cosp.prop_to_delete != 0) { cout4 << *cosp.prop_to_delete << " properties to delete in db" << endl; (*cosp.db_del)[0] << *cosp.prop_to_delete; //for (const auto &elem: *cosp.db_del) // cout << "prop_to_delete name = " << elem.name << endl; Tango::Util *tg = Tango::Util::instance(); // // Implement a reconnection schema. The first exception received if the db server is down is a COMM_FAILURE exception. // Following exception received from following calls are TRANSIENT exception // bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(dev_name,*cosp.db_del); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::validate_change_properties // // description : // Check if attribute change properties are properly defined // // argument : // in : // - dev_name : The name of the device // - prop_name : The name of the property // - change_prop_str : A string representing the change property (in the form of either "value" or // "value1,value2") // // out : // - validated_prop : A vector of parsed change properties values in the form of numbers of type double // //------------------------------------------------------------------------------------------------------------------- void Attribute::validate_change_properties(const string &dev_name, const char *prop_name, string &change_prop_str, vector &validated_prop) { vector bring_usr_def; vector bring_class_def; validate_change_properties(dev_name, prop_name, change_prop_str, validated_prop, bring_usr_def,bring_class_def); } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::validate_change_properties // // description : // Check if attribute change properties are properly defined // // argument : // in : // - dev_name : The name of the device // - prop_name : The name of the property // - change_prop_str : A string representing the change property (in the form of either "value" or // "value1,value2") // // out : // - validated_prop : A vector of parsed change properties values in the form of numbers of type double // - bring_usr_def : A vector of boolean values indicating if for a corresponding value in validated_prop // vector there was a request to restore the user defined value // - bring_class_def : A vector of boolean values indicating if for a corresponding value in validated_prop // vector there was a request to restore the class defined value // //------------------------------------------------------------------------------------------------------------------ void Attribute::validate_change_properties(const string &dev_name, const char *prop_name, string &change_prop_str, vector &validated_prop, vector &bring_usr_def,vector &bring_class_def) { // by default, values for event change properties are set to INT_MAX validated_prop.clear(); validated_prop.push_back(INT_MAX); validated_prop.push_back(INT_MAX); // by default, bring user and class defined properties flags are set to false bring_usr_def.clear(); bring_usr_def.push_back(false); bring_usr_def.push_back(false); bring_class_def.clear(); bring_class_def.push_back(false); bring_class_def.push_back(false); stringstream str; str.precision(TANGO_FLOAT_PRECISION); string prop_min; string prop_max; bool one_param = true; double prop_tmp; size_t pos = change_prop_str.find(','); if(pos != string::npos) { prop_min = change_prop_str.substr(0,pos); prop_max = change_prop_str.erase(0,pos+1); one_param = false; } else prop_min = change_prop_str; if(TG_strcasecmp(prop_min.c_str(),AlrmValueNotSpec) == 0) { validated_prop[0] = INT_MAX; validated_prop[1] = INT_MAX; } else if(TG_strcasecmp(prop_min.c_str(),NotANumber) == 0) { bring_class_def[0] = true; bring_class_def[1] = true; bring_usr_def[0] = true; bring_usr_def[1] = true; } else if(prop_min == "") { bring_usr_def[0] = true; bring_usr_def[1] = true; } else { str << prop_min; if(str >> prop_tmp && str.eof()) { if (fabs(prop_tmp) > 0 && prop_tmp != INT_MAX) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { validated_prop[0] = -fabs(prop_tmp); validated_prop[1] = fabs(prop_tmp); } else throw_err_data_type(prop_name,const_cast(dev_name),"Attribute::validate_change_properties()"); } } else throw_err_format(prop_name,dev_name,"Attribute::validate_change_properties()"); } if(!one_param) { validated_prop[1] = INT_MAX; bring_usr_def[1] = false; bring_class_def[1] = false; if(TG_strcasecmp(prop_max.c_str(),AlrmValueNotSpec) == 0) validated_prop[1] = INT_MAX; else if(TG_strcasecmp(prop_max.c_str(),NotANumber) == 0) bring_class_def[1] = true; else if(prop_max == "") bring_usr_def[1] = true; else { str.str(""); str.clear(); str << prop_max; if(str >> prop_tmp && str.eof()) { if (fabs(prop_tmp) > 0 && prop_tmp != INT_MAX) { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { validated_prop[1] = fabs(prop_tmp); } else throw_err_data_type(prop_name,const_cast(dev_name),"Attribute::validate_change_properties()"); } } else throw_err_format(prop_name,dev_name,"Attribute::validate_change_properties()"); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::event_prop_db_xxx // // description : // // argument : // in : // - rel_change_tmp : // - rel_change_usr : // - v_db : // out : // - apd : // //------------------------------------------------------------------------------------------------------------------- void Attribute::event_prop_db_xxx(vector &rel_change_tmp,vector &rel_change_usr,vector &v_db,AttPropDb &apd) { vector rel_change_str_tmp(2); vector rel_change_usr_def_tmp(2); rel_change_usr_def_tmp[0] = rel_change_usr_def_tmp[1] = false; if(rel_change_tmp[0] == rel_change_usr[0]) { rel_change_str_tmp[0] = NotANumber; rel_change_usr_def_tmp[0] = true; } if(rel_change_tmp[1] == rel_change_usr[1]) { rel_change_str_tmp[1] = NotANumber; rel_change_usr_def_tmp[1] = true; } if(rel_change_usr_def_tmp[0] && rel_change_usr_def_tmp[1]) { apd.dba = DEL; v_db.push_back(apd); } else if(!rel_change_usr_def_tmp[0] && !rel_change_usr_def_tmp[1]) { apd.dba = UPD_FROM_DB; apd.db_value_db = rel_change_tmp; v_db.push_back(apd); } else { stringstream str; str.precision(TANGO_FLOAT_PRECISION); if(rel_change_usr_def_tmp[0] && !rel_change_usr_def_tmp[1]) { str << rel_change_tmp[1]; rel_change_str_tmp[1] = str.str(); } else { str << rel_change_tmp[0]; rel_change_str_tmp[0] = str.str(); } apd.dba = UPD_FROM_VECT_STR; apd.db_value_v_str = rel_change_str_tmp; v_db.push_back(apd); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_one_event_period() // // description : // Analyse new property when for event period. We have two of them. // // Arguments: // in : // - prop_name : The property name // - conf_val : The new property value // - prop_def : Property lib default value // - def_user_prop : User defined default prop. // - def_class_prop : Class defined default prop. // out : // - prop_val : The new property in Attribute object // - v_db : Info for database update/delete // //--------------------------------------------------------------------------------------------------------------------- void Attribute::set_one_event_period(const char *prop_name,const CORBA::String_member &conf_val,int &prop_val,const int &prop_def, vector &v_db,vector &def_user_prop, vector &def_class_prop) { AttPropDb apd; apd.name = prop_name; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); stringstream def_event_period; def_event_period << (int)(prop_def); string class_def_val; string usr_def_val; bool user_defaults = prop_in_list(prop_name,usr_def_val,nb_user,def_user_prop); bool class_defaults = prop_in_list(prop_name,class_def_val,nb_class,def_class_prop); stringstream str; str.precision(TANGO_FLOAT_PRECISION); int old_prop_val = prop_val; if(TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf_val,def_event_period.str().c_str()) == 0) { // force library defaults (even if user defaults defined) prop_val = prop_def; } else if (TG_strcasecmp(conf_val,NotANumber) == 0) { if (class_defaults == false) { if (user_defaults == false) prop_val = prop_def; else { str.str(""); str.clear(); str << usr_def_val; double db; if (!(str >> db && str.eof())) throw_err_format(prop_name,d_name,"Attribute::set_one_event_period()"); prop_val = (int)db; } } else { str.str(""); str.clear(); str << class_def_val; double db; if (!(str >> db && str.eof())) throw_err_format(prop_name,d_name,"Attribute::set_one_event_period()"); prop_val = (int)db; } } else if (strlen(conf_val) == 0) { // set user default value if defined, otherwise use the library defaults if (user_defaults == false) prop_val = prop_def; else { str.str(""); str.clear(); str << usr_def_val; double db; if (!(str >> db && str.eof())) throw_err_format(prop_name,d_name,"Attribute::set_one_event_period()"); prop_val = (int)db; } } else { // set property str.str(""); str.clear(); str << conf_val; double db; if (!(str >> db && str.eof())) throw_err_format(prop_name,d_name,"Attribute::set_one_event_period()"); prop_val = (int)db; } // // Manage db // bool store_in_db = true; if (prop_val != old_prop_val) { if (class_defaults) { if((TG_strcasecmp(class_def_val.c_str(),AlrmValueNotSpec) == 0) || (TG_strcasecmp(class_def_val.c_str(),NotANumber) == 0) || (strlen(class_def_val.c_str()) == 0)) { stringstream str; str << (int)(prop_def); class_def_val = str.str(); } bool input_equal_def = false; str.str(""); str.clear(); str << conf_val.in(); double db; if (str >> db && str.eof()) { str.str(""); str.clear(); str << class_def_val; int i; str >> i; if((int)db == i) input_equal_def = true; } if ((TG_strcasecmp(conf_val,NotANumber) == 0) || (strcmp(conf_val.in(),class_def_val.c_str()) == 0) || (input_equal_def == true)) store_in_db = false; } else if (user_defaults) { bool input_equal_def = false; str.str(""); str.clear(); str << conf_val.in(); double db; if (str >> db && str.eof()) { str.str(""); str.clear(); str << usr_def_val; int i; str >> i; if((int)db == i) input_equal_def = true; } if ((TG_strcasecmp(conf_val,NotANumber) == 0) || (strcmp(conf_val.in(),usr_def_val.c_str()) == 0) || (strlen(conf_val) == 0) || (input_equal_def == true)) store_in_db = false; } else { bool input_equal_def = false; str.str(""); str.clear(); str << conf_val.in(); double db; if (str >> db && str.eof()) { if((int)db == (int)(prop_def)) input_equal_def = true; } if ((TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0) || (TG_strcasecmp(conf_val,def_event_period.str().c_str()) == 0) || (TG_strcasecmp(conf_val,NotANumber) == 0) || (strlen(conf_val) == 0) || (input_equal_def == true)) store_in_db = false; } if(store_in_db) { string tmp = conf_val.in(); if (TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0) { tmp = def_event_period.str(); } else if (strlen(conf_val) == 0) { if (class_defaults && user_defaults) tmp = usr_def_val; else tmp = def_event_period.str(); } else { str.str(""); str.clear(); str << conf_val.in(); double db; if (!(str >> db && str.eof())) throw_err_format(prop_name,d_name,"Attribute::set_one_event_period()"); str.str(""); str.clear(); str << (int)db; tmp = str.str(); } apd.dba = UPD; apd.db_value = tmp; v_db.push_back(apd); } else { apd.dba = DEL; v_db.push_back(apd); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::check_hard_coded() // // description : // Check if the user tries to change attribute properties considered as hard coded added by IDL 5 // Throw exception in case of // // args : // in : // - user_conf : The attribute configuration sent by the user // //------------------------------------------------------------------------------------------------------------------ void Attribute::check_hard_coded(const AttributeConfig_5 &user_conf) { // // Check root attribute name // if (is_fwd_att() == true) { FwdAttribute *fwd = static_cast(this); string root_attr_name(fwd->get_fwd_dev_name() + '/' + fwd->get_fwd_att_name()); string user_root_att_name(user_conf.root_attr_name.in()); transform(user_root_att_name.begin(),user_root_att_name.end(),user_root_att_name.begin(),::tolower); if (user_root_att_name != root_attr_name) { throw_hard_coded_prop("root_attr_name"); } } // // Memorized config // if (writable == WRITE || writable == READ_WRITE) { WAttribute *watt = static_cast(this); if (watt->is_memorized() != user_conf.memorized) { throw_hard_coded_prop("memorized"); } if (watt->is_memorized() == true) { if (watt->is_memorized_init() != user_conf.mem_init) { throw_hard_coded_prop("memorized"); } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::convert_prop_value() // // description : // // // args : // in : // - prop_name : The attribute property name // - dev_name : The device name // - value_str : Attribute property value stored as a string // out : // - val : Attribute property value stored as a number // //------------------------------------------------------------------------------------------------------------------ void Attribute::convert_prop_value(const char *prop_name,string &value_str,Attr_CheckVal &val,const string &dev_name) { stringstream str; str.precision(TANGO_FLOAT_PRECISION); str << value_str; if (!(str >> val.db && str.eof())) throw_err_format(prop_name,dev_name,"Attribute::convert_prop_value()"); switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: val.sh = (DevShort)val.db; str.str(""); str.clear(); str << val.sh; break; case Tango::DEV_LONG: val.lg = (DevLong)val.db; str.str(""); str.clear(); str << val.lg; break; case Tango::DEV_LONG64: val.lg64 = (DevLong64)val.db; str.str(""); str.clear(); str << val.lg64; break; case Tango::DEV_DOUBLE: break; case Tango::DEV_FLOAT: val.fl = (DevFloat)val.db; break; case Tango::DEV_USHORT: (val.db < 0.0) ? val.ush = (DevUShort)(-val.db) : val.ush = (DevUShort)val.db; str.str(""); str.clear(); str << val.ush; break; case Tango::DEV_UCHAR: (val.db < 0.0) ? val.uch = (DevUChar)(-val.db) : val.uch = (DevUChar)val.db; str.str(""); str.clear(); str << (short)val.uch; break; case Tango::DEV_ULONG: (val.db < 0.0) ? val.ulg = (DevULong)(-val.db) : val.ulg = (DevULong)val.db; str.str(""); str.clear(); str << val.ulg; break; case Tango::DEV_ULONG64: (val.db < 0.0) ? val.ulg64 = (DevULong64)(-val.db) : val.ulg64 = (DevULong64)val.db; str.str(""); str.clear(); str << val.ulg64; break; case Tango::DEV_ENCODED: (val.db < 0.0) ? val.uch = (DevUChar)(-val.db) : val.uch = (DevUChar)val.db; str.str(""); str.clear(); str << (short)val.uch; break; } if (data_type != Tango::DEV_FLOAT && data_type != Tango::DEV_DOUBLE) value_str = str.str(); } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::upd_database // // description : // Update database according to the info received in the v_db parameter. We update or delete info in db for // attribute configuration. // // Arguments: // in : // - v_db : The vector of info with what has to be done in DB // //--------------------------------------------------------------------------------------------------------------------- void Attribute::upd_database(vector &v_db) { // // Build info needed for the method upddating DB // long prop_to_update = 0; long prop_to_delete = 0; Tango::DbData db_d; Tango::DbData db_del; db_d.push_back(DbDatum(name)); db_del.push_back(DbDatum(name)); vector::iterator ite; // // A loop for each db action // for (ite = v_db.begin();ite != v_db.end();++ite) { switch (ite->dba) { case UPD: { DbDatum desc(ite->name); desc << ite->db_value; db_d.push_back(desc); prop_to_update++; } break; case UPD_FROM_DB: { DbDatum desc(ite->name); desc << ite->db_value_db; db_d.push_back(desc); prop_to_update++; } break; case UPD_FROM_VECT_STR: { DbDatum desc(ite->name); desc << ite->db_value_v_str; db_d.push_back(desc); prop_to_update++; } break; case DEL: { DbDatum desc(ite->name); db_del.push_back(desc); prop_to_delete++; } break; } } // // Update database // struct CheckOneStrProp cosp; cosp.prop_to_delete = &prop_to_delete; cosp.prop_to_update = &prop_to_update; cosp.db_d = &db_d; cosp.db_del = &db_del; db_access(cosp,d_name); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/attribute.cpp0000644023471100065110000045115313034745001015301 00000000000000static const char *RcsId = "$Id: attribute.cpp 30111 2016-08-31 14:17:26Z taurel $\n$Name$"; //==================================================================================================================== // // file : Attribute.cpp // // description : C++ source code for the Attribute class. This class is used to manage attribute. // A Tango Device object instance has one MultiAttribute object which is an aggregate of // Attribute or WAttribute objects // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30111 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { // // A classical function which will be used as unary predicate for the find_if // algo. It must be used with the bind2nd adapter to be transform as unary and // with the ptr_fun adapter to be transform as a function object // static bool WantedProp_f(AttrProperty a,const char *n) { return (a.get_name() == n); } //-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::Attribute // // description : // Constructor for the Attribute class from the attribute property vector, its type and the device name // // argument : // in : // - prop_list : The attribute property list // - tmp_attr : // - dev_name : The device name // - idx : // //-------------------------------------------------------------------------------------------------------------------- Attribute::Attribute(vector &prop_list,Attr &tmp_attr,string &dev_name,long idx) :date(true),quality(Tango::ATTR_VALID),check_min_value(false),check_max_value(false), enum_nb(0),loc_enum_ptr(Tango_nullptr),poll_period(0),event_period(0),archive_period(0),last_periodic(0.0), archive_last_periodic(0.0),periodic_counter(0),archive_periodic_counter(0), archive_last_event(0.0),dev(NULL),change_event_implmented(false), archive_event_implmented(false),check_change_event_criteria(true), check_archive_event_criteria(true),dr_event_implmented(false), scalar_str_attr_release(false),notifd_event(false),zmq_event(false), check_startup_exceptions(false),startup_exceptions_clear(true),att_mem_exception(false) { // // Create the extension class // ext = new Attribute::AttributeExt(); idx_in_attr = idx; d_name = dev_name; attr_serial_model = ATTR_BY_KERNEL; scalar_str_attr_release = false; // // Init the attribute name // name = tmp_attr.get_name(); name_size = name.size(); name_lower = name; transform(name_lower.begin(),name_lower.end(),name_lower.begin(),::tolower); // // Clear alarm data // alarm_conf.reset(); alarm.reset(); // // Init the remaining attribute main characteristic // data_type = tmp_attr.get_type(); writable = tmp_attr.get_writable(); data_format = tmp_attr.get_format(); disp_level = tmp_attr.get_disp_level(); poll_period = tmp_attr.get_polling_period(); writable_attr_name = tmp_attr.get_assoc(); // // Init the event characteristics // change_event_implmented = tmp_attr.is_change_event(); check_change_event_criteria = tmp_attr.is_check_change_criteria(); archive_event_implmented = tmp_attr.is_archive_event(); check_archive_event_criteria = tmp_attr.is_check_archive_criteria(); dr_event_implmented = tmp_attr.is_data_ready_event(); switch(data_format) { case Tango::SPECTRUM: max_x = static_cast(tmp_attr).get_max_x(); max_y = 0; dim_y = 0; break; case Tango::IMAGE: max_x = static_cast(tmp_attr).get_max_x(); max_y = static_cast(tmp_attr).get_max_y(); break; default : max_x = 1; max_y = 0; dim_x = 1; dim_y = 0; } // // Initialise optional properties // init_opt_prop(prop_list,dev_name); // // Initialise event related fields // init_event_prop(prop_list,dev_name,tmp_attr); // // Enum init (in case of) // if (data_type == DEV_ENUM) init_enum_prop(prop_list); } //-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::~Attribute // // description : // Destructor for the Attribute class // //-------------------------------------------------------------------------------------------------------------------- Attribute::~Attribute() { try { delete ext; delete [] loc_enum_ptr; } catch(omni_thread_fatal &){} } //-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_event_prop // // description : // Init the event related properties // // argument : // in : // - prop_list : The property vector // - dev_name : The device name // - att : The user attribute object // //------------------------------------------------------------------------------------------------------------------- void Attribute::init_event_prop(vector &prop_list,const string &dev_name,Attr &att) { rel_change[0] = INT_MAX; // default for relative change is none rel_change[1] = INT_MAX; // default for relative change is none abs_change[0] = INT_MAX; // default for absolute change is none abs_change[1] = INT_MAX; // default for absolute change is none archive_rel_change[0] = INT_MAX; // default for archive change is none archive_rel_change[1] = INT_MAX; // default for archive change is none archive_abs_change[0] = INT_MAX; // default for archive change is none archive_abs_change[1] = INT_MAX; // default for archive change is none notifd_event = false; zmq_event = false; vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); // // Init min and max relative change for change event // try { string rel_change_str; bool rel_change_defined = false; try { rel_change_str = get_attr_value(prop_list,"rel_change"); rel_change_defined = true; } catch (...) {} if(rel_change_defined) { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { vector rel_change_tmp; vector rel_change_set_usr_def; vector unused; validate_change_properties(dev_name,"rel_change",rel_change_str,rel_change_tmp,rel_change_set_usr_def,unused); rel_change[0] = rel_change_tmp[0]; rel_change[1] = rel_change_tmp[1]; if(rel_change_set_usr_def[0] || rel_change_set_usr_def[1]) { if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "rel_change") break; } if (i != nb_user) { vector rel_change_usr_def; validate_change_properties(dev_name,"rel_change",def_user_prop[i].get_value(),rel_change_usr_def); if(rel_change_set_usr_def[0]) rel_change[0] = rel_change_usr_def[0]; if(rel_change_set_usr_def[1]) rel_change[1] = rel_change_usr_def[1]; } } } cout1 << "Attribute::Attribute(): rel_change = " << rel_change[0] << " " << rel_change[1] << endl; } else throw_err_data_type("rel_change",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("rel_change",e); } // // Init min and max absolute change for change event // try { string abs_change_str; bool abs_change_defined = false; try { abs_change_str = get_attr_value(prop_list,"abs_change"); abs_change_defined = true; } catch (...) {} if(abs_change_defined) { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { vector abs_change_tmp; vector abs_change_set_usr_def; vector unused; validate_change_properties(dev_name,"abs_change",abs_change_str,abs_change_tmp,abs_change_set_usr_def,unused); abs_change[0] = abs_change_tmp[0]; abs_change[1] = abs_change_tmp[1]; if(abs_change_set_usr_def[0] || abs_change_set_usr_def[1]) { if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "abs_change") break; } if (i != nb_user) { vector abs_change_usr_def; validate_change_properties(dev_name,"abs_change",def_user_prop[i].get_value(),abs_change_usr_def); if(abs_change_set_usr_def[0]) abs_change[0] = abs_change_usr_def[0]; if(abs_change_set_usr_def[1]) abs_change[1] = abs_change_usr_def[1]; } } } cout1 << "Attribute::Attribute(): abs_change = " << abs_change[0] << " " << abs_change[1] << endl; } else throw_err_data_type("abs_change",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("abs_change",e); } // // Init min and max relative change for archive event // try { string archive_rel_change_str; bool archive_rel_change_defined = false; try { archive_rel_change_str = get_attr_value(prop_list,"archive_rel_change"); archive_rel_change_defined = true; } catch (...) {} if(archive_rel_change_defined) { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { vector archive_rel_change_tmp; vector archive_rel_change_set_usr_def; vector unused; validate_change_properties(dev_name,"archive_rel_change",archive_rel_change_str,archive_rel_change_tmp,archive_rel_change_set_usr_def,unused); archive_rel_change[0] = archive_rel_change_tmp[0]; archive_rel_change[1] = archive_rel_change_tmp[1]; if(archive_rel_change_set_usr_def[0] || archive_rel_change_set_usr_def[1]) { if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "archive_rel_change") break; } if (i != nb_user) { vector archive_rel_change_usr_def; validate_change_properties(dev_name,"archive_rel_change",def_user_prop[i].get_value(),archive_rel_change_usr_def); if(archive_rel_change_set_usr_def[0]) archive_rel_change[0] = archive_rel_change_usr_def[0]; if(archive_rel_change_set_usr_def[1]) archive_rel_change[1] = archive_rel_change_usr_def[1]; } } } cout1 << "Attribute::Attribute(): archive_rel_change = " << archive_rel_change[0] << " " << archive_rel_change[1] << endl; } else throw_err_data_type("archive_rel_change",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("archive_rel_change",e); } // // Init min and max absolute change for archive event // try { string archive_abs_change_str; bool archive_abs_change_defined = false; try { archive_abs_change_str = get_attr_value(prop_list,"archive_abs_change"); archive_abs_change_defined = true; } catch (...) {} if(archive_abs_change_defined) { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { vector archive_abs_change_tmp; vector archive_abs_change_set_usr_def; vector unused; validate_change_properties(dev_name,"archive_abs_change",archive_abs_change_str,archive_abs_change_tmp,archive_abs_change_set_usr_def,unused); archive_abs_change[0] = archive_abs_change_tmp[0]; archive_abs_change[1] = archive_abs_change_tmp[1]; if(archive_abs_change_set_usr_def[0] || archive_abs_change_set_usr_def[1]) { if (nb_user != 0) { size_t i; for (i = 0;i < nb_user;i++) { if (def_user_prop[i].get_name() == "archive_abs_change") break; } if (i != nb_user) { vector archive_abs_change_usr_def; validate_change_properties(dev_name,"archive_abs_change",def_user_prop[i].get_value(),archive_abs_change_usr_def); if(archive_abs_change_set_usr_def[0]) archive_abs_change[0] = archive_abs_change_usr_def[0]; if(archive_abs_change_set_usr_def[1]) archive_abs_change[1] = archive_abs_change_usr_def[1]; } } } cout1 << "Attribute::Attribute(): archive_abs_change = " << archive_abs_change[0] << " " << archive_abs_change[1] << endl; } else throw_err_data_type("archive_abs_change",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("archive_abs_change",e); } // // Init period for periodic event // try { event_period = (int)(DEFAULT_EVENT_PERIOD); // default for event period is 1 second string event_period_str; bool event_period_defined = false; try { event_period_str = get_attr_value(prop_list,"event_period"); event_period_defined = true; } catch (...) { } if(event_period_defined) { TangoSys_MemStream str; int event_period_tmp = 0; str << event_period_str; if(str >> event_period_tmp && str.eof()) { if (event_period_tmp > 0) event_period = event_period_tmp; cout1 << "Attribute::Attribute(): event_period_str " << event_period_str << " event_period = " << event_period << endl; } else throw_err_format("event_period",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("event_period",e); } // // Init period for archive event // try { archive_period = (int)(INT_MAX); string archive_period_str; bool archive_period_defined = false; try { archive_period_str = get_attr_value(prop_list,"archive_period"); archive_period_defined = true; } catch (...) { } if(archive_period_defined) { TangoSys_MemStream str; int archive_period_tmp = 0; str << archive_period_str; if(str >> archive_period_tmp && str.eof()) { if (archive_period_tmp > 0) { archive_period = archive_period_tmp; } cout1 << "Attribute::Attribute(): archive_period_str " << archive_period_str << " archive_period = " << archive_period << endl; } else throw_err_format("archive_period",dev_name,"Attribute::init_event_prop()"); } } catch(DevFailed &e) { add_startup_exception("archive_period",e); } // // Init remaining parameters // periodic_counter = 0; archive_periodic_counter = 0; last_periodic = 0.; archive_last_periodic = 0.; prev_change_event.inited = false; prev_change_event.err=false; prev_change_event.quality=Tango::ATTR_VALID; prev_archive_event.inited = false; prev_archive_event.err=false; prev_archive_event.quality=Tango::ATTR_VALID; prev_quality_event.inited = false; // // do not start sending events automatically, wait for the first client to subscribe. Sending events automatically // will put an unnecessary load on the server because all attributes will be polled // event_change3_subscription = 0; event_change4_subscription = 0; event_change5_subscription = 0; event_archive3_subscription = 0; event_archive4_subscription = 0; event_archive5_subscription = 0; event_periodic3_subscription = 0; event_periodic4_subscription = 0; event_periodic5_subscription = 0; event_user3_subscription = 0; event_user4_subscription = 0; event_user5_subscription = 0; event_attr_conf_subscription = 0; event_attr_conf5_subscription = 0; event_quality_subscription = 0; event_data_ready_subscription = 0; // // Init client lib parameters // for (int i = 0;i < numEventType;i++) client_lib[i].clear(); } //------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_check_val_prop // // description : // // // argument : // in : // - prop_list : The property vector // - dev_name : The device name (usefull for error) // - prop_name : Property name // - prop_comp : The property object used for checking if min > max // out : // - prop_str : property value as a string // - prop : The property object // //------------------------------------------------------------------------------------------------------------------- bool Attribute::init_check_val_prop (vector &prop_list,string &dev_name,const char* prop_name, string& prop_str,Tango::Attr_CheckVal &prop,Tango::Attr_CheckVal &prop_comp) { prop_str = get_attr_value(prop_list, prop_name); if (prop_str == AlrmValueNotSpec) return false; TangoSys_MemStream str; bool is_err_format = false; bool is_incoherent_val_err = false; bool min_prop = true; if (prop_name[1] == 'a') min_prop = false; str << prop_str; switch (data_type) { case Tango::DEV_SHORT: is_err_format = !(str >> prop.sh && str.eof()); if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.sh >= prop_comp.sh) is_incoherent_val_err = true; } else { if (prop_comp.sh >= prop.sh) is_incoherent_val_err = true; } } } break; case Tango::DEV_LONG: is_err_format = !(str >> prop.db && str.eof()); prop.lg = (DevLong)prop.db; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.lg >= prop_comp.lg) is_incoherent_val_err = true; } else { if (prop_comp.lg >= prop.lg) is_incoherent_val_err = true; } } } break; case Tango::DEV_LONG64: is_err_format = !(str >> prop.db && str.eof()); prop.lg64 = (DevLong64)prop.db; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.lg64 >= prop_comp.lg64) is_incoherent_val_err = true; } else { if (prop_comp.lg64 >= prop.lg64) is_incoherent_val_err = true; } } } break; case Tango::DEV_DOUBLE: is_err_format = !(str >> prop.db && str.eof()); if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.db >= prop_comp.db) is_incoherent_val_err = true; } else { if (prop_comp.db >= prop.db) is_incoherent_val_err = true; } } } break; case Tango::DEV_FLOAT: is_err_format = !(str >> prop.fl && str.eof()); if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.fl >= prop_comp.fl) is_incoherent_val_err = true; } else { if (prop_comp.fl >= prop.fl) is_incoherent_val_err = true; } } } break; case Tango::DEV_USHORT: is_err_format = !(str >> prop.ush && str.eof()); if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.ush >= prop_comp.ush) is_incoherent_val_err = true; } else { if (prop_comp.ush >= prop.ush) is_incoherent_val_err = true; } } } break; case Tango::DEV_UCHAR: is_err_format = !(str >> prop.sh && str.eof()); prop.uch = (DevUChar)prop.sh; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.uch >= prop_comp.uch) is_incoherent_val_err = true; } else { if (prop_comp.uch >= prop.uch) is_incoherent_val_err = true; } } } break; case Tango::DEV_ULONG: is_err_format = !(str >> prop.db && str.eof()); prop.ulg = (DevULong)prop.db; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.ulg >= prop_comp.ulg) is_incoherent_val_err = true; } else { if (prop_comp.ulg >= prop.ulg) is_incoherent_val_err = true; } } } break; case Tango::DEV_ULONG64: is_err_format = !(str >> prop.db && str.eof()); prop.ulg64 = (DevULong64)prop.db; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.ulg64 >= prop_comp.ulg64) is_incoherent_val_err = true; } else { if (prop_comp.ulg64 >= prop.ulg64) is_incoherent_val_err = true; } } } break; case Tango::DEV_ENCODED: is_err_format = !(str >> prop.sh && str.eof()); prop.uch = (DevUChar)prop.sh; if (is_err_format == false) { if (is_value_set(prop_name) == true) { if (min_prop == true) { if (prop.uch >= prop_comp.uch) is_incoherent_val_err = true; } else { if (prop_comp.uch >= prop.uch) is_incoherent_val_err = true; } } } break; default: throw_err_data_type(prop_name, dev_name, "Attribute::init_opt_prop()"); } if (is_err_format) throw_err_format(prop_name, dev_name, "Attribute::init_opt_prop()"); else if (is_incoherent_val_err) { string opp_prop_name(prop_name); opp_prop_name[1] = (opp_prop_name[1] == 'a') ? ('i') : ('a'); // max_... -> mix_... || min_... -> man_... opp_prop_name[2] = (opp_prop_name[2] == 'x') ? ('n') : ('x'); // mix_... -> min_... || man_... -> max_... if (prop_name[1] == 'a') throw_incoherent_val_err(opp_prop_name.c_str(),prop_name,dev_name,"Attribute::init_opt_prop()"); else throw_incoherent_val_err(prop_name,opp_prop_name.c_str(),dev_name,"Attribute::init_opt_prop()"); } return true; } //------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_opt_prop // // description : // Init the optional properties // // argument : // in : // - prop_list : The property vector // - dev_name : The device name (usefull for error) // //------------------------------------------------------------------------------------------------------------------- void Attribute::init_opt_prop(vector &prop_list,string &dev_name) { // // Init the properties // init_string_prop(prop_list, label, "label"); init_string_prop(prop_list, description, "description"); init_string_prop(prop_list, unit, "unit"); init_string_prop(prop_list, standard_unit, "standard_unit"); init_string_prop(prop_list, display_unit, "display_unit"); init_string_prop(prop_list, format, "format"); // // Init the min alarm property // try { if (init_check_val_prop(prop_list,dev_name,"min_alarm",min_alarm_str,min_alarm,max_alarm) == true) alarm_conf.set(min_level); } catch (DevFailed &e) { add_startup_exception("min_alarm",e); } // // Init the max alarm property // try { if (init_check_val_prop(prop_list,dev_name,"max_alarm",max_alarm_str,max_alarm,min_alarm) == true) alarm_conf.set(max_level); } catch (DevFailed &e) { add_startup_exception("max_alarm",e); } // // Init the min value property // try { if (init_check_val_prop(prop_list,dev_name,"min_value",min_value_str,min_value,max_value) == true) check_min_value = true; } catch (DevFailed &e) { add_startup_exception("min_value",e); } // // Init the max value property // try { if (init_check_val_prop(prop_list,dev_name,"max_value",max_value_str,max_value,min_value) == true) check_max_value = true; } catch (DevFailed &e) { add_startup_exception("max_value",e); } // // Init the min warning property // try { if (init_check_val_prop(prop_list,dev_name,"min_warning",min_warning_str,min_warning,max_warning) == true) alarm_conf.set(min_warn); } catch(DevFailed &e) { add_startup_exception("min_warning",e); } // // Init the max warning property // try { if (init_check_val_prop(prop_list,dev_name,"max_warning",max_warning_str,max_warning,min_warning) == true) alarm_conf.set(max_warn); } catch (DevFailed &e) { add_startup_exception("max_warning",e); } // // Get delta_t property // bool delta_t_defined = false; try { delta_t_str = get_attr_value(prop_list,"delta_t"); if (delta_t_str != "0") { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { delta_t = get_lg_attr_value(prop_list,"delta_t"); if (delta_t != 0) delta_t_defined = true; } else throw_err_data_type("delta_t",dev_name,"Attribute::init_opt_prop()"); } else delta_t = 0; } catch(DevFailed &e) { add_startup_exception("delta_t",e); } // // Get delta_val property // bool delta_val_defined = false; try { delta_val_str = get_attr_value(prop_list,"delta_val"); if (delta_val_str != AlrmValueNotSpec) { if((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE) && (data_type != Tango::DEV_ENUM)) { TangoSys_MemStream str; str << delta_val_str; switch (data_type) { case Tango::DEV_SHORT: if (!(str >> delta_val.sh && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); break; case Tango::DEV_LONG: if (!(str >> delta_val.db && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.lg = (DevLong)delta_val.db; break; case Tango::DEV_LONG64: if (!(str >> delta_val.db && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.lg64 = (DevLong64)delta_val.db; break; case Tango::DEV_DOUBLE: if (!(str >> delta_val.db && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); break; case Tango::DEV_FLOAT: if (!(str >> delta_val.fl && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); break; case Tango::DEV_USHORT: if (!(str >> delta_val.ush && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); break; case Tango::DEV_UCHAR: if (!(str >> delta_val.sh && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.uch = (DevUChar)delta_val.sh; break; case Tango::DEV_ULONG: if (!(str >> delta_val.db && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.ulg = (DevULong)delta_val.db; break; case Tango::DEV_ULONG64: if (!(str >> delta_val.db && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.ulg64 = (DevULong64)delta_val.db; break; case Tango::DEV_ENCODED: if (!(str >> delta_val.sh && str.eof())) throw_err_format("delta_val",dev_name,"Attribute::init_opt_prop()"); delta_val.uch = (DevUChar)delta_val.sh; break; } if(delta_t_defined) alarm_conf.set(rds); // set RDS flag only if both delta_t and delta_val are set delta_val_defined = true; } else throw_err_data_type("delta_val",dev_name,"Attribute::init_opt_prop()"); } } catch(DevFailed &e) { add_startup_exception("delta_val",e); } // // Throw exception if only one RDS property is defined // try { if (((delta_t_defined == true) && (delta_val_defined == false)) || ((delta_t_defined == false) && (delta_val_defined == true))) { TangoSys_OMemStream o; o << "RDS alarm properties (delta_t and delta_val) are not correctly defined for attribute " << name; o << " in device " << dev_name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::init_opt_prop()"); } } catch(DevFailed &e) { add_startup_exception("rds_alarm",e); } } //------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_enum_prop // // description : // Get the enumeration labels from the property vector // // argument : // in : // - prop_list : The property vector // //------------------------------------------------------------------------------------------------------------------- void Attribute::init_enum_prop(vector &prop_list) { try { string tmp_enum_label = get_attr_value(prop_list,"enum_labels"); build_check_enum_labels(tmp_enum_label); } catch(DevFailed &e) { string desc(e.errors[0].desc.in()); if (desc.find("Property enum_labels is missing") != string::npos) { stringstream ss; ss << "The attribute " << name << " has the DEV_ENUM data type but there is no enumeration label(s) defined"; e.errors[0].desc = CORBA::string_dup(ss.str().c_str()); } add_startup_exception("enum_labels",e); } } //------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::build_check_enum_labels // // description : // Create vector of enum labels and check that the same label is not used several times // // argument : // in : // - labs : The enum labels (labels1,label2,label3,...) // //------------------------------------------------------------------------------------------------------------------- void Attribute::build_check_enum_labels(string &labs) { string::size_type pos = 0; string::size_type start = 0; bool exit = false; enum_labels.clear(); // // Build vector with enum labels // while(exit == false) { pos = labs.find(',',start); if (pos == string::npos) { string tmp = labs.substr(start); enum_labels.push_back(tmp); exit = true; } else { string tmp = labs.substr(start,pos - start); enum_labels.push_back(tmp); start = pos + 1; } } // // Check that all labels are different // vector v_s = enum_labels; sort(v_s.begin(),v_s.end()); for (size_t loop = 1;loop < v_s.size();loop++) { if (v_s[loop - 1] == v_s[loop]) { stringstream ss; ss << "Enumeration for attribute " << name << " has two similar labels ("; ss << v_s[loop - 1] << ", " << v_s[loop] << ")"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::build_check_enum_labels"); } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::add_startup_exception // // description : // Stores an exception raised during the device startup sequence in a map // // argument : // in : // - prop_name : The property name for which the exception was raised // - except : The raised exception // //------------------------------------------------------------------------------------------------------------------- void Attribute::add_startup_exception(string prop_name,const DevFailed &except) { startup_exceptions.insert(pair(prop_name,except)); check_startup_exceptions = true; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::delete_startup_exception // // description : // Deletes the exception related to the property name from startup_exceptions map // // argument : // in : // - prop_name : The property name as a key for which the exception is to be deleted from // startup_exceptions map // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------- void Attribute::delete_startup_exception(string prop_name,string dev_name) { if(check_startup_exceptions == true) { map::iterator it = startup_exceptions.find(prop_name); if(it != startup_exceptions.end()) startup_exceptions.erase(it); if(startup_exceptions.empty() == true) check_startup_exceptions = false; Util *tg = Util::instance(); bool dev_restart = false; if (dev_name != "None") { dev_restart = tg->is_device_restarting(dev_name); } if (tg->is_svr_starting() == false && dev_restart == false) { DeviceImpl *dev = get_att_device(); dev->set_run_att_conf_loop(true); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::throw_err_format // // description : // Throw a Tango DevFailed exception when an error format is detected in the string which should be converted // to a number // // argument : // in : // - prop_name : The property name // - dev_name : The device name // - origin : The origin of the exception // //-------------------------------------------------------------------------------------------------------------------- void Attribute::throw_err_format(const char *prop_name,const string &dev_name,const char *origin) { TangoSys_OMemStream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nThe property " << prop_name << " is defined in an unsupported format" << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)origin); } //+------------------------------------------------------------------------- // // method : Attribute::throw_incoherent_val_err // // description : Throw a Tango DevFailed exception when the min or max // property is incoherent with its counterpart // // in : min_prop : The min property name // max_prop : The max property name // dev_name : The device name // origin : The origin of the exception // //-------------------------------------------------------------------------- void Attribute::throw_incoherent_val_err(const char *min_prop,const char *max_prop,const string &dev_name,const char *origin) { TangoSys_OMemStream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nValue of " << min_prop << " is greater than or equal to " << max_prop << ends; Except::throw_exception((const char *)API_IncoherentValues, o.str(), (const char *)origin); } //+------------------------------------------------------------------------- // // method : Attribute::throw_err_data_type // // description : Throw a Tango DevFailed exception when an error on // data type is detected // // in : prop_name : The property name // dev_name : The device name // origin : The origin of the exception // //-------------------------------------------------------------------------- void Attribute::throw_err_data_type(const char *prop_name,const string &dev_name,const char *origin) { TangoSys_OMemStream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nThe property " << prop_name << " is not settable for the attribute data type" << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)origin); } //+------------------------------------------------------------------------- // // method : Attribute::throw_min_max_value // // description : Throw a Tango DevFailed exception when an error on // min/max value is detected // // in : dev_name : The device name // memorized_value : The attribute memorized value // check_type : The type of check which was done (min_value or max_value) // //-------------------------------------------------------------------------- void Attribute::throw_min_max_value(string &dev_name,string &memorized_value,MinMaxValueCheck check_type) { TangoSys_OMemStream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nThis attribute is memorized and the memorized value (" << memorized_value << ") is "; if (check_type == MIN) o << "below"; else o << "above"; o << " the new limit!!" << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::throw_min_max_value()"); } //+------------------------------------------------------------------------- // // method : Attribute::is_polled // // description : Check if the attribute polled // // This method returns a boolean set to true if the attribute is polled // //-------------------------------------------------------------------------- bool Attribute::is_polled() { Tango::Util *tg = Util::instance(); if ( dev == NULL ) { dev = tg->get_device_by_name(d_name); } string &att_name = get_name_lower(); vector &attr_list = dev->get_polled_attr(); for (unsigned int i = 0;i < attr_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(attr_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( att_name == name_lowercase ) { // // when the polling buffer is externally filled (polling period == 0) // mark the attribute as not polled! No events can be send by the polling thread! // if ( attr_list[i+1] == "0" ) { return false; } else return true; } } // // now check wether a polling period is set ( for example by pogo) // if ( get_polling_period() > 0 ) { // // check the list of non_auto_polled attributes to verify wether // the polling was disabled // vector &napa = dev->get_non_auto_polled_attr(); for (unsigned int j = 0;j < napa.size();j++) { #ifdef _TG_WINDOWS_ if (_stricmp(napa[j].c_str(), att_name.c_str()) == 0) #else if (strcasecmp(napa[j].c_str(), att_name.c_str()) == 0) #endif { return false; } } return true; } return false; } bool Attribute::is_polled(DeviceImpl *the_dev) { if ((the_dev != NULL) && (dev == NULL)) { dev = the_dev; } return is_polled(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::is_writ_associated // // description : // Check if the attribute has an associated writable attribute // // returns: // This method returns a boolean set to true if the atribute has an associatied writable attribute // //------------------------------------------------------------------------------------------------------------------- bool Attribute::is_writ_associated() { if (writable_attr_name != AssocWritNotSpec) return true; else return false; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_attr_value // // description : // Retrieve a property value as a string from the vector of properties // // arguments : // in : // - prop_list : The property vector // - prop_name : the property name // //------------------------------------------------------------------------------------------------------------------- string &Attribute::get_attr_value(vector &prop_list,const char *prop_name) { vector::iterator pos; // // Get the property value // pos = find_if(prop_list.begin(),prop_list.end(),bind2nd(ptr_fun(WantedProp_f),prop_name)); if (pos == prop_list.end()) { TangoSys_OMemStream o; o << "Property " << prop_name << " is missing for attribute " << name << ends; Except::throw_exception(API_AttrOptProp,o.str(),"Attribute::get_attr_value()"); } return pos->get_value(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_lg_attr_value // // description : // Retrieve a property value as a long from the vector of properties // // argument : // in : // - prop_list : The property vector // - prop_name : the property name // //------------------------------------------------------------------------------------------------------------------ long Attribute::get_lg_attr_value(vector &prop_list,const char *prop_name) { vector::iterator pos; // // Get the property value // pos = find_if(prop_list.begin(),prop_list.end(),bind2nd(ptr_fun(WantedProp_f),prop_name)); if (pos == prop_list.end()) { TangoSys_OMemStream o; o << "Property " << prop_name << " is missing for attribute " << name << ends; Except::throw_exception(API_AttrOptProp,o.str(),"Attribute::get_attr_value()"); } pos->convert(prop_name); return pos->get_lg_value(); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_data_size // // description : // Compute the attribute amount of data // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_data_size() { switch(data_format) { case Tango::SCALAR : data_size = 1; break; case Tango::SPECTRUM : data_size = dim_x; break; case Tango::IMAGE : data_size = dim_x * dim_y; break; case FMT_UNKNOWN : data_size = 0; break; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_time // // description : // Set the date if the date flag is true // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_time() { if (date == true) { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); when.tv_sec = (CORBA::Long)t.time; when.tv_usec = (CORBA::Long)(t.millitm * 1000); when.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); when.tv_sec = (CORBA::Long)tv.tv_sec; when.tv_usec = (CORBA::Long)tv.tv_usec; when.tv_nsec = 0; #endif } } //+------------------------------------------------------------------------- // // method : Attribute::check_alarm // // description : Check if the attribute is in alarm // // This method returns a boolean set to true if the atribute is in alarm. In // this case, it also set the attribute quality factor to ALARM // //-------------------------------------------------------------------------- bool Attribute::check_alarm() { bool returned = false; // // Throw exception if no alarm is defined for this attribute // if (is_alarmed().none() == true) { TangoSys_OMemStream o; o << "No alarm defined for attribute " << name << ends; Except::throw_exception((const char *)API_AttrNoAlarm,o.str(), (const char *)"Attribute::check_alarm()"); } // // If the attribute quality is different than VALID don`t do any checking to avoid // to override a user positioned quality value. // If no alarms levels are specified, just return without alarm. // if (is_fwd_att() == false && quality != Tango::ATTR_VALID ) { log_quality(); return returned; } // // Get the monitor protecting device att config // TangoMonitor &mon1 = get_att_device()->get_att_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // If some alarm are defined on level, check attribute level // bitset &bs = is_alarmed(); if ((bs.test(Attribute::min_level) == true) || (bs.test(Attribute::max_level) == true)) { if (check_level_alarm() == true) returned = true; } if (returned == false) { if ((bs.test(Attribute::min_warn) == true) || (bs.test(Attribute::max_warn) == true)) { if (check_warn_alarm() == true) returned = true; } } // // If the RDS alarm is set, check attribute level // if ((bs.test(Attribute::rds) == true)) { if (check_rds_alarm() == true) returned = true; } log_quality(); return returned; } //+------------------------------------------------------------------------- // // method : Attribute::check_level_alarm // // description : Check if the attribute is in alarm level // // This method returns a boolean set to true if the atribute is in alarm. In // this case, it also set the attribute quality factor to ALARM // //-------------------------------------------------------------------------- bool Attribute::check_level_alarm() { bool returned = false; bool real_returned = false; // // Check the min alarm if defined // long i; if (alarm_conf.test(min_level) == true) { switch (data_type) { case Tango::DEV_SHORT: if (check_scalar_wattribute() == true) { short tmp_val; if (date == false) tmp_val = (*value.sh_seq)[0]; else tmp_val = tmp_sh[0]; if (tmp_val <= min_alarm.sh) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.sh_seq)[i] <= min_alarm.sh) { returned = true; break; } } } break; case Tango::DEV_LONG: if (check_scalar_wattribute() == true) { Tango::DevLong tmp_val; if (date == false) tmp_val = (*value.lg_seq)[0]; else tmp_val = tmp_lo[0]; if (tmp_val <= min_alarm.lg) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.lg_seq)[i] <= min_alarm.lg) { returned = true; break; } } } break; case Tango::DEV_LONG64: if (check_scalar_wattribute() == true) { Tango::DevLong64 tmp_val; if (date == false) tmp_val = (*value.lg64_seq)[0]; else tmp_val = tmp_lo64[0]; if (tmp_val <= min_alarm.lg64) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.lg64_seq)[i] <= min_alarm.lg64) { returned = true; break; } } } break; case Tango::DEV_DOUBLE: if (check_scalar_wattribute() == true) { Tango::DevDouble tmp_val; if (date == false) tmp_val = (*value.db_seq)[0]; else tmp_val = tmp_db[0]; if (tmp_val <= min_alarm.db) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.db_seq)[i] <= min_alarm.db) { returned = true; break; } } } break; case Tango::DEV_FLOAT: if (check_scalar_wattribute() == true) { Tango::DevFloat tmp_val; if (date == false) tmp_val = (*value.fl_seq)[0]; else tmp_val = tmp_fl[0]; if (tmp_val <= min_alarm.fl) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.fl_seq)[i] <= min_alarm.fl) { returned = true; break; } } } break; case Tango::DEV_USHORT: if (check_scalar_wattribute() == true) { Tango::DevUShort tmp_val; if (date == false) tmp_val = (*value.ush_seq)[0]; else tmp_val = tmp_ush[0]; if (tmp_val <= min_alarm.ush) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ush_seq)[i] <= min_alarm.ush) { returned = true; break; } } } break; case Tango::DEV_UCHAR: if (check_scalar_wattribute() == true) { Tango::DevUChar tmp_val; if (date == false) tmp_val = (*value.cha_seq)[0]; else tmp_val = tmp_cha[0]; if (tmp_val <= min_alarm.uch) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.cha_seq)[i] <= min_alarm.uch) { returned = true; break; } } } break; case Tango::DEV_ULONG64: if (check_scalar_wattribute() == true) { Tango::DevULong64 tmp_val; if (date == false) tmp_val = (*value.ulg64_seq)[0]; else tmp_val = tmp_ulo64[0]; if (tmp_val <= min_alarm.ulg64) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ulg64_seq)[i] <= min_alarm.ulg64) { returned = true; break; } } } break; case Tango::DEV_ULONG: if (check_scalar_wattribute() == true) { Tango::DevULong tmp_val; if (date == false) tmp_val = (*value.ulg_seq)[0]; else tmp_val = tmp_ulo[0]; if (tmp_val <= min_alarm.ulg) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ulg_seq)[i] <= min_alarm.ulg) { returned = true; break; } } } break; case Tango::DEV_ENCODED: if (check_scalar_wattribute() == true) { for (unsigned int i = 0;i < tmp_enc[0].encoded_data.length();i++) { if (tmp_enc[0].encoded_data[i] <= min_alarm.uch) { returned = true; break; } } } else { for (unsigned int i = 0;i < (*value.enc_seq)[0].encoded_data.length();i++) { if ((*value.enc_seq)[0].encoded_data[i] <= min_alarm.uch) { returned = true; break; } } } break; } if (returned == true) { quality = Tango::ATTR_ALARM; alarm.set(min_level); real_returned = true; } } // // Check the max alarm if defined // returned = false; if (alarm_conf.test(max_level) == true) { switch (data_type) { case Tango::DEV_SHORT: if (check_scalar_wattribute() == true) { Tango::DevShort tmp_val; if (date == false) tmp_val = (*value.sh_seq)[0]; else tmp_val = tmp_sh[0]; if (tmp_val >= max_alarm.sh) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.sh_seq)[i] >= max_alarm.sh) { returned = true; break; } } } break; case Tango::DEV_LONG: if (check_scalar_wattribute() == true) { Tango::DevLong tmp_val; if (date == false) tmp_val = (*value.lg_seq)[0]; else tmp_val = tmp_lo[0]; if (tmp_val >= max_alarm.lg) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.lg_seq)[i] >= max_alarm.lg) { returned = true; break; } } } break; case Tango::DEV_LONG64: if (check_scalar_wattribute() == true) { Tango::DevLong64 tmp_val; if (date == false) tmp_val = (*value.lg64_seq)[0]; else tmp_val = tmp_lo64[0]; if (tmp_val >= max_alarm.lg64) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.lg64_seq)[i] >= max_alarm.lg64) { returned = true; break; } } } break; case Tango::DEV_DOUBLE: if (check_scalar_wattribute() == true) { Tango::DevDouble tmp_val; if (date == false) tmp_val = (*value.db_seq)[0]; else tmp_val = tmp_db[0]; if (tmp_val >= max_alarm.db) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.db_seq)[i] >= max_alarm.db) { returned = true; break; } } } break; case Tango::DEV_FLOAT: if (check_scalar_wattribute() == true) { Tango::DevFloat tmp_val; if (date == false) tmp_val = (*value.fl_seq)[0]; else tmp_val = tmp_fl[0]; if (tmp_val >= max_alarm.fl) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.fl_seq)[i] >= max_alarm.fl) { returned = true; break; } } } break; case Tango::DEV_USHORT: if (check_scalar_wattribute() == true) { Tango::DevUShort tmp_val; if (date == false) tmp_val = (*value.ush_seq)[0]; else tmp_val = tmp_ush[0]; if (tmp_val >= max_alarm.ush) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ush_seq)[i] >= max_alarm.ush) { returned = true; break; } } } break; case Tango::DEV_UCHAR: if (check_scalar_wattribute() == true) { Tango::DevUChar tmp_val; if (date == false) tmp_val = (*value.cha_seq)[0]; else tmp_val = tmp_cha[0]; if (tmp_val >= max_alarm.uch) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.cha_seq)[i] >= max_alarm.uch) { returned = true; break; } } } break; case Tango::DEV_ULONG: if (check_scalar_wattribute() == true) { Tango::DevULong tmp_val; if (date == false) tmp_val = (*value.ulg_seq)[0]; else tmp_val = tmp_ulo[0]; if (tmp_val >= max_alarm.ulg) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ulg_seq)[i] >= max_alarm.ulg) { returned = true; break; } } } break; case Tango::DEV_ULONG64: if (check_scalar_wattribute() == true) { Tango::DevULong64 tmp_val; if (date == false) tmp_val = (*value.ulg64_seq)[0]; else tmp_val = tmp_ulo64[0]; if (tmp_val >= max_alarm.ulg64) returned = true; } else { for (i = 0;i < data_size;i++) { if ((*value.ulg64_seq)[i] >= max_alarm.ulg64) { returned = true; break; } } } break; case Tango::DEV_ENCODED: if (check_scalar_wattribute() == true) { for (unsigned int i = 0;i < tmp_enc[0].encoded_data.length();i++) { if (tmp_enc[0].encoded_data[i] >= max_alarm.uch) { returned = true; break; } } } else { for (unsigned int i = 0;i < (*value.enc_seq)[0].encoded_data.length();i++) { if ((*value.enc_seq)[0].encoded_data[i] >= max_alarm.uch) { returned = true; break; } } } break; } if (returned == true) { quality = Tango::ATTR_ALARM; alarm.set(max_level); real_returned = true; } } return real_returned; } //+------------------------------------------------------------------------- // // method : Attribute::check_warn_alarm // // description : Check if the attribute is in warning alarm // // This method returns a boolean set to true if the atribute is in alarm. In // this case, it also set the attribute quality factor to ALARM // //-------------------------------------------------------------------------- bool Attribute::check_warn_alarm() { bool returned = false; bool real_returned = false; // // Check the min warning if defined // long i; if (alarm_conf.test(min_warn) == true) { switch (data_type) { case Tango::DEV_SHORT: if (check_scalar_wattribute() == true) { Tango::DevShort tmp_val; tmp_val = date == false ? (*value.sh_seq)[0] : tmp_sh[0]; if (tmp_val <= min_warning.sh) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.sh_seq)[i] <= min_warning.sh) { returned = true; break; } } } break; case Tango::DEV_LONG: if (check_scalar_wattribute() == true) { Tango::DevLong tmp_val; tmp_val = date == false ? (*value.lg_seq)[0] : tmp_lo[0]; if (tmp_val <= min_warning.lg) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.lg_seq)[i] <= min_warning.lg) { returned = true; break; } } } break; case Tango::DEV_LONG64: if (check_scalar_wattribute() == true) { Tango::DevLong64 tmp_val; tmp_val = date == false ? (*value.lg64_seq)[0] : tmp_lo64[0]; if (tmp_val <= min_warning.lg64) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.lg64_seq)[i] <= min_warning.lg64) { returned = true; break; } } } break; case Tango::DEV_DOUBLE: if (check_scalar_wattribute() == true) { Tango::DevDouble tmp_val; tmp_val = date == false ? (*value.db_seq)[0] : tmp_db[0]; if (tmp_val <= min_warning.db) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.db_seq)[i] <= min_warning.db) { returned = true; break; } } } break; case Tango::DEV_FLOAT: if (check_scalar_wattribute() == true) { Tango::DevFloat tmp_val; tmp_val = date == false ? (*value.fl_seq)[0] : tmp_fl[0]; if (tmp_val <= min_warning.fl) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.fl_seq)[i] <= min_warning.fl) { returned = true; break; } } } break; case Tango::DEV_USHORT: if (check_scalar_wattribute() == true) { Tango::DevUShort tmp_val; tmp_val = date == false ? (*value.ush_seq)[0] : tmp_ush[0]; if (tmp_val <= min_warning.ush) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ush_seq)[i] <= min_warning.ush) { returned = true; break; } } } break; case Tango::DEV_UCHAR: if (check_scalar_wattribute() == true) { Tango::DevUChar tmp_val; tmp_val = date == false ? (*value.cha_seq)[0] : tmp_cha[0]; if (tmp_val <= min_warning.uch) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.cha_seq)[i] <= min_warning.uch) { returned = true; break; } } } break; case Tango::DEV_ULONG: if (check_scalar_wattribute() == true) { Tango::DevULong tmp_val; tmp_val = date == false ? (*value.ulg_seq)[0] : tmp_ulo[0]; if (tmp_val <= min_warning.ulg) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ulg_seq)[i] <= min_warning.ulg) { returned = true; break; } } } break; case Tango::DEV_ULONG64: if (check_scalar_wattribute() == true) { Tango::DevULong64 tmp_val; tmp_val = date == false ? (*value.ulg64_seq)[0] : tmp_ulo64[0]; if (tmp_val <= min_warning.ulg64) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ulg64_seq)[i] <= min_warning.ulg64) { returned = true; break; } } } break; case Tango::DEV_ENCODED: if (check_scalar_wattribute() == true) { for (unsigned int i = 0;i < tmp_enc[0].encoded_data.length();i++) { Tango::DevUChar tmp_val; tmp_val = date == false ? (*value.enc_seq)[0].encoded_data[i] : tmp_enc[0].encoded_data[i]; if (tmp_val <= min_warning.uch) { returned = true; break; } } } else { for (unsigned int i = 0;i < (*value.enc_seq)[0].encoded_data.length();i++) { if ((*value.enc_seq)[0].encoded_data[i] <= min_warning.uch) { returned = true; break; } } } break; } if (returned == true) { quality = Tango::ATTR_WARNING; alarm.set(min_warn); real_returned = true; } } // // Check the max warning if defined // returned = false; if (alarm_conf.test(max_warn) == true) { switch (data_type) { case Tango::DEV_SHORT: if (check_scalar_wattribute() == true) { Tango::DevShort tmp_val; tmp_val = date == false ? (*value.sh_seq)[0] : tmp_sh[0]; if (tmp_val >= max_warning.sh) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.sh_seq)[i] >= max_warning.sh) { returned = true; break; } } } break; case Tango::DEV_LONG: if (check_scalar_wattribute() == true) { Tango::DevLong tmp_val; tmp_val = date == false ? (*value.lg_seq)[0] : tmp_lo[0]; if (tmp_val >= max_warning.lg) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.lg_seq)[i] >= max_warning.lg) { returned = true; break; } } } break; case Tango::DEV_LONG64: if (check_scalar_wattribute() == true) { Tango::DevLong64 tmp_val; tmp_val = date == false ? (*value.lg64_seq)[0] : tmp_lo64[0]; if (tmp_val >= max_warning.lg64) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.lg64_seq)[i] >= max_warning.lg64) { returned = true; break; } } } break; case Tango::DEV_DOUBLE: if (check_scalar_wattribute() == true) { Tango::DevDouble tmp_val; tmp_val = date == false ? (*value.db_seq)[0] : tmp_db[0]; if (tmp_val >= max_warning.db) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.db_seq)[i] >= max_warning.db) { returned = true; break; } } } break; case Tango::DEV_FLOAT: if (check_scalar_wattribute() == true) { Tango::DevFloat tmp_val; tmp_val = date == false ? (*value.fl_seq)[0] : tmp_fl[0]; if (tmp_val >= max_warning.fl) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.fl_seq)[i] >= max_warning.fl) { returned = true; break; } } } break; case Tango::DEV_USHORT: if (check_scalar_wattribute() == true) { Tango::DevUShort tmp_val; tmp_val = date == false ? (*value.ush_seq)[0] : tmp_ush[0]; if (tmp_val >= max_warning.ush) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ush_seq)[i] >= max_warning.ush) { returned = true; break; } } } break; case Tango::DEV_UCHAR: if (check_scalar_wattribute() == true) { Tango::DevUChar tmp_val; tmp_val = date == false ? (*value.cha_seq)[0] : tmp_cha[0]; if (tmp_val >= max_warning.uch) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.cha_seq)[i] >= max_warning.uch) { returned = true; break; } } } break; case Tango::DEV_ULONG: if (check_scalar_wattribute() == true) { Tango::DevULong tmp_val; tmp_val = date == false ? (*value.ulg_seq)[0] : tmp_ulo[0]; if (tmp_val >= max_warning.ulg) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ulg_seq)[i] >= max_warning.ulg) { returned = true; break; } } } break; case Tango::DEV_ULONG64: if (check_scalar_wattribute() == true) { Tango::DevULong64 tmp_val; tmp_val = date == false ? (*value.ulg64_seq)[0] : tmp_ulo64[0]; if (tmp_val >= max_warning.ulg64) { returned = true; } } else { for (i = 0;i < data_size;i++) { if ((*value.ulg64_seq)[i] >= max_warning.ulg64) { returned = true; break; } } } break; case Tango::DEV_ENCODED: if (check_scalar_wattribute() == true) { for (unsigned int i = 0;i < tmp_enc[0].encoded_data.length();i++) { Tango::DevUChar tmp_val; tmp_val = date == false ? (*value.enc_seq)[0].encoded_data[i] : tmp_enc[0].encoded_data[i]; if (tmp_val >= max_warning.uch) { returned = true; break; } } } else { for (unsigned int i = 0;i < (*value.enc_seq)[0].encoded_data.length();i++) { if ((*value.enc_seq)[0].encoded_data[i] >= max_warning.uch) { returned = true; break; } } } break; } if (returned == true) { quality = Tango::ATTR_WARNING; alarm.set(max_warn); real_returned = true; } } return real_returned; } //+------------------------------------------------------------------------- // // method : Attribute::check_scalar_wattribute // // description : Check whether the attribute is a READ_WRITE or // READ_WITH_WRITE scalar attribute. // //-------------------------------------------------------------------------- bool Attribute::check_scalar_wattribute() { if ((writable == Tango::READ_WRITE) || (writable == Tango::READ_WITH_WRITE)) { if (data_format == Tango::SCALAR) return true; } return false; } //+------------------------------------------------------------------------- // // method : Attribute::delete_seq // // description : Delete the sequence created to store attribute // value. // In case of a read_attributes CORBA operation, // this delete will be done automatically because the // sequence is inserted in an CORBA::Any object which will // delete the sequence when it is destroyed. // This method is usefull only to delete the sequence // created in case of the attribute is read during a // DevState command to evaluate device state // //-------------------------------------------------------------------------- void Attribute::delete_seq() { switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: delete value.sh_seq; break; case Tango::DEV_LONG: delete value.lg_seq; break; case Tango::DEV_LONG64: delete value.lg64_seq; break; case Tango::DEV_DOUBLE: delete value.db_seq; break; case Tango::DEV_STRING: delete value.str_seq; break; case Tango::DEV_FLOAT: delete value.fl_seq; break; case Tango::DEV_USHORT: delete value.ush_seq; break; case Tango::DEV_UCHAR: delete value.cha_seq; break; case Tango::DEV_BOOLEAN: delete value.boo_seq; break; case Tango::DEV_ULONG: delete value.ulg_seq; break; case Tango::DEV_ULONG64: delete value.ulg64_seq; break; case Tango::DEV_STATE: delete value.state_seq; break; case Tango::DEV_ENCODED: delete value.enc_seq; break; } } //+------------------------------------------------------------------------- // // method : Attribute::add_write_value // // description : These methods add the associated writable attribute // value to the read attribute buffer and create a // sequence from the attribute internal buffer // // in : val : The associated write attribute value // //-------------------------------------------------------------------------- void Attribute::add_write_value(Tango::DevVarShortArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_sh[1] = (*val_ptr)[0]; value.sh_seq = new Tango::DevVarShortArray(data_size + 1,data_size + 1,tmp_sh,false); } else { long nb_read = value.sh_seq->length(); value.sh_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.sh_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarLongArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_lo[1] = (*val_ptr)[0]; value.lg_seq = new Tango::DevVarLongArray(data_size + 1,data_size + 1,tmp_lo,false); } else { long nb_read = value.lg_seq->length(); value.lg_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.lg_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarLong64Array *val_ptr) { if (data_format == Tango::SCALAR) { tmp_lo64[1] = (*val_ptr)[0]; value.lg64_seq = new Tango::DevVarLong64Array(data_size + 1,data_size + 1,tmp_lo64,false); } else { long nb_read = value.lg64_seq->length(); value.lg64_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.lg64_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarDoubleArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_db[1] = (*val_ptr)[0]; value.db_seq = new Tango::DevVarDoubleArray(data_size + 1,data_size + 1,tmp_db,false); } else { long nb_read = value.db_seq->length(); value.db_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.db_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarStringArray *val_ptr) { if (data_format == Tango::SCALAR) { if (scalar_str_attr_release == true) { char **strvec = Tango::DevVarStringArray::allocbuf(2); strvec[0] = tmp_str[0]; strvec[1] = CORBA::string_dup((*val_ptr)[0]); value.str_seq = new Tango::DevVarStringArray(2,2,strvec,true); } else { tmp_str[1] = (*val_ptr)[0]; value.str_seq = new Tango::DevVarStringArray(data_size + 1,data_size + 1,tmp_str,false); } } else { long nb_read = value.str_seq->length(); value.str_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.str_seq)[nb_read + k] = CORBA::string_dup((*val_ptr)[k]); } } void Attribute::add_write_value(Tango::DevVarFloatArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_fl[1] = (*val_ptr)[0]; value.fl_seq = new Tango::DevVarFloatArray(data_size + 1,data_size + 1,tmp_fl,false); } else { long nb_read = value.fl_seq->length(); value.fl_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.fl_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarBooleanArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_boo[1] = (*val_ptr)[0]; value.boo_seq = new Tango::DevVarBooleanArray(data_size + 1,data_size + 1,tmp_boo,false); } else { long nb_read = value.boo_seq->length(); value.boo_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.boo_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarUShortArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_ush[1] = (*val_ptr)[0]; value.ush_seq = new Tango::DevVarUShortArray(data_size + 1,data_size + 1,tmp_ush,false); } else { long nb_read = value.ush_seq->length(); value.ush_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.ush_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarCharArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_cha[1] = (*val_ptr)[0]; value.cha_seq = new Tango::DevVarCharArray(data_size + 1,data_size + 1,tmp_cha,false); } else { long nb_read = value.cha_seq->length(); value.cha_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.cha_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarULongArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_ulo[1] = (*val_ptr)[0]; value.ulg_seq = new Tango::DevVarULongArray(data_size + 1,data_size + 1,tmp_ulo,false); } else { long nb_read = value.ulg_seq->length(); value.ulg_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.ulg_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarULong64Array *val_ptr) { if (data_format == Tango::SCALAR) { tmp_ulo64[1] = (*val_ptr)[0]; value.ulg64_seq = new Tango::DevVarULong64Array(data_size + 1,data_size + 1,tmp_ulo64,false); } else { long nb_read = value.ulg64_seq->length(); value.ulg64_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.ulg64_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevVarStateArray *val_ptr) { if (data_format == Tango::SCALAR) { tmp_state[1] = (*val_ptr)[0]; value.state_seq = new Tango::DevVarStateArray(data_size + 1,data_size + 1,tmp_state,false); } else { long nb_read = value.state_seq->length(); value.state_seq->length(nb_read + val_ptr->length()); for (unsigned int k = 0;k < val_ptr->length();k++) (*value.state_seq)[nb_read + k] = (*val_ptr)[k]; } } void Attribute::add_write_value(Tango::DevEncoded &val_ref) { tmp_enc[1] = val_ref; value.enc_seq = new Tango::DevVarEncodedArray(data_size + 1,data_size + 1,tmp_enc,false); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::Attribute_2_AttributeValue // // description : // Build an AttributeValue_3 object from the Attribute object content // // arguments // in : // - dev : The device to which the attribute belongs to // out : // - ptr : Pointer to the AttributeValue_3 object to be filled in // //-------------------------------------------------------------------------------------------------------------------- void Attribute::Attribute_2_AttributeValue(Tango::AttributeValue_3 *ptr,Tango::DeviceImpl *d) { if ((name_lower == "state") || (name_lower == "status")) { ptr->quality = Tango::ATTR_VALID; CORBA::Any &a = ptr->value; if (name_lower == "state") { a <<= d->get_state(); } else { Tango::DevVarStringArray str_seq(1); str_seq.length(1); str_seq[0] = CORBA::string_dup(d->get_status().c_str()); a <<= str_seq; } #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); ptr->time.tv_sec = (long)t.time; ptr->time.tv_usec = (long)(t.millitm * 1000); ptr->time.tv_nsec = 0; #else struct timeval after; gettimeofday(&after,NULL); ptr->time.tv_sec = after.tv_sec; ptr->time.tv_usec = after.tv_usec; ptr->time.tv_nsec = 0; #endif ptr->r_dim.dim_x = 1; ptr->r_dim.dim_y = 0; ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; ptr->name = CORBA::string_dup(name.c_str()); } else { if (quality != Tango::ATTR_INVALID) { MultiAttribute *m_attr = d->get_device_attr(); // Add the attribute setpoint to the value sequence if ((writable == Tango::READ_WRITE) || (writable == Tango::READ_WITH_WRITE)) { m_attr->add_write_value(*this); } // check for alarms to position the data quality value. if ( is_alarmed().any() == true ) { check_alarm(); } Tango::DevVarShortArray *sh_seq; Tango::DevShort *sh_tmp_ptr; Tango::DevVarLongArray *lo_seq; Tango::DevLong *lo_tmp_ptr; Tango::DevVarDoubleArray *db_seq; Tango::DevDouble *db_tmp_ptr; Tango::DevVarStringArray *str_seq; Tango::DevString *str_tmp_ptr; Tango::DevVarFloatArray *fl_seq; Tango::DevFloat *fl_tmp_ptr; Tango::DevVarBooleanArray *bo_seq; Tango::DevBoolean *bo_tmp_ptr; Tango::DevVarUShortArray *ush_seq; Tango::DevUShort *ush_tmp_ptr; Tango::DevVarUCharArray *uch_seq; Tango::DevUChar *uch_tmp_ptr; Tango::DevVarLong64Array *lo64_seq; Tango::DevLong64 *lo64_tmp_ptr; Tango::DevVarULongArray *ulo_seq; Tango::DevULong *ulo_tmp_ptr; Tango::DevVarULong64Array *ulo64_seq; Tango::DevULong64 *ulo64_tmp_ptr; Tango::DevVarStateArray *state_seq; Tango::DevState *state_tmp_ptr; CORBA::Any &a = ptr->value; long seq_length = value.sh_seq->length(); switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM: sh_tmp_ptr = get_short_value()->get_buffer(); sh_seq = new Tango::DevVarShortArray(seq_length,seq_length,sh_tmp_ptr,false); a <<= *sh_seq; delete sh_seq; break; case Tango::DEV_LONG : lo_tmp_ptr = get_long_value()->get_buffer(); lo_seq = new Tango::DevVarLongArray(seq_length,seq_length,lo_tmp_ptr,false); a <<= *lo_seq; delete lo_seq; break; case Tango::DEV_LONG64 : lo64_tmp_ptr = get_long64_value()->get_buffer(); lo64_seq = new Tango::DevVarLong64Array(seq_length,seq_length,lo64_tmp_ptr,false); a <<= *lo64_seq; delete lo64_seq; break; case Tango::DEV_DOUBLE : db_tmp_ptr = get_double_value()->get_buffer(); db_seq = new Tango::DevVarDoubleArray(seq_length,seq_length,db_tmp_ptr,false); a <<= *db_seq; delete db_seq; break; case Tango::DEV_STRING : str_tmp_ptr = get_string_value()->get_buffer(); str_seq = new Tango::DevVarStringArray(seq_length,seq_length,str_tmp_ptr,false); a <<= *str_seq; delete str_seq; break; case Tango::DEV_FLOAT : fl_tmp_ptr = get_float_value()->get_buffer(); fl_seq = new Tango::DevVarFloatArray(seq_length,seq_length,fl_tmp_ptr,false); a <<= *fl_seq; delete fl_seq; break; case Tango::DEV_BOOLEAN : bo_tmp_ptr = get_boolean_value()->get_buffer(); bo_seq = new Tango::DevVarBooleanArray(seq_length,seq_length,bo_tmp_ptr,false); a <<= *bo_seq; delete bo_seq; break; case Tango::DEV_USHORT : ush_tmp_ptr = get_ushort_value()->get_buffer(); ush_seq = new Tango::DevVarUShortArray(seq_length,seq_length,ush_tmp_ptr,false); a <<= *ush_seq; delete ush_seq; break; case Tango::DEV_UCHAR : uch_tmp_ptr = get_uchar_value()->get_buffer(); uch_seq = new Tango::DevVarUCharArray(seq_length,seq_length,uch_tmp_ptr,false); a <<= *uch_seq; delete uch_seq; break; case Tango::DEV_ULONG : ulo_tmp_ptr = get_ulong_value()->get_buffer(); ulo_seq = new Tango::DevVarULongArray(seq_length,seq_length,ulo_tmp_ptr,false); a <<= *ulo_seq; delete ulo_seq; break; case Tango::DEV_ULONG64 : ulo64_tmp_ptr = get_ulong64_value()->get_buffer(); ulo64_seq = new Tango::DevVarULong64Array(seq_length,seq_length,ulo64_tmp_ptr,false); a <<= *ulo64_seq; delete ulo64_seq; break; case Tango::DEV_STATE : state_tmp_ptr = get_state_value()->get_buffer(); state_seq = new Tango::DevVarStateArray(seq_length,seq_length,state_tmp_ptr,false); a <<= *state_seq; delete state_seq; break; } ptr->r_dim.dim_x = dim_x; ptr->r_dim.dim_y = dim_y; if ((writable == Tango::READ_WRITE) || (writable == Tango::READ_WITH_WRITE)) { WAttribute &assoc_att = m_attr->get_w_attr_by_ind(get_assoc_ind()); ptr->w_dim.dim_x = assoc_att.get_w_dim_x(); ptr->w_dim.dim_y = assoc_att.get_w_dim_y(); } else { ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; } } else { ptr->r_dim.dim_x = 0; ptr->r_dim.dim_y = 0; ptr->w_dim.dim_x = 0; ptr->w_dim.dim_y = 0; } ptr->time = when; ptr->quality = quality; ptr->name = CORBA::string_dup(name.c_str()); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::Attribute_2_AttributeValue // // description : // Build an AttributeValue_4 object from the Attribute object content // // arguments // in : // - d : The device to which the attribute belongs to // out : // - ptr_4 : Pointer to the AttributeValue_5 object to be filled in // //-------------------------------------------------------------------------------------------------------------------- void Attribute::Attribute_2_AttributeValue(Tango::AttributeValue_4 *ptr_4,Tango::DeviceImpl *d) { Attribute_2_AttributeValue_base(ptr_4,d); Tango::AttributeIdlData aid; Tango::AttributeValueList_4 dummy_list(1,1,ptr_4,false); aid.data_4 = &dummy_list; if ((name_lower != "state") && (name_lower != "status") && (quality != Tango::ATTR_INVALID)) d->data_into_net_object(*this,aid,0,writable,false); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::Attribute_2_AttributeValue // // description : // Build an AttributeValue_5 object from the Attribute object content // // arguments // in : // - d : The device to which the attribute belongs to // out : // - ptr_5 : Pointer to the AttributeValue_5 object to be filled in // //-------------------------------------------------------------------------------------------------------------------- void Attribute::Attribute_2_AttributeValue(Tango::AttributeValue_5 *ptr_5,Tango::DeviceImpl *d) { Attribute_2_AttributeValue_base(ptr_5,d); Tango::AttributeIdlData aid; Tango::AttributeValueList_5 dummy_list(1,1,ptr_5,false); aid.data_5 = &dummy_list; if ((name_lower != "state") && (name_lower != "status") && (quality != Tango::ATTR_INVALID)) d->data_into_net_object(*this,aid,0,writable,false); ptr_5->data_type = data_type; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::AttributeValue_4_2_AttributeValue_3 // // description : // Build an AttributeValue_3 object from the AttributeValue_4 object. This method is used in case an event is // requested by a client knowing only IDL release 3 // // args : // in : // - ptr_4 : Pointer to the AttributeValue_4 object // out : // - ptr_3 : Pointer to the AttributeValue_3 object to be filled in // //------------------------------------------------------------------------------------------------------------------- void Attribute::AttributeValue_4_2_AttributeValue_3(const Tango::AttributeValue_4 *ptr_4,Tango::AttributeValue_3 *ptr_3) { // // First copy the data // if (ptr_4->quality != Tango::ATTR_INVALID) { AttrValUnion_2_Any(ptr_4,ptr_3->value); } // // The remaining fields // ptr_3->time = ptr_4->time; ptr_3->quality = ptr_4->quality; ptr_3->name = ptr_4->name; ptr_3->r_dim = ptr_4->r_dim; ptr_3->w_dim = ptr_4->w_dim; ptr_3->err_list = ptr_4->err_list; } void Attribute::AttributeValue_5_2_AttributeValue_3(const Tango::AttributeValue_5 *att_5,Tango::AttributeValue_3 *att_3) { // // First copy the data // if (att_5->quality != Tango::ATTR_INVALID) { AttrValUnion_2_Any(att_5,att_3->value); } // // The remaining fields // att_3->time = att_5->time; att_3->quality = att_5->quality; att_3->name = att_5->name; att_3->r_dim = att_5->r_dim; att_3->w_dim = att_5->w_dim; att_3->err_list = att_5->err_list; } void Attribute::AttributeValue_3_2_AttributeValue_4(const Tango::AttributeValue_3 *att_3,Tango::AttributeValue_4 *att_4) { // TODO: Code data from Any to Union // // The remaining fields // att_4->time = att_3->time; att_4->quality = att_3->quality; att_4->name = att_3->name; att_4->data_format = data_format; att_4->r_dim = att_3->r_dim; att_4->w_dim = att_3->w_dim; att_4->err_list = att_3->err_list; } void Attribute::AttributeValue_5_2_AttributeValue_4(const Tango::AttributeValue_5 *att_5,Tango::AttributeValue_4 *att_4) { // // First pass the data from one union to another WITHOUT copying them // if (att_5->quality != Tango::ATTR_INVALID) { AttrValUnion_fake_copy(att_5,att_4); } // // The remaining fields // att_4->time = att_5->time; att_4->quality = att_5->quality; att_4->name = att_5->name; att_4->data_format = att_5->data_format; att_4->r_dim = att_5->r_dim; att_4->w_dim = att_5->w_dim; att_4->err_list = att_5->err_list; } void Attribute::AttributeValue_3_2_AttributeValue_5(const Tango::AttributeValue_3 *att_3,Tango::AttributeValue_5 *att_5) { // TODO: Code data from Any to Union // // The remaining fields // att_5->time = att_3->time; att_5->quality = att_3->quality; att_5->name = att_3->name; att_5->data_format = data_format; att_5->data_type = data_type; att_5->r_dim = att_3->r_dim; att_5->w_dim = att_3->w_dim; att_5->err_list = att_3->err_list; } void Attribute::AttributeValue_4_2_AttributeValue_5(const Tango::AttributeValue_4 *att_4,Tango::AttributeValue_5 *att_5) { // // First pass the data from one union to another WITHOUT copying them // if (att_4->quality != Tango::ATTR_INVALID) { AttrValUnion_fake_copy(att_4,att_5); } // // The remaining fields // att_5->time = att_4->time; att_5->quality = att_4->quality; att_5->name = att_4->name; att_5->data_format = att_4->data_format; att_5->data_type = data_type; att_5->r_dim = att_4->r_dim; att_5->w_dim = att_4->w_dim; att_5->err_list = att_4->err_list; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::AttributeConfig_5_2_AttributeConfig_3 // // description : // Build an AttributeConfig_3 object from the AttributeConfig_5 object. This method is used in case an event is // requested by a client knowing only IDL release 4 // // argument: // in : // - conf5 : Reference to the AttributeConfig_5 object // out : // - conf3 : Reference to the AttributeConfig_3 object to be filled in // //------------------------------------------------------------------------------------------------------------------- void Attribute::AttributeConfig_5_2_AttributeConfig_3(const Tango::AttributeConfig_5 &conf5,Tango::AttributeConfig_3 &conf3) { size_t j; conf3.name = conf5.name; conf3.writable = conf5.writable; conf3.data_format = conf5.data_format; conf3.data_type = conf5.data_type; conf3.max_dim_x = conf5.max_dim_x; conf3.max_dim_y = conf5.max_dim_y; conf3.description = conf5.description; conf3.label = conf5.label; conf3.unit = conf5.unit; conf3.standard_unit = conf5.standard_unit; conf3.display_unit = conf5.display_unit; conf3.format = conf5.format; conf3.min_value = conf5.min_value; conf3.max_value = conf5.max_value; conf3.writable_attr_name = conf5.writable_attr_name; conf3.level = conf5.level; conf3.extensions.length(conf5.extensions.length()); for (j=0; jget_notifd_event_supplier(); pub_socket_created = true; } if (use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); // // Get client lib and if it's possible to send event (ZMQ socket created) // vector client_libs; { omni_mutex_lock oml(EventSupplier::get_event_mutex()); client_libs = get_client_lib(CHANGE_EVENT); // We want a copy if (use_zmq_event() == true && event_supplier_zmq != NULL) { string &sock_endpoint = static_cast(event_supplier_zmq)->get_event_endpoint(); if (sock_endpoint.empty() == false) pub_socket_created = true; } } vector::iterator ite; for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (change5_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(5,string(EventName[CHANGE_EVENT])); break; case 4: if (change4_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(4,string(EventName[CHANGE_EVENT])); break; default: if (change3_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(3,string(EventName[CHANGE_EVENT])); break; } } if (client_libs.empty() == true) { if ( (name_lower != "state") && (name_lower != "status")) { // delete the data values allocated in the attribute bool data_flag = get_value_flag(); if ( data_flag == true ) { // For writable scalar attributes the sequence for the // attribute data is not yet allocated. This will happen // only when adding the set point! if ( !check_scalar_wattribute() ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } return; } // // Simply return if event supplier(s) are not created // if ((event_supplier_nd == NULL) && (event_supplier_zmq == NULL)) { if ( name_lower != "state" ) { // delete the data values allocated in the attribute bool data_flag = get_value_flag(); if ( data_flag == true ) { // For writable scalar attributes the sequence for the // attribute data is not yet allcoated. This will happen // only when adding the set point! if ( !check_scalar_wattribute() ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } return; } // // Retrieve device object if not already done // if (dev == NULL) dev = tg->get_device_by_name(d_name); if ( except == NULL ) { // // Check that the attribute value has been set // if ((name_lower != "state") && (name_lower != "status")) { if (quality != Tango::ATTR_INVALID) { if (value_flag == false) { TangoSys_OMemStream o; o << "Value for attribute "; o << name; o << " has not been updated. Can't send change event\n"; o << "Set the attribute value (using set_value(...) method) before!" << ends; Except::throw_exception(API_AttrValueNotSet,o.str(),"Attribute::fire_change_event()"); } } } } // // Build one AttributeValue_3, AttributeValue_4 or AttributeValue_5 object // long vers = dev->get_dev_idl_version(); try { if (vers >= 4) send_attr_5 = new Tango::AttributeValue_5; else if (vers == 4) send_attr_4 = new Tango::AttributeValue_4; else send_attr = new Tango::AttributeValue_3; } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server","Attribute::fire_change_event()"); } // // Don`t try to access the attribute data when an exception was indicated // if ( except == NULL ) { if (send_attr_5 != Tango_nullptr) Attribute_2_AttributeValue(send_attr_5,dev); else if (send_attr_4 != NULL) Attribute_2_AttributeValue(send_attr_4,dev); else Attribute_2_AttributeValue(send_attr,dev); } // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); // // Fire event // if ( is_check_change_criteria() == true ) { if (send_attr_5 != Tango_nullptr) ad.attr_val_5 = send_attr_5; else if (send_attr_4 != Tango_nullptr) ad.attr_val_4 = send_attr_4; else ad.attr_val_3 = send_attr; // // Eventually push the event (if detected) // When we have both notifd and zmq event supplier, do not detect the event // two times. The detect_and_push_events() method returns true if the event // is detected. // bool send_event = false; if (event_supplier_nd != NULL) send_event = event_supplier_nd->detect_and_push_change_event(dev,ad,*this,name,except,true); if (event_supplier_zmq != NULL) { if (event_supplier_nd != NULL) { if (send_event == true && pub_socket_created == true) { vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; event_supplier_zmq->push_event_loop(dev,CHANGE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,*this,except); } } else { if (pub_socket_created == true) event_supplier_zmq->detect_and_push_change_event(dev,ad,*this,name,except,true); } } } else { // // Send event, if the read_attribute failed or if it is the first time // that the read_attribute succeed after a failure. // Same thing if the attribute quality factor changes to INVALID // // This is done only to be able to set-up the same filters with events // comming with the standard mechanism or coming from a manual fire event call. // bool force_change = false; bool quality_change = false; if ((except != NULL) || (quality == Tango::ATTR_INVALID) || ((except == NULL) && (prev_change_event.err == true)) || ((quality != Tango::ATTR_INVALID) && (prev_change_event.quality == Tango::ATTR_INVALID))) { force_change = true; } vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; if (except != NULL) { prev_change_event.err = true; prev_change_event.except = *except; } else { Tango::AttrQuality the_quality; if (send_attr_5 != NULL) { the_quality = send_attr_5->quality; prev_change_event.value_4 = send_attr_5->value; } else if (send_attr_4 != NULL) { the_quality = send_attr_4->quality; prev_change_event.value_4 = send_attr_4->value; } else { the_quality = send_attr->quality; prev_change_event.value = send_attr->value; } if (prev_change_event.quality != the_quality) { quality_change = true; } prev_change_event.quality = the_quality; prev_change_event.err = false; } prev_change_event.inited = true; filterable_names.push_back("forced_event"); if (force_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("quality"); if (quality_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); if (send_attr_5 != Tango_nullptr) ad.attr_val_5 = send_attr_5; else if (send_attr_4 != Tango_nullptr) ad.attr_val_4 = send_attr_4; else ad.attr_val_3 = send_attr; // // Finally push the event(s) // if (event_supplier_nd != NULL) event_supplier_nd->push_event(dev, "change", filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, ad, name, except, false); if (event_supplier_zmq != NULL && pub_socket_created == true) { event_supplier_zmq->push_event_loop(dev,CHANGE_EVENT,filterable_names,filterable_data,filterable_names_lg,filterable_data_lg,ad,*this,except); } } // // Return allocated memory // if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != Tango_nullptr) delete send_attr_4; else delete send_attr; // // Delete the data values allocated in the attribute // if ( (name_lower != "state") && (name_lower != "status") ) { bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } catch (...) { if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != NULL) delete send_attr_4; else delete send_attr; if ( (name_lower != "state") && (name_lower != "status")) { // delete the data values allocated in the attribute bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } throw; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::fire_archive_event // // description : // Fire a archive change event for the attribute value. // // arguments: // in : // - ptr : Pointer to a DevFailed exception to fire in case of an error to indicate. // //------------------------------------------------------------------------------------------------------------------- void Attribute::fire_archive_event(DevFailed *except) { cout4 << "Attribute::fire_archive_event() entering ..." << endl; if ( except != NULL ) { set_value_flag (false); } // // Check if it is needed to send an event // Tango::AttributeValue_3 *send_attr = Tango_nullptr; Tango::AttributeValue_4 *send_attr_4 = Tango_nullptr; Tango::AttributeValue_5 *send_attr_5 = Tango_nullptr; try { time_t now; time_t archive3_subscription,archive4_subscription,archive5_subscription; now = time(NULL); archive3_subscription = now - event_archive3_subscription; archive4_subscription = now - event_archive4_subscription; archive5_subscription = now - event_archive5_subscription; // // Get the event supplier(s) // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; bool pub_socket_created = false; Tango::Util *tg = Util::instance(); if (use_notifd_event() == true) { event_supplier_nd = tg->get_notifd_event_supplier(); pub_socket_created = true; } if (use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); // // Get client lib and if it's possible to send event (ZMQ socket created) // vector client_libs; { omni_mutex_lock oml(EventSupplier::get_event_mutex()); client_libs = get_client_lib(ARCHIVE_EVENT); // We want a copy if (use_zmq_event() == true && event_supplier_zmq != NULL) { string &sock_endpoint = static_cast(event_supplier_zmq)->get_event_endpoint(); if (sock_endpoint.empty() == false) pub_socket_created = true; } } vector::iterator ite; for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (archive5_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(5,string(EventName[ARCHIVE_EVENT])); break; case 4: if (archive4_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(4,string(EventName[ARCHIVE_EVENT])); break; default: if (archive3_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(3,string(EventName[ARCHIVE_EVENT])); break; } } if (client_libs.empty() == true) { if ( (name_lower != "state") && (name_lower != "status") ) { // // Delete the data values allocated in the attribute // bool data_flag = get_value_flag(); if ( data_flag == true ) { // // For writable scalar attributes the sequence for the // attribute data is not yet allocated. This will happen // only when adding the set point! // if ( !check_scalar_wattribute() ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } return; } // // Simply return if event supplier(s) are not created // if ((event_supplier_nd == NULL) && (event_supplier_zmq == NULL)) { if ( name_lower != "state" ) { // // Delete the data values allocated in the attribute // bool data_flag = get_value_flag(); if ( data_flag == true ) { // // For writable scalar attributes the sequence for the // attribute data is not yet allcoated. This will happen // only when adding the set point! // if ( !check_scalar_wattribute() ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } return; } // // Retrieve device object if not already done // if (dev == NULL) dev = tg->get_device_by_name(d_name); if ( except == NULL ) { // // Check that the attribute value has been set // if ((name_lower != "state") && (name_lower != "status")) { if (quality != Tango::ATTR_INVALID) { if (value_flag == false) { TangoSys_OMemStream o; o << "Value for attribute "; o << name; o << " has not been updated. Can't send archive event\n"; o << "Set the attribute value (using set_value(...) method) before!" << ends; Except::throw_exception((const char *)API_AttrValueNotSet,o.str(), (const char *)"Attribute::fire_archive_event()"); } } } } // // Build one AttributeValue_3, AttributeValue_4 or AttributeValue_5 object // try { if (dev->get_dev_idl_version() > 4) send_attr_5 = new Tango::AttributeValue_5; else if (dev->get_dev_idl_version() == 4) send_attr_4 = new Tango::AttributeValue_4; else send_attr = new Tango::AttributeValue_3; } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server","Attribute::fire_archive_event()"); } // // Don`t try to access the attribute data when an exception was indicated // if ( except == NULL ) { if (send_attr_5 != Tango_nullptr) Attribute_2_AttributeValue(send_attr_5,dev); else if (send_attr_4 != Tango_nullptr) Attribute_2_AttributeValue(send_attr_4,dev); else Attribute_2_AttributeValue(send_attr,dev); } // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (send_attr_5 != Tango_nullptr) ad.attr_val_5 = send_attr_5; else if (send_attr_4 != Tango_nullptr) ad.attr_val_4 = send_attr_4; else ad.attr_val_3 = send_attr; // // Fire event // if ( is_check_archive_criteria() == true ) { #ifdef _TG_WINDOWS_ struct _timeb now_win; #endif struct timeval now_timeval; #ifdef _TG_WINDOWS_ _ftime(&now_win); now_timeval.tv_sec = (unsigned long)now_win.time; now_timeval.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now_timeval,NULL); #endif // // Eventually push the event (if detected) // When we have both notifd and zmq event supplier, do not detect the event // two times. The detect_and_push_events() method returns true if the event // is detected. // bool send_event = false; if (event_supplier_nd != NULL) send_event = event_supplier_nd->detect_and_push_archive_event(dev,ad,*this,name,except,&now_timeval,true); if (event_supplier_zmq != NULL) { if (event_supplier_nd != NULL) { if (send_event == true && pub_socket_created == true) { vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; event_supplier_zmq->push_event_loop(dev,ARCHIVE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,*this,except); } } else { if (pub_socket_created == true) event_supplier_zmq->detect_and_push_archive_event(dev,ad,*this,name,except,&now_timeval,true); } } } else { // // Execute detect_change only to calculate the delta_change_rel and // delta_change_abs and force_change ! // bool force_change = false; bool quality_change = false; double delta_change_rel = 0.0; double delta_change_abs = 0.0; if (event_supplier_nd != NULL) event_supplier_nd->detect_change(*this, ad,true,delta_change_rel,delta_change_abs,except,force_change,dev); else if (event_supplier_zmq != NULL) event_supplier_zmq->detect_change(*this, ad,true,delta_change_rel,delta_change_abs,except,force_change,dev); vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; if (except != NULL) { prev_archive_event.err = true; prev_archive_event.except = *except; } else { Tango::AttrQuality the_quality; if (send_attr_5 != Tango_nullptr) { prev_archive_event.value_4 = send_attr_5->value; the_quality = send_attr_5->quality; } else if (send_attr_4 != Tango_nullptr) { prev_archive_event.value_4 = send_attr_4->value; the_quality = send_attr_4->quality; } else { prev_archive_event.value = send_attr->value; the_quality = send_attr->quality; } if (prev_archive_event.quality != the_quality) { quality_change = true; } prev_archive_event.quality = the_quality; prev_archive_event.err = false; } prev_archive_event.inited = true; filterable_names.push_back("forced_event"); if (force_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("quality"); if (quality_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("counter"); filterable_data_lg.push_back(-1); filterable_names.push_back("delta_change_rel"); filterable_data.push_back(delta_change_rel); filterable_names.push_back("delta_change_abs"); filterable_data.push_back(delta_change_abs); if (event_supplier_nd != NULL) event_supplier_nd->push_event(dev, "archive", filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, ad, name, except, false); if (event_supplier_zmq != NULL && pub_socket_created == true) { event_supplier_zmq->push_event_loop(dev,ARCHIVE_EVENT,filterable_names,filterable_data,filterable_names_lg,filterable_data_lg,ad,*this,except); } } if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != Tango_nullptr) delete send_attr_4; else delete send_attr; // // Delete the data values allocated in the attribute // if ((name_lower != "state") && (name_lower != "status")) { bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } catch (...) { if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != Tango_nullptr) delete send_attr_4; else delete send_attr; // // Delete the data values allocated in the attribute // if ((name_lower != "state") && (name_lower != "status")) { bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } throw; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::fire_event // // description : // Fire a user event for the attribute value. // // arguments: // in : // - filt_names : The filterable fields name // - filt_vals : The filterable fields value (as double) // - except : Pointer to a DevFailed exception to fire in case of an error to indicate. // //-------------------------------------------------------------------------------------------------------------------- void Attribute::fire_event(vector &filt_names,vector &filt_vals,DevFailed *except) { cout4 << "Attribute::fire_event() entring ..." << endl; if (except != NULL) set_value_flag(false); Tango::AttributeValue_3 *send_attr = Tango_nullptr; Tango::AttributeValue_4 *send_attr_4 = Tango_nullptr; Tango::AttributeValue_5 *send_attr_5 = Tango_nullptr; // // Check if it is needed to send an event // try { time_t now; time_t user3_subscription,user4_subscription,user5_subscription; now = time(NULL); user3_subscription = now - event_user3_subscription; user4_subscription = now - event_user4_subscription; user5_subscription = now - event_user5_subscription; // // Get the event supplier(s) // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; bool pub_socket_created = false; Tango::Util *tg = Util::instance(); if (use_notifd_event() == true) { event_supplier_nd = tg->get_notifd_event_supplier(); pub_socket_created = true; } if (use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); // // Get client lib and if it's possible to send event (ZMQ socket created) // vector client_libs; { omni_mutex_lock oml(EventSupplier::get_event_mutex()); client_libs = get_client_lib(USER_EVENT); // We want a copy if (use_zmq_event() == true && event_supplier_zmq != NULL) { string &sock_endpoint = static_cast(event_supplier_zmq)->get_event_endpoint(); if (sock_endpoint.empty() == false) pub_socket_created = true; } } vector::iterator ite; for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (user5_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(5,string(EventName[USER_EVENT])); break; case 4: if (user4_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(4,string(EventName[USER_EVENT])); break; default: if (user3_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(3,string(EventName[USER_EVENT])); break; } } // // Simply return if event suplier(s) are not created // if (((event_supplier_nd == NULL) && (event_supplier_zmq == NULL)) || client_libs.empty() == true) { if (name_lower != "state") { // // Delete the data values allocated in the attribute // bool data_flag = get_value_flag(); if ( data_flag == true ) { // // For writable scalar attributes the sequence for the // attribute data is not yet allcoated. This will happen // only when adding the set point! // if ( !check_scalar_wattribute() ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } return; } // // Retrieve device object if not already done // if (dev == NULL) dev = tg->get_device_by_name(d_name); if (except == NULL) { // // Check that the attribute value has been set // if ((name_lower != "state") && (name_lower != "status")) { if (quality != Tango::ATTR_INVALID) { if (value_flag == false) { TangoSys_OMemStream o; o << "Value for attribute "; o << name; o << " has not been updated. Can't send user event\n"; o << "Set the attribute value (using set_value(...) method) before!" << ends; Except::throw_exception(API_AttrValueNotSet,o.str(),"Attribute::fire_event()"); } } } } // // Build one AttributeValue_3, AttributeValue_4 object or Attribute_5 object // try { if (dev->get_dev_idl_version() > 4) send_attr_5 = new Tango::AttributeValue_5; else if (dev->get_dev_idl_version() == 4) send_attr_4 = new Tango::AttributeValue_4; else send_attr = new Tango::AttributeValue_3; } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation,"Can't allocate memory in server","Attribute::fire_event()"); } // // Don`t try to access the attribute data when an exception was indicated // if ( except == NULL ) { if (send_attr_5 != Tango_nullptr) Attribute_2_AttributeValue(send_attr_5,dev); else if (send_attr_4 != Tango_nullptr) Attribute_2_AttributeValue(send_attr_4,dev); else Attribute_2_AttributeValue(send_attr,dev); } // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (send_attr_5 != Tango_nullptr) ad.attr_val_5 = send_attr_5; else if (send_attr_4 != NULL) ad.attr_val_4 = send_attr_4; else ad.attr_val_3 = send_attr; // // Fire event // vector filterable_names_lg; vector filterable_data_lg; if (event_supplier_nd != NULL) event_supplier_nd->push_event(dev, "user_event", filt_names, filt_vals, filterable_names_lg, filterable_data_lg, ad, name, except, false); if (event_supplier_zmq != NULL && pub_socket_created == true) { event_supplier_zmq->push_event_loop(dev,USER_EVENT,filt_names,filt_vals,filterable_names_lg,filterable_data_lg,ad,*this,except); } if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != Tango_nullptr) delete send_attr_4; else delete send_attr; // // delete the data values allocated in the attribute // if ((name_lower != "state") && (name_lower != "status")) { bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } } catch (...) { if (send_attr_5 != Tango_nullptr) delete send_attr_5; else if (send_attr_4 != Tango_nullptr) delete send_attr_4; else delete send_attr; // // delete the data values allocated in the attribute // if ((name_lower != "state") && (name_lower != "status")) { bool data_flag = get_value_flag(); if ( data_flag == true ) { if (quality != Tango::ATTR_INVALID) delete_seq(); // set_value_flag (false); } } throw; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::fire_error_periodic_event // // description : // Fire a periodic event with error set. This is used when attribute polling is stopped // // arguments: // in : // - except : Pointer to a DevFailed exception to fire in case of an error to indicate. // //-------------------------------------------------------------------------------------------------------------------- void Attribute::fire_error_periodic_event(DevFailed *except) { cout4 << "Attribute::fire_error_periodic_event() entring ..." << endl; // // Check if it is needed to send an event // time_t now; time_t periodic3_subscription,periodic4_subscription,periodic5_subscription; now = time(NULL); periodic3_subscription = now - event_periodic3_subscription; periodic4_subscription = now - event_periodic4_subscription; periodic5_subscription = now - event_periodic5_subscription; vector client_libs = get_client_lib(PERIODIC_EVENT); // We want a copy vector::iterator ite; for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (periodic5_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(5,string(EventName[PERIODIC_EVENT])); break; case 4: if (periodic4_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(4,string(EventName[PERIODIC_EVENT])); break; default: if (periodic3_subscription >= EVENT_RESUBSCRIBE_PERIOD) remove_client_lib(3,string(EventName[PERIODIC_EVENT])); break; } } // // Get the event supplier, and simply return if not created // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; Tango::Util *tg = Util::instance(); if (use_notifd_event() == true) event_supplier_nd = tg->get_notifd_event_supplier(); if (use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); if (((event_supplier_nd == NULL) && (event_supplier_zmq == NULL)) || client_libs.empty() == true) { return; } // // Retrieve device object if not already done // if (dev == NULL) dev = tg->get_device_by_name(d_name); // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); // // Fire event // vector filterable_names_lg,filt_names; vector filterable_data_lg; vector filt_vals; if (event_supplier_nd != NULL) event_supplier_nd->push_event(dev, "periodic_event", filt_names, filt_vals, filterable_names_lg, filterable_data_lg, ad, name, except, false); if (event_supplier_zmq != NULL) { event_supplier_zmq->push_event_loop(dev,PERIODIC_EVENT,filt_names,filt_vals,filterable_names_lg,filterable_data_lg,ad,*this,except); } } //+------------------------------------------------------------------------- // // operator overloading : set_quality // // description : Set the attribute quality factor // //-------------------------------------------------------------------------- void Attribute::set_quality(Tango::AttrQuality qua,bool send_event) { quality = qua; if (send_event == true) fire_change_event(); } //+------------------------------------------------------------------------- // // method : Attribute::upd_att_prop_db // // description : Update the tango database with the new attribute // values // //-------------------------------------------------------------------------- void Attribute::upd_att_prop_db(Tango::Attr_CheckVal &new_value, const char *prop_name) { cout4 << "Entering upd_att_prop_db method for attribute " << name <<", property = " << prop_name << endl; // // Build the data sent to database // Tango::DbData db_data; Tango::DbDatum att(name),prop(prop_name); att << (short)1; switch (data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: prop << new_value.sh; break; case Tango::DEV_LONG: prop << new_value.lg; break; case Tango::DEV_LONG64: prop << new_value.lg64; break; case Tango::DEV_DOUBLE: prop << new_value.db; break; case Tango::DEV_FLOAT: prop << new_value.fl; break; case Tango::DEV_USHORT: prop << new_value.ush; break; case Tango::DEV_UCHAR: prop << new_value.uch; break; case Tango::DEV_ULONG: prop << new_value.ulg; break; case Tango::DEV_ULONG64: prop << new_value.ulg64; break; case Tango::DEV_STATE: prop << (short)new_value.d_sta; break; } db_data.push_back(att); db_data.push_back(prop); // // Implement a reconnection schema. The first exception received if the db // server is down is a COMM_FAILURE exception. Following exception received // from following calls are TRANSIENT exception // Tango::Util *tg = Tango::Util::instance(); bool retry = true; while (retry == true) { try { tg->get_database()->put_device_attribute_property(d_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } //+------------------------------------------------------------------------- // // method : Attribute::remove_configuration() // // description : Remove the attribute configuration from the database. // This method can be used to clean-up all the configuration // of an attribute to come back to its default values or the // remove all configuration of a dynamic attribute before deleting it. // // The method removes all configured attribute properties // and removes the attribute from the list of polled attributes. //-------------------------------------------------------------------------- void Attribute::remove_configuration() { cout4 << "Entering remove_configuration() method for attribute " << name << endl; Tango::Util *tg = Tango::Util::instance(); // // read all configured properties of the attribute from the database and // delete them! // DbData db_read_data; DbData db_delete_data; db_read_data.push_back(DbDatum(name)); db_delete_data.push_back(DbDatum(name)); // // Implement a reconnection schema. The first exception received if the db // server is down is a COMM_FAILURE exception. Following exception received // from following calls are TRANSIENT exception // bool retry = true; while (retry == true) { try { tg->get_database()->get_device_attribute_property(d_name,db_read_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } long nb_prop = 0; db_read_data[0] >> nb_prop; for (int k=1; k<(nb_prop + 1); k++) { string &prop_name = db_read_data[k].name; db_delete_data.push_back(DbDatum(prop_name)); } // // Implement a reconnection schema. The first exception received if the db // server is down is a COMM_FAILURE exception. Following exception received // from following calls are TRANSIENT exception // if ( nb_prop > 0 ) { retry = true; while (retry == true) { try { tg->get_database()->delete_device_attribute_property(d_name,db_delete_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } } //+------------------------------------------------------------------------- // // method : Attribute::get_att_device // // description : Return a pointer to the attribute device // //-------------------------------------------------------------------------- DeviceImpl *Attribute::get_att_device() { if (dev == NULL) { Tango::Util *tg = Tango::Util::instance(); dev = tg->get_device_by_name(d_name); } return dev; } //+------------------------------------------------------------------------- // // method : Attribute::set_attr_serial_method // // description : Set attribute serialization method // //-------------------------------------------------------------------------- void Attribute::set_attr_serial_model(AttrSerialModel ser_model) { if (ser_model == Tango::ATTR_BY_USER) { Tango::Util *tg = Tango::Util::instance(); if (tg->get_serial_model() != Tango::BY_DEVICE) { Except::throw_exception((const char *)API_AttrNotAllowed, (const char *)"Attribute serial model by user is not allowed when the process is not in BY_DEVICE serialization model", (const char *)"Attribute::set_attr_serial_model"); } } attr_serial_model=ser_model; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::get_att_device_class // // description : // Return a pointer to the attribute device class // // argument : // in : // - dev_name: The device name // //------------------------------------------------------------------------------------------------------------------- DeviceClass *Attribute::get_att_device_class(string &dev_name) { // // Get device class. When the server is started, it's an easy task. When the server is in its starting phase, it's more // tricky. Get from the DeviceClass list the first one for which the device_factory method has not yet been fully // executed. This is the DeviceClass with the device in its init_device() method has called Attribute::set_properties() // Tango::Util *tg = Tango::Util::instance(); Tango::DeviceClass *dev_class = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) { Tango::DeviceImpl *dev = get_att_device(); dev_class = dev->get_device_class(); } else { const vector &tmp_cl_list = *tg->get_class_list(); size_t loop; for (loop = 0;loop < tmp_cl_list.size();++loop) { if (tmp_cl_list[loop]->get_device_factory_done() == false) break; } if (loop != tmp_cl_list.size()) { dev_class = tmp_cl_list[loop]; } else { stringstream o; o << "Device " << dev_name << "-> Attribute : " << name; o << "\nCan't retrieve device class!" << ends; Except::throw_exception(API_CantRetrieveClass,o.str(),"Attribute::set_properties()"); } } return dev_class; } //+------------------------------------------------------------------------- // // method : Attribute::log_quality // // description : Send a logging message (on the device) when the attribute // quality factor changes // //-------------------------------------------------------------------------- void Attribute::log_quality() { // // Set device if not already done // if (dev == NULL) { Tango::Util *tg = Tango::Util::instance(); dev = tg->get_device_by_name(d_name); } // // Log something if the new quality is different than the old one // if (quality != old_quality) { if (alarm.any() == false) { // // No alarm detected // switch(quality) { case ATTR_INVALID: if (dev->get_logger()->is_error_enabled()) dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "INVALID quality for attribute " << name << endl; break; case ATTR_CHANGING: if (dev->get_logger()->is_info_enabled()) dev->get_logger()->info_stream() << log4tango::LogInitiator::_begin_log << "CHANGING quality for attribute " << name << endl; break; case ATTR_VALID: if (dev->get_logger()->is_info_enabled()) dev->get_logger()->info_stream() << log4tango::LogInitiator::_begin_log << "VALID quality for attribute " << name << endl; break; default: break; } } else { // // Different log according to which alarm is set // if (alarm[min_level] == true) { if (dev->get_logger()->is_error_enabled()) dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MIN ALARM for attribute " << name << endl; } else if (alarm[max_level] == true) { if (dev->get_logger()->is_error_enabled()) dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MAX ALARM for attribute " << name << endl; } else if (alarm[rds] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "RDS (Read Different Set) ALARM for attribute " << name << endl; } else if (alarm[min_warn] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MIN WARNING for attribute " << name << endl; } else if (alarm[max_warn] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MAX WARNING for attribute " << name << endl; } } } else { // // The quality is the same but may be the alarm has changed // if (alarm != old_alarm) { if (alarm[min_level] == true) { if (dev->get_logger()->is_error_enabled()) dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MIN ALARM for attribute " << name << endl; } else if (alarm[max_level] == true) { if (dev->get_logger()->is_error_enabled()) dev->get_logger()->error_stream() << log4tango::LogInitiator::_begin_log << "MAX ALARM for attribute " << name << endl; } else if (alarm[rds] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "RDS (Read Different Set) ALARM for attribute " << name << endl; } else if (alarm[min_warn] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MIN WARNING for attribute " << name << endl; } else if (alarm[max_warn] == true) { if (dev->get_logger()->is_warn_enabled()) dev->get_logger()->warn_stream() << log4tango::LogInitiator::_begin_log << "MAX WARNING for attribute " << name << endl; } } } } //+------------------------------------------------------------------------- // // method : Attribute::avns_in_db() // // description : Store in db the famous AVNS (AlrmValueNotSpec) // for a specific attribute property // // Arg in : prop_name : Property name // //-------------------------------------------------------------------------- void Attribute::avns_in_db(const char *prop_name,string &dev_name) { Tango::Util *tg = Tango::Util::instance(); if (Tango::Util::_UseDb == true) { DbDatum attr_dd(name), prop_dd(prop_name); attr_dd << 1L; prop_dd << AlrmValueNotSpec; DbData db_data; db_data.push_back(attr_dd); db_data.push_back(prop_dd); bool retry = true; while (retry == true) { try { tg->get_database()->put_device_attribute_property(dev_name,db_data); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::avns_in_att() // // description : // Store in att the famous AVNS (AlrmValueNotSpec) for a specific attribute property // // Arguments: // in : // - pt : Property type // //--------------------------------------------------------------------------------------------------------------------- void Attribute::avns_in_att(prop_type pt) { Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); { AutoTangoMonitor sync1(mon_ptr); switch (pt) { case MIN_VALUE: check_min_value = false; min_value_str = AlrmValueNotSpec; break; case MAX_VALUE: check_max_value = false; max_value_str = AlrmValueNotSpec; break; case MIN_WARNING: min_warning_str = AlrmValueNotSpec; break; case MAX_WARNING: max_warning_str = AlrmValueNotSpec; break; case MIN_ALARM: min_alarm_str = AlrmValueNotSpec; break; case MAX_ALARM: max_alarm_str = AlrmValueNotSpec; break; default: break; } if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) get_att_device()->push_att_conf_event(this); } } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_format_notspec() // // description : // Set the attribute format property to the default value which depends on attribute data type // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_format_notspec() { switch (data_type) { case DEV_SHORT: case DEV_LONG: case DEV_LONG64: case DEV_UCHAR: case DEV_USHORT: case DEV_ULONG: case DEV_ULONG64: format = FormatNotSpec_INT; break; case DEV_STRING: case DEV_ENUM: format = FormatNotSpec_STR; break; case DEV_STATE: case DEV_ENCODED: case DEV_BOOLEAN: format = AlrmValueNotSpec; break; case DEV_FLOAT: case DEV_DOUBLE: format = FormatNotSpec_FL; break; default: break; } } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::is_format_notspec() // // description : // Set the attribute format property to the default value which depends on attribute data type // // argument : // in : // - format : The format property string // // return : // This method retruns true if the format string is the default value // //-------------------------------------------------------------------------------------------------------------------- bool Attribute::is_format_notspec(const char *format) { bool ret = false; switch (data_type) { case DEV_SHORT: case DEV_LONG: case DEV_LONG64: case DEV_UCHAR: case DEV_USHORT: case DEV_ULONG: case DEV_ULONG64: if (TG_strcasecmp(format,FormatNotSpec_INT) == 0) ret = true; break; case DEV_STRING: case DEV_ENUM: if (TG_strcasecmp(format,FormatNotSpec_STR) == 0) ret = true; break; case DEV_STATE: case DEV_ENCODED: case DEV_BOOLEAN: if (TG_strcasecmp(format,AlrmValueNotSpec) == 0) ret = true; break; case DEV_FLOAT: case DEV_DOUBLE: if (TG_strcasecmp(format,FormatNotSpec_FL) == 0) ret = true; break; default: break; } return ret; } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::def_format_in_dbdatum() // // description : // Insert the default format string in a DbDatum instance. This default value depends on the attribute // data type // // argument : // in : // - db : Reference to the DbDatum object // //-------------------------------------------------------------------------------------------------------------------- void Attribute::def_format_in_dbdatum(DbDatum &db) { switch (data_type) { case DEV_SHORT: case DEV_LONG: case DEV_LONG64: case DEV_UCHAR: case DEV_USHORT: case DEV_ULONG: case DEV_ULONG64: db << FormatNotSpec_INT; break; case DEV_STRING: case DEV_ENUM: db << FormatNotSpec_STR; break; case DEV_STATE: case DEV_ENCODED: case DEV_BOOLEAN: db << AlrmValueNotSpec; break; case DEV_FLOAT: case DEV_DOUBLE: db << FormatNotSpec_FL; break; default: break; } } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::xxx_event_subscribed() // // description : // Returns true if there are some subscriber listening for event. This is a method family. There is one method // for each event type // Cannot replce this methods family by one method with event type as parameter for compatibility reason // //-------------------------------------------------------------------------------------------------------------------- bool Attribute::change_event_subscribed() { bool ret = false; time_t now = time(NULL); if (event_change5_subscription != 0) { if (now - event_change5_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_change4_subscription != 0) { if (now - event_change4_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_change3_subscription != 0) { if (now - event_change3_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } } } return ret; } bool Attribute::periodic_event_subscribed() { bool ret = false; time_t now = time(NULL); if (event_periodic5_subscription != 0) { if (now - event_periodic5_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_periodic4_subscription != 0) { if (now - event_periodic4_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_periodic3_subscription != 0) { if (now - event_periodic3_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } } } return ret; } bool Attribute::archive_event_subscribed() { bool ret = false; time_t now = time(NULL); if (event_archive5_subscription != 0) { if (now - event_archive5_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_archive4_subscription != 0) { if (now - event_archive4_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_archive3_subscription != 0) { if (now - event_archive3_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } } } return ret; } bool Attribute::quality_event_subscribed() { bool ret = false; if (event_quality_subscription != 0) { time_t now = time(NULL); if (now - event_quality_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } return ret; } bool Attribute::user_event_subscribed() { bool ret = false; time_t now = time(NULL); if (event_user5_subscription != 0) { if (now - event_user5_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_user4_subscription != 0) { if (now - event_user4_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_user3_subscription != 0) { if (now - event_user3_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } } } return ret; } bool Attribute::attr_conf_event_subscribed() { bool ret = false; if (event_attr_conf5_subscription != 0) { time_t now = time(NULL); if (now - event_attr_conf5_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } if (ret == false) { if (event_attr_conf_subscription != 0) { time_t now = time(NULL); if (now - event_attr_conf_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } } return ret; } bool Attribute::data_ready_event_subscribed() { bool ret = false; if (event_data_ready_subscription != 0) { time_t now = time(NULL); if (now - event_data_ready_subscription > EVENT_RESUBSCRIBE_PERIOD) ret = false; else ret = true; } return ret; } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::set_client_lib() // // description : // Set client lib (for event compatibility) // // argument : // in : // - _l : Client lib release // - ev_name : Event name // //-------------------------------------------------------------------------------------------------------------------- void Attribute::set_client_lib(int _l,string &ev_name) { int i; for (i = 0;i < numEventType;i++) { if (ev_name == EventName[i]) break; } if (count(client_lib[i].begin(),client_lib[i].end(),_l) == 0) client_lib[i].push_back(_l); } //--------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::remove_client_lib() // // description : // Remove a client lib (for event compatibility) // // argument : // in : // - _l : Client lib release // - ev_name : Event name // //-------------------------------------------------------------------------------------------------------------------- void Attribute::remove_client_lib(int _l,const string &ev_name) { int i; for (i = 0;i < numEventType;i++) { if (ev_name == EventName[i]) break; } vector::iterator pos = find(client_lib[i].begin(),client_lib[i].end(),_l); if (pos != client_lib[i].end()) client_lib[i].erase(pos); } //------------------------------------------------------------------------------------------------------------------- // // operator overloading : << // // description : Friend function to ease printing Attribute class instance // //------------------------------------------------------------------------------------------------------------------- #ifndef TANGO_HAS_LOG4TANGO ostream &operator<<(ostream &o_str,Attribute &p) { Tango::AttributeConfig conf; // // Get attribute properties // p.get_properties(conf); // // Print all these properties // o_str << "Attribute name = " << conf.name.in() << endl; o_str << "Attribute data_type = "; switch (conf.data_type) { case Tango::DEV_SHORT : o_str << "Tango::DevShort" << endl; break; case Tango::DEV_LONG : o_str << "Tango::DevLong" << endl; break; case Tango::DEV_LONG64 : o_str << "Tango::DevLong64" << endl; break; case Tango::DEV_DOUBLE : o_str << "Tango::DevDouble" << endl; break; case Tango::DEV_STRING : o_str << "Tango::DevString" << endl; break; case Tango::DEV_FLOAT : o_str << "Tango::DevFloat" << endl; break; case Tango::DEV_USHORT : o_str << "Tango::DevUShort" << endl; break; case Tango::DEV_UCHAR : o_str << "Tango::DevUChar" << endl; break; case Tango::DEV_BOOLEAN : o_str << "Tango::DevBoolean" << endl; break; case Tango::DEV_STATE : o_str << "Tango::DevState" << endl; break; case Tango::DEV_ULONG : o_str << "Tango::DevULong" << endl; break; case Tango::DEV_ULONG64 : o_str << "Tango::DevULong64" << endl; break; case Tango::Dev_ENCODED : o_str << "Tango::DevEncoded" << endl; break; case Tango::DEV_ENUM : o_str << "Tango::DevEnum" << endl; break; case Tango::DATA_TYPE_UNKNOWN : o_str << "Unknown" << endl; break; } o_str << "Attribute data_format = "; switch (conf.data_format) { case Tango::SCALAR : o_str << "scalar" << endl; break; case Tango::SPECTRUM : o_str << "spectrum, max_dim_x = " << conf.max_dim_x << endl; break; case Tango::IMAGE : o_str << "image, max_dim_x = " << conf.max_dim_x << ", max_dim_y = " << conf.max_dim_y << endl; break; case Tango::FMT_UNKNOWN : o_str << "Unknown" << endl; break; } if ((conf.writable == Tango::WRITE) || (conf.writable == Tango::READ_WRITE)) o_str << "Attribute is writable" << endl; else o_str << "Attribute is not writable" << endl; o_str << "Attribute label = " << conf.label.in() << endl; o_str << "Attribute description = " << conf.description.in() << endl; o_str << "Attribute unit = " << conf.unit.in(); o_str << ", standard unit = " << conf.standard_unit.in(); o_str << ", display unit = " << conf.display_unit.in() << endl; o_str << "Attribute format = " << conf.format.in() << endl; o_str << "Attribute min value = " << conf.min_value.in() << endl; o_str << "Attribute max value = " << conf.max_value.in() << endl; o_str << "Attribute min alarm = " << conf.min_alarm.in() << endl; o_str << "Attribute max alarm = " << conf.max_alarm.in() << endl; o_str << "Attribute writable_attr_name = " << conf.writable_attr_name.in() << endl; return o_str; } #endif // TANGO_HAS_LOG4TANGO } // End of Tango namespace tango-9.2.5a/lib/cpp/server/attrsetval.cpp0000644023471100065110000014507413034745001015471 00000000000000static const char *RcsId = "$Id: attrsetval.cpp 29827 2016-06-15 09:26:59Z taurel $"; //==================================================================================================================== // // file : attrsetval.cpp // // description : C++ source code for the Attribute class set_value() method family. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29827 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------- // // method : Attribute::set_value // // description : Set the attribute read value and quality. This method // automatically set the date when it has been called // This method is overloaded several times for all the // supported attribute data type // // in : p_data : The attribute read value // x : The attribute x dimension (default is 1) // y : The atttribute y dimension (default is 0) // release : A flag set to true if memory must be // de-allocated (default is false) // //-------------------------------------------------------------------------- void Attribute::set_value(Tango::DevShort *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_SHORT && data_type != Tango::DEV_ENUM) { SAFE_DELETE(p_data); stringstream ss; ss << "Invalid data type for attribute " << name; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); stringstream ss; ss << "Data size for attribute " << name << " exceeds given limit"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // For DevEnum, check that the enum labels are defined. Also check the enum value // if (data_type == DEV_ENUM) { if (enum_labels.size() == 0) { SAFE_DELETE(p_data); stringstream ss; ss << "Attribute " << name << " data type is enum but no enum labels are defined!"; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } int max_val = enum_labels.size() - 1; for (unsigned int i = 0;i < data_size;i++) { if (p_data[i] < 0 || p_data[i] > max_val) { SAFE_DELETE(p_data); stringstream ss; ss << "Wrong value for attribute " << name; ss << ". Element " << i << " (value = " << p_data[i] << ") is negative or above the limit defined by the enum (" << max_val << ")."; Except::throw_exception(API_AttrOptProp,ss.str(),"Attribute::set_value()"); } } } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_sh[0] = *p_data; SAFE_DELETE(p_data); } else { value.sh_seq = new Tango::DevVarShortArray(data_size); value.sh_seq->length(data_size); ::memcpy(value.sh_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevShort)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevShort *tmp_ptr = new Tango::DevShort[1]; *tmp_ptr = *p_data; value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.sh_seq = new Tango::DevVarShortArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevLong *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_LONG) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.lg_seq = new Tango::DevVarLongArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_lo[0] = *p_data; SAFE_DELETE(p_data); } else { value.lg_seq = new Tango::DevVarLongArray(data_size); value.lg_seq->length(data_size); ::memcpy(value.lg_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevLong)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevLong *tmp_ptr = new Tango::DevLong[1]; *tmp_ptr = *p_data; value.lg_seq = new Tango::DevVarLongArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.lg_seq = new Tango::DevVarLongArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevLong64 *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_LONG64) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.lg64_seq = new Tango::DevVarLong64Array(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_lo64[0] = *p_data; SAFE_DELETE(p_data); } else { value.lg64_seq = new Tango::DevVarLong64Array(data_size); value.lg64_seq->length(data_size); ::memcpy(value.lg64_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevLong64)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevLong64 *tmp_ptr = new Tango::DevLong64[1]; *tmp_ptr = *p_data; value.lg64_seq = new Tango::DevVarLong64Array(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.lg64_seq = new Tango::DevVarLong64Array(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevFloat *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_FLOAT) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.fl_seq = new Tango::DevVarFloatArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_fl[0] = *p_data; SAFE_DELETE(p_data); } else { value.fl_seq = new Tango::DevVarFloatArray(data_size); value.fl_seq->length(data_size); ::memcpy(value.fl_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevFloat)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevFloat *tmp_ptr = new Tango::DevFloat[1]; *tmp_ptr = *p_data; value.fl_seq = new Tango::DevVarFloatArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.fl_seq = new Tango::DevVarFloatArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevDouble *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_DOUBLE) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data_size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.db_seq = new Tango::DevVarDoubleArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_db[0] = *p_data; SAFE_DELETE(p_data); } else { value.db_seq = new Tango::DevVarDoubleArray(data_size); value.db_seq->length(data_size); ::memcpy(value.db_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevDouble)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevDouble *tmp_ptr = new Tango::DevDouble[1]; *tmp_ptr = *p_data; value.db_seq = new Tango::DevVarDoubleArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.db_seq = new Tango::DevVarDoubleArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevString *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_STRING) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { if (release == true) { char **strvec = Tango::DevVarStringArray::allocbuf(data_size); for (int i = 0;i < data_size;i++) strvec[i] = p_data[i]; value.str_seq = new Tango::DevVarStringArray(data_size,data_size,strvec,release); delete [] p_data; } else value.str_seq = new Tango::DevVarStringArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_str[0] = *p_data; SAFE_DELETE(p_data); scalar_str_attr_release = release; } else { value.str_seq = new Tango::DevVarStringArray(data_size); value.str_seq->length(data_size); for (int k = 0;k < data_size;k++) (*value.str_seq)[k] = CORBA::string_dup(p_data[k]); if (release == true) { if (is_fwd_att() == true) Tango::DevVarStringArray::freebuf(p_data); else { for (int k = 0;k < data_size;k++) delete [] p_data[k]; delete [] p_data; } } } } else { if (release == true) { char **strvec = Tango::DevVarStringArray::allocbuf(data_size); if (is_fwd_att() == true) { for (int i = 0;i < data_size;i++) strvec[i] = CORBA::string_dup(p_data[i]); } else { for (int i = 0;i < data_size;i++) strvec[i] = p_data[i]; } value.str_seq = new Tango::DevVarStringArray(data_size,data_size,strvec,release); if (data_format == Tango::SCALAR) { if (is_fwd_att() == true) Tango::DevVarStringArray::freebuf(p_data); else delete p_data; } else delete [] p_data; } else value.str_seq = new Tango::DevVarStringArray(data_size,data_size,p_data,release); } } value_flag = true; // // Get time // set_time(); } void Attribute::set_value(Tango::DevUShort *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_USHORT) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.ush_seq = new Tango::DevVarUShortArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_ush[0] = *p_data; SAFE_DELETE(p_data); } else { value.ush_seq = new Tango::DevVarUShortArray(data_size); value.ush_seq->length(data_size); ::memcpy(value.ush_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevUShort)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevUShort *tmp_ptr = new Tango::DevUShort[1]; *tmp_ptr = *p_data; value.ush_seq = new Tango::DevVarUShortArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.ush_seq = new Tango::DevVarUShortArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevBoolean *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_BOOLEAN) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.boo_seq = new Tango::DevVarBooleanArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_boo[0] = *p_data; SAFE_DELETE(p_data); } else { value.boo_seq = new Tango::DevVarBooleanArray(data_size); value.boo_seq->length(data_size); for (int k = 0;k < data_size;k++) (*value.boo_seq)[k] = p_data[k]; if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevBoolean *tmp_ptr = new Tango::DevBoolean[1]; *tmp_ptr = *p_data; value.boo_seq = new Tango::DevVarBooleanArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.boo_seq = new Tango::DevVarBooleanArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevUChar *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_UCHAR) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.cha_seq = new Tango::DevVarCharArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_cha[0] = *p_data; SAFE_DELETE(p_data); } else { value.cha_seq = new Tango::DevVarCharArray(data_size); value.cha_seq->length(data_size); ::memcpy(value.cha_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevUChar)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevUChar *tmp_ptr = new Tango::DevUChar[1]; *tmp_ptr = *p_data; value.cha_seq = new Tango::DevVarCharArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.cha_seq = new Tango::DevVarCharArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevULong *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_ULONG) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.ulg_seq = new Tango::DevVarULongArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_ulo[0] = *p_data; SAFE_DELETE(p_data); } else { value.ulg_seq = new Tango::DevVarULongArray(data_size); value.ulg_seq->length(data_size); ::memcpy(value.ulg_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevULong)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevULong *tmp_ptr = new Tango::DevULong[1]; *tmp_ptr = *p_data; value.ulg_seq = new Tango::DevVarULongArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.ulg_seq = new Tango::DevVarULongArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevULong64 *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_ULONG64) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.ulg64_seq = new Tango::DevVarULong64Array(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_ulo64[0] = *p_data; SAFE_DELETE(p_data); } else { value.ulg64_seq = new Tango::DevVarULong64Array(data_size); value.ulg64_seq->length(data_size); ::memcpy(value.ulg64_seq->get_buffer(false),p_data,data_size * sizeof(Tango::DevULong64)); if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevULong64 *tmp_ptr = new Tango::DevULong64[1]; *tmp_ptr = *p_data; value.ulg64_seq = new Tango::DevVarULong64Array(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete [] p_data; else delete p_data; } else value.ulg64_seq = new Tango::DevVarULong64Array(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevState *p_data,long x,long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_STATE) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.state_seq = new Tango::DevVarStateArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { if (data_format == Tango::SCALAR) { tmp_state[0] = *p_data; SAFE_DELETE(p_data); } else { value.state_seq = new Tango::DevVarStateArray(data_size); value.state_seq->length(data_size); for (int k = 0;k < data_size;k++) (*value.state_seq)[k] = p_data[k]; if (release == true) delete [] p_data; } } else { if ((data_format == Tango::SCALAR) && (release == true)) { Tango::DevState *tmp_ptr = new Tango::DevState[1]; *tmp_ptr = *p_data; value.state_seq = new Tango::DevVarStateArray(data_size,data_size,tmp_ptr,release); if (is_fwd_att() == true) delete p_data; else delete p_data; } else value.state_seq = new Tango::DevVarStateArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevEncoded *p_data,long x, long y,bool release) { // // Throw exception if type is not correct // if (data_type != Tango::DEV_ENCODED) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Invalid data type for attribute " << name << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Check that data size is less than the given max // if ((x > max_x) || (y > max_y)) { SAFE_DELETE(p_data); TangoSys_OMemStream o; o << "Data size for attribute " << name << " exceeds given limit" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } // // Compute data size and set default quality to valid. // dim_x = x; dim_y = y; set_data_size(); quality = Tango::ATTR_VALID; // // Throw exception if pointer is null and data size != 0 // if (data_size != 0) { CHECK_PTR(p_data,name); } // // If the data is wanted from the DevState command, store it in a sequence. // If the attribute has an associated writable attribute, store data in a // temporary buffer (the write value must be added before the data is sent // back to the caller) // if (date == false) { value.enc_seq = new Tango::DevVarEncodedArray(data_size,data_size,p_data,release); } else { if ((is_writ_associated() == true)) { tmp_enc[0] = *p_data; SAFE_DELETE(p_data); } else { if (release == true) { DevEncoded *tmp_ptr = new DevEncoded[1]; tmp_ptr->encoded_format = p_data->encoded_format; unsigned long nb_data = p_data->encoded_data.length(); tmp_ptr->encoded_data.replace(nb_data,nb_data,p_data->encoded_data.get_buffer(true),true); p_data->encoded_data.replace(0,0,NULL,false); value.enc_seq = new Tango::DevVarEncodedArray(data_size,data_size,tmp_ptr,true); delete p_data; } else value.enc_seq = new Tango::DevVarEncodedArray(data_size,data_size,p_data,release); } } value_flag = true; // // Reset alarm flags // alarm.reset(); // // Get time // set_time(); } void Attribute::set_value(Tango::DevString *p_data_str,Tango::DevUChar *p_data,long size,bool release) { if (p_data_str == NULL || p_data == NULL) { TangoSys_OMemStream o; o << "Data pointer for attribute " << name << " is NULL!" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } if (release == false) { enc_help.encoded_format = CORBA::string_dup(*p_data_str); enc_help.encoded_data.replace(size,size,p_data,false); set_value(&enc_help); } else { DevEncoded *enc_ptr = new DevEncoded; enc_ptr->encoded_format = CORBA::string_dup(*p_data_str); delete [] *p_data_str; enc_ptr->encoded_data.replace(size,size,p_data,true); set_value(enc_ptr,1,0,true); } } void Attribute::set_value(Tango::EncodedAttribute *attr) { CHECK_PTR(attr,name); Tango::DevString *f = attr->get_format(); Tango::DevUChar *d = attr->get_data(); long size = attr->get_size(); if( *f==NULL ) { TangoSys_OMemStream o; o << "DevEncoded format for attribute " << name << " not specified" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } if( size==0 || !d ) { TangoSys_OMemStream o; o << "DevEncoded data for attribute " << name << " not specified" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"Attribute::set_value()"); } set_value(f,d,size,false); if (attr->get_exclusion() == true) { set_user_attr_mutex(attr->get_mutex()); } } //+------------------------------------------------------------------------- // // method : Attribute::set_value_date_quality // // description : Set the attribute read value date and quality. // This method is overloaded several times for all the // supported attribute data type // // in : p_data : The attribute read value // t : The attribute date // qual : The attribute quality // x : The attribute x dimension (default is 1) // y : The atttribute y dimension (default is 0) // release : A flag set to true if memory must be // de-allocated (default is false) // //-------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevShort *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevShort *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevShort *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevLong *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevLong *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevLong *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevLong64 *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevLong64 *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevLong64 *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevFloat *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevFloat *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevFloat *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevDouble *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevDouble *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevDouble *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevString *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevString *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevString *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevBoolean *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevBoolean *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevBoolean *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevUShort *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevUShort *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevUShort *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevUChar *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevUChar *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevUChar *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevULong *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevULong *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevULong *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevULong64 *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevULong64 *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevULong64 *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevState *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevState *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #else void Attribute::set_value_date_quality(Tango::DevState *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); if (qual == Tango::ATTR_INVALID) { if (!((is_writ_associated() == true) && (data_format == Tango::SCALAR))) delete_seq(); } } #endif //--------------------------------------------------------------------------- void Attribute::set_value_date_quality(Tango::DevEncoded *p_data,time_t t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); } void Attribute::set_value_date_quality(Tango::DevString *p_data_str,Tango::DevUChar *p_data,long size,time_t t, Tango::AttrQuality qual, bool release) { set_value(p_data_str,p_data,size,release); set_quality(qual,false); set_date(t); } #ifdef _TG_WINDOWS_ void Attribute::set_value_date_quality(Tango::DevEncoded *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); } void Attribute::set_value_date_quality(Tango::DevString *p_data_str,Tango::DevUChar *p_data,long size,struct _timeb &t, Tango::AttrQuality qual, bool release) { set_value(p_data_str,p_data,size,release); set_quality(qual,false); set_date(t); } #else void Attribute::set_value_date_quality(Tango::DevEncoded *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y,bool release) { set_value(p_data,x,y,release); set_quality(qual,false); set_date(t); } void Attribute::set_value_date_quality(Tango::DevString *p_data_str,Tango::DevUChar *p_data,long size,struct timeval &t, Tango::AttrQuality qual, bool release) { set_value(p_data_str,p_data,size,release); set_quality(qual,false); set_date(t); } #endif } // End of Tango namespace tango-9.2.5a/lib/cpp/server/attrmanip.cpp0000644023471100065110000000575113034745001015274 00000000000000static const char *RcsId = "$Id: attrmanip.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+=================================================================================================================== // // file : attrmanip.cpp // // description : C++ source code for the tango attribute manipulator // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { void execute_manip(ostream &o_str, string &manip) { // // Set the ostream according to the manipulator // if (manip == "fixed") { o_str.setf(ios::fixed,ios::floatfield); return; } else if (manip == "scientific") { o_str.setf(ios::scientific,ios::floatfield); return; } else if (manip == "uppercase") { o_str.setf(ios::uppercase); return; } else if (manip == "showpoint") { o_str.setf(ios::showpoint); return; } else if (manip == "showpos") { o_str.setf(ios::showpos); return; } else if (manip.substr(0,13) == "setprecision(") { string num_str = manip.substr(13,manip.size() - 14); TangoSys_MemStream o; long num; o << num_str; o >> num; o_str.precision(num); } else if (manip.substr(0,5) == "setw(") { string num_str = manip.substr(5,manip.size() - 6); TangoSys_MemStream o; long num; o << num_str; o >> num; o_str.width(num); } } //#ifndef TANGO_HAS_LOG4TANGO ostream &operator<<(ostream &o_str,const AttrManip &manip) { // // Extract each manipulator (; separated) and call the execute_manip for each one // string::size_type start = 0; string str; string::size_type pos; while ((pos = manip.format.find(';',start)) != string::npos) { str = manip.format.substr(start,pos - start); start = pos + 1; execute_manip(o_str,str); } if (start != manip.format.size()) { str = manip.format.substr(start); execute_manip(o_str,str); } return o_str; } //#endif // TANGO_HAS_LOG4TANGO } // End of tango namespace tango-9.2.5a/lib/cpp/server/basiccommand.cpp0000644023471100065110000002227613034745002015717 00000000000000static const char *RcsId = "$Id: basiccommand.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+================================================================================================================== // // file : BasicCommand.cpp // // description : C++ source code for commands which are automatically installed for every devices // Three commands are : // DevState, DevStatus, DevRestart // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28853 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include extern omni_thread::key_t key_py_data; namespace Tango { //+---------------------------------------------------------------------------------------------------------------- // // method : // DevStatusCmd::DevStatusCmd // // description : // constructor for Command class Status // //----------------------------------------------------------------------------------------------------------------- DevStatusCmd::DevStatusCmd(const char *name,Tango::CmdArgType in,Tango::CmdArgType out) :Command(name,in,out) { } //+-------------------------------------------------------------------------------------------------------------- // // method : // DevStatusCmd::execute // // description : // return status as string // //------------------------------------------------------------------------------------------------------------------ CORBA::Any *DevStatusCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevStatus::execute(): arrived " << endl; // // return status string as Any // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevStatus::execute"); } try { if (device->is_alarm_state_forced() == true) (*out_any) <<= device->DeviceImpl::dev_status(); else (*out_any) <<= device->dev_status(); } catch(...) { delete out_any; throw; } cout4 << "Leaving DevStatus::execute()" << endl; return out_any; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DevStateCmd::DevStateCmd // // description : // constructor for Command class State // //------------------------------------------------------------------------------------------------------------------- DevStateCmd::DevStateCmd(const char *name,Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) { } //+----------------------------------------------------------------------------------------------------------------- // // method : // StateCmd::execute // // description : // return state as enumerated type // //------------------------------------------------------------------------------------------------------------------ CORBA::Any *DevStateCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevState::execute(): arrived" << endl; // // return state as Any // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevStatus::execute"); } try { if (device->is_alarm_state_forced() == true) (*out_any) <<= device->DeviceImpl::dev_state(); else (*out_any) <<= device->dev_state(); } catch(...) { delete out_any; throw; } cout4 << "Leaving DevState::execute()" << endl; return out_any; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevStateCmd::DevInitCmd // // description : // constructor for Command class Init // //------------------------------------------------------------------------------------------------------------------ DevInitCmd::DevInitCmd(const char *name,Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) { } //-------------------------------------------------------------------------------------------------------------------- // // method : // InitCmd::execute // // description : // Initialize a device // // argument : // in : // - device : Pointer to the device on which the command must be excuted // - in_any : Input data packed in a CORBA Any object // //-------------------------------------------------------------------------------------------------------------------- CORBA::Any *DevInitCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "Init::execute(): arrived" << endl; // // Get device interface only if necessary (some client(s) listening on device interface change event) // ZmqEventSupplier *event_supplier_zmq = Tango_nullptr; event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); DevIntr di; bool ev_client = false; if (event_supplier_zmq != Tango_nullptr) { ev_client = event_supplier_zmq->any_dev_intr_client(device); } if (device->get_dev_idl_version() >= MIN_IDL_DEV_INTR && ev_client == true) { di.get_interface(device); device->disable_intr_change_ev(); } // // Init device // omni_thread *th; PyLock *lock_ptr = NULL; Tango::Util *tg; try { NoSyncModelTangoMonitor mon(device); tg = Tango::Util::instance(); if (tg->is_py_ds()) { th = omni_thread::self(); omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Get(); } // clean the sub-device list for this device tg->get_sub_dev_diag().remove_sub_devices (device->get_name()); tg->get_sub_dev_diag().set_associated_device(device->get_name()); device->delete_device(); device->init_device(); // // Re-configure polling in device on which the Init cmd been done is the admin device but only if the Init is not // called during the DS startup sequence // DeviceImpl *admin_dev = NULL; try { admin_dev = tg->get_dserver_device(); } catch (Tango::DevFailed &) {} if (admin_dev == device) tg->polling_configure(); if (tg->is_py_ds()) lock_ptr->Release(); // // Apply memorized values for memorized attributes (if any). For Py DS, if some attributes are memorized, // the write_attributes call will take the Python lock // Tango::DeviceClass *dc = device->get_device_class(); vector dev_v = dc->get_device_list(); unsigned int loop; for (loop = 0;loop < dev_v.size();loop++) { if (dev_v[loop] == device) break; } if (loop != dev_v.size()) dc->set_memorized_values(false,loop,true); else { Tango::Except::throw_exception((const char *)API_DeviceNotFound, (const char *)"Can't find new device in device list", (const char *)"DevInitCmd::execute()"); } } catch (Tango::DevFailed &e) { if ((tg->is_py_ds() == true) && (lock_ptr != NULL)) { lock_ptr->Release(); } device->enable_intr_change_ev(); TangoSys_OMemStream o; o << "Init command failed!!"; o << "\nHINT: RESTART device with the Restart command of the device server adm. device"; o << "\nDevice server adm. device name = dserver/"; o << tg->get_ds_name().c_str() << ends; Except::re_throw_exception(e,(const char *)API_InitThrowsException,o.str(), (const char *)"DevInitCmd::execute()"); } // // Check if device interface has changed and eventually fire device interface change event // if (device->get_dev_idl_version() >= MIN_IDL_DEV_INTR && ev_client == true) { device->enable_intr_change_ev(); if (di.has_changed(device) == true) { Device_5Impl *dev_5 = static_cast(device); DevCmdInfoList_2 *cmds_list = dev_5->command_list_query_2(); DevVarStringArray dvsa(1); dvsa.length(1); dvsa[0] = Tango::string_dup(AllAttr_3); AttributeConfigList_5 *atts_list = dev_5->get_attribute_config_5(dvsa); event_supplier_zmq->push_dev_intr_change_event(device,false,cmds_list,atts_list); } } // // return to the caller // CORBA::Any *ret = return_empty_any("InitCmd"); return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/blackbox.cpp0000644023471100065110000014341713034745001015064 00000000000000static const char *RcsId = "$Id: blackbox.cpp 30454 2016-12-12 13:38:04Z bourtemb $\n$Name$"; //+================================================================================================================== // // file : BlackBox.cpp // // description : C++ source code for the BlackBoxElt and BlackBox classes. These classes are used to implement // the tango device server black box. There is one black box for each Tango device. This black box // keeps info. on all the activities on a device. A client is able to retrieve these data via // a Device CORBA attribute // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30454 $ // //-=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifdef _TG_WINDOWS_ #include #include #include #else #include #include #include #include #include #endif /* _TG_WINDOWS_ */ #include #include #include #include namespace Tango { // // The per thread data storage key (The client IP is stored in thread specific storage) // defined in utils.cpp // extern omni_thread::key_t key; // // The function called by the interceptor // CORBA::Boolean get_client_addr(omni::omniInterceptors::serverReceiveRequest_T::info_T &info) { omni_thread::self()->set_value(key,new client_addr(((omni::giopStrand &)info.giop_s.strand()).connection->peeraddress())); return true; } //+------------------------------------------------------------------------------------------------------------------ // // method : // BlackBoxElt::BlackBoxElt // // description : // Constructor for the BlackBoxElt class. This constructor simply set the internal value to their default // //------------------------------------------------------------------------------------------------------------------- BlackBoxElt::BlackBoxElt() { req_type = Req_Unknown; attr_type = Attr_Unknown; op_type = Op_Unknown; when.tv_sec = when.tv_usec = 0; host_ip_str[0] = '\0'; client_ident = false; attr_names.reserve(DEFAULT_ATTR_NB); } BlackBoxElt::~BlackBoxElt() { } //+------------------------------------------------------------------------------------------------------------------ // // method : // BlackBox::BlackBox // // description : // Two constructors for the BlackBox class. The first one does not take any argument and construct a black box // with the default depth. The second one create a black box with a depth defined by the argument. // // argument : // in : // - max_size : The black box depth // //------------------------------------------------------------------------------------------------------------------- BlackBox::BlackBox():box(DefaultBlackBoxDepth) { insert_elt = 0; nb_elt = 0; max_elt = DefaultBlackBoxDepth; } BlackBox::BlackBox(long max_size):box(max_size) { insert_elt = 0; nb_elt = 0; max_elt = max_size; } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::insert_corba_attr // // description : // This method insert a new element in the black box when this element is a attribute // // argument : // in : // - attr : The attribute type // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::insert_corba_attr(BlackBoxElt_AttrType attr) { // // Take mutex // sync.lock(); // // Insert elt in the box // box[insert_elt].req_type = Req_Attribute; box[insert_elt].attr_type = attr; box[insert_elt].op_type = Op_Unknown; box[insert_elt].client_ident = false; #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); // // Release mutex // sync.unlock(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // BlackBox::insert_cmd // // description : // This method insert a new element in the black box when this element is a call to the operation command_inout // // argument : // in : // - cmd : The command name // - vers : The IDL device version // - sour : The source parameter (DEV, CACHE...) // //------------------------------------------------------------------------------------------------------------------- void BlackBox::insert_cmd(const char *cmd,long vers,DevSource sour) { sync.lock(); insert_cmd_nl(cmd,vers,sour); sync.unlock(); } void BlackBox::insert_cmd_nl(const char *cmd,long vers,DevSource sour) { // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; if (vers == 1) box[insert_elt].op_type = Op_Command_inout; else if (vers <= 3) box[insert_elt].op_type = Op_Command_inout_2; else box[insert_elt].op_type = Op_Command_inout_4; box[insert_elt].cmd_name = cmd; box[insert_elt].source = sour; box[insert_elt].client_ident = false; #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::insert_cmd_cl_ident // // description : // This method insert a new element in the black box when this element is a call to the operation command_inout // // argument : // in : // - cmd : The command name // - cl_id : The client identification data // - sour : The source parameter (DEV, CACHE...) // //------------------------------------------------------------------------------------------------------------------ void BlackBox::insert_cmd_cl_ident(const char *cmd,const ClntIdent &cl_id,long vers,DevSource sour) { sync.lock(); // // Add basic info in the box // long old_insert = insert_elt; insert_cmd_nl(cmd,vers,sour); // // Check if the command is executed due to polling. If true, simply return // if (box[old_insert].host_ip_str[0] == 'p' || box[old_insert].host_ip_str[0] == 'u' || box[old_insert].host_ip_str[0] == 'i') { sync.unlock(); return; } // // Add client ident info into the client_addr instance and into the box // omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); sync.unlock(); } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::add_cl_ident // // description : // Add client identification data to the client address instance // // argument : // in : // - cl_ident : The client identificator // - cl_addr : The client address instance // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::add_cl_ident(const ClntIdent &cl_ident,client_addr *cl_addr) { cl_addr->client_ident = true; Tango::LockerLanguage cl_lang = cl_ident._d(); cl_addr->client_lang = cl_lang; if (cl_lang == Tango::CPP) { cl_addr->client_pid = cl_ident.cpp_clnt(); string str(cl_addr->client_ip); if (str.find(":unix:") != string::npos) { string::size_type pos = str.find(' '); if (pos != string::npos) cl_addr->client_ip[pos] = '\0'; } } else { Tango::JavaClntIdent jci = cl_ident.java_clnt(); cl_addr->java_main_class = jci.MainClass; cl_addr->java_ident[0] = jci.uuid[0]; cl_addr->java_ident[1] = jci.uuid[1]; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::update_client_host // // description : // Add client identification data to one of the BlackBox element // // argument : // in : // - ip : The client address instance // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::update_client_host(client_addr *ip) { long local_insert_elt = insert_elt; if (local_insert_elt == 0) local_insert_elt = max_elt - 1; else local_insert_elt--; box[local_insert_elt].client_ident = true; box[local_insert_elt].client_lang = ip->client_lang; box[local_insert_elt].client_pid = ip->client_pid; box[local_insert_elt].java_main_class = ip->java_main_class; } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::insert_op // // description : // This method insert a new element in the black box when this element is a call to an operation which is not // the command_inout operation // // argument : // in : // - op : The operation type // //------------------------------------------------------------------------------------------------------------------- void BlackBox::insert_op(BlackBoxElt_OpType op) { sync.lock(); insert_op_nl(op); sync.unlock(); } void BlackBox::insert_op(BlackBoxElt_OpType op,const ClntIdent &cl_id) { sync.lock(); long old_insert = insert_elt; insert_op_nl(op); // // Check if the command is executed due to polling. If true, simply return // if (box[old_insert].host_ip_str[0] == 'p' || box[old_insert].host_ip_str[0] == 'u' || box[old_insert].host_ip_str[0] == 'i') { sync.unlock(); return; } // // Add client ident info into the client_addr instance and into the box // omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); sync.unlock(); } void BlackBox::insert_op_nl(BlackBoxElt_OpType op) { // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; box[insert_elt].op_type = op; box[insert_elt].client_ident = false; #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); } //+-------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::insert_attr // // description : // This method insert a new element in the black box when this element is a call to the CORBA operation // read_attributes // // argument : // in : // - names : The attribute(s) name // - vers : The device IDl version // - sour : The device source parameter (CACHE, DEV,...) // //--------------------------------------------------------------------------------------------------------------------- void BlackBox::insert_attr(const Tango::DevVarStringArray &names,long vers,DevSource sour) { // // Take mutex // sync.lock(); // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; switch (vers) { case 1 : box[insert_elt].op_type = Op_Read_Attr; break; case 2 : box[insert_elt].op_type = Op_Read_Attr_2; break; case 3 : box[insert_elt].op_type = Op_Read_Attr_3; break; case 4 : box[insert_elt].op_type = Op_Read_Attr_4; break; } box[insert_elt].source = sour; box[insert_elt].client_ident = false; box[insert_elt].attr_names.clear(); for (unsigned long i = 0;i < names.length();i++) { string tmp_str(names[i]); box[insert_elt].attr_names.push_back(tmp_str); } #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); // // Release mutex // sync.unlock(); } void BlackBox::insert_attr(const Tango::DevVarStringArray &names,const ClntIdent &cl_id,long vers,DevSource sour) { // // Take mutex // sync.lock(); // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; if (vers == 5) box[insert_elt].op_type = Op_Read_Attr_5; else box[insert_elt].op_type = Op_Read_Attr_4; box[insert_elt].source = sour; box[insert_elt].client_ident = false; box[insert_elt].attr_names.clear(); for (unsigned long i = 0;i < names.length();i++) { string tmp_str(names[i]); box[insert_elt].attr_names.push_back(tmp_str); } #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes but before changing indexex, memorize if the request is done by polling or user // threads // bool poll_user = false; if (box[insert_elt].host_ip_str[0] == 'p' || box[insert_elt].host_ip_str[0] == 'u' || box[insert_elt].host_ip_str[0] == 'i') poll_user = true; inc_indexes(); // // If request is executed due to polling or from a user thread, simply return // if (poll_user == true) { sync.unlock(); return; } omni_thread::value_t *ip = omni_thread::self()->get_value(key); // // Add client ident info into the client_addr instance and into the box // add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); // // Release mutex // sync.unlock(); } void BlackBox::insert_attr(const char *name,const ClntIdent &cl_id,TANGO_UNUSED(long vers)) { // // Take mutex // sync.lock(); // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; box[insert_elt].op_type = Op_Read_Pipe_5; box[insert_elt].client_ident = false; box[insert_elt].attr_names.clear(); string tmp_str(name); box[insert_elt].attr_names.push_back(tmp_str); #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // bool poll_user = false; if (box[insert_elt].host_ip_str[0] == 'p' || box[insert_elt].host_ip_str[0] == 'u' || box[insert_elt].host_ip_str[0] == 'i') poll_user = true; inc_indexes(); // // Add client ident info into the client_addr instance and into the box // if (poll_user == false) { omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); } // // Release mutex // sync.unlock(); } void BlackBox::insert_attr(const Tango::DevPipeData &pipe_val,const ClntIdent &cl_id,long vers) { // // Take mutex // sync.lock(); // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; if (vers == 0) box[insert_elt].op_type = Op_Write_Pipe_5; else box[insert_elt].op_type = Op_Write_Read_Pipe_5; box[insert_elt].client_ident = false; box[insert_elt].attr_names.clear(); string tmp_str(pipe_val.name); box[insert_elt].attr_names.push_back(tmp_str); #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // bool poll_user = false; if (box[insert_elt].host_ip_str[0] == 'p' || box[insert_elt].host_ip_str[0] == 'u' || box[insert_elt].host_ip_str[0] == 'i') poll_user = true; inc_indexes(); // // Add client ident info into the client_addr instance and into the box // if (poll_user == false) { omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); } // // Release mutex // sync.unlock(); } void BlackBox::insert_attr(const Tango::AttributeValueList &att_list, long vers) { sync.lock(); insert_attr_nl(att_list,vers); sync.unlock(); } void BlackBox::insert_attr(const Tango::AttributeValueList_4 &att_list, const ClntIdent &cl_id,TANGO_UNUSED(long vers)) { sync.lock(); long old_insert = insert_elt; insert_attr_nl_4(att_list); // // Check if the command is executed due to polling. If true, simply return // if (box[old_insert].host_ip_str[0] == 'p' || box[old_insert].host_ip_str[0] == 'u' || box[old_insert].host_ip_str[0] == 'i') { sync.unlock(); return; } // // Add client ident info into the client_addr instance and into the box // omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); sync.unlock(); } void BlackBox::insert_attr_nl(const Tango::AttributeValueList &att_list, long vers) { // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; if (vers == 1) box[insert_elt].op_type = Op_Write_Attr; else if (vers < 4) box[insert_elt].op_type = Op_Write_Attr_3; else box[insert_elt].op_type = Op_Write_Attr_4; box[insert_elt].attr_names.clear(); for (unsigned long i = 0;i < att_list.length();i++) { string tmp_str(att_list[i].name); box[insert_elt].attr_names.push_back(tmp_str); } box[insert_elt].client_ident = false; #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); } void BlackBox::insert_attr_nl_4(const Tango::AttributeValueList_4 &att_list) { // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; box[insert_elt].op_type = Op_Write_Attr_4; box[insert_elt].attr_names.clear(); for (unsigned long i = 0;i < att_list.length();i++) { string tmp_str(att_list[i].name); box[insert_elt].attr_names.push_back(tmp_str); } #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); } //+-------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::insert_wr_attr // // description : // This method insert a new element in the black box when this element is a call to the CORBA operation // write_read_attributes // // argument : // in : // - att_list : The attribute list // - r_names : Attribute name(s) // - cl_id : Client identifier // - vers : // //--------------------------------------------------------------------------------------------------------------------- void BlackBox::insert_wr_attr(const Tango::AttributeValueList_4 &att_list,const Tango::DevVarStringArray &r_names,const ClntIdent &cl_id,long vers) { sync.lock(); long old_insert = insert_elt; insert_attr_wr_nl(att_list,r_names,vers); // // If request coming from polling thread or user thread, leave method // if (box[old_insert].host_ip_str[0] == 'p' || box[old_insert].host_ip_str[0] == 'u' || box[old_insert].host_ip_str[0] == 'i') { sync.unlock(); return; } // // Add client ident info into the client_addr instance and into the box // omni_thread::value_t *ip = omni_thread::self()->get_value(key); add_cl_ident(cl_id,static_cast(ip)); update_client_host(static_cast(ip)); sync.unlock(); } void BlackBox::insert_attr_wr_nl(const Tango::AttributeValueList_4 &att_list,const Tango::DevVarStringArray &r_names,long vers) { // // Insert elt in the box // box[insert_elt].req_type = Req_Operation; box[insert_elt].attr_type = Attr_Unknown; if (vers == 5) box[insert_elt].op_type = Op_Write_Read_Attributes_5; else box[insert_elt].op_type = Op_Write_Read_Attributes_4; box[insert_elt].attr_names.clear(); for (unsigned long i = 0;i < att_list.length();i++) { string tmp_str(att_list[i].name); box[insert_elt].attr_names.push_back(tmp_str); } box[insert_elt].attr_names.push_back(string("/")); for (unsigned long i = 0;i < r_names.length();i++) { string tmp_str(r_names[i]); box[insert_elt].attr_names.push_back(tmp_str); } #ifdef _TG_WINDOWS_ // // Note that the exact conversion between milli-sec and u-sec will be done only when data is send back to user. // This save some times in unnecessary computation // struct _timeb t; _ftime(&t); box[insert_elt].when.tv_usec = (long)t.millitm; box[insert_elt].when.tv_sec = (unsigned long)t.time; #else struct timezone tz; gettimeofday(&box[insert_elt].when,&tz); #endif // // get client address // get_client_host(); // // manage insert and read indexes // inc_indexes(); } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::inc_indexes // // description : // This private method increment the indexes used to acces the box itself. This is necessary because the box must // be managed as a circular buffer // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::inc_indexes() { insert_elt++; if (insert_elt == max_elt) insert_elt = 0; if (nb_elt != max_elt) nb_elt++; } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::get_client_host // // description : // This private method retrieves the client host IP address (the number). IT USES OMNIORB SPECIFIC INTERCEPTOR // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::get_client_host() { omni_thread *th_id = omni_thread::self(); if (th_id == NULL) th_id = omni_thread::create_dummy(); omni_thread::value_t *ip = th_id->get_value(key); if (ip == NULL) { Tango::Util *tg = Tango::Util::instance(); vector &poll_ths = tg->get_polling_threads_info(); bool found_thread = false; if (poll_ths.empty() == false) { int this_thread_id = th_id->id(); size_t nb_poll_th = poll_ths.size(); size_t loop; for (loop = 0;loop < nb_poll_th;loop++) { if (this_thread_id == poll_ths[loop]->thread_id) { found_thread = true; break; } } } if (tg->is_svr_starting() == true) { if (found_thread == true) strcpy(box[insert_elt].host_ip_str,"polling"); else strcpy(box[insert_elt].host_ip_str,"init"); } else { if (found_thread == true) strcpy(box[insert_elt].host_ip_str,"polling"); else strcpy(box[insert_elt].host_ip_str,"user thread"); } } else strcpy(box[insert_elt].host_ip_str,(static_cast(ip))->client_ip); } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::build_info_as_str // // description : // Translate all the info stored in a black box element into a readable string. // // argument : // in : // - index : The black box element index // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::build_info_as_str(long index) { char date_str[25]; // // Convert time to a string // date_ux_to_str(box[index].when,date_str); elt_str = date_str; // // Add request type and command name in case of // elt_str = elt_str + " : "; if (box[index].req_type == Req_Operation) { elt_str = elt_str + "Operation "; unsigned long i; unsigned long nb_in_vect; switch (box[index].op_type) { case Op_Command_inout : elt_str = elt_str + "command_inout (cmd = " + box[index].cmd_name + ") from "; add_source(index); break; case Op_Ping : elt_str = elt_str + "ping "; break; case Op_Info : elt_str = elt_str + "info "; break; case Op_BlackBox : elt_str = elt_str + "blackbox "; break; case Op_Command_list : elt_str = elt_str + "command_list_query "; break; case Op_Command : elt_str = elt_str + "command_query "; break; case Op_Get_Attr_Config : elt_str = elt_str + "get_attribute_config "; break; case Op_Set_Attr_Config : elt_str = elt_str + "set_attribute_config "; break; case Op_Read_Attr : elt_str = elt_str + "read_attributes ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") from "; add_source(index); break; case Op_Write_Attr : elt_str = elt_str + "write_attributes ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Write_Attr_3 : elt_str = elt_str + "write_attributes_3 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Command_inout_2 : elt_str = elt_str + "command_inout_2 (cmd = " + box[index].cmd_name + ") from "; add_source(index); break; case Op_Command_list_2 : elt_str = elt_str + "command_list_query_2 "; break; case Op_Command_2 : elt_str = elt_str + "command_query_2 "; break; case Op_Get_Attr_Config_2 : elt_str = elt_str + "get_attribute_config_2 "; break; case Op_Read_Attr_2 : elt_str = elt_str + "read_attributes_2 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") from "; add_source(index); break; case Op_Read_Attr_3 : elt_str = elt_str + "read_attributes_3 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") from "; add_source(index); break; case Op_Command_inout_history_2 : elt_str = elt_str + "command_inout_history_2 "; break; case Op_Read_Attr_history_2 : elt_str = elt_str + "read_attribute_history_2 "; break; case Op_Read_Attr_history_3 : elt_str = elt_str + "read_attribute_history_3 "; break; case Op_Info_3 : elt_str = elt_str + "info_3 "; break; case Op_Get_Attr_Config_3 : elt_str = elt_str + "get_attribute_config_3 "; break; case Op_Set_Attr_Config_3 : elt_str = elt_str + "set_attribute_config_3 "; break; case Op_Read_Attr_history_4 : elt_str = elt_str + "read_attribute_history_4 "; break; case Op_Command_inout_history_4 : elt_str = elt_str + "command_inout_history_4 "; break; case Op_Command_inout_4 : elt_str = elt_str + "command_inout_4 (cmd = " + box[index].cmd_name + ") from "; add_source(index); break; case Op_Read_Attr_4 : elt_str = elt_str + "read_attributes_4 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") from "; add_source(index); break; case Op_Write_Attr_4 : elt_str = elt_str + "write_attributes_4 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Set_Attr_Config_4 : elt_str = elt_str + "set_attribute_config_4 "; break; case Op_Write_Read_Attributes_4 : elt_str = elt_str + "write_read_attributes_4 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Get_Attr_Config_5 : elt_str = elt_str + "get_attribute_config_5 "; break; case Op_Set_Attr_Config_5 : elt_str = elt_str + "set_attribute_config_5 "; break; case Op_Read_Attr_5 : elt_str = elt_str + "read_attributes_5 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") from "; add_source(index); break; case Op_Write_Read_Attributes_5 : elt_str = elt_str + "write_read_attributes_5 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1 && box[index].attr_names[i] != "/") { if (box[index].attr_names[i + 1] != "/") elt_str = elt_str + ", "; } } elt_str = elt_str + ") "; break; case Op_Read_Attr_history_5 : elt_str = elt_str + "read_attribute_history_5 "; break; case Op_Get_Pipe_Config_5 : elt_str = elt_str + "get_pipe_config_5 "; break; case Op_Set_Pipe_Config_5 : elt_str = elt_str + "set_pipe_config_5 "; break; case Op_Read_Pipe_5 : elt_str = elt_str + "read_pipe_5 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Write_Pipe_5 : elt_str = elt_str + "write_pipe_5 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Write_Read_Pipe_5 : elt_str = elt_str + "write_read_pipe_5 ("; nb_in_vect = box[index].attr_names.size(); for (i = 0;i < nb_in_vect;i++) { elt_str = elt_str + box[index].attr_names[i]; if (i != nb_in_vect - 1) elt_str = elt_str + ", "; } elt_str = elt_str + ") "; break; case Op_Unknown : elt_str = elt_str + "unknown operation !!!!!"; return; } } else if (box[index].req_type == Req_Attribute) { elt_str = elt_str + "Attribute "; switch (box[index].attr_type) { case Attr_Name : elt_str = elt_str + "name "; break; case Attr_Description : elt_str = elt_str + "description "; break; case Attr_Status : elt_str = elt_str + "status "; break; case Attr_State : elt_str = elt_str + "state "; break; case Attr_AdmName : elt_str = elt_str + "adm_name "; break; case Attr_Unknown : elt_str = elt_str + "unknown attribute !!!!!"; return; } } else { elt_str = elt_str + "Unknown CORBA request type !!!!!"; return; } // // Add client host name. // Extract only IP numbers from the omni address format (giop:tcp:xx.yy.zz.kk:port) // Return in case of badly formed address // if ((box[index].host_ip_str[0] != '\0') && (box[index].host_ip_str[0] != 'p') && (box[index].host_ip_str[5] != 'u') && (box[index].host_ip_str[0] != 'i') && (box[index].host_ip_str[0] != 'u')) { bool ipv6=false; string omni_addr = box[index].host_ip_str; string::size_type pos; if ((pos = omni_addr.find(':')) == string::npos) return; pos++; if ((pos = omni_addr.find(':',pos)) == string::npos) return; pos++; string ip_str = omni_addr.substr(pos); if (ip_str[0] == '[') ipv6 = true; string full_ip_str; if (ipv6 == false) { if ((pos = ip_str.find(':')) == string::npos) return; full_ip_str = ip_str.substr(0,pos); } else { if ((pos = ip_str.find(':')) == string::npos) return; pos++; if ((pos = ip_str.find(':',pos)) == string::npos) return; pos++; if ((pos = ip_str.find(':',pos)) == string::npos) return; pos++; string tmp_ip = ip_str.substr(pos); if ((pos = tmp_ip.find(']')) == string::npos) return; full_ip_str = tmp_ip.substr(0,pos); } if ((pos = full_ip_str.find('.')) == string::npos) return; string ip1_str = full_ip_str.substr(0,pos); string::size_type old_pos; pos++; old_pos = pos; if ((pos = full_ip_str.find('.',pos)) == string::npos) return; string ip2_str = full_ip_str.substr(old_pos,pos - old_pos); pos++; old_pos = pos; if ((pos = full_ip_str.find('.',pos)) == string::npos) return; string ip3_str = full_ip_str.substr(old_pos,pos - old_pos); pos++; string ip4_str = full_ip_str.substr(pos); // // Finally, get host name // struct sockaddr_in si; si.sin_family = AF_INET; si.sin_port = 0; #ifdef _TG_WINDOWS_ int slen = sizeof(si); WSAStringToAddress((char *)full_ip_str.c_str(),AF_INET,NULL,(SOCKADDR *)&si,&slen); #else inet_pton(AF_INET,full_ip_str.c_str(),&si.sin_addr); #endif char host[512]; int res = getnameinfo((const sockaddr *)&si,sizeof(si),host,512,0,0,0); #ifdef _TG_WINDOWS_ for (int i = 0;i < ::strlen(host);i++) host[i] = ::tolower(host[i]); #endif if (res == 0) { elt_str = elt_str + "requested from "; elt_str = elt_str + host; } else { elt_str = elt_str + "requested from "; elt_str = elt_str + full_ip_str; } // // Add client identification if available // if (box[index].client_ident == true) { if (box[index].client_lang == Tango::CPP) { elt_str = elt_str + " (CPP/Python client with PID "; TangoSys_MemStream o; o << box[index].client_pid; elt_str = elt_str + o.str() + ")"; } else { elt_str = elt_str + " (Java client with main class "; elt_str = elt_str + box[index].java_main_class + ")"; } } } else if (box[index].host_ip_str[5] == 'u') { Tango::Util *tg = Tango::Util::instance(); elt_str = elt_str + "requested from " + tg->get_host_name(); // // Add client identification if available // if (box[index].client_ident == true) { if (box[index].client_lang == Tango::CPP) { elt_str = elt_str + " (CPP/Python client with PID "; TangoSys_MemStream o; o << box[index].client_pid; elt_str = elt_str + o.str() + ")"; } else { elt_str = elt_str + " (Java client with main class "; elt_str = elt_str + box[index].java_main_class + ")"; } } } else if (box[index].host_ip_str[0] == 'p') { elt_str = elt_str + "requested from polling"; } else if (box[index].host_ip_str[0] == 'i') { elt_str = elt_str + "requested during device server process init sequence"; } else if (box[index].host_ip_str[0] == 'u') { elt_str = elt_str + "requested from user thread"; } return; } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::add_source // // description : // Read black box element as strings. The newest element is return in the first position // // argument : // in : // - index : The number of element to read // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::add_source(long index) { switch (box[index].source) { case DEV : elt_str = elt_str + "device "; break; case CACHE : elt_str = elt_str + "cache "; break; case CACHE_DEV : elt_str = elt_str + "cache_device "; break; default : elt_str = elt_str + "unknown source (!) "; break; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // BlackBox::read // // description : // Read black box element as strings. The newest element is returned in the first position // // argument : // in : // - index : The number of element to read // //-------------------------------------------------------------------------------------------------------------------- Tango::DevVarStringArray *BlackBox::read(long wanted_elt) { // // Take mutex // sync.lock(); // // Throw exeception if the wanted element is stupid and if there is no element stored in the black box // if (wanted_elt <= 0) { sync.unlock(); Except::throw_exception((const char *)API_BlackBoxArgument, (const char *)"Argument to read black box out of range", (const char *)"BlackBox::read"); } if (nb_elt == 0) { sync.unlock(); Except::throw_exception((const char *)API_BlackBoxEmpty, (const char *)"Nothing stored yet in black-box", (const char *)"BlackBox::read"); } // // Limit wanted element to a reasonable value // if (wanted_elt > max_elt) wanted_elt = max_elt; if (wanted_elt > nb_elt) wanted_elt = nb_elt; // // Read black box elements // Tango::DevVarStringArray *ret = NULL; try { ret = new Tango::DevVarStringArray(wanted_elt); ret->length(wanted_elt); long read_index; if (insert_elt == 0) read_index = max_elt - 1; else read_index = insert_elt - 1; for (long i = 0;i < wanted_elt;i++) { build_info_as_str(read_index); (*ret)[i] = elt_str.c_str(); read_index--; if (read_index < 0) read_index = max_elt - 1; } } catch (bad_alloc &) { sync.unlock(); Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"BlackBox::read"); } // // Release mutex // sync.unlock(); return(ret); } //+------------------------------------------------------------------------------------------------------------------ // // method : // BlackBox::date_ux_to_str // // description : // Convert a UNIX date (number of seconds since EPOCH) to a string of the following format : // dd/mm/yyyy hh24:mi:ss:xx // // argument : // in : // - ux_date : The UNIX date in a timeval structure // out : // - str_date : Pointer to char array where the date will be stored (must be allocated) // //-------------------------------------------------------------------------------------------------------------------- void BlackBox::date_ux_to_str(timeval &ux_date,char *str_date) { long i; char month[5]; char unix_date[40]; /* Convert UNIX date to a string in UNIX format */ time_t tmp_val = ux_date.tv_sec; #ifdef _TG_WINDOWS_ ctime_s(unix_date,40,&tmp_val); #else ctime_r(&tmp_val,unix_date); #endif unix_date[strlen(unix_date) - 1] = '\0'; /* Copy day */ for (i = 0;i < 2;i++) str_date[i] = unix_date[i + 8]; str_date[2] = '/'; str_date[3] = '\0'; if (str_date[0] == ' ') str_date[0] = '0'; /* Copy month */ for (i = 0;i < 3;i++) month[i] = unix_date[i + 4]; month[3] = '\0'; switch(month[0]) { case 'J' : if (month[1] == 'u') { if (month[2] == 'n') strcat(str_date,"06/"); else strcat(str_date,"07/"); } else strcat(str_date,"01/"); break; case 'F' : strcat(str_date,"02/"); break; case 'M' : if (month[2] == 'r') strcat(str_date,"03/"); else strcat(str_date,"05/"); break; case 'A' : if (month[1] == 'p') strcat(str_date,"04/"); else strcat(str_date,"08/"); break; case 'S' : strcat(str_date,"09/"); break; case 'O' : strcat(str_date,"10/"); break; case 'N' : strcat(str_date,"11/"); break; case 'D' : strcat(str_date,"12/"); break; } str_date[6] = '\0'; /* Copy year */ strcat(str_date,&(unix_date[20])); str_date[10] = '\0'; /* Copy date remaining */ strcat(str_date," "); for (i = 0;i < 8;i++) str_date[i + 11] = unix_date[i + 11]; str_date[19] = '\0'; /* Add milliseconds */ #ifdef _TG_WINDOWS_ sprintf(&(str_date[19]),":%.2d",(int)(ux_date.tv_usec/10)); #else sprintf(&(str_date[19]),":%.2d",(int)(ux_date.tv_usec/10000)); #endif } //+------------------------------------------------------------------------------------------------------------------ // // method : // client_addr::client_addr // // description : // Copy ctor of the client_addr class // //------------------------------------------------------------------------------------------------------------------- client_addr::client_addr(const client_addr &rhs) { client_ident = rhs.client_ident; client_lang = rhs.client_lang; client_pid = rhs.client_pid; java_main_class = rhs.java_main_class; java_ident[0] = rhs.java_ident[0]; java_ident[1] = rhs.java_ident[1]; memcpy(client_ip,rhs.client_ip,IP_ADDR_BUFFER_SIZE); } //+------------------------------------------------------------------------------------------------------------------ // // method : // client_addr::operator=() // // description : // Assignement operator of the client_addr class // //------------------------------------------------------------------------------------------------------------------- client_addr & client_addr::operator=(const client_addr &rhs) { if (this == &rhs) return *this; client_ident = rhs.client_ident; client_lang = rhs.client_lang; client_pid = rhs.client_pid; java_main_class = rhs.java_main_class; java_ident[0] = rhs.java_ident[0]; java_ident[1] = rhs.java_ident[1]; memcpy(client_ip,rhs.client_ip,IP_ADDR_BUFFER_SIZE); return *this; } //+------------------------------------------------------------------------------------------------------------------- // // method : // client_addr::operator==() // // description : // Equality operator of the client_addr class // //-------------------------------------------------------------------------------------------------------------------- bool client_addr::operator==(const client_addr &rhs) { if (client_ident != rhs.client_ident) return false; if (client_lang != rhs.client_lang) return false; else { if (client_lang == Tango::CPP) { if (client_pid != rhs.client_pid) return false; char *tmp = client_ip; const char *rhs_tmp = rhs.client_ip; if (strlen(tmp) != strlen(rhs_tmp)) return false; if (strcmp(tmp,rhs_tmp) != 0) return false; } else { if (java_ident[0] != rhs.java_ident[0]) return false; if (java_ident[1] != rhs.java_ident[1]) return false; } } return true; } //+------------------------------------------------------------------------------------------------------------------ // // method : // client_addr::operator!=() // // description : // Operator of the client_addr class // //-------------------------------------------------------------------------------------------------------------------- bool client_addr::operator!=(const client_addr &rhs) { if (client_ident != rhs.client_ident) return true; if (client_lang != rhs.client_lang) return true; else { if (client_lang == Tango::CPP) { if (client_pid != rhs.client_pid) return true; char *tmp = client_ip; const char *rhs_tmp = rhs.client_ip; if (strlen(tmp) != strlen(rhs_tmp)) return true; if (strcmp(tmp,rhs_tmp) != 0) return true; } else { if (java_ident[0] != rhs.java_ident[0]) return true; if (java_ident[1] != rhs.java_ident[1]) return true; } } return false; } //+-------------------------------------------------------------------------------------------------------------------- // // method : // client_addr::client_ip_2_client_name() // // description : // Convert client host IP address to client host name // //--------------------------------------------------------------------------------------------------------------------- int client_addr::client_ip_2_client_name(string &cl_host_name) const { int ret = 0; string client_ip_str(client_ip); string::size_type pos; if ((pos = client_ip_str.find(':')) == string::npos) ret = -1; else { pos++; if ((pos = client_ip_str.find(':',pos)) == string::npos) ret = -1; else { pos++; string ip_str = client_ip_str.substr(pos); if ((pos = ip_str.find(':')) == string::npos) ret = -1; else { string full_ip_str = ip_str.substr(0,pos); if ((pos = full_ip_str.find('.')) == string::npos) ret = -1; else { string ip1_str = full_ip_str.substr(0,pos); string::size_type old_pos; pos++; old_pos = pos; if ((pos = full_ip_str.find('.',pos)) == string::npos) ret = -1; else { string ip2_str = full_ip_str.substr(old_pos,pos - old_pos); pos++; old_pos = pos; if ((pos = full_ip_str.find('.',pos)) == string::npos) ret = -1 ; else { string ip3_str = full_ip_str.substr(old_pos,pos - old_pos); pos++; string ip4_str = full_ip_str.substr(pos); struct sockaddr_in si; si.sin_family = AF_INET; si.sin_port = 0; #ifdef _TG_WINDOWS_ int slen = sizeof(si); WSAStringToAddress((char *)full_ip_str.c_str(),AF_INET,NULL,(SOCKADDR *)&si,&slen); #else inet_pton(AF_INET,full_ip_str.c_str(),&si.sin_addr); #endif char host[512]; int res = getnameinfo((const sockaddr *)&si,sizeof(si),host,512,0,0,0); if (res == 0) { cl_host_name = host; ret = 0; } else ret = -1; } } } } } } return ret; } //+------------------------------------------------------------------------------------------------------------------- // // operator overloading : << // // description : // Friend function to ease printing instance of the client_addr class // //-------------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,const client_addr &ca) { if (ca.client_ident == false) o_str << "Client identification not available"; else { if (ca.client_lang == Tango::CPP) { string cl_name; o_str << "CPP or Python client with PID " << ca.client_pid << " from host "; if (ca.client_ip_2_client_name(cl_name) == 0) o_str << cl_name; else o_str << ca.client_ip; } else { o_str << "JAVA client class " << ca.java_main_class << " from host "; string cl_name; if (ca.client_ip_2_client_name(cl_name) == 0) o_str << cl_name; else o_str << ca.client_ip; } } return o_str; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/class_factory.cpp0000644023471100065110000001255113034745001016125 00000000000000static const char *RcsId = "$Id: class_factory.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+=========================================================================== // // file : class_factory.cpp // // description : C++ source file for a dummy DServer::class_factory() // method. For server, this method is redefined by the // DS programmer in its own file and the linker will not // use this file. For client where ther is no // class_factory() method, this one will be used by the // linker // This works only if class_factory() is in its own file // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-=========================================================================== #if HAVE_CONFIG_H #include #endif #include namespace Tango { // // There is a trick to build Windows DLL and to use it in a server. // To build a DLL, you have to pass your code into the linker. The linker // try to resolve all symbols. Therefore, it resolves the DServer::class_factory // with this default class_factory. For a server, it's annoying because we // want the user DServer::class_factory to be called !! // For all other kinds of lib (Unix type or Windows static), the linker is used // only when the application is built and symbols are resolved first from the // supplied object files and only if not found in object files with symbols // defined in libraries. // Therefore, the trick for DLL, is inside the default DServer::class_factory // to force calling the user DServer::class_factory // To do this, we use the GetProcAddress and we defines in dserver.h file // the class_factory has "export". // There is another trick to cast the pointer returned by GetProcAddress // which is a pointer to function into a pointer to method. // This is done using an union and initializing the pointeur to method // with a local method and then modifying it // #ifdef _TG_WINDOWS_ typedef void (DServer::*PTR)(void); typedef union _convertor { PTR d; FARPROC s; }convertor; #endif #ifdef __darwin__ #include typedef void (DServer::*PTR)(void); typedef union _convertor { PTR d; void *s; }convertor; #endif void DServer::class_factory() { #ifdef _TG_WINDOWS_ Tango::Util *tg = Tango::Util::instance(); string exe_name = tg->get_ds_exec_name(); exe_name = exe_name + ".exe"; HMODULE mod; FARPROC proc; convertor conv; PTR tmp; if (tg->is_py_ds() == false) { if ((mod = GetModuleHandle(exe_name.c_str())) == NULL) { cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); } } else { if ((mod = GetModuleHandle(TANGO_PY_MOD_NAME)) == NULL) { cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); } } // // Use the mangled name to find the user DServer::class_factory method // // Due to the fact that on Windows 64 bits we have both _WIN32 and _WIN64 // defined, start by testing _WIN64 (See tango_config.h) // #ifdef _WIN64 if ((proc = GetProcAddress(mod,"?class_factory@DServer@Tango@@AEAAXXZ")) == NULL) #elif _WIN32 /* WIN32 */ if ((proc = GetProcAddress(mod,"?class_factory@DServer@Tango@@AAEXXZ")) == NULL) #endif { cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); } else { conv.d = &DServer::stop_polling; conv.s = proc; tmp = conv.d; (this->*tmp)(); } #elif __darwin__ Tango::Util *tg = Tango::Util::instance(); string exe_name = tg->get_ds_exec_name(); exe_name = exe_name; void *mod; void *proc; convertor conv; PTR tmp; if (tg->is_py_ds() == false) { if ((mod = dlopen (exe_name.c_str(), RTLD_LAZY )) == NULL) { cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); } } else { /* if ((mod = GetModuleHandle(TANGO_PY_MOD_NAME)) == NULL) { cerr << "Oups, no class defined in this server. Exiting ..." << endl; exit(-1); } */ } // // Use the mangled name to find the user DServer::class_factory method // // Due to the fact that on Windows 64 bits we have both WIN32 and WIN64 // defined, start by testing WIN64 (See tango_config.h) // if ((proc = dlsym (mod,"_ZN5Tango7DServer13class_factoryEv")) == NULL) { cerr << "error : " << dlerror() << endl; cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); } else { conv.d = &DServer::stop_polling; conv.s = proc; tmp = conv.d; (this->*tmp)(); } #else cerr << "Oops, no class defined in this server. Exiting ..." << endl; exit(-1); #endif } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/classattribute.cpp0000644023471100065110000002717713034745001016334 00000000000000 static const char *RcsId = "$Id: classattribute.cpp 27976 2015-05-18 13:59:32Z taurel $\n$Name$"; //+================================================================================================================= // // file : ClassAttribute.cpp // // description : C++ source code for the // AttrProperty // ClassAttribute and // MultiClassAttribute // classes. These classes are used to manage attribute properties defined at the class level. A Tango // DeviceClass class instance has one MultiClassAttribute object which is an aggregate of // ClassAttribute objects // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27976 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // AttrProperty::AttrProperty // // description : // Constructors for the AttrProperty class. These constructor change the property name to lowercase letters and // also change the property value to lowercase letters for the data_format and data_type property // // argument : // in : // - name : The property name // - value : The property value // //------------------------------------------------------------------------------------------------------------------ AttrProperty::AttrProperty(string &name,string &value):attr_name(name),attr_value(value) { attr_lg = 0; // // Property name in lower case letters // transform(attr_name.begin(),attr_name.end(),attr_name.begin(),::tolower); // // For data_type or data_format properties, also change property value to lowercase letters // if ((attr_name == "data_type") || (attr_name == "data_format")) transform(attr_value.begin(),attr_value.end(),attr_value.begin(),::tolower); } AttrProperty::AttrProperty(const char *name,const char *value):attr_name(name),attr_value(value) { attr_lg = 0; // // Property name in lower case letters // transform(attr_name.begin(),attr_name.end(),attr_name.begin(),::tolower); // // For data_type or data_format properties, also change property value to lowercase letters // if ((attr_name == "data_type") || (attr_name == "data_format")) transform(attr_value.begin(),attr_value.end(),attr_value.begin(),::tolower); } AttrProperty::AttrProperty(const char *name,long value):attr_name(name),attr_lg(value) { } AttrProperty::AttrProperty(const char *name,string &value):attr_name(name),attr_value(value),attr_lg(0) { } //+----------------------------------------------------------------------------------------------------------------- // // method : // AttrProperty::convert // // description : // Convert the property value into a long. The long data is also stored in the AttrProperty class // //------------------------------------------------------------------------------------------------------------------ void AttrProperty::convert(const char *prop_name) { TangoSys_MemStream o; o << attr_value; if (!(o >> attr_lg && o.eof())) { stringstream ss; ss << "Can't convert property value for property " << prop_name; Except::throw_exception(API_AttrOptProp, ss.str(), "AttrProperty::convert"); } } //+----------------------------------------------------------------------------------------------------------------- // // operator overloading : << // // description : // Friend function to ease printing instance of the AttrProperty class // //------------------------------------------------------------------------------------------------------------------- #ifndef TANGO_HAS_LOG4TANGO ostream &operator<<(ostream &o_str,const AttrProperty &p) { o_str << "Property name = " << p.attr_name << ", Property value = " << p.attr_value; return o_str; } #endif // TANGO_HAS_LOG4TANGO //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiClassAttribute::MultiClassAttribute // // description : // constructor for the MultiClassAttribute class from the device class name // //------------------------------------------------------------------------------------------------------------------- MultiClassAttribute::~MultiClassAttribute() { long nb_attr = attr_list.size(); for (int i = 0;i < nb_attr;i++) delete attr_list[i]; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassAttribute::MultiClassAttribute // // description : // Constructor for the MultiClassAttribute class from the device class name // //-------------------------------------------------------------------------------------------------------------------- MultiClassAttribute::MultiClassAttribute() { cout4 << "Entering MultiClassAttribute constructor" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassAttribute::init_class_attribute // // description : // Ask the database for properties defined at class level and build the ClassAttribute object for each attribute // with defined properties // // argument : // in : // - class_name : The device class name // //------------------------------------------------------------------------------------------------------------------- void MultiClassAttribute::init_class_attribute(string &class_name,long base) { cout4 << "Entering MultiClassAttribute::init_class_attribute" << endl; long i; Tango::Util *tg = Tango::Util::instance(); CORBA::Any send; long nb_attr; if (base == 0) nb_attr = attr_list.size(); else nb_attr = 1; // // Get class attribute(s) properties stored in DB. No need to implement a retry here (in case of db server restart) // because the db reconnection is forced by the get_property call executed during xxxClass construction // before we reach this code. // if ((nb_attr != 0) && (Tango::Util::_UseDb == true)) { Tango::DbData db_list; for(i = 0;i < nb_attr;i++) db_list.push_back(DbDatum(attr_list[i + base]->get_name())); try { tg->get_database()->get_class_attribute_property(class_name,db_list,tg->get_db_cache()); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Can't get class attribute properties for class " << class_name << ends; Except::re_throw_exception(e,(const char *)API_DatabaseAccess, o.str(), (const char *)"MultiClassAttribute::init_class_attribute"); } // // Sort property for each attribute and create a ClassAttribute object for each of them // long ind = 0; for (i = 0;i < nb_attr;i++) { vector prop_list; string attr_name = db_list[ind].name; long nb_prop = 0; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + " "; tmp = tmp + db_list[ind].value_string[k]; } prop_list.push_back(AttrProperty(db_list[ind].name,tmp)); } else prop_list.push_back(AttrProperty(db_list[ind].name,db_list[ind].value_string[0])); ind++; } if (nb_prop != 0) { // // Find this attribute in the attribute list // unsigned int k; for (k = 0;k < attr_list.size();k++) { if (attr_name == attr_list[k]->get_name()) break; } if (k == attr_list.size()) { TangoSys_OMemStream o; o << "Attribute " << attr_name << " not found in class attribute(s)" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"MultiClassAttribute::init_class_attribute"); } // // Add its class property list // attr_list[k]->set_class_properties(prop_list); } } } for (i = 0;i < nb_attr;i++) { cout4 << *(attr_list[i + base]) << endl; } cout4 << "Leaving MultiClassAttribute::init_class_attribute" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassAttribute::get_attr // // description : // Get the Attr object for the attribute with name passed as parameter // // argument : // in : // - attr_name : The attribute name // // return : // Reference to the ClassAttribute object or throw an exceptionif the attribute is not found // //-------------------------------------------------------------------------------------------------------------------- Attr &MultiClassAttribute::get_attr(string &attr_name) { // // Search for the wanted attribute in the attr_list vector from its name // vector::iterator pos; pos = find_if(attr_list.begin(),attr_list.end(), bind2nd(WantedClassAttr(),attr_name)); if (pos == attr_list.end()) { TangoSys_OMemStream o; o << "Attribute " << attr_name << " not found in class attribute(s)" << ends; Except::throw_exception((const char *)API_AttrOptProp,o.str(), (const char *)"MultiClassAttribute::get_attr"); } return *(*pos); } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiClassAttribute::remove_attr // // description : // Remove the Attr object for the attribute with name passed as parameter // // argument : // in : // - attr_name : The attribute name // - cl_name : The attribute class name // //-------------------------------------------------------------------------------------------------------------------- void MultiClassAttribute::remove_attr(const string &attr_name,const string &cl_name) { vector::iterator ite; for (ite = attr_list.begin();ite != attr_list.end();++ite) { if (((*ite)->get_name() == attr_name) && ((*ite)->get_cl_name() == cl_name)) { attr_list.erase(ite); break; } } } //+------------------------------------------------------------------------------------------------------------------ // // operator overloading : << // // description : // Friend function to ease printing instance of the Attr class. It prints all the attribute property(ies) name // and value defined in DB // //------------------------------------------------------------------------------------------------------------------- #ifndef TANGO_HAS_LOG4TANGO ostream &operator<<(ostream &o_str,const Attr &c) { long nb_prop = c.class_properties.size(); for (long i = 0;i < nb_prop;i++) { o_str << c.class_properties[i]; if (i <= (nb_prop - 2)) o_str << endl; } return o_str; } #endif // TANGO_HAS_LOG4TANGO } // End of Tango namespace tango-9.2.5a/lib/cpp/server/command.cpp0000644023471100065110000006642013034745002014714 00000000000000static const char *RcsId = "$Id: command.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+============================================================================ // // file : Command.cpp // // description : C++ source code for the Command and templCommand classes. // The Command class is the root class for all derived // Command classes. The TemplCommand class is a template // command class use for command which does take input // nor outout parameters. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { //+------------------------------------------------------------------------- // // method : Command::Command // // description : constructors for abstract class Command // //-------------------------------------------------------------------------- Command::Command(const char *s, Tango::CmdArgType in, Tango::CmdArgType out) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = Tango::OPERATOR; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(string &s, Tango::CmdArgType in, Tango::CmdArgType out) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = Tango::OPERATOR; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(const char *s, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = Tango::OPERATOR; if (in_desc != NULL) in_type_desc = in_desc; if (out_desc != NULL) out_type_desc = out_desc; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(string &s, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc, string &out_desc) :name(s),in_type(in),out_type(out), in_type_desc(in_desc),out_type_desc(out_desc),ext(new CommandExt),poll_period(0) { cmd_disp_level = Tango::OPERATOR; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(const char *s, Tango::CmdArgType in, Tango::CmdArgType out, Tango::DispLevel level) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = level; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(string &s, Tango::CmdArgType in, Tango::CmdArgType out, Tango::DispLevel level) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = level; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(const char *s, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :name(s),in_type(in),out_type(out),ext(new CommandExt),poll_period(0) { cmd_disp_level = level; if (in_desc != NULL) in_type_desc = in_desc; if (out_desc != NULL) out_type_desc = out_desc; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } Command::Command(string &s, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc, string &out_desc, Tango::DispLevel level) :name(s),in_type(in),out_type(out), in_type_desc(in_desc),out_type_desc(out_desc),ext(new CommandExt),poll_period(0) { cmd_disp_level = level; lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); } //+---------------------------------------------------------------------------- // // method : Command::extract() // // description : Command extract methods. These are very simple methods // but overloaded many times for all Tango types. // //----------------------------------------------------------------------------- void Command::throw_bad_type(const char *type) { TangoSys_OMemStream o; o << "Incompatible command argument type, expected type is : Tango::" << type << ends; Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, o.str(), (const char *)"Command::extract()"); } void Command::extract(const CORBA::Any &in,Tango::DevBoolean &data) { if ((in >>= CORBA::Any::to_boolean(data)) == false) throw_bad_type("DevBoolean"); } void Command::extract(const CORBA::Any &in,Tango::DevShort &data) { if ((in >>= data) == false) throw_bad_type("DevShort"); } void Command::extract(const CORBA::Any &in,Tango::DevLong &data) { if ((in >>= data) == false) throw_bad_type("DevLong"); } void Command::extract(const CORBA::Any &in,Tango::DevLong64 &data) { if ((in >>= data) == false) throw_bad_type("DevLong64"); } void Command::extract(const CORBA::Any &in,Tango::DevFloat &data) { if ((in >>= data) == false) throw_bad_type("DevFloat"); } void Command::extract(const CORBA::Any &in,Tango::DevDouble &data) { if ((in >>= data) == false) throw_bad_type("DevDouble"); } void Command::extract(const CORBA::Any &in,Tango::DevUShort &data) { if ((in >>= data) == false) throw_bad_type("DevUShort"); } void Command::extract(const CORBA::Any &in,Tango::DevULong &data) { if ((in >>= data) == false) throw_bad_type("DevULong"); } void Command::extract(const CORBA::Any &in,Tango::DevULong64 &data) { if ((in >>= data) == false) throw_bad_type("DevULong64"); } void Command::extract(const CORBA::Any &in,Tango::DevString &data) { if ((in >>= const_cast(data)) == false) throw_bad_type("DevString"); } void Command::extract(const CORBA::Any &in,const char *&data) { if ((in >>= data) == false) throw_bad_type("ConstDevString"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarCharArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarCharArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarShortArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarShortArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarLongArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarLongArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarLong64Array *&data) { if ((in >>= data) == false) throw_bad_type("DevVarLong64Array"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarFloatArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarFloatArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarDoubleArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarDoubleArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarUShortArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarUShortArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarULongArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarULongArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarULong64Array *&data) { if ((in >>= data) == false) throw_bad_type("DevVarULong64Array"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarStringArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarStringArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarLongStringArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarLongStringArray"); } void Command::extract(const CORBA::Any &in,const Tango::DevVarDoubleStringArray *&data) { if ((in >>= data) == false) throw_bad_type("DevVarDoubleStringArray"); } void Command::extract(const CORBA::Any &in,Tango::DevState &data) { if ((in >>= data) == false) throw_bad_type("DevState"); } void Command::extract(const CORBA::Any &in,const Tango::DevEncoded *&data) { if ((in >>= data) == false) throw_bad_type("DevEncoded"); } //+---------------------------------------------------------------------------- // // method : Command::insert() // // description : Command insert methods. These are very simple methods // but overloaded many times for all Tango types. // //----------------------------------------------------------------------------- void Command::alloc_any(CORBA::Any *&any_ptr) { try { any_ptr = new CORBA::Any(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Command::alloc_any()"); } } CORBA::Any *Command::insert() { CORBA::Any *out_any; alloc_any(out_any); return out_any; } CORBA::Any *Command::insert(Tango::DevBoolean data) { CORBA::Any *out_any; alloc_any(out_any); CORBA::Any::from_boolean tmp(data); (*out_any) <<= tmp; return out_any; } CORBA::Any *Command::insert(Tango::DevShort data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevLong data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevLong64 data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevFloat data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevDouble data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevUShort data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevULong data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevULong64 data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevString data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; delete [] data; return out_any; } CORBA::Any *Command::insert(const char *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarCharArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarCharArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarShortArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarShortArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLongArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLongArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLong64Array &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLong64Array *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarFloatArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarFloatArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarDoubleArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarDoubleArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarUShortArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarUShortArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarULongArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarULongArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarULong64Array &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarULong64Array *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarStringArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarStringArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLongStringArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarLongStringArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarDoubleStringArray *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } CORBA::Any *Command::insert(Tango::DevVarDoubleStringArray &data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevState data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= data; return out_any; } CORBA::Any *Command::insert(Tango::DevEncoded *data) { CORBA::Any *out_any; alloc_any(out_any); (*out_any) <<= (*data); delete data; return out_any; } //+------------------------------------------------------------------------- // // method : TempCommand class constructors // // description : instance constructor // //-------------------------------------------------------------------------- TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)()) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &)) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)()) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &)) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),const char *in_desc,const char *out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),string &in_desc,string &out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),const char *in_desc,const char *out_desc,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),const char *in_desc,const char *out_desc,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),bool (DeviceImpl::*a)(const CORBA::Any &),string &in_desc,string &out_desc,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level),exe_ptr(f),ext(Tango_nullptr),allowed_ptr(a) { } TemplCommand::TemplCommand(string &s,void (DeviceImpl::*f)(),string &in_desc,string &out_desc,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level),exe_ptr(f),ext(Tango_nullptr) { allowed_ptr = NULL; } TemplCommand::TemplCommand(const char *s) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID) { } TemplCommand::TemplCommand(string &s) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID) { } TemplCommand::TemplCommand(const char *s,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level) { } TemplCommand::TemplCommand(string &s,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,level) { } TemplCommand::TemplCommand(const char *s,const char *in_desc,const char *out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc) { } TemplCommand::TemplCommand(string &s,string &in_desc,string &out_desc) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc) { } TemplCommand::TemplCommand(const char *s,const char *in_desc,const char *out_desc,Tango::DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level) { } TemplCommand::TemplCommand(string &s,string &in_desc,string &out_desc,DispLevel level) :Command(s,Tango::DEV_VOID,Tango::DEV_VOID,in_desc,out_desc,level) { } //+------------------------------------------------------------------------- // // method : set_type // // description : Set the Command class type data according to the type // of the object passed as parameters // // input : - data_type : reference to the type_info object of the parameter // - type : reference to the Command class type data // //-------------------------------------------------------------------------- void TemplCommand::set_type(const type_info &data_type,Tango::CmdArgType &type) { if (data_type == typeid(void)) { cout4 << "Command : " << name << ", Type is void" << endl; type = Tango::DEV_VOID; } else if (data_type == typeid(Tango::DevBoolean)) { cout4 << "Command : " << name << ", Type is a boolean" << endl; type = Tango::DEV_BOOLEAN; } else if (data_type == typeid(Tango::DevShort)) { cout4 << "Command : " << name << ", Type is a short" << endl; type = Tango::DEV_SHORT; } else if (data_type == typeid(Tango::DevLong)) { cout4 << "Command : " << name << ", Type is a long" << endl; type = Tango::DEV_LONG; } else if (data_type == typeid(Tango::DevLong64)) { cout4 << "Command : " << name << ", Type is a long64" << endl; type = Tango::DEV_LONG64; } else if (data_type == typeid(Tango::DevFloat)) { cout4 << "Command : " << name << ", Type is a float" << endl; type = Tango::DEV_FLOAT; } else if (data_type == typeid(Tango::DevDouble)) { cout4 << "Command : " << name << ", Type is a double" << endl; type = Tango::DEV_DOUBLE; } else if (data_type == typeid(Tango::DevUShort)) { cout4 << "Command : " << name << ", Type is an unsigned short" << endl; type = Tango::DEV_USHORT; } else if (data_type == typeid(Tango::DevULong)) { cout4 << "Command : " << name << ", Type is an unsigned long" << endl; type = Tango::DEV_ULONG; } else if (data_type == typeid(Tango::DevULong64)) { cout4 << "Command : " << name << ", Type is an unsigned long64" << endl; type = Tango::DEV_ULONG64; } else if (data_type == typeid(Tango::DevString)) { cout4 << "Command : " << name << ", Type is a string" << endl; type = Tango::DEV_STRING; } else if ((data_type == typeid(Tango::DevVarCharArray)) || (data_type == typeid(const Tango::DevVarCharArray *)) || (data_type == typeid(Tango::DevVarCharArray *))) { cout4 << "Command : " << name << ", Type is a char array" << endl; type = Tango::DEVVAR_CHARARRAY; } else if ((data_type == typeid(Tango::DevVarShortArray)) || (data_type == typeid(const Tango::DevVarShortArray *)) || (data_type == typeid(Tango::DevVarShortArray *))) { cout4 << "Command : " << name << ", Type is a short array" << endl; type = Tango::DEVVAR_SHORTARRAY; } else if ((data_type == typeid(Tango::DevVarLongArray)) || (data_type == typeid(const Tango::DevVarLongArray *)) || (data_type == typeid(Tango::DevVarLongArray *))) { cout4 << "Command : " << name << ", Type is a long array" << endl; type = Tango::DEVVAR_LONGARRAY; } else if ((data_type == typeid(Tango::DevVarLong64Array)) || (data_type == typeid(const Tango::DevVarLong64Array *)) || (data_type == typeid(Tango::DevVarLong64Array *))) { cout4 << "Command : " << name << ", Type is a long64 array" << endl; type = Tango::DEVVAR_LONG64ARRAY; } else if ((data_type == typeid(Tango::DevVarFloatArray)) || (data_type == typeid(const Tango::DevVarFloatArray *)) || (data_type == typeid(Tango::DevVarFloatArray *))) { cout4 << "Command : " << name << ", Type is a float array" << endl; type = Tango::DEVVAR_FLOATARRAY; } else if ((data_type == typeid(Tango::DevVarDoubleArray)) || (data_type == typeid(const Tango::DevVarDoubleArray *)) || (data_type == typeid(Tango::DevVarDoubleArray *))) { cout4 << "Command : " << name << ", Type is a double array" << endl; type = Tango::DEVVAR_DOUBLEARRAY; } else if ((data_type == typeid(Tango::DevVarUShortArray)) || (data_type == typeid(const Tango::DevVarUShortArray *)) || (data_type == typeid(Tango::DevVarUShortArray *))) { cout4 << "Command : " << name << ", Type is a unsigned short array" << endl; type = Tango::DEVVAR_USHORTARRAY; } else if ((data_type == typeid(Tango::DevVarULongArray)) || (data_type == typeid(const Tango::DevVarULongArray *)) || (data_type == typeid(Tango::DevVarULongArray *))) { cout4 << "Command : " << name << ", Type is a unsigned long array" << endl; type = Tango::DEVVAR_ULONGARRAY; } else if ((data_type == typeid(Tango::DevVarULong64Array)) || (data_type == typeid(const Tango::DevVarULong64Array *)) || (data_type == typeid(Tango::DevVarULong64Array *))) { cout4 << "Command : " << name << ", Type is a unsigned long64 array" << endl; type = Tango::DEVVAR_ULONG64ARRAY; } else if ((data_type == typeid(Tango::DevVarStringArray)) || (data_type == typeid(const Tango::DevVarStringArray *)) || (data_type == typeid(Tango::DevVarStringArray *))) { cout4 << "Command : " << name << ", Type is a string array" << endl; type = Tango::DEVVAR_STRINGARRAY; } else if ((data_type == typeid(Tango::DevVarLongStringArray)) || (data_type == typeid(const Tango::DevVarLongStringArray *)) || (data_type == typeid(Tango::DevVarLongStringArray *))) { cout4 << "Command : " << name << ", Type is a long + string array" << endl; type = Tango::DEVVAR_LONGSTRINGARRAY; } else if ((data_type == typeid(Tango::DevVarDoubleStringArray)) || (data_type == typeid(const Tango::DevVarDoubleStringArray *)) || (data_type == typeid(Tango::DevVarDoubleStringArray *))) { cout4 << "Command : " << name << ", Type is a double + string array" << endl; type = Tango::DEVVAR_DOUBLESTRINGARRAY; } else if (data_type == typeid(Tango::DevState)) { cout4 << "Command : " << name << ", Type is a DevState" << endl; type = Tango::DEV_STATE; } else { cout4 << "Command : " << name << ", Unknown type" << endl; TangoSys_OMemStream o; o << "Command " << name << " defined with an unsupported type" << ends; Except::throw_exception((const char *)API_CmdArgumentTypeNotSupported, o.str(),(const char *)"TemplCommand::set_type"); } } //+------------------------------------------------------------------------- // // method : is_allowed // // description : Check if the command is allowed. If the pointer to // DeviceImpl class method "allowed_ptr" is null, the // default mode id used (command always executed). // Otherwise, the method is executed // // input : - dev_ptr : pointer to the device on which the command must be // executed // - in_any : Incoming command data // // This method returns a boolean set to true if the command is allowed // //-------------------------------------------------------------------------- bool TemplCommand::is_allowed(DeviceImpl *dev_ptr,const CORBA::Any &in_any) { if (allowed_ptr == NULL) return true; else return ((dev_ptr->*allowed_ptr)(in_any)); } //+------------------------------------------------------------------------- // // method : execute // // description : Execute the method associated with the command // (stored in the exe_ptr data) // // input : - dev_ptr : pointer to the device on which the command must be // executed // - in_any : Incoming command data // // This method returns a pointer to an CORBA::Any object with the command outing // data. // //-------------------------------------------------------------------------- CORBA::Any *TemplCommand::execute(DeviceImpl *dev_ptr,TANGO_UNUSED(const CORBA::Any &in_any)) { // // Execute the command associated method // (dev_ptr->*exe_ptr)(); return insert(); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/coutappender.cpp0000644023471100065110000000641313034745001015762 00000000000000static const char *RcsId = "$Id: coutappender.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : coutappender.cpp // // description : // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 3.6 2010/09/09 13:44:46 taurel // - Add year 2010 in Copyright notice // // Revision 3.5 2009/01/21 12:49:04 taurel // - Change CopyRights for 2009 // // Revision 3.4 2008/10/06 15:00:36 taurel // - Changed the licensing info from GPL to LGPL // // Revision 3.3 2008/10/03 06:51:36 taurel // - Add some licensing info in each files // // Revision 3.2 2007/04/20 14:40:28 taurel // - Ported to Windows 64 bits x64 architecture // // Revision 3.1 2003/05/28 14:55:08 taurel // Add the include (conditionally) of the include files generated by autoconf // // Revision 3.0 2003/03/25 16:41:57 taurel // Many changes for Tango release 3.0 including // - Added full logging features // - Added asynchronous calls // - Host name of clients now stored in black-box // - Three serialization model in DS // - Fix miscellaneous bugs // - Ported to gcc 3.2 // - Added ApiUtil::cleanup() and destructor methods // - Some internal cleanups // - Change the way how TangoMonitor class is implemented. It's a recursive // mutex // // Revision 2.2 2003/03/11 17:55:48 nleclercq // Switch from log4cpp to log4tango // // Revision 2.1 2003/02/17 14:57:39 taurel // Added the new Tango logging stuff (Thanks Nicolas from Soleil) // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #if defined(TANGO_HAS_LOG4TANGO) #include namespace Tango { CoutAppender::CoutAppender (const std::string& name) : log4tango::LayoutAppender(name) { //no-op ctor } CoutAppender::~CoutAppender () { //no-op dtor } int CoutAppender::_append (const log4tango::LoggingEvent& event) { #ifdef _TG_WINDOWS_ CoutBuf *dbg_win; try { dbg_win = Util::instance(false)->get_debug_object(); } catch (...) { dbg_win = 0; } if (dbg_win) dbg_win->dbg_out(get_layout().format(event).c_str()); else #endif ::printf("%s\n", get_layout().format(event).c_str()); return 0; } } // namespace tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/classpipe.cpp0000644023471100065110000001427113034745001015255 00000000000000 static const char *RcsId = "$Id: classpipe.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+================================================================================================================= // // file : ClassPipe.cpp // // description : C++ source code for the MultiClassPipe // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiClassPipe::MultiClassPipe // // description : // destructor for the MultiClassPipe class // //------------------------------------------------------------------------------------------------------------------- MultiClassPipe::~MultiClassPipe() { /* long nb_attr = attr_list.size(); for (int i = 0;i < nb_attr;i++) delete attr_list[i];*/ } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassPipe::MultiClassPipe // // description : // Constructor for the MultiClassPipe class // //-------------------------------------------------------------------------------------------------------------------- MultiClassPipe::MultiClassPipe() { cout4 << "Entering MultiClassPipe constructor" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassPipe::init_class_pipe // // description : // Ask the database for properties defined at class level and build the ClassPipe object for each pipe // with defined properties // // argument : // in : // - cl_ptr : The device class object pointer // //------------------------------------------------------------------------------------------------------------------- void MultiClassPipe::init_class_pipe(DeviceClass *cl_ptr) { cout4 << "Entering MultiClassPipe::init_class_pipe" << endl; Tango::Util *tg = Tango::Util::instance(); vector &pi_list = cl_ptr->get_pipe_list(); size_t nb_pipe = pi_list.size(); // // Get class attribute(s) properties stored in DB. No need to implement a retry here (in case of db server restart) // because the db reconnection is forced by the get_property call executed during xxxClass construction // before we reach this code. // if ((nb_pipe != 0) && (Tango::Util::_UseDb == true)) { size_t i; Tango::DbData db_list; string &class_name = cl_ptr->get_name(); size_t nb_db_requested_pipe = 0; // // Ask for class default prop in DB only for pipe with label or desc not already set to some user default value // for(i = 0;i < nb_pipe;i++) { Pipe *pi_ptr = pi_list[i]; string &pi_name = pi_ptr->get_name(); if (pi_ptr->get_label() == pi_name || pi_ptr->get_desc() == DescNotSpec) { db_list.push_back(DbDatum(pi_name)); nb_db_requested_pipe++; } } try { tg->get_database()->get_class_pipe_property(class_name,db_list,tg->get_db_cache()); } catch (Tango::DevFailed &e) { stringstream ss; ss << "Can't get class pipe properties for class " << class_name; Except::re_throw_exception(e,API_DatabaseAccess,ss.str(), "MultiClassPipe::init_class_pipe"); } // // Sort property for each pipe // long ind = 0; for (i = 0;i < nb_db_requested_pipe;i++) { vector prop_list; string pipe_name = db_list[ind].name; long nb_prop = 0; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + " "; tmp = tmp + db_list[ind].value_string[k]; } prop_list.push_back(PipeProperty(db_list[ind].name,tmp)); } else prop_list.push_back(PipeProperty(db_list[ind].name,db_list[ind].value_string[0])); ind++; } if (nb_prop != 0) { #ifdef INIT_LIST pipe_prop_list.insert({pipe_name,prop_list}); #else pipe_prop_list.insert(make_pair(pipe_name,prop_list)); #endif } } } cout4 << "Leaving MultiClassPipe::init_class_pipe" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiClassPipe::get_prop_list // // description : // Get list of pipe property (defined at class level) for the pipe specified as input arg // // argument : // in : // - pipe_name : The pipe name // // return : // Reference to the vector of pipe properties or throw an exception if the pipe is not found // //-------------------------------------------------------------------------------------------------------------------- vector &MultiClassPipe::get_prop_list(const string &pipe_name) { map >::iterator ite; ite = pipe_prop_list.find(pipe_name); if (ite == pipe_prop_list.end()) { stringstream ss; ss << "Pipe " << pipe_name << " not found in class pipe(s) properties" << ends; Except::throw_exception(API_PipeNotFound,ss.str(),"MultiClassPipe::get_prop_list"); } return ite->second; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dev_event.cpp0000644023471100065110000022220713034745001015251 00000000000000static const char *RcsId = "$Id: dev_event.cpp 28932 2015-12-16 11:51:47Z taurel $\n$Name$"; //+================================================================================================================== // // file : dev_event.cpp // // description : C++ source code for the DeviceImpl class methods related to manually firing events. // // project : TANGO // // author(s) : J.Meyer + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28932 $ // //-================================================================================================================= #if HAVE_CONFIG_H #include #endif #include #include #ifdef _TG_WINDOWS_ #include #else #include #endif #ifdef TANGO_HAS_LOG4TANGO #include #endif namespace Tango { //////////////////// Push user event methods!!! ////////////////////////////////////// //+---------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_event // // description : // Push a user event to the Notification service. Should be used to push user events for the state and status // attributes as well as pushing an exception as change event. // // args : // in : // - attr_name : name of the attribute // - filt_names : The filterable fields name // - filt_vals : The filterable fields value (as double) // - except : Tango exception to be pushed as a user event for the attribute. // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_event(string attr_name, vector &filt_names,vector &filt_vals,DevFailed *except) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // push the event attr.fire_event (filt_names,filt_vals,except); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_event // // description : // Push an attribute change event with valid data to the notification service // // args : // in : // - attr_name : name of the attribute // - filt_names : The filterable fields name // - filt_vals : The filterable fields value (as double) // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be freed after being send to the // client. Default value is false. // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevShort *p_data, long x,long y ,bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevFloat *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevDouble *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevBoolean *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUShort *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event(string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUChar *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevState *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevEncoded *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_str, Tango::DevUChar *p_data, long size , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_str,p_data, size, release); // push the event attr.fire_event(filt_names,filt_vals); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_event // // description : // Push an attribute change event with data, time stamp and a quality factor to the notification service. // // args : // in : // - attr_name : name of the attribute // - filt_names : The filterable fields name // - filt_vals : The filterable fields value (as double) // - t : the time stamp // - qual : the attribute quality factor // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be freed after being send to the // client. Default value is false. // //---------------------------------------------------------------------------------------------------------------- #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevShort *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevShort *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong64 *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevLong64 *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevFloat *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevFloat *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevDouble *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevDouble *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevBoolean *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevBoolean *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUShort *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUShort *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUChar *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevUChar *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong64 *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevULong64 *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevState *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevState *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevEncoded *p_data,struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevEncoded *p_data,struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_event(filt_names,filt_vals); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_str_data,Tango::DevUChar *p_data,long size, struct _timeb &t, Tango::AttrQuality qual, bool release) #else void DeviceImpl::push_event (string attr_name,vector &filt_names,vector &filt_vals, Tango::DevString *p_str_data,Tango::DevUChar *p_data,long size, struct timeval &t, Tango::AttrQuality qual, bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_str_data,p_data, size,t, qual, release); // push the event attr.fire_event(filt_names,filt_vals); } //////////////////// Push change event methods!!! ////////////////////////////////////// //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::set_change_event // // description : // Set a flag to indicate that the server pushes change events manually, without the polling to be started for // the attribute. If the detect parameter is set to true, the criteria specified for the change event are // verified and the event is only pushed if they are fulfilled. If detect is set to false the event is fired // without any value checking! // // args : // in : // - implemented : True when the server fires change events manually. // - detect : Triggers the verification of the change event properties when set to true. // //----------------------------------------------------------------------------------------------------------------- void DeviceImpl::set_change_event (string attr_name, bool implemented, bool detect) { // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); attr.set_change_event (implemented, detect); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_change_event // // description : // Push an attribute change event to the Notification service. Should be used to push change events for the // state and status attributes as well as pushing an exception as change event. // // args : // in : // - attr_name : name of the attribute // - except : Tango exception to be pushed as a change event for the attribute. // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_change_event(string attr_name, DevFailed *except) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // push the event attr.fire_change_event (except); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_change_event // // description : // Push an attribute change event with valid data to the notification service // // args: // in : // - attr_name : name of the attribute // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be // freed after being send to the client. Default value is false. // //----------------------------------------------------------------------------------------------------------------- void DeviceImpl::push_change_event (string attr_name, Tango::DevShort *p_data, long x,long y ,bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevLong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevLong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevFloat *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevDouble *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevString *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevBoolean *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevUShort *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event(string attr_name, Tango::DevUChar *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevULong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevULong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevState *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevEncoded *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_change_event(); } void DeviceImpl::push_change_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_str_data, p_data, size, release); // push the event attr.fire_change_event(); } //+---------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_change_event // // description : // Push an attribute change event with data, time stamp and a quality factor to the notification service. // // args: // in : // - attr_name : name of the attribute // - t : the time stamp // - qual : the attribute quality factor // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be // freed after being send to the client. Default value is false. // //----------------------------------------------------------------------------------------------------------------- #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_change_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_change_event (string attr_name, Tango::DevString *p_str_data,Tango::DevUChar *p_data,long size, struct _timeb &t, Tango::AttrQuality qual, bool release) #else void DeviceImpl::push_change_event (string attr_name, Tango::DevString *p_str_data,Tango::DevUChar *p_data,long size, struct timeval &t, Tango::AttrQuality qual, bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_str_data,p_data, size, t, qual, release); // push the event attr.fire_change_event(); } //////////////////// Push change archive methods!!! ////////////////////////////////////// //+--------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::set_archive_event // // description : // Set a flag to indicate that the server pushes archive events manually, without the polling to be started // for the attribute. If the detect parameter is set to true, the criteria specified for the archive // event are verified and the event is only pushed if they are fulfilled. If detect is set to false the event // is fired without any value checking! // // args : // in : // - implemented : True when the server fires archive events manually. // - detect : Triggers the verification of the archive event properties when set to true. // //---------------------------------------------------------------------------------------------------------------- void DeviceImpl::set_archive_event (string attr_name, bool implemented, bool detect) { // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); attr.set_archive_event (implemented, detect); } //+---------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_archive_event // // description : // Push an attribute archive event to the Notification service. Should be used to push archive events for the // state and status attributes as well as pushing an exception as archive event. // // args : // in : // - attr_name : name of the attribute // - except : Tango exception to be pushed as a archive event for the attribute. // //----------------------------------------------------------------------------------------------------------------- void DeviceImpl::push_archive_event(string attr_name, DevFailed *except) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // push the event attr.fire_archive_event (except); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::push_archive_event // // description : // Push an attribute archive event with valid data to the notification service // // args : // in : // - attr_name : name of the attribute // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be // freed after being send to the client. Default value is false. // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_archive_event (string attr_name, Tango::DevShort *p_data, long x,long y ,bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevFloat *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevDouble *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevString *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevBoolean *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevUShort *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event(string attr_name, Tango::DevUChar *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong64 *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevState *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevEncoded *p_data, long x, long y , bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_data, x, y, release); // push the event attr.fire_archive_event(); } void DeviceImpl::push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data, long size, bool release) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value (p_str_data,p_data, size, release); // push the event attr.fire_archive_event(); } //+--------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_archive_event // // description : // Push an attribute archive event with data, time stamp and a quality factor to the notification service. // // args : // in : // - attr_name : name of the attribute // - t : the time stamp // - qual : the attribute quality factor // - p_data : pointer to attribute data // - x : The attribute x length. Default value is 1 // - y : The attribute y length. Default value is 0 // - release : The release flag. If true, memory pointed to by p_data will be // freed after being send to the client. Default value is false. // //----------------------------------------------------------------------------------------------------------------- #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevLong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevFloat *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevFloat *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevDouble *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevDouble *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevString *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevString *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevBoolean *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevBoolean *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevUShort *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevUShort *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevUChar *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevUChar *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong64 *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevULong64 *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevState *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevState *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevEncoded *p_data, struct _timeb &t, Tango::AttrQuality qual, long x,long y ,bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevEncoded *p_data, struct timeval &t, Tango::AttrQuality qual, long x,long y ,bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_data, t, qual, x, y, release); // push the event attr.fire_archive_event(); } #ifdef _TG_WINDOWS_ void DeviceImpl::push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data,long size, struct _timeb &t, Tango::AttrQuality qual, bool release) #else void DeviceImpl::push_archive_event (string attr_name, Tango::DevString *p_str_data, Tango::DevUChar *p_data,long size, struct timeval &t, Tango::AttrQuality qual, bool release) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // set the attribute value attr.set_value_date_quality (p_str_data, p_data, size, t, qual, release); // push the event attr.fire_archive_event(); } //+--------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::set_data_ready_event // // description : // Set a flag to indicate that the server pushes data ready events. // // args : // in : // - attr_name : The attribute name // - implemented : True when the server fires change events manually. // //---------------------------------------------------------------------------------------------------------------- void DeviceImpl::set_data_ready_event (string attr_name, bool implemented) { // search the attribute from the attribute list Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); attr.set_data_ready_event (implemented); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_data_ready_event // // description : // Push an attribute data ready event // // args: // in : // - attr_name : name of the attribute // - ctr : user counter (optional) // //---------------------------------------------------------------------------------------------------------------- void DeviceImpl::push_data_ready_event (const string &attr_name, Tango::DevLong ctr) { Tango::Util *tg = Tango::Util::instance(); // get the tango synchronisation monitor Tango::AutoTangoMonitor synch(this); // search the attribute from the attribute list to check that it exist Tango::MultiAttribute *attr_list = get_device_attr(); Tango::Attribute &attr = attr_list->get_attr_by_name (attr_name.c_str()); // // Get event suppliers // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; if (attr.use_notifd_event() == true) event_supplier_nd = tg->get_notifd_event_supplier(); if (attr.use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); if ((event_supplier_nd == NULL) && (event_supplier_zmq == NULL)) return; // // Push the event // if (event_supplier_nd != NULL) { event_supplier_nd->push_att_data_ready_event(this,attr_name,attr.get_data_type(),ctr); } if (event_supplier_zmq != NULL) { event_supplier_zmq->push_att_data_ready_event(this,attr_name,attr.get_data_type(),ctr); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_pipe_event // // description : // Push a pipe event. // // args : // in : // - pipe_name : name of the pipe // - except : Tango exception to be pushed as event for the pipe. // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_pipe_event(const string &pipe_name, DevFailed *except) { // get the tango synchronisation monitor Tango::AutoTangoMonitor synch(this); // search the pipe from the attribute list Tango::Pipe &pi = get_device_class()->get_pipe_by_name(pipe_name,device_name_lower); // push the event pi.fire_event(this,except); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_pipe_event // // description : // Push a pipe event with data // // args: // in : // - pipe_name : name of the pipe // - p_data : pointer to pipe data // //----------------------------------------------------------------------------------------------------------------- void DeviceImpl::push_pipe_event (const string &pipe_name,Tango::DevicePipeBlob *p_data,bool reuse_it) { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the pipe from the pipe list Tango::Pipe &pi = get_device_class()->get_pipe_by_name(pipe_name,device_name_lower); // push the event pi.fire_event(this,p_data,reuse_it); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_pipe_event // // description : // Push a pipe event with data and timestamp // // args: // in : // - pipe_name : name of the pipe // - p_data : pointer to pipe data // - t : timestamp // //----------------------------------------------------------------------------------------------------------------- #ifdef _TG_WINDOWS_ void DeviceImpl::push_pipe_event (const string &pipe_name, Tango::DevicePipeBlob *p_data,struct _timeb &t,bool reuse_it) #else void DeviceImpl::push_pipe_event (const string &pipe_name, Tango::DevicePipeBlob *p_data,struct timeval &tv,bool reuse_it) #endif { // get the tango synchroisation monitor Tango::AutoTangoMonitor synch(this); // search the pipe from the pipe list Tango::Pipe &pi = get_device_class()->get_pipe_by_name (pipe_name,device_name_lower); #ifdef _TG_WINDOWS_ struct timeval tv; tv.tv_sec = (unsigned long)t.time; tv.tv_usec = (long)t.millitm * 1000; #endif // _TG_WINDOWS_ // push the event pi.fire_event(this,p_data,tv,reuse_it); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dev_poll.cpp0000644023471100065110000004615613034745001015105 00000000000000static const char *RcsId = "$Id$"; //+=================================================================================================================== // // file : dev_poll.cpp // // description : C++ source code for part of the DeviceImpl class. This class is the root class for all derived // Device classes. Tis file contains some polling related methods. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::init_poll_no_db // // description : // Init polling info for device running without DB. In such a case, polling is available only for // object with polling defined in code. Fill in string vectors which are in case of DS using // database initialised from the db. // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::init_poll_no_db() { bool old_set = false; // // A loop for all device attribute // vector &att_list = dev_attr->get_attribute_list(); vector::iterator ite; for (ite = att_list.begin();ite != att_list.end();++ite) { long poll_period = (*ite)->get_polling_period(); if (poll_period != 0) { vector &polled_attr_list = get_polled_attr(); polled_attr_list.push_back((*ite)->get_name()); stringstream ss; ss << poll_period; polled_attr_list.push_back(ss.str()); if (old_set == false) { set_poll_old_factor(DEFAULT_POLL_OLD_FACTOR); old_set = true; } } } // // A loop for all device commands // vector &cmd_list = device_class->get_command_list(); vector::iterator ite_cmd; for (ite_cmd = cmd_list.begin();ite_cmd != cmd_list.end();++ite_cmd) { long poll_period = (*ite_cmd)->get_polling_period(); if (poll_period != 0) { vector &polled_cmd_list = get_polled_cmd(); polled_cmd_list.push_back((*ite_cmd)->get_name()); stringstream ss; ss << poll_period; polled_cmd_list.push_back(ss.str()); if (old_set == false) { set_poll_old_factor(DEFAULT_POLL_OLD_FACTOR); old_set = true; } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::is_attribute_polled // // description : // Returns true if the attribute is polled // // argument: // in : // - att_name : The attribute name // //------------------------------------------------------------------------------------------------------------------- bool DeviceImpl::is_attribute_polled(const string &att_name) { string att = att_name; transform(att.begin(),att.end(),att.begin(),::tolower); vector &att_list = get_polled_attr(); for (unsigned int i = 0;i < att_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(att_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( att == name_lowercase ) { // // when the polling buffer is externally filled (polling period == 0) // mark the attribute as not polled! No events can be send by the polling thread! // if ( att_list[i+1] == "0" ) { return false; } else return true; } } // // now check wether a polling period is set (for example by pogo) // /* Tango::Attribute &the_att = dev_attr->get_attr_by_name(att_name.c_str()); if ( the_att.get_polling_period() > 0 ) { // // check the list of non_auto_polled attributes to verify wether the polling was disabled // vector &napa = get_non_auto_polled_attr(); for (unsigned int j = 0;j < napa.size();j++) { #ifdef _TG_WINDOWS_ if (_stricmp(napa[j].c_str(), att_name.c_str()) == 0) #else if (strcasecmp(napa[j].c_str(), att_name.c_str()) == 0) #endif { return false; } } return true; }*/ return false; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::is_command_polled // // description : // Returns true if the command is polled // // argument: // in : // - cmd_name : The command name // //------------------------------------------------------------------------------------------------------------------- bool DeviceImpl::is_command_polled(const string &cmd_name) { string cmd = cmd_name; transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); vector &cmd_list = get_polled_cmd(); for (unsigned int i = 0;i < cmd_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(cmd_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( cmd == name_lowercase ) { // // when the polling buffer is externally filled (polling period == 0) // mark the attribute as not polled! No events can be send by the polling thread! // if ( cmd_list[i+1] == "0" ) { return false; } else return true; } } // // now check wether a polling period is set (for example by pogo) // /* Tango::Command &the_cmd = device_class->get_cmd_by_name(cmd_name); if ( the_cmd.get_polling_period() > 0 ) { // // check the list of non_auto_polled attributes to verify wether the polling was disabled // vector &napa = get_non_auto_polled_cmd(); for (unsigned int j = 0;j < napa.size();j++) { #ifdef _TG_WINDOWS_ if (_stricmp(napa[j].c_str(), cmd_name.c_str()) == 0) #else if (strcasecmp(napa[j].c_str(), cmd_name.c_str()) == 0) #endif { return false; } } return true; }*/ return false; } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_attribute_poll_period // // description : // Get the attribute polling period in mS (O if not polled) // // argument: // in : // - att_name : The attribute name // //-------------------------------------------------------------------------------------------------------------------- int DeviceImpl::get_attribute_poll_period(const string &att_name) { int per = 0; string att = att_name; transform(att.begin(),att.end(),att.begin(),::tolower); bool found = false; vector &att_list = get_polled_attr(); for (unsigned int i = 0;i < att_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(att_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( att == name_lowercase ) { stringstream ss; ss << att_list[i + 1]; ss >> per; found = true; break; } } // // now check wether a polling period is set (for example by pogo) // if (found == false) { Tango::Attribute &the_att = dev_attr->get_attr_by_name(att_name.c_str()); per = the_att.get_polling_period(); } return per; } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_command_poll_period // // description : // Get the command polling period in mS (0 if not polled) // // argument: // in : // - cmd_name : The command name // //-------------------------------------------------------------------------------------------------------------------- int DeviceImpl::get_command_poll_period(const string &cmd_name) { int per = 0; string cmd = cmd_name; transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); bool found = false; vector &cmd_list = get_polled_cmd(); for (unsigned int i = 0;i < cmd_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(cmd_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( cmd == name_lowercase ) { stringstream ss; ss << cmd_list[i + 1]; ss >> per; found = true; break; } } // // now check wether a polling period is set (for example by pogo) // if (found == false) { Tango::Command &the_cmd = device_class->get_cmd_by_name(cmd_name); per = the_cmd.get_polling_period(); } return per; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::poll_attribute // // description : // Poll one attribute. If the attribute is already polled, update its polling period to the new value // // argument: // in : // - att_name : The attribute name // - period : The polling period // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::poll_attribute(const string &att_name,int period) { poll_object(att_name,period,POLL_ATTR); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::poll_command // // description : // Poll one command. If the command is already polled, update its polling period to the new value // // argument: // in : // - cmd_name : The command name // - period : The polling period // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::poll_command(const string &cmd_name,int period) { poll_object(cmd_name,period,POLL_CMD); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::poll_object // // description : // Poll one object. If the object is already polled, update its polling period to the new value // // argument: // in : // - cmd_name : The object name // - period : The polling period // - type : Command or attribute // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::poll_object(const string &obj_name,int period,PollObjType type) { Tango::Util *tg = Tango::Util::instance(); if (tg->is_svr_shutting_down() == true) { Except::throw_exception((const char *)API_NotSupported, (const char *)"It's not supported to start polling on any device cmd/attr while the device is shutting down", (const char *)"DeviceImpl::poll_object"); } if (tg->is_svr_starting() == true) { // // If server is starting, we rely on the Util::polling_configure method to effectively start the polling // Nevertheless, some tests are coded before doing the job // if (period < MIN_POLL_PERIOD) { TangoSys_OMemStream o; o << period << " is below the min authorized period (" << MIN_POLL_PERIOD << " mS)" << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"DeviceImpl::poll_object"); } // // Just to be sure that the command/attribute exist. Also init ptr to the command/attribute polled list // vector *poll_obj; if (type == POLL_CMD) { device_class->get_cmd_by_name(obj_name); vector &po = get_polled_cmd(); poll_obj = &po; } else { dev_attr->get_attr_by_name(obj_name.c_str()); vector &po = get_polled_attr(); poll_obj = &po; } // // Check if the command is not already in the polled command // If yes, only update polling period in vector. Otherwise, add cmd name and polling period in vector // // Util::polling_configure will ask dserver polling command to store info in db only if polling period is negative. // bool found = false; string obj_name_lower(obj_name); transform(obj_name_lower.begin(),obj_name_lower.end(),obj_name_lower.begin(),::tolower); for (unsigned int i = 0;i < poll_obj->size();i = i + 2) { string tmp_name((*poll_obj)[i]); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == obj_name_lower) { found = true; stringstream ss; string period_str; ss << period; ss >> period_str; if (ss) (*poll_obj)[i + 1] = period_str; } } if (found == false) { stringstream ss; ss << -period; if (ss) { poll_obj->push_back(obj_name); poll_obj->push_back(ss.str()); } } } else { // // Ask the admin device to do the work (simulating the classical way to tune polling) // If the attribute is already polled, it's an update polling period. Otherwise, it's a add object polling command // DServer *ds = tg->get_dserver_device(); CORBA::Any the_any; DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); send->svalue[0] = CORBA::string_dup(get_name().c_str()); string obj_type; if (type == POLL_ATTR) obj_type = "attribute"; else obj_type = "command"; obj_type = obj_type + LOCAL_POLL_REQUEST; send->svalue[1] = CORBA::string_dup(obj_type.c_str()); send->svalue[2] = CORBA::string_dup(obj_name.c_str()); send->lvalue[0] = period; the_any <<= send; CORBA::Any *received_any = NULL; if (type == POLL_CMD) { if (is_command_polled(obj_name) == true) { if (get_command_poll_period(obj_name) != period) received_any = ds->command_inout("UpdObjPollingPeriod",the_any); } else received_any = ds->command_inout("AddObjPolling",the_any); } else { if (is_attribute_polled(obj_name) == true) { if (get_attribute_poll_period(obj_name) != period) received_any = ds->command_inout("UpdObjPollingPeriod",the_any); } else received_any = ds->command_inout("AddObjPolling",the_any); } delete received_any; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::stop_poll_attribute // // description : // Stop polling one attribute. Does nothing if the attribute is not polled // // argument: // in : // - att_name : The attribute name // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::stop_poll_attribute(const string &att_name) { stop_poll_object(att_name,POLL_ATTR); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::stop_poll_command // // description : // Stop polling one command. Does nothing if the command is not polled // // argument: // in : // - cmd_name : The command name // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::stop_poll_command(const string &cmd_name) { stop_poll_object(cmd_name,POLL_CMD); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::stop_poll_object // // description : // Stop polling one object. Does nothing if the object is not polled // // argument: // in : // - obj_name : The object name // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::stop_poll_object(const string &obj_name,PollObjType type) { Tango::Util *tg = Tango::Util::instance(); if (tg->is_svr_starting() == true) { // // Just to be sure that the attribute/command exist // vector *poll_obj; if (type == POLL_CMD) { device_class->get_cmd_by_name(obj_name); vector &po = get_polled_cmd(); poll_obj = &po; } else { dev_attr->get_attr_by_name(obj_name.c_str()); vector &po = get_polled_attr(); poll_obj = &po; } // // Remove object info in vector of polled attributes/commands // string obj_name_lower(obj_name); transform(obj_name_lower.begin(),obj_name_lower.end(),obj_name_lower.begin(),::tolower); vector::iterator ite; for (ite = poll_obj->begin();ite != poll_obj->end();ite = ite + 2) { string tmp_name(*ite); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == obj_name_lower) { ite = poll_obj->erase(ite,ite+2); if (ite == poll_obj->end()) break; else ite = ite - 2; } } } else { if (tg->is_device_restarting(device_name) == false) { // // Ask the admin device to do the work (simulating the classical way to tune polling) // DServer *ds = tg->get_dserver_device(); CORBA::Any the_any; DevVarStringArray *send = new DevVarStringArray(); send->length(3); (*send)[0] = CORBA::string_dup(get_name().c_str()); string str_type; if (type == POLL_CMD) str_type = "command"; else str_type = "attribute"; str_type = str_type + LOCAL_POLL_REQUEST; (*send)[1] = CORBA::string_dup(str_type.c_str()); (*send)[2] = CORBA::string_dup(obj_name.c_str()); the_any <<= send; CORBA::Any *received_any; received_any = ds->command_inout("RemObjPolling",the_any); delete received_any; } } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/device.cpp0000644023471100065110000050476313034745002014544 00000000000000static const char *RcsId = "$Id: device.cpp 29680 2016-04-27 13:57:50Z taurel $"; //+================================================================================================================== // // file : Device.cpp // // description : C++ source code for the DeviceImpl class. This class is the root class for all derived Device // classes. It is an abstract class. The DeviceImpl class is the CORBA servant which is "exported" // onto the network and accessed by the client. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29680 $ // //-================================================================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #ifdef TANGO_HAS_LOG4TANGO #include #endif namespace Tango { // // The per thread data storage key (The client identification is stored in thread specific storage) defined in utils.cpp // extern omni_thread::key_t key; //+------------------------------------------------------------------------- // // method : DeviceImpl::DeviceImpl // // description : constructors for the device_impl class from the class object // pointer, the device name, the description field, // the =aqmz and the status. // // argument : in : - cl_ptr : The class object pointer // - d_name : The device name // - de : The device description (default to "A TANGO device") // - st : The device state (default to UNKNOWN) // - sta : The device status (default to "Not initialised") // //-------------------------------------------------------------------------- DeviceImpl::DeviceImpl(DeviceClass *cl_ptr,const char *d_name, const char *de,Tango::DevState st,const char *sta) :device_name(d_name),desc(de),device_status(sta), device_state(st),device_class(cl_ptr),ext(new DeviceImplExt), #ifdef TANGO_HAS_LOG4TANGO logger(NULL),saved_log_level(log4tango::Level::WARN),rft(Tango::kDefaultRollingThreshold),poll_old_factor(0),idl_version(1), #endif exported(false),polled(false),poll_ring_depth(0),only_one(d_name), store_in_bb(true),poll_mon("cache"),att_conf_mon("att_config"), state_from_read(false),py_device(false),device_locked(false), locker_client(NULL),old_locker_client(NULL),lock_ctr(0), min_poll_period(0),run_att_conf_loop(true),force_alarm_state(false),with_fwd_att(false), event_intr_change_subscription(0),intr_change_ev(false),devintr_thread(Tango_nullptr) { real_ctor(); } DeviceImpl::DeviceImpl(DeviceClass *cl_ptr,string &d_name,string &de, Tango::DevState st,string &sta) :device_name(d_name),desc(de),device_status(sta), device_state(st),device_class(cl_ptr),ext(new DeviceImplExt), #ifdef TANGO_HAS_LOG4TANGO logger(NULL),saved_log_level(log4tango::Level::WARN),rft(Tango::kDefaultRollingThreshold),poll_old_factor(0),idl_version(1), #endif exported(false),polled(false),poll_ring_depth(0),only_one(d_name.c_str()), store_in_bb(true),poll_mon("cache"),att_conf_mon("att_config"), state_from_read(false),py_device(false),device_locked(false), locker_client(NULL),old_locker_client(NULL),lock_ctr(0), min_poll_period(0),run_att_conf_loop(true),force_alarm_state(false),with_fwd_att(false), event_intr_change_subscription(0),intr_change_ev(false),devintr_thread(Tango_nullptr) { real_ctor(); } DeviceImpl::DeviceImpl(DeviceClass *cl_ptr,string &d_name) :device_name(d_name),device_class(cl_ptr),ext(new DeviceImplExt), #ifdef TANGO_HAS_LOG4TANGO logger(NULL),saved_log_level(log4tango::Level::WARN),rft(Tango::kDefaultRollingThreshold),poll_old_factor(0),idl_version(1), #endif exported(false),polled(false),poll_ring_depth(0),only_one(d_name.c_str()), store_in_bb(true),poll_mon("cache"),att_conf_mon("att_config"), state_from_read(false),py_device(false),device_locked(false), locker_client(NULL),old_locker_client(NULL),lock_ctr(0), min_poll_period(0),run_att_conf_loop(true),force_alarm_state(false),with_fwd_att(false), event_intr_change_subscription(0),intr_change_ev(false),devintr_thread(Tango_nullptr) { desc = "A Tango device"; device_state = Tango::UNKNOWN; device_status = StatusNotSet; real_ctor(); } DeviceImpl::DeviceImpl(DeviceClass *cl_ptr,string &d_name,string &description) :device_name(d_name),device_class(cl_ptr),ext(new DeviceImplExt), #ifdef TANGO_HAS_LOG4TANGO logger(NULL),saved_log_level(log4tango::Level::WARN),rft(Tango::kDefaultRollingThreshold),poll_old_factor(0),idl_version(1), #endif exported(false),polled(false),poll_ring_depth(0),only_one(d_name.c_str()), store_in_bb(true),poll_mon("cache"),att_conf_mon("att_config"), state_from_read(false),py_device(false),device_locked(false), locker_client(NULL),old_locker_client(NULL),lock_ctr(0), min_poll_period(0),run_att_conf_loop(true),force_alarm_state(false),with_fwd_att(false), event_intr_change_subscription(0),intr_change_ev(false),devintr_thread(Tango_nullptr) { desc = description; device_state = Tango::UNKNOWN; device_status = StatusNotSet; real_ctor(); } void DeviceImpl::real_ctor() { version = DevVersion; blackbox_depth = 0; device_prev_state = device_state; // // Init lower case device name // device_name_lower = device_name; transform(device_name_lower.begin(),device_name_lower.end(), device_name_lower.begin(),::tolower); // // Write the device name into the per thread data for sub device diagnostics // Tango::Util *tg = Tango::Util::instance(); tg->get_sub_dev_diag().set_associated_device(device_name_lower); // // Create the DbDevice object // try { db_dev = new DbDevice(device_name,Tango::Util::instance()->get_database()); } catch (Tango::DevFailed &) { throw; } get_dev_system_resource(); black_box_create(); idl_version = 1; devintr_shared.th_running = false; // // Create the multi attribute object // dev_attr = new MultiAttribute(device_name,device_class,this); // // Create device pipe and finish the pipe config init since we now have device name // device_class->create_device_pipe(device_class,this); end_pipe_config(); // // Build adm device name // adm_device_name = "dserver/"; adm_device_name = adm_device_name + Util::instance()->get_ds_name(); // // Init logging // #ifdef TANGO_HAS_LOG4TANGO init_logger(); #endif } //+------------------------------------------------------------------------- // // method : DeviceImpl::stop_polling // // description : Stop all polling for a device. if the device is // polled, call this method before deleting it. // // argin(s) : - with_db_upd : Is it necessary to update db ? // //-------------------------------------------------------------------------- void DeviceImpl::stop_polling(bool with_db_upd) { Tango::Util *tg = Tango::Util::instance(); // // If the vector of polling info is empty, no need to do anything (polling // already stopped for all devices) // vector &v_th_info = tg->get_polling_threads_info(); if (v_th_info.empty() == true) return; // // Find out which thread is in charge of the device. // PollingThreadInfo *th_info; int poll_th_id = tg->get_polling_thread_id_by_name(device_name.c_str()); if (poll_th_id == 0) { TangoSys_OMemStream o; o << "Can't find a polling thread for device " << device_name << ends; Except::throw_exception((const char *)API_PollingThreadNotFound,o.str(), (const char *)"DeviImpl::stop_polling"); } th_info = tg->get_polling_thread_info_by_id(poll_th_id); TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_REM_DEV; shared_cmd.dev = this; mon.signal(); // // Wait for thread to execute command // while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Polling thread blocked !!", (const char *)"DeviceImpl::stop_polling"); } } } is_polled(false); // // Update the pool conf first locally. // Also update the map // If this device was the only one for a polling thread, kill the thread // Then in Db if possible // bool kill_thread = false; int ind; if ((ind = tg->get_dev_entry_in_pool_conf(device_name_lower)) == -1) { TangoSys_OMemStream o; o << "Can't find entry for device " << device_name << " in polling threads pool configuration !"<< ends; Except::throw_exception((const char *)API_PolledDeviceNotInPoolConf,o.str(), (const char *)"DeviceImpl::stop_polling"); } vector &pool_conf = tg->get_poll_pool_conf(); string &conf_entry = pool_conf[ind]; string::size_type pos; if ((pos = conf_entry.find(',')) != string::npos) { pos = conf_entry.find(device_name_lower); if ((pos + device_name_lower.size()) != conf_entry.size()) conf_entry.erase(pos,device_name_lower.size() + 1); else conf_entry.erase(pos - 1); } else { vector::iterator iter = pool_conf.begin() + ind; pool_conf.erase(iter); kill_thread = true; } tg->remove_dev_from_polling_map(device_name_lower); // // Kill the thread if needed and join // if (kill_thread == true) { TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; mon.signal(); } void *dummy_ptr; cout4 << "POLLING: Joining with one polling thread" << endl; th_info->poll_th->join(&dummy_ptr); tg->remove_polling_thread_info_by_id(poll_th_id); } // // Update db // if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { DbData send_data; send_data.push_back(DbDatum("polling_threads_pool_conf")); send_data[0] << tg->get_poll_pool_conf(); tg->get_dserver_device()->get_db_device()->put_property(send_data); } } //+------------------------------------------------------------------------- // // method : DeviceImpl::~DeviceImpl // // description : Destructor for the device class. It simply frees // the memory allocated for the black box object // //-------------------------------------------------------------------------- DeviceImpl::~DeviceImpl() { cout4 << "Entering DeviceImpl destructor for device " << device_name << endl; // // Call user delete_device method // delete_device(); // // Delete the black box // delete blackbox_ptr; // // Delete the DbDevice object // delete db_dev; // // Unregister the signal from signal handler // DServerSignal::instance()->unregister_dev_signal(this); // // Delete the multi attribute object // delete dev_attr; // // Clean up previously executed in extension destructor // Deletes memory for ring buffer used for polling // for (unsigned long i = 0;i < poll_obj_list.size();i++) { delete (poll_obj_list[i]); } #ifdef TANGO_HAS_LOG4TANGO if (logger && logger != Logging::get_core_logger()) { logger->remove_all_appenders(); delete logger; logger = 0; } #endif delete locker_client; delete old_locker_client; // // Delete the extension class instance // #ifndef HAS_UNIQUE_PTR delete ext; #endif // // Clear our ptr in the device class vector // vector &dev_vect = get_device_class()->get_device_list(); vector::iterator ite = find(dev_vect.begin(),dev_vect.end(),this); if (ite != dev_vect.end()) *ite = NULL; cout4 << "Leaving DeviceImpl destructor for device " << device_name << endl; } //+------------------------------------------------------------------------- // // method : DeviceImpl::black_box_create // // description : Private method to create the device black box. // The black box depth is a resource with a default // value if the resource is not defined // //-------------------------------------------------------------------------- void DeviceImpl::black_box_create() { // // If the black box depth object attribute is null, create one with the // default depth // try { if (blackbox_depth == 0) blackbox_ptr = new BlackBox(); else blackbox_ptr = new BlackBox(blackbox_depth); } catch (bad_alloc &) { throw; } } //+---------------------------------------------------------------------------- // // method : DeviceImpl::get_dev_system_resource() // // description : Method to retrieve some basic device resources // The resources to be retrived are : // - The black box depth // - The device description // - The polling ring buffer depth // - The polled command(s) // - The polled attribute(s) // - The non automatic polled command list // - The non automatic polled attribute list // - The polling too old factor // - The command polling ring depth (if any) // - The attribute polling ring depth (if any) // //----------------------------------------------------------------------------- void DeviceImpl::get_dev_system_resource() { // // Try to retrieve resources for device black box depth and device // description // Tango::Util *tg = Tango::Util::instance(); if (tg->_UseDb == true) { DbData db_data; db_data.push_back(DbDatum("blackbox_depth")); db_data.push_back(DbDatum("description")); db_data.push_back(DbDatum("poll_ring_depth")); db_data.push_back(DbDatum("polled_cmd")); db_data.push_back(DbDatum("polled_attr")); db_data.push_back(DbDatum("non_auto_polled_cmd")); db_data.push_back(DbDatum("non_auto_polled_attr")); db_data.push_back(DbDatum("poll_old_factor")); db_data.push_back(DbDatum("cmd_poll_ring_depth")); db_data.push_back(DbDatum("attr_poll_ring_depth")); db_data.push_back(DbDatum("min_poll_period")); db_data.push_back(DbDatum("cmd_min_poll_period")); db_data.push_back(DbDatum("attr_min_poll_period")); try { db_dev->get_property(db_data); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Database error while trying to retrieve device prperties for device " << device_name.c_str() << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"DeviceImpl::get_dev_system_resource"); } if (db_data[0].is_empty() == false) db_data[0] >> blackbox_depth; if (db_data[1].is_empty() == false) db_data[1] >> desc; if (db_data[2].is_empty() == false) { long tmp_depth; db_data[2] >> tmp_depth; set_poll_ring_depth(tmp_depth); } if (db_data[3].is_empty() == false) db_data[3] >> get_polled_cmd(); if (db_data[4].is_empty() == false) db_data[4] >> get_polled_attr(); if (db_data[5].is_empty() == false) db_data[5] >> get_non_auto_polled_cmd(); if (db_data[6].is_empty() == false) db_data[6] >> get_non_auto_polled_attr(); if (db_data[7].is_empty() == false) { long tmp_poll; db_data[7] >> tmp_poll; set_poll_old_factor(tmp_poll); } else set_poll_old_factor(DEFAULT_POLL_OLD_FACTOR); if (db_data[8].is_empty() == false) { db_data[8] >> cmd_poll_ring_depth; unsigned long nb_prop = cmd_poll_ring_depth.size(); if ((nb_prop % 2) == 1) { cmd_poll_ring_depth.clear(); TangoSys_OMemStream o; o << "System property cmd_poll_ring_depth for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_dev_system_resource()"); } for (unsigned int i = 0;i < nb_prop;i = i + 2) transform(cmd_poll_ring_depth[i].begin(), cmd_poll_ring_depth[i].end(), cmd_poll_ring_depth[i].begin(), ::tolower); } if (db_data[9].is_empty() == false) { db_data[9] >> attr_poll_ring_depth; unsigned long nb_prop = attr_poll_ring_depth.size(); if ((attr_poll_ring_depth.size() % 2) == 1) { attr_poll_ring_depth.clear(); TangoSys_OMemStream o; o << "System property attr_poll_ring_depth for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_dev_system_resource()"); } for (unsigned int i = 0;i < nb_prop;i = i + 2) transform(attr_poll_ring_depth[i].begin(), attr_poll_ring_depth[i].end(), attr_poll_ring_depth[i].begin(), ::tolower); } // // The min. period related properties // if (db_data[10].is_empty() == false) db_data[10] >> min_poll_period; if (db_data[11].is_empty() == false) { db_data[11] >> cmd_min_poll_period; unsigned long nb_prop = cmd_min_poll_period.size(); if ((cmd_min_poll_period.size() % 2) == 1) { cmd_min_poll_period.clear(); TangoSys_OMemStream o; o << "System property cmd_min_poll_period for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_dev_system_resource()"); } for (unsigned int i = 0;i < nb_prop;i = i + 2) transform(cmd_min_poll_period[i].begin(), cmd_min_poll_period[i].end(), cmd_min_poll_period[i].begin(), ::tolower); } if (db_data[12].is_empty() == false) { db_data[12] >> attr_min_poll_period; unsigned long nb_prop = attr_min_poll_period.size(); if ((attr_min_poll_period.size() % 2) == 1) { attr_min_poll_period.clear(); TangoSys_OMemStream o; o << "System property attr_min_poll_period for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_dev_system_resource()"); } for (unsigned int i = 0;i < nb_prop;i = i + 2) transform(attr_min_poll_period[i].begin(), attr_min_poll_period[i].end(), attr_min_poll_period[i].begin(), ::tolower); } // // Since Tango V5 (IDL V3), State and Status are now polled as attributes // Change properties if necessary // if ((get_polled_cmd()).size() != 0) poll_lists_2_v5(); } } //+------------------------------------------------------------------------- // // method : DeviceImpl::_default_POA // // description : Return a pointer to the POA on which the device should // be activated. This method is required by CORBA to // create a POA with the IMPLICIT_ACTIVATION policy // //-------------------------------------------------------------------------- PortableServer::POA_ptr DeviceImpl::_default_POA() { return Util::instance()->get_poa(); } //+------------------------------------------------------------------------- // // method : DeviceImpl::register_signal // // description : Method to register a device on a signal. When the // signal is sent to the process, the signal_handler // method of this class will be executed // // in : signo : The signal number // //-------------------------------------------------------------------------- #ifndef _TG_WINDOWS_ void DeviceImpl::register_signal(long signo,bool hand) { cout4 << "DeviceImpl::register_signal() arrived for signal " << signo << endl; DServerSignal::instance()->register_dev_signal(signo,hand,this); cout4 << "Leaving DeviceImpl::register_signal method()" << endl; } #else void DeviceImpl::register_signal(long signo) { cout4 << "DeviceImpl::register_signal() arrived for signal " << signo << endl; DServerSignal::instance()->register_dev_signal(signo,this); cout4 << "Leaving DeviceImpl::register_signal method()" << endl; } #endif //+------------------------------------------------------------------------- // // method : DeviceImpl::unregister_signal // // description : Method to unregister a device on a signal. // // in : signo : The signal number // //-------------------------------------------------------------------------- void DeviceImpl::unregister_signal(long signo) { cout4 << "DeviceImpl::unregister_signal() arrived for signal " << signo << endl; DServerSignal::instance()->unregister_dev_signal(signo,this); cout4 << "Leaving DeviceImpl::unregister_signal method()" << endl; } //+------------------------------------------------------------------------- // // method : DeviceImpl::signal_handler // // description : This is the signal handler for the device. This method // is defined as virtual and therefore, can be redefined // by DS programmers in their own classes derived from // DeviceImpl // // in : signo : The signal number // //-------------------------------------------------------------------------- void DeviceImpl::signal_handler(long signo) { cout4 << "DeviceImpl::signal_handler() arrived for signal " << signo << endl; cout4 << "Leaving DeviceImpl::signal_handler method()" << endl; } //+------------------------------------------------------------------------- // // method : DeviceImpl::check_command_exist // // description : This method check that a comamnd is supported by // the device and does not need input value. // The method throws an exception if the // command is not defined or needs an input value // // in : cmd_name : The command name // //-------------------------------------------------------------------------- void DeviceImpl::check_command_exists(const string &cmd_name) { vector &cmd_list = device_class->get_command_list(); unsigned long i; for (i = 0;i < cmd_list.size();i++) { if (cmd_list[i]->get_lower_name() == cmd_name) { if (cmd_list[i]->get_in_type() != Tango::DEV_VOID) { TangoSys_OMemStream o; o << "Command " << cmd_name << " cannot be polled because it needs input value" << ends; Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, o.str(),(const char *)"DeviceImpl::check_command_exists"); } return; } } TangoSys_OMemStream o; o << "Command " << cmd_name << " not found" << ends; Except::throw_exception((const char *)API_CommandNotFound,o.str(), (const char *)"DeviceImpl::check_command_exists"); } //+------------------------------------------------------------------------- // // method : DeviceImpl::get_command // // description : This method returns a pointer to command object. // The method throws an exception if the // command is not defined // // in : cmd_name : The command name // //-------------------------------------------------------------------------- Command *DeviceImpl::get_command(const string &cmd_name) { vector cmd_list = device_class->get_command_list(); unsigned long i; for (i = 0;i < cmd_list.size();i++) { if (cmd_list[i]->get_lower_name() == cmd_name) { return cmd_list[i]; } } TangoSys_OMemStream o; o << "Command " << cmd_name << " not found" << ends; Except::throw_exception((const char *)API_CommandNotFound,o.str(), (const char *)"DeviceImpl::get_command"); // // This piece of code is added for VC++ compiler. As they advice, I have try to // use the __decspec(noreturn) for the throw_exception method, but it seems // that it does not work ! // return NULL; } //+------------------------------------------------------------------------- // // method : DeviceImpl::get_polled_obj_by_type_name // // description : This method check that a comamnd is supported by // the device and does not need input value. // The method throws an exception if the // command is not defined or needs an input value // // in : cmd_name : The command name // //-------------------------------------------------------------------------- vector::iterator DeviceImpl::get_polled_obj_by_type_name( Tango::PollObjType obj_type, const string &obj_name) { vector &po_list = get_poll_obj_list(); vector::iterator ite; for (ite = po_list.begin();ite < po_list.end();++ite) { omni_mutex_lock sync(**ite); { if ((*ite)->get_type_i() == obj_type) { if ((*ite)->get_name_i() == obj_name) { return ite; } } } } TangoSys_OMemStream o; o << obj_name << " not found in list of polled object" << ends; Except::throw_exception((const char *)API_PollObjNotFound,o.str(), (const char *)"DeviceImpl::get_polled_obj_by_type_name"); // // Only to make compiler quiet. Should never pass here // // exclude the return value for VC8+ #if !defined(_TG_WINDOWS_) || (defined(_MSC_VER) && _MSC_VER < 1400) return (vector::iterator)NULL; #endif } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_cmd_poll_ring_depth // // description : // This method returns the polling buffer depth. Most of the times, this is defined at device level // via the device "poll_ring_depth" property. Nevertheless, in some cases, this value can be overwritten via the // device "cmd_poll_ring_depth" property. // // args : // in : // - cmd_name : The command name // // return : // This method returns the polling buffer depth // //------------------------------------------------------------------------------------------------------------------- long DeviceImpl::get_cmd_poll_ring_depth(string &cmd_name) { long ret; if (cmd_poll_ring_depth.size() == 0) { // // No specific depth defined // if (poll_ring_depth == 0) ret = DefaultPollRingDepth; else ret = poll_ring_depth; } else { unsigned long k; // // Try to find command in list of specific polling buffer depth // for (k = 0; k < cmd_poll_ring_depth.size();k = k + 2) { if (cmd_poll_ring_depth[k] == cmd_name) { TangoSys_MemStream s; s << cmd_poll_ring_depth[k + 1]; if (!(s >> ret)) { TangoSys_OMemStream o; o << "System property cmd_poll_ring_depth for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_poll_ring_depth()"); } break; } } if (k >= cmd_poll_ring_depth.size()) { // // Not found // if (poll_ring_depth == 0) ret = DefaultPollRingDepth; else ret = poll_ring_depth; } } return ret; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_attr_poll_ring_depth // // description : // This method returns the polling buffer depth. Most of the times, this is defined at device level // via the device "poll_ring_depth" property. Nevertheless, in some cases, this value can be overwritten via the // device "attr_poll_ring_depth" property. // // args : // in : // - attr_name : The attribute name // // return : // This method returns the polling buffer depth // //-------------------------------------------------------------------------- long DeviceImpl::get_attr_poll_ring_depth(string &attr_name) { long ret; if (attr_poll_ring_depth.size() == 0) { if ((attr_name == "state") || (attr_name == "status")) { ret = get_cmd_poll_ring_depth(attr_name); } else { // // No specific depth defined // if (poll_ring_depth == 0) ret = DefaultPollRingDepth; else ret = poll_ring_depth; } } else { unsigned long k; // // Try to find command in list of specific polling buffer depth // for (k = 0; k < attr_poll_ring_depth.size();k = k + 2) { if (attr_poll_ring_depth[k] == attr_name) { TangoSys_MemStream s; s << attr_poll_ring_depth[k + 1]; if (!(s >> ret)) { TangoSys_OMemStream o; o << "System property attr_poll_ring_depth for device " << device_name << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"DeviceImpl::get_poll_ring_depth()"); } break; } } if (k >= attr_poll_ring_depth.size()) { if ((attr_name == "state") || (attr_name == "status")) { ret = get_cmd_poll_ring_depth(attr_name); } else { // // Not found // if (poll_ring_depth == 0) ret = DefaultPollRingDepth; else ret = poll_ring_depth; } } } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::dev_state // // description : // The default method called by the DevState command. If the device is ON, this method checks attribute // with a defined alarm and set the state to ALARM if one of these attribute is in alarm. Otherwise, simply // returns device state // //-------------------------------------------------------------------------------------------------------------------- Tango::DevState DeviceImpl::dev_state() { NoSyncModelTangoMonitor mon(this); // // If we need to run att. conf loop, do it. // If the flag to force state is true, do not call state computation method, simply set it to ALARM // if (run_att_conf_loop == true) att_conf_loop(); if (device_state != Tango::FAULT && force_alarm_state == true) { return Tango::ALARM; } else { if ((device_state == Tango::ON) || (device_state == Tango::ALARM)) { // // Build attribute lists // long vers = get_dev_idl_version(); bool set_alrm = false; vector attr_list = dev_attr->get_alarm_list(); vector attr_list_2 = get_alarmed_not_read(); vector attr_polled_list; long nb_wanted_attr; if (vers >= 3) { if (state_from_read == true) { vector::iterator ite = attr_list_2.begin(); while (ite != attr_list_2.end()) { Attribute &att = dev_attr->get_attr_by_ind(*ite); if (att.is_polled() == true) { ite = attr_list_2.erase(ite); } else ++ite; } nb_wanted_attr = attr_list_2.size(); } else { vector::iterator ite = attr_list.begin(); while (ite != attr_list.end()) { Attribute &att = dev_attr->get_attr_by_ind(*ite); if (att.is_polled() == true) ite = attr_list.erase(ite); else ++ite; } nb_wanted_attr = attr_list.size(); } } else { nb_wanted_attr = attr_list.size(); } cout4 << "State: Number of attribute(s) to read: " << nb_wanted_attr << endl; if (nb_wanted_attr != 0) { // // Read the hardware // if (state_from_read == false) { read_attr_hardware(attr_list); } // // Set attr value // long i,j; vector &attr_vect = device_class->get_class_attr()->get_attr_list(); for (i = 0;i < nb_wanted_attr;i++) { // // Starting with IDL 3, it is possible that some of the alarmed attribute have already been read. // long idx; if ((vers >= 3) && (state_from_read == true)) idx = attr_list_2[i]; else idx = attr_list[i]; Attribute &att = dev_attr->get_attr_by_ind(idx); att.save_alarm_quality(); try { if (vers < 3) read_attr(att); else { // // Otherwise, get it from device // att.wanted_date(false); att.set_value_flag(false); if (attr_vect[att.get_attr_idx()]->is_allowed(this,Tango::READ_REQ) == false) { att.wanted_date(true); continue; } attr_vect[att.get_attr_idx()]->read(this,att); Tango::AttrQuality qua = att.get_quality(); if ((qua != Tango::ATTR_INVALID) && (att.get_value_flag() == false)) { TangoSys_OMemStream o; o << "Read value for attribute "; o << att.get_name(); o << " has not been updated"; o << "Hint: Did the server follow Tango V5 attribute reading framework ?" << ends; Except::throw_exception((const char *)API_AttrValueNotSet,o.str(), (const char *)"DeviceImpl::dev_state"); } } } catch (Tango::DevFailed &) { for (j = 0;j < i;j++) { long idx; if ((vers >= 3) && (state_from_read == true)) idx = attr_list_2[j]; else idx = attr_list[j]; Tango::Attribute &tmp_att = dev_attr->get_attr_by_ind(idx); if (att.get_wanted_date() == false) { if (tmp_att.get_quality() != Tango::ATTR_INVALID) tmp_att.delete_seq(); tmp_att.wanted_date(true); } } att.wanted_date(true); // throw; } } // // Check alarm level // if (dev_attr->check_alarm() == true) { set_alrm = true; if (device_state != Tango::ALARM) { device_state = Tango::ALARM; ext->alarm_state_kernel = time(NULL); } } else { if (ext->alarm_state_kernel > ext->alarm_state_user) device_state = Tango::ON; } // // Free the sequence created to store the attribute value // for (long i = 0;i < nb_wanted_attr;i++) { long idx; if ((vers >= 3) && (state_from_read == true)) idx = attr_list_2[i]; else idx = attr_list[i]; Tango::Attribute &att = dev_attr->get_attr_by_ind(idx); if (att.get_wanted_date() == false) { if (att.get_quality() != Tango::ATTR_INVALID) att.delete_seq(); att.wanted_date(true); } } } else { if (ext->alarm_state_kernel > ext->alarm_state_user) device_state = Tango::ON; } // // Check if one of the remaining attributes has its quality factor set to ALARM or WARNING. It is not necessary to do // this if we have already detected that the state must switch to ALARM // if ((set_alrm == false) && (device_state != Tango::ALARM)) { if (dev_attr->is_att_quality_alarmed() == true) { if (device_state != Tango::ALARM) { device_state = Tango::ALARM; ext->alarm_state_kernel = time(NULL); } } else device_state = Tango::ON; } } } return device_state; } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::dev_status // // description : // The default method called by the DevStatus command. If the device is ON, this method add Attribute status // for all device attribute in alarm state. // //--------------------------------------------------------------------------------------------------------------------- Tango::ConstDevString DeviceImpl::dev_status() { NoSyncModelTangoMonitor mon(this); const char *returned_str; if (run_att_conf_loop == true) att_conf_loop(); if (device_state != Tango::FAULT && force_alarm_state == true) { alarm_status = "The device is in ALARM state."; // // First add message for attribute with wrong conf. in db // size_t nb_wrong_att = att_wrong_db_conf.size(); if (nb_wrong_att != 0) { alarm_status = alarm_status + "\nAttribute"; build_att_list_in_status_mess(nb_wrong_att,DeviceImpl::CONF); alarm_status = alarm_status + "wrong configuration"; alarm_status = alarm_status + "\nTry accessing the faulty attribute(s) to get more information"; } // // Add message for memorized attributes which failed during device startup // nb_wrong_att = att_mem_failed.size(); if (nb_wrong_att != 0) { alarm_status = alarm_status + "\nMemorized attribute"; build_att_list_in_status_mess(nb_wrong_att,DeviceImpl::MEM); alarm_status = alarm_status + "failed during device startup sequence"; } // // Add message for forwarded attributes wrongly configured // nb_wrong_att = fwd_att_wrong_conf.size(); if (nb_wrong_att != 0) { build_att_list_in_status_mess(nb_wrong_att,DeviceImpl::FWD); } returned_str = alarm_status.c_str(); } else { if (device_status == StatusNotSet) { alarm_status = "The device is in "; alarm_status = alarm_status + DevStateName[device_state] + " state."; if (device_state == Tango::ALARM) { dev_attr->read_alarm(alarm_status); dev_attr->add_alarmed_quality_factor(alarm_status); } returned_str = alarm_status.c_str(); } else { if (device_state == Tango::ALARM) { alarm_status = device_status; dev_attr->read_alarm(alarm_status); dev_attr->add_alarmed_quality_factor(alarm_status); returned_str = alarm_status.c_str(); } else returned_str = device_status.c_str(); } } return returned_str; } //+------------------------------------------------------------------------- // // method : DeviceImpl::command_inout // // description : Method called for each command_inout operation executed // from any client // The call to this method is in a try bloc for the // Tango::DevFailed exception (generated by the idl // compiler in the tango_skel.cpp file). Therefore, it // is not necessary to propagate by re-throw the exceptions // thrown by the underlying functions/methods. // //-------------------------------------------------------------------------- CORBA::Any *DeviceImpl::command_inout(const char *in_cmd, const CORBA::Any &in_any) { AutoTangoMonitor sync(this); string command(in_cmd); CORBA::Any *out_any; cout4 << "DeviceImpl::command_inout(): command received : " << command << endl; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Catch all exceptions to set back the associated device after execution // try { // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_cmd(in_cmd); store_in_bb = true; // // Execute command // out_any = device_class->command_handler(this,command,in_any); } catch (...) { // set back the device attribution for the thread // and rethrow the exception. sub.set_associated_device(last_associated_device); throw; } // set back the device attribution for the thread sub.set_associated_device(last_associated_device); // // Return value to the caller // cout4 << "DeviceImpl::command_inout(): leaving method for command " << in_cmd << endl; return(out_any); } //+------------------------------------------------------------------------- // // method : DeviceImpl::name // // description : Method called when a client request the name attribute // This method is called for a IDL attribute which can // not throw exception to client ==> There is no point // to check if the allocation done by the string_dup // function failed. // //-------------------------------------------------------------------------- char *DeviceImpl::name() { try { cout4 << "DeviceImpl::name arrived" << endl; // // Record attribute request in black box // blackbox_ptr->insert_corba_attr(Attr_Name); } catch (Tango::DevFailed &e) { CORBA::IMP_LIMIT lim; if (strcmp(e.errors[0].reason,API_CommandTimedOut) == 0) lim.minor(TG_IMP_MINOR_TO); else lim.minor(TG_IMP_MINOR_DEVFAILED); cout4 << "Leaving DeviceImpl::name throwing IMP_LIMIT" << endl; throw lim; } catch (...) { CORBA::IMP_LIMIT lim; lim.minor(TG_IMP_MINOR_NON_DEVFAILED); cout4 << "Leaving DeviceImpl::name throwing IMP_LIMIT" << endl; throw lim; } // // Return data to caller // cout4 << "Leaving DeviceImpl::name" << endl; return CORBA::string_dup(device_name.c_str()); } //+------------------------------------------------------------------------- // // method : DeviceImpl::adm_name // // description : Method called when a client request the adm_name attribute // This method is called for a IDL attribute which can // not throw exception to client ==> There is no point // to check if the allocation done by the string_dup // function failed. // //-------------------------------------------------------------------------- char *DeviceImpl::adm_name() { try { cout4 << "DeviceImpl::adm_name arrived" << endl; // // Record attribute request in black box // blackbox_ptr->insert_corba_attr(Attr_AdmName); } catch (Tango::DevFailed &e) { CORBA::IMP_LIMIT lim; if (strcmp(e.errors[0].reason,API_CommandTimedOut) == 0) lim.minor(TG_IMP_MINOR_TO); else lim.minor(TG_IMP_MINOR_DEVFAILED); cout4 << "Leaving DeviceImpl::adm_name throwing IMP_LIMIT" << endl; throw lim; } catch (...) { CORBA::IMP_LIMIT lim; lim.minor(TG_IMP_MINOR_NON_DEVFAILED); cout4 << "Leaving DeviceImpl::adm_name throwing IMP_LIMIT" << endl; throw lim; } // // Return data to caller // cout4 << "Leaving DeviceImpl::adm_name" << endl; return CORBA::string_dup(adm_device_name.c_str()); } //+------------------------------------------------------------------------- // // method : DeviceImpl::description // // description : Method called when a client request the description // attribute // This method is called for a IDL attribute which can // not throw exception to client ==> There is no point // to check if the allocation done by the string_dup // function failed. // //-------------------------------------------------------------------------- char *DeviceImpl::description() { try { cout4 << "DeviceImpl::description arrived" << endl; // // Record attribute request in black box // blackbox_ptr->insert_corba_attr(Attr_Description); } catch (Tango::DevFailed &e) { CORBA::IMP_LIMIT lim; if (strcmp(e.errors[0].reason,API_CommandTimedOut) == 0) lim.minor(TG_IMP_MINOR_TO); else lim.minor(TG_IMP_MINOR_DEVFAILED); cout4 << "Leaving DeviceImpl::description throwing IMP_LIMIT" << endl; throw lim; } catch (...) { CORBA::IMP_LIMIT lim; lim.minor(TG_IMP_MINOR_NON_DEVFAILED); cout4 << "Leaving DeviceImpl::description throwing IMP_LIMIT" << endl; throw lim; } // // Return data to caller // cout4 << "Leaving DeviceImpl::description" << endl; return CORBA::string_dup(desc.c_str()); } //+------------------------------------------------------------------------- // // method : DeviceImpl::state // // description : Method called when a client request the state // attribute // //-------------------------------------------------------------------------- Tango::DevState DeviceImpl::state() { Tango::DevState tmp; string last_associated_device; try { AutoTangoMonitor sync(this); cout4 << "DeviceImpl::state (attribute) arrived" << endl; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Record attribute request in black box // blackbox_ptr->insert_corba_attr(Attr_State); always_executed_hook(); // // Return data to caller. If the state_cmd throw an exception, catch it and do // not re-throw it because we are in a CORBA attribute implementation tmp = dev_state(); } catch (Tango::DevFailed &e) { if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } CORBA::IMP_LIMIT lim; if (strcmp(e.errors[0].reason,API_CommandTimedOut) == 0) lim.minor(TG_IMP_MINOR_TO); else lim.minor(TG_IMP_MINOR_DEVFAILED); cout4 << "Leaving DeviceImpl::state (attribute) throwing IMP_LIMIT" << endl; throw lim; } catch (...) { if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } CORBA::IMP_LIMIT lim; lim.minor(TG_IMP_MINOR_NON_DEVFAILED); cout4 << "Leaving DeviceImpl::state (attribute) throwing IMP_LIMIT" << endl; throw lim; } if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } cout4 << "Leaving DeviceImpl::state (attribute)" << endl; return tmp; } //+------------------------------------------------------------------------- // // method : DeviceImpl::status // // description : Method called when a client request the description // status // This method is called for a IDL attribute which can // not throw exception to client ==> There is no point // to check if the allocation done by the string_dup // function failed. // //-------------------------------------------------------------------------- char *DeviceImpl::status() { char *tmp; string last_associated_device; try { AutoTangoMonitor sync(this); cout4 << "DeviceImpl::status (attibute) arrived" << endl; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Record attribute request in black box // blackbox_ptr->insert_corba_attr(Attr_Status); // // Return data to caller. If the status_cmd method throw exception, catch it // and forget it because we are in a CORBA attribute implementation // always_executed_hook(); tmp = CORBA::string_dup(dev_status()); } catch (Tango::DevFailed &e) { if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } if (strcmp(e.errors[0].reason,API_CommandTimedOut) == 0) tmp = CORBA::string_dup("Not able to acquire device monitor"); else tmp = CORBA::string_dup("Got exception when trying to build device status"); } catch (...) { if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } CORBA::IMP_LIMIT lim; lim.minor(TG_IMP_MINOR_NON_DEVFAILED); throw lim; } if (last_associated_device.size() > 0) { // set back the device attribution for the thread (Tango::Util::instance())->get_sub_dev_diag().set_associated_device(last_associated_device); } cout4 << "Leaving DeviceImpl::status (attribute)" << endl; return tmp; } //+------------------------------------------------------------------------- // // method : DeviceImpl::black_box // // description : CORBA operation to read n element(s) of the black-box. // This method returns black box element as strings // // argument: in : - n : Number of elt to read // //-------------------------------------------------------------------------- Tango::DevVarStringArray* DeviceImpl::black_box(CORBA::Long n) { cout4 << "DeviceImpl::black_box arrived" << endl; Tango::DevVarStringArray *ret = blackbox_ptr->read((long)n); // // Record operation request in black box // blackbox_ptr->insert_op(Op_BlackBox); cout4 << "Leaving DeviceImpl::black_box" << endl; return ret; } //+------------------------------------------------------------------------- // // method : DeviceImpl::command_list_query // // description : CORBA operation to read the device command list. // This method returns command info in a sequence of // DevCmdInfo // //-------------------------------------------------------------------------- Tango::DevCmdInfoList* DeviceImpl::command_list_query() { cout4 << "DeviceImpl::command_list_query arrived" << endl; // // Retrieve number of command and allocate memory to send back info // long nb_cmd = device_class->get_command_list().size(); cout4 << nb_cmd << " command(s) for device" << endl; Tango::DevCmdInfoList *back = NULL; try { back = new Tango::DevCmdInfoList(nb_cmd); back->length(nb_cmd); // // Populate the vector // for (long i = 0;i < nb_cmd;i++) { Tango::DevCmdInfo tmp; tmp.cmd_name = CORBA::string_dup(((device_class->get_command_list())[i]->get_name()).c_str()); tmp.cmd_tag = (long)((device_class->get_command_list())[i]->get_disp_level()); tmp.in_type = (long)((device_class->get_command_list())[i]->get_in_type()); tmp.out_type = (long)((device_class->get_command_list())[i]->get_out_type()); string &str_in = (device_class->get_command_list())[i]->get_in_type_desc(); if (str_in.size() != 0) tmp.in_type_desc = CORBA::string_dup(str_in.c_str()); else tmp.in_type_desc = CORBA::string_dup(NotSet); string &str_out = (device_class->get_command_list())[i]->get_out_type_desc(); if (str_out.size() != 0) tmp.out_type_desc = CORBA::string_dup(str_out.c_str()); else tmp.out_type_desc = CORBA::string_dup(NotSet); (*back)[i] = tmp; } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl::command_list_query"); } // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command_list); // // Return to caller // cout4 << "Leaving DeviceImpl::command_list_query" << endl; return back; } //+------------------------------------------------------------------------- // // method : DeviceImpl::command_query // // description : CORBA operation to read a device command info. // This method returns command info for a specific // command. // // //-------------------------------------------------------------------------- Tango::DevCmdInfo *DeviceImpl::command_query(const char *command) { cout4 << "DeviceImpl::command_query arrived" << endl; Tango::DevCmdInfo *back = NULL; string cmd(command); transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); // // Allocate memory for the stucture sent back to caller. The ORB will free it // try { back = new Tango::DevCmdInfo(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl::command_query"); } // // Try to retrieve the command in the command list // long i; long nb_cmd = device_class->get_command_list().size(); for (i = 0;i < nb_cmd;i++) { if (device_class->get_command_list()[i]->get_lower_name() == cmd) { back->cmd_name = CORBA::string_dup(((device_class->get_command_list())[i]->get_name()).c_str()); back->cmd_tag = (long)((device_class->get_command_list())[i]->get_disp_level()); back->in_type = (long)((device_class->get_command_list())[i]->get_in_type()); back->out_type = (long)((device_class->get_command_list())[i]->get_out_type()); string &str_in = (device_class->get_command_list())[i]->get_in_type_desc(); if (str_in.size() != 0) back->in_type_desc = CORBA::string_dup(str_in.c_str()); else back->in_type_desc = CORBA::string_dup(NotSet); string &str_out = (device_class->get_command_list())[i]->get_out_type_desc(); if (str_out.size() != 0) back->out_type_desc = CORBA::string_dup(str_out.c_str()); else back->out_type_desc = CORBA::string_dup(NotSet); break; } } if (i == nb_cmd) { delete back; cout3 << "DeviceImpl::command_query(): command " << command << " not found" << endl; // // throw an exception to client // TangoSys_OMemStream o; o << "Command " << command << " not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceImpl::command_query"); } // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command); // // Return to caller // cout4 << "Leaving DeviceImpl::command_query" << endl; return back; } //+------------------------------------------------------------------------- // // method : DeviceImpl::info // // description : CORBA operation to get device info // //-------------------------------------------------------------------------- Tango::DevInfo *DeviceImpl::info() { cout4 << "DeviceImpl::info arrived" << endl; Tango::DevInfo *back = NULL; // // Allocate memory for the stucture sent back to caller. The ORB will free it // try { back = new Tango::DevInfo(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl::info"); } // // Retrieve server host // Tango::Util *tango_ptr = Tango::Util::instance(); back->server_host = CORBA::string_dup(tango_ptr->get_host_name().c_str()); // // Fill-in remaining structure fields // back->dev_class = CORBA::string_dup(device_class->get_name().c_str()); back->server_id = CORBA::string_dup(tango_ptr->get_ds_name().c_str()); back->server_version = DevVersion; // // Build the complete info sent in the doc_url string // string doc_url("Doc URL = "); doc_url = doc_url + device_class->get_doc_url(); // // Add TAG if it exist // string &svn_tag = device_class->get_svn_tag(); if (svn_tag.size() != 0) { doc_url = doc_url + "\nSVN Tag = "; doc_url = doc_url + svn_tag; } else { string &cvs_tag = device_class->get_cvs_tag(); if (cvs_tag.size() != 0) { doc_url = doc_url + "\nCVS Tag = "; doc_url = doc_url + cvs_tag; } } // // Add SCM location if defined // string &svn_location = device_class->get_svn_location(); if (svn_location.size() != 0) { doc_url = doc_url + "\nSVN Location = "; doc_url = doc_url + svn_location; } else { string &cvs_location = device_class->get_cvs_location(); if (cvs_location.size() != 0) { doc_url = doc_url + "\nCVS Location = "; doc_url = doc_url + cvs_location; } } back->doc_url = CORBA::string_dup(doc_url.c_str()); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Info); // // Return to caller // cout4 << "Leaving DeviceImpl::info" << endl; return back; } //+------------------------------------------------------------------------- // // method : DeviceImpl::ping // // description : CORBA operation to ping if a device to see it is alive // //-------------------------------------------------------------------------- void DeviceImpl::ping() { cout4 << "DeviceImpl::ping arrived" << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Ping); // // Return to caller // cout4 << "Leaving DeviceImpl::ping" << endl; } //+------------------------------------------------------------------------- // // method : DeviceImpl::get_attribute_config // // description : CORBA operation to get attribute configuration. // // argument: in : - names: name of attribute(s) // // This method returns a pointer to a AttributeConfigList with one AttributeConfig // structure for each atribute // //-------------------------------------------------------------------------- Tango::AttributeConfigList *DeviceImpl::get_attribute_config(const Tango::DevVarStringArray& names) { cout4 << "DeviceImpl::get_attribute_config arrived" << endl; TangoMonitor &mon = get_att_conf_monitor(); AutoTangoMonitor sync(&mon); long nb_attr = names.length(); Tango::AttributeConfigList *back = NULL; bool all_attr = false; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Get_Attr_Config); // // Get attribute number and device version // long nb_dev_attr = dev_attr->get_attr_nb(); long vers = get_dev_idl_version(); // // Check if the caller want to get config for all attribute // If the device implements IDL 3 (State and status as attributes) // and the client is an old one (not able to read state/status as // attribute), decrement attribute number // string in_name(names[0]); if (nb_attr == 1) { if (in_name == AllAttr) { all_attr = true; if (vers < 3) nb_attr = nb_dev_attr; else nb_attr = nb_dev_attr - 2; } else if (in_name == AllAttr_3) { all_attr = true; nb_attr = nb_dev_attr; } } // // Allocate memory for the AttributeConfig structures // try { back = new Tango::AttributeConfigList(nb_attr); back->length(nb_attr); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl::get_attribute_config"); } // // Fill in these structures // for (long i = 0;i < nb_attr;i++) { try { if (all_attr == true) { Attribute &attr = dev_attr->get_attr_by_ind(i); attr.get_properties((*back)[i]); } else { Attribute &attr = dev_attr->get_attr_by_name(names[i]); attr.get_properties((*back)[i]); } } catch (Tango::DevFailed &e) { delete back; throw; } } // // Return to caller // cout4 << "Leaving DeviceImpl::get_attribute_config" << endl; return back; } //+------------------------------------------------------------------------- // // method : DeviceImpl::set_attribute_config // // description : CORBA operation to set attribute configuration locally // and in the Tango database // // argument: in : - new_conf: The new attribute(s) configuration. One // AttributeConfig structure is needed for each // attribute to update // //-------------------------------------------------------------------------- void DeviceImpl::set_attribute_config(const Tango::AttributeConfigList& new_conf) { AutoTangoMonitor sync(this,true); cout4 << "DeviceImpl::set_attribute_config arrived" << endl; // // The attribute conf. is protected by two monitors. One protects access between // get and set attribute conf. The second one protects access between set and // usage. This is the classical device monitor // TangoMonitor &mon1 = get_att_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Set_Attr_Config); // // Check if device is locked // check_lock("set_attribute_config"); // // Return exception if the device does not have any attribute // long nb_dev_attr = dev_attr->get_attr_nb(); if (nb_dev_attr == 0) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"The device does not have any attribute", (const char *)"DeviceImpl::set_attribute_config"); } // // Get some event related data // Tango::Util *tg = Tango::Util::instance(); EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; // // Update attribute config first in database, then locally // Finally send attr conf. event // long nb_attr = new_conf.length(); long i; try { for (i = 0;i < nb_attr;i++) { string tmp_name(new_conf[i].name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if ((tmp_name == "state") || (tmp_name == "status")) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"Cannot set config for attribute state or status", (const char *)"DeviceImpl::set_attribute_config"); } Attribute &attr = dev_attr->get_attr_by_name(new_conf[i].name); bool old_alarm = attr.is_alarmed().any(); vector v_db; attr.set_properties(new_conf[i],device_name,false,v_db); if (Tango::Util::_UseDb == true) attr.upd_database(v_db); // // In case the attribute quality factor was set to ALARM, reset it to VALID // if ((attr.get_quality() == Tango::ATTR_ALARM) && (old_alarm == true) && (attr.is_alarmed().any() == false)) attr.set_quality(Tango::ATTR_VALID); // // Send the event // if (attr.use_notifd_event() == true) event_supplier_nd = tg->get_notifd_event_supplier(); else event_supplier_nd = NULL; if (attr.use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); else event_supplier_zmq = NULL; if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL)) { string tmp_name(new_conf[i].name); EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); long vers = get_dev_idl_version(); if (vers <= 2) { Tango::AttributeConfig_2 attr_conf_2; attr.get_properties(attr_conf_2); ad.attr_conf_2 = &attr_conf_2; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); } else if (vers <= 4) { Tango::AttributeConfig_3 attr_conf_3; attr.get_properties(attr_conf_3); ad.attr_conf_3 = &attr_conf_3; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); } else { Tango::AttributeConfig_5 attr_conf_5; attr.get_properties(attr_conf_5); ad.attr_conf_5 = &attr_conf_5; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,tmp_name); } } } } catch (Tango::DevFailed &e) { // // Re build the list of "alarmable" attribute // dev_attr->get_alarm_list().clear(); for (long j = 0;j < nb_dev_attr;j++) { Attribute &att = dev_attr->get_attr_by_ind(j); if (att.is_alarmed().any() == true) { if (att.get_writable() != Tango::WRITE) dev_attr->get_alarm_list().push_back(j); } } // // Change the exception reason flag // TangoSys_OMemStream o; o << e.errors[0].reason; if (i != 0) o << "\nAll previous attribute(s) have been successfully updated"; if (i != (nb_attr - 1)) o << "\nAll remaining attribute(s) have not been updated"; o << ends; string s = o.str(); e.errors[0].reason = CORBA::string_dup(s.c_str()); throw; } // // Re build the list of "alarmable" attribute // dev_attr->get_alarm_list().clear(); for (i = 0;i < nb_dev_attr;i++) { Tango::Attribute &attr = dev_attr->get_attr_by_ind(i); Tango::AttrWriteType w_type = attr.get_writable(); if (attr.is_alarmed().any() == true) { if (w_type != Tango::WRITE) dev_attr->get_alarm_list().push_back(i); } } // // Return to caller // cout4 << "Leaving DeviceImpl::set_attribute_config" << endl; } //+------------------------------------------------------------------------- // // method : DeviceImpl::read_attributes // // description : CORBA operation to read attribute(s) value. // // argument: in : - names: name of attribute(s) to be read // // This method returns a pointer to a AttributeConfigList with one AttributeValue // structure for each atribute. This structure contains the attribute value, the // value quality and the date. // //-------------------------------------------------------------------------- Tango::AttributeValueList *DeviceImpl::read_attributes(const Tango::DevVarStringArray& names) { AutoTangoMonitor sync(this,true); Tango::AttributeValueList *back = NULL; cout4 << "DeviceImpl::read_attributes arrived" << endl; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // Catch all execeptions to set back the associated device after // execution try { // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(names); store_in_bb = true; // // Return exception if the device does not have any attribute // For device implementing IDL 3, substract 2 to the attributes // number for state and status which could be read only by // a "new" client // long vers = get_dev_idl_version(); long nb_dev_attr = dev_attr->get_attr_nb(); if (nb_dev_attr == 0) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"The device does not have any attribute", (const char *)"DeviceImpl::read_attributes"); } if (vers >= 3) nb_dev_attr = nb_dev_attr - 2; // // Build a sequence with the names of the attribute to be read. // This is necessary in case of the "AllAttr" shortcut is used // If all attributes are wanted, build this list // long i; Tango::DevVarStringArray real_names(nb_dev_attr); long nb_names = names.length(); if (nb_names == 1) { string att_name(names[0]); if (att_name == AllAttr) { real_names.length(nb_dev_attr); for (i = 0;i < nb_dev_attr;i++) real_names[i] = dev_attr->get_attr_by_ind(i).get_name().c_str(); } else { real_names = names; } } else { real_names = names; } // // Retrieve index of wanted attributes in the device attribute list and clear // their value set flag // // In IDL release 3, possibility to write spectrum and // images attributes have been added. This implies some // changes in the struture returned for a read_attributes // Throw exception if users want to use these new features // through an old interface // // nb_names = real_names.length(); vector wanted_attr; vector wanted_w_attr; for (i = 0;i < nb_names;i++) { long j = dev_attr->get_attr_ind_by_name(real_names[i]); if ((dev_attr->get_attr_by_ind(j).get_writable() == Tango::READ_WRITE) || (dev_attr->get_attr_by_ind(j).get_writable() == Tango::READ_WITH_WRITE)) { wanted_w_attr.push_back(j); wanted_attr.push_back(j); Attribute &att = dev_attr->get_attr_by_ind(wanted_attr.back()); Tango::AttrDataFormat format_type = att.get_data_format(); if ((format_type == Tango::SPECTRUM) || (format_type == Tango::IMAGE)) { TangoSys_OMemStream o; o << "Client too old to get data for attribute " << real_names[i].in(); o << ".\nPlease, use a client linked with Tango V5"; o << " and a device inheriting from Device_3Impl" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"DeviceImpl::read_attributes"); } att.set_value_flag(false); att.get_when().tv_sec = 0; } else { if (dev_attr->get_attr_by_ind(j).get_writable() == Tango::WRITE) { wanted_w_attr.push_back(j); Attribute &att = dev_attr->get_attr_by_ind(wanted_w_attr.back()); Tango::AttrDataFormat format_type = att.get_data_format(); if ((format_type == Tango::SPECTRUM) || (format_type == Tango::IMAGE)) { TangoSys_OMemStream o; o << "Client too old to get data for attribute " << real_names[i].in(); o << ".\nPlease, use a client linked with Tango V5"; o << " and a device inheriting from Device_3Impl" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"DeviceImpl::read_attributes"); } } else { wanted_attr.push_back(j); Attribute &att = dev_attr->get_attr_by_ind(wanted_attr.back()); att.set_value_flag(false); att.get_when().tv_sec = 0; } } } long nb_wanted_attr = wanted_attr.size(); long nb_wanted_w_attr = wanted_w_attr.size(); // // Call the always_executed_hook // always_executed_hook(); // // Read the hardware for readable attribute // if (nb_wanted_attr != 0) read_attr_hardware(wanted_attr); // // Set attr value (for readable attribute) // vector &attr_vect = device_class->get_class_attr()->get_attr_list(); for (i = 0;i < nb_wanted_attr;i++) { if (vers < 3) read_attr(dev_attr->get_attr_by_ind(wanted_attr[i])); else { Attribute &att = dev_attr->get_attr_by_ind(wanted_attr[i]); long idx = att.get_attr_idx(); if (idx == -1) { TangoSys_OMemStream o; o << "It is not possible to read state/status as attributes with your\n"; o << "Tango software release. Please, re-link with Tango V5." << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"Device_Impl::read_attributes"); } if (attr_vect[idx]->is_allowed(this,Tango::READ_REQ) == false) { TangoSys_OMemStream o; o << "It is currently not allowed to read attribute "; o << att.get_name() << ends; Except::throw_exception((const char *)API_AttrNotAllowed, o.str(), (const char *)"Device_Impl::read_attributes"); } attr_vect[idx]->read(this,att); } } // // Set attr value for writable attribute // for (i = 0;i < nb_wanted_w_attr;i++) { Tango::AttrWriteType w_type = dev_attr->get_attr_by_ind(wanted_w_attr[i]).get_writable(); if ((w_type == Tango::READ_WITH_WRITE) || (w_type == Tango::WRITE)) dev_attr->get_attr_by_ind(wanted_w_attr[i]).set_rvalue(); } // // Allocate memory for the AttributeValue structures // try { back = new Tango::AttributeValueList(nb_names); back->length(nb_names); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl::read_attributes"); } // // Build the sequence returned to caller for readable attributes and check // that all the wanted attributes set value has been updated // for (i = 0;i < nb_names;i++) { Attribute &att = dev_attr->get_attr_by_name(real_names[i]); Tango::AttrQuality qual = att.get_quality(); if (qual != Tango::ATTR_INVALID) { if (att.get_value_flag() == false) { TangoSys_OMemStream o; delete back; for (long j = 0;j < i;j++) { att = dev_attr->get_attr_by_name(real_names[j]); att.delete_seq(); } try { string att_name(real_names[i]); transform(att_name.begin(),att_name.end(),att_name.begin(),::tolower); vector::iterator ite = get_polled_obj_by_type_name(Tango::POLL_ATTR,att_name); long upd = (*ite)->get_upd(); if (upd == 0) { o << "Attribute "; o << att.get_name(); o << " value is available only by CACHE.\n"; o << "Attribute values are set by external polling buffer filling" << ends; } else { o << "Read value for attribute "; o << att.get_name(); o << " has not been updated" << ends; } } catch (Tango::DevFailed &) { o << "Read value for attribute "; o << att.get_name(); o << " has not been updated" << ends; } Except::throw_exception((const char *)API_AttrValueNotSet, o.str(), (const char *)"DeviceImpl::read_attributes"); } else { Tango::AttrWriteType w_type = att.get_writable(); if ((w_type == Tango::READ) || (w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) dev_attr->add_write_value(att); if ((att.is_alarmed().any() == true) && (qual != Tango::ATTR_INVALID)) att.check_alarm(); } CORBA::Any &a = (*back)[i].value; switch (att.get_data_type()) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { Tango::DevVarShortArray *ptr = att.get_short_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_LONG : { Tango::DevVarLongArray *ptr = att.get_long_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_LONG64 : { Tango::DevVarLong64Array *ptr = att.get_long64_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_DOUBLE : { Tango::DevVarDoubleArray *ptr = att.get_double_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_STRING : { Tango::DevVarStringArray *ptr = att.get_string_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_FLOAT : { Tango::DevVarFloatArray *ptr = att.get_float_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_BOOLEAN : { Tango::DevVarBooleanArray *ptr = att.get_boolean_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_USHORT : { Tango::DevVarUShortArray *ptr = att.get_ushort_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_UCHAR : { Tango::DevVarUCharArray *ptr = att.get_uchar_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_ULONG : { Tango::DevVarULongArray *ptr = att.get_ulong_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_ULONG64 : { Tango::DevVarULong64Array *ptr = att.get_ulong64_value(); a <<= *ptr; delete ptr; break; } case Tango::DEV_STATE : { Tango::DevVarStateArray *ptr = att.get_state_value(); a <<= *ptr; delete ptr; break; } } } } if (att.get_when().tv_sec == 0) att.set_time(); (*back)[i].time = att.get_when(); (*back)[i].quality = att.get_quality(); (*back)[i].name = CORBA::string_dup(att.get_name().c_str()); (*back)[i].dim_x = att.get_x(); (*back)[i].dim_y = att.get_y(); } } catch (...) { // set back the device attribution for the thread // and rethrow the exception. sub.set_associated_device(last_associated_device); throw; } // set back the device attribution for the thread sub.set_associated_device(last_associated_device); // // Return to caller // cout4 << "Leaving DeviceImpl::read_attributes" << endl; return back; } //+------------------------------------------------------------------------- // // method : DeviceImpl::write_attributes // // description : CORBA operation to write attribute(s) value // // argument: in : - values: The new attribute(s) value to be set. // //-------------------------------------------------------------------------- void DeviceImpl::write_attributes(const Tango::AttributeValueList& values) { AutoTangoMonitor sync(this,true); cout4 << "DeviceImpl::write_attributes arrived" << endl; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // Catch all execeptions to set back the associated device after // execution try { // // Record operation request in black box // blackbox_ptr->insert_attr(values); // // Check if the device is locked // check_lock("write_attributes"); // // Return exception if the device does not have any attribute // long nb_dev_attr = dev_attr->get_attr_nb(); if (nb_dev_attr == 0) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"The device does not have any attribute", (const char *)"DeviceImpl::write_attributes"); } // // Retrieve index of wanted attributes in the device attribute list // long nb_updated_attr = values.length(); vector updated_attr; long i; for (i = 0;i < nb_updated_attr;i++) { updated_attr.push_back(dev_attr->get_attr_ind_by_name(values[i].name)); } // // Check that these attributes are writable // for (i = 0;i < nb_updated_attr;i++) { if ((dev_attr->get_attr_by_ind(updated_attr[i]).get_writable() == Tango::READ) || (dev_attr->get_attr_by_ind(updated_attr[i]).get_writable() == Tango::READ_WITH_WRITE)) { TangoSys_OMemStream o; o << "Attribute "; o << dev_attr->get_attr_by_ind(updated_attr[i]).get_name(); o << " is not writable" << ends; Except::throw_exception((const char *)API_AttrNotWritable, o.str(), (const char *)"DeviceImpl::write_attributes"); } } // // Call the always_executed_hook // always_executed_hook(); // // Set attribute internal value // for (i = 0;i < nb_updated_attr;i++) { try { dev_attr->get_w_attr_by_ind(updated_attr[i]).check_written_value(values[i].value,(unsigned long)1,(unsigned long)0); } catch (Tango::DevFailed &) { for (long j = 0;j < i;j++) dev_attr->get_w_attr_by_ind(updated_attr[j]).rollback(); throw; } } // // Write the hardware // long vers = get_dev_idl_version(); if (vers < 3) { write_attr_hardware(updated_attr); for (i = 0;i < nb_updated_attr;i++) { WAttribute &att = dev_attr->get_w_attr_by_ind(updated_attr[i]); att.copy_data(values[i].value); } } else { vector att_in_db; for (i = 0;i < nb_updated_attr;i++) { WAttribute &att = dev_attr->get_w_attr_by_ind(updated_attr[i]); vector &attr_vect = device_class->get_class_attr()->get_attr_list(); if (attr_vect[att.get_attr_idx()]->is_allowed(this,Tango::WRITE_REQ) == false) { TangoSys_OMemStream o; o << "It is currently not allowed to write attribute "; o << att.get_name(); o << ". The device state is " << Tango::DevStateName[get_state()] << ends; Except::throw_exception((const char *)API_AttrNotAllowed, o.str(), (const char *)"Device_Impl::write_attributes"); } attr_vect[att.get_attr_idx()]->write(this,att); att.copy_data(values[i].value); if (att.is_memorized() == true) att_in_db.push_back(i); if (att.is_alarmed().test(Attribute::rds) == true) att.set_written_date(); } if ((Tango::Util::_UseDb == true) && (att_in_db.empty() == false)) { try { static_cast(this)->write_attributes_in_db(att_in_db,updated_attr); } catch (Tango::DevFailed &e) { Except::re_throw_exception(e,(const char *)API_AttrNotAllowed, (const char *)"Failed to store memorized attribute value in db", (const char *)"Device_Impl::write_attributes"); } } } } catch (...) { // set back the device attribution for the thread // and rethrow the exception. sub.set_associated_device(last_associated_device); throw; } // set back the device attribution for the thread sub.set_associated_device(last_associated_device); // // Return to caller. // cout4 << "Leaving DeviceImpl::write_attributes" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::add_attribute // // description : // Add attribute to the device attribute(s) list // // argument: // in : // - new_attr: The new attribute to be added. // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::add_attribute(Tango::Attr *new_attr) { // // Take the device monitor in order to protect the attribute list // AutoTangoMonitor sync(this,true); vector &attr_list = device_class->get_class_attr()->get_attr_list(); long old_attr_nb = attr_list.size(); // // Check that this attribute is not already defined for this device. If it is already there, immediately returns. // Trick : If you add an attribute to a device, this attribute will be inserted in the device class attribute list. // Therefore, all devices created after this attribute addition will also have this attribute. // string &attr_name = new_attr->get_name(); bool already_there = true; bool throw_ex = false; try { Tango::Attribute &al_attr = dev_attr->get_attr_by_name(attr_name.c_str()); if ((al_attr.get_data_type() != new_attr->get_type()) || (al_attr.get_data_format() != new_attr->get_format()) || (al_attr.get_writable() != new_attr->get_writable())) { throw_ex = true; } } catch (Tango::DevFailed &) { already_there = false; } // // Throw exception if the device already have an attribute with the same name but with a different definition // if (throw_ex == true) { TangoSys_OMemStream o; o << "Device " << get_name() << " -> Attribute " << attr_name << " already exists for your device but with other definition"; o << "\n(data type, data format or data write type)" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"DeviceImpl::add_attribute"); } if (already_there == true) { delete new_attr; return; } // // If device is IDL 5 or more and if enabled, and if there is some client(s) listening on the device interface // change event, get device interface. // ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); bool ev_client = event_supplier_zmq->any_dev_intr_client(this); if (idl_version >= MIN_IDL_DEV_INTR && is_intr_change_ev_enable() == true) { if (ev_client == true) { bool th_running; { omni_mutex_lock lo(devintr_mon); th_running = devintr_shared.th_running; } if (th_running == false) devintr_shared.interface.get_interface(this); } } // // Add this attribute in the MultiClassAttribute attr_list vector if it does not already exist // bool need_free = false; long i; for (i = 0;i < old_attr_nb;i++) { if ((attr_list[i]->get_name() == attr_name) && (attr_list[i]->get_cl_name() == new_attr->get_cl_name())) { need_free = true; break; } } if (i == old_attr_nb) { attr_list.push_back(new_attr); // // Get all the properties defined for this attribute at class level // device_class->get_class_attr()->init_class_attribute( device_class->get_name(), old_attr_nb); } else { // // An attribute with the same name is already defined within the class. Check if the data type, data format and // write type are the same // if ((attr_list[i]->get_type() != new_attr->get_type()) || (attr_list[i]->get_format() != new_attr->get_format()) || (attr_list[i]->get_writable() != new_attr->get_writable())) { TangoSys_OMemStream o; o << "Device " << get_name() << " -> Attribute " << attr_name << " already exists for your device class but with other definition"; o << "\n(data type, data format or data write type)" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"DeviceImpl::add_attribute"); } } // // Add the attribute to the MultiAttribute object // if (new_attr->is_fwd() == true) { dev_attr->add_fwd_attribute(device_name,device_class,i,new_attr); } else dev_attr->add_attribute(device_name,device_class,i); // // Eventually start or update device interface change event thread // push_dev_intr(ev_client); // // If attribute has to be polled (set by Pogo), start polling now // long per = new_attr->get_polling_period(); Tango::Util *tg = Tango::Util::instance(); if (tg->is_svr_starting() == false && per != 0) poll_attribute(attr_name,per); // // Free memory if needed // if (need_free == true) delete new_attr; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::remove_attribute // // description : // Remove attribute to the device attribute(s) list // // argument: // in : // - rem_attr: The attribute to be deleted. // - free_it : Free Attr object flag // - clean_db : Clean attribute related info in db // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::remove_attribute(Tango::Attr *rem_attr, bool free_it,bool clean_db) { // // Take the device monitor in order to protect the attribute list // AutoTangoMonitor sync(this,true); // // Check that the class support this attribute // string &attr_name = rem_attr->get_name(); try { dev_attr->get_attr_by_name(attr_name.c_str()); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Attribute " << attr_name << " is not defined as attribute for your device."; o << "\nCan't remove it" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"DeviceImpl::remove_attribute"); } // // If device is IDL 5 or more and if enabled, and if there is some client(s) listening on the device interface // change event, get device interface. // ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); bool ev_client = event_supplier_zmq->any_dev_intr_client(this); if (idl_version >= MIN_IDL_DEV_INTR && is_intr_change_ev_enable() == true) { if (ev_client == true) { bool th_running; { omni_mutex_lock lo(devintr_mon); th_running = devintr_shared.th_running; } if (th_running == false) devintr_shared.interface.get_interface(this); } } // // stop any configured polling for this attribute first! // vector &poll_attr = get_polled_attr(); vector::iterator ite_attr; string attr_name_low(attr_name); transform(attr_name_low.begin(),attr_name_low.end(),attr_name_low.begin(),::tolower); // // Try to find the attribute in the list of polled attributes // Tango::Util *tg = Tango::Util::instance(); ite_attr = find(poll_attr.begin(),poll_attr.end(), attr_name_low); if (ite_attr != poll_attr.end()) { // stop the polling and clean-up the database DServer *adm_dev = tg->get_dserver_device(); DevVarStringArray send; send.length(3); send[0] = CORBA::string_dup(device_name.c_str()); send[1] = CORBA::string_dup("attribute"); send[2] = CORBA::string_dup(attr_name.c_str()); if (tg->is_svr_shutting_down() == true) { // // There is no need to stop the polling because we are in the server shutdown sequence and the polling is // already stopped. // if (clean_db == true && Tango::Util::_UseDb == true) { // // Memorize the fact that the dynamic polling properties has to be removed from db. // The classical attribute properties as well // tg->get_polled_dyn_attr_names().push_back(attr_name_low); if (tg->get_full_polled_att_list().size() == 0) { tg->get_full_polled_att_list() = poll_attr; tg->get_dyn_att_dev_name() = device_name; } } } else { if (tg->is_device_restarting(get_name()) == false) adm_dev->rem_obj_polling(&send, clean_db); } } // // Now remove all configured attribute properties from the database. Do it in one go if the Db server support this // if (clean_db == true) { if ((tg->is_svr_shutting_down() == false) || (tg->get_database()->get_server_release() < 400)) { Tango::Attribute &att_obj = dev_attr->get_attr_by_name(attr_name.c_str()); att_obj.remove_configuration(); } else { tg->get_all_dyn_attr_names().push_back(attr_name); if (tg->get_dyn_att_dev_name().size() == 0) tg->get_dyn_att_dev_name() = device_name; } } // // Remove attribute in MultiClassAttribute in case there is only one device in the class or it is the last device // in this class with this attribute // bool update_idx = false; unsigned long nb_dev = device_class->get_device_list().size(); if (nb_dev <= 1) { device_class->get_class_attr()->remove_attr(attr_name,rem_attr->get_cl_name()); update_idx = true; } else { vector dev_list = device_class->get_device_list(); unsigned long nb_except = 0; for (unsigned long i = 0;i < nb_dev;i++) { try { Attribute &att = dev_list[i]->get_device_attr()->get_attr_by_name(attr_name.c_str()); vector &attr_list = device_class->get_class_attr()->get_attr_list(); if (attr_list[att.get_attr_idx()]->get_cl_name() != rem_attr->get_cl_name()) nb_except++; } catch (Tango::DevFailed &) { nb_except++; } } if (nb_except == (nb_dev - 1)) { device_class->get_class_attr()->remove_attr(attr_name,rem_attr->get_cl_name()); update_idx = true; } } // // Now, remove the attribute from the MultiAttribute object // dev_attr->remove_attribute(attr_name,update_idx); // // Delete Attr object if wanted // if ((free_it == true) && (update_idx == true)) delete rem_attr; // // Eventually start or update device interface change event thread // push_dev_intr(ev_client); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::remove_attribute // // description : // Remove attribute to the device attribute(s) list // // argument: // in : // - rem_attr: The name of the attribute to be deleted. // - free_it : Free Attr object flag // - clean_db : Clean attribute related info in db // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::remove_attribute(string &rem_attr_name, bool free_it,bool clean_db) { try { Attr &att = device_class->get_class_attr()->get_attr(rem_attr_name); remove_attribute(&att,free_it,clean_db); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Attribute " << rem_attr_name << " is not defined as attribute for your device."; o << "\nCan't remove it" << ends; Except::re_throw_exception(e,(const char *)API_AttrNotFound, o.str(), (const char *)"DeviceImpl::remove_attribute"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::add_command // // description : // Add command to the device command(s) list // // argument: // in : // - new_cmd: The new command to be added. // - device_level : flag set to true if the command must be added at the device level (instead of class level) // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::add_command(Tango::Command *new_cmd,bool device_level) { // // Take the device monitor in order to protect the command list // AutoTangoMonitor sync(this,true); // // Check that this command is not already defined for this device. If it is already there, immediately returns. // string &cmd_name = new_cmd->get_name(); bool already_there = true; bool throw_ex = false; try { Tango::Command &al_cmd = device_class->get_cmd_by_name(cmd_name); if ((al_cmd.get_in_type() != new_cmd->get_in_type()) || (al_cmd.get_out_type() != new_cmd->get_out_type())) { throw_ex = true; } } catch (Tango::DevFailed &) { already_there = false; } if (already_there == false) { already_there = true; try { Tango::Command &al_cmd_dev = get_local_cmd_by_name(cmd_name); if ((al_cmd_dev.get_in_type() != new_cmd->get_in_type()) || (al_cmd_dev.get_out_type() != new_cmd->get_out_type())) { throw_ex = true; } } catch (Tango::DevFailed &) { already_there = false; } } // // Throw exception if the device already have a command with the same name but with a different definition // if (throw_ex == true) { TangoSys_OMemStream o; o << "Device " << get_name() << " -> Command " << cmd_name << " already exists for your device but with other definition"; o << "\n(command input data type or command output data type)" << ends; Except::throw_exception(API_CommandNotFound,o.str(),"DeviceImpl::add_command"); } if (already_there == true) { delete new_cmd; return; } // // If device is IDL 5 or more and if enabled, and if there is some client(s) listening on the device interface // change event, get device interface. // ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); bool ev_client = event_supplier_zmq->any_dev_intr_client(this); if (idl_version >= MIN_IDL_DEV_INTR && is_intr_change_ev_enable() == true) { if (ev_client == true) { bool th_running; { omni_mutex_lock lo(devintr_mon); th_running = devintr_shared.th_running; } if (th_running == false) devintr_shared.interface.get_interface(this); } } // // Add this command to the command list // if (device_level == false) { vector &cmd_list = device_class->get_command_list(); cmd_list.push_back(new_cmd); } else { vector &dev_cmd_list = get_local_command_list(); dev_cmd_list.push_back(new_cmd); } // // Eventually start or update device interface change event thread // push_dev_intr(ev_client); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::remove_command // // description : // Remove command to the device command(s) list // // argument: // in : // - rem_cmd: The command to be deleted. // - free_it : Free Command object flag // - clean_db : Clean command related info in db // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::remove_command(Tango::Command *rem_cmd, bool free_it,bool clean_db) { // // Take the device monitor in order to protect the command list // AutoTangoMonitor sync(this,true); // // Check that the class or the device support this command // string &cmd_name = rem_cmd->get_name(); bool device_cmd = false; try { device_class->get_cmd_by_name(cmd_name); } catch (Tango::DevFailed &) { try { get_local_cmd_by_name(cmd_name); device_cmd = true; } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Command " << cmd_name << " is not defined as command for your device."; o << "\nCan't remove it" << ends; Except::throw_exception(API_CommandNotFound,o.str(),"DeviceImpl::remove_command"); } } // // If device is IDL 5 or more and if enabled, and if there is some client(s) listening on the device interface // change event, get device interface. // ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); bool ev_client = event_supplier_zmq->any_dev_intr_client(this); if (idl_version >= MIN_IDL_DEV_INTR && is_intr_change_ev_enable() == true) { if (ev_client == true) { bool th_running; { omni_mutex_lock lo(devintr_mon); th_running = devintr_shared.th_running; } if (th_running == false) devintr_shared.interface.get_interface(this); } } // // stop any configured polling for this command first! // vector &poll_cmd = get_polled_cmd(); vector::iterator ite_cmd; string cmd_name_low(cmd_name); transform(cmd_name_low.begin(),cmd_name_low.end(),cmd_name_low.begin(),::tolower); // // Try to find the command in the list of polled commands // Tango::Util *tg = Tango::Util::instance(); ite_cmd = find(poll_cmd.begin(),poll_cmd.end(), cmd_name_low); if (ite_cmd != poll_cmd.end()) { // stop the polling and clean-up the database DServer *adm_dev = tg->get_dserver_device(); DevVarStringArray send; send.length(3); send[0] = CORBA::string_dup(device_name.c_str()); send[1] = CORBA::string_dup("command"); send[2] = CORBA::string_dup(cmd_name.c_str()); if (tg->is_svr_shutting_down() == true) { // // There is no need to stop the polling because we are in the server shutdown sequence and the polling is // already stopped. // if (clean_db == true && Tango::Util::_UseDb == true) { // // Memorize the fact that the dynamic polling properties has to be removed from db. // tg->get_polled_dyn_cmd_names().push_back(cmd_name_low); if (tg->get_full_polled_cmd_list().size() == 0) { tg->get_full_polled_cmd_list() = poll_cmd; tg->get_dyn_cmd_dev_name() = device_name; } } } else { if (tg->is_device_restarting(get_name()) == false) adm_dev->rem_obj_polling(&send,clean_db); } } // // Now, remove the command from the command list // if (device_cmd == false) device_class->remove_command(cmd_name_low); else remove_local_command(cmd_name_low); // // Delete Command object if wanted // if (free_it == true) delete rem_cmd; // // Eventually start or update device interface change event thread // push_dev_intr(ev_client); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::remove_command // // description : // Remove command to the device command(s) list // // argument: // in : // - rem_cmd_name: The name of the command to be deleted. // - free_it : Free Command object flag // - clean_db : Clean command related info in db // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::remove_command(const string &rem_cmd_name, bool free_it,bool clean_db) { // // Search for command first at class level and then at device level (for dynamic cmd) // try { Command &cmd = device_class->get_cmd_by_name(rem_cmd_name); remove_command(&cmd,free_it,clean_db); } catch (Tango::DevFailed &e) { try { Command &cmd = get_local_cmd_by_name(rem_cmd_name); remove_command(&cmd,free_it,clean_db); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Command " << rem_cmd_name << " is not defined as a command for your device."; o << "\nCan't remove it" << ends; Except::re_throw_exception(e,API_CommandNotFound,o.str(),"DeviceImpl::remove_command"); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::poll_lists_2_v5 // // description : // Started from Tango V5, state and status are polled as attributes. Previously, they were polled as commands. // If state or status are polled as commands, move them to the list of polled attributes // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::poll_lists_2_v5() { bool db_update = false; vector &poll_cmd = get_polled_cmd(); vector &poll_attr = get_polled_attr(); vector::iterator ite_state; vector::iterator ite_status; // // Try to find state in list of polled command(s). If found, remove it from poll cmd and move it to poll attr // ite_state = find(poll_cmd.begin(),poll_cmd.end(),"state"); if (ite_state != poll_cmd.end()) { poll_attr.push_back(*ite_state); poll_attr.push_back(*(ite_state + 1)); poll_cmd.erase(ite_state,ite_state + 2); db_update = true; } // // The same for status // ite_status = find(poll_cmd.begin(),poll_cmd.end(),"status"); if (ite_status != poll_cmd.end()) { poll_attr.push_back(*ite_status); poll_attr.push_back(*(ite_status + 1)); poll_cmd.erase(ite_status,ite_status + 2); db_update = true; } // // Now update database if needed // if (db_update == true) { DbDatum p_cmd("polled_cmd"); DbDatum p_attr("polled_attr"); p_cmd << poll_cmd; p_attr << poll_attr; DbData db_data; db_data.push_back(p_cmd); db_data.push_back(p_attr); get_db_device()->put_property(db_data); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Attribute::init_cmd_poll_ext_trig // // description : // Write the command name to the list of polled commands in the database. The polling period is set to 0 to // indicate that the polling buffer is filled externally from the device server code. // // args : // in : // - cmd_name : The command name // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::init_cmd_poll_ext_trig(string cmd_name) { string cmd_lowercase(cmd_name); transform(cmd_lowercase.begin(),cmd_lowercase.end(),cmd_lowercase.begin(),::tolower); // // never do the for the state or status commands, they are handled as attributes! // if ( cmd_name == "state" || cmd_name == "status" ) { TangoSys_OMemStream o; o << "State and status are handled as attributes for the polling" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceImpl::init_poll_ext_trig"); } // // check whether the command exists for the device and can be polled // check_command_exists (cmd_lowercase); // // check wether the database is used // Tango::Util *tg = Tango::Util::instance(); if ( tg->_UseDb == true ) { vector &poll_list = get_polled_cmd(); Tango::DbData poll_data; bool found = false; poll_data.push_back(Tango::DbDatum("polled_cmd")); if (poll_list.empty() == false) { // // search the attribute in the list of polled attributes // for (unsigned int i = 0;i < poll_list.size();i = i+2) { string name_lowercase(poll_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( name_lowercase == cmd_lowercase) { poll_list[i+1] = "0"; found = true; } } } if ( found == false ) { poll_list.push_back (cmd_lowercase); poll_list.push_back ("0"); } poll_data[0] << poll_list; tg->get_database()->put_device_property(device_name, poll_data); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_cmd_poll_period // // description : // Checks the specified polling period for all commands of the device. If a polling period is specified for a // command the command name and the period are written to the list of polled commands in the database. // This happens only if the command is not yet in the list of polled commands. // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::init_cmd_poll_period() { // // check wether the database is used // Tango::Util *tg = Tango::Util::instance(); if ( tg->_UseDb == true ) { vector &poll_list = get_polled_cmd(); Tango::DbData poll_data; poll_data.push_back(Tango::DbDatum("polled_cmd")); // // get the command list // vector &cmd_list = device_class->get_command_list(); // // loop over the command list // unsigned long added_cmd = 0; unsigned long i; for (i = 0;i < cmd_list.size();i++) { long poll_period; poll_period = cmd_list[i]->get_polling_period(); // // check the validity of the polling period. must be longer than min polling period // if ( poll_period < MIN_POLL_PERIOD ) { continue; } // // never do the for the state or status commands, they are handled as attributes! // string cmd_name = cmd_list[i]->get_lower_name(); if ( cmd_name == "state" || cmd_name == "status" ) { continue; } // // Can only handle commands without input argument // if (cmd_list[i]->get_in_type() != Tango::DEV_VOID) { continue; } // // search the command in the list of polled commands // bool found = false; for (unsigned int i = 0;i < poll_list.size();i = i+2) { string name_lowercase(poll_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( name_lowercase == cmd_name) { found = true; break; } } if ( found == false ) { string period_str; stringstream str; str << poll_period << ends; str >> period_str; poll_list.push_back (cmd_name); poll_list.push_back (period_str); added_cmd++; } } // // only write to the database when a polling need to be added // if ( added_cmd > 0 ) { poll_data[0] << poll_list; tg->get_database()->put_device_property(device_name, poll_data); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Attribute::init_attr_poll_ext_trig // // description : // Write the attribute name to the list of polled attributes in the database. The polling period is set to 0 // to indicate that the polling buffer is filled externally from the device server code. // // args : // in : // - attr_name : The attribute name // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::init_attr_poll_ext_trig(string attr_name) { string attr_lowercase(attr_name); transform(attr_lowercase.begin(),attr_lowercase.end(),attr_lowercase.begin(),::tolower); // // check whether the attribute exists for the device and can be polled // dev_attr->get_attr_by_name (attr_lowercase.c_str()); // // check wether the database is used // Tango::Util *tg = Tango::Util::instance(); if ( tg->_UseDb == true ) { vector &poll_list = get_polled_attr(); Tango::DbData poll_data; bool found = false; poll_data.push_back(Tango::DbDatum("polled_attr")); // // read the polling configuration from the database // if (poll_list.empty() == false) { // // search the attribute in the list of polled attributes // for (unsigned int i = 0;i < poll_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(poll_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( name_lowercase == attr_lowercase) { if ( poll_list[i+1] == "0" ) { // // The configuration is already correct, no need for further action // return; } else { poll_list[i+1] = "0"; found = true; } } } } if ( found == false ) { poll_list.push_back (attr_lowercase); poll_list.push_back ("0"); } poll_data[0] << poll_list; tg->get_database()->put_device_property(device_name, poll_data); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::init_attr_poll_period // // description : // Checks the specified polling period for all attributes of the device. If a polling period is specified for an // attribute the attribute name and the period are written to the list of polled attributes in the database. // This happens only if the attribute is not yet in the list of polled attributes. // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::init_attr_poll_period() { // // check wether the database is used // Tango::Util *tg = Tango::Util::instance(); if ( tg->_UseDb == true ) { vector &poll_list = get_polled_attr(); Tango::DbData poll_data; poll_data.push_back(Tango::DbDatum("polled_attr")); // // get the multi attribute object // vector &attr_list = dev_attr->get_attribute_list(); // // loop over the attribute list // unsigned long added_attr = 0; unsigned long i; for (i = 0;i < attr_list.size();i++) { string &attr_name = attr_list[i]->get_name_lower(); // // Special case for state and status attributes. They are polled as attribute but they are managed by Pogo as // commands (historical reasons). If the polling is set in the state or status defined as command, report this info // when they are defined as attributes // if (attr_name == "state") { Command &state_cmd = device_class->get_cmd_by_name("state"); long state_poll_period = state_cmd.get_polling_period(); if (state_poll_period != 0) { attr_list[i]->set_polling_period(state_poll_period); } } if (attr_name == "status") { Command &status_cmd = device_class->get_cmd_by_name("status"); long status_poll_period = status_cmd.get_polling_period(); if (status_poll_period != 0) { attr_list[i]->set_polling_period(status_poll_period); } } long poll_period; poll_period = attr_list[i]->get_polling_period(); // // check the validity of the polling period. must be longer than 20ms // if ( poll_period < MIN_POLL_PERIOD ) { continue; } // // search the attribute in the list of polled attributes // bool found = false; for (unsigned int i = 0;i < poll_list.size();i = i+2) { // // Convert to lower case before comparison // string name_lowercase(poll_list[i]); transform(name_lowercase.begin(),name_lowercase.end(),name_lowercase.begin(),::tolower); if ( name_lowercase == attr_name) { found = true; break; } } if ( found == false ) { string period_str; stringstream str; str << poll_period << ends; str >> period_str; poll_list.push_back (attr_name); poll_list.push_back (period_str); added_attr++; } } // // only write to the database when a polling need to be added // if ( added_attr > 0 ) { poll_data[0] << poll_list; tg->get_database()->put_device_property(device_name, poll_data); } // // Another loop to correctly initialize polling period data in Attribute instance // for (unsigned int i = 0;i < poll_list.size();i = i+2) { try { Attribute &att = dev_attr->get_attr_by_name(poll_list[i].c_str()); stringstream ss; long per; ss << poll_list[i + 1]; ss >> per; if (ss) att.set_polling_period(per); } catch (Tango::DevFailed &) {} } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_att_conf_event // // description : // Push an attribute configuration event // // args : // in : // - attr : The attribute // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_att_conf_event(Attribute *attr) { EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; Tango::Util *tg = Tango::Util::instance(); if (attr->use_notifd_event() == true) event_supplier_nd = tg->get_notifd_event_supplier(); if (attr->use_zmq_event() == true) event_supplier_zmq = tg->get_zmq_event_supplier(); if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL)) { EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); long vers = get_dev_idl_version(); if (vers <= 2) { Tango::AttributeConfig_2 attr_conf_2; attr->get_properties(attr_conf_2); ad.attr_conf_2 = &attr_conf_2; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); } else if (vers <= 4) { Tango::AttributeConfig_3 attr_conf_3; attr->get_properties(attr_conf_3); ad.attr_conf_3 = &attr_conf_3; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); } else { Tango::AttributeConfig_5 attr_conf_5; attr->get_properties(attr_conf_5); ad.attr_conf_5 = &attr_conf_5; if (event_supplier_nd != NULL) event_supplier_nd->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); if (event_supplier_zmq != NULL) event_supplier_zmq->push_att_conf_events(this,ad,(Tango::DevFailed *)NULL,attr->get_name()); } } } //+---------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_client_ident() // // description : // Get client identification. This method returns a pointer to the client identification // //----------------------------------------------------------------------------------------------------------------- Tango::client_addr *DeviceImpl::get_client_ident() { omni_thread::value_t *ip = omni_thread::self()->get_value(key); return (client_addr *)ip; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::lock // // description : // Lock the device // // args : // in : // - cl : The client identification // - validity : The lock validity // //----------------------------------------------------------------------------------------------------------------- void DeviceImpl::lock(client_addr *cl,int validity) { // // Check if the device is already locked and if it is a valid lock. If the lock is not valid any more, clear it // if (device_locked == true) { if (valid_lock() == true) { if (*cl != *(locker_client)) { TangoSys_OMemStream o; o << "Device " << get_name() << " is already locked by another client" << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(), (const char *)"Device_Impl::lock"); } } else { basic_unlock(); } } // // Lock the device // device_locked = true; if (locker_client == NULL) { locker_client = new client_addr(*cl); } locking_date = time(NULL); lock_validity = validity; lock_ctr++; // // Also lock root device(s) in case it is needed (due to forwarded attributes) // if (get_with_fwd_att() == true) lock_root_devices(validity,true); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::relock // // description : // ReLock the device // // args : // in : // - cl : The client identification // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::relock(client_addr *cl) { // // Check if the device is already locked and if it is a valid lock. A ReLock is valid only if the device is already // locked by the same client and if this lock is valid // if (device_locked == true) { if (valid_lock() == true) { if (*cl != *(locker_client)) { TangoSys_OMemStream o; o << get_name() << ": "; o << "Device " << get_name() << " is already locked by another client" << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(), (const char *)"Device_Impl::relock"); } device_locked = true; locking_date = time(NULL); } else { TangoSys_OMemStream o; o << get_name() << ": "; o << "Device " << get_name() << " is not locked. Can't re-lock it" << ends; Except::throw_exception((const char *)API_DeviceNotLocked,o.str(), (const char *)"Device_Impl::relock"); } } else { TangoSys_OMemStream o; o << get_name() << ": "; o << "Device " << get_name() << " is not locked. Can't re-lock it" << ends; Except::throw_exception((const char *)API_DeviceNotLocked,o.str(), (const char *)"Device_Impl::relock"); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::unlock // // description : // Unlock the device // // args : // in : // - forced : Flag set to true if the unlock is forced // //----------------------------------------------------------------------------------------------------------------- Tango::DevLong DeviceImpl::unlock(bool forced) { // // Check if the device is already locked and if it is a valid lock. If the lock is not valid any more, clear it // if (device_locked == true) { if (valid_lock() == true) { client_addr *cl = get_client_ident(); if (forced == false) { if (*cl != *(locker_client)) { TangoSys_OMemStream o; o << "Device " << get_name() << " is locked by another client, can't unlock it" << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(), (const char *)"Device_Impl::unlock"); } } } } if (lock_ctr > 0) lock_ctr--; if ((lock_ctr <= 0) || (forced == true)) basic_unlock(forced); return lock_ctr; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::basic_unlock // // description : // Mark the device as unlocked // // args : // in : // - forced : Flag set to true if the unlock is forced // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::basic_unlock(bool forced) { device_locked = false; if (forced == true) old_locker_client = locker_client; else delete locker_client; locker_client = NULL; lock_ctr = 0; // // Also unlock root device(s) in case it is needed (due to forwarded attributes) // if (get_with_fwd_att() == true) lock_root_devices(0,false); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::valid_lock // // description : // Check lock validity (according to lock validity time). This method returns true if the lock is still valid. // Otherwise, returns false // //------------------------------------------------------------------------------------------------------------------- bool DeviceImpl::valid_lock() { time_t now = time(NULL); if (now > (locking_date + lock_validity)) return false; else return true; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::lock_status // // description : // Build a device locking status // This method returns a sequence with longs and strings. The strings contain: // 1 - The locker process hostname // 2 - The java main class (in case of Java locker) // 3 - A string which summarizes the locking status // The longs contain: // 1 - A locked flag (0 means not locked, 1 means locked) // 2 - The locker process PID (C++ client) // 3 - The locker UUID (Java client) which needs 4 longs // //------------------------------------------------------------------------------------------------------------------ Tango::DevVarLongStringArray *DeviceImpl::lock_status() { Tango::DevVarLongStringArray *dvlsa = new Tango::DevVarLongStringArray(); dvlsa->lvalue.length(6); dvlsa->svalue.length(3); // // Check if the device is already locked and if it is a valid lock. If the lock is not valid any more, clear it // if (device_locked == true) { if (valid_lock() == true) { lock_stat = "Device " + device_name + " is locked by "; ostringstream ostr; ostr << *(locker_client) << ends; lock_stat = lock_stat + ostr.str(); dvlsa->lvalue[0] = 1; dvlsa->lvalue[1] = locker_client->client_pid; const char *tmp = locker_client->client_ip; dvlsa->svalue[1] = CORBA::string_dup(tmp); if (locker_client->client_lang == Tango::JAVA) { dvlsa->svalue[2] = CORBA::string_dup(locker_client->java_main_class.c_str()); Tango::DevULong64 tmp_data = locker_client->java_ident[0]; dvlsa->lvalue[2] = (DevLong)((tmp_data & 0xFFFFFFFF00000000LL) >> 32); dvlsa->lvalue[3] = (DevLong)(tmp_data & 0xFFFFFFFF); tmp_data = locker_client->java_ident[1]; dvlsa->lvalue[4] = (DevLong)((tmp_data & 0xFFFFFFFF00000000LL) >> 32); dvlsa->lvalue[5] = (DevLong)(tmp_data & 0xFFFFFFFF); } else { dvlsa->svalue[2] = CORBA::string_dup("Not defined"); for (long loop = 2;loop < 6;loop++) dvlsa->lvalue[loop] = 0; } } else { basic_unlock(); lock_stat = "Device " + device_name + " is not locked"; dvlsa->svalue[1] = CORBA::string_dup("Not defined"); dvlsa->svalue[2] = CORBA::string_dup("Not defined"); for (long loop = 0;loop < 6;loop++) dvlsa->lvalue[loop] = 0; } } else { lock_stat = "Device " + device_name + " is not locked"; dvlsa->svalue[1] = CORBA::string_dup("Not defined"); dvlsa->svalue[2] = CORBA::string_dup("Not defined"); for (long loop = 0;loop < 6;loop++) dvlsa->lvalue[loop] = 0; } dvlsa->svalue[0] = CORBA::string_dup(lock_stat.c_str()); return dvlsa; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::set_locking_param // // description : // Restore device locking parameter // // args : // in : // - cl : Locker // - old_cl : Previous locker // - date : Locking date // - ctr : Locking counter // - valid : Locking validity // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::set_locking_param(client_addr *cl,client_addr *old_cl,time_t date,DevLong ctr,DevLong valid) { locker_client = cl; old_locker_client = old_cl; locking_date = date; lock_ctr = ctr; device_locked = true; lock_validity = valid; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::check_lock // // description : // Method called for each command_inout operation executed from any client on a Tango device. // // argument: // in : // - meth : Method name (for error message) // - cmd : Command name // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::check_lock(const char *meth,const char *cmd) { if (device_locked == true) { if (valid_lock() == true) { client_addr *cl = get_client_ident(); if (cl->client_ident == false) { // // Old client, before throwing the exception, in case the CORBA operation is a command_inout, checks if the command // is an "allowed" one // if (cmd != NULL) { if (device_class->is_command_allowed(cmd) == false) { throw_locked_exception(meth); } } else throw_locked_exception(meth); } if (*cl != *(locker_client)) { // // Wrong client, before throwing the exception, in case the CORBA operation is a command_inout, checks if the command // is an "allowed" one // if (cmd != NULL) { if (device_class->is_command_allowed(cmd) == false) { throw_locked_exception(meth); } } else throw_locked_exception(meth); } } else { basic_unlock(); } } else { client_addr *cl = get_client_ident(); if (old_locker_client != NULL) { if (*cl == (*old_locker_client)) { TangoSys_OMemStream o; TangoSys_OMemStream o2; o << "Device " << get_name() << " has been unlocked by an administrative client!!!" << ends; o2 << "Device_Impl::" << meth << ends; Except::throw_exception((const char *)DEVICE_UNLOCKED_REASON,o.str(),o2.str()); } delete old_locker_client; old_locker_client = NULL; } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::throw_locked_exception() // // description : // Throw a DeviceLocked exception // // argument: // in : // - meth : Method name // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::throw_locked_exception(const char *meth) { TangoSys_OMemStream o; TangoSys_OMemStream o2; o << "Device " << get_name() << " is locked by another client" << ends; o2 << "Device_Impl::" << meth << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(),o2.str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::data_into_net_obj // // description : // Put the attribute data within the object used on the wire to transfer the attribute. For IDL release <= 3, // it's an Any object. Then, it is an IDL union // // argument: // in : // - att : // - aid : // - index : // - w_type : // - del_seq : // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::data_into_net_object(Attribute &att,AttributeIdlData &aid, long index,AttrWriteType w_type,bool del_seq) { // // A big switch according to attribute data type // switch (att.get_data_type()) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { DATA_IN_OBJECT(DevVarShortArray,get_short_value,dummy_short_att_value,short_att_value); break; } case Tango::DEV_LONG : { DATA_IN_OBJECT(DevVarLongArray,get_long_value,dummy_long_att_value,long_att_value); break; } case Tango::DEV_LONG64 : { DATA_IN_OBJECT(DevVarLong64Array,get_long64_value,dummy_long64_att_value,long64_att_value); break; } case Tango::DEV_DOUBLE : { DATA_IN_OBJECT(DevVarDoubleArray,get_double_value,dummy_double_att_value,double_att_value); break; } case Tango::DEV_STRING : { DATA_IN_OBJECT(DevVarStringArray,get_string_value,dummy_string_att_value,string_att_value); break; } case Tango::DEV_FLOAT : { DATA_IN_OBJECT(DevVarFloatArray,get_float_value,dummy_float_att_value,float_att_value); break; } case Tango::DEV_BOOLEAN : { DATA_IN_OBJECT(DevVarBooleanArray,get_boolean_value,dummy_boolean_att_value,bool_att_value); break; } case Tango::DEV_USHORT : { DATA_IN_OBJECT(DevVarUShortArray,get_ushort_value,dummy_ushort_att_value,ushort_att_value); break; } case Tango::DEV_UCHAR : { DATA_IN_OBJECT(DevVarCharArray,get_uchar_value,dummy_uchar_att_value,uchar_att_value); break; } case Tango::DEV_ULONG : { DATA_IN_OBJECT(DevVarULongArray,get_ulong_value,dummy_ulong_att_value,ulong_att_value); break; } case Tango::DEV_ULONG64 : { DATA_IN_OBJECT(DevVarULong64Array,get_ulong64_value,dummy_ulong64_att_value,ulong64_att_value); break; } case Tango::DEV_STATE : { DATA_IN_OBJECT(DevVarStateArray,get_state_value,dummy_state_att_value,state_att_value); break; } case Tango::DEV_ENCODED : { if (aid.data_3 != Tango_nullptr) { (*aid.data_3)[index].err_list.length(1); (*aid.data_3)[index].err_list[0].severity = Tango::ERR; (*aid.data_3)[index].err_list[0].reason = CORBA::string_dup(API_NotSupportedFeature); (*aid.data_3)[index].err_list[0].origin = CORBA::string_dup("Device_3Impl::read_attributes_no_except"); (*aid.data_3)[index].err_list[0].desc = CORBA::string_dup("The DevEncoded data type is available only for device implementing IDL 4 and above"); (*aid.data_3)[index].quality = Tango::ATTR_INVALID; (*aid.data_3)[index].name = CORBA::string_dup(att.get_name().c_str()); clear_att_dim((*aid.data_3)[index]); } else { Tango::DevVarEncodedArray *ptr = att.get_encoded_value(); if (aid.data_5 != Tango_nullptr) { (*aid.data_5)[index].value.encoded_att_value(dummy_encoded_att_value); DevVarEncodedArray &the_seq = (*aid.data_5)[index].value.encoded_att_value(); if ((w_type == Tango::READ) || (w_type == Tango::WRITE)) the_seq.length(1); else the_seq.length(2); the_seq[0].encoded_format = CORBA::string_dup((*ptr)[0].encoded_format); if (ptr->release() == true) { unsigned long nb_data = (*ptr)[0].encoded_data.length(); the_seq[0].encoded_data.replace(nb_data,nb_data,(*ptr)[0].encoded_data.get_buffer(true),true); (*ptr)[0].encoded_data.replace(0,0,NULL,false); } else the_seq[0].encoded_data.replace((*ptr)[0].encoded_data.length(),(*ptr)[0].encoded_data.length(),(*ptr)[0].encoded_data.get_buffer()); if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { the_seq[1].encoded_format = CORBA::string_dup((*ptr)[1].encoded_format); the_seq[1].encoded_data.replace((*ptr)[1].encoded_data.length(),(*ptr)[1].encoded_data.length(),(*ptr)[1].encoded_data.get_buffer()); } } else { (*aid.data_4)[index].value.encoded_att_value(dummy_encoded_att_value); DevVarEncodedArray &the_seq = (*aid.data_4)[index].value.encoded_att_value(); if ((w_type == Tango::READ) || (w_type == Tango::WRITE)) the_seq.length(1); else the_seq.length(2); the_seq[0].encoded_format = CORBA::string_dup((*ptr)[0].encoded_format); if (ptr->release() == true) { unsigned long nb_data = (*ptr)[0].encoded_data.length(); the_seq[0].encoded_data.replace(nb_data,nb_data,(*ptr)[0].encoded_data.get_buffer(true),true); (*ptr)[0].encoded_data.replace(0,0,NULL,false); } else the_seq[0].encoded_data.replace((*ptr)[0].encoded_data.length(),(*ptr)[0].encoded_data.length(),(*ptr)[0].encoded_data.get_buffer()); if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { the_seq[1].encoded_format = CORBA::string_dup((*ptr)[1].encoded_format); the_seq[1].encoded_data.replace((*ptr)[1].encoded_data.length(),(*ptr)[1].encoded_data.length(),(*ptr)[1].encoded_data.get_buffer()); } } if (del_seq == true) delete ptr; } break; } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::polled_data_into_net_obj // // description : // Put the attribute data within the object used on the wire to transfer the attribute. For IDL release <= 3, // it's an Any object. Then, it is an IDL union // // argument: // in : // - aid : // - index : // - type : // - vers : Device IDl version // - polled_att : // - names : // //------------------------------------------------------------------------------------------------------------------- void DeviceImpl::polled_data_into_net_object(AttributeIdlData &aid, long index,long type,long vers,PollObj *polled_att, const DevVarStringArray &names) { const Tango::DevVarDoubleArray *tmp_db; Tango::DevVarDoubleArray *new_tmp_db; const Tango::DevVarShortArray *tmp_sh; Tango::DevVarShortArray *new_tmp_sh; const Tango::DevVarLongArray *tmp_lg; Tango::DevVarLongArray *new_tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; Tango::DevVarLong64Array *new_tmp_lg64; const Tango::DevVarStringArray *tmp_str; Tango::DevVarStringArray *new_tmp_str; const Tango::DevVarFloatArray *tmp_fl; Tango::DevVarFloatArray *new_tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; Tango::DevVarBooleanArray *new_tmp_boo; const Tango::DevVarUShortArray *tmp_ush; Tango::DevVarUShortArray *new_tmp_ush; const Tango::DevVarCharArray *tmp_uch; Tango::DevVarCharArray *new_tmp_uch; const Tango::DevVarULongArray *tmp_ulg; Tango::DevVarULongArray *new_tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; Tango::DevVarULong64Array *new_tmp_ulg64; const Tango::DevVarStateArray *tmp_state; Tango::DevVarStateArray *new_tmp_state; Tango::DevState sta; switch (type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : DATA_IN_NET_OBJECT(short_att_value,DevVarShortArray,short,new_tmp_sh,tmp_sh); break; case Tango::DEV_DOUBLE : DATA_IN_NET_OBJECT(double_att_value,DevVarDoubleArray,double,new_tmp_db,tmp_db); break; case Tango::DEV_LONG : DATA_IN_NET_OBJECT(long_att_value,DevVarLongArray,DevLong,new_tmp_lg,tmp_lg); break; case Tango::DEV_LONG64 : DATA_IN_NET_OBJECT(long64_att_value,DevVarLong64Array,DevLong64,new_tmp_lg64,tmp_lg64); break; case Tango::DEV_STRING : DATA_IN_NET_OBJECT(string_att_value,DevVarStringArray,char *,new_tmp_str,tmp_str); break; case Tango::DEV_FLOAT : DATA_IN_NET_OBJECT(float_att_value,DevVarFloatArray,float,new_tmp_fl,tmp_fl); break; case Tango::DEV_BOOLEAN : DATA_IN_NET_OBJECT(bool_att_value,DevVarBooleanArray,DevBoolean,new_tmp_boo,tmp_boo); break; case Tango::DEV_USHORT : DATA_IN_NET_OBJECT(ushort_att_value,DevVarUShortArray,DevUShort,new_tmp_ush,tmp_ush); break; case Tango::DEV_UCHAR : DATA_IN_NET_OBJECT(uchar_att_value,DevVarUCharArray,DevUChar,new_tmp_uch,tmp_uch); break; case Tango::DEV_ULONG : DATA_IN_NET_OBJECT(ulong_att_value,DevVarULongArray,DevULong,new_tmp_ulg,tmp_ulg); break; case Tango::DEV_ULONG64 : DATA_IN_NET_OBJECT(ulong64_att_value,DevVarULong64Array,DevULong64,new_tmp_ulg64,tmp_ulg64); break; case Tango::DEV_STATE : if (aid.data_5 != Tango_nullptr) { AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); if (att_val.value._d() == DEVICE_STATE) { sta = att_val.value.dev_state_att(); (*aid.data_5)[index].value.dev_state_att(sta); } else if (att_val.value._d() == ATT_STATE) { DevVarStateArray &union_seq = att_val.value.state_att_value(); (*aid.data_5)[index].value.state_att_value(union_seq); } } else if (aid.data_4 != Tango_nullptr) { if (vers >= 5) { AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); if (att_val.value._d() == DEVICE_STATE) { sta = att_val.value.dev_state_att(); (*aid.data_4)[index].value.dev_state_att(sta); } else if (att_val.value._d() == ATT_STATE) { DevVarStateArray &union_seq = att_val.value.state_att_value(); (*aid.data_4)[index].value.state_att_value(union_seq); } } else { AttributeValue_4 &att_val = polled_att->get_last_attr_value_4(false); if (att_val.value._d() == DEVICE_STATE) { sta = att_val.value.dev_state_att(); (*aid.data_4)[index].value.dev_state_att(sta); } else if (att_val.value._d() == ATT_STATE) { DevVarStateArray &union_seq = att_val.value.state_att_value(); (*aid.data_4)[index].value.state_att_value(union_seq); } } } else { if (vers >= 5) { AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); if (att_val.value._d() == DEVICE_STATE) { sta = att_val.value.dev_state_att(); (*aid.data_3)[index].value <<= sta; } else if (att_val.value._d() == ATT_STATE) { DevVarStateArray &union_seq = att_val.value.state_att_value(); new_tmp_state = new DevVarStateArray(union_seq.length(), union_seq.length(), const_cast(union_seq.get_buffer()), false); (*aid.data_3)[index].value <<= new_tmp_state; } } else if (vers == 4) { AttributeValue_4 &att_val = polled_att->get_last_attr_value_4(false); if (att_val.value._d() == DEVICE_STATE) { sta = att_val.value.dev_state_att(); (*aid.data_3)[index].value <<= sta; } else if (att_val.value._d() == ATT_STATE) { DevVarStateArray &union_seq = att_val.value.state_att_value(); new_tmp_state = new DevVarStateArray(union_seq.length(), union_seq.length(), const_cast(union_seq.get_buffer()), false); (*aid.data_3)[index].value <<= new_tmp_state; } } else { AttributeValue_3 &att_val = polled_att->get_last_attr_value_3(false); CORBA::TypeCode_var ty; ty = att_val.value.type(); if (ty->kind() == CORBA::tk_enum) { att_val.value >>= sta; (*aid.data_3)[index].value <<= sta; } else { att_val.value >>= tmp_state; new_tmp_state = new DevVarStateArray(tmp_state->length(),tmp_state->length(), const_cast(tmp_state->get_buffer()),false); (*aid.data_3)[index].value <<= new_tmp_state; } } } break; case Tango::DEV_ENCODED: if (aid.data_5 != Tango_nullptr) { AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); DevVarEncodedArray &polled_seq = att_val.value.encoded_att_value(); unsigned int nb_encoded = polled_seq.length(); (*aid.data_5)[index].value.encoded_att_value(dummy_encoded_att_value); DevVarEncodedArray &the_seq = (*aid.data_5)[index].value.encoded_att_value(); the_seq.length(nb_encoded); for (unsigned int loop = 0;loop < nb_encoded;loop++) { the_seq[loop].encoded_format = CORBA::string_dup(polled_seq[loop].encoded_format); unsigned char *tmp_enc = polled_seq[loop].encoded_data.get_buffer(); unsigned int nb_data = polled_seq[loop].encoded_data.length(); the_seq[loop].encoded_data.replace(nb_data,nb_data,tmp_enc); } } else if (aid.data_4 != Tango_nullptr) { if (vers == 5) { AttributeValue_5 &att_val = polled_att->get_last_attr_value_5(false); DevVarEncodedArray &polled_seq = att_val.value.encoded_att_value(); unsigned int nb_encoded = polled_seq.length(); (*aid.data_4)[index].value.encoded_att_value(dummy_encoded_att_value); DevVarEncodedArray &the_seq = (*aid.data_4)[index].value.encoded_att_value(); the_seq.length(nb_encoded); for (unsigned int loop = 0;loop < nb_encoded;loop++) { the_seq[loop].encoded_format = CORBA::string_dup(polled_seq[loop].encoded_format); unsigned char *tmp_enc = polled_seq[loop].encoded_data.get_buffer(); unsigned int nb_data = polled_seq[loop].encoded_data.length(); the_seq[loop].encoded_data.replace(nb_data,nb_data,tmp_enc); } } else { AttributeValue_4 &att_val = polled_att->get_last_attr_value_4(false); DevVarEncodedArray &polled_seq = att_val.value.encoded_att_value(); unsigned int nb_encoded = polled_seq.length(); (*aid.data_4)[index].value.encoded_att_value(dummy_encoded_att_value); DevVarEncodedArray &the_seq = (*aid.data_4)[index].value.encoded_att_value(); the_seq.length(nb_encoded); for (unsigned int loop = 0;loop < nb_encoded;loop++) { the_seq[loop].encoded_format = CORBA::string_dup(polled_seq[loop].encoded_format); unsigned char *tmp_enc = polled_seq[loop].encoded_data.get_buffer(); unsigned int nb_data = polled_seq[loop].encoded_data.length(); the_seq[loop].encoded_data.replace(nb_data,nb_data,tmp_enc); } } } else { TangoSys_OMemStream o; o << "Data type for attribute " << names[index] << " is DEV_ENCODED."; o << " It's not possible to retrieve this data type through the interface you are using (IDL V3)" << ends; (*aid.data_3)[index].err_list.length(1); (*aid.data_3)[index].err_list[0].severity = Tango::ERR; (*aid.data_3)[index].err_list[0].reason = CORBA::string_dup(API_NotSupportedFeature); (*aid.data_3)[index].err_list[0].origin = CORBA::string_dup("Device_3Impl::read_attributes_from_cache"); string s = o.str(); (*aid.data_3)[index].err_list[0].desc = CORBA::string_dup(s.c_str()); (*aid.data_3)[index].quality = Tango::ATTR_INVALID; (*aid.data_3)[index].name = CORBA::string_dup(names[index]); clear_att_dim((*aid.data_3)[index]); } break; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceImpl::att_conf_loop // // description : // Set flags in DeviceImpl if any of the device attributes has some wrong configuration in DB generating // startup exception when the server started. // In DeviceImpl class, this method set the force_alarm_state flag and fills in the // att_wrong_db_conf vector with attribute name(s) (for device status) // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::att_conf_loop() { vector &att_list = get_device_attr()->get_attribute_list(); // // Reset data before the new loop // vector &wrong_conf_att_list = get_att_wrong_db_conf(); wrong_conf_att_list.clear(); vector &mem_att_list = get_att_mem_failed(); mem_att_list.clear(); force_alarm_state = false; // // Run the loop for wrong attribute conf. or memorized att which failed at startup // for (size_t i = 0;i < att_list.size();++i) { if (att_list[i]->is_startup_exception() == true || att_list[i]->is_mem_exception() == true) { force_alarm_state = true; if (att_list[i]->is_startup_exception() == true) wrong_conf_att_list.push_back(att_list[i]->get_name()); else mem_att_list.push_back(att_list[i]->get_name()); } } if (force_alarm_state == false && fwd_att_wrong_conf.empty() == false) force_alarm_state = true; run_att_conf_loop = false; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::check_att_conf // // description : // //-------------------------------------------------------------------------------------------------------------------- void DeviceImpl::check_att_conf() { dev_attr->check_idl_release(this); if (run_att_conf_loop == true) att_conf_loop(); } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::build_att_list_in_status_mess // // description : // Build device status message in case of device with some // - att with wrong conf. in db // - some memorized attribute failed during the startup phase // - some wrongly configured forwarded attributes // // argument: // in : // - nb_att : Number of attributes in error // - att_type : Type of attribute error (conf or mem) // //--------------------------------------------------------------------------------------------------------------------- void DeviceImpl::build_att_list_in_status_mess(size_t nb_att,AttErrorType att_type) { // // First, the wrongly configured forwarded attributes case // if (att_type == Tango::DeviceImpl::FWD) { for (size_t i = 0;i < nb_att;++i) { alarm_status = alarm_status + "\nForwarded attribute " + fwd_att_wrong_conf[i].att_name; if (fwd_att_wrong_conf[i].fae != FWD_ROOT_DEV_NOT_STARTED) alarm_status = alarm_status + " is not correctly configured! "; else alarm_status = alarm_status + " not reachable! "; alarm_status = alarm_status + "Root attribute name = "; alarm_status = alarm_status + fwd_att_wrong_conf[i].full_root_att_name; if (fwd_att_wrong_conf[i].fae != FWD_ROOT_DEV_NOT_STARTED) alarm_status = alarm_status + "\nYou can update it using the Jive tool"; alarm_status = alarm_status + "\nError: "; switch(fwd_att_wrong_conf[i].fae) { case FWD_WRONG_ATTR: alarm_status = alarm_status + "Attribute not found in root device"; break; case FWD_CONF_LOOP: alarm_status = alarm_status + "Loop found in root attributes configuration"; break; case FWD_WRONG_DEV: alarm_status = alarm_status + "Wrong root device"; break; case FWD_MISSING_ROOT: alarm_status = alarm_status + "Missing or wrong root attribute definition"; break; case FWD_ROOT_DEV_LOCAL_DEV: alarm_status = alarm_status + "Root device is local device"; break; case FWD_WRONG_SYNTAX: alarm_status = alarm_status + "Wrong syntax in root attribute definition"; break; case FWD_ROOT_DEV_NOT_STARTED: alarm_status = alarm_status + "Root device not started yet. Polling (if any) for this attribute not available"; break; case FWD_TOO_OLD_LOCAL_DEVICE: alarm_status = alarm_status + "Local device too old (< IDL 5)"; break; case FWD_TOO_OLD_ROOT_DEVICE: alarm_status = alarm_status + "Root device too old (< IDL 5)"; break; case FWD_DOUBLE_USED: { alarm_status = alarm_status + "Root attribute already used in this device server process for attribute "; Util *tg = Util::instance(); string root_name(fwd_att_wrong_conf[i].full_root_att_name); transform(root_name.begin(),root_name.end(),root_name.begin(),::tolower); string local_att_name = tg->get_root_att_reg().get_local_att_name(root_name); alarm_status = alarm_status + local_att_name; break; } default: break; } } } else { // // For wrong conf. in db or memorized attributes which failed at startup // if (nb_att > 1) alarm_status = alarm_status + "s"; alarm_status = alarm_status + " "; for (size_t i = 0;i < nb_att;++i) { if (att_type == Tango::DeviceImpl::CONF) alarm_status = alarm_status + att_wrong_db_conf[i]; else alarm_status = alarm_status + att_mem_failed[i]; if ((nb_att > 1) && (i <= nb_att - 2)) alarm_status = alarm_status + ", "; } if (nb_att == 1) alarm_status = alarm_status + " has "; else alarm_status = alarm_status + " have "; } } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::is_there_subscriber // // description : // Returns true if there is some subscriber(s) listening on the event // // argument: // in : // - att_name : The attribute name // - event_type : The event type // //--------------------------------------------------------------------------------------------------------------------- bool DeviceImpl::is_there_subscriber(const string &att_name,EventType event_type) { Attribute &att = dev_attr->get_attr_by_name(att_name.c_str()); bool ret = false; switch(event_type) { case CHANGE_EVENT: ret = att.change_event_subscribed(); break; case QUALITY_EVENT: ret = att.quality_event_subscribed(); break; case PERIODIC_EVENT: ret = att.periodic_event_subscribed(); break; case ARCHIVE_EVENT: ret = att.archive_event_subscribed(); break; case USER_EVENT: ret = att.user_event_subscribed(); break; case ATTR_CONF_EVENT: ret = att.attr_conf_event_subscribed(); break; case DATA_READY_EVENT: ret = att.data_ready_event_subscribed(); break; default: Except::throw_exception(API_UnsupportedFeature,"Unsupported event type","Device::get_cmd_by_name"); break; } return ret; } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::rem_wrong_fwd_att // // description : // Remove one forwarded attribute from the list of errored forwarded attribute // // argument: // in : // - root_att_name : The root attribute name to be removed // //--------------------------------------------------------------------------------------------------------------------- void DeviceImpl::rem_wrong_fwd_att(const string &root_att_name) { vector::iterator ite; for (ite = fwd_att_wrong_conf.begin();ite != fwd_att_wrong_conf.end();++ite) { string local_name(ite->full_root_att_name); transform(local_name.begin(),local_name.end(),local_name.begin(),::tolower); if (local_name == root_att_name) { fwd_att_wrong_conf.erase(ite); break; } } } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::update_wrong_fwd_att // // description : // Update error code for one forwarded attribute in the list of errored forwarded attribute // // argument: // in : // - root_att_name : The root attribute name to be removed // - err : The new error code // //--------------------------------------------------------------------------------------------------------------------- void DeviceImpl::update_wrong_conf_att(const string &root_att_name,FwdAttError err) { vector::iterator ite; for (ite = fwd_att_wrong_conf.begin();ite != fwd_att_wrong_conf.end();++ite) { string local_name(ite->full_root_att_name); transform(local_name.begin(),local_name.end(),local_name.begin(),::tolower); if (local_name == root_att_name) { ite->fae = err; break; } } } //---------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::lock_root_devices // // description : // Lock/Unlock all root devices for all the forwarded attributes defined for this device // // argument: // in : // - validity : The lock validity interval (used only in case of locking) // - lock_action : Flag set to true if root device(s) must be locked. If false, root devices will be unlocked // //--------------------------------------------------------------------------------------------------------------------- void DeviceImpl::lock_root_devices(int validity,bool lock_action) { // // Get list of root device(s) // vector root_devs; vector::iterator ite; vector att_list = dev_attr->get_attribute_list(); for (size_t j = 0;j < att_list.size();j++) { if (att_list[j]->is_fwd_att() == true) { FwdAttribute *fwd_att = static_cast(att_list[j]); string &dev_name = fwd_att->get_fwd_dev_name(); ite = find(root_devs.begin(),root_devs.end(),dev_name); if (ite == root_devs.end()) root_devs.push_back(dev_name); } } // // Lock/Unlock all these devices // RootAttRegistry &rar = Util::instance()->get_root_att_reg(); for (size_t loop = 0;loop < root_devs.size();loop++) { DeviceProxy *dp = rar.get_root_att_dp(root_devs[loop]); if (lock_action == true) dp->lock(validity); else dp->unlock(); } } //+---------------------------------------------------------------------------- // // method : DeviceImpl::get_local_cmd_by_name // // description : Get a reference to a local Command object // // in : cmd_name : The command name // //----------------------------------------------------------------------------- Command &DeviceImpl::get_local_cmd_by_name(const string &cmd_name) { vector::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(command_list.begin(),command_list.end(), [&] (Command *cmd) -> bool { if (cmd_name.size() != cmd->get_lower_name().size()) return false; string tmp_name(cmd_name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); return cmd->get_lower_name() == tmp_name; }); #else pos = find_if(command_list.begin(),command_list.end(), bind2nd(WantedCmd(),cmd_name.c_str())); #endif if (pos == command_list.end()) { cout3 << "DeviceImpl::get_cmd_by_name throwing exception" << endl; TangoSys_OMemStream o; o << cmd_name << " command not found" << ends; Except::throw_exception(API_CommandNotFound,o.str(),"Device::get_cmd_by_name"); } return *(*pos); } //+---------------------------------------------------------------------------- // // method : DeviceImpl::remove_local_command // // description : Delete a command from the local command list // // in : cmd_name : The command name (in lower case letter) // //----------------------------------------------------------------------------- void DeviceImpl::remove_local_command(const string &cmd_name) { vector::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(command_list.begin(),command_list.end(), [&] (Command *cmd) -> bool { if (cmd_name.size() != cmd->get_lower_name().size()) return false; return cmd->get_lower_name() == cmd_name; }); #else pos = find_if(command_list.begin(),command_list.end(), bind2nd(WantedCmd(),cmd_name.c_str())); #endif if (pos == command_list.end()) { cout3 << "DeviceImpl::remove_local_command throwing exception" << endl; TangoSys_OMemStream o; o << cmd_name << " command not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceImpl::remove_local_command"); } command_list.erase(pos); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::get_event_param // // description : // Return event info for the device with events subscribed // // argument : // out : // - eve : One structure in this vector for each device event subsribed // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::get_event_param(vector &eve) { ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); if (event_supplier_zmq->any_dev_intr_client(this) == true) { EventPar ep; ep.notifd = false; ep.zmq = true; ep.attr_id = -1; ep.quality = false; ep.data_ready = false; ep.dev_intr_change = true; eve.push_back(ep); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::set_event_param // // description : // Set device interface change event subscription time // // argument : // in : // - eve : One structure in this vector for each device event subscribed // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::set_event_param(vector &eve) { for (size_t loop = 0;loop < eve.size();loop++) { if (eve[loop].attr_id == -1) { if (eve[loop].dev_intr_change == true) set_event_intr_change_subscription(time(NULL)); break; } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::push_dev_intr // // description : // Start or update device interface change event thread // // argument : // in : // - ev_client : Flag set to true if some clients are listening on the event // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::push_dev_intr(bool ev_client) { // // If device is IDL 5 or more and if enabled, push a device interface change event but only if there is some // client(s) listening on the event. // This is done by starting a dedicated thread (if not already started). The rule of this thread is to delayed // the event in case of attributes/commands added/removed in a loop in order to minimize the event number. // if (idl_version >= MIN_IDL_DEV_INTR && is_intr_change_ev_enable() == true && ev_client == true) { bool th_running; { omni_mutex_lock lo(devintr_mon); th_running = devintr_shared.th_running; } if (th_running == false) { devintr_shared.cmd_pending = false; devintr_thread = new DevIntrThread(devintr_shared,devintr_mon,this); devintr_shared.th_running = true; devintr_thread->start(); } else { int interupted; omni_mutex_lock sync(devintr_mon); devintr_shared.cmd_pending = true; devintr_shared.cmd_code = DEV_INTR_SLEEP; devintr_mon.signal(); cout4 << "Cmd sent to device interface change thread" << endl; while (devintr_shared.cmd_pending == true) { interupted = devintr_mon.wait(DEFAULT_TIMEOUT); if ((devintr_shared.cmd_pending == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut,"Device interface change event thread blocked !!!", "DeviceImpl::push_dev_intr"); } } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::end_pipe_config // // description : // Get all pipe properties defined at device level and aggregate all the pipe properties defined at different // level (device, user default, class default // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::end_pipe_config() { cout4 << "Entering end_pipe_config for device " << device_name << endl; vector &pipe_list = device_class->get_pipe_list(device_name_lower); size_t nb_pipe = pipe_list.size(); // // First get device pipe configuration from db // cout4 << nb_pipe << " pipe(s)" << endl; if (nb_pipe != 0) { Tango::Util *tg = Tango::Util::instance(); Tango::DbData db_list; if (tg->_UseDb == true) { for (size_t i = 0;i < nb_pipe;i++) db_list.push_back(DbDatum(pipe_list[i]->get_name())); // // On some small and old computers, this request could take time if at the same time some other processes also access // the device pipe properties table. This has been experimented at ESRF. Increase timeout to cover this case // int old_db_timeout = 0; if (Util::_FileDb == false) old_db_timeout = tg->get_database()->get_timeout_millis(); try { if (old_db_timeout != 0) tg->get_database()->set_timeout_millis(6000); tg->get_database()->get_device_pipe_property(device_name,db_list,tg->get_db_cache()); if (old_db_timeout != 0) tg->get_database()->set_timeout_millis(old_db_timeout); } catch (Tango::DevFailed &) { cout4 << "Exception while accessing database" << endl; tg->get_database()->set_timeout_millis(old_db_timeout); stringstream ss; ss << "Can't get device pipe properties for device " << device_name << ends; Except::throw_exception(API_DatabaseAccess,ss.str(),"DeviceImpl::end_pipe_config"); } // // A loop for each pipe // long ind = 0; for (size_t i = 0;i < nb_pipe;i++) { // // If pipe has some properties defined at device level, build a vector of PipeProperty with them // long nb_prop = 0; vector dev_prop; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + ","; tmp = tmp + db_list[ind].value_string[k]; } dev_prop.push_back(PipeProperty(db_list[ind].name,tmp)); } else dev_prop.push_back(PipeProperty(db_list[ind].name,db_list[ind].value_string[0])); ind++; } Pipe *pi_ptr = pipe_list[i]; // // Call method which will aggregate prop definition retrieved at different levels // set_pipe_prop(dev_prop,pi_ptr,LABEL); set_pipe_prop(dev_prop,pi_ptr,DESCRIPTION); } } } cout4 << "Leaving end_pipe_config for device " << device_name << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::set_pipe_prop // // description : // Set a pipe property. A pipe property can be defined at device level in DB, by a user default or at // class level in DB. Properties defined in DB at device level are given to the method as the first // parameter. If the user has defined some user default, the pipe object already has them. The properties // defined at class level are available in the MultiClassPipe object available in the DeviceClass instance // // argument : // in: // - dev_prop : Pipe properties defined at device level // - pi_ptr : Pipe instance pointer // - ppt : Property type (label or description) // //------------------------------------------------------------------------------------------------------------------ void DeviceImpl::set_pipe_prop(vector &dev_prop,Pipe *pi_ptr,PipePropType ppt) { cout4 << "Entering set_pipe_prop() method" << endl; // // Final init of pipe prop with following priorities: // - Device pipe // - User default // - Class pipe // The pipe instance we have here already has config set to user default (if any) // bool found = false; string req_p_name; if (ppt == LABEL) req_p_name = "label"; else req_p_name = "description"; vector::iterator dev_ite; for (dev_ite = dev_prop.begin();dev_ite != dev_prop.end();++dev_ite) { string p_name = dev_ite->get_name(); transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); if (p_name == req_p_name) { found = true; break; } } if (found == true) { if (ppt == LABEL) pi_ptr->set_label(dev_ite->get_value()); else pi_ptr->set_desc(dev_ite->get_value()); } else { // // Prop not defined at device level. If the prop is still the lib default one, search if it is defined at class // level // bool still_default; if (ppt == LABEL) still_default = pi_ptr->is_label_lib_default(); else still_default = pi_ptr->is_desc_lib_default(); if (still_default == true) { try { vector &cl_pi_prop = device_class->get_class_pipe()->get_prop_list(pi_ptr->get_name()); bool found = false; vector::iterator class_ite; for (class_ite = cl_pi_prop.begin();class_ite != cl_pi_prop.end();++class_ite) { string p_name = class_ite->get_name(); transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); if (p_name == req_p_name) { found = true; break; } } if (found == true) { if (ppt == LABEL) pi_ptr->set_label(class_ite->get_value()); else pi_ptr->set_desc(class_ite->get_value()); } } catch (Tango::DevFailed &) {} } } cout4 << "Leaving set_pipe_prop() method" << endl; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/device_2.cpp0000644023471100065110000014640213034745001014754 00000000000000static const char *RcsId = "$Id: device_2.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+============================================================================ // // file : Device_2.cpp // // description : C++ source code for the DeviceImpl and DeviceClass // classes. These classes // are the root class for all derived Device classes. // They are abstract classes. The DeviceImpl class is the // CORBA servant which is "exported" onto the network and // accessed by the client. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #ifdef _TG_WINDOWS_ #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------- // // method : Device_2Impl::Device_2Impl // // description : constructors for the device_impl class from the // class object pointer, the device name, // the description field, the state and the status. // Device_2Impl inherits from DeviceImpl. These constructors // simply call the correct DeviceImpl class // constructor // //-------------------------------------------------------------------------- Device_2Impl::Device_2Impl(DeviceClass *device_class,string &dev_name): DeviceImpl(device_class,dev_name),ext_2(Tango_nullptr) { idl_version = 2; } Device_2Impl::Device_2Impl(DeviceClass *device_class, string &dev_name, string &desc): DeviceImpl(device_class,dev_name,desc),ext_2(Tango_nullptr) { idl_version = 2; } Device_2Impl::Device_2Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status): DeviceImpl(device_class,dev_name,desc,dev_state,dev_status),ext_2(Tango_nullptr) { idl_version = 2; } Device_2Impl::Device_2Impl(DeviceClass *device_class, const char *dev_name, const char *desc, Tango::DevState dev_state, const char *dev_status): DeviceImpl(device_class,dev_name,desc,dev_state,dev_status),ext_2(Tango_nullptr) { idl_version = 2; } //+------------------------------------------------------------------------- // // method : Device_2Impl::command_inout_2 // // description : Method called for each command_inout operation executed // from any client on a Tango device version 2. // //-------------------------------------------------------------------------- CORBA::Any *Device_2Impl::command_inout_2(const char *in_cmd, const CORBA::Any &in_data, Tango::DevSource source) { cout4 << "Device_2Impl::command_inout_2 arrived, source = " << source << ", command = " << in_cmd << endl; PollObj *polled_cmd = NULL; bool polling_failed = false; CORBA::Any *ret = NULL; // // Record operation request in black box // If this method is executed with the request to store info in // blackbox (store_in_bb == true), this means that the request arrives // through a Device_2 CORBA interface. Check locking feature in this // case. Otherwise the request has arrived through Device_4 and the check // is already done // if (store_in_bb == true) { blackbox_ptr->insert_cmd(in_cmd,2,source); // // Do not check lock validity if State or Status is requested using command // bool state_status_cmd = false; if ((TG_strcasecmp(in_cmd,"state") == 0) || (TG_strcasecmp(in_cmd,"status") == 0)) state_status_cmd = true; // // Check if the device is locked and if it is valid // If the lock is not valid any more, clear it // if (state_status_cmd == false) { check_lock("command_inout2",in_cmd); } } store_in_bb = true; // // If the source parameter specifies device, call the command_inout method // implemented by the DeviceImpl class // if (source == Tango::DEV) { AutoTangoMonitor sync(this); store_in_bb = false; return command_inout(in_cmd,in_data); } else { bool status_cmd = false; bool state_cmd = false; TangoMonitor &p_mon = get_poll_monitor(); AutoTangoMonitor sync(&p_mon); try { string cmd_str(in_cmd); transform(cmd_str.begin(),cmd_str.end(),cmd_str.begin(),::tolower); // // Check that device supports this command and also check // if it is state or status // check_command_exists(cmd_str); long vers = get_dev_idl_version(); if (vers >= 3) { if (cmd_str == "state") state_cmd = true; else if (cmd_str == "status") status_cmd = true; } // // Check that the command is polled. // Warning : Since IDL 3 (Tango V5), state and status are polled as attributes // bool found = false; vector &poll_list = get_poll_obj_list(); unsigned long i; for (i = 0;i < poll_list.size();i++) { if (poll_list[i]->get_name() == cmd_str) { if ((state_cmd == true) || (status_cmd == true)) { if (poll_list[i]->get_type() == Tango::POLL_ATTR) { polled_cmd = poll_list[i]; found = true; } } else { if (poll_list[i]->get_type() == Tango::POLL_CMD) { polled_cmd = poll_list[i]; found = true; } } } } // // Throw exception if the command is not polled // if (found == false) { TangoSys_OMemStream o; o << "Command " << in_cmd << " not polled" << ends; Except::throw_exception((const char *)API_CmdNotPolled, o.str(), (const char *)"Device_2Impl::command_inout"); } /* // // If the command is not polled but its polling update period is defined, // and the command is not in the device list of command which should not be // polled, start to poll it // else { found = false; vector &napc = get_non_auto_polled_cmd(); for (i = 0;i < napc.size();i++) { if (napc[i] == cmd_str) found = true; } if (found == true) { TangoSys_OMemStream o; o << "Command " << in_cmd << " not polled" << ends; Except::throw_exception((const char *)API_CmdNotPolled, o.str(), (const char *)"Device_2Impl::command_inout"); } else { Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); send->lvalue[0] = poll_period; send->svalue[0] = device_name.c_str(); send->svalue[1] = CORBA::string_dup("command"); send->svalue[2] = in_cmd; get_poll_monitor().rel_monitor(); adm_dev->add_obj_polling(send,false); delete send; // // Wait for first polling. Release monitor during this sleep in order // to give it to the polling thread // #ifdef _TG_WINDOWS_ Sleep((DWORD)600); get_poll_monitor().get_monitor(); #else struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 600000000; nanosleep(&to_wait,&inter); get_poll_monitor().get_monitor(); #endif // // Update the polled-cmd pointer to the new polled object // for (i = 0;i < poll_list.size();i++) { if (poll_list[i]->get_name() == cmd_str) { polled_cmd = poll_list[i]; break; } } } } }*/ // // Check that some data is available in cache // if (polled_cmd->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for command " << in_cmd << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_2Impl::command_inout"); } // // Check that data are still refreshed by the polling thread // Skip this test for object with external polling triggering (upd = 0) // long tmp_upd = polled_cmd->get_upd(); if (tmp_upd != 0) { double last = polled_cmd->get_last_insert_date(); struct timeval now; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; double now_d = (double)now.tv_sec + ((double)now.tv_usec / 1000000); double diff_d = now_d - last; if (diff_d > polled_cmd->get_authorized_delta()) { TangoSys_OMemStream o; o << "Data in cache for command " << in_cmd; o << " not updated any more" << ends; Except::throw_exception((const char *)API_NotUpdatedAnyMore, o.str(), (const char *)"Device_2Impl::command_inout"); } } } catch (Tango::DevFailed &) { if (source == Tango::CACHE) { throw; } polling_failed = true; } // // Get cmd result (or exception) // if (source == Tango::CACHE) { cout4 << "Device_2Impl: Returning data from polling buffer" << endl; if ((state_cmd == true) || (status_cmd == true)) { long vers = get_dev_idl_version(); omni_mutex_lock sync(*polled_cmd); if (vers >= 5) { Tango::AttributeValue_5 &att_val = polled_cmd->get_last_attr_value_5(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } else if (vers == 4) { Tango::AttributeValue_4 &att_val = polled_cmd->get_last_attr_value_4(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } else { Tango::AttributeValue_3 &att_val = polled_cmd->get_last_attr_value_3(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } } else ret = polled_cmd->get_last_cmd_result(); } else { if (polling_failed == false) { cout4 << "Device_2Impl: Returning data from polling buffer" << endl; if ((state_cmd == true) || (status_cmd == true)) { long vers = get_dev_idl_version(); omni_mutex_lock sync(*polled_cmd); if (vers >= 5) { Tango::AttributeValue_5 &att_val = polled_cmd->get_last_attr_value_5(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } else if (vers == 4) { Tango::AttributeValue_4 &att_val = polled_cmd->get_last_attr_value_4(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } else { Tango::AttributeValue_3 &att_val = polled_cmd->get_last_attr_value_3(false); ret = attr2cmd(att_val,state_cmd,status_cmd); } } else ret = polled_cmd->get_last_cmd_result(); } } } if ((source != Tango::CACHE) && (polling_failed == true)) { AutoTangoMonitor sync(this); store_in_bb = false; ret = command_inout(in_cmd,in_data); } return ret; } //+------------------------------------------------------------------------- // // method : Device_2Impl::read_attributes_2 // // description : Method called for each read_attributes operation executed // from any client on a Tango device version 2. // //-------------------------------------------------------------------------- Tango::AttributeValueList* Device_2Impl::read_attributes_2(const Tango::DevVarStringArray& names, Tango::DevSource source) { // AutoTangoMonitor sync(this); cout4 << "Device_2Impl::read_attributes_2 arrived" << endl; bool att_in_fault = false; bool polling_failed = false; Tango::AttributeValueList *back = NULL; // // Write the device name into the per thread data for // sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, // the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // Catch all execeptions to set back the associated device after // execution try { // // Record operation request in black box // blackbox_ptr->insert_attr(names,2,source); // // If the source parameter specifies device, call the read_attributes method // implemented by the DeviceImpl class // if (source == Tango::DEV) { AutoTangoMonitor sync(this,true); store_in_bb = false; return read_attributes(names); } else { TangoMonitor &p_mon = get_poll_monitor(); AutoTangoMonitor sync(&p_mon); try { // // Build a sequence with the names of the attribute to be read. // This is necessary in case of the "AllAttr" shortcut is used // If all attributes are wanted, build this list // unsigned long i,j; bool all_attr = false; vector &poll_list = get_poll_obj_list(); unsigned long nb_poll = poll_list.size(); unsigned long nb_names = names.length(); Tango::DevVarStringArray real_names(nb_names); if (nb_names == 1) { string att_name(names[0]); if (att_name == AllAttr) { all_attr = true; for (i = 0;i < nb_poll;i++) { if (poll_list[i]->get_type() == Tango::POLL_ATTR) { long nb_in_seq = real_names.length(); real_names.length(nb_in_seq + 1); real_names[nb_in_seq] = poll_list[i]->get_name().c_str(); } } } else { real_names = names; } } else { real_names = names; } // // Check that device supports the wanted attribute // if (all_attr == false) { for (i = 0;i < real_names.length();i++) dev_attr->get_attr_ind_by_name(real_names[i]); } // // Check that all wanted attributes are polled. If some are non polled, store // their index in the real_names sequence in a vector // vector non_polled; if (all_attr == false) { for (i = 0;i < real_names.length();i++) { for (j = 0;j < nb_poll;j++) { #ifdef _TG_WINDOWS_ if (_stricmp(poll_list[j]->get_name().c_str(),real_names[i]) == 0) #else if (strcasecmp(poll_list[j]->get_name().c_str(),real_names[i]) == 0) #endif break; } if (j == nb_poll) { non_polled.push_back(i); } } } // // If some attributes are not polled but their polling update period is defined, // and the attribute is not in the device list of attr which should not be // polled, start to poll them // bool found; vector poll_period; if (non_polled.empty() == false) { // // Check that it is possible to start polling for the non polled attribute // for (i = 0;i < non_polled.size();i++) { Attribute &att = dev_attr->get_attr_by_name(real_names[non_polled[i]]); poll_period.push_back(att.get_polling_period()); if (poll_period.back() == 0) { TangoSys_OMemStream o; o << "Attribute " << real_names[non_polled[i]] << " not polled" << ends; Except::throw_exception((const char *)API_AttrNotPolled, o.str(), (const char *)"Device_2Impl::read_attributes"); } else { found = false; vector &napa = get_non_auto_polled_attr(); for (j = 0;j < napa.size();j++) { #ifdef _TG_WINDOWS_ if (_stricmp(napa[j].c_str(),real_names[non_polled[i]]) == 0) #else if (strcasecmp(napa[j].c_str(),real_names[non_polled[i]]) == 0) #endif found = true; } if (found == true) { TangoSys_OMemStream o; o << "Attribute " << real_names[non_polled[i]] << " not polled" << ends; Except::throw_exception((const char *)API_AttrNotPolled, o.str(), (const char *)"Device_2Impl::read_attributes"); } } } // // Start polling // Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); send->svalue[0] = device_name.c_str(); send->svalue[1] = CORBA::string_dup("attribute"); for (i = 0;i < non_polled.size();i++) { send->lvalue[0] = poll_period[i]; send->svalue[2] = real_names[non_polled[i]]; adm_dev->add_obj_polling(send,false); } delete send; // // Wait for first polling // #ifdef _TG_WINDOWS_ get_poll_monitor().rel_monitor(); Sleep((DWORD)600); get_poll_monitor().get_monitor(); #else struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 600000000; get_poll_monitor().rel_monitor(); nanosleep(&to_wait,&inter); get_poll_monitor().get_monitor(); #endif } // // Allocate memory for the AttributeValue structures // unsigned long nb_attr = real_names.length(); try { back = new Tango::AttributeValueList(nb_attr); back->length(nb_attr); } catch (bad_alloc &) { back = NULL; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DeviceImpl_2::read_attributes"); } // // For each attribute, check that some data are available in cache and that they // are not too old // for (i = 0;i < nb_attr;i++) { vector &poll_list = get_poll_obj_list(); PollObj *polled_attr = NULL; unsigned long j; for (j = 0;j < poll_list.size();j++) { #ifdef _TG_WINDOWS_ if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (_stricmp(poll_list[j]->get_name().c_str(),real_names[i]) == 0)) #else if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (strcasecmp(poll_list[j]->get_name().c_str(),real_names[i]) == 0)) #endif { polled_attr = poll_list[j]; break; } } // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { delete back; back = NULL; TangoSys_OMemStream o; o << "No data available in cache for attribute " << real_names[i] << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_2Impl::read_attributes"); } // // Check that data are still refreshed by the polling thread // Skip this test for object with external polling triggering (upd = 0) // long tmp_upd = polled_attr->get_upd(); if (tmp_upd != 0) { double last = polled_attr->get_last_insert_date(); struct timeval now; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; double now_d = (double)now.tv_sec + ((double)now.tv_usec / 1000000); double diff_d = now_d - last; if (diff_d > polled_attr->get_authorized_delta()) { delete back; back = NULL; TangoSys_OMemStream o; o << "Data in cache for attribute " << real_names[i]; o << " not updated any more" << ends; Except::throw_exception((const char *)API_NotUpdatedAnyMore, o.str(), (const char *)"Device_2Impl::read_attributes"); } } // // Get attribute data type // Attribute &att = dev_attr->get_attr_by_name(real_names[i]); long type = att.get_data_type(); // // In IDL release 3, possibility to write spectrum and // images attributes have been added. This implies some // changes in the struture returned for a read_attributes // For server recompiled with this new release, the polling // thread uses this new structure type to store attribute // value. For some cases, it is possible to pass data from the // new type to the old one, but for other cases, it is not // possible. Throw exception in these cases // Tango::AttrWriteType w_type = att.get_writable(); Tango::AttrDataFormat format_type = att.get_data_format(); if ((format_type == Tango::SPECTRUM) || (format_type == Tango::IMAGE)) { if (w_type != Tango::READ) { delete back; back = NULL; TangoSys_OMemStream o; o << "Client too old to get data for attribute " << real_names[i].in(); o << ".\nPlease, use a client linked with Tango V5"; o << " and a device inheriting from Device_3Impl" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"Device_2Impl::read_attributes"); } } // // Finally, after all these checks, get value and store it in the sequence // sent back to user // In order to avoid unnecessary copy, don't use the assignement operator of the // AttributeValue structure which copy each element and therefore also copy // the Any object. The Any assignement operator is a deep copy! // Create a new sequence using the attribute buffer and insert it into the // Any. The sequence inside the source Any has been created using the attribute // data buffer. // try { { omni_mutex_lock sync(*polled_attr); long vers = get_dev_idl_version(); if (vers >= 4) { AttributeValue_4 &att_val_4 = polled_attr->get_last_attr_value_4(false); if (att_val_4.quality != Tango::ATTR_INVALID) { if (type == Tango::DEV_ENCODED) { delete back; back = NULL; TangoSys_OMemStream o; o << "Data type for attribute " << real_names[i] << " is DEV_ENCODED."; o << " It's not possible to retrieve this data type through the interface you are using (IDL V2)" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"Device_2Impl::read_attributes"); } Polled_2_Live(type,att_val_4.value,(*back)[i].value); (*back)[i].quality= att_val_4.quality; (*back)[i].time = att_val_4.time; (*back)[i].dim_x = att_val_4.r_dim.dim_x; (*back)[i].dim_y = att_val_4.r_dim.dim_y; (*back)[i].name = CORBA::string_dup(att_val_4.name); } } else if (vers == 3) { AttributeValue_3 &att_val_3 = polled_attr->get_last_attr_value_3(false); if (att_val_3.quality != Tango::ATTR_INVALID) { if (type == Tango::DEV_ENCODED) { delete back; back = NULL; TangoSys_OMemStream o; o << "Data type for attribute " << real_names[i] << " is DEV_ENCODED."; o << " It's not possible to retrieve this data type through the interface you are using (IDL V2)" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"Device_2Impl::read_attributes"); } Polled_2_Live(type,att_val_3.value,(*back)[i].value); (*back)[i].quality= att_val_3.quality; (*back)[i].time = att_val_3.time; (*back)[i].dim_x = att_val_3.r_dim.dim_x; (*back)[i].dim_y = att_val_3.r_dim.dim_y; (*back)[i].name = CORBA::string_dup(att_val_3.name); } } else { AttributeValue &att_val = polled_attr->get_last_attr_value(false); if (att_val.quality != Tango::ATTR_INVALID) { if (type == Tango::DEV_ENCODED) { delete back; back = NULL; TangoSys_OMemStream o; o << "Data type for attribute " << real_names[i] << " is DEV_ENCODED."; o << " It's not possible to retrieve this data type through the interface you are using (IDL V2)" << ends; Except::throw_exception((const char *)API_NotSupportedFeature, o.str(), (const char *)"Device_2Impl::read_attributes"); } Polled_2_Live(type,att_val.value,(*back)[i].value); (*back)[i].quality= att_val.quality; (*back)[i].time = att_val.time; (*back)[i].dim_x = att_val.dim_x; (*back)[i].dim_y = att_val.dim_y; (*back)[i].name = CORBA::string_dup(att_val.name); } } } } catch (Tango::DevFailed &) { delete back; att_in_fault = true; throw; } } } catch (Tango::DevFailed &) { // // Re-throw exception if the source parameter is CACHE or if the source param. // is CACHE_DEV but one of the attribute is really in fault (not the polling) // if (source == Tango::CACHE) throw; if (att_in_fault == true) throw; polling_failed = true; } } // // If the source parameter is CACHE, returned data, else called method reading // attribute from device // if ((source == Tango::CACHE_DEV) && (polling_failed == true)) { delete back; AutoTangoMonitor sync(this,true); store_in_bb = false; //return read_attributes(names); back = read_attributes(names); } else { cout4 << "Device_2Impl: Returning attribute(s) value from polling buffer" << endl; //return back; } } catch (...) { // set back the device attribution for the thread // and rethrow the exception. sub.set_associated_device(last_associated_device); throw; } // set back the device attribution for the thread sub.set_associated_device(last_associated_device); return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::command_list_query // // description : CORBA operation to read the device command list. // This method returns command info in a sequence of // DevCmdInfo_2 // // WARNING !!!!!!!!!!!!!!!!!! // // This is the release 2 of this CORBA operation which // returns one more parameter than in release 1 // The code has been duplicated in order to keep it clean // (avoid many "if" on version number in a common method) // //-------------------------------------------------------------------------- Tango::DevCmdInfoList_2 *Device_2Impl::command_list_query_2() { cout4 << "Device_2Impl::command_list_query_2 arrived" << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command_list_2); // // Retrieve number of command and allocate memory to send back info // long nb_cmd_class = device_class->get_command_list().size(); long nb_cmd_dev = get_local_command_list().size(); long nb_cmd = nb_cmd_class + nb_cmd_dev; cout4 << nb_cmd << " command(s) for device" << endl; Tango::DevCmdInfoList_2 *back = NULL; try { back = new Tango::DevCmdInfoList_2(nb_cmd); back->length(nb_cmd); // // Populate the vector // for (long i = 0;i < nb_cmd_class;i++) { Tango::DevCmdInfo_2 tmp; tmp.cmd_name = CORBA::string_dup(((device_class->get_command_list())[i]->get_name()).c_str()); tmp.cmd_tag = 0; tmp.level = (device_class->get_command_list())[i]->get_disp_level(); tmp.in_type = (long)((device_class->get_command_list())[i]->get_in_type()); tmp.out_type = (long)((device_class->get_command_list())[i]->get_out_type()); string &str_in = (device_class->get_command_list())[i]->get_in_type_desc(); if (str_in.size() != 0) tmp.in_type_desc = CORBA::string_dup(str_in.c_str()); else tmp.in_type_desc = CORBA::string_dup(NotSet); string &str_out = (device_class->get_command_list())[i]->get_out_type_desc(); if (str_out.size() != 0) tmp.out_type_desc = CORBA::string_dup(str_out.c_str()); else tmp.out_type_desc = CORBA::string_dup(NotSet); (*back)[i] = tmp; } for (long i = 0;i < nb_cmd_dev;i++) { Command *cmd_ptr = get_local_command_list()[i]; Tango::DevCmdInfo_2 tmp; tmp.cmd_name = CORBA::string_dup(cmd_ptr->get_name().c_str()); tmp.cmd_tag = 0; tmp.level = cmd_ptr->get_disp_level(); tmp.in_type = (long)(cmd_ptr->get_in_type()); tmp.out_type = (long)(cmd_ptr->get_out_type()); string &str_in = cmd_ptr->get_in_type_desc(); if (str_in.size() != 0) tmp.in_type_desc = CORBA::string_dup(str_in.c_str()); else tmp.in_type_desc = CORBA::string_dup(NotSet); string &str_out = cmd_ptr->get_out_type_desc(); if (str_out.size() != 0) tmp.out_type_desc = CORBA::string_dup(str_out.c_str()); else tmp.out_type_desc = CORBA::string_dup(NotSet); (*back)[i + nb_cmd_class] = tmp; } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::command_list_query_2"); } // // Return to caller // cout4 << "Leaving Device_2Impl::command_list_query_2" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::command_query_2 // // description : CORBA operation to read a device command info. // This method returns command info for a specific // command. // // WARNING !!!!!!!!!!!!!!!!!! // // This is the release 2 of this CORBA operation which // returns one more parameter than in release 1 // The code has been duplicated in order to keep it clean // (avoid many "if" on version number in a common method) // //-------------------------------------------------------------------------- Tango::DevCmdInfo_2 *Device_2Impl::command_query_2(const char *command) { cout4 << "DeviceImpl::command_query_2 arrived" << endl; Tango::DevCmdInfo_2 *back = NULL; string cmd(command); transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command_2); // // Allocate memory for the stucture sent back to caller. The ORB will free it // try { back = new Tango::DevCmdInfo_2(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::command_query_2"); } // // Try to retrieve the command in the command list first at class level then at device level // (in case of dyn command instaleld at device level) // long i; bool found = false; Command *cmd_ptr = Tango_nullptr; long nb_cmd = device_class->get_command_list().size(); for (i = 0;i < nb_cmd;i++) { if (device_class->get_command_list()[i]->get_lower_name() == cmd) { found = true; cmd_ptr = device_class->get_command_list()[i]; break; } } if (found == false) { nb_cmd = get_local_command_list().size(); for (i = 0;i < nb_cmd;i++) { if (get_local_command_list()[i]->get_lower_name() == cmd) { found = true; cmd_ptr = get_local_command_list()[i]; break; } } } if (found == true) { back->cmd_name = CORBA::string_dup(cmd_ptr->get_name().c_str()); back->cmd_tag = 0; back->level = cmd_ptr->get_disp_level(); back->in_type = (long)(cmd_ptr->get_in_type()); back->out_type = (long)(cmd_ptr->get_out_type()); string &str_in = cmd_ptr->get_in_type_desc(); if (str_in.size() != 0) back->in_type_desc = CORBA::string_dup(str_in.c_str()); else back->in_type_desc = CORBA::string_dup(NotSet); string &str_out = cmd_ptr->get_out_type_desc(); if (str_out.size() != 0) back->out_type_desc = CORBA::string_dup(str_out.c_str()); else back->out_type_desc = CORBA::string_dup(NotSet); } else { delete back; cout3 << "Device_2Impl::command_query_2(): command " << command << " not found" << endl; // // throw an exception to client // TangoSys_OMemStream o; o << "Command " << command << " not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"Device_2Impl::command_query_2"); } // // Return to caller // cout4 << "Leaving Device_2Impl::command_query_2" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::get_attribute_config_2 // // description : CORBA operation to get attribute configuration. // // argument: in : - names: name of attribute(s) // // This method returns a pointer to a AttributeConfigList_2 with one // AttributeConfig_2 structure for each atribute // // // WARNING !!!!!!!!!!!!!!!!!! // // This is the release 2 of this CORBA operation which // returns one more parameter than in release 1 // The code has been duplicated in order to keep it clean // (avoid many "if" on version number in a common method) // //-------------------------------------------------------------------------- Tango::AttributeConfigList_2 *Device_2Impl::get_attribute_config_2(const Tango::DevVarStringArray& names) throw(Tango::DevFailed, CORBA::SystemException) { TangoMonitor &mon = get_att_conf_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_2Impl::get_attribute_config_2 arrived" << endl; long nb_attr = names.length(); Tango::AttributeConfigList_2 *back = NULL; bool all_attr = false; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Get_Attr_Config_2); // // Get attribute number and device version // long nb_dev_attr = dev_attr->get_attr_nb(); long vers = get_dev_idl_version(); // // Check if the caller want to get config for all attribute // If the device implements IDL 3 (State and status as attributes) // and the client is an old one (not able to read state/status as // attribute), decrement attribute number // string in_name(names[0]); if (nb_attr == 1) { if (in_name == AllAttr) { all_attr = true; if (vers < 3) nb_attr = nb_dev_attr; else nb_attr = nb_dev_attr - 2; } else if (in_name == AllAttr_3) { all_attr = true; nb_attr = nb_dev_attr; } } // // Allocate memory for the AttributeConfig structures // try { back = new Tango::AttributeConfigList_2(nb_attr); back->length(nb_attr); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::get_attribute_config_2"); } // // Fill in these structures // for (long i = 0;i < nb_attr;i++) { try { if (all_attr == true) { Attribute &attr = dev_attr->get_attr_by_ind(i); attr.get_properties((*back)[i]); } else { Attribute &attr = dev_attr->get_attr_by_name(names[i]); attr.get_properties((*back)[i]); } } catch (Tango::DevFailed &) { delete back; throw; } } // // Return to caller // cout4 << "Leaving Device_2Impl::get_attribute_config_2" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::command_inout_history_2 // // description : CORBA operation to read command result history from // the polling buffer. // // argument: in : - command : command name // - n : history depth (in record number) // // This method returns a pointer to a DevCmdHistoryList with one // DevCmdHistory structure for each command record // //-------------------------------------------------------------------------- Tango::DevCmdHistoryList *Device_2Impl::command_inout_history_2(const char* command, CORBA::Long n) throw(Tango::DevFailed, CORBA::SystemException) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_2Impl::command_inout_history_2 arrived" << endl; Tango::DevCmdHistoryList *back = NULL; string cmd_str(command); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command_inout_history_2); // // Check that device supports this command. Also checks if the device // implements IDL 3 (Tango V5) and state or status history is requested // transform(cmd_str.begin(),cmd_str.end(),cmd_str.begin(),::tolower); check_command_exists(cmd_str); bool status_cmd = false; bool state_cmd = false; long vers = get_dev_idl_version(); if (vers >= 3) { if (cmd_str == "state") state_cmd = true; else if (cmd_str == "status") status_cmd = true; } // // Check that the command is polled // PollObj *polled_cmd = NULL; vector &poll_list = get_poll_obj_list(); unsigned long i; for (i = 0;i < poll_list.size();i++) { if (poll_list[i]->get_name() == cmd_str) { if ((state_cmd == true) || (status_cmd == true)) { if (poll_list[i]->get_type() == Tango::POLL_ATTR) { polled_cmd = poll_list[i]; } } else { if (poll_list[i]->get_type() == Tango::POLL_CMD) { polled_cmd = poll_list[i]; } } } } if (polled_cmd == NULL) { TangoSys_OMemStream o; o << "Command " << cmd_str << " not polled" << ends; Except::throw_exception((const char *)API_CmdNotPolled, o.str(), (const char *)"Device_2Impl::command_inout_history_2"); } // // Check that some data is available in cache // if (polled_cmd->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for command " << cmd_str << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_2Impl::command_inout_history_2"); } // // Set the number of returned records // long in_buf = polled_cmd->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevCmdHistoryList(n); back->length(n); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::command_inout_history_2"); } // // Get command result history // Warning : Starting with Tango V5 (IDL 3), state and status are polled // as attributes but could also be retrieved as commands. In this case, // retrieved the history as attributes and transfer this as command // if ((state_cmd == true) || (status_cmd == true)) { Tango::DevAttrHistoryList_3 *back_attr = NULL; try { back_attr = new Tango::DevAttrHistoryList_3(n); back_attr->length(n); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::command_inout_history_2"); } if (status_cmd == true) { if (vers >= 4) polled_cmd->get_attr_history_43(n,back_attr,Tango::DEV_STRING); else polled_cmd->get_attr_history(n,back_attr,Tango::DEV_STRING); for (int k = 0;k < n;k++) { (*back)[k].time = (*back_attr)[k].value.time; (*back)[k].cmd_failed = (*back_attr)[k].attr_failed; Tango::DevVarStringArray *dvsa; (*back_attr)[k].value.value >>= dvsa; (*back)[k].value <<= (*dvsa)[0]; (*back)[k].errors = (*back_attr)[k].value.err_list; } } else { if (vers >= 4) polled_cmd->get_attr_history_43(n,back_attr,Tango::DEV_STATE); else polled_cmd->get_attr_history(n,back_attr,Tango::DEV_STATE); for (int k = 0;k < n;k++) { (*back)[k].time = (*back_attr)[k].value.time; (*back)[k].cmd_failed = (*back_attr)[k].attr_failed; (*back)[k].errors = (*back_attr)[k].value.err_list; if ((*back)[k].cmd_failed == false) { Tango::DevState sta; (*back_attr)[k].value.value >>= sta; (*back)[k].value <<= sta; } } } delete back_attr; } else polled_cmd->get_cmd_history(n,back); cout4 << "Leaving Device_2Impl::command_inout_history_2 method" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::read_attribute_history_2 // // description : CORBA operation to read attribute alue history from // the polling buffer. // // argument: in : - name : attribute name // - n : history depth (in record number) // // This method returns a pointer to a DevAttrHistoryList with one // DevAttrHistory structure for each attribute record // //-------------------------------------------------------------------------- Tango::DevAttrHistoryList *Device_2Impl::read_attribute_history_2(const char* name, CORBA::Long n) throw(Tango::DevFailed, CORBA::SystemException) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_2Impl::read_attribute_history_2 arrived" << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Read_Attr_history_2); long vers = get_dev_idl_version(); Tango::DevAttrHistoryList *back = NULL; Tango::DevAttrHistoryList_3 *back_3 = NULL; vector &poll_list = get_poll_obj_list(); long nb_poll = poll_list.size(); // // Check that the device supports this attribute. This method returns an // exception in case of unsupported attribute // Attribute &att = dev_attr->get_attr_by_name(name); string attr_str(name); transform(attr_str.begin(),attr_str.end(),attr_str.begin(),::tolower); // // Check that the wanted attribute is polled. // long j; PollObj *polled_attr = NULL; for (j = 0;j < nb_poll;j++) { if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (poll_list[j]->get_name() == attr_str)) { polled_attr = poll_list[j]; break; } } if (polled_attr == NULL) { TangoSys_OMemStream o; o << "Attribute " << attr_str << " not polled" << ends; Except::throw_exception((const char *)API_AttrNotPolled, o.str(), (const char *)"Device_2Impl::read_attribute_history_2"); } // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << attr_str << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_2Impl::read_attribute_history_2"); } // // Set the number of returned records // long in_buf = polled_attr->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevAttrHistoryList(n); back->length(n); if (vers >= 3) { back_3 = new Tango::DevAttrHistoryList_3(n); back_3->length(n); } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_2Impl::read_attribute_history_2"); } // // Get attribute value history // if (vers < 3) polled_attr->get_attr_history(n,back,att.get_data_type()); else { polled_attr->get_attr_history(n,back_3,att.get_data_type()); Hist_32Hist(back_3,back); delete back_3; } cout4 << "Leaving Device_2Impl::command_inout_history_2 method" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::attr2cmd // // description : Method to transfer attribute value into the same // kind of data used to transprt command result on // the network (A CORBA Any) // // Args (in) : att_val : A reference to the complete attribute // value // state : Boolean set to true if this method is called // for the state command // status : Boolean set to true if this method is called // for the status command // //-------------------------------------------------------------------------- CORBA::Any *Device_2Impl::attr2cmd(AttributeValue_3 &att_val,bool state,bool status) { CORBA::Any *any = new CORBA::Any(); if (state == true) { Tango::DevState sta; att_val.value >>= sta; (*any) <<= sta; } else if (status == true) { Tango::DevVarStringArray *dvsa; att_val.value >>= dvsa; (*any) <<= (*dvsa)[0]; } return any; } CORBA::Any *Device_2Impl::attr2cmd(AttributeValue_4 &att_val,bool state,bool status) { CORBA::Any *any = new CORBA::Any(); if (state == true) { const Tango::DevState &sta = att_val.value.dev_state_att(); (*any) <<= sta; } else if (status == true) { Tango::DevVarStringArray &dvsa = att_val.value.string_att_value(); (*any) <<= dvsa[0]; } return any; } CORBA::Any *Device_2Impl::attr2cmd(AttributeValue_5 &att_val,bool state,bool status) { CORBA::Any *any = new CORBA::Any(); if (state == true) { const Tango::DevState &sta = att_val.value.dev_state_att(); (*any) <<= sta; } else if (status == true) { Tango::DevVarStringArray &dvsa = att_val.value.string_att_value(); (*any) <<= dvsa[0]; } return any; } //+------------------------------------------------------------------------- // // method : Device_2Impl::Hist_32Hist // // description : Move data from a AttrHistory_3 sequence to an // AttrHistory sequence. Usefull for client linked // with V4 requested history from attribute belonging // to device linked with V5 and inheriting from // Device_3Impl // // Args (in) : back_3 : Pointer to the Attr History 3 sequence // back : Pointer to the Attr History sequence // //-------------------------------------------------------------------------- void Device_2Impl::Hist_32Hist(DevAttrHistoryList_3 *back_3,DevAttrHistoryList *back) { unsigned long nb = back_3->length(); for (unsigned long i = 0;i < nb;i++) { (*back)[i].attr_failed = (*back_3)[i].attr_failed; (*back)[i].value.value = (*back_3)[i].value.value; (*back)[i].value.quality = (*back_3)[i].value.quality; (*back)[i].value.time = (*back_3)[i].value.time; (*back)[i].value.name = (*back_3)[i].value.name; (*back)[i].value.dim_x = (*back_3)[i].value.r_dim.dim_x; (*back)[i].value.dim_y = (*back_3)[i].value.r_dim.dim_y; (*back)[i].errors = (*back_3)[i].value.err_list; } } //+------------------------------------------------------------------------- // // method : Device_2Impl::Polled_2_Live // // description : Move data from a polled V4 device attribute to the Any // used in a V2 or V1 read_attribute request // // Args (in) : data_type : Atrtribute data type // hist_union : Reference to the Union object within the history buffer // live_any : Reference to the Any object returned to the caller // //-------------------------------------------------------------------------- void Device_2Impl::Polled_2_Live(TANGO_UNUSED(long data_type),Tango::AttrValUnion &hist_union,CORBA::Any &live_any) { switch (hist_union._d()) { case ATT_BOOL: { DevVarBooleanArray &union_seq = hist_union.bool_att_value(); live_any <<= union_seq; } break; case ATT_SHORT: { DevVarShortArray &union_seq = hist_union.short_att_value(); live_any <<= union_seq; } break; case ATT_LONG: { DevVarLongArray &union_seq = hist_union.long_att_value(); live_any <<= union_seq; } break; case ATT_LONG64: { DevVarLong64Array &union_seq = hist_union.long64_att_value(); live_any <<= union_seq; } break; case ATT_FLOAT: { DevVarFloatArray &union_seq = hist_union.float_att_value(); live_any <<= union_seq; } break; case ATT_DOUBLE: { DevVarDoubleArray &union_seq = hist_union.double_att_value(); live_any <<= union_seq; } break; case ATT_UCHAR: { DevVarCharArray &union_seq = hist_union.uchar_att_value(); live_any <<= union_seq; } break; case ATT_USHORT: { DevVarUShortArray &union_seq = hist_union.ushort_att_value(); live_any <<= union_seq; } break; case ATT_ULONG: { DevVarULongArray &union_seq = hist_union.ulong_att_value(); live_any <<= union_seq; } break; case ATT_ULONG64: { DevVarULong64Array &union_seq = hist_union.ulong64_att_value(); live_any <<= union_seq; } break; case ATT_STRING: { const DevVarStringArray &union_seq = hist_union.string_att_value(); live_any <<= union_seq; } break; case ATT_STATE: { DevVarStateArray &union_seq = hist_union.state_att_value(); live_any <<= union_seq; } break; case DEVICE_STATE: { DevState union_sta = hist_union.dev_state_att(); live_any <<= union_sta; } break; case ATT_ENCODED: case ATT_NO_DATA: break; } } void Device_2Impl::Polled_2_Live(long data_type,CORBA::Any &hist_any,CORBA::Any &live_any) { const Tango::DevVarDoubleArray *tmp_db; Tango::DevVarDoubleArray *new_tmp_db; const Tango::DevVarShortArray *tmp_sh; Tango::DevVarShortArray *new_tmp_sh; const Tango::DevVarLongArray *tmp_lg; Tango::DevVarLongArray *new_tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; Tango::DevVarLong64Array *new_tmp_lg64; const Tango::DevVarStringArray *tmp_str; Tango::DevVarStringArray *new_tmp_str; const Tango::DevVarFloatArray *tmp_fl; Tango::DevVarFloatArray *new_tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; Tango::DevVarBooleanArray *new_tmp_boo; const Tango::DevVarUShortArray *tmp_ush; Tango::DevVarUShortArray *new_tmp_ush; const Tango::DevVarCharArray *tmp_uch; Tango::DevVarCharArray *new_tmp_uch; const Tango::DevVarULongArray *tmp_ulg; Tango::DevVarULongArray *new_tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; Tango::DevVarULong64Array *new_tmp_ulg64; const Tango::DevVarStateArray *tmp_state; Tango::DevVarStateArray *new_tmp_state; switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : hist_any >>= tmp_sh; new_tmp_sh = new DevVarShortArray( tmp_sh->length(), tmp_sh->length(), const_cast(tmp_sh->get_buffer()), false); live_any <<= new_tmp_sh; break; case Tango::DEV_DOUBLE : hist_any >>= tmp_db; new_tmp_db = new DevVarDoubleArray( tmp_db->length(), tmp_db->length(), const_cast(tmp_db->get_buffer()), false); live_any <<= new_tmp_db; break; case Tango::DEV_LONG : hist_any >>= tmp_lg; new_tmp_lg = new DevVarLongArray(tmp_lg->length(),tmp_lg->length(), const_cast(tmp_lg->get_buffer()),false); live_any <<= new_tmp_lg; break; case Tango::DEV_LONG64 : hist_any >>= tmp_lg64; new_tmp_lg64 = new DevVarLong64Array(tmp_lg64->length(),tmp_lg64->length(), const_cast(tmp_lg64->get_buffer()),false); live_any <<= new_tmp_lg64; break; case Tango::DEV_STRING : hist_any >>= tmp_str; new_tmp_str = new DevVarStringArray( tmp_str->length(), tmp_str->length(), const_cast(tmp_str->get_buffer()), false); live_any <<= new_tmp_str; break; case Tango::DEV_FLOAT : hist_any >>= tmp_fl; new_tmp_fl = new DevVarFloatArray( tmp_fl->length(), tmp_fl->length(), const_cast(tmp_fl->get_buffer()), false); live_any <<= new_tmp_fl; break; case Tango::DEV_BOOLEAN : hist_any >>= tmp_boo; new_tmp_boo = new DevVarBooleanArray( tmp_boo->length(), tmp_boo->length(), const_cast(tmp_boo->get_buffer()), false); live_any <<= new_tmp_boo; break; case Tango::DEV_USHORT : hist_any >>= tmp_ush; new_tmp_ush = new DevVarUShortArray( tmp_ush->length(), tmp_ush->length(), const_cast(tmp_ush->get_buffer()), false); live_any <<= new_tmp_ush; break; case Tango::DEV_UCHAR : hist_any >>= tmp_uch; new_tmp_uch = new DevVarCharArray( tmp_uch->length(), tmp_uch->length(), const_cast(tmp_uch->get_buffer()), false); live_any <<= new_tmp_uch; break; case Tango::DEV_ULONG : hist_any >>= tmp_ulg; new_tmp_ulg = new DevVarULongArray(tmp_ulg->length(),tmp_ulg->length(), const_cast(tmp_ulg->get_buffer()),false); live_any <<= new_tmp_ulg; break; case Tango::DEV_ULONG64 : hist_any >>= tmp_ulg64; new_tmp_ulg64 = new DevVarULong64Array(tmp_ulg64->length(),tmp_ulg64->length(), const_cast(tmp_ulg64->get_buffer()),false); live_any <<= new_tmp_ulg64; break; case Tango::DEV_STATE : hist_any >>= tmp_state; new_tmp_state = new DevVarStateArray(tmp_state->length(),tmp_state->length(), const_cast(tmp_state->get_buffer()),false); live_any <<= new_tmp_state; break; } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/device_3.cpp0000644023471100065110000022550713034745001014761 00000000000000static const char *RcsId = "$Id: device_3.cpp 29538 2016-03-24 14:38:00Z taurel $\n$Name$"; //==================================================================================================================== // // file : Device_3.cpp // // description : C++ source code for the DeviceImpl and DeviceClass classes. These classes are the root class // for all derived Device classes. They are abstract classes. The DeviceImpl class is the // CORBA servant which is "exported" onto the network and accessed by the client. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29538 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::Device_3Impl // // description : // Constructors for the device_impl class from the class object pointer, the device name, the description field, // the state and the status. Device_3Impl inherits from DeviceImpl. These constructors simply call the correct // DeviceImpl class constructor // //-------------------------------------------------------------------------------------------------------------------- Device_3Impl::Device_3Impl(DeviceClass *device_class,string &dev_name): Device_2Impl(device_class,dev_name),ext_3(new Device_3ImplExt) { real_ctor(); } Device_3Impl::Device_3Impl(DeviceClass *device_class, string &dev_name, string &desc): Device_2Impl(device_class,dev_name,desc),ext_3(new Device_3ImplExt) { real_ctor(); } Device_3Impl::Device_3Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status): Device_2Impl(device_class,dev_name,desc,dev_state,dev_status),ext_3(new Device_3ImplExt) { real_ctor(); } Device_3Impl::Device_3Impl(DeviceClass *device_class, const char *dev_name, const char *desc, Tango::DevState dev_state, const char *dev_status): Device_2Impl(device_class,dev_name,desc,dev_state,dev_status),ext_3(new Device_3ImplExt) { real_ctor(); } void Device_3Impl::real_ctor() { idl_version = 3; add_state_status_attrs(); init_cmd_poll_period(); init_attr_poll_period(); Tango::Util *tg = Tango::Util::instance(); if (tg->_UseDb == false) { init_poll_no_db(); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::read_attributes_3 // // description : // Method called for each read_attributes operation executed from any client on a Tango device version 3. // //-------------------------------------------------------------------------------------------------------------------- Tango::AttributeValueList_3* Device_3Impl::read_attributes_3(const Tango::DevVarStringArray& names, Tango::DevSource source) { cout4 << "Device_3Impl::read_attributes_3 arrived for dev " << get_name() << ", att[0] = " << names[0] << endl; // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(names,3,source); store_in_bb = true; // // Build a sequence with the names of the attribute to be read. This is necessary in case of the "AllAttr" shortcut is // used. If all attributes are wanted, build this list // unsigned long nb_names = names.length(); unsigned long nb_dev_attr = dev_attr->get_attr_nb(); Tango::DevVarStringArray real_names(nb_names); unsigned long i; if (nb_names == 1) { string att_name(names[0]); if (att_name == AllAttr) { real_names.length(nb_dev_attr); for (i = 0;i < nb_dev_attr;i++) { real_names[i] = dev_attr->get_attr_by_ind(i).get_name().c_str(); } } else { real_names = names; } } else { real_names = names; } nb_names = real_names.length(); // // Allocate memory for the AttributeValue structures // AttributeIdlData aid; try { aid.data_3 = new Tango::AttributeValueList_3(nb_names); aid.data_3->length(nb_names); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_3Impl::read_attributes_3"); } // // If the source parameter specifies device, call the read_attributes method which does not throw exception except for // major fault (cannot allocate memory,....) // vector idx_in_back; if (source == Tango::DEV) { try { AutoTangoMonitor sync(this); read_attributes_no_except(real_names,aid,false,idx_in_back); } catch (...) { delete aid.data_3; throw; } } else if (source == Tango::CACHE) { try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_3; throw; } } else { // // It must be now CACHE_DEVICE (no other choice), first try to get values from cache // try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_3; throw; } // // Now, build the list of attributes which it was not possible to get their value from cache // Tango::DevVarStringArray names_from_device(nb_names); long nb_attr = 0; for (i = 0;i < nb_names;i++) { long nb_err = (*aid.data_3)[i].err_list.length(); if (nb_err != 0) { nb_err--; if ((strcmp((*aid.data_3)[i].err_list[nb_err].reason,API_AttrNotPolled) == 0) || (strcmp((*aid.data_3)[i].err_list[nb_err].reason,API_NoDataYet) == 0) || (strcmp((*aid.data_3)[i].err_list[nb_err].reason,API_NotUpdatedAnyMore) == 0) || (strcmp((*aid.data_3)[i].err_list[nb_err].origin,"DServer::add_obj_polling") == 0)) { nb_attr++; names_from_device.length(nb_attr); names_from_device[nb_attr - 1] = real_names[i]; idx_in_back.push_back(i); (*aid.data_3)[i].err_list.length(0); } } } if (nb_attr != 0) { // // Try to get their values from device // try { AutoTangoMonitor sync(this); read_attributes_no_except(names_from_device,aid,true,idx_in_back); } catch (...) { delete aid.data_3; throw; } } } return aid.data_3; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_3Impl::read_attributes_no_except // // description : // Read attributes from device but do not throw exception if it fails. This method is mainly a copy of the // original DeviceImpl::read_attributes method. // // arguments: // in : // - names: The names of the attribute to read // - aid : Structure with pointers for data to be returned to caller (several pointers acoording to // caller IDL level) // - second_try : Flag set to true when this method is called due to a client request with source set to // CACHE_DEVICE and the reading the value from the cache failed for one reason or another // - idx : Vector with index in back array for which we have to read data (to store error at the right // place in the array for instance) // //------------------------------------------------------------------------------------------------------------------- void Device_3Impl::read_attributes_no_except(const Tango::DevVarStringArray& names, Tango::AttributeIdlData &aid, bool second_try, vector &idx) { // // Write the device name into the per thread data for sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Catch all exceptions to set back the associated device after execution // try { // // Retrieve index of wanted attributes in the device attribute list and clear their value set flag // long nb_names = names.length(); vector wanted_attr; vector wanted_w_attr; bool state_wanted = false; bool status_wanted = false; long state_idx,status_idx; long i; state_idx = status_idx = -1; for (i = 0;i < nb_names;i++) { AttIdx x; x.idx_in_names = i; string att_name(names[i]); transform(att_name.begin(),att_name.end(),att_name.begin(),::tolower); if (att_name == "state") { x.idx_in_multi_attr = -1; x.failed = false; wanted_attr.push_back(x); state_wanted = true; state_idx = i; } else if (att_name == "status") { x.idx_in_multi_attr = -1; x.failed = false; wanted_attr.push_back(x); status_wanted = true; status_idx = i; } else { try { long j; j = dev_attr->get_attr_ind_by_name(names[i]); if ((dev_attr->get_attr_by_ind(j).get_writable() == Tango::READ_WRITE) || (dev_attr->get_attr_by_ind(j).get_writable() == Tango::READ_WITH_WRITE)) { x.idx_in_multi_attr = j; x.failed = false; Attribute &att = dev_attr->get_attr_by_ind(x.idx_in_multi_attr); if(att.is_startup_exception()) att.throw_startup_exception("Device_3Impl::read_attributes_no_except()"); wanted_w_attr.push_back(x); wanted_attr.push_back(x); att.get_when().tv_sec = 0; att.save_alarm_quality(); } else { if (dev_attr->get_attr_by_ind(j).get_writable() == Tango::WRITE) { // // If the attribute is a forwarded one, force reading it from the root device. Another client could have // written its value // if (dev_attr->get_attr_by_ind(j).is_fwd_att() == true) { x.idx_in_multi_attr = j; x.failed = false; Attribute &att = dev_attr->get_attr_by_ind(x.idx_in_multi_attr); if(att.is_startup_exception()) att.throw_startup_exception("Device_3Impl::read_attributes_no_except()"); wanted_attr.push_back(x); att.get_when().tv_sec = 0; att.save_alarm_quality(); } else { x.idx_in_multi_attr = j ; x.failed = false; Attribute &att = dev_attr->get_attr_by_ind(x.idx_in_multi_attr); if(att.is_startup_exception()) att.throw_startup_exception("Device_3Impl::read_attributes_no_except()"); wanted_w_attr.push_back(x); } } else { x.idx_in_multi_attr = j; x.failed = false; Attribute &att = dev_attr->get_attr_by_ind(x.idx_in_multi_attr); if(att.is_startup_exception()) att.throw_startup_exception("Device_3Impl::read_attributes_no_except()"); wanted_attr.push_back(x); att.get_when().tv_sec = 0; att.save_alarm_quality(); } } } catch (Tango::DevFailed &e) { long index; if (second_try == false) index = i; else index = idx[i]; if (aid.data_5 != Tango_nullptr) error_from_devfailed((*aid.data_5)[index],e,names[i]); else if (aid.data_4 != Tango_nullptr) error_from_devfailed((*aid.data_4)[index],e,names[i]); else error_from_devfailed((*aid.data_3)[index],e,names[i]); } } } long nb_wanted_attr = wanted_attr.size(); long nb_wanted_w_attr = wanted_w_attr.size(); // // Call the always_executed_hook // always_executed_hook(); // // Read the hardware for readable attribute but not for state/status // Warning: If the state is one of the wanted attribute, check and eventually add all the alarmed attributes index // if (nb_wanted_attr != 0) { vector tmp_idx; for (i = 0;i < nb_wanted_attr;i++) { long ii = wanted_attr[i].idx_in_multi_attr; if (ii != -1) tmp_idx.push_back(ii); } if (state_wanted == true) { if ((device_state == Tango::ON) || (device_state == Tango::ALARM)) add_alarmed(tmp_idx); } if (tmp_idx.empty() == false) read_attr_hardware(tmp_idx); } // // Set attr value (for readable attribute) but not for state/status // for (i = 0;i < nb_wanted_attr;i++) { if (wanted_attr[i].idx_in_multi_attr != -1) { Attribute &att = dev_attr->get_attr_by_ind(wanted_attr[i].idx_in_multi_attr); bool is_allowed_failed = false; try { vector &attr_vect = device_class->get_class_attr()->get_attr_list(); if (attr_vect[att.get_attr_idx()]->is_allowed(this,Tango::READ_REQ) == false) { is_allowed_failed = true; TangoSys_OMemStream o; o << "It is currently not allowed to read attribute "; o << att.get_name() << ends; Except::throw_exception((const char *)API_AttrNotAllowed, o.str(), (const char *)"Device_3Impl::read_attributes_no_except"); } // // Take the attribute mutex before calling the user read method // if ((att.get_attr_serial_model() == ATTR_BY_KERNEL) && (aid.data_4 != Tango_nullptr || aid.data_5 != Tango_nullptr)) { cout4 << "Locking attribute mutex for attribute " << att.get_name() << endl; omni_mutex *attr_mut = att.get_attr_mutex(); if (attr_mut->trylock() == 0) { cout4 << "Mutex for attribute " << att.get_name() << " is already taken.........." << endl; attr_mut->lock(); } } // // Call the user read method except if the attribute is writable and memorized and if the write failed during the // device startup sequence // att.set_value_flag(false); if (att.is_mem_exception() == false) attr_vect[att.get_attr_idx()]->read(this,att); else { Tango::WAttribute &w_att = static_cast(att); Tango::DevFailed df(w_att.get_mem_exception()); TangoSys_OMemStream o; o << "Attribute " << w_att.get_name() << " is a memorized attribute."; o << " It failed during the write call of the device startup sequence"; Tango::Except::re_throw_exception(df,API_MemAttFailedDuringInit,o.str(), "Device_3::read_attributes_no_except"); } // // Check alarm // if ((att.is_alarmed().any() == true) && (att.get_quality() != Tango::ATTR_INVALID)) att.check_alarm(); } catch (Tango::DevFailed &e) { long index; if (second_try == false) index = wanted_attr[i].idx_in_names; else index = idx[wanted_attr[i].idx_in_names]; wanted_attr[i].failed = true; if (aid.data_5 != Tango_nullptr) { if ((att.get_attr_serial_model() == ATTR_BY_KERNEL) && (is_allowed_failed == false)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = att.get_attr_mutex(); attr_mut->unlock(); } error_from_devfailed((*aid.data_5)[index],e,names[wanted_attr[i].idx_in_names]); } else if (aid.data_4 != Tango_nullptr) { if ((att.get_attr_serial_model() == ATTR_BY_KERNEL) && (is_allowed_failed == false)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = att.get_attr_mutex(); attr_mut->unlock(); } error_from_devfailed((*aid.data_4)[index],e,names[wanted_attr[i].idx_in_names]); } else error_from_devfailed((*aid.data_3)[index],e,names[wanted_attr[i].idx_in_names]); } catch (...) { long index; if (second_try == false) index = wanted_attr[i].idx_in_names; else index = idx[wanted_attr[i].idx_in_names]; wanted_attr[i].failed = true; Tango::DevErrorList del; del.length(1); del[0].severity = Tango::ERR; del[0].origin = CORBA::string_dup("Device_3Impl::read_attributes_no_except"); del[0].reason = CORBA::string_dup("API_CorbaSysException "); del[0].desc = CORBA::string_dup("Unforseen exception when trying to read attribute. It was even not a Tango DevFailed exception"); if (aid.data_5 != Tango_nullptr) { if ((att.get_attr_serial_model() == ATTR_BY_KERNEL) && (is_allowed_failed == false)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to a severe error which is not a DevFailed" << endl; omni_mutex *attr_mut = att.get_attr_mutex(); attr_mut->unlock(); } error_from_errorlist((*aid.data_5)[index],del,names[wanted_attr[i].idx_in_names]); } else if (aid.data_4 != Tango_nullptr) { if ((att.get_attr_serial_model() == ATTR_BY_KERNEL) && (is_allowed_failed == false)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to severe error which is not a DevFailed" << endl; omni_mutex *attr_mut = att.get_attr_mutex(); attr_mut->unlock(); } error_from_errorlist((*aid.data_4)[index],del,names[wanted_attr[i].idx_in_names]); } else error_from_errorlist((*aid.data_3)[index],del,names[wanted_attr[i].idx_in_names]); } } } // // Set attr value for writable attribute // for (i = 0;i < nb_wanted_w_attr;i++) { Attribute &att = dev_attr->get_attr_by_ind(wanted_w_attr[i].idx_in_multi_attr); Tango::AttrWriteType w_type = att.get_writable(); try { if (att.is_mem_exception() == true) { Tango::WAttribute &w_att = static_cast(att); Tango::DevFailed df(w_att.get_mem_exception()); TangoSys_OMemStream o; o << "Attribute " << w_att.get_name() << " is a memorized attribute."; o << " It failed during the write call of the device startup sequence"; Tango::Except::re_throw_exception(df,API_MemAttFailedDuringInit,o.str(), "Device_3::read_attributes_no_except"); } else { if ((w_type == Tango::READ_WITH_WRITE) || (w_type == Tango::WRITE)) att.set_rvalue(); } } catch (Tango::DevFailed &e) { long index; if (second_try == false) index = wanted_w_attr[i].idx_in_names; else index = idx[wanted_w_attr[i].idx_in_names]; wanted_w_attr[i].failed = true; AttrSerialModel atsm = att.get_attr_serial_model(); if (aid.data_5 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && (w_type == Tango::READ_WITH_WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } error_from_devfailed((*aid.data_5)[index],e,names[wanted_w_attr[i].idx_in_names]); } else if (aid.data_4 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && (w_type == Tango::READ_WITH_WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } error_from_devfailed((*aid.data_4)[index],e,names[wanted_w_attr[i].idx_in_names]); } else error_from_devfailed((*aid.data_3)[index],e,names[wanted_w_attr[i].idx_in_names]); } } // // If necessary, read state and/or status // If the device has some alarmed attributes and some of them have already been read and failed, it is not necessary // to read state, simply copy faulty alarmed attribute error message to the state attribute error messages // Tango::DevState d_state = Tango::UNKNOWN; Tango::ConstDevString d_status = Tango_nullptr; if (state_wanted == true) { // long id = reading_state_necessary(wanted_attr); long id = -1; if (id == -1) { try { alarmed_not_read(wanted_attr); state_from_read = true; if (is_alarm_state_forced() == true) d_state = DeviceImpl::dev_state(); else d_state = dev_state(); state_from_read = false; } catch (Tango::DevFailed &e) { state_from_read = false; if (aid.data_5 != Tango_nullptr) error_from_devfailed((*aid.data_5)[state_idx],e,names[state_idx]); else if (aid.data_4 != Tango_nullptr) error_from_devfailed((*aid.data_4)[state_idx],e,names[state_idx]); else error_from_devfailed((*aid.data_3)[state_idx],e,names[state_idx]); } } else { if (aid.data_5 != Tango_nullptr) error_from_errorlist((*aid.data_5)[state_idx],(*aid.data_5)[wanted_attr[id].idx_in_names].err_list,names[state_idx]); else if (aid.data_4 != Tango_nullptr) error_from_errorlist((*aid.data_4)[state_idx],(*aid.data_4)[wanted_attr[id].idx_in_names].err_list,names[state_idx]); else error_from_errorlist((*aid.data_3)[state_idx],(*aid.data_3)[wanted_attr[id].idx_in_names].err_list,names[state_idx]); } } if (status_wanted == true) { try { if (is_alarm_state_forced() == true) d_status = DeviceImpl::dev_status(); else d_status = dev_status(); } catch (Tango::DevFailed &e) { if (aid.data_5 != Tango_nullptr) error_from_devfailed((*aid.data_5)[status_idx],e,names[status_idx]); else if (aid.data_4 != Tango_nullptr) error_from_devfailed((*aid.data_4)[status_idx],e,names[status_idx]); else error_from_devfailed((*aid.data_3)[status_idx],e,names[status_idx]); } } // // Build the sequence returned to caller for readable attributes and check that all the wanted attributes set value // have been updated // for (i = 0;i < nb_names;i++) { long index; if (second_try == false) index = i; else index = idx[i]; unsigned long nb_err; if (aid.data_5 != Tango_nullptr) nb_err = (*aid.data_5)[index].err_list.length(); else if (aid.data_4 != Tango_nullptr) nb_err = (*aid.data_4)[index].err_list.length(); else nb_err = (*aid.data_3)[index].err_list.length(); if ((state_wanted == true) && (state_idx == i)) { if (aid.data_5 != Tango_nullptr) { if (nb_err == 0) state2attr(d_state,(*aid.data_5)[index]); } else if (aid.data_4 != Tango_nullptr) { if (nb_err == 0) state2attr(d_state,(*aid.data_4)[index]); } else { if (nb_err == 0) state2attr(d_state,(*aid.data_3)[index]); } continue; } if ((status_wanted == true) && (status_idx == i)) { if (aid.data_5 != Tango_nullptr) { if (nb_err == 0) status2attr(d_status,(*aid.data_5)[index]); } else if (aid.data_4 != Tango_nullptr) { if (nb_err == 0) status2attr(d_status,(*aid.data_4)[index]); } else { if (nb_err == 0) status2attr(d_status,(*aid.data_3)[index]); } continue; } if (nb_err == 0) { Attribute &att = dev_attr->get_attr_by_name(names[i]); Tango::AttrQuality qual = att.get_quality(); if (qual != Tango::ATTR_INVALID) { if (att.get_value_flag() == false) { TangoSys_OMemStream o; try { string att_name(names[i]); transform(att_name.begin(),att_name.end(),att_name.begin(),::tolower); vector::iterator ite = get_polled_obj_by_type_name(Tango::POLL_ATTR,att_name); long upd = (*ite)->get_upd(); if (upd == 0) { o << "Attribute "; o << att.get_name(); o << " value is available only by CACHE.\n"; o << "Attribute values are set by external polling buffer filling" << ends; } else { o << "Read value for attribute "; o << att.get_name(); o << " has not been updated" << ends; } } catch (Tango::DevFailed &) { o << "Read value for attribute "; o << att.get_name(); o << " has not been updated" << ends; } string s = o.str(); const char *ori = "Device_3Impl::read_attributes_no_except"; const char *reas = API_AttrValueNotSet; AttrSerialModel atsm = att.get_attr_serial_model(); if (aid.data_5 != NULL) { if ((i != state_idx) && (i != status_idx) && (atsm != ATTR_NO_SYNC) && (att.get_writable() != Tango::WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } one_error((*aid.data_5)[index],reas,ori,s,att); } else if (aid.data_4 != NULL) { if ((i != state_idx) && (i != status_idx) && (atsm != ATTR_NO_SYNC) && (att.get_writable() != Tango::WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } one_error((*aid.data_4)[index],reas,ori,s,att); } else one_error((*aid.data_3)[index],reas,ori,s,att); } else { try { Tango::AttrWriteType w_type = att.get_writable(); if ((w_type == Tango::READ) || (w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) { if ((w_type == Tango::READ_WRITE) || (w_type == Tango::READ_WITH_WRITE)) dev_attr->add_write_value(att); } // // Data into the network object // data_into_net_object(att,aid,index,w_type,true); // // Init remaining elements // if (att.get_when().tv_sec == 0) att.set_time(); AttrSerialModel atsm = att.get_attr_serial_model(); if (aid.data_5 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && ((att.is_fwd_att() == true) || (w_type != Tango::WRITE))) { cout4 << "Giving attribute mutex to CORBA structure for attribute " << att.get_name() << endl; if (atsm == ATTR_BY_KERNEL) GIVE_ATT_MUTEX_5(aid.data_5,index,att); else GIVE_USER_ATT_MUTEX_5(aid.data_5,index,att); } init_out_data((*aid.data_5)[index],att,w_type); (*aid.data_5)[index].data_format = att.get_data_format(); (*aid.data_5)[index].data_type = att.get_data_type(); } else if (aid.data_4 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && ((att.is_fwd_att() == true) || (w_type != Tango::WRITE))) { cout4 << "Giving attribute mutex to CORBA structure for attribute " << att.get_name() << endl; if (atsm == ATTR_BY_KERNEL) GIVE_ATT_MUTEX(aid.data_4,index,att); else GIVE_USER_ATT_MUTEX(aid.data_4,index,att); } init_out_data((*aid.data_4)[index],att,w_type); (*aid.data_4)[index].data_format = att.get_data_format(); } else { init_out_data((*aid.data_3)[index],att,w_type); } } catch (Tango::DevFailed &e) { if (aid.data_5 != Tango_nullptr) { cout4 << "Asking CORBA structure to release attribute mutex for attribute " << att.get_name() << endl; if (att.get_writable() != Tango::WRITE) { REL_ATT_MUTEX_5(aid.data_5,index,att); } error_from_devfailed((*aid.data_5)[index],e,att.get_name().c_str()); } else if (aid.data_4 != Tango_nullptr) { cout4 << "Asking CORBA structure to release attribute mutex for attribute " << att.get_name() << endl; if (att.get_writable() != Tango::WRITE) { REL_ATT_MUTEX(aid.data_4,index,att); } error_from_devfailed((*aid.data_4)[index],e,att.get_name().c_str()); } else error_from_devfailed((*aid.data_3)[index],e,att.get_name().c_str()); } } } else { if (qual != Tango::ATTR_INVALID) qual = Tango::ATTR_INVALID; if (att.get_when().tv_sec == 0) att.set_time(); AttrSerialModel atsm = att.get_attr_serial_model(); if (aid.data_5 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && (att.get_writable() != Tango::WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } init_out_data_quality((*aid.data_5)[index],att,qual); (*aid.data_5)[index].data_format = att.get_data_format(); (*aid.data_5)[index].data_type = att.get_data_type(); } else if (aid.data_4 != Tango_nullptr) { if ((atsm != ATTR_NO_SYNC) && (att.get_writable() != Tango::WRITE)) { cout4 << "Releasing attribute mutex for attribute " << att.get_name() << " due to error" << endl; omni_mutex *attr_mut = (atsm == ATTR_BY_KERNEL) ? att.get_attr_mutex() : att.get_user_attr_mutex(); attr_mut->unlock(); } init_out_data_quality((*aid.data_4)[index],att,qual); (*aid.data_4)[index].data_format = att.get_data_format(); } else { init_out_data_quality((*aid.data_3)[index],att,qual); } } } } } catch (...) { // // Set back the device attribution for the thread and rethrow the exception. // sub.set_associated_device(last_associated_device); throw; } // // Set back the device attribution for the thread // sub.set_associated_device(last_associated_device); cout4 << "Leaving Device_3Impl::read_attributes_no_except" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::read_attributes_from_cache // // description : // Read attributes from cache but do not throw exception if it fails. This method is mainly a copy of the original // DeviceImpl::read_attributes method. // // argument: // in : // - names: The names of the attribute to read // - aid : Structure with pointers to data which should be returned to the caller. This method is called for // 3 differents IDL releases (3, 4 and 5). In this struct, there is one ptr for each possible IDL. // Only the ptr for the caller IDL is not null. // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::read_attributes_from_cache(const Tango::DevVarStringArray& names,Tango::AttributeIdlData &aid) { unsigned long nb_names = names.length(); cout4 << "Reading " << nb_names << " attr in read_attributes_from_cache()" << endl; // // Check that device supports the wanted attribute and that the attribute is polled. If some are non polled, store // their index in the real_names sequence in a vector // unsigned long i; vector &poll_list = get_poll_obj_list(); vector non_polled; unsigned long nb_poll = poll_list.size(); unsigned long j; for (i = 0;i < nb_names;i++) { try { dev_attr->get_attr_ind_by_name(names[i]); for (j = 0;j < nb_poll;j++) { #ifdef _TG_WINDOWS_ if (_stricmp(poll_list[j]->get_name().c_str(),names[i]) == 0) #else if (strcasecmp(poll_list[j]->get_name().c_str(),names[i]) == 0) #endif break; } if (j == nb_poll) { non_polled.push_back(i); } } catch (Tango::DevFailed &e) { if (aid.data_5 != Tango_nullptr) error_from_devfailed((*aid.data_5)[i],e,names[i]); else if (aid.data_4 != Tango_nullptr) error_from_devfailed((*aid.data_4)[i],e,names[i]); else error_from_devfailed((*aid.data_3)[i],e,names[i]); } } // // If some attributes are not polled but their polling update period is defined, and the attribute is not in the device // list of attr which should not be polled, start to poll them // vector poll_period; unsigned long not_polled_attr = 0; if (non_polled.empty() == false) { // // Check that it is possible to start polling for the non polled attribute // for (i = 0;i < non_polled.size();i++) { Attribute &att = dev_attr->get_attr_by_name(names[non_polled[i]]); poll_period.push_back(att.get_polling_period()); if (poll_period.back() == 0) { TangoSys_OMemStream o; o << "Attribute " << att.get_name() << " not polled" << ends; string s = o.str(); const char *ori = "Device_3Impl::read_attributes_from_cache"; const char *reas = API_AttrNotPolled; if (aid.data_5 != NULL) one_error((*aid.data_5)[non_polled[i]],reas,ori,s,att); else if (aid.data_4 != NULL) one_error((*aid.data_4)[non_polled[i]],reas,ori,s,att); else one_error((*aid.data_3)[non_polled[i]],reas,ori,s,att); not_polled_attr++; continue; } } // // Leave method if number of attributes which should not be polled is equal to the requested attribute number // if (not_polled_attr == nb_names) return; } // // For each attribute, check that some data are available in cache and that they are not too old // for (i = 0;i < nb_names;i++) { if (aid.data_5 != Tango_nullptr) { if ((*aid.data_5)[i].err_list.length() != 0) continue; } else if (aid.data_4 != Tango_nullptr) { if ((*aid.data_4)[i].err_list.length() != 0) continue; } else { if ((*aid.data_3)[i].err_list.length() != 0) continue; } PollObj *polled_attr = NULL; unsigned long j; for (j = 0;j < poll_list.size();j++) { #ifdef _TG_WINDOWS_ if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (_stricmp(poll_list[j]->get_name().c_str(),names[i]) == 0)) #else if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (strcasecmp(poll_list[j]->get_name().c_str(),names[i]) == 0)) #endif { polled_attr = poll_list[j]; break; } } // // In some cases where data from polling are required by a DS for devices marked as polled but for which the polling // is not sarted yet, polled_attr could be NULL at the end of this loop. Return "No data yet" in this case // if (polled_attr == NULL) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << names[i] << ends; string s = o.str(); const char *ori = "Device_3Impl::read_attributes_from_cache"; const char *reas = API_NoDataYet; if (aid.data_5 != Tango_nullptr) { one_error((*aid.data_5)[i],reas,ori,s,names[i]); (*aid.data_5)[i].data_format = FMT_UNKNOWN; } else if (aid.data_4 != Tango_nullptr) { one_error((*aid.data_4)[i],reas,ori,s,names[i]); (*aid.data_4)[i].data_format = FMT_UNKNOWN; } else one_error((*aid.data_3)[i],reas,ori,s,names[i]); continue; } // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << names[i] << ends; string s = o.str(); const char *ori = "Device_3Impl::read_attributes_from_cache"; const char *reas = API_NoDataYet; if (aid.data_5 != Tango_nullptr) one_error((*aid.data_5)[i],reas,ori,s,names[i]); else if (aid.data_4 != Tango_nullptr) one_error((*aid.data_4)[i],reas,ori,s,names[i]); else one_error((*aid.data_3)[i],reas,ori,s,names[i]); continue; } // // Check that data are still refreshed by the polling thread // Skip this test for object with external polling triggering (upd = 0) // long tmp_upd = polled_attr->get_upd(); if (tmp_upd != 0) { double last = polled_attr->get_last_insert_date(); struct timeval now; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; double now_d = (double)now.tv_sec + ((double)now.tv_usec / 1000000); double diff_d = now_d - last; if (diff_d > polled_attr->get_authorized_delta()) { TangoSys_OMemStream o; o << "Data in cache for attribute " << names[i]; o << " not updated any more" << ends; string s = o.str(); const char *ori = "Device_3Impl::read_attributes_from_cache"; const char *reas = API_NotUpdatedAnyMore; if (aid.data_5 != Tango_nullptr) one_error((*aid.data_5)[i],reas,ori,s,names[i]); else if (aid.data_4 != Tango_nullptr) one_error((*aid.data_4)[i],reas,ori,s,names[i]); else one_error((*aid.data_3)[i],reas,ori,s,names[i]); continue; } } // // Get attribute data type // Attribute &att = dev_attr->get_attr_by_name(names[i]); long type = att.get_data_type(); // // Finally, after all these checks, get value and store it in the sequence sent back to user // In order to avoid unnecessary copy, don't use the assignement operator of the AttributeValue structure which copy // each element and therefore also copy the Any object. The Any assignement operator is a deep copy! // Create a new sequence using the attribute buffer and insert it into the Any. The sequence inside the source Any has // been created using the attribute data buffer. // try { long vers = get_dev_idl_version(); { omni_mutex_lock sync(*polled_attr); Tango::AttrQuality qual; // // Get device IDL release. Since release 4, devices are polled using read_attribute_4 // if (vers >= 5) { AttributeValue_5 &att_val = polled_attr->get_last_attr_value_5(false); qual = att_val.quality; } else if (vers == 4) { AttributeValue_4 &att_val = polled_attr->get_last_attr_value_4(false); qual = att_val.quality; } else { AttributeValue_3 &att_val = polled_attr->get_last_attr_value_3(false); qual = att_val.quality; } // // Copy the polled data into the Any or the union // if (qual != Tango::ATTR_INVALID) { polled_data_into_net_object(aid,i,type,vers,polled_attr,names); } // // Init remaining structure members according to IDL client (aid.xxxx) and IDL device (vers) // if (aid.data_5 != Tango_nullptr) { AttributeValue_5 &att_val = polled_attr->get_last_attr_value_5(false); init_polled_out_data((*aid.data_5)[i],att_val); (*aid.data_5)[i].data_format = att_val.data_format; (*aid.data_5)[i].data_type = att_val.data_type; } else if (aid.data_4 != Tango_nullptr) { if (vers >= 5) { AttributeValue_5 &att_val = polled_attr->get_last_attr_value_5(false); init_polled_out_data((*aid.data_4)[i],att_val); (*aid.data_4)[i].data_format = att_val.data_format; } else { AttributeValue_4 &att_val = polled_attr->get_last_attr_value_4(false); init_polled_out_data((*aid.data_4)[i],att_val); (*aid.data_4)[i].data_format = att_val.data_format; } } else { if (vers >= 5) { AttributeValue_5 &att_val = polled_attr->get_last_attr_value_5(false); init_polled_out_data((*aid.data_3)[i],att_val); } else if (vers == 4) { AttributeValue_4 &att_val = polled_attr->get_last_attr_value_4(false); init_polled_out_data((*aid.data_3)[i],att_val); } else { AttributeValue_3 &att_val = polled_attr->get_last_attr_value_3(false); init_polled_out_data((*aid.data_3)[i],att_val); } } } } catch (Tango::DevFailed &e) { if (aid.data_5 != Tango_nullptr) error_from_devfailed((*aid.data_5)[i],e,names[i]); else if (aid.data_4 != Tango_nullptr) error_from_devfailed((*aid.data_4)[i],e,names[i]); else error_from_devfailed((*aid.data_3)[i],e,names[i]); } } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::write_attributes_3 // // description : // CORBA operation to write attribute(s) value // // argument: // in : // - values: The new attribute(s) value to be set. // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::write_attributes_3(const Tango::AttributeValueList& values) { AutoTangoMonitor sync(this,true); cout4 << "Device_3Impl::write_attributes_3 arrived" << endl; // // Record operation request in black box. If this method is executed with the request to store info in // blackbox (store_in_bb == true), this means that the request arrives through a Device_2 CORBA interface. // Check locking feature in this case. Otherwise the request has arrived through Device_4 and the check // is already done // if (store_in_bb == true) { blackbox_ptr->insert_attr(values,3); check_lock("write_attributes_3"); } store_in_bb = true; // // Call the method really doing the job // write_attributes_34(&values,NULL); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceImpl::write_attributes_34 // // description : // Method to write the attribute. This method is common to the IDL interface 3 and 4. // // argument: // in : // - values_3: The new attribute(s) value to be set in IDL V3 // - values_4: The new attribute(s) value to be set in IDL V4 // //------------------------------------------------------------------------------------------------------------------ void Device_3Impl::write_attributes_34(const Tango::AttributeValueList *values_3,const Tango::AttributeValueList_4 *values_4) { // // Return exception if the device does not have any attribute // unsigned long nb_dev_attr = dev_attr->get_attr_nb(); if (nb_dev_attr == 0) { Except::throw_exception((const char *)API_AttrNotFound, (const char *)"The device does not have any attribute", (const char *)"DeviceImpl::write_attributes"); } unsigned long nb_failed = 0; Tango::NamedDevErrorList errs; // // Write the device name into the per thread data for sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Catch all exceptions to set back the associated device after execution // try { // // Retrieve index of wanted attributes in the device attribute list // vector updated_attr; unsigned long nb_updated_attr; if (values_3 != NULL) nb_updated_attr = values_3->length(); else nb_updated_attr = values_4->length(); unsigned long i; for (i = 0;i < nb_updated_attr;i++) { const char *single_att_name; long single_att_dimx,single_att_dimy; if (values_3 != NULL) { single_att_name = (*values_3)[i].name; single_att_dimx = (*values_3)[i].dim_x; single_att_dimy = (*values_3)[i].dim_y; } else { single_att_name = (*values_4)[i].name; single_att_dimx = (*values_4)[i].w_dim.dim_x; single_att_dimy = (*values_4)[i].w_dim.dim_y; } try { AttIdx idxs; idxs.idx_in_names = i; idxs.idx_in_multi_attr = dev_attr->get_attr_ind_by_name(single_att_name); updated_attr.push_back(idxs); // // Check that these attributes are writable. // For attributes which are not scalar, also check that their dimensions are correct // Attribute &att = dev_attr->get_attr_by_ind(updated_attr.back().idx_in_multi_attr); if ((att.get_writable() == Tango::READ) || (att.get_writable() == Tango::READ_WITH_WRITE)) { TangoSys_OMemStream o; o << "Attribute "; o << att.get_name(); o << " is not writable" << ends; updated_attr.pop_back(); Except::throw_exception((const char *)API_AttrNotWritable, o.str(), (const char *)"DeviceImpl::write_attributes"); } if (att.get_data_format() != Tango::SCALAR) { TangoSys_OMemStream o; bool err = false; if (att.get_max_dim_x() < single_att_dimx) { err = true; o << "X "; } if (err == false) { if (att.get_max_dim_y() < single_att_dimy) { err = true; o << "Y "; } } if (err == true) { o << "dimesion is greater than the max defined for attribute "; o << att.get_name(); o << ends; updated_attr.pop_back(); Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"DeviceImpl::write_attributes"); } } // // Check if there are some startup exceptions for the attribute (due to invalid attribute properties configuration). // If so, do not allow to write the attribute. // if(att.is_startup_exception() == true) { updated_attr.pop_back(); att.throw_startup_exception("DeviceImpl::write_attributes()"); } } catch (Tango::DevFailed &e) { nb_failed++; errs.length(nb_failed); errs[nb_failed - 1].name = CORBA::string_dup(single_att_name); errs[nb_failed - 1].index_in_call = i; errs[nb_failed - 1].err_list = e.errors; } } // // Call the always_executed_hook // if (nb_failed != nb_updated_attr) always_executed_hook(); // // Set attribute internal value // vector::iterator ctr; for (ctr = updated_attr.begin();ctr < updated_attr.end();++ctr) { const char *single_att_name; long single_att_dimx,single_att_dimy; if (values_3 != NULL) { single_att_name = (*values_3)[ctr->idx_in_names].name; single_att_dimx = (*values_3)[ctr->idx_in_names].dim_x; single_att_dimy = (*values_3)[ctr->idx_in_names].dim_y; } else { single_att_name = (*values_4)[ctr->idx_in_names].name; single_att_dimx = (*values_4)[ctr->idx_in_names].w_dim.dim_x; single_att_dimy = (*values_4)[ctr->idx_in_names].w_dim.dim_y; } try { if (values_3 == NULL) dev_attr->get_w_attr_by_ind(ctr->idx_in_multi_attr).check_written_value((*values_4)[ctr->idx_in_names].value, (unsigned long)single_att_dimx, (unsigned long)single_att_dimy); else dev_attr->get_w_attr_by_ind(ctr->idx_in_multi_attr).check_written_value((*values_3)[ctr->idx_in_names].value, (unsigned long)single_att_dimx, (unsigned long)single_att_dimy); } catch (Tango::DevFailed &e) { nb_failed++; errs.length(nb_failed); errs[nb_failed - 1].name = CORBA::string_dup(single_att_name); errs[nb_failed - 1].index_in_call = ctr->idx_in_names; errs[nb_failed - 1].err_list = e.errors; ctr = updated_attr.erase(ctr); if (ctr >= updated_attr.end()) break; else { if (ctr == updated_attr.begin()) break; else --ctr; } } } // // Write the hardware. Call this method one attribute at a time in order to correctly initialized the MultiDevFailed // exception in case one of the attribute failed. // if (nb_failed != nb_updated_attr) { vector::iterator ite; vector att_idx; for(ite = updated_attr.begin();ite != updated_attr.end();) { WAttribute &att = dev_attr->get_w_attr_by_ind((*ite).idx_in_multi_attr); att_idx.push_back(ite->idx_in_multi_attr); try { att.set_value_flag(false); att.set_user_set_write_value(false); vector &attr_vect = device_class->get_class_attr()->get_attr_list(); if (attr_vect[att.get_attr_idx()]->is_allowed(this,Tango::WRITE_REQ) == false) { TangoSys_OMemStream o; o << "It is currently not allowed to write attribute "; o << att.get_name(); o << ". The device state is " << Tango::DevStateName[get_state()] << ends; Except::throw_exception((const char *)API_AttrNotAllowed, o.str(), (const char *)"Device_3Impl::write_attributes"); } attr_vect[att.get_attr_idx()]->write(this,att); // // If the write call succeed and if the attribute was memorized but with an exception thrown during the device // startup sequence, clear the memorized exception // if (att.get_mem_write_failed() == true) { att.clear_mem_exception(); set_run_att_conf_loop(true); } ++ite; } catch (Tango::MultiDevFailed &e) { nb_failed++; if (att.get_data_format() == SCALAR) att.rollback(); errs.length(nb_failed); if (values_3 != NULL) errs[nb_failed - 1].name = CORBA::string_dup((*values_3)[(*ite).idx_in_names].name); else errs[nb_failed - 1].name = CORBA::string_dup((*values_4)[(*ite).idx_in_names].name); errs[nb_failed - 1].index_in_call = (*ite).idx_in_names; errs[nb_failed - 1].err_list = e.errors[0].err_list; ite = updated_attr.erase(ite); att_idx.pop_back(); } catch (Tango::DevFailed &e) { nb_failed++; if (att.get_data_format() == SCALAR) att.rollback(); errs.length(nb_failed); if (values_3 != NULL) errs[nb_failed - 1].name = CORBA::string_dup((*values_3)[(*ite).idx_in_names].name); else errs[nb_failed - 1].name = CORBA::string_dup((*values_4)[(*ite).idx_in_names].name); errs[nb_failed - 1].index_in_call = (*ite).idx_in_names; errs[nb_failed - 1].err_list = e.errors; ite = updated_attr.erase(ite); att_idx.pop_back(); } } // // Call the write_attr_hardware method // If it throws DevFailed exception, mark all attributes has failure // If it throws NamedDevFailedList exception, mark only referenced attributes as faulty // long vers = get_dev_idl_version(); if (vers >= 4) { try { write_attr_hardware(att_idx); } catch (Tango::MultiDevFailed &e) { for (unsigned long loop = 0;loop < e.errors.length();loop++) { nb_failed++; errs.length(nb_failed); vector::iterator ite_att; for(ite_att = updated_attr.begin();ite_att != updated_attr.end();++ite_att) { if (TG_strcasecmp(dev_attr->get_w_attr_by_ind(ite_att->idx_in_multi_attr).get_name().c_str(),e.errors[loop].name) == 0) { errs[nb_failed - 1].index_in_call = ite_att->idx_in_names; errs[nb_failed - 1].name = CORBA::string_dup(e.errors[loop].name); errs[nb_failed - 1].err_list = e.errors[loop].err_list; WAttribute &att = dev_attr->get_w_attr_by_ind(ite_att->idx_in_multi_attr); if (att.get_data_format() == SCALAR) att.rollback(); break; } } updated_attr.erase(ite_att); } } catch (Tango::DevFailed &e) { vector::iterator ite; for(ite = att_idx.begin();ite != att_idx.end();++ite) { WAttribute &att = dev_attr->get_w_attr_by_ind(*ite); nb_failed++; if (att.get_data_format() == SCALAR) att.rollback(); errs.length(nb_failed); errs[nb_failed - 1].name = CORBA::string_dup(att.get_name().c_str()); vector::iterator ite_att; for(ite_att = updated_attr.begin();ite_att != updated_attr.end();++ite_att) { if (ite_att->idx_in_multi_attr == *ite) { errs[nb_failed - 1].index_in_call = ite_att->idx_in_names; break; } } errs[nb_failed - 1].err_list = e.errors; } updated_attr.clear(); } } } // // Copy data into Attribute object, store the memorized one in db and if the attribute has a RDS alarm, set the write // date // // Warning: Do not copy caller value if the user has manually set the attribute written value in its write method // // WARNING: --> The DevEncoded data type is supported only as SCALAR and is not memorizable. // Therefore, no need to call copy_data // vector att_in_db; for (i = 0;i < updated_attr.size();i++) { WAttribute &att = dev_attr->get_w_attr_by_ind(updated_attr[i].idx_in_multi_attr); if (values_3 != NULL) { if (att.get_user_set_write_value() == false) att.copy_data((*values_3)[updated_attr[i].idx_in_names].value); } else { if (att.get_user_set_write_value() == false) att.copy_data((*values_4)[updated_attr[i].idx_in_names].value); } if (att.is_memorized() == true) { att_in_db.push_back(i); if (att.get_mem_value() == MemNotUsed) att.set_mem_value("Set"); } if (att.is_alarmed().test(Attribute::rds) == true) att.set_written_date(); } if ((Tango::Util::_UseDb == true) && (att_in_db.empty() == false)) { try { write_attributes_in_db(att_in_db,updated_attr); } catch (Tango::DevFailed &e) { errs.length(nb_failed + att_in_db.size()); for (i = 0;i < att_in_db.size();i++) { const char *single_att_name; if (values_3 != NULL) single_att_name = (*values_3)[updated_attr[att_in_db[i]].idx_in_names].name; else single_att_name = (*values_4)[updated_attr[att_in_db[i]].idx_in_names].name; errs[nb_failed + i].name = CORBA::string_dup(single_att_name); errs[nb_failed + i].index_in_call = updated_attr[att_in_db[i]].idx_in_names; errs[nb_failed + i].err_list = e.errors; } nb_failed = nb_failed + att_in_db.size(); } } } catch (...) { // // Set back the device attribution for the thread and rethrow the exception. // sub.set_associated_device(last_associated_device); throw; } // // Set back the device attribution for the thread // sub.set_associated_device(last_associated_device); // // Return to caller. // cout4 << "Leaving Device_3Impl::write_attributes_34" << endl; if (nb_failed != 0) { throw Tango::MultiDevFailed(errs); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::read_attribute_history_3 // // description : // CORBA operation to read attribute value history from the polling buffer. // // argument: // in : // - name : attribute name // - n : history depth (in record number) // // return : // This method returns a pointer to a DevAttrHistoryList with one DevAttrHistory structure for each // attribute record // //-------------------------------------------------------------------------------------------------------------------- Tango::DevAttrHistoryList_3 *Device_3Impl::read_attribute_history_3(const char* name, CORBA::Long n) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_3Impl::read_attribute_history_3 arrived" << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Read_Attr_history_3); Tango::DevAttrHistoryList_3 *back = NULL; vector &poll_list = get_poll_obj_list(); long nb_poll = poll_list.size(); // // Check that the device supports this attribute. This method returns an exception in case of unsupported attribute // Attribute &att = dev_attr->get_attr_by_name(name); string attr_str(name); transform(attr_str.begin(),attr_str.end(),attr_str.begin(),::tolower); // // Check that the wanted attribute is polled. // long j; PollObj *polled_attr = NULL; for (j = 0;j < nb_poll;j++) { if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (poll_list[j]->get_name() == attr_str)) { polled_attr = poll_list[j]; break; } } if (polled_attr == NULL) { TangoSys_OMemStream o; o << "Attribute " << attr_str << " not polled" << ends; Except::throw_exception((const char *)API_AttrNotPolled, o.str(), (const char *)"Device_3Impl::read_attribute_history_3"); } // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << attr_str << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_3Impl::read_attribute_history_3"); } // // Set the number of returned records // long in_buf = polled_attr->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevAttrHistoryList_3(n); back->length(n); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_3Impl::read_attribute_history_3"); } // // Get attribute value history // long vers = get_dev_idl_version(); if (vers < 4) polled_attr->get_attr_history(n,back,att.get_data_type()); else polled_attr->get_attr_history_43(n,back,att.get_data_type()); cout4 << "Leaving Device_3Impl::command_inout_history_3 method" << endl; return back; } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::info_3 // // description : // CORBA operation to get device info // //-------------------------------------------------------------------------------------------------------------------- Tango::DevInfo_3 *Device_3Impl::info_3() { cout4 << "Device_3Impl::info_3 arrived" << endl; Tango::DevInfo_3 *back = NULL; // // Allocate memory for the stucture sent back to caller. The ORB will free it // try { back = new Tango::DevInfo_3(); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_3Impl::info_3"); } // // Retrieve server host // Tango::Util *tango_ptr = Tango::Util::instance(); back->server_host = CORBA::string_dup(tango_ptr->get_host_name().c_str()); // // Fill-in remaining structure fields // back->dev_class = CORBA::string_dup(device_class->get_name().c_str()); back->server_id = CORBA::string_dup(tango_ptr->get_ds_name().c_str()); back->server_version = DevVersion; // // Build the complete info sent in the doc_url string // string doc_url("Doc URL = "); doc_url = doc_url + device_class->get_doc_url(); string &cvs_tag = device_class->get_cvs_tag(); if (cvs_tag.size() != 0) { doc_url = doc_url + "\nCVS Tag = "; doc_url = doc_url + cvs_tag; } string &cvs_location = device_class->get_cvs_location(); if (cvs_location.size() != 0) { doc_url = doc_url + "\nCVS Location = "; doc_url = doc_url + cvs_location; } back->doc_url = CORBA::string_dup(doc_url.c_str()); // // Set the device type // back->dev_type = CORBA::string_dup(device_class->get_type().c_str()); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Info_3); // // Return to caller // cout4 << "Leaving Device_3Impl::info_3" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_3Impl::get_attribute_config_3 // // description : // CORBA operation to get attribute configuration. // // WARNING !!!!!!!!!!!!!!!!!! // // This is the release 3 of this CORBA operation which returns much more parameter than in release 2 // The code has been duplicated in order to keep it clean (avoid many "if" on version number in a common method) // // argument: // in : // - names: name of attribute(s) // // return : // This method returns a pointer to a AttributeConfigList_3 with one AttributeConfig_3 structure for each atribute // //-------------------------------------------------------------------------------------------------------------------- Tango::AttributeConfigList_3 *Device_3Impl::get_attribute_config_3(const Tango::DevVarStringArray& names) { TangoMonitor &mon = get_att_conf_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_3Impl::get_attribute_config_3 arrived" << endl; long nb_attr = names.length(); Tango::AttributeConfigList_3 *back = NULL; bool all_attr = false; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Get_Attr_Config_3); // // Get attribute number and device version // long nb_dev_attr = dev_attr->get_attr_nb(); // // Check if the caller want to get config for all attribute. // If the device implements IDL 3 (State and status as attributes) and the client is an old one (not able to read // state/status as attribute), decrement attribute number // string in_name(names[0]); if (nb_attr == 1) { if (in_name == AllAttr_3) { all_attr = true; nb_attr = nb_dev_attr; } } // // Allocate memory for the AttributeConfig structures // try { back = new Tango::AttributeConfigList_3(nb_attr); back->length(nb_attr); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_3Impl::get_attribute_config_3"); } // // Fill in these structures // for (long i = 0;i < nb_attr;i++) { try { if (all_attr == true) { Attribute &attr = dev_attr->get_attr_by_ind(i); attr.get_properties((*back)[i]); } else { Attribute &attr = dev_attr->get_attr_by_name(names[i]); attr.get_properties((*back)[i]); } } catch (Tango::DevFailed &) { delete back; throw; } } // // Return to caller // cout4 << "Leaving Device_3Impl::get_attribute_config_3" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::set_attribute_config_3 // // description : // CORBA operation to set attribute configuration locally and in the Tango database // // argument: // in : // - new_conf: The new attribute(s) configuration. One AttributeConfig structure is needed for each // attribute to update // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::set_attribute_config_3(const Tango::AttributeConfigList_3& new_conf) { AutoTangoMonitor sync(this,true); cout4 << "DeviceImpl::set_attribute_config_3 arrived" << endl; // // The attribute conf. is protected by two monitors. One protects access between get and set attribute conf. // The second one protects access between set and usage. This is the classical device monitor // TangoMonitor &mon1 = get_att_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // Record operation request in black box // If this method is executed with the request to store info in blackbox (store_in_bb == true), this means that the // request arrives through a Device_2 CORBA interface. Check locking feature in this case. Otherwise the request has // arrived through Device_4 and the check is already done // if (store_in_bb == true) { blackbox_ptr->insert_op(Op_Set_Attr_Config_3); check_lock("set_attribute_config_3"); } store_in_bb = true; return set_attribute_config_3_local(new_conf,new_conf[0],false,3); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::write_attributes_in_db // // description : // Method to write memorized attributes in database // // argument: // in : // - name : attribute name // - n : history depth (in record number) // // return: // This method returns a pointer to a DevAttrHistoryList with one DevAttrHistory structure for each attribute // record // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::write_attributes_in_db(vector &att_in_db,vector &updated_attr) { // // Store memorized attribute in db // Tango::Util *tg = Tango::Util::instance(); Tango::Database *db = tg->get_database(); Tango::DbData db_data; for (unsigned long i = 0;i < att_in_db.size();i++) { Tango::DbDatum tmp_db; // // Update one property // long idx = att_in_db[i]; WAttribute &att = dev_attr->get_w_attr_by_ind(updated_attr[idx].idx_in_multi_attr); tmp_db.name = att.get_name(); tmp_db << (short)1; db_data.push_back(tmp_db); // // Init property value // tmp_db.name = MemAttrPropName; const char *ptr; switch (att.get_data_type()) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : tmp_db << (*att.get_last_written_sh())[0]; break; case Tango::DEV_LONG : tmp_db << (*att.get_last_written_lg())[0]; break; case Tango::DEV_LONG64 : tmp_db << (*att.get_last_written_lg64())[0]; break; case Tango::DEV_DOUBLE : tmp_db << (*att.get_last_written_db())[0]; break; case Tango::DEV_STRING : ptr = (*att.get_last_written_str())[0].in(); tmp_db << ptr; break; case Tango::DEV_FLOAT : tmp_db << (*att.get_last_written_fl())[0]; break; case Tango::DEV_BOOLEAN : tmp_db << (*att.get_last_written_boo())[0]; break; case Tango::DEV_USHORT : tmp_db << (*att.get_last_written_ush())[0]; break; case Tango::DEV_UCHAR : tmp_db << (*att.get_last_written_uch())[0]; break; case Tango::DEV_ULONG : tmp_db << (*att.get_last_written_ulg())[0]; break; case Tango::DEV_ULONG64 : tmp_db << (*att.get_last_written_ulg64())[0]; break; case Tango::DEV_STATE : { Tango::DevState tmp_state = (*att.get_last_written_state())[0]; tmp_db << (short)tmp_state; } break; } db_data.push_back(tmp_db); } db->put_device_attribute_property(device_name,db_data); } void Device_3Impl::write_attributes_in_db(vector &att_in_db,vector &updated_attr) { vector v; for (unsigned int i = 0;i < updated_attr.size();i++) { AttIdx ai; ai.idx_in_multi_attr = updated_attr[i]; v.push_back(ai); } write_attributes_in_db(att_in_db,v); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::add_state_status_attrs // // description : // Add state and status in the device attribute list // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::add_state_status_attrs() { // // First, create the State attribute with default properties // Tango::Attr att_state("State",Tango::DEV_STATE); vector prop_list_state; string att_name("State"); get_attr_props("State",prop_list_state); dev_attr->add_default(prop_list_state,device_name,att_name,Tango::DEV_STATE); dev_attr->add_attr(new Attribute(prop_list_state,att_state,device_name,-1)); // // Now, create the status attribute also with default properties // Tango::Attr att_status("Status",Tango::DEV_STRING); vector prop_list_status; att_name = "Status"; get_attr_props("Status",prop_list_status); dev_attr->add_default(prop_list_status,device_name,att_name,Tango::DEV_STRING); dev_attr->add_attr(new Attribute(prop_list_status,att_status,device_name,-1)); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::get_attr_props // // description : // Get attribute properties. This method is used to retrieve properties for state and status. // // argument: // in : // - attr_name : The attribute name // inout : // - prop_list : The attribute property vector // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::get_attr_props(const char *attr_name,vector &prop_list) { Tango::Util *tg = Tango::Util::instance(); if (tg->_UseDb == true) { Tango::DbData db_list; db_list.push_back(DbDatum(attr_name)); // // Get attr prop from db cache // try { tg->get_database()->get_device_attribute_property(device_name,db_list,tg->get_db_cache()); } catch (Tango::DevFailed &) { cout4 << "Exception while accessing database" << endl; TangoSys_OMemStream o; o << "Can't get device attribute properties for device " << device_name << ", attribute " << attr_name << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"Device_3Impl::get_attr_props"); } // // Insert AttrProperty element in suplied vector for att. properties found in DB // long ind = 0; long nb_prop = 0; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + ","; tmp = tmp + db_list[ind].value_string[k]; } prop_list.push_back(AttrProperty(db_list[ind].name,tmp)); } else prop_list.push_back(AttrProperty(db_list[ind].name, db_list[ind].value_string[0])); ind++; } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::add_alarmed // // description : // Method to add alarmed attributes (if not already there) in the attribute list passed as argument // // argument: // in : // - att_list : The attribute index in the multi attribute instance // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::add_alarmed(vector &att_list) { vector &alarmed_list = dev_attr->get_alarm_list(); long nb_wanted_attr = alarmed_list.size(); if (nb_wanted_attr != 0) { for (int i = 0;i < nb_wanted_attr;i++) { long nb_attr = att_list.size(); bool found = false; for (int j = 0;j < nb_attr;j++) { if (att_list[j] == alarmed_list[i]) { found = true; break; } } // // If not found, add it // if (found == false) { att_list.push_back(alarmed_list[i]); } } } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::reading_state_necessary // // description : // Method to check if it is necessary to read state. If the device has some alarmed attribute and one of these // attributes has already been read and failed, it is not necessary to read state. It will also fail. // // argument: // in : // - wanted_attr : The list of attribute to be read by this call // // return: // This method returns -1 if reading state is possible. Otherwise, it returns the index in the wanted_attr list // of the alarmed attribute which failed // //-------------------------------------------------------------------------------------------------------------------- long Device_3Impl::reading_state_necessary(vector &wanted_attr) { vector &alarmed_list = dev_attr->get_alarm_list(); long nb_alarmed_attr = alarmed_list.size(); long ret = -1; if (nb_alarmed_attr == 0) ret = -1; else { long nb_attr = wanted_attr.size(); for (int j = 0;j < nb_alarmed_attr;j++) { for (int i = 0;i < nb_attr;i++) { if (alarmed_list[j] == wanted_attr[i].idx_in_multi_attr) { if (wanted_attr[i].failed == true) return i; } } } } return ret; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::alarmed_not_read // // description : // This method find all the attributes which will be read by the state (because alarmed) and which have been // already read. It builds a vector with the list of attribute not read // // argument: // in : // - wanted_attr : The list of attribute to be read by this call // //--------------------------------------------------------------------------------------------------------------------- void Device_3Impl::alarmed_not_read(vector &wanted_attr) { vector &alarmed_list = dev_attr->get_alarm_list(); long nb_alarmed_attr = alarmed_list.size(); long nb_attr = wanted_attr.size(); alrmd_not_read.clear(); for (int i = 0;i < nb_alarmed_attr;i++) { bool found = false; for (int j = 0;j < nb_attr;j++) { if (alarmed_list[i] == wanted_attr[j].idx_in_multi_attr) { found = true; break; } } if (found == false) { alrmd_not_read.push_back(alarmed_list[i]); } } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::state2attr // // description : // Method to send a device state as an attribute object // // argument: // in : // - state : The device state // - back : The AttributeValue structure // //--------------------------------------------------------------------------------------------------------------------- void Device_3Impl::state2attr(Tango::DevState state,Tango::AttributeValue_3 &back) { base_state2attr(back); back.value <<= state; } void Device_3Impl::state2attr(Tango::DevState state,Tango::AttributeValue_4 &back) { base_state2attr(back); back.value.dev_state_att(state); back.data_format = Tango::SCALAR; } void Device_3Impl::state2attr(Tango::DevState state,Tango::AttributeValue_5 &back) { base_state2attr(back); back.value.dev_state_att(state); back.data_format = Tango::SCALAR; back.data_type = DEV_STATE; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_3Impl::status2attr // // description : // Method to send a device status string as an attribute object // // argument: // in : // - status : The device status // - back : The AttributeValue structure // //-------------------------------------------------------------------------------------------------------------------- void Device_3Impl::status2attr(Tango::ConstDevString status,Tango::AttributeValue_3 &back) { base_status2attr(back); Tango::DevVarStringArray str_seq(1); str_seq.length(1); str_seq[0] = CORBA::string_dup(status); back.value <<= str_seq; } void Device_3Impl::status2attr(Tango::ConstDevString status,Tango::AttributeValue_4 &back) { base_status2attr(back); Tango::DevVarStringArray str_seq(1); str_seq.length(1); str_seq[0] = CORBA::string_dup(status); back.value.string_att_value(str_seq); back.data_format = Tango::SCALAR; } void Device_3Impl::status2attr(Tango::ConstDevString status,Tango::AttributeValue_5 &back) { base_status2attr(back); Tango::DevVarStringArray str_seq(1); str_seq.length(1); str_seq[0] = CORBA::string_dup(status); back.value.string_att_value(str_seq); back.data_format = Tango::SCALAR; back.data_type = DEV_STRING; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/device_4.cpp0000644023471100065110000005433713034745002014764 00000000000000static const char *RcsId = "$Id: device_4.cpp 28853 2015-12-07 13:38:45Z taurel $"; //+============================================================================ // // file : Device_4.cpp // // description : C++ source code for the DeviceImpl and DeviceClass // classes. These classes // are the root class for all derived Device classes. // They are abstract classes. The DeviceImpl class is the // CORBA servant which is "exported" onto the network and // accessed by the client. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #include namespace Tango { //+------------------------------------------------------------------------- // // method : Device_4Impl::Device_4Impl // // description : constructors for the device_impl class from the // class object pointer, the device name, // the description field, the state and the status. // Device_4Impl inherits from DeviceImpl. These constructors // simply call the correct DeviceImpl class // constructor // //-------------------------------------------------------------------------- Device_4Impl::Device_4Impl(DeviceClass *device_class,string &dev_name): Device_3Impl(device_class,dev_name),ext_4(Tango_nullptr) { idl_version = 4; } Device_4Impl::Device_4Impl(DeviceClass *device_class, string &dev_name, string &desc): Device_3Impl(device_class,dev_name,desc),ext_4(Tango_nullptr) { idl_version = 4; } Device_4Impl::Device_4Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status): Device_3Impl(device_class,dev_name,desc,dev_state,dev_status),ext_4(Tango_nullptr) { idl_version = 4; } Device_4Impl::Device_4Impl(DeviceClass *device_class, const char *dev_name, const char *desc, Tango::DevState dev_state, const char *dev_status): Device_3Impl(device_class,dev_name,desc,dev_state,dev_status),ext_4(Tango_nullptr) { idl_version = 4; } //+------------------------------------------------------------------------- // // method : Device_4Impl::read_attribute_history_4 // // description : CORBA operation to read attribute value history from // the polling buffer. // // argument: in : - name : attribute name // - n : history depth (in record number) // // This method returns a pointer to a DevAttrHistory_4 structure // //-------------------------------------------------------------------------- Tango::DevAttrHistory_4 *Device_4Impl::read_attribute_history_4(const char* name,CORBA::Long n) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_4Impl::read_attribute_history_4 arrived, requested history depth = " << n << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Read_Attr_history_4); Tango::DevAttrHistory_4 *back = NULL; vector &poll_list = get_poll_obj_list(); long nb_poll = poll_list.size(); // // Check that the device supports this attribute. This method returns an // exception in case of unsupported attribute // Attribute &att = dev_attr->get_attr_by_name(name); string attr_str(name); transform(attr_str.begin(),attr_str.end(),attr_str.begin(),::tolower); // // Check that the wanted attribute is polled // long j; PollObj *polled_attr = NULL; for (j = 0;j < nb_poll;j++) { if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (poll_list[j]->get_name() == attr_str)) { polled_attr = poll_list[j]; break; } } if (polled_attr == NULL) { TangoSys_OMemStream o; o << "Attribute " << attr_str << " not polled" << ends; Except::throw_exception(API_AttrNotPolled,o.str(),"Device_4Impl::read_attribute_history_4"); } // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << attr_str << ends; Except::throw_exception(API_NoDataYet,o.str(),"Device_4Impl::read_attribute_history_4"); } // // Set the number of returned records // long in_buf = polled_attr->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevAttrHistory_4; back->dates.length(n); } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server", "Device_4Impl::read_attribute_history_4"); } // // Init attribute name in the returned structure // back->name = CORBA::string_dup(name); // // Get attribute value history // Trick: To identify the state used as an attribute from a classical attribute with type // DEV_STATE, use DEV_VOID for state as data type. // if (att.get_name_lower() == "state") polled_attr->get_attr_history(n,back,Tango::DEV_VOID,att.get_data_format()); else polled_attr->get_attr_history(n,back,att.get_data_type(),att.get_data_format()); cout4 << "Leaving Device_4Impl::read_attribute_history_4 method" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_2Impl::command_inout_history_4 // // description : CORBA operation to read command result history from // the polling buffer. // // argument: in : - command : command name // - n : history depth (in record number) // // This method returns a pointer to a DevCmdHistoryList with one // DevCmdHistory structure for each command record // //-------------------------------------------------------------------------- Tango::DevCmdHistory_4 *Device_4Impl::command_inout_history_4(const char* command,CORBA::Long n) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_4Impl::command_inout_history_4 arrived" << endl; Tango::DevCmdHistory_4 *back = NULL; string cmd_str(command); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Command_inout_history_4); // // Check that device supports this command. Also checks if the device // implements IDL >=3 when state or status history is requested // transform(cmd_str.begin(),cmd_str.end(),cmd_str.begin(),::tolower); check_command_exists(cmd_str); bool status_cmd = false; bool state_cmd = false; long vers = get_dev_idl_version(); if (vers >= 3) { if (cmd_str == "state") state_cmd = true; else if (cmd_str == "status") status_cmd = true; } // // Check that the command is polled // PollObj *polled_cmd = NULL; vector &poll_list = get_poll_obj_list(); unsigned long i; for (i = 0;i < poll_list.size();i++) { if (poll_list[i]->get_name() == cmd_str) { if ((state_cmd == true) || (status_cmd == true)) { if (poll_list[i]->get_type() == Tango::POLL_ATTR) { polled_cmd = poll_list[i]; } } else { if (poll_list[i]->get_type() == Tango::POLL_CMD) { polled_cmd = poll_list[i]; } } } } if (polled_cmd == NULL) { TangoSys_OMemStream o; o << "Command " << cmd_str << " not polled" << ends; Except::throw_exception((const char *)API_CmdNotPolled, o.str(), (const char *)"Device_4Impl::command_inout_history_4"); } // // Check that some data is available in cache // if (polled_cmd->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for command " << cmd_str << ends; Except::throw_exception((const char *)API_NoDataYet, o.str(), (const char *)"Device_4Impl::command_inout_history_4"); } // // Set the number of returned records // long in_buf = polled_cmd->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevCmdHistory_4; back->dates.length(n); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_4Impl::command_inout_history_4"); } // // Get command result history // Warning : Starting with Tango V5 (IDL 3), state and status are polled // as attributes but could also be retrieved as commands. In this case, // retrieved the history as attributes and transfer this as command // if ((state_cmd == true) || (status_cmd == true)) { Tango::DevAttrHistory_4 *back_attr = NULL; try { back_attr = new Tango::DevAttrHistory_4; back_attr->dates.length(n); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_4Impl::command_inout_history_4"); } if (status_cmd == true) { polled_cmd->get_attr_history(n,back_attr,Tango::DEV_STRING,SCALAR); back->dates = back_attr->dates; back->errors = back_attr->errors; back->errors_array = back_attr->errors_array; back->dims = back_attr->r_dims; back->dims_array = back_attr->r_dims_array; back->cmd_type = Tango::DEV_STRING; back->value = back_attr->value; } else { // // Trick: To identify the state used as an attribute from a classical attribute with type // DEV_STATE, use DEV_VOID for state as data type. // polled_cmd->get_attr_history(n,back_attr,Tango::DEV_VOID,SCALAR); back->dates = back_attr->dates; back->errors = back_attr->errors; back->errors_array = back_attr->errors_array; back->dims = back_attr->r_dims; back->dims_array = back_attr->r_dims_array; back->cmd_type = Tango::DEV_STATE; back->value = back_attr->value; } delete back_attr; } else { // // Get command output data type and fill returned structure // string cmd(command); transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); Tango::CmdArgType cmd_type; vector &cmd_list = device_class->get_command_list(); for (unsigned int loop = 0;loop < cmd_list.size();loop++) { string cmd_name(cmd_list[loop]->get_name()); transform(cmd_name.begin(),cmd_name.end(),cmd_name.begin(),::tolower); if (cmd_name == cmd) { cmd_type = cmd_list[loop]->get_out_type(); break; } } polled_cmd->get_cmd_history(n,back,cmd_type); } cout4 << "Leaving Device_4Impl::command_inout_history_4 method" << endl; return back; } //+------------------------------------------------------------------------- // // method : Device_4Impl::command_inout_4 // // description : Method called for each command_inout operation executed // from any client on a Tango device version 4. // //-------------------------------------------------------------------------- CORBA::Any *Device_4Impl::command_inout_4(const char *in_cmd, const CORBA::Any &in_data, Tango::DevSource source, const Tango::ClntIdent &cl_id) { cout4 << "Device_4Impl::command_inout_4 arrived, source = " << source << ", command = " << in_cmd << endl; // // Record operation request in black box // blackbox_ptr->insert_cmd_cl_ident(in_cmd,cl_id,4,source); // // Do not check lock validity if State or Status is requested using command // bool state_status_cmd = false; if ((TG_strcasecmp(in_cmd,"state") == 0) || (TG_strcasecmp(in_cmd,"status") == 0)) state_status_cmd = true; // // Check if the device is locked and if it is valid // If the lock is not valid any more, clear it // if (state_status_cmd == false) { check_lock("command_inout4",in_cmd); } // // Call the Device_2Impl command_inout // store_in_bb = false; return (command_inout_2(in_cmd,in_data,source)); } //+------------------------------------------------------------------------- // // method : Device_4Impl::read_attributes_4 // // description : Method called for each read_attributes operation executed // from any client on a Tango device version 4. // //-------------------------------------------------------------------------- Tango::AttributeValueList_4* Device_4Impl::read_attributes_4(const Tango::DevVarStringArray& names, Tango::DevSource source,const Tango::ClntIdent &cl_id) { cout4 << "Device_4Impl::read_attributes_4 arrived for dev " << get_name() << ", att[0] = " << names[0] << endl; // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(names,cl_id,4,source); store_in_bb = true; // // Build a sequence with the names of the attribute to be read. // This is necessary in case of the "AllAttr" shortcut is used // If all attributes are wanted, build this list // unsigned long nb_names = names.length(); unsigned long nb_dev_attr = dev_attr->get_attr_nb(); Tango::DevVarStringArray real_names(nb_names); unsigned long i; if (nb_names == 1) { string att_name(names[0]); if (att_name == AllAttr) { real_names.length(nb_dev_attr); for (i = 0;i < nb_dev_attr;i++) { real_names[i] = dev_attr->get_attr_by_ind(i).get_name().c_str(); } } else { real_names = names; } } else { real_names = names; } nb_names = real_names.length(); // // Allocate memory for the AttributeValue structures // AttributeIdlData aid; try { Tango::AttributeValue_4 *l_back = new Tango::AttributeValue_4 [nb_names]; aid.data_4 = new Tango::AttributeValueList_4(nb_names,nb_names,l_back,true); for (unsigned long loop = 0;loop < nb_names;loop++) (*aid.data_4)[loop].value.union_no_data(true); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_4Impl::read_attributes_4"); } // // Store source parameter (used in case of forwarded attribute(s)) // set_call_source(source); // // If the source parameter specifies device, call the read_attributes method // which does not throw exception except for major fault (cant allocate // memory,....) // vector idx_in_back; if (source == Tango::DEV) { try { AutoTangoMonitor sync(this); read_attributes_no_except(real_names,aid,false,idx_in_back); } catch (...) { delete aid.data_4; throw; } } else if (source == Tango::CACHE) { // // If the device has some forwarded attribute, do not try to get data from the local cache but get it // from the root device // Create two arrays with local attribute names and fwd attribute names // bool fwd_att_in_call = false; Tango::DevVarStringArray local_names(nb_names); Tango::DevVarStringArray fwd_names(nb_names); if (with_fwd_att == true) { for (size_t loop = 0;loop < nb_names;loop++) { Attribute &att = dev_attr->get_attr_by_name(real_names[loop]); if (att.is_fwd_att() == true) { size_t nb_fwd = 0; fwd_att_in_call = true; nb_fwd++; fwd_names.length(nb_fwd); fwd_names[nb_fwd - 1] = real_names[loop]; idx_in_back.push_back(loop); } else { size_t nb_local = 0; nb_local++; local_names.length(nb_local); local_names[nb_local - 1] = real_names[loop]; } } } if (fwd_att_in_call == false) { // // No fwd attributes in call, get values from local cache // try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_4; throw; } } else { // // Some fwd attributes in call: First get data for local attributes then get data for forwarded attributes from // root devices // try { TangoMonitor &mon = get_poll_monitor(); { AutoTangoMonitor sync(&mon); read_attributes_from_cache(local_names,aid); } { AutoTangoMonitor sync(this); read_attributes_no_except(fwd_names,aid,true,idx_in_back); idx_in_back.clear(); } } catch (...) { delete aid.data_4; throw; } } } else { // // It must be now CACHE_DEVICE (no other choice), first try to get // values from cache // try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_4; throw; } // // Now, build the list of attributes which it was not possible // to get their value from cache // Tango::DevVarStringArray names_from_device(nb_names); long nb_attr = 0; for (i = 0;i < nb_names;i++) { long nb_err = (*aid.data_4)[i].err_list.length(); if (nb_err != 0) { nb_err--; if ((strcmp((*aid.data_4)[i].err_list[nb_err].reason,API_AttrNotPolled) == 0) || (strcmp((*aid.data_4)[i].err_list[nb_err].reason,API_NoDataYet) == 0) || (strcmp((*aid.data_4)[i].err_list[nb_err].reason,API_NotUpdatedAnyMore) == 0) || (strcmp((*aid.data_4)[i].err_list[nb_err].origin,"DServer::add_obj_polling") == 0)) { nb_attr++; names_from_device.length(nb_attr); names_from_device[nb_attr - 1] = real_names[i]; idx_in_back.push_back(i); (*aid.data_4)[i].err_list.length(0); } } } if (nb_attr != 0) { // // Try to get their values from device // try { AutoTangoMonitor sync(this); read_attributes_no_except(names_from_device,aid,true,idx_in_back); } catch (...) { delete aid.data_4; throw; } } } return aid.data_4; } //+------------------------------------------------------------------------- // // method : Device_4Impl::write_attributes_4 // // description : CORBA operation to write attribute(s) value // // argument: in : - values: The new attribute(s) value to be set. // //-------------------------------------------------------------------------- void Device_4Impl::write_attributes_4(const Tango::AttributeValueList_4 & values, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_4Impl::write_attributes_4 arrived" << endl; // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(values,cl_id,4); store_in_bb = true; // // Check if the device is locked and by who // check_lock("write_attributes_4"); // // Call the Device_3Impl write_attributes // return write_attributes_34(NULL,&values); } //+------------------------------------------------------------------------- // // method : Device_4Impl::set_attribute_config_4 // // description : CORBA operation to set attribute configuration locally // and in the Tango database // // argument: in : - new_conf: The new attribute(s) configuration. One // AttributeConfig structure is needed for each // attribute to update // //-------------------------------------------------------------------------- void Device_4Impl::set_attribute_config_4(const Tango::AttributeConfigList_3& new_conf, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_4Impl::set_attribute_config_4 arrived" << endl; // // The attribute conf. is protected by two monitors. One protects access between // get and set attribute conf. The second one protects access between set and // usage. This is the classical device monitor // TangoMonitor &mon1 = get_att_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Set_Attr_Config_4,cl_id); // // Check if the device is locked and by who // check_lock("set_attribute_config_4"); // // Call the Device_3Impl set_attribute_config // store_in_bb = false; return set_attribute_config_3_local(new_conf,new_conf[0],false,4); } //+------------------------------------------------------------------------- // // method : Device_4Impl::write_read_attributes_4 // // description : CORBA operation to write then read attribute(s) value // Nowadays, it is possible to write then read attribute for // only 1 attribute at a time even if the IDL is written for // several attribute // // argument: in : - values: The new attributes value to be set. // //-------------------------------------------------------------------------- Tango::AttributeValueList_4* Device_4Impl::write_read_attributes_4(const Tango::AttributeValueList_4& values, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_4Impl::write_read_attributes_4 arrived" << endl; // // Record operation request in black box // Tango::DevVarStringArray dvsa; dvsa.length(1); dvsa[0] = CORBA::string_dup(values[0].name); blackbox_ptr->insert_wr_attr(values,dvsa,cl_id,4); // // Check if the device is locked and by who // check_lock("write_read_attributes_4"); // // Check the attribute write type (only READ_WRITE or READ_WITH_WRITE allowed) // Tango::Attribute &att = dev_attr->get_attr_by_name(values[0].name); Tango::AttrWriteType awt = att.get_writable(); if ((awt == Tango::READ) || (awt == Tango::WRITE)) { TangoSys_OMemStream o; o << "Attribute " << values[0].name << " is not a READ_WRITE or READ_WITH_WRITE attribute" << ends; Except::throw_exception((const char *)API_AttrNotWritable,o.str(), (const char *)"Device_4Impl::write_read_attribute_4"); } Tango::AttributeValueList_4 *read_val_ptr; // // First, write the attribute // store_in_bb = false; write_attributes_4(values,cl_id); // // Now, read the attribute // Tango::DevVarStringArray att_name(1); att_name.length(1); att_name[0] = CORBA::string_dup(values[0].name); Tango::ClntIdent dummy_cl_id; Tango::CppClntIdent cci = 0; dummy_cl_id.cpp_clnt(cci); store_in_bb = false; read_val_ptr = read_attributes_4(att_name,Tango::DEV,dummy_cl_id); return read_val_ptr; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/device_5.cpp0000644023471100065110000010407013034745001014752 00000000000000static const char *RcsId = "$Id: device_4.cpp 20742 2012-06-21 14:20:20Z taurel $"; //+=================================================================================================================== // // file : Device_5.cpp // // description : C++ source code for the Device_5Impl class. This class is the root class for all derived Device // classes starting with Tango 9 // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 20742 $ // //-=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_5Impl::Device_5Impl // // description : // Constructors for the Device_5impl class from the class object pointer, the device name, the description field, // the state and the status. Device_5Impl inherits from DeviceImpl. These constructors simply call the correct // DeviceImpl class constructor // //-------------------------------------------------------------------------------------------------------------------- Device_5Impl::Device_5Impl(DeviceClass *device_class,string &dev_name): Device_4Impl(device_class,dev_name),ext_5(Tango_nullptr) { idl_version = 5; } Device_5Impl::Device_5Impl(DeviceClass *device_class, string &dev_name, string &desc): Device_4Impl(device_class,dev_name,desc),ext_5(Tango_nullptr) { idl_version = 5; } Device_5Impl::Device_5Impl(DeviceClass *device_class, string &dev_name,string &desc, Tango::DevState dev_state,string &dev_status): Device_4Impl(device_class,dev_name,desc,dev_state,dev_status),ext_5(Tango_nullptr) { idl_version = 5; } Device_5Impl::Device_5Impl(DeviceClass *device_class, const char *dev_name, const char *desc, Tango::DevState dev_state, const char *dev_status): Device_4Impl(device_class,dev_name,desc,dev_state,dev_status),ext_5(Tango_nullptr) { idl_version = 5; } //+----------------------------------------------------------------------------------------------------------------- // // method : // Device_5Impl::read_attributes_5 // // description : // Method called for each read_attributes operation executed from any client on a Tango device version 5. // //------------------------------------------------------------------------------------------------------------------ Tango::AttributeValueList_5* Device_5Impl::read_attributes_5(const Tango::DevVarStringArray& names, Tango::DevSource source,const Tango::ClntIdent &cl_id) { cout4 << "Device_5Impl::read_attributes_5 arrived for dev " << get_name() << ", att[0] = " << names[0] << endl; // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(names,cl_id,5,source); store_in_bb = true; // // Build a sequence with the names of the attribute to be read. This is necessary in case of the "AllAttr" shortcut is // used. If all attributes are wanted, build this list // unsigned long nb_names = names.length(); unsigned long nb_dev_attr = dev_attr->get_attr_nb(); Tango::DevVarStringArray real_names(nb_names); unsigned long i; if (nb_names == 1) { string att_name(names[0]); if (att_name == AllAttr) { real_names.length(nb_dev_attr); for (i = 0;i < nb_dev_attr;i++) { real_names[i] = dev_attr->get_attr_by_ind(i).get_name().c_str(); } } else { real_names = names; } } else { real_names = names; } nb_names = real_names.length(); // // Allocate memory for the AttributeValue structures // AttributeIdlData aid; try { Tango::AttributeValue_5 *l_back = new Tango::AttributeValue_5 [nb_names]; aid.data_5 = new Tango::AttributeValueList_5(nb_names,nb_names,l_back,true); for (unsigned long loop = 0;loop < nb_names;loop++) (*aid.data_5)[loop].value.union_no_data(true); } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation,"Can't allocate memory in server", "Device_5Impl::read_attributes_5"); } // // Store source parameter (used in case of forwarded attribute(s)) // set_call_source(source); // // If the source parameter specifies device, call the read_attributes method which does not throw exception except for // major fault (cant allocate memory,....) // vector idx_in_back; if (source == Tango::DEV) { try { AutoTangoMonitor sync(this); read_attributes_no_except(real_names,aid,false,idx_in_back); } catch (...) { delete aid.data_5; throw; } } else if (source == Tango::CACHE) { // // If the device has some forwarded attribute, do not try to get data from the local cache but get it // from the root device // Create two arrays with local attribute names and fwd attribute names // bool fwd_att_in_call = false; Tango::DevVarStringArray local_names(nb_names); Tango::DevVarStringArray fwd_names(nb_names); if (with_fwd_att == true) { for (size_t loop = 0;loop < nb_names;loop++) { Attribute &att = dev_attr->get_attr_by_name(real_names[loop]); if (att.is_fwd_att() == true) { size_t nb_fwd = 0; fwd_att_in_call = true; nb_fwd++; fwd_names.length(nb_fwd); fwd_names[nb_fwd - 1] = real_names[loop]; idx_in_back.push_back(loop); } else { size_t nb_local = 0; nb_local++; local_names.length(nb_local); local_names[nb_local - 1] = real_names[loop]; } } } if (fwd_att_in_call == false) { // // No fwd attributes in call, get values from local cache // try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_5; throw; } } else { // // Some fwd attributes in call: First get data for local attributes then get data for forwarded attributes from // root devices // try { TangoMonitor &mon = get_poll_monitor(); { AutoTangoMonitor sync(&mon); read_attributes_from_cache(local_names,aid); } { AutoTangoMonitor sync(this); read_attributes_no_except(fwd_names,aid,true,idx_in_back); idx_in_back.clear(); } } catch (...) { delete aid.data_5; throw; } } } else { // // It must be now CACHE_DEVICE (no other choice), first try to get // values from cache // try { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); read_attributes_from_cache(real_names,aid); } catch (...) { delete aid.data_5; throw; } // // Now, build the list of attributes which it was not possible // to get their value from cache // Tango::DevVarStringArray names_from_device(nb_names); long nb_attr = 0; for (i = 0;i < nb_names;i++) { long nb_err = (*aid.data_5)[i].err_list.length(); if (nb_err != 0) { nb_err--; if ((strcmp((*aid.data_5)[i].err_list[nb_err].reason,API_AttrNotPolled) == 0) || (strcmp((*aid.data_5)[i].err_list[nb_err].reason,API_NoDataYet) == 0) || (strcmp((*aid.data_5)[i].err_list[nb_err].reason,API_NotUpdatedAnyMore) == 0) || (strcmp((*aid.data_5)[i].err_list[nb_err].origin,"DServer::add_obj_polling") == 0)) { nb_attr++; names_from_device.length(nb_attr); names_from_device[nb_attr - 1] = real_names[i]; idx_in_back.push_back(i); (*aid.data_5)[i].err_list.length(0); } } } if (nb_attr != 0) { // // Try to get their values from device // try { AutoTangoMonitor sync(this); read_attributes_no_except(names_from_device,aid,true,idx_in_back); } catch (...) { delete aid.data_5; throw; } } } return aid.data_5; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::write_read_attributes_5 // // description : // CORBA operation to write then read attribute(s) value. Nowadays, it is possible to write then read attribute // for only 1 attribute at a time even if the IDL is written for several attribute // //------------------------------------------------------------------------------------------------------------------ Tango::AttributeValueList_5* Device_5Impl::write_read_attributes_5(const Tango::AttributeValueList_4 &values, const Tango::DevVarStringArray &r_names, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_5Impl::write_read_attributes_5 arrived" << endl; // // Record operation request in black box // blackbox_ptr->insert_wr_attr(values,r_names,cl_id,5); // // Check if the device is locked and by who // check_lock("write_read_attributes_5"); unsigned int nb_write = values.length(); unsigned int nb_read = r_names.length(); // // Special case for forwarded attribute used for both read and write // Memorize their root device name to lock unlock them // vector r_w_att; for (unsigned int loop = 0;loop < nb_write;loop++) { string w_att_name(values[loop].name); transform(w_att_name.begin(),w_att_name.end(),w_att_name.begin(),::tolower); for (unsigned int j = 0;j < nb_read;j++) { string r_att_name(r_names[j]); transform(r_att_name.begin(),r_att_name.end(),r_att_name.begin(),::tolower); if (w_att_name == r_att_name) { r_w_att.push_back(w_att_name); break; } } } vector fwd_att_root_dev_name; for (unsigned int loop = 0;loop < r_w_att.size();++loop) { Tango::Attribute &att = dev_attr->get_attr_by_name(values[loop].name); if (att.is_fwd_att() == true) { Tango::FwdAttribute &fwd_att = static_cast(att); fwd_att_root_dev_name.push_back(fwd_att.get_fwd_dev_name()); } } cout4 << fwd_att_root_dev_name.size() << " forwarded attribute(s) in write_read_attributes_5()" << endl; // // If we have some fwd atts, lock their root device // Util *tg = Util::instance(); RootAttRegistry &rar = tg->get_root_att_reg(); if (fwd_att_root_dev_name.empty() == false) { vector::iterator ite; for (ite = fwd_att_root_dev_name.begin();ite != fwd_att_root_dev_name.end();++ite) { DeviceProxy *dp = rar.get_root_att_dp(*ite); dp->lock(); } } // // First, write the attribute(s) // Tango::AttributeValueList_5 *read_val_ptr; try { store_in_bb = false; cout4 << "write_read_attributes_5(): Writing " << nb_write << " attribute(s)" << endl; write_attributes_4(values,cl_id); // // Now, read the attribute(s) // Tango::ClntIdent dummy_cl_id; Tango::CppClntIdent cci = 0; dummy_cl_id.cpp_clnt(cci); store_in_bb = false; cout4 << "write_read_attributes_5(): Reading " << nb_read << " attribute(s)" << endl; read_val_ptr = read_attributes_5(r_names,Tango::DEV,dummy_cl_id); } catch (...) { if (fwd_att_root_dev_name.empty() == false) { vector::iterator ite; for (ite = fwd_att_root_dev_name.begin();ite != fwd_att_root_dev_name.end();++ite) { DeviceProxy *dp = rar.get_root_att_dp(*ite); dp->unlock(); } } throw; } // // Unlock devices (if case there are some due to forwarded attributes) // if (fwd_att_root_dev_name.empty() == false) { vector::iterator ite; for (ite = fwd_att_root_dev_name.begin();ite != fwd_att_root_dev_name.end();++ite) { DeviceProxy *dp = rar.get_root_att_dp(*ite); dp->unlock(); } } return read_val_ptr; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::get_attribute_config_5 // // description : // CORBA operation to get attribute configuration. // // WARNING !!!!!!!!!!!!!!!!!! // // This is the release 3 of this CORBA operation which returns much more parameter than in release 2 // The code has been duplicated in order to keep it clean (avoid many "if" on version number in a common method) // // argument: // in : // - names: name of attribute(s) // // return : // Pointer to a AttributeConfigList_5 with one AttributeConfig_5 structure for each attribute // //------------------------------------------------------------------------------------------------------------------- Tango::AttributeConfigList_5 *Device_5Impl::get_attribute_config_5(const Tango::DevVarStringArray& names) { TangoMonitor &mon = get_att_conf_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_5Impl::get_attribute_config_5 arrived" << endl; long nb_attr = names.length(); Tango::AttributeConfigList_5 *back = NULL; bool all_attr = false; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Get_Attr_Config_5); // // Get attribute number and device version // long nb_dev_attr = dev_attr->get_attr_nb(); // // Check if the caller want to get config for all attribute. // If the device implements IDL 3 or above (State and status as attributes) and the client is an old one (not able to // read state/status as attribute), decrement attribute number // string in_name(names[0]); if (nb_attr == 1) { if (in_name == AllAttr_3) { all_attr = true; nb_attr = nb_dev_attr; } } // // Allocate memory for the AttributeConfig structures // try { back = new Tango::AttributeConfigList_5(nb_attr); back->length(nb_attr); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_5Impl::get_attribute_config_5"); } // // Fill in these structures // for (long i = 0;i < nb_attr;i++) { try { if (all_attr == true) { Attribute &attr = dev_attr->get_attr_by_ind(i); attr.get_properties((*back)[i]); } else { Attribute &attr = dev_attr->get_attr_by_name(names[i]); attr.get_properties((*back)[i]); } } catch (Tango::DevFailed &) { delete back; throw; } } // // Return to caller // cout4 << "Leaving Device_3Impl::get_attribute_config_5" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::set_attribute_config_5 // // description : // CORBA operation to set attribute configuration locally and in the Tango database // // argument: // in : // - new_conf: The new attribute(s) configuration. One AttributeConfig structure is needed for each // attribute to update // //-------------------------------------------------------------------------------------------------------------------- void Device_5Impl::set_attribute_config_5(const Tango::AttributeConfigList_5& new_conf, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_5Impl::set_attribute_config_5 arrived" << endl; // // The attribute conf. is protected by two monitors. One protects access between get and set attribute conf. // The second one protects access between set and usage. This is the classical device monitor // TangoMonitor &mon1 = get_att_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // Is it from the fwd attribute callback ? // bool from_fwd_cb = false; Tango::LockerLanguage cl_lang = cl_id._d(); if (cl_lang == Tango::CPP && cl_id.cpp_clnt() == 0) { from_fwd_cb = true; } // // Record operation request in black box // if (from_fwd_cb == false) blackbox_ptr->insert_op(Op_Set_Attr_Config_5,cl_id); // // Check if the device is locked and by who // check_lock("set_attribute_config_5"); // // Call the Device_3Impl set_attribute_config // return set_attribute_config_3_local(new_conf,new_conf[0],from_fwd_cb,5); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Device_5Impl::read_attribute_history_5 // // description : // CORBA operation to read attribute value history from the polling buffer. // // argument: // in : // - name : attribute name // - n : history depth (in record number) // // return : // A pointer to a DevAttrHistory_5 structure // //------------------------------------------------------------------------------------------------------------------- Tango::DevAttrHistory_5 *Device_5Impl::read_attribute_history_5(const char* name,CORBA::Long n) { TangoMonitor &mon = get_poll_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_5Impl::read_attribute_history_5 arrived, requested history depth = " << n << endl; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Read_Attr_history_5); Tango::DevAttrHistory_5 *back = Tango_nullptr; vector &poll_list = get_poll_obj_list(); long nb_poll = poll_list.size(); // // Check that the device supports this attribute. This method returns an // exception in case of unsupported attribute // Attribute &att = dev_attr->get_attr_by_name(name); string attr_str(name); transform(attr_str.begin(),attr_str.end(),attr_str.begin(),::tolower); // // Check that the wanted attribute is polled (Except in case of forwarded attribute) // long j; PollObj *polled_attr = NULL; for (j = 0;j < nb_poll;j++) { if ((poll_list[j]->get_type() == Tango::POLL_ATTR) && (poll_list[j]->get_name() == attr_str)) { polled_attr = poll_list[j]; break; } } if ((polled_attr == NULL) && (att.is_fwd_att() == false)) { TangoSys_OMemStream o; o << "Attribute " << attr_str << " not polled" << ends; Except::throw_exception(API_AttrNotPolled,o.str(),"Device_5Impl::read_attribute_history_5"); } // // If it is a forwarded attribute, get data from the root attribute // if (att.is_fwd_att() == true) { try { FwdAttribute &fwd_att = static_cast(att); back = fwd_att.read_root_att_history(n); } catch (Tango::DevFailed &e) { stringstream ss; ss << "Reading history for attribute " << attr_str << " on device " << get_name() << " failed!"; Tango::Except::re_throw_exception(e,API_AttributeFailed,ss.str(),"Device_5Impl::read_attribute_history_5"); } } else { // // Check that some data is available in cache // if (polled_attr->is_ring_empty() == true) { TangoSys_OMemStream o; o << "No data available in cache for attribute " << attr_str << ends; Except::throw_exception(API_NoDataYet,o.str(),"Device_5Impl::read_attribute_history_5"); } // // Set the number of returned records // long in_buf = polled_attr->get_elt_nb_in_buffer(); if (n > in_buf) n = in_buf; // // Allocate memory for the returned value // try { back = new Tango::DevAttrHistory_5; back->dates.length(n); } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation, "Can't allocate memory in server", "Device_5Impl::read_attribute_history_5"); } // // Init attribute name in the returned structure // back->name = CORBA::string_dup(name); // // Get attribute value history // Trick: To identify the state used as an attribute from a classical attribute with type // DEV_STATE, use DEV_VOID for state as data type. // if (att.get_name_lower() == "state") polled_attr->get_attr_history(n,back,Tango::DEV_VOID,att.get_data_format()); else polled_attr->get_attr_history(n,back,att.get_data_type(),att.get_data_format()); } cout4 << "Leaving Device_5Impl::read_attribute_history_5 method" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::get_pipe_config_5 // // description : // CORBA operation to get pipe configuration. // // argument: // in : // - names: name of pipe(s) // // return : // Pointer to a PipeConfigList with one PipeConfig_5 structure for each pipe // //------------------------------------------------------------------------------------------------------------------- Tango::PipeConfigList *Device_5Impl::get_pipe_config_5(const Tango::DevVarStringArray& names) { TangoMonitor &mon = get_pipe_conf_monitor(); AutoTangoMonitor sync(&mon); cout4 << "Device_5Impl::get_pipe_config_5 arrived" << endl; long nb_pipe = names.length(); Tango::PipeConfigList *back = Tango_nullptr; bool all_pipe = false; // // Record operation request in black box // blackbox_ptr->insert_op(Op_Get_Pipe_Config_5); // // Check if the caller want to get config for all pipes // string in_name(names[0]); if (nb_pipe == 1 && in_name == AllPipe) { all_pipe = true; nb_pipe = device_class->get_pipe_list(device_name_lower).size(); } // // Allocate memory for the PipeConfig structures // try { back = new Tango::PipeConfigList(nb_pipe); back->length(nb_pipe); } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"Device_5Impl::get_pipe_config_5"); } // // Fill in these structures // vector &pipe_list = device_class->get_pipe_list(device_name_lower); for (long i = 0;i < nb_pipe;i++) { try { if (all_pipe == true) { Pipe *pi_ptr = pipe_list[i]; (*back)[i].name = Tango::string_dup(pi_ptr->get_name().c_str()); (*back)[i].description = Tango::string_dup(pi_ptr->get_desc().c_str()); (*back)[i].label = Tango::string_dup(pi_ptr->get_label().c_str()); (*back)[i].level = pi_ptr->get_disp_level(); (*back)[i].writable = pi_ptr->get_writable(); } else { Pipe &pi = device_class->get_pipe_by_name(names[i].in(),device_name_lower); (*back)[i].name = Tango::string_dup(pi.get_name().c_str()); (*back)[i].description = Tango::string_dup(pi.get_desc().c_str()); (*back)[i].label = Tango::string_dup(pi.get_label().c_str()); (*back)[i].level = pi.get_disp_level(); (*back)[i].writable = pi.get_writable(); } } catch (Tango::DevFailed &e) { delete back; throw; } } // // Return to caller // cout4 << "Leaving Device_5Impl::get_pipe_config_5" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::set_pipe_config_5 // // description : // CORBA operation to set pipe configuration locally and in the Tango database // // argument: // in : // - new_conf: The new pipe(s) configuration. One PipeConfig structure is needed for each // pipe to update // - cl_id : client identifier // //------------------------------------------------------------------------------------------------------------------- void Device_5Impl::set_pipe_config_5(const Tango::PipeConfigList& new_conf, const Tango::ClntIdent &cl_id) { AutoTangoMonitor sync(this,true); cout4 << "Device_5Impl::set_pipe_config_5 arrived for " << new_conf.length() << " pipe(s)" << endl; // // The pipe conf. is protected by two monitors. One protects access between // get and set attribute conf. The second one protects access between set and // usage. This is the classical device monitor // TangoMonitor &mon1 = get_pipe_conf_monitor(); AutoTangoMonitor sync1(&mon1); // // Record operation request in black box // blackbox_ptr->insert_op(Op_Set_Pipe_Config_5,cl_id); // // Check if the device is locked and by who // check_lock("set_pipe_config_5"); // // Return exception if the device does not have any pipe // size_t dev_nb_pipe = device_class->get_pipe_list(device_name_lower).size(); if (dev_nb_pipe == 0) { Except::throw_exception(API_PipeNotFound,"The device does not have any pipe","Device_5Impl::set_pipe_config_5"); } // // Update pipe config first locally then in database // long nb_pipe = new_conf.length(); long i; try { for (i = 0;i < nb_pipe;i++) { Pipe &pi = device_class->get_pipe_by_name(new_conf[i].name.in(),device_name_lower); pi.set_upd_properties(new_conf[i],this); } } catch (Tango::DevFailed &e) { // // Change the exception reason flag // TangoSys_OMemStream o; o << e.errors[0].reason; if (i != 0) o << "\nAll previous pipe(s) have been successfully updated"; if (i != (nb_pipe - 1)) o << "\nAll remaining pipe(s) have not been updated"; o << ends; string s = o.str(); e.errors[0].reason = CORBA::string_dup(s.c_str()); throw; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::read_pipe_5 // // description : // CORBA operation to read a pipe. // // argument: // in : // - name: pipe name // - cl_id : client identifier // // return : // Pointer to a DevPipeData with pipe data (blob) // //------------------------------------------------------------------------------------------------------------------- Tango::DevPipeData *Device_5Impl::read_pipe_5(const char* name,const Tango::ClntIdent &cl_id) { cout4 << "Device_5Impl::read_pipe_5 arrived for pipe " << name << endl; DevPipeData *back = Tango_nullptr; // // Take dev monitor // AutoTangoMonitor sync(this); // // Record operation request in black box // if (store_in_bb == true) blackbox_ptr->insert_attr(name,cl_id,5); store_in_bb = true; // // Write the device name into the per thread data for sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Catch all exceptions to set back the associated device after execution // try { // // Retrieve requested pipe // string pipe_name(name); Pipe &pi = device_class->get_pipe_by_name(pipe_name,device_name_lower); // // Allocate memory for the returned value // try { back = new Tango::DevPipeData; } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation,"Can't allocate memory in server", "Device_5Impl::read_pipe_5"); } // // Call the always_executed_hook // always_executed_hook(); // // Call the is_allowed method // if (pi.is_allowed(this,READ_REQ) == false) { stringstream o; o << "It is currently not allowed to read pipe " << name; Except::throw_exception(API_PipeNotAllowed,o.str(),"Device_5Impl::read_pipe_5"); } // // Take the pipe mutex before calling the user read method // if (pi.get_pipe_serial_model() == PIPE_BY_KERNEL) { cout4 << "Locking pipe mutex for pipe " << name << endl; omni_mutex *pi_mut = pi.get_pipe_mutex(); if (pi_mut->trylock() == 0) { cout4 << "Mutex for pipe " << name << " is already taken.........." << endl; pi_mut->lock(); } } // // Call the user read method but before, set pipe date // try { pi.set_value_flag(false); pi.set_time(); pi.set_returned_data_ptr(back); pi.get_blob().reset_insert_ctr(); pi.get_blob().reset_extract_ctr(); pi.read(this); } catch (DevFailed &e) { DevVarPipeDataEltArray *dvpdea = pi.get_blob().get_insert_data(); delete dvpdea; pi.get_blob().reset_insert_data_ptr(); if (pi.get_pipe_serial_model() == PIPE_BY_KERNEL) { cout4 << "Releasing pipe mutex for pipe " << name << " due to error" << endl; omni_mutex *pi_mut = pi.get_pipe_mutex(); pi_mut->unlock(); } throw e; } catch (...) { if (pi.get_pipe_serial_model() == PIPE_BY_KERNEL) { cout4 << "Releasing pipe mutex for pipe " << name << " due to error which is not a DevFailed !!" << endl; omni_mutex *pi_mut = pi.get_pipe_mutex(); pi_mut->unlock(); } throw; } // // Check that the wanted pipe set value has been updated // if (pi.get_value_flag() == false) { if (pi.get_pipe_serial_model() == PIPE_BY_KERNEL) { cout4 << "Releasing pipe mutex for pipe " << name << " due to error (value not set)" << endl; omni_mutex *pi_mut = pi.get_pipe_mutex(); pi_mut->unlock(); } DevVarPipeDataEltArray *dvpdea = pi.get_blob().get_insert_data(); delete dvpdea; pi.get_blob().reset_insert_data_ptr(); stringstream o; o << "Value for pipe " << pipe_name << " has not been updated"; Except::throw_exception(API_PipeValueNotSet,o.str(),"Device_5Impl::read_pipe_5"); } // // Populate the structure sent back to caller // back->time = pi.get_when(); back->name = CORBA::string_dup(pipe_name.c_str()); back->data_blob.name = CORBA::string_dup(pi.get_blob().get_name().c_str()); DevVarPipeDataEltArray *dvpdea = pi.get_blob().get_insert_data(); CORBA::ULong max,len; max = dvpdea->maximum(); len = dvpdea->length(); back->data_blob.blob_data.replace(max,len,dvpdea->get_buffer((CORBA::Boolean)true),true); delete dvpdea; pi.get_blob().reset_insert_data_ptr(); // // Give pipe mutex to CORBA layer // PipeSerialModel pism = pi.get_pipe_serial_model(); if (pism != PIPE_NO_SYNC) { cout4 << "Giving pipe mutex to CORBA structure for pipe " << name << endl; if (pism == PIPE_BY_KERNEL) back->set_pipe_mutex(pi.get_pipe_mutex()); else back->set_pipe_mutex(pi.get_user_pipe_mutex()); } } catch (...) { // // Set back the device attribution for the thread and rethrow the exception. // sub.set_associated_device(last_associated_device); delete back; throw; } // // Set back the device attribution for the thread // sub.set_associated_device(last_associated_device); // // Return to caller // cout4 << "Leaving Device_5Impl::read_pipe_5" << endl; return back; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::write_pipe_5 // // description : // CORBA operation to write a pipe. // // argument: // in : // - pi_value: new pipe value // - cl_id : client identifier // //------------------------------------------------------------------------------------------------------------------- void Device_5Impl::write_pipe_5(const Tango::DevPipeData &pi_value, const Tango::ClntIdent& cl_id) { string pipe_name(pi_value.name.in()); cout4 << "Device_5Impl::write_pipe_5 arrived for pipe " << pipe_name << endl; // // Take dev monitor // AutoTangoMonitor sync(this,true); // // Record operation in blackbox // if (store_in_bb == true) blackbox_ptr->insert_attr(pi_value,cl_id,0); store_in_bb = true; // // Check if the device is locked and by who // check_lock("write_pipe_5"); // // Write the device name into the per thread data for sub device diagnostics. // Keep the old name, to put it back at the end! // During device access inside the same server, the thread stays the same! // SubDevDiag &sub = (Tango::Util::instance())->get_sub_dev_diag(); string last_associated_device = sub.get_associated_device(); sub.set_associated_device(get_name()); // // Catch all exceptions to set back the associated device after execution // try { // // Retrieve requested pipe // Pipe &tmp_pi = device_class->get_pipe_by_name(pipe_name,device_name_lower); // // Check that pipe is writable // if (tmp_pi.get_writable() != PIPE_READ_WRITE) { stringstream o; o << "Pipe " << pipe_name << " is not writable"; Except::throw_exception(API_PipeNotWritable,o.str(),"Device_5Impl::write_pipe_5"); } WPipe &pi = static_cast(tmp_pi); // // Call the always_executed_hook // always_executed_hook(); // // Call the is_allowed method // if (pi.is_allowed(this,WRITE_REQ) == false) { stringstream o; o << "It is currently not allowed to write pipe " << pipe_name; Except::throw_exception(API_PipeNotAllowed,o.str(),"Device_5Impl::write_pipe_5"); } // // Init the WPipe object with data received from client // string bl_name; if (::strlen(pi_value.data_blob.name.in()) != 0) bl_name = pi_value.data_blob.name.in(); pi.get_blob().set_name(bl_name); pi.get_blob().set_extract_data(&(pi_value.data_blob.blob_data)); pi.get_blob().reset_extract_ctr(); pi.get_blob().reset_insert_ctr(); // // Call the user write method // pi.write(this); } catch (...) { // // Set back the device attribution for the thread and rethrow the exception. // sub.set_associated_device(last_associated_device); throw; } // // Set back the device attribution for the thread // sub.set_associated_device(last_associated_device); // // Return to caller // cout4 << "Leaving Device_5Impl::write_pipe_5" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Device_5Impl::write_read_pipe_5 // // description : // CORBA operation to write then read a pipe. // // argument: // in : // - pi_value: new pipe value // - cl_id : client identifier // // return : // Pointer to a DevPipeData with pipe data (blob) // //------------------------------------------------------------------------------------------------------------------- Tango::DevPipeData *Device_5Impl::write_read_pipe_5(const Tango::DevPipeData &pi_value, const Tango::ClntIdent& cl_id) { AutoTangoMonitor sync(this,true); string pipe_name(pi_value.name.in()); cout4 << "Device_5Impl::write_read_pipe_5 arrived for pipe " << pipe_name << endl; // // Record operation request in black box // blackbox_ptr->insert_attr(pi_value,cl_id,1); // // Check if the device is locked and by who // check_lock("write_read_pipe_5"); // // First, write the pipe // store_in_bb = false; write_pipe_5(pi_value,cl_id); // // Now, read the pipe // store_in_bb = false; DevPipeData *back = read_pipe_5(pi_value.name.in(),cl_id); return back; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/deviceclass.cpp0000644023471100065110000013420713034745001015561 00000000000000static const char *RcsId = "$Id: deviceclass.cpp 30343 2016-11-28 13:04:06Z taurel $\n$Name$"; //+================================================================================================================= // // file : Deviceclass.cpp // // description : C++ source code for the DeviceClass class. This class is one the root class for all derived // Device classes. It is an abstract class. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30343 $ // //-================================================================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #ifdef TANGO_HAS_LOG4TANGO #include #endif extern omni_thread::key_t key_py_data; namespace Tango { static void lower_cmd_name(string &cmd) { transform(cmd.begin(),cmd.end(),cmd.begin(),::tolower); } bool less_than_pipe (Pipe *a,Pipe *b) { if (a->get_name() < b->get_name()) return true; else return false; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::DeviceClass(string &s) // // description : // DeviceClass constructor. Protected method which will be called automatically by the compiler. // //------------------------------------------------------------------------------------------------------------------- DeviceClass::DeviceClass(string &s):name(s),ext(new DeviceClassExt), only_one("class"),default_cmd(NULL),py_class(false),device_factory_done(false) { // // Create the associated DbClass object // db_class = new DbClass(name,Tango::Util::instance()->get_database()); // // initialise command_list with State, Status and Init // try { command_list.push_back(new DevStatusCmd("Status",Tango::DEV_VOID,Tango::DEV_STRING)); command_list[0]->set_out_type_desc("Device status"); command_list.push_back(new DevStateCmd("State",Tango::DEV_VOID,Tango::DEV_STATE)); command_list[1]->set_out_type_desc("Device state"); command_list.push_back(new DevInitCmd("Init",Tango::DEV_VOID,Tango::DEV_VOID)); } catch (bad_alloc &) { if (command_list.empty() == false) { for(unsigned long i = 0;i < command_list.size();i++) delete command_list[i]; command_list.clear(); } throw; } // // Retrieve basic class resource // get_class_system_resource(); // // Create the multi class attribute object // class_attr = new MultiClassAttribute(); // // Create the multi class pipe object // class_pipe = new MultiClassPipe(); // // Give a default value for device type // type = NotSet; } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::get_class_system_resource(string &s) // // description : // Method to retrieve some basic class resource(s) // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::get_class_system_resource() { // // Try to retrieve the class resource doc_url // Tango::Util *tg = Tango::Util::instance(); if (tg->_UseDb == true) { Database *db = tg->get_database(); DbData db_data; db_data.push_back(DbDatum("doc_url")); db_data.push_back(DbDatum("cvs_tag")); db_data.push_back(DbDatum("cvs_location")); db_data.push_back(DbDatum("AllowedAccessCmd")); db_data.push_back(DbDatum("svn_tag")); db_data.push_back(DbDatum("svn_location")); try { db->get_class_property(name,db_data,tg->get_db_cache()); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Database error while trying to retrieve properties for class " << name.c_str() << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"DeviceClass::get_class_system_resource"); } if (db_data[1].is_empty() == false) db_data[1] >> cvs_tag; if (db_data[2].is_empty() == false) db_data[2] >> cvs_location; // // Init allowed commands vector (in lowercase letters) // if (db_data[3].is_empty() == false) { db_data[3] >> allowed_cmds; for_each(allowed_cmds.begin(),allowed_cmds.end(),lower_cmd_name); } if (db_data[0].is_empty() == true) { cout4 << "doc_url property for class " << name << " is not defined in database" << endl; try { db->get_class_property("Default",db_data,tg->get_db_cache()); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Database error while trying to retrieve properties for class " << name.c_str() << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"DeviceClass::get_class_system_resource"); } if (db_data[0].is_empty() == true) { doc_url = DefaultDocUrl; } else db_data[0] >> doc_url; } else db_data[0] >> doc_url; if (db_data[4].is_empty() == false) db_data[4] >> svn_tag; if (db_data[5].is_empty() == false) db_data[5] >> svn_location; } else { doc_url = DefaultDocUrl; } } //--------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::set_memorized_values() // // description : // Write the memorized attribute with the value stored in database // // argument : // in : // - all : Flag set to true if memorized values must be applied to all class devices // - idx : Index of the device in the device_list vector of the device for which memorized values must // be applied. Used if "all" is set to false // - from_init : Flag set to true if the method is called due to a device Init command execution // //-------------------------------------------------------------------------------------------------------------------- void DeviceClass::set_memorized_values(bool all,long idx,bool from_init) { cout4 << "Entering DeviceClass::set_memorized_values() method" << endl; short sh; Tango::DevVarShortArray sh_seq(1); sh_seq.length(1); Tango::DevLong lg; Tango::DevVarLongArray lg_seq(1); lg_seq.length(1); double db; Tango::DevVarDoubleArray db_seq(1); db_seq.length(1); Tango::DevString tmp_str; Tango::DevVarStringArray str_seq(1); str_seq.length(1); float fl; Tango::DevVarFloatArray fl_seq(1); fl_seq.length(1); Tango::DevBoolean boo; Tango::DevVarBooleanArray boo_seq(1); boo_seq.length(1); Tango::DevUShort ush; Tango::DevVarUShortArray ush_seq(1); ush_seq.length(1); Tango::DevUChar uch; Tango::DevVarCharArray uch_seq(1); uch_seq.length(1); Tango::DevULong ulg; Tango::DevVarULongArray ulg_seq(1); ulg_seq.length(1); Tango::DevLong64 lg64; Tango::DevVarLong64Array lg64_seq(1); lg64_seq.length(1); Tango::DevULong64 ulg64; Tango::DevVarULong64Array ulg64_seq(1); ulg64_seq.length(1); // // Set loop start and stop limits // unsigned long start,stop; if (all == true) { start = 0; stop = device_list.size(); } else { start = idx; stop = idx + 1; } for (unsigned long i = start;i < stop;i++) { // // This feature is available only for devices implementing IDL release 3 and above // if (device_list[i]->get_dev_idl_version() < 3) continue; // // Get list of device writable attributes // AttributeValueList att_val(10); vector &att_list = device_list[i]->get_device_attr()->get_w_attr_list(); long nb_wr = 0; for (unsigned long j = 0;j < att_list.size();j++) { WAttribute &att = device_list[i]->get_device_attr()->get_w_attr_by_ind(att_list[j]); if (att.is_memorized() == true) { string &mem_value = att.get_mem_value(); if (mem_value != MemNotUsed) { nb_wr++; att_val.length(nb_wr); // // In order to not send a new time the already memorized value into db, mark it as not memorized before writing // the value // att.set_memorized(false); // // The memorized value gotten from db is a string, we need to convert this string to its real type before inserting // it into an Any // TangoSys_MemStream str; if (from_init == false) str << mem_value << ends; try { switch (att.get_data_type()) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if (from_init == false) { if (!(str >> sh)) throw_mem_value(device_list[i],att); att.set_write_value(sh); } else att.get_write_value(sh); sh_seq[0] = sh; att_val[nb_wr - 1].value <<= sh_seq; break; case Tango::DEV_LONG: if (from_init == false) { if (!(str >> lg)) throw_mem_value(device_list[i],att); att.set_write_value(lg); } else att.get_write_value(lg); lg_seq[0] = lg; att_val[nb_wr - 1].value <<= lg_seq; break; case Tango::DEV_DOUBLE: if (from_init == false) { if (!(str >> db)) throw_mem_value(device_list[i],att); att.set_write_value(db); } else att.get_write_value(db); db_seq[0] = db; att_val[nb_wr - 1].value <<= db_seq; break; case Tango::DEV_STRING: if (from_init == false) { att.set_write_value(mem_value); str_seq[0] = CORBA::string_dup(mem_value.c_str()); } else { att.get_write_value(tmp_str); str_seq[0] = CORBA::string_dup(tmp_str); } att_val[nb_wr - 1].value <<= str_seq; break; case Tango::DEV_FLOAT: if (from_init == false) { if (!(str >> fl)) throw_mem_value(device_list[i],att); att.set_write_value(fl); } else att.get_write_value(fl); fl_seq[0] = fl; att_val[nb_wr - 1].value <<= fl_seq; break; case Tango::DEV_BOOLEAN: if (from_init == false) { if (!(str >> boolalpha >> boo)) throw_mem_value(device_list[i],att); att.set_write_value(boo); } else att.get_write_value(boo); boo_seq[0] = boo; att_val[nb_wr - 1].value <<= boo_seq; break; case Tango::DEV_USHORT: if (from_init == false) { if (!(str >> ush)) throw_mem_value(device_list[i],att); att.set_write_value(ush); } else att.get_write_value(ush); ush_seq[0] = ush; att_val[nb_wr - 1].value <<= ush_seq; break; case Tango::DEV_UCHAR: if (from_init == false) { short tmp_sh; if (!(str >> tmp_sh)) throw_mem_value(device_list[i],att); uch = (DevUChar)tmp_sh; att.set_write_value(uch); } else att.get_write_value(uch); uch_seq[0] = uch; att_val[nb_wr - 1].value <<= uch_seq; break; case Tango::DEV_ULONG: if (from_init == false) { if (!(str >> ulg)) throw_mem_value(device_list[i],att); att.set_write_value(ulg); } else att.get_write_value(ulg); ulg_seq[0] = ulg; att_val[nb_wr - 1].value <<= ulg_seq; break; case Tango::DEV_LONG64: if (from_init == false) { if (!(str >> lg64)) throw_mem_value(device_list[i],att); att.set_write_value(lg64); } else att.get_write_value(lg64); lg64_seq[0] = lg64; att_val[nb_wr - 1].value <<= lg64_seq; break; case Tango::DEV_ULONG64: if (from_init == false) { if (!(str >> ulg64)) throw_mem_value(device_list[i],att); att.set_write_value(ulg64); } else att.get_write_value(ulg64); ulg64_seq[0] = ulg64; att_val[nb_wr - 1].value <<= ulg64_seq; break; } // // Check the initialisation flag for memorized attributes. If the flag is false, do not add the element to the att_val // vector. This avoids a call to write the memorized value to the attribute. // if ( att.is_memorized_init() == false ) { nb_wr--; att_val.length(nb_wr); // reset memorized flag att.set_memorized(true); } else { // // Init the AttributeValue structure // att_val[nb_wr - 1].name = CORBA::string_dup(att.get_name().c_str()); att_val[nb_wr - 1].dim_x = 1; att_val[nb_wr - 1].dim_y = 0; att_val[nb_wr - 1].quality = Tango::ATTR_VALID; } } catch (Tango::DevFailed &e) { cout3 << "Cannot configure setpoint value for memorized attribute " << att.get_name() << endl; Tango::Except::print_exception(e); nb_wr--; att_val.length(nb_wr); // reset memorized flag att.set_memorized(true); } } } } if (nb_wr != 0) { // // Write attribute values. Print exception if any. // try { cout4 << "Writing data for " << att_val.length() << " attribute(s) for device " << device_list[i]->get_name() << endl; (static_cast(device_list[i]))->write_attributes_3(att_val); } catch (Tango::DevFailed &e) { cout3 << "Cannot write setpoint(s) value for any memorized attribute(s) on device " << device_list[i]->get_name() << endl; Tango::Except::print_exception(e); } catch (Tango::MultiDevFailed &e) { cout3 << "Cannot write setpoint(s) value for memorized attribute(s) of device " << device_list[i]->get_name() << endl; for (unsigned long k = 0;k < e.errors.length();k++) { WAttribute &att = device_list[i]->get_device_attr()->get_w_attr_by_name(att_val[e.errors[k].index_in_call].name.in()); att.set_mem_exception(e.errors[k].err_list); log4tango::Logger *log = device_list[i]->get_logger(); if (log->is_warn_enabled()) { log->warn_stream() << log4tango::LogInitiator::_begin_log << "Writing set_point for attribute " << att.get_name() << " failed" << endl; log->warn_stream() << log4tango::LogInitiator::_begin_log << "\tException desc = " << e.errors[k].err_list[0].desc.in() << endl; log->warn_stream() << log4tango::LogInitiator::_begin_log << "\tException reason = " << e.errors[k].err_list[0].reason.in() << endl; } } device_list[i]->set_run_att_conf_loop(true); Tango::NamedDevFailedList e_list (e, device_list[i]->get_name(), (const char *)"DeviceClass::set_memorized_values()", (const char *)API_AttributeFailed); Tango::Except::print_exception(e_list); } catch (...) { cout3 << "Cannot write setpoint(s) value for memorized attribute(s) of device " << device_list[i]->get_name() << endl; cerr << "Received unknown exception while trying to write memorized attribute(s)" << endl; size_t nb_att = att_val.length(); for (size_t k = 0;k < nb_att;k++) { stringstream ss; ss << "Received unknown exception (nor a devfailed, nor a MultiDevFailed !!"; Tango::DevErrorList errors; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "DeviceClass::set_memorized_values()"; errors[0].desc = CORBA::string_dup(ss.str().c_str()); errors[0].severity = ERR; WAttribute &att = device_list[i]->get_device_attr()->get_w_attr_by_name(att_val[k].name.in()); att.set_mem_exception(errors); log4tango::Logger *log = device_list[i]->get_logger(); if (log->is_warn_enabled()) { log->warn_stream() << log4tango::LogInitiator::_begin_log << "Writing set_point for attribute " << att.get_name() << " failed" << endl; } } device_list[i]->set_run_att_conf_loop(true); } // // Reset memorized flags // for (unsigned long k = 0;k < att_val.length();k++) { WAttribute &att = device_list[i]->get_device_attr()->get_w_attr_by_name(att_val[k].name.in()); att.set_memorized(true); } } } cout4 << "Leaving DeviceClass::set_memorized_values() method" << endl; } //------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::throw_mem_value() // // description : // Throw API_AttrWrongMemValue exception // // argument : // in : // - dev: Pointer to the device // - att: The attribute object // //-------------------------------------------------------------------------------------------------------------------- void DeviceClass::throw_mem_value(DeviceImpl *dev,Attribute &att) { TangoSys_OMemStream o; o << "Memorized value for attribute "; o << att.get_name(); o << " (device "; o << dev->get_name(); o << ") is in an incorrect format !" << ends; Except::throw_exception((const char *)API_AttrWrongMemValue, o.str(), (const char *)"DeviceClass::set_memorized_values"); } //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::~DeviceClass(string &s) // // description : // DeviceClass class destructor. // //-------------------------------------------------------------------------------------------------------------------- DeviceClass::~DeviceClass() { cout4 << "Entering DeviceClass destructor for class " << name << endl; // // Destroy the DbClass object // delete db_class; // // Destroy the device list // unsigned long i; if (device_list.size() != 0) { Tango::Util *tg = Tango::Util::instance(); PortableServer::POA_ptr r_poa = tg->get_poa(); unsigned long nb_dev = device_list.size(); for (i = 0;i < nb_dev;i++) { // // Clear vectors used to memorize info used to clean db in case of devices with dyn attr removed during device // destruction // tg->get_polled_dyn_attr_names().clear(); tg->get_full_polled_att_list().clear(); tg->get_all_dyn_attr_names().clear(); tg->get_dyn_att_dev_name().clear(); // // Delete device // delete_dev(0,tg,r_poa); // // Clean-up db (dyn attribute and cmd) // if (tg->get_polled_dyn_attr_names().size() != 0) tg->clean_attr_polled_prop(); if (tg->get_all_dyn_attr_names().size() != 0) tg->clean_dyn_attr_prop(); if (tg->get_polled_dyn_cmd_names().size() != 0) tg->clean_cmd_polled_prop(); vector::iterator it = device_list.begin(); device_list.erase(it); } device_list.clear(); CORBA::release(r_poa); } // // Destroy the command list // for (i = 0;i < command_list.size();i++) delete command_list[i]; command_list.clear(); // // Destroy the pipe list // map >::iterator ite; for (ite = ext->dev_pipe_list.begin();ite != ext->dev_pipe_list.end();ite++) { for (size_t loop = 0;loop < ite->second.size();loop++) delete (ite->second)[loop]; } // // Destroy the MultiClassAttribute object // delete class_attr; // // Destroy the MultiClassPipe object // delete class_pipe; // // Unregister the class from signal handler // DServerSignal::instance()->unregister_class_signal(this); // // Delete the class extension object // #ifndef HAS_UNIQUE_PTR delete ext; #endif cout4 << "Leaving DeviceClass destructor for class " << name << endl; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::delete_dev() // // description : // Delete a device from the class device list // // argument : // in : // - idx : // - tg : Pointer to the Tango Util singleton // - r_poa : Pointer to the CORBA POA // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::delete_dev(long idx,Tango::Util *tg,PortableServer::POA_ptr r_poa) { cout4 << "Entering DeviceClas::delete_dev method for device with index " << idx << endl; // // If the polling thread is alive and if device is polled, ask polling thread to stop polling // if ((tg->get_polling_threads_info().empty() == false) && (device_list[idx]->is_polled() == true)) { device_list[idx]->stop_polling(false); } // // Deactivate the CORBA object // bool py_dev = device_list[idx]->is_py_device(); bool exported_device = device_list[idx]->get_exported_flag(); if (exported_device == true) r_poa->deactivate_object(device_list[idx]->get_obj_id().in()); // // Remove the servant. // For C++ device, this will be automatically done by the POA when the last executing call will be over even if the // device is not exported // if (py_dev == true) { Device_3Impl *dev_3 = static_cast(device_list[idx]); dev_3->delete_dev(); } // // Wait for CORBA to call the device dtor // if (device_list[idx] != NULL && exported_device == true) { #ifdef _TG_WINDOWS_ while (device_list[idx] != NULL) { Sleep(10); } #else struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10000000; while (device_list[idx] != NULL) { nanosleep(&ts,NULL); } #endif } cout4 << "Leaving DeviceClass delete_dev" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::register_signal // // description : // Method to register a class on a signal. When the signal is sent to the process, the signal_handler // method of this class will be executed // // argument : // in : // - signo : The signal number // - delayed : The boolean delayed flag // //------------------------------------------------------------------------------------------------------------------- #if defined _TG_WINDOWS_ void DeviceClass::register_signal(long signo) { cout4 << "DeviceClass::register_signal() arrived for signal " << signo << endl; DServerSignal::instance()->register_class_signal(signo,this); cout4 << "Leaving DeviceClass::register_signal method()" << endl; } #else void DeviceClass::register_signal(long signo,bool handler) { cout4 << "DeviceClass::register_signal() arrived for signal " << signo << endl; DServerSignal::instance()->register_class_signal(signo,handler,this); cout4 << "Leaving DeviceClass::register_signal method()" << endl; } #endif //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::unregister_signal // // description : // Method to unregister a class on a signal. // // argument : // in : // - signo : The signal number // - delayed : The boolean delayed flag // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::unregister_signal(long signo) { cout4 << "DeviceClass::unregister_signal() arrived for signal " << signo << endl; DServerSignal::instance()->unregister_class_signal(signo,this); cout4 << "Leaving DeviceClass::unregister_signal method()" << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::signal_handler // // description : // This is the signal handler for the class. This method is defined as virtual and therefore, can be redefined // by DS programmers in their own classes derived from DeviceClass class // // argument : // in : // - signo : The signal number // //------------------------------------------------------------------------------------------------------------------ void DeviceClass::signal_handler(long signo) { cout4 << "DeviceClass::signal_handler() arrived for signal " << signo << endl; cout4 << "Leaving DeviceClass::signal_handler method()" << endl; } //+---------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::export_device() // // description : // This method exports a device to the outside world. This is done by sending its CORBA network parameter // (mainly the IOR) to the Tango database // // argument : // in : // - dev : The device to be exported // - corba_obj_name : The CORBA object name associated with the device. A default value is provided. // This field is mainly use for specific device server like the database device server. // //------------------------------------------------------------------------------------------------------------------ void DeviceClass::export_device(DeviceImpl *dev,const char *corba_obj_name) { cout4 << "DeviceClass::export_device() arrived" << endl; Device_var d; if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) { // // Take the Tango monitor in order to protect the device against external world access // until memorized attribute (if any) are set but forget the admin device // (which does not have any memorized attribute) // But don't do this for dynamic devices which are not created in the DServer::init_device method class loop // string &dev_name = dev->get_name_lower(); if ((get_device_factory_done() == false) && (dev_name.find("dserver") != 0)) dev->get_dev_monitor().get_monitor(); // // Activate the CORBA object incarnated by the dev C++ object // Also call _remove_ref to give POA the full ownership of servant // d = dev->_this(); dev->set_d_var(Tango::Device::_duplicate(d)); if (is_py_class() == false) dev->_remove_ref(); // // Store the ObjectId (The ObjectId_var type is a typedef of a string_var type) // PortableServer::ObjectId_var oid; try { PortableServer::POA_ptr r_poa = Util::instance()->get_poa(); oid = r_poa->reference_to_id(d); CORBA::release(r_poa); } catch (...) { TangoSys_OMemStream o; o << "Cant get CORBA reference Id for device " << dev->get_name() << ends; Except::throw_exception((const char *)API_CantGetDevObjectId, o.str(), (const char *)"DeviceClass::export_device"); } dev->set_obj_id(oid); } else { // // For server started without db usage (Mostly the database server). In this case, it is necessary to create our own // CORBA object id and to bind it into the Boot Manager for access through a stringified object reference // constructed using the corbaloc style. The API will try to connect to device using lower case letters. // Register device in POA with lower case letters // string corba_obj_name_lower(corba_obj_name); transform(corba_obj_name_lower.begin(),corba_obj_name_lower.end(),corba_obj_name_lower.begin(),::tolower); PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId(corba_obj_name_lower.c_str()); try { PortableServer::POA_ptr r_poa = Util::instance()->get_poa(); r_poa->activate_object_with_id(id.in(),dev); CORBA::release(r_poa); } catch (...) { TangoSys_OMemStream o; o << "Can't get CORBA reference Id for device " << dev->get_name() << ends; Except::throw_exception((const char *)API_CantGetDevObjectId, o.str(), (const char *)"DeviceClass::export_device"); } d = dev->_this(); dev->set_obj_id(id); dev->set_d_var(Tango::Device::_duplicate(d)); dev->_remove_ref(); } // // Prepare sent parameters and allocate mem for them // if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) { Tango::Util *tg = Tango::Util::instance(); CORBA::ORB_ptr orb_ptr = tg->get_orb(); char *s = orb_ptr->object_to_string(d); string ior_string(s); Tango::DbDevExportInfo exp; exp.name = dev->get_name(); exp.ior = ior_string; exp.host = tg->get_host_name(); exp.pid = tg->get_pid(); exp.version = tg->get_version_str(); // // Call db server // We are still in the server starting phase. Therefore, the db timeout is still high (13 sec the 07/01/2011) // with 3 retries in case of timeout // try { tg->get_database()->export_device(exp); } catch (Tango::CommunicationFailed &) { cerr << "CommunicationFailed while exporting device " << dev->get_name() << endl; CORBA::release(orb_ptr); CORBA::string_free(s); throw; } CORBA::release(orb_ptr); CORBA::string_free(s); } // // Set the DeviceImpl exported flag to true. Also enable device interface change event // dev->set_exported_flag(true); dev->enable_intr_change_ev(); cout4 << "Leaving DeviceClass::export_device method()" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::command_handler(string &s) // // description : // Command handler which is called by Device when a command is received. It will check to see if the command is // implemented. If so it will test to see if it is allowed in this state. Finally it will execute the // command by calling its execute method. If an error occurs it will throw a DevFailed exception. // //------------------------------------------------------------------------------------------------------------------- CORBA::Any *DeviceClass::command_handler(DeviceImpl *device,string &command,const CORBA::Any &in_any) { CORBA::Any *ret = NULL; vector::iterator i_cmd; string command_lower(command); cout4 << "Entering DeviceClass::command_handler() method" << endl; transform(command_lower.begin(),command_lower.end(),command_lower.begin(),::tolower); // // Search for command object first at class level then at device level (case of dynamic command installed at device // level) // bool found = false; for (i_cmd = command_list.begin();i_cmd < command_list.end();++i_cmd) { if ((*i_cmd)->get_lower_name() == command_lower) { found = true; break; } } if (found == false) { vector &dev_command_list = device->get_local_command_list(); for (i_cmd = dev_command_list.begin();i_cmd < dev_command_list.end();++i_cmd) { if ((*i_cmd)->get_lower_name() == command_lower) { found = true; break; } } } if (found == true) { // // Call the always executed method // device->always_executed_hook(); // // Check if command is allowed // if ((*i_cmd)->is_allowed(device,in_any) == false) { TangoSys_OMemStream o; o << "Command " << command << " not allowed when the device is in " << Tango::DevStateName[device->get_state()] << " state" << ends; Except::throw_exception((const char *)API_CommandNotAllowed, o.str(), (const char *)"DeviceClass::command_handler"); } // // Execute command // ret = (*i_cmd)->execute(device,in_any); } if (found == false) { cout3 << "DeviceClass::command_handler(): command " << command << " not found in class/device command" << endl; Command *def_cmd = get_default_command(); if (def_cmd != NULL) { // // Set name in default command object // def_cmd->set_name(command); // // Call the always executed method // device->always_executed_hook(); // // Check if command is allowed // if (def_cmd->is_allowed(device,in_any) == false) { TangoSys_OMemStream o; o << "Command " << command << " not allowed when the device is in " << Tango::DevStateName[device->get_state()] << " state" << ends; Except::throw_exception((const char *)API_CommandNotAllowed, o.str(), (const char *)"DeviceClass::command_handler"); } // // Execute command // ret = def_cmd->execute(device,in_any); } else { // // Throw an exception to client // TangoSys_OMemStream o; o << "Command " << command << " not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceClass::command_handler"); } } cout4 << "Leaving DeviceClass::command_handler() method" << endl; return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::add_wiz_dev_prop() // // description : // Method to add a device property definition for the device wizard // // argument : // in : // - name : The device property name // - desc : The device property description // - def : The device property default value // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::add_wiz_dev_prop(string &p_name,string &desc,string &def) { // // Name in lowercase letters // string name_low = p_name; transform(name_low.begin(),name_low.end(),name_low.begin(),::tolower); // // Check that this property is not already in the vector // vector::iterator ite; for (ite = wiz_dev_prop.begin();ite < wiz_dev_prop.end();++ite) { string tmp_name(*ite); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == name_low) break; } if (ite != wiz_dev_prop.end()) { TangoSys_OMemStream o; o << "Device property " << p_name; o << " for class " << name << " is already defined in the wizard" << ends; Except::throw_exception((const char *)API_WizardConfError, o.str(), (const char *)"DeviceClass::add_wiz_dev_prop"); } // // Insert data in vector // wiz_dev_prop.push_back(p_name); wiz_dev_prop.push_back(desc); wiz_dev_prop.push_back(def); } void DeviceClass::add_wiz_dev_prop(string &p_name,string &desc) { string def(AlrmValueNotSpec); add_wiz_dev_prop(p_name,desc,def); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::add_wiz_class_prop() // // description : // Method to add a class property definition for the device wizard // // argument : // in : // - name : The class property name // - desc : The class property description // - def : The class property default value // //-------------------------------------------------------------------------------------------------------------------- void DeviceClass::add_wiz_class_prop(string &p_name,string &desc,string &def) { // // Name in lowercase letters // string name_low = p_name; transform(name_low.begin(),name_low.end(),name_low.begin(),::tolower); // // Check that this property is not already in the vector // vector::iterator ite; for (ite = wiz_class_prop.begin();ite < wiz_class_prop.end();++ite) { string tmp_name(*ite); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == name_low) break; } if (ite != wiz_class_prop.end()) { TangoSys_OMemStream o; o << "Class property " << p_name; o << " for class " << name << " is already defined in the wizard" << ends; Except::throw_exception((const char *)API_WizardConfError, o.str(), (const char *)"DeviceClass::add_wiz_dev_prop"); } // // Insert data in vector // wiz_class_prop.push_back(p_name); wiz_class_prop.push_back(desc); wiz_class_prop.push_back(def); } void DeviceClass::add_wiz_class_prop(string &p_name,string &desc) { string def(AlrmValueNotSpec); add_wiz_class_prop(p_name,desc,def); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::device_destroyer // // description : // Method to remove and delete a device from the running devices belonging to the Tango class // // argument : // in : // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::device_destroyer(const string &dev_name) { // // Check that the class know this device // unsigned long k; for (k = 0;k < device_list.size();k++) { if (device_list[k]->get_name() == dev_name) break; } if (k == device_list.size()) { TangoSys_OMemStream o; o << "Device " << dev_name << " not in Tango class device list!" << ends; Tango::Except::throw_exception((const char *)API_CantDestroyDevice,o.str(), (const char *)"DeviceClass::device_destroyer"); } // // Check if the device is polled. If yes, ask polling thread to stop polling it // if (device_list[k]->is_polled() == true) { device_list[k]->stop_polling(); } // // Delete the device // Tango::Util *tg = Tango::Util::instance(); PortableServer::POA_ptr r_poa = tg->get_poa(); delete_dev(k,tg,r_poa); vector::iterator it = device_list.begin(); it += k; device_list.erase(it); CORBA::release(r_poa); } void DeviceClass::device_destroyer(const char *dev_name) { string name_str(dev_name); return device_destroyer(name_str); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceClass::is_command_allowed // // description : // Method to check if a command is allowed even if the device is locked by another client. It follows the // definition of the Tango control access system to define what is an allowed command // // argument : // in : // - cmd : The command name // //-------------------------------------------------------------------------------------------------------------------- bool DeviceClass::is_command_allowed(const char *cmd) { bool ret = true; string tmp_cmd(cmd); transform(tmp_cmd.begin(),tmp_cmd.end(),tmp_cmd.begin(),::tolower); vector::iterator pos = find(allowed_cmds.begin(),allowed_cmds.end(),tmp_cmd); if (pos == allowed_cmds.end()) ret = false; return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::get_mcast_event() // // description : // Get for all class devices and for all attributes multicast event parameters (if any) // // argument : // in : // - dserv : Pointer to the DServer device // //------------------------------------------------------------------------------------------------------------------ void DeviceClass::get_mcast_event(DServer *dserv) { cout4 << "Entering DeviceClass::get_mcast_event() method" << endl; vector m_cast; for (unsigned int i = 0;i < device_list.size();++i) { vector &att_list = device_list[i]->get_device_attr()->get_attribute_list(); for (unsigned int j = 0;j < att_list.size();++j) { dserv->mcast_event_for_att(device_list[i]->get_name_lower(),att_list[j]->get_name_lower(),m_cast); if (m_cast.empty() == false) att_list[j]->set_mcast_event(m_cast); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::get_cmd_by_name // // description : // Get a reference to the Command object // // arguemt : // in : // - cmd_name : The command name // //------------------------------------------------------------------------------------------------------------------ Command &DeviceClass::get_cmd_by_name(const string &cmd_name) { vector::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(command_list.begin(),command_list.end(), [&] (Command *cmd) -> bool { if (cmd_name.size() != cmd->get_lower_name().size()) return false; string tmp_name(cmd_name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); return cmd->get_lower_name() == tmp_name; }); #else pos = find_if(command_list.begin(),command_list.end(), bind2nd(WantedCmd(),cmd_name.c_str())); #endif if (pos == command_list.end()) { cout3 << "DeviceClass::get_cmd_by_name throwing exception" << endl; TangoSys_OMemStream o; o << cmd_name << " command not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceClass::get_cmd_by_name"); } return *(*pos); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::get_pipe_by_name // // description : // Get a reference to the Pipe object // // arguemt : // in : // - pipe_name : The pipe name // - dev_name : The device name (lower case letters) // //------------------------------------------------------------------------------------------------------------------ Pipe &DeviceClass::get_pipe_by_name(const string &pipe_name,const string &dev_name) { map >::iterator ite = ext->dev_pipe_list.find(dev_name); if (ite == ext->dev_pipe_list.end()) { cout3 << "DeviceClass::get_pipe_by_name throwing exception" << endl; TangoSys_OMemStream o; o << dev_name << " device not found in pipe map" << ends; Except::throw_exception(API_PipeNotFound,o.str(),"DeviceClass::get_pipe_by_name"); } vector::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(ite->second.begin(),ite->second.end(), [&] (Pipe *pi) -> bool { if (pipe_name.size() != pi->get_lower_name().size()) return false; string tmp_name(pipe_name); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); return pi->get_lower_name() == tmp_name; }); #else pos = find_if(ite->second.begin(),ite->second.end(), bind2nd(WantedPipe(),pipe_name.c_str())); #endif if (pos == ite->second.end()) { cout3 << "DeviceClass::get_pipe_by_name throwing exception" << endl; TangoSys_OMemStream o; o << pipe_name << " pipe not found" << ends; Except::throw_exception(API_PipeNotFound,o.str(),"DeviceClass::get_pipe_by_name"); } return *(*pos); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::remove_command // // description : // Delete a command from the command list // // argument : // in : // - cmd_name : The command name (in lower case letter) // //----------------------------------------------------------------------------------------------------------------- void DeviceClass::remove_command(const string &cmd_name) { vector::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(command_list.begin(),command_list.end(), [&] (Command *cmd) -> bool { if (cmd_name.size() != cmd->get_lower_name().size()) return false; return cmd->get_lower_name() == cmd_name; }); #else pos = find_if(command_list.begin(),command_list.end(), bind2nd(WantedCmd(),cmd_name.c_str())); #endif if (pos == command_list.end()) { cout3 << "DeviceClass::get_cmd_by_name throwing exception" << endl; TangoSys_OMemStream o; o << cmd_name << " command not found" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DeviceClass::get_cmd_by_name"); } command_list.erase(pos); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::check_att_conf // // description : // Check attribute configuration (for wrong conf. in db exception) for all devices in the class // //------------------------------------------------------------------------------------------------------------------- void DeviceClass::check_att_conf() { vector::iterator ite; for (ite = device_list.begin();ite != device_list.end();++ite) (*ite)->check_att_conf(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::release_devices_mon // // description : // Release all device(s) class monitor. This is needed in DS startup sequence. Each device monitor is taken // before the device is known to CORBA and released after the memorized attributes (if any) are set // //------------------------------------------------------------------------------------------------------------------ void DeviceClass::release_devices_mon() { vector::iterator ite; // // Release monitor for all devices belonging to this class // for (ite = device_list.begin();ite != device_list.end();++ite) (*ite)->get_dev_monitor().rel_monitor(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::create_device_pipe // // description : // Create all devices for a device // // argument : // in : // - cl : The device class (we need here the pointer to the real device class not to the base class) // - dev : Device ptr // //------------------------------------------------------------------------------------------------------------------ void DeviceClass::create_device_pipe(DeviceClass *cl,DeviceImpl *dev) { // // Create pipe for device and store them in the pipe map // cl->pipe_factory(); if (ext->dev_pipe_list.empty() == true) { MultiClassPipe *c_pipe = get_class_pipe(); c_pipe->init_class_pipe(this); } sort(pipe_list.begin(),pipe_list.end(),less_than_pipe); string dev_name = dev->get_name_lower(); ext->dev_pipe_list.insert(make_pair(dev_name,pipe_list)); pipe_list.clear(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DeviceClass::get_pipe_list // // description : // Get a reference to the Pipe list for a device // // argument : // in : // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------ vector &DeviceClass::get_pipe_list(const string &dev_name) { string local_dev_name(dev_name); transform(local_dev_name.begin(),local_dev_name.end(),local_dev_name.begin(),::tolower); map >::iterator ite = ext->dev_pipe_list.find(local_dev_name); if (ite == ext->dev_pipe_list.end()) { cout3 << "DeviceClass::get_pipe_by_name throwing exception" << endl; TangoSys_OMemStream o; o << dev_name << " device not found in pipe map" << ends; Except::throw_exception(API_PipeNotFound,o.str(),"DeviceClass::get_pipe_list"); } return ite->second; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/devicelog.cpp0000644023471100065110000002271213034745002015233 00000000000000//+============================================================================= // // file : DeviceLog.cpp // // description : Logging oriented methods of the DeviceImpl class // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 3.14 2010/09/09 13:45:22 taurel // - Add year 2010 in Copyright notice // // Revision 3.13 2009/01/21 12:49:04 taurel // - Change CopyRights for 2009 // // Revision 3.12 2008/10/06 15:00:36 taurel // - Changed the licensing info from GPL to LGPL // // Revision 3.11 2008/10/03 06:51:36 taurel // - Add some licensing info in each files // // Revision 3.10 2008/03/11 14:38:25 taurel // - Apply patches from Frederic Picca about compilation with gcc 4.2 // // Revision 3.9 2007/10/26 11:30:35 taurel // - Set admin device logging level if command line -v > 4 // // Revision 3.8 2007/10/17 13:43:24 taurel // - Admin device default logging level set to OFF // // Revision 3.7 2006/03/27 17:00:46 jensmeyer // moved Makefile up // // Revision 3.6 2006/03/02 08:53:45 taurel // - Reset the changes made between 3.4 and 3.5 for VC7 because it makes library // logging messages invisible // // Revision 3.5 2006/02/17 16:54:11 jensmeyer // Corrections when porting to VC7 under windows // // Revision 3.4 2005/07/28 07:34:41 taurel // - Fix some incompatibility between 5.1 and 5.2 // // Revision 3.3 2005/07/04 15:33:30 nleclercq // Added command line logging level 5 for TANGO core debugging // // Revision 3.2 2005/02/25 13:28:51 nleclercq // Added logging support in 'const' methods // // Revision 3.1 2003/05/28 14:55:09 taurel // Add the include (conditionally) of the include files generated by autoconf // // Revision 3.0 2003/03/25 16:42:00 taurel // Many changes for Tango release 3.0 including // - Added full logging features // - Added asynchronous calls // - Host name of clients now stored in black-box // - Three serialization model in DS // - Fix miscellaneous bugs // - Ported to gcc 3.2 // - Added ApiUtil::cleanup() and destructor methods // - Some internal cleanups // - Change the way how TangoMonitor class is implemented. It's a recursive // mutex // // Revision 2.3 2003/03/13 15:17:50 nleclercq // Minor modifications on logging implementation // // Revision 2.2 2003/03/11 17:55:52 nleclercq // Switch from log4cpp to log4tango // // Revision 2.1 2003/02/17 14:57:40 taurel // Added the new Tango logging stuff (Thanks Nicolas from Soleil) // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO #include namespace Tango { //+------------------------------------------------------------------------- // method : DeviceImpl::get_logger_i //-------------------------------------------------------------------------- log4tango::Logger* DeviceImpl::get_logger_i (void) { try { // trace cout4 << "Entering DeviceImpl::get_logger_i" << endl; // instanciate the logger ( // shame on me for a such huggly impl. but polymorphism // can't be used here ! if (logger == 0) { if (device_class->get_name() == "DServer") { logger = Logging::get_core_logger(); } else { // get device name std::string dev_name(device_name); // avoid case sensitive troubles std::transform(dev_name.begin(), dev_name.end(), dev_name.begin(), ::tolower); // instanciate the logger using device name logger = new log4tango::Logger(dev_name); if (logger == 0) { logger = Logging::get_core_logger(); } // set default level logger->set_level(log4tango::Level::WARN); // save current level saved_log_level = log4tango::Level::WARN; } } // trace cout4 << "Leaving DeviceImpl::get_logger_i" << endl; } catch (...) { // save our souls... logger = Logging::get_core_logger(); } return logger; } //+------------------------------------------------------------------------- // method : DeviceImpl::init_logger //-------------------------------------------------------------------------- void DeviceImpl::init_logger (void) { try { // trace cout4 << "Entering DeviceImpl::init_logger" << endl; // get Tango::Util instance Tango::Util *tg = Tango::Util::instance(); // get cmd line logging level then ... int trace_level = tg->get_trace_level(); // ... convert it to log4tango level log4tango::Level::Value cmd_line_level = log4tango::Level::OFF; if (trace_level > 4) cmd_line_level = log4tango::Level::DEBUG; bool level_set_from_cmd_line = true; // are we initializing the dserver's logger log4tango::Logger* the_logger = get_logger(); if (the_logger != Logging::get_core_logger()) { // does the logging level set from cmd line? if (trace_level <= 0) { level_set_from_cmd_line = false; cmd_line_level = log4tango::Level::OFF; } else if (trace_level <= 2) { cmd_line_level = log4tango::Level::INFO; } else { cmd_line_level = log4tango::Level::DEBUG; } // add a console target if logging level set from cmd line if (level_set_from_cmd_line) { // add a console target if logging level set from cmd line Logging::add_logging_target(the_logger, kLogTargetConsole, 0); } } if (tg->_UseDb == false) { // done if we are not using the database if (level_set_from_cmd_line) the_logger->set_level(cmd_line_level); cout4 << "Leaving DeviceImpl::init_logger" << endl; return; } // get both logging level and targets from database DbData db_data; db_data.push_back(DbDatum("logging_level")); db_data.push_back(DbDatum("logging_target")); db_data.push_back(DbDatum("logging_rft")); try { db_dev->get_property(db_data); } catch (...) { // error: set logging level then return the_logger->set_level(cmd_line_level); return; } // set logging level (if not set from cmd line) std::string log_level_property; if (!level_set_from_cmd_line && db_data[0].is_empty() == false) { db_data[0] >> log_level_property; // avoid case sensitive troubles std::transform(log_level_property.begin(), log_level_property.end(), log_level_property.begin(), ::toupper); cout4 << "Initial logging level set to [" << log_level_property << "]" << endl; // convert from string to log4tango level log4tango::Level::Value log4tango_level = log4tango::Level::WARN; try { log4tango_level = Logging::tango_to_log4tango_level(log_level_property, false); } catch (...) { // ignore exception } // set logger's level (from property) the_logger->set_level(log4tango_level); } else { // set logger's level (from cmd line) if (the_logger != Logging::get_core_logger()) the_logger->set_level(cmd_line_level); } // save current logging level saved_log_level = the_logger->get_level(); // get rolling threshold for file targets long rft_property = static_cast(kDefaultRollingThreshold); if (db_data[2].is_empty() == false) { db_data[2] >> rft_property; } // save current rolling threshold rft = static_cast(rft_property); // set logging targets std::vector log_target_property; if (db_data[1].is_empty() == false) { db_data[1] >> log_target_property; // attach targets to logger for (unsigned int i = 0; i < log_target_property.size(); i++) { Logging::add_logging_target(the_logger, log_target_property[i], 0); } } // set rolling file threshold for file targets Logging::set_rolling_file_threshold(the_logger, rft); // trace cout4 << "Leaving DeviceImpl::init_logger" << endl; } catch (...) { // igore any exception } } //+------------------------------------------------------------------------- // method : DeviceImpl::start_logging //-------------------------------------------------------------------------- void DeviceImpl::start_logging (void) { get_logger()->set_level(saved_log_level); } //+------------------------------------------------------------------------- // method : DeviceImpl::stop_logging //-------------------------------------------------------------------------- void DeviceImpl::stop_logging (void) { saved_log_level = get_logger()->get_level(); get_logger()->set_level(log4tango::Level::OFF); } } // namespace Tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/devintr.cpp0000644023471100065110000001641613034745002014751 00000000000000static const char *RcsId = "$Id: devintr.cpp 27410 2015-01-27 05:46:17Z taurel $"; //+================================================================================================================== // // file : devintr.cpp // // description : C++ source code for the DevIntr class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // DevIntr::get_interface // // description : // Get a device interface // // argument : // in : // - dev: Device ptr // //-------------------------------------------------------------------------------------------------------------------- void DevIntr::get_interface(DeviceImpl *dev) { build_cmd_interfaces(dev,cmds); build_att_interfaces(dev,atts); } //-------------------------------------------------------------------------------------------------------------------- // // method : // DevIntr::build_cmd_interfaces // // description : // Build a ordered list of device commands interface // // argument : // in : // - dev: Device ptr // out : // - cmds: reference to vector where commands interface must be stored // //-------------------------------------------------------------------------------------------------------------------- void DevIntr::build_cmd_interfaces(DeviceImpl *dev,vector &cmds) { // // Get commands interface at class and device levels // cmds.clear(); size_t cmd_class = dev->get_device_class()->get_command_list().size(); size_t cmd_dev = dev->get_local_command_list().size(); size_t nb_cmd = cmd_class + cmd_dev; cmds.reserve(nb_cmd); for(size_t loop = 0;loop < cmd_class;loop++) { CmdIntr ci; Command *cmd_ptr = (dev->get_device_class()->get_command_list())[loop]; ci.name = cmd_ptr->get_lower_name(); ci.in_type = cmd_ptr->get_in_type(); ci.out_type = cmd_ptr->get_out_type(); cmds.push_back(ci); } for(size_t loop = 0;loop < cmd_dev;loop++) { CmdIntr ci; Command *cmd_ptr = (dev->get_local_command_list())[loop]; ci.name = cmd_ptr->get_lower_name(); ci.in_type = cmd_ptr->get_in_type(); ci.out_type = cmd_ptr->get_out_type(); cmds.push_back(ci); } // // Sort this list // sort(cmds.begin(),cmds.end()); } //-------------------------------------------------------------------------------------------------------------------- // // method : // DevIntr::build_att_interfaces // // description : // Build a ordered list of device attributes interface // // argument : // in : // - dev: Device ptr // out : // - atts: reference to vector where commands interface must be stored // //-------------------------------------------------------------------------------------------------------------------- void DevIntr::build_att_interfaces(DeviceImpl *dev,vector &atts) { // // Get attribute(s) interface // atts.clear(); size_t nb_attr = dev->get_device_attr()->get_attribute_list().size(); atts.reserve(nb_attr); for (size_t loop = 0;loop < nb_attr;loop++) { AttrIntr ai; Attribute *att_ptr = (dev->get_device_attr()->get_attribute_list())[loop]; ai.name = att_ptr->get_name_lower(); ai.writable = att_ptr->get_writable(); ai.data_type = att_ptr->get_data_type(); ai.data_format = att_ptr->get_data_format(); ai.max_x = att_ptr->get_max_dim_x(); ai.max_y = att_ptr->get_max_dim_y(); ai.enum_labels = att_ptr->get_enum_labels(); if (ai.writable == READ_WRITE || ai.writable == WRITE) { WAttribute *w_att_ptr = static_cast(att_ptr); ai.mem = w_att_ptr->get_memorized(); ai.mem_init = w_att_ptr->get_memorized_init(); ai.writable_attr_name = w_att_ptr->get_assoc_name(); } else { ai.mem = false; ai.mem_init = false; } atts.push_back(ai); } // // Sort the list // sort(atts.begin(),atts.end()); } //-------------------------------------------------------------------------------------------------------------------- // // method : // DevIntr::has_changed // // description : // Check if the device interface has changed // // argument : // in : // - dev: Device ptr // // return: // True if the device interface has changed // //-------------------------------------------------------------------------------------------------------------------- bool DevIntr::has_changed(DeviceImpl *dev) { bool ret = false; // // First, check for commands // vector v_ci; build_cmd_interfaces(dev,v_ci); if (v_ci != cmds) ret = true; else { // // Check attributes // vector v_ai; build_att_interfaces(dev,v_ai); if (v_ai != atts) ret = true; } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DevIntr::== operator // // description : // Check the equality of inner structure // // argument : // in : // - rhs: The right hand side of the equality // // return: // True if the two instances are equals // //-------------------------------------------------------------------------------------------------------------------- bool DevIntr::CmdIntr::operator==(const struct CmdIntr &rhs) const { bool ret = true; if (name != rhs.name) ret = false; else { if (in_type != rhs.in_type) ret = false; else { if (out_type != rhs.out_type) ret = false; } } return ret; } bool DevIntr::AttrIntr::operator==(const struct AttrIntr &rhs) const { bool ret = true; if (name != rhs.name) ret = false; else { if (writable != rhs.writable) ret = false; else { if (data_type != rhs.data_type) ret = false; else { if (data_format != rhs.data_format) ret = false; else { if (max_x != rhs.max_x) ret = false; else { if (max_y != rhs.max_y) ret = false; else { if (mem != rhs.mem) ret = false; else { if (mem_init != rhs.mem_init) ret = false; else { if (writable_attr_name != rhs.writable_attr_name) ret = false; else { if (enum_labels.size() != rhs.enum_labels.size()) ret = false; } } } } } } } } } return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dintrthread.cpp0000644023471100065110000001520213034745001015575 00000000000000static const char *RcsId = "$Id: dintrthread.cpp 28219 2015-07-06 06:09:46Z taurel $"; //+================================================================================================================= // // file : dintrthread.cpp // // description : C++ source code for the DevIntrThread class. This class is used for the device interface // change thread. The rule of this thread is to delay the event sending in order to minimize // the number of events thrown when dynamic command(s) and/or attribute(s) are added/removed // in a loop. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28219 $ // //-================================================================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // DevIntrThread::DevIntrThread // // description : // The device interface change thread constructor. // //------------------------------------------------------------------------------------------------------------------- DevIntrThread::DevIntrThread(ShDevIntrTh &cmd,TangoMonitor &m,DeviceImpl *_d): shared_data(cmd),p_mon(m),dev(_d) { shared_data.cmd_pending = false; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DevIntrThread::run_undetached // // description : // The device interface change thread main code // //------------------------------------------------------------------------------------------------------------------ void DevIntrThread::run(TANGO_UNUSED(void *ptr)) { // // The main loop // bool exit = false; try { while (exit == false) { DevIntrCmdType received = get_command(DEV_INTR_THREAD_SLEEP_TIME); switch (received) { case DEV_INTR_COMMAND: execute_cmd(); break; case DEV_INTR_TIME_OUT: try { push_event(); } catch (Tango::DevFailed &e) { cerr << "Received a DevFailed exception while trying to push the device interface change event!!!" << endl; cerr << e.errors[0].desc.in() << endl; } exit = true; break; } } { omni_mutex_lock sync(p_mon); shared_data.th_running = false; } omni_thread::exit(); } catch (omni_thread_fatal &) { cerr << "OUPS !! A omni thread fatal exception in a device interface change event thread!!!!!!!!" << endl; } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DevIntrThread::get_command // // description : // This method wait on the shared monitor for a new command to be sent to the device interface change thread. // The thread waits with a timeout. // // argument : // in : // - tout : The timeout in mS // // return : // One enum with two possible value: Thread awaken due to timeout or thread awaken due to a received command // //------------------------------------------------------------------------------------------------------------------ DevIntrCmdType DevIntrThread::get_command(DevLong tout) { omni_mutex_lock sync(p_mon); DevIntrCmdType ret; // // Wait on monitor // if (shared_data.cmd_pending == false) { cout4 << "DevIntrThread:: Going to wait on monitor" << endl; p_mon.wait(tout); } // // Test if it is a new command. If yes, copy its data locally // if (shared_data.cmd_pending == true) { local_cmd = shared_data; ret = DEV_INTR_COMMAND; } else ret = DEV_INTR_TIME_OUT; return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevIntrThread::execute_cmd // // description : // This method is called when a command has been received. It execute the command! // //------------------------------------------------------------------------------------------------------------------ void DevIntrThread::execute_cmd() { vector::iterator pos; bool need_exit = false; switch (local_cmd.cmd_code) { // // A new rest // case Tango::DEV_INTR_SLEEP : { break; } // // Ask locking thread to exit // case Tango::DEV_INTR_EXIT : need_exit = true; break; } // // Inform requesting thread that the work is done // { omni_mutex_lock sync(p_mon); shared_data.cmd_pending = false; p_mon.signal(); } // // If the command was an exit one, do it now // if (need_exit == true) { { omni_mutex_lock sync(p_mon); shared_data.th_running = false; } omni_thread::exit(); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevIntrThread::push_event // // description : // This method pushes the device interface change event if there is a interface change // //------------------------------------------------------------------------------------------------------------------ void DevIntrThread::push_event() { cout4 << "Device interface change event thread pushing event!" << endl; AutoTangoMonitor sync(dev,true); if (shared_data.interface.has_changed(dev) == true) { cout4 << "Device interface has changed" << endl; Device_5Impl *dev_5 = static_cast(dev); DevCmdInfoList_2 *cmds_list = dev_5->command_list_query_2(); DevVarStringArray dvsa(1); dvsa.length(1); dvsa[0] = Tango::string_dup(AllAttr_3); AttributeConfigList_5 *atts_list = dev_5->get_attribute_config_5(dvsa); ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); event_supplier_zmq->push_dev_intr_change_event(dev,false,cmds_list,atts_list); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dserver.cpp0000644023471100065110000014757513034745001014762 00000000000000static const char *RcsId = "$Id: dserver.cpp 30110 2016-08-31 13:14:35Z taurel $\n$Name$"; //+================================================================================================================== // // file : DServer.cpp // // description : C++ source for the DServer class and its commands. The class is derived from Device. // It represents the CORBA servant object which will be accessed from the network. All commands // which can be executed on a DServer object are implemented in this file. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30110 $ // //-================================================================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #ifndef _TG_WINDOWS_ #include #include #include #endif /* _TG_WINDOWS_ */ #include extern omni_thread::key_t key_py_data; namespace Tango { ClassFactoryFuncPtr DServer::class_factory_func_ptr = NULL; //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::DServer(string &s) // // description : // constructor for DServer object // // args : // in : // - cp_ptr : The class object pointer // - n : The device name // - d : The device description (default to "not initialised") // - s : The device state (default to UNKNOWN) // - st : The device status (default to "Not initialised") // //------------------------------------------------------------------------------------------------------------------ DServer::DServer(DeviceClass *cl_ptr,const char *n,const char *d,Tango::DevState s,const char *st) :TANGO_BASE_CLASS(cl_ptr,n,d,s,st) { process_name = Tango::Util::instance()->get_ds_exec_name(); instance_name = Tango::Util::instance()->get_ds_inst_name(); full_name = process_name; full_name.append(1,'/'); full_name.append(instance_name); fqdn = "tango://"; Tango::Util *tg = Tango::Util::instance(); Database *db = tg->get_database(); if (db != NULL) fqdn = fqdn + db->get_db_host() + ':' + db->get_db_port() + "/dserver/" + full_name; else fqdn = "dserver/" + full_name; last_heartbeat = time(NULL); last_heartbeat_zmq = last_heartbeat; heartbeat_started = false; polling_th_pool_size = DEFAULT_POLLING_THREADS_POOL_SIZE; optimize_pool_usage = true; from_constructor = true; init_device(); from_constructor = false; } bool less_than (Command *a,Command *b) { if (a->get_name() < b->get_name()) return true; else return false; } void DServer::init_device() { // // In case of database in file // Tango::Util *tg = Tango::Util::instance(); if (tg->_FileDb) { tg->reset_filedatabase(); db_dev->set_dbase(tg->get_database()); } // // Get device properties // get_dev_prop(tg); // // Destroy already registered classes // if (class_list.empty() == false) { delete_devices(); } cout3 << "DServer::DSserver() create dserver " << device_name << endl; bool class_factory_done = false; unsigned long i = 0; try { // // Activate the POA manager // PortableServer::POA_var poa = Util::instance()->get_poa(); PortableServer::POAManager_var manager = poa->the_POAManager(); PortableServer::POAManager::State man_state = manager->get_state(); if ((man_state == PortableServer::POAManager::HOLDING) || (man_state == PortableServer::POAManager::DISCARDING)) manager->activate(); // // Create user TDSOM implementation // if (class_factory_func_ptr == NULL) class_factory(); else class_factory_func_ptr(this); class_factory_done = true; if (class_list.empty() == false) { // // Set the class list pointer in the Util class and add the DServer object class // tg->set_class_list(&class_list); tg->add_class_to_list(this->get_device_class()); // // Retrieve event related properties (multicast and other) // get_event_misc_prop(tg); // // In case nodb is used, validate class name used in DS command line // if (tg->_UseDb == false) tg->validate_cmd_line_classes(); // // A loop for each class // for (i = 0;i < class_list.size();i++) { // // Build class commands // class_list[i]->command_factory(); // // Sort the Command list array // sort(class_list[i]->get_command_list().begin(),class_list[i]->get_command_list().end(),less_than); // // Build class attributes // MultiClassAttribute *c_attr = class_list[i]->get_class_attr(); class_list[i]->attribute_factory(c_attr->get_attr_list()); c_attr->init_class_attribute(class_list[i]->get_name()); // // Retrieve device(s) name list from the database. No need to implement a retry here (in case of db server restart) // because the db reconnection is forced by the get_property call executed during xxxClass construction // before we reach this code. // if (tg->_UseDb == true) { Tango::Database *db = tg->get_database(); Tango::DbDatum na; try { na = db->get_device_name(tg->get_ds_name(),class_list[i]->get_name(),tg->get_db_cache()); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Database error while trying to retrieve device list for class " << class_list[i]->get_name().c_str() << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"Dserver::init_device"); } long nb_dev = na.size(); Tango::DevVarStringArray dev_list(nb_dev); dev_list.length(nb_dev); for (int l = 0;l < nb_dev;l++) dev_list[l] = na.value_string[l].c_str(); cout4 << dev_list.length() << " device(s) defined" << endl; // // Create all device(s) - Device creation creates device pipe(s) // class_list[i]->set_device_factory_done(false); { AutoTangoMonitor sync(class_list[i]); class_list[i]->device_factory(&dev_list); } class_list[i]->set_device_factory_done(true); // // Set value for each device with memorized writable attr. This is necessary only if db is used // For Python device server, writing the attribute will tak the Python lock. If we already have it --> dead lock. // Release the python lock if we already have it before calling the set_memorized_values method // PyLock *lock_ptr = NULL; omni_thread *th; if (tg->is_py_ds() == true) { th = omni_thread::self(); omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Release(); } class_list[i]->set_memorized_values(true); if (tg->is_py_ds() == true) { lock_ptr->Get(); } // // Check attribute configuration // class_list[i]->check_att_conf(); // // Get mcast event parameters (in case of) // class_list[i]->get_mcast_event(this); // // Release device(s) monitor // class_list[i]->release_devices_mon(); } else { // // Retrieve devices name list from either the command line or from the device_name_factory method // vector &list = class_list[i]->get_nodb_name_list(); Tango::DevVarStringArray *dev_list_nodb = new Tango::DevVarStringArray(); tg->get_cmd_line_name_list(class_list[i]->get_name(),list); if (i == class_list.size() - 1) { tg->get_cmd_line_name_list(NoClass,list); } if (list.empty() == true) class_list[i]->device_name_factory(list); if (list.empty() == true) { dev_list_nodb->length(1); (*dev_list_nodb)[0] = CORBA::string_dup("NoName"); } else { (*dev_list_nodb) << list; } // // Create all device(s) // class_list[i]->set_device_factory_done(false); { AutoTangoMonitor sync(class_list[i]); class_list[i]->device_factory(dev_list_nodb); } class_list[i]->set_device_factory_done(true); delete dev_list_nodb; } } } man_state = manager->get_state(); if (man_state == PortableServer::POAManager::DISCARDING) manager->activate(); } catch (bad_alloc &) { // // If the class_factory method have not been successfully executed, erase all classes already built. If the error // occurs during the command or device factories, erase only the following classes // TangoSys_OMemStream o; if (class_factory_done == false) { long class_err = class_list.size() + 1; o << "Can't allocate memory in server while creating class number " << class_err << ends; if (class_list.empty() == false) { for (unsigned long j = 0;j < class_list.size();j++) { class_list[j]->release_devices_mon(); if (class_list[j]->is_py_class() == false) delete class_list[j]; else class_list[j]->delete_class(); } class_list.clear(); } } else { o << "Can't allocate memory in server while building command(s) or device(s) for class number " << i + 1 << ends; for (unsigned long j = i;j < class_list.size();j++) { class_list[j]->release_devices_mon(); if (class_list[j]->is_py_class() == false) delete class_list[j]; else class_list[j]->delete_class(); } class_list.erase(class_list.begin() + i,class_list.end()); } Tango::Util::instance()->set_svr_shutting_down(true); Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"DServer::init_device"); } catch (Tango::NamedDevFailedList &) { // // If the class_factory method have not been successfully executed, erase all classes already built. If the error // occurs during the command or device factories, erase only the following classes // if (class_factory_done == false) { if (class_list.empty() == false) { for (unsigned long j = 0;j < class_list.size();j++) { class_list[j]->release_devices_mon(); if (class_list[j]->is_py_class() == false) delete class_list[j]; else class_list[j]->delete_class(); } class_list.clear(); } } else { for (unsigned long j = i;j < class_list.size();j++) { class_list[j]->release_devices_mon(); if (class_list[j]->is_py_class() == false) delete class_list[j]; else class_list[j]->delete_class(); } class_list.erase(class_list.begin() + i,class_list.end()); } Tango::Util::instance()->set_svr_shutting_down(true); throw; } catch (Tango::DevFailed &) { // // If the class_factory method have not been successfully executed, erase all classes already built. If the error // occurs during the command or device factories, erase only the following classes // if (class_factory_done == false) { if (class_list.empty() == false) { for (unsigned long j = 0;j < class_list.size();j++) { if (class_list[j]->is_py_class() == false) delete class_list[j]; else { class_list[j]->delete_class(); break; } } class_list.clear(); } } else { for (unsigned long j = i;j < class_list.size();j++) { if (class_list[j]->is_py_class() == false) delete class_list[j]; } class_list.erase(class_list.begin() + i,class_list.end()); } Tango::Util::instance()->set_svr_shutting_down(true); throw; } } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::~DServer // // description : // destructor for DServer object // //----------------------------------------------------------------------------------------------------------------- DServer::~DServer() { // // Destroy already registered classes // if (class_list.empty() == false) { for (long i = class_list.size() - 1;i >= 0;i--) { if (class_list[i]->is_py_class() == false) delete class_list[i]; else { class_list[i]->delete_class(); break; } } class_list.clear(); } } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::delete_devices // // description : // Call destructor for all objects registered in the server // //------------------------------------------------------------------------------------------------------------------ void DServer::delete_devices() { if (class_list.empty() == false) { for (long i = class_list.size() - 1;i >= 0;i--) { if (class_list[i]->is_py_class() == false) { Tango::Util *tg = Tango::Util::instance(); PortableServer::POA_ptr r_poa = tg->get_poa(); unsigned long loop; vector &devs = class_list[i]->get_device_list(); unsigned long nb_dev = devs.size(); for (loop = 0;loop < nb_dev;loop++) { // // Clear vectors used to memorize info used to clean db in case of devices with dyn attr removed during device // destruction // tg->get_polled_dyn_attr_names().clear(); tg->get_full_polled_att_list().clear(); tg->get_all_dyn_attr_names().clear(); tg->get_dyn_att_dev_name().clear(); // // Delete device // class_list[i]->delete_dev(0,tg,r_poa); // // Clean-up db (dyn attribute and dyn command) // if (tg->get_polled_dyn_attr_names().size() != 0) tg->clean_attr_polled_prop(); if (tg->get_all_dyn_attr_names().size() != 0) tg->clean_dyn_attr_prop(); if (tg->get_polled_dyn_cmd_names().size() != 0) tg->clean_cmd_polled_prop(); // // Wait for POA to destroy the object before going to the next one. Limit this waiting time to 200 mS // vector::iterator it = devs.begin(); devs.erase(it); } devs.clear(); CORBA::release(r_poa); delete class_list[i]; class_list.pop_back(); } else { class_list[i]->delete_class(); break; } } class_list.clear(); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::add_class() // // description : // To add a new class to the class list vector // // args : // out : // - class_ptr : pointer to DeviceClass object // //------------------------------------------------------------------------------------------------------------------ void DServer::add_class(DeviceClass *class_ptr) { class_list.push_back(class_ptr); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::query_class() // // description : // command to read all the classes used in a device server process // // returns : // The class name list in a strings sequence // //----------------------------------------------------------------------------------------------------------------- Tango::DevVarStringArray *DServer::query_class() { NoSyncModelTangoMonitor sync(this); cout4 << "In query_class command" << endl; long nb_class = class_list.size(); Tango::DevVarStringArray *ret = NULL; try { ret = new Tango::DevVarStringArray(nb_class); ret->length(nb_class); for (int i = 0;i < nb_class;i++) { (*ret)[i] = class_list[i]->get_name().c_str(); } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DServer::query_class"); } return(ret); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::query_device() // // description : // command to read all the devices implemented by a device server process // // returns : // The device name list in a strings sequence // //------------------------------------------------------------------------------------------------------------------ Tango::DevVarStringArray *DServer::query_device() { NoSyncModelTangoMonitor mon(this); cout4 << "In query_device command" << endl; long nb_class = class_list.size(); Tango::DevVarStringArray *ret = NULL; vector vs; try { ret = new Tango::DevVarStringArray(DefaultMaxSeq); for (int i = 0;i < nb_class;i++) { long nb_dev = class_list[i]->get_device_list().size(); string &class_name = class_list[i]->get_name(); for (long j = 0;j < nb_dev;j++) { vs.push_back(class_name + "::" + (class_list[i]->get_device_list())[j]->get_name()); } } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DServer::query_device"); } int nb_dev = vs.size(); ret->length(nb_dev); for (int k = 0;k < nb_dev;k++) (*ret)[k] = CORBA::string_dup(vs[k].c_str()); return(ret); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::query_sub_device() // // description : // command to read all the sub devices used by a device server process // // returns : // The sub device name list in a sequence of strings // //------------------------------------------------------------------------------------------------------------------ Tango::DevVarStringArray *DServer::query_sub_device() { NoSyncModelTangoMonitor mon(this); cout4 << "In query_sub_device command" << endl; Tango::DevVarStringArray *ret; Tango::Util *tg = Tango::Util::instance(); ret = tg->get_sub_dev_diag().get_sub_devices(); return(ret); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::restart() // // description : // command to restart a device // // args : // in : // - d_name : The device name to be re-started // //----------------------------------------------------------------------------------------------------------------- void DServer::restart(string &d_name) { NoSyncModelTangoMonitor mon(this); cout4 << "In restart method" << endl; // // Change device name to lower case letters and remove extra field in name in case of (#dbase=xxx or protocol specif) // Check if the wanted device exists in each class // bool found = false; unsigned int nb_class = class_list.size(); unsigned long i; string lower_d_name(d_name); transform(lower_d_name.begin(),lower_d_name.end(),lower_d_name.begin(),::tolower); string::size_type pos; if ((pos = lower_d_name.find('#')) != string::npos) lower_d_name.erase(pos); if ((pos = lower_d_name.find("://")) != string::npos) { pos = pos + 3; if ((pos = lower_d_name.find('/',pos)) != string::npos) lower_d_name.erase(0,pos + 1); } vector::iterator ite,ite_end; for (i = 0;i < nb_class;i++) { vector &dev_list = class_list[i]->get_device_list(); ite_end = dev_list.end(); for (ite = dev_list.begin();ite != dev_list.end();++ite) { if ((*ite)->get_name_lower() == lower_d_name) { found = true; break; } } if (found == true) break; } // // Throw exception if the device is not found // if ((i == nb_class) && (ite == ite_end)) { cout3 << "Device " << d_name << " not found in server !" << endl; TangoSys_OMemStream o; o << "Device " << d_name << " not found" << ends; Except::throw_exception((const char *)API_DeviceNotFound, o.str(), (const char *)"Dserver::restart()"); } DeviceImpl *dev_to_del = *ite; // // Memorize device interface if some client(s) are listening on device interface change event // DevIntr di; bool ev_client = false; if (dev_to_del->get_dev_idl_version() >= MIN_IDL_DEV_INTR) { ZmqEventSupplier *event_supplier_zmq = Tango_nullptr; event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); if (event_supplier_zmq != Tango_nullptr) ev_client = event_supplier_zmq->any_dev_intr_client(dev_to_del); if (ev_client == true) di.get_interface(dev_to_del); } // // If the device is locked and if the client is not the lock owner, refuse to do the job // check_lock_owner(dev_to_del,"restart",d_name.c_str()); // // clean the sub-device list for this device // Tango::Util *tg = Tango::Util::instance(); tg->get_sub_dev_diag().remove_sub_devices (dev_to_del->get_name()); tg->get_sub_dev_diag().set_associated_device(dev_to_del->get_name()); // // Remove ourself from device list // class_list[i]->get_device_list().erase(ite); // // Get device name, class pointer, polled object list and event parameters // DeviceClass *dev_cl = dev_to_del->get_device_class(); Tango::DevVarStringArray name(1); name.length(1); name[0] = lower_d_name.c_str(); vector &p_obj = dev_to_del->get_poll_obj_list(); vector dev_pol; vector eve; for (i = 0;i < p_obj.size();i++) { Pol tmp; tmp.type = p_obj[i]->get_type(); tmp.upd = p_obj[i]->get_upd(); tmp.name = p_obj[i]->get_name(); dev_pol.push_back(tmp); } dev_to_del->get_device_attr()->get_event_param(eve); dev_to_del->get_event_param(eve); // // Also get device locker parameters if device locked // client_addr *cl_addr = NULL; client_addr *old_cl_addr = NULL; time_t l_date = 0; DevLong l_ctr = 0,l_valid = 0; if (dev_to_del->is_device_locked() == true) { cl_addr = dev_to_del->get_locker(); old_cl_addr = dev_to_del->get_old_locker(); l_date = dev_to_del->get_locking_date(); l_ctr = dev_to_del->get_locking_ctr(); l_valid = dev_to_del->get_lock_validity(); dev_to_del->clean_locker_ptrs(); } // // If the device was polled, stop polling // if (dev_pol.empty() == false) { dev_to_del->stop_polling(false); } // // Delete the device (deactivate it and remove it) // try { tg->add_restarting_device(lower_d_name); PortableServer::POA_ptr r_poa = tg->get_poa(); bool py_device = dev_to_del->is_py_device(); if (py_device == true) { AutoPyLock PyLo; Device_3Impl *dev_to_del_3 = static_cast(dev_to_del); dev_to_del_3->delete_dev(); } if (dev_to_del->get_exported_flag() == true) r_poa->deactivate_object(dev_to_del->get_obj_id().in()); CORBA::release(r_poa); // // Re-create device. Take the monitor in case of class or process serialisation model // dev_cl->set_device_factory_done(false); { AutoTangoMonitor sync(dev_cl); AutoPyLock PyLo; dev_cl->device_factory(&name); } dev_cl->set_device_factory_done(true); tg->delete_restarting_device(lower_d_name); } catch (Tango::DevFailed &e) { tg->delete_restarting_device(lower_d_name); stringstream ss; ss << "init_device() method for device " << d_name << " throws DevFailed exception."; ss << "\nDevice not available any more. Please fix exception reason"; Tango::Except::re_throw_exception(e,API_InitThrowsException,ss.str(),"Dserver::restart()"); } catch (...) { tg->delete_restarting_device(lower_d_name); stringstream ss; ss << "init_device() method for device " << d_name << " throws an unknown exception."; ss << "\nDevice not available any more. Please fix exception reason"; Tango::Except::throw_exception(API_InitThrowsException,ss.str(),"Dserver::restart()"); } // // Apply memorized values for memorized attributes (if any) // dev_cl->set_memorized_values(false,dev_cl->get_device_list().size() - 1); // // Unlock the device (locked by export_device for memorized attribute) // vector &dev_list = dev_cl->get_device_list(); DeviceImpl *last_dev = dev_list.back(); last_dev->get_dev_monitor().rel_monitor(); // // Re-start device polling (if any) // DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); for (i = 0;i < dev_pol.size();i++) { // // Send command to the polling thread // send->lvalue[0] = dev_pol[i].upd; send->svalue[0] = CORBA::string_dup(name[0]); if (dev_pol[i].type == Tango::POLL_CMD) send->svalue[1] = CORBA::string_dup("command"); else send->svalue[1] = CORBA::string_dup("attribute"); send->svalue[2] = CORBA::string_dup(dev_pol[i].name.c_str()); try { add_obj_polling(send,false); } catch (Tango::DevFailed &e) { if (Tango::Util::_tracelevel >= 4) Except::print_exception(e); } } delete send; // // Find the new device // DeviceImpl *new_dev = NULL; vector &d_list = dev_cl->get_device_list(); for (i = 0;i < d_list.size();i++) { if (d_list[i]->get_name() == lower_d_name) { new_dev = d_list[i]; break; } } if (i == d_list.size()) { cout3 << "Not able to find the new device" << endl; TangoSys_OMemStream o; o << "Not able to find the new device" << ends; Except::throw_exception((const char *)API_DeviceNotFound, o.str(), (const char *)"Dserver::restart()"); } // // Re-set classical event parameters (if needed) // Tango::MultiAttribute *m_attr = new_dev->get_device_attr(); m_attr->set_event_param(eve); new_dev->set_event_param(eve); // // Re-set multicast event parameters // vector m_cast; vector &att_list = new_dev->get_device_attr()->get_attribute_list(); for (unsigned int j = 0;j < att_list.size();++j) { mcast_event_for_att(new_dev->get_name_lower(),att_list[j]->get_name_lower(),m_cast); if (m_cast.empty() == false) att_list[j]->set_mcast_event(m_cast); } // // Re-set device pointer in the RootAttRegistry (if needed) // RootAttRegistry &rar = tg->get_root_att_reg(); rar.update_device_impl(lower_d_name,new_dev); // // Re-lock device if necessary // if (cl_addr != NULL) new_dev->set_locking_param(cl_addr,old_cl_addr,l_date,l_ctr,l_valid); // // Fire device interface change event if needed // if (ev_client == true) { if (di.has_changed(new_dev) == true) { cout4 << "Device interface has changed !!!!!!!!!!!!!!!!!!!" << endl; Device_5Impl *dev_5 = static_cast(new_dev); DevCmdInfoList_2 *cmds_list = dev_5->command_list_query_2(); DevVarStringArray dvsa(1); dvsa.length(1); dvsa[0] = Tango::string_dup(AllAttr_3); AttributeConfigList_5 *atts_list = dev_5->get_attribute_config_5(dvsa); ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); event_supplier_zmq->push_dev_intr_change_event(new_dev,false,cmds_list,atts_list); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::restart_server() // // description : // command to restart a server (all devices embedded within the server) // //------------------------------------------------------------------------------------------------------------------ void DServer::restart_server() { NoSyncModelTangoMonitor mon(this); // // Create the thread and start it // ServRestartThread *t = new ServRestartThread(this); t->start(); } void ServRestartThread::run(void *ptr) { PyData *py_data_ptr = new PyData(); omni_thread::self()->set_value(key_py_data,py_data_ptr); // // The arg. passed to this method is a pointer to the DServer device // DServer *dev = (DServer *)ptr; // // clean the sub-device list for the server // Tango::Util *tg = Tango::Util::instance(); tg->get_sub_dev_diag().remove_sub_devices(); // // Change the POA manager to discarding state. This is necessary to discard all request arriving while the server // restart. // PortableServer::POA_var poa = Util::instance()->get_poa(); PortableServer::POAManager_var manager = poa->the_POAManager(); manager->discard_requests(true); // // Setup logging // #ifdef TANGO_HAS_LOG4TANGO dev->init_logger(); #endif // // Reset initial state and status // dev->set_state(Tango::ON); dev->set_status("The device is ON"); // // Memorize event parameters and devices interface // map > map_events; map map_dev_inter; dev->mem_event_par(map_events); dev->mem_devices_interface(map_dev_inter); // // Destroy and recreate the multi attribute object // MultiAttribute *tmp_ptr; try { tmp_ptr = new MultiAttribute(dev->get_name(),dev->get_device_class(),dev); } catch (Tango::DevFailed &) { throw; } delete dev->get_device_attr(); dev->set_device_attr(tmp_ptr); dev->add_state_status_attrs(); // // Restart device(s) // Before set 2 values to retrieve correct polling threads pool size // tg->set_polling_threads_pool_size(ULONG_MAX); dev->set_poll_th_pool_size(DEFAULT_POLLING_THREADS_POOL_SIZE); tg->set_svr_starting(true); { AutoPyLock PyLo; dev->init_device(); } tg->set_svr_starting(false); // // Restart polling (if any) // tg->polling_configure(); // // Reset event params and send event(s) if some device interface has changed // dev->apply_event_par(map_events); dev->changed_devices_interface(map_dev_inter); // // Exit thread // omni_thread::self()->remove_value(key_py_data); delete py_data_ptr; omni_thread::exit(); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::query_class_prop() // // description : // command to return the list of property device at class level for the specified class // //------------------------------------------------------------------------------------------------------------------- Tango::DevVarStringArray *DServer::query_class_prop(string &class_name) { NoSyncModelTangoMonitor sync(this); cout4 << "In query_class_prop command" << endl; long nb_class = class_list.size(); Tango::DevVarStringArray *ret = NULL; // // Find the wanted class in server and throw exception if not found // transform(class_name.begin(),class_name.end(),class_name.begin(),::tolower); int k; for (k = 0;k < nb_class;k++) { string tmp_name(class_list[k]->get_name()); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == class_name) break; } if (k == nb_class) { TangoSys_OMemStream o; o << "Class " << class_name << " not found in device server" << ends; Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::query_class_prop"); } // // Retrieve class prop vector and returns its content in a DevVarStringArray // vector &wiz = class_list[k]->get_wiz_class_prop(); long nb_prop = wiz.size(); try { ret = new Tango::DevVarStringArray(nb_prop); ret->length(nb_prop); for (int i = 0;i < nb_prop;i++) { (*ret)[i] = CORBA::string_dup(wiz[i].c_str()); } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DServer::query_class_prop"); } return(ret); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::query_dev_prop() // // description : // command to return the list of property device at device level for the specified class // //------------------------------------------------------------------------------------------------------------------ Tango::DevVarStringArray *DServer::query_dev_prop(string &class_name) { NoSyncModelTangoMonitor sync(this); cout4 << "In query_dev_prop command" << endl; long nb_class = class_list.size(); Tango::DevVarStringArray *ret = NULL; // // Find the wanted class in server and throw exception if not found // transform(class_name.begin(),class_name.end(),class_name.begin(),::tolower); int k; for (k = 0;k < nb_class;k++) { string tmp_name(class_list[k]->get_name()); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == class_name) break; } if (k == nb_class) { TangoSys_OMemStream o; o << "Class " << class_name << " not found in device server" << ends; Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::query_dev_prop"); } // // Retrieve device prop vector and returns its content in a DevVarStringArray // vector &wiz = class_list[k]->get_wiz_dev_prop(); long nb_prop = wiz.size(); try { ret = new Tango::DevVarStringArray(nb_prop); ret->length(nb_prop); for (int i = 0;i < nb_prop;i++) { (*ret)[i] = CORBA::string_dup(wiz[i].c_str()); } } catch (bad_alloc &) { Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DServer::query_dev_prop"); } return(ret); } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::kill() // // description : // command to kill the device server process. This is done by starting a thread which will kill the process. // Starting a thread allows the client to receive something from the server before it is killed // //----------------------------------------------------------------------------------------------------------------- void DServer::kill() { NoSyncModelTangoMonitor mon(this); cout4 << "In kill command" << endl; // // Create the thread and start it // KillThread *t = new KillThread; t->start(); } void *KillThread::run_undetached(TANGO_UNUSED(void *ptr)) { cout4 << "In the killer thread !!!" << endl; omni_thread::self()->set_value(key_py_data,new PyData()); // // Shutdown the server // Tango::Util *tg = Tango::Util::instance(); tg->shutdown_ds(); return NULL; } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::create_cpp_class() // // description : // Create a Cpp Tango class from its name // //------------------------------------------------------------------------------------------------------------------ void DServer::create_cpp_class(const char *cl_name,const char *par_name) { cout4 << "In DServer::create_cpp_class for " << cl_name << ", " << par_name << endl; string class_name(cl_name); string lib_name = class_name; #ifdef _TG_WINDOWS_ HMODULE mod; if ((mod = LoadLibrary(lib_name.c_str())) == NULL) { char *str = 0; DWORD l_err = GetLastError(); ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL, l_err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(char *)&str,0,NULL); cerr << "Error: " << str << endl; TangoSys_OMemStream o; o << "Trying to load shared library " << lib_name << " failed. It returns error: " << str << ends; ::LocalFree((HLOCAL)str); Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::create_cpp_class"); } cout4 << "GetModuleHandle is a success" << endl; string sym_name("_create_"); sym_name = sym_name + class_name; sym_name = sym_name + "_class"; cout4 << "Symbol name = " << sym_name << endl; FARPROC proc; if ((proc = GetProcAddress(mod,sym_name.c_str())) == NULL) { TangoSys_OMemStream o; o << "Class " << cl_name << " does not have the C creator function (_create__class)" << ends; Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::create_cpp_class"); } cout4 << "GetProcAddress is a success" << endl; Cpp_creator_ptr mt = (Cpp_creator_ptr)proc; #else void *lib_ptr; lib_name = lib_name + ".so"; lib_ptr = dlopen(lib_name.c_str(),RTLD_NOW); if (lib_ptr == NULL) { TangoSys_OMemStream o; o << "Trying to load shared library " << lib_name << " failed. It returns error: " << dlerror() << ends; Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::create_cpp_class"); } cout4 << "dlopen is a success" << endl; void *sym; string sym_name("_create_"); sym_name = sym_name + class_name; sym_name = sym_name + "_class"; cout4 << "Symbol name = " << sym_name << endl; sym = dlsym(lib_ptr,sym_name.c_str()); if (sym == NULL) { TangoSys_OMemStream o; o << "Class " << cl_name << " does not have the C creator function (_create__class)" << ends; Except::throw_exception((const char *)API_ClassNotFound,o.str(), (const char *)"DServer::create_cpp_class"); } cout4 << "dlsym is a success" << endl; Cpp_creator_ptr mt = (Cpp_creator_ptr)sym; #endif /* _TG_WINDOWS_ */ Tango::DeviceClass *dc = (*mt)(par_name); add_class(dc); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::get_dev_prop() // // description : // Retrieve device properties // // args : // in : // - tg : Tango Util object ptr // //------------------------------------------------------------------------------------------------------------------ void DServer::get_dev_prop(Tango::Util *tg) { polling_bef_9_def = false; // // Try to retrieve device properties (Polling threads pool conf.) // if (tg->_UseDb == true) { DbData db_data; db_data.push_back(DbDatum("polling_threads_pool_size")); db_data.push_back(DbDatum("polling_threads_pool_conf")); db_data.push_back(DbDatum("polling_before_9")); try { db_dev->get_property(db_data); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "Database error while trying to retrieve device properties for device " << device_name.c_str() << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"DServer::get_dev_prop"); } // // If the prop is not defined in db and if the user has defined it in the Util class, takes the user definition // if (db_data[0].is_empty() == false) db_data[0] >> polling_th_pool_size; else { unsigned long p_size = tg->get_polling_threads_pool_size(); if (p_size != ULONG_MAX) polling_th_pool_size = p_size; } if (db_data[1].is_empty() == false) { vector tmp_vect; db_data[1] >> tmp_vect; // // If the polling threads pool conf. has been splitted due to the max device property length of 255 chars, // rebuild a real pool conf // string rebuilt_str; bool ended = true; vector::iterator iter; polling_th_pool_conf.clear(); for (iter = tmp_vect.begin();iter != tmp_vect.end();++iter) { string tmp_str = (*iter); if (tmp_str[tmp_str.size() - 1] == '\\') { tmp_str.resize(tmp_str.size() - 1); ended = false; } else ended = true; rebuilt_str = rebuilt_str + tmp_str; if (ended == true) { polling_th_pool_conf.push_back(rebuilt_str); rebuilt_str.clear(); } } } else polling_th_pool_conf.clear(); // // Polling before 9 algorithm property // if (db_data[2].is_empty() == false) { polling_bef_9_def = true; db_data[2] >> polling_bef_9; } else polling_bef_9_def = false; } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::check_lock_owner() // // description : // Check in case the device is locked if the client is the lock owner // // args : // in : // - dev : The device // - cmd_name : The DServer device command name // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------ void DServer::check_lock_owner(DeviceImpl *dev,const char *cmd_name,const char *dev_name) { if (dev->is_device_locked() == true) { if (dev->valid_lock() == true) { client_addr *cl = get_client_ident(); if (cl->client_ident == true) { if (*cl != *(dev->get_locker())) { TangoSys_OMemStream o,v; o << "Device " << dev_name << " is locked by another client."; o << " Your request is not allowed while a device is locked." << ends; v << "DServer::" << cmd_name << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(),v.str()); } } else { TangoSys_OMemStream o,v; o << "Device " << dev_name << " is locked by another client."; o << " Your request is not allowed while a device is locked." << ends; v << "DServer::" << cmd_name << ends; Except::throw_exception((const char *)API_DeviceLocked,o.str(),v.str()); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::get_event_misc_prop() // // description : // Get the properties defining which event has to be transported using multicast protocol. Also retrieve // property for Nan allowed in writing attribute // // args : // in : // - tg : Tango Util instance pointer // //------------------------------------------------------------------------------------------------------------------ void DServer::get_event_misc_prop(Tango::Util *tg) { if (tg->_UseDb == true) { // // Get property // DbData db_data; db_data.push_back(DbDatum("MulticastEvent")); db_data.push_back(DbDatum("MulticastHops")); db_data.push_back(DbDatum("MulticastRate")); db_data.push_back(DbDatum("MulticastIvl")); db_data.push_back(DbDatum("DSEventBufferHwm")); db_data.push_back(DbDatum("EventBufferHwm")); db_data.push_back(DbDatum("WAttrNaNAllowed")); try { tg->get_database()->get_property(CONTROL_SYSTEM,db_data,tg->get_db_cache()); mcast_event_prop.clear(); db_data[0] >> mcast_event_prop; // // Check property coherency // vector::size_type nb_elt = mcast_event_prop.size(); bool uncoherent = false; for (unsigned int i = 0;i < nb_elt;++i) { if (is_ip_address(mcast_event_prop[i]) == true) { // // Check multicast address validity // string start_ip_mcast = mcast_event_prop[i].substr(0,mcast_event_prop[i].find('.')); istringstream ss(start_ip_mcast); int ip_start; ss >> ip_start; if ((ip_start < 224) || (ip_start > 239)) uncoherent = true; else { // // Check property definition // if (nb_elt < i + 3) uncoherent = true; else { if (nb_elt > i + 4) { if ((is_event_name(mcast_event_prop[i + 2]) == false) && (is_event_name(mcast_event_prop[i + 3]) == false) && (is_event_name(mcast_event_prop[i + 4]) == false)) uncoherent = true; } else if (nb_elt > i + 3) { if ((is_event_name(mcast_event_prop[i + 2]) == false) && (is_event_name(mcast_event_prop[i + 3]) == false)) uncoherent = true; } else { if (is_event_name(mcast_event_prop[i + 2]) == false) uncoherent = true; } } } // // If the property is uncoherent, clear it but inform user. No event will use multicasting in this case // if (uncoherent == true) { cerr << "Database CtrlSystem/MulticastEvent property is uncoherent" << endl; cerr << "Prop syntax = mcast ip adr (must be between 224.x.y.z and 239.x.y.z) - port - [rate] - [ivl] - event name" << endl; cerr << "All events will use unicast communication" << endl; mcast_event_prop.clear(); break; } else i = i + 1; } } // // All values in lower case letters // for (unsigned int i = 0;i < nb_elt;i++) { transform(mcast_event_prop[i].begin(),mcast_event_prop[i].end(),mcast_event_prop[i].begin(),::tolower); } // // Multicast Hops // mcast_hops = MCAST_HOPS; if (db_data[1].is_empty() == false) db_data[1] >> mcast_hops; // // Multicast PGM rate // mcast_rate = PGM_RATE; if (db_data[2].is_empty() == false) { db_data[2] >> mcast_rate; mcast_rate = mcast_rate * 1024; } // // Multicast IVL // mcast_ivl = PGM_IVL; if (db_data[3].is_empty() == false) { db_data[3] >> mcast_ivl; mcast_ivl = mcast_ivl * 1000; } // // Publisher Hwm // zmq_pub_event_hwm = PUB_HWM; if (db_data[4].is_empty() == false) db_data[4] >> zmq_pub_event_hwm; // // Subscriber Hwm // zmq_sub_event_hwm = SUB_HWM; if (db_data[5].is_empty() == false) db_data[5] >> zmq_sub_event_hwm; // // Nan allowed in writing attribute // if (db_data[6].is_empty() == false) { bool new_val; db_data[6] >> new_val; tg->set_wattr_nan_allowed(new_val); } } catch (Tango::DevFailed &) { cerr << "Database error while trying to retrieve multicast event property" << endl; cerr << "All events will use unicast communication" << endl; } } else { mcast_event_prop.clear(); zmq_pub_event_hwm = PUB_HWM; zmq_sub_event_hwm = SUB_HWM; } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::mcast_event_for_att() // // description : // Return in m_event vector, list of mcast event for the specified device/attribute. // For each event, the returned string in the vector follows the syntax // event_name:ip_adr:port:rate:ivl // The last two are optionals. Please note that the same dev/att may have several event using multicasting // // args : // in : // - dev_name : The device name // - att_name : The attribute name // out : // - m_event : The multicast event definition // //------------------------------------------------------------------------------------------------------------------ void DServer::mcast_event_for_att(string &dev_name,string &att_name,vector &m_event) { m_event.clear(); string full_att_name = dev_name + '/' + att_name; vector::size_type nb_elt = mcast_event_prop.size(); unsigned int ip_adr_ind = 0; for (unsigned int i = 0;i < nb_elt;++i) { if (is_ip_address(mcast_event_prop[i]) == true) { ip_adr_ind = i; continue; } if (is_event_name(mcast_event_prop[i]) == true) { if (mcast_event_prop[i].find(full_att_name) == 0) { string::size_type pos = mcast_event_prop[i].rfind('.'); string tmp = mcast_event_prop[i].substr(pos + 1); tmp = tmp + ':' + mcast_event_prop[ip_adr_ind] + ':' + mcast_event_prop[ip_adr_ind + 1]; if (is_event_name(mcast_event_prop[ip_adr_ind + 2]) == false) { tmp = tmp + ':' + mcast_event_prop[ip_adr_ind + 2]; if (is_event_name(mcast_event_prop[ip_adr_ind + 3]) == false) tmp = tmp + ':' + mcast_event_prop[ip_adr_ind + 3]; } m_event.push_back(tmp); } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::mem_event_par() // // description : // Store event parameters for all class/devices in a DS. This is necessary in case of command RestartServer // // args : // out : // - _map : The map where these info are stored // //------------------------------------------------------------------------------------------------------------------ void DServer::mem_event_par(map > &_map) { for (size_t i = 0;i < class_list.size();i++) { vector &dev_list = class_list[i]->get_device_list(); for (size_t j = 0;j < dev_list.size();j++) { vector eve; dev_list[j]->get_device_attr()->get_event_param(eve); dev_list[j]->get_event_param(eve); if (eve.size() != 0) { _map.insert(make_pair(dev_list[j]->get_name(),eve)); } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::apply_event_par() // // description : // Apply event parameters for all class/devices in a DS. This is necessary in case of command RestartServer // // args : // in : // - _map : The map where these info are stored // //------------------------------------------------------------------------------------------------------------------ void DServer::apply_event_par(map > &_map) { for (size_t i = 0;i < class_list.size();i++) { vector &dev_list = class_list[i]->get_device_list(); for (size_t j = 0;j < dev_list.size();j++) { string &dev_name = dev_list[j]->get_name(); map >::iterator ite; ite = _map.find(dev_name); if (ite != _map.end()) { dev_list[j]->get_device_attr()->set_event_param(ite->second); dev_list[j]->set_event_param(ite->second); } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::mem_devices_interface() // // description : // Memorize device interface for devices where some client(s) are listening on device interface change // event // // arguments : // out : // - _map : reference to the map (name,device interface) where the interface must be stored // //------------------------------------------------------------------------------------------------------------------ void DServer::mem_devices_interface(map &_map) { ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); if (class_list.empty() == false) { for (long i = class_list.size() - 1;i >= 0;i--) { if (class_list[i]->is_py_class() == false) { vector &devs = class_list[i]->get_device_list(); size_t nb_dev = devs.size(); for (size_t loop = 0;loop < nb_dev;loop++) { if (event_supplier_zmq->any_dev_intr_client(devs[loop]) == true && devs[loop]->get_dev_idl_version() >= MIN_IDL_DEV_INTR) { cout4 << "Memorize dev interface for device " << devs[loop]->get_name() << endl; DevIntr di; di.get_interface(devs[loop]); _map.insert(make_pair(devs[loop]->get_name(),di)); } } } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::changed_devices_interface() // // description : // Check for each device with client(s) listening on device interface change event if the device interface // has changed and if true, send event // // arguments : // in : // - _map : reference to the map (name,device interface) where devices interface are stored // //------------------------------------------------------------------------------------------------------------------ void DServer::changed_devices_interface(map &_map) { Tango::Util *tg = Util::instance(); ZmqEventSupplier *event_supplier_zmq = tg->get_zmq_event_supplier(); map::iterator pos; for (pos = _map.begin();pos != _map.end();++pos) { DeviceImpl *dev = tg->get_device_by_name(pos->first); if (pos->second.has_changed(dev) == true) { cout4 << "Device interface for device " << dev->get_name() << " has changed !!!!!!!!!!!!!!!!!!!" << endl; Device_5Impl *dev_5 = static_cast(dev); DevCmdInfoList_2 *cmds_list = dev_5->command_list_query_2(); DevVarStringArray dvsa(1); dvsa.length(1); dvsa[0] = Tango::string_dup(AllAttr_3); AttributeConfigList_5 *atts_list = dev_5->get_attribute_config_5(dvsa); event_supplier_zmq->push_dev_intr_change_event(dev,false,cmds_list,atts_list); } } } }// End of Tango namespace tango-9.2.5a/lib/cpp/server/dserverclass.cpp0000644023471100065110000014452613034745002016002 00000000000000static const char *RcsId = "$Id: dserverclass.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+============================================================================= // // file : DServerClass.cpp // // description : C++ source for the DServerClass and for the // command class defined for this class. The singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the DServer once per process. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef TANGO_HAS_LOG4TANGO #include #endif #include namespace Tango { //+------------------------------------------------------------------------- // // method : DevRestartCmd::DevRestartCmd // // description : constructors for Command class Restart // //-------------------------------------------------------------------------- DevRestartCmd::DevRestartCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+------------------------------------------------------------------------- // // method : DevRestartCmd::execute // // description : restart a device // //-------------------------------------------------------------------------- CORBA::Any *DevRestartCmd::execute(DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "DevRestart::execute(): arrived " << endl; // // Extract the input string // const char *tmp_name; if ((in_any >>= tmp_name) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : string", (const char *)"DevRestartCmd::execute"); } string d_name(tmp_name); cout4 << "Received string = " << d_name << endl; // // call DServer method which implements this command // (static_cast(device))->restart(d_name); // // return to the caller // CORBA::Any *ret = return_empty_any("DevRestartCmd"); return ret; } //+---------------------------------------------------------------------------- // // method : DevRestartServerCmd::DevRestartServerCmd() // // description : constructor for the DevRestartServerCmd command of the // DServer. // //----------------------------------------------------------------------------- DevRestartServerCmd::DevRestartServerCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out):Command(name,in,out) { } //+---------------------------------------------------------------------------- // // method : DevRestartServerCmd::execute(string &s) // // description : method to trigger the execution of the DevRestartServer // command // //----------------------------------------------------------------------------- CORBA::Any *DevRestartServerCmd::execute(DeviceImpl *device,TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevRestartServerCmd::execute(): arrived" << endl; // // call DServer method which implements this command // (static_cast(device))->restart_server(); // // return to the caller // CORBA::Any *ret = return_empty_any("DevRestartServerCmd"); return ret; } //+---------------------------------------------------------------------------- // // method : DevQueryClassCmd::DevQueryClassCmd() // // description : constructor for the DevQueryClass command of the // DServer. // //----------------------------------------------------------------------------- DevQueryClassCmd::DevQueryClassCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevQueryClassCmd::execute(string &s) // // description : method to trigger the execution of the "QueryClass" // command // //----------------------------------------------------------------------------- CORBA::Any *DevQueryClassCmd::execute(DeviceImpl *device,TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevQueryClassCmd::execute(): arrived" << endl; // // call DServer method which implements this command // Tango::DevVarStringArray *ret = (static_cast(device))->query_class(); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in DevQueryClassCmd::execute()" << endl; delete ret; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevQueryClassCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving DevQueryClassCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : DevQueryDeviceCmd::DevQueryDeviceCmd() // // description : constructor for the DevQueryDevice command of the // DServer. // //----------------------------------------------------------------------------- DevQueryDeviceCmd::DevQueryDeviceCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevQueryDeviceCmd::execute(string &s) // // description : method to trigger the execution of the "QueryDevice" // command // //----------------------------------------------------------------------------- CORBA::Any *DevQueryDeviceCmd::execute(DeviceImpl *device,TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevQueryDeviceCmd::execute(): arrived" << endl; // // call DServer method which implements this command // Tango::DevVarStringArray *ret = (static_cast(device))->query_device(); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in DevQueryDeviceCmd::execute()" << endl; delete ret; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevQueryDeviceCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving DevQueryDeviceCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : DevQuerySubDeviceCmd::DevQuerySubDeviceCmd() // // description : constructor for the DevQuerySubDevice command of the // DServer. // //----------------------------------------------------------------------------- DevQuerySubDeviceCmd::DevQuerySubDeviceCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevQuerySubDeviceCmd::execute(string &s) // // description : method to trigger the execution of the "QuerySubDevice" // command // //----------------------------------------------------------------------------- CORBA::Any *DevQuerySubDeviceCmd::execute(DeviceImpl *device,TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevQuerySubDeviceCmd::execute(): arrived" << endl; // // call DServer method which implements this command // Tango::DevVarStringArray *ret = (static_cast(device))->query_sub_device(); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in DevQuerySubDeviceCmd::execute()" << endl; delete ret; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevQuerySubDeviceCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving DevQuerySubDeviceCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : DevKillCmd::DevKillCmd() // // description : constructor for the DevKill command of the // DServer. // //----------------------------------------------------------------------------- DevKillCmd::DevKillCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out):Command(name,in,out) { } //+---------------------------------------------------------------------------- // // method : DevKillCmd::execute(string &s) // // description : method to trigger the execution of the "Kill" // command // //----------------------------------------------------------------------------- CORBA::Any *DevKillCmd::execute(DeviceImpl *device,TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevKillCmd::execute(): arrived" << endl; // // call DServer method which implements this command // (static_cast(device))->kill(); // // return to the caller // CORBA::Any *ret = return_empty_any("DevKillCmd"); return ret; } //+---------------------------------------------------------------------------- // // method : DevSetTraceLevelCmd::DevSetTraceLevelCmd() // // description : constructor for the DevSetTraceLevel command of the // DServer. // //----------------------------------------------------------------------------- DevSetTraceLevelCmd::DevSetTraceLevelCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+---------------------------------------------------------------------------- // // method : DevSetTraceLevelCmd::execute(string &s) // // description : method to trigger the execution of the "SetTraceLevel" // command // //----------------------------------------------------------------------------- CORBA::Any *DevSetTraceLevelCmd::execute(TANGO_UNUSED(DeviceImpl *device),TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevSetTraceLevelCmd::execute(): arrived" << endl; #ifdef TANGO_HAS_LOG4TANGO Except::throw_exception((const char *)API_DeprecatedCommand, (const char *)"SetTraceLevel is no more supported, please use SetLoggingLevel", (const char *)"DevSetTraceLevelCmd::execute"); // // Make the compiler happy // CORBA::Any *ret = return_empty_any("DevSetTraceLevelCmd"); return ret; #else // TANGO_HAS_LOG4TANGO // // Get new level // int new_level; if ((in_any >>= new_level) == false) { cout3 << "DevSetTraceLevelCmd::execute() --> Wrong argument type" << endl; Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : long", (const char *)"DevSetTraceLevelCmd::execute"); } // // Set new level // Tango::Util::instance()->set_trace_level(new_level); // // Return to the caller // CORBA::Any *ret = return_empty_any("DevSetTraceLevelCmd"); return ret; #endif } //+---------------------------------------------------------------------------- // // method : DevGetTraceLevelCmd::DevGetTraceLevelCmd() // // description : constructor for the DevGetTraceLevel command of the // DServer. // //----------------------------------------------------------------------------- DevGetTraceLevelCmd::DevGetTraceLevelCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevGetTraceLevelCmd::execute(string &s) // // description : method to trigger the execution of the "DevGetTraceLevel" // command // //----------------------------------------------------------------------------- CORBA::Any *DevGetTraceLevelCmd::execute(TANGO_UNUSED(DeviceImpl *device),TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevGetTraceLevelCmd::execute(): arrived" << endl; #ifdef TANGO_HAS_LOG4TANGO Except::throw_exception((const char *)API_DeprecatedCommand, (const char *)"GetTraceLevel is no more supported, please use GetLoggingLevel", (const char *)"DevGetTraceLevelCmd::execute"); // // Make the compiler happy // CORBA::Any *ret = return_empty_any("DevGetTraceLevelCmd"); return ret; #else // TANGO_HAS_LOG4TANGO // // Get level // int level = Tango::Util::instance()->get_trace_level(); // // return data to the caller // CORBA::Any *out_any = new CORBA::Any(); (*out_any) <<= level; cout4 << "Leaving DevGetTraceLevelCmd::execute()" << endl; return(out_any); #endif } //+---------------------------------------------------------------------------- // // method : DevGetTraceOutputCmd::DevGetTraceOutputCmd() // // description : constructor for the DevGetTraceoutput command of the // DServer. // //----------------------------------------------------------------------------- DevGetTraceOutputCmd::DevGetTraceOutputCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevGetTraceOutputCmd::execute(string &s) // // description : method to trigger the execution of the "DevGetTraceOutput" // command // //----------------------------------------------------------------------------- CORBA::Any *DevGetTraceOutputCmd::execute(TANGO_UNUSED(DeviceImpl *device),TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevGetTraceOutputCmd::execute(): arrived" << endl; #ifdef TANGO_HAS_LOG4TANGO Except::throw_exception((const char *)API_DeprecatedCommand, (const char *)"GetTraceOutput is no more supported, please use GetLoggingTarget", (const char *)"DevGetTraceOutputCmd::execute"); // // Make the compiler happy // CORBA::Any *ret = return_empty_any("DevGetTraceOutputCmd"); return ret; #else // // Get Trace output // string st = Tango::Util::instance()->get_trace_output(); // // return data to the caller // CORBA::Any *out_any = new CORBA::Any(); (*out_any) <<= st.c_str(); cout4 << "Leaving DevGetTraceOutputCmd::execute()" << endl; return(out_any); #endif } //+---------------------------------------------------------------------------- // // method : DevSetTraceOutputCmd::DevSetTraceOutputCmd() // // description : constructor for the DevSetTraceoutput command of the // DServer. // //----------------------------------------------------------------------------- DevSetTraceOutputCmd::DevSetTraceOutputCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+---------------------------------------------------------------------------- // // method : DevSetTraceOutputCmd::execute(string &s) // // description : method to trigger the execution of the "Kill" // command // //----------------------------------------------------------------------------- CORBA::Any *DevSetTraceOutputCmd::execute(TANGO_UNUSED(DeviceImpl *device),TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "DevSetTraceOutputCmd::execute(): arrived" << endl; #ifdef TANGO_HAS_LOG4TANGO Except::throw_exception((const char *)API_DeprecatedCommand, (const char *)"SetTraceOutput is no more supported, please use AddLoggingTarget", (const char *)"DevSetTraceOutputCmd::execute"); // // Make the compiler happy // CORBA::Any *ret = return_empty_any("DevSetTraceOutputCmd"); return ret; #else // // Extract the input string and try to create a output file stream from it // const char *in_file_ptr; if ((in_any >>= in_file_ptr) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : string", (const char *)"DevSetTraceOutputCmd::execute"); } string in_file(in_file_ptr); cout4 << "Received string = " << in_file << endl; if (in_file == InitialOutput) { delete(Tango::Util::instance()->get_trace_output_stream()); Tango::Util::instance()->set_trace_output_stream((ofstream *)NULL); ostream &tmp_stream = Tango::Util::instance()->get_out(); // // For windows, the stdc++ library also implements the new IOstreams where the // xx_with_assign classes do not exist. To copy stream, I have used the advice // from the C++ report of June 1997 // cout.copyfmt(tmp_stream); cout.clear(tmp_stream.rdstate()); cout.rdbuf(tmp_stream.rdbuf()); Tango::Util::instance()->set_trace_output(in_file); } else { ofstream *ofp = new ofstream(in_file_ptr); if (ofp->good()) { cout.copyfmt(*ofp); cout.clear(ofp->rdstate()); cout.rdbuf(ofp->rdbuf()); delete(Tango::Util::instance()->get_trace_output_stream()); Tango::Util::instance()->set_trace_output(in_file); Tango::Util::instance()->set_trace_output_stream(ofp); } else { cout3 << "Cannot open ofstream" << endl; TangoSys_OMemStream o; o << "Impossible to open file " << in_file << ends; Except::throw_exception((const char *)API_CannotOpenFile, o.str(), (const char *)"DevSetTraceoutput::execute"); } } // // return to the caller // CORBA::Any *ret = return_empty_any("DevSetTraceOutputCmd"); return ret; #endif } //+---------------------------------------------------------------------------- // // method : QueryWizardClassPropertyCmd::QueryWizardClassPropertyCmd // // description : constructor for the QueryWizardClassProperty command of the // DServer. // //----------------------------------------------------------------------------- QueryWizardClassPropertyCmd::QueryWizardClassPropertyCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc):Command(name,in,out) { set_in_type_desc(in_desc); set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : QueryWizardClassPropertyCmd::execute(string &s) // // description : method to trigger the execution of the "QueryWizardClassProperty" // command // //----------------------------------------------------------------------------- CORBA::Any *QueryWizardClassPropertyCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "QueryWizardClassPropertyCmd::execute(): arrived" << endl; // // Extract the input string // const char *tmp_name; if ((in_any >>= tmp_name) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : string", (const char *)"QueryWizardClassPropertyCmd::execute"); } string class_name(tmp_name); // // call DServer method which implements this command // Tango::DevVarStringArray *ret = (static_cast(device))->query_class_prop(class_name); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in QueryWizardClassPropertyCmd::execute()" << endl; delete ret; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"QueryWizardClassPropertyCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving QueryWizardClassPropertyCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : QueryWizardDevPropertyCmd::QueryWizardDevPropertyCmd // // description : constructor for the QueryWizardDevProperty command of the // DServer. // //----------------------------------------------------------------------------- QueryWizardDevPropertyCmd::QueryWizardDevPropertyCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc):Command(name,in,out) { set_in_type_desc(in_desc); set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : QueryWizardDevPropertyCmd::execute() // // description : method to trigger the execution of the "QueryWizardDevProperty" // command // //----------------------------------------------------------------------------- CORBA::Any *QueryWizardDevPropertyCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "QueryWizardDevPropertyCmd::execute(): arrived" << endl; // // Extract the input string // const char *tmp_name; if ((in_any >>= tmp_name) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : string", (const char *)"QueryWizardDevPropertyCmd::execute"); } string class_name(tmp_name); // // call DServer method which implements this command // Tango::DevVarStringArray *ret = (static_cast(device))->query_dev_prop(class_name); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in QueryWizardDevPropertyCmd::execute()" << endl; delete ret; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"QueryWizardDevPropertyCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving QueryWizardDevPropertyCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : QueryEventChannelIORCmd::QueryEventChannelIORCmd // // description : constructor for the QueryEventChannelIOR command of the // DServer. // //----------------------------------------------------------------------------- QueryEventChannelIORCmd::QueryEventChannelIORCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : QueryEventChannelIORCmd::execute() // // description : method to trigger the execution of the "QueryEventChannelIOR" // command // //----------------------------------------------------------------------------- CORBA::Any *QueryEventChannelIORCmd::execute(TANGO_UNUSED(DeviceImpl *device),TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "QueryEventChannelIORCmd::execute(): arrived" << endl; // // Get DS event channel IOR which is stored in the EventSupplier object // CORBA::Any *out_any = NULL; NotifdEventSupplier *nd_event_supplier; nd_event_supplier = Util::instance()->get_notifd_event_supplier(); if (nd_event_supplier == NULL) { cout3 << "Try to retrieve DS event channel while NotifdEventSupplier object is not yet created" << endl; Except::throw_exception((const char *)API_EventSupplierNotConstructed, (const char *)"Try to retrieve DS event channel while EventSupplier object is not created", (const char *)"QueryEventChannelIORCmd::execute"); } else { string &ior = nd_event_supplier->get_event_channel_ior(); // // return data to the caller // try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in QueryEventChannelIORCmd::execute()" << endl; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"QueryEventChannelIORCmd::execute"); } (*out_any) <<= ior.c_str(); } cout4 << "Leaving QueryEventChannelIORCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : LockDeviceCmd::LockDeviceCmd // // description : constructor for the LockDevice command of the DServer. // //----------------------------------------------------------------------------- LockDeviceCmd::LockDeviceCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+---------------------------------------------------------------------------- // // method : LockDeviceCmd::execute() // // description : method to trigger the execution of the "LockDevice" command // //----------------------------------------------------------------------------- CORBA::Any *LockDeviceCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "LockDeviceCmd::execute(): arrived" << endl; // // Extract the input argument // const Tango::DevVarLongStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // (static_cast(device))->lock_device(in_data); // // return data to the caller // CORBA::Any *ret = return_empty_any("LockDeviceCmd"); return ret; } //+---------------------------------------------------------------------------- // // method : ReLockDevicesCmd::ReLockDeviceCmd // // description : constructor for the ReLockDevices command of the DServer. // //----------------------------------------------------------------------------- ReLockDevicesCmd::ReLockDevicesCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+---------------------------------------------------------------------------- // // method : ReLockDevicesCmd::execute() // // description : method to trigger the execution of the "ReLockDevices" command // //----------------------------------------------------------------------------- CORBA::Any *ReLockDevicesCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "ReLockDevicesCmd::execute(): arrived" << endl; // // Extract the input argument // const Tango::DevVarStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // (static_cast(device))->re_lock_devices(in_data); // // return data to the caller // CORBA::Any *ret = return_empty_any("ReLockDevicesCmd"); return ret; } //+---------------------------------------------------------------------------- // // method : UnLockDeviceCmd::UnLockDeviceCmd // // description : constructor for the UnLockDevice command of the DServer. // //----------------------------------------------------------------------------- UnLockDeviceCmd::UnLockDeviceCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc):Command(name,in,out) { set_in_type_desc(in_desc); set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : UnLockDeviceCmd::execute() // // description : method to trigger the execution of the "UnLockDevice" command // //----------------------------------------------------------------------------- CORBA::Any *UnLockDeviceCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "UnLockDeviceCmd::execute(): arrived" << endl; // // Extract the input string // const Tango::DevVarLongStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // Tango::DevLong ret = (static_cast(device))->un_lock_device(in_data); // // return data to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in UnLockDeviceCmd::execute()" << endl; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"UnLockDeviceCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving UnLockDeviceCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : DevLockStatusCmd::DevLockStatusCmd // // description : constructor for the DevLockStatus command of the DServer. // //----------------------------------------------------------------------------- DevLockStatusCmd::DevLockStatusCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc):Command(name,in,out) { set_in_type_desc(in_desc); set_out_type_desc(out_desc); } //+---------------------------------------------------------------------------- // // method : DevLockStatusCmd::execute() // // description : method to trigger the execution of the "DevLockStatus" command // //----------------------------------------------------------------------------- CORBA::Any *DevLockStatusCmd::execute(DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "DevLockStatusCmd::execute(): arrived" << endl; // // Extract the input string // Tango::ConstDevString in_data; extract(in_any,in_data); // // call DServer method which implements this command // Tango::DevVarLongStringArray *ret = (static_cast(device))->dev_lock_status(in_data); // // return to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in DevLockStatusCmd::execute()" << endl; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"DevLockStatusCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving DevLockStatusCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : EventSubscriptionChangeCmd::EventSubscriptionChangeCmd() // // description : constructor for the command of the EventTester. // // In : - name : The command name // - in : The input parameter type // - out : The output parameter type // - in_desc : The input parameter description // - out_desc : The output parameter description // //----------------------------------------------------------------------------- EventSubscriptionChangeCmd::EventSubscriptionChangeCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc) :Command(name,in,out,in_desc,out_desc) { } // // Constructor without in/out parameters description // EventSubscriptionChangeCmd::EventSubscriptionChangeCmd(const char *name,Tango::CmdArgType in,Tango::CmdArgType out) :Command(name,in,out) { } //+---------------------------------------------------------------------------- // // method : EventSubscriptionChangeCmd::is_allowed() // // description : method to test whether command is allowed or not in this // state. In this case, the command is allowed only if // the device is in ON state // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : boolean - true == is allowed , false == not allowed // //----------------------------------------------------------------------------- bool EventSubscriptionChangeCmd::is_allowed(TANGO_UNUSED(Tango::DeviceImpl *device), TANGO_UNUSED(const CORBA::Any &in_any)) { // End of Generated Code // Re-Start of Generated Code return true; } //+---------------------------------------------------------------------------- // // method : EventSubscriptionChangeCmd::execute() // // description : method to trigger the execution of the command. // PLEASE DO NOT MODIFY this method core without pogo // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : The command output data (packed in the Any object) // //----------------------------------------------------------------------------- CORBA::Any *EventSubscriptionChangeCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "EventSubscriptionChangeCmd::execute(): arrived" << endl; // // Extract the input string array // const Tango::DevVarStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // Tango::DevLong ret = (static_cast(device))->event_subscription_change(in_data); // // return to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in EventSubscriptionChangeCmd::execute()" << endl; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"EventSubscriptionChangeCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving EventSubscriptionChangeCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : ZmqEventSubscriptionChangeCmd::EventSubscriptionChangeCmd() // // description : constructor for the command of the . // // In : - name : The command name // - in : The input parameter type // - out : The output parameter type // - in_desc : The input parameter description // - out_desc : The output parameter description // //----------------------------------------------------------------------------- ZmqEventSubscriptionChangeCmd::ZmqEventSubscriptionChangeCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc) :Command(name,in,out,in_desc,out_desc) { } // // Constructor without in/out parameters description // ZmqEventSubscriptionChangeCmd::ZmqEventSubscriptionChangeCmd(const char *name,Tango::CmdArgType in,Tango::CmdArgType out) :Command(name,in,out) { } //+---------------------------------------------------------------------------- // // method : ZmqEventSubscriptionChangeCmd::is_allowed() // // description : method to test whether command is allowed or not in this // state. In this case, the command is allowed only if // the device is in ON state // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : boolean - true == is allowed , false == not allowed // //----------------------------------------------------------------------------- bool ZmqEventSubscriptionChangeCmd::is_allowed(TANGO_UNUSED(Tango::DeviceImpl *device), TANGO_UNUSED(const CORBA::Any &in_any)) { // End of Generated Code // Re-Start of Generated Code return true; } //+---------------------------------------------------------------------------- // // method : ZmqEventSubscriptionChangeCmd::execute() // // description : method to trigger the execution of the command. // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : The command output data (packed in the Any object) // //----------------------------------------------------------------------------- CORBA::Any *ZmqEventSubscriptionChangeCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "ZmqEventSubscriptionChangeCmd::execute(): arrived" << endl; // // Extract the input string array // const Tango::DevVarStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // Tango::DevVarLongStringArray *ret = (static_cast(device))->zmq_event_subscription_change(in_data); // // return to the caller // CORBA::Any *out_any = NULL; try { out_any = new CORBA::Any(); } catch (bad_alloc &) { cout3 << "Bad allocation while in ZmqEventSubscriptionChangeCmd::execute()" << endl; Except::throw_exception((const char *)API_MemoryAllocation, (const char *)"Can't allocate memory in server", (const char *)"ZmqEventSubscriptionChangeCmd::execute"); } (*out_any) <<= ret; cout4 << "Leaving ZmqEventSubscriptionChangeCmd::execute()" << endl; return(out_any); } //+---------------------------------------------------------------------------- // // method : EventConfirmSubscriptionCmd::EventSubscriptionChangeCmd() // // description : constructor for the command of the . // // In : - name : The command name // - in : The input parameter type // - out : The output parameter type // - in_desc : The input parameter description // - out_desc : The output parameter description // //----------------------------------------------------------------------------- EventConfirmSubscriptionCmd::EventConfirmSubscriptionCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc) :Command(name,in,out) { set_in_type_desc(in_desc); } // // Constructor without in/out parameters description // EventConfirmSubscriptionCmd::EventConfirmSubscriptionCmd(const char *name,Tango::CmdArgType in,Tango::CmdArgType out) :Command(name,in,out) { } //+---------------------------------------------------------------------------- // // method : EventConfirmSubscriptionCmd::is_allowed() // // description : method to test whether command is allowed or not in this // state. In this case, the command is allowed only if // the device is in ON state // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : boolean - true == is allowed , false == not allowed // //----------------------------------------------------------------------------- bool EventConfirmSubscriptionCmd::is_allowed(TANGO_UNUSED(Tango::DeviceImpl *device), TANGO_UNUSED(const CORBA::Any &in_any)) { // End of Generated Code // Re-Start of Generated Code return true; } //+---------------------------------------------------------------------------- // // method : EventConfirmSubscriptionCmd::execute() // // description : method to trigger the execution of the command. // // in : - device : The device on which the command must be excuted // - in_any : The command input data // // returns : The command output data (packed in the Any object) // //----------------------------------------------------------------------------- CORBA::Any *EventConfirmSubscriptionCmd::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any) { cout4 << "EventConfirmSubscriptionCmd::execute(): arrived" << endl; // // Extract the input string array // const Tango::DevVarStringArray *in_data; extract(in_any,in_data); // // call DServer method which implements this command // (static_cast(device))->event_confirm_subscription(in_data); // // return data to the caller // CORBA::Any *ret = return_empty_any("EventConfirmSubscriptionCmd"); return ret; } DServerClass *DServerClass::_instance = NULL; //+---------------------------------------------------------------------------- // // method : DServerClass::DServerClass() // // description : constructor for the DServerClass class // The constructor add specific class commands to the // command list, create a device of the DServer class // retrieve all classes which must be created within the // server and finally, creates these classes // // argument : in : - s : The class name // //----------------------------------------------------------------------------- bool less_than_dserver (Command *a,Command *b) { if (a->get_name() < b->get_name()) return true; else return false; } DServerClass::DServerClass(string &s):DeviceClass(s) { try { // // Add class command(s) to the command_list // command_factory(); // // Sort commands // sort(get_command_list().begin(),get_command_list().end(),less_than_dserver); // // Create device name from device server name // string dev_name(DSDeviceDomain); dev_name.append(1,'/'); dev_name.append(Tango::Util::instance()->get_ds_exec_name()); dev_name.append(1,'/'); dev_name.append(Tango::Util::instance()->get_ds_inst_name()); Tango::DevVarStringArray dev_list(1); dev_list.length(1); dev_list[0] = dev_name.c_str(); // // Create the device server device // device_factory(&dev_list); } catch (bad_alloc &) { for (unsigned long i = 0;i < command_list.size();i++) delete command_list[i]; command_list.clear(); if (device_list.empty() == false) { for (unsigned long i = 0;i < device_list.size();i++) delete device_list[i]; device_list.clear(); } cerr << "Can't allocate memory while building the DServerClass object" << endl; throw; } } //+---------------------------------------------------------------------------- // // method : DServerClass::Instance // // description : Create the object if not already done. Otherwise, just // return a pointer to the object // //----------------------------------------------------------------------------- DServerClass *DServerClass::instance() { if (_instance == NULL) { cerr << "Class DServer is not initialised!" << endl; Except::throw_exception((const char *)API_DServerClassNotInitialised, (const char *)"The DServerClass is not yet initialised, please wait!", (const char *)"DServerClass::instance"); //exit(-1); } return _instance; } DServerClass *DServerClass::init() { if (_instance == NULL) { try { string s("DServer"); _instance = new DServerClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //+---------------------------------------------------------------------------- // // method : DServerClass::command_factory // // description : Create the command object(s) and store them in the // command list // //----------------------------------------------------------------------------- void DServerClass::command_factory() { command_list.push_back(new DevRestartCmd("DevRestart", Tango::DEV_STRING, Tango::DEV_VOID, "Device name")); command_list.push_back(new DevRestartServerCmd("RestartServer", Tango::DEV_VOID, Tango::DEV_VOID)); command_list.push_back(new DevQueryClassCmd("QueryClass", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "Device server class(es) list")); command_list.push_back(new DevQueryDeviceCmd("QueryDevice", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "Device server device(s) list")); command_list.push_back(new DevQuerySubDeviceCmd("QuerySubDevice", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "Device server sub device(s) list")); command_list.push_back(new DevKillCmd("Kill", Tango::DEV_VOID, Tango::DEV_VOID)); // // Now, commands related to polling // command_list.push_back(new PolledDeviceCmd("PolledDevice", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "Polled device name list")); command_list.push_back(new DevPollStatusCmd("DevPollStatus", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Device name", "Device polling status")); string msg("Lg[0]=Upd period."); msg = msg + (" Str[0]=Device name"); msg = msg + (". Str[1]=Object type"); msg = msg + (". Str[2]=Object name"); command_list.push_back(new AddObjPollingCmd("AddObjPolling", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEV_VOID, msg)); command_list.push_back(new UpdObjPollingPeriodCmd("UpdObjPollingPeriod", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEV_VOID, msg)); msg = "Str[0]=Device name. Str[1]=Object type. Str[2]=Object name"; command_list.push_back(new RemObjPollingCmd("RemObjPolling", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, msg)); command_list.push_back(new StopPollingCmd("StopPolling", Tango::DEV_VOID, Tango::DEV_VOID)); command_list.push_back(new StartPollingCmd("StartPolling", Tango::DEV_VOID, Tango::DEV_VOID)); #ifdef TANGO_HAS_LOG4TANGO msg = "Str[i]=Device-name. Str[i+1]=Target-type::Target-name"; command_list.push_back(new AddLoggingTarget("AddLoggingTarget", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, msg)); command_list.push_back(new RemoveLoggingTarget("RemoveLoggingTarget", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, msg)); command_list.push_back(new GetLoggingTarget("GetLoggingTarget", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, std::string("Device name"), std::string("Logging target list"))); command_list.push_back(new SetLoggingLevel("SetLoggingLevel", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEV_VOID, std::string("Lg[i]=Logging Level. Str[i]=Device name."))); command_list.push_back(new GetLoggingLevel("GetLoggingLevel", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_LONGSTRINGARRAY, std::string("Device list"), std::string("Lg[i]=Logging Level. Str[i]=Device name."))); command_list.push_back(new StopLogging("StopLogging", Tango::DEV_VOID, Tango::DEV_VOID)); command_list.push_back(new StartLogging("StartLogging", Tango::DEV_VOID, Tango::DEV_VOID)); #else command_list.push_back(new DevSetTraceLevelCmd("SetTraceLevel", Tango::DEV_LONG, Tango::DEV_VOID, "New trace level")); command_list.push_back(new DevGetTraceLevelCmd("GetTraceLevel", Tango::DEV_VOID, Tango::DEV_LONG, "Device server trace level")); command_list.push_back(new DevSetTraceOutputCmd("SetTraceOutput", Tango::DEV_STRING, Tango::DEV_VOID, "New device server output file")); command_list.push_back(new DevGetTraceOutputCmd("GetTraceOutput", Tango::DEV_VOID, Tango::DEV_STRING, "Device server output file")); #endif // TANGO_HAS_LOG4TANGO command_list.push_back(new EventSubscriptionChangeCmd("EventSubscriptionChange", Tango::DEVVAR_STRINGARRAY, Tango::DEV_LONG, "Event consumer wants to subscribe to", "Tango lib release")); command_list.push_back(new ZmqEventSubscriptionChangeCmd("ZmqEventSubscriptionChange", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_LONGSTRINGARRAY, "Events consumer wants to subscribe to", "Str[0] = Heartbeat pub endpoint - Str[1] = Event pub endpoint\nLg[0] = Tango lib release - Lg[1] = Device IDL release\nLg[2] = Subscriber HWM - Lg[3] = Multicast rate\nLg[4] = Multicast IVL - Lg[5] = ZMQ release")); command_list.push_back(new EventConfirmSubscriptionCmd("EventConfirmSubscription", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = dev1 name, Str[1] = att1 name, Str[2] = event name, Str[3] = dev2 name, Str[4] = att2 name, Str[5] = event name,...")); command_list.push_back(new QueryWizardClassPropertyCmd("QueryWizardClassProperty", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Class name", "Class property list (name - description and default value)")); command_list.push_back(new QueryWizardDevPropertyCmd("QueryWizardDevProperty", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Class name", "Device property list (name - description and default value)")); // // Locking device commands // command_list.push_back(new LockDeviceCmd("LockDevice", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name. Lg[0] = Lock validity")); command_list.push_back(new UnLockDeviceCmd("UnLockDevice", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEV_LONG, "Str[x] = Device name(s). Lg[0] = Force flag", "Device global lock counter")); command_list.push_back(new ReLockDevicesCmd("ReLockDevices", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Device(s) name")); command_list.push_back(new DevLockStatusCmd("DevLockStatus", Tango::DEV_STRING, Tango::DEVVAR_LONGSTRINGARRAY, "Device name", "Device locking status")); if (Util::_FileDb == true) { command_list.push_back(new QueryEventChannelIORCmd("QueryEventChannelIOR", Tango::DEV_VOID, Tango::DEV_STRING, "Device server event channel IOR")); } } //+---------------------------------------------------------------------------- // // method : DServerClass::device_factory // // description : Create the device object(s) and store them in the // device list // // in : Tango::DevVarStringArray *devlist_ptr : // The device name list // //----------------------------------------------------------------------------- void DServerClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { Tango::Util *tg = Tango::Util::instance(); for (unsigned long i = 0;i < devlist_ptr->length();i++) { cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; // // Create device and add it into the device list // device_list.push_back(new DServer(this, (*devlist_ptr)[i], "A device server device !!", Tango::ON, "The device is ON")); // // Export device to the outside world // if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) export_device(device_list.back()); else export_device(device_list.back(),(*devlist_ptr)[i]); // // After the export of the admin device, the server is marked as started // and the database server connection timeout is set to the classical // timeout value (Except for db server itself) // Database *db = tg->get_database(); if ((db != NULL) && (Util::_FileDb == false)) db->set_timeout_millis(CLNT_TIMEOUT); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dserverlock.cpp0000644023471100065110000002152613034745001015616 00000000000000static const char *RcsId = "$Id: dserverlock.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : dserverlock.cpp // // description : C++ source for the DServer class and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on a // DServer object are implemented in this file. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include namespace Tango { //+---------------------------------------------------------------------------- // // method : DServer::lock_device() // // description : command to lock device // // args: - in_data : Pointer to a structure with: // 1 - Name of the device(s) to be locked // 2 - Lock validity // //----------------------------------------------------------------------------- void DServer::lock_device(const Tango::DevVarLongStringArray *in_data) { NoSyncModelTangoMonitor mon(this); string dev_name(in_data->svalue[0]); int lock_validity = in_data->lvalue[0]; cout4 << "In lock_device command for device " << dev_name << ", lock validity = " << lock_validity << endl; // // Get client identification // Tango::client_addr *cl = get_client_ident(); if (cl == NULL) { Except::throw_exception((const char*)API_CantGetClientIdent, (const char*)"Cannot retrieve client identification", (const char*)"DServer::lock_device"); } cout4 << "Client identification = " << *cl << endl; if (cl->client_ident == false) { Except::throw_exception((const char*)"API_ClientTooOld", (const char*)"Your client cannot lock devices. You are using a too old Tango release. Please, update to tango V7 or more", (const char*)"DServer::lock_device"); } // // Transform device name to lower case // Tango::Util *tg = Tango::Util::instance(); string local_dev_name(get_name()); transform(local_dev_name.begin(),local_dev_name.end(),local_dev_name.begin(),::tolower); string d_name_lower(dev_name); transform(d_name_lower.begin(),d_name_lower.end(),d_name_lower.begin(),::tolower); // // Refuse to lock the admin device // if (d_name_lower == local_dev_name) { Except::throw_exception((const char *)API_DeviceUnlockable, (const char *)"Impossible to lock device server administration device", (const char *)"DServer::lock_device"); } // // Get device ptr // DeviceImpl *the_dev; the_dev = tg->get_device_by_name(dev_name); // // Refuse to lock database device // string &cl_name = the_dev->get_device_class()->get_name(); if (::strcmp(cl_name.c_str(),DATABASE_CLASS) == 0) { Except::throw_exception((const char *)API_DeviceUnlockable, (const char *)"Impossible to lock database device", (const char *)"DServer::lock_device"); } // // Mark the device as locked // the_dev->lock(cl,lock_validity); } //+---------------------------------------------------------------------------- // // method : DServer::un_lock_device() // // description : command to un lock a device // // args: - dev_name : The device name // //----------------------------------------------------------------------------- Tango::DevLong DServer::un_lock_device(const Tango::DevVarLongStringArray *in_data) { NoSyncModelTangoMonitor mon(this); cout4 << "In un_lock_device command for device " << in_data->svalue[0] << endl; // // Get client identification // Tango::client_addr *cl = get_client_ident(); if (cl == NULL) { Except::throw_exception((const char*)API_CantGetClientIdent, (const char*)"Cannot retrieve client identification", (const char*)"DServer::un_lock_device"); } cout4 << "Client identification = " << *cl << endl; if ((cl->client_ident == false) && (in_data->lvalue[0] == 0)) { Except::throw_exception((const char*)"API_ClientTooOld", (const char*)"Your client cannot un-lock devices. You are using a too old Tango release. Please, update to tango V7 or more", (const char*)"DServer::un_lock_device"); } // // Get the device and unlock it // DevLong ctr = 0; Tango::Util *tg = Tango::Util::instance(); for (unsigned int loop = 0;loop < in_data->svalue.length();++loop) { string d_name(in_data->svalue[loop]); if (d_name == get_name()) ctr = lock_ctr; else { DeviceImpl *the_dev = tg->get_device_by_name(d_name); ctr = the_dev->unlock((bool)in_data->lvalue[0]); } if (loop > 0) ctr = 0; } return ctr; } //+---------------------------------------------------------------------------- // // method : DServer::re_lock_devices() // // description : command to re-lock devices // // args: - dev_name_list : Name of the device(s) to be re-locked // //----------------------------------------------------------------------------- void DServer::re_lock_devices(const Tango::DevVarStringArray *dev_name_list) { NoSyncModelTangoMonitor mon(this); cout4 << "In re_lock_devices command" << endl; CORBA::ULong loop; CORBA::ULong nb_dev = dev_name_list->length(); for (loop = 0;loop < nb_dev;loop++) cout4 << "Device to re-lock: " << (*dev_name_list)[loop] << endl; // // Get client identification // Tango::client_addr *cl = get_client_ident(); if (cl == NULL) { Except::throw_exception((const char*)API_CantGetClientIdent, (const char*)"Cannot retrieve client identification", (const char*)"DServer::re_lock_devices"); } cout4 << "Client identification = " << *cl << endl; if (cl->client_ident == false) { Except::throw_exception((const char*)"API_ClientTooOld", (const char*)"Your client cannot re_lock devices. You are using a too old Tango release. Please, update to tango V7 or more", (const char*)"DServer::re_lock_devices"); } // // ReLock the devices // If we have an error in this loop, memorize it and throw the exception at the // end of the loop // Tango::Util *tg = Tango::Util::instance(); DevErrorList errors; long nb_error = 0; for (loop = 0;loop < nb_dev;loop++) { string d_name((*dev_name_list)[loop]); // // Get device ptr // DeviceImpl *the_dev = NULL; try { the_dev = tg->get_device_by_name(d_name); } catch (Tango::DevFailed &e) { errors.length(nb_error + 1); errors[nb_error].desc = CORBA::string_dup(e.errors[0].desc.in()); errors[nb_error].reason = CORBA::string_dup(e.errors[0].reason.in()); errors[nb_error].origin = CORBA::string_dup(e.errors[0].origin.in()); errors[nb_error].severity = e.errors[0].severity; nb_error++; } // // ReLock the device // try { the_dev->relock(cl); } catch (Tango::DevFailed &e) { errors.length(nb_error + 1); errors[nb_error].desc = CORBA::string_dup(e.errors[0].desc.in()); errors[nb_error].reason = CORBA::string_dup(e.errors[0].reason.in()); errors[nb_error].origin = CORBA::string_dup(e.errors[0].origin.in()); errors[nb_error].severity = e.errors[0].severity; nb_error++; } } // // Throw the exception if we had one during the loop // if (nb_error != 0) { throw Tango::DevFailed(errors); } } //+---------------------------------------------------------------------------- // // method : DServer::dev_lock_status() // // description : command to get device lock status // // args: - dev_name : The device name // //----------------------------------------------------------------------------- Tango::DevVarLongStringArray *DServer::dev_lock_status(Tango::ConstDevString dev_name) { NoSyncModelTangoMonitor mon(this); cout4 << "In dev_lock_status command for device " << dev_name << endl; // // Get the device and get its lock status // string d_name(dev_name); Tango::Util *tg = Tango::Util::instance(); DeviceImpl *the_dev = tg->get_device_by_name(d_name); return the_dev->lock_status(); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dserverlog.cpp0000644023471100065110000001555313034745001015452 00000000000000static const char *RcsId = "$Id: dserverlog.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : DServerLog.cpp // // description : Implementation of the DServer logging oriented commands // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 3.7 2010/09/09 13:45:22 taurel // - Add year 2010 in Copyright notice // // Revision 3.6 2010/06/18 07:45:47 taurel // - In case of locked device, polling and logging related commands are // allowed only for the locker process // // Revision 3.5 2009/01/21 12:49:04 taurel // - Change CopyRights for 2009 // // Revision 3.4 2008/10/06 15:01:09 taurel // - Changed the licensing info from GPL to LGPL // // Revision 3.3 2008/10/03 06:52:31 taurel // - Add some licensing info in each files // // Revision 3.2 2003/05/28 14:55:09 taurel // Add the include (conditionally) of the include files generated by autoconf // // Revision 3.1 2003/05/16 08:46:16 taurel // Many changes for release 3.0.1. The most important ones are : // - Timeout are backs // - Multiple db servers (change in TANGO_HOST syntax) // - Added methods to print DeviceData, DeviceDataHistory, DeviceAttribute and DeviceAttributeHistory instances // - Attributes name stored in blackbox // - Remove check if a class is created without any device // - It's now possible to create a DeviceProxy from its alias name // - Command, attribute names are case insensitive // - Change parameters of some DeviceProxy logging methods // - Change parameters of DeviceProxy asynchronous replies calls // - New serialization model in device server (no serialization model) // - Win32 (2000) device server service does not exit at loggoff anymore // - Miscellaneous bug fixes // // Revision 3.0 2003/03/25 16:43:20 taurel // Many changes for Tango release 3.0 including // - Added full logging features // - Added asynchronous calls // - Host name of clients now stored in black-box // - Three serialization model in DS // - Fix miscellaneous bugs // - Ported to gcc 3.2 // - Added ApiUtil::cleanup() and destructor methods // - Some internal cleanups // - Change the way how TangoMonitor class is implemented. It's a recursive // mutex // // Revision 2.2 2003/03/11 17:55:53 nleclercq // Switch from log4cpp to log4tango // // Revision 2.1 2003/02/17 14:57:41 taurel // Added the new Tango logging stuff (Thanks Nicolas from Soleil) // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO namespace Tango { //+---------------------------------------------------------------------------- // // method : DServer::add_logging_target // //----------------------------------------------------------------------------- void DServer::add_logging_target (const Tango::DevVarStringArray *argin) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::add_logging_target" << endl; Logging::add_logging_target(argin); cout4 << "Leaving DServer::add_logging_target" << endl; } //+---------------------------------------------------------------------------- // // method : DServer::remove_logging_target // //----------------------------------------------------------------------------- void DServer::remove_logging_target (const Tango::DevVarStringArray *argin) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::remove_logging_target" << endl; Logging::remove_logging_target(argin); cout4 << "Leaving DServer::remove_logging_target" << endl; } //+---------------------------------------------------------------------------- // // method : DServer::get_logging_target // //----------------------------------------------------------------------------- Tango::DevVarStringArray* DServer::get_logging_target (const std::string& dev_name) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::get_logging_target" << endl; DevVarStringArray* res = Logging::get_logging_target(dev_name); cout4 << "Leaving DServer::get_logging_target" << endl; return res; } //+---------------------------------------------------------------------------- // // method : DServer::set_logging_level // //----------------------------------------------------------------------------- void DServer::set_logging_level (const Tango::DevVarLongStringArray *argin) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::set_logging_level" << endl; Logging::set_logging_level(argin); cout4 << "Leaving DServer::set_logging_level" << endl; } //+---------------------------------------------------------------------------- // // method : DServer::get_logging_level // //----------------------------------------------------------------------------- DevVarLongStringArray* DServer::get_logging_level (const DevVarStringArray *argin) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::get_logging_level" << endl; DevVarLongStringArray* res = Logging::get_logging_level(argin); cout4 << "Leaving DServer::get_logging_level" << endl; return res; } //+---------------------------------------------------------------------------- // // method : DServer::stop_logging // //----------------------------------------------------------------------------- void DServer::stop_logging (void) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::stop_logging" << endl; Logging::stop_logging(); cout4 << "Leaving DServer::stop_logging" << endl; } //+---------------------------------------------------------------------------- // // method : DServer::start_logging // //----------------------------------------------------------------------------- void DServer::start_logging (void) { NoSyncModelTangoMonitor mon(this); cout4 << "Entering DServer::start_logging" << endl; Logging::start_logging(); cout4 << "Leaving DServer::start_logging" << endl; } } // End of Tango namespace #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/dserverpoll.cpp0000644023471100065110000015371313034745001015640 00000000000000static const char *RcsId = "$Id: dserverpoll.cpp 29692 2016-04-29 06:16:37Z taurel $\n$Name$"; //+================================================================================================================== // // file : DServer.cpp // // description : C++ source for the DServer class and its commands. The class is derived from Device. It // represents the CORBA servant object which will be accessed from the network. // All commands which can be executed on a DServer object are implemented in this file. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29692 $ // //-================================================================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef _TG_WINDOWS_ #include #else #include #endif #include namespace Tango { //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::polled_device() // // description : // command to read all the devices actually polled by the device server // // retrun : // The device name list in a strings sequence // //----------------------------------------------------------------------------------------------------------------- Tango::DevVarStringArray *DServer::polled_device() { NoSyncModelTangoMonitor mon(this); cout4 << "In polled_device command" << endl; long nb_class = class_list.size(); vector dev_name; try { for (int i = 0;i < nb_class;i++) { long nb_dev = class_list[i]->get_device_list().size(); for (long j = 0;j < nb_dev;j++) { if ((class_list[i]->get_device_list())[j]->is_polled() == true) { dev_name.push_back((class_list[i]->get_device_list())[j]->get_name().c_str()); } } } } catch (bad_alloc &) { Except::throw_exception(API_MemoryAllocation,"Can't allocate memory in server","DServer::polled_device"); } // // Return an empty sequence if no devices are polled // if (dev_name.empty() == true) { Tango::DevVarStringArray *ret = new Tango::DevVarStringArray(); ret->length(0); return ret; } // // Returned device name list to caller (sorted) // sort(dev_name.begin(),dev_name.end()); long nb_dev = dev_name.size(); Tango::DevVarStringArray *ret = new Tango::DevVarStringArray(nb_dev); ret->length(nb_dev); for (long k = 0;k < nb_dev;k++) (*ret)[k] = dev_name[k].c_str(); return(ret); } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::dev_polled_status() // // description : // command to read device polling status // // args : // in : // - dev_name : The device name // // return : // The device polling status as a string (multiple lines) // //----------------------------------------------------------------------------------------------------------------- Tango::DevVarStringArray *DServer::dev_poll_status(string &dev_name) { NoSyncModelTangoMonitor mon(this); cout4 << "In dev_poll_status method" << endl; // // Find the device // Tango::Util *tg = Tango::Util::instance(); DeviceImpl *dev; dev = tg->get_device_by_name(dev_name); vector &poll_list = dev->get_poll_obj_list(); long nb_poll_obj = poll_list.size(); // // Return an empty sequence if nothing is polled for this device // if (nb_poll_obj == 0) { Tango::DevVarStringArray *ret; ret = new DevVarStringArray(); ret->length(0); return ret; } long i,nb_cmd,nb_attr; // // Compute how many cmds and/or attributes are polled. Since IDL V3, state and status are polled as attributes // For compatibility, if one of these "attributes" is polled, also returns the info as the command is polled // nb_cmd = nb_attr = 0; long nb_to_add = 0; for (i = 0;i < nb_poll_obj;i++) { if (poll_list[i]->get_type() == Tango::POLL_CMD) nb_cmd++; else { nb_attr++; if ((poll_list[i]->get_name() == "state") || (poll_list[i]->get_name() == "status")) { nb_cmd++; nb_to_add++; } } } // // Allocate memory for returned strings // Tango::DevVarStringArray *ret; ret = new DevVarStringArray(nb_poll_obj + nb_to_add); ret->length(nb_poll_obj + nb_to_add); // // Create map of polled attributes read by the same call // map > polled_together; bool poll_bef_9 = false; if (polling_bef_9_def == true) poll_bef_9 = polling_bef_9; else if (tg->is_polling_bef_9_def() == true) poll_bef_9 = tg->get_polling_bef_9(); if (poll_bef_9 == false) { for (i = 0;i < nb_poll_obj;i++) { if (poll_list[i]->get_type() == Tango::POLL_CMD) continue; else { long po = poll_list[i]->get_upd(); map >::iterator ite = polled_together.find(po); Attribute &att = dev->get_device_attr()->get_attr_by_name(poll_list[i]->get_name().c_str()); if (ite == polled_together.end()) { vector tmp_name; tmp_name.push_back(att.get_name()); polled_together.insert(pair >(po,tmp_name)); } else ite->second.push_back(att.get_name()); } } } // // Populate returned strings // long cmd_ind = 0; long attr_ind = nb_cmd; string returned_info; map *> root_dev_poll_status; for(i = 0;i < nb_poll_obj;i++) { bool duplicate = false; if (i == nb_poll_obj - 1) { #ifdef HAS_RANGE_BASE_FOR for (auto &elem:root_dev_poll_status) delete elem.second; #else map *>::iterator pos; for (pos = root_dev_poll_status.begin();pos != root_dev_poll_status.end();++pos) delete pos->second; #endif } // // First, the name // Tango::PollObjType type = poll_list[i]->get_type(); if (type == Tango::POLL_CMD) { returned_info = "Polled command name = "; long k; long nb_cmd = dev->get_device_class()->get_command_list().size(); for (k = 0;k < nb_cmd;k++) { if (dev->get_device_class()->get_command_list()[k]->get_lower_name() == poll_list[i]->get_name()) { returned_info = returned_info + dev->get_device_class()->get_command_list()[k]->get_name(); break; } } } else { returned_info = "Polled attribute name = "; if (poll_list[i]->get_name() == "state") { duplicate = true; returned_info = returned_info + "State"; } else if (poll_list[i]->get_name() == "status") { duplicate = true; returned_info = returned_info + "Status"; } else { Attribute &att = dev->get_device_attr()->get_attr_by_name(poll_list[i]->get_name().c_str()); returned_info = returned_info + att.get_name(); } } // // Add update period // stringstream s; string tmp_str; string per; long po = poll_list[i]->get_upd(); if (po == 0) { returned_info = returned_info + "\nPolling externally triggered"; } else { returned_info = returned_info + "\nPolling period (mS) = "; s << po; s >> tmp_str; returned_info = returned_info + tmp_str; s.clear(); // clear the stream eof flag } s.str(""); // clear the underlying string // // Add ring buffer depth // returned_info = returned_info + "\nPolling ring buffer depth = "; long depth = 0; if (type == Tango::POLL_CMD) depth = dev->get_cmd_poll_ring_depth(poll_list[i]->get_name()); else depth = dev->get_attr_poll_ring_depth(poll_list[i]->get_name()); s << depth; returned_info = returned_info + s.str(); s.str(""); // Clear the underlying string // // Add a message if the data ring is empty // if (poll_list[i]->is_ring_empty() == true) { returned_info = returned_info + "\nNo data recorded yet"; } else { // // Take polled object ownership in order to have coherent info returned to caller. We don't want the polling thread // to insert a new elt in polling ring while we are getting these data. Therefore, use the xxx_i methods // { omni_mutex_lock sync(*(poll_list[i])); // // Add needed time to execute last command // double tmp_db = poll_list[i]->get_needed_time_i(); if (tmp_db == 0.0) { returned_info = returned_info + "\nThe polling buffer is externally filled in"; } else { if (po != 0) { returned_info = returned_info + "\nTime needed for the last "; if (type == Tango::POLL_CMD) returned_info = returned_info + "command execution (mS) = "; else { map >::iterator ite = polled_together.find(po); if (ite != polled_together.end()) { if (ite->second.size() == 1) returned_info = returned_info + "attribute reading (mS) = "; else { returned_info = returned_info + "attributes ("; for (size_t loop = 0;loop < ite->second.size();loop++) { returned_info = returned_info + ite->second[loop]; if (loop <= ite->second.size() - 2) returned_info = returned_info + " + "; } returned_info = returned_info + ") reading (mS) = "; } } else returned_info = returned_info + "attribute reading(ms) = "; } s.setf(ios::fixed); s << setprecision(3) << tmp_db; returned_info = returned_info + s.str(); s.str(""); // // Add not updated since... info // returned_info = returned_info + "\nData not updated since "; double since = poll_list[i]->get_last_insert_date_i(); struct timeval now; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; double now_d = (double)now.tv_sec + ((double)now.tv_usec / 1000000); double diff_t = now_d - since; diff_t = diff_t - (tmp_db / 1000); if (diff_t < 1.0) { long nb_msec = (long)(diff_t * 1000); s << nb_msec; returned_info = returned_info + s.str() + " mS"; s.str(""); } else if (diff_t < 60.0) { long nb_sec = (long)diff_t; long nb_msec = (long)((diff_t - nb_sec) * 1000); s << nb_sec; returned_info = returned_info + s.str() + " S and "; s.str(""); s << nb_msec; returned_info = returned_info + s.str() + " mS"; s.str(""); } else { long nb_min = (long)(diff_t / 60); long nb_sec = (long)(diff_t - (60 * nb_min)); long nb_msec = (long)((diff_t - (long)diff_t) * 1000); s << nb_min; returned_info = returned_info + s.str() + " MN"; s.str(""); if (nb_sec != 0) { s << nb_sec ; returned_info = returned_info + " ," + s.str() + " S"; s.str(""); } if (nb_msec != 0) { s << nb_msec; returned_info = returned_info + " and " + s.str() + " mS"; s.str(""); } } } } // // Add delta_t between last record(s) // try { vector delta; poll_list[i]->get_delta_t_i(delta,4); returned_info = returned_info + "\nDelta between last records (in mS) = "; for (unsigned long j = 0;j < delta.size();j++) { long nb_msec = (long)(delta[j] * 1000); s << nb_msec; returned_info = returned_info + s.str(); s.str(""); if (j != (delta.size() - 1)) returned_info = returned_info + ", "; } } catch (Tango::DevFailed &) { } // // Add last polling exception fields (if any) // long dev_vers; bool last_err; dev_vers = dev->get_dev_idl_version(); if (dev_vers < 3) last_err = poll_list[i]->is_last_an_error_i(); else last_err = poll_list[i]->is_last_an_error_i_3(); if (last_err == true) { if (type == Tango::POLL_CMD) returned_info = returned_info + "\nLast command execution FAILED :"; else returned_info = returned_info + "\nLast attribute read FAILED :"; Tango::DevFailed *exe_ptr = poll_list[i]->get_last_except_i(); returned_info = returned_info + "\n\tReason = " + exe_ptr->errors[0].reason.in(); returned_info = returned_info + "\n\tDesc = " + exe_ptr->errors[0].desc.in(); returned_info = returned_info + "\n\tOrigin = " + exe_ptr->errors[0].origin.in(); } // // Release polled object monitor (only a compiler block end) // } } // // Init. string in sequence // if (type == Tango::POLL_CMD) { (*ret)[cmd_ind] = CORBA::string_dup(returned_info.c_str()); cmd_ind++; } else { (*ret)[attr_ind] = CORBA::string_dup(returned_info.c_str()); attr_ind++; // // If the attribute is state or status, also add the string in command list after replacing all occurences of // "attributes" by "command" in the returned string // if (duplicate == true) { string::size_type pos = returned_info.find("attribute"); while (pos != string::npos) { returned_info.replace(pos,9,"command"); string::size_type npos; npos = returned_info.find("attribute",pos); pos = npos; } (*ret)[cmd_ind] = CORBA::string_dup(returned_info.c_str()); cmd_ind++; } } } return(ret); } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::add_obj_polling() // // description : // command to add one object to be polled // // args : // in : // - argin : The polling parameters : // device name // object type (command or attribute) // object name // update period in mS (in the long array) // - with_db_upd : set to true if db has to be updated // - delta_ms : // //------------------------------------------------------------------------------------------------------------------- void DServer::add_obj_polling(const Tango::DevVarLongStringArray *argin,bool with_db_upd,int delta_ms) { NoSyncModelTangoMonitor nosyn_mon(this); cout4 << "In add_obj_polling method" << endl; unsigned long i; for (i = 0;i < argin->svalue.length();i++) cout4 << "Input string = " << (argin->svalue)[i].in() << endl; for (i = 0;i < argin->lvalue.length();i++) cout4 << "Input long = " << (argin->lvalue)[i] << endl; // // Check that parameters number is correct // if ((argin->svalue.length() != 3) || (argin->lvalue.length() != 1)) { Except::throw_exception(API_WrongNumberOfArgs, "Incorrect number of inout arguments", "DServer::add_obj_polling"); } // // Find the device // Tango::Util *tg = Tango::Util::instance(); DeviceImpl *dev = NULL; try { dev = tg->get_device_by_name((argin->svalue)[0]); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << (argin->svalue)[0] << " not found" << ends; Except::re_throw_exception(e,API_DeviceNotFound,o.str(),"DServer::add_obj_polling"); } // // If the device is locked and if the client is not the lock owner, refuse to do the job // check_lock_owner(dev,"add_obj_polling",(argin->svalue)[0]); // // Check that the command (or the attribute) exists. For command, also checks that it does not need input value. // string obj_type((argin->svalue)[1]); transform(obj_type.begin(),obj_type.end(),obj_type.begin(),::tolower); string obj_name((argin->svalue)[2]); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); PollObjType type = Tango::POLL_CMD; Attribute *attr_ptr; bool local_request = false; string::size_type pos = obj_type.rfind(LOCAL_POLL_REQUEST); if (pos == obj_type.size() - LOCAL_REQUEST_STR_SIZE) { local_request = true; obj_type.erase(pos); } if (obj_type == PollCommand) { dev->check_command_exists(obj_name); type = Tango::POLL_CMD; } else if (obj_type == PollAttribute) { Attribute &att = dev->get_device_attr()->get_attr_by_name((argin->svalue)[2]); attr_ptr = &att; type = Tango::POLL_ATTR; } else { TangoSys_OMemStream o; o << "Object type " << obj_type << " not supported" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::add_obj_polling"); } // // If it's for the Init command, refuse to poll it // if (obj_type == PollCommand) { if (obj_name == "init") { TangoSys_OMemStream o; o << "It's not possible to poll the Init command!" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::add_obj_polling"); } // // Since IDl release 3, state and status command must be polled as attributes to be able to generate event on state or // status. // else if ((dev->get_dev_idl_version() >= 3) && ((obj_name == "state") || (obj_name == "status"))) type = Tango::POLL_ATTR; } // // Check that the object is not already polled // vector &poll_list = dev->get_poll_obj_list(); for (i = 0;i < poll_list.size();i++) { if (poll_list[i]->get_type() == type) { string name_lower = poll_list[i]->get_name(); transform(name_lower.begin(),name_lower.end(),name_lower.begin(),::tolower); if (name_lower == obj_name) { TangoSys_OMemStream o; if (type == Tango::POLL_CMD) o << "Command "; else o << "Attribute "; o << obj_name << " already polled" << ends; Except::throw_exception(API_AlreadyPolled,o.str(),"DServer::add_obj_polling"); } } } // // Check that the update period is not to small // int upd = (argin->lvalue)[0]; if ((upd != 0) && (upd < MIN_POLL_PERIOD)) { TangoSys_OMemStream o; o << (argin->lvalue)[0] << " is below the min authorized period (" << MIN_POLL_PERIOD << " mS)" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::add_obj_polling"); } // // Check that the requested polling period is not below the one authorized (if defined) // 0 as polling period is always authorized for polling buffer externally filled // if (upd != 0) check_upd_authorized(dev,upd,type,obj_name); // // Refuse to do the job for forwarded attribute // if (obj_type == PollAttribute && attr_ptr->is_fwd_att() == true) { stringstream ss; ss << "Attribute " << obj_name << " is a forwarded attribute.\n"; ss << "It's not supported to poll a forwarded attribute.\n"; FwdAttribute *fwd = static_cast(attr_ptr); ss << "Polling has to be done on the root attribute ("; ss << fwd->get_fwd_dev_name() << "/" << fwd->get_fwd_att_name() << ")"; Except::throw_exception(API_NotSupportedFeature,ss.str(),"DServer::add_obj_polling"); } // // Create a new PollObj instance for this object. Protect this code by a monitor in case of the polling thread using // one of the vector element. // long depth = 0; if (obj_type == PollCommand) depth = dev->get_cmd_poll_ring_depth(obj_name); else depth = dev->get_attr_poll_ring_depth(obj_name); dev->get_poll_monitor().get_monitor(); poll_list.push_back(new PollObj(dev,type,obj_name,upd,depth)); dev->get_poll_monitor().rel_monitor(); PollingThreadInfo *th_info; int thread_created = -2; // // Find out which thread is in charge of the device. If none exists already, create one // int poll_th_id = tg->get_polling_thread_id_by_name((argin->svalue)[0]); if (poll_th_id == 0) { cout4 << "POLLING: Creating a thread to poll device " << (argin->svalue)[0] << endl; bool poll_bef_9 = false; if (polling_bef_9_def == true) poll_bef_9 = polling_bef_9; else if (tg->is_polling_bef_9_def() == true) poll_bef_9 = tg->get_polling_bef_9(); thread_created = tg->create_poll_thread((argin->svalue)[0],false,poll_bef_9); poll_th_id = tg->get_polling_thread_id_by_name((argin->svalue)[0]); } cout4 << "POLLING: Thread in charge of device " << (argin->svalue)[0] << " is thread " << poll_th_id << endl; th_info = tg->get_polling_thread_info_by_id(poll_th_id); // // Send command to the polling thread but wait in case of previous cmd still not executed // cout4 << "Sending cmd to polling thread" << endl; TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; int th_id = omni_thread::self()->id(); if (th_id != poll_th_id) { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_ADD_OBJ; shared_cmd.dev = dev; shared_cmd.index = poll_list.size() - 1; shared_cmd.new_upd = delta_ms; mon.signal(); cout4 << "Cmd sent to polling thread" << endl; // // Wait for thread to execute command except if the command is requested by the polling thread itself // omni_thread *th = omni_thread::self(); int th_id = th->id(); if (th_id != poll_th_id && local_request == false) { while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; delete poll_list.back(); poll_list.pop_back(); // // If the thread has been created by this request, try to kill it // if (thread_created == -1) { shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; mon.signal(); } Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::add_obj_polling"); } } } } else { shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_ADD_OBJ; shared_cmd.dev = dev; shared_cmd.index = poll_list.size() - 1; shared_cmd.new_upd = delta_ms; PollThread *poll_th = th_info->poll_th; poll_th->set_local_cmd(shared_cmd); poll_th->execute_cmd(); } cout4 << "Thread cmd normally executed" << endl; th_info->nb_polled_objects++; // // Update polling parameters in database (if wanted and possible). If the property is already there // (it should not but...), only update its polling period // if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { TangoSys_MemStream s; string upd_str; s << upd; s >> upd_str; bool found = false; DbDatum db_info("polled_cmd"); if (type == Tango::POLL_CMD) { vector &non_auto_list = dev->get_non_auto_polled_cmd(); vector::iterator ite; for (ite = non_auto_list.begin();ite < non_auto_list.end();++ite) { if (TG_strcasecmp((*ite).c_str(),obj_name.c_str()) == 0) { non_auto_list.erase(ite); db_info.name = "non_auto_polled_cmd"; db_info << non_auto_list; found = true; break; } } if (found == false) { vector &cmd_list = dev->get_polled_cmd(); for (i = 0;i < cmd_list.size();i = i+2) { if (TG_strcasecmp(cmd_list[i].c_str(),obj_name.c_str()) == 0) { cmd_list[i + 1] = upd_str; break; } } if (i == cmd_list.size()) { cmd_list.push_back(obj_name); cmd_list.push_back(upd_str); } db_info << cmd_list; } } else { vector &non_auto_list = dev->get_non_auto_polled_attr(); vector::iterator ite; for (ite = non_auto_list.begin();ite < non_auto_list.end();++ite) { if (TG_strcasecmp((*ite).c_str(),obj_name.c_str()) == 0) { non_auto_list.erase(ite); db_info.name = "non_auto_polled_attr"; db_info << non_auto_list; found = true; break; } } if (found == false) { db_info.name = "polled_attr"; vector &attr_list = dev->get_polled_attr(); for (i = 0;i < attr_list.size();i = i+2) { if (TG_strcasecmp(attr_list[i].c_str(),obj_name.c_str()) == 0) { attr_list[i + 1] = upd_str; break; } } if (i == attr_list.size()) { attr_list.push_back(obj_name); attr_list.push_back(upd_str); } db_info << attr_list; } } DbData send_data; send_data.push_back(db_info); dev->get_db_device()->put_property(send_data); } // // If a polling thread has just been created, ask it to poll // if (thread_created == -1) { start_polling(th_info); } // // Also update the polling threads pool conf if one thread has been created by this call // if (thread_created != -2) { string dev_name((argin->svalue)[0]); transform(dev_name.begin(),dev_name.end(),dev_name.begin(),::tolower); cout4 << "thread_created = " << thread_created << endl; if (thread_created == -1) { tg->get_poll_pool_conf().push_back(dev_name); } else if (thread_created >= 0) { string &conf_entry = (tg->get_poll_pool_conf())[thread_created]; conf_entry = conf_entry + ',' + dev_name; } if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { DbData send_data; send_data.push_back(DbDatum("polling_threads_pool_conf")); vector &ppc = tg->get_poll_pool_conf(); vector::iterator iter; vector new_ppc; for (iter = ppc.begin();iter != ppc.end();++iter) { string v_entry = *iter; unsigned int length = v_entry.size(); int nb_lines = (length / MaxDevPropLength) + 1; if (nb_lines > 1) { string::size_type start; start = 0; for (int i = 0;i < nb_lines;i++) { string sub = v_entry.substr(start,MaxDevPropLength); if (i < (nb_lines - 1)) sub = sub + '\\'; start = start + MaxDevPropLength; new_ppc.push_back(sub); } } else new_ppc.push_back(v_entry); } send_data[0] << new_ppc; tg->get_dserver_device()->get_db_device()->put_property(send_data); } } cout4 << "Polling properties updated" << endl; // // Mark the device as polled // dev->is_polled(true); } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::upd_obj_polling_period() // // description : // command to upadte an already polled object update period // // args : // in : // - argin : The polling parameters : // device name // object type (command or attribute) // object name // update period in mS (in the long array) // - with_db_upd : Flag set to true if db has to be updated // //------------------------------------------------------------------------------------------------------------------ void DServer::upd_obj_polling_period(const Tango::DevVarLongStringArray *argin,bool with_db_upd) { NoSyncModelTangoMonitor nosync_mon(this); cout4 << "In upd_obj_polling_period method" << endl; unsigned long i; for (i = 0;i < argin->svalue.length();i++) cout4 << "Input string = " << (argin->svalue)[i].in() << endl; for (i = 0;i < argin->lvalue.length();i++) cout4 << "Input long = " << (argin->lvalue)[i] << endl; // // Check that parameters number is correct // if ((argin->svalue.length() != 3) || (argin->lvalue.length() != 1)) { Except::throw_exception(API_WrongNumberOfArgs, "Incorrect number of inout arguments", "DServer::upd_obj_polling_period"); } // // Find the device // Tango::Util *tg = Tango::Util::instance(); DeviceImpl *dev = NULL; try { dev = tg->get_device_by_name((argin->svalue)[0]); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << (argin->svalue)[0] << " not found" << ends; Except::re_throw_exception(e,API_DeviceNotFound,o.str(),"DServer::upd_obj_polling_period"); } // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << (argin->svalue)[0] << " is not polled" << ends; Except::throw_exception(API_DeviceNotPolled,o.str(),"DServer::upd_obj_polling_period"); } // // If the device is locked and if the client is not the lock owner, refuse to do the job // check_lock_owner(dev,"upd_obj_polling_period",(argin->svalue)[0]); // // Find the wanted object in the list of device polled object // string obj_type((argin->svalue)[1]); transform(obj_type.begin(),obj_type.end(),obj_type.begin(),::tolower); string obj_name((argin->svalue)[2]); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); PollObjType type = Tango::POLL_CMD; string::size_type pos = obj_type.rfind(LOCAL_POLL_REQUEST); if (pos == obj_type.size() - LOCAL_REQUEST_STR_SIZE) { obj_type.erase(pos); } if (obj_type == PollCommand) { type = Tango::POLL_CMD; // // Since IDl release 3, state and status command must be polled as attributes to be able to generate event on state or // status. // if ((obj_name == "state") || (obj_name == "status")) type = Tango::POLL_ATTR; } else if (obj_type == PollAttribute) { type = Tango::POLL_ATTR; } else { TangoSys_OMemStream o; o << "Object type " << obj_type << " not supported" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::upd_obj_polling_period"); } vector::iterator ite = dev->get_polled_obj_by_type_name(type,obj_name); // // Check that the requested polling period is not below the one authorized (if defined) // int upd = (argin->lvalue)[0]; check_upd_authorized(dev,upd,type,obj_name); // // Check that it is not an externally triggered polling object. In this case, throw exception // /* long tmp_upd = (*ite)->get_upd(); if (tmp_upd == 0) { TangoSys_OMemStream o; o << "Polling for "; if (type == Tango::POLL_CMD) o << "command "; else o << "attribute "; o << (argin->svalue)[2]; o << " (device " << (argin->svalue)[0] << ") "; o << " is externally triggered. Remove and add object to change its polling period"; o << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"DServer::upd_obj_polling_period"); }*/ // // Check that the update period is not to small // if ((upd != 0) && (upd < MIN_POLL_PERIOD)) { TangoSys_OMemStream o; o << (argin->lvalue)[0] << " is below the min authorized period (" << MIN_POLL_PERIOD << " mS)" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::upd_obj_polling"); } // // Find out which thread is in charge of the device. If none exists already, create one // PollingThreadInfo *th_info; int poll_th_id = tg->get_polling_thread_id_by_name((argin->svalue)[0]); if (poll_th_id == 0) { TangoSys_OMemStream o; o << "Can't find a polling thread for device " << (argin->svalue)[0] << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::upd_obj_polling"); } th_info = tg->get_polling_thread_info_by_id(poll_th_id); // // Update polling period // (*ite)->update_upd(upd); // // Send command to the polling thread // TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; int th_id = omni_thread::self()->id(); if (th_id != poll_th_id) { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_UPD_PERIOD; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = type; shared_cmd.new_upd = (argin->lvalue)[0]; shared_cmd.index = distance(dev->get_poll_obj_list().begin(),ite); mon.signal(); } else { shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_UPD_PERIOD; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = type; shared_cmd.new_upd = (argin->lvalue)[0]; shared_cmd.index = distance(dev->get_poll_obj_list().begin(),ite); PollThread *poll_th = th_info->poll_th; poll_th->set_local_cmd(shared_cmd); poll_th->execute_cmd(); } // // Update database property --> Update polling period if this object is already defined in the polling property. // Add object name and update period if the object is not known in the property // if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { TangoSys_MemStream s; string upd_str; s << (argin->lvalue)[0] << ends; s >> upd_str; DbDatum db_info("polled_attr"); if (type == Tango::POLL_CMD) { db_info.name = "polled_cmd"; vector &cmd_list = dev->get_polled_cmd(); for (i = 0;i < cmd_list.size();i = i+2) { if (TG_strcasecmp(cmd_list[i].c_str(),obj_name.c_str()) == 0) { cmd_list[i + 1] = upd_str; break; } } if (i == cmd_list.size()) { cmd_list.push_back(obj_name); cmd_list.push_back(upd_str); } db_info << cmd_list; } else { vector &attr_list = dev->get_polled_attr(); for (i = 0;i < attr_list.size();i = i+2) { if (TG_strcasecmp(attr_list[i].c_str(),obj_name.c_str()) == 0) { attr_list[i + 1] = upd_str; break; } } if (i == attr_list.size()) { attr_list.push_back(obj_name); attr_list.push_back(upd_str); } db_info << attr_list; } DbData send_data; send_data.push_back(db_info); dev->get_db_device()->put_property(send_data); } } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::rem_obj_polling() // // description : // command to remove an already polled object from the device polled object list // // args : // in : // - argin: The polling parameters : // device name // object type (command or attribute) // object name // - with_db_upd : Update db flag // //----------------------------------------------------------------------------------------------------------------- void DServer::rem_obj_polling(const Tango::DevVarStringArray *argin,bool with_db_upd) { NoSyncModelTangoMonitor nosync_mon(this); cout4 << "In rem_obj_polling method" << endl; unsigned long i; for (i = 0;i < argin->length();i++) cout4 << "Input string = " << (*argin)[i].in() << endl; // // Check that parameters number is correct // if (argin->length() != 3) { Except::throw_exception(API_WrongNumberOfArgs, "Incorrect number of inout arguments", "DServer::rem_obj_polling"); } // // Find the device // Tango::Util *tg = Tango::Util::instance(); DeviceImpl *dev = NULL; try { dev = tg->get_device_by_name((*argin)[0]); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << (*argin)[0] << " not found" << ends; Except::re_throw_exception(e,API_DeviceNotFound,o.str(),"DServer::rem_obj_polling"); } // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << (*argin)[0] << " is not polled" << ends; Except::throw_exception(API_DeviceNotPolled,o.str(),"DServer::rem_obj_polling"); } // // If the device is locked and if the client is not the lock owner, refuse to do the job // check_lock_owner(dev,"rem_obj_polling",(*argin)[0]); // // Find the wanted object in the list of device polled object // string obj_type((*argin)[1]); transform(obj_type.begin(),obj_type.end(),obj_type.begin(),::tolower); string obj_name((*argin)[2]); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); bool local_request = false; string::size_type pos = obj_type.rfind(LOCAL_POLL_REQUEST); if (pos == obj_type.size() - LOCAL_REQUEST_STR_SIZE) { local_request = true; obj_type.erase(pos); } PollObjType type = Tango::POLL_CMD; if (obj_type == PollCommand) { type = Tango::POLL_CMD; if ((obj_name == "state") || (obj_name == "status")) type = Tango::POLL_ATTR; } else if (obj_type == PollAttribute) { type = Tango::POLL_ATTR; } else { TangoSys_OMemStream o; o << "Object type " << obj_type << " not supported" << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::rem_obj_polling"); } vector::iterator ite = dev->get_polled_obj_by_type_name(type,obj_name); long tmp_upd = (*ite)->get_upd(); PollingThreadInfo *th_info; int poll_th_id; int th_id = omni_thread::self()->id(); // // Find out which thread is in charge of the device. // if (tg->is_svr_shutting_down() == false) { poll_th_id = tg->get_polling_thread_id_by_name((*argin)[0]); if (poll_th_id == 0) { TangoSys_OMemStream o; o << "Can't find a polling thread for device " << (*argin)[0] << ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::rem_obj_polling"); } cout4 << "Thread in charge of device " << (*argin)[0] << " is thread " << poll_th_id << endl; th_info = tg->get_polling_thread_info_by_id(poll_th_id); // // Test whether the polling thread is still running! // if ( th_info->poll_th != NULL ) { // // Send command to the polling thread // cout4 << "Sending cmd to polling thread" << endl; TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; if (th_id != poll_th_id) { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; if (tmp_upd == 0) shared_cmd.cmd_code = POLL_REM_EXT_TRIG_OBJ; else shared_cmd.cmd_code = POLL_REM_OBJ; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = type; mon.signal(); cout4 << "Cmd sent to polling thread" << endl; // // Wait for thread to execute command except if the command is requested by the polling thread itself // if (th_id != poll_th_id) { if (local_request == false) { while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::rem_obj_polling"); } } } } } else { shared_cmd.cmd_pending = true; if (tmp_upd == 0) shared_cmd.cmd_code = POLL_REM_EXT_TRIG_OBJ; else shared_cmd.cmd_code = POLL_REM_OBJ; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = type; shared_cmd.index = distance(dev->get_poll_obj_list().begin(),ite); PollThread *poll_th = th_info->poll_th; poll_th->set_local_cmd(shared_cmd); poll_th->execute_cmd(); } cout4 << "Thread cmd normally executed" << endl; } else { cout4 << "Polling thread is no longer running!!!!" << endl; } } // // Remove the object from the polled object list // vector &poll_list = dev->get_poll_obj_list(); dev->get_poll_monitor().get_monitor(); delete(*ite); poll_list.erase(ite); dev->get_poll_monitor().rel_monitor(); // // Set attribute polling period to 0 // if (type == Tango::POLL_ATTR) { Attribute &att = dev->get_device_attr()->get_attr_by_name(obj_name.c_str()); att.set_polling_period(0); } // // Mark the device as non polled if this was the last polled object // if (poll_list.empty() == true) dev->is_polled(false); // // Update database property. This means remove object entry in the polling properties if they exist or add it to the // list of device not polled for automatic polling defined at command/attribute level. // Do this if possible and wanted. // if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { DbData send_data; DbDatum db_info("polled_attr"); bool update_needed = false; if (type == Tango::POLL_CMD) { db_info.name = "polled_cmd"; vector &cmd_list = dev->get_polled_cmd(); vector::iterator s_ite; for (s_ite = cmd_list.begin();s_ite < cmd_list.end();++s_ite) { if (TG_strcasecmp((*s_ite).c_str(),obj_name.c_str()) == 0) { s_ite = cmd_list.erase(s_ite); cmd_list.erase(s_ite); db_info << cmd_list; update_needed = true; break; } ++s_ite; } if (update_needed == false) { vector &non_auto_cmd = dev->get_non_auto_polled_cmd(); for (s_ite = non_auto_cmd.begin();s_ite < non_auto_cmd.end();++s_ite) { if (TG_strcasecmp((*s_ite).c_str(),obj_name.c_str()) == 0) break; } if (s_ite == non_auto_cmd.end()) { non_auto_cmd.push_back(obj_name); db_info.name = "non_auto_polled_cmd"; db_info << non_auto_cmd; update_needed = true; } } } else { vector &attr_list = dev->get_polled_attr(); vector::iterator s_ite; for (s_ite = attr_list.begin();s_ite < attr_list.end();++s_ite) { if (TG_strcasecmp((*s_ite).c_str(),obj_name.c_str()) == 0) { s_ite = attr_list.erase(s_ite); attr_list.erase(s_ite); db_info << attr_list; update_needed = true; break; } ++s_ite; } if (update_needed == false) { vector &non_auto_attr = dev->get_non_auto_polled_attr(); for (s_ite = non_auto_attr.begin();s_ite < non_auto_attr.end();++s_ite) { if (TG_strcasecmp((*s_ite).c_str(),obj_name.c_str()) == 0) break; } if (s_ite == non_auto_attr.end()) { non_auto_attr.push_back(obj_name); db_info.name = "non_auto_polled_attr"; db_info << non_auto_attr; update_needed = true; } } } if (update_needed == true) { DbData send_data; send_data.push_back(db_info); if (db_info.size() == 0) dev->get_db_device()->delete_property(send_data); else dev->get_db_device()->put_property(send_data); cout4 << "Database polling properties updated" << endl; } } // // If the device is not polled any more, update the pool conf first locally. Also update the map // If this device was the only one for a polling thread, kill the thread then in Db if possible // bool kill_thread = false; if (poll_list.empty() == true) { int ind; string dev_name((*argin)[0]); transform(dev_name.begin(),dev_name.end(),dev_name.begin(),::tolower); if ((ind = tg->get_dev_entry_in_pool_conf(dev_name)) == -1) { TangoSys_OMemStream o; o << "Can't find entry for device " << (*argin)[0] << " in polling threads pool configuration !"<< ends; Except::throw_exception(API_NotSupported,o.str(),"DServer::rem_obj_polling"); } vector &pool_conf = tg->get_poll_pool_conf(); string &conf_entry = pool_conf[ind]; string::size_type pos; if ((pos = conf_entry.find(',')) != string::npos) { pos = conf_entry.find(dev_name); if ((pos + dev_name.size()) != conf_entry.size()) conf_entry.erase(pos,dev_name.size() + 1); else conf_entry.erase(pos - 1); } else { vector::iterator iter = pool_conf.begin() + ind; pool_conf.erase(iter); kill_thread = true; } tg->remove_dev_from_polling_map(dev_name); // // Kill the thread if needed and join but don do this now if the executing thread is the polling thread itself // (case of a polled command which itself decide to stop its own polling) // if (kill_thread == true && tg->is_svr_shutting_down() == false && th_id != poll_th_id) { TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; mon.signal(); } void *dummy_ptr; cout4 << "POLLING: Joining with one polling thread" << endl; th_info->poll_th->join(&dummy_ptr); tg->remove_polling_thread_info_by_id(poll_th_id); } // // Update db // if ((with_db_upd == true) && (Tango::Util::_UseDb == true)) { DbData send_data; send_data.push_back(DbDatum("polling_threads_pool_conf")); send_data[0] << tg->get_poll_pool_conf(); tg->get_dserver_device()->get_db_device()->put_property(send_data); } } // // In case there are some subscribers for event on this attribute relying on polling, fire event with error // if (type == POLL_ATTR) { Attribute &att = dev->get_device_attr()->get_attr_by_name((*argin)[2]); DevFailed ex; ex.errors.length(1); ex.errors[0].severity = ERR; ex.errors[0].reason = CORBA::string_dup(API_PollObjNotFound); ex.errors[0].origin = CORBA::string_dup("DServer::rem_obj_polling"); stringstream ss; ss << "No event possible on attribute " << obj_name << ". Polling has just being stopped!"; ex.errors[0].desc = CORBA::string_dup(ss.str().c_str()); if (att.periodic_event_subscribed() == true) att.fire_error_periodic_event(&ex); if (att.archive_event_subscribed() == true && att.is_archive_event() == false) dev->push_archive_event(obj_name,&ex); if (att.change_event_subscribed() == true && att.is_change_event() == false) dev->push_change_event(obj_name,&ex); } // // In case of local_request and executing thread is the polling thread, ask our self to exit now that eveything else // is done // if (kill_thread == true && tg->is_svr_shutting_down() == false && th_id == poll_th_id && local_request == true) { tg->remove_polling_thread_info_by_id(poll_th_id); PollThCmd &shared_cmd = th_info->shared_data; shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::stop_polling() // // description : // command to stop the polling thread // //------------------------------------------------------------------------------------------------------------------- void DServer::stop_polling() { NoSyncModelTangoMonitor nosync_mon(this); cout4 << "In stop_polling method" << endl; // // Send command to the polling thread and wait for its execution // int interupted; Tango::Util *tg = Tango::Util::instance(); vector &th_info = tg->get_polling_threads_info(); vector:: iterator iter; for (iter = th_info.begin();iter != th_info.end();++iter) { TangoMonitor &mon = (*iter)->poll_mon; PollThCmd &shared_cmd = (*iter)->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_STOP; mon.signal(); while (shared_cmd.cmd_pending == true) { interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::stop_polling"); } } } } // // Update polling status // tg->poll_status(false); string &str = get_status(); str = "The device is ON\nThe polling is OFF"; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::start_polling() // // description : // command to start the polling thread // //------------------------------------------------------------------------------------------------------------------ void DServer::start_polling() { NoSyncModelTangoMonitor nosync_mon(this); cout4 << "In start_polling method" << endl; // // Send command to the polling thread(s) and wait for its execution // Tango::Util *tg = Tango::Util::instance(); vector &th_info = tg->get_polling_threads_info(); vector:: iterator iter; for (iter = th_info.begin();iter != th_info.end();++iter) { TangoMonitor &mon = (*iter)->poll_mon; PollThCmd &shared_cmd = (*iter)->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_START; mon.signal(); while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::start_polling"); } } } } // // Update polling status // tg->poll_status(true); string &str = get_status(); str = "The device is ON\nThe polling is ON"; } void DServer::start_polling(PollingThreadInfo *th_info) { TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_START; mon.signal(); while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked while trying to start thread polling!!!", "DServer::start_polling"); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::add_event_heartbeat() // // description : // command to ask the heartbeat thread to send the event heartbeat every 9 seconds // //-------------------------------------------------------------------------------------------------------------------- void DServer::add_event_heartbeat() { NoSyncModelTangoMonitor nosyn_mon(this); cout4 << "In add_event_heartbeat method" << endl; // // Send command to the heartbeat thread but wait in case of previous cmd still not executed // cout4 << "Sending cmd to polling thread" << endl; Tango::Util *tg = Tango::Util::instance(); TangoMonitor &mon = tg->get_heartbeat_monitor(); PollThCmd &shared_cmd = tg->get_heartbeat_shared_cmd(); { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_ADD_HEARTBEAT; mon.signal(); cout4 << "Cmd sent to polling thread" << endl; // // Wait for thread to execute command except if the command is requested by the polling thread itself // int th_id = omni_thread::self()->id(); if (th_id != tg->get_heartbeat_thread_id()) { while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::add_event_heartbeat"); } } } } cout4 << "Thread cmd normally executed" << endl; } //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::rem_event_heartbeat() // // description : // command to ask the heartbeat thread to stop sending the event heartbeat // //----------------------------------------------------------------------------------------------------------------- void DServer::rem_event_heartbeat() { NoSyncModelTangoMonitor nosyn_mon(this); cout4 << "In rem_event_heartbeat method" << endl; // // Send command to the heartbeat thread but wait in case of previous cmd still not executed // cout4 << "Sending cmd to polling thread" << endl; Tango::Util *tg = Tango::Util::instance(); TangoMonitor &mon = tg->get_heartbeat_monitor(); PollThCmd &shared_cmd = tg->get_heartbeat_shared_cmd(); { omni_mutex_lock sync(mon); if (shared_cmd.cmd_pending == true) { mon.wait(); } shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_REM_HEARTBEAT; mon.signal(); cout4 << "Cmd sent to polling thread" << endl; // // Wait for thread to execute command except if the command is requested by the polling thread itself // int th_id = omni_thread::self()->id(); if (th_id != tg->get_heartbeat_thread_id()) { while (shared_cmd.cmd_pending == true) { int interupted = mon.wait(DEFAULT_TIMEOUT); if ((shared_cmd.cmd_pending == true) && (interupted == false)) { cout4 << "TIME OUT" << endl; Except::throw_exception(API_CommandTimedOut, "Polling thread blocked !!!", "DServer::rem_event_heartbeat"); } } } } cout4 << "Thread cmd normally executed" << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::check_upd_authorized() // // description : // In case a minimun update polling period is defined (via the min_poll_period, cmd_min_poll_period, // attr_min_poll_period) check if the requested period is not smaller // // args : // in: // - dev : The device // - upd : The requested update period // - type : The polled object type (cmd / attr) // - obj_name : The polled object name // //------------------------------------------------------------------------------------------------------------------ void DServer::check_upd_authorized(DeviceImpl *dev,int upd,PollObjType obj_type,string &obj_name) { int min_upd = 0; // // Get first the xxx_min_poll_period then if not defined the min_poll_period // vector *v_ptr; if (obj_type == Tango::POLL_CMD) v_ptr = &(dev->get_cmd_min_poll_period()); else v_ptr = &(dev->get_attr_min_poll_period()); vector::iterator ite = find(v_ptr->begin(),v_ptr->end(),obj_name); if (ite != v_ptr->end()) { ++ite; TangoSys_MemStream s; s << *ite; if (!(s >> min_upd)) { TangoSys_OMemStream o; o << "System property "; if (obj_type == Tango::POLL_CMD) o << "cmd_min_poll_period"; else o << "attr_min_poll_period"; o << " for device " << dev->get_name() << " has wrong syntax" << ends; Except::throw_exception(API_BadConfigurationProperty,o.str(),"DServer::check_upd_uthorized()"); } } else { min_upd = dev->get_min_poll_period(); } // // Check with user request // if ((min_upd != 0) && (upd < min_upd)) { TangoSys_OMemStream o; o << "Polling period for "; if (obj_type == Tango::POLL_CMD) o << "command "; else o << "attribute "; o << obj_name << " is below the min authorized (" << min_upd << ")" << ends; Except::throw_exception(API_MethodArgument,o.str(),"DServer::check_upd_authorized"); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/dserversignal.cpp0000644023471100065110000005632513034745001016150 00000000000000static const char *RcsId = "$Id: dserversignal.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+================================================================================================================== // // file : DServerSignal.cpp // // description : C++ source for the DServer class and its commands. The class is derived from Device. // It represents the CORBA servant object which will be accessed from the network. // All commands which can be executed on a DServer object are implemented in this file. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28853 $ // //-=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifndef _TG_WINDOWS_ extern int errno; #endif namespace Tango { DServerSignal *DServerSignal::_instance = NULL; DevSigAction DServerSignal::reg_sig[_NSIG]; string DServerSignal::sig_name[_NSIG]; #ifdef _TG_WINDOWS_ HANDLE DServerSignal::win_ev = NULL; int DServerSignal::win_signo = 0; #endif //+------------------------------------------------------------------------------------------------------------------ // // method : // DServerSignal::Instance() // // description : // Instance method for DServerSignal object. This class is a singleton and this method creates the object the // first time it is called or simply returns a pointer to the already created object for all the other calls. // //------------------------------------------------------------------------------------------------------------------- DServerSignal *DServerSignal::instance() { if (_instance == NULL) { try { _instance = new DServerSignal(); } catch (bad_alloc &) { throw; } } return _instance; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::DServerSignal() // // description : // constructor for DServerSignal object. As this class is a singleton, this method is protected // //----------------------------------------------------------------------------------------------------------------- DServerSignal::DServerSignal():TangoMonitor("signal") { cout4 << "Entering DServerSignal constructor" << endl; // // Set array of signal name // #ifdef _TG_WINDOWS_ sig_name[SIGINT] = "SIGINT"; sig_name[SIGILL] = "SIGILL"; sig_name[SIGFPE] = "SIGFPE"; sig_name[SIGSEGV] = "SIGSEGV"; sig_name[SIGTERM] = "SIGTERM"; sig_name[SIGBREAK] = "SIGBREAK"; sig_name[SIGABRT] = "SIGABRT"; #else sig_name[SIGHUP] = "SIGHUP"; sig_name[SIGINT] = "SIGINT"; sig_name[SIGQUIT] = "SIGQUIT"; sig_name[SIGILL] = "SIGILL"; sig_name[SIGTRAP] = "SIGTRAP"; sig_name[SIGABRT] = "SIGABRT"; sig_name[SIGFPE] = "SIGFPE"; sig_name[SIGKILL] = "SIGKILL"; sig_name[SIGBUS] = "SIGBUS"; sig_name[SIGSEGV] = "SIGSEGV"; sig_name[SIGPIPE] = "SIGPIPE"; sig_name[SIGALRM] = "SIGALRM"; sig_name[SIGTERM] = "SIGTERM"; sig_name[SIGUSR1] = "SIGUSR1"; sig_name[SIGUSR2] = "SIGUSR2"; sig_name[SIGCHLD] = "SIGCHLD"; sig_name[SIGVTALRM] = "SIGVTALRM"; sig_name[SIGPROF] = "SIGPROF"; sig_name[SIGIO] = "SIGIO"; sig_name[SIGWINCH] = "SIGWINCH"; sig_name[SIGSTOP] = "SIGSTOP"; sig_name[SIGTSTP] = "SIGTSTP"; sig_name[SIGCONT] = "SIGCONT"; sig_name[SIGTTIN] = "SIGTTIN"; sig_name[SIGTTOU] = "SIGTTOU"; sig_name[SIGURG] = "SIGURG"; sig_name[SIGSYS] = "SIGSYS"; #ifdef linux sig_name[SIGXCPU] = "SIGXCPU"; sig_name[SIGXFSZ] = "SIGXFSZ"; sig_name[SIGCLD] = "SIGCLD"; sig_name[SIGPWR] = "SIGPWR"; #else #ifdef __darwin__ sig_name[SIGEMT] = "SIGEMT"; sig_name[SIGINFO] = "SIGINFO"; #else #ifdef __freebsd__ sig_name[SIGXCPU] = "SIGXCPU"; sig_name[SIGXFSZ] = "SIGXFSZ"; #endif /* __freebsd__ */ #endif /* __darwin__ */ #endif /* linux */ #endif /* _TG_WINDOWS_ */ TangoSys_OMemStream o; for (long i = 0;i < _NSIG;i++) { if (sig_name[i].size() == 0) { o << i << ends; sig_name[i] = o.str(); o.seekp(0); o.clear(); } } sig_to_install = false; sig_to_remove = false; #ifndef _TG_WINDOWS_ // // With Solaris/Linux, the SIGINT and SIGQUIT default actions are set to SIG_IGN for all processes started in the // background (POSIX requirement). Signal SIGINT is used by Tango in its signal management, reset the default action // to default // struct sigaction sa; sa.sa_flags = 0; sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); if (sigaction(SIGINT,&sa,NULL) == -1) cerr << "DServerSignal::DServerSignal --> Can't reset default action for SIGINT to SIG_DFL" << endl; if (sigaction(SIGQUIT,&sa,NULL) == -1) cerr << "DServerSignal::DServerSignal --> Can't reset default action for SIGQUIT to SIG_DFL" << endl; // // Block signals in thread other than the thread dedicated to signal // sigset_t sigs_to_block; sigemptyset(&sigs_to_block); sigfillset(&sigs_to_block); sigdelset(&sigs_to_block,SIGABRT); sigdelset(&sigs_to_block,SIGKILL); sigdelset(&sigs_to_block,SIGILL); sigdelset(&sigs_to_block,SIGTRAP); sigdelset(&sigs_to_block,SIGIOT); sigdelset(&sigs_to_block,SIGFPE); sigdelset(&sigs_to_block,SIGBUS); sigdelset(&sigs_to_block,SIGSEGV); sigdelset(&sigs_to_block,SIGSYS); sigdelset(&sigs_to_block,SIGPIPE); sigdelset(&sigs_to_block,SIGSTOP); sigdelset(&sigs_to_block,SIGTSTP); sigdelset(&sigs_to_block,SIGUSR1); sigdelset(&sigs_to_block,SIGUSR2); sigprocmask(SIG_BLOCK,&sigs_to_block,NULL); #else /* _TG_WINDOWS_ */ win_ev = CreateEvent(NULL,FALSE,FALSE,NULL); register_handler(SIGINT); register_handler(SIGTERM); register_handler(SIGABRT); if (Util::_service == false) register_handler(SIGBREAK); #endif /* _TG_WINDOWS_ */ // // Start the thread dedicated to signal // sig_th = new ThSig(this); sig_th->start(); cout4 << "leaving DServerSignal constructor" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServerSignal::register_class_signal() // // description : // method to register a signal handler at the class level // // argument : // in : // - signo : Signal number // - cl_ptr : Pointer to device class object // //----------------------------------------------------------------------------- #if defined _TG_WINDOWS_ void DServerSignal::register_class_signal(long signo,DeviceClass *cl_ptr) #else void DServerSignal::register_class_signal(long signo,bool handler,DeviceClass *cl_ptr) #endif { // // Check signal validity // if ((signo < 1) || (signo >= _NSIG)) { TangoSys_OMemStream o; o << "Signal number " << signo << " out of range" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_class_signal"); } if (auth_signal(signo) == false) { TangoSys_OMemStream o; o << "Signal " << sig_name[signo] << "is not authorized with your OS" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_class_signal"); } #ifndef _TG_WINDOWS_ if ((auto_signal(signo) == true) && (handler == true)) { TangoSys_OMemStream o; o << "Signal " << sig_name[signo] << "is not authorized using your own handler" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_class_signal"); } #endif // // If nothing is registered for this signal, install the OS signal handler // if (auto_signal(signo) == false) { if ((reg_sig[signo].registered_devices.empty() == true) && (reg_sig[signo].registered_classes.empty() == true)) { #ifdef _TG_WINDOWS_ register_handler(signo); #else register_handler(signo,handler); #endif } } // // Check if class is already registered for this signal. If it is already done, leave method. // Otherwise, record class pointer // vector::iterator f = find_class(signo,cl_ptr); if (f == reg_sig[signo].registered_classes.end()) { reg_sig[signo].registered_classes.push_back(cl_ptr); #ifndef _TG_WINDOWS_ reg_sig[signo].own_handler = handler; #endif } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::find_class // // description : // Method to check if a class is already registered for a signal. If it is true, this method returns in which // element of the vector the class is registered // // argument : // in : // - signo : Signal number // - cl_ptr : Pointer to device class object // //------------------------------------------------------------------------------------------------------------------- vector::iterator DServerSignal::find_class(long signo,DeviceClass *cl_ptr) { vector::iterator p; for (p = reg_sig[signo].registered_classes.begin();p < reg_sig[signo].registered_classes.end();++p) { if ((*p) == cl_ptr) break; } return p; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::register_dev_signal() // // description : // method to register a signal handler at the device level // // argument : // in : // - signo : Signal number // - dev_ptr : Pointer to device object // //------------------------------------------------------------------------------------------------------------------ #ifdef _TG_WINDOWS_ void DServerSignal::register_dev_signal(long signo,DeviceImpl *dev_ptr) #else void DServerSignal::register_dev_signal(long signo,bool handler,DeviceImpl *dev_ptr) #endif { // // Check signal validity // if ((signo < 1) || (signo >= _NSIG)) { TangoSys_OMemStream o; o << "Signal number " << signo << " out of range" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_dev_signal"); } if (auth_signal(signo) == false) { TangoSys_OMemStream o; o << "Signal " << sig_name[signo] << "is not authorized with your OS" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_dev_signal"); } #ifndef _TG_WINDOWS_ if ((auto_signal(signo) == true) && (handler == true)) { TangoSys_OMemStream o; o << "Signal " << sig_name[signo] << "is not authorized using your own handler" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_class_signal"); } #endif // // If nothing is registered for this signal, install the OS signal handler // if (auto_signal(signo) == false) { if ((reg_sig[signo].registered_devices.empty() == true) && (reg_sig[signo].registered_classes.empty() == true)) { #ifdef _TG_WINDOWS_ register_handler(signo); #else register_handler(signo,handler); #endif } } // // Check if devices is already registered for this signal. If it is already done, leave method. // Otherwise, record class pointer // vector::iterator f = find_device(signo,dev_ptr); if (f == reg_sig[signo].registered_devices.end()) { reg_sig[signo].registered_devices.push_back(dev_ptr); #ifndef _TG_WINDOWS_ reg_sig[signo].own_handler = handler; #endif } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::find_device // // description : // Method to check if a device is already registered for a signal. If it is true, this method returns in which // element of the vector the device is registered // // argument : // in : // - signo : Signal number // - dev_ptr : Pointer to device object // //-------------------------------------------------------------------------------------------------------------------- vector::iterator DServerSignal::find_device(long signo,DeviceImpl *dev_ptr) { vector::iterator p; for (p = reg_sig[signo].registered_devices.begin();p < reg_sig[signo].registered_devices.end();++p) { if ((*p) == dev_ptr) break; } return p; } //+------------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::unregister_class_signal() // // description : // Method to unregister a signal handler at the class level // // argument : // in : // - signo : Signal number // - cl_ptr : Pointer to device class object // //------------------------------------------------------------------------------------------------------------------ void DServerSignal::unregister_class_signal(long signo,DeviceClass *cl_ptr) { // // Check signal validity // if ((signo < 1) || (signo >= _NSIG)) { TangoSys_OMemStream o; o << "Signal number " << signo << " out of range" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_proc_signal"); } // // Check if class is already registered for this signal. If it is already done, leave method. // Otherwise, record class pointer // vector::iterator f = find_class(signo,cl_ptr); if (f == reg_sig[signo].registered_classes.end()) return; else reg_sig[signo].registered_classes.erase(f); // // If nothing is registered for this signal, unregister the OS signal handler and (eventually) the event handler // if (auto_signal(signo) == false) { if ((reg_sig[signo].registered_classes.empty() == true) && (reg_sig[signo].registered_devices.empty() == true)) unregister_handler(signo); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServerSignal::unregister_dev_signal() // // description : // Method to unregister a signal handler at the class level // // argument : // in : // - signo : Signal number // - dev_ptr : Pointer to device object // //------------------------------------------------------------------------------------------------------------------ void DServerSignal::unregister_dev_signal(long signo,DeviceImpl *dev_ptr) { // // Check signal validity // if ((signo < 1) || (signo >= _NSIG)) { TangoSys_OMemStream o; o << "Signal number " << signo << " out of range" << ends; Except::throw_exception((const char *)API_SignalOutOfRange, o.str(), (const char *)"DServerSignal::register_proc_signal"); } // // Check if device is already registered for this signal. If yes, remove it. // Otherwise, leave method // vector::iterator f = find_device(signo,dev_ptr); if (f == reg_sig[signo].registered_devices.end()) return; else reg_sig[signo].registered_devices.erase(f); // // If nothing is registered for this signal, unregister the OS signal handler and eventually the event handler // if (auto_signal(signo) == false) { if ((reg_sig[signo].registered_classes.empty() == true) && (reg_sig[signo].registered_devices.empty() == true)) { unregister_handler(signo); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::unregister_dev_signal() // // description : // Method to unregister a signal handler at the device level for all signals // // argument : // in : // - dev_ptr : Pointer to device object // //------------------------------------------------------------------------------------------------------------------ void DServerSignal::unregister_dev_signal(DeviceImpl *dev_ptr) { long i; for (i = 0;i < _NSIG;i++) { // // Check if device is registered for this signal. If yes, remove it. Otherwise, go to next signal // vector::iterator f = find_device(i,dev_ptr); if (f == reg_sig[i].registered_devices.end()) continue; else reg_sig[i].registered_devices.erase(f); // // If nothing is registered for this signal, unregister the OS signal handler // if (auto_signal(i) == false) { if ((reg_sig[i].registered_classes.empty() == true) && (reg_sig[i].registered_devices.empty() == true)) unregister_handler(i); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::unregister_class_signal() // // description : // Method to unregister a signal handler at the class level for all signals // // argument : // in : // - cl_ptr : Pointer to device class object // //------------------------------------------------------------------------------------------------------------------- void DServerSignal::unregister_class_signal(DeviceClass *cl_ptr) { long i; for (i = 0;i < _NSIG;i++) { // // Check if classes is registered for this signal. If yes, remove it. Otherwise, go to next signal // vector::iterator f = find_class(i,cl_ptr); if (f == reg_sig[i].registered_classes.end()) continue; else reg_sig[i].registered_classes.erase(f); // // If nothing is registered for this signal, unregister the OS signal handler // if (auto_signal(i) == false) { if ((reg_sig[i].registered_classes.empty() == true) && (reg_sig[i].registered_devices.empty() == true)) unregister_handler(i); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::register_handler() // // description : // Method to register in the OS the main signal handler for a given signal // // argument : // in : // - signo : Signal number // //------------------------------------------------------------------------------------------------------------------ #ifdef _TG_WINDOWS_ void DServerSignal::register_handler(long signo) #else void DServerSignal::register_handler(long signo,bool handler) #endif { cout4 << "Installing OS signal handler for signal " << sig_name[signo] << endl; #ifdef _TG_WINDOWS_ if (::signal(signo, DServerSignal::main_sig_handler) == SIG_ERR) { TangoSys_OMemStream o; o << "Can't install signal " << signo << ". OS error = " << errno << ends; Except::throw_exception((const char *)API_CantInstallSignal, o.str(), (const char *)"DServerSignal::register_handler"); } #else if (handler == true) { sigset_t sigs_to_unblock; sigemptyset(&sigs_to_unblock); sigaddset(&sigs_to_unblock,signo); if (pthread_sigmask(SIG_UNBLOCK,&sigs_to_unblock,NULL) != 0) { TangoSys_OMemStream o; o << "Can't install signal " << signo << ". OS error = " << errno << ends; Except::throw_exception((const char *)API_CantInstallSignal, o.str(), (const char *)"DServerSignal::register_handler"); } struct sigaction sa; sa.sa_flags = SA_RESTART; sa.sa_handler = DServerSignal::main_sig_handler; sigemptyset(&sa.sa_mask); if (sigaction((int)signo,&sa,0) == -1) { TangoSys_OMemStream o; o << "Can't install signal " << signo << ". OS error = " << errno << ends; Except::throw_exception((const char *)API_CantInstallSignal, o.str(), (const char *)"DServerSignal::register_handler"); } } else { omni_mutex_lock sy(*this); while(sig_to_install == true) { wait(); } sig_to_install = true; inst_sig = signo; pthread_kill(sig_th->my_thread,SIGINT); } #endif } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::unregister_handler() // // description : // Method to unregister from the OS the main signal handler for a given signal // // argument : // in : // - signo : Signal number // //----------------------------------------------------------------------------------------------------------------- void DServerSignal::unregister_handler(long signo) { cout4 << "Removing OS signal handler for signal " << sig_name[signo] << endl; #ifdef _TG_WINDOWS_ if (::signal(signo, SIG_DFL) == SIG_ERR) { TangoSys_OMemStream o; o << "Can't install signal " << signo << ". OS error = " << errno << ends; Except::throw_exception((const char *)API_CantInstallSignal, o.str(), (const char *)"DServerSignal::register_handler"); } #else if (reg_sig[signo].own_handler == true) { struct sigaction sa; sa.sa_flags = 0; sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); if (sigaction((int)signo,&sa,0) == -1) { TangoSys_OMemStream o; o << "Can't install signal " << signo << ". OS error = " << errno << ends; Except::throw_exception((const char *)API_CantInstallSignal, o.str(), (const char *)"DServerSignal::register_handler"); } } else { omni_mutex_lock sy(*this); while(sig_to_remove == true) { wait(); } sig_to_remove = true; rem_sig = signo; pthread_kill(sig_th->my_thread,SIGINT); } #endif } #ifndef _TG_WINDOWS_ pid_t DServerSignal::get_sig_thread_pid() { omni_mutex_lock syn(*this); if (sig_th->my_pid == 0) { wait(1000); } return sig_th->my_pid; } #endif //+------------------------------------------------------------------------------------------------------------------- // // method : // DServerSignal::main_sig_handler() // // description : // This is a dummy signal handler used only with solaris which needs one for signal with a default ignore // action to work correctly with the sigwait() call. // // argument : // in : // - signo : Signal number // //------------------------------------------------------------------------------------------------------------------- #ifndef _TG_WINDOWS_ void DServerSignal::main_sig_handler(int signo) { cout4 << "In main sig_handler !!!!" << endl; DevSigAction *act_ptr = &(DServerSignal::reg_sig[signo]); // // First, execute all the handlers installed at the class level // if (act_ptr->registered_classes.empty() == false) { long nb_class = act_ptr->registered_classes.size(); for (long j = 0;j < nb_class;j++) { act_ptr->registered_classes[j]->signal_handler((long)signo); } } // // Then, execute all the handlers installed at the device level // if (act_ptr->registered_devices.empty() == false) { long nb_dev = act_ptr->registered_devices.size(); for (long j = 0;j < nb_dev;j++) { act_ptr->registered_devices[j]->signal_handler((long)signo); } } } #else void DServerSignal::main_sig_handler(int signo) { cout4 << "In main sig_handler !!!!" << endl; win_signo = signo; SetEvent(win_ev); } #endif } // End of Tango namespace tango-9.2.5a/lib/cpp/server/encoded_attribute.cpp0000644023471100065110000003350413034745001016756 00000000000000///============================================================================= // // file : encoded_attribute.cpp // // description : Management of Tango::DevEncoded format // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // //============================================================================= #include #include using namespace Tango; #define SAFE_FREE(x) if(x) {free(x);x=NULL;} // ---------------------------------------------------------------------------- EncodedAttribute::EncodedAttribute():manage_exclusion(false),ext(Tango_nullptr) { buffer_array = (unsigned char **)calloc(1,sizeof(unsigned char *)); buffer_array[0] = NULL; buffSize_array = (int *)calloc(1,sizeof(int)); buffSize_array[0] = 0; format = NULL; mutex_array = NULL; index = 0; buf_elt_nb = 1; } EncodedAttribute::EncodedAttribute(int si,bool excl):manage_exclusion(excl),ext(Tango_nullptr) { buffer_array = (unsigned char **)calloc(si,sizeof(unsigned char *)); buffSize_array = (int *)calloc(si,sizeof(int)); for (int i = 0;i < si;i++) { buffer_array[i] = NULL; buffSize_array[i] = 0; } format = NULL; index = 0; buf_elt_nb = si; if (manage_exclusion == true) mutex_array = new omni_mutex[si]; } // ---------------------------------------------------------------------------- EncodedAttribute::~EncodedAttribute() { for (int i = 0;i < buf_elt_nb;i++) SAFE_FREE(buffer_array[i]); SAFE_FREE(buffer_array); SAFE_FREE(buffSize_array); if (mutex_array != NULL) delete [] mutex_array; } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_jpeg_gray8(unsigned char *gray8,int width,int height,double quality) { if (manage_exclusion == true) mutex_array[index].lock(); SAFE_FREE(buffer_array[index]); buffSize_array[index] = 0; format = (char *)JPEG_GRAY_8; jpeg_encode_gray8(width,height,gray8,quality,&(buffSize_array[index]),&(buffer_array[index])); INC_INDEX() } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_jpeg_rgb32(unsigned char *rgb32,int width,int height,double quality) { if (manage_exclusion == true) mutex_array[index].lock(); SAFE_FREE(buffer_array[index]); buffSize_array[index] = 0; format = (char *)JPEG_RGB; jpeg_encode_rgb32(width,height,rgb32,quality,&(buffSize_array[index]),&(buffer_array[index])); INC_INDEX() } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_jpeg_rgb24(unsigned char *rgb24,int width,int height,double quality) { if (manage_exclusion == true) mutex_array[index].lock(); SAFE_FREE(buffer_array[index]); buffSize_array[index] = 0; format = (char *)JPEG_RGB; jpeg_encode_rgb24(width,height,rgb24,quality,&(buffSize_array[index]),&(buffer_array[index])); INC_INDEX() } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_gray8(unsigned char *gray8,int width,int height) { int newSize = width*height + 4; if (manage_exclusion == true) mutex_array[index].lock(); if( newSize!=buffSize_array[index] ) { SAFE_FREE(buffer_array[index]); buffer_array[index] = (unsigned char *)malloc(newSize); buffSize_array[index] = newSize; } format = (char *)GRAY_8; // Store image dimension (big endian) unsigned char *tmp_ptr = buffer_array[index]; tmp_ptr[0] = (unsigned char)( (width>>8) & 0xFF ); tmp_ptr[1] = (unsigned char)( width & 0xFF ); tmp_ptr[2] = (unsigned char)( (height>>8) & 0xFF ); tmp_ptr[3] = (unsigned char)( height & 0xFF ); // Copy image memcpy(tmp_ptr+4,gray8,newSize-4); INC_INDEX() } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_gray16(unsigned short *gray16,int width,int height) { int newSize = width*height*2 + 4; if (manage_exclusion == true) mutex_array[index].lock(); if( newSize!=buffSize_array[index] ) { SAFE_FREE(buffer_array[index]); buffer_array[index] = (unsigned char *)malloc(newSize); buffSize_array[index] = newSize; } format = (char *)GRAY_16; // Store image dimension (big endian) unsigned char *tmp_ptr = buffer_array[index]; tmp_ptr[0] = (unsigned char)( (width>>8) & 0xFF ); tmp_ptr[1] = (unsigned char)( width & 0xFF ); tmp_ptr[2] = (unsigned char)( (height>>8) & 0xFF ); tmp_ptr[3] = (unsigned char)( height & 0xFF ); // Store image (big endian) int srcIdx = 0; int dstIdx = 4; for(int j=0;j> 8); tmp_ptr[dstIdx++] = (unsigned char)(s & 0xFF); } } INC_INDEX() } // ---------------------------------------------------------------------------- void EncodedAttribute::encode_rgb24(unsigned char *rgb24,int width,int height) { int newSize = width*height*3 + 4; if (manage_exclusion == true) mutex_array[index].lock(); if( newSize!=buffSize_array[index] ) { SAFE_FREE(buffer_array[index]); buffer_array[index] = (unsigned char *)malloc(newSize); buffSize_array[index] = newSize; } format = (char *)RGB_24; // Store image dimension (big endian) unsigned char *tmp_ptr = buffer_array[index]; tmp_ptr[0] = (unsigned char)( (width>>8) & 0xFF ); tmp_ptr[1] = (unsigned char)( width & 0xFF ); tmp_ptr[2] = (unsigned char)( (height>>8) & 0xFF ); tmp_ptr[3] = (unsigned char)( height & 0xFF ); // Copy image memcpy(tmp_ptr+4,rgb24,newSize-4); } // ---------------------------------------------------------------------------- void EncodedAttribute::decode_rgb32(DeviceAttribute *attr,int *width,int *height,unsigned char **rgb32) { if (attr->is_empty()) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Attribute contains no data", (const char *)"EncodedAttribute::decode_gray8"); } DevVarEncodedArray_var &encDataSeq = attr->get_Encoded_data(); if (encDataSeq.operator->() == NULL) { ApiDataExcept::throw_exception((const char*)"API_IncompatibleAttrArgumentType", (const char*)"Cannot extract, data in DeviceAttribute object is not DevEncoded", (const char*)"EncodedAttribute::decode_gray8"); } string local_format(encDataSeq.in()[0].encoded_format); int isRGB = (strcmp(local_format.c_str() ,RGB_24 ) == 0); int isJPEG = (strcmp(local_format.c_str() ,JPEG_RGB ) == 0); if( !isRGB && !isJPEG ) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Not a color format", (const char *)"EncodedAttribute::decode_rgb32"); } unsigned char *rawBuff = NULL; DevVarEncodedArray &encData = encDataSeq.inout(); DevVarCharArray &encBuff = encData[0].encoded_data; int size = encBuff.length(); rawBuff = encBuff.get_buffer(false); if( isRGB ) { // Get width and height int wh = ((int)rawBuff[0] & 0xFF); int wl = ((int)rawBuff[1] & 0xFF); wh = wh << 8; int iWidth = wh | wl; int hh = ((int)rawBuff[2] & 0xFF); int hl = ((int)rawBuff[3] & 0xFF); hh = hh << 8; int iHeight = hh | hl; unsigned char *data = new unsigned char[iWidth*iHeight*4]; // Convert to RGB32 int srcIdx = 4; int dstIdx = 0; for(int j=0;jis_empty()) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Attribute contains no data", (const char *)"EncodedAttribute::decode_gray8"); } DevVarEncodedArray_var &encDataSeq = attr->get_Encoded_data(); if (encDataSeq.operator->() == NULL) { ApiDataExcept::throw_exception((const char*)"API_IncompatibleAttrArgumentType", (const char*)"Cannot extract, data in DeviceAttribute object is not DevEncoded", (const char*)"EncodedAttribute::decode_gray8"); } string local_format(encDataSeq.in()[0].encoded_format); int isGrey = (strcmp(local_format.c_str() ,GRAY_8 ) == 0); int isJPEG = (strcmp(local_format.c_str() ,JPEG_GRAY_8 ) == 0); if( !isGrey && !isJPEG ) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Not a grayscale 8bit format", (const char *)"EncodedAttribute::decode_gray8"); } unsigned char *rawBuff = NULL; DevVarEncodedArray &encData = encDataSeq.inout(); DevVarCharArray &encBuff = encData[0].encoded_data; int size = encBuff.length(); rawBuff = encBuff.get_buffer(false); if( isGrey ) { // Get width and height int wh = ((int)rawBuff[0] & 0xFF); int wl = ((int)rawBuff[1] & 0xFF); wh = wh << 8; int iWidth = wh | wl; int hh = ((int)rawBuff[2] & 0xFF); int hl = ((int)rawBuff[3] & 0xFF); hh = hh << 8; int iHeight = hh | hl; unsigned char *data = new unsigned char[iWidth*iHeight]; memcpy(data,&(rawBuff[4]),iWidth*iHeight); *gray8 = data; *width = iWidth; *height = iHeight; return; } if( isJPEG ) { int jFormat; int err = jpeg_decode(size,&(rawBuff[0]),width,height,&jFormat,gray8); if(err) { TangoSys_OMemStream o; o << jpeg_get_error_msg(err); Except::throw_exception((const char *)API_DecodeErr, o.str(), (const char *)"EncodedAttribute::decode_gray8"); } if( jFormat!=JPEG_GRAY_FORMAT ) { // Should not happen Except::throw_exception((const char *)API_WrongFormat, (const char *)"Not a grayscale 8bit format", (const char *)"EncodedAttribute::decode_gray8"); } return; } } // ---------------------------------------------------------------------------- void EncodedAttribute::decode_gray16(DeviceAttribute *attr,int *width,int *height,unsigned short **gray16) { if (attr->is_empty()) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Attribute contains no data", (const char *)"EncodedAttribute::decode_gray16"); } DevVarEncodedArray_var &encDataSeq = attr->get_Encoded_data(); if (encDataSeq.operator->() == NULL) { ApiDataExcept::throw_exception((const char*)"API_IncompatibleAttrArgumentType", (const char*)"Cannot extract, data in DeviceAttribute object is not DevEncoded", (const char*)"EncodedAttribute::decode_gray16"); } string local_format(encDataSeq.in()[0].encoded_format); int isGrey = (strcmp(local_format.c_str() ,GRAY_16 ) == 0); if( !isGrey ) { Except::throw_exception((const char *)API_WrongFormat, (const char *)"Not a grayscale 16 bits format", (const char *)"EncodedAttribute::decode_gray16"); } unsigned char *rawBuff = NULL; DevVarEncodedArray &encData = encDataSeq.inout(); DevVarCharArray &encBuff = encData[0].encoded_data; rawBuff = encBuff.get_buffer(false); if( isGrey ) { // Get width and height int wh = ((int)rawBuff[0] & 0xFF); int wl = ((int)rawBuff[1] & 0xFF); wh = wh << 8; int iWidth = wh | wl; int hh = ((int)rawBuff[2] & 0xFF); int hl = ((int)rawBuff[3] & 0xFF); hh = hh << 8; int iHeight = hh | hl; unsigned short *data = new unsigned short[ iWidth*iHeight*2 ]; int srcIdx = 4; int dstIdx = 0; for(int j=0;j. // // $Revision: 30340 $ // //-================================================================================================================= #include #include namespace Tango { //+---------------------------------------------------------------------------------------------------------------- // // method : // DServer::event_subscription_change() // // description : // method to execute the command EventSubscriptionChange command. // // args : // in : // - argin : The command input argument // // returns : // The command output data (Tango lib release number) // //------------------------------------------------------------------------------------------------------------------ DevLong DServer::event_subscription_change(const Tango::DevVarStringArray *argin) { if (argin->length() < 4) { TangoSys_OMemStream o; o << "Not enough input arguments, needs 4 i.e. device name, attribute name, action, event name" << ends; Except::throw_exception((const char *)API_WrongNumberOfArgs, o.str(), (const char *)"DServer::event_subscription_change"); } string dev_name, attr_name, action, event, attr_name_lower; dev_name = (*argin)[0]; attr_name = (*argin)[1]; action = (*argin)[2]; event = (*argin)[3]; attr_name_lower = attr_name; transform(attr_name_lower.begin(),attr_name_lower.end(),attr_name_lower.begin(),::tolower); cout4 << "EventSubscriptionChangeCmd: subscription for device " << dev_name << " attribute " << attr_name << " action " << action << " event " << event << endl; Tango::Util *tg = Tango::Util::instance(); // // If we receive this command while the DS is in its shuting down sequence, do nothing // if (tg->get_heartbeat_thread_object() == NULL) { TangoSys_OMemStream o; o << "The device server is shutting down! You can no longer subscribe for events" << ends; Except::throw_exception((const char *)API_ShutdownInProgress, o.str(), (const char *)"DServer::event_subscription_change"); } // // If the EventSupplier object is not created, create it right now // NotifdEventSupplier *ev; if ((ev = tg->get_notifd_event_supplier()) == NULL) { tg->create_notifd_event_supplier(); ev = tg->get_notifd_event_supplier(); } // // If we are using a file as database, gives port number to event supplier // if (Util::_FileDb == true && ev != NULL) { ev->file_db_svr(); } string mcast; int rate,ivl; // // Check if the request comes from a Tango 6 client (without client identification) // If true, the event has to be sent using AttributeValue_3 data structure // If cl is NULL, this means that the call is local (Two tango classes within the same process and with events between // device from class 1 and device from classs 2) // int client_release = 0; client_addr *cl = get_client_ident(); if (cl == NULL) client_release = 4; else { if (cl->client_ident == true) client_release = 4; else client_release = 3; } event_subscription(dev_name,attr_name,action,event,attr_name_lower,NOTIFD,mcast,rate,ivl,NULL,client_release); // // Init one subscription command flag in Eventsupplier // if (ev != NULL && ev->get_one_subscription_cmd() == false) ev->set_one_subscription_cmd(true); // // Return to caller // Tango::DevLong ret_val = (Tango::DevLong)tg->get_tango_lib_release(); return ret_val; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::event_subscription() // // description : // method to do all the necessary checks on attribute config to generate events // // args : // in : // - dev_name : The device name // - obj_name : The attribute/pipe name // - action : What the user want to do // - event : The event type // - obj_name_lower : The attribute/pipe name in lower case letters // - ct : The channel type (notifd or zmq) // - mcast_data : The multicast transport data // - rate : PGM rate parameter // - ivl : PGM ivl paramteter // - dev : The device pointer // - client_lib : Tango release number used by client // //-------------------------------------------------------------------------------------------------------------------- void DServer::event_subscription(string &dev_name,string &obj_name,string &action,string &event,string &obj_name_lower, ChannelType ct,string &mcast_data,int &rate,int &ivl,DeviceImpl *dev,int client_lib) { Tango::Util *tg = Tango::Util::instance(); // // Get device reference // DeviceImpl *dev_impl = dev; if (dev_impl == NULL) { try { dev_impl = tg->get_device_by_name(dev_name); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << dev_name << " not found" << ends; Except::re_throw_exception(e,(const char *)API_DeviceNotFound,o.str(), (const char *)"DServer::event_subscription"); } } if (event != EventName[INTERFACE_CHANGE_EVENT] && event != EventName[PIPE_EVENT]) { MultiAttribute *m_attr = dev_impl->get_device_attr(); int attr_ind = m_attr->get_attr_ind_by_name(obj_name.c_str()); Attribute &attribute = m_attr->get_attr_by_ind(attr_ind); // // Refuse subscription on forwarded attribute and notifd // if (ct == NOTIFD) { if (attribute.is_fwd_att() == true) { stringstream ss; ss << "The attribute " << obj_name << " is a forwarded attribute."; ss << "\nIt is not supported to subscribe events from forwarded attribute using Tango < 9. Please update!!"; Except::throw_exception(API_NotSupportedFeature, ss.str(),"DServer::event_subscription"); } } else { if (attribute.is_fwd_att() == true && client_lib < 5) { stringstream ss; ss << "The attribute " << obj_name << " is a forwarded attribute."; ss << "\nIt is not supported to subscribe events from forwarded attribute using Tango < 9. Please update!!"; Except::throw_exception(API_NotSupportedFeature, ss.str(),"DServer::event_subscription"); } } if (action == "subscribe") { if (event == "user_event") { cout4 << "DServer::event_subscription(): update user_event subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); switch (client_lib) { case 5: attribute.event_user5_subscription = time(NULL); break; case 4: attribute.event_user4_subscription = time(NULL); break; default: attribute.event_user3_subscription = time(NULL); break; } } else if (event.find(CONF_TYPE_EVENT) != string::npos) { cout4 << "DServer::event_subscription(): update attr_conf subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); if (client_lib == 5) attribute.event_attr_conf5_subscription = time(NULL); else attribute.event_attr_conf_subscription = time(NULL); } else if (event == "data_ready") { if (attribute.is_fwd_att() == false && attribute.is_data_ready_event() == false) { TangoSys_OMemStream o; o << "The attribute "; o << obj_name; o << " is not data ready event enabled" << ends; Except::throw_exception(API_AttributeNotDataReadyEnabled, o.str(), "DServer::event_subscription"); } cout4 << "DServer::event_subscription(): update data_ready subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); attribute.event_data_ready_subscription = time(NULL); } else { // // If the polling is necessary to send events, check whether the polling is started for the requested attribute. // if (attribute.is_polled() == false ) { TangoSys_OMemStream o; o << "The polling (necessary to send events) for the attribute "; o << obj_name; o << " is not started" << ends; if ( event == "change") { if (attribute.is_fwd_att() == false && attribute.is_change_event() == false) { Except::throw_exception(API_AttributePollingNotStarted,o.str(), "DServer::event_subscription"); } } else { if ( event == "archive") { if (attribute.is_fwd_att() == false && attribute.is_archive_event() == false) { Except::throw_exception(API_AttributePollingNotStarted,o.str(), "DServer::event_subscription"); } } else { if (attribute.is_fwd_att() == false) Except::throw_exception(API_AttributePollingNotStarted,o.str(),"DServer::event_subscription"); } } } if (event == "change") { cout4 << "DServer::event_subscription(): update change subscription\n"; // // Check if the attribute has some of the change properties defined // if (obj_name_lower != "state") { if ((attribute.get_data_type() != Tango::DEV_STRING) && (attribute.get_data_type() != Tango::DEV_BOOLEAN) && (attribute.get_data_type() != Tango::DEV_ENCODED) && (attribute.get_data_type() != Tango::DEV_STATE) && (attribute.get_data_type() != Tango::DEV_ENUM)) { if ( attribute.is_check_change_criteria() == true ) { if ((attribute.rel_change[0] == INT_MAX) && (attribute.rel_change[1] == INT_MAX) && (attribute.abs_change[0] == INT_MAX) && (attribute.abs_change[1] == INT_MAX)) { TangoSys_OMemStream o; o << "Event properties (abs_change or rel_change) for attribute "; o << obj_name; o << " are not set" << ends; Except::throw_exception(API_EventPropertiesNotSet, o.str(),"DServer::event_subscription"); } } } } omni_mutex_lock oml(EventSupplier::get_event_mutex()); switch (client_lib) { case 5: attribute.event_change5_subscription = time(NULL); break; case 4: attribute.event_change4_subscription = time(NULL); break; default: attribute.event_change3_subscription = time(NULL); break; } } else if (event == "quality") { cout4 << "DServer::event_subscription(): update quality_change subscription\n"; attribute.event_quality_subscription = time(NULL); } else if (event == "periodic") { cout4 << "DServer::event_subscription(): update periodic subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); switch (client_lib) { case 5: attribute.event_periodic5_subscription = time(NULL); break; case 4: attribute.event_periodic4_subscription = time(NULL); break; default: attribute.event_periodic3_subscription = time(NULL); break; } } else if (event == "archive") { // // Check if the attribute has some of the archive properties defined // if (obj_name_lower != "state") { if ((attribute.get_data_type() != Tango::DEV_STRING) && (attribute.get_data_type() != Tango::DEV_BOOLEAN) && (attribute.get_data_type() != Tango::DEV_ENCODED) && (attribute.get_data_type() != Tango::DEV_STATE) && (attribute.get_data_type() != Tango::DEV_ENUM)) { if ( attribute.is_check_archive_criteria() == true ) { if ((attribute.archive_abs_change[0] == INT_MAX) && (attribute.archive_abs_change[1] == INT_MAX) && (attribute.archive_rel_change[0] == INT_MAX) && (attribute.archive_rel_change[1] == INT_MAX) && (attribute.archive_period == INT_MAX)) { TangoSys_OMemStream o; o << "Archive event properties (archive_abs_change or archive_rel_change or archive_period) for attribute "; o << obj_name; o << " are not set" << ends; Except::throw_exception(API_EventPropertiesNotSet, o.str(),"DServer::event_subscription"); } } } } cout4 << "DServer::event_subscription(): update archive subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); switch (client_lib) { case 5: attribute.event_archive5_subscription = time(NULL); break; case 4: attribute.event_archive4_subscription = time(NULL); break; default: attribute.event_archive3_subscription = time(NULL); break; } } } // // Set channel type in attribute object // if (ct == ZMQ) attribute.set_use_zmq_event(); else attribute.set_use_notifd_event(); // // Check if multicast has to be used for event transport (only for ZMQ event) // Don't forget syntax in attribute mcast_event string: // event_name:ip_address:port:rate:ivl // The last two are not optionals // if (ct == ZMQ) { bool found = false; ZmqEventSupplier *ev; ev = tg->get_zmq_event_supplier(); int zmq_release = ev->get_zmq_release(); for(unsigned int i = 0;i != attribute.mcast_event.size();++i) { if (attribute.mcast_event[i].find(event) == 0) { if (zmq_release < 320) { int zmq_major,zmq_minor,zmq_patch; zmq_version(&zmq_major,&zmq_minor,&zmq_patch); TangoSys_OMemStream o; o << "Device server process is using zmq release "; o << zmq_major << "." << zmq_minor << "." << zmq_patch; o << "\nMulticast event(s) not available with this ZMQ release" << ends; Except::throw_exception(API_UnsupportedFeature, o.str(),"DServer::event_subscription"); } string::size_type start,end; start = attribute.mcast_event[i].find(':'); start++; end = attribute.mcast_event[i].find(':',start); if ((end = attribute.mcast_event[i].find(':',end + 1)) == string::npos) { mcast_data = attribute.mcast_event[i].substr(start); rate = 0; ivl = 0; found = true; break; } else { mcast_data = attribute.mcast_event[i].substr(start,end - start); // // Get rate because one is defined // string::size_type start_rate = end + 1; if ((end = attribute.mcast_event[i].find(':',start_rate)) == string::npos) { istringstream iss(attribute.mcast_event[i].substr(start_rate)); iss >> rate; rate = rate * 1024; ivl = 0; found = true; break; } else { istringstream iss(attribute.mcast_event[i].substr(start_rate,end - start_rate)); iss >> rate; rate = rate * 1024; // // Get ivl because one is defined // istringstream iss_ivl(attribute.mcast_event[i].substr(end + 1)); iss_ivl >> ivl; ivl = ivl * 1000; found = true; break; } } } } if (found == false) { rate = 0; ivl = 0; } // // If one of the 2 parameters are not defined, get the default value // if (rate == 0) rate = mcast_rate; if (ivl == 0) ivl = mcast_ivl; } else { rate = 0; ivl = 0; } } // // Memorize client lib release. Protect this setting in case of user thread pushing event when the subscription // command is received // if (client_lib != 0) { omni_mutex_lock oml(EventSupplier::get_event_mutex()); attribute.set_client_lib(client_lib,event); } } else if (event == EventName[PIPE_EVENT]) { if (action == "subscribe") { DeviceClass *cl = dev_impl->get_device_class(); Pipe &pi = cl->get_pipe_by_name(obj_name,dev_impl->get_name_lower()); cout4 << "DServer::event_subscription(): update pipe subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); pi.set_event_subscription(time(NULL)); // TODO: Pipe: Do we support multicast for pipe event rate = 0; ivl = 0; } } else { if (action == "subscribe") { cout4 << "DServer::event_subscription(): update device interface_change subscription\n"; omni_mutex_lock oml(EventSupplier::get_event_mutex()); dev_impl->set_event_intr_change_subscription(time(NULL)); // TODO: Do we support multicast for interface change event rate = 0; ivl = 0; if (client_lib != 0) dev_impl->set_client_lib(client_lib); } } // // Ask polling thread in charge of heartbeat to send them (if not already done) // if (action == "subscribe") { try { if (get_heartbeat_started() == false) { add_event_heartbeat(); set_heartbeat_started(true); } } catch (...) { } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // DServer::zmq_event_subscription_change() // // description : // method to execute the command ZmqEventSubscriptionChange command. // // args : // in : // - argin : The command input argument // // returns : // The command output data (Tango lib release number) // //------------------------------------------------------------------------------------------------------------------- DevVarLongStringArray *DServer::zmq_event_subscription_change(const Tango::DevVarStringArray *argin) { if (argin->length() > 1 && argin->length() < 4) { TangoSys_OMemStream o; o << "Not enough input arguments, needs at least 4 i.e. device name, attribute/pipe name, action, event name, " << ends; Except::throw_exception((const char *)API_WrongNumberOfArgs, o.str(), (const char *)"DServer::zmq_event_subscription_change"); } Tango::Util *tg = Tango::Util::instance(); Tango::DevVarLongStringArray *ret_data = Tango_nullptr; if (argin->length() == 1) { string arg((*argin)[0]); transform(arg.begin(),arg.end(),arg.begin(),::tolower); if (arg != "info") { TangoSys_OMemStream o; o << "Not enough input arguments, needs 4 i.e. device name, attribute/pipe name, action, event name" << ends; Except::throw_exception((const char *)API_WrongNumberOfArgs, o.str(), (const char *)"DServer::zmq_event_subscription_change"); } // // It's just the call to help debugging. Returns event configuration // ret_data = new Tango::DevVarLongStringArray(); ret_data->svalue.length(2); ret_data->lvalue.length(1); ret_data->lvalue[0] = (Tango::DevLong)tg->get_tango_lib_release();; ZmqEventSupplier *ev; if ((ev = tg->get_zmq_event_supplier()) != NULL) { string tmp_str("Heartbeat: "); tmp_str = tmp_str + ev->get_heartbeat_endpoint(); ret_data->svalue[0] = CORBA::string_dup(tmp_str.c_str()); tmp_str = "Event: "; string ev_end = ev->get_event_endpoint(); if (ev_end.size() != 0) tmp_str = "Event: " + ev_end; size_t nb_mcast = ev->get_mcast_event_nb(); if (nb_mcast != 0) { if (ev_end.size() != 0) tmp_str = tmp_str + "\n"; tmp_str = tmp_str + "Some event(s) sent using multicast protocol"; } ret_data->svalue[1] = CORBA::string_dup(tmp_str.c_str()); size_t nb_alt = ev->get_alternate_heartbeat_endpoint().size(); if (nb_alt != 0) { ret_data->svalue.length((nb_alt + 1) << 1); for (size_t loop = 0;loop < nb_alt;loop++) { string tmp_str("Alternate heartbeat: "); tmp_str = tmp_str + ev->get_alternate_heartbeat_endpoint()[loop]; ret_data->svalue[(loop + 1) << 1] = CORBA::string_dup(tmp_str.c_str()); tmp_str = "Alternate event: "; if (ev->get_alternate_event_endpoint().size() != 0) { string ev_end = ev->get_alternate_event_endpoint()[loop]; if (ev_end.empty() == false) tmp_str = "Alternate event: " + ev_end; } ret_data->svalue[((loop + 1) << 1) + 1] = CORBA::string_dup(tmp_str.c_str()); } } } else { ret_data->svalue[0] = CORBA::string_dup("No ZMQ event yet!"); } } else { string dev_name, obj_name, action, event, obj_name_lower; dev_name = (*argin)[0]; obj_name = (*argin)[1]; action = (*argin)[2]; event = (*argin)[3]; // // Check event type validity // string check_event = event; transform(check_event.begin(),check_event.end(),check_event.begin(),::tolower); string::size_type pos_check = check_event.find(EVENT_COMPAT); if (pos_check != string::npos) check_event.erase(0,EVENT_COMPAT_IDL5_SIZE); size_t nb_event_type = sizeof(EventName)/sizeof(char *); bool found = false; for (size_t loop = 0;loop < nb_event_type;loop++) { if (strcmp(check_event.c_str(),EventName[loop]) == 0) { found = true; break; } } if (found == false) { stringstream ss; ss << "The event type you sent (" << event << ") is not valid event type"; Except::throw_exception(API_WrongNumberOfArgs,ss.str(),"DServer::zmq_event_subscription_change"); } bool intr_change = false; if (event == EventName[INTERFACE_CHANGE_EVENT]) intr_change = true; bool pipe_event = false; if (event == EventName[PIPE_EVENT]) pipe_event = true; obj_name_lower = obj_name; transform(obj_name_lower.begin(),obj_name_lower.end(),obj_name_lower.begin(),::tolower); int client_release = 4; if (event == EventName[ATTR_CONF_EVENT]) client_release = 3; if (argin->length() == 5) { stringstream ss; ss << (*argin)[4]; ss >> client_release; if (client_release == 0) { string::size_type pos = event.find(EVENT_COMPAT); if (pos != string::npos) { string client_lib_str = event.substr(pos + 3,1); stringstream ss; ss << client_lib_str; ss >> client_release; event.erase(0,EVENT_COMPAT_IDL5_SIZE); } else { if (event == EventName[ATTR_CONF_EVENT]) client_release = 3; else { // // Check if the request comes from a Tango 6 client (without client identification) // If true, the event has to be sent using AttributeValue_3 data structure // If cl is NULL, this means that the call is local (Two tango classes within the same process and with events between // device from class 1 and device from classs 2) // client_addr *cl = get_client_ident(); if (cl == NULL) client_release = 4; else { if (cl->client_ident == true) client_release = 4; else client_release = 3; } } } } } cout4 << "ZmqEventSubscriptionChangeCmd: subscription for device " << dev_name << " attribute/pipe " << obj_name << " action " << action << " event " << event << " client lib = " << client_release << endl; // // If we receive this command while the DS is in its shuting down sequence, do nothing // if (tg->get_heartbeat_thread_object() == NULL) { TangoSys_OMemStream o; o << "The device server is shutting down! You can no longer subscribe for events" << ends; Except::throw_exception((const char *)API_ShutdownInProgress, o.str(), (const char *)"DServer::zmq_event_subscription_change"); } // // If the EventSupplier object is not created, create it right now // ZmqEventSupplier *ev; if ((ev = tg->get_zmq_event_supplier()) == NULL) { tg->create_zmq_event_supplier(); ev = tg->get_zmq_event_supplier(); } // // Get device pointer and check which IDL release it implements. If it is less than IDL 4, refuse to use ZMQ event. // To do so, simulate a Tango 7 DS (throw command not exist exception) // Also change event name if both device and client supports IDL5 and lib 9 (For attribute conf. change event) // DeviceImpl *dev = NULL; try { dev = tg->get_device_by_name(dev_name); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << dev_name << " not found" << ends; Except::re_throw_exception(e,(const char *)API_DeviceNotFound,o.str(), (const char *)"DServer::event_subscription"); } long idl_vers = dev->get_dev_idl_version(); if (idl_vers < 4) { TangoSys_OMemStream o; o << "Device " << dev_name << " too old to use ZMQ event (it does not implement IDL 4)"; o << "\nSimulate a CommandNotFound exception to move to notifd event system" << ends; Except::throw_exception((const char *)API_CommandNotFound, o.str(), (const char *)"DServer::zmq_event_subscription_change"); } if (client_release > idl_vers) client_release = idl_vers; // // Call common method (common between old and new command) // string mcast; int rate,ivl; string::size_type pos = event.find(EVENT_COMPAT); if (pos != string::npos) event.erase(0,EVENT_COMPAT_IDL5_SIZE); event_subscription(dev_name,obj_name,action,event,obj_name_lower,ZMQ,mcast,rate,ivl,dev,client_release); // // Check if the client is a new one // bool new_client = ev->update_connected_client(get_client_ident()); if (new_client == true) ev->set_double_send(); // // Create the event publisher socket (if not already done). Take care for case where the device is running with db // in a file // string ev_name = ev->get_fqdn_prefix(); if (Util::_FileDb == true) { int size = ev_name.size(); if (ev_name[size - 1] == '#') ev_name.erase(size - 1); } ev_name = ev_name + dev->get_name_lower(); if (intr_change == false) ev_name = ev_name + '/' + obj_name_lower; if (Util::_FileDb == true && ev != NULL) ev_name = ev_name + MODIFIER_DBASE_NO; ev_name = ev_name + '.' + event; // // If the event is defined as using mcast transport, get caller host // bool local_call = false; if (mcast.empty() == false) { client_addr *c_addr = get_client_ident(); if ((c_addr->client_ip[5] == 'u') || ((c_addr->client_ip[9] == '1') && (c_addr->client_ip[10] == '2') && (c_addr->client_ip[11] == '7'))) { local_call = true; } } // // Create ZMQ event socket // if (mcast.empty() == false) ev->create_mcast_event_socket(mcast,ev_name,rate,local_call); else ev->create_event_socket(); // // Init event counter in Event Supplier // ev->init_event_cptr(ev_name); // // Init one subscription command flag in Eventsupplier // if (ev->get_one_subscription_cmd() == false) ev->set_one_subscription_cmd(true); // // For forwarded attribute, eventually subscribe to events coming from root attribute // if (intr_change == false && pipe_event == false) { Attribute &attribute = dev->get_device_attr()->get_attr_by_name(obj_name.c_str()); EventType et; tg->event_name_2_event_type(event,et); if (attribute.is_fwd_att() == true && et != ATTR_CONF_EVENT) { FwdAttribute &fwd_att = static_cast(attribute); string root_name = fwd_att.get_fwd_dev_name() + "/" + fwd_att.get_fwd_att_name(); RootAttRegistry &rar = tg->get_root_att_reg(); bool already_there = rar.is_event_subscribed(root_name,et); // // We unsubscribe and subscribe. This is mandatory for following case: The appli is killed and re-started // but in the meantime, polling for the root attribute has been stopped. The error that the polling is not started // for the root attribute is sent at subscription time // if (already_there == true) rar.unsubscribe_user_event(fwd_att.get_fwd_dev_name(),fwd_att.get_fwd_att_name(),et); rar.subscribe_user_event(fwd_att.get_fwd_dev_name(),fwd_att.get_fwd_att_name(),et); } } // // Init data returned by command // ret_data = new Tango::DevVarLongStringArray(); ret_data->lvalue.length(6); ret_data->svalue.length(2); ret_data->lvalue[0] = (Tango::DevLong)tg->get_tango_lib_release(); ret_data->lvalue[1] = dev->get_dev_idl_version(); ret_data->lvalue[2] = zmq_sub_event_hwm; ret_data->lvalue[3] = rate; ret_data->lvalue[4] = ivl; ret_data->lvalue[5] = ev->get_zmq_release(); string &heartbeat_endpoint = ev->get_heartbeat_endpoint(); ret_data->svalue[0] = CORBA::string_dup(heartbeat_endpoint.c_str()); if (mcast.empty() == true) { string &event_endpoint = ev->get_event_endpoint(); ret_data->svalue[1] = CORBA::string_dup(event_endpoint.c_str()); } else { if (local_call == true) { string &event_endpoint = ev->get_event_endpoint(); ret_data->svalue[1] = CORBA::string_dup(event_endpoint.c_str()); } else { string &event_endpoint = ev->get_mcast_event_endpoint(ev_name); ret_data->svalue[1] = CORBA::string_dup(event_endpoint.c_str()); } } size_t nb_alt = ev->get_alternate_heartbeat_endpoint().size(); if (nb_alt != 0) { ret_data->svalue.length((nb_alt + 1) << 1); for (size_t loop = 0;loop < nb_alt;loop++) { string tmp_str = ev->get_alternate_heartbeat_endpoint()[loop]; ret_data->svalue[(loop + 1) << 1] = CORBA::string_dup(tmp_str.c_str()); tmp_str = ev->get_alternate_event_endpoint()[loop]; ret_data->svalue[((loop + 1) << 1) + 1] = CORBA::string_dup(tmp_str.c_str()); } } } return ret_data; } //+----------------------------------------------------------------------------------------------------------------- // // method : // DServer::event_confirm_subscription() // // description : // method to execute the command EventConfirmSubscription command. // // args : // in : // - argin : The command input argument // //------------------------------------------------------------------------------------------------------------------ void DServer::event_confirm_subscription(const Tango::DevVarStringArray *argin) { // // Some check on argument // if ((argin->length() == 0) || (argin->length() % 3) != 0) { TangoSys_OMemStream o; o << "Wrong number of input arguments: 3 needed per event: device name, attribute/pipe name and event name" << endl; Except::throw_exception((const char *)API_WrongNumberOfArgs,o.str(), (const char *)"DServer::event_confirm_subscription"); } // // If we receive this command while the DS is in its shuting down sequence, do nothing // Tango::Util *tg = Tango::Util::instance(); if (tg->get_heartbeat_thread_object() == NULL) { TangoSys_OMemStream o; o << "The device server is shutting down! You can no longer subscribe for events" << ends; Except::throw_exception((const char *)API_ShutdownInProgress, o.str(), (const char *)"DServer::event_confirm_subscription"); } // // A loop for each event // unsigned int nb_event = argin->length() / 3; string old_dev; DeviceImpl *dev = NULL; for (unsigned int loop = 0;loop < nb_event;loop++) { string dev_name, obj_name, event, obj_name_lower; int base = loop * 3; dev_name = (*argin)[base]; obj_name = (*argin)[base + 1]; event = (*argin)[base + 2]; obj_name_lower = obj_name; transform(obj_name_lower.begin(),obj_name_lower.end(),obj_name_lower.begin(),::tolower); cout4 << "EventConfirmSubscriptionCmd: confirm subscription for device " << dev_name << " attribute/pipe " << obj_name << " event " << event << endl; // // Find device // if (old_dev != dev_name) { try { dev = tg->get_device_by_name(dev_name); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << dev_name << " not found" << ends; Except::re_throw_exception(e,(const char *)API_DeviceNotFound,o.str(), (const char *)"DServer::event_confirm_subscription"); } old_dev = dev_name; } // // Call common method (common between old and new command) // string mcast; int rate,ivl,client_lib; string action("subscribe"); string client_lib_str; string::size_type pos = event.find(EVENT_COMPAT); if (pos != string::npos) { client_lib_str = event.substr(pos + 3,1); stringstream ss; ss << client_lib_str; ss >> client_lib; event.erase(0,EVENT_COMPAT_IDL5_SIZE); } else { if (event == EventName[ATTR_CONF_EVENT]) client_lib = 3; else client_lib = 4; // Command implemented only with Tango 8 -> IDL 4 for event data } event_subscription(dev_name,obj_name,action,event,obj_name_lower,ZMQ,mcast,rate,ivl,dev,client_lib); } } } // namespace tango-9.2.5a/lib/cpp/server/eventsupplier.cpp0000644023471100065110000024171513034745001016204 00000000000000static const char *RcsId = "$Id: eventsupplier.cpp 28408 2015-08-26 13:22:42Z taurel $"; //==================================================================================================================== // // file : eventsupplier.cpp // // description : C++ classes for implementing the event server and client singleton classes - EventSupplier // This class is used to send events from the server // // author(s) : E.Taurel (taurel@esrf.fr) // // original : 29 June 2004 // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28408 $ // // //==================================================================================================================== #include #include #ifdef _TG_WINDOWS_ #include #endif // _TG_WINDOWS_ namespace Tango { omni_mutex EventSupplier::event_mutex; omni_mutex EventSupplier::detect_mutex; omni_mutex EventSupplier::push_mutex; omni_condition EventSupplier::push_cond(&EventSupplier::push_mutex); string EventSupplier::fqdn_prefix; //--------------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::EventSupplier() // // description : // EventSupplier class ctor // // argument : // in : // - tg : ptr to the Util class singleton // //-------------------------------------------------------------------------------------------------------------------- EventSupplier::EventSupplier(Util *tg):one_subscription_cmd(false) { if (fqdn_prefix.empty() == true) { fqdn_prefix = "tango://"; if (Util::_UseDb == false || Util::_FileDb == true) fqdn_prefix = fqdn_prefix + tg->get_host_name() + ':' + tg->get_svr_port_num() + '/'; else { Database *db = tg->get_database(); fqdn_prefix = fqdn_prefix + db->get_db_host() + ':' + db->get_db_port() + '/'; } transform(fqdn_prefix.begin(),fqdn_prefix.end(),fqdn_prefix.begin(),::tolower); } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::detect_and_push_events() // // description : // Method to detect if it is necessary to push an event // // argument : // in : // - device_impl : The device // - attr_value : The attribute value // - except : The exception thrown during the last attribute reading. NULL if no exception // - attr_name : The attribute name // - time_bef_attr : Exact date when the attribute has been read // //-------------------------------------------------------------------------------------------------------------------- SendEventType EventSupplier::detect_and_push_events(DeviceImpl *device_impl,struct SuppliedEventData &attr_value, DevFailed *except,string &attr_name,struct timeval *time_bef_attr) { string event, domain_name; time_t now, change3_subscription, periodic3_subscription, archive3_subscription; time_t change4_subscription, periodic4_subscription,archive4_subscription; time_t change5_subscription, periodic5_subscription,archive5_subscription; SendEventType ret; cout3 << "EventSupplier::detect_and_push_events(): called for attribute " << attr_name << endl; Attribute &attr = device_impl->dev_attr->get_attr_by_name(attr_name.c_str()); now = time(NULL); { omni_mutex_lock oml(event_mutex); change3_subscription = now - attr.event_change3_subscription; periodic3_subscription = now - attr.event_periodic3_subscription; archive3_subscription = now - attr.event_archive3_subscription; change4_subscription = now - attr.event_change4_subscription; periodic4_subscription = now - attr.event_periodic4_subscription; archive4_subscription = now - attr.event_archive4_subscription; change5_subscription = now - attr.event_change5_subscription; periodic5_subscription = now - attr.event_periodic5_subscription; archive5_subscription = now - attr.event_archive5_subscription; } cout3 << "EventSupplier::detect_and_push_events(): last subscription for change5 " << change5_subscription << " periodic5 " << periodic5_subscription << " archive5 " << archive5_subscription << endl; // // For change event // First check if it is necessary to send the event in case clients are not there any more // ret.change = false; vector client_libs = attr.get_client_lib(CHANGE_EVENT); // We want a copy vector::iterator ite; for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (change5_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(5,string(EventName[CHANGE_EVENT])); break; case 4: if (change4_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(4,string(EventName[CHANGE_EVENT])); break; default: if (change3_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(3,string(EventName[CHANGE_EVENT])); break; } } if (client_libs.empty() == false) { if (detect_and_push_change_event(device_impl,attr_value,attr,attr_name,except) == true) ret.change = true; } // // For periodic event // ret.periodic = false; client_libs.clear(); client_libs = attr.get_client_lib(PERIODIC_EVENT); // We want a copy for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (periodic5_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(5,string(EventName[PERIODIC_EVENT])); break; case 4: if (periodic4_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(4,string(EventName[PERIODIC_EVENT])); break; default: if (periodic3_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(3,string(EventName[PERIODIC_EVENT])); break; } } if (client_libs.empty() == false) { if (detect_and_push_periodic_event(device_impl,attr_value,attr,attr_name,except,time_bef_attr) == true) ret.periodic = true; } // // For archive event // ret.archive = false; client_libs.clear(); client_libs = attr.get_client_lib(ARCHIVE_EVENT); // We want a copy for (ite = client_libs.begin();ite != client_libs.end();++ite) { switch (*ite) { case 5: if (archive5_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(5,string(EventName[ARCHIVE_EVENT])); break; case 4: if (archive4_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(4,string(EventName[ARCHIVE_EVENT])); break; default: if (archive3_subscription >= EVENT_RESUBSCRIBE_PERIOD) attr.remove_client_lib(3,string(EventName[ARCHIVE_EVENT])); break; } } if (client_libs.empty() == false) { if (detect_and_push_archive_event(device_impl,attr_value,attr,attr_name,except,time_bef_attr) == true) ret.archive = true; } return ret; } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::detect_and_push_change_event() // // description : // Method to detect if there it is necessary to push a change event // // argument : // in : // - device_impl : The device // - attr_value : The attribute value // - attr : The attribute object // - attr_name : The attribute name // - except : The exception thrown during the last attribute reading. NULL if no exception // - user_push : Flag set to true if it is a user push // //-------------------------------------------------------------------------------------------------------------------- bool EventSupplier::detect_and_push_change_event(DeviceImpl *device_impl,struct SuppliedEventData &attr_value, Attribute &attr,string &attr_name,DevFailed *except,bool user_push) { string event, domain_name; double delta_change_rel = 0.0; double delta_change_abs = 0.0; bool is_change = false; bool force_change = false; bool quality_change = false; bool ret = false; cout3 << "EventSupplier::detect_and_push_change_event(): called for attribute " << attr_name << endl; Tango::AttrQuality the_quality; if (attr_value.attr_val_5 != NULL) the_quality = attr_value.attr_val_5->quality; else if (attr_value.attr_val_4 != NULL) the_quality = attr_value.attr_val_4->quality; else if (attr_value.attr_val_3 != NULL) the_quality = attr_value.attr_val_3->quality; else the_quality = attr_value.attr_val->quality; // // get the mutex to synchronize the sending of events // omni_mutex_lock l(event_mutex); // // if no attribute of this name is registered with change then insert the current value // if (!attr.prev_change_event.inited) { if (except != NULL) { attr.prev_change_event.err = true; attr.prev_change_event.except = *except; } else { if (attr_value.attr_val_5 != NULL) attr.prev_change_event.value_4 = attr_value.attr_val_5->value; else if (attr_value.attr_val_4 != NULL) attr.prev_change_event.value_4 = attr_value.attr_val_4->value; else if (attr_value.attr_val_3 != NULL) attr.prev_change_event.value = attr_value.attr_val_3->value; else attr.prev_change_event.value = attr_value.attr_val->value; attr.prev_change_event.quality = the_quality; attr.prev_change_event.err = false; } attr.prev_change_event.inited = true; if (user_push == true) is_change = true; } else { // // Determine delta_change in percent compared with previous event sent // is_change = detect_change(attr,attr_value,false,delta_change_rel,delta_change_abs,except,force_change,device_impl); cout3 << "EventSupplier::detect_and_push_change_event(): rel_change " << delta_change_rel << " abs_change " << delta_change_abs << " is change = " << is_change << endl; } // // Check whether the data quality has changed. Fire event on a quality change. // if ((except == NULL) && (attr.prev_change_event.quality != the_quality )) { is_change = true; quality_change = true; } if (is_change) { vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; if (except != NULL) { attr.prev_change_event.err = true; attr.prev_change_event.except = *except; } else { if (attr_value.attr_val_5 != NULL) attr.prev_change_event.value_4 = attr_value.attr_val_5->value; else if (attr_value.attr_val_4 != NULL) attr.prev_change_event.value_4 = attr_value.attr_val_4->value; else if (attr_value.attr_val_3 != NULL) attr.prev_change_event.value = attr_value.attr_val_3->value; else attr.prev_change_event.value = attr_value.attr_val->value; attr.prev_change_event.quality = the_quality; attr.prev_change_event.err = false; } // // Prepare to push the event // domain_name = device_impl->get_name() + "/" + attr_name; filterable_names.push_back("delta_change_rel"); filterable_data.push_back(delta_change_rel); filterable_names.push_back("delta_change_abs"); filterable_data.push_back(delta_change_abs); filterable_names.push_back("forced_event"); if (force_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("quality"); if (quality_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); vector &client_libs = attr.get_client_lib(CHANGE_EVENT); vector::iterator ite; string ev_name = EventName[CHANGE_EVENT]; bool inc_ctr = true; for (ite = client_libs.begin();ite != client_libs.end();++ite) { bool need_free = false; bool name_changed = false; struct SuppliedEventData sent_value; ::memset(&sent_value,0,sizeof(sent_value)); switch (*ite) { case 5: { convert_att_event_to_5(attr_value,sent_value,need_free,attr); ev_name = EVENT_COMPAT_IDL5 + ev_name; name_changed = true; } break; case 4: { convert_att_event_to_4(attr_value,sent_value,need_free,attr); } break; default: { convert_att_event_to_3(attr_value,sent_value,need_free,attr); } break; } push_event(device_impl, ev_name, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, sent_value, attr_name, except, inc_ctr); inc_ctr = false; if (need_free == true) { if (sent_value.attr_val_5 != NULL) delete sent_value.attr_val_5; else if (sent_value.attr_val_4 != NULL) delete sent_value.attr_val_4; else if (sent_value.attr_val_3 != NULL) delete sent_value.attr_val_3; else delete sent_value.attr_val; } if (name_changed == true) ev_name = EventName[CHANGE_EVENT]; } ret = true; } cout3 << "EventSupplier::detect_and_push_change_event(): leaving for attribute " << attr_name << endl; return ret; } //+------------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::detect_and_push_archive_event() // // description : // Method to detect if there it is necessary to push an archive event // // argument : // in : // - device_impl : The device // - attr_value : The attribute value // - attr : The attribute object // - attr_name : The attribute name // - except : The exception thrown during the last attribute reading. NULL if no exception // - time_bef_attr : Date before the attribute was read // - user_push : Flag set to true if it's the user who fires the event // //------------------------------------------------------------------------------------------------------------------ bool EventSupplier::detect_and_push_archive_event(DeviceImpl *device_impl,SuppliedEventData &attr_value, Attribute &attr,string &attr_name,DevFailed *except,struct timeval *time_bef_attr, bool user_push) { string event, domain_name; double delta_change_rel = 0.0; double delta_change_abs = 0.0; bool is_change = false; bool force_change = false; bool period_change = false; bool quality_change = false; bool ret = false; cout3 << "EventSupplier::detect_and_push_archive_event(): called for attribute " << attr_name << endl; double now_ms, ms_since_last_periodic; Tango::AttrQuality the_quality; if (attr_value.attr_val_5 != NULL) the_quality = attr_value.attr_val_5->quality; else if (attr_value.attr_val_4 != NULL) the_quality = attr_value.attr_val_4->quality; else if (attr_value.attr_val_3 != NULL) the_quality = attr_value.attr_val_3->quality; else the_quality = attr_value.attr_val->quality; struct timeval now; if (time_bef_attr == NULL) { #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; } // // get the mutex to synchronize the sending of events // omni_mutex_lock l(event_mutex); // // Do not get time now. This method is executed after the attribute has been read. // For some device, reading one attribute could be long and even worse could have an unstable reading time. // If we takes time now, it will also be unstable. // Use the time taken in the polling thread before the attribute was read. This one is much more stable // if (time_bef_attr != NULL) now_ms = (double)time_bef_attr->tv_sec * 1000. + (double)time_bef_attr->tv_usec / 1000.; else now_ms = (double)now.tv_sec * 1000. + (double)now.tv_usec / 1000.; ms_since_last_periodic = now_ms - attr.archive_last_periodic; int arch_period; TangoMonitor &mon1 = device_impl->get_att_conf_monitor(); mon1.get_monitor(); arch_period = attr.archive_period; mon1.rel_monitor(); // // Specify the precision interval for the archive period testing 2% are used for periods < 5000 ms and // 100ms are used for periods > 5000 ms. // If the attribute archive period is INT_MAX, this means that the user does not want the periodic part of the // archive event // if (arch_period != INT_MAX) { if ( arch_period >= 5000 ) { arch_period = arch_period - DELTA_PERIODIC_LONG; } else { #ifdef _TG_WINDOWS_ double tmp = (double)arch_period * DELTA_PERIODIC; double int_part,eve_round; double frac = modf(tmp,&int_part); if (frac >= 0.5) eve_round = ceil(tmp); else eve_round = floor(tmp); #else double eve_round = round((double)arch_period * DELTA_PERIODIC); #endif arch_period = (int)eve_round; } cout3 << "EventSupplier::detect_and_push_archive_event(): ms_since_last_periodic = " << ms_since_last_periodic << ", arch_period = " << arch_period << ", attr.prev_archive_event.inited = " << attr.prev_archive_event.inited << endl; if ((ms_since_last_periodic > arch_period) && (attr.prev_archive_event.inited == true)) { is_change = true; period_change = true; } } // // If no attribute of this name is registered with change then insert the current value // if (!attr.prev_archive_event.inited) { if (except != NULL) { attr.prev_archive_event.err = true; attr.prev_archive_event.except = *except; } else { if (attr_value.attr_val_5 != NULL) attr.prev_archive_event.value_4 = attr_value.attr_val_5->value; else if (attr_value.attr_val_4 != NULL) attr.prev_archive_event.value_4 = attr_value.attr_val_4->value; else if (attr_value.attr_val_3 != NULL) attr.prev_archive_event.value = attr_value.attr_val_3->value; else attr.prev_archive_event.value = attr_value.attr_val->value; attr.prev_archive_event.quality = the_quality; attr.prev_archive_event.err = false; } attr.archive_last_periodic = now_ms; attr.archive_last_event = now_ms; attr.prev_archive_event.inited = true; if (user_push == true) is_change = true; } else { // // determine delta_change in percent compared with previous event sent // if (is_change == false) { is_change = detect_change(attr,attr_value,true,delta_change_rel,delta_change_abs,except,force_change,device_impl); } } // // check whether the data quality has changed. Fire event on a quality change. // if ( except == NULL && attr.prev_archive_event.quality != the_quality ) { is_change = true; quality_change = true; } if (is_change) { vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; domain_name = device_impl->get_name() + "/" + attr_name; if (except != NULL) { attr.prev_archive_event.err = true; attr.prev_archive_event.except = *except; } else { if (attr_value.attr_val_5 != NULL) attr.prev_archive_event.value_4 = attr_value.attr_val_5->value; else if (attr_value.attr_val_4 != NULL) attr.prev_archive_event.value_4 = attr_value.attr_val_4->value; else if (attr_value.attr_val_3 != NULL) attr.prev_archive_event.value = attr_value.attr_val_3->value; else attr.prev_archive_event.value = attr_value.attr_val->value; attr.prev_archive_event.quality = the_quality; attr.prev_archive_event.err = false; } // // Prepare to push the event // filterable_names_lg.push_back("counter"); if (period_change == true) { attr.archive_periodic_counter++; attr.archive_last_periodic = now_ms; filterable_data_lg.push_back(attr.archive_periodic_counter); } else { filterable_data_lg.push_back(-1); } filterable_names.push_back("delta_change_rel"); filterable_data.push_back(delta_change_rel); filterable_names.push_back("delta_change_abs"); filterable_data.push_back(delta_change_abs); filterable_names.push_back("forced_event"); if (force_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("quality"); if (quality_change == true) filterable_data.push_back((double)1.0); else filterable_data.push_back((double)0.0); filterable_names.push_back("delta_event"); filterable_data.push_back(now_ms - attr.archive_last_event); attr.archive_last_event = now_ms; vector &client_libs = attr.get_client_lib(ARCHIVE_EVENT); vector::iterator ite; string ev_name = EventName[ARCHIVE_EVENT]; bool inc_ctr = true; for (ite = client_libs.begin();ite != client_libs.end();++ite) { bool need_free = false; bool name_changed = false; struct SuppliedEventData sent_value; ::memset(&sent_value,0,sizeof(sent_value)); switch (*ite) { case 5: { convert_att_event_to_5(attr_value,sent_value,need_free,attr); ev_name = EVENT_COMPAT_IDL5 + ev_name; name_changed = true; } break; case 4: { convert_att_event_to_4(attr_value,sent_value,need_free,attr); } break; default: { convert_att_event_to_3(attr_value,sent_value,need_free,attr); } break; } push_event(device_impl, ev_name, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, sent_value, attr_name, except, inc_ctr); inc_ctr = false; if (need_free == true) { if (sent_value.attr_val_5 != NULL) delete sent_value.attr_val_5; else if (sent_value.attr_val_4 != NULL) delete sent_value.attr_val_4; else if (sent_value.attr_val_3 != NULL) delete sent_value.attr_val_3; else delete sent_value.attr_val; } if (name_changed == true) ev_name = EventName[ARCHIVE_EVENT]; } ret = true; } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventSupplier::detect_and_push_periodic_event() // // description : // Method to detect if there it is necessary to push a periodic event // // argument : // in : // - device_impl : The device // - attr_value : The attribute value // - attr : The attribute object // - attr_name : The attribute name // - except : The exception thrown during the last attribute reading. NULL if no exception // - time_bef_attr : Date before the attribute was read // //------------------------------------------------------------------------------------------------------------------ bool EventSupplier::detect_and_push_periodic_event(DeviceImpl *device_impl,struct SuppliedEventData &attr_value, Attribute &attr,string &attr_name,DevFailed *except,struct timeval *time_bef_attr) { string event, domain_name; double now_ms, ms_since_last_periodic; bool ret = false; struct timeval now; if (time_bef_attr == NULL) { #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; } // // Do not get time now. This metthod is executed after the attribute has been read. // For some device, reading one attribute could be long and even worse could have an // unstabe reading time. If we takes time now, it will also be unstable. // Use the time taken inthe polling thread befor the attribute was read. This one is much // more stable // if (time_bef_attr != NULL) now_ms = (double)time_bef_attr->tv_sec * 1000. + (double)time_bef_attr->tv_usec / 1000.; else now_ms = (double)now.tv_sec * 1000. + (double)now.tv_usec / 1000.; // // get the mutex to synchronize the sending of events // omni_mutex_lock l(event_mutex); // // get the event period // int eve_period; TangoMonitor &mon1 = device_impl->get_att_conf_monitor(); mon1.get_monitor(); eve_period = attr.event_period; mon1.rel_monitor(); // // Specify the precision interval for the event period testing 2% are used for periods < 5000 ms and // 100ms are used for periods > 5000 ms. // if ( eve_period >= 5000 ) { eve_period = eve_period - DELTA_PERIODIC_LONG; } else { #ifdef _TG_WINDOWS_ double tmp = (double)eve_period * DELTA_PERIODIC; double int_part,eve_round; double frac = modf(tmp,&int_part); if (frac >= 0.5) eve_round = ceil(tmp); else eve_round = floor(tmp); #else double eve_round = round((double)eve_period * DELTA_PERIODIC); #endif eve_period = (int)eve_round; } // // calculate the time // ms_since_last_periodic = now_ms - attr.last_periodic; cout3 << "EventSupplier::detect_and_push_is_periodic_event(): delta since last periodic " << ms_since_last_periodic << " event_period " << eve_period << " for " << device_impl->get_name()+"/"+attr_name << endl; if ( ms_since_last_periodic > eve_period ) { // // Prepare to push the event // vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; attr.periodic_counter++; attr.last_periodic = now_ms; filterable_names_lg.push_back("counter"); filterable_data_lg.push_back(attr.periodic_counter); vector &client_libs = attr.get_client_lib(PERIODIC_EVENT); vector::iterator ite; string ev_name = EventName[PERIODIC_EVENT]; bool inc_ctr = true; cout3 << "EventSupplier::detect_and_push_is_periodic_event(): detected periodic event for " << device_impl->get_name()+"/"+attr_name << endl; for (ite = client_libs.begin();ite != client_libs.end();++ite) { bool need_free = false; bool name_changed = false; struct SuppliedEventData sent_value; ::memset(&sent_value,0,sizeof(sent_value)); switch (*ite) { case 5: { convert_att_event_to_5(attr_value,sent_value,need_free,attr); ev_name = EVENT_COMPAT_IDL5 + ev_name; name_changed = true; } break; case 4: { convert_att_event_to_4(attr_value,sent_value,need_free,attr); } break; default: { convert_att_event_to_3(attr_value,sent_value,need_free,attr); } break; } push_event(device_impl, ev_name, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, sent_value, attr_name, except, inc_ctr); inc_ctr = false; if (need_free == true) { if (sent_value.attr_val_5 != NULL) delete sent_value.attr_val_5; else if (sent_value.attr_val_4 != NULL) delete sent_value.attr_val_4; else if (sent_value.attr_val_3 != NULL) delete sent_value.attr_val_3; else delete sent_value.attr_val; } if (name_changed == true) ev_name = EventName[PERIODIC_EVENT]; } ret = true; } return ret; } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::detect_change() // // description : // Method to detect if there is a change according to the criterions and return a boolean set to true if a change // is detected // // argument : // in : // - attr : The attribute object // - attr_value : The current attribute value // - archive : // - delta_change_rel : // - delta_change_abs : // - except : The exception thrown during the last attribute reading. NULL if no exception // - force_change : A flag set to true if the change is due to a non mathematical reason // (array size change, from exception to classic...) // - dev : Pointer to the device // //------------------------------------------------------------------------------------------------------------------- bool EventSupplier::detect_change(Attribute &attr,struct SuppliedEventData &attr_value,bool archive, double &delta_change_rel,double &delta_change_abs,DevFailed *except, bool &force_change,DeviceImpl *dev) { bool is_change = false; cout3 << "EventSupplier::detect_change(): called for attribute " << attr.get_name() << endl; Tango::AttrQuality the_new_quality; const CORBA::Any *the_new_any = NULL; if (attr_value.attr_val_5 != NULL) the_new_quality = attr_value.attr_val_5->quality; else if (attr_value.attr_val_4 != NULL) the_new_quality = attr_value.attr_val_4->quality; else if (attr_value.attr_val_3 != NULL) { the_new_quality = attr_value.attr_val_3->quality; the_new_any = &(attr_value.attr_val_3->value); } else { the_new_quality = attr_value.attr_val->quality; the_new_any = &(attr_value.attr_val->value); } // // get the mutex to synchronize the sending of events // omni_mutex_lock l(detect_mutex); // // Send event, if the read_attribute failed or if it is the first time that the read_attribute succeed after a failure. // Same thing if the attribute quality factor changes to INVALID // if (archive == true) { // // force an event only when the last reading was not returning an exception or not returning the same exception // if (except != NULL) { if ( attr.prev_archive_event.err == true ) { if ( Except::compare_exception (*except, attr.prev_archive_event.except) == true ) { force_change = false; return false; } } force_change = true; return true; } // // force an archive event when the last reading was still returning an exception // if ((except == NULL) && (attr.prev_archive_event.err == true)) { force_change = true; return true; } // // check wether the quality is invalid. Force an event only if the last reading was valid // if (the_new_quality == Tango::ATTR_INVALID) { if ( attr.prev_archive_event.quality == Tango::ATTR_INVALID ) { force_change = false; return false; } force_change = true; return true; } // // force an archive event when the last reding was still marked as invalid data // if ((the_new_quality != Tango::ATTR_INVALID) && (attr.prev_archive_event.quality == Tango::ATTR_INVALID)) { force_change = true; return true; } } else { // // force an event only when the last reading was not returning an exception or not returning the same exception // if (except != NULL) { if ( attr.prev_change_event.err == true ) { if ( Except::compare_exception (*except, attr.prev_change_event.except) == true ) { force_change = false; return false; } } force_change = true; return true; } // // force an change event when the last reding was still returning an exception // if ((except == NULL) && (attr.prev_change_event.err == true)) { force_change = true; return true; } // // check wether the quality is invalid. Force an event only if the last reading was valid // if (the_new_quality == Tango::ATTR_INVALID) { if ( attr.prev_change_event.quality == Tango::ATTR_INVALID ) { force_change = false; return false; } force_change = true; return true; } // // force an change event when the last reding was still marked as invalid data // if ((the_new_quality != Tango::ATTR_INVALID) && (attr.prev_change_event.quality == Tango::ATTR_INVALID)) { force_change = true; return true; } } const DevVarLong64Array *curr_seq_64, *prev_seq_64; const DevVarLongArray *curr_seq_lo, *prev_seq_lo; const DevVarShortArray *curr_seq_sh, *prev_seq_sh; const DevVarDoubleArray *curr_seq_db, *prev_seq_db; const DevVarStringArray *curr_seq_str, *prev_seq_str; const DevVarFloatArray *curr_seq_fl, *prev_seq_fl; const DevVarBooleanArray *curr_seq_bo, *prev_seq_bo; const DevVarUShortArray *curr_seq_ush, *prev_seq_ush; const DevVarCharArray *curr_seq_uch, *prev_seq_uch; const DevVarULongArray *curr_seq_ulo, *prev_seq_ulo; const DevVarULong64Array *curr_seq_u64, *prev_seq_u64; const DevVarStateArray *curr_seq_state, *prev_seq_state; double rel_change[2], abs_change[2]; bool inited; CORBA::TypeCode_var ty; delta_change_rel = delta_change_abs = 0; bool enable_check = false; TangoMonitor &mon1 = dev->get_att_conf_monitor(); mon1.get_monitor(); if (!archive) { rel_change[0] = attr.rel_change[0]; rel_change[1] = attr.rel_change[1]; abs_change[0] = attr.abs_change[0]; abs_change[1] = attr.abs_change[1]; inited = attr.prev_change_event.inited; if ((attr.prev_change_event.quality != Tango::ATTR_INVALID) && (the_new_quality != Tango::ATTR_INVALID)) enable_check = true; } else { rel_change[0] = attr.archive_rel_change[0]; rel_change[1] = attr.archive_rel_change[1]; abs_change[0] = attr.archive_abs_change[0]; abs_change[1] = attr.archive_abs_change[1]; inited = attr.prev_archive_event.inited; if ((attr.prev_archive_event.quality != Tango::ATTR_INVALID) && (the_new_quality != Tango::ATTR_INVALID)) enable_check = true; } mon1.rel_monitor(); if (inited) { if (enable_check == true) { unsigned int curr_seq_nb,prev_seq_nb; unsigned int i; if (the_new_any != NULL) ty = the_new_any->type(); // // First, analyse the DevEncoded data type // if (((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_ENCODED)) || ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_ENCODED))) { unsigned int curr_seq_str_nb,prev_seq_str_nb; const char *curr_encoded_format,*prev_encoded_format; const Tango::DevVarUCharArray *curr_data_ptr,*prev_data_ptr; const Tango::DevVarEncodedArray *un_seq; if (attr_value.attr_val_5 != NULL) un_seq = &(attr_value.attr_val_5->value.encoded_att_value()); else un_seq = &(attr_value.attr_val_4->value.encoded_att_value()); curr_seq_str_nb = strlen((*un_seq)[0].encoded_format.in()); curr_seq_nb = (*un_seq)[0].encoded_data.length(); curr_encoded_format = (*un_seq)[0].encoded_format.in(); curr_data_ptr = &((*un_seq)[0].encoded_data); if (archive == true) { DevVarEncodedArray &union_seq = attr.prev_archive_event.value_4.encoded_att_value(); prev_seq_nb = union_seq[0].encoded_data.length(); prev_seq_str_nb = strlen(union_seq[0].encoded_format.in()); prev_encoded_format = union_seq[0].encoded_format.in(); prev_data_ptr = &union_seq[0].encoded_data; } else { DevVarEncodedArray &union_seq = attr.prev_change_event.value_4.encoded_att_value(); prev_seq_nb = union_seq[0].encoded_data.length(); prev_seq_str_nb = strlen(union_seq[0].encoded_format.in()); prev_encoded_format = union_seq[0].encoded_format.in(); prev_data_ptr = &union_seq[0].encoded_data; } if ((curr_seq_nb != prev_seq_nb) || (curr_seq_str_nb != prev_seq_str_nb)) { force_change = true; return true; } if (strcmp(curr_encoded_format,prev_encoded_format) != 0) { delta_change_rel = delta_change_abs = 100.; is_change = true; return(is_change); } if ((rel_change[0] != INT_MAX) || (rel_change[1] != INT_MAX) || (abs_change[0] != INT_MAX) || (abs_change[1] != INT_MAX)) { for (i=0; i< curr_seq_nb; i++) { if (rel_change[0] != INT_MAX) { if ((*prev_data_ptr)[i] != 0) { delta_change_rel = ((*curr_data_ptr)[i] - (*prev_data_ptr)[i])*100/(*prev_data_ptr)[i]; } else { delta_change_rel = 100; if ((*curr_data_ptr)[i] == (*prev_data_ptr)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_data_ptr)[i] - (*prev_data_ptr)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } } } // // Now, the DevState data type // else { DevState curr_sta, prev_sta; bool dev_state_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == DEVICE_STATE)) { dev_state_type = true; curr_sta = attr_value.attr_val_5->value.dev_state_att(); if (archive == true) prev_sta = attr.prev_archive_event.value_4.dev_state_att(); else prev_sta = attr.prev_change_event.value_4.dev_state_att(); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == DEVICE_STATE)) { dev_state_type = true; curr_sta = attr_value.attr_val_4->value.dev_state_att(); if (archive == true) prev_sta = attr.prev_archive_event.value_4.dev_state_att(); else prev_sta = attr.prev_change_event.value_4.dev_state_att(); } else if ((the_new_any != NULL) && (ty->kind() == CORBA::tk_enum)) { dev_state_type = true; *the_new_any >>= curr_sta; if (archive == true) attr.prev_archive_event.value >>= prev_sta; else attr.prev_change_event.value >>= prev_sta; } if (dev_state_type == true) { if (curr_sta != prev_sta) { delta_change_rel = delta_change_abs = 100.; is_change = true; } return is_change; } CORBA::TypeCode_var ty_alias; CORBA::TypeCode_var ty_seq; if (the_new_any != NULL) { ty_alias = ty->content_type(); ty_seq = ty_alias->content_type(); } // // Now, the long data type // bool long_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_LONG)) { GET_SEQ(long_type,curr_seq_lo,long_att_value,prev_seq_lo,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_LONG)) { GET_SEQ(long_type,curr_seq_lo,long_att_value,prev_seq_lo,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_long)) { long_type = true; *the_new_any >>= curr_seq_lo; if (archive == true) attr.prev_archive_event.value >>= prev_seq_lo; else attr.prev_change_event.value >>= prev_seq_lo; } if (long_type == true) { curr_seq_nb = curr_seq_lo->length(); prev_seq_nb = prev_seq_lo->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_lo)[i] != 0) { delta_change_rel = ((*curr_seq_lo)[i] - (*prev_seq_lo)[i])*100/(*prev_seq_lo)[i]; } else { delta_change_rel = 100; if ((*curr_seq_lo)[i] == (*prev_seq_lo)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_seq_lo)[i] - (*prev_seq_lo)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the long 64 bits data type // bool long_long_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_LONG64)) { GET_SEQ(long_long_type,curr_seq_64,long64_att_value,prev_seq_64,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_LONG64)) { GET_SEQ(long_long_type,curr_seq_64,long64_att_value,prev_seq_64,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_longlong)) { long_long_type = true; *the_new_any >>= curr_seq_64; if (archive == true) attr.prev_archive_event.value >>= prev_seq_64; else attr.prev_change_event.value >>= prev_seq_64; } if (long_long_type == true) { curr_seq_nb = curr_seq_64->length(); prev_seq_nb = prev_seq_64->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_64)[i] != 0) { delta_change_rel = (double)(((*curr_seq_64)[i] - (*prev_seq_64)[i])*100/(*prev_seq_64)[i]); } else { delta_change_rel = 100; if ((*curr_seq_64)[i] == (*prev_seq_64)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (double)((*curr_seq_64)[i] - (*prev_seq_64)[i]); if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the short data type // bool short_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_SHORT)) { GET_SEQ(short_type,curr_seq_sh,short_att_value,prev_seq_sh,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_SHORT)) { GET_SEQ(short_type,curr_seq_sh,short_att_value,prev_seq_sh,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_short)) { short_type = true; *the_new_any >>= curr_seq_sh; if (archive == true) attr.prev_archive_event.value >>= prev_seq_sh; else attr.prev_change_event.value >>= prev_seq_sh; } if (short_type == true) { curr_seq_nb = curr_seq_sh->length(); prev_seq_nb = prev_seq_sh->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } if (attr.data_type == DEV_ENUM) { for (i=0; ilength(); i++) { if ((*curr_seq_sh)[i] != (*prev_seq_sh)[i]) { delta_change_rel = delta_change_abs = 100.; is_change = true; } return is_change; } } else { for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_sh)[i] != 0) { delta_change_rel = ((*curr_seq_sh)[i] - (*prev_seq_sh)[i])*100/(*prev_seq_sh)[i]; } else { delta_change_rel = 100; if ((*curr_seq_sh)[i] == (*prev_seq_sh)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_seq_sh)[i] - (*prev_seq_sh)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } } // // Now, the double data type // bool double_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_DOUBLE)) { GET_SEQ(double_type,curr_seq_db,double_att_value,prev_seq_db,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_DOUBLE)) { GET_SEQ(double_type,curr_seq_db,double_att_value,prev_seq_db,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_double)) { double_type = true; *the_new_any >>= curr_seq_db; if (archive == true) attr.prev_archive_event.value >>= prev_seq_db; else attr.prev_change_event.value >>= prev_seq_db; } if (double_type == true) { curr_seq_nb = curr_seq_db->length(); prev_seq_nb = prev_seq_db->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if (Tango_isnan((*prev_seq_db)[i]) != 0 && Tango_isnan((*curr_seq_db)[i]) == 0) { is_change = true; return (is_change); } if ((*prev_seq_db)[i] != 0) { delta_change_rel = ((*curr_seq_db)[i] - (*prev_seq_db)[i])*100/(*prev_seq_db)[i]; } else { delta_change_rel = 100; if ((*curr_seq_db)[i] == (*prev_seq_db)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { if (Tango_isnan((*prev_seq_db)[i]) != 0 && Tango_isnan((*curr_seq_db)[i]) == 0) { is_change = true; return (is_change); } delta_change_abs = (*curr_seq_db)[i] - (*prev_seq_db)[i]; // Correct for rounding errors ! double max_change = delta_change_abs + (abs_change[1] * 1e-10); double min_change = delta_change_abs + (abs_change[0] * 1e-10); //if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) if (min_change <= abs_change[0] || max_change >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the string data type // bool string_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_STRING)) { GET_SEQ(string_type,curr_seq_str,string_att_value,prev_seq_str,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_STRING)) { GET_SEQ(string_type,curr_seq_str,string_att_value,prev_seq_str,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_string)) { string_type = true; *the_new_any >>= curr_seq_str; if (archive == true) attr.prev_archive_event.value >>= prev_seq_str; else attr.prev_change_event.value >>= prev_seq_str; } if (string_type == true) { curr_seq_nb = curr_seq_str->length(); prev_seq_nb = prev_seq_str->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (strcmp((*curr_seq_str)[i],(*prev_seq_str)[i]) != 0) { delta_change_rel = delta_change_abs = 100.; is_change = true; return(is_change); } } return false; } // // Now, the float data type // bool float_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_FLOAT)) { GET_SEQ(float_type,curr_seq_fl,float_att_value,prev_seq_fl,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_FLOAT)) { GET_SEQ(float_type,curr_seq_fl,float_att_value,prev_seq_fl,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_float)) { float_type = true; *the_new_any >>= curr_seq_fl; if (archive == true) attr.prev_archive_event.value >>= prev_seq_fl; else attr.prev_change_event.value >>= prev_seq_fl; } if (float_type == true) { curr_seq_nb = curr_seq_fl->length(); prev_seq_nb = prev_seq_fl->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if (Tango_isnan((*prev_seq_fl)[i]) != 0 && Tango_isnan((*curr_seq_fl)[i]) == 0) { is_change = true; return (is_change); } if ((*prev_seq_fl)[i] != 0) { delta_change_rel = ((*curr_seq_fl)[i] - (*prev_seq_fl)[i])*100/(*prev_seq_fl)[i]; } else { delta_change_rel = 100; if ((*curr_seq_fl)[i] == (*prev_seq_fl)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { if (Tango_isnan((*prev_seq_fl)[i]) != 0 && Tango_isnan((*curr_seq_fl)[i]) == 0) { is_change = true; return (is_change); } delta_change_abs = (*curr_seq_fl)[i] - (*prev_seq_fl)[i]; // Correct for rounding errors ! double max_change = delta_change_abs + (abs_change[1] * 1e-10); double min_change = delta_change_abs + (abs_change[0] * 1e-10); //if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) if (min_change <= abs_change[0] || max_change >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the unsigned short data type // bool unsigned_short_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_USHORT)) { GET_SEQ(unsigned_short_type,curr_seq_ush,ushort_att_value,prev_seq_ush,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_USHORT)) { GET_SEQ(unsigned_short_type,curr_seq_ush,ushort_att_value,prev_seq_ush,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_ushort)) { unsigned_short_type = true; *the_new_any >>= curr_seq_ush; if (archive == true) attr.prev_archive_event.value >>= prev_seq_ush; else attr.prev_change_event.value >>= prev_seq_ush; } if (unsigned_short_type == true) { curr_seq_nb = curr_seq_ush->length(); prev_seq_nb = prev_seq_ush->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_ush)[i] != 0) { delta_change_rel = ((*curr_seq_ush)[i] - (*prev_seq_ush)[i])*100/(*prev_seq_ush)[i]; } else { delta_change_rel = 100; if ((*curr_seq_ush)[i] == (*prev_seq_ush)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_seq_ush)[i] - (*prev_seq_ush)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the boolean data type // bool boolean_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_BOOL)) { GET_SEQ(boolean_type,curr_seq_bo,bool_att_value,prev_seq_bo,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_BOOL)) { GET_SEQ(boolean_type,curr_seq_bo,bool_att_value,prev_seq_bo,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_boolean)) { boolean_type = true; *the_new_any >>= curr_seq_bo; if (archive == true) attr.prev_archive_event.value >>= prev_seq_bo; else attr.prev_change_event.value >>= prev_seq_bo; } if (boolean_type == true) { curr_seq_nb = curr_seq_bo->length(); prev_seq_nb = prev_seq_bo->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if ((*curr_seq_bo)[i] != (*prev_seq_bo)[i]) { delta_change_rel = delta_change_abs = 100.; is_change = true; return(is_change); } } return false; } // // Now, the char data type // bool char_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_UCHAR)) { GET_SEQ(char_type,curr_seq_uch,uchar_att_value,prev_seq_uch,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_UCHAR)) { GET_SEQ(char_type,curr_seq_uch,uchar_att_value,prev_seq_uch,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_octet)) { char_type = true; *the_new_any >>= curr_seq_uch; if (archive == true) attr.prev_archive_event.value >>= prev_seq_uch; else attr.prev_change_event.value >>= prev_seq_uch; } if (char_type == true) { curr_seq_nb = curr_seq_uch->length(); prev_seq_nb = prev_seq_uch->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_uch)[i] != 0) { delta_change_rel = ((*curr_seq_uch)[i] - (*prev_seq_uch)[i])*100/(*prev_seq_uch)[i]; } else { delta_change_rel = 100; if ((*curr_seq_uch)[i] == (*prev_seq_uch)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_seq_uch)[i] - (*prev_seq_uch)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the unsigned long data type // bool unsigned_long_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_ULONG)) { GET_SEQ(unsigned_long_type,curr_seq_ulo,ulong_att_value,prev_seq_ulo,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_ULONG)) { GET_SEQ(unsigned_long_type,curr_seq_ulo,ulong_att_value,prev_seq_ulo,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_ulong)) { unsigned_long_type = true; *the_new_any >>= curr_seq_ulo; if (archive == true) attr.prev_archive_event.value >>= prev_seq_ulo; else attr.prev_change_event.value >>= prev_seq_ulo; } if (unsigned_long_type == true) { curr_seq_nb = curr_seq_ulo->length(); prev_seq_nb = prev_seq_ulo->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_ulo)[i] != 0) { delta_change_rel = ((*curr_seq_ulo)[i] - (*prev_seq_ulo)[i])*100/(*prev_seq_ulo)[i]; } else { delta_change_rel = 100; if ((*curr_seq_ulo)[i] == (*prev_seq_ulo)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (*curr_seq_ulo)[i] - (*prev_seq_ulo)[i]; if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the unsigned 64 bits data type // bool unsigned_64_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_ULONG64)) { GET_SEQ(unsigned_64_type,curr_seq_u64,ulong64_att_value,prev_seq_u64,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_ULONG64)) { GET_SEQ(unsigned_64_type,curr_seq_u64,ulong64_att_value,prev_seq_u64,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_ulonglong)) { unsigned_64_type = true; *the_new_any >>= curr_seq_u64; if (archive == true) attr.prev_archive_event.value >>= prev_seq_u64; else attr.prev_change_event.value >>= prev_seq_u64; } if (unsigned_64_type == true) { curr_seq_nb = curr_seq_u64->length(); prev_seq_nb = prev_seq_u64->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if (rel_change[0] != INT_MAX) { if ((*prev_seq_u64)[i] != 0) { delta_change_rel = (double)(((*curr_seq_u64)[i] - (*prev_seq_u64)[i])*100/(*prev_seq_u64)[i]); } else { delta_change_rel = 100; if ((*curr_seq_u64)[i] == (*prev_seq_u64)[i]) delta_change_rel = 0; } if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1]) { is_change = true; return(is_change); } } if (abs_change[0] != INT_MAX) { delta_change_abs = (double)((*curr_seq_u64)[i] - (*prev_seq_u64)[i]); if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1]) { is_change = true; return(is_change); } } } return false; } // // Now, the state data type // bool state_type = false; if ((attr_value.attr_val_5 != NULL) && (attr_value.attr_val_5->value._d() == ATT_STATE)) { GET_SEQ(state_type,curr_seq_state,state_att_value,prev_seq_state,attr_value.attr_val_5); } else if ((attr_value.attr_val_4 != NULL) && (attr_value.attr_val_4->value._d() == ATT_STATE)) { GET_SEQ(state_type,curr_seq_state,state_att_value,prev_seq_state,attr_value.attr_val_4); } else if ((the_new_any != NULL) && (ty_seq->kind() == CORBA::tk_enum)) { state_type = true; *the_new_any >>= curr_seq_state; if (archive == true) attr.prev_archive_event.value >>= prev_seq_state; else attr.prev_change_event.value >>= prev_seq_state; } if (state_type == true) { curr_seq_nb = curr_seq_state->length(); prev_seq_nb = prev_seq_state->length(); if (curr_seq_nb != prev_seq_nb) { force_change = true; return true; } for (i=0; ilength(); i++) { if ((*curr_seq_state)[i] != (*prev_seq_state)[i]) { delta_change_rel = delta_change_abs = 100.; is_change = true; return(is_change); } } } } } } cout3 << "EventSupplier::detect_change(): leaving for attribute " << attr.get_name() << endl; return(is_change); } //+-------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::push_att_data_ready_event() // // description : // Push a data ready event // // argument : // in : // - device_impl : Pointer to device // - attr_name : Attribute name // - data_type : Attribute data type // - ctr : Counter sent in event // //------------------------------------------------------------------------------------------------------------- void EventSupplier::push_att_data_ready_event(DeviceImpl *device_impl,const string &attr_name,long data_type,DevLong ctr) { cout3 << "EventSupplier::push_att_data_ready_event(): called for attribute " << attr_name << endl; vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; string ev_type(DATA_READY_TYPE_EVENT); AttDataReady dat_ready; dat_ready.name = attr_name.c_str(); dat_ready.data_type = (int)data_type; dat_ready.ctr = ctr; SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); ad.attr_dat_ready = &dat_ready; push_event(device_impl, ev_type, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, ad, const_cast(attr_name), NULL,true); } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::push_att_conf_event() // // description : // Method to push attribute configration event // // argument : // in : // - device_impl : The device // - attr_conf : The attribute configuration // - except : The exception thrown during the last attribute reading. NULL if no exception // - attr_name : The attribute name // //------------------------------------------------------------------------------------------------------------------ void EventSupplier::push_att_conf_events(DeviceImpl *device_impl,SuppliedEventData &attr_conf,DevFailed *except,string &attr_name) { string event, domain_name; time_t now,att_conf_subscription,attr_sub; cout3 << "EventSupplier::push_att_conf_events(): called for attribute " << attr_name << endl; Attribute &attr = device_impl->dev_attr->get_attr_by_name(attr_name.c_str()); // // Called for AttributeConfig_3 or AttributeConfig_5 ? // bool conf5 = false; int vers = 4; if (attr_conf.attr_conf_5 != NULL) { conf5 = true; vers = 5; } // // Return if there is no client or if the last client subscription is more than 10 mins ago // { omni_mutex_lock oml(event_mutex); if (conf5 == true) attr_sub = attr.event_attr_conf5_subscription; else attr_sub = attr.event_attr_conf_subscription; } if (attr_sub == 0) return; now = time(NULL); att_conf_subscription = now - attr_sub; cout3 << "EventSupplier::push_att_conf_events(): delta since last subscription " << att_conf_subscription << endl; if (att_conf_subscription > EVENT_RESUBSCRIBE_PERIOD) { attr.remove_client_lib(vers,string(EventName[ATTR_CONF_EVENT])); return; } // // Push event // vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; string ev_type = CONF_TYPE_EVENT; if (conf5 == true) ev_type = EVENT_COMPAT_IDL5 + ev_type; push_event(device_impl, ev_type, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, attr_conf, attr_name, except, true); } //+-------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::push_dev_intr_change_event() // // description : // Push a device interface change event // // argument : // in : // - device_impl : Pointer to device // - dev_started : Device started flag // - cmds_list: Device commands list // - atts_list: Device attribute list // //------------------------------------------------------------------------------------------------------------- void EventSupplier::push_dev_intr_change_event(DeviceImpl *device_impl,bool dev_start,DevCmdInfoList_2 *cmds_list,AttributeConfigList_5 *atts_list) { cout3 << "EventSupplier::push_dev_intr_change_event(): called for device " << device_impl->get_name() << endl; vector filterable_names; vector filterable_data; vector filterable_names_lg; vector filterable_data_lg; string ev_type(EventName[INTERFACE_CHANGE_EVENT]); time_t now, dev_intr_subscription; // // If no client, do not send event // now = time(NULL); dev_intr_subscription = now - device_impl->get_event_intr_change_subscription(); cout3 << "EventSupplier::push_dev_intr_event(): delta since last subscription " << dev_intr_subscription << endl; if (dev_intr_subscription > EVENT_RESUBSCRIBE_PERIOD) { delete cmds_list; delete atts_list; return; } DevIntrChange dev_intr; dev_intr.dev_started = dev_start; dev_intr.cmds = *cmds_list; dev_intr.atts = *atts_list; SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); ad.dev_intr_change = &dev_intr; string att_name("dummy"); push_event(device_impl, ev_type, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, ad, att_name, NULL, true); // // Free memory allocated for the two pointers we receive // delete cmds_list; delete atts_list; } //+-------------------------------------------------------------------------------------------------------------- // // method : // EventSupplier::any_dev_intr_client // // description : // Check if there is at least a device interface change client // // argument : // in : // - device_impl : Pointer to device // // return : // True if there is at least one client listening for this event // //------------------------------------------------------------------------------------------------------------- bool EventSupplier::any_dev_intr_client(DeviceImpl *device_impl) { bool ret = false; time_t now = time(NULL); time_t dev_intr_subscription = now - device_impl->get_event_intr_change_subscription(); if (dev_intr_subscription < EVENT_RESUBSCRIBE_PERIOD) ret = true; return ret; } void EventSupplier::convert_att_event_to_5(struct EventSupplier::SuppliedEventData &attr_value, struct EventSupplier::SuppliedEventData &sent_value, bool &need_free,Attribute &attr) { if (attr_value.attr_val_3 != Tango_nullptr) { AttributeValue_5 *tmp_attr_val_5 = new AttributeValue_5(); attr.AttributeValue_3_2_AttributeValue_5(attr_value.attr_val_3,tmp_attr_val_5); sent_value.attr_val_5 = tmp_attr_val_5; need_free = true; } else if (attr_value.attr_val_4 != Tango_nullptr) { AttributeValue_5 *tmp_attr_val_5 = new AttributeValue_5(); attr.AttributeValue_4_2_AttributeValue_5(attr_value.attr_val_4,tmp_attr_val_5); sent_value.attr_val_5 = tmp_attr_val_5; need_free = true; } else sent_value.attr_val_5 = attr_value.attr_val_5; } void EventSupplier::convert_att_event_to_4(struct EventSupplier::SuppliedEventData &attr_value, struct EventSupplier::SuppliedEventData &sent_value, bool &need_free,Attribute &attr) { if (attr_value.attr_val_3 != Tango_nullptr) { AttributeValue_4 *tmp_attr_val_4 = new AttributeValue_4(); attr.AttributeValue_3_2_AttributeValue_4(attr_value.attr_val_3,tmp_attr_val_4); sent_value.attr_val_4 = tmp_attr_val_4; need_free = true; } else if (attr_value.attr_val_5 != Tango_nullptr) { AttributeValue_4 *tmp_attr_val_4 = new AttributeValue_4(); attr.AttributeValue_5_2_AttributeValue_4(attr_value.attr_val_5,tmp_attr_val_4); sent_value.attr_val_4 = tmp_attr_val_4; need_free = true; } else sent_value.attr_val_4 = attr_value.attr_val_4; } void EventSupplier::convert_att_event_to_3(struct EventSupplier::SuppliedEventData &attr_value, struct EventSupplier::SuppliedEventData &sent_value, bool &need_free,Attribute &attr) { if (attr_value.attr_val_4 != Tango_nullptr) { AttributeValue_3 *tmp_attr_val_3 = new AttributeValue_3(); attr.AttributeValue_4_2_AttributeValue_3(attr_value.attr_val_4,tmp_attr_val_3); sent_value.attr_val_3 = tmp_attr_val_3; need_free = true; } else if (attr_value.attr_val_5 != Tango_nullptr) { AttributeValue_3 *tmp_attr_val_3 = new AttributeValue_3(); attr.AttributeValue_5_2_AttributeValue_3(attr_value.attr_val_5,tmp_attr_val_3); sent_value.attr_val_3 = tmp_attr_val_3; need_free = true; } else sent_value.attr_val_3 = attr_value.attr_val_3; } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/server/except.cpp0000644023471100065110000006111613034745002014563 00000000000000static const char *RcsId = "$Id: except.cpp 29622 2016-04-15 14:09:56Z bourtemb $\n$Name$"; //+============================================================================= // // file : except.cpp // // description : C++ source for all the utilities used by Tango device // server and mainly for the Tango class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 29622 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include namespace Tango { char Except::mess[256]; omni_mutex Except::the_mutex; //+---------------------------------------------------------------------------- // // method : print_exception // // description : This method prints the information embedded in // a Tango exception. // // in : e : Reference to the exception object // //----------------------------------------------------------------------------- void Except::print_exception(const CORBA::Exception &e) { const CORBA::SystemException *se; // // For a CORBA::SystemException, use the OB function // if ((se = dynamic_cast(&e)) != NULL) { Tango::Except::the_mutex.lock(); cerr << print_CORBA_SystemException(se) << endl; Tango::Except::the_mutex.unlock(); } // // If it is a CORBA::UserException // else if (dynamic_cast(&e) != NULL) { const Tango::DevFailed *te; const Tango::NamedDevFailedList *mdf; // // Print the Tango::NamedDevFailedList exception contents // if ((mdf = dynamic_cast(&e)) != NULL) { cerr << "Tango NamedDevFailedList exception" << endl; for (unsigned long i = 0;i < mdf->err_list.size();i++) { cerr << " Exception for object " << mdf->err_list[i].name << endl; cerr << " Index of object in call (starting at 0) = " << mdf->err_list[i].idx_in_call << endl; for (unsigned long j =0;j < mdf->err_list[i].err_stack.length();j++) { cerr << " Severity = "; switch (mdf->err_list[i].err_stack[j].severity) { case Tango::WARN : cerr << "WARNING "; break; case Tango::ERR : cerr << "ERROR "; break; case Tango::PANIC : cerr << "PANIC "; break; default : cerr << "Unknown severity code"; break; } cerr << endl; cerr << " Error reason = " << mdf->err_list[i].err_stack[j].reason.in() << endl; cerr << " Desc : " << mdf->err_list[i].err_stack[j].desc.in() << endl; cerr << " Origin : " << mdf->err_list[i].err_stack[j].origin.in() << endl; } } cerr << " Summary exception" << endl; for (unsigned long j =0;j < mdf->errors.length();j++) { cerr << " Severity = "; switch (mdf->errors[j].severity) { case Tango::WARN : cerr << "WARNING "; break; case Tango::ERR : cerr << "ERROR "; break; case Tango::PANIC : cerr << "PANIC "; break; default : cerr << "Unknown severity code"; break; } cerr << endl; cerr << " Error reason = " << mdf->errors[j].reason.in() << endl; cerr << " Desc : " << mdf->errors[j].desc.in() << endl; cerr << " Origin : " << mdf->errors[j].origin.in() << endl; cerr << endl; } } // // Print the Tango::DevFailed exception contents // else if ((te = dynamic_cast(&e)) != NULL) { for (unsigned long i =0;i < te->errors.length();i++) { cerr << "Tango exception" << endl; cerr << "Severity = "; switch (te->errors[i].severity) { case Tango::WARN : cerr << "WARNING "; break; case Tango::ERR : cerr << "ERROR "; break; case Tango::PANIC : cerr << "PANIC "; break; default : cerr << "Unknown severity code"; break; } cerr << endl; cerr << "Error reason = " << te->errors[i].reason.in() << endl; cerr << "Desc : " << te->errors[i].desc.in() << endl; cerr << "Origin : " << te->errors[i].origin.in() << endl; cerr << endl; } } // // For an unknown CORBA::UserException // else { cerr << "Unknown CORBA user exception" << endl; } } // // For an unknown exception type // else { cerr << "Unknown exception type !!!!!!" << endl; } } //+---------------------------------------------------------------------------- // // method : print_CORBA_SystemException // // description : This method prints the information embedded in // a CORBA system exception. // // in : e : Pointer to the exception object // //----------------------------------------------------------------------------- char *Except::print_CORBA_SystemException(const CORBA::SystemException *e) { const CORBA::BAD_PARAM *bad; const CORBA::NO_MEMORY *mem; const CORBA::IMP_LIMIT *lim; const CORBA::COMM_FAILURE *comm; const CORBA::INV_OBJREF *inv; const CORBA::NO_PERMISSION *perm; const CORBA::INTERNAL *inter; const CORBA::MARSHAL *mar; const CORBA::INITIALIZE *ini; const CORBA::NO_IMPLEMENT *impl; const CORBA::BAD_TYPECODE *type; const CORBA::BAD_OPERATION *op; const CORBA::NO_RESOURCES *res; const CORBA::NO_RESPONSE *resp; const CORBA::BAD_INV_ORDER *inv_ord; const CORBA::TRANSIENT *tra; const CORBA::OBJ_ADAPTER *adap; const CORBA::OBJECT_NOT_EXIST *not_ex; const CORBA::INV_POLICY *pol; // // It seems that omniORB for Win32 is not compiled with the RTTI enabled // (/GR option). We can't use dynamic_casting here. // We are using CORBA _downcast() method !!! // if (CORBA::UNKNOWN::_downcast(e) != 0) { ::strcpy(mess,"UNKNOWN CORBA system exception"); } else if ((bad = CORBA::BAD_PARAM::_downcast(e)) != 0) { ::strcpy(mess,"BAD_PARAM CORBA system exception: "); const char *err_msg = bad->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((mem = CORBA::NO_MEMORY::_downcast(e)) != 0) { ::strcpy(mess,"NO_MEMORY CORBA system exception: "); const char *err_msg = mem->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((lim = CORBA::IMP_LIMIT::_downcast(e)) != 0) { ::strcpy(mess,"IMP_LIMIT CORBA system exception: "); const char *tmp = lim->NP_minorString(); if (tmp == NULL) { ::strcat(mess,"Unknown minor code: "); TangoSys_MemStream st; st << hex << lim->minor() << dec << ends; string s = st.str(); ::strcat(mess,s.c_str()); } else ::strcat(mess,tmp); } else if ((comm = CORBA::COMM_FAILURE::_downcast(e)) != NULL) { ::strcpy(mess,"COMM_FAILURE CORBA system exception: "); const char *tmp = comm->NP_minorString(); if (tmp == NULL) { ::strcat(mess,"Unknown minor code: "); TangoSys_MemStream st; st << hex << comm->minor() << dec << ends; string s = st.str(); ::strcat(mess,s.c_str()); } else ::strcat(mess,tmp); } else if ((inv = CORBA::INV_OBJREF::_downcast(e)) != NULL) { ::strcpy(mess,"INV_OBJREF CORBA system exception: "); const char *err_msg = inv->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((perm = CORBA::NO_PERMISSION::_downcast(e)) != NULL) { ::strcpy(mess,"NO_PERMISSION CORBA system exception: "); const char *err_msg = perm->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((inter = CORBA::INTERNAL::_downcast(e)) != NULL) { ::strcpy(mess,"INTERNAL CORBA system exception: "); const char *err_msg = inter->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((mar = CORBA::MARSHAL::_downcast(e)) != NULL) { ::strcpy(mess,"MARSHAL CORBA system exception: "); const char *err_msg = mar->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((ini = CORBA::INITIALIZE::_downcast(e)) != NULL) { ::strcpy(mess,"INITIALIZE CORBA system exception: "); const char *err_msg = ini->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((impl = CORBA::NO_IMPLEMENT::_downcast(e)) != NULL) { ::strcpy(mess,"NO_IMPLEMENT CORBA system exception: "); const char *err_msg = impl->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((type = CORBA::BAD_TYPECODE::_downcast(e)) != NULL) { ::strcpy(mess,"BAD_TYPECODE CORBA system exception: "); const char *err_msg = type->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((op = CORBA::BAD_OPERATION::_downcast(e)) != NULL) { ::strcpy(mess,"BAD_OPERATION CORBA system exception: "); const char *err_msg = op->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((res = CORBA::NO_RESOURCES::_downcast(e)) != NULL) { ::strcpy(mess,"NO_RESOURCES CORBA system exception: "); const char *err_msg = res->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((resp = CORBA::NO_RESPONSE::_downcast(e)) != NULL) { ::strcpy(mess,"NO_RESPONSE CORBA system exception: "); const char *err_msg = resp->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((inv_ord = CORBA::BAD_INV_ORDER::_downcast(e)) != NULL) { ::strcpy(mess,"BAD_INV_ORDER CORBA system exception: "); const char *err_msg = inv_ord->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((tra = CORBA::TRANSIENT::_downcast(e)) != NULL) { ::strcpy(mess,"TRANSIENT CORBA system exception: "); const char *tmp = tra->NP_minorString(); if (tmp == NULL) { ::strcat(mess,"Unknown minor code: "); TangoSys_MemStream st; st << hex << tra->minor() << dec << ends; string s = st.str(); ::strcat(mess,s.c_str()); } else ::strcat(mess,tmp); } else if ((adap = CORBA::OBJ_ADAPTER::_downcast(e)) != NULL) { ::strcpy(mess,"OBJ_ADAPTER CORBA system exception: "); const char *err_msg = adap->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((not_ex = CORBA::OBJECT_NOT_EXIST::_downcast(e)) != NULL) { ::strcpy(mess,"OBJECT_NOT_EXIST CORBA system exception: "); const char *err_msg = not_ex->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else if ((pol = CORBA::INV_POLICY::_downcast(e)) != NULL) { ::strcpy(mess,"INV_POLICY CORBA system exception: "); const char *err_msg = pol->NP_minorString(); if ( err_msg == NULL ) ::strcat(mess,"ORB has returned NULL pointer !"); else ::strcat(mess,err_msg); } else ::strcpy(mess,"CORBA unknown system exception !!!!!!!!"); return mess; } //+---------------------------------------------------------------------------- // // method : print_CORBA_SystemException_r // // description : This method prints the information embedded in // a CORBA system exception. This is the reentrant version of // print_CORBA_SystemException method // // in : e : Pointer to the exception object // error_msg : Pointer to an already allocated char * buffer // buffer_size : Size of error_msg buffer // //----------------------------------------------------------------------------- char *Except::print_CORBA_SystemException_r(const CORBA::SystemException *e, char * error_msg) { const CORBA::BAD_PARAM *bad; const CORBA::NO_MEMORY *mem; const CORBA::IMP_LIMIT *lim; const CORBA::COMM_FAILURE *comm; const CORBA::INV_OBJREF *inv; const CORBA::NO_PERMISSION *perm; const CORBA::INTERNAL *inter; const CORBA::MARSHAL *mar; const CORBA::INITIALIZE *ini; const CORBA::NO_IMPLEMENT *impl; const CORBA::BAD_TYPECODE *type; const CORBA::BAD_OPERATION *op; const CORBA::NO_RESOURCES *res; const CORBA::NO_RESPONSE *resp; const CORBA::BAD_INV_ORDER *inv_ord; const CORBA::TRANSIENT *tra; const CORBA::OBJ_ADAPTER *adap; const CORBA::OBJECT_NOT_EXIST *not_ex; const CORBA::INV_POLICY *pol; // // It seems that omniORB for Win32 is not compiled with the RTTI enabled // (/GR option). We can't use dynamic_casting here. // We are using CORBA _downcast() method !!! // if (CORBA::UNKNOWN::_downcast(e) != 0) { ::strcpy(error_msg,"UNKNOWN CORBA system exception"); } else if ((bad = CORBA::BAD_PARAM::_downcast(e)) != 0) { ::strcpy(error_msg,"BAD_PARAM CORBA system exception: "); const char *err_msg = bad->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((mem = CORBA::NO_MEMORY::_downcast(e)) != 0) { ::strcpy(error_msg,"NO_MEMORY CORBA system exception: "); const char *err_msg = mem->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((lim = CORBA::IMP_LIMIT::_downcast(e)) != 0) { ::strcpy(error_msg,"IMP_LIMIT CORBA system exception: "); const char *tmp = lim->NP_minorString(); if (tmp == NULL) { ::strcat(error_msg,"Unknown minor code: "); TangoSys_MemStream st; st << hex << lim->minor() << dec << ends; string s = st.str(); ::strcat(error_msg,s.c_str()); } else ::strcat(error_msg,tmp); } else if ((comm = CORBA::COMM_FAILURE::_downcast(e)) != NULL) { ::strcpy(error_msg,"COMM_FAILURE CORBA system exception: "); const char *tmp = comm->NP_minorString(); if (tmp == NULL) { ::strcat(error_msg,"Unknown minor code: "); TangoSys_MemStream st; st << hex << comm->minor() << dec << ends; string s = st.str(); ::strcat(error_msg,s.c_str()); } else ::strcat(error_msg,tmp); } else if ((inv = CORBA::INV_OBJREF::_downcast(e)) != NULL) { ::strcpy(error_msg,"INV_OBJREF CORBA system exception: "); const char *err_msg = inv->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((perm = CORBA::NO_PERMISSION::_downcast(e)) != NULL) { ::strcpy(error_msg,"NO_PERMISSION CORBA system exception: "); const char *err_msg = perm->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((inter = CORBA::INTERNAL::_downcast(e)) != NULL) { ::strcpy(error_msg,"INTERNAL CORBA system exception: "); const char *err_msg = inter->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((mar = CORBA::MARSHAL::_downcast(e)) != NULL) { ::strcpy(error_msg,"MARSHAL CORBA system exception: "); const char *err_msg = mar->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((ini = CORBA::INITIALIZE::_downcast(e)) != NULL) { ::strcpy(error_msg,"INITIALIZE CORBA system exception: "); const char *err_msg = ini->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((impl = CORBA::NO_IMPLEMENT::_downcast(e)) != NULL) { ::strcpy(error_msg,"NO_IMPLEMENT CORBA system exception: "); const char *err_msg = impl->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((type = CORBA::BAD_TYPECODE::_downcast(e)) != NULL) { ::strcpy(error_msg,"BAD_TYPECODE CORBA system exception: "); const char *err_msg = type->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((op = CORBA::BAD_OPERATION::_downcast(e)) != NULL) { ::strcpy(error_msg,"BAD_OPERATION CORBA system exception: "); const char *err_msg = op->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((res = CORBA::NO_RESOURCES::_downcast(e)) != NULL) { ::strcpy(error_msg,"NO_RESOURCES CORBA system exception: "); const char *err_msg = res->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((resp = CORBA::NO_RESPONSE::_downcast(e)) != NULL) { ::strcpy(error_msg,"NO_RESPONSE CORBA system exception: "); const char *err_msg = resp->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((inv_ord = CORBA::BAD_INV_ORDER::_downcast(e)) != NULL) { ::strcpy(error_msg,"BAD_INV_ORDER CORBA system exception: "); const char *err_msg = inv_ord->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((tra = CORBA::TRANSIENT::_downcast(e)) != NULL) { ::strcpy(error_msg,"TRANSIENT CORBA system exception: "); const char *tmp = tra->NP_minorString(); if (tmp == NULL) { ::strcat(error_msg,"Unknown minor code: "); TangoSys_MemStream st; st << hex << tra->minor() << dec << ends; string s = st.str(); ::strcat(error_msg,s.c_str()); } else ::strcat(error_msg,tmp); } else if ((adap = CORBA::OBJ_ADAPTER::_downcast(e)) != NULL) { ::strcpy(error_msg,"OBJ_ADAPTER CORBA system exception: "); const char *err_msg = adap->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((not_ex = CORBA::OBJECT_NOT_EXIST::_downcast(e)) != NULL) { ::strcpy(error_msg,"OBJECT_NOT_EXIST CORBA system exception: "); const char *err_msg = not_ex->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else if ((pol = CORBA::INV_POLICY::_downcast(e)) != NULL) { ::strcpy(error_msg,"INV_POLICY CORBA system exception: "); const char *err_msg = pol->NP_minorString(); if ( err_msg == NULL ) ::strcat(error_msg,"ORB has returned NULL pointer !"); else ::strcat(error_msg,err_msg); } else ::strcpy(error_msg,"CORBA unknown system exception !!!!!!!!"); return error_msg; } //+---------------------------------------------------------------------------- // // method : print_error_stack // // description : This method prints the a Tango error stack // // in : e : Reference to the error stack // //----------------------------------------------------------------------------- void Except::print_error_stack(const Tango::DevErrorList &e) { for (unsigned long i = 0;i < e.length();i++) { cerr << "Tango error stack" << endl; cerr << "Severity = "; switch (e[i].severity) { case Tango::WARN : cerr << "WARNING "; break; case Tango::ERR : cerr << "ERROR "; break; case Tango::PANIC : cerr << "PANIC "; break; default : cerr << "Unknown severity code"; break; } cerr << endl; cerr << "Error reason = " << e[i].reason.in() << endl; cerr << "Desc : " << e[i].desc.in() << endl; cerr << "Origin : " << e[i].origin.in() << endl; cerr << endl; } } //+---------------------------------------------------------------------------- // // method : throw_exception // // description : These methods throws a Tango DevFailed exception from // a CORBA system exception. // // in : e : Pointer to the exception object // //----------------------------------------------------------------------------- void Except::throw_exception(const CORBA::SystemException &c_ex,const char *origin) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].origin = CORBA::string_dup(origin); errors[0].reason = CORBA::string_dup(API_CorbaSysException); Tango::Except::the_mutex.lock(); char *tmp = print_CORBA_SystemException(&c_ex); errors[0].desc = CORBA::string_dup(tmp); Tango::Except::the_mutex.unlock(); throw Tango::DevFailed(errors); } void Except::throw_exception(const CORBA::SystemException &c_ex,char *origin) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].origin = CORBA::string_dup(origin); delete [] origin; errors[0].reason = CORBA::string_dup(API_CorbaSysException); Tango::Except::the_mutex.lock(); char *tmp = print_CORBA_SystemException(&c_ex); errors[0].desc = CORBA::string_dup(tmp); Tango::Except::the_mutex.unlock(); throw Tango::DevFailed(errors); } void Except::throw_exception(const CORBA::SystemException &c_ex,const string &origin) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].origin = CORBA::string_dup(origin.c_str()); errors[0].reason = CORBA::string_dup(API_CorbaSysException); Tango::Except::the_mutex.lock(); char *tmp = print_CORBA_SystemException(&c_ex); errors[0].desc = CORBA::string_dup(tmp); Tango::Except::the_mutex.unlock(); throw Tango::DevFailed(errors); } void Except::throw_named_exception(Tango::DeviceImpl *d,long ind,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever) { throw_named_exception(d->get_device_attr()->get_attr_by_ind(ind).get_name().c_str(), reason,desc,origin,sever); } void Except::throw_named_exception(Tango::DeviceImpl *d,vector &ind_atts,const char *reason, const char *desc,const char *origin,Tango::ErrSeverity sever) { vector vs; vector::iterator ite; for (ite = ind_atts.begin();ite != ind_atts.end();++ite) { vs.push_back(d->get_device_attr()->get_attr_by_ind(*ite).get_name()); } throw_named_exception(vs,reason,desc,origin,sever); } //+---------------------------------------------------------------------------- // // method : Compare two Tango DevFailed exceptions for equality // // description : The two DevFailed exceptions are verified by comparing the // reason, origin, description and severity of all exceptions in the error stack. // The strings reason, origin and description are compared literally. // // in : ex1 The first DevFailed exception // ex1 The first DevFailed exception // // return: a boolean set to true if the two exceptions are equal //----------------------------------------------------------------------------- bool Except::compare_exception(Tango::DevFailed &ex1, Tango::DevFailed &ex2) { // check the length of the exception stack unsigned long nb_err = ex1.errors.length(); if ( nb_err != ex2.errors.length() ) { return false; } // check all exceptions in the stack for (unsigned long i=0; i. // // $Revision: 28374 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::FwdAttr // // description : // Constructor for the FwdAttr class. Initialize data with default value for a wrongly configured // forwarded attribute // // argument : // in : // - att_name : The attribute name // - root_attribute : The root attribute name // //-------------------------------------------------------------------------------------------------------------------- FwdAttr::FwdAttr(const string &att_name,const string &root_attribute): ImageAttr(att_name.c_str()),full_root_att(root_attribute),fwd_wrongly_conf(false),err_kind(FWD_ERR_UNKNOWN),ext(Tango_nullptr) { writable = Tango::READ; // Difficult to switch it to WT_UNKNOWN // type = DATA_TYPE_UNKNOWN; type = DEV_DOUBLE; format = Tango::FMT_UNKNOWN; // disp_level = DL_UNKNOWN; assoc_name = AssocWritNotSpec; max_x = 0; max_y = 0; mem = false; mem_init = false; fire_change_event = false; fire_archive_event = false; check_change_event = false; check_archive_event = false; fire_dr_event = false; set_cl_name("FwdAttr"); set_err_kind(FWD_NO_ERROR); } FwdAttr::FwdAttr(const FwdAttr &sou):ImageAttr(sou) { full_root_att = sou.full_root_att; fwd_dev_name = sou.fwd_dev_name; fwd_root_att = sou.fwd_root_att; fwd_wrongly_conf = sou.fwd_wrongly_conf; err_kind = sou.err_kind; } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::validate_fwd_att // // description : // Validate that we have the knowledge of the root attribute. // // argument : // in : // - prop_list : The attribute property list // - dev_name : The device name // // return: // True if we have the required info to build a forwarded attribute // //-------------------------------------------------------------------------------------------------------------------- bool FwdAttr::validate_fwd_att(vector &prop_list,const string &dev_name) { bool ret = true; // // Check if root attribute is defined in DB (then in received prop list) // If it's the case, check its syntax // string root_att_db; bool root_att_db_defined = false; Util *tg = Util::instance(); Database *db = tg->get_database(); try { #ifdef HAS_LAMBDA_FUNC auto pos = find_if(prop_list.begin(),prop_list.end(), [] (AttrProperty &ap) -> bool { return ap.get_name() == RootAttrPropName; }); #else vector::iterator pos; for (pos = prop_list.begin();pos != prop_list.end();++pos) { if (pos->get_name() == RootAttrPropName) break; } #endif if (pos != prop_list.end()) { root_att_db = pos->get_value(); root_att_db_defined = true; } else { // // Write something in DB to help user to create the right entry except if the root att name is hard coded // if (full_root_att == RootAttNotDef) { DbDatum att(get_name()); att << (DevShort)1; DbDatum root_name(RootAttrPropName); root_name << RootAttNotDef; DbData db_dat; db_dat.push_back(att); db_dat.push_back(root_name); try { if (db != Tango_nullptr) db->put_device_attribute_property(dev_name,db_dat); } catch(...) {} } } } catch (...) {} if (root_att_db_defined == true) full_root_att = root_att_db; else full_root_att = RootAttNotDef; // // Check root att syntax and add TANGO_HOST info in root device name of not given // Also add dns suffix if not defined in provided TANGO_HOST host name // string fq; if (db != Tango_nullptr) { fq = "tango://"; string &h = db->get_db_host(); string &p = db->get_db_port(); fq = fq + h + ':' + p + '/'; } transform(fq.begin(),fq.end(),fq.begin(),::tolower); if (full_root_att != RootAttNotDef) { int nb_sep = count(full_root_att.begin(),full_root_att.end(),'/'); if (nb_sep == 3) { full_root_att.insert(0,fq); } else if (nb_sep == 6) { string::size_type pos = full_root_att.find("tango://"); if (pos != 0) ret = false; else { pos = full_root_att.find(':',8); string ho = full_root_att.substr(8,pos - 8); string::size_type pos1 = ho.find('.'); size_t old_size = ho.size(); if (pos1 == string::npos) Connection::get_fqdn(ho); string dom = ho.substr(old_size); full_root_att.insert(pos,dom); } } else { fwd_wrongly_conf = true; err_kind = FWD_WRONG_SYNTAX; ret = false; } if (ret == true) { string::size_type pos = full_root_att.find_last_of('/'); fwd_root_att = full_root_att.substr(pos + 1); fwd_dev_name = full_root_att.substr(0,pos); transform(fwd_dev_name.begin(),fwd_dev_name.end(),fwd_dev_name.begin(),::tolower); transform(fwd_root_att.begin(),fwd_root_att.end(),fwd_root_att.begin(),::tolower); } } else { fwd_wrongly_conf = true; err_kind = FWD_MISSING_ROOT; ret = false; } // // Check that the root device is not the local device // string local_dev_name(dev_name); local_dev_name.insert(0,fq); if (fwd_dev_name == local_dev_name) { fwd_wrongly_conf = true; err_kind = FWD_ROOT_DEV_LOCAL_DEV; ret = false; } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::get_root_conf // // description : // Get the root attribute configuration // // argument : // in : // - dev_name : The local device name // - dev : Device pointer // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::get_root_conf(string &dev_name,DeviceImpl *dev) { try { RootAttRegistry &dps = Tango::Util::instance()->get_root_att_reg(); dps.add_root_att(fwd_dev_name,fwd_root_att,dev_name,name,this,dev); } catch (Tango::DevFailed &) { fwd_wrongly_conf = true; throw; } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::read // // description : // Read method for forwarded attribute // // argument : // in : // - dev : The device // - attr : The attribute object // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::read(DeviceImpl *dev,Attribute &attr) { // // Throw exception in case of fwd att wrongly configured or if the root device is not yet accessible // if (attr.get_data_type() == DATA_TYPE_UNKNOWN) { string desc("Attribute "); desc = desc + name + " is a forwarded attribute and its root device ("; desc = desc + fwd_dev_name; desc = desc + ") is not yet available"; Tango::Except::throw_exception(API_AttrConfig,desc,"FwdAttr::read"); } // // Retrieve root attribute device proxy object // FwdAttribute &fwd_attr = static_cast(attr); RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *root_att_dev; try { root_att_dev = rar.get_root_att_dp(fwd_attr.get_fwd_dev_name()); } catch (Tango::DevFailed &e) { string desc("Attribute "); desc = desc + name + " is a forwarded attribute.\n"; desc = desc + "Check device status to get more info"; Tango::Except::re_throw_exception(e,API_AttrConfig,desc,"FwdAttr::read()"); } // // Read the ŕoot attribute // try { root_att_dev->set_source(dev->get_call_source()); DeviceAttribute da = root_att_dev->read_attribute(fwd_attr.get_fwd_att_name()); // // Set the local attribute from the result of the previous read // switch(fwd_attr.get_data_type()) { case DEV_SHORT: case DEV_ENUM: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().sh_seq); break; case DEV_LONG: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().lg_seq); break; case DEV_FLOAT: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().fl_seq); break; case DEV_DOUBLE: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().db_seq); break; case DEV_STRING: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().str_seq); break; case DEV_USHORT: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().ush_seq); break; case DEV_BOOLEAN: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().boo_seq); break; case DEV_UCHAR: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().cha_seq); break; case DEV_LONG64: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().lg64_seq); break; case DEV_ULONG: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().ulg_seq); break; case DEV_ULONG64: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().ulg64_seq); break; case DEV_STATE: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().state_seq); break; case DEV_ENCODED: fwd_attr.set_local_attribute(da,fwd_attr.get_root_ptr().enc_seq); break; default: break; } } catch (Tango::DevFailed &e) { stringstream ss; ss << "Reading root attribute " << fwd_root_att << " on device " << fwd_dev_name << " failed!"; Tango::Except::re_throw_exception(e,API_AttributeFailed,ss.str(),"FwdAttr::read"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::write // // description : // Write method for forwarded attribute // // argument : // in : // - dev : The device // - attr : The attribute object // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::write(TANGO_UNUSED(DeviceImpl *dev),WAttribute &attr) { // // Throw exception in case of fwd att wrongly configured or if the root device is not yet accessible // if (attr.get_data_type() == DATA_TYPE_UNKNOWN) { string desc("Attribute "); desc = desc + name + " is a forwarded attribute and its root device ("; desc = desc + fwd_dev_name; desc = desc + ") is not yet available"; Tango::Except::throw_exception(API_AttrConfig,desc,"FwdAttr::write"); } // // Retrieve root attribute device proxy object // FwdAttribute &fwd_attr = static_cast(attr); RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *root_att_dev; try { root_att_dev = rar.get_root_att_dp(fwd_attr.get_fwd_dev_name()); } catch (Tango::DevFailed &e) { string desc("Attribute "); desc = desc + name + " is a forwarded attribute.\n"; desc = desc + "Check device status to get more info"; Tango::Except::re_throw_exception(e,API_AttrConfig,desc,"FwdAttr::write()"); } // // Write the ŕoot attribute // DeviceAttribute da; da.set_name(fwd_attr.get_fwd_att_name()); switch(fwd_attr.get_data_type()) { case DEV_SHORT: case DEV_ENUM: DevShort *ptr_sh; fwd_attr.propagate_writen_data(da,attr,ptr_sh,fwd_attr.get_root_ptr().sh_seq); break; case DEV_LONG: DevLong *ptr_lo; fwd_attr.propagate_writen_data(da,attr,ptr_lo,fwd_attr.get_root_ptr().lg_seq); break; case DEV_FLOAT: DevFloat *ptr_fl; fwd_attr.propagate_writen_data(da,attr,ptr_fl,fwd_attr.get_root_ptr().fl_seq); break; case DEV_DOUBLE: DevDouble *ptr_db; fwd_attr.propagate_writen_data(da,attr,ptr_db,fwd_attr.get_root_ptr().db_seq); break; case DEV_STRING: ConstDevString *ptr_str; fwd_attr.propagate_writen_data(da,attr,ptr_str,fwd_attr.get_root_ptr().str_seq); break; case DEV_USHORT: DevUShort *ptr_ush; fwd_attr.propagate_writen_data(da,attr,ptr_ush,fwd_attr.get_root_ptr().ush_seq); break; case DEV_BOOLEAN: DevBoolean *ptr_bo; fwd_attr.propagate_writen_data(da,attr,ptr_bo,fwd_attr.get_root_ptr().boo_seq); break; case DEV_UCHAR: DevUChar *ptr_uch; fwd_attr.propagate_writen_data(da,attr,ptr_uch,fwd_attr.get_root_ptr().cha_seq); break; case DEV_LONG64: DevLong64 *ptr_lg64; fwd_attr.propagate_writen_data(da,attr,ptr_lg64,fwd_attr.get_root_ptr().lg64_seq); break; case DEV_ULONG: DevULong *ptr_ulg; fwd_attr.propagate_writen_data(da,attr,ptr_ulg,fwd_attr.get_root_ptr().ulg_seq); break; case DEV_ULONG64: DevULong64 *ptr_ulg64; fwd_attr.propagate_writen_data(da,attr,ptr_ulg64,fwd_attr.get_root_ptr().ulg64_seq); break; case DEV_STATE: DevState *ptr_sta; fwd_attr.propagate_writen_data(da,attr,ptr_sta,fwd_attr.get_root_ptr().state_seq); break; case DEV_ENCODED: DevEncoded *ptr_enc; fwd_attr.propagate_writen_data(da,attr,ptr_enc,fwd_attr.get_root_ptr().enc_seq); break; default: break; } try { root_att_dev->write_attribute(da); } catch (Tango::DevFailed &e) { stringstream ss; ss << "Writing root attribute " << fwd_root_att << " on device " << fwd_dev_name << " failed!"; Tango::Except::re_throw_exception(e,API_AttributeFailed,ss.str(),"FwdAttr::write"); } } //--------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::init_conf() // // description : // This method initialize FwdAttr class data member in case of forwarded attribute from the root attribute // configuration received during the attribute change event subscription // // argument : // in : // - ev_data : The event data // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::init_conf(AttrConfEventData *ev_data) { // // Set main data // type = ev_data->attr_conf->data_type; writable = ev_data->attr_conf->writable; format = ev_data->attr_conf->data_format; max_x = ev_data->attr_conf->max_dim_x; max_y = ev_data->attr_conf->max_dim_y; assoc_name = ev_data->attr_conf->writable_attr_name; if (writable == READ_WRITE) assoc_name = name; disp_level = ev_data->attr_conf->disp_level; switch (ev_data->attr_conf->memorized) { case NOT_KNOWN: case NONE: mem = false; mem_init = false; break; case MEMORIZED: mem = true; mem_init = false; break; case MEMORIZED_WRITE_INIT: mem = true; mem_init = true; break; default: break; } // // Set configuration // If we already have a label in our conf, save it and reapply it // string local_label; try { local_label = get_label_from_default_properties(); } catch (Tango::DevFailed &e) {} UserDefaultAttrProp udap; if (local_label.empty() == false) udap.set_label(local_label.c_str()); udap.set_description(ev_data->attr_conf->description.c_str()); udap.set_unit(ev_data->attr_conf->unit.c_str()); udap.set_standard_unit(ev_data->attr_conf->standard_unit.c_str()); udap.set_display_unit(ev_data->attr_conf->display_unit.c_str()); udap.set_format(ev_data->attr_conf->format.c_str()); udap.set_min_value(ev_data->attr_conf->min_value.c_str()); udap.set_max_value(ev_data->attr_conf->max_value.c_str()); udap.set_enum_labels(ev_data->attr_conf->enum_labels); udap.set_min_alarm(ev_data->attr_conf->alarms.min_alarm.c_str()); udap.set_max_alarm(ev_data->attr_conf->alarms.max_alarm.c_str()); udap.set_min_warning(ev_data->attr_conf->alarms.min_warning.c_str()); udap.set_max_warning(ev_data->attr_conf->alarms.max_warning.c_str()); udap.set_delta_val(ev_data->attr_conf->alarms.delta_val.c_str()); udap.set_delta_t(ev_data->attr_conf->alarms.delta_t.c_str()); udap.set_event_abs_change(ev_data->attr_conf->events.ch_event.abs_change.c_str()); udap.set_event_rel_change(ev_data->attr_conf->events.ch_event.rel_change.c_str()); udap.set_event_period(ev_data->attr_conf->events.per_event.period.c_str()); udap.set_archive_event_abs_change(ev_data->attr_conf->events.arch_event.archive_abs_change.c_str()); udap.set_archive_event_rel_change(ev_data->attr_conf->events.arch_event.archive_rel_change.c_str()); udap.set_archive_event_period(ev_data->attr_conf->events.arch_event.archive_period.c_str()); this->Attr::set_default_properties(udap); } //+------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::set_default_properties // // description : // This method set the default user properties in the Attr object. At this level, each attribute property is // represented by one instance of the Attrproperty class. // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::set_default_properties(UserDefaultFwdAttrProp &prop_list) { if ((prop_list.label.empty() == false) && (TG_strcasecmp(prop_list.label.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.label.c_str(),NotANumber) != 0)) user_default_properties.push_back(AttrProperty("label",prop_list.label)); } //+------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttr::get_label_from_default_properties // // description : // Get the label property from the user default properties list. Throw exception if not in list // // return : // The label property value // //-------------------------------------------------------------------------------------------------------------------- string &FwdAttr::get_label_from_default_properties() { size_t nb_prop = user_default_properties.size(); size_t ctr; for (ctr = 0;ctr < nb_prop;ctr++) { if (user_default_properties[ctr].get_name() == "label") break; } if (ctr == nb_prop) { Except::throw_exception(API_AttrOptProp,"Property label not defined in list", "FwdAttr::get_label_from_default_properties"); } return user_default_properties[ctr].get_value(); } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::remove_useless_prop // // description : // Remove classical attribute property(ies) if found in prop_list input argument. For forwarded attribute, // the configuration is taken from the root att and should not be taken from the DB. If we found some // useless properties, remove them from the prop list and inform the user to clean up the database. // // argument : // in : // - prop_list : The property list // - dev_name : The device name // //-------------------------------------------------------------------------------------------------------------------- void FwdAttr::remove_useless_prop(vector &prop_list,string &dev_name,MultiAttribute *m_attr) { vector::iterator ite; for (ite = prop_list.begin();ite != prop_list.end();) { if (ite->get_name() == "label" || ite->get_name() == "__root_att") { ++ite; continue; } if (m_attr->is_opt_prop(ite->get_name()) == true) { cerr << "Warning: The forwarded attribute " << get_name() << " belonging to device " << dev_name; cerr << " has the property " << ite->get_name() << " defined in DB.\n"; cerr << "This property will not be taken into account. Please clean up your DB." << endl; ite = prop_list.erase(ite); } else ++ite; } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/fwdattribute.cpp0000644023471100065110000007343613034745001016006 00000000000000static const char *RcsId = "$Id: fwdattribute.cpp 29030 2016-01-19 08:42:57Z taurel $\n$Name$"; //==================================================================================================================== // // file : fwdattribute.cpp // // description : C++ source code for the FwdAttribute class. This class is used to manage attribute. // A Tango Device object instance has one MultiAttribute object which is an aggregate of // Attribute, FwdAttribute, WAttribute and FwdWAttribute objects // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29030 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::FwdAttribute // // description : // Constructor for the FwdAttribute class from the attribute property vector, its type and the device name // // argument : // in : // - prop_list : The attribute property list // - tmp_attr : // - dev_name : The device name // - idx : // //-------------------------------------------------------------------------------------------------------------------- FwdAttribute::FwdAttribute(vector &prop_list,Attr &tmp_attr,string &dev_name,long idx) :WAttribute(prop_list,tmp_attr,dev_name,idx) { FwdAttr &attr = static_cast(tmp_attr); // // Init forwarded attribute specific data // fwd_dev_name = attr.get_fwd_dev_name(); fwd_att_name = attr.get_fwd_root_att(); // // Clear Attrdesc in Root attribute registry // // RootAttRegistry &fdp = Util::instance()->get_root_att_reg(); // fdp.clear_attrdesc(fwd_dev_name,fwd_att_name); } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::~FwdAttribute // // description : // Destructor for the FwdAttribute class // //-------------------------------------------------------------------------------------------------------------------- FwdAttribute::~FwdAttribute() { RootAttRegistry &fdp = Util::instance()->get_root_att_reg(); fdp.remove_root_att(fwd_dev_name,fwd_att_name); } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::set_att_config // // description : // Set attribute configuration. In this case, it is much easier than for classical attribute. The config. comes // from the root attribute and therefore, all tests have already been done in the root attribute and we don't // need to store anything in DB // Note that the main attribute characteristics (format, type, memorized...) are set via FwdAttr instance and are // not changeable here // // This method is called when a new attribute configuration is received via the Callback installed for // forwarded attribute // // argument : // in : // - conf : The attribute new configuration // //-------------------------------------------------------------------------------------------------------------------- void FwdAttribute::set_att_config(const Tango::AttributeConfig_5 &conf) { description = conf.description.in(); unit = conf.unit.in(); standard_unit = conf.standard_unit.in(); display_unit = conf.display_unit.in(); format = conf.format.in(); min_value_str = conf.min_value.in(); max_value_str = conf.max_value.in(); disp_level = conf.level; // // Enum labels (in case of) // enum_labels.clear(); size_t enum_labels_nb = conf.enum_labels.length(); for (size_t loop = 0;loop < enum_labels_nb;loop++) enum_labels.push_back(conf.enum_labels[loop].in()); // // min alarm // if (TG_strcasecmp(conf.att_alarm.min_alarm,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.att_alarm.min_alarm,NotANumber) == 0) { min_alarm_str = AlrmValueNotSpec; alarm_conf.reset(min_level); } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { min_alarm_str = conf.att_alarm.min_alarm.in(); convert_prop_value("min_alarm",min_alarm_str,min_alarm,d_name); alarm_conf.set(min_level); } } // // max alarm // if (TG_strcasecmp(conf.att_alarm.max_alarm,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.att_alarm.max_alarm,NotANumber) == 0) { max_alarm_str = AlrmValueNotSpec; alarm_conf.reset(max_level); } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { max_alarm_str = conf.att_alarm.max_alarm.in(); convert_prop_value("max_alarm",max_alarm_str,max_alarm,d_name); alarm_conf.set(max_level); } } // // min warning // if (TG_strcasecmp(conf.att_alarm.min_warning,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.att_alarm.min_warning,NotANumber) == 0) { alarm_conf.reset(min_warn); min_warning_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { min_warning_str = conf.att_alarm.min_warning.in(); convert_prop_value("min_warning",min_warning_str,min_warning,d_name); alarm_conf.set(min_warn); } } // // max warning // if (TG_strcasecmp(conf.att_alarm.max_warning,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.att_alarm.max_warning,NotANumber) == 0) { alarm_conf.reset(max_warn); max_warning_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { max_warning_str = conf.att_alarm.max_warning.in(); convert_prop_value("max_warning",max_warning_str,max_warning,d_name); alarm_conf.set(max_warn); } } // // delta_val // bool delta_val_defined = false; if (TG_strcasecmp(conf.att_alarm.delta_val,AlrmValueNotSpec) == 0 || TG_strcasecmp(conf.att_alarm.delta_val,NotANumber) == 0) delta_val_str = AlrmValueNotSpec; else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { delta_val_str = conf.att_alarm.delta_val.in(); convert_prop_value("delta_val",delta_val_str,delta_val,d_name); delta_val_defined = true; } } // // delta t // bool delta_t_defined = true; stringstream ss; string tmp_prop = conf.att_alarm.delta_t.in(); if (tmp_prop == AlrmValueNotSpec || tmp_prop == NotANumber) { delta_t_str = "0"; delta_t = 0; } else { ss << tmp_prop; ss >> delta_t; delta_t_str = tmp_prop; delta_t_defined = true; } if (delta_t_defined == true && delta_val_defined == true) alarm_conf.set(rds); else alarm_conf.reset(rds); // // Set event related properties (not stored as strings) // tmp_prop = conf.event_prop.ch_event.rel_change.in(); convert_event_prop(tmp_prop,rel_change); tmp_prop = conf.event_prop.ch_event.abs_change.in(); convert_event_prop(tmp_prop,abs_change); ss.str(""); ss.clear(); tmp_prop = conf.event_prop.per_event.period.in(); if (tmp_prop == AlrmValueNotSpec) event_period = DEFAULT_EVENT_PERIOD; else { ss << tmp_prop; ss >> event_period; } tmp_prop = conf.event_prop.arch_event.rel_change.in(); convert_event_prop(tmp_prop,archive_rel_change); tmp_prop = conf.event_prop.arch_event.abs_change.in(); convert_event_prop(tmp_prop,archive_abs_change); ss.str(""); ss.clear(); tmp_prop = conf.event_prop.arch_event.period.in(); if (tmp_prop == AlrmValueNotSpec) archive_period = INT_MAX; else { ss << tmp_prop; ss >> archive_period; } } // // Same method than previous but the argument is not the same and this one is called when a forwarded // attribute configuration is written via a call in the Forwarded attribute callback in the case of // root attribute not available when the DS was started // void FwdAttribute::set_att_config(AttributeInfoEx *aie_ptr) { data_format = aie_ptr->data_format; writable = aie_ptr->writable; data_type = aie_ptr->data_type; disp_level = aie_ptr->disp_level; enum_labels = aie_ptr->enum_labels; switch (aie_ptr->memorized) { case NOT_KNOWN: case NONE: set_memorized(false); set_memorized_init(false); break; case MEMORIZED: set_memorized(true); set_memorized_init(false); break; case MEMORIZED_WRITE_INIT: set_memorized(true); set_memorized_init(true); break; default: break; } writable_attr_name = aie_ptr->writable_attr_name; if (writable == READ_WRITE) writable_attr_name = name; max_x = aie_ptr->max_dim_x; max_y = aie_ptr->max_dim_y; description = aie_ptr->description; unit = aie_ptr->unit; standard_unit = aie_ptr->standard_unit; display_unit = aie_ptr->display_unit; format = aie_ptr->format; min_value_str = aie_ptr->min_value; max_value_str = aie_ptr->max_value; disp_level = aie_ptr->disp_level; // // min alarm // if (TG_strcasecmp(aie_ptr->alarms.min_alarm.c_str(),AlrmValueNotSpec) == 0 || TG_strcasecmp(aie_ptr->alarms.min_alarm.c_str(),NotANumber) == 0) { alarm_conf.reset(min_level); min_alarm_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { min_alarm_str = aie_ptr->alarms.min_alarm; convert_prop_value("min_alarm",min_alarm_str,min_alarm,d_name); alarm_conf.set(min_level); } } // // max alarm // if (TG_strcasecmp(aie_ptr->alarms.max_alarm.c_str(),AlrmValueNotSpec) == 0 || TG_strcasecmp(aie_ptr->alarms.max_alarm.c_str(),NotANumber) == 0) { alarm_conf.reset(max_level); max_alarm_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { max_alarm_str = aie_ptr->alarms.max_alarm; convert_prop_value("max_alarm",max_alarm_str,max_alarm,d_name); alarm_conf.set(max_level); } } // // min warning // if (TG_strcasecmp(aie_ptr->alarms.min_warning.c_str(),AlrmValueNotSpec) == 0 || TG_strcasecmp(aie_ptr->alarms.min_warning.c_str(),NotANumber) == 0) { alarm_conf.reset(min_warn); min_warning_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { min_warning_str = aie_ptr->alarms.min_warning; convert_prop_value("min_warning",min_warning_str,min_warning,d_name); alarm_conf.set(min_warn); } } // // max warning // if (TG_strcasecmp(aie_ptr->alarms.max_warning.c_str(),AlrmValueNotSpec) == 0 || TG_strcasecmp(aie_ptr->alarms.max_warning.c_str(),NotANumber) == 0) { alarm_conf.reset(max_warn); max_warning_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { max_warning_str = aie_ptr->alarms.max_warning; convert_prop_value("max_warning",max_warning_str,max_warning,d_name); alarm_conf.set(max_warn); } } // // delta val // bool delta_val_defined = false; if (TG_strcasecmp(aie_ptr->alarms.delta_val.c_str(),AlrmValueNotSpec) == 0 || TG_strcasecmp(aie_ptr->alarms.delta_val.c_str(),NotANumber) == 0) { delta_val_str = AlrmValueNotSpec; } else { if ((data_type != Tango::DEV_STRING) && (data_type != Tango::DEV_BOOLEAN) && (data_type != Tango::DEV_STATE)) { delta_val_str = aie_ptr->alarms.delta_val; convert_prop_value("delta_val",delta_val_str,delta_val,d_name); delta_val_defined = true; } } // // delta t // bool delta_t_defined = false; string tmp_prop = aie_ptr->alarms.delta_t; if (tmp_prop == AlrmValueNotSpec) { delta_t_str = "0"; delta_t = 0; } else { stringstream ss1; ss1 << tmp_prop; ss1 >> delta_t; delta_t_str = tmp_prop; delta_t_defined = true; } if (delta_t_defined == true && delta_val_defined == true) alarm_conf.set(rds); else alarm_conf.reset(rds); // // Set event related properties (not stored as strings) // stringstream ss; tmp_prop = aie_ptr->events.ch_event.rel_change; convert_event_prop(tmp_prop,rel_change); tmp_prop = aie_ptr->events.ch_event.abs_change; convert_event_prop(tmp_prop,abs_change); ss.str(""); ss.clear(); if (aie_ptr->events.per_event.period != AlrmValueNotSpec) { ss << aie_ptr->events.per_event.period; ss >> event_period; } tmp_prop = aie_ptr->events.arch_event.archive_rel_change; convert_event_prop(tmp_prop,archive_rel_change); tmp_prop = aie_ptr->events.arch_event.archive_abs_change; convert_event_prop(tmp_prop,archive_abs_change); ss.str(""); ss.clear(); if (aie_ptr->events.arch_event.archive_period != AlrmValueNotSpec) { ss << aie_ptr->events.arch_event.archive_period; ss >> archive_period; } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::convert_event_prop // // description : // Convert event property received as a string into double // // argument : // in : // - prop_str : The attribute property as a string // out : // - ptr : Pointer to where the converted vlue must be stored // //-------------------------------------------------------------------------------------------------------------------- void FwdAttribute::convert_event_prop(string &prop_str,double *ptr) { stringstream ss; if (prop_str != AlrmValueNotSpec) { string::size_type pos = prop_str.find(','); if (pos == string::npos) { double tmp_db; ss << prop_str; ss >> tmp_db; ptr[0] = tmp_db; ptr[1] = tmp_db; } else { string first = prop_str.substr(0,pos); string second = prop_str.substr(pos + 1); ss << first; ss >> ptr[0]; ss.str(""); ss.clear(); ss << second; ss >> ptr[1]; } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::upd_att_config_base // // description : // // // argument : // in : // - conf : The attribute new configuration // //-------------------------------------------------------------------------------------------------------------------- void FwdAttribute::upd_att_config_base(const char *new_label) { cout4 << "Entering FwdAttribute::upd_att_config_base" << endl; // // Throw exception in case of fwd att wrongly configured or if the root device is not yet accessible // if (get_data_type() == DATA_TYPE_UNKNOWN) { string desc("Attribute "); desc = desc + name + " is a forwarded attribute and its root device ("; desc = desc + fwd_dev_name; desc = desc + ") is not yet available"; Tango::Except::throw_exception(API_AttrConfig,desc,"FwdAttribute::upd_att_config_base"); } // // A new label (the only att property stored locally) // if (string(new_label) != label) upd_att_label(new_label); } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::upd_att_config // // description : // Update a forwarded attribute config. Only label is maintained locally. Send att conf. to root device only // if it is modified compared to what we have // // argument : // in : // - conf : The attribute new configuration // //-------------------------------------------------------------------------------------------------------------------- void FwdAttribute::upd_att_config(const Tango::AttributeConfig_5 &conf) { // // Send new config to root attribute if received configuration if different than the one we already have // if (new_att_conf(Tango_nullptr,&conf) == true) { AttributeInfoListEx aile; AttributeInfoEx aie; aie = &conf; aie.label = get_fwd_att_name(); RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *dev = rar.get_root_att_dp(fwd_dev_name); aie.name = fwd_att_name; if (aie.writable_attr_name != AssocWritNotSpec) aie.writable_attr_name = fwd_att_name; aile.push_back(aie); cout4 << "Sending att conf to root device " << fwd_dev_name << endl; dev->set_attribute_config(aile); } } void FwdAttribute::upd_att_config(const Tango::AttributeConfig_3 &conf) { // // Send new config to root attribute if received configuration if different than the one we already have // if (new_att_conf(&conf,Tango_nullptr) == true) { AttributeInfoListEx aile; AttributeInfoEx aie; aie = &conf; aie.label = get_fwd_att_name(); RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *dev = rar.get_root_att_dp(fwd_dev_name); aie.name = fwd_att_name; aile.push_back(aie); cout4 << "Sending att conf to root device " << fwd_dev_name << endl; dev->set_attribute_config(aile); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::new_att_conf // // description : // Check if the new attribute config is the same than the one we have // // argument : // in : // - conf : The attribute new configuration // // return : // A boolean set to true if the new config is different than the one we have // //-------------------------------------------------------------------------------------------------------------------- bool FwdAttribute::new_att_conf(const Tango::AttributeConfig_3 *conf3,const Tango::AttributeConfig_5 *conf5) { bool ret = false; if (conf3 != Tango_nullptr) { ret = new_att_conf_base(*conf3); } else { ret = new_att_conf_base(*conf5); if (ret == false) { if (conf5->memorized != is_memorized()) ret = true; else if (conf5->memorized == true) { if (conf5->mem_init != is_memorized_init()) ret = true; } } } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::upd_att_label // // description : // Update the forwarded attribute label property. It is the only property which stays local for forwarded // attribute // // argument : // in : // - new_label : The new attribute label // //-------------------------------------------------------------------------------------------------------------------- void FwdAttribute::upd_att_label(const char *new_label) { cout4 << "Entering FwdAttribute::upd_att_label() for att " << name << " with label set to " << new_label << endl; string old_label = label; // // Change label according to att property changing rule: // LabelNotSpec or AlrmvalueNotSpec means return to lib default (att name in this case) // "" (empty string) means returns to user def if any otherwise return to lib default // NaN means returns to class default (if any), user default (if any), lib default // bool store_db = false; bool remove_db = false; Tango::DeviceClass *dev_class = get_att_device_class(d_name); Tango::MultiClassAttribute *mca = dev_class->get_class_attr(); Tango::Attr &att = mca->get_attr(name); vector &def_user_prop = att.get_user_default_properties(); size_t nb_user = def_user_prop.size(); vector &def_class_prop = att.get_class_properties(); size_t nb_class = def_class_prop.size(); if(TG_strcasecmp(new_label,AlrmValueNotSpec) == 0 || (TG_strcasecmp(new_label,LabelNotSpec) == 0) || (TG_strcasecmp(new_label,name.c_str()) == 0)) { // force library defaults (even if user defaults defined) label = name; remove_db = true; } else if (TG_strcasecmp(new_label,NotANumber) == 0) { // set class default value if defined, otherwise use the user default or library defaults bool found = prop_in_list("label",label,nb_class,def_class_prop); if (found == false) { found = prop_in_list("label",label,nb_user,def_user_prop); remove_db = true; if (found == false) { label = name; } } } else if (strlen(new_label) == 0) { // set user default value if defined, otherwise use the library defaults bool found = prop_in_list("label",label,nb_user,def_user_prop); remove_db = true; if (found == false) { label = name; } } else { // set property label = new_label; store_db = true; } // // Update label in RootAttRegistry // RootAttRegistry &rar = Util::instance()->get_root_att_reg(); rar.update_label(fwd_dev_name,fwd_att_name,label); // // Store new value in DB // if (store_db == true) { DbDatum db_prop(name); DbDatum db_lab("label"); db_prop << 1L; db_lab << new_label; DbData db_dat; db_dat.push_back(db_prop); db_dat.push_back(db_lab); try { Util::instance()->get_database()->put_device_attribute_property(d_name,db_dat); } catch (Tango::DevFailed &e) { label = old_label; rar.update_label(fwd_dev_name,fwd_att_name,label); throw; } } // // Remove value from DB because label is now the default one (class, user or lib) // if (remove_db == true) { DbData db_data; db_data.push_back(DbDatum(name)); db_data.push_back(DbDatum("label")); try { Util::instance()->get_database()->delete_device_attribute_property(d_name, db_data); } catch (Tango::DevFailed &e) { label = old_label; rar.update_label(fwd_dev_name,fwd_att_name,label); throw; } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::read_root_att_history // // description : // Get attribute polling history from the root attribute. // Note that we do not use the classical API DeviceProxy class instance. This is because for this call, the // network transfer uses RLE algorithm and the API is doing the decoding. In our case, we want data from // root attribute in RLE and directly transfer them in RLE to our client. // // argument : // in : // - n : Required history depth // //-------------------------------------------------------------------------------------------------------------------- DevAttrHistory_5 *FwdAttribute::read_root_att_history(long n) { // // Get CORBA object reference // RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *dp = rar.get_root_att_dp(get_fwd_dev_name()); Device_5_var dev = dp->get_device_5(); // // Get data from root device (Reminder: we don't use the classical API. See above) // DevAttrHistory_5 *hist_5; int ctr = 0; while (ctr < 2) { try { dp->check_and_reconnect(); hist_5 = dev->read_attribute_history_5(get_fwd_att_name().c_str(),n); ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"FwdAttribute","read_root_att_history",dp); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"FwdAttribute","read_root_att_history",dp); } else { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(one,"API_CommunicationFailed", desc.str(),"FwdAttribute::read_root_att_history()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"FwdAttribute","read_root_att_history",dp); } else { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(comm,"API_CommunicationFailed", desc.str(),"FwdAttribute::read_root_att_history()"); } } catch (CORBA::SystemException &ce) { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(ce,"API_CommunicationFailed", desc.str(),"FwdAttribute::read_root_att_history()"); } } // // Update attribute name in returned data // hist_5->name = get_name().c_str(); return hist_5; } //-------------------------------------------------------------------------------------------------------------------- // // method : // FwdAttribute::write_read_root_att // // description : // Get attribute polling history from the root attribute. // Note that we do not use the classical API DeviceProxy class instance. This is because for this call, the // network transfer uses RLE algorithm and the API is doing the decoding. In our case, we want data from // root attribute in RLE and directly transfer them in RLE to our client. // // argument : // in : // - n : Required history depth // //-------------------------------------------------------------------------------------------------------------------- AttributeValueList_5 *FwdAttribute::write_read_root_att(Tango::AttributeValueList_4& values) { // // Get CORBA object reference // RootAttRegistry &rar = Util::instance()->get_root_att_reg(); DeviceProxy *dp = rar.get_root_att_dp(get_fwd_dev_name()); Device_5_var dev5 = dp->get_device_5(); // // Update attribute name // values[0].name = get_fwd_att_name().c_str(); Tango::DevVarStringArray dvsa; dvsa.length(1); dvsa[0] = CORBA::string_dup(get_fwd_att_name().c_str()); int ctr = 0; AttributeValueList_5 *attr_value_list_5; Tango::AccessControlType local_act; while (ctr < 2) { try { dp->check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(dp->device); dev->ping(); } catch(...) { dp->set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << get_fwd_dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"FwdAttribute::write_read_root_att()"); } // // Now, call the root device server // ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); attr_value_list_5 = dev5->write_read_attributes_5(values,dvsa,ci); ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << get_fwd_dev_name(); desc << ", attribute "; desc << values[0].name.in(); desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"FwdAttribute::write_read_root_att()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << get_fwd_dev_name(); desc << ", attribute "; desc << values[0].name.in(); desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"FwdAttribute::write_read_root_att()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"FwdAttribute::write_read_root_att()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"FwdAttribute","write_read_root_att()",dp); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"FwdAttribute","write_read_root_att",dp); } else { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_read_attribute on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"FwdAttribute::write_read_root_att()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"FwdAttribute","write_read_root_att",dp); } else { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"FwdAttribute::write_read_root_att"); } } catch (CORBA::SystemException &ce) { dp->set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << get_fwd_dev_name() << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"FwdAttribute::write_read_root_att()"); } } // // Init the returned DeviceAttribute instance // (*attr_value_list_5)[0].name = get_name().c_str(); return attr_value_list_5; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/logcmds.cpp0000644023471100065110000003032713034745001014722 00000000000000static const char *RcsId = "$Id: logcmds.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : LogCmds.cpp // // description : Logging oriented commands of the DServerClass. // // project : TANGO // // author(s) : N.Leclercq // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 3.5 2010/09/09 13:46:00 taurel // - Add year 2010 in Copyright notice // // Revision 3.4 2009/01/21 12:47:15 taurel // - Change CopyRights for 2009 // // Revision 3.3 2008/10/06 15:01:36 taurel // - Changed the licensing info from GPL to LGPL // // Revision 3.2 2008/10/03 06:52:31 taurel // - Add some licensing info in each files // // Revision 3.1 2003/05/28 14:55:09 taurel // Add the include (conditionally) of the include files generated by autoconf // // Revision 3.0 2003/03/25 16:44:09 taurel // Many changes for Tango release 3.0 including // - Added full logging features // - Added asynchronous calls // - Host name of clients now stored in black-box // - Three serialization model in DS // - Fix miscellaneous bugs // - Ported to gcc 3.2 // - Added ApiUtil::cleanup() and destructor methods // - Some internal cleanups // - Change the way how TangoMonitor class is implemented. It's a recursive // mutex // // Revision 2.3 2003/03/19 10:41:32 nleclercq // *** empty log message *** // // Revision 2.2 2003/03/11 17:55:54 nleclercq // Switch from log4cpp to log4tango // // Revision 2.1 2003/02/17 14:57:42 taurel // Added the new Tango logging stuff (Thanks Nicolas from Soleil) // // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO #include namespace Tango { //+------------------------------------------------------------------------- // // method : AddLoggingTarget::AddLoggingTarget // // description : Constructor for Command class AddLoggingTarget // //-------------------------------------------------------------------------- AddLoggingTarget::AddLoggingTarget (const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc) : Command(name, in, out) { set_in_type_desc(const_cast(in_desc)); } //+------------------------------------------------------------------------- // // method : AddLoggingTarget::execute // // description : Trigger the execution of the method implementing // the AddLoggingTarget command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *AddLoggingTarget::execute (DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "AddLoggingTarget::execute(): arrived " << endl; // // Extract the input data // const DevVarStringArray *targets; if ((in_any >>= targets) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarStringArray", (const char *)"AddLoggingTarget::execute"); } // // Call the concrete device method // (static_cast(device))->add_logging_target(targets); // // Return to caller // CORBA::Any *ret = return_empty_any("AddLoggingTarget"); return ret; } //+------------------------------------------------------------------------- // // method : RemoveLoggingTarget::RemoveLoggingTarget // // description : Constructor for Command class RemoveLoggingTarget // //-------------------------------------------------------------------------- RemoveLoggingTarget::RemoveLoggingTarget (const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc) : Command(name, in, out) { set_in_type_desc(const_cast(in_desc)); } //+------------------------------------------------------------------------- // // method : RemoveLoggingTarget::execute // // description : Trigger the execution of the method implementing // the RemoveLoggingTarget command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *RemoveLoggingTarget::execute (DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "RemoveLoggingTarget::execute(): arrived " << endl; // // Extract the input data // const DevVarStringArray *targets; if ((in_any >>= targets) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarStringArray", (const char *)"RemoveLoggingTarget::execute"); } // // Call the concrete device method // (static_cast(device))->remove_logging_target(targets); // // Return to caller // CORBA::Any *ret = return_empty_any("RemoveLoggingTarget"); return ret; } //+------------------------------------------------------------------------- // // method : GetLoggingTarget::GetLoggingTarget // // description : Constructor for Command class GetLoggingTarget // //-------------------------------------------------------------------------- GetLoggingTarget::GetLoggingTarget (const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc, const std::string &out_desc) : Command(name, in, out) { set_in_type_desc(const_cast(in_desc)); set_out_type_desc(const_cast(out_desc)); } //+------------------------------------------------------------------------- // // method : GetLoggingTarget::execute // // description : Trigger the execution of the method implementing // the GetLoggingTarget command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *GetLoggingTarget::execute (DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "GetLoggingTarget::execute(): arrived " << endl; // // Extract the input data // const char* tmp_str; if ((in_any >>= tmp_str) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevString", (const char *)"GetLoggingTarget::execute"); } // // Return to caller // return insert((static_cast(device))->get_logging_target(std::string(tmp_str))); } //+------------------------------------------------------------------------- // // method : SetLoggingLevel::SetLoggingLevel // // description : Constructor for Command class SetLoggingLevel // //-------------------------------------------------------------------------- SetLoggingLevel::SetLoggingLevel (const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc) : Command(name, in, out) { set_in_type_desc(const_cast(in_desc)); } //+------------------------------------------------------------------------- // // method : SetLoggingLevel::execute // // description : Trigger the execution of the method implementing // the SetLoggingLevel command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *SetLoggingLevel::execute (DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "SetLoggingLevel::execute(): arrived " << endl; // // Extract the input data // const DevVarLongStringArray *argin; if ((in_any >>= argin) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarLongStringArray", (const char *)"SetLoggingLevel::execute"); } // // Call the concrete device method // (static_cast(device))->set_logging_level(argin); // // Return to caller // CORBA::Any *ret = return_empty_any("StartLogging"); return ret; } //+------------------------------------------------------------------------- // // method : GetLoggingLevel::GetLoggingLevel // // description : Constructor for Command class GetLoggingLevel // //-------------------------------------------------------------------------- GetLoggingLevel::GetLoggingLevel (const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const std::string &in_desc, const std::string &out_desc) : Command(name, in, out) { set_in_type_desc(const_cast(in_desc)); set_out_type_desc(const_cast(out_desc)); } //+------------------------------------------------------------------------- // // method : GetLoggingLevel::execute // // description : Trigger the execution of the method implementing // the GetLoggingLevel command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *GetLoggingLevel::execute (DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "GetLoggingLevel::execute(): arrived " << endl; // // Extract the input data // const DevVarStringArray *argin; if ((in_any >>= argin) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarStringArray", (const char *)"GetLoggingLevel::execute"); } // // Return to caller // return insert((static_cast(device))->get_logging_level(argin)); } //+------------------------------------------------------------------------- // // method : StopLogging::StopLogging // // description : Constructor for Command class StopLogging // //-------------------------------------------------------------------------- StopLogging::StopLogging(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) : Command(name, in, out) { } //+------------------------------------------------------------------------- // // method : StopLoggingLevel::execute // // description : Trigger the execution of the method implementing // the StopLogging command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *StopLogging::execute (DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "StopLogging::execute(): arrived " << endl; // // Call the concrete device method // (static_cast(device))->stop_logging(); // // Return to caller // CORBA::Any *ret = return_empty_any("StopLogging"); return ret; } //+------------------------------------------------------------------------- // // method : StartLogging::StartLogging // // description : Constructor for Command class StartLogging // //-------------------------------------------------------------------------- StartLogging::StartLogging (const char *name, Tango::CmdArgType in, Tango::CmdArgType out) : Command(name, in, out) { } //+------------------------------------------------------------------------- // // method : StartLogging::execute // // description : Trigger the execution of the method implementing // the StartLogging command of the DServerClass // //-------------------------------------------------------------------------- CORBA::Any *StartLogging::execute (DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "StartLogging::execute(): arrived " << endl; // // Call the concrete device method // (static_cast(device))->start_logging(); // // Return to caller // CORBA::Any *ret = return_empty_any("StartLogging"); return ret; } } // namespace Tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/logging.cpp0000644023471100065110000013107213034745001014717 00000000000000static const char *RcsId = "$Id: logging.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : Logging.cpp // // description : TLS helper class // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO //----------------------------------------------------------------------------- // HEADERS //----------------------------------------------------------------------------- #ifdef _TG_WINDOWS_ # include #else # include # include # include # include # include #endif #include #include #include namespace Tango { //----------------------------------------------------------------------------- // TANGO KERNEL CMD LINE DEBUGGING LEVEL //----------------------------------------------------------------------------- #define kTANGO_CORE_CMD_LINE_LEVEL 5 //----------------------------------------------------------------------------- // LOCAL LOG MACRO (CAN'T USE LOGGING STUFFS DURING LOGGING STUFFS INIT STAGE!) //----------------------------------------------------------------------------- #define _VERBOSE(_MSG_) \ if (Logging::_cmd_line_level >= kTANGO_CORE_CMD_LINE_LEVEL) \ ::printf _MSG_; //----------------------------------------------------------------------------- // LOCAL CONSTs (should be a Logging static const member) //----------------------------------------------------------------------------- static const char* kDefaultTargetName = "default"; static const char* kDefaultConsoleName = "cout"; //----------------------------------------------------------------------------- // STATIC MEMBERS //----------------------------------------------------------------------------- // the DServer logger (use to output TANGO low level messages) log4tango::Logger* _core_logger = 0; // the logging path (use to store file logging targets) std::string Logging::_log_path(""); // the threshold for RollingFileAppender size_t Logging::_rft = 0; // the cmd line verbose level int Logging::_cmd_line_level = 0; //+---------------------------------------------------------------------------- // method : Logging::init() //----------------------------------------------------------------------------- void Logging::init (const std::string& ds_name, // dserver name int cmd_line_level, // cmd. line verbose level bool use_db, // true if using the TANGO-db Database &db, // Db object or null Util *tg) // Tango::Util object { // logging path env. var. name const char* kTangoLogPathVar = "TANGO_LOG_PATH"; // default logging path #ifdef _TG_WINDOWS_ const char* kDefaultTangoLogPath = "c:/tango"; #else const char* kDefaultTangoLogPath = "/tmp/tango"; #endif try { // store cmd line verbose level (set by user) Logging::_cmd_line_level = cmd_line_level; _VERBOSE(("Entering Logging::init\n")); // set default threshold for RollingFileAppender Logging::_rft = kDefaultRollingThreshold; // try to get logging path from kTangoLogPathVar env. var. char *ftg_path = ::getenv(kTangoLogPathVar); if (ftg_path == 0 || ::strlen(ftg_path) == 0) { // log path not set or empty, use default path Logging::_log_path = kDefaultTangoLogPath; #ifndef _TG_WINDOWS_ struct passwd* pw = getpwuid(getuid()); if (pw) { Logging::_log_path = Logging::_log_path + '-' + pw->pw_name; } #else BOOL ret; TCHAR buffer[128]; DWORD nb = 128; ret = GetUserName(buffer,&nb); if (ret == 0){ Logging::_log_path = Logging::_log_path + '-' + buffer; } #endif } else { Logging::_log_path = ftg_path; } _VERBOSE(("\tTANGO_LOG_PATH is %s\n", Logging::_log_path.c_str())); // build logger name from dserver name std::string dserver_dev_name("dserver/" + ds_name); // instanciate the logger log4tango::Logger* logger = new log4tango::Logger(dserver_dev_name); // is logging level set from cmd line? bool level_set_from_cmd_line = (cmd_line_level >= kTANGO_CORE_CMD_LINE_LEVEL) ? true : false; _VERBOSE(("\tcmd line logging level is %d\n", cmd_line_level)); // set logger's effective level if (level_set_from_cmd_line) { logger->set_level(log4tango::Level::DEBUG); } else { logger->set_level(log4tango::Level::ERROR); } // core-logger's targets std::vector targets; if (use_db == true) { // get logging properties from database try { DbData db_data; // the logging path property (overwrites env.var.) db_data.push_back(DbDatum("logging_path")); // the core-logger's rolling file threshold db_data.push_back(DbDatum("logging_rft")); // the core-logger's logging level db_data.push_back(DbDatum("logging_level")); // the core-logger's logging target list db_data.push_back(DbDatum("logging_target")); // get properties from TANGO-db db.get_device_property(dserver_dev_name, db_data,tg->get_db_cache()); // set logging path string level_str("WARN"); if (db_data[0].is_empty() == false) { db_data[0] >> Logging::_log_path; _VERBOSE(("\tLogging::_log_path is %s (set from db)\n", Logging::_log_path.c_str())); } Logging::_rft = kDefaultRollingThreshold; // set rolling file threshold if (db_data[1].is_empty() == false) { unsigned long rtf = 0; db_data[1] >> rtf; Logging::_rft = static_cast(rtf); if (rtf < kMinRollingThreshold) { Logging::_rft = kMinRollingThreshold; } else if (rtf > kMaxRollingThreshold) { Logging::_rft = kMaxRollingThreshold; } #ifdef TANGO_LONG64 _VERBOSE(("\tRolling file threshold is %lu Kb\n", Logging::_rft)); #else _VERBOSE(("\tRolling file threshold is %d Kb\n", Logging::_rft)); #endif } // set logging level (if not set from cmd line) if (! level_set_from_cmd_line) { string level_str("WARN"); if (db_data[2].is_empty() == false) db_data[2] >> level_str; _VERBOSE(("\tproperty::level is %s\n", level_str.c_str())); log4tango::Level::Value level = Logging::tango_to_log4tango_level(level_str, false); _VERBOSE(("\teffective property::level is %s\n", log4tango::Level::get_name(level).c_str())); logger->set_level(level); } // get logging targets if (db_data[3].is_empty() == false) db_data[3] >> targets; } catch (...) { _VERBOSE(("\texception caught while handling logging properties\n")); // ignore any exception } } // create this logging dir Logging::_log_path += "/" + ds_name; int res = Logging::create_log_dir(Logging::_log_path); _VERBOSE(("\tLogging::create_log_dir(%s) returned %d\n", Logging::_log_path.c_str(), res)); // be sure there is a console target if level set from cmd line if (level_set_from_cmd_line) { Logging::add_logging_target(logger, kLogTargetConsole, 0); _VERBOSE(("\tadded console target (logging level set from cmd line)\n")); } for (unsigned int i = 0; i < targets.size(); i++) { _VERBOSE(("\tadding property::targets[%d]=%s\n", i, targets[i].c_str())); Logging::add_logging_target(logger, targets[i], 0); } Tango::_core_logger = logger; _VERBOSE(("Leaving Logging::init\n")); } catch (...) { _VERBOSE(("\tUnknown exception caught\n")); // ignore exception } } //+---------------------------------------------------------------------------- // method : Logging::cleanup //----------------------------------------------------------------------------- void Logging::cleanup (void) { delete Tango::_core_logger; Tango::_core_logger = 0; } //+---------------------------------------------------------------------------- // method : Logging::add_logging_target //----------------------------------------------------------------------------- void Logging::add_logging_target (const Tango::DevVarStringArray *argin) { try { // fight against the "zombie appender" syndrom Logging::kill_zombie_appenders(); // trace cout4 << "Entering Logging::add_logging_target" << endl; // log input unsigned int i; for (i = 0; i < argin->length(); i++) { cout4 << "input string = " << (*argin)[i].in() << endl; } // N x [device-name, target-type::target-name] expected // The length of the input sequence must be a multiple of 2 if ((argin->length() % 2) != 0) { Except::throw_exception((const char *)API_MethodArgument, (const char *)"Incorrect number of inout arguments", (const char *)"Logging::add_logging_target"); } // device name pattern std::string pattern; // the device list (devices which name matches pattern) std::vector dl; // for each tuple{dev_name, target_type, target_name} in argin for (i = 0; i < argin->length(); i += 2) { // get device name pattern; pattern = (*argin)[i]; // convert to lower case std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower); // get devices which name matches the pattern pattern dl = Util::instance()->get_device_list(pattern); // throw an exception if the list is empty if (dl.empty()) { TangoSys_OMemStream o; o << "No device name matching pattern <" << pattern << ">" << ends; Except::throw_exception((const char *)API_DeviceNotFound,o.str(), (const char *)"Logging::add_logging_target"); } // Check that none of the concerned device(s) is locked by another client DServer *adm_dev = Util::instance()->get_dserver_device(); for (unsigned int j = 0; j < dl.size(); j++) { adm_dev->check_lock_owner(dl[j],"add_logging_target",(dl[j]->get_name()).c_str()); } // for each device matching pattern... for (unsigned int j = 0; j < dl.size(); j++) { // ...add logging target Logging::add_logging_target(dl[j]->get_logger(), std::string((*argin)[i + 1])); } } // for each tuple // trace cout4 << "Leaving Logging::add_logging_target" << endl; } catch (std::exception& e) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_InternalError, o.str(), (const char *)"Logging::add_logging_target"); } } //+------------------------------------------------------------------------- // method : Logging::add_logging_target //-------------------------------------------------------------------------- void Logging::add_logging_target(log4tango::Logger* logger, const std::string& tg_type, const std::string& tg_name, int throw_exception) { std::string tg_type_name(tg_type); tg_type_name += kLogTargetSep + tg_name; Logging::add_logging_target(logger, tg_type_name, throw_exception); } //+------------------------------------------------------------------------- // method : Logging::add_logging_target //-------------------------------------------------------------------------- void Logging::add_logging_target(log4tango::Logger* logger, const std::string& in_type_name, int throw_exception) { try { // trace cout4 << "Entering Logging::add_logging_target (internal impl)" << endl; // check input if (!logger) { //--TODO::better error handler needed? cout4 << "internal error (logger is null)" << endl; return; } // target type (as string) std::string ltg_type_str; // target name std::string ltg_name_str; // avoid case sensitive troubles std::string type_name(in_type_name); std::transform(type_name.begin(), type_name.end(), type_name.begin(), ::tolower); // split into and Logging::get_target_type_and_name(type_name, ltg_type_str, ltg_name_str); // target type (as int) int ltg_type; if (ltg_type_str == kLogTargetConsole) { ltg_type = LOG_CONSOLE; // force ltg_name_str to kDefaultConsoleName ltg_name_str = kDefaultConsoleName; } else if (ltg_type_str == kLogTargetFile) { ltg_type = LOG_FILE; } else if (ltg_type_str == kLogTargetDevice) { ltg_type = LOG_DEVICE; } else { if (throw_exception) { TangoSys_OMemStream o; o << "Invalid logging target type specified (" << ltg_type_str << ")" << ends; Except::throw_exception((const char *)API_MethodArgument, o.str(), (const char *)"DeviceImpl::add_logging_target"); } return; } // build full path name (for file targets) std::string full_file_name; // build internal target name (i.e. appender name) std::string appender_name(ltg_type_str + kLogTargetSep); switch (ltg_type) { case LOG_CONSOLE: { appender_name += kDefaultConsoleName; } break; case LOG_FILE: { if (ltg_name_str == kDefaultTargetName) { // use default path and file name full_file_name = Logging::_log_path + "/"; full_file_name += Logging::dev_to_file_name(logger->get_name()) + ".log"; } else if (ltg_name_str.find('/') != std::string::npos) { // user specified a "custom" path and file name full_file_name = ltg_name_str; } else { // user specified a "custom" file name full_file_name = Logging::_log_path + "/" + ltg_name_str; } ltg_name_str = full_file_name; appender_name += ltg_name_str; } break; case LOG_DEVICE: { if (ltg_name_str == kDefaultTargetName) { if (throw_exception) { TangoSys_OMemStream o; o << "Device target name must be specified (no default value)" << ends; Except::throw_exception((const char *)API_MethodArgument, o.str(), (const char *)"DeviceImpl::add_logging_target"); } return; } appender_name += ltg_name_str; } break; } // switch (ltg_type) // attach the appender to the logger if not already attached log4tango::Appender* appender = logger->get_appender(appender_name); if (!appender) { cout4 << "Adding logging target " << appender_name << " to " << logger->get_name() << endl; // instanciate the appender (i.e. the target) and the layout (if needed) switch (ltg_type) { case LOG_CONSOLE: { appender = new CoutAppender(appender_name); if (appender == 0) { cout4 << "Internal error (Appender instanciation failed)" << endl; if (throw_exception) { TangoSys_OMemStream o; o << "Out of memory error" << ends; Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } } break; // case LOG_CONSOLE case LOG_FILE: { appender = new TangoRollingFileAppender(appender_name, full_file_name, Logging::_rft); if (appender == 0) { if (throw_exception) { TangoSys_OMemStream o; o << "Out of memory error" << ends; Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } if (appender->is_valid() == false) { delete appender; appender = 0; if (throw_exception) { TangoSys_OMemStream o; o << "Could not open logging file " << full_file_name << ends; Except::throw_exception((const char *)API_CannotOpenFile, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } log4tango::XMLLayout *layout = new log4tango::XMLLayout(); if (layout == 0) { delete appender; appender = 0; if (throw_exception) { TangoSys_OMemStream o; o << "Out of memory error" << ends; Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } appender->set_layout(layout); } break; // case LOG_FILE case LOG_DEVICE: { appender = new TangoAppender(logger->get_name(), appender_name, ltg_name_str); if (appender == 0) { if (throw_exception) { TangoSys_OMemStream o; o << "Out of memory error" << ends; Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } if (appender->is_valid() == false) { delete appender; appender = 0; if (throw_exception) { TangoSys_OMemStream o; o << "Could not connect to log consumer " << ltg_name_str << ends; Except::throw_exception((const char *)API_ConnectionFailed, o.str(), (const char *)"DeviceImpl::add_logging_target"); } break; } } break; // case LOG_DEVICE } // attach the appender to the logger if (appender) { logger->add_appender(appender); } } else { cout4 << "Target " << appender_name << " is already attached to " << logger->get_name() << endl; } cout4 << "Leaving Logging::add_logging_target (internal impl)" << endl; } catch (std::exception& e) { if (throw_exception) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_StdException, o.str(), (const char *)"Logging::add_logging_target"); } } } //+---------------------------------------------------------------------------- // method : Logging::remove_logging_target //----------------------------------------------------------------------------- void Logging::remove_logging_target (const Tango::DevVarStringArray *argin) { try { // fight against the "zombie appender" syndrom Logging::kill_zombie_appenders(); // trace cout4 << "Entering Logging::remove_logging_target" << endl; // log input unsigned int i; for (i = 0; i < argin->length(); i++) { cout4 << "Input string = " << (*argin)[i].in() << endl; } // N x [device-name, target-type, target-name] expected // The length of the input sequence must a multiple of 3 if ((argin->length() % 2) != 0) { Except::throw_exception((const char *)API_WrongNumberOfArgs, (const char *)"Incorrect number of inout arguments", (const char *)"Logging::remove_logging_target"); } // a logger log4tango::Logger* logger; // input arg target_type::target::name as std::string std::string type_name; // dev_name pattern std::string pattern; // target type (as int and string) int tg_type = 0; std::string tg_type_str; // target name or pattern std::string tg_name; // the "remove all targets of type " flag int remove_all_targets; // the device list std::vector dl(0); // for each tuple{dev_name, target_type::target_name} for (i = 0; i < argin->length();) { // get device name wildcard; pattern = (*argin)[i++]; // convert to lower case std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower); // get devices which name matches the pattern pattern dl = Util::instance()->get_device_list(pattern); // throw an exception if the list is empty if (dl.empty()) { TangoSys_OMemStream o; o << "No device name matching pattern <" << pattern << ">" << ends; Except::throw_exception((const char *)API_DeviceNotFound,o.str(), (const char *)"Logging::remove_logging_target"); } // Check that none of the concerned device(s) is locked by another client DServer *adm_dev = Util::instance()->get_dserver_device(); for (unsigned int j = 0; j < dl.size(); j++) { adm_dev->check_lock_owner(dl[j],"remove_logging_target",(dl[j]->get_name()).c_str()); } // get target type and name from argin (syntax type::name) type_name = (*argin)[i++]; std::transform(type_name.begin(), type_name.end(), type_name.begin(), ::tolower); Logging::get_target_type_and_name(type_name, tg_type_str, tg_name); std::transform(tg_type_str.begin(), tg_type_str.end(), tg_type_str.begin(), ::tolower); // check target type if (tg_type_str == kLogTargetConsole) { tg_type = Tango::LOG_CONSOLE; // force target name to kDefaultConsoleName tg_name = kDefaultConsoleName; } else if (tg_type_str == kLogTargetFile) { tg_type = Tango::LOG_FILE; } else if (tg_type_str == kLogTargetDevice) { tg_type = Tango::LOG_DEVICE; } else { TangoSys_OMemStream o; o << "Logging target type <" << tg_type_str << "> not supported" << ends; Except::throw_exception((const char *)API_MethodArgument, o.str(), (const char *)"Logging::remove_logging_target"); } // do we have to remove all targets? remove_all_targets = (tg_name == "*") ? 1 : 0; // for each device matching pattern for (unsigned int j = 0; j < dl.size(); j++) { // get device's logger logger = dl[j]->get_logger(); if (logger == 0) { TangoSys_OMemStream o; o << "Internal error (got a NULL logger)" << ends; Except::throw_exception((const char *)API_InternalError, o.str(), (const char *)"Logging::remove_logging_target"); } // CASE I: remove ONE target of type if (remove_all_targets == 0) { // build full appender name (target_type+sep+target_name) std::string full_tg_name = tg_type_str + kLogTargetSep; // a special case : target is the a file if (tg_type == Tango::LOG_FILE) { if (tg_name == kDefaultTargetName) { // use both default path and file name full_tg_name += Logging::_log_path + "/"; full_tg_name += Logging::dev_to_file_name(logger->get_name()) + ".log"; } else if (tg_name.find('/') != std::string::npos) { // user specified a "custom" path and file name full_tg_name += tg_name; } else { // user specified a "custom" file name full_tg_name += Logging::_log_path + "/" + tg_name; } } else { full_tg_name += tg_name; } cout4 << "removing target " << full_tg_name << " from " << dl[j]->get_name() << endl; // remove appender from device's logger logger->remove_appender(full_tg_name); } // CASE II: remove ALL targets of type else { cout4 << "removing ALL <" << tg_type_str << "> targets from " << dl[j]->get_name() << endl; // get logger's appender list log4tango::AppenderList al = logger->get_all_appenders(); // find appenders of type in std::string::size_type idx; const std::string substr(tg_type_str + kLogTargetSep); // for each appender in for (unsigned int a = 0; a < al.size(); a++) { idx = al[a]->get_name().find(substr); if (idx != std::string::npos) { cout4 << "\tremoving " << al[a]->get_name() << endl; logger->remove_appender(al[a]->get_name()); } } // for each appender in } // else (if remove_all_targets) } // for each device in
} // for each tuple // trace cout4 << "Leaving Logging::remove_logging_target" << endl; } catch (std::exception& e) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_StdException, o.str(), (const char *)"Logging::remove_logging_target"); } } //+---------------------------------------------------------------------------- // method : Logging::get_logging_target //----------------------------------------------------------------------------- Tango::DevVarStringArray* Logging::get_logging_target (const std::string& dev_name) { Tango::DevVarStringArray* ret = 0; try { // fight against the "zombie appender" syndrom Logging::kill_zombie_appenders(); // trace cout4 << "Entering Logging::get_logging_target " << endl; // first check device name (does it exist?) DeviceImpl* dev = 0; try { dev = Tango::Util::instance()->get_device_by_name(dev_name); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Device " << dev_name << " not found" << ends; Except::re_throw_exception(e, (const char *)API_DeviceNotFound, o.str(), (const char *)"Logging::get_logging_target"); } // get device's logger log4tango::Logger *logger = dev->get_logger(); if (logger == 0) { TangoSys_OMemStream o; o << "Could not instanciate logger (out of memory error)" << ends; Except::throw_exception((const char *)API_MemoryAllocation, o.str(), (const char *)"Logging::get_logging_target"); } // get logger's appender list log4tango::AppenderList al = logger->get_all_appenders(); // instanciate the returned value ret = new Tango::DevVarStringArray(al.size()); if (ret == 0) { TangoSys_OMemStream o; Except::throw_exception((const char *)API_MemoryAllocation, "Out of memory error (DevVarStringArray allocation failed)", (const char *)"Logging::get_logging_target"); } // set CORBA::sequence size to its max size ret->length(al.size()); // populate the CORBA::sequence for (unsigned int i = 0; i != al.size(); i++) { cout4 << "\tadding " << al[i]->get_name() << " to the returned target list" << endl; (*ret)[i] = CORBA::string_dup(al[i]->get_name().c_str()); } // for i // trace cout4 << "Leaving Logging::get_logging_target " << endl; } catch (std::exception& e) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_StdException, o.str(),(const char *)"Logging::get_logging_target"); } return ret; } //+---------------------------------------------------------------------------- // method : Logging::set_logging_level //----------------------------------------------------------------------------- void Logging::set_logging_level (const DevVarLongStringArray *argin) { try { // trace cout4 << "Entering Logging::set_logging_level" << endl; // log input unsigned int i; for (i = 0; i < argin->svalue.length(); i++) cout4 << "Input string = " << argin->svalue[i].in() << endl; for (i = 0; i < argin->lvalue.length(); i++) cout4 << "Input long = " << argin->lvalue[i] << endl; // check input if (argin->svalue.length() != argin->lvalue.length()) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type,\ long and string arrays must have the same length", (const char *)"Logging::set_logging_level"); } // the device name wildcard std::string pattern; // a device list std::vector dl(0); // a logger log4tango::Logger *logger = 0; // for each entry in argin->svalue for (i = 0; i < argin->svalue.length(); i++) { // check logging level if (argin->lvalue[i] < Tango::LOG_OFF || argin->lvalue[i] > Tango::LOG_DEBUG) { Except::throw_exception((const char *)API_MethodArgument, (const char *)"Invalid argument for command,\ logging level out of range", (const char *)"Logging::set_logging_level"); } // get ith wilcard pattern = argin->svalue[i]; // convert to lower case std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower); // get devices which name matches the pattern pattern dl = Util::instance()->get_device_list(pattern); // Check that none of the concerned device(s) is locked by another client DServer *adm_dev = Util::instance()->get_dserver_device(); for (unsigned int j = 0; j < dl.size(); j++) { adm_dev->check_lock_owner(dl[j],"set_logging_level",(dl[j]->get_name()).c_str()); } // for each device in dl for (unsigned int j = 0; j < dl.size(); j++) { // get device's logger (created if does not already exist) logger = dl[j]->get_logger(); if (logger == 0) { //--TODO::change the following message Except::throw_exception((const char *)API_MemoryAllocation, "out of memory error", (const char *)"Logging::set_logging_level"); } // map TANGO level to log4tango level log4tango::Level::Value log4tango_level = Logging::tango_to_log4tango_level(static_cast(argin->lvalue[i])); // set logger's level logger->set_level(log4tango_level); } // for j } // for i // trace cout4 << "Leaving Logging::set_logging_level" << endl; } catch (std::exception& e) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_StdException, o.str(), (const char *)"Logging::set_logging_level"); } } //+---------------------------------------------------------------------------- // method : Logging::get_logging_level //----------------------------------------------------------------------------- DevVarLongStringArray* Logging::get_logging_level (const DevVarStringArray *argin) { Tango::DevVarLongStringArray *ret = 0; try { // trace cout4 << "Entering Logging::get_logging_level" << endl; unsigned int i, j; for (i = 0; i < argin->length(); i++) { cout4 << "Input string = " << (*argin)[i].in() << endl; } // instance the returned CORBA::seq ret = new Tango::DevVarLongStringArray; if (ret == 0) { TangoSys_OMemStream o; Except::throw_exception((const char *)API_MemoryAllocation, "out of memory error", (const char *)"Logging::get_logging_level"); } // a TANGO logging level Tango::LogLevel tango_level; // the device name wildcard std::string pattern; // a device list std::vector dl(0); // a logger log4tango::Logger *logger = 0; for (i = 0; i < argin->length(); i++) { // get ith wilcard pattern = (*argin)[i]; // convert to lower case std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower); // get devices which name matches the pattern pattern dl = Util::instance()->get_device_list(pattern); // for each device in dl for (j = 0; j < dl.size(); j++) { // get device's logger (created if does not already exist) logger = dl[j]->get_logger(); if (logger == 0) { TangoSys_OMemStream o; //--TODO: change the following message o << "out of memory error" << ends; Except::throw_exception((const char *)API_MemoryAllocation, "out of memory error", (const char *)"Logging::get_logging_level"); } // map log4tango level to TANGO log level tango_level = Logging::log4tango_to_tango_level(logger->get_level()); // set max size and size of each array in the struct ret->lvalue.length(ret->lvalue.length() + 1); ret->svalue.length(ret->svalue.length() + 1); // populate ret ret->svalue[ret->svalue.length() - 1] = CORBA::string_dup(dl[j]->get_name().c_str()); ret->lvalue[ret->lvalue.length() - 1] = tango_level; } // for j } // for i // trace cout4 << "Leaving Logging::get_logging_level" << endl; } catch (std::exception& e) { TangoSys_OMemStream o; o << "std::exception caught [" << e.what() << "]" << ends; Except::throw_exception((const char *)API_StdException, o.str(),(const char *)"Logging::get_logging_level"); } return ret; } //+---------------------------------------------------------------------------- // method : Logging::stop_logging //----------------------------------------------------------------------------- void Logging::stop_logging (void) { cout4 << "Entering Logging::stop_logging" << endl; // get all devices std::vector dl = Util::instance()->get_device_list(std::string("*")); for (unsigned int i = 0; i < dl.size(); i++) { dl[i]->stop_logging(); } cout4 << "Leaving Logging::stop_logging" << endl; } //+---------------------------------------------------------------------------- // method : Logging::start_logging //----------------------------------------------------------------------------- void Logging::start_logging (void) { cout4 << "Entering Logging::start_logging" << endl; // get all devices std::vector dl = Util::instance()->get_device_list(std::string("*")); for (unsigned int i = 0; i < dl.size(); i++) { dl[i]->start_logging(); } cout4 << "Leaving Logging::start_logging" << endl; } //+---------------------------------------------------------------------------- // method : Logging::kill_zombie_appenders //----------------------------------------------------------------------------- void Logging::kill_zombie_appenders (void) { cout4 << "Entering kill_zombie_appenders" << endl; // get all devices std::vector dl(0); dl = Util::instance()->get_device_list("*"); // for each device in
log4tango::AppenderList al; log4tango::Logger *logger = 0; unsigned int i, j; for (i = 0; i < dl.size(); i++) { // get device's logger logger = dl[i]->get_logger(); if (logger) { // get logger's appender list al = logger->get_all_appenders(); // for each appender in for (j = 0; j < al.size(); j++) { if (al[j]->is_valid() == false) { cout4 << "Removing zombie appender " << dl[i]->get_name() << "::" << al[j]->get_name() << endl; logger->remove_appender(al[j]); } } // for each appender in } // if logger } // for each device in
cout4 << "Leaving kill_zombie_appenders" << endl; } //+---------------------------------------------------------------------------- // method : Logging::set_rolling_file_threshold //----------------------------------------------------------------------------- void Logging::set_rolling_file_threshold(log4tango::Logger* logger, size_t rtf) { // check input: logger if (!logger) return; // check input: rtf if (rtf < kMinRollingThreshold) { rtf = kMinRollingThreshold; } else if (rtf > kMaxRollingThreshold) { rtf = kMaxRollingThreshold; } // misc. var to find file targets in appender list std::string::size_type idx; TangoRollingFileAppender *rfa; std::string prefix = std::string(kLogTargetFile) + kLogTargetSep; // get logger's appender list log4tango::AppenderList al = logger->get_all_appenders(); // for each appender in for (unsigned int i = 0; i < al.size(); i++) { // is it a file target? idx = al[i]->get_name().find(prefix); if (idx != std::string::npos) { rfa = reinterpret_cast(al[i]); // change its rtf rfa->set_maximum_file_size(rtf * 1024); } } } //+---------------------------------------------------------------------------- // method : Logging::tango_to_log4tango_level //----------------------------------------------------------------------------- log4tango::Level::Value Logging::tango_to_log4tango_level (Tango::LogLevel tango_level, bool throw_exception) { log4tango::Level::Value log4tango_level; switch (tango_level) { case Tango::LOG_OFF: log4tango_level = log4tango::Level::OFF; break; case Tango::LOG_FATAL: log4tango_level = log4tango::Level::FATAL; break; case Tango::LOG_ERROR: log4tango_level = log4tango::Level::ERROR; break; case Tango::LOG_WARN: log4tango_level = log4tango::Level::WARN; break; case Tango::LOG_INFO: log4tango_level = log4tango::Level::INFO; break; case Tango::LOG_DEBUG: log4tango_level = log4tango::Level::DEBUG; break; default: if (throw_exception == true) { TangoSys_OMemStream o; o << "Invalid logging level specified" << ends; Except::throw_exception((const char *)API_MethodArgument, o.str(),(const char *)"Logging::tango_to_log4tango_level"); } log4tango_level = log4tango::Level::WARN; break; } // switch return log4tango_level; } //+---------------------------------------------------------------------------- // method : Logging::tango_to_log4tango_level (string version) //----------------------------------------------------------------------------- log4tango::Level::Value Logging::tango_to_log4tango_level (const std::string& tango_level, bool throw_exception) { log4tango::Level::Value log4tango_level; if (tango_level == "OFF") { log4tango_level = log4tango::Level::OFF; } else if (tango_level == "FATAL") { log4tango_level = log4tango::Level::FATAL; } else if (tango_level == "ERROR") { log4tango_level = log4tango::Level::ERROR; } else if (tango_level == "WARN") { log4tango_level = log4tango::Level::WARN; } else if (tango_level == "INFO") { log4tango_level = log4tango::Level::INFO; } else if (tango_level == "DEBUG") { log4tango_level = log4tango::Level::DEBUG; } else { if (throw_exception == true) { TangoSys_OMemStream o; o << "Invalid logging level specified" << ends; Except::throw_exception((const char *)API_MethodArgument, o.str(),(const char *)"Logging::tango_to_log4tango_level"); } log4tango_level = log4tango::Level::WARN; } return log4tango_level; } //+---------------------------------------------------------------------------- // method : Logging::log4tango_to_tango_level //----------------------------------------------------------------------------- Tango::LogLevel Logging::log4tango_to_tango_level (log4tango::Level::Value log4tango_level) { Tango::LogLevel tango_level; switch (log4tango_level) { case log4tango::Level::FATAL: tango_level = Tango::LOG_FATAL; break; case log4tango::Level::ERROR: tango_level = Tango::LOG_ERROR; break; case log4tango::Level::WARN: tango_level = Tango::LOG_WARN; break; case log4tango::Level::INFO: tango_level = Tango::LOG_INFO; break; case log4tango::Level::DEBUG: tango_level = Tango::LOG_DEBUG; break; case log4tango::Level::OFF: default: tango_level = Tango::LOG_OFF; break; } // switch return tango_level; } //+---------------------------------------------------------------------------- // method : Logging::dev_to_file_name //----------------------------------------------------------------------------- std::string Logging::dev_to_file_name (const std::string& _dev_name) { cout4 << "Entering Logging::dev_to_file_name (input " << _dev_name << ")" << endl; string file_name(_dev_name); std::transform(file_name.begin(), file_name.end(), file_name.begin(), ::tolower); std::string::size_type pos = 0; do { pos = file_name.find('/', pos); if (pos == std::string::npos) { break; } file_name.replace(pos, 1, "_", 1); pos++; } while (1); cout4 << "Leaving Logging::dev_to_file_name (output " << file_name << ")" << endl; return file_name; } //+---------------------------------------------------------------------------- // method : Logging::get_target_type_and_name //----------------------------------------------------------------------------- int Logging::get_target_type_and_name (const std::string& input, std::string& type, std::string& name) { cout4 << "Logging::get_target_type_and_name (input " << input << ")" << endl; std::string::size_type pos = input.find(kLogTargetSep, 0); if (pos == std::string::npos) { type = input; name = kDefaultTargetName; } else { type.assign(input.begin(), input.begin() + pos); name.assign(input.begin() + pos + ::strlen(kLogTargetSep), input.end()); if (name.size() == 0) { name = kDefaultTargetName; } } cout4 << "Logging::get_target_type_and_name (output " << type << " " << name << ")" << endl; return 0; } //+---------------------------------------------------------------------------- // method : Logging::create_log_dir (called @ startup by Logging::init) //----------------------------------------------------------------------------- int Logging::create_log_dir (const std::string& full_path) { //-_VERBOSE(("\tEntering Logging::create_log_dir (input %s)\n", full_path.c_str())); std::string::size_type pos = full_path.rfind('/'); if (pos != std::string::npos) { std::string sub_path; sub_path.assign(full_path.begin(), full_path.begin() + pos); if (sub_path.size()) { Logging::create_log_dir(sub_path); } } #ifdef _TG_WINDOWS_ int res = ::mkdir(full_path.c_str()); #else int res = ::mkdir(full_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); #endif //-_VERBOSE(("\tLeaving Logging::create_log_dir (::mkdir returned %d)\n", res)); return res; } //+---------------------------------------------------------------------------- // method : LogAdapter::LogAdapter //----------------------------------------------------------------------------- LogAdapter::LogAdapter (Tango::DeviceImpl *dev) { if (dev) { logger_ = dev->get_logger(); } else { logger_ = API_LOGGER; } } //+---------------------------------------------------------------------------- // method : LogAdapter::~LogAdapter //----------------------------------------------------------------------------- LogAdapter::~LogAdapter ( ) { //no-op dtor } } // namespace Tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/logstream.cpp0000644023471100065110000004354613034745001015276 00000000000000//+============================================================================= // // file : LogStream.cpp // // description : A TLS helper class // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO namespace Tango { //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevFailed &e) { //split exception stack into several logs [use a tag to identify the exception] static unsigned long exception_tag = 0; unsigned long num_errors = e.errors.length(); for (unsigned long i = 0; i < num_errors; i++) { TangoSys_OMemStream msg; msg << "[Ex:" << exception_tag << "-Err:" << i << "] " << "Rsn: " << e.errors[i].reason.in() << " " << "Dsc: " << e.errors[i].desc.in() << " " << "Org: " << e.errors[i].origin.in(); ls << msg.str(); if (i != num_errors - 1) { ls << endl; } } exception_tag++; return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarCharArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarLongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarFloatArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarDoubleArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarUShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarULongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const DevVarStringArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i].in(); if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const Attribute &a) { Tango::AttributeConfig conf; (const_cast(a)).get_properties(conf); ls << "Attribute name: " << conf.name.in() << endl; ls << "Attribute data_type: "; switch (conf.data_type) { case Tango::DEV_SHORT : ls << "Tango::DevShort" << endl; break; case Tango::DEV_LONG : ls << "Tango::DevLong" << endl; break; case Tango::DEV_DOUBLE : ls << "Tango::DevDouble" << endl; break; case Tango::DEV_STRING : ls << "Tango::DevString" << endl; break; case Tango::DEV_FLOAT : ls << "Tango::DevFloat" << endl; break; case Tango::DEV_BOOLEAN : ls << "Tango::DevBoolean" << endl; break; case Tango::DEV_USHORT : ls << "Tango::DevUShort" << endl; break; case Tango::DEV_UCHAR : ls << "Tango::DevUChar" << endl; break; case Tango::DEV_STATE : ls << "Tango::DevState" << endl; break; case Tango::DEV_ENUM : ls << "Tango::DevEnum" << endl; break; } ls << "Attribute data_format: "; switch (conf.data_format) { case Tango::FMT_UNKNOWN: break; case Tango::SCALAR : ls << "scalar" << endl; break; case Tango::SPECTRUM : ls << "spectrum, max_dim_x: " << conf.max_dim_x << endl; break; case Tango::IMAGE : ls << "image, max_dim_x: " << conf.max_dim_x << ", max_dim_y: " << conf.max_dim_y << endl; break; } if (conf.writable == static_cast(true)) ls << "Attribute is writable" << endl; else ls << "Attribute is not writable" << endl; ls << "Attribute label: " << conf.label.in() << endl; ls << "Attribute description: " << conf.description.in() << endl; ls << "Attribute unit: " << conf.unit.in() << endl; ls << "Attribute standard unit: " << conf.standard_unit.in() << endl; ls << "Attribute display unit: " << conf.display_unit.in() << endl; ls << "Attribute format: " << conf.format.in() << endl; ls << "Attribute min alarm: " << conf.min_alarm.in() << endl; ls << "Attribute max alarm: " << conf.max_alarm.in() << endl; ls << "Attribute min value: " << conf.min_value.in() << endl; ls << "Attribute max value: " << conf.max_value.in() << endl; ls << "Attribute writable_attr_name: " << conf.writable_attr_name.in() << endl; return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const AttrProperty& ap) { AttrProperty& ap_ = const_cast(ap); ls << "Attr.Property: name:" << ap_.get_name() << " - value:" << ap_.get_value() << endl; return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const Attr& a) { vector v = (const_cast(a)).get_class_properties(); unsigned int n = v.size(); if (n) { for (unsigned i = 0; i < n; i++) { ls << "Attr: " << const_cast(a).get_name() << " Property: name:" << v[i].get_name() << " - value:" << v[i].get_value(); if (i <= (n - 2)) ls << endl; } } else { ls << "Attr. " << const_cast(a).get_name() << " has no class properties"; } return ls; } //+---------------------------------------------------------------------------- // // method : LoggerStream::operator<< // //----------------------------------------------------------------------------- log4tango::LoggerStream& operator<< (log4tango::LoggerStream& ls, const AttrManip& m) { ls << m.to_string(); return ls; } /* //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const Devfailed &e) { static unsigned long exception_tag = 0; //split exception stack into several logs (with the same timestamp) unsigned long num_errors = e.errors.length(); for (unsigned long i = 0; i < num_errors; i++) { TangoSys_OMemStream msg; msg << "[Ex: " << ++exception_tag << "-" << i << "] " << "Rsn: " << e.errors[i].reason.in() << " - " << "Dsc: " << e.errors[i].desc.in() << " - " << "Org: " << e.errors[i].origin.in() << ends; ls << msg.str(); if (i != num_errors - 1) { ls << endl; } } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarCharArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarLongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarFloatArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarDoubleArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarUShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarULongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i]; if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const DevVarStringArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { ls << "Element number [" << i << "]: " << v[i].in(); if (i < (nb_elt - 1)) ls << endl; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const Attribute &a) { Tango::AttributeConfig conf; (const_cast(a)).get_properties(conf); ls << "Attribute name: " << conf.name.in() << endl; ls << "Attribute data_type: "; switch (conf.data_type) { case Tango::DEV_SHORT: ls << "Tango::DevShort" << endl; break; case Tango::DEV_LONG: ls << "Tango::DevLong" << endl; break; case Tango::DEV_DOUBLE: ls << "Tango::DevDouble" << endl; break; case Tango::DEV_STRING: ls << "Tango::DevString" << endl; break; } ls << "Attribute data_format: "; switch (conf.data_format) { case Tango::SCALAR: ls << "scalar" << endl; break; case Tango::SPECTRUM: ls << "spectrum, max_dim_x: " << conf.max_dim_x << endl; break; case Tango::IMAGE: ls << "image, max_dim_x: " << conf.max_dim_x << ", max_dim_y: " << conf.max_dim_y << endl; break; } if (conf.writable == static_cast(true)) ls << "Attribute is writable" << endl; else ls << "Attribute is not writable" << endl; ls << "Attribute label: " << conf.label.in() << endl; ls << "Attribute description: " << conf.description.in() << endl; ls << "Attribute unit: " << conf.unit.in() << endl; ls << "Attribute standard unit: " << conf.standard_unit.in() << endl; ls << "Attribute display unit: " << conf.display_unit.in() << endl; ls << "Attribute format: " << conf.format.in() << endl; ls << "Attribute min alarm: " << conf.min_alarm.in() << endl; ls << "Attribute max alarm: " << conf.max_alarm.in() << endl; ls << "Attribute min value: " << conf.min_value.in() << endl; ls << "Attribute max value: " << conf.max_value.in() << endl; ls << "Attribute writable_attr_name: " << conf.writable_attr_name.in() << endl; return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const AttrProperty &p) { AttrProperty &ap = const_cast(p); ls << "Attr.Property: name:" << ap.get_name() << " - Property value:" << ap.get_value(); return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const Attr& a) { vector v = (const_cast(a)).get_class_properties(); unsigned int n = v.size(); if (n) { for (unsigned i = 0; i < n; i++) { ls << "Attr: " << const_cast(a).get_name() << " Property: name:" << v[i].get_name() << " - value:" << v[i].get_value(); if (i <= (n - 2)) ls << endl; } } else { ls << "Attr. " << const_cast(a).get_name() << " has no class properties"; } return ls; } //+---------------------------------------------------------------------------- // // method : LogStream::operator<< // //----------------------------------------------------------------------------- log4tango::LogStream& operator<< (log4tango::LogStream& ls, const AttrManip& m) { ls << m.to_string(); return ls; } */ } // Tango namespace #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/multiattribute.cpp0000644023471100065110000013701213034745002016350 00000000000000static const char *RcsId = "$Id: multiattribute.cpp 28373 2015-08-13 13:58:07Z taurel $\n$Name$"; //+================================================================================================================== // // file : MultiAttribute.cpp // // description : C++ source code for the MultiAttribute class. This class is used to manage attribute. // A Tango Device object instance has one MultiAttribute object which is an aggregate of // Attribute or WAttribute objects // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28373 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include namespace Tango { // // Define the optional attribute name and default value // static OptAttrProp Tango_OptAttrProp[] = { {"label",LabelNotSpec}, {"description",DescNotSpec}, {"unit",UnitNotSpec}, {"standard_unit",StdUnitNotSpec}, {"display_unit",DispUnitNotSpec}, {"format",FormatNotSpec_FL}, {"min_value",AlrmValueNotSpec}, {"max_value",AlrmValueNotSpec}, {"min_alarm",AlrmValueNotSpec}, {"max_alarm",AlrmValueNotSpec}, {"writable_attr_name",AssocWritNotSpec}, {"min_warning",AlrmValueNotSpec}, {"max_warning",AlrmValueNotSpec}, {"delta_t","0"}, {"delta_val",AlrmValueNotSpec}, {"root_attr_name",AssocWritNotSpec} }; //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::MultiAttribute // // description : // Constructor for the MultiAttribute class from the device device name and a pointer to the DeviceClass object // // argument : // in : // - dev_name : The device name // - dev_class_ptr : Pointer to the DeviceClass object // - dev : Device pointer // //------------------------------------------------------------------------------------------------------------------ MultiAttribute::MultiAttribute(string &dev_name,DeviceClass *dev_class_ptr,DeviceImpl *dev) :ext(Tango_nullptr) { long i; cout4 << "Entering MultiAttribute class constructor for device " << dev_name << endl; // // Retrieve attr name list // vector &tmp_attr_list = dev_class_ptr->get_class_attr()->get_attr_list(); long nb_attr = tmp_attr_list.size(); // // Get device attribute properties // No need to implement a retry here (in case of db server restart) because the db reconnection // is forced by the get_property call executed during xxxClass construction before we reach this code. // cout4 << nb_attr << " attribute(s)" << endl; if (nb_attr != 0) { Tango::Util *tg = Tango::Util::instance(); Tango::DbData db_list; if (tg->_UseDb == true) { for (i = 0;i < nb_attr;i++) db_list.push_back(DbDatum(tmp_attr_list[i]->get_name())); // // On some small and old computers, this request could take time if at the same time some other processes also access // the device attribute properties table. This has been experimented at ESRF. Increase timeout to cover this case // int old_db_timeout = 0; if (Util::_FileDb == false) old_db_timeout = tg->get_database()->get_timeout_millis(); try { if (old_db_timeout != 0) tg->get_database()->set_timeout_millis(6000); tg->get_database()->get_device_attribute_property(dev_name,db_list,tg->get_db_cache()); if (old_db_timeout != 0) tg->get_database()->set_timeout_millis(old_db_timeout); } catch (Tango::DevFailed &) { cout4 << "Exception while accessing database" << endl; tg->get_database()->set_timeout_millis(old_db_timeout); TangoSys_OMemStream o; o << "Can't get device attribute properties for device " << dev_name << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"MultiAttribute::MultiAttribute"); } } // // Build property list for each attribute // long ind = 0; vector rem_att_name; vector rem_att_cl_name; int sub = 0; for (i = 0;i < nb_attr;i++) { // // Get attribute class properties // Attr &attr = dev_class_ptr->get_class_attr()->get_attr(tmp_attr_list[i]->get_name()); vector &class_prop = attr.get_class_properties(); vector &def_user_prop = attr.get_user_default_properties(); // // If the attribute has some properties defined at device level, build a vector of these properties // vector dev_prop; if (tg->_UseDb == true) { long nb_prop = 0; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + ","; tmp = tmp + db_list[ind].value_string[k]; } dev_prop.push_back(AttrProperty(db_list[ind].name,tmp)); } else dev_prop.push_back(AttrProperty(db_list[ind].name,db_list[ind].value_string[0])); ind++; } } // // Concatenate these two attribute properties levels // vector prop_list; bool fwd_ok = true; concat(dev_prop,class_prop,prop_list); if (attr.is_fwd() == false) { add_user_default(prop_list,def_user_prop); add_default(prop_list,dev_name,attr.get_name(),attr.get_type()); } else { FwdAttr &fwdattr = static_cast(attr); fwd_ok = fwdattr.validate_fwd_att(prop_list,dev_name); dev->set_with_fwd_att(true); if (fwd_ok == true) { try { fwdattr.get_root_conf(dev_name,dev); fwdattr.remove_useless_prop(prop_list,dev_name,this); add_user_default(prop_list,def_user_prop); add_default(prop_list,dev_name,attr.get_name(),attr.get_type()); } catch (Tango::DevFailed &e) { fwd_ok = false; add_user_default(prop_list,def_user_prop); add_default(prop_list,dev_name,attr.get_name(),attr.get_type()); vector &fwd_wrong_conf = dev->get_fwd_att_wrong_conf(); DeviceImpl::FwdWrongConf fwc; fwc.att_name = attr.get_name(); fwc.full_root_att_name = fwdattr.get_full_root_att(); fwc.fae = fwdattr.get_err_kind(); fwd_wrong_conf.push_back(fwc); if (fwc.fae == FWD_ROOT_DEV_NOT_STARTED) { rem_att_name.push_back(fwdattr.get_name()); rem_att_cl_name.push_back(fwdattr.get_cl_name()); } } } else { vector &fwd_wrong_conf = dev->get_fwd_att_wrong_conf(); DeviceImpl::FwdWrongConf fwc; fwc.att_name = attr.get_name(); fwc.full_root_att_name = fwdattr.get_full_root_att(); fwc.fae = fwdattr.get_err_kind(); fwd_wrong_conf.push_back(fwc); } } // // Create an Attribute instance // if (fwd_ok == true) { if ((attr.get_writable() == Tango::WRITE) || (attr.get_writable() == Tango::READ_WRITE)) { if (attr.is_fwd() == true) attr_list.push_back(new FwdAttribute(prop_list,attr,dev_name,i)); else attr_list.push_back(new WAttribute(prop_list,attr,dev_name,i)); } else { if (attr.is_fwd() == true) attr_list.push_back(new FwdAttribute(prop_list,attr,dev_name,i)); else attr_list.push_back(new Attribute(prop_list,attr,dev_name,i)); } // // If it is writable, add it to the writable attribute list // Tango::AttrWriteType w_type = attr_list[i - sub]->get_writable(); if ((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE)) { writable_attr_list.push_back(i - sub); } // // If one of the alarm properties is defined, add it to the alarmed attribute list // if (attr_list[i - sub]->is_alarmed().any() == true) { if (w_type != Tango::WRITE) alarm_attr_list.push_back(i - sub); } cout4 << *(attr_list[i - sub]) << endl; } else sub++; } // // Remove attdesc entry in class object for forwarded attribute with root device not started // // for (unsigned int loop = 0;loop < rem_att_name.size();loop++) // { // dev_class_ptr->get_class_attr()->remove_attr(rem_att_name[loop],rem_att_cl_name[loop]); // } } // // For each attribute, check if the writable_attr_name is set and in this case, check if the associated attribute // exists and is writable // nb_attr = attr_list.size(); for (i = 0;i < nb_attr;i++) { check_associated(i,dev_name); } cout4 << "Leaving MultiAttribute class constructor" << endl; } //+---------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::~MultiAttribute // // description : // Destructor for the MultiAttribute class. It simply delete all the Attribute object stored in its // attr_list data member // //----------------------------------------------------------------------------------------------------------------- MultiAttribute::~MultiAttribute() { for(unsigned long i = 0;i < attr_list.size();i++) delete attr_list[i]; } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::concat // // description : // Concatenate porperties defined at the class level and at the device level. Prperties defined at the device // level have the highest level // // arguments: // in : // - dev_prop : The device properties // - class_prop : The class properties // out : // - result : The resulting vector // //------------------------------------------------------------------------------------------------------------------ void MultiAttribute::concat(vector &dev_prop, vector &class_prop, vector &result) { // // Copy all device properties // unsigned long i; for (i = 0;i < dev_prop.size();i++) result.push_back(dev_prop[i]); // // Add class properties if they have not been redefined at the device level // vector tmp_result = result; unsigned long nb_class_check = class_prop.size(); for (i = 0;i < nb_class_check;i++) { vector::iterator pos; pos = find_if(tmp_result.begin(),tmp_result.end(), bind2nd(WantedProp(),class_prop[i].get_name())); if (pos != tmp_result.end()) continue; else result.push_back(class_prop[i]); } } //+------------------------------------------------------------------------------------------------------------------ // // method : MultiAttribute::add_default // // description : // Add default value for optional property if they are not defined // // argument : // in : // - prop_list : The already defined property vector // - dev_name : The device name // - att_name : The attribute name // - att_data_type : The attribute data type // //-------------------------------------------------------------------------- void MultiAttribute::add_default(vector &prop_list, TANGO_UNUSED(string &dev_name), string &att_name,long att_data_type) { // // Overwrite the label attribute property in order to be set to the attribute name // Tango_OptAttrProp[0].default_value = att_name.c_str(); // // Also overwrite the format attribute property according to attribute data type // switch (att_data_type) { case DEV_SHORT: case DEV_LONG: case DEV_LONG64: case DEV_UCHAR: case DEV_USHORT: case DEV_ULONG: case DEV_ULONG64: Tango_OptAttrProp[5].default_value = FormatNotSpec_INT; break; case DEV_STRING: case DEV_ENUM: Tango_OptAttrProp[5].default_value = FormatNotSpec_STR; break; case DEV_FLOAT: case DEV_DOUBLE: Tango_OptAttrProp[5].default_value = FormatNotSpec_FL; break; case DEV_STATE: case DEV_ENCODED: case DEV_BOOLEAN: case DATA_TYPE_UNKNOWN: Tango_OptAttrProp[5].default_value = AlrmValueNotSpec; break; default: break; } long nb_opt_prop = sizeof(Tango_OptAttrProp)/sizeof(OptAttrProp); // // For all the optional attribute properties, search in the already built vector of attributes if they are defined. // If yes, continue. Otherwise, add a new property with the default value // for (long i = 0;i < nb_opt_prop;i++) { vector::iterator pos; string opt_prop_name(Tango_OptAttrProp[i].name); pos = find_if(prop_list.begin(),prop_list.end(), bind2nd(WantedProp(),opt_prop_name)); if (pos == prop_list.end()) prop_list.push_back(AttrProperty(Tango_OptAttrProp[i].name,Tango_OptAttrProp[i].default_value)); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::add_user_default // // description : // Add default value for optional property if they are not defined // // argument : // in : // - prop_list : The already defined property vector // - user_default : The user defined default property values // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::add_user_default(vector &prop_list,vector &user_default) { // // Add default user properties if they have not been defined in the database // long nb_user = user_default.size(); for (int i = 0;i < nb_user;i++) { vector::iterator pos; pos = find_if(prop_list.begin(),prop_list.end(), bind2nd(WantedProp(),user_default[i].get_name())); if (pos != prop_list.end()) continue; else prop_list.push_back(user_default[i]); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::check_associated // // description : // Check if the writable_attr_name property is set and in this case, check if the associated attribute exists // and is writable. This is necessary only for attribute of the READ_WITH_WRITE or READ_WRITE types // // argument : // in : // - index : The index of the attribute to checked in the attr vector // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------ void MultiAttribute::check_associated(long index,string &dev_name) { if ((attr_list[index]->get_writable() == Tango::READ_WITH_WRITE) || (attr_list[index]->get_writable() == Tango::READ_WRITE)) { unsigned long j; string &assoc_name = attr_list[index]->get_assoc_name(); transform(assoc_name.begin(),assoc_name.end(),assoc_name.begin(),::tolower); for (j = 0;j < writable_attr_list.size();j++) { if (attr_list[writable_attr_list[j]]->get_name_lower() == assoc_name) break; } if (j == writable_attr_list.size()) { TangoSys_OMemStream o; o << "Device --> " << dev_name; o << "\nProperty writable_attr_name for attribute " << attr_list[index]->get_name(); o << " is set to " << assoc_name; o << ", but this attribute does not exists or is not writable" << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"MultiAttribute::MultiAttribute"); } // // Check that the two associated attributes have the same data type // if (attr_list[writable_attr_list[j]]->get_data_type() != attr_list[index]->get_data_type()) { TangoSys_OMemStream o; o << "Device --> " << dev_name; o << "\nProperty writable_attr_name for attribute " << attr_list[index]->get_name(); o << " is set to " << assoc_name; o << ", but these two attributes do not support the same data type" << ends; Except::throw_exception((const char *)API_AttrOptProp, o.str(), (const char *)"MultiAttribute::MultiAttribute"); } attr_list[index]->set_assoc_ind(writable_attr_list[j]); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::check_idl_release // // description : // Check some features according to which IDL release the device implement. This can not be done in // DeviceImpl class ctor because when the DeviceImpl ctor is executed, it is always IDL release 1. // The real supported IDL release number is set during each Device_XImpl ctor which is executed after // DeviceImpl ctor. // Today, we check : // - Enum attribute with IDL5 // - Forwarded attribute with IDL 5 // // argument : // in : // - dev : The device pointer // //------------------------------------------------------------------------------------------------------------------ void MultiAttribute::check_idl_release(DeviceImpl *dev) { int idl_version = dev->get_dev_idl_version(); size_t nb_attr = attr_list.size(); bool vector_cleared = false; for (size_t i = 0;i < nb_attr;i++) { // // Check for enumerated attribute // if (attr_list[i]->get_data_type() == DEV_ENUM && idl_version < 5) { try { stringstream ss; ss << "Attribute " << attr_list[i]->get_name() << " has a DEV_ENUM data type.\n"; ss << "This is supported oonly for device inheriting from IDL 5 or more"; Except::throw_exception(API_NotSupportedFeature,ss.str(),"MultiAttribute::check_idl_release()"); } catch (Tango::DevFailed &e) { attr_list[i]->add_startup_exception("enum_labels",e); } } // // Chek for forwarded attribute // If IDL < 5, on top of setting wrongly configured attribute in device, remove the root att from // root attribute registry // if (attr_list[i]->is_fwd_att() == true && idl_version < 5) { vector &fwd_wrong_conf = dev->get_fwd_att_wrong_conf(); if (vector_cleared == false) { fwd_wrong_conf.clear(); vector_cleared = true; } DeviceImpl::FwdWrongConf fwc; fwc.att_name = attr_list[i]->get_name(); FwdAttribute *fwd_attr = static_cast(attr_list[i]); fwc.full_root_att_name = fwd_attr->get_fwd_dev_name() + '/' + fwd_attr->get_fwd_att_name(); fwc.fae = FWD_TOO_OLD_LOCAL_DEVICE; fwd_wrong_conf.push_back(fwc); RootAttRegistry &fdp = Util::instance()->get_root_att_reg(); fdp.remove_root_att(fwd_attr->get_fwd_dev_name(),fwd_attr->get_fwd_att_name()); } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::add_attribute // // description : // Construct a new attribute object and add it to the device attribute list // // argument : // in : // - dev_name : The device name // - dev_class_ptr : Pointer to the DeviceClass object // - index : Index in class attribute list of the new device attribute // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::add_attribute(string &dev_name,DeviceClass *dev_class_ptr,long index) { cout4 << "Entering MultiAttribute::add_attribute" << endl; // // Retrieve device class attribute list // vector &tmp_attr_list = dev_class_ptr->get_class_attr()->get_attr_list(); // // Get device attribute properties // No need to implement a retry here (in case of db server restart) because the db reconnection // is forced by the get_property call executed during xxxClass construction before we reach this code. // Tango::Util *tg = Tango::Util::instance(); Tango::DbData db_list; if (tg->_UseDb == true) { db_list.push_back(DbDatum(tmp_attr_list[index]->get_name())); try { tg->get_database()->get_device_attribute_property(dev_name,db_list,tg->get_db_cache()); } catch (Tango::DevFailed &e) { TangoSys_OMemStream o; o << "Can't get device attribute properties for device " << dev_name << ends; Except::re_throw_exception(e,(const char *)API_DatabaseAccess, o.str(), (const char *)"MultiAttribute::add_attribute"); } } // // Get attribute class properties // Attr &attr = dev_class_ptr->get_class_attr()->get_attr(tmp_attr_list[index]->get_name()); vector &class_prop = attr.get_class_properties(); vector &def_user_prop = attr.get_user_default_properties(); // // If the attribute has some properties defined at device level, build a vector of these properties // vector dev_prop; if (tg->_UseDb == true) { long ind = 0; long nb_prop = 0; db_list[ind] >> nb_prop; ind++; for (long j = 0;j < nb_prop;j++) { if (db_list[ind].size() > 1) { string tmp(db_list[ind].value_string[0]); long nb = db_list[ind].size(); for (int k = 1;k < nb;k++) { tmp = tmp + ","; tmp = tmp + db_list[ind].value_string[k]; } dev_prop.push_back(AttrProperty(db_list[ind].name,tmp)); } else dev_prop.push_back(AttrProperty(db_list[ind].name, db_list[ind].value_string[0])); ind++; } } // // Concatenate these two attribute properties levels // vector prop_list; concat(dev_prop,class_prop,prop_list); add_user_default(prop_list,def_user_prop); add_default(prop_list,dev_name,attr.get_name(),attr.get_type()); // // Create an Attribute instance and insert it in the attribute list. If the device implement IDL 3 // (with state and status as attributes), add it at the end of the list but before state and status. // bool idl_3 = false; vector::iterator ite; if ((attr_list.back())->get_name() == "Status") { idl_3 = true; ite = attr_list.end(); ite = ite - 2; } if ((attr.get_writable() == Tango::WRITE) || (attr.get_writable() == Tango::READ_WRITE)) { if (idl_3 == false) { attr_list.push_back(new WAttribute(prop_list,attr,dev_name,index)); index = attr_list.size() - 1; } else { attr_list.insert(ite,new WAttribute(prop_list,attr,dev_name,index)); index = attr_list.size() - 3; } } else { if (idl_3 == false) { attr_list.push_back(new Attribute(prop_list,attr,dev_name,index)); index = attr_list.size() - 1; } else { attr_list.insert(ite,new Attribute(prop_list,attr,dev_name,index)); index = attr_list.size() - 3; } } // // If it is writable, add it to the writable attribute list // Tango::AttrWriteType w_type = attr_list[index]->get_writable(); if ((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE)) { writable_attr_list.push_back(index); } // // If one of the alarm properties is defined, add it to the alarmed attribute list // if (attr_list[index]->is_alarmed().any() == true) { if (w_type != Tango::WRITE) alarm_attr_list.push_back(index); } // // Check if the writable_attr_name property is set and in this case, check if the associated attribute exists and is // writable // check_associated(index,dev_name); cout4 << "Leaving MultiAttribute::add_attribute" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::add_fwd_attribute // // description : // Construct a new forwarded attribute object and add it to the device attribute list // // argument : // in : // - dev_name : The device name // - dev_class_ptr : Pointer to the DeviceClass object // - index : Index in class attribute list of the new device attribute // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::add_fwd_attribute(string &dev_name,DeviceClass *dev_class_ptr,long index, Attr *new_attr) { cout4 << "Entering MultiAttribute::add_fwd_attribute" << endl; // // Retrieve device class attribute list // vector &tmp_attr_list = dev_class_ptr->get_class_attr()->get_attr_list(); // // Get attribute class properties // Attr &attr = dev_class_ptr->get_class_attr()->get_attr(tmp_attr_list[index]->get_name()); vector &def_user_prop = attr.get_user_default_properties(); // // Concatenate these two attribute properties levels // vector prop_list; add_user_default(prop_list,def_user_prop); add_default(prop_list,dev_name,attr.get_name(),attr.get_type()); // // Create an Attribute instance and insert it in the attribute list. If the device implement IDL 3 // (with state and status as attributes), add it at the end of the list but before state and status. // vector::iterator ite; ite = attr_list.end() - 2; attr_list.insert(ite,new FwdAttribute(prop_list,*new_attr,dev_name,index)); index = attr_list.size() - 3; // // If it is writable, add it to the writable attribute list // Tango::AttrWriteType w_type = attr_list[index]->get_writable(); if ((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE)) { writable_attr_list.push_back(index); } // // If one of the alarm properties is defined, add it to the alarmed attribute list // if (attr_list[index]->is_alarmed().any() == true) { if (w_type != Tango::WRITE) alarm_attr_list.push_back(index); } cout4 << "Leaving MultiAttribute::add_fwd_attribute" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::remove_attribute // // description : // Remove one attribute object from the device attribute list // // argument : // in : // - attr_name : The attribute name // - update_idx : Flag set to true if the attributes object index used to retrieve the corresponding Attr // object has to be updated (because one Attr object has been removed) // //-------------------------------------------------------------------------------------------------------------------- void MultiAttribute::remove_attribute(string &attr_name,bool update_idx) { cout4 << "Entering MultiAttribute::remove_attribute" << endl; // // Get attribute index in vector // long att_index = get_attr_ind_by_name(attr_name.c_str()); // // Remove the attribute from the main vector // Attribute *att = attr_list[att_index]; int old_idx = att->get_attr_idx(); DeviceImpl *the_dev = att->get_att_device(); string &dev_class_name = the_dev->get_device_class()->get_name(); delete att; vector::iterator pos = attr_list.begin(); advance(pos,att_index); pos = attr_list.erase(pos); // // Update all the index for attribute following the one which has been deleted // This is a 2 steps process: // 1 - Update index in local device // 2 - Update indexes in remaining device(s) belonging to the same class // if (update_idx == true) { for (;pos != attr_list.end();++pos) (*pos)->set_attr_idx((*pos)->get_attr_idx() - 1); Tango::Util *tg = Tango::Util::instance(); vector &dev_list = tg->get_device_list_by_class(dev_class_name); vector::iterator dev_ite; for (dev_ite = dev_list.begin();dev_ite != dev_list.end();++dev_ite) { if (*dev_ite == the_dev) continue; vector &dev_att_list = (*dev_ite)->get_device_attr()->get_attribute_list(); for (unsigned int loop = 0;loop < dev_att_list.size();++loop) { int idx = dev_att_list[loop]->get_attr_idx(); if (idx > old_idx) dev_att_list[loop]->set_attr_idx(idx - 1); } } } // // Clear the writable attribute index vector and rebuild it. This is necessary because this vector containd index in // the main attribute list which has been modified // writable_attr_list.clear(); for (unsigned long i = 0;i < attr_list.size();i++) { Tango::AttrWriteType w_type = attr_list[i]->get_writable(); if ((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE)) { writable_attr_list.push_back(i); } } // // Do the same for the alarmed attribute for the same reason // alarm_attr_list.clear(); for (unsigned long i = 0;i < attr_list.size();i++) { if (attr_list[i]->is_alarmed().any() == true) { Tango::AttrWriteType w_type = attr_list[i]->get_writable(); if (w_type != Tango::WRITE) alarm_attr_list.push_back(i); } } // // Check the associated attributes // string default_dev_name("a/b/c"); for (unsigned long i = 0;i < attr_list.size();i++) { check_associated(i,default_dev_name); } cout4 << "Leaving MultiAttribute::remove_attribute" << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::get_attr_by_name // // description : // Return a reference to the the Attribute object for the wanted attribue // // argument : // in : // - attr_name : The attribute name // // return : // A reference to the wanted attribute or throws an exception id the attribute is not found // //------------------------------------------------------------------------------------------------------------------- Attribute &MultiAttribute::get_attr_by_name(const char *attr_name) { vector::iterator pos; pos = find_if(attr_list.begin(),attr_list.end(), bind2nd(WantedAttr(),attr_name)); if (pos == attr_list.end()) { cout3 << "MultiAttribute::get_attr_by_name throwing exception" << endl; TangoSys_OMemStream o; o << attr_name << " attribute not found" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"MultiAttribute::get_attr_by_name"); } return *(*pos); } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::get_w_attr_by_name // // description : // Return a reference to the the Attribute object for the wanted attribue // // argument : // in : // - attr_name : The attribute name // // return : // A reference to the wanted attribute or throws an exception id the attribute is not found // //------------------------------------------------------------------------------------------------------------------- WAttribute &MultiAttribute::get_w_attr_by_name(const char *attr_name) { vector::iterator pos; pos = find_if(attr_list.begin(),attr_list.end(), bind2nd(WantedAttr(),attr_name)); if ( ( pos == attr_list.end() ) || ( ((*pos)->get_writable() != Tango::WRITE) && ((*pos)->get_writable() != Tango::READ_WRITE) ) ) { cout3 << "MultiAttribute::get_w_attr_by_name throwing exception" << endl; TangoSys_OMemStream o; o << attr_name << " writable attribute not found" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"MultiAttribute::get_w_attr_by_name"); } return static_cast(*(*pos)); } //+------------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::get_attr_ind_by_name // // description : // Return the index in the Attribute object vector of a specified attribute // // argument : // in : // - attr_name : The attribute name // // return : // The index of the wanted attribute or throws an exception id the attribute is not found // //-------------------------------------------------------------------------------------------------------------------- long MultiAttribute::get_attr_ind_by_name(const char *attr_name) { long i; long nb_attr = attr_list.size(); string st(attr_name); transform(st.begin(),st.end(),st.begin(),::tolower); for (i = 0;i < nb_attr;i++) { if (attr_list[i]->get_name_size() != st.size()) continue; if (attr_list[i]->get_name_lower() == st) break; } if (i == nb_attr) { cout3 << "MultiAttribute::get_attr_ind_by_name throwing exception" << endl; TangoSys_OMemStream o; o << attr_name << " attribute not found" << ends; Except::throw_exception((const char *)API_AttrNotFound, o.str(), (const char *)"MultiAttribute::get_attr_ind_by_name"); } return i; } //+-------------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::check_alarm // // description : // check alarm on all the attribute where one alarm is defined // // return : // A boolen set to true if one of the attribute with an alarm defined is in alarm state // //-------------------------------------------------------------------------------------------------------------------- bool MultiAttribute::check_alarm() { unsigned long i; bool ret,tmp_ret; tmp_ret = false; ret = false; for (i = 0;i < alarm_attr_list.size();i++) { Tango::AttrQuality qua = (get_attr_by_ind(alarm_attr_list[i])).get_quality(); if (ret == false) { if (qua == Tango::ATTR_ALARM) ret = true; } if (qua != Tango::ATTR_INVALID) { // // If the attribute is polled, the check_alarm method has already been called when the polling thread has read the // attribute. // Attribute &att = get_attr_by_ind(alarm_attr_list[i]); if (att.is_polled() == false) { tmp_ret = check_alarm(alarm_attr_list[i]); if (tmp_ret == true) ret = true; } } } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::read_alarm // // description : // Add a message in the device status string if one of the device attribute is in the alarm state // // argument : // in : // - status : The device status // //-------------------------------------------------------------------------------------------------------------------- void MultiAttribute::read_alarm(string &status) { unsigned long i; for (i = 0;i < alarm_attr_list.size();i++) { Attribute &att = get_attr_by_ind(alarm_attr_list[i]); // // Add a message for low level alarm // if (att.is_min_alarm() == true) { string &attr_label = att.get_label(); string str; if (attr_label == LabelNotSpec) { str = "\nAlarm : Value too low for attribute "; str = str + att.get_name(); } else { str = "\nAlarm : Value too low for "; str = str + attr_label; } status = status + str; } // // Add a message for high level alarm // else if (att.is_max_alarm() == true) { string &attr_label = att.get_label(); string str; if (attr_label == LabelNotSpec) { str = "\nAlarm : Value too high for attribute "; str = str + att.get_name(); } else { str = "\nAlarm : Value too high for "; str = str + attr_label; } status = status + str; } // // Add a message for rds alarm // if (att.is_rds_alarm() == true) { string &attr_label = att.get_label(); string str; if (attr_label == LabelNotSpec) { str = "\nAlarm : Read too Different than Set (RDS) for attribute "; str = str + att.get_name(); } else { str = "\nAlarm : Read too Different than Set (RDS) for "; str = str + attr_label; } status = status + str; } // // Add a message for min warning // if (att.is_min_warning() == true) { string &attr_label = att.get_label(); string str; if (attr_label == LabelNotSpec) { str = "\nWarning : Value too low for attribute "; str = str + att.get_name(); } else { str = "\nWarning : Value too low for "; str = str + attr_label; } status = status + str; } // // Add a message for max warning // else if (att.is_max_warning() == true) { string &attr_label = att.get_label(); string str; if (attr_label == LabelNotSpec) { str = "\nWarning : Value too high for attribute "; str = str + att.get_name(); } else { str = "\nWarning : Value too high for "; str = str + attr_label; } status = status + str; } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::get_event_param // // description : // Return event info for each attribute with events subscribed // // argument : // in : // - eve : One structure in this vector for each attribute with events subscribed // //------------------------------------------------------------------------------------------------------------------ void MultiAttribute::get_event_param(vector &eve) { unsigned int i; for (i = 0;i < attr_list.size();i++) { bool once_more = false; vector ch; vector ar; vector pe; vector us; vector ac; bool dr = false; bool qu = false; if (attr_list[i]->change_event_subscribed() == true) { once_more = true; ch = attr_list[i]->get_client_lib(CHANGE_EVENT); } if (attr_list[i]->quality_event_subscribed() == true) { once_more = true; qu = true; } if (attr_list[i]->periodic_event_subscribed() == true) { once_more = true; pe = attr_list[i]->get_client_lib(PERIODIC_EVENT); } if (attr_list[i]->archive_event_subscribed() == true) { once_more = true; ar = attr_list[i]->get_client_lib(ARCHIVE_EVENT); } if (attr_list[i]->user_event_subscribed() == true) { once_more = true; us = attr_list[i]->get_client_lib(USER_EVENT); } if (attr_list[i]->attr_conf_event_subscribed() == true) { once_more = true; ac = attr_list[i]->get_client_lib(ATTR_CONF_EVENT); } if (attr_list[i]->data_ready_event_subscribed() == true) { once_more = true; dr = true; } if (once_more == true) { EventPar ep; if (attr_list[i]->use_notifd_event() == true) ep.notifd = true; else ep.notifd = false; if (attr_list[i]->use_zmq_event() == true) ep.zmq = true; else ep.zmq = false; ep.attr_id = i; ep.change = ch; ep.quality = qu; ep.archive = ar; ep.periodic = pe; ep.user = us; ep.att_conf = ac; ep.data_ready = dr; eve.push_back(ep); } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // MultiAttribute::set_event_param // // description : // Set event info for each attribute with events subscribed // // argument : // in : // - eve : One structure in this vector for each attribute with events subscribed // //------------------------------------------------------------------------------------------------------------------ void MultiAttribute::set_event_param(vector &eve) { for (size_t i = 0;i < eve.size();i++) { if (eve[i].attr_id != -1) { Tango::Attribute &att = get_attr_by_ind(eve[i].attr_id); { omni_mutex_lock oml(EventSupplier::get_event_mutex()); vector::iterator ite; if (eve[i].change.empty() == false) { for (ite = eve[i].change.begin();ite != eve[i].change.end();++ite) att.set_change_event_sub(*ite); } if (eve[i].periodic.empty() == false) { for (ite = eve[i].periodic.begin();ite != eve[i].periodic.end();++ite) att.set_periodic_event_sub(*ite); } if (eve[i].archive.empty() == false) { for (ite = eve[i].archive.begin();ite != eve[i].archive.end();++ite) att.set_archive_event_sub(*ite); } if (eve[i].att_conf.empty() == false) { for (ite = eve[i].att_conf.begin();ite != eve[i].att_conf.end();++ite) att.set_att_conf_event_sub(*ite); } if (eve[i].user.empty() == false) { for (ite = eve[i].user.begin();ite != eve[i].user.end();++ite) att.set_user_event_sub(*ite); } if (eve[i].quality == true) att.set_quality_event_sub(); if (eve[i].data_ready == true) att.set_data_ready_event_sub(); } if (eve[i].notifd == true) att.set_use_notifd_event(); if (eve[i].zmq == true) att.set_use_zmq_event(); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::add_write_value // // description : // For scalar attribute with an associated write attribute, the read_attributes CORBA operation also returns // the write value. This method gets the associated write attribute value and adds it to the read attribute // // argument : // in : // - att : Reference to the attribute which must be read // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::add_write_value(Attribute &att) { WAttribute &assoc_att = get_w_attr_by_ind(att.get_assoc_ind()); Tango::DevVarShortArray *sh_write_val; Tango::DevVarLongArray *lg_write_val; Tango::DevVarLong64Array *lg64_write_val; Tango::DevVarDoubleArray *db_write_val; Tango::DevVarStringArray *str_write_val; Tango::DevVarFloatArray *fl_write_val; Tango::DevVarBooleanArray *boo_write_val; Tango::DevVarUShortArray *ush_write_val; Tango::DevVarCharArray *uch_write_val; Tango::DevVarULongArray *ulg_write_val; Tango::DevVarULong64Array *ulg64_write_val; Tango::DevVarStateArray *state_write_val; switch (att.get_data_type()) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : sh_write_val = assoc_att.get_last_written_sh(); att.add_write_value(sh_write_val); break; case Tango::DEV_LONG : lg_write_val = assoc_att.get_last_written_lg(); att.add_write_value(lg_write_val); break; case Tango::DEV_LONG64 : lg64_write_val = assoc_att.get_last_written_lg64(); att.add_write_value(lg64_write_val); break; case Tango::DEV_DOUBLE : db_write_val = assoc_att.get_last_written_db(); att.add_write_value(db_write_val); break; case Tango::DEV_STRING : str_write_val = assoc_att.get_last_written_str(); att.add_write_value(str_write_val); break; case Tango::DEV_FLOAT : fl_write_val = assoc_att.get_last_written_fl(); att.add_write_value(fl_write_val); break; case Tango::DEV_BOOLEAN : boo_write_val = assoc_att.get_last_written_boo(); att.add_write_value(boo_write_val); break; case Tango::DEV_USHORT : ush_write_val = assoc_att.get_last_written_ush(); att.add_write_value(ush_write_val); break; case Tango::DEV_UCHAR : uch_write_val = assoc_att.get_last_written_uch(); att.add_write_value(uch_write_val); break; case Tango::DEV_ULONG : ulg_write_val = assoc_att.get_last_written_ulg(); att.add_write_value(ulg_write_val); break; case Tango::DEV_ULONG64 : ulg64_write_val = assoc_att.get_last_written_ulg64(); att.add_write_value(ulg64_write_val); break; case Tango::DEV_STATE : state_write_val = assoc_att.get_last_written_state(); att.add_write_value(state_write_val); break; case Tango::DEV_ENCODED : { DevEncoded &enc_write_val = assoc_att.get_last_written_encoded(); att.add_write_value(enc_write_val); break; } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::is_att_quality_alarmed() // // description : // Check for all attribute if one of them has its quality factor set to ALARM. // Returns true in this case. Otherwise, returns false // //------------------------------------------------------------------------------------------------------------------ bool MultiAttribute::is_att_quality_alarmed() { unsigned long i; bool ret; ret = false; for (i = 0;i < attr_list.size();i++) { if ((attr_list[i]->get_quality() == Tango::ATTR_ALARM) || (attr_list[i]->get_quality() == Tango::ATTR_WARNING)) { ret = true; break; } } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::add_alarmed_quality_factor() // // description : // Add to the status string name of attributes with a quality factor set to alarm // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::add_alarmed_quality_factor(string &status) { unsigned long i,j; for (i = 0;i < attr_list.size();i++) { bool found = false; for (j = 0;j < alarm_attr_list.size();j++) { if (alarm_attr_list[j] == (long)i) { found = true; break; } } if (found == true) continue; if (attr_list[i]->get_quality() == Tango::ATTR_ALARM) { string &attr_label = attr_list[i]->get_label(); string str("\nAlarm : Quality factor set to ALARM for attribute "); if (attr_label == LabelNotSpec) { str = str + attr_list[i]->get_name(); } else { str = str + attr_label; } status = status + str; } else if (attr_list[i]->get_quality() == Tango::ATTR_WARNING) { string &attr_label = attr_list[i]->get_label(); string str("\nWarning : Quality factor set to WARNING for attribute "); if (attr_label == LabelNotSpec) { str = str + attr_list[i]->get_name(); } else { str = str + attr_label; } status = status + str; } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::update() // // description : // Update attribute lists when a forwarded attribute conf. is now completely known (after a device with fwd // attributes started before the device with root attribute(s)) // // argument: // in : // - att : The newly configured attribute // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------- void MultiAttribute::update(Attribute &att,string &dev_name) { long ind = get_attr_ind_by_name(att.get_name().c_str()); // // If it is writable, add it to the writable attribute list if not there already // Tango::AttrWriteType w_type = att.get_writable(); if ((w_type == Tango::WRITE) || (w_type == Tango::READ_WRITE)) { vector::iterator pos; pos = find(writable_attr_list.begin(),writable_attr_list.end(),ind); if (pos == writable_attr_list.end()) writable_attr_list.push_back(ind); } // // If one of the alarm properties is defined, add it to the alarmed attribute list // if (att.is_alarmed().any() == true) { if (w_type != Tango::WRITE) { vector::iterator pos; pos = find(alarm_attr_list.begin(),alarm_attr_list.end(),ind); if (pos == alarm_attr_list.end()) alarm_attr_list.push_back(ind); } } // // If if there is one associated att // check_associated(ind,dev_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // MultiAttribute::is_opt_prop() // // description : // This method returns true if the property name passed as argument is the name of one of the attribute optional // properties // // argument: // in : // - prop_name : The property name // // return: // True if prop_name is the name of one of the optional properties. False otherwise // //------------------------------------------------------------------------------------------------------------------- bool MultiAttribute::is_opt_prop(const string &prop_name) { bool ret = false; long nb_opt_prop = sizeof(Tango_OptAttrProp)/sizeof(OptAttrProp); for (long i = 0;i < nb_opt_prop;i++) { if (prop_name == Tango_OptAttrProp[i].name) { ret = true; break; } } return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/notifdeventsupplier.cpp0000644023471100065110000007175013034745001017410 00000000000000static const char *RcsId = "$Id$"; //////////////////////////////////////////////////////////////////////////////// // // file notifdeventsupplier.cpp // // C++ class for implementing the event server // singleton class - NotifdEventSupplier. // This class is used to send events from the server // to the notification service. // // author(s) : E.Taurel (taurel@esrf.fr) // // original : August 2011 // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 17240 $ // // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #include #endif using namespace CORBA; namespace Tango { NotifdEventSupplier *NotifdEventSupplier::_instance = NULL; /************************************************************************/ /* */ /* NotifdEventSupplier class */ /* ------------------- */ /* */ /************************************************************************/ NotifdEventSupplier::NotifdEventSupplier(CORBA::ORB_var _orb, CosNotifyChannelAdmin::SupplierAdmin_var _supplierAdmin, CosNotifyChannelAdmin::ProxyID _proxId, CosNotifyChannelAdmin::ProxyConsumer_var _proxyConsumer, CosNotifyChannelAdmin::StructuredProxyPushConsumer_var _structuredProxyPushConsumer, CosNotifyChannelAdmin::EventChannelFactory_var _eventChannelFactory, CosNotifyChannelAdmin::EventChannel_var _eventChannel, string &event_ior, Util *tg): EventSupplier(tg) { orb_ = _orb; supplierAdmin = _supplierAdmin; proxyId = _proxId; proxyConsumer = _proxyConsumer; structuredProxyPushConsumer = _structuredProxyPushConsumer; eventChannelFactory = _eventChannelFactory; eventChannel = _eventChannel; event_channel_ior = event_ior; _instance = this; } NotifdEventSupplier *NotifdEventSupplier::create(CORBA::ORB_var _orb, string server_name, Util *tg) { cout4 << "calling Tango::NotifdEventSupplier::create() \n"; // // does the NotifdEventSupplier singleton exist already ? if so simply return it // if (_instance != NULL) { return _instance; } // // Connect process to the notifd service // NotifService ns; connect_to_notifd(ns,_orb,server_name,tg); // // NotifdEventSupplier singleton does not exist, create it // NotifdEventSupplier *_event_supplier = new NotifdEventSupplier(_orb,ns.SupAdm,ns.pID,ns.ProCon,ns.StrProPush,ns.EveChaFac,ns.EveCha,ns.ec_ior,tg); return _event_supplier; } void NotifdEventSupplier::connect() { // // Connect to the Proxy Consumer // try { structuredProxyPushConsumer -> connect_structured_push_supplier(_this()); } catch(const CosEventChannelAdmin::AlreadyConnected&) { cerr << "Tango::NotifdEventSupplier::connect() caught AlreadyConnected exception" << endl; } } void NotifdEventSupplier::disconnect_structured_push_supplier() { cout4 << "calling Tango::NotifdEventSupplier::disconnect_structured_push_supplier() \n"; } void NotifdEventSupplier::subscription_change(TANGO_UNUSED(const CosNotification::EventTypeSeq& added), TANGO_UNUSED(const CosNotification::EventTypeSeq& deled)) { cout4 << "calling Tango::NotifdEventSupplier::subscription_change() \n"; } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::connect_to_notifd() // // description : Method to connect the process to the notifd // // argument : in : ns : Ref. to a struct with notifd connection parameters // //----------------------------------------------------------------------------- void NotifdEventSupplier::connect_to_notifd(NotifService &ns,CORBA::ORB_var &_orb, string &server_name, Util *tg) { CosNotifyChannelAdmin::EventChannelFactory_var _eventChannelFactory; CosNotifyChannelAdmin::EventChannel_var _eventChannel; // // Get a reference to the Notification Service EventChannelFactory from // the TANGO database or from the server itself in case of server // started with the -file option // string &host_name = tg->get_host_name(); string factory_ior; string factory_name; factory_name = "notifd/factory/" + host_name; CORBA::Any_var received; string d_name = "DServer/"; d_name = d_name + server_name; const DevVarLongStringArray *dev_import_list; Database *db = tg->get_database(); // // For compatibility reason, search in database first with a fqdn name // If nothing is found in DB and if the provided name is a FQDN, redo the // search with a canonical name. In case the DbCache, is used, this algo // is implemented in the stored procedure // if (Util::_FileDb == false) { try { if (tg->get_db_cache() != NULL) { dev_import_list = tg->get_db_cache()->import_notifd_event(); } else { try { received = db->import_event(factory_name); } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == "DB_DeviceNotDefined") { string::size_type pos = factory_name.find('.'); if (pos != string::npos) { string factory_name_canon = factory_name.substr(0,pos); received = db->import_event(factory_name_canon); } else throw; } else throw; } } } catch (...) { // // Impossible to connect to notifd. In case there is already an entry in the db // for this server event channel, clear it. // if (tg->is_svr_starting() == true) { try { db->unexport_event(d_name); } catch (...) {} // // There is a cout and a cerr here to have the message displayed on the console // AND sent to the logging system (cout is redirected to the logging when // compiled with -D_TANGO_LIB) // cout4 << "Failed to import EventChannelFactory " << factory_name << " from the Tango database" << endl; } EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to import the EventChannelFactory from the Tango database", (const char*)"NotifdEventSupplier::create()"); } if (tg->get_db_cache() == NULL) received.inout() >>= dev_import_list; factory_ior = string((dev_import_list->svalue)[1]); } else { Tango::DbDatum na; string cl_name("notifd"); try { na = db->get_device_name(server_name,cl_name); } catch (Tango::DevFailed &) { if (tg->is_svr_starting() == true) { cout4 << "Failed to import EventChannelFactory from the Device Server property file" << endl; cout4 << "Notifd event will not be generated" << endl; } EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to import the EventChannelFactory from the Device Server property file", (const char*)"NotifdEventSupplier::create()"); } factory_ior = na.value_string[0]; } try { CORBA::Object *event_factory_obj; event_factory_obj = _orb -> string_to_object(factory_ior.c_str()); // omniORB::setClientConnectTimeout(NARROW_CLNT_TIMEOUT); #ifndef _TG_WINDOWS_ if (event_factory_obj -> _non_existent()) event_factory_obj = CORBA::Object::_nil(); #else if (Util::_FileDb == false) { if ((dev_import_list->lvalue)[0] == 0) Tango::Except::throw_exception("aaa","bbb","ccc"); } #endif /* _TG_WINDOWS_ */ // // Narrow the CORBA_Object reference to an EventChannelFactory // reference so we can invoke its methods // _eventChannelFactory = CosNotifyChannelAdmin::EventChannelFactory::_narrow(event_factory_obj); // omniORB::setClientConnectTimeout(0); // // Make sure the CORBA object was really an EventChannelFactory // if(CORBA::is_nil(_eventChannelFactory)) { cerr << factory_name << " is not an EventChannelFactory " << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to import the EventChannelFactory from the Tango database", (const char*)"NotifdEventSupplier::create()"); } } catch (...) { // omniORB::setClientConnectTimeout(0); // // Impossible to connect to notifd. In case there is already an entry in the db // for this server event channel, clear it. // if ((Util::_FileDb == false) && (tg->is_svr_starting() == true)) { try { db->unexport_event(d_name); } catch (...) {} } // // There is a cout and a cerr here to have the message displayed on the console // AND sent to the logging system (cout is redirected to the logging when // compiled with -D_TANGO_LIB) // Print these messages only during DS startup sequence // if (tg->is_svr_starting() == true) { cout4 << "Failed to narrow the EventChannelFactory - Notifd events will not be generated (hint: start the notifd daemon on this host)" << endl; } EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to narrow the EventChannelFactory, make sure the notifd process is running on this host", (const char*)"NotifdEventSupplier::create()"); } // // Get a reference to an EventChannel for this device server from the // TANGO database // int channel_exported=-1; string channel_ior, channel_host; if (Util::_FileDb == false) { try { if (tg->get_db_cache() != NULL) { dev_import_list = tg->get_db_cache()->DbServerCache::import_adm_event(); } else { received = db->import_event(d_name); } } catch (...) { // // There is a cout and a cerr here to have the message displayed on the console // AND sent to the logging system (cout is redirected to the logging when // compiled with -D_TANGO_LIB) // cerr << d_name << " has no event channel defined in the database - creating it " << endl; cout << d_name << " has no event channel defined in the database - creating it " << endl; channel_exported = 0; } if (channel_exported != 0) { if (tg->get_db_cache() == NULL) received.inout() >>= dev_import_list; channel_ior = string((dev_import_list->svalue)[1]); channel_exported = dev_import_list->lvalue[0]; // // check if the channel is exported on this host, if not assume it // is an old channel and we need to recreate it on the local host // channel_host = string((dev_import_list->svalue)[3]); if (channel_host != host_name) channel_exported = 0; } } else { try { Tango::DbDatum na; string cl_name(NOTIFD_CHANNEL); na = db->get_device_name(server_name,cl_name); channel_ior = na.value_string[0]; channel_exported = 1; } catch (Tango::DevFailed &) { channel_exported = 0; } } if (channel_exported) { CORBA::Object *event_channel_obj; event_channel_obj = _orb -> string_to_object(channel_ior.c_str()); try { if (event_channel_obj -> _non_existent()) event_channel_obj = CORBA::Object::_nil(); _eventChannel = CosNotifyChannelAdmin::EventChannel::_nil(); _eventChannel = CosNotifyChannelAdmin::EventChannel::_narrow(event_channel_obj); if(CORBA::is_nil(_eventChannel)) { channel_exported = 0; } } catch (...) { cout4 << "caught exception while trying to test event_channel object\n"; channel_exported = 0; } } // // The device server event channel does not exist, let's create a new one // if (!channel_exported) { CosNotification::QoSProperties initialQoS; CosNotification::AdminProperties initialAdmin; CosNotifyChannelAdmin::ChannelID channelId; try { _eventChannel = _eventChannelFactory -> create_channel(initialQoS, initialAdmin, channelId); cout4 << "Tango::NotifdEventSupplier::create() channel for server " << d_name << " created\n"; char *_ior = _orb->object_to_string(_eventChannel); string ior_string(_ior); if (Util::_FileDb == false) { Tango::DevVarStringArray *eve_export_list = new Tango::DevVarStringArray; eve_export_list->length(5); (*eve_export_list)[0] = CORBA::string_dup(d_name.c_str()); (*eve_export_list)[1] = CORBA::string_dup(ior_string.c_str()); (*eve_export_list)[2] = CORBA::string_dup(host_name.c_str()); ostringstream ostream; ostream << getpid() << ends; (*eve_export_list)[3] = CORBA::string_dup(ostream.str().c_str()); (*eve_export_list)[4] = CORBA::string_dup("1"); bool retry = true; int ctr = 0; int db_to = db->get_timeout_millis(); db->set_timeout_millis(db_to * 2); while ((retry == true) && (ctr < 4)) { try { db->export_event(eve_export_list); retry = false; } catch (Tango::CommunicationFailed &) {ctr++;} } db->set_timeout_millis(db_to); cout4 << "successfully exported event channel to Tango database !\n"; } else { // // In case of DS started with -file option, store the // event channel within the event supplier object and in the file // ns.ec_ior = ior_string; try { db->write_event_channel_ior_filedatabase(ior_string); } catch (Tango::DevFailed &e) {} } CORBA::string_free(_ior); } catch(const CosNotification::UnsupportedQoS&) { cerr << "Failed to create event channel - events will not be generated (hint: start the notifd daemon on this host)" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to create a new EventChannel, make sure the notifd process is running on this host", (const char*)"NotifdEventSupplier::create()"); } catch(const CosNotification::UnsupportedAdmin&) { cerr << "Failed to create event channel - events will not be generated (hint: start the notifd daemon on this host)" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to create a new EventChannel, make sure the notifd process is running on this host", (const char*)"NotifdEventSupplier::create()"); } } else { cout4 << "Tango::NotifdEventSupplier::create(): _narrow worked, use this event channel\n"; if (Util::_FileDb == true) ns.ec_ior = channel_ior; } // // Obtain a Supplier Admin // // // We'll use the channel's default Supplier admin // CosNotifyChannelAdmin::SupplierAdmin_var _supplierAdmin = _eventChannel -> default_supplier_admin(); if (CORBA::is_nil(_supplierAdmin)) { cerr << "Could not get CosNotifyChannelAdmin::SupplierAdmin" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to get the default supplier admin from the notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventSupplier::create()"); } // // If necessary, clean up remaining proxies left by previous run of the DS // which did a core dump (or similar) // if (tg->is_svr_starting() == true) { CosNotifyChannelAdmin::ProxyIDSeq_var proxies; proxies = _supplierAdmin->push_consumers(); if (proxies->length() >= 1) { for (unsigned int loop = 0;loop < proxies->length();loop++) { CosNotifyChannelAdmin::ProxyConsumer_var _tmp_proxyConsumer; _tmp_proxyConsumer = _supplierAdmin->get_proxy_consumer(proxies[loop]); CosNotifyChannelAdmin::StructuredProxyPushConsumer_var _tmp_structuredProxyPushConsumer; _tmp_structuredProxyPushConsumer = CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(_tmp_proxyConsumer); if (CORBA::is_nil(_tmp_structuredProxyPushConsumer)) { continue; } try { _tmp_structuredProxyPushConsumer->disconnect_structured_push_consumer(); } catch(CORBA::Exception &) {} } } } // // Obtain a Proxy Consumer // // // We are using the "Push" model and Structured data // CosNotifyChannelAdmin::ProxyID _proxyId; CosNotifyChannelAdmin::ProxyConsumer_var _proxyConsumer; try { _proxyConsumer = _supplierAdmin -> obtain_notification_push_consumer(CosNotifyChannelAdmin::STRUCTURED_EVENT, _proxyId); if (CORBA::is_nil(_proxyConsumer)) { cerr << "Could not get CosNotifyChannelAdmin::ProxyConsumer" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to obtain a Notification push consumer, make sure the notifd process is running on this host", (const char*)"NotifdEventSupplier::create()"); } } catch(const CosNotifyChannelAdmin::AdminLimitExceeded&) { cerr << "Failed to get push consumer from notification daemon - events will not be generated (hint: start the notifd daemon on this host)" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to get push consumer from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventSupplier::create()"); } CosNotifyChannelAdmin::StructuredProxyPushConsumer_var _structuredProxyPushConsumer = CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(_proxyConsumer); if (CORBA::is_nil(_structuredProxyPushConsumer)) { cerr << "Tango::NotifdEventSupplier::create() could not get CosNotifyChannelAdmin::StructuredProxyPushConsumer" << endl; } // // Init returned value // ns.SupAdm = _supplierAdmin; ns.pID = _proxyId; ns.ProCon = _proxyConsumer; ns.StrProPush = _structuredProxyPushConsumer; ns.EveChaFac = _eventChannelFactory; ns.EveCha = _eventChannel; } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::push_heartbeat_event() // // description : Method to send the hearbeat event // // argument : in : // //----------------------------------------------------------------------------- void NotifdEventSupplier::push_heartbeat_event() { CosNotification::StructuredEvent struct_event; string event, domain_name; time_t delta_time; time_t now_time; static int heartbeat_counter=0; // // Heartbeat - check wether a heartbeat event has been sent recently // if not then send it. A heartbeat contains no data, it is used by the // consumer to know that the supplier is still alive. // Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); now_time = time(NULL); delta_time = now_time - adm_dev->last_heartbeat; cout3 << "NotifdEventSupplier::push_heartbeat_event(): delta time since last heartbeat " << delta_time << endl; // // We here compare delta_time to 8 and not to 10. // This is necessary because, sometimes the polling thread is some // milli second in advance. The computation here is done in seconds // So, if the polling thread is in advance, delta_time computed in // seconds will be 9 even if in reality it is 9,9 // if (delta_time >= 8) { domain_name = "dserver/" + adm_dev->get_full_name(); struct_event.header.fixed_header.event_type.domain_name = CORBA::string_dup(domain_name.c_str()); struct_event.header.fixed_header.event_type.type_name = CORBA::string_dup(fqdn_prefix.c_str()); struct_event.header.variable_header.length( 0 ); cout3 << "NotifdEventSupplier::push_heartbeat_event(): detected heartbeat event for " << domain_name << endl; cout3 << "NotifdEventSupplier::push_heartbeat_event(): delta _time " << delta_time << endl; struct_event.header.fixed_header.event_name = CORBA::string_dup("heartbeat"); struct_event.filterable_data.length(1); struct_event.filterable_data[0].name = CORBA::string_dup("heartbeat_counter"); struct_event.filterable_data[0].value <<= (CORBA::Long) heartbeat_counter++; adm_dev->last_heartbeat = now_time; struct_event.remainder_of_body <<= (CORBA::Long)adm_dev->last_heartbeat; // // Push the event // bool fail = false; try { structuredProxyPushConsumer -> push_structured_event(struct_event); } catch(const CosEventComm::Disconnected&) { cout3 << "NotifdEventSupplier::push_heartbeat_event() event channel disconnected !\n"; fail = true; } catch(const CORBA::TRANSIENT &) { cout3 << "NotifdEventSupplier::push_heartbeat_event() caught a CORBA::TRANSIENT ! " << endl; fail = true; } catch(const CORBA::COMM_FAILURE &) { cout3 << "NotifdEventSupplier::push_heartbeat_event() caught a CORBA::COMM_FAILURE ! " << endl; fail = true; } catch(const CORBA::SystemException &) { cout3 << "NotifdEventSupplier::push_heartbeat_event() caught a CORBA::SystemException ! " << endl; fail = true; } // // If it was not possible to communicate with notifd, // try a reconnection // if (fail == true) { try { reconnect_notifd(); } catch (...) {} } } } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::reconnect_notifd() // // description : Method to reconnect to the notifd // // argument : in : // //----------------------------------------------------------------------------- void NotifdEventSupplier::reconnect_notifd() { // // Check notifd but trying to read an attribute of the event channel // If it works, we immediately return // try { CosNotifyChannelAdmin::EventChannelFactory_var ecf = eventChannel->MyFactory(); return; } catch (...) { cout3 << "Notifd dead !!!!!!" << endl; } // // Reconnect process to notifd after forcing // process to re-read the file database // in case it is used // try { NotifService ns; Tango::Util *tg = Tango::Util::instance(); Database *db = tg->get_database(); if (Util::_FileDb == true) db->reread_filedatabase(); connect_to_notifd(ns,orb_,tg->get_ds_name(),tg); supplierAdmin = ns.SupAdm; proxyId = ns.pID; proxyConsumer = ns.ProCon; structuredProxyPushConsumer = ns.StrProPush; eventChannelFactory = ns.EveChaFac; eventChannel = ns.EveCha; event_channel_ior = ns.ec_ior; } catch (...) { cout3 << "Can't reconnect.............." << endl; } connect(); } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::disconnect_from_notifd() // // description : Method to disconnect the DS from the notifd event channel // //----------------------------------------------------------------------------- void NotifdEventSupplier::disconnect_from_notifd() { try { structuredProxyPushConsumer->disconnect_structured_push_consumer(); } catch(CORBA::Exception &) {} } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::push_event() // // description : Method to send the event to the event channel // // argument : in : device_impl : The device // event_type : The event type (change, periodic....) // filterable_names : // filterable_data : // attr_value : The attribute value // except : The exception thrown during the last // attribute reading. NULL if no exception // //----------------------------------------------------------------------------- void NotifdEventSupplier::push_event(DeviceImpl *device_impl,string event_type, vector &filterable_names,vector &filterable_data,vector &filterable_names_lg, vector &filterable_data_lg, struct SuppliedEventData &attr_value,string &attr_name,DevFailed *except,TANGO_UNUSED(bool inc_cptr)) { CosNotification::StructuredEvent struct_event; string domain_name; cout3 << "NotifdEventSupplier::push_event(): called for attribute " << attr_name << endl; // // If we are called for IDL 5 (AttributeValue_5 or AttributeConfig_5), simply return. IDL 5 is only for ZMQ // if (attr_value.attr_conf_5 != Tango_nullptr || attr_value.attr_val_5 != Tango_nullptr) return; // get the mutex to synchronize the sending of events omni_mutex_lock oml(push_mutex); string loc_attr_name = attr_name; transform(loc_attr_name.begin(),loc_attr_name.end(),loc_attr_name.begin(),::tolower); domain_name = device_impl->get_name_lower() + "/" + loc_attr_name; string::size_type pos = event_type.find(EVENT_COMPAT); if (pos != string::npos) event_type.erase(0,EVENT_COMPAT_IDL5_SIZE); struct_event.header.fixed_header.event_type.domain_name = CORBA::string_dup(domain_name.c_str()); struct_event.header.fixed_header.event_type.type_name = CORBA::string_dup(fqdn_prefix.c_str()); struct_event.header.variable_header.length( 0 ); unsigned long nb_filter = filterable_names.size(); unsigned long nb_filter_lg = filterable_names_lg.size(); struct_event.filterable_data.length(nb_filter + nb_filter_lg); if (nb_filter != 0) { if (nb_filter == filterable_data.size()) { for (unsigned long i = 0; i < nb_filter; i++) { struct_event.filterable_data[i].name = CORBA::string_dup(filterable_names[i].c_str()); struct_event.filterable_data[i].value <<= (CORBA::Double) filterable_data[i]; } } } if (nb_filter_lg != 0) { if (nb_filter_lg == filterable_data_lg.size()) { for (unsigned long i = 0; i < nb_filter_lg; i++) { struct_event.filterable_data[i + nb_filter].name = CORBA::string_dup(filterable_names_lg[i].c_str()); struct_event.filterable_data[i + nb_filter].value <<= (CORBA::Long) filterable_data_lg[i]; } } } if (except == NULL) { if (attr_value.attr_val != NULL) struct_event.remainder_of_body <<= (*attr_value.attr_val); else if (attr_value.attr_val_3 != NULL) struct_event.remainder_of_body <<= (*attr_value.attr_val_3); else if (attr_value.attr_val_4 != NULL) { struct_event.remainder_of_body <<= (*attr_value.attr_val_4); // // Insertion in the event structure Any also copy the mutex ptr. // When this event structure will be deleted (at the end of this method), // the struct inserted into the Any will also be deleted. // This will unlock the mutex.... // Clean the mutex ptr in the structure inserted in the Any to prevent this // bad behavior // const Tango::AttributeValue_4 *tmp_ptr; struct_event.remainder_of_body >>= tmp_ptr; const_cast(tmp_ptr)->mut_ptr = NULL; } else if (attr_value.attr_val_5 != NULL) { string str("Can't send event! Client is too old (Tango 7 or less).\n"); str = str + ("Please, re-compile your client with at least Tango 8"); cerr << str << endl; Except::throw_exception(API_NotSupported,str,"NotifdEventSupplier::push_event"); } else if (attr_value.attr_conf_2 != NULL) struct_event.remainder_of_body <<= (*attr_value.attr_conf_2); else if (attr_value.attr_conf_3 != NULL) struct_event.remainder_of_body <<= (*attr_value.attr_conf_3); else struct_event.remainder_of_body <<= (*attr_value.attr_dat_ready); } else struct_event.remainder_of_body <<= except->errors; struct_event.header.fixed_header.event_name = CORBA::string_dup(event_type.c_str()); cout3 << "EventSupplier::push_event(): push event " << event_type << " for " << device_impl->get_name() + "/" + attr_name << endl; // // Push the event // bool fail = false; try { structuredProxyPushConsumer -> push_structured_event(struct_event); } catch(const CosEventComm::Disconnected&) { cout3 << "EventSupplier::push_event() event channel disconnected !\n"; fail = true; } catch(const CORBA::TRANSIENT &) { cout3 << "EventSupplier::push_event() caught a CORBA::TRANSIENT ! " << endl; fail = true; } catch(const CORBA::COMM_FAILURE &) { cout3 << "EventSupplier::push_event() caught a CORBA::COMM_FAILURE ! " << endl; fail = true; } catch(const CORBA::SystemException &) { cout3 << "EventSupplier::push_event() caught a CORBA::SystemException ! " << endl; fail = true; } catch(...) { fail = true; } // // If it was not possible to communicate with notifd, try a reconnection // if (fail == true) { try { reconnect_notifd(); } catch (...) {} } } //+---------------------------------------------------------------------------- // // method : NotifdEventSupplier::file_db_svr() // // description : In case of DS using file as database, set a marker in the // fqdn_prefix // //----------------------------------------------------------------------------- void NotifdEventSupplier::file_db_svr() { fqdn_prefix = fqdn_prefix + '#'; } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/server/pipe.cpp0000644023471100065110000004777713034745001014250 00000000000000static const char *RcsId = "$Id: pipe.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+================================================================================================================== // // file : Pipe.cpp // // description : C++ source code for the Pipe class. The Pipe class is the root class for all derived // Pipe classes. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28853 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // Pipe::Pipe // // description : // Constructor for abstract class Pipe // //----------------------------------------------------------------------------------------------------------------- Pipe::Pipe(const string &_name,Tango::DispLevel _level,PipeWriteType _pwt) :name(_name),disp_level(_level),writable(_pwt),ext(new PipeExt) { lower_name = name; transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); pipe_serial_model = PIPE_BY_KERNEL; event_subscription = 0; // // Set lib default value for pipe label and desc // label = name; desc = DescNotSpec; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Pipe::set_default_properties // // description : // This method set the default user properties in the Pipe object. // // arguments : // in : // - prop_list : The user property list // //------------------------------------------------------------------------------------------------------------------- void Pipe::set_default_properties(UserDefaultPipeProp &prop_list) { // // Init value in Pipe instance // if ((prop_list.label.empty() == false) && (TG_strcasecmp(prop_list.label.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.label.c_str(),NotANumber) != 0)) label = prop_list.label; if (prop_list.description.empty() == false && (TG_strcasecmp(prop_list.description.c_str(),AlrmValueNotSpec) != 0) && (TG_strcasecmp(prop_list.description.c_str(),NotANumber) != 0)) desc = prop_list.description; // // Memorize user default (if any) for case of user requesting a "return to user default" // user_def_prop.clear(); if (prop_list.label.empty() == false) { PipeProperty pp("label",prop_list.label); user_def_prop.push_back(pp); } if (prop_list.description.empty() == false) { PipeProperty pp("description",prop_list.description); user_def_prop.push_back(pp); } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Pipe::set_upd_properties // // description : // Update pipe properties // // arguments : // in : // - new_conf : The pipe new configuration // - dev : The device // //-------------------------------------------------------------------------------------------------------------------- void Pipe::set_upd_properties(const PipeConfig &new_conf,DeviceImpl *dev) { // // Backup current configuration (only label and description) // PipeConfig old_conf = new_conf; old_conf.label = CORBA::string_dup(label.c_str()); old_conf.description = CORBA::string_dup(desc.c_str()); try { // // Set properties locally. In case of exception bring the backed-up values // vector v_db; set_properties(new_conf,dev,v_db); // // Update database // try { upd_database(v_db,dev->get_name()); } catch(DevFailed &) { // // In case of exception, try to store old properties in the database and inform the user about the error // try { v_db.clear(); set_properties(old_conf,dev,v_db); upd_database(v_db,dev->get_name()); } catch(DevFailed &) { // // If the old values could not be restored, notify the user about possible database corruption // TangoSys_OMemStream o; o << "Device " << dev->get_name() << "-> Pipe : " << name; o << "\nDatabase error occurred whilst setting pipe properties. The database may be corrupted." << ends; Except::throw_exception(API_CorruptedDatabase,o.str(),"Pipe::set_upd_properties()"); } throw; } } catch(DevFailed &) { vector v_db; set_properties(old_conf,dev,v_db); throw; } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // Pipe::upd_database // // description : // Update database according to the info received in the v_db parameter. We update or delete info in db for // pipe configuration. // // Arguments: // in : // - v_db : The vector of info with what has to be done in DB // - dev_name : The device name // //--------------------------------------------------------------------------------------------------------------------- void Pipe::upd_database(vector &v_db,string &dev_name) { // // Build info needed for the method upddating DB // long prop_to_update = 0; long prop_to_delete = 0; Tango::DbData db_d; Tango::DbData db_del; db_d.push_back(DbDatum(name)); db_del.push_back(DbDatum(name)); vector::iterator ite; // // A loop for each db action // for (ite = v_db.begin();ite != v_db.end();++ite) { switch (ite->dba) { case Attribute::UPD: { DbDatum desc(ite->name); desc << ite->db_value; db_d.push_back(desc); prop_to_update++; } break; case Attribute::UPD_FROM_DB: { DbDatum desc(ite->name); desc << ite->db_value_db; db_d.push_back(desc); prop_to_update++; } break; case Attribute::UPD_FROM_VECT_STR: { DbDatum desc(ite->name); desc << ite->db_value_v_str; db_d.push_back(desc); prop_to_update++; } break; case Attribute::DEL: { DbDatum desc(ite->name); db_del.push_back(desc); prop_to_delete++; } break; } } // // Update database // struct Attribute::CheckOneStrProp cosp; cosp.prop_to_delete = &prop_to_delete; cosp.prop_to_update = &prop_to_update; cosp.db_d = &db_d; cosp.db_del = &db_del; // // Update db only if needed // if (*cosp.prop_to_update != 0) { cout4 << *cosp.prop_to_update << " properties to update in db" << endl; (*cosp.db_d)[0] << *cosp.prop_to_update; //for (const auto &elem: *cosp.db_d) // cout << "prop_to_update name = " << elem.name << endl; Tango::Util *tg = Tango::Util::instance(); // // Implement a reconnection schema. The first exception received if the db server is down is a COMM_FAILURE exception. // Following exception received from following calls are TRANSIENT exception // bool retry = true; while (retry == true) { try { tg->get_database()->put_device_pipe_property(dev_name,*cosp.db_d); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } if (*cosp.prop_to_delete != 0) { cout4 << *cosp.prop_to_delete << " properties to delete in db" << endl; (*cosp.db_del)[0] << *cosp.prop_to_delete; //for (const auto &elem: *cosp.db_del) // cout << "prop_to_delete name = " << elem.name << endl; Tango::Util *tg = Tango::Util::instance(); // // Implement a reconnection schema. The first exception received if the db server is down is a COMM_FAILURE exception. // Following exception received from following calls are TRANSIENT exception // bool retry = true; while (retry == true) { try { tg->get_database()->delete_device_pipe_property(dev_name,*cosp.db_del); retry = false; } catch (CORBA::COMM_FAILURE &) { tg->get_database()->reconnect(true); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Pipe::set_properties // // description : // Set the pipe properties value for PipeConfig // // argument : // in : // - conf : The new properties sent by client // - dev : The device // out : // - v_db : Vector of data used for database update/delete // //-------------------------------------------------------------------------------------------------------------------- void Pipe::set_properties(const Tango::PipeConfig &conf,DeviceImpl *dev,vector &v_db) { // // Check if the caller try to change "hard coded"properties. Throw exception in case of // string user_pipe_name(conf.name.in()); transform(user_pipe_name.begin(),user_pipe_name.end(),user_pipe_name.begin(),::tolower); if (user_pipe_name != lower_name) { Except::throw_exception(API_AttrNotAllowed,"Pipe name is not changeable at run time","Pipe::set_properties()"); } if (conf.writable != writable) { Except::throw_exception(API_AttrNotAllowed,"Pipe writable property is not changeable at run time","Pipe::set_properties()"); } // // Copy only a sub-set of the new properties // For each "string" property, an empty string means returns to its default value which could be the library default // value or the user defined default value // Tango::DeviceClass *dev_class = dev->get_device_class(); vector &def_user_prop = get_user_default_properties(); vector def_class_prop; try { def_class_prop = dev_class->get_class_pipe()->get_prop_list(name); } catch (DevFailed &e) {} // // First the string properties // set_one_str_prop("description",conf.description,desc,v_db,def_user_prop,def_class_prop,DescNotSpec); set_one_str_prop("label",conf.label,label,v_db,def_user_prop,def_class_prop,name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Pipe::set_one_str_prop // // description : // Analyse one of the string properties. String properties are description and label // A similar method exist in Attribute class. It's difficult to make it static and use it in this Pipe class // // argument : // in : // - prop_name : The property name // - conf_val : The new property value // - def_user_prop : The set of user defined default values // - def_class_prop : The set of class defined default values // - lib_def : The property library default value // out : // - pipe_conf : The new property in Pipe object // - v_db : Vector of data used for database update/delete // //-------------------------------------------------------------------------------------------------------------------- void Pipe::set_one_str_prop(const char *prop_name,const CORBA::String_member &conf_val, string &pipe_conf,vector &v_db,vector &def_user_prop, vector &def_class_prop,const char *lib_def) { Attribute::AttPropDb apd; apd.name = prop_name; bool user_defaults, class_defaults; string usr_def_val, class_def_val; size_t nb_user = def_user_prop.size(); size_t nb_class = def_class_prop.size(); user_defaults = prop_in_list(prop_name,usr_def_val,nb_user,def_user_prop); class_defaults = prop_in_list(prop_name,class_def_val,nb_class,def_class_prop); if (TG_strcasecmp(conf_val,AlrmValueNotSpec) == 0) { // // Return to lib default. If something defined as user default or class default, put entry in DB to overwrite // these defaults // string old_val = pipe_conf; pipe_conf = lib_def; if (old_val != pipe_conf) { if (user_defaults == true || class_defaults == true) { apd.dba = Attribute::UPD; apd.db_value = pipe_conf; v_db.push_back(apd); } else { apd.dba = Attribute::DEL; v_db.push_back(apd); } } } else if (strlen(conf_val) == 0) { // // Return to user default or lib default. If something defined as class default, put entry in DB in order to // overwrite this default value. // string old_val = pipe_conf; if (user_defaults == true) pipe_conf = usr_def_val; else { pipe_conf = lib_def; } if (old_val != pipe_conf) { if (class_defaults == true) { apd.dba = Attribute::UPD; apd.db_value = pipe_conf; v_db.push_back(apd); } else { apd.dba = Attribute::DEL; v_db.push_back(apd); } } } else if (TG_strcasecmp(conf_val,NotANumber) == 0) { // // Return to class default or user default or lib default // string old_val = pipe_conf; if (class_defaults == true) pipe_conf = class_def_val; else if (user_defaults == true) pipe_conf = usr_def_val; else { pipe_conf = lib_def; } if (old_val != pipe_conf) { apd.dba = Attribute::DEL; v_db.push_back(apd); } } else { // // Set property // string old_val = pipe_conf; pipe_conf = conf_val; if (user_defaults == true && pipe_conf == usr_def_val) { // // Property value is the same than the user default value // if (old_val != pipe_conf) { if (class_defaults == true) { apd.dba = Attribute::UPD; apd.db_value = pipe_conf; v_db.push_back(apd); } else { apd.dba = Attribute::DEL; v_db.push_back(apd); } } } else if (class_defaults == true && pipe_conf == class_def_val) { // // Property value is the same than the class default value // if (old_val != pipe_conf) { apd.dba = Attribute::DEL; v_db.push_back(apd); } } else if (class_defaults == false && TG_strcasecmp(pipe_conf.c_str(),lib_def) == 0) { // // Property value is the same than the lib default value // if (old_val != pipe_conf) { apd.dba = Attribute::DEL; v_db.push_back(apd); } } else if (class_defaults == false && strcmp(prop_name,"label") == 0) { // // Property Label: Property value is the same than the lib default value // if (old_val != pipe_conf) { if (TG_strcasecmp(pipe_conf.c_str(),LabelNotSpec) == 0) { apd.dba = Attribute::DEL; v_db.push_back(apd); } else { apd.dba = Attribute::UPD; apd.db_value = pipe_conf; v_db.push_back(apd); } } } else { if (old_val != pipe_conf) { apd.dba = Attribute::UPD; apd.db_value = pipe_conf; v_db.push_back(apd); } } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Pipe::set_time // // description : // Set the date in the pipe object // //-------------------------------------------------------------------------------------------------------------------- void Pipe::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); when.tv_sec = (CORBA::Long)t.time; when.tv_usec = (CORBA::Long)(t.millitm * 1000); when.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); when.tv_sec = (CORBA::Long)tv.tv_sec; when.tv_usec = (CORBA::Long)tv.tv_usec; when.tv_nsec = 0; #endif } //+------------------------------------------------------------------------- // // method : Pipe::set_pipe_serial_method // // description : Set pipe serialization method // //-------------------------------------------------------------------------- void Pipe::set_pipe_serial_model(PipeSerialModel ser_model) { if (ser_model == Tango::PIPE_BY_USER) { Tango::Util *tg = Tango::Util::instance(); if (tg->get_serial_model() != Tango::BY_DEVICE) { Except::throw_exception(API_PipeNotAllowed, "Pipe serial model by user is not allowed when the process is not in BY_DEVICE serialization model", "Pipe::set_pipe_serial_model"); } } pipe_serial_model=ser_model; } Pipe &Pipe::operator[](const string &_na) { the_blob.operator[](_na); return *this; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Pipe::fire_event // // description : // Fire a pipe event // // arguments: // in : // - dev : Device pointer // - except : Pointer to the DevFailed exception // //--------------------------------------------------------------------------------------------------------------------- void Pipe::fire_event(DeviceImpl *dev,DevFailed *except) { cout4 << "Pipe::fire_event() entering ..." << endl; // // Check if it is needed to send an event // time_t now; time_t delta_subscription; now = time(NULL); delta_subscription = now - event_subscription; if (delta_subscription >= EVENT_RESUBSCRIBE_PERIOD) return; // // Get the event supplier, and simply return if not created // ZmqEventSupplier *event_supplier_zmq = NULL; Tango::Util *tg = Util::instance(); event_supplier_zmq = tg->get_zmq_event_supplier(); if (event_supplier_zmq == NULL) { return; } // // Make sure the severity field is initialized (this field is never used!!) // size_t err_nb = except->errors.length(); for (size_t loop = 0;loop < err_nb;loop++) (except->errors)[loop].severity = Tango::ERR; // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); // // Fire event // vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; event_supplier_zmq->push_event(dev,"pipe",f_names,f_data,f_names_lg,f_data_lg,ad,name,except,true); } #ifdef _TG_WINDOWS_ void Pipe::fire_event(DeviceImpl *_dev,DevicePipeBlob *_dat,bool reuse_it) { struct _timeb now_win; struct timeval now; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; fire_event(_dev,_dat,now,reuse_it); } #endif // _TG_WINDOWS_ void Pipe::fire_event(DeviceImpl *dev,DevicePipeBlob *p_data,struct timeval &t,bool reuse_it) { cout4 << "Pipe::fire_event() entering ..." << endl; // // Check if it is needed to send an event // time_t now; time_t delta_subscription; now = time(NULL); delta_subscription = now - event_subscription; if (delta_subscription >= EVENT_RESUBSCRIBE_PERIOD) return; // // Get the event supplier, and simply return if not created // ZmqEventSupplier *event_supplier_zmq = NULL; Tango::Util *tg = Util::instance(); event_supplier_zmq = tg->get_zmq_event_supplier(); if (event_supplier_zmq == NULL) { return; } // // Create the structure used to send data to event system // EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); // // Init the structure sent with the event // ad.pipe_val = new DevPipeData(); ad.pipe_val->name = CORBA::string_dup(name.c_str()); ::memset(&(ad.pipe_val->time),0,sizeof(ad.pipe_val->time)); ad.pipe_val->time.tv_sec = t.tv_sec; ad.pipe_val->time.tv_usec = t.tv_usec; const string &bl_name = p_data->get_name(); if (bl_name.size() != 0) ad.pipe_val->data_blob.name = bl_name.c_str(); DevVarPipeDataEltArray *tmp_ptr = p_data->get_insert_data(); if (tmp_ptr == Tango_nullptr) { Except::throw_exception(API_PipeNoDataElement,"No data in DevicePipeBlob!","Pipe::fire_event()"); } CORBA::ULong max,len; max = tmp_ptr->maximum(); len = tmp_ptr->length(); ad.pipe_val->data_blob.blob_data.replace(max,len,tmp_ptr->get_buffer((CORBA::Boolean)true),true); // // Fire event // vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; event_supplier_zmq->push_event(dev,"pipe",f_names,f_data,f_names_lg,f_data_lg,ad,name,NULL,true); if (reuse_it == false) { p_data->reset_insert_ctr(); delete tmp_ptr; } delete ad.pipe_val; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/pollcmds.cpp0000644023471100065110000002563013034745001015110 00000000000000static const char *RcsId = "$Id: pollcmds.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : PollCmds.cpp // // description : C++ source for the DServerClass and for the // command class defined for this class. The singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the DServer once per process. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //+------------------------------------------------------------------------- // // method : PolledDeviceCmd::PolledDeviceCmd // // description : constructors for Command class PolledDevice // //-------------------------------------------------------------------------- PolledDeviceCmd::PolledDeviceCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *out_desc):Command(name,in,out) { set_out_type_desc(out_desc); } //+------------------------------------------------------------------------- // // method : PolledDeviceCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *PolledDeviceCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "PolledDevice::execute(): arrived " << endl; // // Call the device method and return to caller // return insert((static_cast(device))->polled_device()); } //+------------------------------------------------------------------------- // // method : DevPollStatusCmd::DevPollStatusCmd // // description : constructors for Command class DevPollStatus // //-------------------------------------------------------------------------- DevPollStatusCmd::DevPollStatusCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc):Command(name,in,out) { set_in_type_desc(in_desc); set_out_type_desc(out_desc); } //+------------------------------------------------------------------------- // // method : DevPollStatusCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *DevPollStatusCmd::execute(DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "DevPollStatus::execute(): arrived " << endl; // // Extract the input string // const char *tmp_name; if ((in_any >>= tmp_name) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : string", (const char *)"DevPollStatusCmd::execute"); } string d_name(tmp_name); cout4 << "Received string = " << d_name << endl; // // Call the device method and return to caller // return insert((static_cast(device))->dev_poll_status(d_name)); } //+------------------------------------------------------------------------- // // method : AddObjPollingCmd::AddObjPollingCmd // // description : constructors for Command class DevPollStatus // //-------------------------------------------------------------------------- AddObjPollingCmd::AddObjPollingCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+------------------------------------------------------------------------- // // method : AddObjPollingCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *AddObjPollingCmd::execute(DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "AddObjPolling::execute(): arrived " << endl; // // Extract the input structure // const DevVarLongStringArray *tmp_data; if ((in_any >>= tmp_data) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarLongStringArray", (const char *)"AddObjPollingCmd::execute"); } // // Call the device method and return to caller // (static_cast(device))->add_obj_polling(tmp_data); // // Return to caller // CORBA::Any *ret = return_empty_any("AddObjPolling"); return ret; } //+------------------------------------------------------------------------- // // method : UpdObjPollingPeriodCmd::UpdObjPollingPeriodCmd // // description : constructors for Command class UpdObjPolledPeriod // //-------------------------------------------------------------------------- UpdObjPollingPeriodCmd::UpdObjPollingPeriodCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+------------------------------------------------------------------------- // // method : UpdObjPollingPeriodCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *UpdObjPollingPeriodCmd::execute(DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "UpdObjPollingPeriod::execute(): arrived " << endl; // // Extract the input structure // const DevVarLongStringArray *tmp_data; if ((in_any >>= tmp_data) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarLongStringArray", (const char *)"UpdObjPollingPeriodCmd::execute"); } // // Call the device method and return to caller // (static_cast(device))->upd_obj_polling_period(tmp_data); // // Return to caller // CORBA::Any *ret = return_empty_any("UpdObjPollingPeriod"); return ret; } //+------------------------------------------------------------------------- // // method : RemObjPollingCmd::RemObjPollingCmd // // description : constructors for Command class RemObjPolled // //-------------------------------------------------------------------------- RemObjPollingCmd::RemObjPollingCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, string &in_desc):Command(name,in,out) { set_in_type_desc(in_desc); } //+------------------------------------------------------------------------- // // method : RemObjPollingCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *RemObjPollingCmd::execute(DeviceImpl *device, const CORBA::Any &in_any) { cout4 << "RemObjPolling::execute(): arrived " << endl; // // Extract the input structure // const DevVarStringArray *tmp_data; if ((in_any >>= tmp_data) == false) { Except::throw_exception((const char *)API_IncompatibleCmdArgumentType, (const char *)"Imcompatible command argument type, expected type is : DevVarStringArray", (const char *)"RemObjPollingCmd::execute"); } // // Call the device method and return to caller // (static_cast(device))->rem_obj_polling(tmp_data); // // Return to caller // CORBA::Any *ret = return_empty_any("RemObjPolling"); return ret; } //+------------------------------------------------------------------------- // // method : StartPollingCmd::StartPollingCmd // // description : constructors for Command class RemObjPolled // //-------------------------------------------------------------------------- StopPollingCmd::StopPollingCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out):Command(name,in,out) { } //+------------------------------------------------------------------------- // // method : StartPollingCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *StopPollingCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "StopPolling::execute(): arrived " << endl; // // Call the device method and return to caller // (static_cast(device))->stop_polling(); // // Return to caller // CORBA::Any *ret = return_empty_any("StopPolling"); return ret; } //+------------------------------------------------------------------------- // // method : StartPollingCmd::StartPollingCmd // // description : constructors for Command class RemObjPolled // //-------------------------------------------------------------------------- StartPollingCmd::StartPollingCmd(const char *name, Tango::CmdArgType in, Tango::CmdArgType out):Command(name,in,out) { } //+------------------------------------------------------------------------- // // method : StartPollingCmd::execute // // description : Trigger the execution of the method really implemented // the command in the DServer class // //-------------------------------------------------------------------------- CORBA::Any *StartPollingCmd::execute(DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout4 << "StartPolling::execute(): arrived " << endl; // // Call the device method and return to caller // (static_cast(device))->start_polling(); // // Return to caller // CORBA::Any *ret = return_empty_any("StartPolling"); return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/pollobj.cpp0000644023471100065110000002604013034745001014730 00000000000000static const char *RcsId = "$Id: pollobj.cpp 29627 2016-04-15 14:18:48Z bourtemb $\n$Name$"; //+================================================================================================================== // // file : PollObj.cpp // // description : C++ source code for the PollObj class. This class is used to store all data specific to one // polled object and which does not need to be stored in the ring buffer // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29627 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // method : // PollObj::PollObj // // description : // Three constructors for the PollObj class. The first one constructs a PollObj instance with the // default polling ring depth. The second one create a PollObj instance with a specified polling ring depth // // argument : // in : // - d : The device pointer // - ty : The polled object type // - na : The polled object name // - user_upd : The polling update period (in mS) // - r_depth : The polling ring depth // //------------------------------------------------------------------------------------------------------------------- PollObj::PollObj(DeviceImpl *d,PollObjType ty,const string &na,int user_upd) :dev(d),type(ty),name(na),ring(),fwd(false) { needed_time.tv_sec = 0; needed_time.tv_usec = 0; if (user_upd < 1000) { upd.tv_usec = user_upd * 1000; upd.tv_sec = 0; } else { upd.tv_sec = user_upd / 1000; upd.tv_usec = (user_upd - (upd.tv_sec * 1000)) * 1000; } max_delta_t = (double)(user_upd / 1000.0) * dev->get_poll_old_factor(); } PollObj::PollObj(DeviceImpl *d,PollObjType ty,const string &na,int user_upd,long r_depth) :dev(d),type(ty),name(na),ring(r_depth),fwd(false) { needed_time.tv_sec = 0; needed_time.tv_usec = 0; if (user_upd < 1000) { upd.tv_usec = user_upd * 1000; upd.tv_sec = 0; } else { upd.tv_sec = user_upd / 1000; upd.tv_usec = (user_upd - (upd.tv_sec * 1000)) * 1000; } max_delta_t = (double)(user_upd / 1000.0) * dev->get_poll_old_factor(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // PollObj::insert_data // // description : // These methods insert a new element in the object ring buffer when its real data // // argument : // in : // - res : The Any returned by the command // - when : The date when data was read // - needed : The time needed to execute command/attribute reading // //-------------------------------------------------------------------------------------------------------------------- void PollObj::insert_data(CORBA::Any *res,struct timeval &when,struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_data(res,when); needed_time = needed; } void PollObj::insert_data(Tango::AttributeValueList *res,struct timeval &when,struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_data(res,when); needed_time = needed; } void PollObj::insert_data(Tango::AttributeValueList_3 *res,struct timeval &when,struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_data(res,when); needed_time = needed; } void PollObj::insert_data(Tango::AttributeValueList_4 *res,struct timeval &when,struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_data(res,when,true); needed_time = needed; } void PollObj::insert_data(Tango::AttributeValueList_5 *res,struct timeval &when,struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_data(res,when,true); needed_time = needed; } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::insert_except // // description : // This method insert a new element in the ring buffer when this element is an exception // // argument : // in : // - res : The DevFailed exception // - when : The date when the exception was thrown // - needed : The time needed for the command/attribute reading // //------------------------------------------------------------------------------------------------------------------- void PollObj::insert_except(Tango::DevFailed *res, struct timeval &when, struct timeval &needed) { omni_mutex_lock sync(*this); ring.insert_except(res,when); needed_time = needed; } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::get_last_insert_date // // description : // This method returns the date stored with the most recent record in the ring buffer (as a double in Sec) // //------------------------------------------------------------------------------------------------------------------- double PollObj::get_last_insert_date_i() { struct timeval last = ring.get_last_insert_date(); double last_d = (double)last.tv_sec + ((double)last.tv_usec / 1000000); return last_d; } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::get_last_cmd_result // // description : // This method returns the last data stored in ring for a polled command or throw an exception if the // command failed when it was executed // //------------------------------------------------------------------------------------------------------------------- CORBA::Any *PollObj::get_last_cmd_result() { omni_mutex_lock sync(*this); return ring.get_last_cmd_result(); } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::get_last_attr_value // // description : // This method returns the last data stored in ring for a polled attribute or throw an exception if the // read attribuite operation failed when it was executed // //------------------------------------------------------------------------------------------------------------------- Tango::AttributeValue &PollObj::get_last_attr_value(bool lock) { if (lock == true) omni_mutex_lock sync(*this); return ring.get_last_attr_value(); } Tango::AttributeValue_3 &PollObj::get_last_attr_value_3(bool lock) { if (lock == true) omni_mutex_lock sync(*this); return ring.get_last_attr_value_3(); } Tango::AttributeValue_4 &PollObj::get_last_attr_value_4(bool lock) { if (lock == true) omni_mutex_lock sync(*this); return ring.get_last_attr_value_4(); } Tango::AttributeValue_5 &PollObj::get_last_attr_value_5(bool lock) { if (lock == true) omni_mutex_lock sync(*this); return ring.get_last_attr_value_5(); } //-------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::update_upd // // description : // This method update the polling update period // // argument : // in : // - new_upd : The new update period (in mS) // //------------------------------------------------------------------------------------------------------------------- void PollObj::update_upd(int new_upd) { if (new_upd < 1000) { upd.tv_usec = new_upd * 1000; upd.tv_sec = 0; } else { upd.tv_sec = new_upd / 1000; upd.tv_usec = (new_upd - (upd.tv_sec * 1000)) * 1000; } max_delta_t = (double)(new_upd / 1000.0) * dev->get_poll_old_factor(); } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::get_cmd_history // // description : // This method get command history from the ring buffer // // argument : // in : // - n : recodr number // - ptr : Pointer to the sequence where command result should be stored // //------------------------------------------------------------------------------------------------------------------- void PollObj::get_cmd_history(long n,Tango::DevCmdHistoryList *ptr) { omni_mutex_lock sync(*this); ring.get_cmd_history(n,ptr); } void PollObj::get_cmd_history(long n,Tango::DevCmdHistory_4 *ptr,Tango::CmdArgType &loc_type) { omni_mutex_lock sync(*this); ring.get_cmd_history(n,ptr,loc_type); } //------------------------------------------------------------------------------------------------------------------- // // method : // PollObj::get_attr_history // // description : // This method get command history from the ring buffer // // argument : // in : // - n : record number // - ptr : Pointer to the sequence where command result should be stored // - type : The attribute type // //------------------------------------------------------------------------------------------------------------------- void PollObj::get_attr_history(long n,Tango::DevAttrHistoryList *ptr,long attr_type) { omni_mutex_lock sync(*this); ring.get_attr_history(n,ptr,attr_type); } void PollObj::get_attr_history(long n,Tango::DevAttrHistoryList_3 *ptr,long attr_type) { omni_mutex_lock sync(*this); ring.get_attr_history(n,ptr,attr_type); // // Add attribute name in case of the attribute failed when it was read. // (This info is not stored in ring in case of attribute reading failure) // for (long i = 0;i < n;i++) { if ((*ptr)[i].attr_failed == true) { (*ptr)[i].value.name = CORBA::string_dup(name.c_str()); } } } void PollObj::get_attr_history(long n,Tango::DevAttrHistory_4 *ptr,long attr_type,TANGO_UNUSED(AttrDataFormat attr_format)) { omni_mutex_lock sync(*this); ring.get_attr_history(n,ptr,attr_type); } void PollObj::get_attr_history(long n,Tango::DevAttrHistory_5 *ptr,long attr_type,AttrDataFormat attr_format) { omni_mutex_lock sync(*this); ring.get_attr_history(n,ptr,attr_type); ptr->data_format = attr_format; ptr->data_type = attr_type; } void PollObj::get_attr_history_43(long n,Tango::DevAttrHistoryList_3 *ptr,long attr_type) { omni_mutex_lock sync(*this); ring.get_attr_history_43(n,ptr,attr_type); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/pollring.cpp0000644023471100065110000014634513034745002015131 00000000000000static const char *RcsId = "$Id: pollring.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================ // // file : PollRing.cpp // // description : C++ source code for the RingElt and PollRing // classes. These classes are used to implement the // tango polling ring buffer. There is one // polling ring for each Tango command or attribute // polled. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------- // // method : RingElt::RingElt // // description : Constructor for the RingElt class. // This constructor simply set the internal value to their // default // //-------------------------------------------------------------------------- RingElt::RingElt() { when.tv_sec = when.tv_usec = 0; cmd_result = NULL; attr_value = NULL; attr_value_3 = NULL; attr_value_4 = NULL; attr_value_5 = NULL; except = NULL; } //+------------------------------------------------------------------------- // // method : PollRing::PollRing // // description : Two constructors for the PollRing class. The first one // does not take any argument and construct a black box // with the default depth. // The second one create a black box with a depth defined // by the argument. // // argument : in : - max_size : The black box depth // //-------------------------------------------------------------------------- PollRing::PollRing():ring(DefaultPollRingDepth) { insert_elt = 0; nb_elt = 0; max_elt = DefaultPollRingDepth; } PollRing::PollRing(long max_size):ring(max_size) { insert_elt = 0; nb_elt = 0; max_elt = max_size; } //+------------------------------------------------------------------------- // // method : PollRing::~PollRing // // description : The class destructor. It frees all the memory allocated // to store command/attribute result // //-------------------------------------------------------------------------- PollRing::~PollRing() { cout4 << "In PollRing destructor" << endl; long nb = ring.size(); for (long i = 0;i < nb;i++) { delete ring[i].cmd_result; delete ring[i].except; delete ring[i].attr_value; delete ring[i].attr_value_3; delete ring[i].attr_value_4; delete ring[i].attr_value_5; } } //+------------------------------------------------------------------------- // // method : PollRing::insert_data // // description : These methods insert a new element in the ring buffer // when its real data // // argument : in : - any_ptr : The Any returned by the command // - t : The date // //-------------------------------------------------------------------------- void PollRing::insert_data(CORBA::Any *any_ptr,struct timeval &t) { // // Insert data in the ring // delete(ring[insert_elt].cmd_result); delete(ring[insert_elt].except); ring[insert_elt].except = NULL; ring[insert_elt].cmd_result = any_ptr; ring[insert_elt].when = t; // // Manage insert and read indexes // inc_indexes(); } void PollRing::insert_data(Tango::AttributeValueList *attr_val,struct timeval &t) { // // Insert data in the ring // delete(ring[insert_elt].attr_value); delete(ring[insert_elt].except); ring[insert_elt].except = NULL; ring[insert_elt].attr_value = attr_val; ring[insert_elt].when = t; // // Manage insert and read indexes // inc_indexes(); } void PollRing::insert_data(Tango::AttributeValueList_3 *attr_val,struct timeval &t) { // // Insert data in the ring // delete(ring[insert_elt].attr_value_3); delete(ring[insert_elt].except); ring[insert_elt].except = NULL; ring[insert_elt].attr_value_3 = attr_val; ring[insert_elt].when = t; // // Manage insert and read indexes // inc_indexes(); } void PollRing::insert_data(Tango::AttributeValueList_4 *attr_val,struct timeval &t,bool unlock) { // // Insert data in the ring // delete(ring[insert_elt].attr_value_4); delete(ring[insert_elt].except); ring[insert_elt].except = NULL; ring[insert_elt].attr_value_4 = attr_val; ring[insert_elt].when = t; force_copy_data(ring[insert_elt].attr_value_4); // // Release attribute mutexes because the data are now copied // if (unlock == true) { for (unsigned int loop = 0;loop < attr_val->length();loop++) { Tango::AttributeValue_4 *tmp_ptr = &((*attr_val)[loop]); (tmp_ptr)->rel_attr_mutex(); } } // // Manage insert and read indexes // inc_indexes(); } void PollRing::insert_data(Tango::AttributeValueList_5 *attr_val,struct timeval &t,bool unlock) { // // Insert data in the ring // delete(ring[insert_elt].attr_value_5); delete(ring[insert_elt].except); ring[insert_elt].except = NULL; ring[insert_elt].attr_value_5 = attr_val; ring[insert_elt].when = t; force_copy_data(ring[insert_elt].attr_value_5); // // Release attribute mutexes because the data are now copied // if (unlock == true) { for (unsigned int loop = 0;loop < attr_val->length();loop++) { Tango::AttributeValue_5 *tmp_ptr = &((*attr_val)[loop]); (tmp_ptr)->rel_attr_mutex(); } } // // Manage insert and read indexes // inc_indexes(); } //------------------------------------------------------------------------- // // method : PollRing::insert_except // // description : This method insert a new element in the ring buffer // when this element is an exception // // argument : in : - ex : The exception to be stored // - t : The date // //-------------------------------------------------------------------------- void PollRing::insert_except(Tango::DevFailed *ex,struct timeval &t) { // // Insert data in the ring // delete(ring[insert_elt].except); if (ring[insert_elt].attr_value != NULL) { delete(ring[insert_elt].attr_value); ring[insert_elt].attr_value = NULL; } if (ring[insert_elt].cmd_result != NULL) { delete(ring[insert_elt].cmd_result); ring[insert_elt].cmd_result = NULL; } ring[insert_elt].except = ex; ring[insert_elt].when = t; // // Manage insert and read indexes // inc_indexes(); } //+------------------------------------------------------------------------- // // method : PollRing::inc_indexes // // description : This private method increment the indexes used to acces // the box itself. This is necessary because the box must // be managed as a circular buffer // //-------------------------------------------------------------------------- void PollRing::inc_indexes() { insert_elt++; if (insert_elt == max_elt) insert_elt = 0; if (nb_elt != max_elt) nb_elt++; } //+------------------------------------------------------------------------- // // method : PollRing::get_delta_t // // description : This method computes the delta time between records // in the ring buffer // // argument : in : - nb : The number of delta t to be computed // out : - res : A reference to the vector where result should // be stored // //-------------------------------------------------------------------------- void PollRing::get_delta_t(vector &res,long nb) { // // Throw exception if nothing in ring // if (nb_elt < 2) { Except::throw_exception((const char *)API_PollRingBufferEmpty, (const char *)"Not enough data stored yet in polling ring buffer", (const char *)"PollRing::get_delta_t"); } // // Get the buffer starting point // long read_index,prev_read; if (insert_elt == 0) { read_index = max_elt - 1; prev_read = read_index - 1; } else { read_index = insert_elt - 1; if (read_index == 0) prev_read = max_elt - 1; else prev_read = read_index - 1; } // // Clear the result vector // res.clear(); // // Compute how many delta can be computed // if (nb_elt <= nb) nb = nb_elt - 1; // // The delta t computing loop // long i; for (i = 0;i < nb;i++) { double t_ref = (double)ring[read_index].when.tv_sec + ((double)ring[read_index].when.tv_usec / 1000000); double t_prev = (double)ring[prev_read].when.tv_sec + ((double)ring[prev_read].when.tv_usec / 1000000); res.push_back(t_ref - t_prev); prev_read--; if (prev_read < 0) prev_read = max_elt - 1; read_index--; if (read_index < 0) read_index = max_elt - 1; } } //+------------------------------------------------------------------------- // // method : PollRing::get_last_insert_date // // description : This method returns the date of the last insert in the // ring buffer // //-------------------------------------------------------------------------- struct timeval PollRing::get_last_insert_date() { if (insert_elt == 0) return ring[max_elt - 1].when; else return ring[insert_elt - 1].when; } //+------------------------------------------------------------------------- // // method : PollRing::is_last_an_error // // description : This method returns a boolean set to true if the last // data recorded into the ring buffer was an exception // //-------------------------------------------------------------------------- bool PollRing::is_last_an_error() { if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) return false; else return true; } else { if (ring[insert_elt - 1].except == NULL) return false; else return true; } } bool PollRing::is_last_cmd_an_error() { if (insert_elt == 0) { if (ring[max_elt - 1].except != NULL) return true; else return false; } else { if (ring[insert_elt - 1].except != NULL) return true; else return false; } } bool PollRing::is_last_attr_an_error() { if (insert_elt == 0) { if (ring[max_elt - 1].except != NULL) return true; else { if (ring[max_elt - 1].attr_value_3 != NULL) { if ((*(ring[max_elt - 1].attr_value_3))[0].err_list.length() != 0) return true; else return false; } else if (ring[max_elt - 1].attr_value_4 != NULL) { if ((*(ring[max_elt - 1].attr_value_4))[0].err_list.length() != 0) return true; else return false; } else { if ((*(ring[max_elt - 1].attr_value_5))[0].err_list.length() != 0) return true; else return false; } } } else { if (ring[insert_elt - 1].except != NULL) return true; else { if (ring[insert_elt - 1].attr_value_3 != NULL) { if ((*(ring[insert_elt - 1].attr_value_3))[0].err_list.length() != 0) return true; else return false; } else if (ring[insert_elt - 1].attr_value_4 != NULL) { if ((*(ring[insert_elt - 1].attr_value_4))[0].err_list.length() != 0) return true; else return false; } else { if ((*(ring[insert_elt - 1].attr_value_5))[0].err_list.length() != 0) return true; else return false; } } } } //+------------------------------------------------------------------------- // // method : PollRing::get_last_except // // description : This method returns the exception recently stored in // the ring buffer. // //-------------------------------------------------------------------------- Tango::DevFailed *PollRing::get_last_except() { if (insert_elt == 0) return ring[max_elt - 1].except; else return ring[insert_elt - 1].except; } //+------------------------------------------------------------------------- // // method : PollRing::get_last_attr_error // // description : This method returns the error stack for polled // attribute belonging to device implementing IDL // release 3 and more. // //-------------------------------------------------------------------------- Tango::DevErrorList &PollRing::get_last_attr_error() { if (insert_elt == 0) { if (ring[max_elt - 1].attr_value_3 != NULL) return (*(ring[max_elt - 1].attr_value_3))[0].err_list; else if (ring[max_elt - 1].attr_value_4 != NULL) return (*(ring[max_elt - 1].attr_value_4))[0].err_list; else return (*(ring[max_elt - 1].attr_value_5))[0].err_list; } else { if (ring[insert_elt - 1].attr_value_3 != NULL) return (*(ring[insert_elt - 1].attr_value_3))[0].err_list; else if (ring[insert_elt - 1].attr_value_4 != NULL) return (*(ring[insert_elt - 1].attr_value_4))[0].err_list; else return (*(ring[insert_elt - 1].attr_value_5))[0].err_list; } } //+------------------------------------------------------------------------- // // method : PollRing::get_last_cmd_result // // description : This method returns the exception recently stored in // the ring buffer. // //-------------------------------------------------------------------------- CORBA::Any *PollRing::get_last_cmd_result() { CORBA::Any *tmp_any; if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) { tmp_any = ring[max_elt - 1].cmd_result; return new CORBA::Any(tmp_any->type(), const_cast(tmp_any->value()), false); } else throw Tango::DevFailed(*(ring[max_elt - 1].except)); } else { if (ring[insert_elt - 1].except == NULL) { tmp_any = ring[insert_elt - 1].cmd_result; return new CORBA::Any(tmp_any->type(), const_cast(tmp_any->value()), false); } else throw Tango::DevFailed(*(ring[insert_elt - 1].except)); } } //+------------------------------------------------------------------------- // // method : PollRing::get_last_attr_value // // description : This method returns the exception recently stored in // the ring buffer. // //-------------------------------------------------------------------------- Tango::AttributeValue &PollRing::get_last_attr_value() { if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) { return (*(ring[max_elt - 1].attr_value))[0]; } else throw Tango::DevFailed(*(ring[max_elt - 1].except)); } else { if (ring[insert_elt - 1].except == NULL) { return (*(ring[insert_elt - 1].attr_value))[0]; } else throw Tango::DevFailed(*(ring[insert_elt - 1].except)); } } Tango::AttributeValue_3 &PollRing::get_last_attr_value_3() { if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) { return (*(ring[max_elt - 1].attr_value_3))[0]; } else throw Tango::DevFailed(*(ring[max_elt - 1].except)); } else { if (ring[insert_elt - 1].except == NULL) { return (*(ring[insert_elt - 1].attr_value_3))[0]; } else throw Tango::DevFailed(*(ring[insert_elt - 1].except)); } } Tango::AttributeValue_4 &PollRing::get_last_attr_value_4() { if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) { return (*(ring[max_elt - 1].attr_value_4))[0]; } else throw Tango::DevFailed(*(ring[max_elt - 1].except)); } else { if (ring[insert_elt - 1].except == NULL) { return (*(ring[insert_elt - 1].attr_value_4))[0]; } else throw Tango::DevFailed(*(ring[insert_elt - 1].except)); } } Tango::AttributeValue_5 &PollRing::get_last_attr_value_5() { if (insert_elt == 0) { if (ring[max_elt - 1].except == NULL) { return (*(ring[max_elt - 1].attr_value_5))[0]; } else throw Tango::DevFailed(*(ring[max_elt - 1].except)); } else { if (ring[insert_elt - 1].except == NULL) { return (*(ring[insert_elt - 1].attr_value_5))[0]; } else throw Tango::DevFailed(*(ring[insert_elt - 1].except)); } } //------------------------------------------------------------------------- // // method : PollObj::get_cmd_history // // description : This method get command history from the ring buffer // // argument : in : - n : record number // - ptr : Pointer to the sequence where command result // should be stored // //-------------------------------------------------------------------------- void PollRing::get_cmd_history(long n,Tango::DevCmdHistoryList *ptr) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; // // Read buffer // for (i = 0;i < n;i++) { (*ptr)[seq_index].time.tv_sec = ring[index].when.tv_sec + DELTA_T; (*ptr)[seq_index].time.tv_usec = ring[index].when.tv_usec; (*ptr)[seq_index].time.tv_nsec = 0; if (ring[index].except == NULL) { (*ptr)[seq_index].cmd_failed = false; (*ptr)[seq_index].value = *(ring[index].cmd_result); (*ptr)[seq_index].errors.length(0); } else { (*ptr)[seq_index].cmd_failed = true; (*ptr)[seq_index].errors = ring[index].except->errors; } if (index == 0) index = max_elt; index--; seq_index--; } } void PollRing::get_cmd_history(long n,Tango::DevCmdHistory_4 *ptr,Tango::CmdArgType &cmd_type) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; const Tango::DevVarCharArray *tmp_uch; const Tango::DevVarShortArray *tmp_sh; const Tango::DevVarLongArray *tmp_lg; const Tango::DevVarFloatArray *tmp_fl; const Tango::DevVarDoubleArray *tmp_db; const Tango::DevVarUShortArray *tmp_ush; const Tango::DevVarULongArray *tmp_ulg; const Tango::DevVarStringArray *tmp_str; const Tango::DevVarBooleanArray *tmp_boo; const Tango::DevVarLong64Array *tmp_lg64; const Tango::DevVarULong64Array *tmp_ulg64; const Tango::DevVarLongStringArray *tmp_lg_str; const Tango::DevVarDoubleStringArray *tmp_db_str; // // Compute the size of the global sequence // We have two cases: // 1 - For simple types where each record has a constant size // 2 - For array types where each record may have different size // long seq_size = 0; long seq_str_size = 0; long seq_number_size = 0; long error_nb = 0; if ((cmd_type <= DEV_STRING) || (cmd_type == DEV_STATE) || (cmd_type == CONST_DEV_STRING) || (cmd_type == DEV_UCHAR) || (cmd_type == DEV_LONG64) || (cmd_type == DEV_ULONG64) || (cmd_type == DEV_ENCODED)) { for (i = 0;i < n;i++) { if (ring[index].except != NULL) error_nb++; if (index == 0) index = max_elt; index--; } seq_size = n - error_nb; } else { for (i = 0;i < n;i++) { if (ring[index].except == NULL) { int data_length = 0; switch(cmd_type) { case DEVVAR_CHARARRAY: (*ring[index].cmd_result) >>= tmp_uch; data_length = tmp_uch->length(); break; case DEVVAR_SHORTARRAY: (*ring[index].cmd_result) >>= tmp_sh; data_length = tmp_sh->length(); break; case DEVVAR_LONGARRAY: (*ring[index].cmd_result) >>= tmp_lg; data_length = tmp_lg->length(); break; case DEVVAR_FLOATARRAY: (*ring[index].cmd_result) >>= tmp_fl; data_length = tmp_fl->length(); break; case DEVVAR_DOUBLEARRAY: (*ring[index].cmd_result) >>= tmp_db; data_length = tmp_db->length(); break; case DEVVAR_USHORTARRAY: (*ring[index].cmd_result) >>= tmp_ush; data_length = tmp_ush->length(); break; case DEVVAR_ULONGARRAY: (*ring[index].cmd_result) >>= tmp_ulg; data_length = tmp_ulg->length(); break; case DEVVAR_STRINGARRAY: (*ring[index].cmd_result) >>= tmp_str; data_length = tmp_str->length(); break; case DEVVAR_BOOLEANARRAY: (*ring[index].cmd_result) >>= tmp_boo; data_length = tmp_boo->length(); break; case DEVVAR_LONG64ARRAY: (*ring[index].cmd_result) >>= tmp_lg64; data_length = tmp_lg64->length(); break; case DEVVAR_ULONG64ARRAY: (*ring[index].cmd_result) >>= tmp_ulg64; data_length = tmp_ulg64->length(); break; case DEVVAR_LONGSTRINGARRAY: (*ring[index].cmd_result) >>= tmp_lg_str; seq_str_size = seq_str_size + tmp_lg_str->svalue.length(); seq_number_size = seq_number_size + tmp_lg_str->lvalue.length(); break; case DEVVAR_DOUBLESTRINGARRAY: (*ring[index].cmd_result) >>= tmp_db_str; seq_str_size = seq_str_size + tmp_db_str->svalue.length(); seq_number_size = seq_number_size + tmp_db_str->dvalue.length(); break; default: break; } seq_size = seq_size + data_length; } else error_nb++; if (index == 0) index = max_elt; index--; } } // // First, copy command output data type // ptr->cmd_type = cmd_type; // // Read buffer // Tango::DevVarCharArray *new_tmp_uch = NULL; Tango::DevVarShortArray *new_tmp_sh = NULL; Tango::DevVarLongArray *new_tmp_lg = NULL; Tango::DevVarFloatArray *new_tmp_fl = NULL; Tango::DevVarDoubleArray *new_tmp_db = NULL; Tango::DevVarUShortArray *new_tmp_ush = NULL; Tango::DevVarULongArray *new_tmp_ulg = NULL; Tango::DevVarStringArray *new_tmp_str = NULL; Tango::DevVarBooleanArray *new_tmp_boo = NULL; Tango::DevVarLong64Array *new_tmp_lg64 = NULL; Tango::DevVarULong64Array *new_tmp_ulg64 = NULL; Tango::DevVarLongStringArray *new_tmp_lg_str = NULL; Tango::DevVarDoubleStringArray *new_tmp_db_str = NULL; Tango::DevVarEncodedArray *new_tmp_enc = NULL; Tango::DevShort sh; Tango::DevBoolean boo; Tango::DevLong lg; Tango::DevLong64 lg64; Tango::DevFloat fl; Tango::DevDouble db; Tango::DevUShort ush; Tango::DevULong ulg; Tango::DevULong64 ulg64; Tango::ConstDevString str; const Tango::DevEncoded *enc; DevErrorList last_err_list; int errors_length = 1; AttributeDim last_dim; int dims_length = 1; last_dim.dim_x = -1; last_dim.dim_y = -1; bool previous_no_data = true; bool no_data = true; unsigned int ind_in_seq = 0; unsigned int ind_str_in_seq = 0; unsigned int ind_num_in_seq = 0; index = insert_elt; if (index == 0) index = max_elt; index--; for (i = 0;i < n;i++) { previous_no_data = no_data; no_data = false; // // Copy dates // ptr->dates[seq_index].tv_sec = ring[index].when.tv_sec + DELTA_T; ptr->dates[seq_index].tv_usec = ring[index].when.tv_usec; ptr->dates[seq_index].tv_nsec = 0; // // Error treatement // if (ring[index].except != NULL) { bool new_err = false; if (previous_no_data == true) { if (ring[index].except->errors.length() != last_err_list.length()) new_err = true; else { for (unsigned int k = 0;k < last_err_list.length();k++) { if (::strcmp(ring[index].except->errors[k].reason.in(),last_err_list[k].reason.in()) != 0) { new_err = true; break; } if (::strcmp(ring[index].except->errors[k].desc.in(),last_err_list[k].desc.in()) != 0) { new_err = true; break; } if (::strcmp(ring[index].except->errors[k].origin.in(),last_err_list[k].origin.in()) != 0) { new_err = true; break; } if (ring[index].except->errors[k].severity != last_err_list[k].severity) { new_err = true; break; } } } } else new_err = true; if (new_err == true) { if (ptr->errors.length() == 0) ptr->errors.length(error_nb); if (ptr->errors_array.length() == 0) ptr->errors_array.length(error_nb); last_err_list = ring[index].except->errors; ptr->errors[errors_length - 1] = last_err_list; ptr->errors_array[errors_length - 1].start = n - (i + 1); ptr->errors_array[errors_length - 1].nb_elt = 1; errors_length++; previous_no_data = no_data; no_data = true; } else { ptr->errors_array[errors_length - 2].nb_elt++; previous_no_data = no_data; no_data = true; } if ((last_dim.dim_x == 0) && (last_dim.dim_y == 0)) { ptr->dims_array[dims_length - 2].nb_elt++; } else { last_dim.dim_x = last_dim.dim_y = 0; ptr->dims.length(dims_length); ptr->dims[dims_length - 1] = last_dim; ptr->dims_array.length(dims_length); ptr->dims_array[dims_length - 1].start = n - (i + 1); ptr->dims_array[dims_length - 1].nb_elt = 1; dims_length++; } } // // The data // if (ring[index].except == NULL) { switch(cmd_type) { case DEVVAR_CHARARRAY: if (new_tmp_uch == NULL) { new_tmp_uch = new DevVarCharArray(); new_tmp_uch->length(seq_size); } (*ring[index].cmd_result) >>= tmp_uch; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_uch,tmp_uch,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_uch->length()); break; case DEV_SHORT: if (new_tmp_sh == NULL) { new_tmp_sh = new DevVarShortArray(); new_tmp_sh->length(seq_size); } (*ring[index].cmd_result) >>= sh; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_sh,sh,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_SHORTARRAY: if (new_tmp_sh == NULL) { new_tmp_sh = new DevVarShortArray(); new_tmp_sh->length(seq_size); } (*ring[index].cmd_result) >>= tmp_sh; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_sh,tmp_sh,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_sh->length()); break; case DEV_LONG: if (new_tmp_lg == NULL) { new_tmp_lg = new DevVarLongArray(); new_tmp_lg->length(seq_size); } (*ring[index].cmd_result) >>= lg; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_lg,lg,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_LONGARRAY: if (new_tmp_lg == NULL) { new_tmp_lg = new DevVarLongArray(); new_tmp_lg->length(seq_size); } (*ring[index].cmd_result) >>= tmp_lg; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_lg,tmp_lg,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_lg->length()); break; case DEV_FLOAT: if (new_tmp_fl == NULL) { new_tmp_fl = new DevVarFloatArray(); new_tmp_fl->length(seq_size); } (*ring[index].cmd_result) >>= fl; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_fl,fl,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_FLOATARRAY: if (new_tmp_fl == NULL) { new_tmp_fl = new DevVarFloatArray(); new_tmp_fl->length(seq_size); } (*ring[index].cmd_result) >>= tmp_fl; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_fl,tmp_fl,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_fl->length()); break; case DEV_DOUBLE: if (new_tmp_db == NULL) { new_tmp_db = new DevVarDoubleArray(); new_tmp_db->length(seq_size); } (*ring[index].cmd_result) >>= db; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_db,db,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_DOUBLEARRAY: if (new_tmp_db == NULL) { new_tmp_db = new DevVarDoubleArray(); new_tmp_db->length(seq_size); } (*ring[index].cmd_result) >>= tmp_db; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_db,tmp_db,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_db->length()); break; case DEV_USHORT: if (new_tmp_ush == NULL) { new_tmp_ush = new DevVarUShortArray(); new_tmp_ush->length(seq_size); } (*ring[index].cmd_result) >>= ush; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_ush,ush,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_USHORTARRAY: if (new_tmp_ush == NULL) { new_tmp_ush = new DevVarUShortArray(); new_tmp_ush->length(seq_size); } (*ring[index].cmd_result) >>= tmp_ush; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_ush,tmp_ush,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_ush->length()); break; case DEV_ULONG: if (new_tmp_ulg == NULL) { new_tmp_ulg = new DevVarULongArray(); new_tmp_ulg->length(seq_size); } (*ring[index].cmd_result) >>= ulg; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_ulg,ulg,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_ULONGARRAY: if (new_tmp_ulg == NULL) { new_tmp_ulg = new DevVarULongArray(); new_tmp_ulg->length(seq_size); } (*ring[index].cmd_result) >>= tmp_ulg; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_ulg,tmp_ulg,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_ulg->length()); break; case DEV_STRING: if (new_tmp_str == NULL) { new_tmp_str = new DevVarStringArray(); new_tmp_str->length(seq_size); } (*ring[index].cmd_result) >>= str; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_str,str,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_STRINGARRAY: if (new_tmp_str == NULL) { new_tmp_str = new DevVarStringArray(); new_tmp_str->length(seq_size); } (*ring[index].cmd_result) >>= tmp_str; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_str,tmp_str,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_str->length()); break; case DEV_BOOLEAN: if (new_tmp_boo == NULL) { new_tmp_boo = new DevVarBooleanArray(); new_tmp_boo->length(seq_size); } (*ring[index].cmd_result) >>= boo; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_boo,boo,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_BOOLEANARRAY: if (new_tmp_boo == NULL) { new_tmp_boo = new DevVarBooleanArray(); new_tmp_boo->length(seq_size); } (*ring[index].cmd_result) >>= tmp_boo; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_boo,tmp_boo,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_boo->length()); break; case DEV_LONG64: if (new_tmp_lg64 == NULL) { new_tmp_lg64 = new DevVarLong64Array(); new_tmp_lg64->length(seq_size); } (*ring[index].cmd_result) >>= lg64; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_lg64,lg64,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_LONG64ARRAY: if (new_tmp_lg64 == NULL) { new_tmp_lg64 = new DevVarLong64Array(); new_tmp_lg64->length(seq_size); } (*ring[index].cmd_result) >>= tmp_lg64; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_lg64,tmp_lg64,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_lg64->length()); break; case DEV_ULONG64: if (new_tmp_ulg64 == NULL) { new_tmp_ulg64 = new DevVarULong64Array(); new_tmp_ulg64->length(seq_size); } (*ring[index].cmd_result) >>= ulg64; ADD_SIMPLE_DATA_TO_GLOBAL_SEQ(new_tmp_ulg64,ulg64,ind_in_seq); MANAGE_DIM_SIMPLE(); break; case DEVVAR_ULONG64ARRAY: if (new_tmp_ulg64 == NULL) { new_tmp_ulg64 = new DevVarULong64Array(); new_tmp_ulg64->length(seq_size); } (*ring[index].cmd_result) >>= tmp_ulg64; ADD_ELT_DATA_TO_GLOBAL_SEQ(new_tmp_ulg64,tmp_ulg64,ind_in_seq); MANAGE_DIM_ARRAY((long)tmp_ulg64->length()); break; case DEVVAR_LONGSTRINGARRAY: if (new_tmp_lg_str == NULL) { new_tmp_lg_str = new DevVarLongStringArray(); new_tmp_lg_str->svalue.length(seq_str_size); new_tmp_lg_str->lvalue.length(seq_number_size); } (*ring[index].cmd_result) >>= tmp_lg_str; ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_REF(new_tmp_lg_str->svalue,tmp_lg_str->svalue,ind_str_in_seq); ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_REF(new_tmp_lg_str->lvalue,tmp_lg_str->lvalue,ind_num_in_seq); MANAGE_DIM_ARRAY_SEQ((long)tmp_lg_str->svalue.length(),(long)tmp_lg_str->lvalue.length()); break; case DEVVAR_DOUBLESTRINGARRAY: if (new_tmp_db_str == NULL) { new_tmp_db_str = new DevVarDoubleStringArray(); new_tmp_db_str->svalue.length(seq_str_size); new_tmp_db_str->dvalue.length(seq_number_size); } (*ring[index].cmd_result) >>= tmp_db_str; ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_REF(new_tmp_db_str->svalue,tmp_db_str->svalue,ind_str_in_seq); ADD_ELT_DATA_TO_GLOBAL_SEQ_BY_REF(new_tmp_db_str->dvalue,tmp_db_str->dvalue,ind_num_in_seq); MANAGE_DIM_ARRAY_SEQ((long)tmp_db_str->svalue.length(),(long)tmp_db_str->dvalue.length()); break; case DEV_ENCODED: if (new_tmp_enc == NULL) { new_tmp_enc = new DevVarEncodedArray(); new_tmp_enc->length(seq_size); } (*ring[index].cmd_result) >>= enc; { unsigned int buffer_data_length = enc->encoded_data.length(); Tango::DevVarCharArray &tmp_buffer = (*new_tmp_enc)[ind_in_seq].encoded_data; tmp_buffer.length(buffer_data_length); for (unsigned int k = 0;k < buffer_data_length;k++) tmp_buffer[k] = enc->encoded_data[k]; (*new_tmp_enc)[ind_in_seq].encoded_format = CORBA::string_dup(enc->encoded_format); ind_in_seq = ind_in_seq + 1; } MANAGE_DIM_SIMPLE(); break; default: break; } } // // If it is the last point, insert the global sequence into the Any // if (i == (n - 1)) { if (errors_length != (error_nb + 1)) { ptr->errors.length(errors_length - 1); ptr->errors_array.length(errors_length - 1); } switch(cmd_type) { case Tango::DEVVAR_CHARARRAY: if (new_tmp_uch != NULL) ptr->value <<= new_tmp_uch; break; case Tango::DEVVAR_SHORTARRAY: case Tango::DEV_SHORT: if (new_tmp_sh != NULL) ptr->value <<= new_tmp_sh; break; case Tango::DEVVAR_LONGARRAY: case Tango::DEV_LONG: if (new_tmp_lg != NULL) ptr->value <<= new_tmp_lg; break; case Tango::DEVVAR_FLOATARRAY: case Tango::DEV_FLOAT: if (new_tmp_fl != NULL) ptr->value <<= new_tmp_fl; break; case Tango::DEVVAR_DOUBLEARRAY: case Tango::DEV_DOUBLE: if (new_tmp_db != NULL) ptr->value <<= new_tmp_db; break; case Tango::DEVVAR_USHORTARRAY: case Tango::DEV_USHORT: if (new_tmp_db != NULL) ptr->value <<= new_tmp_db; break; case Tango::DEVVAR_ULONGARRAY: case Tango::DEV_ULONG: if (new_tmp_db != NULL) ptr->value <<= new_tmp_db; break; case Tango::DEVVAR_STRINGARRAY: case Tango::DEV_STRING: if (new_tmp_str != NULL) ptr->value <<= new_tmp_str; break; case Tango::DEVVAR_BOOLEANARRAY: case Tango::DEV_BOOLEAN: if (new_tmp_boo != NULL) ptr->value <<= new_tmp_boo; break; case Tango::DEVVAR_LONG64ARRAY: case Tango::DEV_LONG64: if (new_tmp_lg64 != NULL) ptr->value <<= new_tmp_lg64; break; case Tango::DEVVAR_ULONG64ARRAY: case Tango::DEV_ULONG64: if (new_tmp_ulg64 != NULL) ptr->value <<= new_tmp_ulg64; break; case Tango::DEVVAR_LONGSTRINGARRAY: if (new_tmp_lg_str != NULL) ptr->value <<= new_tmp_lg_str; break; case Tango::DEVVAR_DOUBLESTRINGARRAY: if (new_tmp_db_str != NULL) ptr->value <<= new_tmp_db_str; break; case Tango::DEV_ENCODED: if (new_tmp_enc != NULL) ptr->value <<= new_tmp_enc; break; default: break; } } // // Manage index in buffer // if (index == 0) index = max_elt; index--; seq_index--; } } //------------------------------------------------------------------------- // // method : PollObj::get_attr_history // // description : This method get attribute history from the ring buffer // // argument : in : - n : record number // - ptr : Pointer to the sequence where attribute result // should be stored // - type : The attribute data type // //-------------------------------------------------------------------------- void PollRing::get_attr_history(long n,Tango::DevAttrHistoryList *ptr,long type) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; // // Read buffer // for (i = 0;i < n;i++) { (*ptr)[seq_index].value.time.tv_sec = ring[index].when.tv_sec + DELTA_T; (*ptr)[seq_index].value.time.tv_usec = ring[index].when.tv_usec; (*ptr)[seq_index].value.time.tv_nsec = 0; if (ring[index].except == NULL) { (*ptr)[seq_index].attr_failed = false; (*ptr)[seq_index].value.quality = (*ring[index].attr_value)[0].quality; (*ptr)[seq_index].value.dim_x = (*ring[index].attr_value)[0].dim_x; (*ptr)[seq_index].value.dim_y = (*ring[index].attr_value)[0].dim_y; (*ptr)[seq_index].value.name = CORBA::string_dup((*ring[index].attr_value)[0].name); if ((*ptr)[seq_index].value.quality != Tango::ATTR_INVALID) { const Tango::DevVarDoubleArray *tmp_db; Tango::DevVarDoubleArray *new_tmp_db; const Tango::DevVarShortArray *tmp_sh; Tango::DevVarShortArray *new_tmp_sh; const Tango::DevVarLongArray *tmp_lg; Tango::DevVarLongArray *new_tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; Tango::DevVarLong64Array *new_tmp_lg64; const Tango::DevVarStringArray *tmp_str; Tango::DevVarStringArray *new_tmp_str; const Tango::DevVarFloatArray *tmp_fl; Tango::DevVarFloatArray *new_tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; Tango::DevVarBooleanArray *new_tmp_boo; const Tango::DevVarUShortArray *tmp_ush; Tango::DevVarUShortArray *new_tmp_ush; const Tango::DevVarCharArray *tmp_uch; Tango::DevVarCharArray *new_tmp_uch; const Tango::DevVarULongArray *tmp_ulg; Tango::DevVarULongArray *new_tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; Tango::DevVarULong64Array *new_tmp_ulg64; const Tango::DevVarStateArray *tmp_state; Tango::DevVarStateArray *new_tmp_state; switch (type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : (*ring[index].attr_value)[0].value >>= tmp_sh; new_tmp_sh = new DevVarShortArray( tmp_sh->length(), tmp_sh->length(), const_cast(tmp_sh->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_sh; break; case Tango::DEV_DOUBLE : (*ring[index].attr_value)[0].value >>= tmp_db; new_tmp_db = new DevVarDoubleArray( tmp_db->length(), tmp_db->length(), const_cast(tmp_db->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_db; break; case Tango::DEV_LONG : (*ring[index].attr_value)[0].value >>= tmp_lg; new_tmp_lg = new DevVarLongArray(tmp_lg->length(),tmp_lg->length(), const_cast(tmp_lg->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_lg; break; case Tango::DEV_LONG64 : (*ring[index].attr_value)[0].value >>= tmp_lg64; new_tmp_lg64 = new DevVarLong64Array(tmp_lg64->length(),tmp_lg64->length(), const_cast(tmp_lg64->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_lg64; break; case Tango::DEV_STRING : (*ring[index].attr_value)[0].value >>= tmp_str; new_tmp_str = new DevVarStringArray( tmp_str->length(), tmp_str->length(), const_cast(tmp_str->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_str; break; case Tango::DEV_FLOAT : (*ring[index].attr_value)[0].value >>= tmp_fl; new_tmp_fl = new DevVarFloatArray( tmp_fl->length(), tmp_fl->length(), const_cast(tmp_fl->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_fl; break; case Tango::DEV_BOOLEAN : (*ring[index].attr_value)[0].value >>= tmp_boo; new_tmp_boo = new DevVarBooleanArray( tmp_boo->length(), tmp_boo->length(), const_cast(tmp_boo->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_boo; break; case Tango::DEV_USHORT : (*ring[index].attr_value)[0].value >>= tmp_ush; new_tmp_ush = new DevVarUShortArray( tmp_ush->length(), tmp_ush->length(), const_cast(tmp_ush->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_ush; break; case Tango::DEV_UCHAR : (*ring[index].attr_value)[0].value >>= tmp_uch; new_tmp_uch = new DevVarCharArray( tmp_uch->length(), tmp_uch->length(), const_cast(tmp_uch->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_uch; break; case Tango::DEV_ULONG : (*ring[index].attr_value)[0].value >>= tmp_ulg; new_tmp_ulg = new DevVarULongArray(tmp_ulg->length(),tmp_ulg->length(), const_cast(tmp_ulg->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_ulg; break; case Tango::DEV_ULONG64 : (*ring[index].attr_value)[0].value >>= tmp_ulg64; new_tmp_ulg64 = new DevVarULong64Array(tmp_ulg64->length(),tmp_ulg64->length(), const_cast(tmp_ulg64->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_ulg64; break; case Tango::DEV_STATE : (*ring[index].attr_value)[0].value >>= tmp_state; new_tmp_state = new DevVarStateArray(tmp_state->length(),tmp_state->length(), const_cast(tmp_state->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_state; break; } } (*ptr)[seq_index].errors.length(0); } else { (*ptr)[seq_index].attr_failed = true; (*ptr)[seq_index].errors = ring[index].except->errors; (*ptr)[seq_index].value.quality = Tango::ATTR_INVALID; (*ptr)[seq_index].value.dim_x = 0; (*ptr)[seq_index].value.dim_y = 0; } if (index == 0) index = max_elt; index--; seq_index--; } } void PollRing::get_attr_history(long n,Tango::DevAttrHistoryList_3 *ptr,long type) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; // // Read buffer // for (i = 0;i < n;i++) { (*ptr)[seq_index].value.time.tv_sec = ring[index].when.tv_sec + DELTA_T; (*ptr)[seq_index].value.time.tv_usec = ring[index].when.tv_usec; (*ptr)[seq_index].value.time.tv_nsec = 0; if (ring[index].except == NULL) { (*ptr)[seq_index].value.err_list = (*ring[index].attr_value_3)[0].err_list; (*ptr)[seq_index].value.quality = (*ring[index].attr_value_3)[0].quality; (*ptr)[seq_index].value.r_dim = (*ring[index].attr_value_3)[0].r_dim; (*ptr)[seq_index].value.w_dim = (*ring[index].attr_value_3)[0].w_dim; (*ptr)[seq_index].value.name = CORBA::string_dup((*ring[index].attr_value_3)[0].name); (*ptr)[seq_index].attr_failed = false; if ((*ptr)[seq_index].value.quality != Tango::ATTR_INVALID) { const Tango::DevVarDoubleArray *tmp_db; Tango::DevVarDoubleArray *new_tmp_db; const Tango::DevVarShortArray *tmp_sh; Tango::DevVarShortArray *new_tmp_sh; const Tango::DevVarLongArray *tmp_lg; Tango::DevVarLongArray *new_tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; Tango::DevVarLong64Array *new_tmp_lg64; const Tango::DevVarStringArray *tmp_str; Tango::DevVarStringArray *new_tmp_str; const Tango::DevVarFloatArray *tmp_fl; Tango::DevVarFloatArray *new_tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; Tango::DevVarBooleanArray *new_tmp_boo; const Tango::DevVarUShortArray *tmp_ush; Tango::DevVarUShortArray *new_tmp_ush; const Tango::DevVarCharArray *tmp_uch; Tango::DevVarCharArray *new_tmp_uch; const Tango::DevVarULongArray *tmp_ulg; Tango::DevVarULongArray *new_tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; Tango::DevVarULong64Array *new_tmp_ulg64; const Tango::DevVarStateArray *tmp_state; Tango::DevVarStateArray *new_tmp_state; switch (type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : (*ring[index].attr_value_3)[0].value >>= tmp_sh; new_tmp_sh = new DevVarShortArray( tmp_sh->length(), tmp_sh->length(), const_cast(tmp_sh->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_sh; break; case Tango::DEV_DOUBLE : (*ring[index].attr_value_3)[0].value >>= tmp_db; new_tmp_db = new DevVarDoubleArray( tmp_db->length(), tmp_db->length(), const_cast(tmp_db->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_db; break; case Tango::DEV_LONG : (*ring[index].attr_value_3)[0].value >>= tmp_lg; new_tmp_lg = new DevVarLongArray(tmp_lg->length(),tmp_lg->length(), const_cast(tmp_lg->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_lg; break; case Tango::DEV_LONG64 : (*ring[index].attr_value_3)[0].value >>= tmp_lg64; new_tmp_lg64 = new DevVarLong64Array(tmp_lg64->length(),tmp_lg64->length(), const_cast(tmp_lg64->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_lg64; break; case Tango::DEV_STRING : (*ring[index].attr_value_3)[0].value >>= tmp_str; new_tmp_str = new DevVarStringArray( tmp_str->length(), tmp_str->length(), const_cast(tmp_str->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_str; break; case Tango::DEV_FLOAT : (*ring[index].attr_value_3)[0].value >>= tmp_fl; new_tmp_fl = new DevVarFloatArray( tmp_fl->length(), tmp_fl->length(), const_cast(tmp_fl->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_fl; break; case Tango::DEV_BOOLEAN : (*ring[index].attr_value_3)[0].value >>= tmp_boo; new_tmp_boo = new DevVarBooleanArray( tmp_boo->length(), tmp_boo->length(), const_cast(tmp_boo->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_boo; break; case Tango::DEV_USHORT : (*ring[index].attr_value_3)[0].value >>= tmp_ush; new_tmp_ush = new DevVarUShortArray( tmp_ush->length(), tmp_ush->length(), const_cast(tmp_ush->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_ush; break; case Tango::DEV_UCHAR : (*ring[index].attr_value_3)[0].value >>= tmp_uch; new_tmp_uch = new DevVarCharArray( tmp_uch->length(), tmp_uch->length(), const_cast(tmp_uch->get_buffer()), false); (*ptr)[seq_index].value.value <<= new_tmp_uch; break; case Tango::DEV_ULONG : (*ring[index].attr_value_3)[0].value >>= tmp_ulg; new_tmp_ulg = new DevVarULongArray(tmp_ulg->length(),tmp_ulg->length(), const_cast(tmp_ulg->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_ulg; break; case Tango::DEV_ULONG64 : (*ring[index].attr_value_3)[0].value >>= tmp_ulg64; new_tmp_ulg64 = new DevVarULong64Array(tmp_ulg64->length(),tmp_ulg64->length(), const_cast(tmp_ulg64->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_ulg64; break; case Tango::DEV_STATE : { CORBA::TypeCode_var ty; ty = (*ring[index].attr_value_3)[0].value.type(); if (ty->kind() == CORBA::tk_enum) { Tango::DevState tmp_ds; (*ring[index].attr_value_3)[0].value >>= tmp_ds; (*ptr)[seq_index].value.value <<= tmp_ds; } else { (*ring[index].attr_value_3)[0].value >>= tmp_state; new_tmp_state = new DevVarStateArray(tmp_state->length(),tmp_state->length(), const_cast(tmp_state->get_buffer()),false); (*ptr)[seq_index].value.value <<= new_tmp_state; } break; } } } } else { (*ptr)[seq_index].attr_failed = true; (*ptr)[seq_index].value.err_list = ring[index].except->errors; (*ptr)[seq_index].value.quality = Tango::ATTR_INVALID; clear_att_dim((*ptr)[seq_index].value); } if (index == 0) index = max_elt; index--; seq_index--; } } void PollRing::get_attr_history_43(long n,Tango::DevAttrHistoryList_3 *ptr,long type) { long i; // // Set index to read ring and to initialised returned sequence // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = n - 1; // // Read buffer // for (i = 0;i < n;i++) { (*ptr)[seq_index].value.time.tv_sec = ring[index].when.tv_sec + DELTA_T; (*ptr)[seq_index].value.time.tv_usec = ring[index].when.tv_usec; (*ptr)[seq_index].value.time.tv_nsec = 0; if (ring[index].except == NULL) { (*ptr)[seq_index].value.err_list = (*ring[index].attr_value_4)[0].err_list; (*ptr)[seq_index].value.quality = (*ring[index].attr_value_4)[0].quality; (*ptr)[seq_index].value.r_dim = (*ring[index].attr_value_4)[0].r_dim; (*ptr)[seq_index].value.w_dim = (*ring[index].attr_value_4)[0].w_dim; (*ptr)[seq_index].value.name = CORBA::string_dup((*ring[index].attr_value_4)[0].name); (*ptr)[seq_index].attr_failed = false; if ((*ptr)[seq_index].value.quality != Tango::ATTR_INVALID) { switch (type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { const DevVarShortArray &tmp_seq = (*ring[index].attr_value_4)[0].value.short_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_DOUBLE : { const DevVarDoubleArray &tmp_seq = (*ring[index].attr_value_4)[0].value.double_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_LONG : { const DevVarLongArray &tmp_seq = (*ring[index].attr_value_4)[0].value.long_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_LONG64 : { const DevVarLong64Array &tmp_seq = (*ring[index].attr_value_4)[0].value.long64_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_STRING : { const DevVarStringArray &tmp_seq = (*ring[index].attr_value_4)[0].value.string_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_FLOAT : { const DevVarFloatArray &tmp_seq = (*ring[index].attr_value_4)[0].value.float_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_BOOLEAN : { const DevVarBooleanArray &tmp_seq = (*ring[index].attr_value_4)[0].value.bool_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_USHORT : { const DevVarUShortArray &tmp_seq = (*ring[index].attr_value_4)[0].value.ushort_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_UCHAR : { const DevVarCharArray &tmp_seq = (*ring[index].attr_value_4)[0].value.uchar_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_ULONG : { const DevVarULongArray &tmp_seq = (*ring[index].attr_value_4)[0].value.ulong_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_ULONG64 : { const DevVarULong64Array &tmp_seq = (*ring[index].attr_value_4)[0].value.ulong64_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } break; case Tango::DEV_STATE : { if ((*ring[index].attr_value_4)[0].value._d() == DEVICE_STATE) { DevState tmp_ds = (*ring[index].attr_value_4)[0].value.dev_state_att(); (*ptr)[seq_index].value.value <<= tmp_ds; } else { DevVarStateArray &tmp_seq = (*ring[index].attr_value_4)[0].value.state_att_value(); (*ptr)[seq_index].value.value <<= tmp_seq; } } break; } } } else { (*ptr)[seq_index].attr_failed = true; (*ptr)[seq_index].value.err_list = ring[index].except->errors; (*ptr)[seq_index].value.quality = Tango::ATTR_INVALID; clear_att_dim((*ptr)[seq_index].value); } if (index == 0) index = max_elt; index--; seq_index--; } } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/pollthread.cpp0000644023471100065110000017575013034745001015442 00000000000000static const char *RcsId = "$Id: pollthread.cpp 29812 2016-06-09 12:23:37Z taurel $\n$Name$"; //+================================================================================================================= // // file : PollThread.cpp // // description : C++ source code for the PollThread class. This class is used for the polling thread. The rule // of this thread is to regulary exceute command on device or read attribute and store result // in a ring buffer. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29812 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifdef _TG_WINDOWS_ #include #else #include #endif #include extern omni_thread::key_t key_py_data; namespace Tango { DeviceImpl *PollThread::dev_to_del = NULL; string PollThread::name_to_del = ""; PollObjType PollThread::type_to_del = Tango::POLL_CMD; //+----------------------------------------------------------------------------------------------------------------- // // method : // PollThread::Pollthread // // description : // The polling thread constructor. // // args : // in : // - cmd : The buffer used to pass command to the polling thread // - m : The mutex used to protect the previous buffer // - heartbeat : Flag set to true if this polling thread is the thread used to send the heartbeat event // //------------------------------------------------------------------------------------------------------------------ PollThread::PollThread(PollThCmd &cmd,TangoMonitor &m,bool heartbeat): shared_cmd(cmd),p_mon(m), sleep(1),polling_stop(true), attr_names(1),tune_ctr(1), need_two_tuning(false),send_heartbeat(heartbeat),heartbeat_ctr(0) { local_cmd.cmd_pending = false; attr_names.length(1); cci = 0; dummy_cl_id.cpp_clnt(cci); previous_nb_late = 0; polling_bef_9 = false; if (heartbeat == true) polling_stop = false; #ifdef _TG_WINDOWS_ LARGE_INTEGER f; BOOL is_ctr; is_ctr = QueryPerformanceFrequency(&f); if (is_ctr != 0) ctr_frequency = 1000000.0 / (double)f.QuadPart; else ctr_frequency = 0.0; #endif dummy_att5.value.union_no_data(true); dummy_att5.quality = ATTR_INVALID; dummy_att4.value.union_no_data(true); dummy_att4.quality = ATTR_INVALID; dummy_att3.quality = ATTR_INVALID; } //+------------------------------------------------------------------------------------------------------------------ // // method : // PollThread::run_undetached // // description : // The polling thread main code // //------------------------------------------------------------------------------------------------------------------- void *PollThread::run_undetached(TANGO_UNUSED(void *ptr)) { PollCmdType received; bool per_thread_data_created = false; // // If the thread is the event heartbeat thread, use it also for the storage of sub device properties. // Declare a work item to check the for new sub devices regularly. // if (send_heartbeat == true) { WorkItem wo; wo.dev = NULL; wo.poll_list = NULL; wo.type = STORE_SUBDEV; wo.update = 30*60*1000; // check ervery 30 minutes wo.name.push_back(string("Sub device property storage")); wo.needed_time.tv_sec = 0; wo.needed_time.tv_usec = 0; #ifdef _TG_WINDOWS_ _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; wo.wake_up_date = now; insert_in_list(wo); } // // The infinite loop // while(1) { try { if (sleep != 0) received = get_command(sleep); else received = POLL_TIME_OUT; // // Create the per thread data if it is not already done (For Python DS) // if (per_thread_data_created == false) { omni_thread::self()->set_value(key_py_data,new PyData()); per_thread_data_created = true; } #ifdef _TG_WINDOWS_ _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif now.tv_sec = now.tv_sec - DELTA_T; switch (received) { case POLL_COMMAND: execute_cmd(); break; case POLL_TIME_OUT: one_more_poll(); break; case POLL_TRIGGER: one_more_trigg(); break; } #ifdef _TG_WINDOWS_ _ftime(&after_win); after.tv_sec = (unsigned long)after_win.time; after.tv_usec = (long)after_win.millitm * 1000; #else gettimeofday(&after,NULL); #endif after.tv_sec = after.tv_sec - DELTA_T; if (tune_ctr <= 0) { tune_list(true,0); if (need_two_tuning == true) { unsigned long nb_works = works.size(); tune_ctr = (nb_works << 2); need_two_tuning = false; } else tune_ctr = POLL_LOOP_NB; } compute_sleep_time(); } catch (omni_thread_fatal &) { cerr << "OUPS !! A omni thread fatal exception received by a polling thread !!!!!!!!" << endl; #ifndef _TG_WINDOWS_ time_t t = time(NULL); cerr << ctime(&t); #endif cerr << "Trying to re-enter the main loop" << endl; } catch (const std::exception &ex) { cerr << "OUPS !! An unforeseen standard exception has been received by a polling thread !!!!!!" << endl; cerr << ex.what() << endl; #ifndef _TG_WINDOWS_ time_t t = time(NULL); cerr << ctime(&t); #endif cerr << "Trying to re-enter the main loop" << endl; } } return NULL; } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::get_command // // description : // This method wait on the shared monitor for a new command to be sent to the polling thread. The thread waits // with a timeout. If the thread is awaken due to the timeout, false is returned. // If the work list is empty, the thread waits for ever. // // args : // in : // - tout : Timeout to be used when waiting on monitor // // returns : // The method returns true if the thread has been awaken due to a new command sent by the main thread // //------------------------------------------------------------------------------------------------------------------ PollCmdType PollThread::get_command(long tout) { omni_mutex_lock sync(p_mon); PollCmdType ret; // // Wait on monitor // if ((shared_cmd.cmd_pending == false) && (shared_cmd.trigger == false)) { if (works.empty() == true) p_mon.wait(); else { if (tout != -1) p_mon.wait(tout); } } // // Test if it is a new command. If yes, copy its data locally // if (shared_cmd.cmd_pending == true) { local_cmd = shared_cmd; ret = POLL_COMMAND; } else if (shared_cmd.trigger == true) { local_cmd = shared_cmd; ret = POLL_TRIGGER; } else ret = POLL_TIME_OUT; return ret; } //+--------------------------------------------------------------------------------------------------------------- // // method : // PollThread::execute_cmd and two unary predicates // // description : // This method is called when a command has been received. It execute the command! // // args : // in : // - w : The work item // //------------------------------------------------------------------------------------------------------------------ bool pred_dev(const WorkItem &w) { return w.dev == PollThread::dev_to_del; } void PollThread::execute_cmd() { WorkItem wo; list::iterator ite; vector::iterator et_ite; switch (local_cmd.cmd_code) { // // Add a new object // case Tango::POLL_ADD_OBJ : { cout5 << "Received a Add object command" << endl; wo.dev = local_cmd.dev; wo.poll_list = &(wo.dev->get_poll_obj_list()); int new_upd = (*wo.poll_list)[local_cmd.index]->get_upd(); PollObjType new_type = (*wo.poll_list)[local_cmd.index]->get_type(); bool found = false; if (new_type == POLL_ATTR && wo.dev->get_dev_idl_version() >= 4 && polling_bef_9 == false) { #ifdef HAS_LAMBDA_FUNC ite = find_if(works.begin(),works.end(), [&] (const WorkItem &wi) {return wi.dev == local_cmd.dev && wi.update == new_upd && wi.type == new_type;}); #else for (ite = works.begin();ite != works.end();++ite) { if (ite->dev == local_cmd.dev && ite->update == new_upd && ite->type == new_type) break; } #endif if (ite != works.end()) { ite->name.push_back((*wo.poll_list)[local_cmd.index]->get_name()); found = true; } } if (found == false) { wo.type = new_type; wo.update = new_upd; wo.name.push_back((*wo.poll_list)[local_cmd.index]->get_name()); wo.needed_time.tv_sec = 0; wo.needed_time.tv_usec = 0; if (wo.update != 0) { wo.wake_up_date = now; if (local_cmd.new_upd != 0) { cout5 << "Received a delta from now of " << local_cmd.new_upd << endl; T_ADD(wo.wake_up_date,local_cmd.new_upd * 1000); } insert_in_list(wo); unsigned long nb_works = works.size(); tune_ctr = (nb_works << 2); need_two_tuning = true; } else { wo.wake_up_date.tv_sec = 0; wo.wake_up_date.tv_usec = 0; ext_trig_works.push_back(wo); } } break; } // // Remove an already polled object // case Tango::POLL_REM_OBJ : cout5 << "Received a Rem object command" << endl; dev_to_del = local_cmd.dev; name_to_del = local_cmd.name; type_to_del = local_cmd.type; size_t i,nb_elt; nb_elt = works.size(); ite = works.begin(); for (i = 0;i < nb_elt;i++) { if (ite->dev == PollThread::dev_to_del) { if (ite->type == PollThread::type_to_del) { vector::iterator ite_str; bool found = false; for (ite_str = ite->name.begin();ite_str != ite->name.end();++ite_str) { if (*ite_str == PollThread::name_to_del) { ite->name.erase(ite_str); if (ite->name.empty() == true) works.erase(ite); found = true; break; } } if (found == true) break; } } ++ite; } break; // // Remove an already externally triggered polled object // case Tango::POLL_REM_EXT_TRIG_OBJ : cout5 << "Received a Ext Trig Rem object command" << endl; for (et_ite = ext_trig_works.begin(); et_ite != ext_trig_works.end();++et_ite) { if (et_ite->dev == local_cmd.dev) { if (et_ite->type == local_cmd.type) { if (et_ite->name[0] == local_cmd.name) { ext_trig_works.erase(et_ite); break; } } } } break; // // Remove all objects belonging to a device. // Take care, the same device could have several objects --> No break after the successfull if in loop // case Tango::POLL_REM_DEV : cout5 << "Received a Rem device command" << endl; dev_to_del = local_cmd.dev; #ifdef _TG_WINDOWS_ nb_elt = works.size(); ite = works.begin(); for (i = 0;i < nb_elt;i++) { if (ite->dev == PollThread::dev_to_del) { ite = works.erase(ite); } else ++ite; } nb_elt = ext_trig_works.size(); et_ite = ext_trig_works.begin(); for (i = 0;i < nb_elt;i++) { if (et_ite->dev == PollThread::dev_to_del) { et_ite = ext_trig_works.erase(et_ite); } else ++et_ite; } #else works.remove_if(pred_dev); ext_trig_works.erase(remove_if(ext_trig_works.begin(), ext_trig_works.end(), pred_dev), ext_trig_works.end()); #endif break; // // Update polling period // Several cases has to be implemented here. // 1 - A classical command from the external world. In this case updating // polling period means removing the already inserted object from the work list, // compute its new polling time and insert it in the work list with its new // polling time and polling period // 2 - This is executed by the polling thread itself // 2-1 - The command updates polling period for another object: idem than previous // 2-2 - The commands updates polling period for the object it is actually polled. // In this case, the object is not in the work list. It has been removed from the // work list at the beginning of the "one_more_poll" method and is memorized there // Therefore, simply stores new polling period in a data member. The "one_more_poll" // method will get its new polling period before re-inserting the object in the work // list with the new update period. // We detect this case because the object is not in any work list (either the work // list or the trigger list) // case Tango::POLL_UPD_PERIOD : { cout5 << "Received a update polling period command" << endl; dev_to_del = local_cmd.dev; name_to_del = local_cmd.name; type_to_del = local_cmd.type; bool found_in_work_list = false; if (local_cmd.new_upd != 0) { WorkItem tmp_work; size_t i,nb_elt; nb_elt = works.size(); ite = works.begin(); if (nb_elt != 0) { bool found = false; for (i = 0;i < nb_elt;i++) { if (ite->dev == PollThread::dev_to_del) { if (ite->type == PollThread::type_to_del) { vector::iterator ite_str; for (ite_str = ite->name.begin();ite_str != ite->name.end();++ite_str) { if (*ite_str == PollThread::name_to_del) { ite->name.erase(ite_str); if (ite->name.empty() == true) { works.erase(ite); } found = true; found_in_work_list = true; break; } } if (found == true) break; } } ++ite; } tmp_work.dev = PollThread::dev_to_del; tmp_work.poll_list = &(tmp_work.dev->get_poll_obj_list()); tmp_work.type = PollThread::type_to_del; tmp_work.update = local_cmd.new_upd; tmp_work.name.push_back(PollThread::name_to_del); tmp_work.needed_time.tv_sec = 0; tmp_work.needed_time.tv_usec = 0; compute_new_date(now,local_cmd.new_upd); tmp_work.wake_up_date = now; add_insert_in_list(tmp_work); tune_ctr = 0; found_in_work_list = true; if (found == false) { rem_upd.push_back(local_cmd.new_upd); rem_name.push_back(PollThread::name_to_del); } } } else { // // First, remove object from polling list and insert it in externally triggered list // size_t i,nb_elt; nb_elt = works.size(); ite = works.begin(); for (i = 0;i < nb_elt;i++) { if (ite->dev == PollThread::dev_to_del) { if (ite->type == PollThread::type_to_del) { bool found = false; vector::iterator ite_str; for (ite_str = ite->name.begin();ite_str != ite->name.end();++ite_str) { if (*ite_str == PollThread::name_to_del) { ite->name.erase(ite_str); if (ite->name.empty() == true) works.erase(ite); found = true; found_in_work_list = true; break; } } if (found == true) break; } } ++ite; } wo.dev = local_cmd.dev; wo.poll_list = &(wo.dev->get_poll_obj_list()); wo.type = (*wo.poll_list)[local_cmd.index]->get_type(); wo.update = (*wo.poll_list)[local_cmd.index]->get_upd(); wo.name.push_back((*wo.poll_list)[local_cmd.index]->get_name()); wo.wake_up_date.tv_sec = 0; wo.wake_up_date.tv_usec = 0; ext_trig_works.push_back(wo); } // // If not found in work list, it should be in the externally triggered object. Therefore, remove it from externally // triggered list and insert it in work list. If not found in work list and in trig list, we are in case // 2-2 as described above (polling thread itself updating polling period of the object it actually polls) // if (found_in_work_list == false) { bool found = false; for (et_ite = ext_trig_works.begin(); et_ite != ext_trig_works.end();++et_ite) { if (et_ite->dev == local_cmd.dev) { if (et_ite->type == local_cmd.type) { if (et_ite->name[0] == local_cmd.name) { ext_trig_works.erase(et_ite); found = true; break; } } } } if (found == true) { wo.dev = local_cmd.dev; wo.poll_list = &(wo.dev->get_poll_obj_list()); wo.type = type_to_del; wo.update = local_cmd.new_upd; wo.name.push_back(name_to_del); wo.wake_up_date = now; insert_in_list(wo); } else { auto_upd.push_back(local_cmd.new_upd); auto_name.push_back(name_to_del); } } break; } // // Add the event heartbeat every 9 seconds // case Tango::POLL_ADD_HEARTBEAT: cout5 << "Received a add heartbeat command" << endl; wo.dev = NULL; wo.poll_list = NULL; wo.type = EVENT_HEARTBEAT; wo.update = 9000; wo.name.push_back(string("Event heartbeat")); wo.needed_time.tv_sec = 0; wo.needed_time.tv_usec = TIME_HEARTBEAT; wo.wake_up_date = now; insert_in_list(wo); break; // // Remove the event heartbeat // case Tango::POLL_REM_HEARTBEAT: cout5 << "Received a remove heartbeat command" << endl; unsigned int ii,nb_elem; nb_elem = works.size(); ite = works.begin(); for (ii = 0;ii < nb_elem;ii++) { if (ite->type == EVENT_HEARTBEAT) { works.erase(ite); break; } ++ite; } break; // // Start polling // case Tango::POLL_START : cout5 << "Received a Start polling command" << endl; polling_stop = false; break; // // Stop polling // case Tango::POLL_STOP : cout5 << "Received a Stop polling command" << endl; polling_stop = true; break; // // Ask polling thread to exit // case Tango::POLL_EXIT : cout5 << "Received an exit command" << endl; omni_thread::exit(); break; } // // Inform requesting thread that the work is done // { omni_mutex_lock sync(p_mon); shared_cmd.cmd_pending = false; p_mon.signal(); } if (Tango::Util::_tracelevel >= 4) print_list(); } //+------------------------------------------------------------------------------------------------------------------- // // method : // PollThread::one_more_poll // // description : // //------------------------------------------------------------------------------------------------------------------- void PollThread::one_more_poll() { WorkItem tmp = works.front(); works.pop_front(); if (polling_stop == false) { switch (tmp.type) { case Tango::POLL_CMD: poll_cmd(tmp); break; case Tango::POLL_ATTR: poll_attr(tmp); break; case Tango::EVENT_HEARTBEAT: eve_heartbeat(); heartbeat_ctr++; if (heartbeat_ctr % 3 == 0) auto_unsub(); break; case Tango::STORE_SUBDEV: store_subdev(); break; } } // // For case where the polling thread itself modify the polling period of the object it already polls // if (auto_upd.empty() == false) { for (size_t loop = 0;loop < auto_upd.size();loop++) { vector::iterator pos = remove(tmp.name.begin(),tmp.name.end(),auto_name[loop]); tmp.name.erase(pos,tmp.name.end()); } if (tmp.name.empty() == false) { compute_new_date(tmp.wake_up_date,tmp.update); insert_in_list(tmp); } list::iterator ite; vector::iterator et_ite; for (size_t loop = 0;loop < auto_upd.size();loop++) { size_t nb_elt = works.size(); ite = works.begin(); bool found = false; for (size_t i = 0;i < nb_elt;i++) { if (ite->dev == tmp.dev && ite->type == tmp.type && ite->update == auto_upd[loop]) { ite->name.push_back(auto_name[loop]); found = true; break; } ++ite; } if (found == false) { WorkItem new_tmp; new_tmp.update = auto_upd[loop]; new_tmp.name.push_back(auto_name[loop]); new_tmp.dev = tmp.dev; new_tmp.poll_list = tmp.poll_list; new_tmp.type = tmp.type; new_tmp.needed_time.tv_sec = 0; new_tmp.needed_time.tv_usec = 0; compute_new_date(now,local_cmd.new_upd); new_tmp.wake_up_date = now; insert_in_list(new_tmp); } } auto_upd.clear(); auto_name.clear(); } // // Compute new polling date and insert work in list // else { if (rem_upd.empty() == false) { for (size_t loop = 0;loop < rem_upd.size();loop++) { vector::iterator pos = remove(tmp.name.begin(),tmp.name.end(),rem_name[loop]); tmp.name.erase(pos,tmp.name.end()); } if (tmp.name.empty() == false) { compute_new_date(tmp.wake_up_date,tmp.update); insert_in_list(tmp); } rem_upd.clear(); rem_name.clear(); } else { compute_new_date(tmp.wake_up_date,tmp.update); insert_in_list(tmp); } } tune_ctr--; } //+--------------------------------------------------------------------------------------------------------------- // // method : // PollThread::one_more_trigg // // description : // This method is called when a trigger command has been received // //---------------------------------------------------------------------------------------------------------------- void PollThread::one_more_trigg() { cout5 << "Polling thread has received a trigger" << endl; // // Check that the object is registered // dev_to_del = local_cmd.dev; name_to_del = local_cmd.name; type_to_del = local_cmd.type; vector::iterator et_ite; for (et_ite = ext_trig_works.begin();et_ite != ext_trig_works.end();++et_ite) { if (et_ite->dev == PollThread::dev_to_del) { if (et_ite->type == PollThread::type_to_del) { if (et_ite->name[0] == PollThread::name_to_del) break; } } } // // Check that the object to poll has been installed. If not, simply returns. This case should never happens because // it is tested in the Util::trigger_polling() method before the trigger is effectively sent to this thread. // if (et_ite == ext_trig_works.end()) { cout5 << "Object externally triggered not found !!!" << endl; { omni_mutex_lock sync(p_mon); shared_cmd.trigger = false; p_mon.signal(); } return; } // // Do the job // WorkItem tmp = *et_ite; if (polling_stop == false) { if (tmp.type == Tango::POLL_CMD) poll_cmd(tmp); else poll_attr(tmp); } // // Inform requesting thread that the work is done // { omni_mutex_lock sync(p_mon); shared_cmd.trigger = false; p_mon.signal(); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // PollThread::print_list // // description : // To print work list // //----------------------------------------------------------------------------------------------------------------- void PollThread::print_list() { list::iterator ite; long nb_elt,i; nb_elt = works.size(); ite = works.begin(); for (i = 0;i < nb_elt;i++) { if (ite->type != EVENT_HEARTBEAT ) { if ( ite->type != STORE_SUBDEV) { string obj_list; for (size_t ctr = 0;ctr < ite->name.size();ctr++) { obj_list = obj_list + ite->name[ctr]; if (ctr < (ite->name.size() - 1)) obj_list = obj_list + ", "; } cout5 << "Dev name = " << ite->dev->get_name() << ", obj name = " << obj_list << ", next wake_up at " << + ite->wake_up_date.tv_sec << "," << setw(6) << setfill('0') << ite->wake_up_date.tv_usec << endl; } else { cout5 << ite->name[0] << ", next wake_up at " << + ite->wake_up_date.tv_sec << "," << setw(6) << setfill('0') << ite->wake_up_date.tv_usec << endl; } } else { cout5 << "Event heartbeat, next wake_up at " << + ite->wake_up_date.tv_sec << "," << setw(6) << setfill('0') << ite->wake_up_date.tv_usec << endl; } ++ite; } } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::insert_in_list // // description : // To insert (at the correct place) a new Work Item in the work list // // args : // in : // - new_work : The new work item // //----------------------------------------------------------------------------------------------------------------- void PollThread::insert_in_list(WorkItem &new_work) { list::iterator ite; for (ite = works.begin();ite != works.end();++ite) { if (ite->wake_up_date.tv_sec < new_work.wake_up_date.tv_sec) continue; else if (ite->wake_up_date.tv_sec == new_work.wake_up_date.tv_sec) { if (ite->wake_up_date.tv_usec < new_work.wake_up_date.tv_usec) continue; else { works.insert(ite,new_work); return; } } else { works.insert(ite,new_work); return; } } if (ite == works.end()) works.push_back(new_work); } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::add_insert_in_list // // description : // To insert (at the correct place) a new Work Item in the work list but before this for attribute, if we // already have a work item with the same device at the same period, simply add the obj name in it. // (in order to use read_attributes() in a optimal way) // // args : // in : // - new_work : The new work item // //----------------------------------------------------------------------------------------------------------------- void PollThread::add_insert_in_list(WorkItem &new_work) { if (new_work.type == POLL_ATTR && new_work.dev->get_dev_idl_version() >= 4 && polling_bef_9 == false) { list::iterator ite; #ifdef HAS_LAMBDA_FUNC ite = find_if(works.begin(),works.end(), [&] (const WorkItem &wi) {return wi.dev == new_work.dev && wi.update == new_work.update && wi.type == new_work.type;}); #else for (ite = works.begin();ite != works.end();++ite) { if (ite->dev == new_work.dev && ite->update == new_work.update && ite->type == new_work.type) break; } #endif if (ite != works.end()) { ite->name.push_back(new_work.name[0]); } else insert_in_list(new_work); } else insert_in_list(new_work); } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::tune_list // // description : // This method tunes the work list. // // args : // in : // - from_needed : Set to true if the delta between work should be at least equal to the // time needed to execute the previous work // - min_delta : Min. delta between polling works when from_needed is false // //---------------------------------------------------------------------------------------------------------------- void PollThread::tune_list(bool from_needed, long min_delta) { list::iterator ite,ite_next,ite_prev; unsigned long nb_works = works.size(); cout4 << "Entering tuning list. The list has " << nb_works << " item(s)" << endl; // // Nothing to do if only one let in list // if (nb_works < 2) return; // // If we try to tune the list with respect to works needed time, compute works needed time sum and find minimun update // period // if (from_needed == true) { unsigned long needed_sum = 0; unsigned long min_upd = 0; long max_delta_needed; for (ite = works.begin();ite != works.end();++ite) { long needed_time_usec = (ite->needed_time.tv_sec * 1000000) + ite->needed_time.tv_usec; needed_sum = needed_sum + (unsigned long)needed_time_usec; unsigned long update_usec = (unsigned long)ite->update * 1000; if (ite == works.begin()) { min_upd = update_usec; } else { if (min_upd > update_usec) min_upd = update_usec; } } // // In some cases, it is impossible to tune // if (needed_sum > min_upd) return; else { long sleeping = min_upd - needed_sum; max_delta_needed = sleeping / (nb_works); } // // Now build a new tuned list // Warning: On Windows 64 bits, long are 32 bits data. Convert everything to DevULong64 to be sure // that we will have computation on unsigned 64 bits data // // To tune the list // - Take obj j and compute when it should be polled (next_work) // - Compute when object j-1 should be polled (prev_obj_work) // - Compute the number of poll between these two dates (n) // - Compute date of previous object polling just before "next_work" // - Assign next_work to this date and add // the time needed to execute previous object polling // the delta computed from the smallest upd and the obj number // Tango::DevULong64 now_us = ((Tango::DevULong64)now.tv_sec * 1000000LL) + (Tango::DevULong64)now.tv_usec; Tango::DevULong64 next_tuning = now_us + (POLL_LOOP_NB * (Tango::DevULong64)min_upd); list new_works; new_works.push_front(works.front()); ite = works.begin(); ite_prev = new_works.begin(); for (++ite;ite != works.end();++ite,++ite_prev) { Tango::DevULong64 needed_time_usec = ((Tango::DevULong64)ite_prev->needed_time.tv_sec * 1000000) + (Tango::DevULong64)ite_prev->needed_time.tv_usec; WorkItem wo = *ite; Tango::DevULong64 next_work = ((Tango::DevULong64)wo.wake_up_date.tv_sec * 1000000LL) + (Tango::DevULong64)wo.wake_up_date.tv_usec; Tango::DevULong64 next_prev; if (next_work < next_tuning) { Tango::DevULong64 prev_obj_work = ((Tango::DevULong64)ite_prev->wake_up_date.tv_sec * 1000000LL) + (Tango::DevULong64)ite_prev->wake_up_date.tv_usec; if (next_work > prev_obj_work) { Tango::DevULong64 n = (next_work - prev_obj_work) / ((Tango::DevULong64)ite_prev->update * 1000LL); next_prev = prev_obj_work + (n * (ite_prev->update * 1000LL)); } else next_prev = prev_obj_work; wo.wake_up_date.tv_sec = (long)(next_prev / 1000000LL); wo.wake_up_date.tv_usec = (long)(next_prev % 1000000LL); T_ADD(wo.wake_up_date,needed_time_usec + max_delta_needed); } new_works.push_back(wo); } // // Replace work list // works = new_works; } else { ite_next = works.begin(); ite = ite_next; ++ite_next; for (unsigned int i = 1;i < nb_works;i++) { long diff; T_DIFF(ite->wake_up_date,ite_next->wake_up_date,diff); // // If delta time between works is less than min, shift following work // if (diff < min_delta) T_ADD(ite_next->wake_up_date,min_delta - diff); ++ite; ++ite_next; } } cout4 << "Tuning list done" << endl; print_list(); } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::compute_new_date // // description : // This method computes the new poll date. // // args : // in : // - time : The actual date // - upd : The polling update period (mS) // //------------------------------------------------------------------------------------------------------------------ void PollThread::compute_new_date(struct timeval &time,int upd) { double ori_d = (double)time.tv_sec + ((double)time.tv_usec / 1000000); double new_d = ori_d + ((double)(upd) / 1000); time.tv_sec = (long)new_d; time.tv_usec = (long)((new_d - time.tv_sec) * 1000000); } void PollThread::time_diff(struct timeval &before, struct timeval &after_t, struct timeval &result) { double bef_d = (double)before.tv_sec + ((double)before.tv_usec / 1000000); double aft_d = (double)after_t.tv_sec + ((double)after_t.tv_usec / 1000000); double diff_d = aft_d - bef_d; result.tv_sec = (long)diff_d; result.tv_usec = (long)((diff_d - result.tv_sec) * 1000000); } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::compute_sleep_time // // description : // This method computes how many mS the thread should sleep before the next poll time. If this time is // negative and greater than a pre-defined threshold, the polling is discarded. // //---------------------------------------------------------------------------------------------------------------- void PollThread::compute_sleep_time() { print_list(); if (works.empty() == false) { double next,after_d,diff; after_d = (double)after.tv_sec + ((double)after.tv_usec / 1000000); bool discard = false; u_int nb_late = 0; if (polling_bef_9 == false) { // // Compute for how many items the polling thread is late // list::iterator ite; for (ite = works.begin();ite != works.end();++ite) { next = (double)ite->wake_up_date.tv_sec + ((double)ite->wake_up_date.tv_usec / 1000000); diff = next - after_d; if (diff < 0 && fabs(diff) > DISCARD_THRESHOLD) nb_late++; } // // If we are late for some item(s): // - Seriously late (number of late items equal number of items) --> We will discard items // - Late for the first time: Poll immediately but memorize the number of items for which we are late // - Late again: If the number of late items increase --> Discard items // if (nb_late != 0) { if (nb_late == works.size()) { cout5 << "Setting discard to true because nb_late == works.size() --> " << nb_late << endl; discard = true; } else { if (previous_nb_late != 0) { if (nb_late < previous_nb_late) { previous_nb_late = nb_late; cout5 << "Late but trying to catch up" << endl; } else { previous_nb_late = 0; discard = true; } } else previous_nb_late = nb_late; sleep = -1; } } } else discard = true; // // Analyse work list // // cout5 << "discard = " << boolalpha << discard << endl; if (nb_late == 0 || discard == true) { previous_nb_late = 0; next = (double)works.front().wake_up_date.tv_sec + ((double)works.front().wake_up_date.tv_usec / 1000000); diff = next - after_d; if (diff < 0) { if (fabs(diff) < DISCARD_THRESHOLD) sleep = -1; else { while((diff < 0) && (fabs(diff) > DISCARD_THRESHOLD)) { cout5 << "Discard one elt !!!!!!!!!!!!!" << endl; WorkItem tmp = works.front(); if (tmp.type == POLL_ATTR) err_out_of_sync(tmp); compute_new_date(tmp.wake_up_date,tmp.update); insert_in_list(tmp); works.pop_front(); tune_ctr--; next = (double)works.front().wake_up_date.tv_sec + ((double)works.front().wake_up_date.tv_usec / 1000000); diff = next - after_d; } if (fabs(diff) < DISCARD_THRESHOLD) sleep = -1; else sleep = (long)(diff * 1000); } } else sleep = (long)(diff * 1000); } cout5 << "Sleep for : " << sleep << endl; } } //+--------------------------------------------------------------------------------------------------------------- // // method : // PollThread::err_out_of_sync // // description : // To force one event if the polling thread has discarded one work item because it is late // // args : // in : // - to_do : The work item // //---------------------------------------------------------------------------------------------------------------- void PollThread::err_out_of_sync(WorkItem &to_do) { EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; // // Retrieve the event supplier(s) for this attribute // size_t nb_obj = to_do.name.size(); for (size_t ctr = 0;ctr < nb_obj;ctr++) { Attribute &att = to_do.dev->get_device_attr()->get_attr_by_name(to_do.name[ctr].c_str()); if (att.use_notifd_event() == true && event_supplier_nd == NULL) event_supplier_nd = Util::instance()->get_notifd_event_supplier(); if (att.use_zmq_event() == true && event_supplier_zmq == NULL) event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL)) { Tango::DevErrorList errs; errs.length(1); errs[0].severity = Tango::ERR; errs[0].reason = CORBA::string_dup("API_PollThreadOutOfSync"); errs[0].origin = CORBA::string_dup("PollThread::err_out_of_sync"); errs[0].desc = CORBA::string_dup("The polling thread is late and discard this object polling.\nAdvice: Tune device server polling"); Tango::DevFailed except(errs); long idl_vers = to_do.dev->get_dev_idl_version(); struct EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (idl_vers > 4) ad.attr_val_5 = &dummy_att5; else if (idl_vers == 4) ad.attr_val_4 = &dummy_att4; else if (idl_vers == 3) ad.attr_val_3 = &dummy_att3; else ad.attr_val = &dummy_att; // // Fire event // SendEventType send_event; if (event_supplier_nd != NULL) send_event = event_supplier_nd->detect_and_push_events(to_do.dev,ad,&except,to_do.name[ctr],(struct timeval *)NULL); if (event_supplier_zmq != NULL) { if (event_supplier_nd != NULL) { vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; if (send_event.change == true) event_supplier_zmq->push_event_loop(to_do.dev,CHANGE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,&except); if (send_event.archive == true) event_supplier_zmq->push_event_loop(to_do.dev,ARCHIVE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,&except); if (send_event.periodic == true) event_supplier_zmq->push_event_loop(to_do.dev,PERIODIC_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,&except); } else event_supplier_zmq->detect_and_push_events(to_do.dev,ad,&except,to_do.name[ctr],(struct timeval *)NULL); } } } } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::poll_cmd // // description : // Execute a command and store the result in the device ring buffer // // args : // in : // - to_do : The work item // //---------------------------------------------------------------------------------------------------------------- void PollThread::poll_cmd(WorkItem &to_do) { cout5 << "----------> Time = " << now.tv_sec << "," << setw(6) << setfill('0') << now.tv_usec << " Dev name = " << to_do.dev->get_name() << ", Cmd name = " << to_do.name[0] << endl; CORBA::Any *argout = NULL; Tango::DevFailed *save_except = NULL; struct timeval before_cmd,after_cmd,needed_time; #ifdef _TG_WINDOWS_ struct _timeb before_win,after_win; LARGE_INTEGER before,after; #endif vector::iterator ite; bool cmd_failed = false; try { #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) QueryPerformanceCounter(&before); _ftime(&before_win); before_cmd.tv_sec = (unsigned long)before_win.time; before_cmd.tv_usec = (long)before_win.millitm * 1000; #else gettimeofday(&before_cmd,NULL); #endif before_cmd.tv_sec = before_cmd.tv_sec - DELTA_T; // // Execute the command // argout = to_do.dev->command_inout(to_do.name[0].c_str(),in_any); #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) { QueryPerformanceCounter(&after); needed_time.tv_sec = 0; needed_time.tv_usec = (long)((double)(after.QuadPart - before.QuadPart) * ctr_frequency); to_do.needed_time = needed_time; } else { _ftime(&after_win); after_cmd.tv_sec = (unsigned long)after_win.time; after_cmd.tv_usec = (long)after_win.millitm * 1000; after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; } #else gettimeofday(&after_cmd,NULL); after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; #endif } catch (Tango::DevFailed &e) { cmd_failed = true; #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) { QueryPerformanceCounter(&after); needed_time.tv_sec = 0; needed_time.tv_usec = (long)((double)(after.QuadPart - before.QuadPart) * ctr_frequency); to_do.needed_time = needed_time; } else { _ftime(&after_win); after_cmd.tv_sec = (unsigned long)after_win.time; after_cmd.tv_usec = (long)after_win.millitm * 1000; after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; } #else gettimeofday(&after_cmd,NULL); after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; #endif save_except = new Tango::DevFailed(e); } // // Insert result in polling buffer and simply forget this command if it is not possible to insert the result in // polling buffer // try { to_do.dev->get_poll_monitor().get_monitor(); ite = to_do.dev->get_polled_obj_by_type_name(to_do.type,to_do.name[0]); if (cmd_failed == false) (*ite)->insert_data(argout,before_cmd,needed_time); else (*ite)->insert_except(save_except,before_cmd,needed_time); to_do.dev->get_poll_monitor().rel_monitor(); } catch (Tango::DevFailed &) { if (cmd_failed == false) delete argout; else delete save_except; to_do.dev->get_poll_monitor().rel_monitor(); } } //+--------------------------------------------------------------------------------------------------------------- // // method : // PollThread::poll_attr // // description : // Read attribute and store the result in the device ring buffer // // args : // in : // - to_do : The work item // //---------------------------------------------------------------------------------------------------------------- void PollThread::poll_attr(WorkItem &to_do) { size_t nb_obj = to_do.name.size(); string att_list; for (size_t ctr = 0;ctr < nb_obj;ctr++) { att_list = att_list + to_do.name[ctr]; if (ctr < (nb_obj - 1)) att_list = att_list + ", "; } cout5 << "----------> Time = " << now.tv_sec << "," << setw(6) << setfill('0') << now.tv_usec << " Dev name = " << to_do.dev->get_name() << ", Attr name = " << att_list << endl; struct timeval before_cmd,after_cmd,needed_time; #ifdef _TG_WINDOWS_ struct _timeb before_win,after_win; LARGE_INTEGER before,after; #endif Tango::AttributeValueList *argout = NULL; Tango::AttributeValueList_3 *argout_3 = NULL; Tango::AttributeValueList_4 *argout_4 = NULL; Tango::AttributeValueList_5 *argout_5 = NULL; Tango::DevFailed *save_except = NULL; bool attr_failed = false; vector::iterator ite; map map_except; long idl_vers = to_do.dev->get_dev_idl_version(); try { #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) QueryPerformanceCounter(&before); _ftime(&before_win); before_cmd.tv_sec = (unsigned long)before_win.time; before_cmd.tv_usec = (long)before_win.millitm * 1000; #else gettimeofday(&before_cmd,NULL); #endif before_cmd.tv_sec = before_cmd.tv_sec - DELTA_T; // // Read the attributes // attr_names.length(nb_obj); for (size_t ctr = 0;ctr < nb_obj;ctr++) attr_names[ctr] = to_do.name[ctr].c_str(); if (idl_vers >= 5) argout_5 = (static_cast(to_do.dev))->read_attributes_5(attr_names,Tango::DEV,dummy_cl_id); else if (idl_vers == 4) argout_4 = (static_cast(to_do.dev))->read_attributes_4(attr_names,Tango::DEV,dummy_cl_id); else if (idl_vers == 3) argout_3 = (static_cast(to_do.dev))->read_attributes_3(attr_names,Tango::DEV); else argout = to_do.dev->read_attributes(attr_names); #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) { QueryPerformanceCounter(&after); needed_time.tv_sec = 0; needed_time.tv_usec = (long)((double)(after.QuadPart - before.QuadPart) * ctr_frequency); to_do.needed_time = needed_time; } else { _ftime(&after_win); after_cmd.tv_sec = (unsigned long)after_win.time; after_cmd.tv_usec = (long)after_win.millitm * 1000; after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; } #else gettimeofday(&after_cmd,NULL); after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; #endif } catch (Tango::DevFailed &e) { attr_failed = true; #ifdef _TG_WINDOWS_ if (ctr_frequency != 0) { QueryPerformanceCounter(&after); needed_time.tv_sec = 0; needed_time.tv_usec = (long)((double)(after.QuadPart - before.QuadPart) * ctr_frequency); to_do.needed_time = needed_time; } else { _ftime(&after_win); after_cmd.tv_sec = (unsigned long)after_win.time; after_cmd.tv_usec = (long)after_win.millitm * 1000; after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; } #else gettimeofday(&after_cmd,NULL); after_cmd.tv_sec = after_cmd.tv_sec - DELTA_T; time_diff(before_cmd,after_cmd,needed_time); to_do.needed_time = needed_time; #endif save_except = new Tango::DevFailed(e); } // // Starting with IDl release 3, an attribute in error is not an exception any more. Re-create one. // Don't forget that it is still possible to receive classical exception (in case of Monitor timeout for instance) // if (idl_vers >= 3) { if (idl_vers >= 5) { if (nb_obj == 1) { if ((attr_failed == false) && ((*argout_5)[0].err_list.length() != 0)) { attr_failed = true; save_except = new Tango::DevFailed((*argout_5)[0].err_list); delete argout_5; } } else { for (size_t ctr = 0;ctr < nb_obj;ctr++) { if ((attr_failed == false) && ((*argout_5)[ctr].err_list.length() != 0)) { Tango::DevFailed *tmp_except = new Tango::DevFailed((*argout_5)[ctr].err_list); map_except.insert(pair(ctr,tmp_except)); } } } } else if (idl_vers == 4) { if (nb_obj == 1) { if ((attr_failed == false) && ((*argout_4)[0].err_list.length() != 0)) { attr_failed = true; save_except = new Tango::DevFailed((*argout_4)[0].err_list); delete argout_4; } } else { for (size_t ctr = 0;ctr < nb_obj;ctr++) { if ((attr_failed == false) && ((*argout_4)[ctr].err_list.length() != 0)) { Tango::DevFailed *tmp_except = new Tango::DevFailed((*argout_4)[ctr].err_list); map_except.insert(pair(ctr,tmp_except)); } } } } else { if ((attr_failed == false) && ((*argout_3)[0].err_list.length() != 0)) { attr_failed = true; save_except = new Tango::DevFailed((*argout_3)[0].err_list); delete argout_3; } } } // // Events - for each event call the detect_and_push() method this method will fire events if there are clients // registered and if there is an event (on_change, on_alarm or periodic) // We also have to retrieve which kind of clients made the subscription (zmq or notifd) and send the event accordingly // EventSupplier *event_supplier_nd = NULL; EventSupplier *event_supplier_zmq = NULL; for (size_t ctr = 0;ctr < nb_obj;ctr++) { Attribute &att = to_do.dev->get_device_attr()->get_attr_by_name(to_do.name[ctr].c_str()); if (att.use_notifd_event() == true && event_supplier_nd == NULL) event_supplier_nd = Util::instance()->get_notifd_event_supplier(); if (att.use_zmq_event() == true && event_supplier_zmq == NULL) event_supplier_zmq = Util::instance()->get_zmq_event_supplier(); if ((event_supplier_nd != NULL) || (event_supplier_zmq != NULL)) { if (attr_failed == true) { struct EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (idl_vers > 4) ad.attr_val_5 = &dummy_att5; else if (idl_vers == 4) ad.attr_val_4 = &dummy_att4; else if (idl_vers == 3) ad.attr_val_3 = &dummy_att3; else ad.attr_val = &dummy_att; // // Eventually push the event (if detected). When we have both notifd and zmq event supplier, do not detect the event // two times. The detect_and_push_events() method returns true if the event is detected. // SendEventType send_event; if (event_supplier_nd != NULL) send_event = event_supplier_nd->detect_and_push_events(to_do.dev,ad,save_except,to_do.name[ctr],&before_cmd); if (event_supplier_zmq != NULL) { if (event_supplier_nd != NULL) { vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; if (send_event.change == true) event_supplier_zmq->push_event_loop(to_do.dev,CHANGE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,save_except); if (send_event.archive == true) event_supplier_zmq->push_event_loop(to_do.dev,ARCHIVE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,save_except); if (send_event.periodic == true) event_supplier_zmq->push_event_loop(to_do.dev,PERIODIC_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,save_except); } else event_supplier_zmq->detect_and_push_events(to_do.dev,ad,save_except,to_do.name[ctr],&before_cmd); } } else { struct EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (idl_vers > 4) ad.attr_val_5 = &((*argout_5)[ctr]); else if (idl_vers == 4) ad.attr_val_4 = &((*argout_4)[ctr]); else if (idl_vers == 3) ad.attr_val_3 = &((*argout_3)[ctr]); else ad.attr_val = &((*argout)[ctr]); // // Eventually push the event (if detected). When we have both notifd and zmq event supplier, do not detect the event // two times. The detect_and_push_events() method returns true if the event is detected. // SendEventType send_event; map::iterator ite2 = map_except.find(ctr); Tango::DevFailed *tmp_except; if (ite2 == map_except.end()) tmp_except = save_except; else tmp_except = ite2->second; if (event_supplier_nd != NULL) send_event = event_supplier_nd->detect_and_push_events(to_do.dev,ad,tmp_except,to_do.name[ctr],&before_cmd); if (event_supplier_zmq != NULL) { if (event_supplier_nd != NULL) { vector f_names; vector f_data; vector f_names_lg; vector f_data_lg; if (send_event.change == true) event_supplier_zmq->push_event_loop(to_do.dev,CHANGE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,tmp_except); if (send_event.periodic == true) event_supplier_zmq->push_event_loop(to_do.dev,PERIODIC_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,tmp_except); if (send_event.archive == true) event_supplier_zmq->push_event_loop(to_do.dev,ARCHIVE_EVENT,f_names,f_data,f_names_lg,f_data_lg,ad,att,tmp_except); } else event_supplier_zmq->detect_and_push_events(to_do.dev,ad,tmp_except,to_do.name[ctr],&before_cmd); } } } } // // Insert result in polling buffer and simply forget this attribute if it is not possible to insert the result in // polling buffer // Different case according to the number of attributes which has been read by this poll. // The PollObj object are supposed to store data coming from a read_attributes() executed for 1 attribute. // Sonce Tango 9.0.8, it is not always the case. This is why we differantiate cases when we read several att // in once call. Sin the last case, re-create memory layout as the one coming from read_attributes called for // single attribute. // This new feature is available only for devices with IDL 4 or more // try { to_do.dev->get_poll_monitor().get_monitor(); for (size_t ctr = 0;ctr < nb_obj;ctr++) { ite = to_do.dev->get_polled_obj_by_type_name(to_do.type,to_do.name[ctr]); if (attr_failed == false) { if (nb_obj == 1) { if (idl_vers >= 5) (*ite)->insert_data(argout_5,before_cmd,needed_time); else if (idl_vers == 4) (*ite)->insert_data(argout_4,before_cmd,needed_time); else if (idl_vers == 3) (*ite)->insert_data(argout_3,before_cmd,needed_time); else (*ite)->insert_data(argout,before_cmd,needed_time); } else { if (idl_vers >= 5) { map::iterator ite2 = map_except.find(ctr); if (ite2 == map_except.end()) { Tango::AttributeValueList_5 *new_argout_5 = new Tango::AttributeValueList_5(1); new_argout_5->length(1); (*new_argout_5)[0].value.union_no_data(true); robb_data((*argout_5)[ctr],(*new_argout_5)[0]); copy_remaining((*argout_5)[ctr],(*new_argout_5)[0]); (*new_argout_5)[0].data_type = (*argout_5)[ctr].data_type; (*ite)->insert_data(new_argout_5,before_cmd,needed_time); } else (*ite)->insert_except(ite2->second,before_cmd,needed_time); } else { map::iterator ite2 = map_except.find(ctr); if (ite2 == map_except.end()) { Tango::AttributeValueList_4 *new_argout_4 = new Tango::AttributeValueList_4(1); new_argout_4->length(1); (*new_argout_4)[0].value.union_no_data(true); robb_data((*argout_4)[ctr],(*new_argout_4)[0]); copy_remaining((*argout_4)[ctr],(*new_argout_4)[0]); (*ite)->insert_data(new_argout_4,before_cmd,needed_time); } else (*ite)->insert_except(ite2->second,before_cmd,needed_time); } } } else { if (nb_obj == 1) (*ite)->insert_except(save_except,before_cmd,needed_time); else { if (ctr != nb_obj - 1) { Tango::DevFailed *dup_except = new Tango::DevFailed(save_except->errors); (*ite)->insert_except(dup_except,before_cmd,needed_time); } else (*ite)->insert_except(save_except,before_cmd,needed_time); } } } if (nb_obj != 1 && attr_failed == false) { if (idl_vers >= 5) delete argout_5; else delete argout_4; } to_do.dev->get_poll_monitor().rel_monitor(); } catch (Tango::DevFailed &) { if (attr_failed == false) { if (idl_vers >= 5) delete argout_5; else if (idl_vers == 4) delete argout_4; else if (idl_vers == 3) delete argout_3; else delete argout; } else delete save_except; to_do.dev->get_poll_monitor().rel_monitor(); } } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::eve_heartbeat // // description : // Send the event heartbeat // //------------------------------------------------------------------------------------------------------------------- void PollThread::eve_heartbeat() { cout5 << "----------> Time = " << now.tv_sec << "," << setw(6) << setfill('0') << now.tv_usec << " Sending event heartbeat" << endl; EventSupplier *event_supplier; event_supplier = Util::instance()->get_zmq_event_supplier(); if ((event_supplier != NULL) && (send_heartbeat == true) && (event_supplier->get_one_subscription_cmd() == true)) { event_supplier->push_heartbeat_event(); } event_supplier = Util::instance()->get_notifd_event_supplier(); if ((event_supplier != NULL) && (send_heartbeat == true) && (event_supplier->get_one_subscription_cmd() == true)) { event_supplier->push_heartbeat_event(); } } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::store_subdev // // description : // Store the sub device properties when needed. // //----------------------------------------------------------------------------------------------------------------- void PollThread::store_subdev() { static bool ignore_call = true; cout5 << "----------> Time = " << now.tv_sec << "," << setw(6) << setfill('0') << now.tv_usec << " Store sub device property data if needed!" << endl; if ( !ignore_call ) { Tango::Util *tg = Tango::Util::instance(); tg->get_sub_dev_diag().store_sub_devices(); } else { // ignore the first call to avoid storage during // device server start-up. ignore_call = false; } } //+---------------------------------------------------------------------------------------------------------------- // // method : // PollThread::auto_unsub // // description : // Check if we can unsubscribe on user events on forwarded attribute(s) // //----------------------------------------------------------------------------------------------------------------- void PollThread::auto_unsub() { RootAttRegistry &rar = Util::instance()->get_root_att_reg(); rar.auto_unsub(); } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/rootattreg.cpp0000644023471100065110000012131013034745002015456 00000000000000static const char *RcsId = "$Id: rootattreg.cpp 28374 2015-08-14 07:03:55Z taurel $"; //+================================================================================================================== // // file : rootattreg.cpp // // description : C++ source code for the RootAttRegistry and RootAttConfCallBack classes // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28374 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::push_event // // description : // Method called when root attribute configuration change event(s) are received // According to which attribute the event has been received for, update its config. // // argument : // in : // - ev : The event data // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::push_event(Tango::AttrConfEventData *ev) { try { //cout << "One attribute configuration change event received" << endl; //cout << "Attr name = " << ev->attr_name << endl; //cout << "Event name = " << ev->event << endl; //cout << "Error flag = " << boolalpha << ev->err << endl; if (ev->err == false) { string att_name = ev->attr_name; { omni_mutex_lock oml(the_lock); map::iterator ite; ite = map_attrdesc.find(att_name); if (ite != map_attrdesc.end()) { if (ite->second.fwd_attr == Tango_nullptr || ite->second.fwd_attr_cl == Tango_nullptr) { // // Event received while everything is OK for the fwd attribute // map::iterator ite3; ite3 = local_dis.find(ite->second.local_name); if (ite3 == local_dis.end()) { cerr << "RootAttRegistry::RootAttConfCallBack::push_event(): Device " ; cerr << ite->second.local_name << " not found in map (local_dis)! Map corrupted?" << endl; } else { Device_5Impl *the_dev = static_cast(ite3->second); if (the_dev != Tango_nullptr) { // // If the callback is executed due to a synchronous call after a re-connection (ptr null), the info we received do // not contain a AttributeConfig structure. In this case, create one from the AttributeInfoEx // FwdAttrConfEventData *ev_fwd = static_cast(ev); AttributeConfig_5 *ptr = const_cast(ev_fwd->get_fwd_attr_conf()); if (ptr == Tango_nullptr) { ptr = AttributeConfigList_5::allocbuf(1); ApiUtil::AttributeInfoEx_to_AttributeConfig(ev->attr_conf,ptr); } AttributeConfigList_5 conf_list(1,1,ptr,false); // // The attribute name, root_attr_name and label are local values // conf_list[0].name = ite->second.local_att_name.c_str(); conf_list[0].root_attr_name = ite->first.c_str(); if (ite->second.local_label.empty() == false) conf_list[0].label = ite->second.local_label.c_str(); the_dev->set_attribute_config_5(conf_list,ci); } else { cerr << "RootAttRegistry::RootAttConfCallBack::push_event(): Device " ; cerr << ite->second.local_name << " has a null pointer in DeviceImpl * map (local_dis)" << endl; } } } else { // // Synchronous event due to subscription or event received after a successfull re-connection if the server // was started while the root device was off // //cout << "Err kind = " << ite->second.fwd_attr->get_err_kind() << endl; if (ite->second.fwd_attr->get_err_kind() == FWD_ROOT_DEV_NOT_STARTED) { map::iterator ite3; ite3 = local_dis.find(ite->second.local_name); if (ite3 == local_dis.end()) { cerr << "RootAttRegistry::RootAttConfCallBack::push_event(): Device " ; cerr << ite->second.local_name << " not found in map (local_dis)! Map corrupted?" << endl; } else { string::size_type pos = att_name.rfind('/'); string root_dev_name = att_name.substr(0,pos); bool rel_ok = rar->check_root_dev_release(root_dev_name); Device_5Impl *the_dev = static_cast(ite3->second); if (rel_ok == true) { if (ite->second.local_label.empty() == false) ev->attr_conf->label = ite->second.local_label; the_dev->add_attribute(ite->second.fwd_attr); Attribute &the_fwd_att = the_dev->get_device_attr()->get_attr_by_name(ite->second.local_att_name.c_str()); static_cast(the_fwd_att).set_att_config(ev->attr_conf); MultiAttribute *m_att = the_dev->get_device_attr(); m_att->update(the_fwd_att,ite->second.local_name); ite->second.fwd_attr = Tango_nullptr; the_dev->rem_wrong_fwd_att(att_name); the_dev->set_run_att_conf_loop(true); // // Now, we can really start polling this attribute (if required) // vector &poll_attr_list = the_dev->get_polled_attr(); string local_att_lower(ite->second.local_att_name); transform(local_att_lower.begin(),local_att_lower.end(),local_att_lower.begin(),::tolower); vector::iterator pos = find(poll_attr_list.begin(),poll_attr_list.end(),local_att_lower); if (pos != poll_attr_list.end()) { DevVarLongStringArray send; send.lvalue.length(1); send.svalue.length(3); send.svalue[0] = CORBA::string_dup(the_dev->get_name().c_str()); send.svalue[1] = CORBA::string_dup("attribute"); send.svalue[2] = CORBA::string_dup((*pos).c_str()); stringstream ss; long upd; ss << *(pos + 1); ss >> upd; if (upd < 0) upd = -upd; send.lvalue[0] = upd; DServer *adm_dev = Util::instance()->get_dserver_device(); adm_dev->add_obj_polling(&send,false); } } else { string root_att_name = att_name.substr(pos + 1); the_dev->update_wrong_conf_att(att_name,FWD_TOO_OLD_ROOT_DEVICE); the_dev->set_run_att_conf_loop(true); } } } else { // // Classical event due to synchronous call during subscription // ite->second.fwd_attr_cl->init_conf(ev); ite->second.fwd_attr_cl = Tango_nullptr; } } } else { cerr << "RootAttRegistry::RootAttConfCallBack::push_event(): " ; cerr << "Root attribute " << att_name << " not found in map (map_attrdesc)! Map corrupted?" << endl; } } } } catch (Tango::DevFailed &e) { cerr << "RootAttRegistry::RootAttConfCallBack::push_event(): Exception!" ; Tango::Except::print_exception(e); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttUserCallBack::push_event // // description : // Method called when root attribute event(s) are received (except att conf change event) // // argument : // in : // - ev : The event data // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttUserCallBack::push_event(Tango::EventData *ev) { try { //cout << "One event received" << endl; //cout << "Attr name = " << ev->attr_name << endl; ZmqEventSupplier *zes = Util::instance()->get_zmq_event_supplier(); // // Get local device name from event name // string local_name = rar->get_local_att_name(ev->attr_name); string::size_type pos = local_name.rfind('/'); string local_dev_name = local_name.substr(0,pos); string local_att_name = local_name.substr(pos + 1); DeviceImpl *dev = rar->get_local_dev(local_dev_name); EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); string event_name = EVENT_COMPAT_IDL5 + ev->event; if (ev->err == true) { DevFailed df(ev->errors); zes->push_event(dev,event_name,dummy_vs,dummy_vd,dummy_vs,dummy_vl,ad,local_att_name,&df,true); } else { FwdEventData *ev_fwd = static_cast(ev); const AttributeValue_5 *ptr = ev_fwd->get_av_5(); zmq::message_t *zmq_mess_ptr = ev_fwd->get_zmq_mess_ptr(); if (ptr != Tango_nullptr || zmq_mess_ptr != Tango_nullptr) { // // Now, forward the event // if (ptr != Tango_nullptr) ad.attr_val_5 = ptr; else ad.zmq_mess = zmq_mess_ptr; zes->push_event(dev,event_name,dummy_vs,dummy_vd,dummy_vs,dummy_vl,ad,local_att_name,Tango_nullptr,true); } } } catch (Tango::DevFailed &e) { cerr << "RootAttRegistry::RootAttUserCallBack::push_event(): Exception!" ; Tango::Except::print_exception(e); } } void RootAttRegistry::RootAttUserCallBack::push_event(Tango::DataReadyEventData *ev) { try { ZmqEventSupplier *zes = Util::instance()->get_zmq_event_supplier(); // // First, extract root att name (root_dev_name/att_name) from the received attribute name // string::size_type pos = ev->attr_name.find("//"); pos = pos + 2; pos = ev->attr_name.find('/',pos); pos = pos + 1; string::size_type pos_end = ev->attr_name.rfind('.'); string root_att_name = ev->attr_name.substr(pos,pos_end - pos); string local_name = rar->get_local_att_name(root_att_name); pos = local_name.rfind('/'); string local_dev_name = local_name.substr(0,pos); string local_att_name = local_name.substr(pos + 1); DeviceImpl *dev = rar->get_local_dev(local_dev_name); EventSupplier::SuppliedEventData ad; ::memset(&ad,0,sizeof(ad)); if (ev->err == true) { DevFailed df(ev->errors); zes->push_event(dev,ev->event,dummy_vs,dummy_vd,dummy_vs,dummy_vl,ad,local_att_name,&df,true); } else { dev->push_data_ready_event(local_att_name,ev->ctr); } } catch (Tango::DevFailed &e) { cerr << "RootAttRegistry::RootAttUserCallBack::push_event(): Exception!" ; Tango::Except::print_exception(e); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::add_att // // description : // Add a attribute object (still in its FwdAttr form) in the map of subscribed object // // argument : // in : // - root_att_name : The attribute name (dev_name/att_name) // - local_dev_name : The local device name // - local_att_name : The local attribute name // - att: The attribute pointer when still a FwdAttr object // - dev : The local device pointer (DeviceImpl *) // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::add_att(string &root_att_name,string &local_dev_name, string &local_att_name,FwdAttr *att,DeviceImpl *dev) { DeviceImpl *the_local_dev; try { the_local_dev = Tango_nullptr; struct NameFwdAttr nf; nf.local_name = local_dev_name; nf.local_att_name = local_att_name; nf.fwd_attr = new FwdAttr(*att); nf.fwd_attr_cl = att; vector &def_user_prop = att->get_user_default_properties(); vector::iterator pos; for (pos = def_user_prop.begin();pos != def_user_prop.end();++pos) { if (pos->get_name() == "label") { nf.local_label = pos->get_value(); break; } } if (pos == def_user_prop.end()) nf.local_label = local_att_name; map::iterator ite; ite = local_dis.find(local_dev_name); if (ite == local_dis.end()) the_local_dev = dev; { omni_mutex_lock oml(the_lock); #ifdef INIT_LIST map_attrdesc.insert({root_att_name,nf}); if (the_local_dev != nullptr) local_dis.insert({local_dev_name,the_local_dev}); #else map_attrdesc.insert(make_pair(root_att_name,nf)); if (the_local_dev != Tango_nullptr) local_dis.insert(make_pair(local_dev_name,the_local_dev)); #endif } } catch (DevFailed &e) {} } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::remove_att // // description : // Remove a attribute object (still in its FwdAttr form) in the map of subscribed object // // argument : // in : // - root_att_name : The attribute name (dev_name/att_name) // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::remove_att(string &root_att_name) { omni_mutex_lock oml(the_lock); // // Get local dev name and check if the same local dev name is used for other forwarded att // map::iterator ite; ite = map_attrdesc.find(root_att_name); if (ite != map_attrdesc.end()) { string local_dev_name = ite->second.local_name; map_attrdesc.erase(ite); bool used_elsewhere = false; map::iterator pos; for (pos = map_attrdesc.begin();pos != map_attrdesc.end();++pos) { if (pos->second.local_name == local_dev_name) { used_elsewhere = true; break; } } // // If the local device name is not referenced in any entry in the map_attrdesc map, we can remove the // corresponding DeviceImpl entry // if (used_elsewhere == false) { map::iterator ite_dp = local_dis.find(local_dev_name); local_dis.erase(ite_dp); } } else { string desc("Root attribute "); desc = desc + root_att_name + " not found in class map!"; Except::throw_exception(API_AttrNotFound,desc,"RootAttConfCallBack::remove_att"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::clear_attrdesc // // description : // // // argument : // in : // - root_att_name : The root attribute name // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::clear_attrdesc(string &root_att_name) { map::iterator ite; ite = map_attrdesc.find(root_att_name); if (ite != map_attrdesc.end()) { ite->second.fwd_attr = Tango_nullptr; } else { string desc("Root attribute "); desc = desc + root_att_name + " not found in class map!"; Except::throw_exception(API_AttrNotFound,desc,"RootAttConfCallBack::clear_attrdesc"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::is_root_att_in_map // // description : // Check if one attribute is defined in the map as one of the root attribute // // argument : // in : // - root_att_name : The attribute name (dev_name/att_name) // // return : // True is the attribute is in the map // //-------------------------------------------------------------------------------------------------------------------- bool RootAttRegistry::RootAttConfCallBack::is_root_att_in_map(string &root_att_name) { bool ret = false; omni_mutex_lock oml(the_lock); map::iterator ite; ite = map_attrdesc.find(root_att_name); if (ite != map_attrdesc.end()) ret = true; return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::count_root_dev // // description : // Count how many times the root device with name given as parameter is used as root device name by all the // registred forwarded attributes // // argument : // in : // - root_dev_name : The root device name // // return : // Number of time the root device name is used in map_attrdesc key // //-------------------------------------------------------------------------------------------------------------------- int RootAttRegistry::RootAttConfCallBack::count_root_dev(string &root_dev_name) { int ret = 0; map::iterator pos; for (pos = map_attrdesc.begin();pos != map_attrdesc.end();++pos) { string::size_type p = pos->first.rfind('/'); string key_dev = pos->first.substr(0,p); if (key_dev == root_dev_name) ret++; } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::update_device_impl // // description : // Update local device pointer in map // // argument : // in : // - local_dev_name : The local device name // - local_dev : The new local device pointer // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::update_device_impl(string &local_dev_name,DeviceImpl *local_dev) { omni_mutex_lock oml(the_lock); map::iterator ite; ite = local_dis.find(local_dev_name); if (ite != local_dis.end()) { ite->second = local_dev; } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::update_err_kind // // description : // Update error type in map for one specific root attribute // // argument : // in : // - root_att_name : The root attribute name // - err : The new error code // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::update_err_kind(string &root_att_name,FwdAttError err) { omni_mutex_lock oml(the_lock); map::iterator ite; ite = map_attrdesc.find(root_att_name); if (ite != map_attrdesc.end()) { ite->second.fwd_attr->set_err_kind(err); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::is_root_dev_not_started_err // // description : // Check if there is some forwarded attribute with error set to FWD_ROOT_DEV_NOT_STARTED // // return : // True if one of the process fwd attribute has its error set to root device not started yet. // //-------------------------------------------------------------------------------------------------------------------- bool RootAttRegistry::RootAttConfCallBack::is_root_dev_not_started_err() { omni_mutex_lock oml(the_lock); map::iterator ite; for (ite = map_attrdesc.begin();ite != map_attrdesc.end();++ite) { if (ite->second.fwd_attr != NULL) { if (ite->second.fwd_attr->get_err_kind() == FWD_ROOT_DEV_NOT_STARTED) return true; } } return false; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::add_root_att // // description : // Add a new root attribute. This means create a device proxy to the device (if not already done) and // subscribe to the root attribute configuration change event // // argument : // in : // - device_name : The device name // - att_name : The attribute name // - local_dev_name : The local device name // - local_att_name : The local attribute name // - attdesc : The attribute object when still a FwdAttr object // - dev : Device pointer // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::add_root_att(string &device_name,string &att_name,string &local_dev_name,string &local_att_name, FwdAttr *attdesc,DeviceImpl *dev) { DeviceProxy *the_dev; map::iterator ite; ite = dps.find(device_name); if (ite == dps.end()) { try { the_dev = new DeviceProxy(device_name); } catch (Tango::DevFailed &e) { attdesc->set_err_kind(FWD_WRONG_DEV); string desc("The root device "); desc = desc + device_name + " is not defined in database"; Except::throw_exception(API_AttrNotAllowed,desc,"RootAttRegistry::add_root_att"); } int idl_vers = the_dev->get_idl_version(); if (idl_vers > 0 && idl_vers < MIN_IDL_CONF5) { attdesc->set_err_kind(FWD_TOO_OLD_ROOT_DEVICE); delete the_dev; string desc("The root device "); desc = desc + device_name + " is too old to support forwarded attribute. It requires IDL >= 5"; Except::throw_exception(API_AttrNotAllowed,desc,"RootAttRegistry::add_root_att"); } #ifdef INIT_LIST dps.insert({device_name,the_dev}); #else dps.insert(make_pair(device_name,the_dev)); #endif } else the_dev = ite->second; // // When the device is not there, subscribing to att change event throws one exception // and it does call the callback with error flag set. Because we want to know that the root device is not yet // ready, implement a two steps subscription // First subscription is in statefull mode while the second one is in stateless mode // string a_name = device_name + '/' + att_name; bool already_there = cbp.is_root_att_in_map(a_name); if (already_there == false) { cbp.add_att(a_name,local_dev_name,local_att_name,attdesc,dev); int event_id; try { event_id = the_dev->subscribe_event(att_name,Tango::ATTR_CONF_EVENT,&cbp); #ifdef INIT_LIST map_event_id.insert({a_name,event_id}); #else map_event_id.insert(make_pair(a_name,event_id)); #endif } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),API_AttrNotFound) == 0) { bool loop = check_loop(device_name,att_name,local_dev_name,local_att_name); if (loop == true) attdesc->set_err_kind(FWD_CONF_LOOP); else attdesc->set_err_kind(FWD_WRONG_ATTR); } else if (::strcmp(e.errors[0].reason.in(),API_CantConnectToDevice) == 0 || ::strcmp(e.errors[0].reason.in(),API_DeviceNotExported) == 0 || ::strcmp(e.errors[0].reason.in(),API_ZmqFailed) == 0) attdesc->set_err_kind(FWD_ROOT_DEV_NOT_STARTED); else if (e.errors.length() > 1 && ::strcmp(e.errors[1].reason.in(),API_CantConnectToDevice) == 0) { Util *tg = Util::instance(); string ds_name = tg->get_ds_name(); transform(ds_name.begin(),ds_name.end(),ds_name.begin(),::tolower); string err_desc(e.errors[1].desc.in()); if (err_desc.find(ds_name) != string::npos) attdesc->set_err_kind(FWD_ROOT_DEV_NOT_STARTED); } else attdesc->set_err_kind(FWD_WRONG_DEV); event_id = the_dev->subscribe_event(att_name,Tango::ATTR_CONF_EVENT,&cbp,true); #ifdef INIT_LIST map_event_id.insert({a_name,event_id}); #else map_event_id.insert(make_pair(a_name,event_id)); #endif cbp.update_err_kind(a_name,attdesc->get_err_kind()); Tango::Except::re_throw_exception(e,"API_DummyException","nothing","RootAttRegistry::add_root_att"); } } else { Tango::Util *tg = Util::instance(); if (tg->is_device_restarting(local_dev_name) == false) { attdesc->set_err_kind(FWD_DOUBLE_USED); cbp.update_err_kind(a_name,attdesc->get_err_kind()); string desc("It's not supported to have in the same device server process two times the same root attribute ("); desc = desc + a_name + ")"; Except::throw_exception(API_AttrNotAllowed,desc,"RootAttRegistry::add_root_att"); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::clear_attrdesc // // description : // // // argument : // in : // - device_name : The device name // - att_name : The attribute name // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::clear_attrdesc(string &dev_name,string &att_name) { string full_att_name = dev_name + '/' + att_name; cbp.clear_attrdesc(full_att_name); } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::remove_root_att // // description : // Remove a forwarded attribute from the registry // // argument : // in : // - root_dev_name : The root device name // - root_att_name : The root attribute name // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::remove_root_att(string &root_dev_name,string &root_att_name) { string full_root_att_name = root_dev_name + '/' + root_att_name; map::iterator pos = dps.find(root_dev_name); // // Unsubscribe from all user events registered on this forwarded attribute (if any) // if (pos != dps.end()) { map >::iterator it; it = map_event_id_user.find(full_root_att_name); if (it != map_event_id_user.end()) { #ifdef HAS_RANGE_BASE_FOR for (const auto &elem:it->second) { pos->second->unsubscribe_event(elem.event_id); } #else vector::iterator posi; for (posi = it->second.begin();posi != it->second.end();++posi) { pos->second->unsubscribe_event(posi->event_id); } #endif map_event_id_user.erase(it); } } // // Maybe this root device is used by other forwarded attribute in this device server // int co = cbp.count_root_dev(root_dev_name); if (co != 0) cbp.remove_att(full_root_att_name); // // Unsubscribe from the event and if the root device is not used elsewhere, remove its device proxy // map::iterator ite = map_event_id.find(full_root_att_name); if (ite != map_event_id.end()) { if (pos != dps.end()) { pos->second->unsubscribe_event(ite->second); map_event_id.erase(ite); if (co == 1) { delete pos->second; dps.erase(pos); } } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::get_root_att_dp // // description : // Get the DeviceProxy instance used in forwarded attribute from a root device name // Throws exception in case of not // // argument : // in : // - device_name : The device name // // return : // The DeviceProxy pointer. // //-------------------------------------------------------------------------------------------------------------------- DeviceProxy *RootAttRegistry::get_root_att_dp(string &device_name) { map::iterator ite; ite = dps.find(device_name); if (ite == dps.end()) { stringstream ss; ss << device_name << " not registered in map of root attribute devices!"; Except::throw_exception(API_FwdAttrInconsistency,ss.str(),"RootAttRegistry::get_root_att_dp"); } return ite->second; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::get_local_att_name // // description : // Get the local attribute name from a root attribute name // // argument : // in : // - root_name : The root attribute name (root dev_name/att_name) // // return : // The local attribute name // //-------------------------------------------------------------------------------------------------------------------- string RootAttRegistry::RootAttConfCallBack::get_local_att_name(const string &root_name) { map::iterator ite; ite = map_attrdesc.find(root_name); if (ite == map_attrdesc.end()) { stringstream ss; ss << root_name << " not registered in map of root attribute!"; Except::throw_exception(API_FwdAttrInconsistency,ss.str(),"RootAttRegistry::get_local_att_name"); } string loc_name = ite->second.local_name + '/' + ite->second.local_att_name; return loc_name; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::get_local_dev // // description : // Get the local device pointer from a local device name // // argument : // in : // - local_dev_name : The local device name // // return : // The local device ptr // //-------------------------------------------------------------------------------------------------------------------- DeviceImpl *RootAttRegistry::RootAttConfCallBack::get_local_dev(string &local_dev_name) { map::iterator ite; ite = local_dis.find(local_dev_name); if (ite == local_dis.end()) { stringstream ss; ss << local_dev_name << " not registered in map of local device!"; Except::throw_exception(API_FwdAttrInconsistency,ss.str(),"RootAttRegistry::get_local_dev"); } return ite->second; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::RootAttConfCallBack::update_label // // description : // Update the attribute label stored in map_attrdesc map // // argument : // in : // - root_name : The full root attribute name // - new_label : The new label // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::RootAttConfCallBack::update_label(string &root_name,string &new_label) { map::iterator ite; ite = map_attrdesc.find(root_name); if (ite != map_attrdesc.end()) { ite->second.local_label = new_label; } else { stringstream ss; ss << root_name << " not registered in map of root attribute!"; Except::throw_exception(API_FwdAttrInconsistency,ss.str(),"RootAttRegistry::update_label"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::check_root_dev_release // // description : // Check if the root device support IDL 5 or more // // argument : // in : // - root_dev_name : The root device name // // returns : // True if the root device is IDL 5 or more // //-------------------------------------------------------------------------------------------------------------------- bool RootAttRegistry::check_root_dev_release(string &root_dev_name) { bool ret = true; DeviceProxy *dp = get_root_att_dp(root_dev_name); int idl_vers = dp->get_idl_version(); if (idl_vers < MIN_IDL_CONF5) ret = false; return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::is_event_subscribed // // description : // Check if one event is already subscribed // // argument : // in : // - ev : The event name (device_name/att_name) // - et : The event type // // returns : // True if the event is subscribed // //-------------------------------------------------------------------------------------------------------------------- bool RootAttRegistry::is_event_subscribed(string &ev,EventType et) { bool ret = false; map >::iterator pos; { ReaderLock rl(id_user_lock); pos = map_event_id_user.find(ev); if (pos != map_event_id_user.end()) { #ifdef HAS_RANGE_BASE_FOR for (const auto &elem:pos->second) { if (elem.event_type == et) { ret = true; break; } } #else vector::iterator posi; for (posi = pos->second.begin();posi != pos->second.end();++posi) { if (posi->event_type == et) { ret = true; break; } } #endif } } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::subscribe_user_event // // description : // Subscribe to event from the root attribute // // argument : // in : // - dev_name : The root device name // - att_name : The attribute name // - et : The event type // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::subscribe_user_event(string &dev_name,string &att_name,EventType et) { // // Find the proxy and create registered event name // DeviceProxy *dp = get_root_att_dp(dev_name); string f_ev_name = dev_name + '/' + att_name; // // Subscribe to the event and store the event_id in the map. If the att is already known in the map, simply add // one element in the vector of subscribed events // int ev_id; UserEvent ue; ue.event_type = et; try { ev_id = dp->subscribe_event(att_name,et,&cbu); ue.event_id = ev_id; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CantConnectToDevice) { ev_id = dp->subscribe_event(att_name,et,&cbu,true); ue.event_id = ev_id; } else throw; } // // Update map // { WriterLock wl(id_user_lock); map >::iterator pos; pos = map_event_id_user.find(f_ev_name); if (pos == map_event_id_user.end()) { vector v_ue; v_ue.push_back(ue); map_event_id_user.insert(make_pair(f_ev_name,v_ue)); } else { pos->second.push_back(ue); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::unsubscribe_user_event // // description : // Unsubscribe to event from the root attribute // // argument : // in : // - dev_name : The root device name // - att_name : The attribute name // - et : The event type // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::unsubscribe_user_event(string &dev_name,string &att_name,EventType et) { // // Find the proxy and create registered event name // DeviceProxy *dp = get_root_att_dp(dev_name); string f_ev_name = dev_name + '/' + att_name; // // Find the event_id // int local_evid = 0; { ReaderLock rl(id_user_lock); map >::iterator pos; pos = map_event_id_user.find(f_ev_name); vector &v_ue = pos->second; for (size_t loop = 0;loop < v_ue.size();++loop) { if (v_ue[loop].event_type == et) { local_evid = v_ue[loop].event_id; break; } } } if (local_evid == 0) { stringstream ss; ss << f_ev_name << " not found in map of user event on root attribute!"; Except::throw_exception(API_FwdAttrInconsistency,ss.str(),"RootAttRegistry::unsubscribe_user_event"); } // // Unsubscribe to the event. // dp->unsubscribe_event(local_evid); // // Remove entry from vector in map. Eventually remove entry from map if vector becomes empty // { WriterLock wl(id_user_lock); map >::iterator pos; pos = map_event_id_user.find(f_ev_name); vector &v_ue = pos->second; vector::iterator iter; for (iter = v_ue.begin();iter != v_ue.end();++iter) { if (iter->event_type == et) { v_ue.erase(iter); break; } } if (v_ue.empty() == true) { map_event_id_user.erase(pos); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::auto_unsub // // description : // Automatic unsubscription to event(s) on root device(s) // //-------------------------------------------------------------------------------------------------------------------- void RootAttRegistry::auto_unsub() { // // Return immediately if there is no user events // if (map_event_id_user.empty() == true) return; // // A loop on each events // time_t now = time(NULL); { WriterLock wl(id_user_lock); map >::iterator ite; for (ite = map_event_id_user.begin();ite != map_event_id_user.end();++ite) { // // Get local dev_name and att name // string local_name = get_local_att_name(ite->first); string::size_type pos = local_name.rfind('/'); string local_dev_name = local_name.substr(0,pos); string local_att_name = local_name.substr(pos + 1); // // Get Attribute and DeviceImpl objects // DeviceImpl *dev = cbp.get_local_dev(local_dev_name); Attribute &att = dev->get_device_attr()->get_attr_by_name(local_att_name.c_str()); // // A loop on each user event registered for this atttribute // time_t delta_t = 0; vector::iterator posi; for (posi = ite->second.begin();posi < ite->second.end();++posi) { { omni_mutex_lock oml(EventSupplier::get_event_mutex()); switch (posi->event_type) { case CHANGE_EVENT: delta_t = now - att.get_change5_event_sub(); break; case PERIODIC_EVENT: delta_t = now - att.get_periodic5_event_sub(); break; case QUALITY_EVENT: delta_t = now - att.get_quality_event_sub(); break; case ARCHIVE_EVENT: delta_t = now - att.get_archive5_event_sub(); break; case USER_EVENT: delta_t = now - att.get_user5_event_sub(); break; case DATA_READY_EVENT: delta_t = now - att.get_data_ready_event_sub(); break; default: break; } } // // Unsubscribe to the event if the last subscription is too old and erase entry in vector of subscribed events // if (delta_t >= EVENT_RESUBSCRIBE_PERIOD) { string::size_type po = ite->first.rfind('/'); string root_dev = ite->first.substr(0,po); DeviceProxy *dp = get_root_att_dp(root_dev); dp->unsubscribe_event(posi->event_id); posi = ite->second.erase(posi); } } // // Remove entry in map if no more events on this forwarded attribute // if (ite->second.empty() == true) map_event_id_user.erase(ite); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // RootAttRegistry::check_loop // // description : // Check if there is a loop in the root attribute configuration. // This is a one level only check. Could (Should) be imprved to be a n level check // // argument : // in : // - device_name : The device name // - att_name : The attribute name // - local_dev_name : The local device name // - local_att_name : The local attribute name // //-------------------------------------------------------------------------------------------------------------------- bool RootAttRegistry::check_loop(string &device_name,string &att_name,string &local_dev_name,string &local_att_name) { string tg_host; int tg_port; bool ret = false; try { // // Get tango host in the device name and the local one // Util::tango_host_from_fqan(device_name,tg_host,tg_port); Util *tg = Util::instance(); Database *db = tg->get_database(); string db_host = db->get_db_host(); int db_port = db->get_db_port_num(); // // Extract device name from fqdn // string::size_type pos = device_name.find('/',8); string res_dev_name = device_name.substr(pos + 1); // // Retrieve root attribute property // DbData db_data; db_data.push_back(DbDatum(att_name)); if (db_port == tg_port && db_host == tg_host) { db->get_device_attribute_property(res_dev_name,db_data); } else { Database other_db(tg_host,tg_port); other_db.get_device_attribute_property(res_dev_name,db_data); } string new_root_att; DevLong nb_prop; db_data[0] >> nb_prop; if (nb_prop != 0) { bool prop_found = false; for (int k=0;k < nb_prop;k++) { string &prop_name = db_data[k + 1].name; if (prop_name == RootAttrPropName) { db_data[k + 1] >> new_root_att; prop_found = true; break; } } // // If the root attribute property is found, compare it with the local device/local_att name. If they are equal, // it is a loop! // if (prop_found == true) { transform(new_root_att.begin(),new_root_att.end(),new_root_att.begin(),::tolower); string full_local_att_name = local_dev_name + '/' + local_att_name; transform(full_local_att_name.begin(),full_local_att_name.end(),full_local_att_name.begin(),::tolower); if (full_local_att_name == new_root_att) ret = true; } } } catch (Tango::DevFailed &) {} return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/seqvec.cpp0000644023471100065110000001224113034745001014553 00000000000000//============================================================================= // // file : SeqVec.cpp // // description : Dource file for CORBA sequence printing functions. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #if HAVE_CONFIG_H #include #endif #include namespace Tango { // // These functions are not defined within the tango namespace because the VC++ // is not able to understand that the operator overloading functions is defined // within a namespace x from th eoerand namespace (c++ or aCC is able to // do it) // //============================================================================= // // The sequence print facilities functions // // description : These methods allow an easy way to print all sequence // element using the following syntax // cout << seq << endl; // //============================================================================= ostream &operator<<(ostream &o,const DevVarCharArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << (short)v[i] << dec; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarLongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarLong64Array &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarFloatArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarDoubleArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarBooleanArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = "; if (v[i] == true) o << "true"; else o << "false"; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarUShortArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarULongArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarULong64Array &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarStringArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i].in(); if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarStateArray &v) { long nb_elt = v.length(); for (long i = 0;i < nb_elt;i++) { o << "Element number [" << i << "] = " << v[i]; if (i < (nb_elt - 1)) o << '\n'; } return o; } ostream &operator<<(ostream &o,const DevVarEncodedArray &v) { long nb_elt = v.length(); for (long loop = 0;loop < nb_elt;loop++) { o << "Encoding string: " << v[loop].encoded_format << endl; long nb_data_elt = v[loop].encoded_data.length(); for (long i = 0;i < nb_data_elt;i++) { o << "Data element number [" << i << "] = " << (int)v[loop].encoded_data[i]; if (i < (nb_data_elt - 1)) o << '\n'; } if (loop < (nb_elt - 1)) o << '\n'; } return o; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/subdev_diag.cpp0000644023471100065110000003375513034745001015556 00000000000000static const char *RcsId = "$Id: subdev_diag.cpp 28853 2015-12-07 13:38:45Z taurel $\n$Name$"; //+============================================================================= // // file : subdev_diag.cpp // // description : Collect information on all used sub devices // in a device server. // // project : TANGO // // author(s) : J.Meyer // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include extern omni_thread::key_t key_py_data; namespace Tango { //+---------------------------------------------------------------------------- // // method : SubDevDiag::~SubDevDiag() // // description : Destructor to free the map data // //----------------------------------------------------------------------------- SubDevDiag::~SubDevDiag() { cout4 << "SubDevDiag::~SubDevDiag() entering ... " << endl; // lock the sub device map omni_mutex_lock l(sub_dev_map_mutex); // remove all sub devices sub_device_map.clear(); sub_device_startup_map.clear(); } //+---------------------------------------------------------------------------- // // method : SubDevDiag::set_associated_device() // // description : Set the device name that should be asscociated // to a thread in the device server // // in : dev_name - device name // //----------------------------------------------------------------------------- void SubDevDiag::set_associated_device(string dev_name) { cout4 << "SubDevDiag::set_associated_device() entering ... "; // get thread omni_thread *th = omni_thread::self(); if ( th != NULL ) { // write the device name to the per thread data structure omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); if ( tmp_py_data != NULL ) (static_cast(tmp_py_data))->device_name = dev_name; } } //+---------------------------------------------------------------------------- // // method : SubDevDiag::get_associated_device() // // description : Get the device name that is asscociated // with the current thread of the device server // // return : associated device name // //----------------------------------------------------------------------------- string SubDevDiag::get_associated_device() { cout4 << "SubDevDiag::get_associated_device() entering ... " << endl; string dev_name = ""; // get thread omni_thread *th = omni_thread::self(); if ( th != NULL ) { // read the device name from the per thread data structure omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); if ( tmp_py_data != NULL ) dev_name = (static_cast(tmp_py_data))->device_name; } cout4 << "SubDevDiag::get_associated_device() found : " << dev_name << endl; return dev_name; } //+---------------------------------------------------------------------------- // // method : SubDevDiag::register_sub_device() // // description : Register a sub device for an associated device // in the list of sub devices of the device server // // in : dev_name = associated device name // sub_dev_name = sub device name // //----------------------------------------------------------------------------- void SubDevDiag::register_sub_device (string dev_name, string sub_dev_name) { cout4 << "SubDevDiag::register_sub_device() dev_name = " << dev_name << " sub_dev_name = "<< sub_dev_name << endl; bool found = false; // be sure that all names are lower case letters std::transform(dev_name.begin(), dev_name.end(), dev_name.begin(), ::tolower); std::transform(sub_dev_name.begin(), sub_dev_name.end(), sub_dev_name.begin(), ::tolower); // lock the sub device map omni_mutex_lock l(sub_dev_map_mutex); // Find whether a sub device list for the device is already available std::map::iterator ipos; ipos = sub_device_map.find(dev_name); if (ipos == sub_device_map.end()) { // device not known, add a new sub device sub_device_map[dev_name].sub_devices.push_back(sub_dev_name); sub_device_map[dev_name].modified = true; } else { // Check whether the sub device name is alreay in the list for (unsigned int i=0; isecond.sub_devices.size(); i++ ) { if (ipos->second.sub_devices[i] == sub_dev_name) { // Name is already in the list found = true; break; } } if ( found == false) { // name is not in the list, add the sub device ipos->second.sub_devices.push_back(sub_dev_name); ipos->second.modified = true; } } } //+---------------------------------------------------------------------------- // // method : SubDevDiag::remove_sub_devices() // // description : Remove all sub devices for a device of the server // // in : dev_name = device name // //----------------------------------------------------------------------------- void SubDevDiag::remove_sub_devices (string dev_name) { cout4 << "SubDevDiag::remove_sub_device() dev_name = " << dev_name << endl; // be sure that all names are lower case letters std::transform(dev_name.begin(), dev_name.end(), dev_name.begin(), ::tolower); // lock the sub device map omni_mutex_lock l(sub_dev_map_mutex); // remove the list of sub devices for a device std::map::iterator ipos; ipos = sub_device_map.find(dev_name); if (ipos != sub_device_map.end()) { sub_device_map.erase(ipos); } } //+---------------------------------------------------------------------------- // // method : SubDevDiag::remove_sub_devices() // // description : Remove all sub devices of the server // // in : dev_name = device name // //----------------------------------------------------------------------------- void SubDevDiag::remove_sub_devices() { cout4 << "SubDevDiag::remove_sub_devices() remove ALL " << endl; // lock the sub device map omni_mutex_lock l(sub_dev_map_mutex); // remove all sub devices sub_device_map.clear(); } //+---------------------------------------------------------------------------- // // method : SubDevDiag::get_sub_devices() // // description : Read the list of sub devices for the device server // The returned strings are formated as: // "device_name sub_device_name" // or // sub_device_name // when no associated device could be identified. // // return : An array of formated strings // //----------------------------------------------------------------------------- Tango::DevVarStringArray *SubDevDiag::get_sub_devices() { cout4 << "SubDevDiag::get_sub_devices() entering ... " << endl; Tango::DevVarStringArray *ret; vector sub_dev_list; string tmp; // lock the sub device map omni_mutex_lock l(sub_dev_map_mutex); try { std::map::iterator ipos; for (ipos = sub_device_map.begin(); ipos != sub_device_map.end(); ++ipos) { for (unsigned int i=0; isecond.sub_devices.size(); i++) { if ( ipos->first.empty() ) tmp = ipos->second.sub_devices[i]; else tmp = ipos->first + " " + ipos->second.sub_devices[i]; sub_dev_list.push_back (tmp); } } ret = new Tango::DevVarStringArray(DefaultMaxSeq); ret->length(sub_dev_list.size()); for (unsigned int k = 0; k::iterator ipos; for (ipos = sub_device_map.begin(); ipos != sub_device_map.end(); ++ipos) { // Check whether the list was modified if ( ipos->second.modified == true ) { // Check whether for modifications compared to // the list read into db_cache during startup // check the number of sub devices if ( ipos->second.sub_devices.size() == sub_device_startup_map[ipos->first].sub_devices.size() ) { // find sub device names in the start-up list bool is_equal = true; for ( unsigned int i=0; isecond.sub_devices.size(); i++ ) { bool found = false; for ( unsigned int k=0; kfirst].sub_devices.size(); k++ ) { if (ipos->second.sub_devices[i] == sub_device_startup_map[ipos->first].sub_devices[k]) { found = true; break; } } if ( found == false ) { is_equal = false; break; } } if ( is_equal == true ) { // sub device names are equal to the names // read from the database at server start-up. // Clear the modification flag ipos->second.modified = false; continue; } } // write the sub device list as device property try { DbDatum list ("__SubDevices"); DbData db_data; list << ipos->second.sub_devices; db_data.push_back(list); // Check for a valid database object. // In the database server itself or any server // running without a database the database object is // not initialised. if ( Tango::Util::_UseDb == true ) { if ( ipos->first.empty() ) { DServer *adm_dev = tg->get_dserver_device(); tg->get_database()->put_device_property (adm_dev->get_name(), db_data); } else { tg->get_database()->put_device_property (ipos->first, db_data); } } // clear the modification flag ipos->second.modified = false; } catch (Tango::DevFailed &) {} } } } //+---------------------------------------------------------------------------- // // method : SubDevDiag::get_sub_devices_from_cache() // // description : Read the list of sub devices from the // database cache. The cache is filled at // server sart-up. // //----------------------------------------------------------------------------- void SubDevDiag::get_sub_devices_from_cache() { cout4 << "SubDevDiag::get_sub_devices_from_cache() entering ... " << endl; DbServerCache *db_cache; Tango::Util *tg = Tango::Util::instance(); try { db_cache = tg->get_db_cache(); } catch (Tango::DevFailed &e) { Except::print_exception(e); db_cache = NULL; } if (db_cache != NULL) { // get the name of the admin device DServer *adm_dev = tg->get_dserver_device(); string adm_name = adm_dev->get_name(); // be sure that all names are lower case letters std::transform(adm_name.begin(), adm_name.end(), adm_name.begin(), ::tolower); // get all devices served vector dev_list = tg->get_device_list("*"); for (unsigned int k=0; kget_name(); // be sure that all names are lower case letters std::transform(dev_name.begin(), dev_name.end(), dev_name.begin(), ::tolower); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(2); (*property_names)[0] = string_dup(dev_name.c_str()); (*property_names)[1] = string_dup("__SubDevices"); try { const DevVarStringArray *property_values = db_cache->get_dev_property(property_names); if ( atol((*property_values)[3]) > 0 ) { // if the device is the admin device, set dev_name to "" // to have the same syntax as in the dynamically created // sub device map. if ( dev_name == adm_name ) dev_name = ""; for (unsigned int i=4; ilength(); i++) { sub_device_startup_map[dev_name].sub_devices.push_back((*property_values)[i].in()); } } } catch(Tango::DevFailed &) { cerr << "Sub device not found in DB cache for " << dev_name << endl; } delete property_names; } } else cerr << "No database cache found to initialise sub device map!" << endl; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/tangoappender.cpp0000644023471100065110000001225713034745002016124 00000000000000static const char *RcsId = "$Id: tangoappender.cpp 28423 2015-09-02 15:05:25Z taurel $\n$Name$"; //+============================================================================= // // file : tangoappender.cpp // // description : // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // // $Revision: 28423 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #ifdef TANGO_HAS_LOG4TANGO #include #define USE_ASYNC_CALL namespace Tango { TangoAppender::TangoAppender (const std::string& src_name, const std::string& name, const std::string& dev_name, bool open_connection) : log4tango::Appender(name), _dev_name(dev_name), _src_name(src_name), _dev_proxy(0) { _req_ctr = 0; if (open_connection == true) reopen(); } TangoAppender::~TangoAppender () { close(); } bool TangoAppender::requires_layout (void) const { return false; } void TangoAppender::set_layout (log4tango::Layout*) { // no-op } bool TangoAppender::is_valid (void) const { if (!_dev_proxy) { return false; } try { _dev_proxy->ping(); } catch (...) { return false; } return true; } int TangoAppender::_append (const log4tango::LoggingEvent& event) { //------------------------------------------------------------ //- DO NOT LOG FROM THIS METHOD !!! //------------------------------------------------------------ if (!_dev_proxy) { //--DO NOT RETURN -1 (ERROR ALREADY HANDLED) return 0; } try { Tango::DevVarStringArray *dvsa = new Tango::DevVarStringArray(6); if (dvsa) { dvsa->length(6); double ts_ms = 1000. * event.timestamp.get_seconds(); ts_ms += event.timestamp.get_milliseconds(); TangoSys_OMemStream ts_ms_str; ts_ms_str << std::fixed << std::noshowpoint << std::setprecision(0) << ts_ms << ends; string st = ts_ms_str.str(); (*dvsa)[0] = CORBA::string_dup(st.c_str()); (*dvsa)[1] = CORBA::string_dup(log4tango::Level::get_name(event.level).c_str()); (*dvsa)[2] = CORBA::string_dup(event.logger_name.c_str()); (*dvsa)[3] = CORBA::string_dup(event.message.c_str()); (*dvsa)[4] = CORBA::string_dup(""); omni_thread* ct = omni_thread::self(); if (ct) { TangoSys_OMemStream ctstr; ctstr << "@" << hex << event.thread_id << " [" << ct->id() << "]"<< ends; string st = ctstr.str(); (*dvsa)[5] = CORBA::string_dup(st.c_str()); } else { (*dvsa)[5] = CORBA::string_dup("unknown"); } DeviceData argin; argin << dvsa; #ifdef USE_ASYNC_CALL _dev_proxy->command_inout_asynch("Log", argin, false); _req_ctr++; if ((_req_ctr % 10) == 0) _dev_proxy->cancel_all_polling_asynch_request(); #else _dev_proxy->command_inout("Log", argin); #endif } } catch (...) { close(); return -1; } return 0; } bool TangoAppender::reopen (void) { bool result = true; try { close(); _dev_proxy = new DeviceProxy(const_cast(_dev_name)); try { DeviceData argin; argin << const_cast(_src_name); #ifdef USE_ASYNC_CALL _dev_proxy->command_inout_asynch("Register", argin, true); #else _dev_proxy->command_inout("Register", argin); #endif } catch (...) { } } catch (...) { close(); result = false; } return result; } void TangoAppender::close (void) { if (_dev_proxy) { try { DeviceData argin; argin << const_cast(_src_name); #ifdef USE_ASYNC_CALL _dev_proxy->command_inout_asynch("UnRegister", argin, true); #else _dev_proxy->command_inout("UnRegister", argin); #endif } catch (...) { // Ignore error: some old logviewer may not support UnRegister } delete _dev_proxy; _dev_proxy = 0; } } } // namespace tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/tangorollingfileappender.cpp0000644023471100065110000000406713034745001020352 00000000000000static const char *RcsId = "$Id: tangorollingfileappender.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : tangorollingfileappender.cpp // // description : Implementation of the DServer logging oriented commands // // project : TANGO // // author(s) : N.Leclercq - SOLEIL // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #ifdef TANGO_HAS_LOG4TANGO #include namespace Tango { TangoRollingFileAppender::TangoRollingFileAppender(const std::string& name, const std::string& fileName, size_t maxFileSize) : log4tango::RollingFileAppender(name, fileName, maxFileSize * 1024) { // no-op } TangoRollingFileAppender::~TangoRollingFileAppender() { // no-op } bool TangoRollingFileAppender::isValid (void) const { return (_fd < 0) ? false : true; } } // namespace tango #endif // TANGO_HAS_LOG4TANGO tango-9.2.5a/lib/cpp/server/templ_inst.cpp0000644023471100065110000016453713034745001015463 00000000000000//+================================================================================================================= // // file : templ_inst.cpp // // description : C++ source code to instantiate template methods/class in order to have explicit instanciation // This makes user life easier in term of getting bug fixes (no re-compilation needed) // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28855 $ // //-================================================================================================================== // // For template management we have several files: // - A file with explicit template instanciation. This file (templ_inst.cpp) // For class with templates: // - A file with template methods/class definition (attribute.tpp for Attribute class) // - A file with template methods/class specialization definition (attribute_spec.tpp for Attribute class) // // We did this in order to have explicit instanciation of templates method except for specialized templates // for which we have instanciation following the inclusion model // See C++ template book chapter 6 // #include #include #include #include #include #include #include #include namespace Tango { // // The DevEncoded and DevString data types are not there. DevString is handle by 2 (for const) classic methods // forwarding the call to the same method using string data type as parameter. DevEncoded and string are // managed as specialized templates // #define TEMPL_EXPL_METH_INST_CONST(CLASS,METH) \ template void CLASS::METH(const DevBoolean &); \ template void CLASS::METH(const DevUChar &); \ template void CLASS::METH(const DevShort &); \ template void CLASS::METH(const DevUShort &); \ template void CLASS::METH(const DevLong &); \ template void CLASS::METH(const DevULong &); \ template void CLASS::METH(const DevLong64 &); \ template void CLASS::METH(const DevULong64 &); \ template void CLASS::METH(const DevFloat &); \ template void CLASS::METH(const DevDouble &); \ template void CLASS::METH(const DevState &); #define TEMPL_EXPL_METH_INST(CLASS,METH) \ template void CLASS::METH(DevBoolean &); \ template void CLASS::METH(DevUChar &); \ template void CLASS::METH(DevShort &); \ template void CLASS::METH(DevUShort &); \ template void CLASS::METH(DevLong &); \ template void CLASS::METH(DevULong &); \ template void CLASS::METH(DevLong64 &); \ template void CLASS::METH(DevULong64 &); \ template void CLASS::METH(DevFloat &); \ template void CLASS::METH(DevDouble &); \ template void CLASS::METH(DevState &); \ template void CLASS::METH(DevString &); \ template void CLASS::METH(DevEncoded &); #define TEMPL_EXPL_CLASS_INST(CLASS) \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; //template class CLASS; //template class CLASS; #define TEMPL_EXPL_CMD_CLASS_INST(CLASS) \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; \ template class CLASS; RANGES_TYPE2CONST(Tango::DevDouble,DEV_DOUBLE) RANGES_TYPE2CONST(Tango::DevFloat,DEV_FLOAT) RANGES_TYPE2CONST(Tango::DevLong,DEV_LONG) RANGES_TYPE2CONST(Tango::DevLong64,DEV_LONG64) RANGES_TYPE2CONST(Tango::DevShort,DEV_SHORT) RANGES_TYPE2CONST(Tango::DevUChar,DEV_UCHAR) RANGES_TYPE2CONST(Tango::DevULong,DEV_ULONG) RANGES_TYPE2CONST(Tango::DevULong64,DEV_ULONG64) RANGES_TYPE2CONST(Tango::DevUShort,DEV_USHORT) RANGES_TYPE2CONST(Tango::DevEncoded,DEV_ENCODED) RANGES_TYPE2CONST(Tango::DevBoolean,DEV_BOOLEAN) RANGES_TYPE2CONST(Tango::DevString,DEV_STRING) RANGES_TYPE2CONST(Tango::DevState,DEV_STATE) //+---------------------------------------------------------------------------- // // Instanciate Attribute::XXX methods and associate template classes // //----------------------------------------------------------------------------- TEMPL_EXPL_METH_INST(Attribute,get_min_alarm) TEMPL_EXPL_METH_INST(Attribute,get_max_alarm) TEMPL_EXPL_METH_INST(Attribute,get_min_warning) TEMPL_EXPL_METH_INST(Attribute,get_max_warning) TEMPL_EXPL_METH_INST_CONST(Attribute,set_min_alarm) TEMPL_EXPL_METH_INST_CONST(Attribute,set_max_alarm) TEMPL_EXPL_METH_INST_CONST(Attribute,set_min_warning) TEMPL_EXPL_METH_INST_CONST(Attribute,set_max_warning) TEMPL_EXPL_CLASS_INST(AttrProp) TEMPL_EXPL_CLASS_INST(DoubleAttrProp) TEMPL_EXPL_CLASS_INST(MultiAttrProp) template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::get_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::set_properties(MultiAttrProp &); template void Attribute::check_hard_coded_properties(const AttributeConfig &); template void Attribute::check_hard_coded_properties(const AttributeConfig_3 &); template void Attribute::set_hard_coded_properties(const AttributeConfig &); template void Attribute::set_hard_coded_properties(const AttributeConfig_3 &); template void Attribute::set_upd_properties(const AttributeConfig &,string &,bool); template void Attribute::set_upd_properties(const AttributeConfig_3 &,string &,bool); template void Attribute::set_upd_properties(const AttributeConfig_5 &,string &,bool); template void Attribute::Attribute_2_AttributeValue_base(AttributeValue_4 *,Tango::DeviceImpl *); template void Attribute::Attribute_2_AttributeValue_base(AttributeValue_5 *,Tango::DeviceImpl *); template void Attribute::AttrValUnion_fake_copy(const AttributeValue_5 *,AttributeValue_4 *); template void Attribute::AttrValUnion_fake_copy(const AttributeValue_4 *,AttributeValue_5 *); template void Attribute::AttrValUnion_2_Any(const AttributeValue_4 *,CORBA::Any &); template void Attribute::AttrValUnion_2_Any(const AttributeValue_5 *,CORBA::Any &); //+---------------------------------------------------------------------------- // // Instanciate Util::fill_XXX_polling buffers methods and associate template classes // //----------------------------------------------------------------------------- TEMPL_EXPL_CLASS_INST(AttrData) TEMPL_EXPL_CLASS_INST(TimedAttrData) TEMPL_EXPL_CLASS_INST(AttrHistoryStack) template class AttrData; template class AttrData; template class TimedAttrData; template class TimedAttrData; template class AttrHistoryStack; template class AttrHistoryStack; template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); template void Util::fill_attr_polling_buffer(DeviceImpl *,string &,AttrHistoryStack &); TEMPL_EXPL_CMD_CLASS_INST(TimedCmdData) TEMPL_EXPL_CMD_CLASS_INST(CmdHistoryStack) template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); template void Util::fill_cmd_polling_buffer(DeviceImpl *,string &,CmdHistoryStack &); //+---------------------------------------------------------------------------- // // Instanciate WAttribute::XXX methods // //----------------------------------------------------------------------------- TEMPL_EXPL_METH_INST(WAttribute,get_min_value) TEMPL_EXPL_METH_INST(WAttribute,get_max_value) TEMPL_EXPL_METH_INST_CONST(WAttribute,set_min_value) TEMPL_EXPL_METH_INST_CONST(WAttribute,set_max_value) template void WAttribute::check_min_max(const unsigned int,const DevVarLongArray &,const DevLong &,const DevLong &); template void WAttribute::check_min_max(const unsigned int,const DevVarShortArray &,const short &,const short &); template void WAttribute::check_min_max(const unsigned int,const DevVarLong64Array &,const DevLong64 &,const DevLong64 &); template void WAttribute::check_min_max(const unsigned int,const DevVarUShortArray &,const unsigned short &,const unsigned short &); template void WAttribute::check_min_max(const unsigned int,const DevVarCharArray &,const unsigned char &,const unsigned char &); template void WAttribute::check_min_max(const unsigned int,const DevVarULongArray &,const DevULong &,const DevULong &); template void WAttribute::check_min_max(const unsigned int,const DevVarULong64Array &,const DevULong64 &,const DevULong64 &); template void WAttribute::check_min_max(const unsigned int,const DevVarStateArray &,const DevState &,const DevState &); //+---------------------------------------------------------------------------- // // Instanciate DevicePipe helper functions // //----------------------------------------------------------------------------- template DevicePipe &operator<<(DevicePipe &,DevBoolean &); template DevicePipe &operator<<(DevicePipe &,short &); template DevicePipe &operator<<(DevicePipe &,DevLong &); template DevicePipe &operator<<(DevicePipe &,DevLong64 &); template DevicePipe &operator<<(DevicePipe &,float &); template DevicePipe &operator<<(DevicePipe &,double &); template DevicePipe &operator<<(DevicePipe &,DevUChar &); template DevicePipe &operator<<(DevicePipe &,DevUShort &); template DevicePipe &operator<<(DevicePipe &,DevULong &); template DevicePipe &operator<<(DevicePipe &,DevULong64 &); template DevicePipe &operator<<(DevicePipe &,DevString &); template DevicePipe &operator<<(DevicePipe &,DevState &); template DevicePipe &operator<<(DevicePipe &,DevEncoded &); template DevicePipe &operator<<(DevicePipe &,string &); template DevicePipe &operator<<(DevicePipe &,DevicePipeBlob &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,vector &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DataElement > &); template DevicePipe &operator<<(DevicePipe &,DevVarBooleanArray &); template DevicePipe &operator<<(DevicePipe &,DevVarShortArray &); template DevicePipe &operator<<(DevicePipe &,DevVarLongArray &); template DevicePipe &operator<<(DevicePipe &,DevVarLong64Array &); template DevicePipe &operator<<(DevicePipe &,DevVarFloatArray &); template DevicePipe &operator<<(DevicePipe &,DevVarDoubleArray &); template DevicePipe &operator<<(DevicePipe &,DevVarUCharArray &); template DevicePipe &operator<<(DevicePipe &,DevVarUShortArray &); template DevicePipe &operator<<(DevicePipe &,DevVarULongArray &); template DevicePipe &operator<<(DevicePipe &,DevVarULong64Array &); template DevicePipe &operator<<(DevicePipe &,DevVarStringArray &); template DevicePipe &operator<<(DevicePipe &,DevVarStateArray &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DevVarBooleanArray *); template DevicePipe &operator<<(DevicePipe &,DevVarShortArray *); template DevicePipe &operator<<(DevicePipe &,DevVarLongArray *); template DevicePipe &operator<<(DevicePipe &,DevVarLong64Array *); template DevicePipe &operator<<(DevicePipe &,DevVarFloatArray *); template DevicePipe &operator<<(DevicePipe &,DevVarDoubleArray *); template DevicePipe &operator<<(DevicePipe &,DevVarUCharArray *); template DevicePipe &operator<<(DevicePipe &,DevVarUShortArray *); template DevicePipe &operator<<(DevicePipe &,DevVarULongArray *); template DevicePipe &operator<<(DevicePipe &,DevVarULong64Array *); template DevicePipe &operator<<(DevicePipe &,DevVarStringArray *); template DevicePipe &operator<<(DevicePipe &,DevVarStateArray *); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); template DevicePipe &operator<<(DevicePipe &,DataElement &); //----------------------------------------------------------------------------------------------------- // // Note that there is no instanciation for type DevString. For this type, a non template method has been written // Otherwise, due the partial specialization for pointer types, it was not possible to use extracttion into // DevString type // template DevicePipe &operator>>(DevicePipe &,DevBoolean &); template DevicePipe &operator>>(DevicePipe &,short &); template DevicePipe &operator>>(DevicePipe &,DevLong &); template DevicePipe &operator>>(DevicePipe &,DevLong64 &); template DevicePipe &operator>>(DevicePipe &,float &); template DevicePipe &operator>>(DevicePipe &,double &); template DevicePipe &operator>>(DevicePipe &,DevUChar &); template DevicePipe &operator>>(DevicePipe &,DevUShort &); template DevicePipe &operator>>(DevicePipe &,DevULong &); template DevicePipe &operator>>(DevicePipe &,DevULong64 &); // Missing DevString (see above) template DevicePipe &operator>>(DevicePipe &,DevState &); template DevicePipe &operator>>(DevicePipe &,DevEncoded &); template DevicePipe &operator>>(DevicePipe &,string &); template DevicePipe &operator>>(DevicePipe &,DevicePipeBlob &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,vector &); //template DevicePipe &operator>>(DevicePipe &,vector &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DataElement > &); //template DevicePipe &operator>>(DevicePipe &,DataElement > &); template DevicePipe &operator>>(DevicePipe &,DevVarBooleanArray *); template DevicePipe &operator>>(DevicePipe &,DevVarShortArray *); template DevicePipe &operator>>(DevicePipe &,DevVarLongArray *); template DevicePipe &operator>>(DevicePipe &,DevVarLong64Array *); template DevicePipe &operator>>(DevicePipe &,DevVarFloatArray *); template DevicePipe &operator>>(DevicePipe &,DevVarDoubleArray *); template DevicePipe &operator>>(DevicePipe &,DevVarUCharArray *); template DevicePipe &operator>>(DevicePipe &,DevVarUShortArray *); template DevicePipe &operator>>(DevicePipe &,DevVarULongArray *); template DevicePipe &operator>>(DevicePipe &,DevVarULong64Array *); template DevicePipe &operator>>(DevicePipe &,DevVarStringArray *); template DevicePipe &operator>>(DevicePipe &,DevVarStateArray *); //template DevicePipe &operator>>(DevicePipe &,DevVarEncodedArray *); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); template DevicePipe &operator>>(DevicePipe &,DataElement &); //template DevicePipe &operator>>(DevicePipe &,DataElement &); //+---------------------------------------------------------------------------- // // Instanciate DevicePipeBlob helper functions // //----------------------------------------------------------------------------- template DevicePipeBlob &operator<<(DevicePipeBlob &,DevBoolean &); template DevicePipeBlob &operator<<(DevicePipeBlob &,short &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevLong &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevLong64 &); template DevicePipeBlob &operator<<(DevicePipeBlob &,float &); template DevicePipeBlob &operator<<(DevicePipeBlob &,double &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevUChar &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevUShort &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevULong &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevULong64 &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevString &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevState &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevEncoded &); template DevicePipeBlob &operator<<(DevicePipeBlob &,const string &); template DevicePipeBlob &operator<<(DevicePipeBlob &,string &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevicePipeBlob &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); //template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,vector &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); //template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarBooleanArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarShortArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarLongArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarLong64Array &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarFloatArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarDoubleArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarUCharArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarUShortArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarULongArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarULong64Array &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarStringArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarStateArray &); //template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarEncodedArray &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); //template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarBooleanArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarShortArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarLongArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarLong64Array *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarFloatArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarDoubleArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarUCharArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarUShortArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarULongArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarULong64Array *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarStringArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarStateArray *); //template DevicePipeBlob &operator<<(DevicePipeBlob &,DevVarEncodedArray *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); //template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); //------------------------------------------------------------------------------------------- template DevicePipeBlob &operator>>(DevicePipeBlob &,DevBoolean &); template DevicePipeBlob &operator>>(DevicePipeBlob &,short &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevLong &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevLong64 &); template DevicePipeBlob &operator>>(DevicePipeBlob &,float &); template DevicePipeBlob &operator>>(DevicePipeBlob &,double &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevUChar &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevUShort &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevULong &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevULong64 &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevString &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevState &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevEncoded &); template DevicePipeBlob &operator>>(DevicePipeBlob &,string &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevicePipeBlob &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); //template DevicePipeBlob &operator>>(DevicePipeBlob &,vector &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); //template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement > &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarBooleanArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarShortArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarLongArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarLong64Array *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarFloatArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarDoubleArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarUCharArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarUShortArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarULongArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarULong64Array *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarStringArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarStateArray *); //template DevicePipeBlob &operator>>(DevicePipeBlob &,DevVarEncodedArray *); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); //template DevicePipeBlob &operator>>(DevicePipeBlob &,DataElement &); //+---------------------------------------------------------------------------- // // Instanciate WPipe helper functions // //----------------------------------------------------------------------------- template WPipe &operator>>(WPipe &,DevBoolean &); template WPipe &operator>>(WPipe &,short &); template WPipe &operator>>(WPipe &,DevLong &); template WPipe &operator>>(WPipe &,DevLong64 &); template WPipe &operator>>(WPipe &,float &); template WPipe &operator>>(WPipe &,double &); template WPipe &operator>>(WPipe &,DevUChar &); template WPipe &operator>>(WPipe &,DevUShort &); template WPipe &operator>>(WPipe &,DevULong &); template WPipe &operator>>(WPipe &,DevULong64 &); template WPipe &operator>>(WPipe &,DevString &); template WPipe &operator>>(WPipe &,DevState &); template WPipe &operator>>(WPipe &,DevEncoded &); template WPipe &operator>>(WPipe &,string &); template WPipe &operator>>(WPipe &,DevicePipeBlob &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,vector &); //template WPipe &operator>>(WPipe &,vector &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DataElement > &); //template WPipe &operator>>(WPipe &,DataElement > &); template WPipe &operator>>(WPipe &,DevVarBooleanArray *); template WPipe &operator>>(WPipe &,DevVarShortArray *); template WPipe &operator>>(WPipe &,DevVarLongArray *); template WPipe &operator>>(WPipe &,DevVarLong64Array *); template WPipe &operator>>(WPipe &,DevVarFloatArray *); template WPipe &operator>>(WPipe &,DevVarDoubleArray *); template WPipe &operator>>(WPipe &,DevVarUCharArray *); template WPipe &operator>>(WPipe &,DevVarUShortArray *); template WPipe &operator>>(WPipe &,DevVarULongArray *); template WPipe &operator>>(WPipe &,DevVarULong64Array *); template WPipe &operator>>(WPipe &,DevVarStringArray *); template WPipe &operator>>(WPipe &,DevVarStateArray *); //template WPipe &operator>>(WPipe &,DevVarEncodedArray *); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); template WPipe &operator>>(WPipe &,DataElement &); //template WPipe &operator>>(WPipe &,DataElement &); //+---------------------------------------------------------------------------- // // Instanciate Pipe helper functions // //----------------------------------------------------------------------------- template Pipe &operator<<(Pipe &,DevBoolean &); template Pipe &operator<<(Pipe &,short &); template Pipe &operator<<(Pipe &,DevLong &); template Pipe &operator<<(Pipe &,DevLong64 &); template Pipe &operator<<(Pipe &,float &); template Pipe &operator<<(Pipe &,double &); template Pipe &operator<<(Pipe &,DevUChar &); template Pipe &operator<<(Pipe &,DevUShort &); template Pipe &operator<<(Pipe &,DevULong &); template Pipe &operator<<(Pipe &,DevULong64 &); template Pipe &operator<<(Pipe &,DevString &); template Pipe &operator<<(Pipe &,DevState &); template Pipe &operator<<(Pipe &,DevEncoded &); template Pipe &operator<<(Pipe &,const string &); template Pipe &operator<<(Pipe &,DevicePipeBlob &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); //template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,vector &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); //template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DataElement > &); template Pipe &operator<<(Pipe &,DevVarBooleanArray &); template Pipe &operator<<(Pipe &,DevVarShortArray &); template Pipe &operator<<(Pipe &,DevVarLongArray &); template Pipe &operator<<(Pipe &,DevVarLong64Array &); template Pipe &operator<<(Pipe &,DevVarFloatArray &); template Pipe &operator<<(Pipe &,DevVarDoubleArray &); template Pipe &operator<<(Pipe &,DevVarUCharArray &); template Pipe &operator<<(Pipe &,DevVarUShortArray &); template Pipe &operator<<(Pipe &,DevVarULongArray &); template Pipe &operator<<(Pipe &,DevVarULong64Array &); template Pipe &operator<<(Pipe &,DevVarStringArray &); template Pipe &operator<<(Pipe &,DevVarStateArray &); //template Pipe &operator<<(Pipe &,DevVarEncodedArray &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); //template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DevVarBooleanArray *); template Pipe &operator<<(Pipe &,DevVarShortArray *); template Pipe &operator<<(Pipe &,DevVarLongArray *); template Pipe &operator<<(Pipe &,DevVarLong64Array *); template Pipe &operator<<(Pipe &,DevVarFloatArray *); template Pipe &operator<<(Pipe &,DevVarDoubleArray *); template Pipe &operator<<(Pipe &,DevVarUCharArray *); template Pipe &operator<<(Pipe &,DevVarUShortArray *); template Pipe &operator<<(Pipe &,DevVarULongArray *); template Pipe &operator<<(Pipe &,DevVarULong64Array *); template Pipe &operator<<(Pipe &,DevVarStringArray *); template Pipe &operator<<(Pipe &,DevVarStateArray *); //template Pipe &operator<<(Pipe &,DevVarEncodedArray *); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); template Pipe &operator<<(Pipe &,DataElement &); //template Pipe &operator<<(Pipe &,DataElement &); //+---------------------------------------------------------------------------- // // Instanciate DataElement helper functions // //----------------------------------------------------------------------------- template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); //template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); #ifndef _TG_WINDOWS_ template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); #endif template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); //template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement &); //template ostream &operator<<(ostream &,DataElement &); } // End of Tango namespace tango-9.2.5a/lib/cpp/server/thsig.cpp0000644023471100065110000001175513034745002014415 00000000000000static const char *RcsId = "$Id: thsig.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================= // // file : thsig.cpp // // description : C++ source for the DServer class and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on a // DServer object are implemented in this file. // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #include extern omni_thread::key_t key_py_data; namespace Tango { void *DServerSignal::ThSig::run_undetached(TANGO_UNUSED(void *ptr)) { #ifndef _TG_WINDOWS_ sigset_t sigs_to_catch; // // Catch main signals // sigemptyset(&sigs_to_catch); sigaddset(&sigs_to_catch,SIGINT); sigaddset(&sigs_to_catch,SIGTERM); sigaddset(&sigs_to_catch,SIGHUP); sigaddset(&sigs_to_catch,SIGQUIT); // // Init thread id and pid (for linux !!) // my_thread = pthread_self(); { omni_mutex_lock syn(*ds); my_pid = getpid(); ds->signal(); } #endif int signo = 0; // // The infinite loop // while(1) { #ifndef _TG_WINDOWS_ int ret = sigwait(&sigs_to_catch,&signo); // sigwait() under linux might return an errno number without initialising the // signo variable. Do a ckeck here to avoid problems!!! if ( ret != 0 ) { cout4 << "Signal thread awaken on error " << ret << endl; continue; } cout4 << "Signal thread awaken for signal " << signo << endl; if (signo == SIGHUP) continue; #else WaitForSingleObject(ds->win_ev,INFINITE); signo = ds->win_signo; cout4 << "Signal thread awaken for signal " << signo << endl; #endif // // Create the per thread data if not already done // if (th_data_created == false) { omni_thread::self()->set_value(key_py_data,new PyData()); th_data_created = true; } #ifndef _TG_WINDOWS_ // // Add a new signal to catch in the mask // { omni_mutex_lock sy(*ds); if (signo == SIGINT) { bool job_done = false; if (ds->sig_to_install == true) { ds->sig_to_install = false; sigaddset(&sigs_to_catch,ds->inst_sig); cout4 << "signal " << ds->inst_sig << " installed" << endl; job_done = true; } // // Remove a signal from the catched one // if (ds->sig_to_remove == true) { ds->sig_to_remove = false; sigdelset(&sigs_to_catch,ds->rem_sig); cout4 << "signal " << ds->rem_sig << " removed" << endl; job_done = true; } if (job_done == true) { ds->signal(); continue; } } } #endif DevSigAction *act_ptr = &(DServerSignal::reg_sig[signo]); // // First, execute all the handlers installed at the class level // if (act_ptr->registered_classes.empty() == false) { long nb_class = act_ptr->registered_classes.size(); for (long j = 0;j < nb_class;j++) { act_ptr->registered_classes[j]->signal_handler((long)signo); } } // // Then, execute all the handlers installed at the device level // if (act_ptr->registered_devices.empty() == false) { long nb_dev = act_ptr->registered_devices.size(); for (long j = 0;j < nb_dev;j++) { act_ptr->registered_devices[j]->signal_handler((long)signo); } } // // For the automatically installed signal, unregister servers from database, // destroy the ORB and exit // if (auto_signal(signo) == true) { Tango::Util *tg = Tango::Util::instance(); if (tg != NULL) { try { tg->shutdown_ds(); } catch(...) { #ifndef _TG_WINDOWS_ raise(SIGKILL); #endif } } } } return NULL; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/utils.cpp0000644023471100065110000023376613034745002014447 00000000000000static const char *RcsId = "$Id: utils.cpp 29477 2016-03-15 15:54:43Z taurel $\n$Name$"; //+=================================================================================================================== // // file : Tango_utils.cpp // // description : C++ source for all the utilities used by Tango device server and mainly for the Tango class // // project : TANGO // // author(s) : A.Gotz + E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29477 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifndef _TG_WINDOWS_ #include #include #include #include #include #else #include #include #include #include #include #endif /* _TG_WINDOWS_ */ #include omni_thread::key_t key_py_data; namespace Tango { Util *Util::_instance = NULL; int Util::_tracelevel = 0; bool Util::_UseDb = true; bool Util::_FileDb = false; bool Util::_daemon = false; long Util::_sleep_between_connect = 60; bool Util::_constructed = false; #ifdef _TG_WINDOWS_ bool Util::_win = false; bool Util::_service = false; #endif // // A global key used for per thread specific storage. This is used to retrieve // client host and stores it in the device blackbox. This global is referenced // in blackbox.cpp // omni_thread::key_t key; //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::init() // // description : // static method to create/retrieve the Tango object. This method is the only one which enables a user to // create the object // // arguments : // in : // - argc : The command line argument number // - argv : The command line argument // //------------------------------------------------------------------------------------------------------------------ Util *Util::init(int argc,char *argv[]) { if (_instance == NULL) { _instance = new Util(argc,argv); } return _instance; } #ifdef _TG_WINDOWS_ Util *Util::init(HINSTANCE hi,int nCmd) { if (_instance == NULL) { _instance = new Util(hi,nCmd); } return _instance; } #endif //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::instance() // // description : // static method to retrieve the Tango object once it has been initialised // //------------------------------------------------------------------------------------------------------------------- Util *Util::instance(bool exit) { if (_instance == NULL) { if (exit == true) Util::print_err_message("Tango is not initialised !!!\nExiting"); else { Except::throw_exception((const char*)"API_UtilSingletonNotCreated", (const char*)"Util singleton not created", (const char*)"Util::instance"); } } return _instance; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::Util() // // description : // Constructor of the Tango class. // //----------------------------------------------------------------------------- #ifdef _TG_WINDOWS Util::Util(int argc,char *argv[]):cl_list_ptr(NULL),mon("Windows startup"),ext(new UtilExt), heartbeat_th(NULL),heartbeat_th_id(0),poll_mon("utils_poll"),poll_on(false),ser_model(BY_DEVICE), only_one("process"),nd_event_supplier(NULL),py_interp(NULL),py_ds(false),py_dbg(false), db_cache(NULL),inter(NULL),svr_starting(true),svr_stopping(false),poll_pool_size(ULONG_MAX), conf_needs_db_upd(false),ev_loop_func(NULL),shutdown_server(false),_dummy_thread(false), zmq_event_supplier(NULL),endpoint_specified(false),user_pub_hwm(-1),wattr_nan_allowed(false), polling_bef_9_def(false) # ifndef TANGO_HAS_LOG4TANGO ,cout_tmp(cout.rdbuf()) # endif #else Util::Util(int argc,char *argv[]):cl_list_ptr(NULL),ext(new UtilExt), heartbeat_th(NULL),heartbeat_th_id(0),poll_mon("utils_poll"),poll_on(false),ser_model(BY_DEVICE), only_one("process"),nd_event_supplier(NULL),py_interp(NULL),py_ds(false),py_dbg(false), db_cache(NULL),inter(NULL),svr_starting(true),svr_stopping(false),poll_pool_size(ULONG_MAX), conf_needs_db_upd(false),ev_loop_func(NULL),shutdown_server(false),_dummy_thread(false), zmq_event_supplier(NULL),endpoint_specified(false),user_pub_hwm(-1),wattr_nan_allowed(false), polling_bef_9_def(false) # ifndef TANGO_HAS_LOG4TANGO ,cout_tmp(cout.rdbuf()) # endif #endif { shared_data.cmd_pending=false; shared_data.trigger=false; cr_py_lock = new CreatePyLock(); // // Do the job // effective_job(argc,argv); _constructed = true; // // For Windows, install a console handler to ignore LOGOFF event // #ifdef _TG_WINDOWS_ install_cons_handler(); #endif } void Util::effective_job(int argc,char *argv[]) { try { // // Check server option // if (argc < 2) { print_usage(argv[0]); } // // Manage command line option (personal name and -v option) // check_args(argc,argv); // // Create the signal object // It is necessary to create this object before the ORB is initialised. // Otherwise, threads created by thread started by the ORB_init will not have // the correct signal mask (set by the DServerSignal object) and the device // server signal feature will not work // DServerSignal::instance(); // // Check if the user specified a endPoint on the command line or using one // env. variable // If true, extract the IP address from the end point and store it // for future use in the ZMQ publiher(s) // check_end_point_specified(argc,argv); // // Destroy the ORB created as a client (in case there is one) // Also destroy database objsect stored in the ApiUtil object. This is needed in case of CS running TAC // because the TAC device is stored in the db object and it references the destroyed ORB // ApiUtil *au = Tango::ApiUtil::instance(); CORBA::ORB_ptr orb_clnt = au->get_orb(); if (CORBA::is_nil(orb_clnt) == false) { orb_clnt->destroy(); CORBA::release(orb_clnt); au->set_orb(CORBA::ORB::_nil()); size_t nb_db = au->get_db_vect().size(); for (size_t ctr = 0;ctr < nb_db;ctr++) delete au->get_db_vect()[ctr]; au->get_db_vect().clear(); } // // Initialise CORBA ORB // #ifdef _TG_WINDOWS_ WORD rel = MAKEWORD(2,2); WSADATA dat; int err = WSAStartup(rel,&dat); if (err != 0) { stringstream ss; ss << "WSAStartup function failed with error " << err; print_err_message(ss.str()); } if (LOBYTE(dat.wVersion) != 2 || HIBYTE(dat.wVersion) != 2) { WSACleanup(); print_err_message("Could not find a usable version of Winsock.dll"); } #endif // // Starting with omniORB 4.2, we need to add the throwTransientOnTimeout option for compatibility // bool omni_42_compat = false; CORBA::ULong omni_vers_hex = omniORB::versionHex(); if (omni_vers_hex > 0x04020000) omni_42_compat = true; if (get_endpoint_specified() == true) { const char *options[][2] = { {"clientCallTimeOutPeriod",CLNT_TIMEOUT_STR}, {"serverCallTimeOutPeriod","5000"}, {"maxServerThreadPoolSize","100"}, {"threadPerConnectionUpperLimit","55"}, {"threadPerConnectionLowerLimit","50"}, {"supportCurrent","0"}, {"verifyObjectExistsAndType","0"}, {"maxGIOPConnectionPerServer",MAX_GIOP_PER_SERVER}, {"giopMaxMsgSize",MAX_TRANSFER_SIZE}, #ifndef _TG_WINDOWS_ {"endPoint","giop:unix:"}, #endif {"throwTransientOnTimeOut","1"}, {0,0} }; if (omni_42_compat == false) { int nb_opt = sizeof(options) / sizeof (char *[2]); options[nb_opt - 2][0] = NULL; options[nb_opt - 2][1] = NULL; } orb = CORBA::ORB_init(argc,argv,"omniORB4",options); } else { const char *options[][2] = { {"endPointPublish","all(addr)"}, {"clientCallTimeOutPeriod",CLNT_TIMEOUT_STR}, {"serverCallTimeOutPeriod","5000"}, {"maxServerThreadPoolSize","100"}, {"threadPerConnectionUpperLimit","55"}, {"threadPerConnectionLowerLimit","50"}, {"supportCurrent","0"}, {"verifyObjectExistsAndType","0"}, {"maxGIOPConnectionPerServer",MAX_GIOP_PER_SERVER}, {"giopMaxMsgSize",MAX_TRANSFER_SIZE}, #ifndef _TG_WINDOWS_ {"endPoint","giop:tcp::"}, {"endPoint","giop:unix:"}, #endif {"throwTransientOnTimeOut","1"}, {0,0} }; if (omni_42_compat == false) { int nb_opt = sizeof(options) / sizeof (char *[2]); options[nb_opt - 2][0] = NULL; options[nb_opt - 2][1] = NULL; } orb = CORBA::ORB_init(argc,argv,"omniORB4",options); } #ifndef TANGO_HAS_LOG4TANGO // // Initialize trace output (For Windows, the stdc++ lib also implements the // new iostreams where the xx_with_assign classes are not defined. Therefore, // to copy streams, I have used the advices in the C++ report of June 1997 // trace_output = InitialOutput; file_stream = NULL; cout_tmp.copyfmt(cout); cout_tmp.clear(cout.rdstate()); #endif // TANGO_HAS_LOG4TANGO // // Init host name // init_host_name(); // // Connect to the database // if (_UseDb == true) { connect_db(); // // Display help message if requested by user. This is done after the process is // connected to the database becaue a call to the database server is done in the // display_help_message() method // if (display_help == true) { display_help_message(); } } else { db = NULL; ApiUtil *au = ApiUtil::instance(); au->in_server(true); } // // Create the server CORBA objects // create_CORBA_objects(); #ifdef TANGO_HAS_LOG4TANGO // // Initialize logging stuffs // Logging::init(ds_name, (int)_tracelevel, ((!_FileDb) && _UseDb), *db, this); #endif cout4 << "Connected to database" << endl; if (get_db_cache() == NULL) cout4 << "DbServerCache unavailable, will call db..." << endl; // // Check if the server is not already running somewhere else // if ((_UseDb == true) && (_FileDb == false)) server_already_running(); // // Get process PID and Tango version // misc_init(); // // Automatically create the EventSupplier objects // // In the future this could be created only when the // first event is fired ... // create_notifd_event_supplier(); create_zmq_event_supplier(); // // Create the heartbeat thread and start it // heartbeat_th = new PollThread(shared_data,poll_mon,true); heartbeat_th->start(); heartbeat_th_id = heartbeat_th->id(); cout4 << "Heartbeat thread Id = " << heartbeat_th_id << endl; cout4 << "Tango object singleton constructed" << endl; } catch (CORBA::Exception &) { throw; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::create_CORBA_objects() // // description : // Create some CORBA objects needed later-on // //------------------------------------------------------------------------------------------------------------------- void Util::create_CORBA_objects() { // // Install an omniORB interceptors to store client name in blackbox and allocate a key for per thread specific storage // omni::omniInterceptors *intercep = omniORB::getInterceptors(); intercep->serverReceiveRequest.add(get_client_addr); intercep->createThread.add(create_PyPerThData); key = omni_thread::allocate_key(); key_py_data = omni_thread::allocate_key(); // // Get some CORBA object references // CORBA::Object_var poaObj = orb->resolve_initial_references("RootPOA"); PortableServer::POA_var root_poa = PortableServer::POA::_narrow(poaObj); // // If the database is not used, we must used the omniINSPOA poa in both cases of database on file or nodb // remember that when you have database on file you have _UseDb == true and _FileDb == true // PortableServer::POA_var nodb_poa; if ((_UseDb == false) || (_FileDb == true)) { CORBA::Object_var poaInsObj = orb->resolve_initial_references("omniINSPOA"); nodb_poa = PortableServer::POA::_narrow(poaInsObj); } // // Store POA. This is the same test but inverted // if ((_UseDb == true) && (_FileDb == false)) _poa = PortableServer::POA::_duplicate(root_poa); else if ((_UseDb == false) || (_FileDb == true)) _poa = PortableServer::POA::_duplicate(nodb_poa); } #ifdef _TG_WINDOWS_ //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::Util() // // description : // Constructor of the Tango class when used in a non-console Windows device server. On top of the UNIX way of // building a Util singleton, for Windows non-console mode, it is necessary to : // - Build a UNIX like argc,argv from the command line // - Initialise the ORB // - Create a debug output window if verbose mode is requested and change cout so that it prints into this // window // // arguments : // in : // - hInst : The application instance // - nCmdShow : The display window flag // //------------------------------------------------------------------------------------------------------------------- Util::Util(HINSTANCE hInst,int nCmdShow):cl_list_ptr(NULL),mon("Windows startup"),ext(new UtilExt), heartbeat_th(NULL),heartbeat_th_id(0),poll_mon("utils_poll"),poll_on(false),ser_model(BY_DEVICE), only_one("process"),nd_event_supplier(NULL),py_interp(NULL),py_ds(false),py_dbg(false), db_cache(NULL),inter(NULL),svr_starting(true),svr_stopping(false),poll_pool_size(ULONG_MAX), conf_needs_db_upd(false),ev_loop_func(NULL),shutdown_server(false),_dummy_thread(false), zmq_event_supplier(NULL),endpoint_specified(false),user_pub_hwm(-1),wattr_nan_allowed(false), polling_bef_9_def(false) #ifndef TANGO_HAS_LOG4TANGO ,cout_tmp(cout.rdbuf()) #endif { // // This method should be called from a Windows graphic program // _win = true; // // Some more init // shared_data.cmd_pending = false; shared_data.trigger = false; cr_py_lock = new CreatePyLock(); // // Build UNIX like command argument(s) // build_argc_argv(); // // Really do the job now // effective_job(argc,argv); // // Store the nCmdShow parameter an mark the object has being completely // constructed. Usefull, in case one of the method previously called // failed, the orb variable (type ORB_var) is alaready destroyed therefore // releasing the orb pointer. // nCmd = nCmdShow; _constructed = true; } #endif //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::ckeck_args() // // description : // Check the command line arguments. The first one is mandatory and is the server personal name. A -v option // is authorized with an optional argument. The other option should be ORBacus option // // arguments : // in : // - argc : The command line argument number // - argv : The command line argument // //------------------------------------------------------------------------------------------------------------------- void Util::check_args(int argc,char *argv[]) { // // Check command line argument // string first_arg(argv[1]); display_help = false; if ((argc == 2) && (_UseDb == true)) { if ((first_arg == "-?") || (first_arg == "-help") || (first_arg == "-h")) { display_help = true; } } if ((display_help == false) && (argv[1][0] == '-')) { print_usage(argv[0]); } ds_instance_name = argv[1]; char *tmp; #ifdef _TG_WINDOWS_ if ((tmp = strrchr(argv[0],'\\')) == 0) { if ((tmp = strrchr(argv[0],'/')) == 0) { ds_exec_name = argv[0]; } else { tmp++; ds_exec_name = tmp; } } else { tmp++; ds_exec_name = tmp; } #else if ((tmp = strrchr(argv[0],'/')) == 0) ds_exec_name = argv[0]; else { tmp++; ds_exec_name = tmp; } #endif // // For Windows only. Remove the .exe after the executable name // #ifdef _TG_WINDOWS_ string::size_type pos; if ((pos = ds_exec_name.find('.')) != string::npos) { ds_exec_name.erase(pos,ds_exec_name.size()); } #endif /* _TG_WINDOWS_ */ if (argc > 2) { long ind = 2; string dlist; while (ind < argc) { if (argv[ind][0] == '-') { switch (argv[ind][1]) { // // The verbose option // case 'v': if (strlen(argv[ind]) == 2) { if ((argc - 1)> ind) { if (argv[ind + 1][0] == '-') set_trace_level(4); else { cerr << "Unknown option " << argv[ind] << endl; print_usage(argv[0]); } } else set_trace_level(4); ind++; } else { long level = atol(&(argv[ind][2])); if (level == 0) { cerr << "Unknown option " << argv[ind] << endl; print_usage(argv[0]); } else { set_trace_level(level); ind++; } } break; // // Device server without database // case 'n': if (strcmp(argv[ind],"-nodb") != 0) { cerr << "Unknown option " << argv[ind] << endl; print_usage(argv[0]); } else { if ( _FileDb ) print_usage(argv[0]); _UseDb = false; ind++; check_orb_endpoint(argc,argv); } break; case 'f': if (strncmp(argv[ind],"-file=",6) != 0) { cerr << "Unknown option " << argv[ind] << endl; print_usage(argv[0]); } else { if ( !_UseDb ) print_usage(argv[0]); Tango::Util::_FileDb = true; database_file_name = argv[ind]; database_file_name.erase(0,6); #ifdef _TG_WINDOWS_ replace(database_file_name.begin(), database_file_name.end(), '\\','/'); #endif cout4 << "File name = <" << database_file_name << ">" << endl; ind++; // // Try to find the ORB endPoint option // check_orb_endpoint(argc,argv); } break; // // Device list (for device server without database) // case 'd': if (strcmp(argv[ind],"-dbg")==0) { ind++; break; } if (strcmp(argv[ind],"-dlist") != 0) { cerr << "Unknown option " << argv[ind] << endl; print_usage(argv[0]); } else { if (_UseDb == true) print_usage(argv[0]); ind++; if (ind == argc) print_usage(argv[0]); else { dlist = argv[ind]; // // Extract each device name // string::size_type start = 0; string str; string::size_type pos; //vector &list = get_cmd_line_name_list(); vector dev_list; while ((pos = dlist.find(',',start)) != string::npos) { str = dlist.substr(start,pos - start); start = pos + 1; dev_list.push_back(str); } if (start != dlist.size()) { str = dlist.substr(start); dev_list.push_back(str); } validate_sort(dev_list); } } break; default: ind++; break; } } else { if (strncmp(argv[ind - 1],"-v",2) == 0) { print_usage(argv[0]); } ind++; } } } // // Build server name // // long ctr; // for (ctr = 0;ctr < ds_exec_name.size();ctr++) // ds_exec_name[ctr] = tolower(ds_exec_name[ctr]); // for (ctr = 0;ctr < ds_instance_name.size();ctr++) // ds_instance_name[ctr] = tolower(ds_instance_name[ctr]); ds_name = ds_exec_name; ds_name.append("/"); ds_name.append(ds_instance_name); // // Check that the server name is not too long // if (ds_name.size() > MaxServerNameLength) { TangoSys_OMemStream o; o << "The device server name is too long! Max length is " << MaxServerNameLength << " characters" << ends; print_err_message(o.str(),Tango::INFO); } // // If the server is the database server (DS started with _UseDb set to false but without the // nodb option), we need its port // if ((_UseDb == false) && (svr_port_num.empty() == true)) { check_orb_endpoint(argc,argv); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::validate_sort // // description : // Validate and sort the list of devices passed by the user to the DS in the command line // // arguments : // in : // - dev_list : Vector with device name list // //------------------------------------------------------------------------------------------------------------------- void Util::validate_sort(vector &dev_list) { unsigned long i,j; vector dev_no_class; // // First, create a vector with device name in lower case letters without class name // for (i = 0;i < dev_list.size();i++) { string tmp(dev_list[i]); transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); string::size_type pos = tmp.find("::"); if (pos == string::npos) { dev_no_class.push_back(tmp); } else { string tmp_no_class = tmp.substr(pos + 2); dev_no_class.push_back(tmp_no_class); } } // // Check that the same device name is not used twice and check that their syntax is correct (2 / characters) // for (i = 0;i < dev_no_class.size();i++) { int nb_char = count(dev_no_class[i].begin(),dev_no_class[i].end(),'/'); if (nb_char != 2) { stringstream ss; ss << "Device name " << dev_list[i] << " does not have the correct syntax (domain/family/member or ClassName::domain/family/member)"; print_err_message(ss.str()); } for (j = 0;j < dev_no_class.size();j++) { if (i == j) continue; else { if (dev_no_class[i] == dev_no_class[j]) { print_err_message("Each device must have different name",Tango::INFO); } } } } // // Sort this device name list and store them in a map according to the class name. Command line device name // syntax is "ClassName::device_name" eg: MyClass::my/device/name // map > &the_map = get_cmd_line_name_list(); string::size_type pos; for (i = 0;i < dev_list.size();i++) { pos = dev_list[i].find("::"); if (pos == string::npos) { map >::iterator ite = the_map.find(NoClass); if (ite == the_map.end()) { vector v_s; v_s.push_back(dev_list[i]); the_map.insert(pair >(NoClass,v_s)); } else { ite->second.push_back(dev_list[i]); } } else { string cl_name = dev_list[i].substr(0,pos); transform(cl_name.begin(),cl_name.end(),cl_name.begin(),::tolower); map >::iterator ite = the_map.find(cl_name); if (ite == the_map.end()) { vector v_s; string d_name = dev_list[i].substr(pos + 2); v_s.push_back(d_name); the_map.insert(pair >(cl_name,v_s)); } else { string d_name = dev_list[i].substr(pos + 2); ite->second.push_back(d_name); } } } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::display_help_message() // // description : // Display Tango device server process command line option and the list of instances defined for the // device server (retrieved from DB) // //------------------------------------------------------------------------------------------------------------------- void Util::display_help_message() { // // Display device server usage string // TangoSys_OMemStream o; o << "usage : " << ds_exec_name << " instance_name [-v[trace level]]"; o << " [-nodb [-dlist ]]"; // // Try to get instance name from db // string str("dserver/"); str.append(ds_exec_name); str.append("/*"); vector db_inst; try { DbDatum received = db->get_device_member(str); received >> db_inst; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_ReadOnlyMode) o << "\n\nWarning: Control System configured with AccessControl but can't communicate with AccessControl server"; o << ends; print_err_message(o.str(),Tango::INFO); } // // Add instance name list to message // o << "\nInstance name defined in database for server " << ds_exec_name << " :"; for (unsigned long i = 0;i < db_inst.size();i++) { o << "\n\t" << db_inst[i]; } o << ends; // // Display message // print_err_message(o.str(),Tango::INFO); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::print_usage() // // description : // Print device server command line syntax // // arguments : // in : // - serv_name : The server name // //------------------------------------------------------------------------------------------------------------------- void Util::print_usage(char *serv_name) { TangoSys_OMemStream o; o << "usage : " << serv_name << " instance_name [-v[trace level]]"; o << " [-file= | -nodb [-dlist ] ]" << ends; print_err_message(o.str(),Tango::INFO); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::connect_db() // // description : // This method builds a connection to the Tango database servant. It uses the db_host and db_port object // variables. The Tango database server implements its CORBA object as named servant. // //-------------------------------------------------------------------------------------------------------------------- void Util::connect_db() { // // Try to create the Database object // if (_daemon == true) { int connected = false; while (connected == false) { try { #ifdef _TG_WINDOWS_ if (_service == true) db = new Database(orb.in(), ds_exec_name, ds_instance_name); else { if (_FileDb == false) db = new Database(orb.in()); else db = new Database(database_file_name); } #else if (_FileDb == false) db = new Database(orb.in()); else db = new Database(database_file_name); #endif db->set_tango_utils(this); connected = true; } catch (Tango::DevFailed &e) { if (strcmp(e.errors[0].reason.in(),API_TangoHostNotSet) == 0) { print_err_message(e.errors[0].desc.in()); } else { cout4 << "Can't contact db server, will try later" << endl; Tango_sleep(_sleep_between_connect); } } catch (CORBA::Exception &) { cout4 << "Can't contact db server, will try later" << endl; Tango_sleep(_sleep_between_connect); } } } else { try { #ifdef _TG_WINDOWS_ if (_service == true) db = new Database(orb.in(), ds_exec_name, ds_instance_name); else { if (_FileDb == false) db = new Database(orb.in()); else db = new Database(database_file_name); } #else if (_FileDb == false) db = new Database(orb.in()); else db = new Database(database_file_name); #endif db->set_tango_utils(this); } catch (Tango::DevFailed &e) { if (e.errors.length() == 2) { if (strcmp(e.errors[1].reason.in(),"API_CantConnectToDatabase") == 0) { TangoSys_OMemStream o; o << "Can't build connection to TANGO database server, exiting"; print_err_message(o.str()); } else print_err_message(e.errors[1].desc.in()); } else print_err_message(e.errors[0].desc.in()); } catch (CORBA::Exception &) { TangoSys_OMemStream o; o << "Can't build connection to TANGO database server, exiting"; print_err_message(o.str()); } } if (CORBA::is_nil(db->get_dbase()) && _FileDb != true) { TangoSys_OMemStream o; o << "Can't build connection to TANGO database server, exiting" << ends; print_err_message(o.str()); } // // Set a timeout on the database device // if (_FileDb == false) db->set_timeout_millis(DB_TIMEOUT); // // Also copy this database object ptr into the ApiUtil object. Therefore, // the same database connection will be used also for DeviceProxy // object created within the server // ApiUtil *au = ApiUtil::instance(); au->get_db_vect().push_back(db); au->in_server(true); // // Try to create the db cache which will be used during the process // startup sequence // For servers with many devices and properties, this could take time // specially during a massive DS startup (after power cut for instance) // Filling the DS cache is a relatively heavy command for the DB server // Trying to minimize retry in this case could be a good idea. // Therefore, change DB device timeout to execute this command // if (_FileDb == false) { string &inst_name = get_ds_inst_name(); if (inst_name != "-?") { db->set_timeout_millis(DB_TIMEOUT * 4); set_svr_starting(false); try { db_cache = new DbServerCache(db,get_ds_name(),get_host_name()); } catch (Tango::DevFailed &e) { string base_desc(e.errors[0].desc.in()); if (base_desc.find("TRANSIENT_CallTimedout") != string::npos) cerr << "DB timeout while trying to fill the DB server cache. Will use traditional way" << endl; } catch (...) { cerr << "Unknown exception while trying to fill database cache..." << endl; } db->set_timeout_millis(DB_TIMEOUT); set_svr_starting(true); } } } void Util::reset_filedatabase() { delete db; db = new Database(database_file_name); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::misc_init() // // description : // This method initialises miscellaneous variable which are needed later in the device server startup sequence. // These variables are : // The process ID // The Tango version // //------------------------------------------------------------------------------------------------------------------- void Util::misc_init() { // // Get PID // TangoSys_OMemStream o; #ifdef _TG_WINDOWS_ pid = _getpid(); #else pid = DServerSignal::instance()->get_sig_thread_pid(); #endif o << pid << ends; pid_str = o.str(); // // Convert Tango version number to string (for device export) // o.seekp(0,ios_base::beg); o.clear(); o << DevVersion << ends; version_str = o.str(); // // Init server version to a default value // server_version = "x.y"; // // Init text to be displayed on main window with a default value // #ifdef _TG_WINDOWS_ main_win_text = "TANGO collaboration\n"; main_win_text = main_win_text + "http://www.tango-controls.org"; #endif // // Check if the user has defined his own publisher hwm (for zmq event tuning) // string var; if (ApiUtil::get_env_var("TANGO_DS_EVENT_BUFFER_HWM",var) == 0) { int pub_hwm = -1; istringstream iss(var); iss >> pub_hwm; if (iss) user_pub_hwm = pub_hwm; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::init_host_name() // // description : // This method initialises the process host name which is needed later in the device server startup sequence. // //------------------------------------------------------------------------------------------------------------------- void Util::init_host_name() { // // Get the FQDN host name (Fully qualified domain name) // If it is not returned by the system call "gethostname", // try with the getnameinfo/getaddrinfo system calls providing // IP address obtained by calling ApiUtil::get_ip_from_if() // // All supported OS have the getaddrinfo() call // char buffer[80]; if (gethostname(buffer,80) == 0) { hostname = buffer; transform(hostname.begin(), hostname.end(), hostname.begin(), ::tolower); // to retain consistency with getnameinfo() which always returns lowercase string::size_type pos = hostname.find('.'); if (pos == string::npos) { struct addrinfo hints; memset(&hints,0,sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; // supports both IPv4 and IPv6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; // inhibits resolution of node parameter if it is not a numeric network address hints.ai_flags |= AI_ADDRCONFIG; struct addrinfo *info, *ptr; char tmp_host[NI_MAXHOST]; bool host_found = false; vector host_names; ApiUtil *au = ApiUtil::instance(); vector ip_list; au->get_ip_from_if(ip_list); // returns a list of numeric network addresses for(size_t i = 0; i < ip_list.size() && !host_found; i++) { if(getaddrinfo(ip_list[i].c_str(),NULL,&hints,&info) == 0) { ptr = info; while(ptr != NULL) { if(getnameinfo(ptr->ai_addr,ptr->ai_addrlen,tmp_host,NI_MAXHOST,NULL,0,NI_NAMEREQD) == 0) { string myhost(tmp_host); #ifdef _TG_WINDOWS_ // // On windows, getnameinfo may return name in uppercase letters // transform(myhost.begin(),myhost.end(),myhost.begin(),::tolower); #endif string::size_type pos = myhost.find('.'); if (pos != string::npos) { host_names.push_back(myhost); } } ptr = ptr->ai_next; } freeaddrinfo(info); } } // // Several cases to find out the real name of the network interface on which the server is running. // First be sure that we got at least one name from call(s) to getnameinfo() // Then, we have to know if the -ORBendPoint option was specified on the command line // If it was not, select the name which is the same than the computer hostname. If not found, select the first name // returned by getnameinfo() // If the endPoint option is used by the host name is not specified within the option (Db case for instance), do the // same than in previous case // If a host is specified in endPOint option: // If it is specified as a name, search for this name in the list returned by getnameinfo calls and select it // If it is specified as a IP address, search for this IP in ip_list vector and select this name in the result // of getnameinfo() call // if (host_names.size() != 0) { if (get_endpoint_specified() == false) { bool found = false; for (size_t loop = 0;loop < host_names.size();loop++) { string::size_type pos = host_names[loop].find('.'); string canon = host_names[loop].substr(0,pos); if (hostname == canon) { found = true; hostname = host_names[loop]; break; } } if (found == false) hostname = host_names[0]; } else { string &spec_ip = get_specified_ip(); if (spec_ip.empty() == true) { bool found = false; for (size_t loop = 0;loop < host_names.size();loop++) { string::size_type pos = host_names[loop].find('.'); string canon = host_names[loop].substr(0,pos); if (hostname == canon) { found = true; hostname = host_names[loop]; break; } } if (found == false) hostname = host_names[0]; } else { int nb_dot = count(spec_ip.begin(),spec_ip.end(),'.'); if (nb_dot == 3) { int ind = -1; for (int loop = 0;loop < (int)ip_list.size();loop++) { if (ip_list[loop] == spec_ip) { ind = loop; break; } if (ind != -1 && (((int)host_names.size() - 1) >= ind)) hostname = host_names[ind]; } } else { string::size_type pos = spec_ip.find('.'); string canon_spec; if (pos != string::npos) canon_spec = spec_ip.substr(0,pos); else canon_spec = spec_ip; for (size_t loop = 0;loop < host_names.size();loop++) { string::size_type pos = host_names[loop].find('.'); string canon = host_names[loop].substr(0,pos); if (canon_spec == canon) { hostname = host_names[loop]; break; } } } } } } } } else { print_err_message("Cant retrieve server host name"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::create_notifd_event_supplier() // // description : // This method create the notifd event_supplier if possible // //------------------------------------------------------------------------------------------------------------------- void Util::create_notifd_event_supplier() { if (_UseDb == true) { try { nd_event_supplier = NotifdEventSupplier::create(orb,ds_name,this); nd_event_supplier->connect(); } catch (...) { nd_event_supplier = NULL; if (_FileDb == true) cerr << "Can't create notifd event supplier. Notifd event not available" << endl; } } else { nd_event_supplier = NULL; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::create_zmq_event_supplier() // // description : // This method create the zmq event_supplier if possible // //------------------------------------------------------------------------------------------------------------------- void Util::create_zmq_event_supplier() { try { zmq_event_supplier = ZmqEventSupplier::create(this); } catch (...) { zmq_event_supplier = NULL; if (_FileDb == true) cerr << "Can't create zmq event supplier. Zmq event not available" << endl; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::~Util() // // description : // Tango singleton object destructor. This destructor shutdown everything before the process dies. This means // - Send kill command to the polling thread // - Join with this polling thread // - Unregister server in database // - Delete devices (except the admin one) // - Shutdown the ORB // - Cleanup Logging // //------------------------------------------------------------------------------------------------------------------- Util::~Util() { #ifdef _TG_WINDOWS_ if (ds_window != NULL) { stop_all_polling_threads(); stop_heartbeat_thread(); clr_heartbeat_th_ptr(); unregister_server(); get_dserver_device()->delete_devices(); if (_FileDb == true) delete db; orb->shutdown(true); //JM : 9.8.2005 : destroy() should be called at the exit of run()! //orb->destroy(); #ifdef TANGO_HAS_LOG4TANGO Logging::cleanup(); #endif } #endif #ifndef HAS_UNIQUE_PTR delete ext; #endif delete cr_py_lock; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::server_already_running() // // description : // Check if the same device server is not already running somewhere else and refuse to start in this case // //------------------------------------------------------------------------------------------------------------------- void Util::server_already_running() { cout4 << "Entering Util::server_already_running method" << endl; // // Build device name and try to import it from database or from cache if available // string dev_name(DSDeviceDomain); dev_name.append(1,'/'); dev_name.append(ds_name); Tango::Device_var dev; try { const Tango::DevVarLongStringArray *db_dev; CORBA::Any_var received; if (db_cache != NULL) { db_dev = db_cache->import_adm_dev(); } else { CORBA::Any send; send <<= dev_name.c_str(); received = db->get_dbase()->command_inout("DbImportDevice",send); if ((received.inout() >>= db_dev) == false) { TangoSys_OMemStream o; o << "Database error while trying to import " << dev_name << ends; Except::throw_exception((const char *)API_DatabaseAccess, o.str(), (const char *)"Util::server_already_running"); } } // // If the device is not imported, leave function // if ((db_dev->lvalue)[0] == 0) { cout4 << "Leaving Util::server_already_running method" << endl; return; } CORBA::Object_var obj = orb->string_to_object((db_dev->svalue)[1]); // // Try to narrow the reference to a Tango::Device object // dev = Tango::Device::_narrow(obj); } catch (Tango::DevFailed &) { TangoSys_OMemStream o; o << "The device server " << ds_name << " is not defined in database. Exiting!" << ends; print_err_message(o.str()); } catch (CORBA::TRANSIENT &) { cout4 << "Leaving Util::server_already_running method" << endl; return; } catch (CORBA::OBJECT_NOT_EXIST &) { cout4 << "Leaving Util::server_already_running method" << endl; return; } catch (CORBA::NO_RESPONSE &) { print_err_message("This server is already running but is blocked!"); } catch (CORBA::COMM_FAILURE &) { cout4 << "Leaving Util::server_already_running method" << endl; return; } if (CORBA::is_nil(dev)) { cout4 << "Leaving Util::server_already_running method" << endl; return; } // // Now, get the device name from the server // try { CORBA::String_var n = dev->name(); unsigned long ctr; char *tmp_ptr = n.inout(); for (ctr = 0;ctr < strlen(tmp_ptr);ctr++) tmp_ptr[ctr] = tolower(tmp_ptr[ctr]); for (ctr = 0;ctr < dev_name.length();ctr++) dev_name[ctr] = tolower(dev_name[ctr]); if (n.in() == dev_name) { print_err_message("This server is already running, exiting!"); } } catch (Tango::DevFailed &) { // // It is necessary to catch this exception because it is thrown by the print_err_message method under windows // throw; } catch (CORBA::NO_RESPONSE &) { try { print_err_message("This server is already running but is blocked!"); } catch (Tango::DevFailed &) { throw; } } catch (CORBA::SystemException &) {} catch (CORBA::Exception &) {} cout4 << "Leaving Util::server_already_running method" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::server_init() // // description : // To initialise all classes in the device server process // //------------------------------------------------------------------------------------------------------------------- void Util::server_init(TANGO_UNUSED(bool with_window)) { // // Even if we are not in a Python DS, we have to create the per-thread PyData object. // For Python DS, this is done in the Python_init method defined in the binding // #ifdef _TG_WINDOWS_ if (Util::_service == true) { omni_thread::create_dummy(); _dummy_thread = true; } omni_thread *th = omni_thread::self(); if (th == NULL) { th = omni_thread::create_dummy(); _dummy_thread = true; } #else omni_thread *th = omni_thread::self(); if (th == NULL) { th = omni_thread::create_dummy(); _dummy_thread = true; } #endif if (is_py_ds() == false) { th->set_value(key_py_data,new Tango::PyData()); } #ifdef _TG_WINDOWS_ if (with_window == true) { // // Create device server windows // ds_window = new W32Win(this,nCmd); // // Change cout that it uses the graphical console window // #ifndef TANGO_HAS_LOG4TANGO cout.rdbuf(ds_window->get_output_buffer()); cout_tmp.rdbuf(ds_window->get_output_buffer()); #endif } #ifdef TANGO_HAS_LOG4TANGO //MODIF-NL else { ds_window = 0; } #endif if (_win == true) { go = false; loop_th = new ORBWin32Loop(this); loop_th->start(); } else { #endif /* WIN 32 */ // // Initialise main class // DServerClass::init(); // // Configure polling from the polling properties. In case of python DS, we need to release the Python GIL // because the polling_configure method will send cmd to the polling thread which will try to get the Python GIL // int th_id = th->id(); PyLock *lock_ptr; bool py_ds_main_th = false; if ((th_id == 0) && (is_py_ds() == true)) { py_ds_main_th = true; omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Release(); } polling_configure(); if (py_ds_main_th == true) { lock_ptr->Get(); } // // Delete the db cache if it has been used // if (db_cache != NULL) { // extract sub device information before deleting cache! get_sub_dev_diag().get_sub_devices_from_cache(); delete db_cache; db_cache = NULL; } // // In case of process with forwarded attributes with root attribute inside this process as well // RootAttRegistry &rar = get_root_att_reg(); if (rar.empty() == false && rar.is_root_dev_not_started_err() == true) { if (EventConsumer::keep_alive_thread != NULL) { ZmqEventConsumer *event_consumer = ApiUtil::instance()->get_zmq_event_consumer(); EventConsumer::keep_alive_thread->fwd_not_conected_event(event_consumer); } } #ifdef _TG_WINDOWS_ } #endif /* _TG_WINDOWS_ */ } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::server_run() // // description : // To start the CORBA event loop // //------------------------------------------------------------------------------------------------------------------ void Util::server_run() { // // The server is now started // #ifndef _TG_WINDOWS_ set_svr_starting(false); #else if (_win == false) set_svr_starting(false); #endif // // Get thread ID // omni_thread *th = omni_thread::self(); int th_id = th->id(); // // For Windows in a non-MSDOS window, start the ORB in its own thread. The main // thread is used for windows management. // #ifdef _TG_WINDOWS_ if (_win == true) { omni_mutex_lock syc(mon); // // Start the ORB thread (and loop) // go = true; mon.signal(); } else { if (_service == true) { NTService *serv = NTService::instance(); serv->statusUpdate(SERVICE_RUNNING); if (serv->stopped_ == false) { //JM : 9.8.2005 : destroy() should be called at the exit of run()! try { orb->run(); server_cleanup(); } catch (CORBA::Exception &) { server_cleanup(); throw; } } } else { cout << "Ready to accept request" << endl; if (th_id == 0) { omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Release(); } //JM : 9.8.2005 : destroy() should be called at the exit of run()! try { orb->run(); server_cleanup(); if (th_id == 0) { omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Get(); } } catch (CORBA::Exception &) { server_cleanup(); throw; } } } #else cout << "Ready to accept request" << endl; if (th_id == 0) { omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Release(); } //JM : 9.8.2005 : destroy() should be called at the exit of run()! try { if (ev_loop_func != NULL) { // // If the user has installed its own event management function, call it in a loop // struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = 20000000; bool user_shutdown_server; while(shutdown_server == false) { if (is_svr_shutting_down() == false) { if (orb->work_pending()) orb->perform_work(); user_shutdown_server = (*ev_loop_func)(); if (user_shutdown_server == true) { shutdown_ds(); shutdown_server = true; } } else { nanosleep(&sleep_time,NULL); } } } else { orb->run(); } server_cleanup(); if (th_id == 0) { omni_thread::value_t *tmp_py_data = th->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Get(); } } catch (CORBA::Exception &e) { server_cleanup(); throw; } #endif } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::server_cleanup() // // description : // To relinquish computer resource before process exit // //------------------------------------------------------------------------------------------------------------------ void Util::server_cleanup() { #ifndef _TG_WINDOWS_ // // Destroy the ORB // if (_constructed == true) { orb->destroy(); // JM : 8.9.2005 : mark as already destroyed _constructed = false; } #else if (ds_window == NULL) { if (_constructed == true) { orb->destroy(); // JM : 8.9.2005 : mark as already destroyed _constructed = false; } } #endif if (_dummy_thread == true) omni_thread::release_dummy(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::get_device_list_by_class() // // description : // To return a reference to the vector of device for a specific class // // arguments : // in : // - class_name : The class name // // returns : // Reference to the vector with device pointers // //------------------------------------------------------------------------------------------------------------------ vector &Util::get_device_list_by_class(const string &class_name) { if (cl_list_ptr == NULL) { Except::throw_exception((const char *)API_DeviceNotFound, (const char *)"It's too early to call this method. Devices are not created yet!", (const char *)"Util::get_device_list_by_class()"); } // // Retrieve class list. Don't use the get_dserver_device() method followed by // the get_class_list(). In case of several classes embedded within // the same server and the use of this method in the object creation, it // will fail because the end of the dserver object creation is after the // end of the last server device creation. // const vector &tmp_cl_list = *cl_list_ptr; // // Check if the wanted class really exists // int nb_class = tmp_cl_list.size(); int i; for (i = 0;i < nb_class;i++) { if (tmp_cl_list[i]->get_name() == class_name) break; } // // Also check if it it the DServer class // if (class_name == "DServer") { return DServerClass::instance()->get_device_list(); } // // Throw exception if the class is not found // if (i == nb_class) { TangoSys_OMemStream o; o << "Class " << class_name << " not found" << ends; Except::throw_exception((const char *)API_ClassNotFound, o.str(), (const char *)"Util::get_device_list_by_class()"); } return tmp_cl_list[i]->get_device_list(); } vector &Util::get_device_list_by_class(const char *class_name) { string class_str(class_name); return get_device_list_by_class(class_str); } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::get_device_by_name() // // description : // To return a reference to the device object from its name // // arguments : // in : // - dev_name : The device name // // returns : // Pointer to the device object // //------------------------------------------------------------------------------------------------------------------- DeviceImpl *Util::get_device_by_name(const string &dev_name) { string dev_name_lower(dev_name); transform(dev_name_lower.begin(),dev_name_lower.end(),dev_name_lower.begin(),::tolower); DeviceImpl *ret_ptr = find_device_name_core(dev_name_lower); // // If the device is not found, may be the name we have received is an alias ? // if (ret_ptr == NULL) { string d_name; if (_UseDb == true) { try { db->get_device_alias(dev_name_lower,d_name); } catch (Tango::DevFailed &) {} } if (d_name.size() != 0) { transform(d_name.begin(),d_name.end(),d_name.begin(),::tolower); ret_ptr = find_device_name_core(d_name); // // If the name given to this method is a valid alias name, store the alias name in device object for possible // future call to this method (save some db calls) // if (ret_ptr != NULL) { ret_ptr->set_alias_name_lower(dev_name_lower); } } } // // Throw exception if the device is not found // if (ret_ptr == NULL) { TangoSys_OMemStream o; o << "Device " << dev_name << " not found" << ends; Except::throw_exception((const char *)API_DeviceNotFound, o.str(), (const char *)"Util::get_device_by_name()"); } return ret_ptr; } DeviceImpl *Util::find_device_name_core(string &dev_name) { // // Retrieve class list. Don't use the get_dserver_device() method followed by the get_class_list(). In case of several // classes embedded within the same server and the use of this method in the object creation, it will fail because the // end of the dserver object creation is after the end of the last server device creation. // const vector &tmp_cl_list = *cl_list_ptr; DeviceImpl *ret_ptr = NULL; // // Check if the wanted device exists in each class // int nb_class = tmp_cl_list.size(); int i,j,nb_dev; bool found = false; for (i = 0;i < nb_class;i++) { vector &dev_list = get_device_list_by_class(tmp_cl_list[i]->get_name()); nb_dev = dev_list.size(); for (j = 0;j < nb_dev;j++) { string name(dev_list[j]->get_name()); transform(name.begin(),name.end(),name.begin(),::tolower); if (name == dev_name) { found = true; ret_ptr = dev_list[j]; break; } string &alias_name = dev_list[j]->get_alias_name_lower(); if (alias_name.size() != 0) { if (alias_name == dev_name) { found = true; ret_ptr = dev_list[j]; break; } } } if (found == true) break; } // // Check also the dserver device // if (found == false && dev_name.find("dserver/") == 0) { DServerClass *ds_class = DServerClass::instance(); vector &devlist = ds_class->get_device_list(); string name(devlist[0]->get_name()); transform(name.begin(),name.end(),name.begin(),::tolower); if (name == dev_name) { ret_ptr = devlist[0]; j--; } } // // Return to caller. The returned value is NULL if the device is not found // return ret_ptr; } DeviceImpl *Util::get_device_by_name(const char *dev_name) { string name_str(dev_name); return get_device_by_name(name_str); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::get_dserver_device() // // description : // To return a pointer to the dserver device automatically attached to each device server process // //------------------------------------------------------------------------------------------------------------------- DServer *Util::get_dserver_device() { return (DServer *)((DServerClass::instance()->get_device_list())[0]); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::get_device_list // // description : // Helper method to get device list from a wild card. If no device is found, does not throw exception, just return // an empty vector // // arguments : // in : // - pattern: The wildcard (e.g. "*", "/tango/tangotest/*", ...) // // returns : // The list of devices which name matches the wildcard // //------------------------------------------------------------------------------------------------------------------- std::vector Util::get_device_list (const std::string& pattern) { cout4 << "In Util::get_device_list" << endl; // the returned list std::vector dl(0); // // ------------------------------------------------------------------ // CASE I: pattern does not contain any '*' char - it's a device name // if (pattern.find('*') == std::string::npos) { DeviceImpl* dev = 0; try { dev = get_device_by_name(pattern); } catch (Tango::DevFailed&) {} // // add dev to the list // if (dev) dl.push_back(dev); return dl; } // // for the two remaining cases, we need the list of all DeviceClasses. // const std::vector dcl(*(get_class_list())); // a vector to store a given class' devices std::vector temp_dl; // // ------------------------------------------------------------------ // CASE II: pattern == "*" - return a list containing all devices // if (pattern == "*") { for (unsigned int i = 0; i < dcl.size(); i++) { temp_dl = dcl[i]->get_device_list(); dl.insert(dl.end(), temp_dl.begin(), temp_dl.end()); } return dl; } // // ------------------------------------------------------------------ // CASE III: pattern contains at least one '*' char // std::string::size_type pos; std::string::size_type last_pos = 0; std::string token; std::vector tokens(0); // // build the token list // int done = 0; do { pos = pattern.find('*', last_pos); if (pos != 0) { if (pos == std::string::npos) { if (last_pos >= pattern.size()) break; pos = pattern.size(); done = 1; } token.assign(pattern.begin() + last_pos, pattern.begin() + pos); cout4 << "Found pattern " << token << endl; tokens.push_back(token); } last_pos = pos + 1; } while (!done); // look for token(s) in device names unsigned int i, j, k; std::string dev_name; // for each DeviceClass... for (i = 0; i < dcl.size(); i++) { // ...get device list temp_dl = dcl[i]->get_device_list(); // for each device in in list... for (j = 0; j < temp_dl.size(); j++) { // get device name dev_name = temp_dl[j]->get_name(); // make sure each char is lower case std::transform(dev_name.begin(), dev_name.end(), dev_name.begin(), ::tolower); // then look for token(s) in device name // to be added to the list, device_name must contains // every token in the right order. for (k = 0, pos = 0; k < tokens.size(); k++) { pos = dev_name.find(tokens[k], pos); if (pos == std::string::npos) break; } // if dev_name matches the pattern, add the device to the list if (k == tokens.size()) { cout4 << "Device " << temp_dl[j]->get_name() << " match pattern" << endl; dl.push_back(temp_dl[j]); } } } cout4 << "Returning a device list containing " << dl.size() << " items" << endl; return dl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::unregister_server() // // description : // Unregister the server from the database // //------------------------------------------------------------------------------------------------------------------- void Util::unregister_server() { cout4 << "Entering Util::unregister_server method" << endl; // // Mark all the devices belonging to this server as unexported // if ((_UseDb == true) && (_FileDb == false)) { try { db->unexport_server(ds_name); } catch (Tango::DevFailed &e) { Except::print_exception(e); throw; } catch (CORBA::Exception &e) { Except::print_exception(e); throw; } } cout4 << "Leaving Util::unregister_server method" << endl; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::print_err_message() // // description : // Print error message in the classical console or with a message box For Linux OS, this method exits. // If it is called under Windows in a graphical environment, it throws exception // // argument : // in : // - err_mess : The error message // - type : The error type // //------------------------------------------------------------------------------------------------------------------ void Util::print_err_message(const char *err_mess,TANGO_UNUSED(Tango::MessBoxType type)) { #ifdef _TG_WINDOWS_ if (_win == true) { switch (type) { case Tango::STOP: MessageBox((HWND)NULL,err_mess,MessBoxTitle,MB_ICONSTOP); break; case Tango::INFO: MessageBox((HWND)NULL,err_mess,MessBoxTitle,MB_ICONINFORMATION); break; } Except::throw_exception((const char *)API_StartupSequence, (const char *)"Error in device server startup sequence", (const char *)"Util::print_err_mess"); } else { cerr << err_mess << endl; exit(-1); } #else cerr << err_mess << endl; _exit(-1); #endif } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::get_tango_lib_vers() // // description : // Return a number set to the Tango release number coded with 3 digits (550, 551,552,600) // //------------------------------------------------------------------------------------------------------------------ long Util::get_tango_lib_release() { return _convert_tango_lib_release(); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::clean_dyn_attr_prop() // // description : // Clean in database the dynamic attribute property(ies) // //------------------------------------------------------------------------------------------------------------------- void Util::clean_dyn_attr_prop() { if (Tango::Util::_UseDb == true) { DbData send_data; for (unsigned long loop = 0;loop < all_dyn_attr.size();loop++) { DbDatum db_dat(all_dyn_attr[loop]); send_data.push_back(db_dat); } db->delete_all_device_attribute_property(dyn_att_dev_name,send_data); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::delete_restarting_device() // // description : // Delete a device from the vector of restarting device // // arguments: // in : // - d_name : - The device name // //------------------------------------------------------------------------------------------------------------------- void Util::delete_restarting_device(string &d_name) { vector::iterator pos; pos = remove(restarting_devices.begin(),restarting_devices.end(),d_name); restarting_devices.erase(pos,restarting_devices.end()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::get_cmd_line_name_list() // // description : // Get command line device name list for a specified class // // arguments: // in : // - cl_name : The class name // out : // - name_list : Vector where device name must be stored // //------------------------------------------------------------------------------------------------------------------- void Util::get_cmd_line_name_list(const string &cl_name,vector &name_list) { string local_cl_name(cl_name); transform(local_cl_name.begin(),local_cl_name.end(),local_cl_name.begin(),::tolower); map >::iterator pos = cmd_line_name_list.find(local_cl_name); if (pos != cmd_line_name_list.end()) name_list.insert(name_list.end(),pos->second.begin(),pos->second.end()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::validate_cmd_line_classes() // // description : // Validate the class name used in DS command line argument // //------------------------------------------------------------------------------------------------------------------- void Util::validate_cmd_line_classes() { map >::iterator pos; for(pos = cmd_line_name_list.begin();pos != cmd_line_name_list.end();++pos) { if (pos->first == NoClass) continue; bool found = false; for (size_t loop = 0;loop < cl_list.size();loop++) { string cl_name = cl_list[loop]->get_name(); transform(cl_name.begin(),cl_name.end(),cl_name.begin(),::tolower); if (cl_name == pos->first) { found = true; break; } } if (found == false) { stringstream ss; ss << "Class name " << pos->first << " used on command line device declaration but this class is not embedded in DS process"; Except::throw_exception(API_WrongCmdLineArgs,ss.str(),"Util::validate_cmd_line_classes"); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::tango_host_from_fqan() // // description : // Utility method to get tango host from a fully qualified Tango attribute name // Note that it works also if the fqan is only a fully qualified Tango device name (fqdn) // // arguments: // in : // - fqan : The fully qualified Tango attribute name // out : // - tg_host : The tango host (host:port) // //------------------------------------------------------------------------------------------------------------------- void Util::tango_host_from_fqan(string &fqan,string &tg_host) { string lower_fqan(fqan); transform(lower_fqan.begin(),lower_fqan.end(),lower_fqan.begin(),::tolower); string start = lower_fqan.substr(0,5); if (start != "tango") { stringstream ss; ss << "The provided fqan (" << fqan << ") is not a valid Tango attribute name" << endl; Except::throw_exception(API_InvalidArgs,ss.str(),"Util::tango_host_from_fqan"); } string::size_type pos = lower_fqan.find('/',8); tg_host = fqan.substr(8,pos - 8); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::tango_host_from_fqan() // // description : // Utility method to get tango host from a fully qualified Tango attribute name // Note that it works also if the fqan is only a fully qualified Tango device name (fqdn) // // arguments: // in : // - fqan : The fully qualified Tango attribute name // out : // - host : The Tango host (only the host name part) // - port : The Tango db server port // //------------------------------------------------------------------------------------------------------------------- void Util::tango_host_from_fqan(string &fqan,string &host,int &port) { string tmp_tg_host; tango_host_from_fqan(fqan,tmp_tg_host); string::size_type pos = tmp_tg_host.find(':'); host = tmp_tg_host.substr(0,pos); string tmp_port = tmp_tg_host.substr(pos + 1); stringstream ss; ss << tmp_port; ss >> port; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::check_end_point_specified() // // description : // Check if the user specified a endPoint // - on the command line // - using one env. variable // - in the omniORB config file (/etc/omniORB.cfg) // If true, extract the IP address from the end point and store it for future use in the ZMQ publiher(s) // //------------------------------------------------------------------------------------------------------------------- void Util::check_end_point_specified(int argc,char *argv[]) { // // First look at command line arg // for (int i = 2;i < argc;i++) { if (::strcmp("-ORBendPoint",argv[i]) == 0) { set_endpoint_specified(true); string endPoint(argv[i + 1]); string::size_type start,stop; start = endPoint.find(':'); ++start; start = endPoint.find(':',start); stop = endPoint.find(':',start + 1); ++start; string ip = endPoint.substr(start,stop - start); set_specified_ip(ip); break; } } // // Then look in env. variables // if (get_endpoint_specified() == false) { DummyDeviceProxy d; string env_var; if (d.get_env_var("ORBendPoint",env_var) == 0) { set_endpoint_specified(true); string::size_type start,stop; start = env_var.find(':'); ++start; start = env_var.find(':',start); stop = env_var.find(':',start + 1); ++start; string ip = env_var.substr(start,stop - start); set_specified_ip(ip); } } // // Finally, look in config file but file name may be specified as command line option or as env. variable!! // if (get_endpoint_specified() == false) { // // First get file name // string fname; bool found = false; for (int i = 2;i < argc;i++) { if (::strcmp("-ORBconfigFile",argv[i]) == 0) { fname = argv[i + 1]; found = true; break; } } if (found == false) { DummyDeviceProxy d; string env_var; if (d.get_env_var("ORBconfigFile",env_var) == 0) { fname = env_var; found = true; } } if (found == false) fname = DEFAULT_OMNI_CONF_FILE; // // Now, look into the file if it exist // string line; ifstream conf_file(fname.c_str()); if (conf_file.is_open()) { while (getline(conf_file,line)) { if (line[0] == '#') continue; string::size_type pos = line.find("endPoint"); if (pos != string::npos) { string::iterator ite = remove(line.begin(),line.end(),' '); line.erase(ite,line.end()); pos = line.find('='); if (pos != string::npos) { string value = line.substr(pos+1); if ((pos = value.find('#')) != string::npos) value.erase(pos); set_endpoint_specified(true); // // Option found in file, extract host ip // string::size_type start,stop; start = value.find(':'); ++start; start = value.find(':',start); stop = value.find(':',start + 1); ++start; string ip = value.substr(start,stop - start); set_specified_ip(ip); } } } conf_file.close(); } else { if (fname != DEFAULT_OMNI_CONF_FILE) { stringstream ss; ss << "Can't open omniORB configuration file (" << fname << ") to check endPoint option" << endl; Except::throw_exception(API_InvalidArgs,ss.str(),"Util::check_end_point_specified"); } } } } #ifdef _TG_WINDOWS_ //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::build_argc_argv() // // description : // Build argc, argv UNIX like parameters from the Windows command line // //------------------------------------------------------------------------------------------------------------------- void Util::build_argc_argv() { // // Get command line // char *cmd_line = GetCommandLine(); int cnt=0; char *tmp; // // First, count how many args we have. If the user type two spaces between args, we will have too many pointers // allocates but it is not a problem // int cmd_line_size = strlen(cmd_line); for (int i = 0;i < cmd_line_size;i++) { if (cmd_line[i] == ' ') cnt++; } // // Allocate memory for argv // argv = new char *[cnt + 1]; // // If only one args, no parsing is necessary // if (cnt == 0) { argv[0] = new char [cmd_line_size + 1]; strcpy(argv[0],cmd_line); argc = 1; } else { // // Get program name // tmp = strtok(cmd_line," "); argv[0] = new char [strlen(tmp) + 1]; strcpy(argv[0],tmp); // // Get remaining args // int i = 1; while ((tmp = strtok(NULL," ")) != NULL) { argv[i] = new char [strlen(tmp) + 1]; strcpy(argv[i],tmp); i++; } argc = i; } } HWND Util::get_console_window() { return ds_window->get_output_buffer()->get_debug_window(); } HWND Util::get_ds_main_window() { return ds_window->get_win(); } CoutBuf *Util::get_debug_object() { return ds_window ? ds_window->get_output_buffer() : 0; } BOOL CtrlHandler(DWORD fdwCtrlType) { switch( fdwCtrlType ) { // Ignore logoff event! case CTRL_LOGOFF_EVENT: return TRUE; // Pass all other signals to the next signal handler default: return FALSE; } } void Util::install_cons_handler() { if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler,TRUE)) print_err_message("WARNING: Can't install the console handler"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::ORBWin32Loop::run() // // description : // Start the ORB loop. This method is in a inner class because it is started using the a separate thread. // One thread is for the Windows event loop and the second thread is for the ORB loop. // //------------------------------------------------------------------------------------------------------------------- void *Util::ORBWin32Loop::run_undetached(void *ptr) { // // Create the per thread data for the main thread // omni_thread::self()->set_value(key_py_data,new Tango::PyData()); // // Create the DServer object // try { DServerClass::init(); } catch (bad_alloc) { MessageBox((HWND)NULL,"Memory error","Device creation failed",MB_ICONSTOP); ::exit(-1); } catch (Tango::DevFailed &e) { string str(e.errors[0].desc.in()); str = str + '\n'; str = str + e.errors[0].origin.in(); MessageBox((HWND)NULL,str.c_str(),"Device creation failed",MB_ICONSTOP); ::exit(-1); } catch (CORBA::Exception &) { MessageBox((HWND)NULL,"CORBA exception","Device creation failed",MB_ICONSTOP); ::exit(-1); } // // Configure polling from polling properties // util->polling_configure(); // // Delete DB cache (if there is one) // if (util->db_cache != NULL) { // extract sub device information before deleting cache! util->get_sub_dev_diag().get_sub_devices_from_cache(); delete util->db_cache; util->db_cache = NULL; } util->set_svr_starting(false); // // Start the ORB // wait_for_go(); util->get_orb()->run(); return NULL; } void Util::ORBWin32Loop::wait_for_go() { omni_mutex_lock sync(util->mon); while(util->go == false) { util->mon.wait(); } } #endif /* _TG_WINDOWS_ */ int TangoMonitor::wait(long nb_millis) { unsigned long s,n; unsigned long nb_sec,nb_nanos; nb_sec = nb_millis / 1000 ; nb_nanos = (nb_millis - (nb_sec * 1000)) * 1000000; omni_thread::get_time(&s,&n,nb_sec,nb_nanos); return cond.timedwait(s,n); } void clear_att_dim(Tango::AttributeValue_3 &att_val) { att_val.r_dim.dim_x = 0; att_val.r_dim.dim_y = 0; att_val.w_dim.dim_x = 0; att_val.w_dim.dim_y = 0; } void clear_att_dim(Tango::AttributeValue_4 &att_val) { att_val.r_dim.dim_x = 0; att_val.r_dim.dim_y = 0; att_val.w_dim.dim_x = 0; att_val.w_dim.dim_y = 0; att_val.data_format = Tango::FMT_UNKNOWN; } void clear_att_dim(Tango::AttributeValue_5 &att_val) { att_val.r_dim.dim_x = 0; att_val.r_dim.dim_y = 0; att_val.w_dim.dim_x = 0; att_val.w_dim.dim_y = 0; att_val.data_format = Tango::FMT_UNKNOWN; att_val.data_type = 0; } // // The function called by the interceptor on thread creation // void create_PyPerThData(omni::omniInterceptors::createThread_T::info_T &info) { PyData *py_dat_ptr = new PyData(); #ifdef _TG_WINDOWS_ omni_thread::ensure_self es; #endif omni_thread::self()->set_value(key_py_data,py_dat_ptr); Util *tg = NULL; Interceptors *Inter = NULL; try { tg = Util::instance(false); Inter = tg->get_interceptors(); } catch(Tango::DevFailed &) {} if (Inter != NULL) Inter->create_thread(); info.run(); omni_thread::self()->remove_value(key_py_data); delete py_dat_ptr; if (Inter != NULL) Inter->delete_thread(); return; } AutoPyLock::AutoPyLock() { omni_thread::value_t *tmp_py_data = omni_thread::self()->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Get(); } AutoPyLock::~AutoPyLock() { omni_thread::value_t *tmp_py_data = omni_thread::self()->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Release(); } // // A small function to convert Tango lib release string to a number // // It is defined as a function to be used within the Utils and ApiUtil // classes (both client and server part) // long _convert_tango_lib_release() { long ret; ret = (TANGO_VERSION_MAJOR * 100) + (TANGO_VERSION_MINOR * 10) + TANGO_VERSION_PATCH; return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/utils_polling.cpp0000644023471100065110000015067513034745001016167 00000000000000static const char *RcsId = "$Id: utils_polling.cpp 29680 2016-04-27 13:57:50Z taurel $"; //+================================================================================================================== // // file : utils_polling.cpp // // description : C++ source for all the methods of the Util class related to polling // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29680 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::polling_configure() // // description : // This method sends command to the polling thread for all cmd/attr with polling configuration stored in db. // This is done in separate thread in order to equally spread all the polled objects polling time on the // smallest polling period. // //------------------------------------------------------------------------------------------------------------------ void Util::polling_configure() { cout4 << "Entering polling_configure()" << endl; // // Get the polling threads pool conf from the DServer device // DServer *admin_dev = get_dserver_device(); set_polling_threads_pool_size(admin_dev->get_poll_th_pool_size()); poll_pool_conf = admin_dev->get_poll_th_conf(); // // Check the coherency of the polling thread pool configuration // check_pool_conf(admin_dev,poll_pool_size); // // Send a stop polling command to thread in order not to poll devices // admin_dev->stop_polling(); vector &tmp_cl_list = admin_dev->get_class_list(); unsigned long i,j,k; int upd; TangoSys_MemStream s; // // Create the structure used to send data to the polling thread and store them in a vector // vector v_poll_cmd; vector v_poll_cmd_fwd; vector dev_db_upd; // // A loop on each class and each device in class // int smallest_upd = 0; bool first_loop = true; for (i = 0;i < tmp_cl_list.size();i++) { vector &dev_list = tmp_cl_list[i]->get_device_list(); for (j = 0;j < dev_list.size();j++) { v_poll_cmd.clear(); vector &poll_cmd_list = dev_list[j]->get_polled_cmd(); vector &poll_attr_list = dev_list[j]->get_polled_attr(); // // Check that cmd_list and attr_list have a correct syntax // if ((poll_cmd_list.size() % 2) == 1) { TangoSys_OMemStream o; o << "System property polled_cmd for device " << dev_list[j]->get_name() << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"Util::polling_configure"); } if ((poll_attr_list.size() % 2) == 1) { TangoSys_OMemStream o; o << "System property polled_attr for device " << dev_list[j]->get_name() << " has wrong syntax" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"Util::polling_configure"); } // // Check the device polling definition (existing polled cmd/attr ?) // If the polling needs to be modified, memorize the index in class and device loop to re-find it later. // int ret; if ((ret = check_dev_poll(poll_cmd_list,poll_attr_list,dev_list[j])) != 0) { DevDbUpd tmp; tmp.class_ind = i; tmp.dev_ind = j; tmp.mod_prop = ret; dev_db_upd.push_back(tmp); } // // A loop on each command // for (k = 0;k < poll_cmd_list.size();k++) { DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); send->svalue[0] = CORBA::string_dup(dev_list[j]->get_name().c_str()); send->svalue[1] = CORBA::string_dup("command"); send->svalue[2] = CORBA::string_dup(poll_cmd_list[k].c_str()); // // Convert polling period to a number and store polling thread command params // s << poll_cmd_list[k + 1]; s >> upd; s.clear(); s.str(""); send->lvalue[0] = upd; if (upd < 0) upd = -upd; if (first_loop == true) { smallest_upd = upd; first_loop = false; } else { if (upd < smallest_upd) smallest_upd = upd; } v_poll_cmd.push_back(send); k++; } // // A loop on each attribute // for (k = 0;k < poll_attr_list.size();k++) { DevVarLongStringArray *send = new DevVarLongStringArray(); send->lvalue.length(1); send->svalue.length(3); send->svalue[0] = CORBA::string_dup(dev_list[j]->get_name().c_str()); send->svalue[1] = CORBA::string_dup("attribute"); send->svalue[2] = CORBA::string_dup(poll_attr_list[k].c_str()); // // Convert polling period to a number and store polling thread command params // s << poll_attr_list[k + 1]; s >> upd; s.clear(); s.str(""); send->lvalue[0] = upd; if (upd < 0) upd = -upd; Attribute &att = dev_list[j]->get_device_attr()->get_attr_by_name(poll_attr_list[k].c_str()); if (att.is_fwd_att() == true) { v_poll_cmd_fwd.push_back(send); } else { if (first_loop == true) { smallest_upd = upd; first_loop = false; } else { if (upd < smallest_upd) smallest_upd = upd; } v_poll_cmd.push_back(send); } k++; } // // Make sure we have a thread in the pool to poll this device // unsigned long nb_cmd = v_poll_cmd.size(); if (nb_cmd != 0) { bool poll_bef_9 = false; if (admin_dev->is_polling_bef_9_def() == true) poll_bef_9 = admin_dev->get_polling_bef_9(); else if (polling_bef_9_def == true) poll_bef_9 = polling_bef_9; create_poll_thread(v_poll_cmd[0]->svalue[0],true,poll_bef_9,smallest_upd); first_loop = true; // // Copy the list of commands to send to the threads in its structure // PollingThreadInfo *th_info = get_polling_thread_info_by_id(get_polling_thread_id_by_name(v_poll_cmd[0]->svalue[0])); for (unsigned long loop = 0;loop < nb_cmd;++loop) th_info->v_poll_cmd.push_back(v_poll_cmd[loop]); } } } // // Send command to polling thread one by one for each threads. In the following computation , I try to take into // account the non real time aspect of our OS. I remove 15 mS from each sleeping time due to thread wake-up time // unsigned long nb_thread = poll_ths.size(); cout4 << "POLLING: " << nb_thread << " thread(s) needed for polling from a pool of " << get_polling_threads_pool_size() << endl; for (unsigned long loop = 0;loop < nb_thread;++loop) { unsigned long nb_cmd = poll_ths[loop]->v_poll_cmd.size(); int sleeping_time = poll_ths[loop]->smallest_upd / nb_cmd; int delta_time = 0; long delta_os = 5; if (delta_os < sleeping_time) sleeping_time = sleeping_time - delta_os; cout4 << "PollConfigureThread: smallest_upd = " << poll_ths[loop]->smallest_upd; cout4 << ", delta_time = " << sleeping_time; cout4 << ", nb_poll_objects = " << nb_cmd << endl; for (unsigned long cmd_loop = 0;cmd_loop < nb_cmd;++cmd_loop) { try { bool upd_db = false; int upd = poll_ths[loop]->v_poll_cmd[cmd_loop]->lvalue[0]; if (upd < 0) { poll_ths[loop]->v_poll_cmd[cmd_loop]->lvalue[0] = -upd; upd_db = true; } admin_dev->add_obj_polling(poll_ths[loop]->v_poll_cmd[cmd_loop],upd_db,delta_time); } catch (Tango::DevFailed &e) { bool throw_ex = true; if (::strcmp(e.errors[0].reason.in(),API_AlreadyPolled) == 0) { try { admin_dev->upd_obj_polling_period(poll_ths[loop]->v_poll_cmd[cmd_loop],false); throw_ex = false; } catch (Tango::DevFailed &) {} } if (throw_ex == true) { TangoSys_OMemStream o; o << "Error when configuring polling for device " << poll_ths[loop]->v_poll_cmd[cmd_loop]->svalue[0].in(); if (::strcmp(poll_ths[loop]->v_poll_cmd[cmd_loop]->svalue[1].in(),"command") == 0) o << ", cmd = "; else o << ", attr = "; o << poll_ths[loop]->v_poll_cmd[cmd_loop]->svalue[2].in() << ends; Except::re_throw_exception(e,(const char *)API_BadConfigurationProperty, o.str(), (const char *)"Util::polling_configure"); } } if (nb_cmd > 1) { delta_time = delta_time + sleeping_time; } } // // Delete allocated memory // for (unsigned long l = 0;l < nb_cmd;l++) delete poll_ths[loop]->v_poll_cmd[l]; } // // Send command to start polling for all forwarded attributes // for (size_t loop = 0;loop < v_poll_cmd_fwd.size();loop++) { try { bool upd_db = false; int upd = v_poll_cmd_fwd[loop]->lvalue[0]; if (upd < 0) { v_poll_cmd_fwd[loop]->lvalue[0] = -upd; upd_db = true; } admin_dev->add_obj_polling(v_poll_cmd_fwd[loop],upd_db,0); } catch (Tango::DevFailed &e) { bool throw_ex = true; if (::strcmp(e.errors[0].reason.in(),API_AlreadyPolled) == 0) { try { admin_dev->upd_obj_polling_period(v_poll_cmd_fwd[loop],false); throw_ex = false; } catch (Tango::DevFailed &) {} } if (throw_ex == true) { TangoSys_OMemStream o; o << "Error when configuring polling for device " << v_poll_cmd_fwd[loop]->svalue[0].in(); o << ", attr = "; o << v_poll_cmd_fwd[loop]->svalue[2].in() << ends; Except::re_throw_exception(e,(const char *)API_BadConfigurationProperty, o.str(), (const char *)"Util::polling_configure"); } } } // // Delete allocated memory // for (size_t l = 0;l < v_poll_cmd_fwd.size();l++) delete v_poll_cmd_fwd[l]; // // Now, start the real polling // admin_dev->start_polling(); // // If some polling related prop. (polling conf or dev conf) has to be updated in db, do it now // Add a check to verify that it is possible to store polling pool conf in database. // Property length cannot be longer than 256 characters // if (poll_pool_conf.empty() == true) { build_first_pool_conf(poll_pool_conf); conf_needs_db_upd = true; } else { vector tmp_pool_conf; build_first_pool_conf(tmp_pool_conf); if (tmp_pool_conf != poll_pool_conf) { poll_pool_conf = tmp_pool_conf; conf_needs_db_upd = true; } } if (((dev_db_upd.empty() == false) || (conf_needs_db_upd == true)) && (_UseDb == true)) upd_polling_prop(dev_db_upd,admin_dev); cout4 << "Leaving polling_configure()" << endl; } //+------------------------------------------------------------------------------------------------------------------- // // method : // Util::trigger_attr_polling() // // description : // Trigger the polling thread for polled attributes registered with a polling update period set as // "externally triggered" (0 mS) // // args : // in : // - dev : The device pointer // - name : The polled attribute name // //------------------------------------------------------------------------------------------------------------------- void Util::trigger_attr_polling(Tango::DeviceImpl *dev,const string &name) { cout4 << "Sending trigger to polling thread" << endl; // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::trigger_attr_polling"); } // // Find the wanted object in the list of device polled object // string obj_name(name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_ATTR,obj_name); // // Check that it is an externally triggered polling object. If it is not the case, throw exception // long tmp_upd = (*ite)->get_upd(); if (tmp_upd != 0) { TangoSys_OMemStream o; o << "Polling for attribute "; o << name; o << " (device " << dev->get_name() << ") "; o << " is not externally triggered."; o << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"Util::trigger_attr_polling"); } // // Find out which thread is in charge of the device. // PollingThreadInfo *th_info; int poll_th_id = get_polling_thread_id_by_name(dev->get_name_lower().c_str()); if (poll_th_id == 0) { TangoSys_OMemStream o; o << "Can't find a polling thread for device " << dev->get_name() << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"Util::trigger_cmd_polling"); } th_info = get_polling_thread_info_by_id(poll_th_id); // // Send command to the polling thread but wait in case of previous cmd still not executed // TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.trigger == true) { mon.wait(); } shared_cmd.trigger = true; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = Tango::POLL_ATTR; mon.signal(); cout4 << "Trigger sent to polling thread" << endl; // // Wait for thread to execute command // TangoMonitor &dev_mon = dev->get_dev_monitor(); omni_thread *th = omni_thread::self(); while (shared_cmd.trigger == true) { // // Warning: It's possible to have a deadlock here (experienced under // Windows) in case of this method being called from a command (or attribute // methods) which are rapidly sent by the client. // Client request cmd1 which send trigger to the polling thread // The polling thread wake up clear shared_cmd.trigger and try to // execute the command. But cmd 1 thread still owns the device monitor and // polling thread wait. cmd 1 finished and client immediately send the // command a new time. On Windows, it may happens that the polling // thread is not activated just after the cmd thread has released the // device monitor. As the client sent a new command, the device monitor // is immediately re-taken by the thread executing the new command sent by // the client. An order is sent to the polling thread and the cmd // thread reach this code. It will wait for polling thread to clear // shared_cmd.trigger. But, the polling thread is already waiting for // the device monitor and ..... deadlock.... // bool deadlock = false; long lock_ctr = 0; if (th->id() == dev_mon.get_locking_thread_id()) { cout4 << "Possible deadlock detected!" << endl; deadlock = true; lock_ctr = dev_mon.get_locking_ctr(); for (long loop = 0;loop < lock_ctr;loop++) dev_mon.rel_monitor(); } int interupted = mon.wait(DEFAULT_TIMEOUT); if (deadlock == true) { for (long loop = 0;loop < lock_ctr;loop++) dev_mon.get_monitor(); } if ((shared_cmd.trigger == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Polling thread blocked !!!", (const char *)"Util::trigger_attr_polling"); } } } cout4 << "Thread cmd normally executed" << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::trigger_cmd_polling() // // description : // Trigger the polling thread for polled command registered with a polling update period set as // "externally triggered" (0 mS) // // args : // in : // - dev : The device pointer // - name : The polled attribute name // //------------------------------------------------------------------------------------------------------------------ void Util::trigger_cmd_polling(Tango::DeviceImpl *dev,const string &name) { cout4 << "Sending trigger to polling thread" << endl; // // Check that the device is polled // if (dev->is_polled() == false) { TangoSys_OMemStream o; o << "Device " << dev->get_name() << " is not polled" << ends; Except::throw_exception((const char *)API_DeviceNotPolled,o.str(), (const char *)"Util::trigger_cmd_polling"); } // // Find the wanted object in the list of device polled object // string obj_name(name); transform(obj_name.begin(),obj_name.end(),obj_name.begin(),::tolower); vector::iterator ite = dev->get_polled_obj_by_type_name(Tango::POLL_CMD,obj_name); // // Check that it is an externally triggered polling object. If it is not the case, throw exception // long tmp_upd = (*ite)->get_upd(); if (tmp_upd != 0) { TangoSys_OMemStream o; o << "Polling for command "; o << name; o << " (device " << dev->get_name() << ") "; o << " is not externally triggered."; o << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"Util::trigger_cmd_polling"); } // // Find out which thread is in charge of the device. // PollingThreadInfo *th_info; int poll_th_id = get_polling_thread_id_by_name(dev->get_name_lower().c_str()); if (poll_th_id == 0) { TangoSys_OMemStream o; o << "Can't find a polling thread for device " << dev->get_name() << ends; Except::throw_exception((const char *)API_NotSupported,o.str(), (const char *)"Util::trigger_cmd_polling"); } th_info = get_polling_thread_info_by_id(poll_th_id); // // Send command to the polling thread but wait in case of previous cmd still not executed // TangoMonitor &mon = th_info->poll_mon; PollThCmd &shared_cmd = th_info->shared_data; { omni_mutex_lock sync(mon); if (shared_cmd.trigger == true) { mon.wait(); } shared_cmd.trigger = true; shared_cmd.dev = dev; shared_cmd.name = obj_name; shared_cmd.type = Tango::POLL_CMD; mon.signal(); cout4 << "Trigger sent to polling thread" << endl; // // Wait for thread to execute command // TangoMonitor &dev_mon = dev->get_dev_monitor(); omni_thread *th = omni_thread::self(); while (shared_cmd.trigger == true) { // // Warning: It's possible to have a deadlock here (experienced under // Windows) in case of this method being called from a command (or attribute // methods) which are rapidly sent by the client. // Client request cmd1 which send trigger to the polling thread // The polling thread wake up clear shared_cmd.trigger and try to // execute the command. But cmd 1 thread still owns the device monitor and // polling thread wait. cmd 1 finished and client immediately send the // command a new time. On Windows, it may happens that the polling // thread is not activated just after the cmd thread has released the // device monitor. As the client sent a new command, the device monitor // is immediately re-taken by the thread executing the new command sent by // the client. An order is sent to the polling thread and the cmd // thread reach this code. It will wait for polling thread to clear // shared_cmd.trigger. But, the polling thread is already waiting for // the device monitor and ..... deadlock.... // bool deadlock = false; long lock_ctr = 0; if (th->id() == dev_mon.get_locking_thread_id()) { cout4 << "Possible deadlock detected!" << endl; deadlock = true; lock_ctr = dev_mon.get_locking_ctr(); for (long loop = 0;loop < lock_ctr;loop++) dev_mon.rel_monitor(); } int interupted = mon.wait(DEFAULT_TIMEOUT); if (deadlock == true) { for (long loop = 0;loop < lock_ctr;loop++) dev_mon.get_monitor(); } if ((shared_cmd.trigger == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Polling thread blocked !!!", (const char *)"Util::trigger_cmd_polling"); } } } cout4 << "Thread cmd normally executed" << endl; } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::clean_attr_polled_prop() // // description : // Clean in database the prop used to memorized which attribute are polled // //----------------------------------------------------------------------------------------------------------------- void Util::clean_attr_polled_prop() { if (Tango::Util::_UseDb == true) { DbData send_data; DbDatum db_info("polled_attr"); for (unsigned int loop = 0;loop < polled_dyn_attr_names.size();loop++) { vector::iterator ite_attr = find(polled_att_list.begin(),polled_att_list.end(), polled_dyn_attr_names[loop]); if (ite_attr != polled_att_list.end()) { ite_attr = polled_att_list.erase(ite_attr); if (ite_attr != polled_att_list.end()) polled_att_list.erase(ite_attr); } else { TangoSys_OMemStream o; o << "Polling properties for attribute " << polled_dyn_attr_names[loop] << " on device " << dyn_att_dev_name; o << " not found device in polled attribute list!" << ends; Except::throw_exception((const char *)API_MethodArgument,o.str(), (const char *)"Util::clean_attr_polling_prop"); } } db_info << polled_att_list; send_data.push_back(db_info); if (db_info.size() == 0) db->delete_device_property(dyn_att_dev_name,send_data); else db->put_device_property(dyn_att_dev_name,send_data); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::clean_cmd_polled_prop() // // description : // Clean in database the prop used to memorized which commands are polled // //----------------------------------------------------------------------------------------------------------------- void Util::clean_cmd_polled_prop() { if (Tango::Util::_UseDb == true) { DbData send_data; DbDatum db_info("polled_cmd"); for (unsigned int loop = 0;loop < polled_dyn_cmd_names.size();loop++) { vector::iterator ite_cmd = find(polled_cmd_list.begin(),polled_cmd_list.end(), polled_dyn_cmd_names[loop]); if (ite_cmd != polled_cmd_list.end()) { ite_cmd = polled_cmd_list.erase(ite_cmd); if (ite_cmd != polled_cmd_list.end()) polled_cmd_list.erase(ite_cmd); } else { TangoSys_OMemStream o; o << "Polling properties for command " << polled_dyn_cmd_names[loop] << " on device " << dyn_cmd_dev_name; o << " not found device in polled command list!" << ends; Except::throw_exception((const char *)API_MethodArgument,o.str(), (const char *)"Util::clean_cmd_polling_prop"); } } db_info << polled_cmd_list; send_data.push_back(db_info); if (db_info.size() == 0) db->delete_device_property(dyn_cmd_dev_name,send_data); else db->put_device_property(dyn_cmd_dev_name,send_data); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::create_poll_thread() // // description : // Create a polling thread for the device specified as parameter. If the thread already exist, do nothing // If the pool is full, associate this device to an already existing thread // // args : // in : // - dev_name : The device name // - startup : True if this method is called during DS startup. In such a case, some exception should not // be thrown // - polling_9 : The polling strict period flag // - smallest_upd : The smallest upd ! // // return : // This method returns -2 if the pool conf. does not need any update. It returns -1 if a new thread has been // created. It returns the index in the pool conf of the entry which has to be modified when the device is // associated to an already existing thread // //------------------------------------------------------------------------------------------------------------------- int Util::create_poll_thread(const char *dev_name,bool startup,bool polling_9,int smallest_upd) { int ret = -2; string local_dev_name(dev_name); transform(local_dev_name.begin(),local_dev_name.end(),local_dev_name.begin(),::tolower); // // If there is already a polling thread for this device, simply returns // map::iterator ite; ite = dev_poll_th_map.find(local_dev_name); if (ite != dev_poll_th_map.end()) { if (smallest_upd != -1) { PollingThreadInfo *th_info = get_polling_thread_info_by_id(ite->second); if (smallest_upd < th_info->smallest_upd) th_info->smallest_upd = smallest_upd; } return ret; } // // Check if the pool is full // if (poll_ths.size() != poll_pool_size) { // // Get from the pool conf which device(s) have the same thread than this one // vector asso_devs; int ind; ind = get_th_polled_devs(local_dev_name,asso_devs); if (asso_devs.empty() != true) { vector::iterator it; // // If we find a thread for one of the associated device, no need to create a new one. Simply add the device entry // in the map // for (it = asso_devs.begin();it != asso_devs.end();++it) { if (*it == local_dev_name) continue; if ((ite = dev_poll_th_map.find(*it)) != dev_poll_th_map.end()) { dev_poll_th_map.insert(make_pair(local_dev_name,ite->second)); PollingThreadInfo *th_info = get_polling_thread_info_by_id(ite->second); th_info->polled_devices.push_back(local_dev_name); th_info->nb_polled_objects++; if (smallest_upd != -1) { if (smallest_upd < th_info->smallest_upd) th_info->smallest_upd = smallest_upd; } ret = ind; return ret; } } } // // Create a new polling thread and start it // PollingThreadInfo *pti_ptr = new PollingThreadInfo(); if (smallest_upd != -1) pti_ptr->smallest_upd = smallest_upd; pti_ptr->poll_th = new PollThread(pti_ptr->shared_data,pti_ptr->poll_mon,false); if (polling_9 == true) pti_ptr->poll_th->set_polling_bef_9(true); pti_ptr->poll_th->start(); int poll_th_id = pti_ptr->poll_th->id(); pti_ptr->thread_id = poll_th_id; pti_ptr->polled_devices.push_back(local_dev_name); pti_ptr->nb_polled_objects++; poll_ths.push_back(pti_ptr); dev_poll_th_map.insert(make_pair(local_dev_name,poll_th_id)); ret = -1; } else { // // Get from the pool conf which device(s) have the same thread than this one // vector asso_devs; int ind; ind = get_th_polled_devs(local_dev_name,asso_devs); if (asso_devs.empty() != true) { vector::iterator it; // // If we find a thread for one of the associated device, simply add the device entry in the map // for (it = asso_devs.begin();it != asso_devs.end();++it) { if (*it == local_dev_name) continue; if ((ite = dev_poll_th_map.find(*it)) != dev_poll_th_map.end()) { dev_poll_th_map.insert(make_pair(local_dev_name,ite->second)); if (smallest_upd != -1) { PollingThreadInfo *th_info = get_polling_thread_info_by_id(ite->second); th_info->polled_devices.push_back(local_dev_name); th_info->nb_polled_objects++; if (smallest_upd < th_info->smallest_upd) th_info->smallest_upd = smallest_upd; } ret = ind; return ret; } } } // // Find the thread with the lowest polled object number // vector::iterator iter,lower_iter; int lower_polled_objects = poll_ths[0]->nb_polled_objects; lower_iter = poll_ths.begin(); for (iter = poll_ths.begin();iter != poll_ths.end();++iter) { if ((*iter)->nb_polled_objects <= lower_polled_objects) { lower_polled_objects = (*iter)->nb_polled_objects; lower_iter = iter; } } // // Find a device already assigned to this thread and then get the device entry in the thread pool // string d_name; for (ite = dev_poll_th_map.begin();ite != dev_poll_th_map.end();++ite) { if (ite->second == (*lower_iter)->thread_id) { d_name = ite->first; break; } } if (ite == dev_poll_th_map.end()) { TangoSys_OMemStream o; o << "The polling threads pool is full.\n"; o << "Device " << dev_name << " should be polled by the thread already polling " << d_name; o << " but this device is not defined in the polled device map!!" << ends; Except::throw_exception((const char *)API_PolledDeviceNotInPoolMap,o.str(), (const char *)"Util::create_poll_thread"); } ind = get_dev_entry_in_pool_conf(d_name); if ((ind == -1) && (startup == false)) { TangoSys_OMemStream o; o << "The polling threads pool is full.\n"; o << "Device " << dev_name << " should be polled by the thread already polling " << d_name; o << " but this device is not defined in the pool configuration!!" << ends; Except::throw_exception((const char *)API_PolledDeviceNotInPoolConf,o.str(), (const char *)"Util::create_poll_thread"); } // // Assign this device to the thread which "seems" to have the less work // (*lower_iter)->polled_devices.push_back(local_dev_name); (*lower_iter)->nb_polled_objects++; dev_poll_th_map.insert(make_pair(local_dev_name,(*lower_iter)->thread_id)); if (smallest_upd != -1) { if (smallest_upd < (*lower_iter)->smallest_upd) (*lower_iter)->smallest_upd = smallest_upd; } ret = ind; } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::stop_all_polling_threads() // // description : // Stop all polling threads used in the polling thread pool // //------------------------------------------------------------------------------------------------------------------ void Util::stop_all_polling_threads() { vector::iterator iter; for (iter = poll_ths.begin();iter != poll_ths.end();++iter) { TangoMonitor &mon = (*iter)->poll_mon; PollThCmd &shared_cmd = (*iter)->shared_data; { omni_mutex_lock sync(mon); shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; mon.signal(); } // // join with the polling thread // void *dummy_ptr; (*iter)->poll_th->join(&dummy_ptr); } for (iter = poll_ths.begin();iter != poll_ths.end();++iter) delete (*iter); poll_ths.clear(); } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::stop_heartbeat_thread() // // description : // Stop the heartbeat thread // //------------------------------------------------------------------------------------------------------------------ void Util::stop_heartbeat_thread() { TangoMonitor &mon = poll_mon; PollThCmd &shared_cmd = shared_data; { omni_mutex_lock sync(mon); shared_cmd.cmd_pending = true; shared_cmd.cmd_code = POLL_EXIT; mon.signal(); } // // join with the polling thread // void *dummy_ptr; heartbeat_th->join(&dummy_ptr); } //+---------------------------------------------------------------------------------------------------------------- // // method : // Util::get_poll_th_id_by_name() // // description : // Return the ID of the thread in charge of the device polling // // args : // in : // - dev_name : The device name // // return : // If there is no thread dedicated to the device, the return value is 0 // //----------------------------------------------------------------------------------------------------------------- int Util::get_polling_thread_id_by_name(const char *dev_name) { int ret = 0; string local_dev_name(dev_name); transform(local_dev_name.begin(),local_dev_name.end(),local_dev_name.begin(),::tolower); map::iterator iter; iter = dev_poll_th_map.find(local_dev_name); if (iter != dev_poll_th_map.end()) ret = iter->second; return ret; } //+---------------------------------------------------------------------------------------------------------------- // // method : // Util::get_polling_thread_info_by_id() // // description : // Return the PollingThreadInfo for the thread with the ID specified as the input argument // // args : // in : // - id : The polling thread identifier // // return : // If there is no polling thread with this ID, throws an exception // //------------------------------------------------------------------------------------------------------------------ PollingThreadInfo *Util::get_polling_thread_info_by_id(int th_id) { PollingThreadInfo *ret_ptr = NULL; vector::iterator iter; for (iter = poll_ths.begin();iter != poll_ths.end();++iter) { if ((*iter)->thread_id == th_id) { ret_ptr = (*iter); break; } } if (iter == poll_ths.end()) { TangoSys_OMemStream o; o << "There is no polling thread with ID = " << th_id << " in the polling threads pool"<< ends; Except::throw_exception((const char *)API_PollingThreadNotFound,o.str(), (const char *)"Util::get_polling_thread_info_by_id"); } return ret_ptr; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::check_poll_conf() // // description : // Check the pool configuration coherency. This means: // - All devices defined in the pool conf has to be created in the DS // - All objects to be polled has to be coherent // - The pool size must be coherent with the conf // // args : // in : // - admin_dev : The DS admin device // - pool_size : The pool size (max number of thread) // //------------------------------------------------------------------------------------------------------------------ void Util::check_pool_conf(DServer *admin_dev,unsigned long pool_size) { // // Simply returns if the conf. is empty // if (poll_pool_conf.empty() == true) return; vector mod_conf = poll_pool_conf; // // First, get the list of devices instanciated in this server and check if the polled devices are defined within // the server // Tango::DevVarStringArray *dev_list = admin_dev->query_device(); unsigned int nb_dev = dev_list->length(); unsigned int loop; int stop = 0; vector splitted; vector::iterator iter,iter_entry; for (iter = mod_conf.begin();iter != mod_conf.end();++iter) { split_string(*iter,',',splitted); stop++; string mod_entry; for (iter_entry = splitted.begin(); iter_entry != splitted.end();++iter_entry) { // // Check that this device is not already defined // string::size_type po; if ((po = mod_entry.find(*iter_entry)) != string::npos) continue; else if (is_dev_already_in_pool_conf(*iter_entry,mod_conf,stop - 1) == true) continue; // // Check if the device is instanciated in this server // string entry_lower(*iter_entry); transform(entry_lower.begin(),entry_lower.end(),entry_lower.begin(),::tolower); for (loop = 0;loop < nb_dev;++loop) { string real_dev_name((*dev_list)[loop]); string::size_type pos; pos = real_dev_name.find(':'); pos = pos + 2; real_dev_name = real_dev_name.substr(pos); transform(real_dev_name.begin(),real_dev_name.end(),real_dev_name.begin(),::tolower); if (entry_lower == real_dev_name) break; } // // The device is not defined in the DS, remove it from the conf. (Do not copy it in the new conf built by this method) // if (loop == nb_dev) { cout << "WARNING: Device " << *iter_entry << " is used in polling threads pool configuration"; cout << " but it is not defined in DS"<< endl; cout << "The pool configuration will be automatically updated" << endl; } else { // // Now, we know that the device exists in the server, but is it really polled ? // DeviceImpl *dev = get_device_by_name(*iter_entry); vector &poll_cmd_list = dev->get_polled_cmd(); vector &poll_attr_list = dev->get_polled_attr(); if ((poll_cmd_list.empty() == true) && (poll_attr_list.empty() == true)) { cout << "WARNING: Device " << *iter_entry << " is used in polling threads pool configuration"; cout << " but it does not have any cmd/attr polled"<< endl; cout << "The pool configuration will be automatically updated" << endl; } else { if (mod_entry.empty() == true) mod_entry = *iter_entry; else mod_entry = mod_entry + ',' + *iter_entry; } } } // // Modify the conf. if some incoherencies have been found // if (mod_entry.empty() == true) { iter = mod_conf.erase(iter); if (iter == mod_conf.end()) break; else { if (iter == mod_conf.begin()) --stop; --iter; } } else if (mod_entry != *iter) *iter = mod_entry; } delete dev_list; // // Now, check that the thread defined by the conf. is <= than the pool size // if (mod_conf.size() > pool_size) { cout << "WARNING: More threads defined in the polling threads pool configuration"; cout << " than in its size ("<< mod_conf.size() << " > " << pool_size << ")" << endl; cout << "The pool configuration will be automatically updated" << endl; // // If we have more threads in the conf than in the pool, distribute the extra thread devices to the still existing // threads // long nb_extra_th = mod_conf.size() - pool_size; for (long i = 0;i < nb_extra_th;i++) { vector polled_dev_th; get_th_polled_devs(i + pool_size,polled_dev_th); unsigned long loop = 0; vector::iterator it; for (it = polled_dev_th.begin();it != polled_dev_th.end();++it) { mod_conf[loop] = mod_conf[loop] + ',' + *it; loop++; if (loop == pool_size) loop = 0; } } vector::iterator it = mod_conf.begin(); it = it + pool_size; mod_conf.erase(it,mod_conf.end()); } // // If necessary, update the conf in db // if (mod_conf != poll_pool_conf) { conf_needs_db_upd = true; poll_pool_conf = mod_conf; } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::check_dev_poll() // // description : // Check if all the cmd/attr to be polled for a device are really supported by the device // // args : // in : // - poll_cmd_list : The polled command(s) // - poll_attr_list : The polled attr(s) // - dev : The device pointer // // return : // This method returns 0 if no polling conf has been modified. Otherwise, it returns -1 if only the command list // has been modified, -2 if the only the attribute list has been modified and -3 if both of them have been // modified // //------------------------------------------------------------------------------------------------------------------ int Util::check_dev_poll(vector &poll_cmd_list,vector &poll_attr_list,DeviceImpl *dev) { int ret = 0; // // First, get device commands list // vector &cmd_list = dev->get_device_class()->get_command_list(); // // Check polled cmds // vector::iterator iter; for (iter = poll_cmd_list.begin();iter != poll_cmd_list.end();iter = iter + 2) { string polled_cmd = *iter; transform(polled_cmd.begin(),polled_cmd.end(),polled_cmd.begin(),::tolower); vector::iterator i_cmd; for (i_cmd = cmd_list.begin();i_cmd < cmd_list.end();++i_cmd) { if ((*i_cmd)->get_lower_name() == polled_cmd) break; } if (i_cmd == cmd_list.end()) { cout << "WARNING: Device " << dev->get_name() << " is configured to be polled with"; cout << " a command which does not exist anymore"<< endl; cout << "The device polling configuration will be automatically updated" << endl; ret = -1; poll_cmd_list.erase(iter,iter + 2); iter = iter - 2; } } // // Now, get device attribute list // vector &att_list = dev->get_device_attr()->get_attribute_list(); // // Check polled attributes // for (iter = poll_attr_list.begin();iter != poll_attr_list.end();iter = iter + 2) { string polled_attr = *iter; transform(polled_attr.begin(),polled_attr.end(),polled_attr.begin(),::tolower); vector::iterator i_attr; for (i_attr = att_list.begin();i_attr < att_list.end();++i_attr) { if ((*i_attr)->get_name_lower() == polled_attr) break; } if (i_attr == att_list.end()) { cout << "WARNING: Device " << dev->get_name() << " is configured to be polled with"; cout << " an attribute which does not exist anymore (" << polled_attr << ")" << endl; cout << "The device polling configuration will be automatically updated" << endl; if (ret == -1) ret = -3; else ret = -2; poll_attr_list.erase(iter,iter+2); iter = iter - 2; } } return ret; } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::split_string() // // description : // Split a string according to a delimiter // // args : // in : // - the_str : ref to the string to be plitted // - delim : The delimiter character // - splited_str : The splitted string returned in a vector of individual elt // //------------------------------------------------------------------------------------------------------------------- void Util::split_string(string &the_str,char delim,vector &splitted_str) { string::size_type pos,start; splitted_str.clear(); start = 0; while ((pos = the_str.find(delim,start)) != string::npos) { splitted_str.push_back(the_str.substr(start,pos - start)); start = pos + 1; } // // The last element // splitted_str.push_back(the_str.substr(start)); } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::upd_polling_prop() // // description : // Update polling related properties in Db // // args : // in : // - upd_devs : ref to a vector with one elt for each dev with polling prop. to be updated // - admin_dev : The DS admin device // //------------------------------------------------------------------------------------------------------------------ void Util::upd_polling_prop(vector &upd_devs,DServer *admin_dev) { vector &tmp_cl_list = admin_dev->get_class_list(); unsigned long i; // // A loop on each device with prop. to be updated // for (i = 0;i < upd_devs.size();i++) { vector &dev_list = tmp_cl_list[upd_devs[i].class_ind]->get_device_list(); vector &poll_cmd_list = dev_list[upd_devs[i].dev_ind]->get_polled_cmd(); vector &poll_attr_list = dev_list[upd_devs[i].dev_ind]->get_polled_attr(); DbData del_prop; DbData upd_prop; // // Is it necessary to update or to delete the property? // if ((upd_devs[i].mod_prop == -1) || (upd_devs[i].mod_prop == -3)) { if (poll_cmd_list.empty() == true) del_prop.push_back(DbDatum("polled_cmd")); else { upd_prop.push_back(DbDatum("polled_cmd")); upd_prop[0] << poll_cmd_list; } } if ((upd_devs[i].mod_prop == -2) || (upd_devs[i].mod_prop == -3)) { if (poll_attr_list.empty() == true) del_prop.push_back(DbDatum("polled_attr")); else { upd_prop.push_back(DbDatum("polled_attr")); upd_prop[0] << poll_attr_list; } } // // Update the database // bool retry = true; long db_retries = DB_START_PHASE_RETRIES; while (retry == true) { try { if (del_prop.empty() == false) get_database()->delete_device_property(dev_list[upd_devs[i].dev_ind]->get_name(),del_prop); if (upd_prop.empty() == false) get_database()->put_device_property(dev_list[upd_devs[i].dev_ind]->get_name(),upd_prop); retry = false; } catch (Tango::CommunicationFailed &) { if (is_svr_starting() == true) { db_retries--; if (db_retries == 0) throw; } else throw; } } // // If now the device does not have any objects polled (no cmd, no attr), it must be removed from the pool conf. // if ((poll_attr_list.empty() == true) && (poll_cmd_list.empty() == true)) { vector::iterator iter; for (iter = poll_pool_conf.begin();iter != poll_pool_conf.end();++iter) { string tmp = *iter; string &d_name = dev_list[upd_devs[i].dev_ind]->get_name(); if (tmp.find(d_name) != string::npos) { string::size_type pos; if ((pos = tmp.find(',')) == string::npos) { iter = poll_pool_conf.erase(iter); } else { tmp.erase(pos,d_name.size()); } conf_needs_db_upd = true; break; } } } } // // Update the polling pool conf if needed // if (conf_needs_db_upd == true) { DbData upd_conf; upd_conf.push_back(DbDatum("polling_threads_pool_conf")); bool retry = true; long db_retries = DB_START_PHASE_RETRIES; while (retry == true) { try { if (poll_pool_conf.empty() == true) { get_database()->delete_device_property(admin_dev->get_name(),upd_conf); } else { // // The max device property size in db is limited to 255. // If we have only one thread, it is easy to catch this threshold. In case this threshold is reached, split entry in // several sub-entries using the \ characters at the end of each sub-entries // vector::iterator iter; vector new_vect; for (iter = poll_pool_conf.begin();iter != poll_pool_conf.end();++iter) { string v_entry = *iter; unsigned int length = v_entry.size(); int nb_lines = (length / MaxDevPropLength) + 1; if (nb_lines > 1) { string::size_type start; start = 0; for (int i = 0;i < nb_lines;i++) { string sub = v_entry.substr(start,MaxDevPropLength); if (i < (nb_lines - 1)) sub = sub + '\\'; start = start + MaxDevPropLength; new_vect.push_back(sub); } } else new_vect.push_back(v_entry); } upd_conf[0] << new_vect; get_database()->put_device_property(admin_dev->get_name(),upd_conf); } retry = false; } catch (Tango::CommunicationFailed &) { if (is_svr_starting() == true) { db_retries--; if (db_retries == 0) throw; } else throw; } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::get_th_polled_devs() // // description : // Get from the polling pool configuration which devices should be polled by the thread which is in charge of // device dev // // args : // in : // - dev : The device name // - th_polled_devs : List of devices also polled by the thread in charge of dev // //------------------------------------------------------------------------------------------------------------------ int Util::get_th_polled_devs(string &dev,vector &th_polled_devs) { th_polled_devs.clear(); vector::iterator iter; unsigned int dev_nb_char = dev.size(); unsigned int pool_dev_nb_char; for (iter = poll_pool_conf.begin();iter != poll_pool_conf.end();++iter) { string tmp = *iter; transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); string::size_type pos,end_pos; pos = tmp.find(dev); if (pos != string::npos) { end_pos = tmp.find(',',pos); if (end_pos != string::npos) pool_dev_nb_char = end_pos - pos; else pool_dev_nb_char = tmp.size() - pos; if (dev_nb_char == pool_dev_nb_char) { split_string(tmp,',',th_polled_devs); break; } } } return iter - poll_pool_conf.begin(); } void Util::get_th_polled_devs(long i,vector &th_polled_devs) { th_polled_devs.clear(); string tmp = poll_pool_conf[i]; split_string(tmp,',',th_polled_devs); } //+---------------------------------------------------------------------------------------------------------------- // // method : // Util::build_first_pool_conf() // // description : // Create a polling tread pool configuration when this data is not defined // // args : // out : // - pool_conf : The polling threads pool configuration // //------------------------------------------------------------------------------------------------------------------ void Util::build_first_pool_conf(vector &pool_conf) { vector::iterator iter; for (iter = poll_ths.begin();iter != poll_ths.end();++iter) { string tmp; vector::iterator it; for (it = (*iter)->polled_devices.begin();it != (*iter)->polled_devices.end();++it) { if (it != (*iter)->polled_devices.begin()) tmp = tmp + ',' + *it; else tmp = *it; } pool_conf.push_back(tmp); } } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::is_dev_already_in_pool_conf() // // description : // Check if a device is already defined in the pool conf // // args : // in : // - dev_name : The device name // - pool : The polling threads pool configuration // - stop : The index in poll conf where the search should be stopped // // return : // This method returns true if the device is already defined in the pool. Otherwise, returns false (amazing no!) // //-------------------------------------------------------------------------------------------------------------------- bool Util::is_dev_already_in_pool_conf(string &dev_name,vector& pool,int stop) { vector::iterator iter; for (iter = pool.begin();iter != pool.begin() + stop;++iter) { vector dev_list; vector::iterator it; split_string(*iter,',',dev_list); for (it = dev_list.begin();it != dev_list.end();++it) { if (*it == dev_name) return true; } } return false; } //+----------------------------------------------------------------------------------------------------------------- // // method : // Util::get_dev_entry_in_pool_conf() // // description : // Get in which entry a device is used in the pool conf // // args : // in : // - dev_name : The device name // // return : // This method returns the index in the pool conf if the device has been found. Otherwise, it returns -1 // //--------------------------------------------------------------------------------------------------------------------- int Util::get_dev_entry_in_pool_conf(string &dev_name) { vector::iterator iter; unsigned int dev_nb_char = dev_name.size(); unsigned int pool_dev_nb_char; for (iter = poll_pool_conf.begin();iter != poll_pool_conf.end();++iter) { string tmp = *iter; string::size_type pos,end_pos; pos = tmp.find(dev_name); if (pos != string::npos) { end_pos = tmp.find(',',pos); if (end_pos != string::npos) pool_dev_nb_char = end_pos - pos; else pool_dev_nb_char = tmp.size() - pos; if (dev_nb_char == pool_dev_nb_char) { break; } } } if (iter != poll_pool_conf.end()) return iter - poll_pool_conf.begin(); else return -1; } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::remove_dev_from_polling_map() // // description : // Remove the device from the polled device map // // args : // in : // - dev_name : The device name // //------------------------------------------------------------------------------------------------------------------- void Util::remove_dev_from_polling_map(string &dev_name) { map::iterator iter; iter = dev_poll_th_map.find(dev_name); if (iter != dev_poll_th_map.end()) dev_poll_th_map.erase(iter); } //+------------------------------------------------------------------------------------------------------------------ // // method : // Util::remove_polling_thread_info_by_id() // // description : // Remove all the polling thread info from the vector of polling thread info for a specific thread // // args : // in : // - th_id : The polling thread id // //------------------------------------------------------------------------------------------------------------------- void Util::remove_polling_thread_info_by_id(int th_id) { vector::iterator iter; for (iter = poll_ths.begin();iter != poll_ths.end();++iter) { if ((*iter)->thread_id == th_id) { delete (*iter); poll_ths.erase(iter); return; } } if (iter == poll_ths.end()) { TangoSys_OMemStream o; o << "There is no polling thread with ID = " << th_id << " in the polling threads pool"<< ends; Except::throw_exception((const char *)API_PollingThreadNotFound,o.str(), (const char *)"Util::remove_polling_thread_info_by_id"); } return; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/utils_shut.cpp0000644023471100065110000001072013034745001015470 00000000000000static const char *RcsId = "$Id: utils_shut.cpp 27410 2015-01-27 05:46:17Z taurel $"; //+============================================================================= // // file : utils_shut.cpp // // description : C++ source for some methods of the Util class related // to server shutdown // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include extern omni_thread::key_t key_py_data; namespace Tango { //+---------------------------------------------------------------------------- // // method : Util::shutdown_ds() // // description : This method sends command to the polling thread for // all cmd/attr with polling configuration stored in db. // This is done in separate thread in order to equally // spread all the polled objects polling time on the // smallest polling period. // //----------------------------------------------------------------------------- void Util::shutdown_ds() { // // Stopping a device server means : // - Mark the server as shutting down // - Send kill command to the polling thread // - Join with this polling thread // - Unregister server in database // - Delete devices (except the admin one) // - Stop the KeepAliveThread and the EventConsumer Thread when // they have been started to receive events // - Force writing file database in case of // - Shutdown the ORB // - Cleanup Logging // set_svr_shutting_down(true); // // send the exit command to all the polling threads in the pool // stop_all_polling_threads(); stop_heartbeat_thread(); clr_heartbeat_th_ptr(); // // Unregister the server in the database // try { unregister_server(); } catch(...) {} // // Delete the devices (except the admin one) // Protect python data // omni_thread::value_t *tmp_py_data = omni_thread::self()->get_value(key_py_data); PyLock *lock_ptr = (static_cast(tmp_py_data))->PerTh_py_lock; lock_ptr->Get(); get_dserver_device()->delete_devices(); lock_ptr->Release(); // // Stop the KeepAliveThread and the EventConsumer thread when // they have been started to receive events. // ApiUtil *au = ApiUtil::instance(); if (au->is_notifd_event_consumer_created() == true) { NotifdEventConsumer *ec = ApiUtil::instance()->get_notifd_event_consumer(); if (ec != NULL) ec->shutdown(); } if (au->is_zmq_event_consumer_created() == true) { ZmqEventConsumer *ec = ApiUtil::instance()->get_zmq_event_consumer(); if (ec != NULL) ec->shutdown(); } // // Disconnect the server from the notifd, when it was connected // NotifdEventSupplier *ev = get_notifd_event_supplier(); if (ev != NULL) ev->disconnect_from_notifd(); // // Delete ZmqEventSupplier // ZmqEventSupplier *zev = get_zmq_event_supplier(); delete zev; // // Close access to file database when used // if (_FileDb == true) { Database *db_ptr = get_database(); db_ptr->write_filedatabase(); delete db_ptr; cout4 << "Database object deleted" << endl; } // // If the server uses its own event loop, do not call it any more // if (is_server_event_loop_set()) set_shutdown_server(true); // // Shutdown the ORB // cout4 << "Going to shutdown ORB" << endl; CORBA::ORB_ptr loc_orb = get_orb(); loc_orb->shutdown(true); cout4 << "ORB shutdown" << endl; #ifdef TANGO_HAS_LOG4TANGO // clean-up the logging system Logging::cleanup(); cout4 << "Logging cleaned-up" << endl; #endif } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/w_attribute.cpp0000644023471100065110000026674713034745001015644 00000000000000static const char *RcsId = "$Id: w_attribute.cpp 29692 2016-04-29 06:16:37Z taurel $\n$Name$"; //+============================================================================ // // file : w_attribute.cpp // // description : C++ source code for the WAttribute class. // This class is used to manage attribute. // A Tango Device object instance has one // MultiAttribute object which is an aggregate of // Attribute or WAttribute objects // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 29692 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #include #else #include #endif /* _TG_WINDOWS_ */ namespace Tango { //+------------------------------------------------------------------------- // // method : WAttribute::WAttribute // // description : constructor for the WAttribute class from the // attribute property vector, its type and the device // name // // argument : in : - prop_list : The attribute property list // - type : The attrubute data type // - dev_name : The device name // //-------------------------------------------------------------------------- WAttribute::WAttribute(vector &prop_list, Attr &tmp_attr,string &dev_name,long idx) :Attribute(prop_list,tmp_attr,dev_name,idx), long_ptr(NULL),double_ptr(NULL),str_ptr(NULL),float_ptr(NULL), boolean_ptr(NULL),ushort_ptr(NULL),uchar_ptr(NULL),encoded_ptr(NULL), string_allocated(false),memorized(false),memorized_init(false),w_ext(new WAttributeExt), long64_ptr(NULL),ulong_ptr(NULL),ulong64_ptr(NULL),state_ptr(NULL),uswv(false),mem_write_failed(false) { // // Init some data // short_val = old_short_val = 0; long_val = old_long_val = 0; double_val = old_double_val = 0.0; float_val = old_float_val = 0.0; boolean_val = old_boolean_val = true; ushort_val = old_ushort_val = 0; uchar_val = old_uchar_val = 0; long64_val = old_long64_val = 0; ulong_val = old_ulong_val = 0; ulong64_val = old_ulong64_val = 0; dev_state_val = old_dev_state_val = Tango::UNKNOWN; str_val = CORBA::string_dup("Not initialised"); old_str_val = CORBA::string_dup("Not initialised"); encoded_val.encoded_data.length(0); encoded_val.encoded_format = CORBA::string_dup("Not initialised"); old_encoded_val.encoded_data.length(0); old_encoded_val.encoded_format = CORBA::string_dup("Not initialised"); short_array_val.length(1); short_array_val[0] = 0; long_array_val.length(1); long_array_val[0] = 0; double_array_val.length(1); double_array_val[0] = 0.0; str_array_val.length(1); str_array_val[0] = CORBA::string_dup("Not initialised"); float_array_val.length(1); float_array_val[0] = 0.0; boolean_array_val.length(1); boolean_array_val[0] = true; ushort_array_val.length(1); ushort_array_val[0] = 0; uchar_array_val.length(1); uchar_array_val[0] = 0; long64_array_val.length(1); long64_array_val[0] = 0; ulong_array_val.length(1); ulong_array_val[0] = 0; ulong64_array_val.length(1); ulong64_array_val[0] = 0; state_array_val.length(1); state_array_val[0] = Tango::UNKNOWN; short_ptr = &short_val; w_dim_x = 1; w_dim_y = 0; write_date.tv_sec = write_date.tv_usec = 0; // // Init memorized field and eventually get the memorized value // set_memorized(tmp_attr.get_memorized()); set_memorized_init(tmp_attr.get_memorized_init()); if (is_memorized() == true) { try { mem_value = get_attr_value(prop_list,MemAttrPropName); } catch (Tango::DevFailed &) { mem_value = MemNotUsed; } } } //+------------------------------------------------------------------------- // // method : WAttribute::~WAttribute // // description : destructor for the WAttribute class // //-------------------------------------------------------------------------- WAttribute::~WAttribute() { #ifndef HAS_UNIQUE_PTR delete w_ext; #endif CORBA::string_free(str_val); CORBA::string_free(old_str_val); // CORBA::string_free(encoded_val.encoded_format); // CORBA::string_free(old_encoded_val.encoded_format); } //+------------------------------------------------------------------------------------------------------------------ // // method : // WAttribute::set_rvalue // // description : // This method is used when a Writable attribute is set to set the value in the Attribute class. This is // necessary for the read_attribute CORBA operation which takes its data from this internal Attribute // class data. It is used in the read_attributes code in the device class // //-------------------------------------------------------------------------------------------------------------------- void WAttribute::set_rvalue() { switch(data_type) { case Tango::DEV_SHORT: case Tango::DEV_ENUM: if (data_format == Tango::SCALAR) set_value(&short_val,1,0,false); else set_value(const_cast(short_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_LONG: if (data_format == Tango::SCALAR) set_value(&long_val,1,0,false); else set_value(const_cast(long_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_LONG64: if (data_format == Tango::SCALAR) set_value(&long64_val,1,0,false); else set_value(const_cast(long64_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_DOUBLE: if (data_format == Tango::SCALAR) set_value(&double_val,1,0,false); else set_value(const_cast(double_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_STRING: if (data_format == Tango::SCALAR) set_value(&str_val,1,0,false); else set_value(const_cast(str_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_FLOAT: if (data_format == Tango::SCALAR) set_value(&float_val,1,0,false); else set_value(const_cast(float_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_BOOLEAN: if (data_format == Tango::SCALAR) set_value(&boolean_val,1,0,false); else set_value(const_cast(boolean_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_USHORT: if (data_format == Tango::SCALAR) set_value(&ushort_val,1,0,false); else set_value(const_cast(ushort_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_UCHAR: if (data_format == Tango::SCALAR) set_value(&uchar_val,1,0,false); else set_value(const_cast(uchar_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_ULONG: if (data_format == Tango::SCALAR) set_value(&ulong_val,1,0,false); else set_value(const_cast(ulong_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_ULONG64: if (data_format == Tango::SCALAR) set_value(&ulong64_val,1,0,false); else set_value(const_cast(ulong64_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_STATE: if (data_format == Tango::SCALAR) set_value(&dev_state_val,1,0,false); else set_value(const_cast(state_array_val.get_buffer()),w_dim_x,w_dim_y,false); break; case Tango::DEV_ENCODED: set_value(&encoded_val,1,0,false); break; } } //+------------------------------------------------------------------------- // // method : WAttribute::check_written_value // // description : Check the value sent by the caller and copy incoming data // for SCALAR attribute only // // in : any : Reference to the CORBA Any object // //-------------------------------------------------------------------------- void WAttribute::check_written_value(const CORBA::Any &any,unsigned long x,unsigned long y) { CORBA::ULong nb_data; unsigned long i; // // If the server is in its starting phase, gives a NULL ptr // to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { // // Check data type inside the any and data number // const Tango::DevVarShortArray *sh_ptr; if ((any >>= sh_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarShortArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = sh_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value against min or max_value if needed // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*sh_ptr)[i] < min_value.sh) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*sh_ptr)[i] > max_value.sh) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } short_ptr = sh_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_short_val = short_val; short_val = (*sh_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_LONG : { // // Check data type inside the any // const Tango::DevVarLongArray *lg_ptr; if ((any >>= lg_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarLongArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = lg_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*lg_ptr)[i] < min_value.lg) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*lg_ptr)[i] > max_value.lg) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } long_ptr = lg_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_long_val = long_val; long_val = (*lg_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_LONG64 : { // // Check data type inside the any // const Tango::DevVarLong64Array *lg64_ptr; if ((any >>= lg64_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarLong64Array (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = lg64_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*lg64_ptr)[i] < min_value.lg64) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*lg64_ptr)[i] > max_value.lg64) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } long64_ptr = lg64_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_long64_val = long64_val; long64_val = (*lg64_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_DOUBLE : { // // Check data type inside the any // const Tango::DevVarDoubleArray *db_ptr; if ((any >>= db_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarDoubleArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = db_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // First check for NaN, INF // { AutoTangoMonitor sync1(mon_ptr); for (i = 0;i < nb_data;i++) { if (tg->is_wattr_nan_allowed() == false) { #ifdef _TG_WINDOWS_ if (_finite((*db_ptr)[i]) == 0) #else if (isfinite((*db_ptr)[i]) == 0) #endif { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is a NaN or INF value (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_min_value == true) { if ((*db_ptr)[i] < min_value.db) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_max_value == true) { if ((*db_ptr)[i] > max_value.db) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } double_ptr = db_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_double_val = double_val; double_val = (*db_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_STRING : // // Check data type inside the any // const Tango::DevVarStringArray *string_ptr; if ((any >>= string_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarStringArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = string_ptr->length(); check_length(nb_data,x,y); str_ptr = string_ptr->get_buffer(); if (data_format == Tango::SCALAR) { CORBA::string_free(old_str_val); old_str_val = CORBA::string_dup(str_val); CORBA::string_free(str_val); str_val = CORBA::string_dup((*string_ptr)[0]); w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } break; case Tango::DEV_FLOAT : { // // Check data type inside the any // const Tango::DevVarFloatArray *fl_ptr; if ((any >>= fl_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarFloatArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = fl_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // First check for NaN, INF // { AutoTangoMonitor sync1(mon_ptr); for (i = 0;i < nb_data;i++) { if (tg->is_wattr_nan_allowed() == false) { #ifdef _TG_WINDOWS_ if (_finite((*fl_ptr)[i]) == 0) #else if (isfinite((*fl_ptr)[i]) == 0) #endif { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is a NaN or INF value (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_min_value == true) { if ((*fl_ptr)[i] < min_value.fl) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_max_value == true) { if ((*fl_ptr)[i] > max_value.fl) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } float_ptr = fl_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_float_val = float_val; float_val = (*fl_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_USHORT : { // // Check data type inside the any // const Tango::DevVarUShortArray *ush_ptr; if ((any >>= ush_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarUShortArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = ush_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*ush_ptr)[i] < min_value.ush) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*ush_ptr)[i] > max_value.ush) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } ushort_ptr = ush_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_ushort_val = ushort_val; ushort_val = (*ush_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_UCHAR : { // // Check data type inside the any // const Tango::DevVarCharArray *uch_ptr; if ((any >>= uch_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarCharArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = uch_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*uch_ptr)[i] < min_value.uch) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*uch_ptr)[i] > max_value.uch) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } uchar_ptr = uch_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_uchar_val = uchar_val; uchar_val = (*uch_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_ULONG : { // // Check data type inside the any // const Tango::DevVarULongArray *ulo_ptr; if ((any >>= ulo_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarULongArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = ulo_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*ulo_ptr)[i] < min_value.ulg) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*ulo_ptr)[i] > max_value.ulg) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } ulong_ptr = ulo_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_ulong_val = ulong_val; ulong_val = (*ulo_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_ULONG64 : { // // Check data type inside the any // const Tango::DevVarULong64Array *ulg64_ptr; if ((any >>= ulg64_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarULong64Array (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = ulg64_ptr->length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); if (check_min_value == true) { for (i = 0;i < nb_data;i++) { if ((*ulg64_ptr)[i] < min_value.ulg64) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { if ((*ulg64_ptr)[i] > max_value.ulg64) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } ulong64_ptr = ulg64_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_ulong64_val = ulong64_val; ulong64_val = (*ulg64_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_BOOLEAN : // // Check data type inside the any // const Tango::DevVarBooleanArray *boo_ptr; if ((any >>= boo_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarBooleanArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = boo_ptr->length(); check_length(nb_data,x,y); boolean_ptr = boo_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_boolean_val = boolean_val; boolean_val = (*boo_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } break; case Tango::DEV_STATE : { // // Check data type inside the any // const Tango::DevVarStateArray *sta_ptr; if ((any >>= sta_ptr) == false) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarStateArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } nb_data = sta_ptr->length(); check_length(nb_data,x,y); state_ptr = sta_ptr->get_buffer(); if (data_format == Tango::SCALAR) { old_dev_state_val = dev_state_val; dev_state_val = (*sta_ptr)[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; } } void WAttribute::check_written_value(const Tango::AttrValUnion &att_union,unsigned long x,unsigned long y) { unsigned int nb_data; unsigned int i; // // If the server is in its starting phase, gives a NULL ptr // to the AutoLock object // Tango::Util *tg = Tango::Util::instance(); Tango::TangoMonitor *mon_ptr = NULL; if (tg->is_svr_starting() == false && tg->is_device_restarting(d_name) == false) mon_ptr = &(get_att_device()->get_att_conf_monitor()); switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : { // // Check data type inside the union and data number // if (att_union._d() != ATT_SHORT) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarShortArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarShortArray &sh_seq = att_union.short_att_value(); nb_data = sh_seq.length(); check_length(nb_data,x,y); // // Check the incoming value against min or max_value if needed // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,sh_seq,min_value.sh,max_value.sh); } short_ptr = sh_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_short_val = short_val; short_val = sh_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } // // If the attribute is enumerated, check the input value compared to the enum labels // if (get_data_type() == DEV_ENUM) { int max_val = enum_labels.size() - 1; for (i = 0;i < nb_data;i++) { if (sh_seq[i] < 0 || sh_seq[i] > max_val) { stringstream ss; ss << "Set value for attribute " << name; ss << " is negative or above the maximun authorized (" << max_val << ") for at least element " << i; Except::throw_exception(API_WAttrOutsideLimit,ss.str(),"WAttribute::check_written_value()"); } } } } break; case Tango::DEV_LONG : { // // Check data type inside the union // if (att_union._d() != ATT_LONG) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarLongArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarLongArray &lg_seq = att_union.long_att_value(); nb_data = lg_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,lg_seq,min_value.lg,max_value.lg); } long_ptr = lg_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_long_val = long_val; long_val = lg_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_LONG64 : { // // Check data type inside the union // if (att_union._d() != ATT_LONG64) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarLong64Array (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarLong64Array &lg64_seq = att_union.long64_att_value(); nb_data = lg64_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,lg64_seq,min_value.lg64,max_value.lg64); } long64_ptr = lg64_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_long64_val = long64_val; long64_val = lg64_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_DOUBLE : { // // Check data type inside the union // if (att_union._d() != ATT_DOUBLE) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarDoubleArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarDoubleArray &db_seq = att_union.double_att_value(); nb_data = db_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // First check for NaN, INF // { AutoTangoMonitor sync1(mon_ptr); for (i = 0;i < nb_data;i++) { if (tg->is_wattr_nan_allowed() == false) { #ifdef _TG_WINDOWS_ if (_finite(db_seq[i]) == 0) #else if (isfinite(db_seq[i]) == 0) #endif { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is a NaN or INF value (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_min_value == true) { if (db_seq[i] < min_value.db) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_max_value == true) { if (db_seq[i] > max_value.db) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } double_ptr = db_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_double_val = double_val; double_val = db_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_STRING : { // // Check data type inside the union // if (att_union._d() != ATT_STRING) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarStringArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarStringArray &string_seq = att_union.string_att_value(); nb_data = string_seq.length(); check_length(nb_data,x,y); str_ptr = string_seq.get_buffer(); if (data_format == Tango::SCALAR) { CORBA::string_free(old_str_val); old_str_val = CORBA::string_dup(str_val); CORBA::string_free(str_val); str_val = CORBA::string_dup(string_seq[0]); w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_FLOAT : { // // Check data type inside the union // if (att_union._d() != ATT_FLOAT) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarFloatArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarFloatArray &fl_seq = att_union.float_att_value(); nb_data = fl_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // First check for NaN, INF // { AutoTangoMonitor sync1(mon_ptr); for (i = 0;i < nb_data;i++) { if (tg->is_wattr_nan_allowed() == false) { #ifdef _TG_WINDOWS_ if (_finite(fl_seq[i]) == 0) #else if (isfinite(fl_seq[i]) == 0) #endif { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is a NaN or INF value (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_min_value == true) { if (fl_seq[i] < min_value.fl) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } if (check_max_value == true) { if (fl_seq[i] > max_value.fl) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } float_ptr = fl_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_float_val = float_val; float_val = fl_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_USHORT : { // // Check data type inside the union // if (att_union._d() != ATT_USHORT) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarUShortArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarUShortArray &ush_seq = att_union.ushort_att_value(); nb_data = ush_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,ush_seq,min_value.ush,max_value.ush); } ushort_ptr = ush_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_ushort_val = ushort_val; ushort_val = ush_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_UCHAR : { // // Check data type inside the union // if (att_union._d() != ATT_UCHAR) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarCharArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarCharArray &uch_seq = att_union.uchar_att_value(); nb_data = uch_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,uch_seq,min_value.uch,max_value.uch); } uchar_ptr = uch_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_uchar_val = uchar_val; uchar_val = uch_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_ULONG : { // // Check data type inside the union // if (att_union._d() != ATT_ULONG) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarULongArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarULongArray &ulo_seq = att_union.ulong_att_value(); nb_data = ulo_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,ulo_seq,min_value.ulg,max_value.ulg); } ulong_ptr = ulo_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_ulong_val = ulong_val; ulong_val = ulo_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_ULONG64 : { // // Check data type inside the union // if (att_union._d() != ATT_ULONG64) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarULong64Array (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarULong64Array &ulo64_seq = att_union.ulong64_att_value(); nb_data = ulo64_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // { AutoTangoMonitor sync1(mon_ptr); check_min_max(nb_data,ulo64_seq,min_value.ulg64,max_value.ulg64); } ulong64_ptr = ulo64_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_ulong64_val = ulong64_val; ulong64_val = ulo64_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_STATE : { // // Check data type inside the union // if (att_union._d() != ATT_STATE) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarStateArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarStateArray &sta_seq = att_union.state_att_value(); nb_data = sta_seq.length(); check_length(nb_data,x,y); // // Check the incoming value // check_min_max(nb_data,sta_seq,min_value.d_sta,max_value.d_sta); state_ptr = sta_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_dev_state_val = dev_state_val; dev_state_val = sta_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_BOOLEAN : { // // Check data type inside the union // if (att_union._d() != ATT_BOOL) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarBooleanArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarBooleanArray &boo_seq = att_union.bool_att_value(); nb_data = boo_seq.length(); check_length(nb_data,x,y); boolean_ptr = boo_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_boolean_val = boolean_val; boolean_val = boo_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; case Tango::DEV_ENCODED : { if (att_union._d() != ATT_ENCODED) { TangoSys_OMemStream o; o << "Incompatible attribute type, expected type is : Tango::DevVarEncodedArray (even for single value)" << ends; Except::throw_exception((const char *)API_IncompatibleAttrDataType, o.str(), (const char *)"WAttribute::check_written_value()"); } const Tango::DevVarEncodedArray &enc_seq = att_union.encoded_att_value(); nb_data = enc_seq.length(); check_length(nb_data,x,y); // // Check the incoming value against min or max_value if needed // { AutoTangoMonitor sync1(mon_ptr); unsigned int j; if (check_min_value == true) { for (i = 0;i < nb_data;i++) { CORBA::ULong nb_data_elt = enc_seq[i].encoded_data.length(); for (j = 0;j < nb_data_elt;j++) { if (enc_seq[i].encoded_data[j] < min_value.uch) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is below the minimum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } if (check_max_value == true) { for (i = 0;i < nb_data;i++) { CORBA::ULong nb_data_elt = enc_seq[i].encoded_data.length(); for (j = 0;j < nb_data_elt;j++) { if (enc_seq[i].encoded_data[j] > max_value.uch) { TangoSys_OMemStream o; o << "Set value for attribute " << name; o << " is above the maximum authorized (at least element " << i << ")" << ends; Except::throw_exception((const char *)API_WAttrOutsideLimit, o.str(), (const char *)"WAttribute::check_written_value()"); } } } } } encoded_ptr = enc_seq.get_buffer(); if (data_format == Tango::SCALAR) { old_encoded_val = encoded_val; encoded_val = enc_seq[0]; w_dim_x = 1; w_dim_y = 0; } else { w_dim_x = x; w_dim_y = y; } } break; } } //+------------------------------------------------------------------------- // // method : WAttribute::get_write_value_length // // description : Returm to the caller the length of the new value to // be written into the attribute // //-------------------------------------------------------------------------- long WAttribute::get_write_value_length() { long ret_val; if (data_format == Tango::SCALAR) ret_val = 1; else if (data_format == Tango::SPECTRUM) ret_val = w_dim_x; else ret_val = w_dim_x * w_dim_y; return ret_val; } //+------------------------------------------------------------------------------------------------------------------- // // method : // WAttribute::set_write_value() methods // // description : // Set the attribute internal value. There are different methods according to the attribute data type and the // attribute type (scalar, spectrum or image) // //------------------------------------------------------------------------------------------------------------------- // DevShort: void WAttribute::set_write_value(Tango::DevShort val) { CORBA::Any tmp_any; Tango::DevVarShortArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevShort *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarShortArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarShortArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevLong: void WAttribute::set_write_value(Tango::DevLong val) { Tango::DevVarLongArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevLong *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarLongArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarLongArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevLong64: void WAttribute::set_write_value(Tango::DevLong64 val) { Tango::DevVarLong64Array tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevLong64 *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarLong64Array tmp_seq(nb_data, nb_data, val, false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarLong64Array tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevDouble: void WAttribute::set_write_value(Tango::DevDouble val) { Tango::DevVarDoubleArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevDouble *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarDoubleArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { CORBA::Any tmp_any; Tango::DevVarDoubleArray tmp_seq(val.size(),val.size(),&val[0],false); tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevString: void WAttribute::set_write_value(Tango::DevString val) { Tango::DevVarStringArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = CORBA::string_dup(val); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(string &val) { Tango::DevVarStringArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val.c_str(); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevString *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarStringArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarStringArray tmp_seq; tmp_seq << val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevFloat: void WAttribute::set_write_value(Tango::DevFloat val) { Tango::DevVarFloatArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevFloat *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarFloatArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarFloatArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevBoolean: void WAttribute::set_write_value(Tango::DevBoolean val) { Tango::DevVarBooleanArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevBoolean *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarBooleanArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarBooleanArray tmp_seq; tmp_seq << val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevUShort: void WAttribute::set_write_value(Tango::DevUShort val) { Tango::DevVarUShortArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevUShort *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarUShortArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarUShortArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevUChar: void WAttribute::set_write_value(Tango::DevUChar val) { Tango::DevVarCharArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevUChar *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarUCharArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarUCharArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevULong: void WAttribute::set_write_value(Tango::DevULong val) { Tango::DevVarULongArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevULong *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarULongArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarULongArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevULong64: void WAttribute::set_write_value(Tango::DevULong64 val) { Tango::DevVarULong64Array tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevULong64 *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarULong64Array tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarULong64Array tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } // DevState: void WAttribute::set_write_value(Tango::DevState val) { Tango::DevVarStateArray tmp_seq(1); tmp_seq.length(1); tmp_seq[0] = val; CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any,1,0); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevState *val, long x, long y) { long nb_data; if (y == 0) nb_data = x; else nb_data = x * y; Tango::DevVarStateArray tmp_seq(nb_data,nb_data,val,false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(vector &val, long x, long y) { Tango::DevVarStateArray tmp_seq(val.size(),val.size(),&val[0],false); CORBA::Any tmp_any; tmp_any <<= tmp_seq; check_written_value(tmp_any, x, y); copy_data(tmp_any); set_user_set_write_value(true); } void WAttribute::set_write_value(Tango::DevEncoded *, TANGO_UNUSED(long x),TANGO_UNUSED(long y)) { // // Dummy method just to make compiler happy when using fill_attr_polling_buffer for DevEncoded // attribute // Should never be called // Tango::Except::throw_exception((const char *)API_NotSupportedFeature, (const char *)"This is a not supported call in case of DevEncoded attribute", (const char *)"Wattribute::set_write_value()"); } //+------------------------------------------------------------------------- // // method : WAttribute::rollback // // description : Reset the internal data to its value before the // set_write_value method was applied (Useful in case of // error in the set_write_value method) // //-------------------------------------------------------------------------- void WAttribute::rollback() { switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : short_val = old_short_val; break; case Tango::DEV_LONG : long_val = old_long_val; break; case Tango::DEV_LONG64 : long64_val = old_long64_val; break; case Tango::DEV_DOUBLE : double_val = old_double_val; break; case Tango::DEV_STRING : CORBA::string_free(str_val); str_val = CORBA::string_dup(old_str_val); break; case Tango::DEV_FLOAT : float_val = old_float_val; break; case Tango::DEV_BOOLEAN : boolean_val = old_boolean_val; break; case Tango::DEV_USHORT : double_val = old_double_val; break; case Tango::DEV_UCHAR : CORBA::string_free(str_val); break; case Tango::DEV_ULONG : ulong_val = old_ulong_val; break; case Tango::DEV_ULONG64 : ulong64_val = old_ulong64_val; break; case Tango::DEV_STATE : dev_state_val = old_dev_state_val; break; } } //+------------------------------------------------------------------------- // // method : WAttribute::copy_data // // description : Copy data into the attribute object in order to return // them in case of a read on this attribute // // in : any : Reference to the CORBA Any object // //-------------------------------------------------------------------------- void WAttribute::copy_data(const CORBA::Any &any) { switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : const Tango::DevVarShortArray *sh_ptr; any >>= sh_ptr; short_array_val = *sh_ptr; break; case Tango::DEV_LONG : const Tango::DevVarLongArray *lo_ptr; any >>= lo_ptr; long_array_val = *lo_ptr; break; case Tango::DEV_LONG64 : const Tango::DevVarLong64Array *lo64_ptr; any >>= lo64_ptr; long64_array_val = *lo64_ptr; break; case Tango::DEV_DOUBLE : const Tango::DevVarDoubleArray *db_ptr; any >>= db_ptr; double_array_val = *db_ptr; break; case Tango::DEV_STRING : const Tango::DevVarStringArray *tmp_str_ptr; any >>= tmp_str_ptr; str_array_val = *tmp_str_ptr; break; case Tango::DEV_FLOAT : const Tango::DevVarFloatArray *fl_ptr; any >>= fl_ptr; float_array_val = *fl_ptr; break; case Tango::DEV_BOOLEAN : const Tango::DevVarBooleanArray *boo_ptr; any >>= boo_ptr; boolean_array_val = *boo_ptr; break; case Tango::DEV_USHORT : const Tango::DevVarUShortArray *ush_ptr; any >>= ush_ptr; ushort_array_val = *ush_ptr; break; case Tango::DEV_UCHAR : const Tango::DevVarCharArray *uch_ptr; any >>= uch_ptr; uchar_array_val = *uch_ptr; break; case Tango::DEV_ULONG : const Tango::DevVarULongArray *ulo_ptr; any >>= ulo_ptr; ulong_array_val = *ulo_ptr; break; case Tango::DEV_ULONG64 : const Tango::DevVarULong64Array *ulo64_ptr; any >>= ulo64_ptr; ulong64_array_val = *ulo64_ptr; break; case Tango::DEV_STATE : const Tango::DevVarStateArray *sta_ptr; any >>= sta_ptr; state_array_val = *sta_ptr; break; } } void WAttribute::copy_data(const Tango::AttrValUnion &the_union) { switch (data_type) { case Tango::DEV_SHORT : case Tango::DEV_ENUM : short_array_val = the_union.short_att_value(); break; case Tango::DEV_LONG : long_array_val = the_union.long_att_value(); break; case Tango::DEV_LONG64 : long64_array_val = the_union.long64_att_value(); break; case Tango::DEV_DOUBLE : double_array_val = the_union.double_att_value(); break; case Tango::DEV_STRING : str_array_val = the_union.string_att_value(); break; case Tango::DEV_FLOAT : float_array_val = the_union.float_att_value(); break; case Tango::DEV_BOOLEAN : boolean_array_val = the_union.bool_att_value(); break; case Tango::DEV_USHORT : ushort_array_val = the_union.ushort_att_value(); break; case Tango::DEV_UCHAR : uchar_array_val = the_union.uchar_att_value(); break; case Tango::DEV_ULONG : ulong_array_val = the_union.ulong_att_value(); break; case Tango::DEV_ULONG64 : ulong64_array_val = the_union.ulong64_att_value(); break; case Tango::DEV_STATE : state_array_val = the_union.state_att_value(); break; } } //+------------------------------------------------------------------------- // // method : WAttribute::set_written_date // // description : Memorized when the attribute is written // //-------------------------------------------------------------------------- void WAttribute::set_written_date() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); write_date.tv_sec = (CORBA::Long)t.time; write_date.tv_usec = (CORBA::Long)(t.millitm * 1000); #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); write_date.tv_sec = (CORBA::Long)tv.tv_sec; write_date.tv_usec = (CORBA::Long)tv.tv_usec; #endif } //+------------------------------------------------------------------------- // // method : WAttribute::check_rds_alarm // // description : Check if the attribute is in read different from set // alarm. // // This method returns true if the attribute has a read too different than the // the last set value. Otherwise, returns false. // //-------------------------------------------------------------------------- bool WAttribute::check_rds_alarm() { bool ret = false; // // Return immediately if the attribute has never been written // if (write_date.tv_sec == 0) return false; // // First, check if it is necessary to check attribute value // Give some time to the device to change its output // struct timeval tv; #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); tv.tv_sec = (CORBA::Long)t.time; tv.tv_usec = (CORBA::Long)(t.millitm * 1000); #else struct timezone tz; gettimeofday(&tv,&tz); #endif long time_diff; COMPUTE_TIME_DIFF(time_diff,write_date,tv); if (time_diff >= delta_t) { // // Now check attribute value with again a switch on attribute data type // long nb_written,nb_read,nb_data,i; switch (data_type) { case Tango::DEV_SHORT: nb_written = short_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.sh_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { short delta = (data_format == Tango::SCALAR) ? short_array_val[0] - tmp_sh[0] : short_array_val[i] - (*value.sh_seq)[i]; if (abs(delta) >= delta_val.sh) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_LONG: nb_written = long_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.lg_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { DevLong delta = (data_format == Tango::SCALAR) ? long_array_val[0] - tmp_lo[0] : long_array_val[i] - (*value.lg_seq)[i]; if (abs(delta) >= delta_val.lg) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_LONG64: nb_written = long64_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.lg64_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { DevLong64 delta = (data_format == Tango::SCALAR) ? long64_array_val[0] - get_tmp_scalar_long64()[0] : long64_array_val[i] - (*value.lg64_seq)[i]; DevLong64 abs_delta; if (delta < 0) abs_delta = -delta; else abs_delta = delta; if (abs_delta >= delta_val.lg64) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_DOUBLE: nb_written = double_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.db_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { // check for NAN values if ( data_format == Tango::SCALAR ) { if ( Tango_isnan(double_array_val[0]) || Tango_isnan(tmp_db[0]) ) { // send an alarm if only read or set value are NAN if ( !(Tango_isnan(double_array_val[0]) && Tango_isnan(tmp_db[0])) ) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } } else { if ( Tango_isnan(double_array_val[i]) || Tango_isnan((*value.db_seq)[i]) ) { // send an alarm if only read or set value are NAN if ( !(Tango_isnan(double_array_val[i]) && Tango_isnan((*value.db_seq)[i])) ) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } } double delta = (data_format == Tango::SCALAR) ? double_array_val[0] - tmp_db[0] : double_array_val[i] - (*value.db_seq)[i]; if (fabs(delta) >= delta_val.db) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_FLOAT: nb_written = float_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.fl_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { // check for NAN values if ( data_format == Tango::SCALAR ) { if ( Tango_isnan(float_array_val[0]) || Tango_isnan(tmp_fl[0]) ) { // send an alarm if only read or set value are NAN if ( !(Tango_isnan(float_array_val[0]) && Tango_isnan(tmp_fl[0])) ) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } } else { if ( Tango_isnan(float_array_val[i]) || Tango_isnan((*value.fl_seq)[i]) ) { // send an alarm if only read or set value are NAN if ( !(Tango_isnan(float_array_val[i]) && Tango_isnan((*value.fl_seq)[i])) ) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } } float delta = (data_format == Tango::SCALAR) ? float_array_val[0] - tmp_fl[0] : float_array_val[i] - (*value.fl_seq)[i]; double delta_d = (double)delta; if (((float)fabs(delta_d)) >= delta_val.fl) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_USHORT: nb_written = ushort_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.ush_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { unsigned short delta = (data_format == Tango::SCALAR) ? ushort_array_val[0] - tmp_ush[0] : ushort_array_val[i] - (*value.ush_seq)[i]; if (abs(delta) >= delta_val.ush) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_UCHAR: nb_written = uchar_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.cha_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { unsigned char delta = (data_format == Tango::SCALAR) ? uchar_array_val[0] - tmp_cha[0] : uchar_array_val[i] - (*value.cha_seq)[i]; if (abs(delta) >= delta_val.uch) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_ULONG: nb_written = ulong_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.ulg_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { DevLong delta = (data_format == Tango::SCALAR) ? ulong_array_val[0] - get_tmp_scalar_ulong()[0] : ulong_array_val[i] - (*value.ulg_seq)[i]; if ((unsigned int)abs(delta) >= delta_val.ulg) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_ULONG64: nb_written = ulong64_array_val.length(); nb_read = (data_format == Tango::SCALAR) ? 1 : value.ulg64_seq->length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { DevLong64 delta = (data_format == Tango::SCALAR) ? ulong64_array_val[0] - get_tmp_scalar_ulong64()[0] : ulong64_array_val[i] - (*value.ulg64_seq)[i]; DevULong64 abs_delta; if (delta < 0) abs_delta = -delta; else abs_delta = delta; if (abs_delta >= delta_val.ulg64) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; case Tango::DEV_ENCODED: nb_written = ::strlen(encoded_val.encoded_format.in()); nb_read = ::strlen((*value.enc_seq)[0].encoded_format.in()); if (nb_written != nb_read) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } if (::strcmp(encoded_val.encoded_format.in(),(*value.enc_seq)[0].encoded_format.in()) != 0) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } nb_written = encoded_val.encoded_data.length(); nb_read = (*value.enc_seq)[0].encoded_data.length(); nb_data = (nb_written > nb_read) ? nb_read : nb_written; for (i = 0;i < nb_data;i++) { unsigned char delta = encoded_val.encoded_data[i] - (*value.enc_seq)[0].encoded_data[i]; if (abs(delta) >= delta_val.uch) { quality = Tango::ATTR_ALARM; alarm.set(rds); ret = true; break; } } break; } } return ret; } void WAttribute::set_min_value(char *new_min_value_str) { set_min_value(string(new_min_value_str)); } void WAttribute::set_min_value(const char *new_min_value_str) { set_min_value(string(new_min_value_str)); } void WAttribute::set_max_value(char *new_max_value_str) { set_max_value(string(new_max_value_str)); } void WAttribute::set_max_value(const char *new_max_value_str) { set_max_value(string(new_max_value_str)); } //+------------------------------------------------------------------------- // // method : WAttribute::mem_value_below_above() // // description : Check if the attribute last written value is below // (or above) the new threshold sent by the requester // // Arg in : check_type : Which check has to be done: Below or above // // This method returns true if the new threshold wanted by the user is not // coherent with the memorized value. Otherwise, returns false. // //-------------------------------------------------------------------------- bool WAttribute::mem_value_below_above(MinMaxValueCheck check_type,string &ret_mem_value) { bool ret = false; if (mem_value == MemNotUsed) return false; // // Check last written attribute value with the new threshold // long nb_written,i; stringstream ss; DevLong lg_val; DevShort sh_val; DevLong64 lg64_val; DevDouble db_val; DevFloat fl_val; DevUShort ush_val; DevUChar uch_val; DevULong ulg_val; DevULong64 ulg64_val; Tango::Util *tg = Tango::Util::instance(); bool svr_starting = tg->is_svr_starting(); switch (data_type) { case Tango::DEV_SHORT: if (svr_starting == true) { ss << mem_value; ss >> sh_val; if (check_type == MIN) { if (sh_val < min_value.sh) { ret_mem_value = mem_value; ret = true; } } else { if (sh_val > max_value.sh) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = short_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (short_array_val[i] < min_value.sh) { ss << short_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (short_array_val[i] > max_value.sh) { ss << short_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_LONG: if (svr_starting == true) { ss << mem_value; ss >> lg_val; if (check_type == MIN) { if (lg_val < min_value.lg) { ret_mem_value = mem_value; ret = true; } } else { if (lg_val > max_value.lg) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = long_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (long_array_val[i] < min_value.lg) { ss << long_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (long_array_val[i] > max_value.lg) { ss << long_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_LONG64: if (svr_starting == true) { ss << mem_value; ss >> lg64_val; if (check_type == MIN) { if (lg64_val < min_value.lg64) { ret_mem_value = mem_value; ret = true; } } else { if (lg64_val > max_value.lg64) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = long64_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (long64_array_val[i] < min_value.lg64) { ss << long64_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (long64_array_val[i] > max_value.lg64) { ss << long64_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_DOUBLE: if (svr_starting == true) { ss << mem_value; ss >> db_val; if (check_type == MIN) { if (db_val < min_value.db) { ret_mem_value = mem_value; ret = true; } } else { if (db_val > max_value.db) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = double_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (double_array_val[i] < min_value.db) { ss << double_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (double_array_val[i] > max_value.db) { ss << double_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_FLOAT: if (svr_starting == true) { ss << mem_value; ss >> fl_val; if (check_type == MIN) { if (fl_val < min_value.fl) { ret_mem_value = mem_value; ret = true; } } else { if (fl_val > max_value.fl) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = float_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (float_array_val[i] < min_value.fl) { ss << float_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (float_array_val[i] > max_value.fl) { ss << float_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_USHORT: if (svr_starting == true) { ss << mem_value; ss >> ush_val; if (check_type == MIN) { if (ush_val < min_value.ush) { ret_mem_value = mem_value; ret = true; } } else { if (ush_val > max_value.ush) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = ushort_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (ushort_array_val[i] < min_value.ush) { ss << ushort_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (ushort_array_val[i] > max_value.ush) { ss << ushort_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_UCHAR: if (svr_starting == true) { ss << mem_value; ss >> uch_val; if (check_type == MIN) { if (uch_val < min_value.uch) { ret_mem_value = mem_value; ret = true; } } else { if (uch_val > max_value.uch) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = uchar_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (uchar_array_val[i] < min_value.uch) { ss << uchar_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (uchar_array_val[i] > max_value.uch) { ss << uchar_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_ULONG: if (svr_starting == true) { ss << mem_value; ss >> ulg_val; if (check_type == MIN) { if (ulg_val < min_value.ulg) { ret_mem_value = mem_value; ret = true; } } else { if (ulg_val > max_value.ulg) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = ulong_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (ulong_array_val[i] < min_value.ulg) { ss << ulong_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (ulong_array_val[i] > max_value.ulg) { ss << ulong_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; case Tango::DEV_ULONG64: if (svr_starting == true) { ss << mem_value; ss >> ulg64_val; if (check_type == MIN) { if (ulg64_val < min_value.ulg64) { ret_mem_value = mem_value; ret = true; } } else { if (ulg64_val > max_value.ulg64) { ret_mem_value = mem_value; ret = true; } } } else { nb_written = ulong64_array_val.length(); for (i = 0;i < nb_written;i++) { if (check_type == MIN) { if (ulong64_array_val[i] < min_value.ulg64) { ss << ulong64_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } else { if (ulong64_array_val[i] > max_value.ulg64) { ss << ulong64_array_val[i]; ret_mem_value = ss.str(); ret = true; break; } } } } break; default: break; } return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/w_pipe.cpp0000644023471100065110000000461013034745001014551 00000000000000static const char *RcsId = "$Id: w_pipe.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+================================================================================================================== // // file : W_pipe.cpp // // description : C++ source code for the WPipe class. The WPipe class is a root class for derived // Pipe classes. // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================== #if HAVE_CONFIG_H #include #endif #include namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // WPipe::WPipe // // description : // Constructor for base class WPipe // //----------------------------------------------------------------------------------------------------------------- WPipe::WPipe(const string &_name,Tango::DispLevel _level) :Pipe(_name,_level,PIPE_READ_WRITE),w_ext(new WPipeExt) { } //+----------------------------------------------------------------------------------------------------------------- // // method : // WPipe::operator[] // // description : // Retrieve one data element from the WPipe from its name // //----------------------------------------------------------------------------------------------------------------- WPipe &WPipe::operator[](const string &_na) { get_blob().operator[](_na); return *this; } } // End of Tango namespace tango-9.2.5a/lib/cpp/server/zmqeventsupplier.cpp0000644023471100065110000014764413034745002016743 00000000000000static const char *RcsId = "$Id$"; //+================================================================================================================== // // zmqeventsupplier.cpp : C++ classes for implementing the event server and client singleton classes -ZmqEventSupplier // This class is used to send events from the server to the client(s) when zmq is used to // transport the events // // author(s) : E.Taurel (taurel@esrf.fr) // // original : August 2011 // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //+================================================================================================================== #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #include #include #include #include #include #endif /* _TG_WINDOWS_ */ using namespace CORBA; namespace Tango { ZmqEventSupplier *ZmqEventSupplier::_instance = NULL; /************************************************************************/ /* */ /* ZmqEventSupplier class */ /* ---------------- */ /* */ /************************************************************************/ ZmqEventSupplier::ZmqEventSupplier(Util *tg):EventSupplier(tg),zmq_context(1),event_pub_sock(NULL), name_specified(false),double_send(0),double_send_heartbeat(false) { _instance = this; // // Create zmq release number // int zmq_major,zmq_minor,zmq_patch; zmq_version(&zmq_major,&zmq_minor,&zmq_patch); zmq_release = (zmq_major * 100) + (zmq_minor * 10) + zmq_patch; // // Create the Publisher socket for heartbeat event and bind it // If the user has specified one IP address on the command line, re-use it in the endpoint // But if the address was specified as a name (supported by omniORB), convert this name to IP address // but uses the name in the endpoint given to client // heartbeat_pub_sock = new zmq::socket_t(zmq_context,ZMQ_PUB); int linger = 0; int reconnect_ivl = -1; heartbeat_pub_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); try { heartbeat_pub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } catch (zmq::error_t &) { reconnect_ivl = 30000; heartbeat_pub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } heartbeat_endpoint = "tcp://"; alt_ip.clear(); alternate_e_endpoint.clear(); alternate_h_endpoint.clear(); string &specified_addr = tg->get_specified_ip(); unsigned char buf[sizeof(struct in_addr)]; bool specified_name = false; #ifndef _TG_WINDOWS_ if (specified_addr.empty() == false && inet_pton(AF_INET,specified_addr.c_str(),buf) == 0) #else struct sockaddr_storage ss; int size = sizeof(ss); char src_copy[INET6_ADDRSTRLEN+1]; ZeroMemory(&ss, sizeof(ss)); strncpy (src_copy, specified_addr.c_str(), INET6_ADDRSTRLEN+1); src_copy[INET6_ADDRSTRLEN] = 0; if (specified_addr.empty() == false && WSAStringToAddress(src_copy,AF_INET,NULL,(struct sockaddr *)&ss,&size) != 0) #endif specified_name = true; string &h_name = tg->get_host_name(); string canon_name; string specified_ip; if (specified_name == true) { struct addrinfo hints; memset(&hints,0,sizeof(struct addrinfo)); hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; struct addrinfo *info; int result = getaddrinfo(specified_addr.c_str(),NULL,&hints,&info); if (result == 0) { struct sockaddr_in *s_in = (sockaddr_in *)info->ai_addr; specified_ip = inet_ntoa(s_in->sin_addr); freeaddrinfo(info); } else { stringstream ss; ss << "Can't convert " << specified_addr << " to IP address"; EventSystemExcept::throw_exception(API_ZmqInitFailed,ss.str(),"ZmqEventSupplier::ZmqEventSupplier()"); } } else specified_ip = specified_addr; string::size_type pos = h_name.find('.'); if (pos != string::npos) canon_name = h_name.substr(0,pos); if (specified_addr.empty() == false && (specified_addr != "localhost")) { heartbeat_endpoint = heartbeat_endpoint + specified_ip + ':'; ip_specified = true; if (specified_name == true) name_specified = true; user_ip = specified_ip; } else { heartbeat_endpoint = heartbeat_endpoint + "*:"; ip_specified = false; } // // Bind the publisher socket to one ephemeral port // tango_bind(heartbeat_pub_sock,heartbeat_endpoint); // // If needed, replace * by host IP address in endpoint string // if (specified_ip.empty() == true) { ApiUtil *au = ApiUtil::instance(); vector adrs; au->get_ip_from_if(adrs); string::size_type pos = heartbeat_endpoint.find('*'); if (adrs.size() > 1) { bool first_set = false; string::size_type po = heartbeat_endpoint.rfind(':'); string port_str = heartbeat_endpoint.substr(po + 1); for (unsigned int i = 0;i < adrs.size();++i) { string::size_type start; if ((start = adrs[i].find("127.")) == 0) continue; if (first_set == false) { heartbeat_endpoint.replace(pos,1,adrs[i]); host_ip = adrs[i]; first_set = true; } else { string str("tcp://"); str = str + adrs[i] + ':' + port_str; alternate_h_endpoint.push_back(str); alt_ip.push_back(adrs[i]); } } } else { heartbeat_endpoint.replace(pos,1,adrs[0]); host_ip = adrs[0]; } } else if (specified_name == true) { string::size_type start = heartbeat_endpoint.find("//"); start = start + 2; string::size_type stop = heartbeat_endpoint.rfind(':'); heartbeat_endpoint.replace(start,stop - start,specified_addr); } // // Find out the host endianness and create the zmq message used to pass it // host_endian = test_endian(); endian_mess.rebuild(1); memcpy(endian_mess.data(),&host_endian,1); endian_mess_2.copy(&endian_mess); endian_mess_heartbeat.rebuild(1); memcpy(endian_mess_heartbeat.data(),&host_endian,1); endian_mess_heartbeat_2.copy(&endian_mess_heartbeat); // // Init heartbeat call info // Leave the OID and method name un-initialized. Marshall the structure into CORBA CDR // heartbeat_call.version = ZMQ_EVENT_PROT_VERSION; heartbeat_call.call_is_except = false; heartbeat_call >>= heartbeat_call_cdr; // // Create some ZMQ messages from the already created memory buffer in CDR // heartbeat_call_mess.rebuild(heartbeat_call_cdr.bufSize()); memcpy(heartbeat_call_mess.data(),heartbeat_call_cdr.bufPtr(),heartbeat_call_cdr.bufSize()); heartbeat_call_mess_2.copy(&heartbeat_call_mess); // // Start to init the event name used for the DS heartbeat event // heartbeat_event_name = fqdn_prefix; heartbeat_event_name = heartbeat_event_name + "dserver/"; heartbeat_name_init = false; // // Init data used in no-copy Zmq API // require_wait = true; } ZmqEventSupplier *ZmqEventSupplier::create(Util *tg) { cout4 << "calling Tango::ZmqEventSupplier::create()" << endl; // // Does the ZmqEventSupplier singleton exist already ? if so simply return it // if (_instance != NULL) { return _instance; } // // ZmqEventSupplier singleton does not exist, create it // ZmqEventSupplier *_event_supplier = new ZmqEventSupplier(tg); return _event_supplier; } //+------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::~ZmqEventSupplier() // // description : // ZmqEventSupplier destructor. // This dtor delete the zmq socket. The ZMQ context will be deleted (then calling zmq_term) when the object is // destroyed // //------------------------------------------------------------------------------------------------------------------- ZmqEventSupplier::~ZmqEventSupplier() { // // Delete zmq sockets // delete heartbeat_pub_sock; delete event_pub_sock; if (event_mcast.empty() == false) { map::iterator ite,ite_stop; ite = event_mcast.begin(); ite_stop = event_mcast.end(); for (ite = event_mcast.begin(); ite != ite_stop;++ite) delete ite->second.pub_socket; } } //+------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::tango_bind() // // description : // Choose a free port to bind ZMQ socket. Ask ZMQ to give us a port number // // argument : // in : // - sock : The ZMQ socket // - endpoint : The beginning of the ZMQ endpoint // //------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::tango_bind(zmq::socket_t *sock,string &endpoint) { string base_endpoint(endpoint); base_endpoint = base_endpoint + "*"; char buf[80]; size_t buf_len = sizeof(buf); try { sock->bind(base_endpoint.c_str()); sock->getsockopt(ZMQ_LAST_ENDPOINT,buf,&buf_len); string str(buf); string::size_type pos = str.rfind(':'); string port_str = str.substr(pos + 1); endpoint = endpoint + port_str; } catch(...) { EventSystemExcept::throw_exception((const char*)API_ZmqInitFailed, (const char*)"Can't bind the ZMQ socket!", (const char*)"ZmqEventSupplier::tango_bind()"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::test_endian() // // description : // Get the host endianness // // return: // This method returns the host endianness // 0 -> Big endian // 1 -> Little endian // //------------------------------------------------------------------------------------------------------------------- unsigned char ZmqEventSupplier::test_endian() { int test_var = 1; unsigned char *cptr = (unsigned char*)&test_var; return (!(cptr[0] == 0)); } //+----------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::create_event_socket() // // description : // Create and bind the publisher socket used to publish the real events // //------------------------------------------------------------------------------------------------------------------ void ZmqEventSupplier::create_event_socket() { if (event_pub_sock == NULL) { omni_mutex_lock oml(event_mutex); // // Create the Publisher socket for real events and bind it // If the user has specified one IP address on the command line, re-use it in the endpoint // event_pub_sock = new zmq::socket_t(zmq_context,ZMQ_PUB); int linger = 0; int reconnect_ivl = -1; event_pub_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); try { event_pub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } catch (zmq::error_t &) { reconnect_ivl = 30000; event_pub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } event_endpoint = "tcp://"; if (ip_specified == true) { event_endpoint = event_endpoint + user_ip + ':'; } else { event_endpoint = event_endpoint + "*:"; } // // Set a publisher HWM // Tango::Util *tg = Tango::Util::instance(); DServer *admin_dev = tg->get_dserver_device(); int hwm = tg->get_user_pub_hwm(); if (hwm == -1) hwm = admin_dev->zmq_pub_event_hwm; event_pub_sock->setsockopt(ZMQ_SNDHWM,&hwm,sizeof(hwm)); // // Bind the publisher socket to one ephemeral port // tango_bind(event_pub_sock,event_endpoint); // // If needed, replace * by host IP address in endpoint string // if (ip_specified == false) { event_endpoint.replace(6,1,host_ip); if (alt_ip.empty() == false) { string::size_type pos = event_endpoint.rfind(':'); string port_str = event_endpoint.substr(pos + 1); for (size_t loop = 0;loop < alt_ip.size();loop++) { string tmp("tcp://"); tmp = tmp + alt_ip[loop] + ':' + port_str; alternate_e_endpoint.push_back(tmp); } } } else if (name_specified == true) { string::size_type start = event_endpoint.find("//"); start = start + 2; string::size_type stop = event_endpoint.rfind(':'); string &specified_addr = tg->get_specified_ip(); event_endpoint.replace(start,stop - start,specified_addr); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::create_mcast_event_socket() // // description : // Create and bind the publisher socket used to publish the real events when multicast transport is required // // argument : // in : // - mcast_data : The multicast addr and port (mcast_adr:port) // - ev_name : The event name (dev_name/attr_name.event_type) // - rate: The user defined PGM rate (O if undefined) // - local_call: True if the caller is on the same host // //------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::create_mcast_event_socket(string &mcast_data,string &ev_name,int rate,bool local_call) { map::iterator ite; // // If the event is already in the mcast event map, check if it is already used by local clients // if ((ite = event_mcast.find(ev_name)) != event_mcast.end()) { if (local_call == true) { if (ite->second.local_client == false) { create_event_socket(); ite->second.local_client = true; } } else { if (ite->second.local_client == true && ite->second.pub_socket == NULL) { create_mcast_socket(mcast_data,rate,ite->second); } } ite->second.double_send = true; } else { // // New mcast event // McastSocketPub ms; ms.double_send = true; if (local_call == true) { create_event_socket(); ms.pub_socket = NULL; ms.local_client = true; } else { create_mcast_socket(mcast_data,rate,ms); ms.local_client = false; } // // Insert element in map // if (event_mcast.insert(make_pair(ev_name,ms)).second == false) { TangoSys_OMemStream o; o << "Can't insert multicast transport parameter for event "; o << ev_name << " in EventSupplier instance" << ends; Except::throw_exception((const char *)API_InternalError, o.str(), (const char *)"ZmqEventSupplier::create_mcast_event_socket"); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::create_mcast_socket() // // description : // Create and bind the publisher socket used to publish the real events when multicast transport is required // // argument : // in : // - mcast_data : The multicast addr and port (mcast_adr:port) // - rate: The user defined PGM rate (O if undefined) // - ms: Reference to the structure to be stored in the macst map // //------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::create_mcast_socket(string &mcast_data,int rate,McastSocketPub &ms) { // // Create the Publisher socket for real events and bind it // If the user has specified one IP address on the command line, re-use it in the endpoint // ms.pub_socket = new zmq::socket_t(zmq_context,ZMQ_PUB); ms.endpoint = MCAST_PROT; if (ip_specified == true) { ms.endpoint = ms.endpoint + user_ip + ';'; } else { ApiUtil *au = ApiUtil::instance(); vector adrs; au->get_ip_from_if(adrs); for (unsigned int i = 0;i < adrs.size();++i) { if (adrs[i].find("127.") == 0) continue; ms.endpoint = ms.endpoint + adrs[i] + ';'; break; } } ms.endpoint = ms.endpoint + mcast_data; int linger = 0; ms.pub_socket->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); // // Change multicast hops // Tango::Util *tg = Tango::Util::instance(); DServer *admin_dev = tg->get_dserver_device(); int nb_hops = admin_dev->mcast_hops; ms.pub_socket->setsockopt(ZMQ_MULTICAST_HOPS,&nb_hops,sizeof(nb_hops)); // // Change PGM rate to default value (80 Mbits/sec) or to user defined value // int local_rate = rate; ms.pub_socket->setsockopt(ZMQ_RATE,&local_rate,sizeof(local_rate)); // // Bind the publisher socket to the specified port // if (zmq_bind(*(ms.pub_socket),ms.endpoint.c_str()) != 0) { TangoSys_OMemStream o; o << "Can't bind ZMQ socket with endpoint "; o << ms.endpoint; o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventSupplier::create_mcast_event_socket"); } // // The connection string returned to client does not need the host IP at all // ms.endpoint = MCAST_PROT + mcast_data; } //+------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::is_event_mcast() // // description : // This method checks if the event is already defined in the map of multicast event. // // argument : // in : // - ev_name : The event name (device/attr.event_type) // // returns : // This method returns true if the event is in the map and false otherwise // //-------------------------------------------------------------------------------------------------------------------- bool ZmqEventSupplier::is_event_mcast(string &ev_name) { bool ret = false; if (event_mcast.find(ev_name) != event_mcast.end()) ret = true; return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::get_mcast_event_endpoint() // // description : // This method returns the multicast socket endpoint for the event passed as parameter // // argument : // in : // - event_name : The event name (device/attr.event_type) // // return : // This method returns a reference to the enpoint string // //-------------------------------------------------------------------------------------------------------------------- string &ZmqEventSupplier::get_mcast_event_endpoint(string &ev_name) { return event_mcast.find(ev_name)->second.endpoint; } //+------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::init_event_cptr() // // description : // Method to initialize event counter for a specific event // // argument : // in : // - event_name : The event name (device/attr.event_type) // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::init_event_cptr(string &event_name) { map::iterator pos; pos = event_cptr.find(event_name); if (pos == event_cptr.end()) { if (event_cptr.insert(make_pair(event_name,1)).second == false) { TangoSys_OMemStream o; o << "Can't insert event counter for event "; o << event_name << " in EventSupplier instance" << ends; Except::throw_exception(API_InternalError,o.str(),"ZmqEventSupplier::init_event_cptr"); } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventSupplier::push_heartbeat_event() // // description : // Method to push the hearbeat event // //------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::push_heartbeat_event() { time_t delta_time; time_t now_time; // // Heartbeat - check wether a heartbeat event has been sent recently. If not then send it. // A heartbeat contains no data, it is used by the consumer to know that the supplier is still alive. // Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); now_time = time(NULL); delta_time = now_time - adm_dev->last_heartbeat_zmq; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta time since last heartbeat " << delta_time << endl; if (heartbeat_name_init == false) { // // Build heartbeat name // This is something like // tango://host:port/dserver/exec_name/inst_name.heartbeat when using DB // tango://host:port/dserver/exec_name/inst_name#dbase=no.heartbeat when using file as database // heartbeat_event_name = heartbeat_event_name + adm_dev->get_full_name(); if (Util::_FileDb == true || Util::_UseDb == false) { bool db_ds = false; const vector *cl_ptr = tg->get_class_list(); for (size_t loop = 0;loop < cl_ptr->size();loop++) { if ((*cl_ptr)[loop]->get_name() == DATABASE_CLASS) { db_ds = true; break; } } if (db_ds == false) heartbeat_event_name = heartbeat_event_name + MODIFIER_DBASE_NO; } heartbeat_event_name = heartbeat_event_name + ".heartbeat"; transform(heartbeat_event_name.begin(),heartbeat_event_name.end(),heartbeat_event_name.begin(),::tolower); heartbeat_name_init = true; } // // We here compare delta_time to 8 and not to 10. // This is necessary because, sometimes the polling thread is some milli second in advance. // The computation here is done in seconds. So, if the polling thread is in advance, delta_time computed in // seconds will be 9 even if in reality it is 9,9 // if (delta_time >= 8) { int nb_event = 1; cout3 << "ZmqEventSupplier::push_heartbeat_event(): detected heartbeat event for " << heartbeat_event_name << endl; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta _time " << delta_time << endl; if (double_send_heartbeat == true) { nb_event = 2; double_send_heartbeat = false; } cout3 << "ZmqEventSupplier::push_heartbeat_event(): nb_event = " << nb_event << endl; while (nb_event != 0) { // // Create zmq message // zmq::message_t name_mess(heartbeat_event_name.size()); memcpy(name_mess.data(),(void *)heartbeat_event_name.data(),heartbeat_event_name.size()); bool endian_mess_sent = false; bool call_mess_sent = false; try { // // For debug and logging purposes // if (nb_event == 1) { if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: Pushing some data" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)name_mess.data(),name_mess.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)endian_mess_heartbeat.data(),endian_mess_heartbeat.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)heartbeat_call_mess.data(),heartbeat_call_mess.size()); } } // // Push the event // adm_dev->last_heartbeat_zmq = now_time; heartbeat_pub_sock->send(name_mess,ZMQ_SNDMORE); heartbeat_pub_sock->send(endian_mess_heartbeat,ZMQ_SNDMORE); endian_mess_sent = true; heartbeat_pub_sock->send(heartbeat_call_mess,0); call_mess_sent = true; // // Push a dummy message in the event socket. This is required by the ZMQ layer. In case of reconnection, if nothing // is sent on the socket between two reconnections, some memory will be "leaked". ZMQ is deleting that memory at // process end (zmq context delete) OR when something is sent to the socket. Therefore, send a dummy message // to the socket to force ZMQ "garbage collection" because we cannot wait for process termination! // string dummy_message("I like beer"); zmq::message_t dummy_mess(dummy_message.size()); memcpy(dummy_mess.data(),(void *)dummy_message.data(),dummy_message.size()); push_mutex.lock(); event_pub_sock->send(dummy_mess); push_mutex.unlock(); // // For reference counting on zmq messages which do not have a local scope // endian_mess_heartbeat.copy(&endian_mess_heartbeat_2); heartbeat_call_mess.copy(&heartbeat_call_mess_2); nb_event--; } catch(...) { cout3 << "ZmqEventSupplier::push_heartbeat_event() failed !\n"; if (endian_mess_sent == true) endian_mess_heartbeat.copy(&endian_mess_heartbeat_2); if (call_mess_sent == true) heartbeat_call_mess.copy(&heartbeat_call_mess_2); TangoSys_OMemStream o; o << "Can't push ZMQ heartbeat event for event "; o << heartbeat_event_name; if (zmq_errno() != 0) o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; else o << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventSupplier::push_heartbeat_event"); } } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::push_event() // // description : // Method to send the event to the event channel // // argument : // in : // - device_impl : The device // - event_type : The event type (change, periodic....) // - filterable_names : // - filterable_data : // - attr_value : The attribute value // - obj_name : The attribute/pipe name // - except : The exception thrown during the last attribute reading. NULL if no exception // //------------------------------------------------------------------------------------------------------------------- // // Small callback used by ZMQ when using the no-copy API to signal that the message has been sent. // Take care, this method is also called when ZMQ connection is closed. In such a case, the calling thread is the // thread doing the zmq::send() call and it's not the ZMQ thread. When this happens, we do not need to send // a signal to the calling thread. // void tg_unlock(TANGO_UNUSED(void *data),void *hint) { omni_thread *th_id = omni_thread::self(); if (th_id == NULL) th_id = omni_thread::create_dummy(); ZmqEventSupplier *ev = (ZmqEventSupplier *)hint; omni_mutex &the_mut = ev->get_push_mutex(); omni_condition &the_cond = ev->get_push_cond(); if (th_id->id() != ev->get_calling_th()) { omni_mutex_lock oml(the_mut); the_cond.signal(); } else { ev->set_require_wait(false); } } void ZmqEventSupplier::push_event(DeviceImpl *device_impl,string event_type, TANGO_UNUSED(vector &filterable_names),TANGO_UNUSED(vector &filterable_data), TANGO_UNUSED(vector &filterable_names_lg),TANGO_UNUSED(vector &filterable_data_lg), struct SuppliedEventData &ev_value,string &obj_name,DevFailed *except,bool inc_cptr) { if (device_impl == NULL) return; cout3 << "ZmqEventSupplier::push_event(): called for attribute/pipe " << obj_name << endl; // // Get the mutex to synchronize the sending of events // This method may be called by several threads in case they are several // user threads doing dev.push_xxxx_event() on several devices. // On top of that, zmq socket can be used by several threads // only if they are memory barriers between their use in these different // threads. The mutex used here is also a memory barrier // omni_thread *th_id = omni_thread::self(); if (th_id == NULL) th_id = omni_thread::create_dummy(); push_mutex.lock(); calling_th = th_id->id(); require_wait = true; // // Create full event name // Don't forget case where we have notifd client (thus with a fqdn_prefix modified) // string loc_obj_name(obj_name); transform(loc_obj_name.begin(),loc_obj_name.end(),loc_obj_name.begin(),::tolower); bool intr_change = false; if (event_type == EventName[INTERFACE_CHANGE_EVENT]) intr_change = true; bool pipe_event = false; if (event_type == EventName[PIPE_EVENT]) pipe_event = true; event_name = fqdn_prefix; int size = event_name.size(); if (event_name[size - 1] == '#') event_name.erase(size - 1); event_name = event_name + device_impl->get_name_lower(); if (intr_change == false) event_name = event_name + '/' + loc_obj_name; if (Util::_FileDb == true || Util::_UseDb == false) event_name = event_name + MODIFIER_DBASE_NO; event_name = event_name + '.'; string ctr_event_name = event_name; string local_event_type = event_type; event_name = event_name + event_type; string::size_type pos = local_event_type.find(EVENT_COMPAT); if (pos != string::npos) local_event_type.erase(0,EVENT_COMPAT_IDL5_SIZE); ctr_event_name = ctr_event_name + local_event_type; // // Create zmq messages // Use memcpy here. Don't use message with no-copy option because // it does not give any performance improvement in this case (too small amount of data) // zmq::message_t name_mess(event_name.size()); memcpy(name_mess.data(),event_name.data(),event_name.size()); // // Get event cptr and create the event call zmq message // map::iterator ev_cptr_ite; unsigned int ev_ctr = 0; ev_cptr_ite = event_cptr.find(ctr_event_name); if (ev_cptr_ite != event_cptr.end()) ev_ctr = ev_cptr_ite->second; else { bool print = false; if (intr_change == false && pipe_event == false) { Attribute &att = device_impl->get_device_attr()->get_attr_by_name(obj_name.c_str()); if (local_event_type == "data_ready") { if (att.event_data_ready_subscription != 0) print = true; } else if (local_event_type == "attr_conf") { if (att.event_attr_conf_subscription != 0 || att.event_attr_conf5_subscription != 0) print = true; } else if (local_event_type == "user_event") { if (att.event_user3_subscription != 0 || att.event_user4_subscription != 0 || att.event_user5_subscription != 0) print = true; } else if (local_event_type == "change") { if (att.event_change3_subscription != 0 || att.event_change4_subscription != 0 || att.event_change5_subscription != 0) print = true; } else if (local_event_type == "periodic") { if (att.event_periodic3_subscription != 0 || att.event_periodic4_subscription != 0 || att.event_periodic5_subscription != 0) print = true; } else if (local_event_type == "archive") { if (att.event_archive3_subscription != 0 || att.event_archive4_subscription != 0 || att.event_archive5_subscription != 0) print = true; } } else if (pipe_event == true) { Pipe &pi = device_impl->get_device_class()->get_pipe_by_name(obj_name.c_str(),device_impl->get_name_lower()); if (pi.event_subscription != 0) print = true; } else { if (device_impl->get_event_intr_change_subscription() != 0) print = true; } if (print == true) cout3 << "-----> Can't find event counter for event " << event_name << " in map!!!!!!!!!!" << endl; } ZmqCallInfo event_call; event_call.version = ZMQ_EVENT_PROT_VERSION; if (except == NULL) event_call.call_is_except = false; else event_call.call_is_except = true; event_call.ctr = ev_ctr; cdrMemoryStream event_call_cdr; event_call >>= event_call_cdr; zmq::message_t event_call_mess(event_call_cdr.bufSize()); memcpy(event_call_mess.data(),event_call_cdr.bufPtr(),event_call_cdr.bufSize()); bool large_data = false; bool large_message_created = false; size_t mess_size; void *mess_ptr; zmq::message_t data_mess; if (ev_value.zmq_mess != NULL) { // // It's a forwarded attribute, therefore, use the already marshalled message // mess_ptr = ev_value.zmq_mess->data(); mess_size = ev_value.zmq_mess->size(); data_mess.move(ev_value.zmq_mess); } else { // // Marshall the event data // CORBA::Long padding = 0XDEC0DEC0; data_call_cdr.rewindPtrs(); padding >>= data_call_cdr; padding >>= data_call_cdr; if (except == NULL) { if (ev_value.attr_val != NULL) { *(ev_value.attr_val) >>= data_call_cdr; } else if (ev_value.attr_val_3 != NULL) { *(ev_value.attr_val_3) >>= data_call_cdr; } else if (ev_value.attr_val_4 != NULL) { // // Get number of data exchanged by this event. If this value is greater than a threshold, set a flag // In such a case, we will use ZMQ no-copy message call // *(ev_value.attr_val_4) >>= data_call_cdr; mess_ptr = data_call_cdr.bufPtr(); mess_ptr = (char *)mess_ptr + (sizeof(CORBA::Long) << 1); int nb_data; int data_discr = ((int *)mess_ptr)[0]; if (data_discr == ATT_ENCODED) { const DevVarEncodedArray &dvea = ev_value.attr_val_4->value.encoded_att_value(); nb_data = dvea.length(); if (nb_data > LARGE_DATA_THRESHOLD_ENCODED) large_data = true; } else if (data_discr == ATT_NO_DATA) { nb_data = 0; } else { nb_data = ((int *)mess_ptr)[1]; if (nb_data >= LARGE_DATA_THRESHOLD) large_data = true; } } else if (ev_value.attr_val_5 != NULL) { // // Get number of data exchanged by this event. If this value is greater than a threshold, set a flag // In such a case, we will use ZMQ no-copy message call // *(ev_value.attr_val_5) >>= data_call_cdr; mess_ptr = data_call_cdr.bufPtr(); mess_ptr = (char *)mess_ptr + (sizeof(CORBA::Long) << 1); int nb_data; int data_discr = ((int *)mess_ptr)[0]; if (data_discr == ATT_ENCODED) { const DevVarEncodedArray &dvea = ev_value.attr_val_5->value.encoded_att_value(); nb_data = dvea.length(); if (nb_data > LARGE_DATA_THRESHOLD_ENCODED) large_data = true; } else if (data_discr == ATT_NO_DATA) { nb_data = 0; } else { nb_data = ((int *)mess_ptr)[1]; if (nb_data >= LARGE_DATA_THRESHOLD) large_data = true; } } else if (ev_value.attr_conf_2 != NULL) { *(ev_value.attr_conf_2) >>= data_call_cdr; } else if (ev_value.attr_conf_3 != NULL) { *(ev_value.attr_conf_3) >>= data_call_cdr; } else if (ev_value.attr_conf_5 != NULL) { *(ev_value.attr_conf_5) >>= data_call_cdr; } else if (ev_value.attr_dat_ready != NULL) { *(ev_value.attr_dat_ready) >>= data_call_cdr; } else if (ev_value.pipe_val != NULL) { size_t nb_data = get_blob_data_nb(ev_value.pipe_val->data_blob.blob_data); if (nb_data >= LARGE_DATA_THRESHOLD) large_data = true; *(ev_value.pipe_val) >>= data_call_cdr; } else { *(ev_value.dev_intr_change) >>= data_call_cdr; } } else { except->errors >>= data_call_cdr; } if (pipe_event == false) { mess_size = data_call_cdr.bufSize() - sizeof(CORBA::Long); mess_ptr = (char *)data_call_cdr.bufPtr() + sizeof(CORBA::Long); } else { mess_size = data_call_cdr.bufSize(); mess_ptr = (char *)data_call_cdr.bufPtr(); } // // For event with small amount of data, use memcpy to initialize the zmq message. For large amount of data, use // zmq message with no-copy option // if (large_data == true) { data_mess.rebuild(mess_ptr,mess_size,tg_unlock,(void *)this); large_message_created = true; } else { data_mess.rebuild(mess_size); memcpy(data_mess.data(),mess_ptr,mess_size); } } // // Send the data // bool endian_mess_sent = false; try { // // For debug and logging purposes // if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: Pushing some data" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)name_mess.data(),name_mess.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)endian_mess.data(),endian_mess.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)event_call_mess.data(),event_call_mess.size()); { omniORB::logger log; log << "ZMQ: Event data" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)data_mess.data(),data_mess.size()); } // // Get publisher socket (multicast case) // int send_nb = 1; zmq::socket_t *pub; pub = event_pub_sock; zmq::message_t *name_mess_ptr = &name_mess; zmq::message_t *endian_mess_ptr = &endian_mess; zmq::message_t *event_call_mess_ptr = &event_call_mess; zmq::message_t *data_mess_ptr = &data_mess; map::iterator mcast_ite; map::iterator mcast_ite_end = event_mcast.end(); int local_double_send = double_send; bool mcast_event = false; if (event_mcast.empty() == false) { if ((mcast_ite = event_mcast.find(event_name)) != mcast_ite_end) { if (mcast_ite->second.local_client == false) { pub = mcast_ite->second.pub_socket; } else { if (mcast_ite->second.pub_socket != NULL) { send_nb = 2; pub = mcast_ite->second.pub_socket; } } if (mcast_ite->second.double_send == true) local_double_send++; mcast_ite->second.double_send = false; mcast_event = true; } } if (local_double_send > 0) { send_nb = 2; if (mcast_event == false) double_send--; } // // If we have a multicast socket with also a local client we are obliged to send two times the messages. // ZMQ does not support local client with PGM socket // zmq::message_t name_mess_cpy; zmq::message_t event_call_mess_cpy; zmq::message_t data_mess_cpy; if (send_nb == 2) { name_mess_cpy.copy(&name_mess); event_call_mess_cpy.copy(&event_call_mess); data_mess_cpy.copy(&data_mess); } while(send_nb > 0) { // // Push the event // bool ret; ret = pub->send(*name_mess_ptr,ZMQ_SNDMORE); if (ret == false) { cerr << "Name message returned false, assertion!!!!" << endl; assert(false); } ret = pub->send(*endian_mess_ptr,ZMQ_SNDMORE); if (ret == false) { cerr << "Endian message returned false, assertion!!!!" << endl; assert(false); } endian_mess_sent = true; ret = pub->send(*event_call_mess_ptr,ZMQ_SNDMORE); if (ret == false) { cerr << "Call message returned false, assertion!!!!" << endl; assert(false); } ret = pub->send(*data_mess_ptr,0); if (ret == false) { cerr << "Data message returned false, assertion!!!!" << endl; assert(false); } send_nb--; if (send_nb == 1) { if ((event_mcast.empty() == false) && (mcast_ite != mcast_ite_end)) { // // Case of multicast socket with a local client. Send the event also on the local socket // if (mcast_ite->second.local_client == true) { zmq::socket_t *old_pub = pub; pub = event_pub_sock; name_mess.copy(&name_mess_cpy); endian_mess.copy(&endian_mess_2); event_call_mess.copy(&event_call_mess_cpy); data_mess.copy(&data_mess_cpy); pub->send(*name_mess_ptr,ZMQ_SNDMORE); pub->send(*endian_mess_ptr,ZMQ_SNDMORE); endian_mess_sent = true; pub->send(*event_call_mess_ptr,ZMQ_SNDMORE); pub->send(*data_mess_ptr,0); pub = old_pub; name_mess_ptr = &name_mess_cpy; endian_mess.copy(&endian_mess_2); event_call_mess_ptr = &event_call_mess_cpy; data_mess_ptr = &data_mess_cpy; } else { name_mess_ptr = &name_mess_cpy; endian_mess.copy(&endian_mess_2); event_call_mess_ptr = &event_call_mess_cpy; data_mess_ptr = &data_mess_cpy; } } name_mess_ptr = &name_mess_cpy; endian_mess.copy(&endian_mess_2); event_call_mess_ptr = &event_call_mess_cpy; data_mess_ptr = &data_mess_cpy; } } // // Increment event counter if required // if (ev_cptr_ite != event_cptr.end() && inc_cptr == true) ev_cptr_ite->second++; // // For reference counting on zmq messages which do not have a local scope // endian_mess.copy(&endian_mess_2); // // release mutex if we haven't use ZMQ no copy mode // if (large_data == false) { push_mutex.release(); } else { if (require_wait == true) { push_cond.wait(); } push_mutex.release(); } } catch(...) { cout3 << "ZmqEventSupplier::push_event() failed !!!!!!!!!!!\n"; if (endian_mess_sent == true) endian_mess.copy(&endian_mess_2); if (large_message_created == false) push_mutex.release(); TangoSys_OMemStream o; o << "Can't push ZMQ event for event "; o << event_name; if (zmq_errno() != 0) o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; else o << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventSupplier::push_event"); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::update_connected_client // // description : // //------------------------------------------------------------------------------------------------------------------- bool ZmqEventSupplier::update_connected_client(client_addr *cl) { bool ret = false; // // Immediately return if client identification not possible. (Very old client....) // if (cl == NULL) return ret; // // First try to find the client in list // struct timeval now; #ifdef _TG_WINDOWS_ struct _timeb after_win; _ftime(&after_win); now.tv_sec = (time_t)after_win.time; #else gettimeofday(&now,NULL); #endif list::iterator pos; #ifdef HAS_LAMBDA_FUNC pos = find_if(con_client.begin(),con_client.end(), [&] (ConnectedClient &cc) -> bool { return (cc.clnt == *cl); }); #else pos = find_if(con_client.begin(),con_client.end(), bind2nd(WantedClient(),*cl)); #endif // // Update date if client in list. Otherwise add client to list // if (pos != con_client.end()) { pos->date = now.tv_sec; } else { ConnectedClient new_cc; new_cc.clnt = *cl; new_cc.date = now.tv_sec; con_client.push_back(new_cc); ret = true; } // // Remove presumly dead client // #ifdef HAS_LAMBDA_FUNC con_client.remove_if([&] (ConnectedClient &cc) -> bool { if (now.tv_sec > (cc.date + 500)) return true; else return false; }); #else con_client.remove_if(bind2nd(OldClient(),now.tv_sec)); #endif return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::push_event_loop() // // description : // Method to send the event in a loop due to possible different client release (event compatibility) // // argument : // in : // - device_impl : The device // - event_type : The event type (change, periodic....) // - filterable_names : // - filterable_data : // - attr_value : The attribute value // - att : The attribute object reference // - except : The exception thrown during the last attribute reading. NULL if no exception // //------------------------------------------------------------------------------------------------------------------- void ZmqEventSupplier::push_event_loop(DeviceImpl *device_impl,EventType event_type, TANGO_UNUSED(vector &filterable_names),TANGO_UNUSED(vector &filterable_data), TANGO_UNUSED(vector &filterable_names_lg),TANGO_UNUSED(vector &filterable_data_lg), struct SuppliedEventData &attr_value,Attribute &att,DevFailed *except) { cout3 << "ZmqEventSupplier::push_event_loop(): called for attribute " << att.get_name() << endl; vector &client_libs = att.get_client_lib(event_type); vector::iterator ite; string ev_name = EventName[event_type]; bool inc_ctr = true; for (ite = client_libs.begin();ite != client_libs.end();++ite) { bool need_free = false; bool name_changed = false; struct SuppliedEventData sent_value; ::memset(&sent_value,0,sizeof(sent_value)); if (except == NULL) { switch (*ite) { case 5: { convert_att_event_to_5(attr_value,sent_value,need_free,att); ev_name = EVENT_COMPAT_IDL5 + ev_name; name_changed = true; } break; case 4: { convert_att_event_to_4(attr_value,sent_value,need_free,att); } break; default: { convert_att_event_to_3(attr_value,sent_value,need_free,att); } break; } } push_event(device_impl, ev_name, filterable_names, filterable_data, filterable_names_lg, filterable_data_lg, sent_value, att.get_name_lower(), except, inc_ctr); inc_ctr = false; if (need_free == true) { if (sent_value.attr_val_5 != NULL) delete sent_value.attr_val_5; else if (sent_value.attr_val_4 != NULL) delete sent_value.attr_val_4; else if (sent_value.attr_val_3 != NULL) delete sent_value.attr_val_3; else delete sent_value.attr_val; } if (name_changed == true) ev_name = EventName[event_type]; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::get_blob_data_elt() // // description : // Get how many data are transferred in the blob given as parameter. For instance, for a blob transporting // one array of 1000 double, the returned value will be 1000 // // argument : // in : // - dvpdea : The sequence of data element in the blob // // return : // Size (in number of data) of the data blob // //------------------------------------------------------------------------------------------------------------------- size_t ZmqEventSupplier::get_blob_data_nb(DevVarPipeDataEltArray &dvpdea) { size_t ret = 0; size_t nb_blob = dvpdea.length(); for (size_t loop = 0;loop < nb_blob;loop++) { ret = ret + get_data_elt_data_nb(dvpdea[loop]); } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // ZmqEventSupplier::get_data_elt_data_nb() // // description : // Get how many data are transferred in the data element given as parameter. For instance, for a data element // transporting one array of 250 floats, the returned value will be 250 // // argument : // in : // - dvde : The data element // // return : // Size (in number of data) of the data element // //------------------------------------------------------------------------------------------------------------------- size_t ZmqEventSupplier::get_data_elt_data_nb(DevPipeDataElt &dvde) { size_t ret = 0; if (dvde.inner_blob.length() != 0) ret = get_blob_data_nb(dvde.inner_blob); else { switch (dvde.value._d()) { case ATT_BOOL: { const DevVarBooleanArray &dvba = dvde.value.bool_att_value(); ret = dvba.length(); } break; case ATT_SHORT: { const DevVarShortArray &dvsa = dvde.value.short_att_value(); ret = dvsa.length(); } break; case ATT_LONG: { const DevVarLongArray &dvla = dvde.value.long_att_value(); ret = dvla.length(); } break; case ATT_LONG64: { const DevVarLong64Array &dvlo64 = dvde.value.long64_att_value(); ret = dvlo64.length(); } break; case ATT_FLOAT: { const DevVarFloatArray &dvfa = dvde.value.float_att_value(); ret = dvfa.length(); } break; case ATT_DOUBLE: { const DevVarDoubleArray &dvda = dvde.value.double_att_value(); ret = dvda.length(); } break; case ATT_UCHAR: { const DevVarCharArray &dvda = dvde.value.uchar_att_value(); ret = dvda.length(); } break; case ATT_USHORT: { const DevVarUShortArray &dvda = dvde.value.ushort_att_value(); ret = dvda.length(); } break; case ATT_ULONG: { const DevVarULongArray &dvda = dvde.value.ulong_att_value(); ret = dvda.length(); } break; case ATT_ULONG64: { const DevVarULong64Array &dvda = dvde.value.ulong64_att_value(); ret = dvda.length(); } break; case ATT_STRING: { const DevVarStringArray &dvda = dvde.value.string_att_value(); ret = dvda.length(); } break; case ATT_STATE: { const DevVarStateArray &dvda = dvde.value.state_att_value(); ret = dvda.length(); } break; case ATT_ENCODED: { const DevVarEncodedArray &dvda = dvde.value.encoded_att_value(); ret = dvda[0].encoded_data.length(); } break; default: break; } } return ret; } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/server/idl/0000755023471100065110000000000013034745257013426 500000000000000tango-9.2.5a/lib/cpp/server/idl/Makefile.am0000644023471100065110000000414513034745000015370 00000000000000 # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = $(ORB_INCLUDE_PREFIX) IDL_BASE_DIR = $(top_srcdir)/lib/idl BUILT_SOURCES = tangoSK.cpp tangoSK.cpp: Makefile $(IDL) -I$(IDL_BASE_DIR) -bcxx -Wbh=.h -Wbs=SK.cpp -Wbd=DynSK.cpp -Wba $(IDL_BASE_DIR)/tango.idl @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~DevPipeData() {if (mut_ptr != NULL)mut_ptr->unlock();}\ DevPipeData() {mut_ptr=NULL;}\ void set_pipe_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_pipe_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *mut_ptr;' tango.h @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~AttributeValue_4() {if (mut_ptr != NULL)mut_ptr->unlock();}\ AttributeValue_4() {mut_ptr=NULL;}\ void set_attr_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_attr_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *get_attr_mutex() {return mut_ptr;}\ omni_mutex *mut_ptr;' tango.h @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~AttributeValue_5() {if (mut_ptr != NULL)mut_ptr->unlock();}\ AttributeValue_5() {mut_ptr=NULL;}\ void set_attr_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_attr_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *get_attr_mutex() {return mut_ptr;}\ omni_mutex *mut_ptr;' tango.h # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libidl.la # These are the sources for the library. nodist_libidl_la_SOURCES = tangoSK.cpp \ tangoDynSK.cpp \ tango.h idldir=${includedir}/tango/idl install-data-local: mkdir -p $(DESTDIR)/$(idldir) cp -f tango.h $(DESTDIR)/$(idldir)/tango.h chmod u+w $(DESTDIR)/$(idldir)/tango.h uninstall-local: rm $(DESTDIR)/$(idldir)/tango.h rmdir $(DESTDIR)/$(idldir) clean-local: clean-local-check .PHONY: clean-local-check clean-local-check: -rm *.cpp -rm *.h #idl_HEADERS=tango.h tango-9.2.5a/lib/cpp/server/idl/Makefile.in0000644023471100065110000005262513034745122015414 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/server/idl DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libidl_la_LIBADD = nodist_libidl_la_OBJECTS = tangoSK.lo tangoDynSK.lo libidl_la_OBJECTS = $(nodist_libidl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(nodist_libidl_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = $(ORB_INCLUDE_PREFIX) IDL_BASE_DIR = $(top_srcdir)/lib/idl BUILT_SOURCES = tangoSK.cpp # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libidl.la # These are the sources for the library. nodist_libidl_la_SOURCES = tangoSK.cpp \ tangoDynSK.cpp \ tango.h idldir = ${includedir}/tango/idl all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/server/idl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/server/idl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libidl.la: $(libidl_la_OBJECTS) $(libidl_la_DEPENDENCIES) $(EXTRA_libidl_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libidl_la_OBJECTS) $(libidl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tangoDynSK.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tangoSK.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-local clean-noinstLTLIBRARIES ctags \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-local tangoSK.cpp: Makefile $(IDL) -I$(IDL_BASE_DIR) -bcxx -Wbh=.h -Wbs=SK.cpp -Wbd=DynSK.cpp -Wba $(IDL_BASE_DIR)/tango.idl @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~DevPipeData() {if (mut_ptr != NULL)mut_ptr->unlock();}\ DevPipeData() {mut_ptr=NULL;}\ void set_pipe_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_pipe_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *mut_ptr;' tango.h @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~AttributeValue_4() {if (mut_ptr != NULL)mut_ptr->unlock();}\ AttributeValue_4() {mut_ptr=NULL;}\ void set_attr_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_attr_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *get_attr_mutex() {return mut_ptr;}\ omni_mutex *mut_ptr;' tango.h @SED@ -i '/typedef\ _CORBA_ConstrType_Variable_Var/a \/\/Added by Tango team\ virtual ~AttributeValue_5() {if (mut_ptr != NULL)mut_ptr->unlock();}\ AttributeValue_5() {mut_ptr=NULL;}\ void set_attr_mutex(omni_mutex *ptr) {mut_ptr=ptr;}\ void rel_attr_mutex() {if (mut_ptr != NULL){mut_ptr->unlock();mut_ptr=NULL;}}\ omni_mutex *get_attr_mutex() {return mut_ptr;}\ omni_mutex *mut_ptr;' tango.h install-data-local: mkdir -p $(DESTDIR)/$(idldir) cp -f tango.h $(DESTDIR)/$(idldir)/tango.h chmod u+w $(DESTDIR)/$(idldir)/tango.h uninstall-local: rm $(DESTDIR)/$(idldir)/tango.h rmdir $(DESTDIR)/$(idldir) clean-local: clean-local-check .PHONY: clean-local-check clean-local-check: -rm *.cpp -rm *.h #idl_HEADERS=tango.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/server/jpeg/0000755023471100065110000000000013034745257013603 500000000000000tango-9.2.5a/lib/cpp/server/jpeg/Makefile.am0000644023471100065110000000201113034744776015556 00000000000000 # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libjpeg.la AM_CXXFLAGS=@JPEG_LIB_CXXFLAGS@ # These are the sources for the library. libjpeg_la_SOURCES = jpeg_bitstream.cpp \ jpeg_color.cpp \ jpeg_dct.cpp \ jpeg_decoder.cpp \ jpeg_encoder.cpp \ jpeg_memory.cpp \ jpeg_bitstream.h \ jpeg_const.h \ jpeg_lib.h \ jpeg_memory.h tango-9.2.5a/lib/cpp/server/jpeg/Makefile.in0000644023471100065110000005064113034745122015565 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/server/jpeg DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libjpeg_la_LIBADD = am_libjpeg_la_OBJECTS = jpeg_bitstream.lo jpeg_color.lo jpeg_dct.lo \ jpeg_decoder.lo jpeg_encoder.lo jpeg_memory.lo libjpeg_la_OBJECTS = $(am_libjpeg_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libjpeg_la_SOURCES) DIST_SOURCES = $(libjpeg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libjpeg.la AM_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ # These are the sources for the library. libjpeg_la_SOURCES = jpeg_bitstream.cpp \ jpeg_color.cpp \ jpeg_dct.cpp \ jpeg_decoder.cpp \ jpeg_encoder.cpp \ jpeg_memory.cpp \ jpeg_bitstream.h \ jpeg_const.h \ jpeg_lib.h \ jpeg_memory.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/server/jpeg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/server/jpeg/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libjpeg.la: $(libjpeg_la_OBJECTS) $(libjpeg_la_DEPENDENCIES) $(EXTRA_libjpeg_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libjpeg_la_OBJECTS) $(libjpeg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_bitstream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_color.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_dct.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpeg_memory.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/server/jpeg/jpeg_bitstream.cpp0000644023471100065110000003215613034744776017242 00000000000000///============================================================================= // // file : jpeg_bitstream.cpp // // description : Simple jpeg coding/decoding library // Bitstream management and huffman coding // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.3 2009/11/02 08:36:17 taurel // - Fix warnings reported when compiling using the option -Wall // // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #include "jpeg_bitstream.h" #include #include #include #ifdef _WINDOWS // Disable "has no EMMS instruction" warning #pragma warning( disable : 4799 ) #endif #ifdef _WINDOWS #ifdef JPG_USE_ASM // MMX putbits only for Windows #define JPG_USE_ASM_PB static unsigned short mmComp[] = { 0xFFFF , 0xFFFF , 0xFFFF , 0xFFFF }; #endif #endif extern int jpgZag[]; // --------------------------------------------------------------------- // Output bitstream // ---------------------------------------------------------------- OutputBitStream::OutputBitStream() { buffer = (unsigned char *)malloc(BUFFER_SIZE); buffSize = BUFFER_SIZE; nbByte = 0; nbBits = 0; bits = 0; bufferPtr = buffer; // numbits table (speed up huffman coding) numbits = (unsigned char *)malloc(2048); numbits[0]=0; numbits[1]=1; for(int i=2;i<12;i++) { int s = (1L<<(i-1)); int e = (1L<<(i)); memset(numbits+s,i,e-s); } } // ---------------------------------------------------------------- OutputBitStream::~OutputBitStream() { if(buffer) free(buffer); if(numbits) free(numbits); } // ---------------------------------------------------------------- void OutputBitStream::init() { #ifdef JPG_USE_ASM_PB __asm { pxor mm1,mm1 movq mm5,mmComp } #endif } void OutputBitStream::flush() { align(); #ifdef JPG_USE_ASM_PB // Flush mm buffer _asm { mov edi,this psrlq mm1,32 movd ebx,mm1 mov dword ptr [edi].bScratch,ebx emms } if(nbBits>=8) { put_byte(bScratch[3]);if(bScratch[3]==0xFF) put_byte(0);nbBits-=8; } if(nbBits>=8) { put_byte(bScratch[2]);if(bScratch[2]==0xFF) put_byte(0);nbBits-=8; } if(nbBits>=8) { put_byte(bScratch[1]);if(bScratch[1]==0xFF) put_byte(0);nbBits-=8; } if(nbBits>=8) { put_byte(bScratch[0]);if(bScratch[0]==0xFF) put_byte(0);nbBits-=8; } #endif } void OutputBitStream::load_mm() { #ifdef JPG_USE_ASM_PB __asm { mov edi,this movq mm2,mm1 psllq mm1,32 psrlq mm2,32 movd ebx,mm2 // Enough free bytes ? mov eax,[edi].buffSize sub eax,[edi].nbByte cmp eax,4 jle _pbload8 // Any 0xFF in the stream ? pcmpeqb mm2,mm5 movd eax,mm2 or eax,eax jz _pbload32 _pbload8: mov dword ptr [edi].bScratch,ebx } put_byte(bScratch[3]);if(bScratch[3]==0xFF) put_byte(0); put_byte(bScratch[2]);if(bScratch[2]==0xFF) put_byte(0); put_byte(bScratch[1]);if(bScratch[1]==0xFF) put_byte(0); put_byte(bScratch[0]);if(bScratch[0]==0xFF) put_byte(0); nbBits -= 32; return; _pbload32: _asm { mov esi,[edi].bufferPtr bswap ebx mov [esi],ebx } bufferPtr += 4; nbByte += 4; nbBits -= 32; #endif } // ---------------------------------------------------------------- #ifdef _WINDOWS __forceinline void OutputBitStream::put_bits(int code,int _size) { #else inline void OutputBitStream::put_bits(int code,int _size) { #endif #ifdef JPG_USE_ASM_PB _asm { mov edi,this movd mm2,code mov edx,[edi].nbBits add edx,_size mov ebx,64 mov [edi].nbBits,edx sub ebx,edx movd mm3,ebx psllq mm2,mm3 por mm1,mm2 } if( nbBits>=32 ) load_mm(); #else nbBits += _size; code <<= 32 - nbBits; bits |= code; while( nbBits>=8 ) { unsigned char c = (unsigned char)(bits >> 24); put_byteI(c); if( c==0xFF ) put_byteI(0); bits <<= 8; nbBits-=8; } #endif } // ---------------------------------------------------------------- void OutputBitStream::align() { int s = 8-(nbBits&7); int val ((1L << s) - 1); put_bits(val,s); } // ---------------------------------------------------------------- #ifdef _WINDOWS __forceinline void OutputBitStream::put_byteI(unsigned char code) { #else inline void OutputBitStream::put_byteI(unsigned char code) { #endif if( nbByte==buffSize ) more_byte(); buffer[nbByte]=code; nbByte++; bufferPtr++; } // ---------------------------------------------------------------- void OutputBitStream::put_byte(unsigned char code) { put_byteI(code); } // ---------------------------------------------------------------- void OutputBitStream::put_short(unsigned short code) { put_byte( code>>8 ); put_byte( code&0xFF ); } // ---------------------------------------------------------------- unsigned char *OutputBitStream::get_data() { return buffer; } // ---------------------------------------------------------------- unsigned long OutputBitStream::get_size() { return nbByte; } // ---------------------------------------------------------------- void OutputBitStream::more_byte() { unsigned char *newBuffer = (unsigned char *)malloc(nbByte + BUFFER_SIZE); memcpy(newBuffer,buffer,nbByte); free(buffer); buffer = newBuffer; buffSize += BUFFER_SIZE; bufferPtr = buffer + nbByte; } // ---------------------------------------------------------------- #define NUMBITS11() \ \ if (val < 0) { \ if( val<-2047 ) val=-2047; \ numBits = numbits[-val]; \ val--; \ val &= ((1L << numBits) - 1); \ } else { \ if( val>2047 ) val=2047; \ numBits = numbits[val]; \ } #define NUMBITS10() \ \ if (val < 0) { \ if( val<-1023 ) val=-1023; \ numBits = numbits[-val]; \ val--; \ val &= ((1L << numBits) - 1); \ } else { \ if( val>1023 ) val=1023; \ numBits = numbits[val]; \ } void OutputBitStream::encode_block(short *block,HUFFMANTABLE *hDC,HUFFMANTABLE *hAC,short *lastDc) { int numBits; int i, zero, sym; short val; #ifdef JPG_USE_ASM_PB int codeV,codeS; #endif // DC difference (10+1 bits interval) val = block[0] - (*lastDc); *lastDc = block[0]; NUMBITS11(); put_bits(hDC->huffCode[numBits], hDC->huffSize[numBits]); if (numBits) put_bits(val, numBits); // AC values zero = 0; for (i=1;i<64;i++) { val = block[jpgZag[i]]; if (val==0) { zero++; } else { // If number of zero >= 16, put run-length-16 code (0xF0) while (zero >= 16) { put_bits(hAC->huffCode[0xF0],hAC->huffSize[0xF0]); zero -= 16; } NUMBITS10(); #ifdef JPG_USE_ASM_PB // MMX put_bits allows up to 32 bit code sym = (zero << 4) + numBits; codeS = hAC->huffSize[sym] + numBits; codeV = hAC->huffCode[sym] << numBits; codeV |= ((unsigned int)val); put_bits(codeV, codeS); #else sym = (zero << 4) + numBits; put_bits(hAC->huffCode[sym], hAC->huffSize[sym]); put_bits(val, numBits); #endif zero=0; } } // EOB if (zero > 0) put_bits(hAC->huffCode[0], hAC->huffSize[0]); } // --------------------------------------------------------------------- // Input bitstream // --------------------------------------------------------------------- //------------------------------------------------------------------------------ // Sign extension static const int extend_test[16] = /* entry n is 2**(n-1) */ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; // Tables are slightly faster with Visual C++ #ifdef _WINDOWS #define HUFF_EXTEND(x,s) s = ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) #else #define HUFF_EXTEND(x,s) s = ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) #endif //------------------------------------------------------------------------------ // Retrieve n first bits from the input stream. #define SHOWBITS(n) (_bits >> (32 - (n))) //------------------------------------------------------------------------------ // Remove n bits from the input stream. #define DROPBITS(n) { \ _nbBits -= (n); \ _bits <<= (n); \ while( _nbBits<=16 ) { \ int c1 = get_byte(); \ /*Remove stuffed 0 (following 0xFF)*/ \ if (c1 == 0xFF) { \ int c2 = get_byte(); \ if (c2!=0) {_bufferPtr--;_byteRead--;}\ } \ _bits |= c1 << (24 - _nbBits); \ _nbBits+=8; \ }} InputBitStream::InputBitStream(unsigned char *buff,int buffSize) { _buffer = buff; _buffSize = buffSize; _nbBits = 0; _bits = 0; _byteRead = 0; _bufferPtr = buff; } InputBitStream::~InputBitStream() { } void InputBitStream::align() { get_bits(_nbBits & 7); } void InputBitStream::flush() { align(); // Make stream ready for get_byte() if( _nbBits>0 ) { if(_nbBits==32) {_bufferPtr-=4;_byteRead-=4;} if(_nbBits==24) {_bufferPtr-=3;_byteRead-=3;} if(_nbBits==16) {_bufferPtr-=2;_byteRead-=2;} if(_nbBits==8) {_bufferPtr-=1;_byteRead-=1;} _nbBits = 0; } } void InputBitStream::init() { get_bits(0); } int InputBitStream::get_byte() { if( _byteRead<_buffSize ) { _byteRead++; return *_bufferPtr++; } else { return 0; } } int InputBitStream::get_bits(int numbits) { int i = SHOWBITS(numbits); DROPBITS(numbits); return i; } // Inverse dct (jpeg_dct.cpp) void jpeg_idct(short *block,unsigned char *dst); void jpeg_idct_mmx(short *block,unsigned char *dst); int InputBitStream::decode_mcu(JPGDECODER *decoder) { int r, s, k, c; int *clist = decoder->compList; short *block = decoder->blocks; unsigned char *ycc = decoder->yccFrame; for(int i=0;imcuNbBlock;i++) { HUFFMANTABLE *hDC = decoder->hTables + decoder->comps[clist[i]].dcIdx; HUFFMANTABLE *hAC = decoder->hTables + decoder->comps[clist[i]].acIdx; short *qTable = decoder->qTables[decoder->comps[clist[i]].quantIdx]; // -- DC value -------------------------------- // Use a tree traversal to find symbol. c = SHOWBITS(8); if ((s = hDC->lookUp[c]) < 0) { DROPBITS(8); int drop = 0; c = ~SHOWBITS(8); do { drop++; s = hAC->tree[~s + ((c&0x80)>>7)]; c <<= 1; } while (s < 0); DROPBITS(drop); } else DROPBITS(hDC->huffSize[s]); // Decode if (s!= 0) { r = get_bits(s); HUFF_EXTEND(r, s); } decoder->comps[clist[i]].lastDc += s; s = decoder->comps[clist[i]].lastDc; block[0] = (short)s * qTable[0]; // -- AC values ------------------------------- for (k = 1; k < 64; k++) { // Use a tree traversal to find symbol. c = SHOWBITS(8); if ((s = hAC->lookUp[c]) < 0) { DROPBITS(8); int drop = 0; c = ~SHOWBITS(8); do { drop++; s = hAC->tree[~s + ((c&0x80)>>7)]; c <<= 1; } while (s < 0); DROPBITS(drop); } else DROPBITS(hAC->huffSize[s]); // Decode r = s >> 4; s &= 15; if (s) { k += r; if (k>63) return -24; // Decode error r = SHOWBITS(s); DROPBITS(s); HUFF_EXTEND(r, s); block[jpgZag[k]] = (short)s * qTable[k]; } else { if (r == 15) { k += 15; } else { break; } } } // end block loop #ifdef JPG_USE_ASM jpeg_idct_mmx(block,ycc); #else jpeg_idct(block,ycc); #endif block += 64; ycc += 64; } return 0; } tango-9.2.5a/lib/cpp/server/jpeg/jpeg_color.cpp0000644023471100065110000004612113034744776016363 00000000000000///============================================================================= // // file : jpeg_color.cpp // // description : Simple jpeg coding/decoding library // Color space conversion // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.3 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= //------------------------------------------------------------------------------ // // (YCbCr to RGB) Y,Cb and Cr range in [0,255] // R = Y + 1.402 * (Cr-128) // G = Y - 0.34414 * (Cb-128) - 0.71414*(Cr-128) // B = Y + 1.772 * (Cb-128) // // (RGB to YCbCr) R,G,B range in [0,255] // Y = 0.299 * R + 0.587 * G + 0.114 * B // Cb = -0.16874 * R - 0.33126 * G + 0.5 * B + 128 // Cr = 0.5 * R - 0.41869 * G - 0.08131 * B + 128 // //------------------------------------------------------------------------------ #include "jpeg_memory.h" #include "jpeg_lib.h" #include #define TRUNC(i) ((i) & 0xFFFFFF00)?(unsigned char)(((~(i)) >> 31) & 0xFF):(unsigned char)(i) static long *ry = NULL; static long *gy = NULL; static long *by = NULL; static long *rcb = NULL; static long *gcb = NULL; static long *bcb = NULL; static long *rcr = NULL; static long *gcr = NULL; static long *bcr = NULL; static long *crr = NULL; static long *cbb = NULL; static long *crg = NULL; static long *cbg = NULL; // ------------------------------------------------------------------------------ void jpeg_init_color() { // Conversion table to speed up RGB <-> YCbCr conversion (fixed point) if( !ry ) { ry = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) ry[i] = (long)(0.299*65536.0+0.5) * i; gy = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) gy[i] = (long)(0.587*65536.0+0.5) * i; by = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) by[i] = (long)(0.114*65536.0+0.5) * i + 32767L; rcb = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) rcb[i] = (long)(0.16874*65536.0+0.5) * (-i); gcb = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) gcb[i] = (long)(0.33126*65536.0+0.5) * (-i); bcb = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) bcb[i] = (long)(0.5*65536.0+0.5) * (i) + 32767L; rcr = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) rcr[i] = (long)(0.5*65536.0+0.5) * (i); gcr = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) gcr[i] = (long)(0.41869*65536.0+0.5) * (-i); bcr = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) bcr[i] = (long)(0.08131*65536.0+0.5) * (-i) + 32767L; crr = (long *)malloc(256 * sizeof(long)); cbb = (long *)malloc(256 * sizeof(long)); crg = (long *)malloc(256 * sizeof(long)); cbg = (long *)malloc(256 * sizeof(long)); for(long i=0;i<256;i++) { double k = (double)((i * 2) - 256); crr[i] = (long)( 1.402*32768.0*k + 32767.0 ) >> 16; cbb[i] = (long)( 1.772*32768.0*k + 32767.0 ) >> 16; crg[i] = (long)( -0.71414*32768.0*k ); cbg[i] = (long)( -0.34414*32768.0*k + 32767.0 ); } } } //------------------------------------------------------------------------------ // MCU16x16 YCbCr H2V2 (2x2:1:1, 6 blocks per MCU) to 32-bit RGB //------------------------------------------------------------------------------ void jpeg_yh2v2_to_rgb32(unsigned char *block,int width,unsigned char *rgb) { unsigned char *y = block; unsigned char *cb = block+64*4; unsigned char *cr = block+64*5; int pitch = width*4; unsigned char *row; unsigned char *yP; long y0,yy,rc,gc,bc; for(int j=0;j<8;j++) { row = rgb; y0 = ((j&4)<<5) + ((j&3)<<4); for(int i=0;i<8;i++) { yP = y + (y0 + ((i&4)<<4) + ((i&3)<<1)); rc = crr[*cr]; gc = ((crg[*cr] + cbg[*cb]) >> 16); bc = cbb[*cb]; yy = yP[0]; row[0] = TRUNC(yy+rc); row[1] = TRUNC(yy+gc); row[2] = TRUNC(yy+bc); yy = yP[1]; row[4] = TRUNC(yy+rc); row[5] = TRUNC(yy+gc); row[6] = TRUNC(yy+bc); yy = yP[8]; row[0+pitch] = TRUNC(yy+rc); row[1+pitch] = TRUNC(yy+gc); row[2+pitch] = TRUNC(yy+bc); yy = yP[9]; row[4+pitch] = TRUNC(yy+rc); row[5+pitch] = TRUNC(yy+gc); row[6+pitch] = TRUNC(yy+bc); row+=8; cr++; cb++; } rgb+=2*pitch; } } //------------------------------------------------------------------------------ // MCU8x8 YCbCr H1V1 (1x1:1:1, 3 blocks per MCU) to 32-bit RGB //------------------------------------------------------------------------------ void jpeg_yh1v1_to_rgb32(unsigned char *block,int width,unsigned char *rgb) { int pitch = width*4; unsigned char *row; unsigned char *ycc = block; for (int i=0; i<8 ; i++) { row = rgb; for (int j=0; j<8; j++) { int y = ycc[0]; int cb = ycc[64]; int cr = ycc[128]; row[0] = TRUNC(y + crr[cr]); row[1] = TRUNC(y + ((crg[cr] + cbg[cb]) >> 16)); row[2] = TRUNC(y + cbb[cb]); row += 4; ycc++; } rgb+=pitch; } } //------------------------------------------------------------------------------ // MCU8x8 Y (1 block per MCU) to 8-bit grayscale //------------------------------------------------------------------------------ void jpeg_y_to_gray(unsigned char *block,int width,unsigned char *rgb) { unsigned char *s = block; unsigned char *d = rgb; for (int i=0;i<8;i++) { *(unsigned long *)d = *(unsigned long *)s; *(unsigned long *)(&d[4]) = *(unsigned long *)(&s[4]); s += 8; d += width; } } #ifdef JPG_USE_ASM extern void conv_block_RGB32H2V2_mmx(long width,unsigned char *rgb,short *y,short *cb,short *cr); extern void conv_block_RGB24H2V2_mmx(long width,unsigned char *rgb,short *y,short *cb,short *cr); extern void conv_block_GRAY8Y_mmx(long width,unsigned char *g,short *y); #endif // -------------------------------------------------------------------------------------- // Convert 16x16 RGB32 pixel map to (4xY 1xCb 1xCr) block (4:2:0) // -------------------------------------------------------------------------------------- void conv_block_RGB32H2V2(int width,unsigned char *rgb,short *y,short *cb,short *cr) { short r00,g00,b00,r10,g10,b10,r01,g01,b01,r11,g11,b11; int y0,yIdx; short rd,gd,bd; for(int j=0;j<8;j++) { y0 = ((j&4)<<5) + ((j&3)<<4); for(int i=0;i<8;i++) { yIdx = y0 + ((i&4)<<4) + ((i&3)<<1); r00 = (short)rgb[0]; g00 = (short)rgb[1]; b00 = (short)rgb[2]; r10 = (short)rgb[4]; g10 = (short)rgb[5]; b10 = (short)rgb[6]; r01 = (short)rgb[0+width*4]; g01 = (short)rgb[1+width*4]; b01 = (short)rgb[2+width*4]; r11 = (short)rgb[4+width*4]; g11 = (short)rgb[5+width*4]; b11 = (short)rgb[6+width*4]; y[0+yIdx] = (short)( (ry[r00] + gy[g00] + by[b00]) >> 16 ) - 128; y[1+yIdx] = (short)( (ry[r10] + gy[g10] + by[b10]) >> 16 ) - 128; y[8+yIdx] = (short)( (ry[r01] + gy[g01] + by[b01]) >> 16 ) - 128; y[9+yIdx] = (short)( (ry[r11] + gy[g11] + by[b11]) >> 16 ) - 128; rd = (r00 + r10 + r01 + r11) >> 2; gd = (g00 + g10 + g01 + g11) >> 2; bd = (b00 + b10 + b01 + b11) >> 2; *cb = (short)( (rcb[rd] + gcb[gd] + bcb[bd]) >> 16 ); *cr = (short)( (rcr[rd] + gcr[gd] + bcr[bd]) >> 16 ); rgb+=8; cb++; cr++; } rgb += 8*width-64; } } void jpeg_rgb32_to_ycc(int width,int height,int outWidth,int outHeight,unsigned char *rgb32,short *ycc) { // outWidth and outHeight must be multiple of 16 // ycc map is stored as jpeg 8x8 block order (4xY 1xCb 1xCr) // ycc must reference a buffer of at least (outWidth*outHeight*3) bytes short *y = ycc; unsigned char *rgb = rgb32; short *cb = ycc + 64*4; short *cr = ycc + 64*5; int k,l,yp,scr; unsigned char rgbScrath[16*16*4]; int w16 = (width >>4) * 16; int h16 = (height>>4) * 16; int paddWidth = (w16> 16 ) - 128; y[1+yIdx] = (short)( (ry[r10] + gy[g10] + by[b10]) >> 16 ) - 128; y[8+yIdx] = (short)( (ry[r01] + gy[g01] + by[b01]) >> 16 ) - 128; y[9+yIdx] = (short)( (ry[r11] + gy[g11] + by[b11]) >> 16 ) - 128; rd = (r00 + r10 + r01 + r11) >> 2; gd = (g00 + g10 + g01 + g11) >> 2; bd = (b00 + b10 + b01 + b11) >> 2; *cb = (short)( (rcb[rd] + gcb[gd] + bcb[bd]) >> 16 ); *cr = (short)( (rcr[rd] + gcr[gd] + bcr[bd]) >> 16 ); rgb+=6; cb++; cr++; } rgb += 6*width-48; } } void jpeg_rgb24_to_ycc(int width,int height,int outWidth,int outHeight,unsigned char *rgb24,short *ycc) { // outWidth and outHeight must be multiple of 16 // ycc map is stored as jpeg 8x8 block order (4xY 1xCb 1xCr) // ycc must reference a buffer of at least (outWidth*outHeight*3) bytes short *y = ycc; unsigned char *rgb = rgb24; short *cb = ycc + 64*4; short *cr = ycc + 64*5; int k,l,yp,scr; unsigned char rgbScrath[16*16*3]; int w16 = (width >>4) * 16; int h16 = (height>>4) * 16; int paddWidth = (w16>3) * 8; int h8 = (height>>3) * 8; int paddWidth = (w8. // // $Revision: 27410 $ // // $Log$ // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= // C implementation comes from JPEG library by Thomas G. Lane #include "jpeg_lib.h" #define SHIFT2(x) (((x) + 2) >> 2 ) #define SHIFT11(x) (((x) + 2048) >> 11) #define SHIFT15(x) (((x) + 32768) >> 15) #define FIXPOINT 13 #define _1 ((long)1) #define SCALE (_1 << FIXPOINT) #define CLIP(x) if (x & 0xFF00) x = (((~x) >> 15) & 0xFF) #define ROUND(x,n) (((x) + (_1 << ((n)-1))) >> (n)) #define FIX_0_298631336 ((long) 2446) /* 0.298631336 -c1+c3+c5-c7 */ #define FIX_0_390180644 ((long) 3196) /* 0.390180644 c5-c3 (neg) */ #define FIX_0_541196100 ((long) 4433) /* 0.541196100 c6 */ #define FIX_0_765366865 ((long) 6270) /* 0.765366865 c2-c6 */ #define FIX_0_899976223 ((long) 7373) /* 0.899976223 c7-c3 (neg) */ #define FIX_1_175875602 ((long) 9633) /* 1.175875602 c3 */ #define FIX_1_501321110 ((long) 12299) /* 1.501321110 c1+c3-c5-c7 */ #define FIX_1_847759065 ((long) 15137) /* 1.847759065 -c2-c6 (neg) */ #define FIX_1_961570560 ((long) 16069) /* 1.961570560 -c5-c3 (neg) */ #define FIX_2_053119869 ((long) 16819) /* 2.053119869 c1+c3-c5+c7 */ #define FIX_2_562915447 ((long) 20995) /* 2.562915447 -c1-c3 (neg) */ #define FIX_3_072711026 ((long) 25172) /* 3.072711026 c1+c3+c5-c7 */ void jpeg_fdct( short *block ) { long tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; long tmp10, tmp11, tmp12, tmp13; long z1, z2, z3, z4, z5; short *dataptr; int ctr; // Process rows dataptr = block; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = (long)dataptr[0] + (long)dataptr[7]; tmp7 = (long)dataptr[0] - (long)dataptr[7]; tmp1 = (long)dataptr[1] + (long)dataptr[6]; tmp6 = (long)dataptr[1] - (long)dataptr[6]; tmp2 = (long)dataptr[2] + (long)dataptr[5]; tmp5 = (long)dataptr[2] - (long)dataptr[5]; tmp3 = (long)dataptr[3] + (long)dataptr[4]; tmp4 = (long)dataptr[3] - (long)dataptr[4]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = (short) ((tmp10 + tmp11) << 2); dataptr[4] = (short) ((tmp10 - tmp11) << 2); z1 = (tmp12 + tmp13)*FIX_0_541196100; dataptr[2] = (short) SHIFT11(z1 + tmp13*FIX_0_765366865); dataptr[6] = (short) SHIFT11(z1 - tmp12*FIX_1_847759065); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4)*FIX_1_175875602; tmp4 *= FIX_0_298631336; tmp5 *= FIX_2_053119869; tmp6 *= FIX_3_072711026; tmp7 *= FIX_1_501321110; z1 *= - FIX_0_899976223; z2 *= - FIX_2_562915447; z3 *= - FIX_1_961570560; z4 *= - FIX_0_390180644; z3 += z5; z4 += z5; dataptr[7] = (short) SHIFT11(tmp4 + z1 + z3); dataptr[5] = (short) SHIFT11(tmp5 + z2 + z4); dataptr[3] = (short) SHIFT11(tmp6 + z2 + z3); dataptr[1] = (short) SHIFT11(tmp7 + z1 + z4); dataptr += 8; } // Process columns dataptr = block; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = (long)dataptr[8*0] + (long)dataptr[8*7]; tmp7 = (long)dataptr[8*0] - (long)dataptr[8*7]; tmp1 = (long)dataptr[8*1] + (long)dataptr[8*6]; tmp6 = (long)dataptr[8*1] - (long)dataptr[8*6]; tmp2 = (long)dataptr[8*2] + (long)dataptr[8*5]; tmp5 = (long)dataptr[8*2] - (long)dataptr[8*5]; tmp3 = (long)dataptr[8*3] + (long)dataptr[8*4]; tmp4 = (long)dataptr[8*3] - (long)dataptr[8*4]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[8*0] = (short) SHIFT2(tmp10 + tmp11); dataptr[8*4] = (short) SHIFT2(tmp10 - tmp11); z1 = (tmp12 + tmp13)*FIX_0_541196100; dataptr[8*2] = (short) SHIFT15(z1 + tmp13*FIX_0_765366865); dataptr[8*6] = (short) SHIFT15(z1 - tmp12*FIX_1_847759065); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4)*FIX_1_175875602; tmp4 *= FIX_0_298631336; tmp5 *= FIX_2_053119869; tmp6 *= FIX_3_072711026; tmp7 *= FIX_1_501321110; z1 *= -FIX_0_899976223; z2 *= -FIX_2_562915447; z3 *= -FIX_1_961570560; z4 *= -FIX_0_390180644; z3 += z5; z4 += z5; dataptr[8*7] = (short) SHIFT15(tmp4 + z1 + z3); dataptr[8*5] = (short) SHIFT15(tmp5 + z2 + z4); dataptr[8*3] = (short) SHIFT15(tmp6 + z2 + z3); dataptr[8*1] = (short) SHIFT15(tmp7 + z1 + z4); dataptr++; } } // ------------------------------------------------------------- void jpeg_idct(short *block, unsigned char *dest) { short innerBuff[64]; long tmp0, tmp1, tmp2, tmp3; long tmp10, tmp11, tmp12, tmp13; long z1, z2, z3, z4, z5; short *in,*inner; int i; short v; // Rows in = block; inner = innerBuff; for (i=0;i<8;i++) { if ((in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) == 0) { short dc = in[0] << 3; inner[0] = dc; inner[1] = dc; inner[2] = dc; inner[3] = dc; inner[4] = dc; inner[5] = dc; inner[6] = dc; inner[7] = dc; in += 8; inner += 8; continue; } z2 = (long) in[2]; z3 = (long) in[6]; z1 = (z2 + z3)*FIX_0_541196100; tmp2 = z1 + z3*(- FIX_1_847759065); tmp3 = z1 + z2*FIX_0_765366865; tmp0 = ((long) in[0] + (long) in[4]) << FIXPOINT; tmp1 = ((long) in[0] - (long) in[4]) << FIXPOINT; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; tmp0 = (long) in[7]; tmp1 = (long) in[5]; tmp2 = (long) in[3]; tmp3 = (long) in[1]; z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = (z3 + z4)*FIX_1_175875602; tmp0 = tmp0 * FIX_0_298631336; tmp1 = tmp1 * FIX_2_053119869; tmp2 = tmp2 * FIX_3_072711026; tmp3 = tmp3 * FIX_1_501321110; z1 = z1 * (-FIX_0_899976223); z2 = z2 * (-FIX_2_562915447); z3 = z3 * (-FIX_1_961570560); z4 = z4 * (-FIX_0_390180644); z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; inner[0] = (short) ROUND(tmp10 + tmp3, FIXPOINT-3); inner[1] = (short) ROUND(tmp11 + tmp2, FIXPOINT-3); inner[2] = (short) ROUND(tmp12 + tmp1, FIXPOINT-3); inner[3] = (short) ROUND(tmp13 + tmp0, FIXPOINT-3); inner[4] = (short) ROUND(tmp13 - tmp0, FIXPOINT-3); inner[5] = (short) ROUND(tmp12 - tmp1, FIXPOINT-3); inner[6] = (short) ROUND(tmp11 - tmp2, FIXPOINT-3); inner[7] = (short) ROUND(tmp10 - tmp3, FIXPOINT-3); in += 8; inner += 8; } // Columns in = innerBuff; for(i=0;i<8;i++) { if ((in[8*1] | in[8*2] | in[8*3] | in[8*4]| in[8*5] | in[8*6] | in[8*7]) == 0) { short dc = (short) ROUND((long)in[0], 6) + 128; CLIP(dc); dest[8*0] = (unsigned char)dc; dest[8*1] = (unsigned char)dc; dest[8*2] = (unsigned char)dc; dest[8*3] = (unsigned char)dc; dest[8*4] = (unsigned char)dc; dest[8*5] = (unsigned char)dc; dest[8*6] = (unsigned char)dc; dest[8*7] = (unsigned char)dc; in++; dest++; continue; } z2 = (long) in[8*2]; z3 = (long) in[8*6]; z1 = (z2 + z3)*FIX_0_541196100; tmp2 = z1 + z3 * (-FIX_1_847759065); tmp3 = z1 + z2 * FIX_0_765366865; tmp0 = ((long) in[8*0] + (long) in[8*4]) << FIXPOINT; tmp1 = ((long) in[8*0] - (long) in[8*4]) << FIXPOINT; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; tmp0 = (long) in[8*7]; tmp1 = (long) in[8*5]; tmp2 = (long) in[8*3]; tmp3 = (long) in[8*1]; z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = (z3 + z4)*FIX_1_175875602; tmp0 = tmp0*FIX_0_298631336; tmp1 = tmp1*FIX_2_053119869; tmp2 = tmp2*FIX_3_072711026; tmp3 = tmp3*FIX_1_501321110; z1 = z1 * (-FIX_0_899976223); z2 = z2 * (-FIX_2_562915447); z3 = z3 * (-FIX_1_961570560); z4 = z4 * (-FIX_0_390180644); z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; v = (short) ROUND(tmp10 + tmp3, FIXPOINT+6) + 128; CLIP(v);dest[8*0] = (unsigned char)v; v = (short) ROUND(tmp11 + tmp2, FIXPOINT+6) + 128; CLIP(v);dest[8*1] = (unsigned char)v; v = (short) ROUND(tmp12 + tmp1, FIXPOINT+6) + 128; CLIP(v);dest[8*2] = (unsigned char)v; v = (short) ROUND(tmp13 + tmp0, FIXPOINT+6) + 128; CLIP(v);dest[8*3] = (unsigned char)v; v = (short) ROUND(tmp13 - tmp0, FIXPOINT+6) + 128; CLIP(v);dest[8*4] = (unsigned char)v; v = (short) ROUND(tmp12 - tmp1, FIXPOINT+6) + 128; CLIP(v);dest[8*5] = (unsigned char)v; v = (short) ROUND(tmp11 - tmp2, FIXPOINT+6) + 128; CLIP(v);dest[8*6] = (unsigned char)v; v = (short) ROUND(tmp10 - tmp3, FIXPOINT+6) + 128; CLIP(v);dest[8*7] = (unsigned char)v; dest++; in++; } } tango-9.2.5a/lib/cpp/server/jpeg/jpeg_decoder.cpp0000644023471100065110000005012113034744776016645 00000000000000///============================================================================= // // file : jpeg_decoder.cpp // // description : Simple jpeg coding/decoding library // Main decoding functions // (does not support progressive decoding) // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.4 2009/11/02 08:36:17 taurel // - Fix warnings reported when compiling using the option -Wall // // Revision 1.3 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #include #include #include #include "jpeg_lib.h" #include "jpeg_const.h" #include "jpeg_memory.h" #include "jpeg_bitstream.h" // color conversion declaration (jpeg_color.cpp) void jpeg_init_color(); void jpeg_yh2v2_to_rgb32(unsigned char *block,int width,unsigned char *rgb); void jpeg_yh1v1_to_rgb32(unsigned char *block,int width,unsigned char *rgb); void jpeg_y_to_gray(unsigned char *block,int width,unsigned char *rgb); #ifdef JPG_USE_ASM void jpeg_yh2v2_to_rgb32_mmx(unsigned char *block,long width,unsigned char *rgb); void jpeg_yh1v1_to_rgb32_mmx(unsigned char *block,long width,unsigned char *rgb); #endif extern int jpgZag[]; // ------------------------------------------------------------------ char *jpeg_get_error_msg(int code) { static char retMsg[1024]; switch(-code) { case 0: sprintf(retMsg,"No error");break; case 1: sprintf(retMsg,"Can't find start of image (SOI), may be not a jpeg stream");break; case 2: sprintf(retMsg,"Not supported jpeg format");break; case 3: sprintf(retMsg,"Unexpected jpeg marker found");break; case 4: sprintf(retMsg,"Unexpected end of stream or marker not found");break; case 5: sprintf(retMsg,"Bad DQT marker");break; case 6: sprintf(retMsg,"Invalid quantization table index");break; case 7: sprintf(retMsg,"Invalid quantization table size");break; case 8: sprintf(retMsg,"Invalid variable marker length");break; case 9: sprintf(retMsg,"Bad DHT marker");break; case 10: sprintf(retMsg,"Bad DHT count");break; case 11: sprintf(retMsg,"Bad DHT index");break; case 12: sprintf(retMsg,"Bad SOS marker");break; case 13: sprintf(retMsg,"Bad component id");break; case 14: sprintf(retMsg,"Only 8 bit precission supported");break; case 15: sprintf(retMsg,"Invalid image size (8192x8192 max)");break; case 16: sprintf(retMsg,"Too many components in frame");break; case 17: sprintf(retMsg,"Bad SOF marker");break; case 18: sprintf(retMsg,"Bad DRI marker");break; case 19: sprintf(retMsg,"One or more quantisation table(s) are missing");break; case 20: sprintf(retMsg,"One or more huffman table(s) are missing");break; case 21: sprintf(retMsg,"Downsampling factor not supported");break; case 22: sprintf(retMsg,"Not enough memory");break; case 23: sprintf(retMsg,"Bad restart marker");break; case 24: sprintf(retMsg,"Decoding error");break; case 25: sprintf(retMsg,"Component info missing");break; case 26: sprintf(retMsg,"Progressive format not supported");break; case 27: sprintf(retMsg,"YH2V1 format not supported");break; case 28: sprintf(retMsg,"YH1V2 format not supported");break; } return retMsg; } #define ERROR(code) if(code<0) {jpeg_decoder_free(&decoder);if(bs) delete bs;return code;} #define CHECK_ERR(code) if(code<0) return code; // ------------------------------------------------------------------ static int jpeg_read_soi_marker(InputBitStream *bs) { int lastchar, thischar; int bytesleft; lastchar = bs->get_byte(); thischar = bs->get_byte(); if ((lastchar == 0xFF) && (thischar == M_SOI)) return 0; bytesleft = 512; while(1) { if (--bytesleft == 0) return -1; lastchar = thischar; thischar = bs->get_byte(); if ((lastchar == 0xFF) && (thischar == M_SOI)) break; } return 0; } // ------------------------------------------------------------------ int jpeg_next_marker(InputBitStream *bs) { int c,count=0; do { do { c = bs->get_byte(); count++; } while ( (c!=0xFF) && (count<1024) ); if( count>=1024 ) return 0; do { c = bs->get_byte(); } while (c == 0xFF); } while (c==0); return c; } // ------------------------------------------------------------------ int jpeg_skip_marker(InputBitStream *bs) { int left; left = (bs->get_byte() << 8) | bs->get_byte(); if (left < 2) return -8; left -= 2; while (left) { bs->get_byte(); left--; } return 0; } // ------------------------------------------------------------------ int jpeg_read_dqt_marker(JPGDECODER *decoder,InputBitStream *bs) { int n, i, prec; int left; int temp; left = (bs->get_byte() << 8) | bs->get_byte(); if (left < 2) return -5; left -= 2; while (left) { n = bs->get_byte(); prec = n >> 4; n &= 0x0F; if (n >= 4) return -6; if( !decoder->qTables[n] ) decoder->qTables[n] = (short *)malloc_16(64*2); // read quantization entries, in zag order for (i = 0; i < 64; i++) { temp = bs->get_byte(); if (prec) temp = (temp << 8) + bs->get_byte(); decoder->qTables[n][i] = (short)temp; } i = 64 + 1; if (prec) i += 64; if (left < i) return -7; left -= i; } return 0; } // ------------------------------------------------------------------ int jpeg_read_dht_marker(JPGDECODER *decoder,InputBitStream *bs) { int i, index, count, p, l, si; int left; int huff_num[17]; int huff_val[256]; int huffsize[257]; int huffcode[257]; int code; int subtree; int code_size; int lastp; int nextfreeentry; int currententry; left = (bs->get_byte() << 8) | bs->get_byte(); if (left < 2) return -9; left -= 2; while (left) { memset(huff_num,0,17*sizeof(int)); memset(huff_val,0,256*sizeof(int)); memset(huffsize,0,257*sizeof(int)); memset(huffcode,0,257*sizeof(int)); // Read a Huffman table index = bs->get_byte(); huff_num[0] = 0; count = 0; for (i = 1; i <= 16; i++) { huff_num[i] = bs->get_byte(); count += huff_num[i]; } if (count > 255) return -10; for (i = 0; i < count; i++) huff_val[i] = bs->get_byte(); i = 1 + 16 + count; if (left < i) return -9; left -= i; if ((index & 0x10) > 0x10) return -11; index = (index & 0x0F) + ((index & 0x10) >> 4) * 4; if (index >= 8) return -11; // Initialise huffman tree (fast decoding) HUFFMANTABLE *hs = &(decoder->hTables[index]); p = 0; for (l = 1; l <= 16; l++) { for (i = 1; i <= huff_num[l]; i++) huffsize[p++] = l; } lastp = p; code = 0; si = huffsize[0]; p = 0; while (huffsize[p]) { while (huffsize[p] == si) { huffcode[p++] = code; code++; } code <<= 1; si++; } nextfreeentry = -1; p = 0; while (p < lastp) { i = huff_val[p]; code = huffcode[p]; code_size = huffsize[p]; hs->huffSize[i] = code_size; if (code_size <= 8) { code <<= (8 - code_size); for (l = 1 << (8 - code_size); l > 0; l--) { hs->lookUp[code] = i; code++; } } else { subtree = (code >> (code_size - 8)) & 0xFF; currententry = hs->lookUp[subtree]; if (currententry == 0) { hs->lookUp[subtree] = currententry = nextfreeentry; nextfreeentry -= 2; } code <<= (16 - (code_size - 8)); for (l = code_size; l > 9; l--) { if ((code & 0x8000) == 0) currententry--; if (hs->tree[-currententry - 1] == 0) { hs->tree[-currententry - 1] = nextfreeentry; currententry = nextfreeentry; nextfreeentry -= 2; } else { currententry = hs->tree[-currententry - 1]; } code <<= 1; } if ((code & 0x8000) == 0) currententry--; hs->tree[-currententry - 1] = i; } p++; } hs->inited = 1; } return 0; } // ------------------------------------------------------------------ int jpeg_read_sos_marker(JPGDECODER *decoder,InputBitStream *bs) { int left; int i,cId,hId,n; left = (bs->get_byte() << 8) | bs->get_byte(); n = bs->get_byte(); decoder->compInScan = n; left -= 3; if ((left != (n*2 + 3)) || (n < 1) || (n > 4) ) return -12; for (i = 0; i < n; i++) { cId = bs->get_byte(); hId = bs->get_byte(); left -= 2; if (cId > 4) return -13; decoder->comps[cId].dcIdx = (hId >> 4) & 15; decoder->comps[cId].acIdx = (hId & 15) + 4; } bs->get_byte(); // spectral_start bs->get_byte(); // spectral_end bs->get_byte(); // successive app. low,high left -= 3; while (left) { bs->get_byte(); left--; } return 0; } // ------------------------------------------------------------------ int jpeg_read_sof_marker(JPGDECODER *decoder,InputBitStream *bs) { int i; int left; left = (bs->get_byte() << 8) | bs->get_byte(); if (bs->get_byte() != 8) return -14; decoder->height = (bs->get_byte() << 8) | bs->get_byte(); decoder->width = (bs->get_byte() << 8) | bs->get_byte(); if ((decoder->height < 1) || (decoder->height > 8192)) return -15; if ((decoder->width < 1) || (decoder->width > 8192)) return -15; decoder->compNb = bs->get_byte(); if (decoder->compNb > 4) return -16; if (left != (decoder->compNb * 3 + 8)) return -17; for (i = 0; i < decoder->compNb; i++) { int compId = bs->get_byte(); if( compId>4 ) return -13; decoder->comps[compId].id = compId; int samp = bs->get_byte(); decoder->comps[compId].horzSampling = samp >> 4; decoder->comps[compId].vertSampling = samp & 0xF; decoder->comps[compId].quantIdx = bs->get_byte(); } return 0; } // ------------------------------------------------------------------ int jpeg_read_dri_marker(JPGDECODER *decoder,InputBitStream *bs) { int left = (bs->get_byte() << 8) | bs->get_byte(); if (left != 4) return -18; decoder->restartInterval = (bs->get_byte() << 8) | bs->get_byte(); if (decoder->restartInterval) { decoder->restartsLeft = decoder->restartInterval; decoder->nextRestart = 0; } return 0; } // ------------------------------------------------------------------ int jpeg_process_marker(JPGDECODER *decoder,InputBitStream *bs) { int m,err; while(1) { m = jpeg_next_marker(bs); switch (m) { case 0: return -4; // Marker not found case M_SOF0: case M_SOF1: err=jpeg_read_sof_marker(decoder,bs);CHECK_ERR(err); break; case M_SOS: err=jpeg_read_sos_marker(decoder,bs);CHECK_ERR(err); return 0; case M_DHT: err=jpeg_read_dht_marker(decoder,bs);CHECK_ERR(err); break; case M_DQT: err=jpeg_read_dqt_marker(decoder,bs);CHECK_ERR(err); break; case M_DRI: err=jpeg_read_dri_marker(decoder,bs);CHECK_ERR(err); break; case M_JPG: case M_RST0: case M_RST1: case M_RST2: case M_RST3: case M_RST4: case M_RST5: case M_RST6: case M_RST7: case M_SOI: return -3; case M_SOF2: return -26; case M_TEM: case M_SOF3: case M_SOF5: case M_SOF6: case M_SOF7: case M_SOF9: case M_SOF10: case M_SOF11: case M_SOF13: case M_SOF14: case M_SOF15: return -2; case M_EOI: break; default: { err=jpeg_skip_marker(bs);CHECK_ERR(err); break; } } } } // ------------------------------------------------------------------ int jpeg_read_restart_marker(JPGDECODER *decoder,InputBitStream *bs) { unsigned char c; bs->align(); // Is it the expected marker? If not, something bad happened. c=bs->get_bits(8); if( c!=0xFF ) return -23; c=bs->get_bits(8); if (c != (decoder->nextRestart + M_RST0)) return -23; // Reset each component's DC prediction values. for(int i=0;i<4;i++) decoder->comps[i].lastDc = 0; decoder->restartsLeft = decoder->restartInterval; decoder->nextRestart = (decoder->nextRestart + 1) & 7; return 0; } // ------------------------------------------------------------------ int jpeg_decoder_init(JPGDECODER *decoder) { if( decoder->compNb!=3 && decoder->compNb!=1 ) return -2; if( decoder->compInScan != decoder->compNb ) return -2; // Check tables for(int i=0;i<4;i++) { int id = decoder->comps[i].id; if(id>=0) { int qIx = decoder->comps[i].quantIdx; if( !decoder->qTables[qIx] ) return -19; int dcIdx = decoder->comps[i].dcIdx; if( !decoder->hTables[dcIdx].inited ) return -20; int acIdx = decoder->comps[i].acIdx; if( !decoder->hTables[acIdx].inited ) return -20; } } // Check comp int found=0;int fComp=0; while(!found && fComp<4) { found = (decoder->comps[fComp].id!=-100); if(!found) fComp++; } if(!found) return -25; // Init scan type if (decoder->compNb == 1) { decoder->scanType = JPG_SCAN_GRAYSCALE; decoder->outFormat = JPEG_GRAY_FORMAT; // Output format decoder->mcuNbBlock = 1; decoder->compList[0] = fComp; decoder->mcuWidth = 8; decoder->mcuHeight = 8; } else if (decoder->compNb == 3) { if ( ((decoder->comps[2].horzSampling != 1) || (decoder->comps[2].vertSampling != 1)) || ((decoder->comps[3].horzSampling != 1) || (decoder->comps[3].vertSampling != 1)) ) return -21; if ((decoder->comps[1].horzSampling == 1) && (decoder->comps[1].vertSampling == 1)) { decoder->scanType = JPG_SCAN_YH1V1; decoder->outFormat = JPEG_RGB32_FORMAT; // Output format decoder->mcuNbBlock = 3; decoder->compList[0] = fComp; decoder->compList[1] = fComp+1; decoder->compList[2] = fComp+2; decoder->mcuWidth = 8; decoder->mcuHeight = 8; } else if ((decoder->comps[1].horzSampling == 2) && (decoder->comps[1].vertSampling == 1)) { //decoder->scanType = JPG_SCAN_YH2V1; //decoder->mcuNbBlock = 4; //decoder->compList[0] = fComp; //decoder->compList[1] = fComp; //decoder->compList[2] = fComp+1; //decoder->compList[3] = fComp+2; //decoder->mcuWidth = 16; //decoder->mcuHeight = 8; return -27; } else if ((decoder->comps[1].horzSampling == 1) && (decoder->comps[1].vertSampling == 2)) { //decoder->scanType = JPG_SCAN_YH1V2; //decoder->mcuNbBlock = 4; //decoder->compList[0] = fComp; //decoder->compList[1] = fComp; //decoder->compList[2] = fComp+1; //decoder->compList[3] = fComp+2; //decoder->mcuWidth = 8; //decoder->mcuHeight = 16; return -28; } else if ((decoder->comps[1].horzSampling == 2) && (decoder->comps[1].vertSampling == 2)) { decoder->scanType = JPG_SCAN_YH2V2; decoder->outFormat = JPEG_RGB32_FORMAT; // Output format decoder->mcuNbBlock = 6; decoder->compList[0] = fComp; decoder->compList[1] = fComp; decoder->compList[2] = fComp; decoder->compList[3] = fComp; decoder->compList[4] = fComp+1; decoder->compList[5] = fComp+2; decoder->mcuWidth = 16; decoder->mcuHeight = 16; } else return -21; } decoder->mcuNbRow = (decoder->width + (decoder->mcuWidth - 1)) / decoder->mcuWidth; decoder->mcuNbCol = (decoder->height + (decoder->mcuHeight - 1)) / decoder->mcuHeight; return 0; } // ------------------------------------------------------------------ void jpeg_decoder_free(JPGDECODER *decoder) { for(int i=0;i<4;i++) if( decoder->qTables[i] ) free_16(decoder->qTables[i]); if( decoder->blocks ) free_16( decoder->blocks ); if( decoder->yccFrame ) free_16( decoder->yccFrame ); if( decoder->rgbFrame ) free_16( decoder->rgbFrame ); } // ------------------------------------------------------------------ int jpeg_decode(int jpegSize,unsigned char *jpegData, int *width,int *height,int *format,unsigned char **frame) { int errCode = 0; JPGDECODER decoder; memset(&decoder,0,sizeof(JPGDECODER)); for(int i=0;i<4;i++) decoder.comps[i].id = -100; InputBitStream *bs = new InputBitStream(jpegData,jpegSize); jpeg_init_color(); // Header errCode = jpeg_read_soi_marker(bs);ERROR(errCode); errCode = jpeg_process_marker(&decoder,bs);ERROR(errCode); errCode = jpeg_decoder_init(&decoder);ERROR(errCode); // int nbMCU = decoder.mcuNbCol * decoder.mcuNbRow; int rWidth = decoder.mcuNbRow * decoder.mcuWidth; int rHeight = decoder.mcuNbCol * decoder.mcuHeight; int mcuSize = decoder.mcuNbBlock*64; decoder.blocks = (short *)malloc_16(mcuSize*2); decoder.yccFrame = (unsigned char *)malloc_16(mcuSize); if( decoder.scanType==JPG_SCAN_GRAYSCALE ) decoder.rgbFrame = (unsigned char *)malloc_16(rWidth*rHeight); else decoder.rgbFrame = (unsigned char *)malloc_16(rWidth*rHeight*4); if(!decoder.rgbFrame) ERROR(-22); // Decode blocks bs->init(); for(int j=0;jdecode_mcu(&decoder); ERROR(errCode); // Convert to RGB int rgbOffset; switch( decoder.scanType ) { case JPG_SCAN_YH2V2: rgbOffset = (i*decoder.mcuWidth + j*decoder.mcuHeight*rWidth) << 2; #ifdef JPG_USE_ASM jpeg_yh2v2_to_rgb32_mmx(decoder.yccFrame,(long)rWidth,decoder.rgbFrame+rgbOffset); #else jpeg_yh2v2_to_rgb32(decoder.yccFrame,rWidth,decoder.rgbFrame+rgbOffset); #endif break; case JPG_SCAN_YH1V1: rgbOffset = (i*decoder.mcuWidth + j*decoder.mcuHeight*rWidth) << 2; #ifdef JPG_USE_ASM jpeg_yh1v1_to_rgb32_mmx(decoder.yccFrame,(long)rWidth,decoder.rgbFrame+rgbOffset); #else jpeg_yh1v1_to_rgb32(decoder.yccFrame,rWidth,decoder.rgbFrame+rgbOffset); #endif break; case JPG_SCAN_GRAYSCALE: rgbOffset = (i*decoder.mcuWidth + j*decoder.mcuHeight*rWidth); jpeg_y_to_gray(decoder.yccFrame,rWidth,decoder.rgbFrame+rgbOffset); break; } } } bs->flush(); #ifdef JPG_USE_ASM #ifdef _WINDOWS __asm emms; #else __asm__ ("emms\n"::); #endif #endif // Clip and Copy frame int rPitch; int rowSize; *width = decoder.width; *height = decoder.height; *format = decoder.outFormat; if( decoder.scanType==JPG_SCAN_GRAYSCALE ) { *frame = new unsigned char[decoder.width*decoder.height]; rPitch = rWidth; rowSize = decoder.width; } else { *frame = new unsigned char[decoder.width*decoder.height*4]; rPitch = rWidth * 4; rowSize = decoder.width * 4; } if(!*frame) ERROR(-22); unsigned char *src = decoder.rgbFrame; unsigned char *dest = *frame; for(int y=0;y. // // $Revision: 27410 $ // // $Log$ // Revision 1.3 2009/09/08 14:23:16 taurel // - No real change, just to make CVS quiet // // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= // // File: jpeg_encoder.cpp // Description: Main encoding functions // Program: Simple jpeg coding/decoding library // Author: JL Pons 2009 // #include #include #include #include "jpeg_lib.h" #include "jpeg_const.h" #include "jpeg_memory.h" #include "jpeg_bitstream.h" /* These are the sample quantization tables given in JPEG spec section K.1. * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ static double std_luminance_quant_tbl[] = { 16.0, 11.0, 10.0, 16.0, 24.0, 40.0, 51.0, 61.0, 12.0, 12.0, 14.0, 19.0, 26.0, 58.0, 60.0, 55.0, 14.0, 13.0, 16.0, 24.0, 40.0, 57.0, 69.0, 56.0, 14.0, 17.0, 22.0, 29.0, 51.0, 87.0, 80.0, 62.0, 18.0, 22.0, 37.0, 56.0, 68.0, 109.0, 103.0, 77.0, 24.0, 35.0, 55.0, 64.0, 81.0, 104.0, 113.0, 92.0, 49.0, 64.0, 78.0, 87.0, 103.0, 121.0, 120.0, 101.0, 72.0, 92.0, 95.0, 98.0, 112.0, 100.0, 103.0, 99.0 }; static double std_chrominance_quant_tbl[] = { 17.0, 18.0, 24.0, 47.0, 99.0, 99.0, 99.0, 99.0, 18.0, 21.0, 26.0, 66.0, 99.0, 99.0, 99.0, 99.0, 24.0, 26.0, 56.0, 99.0, 99.0, 99.0, 99.0, 99.0, 47.0, 66.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0, 99.0 }; // Zig zag order int jpgZag[64] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, }; // Default Huffman table static unsigned char bits_dc_luminance[17] = { 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char val_dc_luminance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static unsigned char bits_dc_chrominance[17] = { 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; //static unsigned char val_dc_chrominance[] = // { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static unsigned char bits_ac_luminance[17] = { 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; static unsigned char val_ac_luminance[] = { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa }; static unsigned char bits_ac_chrominance[17] = { 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; /*static unsigned char val_ac_chrominance[] = { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };*/ // color conversion declaration (jpeg_color.cpp) void jpeg_init_color(); void jpeg_rgb32_to_ycc(int width,int height,int outWidth,int outHeight,unsigned char *rgb32,short *ycc); void jpeg_rgb24_to_ycc(int width,int height,int outWidth,int outHeight,unsigned char *rgb32,short *ycc); void jpeg_gray8_to_y(int width,int height,int outWidth,int outHeight,unsigned char *gray8,short *y); // Forward dct (jpeg_dct.cpp) void jpeg_fdct(short *block); void jpeg_fdct_mmx(short *block); // ---------------------------------------------------------------- // Start of Image marker static void jpeg_write_SOI(OutputBitStream *bs) { bs->put_byte(0xFF); bs->put_byte(M_SOI); } static void jpeg_write_EOI(OutputBitStream *bs) { bs->put_byte(0xFF); bs->put_byte(M_EOI); } // ---------------------------------------------------------------- // Quantization table static void jpeg_write_DQT(OutputBitStream *bs,short *qTable,int tableId,int prec) { int mSize; bs->put_byte(0xFF); bs->put_byte(M_DQT); if( prec ) mSize = 64*2 + 1 + 2; else mSize = 64 + 1 + 2; bs->put_short( mSize ); bs->put_byte( (prec<<4) + tableId ); for (int i=0;i<64;i++) { unsigned short val = (qTable[jpgZag[i]] >> 3); if (prec) bs->put_byte( val>>8 ); bs->put_byte( val & 0xFF ); } } // ---------------------------------------------------------------- static void jpeg_scale_qtable(double quality,double *qTable,short *out,int *prec) { // Set up quality 1->poor, 100->max // This model gives approximately a linear increase of the file size // according to the quality value. When quality is set to 100.0, all // quatization values are set to 1 => No loss due to quatization. double qualityFactor = 0.01; if( quality<1.0 ) quality=1.0; if( quality>100.0 ) quality=100.0; if( quality<100.0 ) qualityFactor = - 0.1/log( 1.0 - (quality/100.0) ); *prec = 0; for(int i=0;i<64;i++) { short val = (short)( qTable[i]*qualityFactor + 0.5 ); if( val<1 ) val = 1; if( val>255 ) *prec=1; out[i] = val << 3; // *8 for DCT scaling } } // ---------------------------------------------------------------- static void jpeg_init_htable(HUFFMANTABLE *table,unsigned char *bits,unsigned char *vals) { int p, i, l, lastp, si; char huffsize[257]; unsigned int huffcode[257]; unsigned int code; // Does not perform checks (encoding phase with valid tables) table->huffBits = bits; table->huffVal = vals; p = 0; for (l = 1; l <= 16; l++) { i = (int) bits[l]; while (i--) huffsize[p++] = (char) l; } huffsize[p] = 0; lastp = p; code = 0; si = huffsize[0]; p = 0; while (huffsize[p]) { while (((int) huffsize[p]) == si) { huffcode[p++] = code; code++; } code <<= 1; si++; } memset(table->huffSize,0,256); for (p = 0; p < lastp; p++) { i = vals[p]; table->huffCode[i] = huffcode[p]; table->huffSize[i] = huffsize[p]; } } // ---------------------------------------------------------------- static void jpeg_write_DHT(OutputBitStream *bs,HUFFMANTABLE *table,int tableId) { int mSize; int lgth = 0; bs->put_byte(0xFF); bs->put_byte(M_DHT); for (int i=1;i<=16;i++) lgth += table->huffBits[i]; mSize = lgth + 2 + 1 + 16; bs->put_short( mSize ); bs->put_byte( tableId ); for (int i=1;i<=16;i++) bs->put_byte(table->huffBits[i]); for (int i=0;iput_byte(table->huffVal[i]); } // ---------------------------------------------------------------- static void jpeg_write_SOF(OutputBitStream *bs,int width,int height,JPGCOMPONENT *comps,int nbComp) { int mSize = 3 * nbComp + 2 + 5 + 1; bs->put_byte(0xFF); bs->put_byte(M_SOF1); bs->put_short( mSize ); bs->put_byte( 8 ); // Precision bs->put_short(height); bs->put_short(width); bs->put_byte(nbComp); for (int i=0;iput_byte(comps[i].id); bs->put_byte((comps[i].horzSampling << 4) + comps[i].vertSampling); bs->put_byte(comps[i].quantIdx); } } // ---------------------------------------------------------------- static void jpeg_write_SOS(OutputBitStream *bs,JPGCOMPONENT *comps,int nbComp) { int mSize = 2 * nbComp + 2 + 1 + 3; bs->put_byte(0xFF); bs->put_byte(M_SOS); bs->put_short( mSize ); bs->put_byte(nbComp); for (int i=0;iput_byte(comps[i].id); bs->put_byte((comps[i].dcIdx << 4) + comps[i].acIdx); } bs->put_byte(0); // Spectral start (progressive only) bs->put_byte(63); // Spectral end (progressive only) bs->put_byte(0); // Successive approx. high,low (progressive only) } // ---------------------------------------------------------------- static void jpeg_quantize_block(short *blocks,unsigned short *qDiv) { //#ifdef JPG_USE_ASM #if 0 short mmRound[] = { 0x7FFF,0x7FFF,0,0 }; short mmOne[] = { 1,1,0,0 }; _asm { mov edi,blocks mov esi,qDiv movq mm0,mmRound movq mm1,mmOne mov ecx,8 _sseqrows: movd mm2,[edi] movd mm4,[edi+4] movd mm3,[esi] movd mm5,[esi+4] punpcklwd mm2,mm0 punpcklwd mm3,mm1 punpcklwd mm4,mm0 punpcklwd mm5,mm1 pmaddwd mm2,mm3 pmaddwd mm4,mm5 pshufw mm6,mm2,141 pshufw mm7,mm4,141 movd [edi],mm6 movd [edi+4],mm7 movd mm2,[edi+8] movd mm4,[edi+12] movd mm3,[esi+8] movd mm5,[esi+12] punpcklwd mm2,mm0 punpcklwd mm3,mm1 punpcklwd mm4,mm0 punpcklwd mm5,mm1 pmaddwd mm2,mm3 pmaddwd mm4,mm5 pshufw mm6,mm2,141 pshufw mm7,mm4,141 movd [edi+8],mm6 movd [edi+12],mm7 add edi,16 add esi,16 dec ecx jnz _sseqrows emms } #else int val; for(int i=0;i<64;i++) { val = (int)blocks[i]; val *= (int)qDiv[i]; val += 32767; // round val >>= 16; blocks[i] = val; } #endif } // ---------------------------------------------------------------- static void jpeg_encode_rgb(int width,int height,unsigned char *rgb,double quality, int *jpegSize,unsigned char **jpegData,int rgbW) { short lumQuant[64]; // Luminance quantization table short chrQuant[64]; // Chrominance quantization table unsigned short *lumDiv; // Luminance quantization table divisor unsigned short *chrDiv; // Chrominance quantization table divisor JPGCOMPONENT comps[3]; // Components YCbCr HUFFMANTABLE hTables[4]; // Huffman tables int prec; int rWidth = ((width +15)>>4) * 16; int rHeight = ((height+15)>>4) * 16; OutputBitStream *bs = new OutputBitStream(); // Header jpeg_write_SOI(bs); // Quatization tables jpeg_scale_qtable(quality,std_luminance_quant_tbl,lumQuant,&prec); jpeg_scale_qtable(quality,std_chrominance_quant_tbl,chrQuant,&prec); jpeg_write_DQT(bs,lumQuant,0,prec); jpeg_write_DQT(bs,chrQuant,1,prec); // Huffman tables jpeg_init_htable(hTables+0,bits_dc_luminance,val_dc_luminance); jpeg_init_htable(hTables+1,bits_ac_luminance,val_ac_luminance); jpeg_init_htable(hTables+2,bits_dc_chrominance,val_dc_luminance); jpeg_init_htable(hTables+3,bits_ac_chrominance,val_ac_luminance); jpeg_write_DHT(bs,hTables+0,0); jpeg_write_DHT(bs,hTables+1,0+0x10); jpeg_write_DHT(bs,hTables+2,1); jpeg_write_DHT(bs,hTables+3,1+0x10); // Luminance component (Y) comps[0].horzSampling = 2; comps[0].vertSampling = 2; comps[0].id = 1; comps[0].quantIdx = 0; comps[0].dcIdx = 0; comps[0].acIdx = 0; comps[0].lastDc = 0; // Chrominance component (Cb) comps[1].horzSampling = 1; comps[1].vertSampling = 1; comps[1].id = 2; comps[1].quantIdx = 1; comps[1].dcIdx = 1; comps[1].acIdx = 1; comps[1].lastDc = 0; // Chrominance component (Cr) comps[2].horzSampling = 1; comps[2].vertSampling = 1; comps[2].id = 3; comps[2].quantIdx = 1; comps[2].dcIdx = 1; comps[2].acIdx = 1; comps[2].lastDc = 0; jpeg_write_SOF(bs,width,height,comps,3); jpeg_write_SOS(bs,comps,3); // Initialise quantization divisor lumDiv = (unsigned short *)malloc_16(64*2); chrDiv = (unsigned short *)malloc_16(64*2); for(int i=0;i<64;i++) { lumDiv[i] = (unsigned short)( 65536.0/(double)lumQuant[i] + 0.5 ); chrDiv[i] = (unsigned short)( 65536.0/(double)chrQuant[i] + 0.5 ); } // Convert to YUV jpeg_init_color(); short *ycc = (short *)malloc_16(rWidth*rHeight*3); if( rgbW==24 ) jpeg_rgb24_to_ycc(width,height,rWidth,rHeight,rgb,ycc); else jpeg_rgb32_to_ycc(width,height,rWidth,rHeight,rgb,ycc); // Encode blocks (downsampling :2 for Cb and Cr) int nbMCU = rWidth/16 * rHeight/16; short *block = ycc; for(int i=0;iinit(); for(int i=0;iencode_block(block+0 ,hTables+0,hTables+1,&(comps[0].lastDc)); bs->encode_block(block+64 ,hTables+0,hTables+1,&(comps[0].lastDc)); bs->encode_block(block+128,hTables+0,hTables+1,&(comps[0].lastDc)); bs->encode_block(block+192,hTables+0,hTables+1,&(comps[0].lastDc)); // Chrominance bs->encode_block(block+256,hTables+2,hTables+3,&(comps[1].lastDc)); bs->encode_block(block+320,hTables+2,hTables+3,&(comps[2].lastDc)); block+=384; } bs->flush(); jpeg_write_EOI(bs); free_16(ycc); free_16(lumDiv); free_16(chrDiv); *jpegData = (unsigned char *)malloc(bs->get_size()); *jpegSize = bs->get_size(); memcpy(*jpegData,bs->get_data(),bs->get_size()); delete bs; } // -------------------------------------------------------------------------- void jpeg_encode_rgb32(int width,int height,unsigned char *rgb32,double quality, int *jpegSize,unsigned char **jpegData) { jpeg_encode_rgb(width,height,rgb32,quality,jpegSize,jpegData,32); } void jpeg_encode_rgb24(int width,int height,unsigned char *rgb24,double quality, int *jpegSize,unsigned char **jpegData) { jpeg_encode_rgb(width,height,rgb24,quality,jpegSize,jpegData,24); } // -------------------------------------------------------------------------- void jpeg_encode_gray8(int width,int height,unsigned char *gray8,double quality, int *jpegSize,unsigned char **jpegData) { short lumQuant[64]; // Luminance quantization table unsigned short *lumDiv; // Luminance quantization table divisor JPGCOMPONENT comps[1]; // Component Y HUFFMANTABLE hTables[2]; // Huffman tables int prec; int rWidth = ((width +7)>>3) * 8; int rHeight = ((height+7)>>3) * 8; OutputBitStream *bs = new OutputBitStream(); // Header jpeg_write_SOI(bs); // Quatization tables jpeg_scale_qtable(quality,std_luminance_quant_tbl,lumQuant,&prec); jpeg_write_DQT(bs,lumQuant,0,prec); // Huffman tables jpeg_init_htable(hTables+0,bits_dc_luminance,val_dc_luminance); jpeg_init_htable(hTables+1,bits_ac_luminance,val_ac_luminance); jpeg_write_DHT(bs,hTables+0,0); jpeg_write_DHT(bs,hTables+1,0+0x10); // Luminance component (Y) comps[0].horzSampling = 1; comps[0].vertSampling = 1; comps[0].id = 1; comps[0].quantIdx = 0; comps[0].dcIdx = 0; comps[0].acIdx = 0; comps[0].lastDc = 0; jpeg_write_SOF(bs,width,height,comps,1); jpeg_write_SOS(bs,comps,1); // Initialise quantization divisor lumDiv = (unsigned short *)malloc_16(64*2); for(int i=0;i<64;i++) { lumDiv[i] = (unsigned short)( 65536.0/(double)lumQuant[i] + 0.5 ); } // Convert to YUV jpeg_init_color(); short *ycc = (short *)malloc_16(rWidth*rHeight*2); jpeg_gray8_to_y(width,height,rWidth,rHeight,gray8,ycc); // Encode blocks (downsampling :2 for Cb and Cr) int nbMCU = rWidth/8 * rHeight/8; short *block = ycc; for(int i=0;iinit(); for(int i=0;iencode_block(block,hTables+0,hTables+1,&(comps[0].lastDc)); block+=64; } bs->flush(); jpeg_write_EOI(bs); free_16(ycc); free_16(lumDiv); *jpegData = (unsigned char *)malloc(bs->get_size()); *jpegSize = bs->get_size(); memcpy(*jpegData,bs->get_data(),bs->get_size()); delete bs; } tango-9.2.5a/lib/cpp/server/jpeg/jpeg_memory.cpp0000644023471100065110000000724713034744776016563 00000000000000///============================================================================= // // file : jpeg_memory.cpp // // description : Simple jpeg coding/decoding library // Small memory manager (16 bytes aligned for MMX/SSE code) // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.4 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #include "jpeg_memory.h" #include #include #define MAX_BUFFER 50 typedef struct { void *buff; void *buff16; size_t size; } MEMORY_HEADER; static int nb_allocated = 0; static MEMORY_HEADER MemTable[MAX_BUFFER]; // Allocate a buffer (always 16 bytes aligned) void *malloc_16(size_t size) { void *mptr; void *mptr16; if( nb_allocated == MAX_BUFFER ) { printf("Warning: jpeg_memory number of buffer exeeded\n"); return NULL; } mptr = malloc(size+16); if( !mptr ) { printf("Warning: jpeg_memory not enough free memory\n"); return NULL; } MemTable[nb_allocated].buff=mptr; MemTable[nb_allocated].size=size; // Aligns memory block on 16byte mptr16 = ((void *)(((size_t)mptr + 15) & ~15)); MemTable[nb_allocated].buff16=mptr16; nb_allocated++; return mptr16; } // Allocate a buffer (always 16 bytes aligned) void *calloc_16(size_t count,size_t size) { void *mptr; void *mptr16; if( nb_allocated == MAX_BUFFER ) return NULL; mptr = malloc(size*count+16); if( !mptr ) return NULL; MemTable[nb_allocated].buff=mptr; MemTable[nb_allocated].size=size; // Aligns memory block on 16byte mptr16 = ((void *)(((size_t)mptr + 15) & ~15)); MemTable[nb_allocated].buff16=mptr16; nb_allocated++; return mptr16; } // Free a buffer void free_16( void *ptr ) { int i,found; if( ptr==NULL ) return; i=0;found=0; while(!found && i. // // $Revision: 27410 $ // // $Log$ // Revision 1.3 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #ifndef _JPEGBITSTREAMH_ #define _JPEGBITSTREAMH_ #include "jpeg_lib.h" #include "jpeg_const.h" #define BUFFER_SIZE 524288 // ------------------------------------------------------------ class OutputBitStream { public: OutputBitStream(); ~OutputBitStream(); void align(); void flush(); void init(); unsigned char *get_data(); unsigned long get_size(); void put_bits(int code,int _size); void put_byte(unsigned char code); void put_byteI(unsigned char code); void put_short(unsigned short code); void encode_block(short *block,HUFFMANTABLE *hDC,HUFFMANTABLE *hAC,short *lastDc); private: void more_byte(); void load_mm(); unsigned char *buffer; int nbByte; int buffSize; int nbBits; #ifdef _WINDOWS unsigned long bits; #else unsigned int bits; #endif unsigned char *bufferPtr; unsigned char *numbits; unsigned char bScratch[4]; }; // ------------------------------------------------------------ class InputBitStream { public: InputBitStream(unsigned char *buff,int buffSize); ~InputBitStream(); void align(); void flush(); void init(); int get_byte(); int backward(int l); int get_bits(int numbits); int decode_mcu(JPGDECODER *decoder); private: unsigned char *_buffer; int _buffSize; int _byteRead; int _nbBits; #ifdef _WINDOWS unsigned long _bits; #else unsigned int _bits; #endif unsigned char *_bufferPtr; }; #endif /* _JPEGBITSTREAMH_ */ tango-9.2.5a/lib/cpp/server/jpeg/jpeg_const.h0000644023471100065110000001123513034744776016036 00000000000000///============================================================================= // // file : jpeg_const.h // // description : Simple jpeg coding/decoding library // Various constants and internal type definitions // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #ifndef _JPEGCONSTH_ #define _JPEGCONSTH_ // Huffman table structure typedef struct { unsigned char *huffBits; // Number of Huffman codes per bit size unsigned char *huffVal; // Huffman codes per bit size unsigned char huffSize[256]; // Huffman codes size unsigned int huffCode[256]; // Huffman codes unsigned int lookUp[256]; // look up table (decoding purpose) unsigned int tree[512]; // Huffman tree (decoding purpose) int inited; // Initialisation flag (decoding purpose) } HUFFMANTABLE; // Components structure typedef struct { int id; // Identifier int horzSampling; // Horizontal sampling factor int vertSampling; // Vertical sampling factor int quantIdx; // Quantization table index int dcIdx; // Huffman table DC index int acIdx; // Huffman table AC index short lastDc; // Last DC value } JPGCOMPONENT; // Decoder structure typedef struct { int width; // Image width int height; // Image height int scanType; // Type of scan int outFormat; // Output format int compNb; // Number of component (frame) int compInScan; // Number of component (scan) int mcuWidth; // MCU width int mcuHeight; // MCU height int mcuNbBlock; // Number of block per MCU (total) int mcuNbRow; // Number of MCU per row int mcuNbCol; // Number of MCU per col int restartInterval; // Restart interval int restartsLeft; // Number of MCU between DRI marker int nextRestart; // Next RST marker code int compList[6]; // List of component (scan) HUFFMANTABLE hTables[8]; // Huffman tables short *qTables[4]; // Quantization tables JPGCOMPONENT comps[4]; // Components short *blocks; // Blocks unsigned char *yccFrame; // Decoded frame (RGB24 or GRAY8) unsigned char *rgbFrame; // Decoded frame (RGB24 or GRAY8) } JPGDECODER; // JPEG scan type #define JPG_SCAN_GRAYSCALE 0 #define JPG_SCAN_YH1V1 1 #define JPG_SCAN_YH2V1 2 #define JPG_SCAN_YH1V2 3 #define JPG_SCAN_YH2V2 4 // JPEG marker codes #define M_SOF0 0xc0 #define M_SOF1 0xc1 #define M_SOF2 0xc2 #define M_SOF3 0xc3 #define M_SOF5 0xc5 #define M_SOF6 0xc6 #define M_SOF7 0xc7 #define M_JPG 0xc8 #define M_SOF9 0xc9 #define M_SOF10 0xca #define M_SOF11 0xcb #define M_SOF13 0xcd #define M_SOF14 0xce #define M_SOF15 0xcf #define M_DHT 0xc4 #define M_DAC 0xcc #define M_RST0 0xd0 #define M_RST1 0xd1 #define M_RST2 0xd2 #define M_RST3 0xd3 #define M_RST4 0xd4 #define M_RST5 0xd5 #define M_RST6 0xd6 #define M_RST7 0xd7 #define M_SOI 0xd8 #define M_EOI 0xd9 #define M_SOS 0xda #define M_DQT 0xdb #define M_DNL 0xdc #define M_DRI 0xdd #define M_DHP 0xde #define M_EXP 0xdf #define M_APP0 0xe0 #define M_APP1 0xe1 #define M_APP2 0xe2 #define M_APP3 0xe3 #define M_APP4 0xe4 #define M_APP5 0xe5 #define M_APP6 0xe6 #define M_APP7 0xe7 #define M_APP8 0xe8 #define M_APP9 0xe9 #define M_APP10 0xea #define M_APP11 0xeb #define M_APP12 0xec #define M_APP13 0xed #define M_APP14 0xee #define M_APP15 0xef #define M_JPG0 0xf0 #define M_JPG13 0xfd #define M_COM 0xfe #define M_TEM 0x01 #endif /* _JPEGCONSTH_ */ tango-9.2.5a/lib/cpp/server/jpeg/jpeg_lib.h0000644023471100065110000000561413034744776015462 00000000000000///============================================================================= // // file : jpeg_lib.h // // description : Simple jpeg coding/decoding library // MMX optimisation supported for both Visual C++ and gcc // Main library header file // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #ifndef _JPEGLIBH_ #define _JPEGLIBH_ // ---------------------------------------------------------------------------- // Encode a RGB image to a buffer // quality ranges in 0(poor), 100(max) // jpegData is allocated by the function and must be freed by the caller. // ---------------------------------------------------------------------------- void jpeg_encode_rgb32(int width,int height,unsigned char *rgb32, double quality,int *jpegSize,unsigned char **jpegData); void jpeg_encode_rgb24(int width,int height,unsigned char *rgb24, double quality,int *jpegSize,unsigned char **jpegData); void jpeg_encode_gray8(int width,int height,unsigned char *gray8, double quality,int *jpegSize,unsigned char **jpegData); // ---------------------------------------------------------------------------- // Decode a JPEG image and return error code in case of failure, 0 is returned // otherwise. frame is a pointer to a set of 8bit sample (8bit gray scale or // 32bit rgb format) which is allocated by the function and must be freed by // the caller. // ---------------------------------------------------------------------------- #define JPEG_GRAY_FORMAT 0 #define JPEG_RGB32_FORMAT 1 int jpeg_decode(int jpegSize,unsigned char *jpegData, int *width,int *height,int *format,unsigned char **frame); // Return error message char *jpeg_get_error_msg(int code); #endif /* _JPEGLIBH_ */ tango-9.2.5a/lib/cpp/server/jpeg/jpeg_memory.h0000644023471100065110000000356213034744776016224 00000000000000///============================================================================= // // file : jpeg_memory.h // // description : Simple jpeg coding/decoding library // Small memory manager (16 bytes aligned for MMX/SSE code) // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.2 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= #ifndef _JPEGMEMORYH_ #define _JPEGMEMORYH_ #include // Allocate a buffer (aligned on 16 bytes boundary) void *malloc_16(size_t size); // Allocate a buffer (aligned on 16 bytes boundary) void *calloc_16(size_t count,size_t size); // Free a buffer void free_16(void *ptr); // Free all allocated buffer void free_all_16(); //Return the size of a buffer previoulsy allocated by malloc_16 size_t _msize_16( void *ptr ); #endif /* _JPEGMEMORYH_ */ tango-9.2.5a/lib/cpp/server/jpeg_mmx/0000755023471100065110000000000013034745257014464 500000000000000tango-9.2.5a/lib/cpp/server/jpeg_mmx/Makefile.am0000644023471100065110000000134313034744777016447 00000000000000 # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/server/jpeg \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libjpeg_mmx.la libjpeg_mmx_la_CXXFLAGS=@JPEG_MMX_LIB_CXXFLAGS@ -O0 # These are the sources for the library. libjpeg_mmx_la_SOURCES = jpeg_color_mmx.cpp \ jpeg_dct_mmx.cpp tango-9.2.5a/lib/cpp/server/jpeg_mmx/Makefile.in0000644023471100065110000005335713034745122016455 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/server/jpeg_mmx DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libjpeg_mmx_la_LIBADD = am_libjpeg_mmx_la_OBJECTS = libjpeg_mmx_la-jpeg_color_mmx.lo \ libjpeg_mmx_la-jpeg_dct_mmx.lo libjpeg_mmx_la_OBJECTS = $(am_libjpeg_mmx_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libjpeg_mmx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libjpeg_mmx_la_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libjpeg_mmx_la_SOURCES) DIST_SOURCES = $(libjpeg_mmx_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/server/jpeg \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libjpeg_mmx.la libjpeg_mmx_la_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ -O0 # These are the sources for the library. libjpeg_mmx_la_SOURCES = jpeg_color_mmx.cpp \ jpeg_dct_mmx.cpp all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/server/jpeg_mmx/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/server/jpeg_mmx/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libjpeg_mmx.la: $(libjpeg_mmx_la_OBJECTS) $(libjpeg_mmx_la_DEPENDENCIES) $(EXTRA_libjpeg_mmx_la_DEPENDENCIES) $(AM_V_CXXLD)$(libjpeg_mmx_la_LINK) $(libjpeg_mmx_la_OBJECTS) $(libjpeg_mmx_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libjpeg_mmx_la-jpeg_color_mmx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libjpeg_mmx_la-jpeg_dct_mmx.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< libjpeg_mmx_la-jpeg_color_mmx.lo: jpeg_color_mmx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libjpeg_mmx_la_CXXFLAGS) $(CXXFLAGS) -MT libjpeg_mmx_la-jpeg_color_mmx.lo -MD -MP -MF $(DEPDIR)/libjpeg_mmx_la-jpeg_color_mmx.Tpo -c -o libjpeg_mmx_la-jpeg_color_mmx.lo `test -f 'jpeg_color_mmx.cpp' || echo '$(srcdir)/'`jpeg_color_mmx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libjpeg_mmx_la-jpeg_color_mmx.Tpo $(DEPDIR)/libjpeg_mmx_la-jpeg_color_mmx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='jpeg_color_mmx.cpp' object='libjpeg_mmx_la-jpeg_color_mmx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libjpeg_mmx_la_CXXFLAGS) $(CXXFLAGS) -c -o libjpeg_mmx_la-jpeg_color_mmx.lo `test -f 'jpeg_color_mmx.cpp' || echo '$(srcdir)/'`jpeg_color_mmx.cpp libjpeg_mmx_la-jpeg_dct_mmx.lo: jpeg_dct_mmx.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libjpeg_mmx_la_CXXFLAGS) $(CXXFLAGS) -MT libjpeg_mmx_la-jpeg_dct_mmx.lo -MD -MP -MF $(DEPDIR)/libjpeg_mmx_la-jpeg_dct_mmx.Tpo -c -o libjpeg_mmx_la-jpeg_dct_mmx.lo `test -f 'jpeg_dct_mmx.cpp' || echo '$(srcdir)/'`jpeg_dct_mmx.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libjpeg_mmx_la-jpeg_dct_mmx.Tpo $(DEPDIR)/libjpeg_mmx_la-jpeg_dct_mmx.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='jpeg_dct_mmx.cpp' object='libjpeg_mmx_la-jpeg_dct_mmx.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libjpeg_mmx_la_CXXFLAGS) $(CXXFLAGS) -c -o libjpeg_mmx_la-jpeg_dct_mmx.lo `test -f 'jpeg_dct_mmx.cpp' || echo '$(srcdir)/'`jpeg_dct_mmx.cpp mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/server/jpeg_mmx/jpeg_color_mmx.cpp0000644023471100065110000013002313034744777020121 00000000000000///============================================================================= // // file : jpeg_color_mmx.cpp // // description : Simple jpeg coding/decoding library // Color space conversion (MMX routines) // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.7 2009/08/27 07:24:30 taurel // - Commit after another merge with Release_7_0_2-bugfixes branch // // Revision 1.6.2.2 2009/08/26 07:16:52 taurel // - Fix bugs in previous change related to PIC code // // Revision 1.6.2.1 2009/08/25 14:03:10 taurel // - First attempt to clarify the gcc PIC problem // // Revision 1.6 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= //------------------------------------------------------------------------------ // // (YCbCr to RGB) Y,Cb and Cr range in [0,255] // R = Y + 1.402 * (Cr-128) // G = Y - 0.34414 * (Cb-128) - 0.71414*(Cr-128) // B = Y + 1.772 * (Cb-128) // // (RGB to YCbCr) R,G,B range in [0,255] // Y = 0.299 * R + 0.587 * G + 0.114 * B // Cb = -0.16874 * R - 0.33126 * G + 0.5 * B + 128 // Cr = 0.5 * R - 0.41869 * G - 0.08131 * B + 128 // //------------------------------------------------------------------------------ #include "jpeg_memory.h" #include "jpeg_lib.h" #include #ifdef JPG_USE_ASM #ifdef _WINDOWS // Disable "has no EMMS instruction" warning #pragma warning( disable : 4799 ) #endif #define FIX14(x) ((short) ((x) * (1L<<14) + 0.5)) #define FIX15(x) ((short) ((x) * (1L<<15) + 0.5)) #define FIX16(x) ((short) ((x) * (1L<<16) + 0.5)) #ifdef _WINDOWS // Visual C++ align directive #define ALIGN8 __declspec(align(8)) #else // gcc align directive #define ALIGN8 __attribute__ ((aligned (8))) #endif // MMX constant (YCbCr to RGB) ALIGN8 short _cbgmm[] = { -FIX14(0.34414),-FIX14(0.34414),-FIX14(0.34414),-FIX14(0.34414) }; ALIGN8 short _cbbmm[] = { FIX14(1.772) , FIX14(1.772) , FIX14(1.772) , FIX14(1.772) }; ALIGN8 short _crgmm[] = { -FIX14(0.71414),-FIX14(0.71414),-FIX14(0.71414),-FIX14(0.71414) }; ALIGN8 short _crrmm[] = { FIX14(1.402) , FIX14(1.402) , FIX14(1.402) , FIX14(1.402) }; ALIGN8 short _128mm[] = { 128,128,128,128 }; // RGB to YCbCr ALIGN8 short _rymm[] = { FIX15(0.299), FIX15(0.299), FIX15(0.299), FIX15(0.299) }; ALIGN8 short _gymm[] = { FIX15(0.587), FIX15(0.587), FIX15(0.587), FIX15(0.587) }; ALIGN8 short _bymm[] = { FIX15(0.114), FIX15(0.114), FIX15(0.114), FIX15(0.114) }; ALIGN8 short _offymm[] = { -127,-127,-127,-127 }; // +1 for rounding ALIGN8 short _rcbcrmm[] = {-FIX15(0.16874),-FIX15(0.16874), FIX15(0.5) , FIX15(0.5) }; ALIGN8 short _gcbcrmm[] = {-FIX15(0.33126),-FIX15(0.33126),-FIX15(0.41869),-FIX15(0.41869)}; ALIGN8 short _bcbcrmm[] = { FIX15(0.5) , FIX15(0.5) ,-FIX15(0.08131),-FIX15(0.08131)}; ALIGN8 short _rcmm[] = { 1,1,1,1 }; // // Unfortunately with gcc, code like "psubw mm2,_128mm" is considered like non PIC // and the scanelf utility complains about this. This is also a problem for distribution like // Debian. Why, I don't know !! // This is a known problem and some WEB page have been written relatedto this issue. // I have used the page http://www.gentoo.org/proj/en/hardened/pic-fix-guide.xml // Within this page, they give 3 pssobilities to remove this kind of code. // I have use case number 1. Case number 2 and 3 are not really usable because // all the registers are already used (Not in all functions but in most of them) // Therefore, every variable defined previously are "manually" loaded into the MMX registers // using the stack as temporary storage // // -FIX14(0.34414) --> 0xe9fa // FIX14(1.772) --> 0x7168 // -FIX14(0.71414) --> 0xd24c // FIX14(1.402) --> 0x59ba // 128 --> 0x0080 // FIX15(0.299) --> 0x2646 // FIX15(0.587) --> 0x4b23 // FIX15(0.114) --> 0x0e98 // -127 --> 0xff81 // -FIX15(0.16874) --> 0xea67 // FIX15(0.5) --> 0x4000 // -FIX15(0.33126) --> 0xd599 // -FIX15(0.41869) --> 0xca68 // -FIX15(0.08131) --> 0xf598 // 1 --> 0x0001 // // This problem is the reason of all the following macros. // It's not a nice way to solve it> When we will have time, we will // try to find a cleaner solution // #ifndef _WINDOWS #ifdef __PIC__ #define sub_128_mmx_reg(REG1,REG2) \ "push 0x00800080 \n" \ "push 0x00800080 \n" \ "psubw "#REG1", QWORD PTR [esp] \n" \ "psubw "#REG2", QWORD PTR [esp] \n" \ "add esp,8 \n" #define add_127_mmx_reg(REG1) \ "push 0xff81ff81 \n" \ "push 0xff81ff81 \n" \ "paddw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define add_1_mmx_reg(REG1) \ "push 0x00010001 \n" \ "push 0x00010001 \n" \ "paddw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mul_cxx_mmx_reg(REG1,REG2,REG3,REG4) \ "push 0xe9fae9fa \n" \ "push 0xe9fae9fa \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "push 0x71687168 \n" \ "push 0x71687168 \n" \ "pmulhw "#REG2", QWORD PTR [esp] \n" \ "push 0xd24cd24c \n" \ "push 0xd24cd24c \n" \ "pmulhw "#REG3", QWORD PTR [esp] \n" \ "push 0x59ba59ba \n" \ "push 0x59ba59ba \n" \ "pmulhw "#REG4", QWORD PTR [esp] \n" \ "add esp,32 \n" #define mul_rgb_mmx_reg(REG1,REG2,REG3) \ "push 0x26462646 \n" \ "push 0x26462646 \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "push 0x4b234b23 \n" \ "push 0x4b234b23 \n" \ "pmulhw "#REG2", QWORD PTR [esp] \n" \ "push 0x0e980e98 \n" \ "push 0x0e980e98 \n" \ "pmulhw "#REG3", QWORD PTR [esp] \n" \ "add esp,24 \n" #define mul_rgbc_mmx_reg(REG1,REG2,REG3) \ "push 0x40004000 \n" \ "push 0xea67ea67 \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "push 0xca68ca68 \n" \ "push 0xd599d599 \n" \ "pmulhw "#REG2", QWORD PTR [esp] \n" \ "push 0xf598f598 \n" \ "push 0x40004000 \n" \ "pmulhw "#REG3", QWORD PTR [esp] \n" \ "add esp,24 \n" #else /* __PIC__ */ #define sub_128_mmx_reg(REG1,REG2) \ "psubw "#REG1",_128mm \n" \ "psubw "#REG2",_128mm \n" #define add_127_mmx_reg(REG1) \ "paddw "#REG1",_offymm \n" #define add_1_mmx_reg(REG1) \ "paddw "#REG1",_rcmm \n" #define mul_cxx_mmx_reg(REG1,REG2,REG3,REG4) \ "pmulhw "#REG1",_cbgmm \n" \ "pmulhw "#REG2",_cbbmm \n" \ "pmulhw "#REG3",_crgmm \n" \ "pmulhw "#REG4",_crrmm \n" #define mul_rgb_mmx_reg(REG1,REG2,REG3) \ "pmulhw "#REG1",_rymm \n" \ "pmulhw "#REG2",_gymm \n" \ "pmulhw "#REG3",_bymm \n" #define mul_rgbc_mmx_reg(REG1,REG2,REG3) \ "pmulhw "#REG1",_rcbcrmm \n" \ "pmulhw "#REG2",_gcbcrmm \n" \ "pmulhw "#REG3",_bcbcrmm \n" #endif /* __PIC__ */ #endif /* _WINDOWS */ //------------------------------------------------------------------------------ // MCU16x16 YCbCr H2V2 (2x2:1:1, 6 blocks per MCU) to 32-bit RGB //------------------------------------------------------------------------------ void jpeg_yh2v2_to_rgb32_mmx(unsigned char *block,long width,unsigned char *rgb) { unsigned char *y = block; unsigned char *cb = block+64*4; long j,y0; // ! Due to wrong gcc stack code (does not detect push), y0 is cleared during asm ! for(j=0;j<8;j++) { y0 = ((j&4)<<5) + ((j&3)<<4); #ifdef _WINDOWS // Visual C++ inline assembly _asm { mov edi,rgb mov esi,y mov eax,width mov ebx,cb mov edx,y0 xor ecx,ecx shl eax,2 __blrow_h2v2: // Y block offset add edx,ecx // -- 00 -- movd mm1,[esi+edx] // [0000][y11][y10][y01][y00] movd mm2,[ebx] // [0000][cb3][cb2][cb1][cb0] movd mm3,[ebx+64] // [0000][cr3][cr2][cr1][cr0] pxor mm0,mm0 punpcklbw mm1,mm0 // [y11][y10][y01][y00] punpcklbw mm2,mm0 // [cb3][cb2][cb1][cb0] punpcklbw mm3,mm0 // [cr3][cr2][cr1][cr0] psubw mm2,_128mm psubw mm3,_128mm psllw mm2,2 psllw mm3,2 movq mm4,mm2 movq mm5,mm3 pmulhw mm2,_cbgmm pmulhw mm4,_cbbmm pmulhw mm3,_crgmm pmulhw mm5,_crrmm movq mm6,mm5 punpcklwd mm6,mm6 // [cr1*crr][cr1*crr][cr0*crr][cr0*crr] paddw mm6,mm1 // R3R2R1R0 movq mm0,mm2 movq mm7,mm3 punpcklwd mm0,mm0 // [cb1*cbg][cb1*cbg][cb0*cbg][cb0*cbg] punpcklwd mm7,mm7 // [cr1*crg][cr1*crg][cr0*crg][cr0*crg] paddw mm0,mm1 paddw mm0,mm7 // G3G2G1G0 movq mm7,mm4 punpcklwd mm7,mm7 // [cb1*cbb][cb1*cbb][cb0*cbb][cb0*cbb] paddw mm7,mm1 // B3B2B1B0 pxor mm1,mm1 packuswb mm6,mm1 // [0000]R3R2R1R0 packuswb mm0,mm1 // [0000]G3G2G1G0 packuswb mm7,mm1 // [0000]B3B2B1B0 punpcklbw mm6,mm0 // G3R3G2R2G1R1G0R0 punpcklbw mm7,mm1 // 00B300B200B100B0 movq mm1,mm6 punpcklwd mm1,mm7 // 00B1G1R100B0G0R0 punpckhwd mm6,mm7 // 00B3G3R300B2G2R2 movq [edi] ,mm1 movq [edi+8],mm6 // -- 01 -- movd mm1,[esi+edx+4] // [0000][y31][y30][y21][y20] pxor mm0,mm0 punpcklbw mm1,mm0 movq mm6,mm5 punpckhwd mm6,mm6 // [cr3*crr][cr3*crr][cr2*crr][cr2*crr] paddw mm6,mm1 // R3R2R1R0 movq mm0,mm2 movq mm7,mm3 punpckhwd mm0,mm0 // [cb3*cbg][cb3*cbg][cb2*cbg][cb2*cbg] punpckhwd mm7,mm7 // [cr3*crg][cr3*crg][cr2*crg][cr2*crg] paddw mm0,mm1 paddw mm0,mm7 // G3G2G1G0 movq mm7,mm4 punpckhwd mm7,mm7 // [cb3*cbb][cb3*cbb][cb2*cbb][cb2*cbb] paddw mm7,mm1 // B3B2B1B0 pxor mm1,mm1 packuswb mm6,mm1 // [0000]R3R2R1R0 packuswb mm0,mm1 // [0000]G3G2G1G0 packuswb mm7,mm1 // [0000]B3B2B1B0 punpcklbw mm6,mm0 // G3R3G2R2G1R1G0R0 punpcklbw mm7,mm1 // 00B300B200B100B0 movq mm1,mm6 punpcklwd mm1,mm7 // 00B1G1R100B0G0R0 punpckhwd mm6,mm7 // 00B3G3R300B2G2R2 movq [edi+16],mm1 movq [edi+24],mm6 // -- 10 -- movd mm1,[esi+edx+8] // [0000][y11][y10][y01][y00] pxor mm0,mm0 punpcklbw mm1,mm0 movq mm6,mm5 punpcklwd mm6,mm6 // [cr1*crr][cr1*crr][cr0*crr][cr0*crr] paddw mm6,mm1 // R3R2R1R0 movq mm0,mm2 movq mm7,mm3 punpcklwd mm0,mm0 // [cb1*cbg][cb1*cbg][cb0*cbg][cb0*cbg] punpcklwd mm7,mm7 // [cr1*crg][cr1*crg][cr0*crg][cr0*crg] paddw mm0,mm1 paddw mm0,mm7 // G3G2G1G0 movq mm7,mm4 punpcklwd mm7,mm7 // [cb1*cbb][cb1*cbb][cb0*cbb][cb0*cbb] paddw mm7,mm1 // B3B2B1B0 pxor mm1,mm1 packuswb mm6,mm1 // [0000]R3R2R1R0 packuswb mm0,mm1 // [0000]G3G2G1G0 packuswb mm7,mm1 // [0000]B3B2B1B0 punpcklbw mm6,mm0 // G3R3G2R2G1R1G0R0 punpcklbw mm7,mm1 // 00B300B200B100B0 movq mm1,mm6 punpcklwd mm1,mm7 // 00B1G1R100B0G0R0 punpckhwd mm6,mm7 // 00B3G3R300B2G2R2 movq [edi+eax] ,mm1 movq [edi+eax+8],mm6 // -- 11 -- movd mm1,[esi+edx+12] // [0000][y31][y30][y21][y20] pxor mm0,mm0 punpcklbw mm1,mm0 movq mm6,mm5 punpckhwd mm6,mm6 // [cr3*crr][cr3*crr][cr2*crr][cr2*crr] paddw mm6,mm1 // R3R2R1R0 movq mm0,mm2 movq mm7,mm3 punpckhwd mm0,mm0 // [cb3*cbg][cb3*cbg][cb2*cbg][cb2*cbg] punpckhwd mm7,mm7 // [cr3*crg][cr3*crg][cr2*crg][cr2*crg] paddw mm0,mm1 paddw mm0,mm7 // G3G2G1G0 movq mm7,mm4 punpckhwd mm7,mm7 // [cb3*cbb][cb3*cbb][cb2*cbb][cb2*cbb] paddw mm7,mm1 // B3B2B1B0 pxor mm1,mm1 packuswb mm6,mm1 // [0000]R3R2R1R0 packuswb mm0,mm1 // [0000]G3G2G1G0 packuswb mm7,mm1 // [0000]B3B2B1B0 punpcklbw mm6,mm0 // G3R3G2R2G1R1G0R0 punpcklbw mm7,mm1 // 00B300B200B100B0 movq mm1,mm6 punpcklwd mm1,mm7 // 00B1G1R100B0G0R0 punpckhwd mm6,mm7 // 00B3G3R300B2G2R2 movq [edi+eax+16],mm1 movq [edi+eax+24],mm6 sub edx,ecx // Restore edx add edi,32 add ebx,4 add ecx,64 cmp ecx,128 jl __blrow_h2v2 } #else // GCC inline assembly code __asm__ ( ".intel_syntax noprefix \n" #ifdef _64BITS "push rbx \n" "mov rbx,rcx \n" "xor rcx,rcx \n" "shl rax,2 \n" "__blrow_h2v2: \n" "add rdx,rcx \n" "movd mm1,[rsi+rdx] \n" "movd mm2,[rbx] \n" "movd mm3,[rbx+64] \n" #else "push ebx \n" "mov ebx,ecx \n" "xor ecx,ecx \n" "shl eax,2 \n" "__blrow_h2v2: \n" "add edx,ecx \n" "movd mm1,[esi+edx] \n" "movd mm2,[ebx] \n" "movd mm3,[ebx+64] \n" #endif "pxor mm0,mm0 \n" "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" sub_128_mmx_reg(mm2,mm3) "psllw mm2,2 \n" "psllw mm3,2 \n" "movq mm4,mm2 \n" "movq mm5,mm3 \n" mul_cxx_mmx_reg(mm2,mm4,mm3,mm5) "movq mm6,mm5 \n" "punpcklwd mm6,mm6 \n" "paddw mm6,mm1 \n" "movq mm0,mm2 \n" "movq mm7,mm3 \n" "punpcklwd mm0,mm0 \n" "punpcklwd mm7,mm7 \n" "paddw mm0,mm1 \n" "paddw mm0,mm7 \n" "movq mm7,mm4 \n" "punpcklwd mm7,mm7 \n" "paddw mm7,mm1 \n" "pxor mm1,mm1 \n" "packuswb mm6,mm1 \n" "packuswb mm0,mm1 \n" "packuswb mm7,mm1 \n" "punpcklbw mm6,mm0 \n" "punpcklbw mm7,mm1 \n" "movq mm1,mm6 \n" "punpcklwd mm1,mm7 \n" "punpckhwd mm6,mm7 \n" #ifdef _64BITS "movq [rdi] ,mm1 \n" "movq [rdi+8],mm6 \n" "movd mm1,[rsi+rdx+4] \n" #else "movq [edi] ,mm1 \n" "movq [edi+8],mm6 \n" "movd mm1,[esi+edx+4] \n" #endif "pxor mm0,mm0 \n" "punpcklbw mm1,mm0 \n" "movq mm6,mm5 \n" "punpckhwd mm6,mm6 \n" "paddw mm6,mm1 \n" "movq mm0,mm2 \n" "movq mm7,mm3 \n" "punpckhwd mm0,mm0 \n" "punpckhwd mm7,mm7 \n" "paddw mm0,mm1 \n" "paddw mm0,mm7 \n" "movq mm7,mm4 \n" "punpckhwd mm7,mm7 \n" "paddw mm7,mm1 \n" "pxor mm1,mm1 \n" "packuswb mm6,mm1 \n" "packuswb mm0,mm1 \n" "packuswb mm7,mm1 \n" "punpcklbw mm6,mm0 \n" "punpcklbw mm7,mm1 \n" "movq mm1,mm6 \n" "punpcklwd mm1,mm7 \n" "punpckhwd mm6,mm7 \n" #ifdef _64BITS "movq [rdi+16],mm1 \n" "movq [rdi+24],mm6 \n" "movd mm1,[rsi+rdx+8] \n" #else "movq [edi+16],mm1 \n" "movq [edi+24],mm6 \n" "movd mm1,[esi+edx+8] \n" #endif "pxor mm0,mm0 \n" "punpcklbw mm1,mm0 \n" "movq mm6,mm5 \n" "punpcklwd mm6,mm6 \n" "paddw mm6,mm1 \n" "movq mm0,mm2 \n" "movq mm7,mm3 \n" "punpcklwd mm0,mm0 \n" "punpcklwd mm7,mm7 \n" "paddw mm0,mm1 \n" "paddw mm0,mm7 \n" "movq mm7,mm4 \n" "punpcklwd mm7,mm7 \n" "paddw mm7,mm1 \n" "pxor mm1,mm1 \n" "packuswb mm6,mm1 \n" "packuswb mm0,mm1 \n" "packuswb mm7,mm1 \n" "punpcklbw mm6,mm0 \n" "punpcklbw mm7,mm1 \n" "movq mm1,mm6 \n" "punpcklwd mm1,mm7 \n" "punpckhwd mm6,mm7 \n" #ifdef _64BITS "movq [rdi+rax] ,mm1 \n" "movq [rdi+rax+8],mm6 \n" "movd mm1,[rsi+rdx+12] \n" #else "movq [edi+eax] ,mm1 \n" "movq [edi+eax+8],mm6 \n" "movd mm1,[esi+edx+12] \n" #endif "pxor mm0,mm0 \n" "punpcklbw mm1,mm0 \n" "movq mm6,mm5 \n" "punpckhwd mm6,mm6 \n" "paddw mm6,mm1 \n" "movq mm0,mm2 \n" "movq mm7,mm3 \n" "punpckhwd mm0,mm0 \n" "punpckhwd mm7,mm7 \n" "paddw mm0,mm1 \n" "paddw mm0,mm7 \n" "movq mm7,mm4 \n" "punpckhwd mm7,mm7 \n" "paddw mm7,mm1 \n" "pxor mm1,mm1 \n" "packuswb mm6,mm1 \n" "packuswb mm0,mm1 \n" "packuswb mm7,mm1 \n" "punpcklbw mm6,mm0 \n" "punpcklbw mm7,mm1 \n" "movq mm1,mm6 \n" "punpcklwd mm1,mm7 \n" "punpckhwd mm6,mm7 \n" #ifdef _64BITS "movq [rdi+rax+16],mm1 \n" "movq [rdi+rax+24],mm6 \n" "sub rdx,rcx \n" "add rdi,32 \n" "add rbx,4 \n" "add rcx,64 \n" "cmp rcx,128 \n" "jl __blrow_h2v2 \n" "pop rbx \n" #else "movq [edi+eax+16],mm1 \n" "movq [edi+eax+24],mm6 \n" "sub edx,ecx \n" "add edi,32 \n" "add ebx,4 \n" "add ecx,64 \n" "cmp ecx,128 \n" "jl __blrow_h2v2 \n" "pop ebx \n" #endif ".att_syntax \n" : /* no output */ : "D"(rgb),"S"(y),"a"(width),"c"(cb),"d"(y0) : "memory","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #endif cb += 8; rgb += 8*width; } } //------------------------------------------------------------------------------ // MCU8x8 YCbCr H1V1 (1x1:1:1, 3 blocks per MCU) to 32-bit RGB //------------------------------------------------------------------------------ void jpeg_yh1v1_to_rgb32_mmx(unsigned char *block,long width,unsigned char *rgb) { #ifdef _WINDOWS // Visual C++ inline assembly _asm { mov edi,rgb mov esi,block mov eax,width shl eax,2 mov ecx,8 pxor mm0,mm0 __blcol_h1v1: // ----- movd mm1,[esi] // [0000][y03][y02][y01][y00] movd mm2,[esi+64] // [0000][cb3][cb2][cb1][cb0] movd mm3,[esi+128] // [0000][cr3][cr2][cr1][cr0] punpcklbw mm1,mm0 // [y03][y02][y01][y00] punpcklbw mm2,mm0 // [cb3][cb2][cb1][cb0] punpcklbw mm3,mm0 // [cr3][cr2][cr1][cr0] psubw mm2,_128mm psubw mm3,_128mm psllw mm2,2 psllw mm3,2 movq mm4,mm2 movq mm5,mm3 pmulhw mm2,_cbgmm // [cb3*cbg][cb2*cbg][cb1*cbg][cb0*cbg] pmulhw mm4,_cbbmm // [cb3*cbb][cb2*cbb][cb1*cbb][cb0*cbb] pmulhw mm3,_crgmm // [cb3*crg][cb2*crg][cb1*crg][cb0*crg] pmulhw mm5,_crrmm // [cb3*crr][cb2*crr][cb1*crr][cb0*crr] paddw mm5,mm1 // R3R2R1R0 paddw mm2,mm1 paddw mm2,mm3 // G3G2G1G0 paddw mm4,mm1 // B3B2B1B0 packuswb mm5,mm0 // [0000]R3R2R1R0 packuswb mm2,mm0 // [0000]G3G2G1G0 packuswb mm4,mm0 // [0000]B3B2B1B0 punpcklbw mm5,mm2 // G3R3G2R2G1R1G0R0 punpcklbw mm4,mm0 // 00B300B200B100B0 movq mm1,mm5 punpcklwd mm1,mm4 // 00B1G1R100B0G0R0 punpckhwd mm5,mm4 // 00B3G3R300B2G2R2 movq [edi],mm1 movq [edi+8],mm5 // ----- movd mm1,[esi+4] // [0000][y03][y02][y01][y00] movd mm2,[esi+68] // [0000][cb3][cb2][cb1][cb0] movd mm3,[esi+132] // [0000][cr3][cr2][cr1][cr0] punpcklbw mm1,mm0 // [y03][y02][y01][y00] punpcklbw mm2,mm0 // [cb3][cb2][cb1][cb0] punpcklbw mm3,mm0 // [cr3][cr2][cr1][cr0] psubw mm2,_128mm psubw mm3,_128mm psllw mm2,2 psllw mm3,2 movq mm4,mm2 movq mm5,mm3 pmulhw mm2,_cbgmm // [cb3*cbg][cb2*cbg][cb1*cbg][cb0*cbg] pmulhw mm4,_cbbmm // [cb3*cbb][cb2*cbb][cb1*cbb][cb0*cbb] pmulhw mm3,_crgmm // [cb3*crg][cb2*crg][cb1*crg][cb0*crg] pmulhw mm5,_crrmm // [cb3*crr][cb2*crr][cb1*crr][cb0*crr] paddw mm5,mm1 // R3R2R1R0 paddw mm2,mm1 paddw mm2,mm3 // G3G2G1G0 paddw mm4,mm1 // B3B2B1B0 packuswb mm5,mm0 // [0000]R3R2R1R0 packuswb mm2,mm0 // [0000]G3G2G1G0 packuswb mm4,mm0 // [0000]B3B2B1B0 punpcklbw mm5,mm2 // G3R3G2R2G1R1G0R0 punpcklbw mm4,mm0 // 00B300B200B100B0 movq mm1,mm5 punpcklwd mm1,mm4 // 00B1G1R100B0G0R0 punpckhwd mm5,mm4 // 00B3G3R300B2G2R2 movq [edi+16],mm1 movq [edi+24],mm5 add esi,8 add edi,eax dec ecx jnz __blcol_h1v1 } #else // GCC inline assembly code __asm__ ( ".intel_syntax noprefix \n" #ifdef _64BITS "shl rax,2 \n" "mov rcx,8 \n" "pxor mm0,mm0 \n" "__blcol_h1v1: \n" "movd mm1,[rsi] \n" "movd mm2,[rsi+64] \n" "movd mm3,[rsi+128] \n" #else "shl eax,2 \n" "mov ecx,8 \n" "pxor mm0,mm0 \n" "__blcol_h1v1: \n" "movd mm1,[esi] \n" "movd mm2,[esi+64] \n" "movd mm3,[esi+128] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" sub_128_mmx_reg(mm2,mm3) "psllw mm2,2 \n" "psllw mm3,2 \n" "movq mm4,mm2 \n" "movq mm5,mm3 \n" mul_cxx_mmx_reg(mm2,mm4,mm3,mm5) "paddw mm5,mm1 \n" "paddw mm2,mm1 \n" "paddw mm2,mm3 \n" "paddw mm4,mm1 \n" "packuswb mm5,mm0 \n" "packuswb mm2,mm0 \n" "packuswb mm4,mm0 \n" "punpcklbw mm5,mm2 \n" "punpcklbw mm4,mm0 \n" "movq mm1,mm5 \n" "punpcklwd mm1,mm4 \n" "punpckhwd mm5,mm4 \n" #ifdef _64BITS "movq [rdi],mm1 \n" "movq [rdi+8],mm5 \n" "movd mm1,[rsi+4] \n" "movd mm2,[rsi+68] \n" "movd mm3,[rsi+132] \n" #else "movq [edi],mm1 \n" "movq [edi+8],mm5 \n" "movd mm1,[esi+4] \n" "movd mm2,[esi+68] \n" "movd mm3,[esi+132] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" sub_128_mmx_reg(mm2,mm3) "psllw mm2,2 \n" "psllw mm3,2 \n" "movq mm4,mm2 \n" "movq mm5,mm3 \n" mul_cxx_mmx_reg(mm2,mm4,mm3,mm5) "paddw mm5,mm1 \n" "paddw mm2,mm1 \n" "paddw mm2,mm3 \n" "paddw mm4,mm1 \n" "packuswb mm5,mm0 \n" "packuswb mm2,mm0 \n" "packuswb mm4,mm0 \n" "punpcklbw mm5,mm2 \n" "punpcklbw mm4,mm0 \n" "movq mm1,mm5 \n" "punpcklwd mm1,mm4 \n" "punpckhwd mm5,mm4 \n" #ifdef _64BITS "movq [rdi+16],mm1 \n" "movq [rdi+24],mm5 \n" "add rsi,8 \n" "add rdi,rax \n" "dec rcx \n" "jnz __blcol_h1v1 \n" #else "movq [edi+16],mm1 \n" "movq [edi+24],mm5 \n" "add esi,8 \n" "add edi,eax \n" "dec ecx \n" "jnz __blcol_h1v1 \n" #endif ".att_syntax \n" : /* no output */ : "D"(rgb),"S"(block),"a"(width) #ifdef _64BITS : "memory","rcx","mm0","mm1","mm2","mm3","mm4","mm5" #else : "memory","ecx","mm0","mm1","mm2","mm3","mm4","mm5" #endif ); #endif } // Convert 8x8 GRAY8 pixel map to (1xY) block void conv_block_GRAY8Y_mmx(long width,unsigned char *g,short *y) { #ifdef _WINDOWS // Visual C++ inline assembly _asm { mov esi,g mov edi,y mov eax,width mov ecx,8 pxor mm0,mm0 __blrow_gray8: movd mm1,[esi] movd mm2,[esi+4] punpcklbw mm1,mm0 punpcklbw mm2,mm0 psubw mm1,_128mm psubw mm2,_128mm movq [edi] ,mm1 movq [edi+8],mm2 add esi,eax add edi,16 dec ecx jnz __blrow_gray8 } #else // GCC inline assembly code __asm__ ( ".intel_syntax noprefix \n" #ifdef _64BITS "mov rcx,8 \n" "pxor mm0,mm0 \n" "__blrow_gray8: \n" "movd mm1,[rsi] \n" "movd mm2,[rsi+4] \n" "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" sub_128_mmx_reg(mm1,mm2) "movq [rdi] ,mm1 \n" "movq [rdi+8],mm2 \n" "add rsi,rax \n" "add rdi,16 \n" "dec rcx \n" "jnz __blrow_gray8 \n" ".att_syntax \n" : /* no output */ : "D"(y),"S"(g),"a"(width) : "memory","rcx","mm0","mm1","mm2" #else "mov ecx,8 \n" "pxor mm0,mm0 \n" "__blrow_gray8: \n" "movd mm1,[esi] \n" "movd mm2,[esi+4] \n" "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" sub_128_mmx_reg(mm1,mm2) "movq [edi] ,mm1 \n" "movq [edi+8],mm2 \n" "add esi,eax \n" "add edi,16 \n" "dec ecx \n" "jnz __blrow_gray8 \n" ".att_syntax \n" : /* no output */ : "D"(y),"S"(g),"a"(width) : "memory","ecx","mm0","mm1","mm2" #endif ); #endif } // Convert 16x16 RGB24 pixel map to (4xY 1xCb 1xCr) block void conv_block_RGB24H2V2_mmx(long width,unsigned char *rgb,short *y,short *cb,short *cr) { long i,j,y0,pitch; short *yB; // ! Due to wrong gcc stack code (does not detect push), yB is cleared during asm ! pitch = 6*width-48; for(j=0;j<8;j++) { y0 = (((j&4)<<5) + ((j&3)<<4)); for(i=0;i<4;i++) { yB = y + (y0 + (((i&2)<<5) + ((i&1)<<2))); #ifdef _WINDOWS // Visual C++ inline assembly _asm { mov esi,rgb mov edi,yB mov eax,width mov ebx,cb mov edx,cr mov ecx,eax shl eax,1 add eax,ecx pxor mm0,mm0 // Y 1st row movd mm1,[esi] // [0000]xxB0G0R0 movd mm3,[esi+6] // [0000]xxB2G2R2 movd mm2,[esi+3] // [0000]xxB1G1R1 movd mm4,[esi+8] // [0000]B3G3R3xx psrlq mm4,8 // [0000]xxB3G3R3 punpcklbw mm1,mm0 // xxB0G0R0 punpcklbw mm2,mm0 // xxB1G1R1 punpcklbw mm3,mm0 // xxB2G2R2 punpcklbw mm4,mm0 // xxB3G3R3 movq mm6,mm3 movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 punpcklwd mm3,mm4 // G3G2R3R2 movq mm5,mm1 punpckldq mm1,mm3 // R3R2R1R0 punpckhdq mm5,mm3 // G3G2G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckhwd mm6,mm4 // xxxxB3B2 punpckldq mm7,mm6 // B3B2B1B0 psllw mm1,1 psllw mm5,1 psllw mm7,1 pmulhw mm1,_rymm pmulhw mm5,_gymm pmulhw mm7,_bymm paddw mm1,mm5 paddw mm1,mm7 // Y3Y2Y1Y0 paddw mm1,_offymm movq [edi],mm1 // 2nd row movd mm1,[esi+eax] // [0000]xxB0G0R0 movd mm3,[esi+eax+6] // [0000]xxB2G2R2 movd mm2,[esi+eax+3] // [0000]xxB1G1R1 movd mm4,[esi+eax+8] // [0000]B3G3R3xx psrlq mm4,8 // [0000]xxB3G3R3 punpcklbw mm1,mm0 // xxB0G0R0 punpcklbw mm2,mm0 // xxB1G1R1 punpcklbw mm3,mm0 // xxB2G2R2 punpcklbw mm4,mm0 // xxB3G3R3 movq mm6,mm3 movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 punpcklwd mm3,mm4 // G3G2R3R2 movq mm5,mm1 punpckldq mm1,mm3 // R3R2R1R0 punpckhdq mm5,mm3 // G3G2G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckhwd mm6,mm4 // xxxxB3B2 punpckldq mm7,mm6 // B3B2B1B0 psllw mm1,1 psllw mm5,1 psllw mm7,1 pmulhw mm1,_rymm pmulhw mm5,_gymm pmulhw mm7,_bymm paddw mm1,mm5 paddw mm1,mm7 // Y3Y2Y1Y0 paddw mm1,_offymm movq [edi+16],mm1 // CbCr (2x downsampling) movd mm1,[esi] // [0000]xxB00G00R00 movd mm3,[esi+eax] // [0000]xxB01G01R01 movd mm2,[esi+3] // [0000]xxB10G10R10 movd mm4,[esi+eax+3] // [0000]xxB11G11R11 punpcklbw mm1,mm0 punpcklbw mm2,mm0 punpcklbw mm3,mm0 punpcklbw mm4,mm0 paddw mm1,mm2 // xx[B00+B10][G00+G10][R00+R10] paddw mm3,mm4 // xx[B01+B11][G01+G11][R01+R11] paddw mm1,mm3 psrlw mm1,1 // xx[B0][G0][R0] movd mm2,[esi+6] // [0000]xxB00G00R00 movd mm4,[esi+eax+6] // [0000]B01G01R01xx movd mm3,[esi+8] // [0000]xxB10G10R10 movd mm5,[esi+eax+8] // [0000]B11G11R11xx psrlq mm3,8 // [0000]xxB01G01R01 psrlq mm5,8 // [0000]xxB11G11R11 punpcklbw mm2,mm0 punpcklbw mm3,mm0 punpcklbw mm4,mm0 punpcklbw mm5,mm0 paddw mm2,mm3 // xx[B00+B10][G00+G10][R00+R10] paddw mm4,mm5 // xx[B01+B11][G01+G11][R01+R11] paddw mm2,mm4 psrlw mm2,1 // xx[B1][G1][R1] movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 movq mm5,mm1 punpckldq mm1,mm1 // R1R0R1R0 punpckhdq mm5,mm5 // G1G0G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckldq mm7,mm7 // B1B0B1B0 pmulhw mm1,_rcbcrmm pmulhw mm5,_gcbcrmm pmulhw mm7,_bcbcrmm paddw mm1,mm5 paddw mm1,mm7 // cb1cb0cr1cr0 paddw mm1,_rcmm movd [ebx],mm1 psrlq mm1,32 movd [edx],mm1 } // end asm #else // GCC inline assembly code __asm__ ( ".intel_syntax noprefix \n" #ifdef _64BITS "push rbx \n" "mov rbx,rcx \n" "mov rcx,rax \n" "shl rax,1 \n" "add rax,rcx \n" "pxor mm0,mm0 \n" "movd mm1,[rsi] \n" "movd mm3,[rsi+6] \n" "movd mm2,[rsi+3] \n" "movd mm4,[rsi+8] \n" #else "push ebx \n" "mov ebx,ecx \n" "mov ecx,eax \n" "shl eax,1 \n" "add eax,ecx \n" "pxor mm0,mm0 \n" "movd mm1,[esi] \n" "movd mm3,[esi+6] \n" "movd mm2,[esi+3] \n" "movd mm4,[esi+8] \n" #endif "psrlq mm4,8 \n" "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "movq mm6,mm3 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "punpcklwd mm3,mm4 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm3 \n" "punpckhdq mm5,mm3 \n" "punpckhwd mm7,mm2 \n" "punpckhwd mm6,mm4 \n" "punpckldq mm7,mm6 \n" "psllw mm1,1 \n" "psllw mm5,1 \n" "psllw mm7,1 \n" mul_rgb_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_127_mmx_reg(mm1) #ifdef _64BITS "movq [rdi],mm1 \n" "movd mm1,[rsi+rax] \n" "movd mm3,[rsi+rax+6] \n" "movd mm2,[rsi+rax+3] \n" "movd mm4,[rsi+rax+8] \n" #else "movq [edi],mm1 \n" "movd mm1,[esi+eax] \n" "movd mm3,[esi+eax+6] \n" "movd mm2,[esi+eax+3] \n" "movd mm4,[esi+eax+8] \n" #endif "psrlq mm4,8 \n" "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "movq mm6,mm3 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "punpcklwd mm3,mm4 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm3 \n" "punpckhdq mm5,mm3 \n" "punpckhwd mm7,mm2 \n" "punpckhwd mm6,mm4 \n" "punpckldq mm7,mm6 \n" "psllw mm1,1 \n" "psllw mm5,1 \n" "psllw mm7,1 \n" mul_rgb_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_127_mmx_reg(mm1) #ifdef _64BITS "movq [rdi+16],mm1 \n" "movd mm1,[rsi] \n" "movd mm3,[rsi+rax] \n" "movd mm2,[rsi+3] \n" "movd mm4,[rsi+rax+3] \n" #else "movq [edi+16],mm1 \n" "movd mm1,[esi] \n" "movd mm3,[esi+eax] \n" "movd mm2,[esi+3] \n" "movd mm4,[esi+eax+3] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "paddw mm1,mm2 \n" "paddw mm3,mm4 \n" "paddw mm1,mm3 \n" "psrlw mm1,1 \n" #ifdef _64BITS "movd mm2,[rsi+6] \n" "movd mm4,[rsi+rax+6] \n" "movd mm3,[rsi+8] \n" "movd mm5,[rsi+rax+8] \n" #else "movd mm2,[esi+6] \n" "movd mm4,[esi+eax+6] \n" "movd mm3,[esi+8] \n" "movd mm5,[esi+eax+8] \n" #endif "psrlq mm3,8 \n" "psrlq mm5,8 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "punpcklbw mm5,mm0 \n" "paddw mm2,mm3 \n" "paddw mm4,mm5 \n" "paddw mm2,mm4 \n" "psrlw mm2,1 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm1 \n" "punpckhdq mm5,mm5 \n" "punpckhwd mm7,mm2 \n" "punpckldq mm7,mm7 \n" mul_rgbc_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_1_mmx_reg(mm1) #ifdef _64BITS "movd [rbx],mm1 \n" "psrlq mm1,32 \n" "movd [rdx],mm1 \n" "pop rbx \n" #else "movd [ebx],mm1 \n" "psrlq mm1,32 \n" "movd [edx],mm1 \n" "pop ebx \n" #endif ".att_syntax \n" : /* no output */ : "D"(yB),"S"(rgb),"a"(width),"c"(cb),"d"(cr) : "memory","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #endif cb+=2; cr+=2; rgb+=12; } rgb+=pitch; } } // Convert 16x16 RGB32 pixel map to (4xY 1xCb 1xCr) block void conv_block_RGB32H2V2_mmx(long width,unsigned char *rgb,short *y,short *cb,short *cr) { long i,j,y0,pitch; short *yB; // ! Due to wrong gcc stack code (does not detect push), yB is cleared during asm ! pitch = 8*width-64; for(j=0;j<8;j++) { y0 = (((j&4)<<5) + ((j&3)<<4)); for(i=0;i<4;i++) { yB = y + (y0 + (((i&2)<<5) + ((i&1)<<2))); #ifdef _WINDOWS // Visual C++ inline assembly _asm { mov esi,rgb mov edi,yB mov eax,width mov ebx,cb mov edx,cr pxor mm0,mm0 shl eax,2 // Y 1st row movd mm1,[esi] // [0000]xxB0G0R0 movd mm3,[esi+8] // [0000]xxB2G2R2 movd mm2,[esi+4] // [0000]xxB1G1R1 movd mm4,[esi+12] // [0000]xxB3G3R3 punpcklbw mm1,mm0 // xxB0G0R0 punpcklbw mm2,mm0 // xxB1G1R1 punpcklbw mm3,mm0 // xxB2G2R2 punpcklbw mm4,mm0 // xxB3G3R3 movq mm6,mm3 movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 punpcklwd mm3,mm4 // G3G2R3R2 movq mm5,mm1 punpckldq mm1,mm3 // R3R2R1R0 punpckhdq mm5,mm3 // G3G2G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckhwd mm6,mm4 // xxxxB3B2 punpckldq mm7,mm6 // B3B2B1B0 psllw mm1,1 psllw mm5,1 psllw mm7,1 pmulhw mm1,_rymm pmulhw mm5,_gymm pmulhw mm7,_bymm paddw mm1,mm5 paddw mm1,mm7 // Y3Y2Y1Y0 paddw mm1,_offymm movq [edi],mm1 // 2nd row movd mm1,[esi+eax] // [0000]xxB0G0R0 movd mm3,[esi+eax+8] // [0000]xxB2G2R2 movd mm2,[esi+eax+4] // [0000]xxB1G1R1 movd mm4,[esi+eax+12] // [0000]xxB3G3R3 punpcklbw mm1,mm0 // xxB0G0R0 punpcklbw mm2,mm0 // xxB1G1R1 punpcklbw mm3,mm0 // xxB2G2R2 punpcklbw mm4,mm0 // xxB3G3R3 movq mm6,mm3 movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 punpcklwd mm3,mm4 // G3G2R3R2 movq mm5,mm1 punpckldq mm1,mm3 // R3R2R1R0 punpckhdq mm5,mm3 // G3G2G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckhwd mm6,mm4 // xxxxB3B2 punpckldq mm7,mm6 // B3B2B1B0 psllw mm1,1 psllw mm5,1 psllw mm7,1 pmulhw mm1,_rymm pmulhw mm5,_gymm pmulhw mm7,_bymm paddw mm1,mm5 paddw mm1,mm7 // Y3Y2Y1Y0 paddw mm1,_offymm movq [edi+16],mm1 // CbCr (2x downsampling) movd mm1,[esi] // [0000]xxB00G00R00 movd mm3,[esi+eax] // [0000]xxB01G01R01 movd mm2,[esi+4] // [0000]xxB10G10R10 movd mm4,[esi+eax+4] // [0000]xxB11G11R11 punpcklbw mm1,mm0 punpcklbw mm2,mm0 punpcklbw mm3,mm0 punpcklbw mm4,mm0 paddw mm1,mm2 // xx[B00+B10][G00+G10][R00+R10] paddw mm3,mm4 // xx[B01+B11][G01+G11][R01+R11] paddw mm1,mm3 psrlw mm1,1 // xx[B0][G0][R0] movd mm2,[esi+8] // [0000]xxB00G00R00 movd mm4,[esi+eax+8] // [0000]B01G01R01xx movd mm3,[esi+12] // [0000]xxB10G10R10 movd mm5,[esi+eax+12] // [0000]xxB11G11R11 punpcklbw mm2,mm0 punpcklbw mm3,mm0 punpcklbw mm4,mm0 punpcklbw mm5,mm0 paddw mm2,mm3 // xx[B00+B10][G00+G10][R00+R10] paddw mm4,mm5 // xx[B01+B11][G01+G11][R01+R11] paddw mm2,mm4 psrlw mm2,1 // xx[B1][G1][R1] movq mm7,mm1 punpcklwd mm1,mm2 // G1G0R1R0 movq mm5,mm1 punpckldq mm1,mm1 // R1R0R1R0 punpckhdq mm5,mm5 // G1G0G1G0 punpckhwd mm7,mm2 // xxxxB1B0 punpckldq mm7,mm7 // B1B0B1B0 pmulhw mm1,_rcbcrmm pmulhw mm5,_gcbcrmm pmulhw mm7,_bcbcrmm paddw mm1,mm5 paddw mm1,mm7 // cb1cb0cr1cr0 paddw mm1,_rcmm movd [ebx],mm1 psrlq mm1,32 movd [edx],mm1 } // end asm #else // GCC inline assembly code __asm__ ( ".intel_syntax noprefix \n" #ifdef _64BITS "push rbx \n" "mov rbx,rcx \n" "pxor mm0,mm0 \n" "shl rax,2 \n" "movd mm1,[rsi] \n" "movd mm3,[rsi+8] \n" "movd mm2,[rsi+4] \n" "movd mm4,[rsi+12] \n" #else "push ebx \n" "mov ebx,ecx \n" "pxor mm0,mm0 \n" "shl eax,2 \n" "movd mm1,[esi] \n" "movd mm3,[esi+8] \n" "movd mm2,[esi+4] \n" "movd mm4,[esi+12] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "movq mm6,mm3 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "punpcklwd mm3,mm4 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm3 \n" "punpckhdq mm5,mm3 \n" "punpckhwd mm7,mm2 \n" "punpckhwd mm6,mm4 \n" "punpckldq mm7,mm6 \n" "psllw mm1,1 \n" "psllw mm5,1 \n" "psllw mm7,1 \n" mul_rgb_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_127_mmx_reg(mm1) #ifdef _64BITS "movq [rdi],mm1 \n" "movd mm1,[rsi+rax] \n" "movd mm3,[rsi+rax+8] \n" "movd mm2,[rsi+rax+4] \n" "movd mm4,[rsi+rax+12] \n" #else "movq [edi],mm1 \n" "movd mm1,[esi+eax] \n" "movd mm3,[esi+eax+8] \n" "movd mm2,[esi+eax+4] \n" "movd mm4,[esi+eax+12] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "movq mm6,mm3 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "punpcklwd mm3,mm4 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm3 \n" "punpckhdq mm5,mm3 \n" "punpckhwd mm7,mm2 \n" "punpckhwd mm6,mm4 \n" "punpckldq mm7,mm6 \n" "psllw mm1,1 \n" "psllw mm5,1 \n" "psllw mm7,1 \n" mul_rgb_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_127_mmx_reg(mm1) #ifdef _64BITS "movq [rdi+16],mm1 \n" "movd mm1,[rsi] \n" "movd mm3,[rsi+rax] \n" "movd mm2,[rsi+4] \n" "movd mm4,[rsi+rax+4] \n" #else "movq [edi+16],mm1 \n" "movd mm1,[esi] \n" "movd mm3,[esi+eax] \n" "movd mm2,[esi+4] \n" "movd mm4,[esi+eax+4] \n" #endif "punpcklbw mm1,mm0 \n" "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "paddw mm1,mm2 \n" "paddw mm3,mm4 \n" "paddw mm1,mm3 \n" "psrlw mm1,1 \n" #ifdef _64BITS "movd mm2,[rsi+8] \n" "movd mm4,[rsi+rax+8] \n" "movd mm3,[rsi+12] \n" "movd mm5,[rsi+rax+12] \n" #else "movd mm2,[esi+8] \n" "movd mm4,[esi+eax+8] \n" "movd mm3,[esi+12] \n" "movd mm5,[esi+eax+12] \n" #endif "punpcklbw mm2,mm0 \n" "punpcklbw mm3,mm0 \n" "punpcklbw mm4,mm0 \n" "punpcklbw mm5,mm0 \n" "paddw mm2,mm3 \n" "paddw mm4,mm5 \n" "paddw mm2,mm4 \n" "psrlw mm2,1 \n" "movq mm7,mm1 \n" "punpcklwd mm1,mm2 \n" "movq mm5,mm1 \n" "punpckldq mm1,mm1 \n" "punpckhdq mm5,mm5 \n" "punpckhwd mm7,mm2 \n" "punpckldq mm7,mm7 \n" mul_rgbc_mmx_reg(mm1,mm5,mm7) "paddw mm1,mm5 \n" "paddw mm1,mm7 \n" add_1_mmx_reg(mm1) #ifdef _64BITS "movd [rbx],mm1 \n" "psrlq mm1,32 \n" "movd [rdx],mm1 \n" "pop rbx \n" #else "movd [ebx],mm1 \n" "psrlq mm1,32 \n" "movd [edx],mm1 \n" "pop ebx \n" #endif ".att_syntax \n" : /* no output */ : "D"(yB),"S"(rgb),"a"(width),"c"(cb),"d"(cr) : "memory","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #endif cb+=2; cr+=2; rgb+=16; } rgb+=pitch; } } #endif /* JPG_USE_ASM */ tango-9.2.5a/lib/cpp/server/jpeg_mmx/jpeg_dct_mmx.cpp0000644023471100065110000016361313034744777017570 00000000000000///============================================================================= // // file : jpeg_dct_mmx.cpp // // description : Simple jpeg coding/decoding library // Discrete Cosine Transform (8x8) MMX code // // project : TANGO // // author(s) : JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.9 2009/09/02 08:01:43 taurel // - Fix linker problem when used with gcc release < 4 // // Revision 1.8 2009/09/01 14:02:07 taurel // - Fix a problem for old gcc release in the asm code. // // Revision 1.7 2009/08/27 07:24:30 taurel // - Commit after another merge with Release_7_0_2-bugfixes branch // // Revision 1.6.2.1 2009/08/25 14:03:10 taurel // - First attempt to clarify the gcc PIC problem // // Revision 1.6 2009/04/20 14:55:58 jlpons // Added GPL header, changed memory allocation to C++ fashion. // //============================================================================= // MMX implementation has been provided by Intel at AP-922 #include "jpeg_lib.h" #ifdef JPG_USE_ASM #ifdef _WINDOWS // Visual C++ align directive #define ALIGN8 __declspec(align(8)) #else // gcc align directive #define ALIGN8 __attribute__ ((aligned (8))) #endif #define BITS_FRW_ACC 3 //// 2 or 3 for accuracy #define SHIFT_FRW_COL BITS_FRW_ACC #define SHIFT_FRW_ROW (BITS_FRW_ACC + 14) #define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1)) // MMX constants ALIGN8 short __jpmm_one_corr[] = {1,1,1,1}; ALIGN8 long __jpmm_round_frw_row[] = {RND_FRW_ROW,RND_FRW_ROW}; ALIGN8 short __jpmm_tg_1_16[] = { 13036, 13036, 13036, 13036 }; //tg * (2<<16) + 0.5 ALIGN8 short __jpmm_tg_2_16[] = { 27146, 27146, 27146, 27146 }; //tg * (2<<16) + 0.5 ALIGN8 short __jpmm_tg_3_16[] = { -21746, -21746, -21746, -21746 }; //tg * (2<<16) + 0.5 ALIGN8 short __jpmm_cos_4_16[] = { -19195, -19195, -19195, -19195 }; //cos * (2<<16) + 0.5 ALIGN8 short __jpmm_ocos_4_16[] = { 23170, 23170, 23170, 23170 }; //cos * (2<<15) + 0.5 ALIGN8 short __jpmm_row_tab_frw[] = { // forward_dct coeff table //row0 16384, 16384, 21407, -8867, // w09 w01 w08 w00 16384, 16384, 8867, -21407, // w13 w05 w12 w04 16384, -16384, 8867, 21407, // w11 w03 w10 w02 -16384, 16384, -21407, -8867, // w15 w07 w14 w06 22725, 12873, 19266, -22725, // w22 w20 w18 w16 19266, 4520, -4520, -12873, // w23 w21 w19 w17 12873, 4520, 4520, 19266, // w30 w28 w26 w24 -22725, 19266, -12873, -22725, // w31 w29 w27 w25 //row1 22725, 22725, 29692, -12299, // w09 w01 w08 w00 22725, 22725, 12299, -29692, // w13 w05 w12 w04 22725, -22725, 12299, 29692, // w11 w03 w10 w02 -22725, 22725, -29692, -12299, // w15 w07 w14 w06 31521, 17855, 26722, -31521, // w22 w20 w18 w16 26722, 6270, -6270, -17855, // w23 w21 w19 w17 17855, 6270, 6270, 26722, // w30 w28 w26 w24 -31521, 26722, -17855, -31521, // w31 w29 w27 w25 //row2 21407, 21407, 27969, -11585, // w09 w01 w08 w00 21407, 21407, 11585, -27969, // w13 w05 w12 w04 21407, -21407, 11585, 27969, // w11 w03 w10 w02 -21407, 21407, -27969, -11585, // w15 w07 w14 w06 29692, 16819, 25172, -29692, // w22 w20 w18 w16 25172, 5906, -5906, -16819, // w23 w21 w19 w17 16819, 5906, 5906, 25172, // w30 w28 w26 w24 -29692, 25172, -16819, -29692, // w31 w29 w27 w25 //row3 19266, 19266, 25172, -10426, // w09 w01 w08 w00 19266, 19266, 10426, -25172, // w13 w05 w12 w04 19266, -19266, 10426, 25172, // w11 w03 w10 w02 -19266, 19266, -25172, -10426, // w15 w07 w14 w06, 26722, 15137, 22654, -26722, // w22 w20 w18 w16 22654, 5315, -5315, -15137, // w23 w21 w19 w17 15137, 5315, 5315, 22654, // w30 w28 w26 w24 -26722, 22654, -15137, -26722, // w31 w29 w27 w25, //row4 16384, 16384, 21407, -8867, // w09 w01 w08 w00 16384, 16384, 8867, -21407, // w13 w05 w12 w04 16384, -16384, 8867, 21407, // w11 w03 w10 w02 -16384, 16384, -21407, -8867, // w15 w07 w14 w06 22725, 12873, 19266, -22725, // w22 w20 w18 w16 19266, 4520, -4520, -12873, // w23 w21 w19 w17 12873, 4520, 4520, 19266, // w30 w28 w26 w24 -22725, 19266, -12873, -22725, // w31 w29 w27 w25 //row5 19266, 19266, 25172, -10426, // w09 w01 w08 w00 19266, 19266, 10426, -25172, // w13 w05 w12 w04 19266, -19266, 10426, 25172, // w11 w03 w10 w02 -19266, 19266, -25172, -10426, // w15 w07 w14 w06 26722, 15137, 22654, -26722, // w22 w20 w18 w16 22654, 5315, -5315, -15137, // w23 w21 w19 w17 15137, 5315, 5315, 22654, // w30 w28 w26 w24 -26722, 22654, -15137, -26722, // w31 w29 w27 w25 //row6 21407, 21407, 27969, -11585, // w09 w01 w08 w00 21407, 21407, 11585, -27969, // w13 w05 w12 w04 21407, -21407, 11585, 27969, // w11 w03 w10 w02 -21407, 21407, -27969, -11585, // w15 w07 w14 w06, 29692, 16819, 25172, -29692, // w22 w20 w18 w16 25172, 5906, -5906, -16819, // w23 w21 w19 w17 16819, 5906, 5906, 25172, // w30 w28 w26 w24 -29692, 25172, -16819, -29692, // w31 w29 w27 w25, //row7 22725, 22725, 29692, -12299, // w09 w01 w08 w00 22725, 22725, 12299, -29692, // w13 w05 w12 w04 22725, -22725, 12299, 29692, // w11 w03 w10 w02 -22725, 22725, -29692, -12299, // w15 w07 w14 w06, 31521, 17855, 26722, -31521, // w22 w20 w18 w16 26722, 6270, -6270, -17855, // w23 w21 w19 w17 17855, 6270, 6270, 26722, // w30 w28 w26 w24 -31521, 26722, -17855, -31521 // w31 w29 w27 w25 }; // // Unfortunately with gcc, code like "psubw mm2,_128mm" is considered like non PIC // and the scanelf utility complains about this. This is also a problem for distribution like // Debian. Why, I don't know !! // This is a known problem and some WEB page have been written relatedto this issue. // I have used the page http://www.gentoo.org/proj/en/hardened/pic-fix-guide.xml // Within this page, they give 3 pssobilities to remove this kind of code. // I have use case number 1. Case number 2 and 3 are not really usable because // all the registers are already used (Not in all functions but in most of them) // Therefore, every variable defined previously are "manually" loaded into the MMX registers // using the stack as temporary storage // // 13036 -> 0x32ec // 27146 -> 0x6a0a // -21746 -> 0xab0e // -19195 -> 0xb505 // 23170 -> 0x5a82 // // This problem is the reason of all the following macros. // It's not a nice way to solve it> When we will have time, we will // try to find a cleaner solution // #ifndef _WINDOWS #ifdef __PIC__ #define por_one_mmx_reg(REG1) \ "push 0x00010001 \n" \ "push 0x00010001 \n" \ "por "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define add_round_mmx_reg(REG1) \ "push 0x00010000 \n" \ "push 0x00010000 \n" \ "paddd "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mov_tg_1_16_mmx_reg(REG1) \ "push 0x32ec32ec \n" \ "push 0x32ec32ec \n" \ "movq "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mov_tg_2_16_mmx_reg(REG1) \ "push 0x6a0a6a0a \n" \ "push 0x6a0a6a0a \n" \ "movq "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mov_tg_3_16_mmx_reg(REG1) \ "push 0xab0eab0e \n" \ "push 0xab0eab0e \n" \ "movq "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mov_ocos_4_16_mmx_reg(REG1) \ "push 0x5a825a82 \n" \ "push 0x5a825a82 \n" \ "movq "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mul_tg_1_16_mmx_reg(REG1) \ "push 0x32ec32ec \n" \ "push 0x32ec32ec \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mul_tg_2_16_mmx_reg(REG1) \ "push 0x6a0a6a0a \n" \ "push 0x6a0a6a0a \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mul_tg_3_16_mmx_reg(REG1) \ "push 0xab0eab0e \n" \ "push 0xab0eab0e \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #define mul_ocos_4_16_mmx_reg(REG1) \ "push 0x5a825a82 \n" \ "push 0x5a825a82 \n" \ "pmulhw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #if __GNUC__ > 3 #define lea_addr_in_reg(REG1) \ "call __i686.get_pc_thunk.bx \n" \ "add ebx,_GLOBAL_OFFSET_TABLE_ \n" \ "lea "#REG1",__jpmm_row_tab_frw@GOTOFF \n" #else #define lea_addr_in_reg(REG1) \ "call __tg_get_pc \n" \ "add ebx,_GLOBAL_OFFSET_TABLE_ \n" \ "lea "#REG1",__jpmm_row_tab_frw@GOTOFF \n" #endif #else /* __PIC__ */ #define por_one_mmx_reg(REG1) \ "por "#REG1", __jpmm_one_corr \n" #define add_round_mmx_reg(REG1) \ "paddd "#REG1", __jpmm_round_frw_row \n" #define mov_tg_1_16_mmx_reg(REG1) \ "movq "#REG1", __jpmm_tg_1_16 \n" #define mov_tg_2_16_mmx_reg(REG1) \ "movq "#REG1", __jpmm_tg_2_16 \n" #define mov_tg_3_16_mmx_reg(REG1) \ "movq "#REG1", __jpmm_tg_3_16 \n" #define mov_ocos_4_16_mmx_reg(REG1) \ "movq "#REG1", __jpmm_ocos_4_16 \n" #define mul_tg_1_16_mmx_reg(REG1) \ "pmulhw "#REG1", __jpmm_tg_1_16 \n" #define mul_tg_2_16_mmx_reg(REG1) \ "pmulhw "#REG1", __jpmm_tg_2_16 \n" #define mul_tg_3_16_mmx_reg(REG1) \ "pmulhw "#REG1", __jpmm_tg_3_16 \n" #define mul_ocos_4_16_mmx_reg(REG1) \ "pmulhw "#REG1", __jpmm_ocos_4_16 \n" #define lea_addr_in_reg(REG1) \ "lea "#REG1",__jpmm_row_tab_frw \n" #endif /* __PIC__ */ #endif /* _WINDOWS */ void jpeg_fdct_mmx( short *block ) { #ifdef _WINDOWS // Visual C++ inline assembly code __asm { // Columns mov eax, block lea ebx, __jpmm_row_tab_frw mov ecx, eax movq mm0, [eax + 1*16] //; 0 ; x1 movq mm1, [eax + 6*16] //; 1 ; x6 movq mm2, mm0 //; 2 ; x1 movq mm3, [eax + 2*16] //; 3 ; x2 paddsw mm0, mm1 //; t1 = x[1] + x[6] movq mm4, [eax + 5*16] //; 4 ; x5 psllw mm0, SHIFT_FRW_COL //; t1 movq mm5, [eax + 0*16] //; 5 ; x0 paddsw mm4, mm3 //; t2 = x[2] + x[5] paddsw mm5, [eax + 7*16] // t0 = x[0] + x[7] psllw mm4, SHIFT_FRW_COL // t2 movq mm6, mm0 // 6 ; t1 psubsw mm2, mm1 // 1 ; t6 = x[1] - x[6] movq mm1, __jpmm_tg_2_16 // 1 ; tg_2_16 psubsw mm0, mm4 // tm12 = t1 - t2 movq mm7, [eax + 3*16] // 7 ; x3 pmulhw mm1, mm0 // tm12*tg_2_16 paddsw mm7, [eax + 4*16] // t3 = x[3] + x[4] psllw mm5, SHIFT_FRW_COL // t0 paddsw mm6, mm4 // 4 ; tp12 = t1 + t2 psllw mm7, SHIFT_FRW_COL // t3 movq mm4, mm5 // 4 ; t0 psubsw mm5, mm7 // tm03 = t0 - t3 paddsw mm1, mm5 // y2 = tm03 + tm12*tg_2_16 paddsw mm4, mm7 // 7 ; tp03 = t0 + t3 por mm1, __jpmm_one_corr // correction y2 +0.5 psllw mm2, SHIFT_FRW_COL+1 // t6 pmulhw mm5, __jpmm_tg_2_16 // tm03*tg_2_16 movq mm7, mm4 // 7 // tp03 psubsw mm3, [eax + 5*16] // t5 = x[2] - x[5] psubsw mm4, mm6 // y4 = tp03 - tp12 movq [ecx + 2*16], mm1 // 1 // save y2 paddsw mm7, mm6 // 6 // y0 = tp03 + tp12 movq mm1, [eax + 3*16] // 1 // x3 psllw mm3, SHIFT_FRW_COL+1 // t5 psubsw mm1, [eax + 4*16] // t4 = x[3] - x[4] movq mm6, mm2 // 6 // t6 movq [ecx + 4*16], mm4 // 4 // save y4 paddsw mm2, mm3 // t6 + t5 pmulhw mm2, __jpmm_ocos_4_16 // tp65 = (t6 + t5)*cos_4_16 psubsw mm6, mm3 // 3 // t6 - t5 pmulhw mm6, __jpmm_ocos_4_16 // tm65 = (t6 - t5)*cos_4_16 psubsw mm5, mm0 // 0 // y6 = tm03*tg_2_16 - tm12 por mm5, __jpmm_one_corr // correction y6 +0.5 psllw mm1, SHIFT_FRW_COL // t4 por mm2, __jpmm_one_corr // correction tp65 +0.5 movq mm4, mm1 // 4 // t4 movq mm3, [eax + 0*16] // 3 // x0 paddsw mm1, mm6 // tp465 = t4 + tm65 psubsw mm3, [eax + 7*16] // t7 = x[0] - x[7] psubsw mm4, mm6 // 6 // tm465 = t4 - tm65 movq mm0, __jpmm_tg_1_16 // 0 // tg_1_16 psllw mm3, SHIFT_FRW_COL // t7 movq mm6, __jpmm_tg_3_16 // 6 // tg_3_16 pmulhw mm0, mm1 // tp465*tg_1_16 movq [ecx + 0*16], mm7 // 7 // save y0 pmulhw mm6, mm4 // tm465*tg_3_16 movq [ecx + 6*16], mm5 // 5 // save y6 movq mm7, mm3 // 7 // t7 movq mm5, __jpmm_tg_3_16 // 5 // tg_3_16 psubsw mm7, mm2 // tm765 = t7 - tp65 paddsw mm3, mm2 // 2 // tp765 = t7 + tp65 pmulhw mm5, mm7 // tm765*tg_3_16 paddsw mm0, mm3 // y1 = tp765 + tp465*tg_1_16 paddsw mm6, mm4 // tm465*tg_3_16 pmulhw mm3, __jpmm_tg_1_16 // tp765*tg_1_16 por mm0, __jpmm_one_corr // correction y1 +0.5 paddsw mm5, mm7 // tm765*tg_3_16 psubsw mm7, mm6 // 6 // y3 = tm765 - tm465*tg_3_16 add eax, 0x08 // // increment pointer movq [ecx + 1*16], mm0 // 0 // save y1 paddsw mm5, mm4 // 4 // y5 = tm765*tg_3_16 + tm465 movq [ecx + 3*16], mm7 // 7 // save y3 psubsw mm3, mm1 // 1 // y7 = tp765*tg_1_16 - tp465 movq [ecx + 5*16], mm5 // 5 // save y5 movq mm0, [eax + 1*16] // 0 // x1 movq [ecx + 7*16], mm3 // 3 // save y7 (columns 0-4) movq mm1, [eax + 6*16] // 1 // x6 movq mm2, mm0 // 2 // x1 movq mm3, [eax + 2*16] // 3 // x2 paddsw mm0, mm1 // t1 = x[1] + x[6] movq mm4, [eax + 5*16] // 4 // x5 psllw mm0, SHIFT_FRW_COL // t1 movq mm5, [eax + 0*16] // 5 // x0 paddsw mm4, mm3 // t2 = x[2] + x[5] paddsw mm5, [eax + 7*16] // t0 = x[0] + x[7] psllw mm4, SHIFT_FRW_COL // t2 movq mm6, mm0 // 6 // t1 psubsw mm2, mm1 // 1 // t6 = x[1] - x[6] movq mm1, __jpmm_tg_2_16 // 1 // tg_2_16 psubsw mm0, mm4 // tm12 = t1 - t2 movq mm7, [eax + 3*16] // 7 // x3 pmulhw mm1, mm0 // tm12*tg_2_16 paddsw mm7, [eax + 4*16] // t3 = x[3] + x[4] psllw mm5, SHIFT_FRW_COL // t0 paddsw mm6, mm4 // 4 // tp12 = t1 + t2 psllw mm7, SHIFT_FRW_COL // t3 movq mm4, mm5 // 4 // t0 psubsw mm5, mm7 // tm03 = t0 - t3 paddsw mm1, mm5 // y2 = tm03 + tm12*tg_2_16 paddsw mm4, mm7 // 7 // tp03 = t0 + t3 por mm1, __jpmm_one_corr // correction y2 +0.5 psllw mm2, SHIFT_FRW_COL+1 // t6 pmulhw mm5, __jpmm_tg_2_16 // tm03*tg_2_16 movq mm7, mm4 // 7 // tp03 psubsw mm3, [eax + 5*16] // t5 = x[2] - x[5] psubsw mm4, mm6 // y4 = tp03 - tp12 movq [ecx + 2*16+8], mm1 // 1 // save y2 paddsw mm7, mm6 // 6 // y0 = tp03 + tp12 movq mm1, [eax + 3*16] // 1 // x3 psllw mm3, SHIFT_FRW_COL+1 // t5 psubsw mm1, [eax + 4*16] // t4 = x[3] - x[4] movq mm6, mm2 // 6 // t6 movq [ecx + 4*16+8], mm4 // 4 // save y4 paddsw mm2, mm3 // t6 + t5 pmulhw mm2, __jpmm_ocos_4_16 // tp65 = (t6 + t5)*cos_4_16 psubsw mm6, mm3 // 3 // t6 - t5 pmulhw mm6, __jpmm_ocos_4_16 // tm65 = (t6 - t5)*cos_4_16 psubsw mm5, mm0 // 0 // y6 = tm03*tg_2_16 - tm12 por mm5, __jpmm_one_corr // correction y6 +0.5 psllw mm1, SHIFT_FRW_COL // t4 por mm2, __jpmm_one_corr // correction tp65 +0.5 movq mm4, mm1 // 4 // t4 movq mm3, [eax + 0*16] // 3 // x0 paddsw mm1, mm6 // tp465 = t4 + tm65 psubsw mm3, [eax + 7*16] // t7 = x[0] - x[7] psubsw mm4, mm6 // 6 // tm465 = t4 - tm65 movq mm0, __jpmm_tg_1_16 // 0 // tg_1_16 psllw mm3, SHIFT_FRW_COL // t7 movq mm6, __jpmm_tg_3_16 // 6 // tg_3_16 pmulhw mm0, mm1 // tp465*tg_1_16 movq [ecx +8], mm7 // 7 // save y0 pmulhw mm6, mm4 // tm465*tg_3_16 movq [ecx + 6*16+8], mm5 // 5 // save y6 movq mm7, mm3 // 7 // t7 movq mm5, __jpmm_tg_3_16 // 5 // tg_3_16 psubsw mm7, mm2 // tm765 = t7 - tp65 paddsw mm3, mm2 // 2 // tp765 = t7 + tp65 pmulhw mm5, mm7 // tm765*tg_3_16 paddsw mm0, mm3 // y1 = tp765 + tp465*tg_1_16 paddsw mm6, mm4 // tm465*tg_3_16 pmulhw mm3, __jpmm_tg_1_16 // tp765*tg_1_16 por mm0, __jpmm_one_corr // correction y1 +0.5 paddsw mm5, mm7 // tm765*tg_3_16 psubsw mm7, mm6 // 6 // y3 = tm765 - tm465*tg_3_16 movq [ecx + 1*16+8], mm0 // 0 // save y1 paddsw mm5, mm4 // 4 // y5 = tm765*tg_3_16 + tm465 movq [ecx + 3*16+8], mm7 // 7 // save y3 psubsw mm3, mm1 // 1 // y7 = tp765*tg_1_16 - tp465 movq [ecx + 5*16+8], mm5 // 5 // save y5 movq [ecx + 7*16+8], mm3 // 3 // save y7 // Rows ----------------------------------------------------------------- mov eax, block mov edi, 0x08 lp_mmx_fdct_row1: movd mm5, dword ptr [eax+12]// // mm5 = 7 6 punpcklwd mm5, qword ptr [eax+8] // mm5 = 5 7 4 6 movq mm2, mm5// // mm2 = 5 7 4 6 psrlq mm5, 32// // mm5 = _ _ 5 7 movq mm0, qword ptr [eax]// // mm0 = 3 2 1 0 punpcklwd mm5, mm2//// mm5 = 4 5 6 7 movq mm1, mm0// // mm1 = 3 2 1 0 paddsw mm0, mm5// // mm0 = [3+4, 2+5, 1+6, 0+7] (xt3, xt2, xt1, xt0) psubsw mm1, mm5// // mm1 = [3-4, 2-5, 1-6, 0-7] (xt7, xt6, xt5, xt4) movq mm2, mm0// // mm2 = [ xt3 xt2 xt1 xt0 ] punpcklwd mm0, mm1//// mm0 = [ xt5 xt1 xt4 xt0 ] punpckhwd mm2, mm1//// mm2 = [ xt7 xt3 xt6 xt2 ] movq mm1, mm2// // mm1 //// shuffle bytes around movq mm2, mm0 // 2 // x3 x2 x1 x0 movq mm3, qword ptr [ebx] // 3 // w06 w04 w02 w00 punpcklwd mm0, mm1 // x5 x1 x4 x0 movq mm5, mm0 // 5 // x5 x1 x4 x0 punpckldq mm0, mm0 // x4 x0 x4 x0 [ xt2 xt0 xt2 xt0 ] movq mm4, qword ptr [ebx+8] // 4 // w07 w05 w03 w01 punpckhwd mm2, mm1 // 1 // x7 x3 x6 x2 pmaddwd mm3, mm0 // x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 // 6 // x7 x3 x6 x2 movq mm1, qword ptr [ebx+32] // 1 // w22 w20 w18 w16 punpckldq mm2, mm2 // x6 x2 x6 x2 [ xt3 xt1 xt3 xt1 ] pmaddwd mm4, mm2 // x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 // x5 x1 x5 x1 [ xt6 xt4 xt6 xt4 ] pmaddwd mm0, qword ptr [ebx+16] // x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 // x7 x3 x7 x3 [ xt7 xt5 xt7 xt5 ] movq mm7, qword ptr [ebx+40] // 7 // w23 w21 w19 w17 pmaddwd mm1, mm5 // x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, __jpmm_round_frw_row // +rounder (y2,y0) pmaddwd mm7, mm6 // x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, qword ptr [ebx+24] // x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 // 4 // a1=sum(even1) a0=sum(even0) // now ( y2, y0) pmaddwd mm5, qword ptr [ebx+48] // x5*w30+x1*w28 x5*w26+x1*w24 pmaddwd mm6, qword ptr [ebx+56] // x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 // 7 // b1=sum(odd1) b0=sum(odd0) // now ( y3, y1) paddd mm0, __jpmm_round_frw_row // +rounder (y6,y4) psrad mm3, SHIFT_FRW_ROW // (y2, y0) paddd mm1, __jpmm_round_frw_row // +rounder (y3,y1) paddd mm0, mm2 // 2 // a3=sum(even3) a2=sum(even2) // now (y6, y4) paddd mm5, __jpmm_round_frw_row // +rounder (y7,y5) psrad mm1, SHIFT_FRW_ROW // y1=a1+b1 y0=a0+b0 paddd mm5, mm6 // 6 // b3=sum(odd3) b2=sum(odd2) // now ( y7, y5) psrad mm0, SHIFT_FRW_ROW //y3=a3+b3 y2=a2+b2 add ecx, 16// // increment row-output address by 1 row psrad mm5, SHIFT_FRW_ROW // y4=a3-b3 y5=a2-b2 add eax, 16// // increment row-address by 1 row packssdw mm3, mm0 // 0 // y6 y4 y2 y0 packssdw mm1, mm5 // 3 // y7 y5 y3 y1 movq mm6, mm3// // mm0 = y6 y4 y2 y0 punpcklwd mm3, mm1// // y3 y2 y1 y0 sub edi, 0x01// // i = i - 1 punpckhwd mm6, mm1// // y7 y6 y5 y4 add ebx,64// // increment to next table movq qword ptr [ecx-16], mm3 // 1 // save y3 y2 y1 y0 movq qword ptr [ecx-8], mm6 // 7 // save y7 y6 y5 y4 cmp edi, 0x00// jg lp_mmx_fdct_row1// // begin fdct processing on next row emms// } #else #ifdef _64BITS // gcc inline assembly code (64bits) // Columns __asm__ ( ".intel_syntax noprefix \n" "mov rcx, rax \n" "movq mm0, [rax + 1*16] \n" "movq mm1, [rax + 6*16] \n" "movq mm2, mm0 \n" "movq mm3, [rax + 2*16] \n" "paddsw mm0, mm1 \n" "movq mm4, [rax + 5*16] \n" "psllw mm0, 3 \n" "movq mm5, [rax + 0*16] \n" "paddsw mm4, mm3 \n" "paddsw mm5, [rax + 7*16] \n" "psllw mm4, 3 \n" "movq mm6, mm0 \n" "psubsw mm2, mm1 \n" mov_tg_2_16_mmx_reg(mm1) "psubsw mm0, mm4 \n" "movq mm7, [rax + 3*16] \n" "pmulhw mm1, mm0 \n" "paddsw mm7, [rax + 4*16] \n" "psllw mm5, 3 \n" "paddsw mm6, mm4 \n" "psllw mm7, 3 \n" "movq mm4, mm5 \n" "psubsw mm5, mm7 \n" "paddsw mm1, mm5 \n" "paddsw mm4, mm7 \n" por_one_mmx_reg(mm1) "psllw mm2, 4 \n" mul_tg_2_16_mmx_reg(mm5) "movq mm7, mm4 \n" "psubsw mm3, [rax + 5*16] \n" "psubsw mm4, mm6 \n" "movq [rcx + 2*16], mm1 \n" "paddsw mm7, mm6 \n" "movq mm1, [rax + 3*16] \n" "psllw mm3, 4 \n" "psubsw mm1, [rax + 4*16] \n" "movq mm6, mm2 \n" "movq [rcx + 4*16], mm4 \n" "paddsw mm2, mm3 \n" mul_ocos_4_16_mmx_reg(mm2) "psubsw mm6, mm3 \n" mul_ocos_4_16_mmx_reg(mm6) "psubsw mm5, mm0 \n" por_one_mmx_reg(mm5) "psllw mm1, 3 \n" por_one_mmx_reg(mm2) "movq mm4, mm1 \n" "movq mm3, [rax + 0*16] \n" "paddsw mm1, mm6 \n" "psubsw mm3, [rax + 7*16] \n" "psubsw mm4, mm6 \n" mov_tg_1_16_mmx_reg(mm0) "psllw mm3, 3 \n" mov_tg_3_16_mmx_reg(mm6) "pmulhw mm0, mm1 \n" "movq [rcx + 0*16], mm7 \n" "pmulhw mm6, mm4 \n" "movq [rcx + 6*16], mm5 \n" "movq mm7, mm3 \n" mov_tg_3_16_mmx_reg(mm5) "psubsw mm7, mm2 \n" "paddsw mm3, mm2 \n" "pmulhw mm5, mm7 \n" "paddsw mm0, mm3 \n" "paddsw mm6, mm4 \n" mul_tg_1_16_mmx_reg(mm3) por_one_mmx_reg(mm0) "paddsw mm5, mm7 \n" "psubsw mm7, mm6 \n" "add rax, 0x08 \n" "movq [rcx + 1*16], mm0 \n" "paddsw mm5, mm4 \n" "movq [rcx + 3*16], mm7 \n" "psubsw mm3, mm1 \n" "movq [rcx + 5*16], mm5 \n" "movq mm0, [rax + 1*16] \n" "movq [rcx + 7*16], mm3 \n" "movq mm1, [rax + 6*16] \n" "movq mm2, mm0 \n" "movq mm3, [rax + 2*16] \n" "paddsw mm0, mm1 \n" "movq mm4, [rax + 5*16] \n" "psllw mm0, 3 \n" "movq mm5, [rax + 0*16] \n" "paddsw mm4, mm3 \n" "paddsw mm5, [rax + 7*16] \n" "psllw mm4, 3 \n" "movq mm6, mm0 \n" "psubsw mm2, mm1 \n" mov_tg_2_16_mmx_reg(mm1) "psubsw mm0, mm4 \n" "movq mm7, [rax + 3*16] \n" "pmulhw mm1, mm0 \n" "paddsw mm7, [rax + 4*16] \n" "psllw mm5, 3 \n" "paddsw mm6, mm4 \n" "psllw mm7, 3 \n" "movq mm4, mm5 \n" "psubsw mm5, mm7 \n" "paddsw mm1, mm5 \n" "paddsw mm4, mm7 \n" por_one_mmx_reg(mm1) "psllw mm2, 4 \n" mul_tg_2_16_mmx_reg(mm5) "movq mm7, mm4 \n" "psubsw mm3, [rax + 5*16] \n" "psubsw mm4, mm6 \n" "movq [rcx + 2*16+8], mm1 \n" "paddsw mm7, mm6 \n" "movq mm1, [rax + 3*16] \n" "psllw mm3, 3+1 \n" "psubsw mm1, [rax + 4*16] \n" "movq mm6, mm2 \n" "movq [rcx + 4*16+8], mm4 \n" "paddsw mm2, mm3 \n" mul_ocos_4_16_mmx_reg(mm2) "psubsw mm6, mm3 \n" mul_ocos_4_16_mmx_reg(mm6) "psubsw mm5, mm0 \n" por_one_mmx_reg(mm5) "psllw mm1, 3 \n" por_one_mmx_reg(mm2) "movq mm4, mm1 \n" "movq mm3, [rax + 0*16] \n" "paddsw mm1, mm6 \n" "psubsw mm3, [rax + 7*16] \n" "psubsw mm4, mm6 \n" mov_tg_1_16_mmx_reg(mm0) "psllw mm3, 3 \n" mov_tg_3_16_mmx_reg(mm6) "pmulhw mm0, mm1 \n" "movq [rcx +8], mm7 \n" "pmulhw mm6, mm4 \n" "movq [rcx + 6*16+8], mm5 \n" "movq mm7, mm3 \n" mov_tg_3_16_mmx_reg(mm5) "psubsw mm7, mm2 \n" "paddsw mm3, mm2 \n" "pmulhw mm5, mm7 \n" "paddsw mm0, mm3 \n" "paddsw mm6, mm4 \n" mul_tg_1_16_mmx_reg(mm3) por_one_mmx_reg(mm0) "paddsw mm5, mm7 \n" "psubsw mm7, mm6 \n" "movq [rcx + 1*16+8], mm0 \n" "paddsw mm5, mm4 \n" "movq [rcx + 3*16+8], mm7 \n" "psubsw mm3, mm1 \n" "movq [rcx + 5*16+8], mm5 \n" "movq [rcx + 7*16+8], mm3 \n" ".att_syntax \n" : /* no output */ : "a"(block) : "memory","rcx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); // Rows __asm__ ( ".intel_syntax noprefix \n" "push rbx \n" lea_addr_in_reg(rbx) "mov rcx, rax \n" "mov rdi, 0x08 \n" "lp_mmx_fdct_row1: \n" "movd mm5, [rax+12] \n" "punpcklwd mm5, [rax+8] \n" "movq mm2, mm5 \n" "psrlq mm5, 32 \n" "movq mm0, [rax] \n" "punpcklwd mm5, mm2 \n" "movq mm1, mm0 \n" "paddsw mm0, mm5 \n" "psubsw mm1, mm5 \n" "movq mm2, mm0 \n" "punpcklwd mm0, mm1 \n" "punpckhwd mm2, mm1 \n" "movq mm1, mm2 \n" "movq mm2, mm0 \n" "movq mm3, [rbx] \n" "punpcklwd mm0, mm1 \n" "movq mm5, mm0 \n" "punpckldq mm0, mm0 \n" "movq mm4, [rbx+8] \n" "punpckhwd mm2, mm1 \n" "pmaddwd mm3, mm0 \n" "movq mm6, mm2 \n" "movq mm1, [rbx+32] \n" "punpckldq mm2, mm2 \n" "pmaddwd mm4, mm2 \n" "punpckhdq mm5, mm5 \n" "pmaddwd mm0, [rbx+16] \n" "punpckhdq mm6, mm6 \n" "movq mm7, [rbx+40] \n" "pmaddwd mm1, mm5 \n" add_round_mmx_reg(mm3) "pmaddwd mm7, mm6 \n" "pmaddwd mm2, [rbx+24] \n" "paddd mm3, mm4 \n" "pmaddwd mm5, [rbx+48] \n" "pmaddwd mm6, [rbx+56] \n" "paddd mm1, mm7 \n" add_round_mmx_reg(mm0) "psrad mm3, 17 \n" add_round_mmx_reg(mm1) "paddd mm0, mm2 \n" add_round_mmx_reg(mm5) "psrad mm1, 17 \n" "paddd mm5, mm6 \n" "psrad mm0, 17 \n" "add rcx, 16 \n" "psrad mm5, 17 \n" "add rax, 16 \n" "packssdw mm3, mm0 \n" "packssdw mm1, mm5 \n" "movq mm6, mm3 \n" "punpcklwd mm3, mm1 \n" "sub rdi, 0x01 \n" "punpckhwd mm6, mm1 \n" "add rbx,64 \n" "movq [rcx-16], mm3 \n" "movq [rcx-8], mm6 \n" "cmp rdi, 0x00 \n" "jg lp_mmx_fdct_row1 \n" "pop rbx \n" "emms \n" ".att_syntax \n" : /* no output */ : "a"(block) : "memory","rcx","rdi","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #else // gcc inline assembly code (32bits) // Columns __asm__ ( ".intel_syntax noprefix \n" "mov ecx, eax \n" "movq mm0, [eax + 1*16] \n" "movq mm1, [eax + 6*16] \n" "movq mm2, mm0 \n" "movq mm3, [eax + 2*16] \n" "paddsw mm0, mm1 \n" "movq mm4, [eax + 5*16] \n" "psllw mm0, 3 \n" "movq mm5, [eax + 0*16] \n" "paddsw mm4, mm3 \n" "paddsw mm5, [eax + 7*16] \n" "psllw mm4, 3 \n" "movq mm6, mm0 \n" "psubsw mm2, mm1 \n" mov_tg_2_16_mmx_reg(mm1) "psubsw mm0, mm4 \n" "movq mm7, [eax + 3*16] \n" "pmulhw mm1, mm0 \n" "paddsw mm7, [eax + 4*16] \n" "psllw mm5, 3 \n" "paddsw mm6, mm4 \n" "psllw mm7, 3 \n" "movq mm4, mm5 \n" "psubsw mm5, mm7 \n" "paddsw mm1, mm5 \n" "paddsw mm4, mm7 \n" por_one_mmx_reg(mm1) "psllw mm2, 4 \n" mul_tg_2_16_mmx_reg(mm5) "movq mm7, mm4 \n" "psubsw mm3, [eax + 5*16] \n" "psubsw mm4, mm6 \n" "movq [ecx + 2*16], mm1 \n" "paddsw mm7, mm6 \n" "movq mm1, [eax + 3*16] \n" "psllw mm3, 3+1 \n" "psubsw mm1, [eax + 4*16] \n" "movq mm6, mm2 \n" "movq [ecx + 4*16], mm4 \n" "paddsw mm2, mm3 \n" mul_ocos_4_16_mmx_reg(mm2) "psubsw mm6, mm3 \n" mul_ocos_4_16_mmx_reg(mm6) "psubsw mm5, mm0 \n" por_one_mmx_reg(mm5) "psllw mm1, 3 \n" por_one_mmx_reg(mm2) "movq mm4, mm1 \n" "movq mm3, [eax + 0*16] \n" "paddsw mm1, mm6 \n" "psubsw mm3, [eax + 7*16] \n" "psubsw mm4, mm6 \n" mov_tg_1_16_mmx_reg(mm0) "psllw mm3, 3 \n" mov_tg_3_16_mmx_reg(mm6) "pmulhw mm0, mm1 \n" "movq [ecx + 0*16], mm7 \n" "pmulhw mm6, mm4 \n" "movq [ecx + 6*16], mm5 \n" "movq mm7, mm3 \n" mov_tg_3_16_mmx_reg(mm5) "psubsw mm7, mm2 \n" "paddsw mm3, mm2 \n" "pmulhw mm5, mm7 \n" "paddsw mm0, mm3 \n" "paddsw mm6, mm4 \n" mul_tg_1_16_mmx_reg(mm3) por_one_mmx_reg(mm0) "paddsw mm5, mm7 \n" "psubsw mm7, mm6 \n" "add eax, 0x08 \n" "movq [ecx + 1*16], mm0 \n" "paddsw mm5, mm4 \n" "movq [ecx + 3*16], mm7 \n" "psubsw mm3, mm1 \n" "movq [ecx + 5*16], mm5 \n" "movq mm0, [eax + 1*16] \n" "movq [ecx + 7*16], mm3 \n" "movq mm1, [eax + 6*16] \n" "movq mm2, mm0 \n" "movq mm3, [eax + 2*16] \n" "paddsw mm0, mm1 \n" "movq mm4, [eax + 5*16] \n" "psllw mm0, 3 \n" "movq mm5, [eax + 0*16] \n" "paddsw mm4, mm3 \n" "paddsw mm5, [eax + 7*16] \n" "psllw mm4, 3 \n" "movq mm6, mm0 \n" "psubsw mm2, mm1 \n" mov_tg_2_16_mmx_reg(mm1) "psubsw mm0, mm4 \n" "movq mm7, [eax + 3*16] \n" "pmulhw mm1, mm0 \n" "paddsw mm7, [eax + 4*16] \n" "psllw mm5, 3 \n" "paddsw mm6, mm4 \n" "psllw mm7, 3 \n" "movq mm4, mm5 \n" "psubsw mm5, mm7 \n" "paddsw mm1, mm5 \n" "paddsw mm4, mm7 \n" por_one_mmx_reg(mm1) "psllw mm2, 4 \n" mul_tg_2_16_mmx_reg(mm5) "movq mm7, mm4 \n" "psubsw mm3, [eax + 5*16] \n" "psubsw mm4, mm6 \n" "movq [ecx + 2*16+8], mm1 \n" "paddsw mm7, mm6 \n" "movq mm1, [eax + 3*16] \n" "psllw mm3, 3+1 \n" "psubsw mm1, [eax + 4*16] \n" "movq mm6, mm2 \n" "movq [ecx + 4*16+8], mm4 \n" "paddsw mm2, mm3 \n" mul_ocos_4_16_mmx_reg(mm2) "psubsw mm6, mm3 \n" mul_ocos_4_16_mmx_reg(mm6) "psubsw mm5, mm0 \n" por_one_mmx_reg(mm5) "psllw mm1, 3 \n" por_one_mmx_reg(mm5) "movq mm4, mm1 \n" "movq mm3, [eax + 0*16] \n" "paddsw mm1, mm6 \n" "psubsw mm3, [eax + 7*16] \n" "psubsw mm4, mm6 \n" mov_tg_1_16_mmx_reg(mm0) "psllw mm3, 3 \n" mov_tg_3_16_mmx_reg(mm6) "pmulhw mm0, mm1 \n" "movq [ecx +8], mm7 \n" "pmulhw mm6, mm4 \n" "movq [ecx + 6*16+8], mm5 \n" "movq mm7, mm3 \n" mov_tg_3_16_mmx_reg(mm5) "psubsw mm7, mm2 \n" "paddsw mm3, mm2 \n" "pmulhw mm5, mm7 \n" "paddsw mm0, mm3 \n" "paddsw mm6, mm4 \n" mul_tg_1_16_mmx_reg(mm3) por_one_mmx_reg(mm0) "paddsw mm5, mm7 \n" "psubsw mm7, mm6 \n" "movq [ecx + 1*16+8], mm0 \n" "paddsw mm5, mm4 \n" "movq [ecx + 3*16+8], mm7 \n" "psubsw mm3, mm1 \n" "movq [ecx + 5*16+8], mm5 \n" "movq [ecx + 7*16+8], mm3 \n" ".att_syntax \n" : /* no output */ : "a"(block) : "memory","ecx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #ifdef __PIC__ #if __GNUC__ > 3 __asm__( "push %ebx \n" "call __i686.get_pc_thunk.bx \n" "add $_GLOBAL_OFFSET_TABLE_, %ebx \n" "lea __jpmm_row_tab_frw@GOTOFF(%ebx),%ebx \n" ); #else __asm__( "push %ebx \n" "call __tg_get_pc \n" "add $_GLOBAL_OFFSET_TABLE_, %ebx \n" "lea __jpmm_row_tab_frw@GOTOFF(%ebx),%ebx \n" ); #endif #endif /* __PIC__ */ // Rows __asm__ ( ".intel_syntax noprefix \n" #ifndef __PIC__ "push ebx \n" "lea ebx,__jpmm_row_tab_frw \n" #endif "mov edi, 0x08 \n" "mov ecx, eax \n" "lp_mmx_fdct_row1: \n" "movd mm5, [eax+12] \n" "punpcklwd mm5, [eax+8] \n" "movq mm2, mm5 \n" "psrlq mm5, 32 \n" "movq mm0, [eax] \n" "punpcklwd mm5, mm2 \n" "movq mm1, mm0 \n" "paddsw mm0, mm5 \n" "psubsw mm1, mm5 \n" "movq mm2, mm0 \n" "punpcklwd mm0, mm1 \n" "punpckhwd mm2, mm1 \n" "movq mm1, mm2 \n" "movq mm2, mm0 \n" "movq mm3, [ebx] \n" "punpcklwd mm0, mm1 \n" "movq mm5, mm0 \n" "punpckldq mm0, mm0 \n" "movq mm4, [ebx+8] \n" "punpckhwd mm2, mm1 \n" "pmaddwd mm3, mm0 \n" "movq mm6, mm2 \n" "movq mm1, [ebx+32] \n" "punpckldq mm2, mm2 \n" "pmaddwd mm4, mm2 \n" "punpckhdq mm5, mm5 \n" "pmaddwd mm0, [ebx+16] \n" "punpckhdq mm6, mm6 \n" "movq mm7, [ebx+40] \n" "pmaddwd mm1, mm5 \n" add_round_mmx_reg(mm3) "pmaddwd mm7, mm6 \n" "pmaddwd mm2, [ebx+24] \n" "paddd mm3, mm4 \n" "pmaddwd mm5, [ebx+48] \n" "pmaddwd mm6, [ebx+56] \n" "paddd mm1, mm7 \n" add_round_mmx_reg(mm0) "psrad mm3, 17 \n" add_round_mmx_reg(mm1) "paddd mm0, mm2 \n" add_round_mmx_reg(mm5) "psrad mm1, 17 \n" "paddd mm5, mm6 \n" "psrad mm0, 17 \n" "add ecx, 16 \n" "psrad mm5, 17 \n" "add eax, 16 \n" "packssdw mm3, mm0 \n" "packssdw mm1, mm5 \n" "movq mm6, mm3 \n" "punpcklwd mm3, mm1 \n" "sub edi, 0x01 \n" "punpckhwd mm6, mm1 \n" "add ebx,64 \n" "movq [ecx-16], mm3 \n" "movq [ecx-8], mm6 \n" "cmp edi, 0x00 \n" "jg lp_mmx_fdct_row1 \n" "pop ebx \n" "emms \n" ".att_syntax \n" : /* no output */ : "a"(block) : "memory","ecx","edi","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #endif /* _64BITS */ #endif /* _WINDOWS */ } #define SHIFT_INV_ROW 11 #define SHIFT_INV_COL 6 ALIGN8 short __jpmm_row_tabs[] = { // Table for rows 0 - constants are multiplied by cos_4_16 16384, 16384, 16384, -16384, 21407, 8867, 8867, -21407, 16384, -16384, 16384, 16384, -8867, 21407, -21407, -8867, 22725, 12873, 19266, -22725, 19266, 4520, -4520, -12873, 12873, 4520, 4520, 19266, -22725, 19266, -12873, -22725, // Table for rows 1 - constants are multiplied by cos_1_16 22725, 22725, 22725, -22725, 29692, 12299, 12299, -29692, 22725, -22725, 22725, 22725, -12299, 29692, -29692, -12299, 31521, 17855, 26722, -31521, 26722, 6270, -6270, -17855, 17855, 6270, 6270, 26722, -31521, 26722, -17855, -31521, // Table for rows 2 - constants are multiplied by cos_2_16 21407, 21407, 21407, -21407, 27969, 11585, 11585, -27969, 21407, -21407, 21407, 21407, -11585, 27969, -27969, -11585, 29692, 16819, 25172, -29692, 25172, 5906, -5906, -16819, 16819, 5906, 5906, 25172, -29692, 25172, -16819, -29692, // Table for rows 3 - constants are multiplied by cos_3_16 19266, 19266, 19266, -19266, 25172, 10426, 10426, -25172, 19266, -19266, 19266, 19266, -10426, 25172, -25172, -10426, 26722, 15137, 22654, -26722, 22654, 5315, -5315, -15137, 15137, 5315, 5315, 22654, -26722, 22654, -15137, -26722, // Table for rows 4 - constants are multiplied by cos_4_16 16384, 16384, 16384, -16384, 21407, 8867, 8867, -21407, 16384, -16384, 16384, 16384, -8867, 21407, -21407, -8867, 22725, 12873, 19266, -22725, 19266, 4520, -4520, -12873, 12873, 4520, 4520, 19266, -22725, 19266, -12873, -22725, // Table for rows 5 - constants are multiplied by cos_3_16 19266, 19266, 19266, -19266, 25172, 10426, 10426, -25172, 19266, -19266, 19266, 19266, -10426, 25172, -25172, -10426, 26722, 15137, 22654, -26722, 22654, 5315, -5315, -15137, 15137, 5315, 5315, 22654, -26722, 22654, -15137, -26722, // Table for rows 6 - constants are multiplied by cos_2_16 21407, 21407, 21407, -21407, 27969, 11585, 11585, -27969, 21407, -21407, 21407, 21407, -11585, 27969, -27969, -11585, 29692, 16819, 25172, -29692, 25172, 5906, -5906, -16819, 16819, 5906, 5906, 25172, -29692, 25172, -16819, -29692, // Table for rows 7 - constants are multiplied by cos_1_16 22725, 22725, 22725, -22725, 29692, 12299, 12299, -29692, 22725, -22725, 22725, 22725, -12299, 29692, -29692, -12299, 31521, 17855, 26722, -31521, 26722, 6270, -6270, -17855, 17855, 6270, 6270, 26722, -31521, 26722, -17855, -31521 }; // Rounding ALIGN8 long __jpmm_rounder[] = { 65536, 65536 , 3597, 3597 , 2260, 2260 , 1203, 1203 , 0, 0 , 120, 120 , 512, 512 , 512, 512 }; // Offset ALIGN8 short __jpmm_offset128[] = { 128,128,128,128 }; #ifndef _WINDOWS #ifdef __PIC__ #define add_off128_mmx_reg(REG1) \ "push 0x00800080 \n" \ "push 0x00800080 \n" \ "paddw "#REG1", QWORD PTR [esp] \n" \ "add esp,8 \n" #if __GNUC__ > 3 #define lea_addr_in_regs(REG1,REG2) \ "push ebx \n" \ "call __i686.get_pc_thunk.bx \n" \ "add ebx,_GLOBAL_OFFSET_TABLE_ \n" \ "lea "#REG1",__jpmm_row_tabs@GOTOFF \n" \ "lea "#REG2",__jpmm_rounder@GOTOFF \n" \ "pop ebx \n" #else #define lea_addr_in_regs(REG1,REG2) \ "push ebx \n" \ "call __tg_get_pc \n" \ "add ebx,_GLOBAL_OFFSET_TABLE_ \n" \ "lea "#REG1",__jpmm_row_tabs@GOTOFF \n" \ "lea "#REG2",__jpmm_rounder@GOTOFF \n" \ "pop ebx \n" #endif #else /* __PIC__ */ #define add_off128_mmx_reg(REG1) \ "paddw "#REG1", __jpmm_offset128 \n" #define lea_addr_in_regs(REG1,REG2) \ "lea "#REG1",__jpmm_row_tabs \n" \ "lea "#REG2",__jpmm_rounder \n" \ #endif /* __PIC__ */ #endif /* _WINDOWS */ void jpeg_idct_mmx(short *block, unsigned char *dest) { short innerBuff[64]; long scratch[4]; #ifdef _WINDOWS // Visual C++ inline assembly code __asm { // Rows ------------------- mov esi, block lea edi, innerBuff lea eax, __jpmm_row_tabs lea ebx, __jpmm_rounder mov ecx, 8 __mmx_idct_rows: movq mm0, [esi] ; 0 ; x3 x2 x1 x0 movq mm1, [esi+8] ; 1 ; x7 x6 x5 x4 movq mm2, mm0 ; 2 ; x3 x2 x1 x0 movq mm3, [eax] ; 3 ; w06 w04 w02 w00 punpcklwd mm0, mm1 ; x5 x1 x4 x0 movq mm5, mm0 ; 5 ; x5 x1 x4 x0 punpckldq mm0, mm0 ; x4 x0 x4 x0 movq mm4, [eax+8] ; 4 ; w07 w05 w03 w01 punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 movq mm6, mm2 ; 6 ; x7 x3 x6 x2 movq mm1, [eax+32] ; 1 ; w22 w20 w18 w16 punpckldq mm2, mm2 ; x6 x2 x6 x2 pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 punpckhdq mm5, mm5 ; x5 x1 x5 x1 pmaddwd mm0, [eax+16] ; x4*w14+x0*w12 x4*w10+x0*w08 punpckhdq mm6, mm6 ; x7 x3 x7 x3 movq mm7, [eax+40] ; 7 ; w23 w21 w19 w17 pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 paddd mm3, [ebx] ; +rounder pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 pmaddwd mm2, [eax+24] ; x6*w15+x2*w13 x6*w11+x2*w09 paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) pmaddwd mm5, [eax+48] ; x5*w30+x1*w28 x5*w26+x1*w24 movq mm4, mm3 ; 4 ; a1 a0 pmaddwd mm6, [eax+56] ; x7*w31+x3*w29 x7*w27+x3*w25 paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) paddd mm0, [ebx] ; +rounder psubd mm3, mm1 ; a1-b1 a0-b0 psrad mm3, SHIFT_INV_ROW ; y6=a1-b1 y7=a0-b0 paddd mm1, mm4 ; 4 ; a1+b1 a0+b0 paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) psrad mm1, SHIFT_INV_ROW ; y1=a1+b1 y0=a0+b0 paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) movq mm4, mm0 ; 4 ; a3 a2 paddd mm0, mm5 ; a3+b3 a2+b2 psubd mm4, mm5 ; 5 ; a3-b3 a2-b2 psrad mm0, SHIFT_INV_ROW ; y3=a3+b3 y2=a2+b2 psrad mm4, SHIFT_INV_ROW ; y4=a3-b3 y5=a2-b2 packssdw mm1, mm0 ; 0 ; y3 y2 y1 y0 packssdw mm4, mm3 ; 3 ; y6 y7 y4 y5 movq mm7, mm4 ; 7 ; y6 y7 y4 y5 psrld mm4, 16 ; 0 y6 0 y4 pslld mm7, 16 ; y7 0 y5 0 movq [edi], mm1 ; 1 ; save y3 y2 y1 y0 por mm7, mm4 ; 4 ; y7 y6 y5 y4 movq [edi+8], mm7 ; 7 ; save y7 y6 y5 y4 add esi, 16 add edi, 16 add eax, 64 add ebx, 8 dec ecx jnz __mmx_idct_rows // Columns ------------------- lea esi, innerBuff mov edi, dest lea eax, scratch mov ecx, 2 __mmx_idct_cols: movq mm0, __jpmm_tg_3_16 movq mm3, [esi+16*3] movq mm1, mm0 ; tg_3_16 movq mm5, [esi+16*5] pmulhw mm0, mm3 ; x3*(tg_3_16-1) movq mm4, __jpmm_tg_1_16 pmulhw mm1, mm5 ; x5*(tg_3_16-1) movq mm7, [esi+16*7] movq mm2, mm4 ; tg_1_16 movq mm6, [esi+16*1] pmulhw mm4, mm7 ; x7*tg_1_16 paddsw mm0, mm3 ; x3*tg_3_16 pmulhw mm2, mm6 ; x1*tg_1_16 paddsw mm1, mm3 ; x3+x5*(tg_3_16-1) psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35 movq mm3, __jpmm_ocos_4_16 paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35 paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17 psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17 movq mm5, mm4 ; tp17 movq mm6, mm2 ; tm17 paddsw mm5, mm1 ; tp17+tp35 = b0 psubsw mm6, mm0 ; tm17-tm35 = b3 psubsw mm4, mm1 ; tp17-tp35 = t1 paddsw mm2, mm0 ; tm17+tm35 = t2 movq mm7, __jpmm_tg_2_16 movq mm1, mm4 ; t1 movq [eax+0], mm5 ; save b0 paddsw mm1, mm2 ; t1+t2 movq [eax+8], mm6 ; save b3 psubsw mm4, mm2 ; t1-t2 movq mm5, [esi+2*16] movq mm0, mm7 ; tg_2_16 movq mm6, [esi+6*16] pmulhw mm0, mm5 ; x2*tg_2_16 pmulhw mm7, mm6 ; x6*tg_2_16 pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2 movq mm2, [esi+0*16] pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2 psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26 movq mm3, mm2 ; x0 movq mm6, [esi+4*16] paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26 paddsw mm2, mm6 ; x0+x4 = tp04 psubsw mm3, mm6 ; x0-x4 = tm04 movq mm5, mm2 ; tp04 movq mm6, mm3 ; tm04 psubsw mm2, mm7 ; tp04-tp26 = a3 paddsw mm3, mm0 ; tm04+tm26 = a1 paddsw mm1, mm1 ; b1 paddsw mm4, mm4 ; b2 paddsw mm5, mm7 ; tp04+tp26 = a0 psubsw mm6, mm0 ; tm04-tm26 = a2 movq mm7, mm3 ; a1 movq mm0, mm6 ; a2 paddsw mm3, mm1 ; a1+b1 paddsw mm6, mm4 ; a2+b2 psraw mm3, SHIFT_INV_COL ; dst1 psubsw mm7, mm1 ; a1-b1 psraw mm6, SHIFT_INV_COL ; dst2 psubsw mm0, mm4 ; a2-b2 movq mm1, [eax+0] ; load b0 psraw mm7, SHIFT_INV_COL ; dst6 movq mm4, mm5 ; a0 psraw mm0, SHIFT_INV_COL ; dst5 paddw mm3,__jpmm_offset128 packuswb mm3,mm0 movd [edi+1*8], mm3 // R1 paddsw mm5, mm1 ; a0+b0 paddw mm6,__jpmm_offset128 packuswb mm6,mm0 movd [edi+2*8], mm6 // R2 psubsw mm4, mm1 ; a0-b0 movq mm3, [eax+8] ; load b3 psraw mm5, SHIFT_INV_COL ; dst0 movq mm6, mm2 ; a3 psraw mm4, SHIFT_INV_COL ; dst7 paddw mm0,__jpmm_offset128 packuswb mm0,mm1 movd [edi+5*8], mm0 // R5 paddsw mm2, mm3 ; a3+b3 paddw mm7,__jpmm_offset128 packuswb mm7,mm0 movd [edi+6*8], mm7 // R6 psubsw mm6, mm3 ; a3-b3 paddw mm5,__jpmm_offset128 packuswb mm5,mm0 movd [edi+0*8], mm5 // R0 psraw mm2, SHIFT_INV_COL ; dst3 paddw mm4,__jpmm_offset128 packuswb mm4,mm0 movd [edi+7*8], mm4 // R7 psraw mm6, SHIFT_INV_COL ; dst4 paddw mm2,__jpmm_offset128 packuswb mm2,mm0 movd [edi+3*8], mm2 // R3 paddw mm6,__jpmm_offset128 packuswb mm6,mm0 movd [edi+4*8], mm6 // R4 add edi,4 add esi,8 dec ecx jnz __mmx_idct_cols emms } #else #ifdef _64BITS // gcc inline assembly code (64bits) // Rows __asm__ ( ".intel_syntax noprefix \n" "push rbx \n" "mov rcx, 8 \n" lea_addr_in_regs(rax,rbx) "__mmx_idct_rows: \n" "movq mm0, [rsi] \n" "movq mm1, [rsi+8] \n" "movq mm2, mm0 \n" "movq mm3, [rax] \n" "punpcklwd mm0, mm1 \n" "movq mm5, mm0 \n" "punpckldq mm0, mm0 \n" "movq mm4, [rax+8] \n" "punpckhwd mm2, mm1 \n" "pmaddwd mm3, mm0 \n" "movq mm6, mm2 \n" "movq mm1, [rax+32] \n" "punpckldq mm2, mm2 \n" "pmaddwd mm4, mm2 \n" "punpckhdq mm5, mm5 \n" "pmaddwd mm0, [rax+16] \n" "punpckhdq mm6, mm6 \n" "movq mm7, [rax+40] \n" "pmaddwd mm1, mm5 \n" "paddd mm3, [rbx] \n" "pmaddwd mm7, mm6 \n" "pmaddwd mm2, [rax+24] \n" "paddd mm3, mm4 \n" "pmaddwd mm5, [rax+48] \n" "movq mm4, mm3 \n" "pmaddwd mm6, [rax+56] \n" "paddd mm1, mm7 \n" "paddd mm0, [rbx] \n" "psubd mm3, mm1 \n" "psrad mm3, 11 \n" "paddd mm1, mm4 \n" "paddd mm0, mm2 \n" "psrad mm1, 11 \n" "paddd mm5, mm6 \n" "movq mm4, mm0 \n" "paddd mm0, mm5 \n" "psubd mm4, mm5 \n" "psrad mm0, 11 \n" "psrad mm4, 11 \n" "packssdw mm1, mm0 \n" "packssdw mm4, mm3 \n" "movq mm7, mm4 \n" "psrld mm4, 16 \n" "pslld mm7, 16 \n" "movq [rdi], mm1 \n" "por mm7, mm4 \n" "movq [rdi+8], mm7 \n" "add rsi, 16 \n" "add rdi, 16 \n" "add rax, 64 \n" "add rbx, 8 \n" "dec rcx \n" "jnz __mmx_idct_rows \n" "pop rbx \n" ".att_syntax \n" : /* no output */ : "D"(innerBuff),"S"(block) : "memory","rax","rcx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); // Columns __asm__ ( ".intel_syntax noprefix \n" "mov rcx, 2 \n" "__mmx_idct_cols: \n" mov_tg_3_16_mmx_reg(mm0) "movq mm3, [rsi+16*3] \n" "movq mm1, mm0 \n" "movq mm5, [rsi+16*5] \n" "pmulhw mm0, mm3 \n" mov_tg_1_16_mmx_reg(mm4) "pmulhw mm1, mm5 \n" "movq mm7, [rsi+16*7] \n" "movq mm2, mm4 \n" "movq mm6, [rsi+16*1] \n" "pmulhw mm4, mm7 \n" "paddsw mm0, mm3 \n" "pmulhw mm2, mm6 \n" "paddsw mm1, mm3 \n" "psubsw mm0, mm5 \n" mov_ocos_4_16_mmx_reg(mm3) "paddsw mm1, mm5 \n" "paddsw mm4, mm6 \n" "psubsw mm2, mm7 \n" "movq mm5, mm4 \n" "movq mm6, mm2 \n" "paddsw mm5, mm1 \n" "psubsw mm6, mm0 \n" "psubsw mm4, mm1 \n" "paddsw mm2, mm0 \n" mov_tg_2_16_mmx_reg(mm7) "movq mm1, mm4 \n" "movq [rax+0], mm5 \n" "paddsw mm1, mm2 \n" "movq [rax+8], mm6 \n" "psubsw mm4, mm2 \n" "movq mm5, [rsi+2*16] \n" "movq mm0, mm7 \n" "movq mm6, [rsi+6*16] \n" "pmulhw mm0, mm5 \n" "pmulhw mm7, mm6 \n" "pmulhw mm1, mm3 \n" "movq mm2, [rsi+0*16] \n" "pmulhw mm4, mm3 \n" "psubsw mm0, mm6 \n" "movq mm3, mm2 \n" "movq mm6, [rsi+4*16] \n" "paddsw mm7, mm5 \n" "paddsw mm2, mm6 \n" "psubsw mm3, mm6 \n" "movq mm5, mm2 \n" "movq mm6, mm3 \n" "psubsw mm2, mm7 \n" "paddsw mm3, mm0 \n" "paddsw mm1, mm1 \n" "paddsw mm4, mm4 \n" "paddsw mm5, mm7 \n" "psubsw mm6, mm0 \n" "movq mm7, mm3 \n" "movq mm0, mm6 \n" "paddsw mm3, mm1 \n" "paddsw mm6, mm4 \n" "psraw mm3, 6 \n" "psubsw mm7, mm1 \n" "psraw mm6, 6 \n" "psubsw mm0, mm4 \n" "movq mm1, [rax+0] \n" "psraw mm7, 6 \n" "movq mm4, mm5 \n" "psraw mm0, 6 \n" add_off128_mmx_reg(mm3) "packuswb mm3,mm0 \n" "movd [rdi+1*8], mm3 \n" "paddsw mm5, mm1 \n" add_off128_mmx_reg(mm6) "packuswb mm6,mm0 \n" "movd [rdi+2*8], mm6 \n" "psubsw mm4, mm1 \n" "movq mm3, [rax+8] \n" "psraw mm5, 6 \n" "movq mm6, mm2 \n" "psraw mm4, 6 \n" add_off128_mmx_reg(mm0) "packuswb mm0,mm1 \n" "movd [rdi+5*8], mm0 \n" "paddsw mm2, mm3 \n" add_off128_mmx_reg(mm7) "packuswb mm7,mm0 \n" "movd [rdi+6*8], mm7 \n" "psubsw mm6, mm3 \n" add_off128_mmx_reg(mm5) "packuswb mm5,mm0 \n" "movd [rdi+0*8], mm5 \n" "psraw mm2, 6 \n" add_off128_mmx_reg(mm4) "packuswb mm4,mm0 \n" "movd [rdi+7*8], mm4 \n" "psraw mm6, 6 \n" add_off128_mmx_reg(mm2) "packuswb mm2,mm0 \n" "movd [rdi+3*8], mm2 \n" add_off128_mmx_reg(mm6) "packuswb mm6,mm0 \n" "movd [rdi+4*8], mm6 \n" "add rdi,4 \n" "add rsi,8 \n" "dec rcx \n" "jnz __mmx_idct_cols \n" "emms \n" ".att_syntax \n" : /* no output */ : "S"(innerBuff),"D"(dest),"a"(scratch) : "memory","rcx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #else #ifdef __PIC__ #if __GNUC__ > 3 __asm__( "push %ebx \n" "push %ecx \n" "call __i686.get_pc_thunk.bx \n" "add $_GLOBAL_OFFSET_TABLE_, %ebx \n" "lea __jpmm_row_tabs@GOTOFF(%ebx),%eax \n" "lea __jpmm_rounder@GOTOFF(%ebx),%ecx \n" "mov %ecx,%ebx \n" "pop %ecx \n" ); #else __asm__( "push %ebx \n" "push %ecx \n" "call __tg_get_pc \n" "add $_GLOBAL_OFFSET_TABLE_, %ebx \n" "lea __jpmm_row_tabs@GOTOFF(%ebx),%eax \n" "lea __jpmm_rounder@GOTOFF(%ebx),%ecx \n" "mov %ecx,%ebx \n" "pop %ecx \n" ); #endif #endif /* __PIC__ */ // gcc inline assembly code (32bits) // Rows __asm__ ( ".intel_syntax noprefix \n" "mov ecx, 8 \n" #ifndef __PIC__ "push ebx \n" "lea eax,__jpmm_row_tabs \n" "lea ebx,__jpmm_rounder \n" #endif "__mmx_idct_rows: \n" "movq mm0, [esi] \n" "movq mm1, [esi+8] \n" "movq mm2, mm0 \n" "movq mm3, [eax] \n" "punpcklwd mm0, mm1 \n" "movq mm5, mm0 \n" "punpckldq mm0, mm0 \n" "movq mm4, [eax+8] \n" "punpckhwd mm2, mm1 \n" "pmaddwd mm3, mm0 \n" "movq mm6, mm2 \n" "movq mm1, [eax+32] \n" "punpckldq mm2, mm2 \n" "pmaddwd mm4, mm2 \n" "punpckhdq mm5, mm5 \n" "pmaddwd mm0, [eax+16] \n" "punpckhdq mm6, mm6 \n" "movq mm7, [eax+40] \n" "pmaddwd mm1, mm5 \n" "paddd mm3, [ebx] \n" "pmaddwd mm7, mm6 \n" "pmaddwd mm2, [eax+24] \n" "paddd mm3, mm4 \n" "pmaddwd mm5, [eax+48] \n" "movq mm4, mm3 \n" "pmaddwd mm6, [eax+56] \n" "paddd mm1, mm7 \n" "paddd mm0, [ebx] \n" "psubd mm3, mm1 \n" "psrad mm3, 11 \n" "paddd mm1, mm4 \n" "paddd mm0, mm2 \n" "psrad mm1, 11 \n" "paddd mm5, mm6 \n" "movq mm4, mm0 \n" "paddd mm0, mm5 \n" "psubd mm4, mm5 \n" "psrad mm0, 11 \n" "psrad mm4, 11 \n" "packssdw mm1, mm0 \n" "packssdw mm4, mm3 \n" "movq mm7, mm4 \n" "psrld mm4, 16 \n" "pslld mm7, 16 \n" "movq [edi], mm1 \n" "por mm7, mm4 \n" "movq [edi+8], mm7 \n" "add esi, 16 \n" "add edi, 16 \n" "add eax, 64 \n" "add ebx, 8 \n" "dec ecx \n" "jnz __mmx_idct_rows \n" "pop ebx \n" ".att_syntax \n" : /* no output */ : "D"(innerBuff),"S"(block) : "memory","eax","ecx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); // Columns __asm__ ( ".intel_syntax noprefix \n" "mov ecx, 2 \n" "__mmx_idct_cols: \n" mov_tg_3_16_mmx_reg(mm0) "movq mm3, [esi+16*3] \n" "movq mm1, mm0 \n" "movq mm5, [esi+16*5] \n" "pmulhw mm0, mm3 \n" mov_tg_1_16_mmx_reg(mm4) "pmulhw mm1, mm5 \n" "movq mm7, [esi+16*7] \n" "movq mm2, mm4 \n" "movq mm6, [esi+16*1] \n" "pmulhw mm4, mm7 \n" "paddsw mm0, mm3 \n" "pmulhw mm2, mm6 \n" "paddsw mm1, mm3 \n" "psubsw mm0, mm5 \n" mov_ocos_4_16_mmx_reg(mm3) "paddsw mm1, mm5 \n" "paddsw mm4, mm6 \n" "psubsw mm2, mm7 \n" "movq mm5, mm4 \n" "movq mm6, mm2 \n" "paddsw mm5, mm1 \n" "psubsw mm6, mm0 \n" "psubsw mm4, mm1 \n" "paddsw mm2, mm0 \n" mov_tg_2_16_mmx_reg(mm7) "movq mm1, mm4 \n" "movq [eax+0], mm5 \n" "paddsw mm1, mm2 \n" "movq [eax+8], mm6 \n" "psubsw mm4, mm2 \n" "movq mm5, [esi+2*16] \n" "movq mm0, mm7 \n" "movq mm6, [esi+6*16] \n" "pmulhw mm0, mm5 \n" "pmulhw mm7, mm6 \n" "pmulhw mm1, mm3 \n" "movq mm2, [esi+0*16] \n" "pmulhw mm4, mm3 \n" "psubsw mm0, mm6 \n" "movq mm3, mm2 \n" "movq mm6, [esi+4*16] \n" "paddsw mm7, mm5 \n" "paddsw mm2, mm6 \n" "psubsw mm3, mm6 \n" "movq mm5, mm2 \n" "movq mm6, mm3 \n" "psubsw mm2, mm7 \n" "paddsw mm3, mm0 \n" "paddsw mm1, mm1 \n" "paddsw mm4, mm4 \n" "paddsw mm5, mm7 \n" "psubsw mm6, mm0 \n" "movq mm7, mm3 \n" "movq mm0, mm6 \n" "paddsw mm3, mm1 \n" "paddsw mm6, mm4 \n" "psraw mm3, 6 \n" "psubsw mm7, mm1 \n" "psraw mm6, 6 \n" "psubsw mm0, mm4 \n" "movq mm1, [eax+0] \n" "psraw mm7, 6 \n" "movq mm4, mm5 \n" "psraw mm0, 6 \n" add_off128_mmx_reg(mm3) "packuswb mm3,mm0 \n" "movd [edi+1*8], mm3 \n" "paddsw mm5, mm1 \n" add_off128_mmx_reg(mm6) "packuswb mm6,mm0 \n" "movd [edi+2*8], mm6 \n" "psubsw mm4, mm1 \n" "movq mm3, [eax+8] \n" "psraw mm5, 6 \n" "movq mm6, mm2 \n" "psraw mm4, 6 \n" add_off128_mmx_reg(mm0) "packuswb mm0,mm1 \n" "movd [edi+5*8], mm0 \n" "paddsw mm2, mm3 \n" add_off128_mmx_reg(mm7) "packuswb mm7,mm0 \n" "movd [edi+6*8], mm7 \n" "psubsw mm6, mm3 \n" add_off128_mmx_reg(mm5) "packuswb mm5,mm0 \n" "movd [edi+0*8], mm5 \n" "psraw mm2, 6 \n" add_off128_mmx_reg(mm4) "packuswb mm4,mm0 \n" "movd [edi+7*8], mm4 \n" "psraw mm6, 6 \n" add_off128_mmx_reg(mm2) "packuswb mm2,mm0 \n" "movd [edi+3*8], mm2 \n" add_off128_mmx_reg(mm6) "packuswb mm6,mm0 \n" "movd [edi+4*8], mm6 \n" "add edi,4 \n" "add esi,8 \n" "dec ecx \n" "jnz __mmx_idct_cols \n" "emms \n" ".att_syntax \n" : /* no output */ : "S"(innerBuff),"D"(dest),"a"(scratch) : "memory","ecx","mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" ); #endif /* _64BITS */ #endif /* _WINDOWS */ } #ifndef _WINDOWS #ifdef __PIC__ __asm__( "__tg_get_pc: \n" "movl (%esp),%ebx \n" "ret \n" ); #endif /* __PIC__ */ #endif /* WINDOWS */ #endif /* JPG_USE_ASM */ tango-9.2.5a/lib/cpp/client/0000755023471100065110000000000013034745260012620 500000000000000tango-9.2.5a/lib/cpp/client/Makefile.am0000644023471100065110000000726013034744772014610 00000000000000SUBDIRS=helpers . # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a shared library with libtool (That's why we use LTLIBRARIES) lib_LTLIBRARIES = libtango.la # We need the libserver to link libtango_la_LIBADD = ../server/libserver.la \ ../server/idl/libidl.la \ ../server/jpeg/libjpeg.la \ ../server/jpeg_mmx/libjpeg_mmx.la \ ../log4tango/src/liblog4tango.la \ $(LIBZMQ_LIBS) # We need to set the -version-info for libtool so that libtool will # generate the correct .so version libtango_la_LDFLAGS=-version-info $(VERSION_INFO) AM_CXXFLAGS=-D_TANGO_LIB if DARWIN_ENABLED AM_LDFLAGS=-flat_namespace --disable-dependency-tracking endif # These are the sources for the library. libtango_la_SOURCES = dbapi_class.cpp \ dbapi_server.cpp \ dbapi_datum.cpp \ dbapi_base.cpp \ dbapi_device.cpp \ dbapi_history.cpp \ dbapi_attribute.cpp \ dbapi_cache.cpp \ dbapi_serverdata.cpp \ devapi_attr.cpp \ devapi_base.cpp \ devapi_data.cpp \ devapi_datahist.cpp \ devapi_utils.cpp \ devapi_pipe.cpp \ api_util.cpp \ asynreq.cpp \ cbthread.cpp \ proxy_asyn.cpp \ proxy_asyn_cb.cpp \ attr_proxy.cpp \ group.cpp \ filedatabase.cpp \ apiexcept.cpp \ accessproxy.cpp \ lockthread.cpp \ event.cpp \ eventkeepalive.cpp \ eventqueue.cpp \ notifdeventconsumer.cpp \ zmqeventconsumer.cpp tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = accessproxy.h \ apiexcept.h \ cbthread.h \ dbapi.h \ devapi.h \ devasyn.h \ event.h \ eventconsumer.h \ filedatabase.h \ group.h \ lockthread.h \ Database.h \ DbDevice.h \ ApiUtil.h \ DeviceData.h \ DeviceAttribute.h \ DevicePipe.h \ Connection.h \ DeviceProxy.h \ AttributeProxy.h \ event.tpp \ devapi_attr.tpp \ devapi_utils.tpp \ api_util.tpp \ devapi_pipe.tpp \ zmq.hpp tango-9.2.5a/lib/cpp/client/Makefile.in0000644023471100065110000010340713034745122014607 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/client DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(tangoinclude_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(tangoincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libtango_la_DEPENDENCIES = ../server/libserver.la \ ../server/idl/libidl.la ../server/jpeg/libjpeg.la \ ../server/jpeg_mmx/libjpeg_mmx.la \ ../log4tango/src/liblog4tango.la $(am__DEPENDENCIES_1) am_libtango_la_OBJECTS = dbapi_class.lo dbapi_server.lo dbapi_datum.lo \ dbapi_base.lo dbapi_device.lo dbapi_history.lo \ dbapi_attribute.lo dbapi_cache.lo dbapi_serverdata.lo \ devapi_attr.lo devapi_base.lo devapi_data.lo \ devapi_datahist.lo devapi_utils.lo devapi_pipe.lo api_util.lo \ asynreq.lo cbthread.lo proxy_asyn.lo proxy_asyn_cb.lo \ attr_proxy.lo group.lo filedatabase.lo apiexcept.lo \ accessproxy.lo lockthread.lo event.lo eventkeepalive.lo \ eventqueue.lo notifdeventconsumer.lo zmqeventconsumer.lo libtango_la_OBJECTS = $(am_libtango_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libtango_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libtango_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libtango_la_SOURCES) DIST_SOURCES = $(libtango_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(tangoinclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = helpers . # We need the ORB to compile and the tango header files to compile AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) # We're making a shared library with libtool (That's why we use LTLIBRARIES) lib_LTLIBRARIES = libtango.la # We need the libserver to link libtango_la_LIBADD = ../server/libserver.la \ ../server/idl/libidl.la \ ../server/jpeg/libjpeg.la \ ../server/jpeg_mmx/libjpeg_mmx.la \ ../log4tango/src/liblog4tango.la \ $(LIBZMQ_LIBS) # We need to set the -version-info for libtool so that libtool will # generate the correct .so version libtango_la_LDFLAGS = -version-info $(VERSION_INFO) AM_CXXFLAGS = -D_TANGO_LIB @DARWIN_ENABLED_TRUE@AM_LDFLAGS = -flat_namespace --disable-dependency-tracking # These are the sources for the library. libtango_la_SOURCES = dbapi_class.cpp \ dbapi_server.cpp \ dbapi_datum.cpp \ dbapi_base.cpp \ dbapi_device.cpp \ dbapi_history.cpp \ dbapi_attribute.cpp \ dbapi_cache.cpp \ dbapi_serverdata.cpp \ devapi_attr.cpp \ devapi_base.cpp \ devapi_data.cpp \ devapi_datahist.cpp \ devapi_utils.cpp \ devapi_pipe.cpp \ api_util.cpp \ asynreq.cpp \ cbthread.cpp \ proxy_asyn.cpp \ proxy_asyn_cb.cpp \ attr_proxy.cpp \ group.cpp \ filedatabase.cpp \ apiexcept.cpp \ accessproxy.cpp \ lockthread.cpp \ event.cpp \ eventkeepalive.cpp \ eventqueue.cpp \ notifdeventconsumer.cpp \ zmqeventconsumer.cpp tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = accessproxy.h \ apiexcept.h \ cbthread.h \ dbapi.h \ devapi.h \ devasyn.h \ event.h \ eventconsumer.h \ filedatabase.h \ group.h \ lockthread.h \ Database.h \ DbDevice.h \ ApiUtil.h \ DeviceData.h \ DeviceAttribute.h \ DevicePipe.h \ Connection.h \ DeviceProxy.h \ AttributeProxy.h \ event.tpp \ devapi_attr.tpp \ devapi_utils.tpp \ api_util.tpp \ devapi_pipe.tpp \ zmq.hpp all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/client/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/client/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libtango.la: $(libtango_la_OBJECTS) $(libtango_la_DEPENDENCIES) $(EXTRA_libtango_la_DEPENDENCIES) $(AM_V_CXXLD)$(libtango_la_LINK) -rpath $(libdir) $(libtango_la_OBJECTS) $(libtango_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/accessproxy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apiexcept.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asynreq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_proxy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cbthread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_base.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_datum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_history.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbapi_serverdata.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_attr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_base.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_datahist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_pipe.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devapi_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventkeepalive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventqueue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filedatabase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/group.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockthread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notifdeventconsumer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy_asyn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proxy_asyn_cb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmqeventconsumer.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tangoincludeHEADERS: $(tangoinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tangoincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tangoincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(tangoincludedir)" || exit $$?; \ done uninstall-tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(tangoincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-tangoincludeHEADERS install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-tangoincludeHEADERS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-tangoincludeHEADERS installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-libLTLIBRARIES uninstall-tangoincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/client/accessproxy.h0000644023471100065110000000313713034744772015267 00000000000000// // AccessProxy.h - include file for TANGO AccessProxy class // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // #ifndef _ACCESSPROXY_H #define _ACCESSPROXY_H #include using namespace std; namespace Tango { #define __AC_BUFFER_SIZE 1024 class AccessProxy: public Tango::DeviceProxy { public: AccessProxy(string &); AccessProxy(const char *); ~AccessProxy() {} AccessControlType check_access_control(string &); bool is_command_allowed(string &,string &); protected: string user; vector host_ips; bool forced; map > allowed_cmd_table; omni_mutex only_one; void get_allowed_commands(string &,vector &); private: void real_ctor(); }; } // End of Tango namespace #endif /* _ACCESSPROXY_H */ tango-9.2.5a/lib/cpp/client/apiexcept.h0000644023471100065110000004022113034744772014701 00000000000000// // apiexcept.h - include file for TANGO device api exceptions // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef _APIEXCEPT_H #define _APIEXCEPT_H #include #include using namespace std; namespace Tango { /*************************************************************************** * * Exception classes used for the write_attribute call * ****************************************************************************/ /** * An exception class * * This class is used as exception for the DeviceProxy::write_attribute call() * * $Author: taurel $ * $Revision: 28101 $ * * @headerfile tango.h * @ingroup Client */ class NamedDevFailed { public: string name; ///< The name of the attribute which fails long idx_in_call; ///< Index in the write_attributes method parameter vector of the attribute which failed. DevErrorList err_stack; ///< The error stack /// @privatesection NamedDevFailed(const DevErrorList &err,const string &na,long idx):name(na),idx_in_call(idx),err_stack(err) {} NamedDevFailed(); }; /** * An exception class * * This class is used as exception for the DeviceProxy::write_attribute call() * * $Author: taurel $ * $Revision: 28101 $ * * @headerfile tango.h * @ingroup Client */ class NamedDevFailedList: public Tango::DevFailed { public: /** * Get faulty attribute number * * Returns the number of attributes which failed during the write_attribute call. * * @return The number of attribute(s) which fail during the write_attribute call */ size_t get_faulty_attr_nb() {return err_list.size();} /** * Check if the call failed * * This method returns true if at least one attribute failed during the call * * @return A boolean set to true if the call failed for at least one attribute */ bool call_failed() {if ((err_list.empty()==true) && (errors.length()!=0))return true;else return false;} vector err_list; ///< There is one element in this vector for each attribute which failed during its writing. /// @privatesection NamedDevFailedList(const Tango::MultiDevFailed &,string,const char *,const char *); NamedDevFailedList() {}; }; /**************************************************************************** * * Macro to define API specific exception and their methods * *****************************************************************************/ #define MAKE_EXCEPT(E,I) \ class E: public Tango::DevFailed \ { \ public: \ E(const DevErrorList& err):DevFailed(err) {} \ }; \ class I \ { \ public: \ static inline void throw_exception(const char *reason,const string &desc,const char *origin, \ Tango::ErrSeverity sever = Tango::ERR) \ {\ Tango::DevErrorList errors(1);\ errors.length(1);\ errors[0].desc = CORBA::string_dup(desc.c_str()); \ errors[0].severity = sever; \ errors[0].reason = CORBA::string_dup(reason);\ errors[0].origin = CORBA::string_dup(origin);\ throw Tango::E(errors);\ }\ \ static inline void throw_exception(const char *reason,char *desc,const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(1);\ errors.length(1);\ errors[0].desc = CORBA::string_dup(desc);\ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup(reason);\ errors[0].origin = CORBA::string_dup(origin);\ delete[] desc;\ throw Tango::E(errors);\ }\ \ static inline void throw_exception(const char *reason,const char *desc,const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(1);\ errors.length(1);\ errors[0].desc = CORBA::string_dup(desc);\ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup(reason);\ errors[0].origin = CORBA::string_dup(origin);\ throw Tango::E(errors);\ }\ \ static inline void re_throw_exception(CORBA::SystemException &cex,\ const string &reason,const string &desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ Tango::Except::the_mutex.lock(); \ char *tmp = Tango::Except::print_CORBA_SystemException(&cex);\ errors[0].desc = CORBA::string_dup(tmp);\ Tango::Except::the_mutex.unlock(); \ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc.c_str());\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason.c_str());\ errors[1].origin = CORBA::string_dup(origin);\ throw Tango::E(errors);\ }\ \ static inline void re_throw_exception(CORBA::SystemException &cex,\ char *reason,char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ Tango::Except::the_mutex.lock(); \ char *tmp = Tango::Except::print_CORBA_SystemException(&cex);\ errors[0].desc = CORBA::string_dup(tmp);\ Tango::Except::the_mutex.unlock(); \ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc);\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin);\ delete[] desc;\ delete[] reason;\ throw Tango::E(errors);\ }\ static inline void re_throw_exception(CORBA::SystemException &cex,\ const char *reason,const string &desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ Tango::Except::the_mutex.lock(); \ char *tmp = Tango::Except::print_CORBA_SystemException(&cex);\ errors[0].desc = CORBA::string_dup(tmp);\ Tango::Except::the_mutex.unlock(); \ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc.c_str());\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin);\ throw Tango::E(errors);\ }\ static inline void re_throw_exception(CORBA::SystemException &cex,\ const char *reason,const string &desc,\ const string &origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ Tango::Except::the_mutex.lock(); \ char *tmp = Tango::Except::print_CORBA_SystemException(&cex);\ errors[0].desc = CORBA::string_dup(tmp);\ Tango::Except::the_mutex.unlock(); \ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin.c_str());\ errors[1].desc = CORBA::string_dup(desc.c_str());\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin.c_str());\ throw Tango::E(errors);\ }\ \ static inline void re_throw_exception(CORBA::SystemException &cex,\ const char *reason,char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ Tango::Except::the_mutex.lock(); \ char *tmp = Tango::Except::print_CORBA_SystemException(&cex);\ errors[0].desc = CORBA::string_dup(tmp);\ Tango::Except::the_mutex.unlock(); \ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc);\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin);\ delete[] desc;\ throw Tango::E(errors);\ }\ \ static inline void re_throw_exception(Tango::E &ex,\ const char *reason,char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ long nb_err = ex.errors.length();\ ex.errors.length(nb_err + 1);\ ex.errors[nb_err].severity = sever;\ ex.errors[nb_err].desc = CORBA::string_dup(desc);\ delete[] desc;\ ex.errors[nb_err].origin = CORBA::string_dup(origin);\ ex.errors[nb_err].reason = CORBA::string_dup(reason);\ throw ex;\ }\ \ static inline void re_throw_exception(Tango::E &ex,\ const char *reason,const string &desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ long nb_err = ex.errors.length();\ ex.errors.length(nb_err + 1);\ ex.errors[nb_err].severity = sever;\ ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str());\ ex.errors[nb_err].origin = CORBA::string_dup(origin);\ ex.errors[nb_err].reason = CORBA::string_dup(reason);\ throw ex;\ }\ static inline void re_throw_exception(Tango::DevFailed &ex,\ const char *reason,char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ long nb_err = ex.errors.length();\ ex.errors.length(nb_err + 1);\ ex.errors[nb_err].severity = sever;\ ex.errors[nb_err].desc = CORBA::string_dup(desc);\ delete[] desc;\ ex.errors[nb_err].origin = CORBA::string_dup(origin);\ ex.errors[nb_err].reason = CORBA::string_dup(reason);\ throw ex;\ }\ \ static inline void re_throw_exception(Tango::DevFailed &ex,\ const char *reason,const string &desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ long nb_err = ex.errors.length();\ ex.errors.length(nb_err + 1);\ ex.errors[nb_err].severity = sever;\ ex.errors[nb_err].desc = CORBA::string_dup(desc.c_str());\ ex.errors[nb_err].origin = CORBA::string_dup(origin);\ ex.errors[nb_err].reason = CORBA::string_dup(reason);\ throw ex;\ }\ static inline void re_throw_exception(Tango::DevFailed &ex,\ const char *reason,const char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ long nb_err = ex.errors.length();\ ex.errors.length(nb_err + 1);\ ex.errors[nb_err].severity = sever;\ ex.errors[nb_err].desc = CORBA::string_dup(desc);\ ex.errors[nb_err].origin = CORBA::string_dup(origin);\ ex.errors[nb_err].reason = CORBA::string_dup(reason);\ throw ex;\ }\ \ static inline void re_throw_exception(char *CORBA_error_desc,\ const char *reason,char *desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ errors[0].desc = CORBA::string_dup(CORBA_error_desc);\ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc);\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin);\ delete[] desc;\ throw Tango::E(errors);\ }\ \ static inline void re_throw_exception(char *CORBA_error_desc,\ const char *reason,const string &desc,\ const char *origin,\ Tango::ErrSeverity sever = Tango::ERR)\ {\ Tango::DevErrorList errors(2);\ errors.length(2);\ errors[0].desc = CORBA::string_dup(CORBA_error_desc);\ errors[0].severity = sever;\ errors[0].reason = CORBA::string_dup("API_CorbaException");\ errors[0].origin = CORBA::string_dup(origin);\ errors[1].desc = CORBA::string_dup(desc.c_str());\ errors[1].severity = sever;\ errors[1].reason = CORBA::string_dup(reason);\ errors[1].origin = CORBA::string_dup(origin);\ throw Tango::E(errors);\ }\ }; MAKE_EXCEPT(ConnectionFailed,ApiConnExcept) MAKE_EXCEPT(CommunicationFailed,ApiCommExcept) MAKE_EXCEPT(WrongNameSyntax,ApiWrongNameExcept) MAKE_EXCEPT(NonDbDevice,ApiNonDbExcept) MAKE_EXCEPT(WrongData,ApiDataExcept) MAKE_EXCEPT(NonSupportedFeature,ApiNonSuppExcept) MAKE_EXCEPT(AsynCall,ApiAsynExcept) MAKE_EXCEPT(AsynReplyNotArrived,ApiAsynNotThereExcept) MAKE_EXCEPT(EventSystemFailed,EventSystemExcept) MAKE_EXCEPT(DeviceUnlocked,DeviceUnlockedExcept) MAKE_EXCEPT(NotAllowed,NotAllowedExcept) // // Define macros for the management of the Corba TRANSIENT exception // #define TRANSIENT_NOT_EXIST_EXCEPT(E,CLASS,NAME,OBJ) \ if (E.minor() == omni::TRANSIENT_CallTimedout) \ { \ \ bool need_reconnect = false; \ omniORB::setClientConnectTimeout(NARROW_CLNT_TIMEOUT); \ try \ { \ Device_var dev = Device::_duplicate(OBJ->device); \ dev->ping(); \ } \ catch(CORBA::TRANSIENT &trans_ping) \ { \ if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || \ trans_ping.minor() == omni::TRANSIENT_CallTimedout || \ (OBJ->ext->has_alt_adr == true && trans_ping.minor() == omni::TRANSIENT_CallTimedout)) \ { \ need_reconnect = true; \ } \ } \ catch(...) {} \ omniORB::setClientConnectTimeout(0); \ \ if (need_reconnect == false) \ { \ TangoSys_OMemStream desc; \ desc << "Timeout (" << OBJ->timeout << " mS) exceeded on device " << OBJ->dev_name(); \ desc << ends; \ TangoSys_OMemStream ori; \ ori << CLASS << ":" << NAME << ends; \ ApiCommExcept::re_throw_exception(E, \ (const char *)"API_DeviceTimedOut", \ desc.str(), ori.str());\ }\ } \ \ OBJ->set_connection_state(CONNECTION_NOTOK); \ ctr++; \ \ if ((OBJ->tr_reco == false) || \ ((ctr == 2) && (OBJ->tr_reco == true))) \ { \ \ TangoSys_OMemStream desc; \ desc << "Failed to execute " << NAME << " on device " << OBJ->dev_name(); \ desc << ends; \ TangoSys_OMemStream ori; \ ori << CLASS << ":" << NAME << ends; \ ApiCommExcept::re_throw_exception(E, \ (const char*)"API_CommunicationFailed", \ desc.str(),ori.str()); \ } #define TRANSIENT_NOT_EXIST_EXCEPT_CMD(E) \ if (E.minor() == omni::TRANSIENT_CallTimedout) \ { \ \ bool need_reconnect = false; \ try \ { \ Device_var dev = Device::_duplicate(device); \ dev->ping(); \ } \ catch(CORBA::TRANSIENT &trans_ping) \ { \ if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || \ trans_ping.minor() == omni::TRANSIENT_CallTimedout || \ (ext->has_alt_adr == true && trans_ping.minor() == omni::TRANSIENT_CallTimedout)) \ { \ need_reconnect = true; \ } \ } \ catch(...) {} \ \ if (need_reconnect == false) \ { \ TangoSys_OMemStream desc; \ desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); \ desc << ", command " << command << ends; \ ApiCommExcept::re_throw_exception(E, \ (const char *)"API_DeviceTimedOut", \ desc.str(), \ (const char *)"Connection::command_inout()"); \ }\ } \ \ set_connection_state(CONNECTION_NOTOK); \ if (get_lock_ctr() != 0) \ { \ set_lock_ctr(0); \ TangoSys_OMemStream desc; \ desc << "Device " << dev_name() << " has lost your lock(s) (server re-start?) while executing command " << command << ends; \ DeviceUnlockedExcept::re_throw_exception(E,(const char*)DEVICE_UNLOCKED_REASON, \ desc.str(), (const char*)"Connection::command_inout()"); \ } \ ctr++; \ \ if ((tr_reco == false) || \ ((ctr == 2) && (tr_reco == true))) \ { \ TangoSys_OMemStream desc; \ desc << "Failed to execute command_inout on device " << dev_name(); \ desc << ", command " << command << ends; \ ApiCommExcept::re_throw_exception(E, \ (const char*)"API_CommunicationFailed", \ desc.str(), \ (const char*)"Connection::command_inout()"); \ } } // End of Tango namespace #endif /* _APIEXCEPT_H */ tango-9.2.5a/lib/cpp/client/cbthread.h0000644023471100065110000000441113034744772014474 00000000000000//============================================================================= // // file : cbthread.h // // description : Include for the CallBackThread object. // This class implements the callback thread // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 29627 $ // //============================================================================= #ifndef _CBTHREAD_H #define _CBTHREAD_H #include namespace Tango { class CbThreadCmd: public omni_mutex { public: CbThreadCmd():stop(false) {}; void stop_thread() {omni_mutex_lock sync(*this);stop=true;} void start_thread() {omni_mutex_lock sync(*this);stop=false;} bool is_stopped() {omni_mutex_lock sync(*this);return stop;} bool stop; }; //============================================================================= // // The CallBackThread class // // description : Class to store all the necessary information for the // polling thread. It's run() method is the thread code // //============================================================================= class CallBackThread: public omni_thread { public: CallBackThread(CbThreadCmd &cmd,AsynReq *as):shared_cmd(cmd), asyn_ptr(as) {}; void *run_undetached(void *); void start() {start_undetached();} CbThreadCmd &shared_cmd; AsynReq *asyn_ptr; }; } // End of Tango namespace #endif /* _CBTHREAD_ */ tango-9.2.5a/lib/cpp/client/dbapi.h0000644023471100065110000010342713034744772014006 00000000000000 //+================================================================================================================== // // dbapi.h - include file for TANGO database api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // //+================================================================================================================== #ifndef _DBAPI_H #define _DBAPI_H #include #include #include /** @defgroup DBase Database Client classes * @ingroup Client */ using namespace std; namespace Tango { /// /// forward declarations /// class DbDatum; class DbDevInfo; class DbDevImportInfo; class DbDevExportInfo; class DbServerInfo; class DbDevFullInfo; class DbHistory; class FileDatabase; class DbServerCache; class Util; class AccessProxy; /// /// Some typedef and define /// typedef vector DbDevInfos; typedef vector DbDevExportInfos; typedef vector DbDevImportInfos; typedef vector DbData; #define POGO_DESC "Description" #define POGO_TITLE "ProjectTitle" /// /// Classes declaration /// /********************************************************************** * * * Database - database object for implementing generic high-level * * interface for TANGO database api * * * **********************************************************************/ #include "Database.h" /********************************************************************** * * * DbDevice - A database object for accessing device related * * information in the database * * * **********************************************************************/ #include "DbDevice.h" /********************************************************************** * * * DbProperty - A database object for accessing general properties * * which are stored in the database * * * **********************************************************************/ class DbProperty { public : DbProperty(string); ~DbProperty(); // // methods // void get(DbData&); void put(DbData&); void delete_(DbData&); }; /********************************************************************** * * * DbAttribute - A database object for accessing attribute related * * information in the database * * * **********************************************************************/ class DbAttribute { private : string name; string device_name; Database *dbase; int db_ind; bool ext_dbase; public : DbAttribute(string &, string &); DbAttribute(string &, string &, Database *); DbAttribute(string &,string &, string &,string &); ~DbAttribute(); // // methods // void get_property(DbData&); void put_property(DbData&); void delete_property(DbData&); }; /********************************************************************** * * * DbServer - A database object for accessing server related * * information in the database * * * **********************************************************************/ /** * A database object for a device server which can be used to query or modify server database information. * * @headerfile tango.h * @ingroup DBase */ class DbServer { private : string name; Database *dbase; int db_ind; bool ext_dbase; class DbServerExt { public: DbServerExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DbServerExt *ext; #endif public : /**@name Constructors */ //@{ /** * Create a DbServer instance. * * A constructor for a DbServer object for a server in the TANGO database specified by the TANGO_HOST * environment variable. * * @param [in] server_name The device server name * */ DbServer(string server_name); /** * Create a DbServer instance using a specified database * * A constructor for a DbServer object for the server in the specified database. This method reuses the * Database supplied by the programmer * * @param [in] server_name The device server name * @param [in] db The database object * */ DbServer(string server_name, Database *db); //@} // // methods // /**@name Server oriented methods */ //@{ /** * Add a device server process into the database * * Add a group of devices to the database. The device names, server names and classes are specified in the * vector of DbDevInfo structures * * @param [in] serv Device server process data * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void add_server(DbDevInfos &serv); /** * Delete the device server from database * * Delete the device server and its associated devices from the database. * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_server(); /** * Export all device server devices in database * * Export a group of device to the database. The device names, IOR, class, server name, pid etc. are specified * in the vector of DbDevExportInfo structures. * * @param [in] serv Devices information * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void export_server(DbDevExportInfos &serv); /** * Mark all devices belonging to the device server as un-exported * * Mark all the devices exported by the server as un-exported. * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void unexport_server(); //@} /// @privatesection ~DbServer(); DbServerInfo get_server_info(); }; /********************************************************************** * * * DbClass - A database object for accessing class related * * information in the database * * * **********************************************************************/ /** * A database object for a class which can be used to query or modify class properties * * @headerfile tango.h * @ingroup DBase */ class DbClass { private : string name; Database *dbase; int db_ind; bool ext_dbase; class DbClassExt { public: DbClassExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DbClassExt *ext; #endif public : /**@name Constructors */ //@{ /** * Create a DbClass instance. * * A constructor for a DbClass object for a class in the TANGO database specified by the TANGO_HOST * environment variable * * @param [in] class_name The Tango class name * */ DbClass(string class_name); /** * Create a DbClass instance using a specified database * * A constructor for a DbClass object for the Tango class in the specified database. This method reuses the * Database supplied by the programmer. * * @param [in] class_name The Tango class name * @param [in] db The database object * */ DbClass(string class_name, Database *db); //@} // // methods // /**@name Property oriented methods */ //@{ /** * Get class property from database * * Query the database for the list of properties of this class. See Database::get_class_property() for an example * of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_property(DbData &db); /** * Update class property in database * * Update the list of properties for this class in the database. See Database::put_class_property() for an example * of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_property(DbData &db); /** * Remove class property from database * * Delete the list of specified properties for this class in the database. See Database::delete_property() for an * example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_property(DbData &db); /** * Get class attribute property from database * * Query the database for the list of attribute properties of this class. See Database::get_class_attribute_property() * for an example of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_attribute_property(DbData &db); /** * Update class attribute property in database * * Update the list of attribute properties for this class in the database. See Database::put_class_attribute_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_attribute_property(DbData &db); /** * Remove class attribute property from database * * Delete all properties for the list of specified attributes for this class in the database. See Database::delete_class_attribute_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_attribute_property(DbData &db); /** * Get class pipe property from database * * Query the database for the list of pipe properties of this class. See Database::get_class_pipe_property() * for an example of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_pipe_property(DbData &db); /** * Update class pipe property in database * * Update the list of pipe properties for this class in the database. See Database::put_class_pipe_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_pipe_property(DbData &db); /** * Remove class pipe property from database * * Delete all properties for the list of specified pipes for this class in the database. See Database::delete_class_pipe_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_pipe_property(DbData &db); //@} /// @privatesection ~DbClass(); }; /********************************************************************** * * * DbDatum - A database object for sending and receiving data * * from the Tango database API * * * **********************************************************************/ /** * A database value * * A single database value which has a name, type, address and value and methods for inserting and extracting * C++ native types. This is the fundamental type for specifying database properties. Every property has a * name and has one or more values associated with it. The values can be inserted and extracted using the * operators << and >> respectively. A status flag indicates if there is data in the DbDatum object or not. An * additional flag allows the user to activate exceptions. * * @headerfile tango.h * @ingroup DBase */ class DbDatum { public: /// @privatesection enum except_flags { isempty_flag, wrongtype_flag, numFlags }; /// @publicsection /**@name Constructors */ //@{ /** * Create a DbDatum object. * * Create an instance of the DbDatum class with name set to the specified parameter * * @param [in] name The CORBA ORB pointer. Default value is fine for 99 % of cases * */ DbDatum (string name); /** * Create a DbDatum object. * * Create an instance of the DbDatum class with name set to the specified parameter * * @param [in] name The CORBA ORB pointer. Default value is fine for 99 % of cases * */ DbDatum (const char *name); //@} /**@name Operators overloading */ //@{ /** * Inserters operators * * The insert and extract operators are specified for the following C++ types : * @li bool * @li unsigned char * @li short * @li unsigned short * @li DevLong * @li DevULong * @li DevLong64 * @li DevULong64 * @li float * @li double * @li string * @li char* (insert only) * @li const char * * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Here is an example of creating, inserting and extracting some DbDatum types : * @code * DbDatum my_short("my_short"), my_long(“my_longâ€), my_string("my_string"); * DbDatum my_float_vector("my_float_vector"), my_double_vector("my_double_vector"); * * string a_string; * short a_short; * DevLong a_long; * vector a_float_vector; * vector a_double_vector; * * my_short << 100; // insert a short * my_short >> a_short; // extract a short * my_long << 1000; // insert a DevLong * my_long >> a_long; // extract a long * my_string << string("estas lista a bailar el tango ?"); // insert a string * my_string >> a_string; // extract a string * my_float_vector << a_float_vector // insert a vector of floats * my_float_vector >> a_float_vector; // extract a vector of floats * my_double_vector << a_double_vector; // insert a vector of doubles * my_double_vector >> a_double_vector; // extract a vector of doubles * @endcode * * @param [in] val Data to be inserted * * @exception WrongData if requested */ void operator << (bool val); /** * Extractors operators * * See documentation of the DbDatum::operator<< for details * * @param [out] val Data to be initalized with database value * @return A boolean set to true if the extraction succeeds * @exception WrongData if requested */ bool operator >> (bool &val); //@} /**@name Exception related methods methods */ //@{ /** * Set exception flag * * Is a method which allows the user to switch on/off exception throwing for trying to extract data from an * empty DbDatum object. The default is to not throw exception. The following flags are supported : * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDbDatum) if user tries to extract * data from an empty DbDatum object * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion * * @param [in] fl The exception flag */ void exceptions(bitset fl) { exceptions_flags = fl;} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * DbDatum da; * * bitset bs = da.exceptions(); * cout << "bs = " << bs << endl; * * da.set_exceptions(DbDatum::wrongtype_flag); * bs = da.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return exceptions_flags;} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(except_flags fl) {exceptions_flags.reset((size_t)fl);} /** * Set one exception flag * * Sets one exception flag. See DbDatum::exceptions() for a usage example * * @param [in] fl The exception flag */ void set_exceptions(except_flags fl) {exceptions_flags.set((size_t)fl);} //@} /**@name Miscellaneous methods */ //@{ /** * Test if instance is empty * * is_empty() is a boolean method which returns true or false depending on whether the DbDatum object contains * data or not. It can be used to test whether a property is defined in the database or not e.g. * @code * sl_props.push_back(parity_prop); * dbase->get_device_property(device_name, sl_props); * * if (! parity_prop.is_empty()) * { * parity_prop >> parity; * } * else * { * cout << device_name << " has no parity defined in database !" << endl; * } * @endcode * * @return True if DdDatum instance is empty * * @exception WrongData if requested */ bool is_empty(); //@} /// @privatesection string name; vector value_string; // // constructor methods // DbDatum(); ~DbDatum(); DbDatum(const DbDatum &); DbDatum &operator=(const DbDatum &); size_t size() {return value_string.size();} // // insert methods // void operator << (short); void operator << (unsigned char); void operator << (unsigned short); void operator << (DevLong); void operator << (DevULong); void operator << (DevLong64); void operator << (DevULong64); void operator << (float); void operator << (double); void operator << (char *); // void operator << (char *&); void operator << (const char *); // void operator << (const char *&); void operator << (string&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); // // extract methods // bool operator >> (short&); bool operator >> (unsigned char&); bool operator >> (unsigned short&); bool operator >> (DevLong&); bool operator >> (DevULong&); bool operator >> (DevLong64&); bool operator >> (DevULong64&); bool operator >> (float&); bool operator >> (double&); bool operator >> (const char*&); bool operator >> (string&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); private : int value_type; int value_size; bitset exceptions_flags; class DbDatumExt { public: DbDatumExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DbDatumExt *ext; #endif }; /********************************************************************** * * * DbHistory - A data object for receiving data history from the * * Tango database * * * **********************************************************************/ /** * Class used to retrieve database object history * * @headerfile tango.h * @ingroup DBase */ class DbHistory { public: // // constructor methods // DbHistory(string ,string ,vector &); DbHistory(string ,string ,string ,vector &); // // getter methods // /** * Get property name * * @return The property name */ string get_name(); /** * Get attribute name * * @return The attribute name */ string get_attribute_name(); /** * Get change date * * @return The date */ string get_date(); /** * Get value * * @return The property value */ DbDatum get_value(); /** * Get property deleted flag * * @return The property deleted flag */ bool is_deleted(); private: string propname; // Property name string attname; // Attribute name (Not used for device/pipe properties) DbDatum value; // Property value string date; // Update date bool deleted; // Deleted flag string format_mysql_date(string ); void make_db_datum(vector &); }; /********************************************************************** * * * DbDevInfo * * * **********************************************************************/ /** * Device information for Database device creation * * @headerfile tango.h * @ingroup DBase */ class DbDevInfo { public : string name; ///< The device name string _class; ///< The device class name string server; ///< The full device server process name }; /********************************************************************** * * * DbDevImportInfo * * * **********************************************************************/ /** * Device import information from the database * * @headerfile tango.h * @ingroup DBase */ class DbDevImportInfo { public : string name; ///< The device name long exported; ///< The exported flag string ior; ///< The device IOR string version; ///< The device version (as a string) }; /**************************************************************** * * * DbDevFullInfo * * * ****************************************************************/ /** * Device information from the database * * @headerfile tango.h * @ingroup DBase */ class DbDevFullInfo: public DbDevImportInfo { public : string class_name; ///< The device class name string ds_full_name; ///< The full device server process name string host; ///< The host name where the device server process is running string started_date; ///< Date of the last device export (empty if not set in DB) string stopped_date; ///< Date of the last device un-export (empty if not set in DB) long pid; ///< The device server process PID (-1 if not set in DB) }; /********************************************************************** * * * DbDevExportInfo * * * **********************************************************************/ /** * Device export information to the database * * @headerfile tango.h * @ingroup DBase */ class DbDevExportInfo { public : string name; ///< The device name string ior; ///< The device IOR string host; ///< The host name where the device server process runs string version; ///< The device version int pid; ///< The device server process PID }; /********************************************************************** * * * DbServerInfo * * * **********************************************************************/ class DbServerInfo { public : string name; string host; int mode; int level; }; /**************************************************************************************** * * * The DbServerCache class * * ------------------ * * * ***************************************************************************************/ // // DbServerCache data object to implement a DB cache // used during the DS startup sequence // class DbServerCache { public: typedef struct { int first_idx; int last_idx; }EltIdx; typedef struct { int first_idx; int last_idx; int prop_nb; int *props_idx; }PropEltIdx; typedef struct { int first_idx; int last_idx; int att_nb; int *atts_idx; }AttPropEltIdx; typedef struct { PropEltIdx dev_prop; AttPropEltIdx dev_att_prop; AttPropEltIdx dev_pipe_prop; }DevEltIdx; typedef struct { PropEltIdx class_prop; AttPropEltIdx class_att_prop; AttPropEltIdx class_pipe_prop; EltIdx dev_list; int dev_nb; DevEltIdx *devs_idx; }ClassEltIdx; DbServerCache(Database *,string &,string &); ~DbServerCache(); const DevVarLongStringArray *import_adm_dev(); const DevVarLongStringArray *import_notifd_event(); const DevVarLongStringArray *import_adm_event(); const DevVarStringArray *get_class_property(DevVarStringArray *); const DevVarStringArray *get_dev_property(DevVarStringArray *); const DevVarStringArray *get_dev_list(DevVarStringArray *); const DevVarStringArray *get_class_att_property(DevVarStringArray *); const DevVarStringArray *get_dev_att_property(DevVarStringArray *); const DevVarStringArray *get_obj_property(DevVarStringArray *); const DevVarStringArray *get_device_property_list(DevVarStringArray *); const DevVarStringArray *get_class_pipe_property(DevVarStringArray *); const DevVarStringArray *get_dev_pipe_property(DevVarStringArray *); const DevVarLongStringArray *import_tac_dev(string &); const EltIdx &get_imp_dat() {return imp_adm;} const EltIdx &get_imp_notifd_event() {return imp_notifd_event;} const EltIdx &get_imp_adm_event() {return imp_adm_event;} const PropEltIdx &get_DServer_class_prop() {return DServer_class_prop;} const PropEltIdx &get_Default_prop() {return Default_prop;} const PropEltIdx &get_adm_dev_prop() {return adm_dev_prop;} const PropEltIdx &get_ctrl_serv_prop() {return ctrl_serv_prop;} int get_class_nb() {return class_nb;} const ClassEltIdx *get_classes_elt() {return classes_idx;} int get_data_nb() {return n_data;} private: void prop_indexes(int &,int &,PropEltIdx &,const DevVarStringArray *); void prop_att_indexes(int &,int &,AttPropEltIdx &,const DevVarStringArray *); void prop_pipe_indexes(int &,int &,AttPropEltIdx &,const DevVarStringArray *); void get_obj_prop(DevVarStringArray *,PropEltIdx &,bool dev_prop=false); int find_class(DevString ); int find_dev_att(DevString,int &,int &); int find_obj(DevString obj_name,int &); void get_obj_prop_list(DevVarStringArray *,PropEltIdx &); CORBA::Any_var received; const DevVarStringArray *data_list; int n_data; int proc_release; EltIdx imp_adm; EltIdx imp_notifd_event; EltIdx imp_adm_event; EltIdx imp_tac; PropEltIdx ctrl_serv_prop; PropEltIdx DServer_class_prop; PropEltIdx Default_prop; PropEltIdx adm_dev_prop; int class_nb; ClassEltIdx *classes_idx; DevVarLongStringArray imp_adm_data; DevVarLongStringArray imp_notifd_event_data; DevVarLongStringArray imp_adm_event_data; DevVarLongStringArray imp_tac_data; DevVarStringArray ret_obj_prop; DevVarStringArray ret_dev_list; DevVarStringArray ret_obj_att_prop; DevVarStringArray ret_obj_pipe_prop; DevVarStringArray ret_prop_list; }; /**************************************************************************************** * * * The DbServerData class * * ---------------- * * * ***************************************************************************************/ // // DbServerData object to implement the features required to move a complete device server proces // configuration from one database to another one // /** * Class used to move/copy a complete device server process database configuration * from one Tango host to another * * @headerfile tango.h * @ingroup DBase */ class DbServerData { private: struct TangoProperty { string name; vector values; TangoProperty(string &na, vector &val):name(na),values(val) {} }; struct TangoAttribute: vector { string name; TangoAttribute(string na):name(na) {} }; struct TangoPipe: vector { string name; TangoPipe(string na):name(na) {} }; struct TangoDevice: DeviceProxy { string name; vector properties; vector attributes; vector pipes; TangoDevice(string &); string get_name() {return name;} vector &get_properties() {return properties;} vector &get_attributes() {return attributes;} vector &get_pipes() {return pipes;} void put_properties(Database *); void put_attribute_properties(Database *); void put_pipe_properties(Database *); }; struct TangoClass: vector { string name; vector properties; vector attributes; vector pipes; TangoClass(const string &,const string &,Database *); string get_name() {return name;} vector &get_properties() {return properties;} vector &get_attributes() {return attributes;} vector &get_pipes() {return pipes;} void put_properties(Database *); void put_attribute_properties(Database *); void put_pipe_properties(Database *); void remove_properties(Database *); }; void create_server(Database *); void put_properties(Database *); string full_server_name; vector classes; public: /** * Create a DbServerData instance. * * A constructor for a DbServerData object for a device server process defined in the TANGO database specified by * the TANGO_HOST environment variable * * @param [in] ds_exec_name The device server process executable name * @param [in] ds_inst_name The device server process instance name * */ DbServerData(const string &ds_exec_name,const string &ds_inst_name); /** * Check if device(s) already defined * * Return true if one of the device defined in the device server process with configuration in this instance is * already defined in the database defined by the Tango host given as parameter * * @param [in] tg_host The tango host * @return Boolean set to true if one of the device server device is defined in the Tango host given as parameter */ bool already_exist(const string &tg_host); /** * Put device server database configuration in new Tango host * * Store the device server process database configuration in the database specified by the given Tango host parameter * * @param [in] tg_host The tango host */ void put_in_database(const string &tg_host); /** * Remove device server database configuration from Tango host * * Remove the device server process database configuration from the database specified by the given Tango host parameter * * @param [in] tg_host The tango host */ void remove(const string &tg_host); /** * Remove device server database configuration from default Tango host * * Remove the device server process database configuration from the database specified by the environment variable * TANGO_HOST * */ void remove(); ///@privatesection ~DbServerData() {} const string &get_name() {return full_server_name;} vector &get_classes() {return classes;} }; /* // Some macros to call the Db server // These macros will do some retries in case of // timeout while calling the DB device // This is necessary in case of massive DS // startup (after a power cut for instance) // when the Db is over-loaded */ #define MANAGE_EXCEPT(NAME) \ catch (Tango::CommunicationFailed &e) \ { \ if (e.errors.length() >= 2) \ { \ if (::strcmp(e.errors[1].reason.in(),"API_DeviceTimedOut") == 0) \ { \ if (db_retries != 0) \ { \ db_retries--; \ if (db_retries == 0) \ throw; \ } \ else \ throw; \ } \ else \ throw; \ } \ else \ throw; \ } #define CALL_DB_SERVER_NO_RET(NAME,SEND) \ { \ bool retry_mac = true; \ long db_retries = 0; \ if (db_tg != NULL) \ { \ if (db_tg->is_svr_starting() == true) \ db_retries = DB_START_PHASE_RETRIES; \ } \ while (retry_mac == true) \ { \ try \ { \ command_inout(NAME,SEND); \ retry_mac = false; \ } \ MANAGE_EXCEPT(NAME) \ } \ } #define CALL_DB_SERVER(NAME,SEND,RET) \ { \ bool retry_mac = true; \ long db_retries = 0; \ if (db_tg != NULL) \ { \ if (db_tg->is_svr_starting() == true) \ db_retries = DB_START_PHASE_RETRIES; \ } \ while (retry_mac == true) \ { \ try \ { \ RET = command_inout(NAME,SEND); \ retry_mac = false; \ } \ MANAGE_EXCEPT(NAME) \ } \ } } // End of Tango namespace #endif /* _DBAPI_H */ tango-9.2.5a/lib/cpp/client/devapi.h0000644023471100065110000006776113034744772014211 00000000000000//===================================================================================================================== // // devapi.h - include file for TANGO device api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 28018 $ // //==================================================================================================================== #ifndef _DEVAPI_H #define _DEVAPI_H #include #include #include #include #include #include #include using namespace std; namespace Tango { /** @defgroup Client Client classes */ // // forward declarations // class DeviceData; class DeviceAttribute; class DbDevice; class DbAttribute; class DbDatum; class DbDevImportInfo; class Database; class AsynReq; class NotifdEventConsumer; class ZmqEventConsumer; class CallBack; class AttributeProxy; class TangoMonitor; // // Some typedef // typedef vector DbData; typedef union { TangoSys_Pid LockerPid; unsigned long UUID[4]; }LockerId; struct LockerInfo { LockerLanguage ll; LockerId li; string locker_host; string locker_class; }; struct LockingThread { TangoMonitor *mon; LockThCmd *shared; LockThread *l_thread; }; /** * Base structure for command information * * @headerfile tango.h */ #ifdef GEN_DOC typedef struct DevCommandInfo #else typedef struct _DevCommandInfo #endif { string cmd_name; ///< The command name long cmd_tag; ///< The command tag long in_type; ///< Input parameter data type long out_type; ///< Output parameter data type string in_type_desc; ///< Input parameter description string out_type_desc; ///< Ouptput parameter description ///@privatesection bool operator==(const _DevCommandInfo &); }DevCommandInfo; struct AttributeDimension { long dim_x; long dim_y; }; /** * Command information data extension * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct CommandInfo : public DevCommandInfo #else typedef struct _CommandInfo : public DevCommandInfo #endif { Tango::DispLevel disp_level; ///< The command display level /// @privatesection friend ostream &operator<<(ostream &,_CommandInfo &); bool operator==(const _CommandInfo &); }CommandInfo; /** * A vector of CommandInfo structure * * @headerfile tango.h * @ingroup Client */ typedef vector CommandInfoList; struct _DeviceInfo { string dev_class; string server_id; string server_host; long server_version; string doc_url; string dev_type; }; typedef _DeviceInfo DeviceInfo; /** * Base structure for Attribute configuration * * @headerfile tango.h */ #ifdef GEN_DOC typedef struct DeviceAttributeConfig #else typedef struct _DeviceAttributeConfig #endif { string name; ///< Name AttrWriteType writable; ///< Writable type (Read, Write,...) AttrDataFormat data_format; ///< Data format (Scalar, Spectrum,...) int data_type; ///< Data type int max_dim_x; ///< Max dim X int max_dim_y; ///< Max dim Y string description; ///< Description string label; ///< Label string unit; ///< Unit string standard_unit; ///< Standard unit string display_unit; ///< Display unit string format; ///< Format string min_value; ///< Min value string max_value; ///< Max value string min_alarm; ///< Min alarm string max_alarm; ///< Max alarm string writable_attr_name; ///< Writable att. name vector extensions; ///< For future extensions /// @privatesection bool operator==(const _DeviceAttributeConfig &); }DeviceAttributeConfig; /** * Attribute configuration data extension * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct AttributeInfo : public DeviceAttributeConfig #else typedef struct _AttributeInfo : public DeviceAttributeConfig #endif { Tango::DispLevel disp_level; ///< Display level /// @privatesection friend ostream &operator<<(ostream &,_AttributeInfo &); bool operator==(const _AttributeInfo &); }AttributeInfo; /** * Attribute alarms configuration * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct AttributeAlarmInfo #else typedef struct _AttributeAlarmInfo #endif { string min_alarm; ///< Min alarm level string max_alarm; ///< max alarm level string min_warning; ///< Min warning level string max_warning; ///< Max warning level string delta_t; ///< Delta t RDS string delta_val; ///< Delta val RDS vector extensions; ///< Future extensions /// @privatesection bool operator==(const _AttributeAlarmInfo &); }AttributeAlarmInfo; /** * Attribute change event configuration * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct ChangeEventInfo #else typedef struct _ChangeEventInfo #endif { string rel_change; ///< Relative change threshold string abs_change; ///< Absolute change threshold vector extensions; ///< Future extensions }ChangeEventInfo; /** * Attribute periodic event configuration * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct PeriodicEventInfo #else typedef struct _PeriodicEventInfo #endif { string period; ///< Event period vector extensions; ///< Future extensions }PeriodicEventInfo; /** * Attribute archive event configuration * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct ArchiveEventInfo #else typedef struct _ArchiveEventInfo #endif { string archive_rel_change; ///< Archive relative change threshold string archive_abs_change; ///< Archive abosolute change threshold string archive_period; ///< Archive event period vector extensions; ///< Future exetnsions }ArchiveEventInfo; /** * Attribute event configuration * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct AttributeEventInfo #else typedef struct _AttributeEventInfo #endif { ChangeEventInfo ch_event; ///< Attribute change event info PeriodicEventInfo per_event; ///< Attribute periodic event info ArchiveEventInfo arch_event; ///< Attribute archive event info /// @privatesection bool operator==(const _AttributeEventInfo &); }AttributeEventInfo; /** * Possible memorized attribute type * * @ingroup Client * @headerfile tango.h */ typedef enum _AttrMemorizedType { NOT_KNOWN, ///< Device too old to get this info NONE, ///< The attribute is not memorized MEMORIZED, ///< Memorized attribute MEMORIZED_WRITE_INIT ///< Memorized attribute with memorized value writen at initialization }AttrMemorizedType; /** * Extended attribute configuration data * * @headerfile tango.h * @ingroup Client */ #ifdef GEN_DOC typedef struct AttributeInfoEx: public AttributeInfo #else typedef struct _AttributeInfoEx : public AttributeInfo #endif { string root_attr_name; ///< Root attribute name (in case of forwarded attribute) AttrMemorizedType memorized; ///< The attribute memorization type vector enum_labels; ///< Enumerated attribute labels AttributeAlarmInfo alarms; ///< The attribute alarms AttributeEventInfo events; ///< The attribute events configuration vector sys_extensions; ///< Future extensions /// @privatesection _AttributeInfoEx & operator=(const AttributeConfig_2 *); _AttributeInfoEx & operator=(const AttributeConfig_3 *); _AttributeInfoEx & operator=(const AttributeConfig_5 *); friend ostream &operator<<(ostream &,_AttributeInfoEx &); bool operator==(const _AttributeInfoEx &); }AttributeInfoEx; typedef vector AttributeInfoList; /** * vector of AttributeInfoEx structure * * @headerfile tango.h * @ingroup Client */ typedef vector AttributeInfoListEx; /** * Base structure for pipe information * * @headerfile tango.h */ #ifdef GEN_DOC typedef struct PipeInfo #else typedef struct _PipeInfo #endif { string name; ///< Pipe name string description; ///< Pipe description string label; ///< Pipe label Tango::DispLevel disp_level; ///< Display level Tango::PipeWriteType writable; ///< Writable type (Read, Read-Write) vector extensions; ///< For future extensions ///@privatesection friend ostream &operator<<(ostream &,_PipeInfo &); // bool operator==(const _PipeInfo &); }PipeInfo; // TODO: Pipe -> Change the type for writable to replace PIPE_READ, PIPE_READ_WRITE by READ, READ_WRITE (IDL limitation) typedef vector PipeInfoList; // // Can't use CALLBACK (without _) in the following enum because it's a // pre-defined type on Windows.... // /** * Possible asynchronous request type * * @ingroup Client * @headerfile tango.h */ enum asyn_req_type { POLLING, ///< Polling mode request CALL_BACK, ///< Callback mode request ALL_ASYNCH ///< All request }; /** * Possible callback mode * * @ingroup Client * @headerfile tango.h */ enum cb_sub_model { PUSH_CALLBACK, ///< Callback push model PULL_CALLBACK ///< Callback pull model }; // // Some define // #define CONNECTION_OK 1 #define CONNECTION_NOTOK 0 #define PROT_SEP "://" #define TACO_PROTOCOL "taco" #define TANGO_PROTOCOL "tango" #define MODIFIER '#' #define DBASE_YES "dbase=yes" #define DBASE_NO "dbase=no" #define MODIFIER_DBASE_NO "#dbase=no" #define HOST_SEP ':' #define PORT_SEP '/' #define DEV_NAME_FIELD_SEP '/' #define RES_SEP "->" #define DEVICE_SEP '/' #define FROM_IOR "IOR" #define NOT_USED "Unused" /**************************************************************************************** * * * The ApiUtil class * * ----------------- * * * ***************************************************************************************/ #include "ApiUtil.h" /**************************************************************************************** * * * The DeviceData class * * -------------------- * * * ***************************************************************************************/ #include "DeviceData.h" /**************************************************************************************** * * * The DevicePipe class * * -------------------- * * * ***************************************************************************************/ #include "DevicePipe.h" /**************************************************************************************** * * * The DeviceAttribute class * * ------------------------- * * * ***************************************************************************************/ #include "DeviceAttribute.h" /**************************************************************************************** * * * The xxxDataHistory classes * * -------------------------- * * * ***************************************************************************************/ /** * Fundamental type for receiving data from device command polling buffers * * This is the fundamental type for receiving data from device command polling buffers. This class inherits * from the Tango::DeviceData class. One instance of this class is created for each command result history. * Within this class, you find the command result data or the exception parameters, a flag indicating if the * command has failed when it was invoked by the device server polling thread and the date when the command * was executed. For history calls, it is not possible to returns command error as exception. See chapter * on Advanced Features in the * Tango book * for all details regarding device polling. * * $Author: taurel $ * $Revision: 28018 $ * * @headerfile tango.h * @ingroup Client */ class DeviceDataHistory: public DeviceData { public : ///@privatesection // // constructor methods // DeviceDataHistory(); DeviceDataHistory(int, int *,DevCmdHistoryList *); DeviceDataHistory(const DeviceDataHistory &); DeviceDataHistory & operator=(const DeviceDataHistory &); #ifdef HAS_RVALUE DeviceDataHistory(DeviceDataHistory &&); DeviceDataHistory &operator=(DeviceDataHistory &&); #endif ~DeviceDataHistory(); ///@publicsection /** * Check if the record was a failure * * Returns a boolean set to true if the record in the polling buffer was a failure * * @return A boolean set to true if the record was a failure */ bool has_failed() {return fail;} /** * Get record polling date * * Returns the date when the device server polling thread has executed the command. * * @return The record polling date */ TimeVal &get_date() {return time;} /** * Get record error stack * * Return the error stack recorded by the device server polling thread in case of the command failed when it * was invoked. * * @return The record error stack */ const DevErrorList &get_err_stack() {return err.in();} /** * Print a DeviceDataHistory instance * * Is an utility function to easily print the contents of a DeviceDataHistory object. This function knows all * types which could be inserted in a DeviceDataHistory object and print them accordingly. It also prints date * and error stack in case the command returned an error. * @code * DeviceProxy *dev = new DeviceProxy(“...â€); * int hist_depth = 4; * vector *hist; * * hist = dev->command_history(“MyCommandâ€,hist_depth); * * for (int i = 0;i < hist_depth;i++) * { * cout << (*hist)[i] << endl; * } * delete hist; * @endcode * * @param [in] str The printing stream * @param [in] ddh The instance to be printed */ friend ostream &operator<<(ostream &str,DeviceDataHistory &ddh); ///@privatesection // Three following methods for compatibility with older release bool failed() {return fail;} void failed(bool val) {fail = val;} void set_date(TimeVal &tv) {time = tv;} TimeVal &date() {return time;} const DevErrorList &errors() {return err.in();} void errors(DevErrorList_var &del) {err = del;} protected: ///@privatesection bool fail; TimeVal time; DevErrorList_var err; DevCmdHistoryList *seq_ptr; int *ref_ctr_ptr; private: class DeviceDataHistoryExt { public: DeviceDataHistoryExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_hist; #else DeviceDataHistoryExt *ext_hist; // Class extension #endif }; typedef vector DeviceDataHistoryList; /** * Fundamental type for receiving data from device attribute polling buffers * * This is the fundamental type for receiving data from device attribute polling buffers. This class inherits * from the Tango::DeviceAttribute class. One instance of this class is created for each attribute result history. * Within this class, you find the attribute result data or the exception parameters and a flag indicating if the * attribute has failed when it was invoked by the device server polling thread. For history calls, it is not * possible to returns attribute error as exception. See chapter on Advanced Features in the * Tango book for all details regarding * device polling. * * $Author: taurel $ * $Revision: 28018 $ * * @headerfile tango.h * @ingroup Client */ class DeviceAttributeHistory: public DeviceAttribute { public : ///@privatesection // // constructor methods // DeviceAttributeHistory(); DeviceAttributeHistory(int, DevAttrHistoryList_var &); DeviceAttributeHistory(int, DevAttrHistoryList_3_var &); DeviceAttributeHistory(const DeviceAttributeHistory &); DeviceAttributeHistory & operator=(const DeviceAttributeHistory &); #ifdef HAS_RVALUE DeviceAttributeHistory(DeviceAttributeHistory &&); DeviceAttributeHistory &operator=(DeviceAttributeHistory &&); #endif ~DeviceAttributeHistory(); ///@publicsection /** * Check if the record was a failure * * Returns a boolean set to true if the record in the polling buffer was a failure * * @return A boolean set to true if the record was a failure */ bool has_failed() {return fail;} /** * Print a DeviceAttributeHistory instance * * Is an utility function to easily print the contents of a DeviceAttributeHistory object. This function knows * all types which could be inserted in a DeviceAttributeHistory object and print them accordingly. It also * in case the attribute returned an error. * @code * DeviceProxy *dev = new DeviceProxy(“...â€); * int hist_depth = 4; * vector *hist; * hist = dev->attribute_history(“MyAttributeâ€,hist_depth); * for (int i = 0;i < hist_depth;i++) * { * cout << (*hist)[i] << endl; * } * delete hist; * @endcode * * @param [in] str The printing stream * @param [in] dah The instance to be printed */ friend ostream &operator<<(ostream &str,DeviceAttributeHistory &dah); ///@privatesection // Three following methods for compatibility with older release bool failed() {return fail;} void failed(bool val) {fail = val;} TimeVal &date() {return time;} // const DevErrorList &errors() {return err;} protected: ///@privatesection bool fail; char compatibility_padding[16]; private: class DeviceAttributeHistoryExt { public: DeviceAttributeHistoryExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_hist; #else DeviceAttributeHistoryExt *ext_hist; // Class extension #endif }; /**************************************************************************************** * * * The Connection class * * -------------------- * * * ***************************************************************************************/ #include "Connection.h" /**************************************************************************************** * * * The DeviceProxy class * * -------------------- * * * ***************************************************************************************/ #include "DeviceProxy.h" /**************************************************************************************** * * * The AttributeProxy class * * -------------------- * * * ***************************************************************************************/ #include "AttributeProxy.h" /**************************************************************************************** * * * The DummyDeviceProxy class * * -------------------- * * * ***************************************************************************************/ class DummyDeviceProxy: public Tango::Connection { public: DummyDeviceProxy():Tango::Connection(true) {}; virtual string get_corba_name(bool) {string str;return str;} virtual string build_corba_name() {string str;return str;} virtual int get_lock_ctr() {return 0;} virtual void set_lock_ctr(int) {}; virtual string dev_name() {string str;return str;} int get_env_var(const char *cc,string &str_ref) {return Tango::Connection::get_env_var(cc,str_ref);} }; /// /// Some inline methods /// ------------------- /// inline ApiUtil *ApiUtil::instance() { omni_mutex_lock lo(inst_mutex); if (_instance == NULL) _instance = new ApiUtil(); return _instance; } inline long Connection::add_asyn_request(CORBA::Request_ptr req,TgRequest::ReqType req_type) { omni_mutex_lock guard(asyn_mutex); long id = ApiUtil::instance()->get_pasyn_table()->store_request(req,req_type); pasyn_ctr++; return id; } inline void Connection::remove_asyn_request(long id) { omni_mutex_lock guard(asyn_mutex); ApiUtil::instance()->get_pasyn_table()->remove_request(id); pasyn_ctr--; } inline void Connection::add_asyn_cb_request(CORBA::Request_ptr req,CallBack *cb,Connection *con,TgRequest::ReqType req_type) { omni_mutex_lock guard(asyn_mutex); ApiUtil::instance()->get_pasyn_table()->store_request(req,cb,con,req_type); pasyn_cb_ctr++; } inline void Connection::remove_asyn_cb_request(Connection *con,CORBA::Request_ptr req) { omni_mutex_lock guard(asyn_mutex); ApiUtil::instance()->get_pasyn_table()->remove_request(con,req); pasyn_cb_ctr--; } inline long Connection::get_pasyn_cb_ctr() { long ret; asyn_mutex.lock(); ret = pasyn_cb_ctr; asyn_mutex.unlock(); return ret; } inline void Connection::dec_asynch_counter(asyn_req_type ty) { omni_mutex_lock guard(asyn_mutex); if (ty==POLLING) pasyn_ctr--; else if (ty==CALL_BACK) pasyn_cb_ctr--; } inline void DeviceProxy::check_connect_adm_device() { omni_mutex_lock guard(adm_dev_mutex); if (adm_device == NULL) connect_to_adm_device(); } // // For Tango 8 ZMQ event system // inline int DeviceProxy::subscribe_event (const string &attr_name, EventType event, CallBack *callback) { vector filt; return subscribe_event (attr_name,event,callback,filt,false); } inline int DeviceProxy::subscribe_event (const string &attr_name, EventType event, CallBack *callback,bool stateless) { vector filt; return subscribe_event(attr_name,event,callback,filt,stateless); } inline int DeviceProxy::subscribe_event (const string &attr_name, EventType event, int event_queue_size,bool stateless) { vector filt; return subscribe_event(attr_name,event,event_queue_size,filt,stateless); } /// /// Some macros /// ----------- /// #define READ_ATT_EXCEPT(NAME_CHAR,OBJ) \ catch (Tango::ConnectionFailed &e) \ { \ TangoSys_OMemStream desc; \ desc << "Failed to read_attribute on device " << device_name; \ desc << ", attribute " << NAME_CHAR << ends; \ ApiConnExcept::re_throw_exception(e,(const char*)"API_AttributeFailed", \ desc.str(), (const char*)"DeviceProxy::read_attribute()"); \ } \ catch (Tango::DevFailed &e) \ { \ TangoSys_OMemStream desc; \ desc << "Failed to read_attribute on device " << device_name; \ desc << ", attribute " << NAME_CHAR << ends; \ Except::re_throw_exception(e,(const char*)"API_AttributeFailed", \ desc.str(), (const char*)"DeviceProxy::read_attribute()"); \ } \ catch (CORBA::TRANSIENT &trans) \ { \ TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","read_attribute",OBJ); \ } \ catch (CORBA::OBJECT_NOT_EXIST &one) \ { \ if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) \ { \ TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","read_attribute",OBJ); \ } \ else \ { \ set_connection_state(CONNECTION_NOTOK); \ TangoSys_OMemStream desc; \ desc << "Failed to read_attribute on device " << device_name << ends; \ ApiCommExcept::re_throw_exception(one, \ (const char*)"API_CommunicationFailed", \ desc.str(), \ (const char*)"DeviceProxy::read_attribute()"); \ } \ } \ catch (CORBA::COMM_FAILURE &comm) \ { \ if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) \ { \ TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","read_attribute",OBJ); \ } \ else \ { \ set_connection_state(CONNECTION_NOTOK); \ TangoSys_OMemStream desc; \ desc << "Failed to read_attribute on device " << device_name << ends; \ ApiCommExcept::re_throw_exception(comm, \ (const char*)"API_CommunicationFailed", \ desc.str(), \ (const char*)"DeviceProxy::read_attribute()"); \ } \ } \ catch (CORBA::SystemException &ce) \ { \ set_connection_state(CONNECTION_NOTOK); \ TangoSys_OMemStream desc; \ desc << "Failed to read_attribute on device " << device_name << ends; \ ApiCommExcept::re_throw_exception(ce, \ (const char*)"API_CommunicationFailed", \ desc.str(), \ (const char*)"DeviceProxy::read_attribute()"); \ } #define COPY_BASE_CONFIG(A,B) \ A[i].name = B[i].name; \ A[i].writable = B[i].writable; \ A[i].data_format = B[i].data_format; \ A[i].data_type = B[i].data_type; \ A[i].max_dim_x = B[i].max_dim_x; \ A[i].max_dim_y = B[i].max_dim_y; \ A[i].description = B[i].description; \ A[i].label = B[i].label; \ A[i].unit = B[i].unit; \ A[i].standard_unit = B[i].standard_unit; \ A[i].display_unit = B[i].display_unit; \ A[i].format = B[i].format; \ A[i].min_value = B[i].min_value; \ A[i].max_value = B[i].max_value; \ A[i].writable_attr_name = B[i].writable_attr_name; \ A[i].extensions.resize(B[i].extensions.length()); \ for (size_t j=0; j. #ifndef _DEVASYN_H #define _DEVASYN_H #include #include using namespace std; namespace Tango { //------------------------------------------------------------------------------ class DeviceProxy; class Connection; class DeviceData; class DeviceAttribute; class NamedDevFailedList; class EventData; class AttrConfEventData; class DataReadyEventData; class DevIntrChangeEventData; class PipeEventData; class EventDataList; class AttrConfEventDataList; class DataReadyEventDataList; class DevIntrChangeEventDataList; class PipeEventDataList; class EventConsumer; class EventConsumerKeepAliveThread; /******************************************************************************** * * * CmdDoneEvent class * * * *******************************************************************************/ /** * Asynchronous command execution callback data * * This class is used to pass data to the callback method in asynchronous callback model for command execution. * * $Author: bourtemb $ * $Revision: 29627 $ * * @headerfile tango.h * @ingroup Client */ class CmdDoneEvent { public: ///@privatesection CmdDoneEvent(DeviceProxy *dev, string &cmd, DeviceData &arg, DevErrorList &err_in):device(dev), cmd_name(cmd), argout(arg), errors(err_in) {if (errors.length()==0) err=false;else err=true;} ///@publicsection Tango::DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string &cmd_name; ///< The command name DeviceData &argout; ///< The command argout bool err; ///< A boolean flag set to true if the command failed. False otherwise DevErrorList &errors; ///< The error stack private: class CmdDoneEventExt { public: CmdDoneEventExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else CmdDoneEventExt *ext; #endif }; /******************************************************************************** * * * AttrReadEvent class * * * *******************************************************************************/ /** * Asynchronous read attribute execution callback data * * This class is used to pass data to the callback method in asynchronous callback model for read_attribute(s) * execution * * $Author: bourtemb $ * $Revision: 29627 $ * * @headerfile tango.h * @ingroup Client */ class AttrReadEvent { public: ///@privatesection AttrReadEvent(DeviceProxy *dev, vector &att_names, vector *arg, DevErrorList &err_in):device(dev), attr_names(att_names), argout(arg), errors(err_in) {if (errors.length()==0) err=false;else err=true;} ///@publicsection Tango::DeviceProxy *device; ///< The DeviceProxy object on which the call was executed vector &attr_names; ///< The attribute name list vector *argout; ///< The attribute data bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList &errors; ///< The error stack private: class AttrReadEventExt { public: AttrReadEventExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else AttrReadEventExt *ext; #endif }; /******************************************************************************** * * * AttrWrittenEvent class * * * *******************************************************************************/ /** * Asynchronous write attribute execution callback data * * This class is used to pass data to the callback method in asynchronous callback model for write_attribute(s) * execution. * * $Author: bourtemb $ * $Revision: 29627 $ * * @headerfile tango.h * @ingroup Client */ class AttrWrittenEvent { public: ///@privatesection AttrWrittenEvent(DeviceProxy *dev, vector &att_names, NamedDevFailedList &err_in):device(dev), attr_names(att_names), errors(err_in) {err = errors.call_failed();} ///@publicsection Tango::DeviceProxy *device; ///< The DeviceProxy object on which the call was executed vector &attr_names; ///< The attribute name list bool err; ///< A boolean flag set to true if the request failed. False otherwise NamedDevFailedList &errors; ///< The error stack private: class AttrWrittenEventExt { public: AttrWrittenEventExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else AttrWrittenEventExt *ext; #endif }; /******************************************************************************** * * * CallBack class * * * *******************************************************************************/ /** * Event and asynchronous (callback model) calls base class * * When using the event push model (callback automatically executed), there are some cases (same callback * used for events coming from different devices hosted in device server process running on different hosts) * where the callback method could be executed concurently by different threads started by the ORB. The * user has to code his callback method in a thread safe manner. * * $Author: bourtemb $ * $Revision: 29627 $ * * @headerfile tango.h * @ingroup Client */ class CallBack { friend class EventConsumer; friend class EventConsumerKeepAliveThread; public: #ifdef GEN_DOC /** * Asynchronous command execution callback method * * This method is defined as being empty and must be overloaded by the user when the asynchronous callback * model is used. This is the method which will be executed when the server reply from a command_inout is * received in both push and pull sub-mode. * * @param cde The command data */ virtual void cmd_ended(CmdDoneEvent *cde) {}; /** * Asynchronous read attribute execution callback method * * This method is defined as being empty and must be overloaded by the user when the asynchronous callback * model is used. This is the method which will be executed when the server reply from a read_attribute(s) is * received in both push and pull sub-mode. * * @param are The read attribute data */ virtual void attr_read(AttrReadEvent *are) {}; /** * Asynchronous write attribute execution callback method * * This method is defined as being empty and must be overloaded by the user when the asynchronous callback * model is used. This is the method which will be executed when the server reply from a write_attribute(s) * is received in both push and pull sub-mode. * * @param awe The write attribute data */ virtual void attr_written(AttrWrittenEvent *awe) {}; /** * Event callback method * * This method is defined as being empty and must be overloaded by the user when events are used. This is * the method which will be executed when the server send event(s) to the client. * * @param ed The event data */ virtual void push_event(EventData *ed) {}; /** * attribute configuration change event callback method * * This method is defined as being empty and must be overloaded by the user when events are used. This * is the method which will be executed when the server send attribute configuration change event(s) to the * client. * * @param ace The attribute configuration change event data */ virtual void push_event(AttrConfEventData *ace) {}; /** * Data ready event callback method * * This method is defined as being empty and must be overloaded by the user when events are used. This is * the method which will be executed when the server send attribute data ready event(s) to the client. * * @param dre The data ready event data */ virtual void push_event(DataReadyEventData *dre) {}; /** * Device interface change event callback method * * This method is defined as being empty and must be overloaded by the user when events are used. This is * the method which will be executed when the server send device interface change event(s) to the client. * * @param dic The device interface change event data */ virtual void push_event(DevIntrChangeEventData *dic) {}; /** * Pipe event callback method * * This method is defined as being empty and must be overloaded by the user when events are used. This is * the method which will be executed when the server send pipe event(s) to the client. * * @param ped The pipe event data */ virtual void push_event(PipeEventData *ped) {}; #else virtual void cmd_ended(CmdDoneEvent *) {}; virtual void attr_read(AttrReadEvent *) {}; virtual void attr_written(AttrWrittenEvent *) {}; virtual void push_event(EventData *) {}; virtual void push_event(AttrConfEventData *) {}; virtual void push_event(DataReadyEventData *) {}; virtual void push_event(DevIntrChangeEventData *) {}; virtual void push_event(PipeEventData *) {}; #endif /// @privatesection virtual ~CallBack() {}; private: class CallBackExt { public: CallBackExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else CallBackExt *ext; #endif }; //------------------------------------------------------------------------------ class UniqIdent: public omni_mutex { public: UniqIdent() {omni_mutex_lock sync(*this);ctr = 0;} long get_ident() {omni_mutex_lock sync(*this);return ++ctr;} long ctr; }; class TgRequest { public: enum ReqType { CMD_INOUT, READ_ATTR, WRITE_ATTR_SINGLE, WRITE_ATTR }; TgRequest(CORBA::Request_ptr re,ReqType ty):request(re),req_type(ty),cb_ptr(NULL), arrived(false),dev(NULL) {}; TgRequest(CORBA::Request_ptr re,ReqType ty,CallBack *cb):request(re),req_type(ty),cb_ptr(cb), arrived(false),dev(NULL) {}; TgRequest(Tango::Connection *con,ReqType ty,CallBack *cb):request(NULL),req_type(ty),cb_ptr(cb), arrived(false),dev(con) {}; CORBA::Request_ptr request; ReqType req_type; CallBack *cb_ptr; bool arrived; Connection *dev; }; class AsynReq: public omni_mutex { public: AsynReq(UniqIdent *ptr):ui_ptr(ptr),cond(this) {}; ~AsynReq() {delete ui_ptr;} TgRequest &get_request(long); TgRequest &get_request(CORBA::Request_ptr); TgRequest *get_request(Tango::Connection *); long store_request(CORBA::Request_ptr,TgRequest::ReqType); void store_request(CORBA::Request_ptr,CallBack *,Connection *,TgRequest::ReqType); void remove_request(long); void remove_request(Connection *,CORBA::Request_ptr); size_t get_request_nb() {omni_mutex_lock sync(*this);return asyn_poll_req_table.size();} size_t get_cb_request_nb() {omni_mutex_lock sync(*this);return cb_req_table.size();} size_t get_cb_request_nb_i() {return cb_req_table.size();} void mark_as_arrived(CORBA::Request_ptr req); multimap &get_cb_dev_table() {return cb_dev_table;} void mark_as_cancelled(long); void mark_all_polling_as_cancelled(); void wait() {cond.wait();} void signal() {omni_mutex_lock sync(*this);cond.signal();} protected: map asyn_poll_req_table; UniqIdent *ui_ptr; multimap cb_dev_table; map cb_req_table; vector cancelled_request; private: omni_condition cond; bool remove_cancelled_request(long); }; } // End of Tango namespace #endif /* _DEVASYN_H */ tango-9.2.5a/lib/cpp/client/event.h0000644023471100065110000003635513034744772014055 00000000000000//=================================================================================================================== // // file : event.h // // description : C++ include file for implementing the TANGO event server and client singleton classes - // EventSupplier and EventConsumer. // These classes are used to send events from the server to the notification service and to receive // events from the notification service. // // author(s) : A.Gotz (goetz@esrf.fr) // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #ifndef _EVENTAPI_H #define _EVENTAPI_H #include #include #include #include namespace Tango { #ifndef _USRDLL extern "C" { #endif void leavefunc(); #ifndef _USRDLL } #endif /******************************************************************************** * * * EventData class * * * *******************************************************************************/ /** * Event callback execution data * * This class is used to pass data to the callback method when an event is sent to the client * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Client */ class EventData { public : ///@privatesection EventData() {} EventData(DeviceProxy *dev,string &nam,string &evt,Tango::DeviceAttribute *attr_value_in,DevErrorList &errors_in); ~EventData(); EventData(const EventData &); EventData & operator=(const EventData &); /** * The date when the event arrived */ Tango::TimeVal reception_date; Tango::TimeVal &get_date() {return reception_date;} ///@publicsection DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string attr_name; ///< The attribute name string event; ///< The event name DeviceAttribute *attr_value; ///< The attribute data bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList errors; ///< The error stack private: void set_time(); }; class FwdEventData: public EventData { public: FwdEventData(); FwdEventData(DeviceProxy *,string &,string &,Tango::DeviceAttribute *,DevErrorList &); FwdEventData(DeviceProxy *,string &,string &,Tango::DeviceAttribute *,DevErrorList &,zmq::message_t *); void set_av_5(const AttributeValue_5 *_p) {av_5 = _p;} const AttributeValue_5 *get_av_5() {return av_5;} zmq::message_t *get_zmq_mess_ptr() {return event_data;} private: const AttributeValue_5 *av_5; zmq::message_t *event_data; }; /******************************************************************************** * * * EventDataList class * * * *******************************************************************************/ class EventDataList:public vector { public: EventDataList(): vector(0) {}; ~EventDataList() { if (size() > 0) { EventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } } } void clear() { if (size() > 0) { EventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } this->vector::clear(); } } }; /******************************************************************************** * * * AttrConfEventData class * * * *******************************************************************************/ /** * Attribute configuration change event callback execution data * * This class is used to pass data to the callback method when an attribute configuration event is sent to the * client * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Client */ class AttrConfEventData { public : ///@privatesection AttrConfEventData() {} AttrConfEventData(DeviceProxy *dev,string &nam,string &evt, Tango::AttributeInfoEx *attr_conf_in, DevErrorList &errors_in); ~AttrConfEventData(); AttrConfEventData(const AttrConfEventData &); AttrConfEventData & operator=(const AttrConfEventData &); /** * The date when the event arrived */ Tango::TimeVal reception_date; Tango::TimeVal &get_date() {return reception_date;} ///@publicsection DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string attr_name; ///< The attribute name string event; ///< The event name AttributeInfoEx *attr_conf; ///< The attribute configuration bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList errors; ///< The error stack private: void set_time(); }; class FwdAttrConfEventData: public AttrConfEventData { public: FwdAttrConfEventData(); FwdAttrConfEventData(DeviceProxy *,string &,string &,Tango::AttributeInfoEx *,DevErrorList &); void set_fwd_attr_conf(const AttributeConfig_5 *_p) {fwd_attr_conf = _p;} const AttributeConfig_5 *get_fwd_attr_conf() {return fwd_attr_conf;} private: const AttributeConfig_5 *fwd_attr_conf; }; /******************************************************************************** * * * AttrConfEventDataList class * * * *******************************************************************************/ class AttrConfEventDataList:public vector { public: AttrConfEventDataList(): vector(0) {}; ~AttrConfEventDataList() { if (size() > 0) { AttrConfEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } } } void clear() { if (size() > 0) { AttrConfEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } this->vector::clear(); } } }; /******************************************************************************** * * * DataReadyEventData class * * * *******************************************************************************/ /** * Data ready event callback execution data * * This class is used to pass data to the callback method when an attribute data ready event is sent to the client. * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Client */ class DataReadyEventData { public : ///@privatesection DataReadyEventData() {} DataReadyEventData(DeviceProxy *,AttDataReady *,string &evt,DevErrorList &); ~DataReadyEventData() {}; DataReadyEventData(const DataReadyEventData &); DataReadyEventData & operator=(const DataReadyEventData &); /** * The date when the event arrived */ Tango::TimeVal reception_date; Tango::TimeVal &get_date() {return reception_date;} ///@publicsection DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string attr_name; ///< The attribute name string event; ///< The event name int attr_data_type; ///< The attribute data type int ctr; ///< The user counter. Set to 0 if not defined when sent by the server bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList errors; ///< The error stack private: void set_time(); }; /******************************************************************************** * * * DataReadyEventDataList class * * * *******************************************************************************/ class DataReadyEventDataList:public vector { public: DataReadyEventDataList(): vector(0) {}; ~DataReadyEventDataList() { if (size() > 0) { DataReadyEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } } } void clear() { if (size() > 0) { DataReadyEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } this->vector::clear(); } } } ; /******************************************************************************** * * * DevIntrChangeEventData class * * * *******************************************************************************/ /** * Device interface change event callback execution data * * This class is used to pass data to the callback method when a device interface change event is sent to the client. * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Client */ class DevIntrChangeEventData { public : ///@privatesection DevIntrChangeEventData() {} DevIntrChangeEventData(DeviceProxy *,string &,string &,DevCmdInfoList_2 *,AttributeConfigList_5 *,bool,DevErrorList &); DevIntrChangeEventData(DeviceProxy *,string &,string &,CommandInfoList *,AttributeInfoListEx *,bool,DevErrorList &); ~DevIntrChangeEventData() {}; DevIntrChangeEventData(const DevIntrChangeEventData &); DevIntrChangeEventData & operator=(const DevIntrChangeEventData &); /** * The date when the event arrived */ Tango::TimeVal reception_date; Tango::TimeVal &get_date() {return reception_date;} ///@publicsection DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string event; ///< The event name string device_name; ///< The device name CommandInfoList cmd_list; ///< Device command list info AttributeInfoListEx att_list; ///< Device attribute list info bool dev_started; ///< Device started flag (true when event sent due to device being (re)started ///< and with only a possible but not sure interface change) bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList errors; ///< The error stack private: void set_time(); }; /******************************************************************************** * * * DevIntrChangeEventDataList class * * * *******************************************************************************/ class DevIntrChangeEventDataList:public vector { public: DevIntrChangeEventDataList(): vector(0) {}; ~DevIntrChangeEventDataList() { if (size() > 0) { DevIntrChangeEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } } } void clear() { if (size() > 0) { DevIntrChangeEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } this->vector::clear(); } } }; /******************************************************************************** * * * PipeEventData class * * * *******************************************************************************/ /** * Pipe event callback execution data * * This class is used to pass data to the callback method when a pipe event is sent to the client * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Client */ class PipeEventData { public : ///@privatesection PipeEventData() {} PipeEventData(DeviceProxy *dev,string &nam,string &evt,Tango::DevicePipe *pipe_value_in,DevErrorList &errors_in); ~PipeEventData(); PipeEventData(const PipeEventData &); PipeEventData & operator=(const PipeEventData &); /** * The date when the event arrived */ Tango::TimeVal reception_date; Tango::TimeVal &get_date() {return reception_date;} ///@publicsection DeviceProxy *device; ///< The DeviceProxy object on which the call was executed string pipe_name; ///< The pipe name string event; ///< The event name DevicePipe *pipe_value; ///< The pipe data bool err; ///< A boolean flag set to true if the request failed. False otherwise DevErrorList errors; ///< The error stack private: void set_time(); }; /******************************************************************************** * * * PipeEventDataList class * * * *******************************************************************************/ class PipeEventDataList:public vector { public: PipeEventDataList(): vector(0) {}; ~PipeEventDataList() { if (size() > 0) { PipeEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } } } void clear() { if (size() > 0) { PipeEventDataList::iterator vpos; for (vpos=begin(); vpos!=end(); ++vpos) { delete (*vpos); } this->vector::clear(); } } }; /******************************************************************************** * * * EventQueue class * * * *******************************************************************************/ class EventQueue { public: EventQueue(); EventQueue(long max_size); ~EventQueue(); void insert_event(EventData *new_event); void insert_event(AttrConfEventData *new_event); void insert_event(DataReadyEventData *new_event); void insert_event(DevIntrChangeEventData *new_event); void insert_event(PipeEventData *new_event); int size(); TimeVal get_last_event_date(); bool is_empty() {if (event_buffer.empty() == true) return true;else return false;} void get_events(EventDataList &event_list); void get_events(AttrConfEventDataList &event_list); void get_events(DataReadyEventDataList &event_list); void get_events(DevIntrChangeEventDataList &event_list); void get_events(PipeEventDataList &event_list); void get_events(CallBack *cb); private: void inc_indexes(); vector event_buffer; vector conf_event_buffer; vector ready_event_buffer; vector dev_inter_event_buffer; vector pipe_event_buffer; long max_elt; long insert_elt; long nb_elt; omni_mutex modification_mutex; }; } // End of namespace #endif // _EVENTAPI_H tango-9.2.5a/lib/cpp/client/eventconsumer.h0000644023471100065110000006152613034744771015626 00000000000000//==================================================================================================================== // // file : eventconsumer.h // // description : C++ include file for implementing the TANGO event related client classes - EventConsumer and others. // These classes are used to receive events from the server and from the notification service. // // author(s) : E.Taurel (taurel@esrf.fr) // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //==================================================================================================================== #ifndef _EVENTCONSUMER_H #define _EVENTCONSUMER_H #include #include #include #include #include #include #include #include #include #include #ifdef ZMQ_VERSION #if ZMQ_VERSION > 30201 #define ZMQ_HAS_DISCONNECT #endif #endif namespace Tango { #ifndef _USRDLL extern "C" { #endif void leavefunc(); #ifndef _USRDLL } #endif /******************************************************************************** * * * ZMQ event unmarshalling related classes * * * *******************************************************************************/ /*** TangoCdrMemoryStream ***/ class TangoCdrMemoryStream : public cdrMemoryStream { public: enum Unmarshal_type { UN_ATT, UN_PIPE }; TangoCdrMemoryStream(void *buf,size_t si):cdrMemoryStream(buf,si) {} TangoCdrMemoryStream():cdrMemoryStream(512,false) {} void tango_get_octet_array(int size); void *get_end_out_buf() {return pd_outb_end;} void *get_mkr_out_buf() {return pd_outb_mkr;} void *get_end_in_buf() {return pd_inb_end;} void *get_mkr_in_buf() {return pd_inb_mkr;} void set_mkr_in_buf(void *_ptr) {pd_inb_mkr=_ptr;} void rewind_in(int _nb) {pd_inb_mkr = (char *)pd_inb_mkr - _nb;} void set_un_marshal_type(Unmarshal_type _ty) {un_type=_ty;} Unmarshal_type get_un_marshal_type() {return un_type;} omni::ptr_arith_t align_to(omni::ptr_arith_t p,omni::alignment_t align); protected: Unmarshal_type un_type; }; inline omni::ptr_arith_t TangoCdrMemoryStream::align_to(omni::ptr_arith_t p,omni::alignment_t align) { return (p + ((omni::ptr_arith_t) align - 1)) & ~((omni::ptr_arith_t) align - 1); } inline void TangoCdrMemoryStream::tango_get_octet_array(int size) { pd_inb_mkr = (void*)((char *)pd_inb_mkr+size); } /*** ZmqAttrValUnion ***/ class ZmqAttrValUnion:public AttrValUnion { public: void operator<<= (TangoCdrMemoryStream &); template void init_seq(char *,_CORBA_ULong &,TangoCdrMemoryStream &); template void set_seq(T &) {cerr << "In default ZmqAttrValUnion::set_seq!" << endl;assert(false);} template T &get_seq() {cerr << "In default ZmqAttrValUnion::get_seq!" << endl;assert(false);} }; /*** ZmqAttributeValue_4 ***/ struct ZmqAttributeValue_4:public AttributeValue_4 { ZmqAttrValUnion zvalue; void operator<<= (TangoCdrMemoryStream &); }; /*** ZmqAttributeValue_5 ***/ struct ZmqAttributeValue_5:public AttributeValue_5 { ZmqAttrValUnion zvalue; void operator<<= (TangoCdrMemoryStream &); }; /*** ZmqDevPipeData ***/ struct ZmqDevPipeData:public DevPipeData { void operator<<= (TangoCdrMemoryStream &); }; /*** ZmqDevPipeBlob ***/ struct ZmqDevPipeBlob:public DevPipeBlob { void operator<<= (TangoCdrMemoryStream &); }; /*** ZmqDevVarPipeDataEltArray ***/ class ZmqDevVarPipeDataEltArray:public DevVarPipeDataEltArray { public: void operator<<= (TangoCdrMemoryStream &); }; /*** ZmqDevPipeDataElt ***/ struct ZmqDevPipeDataElt:public DevPipeDataElt { void operator<<= (TangoCdrMemoryStream &); }; /*** Macros to help coding ***/ #ifndef Swap16 #define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) #else #error "Swap16 has already been defined" #endif #ifndef Swap32 #define Swap32(l) ((((l) & 0xff000000) >> 24) | \ (((l) & 0x00ff0000) >> 8) | \ (((l) & 0x0000ff00) << 8) | \ (((l) & 0x000000ff) << 24)) #else #error "Swap32 has already been defined" #endif // // These template specialization allow us to set or get sequences within a AttrValUnion union. // Union method to get/set sequence value are named short_att_value(), double_att_value(), // float_att_value().... // #define SEQ_METH(NAME,TYPE) \ template <> \ inline void ZmqAttrValUnion::set_seq(TYPE &val) {NAME##_att_value(val);} \ \ template <> \ inline TYPE &ZmqAttrValUnion::get_seq() {return NAME##_att_value();} /*** Macros call to generate required template specialisation ***/ SEQ_METH(short,DevVarShortArray) SEQ_METH(double,DevVarDoubleArray) SEQ_METH(float,DevVarFloatArray) SEQ_METH(ushort,DevVarUShortArray) SEQ_METH(bool,DevVarBooleanArray) SEQ_METH(long,DevVarLongArray) SEQ_METH(long64,DevVarLong64Array) SEQ_METH(ulong,DevVarULongArray) SEQ_METH(uchar,DevVarUCharArray) SEQ_METH(ulong64,DevVarULong64Array) SEQ_METH(state,DevVarStateArray) /** Template methods definition ***/ // // Create a dummy empty sequence and init union with this dummy sequence (minimun data copy) // Retrieve a reference to that sequence once it is in the union and replace its data pointer // by the data in the CdrMemoryStream. // Use set_seq(), get_seq() specialized template created just above to set/get union sequences // T is the basic data type (DevShort) // TA is the sequence data type (DevVarShortArray) // // Also manage big and litle endian!! // template inline void ZmqAttrValUnion::init_seq(char *base_ptr,_CORBA_ULong &length,TangoCdrMemoryStream &_n) { TA dummy_val; set_seq(dummy_val); T *ptr; if (_n.get_un_marshal_type() == TangoCdrMemoryStream::UN_ATT) ptr = (T *)(base_ptr + _n.currentInputPtr()); else { char *tmp = (char *)_n.get_mkr_in_buf(); int delta = tmp - base_ptr; ptr = (T *)(base_ptr + delta); } if (_n.unmarshal_byte_swap() == true) { if (sizeof(T) == 2) { for (_CORBA_ULong i = 0;i < length;i++) { _CORBA_UShort *tmp_ptr = (_CORBA_UShort *)ptr; _CORBA_UShort tt = *(tmp_ptr + i); *(tmp_ptr + i) = Swap16(tt); } } else if (sizeof(T) == 4) { for (_CORBA_ULong i = 0;i < length;i++) { _CORBA_ULong *tmp_ptr = (_CORBA_ULong *)ptr; _CORBA_ULong t = *(tmp_ptr + i); *(tmp_ptr + i) = Swap32(t); } } else if (sizeof(T) == 8) { _CORBA_ULong double_length = length * 2; for (_CORBA_ULong i = 0;i < double_length;i += 2) { _CORBA_ULong *tmp_ptr = (_CORBA_ULong *)ptr; _CORBA_ULong tl1 = *(tmp_ptr + i + 1); _CORBA_ULong tl2 = Swap32(tl1); tl1 = *(tmp_ptr + i); *(tmp_ptr + i) = tl2; *(tmp_ptr + i + 1) = Swap32(tl1); } } } TA &the_seq = get_seq(); the_seq.replace(length,length,ptr,false); _n.tango_get_octet_array((length * sizeof(T))); } /******************************************************************************** * * * KeepAliveThCmd class * * * *******************************************************************************/ class KeepAliveThCmd:public omni_mutex { public : KeepAliveThCmd():cmd_pending(false),cond(this) {}; bool cmd_pending; // The new command flag KeepAliveCmdCode cmd_code; // The command code omni_condition cond; }; /******************************************************************************** * * * Map structures * * * *******************************************************************************/ typedef struct event_not_connected { DeviceProxy *device; string attribute; EventType event_type; string event_name; int event_id; CallBack *callback; EventQueue *ev_queue; vector filters; time_t last_heartbeat; string prefix; } EventNotConnected; //------------------------ Event Callback related info -------------------------------------- typedef struct event_subscribe { EventQueue *ev_queue; CallBack *callback; int id; } EventSubscribeStruct; typedef struct event_callback_base { DeviceProxy *device; string obj_name; string event_name; string channel_name; string fully_qualified_event_name; time_t last_subscribed; TangoMonitor *callback_monitor; vector callback_list; bool alias_used; } EventCallBackBase; typedef struct event_callback_zmq { DevLong device_idl; DevULong ctr; string endpoint; bool discarded_event; bool fwd_att; }EventCallBackZmq; typedef struct event_callback: public EventCallBackBase, public EventCallBackZmq { string filter_constraint; CosNotifyFilter::FilterID filter_id; bool filter_ok; } EventCallBackStruct; //------------------------ Event Channel related info -------------------------------------- typedef struct event_channel_base { DeviceProxy *adm_device_proxy; string full_adm_name; time_t last_subscribed; time_t last_heartbeat; bool heartbeat_skipped; TangoMonitor *channel_monitor; ChannelType channel_type; } EventChannelBase; typedef struct event_channel_zmq { string endpoint; size_t valid_endpoint; }EventChannelZmq; typedef struct channel_struct: public EventChannelBase, public EventChannelZmq { CosNotifyChannelAdmin::EventChannel_var eventChannel; CosNotifyChannelAdmin::StructuredProxyPushSupplier_var structuredProxyPushSupplier; CosNotifyFilter::FilterID heartbeat_filter_id; string notifyd_host; bool event_system_failed; long has_notifd_closed_the_connection; } EventChannelStruct; typedef std::map::iterator EvChanIte; typedef std::map::iterator EvCbIte; /******************************************************************************** * * * EventConsumer class * * * *******************************************************************************/ class EventConsumer { typedef void (*EventCallbackFunction)(string event_name,string event_type,Tango::DeviceAttribute *attr_value); public : EventConsumer(ApiUtil *ptr); virtual ~EventConsumer() {} int connect_event(DeviceProxy *,const string &,EventType,CallBack *,EventQueue *,const vector &,string &,int event_id = 0); void connect(DeviceProxy *,string &,DeviceData &,string &,bool &); void shutdown(); void shutdown_keep_alive_thread(); ChannelType get_event_system_for_event_id(int); virtual void cleanup_EventChannel_map() = 0; virtual void get_subscription_command_name(string &) = 0; int subscribe_event(DeviceProxy *device, const string &attribute, EventType event, CallBack *callback, const vector &filters, bool stateless = false); int subscribe_event(DeviceProxy *device, const string &attribute, EventType event, int event_queue_size, const vector &filters, bool stateless = false); int subscribe_event(DeviceProxy *device, EventType event,CallBack *callback,bool stateless = false); int subscribe_event(DeviceProxy *device, EventType event,int event_queue_size,bool stateless = false); void unsubscribe_event(int event_id); // methods to access data in event queues void get_events (int event_id, EventDataList &event_list); void get_events (int event_id, AttrConfEventDataList &event_list); void get_events (int event_id, DataReadyEventDataList &event_list); void get_events (int event_id, DevIntrChangeEventDataList &event_list); void get_events (int event_id, PipeEventDataList &event_list); void get_events (int event_id, CallBack *cb); int event_queue_size(int event_id); TimeVal get_last_event_date(int event_id); bool is_event_queue_empty(int event_id); int get_thread_id() {return thread_id;} void add_not_connected_event(DevFailed &,EventNotConnected &); static ReadersWritersLock &get_map_modification_lock() {return map_modification_lock;}; static KeepAliveThCmd cmd; static EventConsumerKeepAliveThread *keep_alive_thread; protected : int subscribe_event(DeviceProxy *device, const string &attribute, EventType event, CallBack *callback, EventQueue *ev_queue, const vector &filters, bool stateless = false); friend class EventConsumerKeepAliveThread; void attr_to_device(const AttributeValue *,const AttributeValue_3 *,long,DeviceAttribute *); void attr_to_device(const AttributeValue_4 *,DeviceAttribute *); void attr_to_device(const ZmqAttributeValue_4 *,DeviceAttribute *); void attr_to_device(const ZmqAttributeValue_5 *,DeviceAttribute *); template void base_attr_to_device(const T *,DeviceAttribute *); void att_union_to_device(const AttrValUnion *union_ptr,DeviceAttribute *dev_attr); void conf_to_info(AttributeConfig_2 &,AttributeInfoEx **); void get_cs_tango_host(Database *); static map device_channel_map; // key - device_name, value - channel name (full adm name) static map channel_map; // key - channel_name (full adm name), value - Event Channel info static map event_callback_map; // key - callback_key, value - Event CallBack info static ReadersWritersLock map_modification_lock; static vector event_not_connected; static int subscribe_event_id; // unique event id static vector env_var_fqdn_prefix; static map alias_map; // key - real host name, value - alias static omni_mutex ev_consumer_inst_mutex; string device_name; string obj_name_lower; int thread_id; int add_new_callback(EvCbIte &,CallBack *,EventQueue *,int); void get_fire_sync_event(DeviceProxy *,CallBack *,EventQueue *,EventType,string &,const string &,EventCallBackStruct &,string &); virtual void connect_event_channel(string &,Database *,bool,DeviceData &) = 0; virtual void disconnect_event_channel(TANGO_UNUSED(string &channel_name),TANGO_UNUSED(string &endpoint),TANGO_UNUSED(string &endpoint_event)) {} virtual void connect_event_system(string &,string &,string &e,const vector &,EvChanIte &,EventCallBackStruct &,DeviceData &,size_t) = 0; virtual void disconnect_event(string &,string &) {} virtual void set_channel_type(EventChannelStruct &) = 0; virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &) = 0; }; /******************************************************************************** * * * NotifdEventConsumer class * * * *******************************************************************************/ class NotifdEventConsumer : public POA_CosNotifyComm::StructuredPushConsumer , public EventConsumer , public omni_thread { public : static NotifdEventConsumer *create(); TANGO_IMP_EXP static void cleanup() {if (_instance != NULL){_instance=NULL;}} void push_structured_event(const CosNotification::StructuredEvent&); virtual void cleanup_EventChannel_map(); void disconnect_structured_push_consumer(); void offer_change(const CosNotification::EventTypeSeq &,const CosNotification::EventTypeSeq &); virtual void get_subscription_command_name(string &cmd) {cmd="EventSubscriptionChange";} CORBA::ORB_var orb_; protected : NotifdEventConsumer(ApiUtil *ptr); virtual void connect_event_channel(string &,Database *,bool,DeviceData &); virtual void connect_event_system(string &,string &,string &e,const vector &,EvChanIte &,EventCallBackStruct &,DeviceData &,size_t); virtual void set_channel_type(EventChannelStruct &ecs) {ecs.channel_type = NOTIFD;} virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &) {} private : TANGO_IMP static NotifdEventConsumer *_instance; CosNotifyChannelAdmin::EventChannel_var eventChannel; CosNotifyChannelAdmin::ConsumerAdmin_var consumerAdmin; CosNotifyChannelAdmin::ProxyID proxyId; CosNotifyChannelAdmin::ProxySupplier_var proxySupplier; CosNotifyChannelAdmin::StructuredProxyPushSupplier_var structuredProxyPushSupplier; CosNotifyChannelAdmin::EventChannelFactory_var eventChannelFactory; void *run_undetached(void *arg); }; /******************************************************************************** * * * ZmqEventConsumer class * * * *******************************************************************************/ class ZmqEventConsumer : public EventConsumer , public omni_thread { public : static ZmqEventConsumer *create(); TANGO_IMP_EXP static void cleanup() {if (_instance != NULL){_instance=NULL;}} virtual void cleanup_EventChannel_map(); virtual void get_subscription_command_name(string &cmd) {cmd="ZmqEventSubscriptionChange";} void get_subscribed_event_ids(DeviceProxy *,vector &); enum UserDataEventType { ATT_CONF = 0, ATT_READY, ATT_VALUE, DEV_INTR, PIPE }; enum SocketCmd { SUBSCRIBE = 0, UNSUBSCRIBE }; protected : ZmqEventConsumer(ApiUtil *ptr); virtual void connect_event_channel(string &,Database *,bool,DeviceData &); virtual void disconnect_event_channel(string &channel_name,string &endpoint,string &endpoint_event); virtual void connect_event_system(string &,string &,string &e,const vector &,EvChanIte &,EventCallBackStruct &,DeviceData &,size_t); virtual void disconnect_event(string &,string &); virtual void set_channel_type(EventChannelStruct &ecs) {ecs.channel_type = ZMQ;} virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &); private : TANGO_IMP static ZmqEventConsumer *_instance; zmq::context_t zmq_context; // ZMQ context zmq::socket_t *heartbeat_sub_sock; // heartbeat subscriber socket zmq::socket_t *control_sock; // control socket zmq::socket_t *event_sub_sock; // event subscriber socket map event_mcast; // multicast socket(s) vector connected_pub; // vector connected_heartbeat; // AttributeValue_var av; AttributeValue_3_var av3; ZmqAttributeValue_4 zav4; ZmqAttributeValue_5 zav5; AttributeConfig_2_var ac2; AttributeConfig_3_var ac3; AttributeConfig_5_var ac5; AttDataReady_var adr; DevIntrChange_var dic; ZmqDevPipeData zdpd; DevErrorList_var del; int old_poll_nb; TangoMonitor subscription_monitor; omni_mutex sock_bound_mutex; bool ctrl_socket_bound; void *run_undetached(void *arg); void push_heartbeat_event(string &); void push_zmq_event(string &,unsigned char,zmq::message_t &,bool,const DevULong &); bool process_ctrl(zmq::message_t &,zmq::pollitem_t *,int &); void process_heartbeat(zmq::message_t &,zmq::message_t &,zmq::message_t &); void process_event(zmq::message_t &,zmq::message_t &,zmq::message_t &,zmq::message_t &); void process_event(zmq_msg_t &,zmq_msg_t &,zmq_msg_t &,zmq_msg_t &); void multi_tango_host(zmq::socket_t *,SocketCmd,string &); void print_error_message(const char *mess) {ApiUtil *au=ApiUtil::instance();au->print_error_message(mess);} void set_ctrl_sock_bound() {sock_bound_mutex.lock();ctrl_socket_bound=true;sock_bound_mutex.unlock();} bool is_ctrl_sock_bound() {bool _b;sock_bound_mutex.lock();_b=ctrl_socket_bound;sock_bound_mutex.unlock();return _b;} bool check_zmq_endpoint(const string &); friend class DelayEvent; }; class DelayEvent { public: DelayEvent(EventConsumer *); ~DelayEvent(); void release(); private: bool released; ZmqEventConsumer *eve_con; }; /******************************************************************************** * * * EventConsumerKeepAliveThread class * * * *******************************************************************************/ class EventConsumerKeepAliveThread : public omni_thread { public : EventConsumerKeepAliveThread(const EventConsumer&); EventConsumerKeepAliveThread(KeepAliveThCmd &cmd):shared_cmd(cmd){}; void start() {start_undetached();} void stateless_subscription_failed(vector::iterator &,DevFailed &,time_t &); void fwd_not_conected_event(ZmqEventConsumer *); protected : KeepAliveThCmd &shared_cmd; private : void *run_undetached(void *arg); bool reconnect_to_channel(EvChanIte &,EventConsumer *); void reconnect_to_event(EvChanIte &,EventConsumer *); void re_subscribe_event(EvCbIte &,EvChanIte &); bool reconnect_to_zmq_channel(EvChanIte &,EventConsumer *,DeviceData &); void reconnect_to_zmq_event(EvChanIte &,EventConsumer *,DeviceData &); void not_conected_event(ZmqEventConsumer *,time_t,NotifdEventConsumer *); void confirm_subscription(ZmqEventConsumer *,map::iterator &); void main_reconnect(ZmqEventConsumer *,NotifdEventConsumer *,map::iterator &,map::iterator &); void re_subscribe_after_reconnect(ZmqEventConsumer *,NotifdEventConsumer *,map::iterator &,map::iterator &,string &); }; /******************************************************************************** * * * DelayedEventUnsubThread class * * * *******************************************************************************/ class DelayedEventUnsubThread: public omni_thread { public: DelayedEventUnsubThread(EventConsumer *ec,int id,TangoMonitor *m):omni_thread(),event_id(id),ev_cons(ec),the_mon(m) {} void run(void *); private: int event_id; EventConsumer *ev_cons; TangoMonitor *the_mon; }; /******************************************************************************** * * * DelayedEventSubThread class * * * *******************************************************************************/ class DelayedEventSubThread: public omni_thread { public: DelayedEventSubThread(EventConsumer *ec,DeviceProxy *_device, const string &_attribute, EventType _event, CallBack *_callback, EventQueue *_ev_queue, bool _stateless, const string &_ev_name, int _id):omni_thread(),ev_cons(ec),device(_device), attribute(_attribute),et(_event),callback(_callback),ev_queue(_ev_queue), stateless(_stateless),ev_id(_id),event_name(_ev_name) {} void run(void *); private: EventConsumer *ev_cons; DeviceProxy *device; string attribute; EventType et; CallBack *callback; EventQueue *ev_queue; bool stateless; int ev_id; string event_name; }; } // End of namespace #endif // _EVENTCONSUMER_H tango-9.2.5a/lib/cpp/client/filedatabase.h0000644023471100065110000001332313034744772015326 00000000000000// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef FILEDATABASE_H #define FILEDATABASE_H #include #include #include #include namespace Tango{ #define _TG_NUMBER 1 #define _TG_STRING 2 #define _TG_COMA 3 #define _TG_COLON 4 #define _TG_SLASH 5 #define _TG_ASLASH 6 #define _TG_ARROW 7 class t_property { public: std::string name; std::vector value; }; class t_attribute_property { public: std::string attribute_name; std::vector properties; }; class t_device { public: std::string name; std::vector properties; std::vector attribute_properties; }; class t_tango_class { public: std::string name; std::string description; std::string title; std::vector devices; std::vector properties; std::vector attribute_properties; }; class t_server { public: std::string name; std::string instance_name; std::vector classes; std::vector devices; }; template class hasName { string name; public: hasName (string _name) : name(_name) {}; bool operator () (T* obj); }; template class hasAttributeName { string attribute_name; public: hasAttributeName (string _name) : attribute_name(_name) {}; bool operator () (T* obj); }; class FileDatabaseExt { public: FileDatabaseExt(); ~FileDatabaseExt(); }; class FileDatabase { public: FileDatabase(const std::string& file_name); ~FileDatabase(); std::string parse_res_file(const std::string& file_name); void display(); string get_display(); void write_event_channel_ior(string &); CORBA::Any* DbInfo(CORBA::Any&); CORBA::Any* DbImportDevice(CORBA::Any&); CORBA::Any* DbExportDevice(CORBA::Any&); CORBA::Any* DbUnExportDevice(CORBA::Any&); CORBA::Any* DbAddDevice(CORBA::Any&); CORBA::Any* DbDeleteDevice(CORBA::Any&); CORBA::Any* DbAddServer(CORBA::Any&); CORBA::Any* DbDeleteServer(CORBA::Any&); CORBA::Any* DbExportServer(CORBA::Any&); CORBA::Any* DbUnExportServer(CORBA::Any&); CORBA::Any* DbGetServerInfo(CORBA::Any&); CORBA::Any* DbGetDeviceProperty(CORBA::Any&); CORBA::Any* DbPutDeviceProperty(CORBA::Any&); CORBA::Any* DbDeleteDeviceProperty(CORBA::Any&); CORBA::Any* DbGetDeviceAttributeProperty(CORBA::Any&); CORBA::Any* DbPutDeviceAttributeProperty(CORBA::Any&); CORBA::Any* DbDeleteDeviceAttributeProperty(CORBA::Any&); CORBA::Any* DbGetClassProperty(CORBA::Any&); CORBA::Any* DbPutClassProperty(CORBA::Any&); CORBA::Any* DbDeleteClassProperty(CORBA::Any&); CORBA::Any* DbGetClassAttributeProperty(CORBA::Any&); CORBA::Any* DbPutClassAttributeProperty(CORBA::Any&); CORBA::Any* DbDeleteClassAttributeProperty(CORBA::Any&); CORBA::Any* DbGetDeviceList(CORBA::Any&); CORBA::Any* DbGetDeviceDomainList(CORBA::Any&); CORBA::Any* DbGetDeviceMemberList(CORBA::Any&); CORBA::Any* DbGetDeviceExportedList(CORBA::Any&); CORBA::Any* DbGetDeviceFamilyList(CORBA::Any&); CORBA::Any* DbGetProperty(CORBA::Any&); CORBA::Any* DbPutProperty(CORBA::Any&); CORBA::Any* DbDeleteProperty(CORBA::Any&); CORBA::Any* DbGetAliasDevice(CORBA::Any&); CORBA::Any* DbGetDeviceAlias(CORBA::Any&); CORBA::Any* DbGetAttributeAlias(CORBA::Any&); CORBA::Any* DbGetDeviceAliasList(CORBA::Any&); CORBA::Any* DbGetAttributeAliasList(CORBA::Any&); CORBA::Any* DbGetClassPipeProperty(CORBA::Any&); CORBA::Any* DbGetDevicePipeProperty(CORBA::Any&); CORBA::Any* DbDeleteClassPipeProperty(CORBA::Any&); CORBA::Any* DbDeleteDevicePipeProperty(CORBA::Any&); CORBA::Any* DbPutClassPipeProperty(CORBA::Any&); CORBA::Any* DbPutDevicePipeProperty(CORBA::Any&); void write_file(); private: string filename; t_server m_server; void read_char(std::ifstream& f); int class_lex(std::string& word); void jump_line(std::ifstream& f); void jump_space(std::ifstream& f); std::string read_word(std::ifstream& f); void CHECK_LEX(int lt,int le); std::vector parse_resource_value(std::ifstream& f); std::string read_full_word(std::ifstream& f); void escape_double_quote(string &); static const char* lexical_word_null; static const char* lexical_word_number; static const char* lexical_word_string; static const char* lexical_word_coma; static const char* lexical_word_colon; static const char* lexical_word_slash; static const char* lexical_word_backslash; static const char* lexical_word_arrow; static int ReadBufferSize; static int MaxWordLength; int length_buf; int pos_buf; int CrtLine; int StartLine; char CurrentChar; char NextChar; bool DELETE_ENTRY; string word; FileDatabaseExt *ext; }; } // end namespace Tango #endif tango-9.2.5a/lib/cpp/client/group.h0000644023471100065110000023271213034744772014063 00000000000000//============================================================================= // // file : group.h // // description : Include for Tango Group impl. // // project : TANGO // // author(s) : N.Leclercq // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _GROUP_H_ #define _GROUP_H_ #include namespace Tango { /** @defgroup Grp Group Client classes * @ingroup Client */ //============================================================================= // THREAD SAFE IMPL OPTION //============================================================================= #define TANGO_GROUP_HAS_THREAD_SAFE_IMPL 1 //============================================================================= // FORWARD DECLARATIONS //============================================================================= class Group; class GroupElement; //============================================================================= // Misc. Typedefs //============================================================================= //- group content (individual devices and/or sub-groups) typedef std::vector GroupElements; //- group content iterator typedef GroupElements::iterator GroupElementsIterator; //----------------------------------------------------------------------------- //- define what is a list of token (for name pattern management) typedef std::vector TokenList; //============================================================================= // class ExtRequestDesc : an asynch. request holder for groups //----------------------------------------------------------------------------- class AsynchRequest { //- An asynch. request repository is maintain by each GroupDeviceElement friend class GroupDeviceElement; public: //- ctor AsynchRequest (long _rid, const std::string& _obj_name, bool ge_enabled = true) : rq_id(_rid), group_element_enabled_m(ge_enabled) { obj_names.push_back(_obj_name); }; //- ctor AsynchRequest (long _rid, const std::vector& _obj_names, bool ge_enabled = true) : rq_id(_rid), group_element_enabled_m(ge_enabled) { obj_names = _obj_names; }; //- ctor AsynchRequest (long _rid, const std::string& _obj_name, const DevFailed& _df) : rq_id(_rid), rq_ex(_df), group_element_enabled_m(true) { obj_names.push_back(_obj_name); }; //- ctor AsynchRequest (long _rid, const std::vector& _obj_names, const DevFailed& _df) : rq_id(_rid), rq_ex(_df), group_element_enabled_m(true) { obj_names = _obj_names; }; //- dtor virtual ~AsynchRequest () { //-noop impl }; //- group_element_enabled accessor inline bool group_element_enabled () const { return group_element_enabled_m; } private: //- request ID long rq_id; //- name of requested objects (command or attribute) std::vector obj_names; //- DevFailed containing potential error DevFailed rq_ex; //- true is the associated group member is enabled, false otherwise bool group_element_enabled_m; }; //----------------------------------------------------------------------------- //- asynch. request repository typedef std::map AsynchRequestRep; //- asynch. request repository iterator typedef AsynchRequestRep::iterator AsynchRequestRepIterator; //- asynch. request repository value typedef AsynchRequestRep::value_type AsynchRequestRepValue; //============================================================================= //============================================================================= // class GroupReply : base class for group reply //============================================================================= /** * Base class for Group reply * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupReply { public: ///@privatesection //- default ctor GroupReply (); //- copy ctor GroupReply (const GroupReply& src); //- ctor GroupReply (const std::string& dev_name, const std::string& obj_name, bool group_element_enabled = true); //- ctor GroupReply (const std::string& dev_name, const std::string& obj_name, const DevFailed& exception, bool group_element_enabled = true); //- dtor virtual ~GroupReply (); //- group_element_enabled accessor inline bool group_element_enabled () const { return group_element_enabled_m; } ///@publicsection //- enable/disable exception - returns the previous mode /** * Enable/Disable exception * * Set the group exception mode. If set to true, exception will be thrown * (when needed) by the library when the user get command execution result. * If set to false (the default), the user has to deal with the has_failed() * exception to manage cases of wrong execution command. * * @param [in] exception_mode The new exception mode * @return The previous exception mode */ static bool enable_exception (bool exception_mode = true); //- has_failed accessor /** * Check if an error has occured * * Returns a boolean set to true if the command executed on the group * element has failed. Otherwise, returns false * * @return The error flag */ inline bool has_failed () const { return has_failed_m; } //- device name accessor /** * Get device name * * Returns the device name for the group element * * @return The device name */ inline const std::string& dev_name () const { return dev_name_m; } //- object (i.e. command or attribute) name accessor /** * Get object name * * Returns the object name (i.e. command or attribute) for the group element * * @return The object name */ inline const std::string& obj_name () const { return obj_name_m; } //- error stack accessor /** * Get error stack * * Returns the error stack for the group element * * @return The error stack */ inline const DevErrorList& get_err_stack () const { return exception_m.errors; } protected: ///@privatesection //- exception flag (enable/disable) static bool exception_enabled; //- the device name std::string dev_name_m; //- command or attribute name std::string obj_name_m; //- has_failed_m: true is an error occurred, false otherwise bool has_failed_m; //- group_element_enabled_m : true is the associated group member is enabled, false otherwise bool group_element_enabled_m; //- exception: valid if has_failed_m set to true DevFailed exception_m; }; //============================================================================= // class GroupCmdReply : reply to command executed on a group //============================================================================= /** * Single element group reply for a command execution * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupCmdReply : public GroupReply { public: ///@privatesection //- default ctor GroupCmdReply (); //- copy ctor GroupCmdReply (const GroupCmdReply& src); //- GroupCmdReply (const std::string& dev_name, const std::string& obj_name, const DeviceData& data); //- ctor GroupCmdReply (const std::string& dev_name, const std::string& obj_name, const DevFailed& exception); //- ctor GroupCmdReply (const std::string& dev_name, const std::string& obj_name, bool group_element_enabled); //- dtor virtual ~GroupCmdReply (); ///@publicsection //- data accessor (may throw Tango::DevFailed) /** * Get command data * * Get command result for a device member of a group hierarchy * * @return The command data */ DeviceData& get_data (); //- template data exctractor method /** * Get command data and extract them * * Get command result for a device member of a group hierarchy and extract * them in the provided variable * * @param [out] dest The variable in which the data should be extracted * @return Flag set to true if the extraction succeeds */ template bool operator>> (T& dest); //- data exctractor method for DevVarLongStringArray /** * Get command data and extract them (DevVarLongStringArray) * * Get command result for a device member of a group hierarchy and extract * them in the provided variable in case the command returns a * data of the DevVarLongStringArray type * * @param [out] vl The array of DevLong part of the DevVarLongStringArray * @param [out] vs The array of string part of the DevVarLongStringArray data * @return Flag set to true if the extraction succeeds */ bool extract (std::vector& vl, std::vector& vs); //- data exctractor method for DevVarDoubleStringArray /** * Get command data and extract them (DevVarDoubleStringArray) * * Get command result for a device member of a group hierarchy and extract * them in the provided variable in case the command returns a * data of the DevVarDoubleStringArray type * * @param [out] vd The array of DevDouble part of the DevVarDoubleStringArray * @param [out] vs The array of string part of the DevVarDoubleStringArray data * @return Flag set to true if the extraction succeeds */ bool extract (std::vector& vd, std::vector& vs); private: //- data: valid if GroupReply::has_failed_m set to false and //- GroupReply::enabled_m set to true DeviceData data_m; }; //============================================================================= // class GroupAttrReply : reply to an attribute reading executed on a group //============================================================================= /** * Single element group reply for a read attribute execution * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupAttrReply : public GroupReply { public: ///@privatesection //- ctor GroupAttrReply (); //- copy ctor GroupAttrReply (const GroupAttrReply& src); //- ctor GroupAttrReply (const std::string& dev_name, const std::string& obj_name, const DeviceAttribute& data); //- ctor GroupAttrReply (const std::string& dev_name, const std::string& obj_name, const DevFailed& exception); //- ctor GroupAttrReply (const std::string& dev_name, const std::string& obj_name, bool group_element_enabled); //- dtor virtual ~GroupAttrReply (); ///@publicsection //- data accessor (may throw Tango::DevFailed) /** * Get attribute data * * Get attribute data for a device member of a group hierarchy * * @return The attribute data */ DeviceAttribute& get_data (); //- template data exctractor method /** * Get attribute data and extract them * * Get attribute data for a device member of a group hierarchy and extract * them in the provided variable * * @param [out] dest The variable in which the data should be extracted * @return Flag set to true if the extraction succeeds */ template bool operator>> (T& dest); private: //- data: valid if GroupReply::has_failed_m set to false and //- GroupReply::enabled_m set to true DeviceAttribute data_m; }; //============================================================================= // class GroupReplyList : a simple list of GroupReply //============================================================================= /** * Group reply for a write_attribute execution * * This class inherits from @b vector and therefore, each * device in the group heierarchy has his own GroupReply object * which can be retrieved with the classical vector [] operator * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupReplyList : public std::vector { ///@privatesection typedef std::vector Inherited; friend class Group; public: ///@privatesection //- ctor GroupReplyList(); //- dtor virtual ~GroupReplyList(); ///@publicsection //- has_failed accessor /** * Check if an error has occured * * Returns a boolean set to true if the write_attribute executed on the group has failed * for any device member of the hierarchy. Otherwise, returns false * * @return The error flag */ bool has_failed () const { return has_failed_m; } //- reset the error list /** * Reset the object * * This methods empty the inherited vector and reset the error flag */ inline void reset () { clear(); has_failed_m = false; }; ///@privatesection //- push_back overload void push_back (const GroupReply& r) { if (r.has_failed()) { has_failed_m = true; } Inherited::push_back(r); } private: //- has_failed_m: true if at least one error occurred, false otherwise bool has_failed_m; }; //============================================================================= // class GroupCmdReplyList : a simple list of GroupCmdReply //============================================================================= /** * Group reply for a command execution * * This class inherits from @b vector and therefore, each * device in the group heierarchy has his own GroupCmdReply object * which can be retrieved with the classical vector [] operator * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupCmdReplyList : public std::vector { ///@privatesection typedef std::vector Inherited; friend class Group; public: ///@privatesection //- ctor GroupCmdReplyList(); //- dtor virtual ~GroupCmdReplyList(); ///@publicsection //- has_failed accessor method /** * Check if an error has occured * * Returns a boolean set to true if the command executed on the group has failed * for any device member of the hierarchy. Otherwise, returns false * * @return The error flag */ bool has_failed () const { return has_failed_m; } //- reset the error list /** * Reset the object * * This methods empty the inherited vector and reset the error flag */ inline void reset () { clear(); has_failed_m = false; }; ///@privatesection //- push_back overload void push_back (const GroupCmdReply& cr) { if (cr.has_failed()) { has_failed_m = true; } Inherited::push_back(cr); } private: //- has_failed_m: true if at least one error occurred, false otherwise bool has_failed_m; }; //============================================================================= // class GroupAttrReplyList : a simple list of GroupAttrReply //============================================================================= /** * Group reply for a read_attribute execution * * This class inherits from @b vector and therefore, each * device in the group heierarchy has his own GroupAttrReply object * which can be retrieved with the classical vector [] operator * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class GroupAttrReplyList : public std::vector { ///@privatesection typedef std::vector Inherited; friend class Group; public: ///@privatesection //- ctor GroupAttrReplyList(); //- dtor virtual ~GroupAttrReplyList(); ///@publicsection //- has_failed accessor method /** * Check if an error has occured * * Returns a boolean set to true if the read_attribute executed on the group has failed * for any device member of the hierarchy. Otherwise, returns false * * @return The error flag */ bool has_failed () const { return has_failed_m; } //- reset the error list /** * Reset the object * * This methods empty the inherited vector and reset the error flag */ inline void reset () { clear(); has_failed_m = false; }; ///@privatesection //- push_back overload void push_back (const GroupAttrReply& ar) { if (ar.has_failed()) { has_failed_m = true; } Inherited::push_back(ar); } private: //- has_failed_m: true if at least one error occurred, false otherwise bool has_failed_m; }; //============================================================================= // class GroupElementFactory : a GroupElement factory //============================================================================= class GroupElementFactory { friend class Group; //- instanciatethe GroupElement which name matches the specified pattern with the specified timeout //- timeout = -1 => do not change the timeout static GroupElements instanciate (const std::string& p, int tmo = -1); static void parse_name (const std::string& p, std::string &db_host, int &db_port, std::string &dev_pattern); //- forbidden methods GroupElementFactory(); ~GroupElementFactory(); GroupElementFactory& operator=(const GroupElementFactory& other); }; //============================================================================= // class GroupElement: base class for all tango group element //============================================================================= class GroupElement { friend class Group; public: //--------------------------------------------- //- Group management methods //--------------------------------------------- //- virtual bool contains (const std::string& n, bool fwd = true); //- virtual DeviceProxy* get_device (const std::string& n) = 0; //- virtual DeviceProxy* get_device (long idx) = 0; //- virtual DeviceProxy* operator[] (long idx) = 0; //--------------------------------------------- //- a la DeviceProxy interface //--------------------------------------------- //- virtual bool ping (bool fwd = true) = 0; //- virtual void set_timeout_millis (int tmo_ms) = 0; //--------------------------------------------- //- Misc. //--------------------------------------------- //- inline const std::string& get_name () const { return name; }; //- inline const std::string get_fully_qualified_name () const { if (parent) { return parent->get_fully_qualified_name() + "." + name; } return name; }; //- inline void enable () { enabled = true; }; //- inline void disable () { enabled = false; }; //- inline bool is_enabled () const { return enabled; }; bool name_equals (const std::string& n); //- bool name_matches (const std::string& n); //- virtual void dump (int indent_level = 0) = 0; //- virtual void dump (TangoSys_OMemStream& oms, int indent_level = 0) = 0; //- virtual bool is_connected(); protected: //- ctor: creates an GroupElement named GroupElement (const std::string& name, GroupElement* parent = 0); //- dtor virtual ~GroupElement(); private: //- element name std::string name; //- parent element GroupElement* parent; //- enabled: true is this group member is enabled, false otherwise bool enabled; //- forbidden methods GroupElement (); GroupElement (const GroupElement&); GroupElement& operator=(const GroupElement&); //- element name tokenizer TokenList tokenize_i (const std::string& p); //- element name pattern matching bool match_i (const std::string& p, const TokenList& tokens); //- element identification virtual bool is_device_i () = 0; virtual bool is_group_i () = 0; //- group interface virtual long get_size_i (bool fwd = true) = 0; //- element searching virtual GroupElement* find_i (const std::string& n, bool fwd = true); //- private part of the asynch command exec. impl. virtual long command_inout_asynch_i (const std::string& c, bool fgt, bool fwd , long ari) = 0; virtual long command_inout_asynch_i (const std::string& c, const DeviceData& d, bool fgt, bool fwd, long ari) = 0; virtual GroupCmdReplyList command_inout_reply_i (long req_id, long tmo_ms) = 0; //- private part of the asynch attribute(s) reading impl. virtual long read_attribute_asynch_i (const std::string& a, bool fwd, long ari) = 0; virtual GroupAttrReplyList read_attribute_reply_i (long req_id, long tmo_ms) = 0; virtual long read_attributes_asynch_i (const std::vector& al, bool fwd, long ari) = 0; virtual GroupAttrReplyList read_attributes_reply_i (long req_id, long tmo_ms) = 0; //- private part of the asynch attribute writting impl. virtual long write_attribute_asynch_i (const DeviceAttribute& d, bool fwd, long ari) = 0; virtual GroupReplyList write_attribute_reply_i (long req_id, long tmo_ms) = 0; //- set the parent element, returns previous parent or 0 (null) if none GroupElement* set_parent (GroupElement* _parent); }; //============================================================================= // class Group: actual tango group implementation //============================================================================= /** * High level class allowing the user to handle Tango group * * $Author: taurel $ * $Revision: 27410 $ * * @headerfile tango.h * @ingroup Grp */ class Group : public GroupElement { typedef std::map AsynchRequestDesc; typedef AsynchRequestDesc::iterator AsynchRequestDescIt; typedef AsynchRequestDesc::value_type AsynchRequestDescVal; public: //--------------------------------------------- //- Ctor & Dtor //--------------------------------------------- /**@name Constructor and destructor */ //@{ /** * Create a Group instance * * Instanciate an empty group. The group name allows retrieving a sub-group in the hierarchy. * * @param name The group name */ Group (const std::string& name); /** * Create a Group instance * * Delete a group and all its elements. * Be aware that a group always gets the ownership of its children and deletes themwhen it is itself deleted. * Therefore, never try to delete a Group (respectively a DeviceProxy) returned by a call to @e Tango::Group::get_group() * (respectively to @e Tango::Group::get_device()). Use the @e Tango::Group::remove() method instead. */ virtual ~Group(); //@} //--------------------------------------------- //- Group management methods //--------------------------------------------- /**@name Group management related methods */ //@{ /** * Attaches a (sub) group * * Be aware that a group always gets the ownership of its children and deletes them when it is itself * deleted. Therefore, never try to delete a Group attached to a Group. Use the Group::remove() method * instead. * If timeout_ms parameter is different from -1, the client side timeout associated to each device composing * the group added is set to timeout_ms milliseconds. If timeout_ms is -1, timeouts are not changed. * This method does nothing if the specified group is already attached (i.e. it is silently ignored) and * timeout_ms = -1. * If the specified group is already attached and timeout_ms is different from -1, the client side timeout of * each device composing the group given in parameter is set to timeout_ms milliseconds. * * @param [in] group The group to be attached * @param [in] tmo_ms The timeout value */ virtual void add (Group* group, int tmo_ms = -1); /** * Attaches any device which name matches the specified pattern * * The pattern parameter can be a simple device name or a device name pattern (e.g. domain_* / family/ * member_*). * This method first asks to the Tango database the list of device names matching the pattern. Devices are * then attached to the group in the order in which they are returned by the database. * Any device already present in the hierarchy (i.e. a device belonging to the group or to one of its * subgroups) is silently ignored but its client side timeout is set to timeout_ms milliseconds if timeout_ms is * different from -1. * Set the client side timeout of each device matching the specified pattern to timeout_ms milliseconds if * timeout_ms is different from -1. * * @param [in] pattern The device selection pattern * @param [in] tmo_ms The timeout value */ virtual void add (const std::string& pattern, int tmo_ms = -1); /** * Attaches any device which name matches one of the specified pattern * * The patterns parameter can be an array of device names and/or device name patterns. * Thismethod first asks to the Tango database the list of device namesmatching one the patterns. Devices * are then attached to the group in the order in which they are returned by the database. * Any device already present in the hierarchy (i.e. a device belonging to the group or to one of its * subgroups), is silently ignored but its client side timeout is set to timeout_ms milliseconds if timeout_ms is * different from -1. * If timeout_ms is different from -1, the client side timeouts of all devices matching the specified patterns * are set to timeout_ms milliseconds. * * @param [in] patterns The device selection pattern list * @param [in] tmo_ms The timeout value */ virtual void add (const std::vector& patterns, int tmo_ms = -1); #ifdef GEN_DOC /** * Removes any group or device which name matches the specified pattern. * * The pattern parameter can be a group name, a device name or a device name pattern (e.g domain_* /family/member_*). * Since we can have groups with the same name in the hierarchy, a group name can be fully qualified to * specify which group should be removed. Considering the following group: * @verbatim -> gauges | -> cell-01 | | -> penning | | | -> ... | | -> pirani | | | -> ... | -> cell-02 | | -> penning | | | -> ... | | -> pirani | | | -> ... | -> cell-03 | | -> ... @endverbatim * A call to gauges->remove("penning") will remove any group named "penning" in the hierarchy while * gauges->remove("gauges.cell-02.penning") will only remove the specified group. * If fwd is set to true (the default), the remove request is also forwarded to subgroups. Otherwise, it is * only applied to the local set of elements. For instance, the following code remove any stepper motor in the * hierarchy: * @code * root_group->remove("*/stepper_motor/*"); * @endcode * * @param [in] pattern The device selection pattern * @param [in] fwd The forward flag */ #endif virtual void remove (const std::string& pattern, bool fwd = true); /** * Removes any group or device which name matches any of the specified patterns. * * The patterns parameter can be an array of group names and/or device names and/or device name patterns. * Since we can have groups with the same name in the hierarchy, a group name can be fully qualified to * specify which group should be removed. See previous method for details. * If fwd is set to true (the default), the remove request is also forwarded to subgroups. Otherwise, it is * only applied to the local set of elements. * * @param [in] patterns The device selection patterns * @param [in] fwd The forward flag */ virtual void remove (const std::vector& patterns, bool fwd = true); /** * Removes all elements in the group * * Removes all elements in the group. After such a call, the group is empty. */ virtual void remove_all (); /** * Check if the hierarchy contains groups and/or devices which name matches the specified pattern. * * Returns true if the hierarchy contains groups and/or devices which name matches the specified pattern. * Returns false otherwise. * The pattern can be a fully qualified or simple group name, a device name or a device name pattern. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of elements. * * @param [in] pattern The device selection pattern * @param [in] fwd The forward flag * @return True if the hierarchy contains the element */ virtual bool contains (const std::string& pattern, bool fwd = true); /** * Returns a reference to the specified device * * Returns a reference to the specified device or NULL if there is no device by that name in the group. This * method may throw an exception in case the specified device belongs to the group but can’t be reached (not * registered, down...). See example below. See also the Tango::DeviceProxy class documentation for details. * @code * try * { * Tango::DeviceProxy *dp = g->get_device("my/device/01"); * if (dp == 0) * { * // my/device/01 does not belongs to the group * } * } * catch (const Tango::DevFailed &df) * { * // my/device/01 belongs to the group but can’t be reached * } * @endcode * The request is systematically forwarded to subgroups (i.e. if no device named device_name could be * found in the local set of devices, the request is forwarded to subgroups). * Be aware that a group always gets the ownership of its children and deletes them when it is itself * deleted. Therefore, never try to delete a DeviceProxy returned by the Group::get_device()method. Use the * Tango::Group::remove() method instead. * * @param [in] device_name The device name * @return True if the hierarchy contains the element */ virtual DeviceProxy* get_device (const std::string& device_name); /** * Returns a reference to the "idx-th" device in the hierarchy * * Returns a reference to the "idx-th" device in the hierarchy or NULL if the hierarchy contains less than * "idx" devices. This method may throw an exception in case the specified device belongs to the group but * can’t be reached (not registered, down...). See previous example. See also the Tango::DeviceProxy class * documentation for details. * The request is systematically forwarded to subgroups (i.e. if the local set of devices contains less than * "idx" devices, the request is forwarded to subgroups). * Be aware that a group always gets the ownership of its children and deletes them when it is itself * deleted. Therefore, never try to delete a DeviceProxy returned by the Group::get_device()method. Use the * Tango::Group::remove() method instead. * * @param [in] idx The device name * @return device reference */ virtual DeviceProxy* get_device (long idx); /** * Returns a reference to the "idx-th" device in the hierarchy * * Returns a reference to the "idx-th" device in the hierarchy or NULL if the hierarchy contains less than "idx" * devices. See the Tango::DeviceProxy class documentation for details. * The request is systematically forwarded to subgroups (i.e. if the local set of devices contains less than * "idx" devices, the request is forwarded to subgroups). * Be aware that a group always gets the ownership of its children and deletes them when it is itself * deleted. Therefore, never try to delete a DeviceProxy returned by the Group::get_device()method. Use the * Tango::Group::remove() method instead. * * @param [in] idx The device name * @return device reference */ virtual DeviceProxy* operator[] (long idx); /** * Returns a reference to the specified group * * Returns a reference to the specified group or NULL if there is no group by that name. The group_name * can be a fully qualified name. * Considering the following group: * @verbatim -> gauges | -> cell-01 | | -> penning | | | -> ... | | -> pirani | | | -> ... | -> cell-02 | | -> penning | | | -> ... | | -> pirani | | | -> ... | -> cell-03 | | -> ... @endverbatim * A call to gauges->get_group("penning") returns the first group named "penning" in the hierarchy (i.e. * gauges.cell-01.penning)while gauges->get_group("gauges.cell-02.penningâ€) returns the specified group. * The request is systematically forwarded to subgroups (i.e. if no group named group_name could be * found in the local set of elements, the request is forwarded to subgroups). * Be aware that a group always gets the ownership of its children and deletes them when it is itself * deleted. Therefore, never try to delete a Group returned by the Group::get_group() method. Use the * Tango::Group::remove() method instead. * * @param [in] group_name The group name * @return group pointer */ virtual Group* get_group (const std::string& group_name); /** * Return the number of devices in the hierarchy * * Return the number of devices in the hierarchy (respectively the number of device in the group) if the * forward option is set to true (respectively set to false) * * @param [in] fwd The forward flag * @return group size */ long get_size (bool fwd = true); /** * Returns the list of devices currently in the hierarchy. * * Returns the list of devices currently in the hierarchy. * If fwd is set to true (the default) the request is forwarded to subgroups. Otherwise, it is only applied to * the local set of devices. * Considering the following hierarchy: * @code * g2->add("my/device/04"); g2->add("my/device/05"); * * g4->add("my/device/08"); g4->add("my/device/09"); * * g3->add("my/device/06"); * g3->addg(g4); * g3->add("my/device/07"); * * g1->add("my/device/01"); * g1->add(g2); * g1->add("my/device/03"); * g1->add(g3); * g1->add("my/device/02"); * @endcode * The returned vector content depends on the value of the forward option. If set to true, the results will be * organized as follows: * @code * std::vector dl = g1->get_device_list(true); * @endcode * dl[0] contains "my/device/01" which belongs to g1 * @n dl[1] contains "my/device/04" which belongs to g1.g2 * @n dl[2] contains "my/device/05" which belongs to g1.g2 * @n dl[3] contains "my/device/03" which belongs to g1 * @n dl[4] contains "my/device/06" which belongs to g1.g3 * @n dl[5] contains "my/device/08" which belongs to g1.g3.g4 * @n dl[6] contains "my/device/09" which belongs to g1.g3.g4 * @n dl[7] contains "my/device/07" which belongs to g1.g3 * @n dl[8] contains "my/device/02" which belongs to g1 * @n @n If the forward option is set to false, the results are: * @code * std::vector dl = g1->get_device_list(false); * @endcode * dl[0] contains "my/device/01" which belongs to g1 * @n dl[1] contains "my/device/03" which belongs to g1 * @n dl[2] contains "my/device/02" which belongs to g1 * * @param [in] fwd The forward flag * @return group size */ std::vector get_device_list (bool fwd = true); //- //@} ///@privatesection //- virtual Group* get_parent () const; //- void enable (const std::string& device_name, bool fwd = true); //- void disable (const std::string& device_name, bool fwd = true); //- bool is_enabled (const std::string& device_name, bool fwd = true) { GroupElement * ge = this->find_i(device_name, fwd); return ge ? ge->is_enabled() : false; }; //- bool is_root_group () const; //--------------------------------------------- //- a la DeviceProxy interface //--------------------------------------------- ///@publicsection ///@name a la Deviceproxy interface //@{ //- misc. //--------------------------------------------- /** * Ping all devices in a group * * Ping all devices in a group. This method returns true if all devices in the group are alive, false otherwise. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * * @param [in] fwd The forward flag * @return True if all devices are alive */ virtual bool ping (bool fwd = true); /** * Set client side timeout for all devices in the group * * Set client side timeout for all devices composing the group in milliseconds. Any method which takes longer * than this time to execute will throw an exception. * * @param [in] tmo_ms The timeout value */ virtual void set_timeout_millis (int tmo_ms); //- command execution //--------------------------------------------- /** * Executes a Tango command on a group * * Executes a Tango command on a group. This method is synchronous and does not return until replies are * obtained or timeouts occurred. * The parameter c is the name of the command. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * Command results are returned in a GroupCmdReplyList. See Obtaining command result for details * (Chapter 4.7.3.1 in Tango book). See also Case 1 of executing a command * (Chapter 4.7.3.2 in Tango book) for an example. * * @param [in] c The command name * @param [in] fwd The forward flag * @return The group command result */ GroupCmdReplyList command_inout (const std::string& c, bool fwd = true); /** * Executes a Tango command with the same input data on a group * * Executes a Tango command on each device in the group. This method is synchronous and does not return * until replies are obtained or timeouts occurred. * The parameter c is the name of the command. * The second parameter d is a Tango generic container for command carrying the command argument. * See the Tango::DeviceData documentation. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * Command results are returned in a GroupCmdReplyList. See Obtaining command results * (Chapter 4.7.3.1 in Tango book) for * details. See also Case 2 of executing a command (Chapter 4.7.3.4 in * Tango book) for an example. * * @param [in] c The command name * @param [in] d The command data * @param [in] fwd The forward flag * @return The group command result */ GroupCmdReplyList command_inout (const std::string& c, const DeviceData& d, bool fwd = true); /** * Executes a Tango command with the different input data on a group (Using DeviceData class instances) * * Executes a Tango command on each device in the group. This method is synchronous and does not return * until replies are obtained or timeouts occurred. * This implementation of command_inout allows passing a specific input argument to each device in * the group. In order to use this form of command_inout, the user must have an "a priori" and "perfect" * knowledge of the devices order in the group. * @n The parameter c is the name of the command. * The std::vector d contains a specific argument value for each device in the group. Its size must equal Group::get_size(fwd). * Otherwise, an exception is thrown. The order of the argument values must follows the order of the devices * in the group (d[0] => 1st device, d[1] => 2nd device and so on). * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * Command results are returned in a GroupCmdReplyList. See Obtaining command results (Chpater 4.7.3.1 in * Tango book) * for details. See also Case 3 of executing a command (Chapter 4.7.3.5 in * Tango book) for an example of this special form of * command_inout. * * @param [in] c The command name * @param [in] d The command data * @param [in] fwd The forward flag * @return The group command result */ GroupCmdReplyList command_inout (const std::string& c, const std::vector& d, bool fwd = true); /** * Executes a Tango command with the different input data on a group * * Executes a Tango command on each device in the group. This method is synchronous and does not return * until replies are obtained or timeouts occurred. * This implementation of command_inout allows passing a specific input argument to each device in * the group. In order to use this form of command_inout, the user must have an "a priori" and "perfect" * knowledge of the devices order in the group. * @n The parameter c is the name of the command. * The std::vector d contains a specific argument value for each device in the group. Since this method is a * template, d is able to contain any Tango command argument type. Its size must equal Group::get_size(fwd). * Otherwise, an exception is thrown. The order of the argument values must follows the order of the devices * in the group (d[0] => 1st device, d[1] => 2nd device and so on). * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * Command results are returned in a GroupCmdReplyList. See Obtaining command results (Chpater 4.7.3.1 in * Tango book) * for details. See also Case 3 of executing a command (Chapter 4.7.3.5 in * Tango book) for an example of this special form of * command_inout. * * @tparam T The command input data type * @param [in] c The command name * @param [in] d The command data * @param [in] fwd The forward flag * @return The group command result */ template GroupCmdReplyList command_inout (const std::string& c, const std::vector& d, bool fwd = true); /** * Executes a Tango command on each device in the group asynchronously. * * Executes a Tango command on each device in the group asynchronously. The method sends the request * to all devices and returns immediately. Pass the returned request id to Group::command_inout_reply() to * obtain the results. * The parameter c is the name of the command. * The parameter fgt is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller * does not care about it and will not even try to get it). A false default value is provided. * If the parameter fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * See Case 1 of Executing a command (Chapter 4.7.3.2 in * Tango book) for an example. * * @param [in] c The command name * @param [in] fgt The command data * @param [in] fwd The forward flag * @return The call identifier */ long command_inout_asynch (const std::string& c, bool fgt = false, bool fwd = true); /** * Executes a Tango command with same input data on each device in the group asynchronously. * * Executes a Tango command on each device in the group asynchronously. The method sends the request * to all devices and returns immediately. Pass the returned request id to Group::command_inout_reply() to * obtain the results. * The parameter c is the name of the command. * The second parameter d is a Tango generic container for command carrying the command argument. * See the Tango::DeviceData documentation for details. * The parameter fgt is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller * does not care about it and will not even try to get it). A false default value is provided. * If the parameter fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * See Case 2 of Executing a command (Chapter 4.7.3.4 in * Tango book) for an example. * * @param [in] c The command name * @param [in] d The command input data * @param [in] fgt The command data * @param [in] fwd The forward flag * @return The call identifier */ long command_inout_asynch (const std::string& c, const DeviceData& d, bool fgt = false, bool fwd = true); /** * Executes a Tango command with different input data (using DeviceData object) on each device in the group asynchronously. * * Executes a Tango command on each device in the group asynchronously. The method send the request to * all devices and return immediately. Pass the returned request id to Group::command_inout_reply to obtain * the results. * This implementation of command_inout allows passing a specific input argument to each device in the * group. In order to use this form of command_inout_asynch, the user must have an "a priori" and "perfect" * knowledge of the devices order in the group. * The parameter c is the name of the command. * The std::vector d contains a specific argument value for each device in the group. Its size must equal Group::get_size(fwd). Otherwise, an exception is * thrown. The order of the argument values must follows the order of the devices in the group (d[0] => 1st * device, d[1] => 2nd device and so on). * The parameter fgt is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller * does not care about it and will not even try to get it). A false default value is provided. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * See Case 3 of Executing a command (Chapter 4.7.3.5 in * Tango book) for an example of this special form of command_inout. * * @param [in] c The command name * @param [in] d The command input data * @param [in] fgt The command data * @param [in] fwd The forward flag * @return The call identifier */ long command_inout_asynch (const std::string& c, const std::vector& d, bool fgt = false, bool fwd = true); /** * Executes a Tango command with different input data on each device in the group asynchronously. * * Executes a Tango command on each device in the group asynchronously. The method send the request to * all devices and return immediately. Pass the returned request id to Group::command_inout_reply to obtain * the results. * This implementation of command_inout allows passing a specific input argument to each device in the * group. In order to use this form of command_inout_asynch, the user must have an "a priori" and "perfect" * knowledge of the devices order in the group. * The parameter c is the name of the command. * The std::vector d contains a specific argument value for each device in the group. Since it's a template data type, d is able to contain * any Tango command argument type. Its size must equal Group::get_size(fwd). Otherwise, an exception is * thrown. The order of the argument values must follows the order of the devices in the group (d[0] => 1st * device, d[1] => 2nd device and so on). * The parameter fgt is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller * does not care about it and will not even try to get it). A false default value is provided. * If fwd is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only * applied to the local set of devices. * See Case 3 of Executing a command (Chapter 4.7.3.5 in * Tango book) for an example of this special form of command_inout. * * @tparam T The command input data type * @param [in] c The command name * @param [in] d The command input data * @param [in] fgt The command data * @param [in] fwd The forward flag * @return The call identifier */ template long command_inout_asynch (const std::string& c, const std::vector& d, bool fgt = false, bool fwd = true); /** * Returns the results of an asynchronous command. * * Returns the results of an asynchronous command. * The first parameter req_id is a request identifier previously returned by one of the command_inout_asynch * methods. * For each device in the hierarchy, if the command result is not yet available, command_inout_replywait * timeout_ms milliseconds before throwing an exception. This exception will be part of the global reply. If * timeout_ms is set to 0, command_inout_reply waits "indefinitely". * Command results are returned in a GroupCmdReplyList. See Obtaining command results (Chapter 4.7.3.1 in * Tango book) for * details. * * @param [in] req_id The request identifier * @param [in] tmo_ms The timeout value * @return The group command result */ GroupCmdReplyList command_inout_reply (long req_id, long tmo_ms = 0); //- attribute(s) reading //--------------------------------------------- /** * Reads an attribute on each device in the group * * Reads an attribute on each device in the group. This method is synchronous and does not return until replies * are obtained or timeouts occurred. * The parameter a is the name of the attribute to read. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * Attribute values are returned in a GroupAttrReplyList. See Obtaining attribute values (Chapter 4.7.4.1 in * Tango book) for * details. See also Reading an attribute (Chapter 4.7.4 in * Tango book) for an example. * * @param [in] a The attribute name * @param [in] fwd The forward flag * @return The group attribute data */ GroupAttrReplyList read_attribute (const std::string& a, bool fwd = true); /** * Reads several attributes on each device in the group * * Reads several attributes on each device in the group. This method is synchronous and does not return until replies * are obtained or timeouts occurred. * The parameter al is the list of attributes to be read. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * Attribute values are returned in a GroupAttrReplyList. See Obtaining attribute values (Chapter 4.7.4.1 in * Tango book) for * details. See also Reading an attribute (Chapter 4.7.4 in * Tango book) for an example. * * @param [in] al The attribute name list * @param [in] fwd The forward flag * @return The group attribute data */ GroupAttrReplyList read_attributes (const std::vector& al, bool fwd = true); /** * Reads an attribute on each device in the group asynchronously * * Reads an attribute on each device in the group asynchronously. The method sends the request to all devices * and returns immediately. Pass the returned request id to Group::read_attribute_reply() to obtain the results. * The parameter a is the name of the attribute to read. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * The last parameter (rsv) is reserved for internal purpose and should not be modify. It may disappear in * a near future. * See Reading an attribute (Chapter 4.7.4 in Tango book) for an example. * * @param [in] a The attribute name * @param [in] fwd The forward flag * @return The call identifier */ long read_attribute_asynch (const std::string& a, bool fwd = true); /** * Reads several attributes on each device in the group asynchronously * * Reads several attribute on each device in the group asynchronously. The method sends the request to all devices * and returns immediately. Pass the returned request id to Group::read_attribute_reply() to obtain the results. * The parameter a is the name of the attribute to read. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * The last parameter (rsv) is reserved for internal purpose and should not be modify. It may disappear in * a near future. * See Reading an attribute (Chapter 4.7.4 in Tango book) for an example. * * @param [in] al The attribute name list * @param [in] fwd The forward flag * @return The call identifier */ long read_attributes_asynch (const std::vector& al, bool fwd = true); /** * Returns the results of an asynchronous attribute reading * * Returns the results of an asynchronous attribute reading. * The first parameter req_id is a request identifier previously returned by read_attribute_asynch. * For each device in the hierarchy, if the attribute value is not yet available, read_attribute_reply wait * timeout_ms milliseconds before throwing an exception. This exception will be part of the global reply. If * timeout_ms is set to 0, read_attribute_reply waits "indefinitely". * Replies are returned in a GroupAttrReplyList. See Obtaining attribute values (Chapter 4.7.4.1 in * Tango book) for details * * @param [in] req_id The attribute name list * @param [in] tmo_ms The timeout value * @return The group attribute data */ GroupAttrReplyList read_attribute_reply (long req_id, long tmo_ms = 0); /** * Returns the results of an asynchronous attributes reading * * Returns the results of an asynchronous attributes reading. * The first parameter req_id is a request identifier previously returned by read_attribute_asynch. * For each device in the hierarchy, if the attribute value is not yet available, read_attribute_reply wait * timeout_ms milliseconds before throwing an exception. This exception will be part of the global reply. If * timeout_ms is set to 0, read_attribute_reply waits "indefinitely". * Replies are returned in a GroupAttrReplyList. See Obtaining attribute values (Chapter 4.7.4.1 in * Tango book) for details * * @param [in] req_id The attribute name list * @param [in] tmo_ms The timeout value * @return The group attribute data */ GroupAttrReplyList read_attributes_reply (long req_id, long tmo_ms = 0); //- attribute writting //--------------------------------------------- /** * Writes an attribute on each device in the group * * Writes an attribute on each device in the group. This method is synchronous and does not return until * acknowledgements are obtained or timeouts occurred. * The first parameter d is a Tango generic container for attribute carrying both the attribute name and the * value. See the Tango::DeviceAttribute documentation for details. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements (Chapter 4.7.5.1 in * Tango book) for * details. See also Case 1 of Writing an attribute (Chapter 4.7.5.2 in * Tango book) for an example. * * @param [in] d The attribute name and value * @param [in] fwd The forward flag * @return The group reply */ GroupReplyList write_attribute (const DeviceAttribute& d, bool fwd = true); /** * Writes several attributes on each device in the group (using DeviceAttribute) * * Writes several attributes on each device in the group. This method is synchronous and does not return until * acknowledgements are obtained or timeouts occurred. * The first parameter d is a vector of Tango generic container for attribute carrying both the attribute name and the * value. See the Tango::DeviceAttribute documentation for details. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements (Chapter 4.7.5.1 in * Tango book) for * details. See also Case 2 of Writing an attribute (Chapter 4.7.5.3 in * Tango book) for an example. * * @param [in] d The attribute names and values * @param [in] fwd The forward flag * @return The group reply */ GroupReplyList write_attribute (const std::vector& d, bool fwd = true); /** * Writes one attributes on each device in the group with specific value per device * * Writes an attribute on each device in the group. This method is synchronous and does not return until * replies are obtained or timeouts occurred. * This implementation of write_attribute allows writing a specific value to each device in the group. In * order to use this form of write_attribute, the user must have an "a priori" and "perfect" knowledge of the * devices order in the group. * The parameter a is the name of the attribute. * The std::vector d contains a specific value for each device in the group. Since this method is a template, * d is able to contain any Tango attribute type. Its size must equal Group::get_size(fwd). Otherwise, an * exception is thrown. The order of the attribute values must follows the order of the devices in the group * (d[0] => 1st device, d[1] => 2nd device and so on). * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements (Chapter 4.7.5.1 in * Tango book) for * details. See also Case 2 of Writing an attribute (Chapter 4.7.5.3 in * Tango book) for an example. * * @tparam T The attribute data type * @param [in] n The attribute name * @param [in] d The attribute names and values * @param [in] fwd The forward flag * @return The group reply */ template GroupReplyList write_attribute (const std::string& n, const std::vector& d, bool fwd = true); /** * Writes an attribute on each device in the group asynchronously. * * Write an attribute on each device in the group asynchronously. The method sends the request to all * devices and returns immediately. Pass the returned request id to Group::write_attribute_reply() to obtain * the acknowledgements. * The first parameter d is a Tango generic container for attribute carrying both the attribute name and the * value. See the Tango::DeviceAttribute documentation for details. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * See Case 1 of Writing an attribute (Chapter 4.7.5.2 in * Tango book) for an example. * * @param [in] d The attribute name and value * @param [in] fwd The forward flag * @return The call identifier */ long write_attribute_asynch (const DeviceAttribute& d, bool fwd = true); /** * Writes several attributes on each device in the group asynchronously. * * Write several attributes on each device in the group asynchronously. The method sends the request to all * devices and returns immediately. Pass the returned request id to Group::write_attribute_reply() to obtain * the acknowledgements. * The first parameter d is a vector of Tango generic container for attribute carrying both the attribute name and the * value. See the Tango::DeviceAttribute documentation for details. * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * See Case 1 of Writing an attribute (Chapter 4.7.5.2 in * Tango book) for an example. * * @param [in] d The attribute name and value * @param [in] fwd The forward flag * @return The call identifier */ long write_attribute_asynch (const std::vector& d, bool fwd = true); /** * Writes an attribute on each device in the group asynchronously (Without DeviceAttribute data) * * Writes an attribute on each device in the group asynchronously. The method sends the request to all * devices and returns immediately. Pass the returned request id to Group::write_attribute_reply() to obtain * the acknowledgements. * This implementation of write_attribute_asynch allows writing a specific value to each device in the * group. In order to use this form of write_attribute_asynch, the user must have an "a priori" and "perfect" * knowledge of the devices order in the group. * The parameter a is the name of the attribute. * The std::vector d contains a specific value for each device in the group. Since this method is a template, * d is able to contain any Tango attribute type. Its size must equal Group::get_size(fwd). Otherwise, an * exception is thrown. The order of the attribute values must follows the order of the devices in the group * (d[0] => 1st device, d[1] => 2nd device and so on). * If fwd is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the * local set of devices. * See Case2 of Writing an attribute (Chapter 4.7.5.3 in Tango book) for an example. * * @tparam T The attribute data type * @param [in] a The attribute name * @param [in] d The attribute value(s) * @param [in] fwd The forward flag * @return The call identifier */ template long write_attribute_asynch (const std::string &a, const std::vector &d, bool fwd = true); /** * Returns the acknowledgements of an asynchronous attribute writing. * * Returns the acknowledgements of an asynchronous attribute writing. * The first parameter req_id is a request identifier previously returned by one of the write_attribute_asynch * implementation. * For each device in the hierarchy, if the acknowledgement is not yet available, write_attribute_replywait * timeout_ms milliseconds before throwing an exception. This exception will be part of the global reply. If * timeout_ms is set to 0, write_attribute_reply waits "indefinitely". * Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements (Chapter 4.7.5.1 in * Tango book) for * details. * * @param [in] req_id The request identifier * @param [in] tmo_ms The timeout value * @return The attribute writing acknowledgements */ GroupReplyList write_attribute_reply (long req_id, long tmo_ms = 0); ///@privatesection //--------------------------------------------- //- Misc. //--------------------------------------------- //- virtual void dump (int indent_level = 0); //- virtual void dump (TangoSys_OMemStream& oms, int indent_level = 0); //@} private: //- long next_asynch_request_id (); //- bool add_i (GroupElement* e, bool fwd = true); //- void remove_i (const std::string& p, bool fwd = true); //- GroupElement* find_i (const std::string& n, bool fwd = true); //- GroupElements get_hiearchy (); //- Group* get_group_i (const std::string& n); //- long get_size_i (bool fwd); //- void push_async_request (long rid, bool fwded); //- void pop_async_request (long rid); //- virtual bool is_device_i (); //- virtual bool is_group_i (); #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex elements_mutex; #endif //- elements GroupElements elements; //- asynch request repository AsynchRequestDesc arp; //- pseudo asynch. req. id generator long asynch_req_id; //- forbidden methods Group (); Group (const Group&); Group& operator=(const Group&); //- private part of the asynch impl virtual long command_inout_asynch_i (const std::string& c, bool fgt, bool fwd, long ari); virtual long command_inout_asynch_i (const std::string& c, const DeviceData& d, bool fgt, bool fwd, long ari); virtual long command_inout_asynch_i (const std::string& c, const std::vector& d, bool fgt, bool fwd, long ari); template long command_inout_asynch_i (const std::string& c, /*const*/ std::vector& d, bool fgt, bool fwd, long ari); virtual GroupCmdReplyList command_inout_reply_i (long req_id, long tmo_ms); virtual long read_attribute_asynch_i (const std::string& a, bool fwd, long ari); virtual GroupAttrReplyList read_attribute_reply_i (long req_id, long tmo_ms); virtual long read_attributes_asynch_i (const std::vector& al, bool fwd, long ari); virtual GroupAttrReplyList read_attributes_reply_i (long req_id, long tmo_ms); virtual long write_attribute_asynch_i (const DeviceAttribute& d, bool fwd, long ari); virtual long write_attribute_asynch_i (const std::vector& d, bool fwd, long ari); template long write_attribute_asynch_i (const std::string& a, /*const*/ std::vector& d, bool fwd, long ari); virtual GroupReplyList write_attribute_reply_i (long req_id, long tmo_ms); }; //============================================================================= // class GroupDeviceElement: a device element //============================================================================= class GroupDeviceElement : public GroupElement { friend class Group; friend class GroupElementFactory; public: //--------------------------------------------- //- Group management //--------------------------------------------- //- virtual DeviceProxy* get_device (const std::string& n); //- virtual DeviceProxy* get_device (long idx); //- virtual DeviceProxy* operator[] (long idx); //--------------------------------------------- //- a la DeviceProxy interface //--------------------------------------------- //- virtual bool ping (bool fwd = true); //- virtual void set_timeout_millis (int tmo_ms); //--------------------------------------------- //- Misc //--------------------------------------------- //- virtual void dump (int indent_level = 0); //- virtual void dump (TangoSys_OMemStream& oms, int indent_level = 0); //- virtual bool is_connected(); private: //- the device proxy DeviceProxy *dp; //- asynch request repository AsynchRequestRep arp; //- forbidden methods GroupDeviceElement (); GroupDeviceElement (const GroupDeviceElement&); GroupDeviceElement& operator=(const GroupDeviceElement&); //- ctor: creates an GroupDeviceElement named GroupDeviceElement (const std::string& name); //- ctor: creates a GroupDeviceElement named with timeout set to tmo_ms milliseconds GroupDeviceElement (const std::string& name, int tmo_ms); //- dtor: release resources virtual ~GroupDeviceElement(); //- build connection to the device (may throw DevFailed) DeviceProxy * connect (); //- close connection void disconnect (); //- a trick to get a valid device proxy or an exception inline DeviceProxy* dev_proxy () { return dp ? dp : connect(); } //- element identification virtual bool is_device_i (); virtual bool is_group_i (); //- size (group interface) virtual long get_size_i (bool fwd = true); //- private part of the asynch impl virtual long command_inout_asynch_i (const std::string& c, bool fgt, bool fwd, long ari); virtual long command_inout_asynch_i (const std::string& c, const DeviceData& d, bool fgt, bool fwd, long ari); virtual GroupCmdReplyList command_inout_reply_i (long req_id, long tmo_ms); virtual long read_attribute_asynch_i (const std::string& a, bool fwd, long ari); virtual GroupAttrReplyList read_attribute_reply_i (long req_id, long tmo_ms); virtual long read_attributes_asynch_i (const std::vector& al, bool fwd, long ari); virtual GroupAttrReplyList read_attributes_reply_i (long req_id, long tmo_ms); virtual long write_attribute_asynch_i (const DeviceAttribute& d, bool fwd, long ari); virtual GroupReplyList write_attribute_reply_i (long req_id, long tmo_ms); }; //============================================================================= // GroupCmdReply::operator>> template impl. //============================================================================= template bool GroupCmdReply::operator>> (T& dest) { bool result = true; if (GroupReply::group_element_enabled_m == false) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupCmdReply::operator>>"); DevFailed df(errors); throw df; } result = false; } else if (GroupReply::has_failed_m == true) { if (exception_enabled) throw GroupReply::exception_m; result = false; } else { std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); try { result = data_m >> dest; } catch (const DevFailed& df) { GroupReply::exception_m = df; if (exception_enabled) throw GroupReply::exception_m; result = false; } catch (...) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown exception caught"); errors[0].reason = CORBA::string_dup("an error occured while trying to extract data"); errors[0].origin = CORBA::string_dup("GroupCmdReply::operator>>"); DevFailed df(errors); GroupReply::exception_m = df; throw GroupReply::exception_m; } result = false; } } return result; } //============================================================================= // GroupAttrReply::operator>> template impl. //============================================================================= template bool GroupAttrReply::operator>> (T& dest) { bool result = true; if (GroupReply::group_element_enabled_m == false) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupAttrReply::operator>>"); DevFailed df(errors); throw df; } result = false; } else if (GroupReply::has_failed_m == true) { if (exception_enabled) throw GroupReply::exception_m; result = false; } else { std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); try { result = data_m >> dest; } catch (const DevFailed& df) { GroupReply::exception_m = df; if (exception_enabled) throw GroupReply::exception_m; result = false; } catch (...) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown exception caught"); errors[0].reason = CORBA::string_dup("an error occured while trying to extract data"); errors[0].origin = CORBA::string_dup("GroupAttrReply::operator>>"); DevFailed df(errors); GroupReply::exception_m = df; throw GroupReply::exception_m; } result = false; } } return result; } //============================================================================= // Group::command_inout template impl. //============================================================================= template GroupCmdReplyList Group::command_inout (const std::string& c, const std::vector& d, bool fwd) { long id = command_inout_asynch_i(c, const_cast&>(d), false, fwd, -1); return command_inout_reply_i(id, 0); } //============================================================================= // Group::command_inout_asynch template impl. //============================================================================= template long Group::command_inout_asynch (const std::string& c, const std::vector& d, bool fgt, bool fwd) { return command_inout_asynch_i(c, const_cast&>(d), fgt, fwd, -1); } //============================================================================= // Group::command_inout_asynch template impl. //============================================================================= template long Group::command_inout_asynch_i (const std::string& c, /*const*/ std::vector& d, bool fgt, bool fwd, long ari) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif long gsize = get_size_i(fwd); if (gsize != static_cast(d.size())) { TangoSys_OMemStream desc; desc << "the size of the input argument list must equal the number of device in the group" << " [expected:" << gsize << " - got:" << d.size() << "]" << ends; ApiDataExcept::throw_exception((const char*)API_MethodArgument, (const char*)desc.str().c_str(), (const char*)"Group::command_inout_asynch"); } if (ari == -1) ari = next_asynch_request_id(); for (unsigned int i = 0, j = 0; i < elements.size(); i++) { if (elements[i]->is_device_i()) { Tango::DeviceData dd; dd << d[j++]; elements[i]->command_inout_asynch_i(c, dd, fgt, false, ari); } else if (fwd) { Tango::Group * g = reinterpret_cast(elements[i]); long gsize = g->get_size_i(fwd); std::vector sub_d(d.begin() + j, d.begin() + j + gsize); reinterpret_cast(elements[i])->command_inout_asynch_i(c, sub_d, fgt, fwd, ari); j += gsize; } } if (fgt == false) { push_async_request(ari, fwd); } return ari; } //============================================================================= // Group::write_attribute_asynch template impl. //============================================================================= template GroupReplyList Group::write_attribute (const std::string& a, const std::vector& d, bool fwd) { long id = write_attribute_asynch_i(a, const_cast&>(d), fwd, -1); return write_attribute_reply(id); } //============================================================================= // Group::write_attribute_asynch template impl. //============================================================================= template long Group::write_attribute_asynch (const std::string& a, const std::vector& d, bool fwd) { return write_attribute_asynch_i(a, const_cast&>(d), fwd, -1); } //============================================================================= // Group::write_attribute_asynch_i template impl. //============================================================================= template long Group::write_attribute_asynch_i (const std::string& a, /*const*/ std::vector& d, bool fwd, long ari) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif GroupReplyList rl; long gsize = get_size_i(fwd); if (gsize != static_cast(d.size())) { TangoSys_OMemStream desc; desc << "the size of the input argument list must equal the number of device in the group" << " [expected:" << gsize << " - got:" << d.size() << "]" << ends; ApiDataExcept::throw_exception((const char*)API_MethodArgument, (const char*)desc.str().c_str(), (const char*)"Group::write_attribute_asynch"); } if (ari == -1) ari = next_asynch_request_id(); DeviceAttribute da; da.name = a; for (unsigned int i = 0, j = 0; i < elements.size(); i++) { if (elements[i]->is_device_i()) { da << d[j++]; elements[i]->write_attribute_asynch_i(da, false, ari); } else if (fwd) { Tango::Group * g = reinterpret_cast(elements[i]); long gsize = g->get_size_i(fwd); std::vector sub_d(d.begin() + j, d.begin() + j + gsize); reinterpret_cast(elements[i])->write_attribute_asynch_i(a, sub_d, fwd, ari); j += gsize; } } push_async_request(ari, fwd); return ari; } } // namespace Tango #endif /* _GROUP_H_ */ tango-9.2.5a/lib/cpp/client/lockthread.h0000644023471100065110000000625713034744772015052 00000000000000//============================================================================= // // file : LockThread.h // // description : Include for the LockThread object. This class implements // the locking thread // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #ifndef _LOCKTHREAD_H #define _LOCKTHREAD_H #include #ifndef _TG_WINDOWS_ #include #endif namespace Tango { //============================================================================= // // The LockThCmd structure // // description : This structure is used to shared data between the locking // thread and the main thread. // //============================================================================= struct LockThCmd { bool cmd_pending; // The new command flag LockCmdCode cmd_code; // The command code string dev_name; // The device name DevLong lock_validity; // The lock validity bool suicide; // The suicide flag }; struct LockedDevice { string dev_name; // The locked device name DevLong validity; // The locked device validity bool operator<(LockedDevice &arg) {return validity < arg.validity;} }; enum LockCmdType { LOCK_TIME_OUT = 0, LOCK_COMMAND }; //============================================================================= // // The LockThread class // // description : Class to store all the necessary information for the // locking thread. It's run() method is the thread code // //============================================================================= class TangoMonitor; class LockThread: public omni_thread { public: LockThread(LockThCmd &,TangoMonitor &,DeviceProxy *,string &,DevLong); void run(void *); void execute_cmd(); void one_more_lock(); void unlock_all_devs(); void update_th_period(); void compute_sleep_time(bool); LockCmdType get_command(DevLong); protected: LockThCmd &shared_cmd; TangoMonitor &p_mon; LockThCmd local_cmd; DevLong sleep; vector locked_devices; vector re_lock_cmd_args; DevLong period; DevLong period_ms; DeviceProxy *admin_proxy; struct timeval next_work; }; } // End of Tango namespace #endif /* _LOCKTHREAD_ */ tango-9.2.5a/lib/cpp/client/Database.h0000644023471100065110000017560013034744771014434 00000000000000 //+================================================================================================================== // // dbapi.h - include file for TANGO database api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-================================================================================================================ #ifndef _DATABASE_H #define _DATABASE_H /**************************************************************************************** * * * The Database class * * ------------------ * * * ***************************************************************************************/ /** * A high level object which contains the link to the database. * * This class has methods for all database commands e.g. get_device_property(), * device_list(), info(), etc. * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup DBase */ class Database : public Tango::Connection { private : virtual string get_corba_name(bool); virtual string build_corba_name() {return string("nada");} virtual int get_lock_ctr() {return 0;} virtual void set_lock_ctr(int) {} class DatabaseExt { public: DatabaseExt() {}; string orig_tango_host; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DatabaseExt *ext; #endif bool db_multi_svc; vector multi_db_port; vector multi_db_host; FileDatabase *filedb; string file_name; int serv_version; AccessProxy *access_proxy; bool access_checked; DevErrorList access_except_errors; map dev_class_cache; string db_device_name; bool access_service_defined; Tango::Util *db_tg; omni_mutex map_mutex; DbDatum make_string_array(string, CORBA::Any_var &); vector make_history_array(bool, CORBA::Any_var &); void check_access(); inline string dev_name(); void set_server_release(); void check_access_and_get(); public : /**@name Constructors */ //@{ /** * Create a TANGO Database object. * * The constructor uses the environment variable “TANGO_HOST†to * determine which instance of the TANGO database to connect to. Example : * @code * using namespace Tango; * Database *db = new Database(); * @endcode * * @param [in] orb The CORBA ORB pointer. Default value is fine for 99 % of cases * */ Database(CORBA::ORB *orb=NULL); // @} /**@name General methods */ //@{ /** * Get database info. * * Query the database for some general info about the tables in the database. * Result is returned as a string. Example : * @code * cout << db->get_info() << endl; * @endcode * will return information like this: * @code * Running since 2000-11-06 14:10:46 * Devices defined = 115 * Devices exported = 41 * Device servers defined = 47 * Device servers exported = 17 * Class properties defined = 5 * Device properties defined = 130 * Class attribute properties defined = 20 * Device attribute properties defined = 92 * @endcode * * @return The string giving database info * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ string get_info(); //@} /**@name Device oriented methods */ //@{ /** * Add a device into the database. * * Add a device to the database. The device name, server and class are specified in the DbDevInfo structure. * Example : * @code * DbDevInfo my_device_info; * * my_device_info.name = “my/own/deviceâ€; * my_device_info._class = “MyDeviceâ€; * my_device_info.server = “MyServer/testâ€; * * db->add_device(my_device_info); * @endcode * * @param [in] dev_info A reference to a DbDevInfo instance with all device info. * * @exception ConnectionFailed, CommunnicationFailed, DevFailed */ void add_device(DbDevInfo &dev_info); /** * Delete a device from the database. * * Delete the device of the specified name from the database. Example * @code * db->delete_device(“my/own/deviceâ€); * @endcode * * @param [in] dev_name The device name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError, DB_DeviceNotDefined) */ void delete_device(string dev_name); /** * Import a device from the database. * * Query the database for the export info of the specified device. * The command returns the information in a DbDevImportInfo structure. Example : * @code * DbDevImportInfo my_device_import; * * my_device_import = db->import_device(“my/own/deviceâ€); * * cout << “ device †<< my_device_import.name; * cout << “exported †<< my_device_import.exported; * cout << “ior †<< my_device_import.ior; * cout << “version †<< my_device_import.version; * cout << endl; * @endcode * * @param [in] dev_name The device name * @return One instance of a DbDevImportInfo class * * @exception ConnectionFailed, CommunicationFailed, DevFailed */ DbDevImportInfo import_device(string &dev_name); /** * Export a device into the database. * * Update the export info for this device in the database. Device name, server, class, pid and version are * specified in the DbDevExportInfo structure. Example : * @code * DbDevExportInfo my_device_export; * * my_device_export.name = “my/own/deviceâ€; * my_device_export.ior = “the real iorâ€; * my_device_export.host = “dumelaâ€; * my_device_export.version = “1.0â€; * my_device_export.pid = get_pid(); * * db->export_device(my_device_export); * @endcode * * @param [in] info The device export information * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError, DB_DeviceNotDefined) */ void export_device(DbDevExportInfo &info); /** * Unexport a device in the database. * * Mark the specified device as un-exported in the database. Example : * @code * db->unexport_device(“my/own/deviceâ€); * @endcode * * @param [in] dev_name The device name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void unexport_device(string dev_name); /** * Get device information * * Return miscellaneous device information from the database (not from the device itself) * * @param [in] dev_name The device name * @return The device information class instance * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDevFullInfo get_device_info(string &dev_name); /** * Get class name for a device * * Return the class of the specified device. * @code * string devname("sr/rf-cavity/1"); * string classname = db->get_class_for_device(devname); * @endcode * * @param [in] dev_name The device name * @return The device class name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ string get_class_for_device(string &dev_name); /** * Get device inheritance scheme * * Return the class inheritance scheme of the specified device * @code * string devname("sr/rf-cavity/1"); * * DbDatum db_datum = db->get_class_inheritance_for_device(devname); * * vector class_list; * db_datum >> class_list; * @endcode * * @param [in] dev_name The device name * @return The device inheritance * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_class_inheritance_for_device(string &dev_name); //@} /**@name Server oriented methods */ //@{ /** * Create a device server process in database. * * Add a group of devices to the database. * The device names, server names and classes are specified in a vector of DbDevInfo structures. * * @param [in] ds_name The full device server process name * @param [in] devs Vector of DbDevInfo instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void add_server(string &ds_name, DbDevInfos &devs); /** * Delete a device server process from the database. * * Delete the device server and its associated devices from the database. * * @param [in] ds_name The full device server process name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void delete_server(string &ds_name); /** * Delete a device server process from the database. * * Export a group of devices to the database. * The device names, IOR, class, server name, pid etc. are specified in the vector of DbDevExportInfo structures. * * @param [in] devs Devices information in a vector of DbDevExportInfo * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void export_server(DbDevExportInfos &devs); /** * Unexport all devices from a device server in the database. * * Mark all devices exported for this device server process as unexported. * * @param [in] ds_name The full device server process name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void unexport_server(string &ds_name); /** * Rename a device server in the database. * * Rename a device server process in the database. * * @param [in] old_ds_name The old device server process name * @param [in] new_ds_name The new device server process name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device (DB_SQLError) */ void rename_server(const string &old_ds_name,const string &new_ds_name); //@} /**@name Services oriented methods */ //@{ /** * Get services list from database * * Query database for specified services. The instname parameter can be a wildcard character ("*"). * @code * string servicename("HdbManager"); * string instname("ctrm"); * * DbDatum db_datum = db->get_services(servicename,instname); * * vector service_list; * db_datum >> service_list; * @endcode * * @param [in] service_name The service name * @param [in] inst_name The instance name * @return A service list matching the input parameters * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_services(string &service_name,string &inst_name); /** * Get services list from database * * Query database for specified services. The vector of strings returned in the DbDatum * object contains pair of strings followed by * @code * string servicename("HdbManager"); * * DbDatum db_datum = db->get_services(servicename); * * vector service_device_list; * db_datum >> service_device_list; * @endcode * * @param [in] service_name The service name * @return A service/device list matching the input parameter * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_service_list(string &service_name); /** * Register a service in the database * * Register the specified service wihtin the database. * @code * string servicename("HdbManager"); * string instname("ctrm"); * string devname("sys/hdb/1"); * * db->register_service(servicename,instname,devname); * @endcode * * @param [in] service_name The service name * @param [in] inst_name The instance name * @param [in] dev_name The device name implementing the service * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void register_service(string &service_name,string &inst_name,string &dev_name); /** * Unregister a service from the database * * Unregister the specified service from the database. * @code * string servicename("HdbManager"); * string instname("ctrm"); * * db->unregister_service(servicename,instname); * @endcode * * @param [in] service_name The service name * @param [in] inst_name The instance name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void unregister_service(string &service_name,string &inst_name); //@} /**@name Object property oriented methods */ //@{ /** * Get object property value * * Query the database for a list of object (i.e. non-device) properties for the specified object. The property * names are specified by the vector of DbDatum structures. The method returns the properties in the same * DbDatum structures. To retrieve the properties use the extract operator >>. Here is an example of how to * use the DbData type to specify and extract properties : * @code * DbData db_data; * db_data.push_back(DbDatum(“velocityâ€)); * db_data.push_back(DbDatum(“accelerationâ€)); * * db->get_property(“mymotorâ€, db_data); * * float velocity, acceleration; * db_data[0] >> velocity; * db_data[1] >> acceleration; * @endcode * * @param [in] obj_name The object (free property) name * @param [in,out] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_property(string obj_name, DbData &db) {get_property(obj_name,db,NULL);} /** * Put object property value in database * * Insert or update a list of properties for the specified object. The property names and their values are * specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the * DbDatum structures. Here is an example of how to insert properties into the database using this method : * @code * DbDatum velocity(“velocityâ€), acceleration(“accelerationâ€); * DbData db_data; * * velocity << 100000.0; * acceleration << 500000.0; * db_data.push_back(velocity); * db_data.push_back(acceleration); * * db->put_property(“mymotorâ€, db_data); * @endcode * * @param [in] obj_name The object (free property) name * @param [in] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_property(string obj_name, DbData &db); /** * Delete object property from database * * Delete a list of properties for the specified object. The property names are specified by the vector of * DbDatum structures. Here is an example of how to delete properties from the database using this method : * @code * DbData db_data; * db_data.push_back(DbDatum(“velocityâ€)); * db_data.push_back(DbDatum(“accelerationâ€)); * * db->delete_property(“mymotorâ€, db_data); * @endcode * * @param [in] obj_name The object (free property) name * @param [in] db The property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_property(string obj_name, DbData &db); /** * Get object property history from database * * Get the list of the last 10 modifications of the specifed object property. Note that propname can contain a * wildcard character (eg: "prop*"). * @code * vector hist; * DbDatum result; * string objname("jlptest"); * string propname("test_prop"); * * hist = db->get_property_history(objname,propname); * * // Print the modification history of the specified property * for(int i=0;i> result; * for (int j=0; j get_property_history(string &obj_name,string &prop_name); //@} /**@name Device property oriented methods */ //@{ /** * Get device property value * * Query the database for a list of device properties for the specified object. The property names are specified * by the vector of DbDatum structures. The method returns the properties in the same DbDatum structures. * To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData type to * specify and extract properties : * @code * DbData db_data; * db_data.push_back(DbDatum(“velocityâ€)); * db_data.push_back(DbDatum(“accelerationâ€)); * * db->get_device_property(“id11/motor/1â€, db_data); * * float velocity, acceleration; * db_data[0] >> velocity; * db_data[1] >> acceleration; * @endcode * * @param [in] dev_name The device name * @param [in,out] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_property(string dev_name, DbData &db) {get_device_property(dev_name,db,NULL);} /** * Put device property value in database * * Insert or update a list of properties for the specified device. The property names and their values are * specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the * DbDatum structures. Here is an example of how to insert properties into the database using this method : * @code * DbDatum velocity(“velocityâ€), acceleration(“accelerationâ€); * DbData db_data; * * velocity << 100000.0; * acceleration << 500000.0; * db_data.push_back(velocity); * db_data.push_back(acceleration); * * db->put_device_property(“id11/motor/1â€, db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_device_property(string dev_name, DbData &db); /** * Delete device property from database * * Delete a list of properties for the specified device. The property names are specified by the vector of * DbDatum structures. Here is an example of how to delete properties from the database using this method : * @code * DbData db_data; * db_data.push_back(DbDatum(“velocityâ€)); * db_data.push_back(DbDatum(“accelerationâ€)); * * db->delete_device_property(“id11/motor/1â€, db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_device_property(string dev_name, DbData &db); /** * Get device property history from database * * Get the list of the last 10 modifications of the specifed device property. Note that prop_name can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] dev_name The device name * @param [in] prop_name The property name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_device_property_history(string &dev_name,string &prop_name); //@} /**@name Device attribute property oriented methods */ //@{ /** * Get device attribute property value * * Query the database for a list of device attribute properties for the specified object. The attribute names * are specified by the vector of DbDatum structures. The method returns all the properties for the specified * attributes. The attribute names are returned with the number of properties specified as their value. The * first DbDatum element of the returned DbData vector contains the first attribute name and the first attribute * property number. The following DbDatum element contains the first attribute property name and property * values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData * type to specify and extract attribute properties : * @code * DbData db_data; * * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("acceleration")); * * db->get_device_attribute_property("id11/motor/1", db_data); * * float vel_max, vel_min, acc_max, acc_min; * for (int i=0;i < db_data.size();i++) * { * long nb_prop; * string &att_name = db_data[i].name; * db_data[i] >> nb_prop; * i++; * for (int k=0;k < nb_prop;k++) * { * string &prop_name = db_data[i].name; * if (att_name == "velocity") * { * if (prop_name == "min") * db_data[i] >> vel_min; * else if (att_name == "max") * db_data[i] >> vel_max; * } * else * { * if (prop_name == "min") * db_data[i] >> acc_min; * else * db_data[i] >> acc_max; * } * i++; * } * } * @endcode * * @param [in] dev_name The device name * @param [in,out] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_attribute_property(string dev_name, DbData &db) {get_device_attribute_property(dev_name,db,NULL);} /** * Put device attribute property value in database * * Insert or update a list of attribute properties for the specified device. The attribute property names and their * values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties * into the DbDatum structures. Here is an example of how to insert/update properties min, max for attribute * velocity and properties min, max for attribute acceleration of device id11/motor/1 into the database using * this method : * @code * DbDatum vel("velocity"); // We want to put properties for attribute "velocity" * DbDatum vel_min("min"), vel_max("max"); * DbDatum acc("acceleration") // We want to put properties for attribute "acceleration" * DbDatum acc_min("min"), acc_max("max"); * DbData db_data; * * vel << 2; // Two properties for attribute "velocity" * vel_min << 0.0; // Value for property min * vel_max << 1000000.0; // Value for property max * * db_data.push_back(vel); * db_data.push_back(vel_min); * db_data.push_back(vel_max); * * acc << 2; // Two properties for attribute "acceleration" * acc_min << 0.0; // Value for property min * acc_max << 8000000; // Value for property max * * db_data.push_back(acc); * db_data.push_back(acc_min); * db_data.push_back(acc_max); * * db->put_device_attribute_property(“id11/motor/1â€, db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_device_attribute_property(string dev_name, DbData &db); /** * Delete device attribute property from database * * Delete a list of attribute properties for the specified device. The attribute names are specified by the vector * of DbDatum structures. Here is an example of how to delete the unit property of the velocity attribute of * the id11/motor/1 device using this method : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("unit")); * * db->delete_device_attribute_property("id11/motor/1", db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_device_attribute_property(string dev_name, DbData &db); /** * Get device attribute property history from database * * Get the list of the last 10 modifications of the specifed device attribute property. Note that prop_name * and att_name can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] dev_name The device name * @param [in] prop_name The property name * @param [in] att_name The property name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_device_attribute_property_history(string &dev_name,string &prop_name,string &att_name); /** * Get list of attribute with data in database for a specific device * * Get the list of attribute(s) with some data defined in database for a specified device. * Note that this is not the list of all device attributes because not all attribute(s) have * some data in database * * @param [in] dev_name The device name * @param [in] att_list The attribute name list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_attribute_list(string &dev_name,vector &att_list); /** * Get list of pipe with data in database for a specific device * * Get the list of pipe(s) with some data defined in database for a specified device. * Note that this is not the list of all device pipes because not all pipe(s) have * some data in database * * @param [in] dev_name The device name * @param [in] pipe_list The pipe name list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_pipe_list(const string &dev_name,vector &pipe_list); //@} /**@name Device pipe property oriented methods */ //@{ /** * Get device pipe property value * * Query the database for a list of device pipe properties for the specified object. The pipe names * are specified by the vector of DbDatum structures. The method returns all the properties for the specified * pipes. The pipe names are returned with the number of properties specified as their value. The * first DbDatum element of the returned DbData vector contains the first pipe name and the first pipe * property number. The following DbDatum element contains the first pipe property name and property * values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData * type to specify and extract pipe properties : * @code * DbData db_data; * * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("acceleration")); * * db->get_device_pipe_property("id11/motor/1", db_data); * * float vel_max, vel_min, acc_max, acc_min; * for (int i=0;i < db_data.size();i++) * { * long nb_prop; * string &pipe_name = db_data[i].name; * db_data[i] >> nb_prop; * i++; * for (int k=0;k < nb_prop;k++) * { * string &prop_name = db_data[i].name; * if (pipe_name == "velocity") * { * if (prop_name == "min") * db_data[i] >> vel_min; * else if (att_name == "max") * db_data[i] >> vel_max; * } * else * { * if (prop_name == "min") * db_data[i] >> acc_min; * else * db_data[i] >> acc_max; * } * i++; * } * } * @endcode * * @param [in] dev_name The device name * @param [in,out] db The pipe/property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_pipe_property(string dev_name, DbData &db) {get_device_pipe_property(dev_name,db,NULL);} /** * Put device pipe property value in database * * Insert or update a list of pipe properties for the specified device. The pipe property names and their * values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties * into the DbDatum structures. Here is an example of how to insert/update properties min, max for pipe * velocity and properties min, max for pipe acceleration of device id11/motor/1 into the database using * this method : * @code * DbDatum vel("velocity"); // We want to put properties for pipe "velocity" * DbDatum vel_min("min"), vel_max("max"); * DbDatum acc("acceleration") // We want to put properties for pipe "acceleration" * DbDatum acc_min("min"), acc_max("max"); * DbData db_data; * * vel << 2; // Two properties for pipe "velocity" * vel_min << 0.0; // Value for property min * vel_max << 1000000.0; // Value for property max * * db_data.push_back(vel); * db_data.push_back(vel_min); * db_data.push_back(vel_max); * * acc << 2; // Two properties for pipe "acceleration" * acc_min << 0.0; // Value for property min * acc_max << 8000000; // Value for property max * * db_data.push_back(acc); * db_data.push_back(acc_min); * db_data.push_back(acc_max); * * db->put_device_pipe_property(“id11/motor/1â€, db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The pipe/property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_device_pipe_property(string dev_name, DbData &db); /** * Delete device pipe property from database * * Delete a list of pipe properties for the specified device. The pipe names are specified by the vector * of DbDatum structures. Here is an example of how to delete the unit property of the velocity pipe of * the id11/motor/1 device using this method : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("unit")); * * db->delete_device_attribute_property("id11/motor/1", db_data); * @endcode * * @param [in] dev_name The device name * @param [in] db The pipe/property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_device_pipe_property(string dev_name, DbData &db); /** * Get device pipe property history from database * * Get the list of the last 10 modifications of the specifed device pipe property. Note that prop_name * and pipe_name can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] dev_name The device name * @param [in] pipe_name The property name * @param [in] prop_name The pipe name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_device_pipe_property_history(string &dev_name,string &pipe_name,string &prop_name); //@} /**@name Class property oriented methods */ //@{ /** * Get class property value * * Query the database for a list of class properties. The property names are specified by the vector of DbDatum * structures. The method returns the properties in the same DbDatum structures. To retrieve the properties * use the extract operator >>. Here is an example of how to use the DbData type to specify and extract * properties : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("acceleration")); * * db->get_class_property("StepperMotor", db_data); * * float velocity, acceleration; * db_data[0] >> velocity; * db_data[1] >> acceleration; * @endcode * * @param [in] class_name The class name * @param [in,out] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_class_property(string class_name,DbData &db) {get_class_property(class_name,db,NULL);} /** * Put class property value in database * * Insert or update a list of properties for the specified class. The property names and their values are specified * by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum * structures. Here is an example of how to insert properties into the database using this method : * @code * DbDatum velocity("velocity"), acceleration("acceleration"); * DbData db_data; * * velocity << 100000.0; * acceleration << 500000.0; * db_data.push_back(velocity); * db_data.push_back(acceleration); * * db->put_class_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_class_property(string class_name, DbData &db); /** * Delete class property from database * * Delete a list of properties for the specified class. The property names are specified by the vector of Db- * Datum structures. Here is an example of how to delete properties from the database using this method * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("acceleration")); * * db->delete_class_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_class_property(string class_name, DbData &db); /** * Get class property history from database * * Get the list of the last 10 modifications of the specifed class property. Note that prop_name * can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] class_name The class name * @param [in] prop_name The property name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_class_property_history(string &class_name,string &prop_name); //@} /**@name Class attribute property oriented methods */ //@{ /** * Get class attribute property value * * Query the database for a list of class attribute properties for the specified object. The attribute names are * specified by the vector of DbDatum structures. The method returns all the properties for the specified * attributes. The attribute names are returned with the number of properties specified as their value. The * first DbDatum element of the returned DbData vector contains the first attribute name and the first attribute * property number. The following DbDatum element contains the first attribute property name and property * values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData * type to specify and extract attribute properties : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("acceleration")); * * db->get_class_attribute_property("StepperMotor", db_data); * * float vel_max, vel_min, acc_max, acc_min; * for (int i=0; i< db_data.size(); i++) * { * long nb_prop; * string &att_name = db_data[i].name; * db_data[i] >> nb_prop; * i++; * for (int k=0;k < nb_prop;k++) * { * string &prop_name = db_data[i].name; * if (att_name == "velocity") * { * if (prop_name == "min") * db_data[i] >> vel_min; * else if (att_name == "max") * db_data[i] >> vel_max; * } * else * { * if (prop_name == "min") * db_data[i] >> acc_min; * else * db_data[i] >> acc_max; * } * i++; * } * } * @endcode * * @param [in] class_name The class name * @param [in,out] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_class_attribute_property(string class_name,DbData &db) {get_class_attribute_property(class_name,db,NULL);} /** * Put class attribute property value in database * * Insert or update a list of attribute properties for the specified class. The attribute property names and their * values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties * into the DbDatum structures. Here is an example of how to insert/update min, max properties for attribute * velocity and min, max properties for attribute acceleration properties belonging to class StepperMotor into * the database using this method : * @code * DbDatum velocity("velocity"), vel_min("min"), vel_max("max"); * DbDatum acceleration("acceleration"), acc_min("min"), acc_max("max"); * DbData db_data; * * velocity << 2; * vel_min << 0.0; * vel_max << 1000000.0; * * db_data.push_back(velocity); * db_data.push_back(vel_min); * db_data.push_back(vel_max); * * acceleration << 2; * acc_min << 0.0; * acc_max << 8000000; * * db_data.push_back(acceleration); * db_data.push_back(acc_min); * db_data.push_back(acc_max); * * db->put_class_attribute_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_class_attribute_property(string class_name, DbData &db); /** * Delete class attribute property from database * * Delete a list of attribute properties for the specified class. The attribute names are specified by the vector * of DbDatum structures. All properties belonging to the listed attributes are deleted. Here is an example of * how to delete the unit property of the velocity attribute of the StepperMotor class from the database using * this method : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("unit")); * * db->delete_class_attribute_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_class_attribute_property(string class_name, DbData &db); /** * Get class attribute property history from database * * Get the list of the last 10 modifications of the specifed class attribute property. Note that prop_name * and att_name can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] class_name The class name * @param [in] att_name The attribute name * @param [in] prop_name The property name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_class_attribute_property_history(string &class_name,string &att_name,string &prop_name); //@} /**@name Class pipe property oriented methods */ //@{ /** * Get class pipe property value * * Query the database for a list of class pipe properties for the specified object. The pipe names are * specified by the vector of DbDatum structures. The method returns all the properties for the specified * pipes. The pipe names are returned with the number of properties specified as their value. The * first DbDatum element of the returned DbData vector contains the first pipe name and the first pipe * property number. The following DbDatum element contains the first pipe property name and property * values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData * type to specify and extract pipe properties : * @code * DbData db_data; * db_data.push_back(DbDatum("pipe_image")); * db_data.push_back(DbDatum("pipe_misc")); * * db->get_class_pipe_property("MyDetector", db_data); * * int max_x, min_x, size; * for (int i=0; i< db_data.size(); i++) * { * long nb_prop; * string &pipe_name = db_data[i].name; * db_data[i] >> nb_prop; * i++; * for (int k=0;k < nb_prop;k++) * { * string &prop_name = db_data[i].name; * if (pipe_name == "pipe_image") * { * if (prop_name == "min_x") * db_data[i] >> min_x; * else if (att_name == "max_x") * db_data[i] >> max_x; * } * else * { * if (prop_name == "size") * db_data[i] >> size; * } * i++; * } * } * @endcode * * @param [in] class_name The class name * @param [in,out] db The pipe/property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_class_pipe_property(string class_name,DbData &db) {get_class_pipe_property(class_name,db,NULL);} /** * Put class pipe property value in database * * Insert or update a list of pipe properties for the specified class. The pipe property names and their * values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties * into the DbDatum structures. Here is an example of how to insert/update min, max properties for pipe * velocity and min, max properties for pipe acceleration properties belonging to class StepperMotor into * the database using this method : * @code * DbDatum velocity("velocity"), vel_min("min"), vel_max("max"); * DbDatum acceleration("acceleration"), acc_min("min"), acc_max("max"); * DbData db_data; * * velocity << 2; * vel_min << 0.0; * vel_max << 1000000.0; * * db_data.push_back(velocity); * db_data.push_back(vel_min); * db_data.push_back(vel_max); * * acceleration << 2; * acc_min << 0.0; * acc_max << 8000000; * * db_data.push_back(acceleration); * db_data.push_back(acc_min); * db_data.push_back(acc_max); * * db->put_class_pipe_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The pipe/property names and values * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_class_pipe_property(string class_name, DbData &db); /** * Delete class pipe property from database * * Delete a list of pipe properties for the specified class. The pipe names are specified by the vector * of DbDatum structures. All properties belonging to the listed pipes are deleted. Here is an example of * how to delete the unit property of the velocity pipe of the StepperMotor class from the database using * this method : * @code * DbData db_data; * db_data.push_back(DbDatum("velocity")); * db_data.push_back(DbDatum("unit")); * * db->delete_class_pipe_property("StepperMotor", db_data); * @endcode * * @param [in] class_name The class name * @param [in] db The pipe/property names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_class_pipe_property(string class_name, DbData &db); /** * Get class pipe property history from database * * Get the list of the last 10 modifications of the specifed class pipe property. Note that prop_name * and pipe_name can contain * a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the * documentation of the get_property_history() function. * * @param [in] class_name The class name * @param [in] pipe_name The pipe name * @param [in] prop_name The property name * @return A vector of DbHistory instances * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ vector get_class_pipe_property_history(string &class_name,string &pipe_name,string &prop_name); //@} /**@name Alias oriented methods */ //@{ /** * Get device name from its alias * * Get the device name from its alias. The device alias is specified by alias and the device name * is returned in dev_name. If there is no device defined with the given alias, a DevFailed exception is thrown. * * @param [in] alias The device alias * @param [out] dev_name The device name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_from_alias(string alias,string &dev_name); /** * Get device alias form its name * * Get the device alias from its name. The device name is specified by dev_name and the device alias is * returned in alias. If there is no alias defined for the device, a DevFailed exception is thrown. * * @param [in] dev_name The device name * @param [out] alias The device alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_alias_from_device(string dev_name,string &alias); /** * Get device alias from its name * * @deprecated use get_alias_from_device() * * Get the device alias name from its name. The device name is specified by dev_name and the device alias * name is returned in dev_alias. If there is no alias defined for the device, a DevFailed exception is thrown. * * @param [in] dev_name The device name * @param [out] dev_alias The device alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_alias(string dev_name,string &dev_alias); /** * Get device name from its alias * * @deprecated use get_device_from_alias() * * Get the device name from an alias. The device alias is specified by dev_alias and the device name is * returned in dev_name. If there is no device with the given alias, a DevFailed exception is thrown. * * @param [in] dev_alias The device alias * @param [out] dev_name The device name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_device_alias(string dev_alias,string &dev_name); /** * Define device alias * * Create a device alias. Alias name has to be uniq within a Tango control system and you will receive an * exception if the alias is already defined. * * @param [in] dev_name The device name * @param [in] dev_alias The device alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_device_alias(string &dev_name,string &dev_alias); /** * Delete device alias * * Delete a device alias. * * @param [in] dev_alias The device alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_device_alias(string &dev_alias); /** * Get attribute name from its alias * * Get the attribute name from its alias. The attribute alias is specified by alias and the attribute name * is returned in att_name. If there is no attribute defined with the given alias, a DevFailed exception is thrown. * * @param [in] alias The attribute alias * @param [out] att_name The attribute name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_attribute_from_alias(string alias,string &att_name); /** * Get attribute alias form its name * * Get the attribute alias from its name. The attribute name is specified by att_name and the attribute alias is * returned in alias. If there is no alias defined for the attribute, a DevFailed exception is thrown. * * @param [in] att_name The attribute name * @param [out] alias The attribute alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_alias_from_attribute(string att_name,string &alias); /** * Get attribute name from its alias * * Get the full attribute name from an alias. The attribute alias is specified by att_alias and the full attribute * name is returned in att_name. If there is no attribute with the given alias, a DevFailed exception is thrown. * * @param [in] att_alias The attribute alias * @param [out] att_name The attribute name * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void get_attribute_alias(string att_alias, string &att_name); /** * Define attribute alias * * Set an alias for an attribute name. The attribute alias is specified by att_alias and the attribute name is * specifed by att_name. If the given alias already exists, a DevFailed exception is thrown. * * @param [in] att_name The attribute name * @param [in] att_alias The attribute alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void put_attribute_alias(string &att_name,string &att_alias); /** * Delete attribute alias * * Remove the alias associated to an attribute name. * * @param [in] att_alias The attribute alias * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ void delete_attribute_alias(string &att_alias); //@} /**@name Database browsing oriented methods */ //@{ /** * Get host list * * Returns the list of all host names registered in the database. * @code * DbDatum db_datum = db->get_host_list(); * * vector host_list; * db_datum >> host_list; * @endcode * * @return A host name list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_host_list(); /** * Get host list with name matching a wildcard * * Returns the list of all host names registered in the database which match the specified wildcard (eg: "lc0*") * @code * string wildcard("l-c0*"); * * DbDatum db_datum = db->get_host_list(wildcard); * * vector host_list; * db_datum >> host_list; * @endcode * * @param [in] wildcard The wildcard * @return A host name list matching the input * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_host_list(string &wildcard); /** * Get list of Tango classes embedded in a device server proess * * Query the database for a list of classes instancied by the specified server. * The DServer class exists in all TANGO servers and for this reason this class * is removed from the returned list. * @code * string server("Serial/1"); * * DbDatum db_datum = db->get_server_class_list(server); * * vector class_list; * db_datum >> class_list; * @endcode * * @param [in] ds_name The full device server process name * @return The list of Tango classes embedded in the specified server process * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_server_class_list(string &ds_name); /** * Get list of all Tango device server process * * Return the list of all server names registered in the database. * @code * DbDatum db_datum = db->get_server_name_list(); * * vector server_list; * db_datum >> server_list; * @endcode * * @return The list of all server names * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_server_name_list(); /** * Get list of instances * * Return the list of all instance names existing in the database for the specifed server. * @code * string servername("Serial"); * * DbDatum db_datum = db->get_instance_name_list(servername); * * vector instance_list; * db_datum >> instance_list; * @endcode * * @param [in] ds_name The device server process executable name * @return The list of all instances for the specified device server process * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_instance_name_list(string &ds_name); /** * Get list of device server processes * * Return the list of all servers registered in the database. * @code * DbDatum db_datum = db->get_server_list(); * * vector server_list; * db_datum >> server_list; * @endcode * * @return The list of all device server processes defined in database * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_server_list(); /** * Get list of device server processes with a wildcard * * Return the list of all servers registered in the database which match the specified wildcard (eg: "Serial/l*"). * @code * string wildcard("Serial/l*"); * * DbDatum db_datum = db->get_server_list(wildcard); * * vector server_list; * db_datum >> server_list; * @endcode * * @param [in] wildcard The wildcard * @return The list of device server processes defined in database matching the specified wildcard * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_server_list(string &wildcard); /** * Get list of device server processes running on a host * * Query the database for a list of servers registred on the specified host. * @code * string host("kidiboo"); * * DbDatum db_datum = db->get_host_server_list(wildcard); * * vector server_list; * db_datum >> server_list; * @endcode * * @param [in] host_name The host name * @return The list of device server processes * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_host_server_list(string &host_name); /** * Get list of devices served by a device server process * * Query the database for a list of devices served by the specified server (1st parameter) * and of the specified class (2nd parameter). * * @param [in] ds_name The device server name (executable/instance) * @param [in] class_name The class name * @return The list of devices * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_name(string &ds_name, string &class_name); /** * Get list of exported devices * * Query the database for a list of exported devices whose names satisfy the supplied filter * (* is wildcard for any character(s)). * * @param [in] filter The filter * @return The list of exported devices * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_exported(string &filter); /** * Get list of device domain names * * Query the database for a list of device domain names which match the wildcard provided. * Wildcard character * matches any number of characters. Domain names are case insensitive. * * @param [in] wildcard The wildcard * @return The device domain names list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_domain(string &wildcard); /** * Get list of device family name * * Query the database for a list of device family names which match the wildcard provided. * Wildcard character * matches any number of characters. Family names are case insensitive. * * @param [in] wildcard The wildcard * @return The device family names list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_family(string &wildcard); /** * Get list of device member name * * Query the database for a list of device member names which match the wildcard provided. * Wildcard character * matches any number of characters. Member names are case insensitive. * * @param [in] wildcard The wildcard * @return The device member names list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_member(string &wildcard); /** * Get list of devices/classes for a specified device server * * Query the database for a list of devices and classes served by the specified server. * Return a list with the following structure: {device name,class name,device name,class name,...} * @code * string server("Serial/1"); * * DbDatum db_datum = db->get_device_class_list(server); * * vector dev_list; * db_datum >> dev_list; * @endcode * * @param [in] ds_name The full device server process name * @return The device / class list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_class_list(string &ds_name); /** * Get list of exported device for a class * * Query database for list of exported devices for the specified class. * @code * string classname("MyClass"); * * DbDatum db_datum = db->get_device_exported_for_class(classname); * * vector dev_list; * db_datum >> dev_list; * @endcode * * @param [in] class_name The Tango device class name * @return The exported device list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_exported_for_class(string &class_name); /** * Get object (free property) list * * Query the database for a list of object (free properties) for which properties are defined and which match * the specified wildcard. * @code * string wildcard("Optic*"); * * DbDatum db_datum = db->get_object_list(wildcard); * * vector obj_list; * db_datum >> obj_list; * @endcode * * @param [in] wildcard The wildcard * @return The object (free property) list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_object_list(string &wildcard); /** * Get object property list * * Query the database for a list of properties defined for the specified object and which match the specified wildcard. * @code * string objname("OpticID9"); * string wildcard("Delta*"); * * DbDatum db_datum = db->get_object_property_list(objname,wildcard); * * vector prop_list; * db_datum >> prop_list; * @endcode * * @param [in] obj_name The object (free property) name * @param [in] wildcard The wildcard * @return The object (free property) property list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_object_property_list(string &obj_name,string &wildcard); /** * Get Tango class list * * Query the database for a list of classes which match the specified wildcard. * @code * string wildcard("Motor*"); * * DbDatum db_datum = db->get_class_list(wildcard); * * vector class_list; * db_datum >> class_list; * @endcode * * @param [in] wildcard The wildcard * @return The class list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_class_list(string &wildcard); /** * Get class property list * * Query the database for a list of properties defined for the specified class. * @code * string classname("MyClass"); * * DbDatum db_datum = db->get_object_property_list(classname); * * vector prop_list; * db_datum >> prop_list; * @endcode * * @param [in] class_name The class name * @return The class property list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_class_property_list(string &class_name); /** * Get class attribute list * * Query the database for a list of attributes defined for the specified class which match the specified wildcard. * @code * string classname("MyClass"); * string wildcard("*"); * * DbDatum db_datum = db->get_class_attribute_list(classname,wildcard); * * vector att_list; * db_datum >> att_list; * @endcode * * @param [in] class_name The class name * @param [in] wildcard The wildcard * @return The class property list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_class_attribute_list(string &class_name,string &wildcard); /** * Get class pipe list * * Query the database for a list of pipes defined for the specified class which match the specified wildcard. * @code * string classname("MyClass"); * string wildcard("*"); * * DbDatum db_datum = db->get_class_pipe_list(classname,wildcard); * * vector pipe_list; * db_datum >> pipe_list; * @endcode * * @param [in] class_name The class name * @param [in] wildcard The wildcard * @return The class pipe list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_class_pipe_list(const string &class_name,const string &wildcard); /** * Get device alias list * * Get device alias list. The parameter is a string to filter the alias list returned. Wildcard (*) is supported. * For instance, if the string passed as the method parameter is initialised with only the * character, all * the defined device alias will be returned. The DbDatum returned by this method is initialised with an array * of strings and must be extracted into a vector. If there is no alias with the given filter, the returned * array will have a 0 size. * @code * DbData db_data; * string filter("*"); * * db_data = db->get_device_alias_list(filter); * * vector al_list; * db_data >> al_list; * * cout << al_list.size() << " device alias defined in db" << endl; * for (int i=0;i < al_list.size();i++) * cout << "alias = " << al_list[i] << endl; * @endcode * * @param [in] filter The filter * @return The device alias list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_device_alias_list(string &filter); /** * Get attribute alias list * * Get attribute alias list. The parameter is a string to filter the alias list returned. Wildcard (*) is * supported. For instance, if the string passed as the method parameter is initialised with only the * * character, all the defined attribute alias will be returned. The DbDatum returned by this method is * initialised with an array of strings and must be extracted into a vector. If there is no alias with the * given filter, the returned array will have a 0 size. * * @param [in] filter The filter * @return The attribute alias list * * @exception ConnectionFailed,CommunicationFailed,DevFailed from device */ DbDatum get_attribute_alias_list(string &filter); //@} ///@privatesection Database(string &host, int port, CORBA::ORB *orb=NULL); Database(string &file); Database(const Database &); Database & operator=(const Database &); void write_filedatabase(); void reread_filedatabase(); void write_event_channel_ior_filedatabase(string &); void build_connection (); void post_reconnection(); ~Database(); inline Device_var &get_dbase() { return device;} void check_tango_host(const char *); AccessControlType check_access_control(string &); bool is_control_access_checked() {return access_checked;} void set_access_checked(bool val) {access_checked = val;} void set_tango_utils(Tango::Util *ptr) {db_tg=ptr;} int get_server_release() {return serv_version;} DevErrorList &get_access_except_errors() {return access_except_errors;} void clear_access_except_errors() {access_except_errors.length(0);} bool is_command_allowed(string &,string &); bool is_multi_tango_host() {return db_multi_svc;} vector &get_multi_host() {return multi_db_host;} vector &get_multi_port() {return multi_db_port;} const string &get_file_name(); const string &get_orig_tango_host() {return ext->orig_tango_host;} void set_orig_tango_host(const string &_s) {ext->orig_tango_host=_s;} #ifdef _TG_WINDOWS_ Database(CORBA::ORB *orb,string &,string &); long get_tango_host_from_reg(char **,string &,string &); #endif // // general methods // CORBA::Any *fill_server_cache(string &,string &); // // device methods // DbDatum get_device_name(string &, string &,DbServerCache *dsc); // // server methods // DbServerInfo get_server_info(string &); void put_server_info(DbServerInfo &); void delete_server_info(string &); // // property methods // void get_property(string, DbData &,DbServerCache *dsc); void get_property_forced(string, DbData &,DbServerCache *dsc = NULL); void get_device_property(string, DbData &, DbServerCache *dsc); DbDatum get_device_property_list(string &,string &); void get_device_property_list(string &,const string &,vector &,DbServerCache *dsc = NULL); void get_device_attribute_property(string, DbData &, DbServerCache *dsc); void get_device_pipe_property(string, DbData &, DbServerCache *dsc); void delete_all_device_attribute_property(string, DbData &); void delete_all_device_pipe_property(string, DbData &); void get_class_property(string, DbData &, DbServerCache *dsc); void get_class_attribute_property(string, DbData &, DbServerCache *dsc); void get_class_pipe_property(string, DbData &, DbServerCache *dsc); // // event methods // void export_event(DevVarStringArray *); void unexport_event(string &); CORBA::Any *import_event(string &); }; // // Some Database class inline methods // inline string Database::dev_name() { if (db_device_name.empty() == true) { CORBA::String_var n = device->name(); db_device_name = n; } return db_device_name; } #endif /* _DATABASE_H */ tango-9.2.5a/lib/cpp/client/DbDevice.h0000644023471100065110000001625013034744772014371 00000000000000// // dbapi.h - include file for TANGO database api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef _DBDEVICE_H #define _DBDEVICE_H /**************************************************************************************** * * * The DbDevice class * * ------------------ * * * ***************************************************************************************/ /** * A high level object for a device interface to the database * * A database object for a device which can be used to query or modify properties, import and export information * for a device. This class provides an easy to use interface for device objects in the database. It uses * the methods of the Database class therefore the reader is referred to these for the exact calling syntax and * examples. The following methods are defined for the DbDevice class : * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup DBase */ class DbDevice { private : string name; Database *dbase; int db_ind; bool ext_dbase; class DbDeviceExt { public: DbDeviceExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DbDeviceExt *ext; #endif public : /**@name Constructors */ //@{ /** * Create a DbDevice object. * * A constructor for a DbDevice object for a device in the TANGO database specified by the TANGO_HOST * environment variable. * * @param [in] dev_name The device name * */ DbDevice(string &dev_name); /** * Create a DbDevice object using a specified database * * A constructor for a DbDevice object for the device in the specified database. This method reuses the * Database supplied by the programmer. * * @param [in] dev_name The device name * @param [in] db The database object * */ DbDevice(string &dev_name, Database *db); //@} /**@name Device oriented methods */ //@{ /** * Import the device from database * * Query the database for the import info of this device. Returns a DbDevImportInfo structure. * * @return [in] The device import information * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ DbDevImportInfo import_device(); /** * Export device info to the database * * Update the export info for this device in the database. * * @param [in] dev_info Device export info * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void export_device(DbDevExportInfo &dev_info); //@} /**@name Property oriented methods */ //@{ /** * Get device property from database * * Query the database for the list of properties of this device. See Database::get_device_property() for an * example of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_property(DbData &db); /** * Update device property in database * * Update the list of properties for this device in the database. See Database::put_device_property() for an * example of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_property(DbData &db); /** * Remove device property from database * * Delete the list of specified properties for this device in the database. See Database::delete_property() for * an example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_property(DbData &db); /** * Get device attribute property from database * * Query the database for the list of attribute properties of this device. See Database::get_device_attribute_property() * for an example of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_attribute_property(DbData &db); /** * Update device attribute property in database * * Update the list of attribute properties for this device in the database. See Database::put_device_attribute_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_attribute_property(DbData &db); /** * Remove device attribute property from database * * Delete all properties for the list of specified attributes for this device in the database. See Database::delete_device_attribute_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_attribute_property(DbData &db); /** * Get device pipe property from database * * Query the database for the list of pipe properties of this device. See Database::get_device_pipe_property() * for an example of how to specify and retrieve the properties. * * @param [in,out] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void get_pipe_property(DbData &db); /** * Update device pipe property in database * * Update the list of pipe properties for this device in the database. See Database::put_device_pipe_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) and value * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void put_pipe_property(DbData &db); /** * Remove device pipe property from database * * Delete all properties for the list of specified pipes for this device in the database. See Database::delete_device_pipe_property() * for an example of how to specify the properties. * * @param [in] db Property name(s) * * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ void delete_pipe_property(DbData &db); //@} /// @privatesection DbDevice(string &,string &,string &); ~DbDevice(); void set_name(string &new_name) {name = new_name;} Database *get_dbase(); void set_dbase(Database *db) {dbase = db;} AccessControlType check_access_control(); void clear_access_except_errors(); void get_property_list(const string &,vector &); }; #endif /* _DBDEVICE_H */ tango-9.2.5a/lib/cpp/client/ApiUtil.h0000644023471100065110000002035413034744772014273 00000000000000////////////////////////////////////////////////////////////////// // // ApiUtil.h - include file for TANGO device api class ApiUtil // // // Copyright (C) : 2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 20437 $ // /////////////////////////////////////////////////////////////// #ifndef _APIUTIL_H #define _APIUTIL_H /**************************************************************************************** * * * The ApiUtil class * * ----------------- * * * ***************************************************************************************/ /** * Miscellaneous utility methods usefull in a Tango client. * * This class is a singleton. Therefore, it is not necessary to create it. It will be automatically done. A static * method allows a user to retrieve the instance * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup Client */ class ApiUtil { public: /** * Retrieve the ApiUtil instance * * Return the ApiUtil singleton instance * * @return The singleton instance */ TANGO_IMP_EXP static ApiUtil *instance(); /** * Destroy the ApiUtil instance * * Destroy the ApiUtil singleton instance. */ TANGO_IMP_EXP static inline void cleanup() {if (_instance != NULL){delete _instance;_instance=NULL;}} /** * Get environment variable * * Get environment variable. On Unixes OS, this call tries to get the variable in the caller environment then * in a file @e .tangorc in the user home directory and finally in a file @e /etc/tangorc. On Windows, this call looks * in the user environment then in a file stored in %TANGO_HOME%/tangorc. This method returns 0 of the * environment variable is found. Otherwise, it returns -1. * * @param [in] name The environment variable name * @param [out] value The environment variable value * @return Set to -1 if the environment varaibel is not found */ TANGO_IMP_EXP static int get_env_var(const char *name,string &value); /** * Get pending asynchronous requets number * * Return number of asynchronous pending requests (any device). * * @param [in] ty Asynchronous request type * @return Pending asynchronous request number */ size_t pending_asynch_call(asyn_req_type ty) {if (ty==POLLING)return asyn_p_table->get_request_nb(); else if (ty==CALL_BACK)return asyn_p_table->get_cb_request_nb(); else return (asyn_p_table->get_request_nb()+asyn_p_table->get_cb_request_nb());} /** * Fire callback methods for asynchronous request(s) * * Fire callback methods for all (any device) asynchronous requests (command and attribute) with already * arrived replied. Returns immediately if there is no replies already arrived or if there is no asynchronous * requests. */ void get_asynch_replies(); /** * Fire callback methods for asynchronous request(s) with timeout * * Fire callback methods for all (any device) asynchronous requests (command and attributes) with already * arrived replied. Wait and block the caller for timeout milliseconds if they are some device asynchronous * requests which are not yet arrived. Returns immediately if there is no asynchronous request. If timeout is * set to 0, the call waits until all the asynchronous requests sent has received a reply. * * @param [in] timeout The timeout value */ void get_asynch_replies(long timeout); /** * Set asynchronous callback sub-model * * Set the asynchronous callback sub-model between the pull and push sub-model. See Tango book chapter 4.5 to read * the definition of these sub-models. * By default, all Tango client using asynchronous callback model are in pull sub-model. This call must be * used to switch to the push sub-model. NOTE that in push sub-model, a separate thread is spawned to deal * with server replies. * * @param [in] csm The asynchronous callback sub-model */ void set_asynch_cb_sub_model(cb_sub_model csm); /** * Get asynchronous callback sub-model * * Get the asynchronous callback sub-model * * @return The asynchronous callback sub-model */ cb_sub_model get_asynch_cb_sub_model() {return auto_cb;} /// @privatesection CORBA::ORB_ptr get_orb() {return CORBA::ORB::_duplicate(_orb);} void set_orb(CORBA::ORB_ptr orb_in) {_orb = orb_in;} void create_orb(); int get_db_ind(); int get_db_ind(string &host,int port); vector &get_db_vect() {return db_vect;} bool in_server() {return in_serv;} void in_server(bool serv) {in_serv = serv;} TangoSys_Pid get_client_pid() {return cl_pid;} void clean_locking_threads(bool clean=true); bool is_lock_exit_installed() {omni_mutex_lock guard(lock_th_map);return exit_lock_installed;} void set_lock_exit_installed(bool in) {omni_mutex_lock guard(lock_th_map);exit_lock_installed = in;} bool need_reset_already_flag() {return reset_already_executed_flag;} void need_reset_already_flag(bool in) {reset_already_executed_flag = in;} TANGO_IMP_EXP static inline bool _is_instance_null() {return _instance == NULL;} // // Utilities methods // int get_user_connect_timeout() {return user_connect_timeout;} DevLong get_user_sub_hwm() {return user_sub_hwm;} void set_event_buffer_hwm(DevLong val) {if (user_sub_hwm == -1)user_sub_hwm=val;} void get_ip_from_if(vector &); void print_error_message(const char *); void set_sig_handler(); // // EventConsumer related methods // void create_notifd_event_consumer(); void create_zmq_event_consumer(); bool is_notifd_event_consumer_created() {return notifd_event_consumer != NULL;} NotifdEventConsumer *get_notifd_event_consumer(); bool is_zmq_event_consumer_created() {return zmq_event_consumer != NULL;} ZmqEventConsumer *get_zmq_event_consumer(); // // Asynchronous methods // AsynReq *get_pasyn_table() {return asyn_p_table;} // // Conv. between AttributeValuexxx and DeviceAttribute // static void attr_to_device(const AttributeValue *,const AttributeValue_3 *,long,DeviceAttribute *); static void attr_to_device(const AttributeValue_4 *,long,DeviceAttribute *); static void attr_to_device(const AttributeValue_5 *,long,DeviceAttribute *); static void device_to_attr(const DeviceAttribute &,AttributeValue_4 &); static void device_to_attr(const DeviceAttribute &,AttributeValue &,string &); // // Conv. between AttributeConfig and AttributeInfoEx // static void AttributeInfoEx_to_AttributeConfig(const AttributeInfoEx *,AttributeConfig_5 *); protected: /// @privatesection ApiUtil(); virtual ~ApiUtil(); vector db_vect; omni_mutex the_mutex; CORBA::ORB_ptr _orb; bool in_serv; cb_sub_model auto_cb; CbThreadCmd cb_thread_cmd; CallBackThread *cb_thread_ptr; AsynReq *asyn_p_table; public: /// @privatesection omni_mutex lock_th_map; map lock_threads; private: class ApiUtilExt { public: ApiUtilExt() {}; }; TANGO_IMP static ApiUtil *_instance; static omni_mutex inst_mutex; bool exit_lock_installed; bool reset_already_executed_flag; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else ApiUtilExt *ext; // Class extension #endif NotifdEventConsumer *notifd_event_consumer; TangoSys_Pid cl_pid; int user_connect_timeout; ZmqEventConsumer *zmq_event_consumer; vector host_ip_adrs; DevLong user_sub_hwm; template static void attr_to_device_base(const T *,DeviceAttribute *); }; class _KillProc_: public omni_thread { public: void run(void *) {::exit(-1);} }; #endif /* _APIUTIL_H */ tango-9.2.5a/lib/cpp/client/DeviceData.h0000644023471100065110000005251613034744771014721 00000000000000////////////////////////////////////////////////////////////////// // // DeviceData.h - include file for TANGO device api class DeviceData // // // Copyright (C) : 2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 20437 $ // /////////////////////////////////////////////////////////////// #ifndef _DEVICEDATA_H #define _DEVICEDATA_H /**************************************************************************************** * * * The DeviceData class * * -------------------- * * * ***************************************************************************************/ /** * Fundamental type for sending and receiving data from device commands * * This is the fundamental type for sending and receiving data from device commands. The values can be * inserted and extracted using the operators << and >> respectively and insert() for mixed data types. A * status flag indicates if there is data in the DbDatum object or not. An additional flag allows the user to * activate exceptions. * * Insertion by pointers takes full ownership of the pointed to memory. The insertion copy the data in * the DeviceData object and delete the pointed to memory. Therefore, the memory is not more usable * after the insertion.\n * When using extraction by pointers, the pointed to memory is inside * the DeviceData object and its lifetime is the same than the DeviceData object lifetime. * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup Client */ class DeviceData { public : ///@privatesection // // constructor methods // enum except_flags { isempty_flag, wrongtype_flag, numFlags }; // DeviceData(); DeviceData(const DeviceData &); DeviceData & operator=(const DeviceData &); #ifdef HAS_RVALUE DeviceData(DeviceData &&); DeviceData & operator=(DeviceData &&); #endif virtual ~DeviceData(); CORBA::Any_var any; ///@publicsection /**@name Constructors */ //@{ /** * Create a DeviceData object. * * Default constructor. The instance is empty * */ DeviceData(); //@} /**@name Inserters and Extractors */ //@{ /** * The insert operators * * The insert operators are specified for the following C++ types : * @li bool * @li short * @li unsigned short * @li DevLong * @li DevULong * @li DevLong64 * @li DevULong64 * @li DevState * @li DevEncoded * @li float * @li double * @li string * @li char* (insert only) * @li const char * * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Operators exist for inserting the native TANGO CORBA sequence types. These can be * useful for programmers who want to use the TANGO api internally in their device servers and do not want * to convert from CORBA to C++ types. Insert and extract operators exist for the following types : * @li DevVarUCharArray * * @li DevVarShortArray * * @li DevVarUShortArray * * @li DevVarLongArray * * @li DevVarULongArray * * @li DevVarLong64Array * * @li DevVarULong64Array * * @li DevVarFloatArray * * @li DevVarDoubleArray * * @li DevVarStringArray * * @li DevVarLongStringArray * * @li DevVarDoubleStringArray * * * Insertion by pointers takes full ownership of the pointed to memory. The insertion copy the data in * the DeviceData object and delete the pointed to memory. Therefore, the memory is not more usable * after the insertion. * * Operators also exist for inserting TANGO CORBA sequence type by reference. The insertion copy the * data into the DeviceData object. Insert operator exist for the following types : * @li DevVarUCharArray & * @li DevVarShortArray & * @li DevVarUShortArray & * @li DevVarLongArray & * @li DevVarULongArray & * @li DevVarLong64Array& * @li DevVarULong64Array& * @li DevVarFloatArray & * @li DevVarDoubleArray & * @li DevVarStringArray & * @li DevVarLongStringArray& * @li DevVarDoubleStringArray& * * Special care has been taken to avoid memory copy between the network layer and the user application. * Nevertheless, C++ vector types are not the CORBA native type and one copy is unavoidable when using * vectors. Using the native TANGO CORBA sequence types avoid any copy. When using these TANGO * CORBA sequence types, insertion into the DeviceData object consumes the memory pointed to by the * pointer. After the insertion, it is not necessary to delete the memory. It will be done by the destruction of * the DeviceData object. For extraction, the pointer used for the extraction points into memory inside the * DeviceData object and you should not delete it * Here is an example of creating, inserting and extracting some data type from/into DeviceData object : * @code * DeviceData my_short, my_long, my_string; * DeviceData my_float_vector, my_double_vector; * string a_string; * short a_short; * DevLong a_long; * vector a_float_vector; * vector a_double_vector; * * my_short << 100; // insert a short * my_short >> a_short; // extract a short * * my_long << 1000; // insert a long * my_long >> a_long; // extract a long * * my_string << string(“estas lista a bailar el tango ?â€); // insert a string * my_string >> a_string; // extract a string * * my_float_vector << a_float_vector // insert a vector of floats * my_float_vector >> a_float_vector; // extract a vector of floats * * my_double_vector << a_double_vector; // insert a vector of doubles * my_double_vector >> a_double_vector; // extract a vector of doubles * * // * // Example of memory management with TANGO sequence types without memory leaks * // * * for (int i = 0;i < 10;i++) * { * DeviceData din,dout; * DevVarLongArray *in = new DevVarLongArray(); * in->length(2); * (*in)[0] = 2; * (*in)[1] = 4; * din << in; * try * { * dout = device->command_inout(“Cmdâ€,din); * } * catch(DevFailed &e) * { * .... * } * const DevVarLongArray *out; * dout >> out; * cout << “Received value = “ << (*out)[0]; * } * @endcode * * @param [in] datum The data to be inserted * @exception WrongData if requested */ void operator << (bool datum) {any <<= CORBA::Any::from_boolean(datum);} /** * Insert data into a DeviceData for the DevVarLongStringArray data type * * Insert data into a DeviceData for the DevVarLongStringArray data type * * @param [in] vl The long vector to be inserted * @param [in] vs The string vector to be inserted * @exception WrongData if requested */ void insert(vector &vl, vector&vs); /** * Insert data into a DeviceData for the DevVarDoubleStringArray data type * * Insert data into a DeviceData for the DevVarDoubleStringArray data type * * @param [in] vd The double vector to be inserted * @param [in] vs The string vector to be inserted * @exception WrongData if requested */ void insert(vector &vd, vector &vs); /** * Insert data into a DeviceData for the DevEncoded data type * * Insert data into a DeviceData for the DevEncoded data type * @n Similar methods with different parameters data type exist for * inserting data for a DevEncoded data type * @li void insert(const char *str, DevVarCharArray *data); * @li void insert(const char *str, unsigned char *data,unsigned int length); * * These three methods do not take ownership of the memory used for the data buffer. * * @param [in] str The string part of the DevEncoded instance * @param [in] buffer The data part of the DevEncoded instance * @exception WrongData if requested */ void insert(const string &str,vector &buffer); /** * The extract operators * * The extract operators are specified for the following C++ types : * @li bool * @li short * @li unsigned short * @li DevLong * @li DevULong * @li DevLong64 * @li DevULong64 * @li float * @li double * @li string * @li char* (insert only) * @li const char * * @li DevEncoded * @li DevState * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Operators exist for extracting the native TANGO CORBA sequence types. These can be * useful for programmers who want to use the TANGO api internally in their device servers and do not want * to convert from CORBA to C++ types. Insert and extract operators exist for the following types : * @li const DevVarUCharArray * * @li const DevVarShortArray * * @li const DevVarUShortArray * * @li const DevVarLongArray * * @li const DevVarULongArray * * @li const DevVarLong64Array * * @li const DevVarULong64Array * * @li const DevVarFloatArray * * @li const DevVarDoubleArray * * @li const DevVarStringArray * * @li const DevVarLongStringArray * * @li const DevVarDoubleStringArray * * * Note that when using extraction by pointers, the pointed to memory is inside * the DeviceData object and its lifetime is the same than the DeviceData object lifetime. * * Special care has been taken to avoid memory copy between the network layer and the user application. * Nevertheless, C++ vector types are not the CORBA native type and one copy is unavoidable when using * vectors. Using the native TANGO CORBA sequence types avoid any copy. When using these TANGO * CORBA sequence types, for extraction, the pointer used for the extraction points into memory inside the * DeviceData object and you should not delete it * See DeviceData::operator<< for inserters and extractors usage example * * @param [out] datum The variable which will be initalized * @return Boolean set to false if the extraction failed * @exception WrongData if requested */ bool operator >> (bool &datum); /** * Extract data from a DeviceData for the DevVarLongStringArray data type * * Extract data from a DeviceData for the DevVarLongStringArray data type * * @param [out] vl The long vector which will be inialized * @param [out] vs The string vector to be initialized * @return Boolean set to false if the extraction failed * @exception WrongData if requested */ bool extract(vector &vl, vector &vs); /** * Extract data from a DeviceData for the DevVarDoubleStringArray data type * * Extract data from a DeviceData for the DevVarDoubleStringArray data type * * @param [out] vd The double vector to be initialized * @param [out] vs The string vector to be initialized * @return Boolean set to false if the extraction failed * @exception WrongData if requested */ bool extract(vector &vd, vector &vs); /** * Extract data from a DeviceData for the DevEncoded data type * * Extract command data when the command data type is DevEncoded * Similar method with following signature also exist * @li extract(string &str,vector &data); * * @param [out] str The DevEncoded string * @param [out] data The DevEncoded data pointer * @param [out] length The DevEncoded data length * @return Boolean set to false if the extraction failed * @exception WrongData if requested */ bool extract(const char *&str,const unsigned char *&data,unsigned int &length); //@} ///@privatesection // // insert methods for native C++ types // // void operator << (bool datum) {any <<= CORBA::Any::from_boolean(datum);} void operator << (short datum) {any <<= datum;} void operator << (unsigned short datum) {any <<= datum;} void operator << (DevLong datum) {any <<= datum;} void operator << (DevULong datum) {any <<= datum;} void operator << (DevLong64 datum) {any <<= datum;} void operator << (DevULong64 datum) {any <<= datum;} void operator << (float datum) {any <<= datum;} void operator << (double datum) {any <<= datum;} void operator << (char *&datum) {any <<= datum;} void operator << (const char *&datum) {any <<= datum;} void operator << (string &datum) {any <<= datum.c_str();} void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector&); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector&); void operator << (vector&); void operator << (DevState datum) {(any.inout()) <<= datum;} void operator << (DevEncoded &datum) {(any.inout()) <<= datum;} // void insert(vector&, vector&); // void insert(vector&, vector&); // void insert(const string &,vector&); void insert(const char *,DevVarCharArray *); void insert(const char *,unsigned char *,unsigned int); // // insert methods for TANGO CORBA sequence types // inline void operator << (DevVarCharArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarShortArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarUShortArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarLongArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarLong64Array *datum) { any.inout() <<= datum;} inline void operator << (DevVarULongArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarULong64Array* datum) { any.inout() <<= datum;} inline void operator << (DevVarFloatArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarDoubleArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarStringArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarLongStringArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarDoubleStringArray* datum) { any.inout() <<= datum;} inline void operator << (DevVarCharArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarShortArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarUShortArray datum) { any.inout() <<= datum;} inline void operator << (DevVarLongArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarLong64Array &datum) { any.inout() <<= datum;} inline void operator << (DevVarULongArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarULong64Array &datum) { any.inout() <<= datum;} inline void operator << (DevVarFloatArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarDoubleArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarStringArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarLongStringArray &datum) { any.inout() <<= datum;} inline void operator << (DevVarDoubleStringArray &datum) { any.inout() <<= datum;} // // extract methods for native C++ types // // bool operator >> (bool&); bool operator >> (short&); bool operator >> (unsigned short&); bool operator >> (DevLong&); bool operator >> (DevULong&); bool operator >> (DevLong64&); bool operator >> (DevULong64&); bool operator >> (float&); bool operator >> (double&); bool operator >> (const char*&); bool operator >> (string&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (DevState&); // bool extract(vector&, vector&); // bool extract(vector&, vector&); // bool extract(const char *&,unsigned char *&,unsigned int &); bool extract(string &,vector &); // // extract methods for TANGO CORBA sequence types // bool operator >> (const DevVarCharArray* &datum); bool operator >> (const DevVarShortArray* &datum); bool operator >> (const DevVarUShortArray* &datum); bool operator >> (const DevVarLongArray* &datum); bool operator >> (const DevVarLong64Array* &datum); bool operator >> (const DevVarULongArray* &datum); bool operator >> (const DevVarULong64Array* &datum); bool operator >> (const DevVarFloatArray* &datum); bool operator >> (const DevVarDoubleArray* &datum); bool operator >> (const DevVarStringArray* &datum); bool operator >> (const DevVarLongStringArray* &datum); bool operator >> (const DevVarDoubleStringArray* &datum); bool operator >> (const DevEncoded* &datum); bool operator >> (DevEncoded &datum); ///@publicsection /**@name Exception and error related methods methods */ //@{ /** * Set exception flag * * It's a method which allows the user to switch on/off exception throwing when trying to extract data from a * DeviceData object. The following flags are supported : * @li @b isempty_flag - throw a Empty DeviceData exception (reason = API_EmptyDeviceData) if user tries to extract * data from an empty DeviceData object. By default, this flag is set * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion. By default, this flag * is not set * * @param [in] fl The exception flag */ void exceptions(bitset fl) {exceptions_flags = fl;} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * DeviceData dd; * * bitset bs = dd.exceptions(); * cout << "bs = " << bs << endl; * * da.set_exceptions(DeviceData::wrongtype_flag); * bs = dd.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return exceptions_flags;} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(except_flags fl) {exceptions_flags.reset((size_t)fl);} /** * Set one exception flag * * Sets one exception flag. See DeviceData::exceptions() for a usage example. * * @param [in] fl The exception flag */ void set_exceptions(except_flags fl) {exceptions_flags.set((size_t)fl);} /** * Get instance extraction state * * Allow the user to find out what was the reason of extraction from DeviceData failure. This * method has to be used when exceptions are disabled. * Here is an example of how method state() could be used * @code * DeviceData dd = .... * * bitset bs; * da.exceptions(bs); * * DevLong dl; * if ((da >> dl) == false) * { * bitset bs_err = da.state(); * if (bs_err.test(DeviceData::isempty_flag) == true) * ..... * } * @endcode * * @return The error bit set. */ bitset state() {return ext->ext_state;} //@} /**@name miscellaneous methods */ //@{ /** * Check if the DeviceData instance is empty * * is_empty() is a boolean method which returns true or false depending on whether the DeviceData object * contains data or not. It can be used to test whether the DeviceData has been initialized or not but * you have first to disable exception throwing in case of empty object e.g. * @code * string string_read; * * DeviceData sl_read = my_device->command_inout(“ReadLineâ€); * sl_read.reset_exceptions(DeviceData::isempty_flag); * * if (! sl_read.is_empty()) * { * sl_read >> string_read; * } * else * { * cout << “ no data read from serial line !†<< endl; * } * @endcode * * @return Boolean set to true is the instance is empty */ bool is_empty(); /** * Get Tango data type of the included data * * This method returns the Tango data type of the data inside the DeviceData object * * @return The data type */ int get_type(); //@} /** * Print a DeviceData instance * * Is an utility function to easily print the contents of a DeviceData object. This function knows all types * which could be inserted in a DeviceData object and print them accordingly. A special string is printed if * the DeviceData object is empty * @code * DeviceProxy *dev = new DeviceProxy(“...â€); * DeviceData out; * * out = dev->command_inout(“MyCommandâ€); * cout << “Command returned: †<< out << endl; * @endcode * * @param [in] str The printing stream * @param [in] dd The instance to be printed */ friend ostream &operator<<(ostream &str,DeviceData &dd); protected : ///@privatesection bool any_is_null(); bitset exceptions_flags; private: class DeviceDataExt { public: DeviceDataExt() {}; bitset ext_state; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DeviceDataExt *ext; // Class extension #endif }; #endif /* _DEVICEDATA_H */ tango-9.2.5a/lib/cpp/client/DeviceAttribute.h0000644023471100065110000013410413034744772016006 00000000000000 //+================================================================================================================== // // DeviceAttribute.h - include file for TANGO device api class DeviceAttribute // // // Copyright (C) : 2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 20437 $ // //+================================================================================================================== #ifndef _DEVICEATTRIBUTE_H #define _DEVICEATTRIBUTE_H /**************************************************************************************** * * * The DeviceAttribute class * * ------------------------- * * * ***************************************************************************************/ /** * Fundamental type for sending an dreceiving data to and from device attributes. * * This is the fundamental type for sending and receiving data to and from device attributes. The values can be * inserted and extracted using the operators << and >> respectively and insert() for mixed data types. There * are two ways to check if the extraction operator succeed : *
    *
  • 1. By testing the extractor operators return value. All the extractors operator returns a boolean value set * to false in case of problem. *
  • 2. By asking the DeviceAttribute object to throw exception in case of problem. By default, DeviceAttribute * throws exception : *
      *
    1. When the user try to extract data and the server reported an error when the attribute was read. *
    2. When the user try to extract data from an empty DeviceAttribute *
    *
* * For insertion into DeviceAttribute instance from TANGO CORBA sequence pointers, the DeviceAttribute * object takes ownership of the pointed to memory. This means that the pointed * to memory will be freed when the DeviceAttribute object is destroyed or when another data is * inserted into it. The insertion into DeviceAttribute instance from TANGO CORBA sequence reference copy * the data into the DeviceAttribute object.\n * For extraction into TANGO CORBA sequence types, the extraction method consumes the * memory allocated to store the data and it is the caller responsibility to delete this memory. * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup Client */ class DeviceAttribute { public : ///@privatesection // // constructor methods // enum except_flags { isempty_flag = 0, wrongtype_flag, failed_flag, unknown_format_flag, numFlags }; DeviceAttribute(const DeviceAttribute&); DeviceAttribute & operator=(const DeviceAttribute &); #ifdef HAS_RVALUE DeviceAttribute(DeviceAttribute &&); DeviceAttribute & operator=(DeviceAttribute &&); #endif void deep_copy(const DeviceAttribute &); DeviceAttribute(AttributeValue); ///@publicsection /**@name Constructors */ //@{ /** * Create a DeviceAttribute object. * * Default constructor. The instance is empty * */ DeviceAttribute(); /** * Create a DeviceAttribute object from attribute name and value for scalar attribute * * Create a DeviceAttribute object from attribute name and value for @b scalar attribute. * These constructors exists for the following data type: * @li DeviceAttribute(string &, bool); * @li DeviceAttribute(string &, short); * @li DeviceAttribute(string &, DevLong); * @li DeviceAttribute(string &, DevLong64); * @li DeviceAttribute(string &, float); * @li DeviceAttribute(string &, double); * @li DeviceAttribute(string &, unsigned char); * @li DeviceAttribute(string &, unsigned short); * @li DeviceAttribute(string &, DevULong); * @li DeviceAttribute(string &, DevULong64); * @li DeviceAttribute(string &, string &); * @li DeviceAttribute(string &, DevState); * @li DeviceAttribute(string &, DevEncoded &); * @n @n * @li DeviceAttribute(const char *, bool); * @li DeviceAttribute(const char *, short); * @li DeviceAttribute(const char *, DevLong); * @li DeviceAttribute(const char *, DevLong64); * @li DeviceAttribute(const char *, float); * @li DeviceAttribute(const char *, double); * @li DeviceAttribute(const char *, unsigned char); * @li DeviceAttribute(const char *, unsigned short); * @li DeviceAttribute(const char *, DevULong); * @li DeviceAttribute(const char *, DevULong64); * @li DeviceAttribute(const char *, string &); * @li DeviceAttribute(const char *, DevState); * @li DeviceAttribute(const char *,DevEncoded &); * * @param [in] name The attribute name * @param [in] val The attribute value */ DeviceAttribute(string &name, short val); /** * Create a DeviceAttribute object from attribute name and value for spectrum attribute * * Create a DeviceAttribute object from attribute name and value for @b spectrum attribute. * These constructors exists for the following data type: * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector&); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector &); * @li DeviceAttribute(string &, vector&); * @li DeviceAttribute(string &, vector & ); * @li DeviceAttribute(string &, vector &); * @n @n * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector&); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector &); * @li DeviceAttribute(const char *, vector&); * @li DeviceAttribute(const char *, vector & ); * @li DeviceAttribute(const char *, vector &); * * @param [in] name The attribute name * @param [in] val The attribute value */ DeviceAttribute(string &name, vector &val); /** * Create a DeviceAttribute object from attribute name and value for image attribute * * Create a DeviceAttribute object from attribute name and value for @b image attribute. * These constructors have two more parameters allowing the user to define the x and y image * dimensions. * These constructors exists for the following data type: * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector&, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector &, int, int); * @li DeviceAttribute(string &, vector&, int, int); * @li DeviceAttribute(string &, vector &, int, int ); * @li DeviceAttribute(string &, vector &, int, int); * @n @n * DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector&, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector &, int, int); * @li DeviceAttribute(const char *, vector&, int, int); * @li DeviceAttribute(const char *, vector & , int, int); * @li DeviceAttribute(const char *, vector &val,int dim_x,int dim_y); //@} ///@privatesection DeviceAttribute(string&, DevLong); DeviceAttribute(string&, double); DeviceAttribute(string&, string&); DeviceAttribute(string&, const char *); DeviceAttribute(string&, float); DeviceAttribute(string&, bool); DeviceAttribute(string&, unsigned short); DeviceAttribute(string&, unsigned char); DeviceAttribute(string&, DevLong64); DeviceAttribute(string&, DevULong); DeviceAttribute(string&, DevULong64); DeviceAttribute(string&, DevState); DeviceAttribute(string&, DevEncoded &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(string&, vector &,int,int); DeviceAttribute(const char *, short); DeviceAttribute(const char *, DevLong); DeviceAttribute(const char *, double); DeviceAttribute(const char *, string&); DeviceAttribute(const char *, const char *); DeviceAttribute(const char *, float); DeviceAttribute(const char *, bool); DeviceAttribute(const char *, unsigned short); DeviceAttribute(const char *, unsigned char); DeviceAttribute(const char *, DevLong64); DeviceAttribute(const char *, DevULong); DeviceAttribute(const char *, DevULong64); DeviceAttribute(const char *, DevState); DeviceAttribute(const char *, DevEncoded &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); DeviceAttribute(const char *, vector &,int,int); template DeviceAttribute(string &,T); template DeviceAttribute(const char *,T); template DeviceAttribute(string &,vector &); template DeviceAttribute(const char *,vector &); template DeviceAttribute(string &,vector &,int,int); template DeviceAttribute(const char *,vector &,int,int); template void base_val(T); template void base_vect(vector &); template void base_vect_size(vector &); template void operator << (T); template void operator << (vector &); template void insert(vector &,int,int); template bool operator >> (T &); template bool operator >> (vector &); template bool extract_read (vector &); template bool extract_set(vector &); template bool template_type_check(T &); virtual ~DeviceAttribute(); AttrQuality quality; AttrDataFormat data_format; int data_type; string name; int dim_x; int dim_y; int w_dim_x; int w_dim_y; TimeVal time; void set_w_dim_x(int val) {w_dim_x = val;} void set_w_dim_y(int val) {w_dim_y = val;} void set_error_list(DevErrorList *ptr) {err_list = ptr;} DevVarEncodedArray_var &get_Encoded_data() {return EncodedSeq;} DevErrorList_var &get_error_list() {return err_list;} DevVarLongArray_var LongSeq; DevVarShortArray_var ShortSeq; DevVarDoubleArray_var DoubleSeq; DevVarStringArray_var StringSeq; DevVarFloatArray_var FloatSeq; DevVarBooleanArray_var BooleanSeq; DevVarUShortArray_var UShortSeq; DevVarCharArray_var UCharSeq; DevVarLong64Array_var Long64Seq; DevVarULongArray_var ULongSeq; DevVarULong64Array_var ULong64Seq; DevVarStateArray_var StateSeq; DevVarEncodedArray_var EncodedSeq; DevErrorList_var err_list; // // For the state attribute // DevState d_state; bool d_state_filled; // // Insert operators for C++ types // ///@publicsection /**@name Inserters and Extractors */ //@{ /** * Insert attribute data * * Special care has been taken to avoid memory copy between the network layer and the user application. * Nevertheless, C++ vector types are not the CORBA native type and one copy is unavoidable when using * vectors. Using the native TANGO CORBA sequence types in most cases avoid any copy but needs some * more care about memory usage. * @li For insertion into DeviceAttribute instance from TANGO CORBA sequence pointers, the DeviceAttribute * object takes ownership of the pointed to memory. This means that the pointed * to memory will be freed when the DeviceAttribute object is destroyed or when another data is * inserted into it. * @li The insertion into DeviceAttribute instance from TANGO CORBA sequence reference copy * the data into the DeviceAttribute object. * * Insert operators for the following scalar C++ types * @li bool * @li short * @li DevLong * @li DevLong64 * @li float * @li double * @li unsigned char * @li unsigned short * @li DevULong * @li DevULong64 * @li string * @li DevState * @li DevEncoded * @li DevString * @li const char * * * Insert operators for the following C++ vector types for @b spectrum attributes : * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Insert operators for @b spectrum attribute and for the following types by pointer (with memory ownership transfert) : * @li DevVarBooleanArray * * @li DevVarShortArray * * @li DevVarLongArray * * @li DevVarLong64Array * * @li DevVarFloatArray * * @li DevVarDoubleArray * * @li DevVarUCharArray * * @li DevVarUShortArray * * @li DevVarULongArray * * @li DevVarULong64Array * * @li DevVarStringArray * * @li DevVarStateArray * * * Insert operators for @b spectrum attribute and for the following types by reference : * @li const DevVarBooleanArray & * @li const DevVarShortArray & * @li const DevVarLongArray & * @li const DevVarLong64Array& * @li const DevVarFloatArray & * @li const DevVarDoubleArray & * @li const DevVarUCharArray & * @li const DevVarUShortArray & * @li const DevVarULongArray & * @li const DevVarULong64Array& * @li const DevVarStringArray & * @li const DevVarStateArray & * * Here is an example of creating, inserting and extracting some DeviceAttribute types : * @code * DeviceAttribute my_short, my_long, my_string; * DeviceAttribute my_float_vector, my_double_vector; * string a_string; * short a_short; * DevLong a_long; * vector a_float_vector; * vector a_double_vector; * * my_short << 100; // insert a short * my_short >> a_short; // extract a short * * my_long << 1000; // insert a long * my_long >> a_long; // extract a DevLong * * my_string << string("estas lista a bailar el tango ?"); // insert a string * my_string >> a_string; // extract a string * * my_float_vector << a_float_vector // insert a vector of floats * my_float_vector >> a_float_vector; // extract a vector of floats * * my_double_vector << a_double_vector; // insert a vector of doubles * my_double_vector >> a_double_vector; // extract a vector of doubles * // * // Extract read and set value of an attribute separately * // and get their dimensions * // * vector r_float_vector, w_float_vector; * * my_float_vector.extract_read (r_float_vector) // extract read values * int dim_x = my_float_vector.get_dim_x(); // get x dimension * int dim_y = my_float_vector.get_dim_y(); // get y dimension * * my_float_vector.extract_set (w_float_vector) // extract set values * int w_dim_x = my_float_vector.get_written_dim_x(); // get x dimension * int W_dim_y = my_float_vector.get_written_dim_y(); // get y dimension * // * // Example of memory management with TANGO sequence types without memory leaks * // * for (int i = 0;i < 10;i++) * { * DeviceAttribute da; * DevVarLongArray *out; * try * { * da = device->read_attribute("Attr"); * da >> out; * } * catch(DevFailed &e) * { * .... * } * cout << "Received value = " << (*out)[0]; * delete out; * } * @endcode * * @param [in] val The attribute value * @exception WrongData if requested */ void operator << (short val); /** * Insert attribute data for DevEncoded attribute * * Insert attribute data when the attribute data type is DevEncoded * @n Similar methods with following signature also exist * @li insert(const string &str, vector &data); * @li insert(const char *str, DevVarCharArray *data); * * These three methods do not take ownership of the memory used for the data buffer. * @n See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [in] str The DevEncoded string * @param [in] data The DevEncoded data pointer * @param [in] length The DevEncoded data length * @exception WrongData if requested */ void insert(const char *str,unsigned char *data,unsigned int length); /** * Insert attribute data for image attribute (from C++ vector) * * Insert methods for the following C++ vector types for image attributes allowing the specification of * the x and y image dimensions : * @li insert(vector &,int, int) * @li insert(vector &,int, int) * @li insert(vector&,int, int) * @li insert(vector&,int, int) * @li insert(vector &,int, int) * @li insert(vector &,int, int) * @li insert(vector &,int, int) * @li insert(vector &,int, int) * @li insert(vector&,int, int) * @li insert(vector&,int, int) * @li insert(vector &,int, int) * @li insert(vector &,int, int) * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [in] datum The attribute data * @param [in] dim_x The attribute X dimension * @param [in] dim_y The attribute Y dimension * @exception WrongData if requested */ void insert(vector &datum,int dim_x,int dim_y); /** * Insert attribute data for image attribute (from CORBA sequence by reference) * * Insert methods for @b image attribute and for the following types by reference. * These method allow the programmer to define the x and y image dimensions. The following methods are defined : * @li insert(const DevVarBooleanArray &,int, int) * @li insert(const DevVarShortArray &,int, int) * @li insert(const DevVarLongArray &,int, int) * @li insert(const DevVarLong64Array&,int, int) * @li insert(const DevVarFloatArray &,int, int) * @li insert(const DevVarDoubleArray &,int, int) * @li insert(const DevVarUCharArray &,int, int) * @li insert(const DevVarUShortArray &,int, int) * @li insert(const DevVarULongArray &,int, int) * @li insert(const DevVarULong64Array&,int, int) * @li insert(const DevVarStringArray &,int, int) * @li insert(const DevVarStateArray &,int, int) * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [in] datum The attribute data * @param [in] dim_x The attribute X dimension * @param [in] dim_y The attribute Y dimension * @exception WrongData if requested */ void insert(const DevVarShortArray &datum,int dim_x,int dim_y); /** * Insert attribute data for image attribute (from CORBA sequence by pointer) * * Insert methods for @b image attribute and pointers. The DeviceAttribute object takes ownership of the * given memory. These method allow the programmer to define the x * and y image dimensions. The following methods are defined : * @li insert(DevVarBooleanArray *, int , int ) * @li insert(DevVarShortArray *, int , int ) * @li insert(DevVarLongArray *, int , int ) * @li insert(DevVarLong64Array *, int, int ) * @li insert(DevVarFloatArray *, int , int ) * @li insert(DevVarDoubleArray *, int , int ) * @li insert(DevVarUCharArray *, int , int ) * @li insert(DevVarUShortArray *, int , int ) * @li insert(DevVarULongArray *, int , int ) * @li insert(DevVarULong64Array *, int, int ) * @li insert(DevVarStringArray *, int , int ) * @li insert(DevVarStateArray *, int, int) * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [in] datum The attribute data * @param [in] dim_x The attribute X dimension * @param [in] dim_y The attribute Y dimension * @exception WrongData if requested */ void insert(DevVarShortArray *datum,int dim_x,int dim_y); /** * Extract attribute data * * Special care has been taken to avoid memory copy between the network layer and the user application. * Nevertheless, C++ vector types are not the CORBA native type and one copy is unavoidable when using * vectors. Using the native TANGO CORBA sequence types in most cases avoid any copy but needs some * more care about memory usage. * @li For extraction into TANGO CORBA sequence types, the extraction method consumes the * memory allocated to store the data and it is the caller responsibility to delete this memory. * * Extract operators for the following scalar C++ types * @li bool * @li short * @li DevLong * @li DevLong64 * @li float * @li double * @li unsigned char * @li unsigned short * @li DevULong * @li DevULong64 * @li string * @li DevState * @li DevEncoded * * Extract operators for the following C++ vector types for @b spectrum and @b image attributes : * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Extract operators for the following CORBA sequence types with memory consumption : * @li DevVarBooleanArray * * @li DevVarShortArray * * @li DevVarLongArray * * @li DevVarLong64Array * * @li DevVarFloatArray * * @li DevVarDoubleArray * * @li DevVarUCharArray * * @li DevVarUShortArray * * @li DevVarULongArray * * @li DevVarULong64Array * * @li DevVarStringArray * * @li DevVarStateArray * * @li DevVarEncodedArray * * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [out] data The attribute data * @exception WrongData if requested, DevFailed from device */ bool operator >> (short &data); /** * Extract attribute data for DevEncoded attribute * * Extract attribute data when the attribute data type is DevEncoded * It's the user responsability to release the memory pointed to by the two * pointers method parameter. * @n Similar method with following signature also exist * @b extract(string &,vector &); * @n See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [out] str The DevEncoded string * @param [out] data The DevEncoded data pointer * @param [out] length The DevEncoded data length * @exception WrongData if requested, DevFailed from device */ bool extract(const char *&str,unsigned char *&data,unsigned int &length); /** * Extract only read part of attribute data * * Extract methods to extract only the read value of an attribute into a C++ vector. The dimension of * the read value can be read by using the methods get_dim_x() and get_dim_y() or get_r_dimension(). * The methods use the same return values as the extraction operators with exceptions triggered by the * exception flags. This method exist for the following data type: * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read (vector&); * @li bool DeviceAttribute::extract_read(string&, vector &); * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [out] data The attribute data * @exception WrongData if requested, DevFailed from device */ bool extract_read (vector &data); /** * Extract only written part of attribute data * * Extract methods to extract only the set value of an attribute into a C++ vector. The dimension * of the set value can be read by using the methods get_written_dim_x() and get_written_dim_y() * or get_w_dimension(). The methods use the same return values as the extraction operators with * exceptions triggered by the exception flags. This method exist for the following data type: * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set (vector&); * @li bool DeviceAttribute::extract_set(string &, vector &); * See DeviceAttribute::operator<< for example of inserting and extracting data to/from DeviceAttribute instance * * @param [out] data The attribute data * @exception WrongData if requested, DevFailed from device */ bool extract_set (vector &data); //@} ///@privatesection // void operator << (short); void operator << (DevLong); void operator << (double); void operator << (string &); void operator << (float); void operator << (bool); void operator << (unsigned short); void operator << (unsigned char); void operator << (DevLong64); void operator << (DevULong); void operator << (DevULong64); void operator << (DevState); void operator << (DevEncoded &); void operator << (DevString); void operator << (const char *); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (vector &); void operator << (const DevVarShortArray &datum); void operator << (const DevVarLongArray &datum); void operator << (const DevVarDoubleArray &datum); void operator << (const DevVarStringArray &datum); void operator << (const DevVarFloatArray &datum); void operator << (const DevVarBooleanArray &datum); void operator << (const DevVarUShortArray &datum); void operator << (const DevVarCharArray &datum); void operator << (const DevVarLong64Array &datum); void operator << (const DevVarULongArray &datum); void operator << (const DevVarULong64Array &datum); void operator << (const DevVarStateArray &datum); void operator << (DevVarShortArray *datum); void operator << (DevVarLongArray *datum); void operator << (DevVarDoubleArray *datum); void operator << (DevVarStringArray *datum); void operator << (DevVarFloatArray *datum); void operator << (DevVarBooleanArray *datum); void operator << (DevVarUShortArray *datum); void operator << (DevVarCharArray *datum); void operator << (DevVarLong64Array *datum); void operator << (DevVarULongArray *datum); void operator << (DevVarULong64Array *datum); void operator << (DevVarStateArray *datum); void operator << (TANGO_UNUSED(DevVarEncodedArray *datum)) {} // For template stuff // // Insert methods // // void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); void insert(vector &,int,int); // void insert(const DevVarShortArray &datum,int,int); void insert(const DevVarLongArray &datum,int,int); void insert(const DevVarDoubleArray &datum,int,int); void insert(const DevVarStringArray &datum,int,int); void insert(const DevVarFloatArray &datum,int,int); void insert(const DevVarBooleanArray &datum,int,int); void insert(const DevVarUShortArray &datum,int,int); void insert(const DevVarCharArray &datum,int,int); void insert(const DevVarLong64Array &datum,int,int); void insert(const DevVarULongArray &datum,int,int); void insert(const DevVarULong64Array &datum,int,int); void insert(const DevVarStateArray &datum,int,int); // void insert(DevVarShortArray *datum,int,int); void insert(DevVarLongArray *datum,int,int); void insert(DevVarDoubleArray *datum,int,int); void insert(DevVarStringArray *datum,int,int); void insert(DevVarFloatArray *datum,int,int); void insert(DevVarBooleanArray *datum,int,int); void insert(DevVarUShortArray *datum,int,int); void insert(DevVarCharArray *datum,int,int); void insert(DevVarLong64Array *datum,int,int); void insert(DevVarULongArray *datum,int,int); void insert(DevVarULong64Array *datum,int,int); void insert(DevVarStateArray *datum,int,int); void insert(char *&,unsigned char *&,unsigned int); // Deprecated. For compatibility purpose // void insert(const char *str,unsigned char *data,unsigned int length); void insert(const string &,vector &); void insert(string &,vector &); // Deprecated. For compatibility purpose void insert(const char *,DevVarCharArray *); // // Extract operators for C++ types // // bool operator >> (short &); bool operator >> (DevLong &); bool operator >> (double &); bool operator >> (string&); bool operator >> (float &); bool operator >> (bool &); bool operator >> (unsigned short &); bool operator >> (unsigned char &); bool operator >> (DevLong64 &); bool operator >> (DevULong &); bool operator >> (DevULong64 &); bool operator >> (DevState &); bool operator >> (DevEncoded &); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (vector&); bool operator >> (DevVarShortArray* &datum); bool operator >> (DevVarLongArray* &datum); bool operator >> (DevVarDoubleArray* &datum); bool operator >> (DevVarStringArray* &datum); bool operator >> (DevVarFloatArray* &datum); bool operator >> (DevVarBooleanArray* &datum); bool operator >> (DevVarUShortArray* &datum); bool operator >> (DevVarCharArray* &datum); bool operator >> (DevVarLong64Array * &datum); bool operator >> (DevVarULongArray * &datum); bool operator >> (DevVarULong64Array * &datum); bool operator >> (DevVarStateArray * &datum); bool operator >> (DevVarEncodedArray *&datum); // // Extract_xxx methods // // bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (vector&); bool extract_read (string &,vector &); // bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (vector&); bool extract_set (string &,vector &); // bool extract(const char *&,unsigned char *&,unsigned int &); bool extract(char *&,unsigned char *&,unsigned int &); // Deprecated. For compatibility purpose bool extract(string &,vector &); ///@publicsection /**@name Exception and error related methods */ //@{ /** * Set exception flag * * Is a method which allows the user to switch on/off exception throwing when trying to extract data from a * DeviceAttribute object. The following flags are supported : * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDbDatum) if user tries to extract * data from an empty DeviceAttribute object. By default, this flag is set * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion. By default, this flag * is not set * @li @b failed_flag - throw an exception when the user try to extract data from the DeviceAttribute object and * an error was reported by the server when the user try to read the attribute. The type of the exception * thrown is the type of the error reported by the server. By default, this flag is set. * @li @b unknown_format_flag - throw an exception when the user try to get the attribute data format from * the DeviceAttribute object when this information is not yet available. This information is available * only after the read_attribute call has been sucessfully executed. The type of the exception thrown is * WrongData exception (reason = API_EmptyDeviceAttribute). By default, this flag is not set. * * @param [in] fl The exception flag */ void exceptions(bitset fl) {exceptions_flags = fl;} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * DeviceAttribute da; * * bitset bs = da.exceptions(); * cout << "bs = " << bs << endl; * * da.set_exceptions(DeviceAttribute::wrongtype_flag); * bs = da.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return exceptions_flags;} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(except_flags fl) {exceptions_flags.reset((size_t)fl);} /** * Set one exception flag * * Sets one exception flag. * The following is an example of how to use this exceptions related methods * @code * DeviceAttribute da = dev.read_attribute("MyAttr"); * da.set_exceptions(DeviceAttribute::wrongtype_flag); * * DevLong dl; * try * { * da >> dl; * } * catch (DevFailed &e) * { * .... * @endcode * There is another usage example in the DeviceAttribute::exceptions() method documentation. * @param [in] fl The exception flag */ void set_exceptions(except_flags fl) {exceptions_flags.set((size_t)fl);} /** * Get instance extraction state * * Allow the user to find out what was the reason of extraction from DeviceAttribute failure. This * method has to be used when exceptions are disabled. * Here is an example of how method state() could be used * @code * DeviceAttribute da = .... * * bitset bs; * da.exceptions(bs); * * DevLong dl; * if ((da >> dl) == false) * { * bitset bs_err = da.state(); * if (bs_err.test(DeviceAttribute::isempty_flag) == true) * ..... * } * @endcode * * @return The error bit set. */ bitset state() {return ext->ext_state;} /** * Check if the call failed * * Returns a boolean set to true if the server report an error when the attribute was read. * * @return A boolean set to true if the call failed */ bool has_failed() {DevErrorList *tmp;if ((tmp=err_list.operator->())==NULL)return false; else{if (tmp->length() != 0)return true;else return false;}} /** * Get the error stack * * Returns the error stack reported by the server when the attribute was read. * The following is an example of the three available ways to get data out of a DeviceAttribute object * @code * DeviceAttribute da; * vector attr_data; * * try * { * da = device->read_attribute("Attr"); * da >> attr_data; * } * catch (DevFailed &e) * { * .... * } * * ------------------------------------------------------------------------ * * DeviceAttribute da; * vector attr_data; * * da.reset_exceptions(DeviceAttribute::failed_flag); * * try * { * da = device->read_attribute("Attr"); * } * catch (DevFailed &e) * { * ..... * } * * if (!(da >> attr_data)) * { * DevErrorList &err = da.get_err_stack(); * ..... * } * else * { * ..... * } * * ---------------------------------------------------------------------- * * DeviceAttribute da; * vector attr_data; * * try * { * da = device->read_attribute("Attr"); * } * catch (DevFailed &e) * { * ...... * } * * if (da.has_failed()) * { * DevErrorList &err = da.get_err_stack(); * .... * } * else * { * da >> attr_data; * } * @endcode * The first way uses the default behaviour of the DeviceAttribute * object which is to throw an exception when the user try to extract data when the server reports an error * when the attribute was read. In the second way, the DeviceAttribute object * now does not throw "DevFailed" exception any more and the return value of the extractor operator is checked. * IN the last case, the attribute data validity is checked before * trying to extract them. * * @return The error stack */ const DevErrorList &get_err_stack() {return err_list.in();} //@} /**@name Miscellaneous methods */ //@{ /** * Check is the instance is empty * * is_empty() is a boolean method which returns true or false depending on whether the DeviceAttribute * object contains data or not. Note that by default, a DeviceAttribute object throws exception if it is empty * (See DeviceAttribute::exceptions() method). If you want to use this method, you have to change this * default behavior. It can be used to test whether the DeviceAttribute has been initialized or not * e.g. * @code * string parity; * DeviceAttribute sl_parity = my_device->read_attribute("parity"); * sl_parity.reset_exceptions(DeviceAttribute::isempty_flag); * * if (! sl_parity.is_empty()) * { * sl_parity >> parity; * } * else * { * cout << " no parity attribute defined for serial line !" << endl; * } * @endcode * * @return Boolean set to true if the instance is empty * @exception WrongData if requested */ bool is_empty(); /** * Returns the name of the attribute * * Returns the name of the attribute * * @return The attribute name */ string &get_name() {return name;} /** * Set attribute name * * Set attribute name * * @param na The attribute name */ void set_name(string &na) {name = na;} /** * Set attribute name * * Set attribute name * * @param na The attribute name */ void set_name(const char *na) {string str(na);name = str;} /** * Get attribute X dimension * * Returns the attribute read x dimension * * @return The attribute X dimension */ int get_dim_x() {return dim_x;} /** * Get attribute Y dimension * * Returns the attribute read y dimension * * @return The attribute Y dimension */ int get_dim_y() {return dim_y;} /** * Get the attribute write X dimension * * Returns the attribute write x dimension * * @return The attribute write X dimension */ int get_written_dim_x() {return w_dim_x;} /** * Get the attribute write Y dimension * * Returns the attribute write y dimension * * @return The attribute write Y dimension */ int get_written_dim_y() {return w_dim_y;} /** * Get the attribute read dimensions * * Returns the attribute read dimensions * * @return The attribute read dimensions */ AttributeDimension get_r_dimension(); /** * Get the attribute write dimensions * * Returns the attribute write dimensions * * @return The attribute write dimensions */ AttributeDimension get_w_dimension(); /** * Get the number of read value * * Returns the number of read values * * @return The read value number */ long get_nb_read(); /** * Get the number of written value * * Returns the number of written values. Here is an example of these last methods usage. * @code * DeviceAttribute da; * vector attr_data; * * try * { * da = device->read_attribute("Attr"); * da >> attr_data; * } * catch (DevFailed &e) * { * .... * } * * long read = da.get_nb_read(); * long written = da.get_nb_written(); * * for (long i = 0;i < read;i++) * cout << "Read value " << i+1 << " = " << attr_data[i] << endl; * * for (long j = 0; j < written;j++) * cout << "Last written value " << j+1 << " = " << attr_data[j + read] << endl; * @endcode * * @return The read value number */ long get_nb_written(); /** * Get attribute quality factor * * Returns the quality of the attribute: an enumerate type which can be one of: * @li ATTR_VALID * @li ATTR_INVALID * @li ATTR_ALARM * @li ATTR_CHANGING * @li ATTR_WARNING * * @return The attribute quality */ AttrQuality &get_quality() {return quality;} /** * Get attribute data type * * Returns the type of the attribute data. * * @return The attribute data type */ int get_type(); /** * Get attribute data format * * Returns the attribute data format. Note that this information is valid only after the call to the device has * been executed. Otherwise the FMT_UNKNOWN value of the AttrDataFormat enumeration is returned or * an exception is thrown according to the object exception flags. * * @return The attribute data format */ AttrDataFormat get_data_format(); /** * Get attribute read date * * Returns a reference to the time when the attribute was read in server * * @return The attribute read date */ TimeVal &get_date() {return time;} //@} ///@privatesection friend ostream &operator<<(ostream &,DeviceAttribute &); protected : ///@privatesection bitset exceptions_flags; void del_mem(int); bool check_for_data(); bool check_wrong_type_exception(); int check_set_value_size(int seq_length); class DeviceAttributeExt { public: DeviceAttributeExt() {}; DeviceAttributeExt & operator=(const DeviceAttributeExt &); bitset ext_state; void deep_copy(const DeviceAttributeExt &); }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DeviceAttributeExt *ext; // Class extension #endif }; #endif /* _DEVICEATTRIBUTE_H */ tango-9.2.5a/lib/cpp/client/DevicePipe.h0000644023471100065110000013477013034744772014751 00000000000000//=================================================================================================================== // // DevicePipe.h - include file for TANGO device api class DevicePipe // // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29869 $ // //=================================================================================================================== #ifndef _DEVICEPIPE_H #define _DEVICEPIPE_H /** * Fundamental type for extracting data from a device pipe blob * * This is the fundamental type for extracting data from a device pipe blob * * $Author: taurel $ * $Revision: 29869 $ * * @headerfile tango.h * @ingroup Client */ template struct DataElement { /** * Create a DataElement object. * * Create a DataElement object for device pipe blob extraction * * @param [in] name The data element name * @param [in] value The data element value */ DataElement(const string &name,T value); /** * Create a DataElement object. * * Create a DataElement object for device pipe blob extraction * * @param [in] name The data element name */ DataElement(const string &name); /** * Create a DataElement object. * * Create a DataElement object for device pipe blob extraction. Usefull for extraction into TANGO CORBA * sequence. See DevicePipeBlob extraction method * * @param [in] value The data element value */ DataElement(T value); DataElement(); string name; ///< The data element name T value; ///< The data element value }; template DataElement::DataElement(const string &_na,T _val):name(_na),value(_val) { } template DataElement::DataElement(const string &_na):name(_na) { } template DataElement::DataElement(T _val):value(_val) { } template DataElement::DataElement() { } /** * A device pipe blob * * A device pipe blob. A blob is used to pack data to be sent through device pipe * * $Author: taurel $ * $Revision: 29869 $ * * @headerfile tango.h * @ingroup Client */ class DevicePipeBlob { public: ///@privatesection enum except_flags { isempty_flag, wrongtype_flag, notenoughde_flag, blobdenamenotset_flag, mixing_flag, numFlags }; ///@publicsection /**@name Constructors */ //@{ /** * Create a DevicePipeBlob object. * * Default constructor. * */ DevicePipeBlob(); /** * Create a DevicePipeBlob object with name * * Create one instance of the DevicePipeBlob class and set its name * * @param [in] blob_name The blob name */ DevicePipeBlob(const string &blob_name); //@} /**@name Get/Set methods */ //@{ /** * Set blob name * * Set the blob name * * @param [in] blob_name The blob name */ void set_name(const string &blob_name) {name=blob_name;} /** * Get blob name * * Get the blob name * * @return The blob name */ const string &get_name() {return name;} //@} /**@name Inserting data into a DevicePipeBlob */ //@{ /** * Insert data into a data blob * * According to the data to be inserted into the blob data element, several kinds of insetor methods have been * implemented. You can insert data from: * @li Scalar data type * @li vector * @li TANGO CORBA sequence types (by reference) * @li TANGO CORBA sequence types (by pointer) * @li DataElement with T being scalar data type * @li DataElement with T being vector * @li DataElement with T being TANGO CORBA sequence type (by reference) * @li DataElement with T being TANGO CORBA sequence type (by pointer) * * When inserting data using a DataElement instance, the data element name is also set. * For insertion from TANGO CORBA sequence type pointer, the insertion method consumes the * memory allocated to store the data and it will be freed by the Tango layer. * * Insert operators for the following scalar C++ types (and DataElement) * @li bool * @li short * @li DevLong * @li DevLong64 * @li float * @li double * @li unsigned char * @li unsigned short * @li DevULong * @li DevULong64 * @li DevString * @li string * @li DevState * @li DevEncoded * * Insert operators for the following C++ vector types (and DataElement) * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Insert operators for the following CORBA sequence types (and DataElement): * @li DevVarBooleanArray & * @li DevVarShortArray & * @li DevVarLongArray & * @li DevVarLong64Array & * @li DevVarFloatArray & * @li DevVarDoubleArray & * @li DevVarUCharArray & * @li DevVarUShortArray & * @li DevVarULongArray & * @li DevVarULong64Array & * @li DevVarStringArray & * @li DevVarStateArray & * * Insert operators for the following CORBA sequence types with memory consumption (and DataElement): * @li DevVarBooleanArray * * @li DevVarShortArray * * @li DevVarLongArray * * @li DevVarLong64Array * * @li DevVarFloatArray * * @li DevVarDoubleArray * * @li DevVarUCharArray * * @li DevVarUShortArray * * @li DevVarULongArray * * @li DevVarULong64Array * * @li DevVarStringArray * * @li DevVarStateArray * * * Here is an example of inserting data into a DevicePipeBlob instance. We insert * 3 data element into the pipe blob with a DevLong, a vector of doubles and finally an array of 100 unsigned short * @code * DevicePipeBlob dpb("MyBlob"); * * vector de_names = {"FirstDE","SecondDE","ThirdDE"}; * dpb.set_data_elt_names(de_names); * * DevLong dl = 666; * vector v_db = {1.11,2.22}; * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another * * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); * * try * { * dpb << dl << v_db << dvush; * } * catch (DevFailed &e) * { * cout << "DevicePipeBlob insertion failed" << endl; * .... * } * * @endcode * The same example of inserting data into a DevicePipeBlob instance when we want to set the data element name. * @code * DevicePipeBlob dpb("MyBlob"); * * DataElement de_dl("FirstDE",666); * * vector v_db = {1.11,2.22}; * DataElement > de_v_db("SecondDE",v_db); * * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); * DataElement de_dvush("ThirdDE",array); * * try * { * dpb << de_dl << de_v_db << de_dvush; * } * catch (DevFailed &e) * { * cout << "DevicePipeBlob insertion failed" << endl; * .... * } * * ... * @endcode * It is also possible to do the insertion in a third way * @code * DevicePipeBlob dpb("MyBlob"); * * vector de_names{"FirstDE","SecondDE","ThirdDE"}; * dpb.set_data_elt_names(de_names); * * DevLong dl = 666; * vector v_db = {1.11,2.22}; * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another * * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); * * dpb["FirstDE"] << dl; * dpb["SecondDE"] << v_db; * dpb["ThirdDE"] << dvush; * * @endcode * * @param [in] datum The data to be inserted into the DevicePipeBlob * @exception WrongData if requested */ DevicePipeBlob & operator << (short &datum); /** * Set blob data element number * * Set the blob data element number * * @param [in] nb The blob data element number */ void set_data_elt_nb(size_t nb); /** * Set blob data element number and names * * Set the blob data element number and names. The data element number is the number of names in the input * parameter. * * @param [in] names The blob data element names */ void set_data_elt_names(vector &names); //@} /**@name Extracting data from a DevicePipeBlob */ //@{ /** * Extract data from a data blob * * According to the data inside blob data element, several kinds of extractor methods have been implemented. You * can extract data into: * @li Scalar data type * @li vector * @li TANGO CORBA sequence types * @li DataElement with T being scalar data type * @li DataElement with T being vector * @li DataElement with T being TANGO CORBA sequence type * * When extracting data using a DataElement instance, the data element name is also returned. * For extraction into C++ vector, data are copied into the vector. It is not the case for extraction into TANGO * CORBA sequence type. For extraction into TANGO CORBA sequence types, the extraction method consumes the * memory allocated to store the data and it is the caller responsibility to delete this memory. * * Extract operators for the following scalar C++ types (and DataElement) * @li bool * @li short * @li DevLong * @li DevLong64 * @li float * @li double * @li unsigned char * @li unsigned short * @li DevULong * @li DevULong64 * @li string * @li DevState * @li DevEncoded * * Extract operators for the following C++ vector types (and DataElement) * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * @li vector * * Extract operators for the following CORBA sequence types with memory consumption (and DataElement): * @li DevVarBooleanArray * * @li DevVarShortArray * * @li DevVarLongArray * * @li DevVarLong64Array * * @li DevVarFloatArray * * @li DevVarDoubleArray * * @li DevVarUCharArray * * @li DevVarUShortArray * * @li DevVarULongArray * * @li DevVarULong64Array * * @li DevVarStringArray * * @li DevVarStateArray * * * Here is an example of extracting data from a DevicePipeBlob instance. We know that the DevicePipeBlob contains * 3 data element with a DevLong, an array of doubles and finally an array of unsigned short * @code * DevicePipeBlob dpb = ..... * * DevLong dl; * vector v_db; * DevVarUShortArray *dvush = new DevVarUShortArray(); * * try * { * dpb >> dl >> v_db >> dvush; * } * catch (DevFailed &e) * { * cout << "DevicePipeBlob extraction failed" << endl; * .... * } * * delete dvush; * @endcode * The same example of extracting data from a DevicePipeBlob instance when we want to retrieve the data element name. * @code * DevicePipeBlob dpb = ..... * * DataElement de_dl; * DataElement > de_v_db; * DataElement de_dvush(new DevVarUShortArray()); * * try * { * dpb >> de_dl >> de_v_db >> de_dvush; * } * catch (DevFailed &e) * { * cout << "DevicePipeBlob extraction failed" << endl; * .... * } * * cout << "Data element name = " << de_dl.name << " - Value = " << de_dl.value << endl; * ... * delete de_dvush.value; * @endcode * It is also possible to do the extraction in a generic way * @code * DevicePipeBlob dpb = ..... * * size_t nb_de = dpb.get_data_elt_nb(); * for (size_t loop = 0;loop < nb;loop++) * { * int data_type = dpb.get_data_elt_type(loop); * string de_name = dpb.get_data_elt_name(loop); * switch(data_type) * { * case DEV_LONG: * { * DevLong lg; * dpb >> lg; * } * break; * * case DEVVAR_DOUBLEARRAY: * { * vector v_db; * dpb >> v_db; * } * break; * .... * } * ... * } * @endcode * Note that instead of using DevLong and vector data, the extraction can be done using DataElement * instances. In this case, the call to the get_data_elt_name() method becomes useless. * * @param [out] datum The blob data * @exception WrongData if requested */ DevicePipeBlob & operator >> (short &datum); /** * Get blob data element number * * Get the blob data element number * * @return The blob data element number */ size_t get_data_elt_nb(); /** * Get blob data elements name * * Get the blob data elements name * * @return The blob data elements name */ vector get_data_elt_names(); /** * Get blob data element name * * Get the blob data element name for a single data element * * @param [in] ind The data element index within the blob * @return The blob data element name */ string get_data_elt_name(size_t ind); /** * Get blob data element value type * * Get the blob data element value type for a single data element * * @param [in] ind The data element index within the blob * @return The blob data element value type */ int get_data_elt_type(size_t ind); //@} /**@name Exception and error related methods methods */ //@{ /** * Set exception flag * * It's a method which allows the user to switch on/off exception throwing when trying to extract data from a * DevicePipeBlob object. The following flags are supported : * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user * tries to extract data from one empty blob data element. By default, this flag * is set * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion. By default, this flag * is set * @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user * tries to extract data from a DevicePipeBlob for a data element which does not exist. By default, this flag * is set * @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to * insert data into the blob while the name or number of data element has not been set with methods * set_data_elt_nb() or set_data_elt_names() * @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix * insertion/extraction method (<< or >>) with operator[] * * @param [in] fl The exception flag */ void exceptions(bitset fl) {exceptions_flags = fl;} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * DevicePipeBlob dpb; * * bitset bs = dpb.exceptions(); * cout << "bs = " << bs << endl; * * dpb.set_exceptions(DevicePipeBlob::wrongtype_flag); * bs = dpb.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return exceptions_flags;} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(except_flags fl) {exceptions_flags.reset((size_t)fl);} /** * Set one exception flag * * Sets one exception flag. See DevicePipeBlob::exceptions() for a usage example. * * @param [in] fl The exception flag */ void set_exceptions(except_flags fl) {exceptions_flags.set((size_t)fl);} /** * Check insertion/extraction success * * Allow the user to check if insertion/extraction into/from DevicePipeBlob instance was successfull. This * method has to be used when exceptions are disabled. * * @return True if insertion/extraction has failed */ bool has_failed(); /** * Get instance insertion/extraction state * * Allow the user to find out what was the reason of insertion/extraction into/from DevicePipeBlob failure. This * method has to be used when exceptions are disabled. * Here is an example of how methods has_failed() and state() could be used * @code * DevicePipeBlob dpb = .... * * bitset bs; * bs.reset(); * dpb.exceptions(bs); * * DevLong dl; * dpb >> dl; * * if (dpb.has_failed() == true) * { * bitset bs_err = dpb.state(); * if (bs_err.test(DevicePipeBlob::isempty_flag) == true) * ..... * } * @endcode * * @return The error bit set. */ bitset state() {return ext_state;} //@} ///@privatesection ~DevicePipeBlob(); DevicePipeBlob(const DevicePipeBlob &); DevicePipeBlob & operator=(const DevicePipeBlob &); #ifdef HAS_RVALUE DevicePipeBlob(DevicePipeBlob &&); DevicePipeBlob & operator=(DevicePipeBlob &&); #endif DevicePipeBlob & operator << (DevBoolean &); // DevicePipeBlob & operator << (short &); DevicePipeBlob & operator << (DevLong &); DevicePipeBlob & operator << (DevLong64 &); DevicePipeBlob & operator << (float &); DevicePipeBlob & operator << (double &); DevicePipeBlob & operator << (DevUChar &); DevicePipeBlob & operator << (DevUShort &); DevicePipeBlob & operator << (DevULong &); DevicePipeBlob & operator << (DevULong64 &); DevicePipeBlob & operator << (DevString &); DevicePipeBlob & operator << (DevState &); DevicePipeBlob & operator << (DevEncoded &); DevicePipeBlob & operator << (const string &); DevicePipeBlob & operator << (DevicePipeBlob &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (vector &); DevicePipeBlob & operator << (DevVarBooleanArray &); DevicePipeBlob & operator << (DevVarShortArray &); DevicePipeBlob & operator << (DevVarLongArray &); DevicePipeBlob & operator << (DevVarLong64Array &); DevicePipeBlob & operator << (DevVarFloatArray &); DevicePipeBlob & operator << (DevVarDoubleArray &); DevicePipeBlob & operator << (DevVarUCharArray &); DevicePipeBlob & operator << (DevVarUShortArray &); DevicePipeBlob & operator << (DevVarULongArray &); DevicePipeBlob & operator << (DevVarULong64Array &); DevicePipeBlob & operator << (DevVarStringArray &); DevicePipeBlob & operator << (DevVarStateArray &); DevicePipeBlob & operator << (DevVarEncodedArray &); DevicePipeBlob & operator << (DevVarBooleanArray *); DevicePipeBlob & operator << (DevVarShortArray *); DevicePipeBlob & operator << (DevVarLongArray *); DevicePipeBlob & operator << (DevVarLong64Array *); DevicePipeBlob & operator << (DevVarFloatArray *); DevicePipeBlob & operator << (DevVarDoubleArray *); DevicePipeBlob & operator << (DevVarUCharArray *); DevicePipeBlob & operator << (DevVarUShortArray *); DevicePipeBlob & operator << (DevVarULongArray *); DevicePipeBlob & operator << (DevVarULong64Array *); DevicePipeBlob & operator << (DevVarStringArray *); DevicePipeBlob & operator << (DevVarStateArray *); DevicePipeBlob & operator << (DevVarEncodedArray *); //------------------------------------------------------------------------------------------------- DevicePipeBlob & operator >> (DevBoolean &); // DevicePipeBlob & operator >> (short &); DevicePipeBlob & operator >> (DevLong &); DevicePipeBlob & operator >> (DevLong64 &); DevicePipeBlob & operator >> (float &); DevicePipeBlob & operator >> (double &); DevicePipeBlob & operator >> (DevUChar &); DevicePipeBlob & operator >> (DevUShort &); DevicePipeBlob & operator >> (DevULong &); DevicePipeBlob & operator >> (DevULong64 &); DevicePipeBlob & operator >> (DevString &); DevicePipeBlob & operator >> (DevState &); DevicePipeBlob & operator >> (DevEncoded &); DevicePipeBlob & operator >> (string &); DevicePipeBlob & operator >> (DevicePipeBlob &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (vector &); // DevicePipeBlob & operator >> (vector &); DevicePipeBlob & operator >> (DevVarBooleanArray *); DevicePipeBlob & operator >> (DevVarShortArray *); DevicePipeBlob & operator >> (DevVarLongArray *); DevicePipeBlob & operator >> (DevVarLong64Array *); DevicePipeBlob & operator >> (DevVarFloatArray *); DevicePipeBlob & operator >> (DevVarDoubleArray *); DevicePipeBlob & operator >> (DevVarUCharArray *); DevicePipeBlob & operator >> (DevVarUShortArray *); DevicePipeBlob & operator >> (DevVarULongArray *); DevicePipeBlob & operator >> (DevVarULong64Array *); DevicePipeBlob & operator >> (DevVarStringArray *); DevicePipeBlob & operator >> (DevVarStateArray *); DevicePipeBlob & operator >> (DevVarEncodedArray *); DevicePipeBlob &operator[](const string &); const char *get_current_delt_name() {return (*extract_elt_array)[extract_ctr].name.in();} void set_current_delt_name(const string &); size_t get_extract_ind_from_name(const string &); size_t get_insert_ind_from_name(const string &); void reset_insert_ctr() {insert_ctr=0;} DevVarPipeDataEltArray *get_insert_data() {return insert_elt_array;} const DevVarPipeDataEltArray *get_extract_data() {return extract_elt_array;} void set_extract_data(const DevVarPipeDataEltArray *_ptr) {extract_elt_array=_ptr;} void reset_insert_data_ptr() {insert_elt_array=Tango_nullptr;} void reset_extract_ctr() {extract_ctr=0;} void set_extract_delete(bool _b) {extract_delete=_b;} void print(ostream &,int,bool); protected: ///@privatesection void throw_type_except(const string &,const string &); void throw_too_many(const string &,bool); void throw_is_empty(const string &); void throw_name_not_set(const string &); void throw_mixing(const string &); private: string name; // The blob name bitset exceptions_flags; // Exception flag bitset ext_state; // Extraction state bool failed; // Failed flag DevVarPipeDataEltArray *insert_elt_array; // Ptr for data to be inserted (client write/Server read) int insert_ctr; // Ctr for inserting data elt int insert_ind; const DevVarPipeDataEltArray *extract_elt_array; // Ptr for data to be extracted (client read/Server write) int extract_ctr; // Ctr for extracting data elt bool extract_delete; // Flag to force extract ptr delete int extract_ind; class DevicePipeBlobExt { public: DevicePipeBlobExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DevicePipeBlobExt *ext; // Class extension #endif }; /**************************************************************************************** * * * The DevicePipe class * * -------------------- * * * ***************************************************************************************/ /** * Fundamental type for sending/receiving data from device pipes * * This is the fundamental type for sending/receiving data to/from device pipe. * * $Author: taurel $ * $Revision: 29869 $ * * @headerfile tango.h * @ingroup Client */ class DevicePipe { public : ///@publicsection /**@name Constructors */ //@{ /** * Create a DevicePipe object. * * Default constructor. The instance is empty * */ DevicePipe(); /** * Create a DevicePipe object with name * * Create one instance of the DevicePipe class and set its name * * @param [in] pipe_name The pipe name */ DevicePipe(const string &pipe_name); /** * Create a DevicePipe object with name and root blob name. * * Create one instance of the DevicePipe class and set its name and its root blob name * * @param [in] pipe_name The pipe name * @param [in] root_blob_name The root blob name */ DevicePipe(const string &pipe_name,const string &root_blob_name); //@} /**@name Get/Set methods */ //@{ /** * Set pipe name * * Set the device pipe name * * @param [in] pipe_name The pipe name */ void set_name(const string &pipe_name) {name=pipe_name;} /** * Get pipe name * * Set the device pipe name * * @return The pipe name */ const string &get_name() {return name;} /** * Set root blob name * * Set the root blob name * * @param [in] root_blob_name The root blob name */ void set_root_blob_name(const string &root_blob_name) {the_root_blob.set_name(root_blob_name);} /** * Get root blob name * * Get the root blob name * * @return The root blob name */ const string &get_root_blob_name() {return the_root_blob.get_name();} //@} /**@name Inserting data into a DevicePipe */ //@{ #ifdef GEN_DOC /** * Insert data into a device pipe * * Inserting data into a DevicePipe instance is simlar to inserting data into a DevicePipeBlob class instance. * See doc of DevicePipeBlob class insertion methods (DevicePipeBlob::operator<<) to get a complete documentation on * how to insert data into a DevicePipe * * @param [in] datum The data to be inserted into the DevicePipe * @exception WrongData if requested */ DevicePipe & operator << (short &datum); #endif /** * Set blob data element number * * Set the blob data element number * * @param [in] nb The blob data element number */ void set_data_elt_nb(size_t nb) {the_root_blob.set_data_elt_nb(nb);} /** * Set blob data element number and names * * Set the blob data element number and names. The data element number is the number of names in the input * parameter. * * @param [in] names The blob data element names */ void set_data_elt_names(vector &names) {the_root_blob.set_data_elt_names(names);} //@} /**@name Extracting data from a DevicePipe */ //@{ #ifdef GEN_DOC /** * Extract data from a device pipe * * Extracting data from a DevicePipe instance is simlar to extracting data from a DevicePipeBlob class instance. * See doc of DevicePipeBlob class extraction methods (DevicePipeBlob::operator>>) to get a complete documentation on * how to extract data from a DevicePipe * * @param [in] datum The pipe data * @exception WrongData if requested */ DevicePipe & operator >> (short &datum); #endif /** * Get root blob data element number * * Get the root blob data element number * * @return The root blob data element number */ size_t get_data_elt_nb() {return the_root_blob.get_data_elt_nb();} /** * Get root blob data elements name * * Get the root blob data elements name * * @return The root blob data elements name */ vector get_data_elt_names() {return the_root_blob.get_data_elt_names();} /** * Get root blob data element name * * Get root blob data element name for a single data element * * @param [in] ind The data element index within the root blob * @return The root blob data element name */ string get_data_elt_name(size_t ind) {return the_root_blob.get_data_elt_name(ind);} /** * Get root blob data element value type * * Get root blob data element value type for a single data element * * @param [in] ind The data element index within the root blob * @return The root blob data element value type */ int get_data_elt_type(size_t ind) {return the_root_blob.get_data_elt_type(ind);} //@} /**@name Exception and error related methods methods */ //@{ /** * Set exception flag * * It's a method which allows the user to switch on/off exception throwing when trying to insert/extract data from a * DevicePipe object. The following flags are supported : * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user * tries to extract data from one empty pipe data element. By default, this flag * is set * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user * tries to extract data with a type different than the type used for insertion. By default, this flag * is set * @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user * tries to extract data from a DevicePipe for a data element which does not exist. By default, this flag * is set * @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to * insert data into the blob while the name or number of data element has not been set with methods * set_data_elt_nb() or set_data_elt_names() * @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix * insertion/extraction method (<< or >>) with operator[] * * @param [in] fl The exception flag */ void exceptions(bitset fl) {the_root_blob.exceptions(fl);} /** * Get exception flag * * Returns the whole exception flags. * The following is an example of how to use these exceptions related methods * @code * DevicePipe dp; * * bitset bs = dp.exceptions(); * cout << "bs = " << bs << endl; * * dp.set_exceptions(DevicePipeBlob::wrongtype_flag); * bs = dp.exceptions(); * * cout << "bs = " << bs << endl; * @endcode * * @return The exception flag */ bitset exceptions() {return the_root_blob.exceptions();} /** * Reset one exception flag * * Resets one exception flag * * @param [in] fl The exception flag */ void reset_exceptions(DevicePipeBlob::except_flags fl) {the_root_blob.reset_exceptions(fl);} /** * Set one exception flag * * Sets one exception flag. See DevicePipe::exceptions() for a usage example. * * @param [in] fl The exception flag */ void set_exceptions(DevicePipeBlob::except_flags fl) {the_root_blob.set_exceptions(fl);} /** * Check insertion/extraction success * * Allow the user to check if insertion/extraction into/from DevicePipe instance was successfull. This * method has to be used when exceptions are disabled. * * @return True if insertion/extraction has failed */ bool has_failed() {return the_root_blob.has_failed();} /** * Get instance insertion/extraction state * * Allow the user to find out what was the reason of insertion/extraction into/from DevicePipe failure. This * method has to be used when exceptions are disabled. * Here is an example of how methods has_failed() and state() could be used * @code * DevicePipe dpb = .... * * bitset bs; * bs.reset(); * dpb.exceptions(bs); * * DevLong dl; * dpb >> dl; * * if (dpb.has_failed() == true) * { * bitset bs_err = dpb.state(); * if (dpb.test(DevicePipeBlob::isempty_flag) == true) * ..... * } * @endcode * * @return The error bit set. */ bitset state() {return the_root_blob.state();} //@} /** * Print a DevicePipe instance * * Is an utility function to easily print the contents of a DevicePipe object. This function knows all types * which could be inserted in a DevicePipe object and print them accordingly. A special string is printed if * the DevicePipe object is empty * @code * DeviceProxy *dev = new DeviceProxy(“...â€); * DevicePipe out; * * out = dev->read_pipe(“MyPipeâ€); * cout << “Pipe content: †<< out << endl; * @endcode * * @param [in] str The printing stream * @param [in] dd The instance to be printed */ friend ostream &operator<<(ostream &str,DevicePipe &dd); public : ///@privatesection DevicePipe(const DevicePipe &); DevicePipe & operator=(const DevicePipe &); #ifdef HAS_RVALUE DevicePipe(DevicePipe &&); DevicePipe & operator=(DevicePipe &&); #endif ~DevicePipe(); void set_time(TimeVal &_ti) {time=_ti;} DevicePipeBlob &get_root_blob() {return the_root_blob;} DevicePipe &operator[](const string &); private: DevicePipeBlob the_root_blob; // Root blob string name; // Pipe name TimeVal time; // When pipe has been read class DevicePipeExt { public: DevicePipeExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else DevicePipeExt *ext; // Class extension #endif }; /**************************************************************************************** * * * Some DevicePipe, DevicePipeBlob and DataElement helper functions * * ---------------------------------------------------------------- * * * ***************************************************************************************/ DevicePipe &operator>>(DevicePipe &_dp,char *&datum); // // For DataElement printing // template ostream &operator<<(ostream &,DataElement &); template ostream &operator<<(ostream &,DataElement > &); template ostream &operator<<(ostream &,DataElement &); // // For DevicePipe insertion // template DevicePipe &operator<<(DevicePipe &,T &); template DevicePipe &operator<<(DevicePipe &,T *); template DevicePipe &operator<<(DevicePipe &, DataElement &); // // For DevicePipe extraction // template DevicePipe &operator>>(DevicePipe &,T &); template DevicePipe &operator>>(DevicePipe &,T *); template DevicePipe &operator>>(DevicePipe &, DataElement &); // // For DevicePipeBlob insertion // template DevicePipeBlob &operator<<(DevicePipeBlob &,T &); template DevicePipeBlob &operator<<(DevicePipeBlob &,T *); template DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement &); // // For DevicePipeBlob extraction // template DevicePipeBlob &operator>>(DevicePipeBlob &,T &); template DevicePipeBlob &operator>>(DevicePipeBlob &,T *); template DevicePipeBlob &operator>>(DevicePipeBlob &, DataElement &); /**************************************************************************************** * * * Some macros (shame on me, but I am too lazy) * * ------------------------------------------- * * * ***************************************************************************************/ // // A is the required value for the IDL enum descriminator // B is the IDL enum method to get data // C is data type name // #define EXTRACT_BASIC_TYPE(A,B,C) \ failed = false; \ ext_state.reset(); \ \ if (extract_elt_array == Tango_nullptr) \ ext_state.set(isempty_flag); \ else if (extract_ctr > (int)extract_elt_array->length() - 1) \ ext_state.set(notenoughde_flag); \ else if (extract_ctr == -1 && extract_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ int ind; \ if (extract_ind != -1) \ ind = extract_ind; \ else \ ind = extract_ctr; \ const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \ AttributeDataType adt = uni_ptr->_d(); \ if (adt != A) \ { \ if (adt == ATT_NO_DATA) \ { \ if ((*extract_elt_array)[ind].inner_blob.length() == 0) \ ext_state.set(isempty_flag); \ else \ ext_state.set(wrongtype_flag); \ } \ else \ ext_state.set(wrongtype_flag); \ } \ else \ { \ datum = (uni_ptr->B())[0]; \ if (extract_ind != -1) \ extract_ind = -1; \ else \ extract_ctr++; \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \ throw_is_empty("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator>>",true); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \ throw_type_except(C,"operator>>"); // // A is the required value for the IDL enum descriminator // B is the IDL enum method to get data // C is the CORBA sequence type name // D is data type name // #define EXTRACT_VECTOR_TYPE(A,B,C,D) \ failed = false; \ ext_state.reset(); \ \ if (extract_elt_array == Tango_nullptr) \ ext_state.set(isempty_flag); \ else if (extract_ctr > (int)extract_elt_array->length() - 1) \ ext_state.set(notenoughde_flag); \ else if (extract_ctr == -1 && extract_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ int ind; \ if (extract_ind != -1) \ ind = extract_ind; \ else \ ind = extract_ctr; \ const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \ AttributeDataType adt = uni_ptr->_d(); \ if (adt != A) \ { \ if (adt == ATT_NO_DATA) \ { \ if ((*extract_elt_array)[ind].inner_blob.length() == 0) \ ext_state.set(isempty_flag); \ else \ ext_state.set(wrongtype_flag); \ } \ else \ ext_state.set(wrongtype_flag); \ } \ else \ { \ const C &dvsa = uni_ptr->B(); \ datum << dvsa; \ if (extract_ind != -1) \ extract_ind = -1; \ else \ extract_ctr++; \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \ throw_is_empty("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator>>",true); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \ throw_type_except(D,"operator>>"); // // A is the required value for the IDL enum descriminator // B is the IDL enum method to get data // C is the CORBA sequence type name // D is data type name // #define EXTRACT_SEQ_PTR_TYPE(A,B,C,D) \ failed = false; \ ext_state.reset(); \ \ if (extract_elt_array == Tango_nullptr) \ ext_state.set(isempty_flag); \ else if (extract_ctr > (int)extract_elt_array->length() - 1) \ ext_state.set(notenoughde_flag); \ else if (extract_ctr == -1 && extract_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ int ind; \ if (extract_ind != -1) \ ind = extract_ind; \ else \ ind = extract_ctr; \ const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \ AttributeDataType adt = uni_ptr->_d(); \ if (adt != A) \ { \ if (adt == ATT_NO_DATA) \ { \ if ((*extract_elt_array)[ind].inner_blob.length() == 0) \ ext_state.set(isempty_flag); \ else \ ext_state.set(wrongtype_flag); \ } \ else \ ext_state.set(wrongtype_flag); \ } \ else \ { \ C &dvsa = const_cast(uni_ptr->B()); \ CORBA::Long max,len; \ max = dvsa.maximum(); \ len = dvsa.length(); \ datum->replace(max,len,dvsa.get_buffer((CORBA::Boolean)true),true); \ if (extract_ind != -1) \ extract_ind = -1; \ else \ extract_ctr++; \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \ throw_is_empty("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator>>",true); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \ throw_type_except(D,"operator>>"); // // A is the sequence CORBA name // B is the IDL enum method to set data // #define INSERT_BASIC_TYPE(A,B) \ failed = false; \ ext_state.reset(); \ \ if (insert_elt_array == Tango_nullptr) \ ext_state.set(blobdenamenotset_flag); \ else if (insert_ctr == -1 && insert_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ size_t nb_insert = insert_elt_array->length(); \ if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \ ext_state.set(notenoughde_flag); \ else \ { \ A dvsa; \ dvsa.length(1); \ dvsa[0] = datum; \ \ if (insert_ind != -1) \ { \ (*insert_elt_array)[insert_ind].value.B(dvsa); \ (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(SCALAR_PIPE); \ insert_ind = -1; \ } \ else \ { \ (*insert_elt_array)[insert_ctr].value.B(dvsa); \ (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(SCALAR_PIPE); \ insert_ctr++; \ } \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \ throw_name_not_set("operator<<"); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator<<",false); // // A is the sequence CORBA name // B is the IDL enum method to set data // #define INSERT_VECTOR_TYPE(A,B) \ failed = false; \ ext_state.reset(); \ \ if (insert_elt_array == Tango_nullptr) \ ext_state.set(blobdenamenotset_flag); \ else if (insert_ctr == -1 && insert_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ size_t nb_insert = insert_elt_array->length(); \ if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \ ext_state.set(notenoughde_flag); \ else \ { \ A dvsa; \ if (insert_ind != -1) \ { \ (*insert_elt_array)[insert_ind].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \ dvsb.replace(datum.size(),datum.size(),&datum[0],false); \ (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ind = -1; \ } \ else \ { \ (*insert_elt_array)[insert_ctr].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \ dvsb.replace(datum.size(),datum.size(),&datum[0],false); \ (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ctr++; \ } \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \ throw_name_not_set("operator<<"); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator<<",false); // // A is the sequence CORBA name // B is the IDL enum method to set data // #define INSERT_SEQ_TYPE(A,B) \ failed = false; \ ext_state.reset(); \ \ if (insert_elt_array == Tango_nullptr) \ ext_state.set(blobdenamenotset_flag); \ else if (insert_ctr == -1 && insert_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ size_t nb_insert = insert_elt_array->length(); \ if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \ ext_state.set(notenoughde_flag); \ else \ { \ CORBA::Long max,len; \ max = datum.maximum(); \ len = datum.length(); \ A dvsa; \ if (insert_ind != -1) \ { \ (*insert_elt_array)[insert_ind].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \ dvsb.replace(max,len,datum.get_buffer(),false); \ (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ind = -1; \ } \ else \ { \ (*insert_elt_array)[insert_ctr].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \ dvsb.replace(max,len,datum.get_buffer(),false); \ (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ctr++; \ } \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \ throw_name_not_set("operator<<"); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator<<",false); // // A is the sequence CORBA name // B is the IDL enum method to set data // #define INSERT_SEQ_PTR_TYPE(A,B) \ failed = false; \ ext_state.reset(); \ \ if (insert_elt_array == Tango_nullptr) \ ext_state.set(blobdenamenotset_flag); \ else if (insert_ctr == -1 && insert_ind == -1) \ ext_state.set(mixing_flag); \ else \ { \ size_t nb_insert = insert_elt_array->length(); \ if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \ ext_state.set(notenoughde_flag); \ else \ { \ A dvsa; \ CORBA::Long max,len; \ max = datum->maximum(); \ len = datum->length(); \ bool rel = datum->release(); \ if (rel == false) \ { \ datum->replace(max,len,datum->get_buffer(),true); \ } \ if (insert_ind != -1) \ { \ (*insert_elt_array)[insert_ind].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \ dvsb.replace(max,len,datum->get_buffer((CORBA::Boolean)true),true); \ (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ind = -1; \ } \ else \ {\ (*insert_elt_array)[insert_ctr].value.B(dvsa); \ A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \ dvsb.replace(max,len,datum->get_buffer((CORBA::Boolean)true),true); \ (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \ insert_ctr++; \ } \ \ delete datum; \ } \ } \ \ if (ext_state.any() == true) \ failed = true; \ \ if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \ throw_name_not_set("operator<<"); \ \ if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \ throw_mixing("operator>>"); \ \ if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \ throw_too_many("operator<<",false); #endif /* _DEVICEPIPE_H */ tango-9.2.5a/lib/cpp/client/Connection.h0000644023471100065110000005070013034744771015020 00000000000000////////////////////////////////////////////////////////////////// // // Connection.h - include file for TANGO class Connection // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 20437 $ // /////////////////////////////////////////////////////////////// #ifndef _CONNECTION_H #define _CONNECTION_H /**************************************************************************************** * * * The Connection class * * -------------------- * * * ***************************************************************************************/ /** * Base class for Tango device access * * Base class for Tango device access. This class is pure virtual and can be instanciated * as is. * * $Author: taurel $ * $Revision: 1 $ * * @ingroup Client * @headerfile tango.h */ class Connection { protected : ///@privatesection bool dbase_used; // Dev. with database bool from_env_var; // DB from TANGO_HOST string host; // DS host (if dbase_used=false) string port; // DS port (if dbase_used=false) int port_num; // DS port (as number) string db_host; // DB host string db_port; // DB port int db_port_num; // DB port (as number) string ior; long pasyn_ctr; long pasyn_cb_ctr; Tango::Device_var device; Tango::Device_2_var device_2; int timeout; int connection_state; int version; Tango::DevSource source; bool check_acc; AccessControlType access; virtual string get_corba_name(bool)=0; virtual string build_corba_name()=0; virtual int get_lock_ctr()=0; virtual void set_lock_ctr(int)=0; DeviceData redo_synch_cmd(TgRequest &); int get_env_var(const char *,string &); int get_env_var_from_file(string &,const char *,string &); void set_connection_state(int); void check_and_reconnect(); void check_and_reconnect(Tango::DevSource &); void check_and_reconnect(Tango::AccessControlType &); void check_and_reconnect(Tango::DevSource &,Tango::AccessControlType &); long add_asyn_request(CORBA::Request_ptr,TgRequest::ReqType); void remove_asyn_request(long); void add_asyn_cb_request(CORBA::Request_ptr,CallBack *,Connection *,TgRequest::ReqType); void remove_asyn_cb_request(Connection *,CORBA::Request_ptr); long get_pasyn_cb_ctr(); class ConnectionExt { public: ConnectionExt():has_alt_adr(false) {} ~ConnectionExt() {} ConnectionExt & operator=(const ConnectionExt &); bool has_alt_adr; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else ConnectionExt *ext; // Class extension #endif bool tr_reco; Tango::Device_3_var device_3; bool prev_failed; double prev_failed_t0; Tango::Device_4_var device_4; omni_mutex adm_dev_mutex; omni_mutex asyn_mutex; ReadersWritersLock con_to_mon; int user_connect_timeout; bool tango_host_localhost; Tango::Device_5_var device_5; public : ///@publicsection /**@name Miscellaneous methods */ //@{ /** * Set device timeout * * Set client side timeout for device in milliseconds. Any method which takes longer than this time to execute * will throw an exception. * * @param [in] timeout The timeout value in mS */ virtual void set_timeout_millis(int timeout); /** * Get device timeout * * Get the client side timeout in milliseconds. * * @return The device timeout (in mS) */ virtual int get_timeout_millis(); /** * Get device IDL version * * Get the version of the Tango Device IDL interface implemented by the device * * @return The device IDL version */ int get_idl_version() {return version;} /** * Get device source * * Get the device data source used by command_inout or read_attribute methods. The DevSource is an enumerated * type which can be one of {DEV, CACHE, CACHE_DEV}. See chapter on Advanced Feature in * Tango book * for all details regarding polling. * * @return The device source flag */ virtual Tango::DevSource get_source(); /** * Set device source * * Set the data source (device, polling buffer, polling buffer than device) for command_inout and read_attribute * methods. The DevSource is an enumerated type which can be one of {DEV, CACHE, CACHE_DEV}. The * default value is CACHE_DEV. See chapter on Advanced Feature for all details regarding polling * * @param [in] sou The device source */ virtual void set_source(Tango::DevSource sou); /** * Set device transparency (reconnection) mode * * If flag is true, no exception will be thrown in case of network communication error between client and * server. The API will try to re-build the network connection between client and server as soon as an error is * detected. See @ref recon for more details on reconnection and exception * * @param [in] val The device transparency flag */ virtual void set_transparency_reconnection(bool val) {tr_reco = val;} /** * Get device transparency (reconnection) mode * * Returns the transparency reconnection flag. * See @ref recon for more details on reconnection and exception * * @return The device transparency flag */ virtual bool get_transparency_reconnection() {return tr_reco;} //@} /** @name Synchronous command oriented methods */ //@{ /** * Execute a command (without input data) * * Execute a command on a device which takes no input arguments (void). The result is returned in a DeviceData object * * @param [in] cmd_name The command name * @return The command result * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual DeviceData command_inout(string &cmd_name); /** * Execute a command (without input data) * * Execute a command on a device which takes no input arguments (void). The result is returned in a DeviceData object * * @param [in] cmd_name The command name * @return The command result * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual DeviceData command_inout(const char *cmd_name) {string str(cmd_name);return command_inout(str);} /** * Execute a command (with input data) * * Execute a command on a device. Input arguments are passed in a DeviceData object, output is returned as * a DeviceData object. * * @param [in] cmd_name The command name * @param [in] d_in Command input data * @return The command result * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual DeviceData command_inout(string &cmd_name, DeviceData &d_in); /** * Execute a command (with input data) * * Execute a command on a device. Input arguments are passed in a DeviceData object, output is returned as * a DeviceData object. * * @param [in] cmd_name The command name * @param [in] d_in Command input data * @return The command result * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual DeviceData command_inout(const char *cmd_name,DeviceData &d_in) {string str(cmd_name);return command_inout(str,d_in);} //@} /** @name Aynchronous command oriented methods */ //@{ /** * Execute a command asynchronously (with input argument) * * Execute asynchronously (polling model) a command on a device. Input arguments are passed in a DeviceData * object (see following chapters on how to insert data into DeviceData object). The last argument * is a fire and forget flag. If this flag is set to true, this means that the client does not care at all about the * server answer and will even not try to get it. A false default value is provided. Please, note that device * re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an * application using only fire and forget requests is not able to automatically re-connnect to device. This call * returns an asynchronous call identifier which is needed to get the command result. * * @param [in] cmd_name The command name * @param [in] argin Command input data * @param [in] forget Fire and forget flag * @return The call identifier * @throws ConnectionFailed */ virtual long command_inout_asynch(const char *cmd_name,DeviceData &argin,bool forget=false); /** * Execute a command asynchronously (with input argument) * * Execute asynchronously (polling model) a command on a device. Input arguments are passed in a DeviceData * object (see following chapters on how to insert data into DeviceData object). The last argument * is a fire and forget flag. If this flag is set to true, this means that the client does not care at all about the * server answer and will even not try to get it. A false default value is provided. Please, note that device * re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an * application using only fire and forget requests is not able to automatically re-connnect to device. This call * returns an asynchronous call identifier which is needed to get the command result. * * @param [in] cmd_name The command name * @param [in] argin Command input data * @param [in] forget Fire and forget flag * @return The call identifier * @throws ConnectionFailed */ virtual long command_inout_asynch(string &cmd_name,DeviceData &argin,bool forget=false); /** * Execute a command asynchronously * * Execute asynchronously (polling model) a command on a device which takes no input argument. The last * argument is a fire and forget flag. If this flag is set to true, this means that the client does not care at all * about the server answer and will even not try to get it. A false default value is provided. Please, note that * device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, * an application using only fire and forget requests is not able to automatically re-connnect to device. This * call returns an asynchronous call identifier which is needed to get the command result. * * @param [in] cmd_name The command name * @param [in] forget Fire and forget flag * @return The call identifier * @throws ConnectionFailed */ virtual long command_inout_asynch(const char *cmd_name,bool forget=false); /** * Execute a command asynchronously * * Execute asynchronously (polling model) a command on a device which takes no input argument. The last * argument is a fire and forget flag. If this flag is set to true, this means that the client does not care at all * about the server answer and will even not try to get it. A false default value is provided. Please, note that * device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, * an application using only fire and forget requests is not able to automatically re-connnect to device. This * call returns an asynchronous call identifier which is needed to get the command result. * * @param [in] cmd_name The command name * @param [in] forget Fire and forget flag * @return The call identifier * @throws ConnectionFailed */ virtual long command_inout_asynch(string &cmd_name,bool forget=false); /** * Check an asynchronous command_inout answer is arrived * * Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData * object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the * reply is not yet arrived. Example : * @code * Tango::DeviceProxy dev("..."); * long asyn_id; * asyn_id = dev.command_inout_asynch("MyCmd"); * ... * ... * ... * Tango::DeviceData arg; * try * { * arg = dev.command_inout_reply(asyn_id); * } * catch(Tango::AsynReplyNotArrived) * { * cerr << "Command not arrived !" << endl; * } * catch (Tango::DevFailed &e) * { * Tango::Except::print_exception(e); * } * @endcode * * @param [in] id The call identifier * @return The command result * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceData command_inout_reply(long id); /** * Check an asynchronous command_inout answer is arrived with timeout * * Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData * object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will * wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still * not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. * * @param [in] id The call identifier 8 @param [in] timeout The timeout value * @return The command result * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceData command_inout_reply(long id,long timeout); /** * Execute a command asynchronously with callback * * Execute asynchronously (callback model) a command on a device which takes no input argument. The * last argument is a reference to a callback object. This callback object should be an instance of a user class * inheriting from the Tango::CallBack class with the cmd_ended() method overloaded. * * @param [in] cmd_name The command name * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void command_inout_asynch(string &cmd_name,CallBack &cb); /** * Execute a command asynchronously with callback * * Execute asynchronously (callback model) a command on a device which takes no input argument. The * last argument is a reference to a callback object. This callback object should be an instance of a user class * inheriting from the Tango::CallBack class with the cmd_ended() method overloaded. * * @param [in] cmd_name The command name * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void command_inout_asynch(const char *cmd_name,CallBack &cb); /** * Execute a command asynchronously with input value and callback * * Execute asynchronously (callback model) a command on a device. Input arguments are passed in a DeviceData * object (see following chapters on how to insert data into DeviceData object). The last argument is * a reference to a callback object. This callback object should be an instance of a user class inheriting from * the Tango::CallBack class with the cmd_ended() method overloaded. * * @param [in] cmd_name The command name * @param [in] argin The command input data * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void command_inout_asynch(string &cmd_name,DeviceData &argin,CallBack &cb); /** * Execute a command asynchronously with input value and callback * * Execute asynchronously (callback model) a command on a device. Input arguments are passed in a DeviceData * object (see following chapters on how to insert data into DeviceData object). The last argument is * a reference to a callback object. This callback object should be an instance of a user class inheriting from * the Tango::CallBack class with the cmd_ended() method overloaded. * * @param [in] cmd_name The command name * @param [in] argin The command input data * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void command_inout_asynch(const char *cmd_name,DeviceData &argin,CallBack &cb); //@} /** @name Asynchronous attribute related methods */ //@{ /** * Fire callback methods * * Fire callback methods for device asynchronous requests with already arrived replied. Returns immediately * if there is no replies already arrived or if there is no asynchronous request for the device. Example : * @code * class MyCallBack: Tango::CallBack * { * public: * MyCallback(double d):data(d) {}; * virtual void cmd_ended(Tango::CmdDoneEvent *); * private: * double data; * }; * * void MyCallBack::cmd_ended(Tango CmdDoneEvent *cmd) * { * if (cmd->err == true) * Tango::Except::print_error_stack(cmd->errors); * else * { * short cmd_result; * cmd->argout >> cmd_result; * cout << "Command result = " << cmd_result << endl; * cout << "Callback personal data = " << data << endl; * } * } * * int main(int argc, char *argv[]) * { * .... * .... * Tango::DeviceProxy dev("..."); * double my_data = ...; * MyCallBack cb(my_data); * ... * dev.command_inout_asynch("MyCmd",cb); * ... * ... * ... * dev.get_asynch_replies(); * ... * ... * } * @endcode * */ virtual void get_asynch_replies(); /** * Fire callback methds with timeout * * Fire callback methods for device asynchronous requests (command and attributes) with already arrived * replied. Wait and block the caller for timeout milliseconds if they are some device asynchronous requests * which are not yet arrived. Returns immediately if there is no asynchronous request for the device. If * timeout is set to 0, the call waits until all the asynchronous requests sent to the device has received a reply. * * @param [in] timeout The timeout value */ virtual void get_asynch_replies(long timeout); /** * Cancel a pending asynchronous request * * Cancel a pending asynchronous request. id is the asynchronous call identifier. This is a call local to the * client. It simply allows the caller not to get the answer of the asynchronous request. It does not interrupt * the call execution on the remote device. * * @param [in] id The call identifier * @throws AsynCall */ virtual void cancel_asynch_request(long id); /** * Cancel all pending asynchronous request * * Cancel all pending polling asynchronous requests. This is a call local to the client. It simply allows the * caller not to get the answers of the asynchronous requests. It does not interrupt the call execution on the * remote devices. * */ virtual void cancel_all_polling_asynch_request(); //@} ///@privatesection virtual string dev_name()=0; Connection(CORBA::ORB *orb = NULL); Connection(bool dummy); virtual ~Connection(); Connection(const Connection &); Connection & operator=(const Connection &); string &get_db_host() {return db_host;} string &get_db_port() {return db_port;} int get_db_port_num() {return db_port_num;} bool get_from_env_var() {return from_env_var;} static void get_fqdn(string &); bool is_dbase_used() {return dbase_used;} string &get_dev_host() {return host;} string &get_dev_port() {return port;} void connect(string &name); virtual void reconnect(bool); bool is_connected(); Tango::Device_var &get_device() {return device;} // For CORBA expert !! Tango::Device_4_ptr get_device_4() {return Device_4::_duplicate(device_4);} Tango::Device_5_ptr get_device_5() {return Device_5::_duplicate(device_5);} virtual CORBA::Any_var command_inout(string &, CORBA::Any&); virtual CORBA::Any_var command_inout(const char *co, CORBA::Any &d) {string str(co);return command_inout(str,d);} // // Asynchronous methods // void Cb_Cmd_Request(CORBA::Request_ptr,Tango::CallBack *); void Cb_ReadAttr_Request(CORBA::Request_ptr,Tango::CallBack *); void Cb_WriteAttr_Request(CORBA::Request_ptr req,Tango::CallBack *cb_ptr); void dec_asynch_counter(asyn_req_type ty); // // Control access related methods // AccessControlType get_access_control() {return access;} void set_access_control(AccessControlType acc) {access=acc;} AccessControlType get_access_right() {return get_access_control();} friend class FwdAttribute; private: void omni420_timeout(int,char *); DeviceData omni420_except(int,char *,TgRequest &); void toIOR(const char*,IOP::IOR&); }; #endif /* _CONNECTION_H */ tango-9.2.5a/lib/cpp/client/DeviceProxy.h0000644023471100065110000024502713034744772015173 00000000000000//================================================================================================================== // // DeviceProxy.h - include file for TANGO device api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //=================================================================================================================== #ifndef _DEVICEPROXY_H #define _DEVICEPROXY_H /**************************************************************************************** * * * The DeviceProxy class * * -------------------- * * * ***************************************************************************************/ /** * High level class which provides the client with an easy-to-use interface to TANGO devices. * * The high level object which provides the client with an easy-to-use interface to TANGO devices. DeviceProxy * is a handle to the real Device (hence the name Proxy) and is not the real Device (of course). * DeviceProxy provides interfaces to all TANGO devices. The DeviceProxy manages timeouts, * stateless connections (new DeviceProxy() nearly always works), and reconnection if the device server is * restarted. * * $Author: taurel $ * $Revision: 1 $ * * @ingroup Client * @headerfile tango.h */ class DeviceProxy: public Tango::Connection { private : void real_constructor(string &,bool ch_acc=true); Tango::DbDevice *db_dev; string device_name; string alias_name; DeviceInfo _info; bool is_alias; DeviceProxy *adm_device; string adm_dev_name; omni_mutex netcalls_mutex; int lock_ctr; int lock_valid; void connect_to_adm_device(); void retrieve_read_args(TgRequest &,vector &); DeviceAttribute *redo_synch_read_call(TgRequest &); vector *redo_synch_reads_call(TgRequest &); void redo_synch_write_call(TgRequest &); void write_attribute(const AttributeValueList &); void write_attribute(const AttributeValueList_4 &); void create_locking_thread(ApiUtil *,DevLong); void local_import(string &); enum read_attr_type { SIMPLE, MULTIPLE }; void read_attr_except(CORBA::Request_ptr,long,read_attr_type); void write_attr_except(CORBA::Request_ptr,long,TgRequest::ReqType); void check_connect_adm_device(); void omni420_timeout_attr(int,char *,read_attr_type); void omni420_except_attr(int,char *,read_attr_type); void omni420_timeout_wattr(int,char *); void omni420_except_wattr(int,char *); friend class AttributeProxy; protected : /// @privatesection virtual string get_corba_name(bool); virtual string build_corba_name(); virtual int get_lock_ctr() {return lock_ctr;} virtual void set_lock_ctr(int lo) {lock_ctr=lo;} enum polled_object { Cmd, Attr }; bool is_polled(polled_object,string &, string &); virtual void reconnect(bool); void get_remaining_param(AttributeInfoListEx *); template void from_hist_2_AttHistory(T &,vector *); void from_hist4_2_DataHistory(DevCmdHistory_4_var &,vector *); void ask_locking_status(vector &,vector &); void get_locker_host(string &,string &); void same_att_name(vector &,const char *); private: class DeviceProxyExt { public: DeviceProxyExt() {}; bool nethost_alias; string orig_tango_host; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext_proxy; #else DeviceProxyExt *ext_proxy; // Class extension #endif omni_mutex lock_mutex; public : /**@name Constructors */ //@{ /** * Create a DeviceProxy instance. * * Create a DeviceProxy to a device of the specified name. The TANGO_HOST environment variable is used * to determine which TANGO database to connect to. The client can specify an ORB as argument if she * wants to. The constructor will connect to the TANGO database, query for the client’s network address and * build a connection to the device. If the device is defined in the TANGO database but the device server is * not running DeviceProxy will try to build a connection every time the client tries to access the device. If * the device is not defined an exception is thrown. Example : * \code * DeviceProxy *my_device = new DeviceProxy(“my/own/deviceâ€); * \endcode * See appendix on device naming in * Tango book * for all details about Tango device naming syntax. * If an alias name is * defined for the device, this alias name can be used to create the DeviceProxy instance. * * @param [in] name The device name * @param [in] orb Pointer to the ORB. Default value is fine for 99 % of cases * * @throws WrongNameSyntax, ConnectionFailed * */ DeviceProxy(string &name, CORBA::ORB *orb=NULL); /** * Create a DeviceProxy instance. * * Create a DeviceProxy to a device of the specified name. The TANGO_HOST environment variable is used * to determine which TANGO database to connect to. The client can specify an ORB as argument if she * wants to. The constructor will connect to the TANGO database, query for the client’s network address and * build a connection to the device. If the device is defined in the TANGO database but the device server is * not running DeviceProxy will try to build a connection every time the client tries to access the device. If * the device is not defined an exception is thrown. Example : * \code * DeviceProxy *my_device = new DeviceProxy(“my/own/deviceâ€); * \endcode * See appendix on device naming in * Tango book * for all details about Tango device naming syntax. * If an alias name is * defined for the device, this alias name can be used to create the DeviceProxy instance. * * @param [in] name The device name * @param [in] orb Pointer to the ORB. Default value is fine for 99 % of cases * * @throws WrongNameSyntax, ConnectionFailed * */ DeviceProxy(const char *name, CORBA::ORB *orb=NULL); //@} /// @privatesection DeviceProxy(string &name, bool ch_access, CORBA::ORB *orb=NULL); DeviceProxy(const char *, bool ch_access, CORBA::ORB *orb=NULL); DeviceProxy(const DeviceProxy &); DeviceProxy & operator=(const DeviceProxy &); virtual ~DeviceProxy(); DeviceProxy():Connection((CORBA::ORB *)NULL),db_dev(NULL),adm_device(NULL),lock_ctr(0),ext_proxy(Tango_nullptr) {dbase_used = false;} /// @publicsection // // general methods // /**@name Miscellaneous methods */ //@{ /** * Get device info. * * A method which returns information on the device in a DeviceInfo structure. Example : * \code * cout << " device info : " << endl * DeviceInfo dev_info = my_device->info() << endl; * cout << " dev_class " << dev_info.dev_class; * cout << " server_id " << dev_info.server_id; * cout << " server_host " << dev_info.server_host; * cout << " server_version " << dev_info.server_version; * cout << " doc_url " << dev_info.doc_url; * cout << " device_type " << dev_info.dev_type; * \endcode * All DeviceInfo fields are strings except server_version * which is a long integer. * * @return Device information structure * * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual DeviceInfo const &info(); /** * Get device state. * * A method which returns the state of the device as a Tango::DevState type. Example : * \code * Tango::DevState dev_state = my_device->state(); * \endcode * * @return Device state enumeration * * @throws ConnectionFailed, CommunicationFailed */ virtual DevState state(); /** * Get device status. * * A method which returns the status of the device as a string. Example : * \code * cout << "device status: " << my_device->status() << endl; * \endcode * * @return Device status * * @throws ConnectionFailed, CommunicationFailed */ virtual string status(); /** * Ping a device. * * A method which sends a ping to the device and returns the time elapsed as microseconds. Example : * @code * cout << " device ping took " << my_device->ping() << " microseconds" << endl; * @endcode * * @throws ConnectionFailed, CommunicationFailed */ virtual int ping(); /** * Get device black box content * * Get the last n commands executed on the device server and return a pointer to a vector of strings containing * the date, time, command, and from which client computer the command was executed. This method * allocates memory for the vector of strings returned to the caller. It is the caller responsibility to delete this * memory. * * @param [in] nb Number of requested records. If more records than available is requested, only the available records are returned * @return Black box content * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *black_box(int nb); /** * Return the device name (from the device itself) * * Return the device name (from the device itself) * * @return The device name * @throws ConnectionFailed, CommunicationFailed */ virtual string name(); /** * Return the administrator device name * * Returns the name of the corresponding administrator device. This is useful if you need to send an administration * command to the device server e.g. restart it. * * @return The administrator device name * @throws ConnectionFailed, CommunicationFailed */ virtual string adm_name(); /** * Return the device name as it is stored locally * * Return the device name as it is stored locally * * @return The device name */ virtual inline string dev_name() { return device_name; } /** * Returns the device description as a string. * * Returns the device description as a string. * * @return The device description * @throws ConnectionFailed, CommunicationFailed */ virtual string description(); /** * Returns device alias * * Returns the device alias name if one is defined otherwise, throws a DevFailed exception with the reason * field set to Db_AliasNotDefined. * * @return The device alias * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual string alias(); /** * Query the device for import info from the database. * * Query the device for import info from the database. * * @return The device import info * @throws ConnectionFailed, CommunicationFailed, NonDbDevice */ virtual DbDevImportInfo import_info(); /** * Get device Tango lib version * * Get the version of the Tango library used by the device * * @return The device Tango lib version */ virtual int get_tango_lib_version(); //@} /** @name Synchronous command related methods */ //@{ /** * Query the device for single command information. * * Query the device for information about a single command. This command returns a single CommandInfo * type. * * @param [in] cmd_name The command name * @return The command information structure * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual CommandInfo command_query(string cmd_name); /** * Query the device for all commands information. * * Query the device for info on all commands. This method returns a vector of CommandInfo types. This * method allocates memory for the vector of CommandInfo returned to the caller. It is the caller responsibility * to delete this memory * * @return The command information list: One CommandInfo structure per command * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual CommandInfoList *command_list_query(); /** * Query all commands name * * Return the names of all commands implemented for this device as a vector of strings. This method allocates * memory for the vector of strings returned to the caller. It is the caller responsibility to delete this memory. * * @return A vector of string with one string per command * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *get_command_list(); /** * Get command information for a single command * * Return the command information for a single command. * * @param [in] cmd_name Command name * @return The command information * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual CommandInfo get_command_config(const string &cmd_name) {return command_query(cmd_name);} /** * Get information for a set of commands * * Return command information for the list of specified commands. This method allocates memory for the vector of * CommandInfo returned to the caller. It is the caller responsibility to delete this memory. * * @param [in] cmd_names Command name list * @return A vector of CommadnInfo srtuctures with one element per command * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual CommandInfoList *get_command_config(vector &cmd_names); /** * Retrieve command history from polling buffer. * * Retrieve command history from the command polling buffer. The first argument is the command name. * The second argument is the wanted history depth. This method returns a vector of DeviceDataHistory * types. This method allocates memory for the vector of DeviceDataHistory returned to the caller. It is the * caller responsibility to delete this memory. See chapter "Advanced Feature" * Tango book * for all details regarding polling. * @code * DeviceProxy dev = new DeviceProxy("..."); * vector *hist; * * hist = dev->command_history("Status",5); * * for (int i = 0;i < 5;i++) * { * bool fail = (*hist)[i].has_failed(); * if (fail == false) * { * string str; * (*hist)[i] >> str; * cout << "Status = " << str << endl; * } * else * { * cout << "Command failed !" << endl; * cout << "Error level 0 desc = " << ((*hist)[i].errors())[0].desc << endl; * } * cout << "Date = " << (*hist)[i].date().tv_sec << endl; * } * delete hist; * @endcode * * @param [in] cmd_name The command name * @param [in] depth The required history depth * @return The command information list: One CommandInfo structure per command * @throws NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *command_history(string &cmd_name,int depth); /** * Retrieve command history from polling buffer. * * Retrieve command history from the command polling buffer. The first argument is the command name. * The second argument is the wanted history depth. This method returns a vector of DeviceDataHistory * types. This method allocates memory for the vector of DeviceDataHistory returned to the caller. It is the * caller responsibility to delete this memory. See chapter "Advanced Feature" * Tango book * for all details regarding polling. * @code * DeviceProxy dev = new DeviceProxy("..."); * vector *hist; * * hist = dev->command_history("Status",5); * * for (int i = 0;i < 5;i++) * { * bool fail = (*hist)[i].has_failed(); * if (fail == false) * { * string str; * (*hist)[i] >> str; * cout << "Status = " << str << endl; * } * else * { * cout << "Command failed !" << endl; * cout << "Error level 0 desc = " << ((*hist)[i].errors())[0].desc << endl; * } * cout << "Date = " << (*hist)[i].date().tv_sec << endl; * } * delete hist; * @endcode * * @param [in] cmd_name The command name * @param [in] depth The required history depth * @return The command information list: One CommandInfo structure per command * @throws NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *command_history(const char *cmd_name,int depth) {string str(cmd_name);return command_history(str,depth);} //@} /** @name Synchronous attribute related methods */ //@{ /** * Query the device for attribute information * * Query the device for information about a single attribute. This command returns a single AttributeInfoEx * type. * * @b NOTE on compatibility between Tango V4 and Tango V5 regarding attribute properties: * @n Between Tango V4 and Tango V5, attribute configuration has been modified to incorporate alarm and event * related parameters. This explains why it exists two structure types for attribute configuration parameters. * All Tango V4 parameters are defined in a structure called AttributeInfo and a new structure called AttributeInfoEx * has been defined for all Tango V5 parameters. Nevertheless, AttributeInfoEx inherits from * AttributeInfo and it is always possible to call the Tango V5 DeviceProxy::attribute_query() method and to * store its result in one AttributeInfo structure thus allowing compatibility for client written for Tango V4 * but linked with Tango V5. It is also possible for a client written and linked with Tango V5 to call Tango * V5 DeviceProxy::attribute_query() method to all kind of Tango devices. For device using Tango V4, the * alarm and event related parameters will be retrieved from the database instead of from the device * * @param [in] att_name The attribute name * @return The attribute information structure * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoEx attribute_query(string att_name) {return get_attribute_config(att_name);} /** * Query the device for information on all attributes * * Query the device for info on all attributes. This method returns a vector of AttributeInfo types. * This method allocates memory for the * vector of AttributeInfo structures returned to the caller. It is the caller responsibility to delete this memory. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @return A vector of AttributeInfo structures with one element per attribute * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoList *attribute_list_query(); /** * Query the device for information on all attributes * * Query the device for info on all attributes. This method returns a vector of AttributeInfoEx types. * This method allocates memory for the * vector of AttributeInfoEx structures returned to the caller. It is the caller responsibility to delete this memory. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @return A vector of AttributeInfoEx structures with one element per attribute * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoListEx *attribute_list_query_ex(); /** * Query all attributes name * * Return the names of all attributes implemented for this device as a vector of strings. This method allocates * memory for the vector of strings returned to the caller. It is the caller responsibility to delete this memory. * * @return A vector of string with one string per attribute * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *get_attribute_list(); /** * Get attribute configuration for a list of attributes * * Return the attribute configuration for the list of specified attributes. To get all the attributes pass a vector * containing the string AllAttr (defined in tango_const.h). This method allocates memory for the vector of * AttributeInfo returned to the caller. It is the caller responsibility to delete this memory. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @param [in] att_names Attributes name list * @return A vector of AttributeInfo structures with one element per attribute * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoList *get_attribute_config(vector &att_names); /** * Get attribute configuration (extended) for a list of attributes * * Return the extended attribute configuration for the list of specified attributes. To get all the attributes * pass a vector containing the define AllAttr (defined in tango_const.h). This method allocates memory for * the vector of AttributeInfoEx returned to the caller. It is the caller responsibility to delete this memory. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @param [in] att_names Attributes name list * @return A vector of AttributeInfoEx structures with one element per attribute * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoListEx *get_attribute_config_ex(vector &att_names); /** * Get attribute configuration (extended) for a single attribute * * Return the attribute configuration for a single attribute. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @param [in] att_name Attribute name * @return The extended attribute information * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual AttributeInfoEx get_attribute_config(const string &att_name); /** * Set attribute configuration * * Change the attribute configuration for the specified attributes. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @param [in] atts New attributes configuration * @throws ConnectionFailed, CommunicationFailed, DevUnlocked, DevFailed from device */ virtual void set_attribute_config(AttributeInfoList &atts); /** * Set extended attribute configuration * * Change the extended attribute configuration for the specified attributes. * @n See DeviceProxy::attribute_query for a note about compatibility between attribute properties structure * * @param [in] atts New extended attributes configuration * @throws ConnectionFailed, CommunicationFailed, DevUnlocked, DevFailed from device */ virtual void set_attribute_config(AttributeInfoListEx &atts); /** * Read the list of specified attributes * * Read the list of specified attributes. To extract the value you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion * from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a * double, you have to extract it as a short. By default, if the server reports error for one of the attribute * in the list, this error will be passed to the user using exception when he (she) will try to extract the data * form the corresponding See sub-chapter on DeviceAttribute to learn how to change this default behaviour. * DeviceAttribute object. This method allocates memory for the vector of DeviceAttribute objects returned * to the caller. This is the caller responsibility to delete this memory. Example : * @code * vector *devattr; * vector attr_names; * * attr_names.push_back("attribute_1"); * attr_names.push_back("attribute_2"); * * devattr = device->read_attributes(attr_names); * * short short_attr_1; * long long_attr_2; * * (*devattr)[0] >> short_attr_1; * (*devattr)[1] >> long_attr_2; * * cout << "my_attribute value " << short_attr; * delete devattr; * @endcode * * @param [in] att_names Attribute names * @return A vector of DeviceAttribute instances with one element for each read attribute * @throws ConnectionFailed, CommunicationFailed */ virtual vector *read_attributes(vector &att_names); /** * Read a single attribute * * Read a single attribute. To extract the value you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double (this * will return 0) you have to extract it as a short. * See usage eample in DeviceProxy::read_attributes * * @param [in] att_name Attribute name * @return The attribute value in a DeviceAttribute instance * @throws ConnectionFailed, CommunicationFailed */ virtual DeviceAttribute read_attribute(string &att_name); /** * Read the list of specified attributes * * Read a single attribute. To extract the value you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double (this * will return 0) you have to extract it as a short. * See usage eample in DeviceProxy::read_attributes * * @param [in] att_name Attribute name * @return The attribute value in a DeviceAttribute instance * @throws ConnectionFailed, CommunicationFailed */ virtual DeviceAttribute read_attribute(const char *att_name) {string str(att_name);return read_attribute(str);} /** * Write the specified attributes * * Write the specified attributes. To insert the values to write you have to use the operator of the DeviceAttribute * class which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion * from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as * a double (this will throw an exception) you have to insert it as a short. Note that this is the only API call * which could throw a NamedDevFailedList exception. See @ref except to get all the details on this exception. * Example : * @code * vector attr_in; * * string att1_name("First_attr"); * string att2_name("Second_attr"); * * short short_attr = ...; * double double_attr = ...; * * attr_in.push_back(DeviceAttribute(att1_name,short_attr)); * attr_in.push_back(DeviceAttribute(att2_name,double_attr)); * * device->write_attributes(attr_in); * @endcode * * @param [in] attr_in Attributes name and value * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed or NamedDevFailedList from device */ virtual void write_attributes(vector &attr_in); /** * Write a single attribute * * Write a single attribute. To insert the value to write you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this * will throw an exception) you have to insert it as a short. See Deviceproxy::write_attributes for a usage example. * * @param [in] attr_in Attribute name and value * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual void write_attribute(DeviceAttribute &attr_in); /** * Write and read a single attribute * * Write then read a single attribute in a single network call. By default (serialisation by device), the execution * of this call in the server can’t be interrupted by other clients. To insert/extract the value to write/read you * have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. * NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an * attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it * as a short. * * @param [in] attr_in Attribute name and value (to be written) * @return The read attribute data * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual DeviceAttribute write_read_attribute(DeviceAttribute &attr_in); /** * Write and read attribute(s) * * Write then read attribute(s) in a single network call. By default (serialisation by device), the execution * of this call in the server can’t be interrupted by other clients. On the server side, attribute(s) are first * written and if no exception has been thrown during the write phase, attributes will be read. * To insert/extract the value to write/read you * have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. * NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an * attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it * as a short. * * @param [in] attr_in The attribute(s) name and value (to be written) * @param [in] r_names Names of attribute to be read * @return The read attribute(s) data * @throws ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device */ virtual vector *write_read_attributes(vector &attr_in,vector &r_names); /** * Retrieve attribute history from polling buffer * * Retrieve attribute history from the attribute polling buffer. The first argument is the attribute name. The * second argument is the wanted history depth. This method returns a vector of DeviceAttributeHistory * types. This method allocates memory for the vector of DeviceAttributeHistory returned to the caller. It is * the caller responsibility to delete this memory. * See chapter on Advanced Feature * in Tango book * for all details regarding polling. * @code * DeviceProxy dev = new DeviceProxy("..."); * vector *hist; * * hist = dev->attribute_history("Current",5); * * for (int i = 0;i < 5;i++) * { * bool fail = (*hist)[i].has_failed(); * if (fail == false) * { * cout << "Attribute name = " << (*hist)[i].get_name() << endl; * cout << "Attribute quality factor = " << (*hist)[i].get_quality() << endl; * long value; * (*hist)[i] >> value; * cout << "Current = " << value << endl; * } * else * { * cout << "Attribute failed !" << endl; * cout << "Error level 0 desc = " << ((*hist)[i].get_err_stack())[0].desc << endl; * } * cout << "Date = " << (*hist)[i].get_date().tv_sec << endl; * } * delete hist; * @endcode * * @param [in] att_name Attribute name * @param [in] depth The required history depth * @return The read attribute history data * @throws NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *attribute_history(string &att_name,int depth); /** * Retrieve attribute history from polling buffer * * Retrieve attribute history from the attribute polling buffer. The first argument is the attribute name. The * second argument is the wanted history depth. This method returns a vector of DeviceAttributeHistory * types. This method allocates memory for the vector of DeviceAttributeHistory returned to the caller. It is * the caller responsibility to delete this memory. * See chapter on Advanced Feature * in Tango book * for all details regarding polling. * @code * DeviceProxy dev = new DeviceProxy("..."); * vector *hist; * * hist = dev->attribute_history("Current",5); * * for (int i = 0;i < 5;i++) * { * bool fail = (*hist)[i].has_failed(); * if (fail == false) * { * cout << "Attribute name = " << (*hist)[i].get_name() << endl; * cout << "Attribute quality factor = " << (*hist)[i].get_quality() << endl; * long value; * (*hist)[i] >> value; * cout << "Current = " << value << endl; * } * else * { * cout << "Attribute failed !" << endl; * cout << "Error level 0 desc = " << ((*hist)[i].get_err_stack())[0].desc << endl; * } * cout << "Date = " << (*hist)[i].get_date().tv_sec << endl; * } * delete hist; * @endcode * * @param [in] att_name Attribute name * @param [in] depth The required history depth * @return The read attribute history data * @throws NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *attribute_history(const char *att_name,int depth) {string str(att_name);return attribute_history(str,depth);} //@} /** @name Pipe related methods */ //@{ /** * Get pipe configuration for a list of pipes * * Return the pipe configuration for the list of specified pipes. To get all the pipes * pass a vector containing the define AllPipe (defined in tango_const.h). This method allocates memory for * the vector of PipeInfo returned to the caller. It is the caller responsibility to delete this memory. * * @param [in] pipe_names Pipes name list * @return A vector of PipeInfo structures with one element per pipe * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual PipeInfoList *get_pipe_config(vector &pipe_names); /** * Get pipe configuration for a single pipe * * Return the pipe configuration for a single pipe. * * @param [in] pipe_name Pipe name * @return The pipe information * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual PipeInfo get_pipe_config(const string &pipe_name); /** * Set pipe configuration * * Change the pipe configuration for the specified pipes. * * @param [in] pipes New pipes configuration * @throws ConnectionFailed, CommunicationFailed, DevUnlocked, DevFailed from device */ virtual void set_pipe_config(PipeInfoList &pipes); /** * Query all pipes name * * Return the names of all pipes implemented for this device as a vector of strings. This method allocates * memory for the vector of strings returned to the caller. It is the caller responsibility to delete this memory. * * @return A vector of string with one string per pipe * @throws ConnectionFailed, CommunicationFailed, DevFailed from device */ virtual vector *get_pipe_list(); /** * Read a pipe * * Read a pipe. * * @param [in] pipe_name Pipe name * @return The pipe value in a DevicePipe instance * @throws ConnectionFailed, CommunicationFailed */ virtual DevicePipe read_pipe(const string &pipe_name); /** * Write a pipe * * Write a pipe. * * @param [in] pipe_data Data to be sent to the device through the pipe * @throws ConnectionFailed, CommunicationFailed */ virtual void write_pipe(DevicePipe &pipe_data); /** * Write then read a pipe * * Write then read a pipe in a single network call. By default (serialisation by device), the execution * of this call in the server can’t be interrupted by other clients. * * @param [in] pipe_data Data to be sent to the device through the pipe * @return The pipe value in a DevicePipe instance * @throws ConnectionFailed, CommunicationFailed */ virtual DevicePipe write_read_pipe(DevicePipe &pipe_data); //@} /** @name Asynchronous attribute related methods */ //@{ /** * Read a single attribute asynchronously * * Read asynchronously (polling model) a single attribute. This call returns an asynchronous call identifier * which is needed to get the attribute value. * * @param [in] att_name The attributes name * @return The call identifier * @throws ConnectionFailed */ virtual long read_attribute_asynch(string &att_name); /** * Read a single attribute asynchronously * * Read asynchronously (polling model) a single attribute. This call returns an asynchronous call identifier * which is needed to get the attribute value. * * @param [in] att_name The attributes name * @return The call identifier * @throws ConnectionFailed */ virtual long read_attribute_asynch(const char *att_name) {string tmp(att_name);return read_attribute_asynch(tmp);} /** * Read asynchronously alist of attributes * * Read asynchronously (polling model) the list of specified attributes. This call returns an asynchronous call * identifier which is needed to get attributes value. * * @param [in] att_names The attributes names * @return The call identifier * @throws ConnectionFailed */ virtual long read_attributes_asynch(vector &att_names); /** * Check if an asynchronous read_attributes call is arrived * * Check if the answer of an asynchronous read_attribute is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute * object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the * reply is not yet arrived. To extract attribute value, you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from * the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, * you have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the * caller. This is the caller responsibility to delete this memory. * * @param [in] id The call identifier * @return The attribute(s) data * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual vector *read_attributes_reply(long id); /** * Check if an asynchronous read_attributes call is arrived (with timeout) * * Check if the answer of an asynchronous read_attribute is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute * object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will * wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still * not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract * attribute value, you have to use the operator of the class DeviceAttribute which corresponds to the data type * of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type * e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory * has been allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to * delete this memory. * * @param [in] id The call identifier * @param [in] timeout The timeout value * @return The attribute(s) data * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual vector *read_attributes_reply(long id,long timeout); /** * Check if an asynchronous read_attribute (single attribute) call is arrived * * Check if the answer of an asynchronous read_attribute is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute. * If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply * is not yet arrived. To extract attribute value, you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you * have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to * the caller. This is the caller responsibility to delete this memory. * * @param [in] id The call identifier * @return The attribute data * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceAttribute *read_attribute_reply(long id); /** * Check if an asynchronous read_attribute (single attribute) call is arrived (with timeout) * * Check if the answer of an asynchronous read_attributes is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute. * If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait * (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not * there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract attribute * value, you have to use the operator of the class DeviceAttribute which corresponds to the data type of the * attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an * attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been * allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to * delete this memory. * * @param [in] id The call identifier * @param [in] timeout The timeout value * @return The attribute data * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceAttribute *read_attribute_reply(long id,long timeout); /** * Write a single attribute asynchronously * * Write asynchronously (polling model) a single attribute. To insert the value to write you have to use the * operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is * no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a * short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This * call returns an asynchronous call identifier which is needed to get the server reply. * * @param [in] argin The attribute name and value * @return The call identifier * @throws ConnectionFailed */ virtual long write_attribute_asynch(DeviceAttribute &argin); /** * Write asynchronously alist of attributes * * Write asynchronously (polling model) the specified attributes. To insert the value to write you have to use * the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There * is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects * a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This * call returns an asynchronous call identifier which is needed to get the server reply. * * @param [in] argin The attributes name and value * @return The call identifier * @throws ConnectionFailed */ virtual long write_attributes_asynch(vector &argin); /** * Check if the answer of one asynchronous write_attribute (single attribute) call is arrived * * Check if the answer of an asynchronous write_attribute is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, * it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. * * @param [in] id The call identifier * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_attribute_reply(long id) {write_attributes_reply(id);} /** * Check if the answer of one asynchronous write_attribute call (single attribute) is arrived with timeout * * Check if the answer of an asynchronous write_attribute is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, * it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the * time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. * If timeout is set to 0, the call waits until the reply arrived. * * @param [in] id The call identifier * @param [in] timeout The timeout value * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_attribute_reply(long id,long timeout) {write_attributes_reply(id,timeout);} /** * Check if the answer of one asynchronous write_attributes call is arrived * * Check if the answer of an asynchronous write_attributes is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, * it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. * * @param [in] id The call identifier * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_attributes_reply(long id); /** * Check if the answer of one asynchronous write_attributes call is arrived with timeout * * Check if the answer of an asynchronous write_attributes is arrived (polling model). id is the asynchronous * call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, * it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the * time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. * If timeout is set to 0, the call waits until the reply arrived. * * @param [in] id The call identifier * @param [in] timeout The timeout value * @throws AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_attributes_reply(long id,long timeout); /** * Read a single attribute asynchronously in callback model * * Read asynchronously (callback model) a single attribute. The last argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the @e attr_read() method overloaded. * * @param [in] att_name The attribute name * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void read_attribute_asynch(const char *att_name,CallBack &cb) {string tmp(att_name);read_attribute_asynch(tmp,cb);} /** * Read a single attribute asynchronously in callback model * * Read asynchronously (callback model) a single attribute. The last argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the @e attr_read() method overloaded. * * @param [in] att_name The attribute name * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void read_attribute_asynch(string &att_name,CallBack &cb); /** * Read asynchronously in callback model a list of attributes * * Read asynchronously (callback model) an attribute list. The last argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the @e attr_read() method overloaded. * * @param [in] att_names The attribute name list * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void read_attributes_asynch(vector &att_names,CallBack &cb); /** * Write asynchronously in callback model a single attribute * * Write asynchronously (callback model) a single attribute. The last argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the @e attr_written() method overloaded. * * @param [in] argin The attribute name and value * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void write_attribute_asynch(DeviceAttribute &argin,CallBack &cb); /** * Write asynchronously in callback model a list of attributes * * Write asynchronously (callback model) an attribute list. The last argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the @e attr_written() method overloaded. * * @param [in] argin The attribute names and values * @param [in] cb The call-back object * @throws ConnectionFailed */ virtual void write_attributes_asynch(vector &argin,CallBack &cb); //@} /** @name Asynchronous related methods */ //@{ /** * Get pending asynchronous request number * * Return number of device asynchronous pending requests. The input parameter is an enumeration with three * values which are: * @li POLLING : Returns only device polling model asynchronous request number * @li CALLBACK : Returns only device callback model asynchronous request number * @li ALL_ASYNCH : Returns device asynchronous request number * * @param [in] req The asynchronous request type * @return Pending asynchronous request number */ virtual long pending_asynch_call(asyn_req_type req) {if (req == POLLING)return pasyn_ctr; else if (req==CALL_BACK) return pasyn_cb_ctr; else return (pasyn_ctr + pasyn_cb_ctr);} //@} /** @name Polling related methods */ //@{ /** * Check if a command is polled * * Returns true if the command "cmd_name" is polled. Otherwise, returns false. * * @param [in] cmd_name The command name * @return Flag set to true if the command is polled */ virtual bool is_command_polled(string &cmd_name); /** * Check if a command is polled * * Returns true if the command "cmd_name" is polled. Otherwise, returns false. * * @param [in] cmd_name The command name * @return Flag set to true if the command is polled */ virtual bool is_command_polled(const char *cmd_name) {string tmp(cmd_name);return is_command_polled(tmp);} /** * Check if one attribute is polled * * Returns true if the attribute "att_name" is polled. Otherwise, returns false. * * @param [in] att_name The attribute name * @return Flag set to true if the attribute is polled */ virtual bool is_attribute_polled(string &att_name); /** * Check if one attribute is polled * * Returns true if the attribute "att_name" is polled. Otherwise, returns false. * * @param [in] att_name The attribute name * @return Flag set to true if the attribute is polled */ virtual bool is_attribute_polled(const char *att_name) {string tmp(att_name);return is_attribute_polled(tmp);} /** * Get command polling period * * Returns the command "cmd_name" polling period in mS. If the command is not polled, it returns 0. * * @param [in] cmd_name The command name * @return The command polling period */ virtual int get_command_poll_period(string &cmd_name); /** * Get command polling period * * Returns the command "cmd_name" polling period in mS. If the command is not polled, it returns 0. * * @param [in] cmd_name The command name * @return The command polling period */ virtual int get_command_poll_period(const char *cmd_name) {string tmp(cmd_name);return get_command_poll_period(tmp);} /** * Get attribute polling period * * Returns the attribute "att_name" polling period in mS. If the attribute is not polled, it returns 0. * * @param [in] att_name The attribute name * @return The attribute polling period */ virtual int get_attribute_poll_period(string &att_name); /** * Get attribute polling period * * Returns the attribute "att_name" polling period in mS. If the attribute is not polled, it returns 0. * * @param [in] att_name The attribute name * @return The attribute polling period */ virtual int get_attribute_poll_period(const char *att_name) {string tmp(att_name);return get_attribute_poll_period(tmp);} /** * Get polling status * * Returns the device polling status. There is one string for each polled command/attribute. Each string is * multi-line string with : * @li The attribute/command name * @li The attribute/command polling period (in mS) * @li The attribute/command polling ring buffer depth * @li The time needed for the last command/attribute execution (in mS) * @li The time since data in the ring buffer has not been updated * @li The delta time between the last records in the ring buffer * @li The exception parameters in case of the last command/attribute execution failed * * This method allocates memory for the vector of string(s) returned to the caller. It is the caller responsibility * to delete this memory. * * @return The polling status */ virtual vector *polling_status(); /** * Poll a command * * Add the command "cmd_name" to the list of polled command. The polling period is specified by "polling_period" * (in mS). If the command is already polled, this method will update the polling period according to "polling_period". * * @param [in] cmd_name The command name * @param [in] polling_period The polling period */ virtual void poll_command(string &cmd_name, int polling_period); /** * Poll a command * * Add the command "cmd_name" to the list of polled command. The polling period is specified by "polling_period" * (in mS). If the command is already polled, this method will update the polling period according to "polling_period". * * @param [in] cmd_name The command name * @param [in] polling_period The polling period */ virtual void poll_command(const char *cmd_name, int polling_period) {string tmp(cmd_name);poll_command(tmp,polling_period);} /** * Poll an attribute * * Add the attribute "att_name" to the list of polled attributes. The polling period is specified by "polling_period" (in * mS). If the attribute is already polled, this method will update the polling period according to "polling_period". * * @param [in] att_name The attribute name * @param [in] polling_period The polling period */ virtual void poll_attribute(string &att_name, int polling_period); /** * Poll an attribute * * Add the attribute "att_name" to the list of polled attributes. The polling period is specified by "polling_period" (in * mS). If the attribute is already polled, this method will update the polling period according to "polling_period". * * @param [in] att_name The attribute name * @param [in] polling_period The polling period */ virtual void poll_attribute(const char *att_name, int polling_period) {string tmp(att_name);poll_attribute(tmp,polling_period);} /** * Stop polling a command * * Remove command "cmd_name" from the list of polled command. * * @param [in] cmd_name The command name */ virtual void stop_poll_command(string &cmd_name); /** * Stop polling a command * * Remove command "cmd_name" from the list of polled command. * * @param [in] cmd_name The command name */ virtual void stop_poll_command(const char *cmd_name) {string tmp(cmd_name);stop_poll_command(tmp);} /** * Stop polling an attribute * * Remove attribute "att_name" from the list of polled attributes * * @param [in] att_name The attribute name */ virtual void stop_poll_attribute(string &att_name); /** * Stop polling an attribute * * Remove attribute "att_name" from the list of polled attributes * * @param [in] att_name The attribute name */ virtual void stop_poll_attribute(const char *att_name) {string tmp(att_name);stop_poll_attribute(tmp);} //@} /** @name Event related methods */ //@{ /** * Subscribe for event reception * * The client call to subscribe for event reception in the push model. The client implements a callback method * which is triggered when the event is received. Filtering is done based on the event * type. For example when reading the state and the reason specified is "change" the event will be fired only * when the state changes. Events consist of an attribute name and the event reason. A standard set of reasons * are implemented by the system, additional device specific reasons can be implemented by device servers * programmers. * The attribute parameter is the device attribute name which will be sent as an event e.g. “currentâ€, event * parameter is the event reason, * cb is a pointer to a class inheriting from the Tango CallBack class and implementing a push_event() method. * The subscribe_event() call returns an event id which has to be specified when unsubscribing from this * event. Please, note that the cb parameter is a pointer. The lifetime of the pointed to object must at least * be equal to the time when events are requested because only the pointer is stored into the event machinery. * The same thing is true for the DeviceProxy instance on which the subscribe_event() method is called. * * @param [in] att_name The attribute name * @param [in] event The event type * @param [in] cb The callback object * @return The event identifier * @throws EventSystemFailed */ virtual int subscribe_event(const string &att_name, EventType event, CallBack *cb); /** * Subscribe for event reception with stateless support * * The client call to subscribe for event reception in the push model. The client implements a callback method * which is triggered when the event is received. Filtering is done based on the event * type. For example when reading the state and the reason specified is "change" the event will be fired only * when the state changes. Events consist of an attribute name and the event reason. A standard set of reasons * are implemented by the system, additional device specific reasons can be implemented by device servers * programmers. * The attribute parameter is the device attribute name which will be sent as an event e.g. “currentâ€, event * parameter is the event reason, * cb is a pointer to a class inheriting from the Tango CallBack class and implementing a push_event() method. * The last call parameter is named stateless. When the stateless flag is set to false, an exception will be thrown when the event * subscription encounters a problem. * With the stateless flag set to true, the event subscription will always succeed, even if the corresponding * device server is not running. The keep alive thread will try every 10 seconds to subscribe for the specified * event. At every subscription retry, a callback is executed which contains the corresponding exception. * The subscribe_event() call returns an event id which has to be specified when unsubscribing from this * event. Please, note that the cb parameter is a pointer. The lifetime of the pointed to object must at least * be equal to the time when events are requested because only the pointer is stored into the event machinery. * The same thing is true for the DeviceProxy instance on which the subscribe_event() method is called. * * @param [in] att_name The attribute name * @param [in] event The event type * @param [in] cb The callback object * @param [in] stateless The stateless flag * @return The event identifier * @throws EventSystemFailed */ virtual int subscribe_event(const string &att_name, EventType event, CallBack *cb,bool stateless); /** * Subscribe for event reception with event queue * * The client call to subscribe for event reception in the pull model. Instead of a callback method the client * has to specify the size of the event reception buffer. * The event reception buffer is implemented as a round robin buffer. This way the client can set-up * different ways to receive events. * @li Event reception buffer size = 1 : The client is interested only in the value of the last event received. * All other events that have been received since the last reading are discarded. * @li Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When * more events arrive since the last reading, older events will be discarded. * @li Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size * is unlimited and only restricted by the available memory for the client. * * All other parameters (att_name, event, stateless) are similar to those described in DeviceProxy::subscribe_event(const string &,EventType,CallBack *,bool) * * @param [in] att_name The attribute name * @param [in] event The event type * @param [in] event_queue_size The event queue size * @param [in] stateless The stateless flag * @return The event identifier * @throws EventSystemFailed */ virtual int subscribe_event(const string &att_name, EventType event, int event_queue_size,bool stateless = false); /** * Subscribe for device event reception with stateless support * * The client call to subscribe for device event reception in the push model. The client implements a callback method * which is triggered when the event is received. Filtering is done based on the event * type. Today, only one event type is supported for device event. This event type is a device interface * change event. * cb is a pointer to a class inheriting from the Tango CallBack class and implementing a push_event() method. * The last call parameter is named stateless. When the stateless flag is set to false, an exception will be thrown * when the event subscription encounters a problem. * With the stateless flag set to true, the event subscription will always succeed, even if the corresponding * device server is not running. The keep alive thread will try every 10 seconds to subscribe for the specified * event. At every subscription retry, a callback is executed which contains the corresponding exception. * The subscribe_event() call returns an event id which has to be specified when unsubscribing from this * event. Please, note that the cb parameter is a pointer. The lifetime of the pointed to object must at least * be equal to the time when events are requested because only the pointer is stored into the event machinery. * The same thing is true for the DeviceProxy instance on which the subscribe_event() method is called. * * @param [in] event The event type * @param [in] cb The callback object * @param [in] stateless The stateless flag * @return The event identifier * @throws EventSystemFailed */ virtual int subscribe_event(EventType event,CallBack *cb,bool stateless = false); /** * Subscribe for device event reception with stateless support and event queue * * The client call to subscribe for device event reception in the pull model. * Today, only one event type is supported for device event. This event type is a device interface * change event. * Instead of a callback method the client * has to specify the size of the event reception buffer. * The event reception buffer is implemented as a round robin buffer. This way the client can set-up * different ways to receive events. * @li Event reception buffer size = 1 : The client is interested only in the value of the last event received. * All other events that have been received since the last reading are discarded. * @li Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When * more events arrive since the last reading, older events will be discarded. * @li Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size * is unlimited and only restricted by the available memory for the client. * The last call parameter is named stateless. When the stateless flag is set to false, an exception will be thrown * when the event subscription encounters a problem. * With the stateless flag set to true, the event subscription will always succeed. * * @param [in] event The event type * @param [in] event_queue_size The event queue size * @param [in] stateless The stateless flag * @return The event identifier * @throws EventSystemFailed */ virtual int subscribe_event(EventType event,int event_queue_size,bool stateless = false); /** * Unsubscribe for event reception * * Unsubscribe a client from receiving the event specified by event_id. event_id is the event identifier returned * by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @throws EventSystemFailed */ virtual void unsubscribe_event(int event_id); /** * Fire event callback in event pull model * * The method extracts all waiting events from the event reception buffer and executes the callback method * cb for every event. During event subscription the client must have chosen the pull model for this event. * event_id is the event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [in] cb The callback object * @throws EventSystemFailed */ virtual void get_events (int event_id, CallBack *cb); /** * Get arrived events from the event queue in event pull model * * The method extracts all waiting events from the event reception buffer. The returned event_list is a vector * of EventData pointers. The EventData object contains the event information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [out] event_list The event(s) list * @throws EventSystemFailed */ virtual void get_events (int event_id, EventDataList &event_list); /** * Get arrived events from event queue in event pull model * * The method extracts all waiting attribute configuration events from the event reception buffer. The returned * event_list is a vector of AttrConfEventData pointers. The AttrConfEventData object contains the event * information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [out] event_list The event(s) list * @throws EventSystemFailed */ virtual void get_events (int event_id, AttrConfEventDataList &event_list); /** * Get arrived events from event queue in event pull model * * The method extracts all waiting attribute configuration events from the event reception buffer. The returned * event_list is a vector of DataReadyEventData pointers. The DataReadyEventData object contains the event * information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [out] event_list The event(s) list * @throws EventSystemFailed */ virtual void get_events (int event_id, DataReadyEventDataList &event_list); /** * Get arrived events from event queue in event pull model * * The method extracts all waiting attribute configuration events from the event reception buffer. The returned * event_list is a vector of DevIntrChangeEventData pointers. The DevIntrChangeEventData object contains the event * information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [out] event_list The event(s) list * @throws EventSystemFailed */ virtual void get_events (int event_id, DevIntrChangeEventDataList &event_list); /** * Get arrived events from event queue in event pull model * * The method extracts all waiting pipe events from the event reception buffer. The returned * event_list is a vector of PipeEventData pointers. The PipeEventData object contains the event * information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @param [out] event_list The event(s) list * @throws EventSystemFailed */ virtual void get_events (int event_id, PipeEventDataList &event_list); /** * Get event number in event queue * * Returns the number of stored events in the event reception buffer. After every call to DeviceProxy:get_events(), * the event queue size is 0. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @return The event number in queue * @throws EventSystemFailed */ virtual int event_queue_size(int event_id); /** * Get date of the last event in queue * * Returns the arrival time of the last event stored in the event reception buffer. After every call to Device- * Proxy:get_events(), the event reception buffer is empty. In this case an exception will be returned. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @return The last event date * @throws EventSystemFailed */ virtual TimeVal get_last_event_date(int event_id); /** * Check if the event queue is empty * * Returns true when the event reception buffer is empty. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the DeviceProxy::subscribe_event() method. * * @param [in] event_id The event identifier * @return true if the event queue is empty * @throws EventSystemFailed */ virtual bool is_event_queue_empty(int event_id); //@} /** @name Property related methods */ //@{ /** * Get a single device property * * Get a single property for a device. The property to get is specified as a string. Refer to DbDevice::get_property() * and DbData sections below for details on the DbData type. * * @param [in] prop_name The property name * @param [out] db The property value * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void get_property(string &prop_name, DbData &db); /** * Get a list of device properties * * Get a list of properties for a device. The properties to get are specified as a vector of strings. Refer to * DbDevice::get_property() and DbData sections below for details on the DbData type. * * @param [in] prop_names The property names * @param [out] db The properties values * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void get_property(vector &prop_names, DbData &db); /** * Get property(ies) for a device * * Get property(ies) for a device. Properties to get are specified using the DbData type. Refer to DbDevice:: * get_property() and DbData sections below for details. * * @param [in,out] db The property(ies) names and values * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void get_property(DbData &db); /** * Put property(ies) for a device * * Put property(ies) for a device. Properties to put are specified using the DbData type. Refer to DbDevice:: * put_property() and DbData sections below for details. * * @param [in] db The property(ies) names and values * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void put_property(DbData &db); /** * Delete a single device property * * Delete a single property for a device. The property to delete is specified as a string. * * @param [in] prop_name The property name * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void delete_property(string &prop_name); /** * Delete a list of device properties * * Delete a list of properties for a device. The properties to delete are specified as a vector of strings. * * @param [in] prop_names The property names list * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void delete_property(vector &prop_names); /** * Delete property(ies) for a device * * Delete property(ies) for a device. Properties to delete are specified using the DbData type. Refer to DbDevice:: * get_property() and DbData sections below for details. * * @param [in] db The property names * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void delete_property(DbData &db); /** * Get list of property names for a device * * Get the list of property names for the device. The parameter filter allows the user to filter the returned name * list. The wildcard character is ’*’. Only one wildcard character is allowed in the filter parameter. The name * list is returned in the vector of strings passed as the method second argument. * * @param [in] filter The filter * @param [out] prop_list The device property list * @throws NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database device */ virtual void get_property_list(const string &filter,vector &prop_list); //@} /** @name Logging related methods */ //@{ #ifdef TANGO_HAS_LOG4TANGO /** * Add a logging target to the device * * Adds a new logging target to the device. The target_type_name input parameter must follow the * format: @b target_type::target_name. Supported target types are: * @li console * @li file * @li device * * For a device target, * the target_name part of the target_type_target_name parameter must contain the name of a log consumer * device (as defined in A.8). For a file target, target_name is the full path to the file to log to. If omitted, the * device’s name is used to build the file name (which is something like domain_family_member.log). Finally, * the target_name part of the target_type_target_name input parameter is ignored in case of a console target * and can be omitted. * * @param [in] target_type_name The target type and name * @throws DevFailed from device */ virtual void add_logging_target(const string &target_type_name); /** * Add a logging target to the device * * Adds a new logging target to the device. The target_type_name input parameter must follow the * format: @b target_type::target_name. Supported target types are: * @li console * @li file * @li device * * For a device target, * the target_name part of the target_type_target_name parameter must contain the name of a log consumer * device (as defined in A.8). For a file target, target_name is the full path to the file to log to. If omitted, the * device’s name is used to build the file name (which is something like domain_family_member.log). Finally, * the target_name part of the target_type_target_name input parameter is ignored in case of a console target * and can be omitted. * * @param [in] target_type_name The target type and name * @throws DevFailed from device */ virtual void add_logging_target(const char *target_type_name) {add_logging_target(string(target_type_name));} /** * Remove a logging target from the device * * Removes a logging target from the device’s target list. The target_type_name input parameter must * follow the format: target_type::target_name. Supported target types are: * @li console * @li file * @li device * * For a * device target, the target_name part of the target_type_target_name parameter must contain the name of a * log consumer device (as defined in ). For a file target, target_name is the full path to the file to remove. If * omitted, the default log file is removed. Finally, the target_name part of the target_type_target_name input * parameter is ignored in case of a console target and can be omitted. * If target_name is set to "*", all targets of the specified target_type are removed. * * @param [in] target_type_name The target type and name */ virtual void remove_logging_target(const string &target_type_name); /** * Remove a logging target from the device * * Removes a logging target from the device’s target list. The target_type_name input parameter must * follow the format: target_type::target_name. Supported target types are: * @li console * @li file * @li device * * For a * device target, the target_name part of the target_type_target_name parameter must contain the name of a * log consumer device (as defined in ). For a file target, target_name is the full path to the file to remove. If * omitted, the default log file is removed. Finally, the target_name part of the target_type_target_name input * parameter is ignored in case of a console target and can be omitted. * If target_name is set to "*", all targets of the specified target_type are removed. * * @param [in] target_type_name The target type and name */ virtual void remove_logging_target(const char *target_type_name) {remove_logging_target(string(target_type_name));} /** * Get current device's logging targets * * Returns a vector of string containing the current device’s logging targets. Each vector element has the * following format: target_type::target_name. An empty vector is returned is the device has no logging * targets. * * @return List of loggin target */ virtual vector get_logging_target (void); /** * Get current device's logging level * * Returns the current device’s logging level (0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG). * * @return The device logging level */ virtual int get_logging_level (void); /** * Set the device logging level * * Changes the device’s logging level. (0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG). * * @param [in] level The new device logging level */ virtual void set_logging_level (int level); #endif // TANGO_HAS_LOG4TANGO //@} /** @name Locking related methods */ //@{ /** * Lock a device * * Lock a device. The lock_validity is the time (in seconds) the lock is kept valid after the previous lock call. * A default value of 10 seconds is provided and should be fine in most cases. In case it is necessary to change * the lock validity, it’s not possible to ask for a validity less than a minimum value set to 2 seconds. The * library provided an automatic system to periodically re lock the device until an unlock call. No code is * needed to start/stop this automatic re-locking system. The locking system is re-entrant. It is then allowed * to call this method on a device already locked by the same process. The locking system has the following * features: * @li It is impossible to lock the database device or any device server process admin device * @li Destroying a locked DeviceProxy unlocks the device * @li Restarting a locked device keeps the lock * @li It is impossible to restart a device locked by someone else * @li Restarting a server breaks the lock * * A locked device is protected against the following calls when executed by another client: * @li command_inout call except for device state and status requested via command and for the set of * commands defined as allowed following the definition of allowed command in the Tango control * access schema. * @li write_attribute call * @li write_pipe call * @li write_read_attribute call * @li write_read_pipe call * @li set_attribute_config call * @li set_pipe_config call * * @param [in] lock_validity The lock validity (in seconds) */ virtual void lock(int lock_validity=DEFAULT_LOCK_VALIDITY); /** * Unlock a device * * Unlock a device. If used, the method argument provides a back door on the locking system. If this argument * is set to true, the device will be unlocked even if the caller is not the locker. This feature is provided for * administration purpose and should be used very carefully. If this feature is used, the locker will receive a * DeviceUnlocked exception during the next call which is normally protected by the locking Tango system. * * @param [in] force The force unlock flag */ virtual void unlock(bool force=false); /** * Get device locking status * * This method returns a plain string describing the device locking status. This string can be: * @li "Device is not locked" in case the device is not locked * @li "Device is locked by CPP or Python client with PID from host " * in case the device is locked by a CPP client * @li "Device is locked by JAVA client class
from host " in case * the device is locked by a JAVA client * * @return The device locking status */ virtual string locking_status(); /** * Check if the device is locked * * Returns true if the device is locked. Otherwise, returns false * * @return The device locked flag */ virtual bool is_locked(); /** * Check if the device is locked by the caller * * Returns true if the device is locked by the caller. Otherwise, returns false (device not locked or locked by * someone else) * * @return The device locked flag */ virtual bool is_locked_by_me(); /** * Get device locking information * * If the device is locked, this method returns true an set some locker process informations in the structure * passed as argument. If the device is not locked, the method returns false. The LockerInfo structure definition * is * @code * typedef union * { * pid_t LockerPid; * unsigned long UUID[4]; * }LockerId; * * enum LockerLanguage * { * CPP, * JAVA * }; * * struct LockerInfo * { * LockerLanguage ll; * LockerId li; * string locker_host; * string locker_class; * }; * @endcode * * @param [out] li Device locking information * @return The device locked flag */ virtual bool get_locker(LockerInfo &li); //@} /// @privatesection virtual void parse_name(string &); virtual Database *get_device_db(); DeviceProxy *get_adm_device() {return adm_device;} // // attribute methods // void read_attribute(const string &,AttributeValue_4 *&); void read_attribute(const string &,AttributeValue_5 *&); void read_attribute(const char *,DeviceAttribute &); void read_attribute(string &at,DeviceAttribute &da) {read_attribute(at.c_str(),da);} // // Old event methods // virtual int subscribe_event(const string &attr_name, EventType event, CallBack *, const vector &filters); // For compatibility with Tango < 8 virtual int subscribe_event(const string &attr_name, EventType event, CallBack *, const vector &filters, bool stateless); // For compatibility with Tango < 8 virtual int subscribe_event(const string &attr_name, EventType event, int event_queue_size, const vector &filters, bool stateless = false); // For compatibility with Tango < 8 }; #endif /* _DEVICEPROXY_H */ tango-9.2.5a/lib/cpp/client/AttributeProxy.h0000644023471100065110000007054413034744772015737 00000000000000////////////////////////////////////////////////////////////////// // // devapi.h - include file for TANGO device api // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 1 $ // /////////////////////////////////////////////////////////////// #ifndef _ATTRIBUTEPROXY_H #define _ATTRIBUTEPROXY_H /**************************************************************************************** * * * The AttributeProxy class * * -------------------- * * * ***************************************************************************************/ /** * Easy to use interface to Tango device attribute * * The high level object which provides the client with an easy-to-use interface to TANGO device attributes. * AttributeProxy is a handle to the real attribute (hence the name Proxy) and is not the real attribute (of * course). The AttributeProxy manages timeouts, stateless connections (new AttributeProxy() nearly always * works), and reconnection if the device server is restarted. * * $Author: taurel $ * $Revision: 1 $ * * @headerfile tango.h * @ingroup Client */ class AttributeProxy { private : string attr_name; string device_name; string alias_name; Tango::DeviceProxy *dev_proxy; Tango::DbAttribute *db_attr; bool dbase_used; // Dev. with database bool from_env_var; // DB from TANGO_HOST string host; // DS host (if dbase_used=false) string port; // DS port (if dbase_used=false) int port_num; // DS port (as number) string db_host; // DB host string db_port; // DB port int db_port_num; // DB port (as number) void real_constructor(string &); void ctor_from_dp(const DeviceProxy *,string &); class AttributeProxyExt { public: AttributeProxyExt() {}; }; #ifdef HAS_UNIQUE_PTR unique_ptr ext; #else AttributeProxyExt *ext; // Class extension #endif public : ///@name Constructors //@{ /** * Create a AttributeProxy object. * * Create an AttributeProxy to an attribute of the specified name. The constructor will connect to the TANGO * database, query for the device to which the attribute belongs to network address and build a connection * to this device. If the device to which the attribute belongs to is defined in the TANGO database but the * device server is not running, AttributeProxy will try to build a connection every time the client tries to * access the attribute. If an alias name is defined for the attribute, this alias name can be used to create * the AttributeProxy instance. If a device name alias is defined for the device, it can be used instead of the * three fields device name. If the device to which the attribute belongs to is not defined in the database, an * exception is thrown. Examples : * @code * AttributeProxy *my_attr = new AttributeProxy("my/own/device/attr"); * AttributeProxy *my_attr_bis = new AttributeProxy("attr_alias"); * AttributeProxy *my_attr_ter = new AttributeProxy("dev_alias/attr"); * @endcode * * @param [in] name The attribute name */ AttributeProxy(string &name); /** * Create a AttributeProxy object. * * Idem previous constructor * * @param [in] name The attribute name */ AttributeProxy(const char *name); //@} ///@name Miscellaneous methods //@{ /** * Get attribute name * * Returns the attribute name * * @return The attribute name */ virtual inline string name() { return attr_name; } /** * Get associated DeviceProxy instance * * Returns the DeviceProxy instance used to communicate with the device to which the attributes belongs * * @return The underlying DeviceProxy object */ virtual inline DeviceProxy* get_device_proxy() { return dev_proxy; } /** * Get device status * * A method which return the status of the device to which the attribute belongs to. The status is returned as * a string. Example : * @code * cout << "device status: " << my_attr->status() << endl; * @endcode * * @return The underlying device status * @exception ConnectionFailed, CommunnicationFailed */ virtual string status(); /** * Get device state * * A method which returns the state of the device to which the attribute belongs to. This state is returned as a * Tango::DevState type. Example : * @code * dev_state = my_attr->state() << endl; * @endcode * * @return The underlying device state * @exception ConnectionFailed, CommunnicationFailed */ virtual DevState state(); /** * Ping the device * * A method which sends a ping to the device to which the attribute belongs and returns the time elapsed in * microseconds. Example : * @code * cout << "device ping took " << my_device->ping() << “ microseconds†<< endl; * @endcode * * @return Time needed by the ping call * @exception ConnectionFailed, CommunnicationFailed */ virtual int ping(); //@} ///@name Synchronous methods //@{ /** * Get attribute configuration * * Return the attribute configuration * * @return The attribute configuration data * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ virtual AttributeInfoEx get_config(); /** * Set attribute configuration * * Change the attribute configuration. * * @param [in] ai The new attribute configuration data * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device * @deprecated Use the set_config() method with AttributeInfoEx parameter data type */ virtual void set_config(AttributeInfo &ai); /** * Set extended attribute configuration * * Change the attribute configuration. * * @param [in] ai The new extended attribute configuration data * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ virtual void set_config(AttributeInfoEx &ai); /** * Read attribute value * * Read the attribute. To extract the value you have to use the operator of the class DeviceAttribute which * corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double (this * will return 0) you have to extract it as a short. * * @return The attribute value * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device */ virtual DeviceAttribute read(); /** * Write attribute value * * Write the attribute. To insert the value to write you have to use the operator of the class DeviceAttribute * which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the * user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this * will throw an exception) you have to insert it as a short. * * @param [in] da The new attribute value * @exception ConnectionFailed, CommunnicationFailed, DevUnlocked, DevFailed from device */ virtual void write(DeviceAttribute &da); /** * Write the Read attribute value * * Write then read a single attribute in a single network call. By default (serialisation by device), the execution * of this call in the server can’t be interrupted by other clients. To insert/extract the value to write/read you * have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. * NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an * attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it * as a short. * * @param [in] da The new attribute value * @return The new attribute value * @exception ConnectionFailed, CommunnicationFailed, DevUnlocked, DevFailed from device */ virtual DeviceAttribute write_read(DeviceAttribute &da); /** * Get attribute history from polling buffer * * Retrieve attribute history from the attribute polling buffer. The argument is the wanted history depth. This * method returns a vector of DeviceAttributeHistory types. This method allocates memory for the vector of * DeviceAttributeHistory returned to the caller. It is the caller responsibility to delete this memory. * See Tango book chapter on Advanced Feature for all details regarding * polling. * @code * AttributeProxy attr = new AttributeProxy("my/own/device/Current"); * vector *hist; * * hist = attr->history(5); * * for (int i = 0;i < 5;i++) * { * bool fail = (*hist)[i].has_failed(); * if (fail == false) * { * cout << "Attribute name = " << (*hist)[i].get_name() << endl; * cout << "Attribute quality factor = " << (*hist)[i].get_quality() << endl; * long value; * (*hist)[i] >> value; * cout << "Current = " << value << endl; * } * else * { * cout << "Attribute failed !" << endl; * cout << "Error level 0 desc = " << ((*hist)[i].get_err_stack())[0].desc << endl; * } * cout << "Date = " << (*hist)[i].get_date().tv_sec << endl; * } * delete hist; * @endcode * * @param [in] depth The required history depth * @return The attribute value history * @exception ConnectionFailed, CommunnicationFailed, NonSupportedFeature, DevFailed from device */ virtual vector *history(int depth); //@} ///@name Asynchronous methods //@{ /** * Read attribute value asynchronously in polling model * * Read the attribute asynchronously (polling model). This call returns an asynchronous call identifier which * is needed to get the attribute value. * * @return The asynchronous call identifier * @exception ConnectionFailed */ virtual long read_asynch() {return dev_proxy->read_attribute_asynch(attr_name);} /** * Get asynchronous read attribute call reply * * Check if the answer of an asynchronous read is arrived (polling model). id is the asynchronous call identifier. * If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. If * the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not * yet arrived. To extract attribute value, you have to use the operator of the class DeviceAttribute which corresponds * to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute * native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to * extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the caller. This * is the caller responsibility to delete this memory. * * @param [in] id The asynchronous identifier * @return The attribute value * @exception AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceAttribute *read_reply(long id) {return dev_proxy->read_attribute_reply(id);} /** * Get asynchronous read attribute call reply with timeout * * Check if the answer of an asynchronous read is arrived (polling model). id is the asynchronous call identifier. * If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. * If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait * (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not * there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract attribute * value, you have to use the operator of the class DeviceAttribute which corresponds to the data type of the * attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an * attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been * allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to delete this * memory. * * @param [in] id The asynchronous identifier * @param [in] to The timeout value * @return The attribute value * @exception AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual DeviceAttribute *read_reply(long id,long to) {return dev_proxy->read_attribute_reply(id,to);} /** * Write attribute value asynchrnously in polling model * * Write the attribute asynchronously (polling model). To insert the value to write you have to use the operator * of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no * automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short * you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This call * returns an asynchronous call identifier which is needed to get the server reply. * * @param [in] da The attribute value * @return The asynchrnous call identifier * @exception ConnectionFailed */ virtual long write_asynch(DeviceAttribute &da) {return dev_proxy->write_attribute_asynch(da);} /** * Get asynchronous write attribute call reply * * Check if the answer of an asynchronous write is arrived (polling model). id is the asynchronous call * identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is * re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. * * @param [in] id The asynchronous identifier * @exception AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_reply(long id) {dev_proxy->write_attribute_reply(id);} /** * Get asynchronous write attribute call reply with timeout * * Check if the answer of an asynchronous write is arrived (polling model). id is the asynchronous call * identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is * re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time * specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If * timeout is set to 0, the call waits until the reply arrived. * * @param [in] id The asynchronous identifier * @param [in] to The timeout value * @exception AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device */ virtual void write_reply(long id,long to) {dev_proxy->write_attribute_reply(id,to);} /** * Read attribute asynchronously in callback model * * Read the attribute asynchronously using the callback model. The argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the attr_read() method overloaded. * * @param [in] cb The callback object * @exception ConnectionFailed */ virtual void read_asynch(CallBack &cb) {dev_proxy->read_attribute_asynch(attr_name,cb);} /** * Write attribute asynchronously in callback model * * Write the attribute asynchronously using the callback model. The argument is a reference to a callback * object. This callback object should be an instance of a user class inheriting from the Tango::CallBack class * with the attr_written() method overloaded. * * @param [in] da The new attribute value * @param [in] cb The callback object * @exception ConnectionFailed */ virtual void write_asynch(DeviceAttribute &da,CallBack &cb) {dev_proxy->write_attribute_asynch(da,cb);} //@} ///@name Polling related methods //@{ /** * Check if the attribute is polled * * Returns true if the attribute is polled. Otherwise, returns false. * * @return Boolean true id the attribute is polled */ virtual bool is_polled(); /** * Get attribute polling period * * Returns the attribute polling period in mS. If the attribute is not polled, it returns 0. * * @return The polling period */ virtual int get_poll_period(); /** * Set attribute polling period * * Add the attribute to the list of polled attributes. The polling period is specified by "period" (in mS). If the * attribute is already polled, this method will update the polling period according to "period". * * @param [in] period The polling period */ virtual void poll(int period); /** * Stop attribute polling * * Remove attribute from the list of polled attributes. */ virtual void stop_poll(); //@} ///@name Event related methods //@{ /** * Subscribe to attribute event * * The client call to subscribe for event reception in the pushmodel. The client implements a callbackmethod * which is triggered when the event is received either by polling or a dedicated thread. Filtering is done based * on the reason specified and the event type. For example when reading the state and the reason specified is * "change" the event will be fired only when the state changes. Events consist of an attribute name and the * event reason. A standard set of reasons are implemented by the system, additional device specific reasons * an be implemented by device servers programmers. * cb is a pointer to a class inheriting fromthe Tango CallBack class and implementing a push_event() method. * The lifetime of the pointed to object must at least * be equal to the time when events are requested because only the pointer is stored into the event machinery. * The subscribe_event() * call returns an event id which has to be specified when unsubscribing from this event. * * @param [in] event The event type (reason) * @param [in] cb The event callback * @return The event identifier * @exception EventSystemFailed */ virtual int subscribe_event (EventType event, CallBack *cb); /** * Stateless subscription to attribute event * * This subscribe event method has the same functionality as described in the last section. It adds an additional * flag called stateless. When the stateless flag is set to false, an exception will be thrown when the event * subscription encounters a problem. * With the stateless flag set to true, the event subscription will always succeed, even if the corresponding * device server is not running. The keep alive thread will try every 10 seconds to subscribe for the specified * event. At every subscription retry, a callback is executed which contains the corresponding exception. * * @param [in] event The event type (reason) * @param [in] cb The event callback * @param [in] stateless The stateless flag * @return The event identifier * @exception EventSystemFailed */ virtual int subscribe_event (EventType event, CallBack *cb,bool stateless); /** * Stateless subscription to attribute event with event queue * * The client call to subscribe for event reception in the pull model. Instead of a callback method the client * has to specify the size of the event reception buffer. * The event reception buffer is implemented as a round robin buffer. This way the client can set-up * different ways to receive events. * @li Event reception buffer size = 1 : The client is interested only in the value of the last event received. All * other events that have been received since the last reading are discarded. * @li Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When * more events arrive since the last reading, older events will be discarded. * @li Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size is * unlimited and only restricted by the available memory for the client. * * All other parameters are similar to the descriptions given in the last two sections. * * @param [in] event The event type (reason) * @param [in] event_queue_size The event queue size * @param [in] stateless The stateless flag * @return The event identifier * @exception EventSystemFailed */ virtual int subscribe_event (EventType event, int event_queue_size, bool stateless = false); /** * Unsubsribe to attribute event * * Unsubscribe a client from receiving the event specified by event_id. event_id is the event identifier returned * by the AttributeProxy::subscribe_event() method. * * @param [in] ev_id The event identifier * @exception EventSystemFailed */ virtual void unsubscribe_event (int ev_id) {dev_proxy->unsubscribe_event(ev_id);} /** * Get events from event queue (pull model) * * The method extracts all waiting events from the event reception buffer and executes the callback method * cb for every event. During event subscription the client must have chosen the pull model for this event. * event_id is the event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @param [in] cb The event callback * @exception EventSystemFailed */ virtual void get_events (int event_id, CallBack *cb) {dev_proxy->get_events (event_id, cb);} /** * Get events from event queue (pull model) * * The method extracts all waiting events from the event reception buffer. The returned event_list is a vector * of EventData pointers. The EventData object contains the event information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @param [out] event_list The event list * @exception EventSystemFailed */ virtual void get_events (int event_id, EventDataList &event_list) {dev_proxy->get_events (event_id, event_list);} /** * Get events from event queue (pull model) * * The method extracts all waiting attribute configuration events from the event reception buffer. The returned * event_list is a vector of AttrConfEventData pointers. The AttrConfEventData object contains the event * information as for the callback methods. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @param [out] event_list The event list * @exception EventSystemFailed */ virtual void get_events (int event_id, AttrConfEventDataList &event_list) {dev_proxy->get_events (event_id, event_list);} /** * Get events number in queue * * Returns the number of stored events in the event reception buffer. After every call to DeviceProxy:get_events(), * the event queue size is 0. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @return The event number in the queue * @exception EventSystemFailed */ virtual int event_queue_size(int event_id) {return dev_proxy->event_queue_size(event_id);} /** * Get last event date * * Returns the arrival time of the last event stored in the event reception buffer. After every call to * AttributeProxy:get_events(), the event reception buffer is empty. In this case an exception will be returned. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @return The last event date * @exception EventSystemFailed */ virtual TimeVal get_last_event_date(int event_id) {return dev_proxy->get_last_event_date(event_id);} /** * Check if the event queue is empty * * Returns true when the event reception buffer is empty. * During event subscription the client must have chosen the pull model for this event. event_id is the * event identifier returned by the AttributeProxy::subscribe_event()method. * * @param [in] event_id The event identifier * @return The event queue empty flag * @exception EventSystemFailed */ virtual bool is_event_queue_empty(int event_id) {return dev_proxy->is_event_queue_empty(event_id);} //@} ///@name Property related methods //@{ /** * Get single attribute property * * Get a single property for the attribute. The property to get is specified as a string. Refer to DbDevice:: * get_property() and DbData sections for details on the DbData type. * * @param [in] prop_name The property name * @param [out] db Property value * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void get_property(string &prop_name, DbData &db); /** * Get multiple attribute property * * Get a list of properties for the attribute. The properties to get are specified as a vector of strings. Refer to * DbDevice::get_property() and DbData sections for details on the DbData type. * * @param [in] prop_names The property names * @param [out] db Properties value * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void get_property(vector &prop_names, DbData &db); /** * Get attribute property(ies) * * Get property(ies) for the attribute. Properties to get are specified using the DbData type. Refer to DbDevice:: * get_property() and DbData sections for details. * * @param [in,out] db Properties value * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void get_property(DbData &db); /** * Put attribute property(ies) * * Put property(ies) for an attribute. Properties to put are specified using the DbData type. Refer to DbDevice:: * put_property() and DbData sections for details. * * @param [in,out] db Properties value * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void put_property(DbData &db); /** * Delete a single attribute property * * Delete a single property for an attribute. The property to delete is specified as a string. Refer to DbDevice:: * delete_property() and DbData sections for details on the DbData type. * * @param [in] prop_name The property name * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void delete_property(string &prop_name); /** * Delete a list of attribute property * * Delete a list of properties for an attribute. The properties to delete are specified as a vector of strings. Refer * to DbDevice::get_property() and DbData sections for details on the DbData type. * * @param [in] prop_names The properties name * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void delete_property(vector &prop_names); /** * Delete attribute property(ies) * * Delete property(ies) for an attribute. Properties to delete are specified using the DbData type. Refer to * DbDevice::get_property() and DbData sections for details. * * @param [in] db The properties name * @exception NonDbDevice, ConnectionFailed, CommunicationFailed, DevFailed from database */ virtual void delete_property(DbData &db); //@} /// @privatesection // // general methods // virtual void parse_name(string &); virtual void set_transparency_reconnection(bool); virtual bool get_transparency_reconnection(); // // Old event methods // virtual int subscribe_event (EventType event, CallBack *,const vector &filters); // For compatibility virtual int subscribe_event (EventType event, CallBack *,const vector &filters, bool stateless); // For compatibility virtual int subscribe_event (EventType event, int event_queue_size,const vector &filters, bool stateless = false); // For compatibility AttributeProxy(const DeviceProxy *,string &); AttributeProxy(const DeviceProxy *,const char *); AttributeProxy(const AttributeProxy &); AttributeProxy & operator=(const AttributeProxy &); virtual ~AttributeProxy(); }; #endif /* _ATTRIBUTEPROXY_H */ tango-9.2.5a/lib/cpp/client/event.tpp0000644023471100065110000000501513034744772014416 00000000000000 //==================================================================================================================== // // file : event.tpp // // description : C++ classes for implementing the template method(s) of the EventConsumer class // // author(s) : E. Taurel // // original : March 2014 // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 25249 $ // // //==================================================================================================================== using namespace CORBA; namespace Tango { //+----------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::attr_to_device() // // description : // Method to initialize in the DeviceAttribute instance given to the user the attribute value which are received // in a AttrValUnion (or in a class inheriting from) // // argument : // in : // - attr_value : // out : // - dev_attr : // //------------------------------------------------------------------------------------------------------------------- template inline void EventConsumer::base_attr_to_device(const T *attr_value,DeviceAttribute *dev_attr) { dev_attr->name = attr_value->name; dev_attr->quality = attr_value->quality; dev_attr->time = attr_value->time; dev_attr->dim_x = attr_value->r_dim.dim_x; dev_attr->dim_y = attr_value->r_dim.dim_y; dev_attr->set_w_dim_x(attr_value->w_dim.dim_x); dev_attr->set_w_dim_y(attr_value->w_dim.dim_y); dev_attr->err_list = new DevErrorList(attr_value->err_list); dev_attr->data_format = attr_value->data_format; if (dev_attr->quality != Tango::ATTR_INVALID) { att_union_to_device(&attr_value->zvalue,dev_attr); } } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/client/devapi_attr.tpp0000644023471100065110000002375513034744772015612 00000000000000//+=================================================================================================================== // // file : devapi_att.tpp // // description : C++ source code for the Attribute class template methods when they are not specialized and // related to attribute value setting // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _DEVAPI_ATTR_TPP #define _DEVAPI_ATTR_TPP #ifdef HAS_TYPE_TRAITS #include #endif namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceAttribute::DeviceAttribute // // description : // The DeviceAttribute class constructors used for enumeration. They are implemented as template methods // //------------------------------------------------------------------------------------------------------------------- template DeviceAttribute::DeviceAttribute(string &_name,T _val):ext(new DeviceAttributeExt) { name = _name; base_val(_val); } template DeviceAttribute::DeviceAttribute(const char *_name,T _val):ext(new DeviceAttributeExt) { name = _name; base_val(_val); } template void DeviceAttribute::base_val(T _val) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq->length(1); ShortSeq[0] = static_cast(_val); } //----------------------------------------------------------------------------------------------------------------- template DeviceAttribute::DeviceAttribute(string &_name,vector &_val):ext(new DeviceAttributeExt) { name = _name; dim_x = _val.size(); base_vect(_val); } template DeviceAttribute::DeviceAttribute(const char *_name,vector &_val):ext(new DeviceAttributeExt) { name = _name; dim_x = _val.size(); base_vect(_val); } template void DeviceAttribute::base_vect(vector &_val) { dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq->length(_val.size()); for (size_t loop = 0;loop < _val.size();loop++) ShortSeq[loop] = static_cast(_val[loop]); } //----------------------------------------------------------------------------------------------------------------- template DeviceAttribute::DeviceAttribute(string &_name,vector &_val,int _x,int _y):ext(new DeviceAttributeExt) { name = _name; dim_x = _x; dim_y = _y; base_vect_size(_val); } template DeviceAttribute::DeviceAttribute(const char *_name,vector &_val,int _x,int _y):ext(new DeviceAttributeExt) { name = _name; dim_x = _x; dim_y = _y; base_vect_size(_val); } template void DeviceAttribute::base_vect_size(vector &_val) { w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq->length(_val.size()); for (size_t loop = 0;loop < _val.size();loop++) ShortSeq[loop] = static_cast(_val[loop]); } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceAttribute::operator >> // // description : // Extractor method used for enumeration. It is implemented as a template method // // argument : // out : // - datum : The enumeration to be filled in // //------------------------------------------------------------------------------------------------------------------- template bool DeviceAttribute::operator >> (T &datum) { bool ret = true; // // Some check on provided type (for modern compiler...) // ret = template_type_check(datum); // // check for available data // if (ret == true) { ret = check_for_data(); if (ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) datum = static_cast(ShortSeq[0]); else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } } return ret; } template bool DeviceAttribute::operator >> (vector &datum) { bool ret = true; // // Some check on provided type (for modern compiler...) // T dummy; ret = template_type_check(dummy); // // check for available data // ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { datum.resize(ShortSeq->length()); for (size_t i=0; ilength(); i++) datum[i] = static_cast(ShortSeq[i]); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } template bool DeviceAttribute::extract_read (vector &_data) { bool ret = true; // // Some check on provided type (for modern compiler...) // T dummy; ret = template_type_check(dummy); // // check for available data // ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { size_t length = get_nb_read(); _data.resize(length); for (size_t i=0; i(ShortSeq[i]); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } template bool DeviceAttribute::extract_set(vector &_data) { bool ret = true; // // Some check on provided type (for modern compiler...) // T dummy; ret = template_type_check(dummy); // // check for available data // ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (ShortSeq->length()); // copy the set point values to the vector _data.resize(ShortSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) _data[k] = static_cast(ShortSeq[i]); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //+------------------------------------------------------------------------------------------------------------------- // // method : // DeviceAttribute::operator << // // description : // Insertor method used for enumeration. It is implemented as a template method // // argument : // out : // - datum : The enumeration to be filled in // //------------------------------------------------------------------------------------------------------------------- template void DeviceAttribute::operator << (T datum) { template_type_check(datum); dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarShortArray *short_vararr = new(DevVarShortArray); short_vararr->length(1); (*short_vararr)[0] = static_cast(datum); ShortSeq = short_vararr; del_mem(Tango::DEV_SHORT); } template void DeviceAttribute::operator << (vector &_datum) { T dummy; template_type_check(dummy); dim_x = _datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (ShortSeq.operator->() == NULL) { DevVarShortArray *short_vararr = new(DevVarShortArray); ShortSeq = short_vararr; } ShortSeq->length(_datum.size()); for (size_t loop = 0;loop < _datum.size();loop++) ShortSeq[loop] = static_cast(_datum[loop]); del_mem(Tango::DEV_SHORT); } template void DeviceAttribute::insert(vector &_datum,int _x,int _y) { *this << _datum; dim_x = _x; dim_y = _y; } template bool DeviceAttribute::template_type_check(T &_datum) { #ifdef HAS_UNDERLYING bool short_enum = is_same::type>::value; bool uns_int_enum = is_same::type>::value; if (short_enum == false && uns_int_enum == false) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception("API_IncompatibleAttrArgumentType", "Type provided for insertion is not a valid enum. Only C enum or C++11 enum with underlying short data type are supported", "DeviceAttribute::operator<<"); } return false; } #endif // HAS_UNDERLYING #ifdef HAS_TYPE_TRAITS if (is_enum::value == false) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception("API_IncompatibleAttrArgumentType", "Type provided for insertion is not an enumeration", "DeviceAttribute::operator<<"); } return false; } #endif // HAS_TYPE_TRAITS return true; } } // End of Tango namespace #endif // _DEVAPI_ATTR_TPP tango-9.2.5a/lib/cpp/client/devapi_utils.tpp0000644023471100065110000002407613034744772015775 00000000000000 //+================================================================================================================== // devapi_utils.cpp - C++ source code file for TANGO device api // // programmer(s) - Emmanuel Taurel(taurel@esrf.fr) // // original - March 2014 // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that 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 Lesser Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 25126 $ // //+================================================================================================================== using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method : // DeviceProxy::from_hist_2_AttHistory() // // description : // Convert the attribute history as returned by a IDL 4 device to the classical DeviceAttributeHistory format // //------------------------------------------------------------------------------------------------------------------- template void DeviceProxy::from_hist_2_AttHistory(T &hist,vector *ddh) { // // Check received data validity // if ((hist->quals.length() != hist->quals_array.length()) || (hist->r_dims.length() != hist->r_dims_array.length()) || (hist->w_dims.length() != hist->w_dims_array.length()) || (hist->errors.length() != hist->errors_array.length())) { Tango::Except::throw_exception((const char *)API_WrongHistoryDataBuffer, (const char *)"Data buffer received from server is not valid !", (const char *)"DeviceProxy::from_hist4_2_AttHistory"); } // // Get history depth // unsigned int h_depth = hist->dates.length(); // // Copy date and name in each history list element // unsigned int loop; for (loop = 0;loop < h_depth;loop++) { (*ddh)[loop].time = hist->dates[loop]; (*ddh)[loop].name = hist->name.in(); } // // Copy the attribute quality factor // int k; for (loop = 0;loop < hist->quals.length();loop++) { int nb_elt = hist->quals_array[loop].nb_elt; int start = hist->quals_array[loop].start; for (k = 0;k < nb_elt;k++) (*ddh)[start - k].quality = hist->quals[loop]; } // // Copy read dimension // for (loop = 0;loop < hist->r_dims.length();loop++) { int nb_elt = hist->r_dims_array[loop].nb_elt; int start = hist->r_dims_array[loop].start; for (k = 0;k < nb_elt;k++) { (*ddh)[start - k].dim_x = hist->r_dims[loop].dim_x; (*ddh)[start - k].dim_y = hist->r_dims[loop].dim_y; } } // // Copy write dimension // for (loop = 0;loop < hist->w_dims.length();loop++) { int nb_elt = hist->w_dims_array[loop].nb_elt; int start = hist->w_dims_array[loop].start; for (k = 0;k < nb_elt;k++) { (*ddh)[start - k].set_w_dim_x(hist->w_dims[loop].dim_x); (*ddh)[start - k].set_w_dim_y(hist->w_dims[loop].dim_y); } } // // Copy errors // for (loop = 0;loop < hist->errors.length();loop++) { int nb_elt = hist->errors_array[loop].nb_elt; int start = hist->errors_array[loop].start; for (k = 0;k < nb_elt;k++) { (*ddh)[start - k].failed(true); DevErrorList &err_list = (*ddh)[start - k].get_error_list(); err_list.length(hist->errors[loop].length()); for (unsigned int g = 0;g < hist->errors[loop].length();g++) { err_list[g] = (hist->errors[loop])[g]; } } } // // Get data type and data ptr // const Tango::DevVarDoubleArray *tmp_db; const Tango::DevVarShortArray *tmp_sh; const Tango::DevVarLongArray *tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; const Tango::DevVarStringArray *tmp_str; const Tango::DevVarFloatArray *tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; const Tango::DevVarUShortArray *tmp_ush; const Tango::DevVarCharArray *tmp_uch; const Tango::DevVarULongArray *tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; const Tango::DevVarStateArray *tmp_state; const Tango::DevVarEncodedArray *tmp_enc; long data_type = -1; unsigned int seq_size = 0; CORBA::TypeCode_var ty = hist->value.type(); if (ty->kind() != tk_null) { CORBA::TypeCode_var ty_alias = ty->content_type(); CORBA::TypeCode_var ty_seq = ty_alias->content_type(); switch (ty_seq->kind()) { case tk_long: data_type = DEV_LONG; hist->value >>= tmp_lg; seq_size = tmp_lg->length(); break; case tk_longlong: data_type = DEV_LONG64; hist->value >>= tmp_lg64; seq_size = tmp_lg64->length(); break; case tk_short: data_type = DEV_SHORT; hist->value >>= tmp_sh; seq_size = tmp_sh->length(); break; case tk_double: data_type = DEV_DOUBLE; hist->value >>= tmp_db; seq_size = tmp_db->length(); break; case tk_string: data_type = DEV_STRING; hist->value >>= tmp_str; seq_size = tmp_str->length(); break; case tk_float: data_type = DEV_FLOAT; hist->value >>= tmp_fl; seq_size = tmp_fl->length(); break; case tk_boolean: data_type = DEV_BOOLEAN; hist->value >>= tmp_boo; seq_size = tmp_boo->length(); break; case tk_ushort: data_type = DEV_USHORT; hist->value >>= tmp_ush; seq_size = tmp_ush->length(); break; case tk_octet: data_type = DEV_UCHAR; hist->value >>= tmp_uch; seq_size = tmp_uch->length(); break; case tk_ulong: data_type = DEV_ULONG; hist->value >>= tmp_ulg; seq_size = tmp_ulg->length(); break; case tk_ulonglong: data_type = DEV_ULONG64; hist->value >>= tmp_ulg64; seq_size = tmp_ulg64->length(); break; case tk_enum: data_type = DEV_STATE; hist->value >>= tmp_state; seq_size = tmp_state->length(); break; case tk_struct: data_type = DEV_ENCODED; hist->value >>= tmp_enc; seq_size = tmp_enc->length(); break; default: break; } } // // Copy data // int base = seq_size; for (loop = 0;loop < h_depth;loop++) { if (((*ddh)[loop].failed() == true) || ((*ddh)[loop].quality == Tango::ATTR_INVALID)) continue; // // Get the data length for this record // int r_dim_x = (*ddh)[loop].dim_x; int r_dim_y = (*ddh)[loop].dim_y; int w_dim_x = (*ddh)[loop].get_written_dim_x(); int w_dim_y = (*ddh)[loop].get_written_dim_y(); int data_length; (r_dim_y == 0) ? data_length = r_dim_x : data_length = r_dim_x * r_dim_y; (w_dim_y == 0) ? data_length += w_dim_x : data_length += (w_dim_x * w_dim_y); // // Real copy now // int ll = 0; switch (data_type) { case DEV_SHORT: (*ddh)[loop].ShortSeq = new DevVarShortArray(); (*ddh)[loop].ShortSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].ShortSeq[ll] = (*tmp_sh)[(base - data_length) + ll]; break; case DEV_LONG: (*ddh)[loop].LongSeq = new DevVarLongArray(); (*ddh)[loop].LongSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].LongSeq[ll] = (*tmp_lg)[(base - data_length) + ll]; break; case DEV_LONG64: (*ddh)[loop].Long64Seq = new DevVarLong64Array(); (*ddh)[loop].Long64Seq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].Long64Seq[ll] = (*tmp_lg64)[(base - data_length) + ll]; break; case DEV_FLOAT: (*ddh)[loop].FloatSeq = new DevVarFloatArray(); (*ddh)[loop].FloatSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].FloatSeq[ll] = (*tmp_fl)[(base - data_length) + ll]; break; case DEV_DOUBLE: (*ddh)[loop].DoubleSeq = new DevVarDoubleArray(); (*ddh)[loop].DoubleSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].DoubleSeq[ll] = (*tmp_db)[(base - data_length) + ll]; break; case DEV_STRING: (*ddh)[loop].StringSeq = new DevVarStringArray(); (*ddh)[loop].StringSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].StringSeq[ll] = (*tmp_str)[(base - data_length) + ll]; break; case DEV_BOOLEAN: (*ddh)[loop].BooleanSeq = new DevVarBooleanArray(); (*ddh)[loop].BooleanSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].BooleanSeq[ll] = (*tmp_boo)[(base - data_length) + ll]; break; case DEV_USHORT: (*ddh)[loop].UShortSeq = new DevVarUShortArray(); (*ddh)[loop].UShortSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].UShortSeq[ll] = (*tmp_ush)[(base - data_length) + ll]; break; case DEV_UCHAR: (*ddh)[loop].UCharSeq = new DevVarUCharArray(); (*ddh)[loop].UCharSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].UCharSeq[ll] = (*tmp_uch)[(base - data_length) + ll]; break; case DEV_ULONG: (*ddh)[loop].ULongSeq = new DevVarULongArray(); (*ddh)[loop].ULongSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].ULongSeq[ll] = (*tmp_ulg)[(base - data_length) + ll]; break; case DEV_ULONG64: (*ddh)[loop].ULong64Seq = new DevVarULong64Array(); (*ddh)[loop].ULong64Seq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].ULong64Seq[ll] = (*tmp_ulg64)[(base - data_length) + ll]; break; case DEV_STATE: (*ddh)[loop].StateSeq = new DevVarStateArray(); (*ddh)[loop].StateSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].StateSeq[ll] = (*tmp_state)[(base - data_length) + ll]; break; case DEV_ENCODED: (*ddh)[loop].EncodedSeq = new DevVarEncodedArray(); (*ddh)[loop].EncodedSeq->length(data_length); for (ll = 0;ll < data_length;ll++) (*ddh)[loop].EncodedSeq[ll] = (*tmp_enc)[(base - data_length) + ll]; break; } base = base - ll; } } } // End of namespace tango-9.2.5a/lib/cpp/client/api_util.tpp0000644023471100065110000002312713034744772015107 00000000000000 //+================================================================================================================== // // C++ source code file for TANGO api class ApiUtil template methods // // programmer - Emmanuel Taurel (taurel@esrf.fr) // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that 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 Lesser Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // original - May 2002 // // $Revision: 25091 $ // //+================================================================================================================== namespace Tango { //----------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::attr_to_device_base() // // description : // // //------------------------------------------------------------------------------------------------------------------- template inline void ApiUtil::attr_to_device_base(const T *attr_value,DeviceAttribute *dev_attr) { CORBA::Long *tmp_lo; CORBA::Short *tmp_sh; CORBA::Double *tmp_db; char **tmp_str; CORBA::Float *tmp_fl; CORBA::Boolean *tmp_boo; CORBA::UShort *tmp_ush; CORBA::Octet *tmp_uch; CORBA::LongLong *tmp_lolo; CORBA::ULong *tmp_ulo; CORBA::ULongLong *tmp_ulolo; Tango::DevState *tmp_state; Tango::DevEncoded *tmp_enc; CORBA::ULong max,len; dev_attr->name = attr_value->name; dev_attr->quality = attr_value->quality; dev_attr->data_format = attr_value->data_format; dev_attr->time = attr_value->time; dev_attr->dim_x = attr_value->r_dim.dim_x; dev_attr->dim_y = attr_value->r_dim.dim_y; dev_attr->set_w_dim_x(attr_value->w_dim.dim_x); dev_attr->set_w_dim_y(attr_value->w_dim.dim_y); dev_attr->err_list = new DevErrorList(attr_value->err_list); if (dev_attr->quality != Tango::ATTR_INVALID) { switch (attr_value->value._d()) { case ATT_BOOL: { const DevVarBooleanArray &tmp_seq = attr_value->value.bool_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_boo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); } else { tmp_boo = const_cast(tmp_seq.get_buffer()); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,false); } } break; case ATT_SHORT: { const DevVarShortArray &tmp_seq = attr_value->value.short_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_sh = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); } else { tmp_sh = const_cast(tmp_seq.get_buffer()); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,false); } } break; case ATT_LONG: { const DevVarLongArray &tmp_seq = attr_value->value.long_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_lo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,true); } else { tmp_lo = const_cast(tmp_seq.get_buffer()); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,false); } } break; case ATT_LONG64: { const DevVarLong64Array &tmp_seq = attr_value->value.long64_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_lolo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,true); } else { tmp_lolo = const_cast(tmp_seq.get_buffer()); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,false); } } break; case ATT_FLOAT: { const DevVarFloatArray &tmp_seq = attr_value->value.float_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_fl = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); } else { tmp_fl = const_cast(tmp_seq.get_buffer()); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,false); } } break; case ATT_DOUBLE: { const DevVarDoubleArray &tmp_seq = attr_value->value.double_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_db = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); } else { tmp_db = const_cast(tmp_seq.get_buffer()); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,false); } } break; case ATT_UCHAR: { const DevVarCharArray &tmp_seq = attr_value->value.uchar_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_uch = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); } else { tmp_uch = const_cast(tmp_seq.get_buffer()); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,false); } } break; case ATT_USHORT: { const DevVarUShortArray &tmp_seq = attr_value->value.ushort_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ush = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); } else { tmp_ush = const_cast(tmp_seq.get_buffer()); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,false); } } break; case ATT_ULONG: { const DevVarULongArray &tmp_seq = attr_value->value.ulong_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ulo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); } else { tmp_ulo = const_cast(tmp_seq.get_buffer()); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,false); } } break; case ATT_ULONG64: { const DevVarULong64Array &tmp_seq = attr_value->value.ulong64_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ulolo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); } else { tmp_ulolo = const_cast(tmp_seq.get_buffer()); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,false); } } break; case ATT_STRING: { const DevVarStringArray &tmp_seq = attr_value->value.string_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_str = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,true); } else { tmp_str = const_cast(tmp_seq.get_buffer()); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,false); } } break; case ATT_STATE: { const DevVarStateArray &tmp_seq = attr_value->value.state_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_state = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,true); } else { tmp_state = const_cast(tmp_seq.get_buffer()); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,false); } } break; case DEVICE_STATE: { dev_attr->d_state = attr_value->value.dev_state_att(); dev_attr->d_state_filled = true; } break; case ATT_ENCODED: { const DevVarEncodedArray &tmp_seq = attr_value->value.encoded_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_enc = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->EncodedSeq = new DevVarEncodedArray(max,len,tmp_enc,true); } else { tmp_enc = const_cast(tmp_seq.get_buffer()); dev_attr->EncodedSeq = new DevVarEncodedArray(max,len,tmp_enc,false); } } break; case ATT_NO_DATA: break; } } } } // End of tango namespace tango-9.2.5a/lib/cpp/client/devapi_pipe.tpp0000644023471100065110000001257413034744772015572 00000000000000//+=================================================================================================================== // // file : devapi_pipe.tpp // // description : C++ source code for the DevicePipe class template methods/functions // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 17240 $ // //-=================================================================================================================== #ifndef _DEVAPI_PIPE_TPP #define _DEVAPI_PIPE_TPP namespace Tango { //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : << // // description : // Helper function to ease data insertion into DevicePipe/DevicePipeBlob instance // //------------------------------------------------------------------------------------------------------------------- template DevicePipe &operator<<(DevicePipe &_dp,T &datum) { _dp.get_root_blob().operator<<(datum); return _dp; } template DevicePipe &operator<<(DevicePipe &_dp,T *datum) { _dp.get_root_blob().operator<<(datum); return _dp; } template DevicePipe &operator<<(DevicePipe &_dp,DataElement &datum) { _dp.get_root_blob().set_current_delt_name(datum.name); _dp.get_root_blob().operator<<(datum.value); return _dp; } template DevicePipeBlob &operator<<(DevicePipeBlob &_dp,T &datum) { _dp.operator<<(datum); return _dp; } template DevicePipeBlob &operator<<(DevicePipeBlob &_dp,T *datum) { _dp.operator<<(datum); return _dp; } template DevicePipeBlob &operator<<(DevicePipeBlob &_dp,DataElement &datum) { _dp.set_current_delt_name(datum.name); _dp.operator<<(datum.value); return _dp; } //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : >> // // description : // Helper function to ease data extraction from DevicePipe root blob // //------------------------------------------------------------------------------------------------------------------- template DevicePipe &operator>>(DevicePipe &_dp,T &datum) { _dp.get_root_blob().operator>>(datum); return _dp; } template DevicePipe &operator>>(DevicePipe &_dp,T *datum) { _dp.get_root_blob().operator>>(datum); return _dp; } template DevicePipe &operator>>(DevicePipe &_dp,DataElement &datum) { datum.name = _dp.get_root_blob().get_current_delt_name(); _dp.get_root_blob().operator>>(datum.value); return _dp; } template DevicePipeBlob &operator>>(DevicePipeBlob &_dp,T &datum) { _dp.operator>>(datum); return _dp; } template DevicePipeBlob &operator>>(DevicePipeBlob &_dp,T *datum) { _dp.operator>>(datum); return _dp; } template DevicePipeBlob &operator>>(DevicePipeBlob &_dp,DataElement &datum) { datum.name = _dp.get_current_delt_name(); _dp.operator>>(datum.value); return _dp; } //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : >> // // description : // Helper function to ease printing of DataElement class instances: For basic type, for vector of basic type // and for CORBA sequence ptr // //------------------------------------------------------------------------------------------------------------------- template ostream &operator<<(ostream &str,DataElement &dd) { str << "Name = " << dd.name << " - Value = " << dd.value; return str; } template <> ostream &operator<<(ostream &str,DataElement &dd) { str << "Name = " << dd.name << " - Value = " << dd.value; return str; } template ostream &operator<<(ostream &str,DataElement > &dd) { str << "Name = " << dd.name << " - Value = "; for (size_t loop = 0;loop < dd.value.size();loop++) { str << dd.value[loop]; if (loop <= dd.value.size() - 2) str << ", "; } return str; } template ostream &operator<<(ostream &str,DataElement &dd) { str << "Name = " << dd.name << " - Value = "; for (size_t loop = 0;loop < dd.value->length();loop++) { str << (*dd.value)[loop]; if (loop <= dd.value->length() - 2) str << ", "; } return str; } template <> ostream &operator<<(ostream &str,DataElement &dd) { str << "Name = " << dd.name << "- Value = "; dd.value.print(str,0,true); dd.value.print(str,0,false); return str; } } // End of Tango namespace #endif // _DEVAPI_PIPE_TPP tango-9.2.5a/lib/cpp/client/zmq.hpp0000644023471100065110000001623113034744772014072 00000000000000/* Copyright (c) 2007-2011 iMatix Corporation Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file This file is part of 0MQ. 0MQ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 0MQ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef __ZMQ_HPP_INCLUDED__ #define __ZMQ_HPP_INCLUDED__ #include #include #include #include namespace zmq { typedef zmq_free_fn free_fn; typedef zmq_pollitem_t pollitem_t; class error_t : public std::exception { public: error_t () : errnum (zmq_errno ()) {} virtual const char *what () const throw () { return zmq_strerror (errnum); } int num () const { return errnum; } private: int errnum; }; inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1) { int rc = zmq_poll (items_, nitems_, timeout_); if (rc < 0) throw error_t (); return rc; } inline void version (int *major_, int *minor_, int *patch_) { zmq_version (major_, minor_, patch_); } class message_t { friend class socket_t; public: inline message_t () { int rc = zmq_msg_init (&msg); if (rc != 0) throw error_t (); } inline message_t (size_t size_) { int rc = zmq_msg_init_size (&msg, size_); if (rc != 0) throw error_t (); } inline message_t (void *data_, size_t size_, free_fn *ffn_, void *hint_ = NULL) { int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); if (rc != 0) throw error_t (); } inline ~message_t () { int rc = zmq_msg_close (&msg); assert (rc == 0); } inline void rebuild () { int rc = zmq_msg_close (&msg); if (rc != 0) throw error_t (); rc = zmq_msg_init (&msg); if (rc != 0) throw error_t (); } inline void rebuild (size_t size_) { int rc = zmq_msg_close (&msg); if (rc != 0) throw error_t (); rc = zmq_msg_init_size (&msg, size_); if (rc != 0) throw error_t (); } inline void rebuild (void *data_, size_t size_, free_fn *ffn_, void *hint_ = NULL) { int rc = zmq_msg_close (&msg); if (rc != 0) throw error_t (); rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_); if (rc != 0) throw error_t (); } inline void move (message_t *msg_) { int rc = zmq_msg_move (&msg, &(msg_->msg)); if (rc != 0) throw error_t (); } inline void copy (message_t *msg_) { int rc = zmq_msg_copy (&msg, &(msg_->msg)); if (rc != 0) throw error_t (); } inline void *data () { return zmq_msg_data (&msg); } inline size_t size () { return zmq_msg_size (&msg); } private: // The underlying message zmq_msg_t msg; // Disable implicit message copying, so that users won't use shared // messages (less efficient) without being aware of the fact. message_t (const message_t&); void operator = (const message_t&); }; class context_t { friend class socket_t; public: inline context_t (int io_threads_) { ptr = zmq_init (io_threads_); if (ptr == NULL) throw error_t (); } inline ~context_t () { int rc = zmq_term (ptr); assert (rc == 0); } // Be careful with this, it's probably only useful for // using the C api together with an existing C++ api. // Normally you should never need to use this. inline operator void* () { return ptr; } private: void *ptr; context_t (const context_t&); void operator = (const context_t&); }; class socket_t { public: inline socket_t (context_t &context_, int type_) { ptr = zmq_socket (context_.ptr, type_); if (ptr == NULL) throw error_t (); } inline ~socket_t () { close(); } inline operator void* () { return ptr; } inline void close() { if(ptr == NULL) // already closed return ; int rc = zmq_close (ptr); if (rc != 0) throw error_t (); ptr = 0 ; } inline void setsockopt (int option_, const void *optval_, size_t optvallen_) { int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_); if (rc != 0) throw error_t (); } inline void getsockopt (int option_, void *optval_, size_t *optvallen_) { int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_); if (rc != 0) throw error_t (); } inline void bind (const char *addr_) { int rc = zmq_bind (ptr, addr_); if (rc != 0) throw error_t (); } inline void connect (const char *addr_) { int rc = zmq_connect (ptr, addr_); if (rc != 0) throw error_t (); } inline void disconnect (const char *addr_) { int rc = zmq_disconnect (ptr, addr_); if (rc != 0) throw error_t (); } inline bool send (message_t &msg_, int flags_ = 0) { int nbytes = zmq_sendmsg (ptr, &(msg_.msg), flags_); if (nbytes >= 0) return true; if (zmq_errno () == EAGAIN) return false; throw error_t (); } inline bool recv (message_t *msg_, int flags_ = 0) { int nbytes = zmq_recvmsg (ptr, &(msg_->msg), flags_); if (nbytes >= 0) return true; if (zmq_errno () == EAGAIN) return false; throw error_t (); } private: void *ptr; socket_t (const socket_t&); void operator = (const socket_t&); }; } #endif tango-9.2.5a/lib/cpp/client/dbapi_class.cpp0000644023471100065110000002173613034744772015530 00000000000000static const char *RcsId = "$Id: dbapi_class.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //================================================================================================================== // // dbapi_class.cpp - C++ source code file for TANGO dbapi class DbClass // // programmer - Andy Gotz (goetz@esrf.fr) - E. Taurel // // original - October 2000 // // Copyright (C) : 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::DbClass() // // description: // Constructor to create a DbClass object for accessing a class of this name in the specified // TANGO database (import/export info and properties) // // argument: // in : // - class_name : The class name // - class_dbase : The database object ptr // //------------------------------------------------------------------------------------------------------------------ DbClass::DbClass(string class_name, Database *class_dbase):ext(Tango_nullptr) { name = string(class_name); dbase = class_dbase; ext_dbase = true; } DbClass::DbClass(string class_name):ext(Tango_nullptr) { name = string(class_name); db_ind = ApiUtil::instance()->get_db_ind(); ext_dbase = false; } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::~DbClass() // // description: // Destructor to destroy a DbClass object // //-------------------------------------------------------------------------------------------------------------------- DbClass::~DbClass() { } //--------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::get_property() // // description: // Public method to get class properties from the database // //--------------------------------------------------------------------------------------------------------------------- void DbClass::get_property(DbData &db_data) { // // Try to get db server cache in case we are called during a DS startup sequence // ApiUtil *au = ApiUtil::instance(); DbServerCache *dsc; if (au->in_server() == true) { Tango::Util *tg = Tango::Util::instance(); dsc = tg->get_db_cache(); } else dsc = NULL; // // Call DB (or cache) // if (ext_dbase == true) dbase->get_class_property(name, db_data, dsc); else { (au->get_db_vect())[db_ind]->get_class_property(name, db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::put_property() // // description: // Public method to put class properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::put_property(DbData &db_data) { // // Protect DS code againt a DB exception while the server is in its starting phase // ApiUtil *au = ApiUtil::instance(); bool forget_except = false; if (au->in_server() == true) { Tango::Util *tg = Tango::Util::instance(); if (tg->is_svr_starting() == true) { if (db_data.size() >= 2) { if ((db_data[0].name == POGO_TITLE) && (db_data[1].name == POGO_DESC)) forget_except = true; } } } // // Call DB // try { if (ext_dbase == true) dbase->put_class_property(name, db_data); else { (au->get_db_vect())[db_ind]->put_class_property(name, db_data); } } catch (Tango::DevFailed &) { if (forget_except == false) throw; } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::delete_property() // // description: // Public method to delete class properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::delete_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_class_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_class_property(name, db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::get_attribute_property() // // description: // Public method to get class attribute properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::get_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->get_class_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->get_class_attribute_property(name, db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::put_attribute_property() // // description: // Public method to put class attribute properties from the database // //------------------------------------------------------------------------------------------------------------------- void DbClass::put_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->put_class_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_class_attribute_property(name, db_data); } } //--------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::delete_attribute_property() // // descriptio: // Public method to delete class attribute properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::delete_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_class_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_class_attribute_property(name, db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::get_pipe_property() // // description: // Public method to get class pipe properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::get_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->get_class_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->get_class_pipe_property(name, db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::put_pipe_property() // // description: // Public method to put class pipe properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::put_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->put_class_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_class_pipe_property(name, db_data); } } //--------------------------------------------------------------------------------------------------------------------- // // method: // DbClass::delete_pipe_property() // // description: // Public method to delete class pipe properties from the database // //-------------------------------------------------------------------------------------------------------------------- void DbClass::delete_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_class_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_class_pipe_property(name, db_data); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_server.cpp0000644023471100065110000001202413034744772015717 00000000000000static const char *RcsId = "$Id: dbapi_server.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; // // dbdevice.cpp - C++ source code file for TANGO dbapi class DbServer // // programmer - Andy Gotz (goetz@esrf.fr) // // original - November 2000 // // Copyright (C) : 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DbServer::DbServer() - constructor to create a DbServer object for // accessing a server of this name in the specified // TANGO database (import/export info and properties) // //----------------------------------------------------------------------------- DbServer::DbServer(string server_name, Database *server_dbase):ext(Tango_nullptr) { name = string(server_name); dbase = server_dbase; ext_dbase = true; } //----------------------------------------------------------------------------- // // DbServer::DbServer() - constructor to create a DbServer object for // accessing a server of this name without specifying // the TANGO database. // //----------------------------------------------------------------------------- DbServer::DbServer(string server_name):ext(Tango_nullptr) { name = string(server_name); db_ind = ApiUtil::instance()->get_db_ind(); ext_dbase = false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // // DbServer::~DbServer() - destructor to destroy a DbServer object // //----------------------------------------------------------------------------- DbServer::~DbServer() { } //----------------------------------------------------------------------------- // // DbServer::add_server() - public method to add a server and its devices // to the database // //----------------------------------------------------------------------------- void DbServer::add_server(DbDevInfos &dev_infos) { if (ext_dbase == true) dbase->add_server(name, dev_infos); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->add_server(name, dev_infos); } } //----------------------------------------------------------------------------- // // DbServer::export_server() - public method to export devices belonging to // this server to the database // //----------------------------------------------------------------------------- void DbServer::export_server(DbDevExportInfos &dev_export) { if (ext_dbase == true) dbase->export_server(dev_export); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->export_server(dev_export); } } //----------------------------------------------------------------------------- // // DbServer::unexport_server() - public method to unexport all devices belonging // to this server in the database // //----------------------------------------------------------------------------- void DbServer::unexport_server() { if (ext_dbase == true) dbase->unexport_server(name); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->unexport_server(name); } } //----------------------------------------------------------------------------- // // DbServer::delete_server() - public method to delete all devices belonging // to this server from the database // //----------------------------------------------------------------------------- void DbServer::delete_server() { if (ext_dbase == true) dbase->delete_server(name); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_server(name); } } //----------------------------------------------------------------------------- // // DbServer::get_server_info() - public method to get server info // //----------------------------------------------------------------------------- DbServerInfo DbServer::get_server_info() { if (ext_dbase == true) return dbase->get_server_info(name); else { ApiUtil *au = ApiUtil::instance(); return (au->get_db_vect())[db_ind]->get_server_info(name); } } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_datum.cpp0000644023471100065110000011372613034744771015535 00000000000000static const char *RcsId = "$Id: dbapi_datum.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; // // dbdatum.cpp - C++ source code file for TANGO dbapi class DbDatum // // programmer - Andy Gotz (goetz@esrf.fr) // // original - October 2000 // // Copyright (C) : 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // #if HAVE_CONFIG_H #include #endif #include #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DbDatum::DbDatum() - constructor to create DbDatum specifying name // //----------------------------------------------------------------------------- DbDatum::DbDatum(string p_name):ext(Tango_nullptr) { name = p_name; value_size = 0; value_string.resize(0); } DbDatum::DbDatum(const char *p_name):name(p_name),ext(Tango_nullptr) { value_size = 0; value_string.resize(0); } //----------------------------------------------------------------------------- // // DbDatum::DbDatum() - constructor to create DbDatum without arguments // //----------------------------------------------------------------------------- DbDatum::DbDatum():ext(Tango_nullptr) { } //----------------------------------------------------------------------------- // // DbDatum::~DbDatum() - destructor to destroy DbDatum // //----------------------------------------------------------------------------- DbDatum::~DbDatum() { #ifndef HAS_UNIQUE_PTR #ifndef _TG_WINDOWS_ delete ext; #endif #endif } //----------------------------------------------------------------------------- // // DbDatum::DbDatum() - Copy constructor // //----------------------------------------------------------------------------- DbDatum::DbDatum(const DbDatum &source):ext(new DbDatumExt) { name = source.name; value_string = source.value_string; value_type = source.value_type; value_size = source.value_size; exceptions_flags = source.exceptions_flags; } //----------------------------------------------------------------------------- // // DbDatum::operator() - assignement operator // //----------------------------------------------------------------------------- DbDatum &DbDatum::operator=(const DbDatum &rval) { name = rval.name; value_string = rval.value_string; value_type = rval.value_type; value_size = rval.value_size; exceptions_flags = rval.exceptions_flags; #ifdef HAS_UNIQUE_PTR ext.reset(new DbDatumExt); #else if (rval.ext != NULL) { if (ext != Tango_nullptr) delete ext; ext = new DbDatumExt; *ext = *rval.ext; } #endif return *this; } //----------------------------------------------------------------------------- // // DbDatum::is_empty() - returns true or false if datum is empty // //----------------------------------------------------------------------------- bool DbDatum::is_empty() { if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"The DbDatum object is empty", (const char*)"DbDatum::is_empty"); } return true; } else { return false; } } //----------------------------------------------------------------------------- // // DbDatum::operator <<(bool &) - insert a boolean into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (bool datum) { ostringstream ostream; ostream << boolalpha << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_BOOLEAN; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(bool &) - extract a boolean from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (bool &datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"Cannot extract short, no data in DbDatum object ", (const char*)"DbDatum::operator >>(short)"); } ret = false; } else { transform(value_string[0].begin(), value_string[0].end(), value_string[0].begin(), ::tolower); istringstream istream(value_string[0]); istream >> boolalpha >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a short", (const char *)"DbDatum::operator >>(short)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(short &) - insert a short into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (short datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_SHORT; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(short &) - extract a short from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (short &datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"Cannot extract short, no data in DbDatum object ", (const char*)"DbDatum::operator >>(short)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a short", (const char *)"DbDatum::operator >>(short)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(unsigned char &) - insert a unsigned char into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (unsigned char datum) { ostringstream ostream; ostream << (short)datum; // to accept only numbers value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_UCHAR; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(unsigned char &) - extract a unsigned char from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (unsigned char& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned short, no data in DbDatum object ", (const char*)"DbDatum::operator >>(unsigned char)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not an unsigned short", (const char *)"DbDatum::operator >>(unsigned short)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(unsigned short &) - insert a unsigned short into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (unsigned short datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_USHORT; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(unsigned short &) - extract a unsigned short from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (unsigned short& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned short, no data in DbDatum object ", (const char*)"DbDatum::operator >>(unsigned short)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not an unsigned short", (const char *)"DbDatum::operator >>(unsigned short)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(DevLong &) - insert a DevLong into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (DevLong datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_LONG; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(DevLong &) - extract a long from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (DevLong& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDbDatum", (const char*)"cannot extract long, no data in DbDatum object ", (const char*)"DbDatum::operator >>(long)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a DevLong (long 32 bits)", (const char *)"DbDatum::operator >>(DevLong)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(DevULong &) - insert a unsigned short into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (DevULong datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_ULONG; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(DevULong &) - extract a DevULong from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (DevULong& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long, no data in DbDatum object ", (const char*)"DbDatum::operator >>(unsigned long)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a DevULong (unsigned long 32 bits)", (const char *)"DbDatum::operator >>(DevULong)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(DevLong64 &) - insert a DevLong64 into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (DevLong64 datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_LONG64; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(DevLong64 &) - extract a DevLong64 from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (DevLong64 &datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long, no data in DbDatum object ", (const char*)"DbDatum::operator >>(DevLong64)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a DevLong64 (long 64 bits)", (const char *)"DbDatum::operator >>(DevULong)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(DevULong64 &) - insert a DevULong64 into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (DevULong64 datum) { ostringstream ostream; ostream << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_ULONG64; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(DevULong64 &) - extract a DevULong64 from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (DevULong64 &datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long, no data in DbDatum object ", (const char*)"DbDatum::operator >>(DevLong64)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a DevULong64 (unsigned long 64 bits)", (const char *)"DbDatum::operator >>(DevULong)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(float &) - insert a float into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (float datum) { ostringstream ostream; ostream << std::setprecision(TANGO_FLOAT_PRECISION) << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_FLOAT; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(float &) - extract a float from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (float& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDbDatum", (const char*)"cannot extract float, no data in DbDatum object ", (const char*)"DbDatum::operator >>(float)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a float", (const char *)"DbDatum::operator >>(float)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(double &) - insert a double into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (double datum) { ostringstream ostream; ostream << setprecision(TANGO_FLOAT_PRECISION) << datum; value_string.resize(1); value_string[0] = string(ostream.str()); value_type = DEV_DOUBLE; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(double &) - extract a double from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (double& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract double, no data in DbDatum object ", (const char*)"DbDatum::operator >>(double)"); } ret = false; } else { istringstream istream(value_string[0]); istream >> std::setprecision(TANGO_FLOAT_PRECISION) >> datum; if (!istream) { if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char *)API_IncompatibleArgumentType, (const char *)"Cannot extract, data in DbDatum is not a double", (const char *)"DbDatum::operator >>(double)"); } ret = false; } else ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(string &) - insert a string into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (string& datum) { value_string.resize(1); value_string[0] = datum; value_type = DEV_STRING; value_size = 1; } //----------------------------------------------------------------------------- // // DbDatum::operator >>(string &) - extract a string from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (string& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract string, no data in DbDatum object ", (const char*)"DbDatum::operator >>(string)"); } ret = false; } else { datum = value_string[0]; ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(char* &) - insert a char* into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (char* datum) { value_string.resize(1); value_string[0] = datum; value_type = DEV_STRING; value_size = 1; } /*void DbDatum::operator << (char*& datum) { value_string.resize(1); value_string[0] = datum; value_type = DEV_STRING; value_size = 1; }*/ //----------------------------------------------------------------------------- // // DbDatum::operator <<(const char* &) - insert a const char* into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (const char* datum) { value_string.resize(1); value_string[0] = datum; value_type = DEV_STRING; value_size = 1; } /*void DbDatum::operator << (const char*& datum) { value_string.resize(1); value_string[0] = datum; value_type = DEV_STRING; value_size = 1; }*/ //----------------------------------------------------------------------------- // // DbDatum::operator >>(const char* &) - extract a const char* from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (const char*& datum) { bool ret; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract string, no data in DbDatum object ", (const char*)"DbDatum::operator >>(string)"); } ret = false; } else { datum = value_string[0].c_str(); ret = true; } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract short vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract short vector, elt number "; desc << i+1 << " is not a short" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned short vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract unsigned short vector, elt number "; desc << i+1 << " is not an unsigned short" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract long vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract long vector, elt number "; desc << i+1 << " is not a DevLong (long 32 bits)" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract unsigned long vector, elt number "; desc << i+1 << " is not a DevULong (unsigned long 32 bits)" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract unsigned long vector, elt number "; desc << i+1 << " is not a DevLong64 (long 64 bits)" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract unsigned long vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract unsigned long vector, elt number "; desc << i+1 << " is not a DevULong64 (unsigned long 64 bits)" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract float vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract float vector, elt number "; desc << i+1 << " is not a float" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { ostringstream ostream; value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract double vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { stringstream iostream; datum.resize(value_string.size()); for (unsigned int i=0; i> std::setprecision(TANGO_FLOAT_PRECISION) >> datum[i]; if (!iostream) { if (exceptions_flags.test(wrongtype_flag)) { TangoSys_OMemStream desc; desc << "Cannot extract double vector, elt number "; desc << i+1 << " is not a double" << ends; ApiDataExcept::throw_exception((const char*)API_IncompatibleArgumentType, desc.str(), (const char*)"DbDatum::operator >>(vector)"); } ret = false; break; } } } return ret; } //----------------------------------------------------------------------------- // // DbDatum::operator <<(vector &) - insert a vector into DbDatum // //----------------------------------------------------------------------------- void DbDatum::operator << (vector& datum) { value_string.resize(datum.size()); for (unsigned int i=0; i>(vector &) - extract a vector from DbDatum // //----------------------------------------------------------------------------- bool DbDatum::operator >> (vector& datum) { bool ret = true; if (value_string.size() == 0) { if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDbDatum", (const char*)"cannot extract string vector, no data in DbDatum object ", (const char*)"DbDatum::operator >>(vector)"); } datum.resize(0); ret = false; } else { datum.resize(value_string.size()); for (unsigned int i=0; i. // // // #if HAVE_CONFIG_H #include #endif #include #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // Database::Database() - constructor to create connection to TANGO Database // without arguments, host and port specified by // environment variable TANGO_HOST // Rem : For Windows, when the server is used as a // service, the TANGO_HOST environment // variable must be retrieved from the registry // from the device server exec name and instance // name // //----------------------------------------------------------------------------- Database::Database(ORB *orb_in) : Connection(orb_in), ext(new DatabaseExt), access_proxy(NULL),access_checked(false),access_service_defined(false),db_tg(NULL) { // // get host and port from environment variable TANGO_HOST // string tango_host_env_var; int ret; filedb = Tango_nullptr; serv_version = 0; ret = get_env_var(EnvVariable,tango_host_env_var); if (ret == -1) { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable not set, set it and retry (e.g. TANGO_HOST=:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } check_tango_host(tango_host_env_var.c_str()); cout4 <<"Database::Database(): TANGO host " << host << " port " << port << endl; build_connection(); set_server_release(); dev_name(); } #ifdef _TG_WINDOWS_ Database::Database(ORB *orb_in,string &ds_exec_name,string &ds_inst_name) : Connection(orb_in), ext(new DatabaseExt), access_proxy(NULL),access_checked(false),access_service_defined(false),db_tg(NULL) { // // get host and port from environment variable TANGO_HOST // char *tango_host_env_c_str; filedb = Tango_nullptr; serv_version = 0; if (get_tango_host_from_reg(&tango_host_env_c_str,ds_exec_name,ds_inst_name) == -1) tango_host_env_c_str = NULL; if (tango_host_env_c_str == NULL) { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable not set, set it and retry (e.g. TANGO_HOST=:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } check_tango_host(tango_host_env_c_str); delete [] tango_host_env_c_str; cout4 <<"Database::Database(): TANGO host " << host << " port " << port << endl; build_connection(); set_server_release(); dev_name(); } #endif //+---------------------------------------------------------------------------- // // method : Database::check_tango_host() // // description : Check the TANGO_HOST environment variable syntax and // extract database server host(s) and port(s) from // it // // in : tango_host_env_c_str : The TANGO_HOST env. variable value // //----------------------------------------------------------------------------- void Database::check_tango_host(const char *tango_host_env_c_str) { filedb = Tango_nullptr; string tango_host_env(tango_host_env_c_str); string::size_type separator; db_multi_svc = false; separator = tango_host_env.find(','); if (separator != string::npos) { // // It is a multi db server system, extract each host and port and check // syntax validity (:,:) // db_multi_svc = true; separator = 0; string::size_type old_sep = separator; string::size_type host_sep; while((separator = tango_host_env.find(',',separator + 1)) != string::npos) { string sub = tango_host_env.substr(old_sep,separator - old_sep); old_sep = separator + 1; host_sep = sub.find(":"); if (host_sep != string::npos) { if ((host_sep == sub.size() - 1) || (host_sep == 0)) { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:,:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } multi_db_port.push_back(sub.substr(host_sep + 1)); } else { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:,:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } string tmp_host(sub.substr(0,host_sep)); if (tmp_host.find('.') == string::npos) get_fqdn(tmp_host); multi_db_host.push_back(tmp_host); } string last = tango_host_env.substr(old_sep); host_sep = last.find(":"); if (host_sep != string::npos) { if ((host_sep == last.size() - 1) || (host_sep == 0)) { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:,:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } multi_db_port.push_back(last.substr(host_sep + 1)); } else { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:,:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } string tmp_host(last.substr(0,host_sep)); if (tmp_host.find('.') == string::npos) get_fqdn(tmp_host); multi_db_host.push_back(tmp_host); db_port = multi_db_port[0]; db_host = multi_db_host[0]; db_port_num = atoi(db_port.c_str()); } else { // // Single database server case // separator = tango_host_env.find(":"); if (separator != string::npos) { if ((separator == tango_host_env.size() - 1) || (separator == 0)) { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } db_port = tango_host_env.substr(separator+1); db_port_num = atoi(db_port.c_str()); } else { TangoSys_MemStream desc; desc << "TANGO_HOST env. variable syntax incorrect (e.g. TANGO_HOST=:)" << ends; ApiConnExcept::throw_exception((const char *)API_TangoHostNotSet, desc.str(), (const char *)"Database::Database"); } db_host = tango_host_env.substr(0,separator); // // If localhost is used as host name, try to replace it by the real host name // string db_host_lower(db_host); transform(db_host_lower.begin(),db_host_lower.end(),db_host_lower.begin(),::tolower); if (db_host_lower == "localhost") { char h_name[80]; int res = gethostname(h_name,80); if (res == 0) { db_host = h_name; tango_host_localhost = true; } } // // Get FQDN but store original TANGO_HOST (for event in case of alias used in TANGO_HOST) // ext->orig_tango_host = db_host; if (db_host.find('.') == string::npos) { get_fqdn(db_host); string::size_type pos = db_host.find('.'); if (pos != string::npos) { string fq = db_host.substr(pos); ext->orig_tango_host = ext->orig_tango_host + fq; } } } host = db_host; port = db_port; port_num = db_port_num; dbase_used = true; from_env_var = true; } //----------------------------------------------------------------------------- // // Database::Database(string host, int port, ORB *orb) - constructor to // create connection to TANGO Database with host, port, orb specified. // //----------------------------------------------------------------------------- Database::Database(string &in_host, int in_port, ORB *orb_in) : Connection(orb_in), ext(new DatabaseExt), access_proxy(NULL),access_checked(false),access_service_defined(false),db_tg(NULL) { filedb = Tango_nullptr; serv_version = 0; db_multi_svc = false; host = in_host; db_host = host; TangoSys_MemStream o; o << in_port << ends; string st = o.str(); port = st.c_str(); db_port = port; db_port_num = in_port; port_num = in_port; from_env_var = false; dbase_used = true; build_connection(); set_server_release(); dev_name(); } Database::Database(string &name) : Connection(true), ext(new DatabaseExt), access_proxy(NULL),access_checked(false),access_service_defined(false),db_tg(NULL) { file_name = name; filedb = new FileDatabase(file_name); serv_version = 230; check_acc = false; } //----------------------------------------------------------------------------- // // Database::Database() - copy constructor // //----------------------------------------------------------------------------- Database::Database(const Database &sou):Connection(sou),ext(Tango_nullptr) { // // Copy Database members // db_multi_svc = sou.db_multi_svc; multi_db_port = sou.multi_db_port; multi_db_host = sou.multi_db_host; file_name = sou.file_name; if (sou.filedb == Tango_nullptr) filedb = Tango_nullptr; else filedb = new FileDatabase(file_name); serv_version = sou.serv_version; if (sou.access_proxy == Tango_nullptr) access_proxy = Tango_nullptr; else access_proxy = new AccessProxy(sou.access_proxy->name().c_str()); access_checked = sou.access_checked; access_except_errors = sou.access_except_errors; dev_class_cache = sou.dev_class_cache; db_device_name = sou.db_device_name; access_service_defined = sou.access_service_defined; db_tg = sou.db_tg; // // Copy extension class // #ifdef HAS_UNIQUE_PTR if (sou.ext.get() != NULL) { ext.reset(new DatabaseExt); } #else if (sou.ext == NULL) ext = NULL; else { ext = new DatabaseExt(); } #endif } //----------------------------------------------------------------------------- // // Database::Database() - assignement operator // //----------------------------------------------------------------------------- Database &Database::operator=(const Database &rval) { if (this != &rval) { this->Connection::operator=(rval); // // Now Database members // db_multi_svc = rval.db_multi_svc; multi_db_port = rval.multi_db_port; multi_db_host = rval.multi_db_host; file_name = rval.file_name; serv_version = rval.serv_version; delete filedb; if (rval.filedb == Tango_nullptr) filedb = Tango_nullptr; else filedb = new FileDatabase(file_name); delete access_proxy; if (rval.access_proxy == Tango_nullptr) access_proxy = Tango_nullptr; else access_proxy = new AccessProxy(rval.access_proxy->name().c_str()); access_checked = rval.access_checked; access_except_errors = rval.access_except_errors; dev_class_cache = rval.dev_class_cache; db_device_name = rval.db_device_name; access_service_defined = rval.access_service_defined; db_tg = rval.db_tg; #ifdef HAS_UNIQUE_PTR if (rval.ext.get() != NULL) { ext.reset(new DatabaseExt); } else ext.reset(); #else delete ext; if (rval.ext != NULL) { ext = new DatabaseExt; } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // Database::check_access_and_get() - Check if the access has been retrieved // and get it if not. // Protect this code using a TangoMonitor defined in the Connection class // //----------------------------------------------------------------------------- void Database::check_access_and_get() { bool local_access_checked; { ReaderLock guard(con_to_mon); local_access_checked = access_checked; } if (local_access_checked == false) { WriterLock guard(con_to_mon); if (access_checked == false) check_access(); } } //----------------------------------------------------------------------------- // // Database::set_server_release() - Check which is the database server release // //----------------------------------------------------------------------------- void Database::set_server_release() { try { DevCmdInfo *cmd_ptr = device->command_query("DbDeleteAllDeviceAttributeProperty"); serv_version = 400; delete cmd_ptr; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),API_CommandNotFound) == 0) { try { DevCmdInfo *cmd_ptr = device->command_query("DbGetDeviceAttributeProperty2"); serv_version = 230; delete cmd_ptr; } catch (Tango::DevFailed &e) { serv_version = 210; } } else serv_version = 210; } } //----------------------------------------------------------------------------- // // Database::get_file_name() - Get file name when the database is a file // //----------------------------------------------------------------------------- const string &Database::get_file_name() { if (filedb == 0) { Tango::Except::throw_exception ((const char *)API_NotSupportedFeature, (const char *)"The database is not a file-based database", (const char *)"Database::get_file_name"); } return file_name; } //----------------------------------------------------------------------------- // // Database::~Database() - destructor to destroy connection to TANGO Database // //----------------------------------------------------------------------------- Database::~Database() { if (filedb != 0) { write_filedatabase(); delete filedb; } delete access_proxy; #ifndef HAS_UNIQUE_PTR delete ext; #endif } #ifdef _TG_WINDOWS_ //+---------------------------------------------------------------------------- // // method : Util::get_tango_host_from_reg() // // description : When the server is a Win32 service, it is not // possible to get the env. variable TANGO_HOST // value. In this case, the TANGO_HOST value is // stored in the WIN32 registry when the service is // installed and retrieved by this method. // //----------------------------------------------------------------------------- long Database::get_tango_host_from_reg(char **buffer, string &ds_exec_name, string &ds_instance_name) { // // Build the key name // HKEY regHandle = HKEY_LOCAL_MACHINE; string keyName("SYSTEM\\CurrentControlSet\\Services\\"); keyName = keyName + ds_exec_name + '_' + ds_instance_name; keyName = keyName + "\\Server"; // // Open the key. // HKEY keyHandle; if(::RegOpenKeyEx(regHandle,keyName.c_str(),0,KEY_ALL_ACCESS, &keyHandle) != ERROR_SUCCESS) { return -1; } // // Read the value // DWORD type,size; char tmp_buf[128]; size = 127; if (::RegQueryValueEx(keyHandle,"TangoHost",NULL,&type, (unsigned char *)tmp_buf, &size) != ERROR_SUCCESS) { return -1; } // // Store answer in caller parameter // *buffer = new char[strlen(tmp_buf) + 1]; strcpy(*buffer,tmp_buf); return 0; } #endif //----------------------------------------------------------------------------- // // Database::connect() - method to create connection to TANGO Database // specifying host and port // //----------------------------------------------------------------------------- void Database::write_filedatabase() { if (filedb != 0) filedb->write_file(); } void Database::reread_filedatabase() { delete filedb; filedb = new FileDatabase(file_name); } void Database::build_connection() { string corba_name = get_corba_name(true); // omniORB::setClientConnectTimeout(CORBA::ULong(DB_CONNECT_TIMEOUT)); try { connect(corba_name); // omniORB::setClientConnectTimeout(0); } catch (Tango::DevFailed &) { // omniORB::setClientConnectTimeout(0); throw; } return; } //----------------------------------------------------------------------------- // // Database::get_corba_name() - private method to return corba name // //----------------------------------------------------------------------------- string Database::get_corba_name(TANGO_UNUSED(bool ch_acc)) { string db_corbaloc; if (db_multi_svc == true) { db_corbaloc = "corbaloc:iiop:1.2@"; int nb_host = multi_db_host.size(); for (int i = 0;i < nb_host;i++) { db_corbaloc = db_corbaloc + multi_db_host[i]; db_corbaloc = db_corbaloc + ":" + multi_db_port[i]; if (i != nb_host - 1) db_corbaloc = db_corbaloc + ",iiop:1.2@"; } db_corbaloc = db_corbaloc + "/" + DbObjName; } else { db_corbaloc = "corbaloc:iiop:"; if (tango_host_localhost == true) db_corbaloc = db_corbaloc+"localhost:"; else db_corbaloc = db_corbaloc+db_host+":"; db_corbaloc = db_corbaloc+port+"/"+DbObjName; } return db_corbaloc; } //----------------------------------------------------------------------------- // // Database::post_reconnection() - do what is necessary after a db re-connection // //----------------------------------------------------------------------------- void Database::post_reconnection() { set_server_release(); dev_name(); } //----------------------------------------------------------------------------- // // Database::get_info() - public method to return info about the Database // //----------------------------------------------------------------------------- string Database::get_info() { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); if (filedb != 0) received = filedb->DbInfo(send); else CALL_DB_SERVER("DbInfo",send,received); const DevVarStringArray *db_info_list = NULL; received.inout() >>= db_info_list; ostringstream ostream; for (unsigned int i=0; ilength(); i++) { ostream << (*db_info_list)[i].in() << endl; } string ret_str = ostream.str(); return(ret_str); } //----------------------------------------------------------------------------- // // Database::import_device() - public method to return import info for a device // //----------------------------------------------------------------------------- DbDevImportInfo Database::import_device(string &dev) { Any send; DeviceData received_cmd; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); const DevVarLongStringArray *dev_import_list = NULL; // // Import device is allways possible whatever access rights are // DbDevImportInfo dev_import; { WriterLock guard(con_to_mon); AccessControlType tmp_access = access; access = ACCESS_WRITE; send <<= dev.c_str(); bool imported_from_cache = false; try { if (filedb != 0) { received = filedb->DbImportDevice(send); received.inout() >>= dev_import_list; } else { // // If we are in a server with a valid db_cache (meaning only during // device server startup sequence) and if // the device to be imported is the TAC device, do the // import from the cache. // All devices imported in a DS during its startup sequence will // be searched first from the cache. This will slow down a litle // bit but with this code the TAC device is really imported from the // cache instead of from DB itself. // ApiUtil *au = ApiUtil::instance(); if (au->in_server() == true) { if (db_tg != NULL) { try { DbServerCache *dsc = db_tg->get_db_cache(); if (dsc != NULL) { dev_import_list = dsc->import_tac_dev(dev); imported_from_cache = true; } } catch (Tango::DevFailed &) {} } } if (imported_from_cache == false) { DeviceData send_name; send_name << dev; CALL_DB_SERVER("DbImportDevice",send_name,received_cmd); received_cmd >> dev_import_list; } } } catch (Tango::DevFailed &) { access = tmp_access; throw; } dev_import.exported = 0; dev_import.name = dev; dev_import.ior = string((dev_import_list->svalue)[1]); dev_import.version = string((dev_import_list->svalue)[2]); dev_import.exported = dev_import_list->lvalue[0]; // // If the db server returns the device class, // store device class in cache if not already there // if (dev_import_list->svalue.length() == 6) { omni_mutex_lock guard(map_mutex); map::iterator pos = dev_class_cache.find(dev); if (pos == dev_class_cache.end()) { string dev_class((dev_import_list->svalue)[5]); pair::iterator,bool> status; status = dev_class_cache.insert(make_pair(dev,dev_class)); if (status.second == false) { TangoSys_OMemStream o; o << "Can't insert device class for device " << dev << " in device class cache" << ends; Tango::Except::throw_exception((const char *)API_CantStoreDeviceClass,o.str(), (const char *)"DeviceProxy::import_device()"); } } } access = tmp_access; } return(dev_import); } //----------------------------------------------------------------------------- // // Database::export_device() - public method to export device to the Database // //----------------------------------------------------------------------------- void Database::export_device(DbDevExportInfo& dev_export) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *dev_export_list = new DevVarStringArray; dev_export_list->length(5); (*dev_export_list)[0] = string_dup(dev_export.name.c_str()); (*dev_export_list)[1] = string_dup(dev_export.ior.c_str()); (*dev_export_list)[2] = string_dup(dev_export.host.c_str()); ostringstream ostream; ostream << dev_export.pid << ends; string st = ostream.str(); (*dev_export_list)[3] = string_dup(st.c_str()); (*dev_export_list)[4] = string_dup(dev_export.version.c_str()); send <<= dev_export_list; if (filedb != 0) filedb->DbExportDevice(send); else CALL_DB_SERVER_NO_RET("DbExportDevice",send); return; } //----------------------------------------------------------------------------- // // Database::unexport_device() - public method to unexport a device from the Database // //----------------------------------------------------------------------------- void Database::unexport_device(string dev) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= string_dup(dev.c_str()); if (filedb != 0) filedb->DbUnExportDevice(send); else CALL_DB_SERVER_NO_RET("DbUnExportDevice",send); return; } //----------------------------------------------------------------------------- // // Database::add_device() - public method to add a device to the Database // //----------------------------------------------------------------------------- void Database::add_device(DbDevInfo &dev_info) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *dev_info_list = new DevVarStringArray; dev_info_list->length(3); (*dev_info_list)[0] = string_dup(dev_info.server.c_str()); (*dev_info_list)[1] = string_dup(dev_info.name.c_str()); (*dev_info_list)[2] = string_dup(dev_info._class.c_str()); send <<= dev_info_list; if (filedb != 0) filedb->DbAddDevice(send); else CALL_DB_SERVER_NO_RET("DbAddDevice",send); return; } //----------------------------------------------------------------------------- // // Database::delete_device() - public method to delete a device from the Database // //----------------------------------------------------------------------------- void Database::delete_device(string dev) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= dev.c_str(); if (filedb != 0) filedb->DbDeleteDevice(send); else CALL_DB_SERVER_NO_RET("DbDeleteDevice",send); return; } //----------------------------------------------------------------------------- // // Database::add_server() - public method to add a server to the Database // //----------------------------------------------------------------------------- void Database::add_server(string &server, DbDevInfos &dev_infos) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *dev_info_list = new DevVarStringArray; dev_info_list->length(2*dev_infos.size()+1); (*dev_info_list)[0] = string_dup(server.c_str()); for (unsigned int i=0; iDbAddServer(send); else CALL_DB_SERVER_NO_RET("DbAddServer",send); return; } //----------------------------------------------------------------------------- // // Database::delete_server() - public method to delete a server from the Database // //----------------------------------------------------------------------------- void Database::delete_server(string &server) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= string_dup(server.c_str()); if (filedb != 0) filedb->DbDeleteServer(send); else CALL_DB_SERVER_NO_RET("DbDeleteServer",send); return; } //----------------------------------------------------------------------------- // // Database::export_server() - public method to export a server to the Database // //----------------------------------------------------------------------------- void Database::export_server(DbDevExportInfos& dev_export) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *dev_export_list = new DevVarStringArray; dev_export_list->length(5*dev_export.size()); ostringstream ostream; for (unsigned int i=0; iDbExportServer(send); else CALL_DB_SERVER_NO_RET("DbExportServer",send); return; } //----------------------------------------------------------------------------- // // Database::unexport_server() - public method to unexport a server from the Database // //----------------------------------------------------------------------------- void Database::unexport_server(string &server) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= server.c_str(); if (filedb != 0) filedb->DbUnExportServer(send); else CALL_DB_SERVER_NO_RET("DbUnExportServer",send); return; } //----------------------------------------------------------------------------- // // Database::get_server_info() - public method to return info for a server // //----------------------------------------------------------------------------- DbServerInfo Database::get_server_info(string &server) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= server.c_str(); if (filedb != 0) received = filedb->DbGetServerInfo(send); else CALL_DB_SERVER("DbGetServerInfo",send,received); const DevVarStringArray *server_info_list = NULL; received.inout() >>= server_info_list; DbServerInfo server_info; if (server_info_list != NULL) { server_info.name = string((*server_info_list)[0]); server_info.host = string((*server_info_list)[1]); server_info.mode = atoi((*server_info_list)[2]); server_info.level = atoi((*server_info_list)[3]); } else { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_server_info()"); } return(server_info); } //----------------------------------------------------------------------------- // // Database::get_device_property() - public method to get a device property from // the Database // //----------------------------------------------------------------------------- void Database::get_device_property(string dev, DbData &db_data,DbServerCache *db_cache) { unsigned int i; Any_var received; const DevVarStringArray *property_values = NULL; check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(dev.c_str()); for (i=0; iDbGetDeviceProperty(send); else CALL_DB_SERVER("DbGetDeviceProperty",send,received); received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_dev_property(property_names); delete property_names; } catch(Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_DeviceNotFoundInCache") == 0) { // // The device is not defined in the cache, call DB server // AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; send <<= property_names; if (filedb != 0) received = filedb->DbGetDeviceProperty(send); else CALL_DB_SERVER("DbGetDeviceProperty",send,received); received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_props, index; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_props; index = 2; for (i=0; i> n_values; index++; db_data[i].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value " " } else { for (int j=0; jlength(2); index = 2; (*property_values)[0] = string_dup(dev.c_str()); ostream << db_data.size(); string st = ostream.str(); (*property_values)[1] = string_dup(st.c_str()); for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); ostream.seekp (0); ostream.clear(); ostream << db_data[i].size() << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (size_t j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i].value_string[j].c_str()); } } send <<= property_values; if (filedb != 0) { CORBA::Any_var the_any; the_any = filedb->DbPutDeviceProperty(send); } else CALL_DB_SERVER_NO_RET("DbPutDeviceProperty",send); return; } //----------------------------------------------------------------------------- // // Database::delete_device_property() - public method to delete device properties // from the Database // //----------------------------------------------------------------------------- void Database::delete_device_property(string dev, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(dev.c_str()); for (unsigned int i=0; iDbDeleteDeviceProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteDeviceProperty",send); return; } //----------------------------------------------------------------------------- // // Database::get_device_attribute_property() - public method to get device // attribute properties from the Database // //----------------------------------------------------------------------------- void Database::get_device_attribute_property(string dev, DbData &db_data, DbServerCache *db_cache) { unsigned int i,j; Any_var received; const DevVarStringArray *property_values = NULL; check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(dev.c_str()); for (i=0; iDbGetDeviceAttributeProperty(send); } else { try { if (serv_version >= 230) { CALL_DB_SERVER("DbGetDeviceAttributeProperty2",send,received); } else CALL_DB_SERVER("DbGetDeviceAttributeProperty",send,received); } catch (Tango::DevFailed &) { throw; } } received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_dev_att_property(property_names); delete property_names; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_DeviceNotFoundInCache") == 0) { // // The device is not in cache, ask the db server // AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; send <<= property_names; if (filedb != 0) { received = filedb->DbGetDeviceAttributeProperty(send); } else { CALL_DB_SERVER("DbGetDeviceAttributeProperty2",send,received); } received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_attribs, index; int i_total_props; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_attribs; index = 2; if (serv_version < 230) db_data.resize((property_values->length())/2 -1); i_total_props = 0; if (serv_version < 230) { for (i=0; i> n_props; db_data[i_total_props] << n_props; i_total_props++; index++; for (j=0; j> n_props; db_data[i_total_props] << n_props; db_data.resize(old_size + n_props); old_size = old_size + n_props; i_total_props++; index++; for (j=0; j> n_values; index++; db_data[i_total_props].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value " " } else { for (int k=0; klength(2); index = 2; (*property_values)[0] = string_dup(dev.c_str()); n_attribs = 0; if (serv_version >= 230) { for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); int prop_size = db_data[i+j+1].size(); ostream.seekp(0); ostream.clear(); ostream << prop_size << ends; string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); property_values->length(index + prop_size); for (int q=0; qlength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].value_string[0].c_str()); } i = i+n_props+1; n_attribs++; } ostream.seekp(0); ostream.clear(); ostream << n_attribs << ends; string st = ostream.str(); (*property_values)[1] = string_dup(st.c_str()); } send <<= property_values; if (filedb != 0) { filedb->DbPutDeviceAttributeProperty(send); retry = false; } else { try { if (serv_version >= 230) { CALL_DB_SERVER_NO_RET("DbPutDeviceAttributeProperty2",send); } else CALL_DB_SERVER_NO_RET("DbPutDeviceAttributeProperty",send); retry = false; } catch (Tango::DevFailed &) { throw; } } } return; } //----------------------------------------------------------------------------- // // Database::delete_device_attribute_property() - public method to delete device // attribute properties from the Database // //----------------------------------------------------------------------------- void Database::delete_device_attribute_property(string dev, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *property_values = new DevVarStringArray; unsigned int nb_prop = db_data.size() - 1; property_values->length(nb_prop + 2); (*property_values)[0] = string_dup(dev.c_str()); (*property_values)[1] = string_dup(db_data[0].name.c_str()); for (unsigned int i=0; i < nb_prop;i++) (*property_values)[i + 2] = string_dup(db_data[i + 1].name.c_str()); send <<= property_values; if (filedb != 0) filedb->DbDeleteDeviceAttributeProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteDeviceAttributeProperty",send); return; } //----------------------------------------------------------------------------- // // Database::get_class_property() - public method to get class properties from // the Database // //----------------------------------------------------------------------------- void Database::get_class_property(string device_class, DbData &db_data, DbServerCache *db_cache) { unsigned int i; const DevVarStringArray *property_values = NULL; Any_var received; // // Parameters for db server call // DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(device_class.c_str()); for (i=0; iget_class_property(property_names); delete property_names; } catch(Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_ClassNotFoundInCache") == 0) { // // The class is not defined in cache, try in DB server // Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= property_names; if (filedb != 0) received = filedb->DbGetClassProperty(send); else CALL_DB_SERVER("DbGetClassProperty",send,received); received.inout() >>= property_values; } else { delete property_names; throw; } } } else { // // Call DB server // Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= property_names; if (filedb != 0) received = filedb->DbGetClassProperty(send); else CALL_DB_SERVER("DbGetClassProperty",send,received); received.inout() >>= property_values; } // // Build data returned to caller from those received from db server or from cache // unsigned int n_props, index; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_props; index = 2; for (i=0; i> n_values; db_data[i].value_string.resize(n_values); for (int j=0; jlength(2); index = 2; (*property_values)[0] = string_dup(device_class.c_str()); ostream << db_data.size() << ends; string st = ostream.str(); (*property_values)[1] = string_dup(st.c_str()); for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); ostream.seekp (0); ostream.clear(); ostream << db_data[i].size() << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (size_t j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i].value_string[j].c_str()); } } send <<= property_values; if (filedb != 0) { CORBA::Any_var the_any; the_any = filedb->DbPutClassProperty(send); } else CALL_DB_SERVER_NO_RET("DbPutClassProperty",send); return; } //----------------------------------------------------------------------------- // // Database::delete_class_property() - public method to delete class properties from // the Database // //----------------------------------------------------------------------------- void Database::delete_class_property(string device_class, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(device_class.c_str()); for (unsigned int i=0; iDbDeleteClassProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteClassProperty",send); return; } //----------------------------------------------------------------------------- // // Database::get_class_attribute_property() - public method to get class attribute // properties from the Database // //----------------------------------------------------------------------------- void Database::get_class_attribute_property(string device_class, DbData &db_data, DbServerCache *db_cache) { unsigned int i; Any_var received; const DevVarStringArray *property_values = NULL; check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(device_class.c_str()); for (i=0; iDbGetClassAttributeProperty(send); } else { try { if (serv_version >= 230) { CALL_DB_SERVER("DbGetClassAttributeProperty2",send,received); } else { CALL_DB_SERVER("DbGetClassAttributeProperty",send,received); } } catch (Tango::DevFailed &) { throw; } } received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_class_att_property(property_names); delete property_names; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_ClassNotFoundInCache") == 0) { // // The class is not defined in cache, get property(ies) from DB server // Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= property_names; if (filedb != 0) { received = filedb->DbGetClassAttributeProperty(send); } else { CALL_DB_SERVER("DbGetClassAttributeProperty2",send,received); } received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_attribs, index; int i_total_props; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_attribs; index = 2; if (serv_version < 230) db_data.resize((property_values->length())/2 - 1); i_total_props = 0; if (serv_version < 230) { for (i=0; i> n_props; db_data[i_total_props] << n_props; i_total_props++; for (int j=0; j> n_props; db_data[i_total_props] << n_props; db_data.resize(old_size + n_props); old_size = old_size + n_props; i_total_props++; index++; for (int j=0; j> n_values; index++; db_data[i_total_props].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value "" } else { for (int k=0; klength(2); index = 2; (*property_values)[0] = string_dup(device_class.c_str()); n_attribs = 0; if (serv_version >= 230) { for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); int prop_size = db_data[i+j+1].size(); ostream.seekp(0); ostream.clear(); ostream << prop_size << ends; string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); property_values->length(index + prop_size); for (int q=0; qlength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].value_string[0].c_str()); } i = i+n_props+1; n_attribs++; } ostream.seekp(0); ostream.clear(); ostream << n_attribs << ends; string st = ostream.str(); (*property_values)[1] = string_dup(st.c_str()); } send <<= property_values; if (filedb != 0) { filedb->DbPutClassAttributeProperty(send); retry = false; } else { if (serv_version >= 230) { CALL_DB_SERVER_NO_RET("DbPutClassAttributeProperty2",send); } else { CALL_DB_SERVER_NO_RET("DbPutClassAttributeProperty",send); } retry = false; } } return; } //----------------------------------------------------------------------------- // // Database::delete_class_attribute_property() - public method to delete class // attribute properties from the Database // //----------------------------------------------------------------------------- void Database::delete_class_attribute_property(string device_class, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *property_values = new DevVarStringArray; unsigned int nb_prop = db_data.size() - 1; property_values->length(nb_prop + 2); (*property_values)[0] = string_dup(device_class.c_str()); (*property_values)[1] = string_dup(db_data[0].name.c_str()); for (unsigned int i=0; i < nb_prop;i++) (*property_values)[i + 2] = string_dup(db_data[i + 1].name.c_str()); send <<= property_values; if (filedb != 0) filedb->DbDeleteClassAttributeProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteClassAttributeProperty",send); return; } //----------------------------------------------------------------------------- // // Database::get_device_name() - public method to get device names from // the Database // //----------------------------------------------------------------------------- DbDatum Database::get_device_name(string &d_server, string &d_class) { return get_device_name(d_server,d_class,NULL); } DbDatum Database::get_device_name(string &device_server, string &device_class, DbServerCache *db_cache) { Any_var received; const DevVarStringArray *device_names = NULL; check_access_and_get(); DevVarStringArray *device_server_class = new DevVarStringArray; device_server_class->length(2); (*device_server_class)[0] = string_dup(device_server.c_str()); (*device_server_class)[1] = string_dup(device_class.c_str()); if (db_cache == NULL) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= device_server_class; if (filedb != 0) received = filedb->DbGetDeviceList(send); else CALL_DB_SERVER("DbGetDeviceList",send,received); received.inout() >>= device_names; } else { device_names = db_cache->get_dev_list(device_server_class); delete device_server_class; } DbDatum db_datum; int n_devices; n_devices = device_names->length(); db_datum.name = device_server; db_datum.value_string.resize(n_devices); for (int i=0; iDbGetDeviceExportedList(send); else CALL_DB_SERVER("DbGetDeviceExportedList",send,received); const DevVarStringArray *device_names = NULL; received.inout() >>= device_names; DbDatum db_datum; if (device_names == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_exported()"); } else { int n_devices; n_devices = device_names->length(); db_datum.name = filter; db_datum.value_string.resize(n_devices); for (int i=0; iDbGetDeviceMemberList(send); else CALL_DB_SERVER("DbGetDeviceMemberList",send,received); const DevVarStringArray *device_member = NULL; received.inout() >>= device_member; DbDatum db_datum; if (device_member == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_member()"); } else { int n_members; n_members = device_member->length(); db_datum.name = wildcard; db_datum.value_string.resize(n_members); for (int i=0; iDbGetDeviceFamilyList(send); else CALL_DB_SERVER("DbGetDeviceFamilyList",send,received); const DevVarStringArray *device_family = NULL; received.inout() >>= device_family; DbDatum db_datum; if (device_family == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_family()"); } else { int n_familys; n_familys = device_family->length(); db_datum.name = wildcard; db_datum.value_string.resize(n_familys); for (int i=0; iDbGetDeviceDomainList(send); else CALL_DB_SERVER("DbGetDeviceDomainList",send,received); const DevVarStringArray *device_domain = NULL; received.inout() >>= device_domain; DbDatum db_datum; if (device_domain == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_domain()"); } else { int n_domains; n_domains = device_domain->length(); db_datum.name = wildcard; db_datum.value_string.resize(n_domains); for (int i=0; ilength(db_data.size()+1); (*property_names)[0] = string_dup(obj.c_str()); for (i=0; iDbGetProperty(send); else CALL_DB_SERVER("DbGetProperty",send,received); received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_obj_property(property_names); delete property_names; } catch(Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_DeviceNotFoundInCache") == 0) { // // The object is not defined in the cache, call DB server // AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; send <<= property_names; if (filedb != 0) received = filedb->DbGetDeviceProperty(send); else CALL_DB_SERVER("DbGetDeviceProperty",send,received); received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_props, index; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_props; index = 2; for (i=0; i> n_values; index++; db_data[i].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value " " } else { for (int j=0; jlength(2); index = 2; (*property_values)[0] = string_dup(obj.c_str()); ostream << db_data.size(); string st = ostream.str(); (*property_values)[1] = string_dup(st.c_str()); for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); ostream.seekp (0); ostream.clear(); ostream << db_data[i].size() << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (size_t j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i].value_string[j].c_str()); } } send <<= property_values; if (filedb != 0) filedb->DbPutProperty(send); else CALL_DB_SERVER_NO_RET("DbPutProperty",send); return; } //----------------------------------------------------------------------------- // // Database::delete_property() - public method to delete object properties from // the Database // //----------------------------------------------------------------------------- void Database::delete_property(string obj, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(obj.c_str()); for (unsigned int i=0; iDbDeleteProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteProperty",send); return; } //----------------------------------------------------------------------------- // // Database::get_device_alias() - public method to get device name from // its alias // //----------------------------------------------------------------------------- void Database::get_device_alias(string alias,string &dev_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= alias.c_str(); if (filedb != 0) received = filedb->DbGetAliasDevice(send); else CALL_DB_SERVER("DbGetAliasDevice",send,received); const char *dev_name_tmp = NULL; received.inout() >>= dev_name_tmp; dev_name = dev_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_alias() - public method to get alias name from // device name // //----------------------------------------------------------------------------- void Database::get_alias(string dev_name,string &alias_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= dev_name.c_str(); if (filedb != 0) received = filedb->DbGetDeviceAlias(send); else CALL_DB_SERVER("DbGetDeviceAlias",send,received); const char *dev_name_tmp = NULL; received.inout() >>= dev_name_tmp; alias_name = dev_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_attribute_alias() - public method to get attribute name from // its alias // //----------------------------------------------------------------------------- void Database::get_attribute_alias(string attr_alias, string &attr_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= attr_alias.c_str(); if (filedb != 0) received = filedb->DbGetAttributeAlias(send); else CALL_DB_SERVER("DbGetAttributeAlias",send,received); const char* attr_name_tmp = NULL; received.inout() >>= attr_name_tmp; if (attr_name_tmp == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_attribute_alias()"); } else attr_name = attr_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_device_alias_list() - public method to get device alias list. // Wildcard (*) is suported // //----------------------------------------------------------------------------- DbDatum Database::get_device_alias_list(string &alias) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= alias.c_str(); if (filedb != 0) received = filedb->DbGetDeviceAliasList(send); else CALL_DB_SERVER("DbGetDeviceAliasList",send,received); const DevVarStringArray *alias_array = NULL; received.inout() >>= alias_array; DbDatum db_datum; if (alias_array == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_alias_list()"); } else { int n_aliases; n_aliases = alias_array->length(); db_datum.name = alias; db_datum.value_string.resize(n_aliases); for (int i=0; iDbGetAttributeAliasList(send); else CALL_DB_SERVER("DbGetAttributeAliasList",send,received); const DevVarStringArray *alias_array = NULL; received.inout() >>= alias_array; DbDatum db_datum; if (alias_array == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_attribute_alias_list()"); } else { int n_aliases; n_aliases = alias_array->length(); db_datum.name = alias; db_datum.value_string.resize(n_aliases); for (int i=0; i>= prop_list; if (prop_list == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::make_string_array()"); } else { int n_props; n_props = prop_list->length(); db_datum.name = name; db_datum.value_string.resize(n_props); for (int i=0; ilength(2); (*sent_names)[0] = string_dup(dev.c_str()); (*sent_names)[1] = string_dup(wildcard.c_str()); send <<= sent_names; CALL_DB_SERVER("DbGetDevicePropertyList",send,received); return make_string_array(dev,received); } void Database::get_device_property_list(string &dev, const string &wildcard, vector &prop_list,DbServerCache *db_cache) { if (db_cache == NULL) { DbDatum db = get_device_property_list(dev,const_cast(wildcard)); prop_list = db.value_string; } else { // // Try to get property names from cache // DevVarStringArray send_seq; send_seq.length(2); send_seq[0] = CORBA::string_dup(dev.c_str()); send_seq[1] = CORBA::string_dup(wildcard.c_str()); try { const DevVarStringArray *recev; recev = db_cache->get_device_property_list(&send_seq); prop_list << *recev; } catch(Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"DB_DeviceNotFoundInCache") == 0) { // // The object is not defined in the cache, call DB server // AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; Any_var received; send <<= send_seq; if (filedb != 0) received = filedb->DbGetDeviceProperty(send); else CALL_DB_SERVER("DbGetDevicePropertyList",send,received); DbDatum db_d = make_string_array(dev,received); prop_list = db_d.value_string; } else { throw; } } } } //----------------------------------------------------------------------------- // // Database::get_host_list() - Query the database for a list of host registered. // //----------------------------------------------------------------------------- DbDatum Database::get_host_list() { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= "*"; CALL_DB_SERVER("DbGetHostList",send,received); return make_string_array(string("host"),received); } //----------------------------------------------------------------------------- // // Database::get_host_list() - Query the database for a list of host registred. // //----------------------------------------------------------------------------- DbDatum Database::get_host_list(string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= wildcard.c_str(); CALL_DB_SERVER("DbGetHostList",send,received); return make_string_array(string("host"),received); } //----------------------------------------------------------------------------- // // Database::get_server_class_list() - Query the database for a list of classes // instancied for a server // //----------------------------------------------------------------------------- DbDatum Database::get_server_class_list(string &servname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= servname.c_str(); CALL_DB_SERVER("DbGetDeviceServerClassList",send,received); const DevVarStringArray *prop_list = NULL; received.inout() >>= prop_list; DbDatum db_datum; if (prop_list == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_server_class_list()"); } else { // Extract the DServer class int n_props; int nb_classes; n_props = prop_list->length(); if(n_props == 0 ) nb_classes = 0; else nb_classes = n_props - 1; db_datum.name = servname; db_datum.value_string.resize(nb_classes); for (int i=0,j=0; ilength(4); (*serv_info)[0] = string_dup(info.name.c_str()); (*serv_info)[1] = string_dup(info.host.c_str()); ostream.seekp(0); ostream.clear(); ostream << info.mode << ends; string st = ostream.str(); (*serv_info)[2] = string_dup(st.c_str()); ostream.seekp(0); ostream.clear(); ostream << info.level << ends; st = ostream.str(); (*serv_info)[3] = string_dup(st.c_str()); send <<= serv_info; CALL_DB_SERVER_NO_RET("DbPutServerInfo",send); return; } //----------------------------------------------------------------------------- // // Database::delete_server_info() - Delete server information in databse // //----------------------------------------------------------------------------- void Database::delete_server_info(string &servname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= servname.c_str(); CALL_DB_SERVER_NO_RET("DbDeleteServerInfo",send); return; } //----------------------------------------------------------------------------- // // Database::get_device_class_list() - Query the database for server devices // and classes. // //----------------------------------------------------------------------------- DbDatum Database::get_device_class_list(string &servname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= servname.c_str(); CALL_DB_SERVER("DbGetDeviceClassList",send,received); return make_string_array(string("server"),received); } //----------------------------------------------------------------------------- // // Database::get_object_list() - Query the database for a list of object // (ie non-device) for which properties are defined // //----------------------------------------------------------------------------- DbDatum Database::get_object_list(string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= wildcard.c_str(); CALL_DB_SERVER("DbGetObjectList",send,received); return make_string_array(string("object"),received); } //----------------------------------------------------------------------------- // // Database::get_object_property_list() - Query the database for a list of // properties defined for the specified // object. // //----------------------------------------------------------------------------- DbDatum Database::get_object_property_list(string &objname,string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *obj_info = new DevVarStringArray; obj_info->length(2); (*obj_info)[0] = string_dup(objname.c_str()); (*obj_info)[1] = string_dup(wildcard.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetPropertyList",send,received); return make_string_array(string("object"),received); } //----------------------------------------------------------------------------- // // Database::get_class_property_list() - Query the database for a list of // properties defined for the specified // class. // //----------------------------------------------------------------------------- DbDatum Database::get_class_property_list(string &classname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= classname.c_str(); CALL_DB_SERVER("DbGetClassPropertyList",send,received); return make_string_array(string("class"),received); } //----------------------------------------------------------------------------- // // Database::get_class_for_device() - Return the class of the specified device // //----------------------------------------------------------------------------- string Database::get_class_for_device(string &devname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); // // First check if the device class is not already in the device class cache // If yes, simply returns it otherwise get class name from Db server // and stores it in device class cache // string ret_str; { omni_mutex_lock guard(map_mutex); map::iterator pos = dev_class_cache.find(devname); if (pos == dev_class_cache.end()) { send <<= devname.c_str(); CALL_DB_SERVER("DbGetClassforDevice",send,received); const char *classname = NULL; received.inout() >>= classname; ret_str = classname; pair::iterator,bool> status; status = dev_class_cache.insert(make_pair(devname,ret_str)); if (status.second == false) { TangoSys_OMemStream o; o << "Can't insert device class for device " << devname << " in device class cache" << ends; Tango::Except::throw_exception((const char *)API_CantStoreDeviceClass,o.str(), (const char *)"DeviceProxy::get_class_for_device()"); } } else { ret_str = pos->second; } } return ret_str; } //----------------------------------------------------------------------------- // // Database::get_class_inheritance_for_device() - Return the class inheritance // scheme of the specified device // //----------------------------------------------------------------------------- DbDatum Database::get_class_inheritance_for_device(string &devname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= devname.c_str(); try { CALL_DB_SERVER("DbGetClassInheritanceForDevice",send,received); } catch (DevFailed &e) { // Check if an old API else re-throw if (strcmp(e.errors[0].reason.in(),API_CommandNotFound) != 0) { throw; } else { DbDatum db_datum; db_datum.name = "class"; db_datum.value_string.resize(1); db_datum.value_string[0] = "Device_3Impl"; return db_datum; } } return make_string_array(string("class"),received); } //----------------------------------------------------------------------------- // // Database::get_class_list() - Query the database for a list of classes // //----------------------------------------------------------------------------- DbDatum Database::get_class_list(string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= wildcard.c_str(); CALL_DB_SERVER("DbGetClassList",send,received); return make_string_array(string("class"),received); } //----------------------------------------------------------------------------- // // Database::get_class_attribute_list() - Query the database for a list of // attributes defined for the specified // class. // //----------------------------------------------------------------------------- DbDatum Database::get_class_attribute_list(string &classname,string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *class_info = new DevVarStringArray; class_info->length(2); (*class_info)[0] = string_dup(classname.c_str()); (*class_info)[1] = string_dup(wildcard.c_str()); send <<= class_info; CALL_DB_SERVER("DbGetClassAttributeList",send,received); return make_string_array(string("class"),received); } //----------------------------------------------------------------------------- // // Database::get_device_exported_for_class() - Query database for list of exported // devices for the specified class // //----------------------------------------------------------------------------- DbDatum Database::get_device_exported_for_class(string &classname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= classname.c_str(); CALL_DB_SERVER("DbGetExportdDeviceListForClass",send,received); return make_string_array(string("device"),received); } //----------------------------------------------------------------------------- // // Database::put_device_alias() - Set an alias for a device // //----------------------------------------------------------------------------- void Database::put_device_alias(string &devname,string &aliasname) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *alias_info = new DevVarStringArray; alias_info->length(2); (*alias_info)[0] = string_dup(devname.c_str()); (*alias_info)[1] = string_dup(aliasname.c_str()); send <<= alias_info; CALL_DB_SERVER_NO_RET("DbPutDeviceAlias",send); return; } //----------------------------------------------------------------------------- // // Database::delete_device_alias() - Delete a device alias from the database // //----------------------------------------------------------------------------- void Database::delete_device_alias(string &aliasname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= aliasname.c_str(); CALL_DB_SERVER_NO_RET("DbDeleteDeviceAlias",send); return; } //----------------------------------------------------------------------------- // // Database::put_attribute_alias() - Set an alias for an attribute // //----------------------------------------------------------------------------- void Database::put_attribute_alias(string &attname,string &aliasname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *alias_info = new DevVarStringArray; alias_info->length(2); (*alias_info)[0] = string_dup(attname.c_str()); (*alias_info)[1] = string_dup(aliasname.c_str()); send <<= alias_info; CALL_DB_SERVER_NO_RET("DbPutAttributeAlias",send); return; } //----------------------------------------------------------------------------- // // Database::delete_attribute_alias() - Delete an attribute alias from the database // //----------------------------------------------------------------------------- void Database::delete_attribute_alias(string &aliasname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= aliasname.c_str(); CALL_DB_SERVER("DbDeleteAttributeAlias",send,received); return; } //----------------------------------------------------------------------------- // // Database::make_history_array() - Convert the result of a DbGet...PropertyHist // command. // //----------------------------------------------------------------------------- vector Database::make_history_array(bool is_attribute, Any_var &received) { const DevVarStringArray *ret = NULL; received.inout() >>= ret; vector v; if (ret == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::make_history_array()"); } else { unsigned int i=0; int count=0; int offset; string aName = ""; string pName; string pDate; string pCount; while(ilength()) { if(is_attribute) { aName = (*ret)[i]; pName = (*ret)[i+1]; pDate = (*ret)[i+2]; pCount = (*ret)[i+3]; offset = 4; } else { pName = (*ret)[i]; pDate = (*ret)[i+1]; pCount = (*ret)[i+2]; offset = 3; } istringstream istream(pCount); istream >> count; if (!istream) { Except::throw_exception( (const char *)"API_HistoryInvalid", (const char *)"History format is invalid", (const char *)"Database::make_history_array()"); } vector value; for(int j=0;j Database::get_property_history(string &objname,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *obj_info = new DevVarStringArray; obj_info->length(2); (*obj_info)[0] = string_dup(objname.c_str()); (*obj_info)[1] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetPropertyHist",send,received); return make_history_array(false,received); } //----------------------------------------------------------------------------- // // Database::get_device_property_history() - Returns the history of the specified // device property // //----------------------------------------------------------------------------- vector Database::get_device_property_history(string &devname,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *obj_info = new DevVarStringArray; obj_info->length(2); (*obj_info)[0] = string_dup(devname.c_str()); (*obj_info)[1] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetDevicePropertyHist",send,received); return make_history_array(false,received); } //----------------------------------------------------------------------------- // // Database::get_device_attribute_property_history() - Returns the history of // the specified device // attribute property // //----------------------------------------------------------------------------- vector Database::get_device_attribute_property_history(string &devname,string &attname,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *obj_info = new DevVarStringArray; obj_info->length(3); (*obj_info)[0] = string_dup(devname.c_str()); (*obj_info)[1] = string_dup(attname.c_str()); (*obj_info)[2] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetDeviceAttributePropertyHist",send,received); return make_history_array(true,received); } //----------------------------------------------------------------------------- // // Database::get_class_property_history() - Returns the history of the specified // class property // //----------------------------------------------------------------------------- vector Database::get_class_property_history(string &classname,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *obj_info = new DevVarStringArray; check_access_and_get(); obj_info->length(2); (*obj_info)[0] = string_dup(classname.c_str()); (*obj_info)[1] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetClassPropertyHist",send,received); return make_history_array(false,received); } //----------------------------------------------------------------------------- // // Database::get_class_attribute_property_history() - Returns the history of // the specified class // attribute property // //----------------------------------------------------------------------------- vector Database::get_class_attribute_property_history(string &classname,string &attname,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *obj_info = new DevVarStringArray; check_access_and_get(); obj_info->length(3); (*obj_info)[0] = string_dup(classname.c_str()); (*obj_info)[1] = string_dup(attname.c_str()); (*obj_info)[2] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetClassAttributePropertyHist",send,received); return make_history_array(true,received); } //----------------------------------------------------------------------------- // // Database::get_services() - Query database for specified services // //----------------------------------------------------------------------------- DbDatum Database::get_services(string &servname,string &instname) { DbData data; DbDatum db_datum; vector services; vector filter_services; // Get list of services ApiUtil *au = ApiUtil::instance(); DbServerCache *dsc; if (au->in_server() == true) { if (from_env_var == false) dsc = NULL; else { try { Tango::Util *tg = Tango::Util::instance(false); dsc = tg->get_db_cache(); } catch (Tango::DevFailed &e) { string reason = e.errors[0].reason.in(); if (reason == "API_UtilSingletonNotCreated" && db_tg != NULL) dsc = db_tg->get_db_cache(); else dsc = NULL; } } } else dsc = NULL; DbDatum db_d(SERVICE_PROP_NAME); data.push_back(db_d); get_property_forced(CONTROL_SYSTEM, data,dsc); data[0] >> services; // Filter string filter = servname+"/"; if( strcmp( instname.c_str() , "*")!=0 ) filter += instname + ":"; transform(filter.begin(),filter.end(),filter.begin(),::tolower); for(unsigned int i=0;i services; vector filter_services; // // Get list of services // ApiUtil *au = ApiUtil::instance(); DbServerCache *dsc; if (au->in_server() == true) { if (from_env_var == false) dsc = NULL; else { try { Tango::Util *tg = Tango::Util::instance(false); dsc = tg->get_db_cache(); } catch (Tango::DevFailed &e) { string reason = e.errors[0].reason.in(); if (reason == "API_UtilSingletonNotCreated" && db_tg != NULL) dsc = db_tg->get_db_cache(); else dsc = NULL; } } } else dsc = NULL; DbDatum db_d(SERVICE_PROP_NAME); data.push_back(db_d); get_property_forced(CONTROL_SYSTEM, data,dsc); data[0] >> services; // // Filter the required service // string filter = servname + "/"; transform(filter.begin(),filter.end(),filter.begin(),::tolower); for(unsigned int i = 0;i < services.size();i++) { transform(services[i].begin(),services[i].end(),services[i].begin(),::tolower); if (strncmp(services[i].c_str(),filter.c_str(),filter.length()) == 0) { string::size_type pos,pos_end; pos = services[i].find('/'); if (pos != string::npos) { pos_end = services[i].find(':'); if (pos != string::npos) { filter_services.push_back(services[i].substr(pos + 1,pos_end - pos - 1)); filter_services.push_back(services[i].substr(pos_end + 1)); } } } } // // Build return value // db_datum.name = "services"; db_datum.value_string.resize(filter_services.size()); for (unsigned int i = 0;i < filter_services.size();i++) db_datum.value_string[i] = filter_services[i]; return db_datum; } //----------------------------------------------------------------------------- // // Database::register_service() - Register a new service // //----------------------------------------------------------------------------- void Database::register_service(string &servname,string &instname,string &devname) { DbData data; vector services; vector new_services; bool service_exists = false; // Get list of services data.push_back( DbDatum(SERVICE_PROP_NAME) ); get_property(CONTROL_SYSTEM,data ); data[0] >> services; string full_name = servname+"/"+instname+":"; transform(full_name.begin(),full_name.end(),full_name.begin(),::tolower); // Update service list for(unsigned int i=0;i services; vector new_services; bool service_deleted = false; // Get list of services data.push_back( DbDatum(SERVICE_PROP_NAME) ); get_property(CONTROL_SYSTEM, data ); data[0] >> services; string full_name = servname+"/"+instname+":"; transform(full_name.begin(),full_name.end(),full_name.begin(),::tolower); // Update service list for(unsigned int i=0;i/", (const char *)"Database::fill_server_cache"); } // // Read Db device "StoredProcedureRelease" attribute. In case the stored procedure release is >= 1.9, // add Tango major release at the end the host name. This is required to manage compatibility between different // Tango releases used by device server(s) process when stored procedure supporting pipes is installed // (release 1.9 or higher) // To read the attribute, we do not have a DeviceProxy. // string ds_host(loc_host); int db_proc_release = 0; AttributeValueList_3 *attr_value_list_3 = NULL; AttributeValueList_4 *attr_value_list_4 = NULL; AttributeValueList_5 *attr_value_list_5 = NULL; DevVarStringArray attr_list; attr_list.length(1); attr_list[0] = CORBA::string_dup("StoredProcedureRelease"); DeviceAttribute da; try { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); if (version >= 5) { Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->read_attributes_5(attr_list,DEV,ci); ApiUtil::attr_to_device(&((*attr_value_list_5)[0]),version,&da); delete attr_value_list_5; } else if (version == 4) { Device_4_var dev = Device_4::_duplicate(device_4); attr_value_list_4 = dev->read_attributes_4(attr_list,DEV,ci); ApiUtil::attr_to_device(&((*attr_value_list_4)[0]),version,&da); delete attr_value_list_4; } else { Device_3_var dev = Device_3::_duplicate(device_3); attr_value_list_3 = dev->read_attributes_3(attr_list,DEV); ApiUtil::attr_to_device(NULL,&((*attr_value_list_3)[0]),version,&da); delete attr_value_list_3; } string sp_rel; da >> sp_rel; string rel = sp_rel.substr(8); string::size_type pos = rel.find('.'); if (pos != string::npos) { string maj_str = rel.substr(0,pos); string min_str = rel.substr(pos + 1); int maj = atoi(maj_str.c_str()); int min = atoi(min_str.c_str()); db_proc_release = (maj * 100) + min; } } catch (DevFailed &) {} if (db_proc_release >= 109) ds_host = ds_host + "%%" + TgLibMajorVers; // // Filling the cache is always possible whatever access rights are // Any_var received; { WriterLock guard(con_to_mon); AccessControlType tmp_access = access; access = ACCESS_WRITE; // // Call the db server // Any send; DevVarStringArray *sent_info = new DevVarStringArray; sent_info->length(2); (*sent_info)[0] = string_dup(ds_name.c_str()); (*sent_info)[1] = string_dup(ds_host.c_str()); send <<= sent_info; try { CALL_DB_SERVER("DbGetDataForServerCache",send,received); access = tmp_access; } catch (Tango::DevFailed &) { access = tmp_access; throw; } } return received._retn(); } //----------------------------------------------------------------------------- // // Database::delete_all_device_attribute_property() - Call Db server to // delete all the property(ies) belonging to the specified device // attribute(s) // //----------------------------------------------------------------------------- void Database::delete_all_device_attribute_property(string dev_name,DbData &db_data) { AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; DevVarStringArray *att_names = new DevVarStringArray; att_names->length(db_data.size()+1); (*att_names)[0] = string_dup(dev_name.c_str()); for (unsigned int i=0; i serv_dev_list; db_serv >> serv_dev_list; if (serv_dev_list.empty() == false) { access_devname_str = serv_dev_list[0]; access_service_defined = true; } else { // // No access service defined, give WRITE ACCESS to everyone also on the // database device // // cerr << "No access service found" << endl; access = ACCESS_WRITE; return ACCESS_WRITE; } } // // Build the local AccessProxy instance // If the database has been built for a device defined with a FQDN, // don't forget to add db_host and db_port on the TAC device name // but only if FQDN infos are not laredy defined in the service // device name // if (from_env_var == false) { int num = 0; num = count(access_devname_str.begin(),access_devname_str.end(),'/'); if (num == 2) { string fqdn("tango://"); fqdn = fqdn + db_host + ":" + db_port + "/"; access_devname_str.insert(0,fqdn); } } access_proxy = new AccessProxy(access_devname_str); } // // Get access rights // if (access_proxy != NULL) local_access = access_proxy->check_access_control(devname); else { if (access_service_defined == false) local_access = ACCESS_WRITE; else local_access = ACCESS_READ; } access_except_errors.length(0); } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),API_DeviceNotExported) == 0 || ::strcmp(e.errors[0].reason.in(),"DB_DeviceNotDefined") == 0) { string tmp_err_desc(e.errors[0].desc.in()); tmp_err_desc = tmp_err_desc + "\nControlled access service defined in Db but unreachable --> Read access given to all devices..."; e.errors[0].desc = CORBA::string_dup(tmp_err_desc.c_str()); } access_except_errors = e.errors; local_access = ACCESS_READ; } return local_access; } //----------------------------------------------------------------------------- // // Database::is_command_allowed() - // //----------------------------------------------------------------------------- bool Database::is_command_allowed(string &devname,string &cmd) { WriterLock guard(con_to_mon); bool ret; if (access_proxy == NULL) { AccessControlType acc = check_access_control(devname); if (access_proxy == NULL) { // ret = !check_acc; if (acc == ACCESS_READ) ret = false; else ret = true; return ret; } else { access = acc; clear_access_except_errors(); } } if (devname == db_device_name) { // // In case of Database object, the first command uses the default access right (READ) // Therefore, this is_command_allowed method is called and the access are checked by the // check_access_control() call upper in this method. If the access is WRITE, force // true for the retrun value of this method // if (access == ACCESS_READ) { string db_class("Database"); ret = access_proxy->is_command_allowed(db_class,cmd); } else ret = true; } else { // // Get device class // string dev_class = get_class_for_device(devname); ret = access_proxy->is_command_allowed(dev_class,cmd); } return ret; } //----------------------------------------------------------------------------- // // method : Database::write_event_channel_ior_filedatabase() - // // description : Method to connect write the event channel ior to the file // used as database // // argument : in : ec_ior : The event channel IOR // //----------------------------------------------------------------------------- void Database::write_event_channel_ior_filedatabase(string &ec_ior) { if (filedb == NULL) { Tango::Except::throw_exception((const char *)API_NotSupportedFeature, (const char *)"This call is supported only when the database is a file", (const char *)"Database::write_event_channel_ior_filedatabase"); } filedb->write_event_channel_ior(ec_ior); } //----------------------------------------------------------------------------- // // Database::get_device_info() - public method to get device information // //----------------------------------------------------------------------------- DbDevFullInfo Database::get_device_info(string &dev) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= dev.c_str(); CALL_DB_SERVER("DbGetDeviceInfo",send,received); const DevVarLongStringArray *dev_info_db = NULL; received.inout() >>= dev_info_db; DbDevFullInfo dev_info; if (dev_info_db != NULL) { dev_info.name = string(dev_info_db->svalue[0]); dev_info.ior = string(dev_info_db->svalue[1]); dev_info.version = string(dev_info_db->svalue[2]); dev_info.ds_full_name = string(dev_info_db->svalue[3]); dev_info.host = string(dev_info_db->svalue[4]); if (::strlen(dev_info_db->svalue[5]) != 1) dev_info.started_date = string(dev_info_db->svalue[5]); if (::strlen(dev_info_db->svalue[6]) != 1) dev_info.stopped_date = string(dev_info_db->svalue[6]); if (dev_info_db->svalue.length() > 7) dev_info.class_name = string(dev_info_db->svalue[7]); else { try { dev_info.class_name = get_class_for_device(dev); } catch(...) {} } dev_info.exported = dev_info_db->lvalue[0]; dev_info.pid = dev_info_db->lvalue[1]; } else { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_device_info()"); } return(dev_info); } //----------------------------------------------------------------------------- // // Database::get_device_from_alias() - Get device name from an alias // //----------------------------------------------------------------------------- void Database::get_device_from_alias(string alias_name, string &dev_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= alias_name.c_str(); if (filedb != 0) received = filedb->DbGetAliasDevice(send); else CALL_DB_SERVER("DbGetAliasDevice",send,received); const char *dev_name_tmp = NULL; received.inout() >>= dev_name_tmp; dev_name = dev_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_alias_from_device() - Get alias name from a device name // //----------------------------------------------------------------------------- void Database::get_alias_from_device(string dev_name, string &alias_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= dev_name.c_str(); if (filedb != 0) received = filedb->DbGetDeviceAlias(send); else CALL_DB_SERVER("DbGetDeviceAlias",send,received); const char *dev_name_tmp = NULL; received.inout() >>= dev_name_tmp; alias_name = dev_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_attribute_from_alias() - Get attribute name from an alias // //----------------------------------------------------------------------------- void Database::get_attribute_from_alias(string attr_alias, string &attr_name) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= attr_alias.c_str(); /* if (filedb != 0) received = filedb->DbGetAliasAttribute(send); else*/ CALL_DB_SERVER("DbGetAliasAttribute",send,received); const char* attr_name_tmp = NULL; received.inout() >>= attr_name_tmp; if (attr_name_tmp == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_attribute_from_alias()"); } else attr_name = attr_name_tmp; } //----------------------------------------------------------------------------- // // Database::get_alias_from_attribute() - Get alias name from an attribute name // //----------------------------------------------------------------------------- void Database::get_alias_from_attribute(string attr_name, string &attr_alias) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); send <<= attr_name.c_str(); /* if (filedb != 0) received = filedb->DbGetAttributeAlias2(send); else*/ CALL_DB_SERVER("DbGetAttributeAlias2",send,received); const char* attr_alias_tmp = NULL; received.inout() >>= attr_alias_tmp; if (attr_alias_tmp == NULL) { Tango::Except::throw_exception((const char *)API_IncoherentDbData, (const char *)"Incoherent data received from database", (const char *)"Database::get_alias_from_attribute()"); } else attr_alias = attr_alias_tmp; } //----------------------------------------------------------------------------- // // Database::get_device_attribute_list() - Get list of attributes with data in db // for a specified device // //----------------------------------------------------------------------------- void Database::get_device_attribute_list(string &dev_name, vector &att_list) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *sent_names = new DevVarStringArray; sent_names->length(2); (*sent_names)[0] = string_dup(dev_name.c_str()); (*sent_names)[1] = string_dup("*"); send <<= sent_names; CALL_DB_SERVER("DbGetDeviceAttributeList",send,received); const DevVarStringArray *recv_names = NULL; received.inout() >>= recv_names; att_list << *recv_names; } //----------------------------------------------------------------------------- // // Database::rename_server() - Rename a device server process // //----------------------------------------------------------------------------- void Database::rename_server(const string &old_ds_name, const string &new_ds_name) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *sent_names = new DevVarStringArray; sent_names->length(2); (*sent_names)[0] = string_dup(old_ds_name.c_str()); (*sent_names)[1] = string_dup(new_ds_name.c_str()); send <<= sent_names; CALL_DB_SERVER_NO_RET("DbRenameServer",send); } //----------------------------------------------------------------------------------------------------------------- // // Database::get_class_pipe_property() - public method to get class pipe properties from the Database // //----------------------------------------------------------------------------------------------------------------- void Database::get_class_pipe_property(string device_class, DbData &db_data, DbServerCache *db_cache) { unsigned int i; Any_var received; const DevVarStringArray *property_values = NULL; check_access_and_get(); DevVarStringArray *property_names = new DevVarStringArray; property_names->length(db_data.size()+1); (*property_names)[0] = string_dup(device_class.c_str()); for (i=0; iDbGetClassPipeProperty(send); } else { try { CALL_DB_SERVER("DbGetClassPipeProperty",send,received); } catch (Tango::DevFailed &) { throw; } } received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_class_pipe_property(property_names); delete property_names; } catch (Tango::DevFailed &e) { string err_reason(e.errors[0].reason.in()); if (err_reason == "DB_ClassNotFoundInCache" || err_reason == "DB_TooOldStoredProc") { if (err_reason == "DB_TooOldStoredProc") { cout << "WARNING: You database stored procedure is too old to support device pipe" << endl; cout << "Please, update to stored procedure release 1.9 or more" << endl; cout << "Trying direct Db access" << endl; } // // The class is not defined in cache, get property(ies) from DB server // Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); send <<= property_names; if (filedb != 0) { received = filedb->DbGetClassPipeProperty(send); } else { CALL_DB_SERVER("DbGetClassPipeProperty",send,received); } received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_pipes, index; int i_total_props; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_pipes; index = 2; i_total_props = 0; long old_size = 0; for (i=0; i> n_props; db_data[i_total_props] << n_props; db_data.resize(old_size + n_props); old_size = old_size + n_props; i_total_props++; index++; for (int j=0; j> n_values; index++; db_data[i_total_props].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value "" } else { for (int k=0; klength(db_data.size()+1); (*property_names)[0] = string_dup(dev.c_str()); for (i=0; iDbGetDevicePipeProperty(send); } else { try { CALL_DB_SERVER("DbGetDevicePipeProperty",send,received); } catch (Tango::DevFailed &) { throw; } } received.inout() >>= property_values; } else { // // Try to get property(ies) from cache // try { property_values = db_cache->get_dev_pipe_property(property_names); delete property_names; } catch (Tango::DevFailed &e) { string err_reason(e.errors[0].reason.in()); if (err_reason == "DB_DeviceNotFoundInCache" || err_reason == "DB_TooOldStoredProc") { if (err_reason == "DB_TooOldStoredProc") { cout << "WARNING: You database stored procedure is too old to support device pipe" << endl; cout << "Please, update to stored procedure release 1.9 or more" << endl; cout << "Trying direct Db access" << endl; } // // The device is not in cache, ask the db server // AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; send <<= property_names; if (filedb != 0) { received = filedb->DbGetDeviceAttributeProperty(send); } else { CALL_DB_SERVER("DbGetDevicePipeProperty",send,received); } received.inout() >>= property_values; } else { delete property_names; throw; } } } unsigned int n_pipes, index; int i_total_props; stringstream iostream; iostream << (*property_values)[1].in() << ends; iostream >> n_pipes; index = 2; i_total_props = 0; long old_size = 0; for (i=0; i> n_props; db_data[i_total_props] << n_props; db_data.resize(old_size + n_props); old_size = old_size + n_props; i_total_props++; index++; for (j=0; j> n_values; index++; db_data[i_total_props].value_string.resize(n_values); if (n_values == 0) { index++; // skip dummy returned value " " } else { for (int k=0; klength(nb_prop + 2); (*property_values)[0] = string_dup(device_class.c_str()); (*property_values)[1] = string_dup(db_data[0].name.c_str()); for (unsigned int i=0; i < nb_prop;i++) (*property_values)[i + 2] = string_dup(db_data[i + 1].name.c_str()); send <<= property_values; if (filedb != 0) filedb->DbDeleteClassPipeProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteClassPipeProperty",send); return; } //-------------------------------------------------------------------------------------------------------------------- // // Database::delete_device_pipe_property() - public method to delete device pipe properties from the Database // //-------------------------------------------------------------------------------------------------------------------- void Database::delete_device_pipe_property(string dev, DbData &db_data) { Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *property_values = new DevVarStringArray; unsigned int nb_prop = db_data.size() - 1; property_values->length(nb_prop + 2); (*property_values)[0] = string_dup(dev.c_str()); (*property_values)[1] = string_dup(db_data[0].name.c_str()); for (unsigned int i=0; i < nb_prop;i++) (*property_values)[i + 2] = string_dup(db_data[i + 1].name.c_str()); send <<= property_values; if (filedb != 0) filedb->DbDeleteDevicePipeProperty(send); else CALL_DB_SERVER_NO_RET("DbDeleteDevicePipeProperty",send); return; } //------------------------------------------------------------------------------------------------------------------- // // Database::get_class_pipe_list() - Query the database for a list of pipes defined for the specified class. // //------------------------------------------------------------------------------------------------------------------- DbDatum Database::get_class_pipe_list(const string &classname,const string &wildcard) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *class_info = new DevVarStringArray; class_info->length(2); (*class_info)[0] = string_dup(classname.c_str()); (*class_info)[1] = string_dup(wildcard.c_str()); send <<= class_info; CALL_DB_SERVER("DbGetClassPipeList",send,received); return make_string_array(string("class"),received); } //------------------------------------------------------------------------------------------------------------------- // // Database::get_device_pipe_list() - Get list of pipes with data in db for a specified device // //------------------------------------------------------------------------------------------------------------------- void Database::get_device_pipe_list(const string &dev_name, vector &pipe_list) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *sent_names = new DevVarStringArray; sent_names->length(2); (*sent_names)[0] = string_dup(dev_name.c_str()); (*sent_names)[1] = string_dup("*"); send <<= sent_names; CALL_DB_SERVER("DbGetDevicePipeList",send,received); const DevVarStringArray *recv_names = NULL; received.inout() >>= recv_names; pipe_list << *recv_names; } //---------------------------------------------------------------------------------------------------------------- // // Database::delete_all_device_pipe_property() - Call Db server to delete all the property(ies) belonging to the // specified device pipe(s) // //---------------------------------------------------------------------------------------------------------------- void Database::delete_all_device_pipe_property(string dev_name,DbData &db_data) { AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); Any send; DevVarStringArray *att_names = new DevVarStringArray; att_names->length(db_data.size()+1); (*att_names)[0] = string_dup(dev_name.c_str()); for (unsigned int i=0; ilength(2); index = 2; (*property_values)[0] = string_dup(device_class.c_str()); n_pipes = 0; for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); int prop_size = db_data[i+j+1].size(); ostream.seekp(0); ostream.clear(); ostream << prop_size << ends; string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); property_values->length(index + prop_size); for (int q=0; qDbPutClassPipeProperty(send); retry = false; } else { CALL_DB_SERVER_NO_RET("DbPutClassPipeProperty",send); retry = false; } } return; } //------------------------------------------------------------------------------------------------------------------- // // Database::put_device_pipe_property() - public method to put device pipe properties into the Database // //------------------------------------------------------------------------------------------------------------------- void Database::put_device_pipe_property(string dev, DbData &db_data) { ostringstream ostream; Any send; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); int index, n_pipes ; bool retry = true; check_access_and_get(); while (retry == true) { DevVarStringArray *property_values = new DevVarStringArray; property_values->length(2); index = 2; (*property_values)[0] = string_dup(dev.c_str()); n_pipes = 0; for (unsigned int i=0; ilength(index); (*property_values)[index-1] = string_dup(db_data[i].name.c_str()); db_data[i] >> n_props; ostream.seekp(0); ostream.clear(); ostream << n_props << ends; index++; property_values->length(index); string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); for (int j=0; jlength(index); (*property_values)[index-1] = string_dup(db_data[i+j+1].name.c_str()); index++; property_values->length(index); int prop_size = db_data[i+j+1].size(); ostream.seekp(0); ostream.clear(); ostream << prop_size << ends; string st = ostream.str(); (*property_values)[index-1] = string_dup(st.c_str()); property_values->length(index + prop_size); for (int q=0; qDbPutDevicePipeProperty(send); retry = false; } else { try { CALL_DB_SERVER_NO_RET("DbPutDevicePipeProperty",send); retry = false; } catch (Tango::DevFailed &) { throw; } } } return; } //------------------------------------------------------------------------------------------------------------------ // // Database::get_class_pipe_property_history() - Returns the history of the specified class pipe property // //------------------------------------------------------------------------------------------------------------------ vector Database::get_class_pipe_property_history(string &classname,string &pipename,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); DevVarStringArray *obj_info = new DevVarStringArray; check_access_and_get(); obj_info->length(3); (*obj_info)[0] = string_dup(classname.c_str()); (*obj_info)[1] = string_dup(pipename.c_str()); (*obj_info)[2] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetClassPipePropertyHist",send,received); return make_history_array(true,received); } //----------------------------------------------------------------------------------------------------------------- // // Database::get_device_pipe_property_history() - Returns the history of the specified device pipe property // //----------------------------------------------------------------------------------------------------------------- vector Database::get_device_pipe_property_history(string &devname,string &pipename,string &propname) { Any send; Any_var received; AutoConnectTimeout act(DB_RECONNECT_TIMEOUT); check_access_and_get(); DevVarStringArray *obj_info = new DevVarStringArray; obj_info->length(3); (*obj_info)[0] = string_dup(devname.c_str()); (*obj_info)[1] = string_dup(pipename.c_str()); (*obj_info)[2] = string_dup(propname.c_str()); send <<= obj_info; CALL_DB_SERVER("DbGetDevicePipePropertyHist",send,received); return make_history_array(true,received); } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_device.cpp0000644023471100065110000003224313034744772015655 00000000000000static const char *RcsId = "$Id: dbapi_device.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //=================================================================================================================== // // dbdevice.cpp - C++ source code file for TANGO dbapi class DbDevice // // programmer - Andy Gotz (goetz@esrf.fr) // // original - October 2000 // // Copyright (C) : 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // //=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::DbDevice() // // description : // Constructor to create a DbDevice object for accessing a device of this name in the specified TANGO database // (import/export info and properties) // //------------------------------------------------------------------------------------------------------------------ DbDevice::DbDevice(string &dev_name, Database *dev_dbase):ext(Tango_nullptr) { name = dev_name; dbase = dev_dbase; ext_dbase = true; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbDevice::DbDevice() // // description : // Constructor to create a DbDevice object for accessing a device of this name without specifying the // TANGO database. // //----------------------------------------------------------------------------------------------------------------- DbDevice::DbDevice(string &dev_name):ext(Tango_nullptr) { name = dev_name; db_ind = ApiUtil::instance()->get_db_ind(); ext_dbase = false; } //----------------------------------------------------------------------------------------------------------------- // // method: // DbDevice::DbDevice() // // description : // Constructor to create a DbDevice object for accessing a device of this name with specifying the TANGO // database via its server host and port // //------------------------------------------------------------------------------------------------------------------ DbDevice::DbDevice(string &dev_name,string &host,string &port_str):ext(Tango_nullptr) { name = dev_name; TangoSys_MemStream s; int port_num; s << port_str << ends; s >> port_num; db_ind = ApiUtil::instance()->get_db_ind(host,port_num); ext_dbase = false; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbDevice::~DbDevice() // // description : // Destructor to destroy a DbDevice object // //------------------------------------------------------------------------------------------------------------------ DbDevice::~DbDevice() { } //------------------------------------------------------------------------------------------------------------------ // // method : // DbDevice::get_dbase() // // description : // Public method to return the database used by this db device. // //------------------------------------------------------------------------------------------------------------------ Database *DbDevice::get_dbase() { if (ext_dbase == true) return dbase; else { ApiUtil *au = ApiUtil::instance(); return (au->get_db_vect())[db_ind]; } } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::import() // // description : // Public method to return import info for a device // //------------------------------------------------------------------------------------------------------------------ DbDevImportInfo DbDevice::import_device() { if (ext_dbase == true) return dbase->import_device(name); else { ApiUtil *au = ApiUtil::instance(); return (au->get_db_vect())[db_ind]->import_device(name); } } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::export_device() // // description : // Public method to export device to the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::export_device(DbDevExportInfo &dev_export) { if (ext_dbase == true) dbase->export_device(dev_export); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->export_device(dev_export); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::get_property() // // description : // Public method to get device properties from the database // //------------------------------------------------------------------------------------------------------------------ void DbDevice::get_property(DbData &db_data) { ApiUtil *au = ApiUtil::instance(); DbServerCache *dsc; if (au->in_server() == true) { Tango::Util *tg = Tango::Util::instance(); dsc = tg->get_db_cache(); } else dsc = NULL; if (ext_dbase == true) dbase->get_device_property(name, db_data, dsc); else { (au->get_db_vect())[db_ind]->get_device_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::put_property() // // description : // Public method to put device properties from the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::put_property(DbData &db_data) { if (ext_dbase == true) dbase->put_device_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_device_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::delete_property() // // description : // Public method to delete device properties from the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::delete_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_device_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_device_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbDevice::get_attribute_property() // // description: // Public method to get device attribute properties from the database // //------------------------------------------------------------------------------------------------------------------ void DbDevice::get_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->get_device_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->get_device_attribute_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::put_attribute_property() // // description : // Public method to put device attribute properties from the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::put_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->put_device_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_device_attribute_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::delete_attribute_property() // // description : // Public method to delete device attribute properties from the database // //------------------------------------------------------------------------------------------------------------------ void DbDevice::delete_attribute_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_device_attribute_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_device_attribute_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbDevice::get_pipe_property() // // description: // Public method to get device pipe properties from the database // //------------------------------------------------------------------------------------------------------------------ void DbDevice::get_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->get_device_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->get_device_pipe_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::put_pipe_property() // // description : // Public method to put device pipe properties from the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::put_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->put_device_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_device_pipe_property(name,db_data); } return; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::delete_pipe_property() // // description : // Public method to delete device pipe properties from the database // //------------------------------------------------------------------------------------------------------------------ void DbDevice::delete_pipe_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_device_pipe_property(name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_device_pipe_property(name,db_data); } return; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::check_access_control() // // description : // Public method to return device access right // //------------------------------------------------------------------------------------------------------------------- AccessControlType DbDevice::check_access_control() { if (ext_dbase == true) return dbase->check_access_control(name); else { ApiUtil *au = ApiUtil::instance(); Database *db = au->get_db_vect()[db_ind]; AccessControlType acc = db->check_access_control(name); return acc; } } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::clear_access_except_errors() // // description : // Public method to clear memorized access control exception // //------------------------------------------------------------------------------------------------------------------ void DbDevice::clear_access_except_errors() { if (ext_dbase == true) dbase->clear_access_except_errors(); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->clear_access_except_errors(); } } //------------------------------------------------------------------------------------------------------------------- // // method : // DbDevice::get_property_list() // // description : // Public method to get device properties list from the database // //------------------------------------------------------------------------------------------------------------------- void DbDevice::get_property_list(const string &wildcard,vector &prop_list) { ApiUtil *au = ApiUtil::instance(); DbServerCache *dsc; if (au->in_server() == true) { Tango::Util *tg = Tango::Util::instance(); dsc = tg->get_db_cache(); } else dsc = NULL; if (ext_dbase == true) { dbase->get_device_property_list(name, wildcard, prop_list, dsc); } else { (au->get_db_vect())[db_ind]->get_device_property_list(name, wildcard, prop_list); } return; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_history.cpp0000644023471100065110000001246713034744772016125 00000000000000static const char *RcsId = "$Id: dbapi_history.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; // // dbapi_history.cpp - C++ source code file for TANGO dbapi class DbHistory // // programmer - JL Pons (pons@esrf.fr) // // original - Feb 2007 // // Copyright (C) : 2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Log$ // Revision 3.6 2010/09/09 13:43:38 taurel // - Add year 2010 in Copyright notice // // Revision 3.5 2009/01/21 12:45:15 taurel // - Change CopyRights for 2009 // // Revision 3.4 2008/10/06 15:02:17 taurel // - Changed the licensing info from GPL to LGPL // // Revision 3.3 2008/10/02 16:09:25 taurel // - Add some licensing information in each files... // // Revision 3.2 2008/03/11 14:36:44 taurel // - Apply patches from Frederic Picca about compilation with gcc 4.2 // // Revision 3.1 2007/04/30 14:05:47 jlpons // Added new commands to the database client interface. // // // #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DbHistory::DbHistory() - Constructs a property // //----------------------------------------------------------------------------- DbHistory::DbHistory(string _propname,string _date,vector &svalues) { propname = _propname; date = format_mysql_date(_date); deleted = (svalues.size()==0); make_db_datum(svalues); } //----------------------------------------------------------------------------- // // DbHistory::DbHistory() - Constructs an attribute property. // //----------------------------------------------------------------------------- DbHistory::DbHistory(string _propname,string _attname,string _date,vector &svalues) { propname = _propname; attname = _attname; date = format_mysql_date(_date); deleted = (svalues.size()==0); make_db_datum(svalues); } //----------------------------------------------------------------------------- // // DbHistory::get_name() - Returns property name. // //----------------------------------------------------------------------------- string DbHistory::get_name() { return propname; } //----------------------------------------------------------------------------- // // DbHistory::get_attribute_name() - Returns attribute name. // Used when retrieving attribute property. // //----------------------------------------------------------------------------- string DbHistory::get_attribute_name() { return attname; } //----------------------------------------------------------------------------- // // DbHistory::get_date() - Returns the update date. // //----------------------------------------------------------------------------- string DbHistory::get_date() { return date; } //----------------------------------------------------------------------------- // // DbHistory::get_value() - Returns the value. // //----------------------------------------------------------------------------- DbDatum DbHistory::get_value() { return value; } //----------------------------------------------------------------------------- // // DbHistory::is_deleted() - Return true if the property is deleted. // //----------------------------------------------------------------------------- bool DbHistory::is_deleted() { return deleted; } //----------------------------------------------------------------------------- // // DbHistory::format_mysql_date() - Format mysql date using format // DD/MM/YYYY hh:mm:ss // //----------------------------------------------------------------------------- string DbHistory::format_mysql_date(string _date) { // Handle MySQL date formating if( _date.find("-")!=string::npos ) return _date.substr(8,2) + "/" + _date.substr(5,2) + "/" + _date.substr(0,4) + " " + _date.substr(11,2) + ":" + _date.substr(14,2) + ":" + _date.substr(17,2); else return _date.substr(6,2) + "/" + _date.substr(4,2) + "/" + _date.substr(0,4) + " " + _date.substr(8,2) + ":" + _date.substr(10,2) + ":" + _date.substr(12,2); } //----------------------------------------------------------------------------- // // DbHistory::make_db_datum() - Build the value as DbDatum // //----------------------------------------------------------------------------- void DbHistory::make_db_datum(vector &values) { value.name = propname; value.value_string.resize(values.size()); for (unsigned int i=0; i. // // last changed - 7/7/20003 // // version - 1.0 // #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DbAttribute::DbAttribute() - constructor to create a DbAttribute object for // accessing an attribute of this name in the specified // TANGO database (import/export info and properties) // //----------------------------------------------------------------------------- DbAttribute::DbAttribute(string &att_name, string &dev_name, Database *att_dbase) { name = att_name; device_name = dev_name; dbase = att_dbase; ext_dbase = true; } //----------------------------------------------------------------------------- // // DbAttribute::DbAttribute() - constructor to create a DbAttribute object for // accessing an attribute of this name without specifying // the TANGO database. // //----------------------------------------------------------------------------- DbAttribute::DbAttribute(string &att_name, string &dev_name) { name = att_name; device_name = dev_name; db_ind = ApiUtil::instance()->get_db_ind(); ext_dbase = false; } //----------------------------------------------------------------------------- // // DbAttribute::DbAttribute() - constructor to create a DbAttribute object for // accessing an attribute of this name with specifying // the TANGO database via its server host and port // //----------------------------------------------------------------------------- DbAttribute::DbAttribute(string &att_name, string &dev_name, string &host,string &port_str) { name = att_name; device_name = dev_name; TangoSys_MemStream s; int port_num; s << port_str << ends; s >> port_num; db_ind = ApiUtil::instance()->get_db_ind(host,port_num); ext_dbase = false; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // // DbAttribute::~DbAttribute() - destructor to destroy a DbAttribute object // //----------------------------------------------------------------------------- DbAttribute::~DbAttribute() { } //----------------------------------------------------------------------------- // // DbAttribute::get_property() - public method to get attribute properties from the database // //----------------------------------------------------------------------------- void DbAttribute::get_property(DbData &db_data) { if (ext_dbase == true) dbase->get_device_attribute_property(device_name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->get_device_attribute_property(device_name,db_data); } return; } //----------------------------------------------------------------------------- // // DbAttribute::put_property() - public method to put attribute properties from the database // //----------------------------------------------------------------------------- void DbAttribute::put_property(DbData &db_data) { if (ext_dbase == true) dbase->put_device_attribute_property(device_name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->put_device_attribute_property(device_name,db_data); } return; } //----------------------------------------------------------------------------- // // DbAttribute::delete_property() - public method to delete attribute properties from the database // //----------------------------------------------------------------------------- void DbAttribute::delete_property(DbData &db_data) { if (ext_dbase == true) dbase->delete_device_attribute_property(device_name, db_data); else { ApiUtil *au = ApiUtil::instance(); (au->get_db_vect())[db_ind]->delete_device_attribute_property(device_name,db_data); } return; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_cache.cpp0000644023471100065110000013511313034744771015460 00000000000000static const char *RcsId = "$Id: dbapi_cache.cpp 27410 2015-01-27 05:46:17Z taurel $"; //+================================================================================================================= // // file : Deviceclass.cpp // // description : C++ source code for the DbServerCache class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================ #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method: // DbServerCache::DbServerCache() // // description: // Constructor of the DbServerCache class. This class manage a data cache used during the device server // process startup phase. // // arguments: // in : // - db : The database object // - ds_name : The device server name (exec_name/inst_name) // - host : The host name // //------------------------------------------------------------------------------------------------------------------ DbServerCache::DbServerCache(Database *db,string &ds_name,string &host) { // // Get all data from database // try { received = db->fill_server_cache(ds_name,host); } catch (Tango::DevFailed &) { cout3 << "Got an exception while getting cache data from database !!" << endl; throw; } received.inout() >>= data_list; n_data = data_list->length(); // // Extract the different blocks from the big list. First the stored procedure release nb // The release number is stored as: // (major_number * 100) + minor_number // Ex: 1.9 -> 109 // proc_release = 0; string proc_rel((*data_list)[0]); if (proc_rel.find("release") != string::npos) { string rel = proc_rel.substr(8); string::size_type pos = rel.find('.'); if (pos != string::npos) { string maj_str = rel.substr(0,pos); string min_str = rel.substr(pos + 1); int maj = atoi(maj_str.c_str()); int min = atoi(min_str.c_str()); proc_release = (maj * 100) + min; } } // // First, the device server admin device parameters // int start_idx = 0; int stop_idx = 0; if (proc_release != 0) { start_idx++; stop_idx++; } if (n_data == 2 || n_data == 3) { imp_adm.first_idx = start_idx; imp_adm.last_idx = start_idx + 1; ctrl_serv_prop.first_idx = -1; DServer_class_prop.first_idx = -1; Default_prop.first_idx = -1; adm_dev_prop.first_idx = -1; return; } stop_idx = start_idx + 7; imp_adm.first_idx = start_idx; imp_adm.last_idx = stop_idx; // // Event factory // start_idx = stop_idx + 1; if (::strcmp((*data_list)[start_idx + 1],"Not Found") == 0) { stop_idx = stop_idx + 2; } else { stop_idx = stop_idx + 6; } imp_notifd_event.first_idx = start_idx; imp_notifd_event.last_idx = stop_idx; // // Server event // start_idx = stop_idx + 1; if (::strcmp((*data_list)[start_idx + 1],"Not Found") == 0) { stop_idx = stop_idx + 2; } else { stop_idx = stop_idx + 6; } imp_adm_event.first_idx = start_idx; imp_adm_event.last_idx = stop_idx; // // DServer class prop // prop_indexes(start_idx,stop_idx,DServer_class_prop,data_list); // // Default prop // prop_indexes(start_idx,stop_idx,Default_prop,data_list); // // Admin device prop // prop_indexes(start_idx,stop_idx,adm_dev_prop,data_list); // // Embedded classes number // start_idx = stop_idx + 1; class_nb = ::atoi((*data_list)[start_idx + 1]); stop_idx = stop_idx + 2; classes_idx = new ClassEltIdx [class_nb]; for (int cl_loop = 0;cl_loop < class_nb;cl_loop++) { // // Embedded class prop // prop_indexes(start_idx,stop_idx,classes_idx[cl_loop].class_prop,data_list); // // Embedded class attribute prop // prop_att_indexes(start_idx,stop_idx,classes_idx[cl_loop].class_att_prop,data_list); // // Embedded class pipe prop // if (proc_release >= 109) prop_pipe_indexes(start_idx,stop_idx,classes_idx[cl_loop].class_pipe_prop,data_list); else classes_idx[cl_loop].class_pipe_prop.atts_idx = NULL; // // Device list // start_idx = stop_idx + 1; int nb_dev = ::atoi((*data_list)[start_idx + 1]); stop_idx = stop_idx + nb_dev + 2; classes_idx[cl_loop].dev_list.first_idx = start_idx; classes_idx[cl_loop].dev_list.last_idx = stop_idx; classes_idx[cl_loop].dev_nb = nb_dev; classes_idx[cl_loop].devs_idx = new DevEltIdx [nb_dev]; for (int loop = 0;loop < nb_dev;loop++) { // // Device properties // prop_indexes(start_idx,stop_idx,classes_idx[cl_loop].devs_idx[loop].dev_prop,data_list); // // Device attribute properties // prop_att_indexes(start_idx,stop_idx,classes_idx[cl_loop].devs_idx[loop].dev_att_prop,data_list); // // Device pipe properties // if (proc_release >= 109) prop_pipe_indexes(start_idx,stop_idx,classes_idx[cl_loop].devs_idx[loop].dev_pipe_prop,data_list); else classes_idx[cl_loop].devs_idx[loop].dev_pipe_prop.atts_idx = NULL; } } // // Control System Service(s) property // prop_indexes(start_idx,stop_idx,ctrl_serv_prop,data_list); // // Tac device import info // start_idx = stop_idx + 1; if (stop_idx == n_data) { stop_idx = -1; } else { stop_idx = n_data; imp_tac.first_idx = start_idx; imp_tac.last_idx = stop_idx; } } //------------------------------------------------------------------------------------------------------------------ // // method: // DbServerCache::import_adm_dev() // // description: // This method returns to the caller of the info necessary to import the DS admin device. The returned data // are the same than the one returned by the classical API // // return: // This method returns a pointer to a DevVarLongStringArray initilised with the adm device import data // //------------------------------------------------------------------------------------------------------------------ const DevVarLongStringArray *DbServerCache::import_adm_dev() { int last_index; if (proc_release >= 109) last_index = 2; else last_index = 1; if (imp_adm.last_idx == last_index) { Tango::Except::throw_exception("aaa","bbb","ccc"); } imp_adm_data.lvalue.length(2); imp_adm_data.svalue.length(5); imp_adm_data.lvalue[0] = ::atoi((*data_list)[imp_adm.first_idx + 5]); imp_adm_data.lvalue[1] = ::atoi((*data_list)[imp_adm.last_idx]); for (int loop = 0;loop < 5;loop++) imp_adm_data.svalue[loop] = CORBA::string_dup((*data_list)[imp_adm.first_idx + loop]); return &imp_adm_data; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbServerCache::import_notifd_event() // // description : // This method returns to the caller of the info necessary to import the event associated to the notifd running // on the DS host. The returned data are the same than the one returned by the classical API // // return : // This method returns a pointer to a DevVarLongStringArray initilised with the notifd event import data // //------------------------------------------------------------------------------------------------------------------ const DevVarLongStringArray *DbServerCache::import_notifd_event() { if (imp_notifd_event.last_idx == imp_notifd_event.first_idx + 1) { Tango::Except::throw_exception("aaa","bbb","ccc"); } imp_notifd_event_data.lvalue.length(2); imp_notifd_event_data.svalue.length(5); imp_notifd_event_data.lvalue[0] = ::atoi((*data_list)[imp_notifd_event.first_idx + 4]); imp_notifd_event_data.lvalue[1] = ::atoi((*data_list)[imp_notifd_event.last_idx]); for (int loop = 0;loop < 4;loop++) imp_notifd_event_data.svalue[loop] = CORBA::string_dup((*data_list)[imp_notifd_event.first_idx + loop]); return &imp_notifd_event_data; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::import_adm_event() // // description : // This method returns to the caller of the info necessary to import the event associated to the DS server. // The returned data are the same than the one returned by the classical API // // return : // This method returns a pointer to a DevVarLongStringArray initilised with the DS event import data // //------------------------------------------------------------------------------------------------------------------- const DevVarLongStringArray *DbServerCache::import_adm_event() { if (imp_adm_event.last_idx == imp_adm_event.first_idx + 1) { Tango::Except::throw_exception("aaa","bbb","ccc"); } imp_adm_event_data.lvalue.length(2); imp_adm_event_data.svalue.length(5); imp_adm_event_data.lvalue[0] = ::atoi((*data_list)[imp_adm_event.first_idx + 4]); imp_adm_event_data.lvalue[1] = ::atoi((*data_list)[imp_notifd_event.last_idx]); for (int loop = 0;loop < 4;loop++) imp_adm_event_data.svalue[loop] = CORBA::string_dup((*data_list)[imp_adm_event.first_idx + loop]); return &imp_adm_event_data; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::get_class_property() // // description : // This method returns to the caller the wanted class properties. The returned data are the same than the one // returned by the classical API // // argument : // in : // - in_param : The class name followed by the wanted property names // // return : // This method returns a pointer to a DevVarStringArray initilised with the class properties // //------------------------------------------------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_class_property(DevVarStringArray *in_param) { int ret_length = 2; if (TG_strcasecmp((*in_param)[0],"DServer") == 0) { ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup("DServer"); get_obj_prop(in_param,DServer_class_prop); } else if (TG_strcasecmp((*in_param)[0],"Default") == 0) { ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup("Default"); get_obj_prop(in_param,Default_prop); } else { ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup((*in_param)[0]); int cl_idx = find_class((*in_param)[0]); if (cl_idx != -1) { get_obj_prop(in_param,classes_idx[cl_idx].class_prop); } else { TangoSys_OMemStream o; o << "Class " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_ClassNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_property"); } } return &ret_obj_prop; } //------------------------------------------------------------------------------------------------------------------ // // method: // DbServerCache::get_obj_prop() // // description : // This method searches the index(es) of the object wanted property within all the data returne by the DB server. // A structure will be initialised with the indexes // // argument : // in : // - in_param : The object name followed by the wanted property names // - dev_prop : Boolean set to true in case of device property. For device property, a undefined prop is // returned with a value set to " " ! // out : // - obj : Reference to the structure which will be initialsed by this method // //------------------------------------------------------------------------------------------------------------------ void DbServerCache::get_obj_prop(DevVarStringArray *in_param,PropEltIdx &obj,bool dev_prop) { int ret_length = 2; int found_prop = 0; char n_prop_str[256]; int nb_wanted_prop = in_param->length() - 1; int obj_prop = obj.prop_nb; for (int loop = 0;loop < nb_wanted_prop;loop++) { int lo; for (lo = 0;lo < obj_prop * 2;lo = lo + 2) { if (TG_strcasecmp((*in_param)[loop + 1],(*data_list)[obj.props_idx[lo]]) == 0) { int old_ret_length = ret_length; int nb_elt = obj.props_idx[lo + 1]; ret_length = ret_length + 2 + nb_elt; ret_obj_prop.length(ret_length); ret_obj_prop[old_ret_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_prop[old_ret_length + 1] = CORBA::string_dup((*data_list)[obj.props_idx[lo] + 1]); for (int k = 0;k < nb_elt;k++) { ret_obj_prop[old_ret_length + 2 + k] = CORBA::string_dup((*data_list)[obj.props_idx[lo] + 2 + k]); } found_prop++; break; } } if (lo >= (obj_prop * 2)) { int old_length = ret_length; ret_length = ret_length + 2; if (dev_prop == true) ret_length++; ret_obj_prop.length(ret_length); ret_obj_prop[old_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_prop[old_length + 1] = CORBA::string_dup("0"); if (dev_prop == true) ret_obj_prop[old_length + 2] = CORBA::string_dup(" "); found_prop++; } } ::sprintf(n_prop_str,"%d",found_prop); ret_obj_prop[1] = CORBA::string_dup(n_prop_str); // cout4 << "DbCache --> Data returned for a get_obj_property for object " << (*in_param)[0] << endl; // for (unsigned int ll=0;ll< ret_obj_prop.length();ll++) // cout4 << " DbCache --> Returned string = " << ret_obj_prop[ll] << endl; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbServerCache::get_dev_property() // // description : // This method returns to the caller the wanted device properties The returned data are the same than the one // returned by the classical API // // argument : // in : // - in_param : The device name followed by the wanted property names // // return : // This method returns a pointer to a DevVarStringArray initilised with the device properties // //------------------------------------------------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_dev_property(DevVarStringArray *in_param) { int ret_length = 2; // // There is a special case for the dserver admin device // if (TG_strncasecmp((*in_param)[0],"dserver/",8) == 0) { if (adm_dev_prop.first_idx == -1) { TangoSys_OMemStream o; o << "Device " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_property"); } ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup((*in_param)[0]); get_obj_prop(in_param,adm_dev_prop,true); } else { int class_ind,dev_ind; int res = find_dev_att((*in_param)[0],class_ind,dev_ind); if (res == -1) { TangoSys_OMemStream o; o << "Device " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_property"); } else { ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup((*in_param)[0]); get_obj_prop(in_param,classes_idx[class_ind].devs_idx[dev_ind].dev_prop,true); } } return &ret_obj_prop; } //----------------------------------------------------------------------------- // // DbServerCache::get_dev_list() // // This method returns to the list of devices for a specified class embedded // within the device server process // The returned data are the same than the one returned by // the classical API // // in : in_param : The device server name followed by the class name // // This method returns a pointer to a DevVarStringArray initilised // with the device list //----------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_dev_list(DevVarStringArray *in_param) { int cl_idx = find_class((*in_param)[1]); if (cl_idx != -1) { ret_dev_list.length(classes_idx[cl_idx].dev_nb); for (int loop = 0;loop < classes_idx[cl_idx].dev_nb;loop++) ret_dev_list[loop] = CORBA::string_dup((*data_list)[classes_idx[cl_idx].dev_list.first_idx + 2 + loop]); } else ret_dev_list.length(0); return &ret_dev_list; } //----------------------------------------------------------------------------- // // DbServerCache::find_class() // // This method returns the index of the class with name passed as parameter // into the array of classes info // // in : cl_name : The class name // // This method returns the index in the classes info array of the wanted // class //----------------------------------------------------------------------------- int DbServerCache::find_class(DevString cl_name) { for (int loop = 0;loop < class_nb;loop++) { if (TG_strcasecmp((*data_list)[classes_idx[loop].class_prop.first_idx],cl_name) == 0) return loop; } return -1; } //----------------------------------------------------------------------------- // // DbServerCache::get_class_att_property() // // This method returns to the caller the class attribute properties for the // class and attributes specified in the in parameters // The returned data are the same than the one returned by // the classical API // // in : in_param : The class name followed by the wanted // attribute names // // This method returns a pointer to a DevVarStringArray initilised // with the class attribute properties //----------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_class_att_property(DevVarStringArray *in_param) { char n_att_str[256]; ret_obj_att_prop.length(2); ret_obj_att_prop[0] = CORBA::string_dup((*in_param)[0]); int cl_idx = find_class((*in_param)[0]); if (cl_idx != -1) { int found_att = 0; // // The class is found // int wanted_att_nb = in_param->length() - 1; int class_att_nb = classes_idx[cl_idx].class_att_prop.att_nb; for (int loop = 0;loop < wanted_att_nb;loop++) { int ll; for (ll = 0;ll < class_att_nb;ll++) { if (TG_strcasecmp((*in_param)[loop + 1],(*data_list)[classes_idx[cl_idx].class_att_prop.atts_idx[ll]]) == 0) { // // The attribute is found, copy all its properties // int att_index = classes_idx[cl_idx].class_att_prop.atts_idx[ll]; int nb_prop = ::atoi((*data_list)[att_index + 1]); int nb_elt = 0; int nb_to_copy = 0; int tmp_idx = att_index + 2; nb_to_copy = 2; for (int k = 0;k < nb_prop;k++) { nb_elt = ::atoi((*data_list)[tmp_idx + 1]); tmp_idx = tmp_idx + nb_elt + 2; nb_to_copy = nb_to_copy + 2 + nb_elt; } int old_length = ret_obj_att_prop.length(); ret_obj_att_prop.length(old_length + nb_to_copy); for (int j = 0;j < nb_to_copy;j++) ret_obj_att_prop[old_length + j] = CORBA::string_dup((*data_list)[att_index + j]); found_att++; break; } } if (ll == class_att_nb) { found_att++; int old_length = ret_obj_att_prop.length(); ret_obj_att_prop.length(old_length + 2); ret_obj_att_prop[old_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_att_prop[old_length + 1] = CORBA::string_dup("0"); } } ::sprintf(n_att_str,"%d",found_att); ret_obj_att_prop[1] = CORBA::string_dup(n_att_str); } else { TangoSys_OMemStream o; o << "Class " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_ClassNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_property"); } // cout4 << "DbCache --> Returned data for a get_class_att_property for class " << (*in_param)[0] << endl; // for (unsigned int ll=0;ll< ret_obj_att_prop.length();ll++) // cout4 << " DbCache --> Returned object att prop = " << ret_obj_att_prop[ll] << endl; return &ret_obj_att_prop; } //----------------------------------------------------------------------------- // // DbServerCache::get_dev_att_property() // // This method returns to the caller the device attribute properties for the // device and attributes specified in the in parameters // The returned data are the same than the one returned by // the classical API // // in : in_param : The device name followed by the wanted // attribute names // // This method returns a pointer to a DevVarStringArray initialised // with the device attribute properties //----------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_dev_att_property(DevVarStringArray *in_param) { int found_att = 0; char n_att_str[256]; ret_obj_att_prop.length(2); ret_obj_att_prop[0] = CORBA::string_dup((*in_param)[0]); int class_ind,dev_ind; int ret_value = find_dev_att((*in_param)[0],class_ind,dev_ind); if (ret_value != -1) { int wanted_att_nb = in_param->length() - 1; int dev_att_nb = classes_idx[class_ind].devs_idx[dev_ind].dev_att_prop.att_nb; for (int loop = 0;loop < wanted_att_nb;loop++) { int ll; for (ll = 0;ll < dev_att_nb;ll++) { if (TG_strcasecmp((*in_param)[loop + 1],(*data_list)[classes_idx[class_ind].devs_idx[dev_ind].dev_att_prop.atts_idx[ll]]) == 0) { int att_index = classes_idx[class_ind].devs_idx[dev_ind].dev_att_prop.atts_idx[ll]; int nb_prop = ::atoi((*data_list)[att_index + 1]); int nb_elt = 0; int nb_to_copy = 0; int tmp_idx = att_index + 2; nb_to_copy = 2; for (int k = 0;k < nb_prop;k++) { nb_elt = ::atoi((*data_list)[tmp_idx + 1]); tmp_idx = tmp_idx + nb_elt + 2; nb_to_copy = nb_to_copy + 2 + nb_elt; } int old_length = ret_obj_att_prop.length(); ret_obj_att_prop.length(old_length + nb_to_copy); for (int j = 0;j < nb_to_copy;j++) ret_obj_att_prop[old_length + j] = CORBA::string_dup((*data_list)[att_index + j]); found_att++; break; } } if (ll == dev_att_nb) { found_att++; int old_length = ret_obj_att_prop.length(); ret_obj_att_prop.length(old_length + 2); ret_obj_att_prop[old_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_att_prop[old_length + 1] = CORBA::string_dup("0"); } } ::sprintf(n_att_str,"%d",found_att); ret_obj_att_prop[1] = CORBA::string_dup(n_att_str); } else { if (TG_strncasecmp("dserver/",(*in_param)[0],8) != 0) { TangoSys_OMemStream o; o << "Device " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_att_property"); } else { ::sprintf(n_att_str,"%d",found_att); ret_obj_att_prop[1] = CORBA::string_dup(n_att_str); } } // cout4 << "DbCache --> Returned data for a get_dev_att_property for device " << (*in_param)[0] << endl; // for (unsigned int ll=0;ll< ret_obj_att_prop.length();ll++) // cout4 << " DbCache --> Returned object att prop = " << ret_obj_att_prop[ll] << endl; return &ret_obj_att_prop; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::find_dev_att() // // description : // This method sets the class and device index for the device with name passed in the in parameter. These indexes // are indexes in the local structure arrays // // argument : // in : // - dev_name : The device name // out : // - class_ind : The index of the data related to the device class // - dev_ind : The index of the data related to the device itself // // return : // This method returns 0 if everything OK or -1 if the device is not found // //------------------------------------------------------------------------------------------------------------------- int DbServerCache::find_dev_att(DevString dev_name,int &class_ind,int &dev_ind) { for (int loop = 0;loop < class_nb;loop++) { for (int ll = 0;ll < classes_idx[loop].dev_nb;ll++) { if (TG_strcasecmp((*data_list)[classes_idx[loop].dev_list.first_idx + 2 + ll],dev_name) == 0) { class_ind = loop; dev_ind = ll; return 0; } } } return -1; } //------------------------------------------------------------------------------------------------------------------- // // method // DbServerCache::find_obj() // // description : // This method sets the class and device index for the device with name passed in the in parameter. // These indexes are indexes in the local structure arrays // // argument // in : // - obj_name : The object name // out : // - obj_ind : The index of the data related to the object // // return : // This method returns 0 if everything OK or -1 if the device is not found // //-------------------------------------------------------------------------------------------------------------------- int DbServerCache::find_obj(DevString obj_name,int &obj_ind) { if (ctrl_serv_prop.first_idx == -1) return -1; if (TG_strcasecmp((*data_list)[ctrl_serv_prop.first_idx],obj_name) == 0) { obj_ind = ctrl_serv_prop.first_idx; return 0; } return -1; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbServerCache::~DbServerCache() // // description : // destructor of the DbServerCache class // //------------------------------------------------------------------------------------------------------------------ DbServerCache::~DbServerCache() { delete [] DServer_class_prop.props_idx; delete [] Default_prop.props_idx; delete [] adm_dev_prop.props_idx; delete [] ctrl_serv_prop.props_idx; for (int cl_loop = 0;cl_loop < class_nb;cl_loop++) { if (classes_idx[cl_loop].class_prop.props_idx != NULL) delete [] classes_idx[cl_loop].class_prop.props_idx; if (classes_idx[cl_loop].class_att_prop.atts_idx != NULL) delete [] classes_idx[cl_loop].class_att_prop.atts_idx; if (classes_idx[cl_loop].class_pipe_prop.atts_idx != NULL) delete [] classes_idx[cl_loop].class_pipe_prop.atts_idx; for (int dev_loop = 0;dev_loop < classes_idx[cl_loop].dev_nb;dev_loop++) { if (classes_idx[cl_loop].devs_idx[dev_loop].dev_prop.props_idx != NULL) delete [] classes_idx[cl_loop].devs_idx[dev_loop].dev_prop.props_idx; if (classes_idx[cl_loop].devs_idx[dev_loop].dev_att_prop.atts_idx != NULL) delete [] classes_idx[cl_loop].devs_idx[dev_loop].dev_att_prop.atts_idx; if (classes_idx[cl_loop].devs_idx[dev_loop].dev_pipe_prop.atts_idx != NULL) delete [] classes_idx[cl_loop].devs_idx[dev_loop].dev_pipe_prop.atts_idx; } delete [] classes_idx[cl_loop].devs_idx; } delete [] classes_idx; } //----------------------------------------------------------------------------- // // DbServerCache::prop_indexes() // // This method computes where is the last data related to the object // in the big array coming from the Db server // // args (in) : start : The index in the array of the first data related // to the object // list : The string array coming from Db server // // args (out) : stop : The index in the array of the last data related // to the object // obj : Structure where all object parameters must be stored //----------------------------------------------------------------------------- void DbServerCache::prop_indexes(int &start,int &stop,PropEltIdx &obj,const DevVarStringArray *list) { start = stop + 1; int nb_prop = atoi((*list)[start + 1]); if (nb_prop == 0) { stop = start + 1; obj.last_idx = stop; obj.first_idx = start; obj.prop_nb = 0; obj.props_idx = NULL; return; } stop = stop + 2; int id = 0; obj.props_idx = new int[nb_prop * 2]; for (int loop = 0;loop < nb_prop;loop++) { obj.props_idx[id++] = stop + 1; int nb_elt = atoi((*list)[stop + 2]); obj.props_idx[id++] = nb_elt; stop = stop + nb_elt + 2; } obj.last_idx = stop; obj.first_idx = start; obj.prop_nb = nb_prop; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::prop_att_indexes() // // description : // This method computes where is the last data related to the object (for attribute related object) in the big // array coming from the Db server // // argument : // in : // - start : The index in the array of the first data related to the object // - list : The string array coming from Db server // // out : // - stop : The index in the array of the last data related to the object // - obj : Structure where all object parameters must be stored // //------------------------------------------------------------------------------------------------------------------- void DbServerCache::prop_att_indexes(int &start,int &stop,AttPropEltIdx &obj,const DevVarStringArray *list) { start = stop + 1; int nb_att = atoi((*list)[start + 1]); if (nb_att == 0) { stop = start + 1; obj.last_idx = stop; obj.first_idx = start; obj.att_nb = 0; obj.atts_idx = NULL; return; } int id = 0; obj.att_nb = nb_att; obj.atts_idx = new int[nb_att]; stop = start + 2; for (int ll = 0;ll < nb_att;ll++) { obj.atts_idx[id++] = stop; int nb_prop = atoi((*list)[stop + 1]); stop = stop + 2; for (int loop = 0;loop < nb_prop;loop++) { int nb_elt = atoi((*list)[stop + 1]); stop = stop + nb_elt + 2; } if (ll == (nb_att - 1)) stop--; } obj.last_idx = stop; obj.first_idx = start; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbServerCache::prop_pipe_indexes() // // description : // This method computes where is the last data related to the object (for attribute related object) in the big // array coming from the Db server // // argument : // in : // - start : The index in the array of the first data related to the object // - list : The string array coming from Db server // out : // - stop : The index in the array of the last data related to the object // - obj : Structure where all object parameters must be stored // //------------------------------------------------------------------------------------------------------------------ void DbServerCache::prop_pipe_indexes(int &start,int &stop,AttPropEltIdx &obj,const DevVarStringArray *list) { start = stop + 1; int nb_att = atoi((*list)[start + 1]); if (nb_att == 0) { stop = start + 1; obj.last_idx = stop; obj.first_idx = start; obj.att_nb = 0; obj.atts_idx = NULL; return; } int id = 0; obj.att_nb = nb_att; obj.atts_idx = new int[nb_att]; stop = start + 2; for (int ll = 0;ll < nb_att;ll++) { obj.atts_idx[id++] = stop; int nb_prop = atoi((*list)[stop + 1]); stop = stop + 2; for (int loop = 0;loop < nb_prop;loop++) { int nb_elt = atoi((*list)[stop + 1]); stop = stop + nb_elt + 2; } if (ll == (nb_att - 1)) stop--; } obj.last_idx = stop; obj.first_idx = start; } //------------------------------------------------------------------------------------------------------------------- // // method // DbServerCache::get_obj_property() // // description : // This method returns to the caller the wanted object properties. The returned data are the same than the one // returned by the classical API // // argument : // in : // - in_param : The object name followed by the wanted property names // // return : // This method returns a pointer to a DevVarStringArray initilised with the object properties // //------------------------------------------------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_obj_property(DevVarStringArray *in_param) { int obj_ind; int res = find_obj((*in_param)[0],obj_ind); if (res == -1) { TangoSys_OMemStream o; o << "Object " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_obj_property"); } else { int ret_length = 2; ret_obj_prop.length(ret_length); ret_obj_prop[0] = CORBA::string_dup((*in_param)[0]); get_obj_prop(in_param,ctrl_serv_prop,true); } return &ret_obj_prop; } //------------------------------------------------------------------------------------------------------------------ // // method : // DbServerCache::get_device_property_list() // // description : // This method returns to the caller the device property names. The returned data are the same than the one // returned by the classical API // // argument : // in : // - in_param : The device name followed by a wildcard // // return : // This method returns a pointer to a DevVarStringArray initilised with the device property names // //------------------------------------------------------------------------------------------------------------------ const DevVarStringArray *DbServerCache::get_device_property_list(DevVarStringArray *in_param) { // // There is a special case for the dserver admin device // if (TG_strncasecmp((*in_param)[0],"dserver/",8) == 0) { ret_prop_list.length(0); get_obj_prop_list(in_param,adm_dev_prop); } else { int class_ind,dev_ind; int res = find_dev_att((*in_param)[0],class_ind,dev_ind); if (res == -1) { TangoSys_OMemStream o; o << "Device " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_device_property_list"); } else { ret_prop_list.length(0); get_obj_prop_list(in_param,classes_idx[class_ind].devs_idx[dev_ind].dev_prop); } } return &ret_prop_list; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::get_obj_prop_list() // // description : // This method retrieves device property list for a device // // argument : // in : // - in_param : The device name followed by a wildcard // - obj : The device object in the cache // // retrun : // This method returns a pointer to a DevVarStringArray initialised with the device property names // //------------------------------------------------------------------------------------------------------------------ void DbServerCache::get_obj_prop_list(DevVarStringArray *in_param,PropEltIdx &obj) { // // First analyse the wildcard // bool before = false,after = false,wildcard_used; string before_str; string after_str; string wildcard((*in_param)[1]); transform(wildcard.begin(),wildcard.end(),wildcard.begin(),::tolower); string::size_type pos = wildcard.find('*'); if (pos != string::npos) { wildcard_used = true; if (pos == 0) { if (wildcard.size() == 1) { before = false; after = false; } else { before = false; after = true; after_str = wildcard.substr(pos + 1); } } else { before = true; before_str = wildcard.substr(0,pos); if (pos == wildcard.size() - 1) after = false; else { after = true; after_str = wildcard.substr(pos + 1); } } } else wildcard_used = false; int ret_length = 1; int obj_prop = obj.prop_nb; int lo; string::size_type pos_after,pos_before; // // A loop on each prop. // for (lo = 0;lo < obj_prop * 2;lo = lo + 2) { // // Check according to the user wildcard, if we have to returned this property name // Note: The property name is case independant // bool store = false; if (wildcard_used == true) { if (before == false) { if (after == false) store = true; else { string tmp_name((*data_list)[obj.props_idx[lo]]); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); pos_after = tmp_name.rfind(after_str); if ((pos_after != string::npos) && (pos_after == (tmp_name.size() - after_str.size()))) store = true; } } else { string tmp_name((*data_list)[obj.props_idx[lo]]); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (after == false) { pos_before = tmp_name.find(before_str); if ((pos_before != string::npos) && (pos_before == 0)) store = true; } else { pos_before = tmp_name.find(before_str); pos_after = tmp_name.rfind(after_str); if ((pos_before != string::npos) && (pos_before == 0) && (pos_after != string::npos) && (pos_after == (tmp_name.size() - after_str.size()))) store = true; } } } else { string tmp_name((*data_list)[obj.props_idx[lo]]); transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower); if (tmp_name == wildcard) store = true; } // // Store the property name if decided // if (store == true) { ret_prop_list.length(ret_length); ret_prop_list[ret_length - 1] = CORBA::string_dup((*data_list)[obj.props_idx[lo]]); ret_length = ret_length + 1; } } } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::import_tac_dev() // // description : // This method returns to the caller of the info necessary to import the TAC device. // The returned data are the same than the one returned by the classical API // // return : // This method returns a pointer to a DevVarLongStringArray initilised with the Tango access control import data // //------------------------------------------------------------------------------------------------------------------- const DevVarLongStringArray *DbServerCache::import_tac_dev(string &tac_dev) { // // Throw exception if no info in cache // if (imp_tac.last_idx == -1 || imp_tac.first_idx >= (int)data_list->length()) { Tango::Except::throw_exception((const char *)API_DatabaseCacheAccess, (const char *)"No TAC device in Db cache", (const char *)"DbServerCache::import_tac_dev"); } // // Throw exception if the device in cache is not the requested one // if (tac_dev.size() != strlen((*data_list)[imp_tac.first_idx])) { Tango::Except::throw_exception((const char *)API_DatabaseCacheAccess, (const char *)"Device not available from cache", (const char *)"DbServerCache::import_tac_dev"); } string local_tac_dev(tac_dev); string cache_tac_dev((*data_list)[imp_tac.first_idx]); transform(local_tac_dev.begin(),local_tac_dev.end(),local_tac_dev.begin(),::tolower); transform(cache_tac_dev.begin(),cache_tac_dev.end(),cache_tac_dev.begin(),::tolower); if (local_tac_dev != cache_tac_dev) { Tango::Except::throw_exception((const char *)API_DatabaseCacheAccess, (const char *)"Device not available from cache", (const char *)"DbServerCache::import_tac_dev"); } // // Throw exception if the device is not found in DB // if (::strcmp((*data_list)[imp_tac.first_idx + 1],"Not Found") == 0) { TangoSys_OMemStream o; o << "Device " << tac_dev << " not defined in database" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotDefined",o.str(), (const char *)"DbServerCache::import_tac_dev"); } // // Return cache data // imp_tac_data.lvalue.length(2); imp_tac_data.svalue.length(5); imp_tac_data.lvalue[0] = ::atoi((*data_list)[imp_tac.first_idx + 5]); imp_tac_data.lvalue[1] = ::atoi((*data_list)[imp_tac.last_idx - 1]); for (int loop = 0;loop < 5;loop++) imp_tac_data.svalue[loop] = CORBA::string_dup((*data_list)[imp_tac.first_idx + loop]); return &imp_tac_data; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::get_class_pipe_property() // // description : // This method returns to the caller the class pipe properties for the class and pipes specified in // the in parameters. The returned data are the same than the one returned by the classical API // // argument // in : // - in_param : The class name followed by the wanted pipe names // // return : // This method returns a pointer to a DevVarStringArray initilised with the class pipe properties // //------------------------------------------------------------------------------------------------------------------- const DevVarStringArray *DbServerCache::get_class_pipe_property(DevVarStringArray *in_param) { // // Throw exception if stored procedure does not support pipe // if (proc_release < 109) { string mess("Your database stored procedure is too old to support pipe. Please update to stored procedure release 1.9 or more"); Tango::Except::throw_exception("DB_TooOldStoredProc",mess,"DbServerCache::get_class_pipe_property"); } int found_pipe = 0; char n_pipe_str[256]; ret_obj_pipe_prop.length(2); ret_obj_pipe_prop[0] = CORBA::string_dup((*in_param)[0]); int cl_idx = find_class((*in_param)[0]); if (cl_idx != -1) { // // The class is found // int wanted_pipe_nb = in_param->length() - 1; int class_pipe_nb = classes_idx[cl_idx].class_pipe_prop.att_nb; for (int loop = 0;loop < wanted_pipe_nb;loop++) { int ll; for (ll = 0;ll < class_pipe_nb;ll++) { if (TG_strcasecmp((*in_param)[loop + 1],(*data_list)[classes_idx[cl_idx].class_pipe_prop.atts_idx[ll]]) == 0) { // // The pipe is found, copy all its properties // int pipe_index = classes_idx[cl_idx].class_pipe_prop.atts_idx[ll]; int nb_prop = ::atoi((*data_list)[pipe_index + 1]); int nb_elt = 0; int nb_to_copy = 0; int tmp_idx = pipe_index + 2; nb_to_copy = 2; for (int k = 0;k < nb_prop;k++) { nb_elt = ::atoi((*data_list)[tmp_idx + 1]); tmp_idx = tmp_idx + nb_elt + 2; nb_to_copy = nb_to_copy + 2 + nb_elt; } int old_length = ret_obj_pipe_prop.length(); ret_obj_pipe_prop.length(old_length + nb_to_copy); for (int j = 0;j < nb_to_copy;j++) ret_obj_pipe_prop[old_length + j] = CORBA::string_dup((*data_list)[pipe_index + j]); found_pipe++; break; } } if (ll == class_pipe_nb) { found_pipe++; int old_length = ret_obj_pipe_prop.length(); ret_obj_pipe_prop.length(old_length + 2); ret_obj_pipe_prop[old_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_pipe_prop[old_length + 1] = CORBA::string_dup("0"); } } ::sprintf(n_pipe_str,"%d",found_pipe); ret_obj_pipe_prop[1] = CORBA::string_dup(n_pipe_str); } else { TangoSys_OMemStream o; o << "Class " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception("DB_ClassNotFoundInCache",o.str(), "DbServerCache::get_class_pipe_property"); } // cout4 << "DbCache --> Returned data for a get_class_pipe_property for class " << (*in_param)[0] << endl; // for (unsigned int ll=0;ll< ret_obj_pipe_prop.length();ll++) // cout4 << " DbCache --> Returned object pipe prop = " << ret_obj_pipe_prop[ll] << endl; return &ret_obj_pipe_prop; } //------------------------------------------------------------------------------------------------------------------- // // method : // DbServerCache::get_dev_pipe_property() // // description : // This method returns to the caller the device pipe properties for the device and pipes specified in // the in parameters. The returned data are the same than the one returned by the classical API // // argument // in : // - in_param : The device name followed by the wanted pipe names // // return : // This method returns a pointer to a DevVarStringArray initialised with the device pipe properties // //------------------------------------------------------------------------------------------------------------------ const DevVarStringArray *DbServerCache::get_dev_pipe_property(DevVarStringArray *in_param) { // // Throw exception if stored procedure does not support pipe // if (proc_release < 109) { string mess("Your database stored procedure is too old to support pipe. Please update to stored procedure release 1.9 or more"); Tango::Except::throw_exception("DB_TooOldStoredProc",mess,"DbServerCache::get_dev_pipe_property"); } int found_pipe = 0; char n_pipe_str[256]; ret_obj_pipe_prop.length(2); ret_obj_pipe_prop[0] = CORBA::string_dup((*in_param)[0]); int class_ind,dev_ind; int ret_value = find_dev_att((*in_param)[0],class_ind,dev_ind); if (ret_value != -1) { int wanted_pipe_nb = in_param->length() - 1; int dev_pipe_nb = classes_idx[class_ind].devs_idx[dev_ind].dev_pipe_prop.att_nb; for (int loop = 0;loop < wanted_pipe_nb;loop++) { int ll; for (ll = 0;ll < dev_pipe_nb;ll++) { if (TG_strcasecmp((*in_param)[loop + 1],(*data_list)[classes_idx[class_ind].devs_idx[dev_ind].dev_pipe_prop.atts_idx[ll]]) == 0) { int pipe_index = classes_idx[class_ind].devs_idx[dev_ind].dev_pipe_prop.atts_idx[ll]; int nb_prop = ::atoi((*data_list)[pipe_index + 1]); int nb_elt = 0; int nb_to_copy = 0; int tmp_idx = pipe_index + 2; nb_to_copy = 2; for (int k = 0;k < nb_prop;k++) { nb_elt = ::atoi((*data_list)[tmp_idx + 1]); tmp_idx = tmp_idx + nb_elt + 2; nb_to_copy = nb_to_copy + 2 + nb_elt; } int old_length = ret_obj_pipe_prop.length(); ret_obj_pipe_prop.length(old_length + nb_to_copy); for (int j = 0;j < nb_to_copy;j++) ret_obj_pipe_prop[old_length + j] = CORBA::string_dup((*data_list)[pipe_index + j]); found_pipe++; break; } } if (ll == dev_pipe_nb) { found_pipe++; int old_length = ret_obj_pipe_prop.length(); ret_obj_pipe_prop.length(old_length + 2); ret_obj_pipe_prop[old_length] = CORBA::string_dup((*in_param)[loop + 1]); ret_obj_pipe_prop[old_length + 1] = CORBA::string_dup("0"); } } ::sprintf(n_pipe_str,"%d",found_pipe); ret_obj_pipe_prop[1] = CORBA::string_dup(n_pipe_str); } else { if (TG_strncasecmp("dserver/",(*in_param)[0],8) != 0) { TangoSys_OMemStream o; o << "Device " << (*in_param)[0] << " not found in DB cache" << ends; Tango::Except::throw_exception((const char *)"DB_DeviceNotFoundInCache",o.str(), (const char *)"DbServerCache::get_dev_pipe_property"); } else { ::sprintf(n_pipe_str,"%d",found_pipe); ret_obj_pipe_prop[1] = CORBA::string_dup(n_pipe_str); } } // cout4 << "DbCache --> Returned data for a get_dev_pipe_property for device " << (*in_param)[0] << endl; // for (unsigned int ll=0;ll< ret_obj_pipe_prop.length();ll++) // cout4 << " DbCache --> Returned object pipe prop = " << ret_obj_pipe_prop[ll] << endl; return &ret_obj_pipe_prop; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/dbapi_serverdata.cpp0000644023471100065110000005406113034744771016557 00000000000000static const char *RcsId = "$Id$"; //+=================================================================================================================== // // file : dbapi_serverdata.cpp // // description : C++ source code for the DbServerData class // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or (at your option) // any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // //-=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::DbServerData // // description: // constructor for the DbServerData class. This class data stored in the database related to a device server // process. It allows easy insert/remove of one device server process from one database to another // // argument: // in : // exec_name : The device server process exec name // inst_name : The device server process instance name // //-------------------------------------------------------------------------------------------------------------------- DbServerData::DbServerData(const string &exec_name,const string &inst_name) { full_server_name = exec_name + '/' + inst_name; // // Check if server defined in database // string adm_name("dserver/"); adm_name = adm_name + full_server_name; Database *db_ptr = NULL; try { DeviceProxy adm(adm_name); ApiUtil *au = ApiUtil::instance(); int ind = au->get_db_ind(adm.get_db_host(),adm.get_db_port_num()); db_ptr = au->get_db_vect()[ind]; } catch (Tango::DevFailed &e) { stringstream ss; ss << "Device server process " << full_server_name << " is not defined in database"; Tango::Except::throw_exception("DBServerNotDefinedInDb",ss.str(),"DbServerData::DbServerData"); } // // Build Server classes // TangoClass tc("DServer",full_server_name,db_ptr); classes.push_back(tc); DbDatum svr_class_list = db_ptr->get_server_class_list(full_server_name); vector vs; svr_class_list >> vs; for (size_t loop = 0;loop < vs.size();loop++) { TangoClass tc(vs[loop],full_server_name,db_ptr); classes.push_back(tc); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::put_in_database // // description: // Store all the data related to the device server process in the database specified by the input arg. // // argument: // in : // tg_host : The tango host for the new database // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::put_in_database(const string &tg_host) { // // Check tango host syntax // string::size_type pos; if ((pos = tg_host.find(':')) == string::npos) { stringstream ss; ss << tg_host << " is not a valid synatx for Tango host (host:port)"; Tango::Except::throw_exception("DBWrongTangoHostSyntax",ss.str(),"DbServerData::put_in_database"); } // // Create db object // string db_host = tg_host.substr(0,pos); string db_port_str = tg_host.substr(pos + 1); stringstream ss; ss << db_port_str; int db_port; ss >> db_port; Database *db_ptr = new Database(db_host,db_port); // // Create server in DB and put associated properties // create_server(db_ptr); put_properties(db_ptr); } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::already_exist // // description: // Check if any of the device server process device(s) is already defined in the database specified by the // tango host given as input arg // // argument: // in : // tg_host : The tango host for the database // // return: // True in case any of the device is already known. False otherwise // //-------------------------------------------------------------------------------------------------------------------- bool DbServerData::already_exist(const string &tg_host) { // // Check tango host syntax // if (tg_host.find(':') == string::npos) { stringstream ss; ss << tg_host << " is not a valid synatx for Tango host (host:port)"; Tango::Except::throw_exception("DBWrongTangoHostSyntax",ss.str(),"DbServerData::already_exist"); } string header("tango://"); header = header + tg_host + '/'; // // Check if server is defined and immediately returned if it is defined // try { string adm_name(header); adm_name = adm_name + "dserver/" + full_server_name; DeviceProxy adm(adm_name); return true; } catch (Tango::DevFailed &) {} // // Check if at least one device already defined // for (size_t loop = 0;loop < classes.size();loop++) { for (size_t ctr = 0;ctr < classes[loop].size();ctr++) { string dev_name = header + classes[loop][ctr].name; try { DeviceProxy dev(dev_name); return true; } catch (Tango::DevFailed &e) { string desc(e.errors[0].desc.in()); if (desc.find("not defined in the database") == string::npos) { stringstream ss; ss << "Failed to check " << dev_name << " in Tango host " << tg_host << endl; Tango::Except::re_throw_exception(e,"DBFailedToCheck",ss.str(),"DbServerData::already_exist"); } } } } return false; } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::create_server // // description: // Create the device server process with all its devices in the database given as input arg // // argument: // in : // db_ptr : Ptr to the database object // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::create_server(Database *db_ptr) { DbDevInfos db_infs; for (size_t loop = 0;loop < classes.size();loop++) { for (size_t lo = 0;lo < classes[loop].size();lo++) { DbDevInfo ddi; ddi.name = classes[loop][lo].name; ddi._class = classes[loop].name; ddi.server = full_server_name; db_infs.push_back(ddi); } } db_ptr->add_server(full_server_name,db_infs); } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::put_properties // // description: // Store all properties (for classes and devices) in the database specified by the input arg // // argument: // in : // db_ptr : Ptr to the database object // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::put_properties(Database *db_ptr) { for (size_t loop = 0;loop < classes.size();loop++) { classes[loop].put_properties(db_ptr); classes[loop].put_attribute_properties(db_ptr); classes[loop].put_pipe_properties(db_ptr); for (size_t ctr = 0;ctr < classes[loop].size();ctr++) { classes[loop][ctr].put_properties(db_ptr); classes[loop][ctr].put_attribute_properties(db_ptr); classes[loop][ctr].put_pipe_properties(db_ptr); } } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::remove // // description: // Remove device server process from a database // // argument: // in : // tg_host : The tango host for the new database // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::remove(const string &tg_host) { // // Check tango host syntax // string::size_type pos; if ((pos = tg_host.find(':')) == string::npos) { stringstream ss; ss << tg_host << " is not a valid synatx for Tango host (host:port)"; Tango::Except::throw_exception("DBWrongTangoHostSyntax",ss.str(),"DbServerData::remove"); } // // Create db object // string db_host = tg_host.substr(0,pos); string db_port_str = tg_host.substr(pos + 1); stringstream ss; ss << db_port_str; int db_port; ss >> db_port; Database *db_ptr = new Database(db_host,db_port); try { // // Delete devices // for (size_t loop = classes.size();loop != 0;loop--) { for (size_t ctr = 0;ctr < classes[loop - 1].size();ctr++) { db_ptr->delete_device(classes[loop - 1][ctr].name); } } // // Also delete class properties if this is the last class instance in DB // Forget DServer class // for (size_t loop = 1;loop < classes.size();loop++) { string all("*"); DbDatum dev_list = db_ptr->get_device_name(all,classes[loop].name); if (dev_list.value_string.empty() == true) { classes[loop].remove_properties(db_ptr); } } } catch(Tango::DevFailed &) { delete db_ptr; throw; } delete db_ptr; } void DbServerData::remove() { // // Get from one device the tango host // string &db_host = classes[0][0].get_db_host(); string &db_port = classes[0][0].get_db_port(); string tg_host = db_host + ":" + db_port; remove(tg_host); } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoDevice::TangoDevice // // description: // Constructor for the DbServerData inner structure TangoDevice. There is one instance of this struc for // every device defined in the device server process // // argument: // in : // na : The device name // //-------------------------------------------------------------------------------------------------------------------- DbServerData::TangoDevice::TangoDevice(string &na):DeviceProxy(na),name(na) { // // First read device properties // vector prop_list; get_property_list("*",prop_list); if (prop_list.empty() == false) { DbData prop_val; get_property(prop_list,prop_val); for (size_t loop = 0; loop < prop_list.size();loop++) { if (prop_val[loop].is_empty() == false) { TangoProperty tp(prop_list[loop],prop_val[loop].value_string); properties.push_back(tp); } } } // // Get attribute list from db // ApiUtil *au = ApiUtil::instance(); int ind = au->get_db_ind(get_db_host(),get_db_port_num()); Database *db = au->get_db_vect()[ind]; vector att_list; db->get_device_attribute_list(name,att_list); for (size_t loop = 0; loop < att_list.size();loop++) { DbData db_data; db_data.push_back(DbDatum(att_list[loop])); db->get_device_attribute_property(na,db_data); for (size_t lo = 1;lo < db_data.size();lo++) { if (db_data[lo].is_empty() == false) { TangoAttribute ta(att_list[loop]); ta.push_back(TangoProperty(db_data[lo].name,db_data[lo].value_string)); attributes.push_back(ta); } } } // // Then get pipe list from db // vector pipe_list; try { db->get_device_pipe_list(name,pipe_list); for (size_t loop = 0; loop < pipe_list.size();loop++) { DbData db_data; db_data.push_back(DbDatum(pipe_list[loop])); db->get_device_pipe_property(na,db_data); for (size_t lo = 1;lo < db_data.size();lo++) { if (db_data[lo].is_empty() == false) { TangoPipe ta(pipe_list[loop]); ta.push_back(TangoProperty(db_data[lo].name,db_data[lo].value_string)); pipes.push_back(ta); } } } } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason != "API_CommandNotFound") throw; } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoDevice::put_properties // // description: // Store in database all the properties belonging to the device // // argument: // in : // db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoDevice::put_properties(Database *db_ptr) { if (properties.empty() == false) { DbData db_data; for (size_t ctr = 0;ctr < properties.size();ctr++) { DbDatum prop(properties[ctr].name); prop.value_string = properties[ctr].values; db_data.push_back(prop); } db_ptr->put_device_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoDevice::put_attribute_properties // // description: // Store in database all the properties belonging to the device attribute(s) // // argument: // in : // db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoDevice::put_attribute_properties(Database *db_ptr) { if (attributes.empty() == false) { DbData db_data; for (size_t loop = 0;loop < attributes.size();loop++) { if (attributes[loop].empty() == false) { DbDatum db_d(attributes[loop].name); db_d << (DevLong)attributes[loop].size(); db_data.push_back(db_d); for (size_t ctr = 0;ctr < attributes[loop].size();ctr++) { DbDatum db(attributes[loop][ctr].name); db.value_string = attributes[loop][ctr].values; db_data.push_back(db); } } } db_ptr->put_device_attribute_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoDevice::put_pipe_properties // // description: // Store in database all the properties belonging to the device pipe(s) // // argument: // in : // db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoDevice::put_pipe_properties(Database *db_ptr) { if (pipes.empty() == false) { DbData db_data; for (size_t loop = 0;loop < pipes.size();loop++) { if (pipes[loop].empty() == false) { DbDatum db_d(pipes[loop].name); db_d << (DevLong)pipes[loop].size(); db_data.push_back(db_d); for (size_t ctr = 0;ctr < pipes[loop].size();ctr++) { DbDatum db(pipes[loop][ctr].name); db.value_string = pipes[loop][ctr].values; db_data.push_back(db); } } } db_ptr->put_device_pipe_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoClass::TangoClass // // description: // Constructor for the DbServerData inner structure TangoClass. There is one instance of this struc for // every tango class defined in the device server process // // argument: // in : // - na : The Tango class name // - full_ds_name : The device server process name // - db : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- DbServerData::TangoClass::TangoClass(const string &na,const string &full_ds_name,Database *db):name(na) { // // First, read class properties // DbDatum cl_prop = db->get_class_property_list(name); if (cl_prop.is_empty() == false) { vector vs; cl_prop >> vs; DbData db_data; for (size_t loop = 0;loop < vs.size();loop++) db_data.push_back(DbDatum(vs[loop])); db->get_class_property(name,db_data); for (size_t loop = 0;loop < vs.size();loop++) { TangoProperty tp(db_data[loop].name,db_data[loop].value_string); properties.push_back(tp); } } // // Get class attribute list // string all("*"); DbDatum cl_att_list = db->get_class_attribute_list(name,all); if (cl_att_list.is_empty() == false) { vector vs; cl_att_list >> vs; for (size_t loop = 0;loop < vs.size();loop++) { DbData db_data; db->get_class_attribute_property(vs[loop],db_data); for (size_t lo = 0;lo < db_data.size();lo++) { TangoAttribute ta(vs[loop]); ta.push_back(TangoProperty(db_data[lo].name,db_data[lo].value_string)); attributes.push_back(ta); } } } // // Get class pipe list // try { DbDatum cl_pipe_list = db->get_class_pipe_list(name,all); if (cl_pipe_list.is_empty() == false) { vector vs; cl_pipe_list >> vs; for (size_t loop = 0;loop < vs.size();loop++) { DbData db_data; db->get_class_pipe_property(vs[loop],db_data); for (size_t lo = 0;lo < db_data.size();lo++) { TangoPipe ta(vs[loop]); ta.push_back(TangoProperty(db_data[lo].name,db_data[lo].value_string)); pipes.push_back(ta); } } } } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason != "API_CommandNotFound") throw; } // // Get all devices for this class // DbDatum dev_names = db->get_device_name(const_cast(full_ds_name),name); for (size_t loop = 0;loop < dev_names.value_string.size();loop++) { TangoDevice td(dev_names.value_string[loop]); push_back(td); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoClass::put_properties // // description: // Store in database all the class properties // // argument: // in : // - db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoClass::put_properties(Database *db_ptr) { if (properties.empty() == false) { DbData db_data; for (size_t ctr = 0;ctr < properties.size();ctr++) { DbDatum prop(properties[ctr].name); prop.value_string = properties[ctr].values; db_data.push_back(prop); } db_ptr->put_class_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoClass::put_attribute_properties // // description: // Store in database all the class attribute properties // // argument: // in : // - db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoClass::put_attribute_properties(Database *db_ptr) { if (attributes.empty() == false) { DbData db_data; for (size_t loop = 0;loop < attributes.size();loop++) { if (attributes[loop].empty() == false) { DbDatum db_d(attributes[loop].name); db_d << (DevLong)attributes[loop].size(); db_data.push_back(db_d); for (size_t ctr = 0;ctr < attributes[loop].size();ctr++) { DbDatum db(attributes[loop][ctr].name); db.value_string = attributes[loop][ctr].values; db_data.push_back(db); } } } db_ptr->put_class_attribute_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoClass::put_pipe_properties // // description: // Store in database all the class pipe properties // // argument: // in : // - db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoClass::put_pipe_properties(Database *db_ptr) { if (pipes.empty() == false) { DbData db_data; for (size_t loop = 0;loop < pipes.size();loop++) { if (pipes[loop].empty() == false) { DbDatum db_d(pipes[loop].name); db_d << (DevLong)pipes[loop].size(); db_data.push_back(db_d); for (size_t ctr = 0;ctr < pipes[loop].size();ctr++) { DbDatum db(pipes[loop][ctr].name); db.value_string = pipes[loop][ctr].values; db_data.push_back(db); } } } db_ptr->put_class_pipe_property(name,db_data); } } //-------------------------------------------------------------------------------------------------------------------- // // method: // DbServerData::TangoClass::remove_properties // // description: // Remove from the database all the class properties // // argument: // in : // - db_ptr : Pointer to the database instance // //-------------------------------------------------------------------------------------------------------------------- void DbServerData::TangoClass::remove_properties(Database *db_ptr) { // // Delete class properties if any // if (properties.empty() == false) { DbData props; for (size_t loop = 0;loop < properties.size();loop++) props.push_back(DbDatum(properties[loop].name)); db_ptr->delete_class_property(name,props); } // // Delete class attribute properties if any // if (attributes.empty() == false) { for (size_t loop = 0;loop < attributes.size();loop++) { if (attributes[loop].empty() == false) { DbData db_data; db_data.push_back(DbDatum(attributes[loop].name)); for (size_t ctr = 0;ctr < attributes[loop].size();ctr++) db_data.push_back(DbDatum(attributes[loop][ctr].name)); db_ptr->delete_class_attribute_property(name,db_data); } } } // // Delete class pipe properties if any // if (pipes.empty() == false) { for (size_t loop = 0;loop < pipes.size();loop++) { if (pipes[loop].empty() == false) { DbData db_data; db_data.push_back(DbDatum(pipes[loop].name)); for (size_t ctr = 0;ctr < pipes[loop].size();ctr++) db_data.push_back(DbDatum(pipes[loop][ctr].name)); db_ptr->delete_class_pipe_property(name,db_data); } } } } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/devapi_attr.cpp0000644023471100065110000045754413034744771015577 00000000000000static const char *RcsId = "$Id: devapi_attr.cpp 27976 2015-05-18 13:59:32Z taurel $\n$Name$"; //=================================================================================================================== // // devapi_attr.cpp - C++ source code file for TANGO devapi class DeviceAttribute // // programmer(s) - Andy Gotz (goetz@esrf.fr) // // original - February 2002 // // Copyright (C) : 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see // // $Revision: 27976 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DeviceAttributeExt::assignment operator // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttributeExt &DeviceAttribute::DeviceAttributeExt::operator=(TANGO_UNUSED(const DeviceAttribute::DeviceAttributeExt &rval)) { ext_state = rval.ext_state; return *this; } void DeviceAttribute::DeviceAttributeExt::deep_copy(TANGO_UNUSED(const DeviceAttribute::DeviceAttributeExt &rval)) { ext_state = rval.ext_state; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - default constructor to create DeviceAttribute // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute():ext(new DeviceAttributeExt) { name = "Name not set"; dim_x = 0; dim_y = 0; w_dim_x = 0; w_dim_y = 0; time.tv_sec = 0; time.tv_usec = 0; time.tv_nsec = 0; quality = Tango::ATTR_INVALID; data_format = Tango::FMT_UNKNOWN; data_type = Tango::DATA_TYPE_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - copy constructor to create DeviceAttribute // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(const DeviceAttribute & source):ext(Tango_nullptr) { name = source.name; exceptions_flags = source.exceptions_flags; dim_x = source.dim_x; dim_y = source.dim_y; w_dim_x = source.w_dim_x; w_dim_y = source.w_dim_y; quality = source.quality; data_format = source.data_format; data_type = source.data_type; time = source.time; err_list = source.err_list; #ifdef HAS_RVALUE LongSeq = source.LongSeq; ShortSeq = source.ShortSeq; DoubleSeq = source.DoubleSeq; StringSeq = source.StringSeq; FloatSeq = source.FloatSeq; BooleanSeq = source.BooleanSeq; UShortSeq = source.UShortSeq; UCharSeq = source.UCharSeq; Long64Seq = source.Long64Seq; ULongSeq = source.ULongSeq; ULong64Seq = source.ULong64Seq; StateSeq = source.StateSeq; EncodedSeq = source.EncodedSeq; #else DeviceAttribute &nc_source = const_cast(source); if (nc_source.LongSeq.operator->() != NULL) LongSeq = nc_source.LongSeq._retn(); if (nc_source.ShortSeq.operator->() != NULL) ShortSeq = nc_source.ShortSeq._retn(); if (nc_source.DoubleSeq.operator->() != NULL) DoubleSeq = nc_source.DoubleSeq._retn(); if (nc_source.StringSeq.operator->() != NULL) StringSeq = nc_source.StringSeq._retn(); if (nc_source.FloatSeq.operator->() != NULL) FloatSeq = nc_source.FloatSeq._retn(); if (nc_source.BooleanSeq.operator->() != NULL) BooleanSeq = nc_source.BooleanSeq._retn(); if (nc_source.UShortSeq.operator->() != NULL) UShortSeq = nc_source.UShortSeq._retn(); if (nc_source.UCharSeq.operator->() != NULL) UCharSeq = nc_source.UCharSeq._retn(); if (nc_source.Long64Seq.operator->() != NULL) Long64Seq = nc_source.Long64Seq._retn(); if (nc_source.ULongSeq.operator->() != NULL) ULongSeq = nc_source.ULongSeq._retn(); if (nc_source.ULong64Seq.operator->() != NULL) ULong64Seq = nc_source.ULong64Seq._retn(); if (nc_source.StateSeq.operator->() != NULL) StateSeq = nc_source.StateSeq._retn(); if (nc_source.EncodedSeq.operator->() != NULL) EncodedSeq = nc_source.EncodedSeq._retn(); #endif d_state = source.d_state; d_state_filled = source.d_state_filled; #ifdef HAS_UNIQUE_PTR if (source.ext.get() != NULL) { ext.reset(new DeviceAttributeExt); *(ext.get()) = *(source.ext.get()); } #else if (source.ext != NULL) { ext = new DeviceAttributeExt(); *ext = *(source.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - move constructor to create DeviceAttribute // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DeviceAttribute::DeviceAttribute(DeviceAttribute &&source):ext(Tango_nullptr) { name = move(source.name); exceptions_flags = source.exceptions_flags; dim_x = source.dim_x; dim_y = source.dim_y; w_dim_x = source.w_dim_x; w_dim_y = source.w_dim_y; quality = source.quality; data_format = source.data_format; data_type = source.data_type; time = source.time; err_list = source.err_list; if (source.LongSeq.operator->() != NULL) LongSeq = source.LongSeq._retn(); if (source.ShortSeq.operator->() != NULL) ShortSeq = source.ShortSeq._retn(); if (source.DoubleSeq.operator->() != NULL) DoubleSeq = source.DoubleSeq._retn(); if (source.StringSeq.operator->() != NULL) StringSeq = source.StringSeq._retn(); if (source.FloatSeq.operator->() != NULL) FloatSeq = source.FloatSeq._retn(); if (source.BooleanSeq.operator->() != NULL) BooleanSeq = source.BooleanSeq._retn(); if (source.UShortSeq.operator->() != NULL) UShortSeq = source.UShortSeq._retn(); if (source.UCharSeq.operator->() != NULL) UCharSeq = source.UCharSeq._retn(); if (source.Long64Seq.operator->() != NULL) Long64Seq = source.Long64Seq._retn(); if (source.ULongSeq.operator->() != NULL) ULongSeq = source.ULongSeq._retn(); if (source.ULong64Seq.operator->() != NULL) ULong64Seq = source.ULong64Seq._retn(); if (source.StateSeq.operator->() != NULL) StateSeq = source.StateSeq._retn(); if (source.EncodedSeq.operator->() != NULL) EncodedSeq = source.EncodedSeq._retn(); d_state = source.d_state; d_state_filled = source.d_state_filled; if (source.ext.get() != NULL) ext = move(source.ext); } #endif void DeviceAttribute::deep_copy(const DeviceAttribute & source) { name = source.name; exceptions_flags = source.exceptions_flags; dim_x = source.dim_x; dim_y = source.dim_y; w_dim_x = source.w_dim_x; w_dim_y = source.w_dim_y; quality = source.quality; data_format = source.data_format; data_type = source.data_type; time = source.time; err_list = source.err_list; LongSeq = source.LongSeq; ShortSeq = source.ShortSeq; DoubleSeq = source.DoubleSeq; StringSeq = source.StringSeq; FloatSeq = source.FloatSeq; BooleanSeq = source.BooleanSeq; UShortSeq = source.UShortSeq; UCharSeq = source.UCharSeq; Long64Seq = source.Long64Seq; ULongSeq = source.ULongSeq; ULong64Seq = source.ULong64Seq; StateSeq = source.StateSeq; EncodedSeq = source.EncodedSeq; d_state = source.d_state; d_state_filled = source.d_state_filled; #ifdef HAS_UNIQUE_PTR if (source.ext.get() != NULL) { ext.reset(new DeviceAttributeExt); ext.get()->deep_copy(*(source.ext.get())); } else ext.reset(); #else if (source.ext != NULL) { if (ext == NULL) ext = new DeviceAttributeExt(); ext->deep_copy(*source.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // DeviceAttribute::get_x_dimension - Get attribute data transfer dimension // //----------------------------------------------------------------------------- AttributeDimension DeviceAttribute::get_r_dimension() { AttributeDimension d; d.dim_x = dim_x; d.dim_y = dim_y; return d; } long DeviceAttribute::get_nb_read() { if (dim_y == 0) return dim_x; else return dim_x * dim_y; } AttributeDimension DeviceAttribute::get_w_dimension() { AttributeDimension d; d.dim_x = w_dim_x; d.dim_y = w_dim_y; return d; } long DeviceAttribute::get_nb_written() { if (w_dim_y == 0) return w_dim_x; else return w_dim_x * w_dim_y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator=() - assignement operator // //----------------------------------------------------------------------------- DeviceAttribute & DeviceAttribute::operator=(const DeviceAttribute &rval) { if (this != &rval) { name = rval.name; exceptions_flags = rval.exceptions_flags; dim_x = rval.dim_x; dim_y = rval.dim_y; w_dim_x = rval.w_dim_x; w_dim_y = rval.w_dim_y; quality = rval.quality; data_format = rval.data_format; data_type = rval.data_type; time = rval.time; err_list = rval.err_list; #ifdef HAS_RVALUE LongSeq = rval.LongSeq; ShortSeq = rval.ShortSeq; DoubleSeq = rval.DoubleSeq; StringSeq = rval.StringSeq; FloatSeq = rval.FloatSeq; BooleanSeq = rval.BooleanSeq; UShortSeq = rval.UShortSeq; UCharSeq = rval.UCharSeq; Long64Seq = rval.Long64Seq; ULongSeq = rval.ULongSeq; ULong64Seq = rval.ULong64Seq; StateSeq = rval.StateSeq; EncodedSeq = rval.EncodedSeq; #else DeviceAttribute &nc_rval = const_cast(rval); if (nc_rval.LongSeq.operator->() != NULL) LongSeq = nc_rval.LongSeq._retn(); else LongSeq = NULL; if (nc_rval.ShortSeq.operator->() != NULL) ShortSeq = nc_rval.ShortSeq._retn(); else ShortSeq = NULL; if (nc_rval.DoubleSeq.operator->() != NULL) DoubleSeq = nc_rval.DoubleSeq._retn(); else DoubleSeq = NULL; if (nc_rval.StringSeq.operator->() != NULL) StringSeq = nc_rval.StringSeq._retn(); else StringSeq = NULL; if (nc_rval.FloatSeq.operator->() != NULL) FloatSeq = nc_rval.FloatSeq._retn(); else FloatSeq = NULL; if (nc_rval.BooleanSeq.operator->() != NULL) BooleanSeq = nc_rval.BooleanSeq._retn(); else BooleanSeq = NULL; if (nc_rval.UShortSeq.operator->() != NULL) UShortSeq = nc_rval.UShortSeq._retn(); else UShortSeq = NULL; if (nc_rval.UCharSeq.operator->() != NULL) UCharSeq = nc_rval.UCharSeq._retn(); else UCharSeq = NULL; if (nc_rval.Long64Seq.operator->() != NULL) Long64Seq = nc_rval.Long64Seq._retn(); else Long64Seq = NULL; if (nc_rval.ULongSeq.operator->() != NULL) ULongSeq = nc_rval.ULongSeq._retn(); else ULongSeq = NULL; if (nc_rval.ULong64Seq.operator->() != NULL) ULong64Seq = nc_rval.ULong64Seq._retn(); else ULong64Seq = NULL; if (nc_rval.StateSeq.operator->() != NULL) StateSeq = nc_rval.StateSeq._retn(); else StateSeq = NULL; if (nc_rval.EncodedSeq.operator->() != NULL) EncodedSeq = nc_rval.EncodedSeq._retn(); else EncodedSeq = NULL; #endif d_state = rval.d_state; d_state_filled = rval.d_state_filled; #ifdef HAS_UNIQUE_PTR if (rval.ext.get() != NULL) { ext.reset(new DeviceAttributeExt); *(ext.get()) = *(rval.ext.get()); } else ext.reset(); #else delete ext; if (rval.ext != NULL) { ext = new DeviceAttributeExt(); *ext = *(rval.ext); } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator=() - move assignement operator // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DeviceAttribute & DeviceAttribute::operator=(DeviceAttribute &&rval) { name = move(rval.name); exceptions_flags = rval.exceptions_flags; dim_x = rval.dim_x; dim_y = rval.dim_y; w_dim_x = rval.w_dim_x; w_dim_y = rval.w_dim_y; quality = rval.quality; data_format = rval.data_format; data_type = rval.data_type; time = rval.time; err_list = rval.err_list; if (rval.LongSeq.operator->() != NULL) LongSeq = rval.LongSeq._retn(); else LongSeq = Tango_nullptr; if (rval.ShortSeq.operator->() != NULL) ShortSeq = rval.ShortSeq._retn(); else ShortSeq = Tango_nullptr; if (rval.DoubleSeq.operator->() != NULL) DoubleSeq = rval.DoubleSeq._retn(); else DoubleSeq = Tango_nullptr; if (rval.StringSeq.operator->() != NULL) StringSeq = rval.StringSeq._retn(); else StringSeq = Tango_nullptr; if (rval.FloatSeq.operator->() != NULL) FloatSeq = rval.FloatSeq._retn(); else FloatSeq = Tango_nullptr; if (rval.BooleanSeq.operator->() != NULL) BooleanSeq = rval.BooleanSeq._retn(); else BooleanSeq = Tango_nullptr; if (rval.UShortSeq.operator->() != NULL) UShortSeq = rval.UShortSeq._retn(); else UShortSeq = Tango_nullptr; if (rval.UCharSeq.operator->() != NULL) UCharSeq = rval.UCharSeq._retn(); else UCharSeq = Tango_nullptr; if (rval.Long64Seq.operator->() != NULL) Long64Seq = rval.Long64Seq._retn(); else Long64Seq = Tango_nullptr; if (rval.ULongSeq.operator->() != NULL) ULongSeq = rval.ULongSeq._retn(); else ULongSeq = Tango_nullptr; if (rval.ULong64Seq.operator->() != NULL) ULong64Seq = rval.ULong64Seq._retn(); else ULong64Seq = Tango_nullptr; if (rval.StateSeq.operator->() != NULL) StateSeq = rval.StateSeq._retn(); else StateSeq = Tango_nullptr; if (rval.EncodedSeq.operator->() != NULL) EncodedSeq = rval.EncodedSeq._retn(); else EncodedSeq = Tango_nullptr; d_state = rval.d_state; d_state_filled = rval.d_state_filled; if (rval.ext.get() != NULL) { ext = move(rval.ext); } else ext.reset(); return *this; } #endif //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for short // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string &new_name, short datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq->length(1); ShortSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, short datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq->length(1); ShortSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevLong // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, DevLong datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq->length(1); LongSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevLong datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq->length(1); LongSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevLong64 // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, DevLong64 datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq->length(1); Long64Seq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevLong64 datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq->length(1); Long64Seq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for double // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, double datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq->length(1); DoubleSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, double datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq->length(1); DoubleSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for string // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, string& datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq->length(1); StringSeq[0] = string_dup(datum.c_str()); } DeviceAttribute::DeviceAttribute(const char *new_name, string& datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq->length(1); StringSeq[0] = string_dup(datum.c_str()); } DeviceAttribute::DeviceAttribute(string& new_name, const char *datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq->length(1); StringSeq[0] = string_dup(datum); } DeviceAttribute::DeviceAttribute(const char *new_name, const char *datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq->length(1); StringSeq[0] = string_dup(datum); } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for float // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, float datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq->length(1); FloatSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, float datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq->length(1); FloatSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for boolean // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, bool datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq->length(1); BooleanSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, bool datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq->length(1); BooleanSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for unsigned short (DevUShort) // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, unsigned short datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq->length(1); UShortSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, unsigned short datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq->length(1); UShortSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for unsigned char (DevUChar) // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, unsigned char datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq->length(1); UCharSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, unsigned char datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq->length(1); UCharSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevULong // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, DevULong datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq->length(1); ULongSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevULong datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq->length(1); ULongSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevULong64 // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, DevULong64 datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq->length(1); ULong64Seq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevULong64 datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq->length(1); ULong64Seq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevState // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, DevState datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq->length(1); StateSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevState datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq->length(1); StateSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for DevEncoded // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string &new_name, DevEncoded &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); EncodedSeq = new(DevVarEncodedArray); EncodedSeq->length(1); EncodedSeq[0] = datum; } DeviceAttribute::DeviceAttribute(const char *new_name, DevEncoded &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); EncodedSeq = new(DevVarEncodedArray); EncodedSeq->length(1); EncodedSeq[0] = datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of short // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ShortSeq = new(DevVarShortArray); ShortSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of DevLong // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); LongSeq = new(DevVarLongArray); LongSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of DevLong64 // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); Long64Seq = new(DevVarLong64Array); Long64Seq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of double // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); DoubleSeq = new(DevVarDoubleArray); DoubleSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of string // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StringSeq = new(DevVarStringArray); StringSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of float // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); FloatSeq = new(DevVarFloatArray); FloatSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of bool // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); BooleanSeq = new(DevVarBooleanArray); BooleanSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of unsigned short // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UShortSeq = new(DevVarUShortArray); UShortSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of unsigned char // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); UCharSeq = new(DevVarCharArray); UCharSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of DevULong // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULongSeq = new(DevVarULongArray); ULongSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of DevULong64 // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); ULong64Seq = new(DevVarULong64Array); ULong64Seq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::DeviceAttribute() - constructor for vector of DevState // //----------------------------------------------------------------------------- DeviceAttribute::DeviceAttribute(string& new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum):ext(new DeviceAttributeExt) { name = new_name; dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(string& new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq.inout() << datum; } DeviceAttribute::DeviceAttribute(const char *new_name, vector &datum,int x,int y):ext(new DeviceAttributeExt) { name = new_name; dim_x = x; dim_y = y; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; d_state_filled = false; exceptions_flags.set(failed_flag); exceptions_flags.set(isempty_flag); StateSeq = new(DevVarStateArray); StateSeq.inout() << datum; } //----------------------------------------------------------------------------- // // DeviceAttribute::~DeviceAttribute() - destructor to destroy DeviceAttribute // //----------------------------------------------------------------------------- DeviceAttribute::~DeviceAttribute() { #ifndef HAS_UNIQUE_PTR delete ext; #endif } //----------------------------------------------------------------------------- // // DeviceAttribute::is_empty() - returns true or false if datum is empty // //----------------------------------------------------------------------------- bool DeviceAttribute::is_empty() { ext->ext_state.reset(isempty_flag); if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) return false; } if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) return false; } if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) return false; } if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) return false; } if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) return false; } if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) return false; } if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) return false; } if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) return false; } if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) return false; } if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) return false; } if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) return false; } if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) return false; } if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() != 0) return false; } if (d_state_filled == true) return false; ext->ext_state.set(isempty_flag); if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception(API_EmptyDeviceAttribute, "cannot extract, no data in DeviceAttribute object ", "DeviceAttribute::is_empty"); } return true; } //----------------------------------------------------------------------------- // // DeviceAttribute::get_type() - returns attribute data type // //----------------------------------------------------------------------------- int DeviceAttribute::get_type() { int da_type; if (is_empty() == true) return -1; else { if (LongSeq.operator->() != NULL) da_type = Tango::DEV_LONG; else if (ShortSeq.operator->() != NULL) { da_type = data_type; } else if (DoubleSeq.operator->() != NULL) da_type = Tango::DEV_DOUBLE; else if (FloatSeq.operator->() != NULL) da_type = Tango::DEV_FLOAT; else if (BooleanSeq.operator->() != NULL) da_type = Tango::DEV_BOOLEAN; else if (UShortSeq.operator->() != NULL) da_type = Tango::DEV_USHORT; else if (UCharSeq.operator->() != NULL) da_type = Tango::DEV_UCHAR; else if (StringSeq.operator->() != NULL) da_type = Tango::DEV_STRING; else if (Long64Seq.operator->() != NULL) da_type = Tango::DEV_LONG64; else if (ULongSeq.operator->() != NULL) da_type = Tango::DEV_ULONG; else if (ULong64Seq.operator->() != NULL) da_type = Tango::DEV_ULONG64; else if (EncodedSeq.operator->() != NULL) da_type = Tango::DEV_ENCODED; else if ((StateSeq.operator->() != NULL) || (d_state_filled == true)) da_type = Tango::DEV_STATE; else da_type = -1; } return da_type; } //----------------------------------------------------------------------------- // // DeviceAttribute::get_data_format() - returns attribute data format // //----------------------------------------------------------------------------- AttrDataFormat DeviceAttribute::get_data_format() { if (exceptions_flags.test(unknown_format_flag) && (data_format == Tango::FMT_UNKNOWN)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDeviceAttribute", (const char*)"Cannot returned data_type from DeviceAttribute object: Not initialised yet or too old device (< V7)", (const char*)"DeviceAttribute::get_data_format"); } return data_format; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(short &) - extract a short from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (short &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) datum = ShortSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(short) - insert a short into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (short datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarShortArray *short_vararr = new(DevVarShortArray); short_vararr->length(1); (*short_vararr)[0] = datum; ShortSeq = short_vararr; del_mem(Tango::DEV_SHORT); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevLong &) - extract a DevLong from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevLong &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) datum = LongSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevLong) - insert a DevLong into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevLong datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarLongArray *long_vararr = new(DevVarLongArray); long_vararr->length(1); (*long_vararr)[0] = datum; LongSeq = long_vararr; del_mem(Tango::DEV_LONG); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevLong64 &) - extract a DevLong64 from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevLong64 &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) datum = Long64Seq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevLong64) - insert a DevLong64 into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevLong64 datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarLong64Array *long_vararr = new(DevVarLong64Array); long_vararr->length(1); (*long_vararr)[0] = datum; Long64Seq = long_vararr; del_mem(Tango::DEV_LONG64); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(double &) - extract a double from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (double &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) datum = DoubleSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(double) - insert a double into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (double datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarDoubleArray *double_vararr = new(DevVarDoubleArray); double_vararr->length(1); (*double_vararr)[0] = datum; DoubleSeq = double_vararr; del_mem(Tango::DEV_DOUBLE); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(string &) - extract a string from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (string& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) datum = StringSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(string &) - insert a string into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (string& datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarStringArray *string_vararr = new(DevVarStringArray); string_vararr->length(1); (*string_vararr)[0] = string_dup(datum.c_str()); StringSeq = string_vararr; del_mem(Tango::DEV_STRING); } void DeviceAttribute::operator << (DevString datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarStringArray *string_vararr = new(DevVarStringArray); string_vararr->length(1); (*string_vararr)[0] = string_dup(datum); StringSeq = string_vararr; del_mem(Tango::DEV_STRING); } void DeviceAttribute::operator << (const char *datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarStringArray *string_vararr = new(DevVarStringArray); string_vararr->length(1); (*string_vararr)[0] = string_dup(datum); StringSeq = string_vararr; del_mem(Tango::DEV_STRING); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(float &) - extract a float from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (float &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) datum = FloatSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(float) - insert a float into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (float datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarFloatArray *float_vararr = new(DevVarFloatArray); float_vararr->length(1); (*float_vararr)[0] = datum; FloatSeq = float_vararr; del_mem(Tango::DEV_FLOAT); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(bool &) - extract a boolean from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (bool &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) datum = BooleanSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(bool) - insert a boolean into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (bool datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarBooleanArray *bool_vararr = new(DevVarBooleanArray); bool_vararr->length(1); (*bool_vararr)[0] = datum; BooleanSeq = bool_vararr; del_mem(Tango::DEV_BOOLEAN); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(unsigned short &) - extract a unsigned short from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (unsigned short &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) datum = UShortSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(unsigned short) - insert a unsigned short into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (unsigned short datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarUShortArray *ush_vararr = new(DevVarUShortArray); ush_vararr->length(1); (*ush_vararr)[0] = datum; UShortSeq = ush_vararr; del_mem(Tango::DEV_USHORT); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(unsigned char &) - extract a unsigned char from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (unsigned char &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) datum = UCharSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(unsigned char) - insert a unsigned char into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (unsigned char datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarCharArray *uch_vararr = new(DevVarCharArray); uch_vararr->length(1); (*uch_vararr)[0] = datum; UCharSeq = uch_vararr; del_mem(Tango::DEV_UCHAR); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevULong &) - extract a DevULong from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevULong &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) datum = ULongSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevULong) - insert a DevULong into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevULong datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarULongArray *long_vararr = new(DevVarULongArray); long_vararr->length(1); (*long_vararr)[0] = datum; ULongSeq = long_vararr; del_mem(Tango::DEV_ULONG); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevULong64 &) - extract a DevULong64 from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevULong64 &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) datum = ULong64Seq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevULong64) - insert a DevULong64 into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevULong64 datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarULong64Array *long_vararr = new(DevVarULong64Array); long_vararr->length(1); (*long_vararr)[0] = datum; ULong64Seq = long_vararr; del_mem(Tango::DEV_ULONG64); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevState &) - extract a DevState from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevState &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (d_state_filled == true) { datum = d_state; d_state_filled = false; return ret; } if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) datum = StateSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevState) - insert a DevState into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevState datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarStateArray *state_vararr = new(DevVarStateArray); state_vararr->length(1); (*state_vararr)[0] = datum; StateSeq = state_vararr; del_mem(Tango::DEV_STATE); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevEncoded &) - extract a DevEncoded from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevEncoded &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() != 0) datum = EncodedSeq[0]; else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevEncoded) - insert a DevEncoded into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevEncoded &datum) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarEncodedArray *enc_vararr = new(DevVarEncodedArray); enc_vararr->length(1); (*enc_vararr)[0] = datum; EncodedSeq = enc_vararr; del_mem(Tango::DEV_ENCODED); } void DeviceAttribute::insert(char *&str,unsigned char *&ptr,unsigned int size) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarEncodedArray *enc_vararr = new(DevVarEncodedArray); enc_vararr->length(1); (*enc_vararr)[0].encoded_format = CORBA::string_dup(str); (*enc_vararr)[0].encoded_data.replace(size,size,(CORBA::Octet *)ptr); EncodedSeq = enc_vararr; del_mem(Tango::DEV_ENCODED); } void DeviceAttribute::insert(const char *str,unsigned char *ptr,unsigned int size) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarEncodedArray *enc_vararr = new(DevVarEncodedArray); enc_vararr->length(1); (*enc_vararr)[0].encoded_format = CORBA::string_dup(str); (*enc_vararr)[0].encoded_data.replace(size,size,(CORBA::Octet *)ptr); EncodedSeq = enc_vararr; del_mem(Tango::DEV_ENCODED); } void DeviceAttribute::insert(const string &str,vector &array) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarEncodedArray *enc_vararr = new(DevVarEncodedArray); enc_vararr->length(1); (*enc_vararr)[0].encoded_format = CORBA::string_dup(str.c_str()); (*enc_vararr)[0].encoded_data << array; EncodedSeq = enc_vararr; del_mem(Tango::DEV_ENCODED); } void DeviceAttribute::insert(string &str,vector &array) { const string &tmp_str = str; insert(tmp_str,array); } void DeviceAttribute::insert(const char *str,DevVarCharArray *array) { dim_x = 1; dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DevVarEncodedArray *enc_vararr = new(DevVarEncodedArray); enc_vararr->length(1); (*enc_vararr)[0].encoded_format = CORBA::string_dup(str); (*enc_vararr)[0].encoded_data.replace(array->length(),array->length(),array->get_buffer()); EncodedSeq = enc_vararr; del_mem(Tango::DEV_ENCODED); } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of string into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (StringSeq.operator->() == NULL) { DevVarStringArray *str_vararr = new(DevVarStringArray); StringSeq = str_vararr; } StringSeq.inout() << datum; del_mem(Tango::DEV_STRING); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) { datum.resize(StringSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = StringSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of short into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (ShortSeq.operator->() == NULL) { DevVarShortArray *short_vararr = new(DevVarShortArray); ShortSeq = short_vararr; } ShortSeq.inout() << datum; del_mem(Tango::DEV_SHORT); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { datum.resize(ShortSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = ShortSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of DevLong into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (LongSeq.operator->() == NULL) { DevVarLongArray *long_vararr = new(DevVarLongArray); LongSeq = long_vararr; } LongSeq.inout() << datum; del_mem(Tango::DEV_LONG); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) { datum.resize(LongSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = LongSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of DevLong64 into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (Long64Seq.operator->() == NULL) { DevVarLong64Array *long_vararr = new(DevVarLong64Array); Long64Seq = long_vararr; } Long64Seq.inout() << datum; del_mem(Tango::DEV_LONG64); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) { datum.resize(Long64Seq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = Long64Seq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of double into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (DoubleSeq.operator->() == NULL) { DevVarDoubleArray *double_vararr = new(DevVarDoubleArray); DoubleSeq = double_vararr; } DoubleSeq.inout() << datum; del_mem(Tango::DEV_DOUBLE); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) { datum.resize(DoubleSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = DoubleSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of float into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (FloatSeq.operator->() == NULL) { DevVarFloatArray *float_vararr = new(DevVarFloatArray); FloatSeq = float_vararr; } FloatSeq.inout() << datum; del_mem(Tango::DEV_FLOAT); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) { datum.resize(FloatSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = FloatSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of boolean into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (BooleanSeq.operator->() == NULL) { DevVarBooleanArray *bool_vararr = new(DevVarBooleanArray); BooleanSeq = bool_vararr; } BooleanSeq.inout() << datum; del_mem(Tango::DEV_BOOLEAN); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) { datum.resize(BooleanSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = BooleanSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of unsigned short into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (UShortSeq.operator->() == NULL) { DevVarUShortArray *ushort_vararr = new(DevVarUShortArray); UShortSeq = ushort_vararr; } UShortSeq.inout() << datum; del_mem(Tango::DEV_USHORT); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) { datum.resize(UShortSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = UShortSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of unsigned char into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (UCharSeq.operator->() == NULL) { DevVarUCharArray *uchar_vararr = new(DevVarUCharArray); UCharSeq = uchar_vararr; } UCharSeq.inout() << datum; del_mem(Tango::DEV_UCHAR); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) { datum.resize(UCharSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = UCharSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of DevULong into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (ULongSeq.operator->() == NULL) { DevVarULongArray *long_vararr = new(DevVarULongArray); ULongSeq = long_vararr; } ULongSeq.inout() << datum; del_mem(Tango::DEV_ULONG); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) { datum.resize(ULongSeq->length()); for (unsigned int i=0; i< ULongSeq->length(); i++) { datum[i] = ULongSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of DevULong64 into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (ULong64Seq.operator->() == NULL) { DevVarULong64Array *long_vararr = new(DevVarULong64Array); ULong64Seq = long_vararr; } ULong64Seq.inout() << datum; del_mem(Tango::DEV_ULONG64); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) { datum.resize(ULong64Seq->length()); for (unsigned int i=0; i < ULong64Seq->length(); i++) { datum[i] = ULong64Seq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(vector) - // insert a vector of DevState into DeviceAttribute // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (vector &datum) { dim_x = datum.size(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; if (StateSeq.operator->() == NULL) { DevVarStateArray *long_vararr = new(DevVarStateArray); StateSeq = long_vararr; } StateSeq.inout() << datum; del_mem(Tango::DEV_STATE); } void DeviceAttribute::insert(vector &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(vector &) - extract a vector from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) { datum.resize(StateSeq->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = StateSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarShortArray *) - extract a sequence of // short from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarShortArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { datum = ShortSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarLongArray *) - extract a sequence of // long from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarLongArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) { datum = LongSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarDoubleArray *) - extract a sequence of // double from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarDoubleArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) { datum = DoubleSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarStringArray *) - extract a sequence of // string from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarStringArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) { datum = StringSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarFloatArray *) - extract a sequence of // double from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarFloatArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) { datum = FloatSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarBooleanArray *) - extract a sequence of // bool from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarBooleanArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) { datum = BooleanSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarUShortArray *) - extract a sequence of // unsigned short from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarUShortArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) { datum = UShortSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarCharArray *) - extract a sequence of // unsigned char from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarCharArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) { datum = UCharSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarLong64Array *) - extract a sequence of // DevLong64 from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarLong64Array* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) { datum = Long64Seq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarULongArray *) - extract a sequence of // DevULong from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarULongArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) { datum = ULongSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarULong64Array *) - extract a sequence of // DevUULong64 from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarULong64Array* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) { datum = ULong64Seq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarStateArray *) - extract a sequence of // DevState from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarStateArray* &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) { datum = StateSeq._retn(); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator >>(DevVarEncodedArray *) - extract a sequence of // long from DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::operator >> (DevVarEncodedArray* &datum) { bool ret = true; if (err_list.operator->() != NULL) { if (err_list.in().length() != 0) { if (exceptions_flags.test(failed_flag)) throw DevFailed(err_list.in()); else return false; } } if (is_empty() == true) return false; if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() != 0) { datum = EncodedSeq._retn(); } else ret = false; } else { ret = false; if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)"API_IncompatibleAttrArgumentType", (const char*)"Cannot extract, data in DeviceAttribute object is not an array of DevEncoded", (const char*)"DeviceAttribute::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarShortArray &) - // insert a DevVarShortArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarShortArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ShortSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) ShortSeq[i] = datum[i]; del_mem(Tango::DEV_SHORT); } void DeviceAttribute::insert(const DevVarShortArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarShortArray *) - // insert a DevVarShortArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarShortArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ShortSeq = datum; del_mem(Tango::DEV_SHORT); } void DeviceAttribute::insert(DevVarShortArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarLongArray &) - // insert a DevVarLongArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarLongArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; LongSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) LongSeq[i] = datum[i]; del_mem(Tango::DEV_LONG); } void DeviceAttribute::insert(const DevVarLongArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarLongArray *) - // insert a DevVarLongArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarLongArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; LongSeq = datum; del_mem(Tango::DEV_LONG); } void DeviceAttribute::insert(DevVarLongArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarDoubleArray &) - // insert a DevVarDoubleArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarDoubleArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DoubleSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) DoubleSeq[i] = datum[i]; del_mem(Tango::DEV_DOUBLE); } void DeviceAttribute::insert(const DevVarDoubleArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarDoubleArray *) - // insert a DevVarDoubleArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarDoubleArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; DoubleSeq = datum; del_mem(Tango::DEV_DOUBLE); } void DeviceAttribute::insert(DevVarDoubleArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarStringArray &) - // insert a DevVarStringArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarStringArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; StringSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) StringSeq[i] = datum[i]; del_mem(Tango::DEV_STRING); } void DeviceAttribute::insert(const DevVarStringArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarStringArray *) - // insert a DevVarStringArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarStringArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; StringSeq = datum; del_mem(Tango::DEV_STRING); } void DeviceAttribute::insert(DevVarStringArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarFloatArray &) - // insert a DevVarFloatArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarFloatArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; FloatSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) FloatSeq[i] = datum[i]; del_mem(Tango::DEV_FLOAT); } void DeviceAttribute::insert(const DevVarFloatArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarFloatArray *) - // insert a DevVarFloatArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarFloatArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; FloatSeq = datum; del_mem(Tango::DEV_FLOAT); } void DeviceAttribute::insert(DevVarFloatArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarBooleanArray &) - // insert a DevVarBooleanArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarBooleanArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; BooleanSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) BooleanSeq[i] = datum[i]; del_mem(Tango::DEV_BOOLEAN); } void DeviceAttribute::insert(const DevVarBooleanArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarBooleanArray *) - // insert a DevVarBooleanArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarBooleanArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; BooleanSeq = datum; del_mem(Tango::DEV_BOOLEAN); } void DeviceAttribute::insert(DevVarBooleanArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarUShortArray &) - // insert a DevVarUShortArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarUShortArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; UShortSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) UShortSeq[i] = datum[i]; del_mem(Tango::DEV_USHORT); } void DeviceAttribute::insert(const DevVarUShortArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarUShortArray *) - // insert a DevVarUShortArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarUShortArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; UShortSeq = datum; del_mem(Tango::DEV_USHORT); } void DeviceAttribute::insert(DevVarUShortArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarCharArray &) - // insert a DevVarCharArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarCharArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; UCharSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) UCharSeq[i] = datum[i]; del_mem(Tango::DEV_UCHAR); } void DeviceAttribute::insert(const DevVarCharArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarCharArray *) - // insert a DevVarCharArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarCharArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; UCharSeq = datum; del_mem(Tango::DEV_UCHAR); } void DeviceAttribute::insert(DevVarCharArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarLong64Array &) - // insert a DevVarLong64Array by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarLong64Array &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; Long64Seq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) Long64Seq[i] = datum[i]; del_mem(Tango::DEV_LONG64); } void DeviceAttribute::insert(const DevVarLong64Array &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarLong64Array *) - // insert a DevVarLong64Array by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarLong64Array *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; Long64Seq = datum; del_mem(Tango::DEV_LONG64); } void DeviceAttribute::insert(DevVarLong64Array *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarULongArray &) - // insert a DevVarULongArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarULongArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ULongSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) ULongSeq[i] = datum[i]; del_mem(Tango::DEV_ULONG); } void DeviceAttribute::insert(const DevVarULongArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarULongArray *) - // insert a DevVarULongArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarULongArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ULongSeq = datum; del_mem(Tango::DEV_ULONG); } void DeviceAttribute::insert(DevVarULongArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarULong64Array &) - // insert a DevVarULong64Array by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarULong64Array &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ULong64Seq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) ULong64Seq[i] = datum[i]; del_mem(Tango::DEV_ULONG64); } void DeviceAttribute::insert(const DevVarULong64Array &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarULong64Array *) - // insert a DevVarULong64Array by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarULong64Array *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; ULong64Seq = datum; del_mem(Tango::DEV_ULONG64); } void DeviceAttribute::insert(DevVarULong64Array *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarStateArray &) - // insert a DevVarStateArray by reference into the DeviceAttribute. // This inserter copy the data // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (const DevVarStateArray &datum) { dim_x = datum.length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; StateSeq->length(datum.length()); for (unsigned int i = 0;i < datum.length();i++) StateSeq[i] = datum[i]; del_mem(Tango::DEV_STATE); } void DeviceAttribute::insert(const DevVarStateArray &datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::operator <<(DevVarStateArray *) - // insert a DevVarStateArray by pointer into the DeviceAttribute. // This inserter takes onwership of the pointed to memory // //----------------------------------------------------------------------------- void DeviceAttribute::operator << (DevVarStateArray *datum) { dim_x = datum->length(); dim_y = 0; w_dim_x = 0; w_dim_y = 0; quality = Tango::ATTR_VALID; data_format = Tango::FMT_UNKNOWN; StateSeq = datum; del_mem(Tango::DEV_STATE); } void DeviceAttribute::insert(DevVarStateArray *datum,int x,int y) { *this << datum; dim_x = x; dim_y = y; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract(char *&,unsigned char *&) // // - extract the read value as pointers from the DeviceAttribute // for the DevEncoded data type // //----------------------------------------------------------------------------- bool DeviceAttribute::extract(char *&str,unsigned char *&data_ptr,unsigned int &data_size) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() != 0) { str = CORBA::string_dup(EncodedSeq[0].encoded_format.in()); data_size = EncodedSeq[0].encoded_data.length(); data_ptr = EncodedSeq[0].encoded_data.get_buffer(true); } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } bool DeviceAttribute::extract(const char *&str,unsigned char *&data_ptr,unsigned int &data_size) { return extract(const_cast(str),data_ptr,data_size); } //----------------------------------------------------------------------------- // // DeviceAttribute::extract(string &,vector &) // // - extract the read value as pointers from the DeviceAttribute // for the DevEncoded data type // //----------------------------------------------------------------------------- bool DeviceAttribute::extract(string &str,vector &dat) { return extract_read(str,dat); } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(string &,vector &) // // - extract the read value as a string, vector from the DeviceAttribute // for the DevEncoded data type // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (string &datum_str,vector &datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() != 0) { datum_str = EncodedSeq[0].encoded_format; unsigned long length = EncodedSeq[0].encoded_data.length(); datum.resize(length); for (unsigned long i=0; i &) // // - extract the set value as a string,vector from the DeviceAttribute // when the data type is DevEncoded // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (string &datum_str,vector &datum) { // check for available data bool ret = check_for_data(); if (ret == false) return false; if (EncodedSeq.operator->() != NULL) { if (EncodedSeq->length() == 2) { datum_str = EncodedSeq[1].encoded_format; unsigned long length = EncodedSeq[1].encoded_data.length(); datum.resize(length); for (unsigned long i=0; i &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if (ret == false) return false; // copy the read value to the vector if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StringSeq.operator->() != NULL) { if (StringSeq->length() != 0) { // check the size of the setpoint values int read_length = check_set_value_size (StringSeq->length()); // copy the set point values to the vector datum.resize(StringSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = StringSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ShortSeq.operator->() != NULL) { if (ShortSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (ShortSeq->length()); // copy the set point values to the vector datum.resize(ShortSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = ShortSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (LongSeq.operator->() != NULL) { if (LongSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (LongSeq->length()); // copy the set point values to the vector datum.resize(LongSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = LongSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (DoubleSeq.operator->() != NULL) { if (DoubleSeq->length() != 0) { // check the size of the setpoint values int read_length = check_set_value_size (DoubleSeq->length()); // copy the set point values to the vector datum.resize(DoubleSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = DoubleSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (FloatSeq.operator->() != NULL) { if (FloatSeq->length() != 0) { // check the size of the setpoint values int read_length = check_set_value_size (FloatSeq->length()); // copy the set point values to the vector datum.resize(FloatSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = FloatSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (BooleanSeq.operator->() != NULL) { if (BooleanSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (BooleanSeq->length()); // copy the set point values to the vector datum.resize(BooleanSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = BooleanSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UShortSeq.operator->() != NULL) { if (UShortSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (UShortSeq->length()); // copy the set point values to the vector datum.resize(UShortSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = UShortSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (UCharSeq.operator->() != NULL) { if (UCharSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (UCharSeq->length()); // copy the set point values to the vector datum.resize(UCharSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = UCharSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (Long64Seq.operator->() != NULL) { if (Long64Seq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (Long64Seq->length()); // copy the set point values to the vector datum.resize(Long64Seq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = Long64Seq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULong64Seq.operator->() != NULL) { if (ULong64Seq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (ULong64Seq->length()); // copy the set point values to the vector datum.resize(ULong64Seq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = ULong64Seq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (ULongSeq.operator->() != NULL) { if (ULongSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (ULongSeq->length()); // copy the set point values to the vector datum.resize(ULongSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = ULongSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //----------------------------------------------------------------------------- // // DeviceAttribute::extract_read(vector &) // // - extract the read value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_read (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; // copy the read value to the vector if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) { long length = get_nb_read(); datum.resize(length); for (long i=0; i &) // // - extract the set value as a vector from the DeviceAttribute // //----------------------------------------------------------------------------- bool DeviceAttribute::extract_set (vector& datum) { // check for available data bool ret = check_for_data(); if ( ret == false) return false; if (StateSeq.operator->() != NULL) { if (StateSeq->length() != 0) { // check the size of the setpoint values long read_length = check_set_value_size (StateSeq->length()); // copy the set point values to the vector datum.resize(StateSeq->length() - read_length); unsigned int k = 0; for (unsigned int i=read_length; ilength(); i++, k++) { datum[k] = StateSeq[i]; } } else ret = false; } else { // check the wrongtype_flag ret = check_wrong_type_exception(); } return ret; } //+------------------------------------------------------------------------- // // method name : check_for data // // description : Checks whether attribute data is available. // In case of missing data, an exception will be // thrown when the failed exception flag is set. // Otherwise the method returns false. // // ret : false when no attribute data is available. // //-------------------------------------------------------------------------- bool DeviceAttribute::check_for_data() { ext->ext_state.reset(); if (err_list.operator->() != NULL) { if (err_list.in().length() != 0) { ext->ext_state.set(failed_flag); if (exceptions_flags.test(failed_flag)) throw DevFailed(err_list.in()); else return false; } } if (is_empty() == true) return false; return true; } //+------------------------------------------------------------------------------------------------------------------- // // method name : // check_wrong_type_exception // // description : // Checks whether the wrongtype exception flag is set and throws an exception in this case. // Otherwise the method will return false. // // return : // False when no exception was thrown. // //------------------------------------------------------------------------------------------------------------------- bool DeviceAttribute::check_wrong_type_exception() { ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception("API_IncompatibleAttrArgumentType", "Cannot extract, data type in DeviceAttribute object is not coherent with the type provided to extraction method", "DeviceAttribute::operator>>"); } return false; } //+----------------------------------------------------------------------------------------------------------------- // // method name : // check_set_value_size // // description : // checks wether set value data is available and calculates the index of the first set value element. // // arg(s) : // in: // - seq_length : the length of the attribute data array // // return : // The index of the first set value element. // //---------------------------------------------------------------------------------------------------------------- int DeviceAttribute::check_set_value_size(int seq_length) { // // check if the attribute data contains a set value // if ( get_nb_written() == 0 ) { // no set point available ApiDataExcept::throw_exception((const char*)"API_NoSetValueAvailable", (const char*)"Cannot extract, data from the DeviceAttribute object. No set value available", (const char*)"DeviceAttribute::extract_set"); } // // For Tango::WRITE attributes, the read and set value are identical! In this case the number of set values is the // same as the number of data elements in the returned sequence. // if ( get_nb_written() == seq_length ) { return 0; } else { return get_nb_read(); } } //+---------------------------------------------------------------------------------------------------------------- // // method name : // DeviceAttribute::del_mem // // description : // Delete already allocated memory except for the data just inserted // // arg(s) : // in : // - data_type : The data type just inserted // //---------------------------------------------------------------------------------------------------------------- void DeviceAttribute::del_mem(int _data_type) { if ((_data_type != Tango::DEV_STRING) && (StringSeq.operator->() != NULL)) delete StringSeq._retn(); if ((_data_type != Tango::DEV_LONG) && (LongSeq.operator->() != NULL)) delete LongSeq._retn(); if ((_data_type != Tango::DEV_SHORT) && (ShortSeq.operator->() != NULL)) delete ShortSeq._retn(); if ((_data_type != Tango::DEV_DOUBLE) && (DoubleSeq.operator->() != NULL)) delete DoubleSeq._retn(); if ((_data_type != Tango::DEV_FLOAT) && (FloatSeq.operator->() != NULL)) delete FloatSeq._retn(); if ((_data_type != Tango::DEV_BOOLEAN) && (BooleanSeq.operator->() != NULL)) delete BooleanSeq._retn(); if ((_data_type != Tango::DEV_USHORT) && (UShortSeq.operator->() != NULL)) delete UShortSeq._retn(); if ((_data_type != Tango::DEV_UCHAR) && (UCharSeq.operator->() != NULL)) delete UCharSeq._retn(); if ((_data_type != Tango::DEV_LONG64) && (Long64Seq.operator->() != NULL)) delete Long64Seq._retn(); if ((_data_type != Tango::DEV_ULONG) && (ULongSeq.operator->() != NULL)) delete ULongSeq._retn(); if ((_data_type != Tango::DEV_ULONG64) && (ULong64Seq.operator->() != NULL)) delete ULong64Seq._retn(); if ((_data_type != Tango::DEV_STATE) && (StateSeq.operator->() != NULL)) delete StateSeq._retn(); if ((_data_type != Tango::DEV_ENCODED) && (EncodedSeq.operator->() != NULL)) delete EncodedSeq._retn(); } //+----------------------------------------------------------------------------------------------------------------- // // function name : // operator overloading : << // // description : // Friend function to ease printing instance of the DeviceAttribute class // //------------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,DeviceAttribute &da) { if (da.has_failed() == true) { o_str << "Exception stored in DeviceAttribute object" << endl; Except::print_error_stack(da.err_list); } else { bitset bs = da.exceptions(); da.reset_exceptions(DeviceAttribute::isempty_flag); if (da.is_empty() == true) { da.exceptions(bs); o_str << "No data in DeviceAttribute object"; return o_str; } da.exceptions(bs); // // Print date // if (da.time.tv_sec != 0) { time_t tmp_val = da.time.tv_sec; char tmp_date[128]; #ifdef _TG_WINDOWS_ ctime_s(tmp_date,128,&tmp_val); #else ctime_r(&tmp_val,tmp_date); #endif tmp_date[strlen(tmp_date) - 1] = '\0'; o_str << tmp_date; o_str << " (" << da.time.tv_sec << "," << da.time.tv_usec << " sec) : "; } // // print attribute name // o_str << da.name; // // print dim_x and dim_y // o_str << " (dim_x = " << da.dim_x << ", dim_y = " << da.dim_y << ", "; o_str << "w_dim_x = " << da.w_dim_x << ", w_dim_y = " << da.w_dim_y << ", "; // // Print quality // o_str << "Data quality factor = "; switch (da.quality) { case Tango::ATTR_VALID: o_str << "VALID, "; break; case Tango::ATTR_INVALID: o_str << "INVALID, "; break; case Tango::ATTR_ALARM: o_str << "ALARM, "; break; case Tango::ATTR_CHANGING: o_str << "CHANGING, "; break; case Tango::ATTR_WARNING: o_str << "WARNING, "; break; } // // Print data format // o_str << "Data format = "; switch (da.data_format) { case Tango::SCALAR: o_str << "SCALAR, "; break; case Tango::SPECTRUM: o_str << "SPECTRUM, "; break; case Tango::IMAGE: o_str << "IMAGE, "; break; case Tango::FMT_UNKNOWN: o_str << "UNKNOWN, "; break; } // // Print data type // if (da.get_type() != DATA_TYPE_UNKNOWN) o_str << "Data type = " << CmdArgTypeName[da.get_type()] << ")" << endl; // // Print data (if valid) // if (da.quality != Tango::ATTR_INVALID) { if (da.LongSeq.operator->() != NULL) o_str << *(da.LongSeq.operator->()); else if (da.Long64Seq.operator->() != NULL) o_str << *(da.Long64Seq.operator->()); else if (da.ShortSeq.operator->() != NULL) o_str << *(da.ShortSeq.operator->()); else if (da.DoubleSeq.operator->() != NULL) o_str << *(da.DoubleSeq.operator->()); else if (da.FloatSeq.operator->() != NULL) o_str << *(da.FloatSeq.operator->()); else if (da.BooleanSeq.operator->() != NULL) o_str << *(da.BooleanSeq.operator->()); else if (da.UShortSeq.operator->() != NULL) o_str << *(da.UShortSeq.operator->()); else if (da.UCharSeq.operator->() != NULL) o_str << *(da.UCharSeq.operator->()); else if (da.StringSeq.operator->() != NULL) o_str << *(da.StringSeq.operator->()); else if (da.ULongSeq.operator->() != NULL) o_str << *(da.ULongSeq.operator->()); else if (da.ULong64Seq.operator->() != NULL) o_str << *(da.ULong64Seq.operator->()); else if (da.StateSeq.operator->() != NULL) o_str << *(da.StateSeq.operator->()); else if (da.EncodedSeq.operator->() != NULL) o_str << *(da.EncodedSeq.operator->()); else o_str << DevStateName[da.d_state]; } } return o_str; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/devapi_base.cpp0000644023471100065110000102716513034744772015531 00000000000000static const char *RcsId = "$Id: devapi_base.cpp 30109 2016-08-30 13:31:39Z taurel $\n$Name$"; //=================================================================================================================== // // devapi_base.cpp - C++ source code file for TANGO device api // // programmer(s) - Andy Gotz (goetz@esrf.fr) // // original - March 2001 // // Copyright (C) : 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30109 $ // //=================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifdef _TG_WINDOWS_ #include #include #include #else #include #include #include #include #include #include #endif /* _TG_WINDOWS_ */ #include #include #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // ConnectionExt class methods: // // - assignement operator // //----------------------------------------------------------------------------- Connection::ConnectionExt &Connection::ConnectionExt::operator=(TANGO_UNUSED(const Connection::ConnectionExt &rval)) { return *this; } //----------------------------------------------------------------------------- // // Connection::Connection() - constructor to manage a connection to a device // //----------------------------------------------------------------------------- Connection::Connection(ORB *orb_in):pasyn_ctr(0),pasyn_cb_ctr(0), timeout(CLNT_TIMEOUT), version(0),source(Tango::CACHE_DEV),ext(new ConnectionExt()), tr_reco(true),prev_failed(false),prev_failed_t0(0.0), user_connect_timeout(-1),tango_host_localhost(false) { // // Some default init for access control // check_acc = true; access = ACCESS_READ; // // If the proxy is created from inside a device server, use the server orb // ApiUtil *au = ApiUtil::instance(); if ((orb_in == NULL) && (CORBA::is_nil(au->get_orb()) == true)) { if (au->in_server() == true) ApiUtil::instance()->set_orb(Util::instance()->get_orb()); else ApiUtil::instance()->create_orb(); } else { if (orb_in != NULL) au->set_orb(orb_in); } // // Get user connect timeout if one is defined // int ucto = au->get_user_connect_timeout(); if (ucto != -1) user_connect_timeout = ucto; } Connection::Connection(bool dummy):ext(Tango_nullptr),tr_reco(true),prev_failed(false),prev_failed_t0(0.0), user_connect_timeout(-1),tango_host_localhost(false) { if (dummy) { #ifdef HAS_UNIQUE_PTR ext.reset(new ConnectionExt()); #else ext = new ConnectionExt(); #endif } } //----------------------------------------------------------------------------- // // Connection::~Connection() - destructor to destroy connection to TANGO device // //----------------------------------------------------------------------------- Connection::~Connection() { #ifndef HAS_UNIQUE_PTR delete ext; #endif } //----------------------------------------------------------------------------- // // Connection::Connection() - copy constructor // //----------------------------------------------------------------------------- Connection::Connection(const Connection &sou):ext(Tango_nullptr) { dbase_used = sou.dbase_used; from_env_var = sou.from_env_var; host = sou.host; port = sou.port; port_num = sou.port_num; db_host = sou.db_host; db_port = sou.db_port; db_port_num = sou.db_port_num; ior = sou.ior; pasyn_ctr = sou.pasyn_ctr; pasyn_cb_ctr = sou.pasyn_cb_ctr; device = sou.device; if (sou.version >= 2) device_2 = sou.device_2; timeout = sou.timeout; connection_state = sou.connection_state; version = sou.version; source = sou.source; check_acc = sou.check_acc; access = sou.access; tr_reco = sou.tr_reco; device_3 = sou.device_3; prev_failed = sou.prev_failed; prev_failed_t0 = sou.prev_failed_t0; device_4 = sou.device_4; user_connect_timeout = sou.user_connect_timeout; tango_host_localhost = sou.tango_host_localhost; device_5 = sou.device_5; #ifdef HAS_UNIQUE_PTR if (sou.ext.get() != NULL) { ext.reset(new ConnectionExt); *(ext.get()) = *(sou.ext.get()); } #else if (sou.ext != NULL) { ext = new ConnectionExt(); *ext = *(sou.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // Connection::operator=() - assignement operator // //----------------------------------------------------------------------------- Connection &Connection::operator=(const Connection &rval) { dbase_used = rval.dbase_used; from_env_var = rval.from_env_var; host = rval.host; port = rval.port; port_num = rval.port_num; db_host = rval.db_host; db_port = rval.db_port; db_port_num = rval.db_port_num; ior = rval.ior; pasyn_ctr = rval.pasyn_ctr; pasyn_cb_ctr = rval.pasyn_cb_ctr; device = rval.device; if (rval.version >= 2) device_2 = rval.device_2; timeout = rval.timeout; connection_state = rval.connection_state; version = rval.version; source = rval.source; check_acc = rval.check_acc; access = rval.access; tr_reco = rval.tr_reco; device_3 = rval.device_3; prev_failed = rval.prev_failed; prev_failed_t0 = rval.prev_failed_t0; device_4 = rval.device_4; user_connect_timeout = rval.user_connect_timeout; tango_host_localhost = rval.tango_host_localhost; device_5 = rval.device_5; #ifdef HAS_UNIQUE_PTR if (rval.ext.get() != NULL) { ext.reset(new ConnectionExt); *(ext.get()) = *(rval.ext.get()); } else ext.reset(Tango_nullptr); #else if (rval.ext != NULL) { ext = new ConnectionExt(); *ext = *(rval.ext); } else ext = NULL; #endif return *this; } //----------------------------------------------------------------------------- // // Connection::check_and_reconnect() methods family // // Check if a re-connection is needed and if true, try to reconnect. // These meethods also manage a TangoMonitor object for thread safety. // Some of them set parameters while the object is locked in order to pass // them to the caller in thread safe way. // //----------------------------------------------------------------------------- void Connection::check_and_reconnect() { int local_connection_state; { ReaderLock guard(con_to_mon); local_connection_state = connection_state; } if (local_connection_state != CONNECTION_OK) { WriterLock guard(con_to_mon); if (connection_state != CONNECTION_OK) reconnect(dbase_used); } } void Connection::check_and_reconnect(Tango::DevSource &sou) { int local_connection_state; { ReaderLock guard(con_to_mon); local_connection_state = connection_state; sou = source; } if (local_connection_state != CONNECTION_OK) { WriterLock guard(con_to_mon); if (connection_state != CONNECTION_OK) reconnect(dbase_used); } } void Connection::check_and_reconnect(Tango::AccessControlType &act) { int local_connection_state; { ReaderLock guard(con_to_mon); local_connection_state = connection_state; act = access; } if (local_connection_state != CONNECTION_OK) { WriterLock guard(con_to_mon); if (connection_state != CONNECTION_OK) { reconnect(dbase_used); act = access; } } } void Connection::check_and_reconnect(Tango::DevSource &sou,Tango::AccessControlType &act) { int local_connection_state; { ReaderLock guard(con_to_mon); local_connection_state = connection_state; act = access; sou = source; } if (local_connection_state != CONNECTION_OK) { WriterLock guard(con_to_mon); if (connection_state != CONNECTION_OK) { reconnect(dbase_used); act = access; } } } void Connection::set_connection_state(int con) { WriterLock guard(con_to_mon); connection_state = con; } Tango::DevSource Connection::get_source() { ReaderLock guard(con_to_mon); return source; } void Connection::set_source(Tango::DevSource sou) { WriterLock guard(con_to_mon); source = sou; } //----------------------------------------------------------------------------- // // Connection::connect() - method to create connection to a TANGO device // using its stringified CORBA reference i.e. IOR or corbaloc // //----------------------------------------------------------------------------- void Connection::connect(string &corba_name) { bool retry = true; long db_retries = DB_START_PHASE_RETRIES; bool connect_to_db = false; while (retry == true) { try { Object_var obj; obj = ApiUtil::instance()->get_orb()->string_to_object(corba_name.c_str()); // // Narrow CORBA string name to CORBA object // First, try as a Device_5, then as a Device_4, then as .... and finally as a Device // // But we have want to know if the connection to the device is OK or not. // The _narrow() call does not necessary generates a remote call. It all depends on the object IDL type // stored in the IOR. If in the IOR, the IDL is the same than the one on which the narrow is done (Device_5 on both // side for instance), then the _narrow call will not generate any remote call and therefore, we don know // if the connection is OK or NOT. This is the reason of the _non_existent() call. // In case the IDl in the IOR and in the narrow() call are different, then the _narrow() call try to execute a // remote _is_a() call and therefore tries to connect to the device. IN this case, the _non_existent() call is // useless. But because we don want to analyse the IOR ourself, we always call _non_existent() // Reset the connection timeout only after the _non_existent call. // if (corba_name.find(DbObjName) != string::npos) connect_to_db = true; if (connect_to_db == false) { if (user_connect_timeout != -1) omniORB::setClientConnectTimeout(user_connect_timeout); else omniORB::setClientConnectTimeout(NARROW_CLNT_TIMEOUT); } device_5 = Device_5::_narrow(obj); if (CORBA::is_nil(device_5)) { device_4 = Device_4::_narrow(obj); if (CORBA::is_nil(device_4)) { device_3 = Device_3::_narrow(obj); if (CORBA::is_nil(device_3)) { device_2 = Device_2::_narrow(obj); if (CORBA::is_nil(device_2)) { device = Device::_narrow(obj); if (CORBA::is_nil(device)) { cerr << "Can't build connection to object " << corba_name << endl; connection_state = CONNECTION_NOTOK; TangoSys_OMemStream desc; desc << "Failed to connect to device " << dev_name(); desc << " (device nil after _narrowing)" << ends; ApiConnExcept::throw_exception((const char*)API_CantConnectToDevice, desc.str(), (const char*)"Connection::connect()"); } else { device->_non_existent(); version = 1; } } else { device_2->_non_existent(); version = 2; device = Device_2::_duplicate(device_2); } } else { device_3->_non_existent(); version = 3; device_2 = Device_3::_duplicate(device_3); device = Device_3::_duplicate(device_3); } } else { device_4->_non_existent(); version = 4; device_3 = Device_4::_duplicate(device_4); device_2 = Device_4::_duplicate(device_4); device = Device_4::_duplicate(device_4); } } else { device_5->_non_existent(); version = 5; device_4 = Device_5::_duplicate(device_5); device_3 = Device_5::_duplicate(device_5); device_2 = Device_5::_duplicate(device_5); device = Device_5::_duplicate(device_5); } // // Warning! Some non standard code (omniORB specific). // Set a flag if the object is running on a host with several net addresses. This is used during re-connection // algo. // if (corba_name[0] == 'I' && corba_name[1] == 'O' && corba_name[2] == 'R') { IOP::IOR ior; toIOR(corba_name.c_str(),ior); IIOP::ProfileBody pBody; IIOP::unmarshalProfile(ior.profiles[0],pBody); CORBA::ULong total = pBody.components.length(); for (CORBA::ULong index=0; index < total; index++) { IOP::TaggedComponent& c = pBody.components[index]; if (c.tag == 3) { ext->has_alt_adr = true; break; } else ext->has_alt_adr = false; } } // if (connect_to_db == false) // omniORB::setClientConnectTimeout(0); retry = false; // // Mark the connection as OK and set timeout to its value // (The default is 3 seconds) // connection_state = CONNECTION_OK; if (timeout != CLNT_TIMEOUT) set_timeout_millis(timeout); } catch (CORBA::SystemException &ce) { // if (connect_to_db == false) // omniORB::setClientConnectTimeout(0); TangoSys_OMemStream desc; TangoSys_MemStream reason; bool db_connect = false; desc << "Failed to connect to "; string::size_type pos = corba_name.find(':'); if (pos == string::npos) { desc << "device " << dev_name() << ends; reason << API_CantConnectToDevice << ends; } else { string prot = corba_name.substr(0,pos); if (prot == "corbaloc") { string::size_type tmp = corba_name.find('/'); if (tmp != string::npos) { string dev = corba_name.substr(tmp + 1); if (dev == "database") { desc << "database on host "; desc << db_host << " with port "; desc << db_port << ends; reason << "API_CantConnectToDatabase" << ends; db_retries--; if (db_retries != 0) db_connect = true; } else { desc << "device " << dev_name() << ends; if (CORBA::OBJECT_NOT_EXIST::_downcast(&ce) != 0) reason << "API_DeviceNotDefined" << ends; else if (CORBA::TRANSIENT::_downcast(&ce) != 0) reason << "API_ServerNotRunning" << ends; else reason << API_CantConnectToDevice << ends; } } else { desc << "device " << dev_name() << ends; reason << API_CantConnectToDevice << ends; } } else { desc << "device " << dev_name() << ends; reason << API_CantConnectToDevice << ends; } } if (db_connect == false) { ApiConnExcept::re_throw_exception(ce,reason.str(),desc.str(), (const char *)"Connection::connect"); } } } } //----------------------------------------------------------------------------- // // Connection::toIOR() - Convert string IOR to omniORB IOR object // omniORB specific code !!! // //----------------------------------------------------------------------------- void Connection::toIOR(const char* iorstr,IOP::IOR& ior) { size_t s = (iorstr ? strlen(iorstr) : 0); if (s<4) throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO); const char *p = iorstr; if (p[0] != 'I' || p[1] != 'O' || p[2] != 'R' || p[3] != ':') throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO); s = (s-4)/2; // how many octets are there in the string p += 4; cdrMemoryStream buf((CORBA::ULong)s,0); for (int i=0; i<(int)s; i++) { int j = i*2; CORBA::Octet v; if (p[j] >= '0' && p[j] <= '9') { v = ((p[j] - '0') << 4); } else if (p[j] >= 'a' && p[j] <= 'f') { v = ((p[j] - 'a' + 10) << 4); } else if (p[j] >= 'A' && p[j] <= 'F') { v = ((p[j] - 'A' + 10) << 4); } else throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO); if (p[j+1] >= '0' && p[j+1] <= '9') { v += (p[j+1] - '0'); } else if (p[j+1] >= 'a' && p[j+1] <= 'f') { v += (p[j+1] - 'a' + 10); } else if (p[j+1] >= 'A' && p[j+1] <= 'F') { v += (p[j+1] - 'A' + 10); } else throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO); buf.marshalOctet(v); } buf.rewindInputPtr(); CORBA::Boolean b = buf.unmarshalBoolean(); buf.setByteSwapFlag(b); ior.type_id = IOP::IOR::unmarshaltype_id(buf); ior.profiles <<= buf; } //----------------------------------------------------------------------------- // // Connection::reconnect() - reconnect to a CORBA object // //----------------------------------------------------------------------------- void Connection::reconnect(bool db_used) { struct timeval now; #ifndef _TG_WINDOWS_ gettimeofday(&now, NULL); #else struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #endif /* _TG_WINDOWS_ */ double t = (double)now.tv_sec + ((double)now.tv_usec / 1000000); double delay = t - prev_failed_t0; if (connection_state != CONNECTION_OK) { // Do not reconnect if to soon if ( (prev_failed == true) && delay < (RECONNECTION_DELAY / 1000) ) { TangoSys_OMemStream desc; desc << "Failed to connect to device " << dev_name() << endl; desc << "The connection request was delayed." << endl; desc << "The last connection request was done less than " << RECONNECTION_DELAY << " ms ago" << ends; Tango::Except::throw_exception ( (const char *)API_CantConnectToDevice, desc.str(), (const char *)"Connection::reconnect"); } } try { string corba_name; if (connection_state != CONNECTION_OK) { if (db_used == true) { corba_name = get_corba_name(check_acc); if (check_acc == false) { ApiUtil *au = ApiUtil::instance(); int db_num; if (get_from_env_var() == true) db_num = au->get_db_ind(); else db_num = au->get_db_ind(get_db_host(),get_db_port_num()); (au->get_db_vect())[db_num]->clear_access_except_errors(); } } else corba_name = build_corba_name(); connect(corba_name); } // // Try to ping the device. With omniORB, it is possible that the first // real access to the device is done when a call to one of the interface // operation is done. Do it now. // if (connection_state == CONNECTION_OK) { try { // if (user_connect_timeout != -1) // omniORB::setClientConnectTimeout(user_connect_timeout); // else // omniORB::setClientConnectTimeout(NARROW_CLNT_TIMEOUT); device->ping(); // omniORB::setClientConnectTimeout(0); prev_failed_t0 = t; prev_failed = false; // // If the device is the database, call its post-reconnection method // // TODO: Implement this with a virtual method in Connection and Database // class. Doing it now, will break compatibility (one more virtual method) // if (corba_name.find("database") != string::npos) { static_cast(this)->post_reconnection(); } } catch (CORBA::SystemException &ce) { // omniORB::setClientConnectTimeout(0); connection_state = CONNECTION_NOTOK; TangoSys_OMemStream desc; desc << "Failed to connect to device " << dev_name() << ends; ApiConnExcept::re_throw_exception(ce, (const char *)API_CantConnectToDevice, desc.str(), (const char *)"Connection::reconnect"); } } } catch (DevFailed &) { prev_failed = true; prev_failed_t0 = t; throw; } } //----------------------------------------------------------------------------- // // Connection::is_connected() - returns true if connection is in the OK state // //----------------------------------------------------------------------------- bool Connection::is_connected() { bool connected = true; ReaderLock guard(con_to_mon); if(connection_state != CONNECTION_OK) connected = false; return connected; } //----------------------------------------------------------------------------- // // Connection::get_env_var() - Get an environment variable // // This method get an environment variable value from different source. // which are (orderd by piority) // // 1 - A real environement variable // 2 - A file ".tangorc" in the user home directory // 3 - A file "/etc/tangorc" // // in : - env_var_name : The environment variable name // // out : - env_var : The string initialised with the env. variable value // // This method returns 0 of the env. variable is found. Otherwise, it returns -1 // //----------------------------------------------------------------------------- int Connection::get_env_var(const char *env_var_name,string &env_var) { int ret = -1; char *env_c_str; // // try to get it as a classical env. variable // env_c_str = getenv(env_var_name); if (env_c_str == NULL) { #ifndef _TG_WINDOWS_ uid_t user_id = geteuid(); struct passwd pw; struct passwd *pw_ptr; char buffer[1024]; if (getpwuid_r(user_id,&pw,buffer,sizeof(buffer),&pw_ptr) != 0) { return ret; } if (pw_ptr == NULL) { return ret; } // // Try to get it from the user home dir file // string home_file(pw.pw_dir); home_file = home_file + "/" + USER_ENV_VAR_FILE; int local_ret; string local_env_var; local_ret = get_env_var_from_file(home_file,env_var_name,local_env_var); if (local_ret == 0) { env_var = local_env_var; ret = 0; } else { // // Try to get it from a host defined file // home_file = TANGO_RC_FILE; local_ret = get_env_var_from_file(home_file,env_var_name,local_env_var); if (local_ret == 0) { env_var = local_env_var; ret = 0; } } #else char *env_tango_root; env_tango_root = getenv(WindowsEnvVariable); if (env_tango_root != NULL) { string home_file(env_tango_root); home_file = home_file + "/" + WINDOWS_ENV_VAR_FILE; int local_ret; string local_env_var; local_ret = get_env_var_from_file(home_file,env_var_name,local_env_var); if (local_ret == 0) { env_var = local_env_var; ret = 0; } } #endif } else { env_var = env_c_str; ret = 0; } return ret; } //----------------------------------------------------------------------------- // // Connection::get_env_var_from_file() - Get an environment variable from a file // // in : - env_var : The environment variable name // - f_name : The file name // // out : - ret_env_var : The string initialised with the env. variable value // // This method returns 0 of the env. variable is found. Otherwise, it returns -1 // //----------------------------------------------------------------------------- int Connection::get_env_var_from_file(string &f_name,const char *env_var,string &ret_env_var) { ifstream inFile; string file_line; string var(env_var); int ret = -1; inFile.open(f_name.c_str()); if (!inFile) { return ret; } transform(var.begin(),var.end(),var.begin(),::tolower); string::size_type pos_env,pos_comment; while (!inFile.eof()) { getline(inFile,file_line); transform(file_line.begin(),file_line.end(),file_line.begin(),::tolower); if ((pos_env = file_line.find(var)) != string::npos) { pos_comment = file_line.find('#'); if ((pos_comment != string::npos) && (pos_comment < pos_env)) continue; string::size_type pos; if ((pos = file_line.find('=')) != string::npos) { string tg_host = file_line.substr(pos + 1); string::iterator end_pos = remove(tg_host.begin(),tg_host.end(),' '); tg_host.erase(end_pos,tg_host.end()); ret_env_var = tg_host; ret = 0; break; } } } inFile.close(); return ret; } //------------------------------------------------------------------------------------------------------------------- // // method: // Connection::get_fqdn() // // description: // This method gets the host fully qualified domain name (from DNS) and modified the passed string accordingly // // argument: // in/out : // - the_host: The original host name // //------------------------------------------------------------------------------------------------------------------ void Connection::get_fqdn(string &the_host) { // // If the host name we received is the name of the host we are running on, // set a flag // char buffer[80]; bool local_host = false; if (gethostname(buffer,80) == 0) { if (::strcmp(buffer,the_host.c_str()) == 0) local_host = true; } struct addrinfo hints; memset(&hints,0,sizeof(struct addrinfo)); hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; struct addrinfo *info; struct addrinfo *ptr; char tmp_host[512]; bool host_found = false; vector ip_list; // // If we are running on local host, get IP address(es) from NIC board // if (local_host == true) { ApiUtil *au = ApiUtil::instance(); au->get_ip_from_if(ip_list); hints.ai_flags |= AI_NUMERICHOST; } else ip_list.push_back(the_host); // // Try to get FQDN // size_t i; for(i = 0; i < ip_list.size() && !host_found; i++) { int result = getaddrinfo(ip_list[i].c_str(),NULL,&hints,&info); if (result == 0) { ptr = info; int nb_loop = 0; string myhost; string::size_type pos; while (ptr != NULL) { if (getnameinfo(ptr->ai_addr,ptr->ai_addrlen,tmp_host,512,0,0,NI_NAMEREQD) == 0) { nb_loop++; myhost = tmp_host; pos = myhost.find('.'); if (pos != string::npos) { string canon = myhost.substr(0,pos); if (canon == the_host) { the_host = myhost; host_found = true; break; } } } ptr = ptr->ai_next; } freeaddrinfo(info); if (host_found == false && nb_loop == 1 && i == (ip_list.size() - 1)) { the_host = myhost; } } } } //----------------------------------------------------------------------------- // // Connection::get_timeout_millis() - public method to get timeout on a TANGO device // //----------------------------------------------------------------------------- int Connection::get_timeout_millis() { ReaderLock guard(con_to_mon); return timeout; } //----------------------------------------------------------------------------- // // Connection::set_timeout_millis() - public method to set timeout on a TANGO device // //----------------------------------------------------------------------------- void Connection::set_timeout_millis(int millisecs) { WriterLock guard(con_to_mon); timeout = millisecs; try { if (connection_state != CONNECTION_OK) reconnect(dbase_used); omniORB::setClientCallTimeout(device,millisecs); switch (version) { case 5: omniORB::setClientCallTimeout(device_5,millisecs); omniORB::setClientCallTimeout(device_4,millisecs); omniORB::setClientCallTimeout(device_3,millisecs); omniORB::setClientCallTimeout(device_2,millisecs); break; case 4: omniORB::setClientCallTimeout(device_4,millisecs); omniORB::setClientCallTimeout(device_3,millisecs); omniORB::setClientCallTimeout(device_2,millisecs); break; case 3: omniORB::setClientCallTimeout(device_3,millisecs); omniORB::setClientCallTimeout(device_2,millisecs); break; case 2: omniORB::setClientCallTimeout(device_2,millisecs); break; default: break; } } catch (Tango::DevFailed &) {} } //----------------------------------------------------------------------------- // // Connection::command_inout() - public method to execute a command on a TANGO device // //----------------------------------------------------------------------------- DeviceData Connection::command_inout(string &command) { DeviceData data_in; return(command_inout(command,data_in)); } //----------------------------------------------------------------------------- // // Connection::command_inout() - public method to execute a command on a TANGO device // //----------------------------------------------------------------------------- DeviceData Connection::command_inout(string &command, DeviceData &data_in) { // // We are using a pointer to an Any as the return value of the command_inout // call. This is because the assignament to the Any_var any in the // DeviceData object in faster in this case (no copy). // Don't forget that the any_var in the DeviceData takes ownership of the // memory allocated // DeviceData data_out; int ctr = 0; DevSource local_source; AccessControlType local_act; while (ctr < 2) { try { check_and_reconnect(local_source,local_act); // // Manage control access in case the access right // is READ_ONLY. We need to check if the command is a // "READ" command or not // if (local_act == ACCESS_READ) { ApiUtil *au = ApiUtil::instance(); vector & v_d = au->get_db_vect(); Database *db; if (v_d.empty() == true) db = static_cast(this); else { int db_num; if (get_from_env_var() == true) db_num = au->get_db_ind(); else db_num = au->get_db_ind(get_db_host(),get_db_port_num()); db = v_d[db_num]; /* if (db->is_control_access_checked() == false) db = static_cast(this);*/ } // // If the command is not allowed, throw exception // Also throw exception if it was not possible to get the list // of allowed commands from the control access service // // The ping rule is simply to send to the client correct // error message in case of re-connection // string d_name = dev_name(); if (db->is_command_allowed(d_name,command) == false) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } DevErrorList &e = db->get_access_except_errors(); /* if (e.length() != 0) { DevFailed df(e); throw df; }*/ TangoSys_OMemStream desc; if (e.length() == 0) desc << "Command " << command << " on device " << dev_name() << " is not authorized" << ends; else { desc << "Command " << command << " on device " << dev_name() << " is not authorized because an error occurs while talking to the Controlled Access Service" << ends; string ex(e[0].desc); if (ex.find("defined") != string::npos) desc << "\n" << ex; desc << ends; } NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"Connection::command_inout()"); } } // // Now, try to execute the command // CORBA::Any *received; if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); received = dev->command_inout_4(command.c_str(),data_in.any,local_source,ci); } else if (version >= 2) { Device_2_var dev = Device_2::_duplicate(device_2); received = dev->command_inout_2(command.c_str(),data_in.any,local_source); } else { Device_var dev = Device::_duplicate(device); received = dev->command_inout(command.c_str(),data_in.any); } ctr = 2; data_out.any = received; } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"Connection::command_inout()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"Connection::command_inout()"); else Except::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"Connection::command_inout()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(trans); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(one); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(comm); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } return data_out; } //----------------------------------------------------------------------------- // // Connection::command_inout() - public method to execute a command on a TANGO device // using low level CORBA types // //----------------------------------------------------------------------------- CORBA::Any_var Connection::command_inout(string &command, CORBA::Any &any) { int ctr = 0; Tango::DevSource local_source; Tango::AccessControlType local_act; while (ctr < 2) { try { check_and_reconnect(local_source,local_act); // // Manage control access in case the access right // is READ_ONLY. We need to check if the command is a // "READ" command or not // if (local_act == ACCESS_READ) { ApiUtil *au = ApiUtil::instance(); vector & v_d = au->get_db_vect(); Database *db; if (v_d.empty() == true) db = static_cast(this); else { int db_num; if (get_from_env_var() == true) db_num = au->get_db_ind(); else db_num = au->get_db_ind(get_db_host(),get_db_port_num()); db = v_d[db_num]; /* if (db->is_control_access_checked() == false) db = static_cast(this);*/ } // // If the command is not allowed, throw exception // Also throw exception if it was not possible to get the list // of allowed commands from the control access service // // The ping rule is simply to send to the client correct // error message in case of re-connection // string d_name = dev_name(); if (db->is_command_allowed(d_name,command) == false) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } DevErrorList &e = db->get_access_except_errors(); /* if (e.length() != 0) { DevFailed df(e); throw df; }*/ TangoSys_OMemStream desc; if (e.length() == 0) desc << "Command " << command << " on device " << dev_name() << " is not authorized" << ends; else { desc << "Command " << command << " on device " << dev_name() << " is not authorized because an error occurs while talking to the Controlled Access Service" << ends; string ex(e[0].desc); if (ex.find("defined") != string::npos) desc << "\n" << ex; desc << ends; } NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"Connection::command_inout()"); } } if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); return (dev->command_inout_4(command.c_str(),any,local_source,ci)); } else if (version >= 2) { Device_2_var dev = Device_2::_duplicate(device_2); return (dev->command_inout_2(command.c_str(),any,local_source)); } else { Device_var dev = Device::_duplicate(device); return (dev->command_inout(command.c_str(),any)); } ctr = 2; } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"Connection::command_inout()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"Connection::command_inout()"); else Except::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"Connection::command_inout()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(trans); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(one); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT_CMD(comm); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"Connection::command_inout()"); } } // // Just to make VC++ quiet (will never reach this code !) // CORBA::Any_var tmp; return tmp; } //----------------------------------------------------------------------------- // // DeviceProxy::DeviceProxy() - constructor for device proxy object // //----------------------------------------------------------------------------- DeviceProxy::DeviceProxy (string &name, CORBA::ORB *orb) : Connection(orb), db_dev(NULL), is_alias(false), adm_device(NULL), lock_ctr(0), ext_proxy(new DeviceProxyExt()) { real_constructor(name,true); } DeviceProxy::DeviceProxy (const char *na, CORBA::ORB *orb) : Connection(orb), db_dev(NULL), is_alias(false), adm_device(NULL), lock_ctr(0), ext_proxy(new DeviceProxyExt()) { string name(na); real_constructor(name,true); } DeviceProxy::DeviceProxy (string &name, bool need_check_acc,CORBA::ORB *orb) : Connection(orb), db_dev(NULL), is_alias(false), adm_device(NULL), lock_ctr(0), ext_proxy(new DeviceProxyExt()) { real_constructor(name,need_check_acc); } DeviceProxy::DeviceProxy (const char *na, bool need_check_acc,CORBA::ORB *orb) : Connection(orb), db_dev(NULL), is_alias(false), adm_device(NULL), lock_ctr(0), ext_proxy(new DeviceProxyExt()) { string name(na); real_constructor(name,need_check_acc); } void DeviceProxy::real_constructor (string &name,bool need_check_acc) { // // Parse device name // parse_name(name); string corba_name; bool exported = true; if (dbase_used == true) { try { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); db_dev = new DbDevice(device_name); int ind = ui->get_db_ind(); db_host = (ui->get_db_vect())[ind]->get_db_host(); db_port = (ui->get_db_vect())[ind]->get_db_port(); db_port_num = (ui->get_db_vect())[ind]->get_db_port_num(); } else { db_dev = new DbDevice(device_name,db_host,db_port); if (ext_proxy->nethost_alias == true) { Database *tmp_db = db_dev->get_dbase(); const string &orig = tmp_db->get_orig_tango_host(); if (orig.empty() == true) { string orig_tg_host = ext_proxy->orig_tango_host; if (orig_tg_host.find('.') == string::npos) { get_fqdn(orig_tg_host); } tmp_db->set_orig_tango_host(ext_proxy->orig_tango_host); } } } } catch (Tango::DevFailed &e) { if (strcmp(e.errors[0].reason.in(),API_TangoHostNotSet) == 0) { cerr << e.errors[0].desc.in() << endl; } throw; } try { corba_name = get_corba_name(need_check_acc); } catch (Tango::DevFailed &dfe) { if (strcmp(dfe.errors[0].reason,"DB_DeviceNotDefined") == 0) { delete db_dev; TangoSys_OMemStream desc; desc << "Can't connect to device " << device_name << ends; ApiConnExcept::re_throw_exception(dfe, (const char *)"API_DeviceNotDefined", desc.str(), (const char *)"DeviceProxy::DeviceProxy"); } else if (strcmp(dfe.errors[0].reason,API_DeviceNotExported) == 0) exported = false; } } else { corba_name = build_corba_name(); // // If we are not using the database, give write access // access = ACCESS_WRITE; } // // Implement stateless new() i.e. even if connect fails continue // If the DeviceProxy was created using device alias, ask for the real // device name. // try { if (exported == true) { connect(corba_name); if (is_alias == true) { CORBA::String_var real_name = device->name(); device_name = real_name.in(); transform(device_name.begin(),device_name.end(),device_name.begin(),::tolower); db_dev->set_name(device_name); } } } catch (Tango::ConnectionFailed &dfe) { set_connection_state(CONNECTION_NOTOK); if (dbase_used == false) { if (strcmp(dfe.errors[1].reason,"API_DeviceNotDefined") == 0) throw; } } catch (CORBA::SystemException &) { set_connection_state(CONNECTION_NOTOK); if (dbase_used == false) throw; } // // For non-database device , try to ping them. It's the only way to know that // the device is not defined // if (dbase_used == false) { try { ping(); } catch (Tango::ConnectionFailed &dfe) { if (strcmp(dfe.errors[1].reason,"API_DeviceNotDefined") == 0) throw; } } // // get the name of the asscociated device when connecting // inside a device server // try { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) { Tango::Util *tg = Tango::Util::instance(false); tg->get_sub_dev_diag().register_sub_device (tg->get_sub_dev_diag().get_associated_device(), name); } } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),"API_UtilSingletonNotCreated") != 0) throw; } return; } //----------------------------------------------------------------------------- // // DeviceProxy::DeviceProxy() - copy constructor // //----------------------------------------------------------------------------- DeviceProxy::DeviceProxy(const DeviceProxy &sou):Connection(sou),ext_proxy(Tango_nullptr) { // // Copy DeviceProxy members // device_name = sou.device_name; alias_name = sou.alias_name; is_alias = sou.is_alias; adm_dev_name = sou.adm_dev_name; lock_ctr = sou.lock_ctr; if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) db_dev = new DbDevice(device_name,Tango::Util::instance()->get_database()); else db_dev = new DbDevice(device_name); } else { db_dev = new DbDevice(device_name,db_host,db_port); } } // // Copy adm device pointer // if (sou.adm_device == NULL) adm_device = NULL; else { adm_device = new DeviceProxy(sou.adm_device->dev_name().c_str()); } // // Copy extension class // #ifdef HAS_UNIQUE_PTR if (sou.ext_proxy.get() != NULL) { ext_proxy.reset(new DeviceProxyExt); *(ext_proxy.get()) = *(sou.ext_proxy.get()); } #else if (sou.ext_proxy == NULL) ext_proxy = NULL; else { ext_proxy = new DeviceProxyExt(); *ext_proxy = *(sou.ext_proxy); } #endif } //----------------------------------------------------------------------------- // // DeviceProxy::DeviceProxy() - assignement operator // //----------------------------------------------------------------------------- DeviceProxy &DeviceProxy::operator=(const DeviceProxy &rval) { if (this != &rval) { this->Connection::operator=(rval); // // Now DeviceProxy members // device_name = rval.device_name; alias_name = rval.alias_name; is_alias = rval.is_alias; adm_dev_name = rval.adm_dev_name; lock_ctr = rval.lock_ctr; lock_valid = rval.lock_valid; delete db_dev; if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) db_dev = new DbDevice(device_name,Tango::Util::instance()->get_database()); else db_dev = new DbDevice(device_name); } else { db_dev = new DbDevice(device_name,db_host,db_port); } } delete adm_device; if (rval.adm_device != NULL) { adm_device = new DeviceProxy(rval.adm_device->dev_name().c_str()); } else adm_device = NULL; #ifdef HAS_UNIQUE_PTR if (rval.ext_proxy.get() != NULL) { ext_proxy.reset(new DeviceProxyExt); *(ext_proxy.get()) = *(rval.ext_proxy.get()); } else ext_proxy.reset(); #else delete ext_proxy; if (rval.ext_proxy != NULL) { ext_proxy = new DeviceProxyExt; *ext_proxy = *(rval.ext_proxy); } else ext_proxy = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DeviceProxy::parse_name() - Parse device name according to Tango device // name syntax // // in : - full_name : The device name // //----------------------------------------------------------------------------- void DeviceProxy::parse_name(string &full_name) { string name_wo_prot; string name_wo_db_mod; string dev_name,object_name; // // Error of the string is empty // if (full_name.empty() == true) { TangoSys_OMemStream desc; desc << "The given name is an empty string!!! " << full_name << endl; desc << "Device name syntax is domain/family/member" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } // // Device name in lower case letters // string full_name_low(full_name); transform(full_name_low.begin(),full_name_low.end(),full_name_low.begin(),::tolower); // // Try to find protocol specification in device name and analyse it // string::size_type pos = full_name_low.find(PROT_SEP); if (pos == string::npos) { if (full_name_low.size() > 2) { if ((full_name_low[0] == '/') && (full_name_low[1] == '/')) name_wo_prot = full_name_low.substr(2); else name_wo_prot = full_name_low; } else name_wo_prot = full_name_low; } else { string protocol = full_name_low.substr(0,pos); if (protocol == TANGO_PROTOCOL) { name_wo_prot = full_name_low.substr(pos + 3); } else if (protocol == TACO_PROTOCOL) { TangoSys_OMemStream desc; desc << "Taco protocol is not supported" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedProtocol", desc.str(), (const char*)"DeviceProxy::parse_name()"); } else { TangoSys_OMemStream desc; desc << protocol; desc << " protocol is an unsupported protocol" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedProtocol", desc.str(), (const char*)"DeviceProxy::parse_name()"); } } // // Try to find database database modifier and analyse it // pos = name_wo_prot.find(MODIFIER); if (pos != string::npos) { string mod = name_wo_prot.substr(pos + 1); if (mod == DBASE_YES) { string::size_type len = name_wo_prot.size(); name_wo_db_mod = name_wo_prot.substr(0,len - (len - pos)); dbase_used = true; } else if (mod == DBASE_NO) { string::size_type len = name_wo_prot.size(); name_wo_db_mod = name_wo_prot.substr(0,len - (len - pos)); dbase_used = false; } else { //cerr << mod << " is a non supported database modifier!" << endl; TangoSys_OMemStream desc; desc << mod; desc << " modifier is an unsupported db modifier" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedDBaseModifier", desc.str(), (const char*)"DeviceProxy::parse_name()"); } } else { name_wo_db_mod = name_wo_prot; dbase_used = true; } if (dbase_used == false) { // // Extract host name and port number // pos = name_wo_db_mod.find(HOST_SEP); if (pos == string::npos) { TangoSys_OMemStream desc; desc << "Host and port not correctly defined in device name " << full_name << ends; ApiWrongNameExcept::throw_exception((const char*)API_WrongDeviceNameSyntax, desc.str(), (const char*)"DeviceProxy::parse_name()"); } host = name_wo_db_mod.substr(0,pos); string::size_type tmp = name_wo_db_mod.find(PORT_SEP); if (tmp == string::npos) { TangoSys_OMemStream desc; desc << "Host and port not correctly defined in device name " << full_name << ends; ApiWrongNameExcept::throw_exception((const char*)API_WrongDeviceNameSyntax, desc.str(), (const char*)"DeviceProxy::parse_name()"); } port = name_wo_db_mod.substr(pos + 1,tmp - pos - 1); TangoSys_MemStream s; s << port << ends; s >> port_num; device_name = name_wo_db_mod.substr(tmp + 1); // // Check device name syntax (domain/family/member). Alias are forbidden without // using the db // tmp = device_name.find(DEV_NAME_FIELD_SEP); if (tmp == string::npos) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << endl; desc << "Rem: Alias are forbidden when not using a database" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } string::size_type prev_sep = tmp; tmp = device_name.find(DEV_NAME_FIELD_SEP,tmp + 1); if ((tmp == string::npos) || (tmp == prev_sep + 1)) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << endl; desc << "Rem: Alias are forbidden when not using a database" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } prev_sep = tmp; tmp = device_name.find(DEV_NAME_FIELD_SEP,tmp + 1); if (tmp != string::npos) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << endl; desc << "Rem: Alias are forbidden when not using a database" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } db_host = db_port = NOT_USED; db_port_num = 0; from_env_var = false; } else { // // Search if host and port are specified // pos = name_wo_db_mod.find(PORT_SEP); if (pos == string::npos) { // // It could be an alias name, check its syntax // pos = name_wo_db_mod.find(HOST_SEP); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong alias name syntax in " << full_name << " (: is not allowed in alias name)" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } pos = name_wo_db_mod.find(RES_SEP); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong alias name syntax in " << full_name << " (-> is not allowed in alias name)" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } // // Alias name syntax OK // alias_name = device_name = name_wo_db_mod; is_alias = true; from_env_var = true; port_num = 0; host = FROM_IOR; port = FROM_IOR; } else { string bef_sep = name_wo_db_mod.substr(0,pos); string::size_type tmp = bef_sep.find(HOST_SEP); if (tmp == string::npos) { // // There is at least one / in dev name but it is not a TANGO_HOST definition. // A correct dev name must have 2 /. Check this. An alias cannot have any / // if (pos == 0) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } string::size_type prev_sep = pos; pos = name_wo_db_mod.find(DEV_NAME_FIELD_SEP,pos + 1); if ((pos == string::npos) || (pos == prev_sep + 1)) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } prev_sep = pos; pos = name_wo_db_mod.find(DEV_NAME_FIELD_SEP,prev_sep + 1); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } device_name = name_wo_db_mod; from_env_var = true; port_num = 0; port = FROM_IOR; host = FROM_IOR; } else { string tmp_host(bef_sep.substr(0,tmp)); string safe_tmp_host(tmp_host); if (tmp_host.find('.') == string::npos) get_fqdn(tmp_host); string::size_type pos2 = tmp_host.find('.'); bool alias_used = false; string fq; if (pos2 != string::npos) { string h_name = tmp_host.substr(0,pos2); fq = tmp_host.substr(pos2); if (h_name != tmp_host) alias_used = true; } if (alias_used == true) { ext_proxy->nethost_alias = true; ext_proxy->orig_tango_host = safe_tmp_host; if (safe_tmp_host.find('.') == string::npos) ext_proxy->orig_tango_host = ext_proxy->orig_tango_host + fq; } else ext_proxy->nethost_alias = false; db_host = tmp_host; db_port = bef_sep.substr(tmp + 1); TangoSys_MemStream s; s << db_port << ends; s >> db_port_num; object_name = name_wo_db_mod.substr(pos + 1); // // We should now check if the object name is a device name or an alias // pos = object_name.find(DEV_NAME_FIELD_SEP); if (pos == string::npos) { // // It is an alias. Check its syntax // pos = object_name.find(HOST_SEP); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong alias name syntax in " << full_name << " (: is not allowed in alias name)" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } pos = object_name.find(RES_SEP); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong alias name syntax in " << full_name << " (-> is not allowed in alias name)" << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } alias_name = device_name = object_name; is_alias = true; // // Alias name syntax OK, but is it really an alias defined in db ? // } else { // // It's a device name. Check its syntax. // There is at least one / in dev name but it is not a TANGO_HOST definition. // A correct dev name must have 2 /. Check this. An alias cannot have any / // string::size_type prev_sep = pos; pos = object_name.find(DEV_NAME_FIELD_SEP,pos + 1); if ((pos == string::npos) || (pos == prev_sep + 1)) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } prev_sep = pos; pos = object_name.find(DEV_NAME_FIELD_SEP,prev_sep + 1); if (pos != string::npos) { TangoSys_OMemStream desc; desc << "Wrong device name syntax (domain/family/member) in " << full_name << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"DeviceProxy::parse_name()"); } device_name = object_name; } from_env_var = false; port_num = 0; port = FROM_IOR; host = FROM_IOR; } } } } //----------------------------------------------------------------------------- // // DeviceProxy::get_corba_name() - return IOR for device from database // //----------------------------------------------------------------------------- string DeviceProxy::get_corba_name(bool need_check_acc) { // // If we are in a server, try a local import // (in case the device is embedded in the same process) // string local_ior; if (ApiUtil::instance()->in_server() == true) local_import(local_ior); // // If we are not in a server or if the device is not in the same process, // ask the database // DbDevImportInfo import_info; if (local_ior.size() == 0) { import_info = db_dev->import_device(); if (import_info.exported != 1) { connection_state = CONNECTION_NOTOK; TangoSys_OMemStream desc; desc << "Device " << device_name << " is not exported (hint: try starting the device server)" << ends; ApiConnExcept::throw_exception(API_DeviceNotExported,desc.str(), "DeviceProxy::get_corba_name()"); } } // // Get device access right // if (need_check_acc == true) access = db_dev->check_access_control(); else check_acc = false; if (local_ior.size() != 0) return local_ior; else return import_info.ior; } //----------------------------------------------------------------------------- // // DeviceProxy::build_corba_name() - build corba name for non database device // server. In this case, corba name uses // the "corbaloc" naming schema // //----------------------------------------------------------------------------- string DeviceProxy::build_corba_name() { string db_corbaloc = "corbaloc:iiop:"; db_corbaloc = db_corbaloc + host + ":" + port; db_corbaloc = db_corbaloc + "/" + device_name; return db_corbaloc; } //----------------------------------------------------------------------------- // // DeviceProxy::reconnect() - Call the reconnection method and in case // the device has been created from its alias, // get its real name. // //----------------------------------------------------------------------------- void DeviceProxy::reconnect(bool db_used) { Connection::reconnect(db_used); if (connection_state == CONNECTION_OK) { if (is_alias == true) { CORBA::String_var real_name = device->name(); device_name = real_name.in(); transform(device_name.begin(),device_name.end(),device_name.begin(),::tolower); db_dev->set_name(device_name); } } } //----------------------------------------------------------------------------- // // DeviceProxy::import_info() - return import info for device from database // //----------------------------------------------------------------------------- DbDevImportInfo DeviceProxy::import_info() { DbDevImportInfo import_info; if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::import_info"); } else { import_info = db_dev->import_device(); } return(import_info); } //----------------------------------------------------------------------------- // // DeviceProxy::~DeviceProxy() - destructor to destroy proxy to TANGO device // //----------------------------------------------------------------------------- DeviceProxy::~DeviceProxy() { if (dbase_used == true) delete db_dev; // // If the device has some subscribed event, unsubscribe them // if (ApiUtil::_is_instance_null() == false) { ApiUtil *api_ptr = ApiUtil::instance(); ZmqEventConsumer *zmq = api_ptr->get_zmq_event_consumer(); if (zmq != Tango_nullptr) { vector ids; zmq->get_subscribed_event_ids(this,ids); if (ids.empty() == false) { vector::iterator ite; for (ite = ids.begin();ite != ids.end();++ite) { unsubscribe_event(*ite); } } } } // // If the device is locked, unlock it whatever the lock counter is // if (ApiUtil::_is_instance_null() == false) { if (lock_ctr > 0) { try { unlock(true); } catch(...) {} } } // // Delete memory // delete adm_device; #ifndef HAS_UNIQUE_PTR delete ext_proxy; #endif } //----------------------------------------------------------------------------- // // DeviceProxy::s) - ping TANGO device and return time elapsed in microseconds // //----------------------------------------------------------------------------- int DeviceProxy::ping() { int elapsed; #ifndef _TG_WINDOWS_ struct timeval before, after; gettimeofday(&before, NULL); #else struct _timeb before, after; _ftime(&before); #endif /* _TG_WINDOWS_ */ int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); dev->ping(); ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","ping",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","ping",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute ping on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::ping()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","ping",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute ping on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::ping()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute ping on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::ping()"); } } #ifndef _TG_WINDOWS_ gettimeofday(&after, NULL); elapsed = (after.tv_sec-before.tv_sec)*1000000; elapsed = (after.tv_usec-before.tv_usec) + elapsed; #else _ftime(&after); elapsed = (after.time-before.time)*1000000; elapsed = (after.millitm-before.millitm)*1000 + elapsed; #endif /* _TG_WINDOWS_ */ return(elapsed); } //----------------------------------------------------------------------------- // // DeviceProxy::name() - return TANGO device name as string // //----------------------------------------------------------------------------- string DeviceProxy::name() { string na; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); CORBA::String_var n = dev->name(); ctr = 2; na = n; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","name",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","name",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::name()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","name",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::name()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::name()"); } } return(na); } //----------------------------------------------------------------------------- // // DeviceProxy::alias() - return TANGO device alias (if any) // //----------------------------------------------------------------------------- string DeviceProxy::alias() { if (alias_name.size() == 0) { Database *db = this->get_device_db(); if (db != NULL) db->get_alias(device_name,alias_name); else { Tango::Except::throw_exception((const char *)"DB_AliasNotDefined", (const char *)"No alias found for your device", (const char *)"DeviceProxy::alias()"); } } return alias_name; } //----------------------------------------------------------------------------- // // DeviceProxy::state() - return TANGO state of device // //----------------------------------------------------------------------------- DevState DeviceProxy::state() { DevState sta = Tango::UNKNOWN; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); sta = dev->state(); ctr = 2; } catch (CORBA::TRANSIENT &transp) { TRANSIENT_NOT_EXIST_EXCEPT(transp,"DeviceProxy","state",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","state",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute state() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::state()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","state",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute state() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::state()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute state() on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::state()"); } } return sta; } //----------------------------------------------------------------------------- // // DeviceProxy::status() - return TANGO status of device // //----------------------------------------------------------------------------- string DeviceProxy::status() { string status_str; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); CORBA::String_var st = dev->status(); ctr = 2; status_str = st; } catch (CORBA::TRANSIENT &transp) { TRANSIENT_NOT_EXIST_EXCEPT(transp,"DeviceProxy","status",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","status",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute status() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::status()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","status",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute status() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::status()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute status() on device (CORBA exception)" << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::status()"); } } return(status_str); } //----------------------------------------------------------------------------- // // DeviceProxy::adm_name() - return TANGO admin name of device // //----------------------------------------------------------------------------- string DeviceProxy::adm_name() { string adm_name_str; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); CORBA::String_var st = dev->adm_name(); ctr = 2; adm_name_str = st; if (dbase_used == false) { string prot("tango://"); if (host.find('.') == string::npos) Connection::get_fqdn(host); prot = prot + host + ':' + port + '/'; adm_name_str.insert(0,prot); adm_name_str.append(MODIFIER_DBASE_NO); } else if (from_env_var == false) { string prot("tango://"); prot = prot + db_host + ':' + db_port + '/'; adm_name_str.insert(0,prot); } } catch (CORBA::TRANSIENT &transp) { TRANSIENT_NOT_EXIST_EXCEPT(transp,"DeviceProxy","adm_name",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","adm_name",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute adm_name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::adm_name()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","adm_name",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute adm_name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::adm_name()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute adm_name() on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::adm_name()"); } } return(adm_name_str); } //----------------------------------------------------------------------------- // // DeviceProxy::description() - return TANGO device description as string // //----------------------------------------------------------------------------- string DeviceProxy::description() { string description_str; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); CORBA::String_var st = dev->description(); ctr = 2; description_str = st; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","description",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","description",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute description() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::description()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","description",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute description() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::description()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute description() on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::description()"); } } return(description_str); } //----------------------------------------------------------------------------- // // DeviceProxy::black_box() - return the list of the last n commands exectued on // this TANGO device // //----------------------------------------------------------------------------- vector *DeviceProxy::black_box(int last_n_commands) { DevVarStringArray_var last_commands; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); Device_var dev = Device::_duplicate(device); last_commands = dev->black_box(last_n_commands); ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","black_box",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","black_box",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute black_box on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::black_box()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","black_box",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute black_box on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::black_box()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute black_box on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::black_box()"); } } vector *last_commands_vector = new(vector); last_commands_vector->resize(last_commands->length()); for (unsigned int i=0; ilength(); i++) { (*last_commands_vector)[i] = last_commands[i]; } return(last_commands_vector); } //----------------------------------------------------------------------------- // // DeviceProxy::info() - return information about this device // //----------------------------------------------------------------------------- DeviceInfo const &DeviceProxy::info() { DevInfo_var dev_info; DevInfo_3_var dev_info_3; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); if (version >= 3) { Device_3_var dev = Device_3::_duplicate(device_3); dev_info_3 = dev->info_3(); _info.dev_class = dev_info_3->dev_class; _info.server_id = dev_info_3->server_id; _info.server_host = dev_info_3->server_host; _info.server_version = dev_info_3->server_version; _info.doc_url = dev_info_3->doc_url; _info.dev_type = dev_info_3->dev_type; } else { Device_var dev = Device::_duplicate(device); dev_info = dev->info(); _info.dev_class = dev_info->dev_class; _info.server_id = dev_info->server_id; _info.server_host = dev_info->server_host; _info.server_version = dev_info->server_version; _info.doc_url = dev_info->doc_url; _info.dev_type = NotSet; } ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","info",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","info",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute info() on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::info()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","info",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute info() on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::info()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute info() on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::info()"); } } return(_info); } //----------------------------------------------------------------------------- // // DeviceProxy::command_query() - return the description for the specified // command implemented for this TANGO device // //----------------------------------------------------------------------------- CommandInfo DeviceProxy::command_query(string cmd) { CommandInfo command_info; DevCmdInfo_var cmd_info; DevCmdInfo_2_var cmd_info_2; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); if (version == 1) { Device_var dev = Device::_duplicate(device); cmd_info = dev->command_query(cmd.c_str()); command_info.cmd_name = cmd_info->cmd_name; command_info.cmd_tag = cmd_info->cmd_tag; command_info.in_type = cmd_info->in_type; command_info.out_type = cmd_info->out_type; command_info.in_type_desc = cmd_info->in_type_desc; command_info.out_type_desc = cmd_info->out_type_desc; command_info.disp_level = Tango::OPERATOR; } else { Device_2_var dev = Device_2::_duplicate(device_2); cmd_info_2 = dev->command_query_2(cmd.c_str()); command_info.cmd_name = cmd_info_2->cmd_name; command_info.cmd_tag = cmd_info_2->cmd_tag; command_info.in_type = cmd_info_2->in_type; command_info.out_type = cmd_info_2->out_type; command_info.in_type_desc = cmd_info_2->in_type_desc; command_info.out_type_desc = cmd_info_2->out_type_desc; command_info.disp_level = cmd_info_2->level; } ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","command_query",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","command_query",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_query()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","command_query",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_query()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_query()"); } } return(command_info); } //----------------------------------------------------------------------------- // // DeviceProxy::get_command_config() - return the command info for a set of commands // //----------------------------------------------------------------------------- CommandInfoList *DeviceProxy::get_command_config(vector &cmd_names) { CommandInfoList *all_cmds = command_list_query(); // // Leave method if the user requires config for all commands // if (cmd_names.size() == 1 && cmd_names[0] == AllCmd) return all_cmds; // // Return only the required commands config // CommandInfoList *ret_cmds = new CommandInfoList; vector::iterator ite; for (ite = cmd_names.begin();ite != cmd_names.end();++ite) { string w_str(*ite); transform(w_str.begin(),w_str.end(),w_str.begin(),::tolower); vector::iterator pos; for (pos = all_cmds->begin();pos != all_cmds->end();++pos) { string lower_cmd(pos->cmd_name); transform(lower_cmd.begin(),lower_cmd.end(),lower_cmd.begin(),::tolower); if (w_str == lower_cmd) { ret_cmds->push_back(*pos); break; } } } delete all_cmds; return ret_cmds; } //----------------------------------------------------------------------------- // // DeviceProxy::command_list_query() - return the list of commands implemented for this TANGO device // //----------------------------------------------------------------------------- CommandInfoList *DeviceProxy::command_list_query() { CommandInfoList *command_info_list = NULL; DevCmdInfoList_var cmd_info_list; DevCmdInfoList_2_var cmd_info_list_2; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); if (version == 1) { Device_var dev = Device::_duplicate(device); cmd_info_list = dev->command_list_query(); command_info_list = new CommandInfoList(cmd_info_list->length()); // command_info_list->resize(cmd_info_list->length()); for (unsigned int i=0; i < cmd_info_list->length(); i++) { (*command_info_list)[i].cmd_name = cmd_info_list[i].cmd_name; (*command_info_list)[i].cmd_tag = cmd_info_list[i].cmd_tag; (*command_info_list)[i].in_type = cmd_info_list[i].in_type; (*command_info_list)[i].out_type = cmd_info_list[i].out_type; (*command_info_list)[i].in_type_desc = cmd_info_list[i].in_type_desc; (*command_info_list)[i].out_type_desc = cmd_info_list[i].out_type_desc; (*command_info_list)[i].disp_level = Tango::OPERATOR; } } else { Device_2_var dev = Device_2::_duplicate(device_2); cmd_info_list_2 = dev->command_list_query_2(); command_info_list = new CommandInfoList(cmd_info_list_2->length()); // command_info_list->resize(cmd_info_list_2->length()); for (unsigned int i=0; i < cmd_info_list_2->length(); i++) { (*command_info_list)[i].cmd_name = cmd_info_list_2[i].cmd_name; (*command_info_list)[i].cmd_tag = cmd_info_list_2[i].cmd_tag; (*command_info_list)[i].in_type = cmd_info_list_2[i].in_type; (*command_info_list)[i].out_type = cmd_info_list_2[i].out_type; (*command_info_list)[i].in_type_desc = cmd_info_list_2[i].in_type_desc; (*command_info_list)[i].out_type_desc = cmd_info_list_2[i].out_type_desc; (*command_info_list)[i].disp_level = cmd_info_list_2[i].level; } } ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","command_list_query",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","command_list_query",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_list_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_list_query()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","command_list_query",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_list_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_list_query()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute command_list_query on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_list_query()"); } } return(command_info_list); } //----------------------------------------------------------------------------- // // DeviceProxy::get_command_list() - return the list of commands implemented for this TANGO device (only names) // //----------------------------------------------------------------------------- vector *DeviceProxy::get_command_list() { CommandInfoList *all_cmd_config; all_cmd_config = command_list_query(); vector *cmd_list = new vector; cmd_list->resize(all_cmd_config->size()); for (unsigned int i=0; isize(); i++) { (*cmd_list)[i] = (*all_cmd_config)[i].cmd_name; } delete all_cmd_config; return cmd_list; } //----------------------------------------------------------------------------- // // DeviceProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::get_property(string &property_name, DbData &db_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::get_property"); } else { db_data.resize(1); db_data[0] = DbDatum(property_name); db_dev->get_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::get_property(vector &property_names, DbData &db_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::get_property"); } else { db_data.resize(property_names.size()); for (unsigned int i=0; iget_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::get_property(DbData &db_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::get_property"); } else { db_dev->get_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::put_property() - put a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::put_property(DbData &db_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::put_property"); } else { db_dev->put_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::delete_property(string &property_name) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::delete_property"); } else { DbData db_data; db_data.push_back(DbDatum(property_name)); db_dev->delete_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::delete_property(vector &property_names) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::delete_property"); } else { DbData db_data; for (unsigned int i=0; idelete_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void DeviceProxy::delete_property(DbData &db_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::delete_property"); } else { db_dev->delete_property(db_data); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_property_list() - get a list of property names from the database // //----------------------------------------------------------------------------- void DeviceProxy::get_property_list(const string &wildcard,vector &prop_list) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::get_property_list"); } else { int num = 0; num = count(wildcard.begin(),wildcard.end(),'*'); if (num > 1) { ApiWrongNameExcept::throw_exception((const char*)"API_WrongWildcardUsage", (const char *)"Only one wildcard character (*) allowed!", (const char *)"DeviceProxy::get_property_list"); } db_dev->get_property_list(wildcard,prop_list); } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_attribute_config() - return a list of attributes // //----------------------------------------------------------------------------- AttributeInfoList *DeviceProxy::get_attribute_config(vector& attr_string_list) { AttributeConfigList_var attr_config_list; AttributeConfigList_2_var attr_config_list_2; AttributeInfoList *dev_attr_config = new AttributeInfoList(); DevVarStringArray attr_list; int ctr = 0; attr_list.length(attr_string_list.size()); for (unsigned int i=0; i= 3) attr_list[i] = string_dup(AllAttr_3); else attr_list[i] = string_dup(AllAttr); } else if (attr_string_list[i] == AllAttr_3) { if (version < 3) attr_list[i] = string_dup(AllAttr); else attr_list[i] = string_dup(AllAttr_3); } else attr_list[i] = string_dup(attr_string_list[i].c_str()); } while (ctr < 2) { try { check_and_reconnect(); if (version == 1) { Device_var dev = Device::_duplicate(device); attr_config_list = dev->get_attribute_config(attr_list); dev_attr_config->resize(attr_config_list->length()); for (unsigned int i=0; ilength(); i++) { (*dev_attr_config)[i].name = attr_config_list[i].name; (*dev_attr_config)[i].writable = attr_config_list[i].writable; (*dev_attr_config)[i].data_format = attr_config_list[i].data_format; (*dev_attr_config)[i].data_type = attr_config_list[i].data_type; (*dev_attr_config)[i].max_dim_x = attr_config_list[i].max_dim_x; (*dev_attr_config)[i].max_dim_y = attr_config_list[i].max_dim_y; (*dev_attr_config)[i].description = attr_config_list[i].description; (*dev_attr_config)[i].label = attr_config_list[i].label; (*dev_attr_config)[i].unit = attr_config_list[i].unit; (*dev_attr_config)[i].standard_unit = attr_config_list[i].standard_unit; (*dev_attr_config)[i].display_unit = attr_config_list[i].display_unit; (*dev_attr_config)[i].format = attr_config_list[i].format; (*dev_attr_config)[i].min_value = attr_config_list[i].min_value; (*dev_attr_config)[i].max_value = attr_config_list[i].max_value; (*dev_attr_config)[i].min_alarm = attr_config_list[i].min_alarm; (*dev_attr_config)[i].max_alarm = attr_config_list[i].max_alarm; (*dev_attr_config)[i].writable_attr_name = attr_config_list[i].writable_attr_name; (*dev_attr_config)[i].extensions.resize(attr_config_list[i].extensions.length()); for (unsigned int j=0; jget_attribute_config_2(attr_list); dev_attr_config->resize(attr_config_list_2->length()); for (unsigned int i=0; ilength(); i++) { (*dev_attr_config)[i].name = attr_config_list_2[i].name; (*dev_attr_config)[i].writable = attr_config_list_2[i].writable; (*dev_attr_config)[i].data_format = attr_config_list_2[i].data_format; (*dev_attr_config)[i].data_type = attr_config_list_2[i].data_type; (*dev_attr_config)[i].max_dim_x = attr_config_list_2[i].max_dim_x; (*dev_attr_config)[i].max_dim_y = attr_config_list_2[i].max_dim_y; (*dev_attr_config)[i].description = attr_config_list_2[i].description; (*dev_attr_config)[i].label = attr_config_list_2[i].label; (*dev_attr_config)[i].unit = attr_config_list_2[i].unit; (*dev_attr_config)[i].standard_unit = attr_config_list_2[i].standard_unit; (*dev_attr_config)[i].display_unit = attr_config_list_2[i].display_unit; (*dev_attr_config)[i].format = attr_config_list_2[i].format; (*dev_attr_config)[i].min_value = attr_config_list_2[i].min_value; (*dev_attr_config)[i].max_value = attr_config_list_2[i].max_value; (*dev_attr_config)[i].min_alarm = attr_config_list_2[i].min_alarm; (*dev_attr_config)[i].max_alarm = attr_config_list_2[i].max_alarm; (*dev_attr_config)[i].writable_attr_name = attr_config_list_2[i].writable_attr_name; (*dev_attr_config)[i].extensions.resize(attr_config_list_2[i].extensions.length()); for (unsigned int j=0; j& attr_string_list) { AttributeConfigList_var attr_config_list; AttributeConfigList_2_var attr_config_list_2; AttributeConfigList_3_var attr_config_list_3; AttributeConfigList_5_var attr_config_list_5; AttributeInfoListEx *dev_attr_config = new AttributeInfoListEx(); DevVarStringArray attr_list; int ctr = 0; attr_list.length(attr_string_list.size()); for (unsigned int i=0; i= 3) attr_list[i] = string_dup(AllAttr_3); else attr_list[i] = string_dup(AllAttr); } else if (attr_string_list[i] == AllAttr_3) { if (version < 3) attr_list[i] = string_dup(AllAttr); else attr_list[i] = string_dup(AllAttr_3); } else attr_list[i] = string_dup(attr_string_list[i].c_str()); } while (ctr < 2) { try { check_and_reconnect(); switch (version) { case 1: { Device_var dev = Device::_duplicate(device); attr_config_list = dev->get_attribute_config(attr_list); dev_attr_config->resize(attr_config_list->length()); for (size_t i=0; ilength(); i++) { COPY_BASE_CONFIG((*dev_attr_config),attr_config_list) (*dev_attr_config)[i].min_alarm = attr_config_list[i].min_alarm; (*dev_attr_config)[i].max_alarm = attr_config_list[i].max_alarm; (*dev_attr_config)[i].disp_level = Tango::OPERATOR; } } break; case 2: { Device_2_var dev = Device_2::_duplicate(device_2); attr_config_list_2 = dev->get_attribute_config_2(attr_list); dev_attr_config->resize(attr_config_list_2->length()); for (size_t i=0; ilength(); i++) { COPY_BASE_CONFIG((*dev_attr_config),attr_config_list_2) (*dev_attr_config)[i].min_alarm = attr_config_list_2[i].min_alarm; (*dev_attr_config)[i].max_alarm = attr_config_list_2[i].max_alarm; (*dev_attr_config)[i].disp_level = attr_config_list_2[i].level; } get_remaining_param(dev_attr_config); } break; case 3: case 4: { Device_3_var dev = Device_3::_duplicate(device_3); attr_config_list_3 = dev->get_attribute_config_3(attr_list); dev_attr_config->resize(attr_config_list_3->length()); for (size_t i=0; ilength(); i++) { COPY_BASE_CONFIG((*dev_attr_config),attr_config_list_3) for (size_t j=0; jget_attribute_config_5(attr_list); dev_attr_config->resize(attr_config_list_5->length()); for (size_t i=0; ilength(); i++) { COPY_BASE_CONFIG((*dev_attr_config),attr_config_list_5) for (size_t j=0; jsize();loop++) { (*dev_attr_config)[loop].alarms.min_alarm = (*dev_attr_config)[loop].min_alarm; (*dev_attr_config)[loop].alarms.max_alarm = (*dev_attr_config)[loop].max_alarm; (*dev_attr_config)[loop].alarms.min_warning = AlrmValueNotSpec; (*dev_attr_config)[loop].alarms.max_warning = AlrmValueNotSpec; (*dev_attr_config)[loop].alarms.delta_t = AlrmValueNotSpec; (*dev_attr_config)[loop].alarms.delta_val = AlrmValueNotSpec; (*dev_attr_config)[loop].events.ch_event.abs_change = AlrmValueNotSpec; (*dev_attr_config)[loop].events.ch_event.rel_change = AlrmValueNotSpec; (*dev_attr_config)[loop].events.per_event.period = AlrmValueNotSpec; (*dev_attr_config)[loop].events.arch_event.archive_abs_change = AlrmValueNotSpec; (*dev_attr_config)[loop].events.arch_event.archive_rel_change = AlrmValueNotSpec; (*dev_attr_config)[loop].events.arch_event.archive_period = AlrmValueNotSpec; } // // If device does not use db, simply retruns // if (dbase_used == false) { return; } else { // // First get device class (if not already done) // if (_info.dev_class.empty() == true) { this->info(); } // // Get class attribute properties // DbData db_data_class, db_data_device; unsigned int i,k; int j; for (i = 0;i < dev_attr_config->size();i++) { db_data_class.push_back(DbDatum((*dev_attr_config)[i].name)); db_data_device.push_back(DbDatum((*dev_attr_config)[i].name)); } db_dev->get_dbase()->get_class_attribute_property(_info.dev_class,db_data_class); // // Now get device attribute properties // db_dev->get_attribute_property(db_data_device); // // Init remaining parameters from them retrieve at class level // for (i = 0;i < db_data_class.size();i++) { long nb_prop; string &att_name = db_data_class[i].name; db_data_class[i] >> nb_prop; i++; for (j = 0;j < nb_prop;j++) { // // Extract prop value // string prop_value; string &prop_name = db_data_class[i].name; if (db_data_class[i].size() != 1) { vector tmp; db_data_class[i] >> tmp; prop_value = tmp[0] + ", " + tmp[1]; } else db_data_class[i] >> prop_value; i++; // // Store prop value in attribute config vector // for (k = 0;k < dev_attr_config->size();k++) { if ((*dev_attr_config)[k].name == att_name) { if (prop_name == "min_warning") (*dev_attr_config)[k].alarms.min_warning = prop_value; else if (prop_name == "max_warning") (*dev_attr_config)[k].alarms.max_warning = prop_value; else if (prop_name == "delta_t") (*dev_attr_config)[k].alarms.delta_t = prop_value; else if (prop_name == "delta_val") (*dev_attr_config)[k].alarms.delta_val = prop_value; else if (prop_name == "abs_change") (*dev_attr_config)[k].events.ch_event.abs_change = prop_value; else if (prop_name == "rel_change") (*dev_attr_config)[k].events.ch_event.rel_change = prop_value; else if (prop_name == "period") (*dev_attr_config)[k].events.per_event.period = prop_value; else if (prop_name == "archive_abs_change") (*dev_attr_config)[k].events.arch_event.archive_abs_change = prop_value; else if (prop_name == "archive_rel_change") (*dev_attr_config)[k].events.arch_event.archive_rel_change = prop_value; else if (prop_name == "archive_period") (*dev_attr_config)[k].events.arch_event.archive_period = prop_value; } } } } // // Init remaining parameters from them retrieve at device level // for (i = 0;i < db_data_device.size();i++) { long nb_prop; string &att_name = db_data_device[i].name; db_data_device[i] >> nb_prop; i++; for (j = 0;j < nb_prop;j++) { // // Extract prop value // string prop_value; string &prop_name = db_data_device[i].name; if (db_data_device[i].size() != 1) { vector tmp; db_data_device[i] >> tmp; prop_value = tmp[0] + ", " + tmp[1]; } else db_data_device[i] >> prop_value; i++; // // Store prop value in attribute config vector // for (k = 0;k < dev_attr_config->size();k++) { if ((*dev_attr_config)[k].name == att_name) { if (prop_name == "min_warning") (*dev_attr_config)[k].alarms.min_warning = prop_value; else if (prop_name == "max_warning") (*dev_attr_config)[k].alarms.max_warning = prop_value; else if (prop_name == "delta_t") (*dev_attr_config)[k].alarms.delta_t = prop_value; else if (prop_name == "delta_val") (*dev_attr_config)[k].alarms.delta_val = prop_value; else if (prop_name == "abs_change") (*dev_attr_config)[k].events.ch_event.abs_change = prop_value; else if (prop_name == "rel_change") (*dev_attr_config)[k].events.ch_event.rel_change = prop_value; else if (prop_name == "period") (*dev_attr_config)[k].events.per_event.period = prop_value; else if (prop_name == "archive_abs_change") (*dev_attr_config)[k].events.arch_event.archive_abs_change = prop_value; else if (prop_name == "archive_rel_change") (*dev_attr_config)[k].events.arch_event.archive_rel_change = prop_value; else if (prop_name == "archive_period") (*dev_attr_config)[k].events.arch_event.archive_period = prop_value; } } } } } } //----------------------------------------------------------------------------- // // DeviceProxy::get_attribute_config() - return a single attribute config // //----------------------------------------------------------------------------- AttributeInfoEx DeviceProxy::get_attribute_config(const string& attr_string) { vector attr_string_list; AttributeInfoListEx *dev_attr_config_list; AttributeInfoEx dev_attr_config; attr_string_list.push_back(attr_string); dev_attr_config_list = get_attribute_config_ex(attr_string_list); dev_attr_config = (*dev_attr_config_list)[0]; delete(dev_attr_config_list); return(dev_attr_config); } //----------------------------------------------------------------------------- // // DeviceProxy::set_attribute_config() - set config for a list of attributes // //----------------------------------------------------------------------------- void DeviceProxy::set_attribute_config(AttributeInfoList &dev_attr_list) { AttributeConfigList attr_config_list; DevVarStringArray attr_list; int ctr = 0; attr_config_list.length(dev_attr_list.size()); for (unsigned int i=0; iset_attribute_config(attr_config_list); ctr = 2; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) { TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } else throw; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","set_attribute_config",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","set_attribute_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","set_attribute_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } return; } void DeviceProxy::set_attribute_config(AttributeInfoListEx &dev_attr_list) { AttributeConfigList attr_config_list; AttributeConfigList_3 attr_config_list_3; AttributeConfigList_5 attr_config_list_5; DevVarStringArray attr_list; int ctr = 0; unsigned int i,j; if (version >= 5) { attr_config_list_5.length(dev_attr_list.size()); for (i=0; i= 3) { attr_config_list_3.length(dev_attr_list.size()); for (i=0; i= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); if (version == 5) { Device_5_var dev = Device_5::_duplicate(device_5); dev->set_attribute_config_5(attr_config_list_5,ci); } else { Device_4_var dev = Device_4::_duplicate(device_4); dev->set_attribute_config_4(attr_config_list_3,ci); } } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); dev->set_attribute_config_3(attr_config_list_3); } else { Device_var dev = Device::_duplicate(device); device->set_attribute_config(attr_config_list); } ctr = 2; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) { TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } else throw; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","set_attribute_config",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","set_attribute_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","set_attribute_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_attribute_config()"); } } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_pipe_config() - return a list of pipe config // //----------------------------------------------------------------------------- PipeInfoList *DeviceProxy::get_pipe_config(vector& pipe_string_list) { PipeConfigList_var pipe_config_list_5; PipeInfoList *dev_pipe_config = new PipeInfoList(); DevVarStringArray pipe_list; int ctr = 0; // // Error if device does not support IDL 5 // if (version > 0 && version < 5) { stringstream ss; ss << "Device " << device_name << " too old to use get_pipe_config() call. Please upgrade to Tango 9/IDL5"; ApiNonSuppExcept::throw_exception(API_UnsupportedFeature, ss.str(),"DeviceProxy::get_pipe_config()"); } // // Prepare sent parameters // pipe_list.length(pipe_string_list.size()); for (unsigned int i=0; iget_pipe_config_5(pipe_list); dev_pipe_config->resize(pipe_config_list_5->length()); for (size_t i=0; ilength(); i++) { (*dev_pipe_config)[i].disp_level = pipe_config_list_5[i].level; (*dev_pipe_config)[i].name = pipe_config_list_5[i].name; (*dev_pipe_config)[i].description = pipe_config_list_5[i].description; (*dev_pipe_config)[i].label = pipe_config_list_5[i].label; (*dev_pipe_config)[i].writable = pipe_config_list_5[i].writable; for (size_t j=0; j pipe_string_list; PipeInfoList *dev_pipe_config_list; PipeInfo dev_pipe_config; pipe_string_list.push_back(pipe_name); dev_pipe_config_list = get_pipe_config(pipe_string_list); dev_pipe_config = (*dev_pipe_config_list)[0]; delete(dev_pipe_config_list); return(dev_pipe_config); } //----------------------------------------------------------------------------- // // DeviceProxy::set_pipe_config() - set config for a list of pipes // //----------------------------------------------------------------------------- void DeviceProxy::set_pipe_config(PipeInfoList &dev_pipe_list) { // // Error if device does not support IDL 5 // if (version > 0 && version < 5) { stringstream ss; ss << "Device " << device_name << " too old to use set_pipe_config() call. Please upgrade to Tango 9/IDL5"; ApiNonSuppExcept::throw_exception(API_UnsupportedFeature,ss.str(),"DeviceProxy::set_pipe_config()"); } PipeConfigList pipe_config_list; int ctr = 0; pipe_config_list.length(dev_pipe_list.size()); for (unsigned int i=0; iget_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); dev->set_pipe_config_5(pipe_config_list,ci); ctr = 2; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) { TangoSys_OMemStream desc; desc << "Failed to execute set_pipe_config on device " << device_name << ends; DeviceUnlockedExcept::re_throw_exception(e,DEVICE_UNLOCKED_REASON, desc.str(), "DeviceProxy::set_pipe_config()"); } else throw; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","set_pipe_config",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","set_pipe_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_pipe_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_pipe_config()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","set_pipe_config",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_pipe_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_pipe_config()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute set_pipe_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::set_pipe_config()"); } } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_pipe_list() - get list of pipes // //----------------------------------------------------------------------------- vector *DeviceProxy::get_pipe_list() { vector all_pipe; PipeInfoList *all_pipe_config; all_pipe.push_back(AllPipe); all_pipe_config = get_pipe_config(all_pipe); vector *pipe_list = new vector; pipe_list->resize(all_pipe_config->size()); for (unsigned int i=0; isize(); i++) { (*pipe_list)[i] = (*all_pipe_config)[i].name; } delete all_pipe_config; return pipe_list; } //----------------------------------------------------------------------------- // // DeviceProxy::read_pipe() - read a single pipe // //----------------------------------------------------------------------------- DevicePipe DeviceProxy::read_pipe(const string& pipe_name) { DevPipeData_var pipe_value_5; DevicePipe dev_pipe; int ctr = 0; // // Error if device does not support IDL 5 // if (version > 0 && version < 5) { stringstream ss; ss << "Device " << device_name << " too old to use read_pipe() call. Please upgrade to Tango 9/IDL5"; ApiNonSuppExcept::throw_exception(API_UnsupportedFeature,ss.str(),"DeviceProxy::read_pipe()"); } while (ctr < 2) { try { check_and_reconnect(); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); pipe_value_5 = dev->read_pipe_5(pipe_name.c_str(),ci); ctr = 2; } catch (Tango::ConnectionFailed &e) { stringstream desc; desc << "Failed to read_pipe on device " << device_name << ", pipe " << pipe_name; ApiConnExcept::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::read_pipe()"); } catch (Tango::DevFailed &e) { stringstream desc; desc << "Failed to read_pipe on device " << device_name << ", pipe " << pipe_name; Except::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::read_pipe()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","read_pipe",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","read_pipe",this); } else { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(one,"API_CommunicationFailed",desc.str(),"DeviceProxy::read_pipe()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","read_pipe",this); } else { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(comm,"API_CommunicationFailed",desc.str(),"DeviceProxy::read_pipe()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(ce,"API_CommunicationFailed",desc.str(),"DeviceProxy::read_pipe()"); } } // // Pass received data to the caller. // For thw data elt sequence, we create a new one with size and buffer from the original one. // This is required because the whole object received by the call will be deleted at the end of this method // dev_pipe.set_name(pipe_value_5->name.in()); dev_pipe.set_time(pipe_value_5->time); CORBA::ULong max,len; max = pipe_value_5->data_blob.blob_data.maximum(); len = pipe_value_5->data_blob.blob_data.length(); DevPipeDataElt *buf = pipe_value_5->data_blob.blob_data.get_buffer((CORBA::Boolean)true); DevVarPipeDataEltArray *dvpdea = new DevVarPipeDataEltArray(max,len,buf,true); dev_pipe.get_root_blob().reset_extract_ctr(); dev_pipe.get_root_blob().reset_insert_ctr(); dev_pipe.get_root_blob().set_name(pipe_value_5->data_blob.name.in()); delete dev_pipe.get_root_blob().get_extract_data(); dev_pipe.get_root_blob().set_extract_data(dvpdea); dev_pipe.get_root_blob().set_extract_delete(true); return dev_pipe; } //----------------------------------------------------------------------------- // // DeviceProxy::write_pipe() - write a single pipe // //----------------------------------------------------------------------------- void DeviceProxy::write_pipe(DevicePipe& dev_pipe) { DevPipeData pipe_value_5; int ctr = 0; // // Error if device does not support IDL 5 // if (version > 0 && version < 5) { stringstream ss; ss << "Device " << device_name << " too old to use write_pipe() call. Please upgrade to Tango 9/IDL5"; ApiNonSuppExcept::throw_exception(API_UnsupportedFeature,ss.str(),"DeviceProxy::write_pipe()"); } // // Prepare data sent to device // pipe_value_5.name = dev_pipe.get_name().c_str(); const string &bl_name = dev_pipe.get_root_blob().get_name(); if (bl_name.size() != 0) pipe_value_5.data_blob.name = bl_name.c_str(); DevVarPipeDataEltArray *tmp_ptr = dev_pipe.get_root_blob().get_insert_data(); if (tmp_ptr == Tango_nullptr) { Except::throw_exception(API_PipeNoDataElement,"No data in pipe!","DeviceProxy::write_pipe()"); } CORBA::ULong max,len; max = tmp_ptr->maximum(); len = tmp_ptr->length(); pipe_value_5.data_blob.blob_data.replace(max,len,tmp_ptr->get_buffer((CORBA::Boolean)true),true); while (ctr < 2) { try { check_and_reconnect(); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); dev->write_pipe_5(pipe_value_5,ci); ctr = 2; } catch (Tango::ConnectionFailed &e) { dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; stringstream desc; desc << "Failed to write_pipe on device " << device_name << ", pipe " << dev_pipe.get_name(); ApiConnExcept::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::write_pipe()"); } catch (Tango::DevFailed &e) { dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; stringstream desc; desc << "Failed to write_pipe on device " << device_name << ", pipe " << dev_pipe.get_name(); Except::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::write_pipe()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_pipe",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_pipe",this); } else { dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_pipe on device " << device_name; ApiCommExcept::re_throw_exception(one,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_pipe()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_pipe",this); } else { dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_pipe on device " << device_name; ApiCommExcept::re_throw_exception(comm,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_pipe()"); } } catch (CORBA::SystemException &ce) { dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_pipe on device " << device_name; ApiCommExcept::re_throw_exception(ce,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_pipe()"); } } dev_pipe.get_root_blob().reset_insert_ctr(); delete tmp_ptr; } //----------------------------------------------------------------------------- // // DeviceProxy::write_read_pipe() - write then read a single pipe // //----------------------------------------------------------------------------- DevicePipe DeviceProxy::write_read_pipe(DevicePipe &pipe_data) { DevPipeData pipe_value_5; DevPipeData_var r_pipe_value_5; DevicePipe r_dev_pipe; int ctr = 0; // // Error if device does not support IDL 5 // if (version > 0 && version < 5) { stringstream ss; ss << "Device " << device_name << " too old to use write_read_pipe() call. Please upgrade to Tango 9/IDL5"; ApiNonSuppExcept::throw_exception(API_UnsupportedFeature,ss.str(),"DeviceProxy::write_read_pipe()"); } // // Prepare data sent to device // pipe_value_5.name = pipe_data.get_name().c_str(); const string &bl_name = pipe_data.get_root_blob().get_name(); if (bl_name.size() != 0) pipe_value_5.data_blob.name = bl_name.c_str(); DevVarPipeDataEltArray *tmp_ptr = pipe_data.get_root_blob().get_insert_data(); CORBA::ULong max,len; max = tmp_ptr->maximum(); len = tmp_ptr->length(); pipe_value_5.data_blob.blob_data.replace(max,len,tmp_ptr->get_buffer((CORBA::Boolean)true),true); delete tmp_ptr; while (ctr < 2) { try { check_and_reconnect(); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); r_pipe_value_5 = dev->write_read_pipe_5(pipe_value_5,ci); ctr = 2; } catch (Tango::ConnectionFailed &e) { stringstream desc; desc << "Failed to write_read_pipe on device " << device_name << ", pipe " << pipe_data.get_name(); ApiConnExcept::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::write_read_pipe()"); } catch (Tango::DevFailed &e) { stringstream desc; desc << "Failed to write_pipe on device " << device_name << ", pipe " << pipe_data.get_name(); Except::re_throw_exception(e,API_PipeFailed,desc.str(),"DeviceProxy::write_read_pipe()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_read_pipe",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_read_pipe",this); } else { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(one,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_read_pipe()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_read_pipe",this); } else { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(comm,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_read_pipe()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); stringstream desc; desc << "Failed to write_read_pipe on device " << device_name; ApiCommExcept::re_throw_exception(ce,"API_CommunicationFailed",desc.str(),"DeviceProxy::write_read_pipe()"); } } // // Pass received data to the caller. // For thw data elt sequence, we create a new one with size and buffer from the original one. // This is required because the whole object received by the call will be deleted at the end of this method // r_dev_pipe.set_name(r_pipe_value_5->name.in()); r_dev_pipe.set_time(r_pipe_value_5->time); max = r_pipe_value_5->data_blob.blob_data.maximum(); len = r_pipe_value_5->data_blob.blob_data.length(); DevPipeDataElt *buf = r_pipe_value_5->data_blob.blob_data.get_buffer((CORBA::Boolean)true); DevVarPipeDataEltArray *dvpdea = new DevVarPipeDataEltArray(max,len,buf,true); r_dev_pipe.get_root_blob().reset_extract_ctr(); r_dev_pipe.get_root_blob().reset_insert_ctr(); r_dev_pipe.get_root_blob().set_name(r_pipe_value_5->data_blob.name.in()); r_dev_pipe.get_root_blob().set_extract_data(dvpdea); r_dev_pipe.get_root_blob().set_extract_delete(true); return r_dev_pipe; } //----------------------------------------------------------------------------- // // DeviceProxy::read_attributes() - Read attributes // //----------------------------------------------------------------------------- vector *DeviceProxy::read_attributes(vector& attr_string_list) { AttributeValueList_var attr_value_list; AttributeValueList_3_var attr_value_list_3; AttributeValueList_4_var attr_value_list_4; AttributeValueList_5_var attr_value_list_5; DevVarStringArray attr_list; // // Check that the caller did not give two times the same attribute // same_att_name(attr_string_list,"Deviceproxy::read_attributes()"); unsigned long i; attr_list.length(attr_string_list.size()); for (i = 0;i < attr_string_list.size();i++) { attr_list[i] = string_dup(attr_string_list[i].c_str()); } int ctr = 0; Tango::DevSource local_source; while (ctr < 2) { try { check_and_reconnect(local_source); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); if (version == 5) { Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->read_attributes_5(attr_list,local_source,ci); } else if (version == 4) { Device_4_var dev = Device_4::_duplicate(device_4); attr_value_list_4 = dev->read_attributes_4(attr_list,local_source,ci); } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); attr_value_list_3 = dev->read_attributes_3(attr_list,local_source); } else if (version == 2) { Device_2_var dev = Device_2::_duplicate(device_2); attr_value_list = dev->read_attributes_2(attr_list,local_source); } else { Device_var dev = Device::_duplicate(device); attr_value_list = dev->read_attributes(attr_list); } ctr = 2; } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attributes "; int nb_attr = attr_string_list.size(); for (int i = 0;i < nb_attr;i++) { desc << attr_string_list[i]; if (i != nb_attr - 1) desc << ", "; } desc << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::read_attributes()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attributes "; int nb_attr = attr_string_list.size(); for (int i = 0;i < nb_attr;i++) { desc << attr_string_list[i]; if (i != nb_attr - 1) desc << ", "; } desc << ends; Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::read_attributes()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","read_attributes",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","read_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute read_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::read_attributes()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","read_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute read_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::read_attributes()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute read_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::read_attributes()"); } } unsigned long nb_received; if (version >= 5) nb_received = attr_value_list_5->length(); else if (version == 4) nb_received = attr_value_list_4->length(); else if (version == 3) nb_received = attr_value_list_3->length(); else nb_received = attr_value_list->length(); vector *dev_attr = new(vector); dev_attr->resize(nb_received); for (i=0; i < nb_received; i++) { if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&(attr_value_list_5[i]),version,&(*dev_attr)[i]); else if (version == 4) ApiUtil::attr_to_device(&(attr_value_list_4[i]),version,&(*dev_attr)[i]); else ApiUtil::attr_to_device(NULL,&(attr_value_list_3[i]),version,&(*dev_attr)[i]); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = (*dev_attr)[i].get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attribute " << (*dev_attr)[i].name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attributes()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&(attr_value_list[i]),NULL,version,&(*dev_attr)[i]); } } return(dev_attr); } //----------------------------------------------------------------------------- // // DeviceProxy::read_attribute() - return a single attribute // //----------------------------------------------------------------------------- DeviceAttribute DeviceProxy::read_attribute(string& attr_string) { AttributeValueList_var attr_value_list; AttributeValueList_3_var attr_value_list_3; AttributeValueList_4_var attr_value_list_4; AttributeValueList_5_var attr_value_list_5; DeviceAttribute dev_attr; DevVarStringArray attr_list; int ctr = 0; Tango::DevSource local_source; attr_list.length(1); attr_list[0] = CORBA::string_dup(attr_string.c_str()); while (ctr < 2) { try { check_and_reconnect(local_source); if (version >= 5) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->read_attributes_5(attr_list,local_source,ci); } else if (version == 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); attr_value_list_4 = dev->read_attributes_4(attr_list,local_source,ci); } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); attr_value_list_3 = dev->read_attributes_3(attr_list,local_source); } else if (version == 2) { Device_2_var dev = Device_2::_duplicate(device_2); attr_value_list = dev->read_attributes_2(attr_list,local_source); } else { Device_var dev = Device::_duplicate(device); attr_value_list = dev->read_attributes(attr_list); } ctr = 2; } READ_ATT_EXCEPT(attr_string,this) } if (version >= 3) { if (version >= 5) ApiUtil::attr_to_device(&(attr_value_list_5[0]),version,&dev_attr); else if (version == 4) ApiUtil::attr_to_device(&(attr_value_list_4[0]),version,&dev_attr); else ApiUtil::attr_to_device(NULL,&(attr_value_list_3[0]),version,&dev_attr); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = dev_attr.get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attribute on device " << device_name; desc << ", attribute " << dev_attr.name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&(attr_value_list[0]),NULL,version,&dev_attr); } return(dev_attr); } void DeviceProxy::read_attribute(const char *attr_str,DeviceAttribute &dev_attr) { AttributeValueList *attr_value_list = NULL; AttributeValueList_3 *attr_value_list_3 = NULL; AttributeValueList_4 *attr_value_list_4 = NULL; AttributeValueList_5 *attr_value_list_5 = NULL; DevVarStringArray attr_list; int ctr = 0; Tango::DevSource local_source; attr_list.length(1); attr_list[0] = CORBA::string_dup(attr_str); while (ctr < 2) { try { check_and_reconnect(local_source); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); if (version >= 5) { Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->read_attributes_5(attr_list,local_source,ci); } else if (version == 4) { Device_4_var dev = Device_4::_duplicate(device_4); attr_value_list_4 = dev->read_attributes_4(attr_list,local_source,ci); } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); attr_value_list_3 = dev->read_attributes_3(attr_list,local_source); } else if (version == 2) { Device_2_var dev = Device_2::_duplicate(device_2); attr_value_list = dev->read_attributes_2(attr_list,local_source); } else { Device_var dev = Device::_duplicate(device); attr_value_list = dev->read_attributes(attr_list); } ctr = 2; } READ_ATT_EXCEPT(attr_str,this) } if (version >= 3) { if (version >= 5) { ApiUtil::attr_to_device(&((*attr_value_list_5)[0]),version,&dev_attr); delete attr_value_list_5; } else if (version == 4) { ApiUtil::attr_to_device(&((*attr_value_list_4)[0]),version,&dev_attr); delete attr_value_list_4; } else { ApiUtil::attr_to_device(NULL,&((*attr_value_list_3)[0]),version,&dev_attr); delete attr_value_list_3; } // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = dev_attr.get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attribute on device " << device_name; desc << ", attribute " << dev_attr.name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*attr_value_list)[0]),NULL,version,&dev_attr); delete attr_value_list; } } void DeviceProxy::read_attribute(const string &attr_str,AttributeValue_4 *&av_4) { DevVarStringArray attr_list; int ctr = 0; Tango::DevSource local_source; if (version < 4) { stringstream ss; ss << "Device " << dev_name() << " is too old to support this call. Please, update to IDL 4 (Tango 7.x or more)"; Except::throw_exception(API_NotSupported,ss.str(),"DeviceProxy::read_attribute"); } attr_list.length(1); attr_list[0] = CORBA::string_dup(attr_str.c_str()); while (ctr < 2) { try { check_and_reconnect(local_source); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); AttributeValueList_4 *attr_value_list_4 = dev->read_attributes_4(attr_list,local_source,ci); av_4 = attr_value_list_4->get_buffer(true); delete attr_value_list_4; ctr = 2; } READ_ATT_EXCEPT(attr_str,this) } // // Add an error in the error stack in case there is one // long nb_except = av_4->err_list.length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attribute on device " << device_name; desc << ", attribute " << attr_str << ends; av_4->err_list.length(nb_except + 1); av_4->err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); av_4->err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute()"); string st = desc.str(); av_4->err_list[nb_except].desc = CORBA::string_dup(st.c_str()); av_4->err_list[nb_except].severity = Tango::ERR; } } void DeviceProxy::read_attribute(const string &attr_str,AttributeValue_5 *&av_5) { DevVarStringArray attr_list; int ctr = 0; Tango::DevSource local_source; if (version < 5) { stringstream ss; ss << "Device " << dev_name() << " is too old to support this call. Please, update to IDL 5 (Tango 9.x or more)"; Except::throw_exception(API_NotSupported,ss.str(),"DeviceProxy::read_attribute"); } attr_list.length(1); attr_list[0] = CORBA::string_dup(attr_str.c_str()); while (ctr < 2) { try { check_and_reconnect(local_source); ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); AttributeValueList_5 *attr_value_list_5 = dev->read_attributes_5(attr_list,local_source,ci); av_5 = attr_value_list_5->get_buffer(true); delete attr_value_list_5; ctr = 2; } READ_ATT_EXCEPT(attr_str,this) } // // Add an error in the error stack in case there is one // long nb_except = av_5->err_list.length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attribute on device " << device_name; desc << ", attribute " << attr_str << ends; av_5->err_list.length(nb_except + 1); av_5->err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); av_5->err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute()"); string st = desc.str(); av_5->err_list[nb_except].desc = CORBA::string_dup(st.c_str()); av_5->err_list[nb_except].severity = Tango::ERR; } } //----------------------------------------------------------------------------- // // DeviceProxy::write_attributes() - write a list of attributes // //----------------------------------------------------------------------------- void DeviceProxy::write_attributes(vector& attr_list) { AttributeValueList attr_value_list; AttributeValueList_4 attr_value_list_4; Tango::AccessControlType local_act; if (version == 0) check_and_reconnect(local_act); if (version >= 4) attr_value_list_4.length(attr_list.size()); else attr_value_list.length(attr_list.size()); for (unsigned int i=0; i= 4) { attr_value_list_4[i].name = attr_list[i].name.c_str(); attr_value_list_4[i].quality = attr_list[i].quality; attr_value_list_4[i].data_format = attr_list[i].data_format; attr_value_list_4[i].time = attr_list[i].time; attr_value_list_4[i].w_dim.dim_x = attr_list[i].dim_x; attr_value_list_4[i].w_dim.dim_y = attr_list[i].dim_y; } else { attr_value_list[i].name = attr_list[i].name.c_str(); attr_value_list[i].quality = attr_list[i].quality; attr_value_list[i].time = attr_list[i].time; attr_value_list[i].dim_x = attr_list[i].dim_x; attr_value_list[i].dim_y = attr_list[i].dim_y; } if (attr_list[i].LongSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.long_att_value(attr_list[i].LongSeq.in()); else attr_value_list[i].value <<= attr_list[i].LongSeq.in(); continue; } if (attr_list[i].Long64Seq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.long64_att_value(attr_list[i].Long64Seq.in()); else attr_value_list[i].value <<= attr_list[i].Long64Seq.in(); continue; } if (attr_list[i].ShortSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.short_att_value(attr_list[i].ShortSeq.in()); else attr_value_list[i].value <<= attr_list[i].ShortSeq.in(); continue; } if (attr_list[i].DoubleSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.double_att_value(attr_list[i].DoubleSeq.in()); else attr_value_list[i].value <<= attr_list[i].DoubleSeq.in(); continue; } if (attr_list[i].StringSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.string_att_value(attr_list[i].StringSeq.in()); else attr_value_list[i].value <<= attr_list[i].StringSeq.in(); continue; } if (attr_list[i].FloatSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.float_att_value(attr_list[i].FloatSeq.in()); else attr_value_list[i].value <<= attr_list[i].FloatSeq.in(); continue; } if (attr_list[i].BooleanSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.bool_att_value(attr_list[i].BooleanSeq.in()); else attr_value_list[i].value <<= attr_list[i].BooleanSeq.in(); continue; } if (attr_list[i].UShortSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.ushort_att_value(attr_list[i].UShortSeq.in()); else attr_value_list[i].value <<= attr_list[i].UShortSeq.in(); continue; } if (attr_list[i].UCharSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.uchar_att_value(attr_list[i].UCharSeq.in()); else attr_value_list[i].value <<= attr_list[i].UCharSeq.in(); continue; } if (attr_list[i].ULongSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.ulong_att_value(attr_list[i].ULongSeq.in()); else attr_value_list[i].value <<= attr_list[i].ULongSeq.in(); continue; } if (attr_list[i].ULong64Seq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.ulong64_att_value(attr_list[i].ULong64Seq.in()); else attr_value_list[i].value <<= attr_list[i].ULong64Seq.in(); continue; } if (attr_list[i].StateSeq.operator->() != NULL) { if (version >= 4) attr_value_list_4[i].value.state_att_value(attr_list[i].StateSeq.in()); else attr_value_list[i].value <<= attr_list[i].StateSeq.in(); continue; } } int ctr = 0; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_attributes()"); } // // Now, write the attribute(s) // if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); dev->write_attributes_4(attr_value_list_4,ci); } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); dev->write_attributes_3(attr_value_list); } else { Device_var dev = Device::_duplicate(device); dev->write_attributes(attr_value_list); } ctr = 2; } catch (Tango::MultiDevFailed &e) { throw Tango::NamedDevFailedList(e, device_name, (const char *)"DeviceProxy::write_attributes", (const char *)API_AttributeFailed); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_attributes on device " << device_name; desc << ", attributes "; int nb_attr = attr_value_list.length(); for (int i = 0;i < nb_attr;i++) { desc << attr_value_list[i].name.in(); if (i != nb_attr - 1) desc << ", "; } desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_attribute()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_attributes",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attributes()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attributes()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attributes()"); } } return; } //----------------------------------------------------------------------------- // // DeviceProxy::write_attribute() - write a single attribute // //----------------------------------------------------------------------------- void DeviceProxy::write_attribute(DeviceAttribute &dev_attr) { AttributeValueList attr_value_list; AttributeValueList_4 attr_value_list_4; Tango::AccessControlType local_act; if (version == 0) check_and_reconnect(local_act); if (version >= 4) { attr_value_list_4.length(1); attr_value_list_4[0].name = dev_attr.name.c_str(); attr_value_list_4[0].quality = dev_attr.quality; attr_value_list_4[0].data_format = dev_attr.data_format; attr_value_list_4[0].time = dev_attr.time; attr_value_list_4[0].w_dim.dim_x = dev_attr.dim_x; attr_value_list_4[0].w_dim.dim_y = dev_attr.dim_y; if (dev_attr.LongSeq.operator->() != NULL) attr_value_list_4[0].value.long_att_value(dev_attr.LongSeq.in()); else if (dev_attr.Long64Seq.operator->() != NULL) attr_value_list_4[0].value.long64_att_value(dev_attr.Long64Seq.in()); else if (dev_attr.ShortSeq.operator->() != NULL) attr_value_list_4[0].value.short_att_value(dev_attr.ShortSeq.in()); else if (dev_attr.DoubleSeq.operator->() != NULL) attr_value_list_4[0].value.double_att_value(dev_attr.DoubleSeq.in()); else if (dev_attr.StringSeq.operator->() != NULL) attr_value_list_4[0].value.string_att_value(dev_attr.StringSeq.in()); else if (dev_attr.FloatSeq.operator->() != NULL) attr_value_list_4[0].value.float_att_value(dev_attr.FloatSeq.in()); else if (dev_attr.BooleanSeq.operator->() != NULL) attr_value_list_4[0].value.bool_att_value(dev_attr.BooleanSeq.in()); else if (dev_attr.UShortSeq.operator->() != NULL) attr_value_list_4[0].value.ushort_att_value(dev_attr.UShortSeq.in()); else if (dev_attr.UCharSeq.operator->() != NULL) attr_value_list_4[0].value.uchar_att_value(dev_attr.UCharSeq.in()); else if (dev_attr.ULongSeq.operator->() != NULL) attr_value_list_4[0].value.ulong_att_value(dev_attr.ULongSeq.in()); else if (dev_attr.ULong64Seq.operator->() != NULL) attr_value_list_4[0].value.ulong64_att_value(dev_attr.ULong64Seq.in()); else if (dev_attr.StateSeq.operator->() != NULL) attr_value_list_4[0].value.state_att_value(dev_attr.StateSeq.in()); else if (dev_attr.EncodedSeq.operator->() != NULL) attr_value_list_4[0].value.encoded_att_value(dev_attr.EncodedSeq.in()); } else { attr_value_list.length(1); attr_value_list[0].name = dev_attr.name.c_str(); attr_value_list[0].quality = dev_attr.quality; attr_value_list[0].time = dev_attr.time; attr_value_list[0].dim_x = dev_attr.dim_x; attr_value_list[0].dim_y = dev_attr.dim_y; if (dev_attr.LongSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.LongSeq.in(); else if (dev_attr.Long64Seq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.Long64Seq.in(); else if (dev_attr.ShortSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.ShortSeq.in(); else if (dev_attr.DoubleSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.DoubleSeq.in(); else if (dev_attr.StringSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.StringSeq.in(); else if (dev_attr.FloatSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.FloatSeq.in(); else if (dev_attr.BooleanSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.BooleanSeq.in(); else if (dev_attr.UShortSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.UShortSeq.in(); else if (dev_attr.UCharSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.UCharSeq.in(); else if (dev_attr.ULongSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.ULongSeq.in(); else if (dev_attr.ULong64Seq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.ULong64Seq.in(); else if (dev_attr.StateSeq.operator->() != NULL) attr_value_list[0].value <<= dev_attr.StateSeq.in(); } int ctr = 0; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_attribute()"); } // // Now, write the attribute(s) // if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); dev->write_attributes_4(attr_value_list_4,ci); } else if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); dev->write_attributes_3(attr_value_list); } else { Device_var dev = Device::_duplicate(device); dev->write_attributes(attr_value_list); } ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << dev_attr.name; desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << dev_attr.name; desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_attribute()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_attribute()",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } return; } //----------------------------------------------------------------------------- // // DeviceProxy::write_attribute() - write attribute(s) using the CORBA data type // //----------------------------------------------------------------------------- void DeviceProxy::write_attribute(const AttributeValueList &attr_val) { int ctr = 0; Tango::AccessControlType local_act; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_attribute()"); } // // Now, write the attribute(s) // if (version >= 3) { Device_3_var dev = Device_3::_duplicate(device_3); dev->write_attributes_3(attr_val); } else { Device_var dev = Device::_duplicate(device); dev->write_attributes(attr_val); } ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << attr_val[0].name.in(); desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << attr_val[0].name.in(); desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_attribute()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_attribute()",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } return; } void DeviceProxy::write_attribute(const AttributeValueList_4 &attr_val) { Tango::AccessControlType local_act; if (version == 0) check_and_reconnect(local_act); // // Check that the device supports IDL V4 // if (version < 4) { TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << attr_val[0].name.in(); desc << ". The device does not support thi stype of data (Bad IDL release)"; desc << ends; Tango::Except::throw_exception((const char*)API_NotSupportedFeature, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } int ctr = 0; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_attribute()"); } // // Now, write the attribute(s) // ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_4_var dev = Device_4::_duplicate(device_4); dev->write_attributes_4(attr_val,ci); ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << attr_val[0].name.in(); desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_attribute on device " << device_name; desc << ", attribute "; desc << attr_val[0].name.in(); desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_attribute()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_attribute()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_attribute()",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_attribute()"); } } return; } //----------------------------------------------------------------------------- // // DeviceProxy::get_attribute_list() - get list of attributes // //----------------------------------------------------------------------------- vector *DeviceProxy::get_attribute_list() { vector all_attr; AttributeInfoListEx * all_attr_config; all_attr.push_back(AllAttr_3); all_attr_config = get_attribute_config_ex(all_attr); vector *attr_list = new vector; attr_list->resize(all_attr_config->size()); for (unsigned int i=0; isize(); i++) { (*attr_list)[i] = (*all_attr_config)[i].name; } delete all_attr_config; return attr_list; } //----------------------------------------------------------------------------- // // DeviceProxy::attribute_list_query() - get list of attributes // //----------------------------------------------------------------------------- AttributeInfoList *DeviceProxy::attribute_list_query() { vector all_attr; AttributeInfoList *all_attr_config; all_attr.push_back(AllAttr_3); all_attr_config = get_attribute_config(all_attr); return all_attr_config; } //----------------------------------------------------------------------------- // // DeviceProxy::attribute_list_query_ex() - get list of attributes // //----------------------------------------------------------------------------- AttributeInfoListEx *DeviceProxy::attribute_list_query_ex() { vector all_attr; AttributeInfoListEx *all_attr_config; all_attr.push_back(AllAttr_3); all_attr_config = get_attribute_config_ex(all_attr); return all_attr_config; } //----------------------------------------------------------------------------- // // DeviceProxy::command_history() - get command history (only for polled command) // //----------------------------------------------------------------------------- vector *DeviceProxy::command_history(string &cmd_name,int depth) { if (version == 1) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << " does not support command_history feature" << ends; ApiNonSuppExcept::throw_exception((const char *)API_UnsupportedFeature, desc.str(), (const char *)"DeviceProxy::command_history"); } DevCmdHistoryList *hist = NULL; DevCmdHistory_4_var hist_4 = NULL; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); if (version <= 3) { Device_2_var dev = Device_2::_duplicate(device_2); hist = dev->command_inout_history_2(cmd_name.c_str(),depth); } else { Device_4_var dev = Device_4::_duplicate(device_4); hist_4 = dev->command_inout_history_4(cmd_name.c_str(),depth); } ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","command_history",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","command_history",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Command_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_history()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","command_history",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Command_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_history()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Command_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::command_history()"); } } vector *ddh = new vector; if (version <= 3) { int *ctr_ptr = new int; *ctr_ptr = 0; ddh->reserve(hist->length()); for (unsigned int i = 0;i < hist->length();i++) { ddh->push_back(DeviceDataHistory(i,ctr_ptr,hist)); } } else { ddh->reserve(hist_4->dates.length()); for (unsigned int i = 0;i < hist_4->dates.length();i++) ddh->push_back(DeviceDataHistory()); from_hist4_2_DataHistory(hist_4,ddh); } return ddh; } //----------------------------------------------------------------------------- // // DeviceProxy::attribute_history() - get attribute history // (only for polled attribute) // //----------------------------------------------------------------------------- vector *DeviceProxy::attribute_history(string &cmd_name,int depth) { if (version == 1) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << " does not support attribute_history feature" << ends; ApiNonSuppExcept::throw_exception((const char *)API_UnsupportedFeature, desc.str(), (const char *)"DeviceProxy::attribute_history"); } DevAttrHistoryList_var hist; DevAttrHistoryList_3_var hist_3; DevAttrHistory_4_var hist_4; DevAttrHistory_5_var hist_5; int ctr = 0; while (ctr < 2) { try { check_and_reconnect(); if (version == 2) { Device_2_var dev = Device_2::_duplicate(device_2); hist = device_2->read_attribute_history_2(cmd_name.c_str(),depth); } else { if (version == 3) { Device_3_var dev = Device_3::_duplicate(device_3); hist_3 = dev->read_attribute_history_3(cmd_name.c_str(),depth); } else if (version == 4) { Device_4_var dev = Device_4::_duplicate(device_4); hist_4 = dev->read_attribute_history_4(cmd_name.c_str(),depth); } else { Device_5_var dev = Device_5::_duplicate(device_5); hist_5 = dev->read_attribute_history_5(cmd_name.c_str(),depth); } } ctr = 2; } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","attribute_history",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","attribute_history",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::attribute_history()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","attribute_history",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::attribute_history()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Attribute_history failed on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::attribute_history()"); } } vector *ddh = new vector; if (version > 4) { ddh->reserve(hist_5->dates.length()); for (unsigned int i = 0;i < hist_5->dates.length();i++) ddh->push_back(DeviceAttributeHistory()); from_hist_2_AttHistory(hist_5,ddh); for (unsigned int i = 0;i < hist_5->dates.length();i++) (*ddh)[i].data_type = hist_5->data_type; } else if (version == 4) { ddh->reserve(hist_4->dates.length()); for (unsigned int i = 0;i < hist_4->dates.length();i++) ddh->push_back(DeviceAttributeHistory()); from_hist_2_AttHistory(hist_4,ddh); } else if (version == 3) { ddh->reserve(hist_3->length()); for (unsigned int i = 0;i < hist_3->length();i++) { ddh->push_back(DeviceAttributeHistory(i,hist_3)); } } else { ddh->reserve(hist->length()); for (unsigned int i = 0;i < hist->length();i++) { ddh->push_back(DeviceAttributeHistory(i,hist)); } } return ddh; } //--------------------------------------------------------------------------------------------------------------------- // // method: // DeviceProxy::connect_to_adm_device() // // description: // Create a connection to the admin device of the Tango device server process where the device is running. // //-------------------------------------------------------------------------------------------------------------------- void DeviceProxy::connect_to_adm_device() { adm_dev_name = adm_name(); adm_device = new DeviceProxy(adm_dev_name); } //----------------------------------------------------------------------------- // // DeviceProxy::polling_status() - get device polling status // //----------------------------------------------------------------------------- vector *DeviceProxy::polling_status() { check_connect_adm_device(); DeviceData dout,din; string cmd("DevPollStatus"); din.any <<= device_name.c_str(); // // In case of connection failed error, do a re-try // try { dout = adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { dout = adm_device->command_inout(cmd,din); } const DevVarStringArray *out_str; dout >> out_str; vector *poll_stat = new vector; poll_stat->reserve(out_str->length()); for (unsigned int i = 0;i < out_str->length();i++) { string str = (*out_str)[i].in(); poll_stat->push_back(str); } return poll_stat; } //----------------------------------------------------------------------------- // // DeviceProxy::is_polled() - return true if the object "obj_name" is polled. // In this case, the upd string is initialised with // the polling period. // //----------------------------------------------------------------------------- bool DeviceProxy::is_polled(polled_object obj, string &obj_name,string &upd) { bool ret = false; vector *poll_str; poll_str = polling_status(); if (poll_str->empty() == true) { delete poll_str; return ret; } string loc_obj_name(obj_name); transform(loc_obj_name.begin(),loc_obj_name.end(),loc_obj_name.begin(),::tolower); for (unsigned int i = 0;i < poll_str->size();i++) { string &tmp_str = (*poll_str)[i]; string::size_type pos,end; pos = tmp_str.find(' '); pos++; end = tmp_str.find(' ',pos + 1); string obj_type = tmp_str.substr(pos, end - pos); if (obj_type == "command") { if (obj == Attr) continue; } else if (obj_type == "attribute") { if (obj == Cmd) { if ((loc_obj_name != "state") && (loc_obj_name != "status")) continue; } } pos = tmp_str.find('='); pos = pos + 2; end = tmp_str.find(". S",pos + 1); if (end == string::npos) end = tmp_str.find('\n',pos + 1); string name = tmp_str.substr(pos, end - pos); transform(name.begin(),name.end(),name.begin(),::tolower); if (name == loc_obj_name) { // // Now that it's found, search for its polling period // pos = tmp_str.find("triggered",end); if (pos != string::npos) { ret = true; upd = "0"; break; } else { pos = tmp_str.find('=',end); pos = pos + 2; end = tmp_str.find('\n',pos + 1); string per = tmp_str.substr(pos, end - pos); upd = per; ret = true; break; } } } delete poll_str; return ret; } //----------------------------------------------------------------------------- // // DeviceProxy::get_command_poll_period() - Return command polling period // (in mS) // //----------------------------------------------------------------------------- int DeviceProxy::get_command_poll_period(string &cmd_name) { string poll_per; bool poll = is_polled(Cmd,cmd_name,poll_per); int ret; if (poll == true) { TangoSys_MemStream stream; stream << poll_per << ends; stream >> ret; } else ret = 0; return ret; } //----------------------------------------------------------------------------- // // DeviceProxy::get_attribute_poll_period() - Return attribute polling period // (in mS) // //----------------------------------------------------------------------------- int DeviceProxy::get_attribute_poll_period(string &attr_name) { string poll_per; bool poll = is_polled(Attr,attr_name,poll_per); int ret; if (poll == true) { TangoSys_MemStream stream; stream << poll_per << ends; stream >> ret; } else ret = 0; return ret; } //----------------------------------------------------------------------------- // // DeviceProxy::poll_command() - If object is already polled, just update its // polling period. If object is not polled, add // it to the list of polled objects // //----------------------------------------------------------------------------- void DeviceProxy::poll_command(string &cmd_name, int period) { string poll_per; bool poll = is_polled(Cmd,cmd_name,poll_per); DevVarLongStringArray in; in.lvalue.length(1); in.svalue.length(3); in.svalue[0] = CORBA::string_dup(device_name.c_str()); in.svalue[1] = CORBA::string_dup("command"); in.svalue[2] = CORBA::string_dup(cmd_name.c_str()); in.lvalue[0] = period; if (poll == true) { // // If object is polled and the polling period is the same, simply retruns // TangoSys_MemStream stream; int per; stream << poll_per << ends; stream >> per; if ((per == period) || (per == 0)) return; else { // // If object is polled, this is an update of the polling period // DeviceData din; string cmd("UpdObjPollingPeriod"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } } else { // // This a AddObjPolling command // DeviceData din; string cmd("AddObjPolling"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } } //----------------------------------------------------------------------------- // // DeviceProxy::poll_attribute() - If object is already polled, just update its // polling period. If object is not polled, add // it to the list of polled objects // //----------------------------------------------------------------------------- void DeviceProxy::poll_attribute(string &attr_name, int period) { string poll_per; bool poll = is_polled(Attr,attr_name,poll_per); DevVarLongStringArray in; in.lvalue.length(1); in.svalue.length(3); in.svalue[0] = CORBA::string_dup(device_name.c_str()); in.svalue[1] = CORBA::string_dup("attribute"); in.svalue[2] = CORBA::string_dup(attr_name.c_str()); in.lvalue[0] = period; if (poll == true) { // // If object is polled and the polling period is the same, simply returns // TangoSys_MemStream stream; int per; stream << poll_per << ends; stream >> per; if ((per == period) || (per == 0)) return; else { // // If object is polled, this is an update of the polling period // DeviceData din; string cmd("UpdObjPollingPeriod"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } } else { // // This a AddObjPolling command // DeviceData din; string cmd("AddObjPolling"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } } //----------------------------------------------------------------------------- // // DeviceProxy::is_cmd_polled() - return true if the command is polled // //----------------------------------------------------------------------------- bool DeviceProxy::is_command_polled(string &cmd_name) { string upd; return is_polled(Cmd,cmd_name,upd); } //----------------------------------------------------------------------------- // // DeviceProxy::is_attribute_polled() - return true if the attribute is polled // //----------------------------------------------------------------------------- bool DeviceProxy::is_attribute_polled(string &attr_name) { string upd; return is_polled(Attr,attr_name,upd); } //----------------------------------------------------------------------------- // // DeviceProxy::stop_poll_command() - Stop polling a command // //----------------------------------------------------------------------------- void DeviceProxy::stop_poll_command(string &cmd_name) { check_connect_adm_device(); DevVarStringArray in; in.length(3); in[0] = CORBA::string_dup(device_name.c_str()); in[1] = CORBA::string_dup("command"); in[2] = CORBA::string_dup(cmd_name.c_str()); DeviceData din; string cmd("RemObjPolling"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } //----------------------------------------------------------------------------- // // DeviceProxy::stop_poll_attribute() - Stop polling attribute // //----------------------------------------------------------------------------- void DeviceProxy::stop_poll_attribute(string &attr_name) { check_connect_adm_device(); DevVarStringArray in; in.length(3); in[0] = CORBA::string_dup(device_name.c_str()); in[1] = CORBA::string_dup("attribute"); in[2] = CORBA::string_dup(attr_name.c_str()); DeviceData din; string cmd("RemObjPolling"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } #ifdef TANGO_HAS_LOG4TANGO //----------------------------------------------------------------------------- // // DeviceProxy::add_logging_target - Add a logging target // //----------------------------------------------------------------------------- void DeviceProxy::add_logging_target(const string &target_type_name) { check_connect_adm_device(); DevVarStringArray in(2); in.length(2); in[0] = CORBA::string_dup(device_name.c_str()); in[1] = CORBA::string_dup(target_type_name.c_str()); DeviceData din; string cmd("AddLoggingTarget"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } //----------------------------------------------------------------------------- // // DeviceProxy::remove_logging_target - Remove a logging target // //----------------------------------------------------------------------------- void DeviceProxy::remove_logging_target (const string &target_type_name) { check_connect_adm_device(); DevVarStringArray in(2); in.length(2); in[0] = CORBA::string_dup(device_name.c_str()); in[1] = CORBA::string_dup(target_type_name.c_str()); DeviceData din; string cmd("RemoveLoggingTarget"); din.any <<= in; try { adm_device->command_inout(cmd,din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd,din); } } //----------------------------------------------------------------------------- // // DeviceProxy::get_logging_target - Returns the logging target list // //----------------------------------------------------------------------------- vector DeviceProxy::get_logging_target (void) { check_connect_adm_device(); DeviceData din; din << device_name; string cmd("GetLoggingTarget"); DeviceData dout; DevVarStringArray_var logging_targets; try { dout = adm_device->command_inout(cmd, din); } catch (Tango::CommunicationFailed &) { dout = adm_device->command_inout(cmd, din); } vector logging_targets_vec; dout >> logging_targets_vec; return logging_targets_vec; } //----------------------------------------------------------------------------- // // DeviceProxy::get_logging_level - Returns the current logging level // //----------------------------------------------------------------------------- int DeviceProxy::get_logging_level (void) { check_connect_adm_device(); string cmd("GetLoggingLevel"); DevVarStringArray in; in.length(1); in[0] = CORBA::string_dup(device_name.c_str()); DeviceData din; din.any <<= in; DeviceData dout; try { dout = adm_device->command_inout(cmd, din); } catch (Tango::CommunicationFailed &) { dout = adm_device->command_inout(cmd, din); } long level; if ((dout >> level) == false) { const Tango::DevVarLongStringArray *lsarr; dout >> lsarr; string devnm = dev_name(); std::transform( devnm.begin(), devnm.end(), devnm.begin(), ::tolower ); for( unsigned int i = 0; i < lsarr->svalue.length(); i++ ) { string nm( lsarr->svalue[i] ); std::transform( nm.begin(), nm.end(), nm.begin(), ::tolower ); if( devnm == nm ) { level = lsarr->lvalue[i]; break; } } } return (int)level; } //----------------------------------------------------------------------------- // // DeviceProxy::set_logging_level - Set the logging level // //----------------------------------------------------------------------------- void DeviceProxy::set_logging_level (int level) { check_connect_adm_device(); string cmd("SetLoggingLevel"); DevVarLongStringArray in; in.lvalue.length(1); in.lvalue[0] = level; in.svalue.length(1); in.svalue[0] = CORBA::string_dup(device_name.c_str()); DeviceData din; din.any <<= in; try { adm_device->command_inout(cmd, din); } catch (Tango::CommunicationFailed &) { adm_device->command_inout(cmd, din); } } #endif // TANGO_HAS_LOG4TANGO //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceProxy::subscribe_event // // description : // Subscribe to an event - Old interface for compatibility // //------------------------------------------------------------------------------------------------------------------- int DeviceProxy::subscribe_event (const string &attr_name, EventType event, CallBack *callback, const vector &filters) { return subscribe_event (attr_name, event, callback, filters, false); } //------------------------------------------------------------------------------------------------------------------- // // method : // DeviceProxy::subscribe_event // // description : // Subscribe to an event- Adds the statless flag for stateless event subscription. // //------------------------------------------------------------------------------------------------------------------- int DeviceProxy::subscribe_event (const string &attr_name, EventType event, CallBack *callback, const vector &filters, bool stateless) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } // // First, try using zmq. If it fails with the error "Command Not Found", try using notifd // int ret; try { ret = api_ptr->get_zmq_event_consumer()->subscribe_event(this, attr_name,event, callback, filters, stateless); } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { if (api_ptr->get_notifd_event_consumer() == NULL) { api_ptr->create_notifd_event_consumer(); } ret = api_ptr->get_notifd_event_consumer()->subscribe_event(this, attr_name,event, callback, filters, stateless); } else throw; } return ret; } //------------------------------------------------------------------------------------------------------------------ // // method : // DeviceProxy::subscribe_event // // description : // Subscribe to an event with the usage of the event queue for data reception. Adds the statless flag for // stateless event subscription. // //----------------------------------------------------------------------------------------------------------------- int DeviceProxy::subscribe_event (const string &attr_name, EventType event, int event_queue_size, const vector &filters, bool stateless) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } // // First, try using zmq. If it fails with the error "Command Not Found", try using notifd // int ret; try { ret = api_ptr->get_zmq_event_consumer()->subscribe_event(this, attr_name,event, event_queue_size, filters, stateless); } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { if (api_ptr->get_notifd_event_consumer() == NULL) { api_ptr->create_notifd_event_consumer(); } ret = api_ptr->get_notifd_event_consumer()->subscribe_event(this, attr_name,event, event_queue_size, filters, stateless); } else throw; } return ret; } //------------------------------------------------------------------------------------------------------------------- // // method : // DeviceProxy::subscribe_event // // description : // Subscribe to a device event- Add the statless flag for stateless event subscription. // //------------------------------------------------------------------------------------------------------------------- int DeviceProxy::subscribe_event (EventType event,CallBack *callback,bool stateless) { if (version < MIN_IDL_DEV_INTR) { stringstream ss; ss << "Device " << dev_name() << " does not support device interface change event\n"; ss << "Available since Tango release 9 AND for device inheriting from IDL release 5 (Device_5Impl)"; Tango::Except::throw_exception(API_NotSupportedFeature,ss.str(),"DeviceProxy::subscribe_event()"); } ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } int ret; ret = api_ptr->get_zmq_event_consumer()->subscribe_event(this,event,callback,stateless); return ret; } //------------------------------------------------------------------------------------------------------------------ // // method : // DeviceProxy::subscribe_event // // description : // Subscribe to an event with the usage of the event queue for data reception. Adds the statless flag for // stateless event subscription. // //----------------------------------------------------------------------------------------------------------------- int DeviceProxy::subscribe_event (EventType event,int event_queue_size,bool stateless) { if (version < MIN_IDL_DEV_INTR) { stringstream ss; ss << "Device " << dev_name() << " does not support device interface change event\n"; ss << "Available since Tango release 9 AND for device inheriting from IDL release 5 (Device_5Impl)"; Tango::Except::throw_exception(API_NotSupportedFeature,ss.str(),"DeviceProxy::subscribe_event()"); } ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } int ret; ret = api_ptr->get_zmq_event_consumer()->subscribe_event(this,event,event_queue_size,stateless); return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // DeviceProxy::unsubscribe_event // // description : // Unsubscribe to an event // //------------------------------------------------------------------------------------------------------------------- void DeviceProxy::unsubscribe_event (int event_id) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::unsubscribe_event()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->unsubscribe_event(event_id); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::unsubscribe_event()"); } api_ptr->get_notifd_event_consumer()->unsubscribe_event(event_id); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::get_events() // // description : Return a vector with all events stored in the event queue. // Events are kept in the buffer since the last extraction // with get_events(). // After returning the event data, the event queue gets // emptied! // // argument : in : event_id : The event identifier // argument : out : event_list : A reference to an event data list to be filled //----------------------------------------------------------------------------- void DeviceProxy::get_events (int event_id, EventDataList &event_list) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, event_list); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_events()"); } api_ptr->get_notifd_event_consumer()->get_events(event_id,event_list); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::get_events() // // description : Return a vector with all attribute configuration events // stored in the event queue. // Events are kept in the buffer since the last extraction // with get_events(). // After returning the event data, the event queue gets // emptied! // // argument : in : event_id : The event identifier // argument : out : event_list : A reference to an event data list to be filled //----------------------------------------------------------------------------- void DeviceProxy::get_events (int event_id, AttrConfEventDataList &event_list) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, event_list); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } api_ptr->get_notifd_event_consumer()->get_events(event_id,event_list); } } void DeviceProxy::get_events (int event_id, DataReadyEventDataList &event_list) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, event_list); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } api_ptr->get_notifd_event_consumer()->get_events(event_id,event_list); } } void DeviceProxy::get_events (int event_id, DevIntrChangeEventDataList &event_list) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { stringstream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, event_list); } else { stringstream desc; desc << "Event Device Interface Change not implemented in old Tango event system (notifd)"; Tango::Except::throw_exception(API_UnsupportedFeature,desc.str(),"DeviceProxy::get_events()"); } } void DeviceProxy::get_events (int event_id, PipeEventDataList &event_list) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { stringstream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; Tango::Except::throw_exception(API_EventConsumer,desc.str(),"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, event_list); } else { stringstream desc; desc << "Pipe event not implemented in old Tango event system (notifd)"; Tango::Except::throw_exception(API_UnsupportedFeature,desc.str(),"DeviceProxy::get_events()"); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::get_events() // // description : Call the callback method for all events stored // in the event queue. // Events are kept in the buffer since the last extraction // with get_events(). // After returning the event data, the event queue gets // emptied! // // argument : in : event_id : The event identifier // argument : out : cb : The callback object pointer //----------------------------------------------------------------------------- void DeviceProxy::get_events (int event_id, CallBack *cb) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_events()"); } if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { api_ptr->get_zmq_event_consumer()->get_events(event_id, cb); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_events()"); } api_ptr->get_notifd_event_consumer()->get_events(event_id,cb); } } //+---------------------------------------------------------------------------- // // method : DeviceProxy::event_queue_size() // // description : Returns the number of events stored in the event queue // // argument : in : event_id : The event identifier // //----------------------------------------------------------------------------- int DeviceProxy::event_queue_size(int event_id) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::event_queue_size()"); } EventConsumer *ev = NULL; if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { ev = api_ptr->get_zmq_event_consumer(); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::event_queue_size()"); } else ev = api_ptr->get_notifd_event_consumer(); } return ev->event_queue_size(event_id); } //+---------------------------------------------------------------------------- // // method : DeviceProxy::is_event_queue_empty() // // description : Returns true when the event queue is empty // // argument : in : event_id : The event identifier // //----------------------------------------------------------------------------- bool DeviceProxy::is_event_queue_empty(int event_id) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::is_event_queue_empty()"); } EventConsumer *ev = NULL; if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { ev = api_ptr->get_zmq_event_consumer(); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::is_event_queue_empty()"); } else ev = api_ptr->get_notifd_event_consumer(); } return (ev->is_event_queue_empty(event_id)); } //+---------------------------------------------------------------------------- // // method : DeviceProxy::get_last_event_date() // // description : Get the time stamp of the last inserted event // // argument : in : event_id : The event identifier // //----------------------------------------------------------------------------- TimeVal DeviceProxy::get_last_event_date(int event_id) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_last_event_date()"); } EventConsumer *ev = NULL; if (api_ptr->get_zmq_event_consumer()->get_event_system_for_event_id(event_id) == ZMQ) { ev = api_ptr->get_zmq_event_consumer(); } else { if (api_ptr->get_notifd_event_consumer() == NULL) { TangoSys_OMemStream desc; desc << "Could not find event consumer object, \n"; desc << "probably no event subscription was done before!"; desc << ends; Tango::Except::throw_exception( (const char*)"API_EventConsumer", desc.str(), (const char*)"DeviceProxy::get_last_event_date()"); } else ev = api_ptr->get_notifd_event_consumer(); } return (ev->get_last_event_date(event_id)); } //----------------------------------------------------------------------------- // // DeviceProxy::get_device_db - get database // //----------------------------------------------------------------------------- Database * DeviceProxy::get_device_db() { if ((db_port_num != 0) && (db_dev != NULL)) return db_dev->get_dbase(); else return (Database *)NULL; } //----------------------------------------------------------------------------- // // clean_lock - Litle function installed in the list of function(s) to be called // at exit time. It will clean all locking thread(s) and unlock locked device(s) // //----------------------------------------------------------------------------- void clean_lock() { if (ApiUtil::_is_instance_null() == false) { ApiUtil *au = ApiUtil::instance(); au->clean_locking_threads(); } } //----------------------------------------------------------------------------- // // DeviceProxy::lock - Lock the device // //----------------------------------------------------------------------------- void DeviceProxy::lock(int lock_validity) { // // Feature unavailable for device without database // if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Feature not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::lock"); } // // Some checks on lock validity // if (lock_validity < MIN_LOCK_VALIDITY) { TangoSys_OMemStream desc; desc << "Lock validity can not be lower than " << MIN_LOCK_VALIDITY << " seconds" << ends; Except::throw_exception((const char*)API_MethodArgument,desc.str(), (const char*)"DeviceProxy::lock"); } { omni_mutex_lock guard(lock_mutex); if (lock_ctr != 0) { if (lock_validity != lock_valid) { TangoSys_OMemStream desc; desc << "Device " << device_name << " is already locked with another lock validity ("; desc << lock_valid << " sec)" << ends; Except::throw_exception((const char*)API_MethodArgument,desc.str(), (const char*)"DeviceProxy::lock"); } } } // // Check if the function to be executed atexit is already installed // Tango::ApiUtil *au = ApiUtil::instance(); if (au->is_lock_exit_installed() == false) { atexit(clean_lock); au->set_sig_handler(); au->set_lock_exit_installed(true); } // // Connect to the admin device if not already done // check_connect_adm_device(); // // Send command to admin device // string cmd("LockDevice"); DeviceData din; DevVarLongStringArray sent_data; sent_data.svalue.length(1); sent_data.svalue[0] = CORBA::string_dup(device_name.c_str()); sent_data.lvalue.length(1); sent_data.lvalue[0] = lock_validity; din << sent_data; adm_device->command_inout(cmd, din); // // Increment locking counter // { omni_mutex_lock guard(lock_mutex); lock_ctr++; lock_valid = lock_validity; } // // Try to find the device's server admin device locking thread // in the ApiUtil map. // If the thread is not there, start one. // If the thread is there, ask it to add the device to its list // of locked devices // { omni_mutex_lock oml(au->lock_th_map); map::iterator pos = au->lock_threads.find(adm_dev_name); if (pos == au->lock_threads.end()) { create_locking_thread(au,lock_validity); } else { bool local_suicide; { omni_mutex_lock sync(*(pos->second.mon)); local_suicide = pos->second.shared->suicide; } if (local_suicide == true) { delete pos->second.shared; delete pos->second.mon; au->lock_threads.erase(pos); create_locking_thread(au,lock_validity); } else { int interupted; omni_mutex_lock sync(*(pos->second.mon)); if (pos->second.shared->cmd_pending == true) { interupted = pos->second.mon->wait(DEFAULT_TIMEOUT); if ((pos->second.shared->cmd_pending == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Locking thread blocked !!!", (const char *)"DeviceProxy::lock"); } } pos->second.shared->cmd_pending = true; pos->second.shared->cmd_code = LOCK_ADD_DEV; pos->second.shared->dev_name = device_name; { omni_mutex_lock guard(lock_mutex); pos->second.shared->lock_validity = lock_valid; } pos->second.mon->signal(); cout4 << "Cmd sent to locking thread" << endl; while (pos->second.shared->cmd_pending == true) { interupted = pos->second.mon->wait(DEFAULT_TIMEOUT); if ((pos->second.shared->cmd_pending == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Locking thread blocked !!!", (const char *)"DeviceProxy::lock"); } } } } } } //----------------------------------------------------------------------------- // // DeviceProxy::unlock - Unlock the device // //----------------------------------------------------------------------------- void DeviceProxy::unlock(bool force) { // // Feature unavailable for device without database // if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Feature not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::unlock"); } check_connect_adm_device(); // // Send command to admin device // string cmd("UnLockDevice"); DeviceData din,dout; DevVarLongStringArray sent_data; sent_data.svalue.length(1); sent_data.svalue[0] = CORBA::string_dup(device_name.c_str()); sent_data.lvalue.length(1); if (force == true) sent_data.lvalue[0] = 1; else sent_data.lvalue[0] = 0; din << sent_data; // // Send request to the DS admin device // dout = adm_device->command_inout(cmd, din); // // Decrement locking counter or replace it by the device global counter // returned by the server // Tango::DevLong glob_ctr; dout >> glob_ctr; int local_lock_ctr; { omni_mutex_lock guard(lock_mutex); lock_ctr--; if (glob_ctr != lock_ctr) lock_ctr = glob_ctr; local_lock_ctr = lock_ctr; } // // Try to find the device's server admin device locking thread // in the ApiUtil map. // Ask the thread to remove the device to its list of locked devices // if ((local_lock_ctr == 0) || (force == true)) { Tango::ApiUtil *au = Tango::ApiUtil::instance(); { omni_mutex_lock oml(au->lock_th_map); map::iterator pos = au->lock_threads.find(adm_dev_name); if (pos == au->lock_threads.end()) { // TangoSys_OMemStream o; // o << "Can't find the locking thread for device " << device_name << " and admin device " << adm_dev_name << ends; // Tango::Except::throw_exception((const char *)API_CantFindLockingThread,o.str(), // (const char *)"DeviceProxy::unlock()"); } else { if (pos->second.shared->suicide == true) { delete pos->second.shared; delete pos->second.mon; au->lock_threads.erase(pos); } else { int interupted; omni_mutex_lock sync(*(pos->second.mon)); if (pos->second.shared->cmd_pending == true) { interupted = pos->second.mon->wait(DEFAULT_TIMEOUT); if ((pos->second.shared->cmd_pending == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Locking thread blocked !!!", (const char *)"DeviceProxy::unlock"); } } pos->second.shared->cmd_pending = true; pos->second.shared->cmd_code = LOCK_REM_DEV; pos->second.shared->dev_name = device_name; pos->second.mon->signal(); cout4 << "Cmd sent to locking thread" << endl; while (pos->second.shared->cmd_pending == true) { interupted = pos->second.mon->wait(DEFAULT_TIMEOUT); if ((pos->second.shared->cmd_pending == true) && (interupted == 0)) { cout4 << "TIME OUT" << endl; Except::throw_exception((const char *)API_CommandTimedOut, (const char *)"Locking thread blocked !!!", (const char *)"DeviceProxy::unlock"); } } } } } } } //----------------------------------------------------------------------------- // // DeviceProxy::create_locking_thread - Create and start a locking thread // //----------------------------------------------------------------------------- void DeviceProxy::create_locking_thread(ApiUtil *au,DevLong dl) { LockingThread lt; lt.mon = NULL; lt.l_thread = NULL; lt.shared = NULL; pair::iterator,bool> status; status = au->lock_threads.insert(make_pair(adm_dev_name,lt)); if (status.second == false) { TangoSys_OMemStream o; o << "Can't create the locking thread for device " << device_name << " and admin device " << adm_dev_name << ends; Tango::Except::throw_exception((const char *)API_CantCreateLockingThread,o.str(), (const char *)"DeviceProxy::create_locking_thread()"); } else { map::iterator pos; pos = status.first; pos->second.mon = new TangoMonitor(adm_dev_name.c_str()); pos->second.shared = new LockThCmd; pos->second.shared->cmd_pending = false; pos->second.shared->suicide = false; pos->second.l_thread = new LockThread(*pos->second.shared,*pos->second.mon,adm_device,device_name,dl); pos->second.l_thread->start(); } } //----------------------------------------------------------------------------- // // DeviceProxy::locking_status - Return a device locking status as a string // //----------------------------------------------------------------------------- string DeviceProxy::locking_status() { vector v_str; vector v_l; ask_locking_status(v_str,v_l); string str(v_str[0]); return str; } //----------------------------------------------------------------------------- // // DeviceProxy::is_locked - Check if a device is locked // // Returns true if locked, false otherwise // //----------------------------------------------------------------------------- bool DeviceProxy::is_locked() { vector v_str; vector v_l; ask_locking_status(v_str,v_l); return (bool)v_l[0]; } //----------------------------------------------------------------------------- // // DeviceProxy::is_locked_by_me - Check if a device is locked by the caller // // Returns true if the caller is the locker, false otherwise // //----------------------------------------------------------------------------- bool DeviceProxy::is_locked_by_me() { vector v_str; vector v_l; ask_locking_status(v_str,v_l); bool ret = false; if (v_l[0] == 0) ret = false; else { #ifndef _TG_WINDOWS_ if (getpid() != v_l[1]) #else if (_getpid() != v_l[1]) #endif ret = false; else if ((v_l[2] != 0) || (v_l[3] != 0) || (v_l[4] != 0) || (v_l[5] != 0)) ret = false; else { string full_ip_str; get_locker_host(v_str[1],full_ip_str); // // If the call is local, as the PID is already the good one, the caller is the locker // if (full_ip_str == TG_LOCAL_HOST) ret = true; else { // // Get the host address(es) and check if it is the same than the one sent by the server // ApiUtil *au = ApiUtil::instance(); vector adrs; string at_least_one; au->get_ip_from_if(adrs); for (unsigned int nb_adrs = 0;nb_adrs < adrs.size();nb_adrs++) { if (adrs[nb_adrs] == full_ip_str) { ret = true; break; } } } } } return ret; } //----------------------------------------------------------------------------- // // DeviceProxy::get_locker - Get some info on the device locker if the device // is locked // This method returns true if the device is effectively locked. // Otherwise, it returns false // //----------------------------------------------------------------------------- bool DeviceProxy::get_locker(LockerInfo &lock_info) { vector v_str; vector v_l; ask_locking_status(v_str,v_l); if (v_l[0] == 0) return false; else { // // If the PID info coming from server is not 0, the locker is CPP // Otherwise, it is Java // if (v_l[1] != 0) { lock_info.ll = Tango::CPP; lock_info.li.LockerPid = v_l[1]; lock_info.locker_class = "Not defined"; } else { lock_info.ll = Tango::JAVA; for (int loop = 0;loop < 4;loop++) lock_info.li.UUID[loop] = v_l[2 + loop]; string full_ip; get_locker_host(v_str[1],full_ip); lock_info.locker_class = v_str[2]; } // // Add locker host name // string full_ip; get_locker_host(v_str[1],full_ip); // // Convert locker IP address to its name // if (full_ip != TG_LOCAL_HOST) { struct sockaddr_in si; si.sin_family = AF_INET; si.sin_port = 0; #ifdef _TG_WINDOWS_ int slen = sizeof(si); WSAStringToAddress((char *)full_ip.c_str(),AF_INET,NULL,(SOCKADDR *)&si,&slen); #else inet_pton(AF_INET,full_ip.c_str(),&si.sin_addr); #endif char host_os[512]; int res = getnameinfo((const sockaddr *)&si,sizeof(si),host_os,512,0,0,0); if (res == 0) lock_info.locker_host = host_os; else lock_info.locker_host = full_ip; } else { char h_name[80]; gethostname(h_name,80); lock_info.locker_host = h_name; } } return true; } //----------------------------------------------------------------------------- // // DeviceProxy::ask_locking_status - Get the device locking status // //----------------------------------------------------------------------------- void DeviceProxy::ask_locking_status(vector &v_str,vector &v_l) { // // Feature unavailable for device without database // if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Feature not available for device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"DeviceProxy::locking_status"); } check_connect_adm_device(); // // Send command to admin device // string cmd("DevLockStatus"); DeviceData din,dout; din.any <<= device_name.c_str(); dout = adm_device->command_inout(cmd, din); // // Extract data and return data to caller // dout.extract(v_l,v_str); } //----------------------------------------------------------------------------- // // DeviceProxy::get_locker_host - Isolate from the host string as it is returned // by omniORB, only the host IP address // //----------------------------------------------------------------------------- void DeviceProxy::get_locker_host(string &f_addr,string &ip_addr) { // // The hostname is returned in the following format: // "giop:tcp:160.103.5.157:32989" or "giop:tcp:[::ffff:160.103.5.157]:32989 // or "giop:unix:/tmp..." // We need to isolate the IP address // bool ipv6 = false; if (f_addr.find('[') != string::npos) ipv6 = true; if (f_addr.find(":unix:") != string::npos) { ip_addr = TG_LOCAL_HOST; } else { string::size_type pos; if ((pos = f_addr.find(':')) == string::npos) { Tango::Except::throw_exception((const char*)API_WrongLockingStatus, (const char *)"Locker IP address returned by server is unvalid", (const char *)"DeviceProxy::get_locker_host()"); } pos++; if ((pos = f_addr.find(':',pos)) == string::npos) { Tango::Except::throw_exception((const char*)API_WrongLockingStatus, (const char *)"Locker IP address returned by server is unvalid", (const char *)"DeviceProxy::get_locker_host()"); } pos++; if (ipv6 == true) { pos = pos + 3; if ((pos = f_addr.find(':',pos)) == string::npos) { Tango::Except::throw_exception((const char*)API_WrongLockingStatus, (const char *)"Locker IP address returned by server is unvalid", (const char *)"DeviceProxy::get_locker_host()"); } pos++; string ip_str = f_addr.substr(pos); if ((pos = ip_str.find(']')) == string::npos) { Tango::Except::throw_exception((const char*)API_WrongLockingStatus, (const char *)"Locker IP address returned by server is unvalid", (const char *)"DeviceProxy::get_locker_host()"); } ip_addr = ip_str.substr(0,pos); } else { string ip_str = f_addr.substr(pos); if ((pos = ip_str.find(':')) == string::npos) { Tango::Except::throw_exception((const char*)API_WrongLockingStatus, (const char *)"Locker IP address returned by server is unvalid", (const char *)"DeviceProxy::get_locker_host()"); } ip_addr = ip_str.substr(0,pos); } } } //----------------------------------------------------------------------------- // // DeviceProxy::write_read_attribute() - write then read a single attribute // //----------------------------------------------------------------------------- DeviceAttribute DeviceProxy::write_read_attribute(DeviceAttribute &dev_attr) { // // This call is available only for Devices implemented IDL V4 // if (version < 4) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << " does not support write_read_attribute feature" << ends; ApiNonSuppExcept::throw_exception((const char *)API_UnsupportedFeature, desc.str(), (const char *)"DeviceProxy::write_read_attribute"); } // // Data into the AttributeValue object // AttributeValueList_4 attr_value_list; attr_value_list.length(1); attr_value_list[0].name = dev_attr.name.c_str(); attr_value_list[0].quality = dev_attr.quality; attr_value_list[0].data_format = dev_attr.data_format; attr_value_list[0].time = dev_attr.time; attr_value_list[0].w_dim.dim_x = dev_attr.dim_x; attr_value_list[0].w_dim.dim_y = dev_attr.dim_y; if (dev_attr.LongSeq.operator->() != NULL) attr_value_list[0].value.long_att_value(dev_attr.LongSeq.in()); else if (dev_attr.Long64Seq.operator->() != NULL) attr_value_list[0].value.long64_att_value(dev_attr.Long64Seq.in()); else if (dev_attr.ShortSeq.operator->() != NULL) attr_value_list[0].value.short_att_value(dev_attr.ShortSeq.in()); else if (dev_attr.DoubleSeq.operator->() != NULL) attr_value_list[0].value.double_att_value(dev_attr.DoubleSeq.in()); else if (dev_attr.StringSeq.operator->() != NULL) attr_value_list[0].value.string_att_value(dev_attr.StringSeq.in()); else if (dev_attr.FloatSeq.operator->() != NULL) attr_value_list[0].value.float_att_value(dev_attr.FloatSeq.in()); else if (dev_attr.BooleanSeq.operator->() != NULL) attr_value_list[0].value.bool_att_value(dev_attr.BooleanSeq.in()); else if (dev_attr.UShortSeq.operator->() != NULL) attr_value_list[0].value.ushort_att_value(dev_attr.UShortSeq.in()); else if (dev_attr.UCharSeq.operator->() != NULL) attr_value_list[0].value.uchar_att_value(dev_attr.UCharSeq.in()); else if (dev_attr.ULongSeq.operator->() != NULL) attr_value_list[0].value.ulong_att_value(dev_attr.ULongSeq.in()); else if (dev_attr.ULong64Seq.operator->() != NULL) attr_value_list[0].value.ulong64_att_value(dev_attr.ULong64Seq.in()); else if (dev_attr.StateSeq.operator->() != NULL) attr_value_list[0].value.state_att_value(dev_attr.StateSeq.in()); else if (dev_attr.EncodedSeq.operator->() != NULL) attr_value_list[0].value.encoded_att_value(dev_attr.EncodedSeq.in()); Tango::DevVarStringArray dvsa; dvsa.length(1); dvsa[0] = CORBA::string_dup(dev_attr.name.c_str()); int ctr = 0; AttributeValueList_4_var attr_value_list_4; AttributeValueList_5_var attr_value_list_5; Tango::AccessControlType local_act; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_read_attribute()"); } // // Now, call the server // ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); if (version >= 5) { Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->write_read_attributes_5(attr_value_list,dvsa,ci); } else { Device_4_var dev = Device_4::_duplicate(device_4); attr_value_list_4 = dev->write_read_attributes_4(attr_value_list,ci); } ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << device_name; desc << ", attribute "; desc << attr_value_list[0].name.in(); desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << device_name; desc << ", attribute "; desc << attr_value_list[0].name.in(); desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_read_attribute()",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_read_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_read_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_read_attribute",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attribute on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attribute()"); } } // // Init the returned DeviceAttribute instance // DeviceAttribute ret_dev_attr; if (version >= 5) ApiUtil::attr_to_device(&(attr_value_list_5[0]),version,&ret_dev_attr); else ApiUtil::attr_to_device(&(attr_value_list_4[0]),version,&ret_dev_attr); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = ret_dev_attr.get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << device_name; desc << ", attribute " << dev_attr.name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::write_read_attribute()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } return(ret_dev_attr); } //----------------------------------------------------------------------------- // // DeviceProxy::write_read_attributes() - write then read a single attribute // //----------------------------------------------------------------------------- vector *DeviceProxy::write_read_attributes(vector &attr_list,vector &r_names) { // // This call is available only for Devices implemented IDL V5 // if (version < 5) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << " does not support write_read_attributes feature" << ends; ApiNonSuppExcept::throw_exception((const char *)API_UnsupportedFeature, desc.str(), (const char *)"DeviceProxy::write_read_attributes"); } // // Data into the AttributeValue object // AttributeValueList_4 attr_value_list; attr_value_list.length(attr_list.size()); for (unsigned int i=0; i() != NULL) attr_value_list[i].value.long_att_value(attr_list[i].LongSeq.in()); else if (attr_list[i].Long64Seq.operator->() != NULL) attr_value_list[i].value.long64_att_value(attr_list[i].Long64Seq.in()); else if (attr_list[i].ShortSeq.operator->() != NULL) attr_value_list[i].value.short_att_value(attr_list[i].ShortSeq.in()); else if (attr_list[i].DoubleSeq.operator->() != NULL) attr_value_list[i].value.double_att_value(attr_list[i].DoubleSeq.in()); else if (attr_list[i].StringSeq.operator->() != NULL) attr_value_list[i].value.string_att_value(attr_list[i].StringSeq.in()); else if (attr_list[i].FloatSeq.operator->() != NULL) attr_value_list[i].value.float_att_value(attr_list[i].FloatSeq.in()); else if (attr_list[i].BooleanSeq.operator->() != NULL) attr_value_list[i].value.bool_att_value(attr_list[i].BooleanSeq.in()); else if (attr_list[i].UShortSeq.operator->() != NULL) attr_value_list[i].value.ushort_att_value(attr_list[i].UShortSeq.in()); else if (attr_list[i].UCharSeq.operator->() != NULL) attr_value_list[i].value.uchar_att_value(attr_list[i].UCharSeq.in()); else if (attr_list[i].ULongSeq.operator->() != NULL) attr_value_list[i].value.ulong_att_value(attr_list[i].ULongSeq.in()); else if (attr_list[i].ULong64Seq.operator->() != NULL) attr_value_list[i].value.ulong64_att_value(attr_list[i].ULong64Seq.in()); else if (attr_list[i].StateSeq.operator->() != NULL) attr_value_list[i].value.state_att_value(attr_list[i].StateSeq.in()); else if (attr_list[i].EncodedSeq.operator->() != NULL) attr_value_list[i].value.encoded_att_value(attr_list[i].EncodedSeq.in()); } // // Create remaining parameter // Tango::DevVarStringArray dvsa; dvsa << r_names; // // Call device // int ctr = 0; AttributeValueList_5_var attr_value_list_5; Tango::AccessControlType local_act; while (ctr < 2) { try { check_and_reconnect(local_act); // // Throw exception if caller not allowed to write_attribute // if (local_act == ACCESS_READ) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(...) { set_connection_state(CONNECTION_NOTOK); throw; } TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception((const char *)API_ReadOnlyMode,desc.str(), (const char *)"DeviceProxy::write_read_attribute()"); } // // Now, call the server // ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); Device_5_var dev = Device_5::_duplicate(device_5); attr_value_list_5 = dev->write_read_attributes_5(attr_value_list,dvsa,ci); ctr = 2; } catch (Tango::MultiDevFailed &e) { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(e.errors[0].err_list); TangoSys_OMemStream desc; desc << "Failed to write_read_attributes on device " << device_name; desc << ", attribute "; desc << attr_value_list[0].name.in(); desc << ends; Except::re_throw_exception(ex,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); } catch (Tango::DevFailed &e) { TangoSys_OMemStream desc; desc << "Failed to write_read_attributes on device " << device_name; desc << ", attribute "; desc << attr_value_list[0].name.in(); desc << ends; if (::strcmp(e.errors[0].reason,DEVICE_UNLOCKED_REASON) == 0) DeviceUnlockedExcept::re_throw_exception(e,(const char*)DEVICE_UNLOCKED_REASON, desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); else Except::re_throw_exception(e,(const char*)API_AttributeFailed, desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); } catch (CORBA::TRANSIENT &trans) { TRANSIENT_NOT_EXIST_EXCEPT(trans,"DeviceProxy","write_read_attributes()",this); } catch (CORBA::OBJECT_NOT_EXIST &one) { if (one.minor() == omni::OBJECT_NOT_EXIST_NoMatch || one.minor() == 0) { TRANSIENT_NOT_EXIST_EXCEPT(one,"DeviceProxy","write_read_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_read_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(one, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); } } catch (CORBA::COMM_FAILURE &comm) { if (comm.minor() == omni::COMM_FAILURE_WaitingForReply) { TRANSIENT_NOT_EXIST_EXCEPT(comm,"DeviceProxy","write_read_attributes",this); } else { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(comm, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); } } catch (CORBA::SystemException &ce) { set_connection_state(CONNECTION_NOTOK); TangoSys_OMemStream desc; desc << "Failed to execute write_read_attributes on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"DeviceProxy::write_read_attributes()"); } } // // Init the returned DeviceAttribute vector unsigned long nb_received; nb_received = attr_value_list_5->length(); vector *dev_attr = new(vector); dev_attr->resize(nb_received); for (unsigned int i=0; i < nb_received; i++) { ApiUtil::attr_to_device(&(attr_value_list_5[i]),5,&(*dev_attr)[i]); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = (*dev_attr)[i].get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to write_read_attribute on device " << device_name; desc << ", attribute " << (*dev_attr)[i].name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::write_read_attributes()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } return(dev_attr); } //----------------------------------------------------------------------------- // // method : DeviceProxy::same_att_name() // // description : Check if in the attribute name list there is not several // times the same attribute. Throw exception in case of // // argin(s) : attr_list : The attribute name(s) list // met_name : The calling method name (for exception) // //----------------------------------------------------------------------------- void DeviceProxy::same_att_name(vector &attr_list,const char *met_name) { if (attr_list.size() > 1) { unsigned int i; vector same_att = attr_list; for (i = 0;i < same_att.size();++i) transform(same_att[i].begin(),same_att[i].end(),same_att[i].begin(),::tolower); sort(same_att.begin(),same_att.end()); vector same_att_lower = same_att; vector::iterator pos = unique(same_att.begin(),same_att.end()); int duplicate_att; duplicate_att = distance(attr_list.begin(),attr_list.end()) - distance(same_att.begin(),pos); if (duplicate_att != 0) { TangoSys_OMemStream desc; desc << "Several times the same attribute in required attributes list: "; int ctr = 0; for (i = 0;i < same_att_lower.size() - 1;i++) { if (same_att_lower[i] == same_att_lower[i + 1]) { ctr++; desc << same_att_lower[i]; if (ctr < duplicate_att) desc << ", "; } } desc << ends; ApiConnExcept::throw_exception((const char*)API_AttributeFailed,desc.str(), met_name); } } } //----------------------------------------------------------------------------- // // DeviceProxy::local_import() - If the device is embedded within the same // process, re-create its IOR and returns it. This save one DB call. // //----------------------------------------------------------------------------- void DeviceProxy::local_import(string &local_ior) { Tango::Util *tg = NULL; // // In case of controlled access used, this method is called while the // Util object is still in its construction case. // Catch this exception and return from this method in this case // try { tg = Tango::Util::instance(false); } catch (Tango::DevFailed &e) { string reas(e.errors[0].reason); if (reas == "API_UtilSingletonNotCreated") return; } const vector *cl_list_ptr = tg->get_class_list(); for (unsigned int loop = 0;loop < cl_list_ptr->size();loop++) { Tango::DeviceClass *cl_ptr = (*cl_list_ptr)[loop]; vector dev_list = cl_ptr->get_device_list(); for (unsigned int lo = 0;lo < dev_list.size();lo++) { if (dev_list[lo]->get_name_lower() == device_name) { if (Tango::Util::_UseDb == true) { Database *db = tg->get_database(); if (db->get_db_host() != get_db_host()) return; } Tango::Device_var d_var = dev_list[lo]->get_d_var(); CORBA::ORB_ptr orb_ptr = tg->get_orb(); char *s = orb_ptr->object_to_string(d_var); local_ior = s; CORBA::release(orb_ptr); CORBA::string_free(s); return; } } } } //--------------------------------------------------------------------------------------------------------------------- // // method: // DeviceProxy::get_tango_lib_version() // // description: // Returns the Tango lib version number used by the remote device // // return: // The device Tango lib version as a 3 or 4 digits number // Possible return value are: 100,200,500,520,700,800,810,... // //--------------------------------------------------------------------------------------------------------------------- int DeviceProxy::get_tango_lib_version() { int ret = 0; check_connect_adm_device(); // // Get admin device IDL release and command list // int admin_idl_vers = adm_device->get_idl_version(); Tango::CommandInfoList *cmd_list; cmd_list = adm_device->command_list_query(); switch (admin_idl_vers) { case 1: ret = 100; break; case 2: ret = 200; break; case 3: { // // IDL 3 is for Tango 5 and 6. Unfortunately, there is no way from the client side to determmine if it is // Tango 5 or 6. The beast we can do is to get the info that it is Tango 5.2 (or above) // #ifdef HAS_LAMBDA_FUNC auto pos = find_if((*cmd_list).begin(),(*cmd_list).end(), [] (Tango::CommandInfo &cc) -> bool { return cc.cmd_name == "QueryWizardClassProperty"; }); #else vector::iterator pos,end; for (pos = (*cmd_list).begin(), end = (*cmd_list).end();pos != end;++pos) { if (pos->cmd_name == "QueryWizardClassProperty") break; } #endif if (pos != (*cmd_list).end()) ret = 520; else ret = 500; break; } case 4: { // // IDL 4 is for Tango 7 and 8. // bool ecs = false; bool zesc = false; #ifdef HAS_RANGE_BASE_FOR for (const auto &cmd : *cmd_list) { if (cmd.cmd_name == "EventConfirmSubscription") { ecs = true; break; } if (cmd.cmd_name == "ZmqEventSubscriptionChange") zesc = true; } #else vector::iterator pos,pos_end; for (pos = (*cmd_list).begin(), pos_end = (*cmd_list).end();pos != pos_end;++pos) { if (pos->cmd_name == "EventConfirmSubscription") { ecs = true; break; } if (pos->cmd_name == "ZmqEventSubscriptionChange") zesc = true; } #endif if (ecs == true) ret = 810; else if (zesc == true) ret = 800; else ret = 700; break; } case 5: ret = 902; break; default: break; } delete cmd_list; return ret; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/devapi_data.cpp0000644023471100065110000017771513034744771015535 00000000000000static const char *RcsId = "$Id: devapi_data.cpp 29768 2016-05-31 07:22:06Z taurel $"; // // devapi_data.cpp - C++ source code file for TANGO devapi class DeviceData // // programmer(s) - Andy Gotz (goetz@esrf.fr) // // original - March 2001 // // Copyright (C) : 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // version - $Revision: 29768 $ // #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DeviceData::DeviceData() - constructor to create DeviceData // //----------------------------------------------------------------------------- DeviceData::DeviceData():ext(new DeviceDataExt) { // // For omniORB, it is necessary to do the ORB::init before creating the Any. // Otherwise, string insertion into the Any will not be possible // ApiUtil *au = ApiUtil::instance(); if (CORBA::is_nil(au->get_orb()) == true) au->create_orb(); any = new CORBA::Any(); exceptions_flags.set(isempty_flag); } //----------------------------------------------------------------------------- // // DeviceData::DeviceData() - copy constructor to create DeviceData // //----------------------------------------------------------------------------- DeviceData::DeviceData(const DeviceData & source) { exceptions_flags = source.exceptions_flags; #ifdef HAS_RVALUE any = source.any; #else any = const_cast(source).any._retn(); #endif #ifdef HAS_UNIQUE_PTR if (source.ext.get() != NULL) { ext.reset(new DeviceDataExt); *(ext.get()) = *(source.ext.get()); } #else if (source.ext != NULL) { ext = new DeviceDataExt(); *ext = *(source.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // DeviceData::DeviceData() - move constructor to create DeviceData // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DeviceData::DeviceData(DeviceData &&source):ext(new DeviceDataExt) { exceptions_flags = source.exceptions_flags; any = source.any._retn(); if (source.ext.get() != NULL) ext = move(source.ext); } #endif //----------------------------------------------------------------------------- // // DeviceData::operator=() - assignement operator // //----------------------------------------------------------------------------- DeviceData & DeviceData::operator=(const DeviceData &rval) { if (this != &rval) { exceptions_flags = rval.exceptions_flags; #ifdef HAS_RVALUE any = rval.any; #else any = const_cast(rval).any._retn(); #endif #ifdef HAS_UNIQUE_PTR if (rval.ext.get() != NULL) { ext.reset(new DeviceDataExt); *(ext.get()) = *(rval.ext.get()); } else ext.reset(); #else delete ext; if (rval.ext != NULL) { ext = new DeviceDataExt(); *ext = *(rval.ext); } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DeviceData::operator=() - move assignement operator // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DeviceData & DeviceData::operator=(DeviceData &&rval) { exceptions_flags = rval.exceptions_flags; any = rval.any._retn(); if (rval.ext.get() != NULL) ext = move(rval.ext); else ext.reset(); return *this; } #endif //----------------------------------------------------------------------------- // // DeviceData::~DeviceData() - destructor to destroy DeviceData // //----------------------------------------------------------------------------- DeviceData::~DeviceData() { #ifndef HAS_UNIQUE_PTR delete ext; #endif } //----------------------------------------------------------------------------- // // DeviceData::is_empty() - test is DeviceData is empty ! // //----------------------------------------------------------------------------- bool DeviceData::is_empty() { bool ret = any_is_null(); return(ret); } //----------------------------------------------------------------------------- // // DeviceData::any_is_null() - test any type for equality to null // //----------------------------------------------------------------------------- bool DeviceData::any_is_null() { ext->ext_state.reset(isempty_flag); CORBA::TypeCode_ptr tc; tc = any->type(); if (tc->equal(CORBA::_tc_null)) { ext->ext_state.set(isempty_flag); if (exceptions_flags.test(isempty_flag)) { ApiDataExcept::throw_exception((const char*)"API_EmptyDeviceData", (const char*)"Cannot extract, no data in DeviceData object ", (const char*)"DeviceData::any_is_null"); } return(true); } CORBA::release(tc); return(false); } //----------------------------------------------------------------------------- // // DeviceData::get_type() - return DeviceData data type // //----------------------------------------------------------------------------- int DeviceData::get_type() { int data_type = 0; if (any_is_null() == true) return -1; else { CORBA::TypeCode_ptr tc; CORBA::TypeCode_var tc_al; CORBA::TypeCode_var tc_seq; CORBA::TypeCode_var tc_field; tc = any->type(); switch(tc->kind()) { case CORBA::tk_boolean: data_type = Tango::DEV_BOOLEAN; break; case CORBA::tk_short: data_type = Tango::DEV_SHORT; break; case CORBA::tk_long: data_type = Tango::DEV_LONG; break; case CORBA::tk_longlong: data_type = Tango::DEV_LONG64; break; case CORBA::tk_float: data_type = Tango::DEV_FLOAT; break; case CORBA::tk_double: data_type = Tango::DEV_DOUBLE; break; case CORBA::tk_ushort: data_type = Tango::DEV_USHORT; break; case CORBA::tk_ulong: data_type = Tango::DEV_ULONG; break; case CORBA::tk_ulonglong: data_type = Tango::DEV_ULONG64; break; case CORBA::tk_string: data_type = Tango::DEV_STRING; break; case CORBA::tk_alias: tc_al = tc->content_type(); tc_seq = tc_al->content_type(); switch (tc_seq->kind()) { case CORBA::tk_octet: data_type = Tango::DEVVAR_CHARARRAY; break; case CORBA::tk_short: data_type = Tango::DEVVAR_SHORTARRAY; break; case CORBA::tk_long: data_type = Tango::DEVVAR_LONGARRAY; break; case CORBA::tk_longlong: data_type = Tango::DEVVAR_LONG64ARRAY; break; case CORBA::tk_float: data_type = Tango::DEVVAR_FLOATARRAY; break; case CORBA::tk_double: data_type = Tango::DEVVAR_DOUBLEARRAY; break; case CORBA::tk_ushort: data_type = Tango::DEVVAR_USHORTARRAY; break; case CORBA::tk_ulong: data_type = Tango::DEVVAR_ULONGARRAY; break; case CORBA::tk_ulonglong: data_type = Tango::DEVVAR_ULONG64ARRAY; break; case CORBA::tk_string: data_type = Tango::DEVVAR_STRINGARRAY; break; default: break; } break; case CORBA::tk_struct: tc_field = tc->member_type(0); tc_al = tc_field->content_type(); switch (tc_al->kind()) { case CORBA::tk_sequence: tc_seq = tc_al->content_type(); switch (tc_seq->kind()) { case CORBA::tk_long: data_type = Tango::DEVVAR_LONGSTRINGARRAY; break; case CORBA::tk_double: data_type = Tango::DEVVAR_DOUBLESTRINGARRAY; break; default: break; } break; case CORBA::tk_string: data_type = Tango::DEV_ENCODED; break; default: break; } break; case CORBA::tk_enum: data_type = Tango::DEV_STATE; break; default: break; } CORBA::release(tc); } return data_type; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(bool &) - extract a boolean from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (bool& datum) { ext->ext_state.reset(); bool ret = any >>= CORBA::Any::to_boolean(datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a boolean", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(short &) - extract a short from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (short& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a short", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(unsigned short &) - extract a unsigned short from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (unsigned short& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an unsigned short", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevLong &) - extract a DevLong from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevLong& datum) { ext->ext_state.reset(); bool ret = (any >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevLong (long 32 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevULong &) - extract a DevULong from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevULong& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an DevULong (unsigned long 32 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevLong64) - extract a DevLong64 from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevLong64 & datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevLong64 (64 bits long)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevULong64 &) - extract a DevULong64 from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevULong64 & datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevULong64 (unsigned 64 bits long)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(float &) - extract a float from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (float& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a float", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(double &) - extract a double from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (double& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a double", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(string &) - extract a string from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (string& datum) { ext->ext_state.reset(); const char *c_string = NULL; bool ret = (any >>= c_string); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a string", (const char*)"DeviceData::operator>>"); } } else { datum = c_string; } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(const char* &) - extract a const char* from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const char*& datum) { ext->ext_state.reset(); bool ret = any >>= datum; if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of char", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevState &) - extract a DevState from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevState& datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevState", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarCharArray *char_array = NULL; bool ret = (any.inout() >>= char_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of char", (const char*)"DeviceData::operator>>"); } } else { if (char_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(char_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*char_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarCharArray *) - extract a DevVarCharArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarCharArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of char", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarShortArray *short_array = NULL; bool ret = (any.inout() >>= short_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of short", (const char*)"DeviceData::operator>>"); } } else { if (short_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(short_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*short_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarShortArray *) - extract a DevVarShortArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarShortArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of short", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarUShortArray *ushort_array = NULL; bool ret = (any.inout() >>= ushort_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of unsigned short", (const char*)"DeviceData::operator>>"); } } else { if (ushort_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(ushort_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*ushort_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarUShortArray *) - extract a DevVarUShortArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarUShortArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of unusigned short", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarLongArray *long_array = NULL; bool ret = (any.inout() >>= long_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of DevLong (long 32 bits)", (const char*)"DeviceData::operator>>"); } } else { if (long_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(long_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*long_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarLongArray *) - extract a DevVarLongArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarLongArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of long (32 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarULongArray *ulong_array = NULL; bool ret = (any.inout() >>= ulong_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of DevULong (unsigned long 32 bits)", (const char*)"DeviceData::operator>>"); } } else { if (ulong_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(ulong_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*ulong_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarULongArray *) - extract a DevVarULongArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarULongArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of unsigned long (32 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarLong64Array *) - extract a DevVarLong64Array from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarLong64Array* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of long (64 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarULong64Array *) - extract a DevVarULong64Array from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarULong64Array* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of unsigned long (64 bits)", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarLong64Array *ll_array = NULL; bool ret = (any.inout() >>= ll_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of DevLong64 (64 bits long)", (const char*)"DeviceData::operator>>"); } } else { if (ll_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(ll_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*ll_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarULong64Array *ull_array = NULL; bool ret = (any.inout() >>= ull_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of DevULong64 (unsigned 64 bits long)", (const char*)"DeviceData::operator>>"); } } else { if (ull_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(ull_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*ull_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarFloatArray *float_array = NULL; bool ret = (any.inout() >>= float_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of float", (const char*)"DeviceData::operator>>"); } } else { if (float_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(float_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*float_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarFloatArray *) - extract a DevVarFloatArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarFloatArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of float", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarDoubleArray *double_array = NULL; bool ret = (any.inout() >>= double_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of double", (const char*)"DeviceData::operator>>"); } } else { if (double_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(double_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*double_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarDoubleArray *) - extract a DevVarDoubleArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarDoubleArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of double", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(vector &) - extract a vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (vector& datum) { ext->ext_state.reset(); const DevVarStringArray *string_array = NULL; bool ret = (any.inout() >>= string_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of string", (const char*)"DeviceData::operator>>"); } } else { if (string_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.resize(string_array->length()); for (unsigned int i=0; ilength(); i++) { datum[i] = (*string_array)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarStringArray *) - extract a DevVarStringArray from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarStringArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not an array of string", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevEncoded *) - extract a DevEncoded from DeviceData // by pointer // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevEncoded* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevEncoded", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevEncoded &) - extract a DevEncoded from DeviceData // by reference // //----------------------------------------------------------------------------- bool DeviceData::operator >> (DevEncoded &datum) { ext->ext_state.reset(); const DevEncoded *tmp_enc = NULL; bool ret = (any.inout() >>= tmp_enc); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevEncoded", (const char*)"DeviceData::operator>>"); } } else { if (tmp_enc == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { datum.encoded_data.length(tmp_enc->encoded_data.length()); for (unsigned int i=0; iencoded_data.length(); i++) { datum.encoded_data[i] = tmp_enc->encoded_data[i]; } datum.encoded_format = CORBA::string_dup(tmp_enc->encoded_format); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator <<(vector &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarCharArray *char_array = new DevVarCharArray(); char_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarShortArray *short_array = new DevVarShortArray(); short_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarUShortArray *ushort_array = new DevVarUShortArray(); ushort_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarLongArray *long_array = new DevVarLongArray(); long_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarULongArray *ulong_array = new DevVarULongArray(); ulong_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarFloatArray *float_array = new DevVarFloatArray(); float_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarDoubleArray *double_array = new DevVarDoubleArray(); double_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarStringArray *string_array = new DevVarStringArray(); string_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarLong64Array *ll_array = new DevVarLong64Array(); ll_array->length(datum.size()); for (unsigned int i=0; i &) - insert a vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::operator << (vector& datum) { DevVarULong64Array *ull_array = new DevVarULong64Array(); ull_array->length(datum.size()); for (unsigned int i=0; i, vector &) - insert a pair of // vector,vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::insert (vector &long_datum, vector& string_datum) { unsigned int i; DevVarLongStringArray *long_string_array = new DevVarLongStringArray(); long_string_array->lvalue.length(long_datum.size()); for (i=0; ilvalue)[i] = long_datum[i]; } long_string_array->svalue.length(string_datum.size()); for (i=0; isvalue)[i] = string_dup(string_datum[i].c_str()); } any.inout() <<= long_string_array; } //----------------------------------------------------------------------------- // // DeviceData::extract (vector, vector &) - extract a pair of // vector,vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::extract(vector &long_datum, vector& string_datum) { bool ret; ext->ext_state.reset(); const DevVarLongStringArray *long_string_array = NULL; ret = (any.inout() >>= long_string_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a structure with sequences of string(s) and long(s) (32 bits)", (const char*)"DeviceData::operator>>"); } } else { if (long_string_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { unsigned int i; long_datum.resize(long_string_array->lvalue.length()); for (i=0; ilvalue)[i]; } string_datum.resize(long_string_array->svalue.length()); for (i=0; isvalue)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarLongStringArray *) - insert a DevVarLongStringArray into DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarLongStringArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a structure with sequences of string(s) and long(s) (32 bits) ", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::insert (vector, vector &) - insert a pair of // vector,vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::insert (vector &double_datum, vector& string_datum) { unsigned int i; DevVarDoubleStringArray *double_string_array = new DevVarDoubleStringArray(); double_string_array->dvalue.length(double_datum.size()); for (i=0; idvalue)[i] = double_datum[i]; } double_string_array->svalue.length(string_datum.size()); for (i=0; isvalue)[i] = string_dup(string_datum[i].c_str()); } any.inout() <<= double_string_array; } //----------------------------------------------------------------------------- // // DeviceData::extract (vector, vector &) - extract a pair of // vector,vector from DeviceData // //----------------------------------------------------------------------------- bool DeviceData::extract (vector &double_datum, vector& string_datum) { bool ret; ext->ext_state.reset(); const DevVarDoubleStringArray *double_string_array = NULL; ret = (any.inout() >>= double_string_array); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a boolean", (const char*)"DeviceData::operator>>"); } } else { if (double_string_array == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::operator>>"); } else { unsigned int i; double_datum.resize(double_string_array->dvalue.length()); for (i=0; idvalue)[i]; } string_datum.resize(double_string_array->svalue.length()); for (i=0; isvalue)[i]; } } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::operator >>(DevVarDoubleStringArray *) - insert a DevVarDoubleStringArray into DeviceData // //----------------------------------------------------------------------------- bool DeviceData::operator >> (const DevVarDoubleStringArray* &datum) { ext->ext_state.reset(); bool ret = (any.inout() >>= datum); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a structure with sequences of string(s) and double(s) ", (const char*)"DeviceData::operator>>"); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::insert (string, vector &) - insert a pair of // string,vector into DeviceData // //----------------------------------------------------------------------------- void DeviceData::insert (const string &str_datum, vector& char_datum) { DevEncoded *the_enc = new DevEncoded(); the_enc->encoded_format = CORBA::string_dup(str_datum.c_str()); the_enc->encoded_data.replace(char_datum.size(),char_datum.size(),&(char_datum[0]),false); any.inout() <<= the_enc; } //----------------------------------------------------------------------------- // // DeviceData::insert (const char *, DevVarCharArray *) - insert a pair of // char *,DevVarCharArray into DeviceData // //----------------------------------------------------------------------------- void DeviceData::insert (const char *str_datum, DevVarCharArray *char_datum) { DevEncoded *the_enc = new DevEncoded(); the_enc->encoded_format = CORBA::string_dup(str_datum); the_enc->encoded_data.replace(char_datum->length(),char_datum->length(),char_datum->get_buffer(),false); any.inout() <<= the_enc; } //----------------------------------------------------------------------------- // // DeviceData::insert (const char *&, DevVarCharArray *) - insert a pair of // char *,DevVarCharArray into DeviceData // //----------------------------------------------------------------------------- void DeviceData::insert (const char *str_datum,unsigned char *data,unsigned int length) { DevEncoded *the_enc = new DevEncoded(); the_enc->encoded_format = CORBA::string_dup(str_datum); the_enc->encoded_data.replace(length,length,data,false); any.inout() <<= the_enc; } //----------------------------------------------------------------------------- // // DeviceData::extract(const char *&,unsigned char *&,unsigned int &) // // - extract data for the DevEncoded data type // //----------------------------------------------------------------------------- bool DeviceData::extract(const char *&str,const unsigned char *&data_ptr,unsigned int &data_size) { ext->ext_state.reset(); const DevEncoded *tmp_enc = NULL; bool ret = (any.inout() >>= tmp_enc); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevEncoded", (const char*)"DeviceData::extract"); } } else { if (tmp_enc == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::extract"); } else { str = tmp_enc->encoded_format; data_size = tmp_enc->encoded_data.length(); data_ptr = tmp_enc->encoded_data.get_buffer(); } } return ret; } //----------------------------------------------------------------------------- // // DeviceData::extract(const char *&,unsigned char *&,unsigned int &) // // - extract data for the DevEncoded data type // //----------------------------------------------------------------------------- bool DeviceData::extract(string &str,vector &datum) { ext->ext_state.reset(); const DevEncoded *tmp_enc = NULL; bool ret = (any.inout() >>= tmp_enc); if (ret == false) { if (any_is_null()) return ret; ext->ext_state.set(wrongtype_flag); if (exceptions_flags.test(wrongtype_flag)) { ApiDataExcept::throw_exception((const char*)API_IncompatibleCmdArgumentType, (const char*)"Cannot extract, data in DeviceData object is not a DevEncoded", (const char*)"DeviceData::extract"); } } else { if (tmp_enc == NULL) { ext->ext_state.set(wrongtype_flag); ApiDataExcept::throw_exception((const char *)API_IncoherentDevData, (const char *)"Incoherent data received from server", (const char *)"DeviceData::extract"); } else { str = tmp_enc->encoded_format; unsigned long length = tmp_enc->encoded_data.length(); datum.resize(length); datum.assign(tmp_enc->encoded_data.get_buffer(),tmp_enc->encoded_data.get_buffer() + length); } } return ret; } //+------------------------------------------------------------------------- // // operator overloading : << // // description : Friend function to ease printing instance of the // DeviceData class // //-------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,DeviceData &dd) { if (dd.any_is_null() == true) o_str << "No data in DeviceData object"; else { CORBA::TypeCode_ptr tc; CORBA::TypeCode_var tc_al; CORBA::TypeCode_var tc_seq; CORBA::TypeCode_var tc_field; tc = dd.any->type(); switch(tc->kind()) { case CORBA::tk_boolean: bool bo_tmp; dd.any >>= CORBA::Any::to_boolean(bo_tmp); if (bo_tmp == true) o_str << "true" ; else o_str << "false" ; break; case CORBA::tk_short: short tmp; dd.any >>= tmp; o_str << tmp; break; case CORBA::tk_long: Tango::DevLong l_tmp; dd.any >>= l_tmp; o_str << l_tmp; break; case CORBA::tk_longlong: #ifdef TANGO_LONG32 long long ll_tmp; #else long ll_tmp; #endif dd.any >>= ll_tmp; o_str << ll_tmp; break; case CORBA::tk_float: float f_tmp; dd.any >>= f_tmp; o_str << f_tmp; break; case CORBA::tk_double: double db_tmp; dd.any >>= db_tmp; o_str << db_tmp; break; case CORBA::tk_ushort: unsigned short us_tmp; dd.any >>= us_tmp; o_str << us_tmp; break; case CORBA::tk_ulong: Tango::DevULong ul_tmp; dd.any >>= ul_tmp; o_str << ul_tmp; break; case CORBA::tk_ulonglong: unsigned long ull_tmp; dd.any >>= ull_tmp; o_str << ull_tmp; break; case CORBA::tk_string: const char *str_tmp; dd.any >>= str_tmp; o_str << str_tmp; break; case CORBA::tk_alias: tc_al = tc->content_type(); tc_seq = tc_al->content_type(); switch (tc_seq->kind()) { case CORBA::tk_octet: Tango::DevVarCharArray *ch_arr; dd.any.inout() >>= ch_arr; o_str << *ch_arr; break; case CORBA::tk_short: Tango::DevVarShortArray *sh_arr; dd.any.inout() >>= sh_arr; o_str << *sh_arr; break; case CORBA::tk_long: Tango::DevVarLongArray *lg_arr; dd.any.inout() >>= lg_arr; o_str << *lg_arr; break; case CORBA::tk_longlong: Tango::DevVarLong64Array *llg_arr; dd.any.inout() >>= llg_arr; o_str << *llg_arr; break; case CORBA::tk_float: Tango::DevVarFloatArray *fl_arr; dd.any.inout() >>= fl_arr; o_str << *fl_arr; break; case CORBA::tk_double: Tango::DevVarDoubleArray *db_arr; dd.any.inout() >>= db_arr; o_str << *db_arr; break; case CORBA::tk_ushort: Tango::DevVarUShortArray *us_arr; dd.any.inout() >>= us_arr; o_str << *us_arr; break; case CORBA::tk_ulong: Tango::DevVarULongArray *ul_arr; dd.any.inout() >>= ul_arr; o_str << *ul_arr; break; case CORBA::tk_ulonglong: Tango::DevVarULong64Array *ull_arr; dd.any.inout() >>= ull_arr; o_str << *ull_arr; break; case CORBA::tk_string: Tango::DevVarStringArray *str_arr; dd.any.inout() >>= str_arr; o_str << *str_arr; break; default: break; } break; case CORBA::tk_struct: tc_field = tc->member_type(0); tc_al = tc_field->content_type(); switch (tc_al->kind()) { case CORBA::tk_sequence: tc_seq = tc_al->content_type(); switch (tc_seq->kind()) { case CORBA::tk_long: Tango::DevVarLongStringArray *lgstr_arr; dd.any.inout() >>= lgstr_arr; o_str << lgstr_arr->lvalue << endl; o_str << lgstr_arr->svalue; break; case CORBA::tk_double: Tango::DevVarDoubleStringArray *dbstr_arr; dd.any.inout() >>= dbstr_arr; o_str << dbstr_arr->dvalue << endl; o_str << dbstr_arr->svalue; break; default: break; } break; case CORBA::tk_string: Tango::DevEncoded *enc; dd.any.inout() >>= enc; o_str << "Encoding string: " << enc->encoded_format << endl; { long nb_data_elt = enc->encoded_data.length(); for (long i = 0;i < nb_data_elt;i++) { o_str << "Data element number [" << i << "] = " << (int)enc->encoded_data[i]; if (i < (nb_data_elt - 1)) o_str << '\n'; } } break; default: break; } break; case CORBA::tk_enum: Tango::DevState tmp_state; dd.any.inout() >>= tmp_state; o_str << Tango::DevStateName[tmp_state]; break; default: break; } CORBA::release(tc); } return o_str; } } // End of Tango namepsace tango-9.2.5a/lib/cpp/client/devapi_datahist.cpp0000644023471100065110000005671713034744772016424 00000000000000static const char *RcsId = "$Id: devapi_datahist.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; // // devapi_datahist.cpp - C++ source code file for TANGO devapi class // DeviceDataHistory and DeviceAttributeHistory // // programmer(s) - Emmanuel Taurel (taurel@esrf.fr) // // original - June 2002 // // Copyright (C) : 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // // version - $Revision: 27410 $ // #if HAVE_CONFIG_H #include #endif #include #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // DeviceDataHistory::DeviceDataHistory() - constructors to create DeviceDataHistory // //----------------------------------------------------------------------------- DeviceDataHistory::DeviceDataHistory():DeviceData(),ext_hist(Tango_nullptr) { fail = false; err = new DevErrorList(); seq_ptr = NULL; ref_ctr_ptr = NULL; } DeviceDataHistory::DeviceDataHistory(int n, int *ref,DevCmdHistoryList *ptr):ext_hist(Tango_nullptr) { ref_ctr_ptr = ref; seq_ptr = ptr; (*ref_ctr_ptr)++; any = &((*ptr)[n].value); fail = (*ptr)[n].cmd_failed; time = (*ptr)[n].time; err = &((*ptr)[n].errors); } DeviceDataHistory::DeviceDataHistory(const DeviceDataHistory & source):DeviceData(source),ext_hist(Tango_nullptr) { fail = source.fail; time = source.time; err = const_cast(source).err._retn(); seq_ptr = source.seq_ptr; ref_ctr_ptr = source.ref_ctr_ptr; if (ref_ctr_ptr != NULL) (*ref_ctr_ptr)++; #ifdef HAS_UNIQUE_PTR if (source.ext_hist.get() != NULL) { ext_hist.reset(new DeviceDataHistoryExt); *(ext_hist.get()) = *(source.ext_hist.get()); } #else if (source.ext_hist == NULL) ext_hist = NULL; else { ext_hist = new DeviceDataHistoryExt(); *ext_hist = *(source.ext_hist); } #endif } #ifdef HAS_RVALUE DeviceDataHistory::DeviceDataHistory(DeviceDataHistory && source):DeviceData(move(source)),ext_hist(Tango_nullptr) { fail = source.fail; time = source.time; err = source.err._retn(); seq_ptr = source.seq_ptr; ref_ctr_ptr = source.ref_ctr_ptr; if (source.ext_hist.get() != NULL) ext_hist = move(source.ext_hist); else ext_hist.reset(); } #endif //----------------------------------------------------------------------------- // // DeviceDataHistory::~DeviceDataHistory() - Destructor // //----------------------------------------------------------------------------- DeviceDataHistory::~DeviceDataHistory() { if (seq_ptr != NULL) { any._retn(); err._retn(); (*ref_ctr_ptr)--; if (*ref_ctr_ptr == 0) { delete seq_ptr; delete ref_ctr_ptr; } } #ifndef HAS_UNIQUE_PTR delete ext_hist; #endif } //----------------------------------------------------------------------------- // // DeviceDataHistory::operator=() - assignement operator // //----------------------------------------------------------------------------- DeviceDataHistory & DeviceDataHistory::operator=(const DeviceDataHistory &rval) { if (this != &rval) { // // Assignement of DeviceData class members first // this->DeviceData::operator=(rval); // // Then, assignement of DeviceDataHistory members // fail = rval.fail; time = rval.time; #ifdef HAS_RVALUE err = rval.err; #else err = const_cast(rval).err._retn(); #endif if (ref_ctr_ptr != NULL) { (*ref_ctr_ptr)--; if (*ref_ctr_ptr == 0) { delete seq_ptr; delete ref_ctr_ptr; } } seq_ptr = rval.seq_ptr; ref_ctr_ptr = rval.ref_ctr_ptr; (*ref_ctr_ptr)++; #ifdef HAS_UNIQUE_PTR if (rval.ext_hist.get() != NULL) { ext_hist.reset(new DeviceDataHistoryExt); *(ext_hist.get()) = *(rval.ext_hist.get()); } else ext_hist.reset(); #else delete ext_hist; if (rval.ext_hist != NULL) { ext_hist = new DeviceDataHistoryExt(); *ext_hist = *(rval.ext_hist); } else ext_hist = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DeviceDataHistory::operator=() - move assignement operator // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DeviceDataHistory & DeviceDataHistory::operator=(DeviceDataHistory &&rval) { // // Assignement of DeviceData class members first // this->DeviceData::operator=(move(rval)); // // Then, assignement of DeviceDataHistory members // fail = rval.fail; time = rval.time; err = rval.err._retn(); // // Decrement old ctr // if (ref_ctr_ptr != NULL) { (*ref_ctr_ptr)--; if (*ref_ctr_ptr == 0) { delete seq_ptr; delete ref_ctr_ptr; } } // // Copy ctr (but don't increment it) and ptr // seq_ptr = rval.seq_ptr; ref_ctr_ptr = rval.ref_ctr_ptr; // // Extension class // if (rval.ext_hist.get() != NULL) ext_hist = move(rval.ext_hist); else ext_hist.reset(); return *this; } #endif //+------------------------------------------------------------------------- // // operator overloading : << // // description : Friend function to ease printing instance of the // DeviceDataHistory class // //-------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,DeviceDataHistory &dh) { // // First, print date // time_t tmp_val = dh.time.tv_sec; char tmp_date[128]; #ifdef _TG_WINDOWS_ ctime_s(tmp_date,128,&tmp_val); #else ctime_r(&tmp_val,tmp_date); #endif tmp_date[strlen(tmp_date) - 1] = '\0'; o_str << tmp_date; o_str << " (" << dh.time.tv_sec << "," << setw(6) << setfill('0') << dh.time.tv_usec << " sec) : "; // // Print data or error stack // if (dh.fail == true) { unsigned int nb_err = dh.err.in().length(); for (unsigned long i = 0;i < nb_err;i++) { o_str << "Tango error stack" << endl; o_str << "Severity = "; switch ((dh.err.in())[i].severity) { case Tango::WARN : o_str << "WARNING "; break; case Tango::ERR : o_str << "ERROR "; break; case Tango::PANIC : o_str << "PANIC "; break; default : o_str << "Unknown severity code"; break; } o_str << endl; o_str << "Error reason = " << (dh.err.in())[i].reason.in() << endl; o_str << "Desc : " << (dh.err.in())[i].desc.in() << endl; o_str << "Origin : " << (dh.err.in())[i].origin.in(); if (i != nb_err - 1) o_str << endl; } } else { o_str << static_cast(dh); } return o_str; } //----------------------------------------------------------------------------- // // DeviceAttributeHistory::DeviceAttributeHistory() - constructors to create DeviceAttributeHistory // //----------------------------------------------------------------------------- DeviceAttributeHistory::DeviceAttributeHistory():DeviceAttribute(),ext_hist(Tango_nullptr) { fail = false; err_list = new DevErrorList(); } DeviceAttributeHistory::DeviceAttributeHistory(int n,DevAttrHistoryList_var &seq):ext_hist(Tango_nullptr) { fail = seq[n].attr_failed; err_list = new DevErrorList(seq[n].errors); time = seq[n].value.time; quality = seq[n].value.quality; dim_x = seq[n].value.dim_x; dim_y = seq[n].value.dim_y; name = seq[n].value.name; const DevVarLongArray *tmp_seq_lo; CORBA::Long *tmp_lo; const DevVarLong64Array *tmp_seq_lolo; CORBA::LongLong *tmp_lolo; const DevVarShortArray *tmp_seq_sh; CORBA::Short *tmp_sh; const DevVarDoubleArray *tmp_seq_db; CORBA::Double *tmp_db; const DevVarStringArray *tmp_seq_str; char **tmp_str; const DevVarFloatArray *tmp_seq_fl; CORBA::Float *tmp_fl; const DevVarBooleanArray *tmp_seq_boo; CORBA::Boolean *tmp_boo; const DevVarUShortArray *tmp_seq_ush; CORBA::UShort *tmp_ush; const DevVarCharArray *tmp_seq_uch; CORBA::Octet *tmp_uch; const DevVarULongArray *tmp_seq_ulo; CORBA::ULong *tmp_ulo; const DevVarULong64Array *tmp_seq_ulolo; CORBA::ULongLong *tmp_ulolo; const DevVarStateArray *tmp_seq_state; Tango::DevState *tmp_state; CORBA::ULong max,len; if ((fail == false) && (quality != Tango::ATTR_INVALID)) { CORBA::TypeCode_var ty = seq[n].value.value.type(); CORBA::TypeCode_var ty_alias = ty->content_type(); CORBA::TypeCode_var ty_seq = ty_alias->content_type(); switch (ty_seq->kind()) { case tk_long: seq[n].value.value >>= tmp_seq_lo; max = tmp_seq_lo->maximum(); len = tmp_seq_lo->length(); tmp_lo = (const_cast(tmp_seq_lo))->get_buffer((CORBA::Boolean)true); LongSeq = new DevVarLongArray(max,len,tmp_lo,true); break; case tk_longlong: seq[n].value.value >>= tmp_seq_lolo; max = tmp_seq_lolo->maximum(); len = tmp_seq_lolo->length(); tmp_lolo = (const_cast(tmp_seq_lolo))->get_buffer((CORBA::Boolean)true); Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,true); break; case tk_short: seq[n].value.value >>= tmp_seq_sh; max = tmp_seq_sh->maximum(); len = tmp_seq_sh->length(); tmp_sh = (const_cast(tmp_seq_sh))->get_buffer((CORBA::Boolean)true); ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); break; case tk_double: seq[n].value.value >>= tmp_seq_db; max = tmp_seq_db->maximum(); len = tmp_seq_db->length(); tmp_db = (const_cast(tmp_seq_db))->get_buffer((CORBA::Boolean)true); DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); break; case tk_string: seq[n].value.value >>= tmp_seq_str; max = tmp_seq_str->maximum(); len = tmp_seq_str->length(); tmp_str = (const_cast(tmp_seq_str))->get_buffer((CORBA::Boolean)true); StringSeq = new DevVarStringArray(max,len,tmp_str,true); break; case tk_float: seq[n].value.value >>= tmp_seq_fl; max = tmp_seq_fl->maximum(); len = tmp_seq_fl->length(); tmp_fl = (const_cast(tmp_seq_fl))->get_buffer((CORBA::Boolean)true); FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); break; case tk_boolean: seq[n].value.value >>= tmp_seq_boo; max = tmp_seq_boo->maximum(); len = tmp_seq_boo->length(); tmp_boo = (const_cast(tmp_seq_boo))->get_buffer((CORBA::Boolean)true); BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); break; case tk_ushort: seq[n].value.value >>= tmp_seq_ush; max = tmp_seq_ush->maximum(); len = tmp_seq_ush->length(); tmp_ush = (const_cast(tmp_seq_ush))->get_buffer((CORBA::Boolean)true); UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); break; case tk_octet: seq[n].value.value >>= tmp_seq_uch; max = tmp_seq_uch->maximum(); len = tmp_seq_uch->length(); tmp_uch = (const_cast(tmp_seq_uch))->get_buffer((CORBA::Boolean)true); UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); break; case tk_ulong: seq[n].value.value >>= tmp_seq_ulo; max = tmp_seq_ulo->maximum(); len = tmp_seq_ulo->length(); tmp_ulo = (const_cast(tmp_seq_ulo))->get_buffer((CORBA::Boolean)true); ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); break; case tk_ulonglong: seq[n].value.value >>= tmp_seq_ulolo; max = tmp_seq_ulolo->maximum(); len = tmp_seq_ulolo->length(); tmp_ulolo = (const_cast(tmp_seq_ulolo))->get_buffer((CORBA::Boolean)true); ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); break; case tk_enum: seq[n].value.value >>= tmp_seq_state; max = tmp_seq_state->maximum(); len = tmp_seq_state->length(); tmp_state = (const_cast(tmp_seq_state))->get_buffer((CORBA::Boolean)true); StateSeq = new DevVarStateArray(max,len,tmp_state,true); break; default: break; } } } DeviceAttributeHistory::DeviceAttributeHistory(int n,DevAttrHistoryList_3_var &seq):ext_hist(Tango_nullptr) { fail = seq[n].attr_failed; err_list = new DevErrorList(seq[n].value.err_list); time = seq[n].value.time; quality = seq[n].value.quality; dim_x = seq[n].value.r_dim.dim_x; dim_y = seq[n].value.r_dim.dim_y; w_dim_x = seq[n].value.w_dim.dim_x; w_dim_y = seq[n].value.w_dim.dim_y; name = seq[n].value.name; const DevVarLongArray *tmp_seq_lo; CORBA::Long *tmp_lo; const DevVarLong64Array *tmp_seq_lolo; CORBA::LongLong *tmp_lolo; const DevVarShortArray *tmp_seq_sh; CORBA::Short *tmp_sh; const DevVarDoubleArray *tmp_seq_db; CORBA::Double *tmp_db; const DevVarStringArray *tmp_seq_str; char **tmp_str; const DevVarFloatArray *tmp_seq_fl; CORBA::Float *tmp_fl; const DevVarBooleanArray *tmp_seq_boo; CORBA::Boolean *tmp_boo; const DevVarUShortArray *tmp_seq_ush; CORBA::UShort *tmp_ush; const DevVarCharArray *tmp_seq_uch; CORBA::Octet *tmp_uch; const DevVarULongArray *tmp_seq_ulo; CORBA::ULong *tmp_ulo; const DevVarULong64Array *tmp_seq_ulolo; CORBA::ULongLong *tmp_ulolo; const DevVarStateArray *tmp_seq_state; Tango::DevState *tmp_state; CORBA::ULong max,len; if ((fail == false) && (quality != Tango::ATTR_INVALID)) { CORBA::TypeCode_var ty = seq[n].value.value.type(); CORBA::TypeCode_var ty_alias = ty->content_type(); CORBA::TypeCode_var ty_seq = ty_alias->content_type(); switch (ty_seq->kind()) { case tk_long: seq[n].value.value >>= tmp_seq_lo; max = tmp_seq_lo->maximum(); len = tmp_seq_lo->length(); tmp_lo = (const_cast(tmp_seq_lo))->get_buffer((CORBA::Boolean)true); LongSeq = new DevVarLongArray(max,len,tmp_lo,true); break; case tk_longlong: seq[n].value.value >>= tmp_seq_lolo; max = tmp_seq_lolo->maximum(); len = tmp_seq_lolo->length(); tmp_lolo = (const_cast(tmp_seq_lolo))->get_buffer((CORBA::Boolean)true); Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,true); break; case tk_short: seq[n].value.value >>= tmp_seq_sh; max = tmp_seq_sh->maximum(); len = tmp_seq_sh->length(); tmp_sh = (const_cast(tmp_seq_sh))->get_buffer((CORBA::Boolean)true); ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); break; case tk_double: seq[n].value.value >>= tmp_seq_db; max = tmp_seq_db->maximum(); len = tmp_seq_db->length(); tmp_db = (const_cast(tmp_seq_db))->get_buffer((CORBA::Boolean)true); DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); break; case tk_string: seq[n].value.value >>= tmp_seq_str; max = tmp_seq_str->maximum(); len = tmp_seq_str->length(); tmp_str = (const_cast(tmp_seq_str))->get_buffer((CORBA::Boolean)true); StringSeq = new DevVarStringArray(max,len,tmp_str,true); break; case tk_float: seq[n].value.value >>= tmp_seq_fl; max = tmp_seq_fl->maximum(); len = tmp_seq_fl->length(); tmp_fl = (const_cast(tmp_seq_fl))->get_buffer((CORBA::Boolean)true); FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); break; case tk_boolean: seq[n].value.value >>= tmp_seq_boo; max = tmp_seq_boo->maximum(); len = tmp_seq_boo->length(); tmp_boo = (const_cast(tmp_seq_boo))->get_buffer((CORBA::Boolean)true); BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); break; case tk_ushort: seq[n].value.value >>= tmp_seq_ush; max = tmp_seq_ush->maximum(); len = tmp_seq_ush->length(); tmp_ush = (const_cast(tmp_seq_ush))->get_buffer((CORBA::Boolean)true); UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); break; case tk_octet: seq[n].value.value >>= tmp_seq_uch; max = tmp_seq_uch->maximum(); len = tmp_seq_uch->length(); tmp_uch = (const_cast(tmp_seq_uch))->get_buffer((CORBA::Boolean)true); UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); break; case tk_ulong: seq[n].value.value >>= tmp_seq_ulo; max = tmp_seq_ulo->maximum(); len = tmp_seq_ulo->length(); tmp_ulo = (const_cast(tmp_seq_ulo))->get_buffer((CORBA::Boolean)true); ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); break; case tk_ulonglong: seq[n].value.value >>= tmp_seq_ulolo; max = tmp_seq_ulolo->maximum(); len = tmp_seq_ulolo->length(); tmp_ulolo = (const_cast(tmp_seq_ulolo))->get_buffer((CORBA::Boolean)true); ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); break; case tk_enum: seq[n].value.value >>= tmp_seq_state; max = tmp_seq_state->maximum(); len = tmp_seq_state->length(); tmp_state = (const_cast(tmp_seq_state))->get_buffer((CORBA::Boolean)true); StateSeq = new DevVarStateArray(max,len,tmp_state,true); break; default: break; } } } DeviceAttributeHistory::DeviceAttributeHistory(const DeviceAttributeHistory & source):DeviceAttribute(source),ext_hist(Tango_nullptr) { fail = source.fail; #ifdef HAS_UNIQUE_PTR if (source.ext_hist.get() != NULL) { ext_hist.reset(new DeviceAttributeHistoryExt); *(ext_hist.get()) = *(source.ext_hist.get()); } #else if (source.ext_hist == NULL) ext_hist = NULL; else { ext_hist = new DeviceAttributeHistoryExt(); *ext_hist = *(source.ext_hist); } #endif } #ifdef HAS_RVALUE DeviceAttributeHistory::DeviceAttributeHistory(DeviceAttributeHistory &&source):DeviceAttribute(move(source)),ext_hist(Tango_nullptr) { fail = source.fail; if (source.ext_hist.get() != NULL) ext_hist = move(source.ext_hist); } #endif //----------------------------------------------------------------------------- // // DeviceAttributeHistory::~DeviceAttributeHistory() - Destructor // //----------------------------------------------------------------------------- DeviceAttributeHistory::~DeviceAttributeHistory() { #ifndef HAS_UNIQUE_PTR delete ext_hist; #endif } //----------------------------------------------------------------------------- // // DeviceAttributeHistory::operator=() - assignement operator // //----------------------------------------------------------------------------- DeviceAttributeHistory & DeviceAttributeHistory::operator=(const DeviceAttributeHistory &rval) { if (this != &rval) { // // First, assignement of DeviceAttribute class members // this->DeviceAttribute::operator=(rval); // // Then, assignement of DeviceAttributeHistory members // fail = rval.fail; #ifdef HAS_UNIQUE_PTR if (rval.ext_hist.get() != NULL) { ext_hist.reset(new DeviceAttributeHistoryExt); *(ext_hist.get()) = *(rval.ext_hist.get()); } else ext_hist.reset(); #else delete ext_hist; if (rval.ext_hist != NULL) { ext_hist = new DeviceAttributeHistoryExt(); *ext_hist = *(rval.ext_hist); } else ext_hist = NULL; #endif } return *this; } #ifdef HAS_RVALUE DeviceAttributeHistory & DeviceAttributeHistory::operator=(DeviceAttributeHistory &&rval) { // // First, assignement of DeviceAttribute class members // this->DeviceAttribute::operator=(move(rval)); // // Then, assignement of DeviceAttributeHistory members // fail = rval.fail; if (rval.ext_hist.get() != NULL) ext_hist = move(rval.ext_hist); else ext_hist.reset(); return *this; } #endif //+------------------------------------------------------------------------- // // operator overloading : << // // description : Friend function to ease printing instance of the // DeviceAttributeHistory class // //-------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,DeviceAttributeHistory &dah) { // // Print date // if (dah.time.tv_sec != 0) { char tmp_date[128]; time_t tmp_val = dah.time.tv_sec; #ifdef _TG_WINDOWS_ ctime_s(tmp_date,128,&tmp_val); #else ctime_r(&tmp_val,tmp_date); #endif tmp_date[strlen(tmp_date) - 1] = '\0'; o_str << tmp_date; o_str << " (" << dah.time.tv_sec << "," << setw(6) << setfill('0') << dah.time.tv_usec << " sec) : "; } // // print attribute name // o_str << dah.name; // // print dim_x and dim_y // o_str << " (dim_x = " << dah.dim_x << ", dim_y = " << dah.dim_y << ", "; // // print write dim_x and dim_y // o_str << "w_dim_x = " << dah.w_dim_x << ", w_dim_y = " << dah.w_dim_y << ", "; // // Print quality // o_str << "Data quality factor = "; switch (dah.quality) { case Tango::ATTR_VALID: o_str << "VALID)" << endl; break; case Tango::ATTR_INVALID: o_str << "INVALID)"; break; case Tango::ATTR_ALARM: o_str << "ALARM)" << endl; break; case Tango::ATTR_CHANGING: o_str << "CHANGING)" << endl; break; case Tango::ATTR_WARNING: o_str << "WARNING) " << endl; break; } // // Print data (if valid) or error stack // if (dah.fail == true) { unsigned int nb_err = dah.err_list.in().length(); for (unsigned long i = 0;i < nb_err;i++) { o_str << "Tango error stack" << endl; o_str << "Severity = "; switch (dah.err_list[i].severity) { case Tango::WARN : o_str << "WARNING "; break; case Tango::ERR : o_str << "ERROR "; break; case Tango::PANIC : o_str << "PANIC "; break; default : o_str << "Unknown severity code"; break; } o_str << endl; o_str << "Error reason = " << dah.err_list[i].reason.in() << endl; o_str << "Desc : " << dah.err_list[i].desc.in() << endl; o_str << "Origin : " << dah.err_list[i].origin.in(); if (i != nb_err - 1) o_str << endl; } } else { if (dah.quality != Tango::ATTR_INVALID) { if (dah.is_empty() == true) o_str << "No data in DeviceData object"; else { if (dah.LongSeq.operator->() != NULL) o_str << *(dah.LongSeq.operator->()); else if (dah.ShortSeq.operator->() != NULL) o_str << *(dah.ShortSeq.operator->()); else if (dah.DoubleSeq.operator->() != NULL) o_str << *(dah.DoubleSeq.operator->()); else if (dah.FloatSeq.operator->() != NULL) o_str << *(dah.FloatSeq.operator->()); else if (dah.BooleanSeq.operator->() != NULL) o_str << *(dah.BooleanSeq.operator->()); else if (dah.UShortSeq.operator->() != NULL) o_str << *(dah.UShortSeq.operator->()); else if (dah.UCharSeq.operator->() != NULL) o_str << *(dah.UCharSeq.operator->()); else if (dah.Long64Seq.operator->() != NULL) o_str << *(dah.Long64Seq.operator->()); else if (dah.ULongSeq.operator->() != NULL) o_str << *(dah.ULongSeq.operator->()); else if (dah.ULong64Seq.operator->() != NULL) o_str << *(dah.ULong64Seq.operator->()); else if (dah.StateSeq.operator->() != NULL) o_str << *(dah.StateSeq.operator->()); else if (dah.EncodedSeq.operator->() != NULL) o_str << *(dah.EncodedSeq.operator->()); else o_str << *(dah.StringSeq.operator->()); } } } return o_str; } } // End of Tango namepsace tango-9.2.5a/lib/cpp/client/devapi_utils.cpp0000644023471100065110000004347113034744772015754 00000000000000static const char *RcsId = "$Id: devapi_utils.cpp 27410 2015-01-27 05:46:17Z taurel $"; //+================================================================================================================== // devapi_utils.cpp - C++ source code file for TANGO device api // // programmer(s) - Emmanuel Taurel(taurel@esrf.fr) // // original - November 2007 // // Copyright (C) : 2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that 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 Lesser Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //+================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method : // DeviceProxy::from_hist4_2_DataHistory() // // description : // Convert the command history as returned by a IDL 4 device to the classical DeviceDataHistory format // //------------------------------------------------------------------------------------------------------------------- void DeviceProxy::from_hist4_2_DataHistory(DevCmdHistory_4_var &hist_4,vector *ddh) { // // Check received data validity // if ((hist_4->dims.length() != hist_4->dims_array.length()) || (hist_4->errors.length() != hist_4->errors_array.length())) { Tango::Except::throw_exception((const char *)API_WrongHistoryDataBuffer, (const char *)"Data buffer received from server is not valid !", (const char *)"DeviceProxy::from_hist4_2_DataHistory"); } // // Get history depth // unsigned int h_depth = hist_4->dates.length(); // // Copy date in each history list element // unsigned int loop; int k; for (loop = 0;loop < h_depth;loop++) { (*ddh)[loop].set_date(hist_4->dates[loop]); } // // Copy errors // for (loop = 0;loop < hist_4->errors.length();loop++) { int nb_elt = hist_4->errors_array[loop].nb_elt; int start = hist_4->errors_array[loop].start; for (k = 0;k < nb_elt;k++) { (*ddh)[start - k].failed(true); DevErrorList_var del(&hist_4->errors[loop]); (*ddh)[start - k].errors(del); del._retn(); } } // // Create a temporary sequence with record dimension // Tango::AttributeDimList ad(h_depth); ad.length(h_depth); for (loop = 0;loop < hist_4->dims.length();loop++) { int nb_elt = hist_4->dims_array[loop].nb_elt; int start = hist_4->dims_array[loop].start; for (k = 0;k < nb_elt;k++) { ad[start - k].dim_x = hist_4->dims[loop].dim_x; ad[start - k].dim_y = hist_4->dims[loop].dim_y; } } // // Get data ptr and data size // const Tango::DevVarDoubleArray *tmp_db; const Tango::DevVarShortArray *tmp_sh; const Tango::DevVarLongArray *tmp_lg; const Tango::DevVarLong64Array *tmp_lg64; const Tango::DevVarStringArray *tmp_str; const Tango::DevVarFloatArray *tmp_fl; const Tango::DevVarBooleanArray *tmp_boo; const Tango::DevVarUShortArray *tmp_ush; const Tango::DevVarCharArray *tmp_uch; const Tango::DevVarULongArray *tmp_ulg; const Tango::DevVarULong64Array *tmp_ulg64; const Tango::DevVarStateArray *tmp_state; const Tango::DevVarLongStringArray *tmp_lg_str; const Tango::DevVarDoubleStringArray *tmp_db_str; const Tango::DevVarEncodedArray *tmp_enc; unsigned int seq_size = 0; unsigned int seq_size_str = 0; unsigned int seq_size_num = 0; switch (hist_4->cmd_type) { case DEV_LONG: case DEVVAR_LONGARRAY: hist_4->value >>= tmp_lg; seq_size = tmp_lg->length(); break; case DEV_LONG64: case DEVVAR_LONG64ARRAY: hist_4->value >>= tmp_lg64; seq_size = tmp_lg64->length(); break; case DEV_SHORT: case DEVVAR_SHORTARRAY: hist_4->value >>= tmp_sh; seq_size = tmp_sh->length(); break; case DEV_DOUBLE: case DEVVAR_DOUBLEARRAY: hist_4->value >>= tmp_db; seq_size = tmp_db->length(); break; case DEV_STRING: case DEVVAR_STRINGARRAY: hist_4->value >>= tmp_str; seq_size = tmp_str->length(); break; case DEV_FLOAT: case DEVVAR_FLOATARRAY: hist_4->value >>= tmp_fl; seq_size = tmp_fl->length(); break; case DEV_BOOLEAN: hist_4->value >>= tmp_boo; seq_size = tmp_boo->length(); break; case DEV_USHORT: case DEVVAR_USHORTARRAY: hist_4->value >>= tmp_ush; seq_size = tmp_ush->length(); break; case DEVVAR_CHARARRAY: hist_4->value >>= tmp_uch; seq_size = tmp_uch->length(); break; case DEV_ULONG: case DEVVAR_ULONGARRAY: hist_4->value >>= tmp_ulg; seq_size = tmp_ulg->length(); break; case DEV_ULONG64: case DEVVAR_ULONG64ARRAY: hist_4->value >>= tmp_ulg64; seq_size = tmp_ulg64->length(); break; case DEV_STATE: hist_4->value >>= tmp_state; seq_size = tmp_state->length(); break; case DEVVAR_LONGSTRINGARRAY: hist_4->value >>= tmp_lg_str; seq_size_str = tmp_lg_str->svalue.length(); seq_size_num = tmp_lg_str->lvalue.length(); break; case DEVVAR_DOUBLESTRINGARRAY: hist_4->value >>= tmp_db_str; seq_size_str = tmp_db_str->svalue.length(); seq_size_num = tmp_db_str->dvalue.length(); break; case DEV_ENCODED: hist_4->value >>= tmp_enc; seq_size = tmp_enc->length(); break; } // // Copy data // int base = seq_size; int base_str = seq_size_str; int base_num = seq_size_num; for (loop = 0;loop < h_depth;loop++) { if ((*ddh)[loop].failed() == true) continue; // // Get the data length for this record // int data_length = ad[loop].dim_x; int data_num_length = ad[loop].dim_y; // // Real copy now // switch (hist_4->cmd_type) { case Tango::DEV_SHORT: { Tango::DevShort tmp_data = (*tmp_sh)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_SHORTARRAY: { const CORBA::Short *c_seq_buff = tmp_sh->get_buffer(); CORBA::Short *seq_buff = const_cast(c_seq_buff); Tango::DevVarShortArray ShortSeq = DevVarShortArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= ShortSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_LONG: { Tango::DevLong tmp_data = (*tmp_lg)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_LONGARRAY: { const CORBA::Long *c_seq_buff = tmp_lg->get_buffer(); CORBA::Long *seq_buff = const_cast(c_seq_buff); Tango::DevVarLongArray LongSeq = DevVarLongArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= LongSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_FLOAT: { Tango::DevFloat tmp_data = (*tmp_fl)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_FLOATARRAY: { const CORBA::Float *c_seq_buff = tmp_fl->get_buffer(); CORBA::Float *seq_buff = const_cast(c_seq_buff); Tango::DevVarFloatArray FloatSeq = DevVarFloatArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= FloatSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_DOUBLE: { Tango::DevDouble tmp_data = (*tmp_db)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_DOUBLEARRAY: { const CORBA::Double *c_seq_buff = tmp_db->get_buffer(); CORBA::Double *seq_buff = const_cast(c_seq_buff); Tango::DevVarDoubleArray DoubleSeq = DevVarDoubleArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= DoubleSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_LONG64: { Tango::DevLong64 tmp_data = (*tmp_lg64)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_LONG64ARRAY: { const CORBA::LongLong *c_seq_buff = tmp_lg64->get_buffer(); CORBA::LongLong *seq_buff = const_cast(c_seq_buff); Tango::DevVarLong64Array Long64Seq = DevVarLong64Array(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= Long64Seq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_STRING: { Tango::ConstDevString tmp_data = (*tmp_str)[base - 1].in(); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_STRINGARRAY: { const Tango::ConstDevString *c_seq_buff = tmp_str->get_buffer(); char **seq_buff = const_cast(c_seq_buff); Tango::DevVarStringArray StrSeq = DevVarStringArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= StrSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_BOOLEAN: { Tango::DevBoolean tmp_data = (*tmp_boo)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= CORBA::Any::from_boolean(tmp_data); (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_USHORT: { Tango::DevUShort tmp_data = (*tmp_ush)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_USHORTARRAY: { const Tango::DevUShort *c_seq_buff = tmp_ush->get_buffer(); Tango::DevUShort *seq_buff = const_cast(c_seq_buff); Tango::DevVarUShortArray UshSeq = DevVarUShortArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= UshSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_ULONG: { Tango::DevULong tmp_data = (*tmp_ulg)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_ULONGARRAY: { const Tango::DevULong *c_seq_buff = tmp_ulg->get_buffer(); Tango::DevULong *seq_buff = const_cast(c_seq_buff); Tango::DevVarULongArray UlgSeq = DevVarULongArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= UlgSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_ULONG64: { Tango::DevULong64 tmp_data = (*tmp_ulg64)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_ULONG64ARRAY: { const Tango::DevULong64 *c_seq_buff = tmp_ulg64->get_buffer(); Tango::DevULong64 *seq_buff = const_cast(c_seq_buff); Tango::DevVarULong64Array Ulg64Seq = DevVarULong64Array(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= Ulg64Seq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_CHARARRAY: { const Tango::DevUChar *c_seq_buff = tmp_uch->get_buffer(); Tango::DevUChar *seq_buff = const_cast(c_seq_buff); Tango::DevVarCharArray CharSeq = DevVarCharArray(data_length,data_length,&(seq_buff[base - data_length]),false); CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= CharSeq; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_STATE: { Tango::DevState tmp_data = (*tmp_state)[base - 1]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= tmp_data; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_LONGSTRINGARRAY: { Tango::DevVarLongStringArray *dvlsa = new Tango::DevVarLongStringArray(); dvlsa->svalue.length(data_length); dvlsa->lvalue.length(data_num_length); int ll; for (ll = 0;ll < data_length;ll++) dvlsa->svalue[ll] = tmp_lg_str->svalue[(base_str - data_length) + ll]; for (ll = 0;ll < data_num_length;ll++) dvlsa->lvalue[ll] = tmp_lg_str->lvalue[(base_num - data_num_length) + ll]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= dvlsa; (*ddh)[loop].any = any_ptr; } break; case Tango::DEVVAR_DOUBLESTRINGARRAY: { Tango::DevVarDoubleStringArray *dvdsa = new Tango::DevVarDoubleStringArray(); dvdsa->svalue.length(data_length); dvdsa->dvalue.length(data_num_length); int ll; for (ll = 0;ll < data_length;ll++) dvdsa->svalue[ll] = tmp_db_str->svalue[(base_str - data_length) + ll]; for (ll = 0;ll < data_num_length;ll++) dvdsa->dvalue[ll] = tmp_db_str->dvalue[(base_num - data_num_length) + ll]; CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= dvdsa; (*ddh)[loop].any = any_ptr; } break; case Tango::DEV_ENCODED: { /* Tango::DevEncoded &tmp_data = (*tmp_enc)[base - 1]; Tango::DevEncoded EncSeq; EncSeq.encoded_format = CORBA::string_dup(tmp_data.encoded_format); unsigned int buffer_length = tmp_data.encoded_data.length(); EncSeq.encoded_data.length(buffer_length); for (unsigned int ll = 0;ll << buffer_length;++ll) EncSeq.encoded_data[ll] = tmp_data.encoded_data[ll];*/ CORBA::Any *any_ptr = new CORBA::Any(); (*any_ptr) <<= (*tmp_enc)[base - 1]; (*ddh)[loop].any = any_ptr; } break; } if ((hist_4->cmd_type == DEVVAR_LONGSTRINGARRAY) || (hist_4->cmd_type == DEVVAR_DOUBLESTRINGARRAY)) { base_str = base_str - data_length; base_num = base_num - data_num_length; } else base = base - data_length; } } //------------------------------------------------------------------------------------------------------------------- // // Some operator method definition to make Python binding development easier // //------------------------------------------------------------------------------------------------------------------- bool _DevCommandInfo::operator==(const _DevCommandInfo &dci) { return cmd_tag == dci.cmd_tag && cmd_name == dci.cmd_name && in_type == dci.in_type && out_type == dci.out_type; } bool _CommandInfo::operator==(const _CommandInfo &ci) { return _DevCommandInfo::operator==(ci) && disp_level == ci.disp_level; } ostream &operator<<(ostream &o_str,_CommandInfo &ci) { o_str << "Command name = " << ci.cmd_name << endl; o_str << "Command input parameter data type = Tango::" << CmdArgTypeName[ci.in_type] << endl; if (ci.in_type_desc.empty() == false) o_str << "Command input parameter description = " << ci.in_type_desc << endl; o_str << "Command output parameter data type = Tango::" << CmdArgTypeName[ci.out_type] << endl; if (ci.out_type_desc.empty() == false) o_str << "Command output parameter description = " << ci.out_type_desc; return o_str; } bool _DeviceAttributeConfig::operator==(const _DeviceAttributeConfig &dac) { return name == dac.name && writable == dac.writable && data_format == dac.data_format && data_type == dac.data_type && max_dim_x == dac.max_dim_x && max_dim_y == dac.max_dim_y && description == dac.description && label == dac.label && unit == dac.unit && standard_unit == dac.standard_unit && display_unit == dac.display_unit && format == dac.format && min_value == dac.min_value && max_value == dac.max_value && min_alarm == dac.min_alarm && max_alarm == dac.max_alarm && writable_attr_name == dac.writable_attr_name && extensions == dac.extensions; } bool _AttributeInfo::operator==(const _AttributeInfo &ai) { return DeviceAttributeConfig::operator==(ai) && disp_level == ai.disp_level; } bool _AttributeAlarmInfo::operator==(const _AttributeAlarmInfo &aai) { return min_alarm == aai.min_alarm && max_alarm == aai.max_alarm && min_warning == aai.min_warning && max_warning == aai.max_warning && delta_t == aai.delta_t && delta_val == aai.delta_val && extensions == aai.extensions; } bool _AttributeEventInfo::operator==(const _AttributeEventInfo &aei) { return ch_event.rel_change == aei.ch_event.rel_change && ch_event.abs_change == aei.ch_event.abs_change && ch_event.extensions == aei.ch_event.extensions && per_event.period == aei.per_event.period && per_event.extensions == aei.per_event.extensions && arch_event.archive_abs_change == aei.arch_event.archive_abs_change && arch_event.archive_rel_change == aei.arch_event.archive_rel_change && arch_event.archive_period == aei.arch_event.archive_period && arch_event.extensions == aei.arch_event.extensions; } bool _AttributeInfoEx::operator==(const _AttributeInfoEx &aie) { return AttributeInfo::operator==(aie) && alarms.AttributeAlarmInfo::operator==(aie.alarms) && events.AttributeEventInfo::operator==(aie.events) && sys_extensions == aie.sys_extensions && root_attr_name == aie.root_attr_name && memorized == aie.memorized && enum_labels == aie.enum_labels; } } // End of namespace tango-9.2.5a/lib/cpp/client/devapi_pipe.cpp0000644023471100065110000016666613034744772015565 00000000000000static const char *RcsId = "$Id: devapi_pipe.cpp 29869 2016-06-21 14:28:07Z taurel $"; //=================================================================================================================== // // devapi_pipe.cpp - C++ source code file for TANGO devapi class DevicePipe // // programmer(s) - E. Taurel // // original - March 2001 // // Copyright (C) : 2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // version - $Revision: 29869 $ // //==================================================================================================================== #if HAVE_CONFIG_H #include #endif #include using namespace CORBA; namespace Tango { //------------------------------------------------------------------------------------------------------------------ // // method: // DevicePipe::DevicePipe() // // description: // Constructor for DevicePipe class // //------------------------------------------------------------------------------------------------------------------ DevicePipe::DevicePipe():ext(Tango_nullptr) { } DevicePipe::DevicePipe(const string &pipe_name):name(pipe_name),ext(Tango_nullptr) { } DevicePipe::DevicePipe(const string &pipe_name,const string &root_blob_name):name(pipe_name),ext(Tango_nullptr) { the_root_blob.set_name(root_blob_name); } //----------------------------------------------------------------------------- // // DevicePipe::DevicePipe() - copy constructor to create DevicePipe // //----------------------------------------------------------------------------- DevicePipe::DevicePipe(const DevicePipe & source):ext(Tango_nullptr) { name = source.name; time = source.time; the_root_blob = source.the_root_blob; #ifdef HAS_UNIQUE_PTR if (source.ext.get() != NULL) { ext.reset(new DevicePipeExt); *(ext.get()) = *(source.ext.get()); } #else if (source.ext != NULL) { ext = new DevicePipeExt(); *ext = *(source.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // DevicePipe::operator= - assignment operator for DevicePipe class // //----------------------------------------------------------------------------- DevicePipe &DevicePipe::operator=(const DevicePipe &rhs) { if (this != &rhs) { name = rhs.name; time = rhs.time; the_root_blob = rhs.the_root_blob; #ifdef HAS_UNIQUE_PTR if (rhs.ext.get() != NULL) { ext.reset(new DevicePipeExt); *(ext.get()) = *(rhs.ext.get()); } #else if (rhs.ext != NULL) { ext = new DevicePipeExt(); *ext = *(rhs.ext); } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DevicePipe::DevicePipe() - Move copy constructor to create DevicePipe // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DevicePipe::DevicePipe(DevicePipe && source):ext(Tango_nullptr) { name = move(source.name); time = source.time; the_root_blob = move(source.the_root_blob); if (source.ext.get() != NULL) { ext = move(source.ext); } } #endif // HAS_RVALUE //----------------------------------------------------------------------------- // // DevicePipe::operator= - Move assignment operator for DevicePipe class // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DevicePipe &DevicePipe::operator=(DevicePipe &&rhs) { name = move(rhs.name); time = rhs.time; the_root_blob = move(rhs.the_root_blob); if (rhs.ext.get() != NULL) { ext = move(rhs.ext); } else ext.reset(); return *this; } #endif //---------------------------------------------------------------------------------------------------------------- // // DevicePipe::~DevicePipe() - destructor to destroy DevicePipe // //---------------------------------------------------------------------------------------------------------------- DevicePipe::~DevicePipe() { #ifndef HAS_UNIQUE_PTR delete ext; #endif } DevicePipe &DevicePipe::operator[](const string &_na) { the_root_blob.operator[](_na); return *this; } //************************************************************************************************************* // // DevicePipeBlob class // //************************************************************************************************************* //------------------------------------------------------------------------------------------------------------------ // // method: // DevicePipeBlob::DevicePipeBlob() // // description: // Constructor for DevicePipeBlob class // //------------------------------------------------------------------------------------------------------------------ DevicePipeBlob::DevicePipeBlob():failed(false),insert_elt_array(Tango_nullptr),insert_ctr(0), extract_elt_array(Tango_nullptr),extract_ctr(0),extract_delete(false),ext(Tango_nullptr) { exceptions_flags.set(); ext_state.reset(); insert_ind = -1; extract_ind = -1; } DevicePipeBlob::DevicePipeBlob(const string &blob_name):name(blob_name),failed(false), insert_elt_array(Tango_nullptr),insert_ctr(0),extract_elt_array(Tango_nullptr),extract_ctr(0), extract_delete(false),ext(Tango_nullptr) { exceptions_flags.set(); ext_state.reset(); insert_ind = -1; extract_ind = -1; } //---------------------------------------------------------------------------------------------------------------- // // DevicePipeBlob::~DevicePipeBlob() - destructor to destroy DevicePipeBlob instance // //---------------------------------------------------------------------------------------------------------------- DevicePipeBlob::~DevicePipeBlob() { if (extract_delete == true) delete extract_elt_array; #ifndef HAS_UNIQUE_PTR delete ext; #endif } //----------------------------------------------------------------------------- // // DevicePipeBlob::DevicePipeBlob() - copy constructor to create DevicePipeBlob // //----------------------------------------------------------------------------- DevicePipeBlob::DevicePipeBlob(const DevicePipeBlob & source):ext(Tango_nullptr) { name = source.name; exceptions_flags = source.exceptions_flags; ext_state = source.ext_state; failed = source.failed; insert_ind = source.insert_ind; extract_ind = source.extract_ind; if (source.insert_elt_array != Tango_nullptr) { insert_elt_array = new DevVarPipeDataEltArray(); (*insert_elt_array) = (*source.insert_elt_array); } else insert_elt_array = Tango_nullptr; insert_ctr = source.insert_ctr; if (source.extract_elt_array != Tango_nullptr) { DevVarPipeDataEltArray *tmp = new DevVarPipeDataEltArray(); *tmp = (*source.extract_elt_array); set_extract_data(tmp); extract_delete = true; } else { extract_delete = source.extract_delete; } extract_ctr = source.extract_ctr; #ifdef HAS_UNIQUE_PTR if (source.ext.get() != NULL) { ext.reset(new DevicePipeBlobExt); *(ext.get()) = *(source.ext.get()); } #else if (source.ext != NULL) { ext = new DevicePipeBlobExt(); *ext = *(source.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // DevicePipeBlob::operator= - assignment operator for DevicePipeBlob class // //----------------------------------------------------------------------------- DevicePipeBlob &DevicePipeBlob::operator=(const DevicePipeBlob &rhs) { if (this != &rhs) { name = rhs.name; exceptions_flags = rhs.exceptions_flags; ext_state = rhs.ext_state; failed = rhs.failed; insert_ind = rhs.insert_ind; extract_ind = rhs.extract_ind; if (rhs.insert_elt_array != Tango_nullptr) { insert_elt_array = new DevVarPipeDataEltArray(); (*insert_elt_array) = (*rhs.insert_elt_array); } else insert_elt_array = Tango_nullptr; insert_ctr = rhs.insert_ctr; if (rhs.extract_elt_array != Tango_nullptr) { DevVarPipeDataEltArray *tmp = new DevVarPipeDataEltArray(); *tmp = (*rhs.extract_elt_array); set_extract_data(tmp); extract_delete = true; } else { extract_delete = rhs.extract_delete; } extract_ctr = rhs.extract_ctr; #ifdef HAS_UNIQUE_PTR if (rhs.ext.get() != NULL) { ext.reset(new DevicePipeBlobExt); *(ext.get()) = *(rhs.ext.get()); } else ext.reset(); #else delete ext; if (rhs.ext != NULL) { ext = new DevicePipeBlobExt(); *ext = *(rhs.ext); } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // DevicePipeBlob::DevicePipeBlob() - Move copy constructor to create DevicePipeBlob // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DevicePipeBlob::DevicePipeBlob(DevicePipeBlob && source):ext(Tango_nullptr) { name = move(source.name); exceptions_flags = source.exceptions_flags; ext_state = source.ext_state; failed = source.failed; insert_ind = source.insert_ind; extract_ind = source.extract_ind; if (source.insert_elt_array != Tango_nullptr) { insert_elt_array = new DevVarPipeDataEltArray(); (*insert_elt_array) = (*source.insert_elt_array); } else insert_elt_array = Tango_nullptr; insert_ctr = source.insert_ctr; if (source.extract_elt_array != Tango_nullptr) { DevVarPipeDataEltArray *tmp = new DevVarPipeDataEltArray(); *tmp = (*source.extract_elt_array); set_extract_data(tmp); extract_delete = true; } else { extract_delete = source.extract_delete; } extract_ctr = source.extract_ctr; if (source.ext.get() != NULL) { ext = move(source.ext); } } #endif //----------------------------------------------------------------------------- // // DevicePipeBlob::operator= - Move assignment operator for DevicePipeBlob class // //----------------------------------------------------------------------------- #ifdef HAS_RVALUE DevicePipeBlob &DevicePipeBlob::operator=(DevicePipeBlob &&rhs) { name = move(rhs.name); exceptions_flags = rhs.exceptions_flags; ext_state = rhs.ext_state; failed = rhs.failed; insert_ind = rhs.insert_ind; extract_ind = rhs.extract_ind; if (rhs.insert_elt_array != Tango_nullptr) insert_elt_array = rhs.insert_elt_array; rhs.insert_elt_array = Tango_nullptr; insert_ctr = rhs.insert_ctr; if (extract_delete == true) delete extract_elt_array; if (rhs.extract_elt_array != Tango_nullptr) extract_elt_array = rhs.extract_elt_array; rhs.extract_elt_array = Tango_nullptr; extract_delete = rhs.extract_delete; extract_ctr = rhs.extract_ctr; if (rhs.ext.get() != NULL) { ext = move(rhs.ext); } else ext.reset(); return *this; } #endif //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::get_data_elt_name // // description : // Get all data element name // // return: // vector with the data elt name // //------------------------------------------------------------------------------------------------------------------- vector DevicePipeBlob::get_data_elt_names() { if (extract_elt_array == Tango_nullptr) { stringstream ss; ss << "You try to get data element name(s) for a blob which has never been received from a device"; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_data_elt_names()"); } vector v_str; size_t nb_elt = extract_elt_array->length(); for (size_t loop = 0;loop < nb_elt;loop++) { v_str.push_back(string((*extract_elt_array)[loop].name.in())); } return v_str; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::get_data_elt_name // // description : // Get data element name for a single data element // // argument : // in: // - _ind : Data element index in the blob // // return: // The data elt name // //------------------------------------------------------------------------------------------------------------------- string DevicePipeBlob::get_data_elt_name(size_t _ind) { if (extract_elt_array == Tango_nullptr) { stringstream ss; ss << "You try to get data element name(s) for a blob which has never been received from a device"; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_data_elt_names()"); } if (_ind > extract_elt_array->length()) { stringstream ss; ss << "Given index (" << _ind << ") is above the number of data element in the data blob (" << get_data_elt_nb() << ")"; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_data_elt_name()"); } string tmp((*extract_elt_array)[_ind].name.in()); return tmp; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::get_data_elt_type // // description : // Get data element name for a single data element // // argument : // in: // - _ind : Data element index in the blob // // return: // The data elt name // //------------------------------------------------------------------------------------------------------------------- int DevicePipeBlob::get_data_elt_type(size_t _ind) { int ret = 0; if (extract_elt_array == Tango_nullptr) { stringstream ss; ss << "You try to get data element name(s) for a blob which has never been received from a device"; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_data_elt_type()"); } if (_ind > extract_elt_array->length()) { stringstream ss; ss << "Given index (" << _ind << ") is above the number of data element in the data blob (" << get_data_elt_nb() << ")"; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_data_elt_type()"); } // // Do we have a Blob at this index? // if ((*extract_elt_array)[_ind].inner_blob.length() != 0) { ret = DEV_PIPE_BLOB; } else { string d_type = (*extract_elt_array)[_ind].inner_blob_name.in(); switch((*extract_elt_array)[_ind].value._d()) { case ATT_BOOL: { if (d_type == SCALAR_PIPE) ret = DEV_BOOLEAN; else ret = DEVVAR_BOOLEANARRAY; } break; case ATT_SHORT: { if (d_type == SCALAR_PIPE) ret = DEV_SHORT; else ret = DEVVAR_SHORTARRAY; } break; case ATT_LONG: { if (d_type == SCALAR_PIPE) ret = DEV_LONG; else ret = DEVVAR_LONGARRAY; } break; case ATT_LONG64: { if (d_type == SCALAR_PIPE) ret = DEV_LONG64; else ret = DEVVAR_LONG64ARRAY; } break; case ATT_FLOAT: { if (d_type == SCALAR_PIPE) ret = DEV_FLOAT; else ret = DEVVAR_FLOATARRAY; } break; case ATT_DOUBLE: { if (d_type == SCALAR_PIPE) ret = DEV_DOUBLE; else ret = DEVVAR_DOUBLEARRAY; } break; case ATT_UCHAR: { if (d_type == SCALAR_PIPE) ret = DEV_UCHAR; else ret = DEVVAR_CHARARRAY; } break; case ATT_USHORT: { if (d_type == SCALAR_PIPE) ret = DEV_USHORT; else ret = DEVVAR_USHORTARRAY; } break; case ATT_ULONG: { if (d_type == SCALAR_PIPE) ret = DEV_ULONG; else ret = DEVVAR_ULONGARRAY; } break; case ATT_ULONG64: { if (d_type == SCALAR_PIPE) ret = DEV_ULONG64; else ret = DEVVAR_ULONG64ARRAY; } break; case ATT_STRING: { if (d_type == SCALAR_PIPE) ret = DEV_STRING; else ret = DEVVAR_STRINGARRAY; } break; case ATT_STATE: { if (d_type == SCALAR_PIPE) ret = DEV_STATE; else ret = DEVVAR_STATEARRAY; } break; case ATT_ENCODED: { ret = DEV_ENCODED; } break; default: Except::throw_exception(API_PipeWrongArg, "Unsupported data type in data element! (ATT_NO_DATA, DEVICE_STATE)", "DevicePipeBlob::get_data_elt_type()"); break; } } return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::get_extract_ind_from_name // // description : // Get the index of a data element in the extract blob from its name. Throw exception if not found // // argument : // in: // - _na : Data element name // // return: // The data elt index. // //------------------------------------------------------------------------------------------------------------------- size_t DevicePipeBlob::get_extract_ind_from_name(const string &_na) { string lower_name(_na); transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); bool found = false; size_t loop; if (extract_elt_array == Tango_nullptr) { Except::throw_exception(API_PipeNoDataElement, "No data element available for extraction", "DevicePipeBlob::get_extract_ind_from_name()"); } if (extract_ctr > 0) { Except::throw_exception(API_NotSupportedFeature, "Not supported to mix extraction type (operator >> and operator [])", "DevicePipeBlob::get_extract_ind_from_name()"); } for (loop = 0;loop < extract_elt_array->length();loop++) { string tmp((*extract_elt_array)[loop].name.in()); transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); if (tmp == lower_name) { found = true; break; } } if (found == false) { stringstream ss; ss << "Can't get data element with name " << _na; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_extract_ind_from_name()"); } extract_ctr = -1; return loop; } size_t DevicePipeBlob::get_insert_ind_from_name(const string &_na) { string lower_name(_na); transform(lower_name.begin(),lower_name.end(),lower_name.begin(),::tolower); bool found = false; size_t loop; if (insert_elt_array == Tango_nullptr) { Except::throw_exception(API_PipeNoDataElement, "No data element available for insertion", "DevicePipeBlob::get_insert_ind_from_name()"); } if (insert_ctr > 0) { Except::throw_exception(API_NotSupportedFeature, "Not supported to mix insertion type (operator << and operator [])", "DevicePipeBlob::get_insert_ind_from_name()"); } for (loop = 0;loop < insert_elt_array->length();loop++) { string tmp((*insert_elt_array)[loop].name.in()); transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); if (tmp == lower_name) { found = true; break; } } if (found == false) { stringstream ss; ss << "Can't get data element with name " << _na; Except::throw_exception(API_PipeWrongArg,ss.str(),"DevicePipeBlob::get_insert_ind_from_name()"); } insert_ctr = -1; return loop; } //------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::operator[] // // description : // Return the object itself with the extract counter set to the ind of the data element with name given as // parameter. This allows user to write code like // pipe_blob["MyDataElt"] >> sh; // // argument : // in: // - _na : Data element name // // return: // The DevicePipeBlob object itself // //------------------------------------------------------------------------------------------------------------------- DevicePipeBlob &DevicePipeBlob::operator[](const string &_na) { int ind; try { ind = get_extract_ind_from_name(_na); extract_ind = ind; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason != API_PipeNoDataElement) throw; } try { ind = get_insert_ind_from_name(_na); insert_ind = ind; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason != API_PipeNoDataElement) throw; } return *this; } //------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::set_data_elt_names // // description : // Set the blob data element name(s) // // argument : // in: // - elt_names : Vector with data elements name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::set_data_elt_names(vector &elt_names) { // // Check that we do not have two times the same DE name (case independant) // if (elt_names.size() > 1) { unsigned int i; vector same_de = elt_names; for (i = 0;i < same_de.size();++i) transform(same_de[i].begin(),same_de[i].end(),same_de[i].begin(),::tolower); sort(same_de.begin(),same_de.end()); vector same_de_lower = same_de; vector::iterator pos = unique(same_de.begin(),same_de.end()); int duplicate_de; duplicate_de = distance(elt_names.begin(),elt_names.end()) - distance(same_de.begin(),pos); if (duplicate_de != 0) { stringstream desc; desc << "Several times the same data element name in provided vector: "; int ctr = 0; for (i = 0;i < same_de_lower.size() - 1;i++) { if (same_de_lower[i] == same_de_lower[i + 1]) { ctr++; desc << same_de_lower[i]; if (ctr < duplicate_de) desc << ", "; } } ApiConnExcept::throw_exception(API_PipeDuplicateDEName,desc.str(),"set_data_elt_names"); } } // // Init insert elt array and set names // insert_elt_array = new DevVarPipeDataEltArray(); insert_elt_array->length(elt_names.size()); for (size_t loop = 0;loop < elt_names.size();loop++) { (*insert_elt_array)[loop].name = CORBA::string_dup(elt_names[loop].c_str()); (*insert_elt_array)[loop].value.union_no_data(true); (*insert_elt_array)[loop].inner_blob.length(0); } insert_ctr = 0; extract_ctr = 0; insert_ind = -1; extract_ind = -1; } //------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::set_data_elt_nb // // description : // Set the blob data element number // // argument : // in: // - _nb : The data elements number // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::set_data_elt_nb(size_t _nb) { insert_elt_array = new DevVarPipeDataEltArray(); insert_elt_array->length(_nb); for (size_t loop = 0;loop < _nb;loop++) { (*insert_elt_array)[loop].value.union_no_data(true); (*insert_elt_array)[loop].inner_blob.length(0); } insert_ctr = 0; extract_ctr = 0; insert_ind = -1; extract_ind = -1; } //------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::set_current_delt_name // // description : // Set the data element name. This method create the pipe data elt array (insert) if not already done // // argument : // in: // - _na : The data elements name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::set_current_delt_name(const string &_na) { if (insert_elt_array == Tango_nullptr) { insert_elt_array = new DevVarPipeDataEltArray(10); insert_elt_array->length(1); (*insert_elt_array)[0].value.union_no_data(true); (*insert_elt_array)[0].inner_blob.length(0); insert_ctr = 0; extract_ctr = 0; insert_ind = -1; extract_ind = -1; } else if (insert_ctr == (int)insert_elt_array->length()) { insert_elt_array->length(insert_elt_array->length() + 1); (*insert_elt_array)[insert_ctr].value.union_no_data(true); (*insert_elt_array)[insert_ctr].inner_blob.length(0); } (*insert_elt_array)[insert_ctr].name = CORBA::string_dup(_na.c_str()); } //------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::get_data_elt_nb() // // description : // Get the data element number in the blob // // return : // The data element number // //------------------------------------------------------------------------------------------------------------------- size_t DevicePipeBlob::get_data_elt_nb() { size_t ret; if (extract_elt_array == Tango_nullptr) { if (insert_elt_array == Tango_nullptr) ret = 0; else ret = insert_elt_array->length(); } else ret = extract_elt_array->length(); return ret; } //****************************************************************************************************************** DevicePipeBlob & DevicePipeBlob::operator<<(DevBoolean &datum) { INSERT_BASIC_TYPE(DevVarBooleanArray,bool_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(short &datum) { INSERT_BASIC_TYPE(DevVarShortArray,short_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevLong &datum) { INSERT_BASIC_TYPE(DevVarLongArray,long_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevLong64 &datum) { INSERT_BASIC_TYPE(DevVarLong64Array,long64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(float &datum) { INSERT_BASIC_TYPE(DevVarFloatArray,float_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(double &datum) { INSERT_BASIC_TYPE(DevVarDoubleArray,double_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevUChar &datum) { INSERT_BASIC_TYPE(DevVarUCharArray,uchar_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevUShort &datum) { INSERT_BASIC_TYPE(DevVarUShortArray,ushort_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevULong &datum) { INSERT_BASIC_TYPE(DevVarULongArray,ulong_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevULong64 &datum) { INSERT_BASIC_TYPE(DevVarULong64Array,ulong64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevString &datum) { failed = false; ext_state.reset(); if (insert_elt_array == Tango_nullptr) ext_state.set(blobdenamenotset_flag); else if (insert_ctr == -1 && insert_ind == -1) ext_state.set(mixing_flag); else { size_t nb_insert = insert_elt_array->length(); if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) ext_state.set(notenoughde_flag); else { DevVarStringArray dvsa; dvsa.length(1); dvsa[0] = CORBA::string_dup(datum); if (insert_ind != -1) { (*insert_elt_array)[insert_ind].value.string_att_value(dvsa); (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup("Scalar"); insert_ind = -1; } else { (*insert_elt_array)[insert_ctr].value.string_att_value(dvsa); (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup("Scalar"); insert_ctr++; } } } if (ext_state.any() == true) failed = true; if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) throw_name_not_set("operator<<"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator<<",false); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevState &datum) { INSERT_BASIC_TYPE(DevVarStateArray,state_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevEncoded &datum) { INSERT_BASIC_TYPE(DevVarEncodedArray,encoded_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(const string &datum) { failed = false; ext_state.reset(); if (insert_elt_array == Tango_nullptr) ext_state.set(blobdenamenotset_flag); else if (insert_ctr == -1 && insert_ind == -1) ext_state.set(mixing_flag); else { size_t nb_insert = insert_elt_array->length(); if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) ext_state.set(notenoughde_flag); else { DevVarStringArray dvsa; dvsa.length(1); dvsa[0] = CORBA::string_dup(datum.c_str()); if (insert_ind != -1) { (*insert_elt_array)[insert_ind].value.string_att_value(dvsa); (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup("Scalar"); insert_ind = -1; } else { (*insert_elt_array)[insert_ctr].value.string_att_value(dvsa); (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup("Scalar"); insert_ctr++; } } } if (ext_state.any() == true) failed = true; if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) throw_name_not_set("operator<<"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator<<",false); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevicePipeBlob &datum) { failed = false; ext_state.reset(); if (insert_elt_array == Tango_nullptr) ext_state.set(blobdenamenotset_flag); else if (insert_ctr == -1 && insert_ind == -1) ext_state.set(mixing_flag); else { size_t nb_insert = insert_elt_array->length(); if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) ext_state.set(notenoughde_flag); else { DevVarPipeDataEltArray *tmp_ptr = datum.get_insert_data(); if (tmp_ptr != Tango_nullptr) { CORBA::ULong max,len; max = tmp_ptr->maximum(); len = tmp_ptr->length(); if (insert_ind != -1) { (*insert_elt_array)[insert_ind].inner_blob.replace(max,len,tmp_ptr->get_buffer((CORBA::Boolean)true),true); (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(datum.get_name().c_str()); insert_ind = -1; } else { (*insert_elt_array)[insert_ctr].inner_blob.replace(max,len,tmp_ptr->get_buffer((CORBA::Boolean)true),true); (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(datum.get_name().c_str()); insert_ctr++; } delete tmp_ptr; } } } if (ext_state.any() == true) failed = true; if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) throw_name_not_set("operator<<"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator<<",false); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); return *this; } //--------------------------------------------------------------------------------------------------------------- DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { failed = false; ext_state.reset(); if (insert_elt_array == Tango_nullptr) ext_state.set(blobdenamenotset_flag); else if (insert_ctr == -1 && insert_ind == -1) ext_state.set(mixing_flag); else { size_t nb_insert = insert_elt_array->length(); if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) ext_state.set(notenoughde_flag); else { DevVarBooleanArray dvsa; if (insert_ind != -1) { (*insert_elt_array)[insert_ind].value.bool_att_value(dvsa); DevVarBooleanArray &dvsb = (*insert_elt_array)[insert_ind].value.bool_att_value(); dvsb << datum; insert_ind = -1; } else { (*insert_elt_array)[insert_ctr].value.bool_att_value(dvsa); DevVarBooleanArray &dvsb = (*insert_elt_array)[insert_ctr].value.bool_att_value(); dvsb << datum; insert_ctr++; } } } if (ext_state.any() == true) failed = true; if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) throw_name_not_set("operator<<"); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator<<",false); return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarShortArray,short_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarLongArray,long_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarLong64Array,long64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarFloatArray,float_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarDoubleArray,double_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarUCharArray,uchar_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarUShortArray,ushort_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarULongArray,ulong_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarULong64Array,ulong64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarStringArray,string_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarStateArray,state_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { INSERT_VECTOR_TYPE(DevVarEncodedArray,encoded_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(vector &datum) { failed = false; ext_state.reset(); if (insert_elt_array == Tango_nullptr) ext_state.set(blobdenamenotset_flag); else if (insert_ctr == -1 && insert_ind == -1) ext_state.set(mixing_flag); else { size_t nb_insert = insert_elt_array->length(); if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) ext_state.set(notenoughde_flag); else { size_t nb = datum.size(); char **strvec = DevVarStringArray::allocbuf(nb); for (size_t i = 0;i < nb;i++) strvec[i] = CORBA::string_dup(datum[i].c_str()); DevVarStringArray dvsa; if (insert_ind != -1) { (*insert_elt_array)[insert_ind].value.string_att_value(dvsa); DevVarStringArray &dvsb = (*insert_elt_array)[insert_ind].value.string_att_value(); dvsb.replace(datum.size(),datum.size(),strvec,true); insert_ind = -1; } else { (*insert_elt_array)[insert_ctr].value.string_att_value(dvsa); DevVarStringArray &dvsb = (*insert_elt_array)[insert_ctr].value.string_att_value(); dvsb.replace(datum.size(),datum.size(),strvec,true); insert_ctr++; } } } if (ext_state.any() == true) failed = true; if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) throw_name_not_set("operator<<"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator<<",false); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); return *this; } //--------------------------------------------------------------------------------------------------------------- DevicePipeBlob & DevicePipeBlob::operator<<(DevVarBooleanArray &datum) { INSERT_SEQ_TYPE(DevVarBooleanArray,bool_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarShortArray &datum) { INSERT_SEQ_TYPE(DevVarShortArray,short_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarLongArray &datum) { INSERT_SEQ_TYPE(DevVarLongArray,long_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarLong64Array &datum) { INSERT_SEQ_TYPE(DevVarLong64Array,long64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarFloatArray &datum) { INSERT_SEQ_TYPE(DevVarFloatArray,float_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarDoubleArray &datum) { INSERT_SEQ_TYPE(DevVarDoubleArray,double_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarUCharArray &datum) { INSERT_SEQ_TYPE(DevVarUCharArray,uchar_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarUShortArray &datum) { INSERT_SEQ_TYPE(DevVarUShortArray,ushort_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarULongArray &datum) { INSERT_SEQ_TYPE(DevVarULongArray,ulong_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarULong64Array &datum) { INSERT_SEQ_TYPE(DevVarULong64Array,ulong64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarStringArray &datum) { INSERT_SEQ_TYPE(DevVarStringArray,string_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarStateArray &datum) { INSERT_SEQ_TYPE(DevVarStateArray,state_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarEncodedArray &datum) { INSERT_SEQ_TYPE(DevVarEncodedArray,encoded_att_value) return *this; } //--------------------------------------------------------------------------------------------------------------- DevicePipeBlob & DevicePipeBlob::operator<<(DevVarBooleanArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarBooleanArray,bool_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarShortArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarShortArray,short_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarLongArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarLongArray,long_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarLong64Array *datum) { INSERT_SEQ_PTR_TYPE(DevVarLong64Array,long64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarFloatArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarFloatArray,float_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarDoubleArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarDoubleArray,double_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarUCharArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarUCharArray,uchar_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarUShortArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarUShortArray,ushort_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarULongArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarULongArray,ulong_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarULong64Array *datum) { INSERT_SEQ_PTR_TYPE(DevVarULong64Array,ulong64_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarStringArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarStringArray,string_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarStateArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarStateArray,state_att_value) return *this; } DevicePipeBlob & DevicePipeBlob::operator<<(DevVarEncodedArray *datum) { INSERT_SEQ_PTR_TYPE(DevVarEncodedArray,encoded_att_value) return *this; } //****************************************************************************************************************** DevicePipeBlob &DevicePipeBlob::operator >> (DevBoolean &datum) { EXTRACT_BASIC_TYPE(ATT_BOOL,bool_att_value,"DevBoolean") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (short &datum) { EXTRACT_BASIC_TYPE(ATT_SHORT,short_att_value,"DevShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevLong &datum) { EXTRACT_BASIC_TYPE(ATT_LONG,long_att_value,"DevLong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevLong64 &datum) { EXTRACT_BASIC_TYPE(ATT_LONG64,long64_att_value,"DevLong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (float &datum) { EXTRACT_BASIC_TYPE(ATT_FLOAT,float_att_value,"DevFloat") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (double &datum) { EXTRACT_BASIC_TYPE(ATT_DOUBLE,double_att_value,"DevDouble") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevUChar &datum) { EXTRACT_BASIC_TYPE(ATT_UCHAR,uchar_att_value,"DevUChar") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevUShort &datum) { EXTRACT_BASIC_TYPE(ATT_USHORT,ushort_att_value,"DevUShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevULong &datum) { EXTRACT_BASIC_TYPE(ATT_ULONG,ulong_att_value,"DevULong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevULong64 &datum) { EXTRACT_BASIC_TYPE(ATT_ULONG64,ulong64_att_value,"DevULong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevString &datum) { failed = false; ext_state.reset(); if (extract_elt_array == Tango_nullptr) ext_state.set(isempty_flag); else if (extract_ctr > (int)extract_elt_array->length() - 1) ext_state.set(notenoughde_flag); else if (extract_ctr == -1 && extract_ind == -1) ext_state.set(mixing_flag); else { int ind; if (extract_ind != -1) ind = extract_ind; else ind = extract_ctr; const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); AttributeDataType adt = uni_ptr->_d(); if (adt != ATT_STRING) { if (adt == ATT_NO_DATA) { if ((*extract_elt_array)[ind].inner_blob.length() == 0) ext_state.set(isempty_flag); } else ext_state.set(wrongtype_flag); } else { datum = CORBA::string_dup((uni_ptr->string_att_value())[0].in()); if (extract_ind != -1) extract_ind = -1; else extract_ctr++; } } if (ext_state.any() == true) failed = true; if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) throw_is_empty("operator>>"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator>>",true); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) throw_type_except("DevString","operator>>"); return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevState &datum) { EXTRACT_BASIC_TYPE(ATT_STATE,state_att_value,"DevState") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevEncoded &datum) { EXTRACT_BASIC_TYPE(ATT_ENCODED,encoded_att_value,"DevEncoded") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (string &datum) { EXTRACT_BASIC_TYPE(ATT_STRING,string_att_value,"DevString") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevicePipeBlob &datum) { failed = false; ext_state.reset(); if (extract_elt_array == Tango_nullptr) ext_state.set(isempty_flag); else if (extract_ctr > (int)extract_elt_array->length() - 1) ext_state.set(notenoughde_flag); else if (extract_ctr == -1 && extract_ind == -1) ext_state.set(mixing_flag); else { int ind; if (extract_ind != -1) ind = extract_ind; else ind = extract_ctr; if ((*extract_elt_array)[ind].inner_blob.length() == 0) { if ((*extract_elt_array)[ind].value._d() == ATT_NO_DATA) ext_state.set(isempty_flag); else ext_state.set(wrongtype_flag); } else { datum.set_extract_data(&((*extract_elt_array)[ind].inner_blob)); string tmp((*extract_elt_array)[ind].inner_blob_name.in()); datum.set_name(tmp); datum.reset_extract_ctr(); if (extract_ind != -1) extract_ind = -1; else extract_ctr++; } } if (ext_state.any() == true) failed = true; if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) throw_is_empty("operator>>"); if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) throw_too_many("operator>>",true); if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) throw_mixing("operator>>"); if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) throw_type_except("DevicePipeBlob","operator>>"); return *this; } //---------------------------------------------------------------------------------------------------------- DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_BOOL,bool_att_value,DevVarBooleanArray,"DevBoolean") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_SHORT,short_att_value,DevVarShortArray,"DevShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_LONG,long_att_value,DevVarLongArray,"DevLong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_LONG64,long64_att_value,DevVarLong64Array,"DevLong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_FLOAT,float_att_value,DevVarFloatArray,"DevFloat") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_DOUBLE,double_att_value,DevVarDoubleArray,"DevDouble") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_UCHAR,uchar_att_value,DevVarUCharArray,"DevUChar") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_USHORT,ushort_att_value,DevVarUShortArray,"DevUShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_ULONG,ulong_att_value,DevVarULongArray,"DevULong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_ULONG64,ulong64_att_value,DevVarULong64Array,"DevULong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_STRING,string_att_value,DevVarStringArray,"DevString") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_STATE,state_att_value,DevVarStateArray,"DevState") return *this; } /*DevicePipeBlob &DevicePipeBlob::operator >> (vector &datum) { EXTRACT_VECTOR_TYPE(ATT_ENCODED,encoded_att_value,DevVarEncodedArray,"DevEncoded") return *this; }*/ //---------------------------------------------------------------------------------------------------------- DevicePipeBlob &DevicePipeBlob::operator >> (DevVarBooleanArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_BOOL,bool_att_value,DevVarBooleanArray,"DevBoolean") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarShortArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_SHORT,short_att_value,DevVarShortArray,"DevShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarLongArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_LONG,long_att_value,DevVarLongArray,"DevLong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarLong64Array *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_LONG64,long64_att_value,DevVarLong64Array,"DevLong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarFloatArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_FLOAT,float_att_value,DevVarFloatArray,"DevFloat") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarDoubleArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_DOUBLE,double_att_value,DevVarDoubleArray,"DevDouble") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarUCharArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_UCHAR,uchar_att_value,DevVarUCharArray,"DevUChar") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarUShortArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_USHORT,ushort_att_value,DevVarUShortArray,"DevUShort") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarULongArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_ULONG,ulong_att_value,DevVarULongArray,"DevULong") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarULong64Array *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_ULONG64,ulong64_att_value,DevVarULong64Array,"DevULong64") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarStringArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_STRING,string_att_value,DevVarStringArray,"DevString") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarStateArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_STATE,state_att_value,DevVarStateArray,"DevState") return *this; } DevicePipeBlob &DevicePipeBlob::operator >> (DevVarEncodedArray *datum) { EXTRACT_SEQ_PTR_TYPE(ATT_ENCODED,encoded_att_value,DevVarEncodedArray,"DevEncoded") return *this; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::has_failed // // description : // Throw exception when wrong data type is used // // return: // True if previous insertion/extraction has failed for one reason or another // //------------------------------------------------------------------------------------------------------------------- bool DevicePipeBlob::has_failed() { if (failed == true) { delete insert_elt_array; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } } return failed; } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::throw_type_except // // description : // Throw exception when wrong data type is used // // argument: // in : // - _ty: data type name // - _meth : Caller method name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::throw_type_except(const string &_ty,const string &_meth) { delete insert_elt_array; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } stringstream ss; ss << "Can't get data element " << extract_ctr << " (numbering starting from 0) into a " << _ty << " data type"; string m_name("DevicePipeBlob::"); m_name = m_name + _meth; ApiDataExcept::throw_exception(API_IncompatibleArgumentType,ss.str(),m_name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::throw_too_many // // description : // Throw exception when user try to insert/extract too many data from the blob // // argument: // in : // - _meth : Caller method name // - _extract : Flag set to true if this method is called during extraction. Otherwise, false // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::throw_too_many(const string &_meth,bool _extract) { stringstream ss; ss << "Not enough data element in blob ("; if (_extract == true) ss << get_data_elt_nb(); else ss << insert_elt_array->length(); ss << " data elt in created/received blob)"; string m_name("DevicePipeBlob::"); m_name = m_name + _meth; delete insert_elt_array; insert_elt_array = Tango_nullptr; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } ApiDataExcept::throw_exception(API_PipeWrongArg,ss.str(),m_name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::throw_is_empty // // description : // Throw exception when user try to insert/extract data from one empty data element // // argument: // in : // - _meth : Caller method name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::throw_is_empty(const string &_meth) { delete insert_elt_array; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } string m_name("DevicePipeBlob::"); m_name = m_name + _meth; ApiDataExcept::throw_exception(API_EmptyDataElement,"The data element is empty",m_name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::throw_name_not_set // // description : // Throw exception when user try to insert data into a device blob while the DE name/nb not set // // argument: // in : // - _meth : Caller method name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::throw_name_not_set(const string &_meth) { delete insert_elt_array; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } string m_name("DevicePipeBlob::"); m_name = m_name + _meth; ApiDataExcept::throw_exception(API_PipeNoDataElement,"The blob data element number (or name) not set",m_name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method : // DevicePipeBlob::throw_mixing // // description : // Throw exception when user try to mix [] and >> (<<) insertion/extraction method // // argument: // in : // - _meth : Caller method name // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::throw_mixing(const string &_meth) { delete insert_elt_array; if (extract_delete == true) { delete extract_elt_array; extract_delete = false; } string m_name("DevicePipeBlob::"); m_name = m_name + _meth; Except::throw_exception(API_NotSupportedFeature, "Not supported to mix extraction type (operator >> (or <<) and operator [])",m_name.c_str()); } //+------------------------------------------------------------------------------------------------------------------ // // method // DevicePipeBlob::print // // description : // Print blob content. Due to recusrsive type, it was not possible to write this feature as a classical // << operator. // // argument: // in : // - o_str : The stream used for printing // - indent : Indentation level for printing in case of blob inside blob // - insert_extract: Flag set to true is insert data should be printed, else extract data are printed // //------------------------------------------------------------------------------------------------------------------- void DevicePipeBlob::print(ostream &o_str,int indent,bool insert_extract) { // // Print blob name (if any) // if (name.size() != 0 && insert_extract == true) { int max = indent; if (indent > 1) max--; for (int loop = 0;loop < max;loop++) o_str << "\t"; o_str << "Blob name = " << name << endl; } // // Data element name/value // const DevVarPipeDataEltArray *dvpdea; if (insert_extract == false) dvpdea = get_extract_data(); else dvpdea = get_insert_data(); if (dvpdea != Tango_nullptr) { for (size_t ctr = 0;ctr < dvpdea->length();ctr++) { for (int loop = 0;loop < indent;loop++) o_str << "\t"; o_str << "Data element name = " << (*dvpdea)[ctr].name.in() << endl; for (int loop = 0;loop < indent;loop++) o_str<< "\t"; o_str << "Data element value:" << endl; // // Print indent level // for (int loop = 0;loop < indent;loop++) o_str << "\t"; // // Print data element value // switch ((*dvpdea)[ctr].value._d()) { case ATT_BOOL: { const DevVarBooleanArray &dvba = (*dvpdea)[ctr].value.bool_att_value(); o_str << dvba; } break; case ATT_SHORT: { const DevVarShortArray &dvsa = (*dvpdea)[ctr].value.short_att_value(); o_str << dvsa; } break; case ATT_LONG: { const DevVarLongArray &dvla = (*dvpdea)[ctr].value.long_att_value(); o_str << dvla; } break; case ATT_LONG64: { const DevVarLong64Array &dvlo64 = (*dvpdea)[ctr].value.long64_att_value(); o_str << dvlo64; } break; case ATT_FLOAT: { const DevVarFloatArray &dvfa = (*dvpdea)[ctr].value.float_att_value(); o_str << dvfa; } break; case ATT_DOUBLE: { const DevVarDoubleArray &dvda = (*dvpdea)[ctr].value.double_att_value(); o_str << dvda; } break; case ATT_UCHAR: { const DevVarCharArray &dvda = (*dvpdea)[ctr].value.uchar_att_value(); o_str << dvda; } break; case ATT_USHORT: { const DevVarUShortArray &dvda = (*dvpdea)[ctr].value.ushort_att_value(); o_str << dvda; } break; case ATT_ULONG: { const DevVarULongArray &dvda = (*dvpdea)[ctr].value.ulong_att_value(); o_str << dvda; } break; case ATT_ULONG64: { const DevVarULong64Array &dvda = (*dvpdea)[ctr].value.ulong64_att_value(); o_str << dvda; } break; case ATT_STRING: { const DevVarStringArray &dvda = (*dvpdea)[ctr].value.string_att_value(); o_str << dvda; } break; case ATT_STATE: { const DevVarStateArray &dvda = (*dvpdea)[ctr].value.state_att_value(); o_str << dvda; } break; case ATT_ENCODED: { const DevVarEncodedArray &dvda = (*dvpdea)[ctr].value.encoded_att_value(); o_str << dvda; } break; case DEVICE_STATE: o_str << "Unsupported data type in data element (ATT_NO_DATA, DEVICE_STATE)!" << endl; break; default: break; } // // Print inner blob if any // if ((*dvpdea)[ctr].inner_blob.length() != 0) { DevicePipeBlob dpb((*dvpdea)[ctr].inner_blob_name.in()); dpb.set_extract_data(&(*dvpdea)[ctr].inner_blob); dpb.print(o_str,indent + 1,true); dpb.print(o_str,indent + 1,false); } if (ctr < dvpdea->length() - 1) o_str << endl; } } } //+------------------------------------------------------------------------------------------------------------------ // // Function // operator overloading : << // // description : // Friend function to ease printing instance of the DevicePipe class // //------------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,DevicePipe &dd) { // // Pipe date // if (dd.time.tv_sec != 0) { time_t tmp_val = dd.time.tv_sec; char tmp_date[128]; #ifdef _TG_WINDOWS_ ctime_s(tmp_date,128,&tmp_val); #else ctime_r(&tmp_val,tmp_date); #endif tmp_date[strlen(tmp_date) - 1] = '\0'; o_str << tmp_date; o_str << " (" << dd.time.tv_sec << "," << dd.time.tv_usec << " sec) : "; } // // Print pipe name // o_str << dd.name << endl; // // Print blob // DevicePipeBlob &dpb = dd.get_root_blob(); if (dpb.get_insert_data() == Tango_nullptr && dpb.get_extract_data() == Tango_nullptr) o_str << "DevicePipe is empty"; else { dpb.print(o_str,0,true); dpb.print(o_str,0,false); } return o_str; } DevicePipe &operator>>(DevicePipe &_dp,char *&datum) { _dp.get_root_blob().operator>>(datum); return _dp; } } // End of Tango namepsace tango-9.2.5a/lib/cpp/client/api_util.cpp0000644023471100065110000017064413034744771015074 00000000000000static const char *RcsId = "$Id: api_util.cpp 30271 2016-11-09 12:19:27Z bourtemb $\n$Name$"; //+================================================================================================================== // // C++ source code file for TANGO api class ApiUtil // // programmer - Emmanuel Taurel (taurel@esrf.fr) // // Copyright (C) : 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that 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 Lesser Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // original - May 2002 // // $Revision: 30271 $ // //+================================================================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifndef _TG_WINDOWS_ #include #include #include #include #include #include #include #ifdef HAS_THREAD #include #endif #include // FreeBSD #else #include #include #endif namespace Tango { ApiUtil *ApiUtil::_instance = NULL; omni_mutex ApiUtil::inst_mutex; #ifdef HAS_THREAD void _killproc_() { ::exit(-1); } #endif // HAS_THREAD void _t_handler (TANGO_UNUSED(int signum)) { #ifdef HAS_THREAD thread t(_killproc_); t.detach(); #else _KillProc_ *t = new _KillProc_; t->start(); #endif Tango_sleep(3); } //+----------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::ApiUtil() // // description : // Constructor of the ApiUtil class. // //------------------------------------------------------------------------------------------------------------------ ApiUtil::ApiUtil():exit_lock_installed(false),reset_already_executed_flag(false),ext(new ApiUtilExt), notifd_event_consumer(NULL),cl_pid(0),user_connect_timeout(-1),zmq_event_consumer(NULL),user_sub_hwm(-1) { _orb = CORBA::ORB::_nil(); // // Check if it is created from a device server // if (Util::_constructed == true) in_serv = true; else in_serv = false; // // Create the Asynchronous polling request Id generator // UniqIdent *ui = new UniqIdent(); // // Create the table used to store asynchronous polling requests // asyn_p_table = new AsynReq(ui); // // Set the asynchronous callback mode to "ON_CALL" // auto_cb = PULL_CALLBACK; cb_thread_ptr = NULL; // // Get the process PID // #ifdef _TG_WINDOWS_ cl_pid = _getpid(); #else cl_pid = getpid(); #endif // // Check if the user has defined his own connection timeout // string var; if (get_env_var("TANGOconnectTimeout",var) == 0) { int user_to = -1; istringstream iss(var); iss >> user_to; if (iss) user_connect_timeout = user_to; } // // Check if the user has defined his own subscriber hwm (fpr zmq event tuning) // var.clear(); if (get_env_var("TANGO_EVENT_BUFFER_HWM",var) == 0) { int sub_hwm = -1; istringstream iss(var); iss >> sub_hwm; if (iss) user_sub_hwm = sub_hwm; } } //+---------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::~ApiUtil() // // description : // Destructor of the ApiUtil class. // //------------------------------------------------------------------------------------------------------------------ ApiUtil::~ApiUtil() { // // Release Asyn stuff // delete asyn_p_table; if (cb_thread_ptr != NULL) { cb_thread_cmd.stop_thread(); cb_thread_ptr->join(0); } // // Kill any remaining locking threads // clean_locking_threads(); // // Release event stuff (in case it is necessary) // bool event_was_used = false; #ifdef HAS_UNIQUE_PTR if (ext.get() != NULL) #else if (ext != NULL) #endif { if ((notifd_event_consumer != NULL) || (zmq_event_consumer != NULL)) { event_was_used = true; leavefunc(); NotifdEventConsumer::cleanup(); ZmqEventConsumer::cleanup(); } #ifndef HAS_UNIQUE_PTR delete ext; #endif } // // Delete the database object // for (unsigned int i = 0;i < db_vect.size();i++) { delete db_vect[i]; } // // Properly shutdown the ORB // if ((in_serv == false) && (CORBA::is_nil(_orb) == false)) { if (event_was_used == false) { try { _orb->destroy(); } catch (...) {} } CORBA::release(_orb); } } //------------------------------------------------------------------------------------------------------------------ // // method : // ApiUtil::set_sig_handler() // // description : // Install a signal handler for SIGINT and SIGTERM but only if nothing is already installed // //------------------------------------------------------------------------------------------------------------------- void ApiUtil::set_sig_handler() { #ifndef _TG_WINDOWS_ if (in_serv == false) { struct sigaction sa,old_action; sa.sa_handler = _t_handler; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGTERM,NULL,&old_action) != -1) { if (old_action.sa_handler == NULL) sigaction(SIGTERM,&sa,NULL); } if (sigaction(SIGINT,NULL,&old_action) != -1) { if (old_action.sa_handler == NULL) sigaction(SIGINT,&sa,NULL); } } #endif } //------------------------------------------------------------------------------------------------------------------ // // method : // ApiUtil::create_orb() // // description : // Create the CORBA orb object // //------------------------------------------------------------------------------------------------------------------- void ApiUtil::create_orb() { int _argc; char **_argv; // // pass dummy arguments to init() because we don't have access to argc and argv // _argc = 1; _argv = (char**)malloc(sizeof(char*)); _argv[0] = (char*)"dummy"; // // Get user signal handler for SIGPIPE (ORB_init call install a SIG_IGN for SIGPIPE. This could be annoying in case // the user uses SIGPIPE) // #ifndef _TG_WINDOWS_ struct sigaction sa; sa.sa_handler = NULL; if (sigaction(SIGPIPE,NULL,&sa) == -1) sa.sa_handler = NULL; #endif // // Init the ORB // Starting with omniORB 4.2, we need to add the throwTransientOnTimeout option for compatibility // bool omni_42_compat = false; CORBA::ULong omni_vers_hex = omniORB::versionHex(); if (omni_vers_hex > 0x04020000) omni_42_compat = true; const char *options[][2] = { {"clientCallTimeOutPeriod",CLNT_TIMEOUT_STR}, {"verifyObjectExistsAndType","0"}, {"maxGIOPConnectionPerServer",MAX_GIOP_PER_SERVER}, {"giopMaxMsgSize",MAX_TRANSFER_SIZE}, {"throwTransientOnTimeOut","1"}, {0,0}}; if (omni_42_compat == false) { int nb_opt = sizeof(options) / sizeof (char *[2]); options[nb_opt - 2][0] = NULL; options[nb_opt - 2][1] = NULL; } _orb = CORBA::ORB_init(_argc,_argv,"omniORB4",options); free(_argv); // // Restore SIGPIPE handler // #ifndef _TG_WINDOWS_ if (sa.sa_handler != NULL) { struct sigaction sb; sb = sa; if (sigaction(SIGPIPE,&sb,NULL) == -1) { cerr << "Can re-install user signal handler for SIGPIPE!" << endl; } } #endif } //--------------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::get_db_ind() // // description : // Retrieve a Tango database object created from the TANGO_HOST environment variable // //-------------------------------------------------------------------------------------------------------------------- int ApiUtil::get_db_ind() { omni_mutex_lock lo(the_mutex); for (unsigned int i = 0;i < db_vect.size();i++) { if (db_vect[i]->get_from_env_var() == true) return i; } // // The database object has not been found, create it // db_vect.push_back(new Database()); return (db_vect.size() - 1); } int ApiUtil::get_db_ind(string &host,int port) { omni_mutex_lock lo(the_mutex); for (unsigned int i = 0;i < db_vect.size();i++) { if (db_vect[i]->get_db_port_num() == port) { if (db_vect[i]->get_db_host() == host) return i; } } // // The database object has not been found, create it // db_vect.push_back(new Database(host,port)); return (db_vect.size() - 1); } //------------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::get_asynch_replies() // // description : // Try to obtain data returned by a command asynchronously requested. This method does not block if the reply is // not yet arrived. Fire callback for replies already arrived // //------------------------------------------------------------------------------------------------------------------ void ApiUtil::get_asynch_replies() { // // First get all replies from ORB buffers // try { while (_orb->poll_next_response() == true) { CORBA::Request_ptr req; _orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = asyn_p_table->get_request(req); tg_req.arrived = true; asyn_p_table->mark_as_arrived(req); // // Process request // switch (tg_req.req_type) { case TgRequest::CMD_INOUT : tg_req.dev->Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : tg_req.dev->Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : tg_req.dev->Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } tg_req.dev->dec_asynch_counter(CALL_BACK); asyn_p_table->remove_request(tg_req.dev,req); } } catch (CORBA::BAD_INV_ORDER &e) { if (e.minor() != omni::BAD_INV_ORDER_RequestNotSentYet) throw; } // // For all replies already there // multimap::iterator pos; multimap &req_table = asyn_p_table->get_cb_dev_table(); for (pos = req_table.begin();pos != req_table.end();++pos) { if (pos->second.arrived == true) { switch (pos->second.req_type) { case TgRequest::CMD_INOUT : pos->first->Cb_Cmd_Request(pos->second.request,pos->second.cb_ptr); break; case TgRequest::READ_ATTR : pos->first->Cb_ReadAttr_Request(pos->second.request,pos->second.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : pos->first->Cb_WriteAttr_Request(pos->second.request,pos->second.cb_ptr); break; } pos->first->dec_asynch_counter(CALL_BACK); asyn_p_table->remove_request(pos->first,pos->second.request); } } } //------------------------------------------------------------------------------------------------------------------ // // method : // ApiUtil::get_asynch_replies() // // description : // Try to obtain data returned by a command asynchronously requested. This method does not block if the reply is // not yet arrived. Fire callback for replies already arrived // // arg(s) : // in : // - call_timeout : The timeout value in mS // //----------------------------------------------------------------------------- void ApiUtil::get_asynch_replies(long call_timeout) { // // For all replies already there // multimap::iterator pos; multimap &req_table = asyn_p_table->get_cb_dev_table(); for (pos = req_table.begin();pos != req_table.end();++pos) { if (pos->second.arrived == true) { switch (pos->second.req_type) { case TgRequest::CMD_INOUT : pos->first->Cb_Cmd_Request(pos->second.request,pos->second.cb_ptr); break; case TgRequest::READ_ATTR : pos->first->Cb_ReadAttr_Request(pos->second.request,pos->second.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : pos->first->Cb_WriteAttr_Request(pos->second.request,pos->second.cb_ptr); break; } pos->first->dec_asynch_counter(CALL_BACK); asyn_p_table->remove_request(pos->first,pos->second.request); } } // // If they are requests already sent but without being replied yet // if (asyn_p_table->get_cb_request_nb() != 0) { CORBA::Request_ptr req; if (call_timeout != 0) { // // A timeout has been specified. Wait if there are still request without replies but not more than the specified // timeout. Leave method if the timeout is not arrived but there is no more request without reply // long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif while ((nb > 0) && (asyn_p_table->get_cb_request_nb() != 0)) { #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif nb--; try { if (_orb->poll_next_response() == true) { _orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = asyn_p_table->get_request(req); tg_req.arrived = true; asyn_p_table->mark_as_arrived(req); // // Is it a request for our device, process it ? // switch (tg_req.req_type) { case TgRequest::CMD_INOUT : tg_req.dev->Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : tg_req.dev->Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : tg_req.dev->Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } tg_req.dev->dec_asynch_counter(CALL_BACK); asyn_p_table->remove_request(tg_req.dev,req); } } catch (CORBA::BAD_INV_ORDER &e) { if (e.minor() != omni::BAD_INV_ORDER_RequestNotSentYet) throw; } } // // Throw exception if the timeout has expired but there are still request without replies // if ((nb == 0) && (asyn_p_table->get_cb_request_nb() != 0)) { TangoSys_OMemStream desc; desc << "Still some reply(ies) for asynchronous callback call(s) to be received" << ends; ApiAsynNotThereExcept::throw_exception((const char *)API_AsynReplyNotArrived, desc.str(), (const char *)"ApiUtil::get_asynch_replies"); } } else { // // If timeout is set to 0, this means wait until all the requests sent to this device has sent their replies // while (asyn_p_table->get_cb_request_nb() != 0) { try { _orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = asyn_p_table->get_request(req); tg_req.arrived = true; asyn_p_table->mark_as_arrived(req); // // Process the reply // switch (tg_req.req_type) { case TgRequest::CMD_INOUT : tg_req.dev->Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : tg_req.dev->Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : tg_req.dev->Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } tg_req.dev->dec_asynch_counter(CALL_BACK); asyn_p_table->remove_request(tg_req.dev,req); } catch (CORBA::BAD_INV_ORDER &e) { if (e.minor() != omni::BAD_INV_ORDER_RequestNotSentYet) throw; } } } } } //------------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::set_asynch_cb_sub_model() // // description : // Set the callback automatic mode (Fired by dedicated call or automatically fired by a separate thread) // // arg(s) : // in : // - mode : The new callback mode // //-------------------------------------------------------------------------------------------------------------------- void ApiUtil::set_asynch_cb_sub_model(cb_sub_model mode) { if (auto_cb == PULL_CALLBACK) { if (mode == PUSH_CALLBACK) { // // In this case, delete the old object in case it is needed, create a new thread and start it // delete cb_thread_ptr; cb_thread_ptr = NULL; cb_thread_cmd.start_thread(); cb_thread_ptr = new CallBackThread(cb_thread_cmd,asyn_p_table); cb_thread_ptr->start(); auto_cb = PUSH_CALLBACK; } } else { if (mode == PULL_CALLBACK) { // // Ask the thread to stop and to exit // cb_thread_cmd.stop_thread(); auto_cb = PULL_CALLBACK; asyn_p_table->signal(); } } } //----------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::create_xxx_event_consumer() // // description : // Create the event consumer. This will automatically start a new thread which is waiting in a CORBA::run() // indefintely for events. It will then trigger the events. // //---------------------------------------------------------------------------------------------------------------- void ApiUtil::create_notifd_event_consumer() { notifd_event_consumer = NotifdEventConsumer::create(); } void ApiUtil::create_zmq_event_consumer() { zmq_event_consumer = ZmqEventConsumer::create(); } NotifdEventConsumer *ApiUtil::get_notifd_event_consumer() { return notifd_event_consumer; } ZmqEventConsumer *ApiUtil::get_zmq_event_consumer() { return zmq_event_consumer; } //+----------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::clean_locking_threads() // // description : // Ask all remaining locking threads to exit // // args : // in : // - clean : // //------------------------------------------------------------------------------------------------------------------ void ApiUtil::clean_locking_threads(bool clean) { omni_mutex_lock oml(lock_th_map); if (lock_threads.empty() == false) { map::iterator pos; for (pos = lock_threads.begin();pos != lock_threads.end();++pos) { if (pos->second.shared->suicide == true) { delete pos->second.shared; delete pos->second.mon; } else { { omni_mutex_lock sync(*(pos->second.mon)); pos->second.shared->cmd_pending = true; if (clean == true) pos->second.shared->cmd_code = LOCK_UNLOCK_ALL_EXIT; else pos->second.shared->cmd_code = LOCK_EXIT; pos->second.mon->signal(); cout4 << "Cmd sent to locking thread" << endl; if (pos->second.shared->cmd_pending == true) pos->second.mon->wait(DEFAULT_TIMEOUT); } delete pos->second.shared; delete pos->second.mon; } } if (clean == false) lock_threads.clear(); } } //----------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::attr_to_device() // // description : // // //------------------------------------------------------------------------------------------------------------------- void ApiUtil::attr_to_device(const AttributeValue *attr_value,const AttributeValue_3 *attr_value_3, long vers,DeviceAttribute *dev_attr) { const DevVarLongArray *tmp_seq_lo; CORBA::Long *tmp_lo; const DevVarShortArray *tmp_seq_sh; CORBA::Short *tmp_sh; const DevVarDoubleArray *tmp_seq_db; CORBA::Double *tmp_db; const DevVarStringArray *tmp_seq_str; char **tmp_str; const DevVarFloatArray *tmp_seq_fl; CORBA::Float *tmp_fl; const DevVarBooleanArray *tmp_seq_boo; CORBA::Boolean *tmp_boo; const DevVarUShortArray *tmp_seq_ush; CORBA::UShort *tmp_ush; const DevVarCharArray *tmp_seq_uch; CORBA::Octet *tmp_uch; const DevVarLong64Array *tmp_seq_64; CORBA::LongLong *tmp_lolo; const DevVarULongArray *tmp_seq_ulo; CORBA::ULong *tmp_ulo; const DevVarULong64Array *tmp_seq_u64; CORBA::ULongLong *tmp_ulolo; const DevVarStateArray *tmp_seq_state; Tango::DevState *tmp_state; CORBA::ULong max,len; if (vers == 3) { dev_attr->name = attr_value_3->name; dev_attr->quality = attr_value_3->quality; dev_attr->time = attr_value_3->time; dev_attr->dim_x = attr_value_3->r_dim.dim_x; dev_attr->dim_y = attr_value_3->r_dim.dim_y; dev_attr->set_w_dim_x(attr_value_3->w_dim.dim_x); dev_attr->set_w_dim_y(attr_value_3->w_dim.dim_y); dev_attr->err_list = new DevErrorList(attr_value_3->err_list); } else { dev_attr->name = attr_value->name; dev_attr->quality = attr_value->quality; dev_attr->time = attr_value->time; dev_attr->dim_x = attr_value->dim_x; dev_attr->dim_y = attr_value->dim_y; } if (dev_attr->quality != Tango::ATTR_INVALID) { CORBA::TypeCode_var ty; if (vers == 3) ty = attr_value_3->value.type(); else ty = attr_value->value.type(); if (ty->kind() == CORBA::tk_enum) { attr_value_3->value >>= dev_attr->d_state; dev_attr->d_state_filled = true; return; } CORBA::TypeCode_var ty_alias = ty->content_type(); CORBA::TypeCode_var ty_seq = ty_alias->content_type(); switch (ty_seq->kind()) { case CORBA::tk_long: if (vers == 3) attr_value_3->value >>= tmp_seq_lo; else attr_value->value >>= tmp_seq_lo; max = tmp_seq_lo->maximum(); len = tmp_seq_lo->length(); if (tmp_seq_lo->release() == true) { tmp_lo = (const_cast(tmp_seq_lo))->get_buffer((CORBA::Boolean)true); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,true); } else { tmp_lo = const_cast(tmp_seq_lo->get_buffer()); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,false); } break; case CORBA::tk_longlong: if (vers == 3) attr_value_3->value >>= tmp_seq_64; else attr_value->value >>= tmp_seq_64; max = tmp_seq_64->maximum(); len = tmp_seq_64->length(); if (tmp_seq_64->release() == true) { tmp_lolo = (const_cast(tmp_seq_64))->get_buffer((CORBA::Boolean)true); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,true); } else { tmp_lolo = const_cast(tmp_seq_64->get_buffer()); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,false); } break; case CORBA::tk_short: if (vers == 3) attr_value_3->value >>= tmp_seq_sh; else attr_value->value >>= tmp_seq_sh; max = tmp_seq_sh->maximum(); len = tmp_seq_sh->length(); if (tmp_seq_sh->release() == true) { tmp_sh = (const_cast(tmp_seq_sh))->get_buffer((CORBA::Boolean)true); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); } else { tmp_sh = const_cast(tmp_seq_sh->get_buffer()); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,false); } break; case CORBA::tk_double: if (vers == 3) attr_value_3->value >>= tmp_seq_db; else attr_value->value >>= tmp_seq_db; max = tmp_seq_db->maximum(); len = tmp_seq_db->length(); if (tmp_seq_db->release() == true) { tmp_db = (const_cast(tmp_seq_db))->get_buffer((CORBA::Boolean)true); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); } else { tmp_db = const_cast(tmp_seq_db->get_buffer()); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,false); } break; case CORBA::tk_string: if (vers == 3) attr_value_3->value >>= tmp_seq_str; else attr_value->value >>= tmp_seq_str; max = tmp_seq_str->maximum(); len = tmp_seq_str->length(); if (tmp_seq_str->release() == true) { tmp_str = (const_cast(tmp_seq_str))->get_buffer((CORBA::Boolean)true); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,true); } else { tmp_str = const_cast(tmp_seq_str->get_buffer()); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,false); } break; case CORBA::tk_float: if (vers == 3) attr_value_3->value >>= tmp_seq_fl; else attr_value->value >>= tmp_seq_fl; max = tmp_seq_fl->maximum(); len = tmp_seq_fl->length(); if (tmp_seq_fl->release() == true) { tmp_fl = (const_cast(tmp_seq_fl))->get_buffer((CORBA::Boolean)true); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); } else { tmp_fl = const_cast(tmp_seq_fl->get_buffer()); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,false); } break; case CORBA::tk_boolean: if (vers == 3) attr_value_3->value >>= tmp_seq_boo; else attr_value->value >>= tmp_seq_boo; max = tmp_seq_boo->maximum(); len = tmp_seq_boo->length(); if (tmp_seq_boo->release() == true) { tmp_boo = (const_cast(tmp_seq_boo))->get_buffer((CORBA::Boolean)true); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); } else { tmp_boo = const_cast(tmp_seq_boo->get_buffer()); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,false); } break; case CORBA::tk_ushort: if (vers == 3) attr_value_3->value >>= tmp_seq_ush; else attr_value->value >>= tmp_seq_ush; max = tmp_seq_ush->maximum(); len = tmp_seq_ush->length(); if (tmp_seq_ush->release() == true) { tmp_ush = (const_cast(tmp_seq_ush))->get_buffer((CORBA::Boolean)true); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); } else { tmp_ush = const_cast(tmp_seq_ush->get_buffer()); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,false); } break; case CORBA::tk_octet: if (vers == 3) attr_value_3->value >>= tmp_seq_uch; else attr_value->value >>= tmp_seq_uch; max = tmp_seq_uch->maximum(); len = tmp_seq_uch->length(); if (tmp_seq_uch->release() == true) { tmp_uch = (const_cast(tmp_seq_uch))->get_buffer((CORBA::Boolean)true); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); } else { tmp_uch = const_cast(tmp_seq_uch->get_buffer()); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,false); } break; case CORBA::tk_ulong: if (vers == 3) attr_value_3->value >>= tmp_seq_ulo; else attr_value->value >>= tmp_seq_ulo; max = tmp_seq_ulo->maximum(); len = tmp_seq_ulo->length(); if (tmp_seq_ulo->release() == true) { tmp_ulo = (const_cast(tmp_seq_ulo))->get_buffer((CORBA::Boolean)true); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); } else { tmp_ulo = const_cast(tmp_seq_ulo->get_buffer()); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,false); } break; case CORBA::tk_ulonglong: if (vers == 3) attr_value_3->value >>= tmp_seq_u64; else attr_value->value >>= tmp_seq_u64; max = tmp_seq_u64->maximum(); len = tmp_seq_u64->length(); if (tmp_seq_u64->release() == true) { tmp_ulolo = (const_cast(tmp_seq_u64))->get_buffer((CORBA::Boolean)true); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); } else { tmp_ulolo = const_cast(tmp_seq_u64->get_buffer()); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,false); } break; case CORBA::tk_enum: if (vers == 3) attr_value_3->value >>= tmp_seq_state; else attr_value->value >>= tmp_seq_state; max = tmp_seq_state->maximum(); len = tmp_seq_state->length(); if (tmp_seq_state->release() == true) { tmp_state = (const_cast(tmp_seq_state))->get_buffer((CORBA::Boolean)true); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,true); } else { tmp_state = const_cast(tmp_seq_state->get_buffer()); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,false); } break; default: break; } dev_attr->data_type = Tango::DEV_SHORT; } } void ApiUtil::attr_to_device(const AttributeValue_4 *attr_value_4,TANGO_UNUSED(long vers),DeviceAttribute *dev_attr) { attr_to_device_base(attr_value_4,dev_attr); // // Warning: Since Tango 9, data type SHORT is used for both short attribute and enumeration attribute! // Therefore, we need to store somewhere which exact type it is. With IDL 5, it is easy, because the data type is // transferred on the network (modified IDL), For previous release, we do not have enumerated data type and therefore // the data type could be used only for SHORT. // dev_attr->data_type = Tango::DEV_SHORT; } void ApiUtil::attr_to_device(const AttributeValue_5 *attr_value_5,TANGO_UNUSED(long vers),DeviceAttribute *dev_attr) { attr_to_device_base(attr_value_5,dev_attr); dev_attr->data_type = attr_value_5->data_type; } //------------------------------------------------------------------------------------------------------------------ // // method : // ApiUtil::device_to_attr() // // description : // initialize one AttributeValue instance from a DeviceAttribute one // // arg(s) : // in : // - dev_attr : The DeviceAttribute instance taken as source // out : // - att : The AttributeValue used as destination // //--------------------------------------------------------------------------------------------------------------- void ApiUtil::device_to_attr(const DeviceAttribute &dev_attr,AttributeValue_4 &att) { att.name = dev_attr.name.c_str(); att.quality = dev_attr.quality; att.time = dev_attr.time; att.w_dim.dim_x = dev_attr.dim_x; att.w_dim.dim_y = dev_attr.dim_y; att.data_format = Tango::FMT_UNKNOWN; if (dev_attr.LongSeq.operator->() != NULL) att.value.long_att_value(dev_attr.LongSeq.in()); else if (dev_attr.ShortSeq.operator->() != NULL) att.value.short_att_value(dev_attr.ShortSeq.in()); else if (dev_attr.DoubleSeq.operator->() != NULL) att.value.double_att_value(dev_attr.DoubleSeq.in()); else if (dev_attr.StringSeq.operator->() != NULL) att.value.string_att_value(dev_attr.StringSeq.in()); else if (dev_attr.FloatSeq.operator->() != NULL) att.value.float_att_value(dev_attr.FloatSeq.in()); else if (dev_attr.BooleanSeq.operator->() != NULL) att.value.bool_att_value(dev_attr.BooleanSeq.in()); else if (dev_attr.UShortSeq.operator->() != NULL) att.value.ushort_att_value(dev_attr.UShortSeq.in()); else if (dev_attr.UCharSeq.operator->() != NULL) att.value.uchar_att_value(dev_attr.UCharSeq.in()); else if (dev_attr.Long64Seq.operator->() != NULL) att.value.long64_att_value(dev_attr.Long64Seq.in()); else if (dev_attr.ULongSeq.operator->() != NULL) att.value.ulong_att_value(dev_attr.ULongSeq.in()); else if (dev_attr.ULong64Seq.operator->() != NULL) att.value.ulong64_att_value(dev_attr.ULong64Seq.in()); else if (dev_attr.StateSeq.operator->() != NULL) att.value.state_att_value(dev_attr.StateSeq.in()); else if (dev_attr.EncodedSeq.operator->() != NULL) att.value.encoded_att_value(dev_attr.EncodedSeq.in()); } void ApiUtil::device_to_attr(const DeviceAttribute &dev_attr,AttributeValue &att,string &d_name) { att.name = dev_attr.name.c_str(); att.quality = dev_attr.quality; att.time = dev_attr.time; att.dim_x = dev_attr.dim_x; att.dim_y = dev_attr.dim_y; if (dev_attr.LongSeq.operator->() != NULL) att.value <<= dev_attr.LongSeq.in(); else if (dev_attr.ShortSeq.operator->() != NULL) att.value <<= dev_attr.ShortSeq.in(); else if (dev_attr.DoubleSeq.operator->() != NULL) att.value <<= dev_attr.DoubleSeq.in(); else if (dev_attr.StringSeq.operator->() != NULL) att.value <<= dev_attr.StringSeq.in(); else if (dev_attr.FloatSeq.operator->() != NULL) att.value <<= dev_attr.FloatSeq.in(); else if (dev_attr.BooleanSeq.operator->() != NULL) att.value <<= dev_attr.BooleanSeq.in(); else if (dev_attr.UShortSeq.operator->() != NULL) att.value <<= dev_attr.UShortSeq.in(); else if (dev_attr.UCharSeq.operator->() != NULL) att.value <<= dev_attr.UCharSeq.in(); else if (dev_attr.Long64Seq.operator->() != NULL) att.value <<= dev_attr.Long64Seq.in(); else if (dev_attr.ULongSeq.operator->() != NULL) att.value <<= dev_attr.ULongSeq.in(); else if (dev_attr.ULong64Seq.operator->() != NULL) att.value <<= dev_attr.ULong64Seq.in(); else if (dev_attr.StateSeq.operator->() != NULL) att.value <<= dev_attr.StateSeq.in(); else if (dev_attr.EncodedSeq.operator->() != NULL) { TangoSys_OMemStream desc; desc << "Device " << d_name; desc << " does not support DevEncoded data type" << ends; ApiNonSuppExcept::throw_exception((const char *)API_UnsupportedFeature, desc.str(), (const char *)"DeviceProxy::device_to_attr"); } } //------------------------------------------------------------------------------------------------------------------ // // method : // ApiUtil::AttributeInfoEx_to_AttributeConfig() // // description : // Initialize one AttributeConfig instance from a AttributeInfoEx one // // arg(s) : // in : // - aie : The AttributeInfoEx instance taken as source // out : // - att_conf_5 : The AttributeConfig used as destination // //------------------------------------------------------------------------------------------------------------------ void ApiUtil::AttributeInfoEx_to_AttributeConfig(const AttributeInfoEx *aie,AttributeConfig_5 *att_conf_5) { att_conf_5->name = aie->name.c_str(); att_conf_5->writable = aie->writable; att_conf_5->data_format = aie->data_format; att_conf_5->data_type = aie->data_type; att_conf_5->max_dim_x = aie->max_dim_x; att_conf_5->max_dim_y = aie->max_dim_y; att_conf_5->description = aie->description.c_str(); att_conf_5->label = aie->label.c_str(); att_conf_5->unit = aie->unit.c_str(); att_conf_5->standard_unit = aie->standard_unit.c_str(); att_conf_5->display_unit = aie->display_unit.c_str(); att_conf_5->format = aie->format.c_str(); att_conf_5->min_value = aie->min_value.c_str(); att_conf_5->max_value = aie->max_value.c_str(); att_conf_5->writable_attr_name = aie->writable_attr_name.c_str(); att_conf_5->level = aie->disp_level; att_conf_5->root_attr_name = aie->root_attr_name.c_str(); switch(aie->memorized) { case NOT_KNOWN: case NONE: att_conf_5->memorized = false; att_conf_5->mem_init = false; break; case MEMORIZED: att_conf_5->memorized = true; att_conf_5->mem_init = false; break; case MEMORIZED_WRITE_INIT: att_conf_5->memorized = true; att_conf_5->mem_init = true; break; default: break; } att_conf_5->enum_labels.length(aie->enum_labels.size()); for (size_t j=0; jenum_labels.size(); j++) { att_conf_5->enum_labels[j] = string_dup(aie->enum_labels[j].c_str()); } att_conf_5->extensions.length(aie->extensions.size()); for (size_t j=0; jextensions.size(); j++) { att_conf_5->extensions[j] = string_dup(aie->extensions[j].c_str()); } for (size_t j=0; jsys_extensions.size(); j++) { att_conf_5->sys_extensions[j] = string_dup(aie->sys_extensions[j].c_str()); } att_conf_5->att_alarm.min_alarm = aie->alarms.min_alarm.c_str(); att_conf_5->att_alarm.max_alarm = aie->alarms.max_alarm.c_str(); att_conf_5->att_alarm.min_warning = aie->alarms.min_warning.c_str(); att_conf_5->att_alarm.max_warning = aie->alarms.max_warning.c_str(); att_conf_5->att_alarm.delta_t = aie->alarms.delta_t.c_str(); att_conf_5->att_alarm.delta_val = aie->alarms.delta_val.c_str(); for (size_t j=0; jalarms.extensions.size(); j++) { att_conf_5->att_alarm.extensions[j] = string_dup(aie->alarms.extensions[j].c_str()); } att_conf_5->event_prop.ch_event.rel_change = aie->events.ch_event.rel_change.c_str(); att_conf_5->event_prop.ch_event.abs_change = aie->events.ch_event.abs_change.c_str(); for (size_t j=0; jevents.ch_event.extensions.size(); j++) { att_conf_5->event_prop.ch_event.extensions[j] = string_dup(aie->events.ch_event.extensions[j].c_str()); } att_conf_5->event_prop.per_event.period = aie->events.per_event.period.c_str(); for (size_t j=0; jevents.per_event.extensions.size(); j++) { att_conf_5->event_prop.per_event.extensions[j] = string_dup(aie->events.per_event.extensions[j].c_str()); } att_conf_5->event_prop.arch_event.rel_change = aie->events.arch_event.archive_rel_change.c_str(); att_conf_5->event_prop.arch_event.abs_change = aie->events.arch_event.archive_abs_change.c_str(); att_conf_5->event_prop.arch_event.period = aie->events.arch_event.archive_period.c_str(); for (size_t j=0; jevents.ch_event.extensions.size(); j++) { att_conf_5->event_prop.arch_event.extensions[j] = string_dup(aie->events.arch_event.extensions[j].c_str()); } } //------------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::get_env_var() // // description : // Get environment variable // // arg(s) : // in : // - env_var_name : The environment variable name // out : // - env_var : Reference to the string initialised with the env. variable value (if found) // // return : // 0 if the env. variable is found and -1 otherwise // //---------------------------------------------------------------------------------------------------------------- int ApiUtil::get_env_var(const char *env_var_name,string &env_var) { DummyDeviceProxy d; return d.get_env_var(env_var_name,env_var); } //--------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::get_ip_from_if() // // description : // Get host IP address from its network interface // // arg(s) : // out : // - ip_adr_list : Host IP address // //---------------------------------------------------------------------------------------------------------------- void ApiUtil::get_ip_from_if(vector &ip_adr_list) { omni_mutex_lock oml(lock_th_map); if (host_ip_adrs.empty() == true) { #ifndef _TG_WINDOWS_ struct ifaddrs *ifaddr, *ifa; int family, s; char host[NI_MAXHOST]; if (getifaddrs(&ifaddr) == -1) { cerr << "ApiUtil::get_ip_from_if: getifaddrs() failed: " << strerror(errno) << endl; Tango::Except::throw_exception((const char *)API_SystemCallFailed, (const char *) strerror(errno), (const char *)"ApiUtil::get_ip_from_if()"); } // // Walk through linked list, maintaining head pointer so we can free list later. The ifa_addr field points to a // structure containing the interface address. (The sa_family subfield should be consulted to determine the format // of the address structure.) // for (ifa = ifaddr;ifa != NULL;ifa = ifa->ifa_next) { if (ifa->ifa_addr != NULL) { family = ifa->ifa_addr->sa_family; // // Only get IP V4 addresses // /* if(family == AF_INET || family == AF_INET6) { s = getnameinfo(ifa->ifa_addr,(family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);*/ if (family == AF_INET) { s = getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in),host,NI_MAXHOST,NULL,0,NI_NUMERICHOST); if (s != 0) { cerr << "ApiUtil::get_ip_from_if: getnameinfo() failed: " << gai_strerror(s); cerr << "ApiUtil::get_ip_from_if: not getting info from remaining ifaddrs"; freeifaddrs(ifaddr); Tango::Except::throw_exception((const char *)API_SystemCallFailed, (const char *) gai_strerror(s), (const char *)"ApiUtil::get_ip_from_if()"); } else { host_ip_adrs.push_back(string(host)); } } } } freeifaddrs(ifaddr); #else // // Get address from interfaces // int sock = socket(AF_INET,SOCK_STREAM,0); INTERFACE_INFO info[64]; // Assume max 64 interfaces DWORD retlen; if ( WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL,0,(LPVOID)&info, sizeof(info), (LPDWORD)&retlen,NULL,NULL) == SOCKET_ERROR ) { closesocket(sock); int err = WSAGetLastError(); cerr << "Warning: WSAIoctl failed" << endl; cerr << "Unable to obtain the list of all interface addresses. Error = " << err << endl; TangoSys_OMemStream desc; desc << "Can't retrieve list of all interfaces addresses (WSAIoctl)! Error = " << err << ends; Tango::Except::throw_exception((const char*)API_SystemCallFailed, (const char *)desc.str().c_str(), (const char *)"ApiUtil::get_ip_from_if()"); } closesocket(sock); // // Converts addresses to string. Only for running interfaces // int numAddresses = retlen / sizeof(INTERFACE_INFO); for (int i = 0; i < numAddresses; i++) { if (info[i].iiFlags & IFF_UP) { if (info[i].iiAddress.Address.sa_family == AF_INET || info[i].iiAddress.Address.sa_family == AF_INET6) { struct sockaddr* addr = (struct sockaddr*)&info[i].iiAddress.AddressIn; char dest[NI_MAXHOST]; socklen_t addrlen = sizeof(sockaddr); int result = getnameinfo(addr, addrlen, dest, sizeof(dest),0,0,NI_NUMERICHOST); if (result != 0) { cerr << "Warning: getnameinfo failed" << endl; cerr << "Unable to convert IP address to string (getnameinfo)." << endl; Tango::Except::throw_exception((const char *)API_SystemCallFailed, (const char *)"Can't convert IP address to string (getnameinfo)!", (const char *)"ApiUtil::get_ip_from_if()"); } string tmp_str(dest); if (tmp_str != "0.0.0.0" && tmp_str != "0:0:0:0:0:0:0:0" &&tmp_str != "::") host_ip_adrs.push_back(tmp_str); } } } #endif } // // Copy host IP addresses into caller vector // ip_adr_list.clear(); copy(host_ip_adrs.begin(),host_ip_adrs.end(),back_inserter(ip_adr_list)); } //-------------------------------------------------------------------------------------------------------------------- // // method : // ApiUtil::print_error_message // // description : // Print error message on stderr but first print date // // argument : // in : // - mess : The user error message // //--------------------------------------------------------------------------------------------------------------------- void ApiUtil::print_error_message(const char *mess) { time_t tmp_val = time(NULL); char tmp_date[128]; #ifdef _TG_WINDOWS_ ctime_s(tmp_date,128,&tmp_val); #else ctime_r(&tmp_val,tmp_date); #endif tmp_date[strlen(tmp_date) - 1] = '\0'; cerr << tmp_date << ": " << mess << endl; } //+----------------------------------------------------------------------------------------------------------------- // // function // operator overloading : << // // description : // Friend function to ease printing instance of the AttributeInfo class // //----------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,AttributeInfo &p) { // // Print all these properties // o_str << "Attribute name = " << p.name << endl; o_str << "Attribute data_type = "; switch (p.data_type) { case Tango::DEV_SHORT : o_str << "Tango::DevShort" << endl; break; case Tango::DEV_LONG : o_str << "Tango::DevLong" << endl; break; case Tango::DEV_DOUBLE : o_str << "Tango::DevDouble" << endl; break; case Tango::DEV_STRING : o_str << "Tango::DevString" << endl; break; case Tango::DEV_FLOAT : o_str << "Tango::DevFloat" << endl; break; case Tango::DEV_USHORT : o_str << "Tango::DevUShort" << endl; break; case Tango::DEV_UCHAR : o_str << "Tango::DevUChar" << endl; break; case Tango::DEV_BOOLEAN : o_str << "Tango::DevBoolean" << endl; break; case Tango::DEV_STATE : o_str << "Tango::DevState" << endl; break; } o_str << "Attribute data_format = "; switch (p.data_format) { case Tango::FMT_UNKNOWN: break; case Tango::SCALAR : o_str << "scalar" << endl; break; case Tango::SPECTRUM : o_str << "spectrum, max_dim_x = " << p.max_dim_x << endl; break; case Tango::IMAGE : o_str << "image, max_dim_x = " << p.max_dim_x << ", max_dim_y = " << p.max_dim_y << endl; break; } if ((p.writable == Tango::WRITE) || (p.writable == Tango::READ_WRITE)) o_str << "Attribute is writable" << endl; else o_str << "Attribute is not writable" << endl; o_str << "Attribute label = " << p.label << endl; o_str << "Attribute description = " << p.description << endl; o_str << "Attribute unit = " << p.unit; o_str << ", standard unit = " << p.standard_unit; o_str << ", display unit = " << p.display_unit << endl; o_str << "Attribute format = " << p.format << endl; o_str << "Attribute min alarm = " << p.min_alarm << endl; o_str << "Attribute max alarm = " << p.max_alarm << endl; o_str << "Attribute min value = " << p.min_value << endl; o_str << "Attribute max value = " << p.max_value << endl; o_str << "Attribute writable_attr_name = " << p.writable_attr_name; return o_str; } //+---------------------------------------------------------------------------------------------------------------- // // function : // operator overloading : = // // description : // Assignement operator for the AttributeInfoEx class from a AttributeConfig_2 pointer // //---------------------------------------------------------------------------------------------------------------- AttributeInfoEx &AttributeInfoEx::operator=(const AttributeConfig_2 *att_2) { name = att_2->name; writable = att_2->writable; data_format = att_2->data_format; data_type = att_2->data_type; max_dim_x = att_2->max_dim_x; max_dim_y = att_2->max_dim_y; description = att_2->description; label = att_2->label; unit = att_2->unit; standard_unit = att_2->standard_unit; display_unit = att_2->display_unit; format = att_2->format; min_value = att_2->min_value; max_value = att_2->max_value; min_alarm = att_2->min_alarm; max_alarm = att_2->max_alarm; writable_attr_name = att_2->writable_attr_name; extensions.resize(att_2->extensions.length()); for (unsigned int j=0; jextensions.length(); j++) { extensions[j] = att_2->extensions[j]; } disp_level = att_2->level; return *this; } //+--------------------------------------------------------------------------------------------------------------- // // function : // operator overloading : = // // description : // Assignement operator for the AttributeInfoEx class from a AttributeConfig_3 pointer // //----------------------------------------------------------------------------------------------------------------- AttributeInfoEx &AttributeInfoEx::operator=(const AttributeConfig_3 *att_3) { name = att_3->name; writable = att_3->writable; data_format = att_3->data_format; data_type = att_3->data_type; max_dim_x = att_3->max_dim_x; max_dim_y = att_3->max_dim_y; description = att_3->description; label = att_3->label; unit = att_3->unit; standard_unit = att_3->standard_unit; display_unit = att_3->display_unit; format = att_3->format; min_value = att_3->min_value; max_value = att_3->max_value; min_alarm = att_3->att_alarm.min_alarm; max_alarm = att_3->att_alarm.max_alarm; writable_attr_name = att_3->writable_attr_name; extensions.resize(att_3->sys_extensions.length()); for (unsigned int j=0; jsys_extensions.length(); j++) { extensions[j] = att_3->sys_extensions[j]; } disp_level = att_3->level; alarms.min_alarm = att_3->att_alarm.min_alarm; alarms.max_alarm = att_3->att_alarm.max_alarm; alarms.min_warning = att_3->att_alarm.min_warning; alarms.max_warning = att_3->att_alarm.max_warning; alarms.delta_t = att_3->att_alarm.delta_t; alarms.delta_val = att_3->att_alarm.delta_val; alarms.extensions.resize(att_3->att_alarm.extensions.length()); for (unsigned int j=0; jatt_alarm.extensions.length(); j++) { alarms.extensions[j] = att_3->att_alarm.extensions[j]; } events.ch_event.abs_change = att_3->event_prop.ch_event.abs_change; events.ch_event.rel_change = att_3->event_prop.ch_event.rel_change; events.ch_event.extensions.resize(att_3->event_prop.ch_event.extensions.length()); for (unsigned int j=0; jevent_prop.ch_event.extensions.length(); j++) { events.ch_event.extensions[j] = att_3->event_prop.ch_event.extensions[j]; } events.per_event.period = att_3->event_prop.per_event.period; events.per_event.extensions.resize(att_3->event_prop.per_event.extensions.length()); for (unsigned int j=0; jevent_prop.per_event.extensions.length(); j++) { events.per_event.extensions[j] = att_3->event_prop.per_event.extensions[j]; } events.arch_event.archive_abs_change = att_3->event_prop.arch_event.abs_change; events.arch_event.archive_rel_change = att_3->event_prop.arch_event.rel_change; events.arch_event.archive_period = att_3->event_prop.arch_event.period; events.arch_event.extensions.resize(att_3->event_prop.arch_event.extensions.length()); for (unsigned int j=0; jevent_prop.arch_event.extensions.length(); j++) { events.arch_event.extensions[j] = att_3->event_prop.arch_event.extensions[j]; } return *this; } //+--------------------------------------------------------------------------------------------------------------- // // function : // operator overloading : = // // description : // Assignement operator for the AttributeInfoEx class from a AttributeConfig_5 pointer // //----------------------------------------------------------------------------------------------------------------- AttributeInfoEx &AttributeInfoEx::operator=(const AttributeConfig_5 *att_5) { name = att_5->name; writable = att_5->writable; data_format = att_5->data_format; data_type = att_5->data_type; max_dim_x = att_5->max_dim_x; max_dim_y = att_5->max_dim_y; description = att_5->description; label = att_5->label; unit = att_5->unit; standard_unit = att_5->standard_unit; display_unit = att_5->display_unit; format = att_5->format; min_value = att_5->min_value; max_value = att_5->max_value; min_alarm = att_5->att_alarm.min_alarm; max_alarm = att_5->att_alarm.max_alarm; writable_attr_name = att_5->writable_attr_name; extensions.resize(att_5->sys_extensions.length()); for (unsigned int j=0; jsys_extensions.length(); j++) { extensions[j] = att_5->sys_extensions[j]; } disp_level = att_5->level; root_attr_name = att_5->root_attr_name; if (att_5->memorized == false) memorized = NONE; else { if (att_5->mem_init == false) memorized = MEMORIZED; else memorized = MEMORIZED_WRITE_INIT; } enum_labels.clear(); for (unsigned int j=0; jenum_labels.length(); j++) { enum_labels.push_back(att_5->enum_labels[j].in()); } alarms.min_alarm = att_5->att_alarm.min_alarm; alarms.max_alarm = att_5->att_alarm.max_alarm; alarms.min_warning = att_5->att_alarm.min_warning; alarms.max_warning = att_5->att_alarm.max_warning; alarms.delta_t = att_5->att_alarm.delta_t; alarms.delta_val = att_5->att_alarm.delta_val; alarms.extensions.resize(att_5->att_alarm.extensions.length()); for (unsigned int j=0; jatt_alarm.extensions.length(); j++) { alarms.extensions[j] = att_5->att_alarm.extensions[j]; } events.ch_event.abs_change = att_5->event_prop.ch_event.abs_change; events.ch_event.rel_change = att_5->event_prop.ch_event.rel_change; events.ch_event.extensions.resize(att_5->event_prop.ch_event.extensions.length()); for (unsigned int j=0; jevent_prop.ch_event.extensions.length(); j++) { events.ch_event.extensions[j] = att_5->event_prop.ch_event.extensions[j]; } events.per_event.period = att_5->event_prop.per_event.period; events.per_event.extensions.resize(att_5->event_prop.per_event.extensions.length()); for (unsigned int j=0; jevent_prop.per_event.extensions.length(); j++) { events.per_event.extensions[j] = att_5->event_prop.per_event.extensions[j]; } events.arch_event.archive_abs_change = att_5->event_prop.arch_event.abs_change; events.arch_event.archive_rel_change = att_5->event_prop.arch_event.rel_change; events.arch_event.archive_period = att_5->event_prop.arch_event.period; events.arch_event.extensions.resize(att_5->event_prop.arch_event.extensions.length()); for (unsigned int j=0; jevent_prop.arch_event.extensions.length(); j++) { events.arch_event.extensions[j] = att_5->event_prop.arch_event.extensions[j]; } return *this; } //+---------------------------------------------------------------------------------------------------------------- // // function : // operator overloading : << // // description : // Friend function to ease printing instance of the AttributeInfo class // //----------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,AttributeInfoEx &p) { // // Print all these properties // o_str << "Attribute name = " << p.name << endl; o_str << "Attribute data_type = "; switch (p.data_type) { case Tango::DEV_SHORT : o_str << "Tango::DevShort" << endl; break; case Tango::DEV_LONG : o_str << "Tango::DevLong" << endl; break; case Tango::DEV_DOUBLE : o_str << "Tango::DevDouble" << endl; break; case Tango::DEV_STRING : o_str << "Tango::DevString" << endl; break; case Tango::DEV_FLOAT : o_str << "Tango::DevFloat" << endl; break; case Tango::DEV_USHORT : o_str << "Tango::DevUShort" << endl; break; case Tango::DEV_UCHAR : o_str << "Tango::DevUChar" << endl; break; case Tango::DEV_BOOLEAN : o_str << "Tango::DevBoolean" << endl; break; case Tango::DEV_STATE : o_str << "Tango::DevState" << endl; break; case Tango::DEV_ULONG : o_str << "Tango::DevULong" << endl; break; case Tango::DEV_ULONG64 : o_str << "Tango::DevULong64" << endl; break; case Tango::DEV_ENCODED : o_str << "Tango::DevEncoded" << endl; break; case Tango::DEV_ENUM : o_str << "Tango::DevEnum" << endl; for (size_t loop = 0;loop < p.enum_labels.size();loop++) o_str << "\tEnumeration label = " << p.enum_labels[loop] << endl; break; case Tango::DATA_TYPE_UNKNOWN : o_str << "Unknown" << endl; break; } o_str << "Attribute data_format = "; switch (p.data_format) { case Tango::FMT_UNKNOWN: o_str << " Unknown" << endl; break; case Tango::SCALAR : o_str << "scalar" << endl; break; case Tango::SPECTRUM : o_str << "spectrum, max_dim_x = " << p.max_dim_x << endl; break; case Tango::IMAGE : o_str << "image, max_dim_x = " << p.max_dim_x << ", max_dim_y = " << p.max_dim_y << endl; break; } o_str << "Attribute writable type = "; switch (p.writable) { case Tango::WRITE: o_str << "Write" << endl; break; case Tango::READ: o_str << "Read" << endl; break; case Tango::READ_WRITE: o_str << "Read/Write" << endl; break; case Tango::READ_WITH_WRITE: o_str << "Read with write" << endl; break; default: break; } if ((p.writable == Tango::WRITE) || (p.writable == Tango::READ_WRITE)) { switch(p.memorized) { case NOT_KNOWN: o_str << "Device/Appli too old to send/receive attribute memorisation data" << endl; break; case NONE: o_str << "Attribute is not memorized" << endl; break; case MEMORIZED: o_str << "Attribute is memorized" << endl; break; case MEMORIZED_WRITE_INIT: o_str << "Attribute is memorized and the memorized value is written at initialisation" << endl; break; default: break; } } o_str << "Attribute display level = "; switch(p.disp_level) { case DL_UNKNOWN : o_str << "Unknown" << endl; break; case OPERATOR: o_str << "Operator" << endl; break; case EXPERT: o_str << "Expert" << endl; break; default: break; } o_str << "Attribute writable_attr_name = " << p.writable_attr_name << endl; if (p.root_attr_name.empty() == false) o_str << "Root attribute name = " << p.root_attr_name << endl; o_str << "Attribute label = " << p.label << endl; o_str << "Attribute description = " << p.description << endl; o_str << "Attribute unit = " << p.unit; o_str << ", standard unit = " << p.standard_unit; o_str << ", display unit = " << p.display_unit << endl; o_str << "Attribute format = " << p.format << endl; o_str << "Attribute min value = " << p.min_value << endl; o_str << "Attribute max value = " << p.max_value << endl; unsigned int i; for (i = 0;i < p.extensions.size();i++) o_str << "Attribute extensions " << i + 1 << " = " << p.extensions[i] << endl; o_str << "Attribute alarm : min alarm = "; p.alarms.min_alarm.empty() == true ? o_str << "Not specified" : o_str << p.alarms.min_alarm; o_str << endl; o_str << "Attribute alarm : max alarm = "; p.alarms.max_alarm.empty() == true ? o_str << "Not specified" : o_str << p.alarms.max_alarm; o_str << endl; o_str << "Attribute warning alarm : min warning = "; p.alarms.min_warning.empty() == true ? o_str << "Not specified" : o_str << p.alarms.min_warning; o_str << endl; o_str << "Attribute warning alarm : max warning = "; p.alarms.max_warning.empty() == true ? o_str << "Not specified" : o_str << p.alarms.max_warning; o_str << endl; o_str << "Attribute rds alarm : delta time = "; p.alarms.delta_t.empty() == true ? o_str << "Not specified" : o_str << p.alarms.delta_t; o_str << endl; o_str << "Attribute rds alarm : delta value = "; p.alarms.delta_val.empty() == true ? o_str << "Not specified" : o_str << p.alarms.delta_val; o_str << endl; for (i = 0;i < p.alarms.extensions.size();i++) o_str << "Attribute alarm extensions " << i + 1 << " = " << p.alarms.extensions[i] << endl; o_str << "Attribute event : change event absolute change = "; p.events.ch_event.abs_change.empty() == true ? o_str << "Not specified" : o_str << p.events.ch_event.abs_change; o_str << endl; o_str << "Attribute event : change event relative change = "; p.events.ch_event.rel_change.empty() == true ? o_str << "Not specified" : o_str << p.events.ch_event.rel_change; o_str << endl; for (i = 0;i < p.events.ch_event.extensions.size();i++) o_str << "Attribute alarm : change event extensions " << i + 1 << " = " << p.events.ch_event.extensions[i] << endl; o_str << "Attribute event : periodic event period = "; p.events.per_event.period.empty() == true ? o_str << "Not specified" : o_str << p.events.per_event.period; o_str << endl; for (i = 0;i < p.events.per_event.extensions.size();i++) o_str << "Attribute alarm : periodic event extensions " << i + 1 << " = " << p.events.per_event.extensions[i] << endl; o_str << "Attribute event : archive event absolute change = "; p.events.arch_event.archive_abs_change.empty() == true ? o_str << "Not specified" : o_str << p.events.arch_event.archive_abs_change; o_str << endl; o_str << "Attribute event : archive event relative change = "; p.events.arch_event.archive_rel_change.empty() == true ? o_str << "Not specified" : o_str << p.events.arch_event.archive_rel_change; o_str << endl; o_str << "Attribute event : archive event period = "; p.events.arch_event.archive_period.empty() == true ? o_str << "Not specified" : o_str << p.events.arch_event.archive_period; o_str << endl; for (i = 0;i < p.events.arch_event.extensions.size();i++) { if (i == 0) o_str << endl; o_str << "Attribute alarm : archive event extensions " << i + 1 << " = " << p.events.arch_event.extensions[i]; if (i != p.events.arch_event.extensions.size() - 1) o_str << endl; } return o_str; } //+---------------------------------------------------------------------------------------------------------------- // // function : // operator overloading : << // // description : // Friend function to ease printing instance of the PipeInfo class // //----------------------------------------------------------------------------------------------------------------- ostream &operator<<(ostream &o_str,PipeInfo &p) { // // Print all these properties // o_str << "Pipe name = " << p.name << endl; o_str << "Pipe label = " << p.label << endl; o_str << "Pipe description = " << p.description << endl; o_str << "Pipe writable type = "; if (p.writable == PIPE_READ) o_str << "READ" << endl; else o_str << "READ_WRITE" << endl; o_str << "Pipe display level = "; switch(p.disp_level) { case DL_UNKNOWN : o_str << "Unknown"; break; case OPERATOR: o_str << "Operator"; break; case EXPERT: o_str << "Expert"; break; default: break; } unsigned int i; for (i = 0;i < p.extensions.size();i++) { if (i == 0) o_str << endl; o_str << "Pipe extensions " << i + 1 << " = " << p.extensions[i] << endl; } return o_str; } } // End of tango namespace tango-9.2.5a/lib/cpp/client/asynreq.cpp0000644023471100065110000002607213034744772014744 00000000000000static const char *RcsId = "$Id: asynreq.cpp 29627 2016-04-15 14:18:48Z bourtemb $\n$Name$"; // // cpp - C++ source code file for TANGO AsynReq class // // programmer - Emmanuel Taurel // // original - January 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // #if HAVE_CONFIG_H #include #endif #include namespace Tango { //+---------------------------------------------------------------------------- // // method : AsynReq::store_request() // // description : Store a new request in the polling request map // // argin(s) : req : The CORBA request object // type : The request type // // return : The asynchronous request identifier // //----------------------------------------------------------------------------- long AsynReq::store_request(CORBA::Request_ptr req,TgRequest::ReqType type) { // // If they are some cancelled requests, remove them // omni_mutex_lock sync(*this); if (cancelled_request.empty() == false) { vector::iterator ite; bool ret; for (ite = cancelled_request.begin();ite != cancelled_request.end();++ite) { try { ret = remove_cancelled_request(*ite); } catch(...) {ret = false;} if (ret == true) { ite = cancelled_request.erase(ite); if (ite == cancelled_request.end()) break; } } } // // Get a request identifier // long req_id = ui_ptr->get_ident(); // // Store couple ident/request in map // TgRequest tmp_req(req,type); asyn_poll_req_table.insert(map::value_type(req_id,tmp_req)); return req_id; } //+---------------------------------------------------------------------------- // // method : AsynReq::store_request() // // description : Store a new request in the callback request maps // // argin(s) : req : The CORBA request object // cb : The callback object // dev : The device // type : The request type // //----------------------------------------------------------------------------- void AsynReq::store_request(CORBA::Request_ptr req, CallBack *cb, Connection *dev, TgRequest::ReqType type) { // // Store couple device_ptr/request in map // TgRequest tmp_req_dev(req,type,cb); TgRequest tmp_req(dev,type,cb); omni_mutex_lock sync(*this); cb_dev_table.insert(map::value_type(dev,tmp_req_dev)); cb_req_table.insert(map::value_type(req,tmp_req)); } //+---------------------------------------------------------------------------- // // method : AsynReq::get_request() // // description : Return the Tango request object associated to the id // passed as method argument. This method is used // for asynchronous polling mode // // argin(s) : req_id : The Tango request identifier // // return : The Tango request object // //----------------------------------------------------------------------------- Tango::TgRequest &AsynReq::get_request(long req_id) { map::iterator pos; omni_mutex_lock sync(*this); pos = asyn_poll_req_table.find(req_id); if (pos == asyn_poll_req_table.end()) { TangoSys_OMemStream desc; desc << "Failed to find a asynchronous polling request "; desc << "with id = " << req_id << ends; ApiAsynExcept::throw_exception((const char*)"API_BadAsynPollId", desc.str(), (const char*)"AsynReq::get_request()"); } return pos->second; } //+---------------------------------------------------------------------------- // // method : AsynReq::get_request() // // description : Return the Tango request object associated to the CORBA // request object passed as method argument. // This method is used for asynchronous callback mode // // argin(s) : req : The CORBA request object // // return : The Tango request object // //----------------------------------------------------------------------------- Tango::TgRequest &AsynReq::get_request(CORBA::Request_ptr req) { map::iterator pos; omni_mutex_lock sync(*this); pos = cb_req_table.find(req); if (pos == cb_req_table.end()) { TangoSys_OMemStream desc; desc << "Failed to find a asynchronous callback request "; ApiAsynExcept::throw_exception((const char*)"API_BadAsyn", desc.str(), (const char*)"AsynReq::get_request() (by request)"); } return pos->second; } //+---------------------------------------------------------------------------- // // method : AsynReq::get_request() // // description : Return the Tango request object associated to the device // passed as method argument and for which replies are // already arrived. // This method is used for asynchronous callback mode // // argin(s) : dev : The Tango device // // return : The Tango request object // //----------------------------------------------------------------------------- Tango::TgRequest *AsynReq::get_request(Tango::Connection *dev) { multimap::iterator pos; bool found = false; omni_mutex_lock sync(*this); for (pos = cb_dev_table.lower_bound(dev);pos != cb_dev_table.upper_bound(dev);++pos) { if (pos->second.arrived == true) { found = true; break; } } if (found == false) return NULL; else return &(pos->second); } //+---------------------------------------------------------------------------- // // method : AsynReq::mark_as_arrived() // // description : Mark a request as arrived in the callback device map // // argin(s) : req : The CORBA request object // //----------------------------------------------------------------------------- void AsynReq::mark_as_arrived(CORBA::Request_ptr req) { multimap::iterator pos; omni_mutex_lock sync(*this); for (pos = cb_dev_table.begin();pos != cb_dev_table.end();++pos) { if (pos->second.request == req) { pos->second.arrived = true; break; } } } //+---------------------------------------------------------------------------- // // method : AsynReq::remove_request() // // description : Remove a request from the object map. The Id is passed // as input argument. This method is used for the polling // mode // // argin(s) : req_id : The Tango request identifier // //----------------------------------------------------------------------------- void AsynReq::remove_request(long req_id) { map::iterator pos; omni_mutex_lock sync(*this); pos = asyn_poll_req_table.find(req_id); if (pos == asyn_poll_req_table.end()) { TangoSys_OMemStream desc; desc << "Failed to find a asynchronous polling request "; desc << "with id = " << req_id << ends; ApiAsynExcept::throw_exception((const char*)"API_BadAsynPollId", desc.str(), (const char*)"AsynReq::remove_request()"); } else { CORBA::release(pos->second.request); asyn_poll_req_table.erase(pos); } } //+---------------------------------------------------------------------------- // // method : AsynReq::remove_cancelled_request() // // description : Remove a already cancelled request from the object map. // The Id is passed as input argument. // // argin(s) : req_id : The Tango request identifier // // This method returns true if it was possible to remove the request // (reply already arrived from the server). Otherwise, it returns false // //----------------------------------------------------------------------------- bool AsynReq::remove_cancelled_request(long req_id) { map::iterator pos; pos = asyn_poll_req_table.find(req_id); bool ret = true; if (pos != asyn_poll_req_table.end()) { if (pos->second.request->poll_response() == false) ret = false; else { CORBA::release(pos->second.request); asyn_poll_req_table.erase(pos); } } return ret; } //+---------------------------------------------------------------------------- // // method : AsynReq::remove_request() // // description : Remove a request from the two map used for asynchronous // callback request. This method is used for the callback // mode // // argin(s) : dev : The Tango device // req : The CORBA request object // //----------------------------------------------------------------------------- void AsynReq::remove_request(Connection *dev,CORBA::Request_ptr req) { multimap::iterator pos; map::iterator pos_req; omni_mutex_lock sync(*this); for (pos = cb_dev_table.lower_bound(dev);pos != cb_dev_table.upper_bound(dev);++pos) { if (pos->second.request == req) { CORBA::release(pos->second.request); cb_dev_table.erase(pos); break; } } pos_req = cb_req_table.find(req); if (pos_req != cb_req_table.end()) { cb_req_table.erase(pos_req); } } //+---------------------------------------------------------------------------- // // method : AsynReq::mark_as_cancelled() // // description : Mark a pending polling request as cancelled // // argin(s) : req_id : The request identifier // //----------------------------------------------------------------------------- void AsynReq::mark_as_cancelled(long req_id) { omni_mutex_lock sync(*this); map::iterator pos; pos = asyn_poll_req_table.find(req_id); if (pos != asyn_poll_req_table.end()) { if (find(cancelled_request.begin(),cancelled_request.end(),req_id) == cancelled_request.end()) cancelled_request.push_back(req_id); } else { TangoSys_OMemStream desc; desc << "Failed to find a asynchronous polling request "; desc << "with id = " << req_id << ends; ApiAsynExcept::throw_exception((const char*)"API_BadAsynPollId", desc.str(), (const char*)"AsynReq::mark_as_cancelled()"); } } //+---------------------------------------------------------------------------- // // method : AsynReq::mark_all_polling_as_cancelled() // // description : Mark all pending polling request as cancelled // //----------------------------------------------------------------------------- void AsynReq::mark_all_polling_as_cancelled() { map::iterator pos; omni_mutex_lock sync(*this); for (pos = asyn_poll_req_table.begin();pos != asyn_poll_req_table.end();++pos) { long id = pos->first; if (find(cancelled_request.begin(),cancelled_request.end(),id) == cancelled_request.end()) cancelled_request.push_back(id); } } } // End of tango namespace tango-9.2.5a/lib/cpp/client/cbthread.cpp0000644023471100065110000000537413034744772015040 00000000000000static const char *RcsId = "$Id: cbthread.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================ // // file : cbthread.cpp // // description : C++ source code for the CallBackThread class. // This class is used in automatic callback mode. // The thread mainly waits on aa asynchronous callback // request and will call the get_asynch_replies() call // to fire the callback when the answer is received // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { //+------------------------------------------------------------------------- // // method : CallBackThread::CallBackThread // // description : Two constructors for the PollObj class. The first one // constructs a PollObji nstance with the default polling // ring depth // The second one create a PollObj instance with a // specified polling ring depth // // argument : in : // //-------------------------------------------------------------------------- void *CallBackThread::run_undetached(TANGO_UNUSED(void *ptr)) { while(shared_cmd.is_stopped() == false) { try { { omni_mutex_lock sync(*asyn_ptr); if (asyn_ptr->get_cb_request_nb_i() == 0) { asyn_ptr->wait(); } } if (asyn_ptr->get_cb_request_nb() != 0) ApiUtil::instance()->get_asynch_replies(0); } catch (omni_thread_fatal &) { cerr << "OUPS !! A omni thread fatal exception !!!!!!!!" << endl; #ifndef _TG_WINDOWS_ time_t t = time(NULL); cerr << ctime(&t); #endif cerr << "Trying to re-enter the main loop" << endl; } } omni_thread::exit(); return NULL; } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/proxy_asyn.cpp0000644023471100065110000024610513034744772015476 00000000000000static const char *RcsId = "$Id: proxy_asyn.cpp 30242 2016-10-27 11:48:23Z bourtemb $\n$Name$"; //==================================================================================== // // cpp - C++ source code file for TANGO api Connection and DeviceProxy // classes (asynchronous polling related methods) // // programmer - Emmanuel Taurel (taurel@esrf.fr) // // original - August 2002 // // Copyright (C) : 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // // $Revision: 30242 $ // //=================================================================================== #if HAVE_CONFIG_H #include #endif #include #define _dyn_attr #ifdef _TG_WINDOWS_ #include #else #include #endif namespace Tango { //----------------------------------------------------------------------------- // // method : Connection::command_inout_asyn() // // description : Send a command to a Tango device asynchronously. // The client is not blocked until the command is executed // // argin(s) : command : The command name // data_in : Command input data // faf : Fire And Forget flag // // return : The asynchronous call identifier // //----------------------------------------------------------------------------- long Connection::command_inout_asynch(const char *command, DeviceData &data_in, bool faf) { // // Throw exception if caller not allowed to do write action // if (access == ACCESS_READ) { int db_num; ApiUtil *au = ApiUtil::instance(); if (get_from_env_var() == true) db_num = au->get_db_ind(); else db_num = au->get_db_ind(get_db_host(),get_db_port_num()); vector & v_d = au->get_db_vect(); Database *db = v_d[db_num]; // // If the command is not allowed, throw exception // Also throw exception if it was not possible to get the list // of allowed commands from the control access service // string d_name = dev_name(); string cmd(command); if (db->is_command_allowed(d_name,cmd) == false) { DevErrorList &e = db->get_access_except_errors(); if (e.length() != 0) { DevFailed df(e); throw df; } TangoSys_OMemStream desc; desc << "Command_inout_asynch on device " << dev_name() << " for command "; desc << command << " is not authorized" << ends; NotAllowedExcept::throw_exception(API_ReadOnlyMode,desc.str(), "Connection::command_inout_asynch()"); } } // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiConnExcept::re_throw_exception(e,API_CommandFailed, desc.str(),"Connection::command_inout_asynch()"); } // // Create the request object // CORBA::Request_ptr request; if (version >= 4) request = device_4->_request("command_inout_4"); else if (version >=2) request = device_2->_request("command_inout_2"); else request = device->_request("command_inout"); request->add_in_arg() <<= command; request->add_in_arg() <<= data_in.any.in(); if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); request->add_in_arg() <<= source; request->add_in_arg() <<= ci; } else if (version >= 2) request->add_in_arg() <<= source; request->set_return_type(CORBA::_tc_any); request->exceptions()->add(Tango::_tc_DevFailed); // // If its a fire and forget (faf) call, send it and forget. Otherwise, send it // and store the request in the global asynchronous polling requests table // long id = 0; if (faf == false) { id = add_asyn_request(request,TgRequest::CMD_INOUT); request->send_deferred(); } else { request->send_oneway(); CORBA::release(request); } return id; } //----------------------------------------------------------------------------- // // method : Connection::command_inout_asyn() // // description : Send a command to a Tango device asynchrnously. // The client is not blocked until the command is executed // These methods are only user helper methods which call // the official command_inout_asyn() method // // argin(s) : command : The command name // data_in : Command input data // faf : Fire And Forget flag // // return : The asynchronous call identifier // //----------------------------------------------------------------------------- long Connection::command_inout_asynch(string &command, DeviceData &data_in, bool faf) { return command_inout_asynch(command.c_str(),data_in,faf); } long Connection::command_inout_asynch(const char *command,bool faf) { DeviceData data_in; return command_inout_asynch(command,data_in,faf); } long Connection::command_inout_asynch(string &command,bool faf) { DeviceData data_in; return command_inout_asynch(command.c_str(),data_in,faf); } //----------------------------------------------------------------------------- // // method : Connection::command_inout_reply() // // description : Try to obtain data returned by a command asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : id : The asynchrnous call identifier // // return : The command output data // //----------------------------------------------------------------------------- DeviceData Connection::command_inout_reply(long id) { DeviceData data_out; // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::CMD_INOUT) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::command_inout_reply"); } // // Reply arrived ? Throw exception if not yet arrived // if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << dev_name(); desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "Connection::command_inout_reply"); } // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout(id,cb_excep_mess); } else { set_connection_state(CONNECTION_NOTOK); return omni420_except(id,cb_excep_mess,req); } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); return omni420_except(id,cb_excep_mess,req); } if (!CORBA::is_nil(env) && (env->exception() == NULL)) { // // Get received value // const CORBA::Any *received = NULL; CORBA::Any &dii_any = req.request->return_value(); dii_any >>= received; CORBA::Any *server_any = new CORBA::Any(*received); data_out.any = server_any; } else { // // Retrieve exception and re-throw it. // CORBA::Exception *ex_ptr = env->exception(); // // Special treatment for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); if (need_reconnect == false) { CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut", desc.str(), "Connection::command_inout_reply()"); } else { set_connection_state(CONNECTION_NOTOK); remove_asyn_request(id); stringstream ss; ss << "Failed to execute command_inout_asynch on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(), "Connection::command_inout_reply()"); } } } CORBA::UnknownUserException *unk_ex; if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex; unk_ex->exception() >>= serv_ex; Tango::DevFailed ex(*serv_ex); CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id); Except::re_throw_exception(ex, API_CommandFailed, desc.str(), "Connection::command_inout_reply()"); } CORBA::SystemException *sys_ex; if ((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) { set_connection_state(CONNECTION_NOTOK); // // Re-throw nearly all CORBA system exceptions // CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); // // Check if the exception was a connection exception // If so, execute the command synchronously (tries to reconnect) // If successful just return, otherwise throw the first exception // string ex(cb_excep_mess); string::size_type pos_con = ex.find("TRANSIENT_ConnectFailed"); string::size_type pos_one = ex.find("EXIST_NoMatch"); if (pos_con != string::npos || pos_one != string::npos) { try { DeviceData dd_out = redo_synch_cmd(req); // // Remove request from request global table. // CORBA::string_free(tmp); remove_asyn_request(id); return dd_out; } catch (Tango::DevFailed &) {} } TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed", desc.str(), "Connection::command_inout_reply()"); } } // // Remove request from request global table. // remove_asyn_request(id); return data_out; } //----------------------------------------------------------------------------- // // method : Connection::command_inout_reply() // // description : Try to obtain data returned by a command asynchronously // requested. This method blocks if the reply is // not yet arrived for a max of timeout mS. // An exception is thrown in case of reply not yet arrived. // // argin(s) : call_timeout : The max time to block the calling process // if timeout is 0, this means wait until the reply is // there // id : The asynchrnous call identifier // // return : The command output data // //----------------------------------------------------------------------------- DeviceData Connection::command_inout_reply(long id,long call_timeout) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::CMD_INOUT) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::command_inout_reply"); } // // Use CORBA get_response call if the call timeout is specified as 0 // (If the response is not already there). // Otherwise, uses a loop. Switch process to sleeping state for 20 ms // between each test to check if the replies has arrived. // if (call_timeout == 0) { if (req.request->poll_response() == false) { try { req.request->get_response(); } catch (...) {} } } else { long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif int i; for (i = 0;i < nb;i++) { if (req.request->poll_response() == true) { break; } #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif } if (i == nb) { if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << dev_name(); desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "Connection::command_inout_reply"); } } } // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // DeviceData data_out; CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout(id,cb_excep_mess); } else { set_connection_state(CONNECTION_NOTOK); return omni420_except(id,cb_excep_mess,req); } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); return omni420_except(id,cb_excep_mess,req); } if (!CORBA::is_nil(env) && (env->exception() == NULL)) { // // It's not an exception, therefore get received value // const CORBA::Any *received; CORBA::Any &dii_any = req.request->return_value(); dii_any >>= received; CORBA::Any *server_any = new CORBA::Any(*received); data_out.any = server_any; } else { // // Retrieve exception and re-throw it. // CORBA::Exception *ex_ptr = env->exception(); // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); if (need_reconnect == false) { CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut", desc.str(), "Connection::command_inout_reply()"); } else { set_connection_state(CONNECTION_NOTOK); remove_asyn_request(id); stringstream ss; ss << "Failed to execute command_inout_asynch on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(), "Connection::command_inout_reply()"); } } } CORBA::UnknownUserException *unk_ex; if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex; unk_ex->exception() >>= serv_ex; Tango::DevFailed ex(*serv_ex); CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id);; Except::re_throw_exception(ex, API_CommandFailed,desc.str(), "Connection::command_inout_reply()"); } CORBA::SystemException *sys_ex; if ((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) { set_connection_state(CONNECTION_NOTOK); // // Re-throw nearly all CORBA system exceptions // CORBA::NVList_ptr req_arg = req.request->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; char *tmp = CORBA::string_dup(cmd); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); // // Check if the exception was a connection exception // If so, execute the command synchronously (tries to reconnect) // If successful just return, otherwise throw the first exception // string ex(cb_excep_mess); string::size_type pos_con = ex.find("TRANSIENT_ConnectFailed"); string::size_type pos_one = ex.find("EXIST_NoMatch"); if (pos_con != string::npos || pos_one != string::npos) { try { DeviceData dd_out = redo_synch_cmd(req); // // Remove request from request global table. // CORBA::string_free(tmp); remove_asyn_request(id); return dd_out; } catch (Tango::DevFailed &) {} } TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",desc.str(), "Connection::command_inout_reply()"); } } // // Remove request from request global table. // remove_asyn_request(id); return data_out; } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attributes_asynch() // // description : Read Tango device attributes asynchrnously. // The client is not blocked until the attributes are read // // argin(s) : attr_names : The attribute name(s) // // return : The asynchronous call identifier // //----------------------------------------------------------------------------- long DeviceProxy::read_attributes_asynch(vector &attr_names) { // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,API_CommandFailed, desc.str(),"DeviceProxy::read_attributes_asynch()"); } // // Check that the caller did not give two times the same attribute // same_att_name(attr_names,"DeviceProxy::read_attributes_asynch"); // // Create the request object // Tango::DevVarStringArray names; long nb_names = attr_names.size(); names.length(nb_names); for (int i = 0;i < nb_names;i++) names[i] = attr_names[i].c_str(); CORBA::Request_ptr request; if (version >= 5) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); request = Connection::device_5->_request("read_attributes_5"); request->add_in_arg() <<= names; request->add_in_arg() <<= source; request->add_in_arg() <<= ci; request->set_return_type(Tango::_tc_AttributeValueList_5); } else if (version == 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); request = Connection::device_4->_request("read_attributes_4"); request->add_in_arg() <<= names; request->add_in_arg() <<= source; request->add_in_arg() <<= ci; request->set_return_type(Tango::_tc_AttributeValueList_4); } else if (version == 3) { request = Connection::device_3->_request("read_attributes_3"); request->add_in_arg() <<= names; request->add_in_arg() <<= source; request->set_return_type(Tango::_tc_AttributeValueList_3); } else if (version == 2) { request = device_2->_request("read_attributes_2"); request->add_in_arg() <<= names; request->add_in_arg() <<= source; request->set_return_type(Tango::_tc_AttributeValueList); } else { request = device->_request("read_attributes"); request->add_in_arg() <<= names; request->set_return_type(Tango::_tc_AttributeValueList); } request->exceptions()->add(Tango::_tc_DevFailed); // // Send it and store the request in the global asynchronous polling requests // table // long id = 0; id = add_asyn_request(request,TgRequest::READ_ATTR); request->send_deferred(); return id; } long DeviceProxy::read_attribute_asynch(string &name) { vector tmp_names(1,name); return read_attributes_asynch(tmp_names); } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attributes_reply() // // description : Try to obtain data returned by attributes asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : id : The asynchrnous call identifier // // return : The attributes data // //----------------------------------------------------------------------------- vector *DeviceProxy::read_attributes_reply(long id) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::READ_ATTR) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::read_attributes_reply"); } // // Reply arrived ? Throw exception is not yet arrived // if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << dev_name(); desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::read_attributes_reply"); } else { // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_attr(id,cb_excep_mess,MULTIPLE); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_attr(id,cb_excep_mess,MULTIPLE); vector *a_ptr = redo_synch_reads_call(req); remove_asyn_request(id); return a_ptr; } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_attr(id,cb_excep_mess,MULTIPLE); vector *a_ptr = redo_synch_reads_call(req); remove_asyn_request(id); return a_ptr; } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { read_attr_except(req.request,id,MULTIPLE); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // vector *a_ptr; a_ptr = redo_synch_reads_call(req); // // Remove request from request global table. // remove_asyn_request(id); return a_ptr; } vector *dev_attr = new(vector); // // Get received value // const Tango::AttributeValueList *received; const Tango::AttributeValueList_3 *received_3; const Tango::AttributeValueList_4 *received_4; const Tango::AttributeValueList_5 *received_5; CORBA::Any &dii_any = req.request->return_value(); unsigned long nb_received; switch (version) { case 5: dii_any >>= received_5; nb_received = received_5->length(); break; case 4: dii_any >>= received_4; nb_received = received_4->length(); break; case 3: dii_any >>= received_3; nb_received = received_3->length(); break; default: dii_any >>= received; nb_received = received->length(); break; } dev_attr->resize(nb_received); for (unsigned long i=0; i < nb_received; i++) { if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&((*received_5)[i]),version,&((*dev_attr)[i])); else if (version == 4) ApiUtil::attr_to_device(&((*received_4)[i]),version,&((*dev_attr)[i])); else ApiUtil::attr_to_device(NULL,&((*received_3)[i]),version,&((*dev_attr)[i])); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = (*dev_attr)[i].get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attribute " << (*dev_attr)[i].name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*received)[i]), NULL,version,&((*dev_attr)[i])); } } // // Remove request from request global table. // remove_asyn_request(id); return dev_attr; } return NULL; } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attribute_reply() // // description : Try to obtain data returned by an attribute asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : id : The asynchronous call identifier // // return : The attribute data // //----------------------------------------------------------------------------- DeviceAttribute *DeviceProxy::read_attribute_reply(long id) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::READ_ATTR) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::read_attribute_reply"); } // // Reply arrived ? Throw exception is not yet arrived // if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << dev_name(); desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::read_attribute_reply"); } else { // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_attr(id,cb_excep_mess,SIMPLE); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_attr(id,cb_excep_mess,SIMPLE); DeviceAttribute *a_ptr = redo_synch_read_call(req); remove_asyn_request(id); return a_ptr; } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_attr(id,cb_excep_mess,SIMPLE); DeviceAttribute *a_ptr = redo_synch_read_call(req); remove_asyn_request(id); return a_ptr; } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { read_attr_except(req.request,id,SIMPLE); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // DeviceAttribute *a_ptr; a_ptr = redo_synch_read_call(req); // // Remove request from request global table. // remove_asyn_request(id); return a_ptr; } DeviceAttribute *dev_attr = new DeviceAttribute; // // Get received value // const Tango::AttributeValueList *received; const Tango::AttributeValueList_3 *received_3; const Tango::AttributeValueList_4 *received_4; const Tango::AttributeValueList_5 *received_5; CORBA::Any &dii_any = req.request->return_value(); switch (version) { case 5: dii_any >>= received_5; break; case 4: dii_any >>= received_4; break; case 3: dii_any >>= received_3; break; default: dii_any >>= received; break; } if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&((*received_5)[0]),version,dev_attr); else if (version == 4) ApiUtil::attr_to_device(&((*received_4)[0]),version,dev_attr); else ApiUtil::attr_to_device(NULL,&((*received_3)[0]),version,dev_attr); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = dev_attr->get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attribute " << dev_attr->name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute_reply()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*received)[0]), NULL,version,dev_attr); } // // Remove request from request global table. // remove_asyn_request(id); return dev_attr; } return NULL; } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attributes_reply() // // description : Try to obtain data returned by a read attributes asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : call_timeout : The max time to block the calling process // if timeout is 0, this means wait until the reply is // there // id : The asynchrnous call identifier // // return : The command output data // //----------------------------------------------------------------------------- vector *DeviceProxy::read_attributes_reply(long id,long call_timeout) { // // Retrieve request object // TgRequest req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::READ_ATTR) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::read_attributes_reply"); } // // Use CORBA get_response call if the call timeout is specified as 0 // (If the response is not already there). // Otherwise, uses a loop. Switch process to sleeping state for 20 ms // between each test to check if the replies has arrived. // if (call_timeout == 0) { if (req.request->poll_response() == false) { try { req.request->get_response(); } catch(...) {} } } else { long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif int i; for (i = 0;i < nb;i++) { if (req.request->poll_response() == true) { break; } #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif } if (i == nb) { if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::read_attributes_reply"); } } } // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_attr(id,cb_excep_mess,MULTIPLE); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_attr(id,cb_excep_mess,MULTIPLE); vector *a_ptr = redo_synch_reads_call(req); remove_asyn_request(id); return a_ptr; } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_attr(id,cb_excep_mess,MULTIPLE); vector *a_ptr = redo_synch_reads_call(req); remove_asyn_request(id); return a_ptr; } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { read_attr_except(req.request,id,MULTIPLE); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // vector *a_ptr; a_ptr = redo_synch_reads_call(req); // // Remove request from request global table. // remove_asyn_request(id); return a_ptr; } vector *dev_attr = new(vector); // // Get received value // const Tango::AttributeValueList *received; const Tango::AttributeValueList_3 *received_3; const Tango::AttributeValueList_4 *received_4; const Tango::AttributeValueList_5 *received_5; unsigned long nb_received; CORBA::Any &dii_any = req.request->return_value(); switch (version) { case 5: dii_any >>= received_5; nb_received = received_5->length(); break; case 4: dii_any >>= received_4; nb_received = received_4->length(); break; case 3: dii_any >>= received_3; nb_received = received_3->length(); break; default: dii_any >>= received; nb_received = received->length(); break; } dev_attr->resize(nb_received); for (unsigned long i=0; i < nb_received; i++) { if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&((*received_5)[i]),version,&((*dev_attr)[i])); else if (version == 4) ApiUtil::attr_to_device(&((*received_4)[i]),version,&((*dev_attr)[i])); else ApiUtil::attr_to_device(NULL,&((*received_3)[i]),version,&((*dev_attr)[i])); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = (*dev_attr)[i].get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attribute " << (*dev_attr)[i].name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attributes_reply()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*received)[i]),NULL,version,&((*dev_attr)[i])); } } // // Remove request from request global table. // remove_asyn_request(id); return dev_attr; } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attribute_reply() // // description : Try to obtain data returned by a read attribute asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // This call is for one attribute only // // argin(s) : call_timeout : The max time to block the calling process // if timeout is 0, this means wait until the reply is // there // id : The asynchrnous call identifier // // return : The command output data // //----------------------------------------------------------------------------- DeviceAttribute *DeviceProxy::read_attribute_reply(long id,long call_timeout) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if (req.req_type != TgRequest::READ_ATTR) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::read_attribute_reply"); } // // Use CORBA get_response call if the call timeout is specified as 0 // (If the response is not already there). // Otherwise, uses a loop. Switch process to sleeping state for 20 ms // between each test to check if the replies has arrived. // if (call_timeout == 0) { if (req.request->poll_response() == false) { try { req.request->get_response(); } catch(...) {} } } else { long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif int i; for (i = 0;i < nb;i++) { if (req.request->poll_response() == true) { break; } #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif } if (i == nb) { if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::read_attribute_reply"); } } } // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.2 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_attr(id,cb_excep_mess,SIMPLE); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_attr(id,cb_excep_mess,SIMPLE); DeviceAttribute *a_ptr = redo_synch_read_call(req); remove_asyn_request(id); return a_ptr; } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_attr(id,cb_excep_mess,SIMPLE); DeviceAttribute *a_ptr = redo_synch_read_call(req); remove_asyn_request(id); return a_ptr; } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { read_attr_except(req.request,id,SIMPLE); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // DeviceAttribute *a_ptr; a_ptr = redo_synch_read_call(req); // // Remove request from request global table. // remove_asyn_request(id); return a_ptr; } DeviceAttribute *dev_attr = new DeviceAttribute; // // Get received value // const Tango::AttributeValueList *received; const Tango::AttributeValueList_3 *received_3; const Tango::AttributeValueList_4 *received_4; const Tango::AttributeValueList_5 *received_5; CORBA::Any &dii_any = req.request->return_value(); switch (version) { case 5: dii_any >>= received_5; break; case 4: dii_any >>= received_4; break; case 3: dii_any >>= received_3; break; default: dii_any >>= received; break; } if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&((*received_5)[0]),version,dev_attr); else if (version == 4) ApiUtil::attr_to_device(&((*received_4)[0]),version,dev_attr); else ApiUtil::attr_to_device(NULL,&((*received_3)[0]),version,dev_attr); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = dev_attr->get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << device_name; desc << ", attribute " << dev_attr->name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("DeviceProxy::read_attribute_reply()"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*received)[0]),NULL,version,dev_attr); } // // Remove request from request global table. // remove_asyn_request(id); return dev_attr; } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attr_except() // // description : Analyse the exception returned by the DII call and // send a Tango::DevFailed exception to the caller // // argin(s) : req : The CORBA request object // id : The asynchrnous call identifier // type : The request type // //----------------------------------------------------------------------------- void DeviceProxy::read_attr_except(CORBA::Request_ptr req,long id,read_attr_type type) { CORBA::Environment_ptr env = req->env(); CORBA::Exception *ex_ptr = env->exception(); // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); string meth; if (type == SIMPLE) meth = "DeviceProxy::read_attribute_replay()"; else meth = "DeviceProxy::read_attributes_reply()"; if (need_reconnect == false) { CORBA::NVList_ptr req_arg = req->arguments(); const Tango::DevVarStringArray *names; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= names; TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << device_name; desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess,"API_DeviceTimedOut",desc.str(),meth.c_str()); } else { set_connection_state(CONNECTION_NOTOK); remove_asyn_request(id); stringstream ss; ss << "Failed to execute read_attribute_asynch on device " << device_name; ApiCommExcept::re_throw_exception(cb_excep_mess,"API_CommunicationFailed",ss.str(),meth.c_str()); } } } CORBA::UnknownUserException *unk_ex; if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex; unk_ex->exception() >>= serv_ex; Tango::DevFailed ex(*serv_ex); CORBA::NVList_ptr req_arg = req->arguments(); const Tango::DevVarStringArray *names; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= names; TangoSys_OMemStream desc; desc << "Failed to execute read_attribute_asynch on device " << device_name; desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; remove_asyn_request(id); if (type == SIMPLE) Except::re_throw_exception(ex, API_AttributeFailed,desc.str(), "DeviceProxy::read_attribute_reply()"); else Except::re_throw_exception(ex, API_AttributeFailed,desc.str(), "DeviceProxy::read_attributes_reply()"); } CORBA::SystemException *sys_ex; if ((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) { set_connection_state(CONNECTION_NOTOK); // // Re-throw nearly (but not all) all CORBA system exceptions // CORBA::NVList_ptr req_arg = req->arguments(); const Tango::DevVarStringArray *names; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= names; char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); // // Check if the exception was a connection exception // In this case, try to ping the device. // If successfull, just returns otherwise, throw the first exception // string ex(cb_excep_mess); string::size_type pos = ex.find("TRANSIENT_ConnectFailed"); string::size_type pos_one = ex.find("EXIST_NoMatch"); if (pos != string::npos || pos_one != string::npos) { try { ping(); return; } catch (Tango::DevFailed &) {} } TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << device_name; desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; remove_asyn_request(id); if (type == SIMPLE) ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",desc.str(), "DeviceProxy::read_attribute_reply()"); else ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",desc.str(), "DeviceProxy::read_attributes_reply()"); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attributes_asynch() // // description : Write Tango device attributes asynchronously. // The client is not blocked until the attributes are written // // argin(s) : attr_list : The attribute name(s) and value(s) // // return : The asynchronous call identifier // //----------------------------------------------------------------------------- long DeviceProxy::write_attributes_asynch(vector &attr_list) { // // Throw exception if caller not allowed to write_attribute // if (access == ACCESS_READ) { TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception(API_ReadOnlyMode,desc.str(), "DeviceProxy::write_attributes_asynch()"); } // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute write_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,API_CommandFailed, desc.str(),"DeviceProxy::write_attributes_asynch()"); } // // Create the request object // Tango::AttributeValueList att; Tango::AttributeValueList_4 att_4; long nb_attr = attr_list.size(); if (version >= 4) att_4.length(nb_attr); else att.length(nb_attr); for (int i = 0;i < nb_attr;i++) { if (version >= 4) ApiUtil::device_to_attr(attr_list[i],att_4[i]); else ApiUtil::device_to_attr(attr_list[i],att[i],device_name); } CORBA::Request_ptr request; if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); request = device_4->_request("write_attributes_4"); request->add_in_arg() <<= att_4; request->add_in_arg() <<= ci; request->exceptions()->add(Tango::_tc_MultiDevFailed); } else if (version == 3) { request = device->_request("write_attributes_3"); request->add_in_arg() <<= att; request->exceptions()->add(Tango::_tc_MultiDevFailed); } else { request = device->_request("write_attributes"); request->add_in_arg() <<= att; } request->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // long id = 0; id = add_asyn_request(request,TgRequest::WRITE_ATTR); request->send_deferred(); return id; } long DeviceProxy::write_attribute_asynch(DeviceAttribute &attr) { // // Throw exception if caller not allowed to write_attribute // if (access == ACCESS_READ) { TangoSys_OMemStream desc; desc << "Writing attribute(s) on device " << dev_name() << " is not authorized" << ends; NotAllowedExcept::throw_exception(API_ReadOnlyMode,desc.str(), "DeviceProxy::write_attribute_asynch()"); } // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute write_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,API_CommandFailed, desc.str(),"DeviceProxy::write_attribute_asynch()"); } // // Create the request object // Tango::AttributeValueList att; Tango::AttributeValueList_4 att_4; if (version < 4) { att.length(1); ApiUtil::device_to_attr(attr,att[0],device_name); } else { att_4.length(1); ApiUtil::device_to_attr(attr,att_4[0]); } CORBA::Request_ptr request; if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); request = device_4->_request("write_attributes_4"); request->add_in_arg() <<= att_4; request->add_in_arg() <<= ci; request->exceptions()->add(Tango::_tc_MultiDevFailed); } else if (version == 3) { request = device->_request("write_attributes_3"); request->add_in_arg() <<= att; request->exceptions()->add(Tango::_tc_MultiDevFailed); } else { request = device->_request("write_attributes"); request->add_in_arg() <<= att; } request->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // long id = 0; id = add_asyn_request(request,TgRequest::WRITE_ATTR_SINGLE); request->send_deferred(); return id; } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attributes_reply() // // description : Try to obtain data returned by a write attribute asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : call_timeout : The max time to block the calling process // if timeout is 0, this means wait until the reply is // there // id : The asynchrnous call identifier // //----------------------------------------------------------------------------- void DeviceProxy::write_attributes_reply(long id,long call_timeout) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if ((req.req_type == TgRequest::CMD_INOUT) || (req.req_type == TgRequest::READ_ATTR)) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::write_attributes_reply"); } // // Use CORBA get_response call if the call timeout is specified as 0 // (If the response is not already there). // Otherwise, uses a loop. Switch process to sleeping state for 20 ms // between each test to check if the replies has arrived. // if (call_timeout == 0) { if (req.request->poll_response() == false) { try { req.request->get_response(); } catch (...) {} } } else { long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif int i; for (i = 0;i < nb;i++) { if (req.request->poll_response() == true) { break; } #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif } if (i == nb) { if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << device_name; desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::write_attributes_reply"); } } } // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_wattr(id,cb_excep_mess); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_wattr(id,cb_excep_mess); redo_synch_write_call(req); } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_wattr(id,cb_excep_mess); redo_synch_write_call(req); } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { write_attr_except(req.request,id,req.req_type); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // redo_synch_write_call(req); } // // Remove request from request global table. // remove_asyn_request(id); } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attributes_reply() // // description : Try to obtain data returned by a read attribute asynchronously // requested. This method does not block if the reply is // not yet arrived. An exception is thrown in this case. // // argin(s) : id : The asynchrnous call identifier // //----------------------------------------------------------------------------- void DeviceProxy::write_attributes_reply(long id) { // // Retrieve request object // TgRequest &req = ApiUtil::instance()->get_pasyn_table()->get_request(id); // // Check request type // if ((req.req_type == TgRequest::CMD_INOUT) || (req.req_type == TgRequest::READ_ATTR)) { ApiAsynExcept::throw_exception(API_BadAsynReqType, "Incompatible request type", "Connection::write_attributes_reply"); } // // Reply arrived ? Throw exception is not yet arrived // if (req.request->poll_response() == false) { TangoSys_OMemStream desc; desc << "Device " << dev_name(); desc << ": Reply for asynchronous call (id = " << id; desc << ") is not yet arrived" << ends; ApiAsynNotThereExcept::throw_exception(API_AsynReplyNotArrived, desc.str(), "DeviceProxy::write_attributes_reply"); } else { // // Check if the reply is an exception // Due to a compatibility pb between omniORB 4.1 and omniORB 4.1 (at least 4.2.0), // we have to also handle CORBA::Request instance throwing exception in its env() and // other methods. This was not the case in omniORB 4.1! // CORBA::Environment_ptr env; try { env = req.request->env(); } catch (CORBA::TRANSIENT &tra) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&tra,cb_excep_mess); if (tra.minor() == omni::TRANSIENT_CallTimedout) { omni420_timeout_wattr(id,cb_excep_mess); } else { set_connection_state(CONNECTION_NOTOK); omni420_except_wattr(id,cb_excep_mess); redo_synch_write_call(req); } } catch(CORBA::SystemException &ex) { set_connection_state(CONNECTION_NOTOK); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&ex,cb_excep_mess); omni420_except_wattr(id,cb_excep_mess); redo_synch_write_call(req); } if (!CORBA::is_nil(env) && (env->exception() != NULL)) { write_attr_except(req.request,id,req.req_type); // // If we arrive here, this means the exception was there due to a server // shutdown but it is now back into operation // Try to redo the call synchronously // redo_synch_write_call(req); } } // // Remove request from request global table. // remove_asyn_request(id); } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attr_except() // // description : Analyse the exception returned by the DII call and // send a Tango::DevFailed exception to the caller // // argin(s) : req : The CORBA request object // id : The asynchrnous call identifier // //----------------------------------------------------------------------------- void DeviceProxy::write_attr_except(CORBA::Request_ptr req,long id,TgRequest::ReqType req_type) { CORBA::Environment_ptr env = req->env(); CORBA::Exception *ex_ptr = env->exception(); // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); if (need_reconnect == false) { CORBA::NVList_ptr req_arg = req->arguments(); const Tango::AttributeValueList *att; const Tango::AttributeValueList_4 *att_4; unsigned int nb_att = 0; CORBA::NamedValue_ptr nv = req_arg->item(0); if (version < 4) { if ((*(nv->value()) >>= att) == true) nb_att = att->length(); } else { if ((*(nv->value()) >>= att_4) == true) nb_att = att_4->length(); } TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << device_name; if (nb_att != 0) { desc << "\nAttribute(s): "; for (unsigned int i = 0;i < nb_att;i++) { (version < 4) ? desc << (*att)[i].name : desc << (*att_4)[i].name; if (i != (nb_att - 1)) desc << ", "; } desc << ends; } remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut", desc.str(), "DeviceProxy::write_attributes_reply()"); } else { set_connection_state(CONNECTION_NOTOK); remove_asyn_request(id); stringstream ss; ss << "Failed to execute write_attribute_asynch on device " << device_name; ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),"DeviceProxy::write_attributes_reply"); } } } CORBA::UnknownUserException *unk_ex; if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex = NULL; Tango::DevFailed ex; const Tango::MultiDevFailed *multi_serv_ex = NULL; Tango::MultiDevFailed m_ex; if (version < 3) { unk_ex->exception() >>= serv_ex; ex = *serv_ex; } else { if ((unk_ex->exception() >>= multi_serv_ex) == true) m_ex = *multi_serv_ex; else { unk_ex->exception() >>= serv_ex; ex = *serv_ex; } } CORBA::NVList_ptr req_arg = req->arguments(); const Tango::AttributeValueList *att; const Tango::AttributeValueList_4 *att_4; unsigned int nb_att = 0; CORBA::NamedValue_ptr nv = req_arg->item(0); if (version < 4) { if ((*(nv->value()) >>= att) == true) nb_att = att->length(); } else { if ((*(nv->value()) >>= att_4) == true) nb_att = att_4->length(); } TangoSys_OMemStream desc; desc << "Failed to execute write_attributes_asynch on device " << device_name; if (nb_att != 0) { desc << "\nAttribute(s): "; for (unsigned int i = 0;i < nb_att;i++) { if (version < 4) desc << (*att)[i].name; else desc << (*att_4)[i].name; if (i != (nb_att - 1)) desc << ", "; } } desc << ends; remove_asyn_request(id); if (version < 3) { Except::re_throw_exception(ex,API_AttributeFailed, desc.str(), "DeviceProxy::write_attributes_reply()"); } else { if (serv_ex != NULL) { Except::re_throw_exception(ex,API_AttributeFailed, desc.str(), "DeviceProxy::write_attributes_reply()"); } if (req_type == TgRequest::WRITE_ATTR) throw Tango::NamedDevFailedList(m_ex, device_name, "DeviceProxy::write_attributes_reply()", API_AttributeFailed); else { // // Transfer this exception into a DevFailed exception // Tango::DevFailed ex(m_ex.errors[0].err_list); Except::re_throw_exception(ex,API_AttributeFailed, desc.str(),"DeviceProxy::write_attributes_reply()"); } } } CORBA::SystemException *sys_ex; if ((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) { set_connection_state(CONNECTION_NOTOK); // // Re-throw nearly all CORBA system exceptions // CORBA::NVList_ptr req_arg = req->arguments(); const Tango::AttributeValueList *att; const Tango::AttributeValueList *att_4; unsigned int nb_att = 0; CORBA::NamedValue_ptr nv = req_arg->item(0); if (version < 4) { if ((*(nv->value()) >>= att) == true) nb_att = att->length(); } else { if ((*(nv->value()) >>= att_4) == true) nb_att = att_4->length(); } char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); // // Check if the exception was a connection exception // In this case, try to ping the device. // If successfull, just returns otherwise, throw the first exception // string ex(cb_excep_mess); string::size_type pos = ex.find("TRANSIENT_ConnectFailed"); string::size_type pos_one = ex.find("EXIST_NoMatch"); if (pos != string::npos || pos_one != string::npos) { try { ping(); return; } catch (Tango::DevFailed &) {} } TangoSys_OMemStream desc; desc << "Failed to execute write_attributes_asynch on device " << device_name; if (nb_att != 0) { desc << "\nAttribute(s): "; for (unsigned int i = 0;i < nb_att;i++) { if (version < 4) desc << (*att)[i].name; else desc << (*att_4)[i].name; if (i != (nb_att - 1)) desc << ", "; } } desc << ends; remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",desc.str(), "DeviceProxy::write_attributes_reply()"); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::retrieve_read_args() // // description : Retrieve the read_attribute asynchrouns call from the // Tango request object which itself contains the CORBA // request object // // argin(s) : req : The Tango request object // att_list : reference to a string vector whihc will be filled // in with attribute(s) name // //----------------------------------------------------------------------------- void DeviceProxy::retrieve_read_args(TgRequest &req,vector &att_list) { att_list.clear(); // // Retrieve which attribute was read // const Tango::DevVarStringArray *att_names = NULL; try { CORBA::NVList_ptr args_ptr = req.request->arguments(); CORBA::NamedValue_ptr arg_ptr = args_ptr->item(0); CORBA::Any *arg_val = arg_ptr->value(); (*arg_val) >>= att_names; for (unsigned loop = 0;loop < att_names->length();loop++) att_list.push_back(string((*att_names)[loop])); } catch (CORBA::SystemException &e) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&e,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to redo the call synchronously on device " << device_name; if (att_names != NULL) { desc << "\nAttribute(s): "; for (unsigned int i = 0;i < att_names->length();i++) { desc << (*att_names)[i]; if (i != (att_names->length() - 1)) desc << ", "; } } desc << ends; ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed", desc.str(), "DeviceProxy::redo_simpl_call()"); } } //----------------------------------------------------------------------------- // // method : DeviceProxy::redo_synch_read_call() // // description : Redo a synchronous read_attribute() call // This is needed for re-connection with asynchronous call // // argin(s) : req : The Tango request object // //----------------------------------------------------------------------------- DeviceAttribute *DeviceProxy::redo_synch_read_call(TgRequest &req) { // // Retrieve which attribute was read // vector att_list; retrieve_read_args(req,att_list); // // Redo the read_attribute but synchronously // DeviceAttribute attrib = read_attribute(att_list[0]); DeviceAttribute *attr_ptr = new DeviceAttribute(attrib); return attr_ptr; } //----------------------------------------------------------------------------- // // method : DeviceProxy::redo_synch_reads_call() // // description : Redo a read-attributes() call but synchronously // This is needed for re-connection with asynchronous call // // argin(s) : req : The Tango request object // //----------------------------------------------------------------------------- vector *DeviceProxy::redo_synch_reads_call(TgRequest &req) { // // Retrieve which attributes was read // vector att_list; retrieve_read_args(req,att_list); // // Redo the read_attributes but synchronously // return read_attributes(att_list); } //----------------------------------------------------------------------------- // // method : DeviceProxy::redo_synch_write_call() // // description : Redo a read-attributes() call but synchronously // This is needed for re-connection with asynchronous call // // argin(s) : req : The Tango request object // //----------------------------------------------------------------------------- void DeviceProxy::redo_synch_write_call(TgRequest &req) { // // Retrieve which attributes was written // const Tango::AttributeValueList *att; try { CORBA::NVList_ptr args_ptr = req.request->arguments(); CORBA::NamedValue_ptr arg_ptr = args_ptr->item(0); CORBA::Any *arg_val = arg_ptr->value(); (*arg_val) >>= att; } catch (CORBA::SystemException &e) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&e,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to redo the call synchronously on device " << device_name << ends; ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed", desc.str(), "DeviceProxy::redo_synch_write_call()"); } // // Redo the write_attributes but synchronously // return write_attribute(*att); } //----------------------------------------------------------------------------- // // method : Connection::redo_synch_cmd() // // description : Redo a command_inout() call but synchronously // This is needed for re-connection with asynchronous call // // argin(s) : req : The Tango request object // //----------------------------------------------------------------------------- DeviceData Connection::redo_synch_cmd(TgRequest &req) { const char *cmd_name = NULL; const CORBA::Any *a_ptr; try { CORBA::NVList_ptr args_ptr = req.request->arguments(); CORBA::NamedValue_ptr arg_ptr = args_ptr->item(0); *(arg_ptr->value()) >>= cmd_name; arg_ptr = args_ptr->item(1); *(arg_ptr->value()) >>= a_ptr; } catch (CORBA::SystemException &e) { char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(&e,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to redo the call synchronously on device " << dev_name() << ends; ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed", desc.str(), "DeviceProxy::redo_synch_write_call()"); } // // Redo the call synchronously // DeviceData dd; CORBA::Any *tmp_any_ptr = new CORBA::Any(*a_ptr); dd.any = tmp_any_ptr; return command_inout(cmd_name,dd); } //----------------------------------------------------------------------------- // // method : Connection::cancel_asynch_request() // // description : Cancel a running asynchronous request // This is a client side call. Obviously, the call cannot be aborted // while it is running in the device. // // argin(s) : id : The asynchronous call identifier // //----------------------------------------------------------------------------- void Connection::cancel_asynch_request(long id) { omni_mutex_lock guard(asyn_mutex); ApiUtil::instance()->get_pasyn_table()->mark_as_cancelled(id); pasyn_ctr--; } //----------------------------------------------------------------------------- // // method : Connection::cancel_all_polling_asynch_request() // // description : Cancel all running asynchronous request // This is a client side call. Obviously, the calls cannot be aborted // while it is running in the device. // // argin(s) : id : The asynchronous call identifier // //----------------------------------------------------------------------------- void Connection::cancel_all_polling_asynch_request() { omni_mutex_lock guard(asyn_mutex); ApiUtil::instance()->get_pasyn_table()->mark_all_polling_as_cancelled(); pasyn_ctr = 0; } //----------------------------------------------------------------------------- // // method : Connection::omni420_xxx // DeviceProxy::omni420_xxx // // description : These methods are there due to the compatibility pb with omniORB // 4.2.0 about CORBA::Request class methods throwing exceptions while // it was not the case in omniORB 4.1! // //----------------------------------------------------------------------------- void Connection::omni420_timeout(int id,char *cb_excep_mess) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } stringstream ss; remove_asyn_request(id); if (need_reconnect == false) { ss << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut",ss.str(), "Connection::command_inout_reply()"); } else { set_connection_state(CONNECTION_NOTOK); ss << "Failed to execute command_inout_asynch on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(), "Connection::command_inout_reply()"); } } DeviceData Connection::omni420_except(int id,char *cb_excep_mess,TgRequest &req) { // // Check if the exception was a connection exception // If so, execute the command synchronously (tries to reconnect) // If successful just return, otherwise throw the first exception // string ex(cb_excep_mess); string::size_type pos = ex.find("TRANSIENT_ConnectFailed"); if (pos != string::npos) { try { DeviceData dd_out = redo_synch_cmd(req); // // Remove request from request global table and return // remove_asyn_request(id); return dd_out; } catch (Tango::DevFailed &) {} } stringstream ss; ss << "Failed to execute command_inout_asynch on device " << dev_name(); remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),"Connection::command_inout_reply"); DeviceData dummy; return dummy; } void DeviceProxy::omni420_timeout_attr(int id,char *cb_excep_mess,read_attr_type type) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } stringstream ss; remove_asyn_request(id); string meth; if (type == SIMPLE) meth = "DeviceProxy::read_attribute_reply()"; else meth = "DeviceProxy::read_attributes_reply()"; if (need_reconnect == false) { ss << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut",ss.str(),meth.c_str()); } else { set_connection_state(CONNECTION_NOTOK); ss << "Failed to execute command_inout_asynch on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),meth.c_str()); } } void DeviceProxy::omni420_except_attr(int id,char *cb_excep_mess,read_attr_type type) { string ex(cb_excep_mess); string::size_type pos = ex.find("TRANSIENT_ConnectFailed"); if (pos != string::npos) { try { ping(); return; } catch (Tango::DevFailed &) {} } stringstream ss; ss << "Failed to execute read_attributes_asynch on device " << device_name; remove_asyn_request(id); string meth; if (type == SIMPLE) meth = "DeviceProxy::read_attribute_reply()"; else meth = "DeviceProxy::read_attributes_reply()"; ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),meth.c_str()); } void DeviceProxy::omni420_timeout_wattr(int id,char *cb_excep_mess) { bool need_reconnect = false; if (ext->has_alt_adr == true) { try { Device_var dev = Device::_duplicate(device); dev->ping(); } catch(CORBA::TRANSIENT &trans_ping) { if (trans_ping.minor() == omni::TRANSIENT_ConnectFailed || trans_ping.minor() == omni::TRANSIENT_CallTimedout) { need_reconnect = true; } } catch(...) {} } stringstream ss; remove_asyn_request(id); if (need_reconnect == false) { ss << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_DeviceTimedOut",ss.str(),"DeviceProxy::write_attributes_reply()"); } else { set_connection_state(CONNECTION_NOTOK); ss << "Failed to execute write_attribute_asynch on device " << dev_name(); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),"DeviceProxy::write_attributes_reply()"); } } void DeviceProxy::omni420_except_wattr(int id,char *cb_excep_mess) { string ex(cb_excep_mess); string::size_type pos = ex.find("TRANSIENT_ConnectFailed"); if (pos != string::npos) { try { ping(); return; } catch (Tango::DevFailed &) {} } stringstream ss; ss << "Failed to execute write_attributes_asynch on device " << device_name; remove_asyn_request(id); ApiCommExcept::re_throw_exception(cb_excep_mess, "API_CommunicationFailed",ss.str(),"DeviceProxy::write_attributes_reply()"); } } // End of tango namespace tango-9.2.5a/lib/cpp/client/proxy_asyn_cb.cpp0000644023471100065110000011077213034744772016142 00000000000000static const char *RcsId = "$Id: proxy_asyn_cb.cpp 29622 2016-04-15 14:09:56Z bourtemb $\n$Name$"; // // cpp - C++ source code file for TANGO api class and asynchronous callback // related methods // // programmer - Emmanuel Taurel (taurel@esrf.fr) // // original - January 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // #if HAVE_CONFIG_H #include #endif #include #ifdef _TG_WINDOWS_ #include #else #include #endif namespace Tango { //----------------------------------------------------------------------------- // // method : Connection::command_inout_asyn() // // description : Send a command to a Tango device asynchrnously. // The client is not blocked until the command is executed // // argin(s) : command : The command name // data_in : Command input data // cb : The callback object // //----------------------------------------------------------------------------- void Connection::command_inout_asynch(const char *command, DeviceData &data_in, CallBack &cb) { // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute command_inout on device " << dev_name(); desc << ", command " << command << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"Connection::command_inout_asynch()"); } // // Create the request object // CORBA::ORB::RequestSeq req_seq; req_seq.length(1); if (version >= 4) req_seq[0] = device_4->_request("command_inout_4"); else if (version >= 2) req_seq[0] = device_2->_request("command_inout_2"); else req_seq[0] = device->_request("command_inout"); req_seq[0]->add_in_arg() <<= command; req_seq[0]->add_in_arg() <<= data_in.any.in(); if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); req_seq[0]->add_in_arg() <<= source; req_seq[0]->add_in_arg() <<= ci; } else if (version >= 2) req_seq[0]->add_in_arg() <<= source; req_seq[0]->set_return_type(CORBA::_tc_any); req_seq[0]->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // and store it in the global asynchronous cb requests table // ApiUtil *au = ApiUtil::instance(); add_asyn_cb_request(req_seq[0],&cb,this,TgRequest::CMD_INOUT); CORBA::ORB_ptr orb = au->get_orb(); orb->send_multiple_requests_deferred(req_seq); if (au->get_asynch_cb_sub_model() == PUSH_CALLBACK) au->get_pasyn_table()->signal(); } //----------------------------------------------------------------------------- // // method : Connection::command_inout_asyn() // // description : Send a command to a Tango device asynchrnously. // The client is not blocked until the command is executed // These methods are only user helper methods which call // the official command_inout_asyn() method // // argin(s) : command : The command name // data_in : Command input data // cb : The callback object // //----------------------------------------------------------------------------- void Connection::command_inout_asynch(string &command, DeviceData &data_in, CallBack &cb) { command_inout_asynch(command.c_str(),data_in,cb); } void Connection::command_inout_asynch(const char *command,CallBack &cb) { DeviceData data_in; command_inout_asynch(command,data_in,cb); } void Connection::command_inout_asynch(string &command,CallBack &cb) { DeviceData data_in; command_inout_asynch(command.c_str(),data_in,cb); } //----------------------------------------------------------------------------- // // method : Connection::get_asynch_replies() // // description : Try to obtain data returned by a command asynchronously // requested. This method does not block if the reply is // not yet arrived. This method fires callback for already // arrived replies. // //----------------------------------------------------------------------------- void Connection::get_asynch_replies() { CORBA::ORB_ptr orb = ApiUtil::instance()->get_orb(); // // First get all replies from ORB buffers // try { while (orb->poll_next_response() == true) { CORBA::Request_ptr req; orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = ApiUtil::instance()->get_pasyn_table()->get_request(req); tg_req.arrived = true; ApiUtil::instance()->get_pasyn_table()->mark_as_arrived(req); // // Is it a request for our device, process it ? // if (tg_req.dev == this) { switch (tg_req.req_type) { case TgRequest::CMD_INOUT : Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } remove_asyn_cb_request(this,req); } } } catch (CORBA::BAD_INV_ORDER &e) { if (e.minor() != omni::BAD_INV_ORDER_RequestNotSentYet) throw; } // // Now check all replies already there // TgRequest *tg_ptr; while ((tg_ptr = ApiUtil::instance()->get_pasyn_table()->get_request(this)) != NULL) { switch (tg_ptr->req_type) { case TgRequest::CMD_INOUT : Cb_Cmd_Request(tg_ptr->request,tg_ptr->cb_ptr); break; case TgRequest::READ_ATTR : Cb_ReadAttr_Request(tg_ptr->request,tg_ptr->cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : Cb_WriteAttr_Request(tg_ptr->request,tg_ptr->cb_ptr); break; } remove_asyn_cb_request(this,tg_ptr->request); } } //----------------------------------------------------------------------------- // // method : Connection::Cb_Cmd_Request() // // description : Fire callback for a command request // // argin(s) : req : The CORBA request object // cb_ptr : The callback object // //----------------------------------------------------------------------------- void Connection::Cb_Cmd_Request(CORBA::Request_ptr req,Tango::CallBack *cb_ptr) { DeviceData data_out; Tango::DevErrorList errors(2); errors.length(0); CORBA::NVList_ptr req_arg = req->arguments(); const char *cmd = NULL; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= cmd; // // Check if the reply is an exception // CORBA::Environment_ptr env = req->env(); if (!CORBA::is_nil(env) && (env->exception() == NULL)) { // // Get received value // const CORBA::Any *received; CORBA::Any &dii_any = req->return_value(); dii_any >>= received; CORBA::Any *server_any = new CORBA::Any(*received); data_out.any = server_any; } else { // // Retrieve exception // CORBA::Exception *ex_ptr = env->exception(); // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; CORBA::UnknownUserException *unk_ex; CORBA::SystemException *sys_ex; bool to_except = false; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { to_except = true; char *tmp = CORBA::string_dup(cmd); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); errors.length(2); errors[0].desc = CORBA::string_dup(cb_excep_mess); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_CorbaException"); errors[0].origin = CORBA::string_dup("Connection::Cb_Cmd_Request()"); string st = desc.str(); errors[1].desc = CORBA::string_dup(st.c_str()); errors[1].severity = Tango::ERR; errors[1].reason = CORBA::string_dup("API_DeviceTimedOut"); errors[1].origin = CORBA::string_dup("Connection::Cb_Cmd_request()"); } } if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex; unk_ex->exception() >>= serv_ex; errors = serv_ex->errors; char *tmp = CORBA::string_dup(cmd); TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << tmp << ends; CORBA::string_free(tmp); long nb_err = errors.length(); errors.length(nb_err + 1); errors[nb_err].severity = Tango::ERR; string st = desc.str(); errors[nb_err].desc = CORBA::string_dup(st.c_str()); errors[nb_err].origin = CORBA::string_dup("Connection::Cb_Cmd_Request()"); errors[nb_err].reason = CORBA::string_dup(API_CommandFailed); } else if (((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) && (to_except == false)) { set_connection_state(CONNECTION_NOTOK); // // Re-throw all CORBA system exceptions // char *tmp = CORBA::string_dup(cmd); char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to execute command_inout_asynch on device " << dev_name(); desc << ", command " << cmd << ends; CORBA::string_free(tmp); errors.length(2); errors[0].desc = CORBA::string_dup(cb_excep_mess); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_CorbaException"); errors[0].origin = CORBA::string_dup("Connection::Cb_Cmd_Request()"); string st = desc.str(); errors[1].desc = CORBA::string_dup(st.c_str()); errors[1].severity = Tango::ERR; errors[1].reason = CORBA::string_dup("API_CommunicationFailed"); errors[1].origin = CORBA::string_dup("Connection::Cb_Cmd_request()"); } } // // Fire Callback // string cmd_str(cmd); DeviceProxy *local_dev = static_cast(this); CmdDoneEvent *cb_data = new CmdDoneEvent(local_dev,cmd_str,data_out,errors); #ifdef HAS_UNIQUE_PTR unique_ptr auto_cb_data(cb_data); #else auto_ptr auto_cb_data(cb_data); #endif cb_ptr->cmd_ended(auto_cb_data.get()); } //----------------------------------------------------------------------------- // // method : Connection::Cb_ReadAttr_Request() // // description : Fire callback for a read attributes request // // argin(s) : req : The CORBA request object // cb_ptr : The callback object // //----------------------------------------------------------------------------- void Connection::Cb_ReadAttr_Request(CORBA::Request_ptr req,Tango::CallBack *cb_ptr) { vector *dev_attr = NULL; Tango::DevErrorList errors(2); errors.length(0); CORBA::NVList_ptr req_arg = req->arguments(); const Tango::DevVarStringArray *names; CORBA::NamedValue_ptr nv = req_arg->item(0); *(nv->value()) >>= names; vector attr_names; attr_names.resize(names->length()); for (unsigned int i = 0;i < names->length();i++) attr_names[i] = (*names)[i]; // // Check if the reply is an exception // CORBA::Environment_ptr env = req->env(); if (!CORBA::is_nil(env) && (env->exception() == NULL)) { // // Get received value // dev_attr = new(vector); const Tango::AttributeValueList *received; const Tango::AttributeValueList_3 *received_3; const Tango::AttributeValueList_4 *received_4; const Tango::AttributeValueList_5 *received_5; unsigned long nb_received; CORBA::Any &dii_any = req->return_value(); switch (version) { case 5: dii_any >>= received_5; nb_received = received_5->length(); break; case 4: dii_any >>= received_4; nb_received = received_4->length(); break; case 3: dii_any >>= received_3; nb_received = received_3->length(); break; default: dii_any >>= received; nb_received = received->length(); break; } dev_attr->resize(nb_received); for (unsigned long i=0; i < nb_received; i++) { if (version >= 3) { if (version == 5) ApiUtil::attr_to_device(&((*received_5)[i]),version,&((*dev_attr)[i])); else if (version == 4) ApiUtil::attr_to_device(&((*received_4)[i]),version,&((*dev_attr)[i])); else ApiUtil::attr_to_device(NULL,&((*received_3)[i]),version,&((*dev_attr)[i])); // // Add an error in the error stack in case there is one // DevErrorList_var &err_list = (*dev_attr)[i].get_error_list(); long nb_except = err_list.in().length(); if (nb_except != 0) { TangoSys_OMemStream desc; desc << "Failed to read_attributes on device " << dev_name(); desc << ", attribute " << (*dev_attr)[i].name << ends; err_list.inout().length(nb_except + 1); err_list[nb_except].reason = CORBA::string_dup(API_AttributeFailed); err_list[nb_except].origin = CORBA::string_dup("Connection::Cb_ReadAttr_Request"); string st = desc.str(); err_list[nb_except].desc = CORBA::string_dup(st.c_str()); err_list[nb_except].severity = Tango::ERR; } } else { ApiUtil::attr_to_device(&((*received)[i]),NULL,version,&((*dev_attr)[i])); } } } else { // // The reply is an exception // CORBA::Exception *ex_ptr = env->exception(); CORBA::UnknownUserException *unk_ex; CORBA::SystemException *sys_ex; bool to_except = false; // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { to_except = true; char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; errors.length(2); errors[0].desc = CORBA::string_dup(cb_excep_mess); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_CorbaException"); errors[0].origin = CORBA::string_dup("Connection::Cb_ReadAttr_Request()"); string st = desc.str(); errors[1].desc = CORBA::string_dup(st.c_str()); errors[1].severity = Tango::ERR; errors[1].reason = CORBA::string_dup("API_DeviceTimedOut"); errors[1].origin = CORBA::string_dup("Connection::Cb_ReadAttr_request()"); } } if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex; unk_ex->exception() >>= serv_ex; errors = serv_ex->errors; TangoSys_OMemStream desc; desc << "Failed to execute read_attribute_asynch on device " << dev_name(); desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; long nb_err = errors.length(); errors.length(nb_err + 1); errors[nb_err].severity = Tango::ERR; string st = desc.str(); errors[nb_err].desc = CORBA::string_dup(st.c_str()); errors[nb_err].origin = CORBA::string_dup("Connection::Cb_ReadAttr_Request()"); errors[nb_err].reason = CORBA::string_dup(API_AttributeFailed); } else if (((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) && (to_except == false)) { set_connection_state(CONNECTION_NOTOK); // // Re-throw all CORBA system exceptions // char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << dev_name(); desc << "\nAttribute(s): "; for (unsigned int i = 0;i < names->length();i++) { desc << (*names)[i]; if (i != (names->length() - 1)) desc << ", "; } desc << ends; errors.length(2); errors[0].desc = CORBA::string_dup(cb_excep_mess); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_CorbaException"); errors[0].origin = CORBA::string_dup("Connection::Cb_ReadAttr_Request()"); string st = desc.str(); errors[1].desc = CORBA::string_dup(st.c_str()); errors[1].severity = Tango::ERR; errors[1].reason = CORBA::string_dup("API_CommunicationFailed"); errors[1].origin = CORBA::string_dup("Connection::Cb_ReadAttr_Request()"); } } // // Fire Callback // DeviceProxy *local_dev = static_cast(this); AttrReadEvent *cb_data = new AttrReadEvent(local_dev,attr_names,dev_attr,errors); #ifdef HAS_UNIQUE_PTR unique_ptr auto_cb_data(cb_data); #else auto_ptr auto_cb_data(cb_data); #endif cb_ptr->attr_read(auto_cb_data.get()); } //----------------------------------------------------------------------------- // // method : Connection::Cb_WriteAttr_Request() // // description : Fire callback for a write attribute request // // argin(s) : req : The CORBA request object // cb_ptr : The callback object // //----------------------------------------------------------------------------- void Connection::Cb_WriteAttr_Request(CORBA::Request_ptr req,Tango::CallBack *cb_ptr) { Tango::NamedDevFailedList err_3; CORBA::NVList_ptr req_arg = req->arguments(); const Tango::AttributeValueList *att; const Tango::AttributeValueList_4 *att_4; CORBA::NamedValue_ptr nv = req_arg->item(0); long nb_attr = 0; if (version >= 4) { if ((*(nv->value()) >>= att_4) == true) nb_attr = att_4->length(); } else { if ((*(nv->value()) >>= att) == true) nb_attr = att->length(); } // // Check if the reply is an exception // CORBA::Environment_ptr env = req->env(); if (!CORBA::is_nil(env) && (env->exception() != NULL)) { // // The reply is an exception // CORBA::Exception *ex_ptr = env->exception(); CORBA::UnknownUserException *unk_ex; CORBA::SystemException *sys_ex; bool to_except = false; // // Special treatement for timeout exception (TRANSIENT with specific minor code) // CORBA::TRANSIENT *tra; if ((tra = CORBA::TRANSIENT::_downcast(ex_ptr)) != NULL) { if (tra->minor() == omni::TRANSIENT_CallTimedout) { to_except = true; char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(tra,cb_excep_mess); TangoSys_OMemStream desc; desc << "Timeout (" << timeout << " mS) exceeded on device " << dev_name(); if (nb_attr != 0) { desc << "\nAttribute(s): "; for (int i = 0;i < nb_attr;i++) { (version < 4) ? desc << (*att)[i].name : desc << (*att_4)[i].name; if (i != (nb_attr - 1)) desc << ", "; } } desc << ends; err_3.errors.length(2); err_3.errors[0].desc = CORBA::string_dup(cb_excep_mess); err_3.errors[0].severity = Tango::ERR; err_3.errors[0].reason = CORBA::string_dup("API_CorbaException"); err_3.errors[0].origin = CORBA::string_dup("Connection::Cb_WriteAttr_Request()"); string st = desc.str(); err_3.errors[1].desc = CORBA::string_dup(st.c_str()); err_3.errors[1].severity = Tango::ERR; err_3.errors[1].reason = CORBA::string_dup("API_DeviceTimedOut"); err_3.errors[1].origin = CORBA::string_dup("Connection::Cb_WriteAttr_request()"); } } if ((unk_ex = CORBA::UnknownUserException::_downcast(ex_ptr)) != NULL) { // // It is a UserUnknownException exception. This means that the // server has sent a DevFailed exception // const Tango::DevFailed *serv_ex = NULL; Tango::DevFailed ex; const Tango::MultiDevFailed *multi_serv_ex = NULL; Tango::MultiDevFailed m_ex; TangoSys_OMemStream desc; if (version < 3) { unk_ex->exception() >>= serv_ex; ex = *serv_ex; desc << "Failed to execute write_attributes_asynch on device " << dev_name(); if (nb_attr != 0) desc << "\nAttribute(s): "; for (int i = 0;i < nb_attr;i++) { desc << (*att)[i].name.in(); if (i != (nb_attr - 1)) desc << ", "; } desc << ends; err_3.errors.length(1); err_3.errors[0].severity = Tango::ERR; string st = desc.str(); err_3.errors[0].desc = CORBA::string_dup(st.c_str()); err_3.errors[0].origin = CORBA::string_dup("Connection::Cb_WriteAttr_Request()"); err_3.errors[0].reason = CORBA::string_dup(API_AttributeFailed); err_3.err_list.resize(1); err_3.err_list[0].err_stack = serv_ex->errors; err_3.err_list[0].name = (*att)[0].name.in(); err_3.err_list[0].idx_in_call = 0; } else { if ((unk_ex->exception() >>= multi_serv_ex) == true) { m_ex = *multi_serv_ex; err_3 = Tango::NamedDevFailedList(m_ex, dev_name(), (const char *)"Connection::Cb_WriteAttr_Request()", (const char *)API_AttributeFailed); } else { unk_ex->exception() >>= serv_ex; ex = *serv_ex; desc << "Failed to execute write_attributes_asynch on device " << dev_name(); if (nb_attr != 0) desc << "\nAttribute(s): "; for (int i = 0;i < nb_attr;i++) { (version < 4) ? desc << (*att)[i].name : desc << (*att_4)[i].name; if (i != (nb_attr - 1)) desc << ", "; } desc << ends; err_3.errors.length(1); err_3.errors[0].severity = Tango::ERR; string st = desc.str(); err_3.errors[0].desc = CORBA::string_dup(st.c_str()); err_3.errors[0].origin = CORBA::string_dup("Connection::Cb_WriteAttr_Request()"); err_3.errors[0].reason = CORBA::string_dup(API_AttributeFailed); err_3.err_list.resize(1); err_3.err_list[0].err_stack = serv_ex->errors; err_3.err_list[0].name = (*att)[0].name.in(); err_3.err_list[0].idx_in_call = 0; } } } else if (((sys_ex = CORBA::SystemException::_downcast(ex_ptr)) != NULL) && (to_except == false)) { set_connection_state(CONNECTION_NOTOK); // // Re-throw all CORBA system exceptions // char cb_excep_mess[256]; Tango::Except::print_CORBA_SystemException_r(sys_ex,cb_excep_mess); TangoSys_OMemStream desc; desc << "Failed to execute write_attributes_asynch on device " << dev_name(); if (nb_attr != 0) desc << "\nAttribute(s): "; for (int i = 0;i < nb_attr;i++) { (version < 4) ? desc << (*att)[i].name : desc << (*att_4)[i].name; if (i != (nb_attr - 1)) desc << ", "; } desc << ends; err_3.errors.length(2); err_3.errors[0].desc = CORBA::string_dup(cb_excep_mess); err_3.errors[0].severity = Tango::ERR; err_3.errors[0].reason = CORBA::string_dup("API_CorbaException"); err_3.errors[0].origin = CORBA::string_dup("Connection::Cb_WriteAttr_Request()"); string st = desc.str(); err_3.errors[1].desc = CORBA::string_dup(st.c_str()); err_3.errors[1].severity = Tango::ERR; err_3.errors[1].reason = CORBA::string_dup("API_CommunicationFailed"); err_3.errors[1].origin = CORBA::string_dup("Connection::Cb_WriteAttr_Request()"); } } // // Fire Callback // vector att_name; if (version >= 4) { for (int i = 0;i < nb_attr;i++) att_name.push_back((*att_4)[i].name.in()); } else { for (int i = 0;i < nb_attr;i++) att_name.push_back((*att)[i].name.in()); } DeviceProxy *local_dev = static_cast(this); AttrWrittenEvent *cb_data = new AttrWrittenEvent(local_dev,att_name,err_3); #ifdef HAS_UNIQUE_PTR unique_ptr auto_cb_data(cb_data); #else auto_ptr auto_cb_data(cb_data); #endif cb_ptr->attr_written(auto_cb_data.get()); } //----------------------------------------------------------------------------- // // method : Connection::get_asynch_replies() // // description : Try to obtain data returned by a command asynchronously // requested. This method block for the specified timeout // if the reply is not yet arrived. This method fires // callback when the reply arived. If the timeout is // set to 0, the call wait undefinitely wait the reply. // // argin(s) : call_timeout : The timeout in mS // //----------------------------------------------------------------------------- void Connection::get_asynch_replies(long call_timeout) { // // First check all replies already there // TgRequest *tg_ptr; while ((tg_ptr = ApiUtil::instance()->get_pasyn_table()->get_request(this)) != NULL) { switch (tg_ptr->req_type) { case TgRequest::CMD_INOUT : Cb_Cmd_Request(tg_ptr->request,tg_ptr->cb_ptr); break; case TgRequest::READ_ATTR : Cb_ReadAttr_Request(tg_ptr->request,tg_ptr->cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : Cb_WriteAttr_Request(tg_ptr->request,tg_ptr->cb_ptr); break; } remove_asyn_cb_request(this,tg_ptr->request); } // // If they are requests already sent but without being replied yet // if (get_pasyn_cb_ctr() != 0) { CORBA::ORB_ptr orb = ApiUtil::instance()->get_orb(); CORBA::Request_ptr req; if (call_timeout != 0) { // // A timeout has been specified. Wait if there are still request without // replies but not more than the specified timeout. Leave method if the // timeout is not arrived but there is no more request without reply // long nb = call_timeout / 20; #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 20000000; #endif while ((nb > 0) && (get_pasyn_cb_ctr() != 0)) { #ifdef _TG_WINDOWS_ Sleep(20); #else nanosleep(&to_wait,&inter); #endif nb--; if (orb->poll_next_response() == true) { orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = ApiUtil::instance()->get_pasyn_table()->get_request(req); tg_req.arrived = true; ApiUtil::instance()->get_pasyn_table()->mark_as_arrived(req); // // Is it a request for our device, process it ? // if (tg_req.dev == this) { switch (tg_req.req_type) { case TgRequest::CMD_INOUT : Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } remove_asyn_cb_request(this,req); } } } // // Throw exception if the timeout has expired but there are still request // without replies // if ((nb == 0) && (get_pasyn_cb_ctr() != 0)) { TangoSys_OMemStream desc; desc << "Still some reply(ies) for asynchronous callback call(s) to be received" << ends; ApiAsynNotThereExcept::throw_exception((const char *)API_AsynReplyNotArrived, desc.str(), (const char *)"Connection::get_asynch_replies"); } } else { // // If timeout is set to 0, this means wait until all the requests sent to this // device has sent their replies // while (get_pasyn_cb_ctr() != 0) { orb->get_next_response(req); // // Retrieve this request in the cb request map and mark it as "arrived" in both maps // TgRequest &tg_req = ApiUtil::instance()->get_pasyn_table()->get_request(req); tg_req.arrived = true; ApiUtil::instance()->get_pasyn_table()->mark_as_arrived(req); // // Is it a request for our device, process it ? // if (tg_req.dev == this) { switch (tg_req.req_type) { case TgRequest::CMD_INOUT : Cb_Cmd_Request(req,tg_req.cb_ptr); break; case TgRequest::READ_ATTR : Cb_ReadAttr_Request(req,tg_req.cb_ptr); break; case TgRequest::WRITE_ATTR : case TgRequest::WRITE_ATTR_SINGLE : Cb_WriteAttr_Request(req,tg_req.cb_ptr); break; } remove_asyn_cb_request(this,req); } } } } } //----------------------------------------------------------------------------- // // method : DeviceProxy::read_attributes_asynch() // // description : Read Tango device attributes asynchrnously. // The client is not blocked until the attributes are read // // argin(s) : attr_names : The attribute name(s) // cb : The callback object // //----------------------------------------------------------------------------- void DeviceProxy::read_attributes_asynch(vector &attr_names,CallBack &cb) { // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"DeviceProxy::read_attributes_asynch()"); } // // Check that the caller did not give two times the same attribute // same_att_name(attr_names,"DeviceProxy::read_attributes_asynch"); // // Create the request object // CORBA::ORB::RequestSeq req_seq; req_seq.length(1); Tango::DevVarStringArray names; long nb_names = attr_names.size(); names.length(nb_names); for (int i = 0;i < nb_names;i++) names[i] = attr_names[i].c_str(); if (version >= 5) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); req_seq[0] = Connection::device_5->_request("read_attributes_5"); req_seq[0]->add_in_arg() <<= names; req_seq[0]->add_in_arg() <<= source; req_seq[0]->add_in_arg() <<= ci; req_seq[0]->set_return_type(Tango::_tc_AttributeValueList_5); } else if (version == 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); req_seq[0] = Connection::device_4->_request("read_attributes_4"); req_seq[0]->add_in_arg() <<= names; req_seq[0]->add_in_arg() <<= source; req_seq[0]->add_in_arg() <<= ci; req_seq[0]->set_return_type(Tango::_tc_AttributeValueList_4); } else if (version == 3) { req_seq[0] = Connection::device_3->_request("read_attributes_3"); req_seq[0]->add_in_arg() <<= names; req_seq[0]->add_in_arg() <<= source; req_seq[0]->set_return_type(Tango::_tc_AttributeValueList_3); } else if (version == 2) { req_seq[0] = device_2->_request("read_attributes_2"); req_seq[0]->add_in_arg() <<= names; req_seq[0]->add_in_arg() <<= source; req_seq[0]->set_return_type(Tango::_tc_AttributeValueList); } else { req_seq[0] = device->_request("read_attributes"); req_seq[0]->add_in_arg() <<= names; req_seq[0]->set_return_type(Tango::_tc_AttributeValueList); } req_seq[0]->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // and store it in the global asynchronous cb requests table // ApiUtil *au = ApiUtil::instance(); add_asyn_cb_request(req_seq[0],&cb,this,TgRequest::READ_ATTR); CORBA::ORB_ptr orb = au->get_orb(); orb->send_multiple_requests_deferred(req_seq); if (au->get_asynch_cb_sub_model() == PUSH_CALLBACK) au->get_pasyn_table()->signal(); } void DeviceProxy::read_attribute_asynch(string &attr_name,CallBack &cb) { vector tmp_att_names(1,attr_name); read_attributes_asynch(tmp_att_names,cb); } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attributes_asynch() // // description : Write Tango device attributes asynchronously. // The client is not blocked until the attributes are written // // argin(s) : attr_list : The attribute name(s) and value(s) // cb : The callback object // //----------------------------------------------------------------------------- void DeviceProxy::write_attributes_asynch(vector &attr_list, CallBack &cb) { // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"DeviceProxy::write_attributes_asynch()"); } // // Create the request object // CORBA::ORB::RequestSeq req_seq; req_seq.length(1); Tango::AttributeValueList att; Tango::AttributeValueList_4 att_4; long nb_attr = attr_list.size(); if (version < 4) att.length(nb_attr); else att_4.length(nb_attr); for (int i = 0;i < nb_attr;i++) { if (version < 4) ApiUtil::device_to_attr(attr_list[i],att[i],device_name); else ApiUtil::device_to_attr(attr_list[i],att_4[i]); } if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); req_seq[0] = device_4->_request("write_attributes_4"); req_seq[0]->add_in_arg() <<= att_4; req_seq[0]->add_in_arg() <<= ci; req_seq[0]->exceptions()->add(Tango::_tc_MultiDevFailed); } else if (version == 3) { req_seq[0] = device->_request("write_attributes_3"); req_seq[0]->add_in_arg() <<= att; req_seq[0]->exceptions()->add(Tango::_tc_MultiDevFailed); } else { req_seq[0] = device->_request("write_attributes"); req_seq[0]->add_in_arg() <<= att; } req_seq[0]->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // and store it in the global asynchronous cb requests table // ApiUtil *au = ApiUtil::instance(); add_asyn_cb_request(req_seq[0],&cb,this,TgRequest::WRITE_ATTR); CORBA::ORB_ptr orb = au->get_orb(); orb->send_multiple_requests_deferred(req_seq); if (au->get_asynch_cb_sub_model() == PUSH_CALLBACK) au->get_pasyn_table()->signal(); } //----------------------------------------------------------------------------- // // method : DeviceProxy::write_attribute_asynch() // // description : Write Tango device attribute asynchronously. // The client is not blocked until the attributes are written // // WARNING : Obviously, this method could simply create // a vector of DeviceAttribute and call the previous // method (write_attributes_asynch (note the attributes)) // using this vector. But the copy constructor of the // DeviceAttribute class, pass the memory to the newly // created DeviceAttribute object !!!! // Therefore, it is not possible to use this solution // in this case // // argin(s) : attr_list : The attribute name(s) and value(s) // cb : The callback object // //----------------------------------------------------------------------------- void DeviceProxy::write_attribute_asynch(DeviceAttribute &attr,CallBack &cb) { // // Reconnect to device in case it is needed // try { check_and_reconnect(); } catch (Tango::ConnectionFailed &e) { TangoSys_OMemStream desc; desc << "Failed to execute read_attributes_asynch on device " << dev_name() << ends; ApiConnExcept::re_throw_exception(e,(const char*)API_CommandFailed, desc.str(), (const char*)"DeviceProxy::write_attributes_asynch()"); } // // Create the request object // CORBA::ORB::RequestSeq req_seq; req_seq.length(1); Tango::AttributeValueList att; Tango::AttributeValueList_4 att_4; if (version < 4) { att.length(1); ApiUtil::device_to_attr(attr,att[0],device_name); } else { att_4.length(1); ApiUtil::device_to_attr(attr,att_4[0]); } if (version >= 4) { ClntIdent ci; ApiUtil *au = ApiUtil::instance(); ci.cpp_clnt(au->get_client_pid()); req_seq[0] = device_4->_request("write_attributes_4"); req_seq[0]->add_in_arg() <<= att_4; req_seq[0]->add_in_arg() <<= ci; req_seq[0]->exceptions()->add(Tango::_tc_MultiDevFailed); } else if (version == 3) { req_seq[0] = device->_request("write_attributes_3"); req_seq[0]->add_in_arg() <<= att; req_seq[0]->exceptions()->add(Tango::_tc_MultiDevFailed); } else { req_seq[0] = device->_request("write_attributes"); req_seq[0]->add_in_arg() <<= att; } req_seq[0]->exceptions()->add(Tango::_tc_DevFailed); // // Send the request // and store it in the global asynchronous cb requests table // ApiUtil *au = ApiUtil::instance(); add_asyn_cb_request(req_seq[0],&cb,this,TgRequest::WRITE_ATTR_SINGLE); CORBA::ORB_ptr orb = au->get_orb(); orb->send_multiple_requests_deferred(req_seq); if (au->get_asynch_cb_sub_model() == PUSH_CALLBACK) au->get_pasyn_table()->signal(); } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/attr_proxy.cpp0000644023471100065110000011015313034744772015467 00000000000000static const char *RcsId = "$Id: attr_proxy.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; // // attr_proxy.cpp - C++ source code file for TANGO attribute proxy api // // programmer(s) - Andy Gotz (goetz@esrf.fr) // // original - July 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // version - $Version$ // #if HAVE_CONFIG_H #include #endif #include #include #ifdef _TG_WINDOWS_ #include #else #include #endif /* _TG_WINDOWS_ */ #include #include #include using namespace CORBA; namespace Tango { //----------------------------------------------------------------------------- // // AttributeProxy::AttributeProxy() - constructor for attribute proxy object // //----------------------------------------------------------------------------- AttributeProxy::AttributeProxy (string &name):dev_proxy(NULL),ext(Tango_nullptr) { real_constructor(name); } AttributeProxy::AttributeProxy (const char *na):dev_proxy(NULL),ext(Tango_nullptr) { string name(na); real_constructor(name); } void AttributeProxy::real_constructor (string &name) { // // parse device name // parse_name(name); string corba_name; // // Create the associated DeviceProxy object // if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); dev_proxy = new DeviceProxy(device_name); if (alias_name.empty() == false && dev_proxy != Tango_nullptr) device_name = dev_proxy->dev_name(); if (ui->in_server() == true) db_attr = new DbAttribute(attr_name,device_name,Tango::Util::instance()->get_database()); else db_attr = new DbAttribute(attr_name,device_name); int ind = ui->get_db_ind(); db_host = (ui->get_db_vect())[ind]->get_db_host(); db_port = (ui->get_db_vect())[ind]->get_db_port(); db_port_num = (ui->get_db_vect())[ind]->get_db_port_num(); } else { string noenv_dev_name(db_host); noenv_dev_name = noenv_dev_name + ":" + db_port + "/" + device_name; dev_proxy = new DeviceProxy(noenv_dev_name); db_attr = new DbAttribute(attr_name,device_name,db_host,db_port); } } else { db_attr = NULL; string::size_type stop; stop = name.rfind(DEVICE_SEP); string nodb_dev_name = name.substr(0,stop); nodb_dev_name = nodb_dev_name + MODIFIER_DBASE_NO; dev_proxy = new DeviceProxy(nodb_dev_name); } // // Check that the device support this attribute // try { dev_proxy->get_attribute_config(attr_name); } catch (Tango::ConnectionFailed &) {} catch (Tango::CommunicationFailed &) {} catch (Tango::DevFailed &dfe) { delete db_attr; delete dev_proxy; if (strcmp(dfe.errors[0].reason.in(),API_AttrNotFound) == 0) { TangoSys_OMemStream desc; desc << "Attribute " << attr_name << " is not supported by device " << device_name << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedAttribute", desc.str(), (const char*)"AttributeProxy::real_constructor()"); } } } void AttributeProxy::ctor_from_dp(const DeviceProxy *dev_ptr,string &att_name) { // // First copy DeviceProxy object // dev_proxy = new DeviceProxy(); *dev_proxy = *dev_ptr; // // Init local data members from device proxy object // dbase_used = dev_proxy->dbase_used; from_env_var = dev_proxy->from_env_var; host = dev_proxy->host; port = dev_proxy->port; port_num = dev_proxy->port_num; db_host = dev_proxy->db_host; db_port = dev_proxy->db_port; db_port_num = dev_proxy->db_port_num; attr_name = att_name; // // Now AttributeProxy members // device_name = dev_proxy->device_name; if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) { db_attr = new DbAttribute(attr_name,device_name,Tango::Util::instance()->get_database()); } else { db_attr = new DbAttribute(attr_name,device_name); } } else { db_attr = new DbAttribute(attr_name,device_name,db_host,db_port); } } // // Check that the device support this attribute // try { dev_proxy->get_attribute_config(attr_name); } catch (Tango::ConnectionFailed &) {} catch (Tango::CommunicationFailed &) {} catch (Tango::DevFailed &dfe) { delete db_attr; delete dev_proxy; if (strcmp(dfe.errors[0].reason.in(),API_AttrNotFound) == 0) { TangoSys_OMemStream desc; desc << "Attribute " << attr_name << " is not supported by device " << device_name << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedAttribute", desc.str(), (const char*)"AttributeProxy::ctor_from_dp()"); } } } AttributeProxy::AttributeProxy (const DeviceProxy *dev_ptr,const char *att_name):ext(Tango_nullptr) { string att_na(att_name); ctor_from_dp(dev_ptr,att_na); } AttributeProxy::AttributeProxy (const DeviceProxy *dev_ptr,string &att_name):ext(Tango_nullptr) { ctor_from_dp(dev_ptr,att_name); } //----------------------------------------------------------------------------- // // AttributeProxy::AttributeProxy() - copy constructor // //----------------------------------------------------------------------------- AttributeProxy::AttributeProxy(const AttributeProxy &prev):ext(Tango_nullptr) { // // First Connection call members // dbase_used = prev.dbase_used; from_env_var = prev.from_env_var; host = prev.host; port = prev.port; port_num = prev.port_num; db_host = prev.db_host; db_port = prev.db_port; db_port_num = prev.db_port_num; // // Now AttributeProxy members // device_name = prev.device_name; alias_name = prev.alias_name; if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) { db_attr = new DbAttribute(attr_name,device_name,Tango::Util::instance()->get_database()); dev_proxy = new DeviceProxy(device_name); } else { string noenv_dev_name(db_host); noenv_dev_name = noenv_dev_name + ":" + db_port + "/" + device_name; dev_proxy = new DeviceProxy(noenv_dev_name); db_attr = new DbAttribute(attr_name,device_name); } } else { db_attr = new DbAttribute(attr_name,device_name,db_host,db_port); dev_proxy = new DeviceProxy(device_name); } } #ifdef HAS_UNIQUE_PTR if (prev.ext.get() != NULL) { ext.reset(new AttributeProxyExt); } #else if (prev.ext != NULL) { ext = new AttributeProxyExt(); *ext = *(prev.ext); } else ext = NULL; #endif } //----------------------------------------------------------------------------- // // AttributeProxy::AttributeProxy() - assignment operator // //----------------------------------------------------------------------------- AttributeProxy &AttributeProxy::operator=(const AttributeProxy &rval) { if (this != &rval) { // // First Connection call members // if (dbase_used == true) delete db_attr; dbase_used = rval.dbase_used; from_env_var = rval.from_env_var; host = rval.host; port = rval.port; port_num = rval.port_num; db_host = rval.db_host; db_port = rval.db_port; db_port_num = rval.db_port_num; // // Now AttributeProxy members // attr_name = rval.attr_name; device_name = rval.device_name; alias_name = rval.alias_name; if (dbase_used == true) { if (from_env_var == true) { ApiUtil *ui = ApiUtil::instance(); if (ui->in_server() == true) { db_attr = new DbAttribute(attr_name,device_name,Tango::Util::instance()->get_database()); dev_proxy = new DeviceProxy(device_name); } else { db_attr = new DbAttribute(attr_name,device_name); dev_proxy = new DeviceProxy(device_name); } } else { string noenv_dev_name(db_host); noenv_dev_name = noenv_dev_name + ":" + db_port + "/" + device_name; dev_proxy = new DeviceProxy(noenv_dev_name); db_attr = new DbAttribute(attr_name,device_name,db_host,db_port); } } #ifdef HAS_UNIQUE_PTR if (rval.ext.get() != NULL) ext.reset(new AttributeProxyExt); else ext.reset(); #else if (rval.ext != NULL) { ext = new AttributeProxyExt(); *ext = *(rval.ext); } else ext = NULL; #endif } return *this; } //----------------------------------------------------------------------------- // // AttributeProxy::parse_name() - Parse attribute name according to Tango device // name syntax // // in : - full_name : The attribute name // //----------------------------------------------------------------------------- void AttributeProxy::parse_name(string &full_name) { string name_wo_prot; string name_wo_db_mod; // // Attribute name in lower case letters // string cased_name = full_name; transform(full_name.begin(),full_name.end(),full_name.begin(),::tolower); // // Try to find protocol specification in attribute name and analyse it // string::size_type pos = full_name.find(PROT_SEP); if (pos == string::npos) { if (full_name.size() > 2) { if ((full_name[0] == '/') && (full_name[1] == '/')) name_wo_prot = full_name.substr(2); else name_wo_prot = full_name; } else name_wo_prot = full_name; } else { string protocol = full_name.substr(0,pos); if (protocol == TANGO_PROTOCOL) { name_wo_prot = full_name.substr(pos + 3); } else if (protocol == TACO_PROTOCOL) { TangoSys_OMemStream desc; desc << "Taco protocol is not supported" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedProtocol", desc.str(), (const char*)"AttributeProxy::parse_name()"); } else { TangoSys_OMemStream desc; desc << protocol; desc << " protocol is an unsupported protocol" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedProtocol", desc.str(), (const char*)"AttributeProxy::parse_name()"); } } // // Try to find database database modifier and analyse it // pos = name_wo_prot.find(MODIFIER); if (pos != string::npos) { string mod = name_wo_prot.substr(pos + 1); if (mod == DBASE_YES) { string::size_type len = name_wo_prot.size(); name_wo_db_mod = name_wo_prot.substr(0,len - (len - pos)); dbase_used = true; } else if (mod == DBASE_NO) { string::size_type len = name_wo_prot.size(); name_wo_db_mod = name_wo_prot.substr(0,len - (len - pos)); dbase_used = false; } else { TangoSys_OMemStream desc; desc << mod; desc << " modifier is an unsupported db modifier" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedDBaseModifier", desc.str(), (const char*)"AttributeProxy::parse_name()"); } } else { name_wo_db_mod = name_wo_prot; dbase_used = true; } if (dbase_used == false) { // // Extract host name and port number // pos = name_wo_db_mod.find(HOST_SEP); if (pos == string::npos) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Host and port not correctly defined in device name", (const char*)"AttributeProxy::parse_name()"); } host = name_wo_db_mod.substr(0,pos); string::size_type tmp = name_wo_db_mod.find(PORT_SEP); if (tmp == string::npos) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Host and port not correctly defined in device name", (const char*)"AttributeProxy::parse_name()"); } port = name_wo_db_mod.substr(pos + 1,tmp - pos - 1); TangoSys_MemStream s; s << port << ends; s >> port_num; device_name = name_wo_db_mod.substr(tmp + 1); db_host = db_port = NOT_USED; db_port_num = 0; } else { // // Search if host and port are specified // pos = name_wo_db_mod.find(PORT_SEP); if (pos == string::npos) { device_name = name_wo_db_mod; from_env_var = true; port_num = 0; host = FROM_IOR; port = FROM_IOR; } else { string bef_sep = name_wo_db_mod.substr(0,pos); string::size_type tmp = bef_sep.find(HOST_SEP); if (tmp == string::npos) { device_name = name_wo_db_mod; from_env_var = true; port_num = 0; port = FROM_IOR; host = FROM_IOR; } else { db_host = bef_sep.substr(0,tmp); db_port = bef_sep.substr(tmp + 1); TangoSys_MemStream s; s << db_port << ends; s >> db_port_num; device_name = name_wo_db_mod.substr(pos + 1); from_env_var = false; port_num = 0; port = FROM_IOR; host = FROM_IOR; } } } // // decompose device_name into device and attribute // int n_sep = 0; string device_name_tmp(device_name); string::size_type device_name_end_pos=0; do { pos = device_name_tmp.find(DEVICE_SEP); if (pos != string::npos) { if (pos == 0) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Attribute name must have four fields separated by /'s or no /'s at all if it is an alias (e.g. my/device/name/an_attr or myalias)", (const char*)"AttributeProxy::parse_name()"); } n_sep++; device_name_tmp = device_name_tmp.substr(pos+1); if (device_name_tmp.size() == 0) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Attribute name must have four fields separated by /'s or no /'s at all if it is an alias (e.g. my/device/name/an_attr or myalias)", (const char*)"AttributeProxy::parse_name()"); } device_name_end_pos += pos+1; } } while (pos != string::npos); if ((n_sep > 1) && (n_sep != 3)) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Attribute name must have four fields separated by /'s or no /'s at all if it is an alias (e.g. my/device/name/an_attr or myalias)", (const char*)"AttributeProxy::parse_name()"); } // // if this is an alias (no slashes in name) then get the device and attribute // name from the database // if (n_sep == 0) { if (dbase_used == false) { ApiWrongNameExcept::throw_exception((const char *)API_WrongAttributeNameSyntax, (const char *)"Attribute alias is not supported when not using database", (const char *)"AttributeProxy::parse_name()"); } // // Check alias name syntax // pos = device_name.find(HOST_SEP); if (pos != string::npos) { ApiWrongNameExcept::throw_exception((const char *)API_WrongAttributeNameSyntax, (const char *)"Wrong alias name (: not allowed in alias name)", (const char *)"AttributeProxy::parse_name()"); } pos = device_name.find(RES_SEP); if (pos != string::npos) { ApiWrongNameExcept::throw_exception((const char *)API_WrongAttributeNameSyntax, (const char *)"Wrong alias name (-> not allowed in alias name)", (const char *)"DeviceProxy::parse_name()"); } // // Get full attribute name from database but connect to database first if it is not done already // ApiUtil *ui = ApiUtil::instance(); string db_attr_name; if (from_env_var == true) { if (ui->in_server() == true) { try { Tango::Util::instance()->get_database()->get_attribute_alias(device_name,db_attr_name); } catch (DevFailed &dfe) { if (strcmp(dfe.errors[0].reason,"DB_SQLError") == 0) { TangoSys_OMemStream desc; desc << "Can't connect to attribute with alias " << device_name << ends; ApiConnExcept::re_throw_exception(dfe, (const char *)"API_AliasNotDefined", desc.str(), (const char *)"AttributeProxy::parse_name"); } else throw; } } else { int ind = ui->get_db_ind(); try { (ui->get_db_vect())[ind]->get_attribute_alias(device_name,db_attr_name); } catch (DevFailed &dfe) { if (strcmp(dfe.errors[0].reason,"DB_SQLError") == 0) { TangoSys_OMemStream desc; desc << "Can't connect to attribute with alias " << device_name << ends; ApiConnExcept::re_throw_exception(dfe, (const char *)"API_AliasNotDefined", desc.str(), (const char *)"AttributeProxy::parse_name"); } else throw; } } } else { int ind = ui->get_db_ind(db_host,db_port_num); try { (ui->get_db_vect())[ind]->get_attribute_alias(device_name,db_attr_name); } catch (DevFailed &dfe) { if (strcmp(dfe.errors[0].reason,"DB_SQLError") == 0) { TangoSys_OMemStream desc; desc << "Can't connect to attribute with alias " << device_name << ends; ApiConnExcept::re_throw_exception(dfe, (const char *)"API_AliasNotDefined", desc.str(), (const char *)"AttributeProxy::parse_name"); } else throw; } } // // A fast syntax check on the full attribute name returned from the database // string attr_name_tmp = db_attr_name; do { pos = attr_name_tmp.find(DEVICE_SEP); if (pos != string::npos) { n_sep++; attr_name_tmp = attr_name_tmp.substr(pos+1); device_name_end_pos += pos+1; } } while (pos != string::npos); if (n_sep != 3) { ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Attribute name must have four fields separated by /'s (check the alias entry in the database) ", (const char*)"AttributeProxy::parse_name()"); } attr_name = db_attr_name.substr(device_name_end_pos); device_name = db_attr_name.substr(0,device_name_end_pos - 1); } // // attribute name has four fields, separate them into device and attribute names // but keep attr_name as a case sentitive name // else { device_name = device_name.substr(0,device_name_end_pos - 1); if (n_sep == 1) { if (db_host == NOT_USED) { // // We are in the following case "device alias/attribute name" // but the no dbase option was used. This is an error. // We can't have alias without db // ApiWrongNameExcept::throw_exception((const char*)API_WrongAttributeNameSyntax, (const char*)"Can't use device or attribute alias without database", (const char*)"AttributeProxy::parse_name()"); } if (from_env_var == false) { pos = name_wo_db_mod.rfind(DEVICE_SEP); device_name = name_wo_db_mod.substr(0,pos); } alias_name = device_name; } pos = cased_name.rfind(DEVICE_SEP); string::size_type pos_mod = cased_name.rfind(MODIFIER); if (pos_mod != string::npos) attr_name = cased_name.substr(pos + 1,pos_mod - (pos + 1)); else attr_name = cased_name.substr(pos + 1); } } //----------------------------------------------------------------------------- // // AttributeProxy::~AttributeProxy() - destructor to destroy proxy to TANGO device // //----------------------------------------------------------------------------- AttributeProxy::~AttributeProxy() { if (dbase_used == true) delete db_attr; delete dev_proxy; #ifndef HAS_UNIQUE_PTR delete ext; #endif } //----------------------------------------------------------------------------- // // AttributeProxy::ping() - ping TANGO device and return time elapsed in microseconds // //----------------------------------------------------------------------------- int AttributeProxy::ping() { return(dev_proxy->ping()); } //----------------------------------------------------------------------------- // // AttributeProxy::state() - return TANGO state of device // //----------------------------------------------------------------------------- DevState AttributeProxy::state() { return(dev_proxy->state()); } //----------------------------------------------------------------------------- // // AttributeProxy::status() - return TANGO status of device // //----------------------------------------------------------------------------- string AttributeProxy::status() { return(dev_proxy->status()); } //----------------------------------------------------------------------------- // // AttributeProxy::set_transparency_reconnection() - Set transparency // reconnection on the underlying device // //----------------------------------------------------------------------------- void AttributeProxy::set_transparency_reconnection(bool val) { dev_proxy->set_transparency_reconnection(val); } //----------------------------------------------------------------------------- // // AttributeProxy::get_transparency_reconnection() - Get underlying device // transparency reconnection flag // //----------------------------------------------------------------------------- bool AttributeProxy::get_transparency_reconnection() { return dev_proxy->get_transparency_reconnection(); } //----------------------------------------------------------------------------- // // AttributeProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::get_property(string &property_name, DbData &user_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::get_property"); } else { DbData db_data; db_data.resize(1); db_data[0] = DbDatum(attr_name); db_attr->get_property(db_data); long nb_prop = db_data.size(); int i; for (i = 1;i < nb_prop;i++) { if (db_data[i].name == property_name) { user_data.resize(0); user_data.push_back(db_data[i]); break; } } if (i == nb_prop) { user_data.resize(0); DbDatum no_data; no_data.name = property_name; no_data.value_string.resize(0); user_data.push_back(no_data); } } return; } //----------------------------------------------------------------------------- // // AttributeProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::get_property(vector &property_names, DbData &user_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::get_property"); } else { long nb_prop = property_names.size(); DbData db_data; db_data.resize(1); db_data[0] = DbDatum(attr_name); db_attr->get_property(db_data); int i,j; user_data.resize(0); long nb_recev_prop = db_data.size(); for (i = 0;i < nb_prop;i++) { for (j = 1;j < nb_recev_prop;j++) { if (db_data[j].name == property_names[i]) { user_data.push_back(db_data[j]); break; } } if (j == nb_recev_prop) { DbDatum no_data; no_data.name = property_names[i]; no_data.value_string.resize(0); user_data.push_back(no_data); } } } return; } //----------------------------------------------------------------------------- // // AttributeProxy::get_property() - get a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::get_property(DbData &user_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::get_property"); } else { long nb_prop = user_data.size(); DbData db_data; db_data.resize(1); db_data[0] = DbDatum(attr_name); db_attr->get_property(db_data); int i,j; long nb_recev_prop = db_data.size(); for (i = 0;i < nb_prop;i++) { for (j = 1;j < nb_recev_prop;j++) { if (db_data[j].name == user_data[i].name) { user_data[i] = db_data[j]; break; } } if (j == nb_recev_prop) { user_data[i].value_string.resize(0); } } } return; } //----------------------------------------------------------------------------- // // AttributeProxy::put_property() - put a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::put_property(DbData &user_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::put_property"); } else { DbData db_data; DbDatum att_name(attr_name); long nb_prop = user_data.size(); att_name << (short)nb_prop; db_data.push_back(att_name); for (int i = 0;i < nb_prop;i++) db_data.push_back(user_data[i]); db_attr->put_property(db_data); } return; } //----------------------------------------------------------------------------- // // AttributeProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::delete_property(string &property_name) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::delete_property"); } else { DbData db_data; DbDatum att(attr_name); db_data.push_back(att); db_data.push_back(DbDatum(property_name)); db_attr->delete_property(db_data); } return; } //----------------------------------------------------------------------------- // // AttributeProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::delete_property(vector &property_names) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::delete_property"); } else { DbData db_data; DbDatum att(attr_name); db_data.push_back(att); for (unsigned int i=0; idelete_property(db_data); } return; } //----------------------------------------------------------------------------- // // AttributeProxy::delete_property() - delete a property from the database // //----------------------------------------------------------------------------- void AttributeProxy::delete_property(DbData &user_data) { if (dbase_used == false) { TangoSys_OMemStream desc; desc << "Method not available for attribute belonging to device "; desc << device_name; desc << " which is a non database device"; ApiNonDbExcept::throw_exception((const char *)API_NonDatabaseDevice, desc.str(), (const char *)"AttributeProxy::delete_property"); } else { DbData db_data; DbDatum att(attr_name); db_data.push_back(att); for (unsigned int i=0; idelete_property(db_data); } return; } //----------------------------------------------------------------------------- // // AttributeProxy::get_config() - return attribute config // //----------------------------------------------------------------------------- AttributeInfoEx AttributeProxy::get_config() { return (dev_proxy->get_attribute_config(attr_name)); } //----------------------------------------------------------------------------- // // AttributeProxy::set_attribute_config() - set config for attribute // //----------------------------------------------------------------------------- void AttributeProxy::set_config(AttributeInfo &dev_attr_info) { AttributeInfoList attr_info_list; attr_info_list.push_back(dev_attr_info); try { dev_proxy->set_attribute_config(attr_info_list); } catch (CORBA::SystemException &ce) { TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"AttributeProxy::set_attribute_config()"); } } void AttributeProxy::set_config(AttributeInfoEx &dev_attr_info) { AttributeInfoListEx attr_info_list; attr_info_list.push_back(dev_attr_info); try { dev_proxy->set_attribute_config(attr_info_list); } catch (CORBA::SystemException &ce) { TangoSys_OMemStream desc; desc << "Failed to execute set_attribute_config on device " << device_name << ends; ApiCommExcept::re_throw_exception(ce, (const char*)"API_CommunicationFailed", desc.str(), (const char*)"AttributeProxy::set_attribute_config()"); } } //----------------------------------------------------------------------------- // // AttributeProxy::read() - read attribute // //----------------------------------------------------------------------------- DeviceAttribute AttributeProxy::read() { return(dev_proxy->read_attribute(attr_name)); } //----------------------------------------------------------------------------- // // AttributeProxy::write() - write attribute // //----------------------------------------------------------------------------- void AttributeProxy::write(DeviceAttribute& attr_value) { attr_value.set_name(attr_name); dev_proxy->write_attribute(attr_value); } //----------------------------------------------------------------------------- // // AttributeProxy::write_read() - write then read attribute // //----------------------------------------------------------------------------- DeviceAttribute AttributeProxy::write_read(DeviceAttribute& attr_value) { attr_value.set_name(attr_name); return dev_proxy->write_read_attribute(attr_value); } //----------------------------------------------------------------------------- // // AttributeProxy::history() - get attribute history // (only for polled attribute) // //----------------------------------------------------------------------------- vector *AttributeProxy::history(int depth) { return(dev_proxy->attribute_history(attr_name, depth)); } //----------------------------------------------------------------------------- // // AttributeProxy::get_poll_period() - Return attribute polling period // (in mS) // //----------------------------------------------------------------------------- int AttributeProxy::get_poll_period() { return(dev_proxy->get_attribute_poll_period(attr_name)); } //----------------------------------------------------------------------------- // // AttributeProxy::poll() - If object is already polled, just update its // polling period. If object is not polled, add // it to the list of polled objects // //----------------------------------------------------------------------------- void AttributeProxy::poll(int period) { dev_proxy->poll_attribute(attr_name, period); } //----------------------------------------------------------------------------- // // AttributeProxy::is_polled() - return true if the attribute is polled // //----------------------------------------------------------------------------- bool AttributeProxy::is_polled() { return(dev_proxy->is_attribute_polled(attr_name)); } //----------------------------------------------------------------------------- // // AttributeProxy::stop_poll() - Stop polling attribute // //----------------------------------------------------------------------------- void AttributeProxy::stop_poll() { dev_proxy->stop_poll_attribute(attr_name); } //----------------------------------------------------------------------------- // // AttributeProxy::subscribe_event - Subscribe to an event // Old interface for compatibility // //----------------------------------------------------------------------------- int AttributeProxy::subscribe_event (EventType event, CallBack *callback, const vector &filters) { return subscribe_event (event, callback, filters, false); } int AttributeProxy::subscribe_event (EventType event, CallBack *callback) { vector filters; return subscribe_event (event, callback, filters, false); } //----------------------------------------------------------------------------- // // AttributeProxy::subscribe_event - Subscribe to an event // Adds the statless flag for stateless // event subscription. // //----------------------------------------------------------------------------- int AttributeProxy::subscribe_event (EventType event, CallBack *callback, const vector &filters, bool stateless) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } int ret; try { ret = api_ptr->get_zmq_event_consumer()->subscribe_event(dev_proxy,attr_name, event, callback, filters, stateless); } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { if (ApiUtil::instance()->get_notifd_event_consumer() == NULL) { ApiUtil::instance()->create_notifd_event_consumer(); } ret = api_ptr->get_notifd_event_consumer()->subscribe_event(dev_proxy,attr_name, event, callback, filters, stateless); } else throw; } return ret; } int AttributeProxy::subscribe_event (EventType event, CallBack *callback,bool stateless) { vector vs; return subscribe_event(event,callback,vs,stateless); } //----------------------------------------------------------------------------- // // AttributeProxy::subscribe_event - Subscribe to an event with an event queue // Adds the statless flag for stateless // event subscription. // //----------------------------------------------------------------------------- int AttributeProxy::subscribe_event (EventType event, int event_queue_size, const vector &filters, bool stateless) { ApiUtil *api_ptr = ApiUtil::instance(); if (api_ptr->get_zmq_event_consumer() == NULL) { api_ptr->create_zmq_event_consumer(); } int ret; try { ret = api_ptr->get_zmq_event_consumer()->subscribe_event(dev_proxy,attr_name, event, event_queue_size, filters, stateless); } catch (DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { if (api_ptr->get_notifd_event_consumer() == NULL) { api_ptr->create_notifd_event_consumer(); } ret = api_ptr->get_notifd_event_consumer()->subscribe_event(dev_proxy,attr_name, event, event_queue_size, filters, stateless); } else throw; } return ret; } int AttributeProxy::subscribe_event (EventType event, int event_queue_size,bool stateless) { vector vs; return subscribe_event(event,event_queue_size,vs,stateless); } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/group.cpp0000644023471100065110000021154513034744772014417 00000000000000//============================================================================= // // file : group.cpp // // description : Tango Group impl. // // project : TANGO // // author(s) : N.Leclercq // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //============================================================================= #include //----------------------------------------------------------------------------- // LOCAL DEBUGGING MACRO //----------------------------------------------------------------------------- //#define _LOCAL_DEBUGGING namespace Tango { //============================================================================= // STATIC MEMBERS //============================================================================= bool GroupReply::exception_enabled = false; //============================================================================= // class GroupElementFactory //============================================================================= GroupElements GroupElementFactory::instanciate (const std::string& p, int tmo_ms) { #if defined(_LOCAL_DEBUGGING) cout << "GroupElementFactory::instanciate::pattern [" << p << "]" << endl; #endif //- a vector to store device names std::vector dnl(0); //- is

a device name or a device name pattern ? if (p.find('*', 0) == std::string::npos) { #if defined(_LOCAL_DEBUGGING) cout << "\t|- pattern is pure device name" << endl; #endif dnl.push_back(p); } else { int db_port = 0; std::string db_host, new_pattern; DbDatum dbd; parse_name(p, db_host, db_port, new_pattern); if (db_host.size() == 0) { Database db; //- ask the db the list of device matching pattern p dbd = db.get_device_exported(const_cast(p)); } else { ApiUtil *au = ApiUtil::instance(); int db_ind = au->get_db_ind(db_host,db_port); dbd = ((au->get_db_vect())[db_ind])->get_device_exported(const_cast(new_pattern)); } //- extract device names from dbd dbd >> dnl; #if defined(_LOCAL_DEBUGGING) cout << "\t|- db.get_device_exported::found "; cout << dnl.size() << " device names matching pattern" << endl; for (unsigned int dn = 0; dn < dnl.size(); dn++) { cout << "\t\t|- " << dnl[dn] << endl; } #endif } //- build the returned GroupElementList GroupElements tel(0); GroupDeviceElement* tde; for (unsigned int i = 0; i < dnl.size(); i++) { tde = new GroupDeviceElement(dnl[i],tmo_ms); if (tde) { tel.push_back(tde); } } #if defined(_LOCAL_DEBUGGING) cout << "\t|- GroupElementList contains " << tel.size() << " elements" << endl; #endif //- return the list to the caller return tel; } void GroupElementFactory::parse_name (const std::string& p, string &db_host,int &db_port,string &dev_pattern) { string pattern_name_low(p); transform(pattern_name_low.begin(),pattern_name_low.end(),pattern_name_low.begin(),::tolower); // Try to find protocol specification in device pattern and analyse it string name_wo_prot; string::size_type pos = pattern_name_low.find(PROT_SEP); if (pos == string::npos) { if (pattern_name_low.size() > 2) { if ((pattern_name_low[0] == '/') && (pattern_name_low[1] == '/')) name_wo_prot = pattern_name_low.substr(2); else name_wo_prot = pattern_name_low; } else name_wo_prot = pattern_name_low; } else { string protocol = pattern_name_low.substr(0,pos); if (protocol == TANGO_PROTOCOL) { name_wo_prot = pattern_name_low.substr(pos + 3); } else { TangoSys_OMemStream desc; desc << protocol; desc << " protocol is an unsupported protocol" << ends; ApiWrongNameExcept::throw_exception((const char*)"API_UnsupportedProtocol", desc.str(), (const char*)"GroupElementFactory::parse_name()"); } } // Search if host and port are specified pos = name_wo_prot.find(PORT_SEP); if (pos == string::npos) { TangoSys_OMemStream desc; desc << "Wrong device name syntax in " << p << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"GroupElementFactory::parse_name()"); } string bef_sep = name_wo_prot.substr(0,pos); string::size_type tmp = bef_sep.find(HOST_SEP); if (tmp != string::npos) { string tmp_host(bef_sep.substr(0,tmp)); if (tmp_host.find('.') == string::npos) DeviceProxy::get_fqdn(tmp_host); db_host = tmp_host; string db_port_str = bef_sep.substr(tmp + 1); if (db_port_str.size() == 0) { TangoSys_OMemStream desc; desc << "Wrong device name syntax in " << p << ends; ApiWrongNameExcept::throw_exception((const char *)API_WrongDeviceNameSyntax, desc.str(), (const char *)"GroupElementFactory::parse_name()"); } TangoSys_MemStream s; s << db_port_str << ends; s >> db_port; dev_pattern = name_wo_prot.substr(pos + 1); } else dev_pattern = name_wo_prot; } //============================================================================= // class GroupCmdReply //============================================================================= GroupReply::GroupReply () : dev_name_m("unknown"), obj_name_m("unknown"), has_failed_m(false), group_element_enabled_m(true) { } //----------------------------------------------------------------------------- GroupReply::GroupReply (const GroupReply& _src) : dev_name_m(_src.dev_name_m), obj_name_m(_src.obj_name_m), has_failed_m(_src.has_failed_m), group_element_enabled_m(_src.group_element_enabled_m), exception_m(_src.exception_m) { } //----------------------------------------------------------------------------- GroupReply::GroupReply (const std::string& _dev_name, const std::string& _obj_name, bool group_element_enabled) : dev_name_m(_dev_name), obj_name_m(_obj_name), has_failed_m(false), group_element_enabled_m(group_element_enabled) { } //----------------------------------------------------------------------------- GroupReply::GroupReply (const std::string& _dev_name, const std::string& _obj_name, const Tango::DevFailed& exception, bool group_element_enabled) : dev_name_m(_dev_name), obj_name_m(_obj_name), has_failed_m(true), group_element_enabled_m(group_element_enabled), exception_m(exception) { } //----------------------------------------------------------------------------- GroupReply::~GroupReply () { //-noop impl } //----------------------------------------------------------------------------- bool GroupReply::enable_exception (bool exception_mode) { bool tmp = GroupReply::exception_enabled; GroupReply::exception_enabled = exception_mode; return tmp; } //============================================================================= // class GroupReplyList //============================================================================= GroupReplyList::GroupReplyList () : std::vector(0), has_failed_m(false) { //-noop impl } //----------------------------------------------------------------------------- GroupReplyList::~GroupReplyList () { //-noop impl } //============================================================================= // class GroupCmdReply : reply to command executed on a group //============================================================================= GroupCmdReply::GroupCmdReply () : GroupReply() { //-noop impl } //----------------------------------------------------------------------------- GroupCmdReply::GroupCmdReply (const GroupCmdReply& src) : GroupReply(src), data_m(src.data_m) { } //----------------------------------------------------------------------------- GroupCmdReply::GroupCmdReply (const std::string& _dev_name, const std::string& _obj_name, const Tango::DeviceData& _dev_data) : GroupReply(_dev_name, _obj_name, true), data_m(_dev_data) { //-noop impl } //----------------------------------------------------------------------------- GroupCmdReply::GroupCmdReply (const std::string& _dev_name, const std::string& _obj_name, const Tango::DevFailed& _exception) : GroupReply(_dev_name, _obj_name, _exception, true) { //-noop impl } //----------------------------------------------------------------------------- GroupCmdReply::GroupCmdReply (const std::string& _dev_name, const std::string& _obj_name, bool group_element_enabled) : GroupReply(_dev_name, _obj_name, group_element_enabled) { //-noop impl } //----------------------------------------------------------------------------- GroupCmdReply::~GroupCmdReply () { //-noop impl } //----------------------------------------------------------------------------- /*const*/ DeviceData& GroupCmdReply::get_data () { if (group_element_enabled_m == false && exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupCmdReply::get_data"); DevFailed df(errors); throw df; } else if (has_failed_m && exception_enabled) { throw exception_m; } std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); return data_m; } //----------------------------------------------------------------------------- bool GroupCmdReply::extract (std::vector& vl, std::vector& vs) { bool result = true; if (group_element_enabled_m == false) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupCmdReply::extract"); DevFailed df(errors); throw df; } result = false; } else if (has_failed_m == true) { if (exception_enabled) throw exception_m; result = false; } else { std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); try { result = data_m.extract(vl, vs); } catch (const Tango::DevFailed& df) { exception_m = df; if (exception_enabled) throw exception_m; result = false; } catch (...) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown exception caught"); errors[0].reason = CORBA::string_dup("an error occured while trying to extract data"); errors[0].origin = CORBA::string_dup("GroupCmdReply::extract"); DevFailed df(errors); exception_m = df; throw exception_m; } result = false; } } return result; } //----------------------------------------------------------------------------- bool GroupCmdReply::extract (std::vector& vd, std::vector& vs) { bool result = true; if (group_element_enabled_m == false) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupCmdReply::extract"); DevFailed df(errors); throw df; } result = false; } else if (has_failed_m == true) { if (exception_enabled) throw exception_m; result = false; } else { std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); try { result = data_m.extract(vd, vs); } catch (const Tango::DevFailed& df) { exception_m = df; if (exception_enabled) { throw exception_m; } result = false; } catch (...) { if (exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown exception caught"); errors[0].reason = CORBA::string_dup("an error occured while trying to extract data"); errors[0].origin = CORBA::string_dup("GroupCmdReply::extract"); DevFailed df(errors); exception_m = df; throw exception_m; } result = false; } } return result; } //============================================================================= // class GroupCmdReplyList //============================================================================= GroupCmdReplyList::GroupCmdReplyList () : std::vector(0), has_failed_m(false) { //-noop impl } //----------------------------------------------------------------------------- GroupCmdReplyList::~GroupCmdReplyList () { //-noop impl } //============================================================================= // class GroupAttrReply : reply to read/write attr on a group //============================================================================= GroupAttrReply::GroupAttrReply () : GroupReply() { //-noop impl } //----------------------------------------------------------------------------- GroupAttrReply::GroupAttrReply (const GroupAttrReply& src) : GroupReply(src), data_m(src.data_m) { } //----------------------------------------------------------------------------- GroupAttrReply::GroupAttrReply (const std::string& _dev_name, const std::string& _obj_name, const Tango::DeviceAttribute& _dev_attr) : GroupReply(_dev_name, _obj_name, true), data_m(_dev_attr) { //-noop impl } //----------------------------------------------------------------------------- GroupAttrReply::GroupAttrReply (const std::string& _dev_name, const std::string& _obj_name, const Tango::DevFailed& _exception) : GroupReply(_dev_name, _obj_name, _exception, true) { //-noop impl } //----------------------------------------------------------------------------- GroupAttrReply::GroupAttrReply (const std::string& _dev_name, const std::string& _obj_name, bool _group_element_enabled) : GroupReply(_dev_name, _obj_name, _group_element_enabled) { //-noop impl } //----------------------------------------------------------------------------- GroupAttrReply::~GroupAttrReply () { //-noop impl } //----------------------------------------------------------------------------- /*const*/ DeviceAttribute& GroupAttrReply::get_data () { if (group_element_enabled_m == false && exception_enabled) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("no available data"); errors[0].reason = CORBA::string_dup("no data - group member is disabled"); errors[0].origin = CORBA::string_dup("GroupCmdReply::get_data"); DevFailed df(errors); throw df; } else if (has_failed_m && exception_enabled) { throw exception_m; } std::bitset bs; data_m.exceptions(exception_enabled ? bs.set() : bs.reset()); return data_m; } //============================================================================= // class GroupAttrReplyList //============================================================================= GroupAttrReplyList::GroupAttrReplyList () : std::vector(0), has_failed_m(false) { //-noop impl } //----------------------------------------------------------------------------- GroupAttrReplyList::~GroupAttrReplyList () { //-noop impl } //============================================================================= // class GroupElement //============================================================================= GroupElement::GroupElement (const std::string& _name, GroupElement* _parent) : name(_name), parent(_parent), enabled(true) { //- noop ctor } //----------------------------------------------------------------------------- GroupElement::~GroupElement() { //- noop dtor } //----------------------------------------------------------------------------- bool GroupElement::contains (const std::string& n, TANGO_UNUSED(bool fwd)) { std::string::size_type pos = n.find('*', 0); return (pos == std::string::npos) ? name_equals(n) : name_matches(n); } //----------------------------------------------------------------------------- GroupElement* GroupElement::find_i (const std::string& n, TANGO_UNUSED(bool fwd)) { return name_equals(n) ? this : 0; } //----------------------------------------------------------------------------- TokenList GroupElement::tokenize_i (const std::string& p) { #if defined(_LOCAL_DEBUGGING) cout << "\t|- Group::tokenize::pattern [" << p << "]" << endl; #endif int done = 0; std::string token; std::string::size_type pos; std::string::size_type last_pos = 0; std::vector tokens(0); do { pos = p.find('*', last_pos); if (pos != 0) { if (pos == std::string::npos) { if (last_pos >= p.size()) break; pos = p.size(); done = 1; } token.assign(p.begin() + last_pos, p.begin() + pos); tokens.push_back(token); } last_pos = pos + 1; } while (!done); #if defined(_LOCAL_DEBUGGING) cout << "\t\t|- tokens: ["; for (int t = 0; t < tokens.size(); t++) { cout << tokens[t]; cout << ((t == tokens.size() - 1) ? "]" : ";"); } cout << endl; #endif return tokens; } //----------------------------------------------------------------------------- bool GroupElement::match_i (const std::string& _p, const TokenList& tokens) { unsigned int t; std::string p(_p); std::transform(p.begin(),p.end(),p.begin(),::tolower); #if defined(_LOCAL_DEBUGGING) cout << "\t|- Group::match::pattern " << _p << endl; #endif bool result = false; std::string::size_type pos; for (t = 0, pos = 0; t < tokens.size(); t++) { string token(tokens[t]); std::transform(token.begin(),token.end(),token.begin(),::tolower); pos = p.find(token, pos); if (pos == std::string::npos) break; } if (t == tokens.size()) { result = true; } #if defined(_LOCAL_DEBUGGING) if (result == true) { cout << "\t\t|- Group::match::pattern matches tokens" << endl; } else { cout << "\t\t|- Group::match::pattern does NOT match tokens" << endl; } #endif return result; } //----------------------------------------------------------------------------- bool GroupElement::name_matches (const std::string& n) { TokenList tokens = tokenize_i(n); return match_i(name, tokens) || match_i(get_fully_qualified_name(), tokens); } //----------------------------------------------------------------------------- bool GroupElement::name_equals (const std::string& in_name) { std::string lin(in_name); std::transform(lin.begin(),lin.end(),lin.begin(),::tolower); std::string lfqn(get_fully_qualified_name()); std::transform(lfqn.begin(),lfqn.end(),lfqn.begin(),::tolower); std::string ln(name); std::transform(ln.begin(),ln.end(),ln.begin(),::tolower); return lin == ln || lin == lfqn; } //----------------------------------------------------------------------------- GroupElement* GroupElement::set_parent (GroupElement* _parent) { GroupElement* previous_parent = parent; parent = _parent; return previous_parent; } //----------------------------------------------------------------------------- bool GroupElement::is_connected () { return true; } //============================================================================= // class Group //============================================================================= Group::Group (const std::string& name) : GroupElement(name), asynch_req_id(0) { //- noop ctor } //----------------------------------------------------------------------------- Group::~Group () { remove_all(); arp.clear(); } //----------------------------------------------------------------------------- Group * Group::get_parent () const { return reinterpret_cast(parent); } //----------------------------------------------------------------------------- bool Group::is_root_group () const { return parent ? false : true; } //----------------------------------------------------------------------------- std::vector Group::get_device_list (bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif std::vector dl(0); std::vector sub_dl(0); GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i()) { dl.push_back((*it)->get_name()); } else if (fwd) { sub_dl = (static_cast(*it))->get_device_list(fwd); if (sub_dl.empty() == false) { dl.insert(dl.end(), sub_dl.begin(), sub_dl.end()); } sub_dl.clear(); } } return dl; } //----------------------------------------------------------------------------- GroupElements Group::get_hiearchy () { GroupElements te(0); GroupElements sub_te(0); GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i()) { te.push_back(*it); } else { sub_te = (static_cast(*it))->get_hiearchy(); if (sub_te.empty() == false) { te.insert(te.end(), sub_te.begin(), sub_te.end()); } sub_te.clear(); } } return te; } //----------------------------------------------------------------------------- long Group::get_size (bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif return get_size_i(fwd); } //----------------------------------------------------------------------------- long Group::get_size_i (bool fwd) { long size = 0; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { size += (*it)->get_size_i(); } } return size; } //----------------------------------------------------------------------------- void Group::add (Group* g, int tmo_ms) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif #if defined(_LOCAL_DEBUGGING) cout << "Group::add::adding sub-group " << (g ? g->get_name() : "NULL") << endl; #endif if (g == 0 || get_group_i(g->get_name()) == g || g->get_group_i(get_name()) == this) { #if defined(_LOCAL_DEBUGGING) cout << "Group::add::failed to add group" << (g ? (g->get_name() + " (self ref. or already in group)") : "NULL") << endl; #endif if(g != 0) { g->set_timeout_millis(tmo_ms); } return; } add_i(g, false); g->set_timeout_millis(tmo_ms); } //----------------------------------------------------------------------------- void Group::add (const std::string& p, int tmo_ms) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif GroupElements el = GroupElementFactory::instanciate(p,tmo_ms); for (unsigned int e = 0; e < el.size(); e++) { if (el[e] && (add_i(el[e]) == false)) { GroupElement* te = find_i(el[e]->get_name()); try { te->set_timeout_millis(tmo_ms); } catch(...) { // ignore errors } delete el[e]; } } } //----------------------------------------------------------------------------- void Group::add (const std::vector& pl, int tmo_ms) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif for (unsigned int p = 0; p < pl.size(); p++) { GroupElements el = GroupElementFactory::instanciate(pl[p],tmo_ms); for (unsigned int e = 0; e < el.size(); e++) { if (el[e] && (add_i(el[e]) == false)) { GroupElement* te = find_i(el[e]->get_name()); try { te->set_timeout_millis(tmo_ms); } catch(...) { // ignore errors } delete el[e]; } } } } //----------------------------------------------------------------------------- bool Group::add_i (GroupElement* e, bool fwd) { if (e == 0 || e == this) { #if defined(_LOCAL_DEBUGGING) cout << "Group::add_i::failed to add " << (e ? (e->get_name() + " (null or self ref)") : "NULL") << endl; #endif return false; } GroupElement* te = find_i(e->get_name(), fwd); if (te != 0 && te != this) { #if defined(_LOCAL_DEBUGGING) cout << "Group::add_i::failed to add " << e->get_name() << " (already in group)" << endl; #endif return false; } elements.push_back(e); e->set_parent(this); return true; } //----------------------------------------------------------------------------- void Group::remove (const std::string& p, bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif #if defined(_LOCAL_DEBUGGING) cout << "Group::remove::pattern [" << p << "]" << endl; #endif remove_i(p, fwd); } //----------------------------------------------------------------------------- void Group::remove (const std::vector& pl, bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif #if defined(_LOCAL_DEBUGGING) cout << "Group::remove::pattern list" << endl; #endif for (unsigned int p = 0; p < pl.size(); p++) { remove_i(pl[p], fwd); } } //----------------------------------------------------------------------------- void Group::remove_i (const std::string& p, bool fwd) { #if defined(_LOCAL_DEBUGGING) cout << "\t|- Group::remove_i" << endl; #endif if (name_equals(p)) { #if defined(_LOCAL_DEBUGGING) cout << "Group::remove_i::failed to remove " << _p << " (can't remove self)" << endl; #endif return; } GroupElementsIterator it; if (p.find('*', 0) == std::string::npos) { for (it = elements.begin(); it != elements.end(); ++it) { if ((*it)->name_equals(p)) { delete *it; elements.erase(it); break; } } } else { std::vector remove_list(0); for (it = elements.begin(); it != elements.end(); ++it) { if ((*it)->name_matches(p)) { remove_list.push_back(*it); } } for (unsigned int i = 0; i < remove_list.size(); i++) { it = std::find(elements.begin(), elements.end(), remove_list[i]); if (it != elements.end()) { # if defined(_LOCAL_DEBUGGING) cout << "\t|- Group::remove_i::removing " << (*it)->get_name() << endl; # endif // _LOCAL_DEBUGGING delete remove_list[i]; elements.erase(it); } } } if ( fwd ) { for (it = elements.begin(); it != elements.end(); ++it) { if ( (*it)->is_group_i() ) { reinterpret_cast((*it))->remove(p, fwd); } } } } //----------------------------------------------------------------------------- void Group::remove_all () { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif #if defined(_LOCAL_DEBUGGING) cout << "Group::remove_all::" << get_name() << endl; #endif GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { delete *it; } elements.clear(); } //----------------------------------------------------------------------------- bool Group::contains (const std::string& n, bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif return (find_i(n, fwd) != 0) ? true : false; } //----------------------------------------------------------------------------- GroupElement* Group::find_i (const std::string& n, bool fwd) { std::string::size_type pos = n.find('*',0); bool is_pattern = (pos != std::string::npos) ? true : false; if (is_pattern) { if (name_matches(n)) return this; } else { if (name_equals(n)) return this; } GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if (is_pattern) { if ((*it)->name_matches(n)) return *it; } else { if ((*it)->name_equals(n)) return *it; } } GroupElement* e = 0; if (fwd) { it = elements.begin(); end = elements.end(); while (it != end && e == 0) { e = (*it)->find_i(n); ++it; } } return e; } //----------------------------------------------------------------------------- DeviceProxy* Group::get_device (const std::string& n) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif DeviceProxy* dp = 0; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); while (it != end && dp == 0) { dp = (*it)->get_device(n); ++it; } return dp; } //----------------------------------------------------------------------------- DeviceProxy* Group::get_device (long idx) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif DeviceProxy* dp = 0; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); while (it != end && dp == 0) { dp = (*it)->get_device(idx--); ++it; } return dp; } //----------------------------------------------------------------------------- DeviceProxy* Group::operator[] (long idx) { return get_device(idx); } //----------------------------------------------------------------------------- Group* Group::get_group (const std::string& n) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif return get_group_i(n); } //----------------------------------------------------------------------------- Group* Group::get_group_i (const std::string& n) { GroupElement* e = find_i(n, true); return (e != 0 && e->is_group_i()) ? reinterpret_cast(e) : 0; } //----------------------------------------------------------------------------- void Group::enable (const std::string& n, bool fwd) { GroupElement* e = find_i(n, fwd); if (e) e->enable(); } //----------------------------------------------------------------------------- void Group::disable (const std::string& n, bool fwd) { GroupElement* e = find_i(n, fwd); if (e) e->disable(); } //----------------------------------------------------------------------------- bool Group::ping (bool fwd) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif bool result = true; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end && result != false ; ++it) { if ((*it)->is_device_i() || fwd) { result = (*it)->ping(fwd); } } return result; } //----------------------------------------------------------------------------- void Group::set_timeout_millis (int tmo_ms) { GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end ; ++it) { try { (*it)->set_timeout_millis(tmo_ms); } catch(...) { // ignore errors } } } //----------------------------------------------------------------------------- GroupCmdReplyList Group::command_inout (const std::string& c, bool fwd) { long id = command_inout_asynch_i(c, false, fwd, -1); return command_inout_reply_i(id, 0); } //----------------------------------------------------------------------------- GroupCmdReplyList Group::command_inout (const std::string& c, const DeviceData& d, bool fwd) { long id = command_inout_asynch_i(c, d, false, fwd, -1); return command_inout_reply_i(id, 0); } //----------------------------------------------------------------------------- GroupCmdReplyList Group::command_inout (const std::string& c, const std::vector& d, bool fwd) { long id = command_inout_asynch_i(c, d, false, fwd, -1); return command_inout_reply_i(id, 0); } //----------------------------------------------------------------------------- long Group::command_inout_asynch (const std::string& c, bool fgt, bool fwd) { return command_inout_asynch_i(c, fgt, fwd, -1); } //----------------------------------------------------------------------------- long Group::command_inout_asynch_i (const std::string& c, bool fgt, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif if (id == -1) { id = next_asynch_request_id(); } GroupElements disconnected; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { if((*it)->is_connected()) (*it)->command_inout_asynch_i(c, fgt, fwd, id); else disconnected.push_back(*it); } } for(size_t i = 0; i < disconnected.size(); i++) disconnected[i]->command_inout_asynch_i(c, fgt, fwd, id); if ( ! fgt ) { push_async_request(id, fwd); } return id; } //----------------------------------------------------------------------------- long Group::command_inout_asynch (const std::string& c, const DeviceData& d, bool fgt, bool fwd) { return command_inout_asynch_i(c, d, fgt, fwd, -1); } //----------------------------------------------------------------------------- long Group::command_inout_asynch_i (const std::string& c, const DeviceData& d, bool fgt, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif if (id == -1) { id = next_asynch_request_id(); } GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { (*it)->command_inout_asynch_i(c, d, fgt, fwd, id); } } if ( ! fgt ) { push_async_request(id, fwd); } return id; } //----------------------------------------------------------------------------- long Group::command_inout_asynch (const std::string& c, const std::vector& d, bool fgt, bool fwd) { return command_inout_asynch_i(c, d, fgt, fwd, -1); } //----------------------------------------------------------------------------- long Group::command_inout_asynch_i (const std::string& c, const std::vector& d, bool fgt, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif long gsize = get_size_i(fwd); if (gsize != static_cast(d.size())) { TangoSys_OMemStream desc; desc << "the size of the input argument list must equal the number of device in the group" << " [expected:" << gsize << " - got:" << d.size() << "]" << ends; ApiDataExcept::throw_exception((const char*)API_MethodArgument, (const char*)desc.str().c_str(), (const char*)"Group::command_inout_asynch"); } if ( id == -1 ) id = next_asynch_request_id(); for (unsigned int i = 0, j = 0; i < elements.size(); i++) { if ( elements[i]->is_device_i() ) { elements[i]->command_inout_asynch_i(c, d[j++], fgt, false, id); } else if ( fwd ) { Tango::Group * g = reinterpret_cast(elements[i]); gsize = g->get_size_i(fwd); std::vector sub_d(d.begin() + j, d.begin() + j + gsize); g->command_inout_asynch_i(c, static_cast&>(sub_d), fgt, fwd, id); j += gsize; } } if ( ! fgt ) push_async_request(id, fwd); return id; } //----------------------------------------------------------------------------- GroupCmdReplyList Group::command_inout_reply (long ari, long tmo) { return command_inout_reply_i(ari, tmo); } //----------------------------------------------------------------------------- GroupCmdReplyList Group::command_inout_reply_i (long ari, long tmo) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif AsynchRequestDescIt r = arp.find(ari); if (r == arp.end()) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("Group::command_inout_reply"); throw DevFailed(errors); } GroupCmdReplyList reply; GroupCmdReplyList sub_reply; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || r->second) { sub_reply = (*it)->command_inout_reply_i(ari, tmo); if (sub_reply.empty() == false) { reply.insert(reply.end(), sub_reply.begin(), sub_reply.end()); } if (sub_reply.has_failed_m) { reply.has_failed_m = true; } sub_reply.reset(); } } arp.erase(r); return reply; } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attribute (const std::string& a, bool fwd) { long id = read_attribute_asynch_i(a, fwd, -1); return read_attribute_reply_i(id, 0); } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attributes (const std::vector& al, bool fwd) { long id = read_attributes_asynch_i(al, fwd, -1); return read_attributes_reply_i(id, 0); } //----------------------------------------------------------------------------- long Group::read_attribute_asynch (const std::string& a, bool fwd) { return read_attribute_asynch_i(a, fwd, -1); } //----------------------------------------------------------------------------- long Group::read_attribute_asynch_i (const std::string& a, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif if (id == -1) { id = next_asynch_request_id(); } GroupElements disconnected; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { if((*it)->is_connected()) id = (*it)->read_attribute_asynch_i(a, fwd, id); else disconnected.push_back(*it); } } for(size_t i = 0; i < disconnected.size(); i++) id = disconnected[i]->read_attribute_asynch_i(a, fwd, id); push_async_request(id, fwd); return id; } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attribute_reply (long ari, long tmo) { return read_attribute_reply_i(ari, tmo); } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attribute_reply_i (long ari, long tmo) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif AsynchRequestDescIt r = arp.find(ari); if (r == arp.end()) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("Group::read_attribute_reply"); throw DevFailed(errors); } GroupAttrReplyList reply; GroupAttrReplyList sub_reply; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || r->second) { sub_reply = (*it)->read_attribute_reply_i(ari, tmo); if (sub_reply.empty() == false) { reply.insert(reply.end(), sub_reply.begin(), sub_reply.end()); } if (sub_reply.has_failed_m) { reply.has_failed_m = true; } sub_reply.reset(); } } arp.erase(r); return reply; } //----------------------------------------------------------------------------- long Group::read_attributes_asynch (const std::vector& al, bool fwd) { return read_attributes_asynch_i(al, fwd, -1); } //----------------------------------------------------------------------------- long Group::read_attributes_asynch_i (const std::vector& al, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif if (id == -1) { id = next_asynch_request_id(); } GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { id = (*it)->read_attributes_asynch_i(al, fwd, id); } } push_async_request(id, fwd); return id; } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attributes_reply (long ari, long tmo) { return read_attributes_reply_i(ari, tmo); } //----------------------------------------------------------------------------- GroupAttrReplyList Group::read_attributes_reply_i (long ari, long tmo) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif AsynchRequestDescIt r = arp.find(ari); if (r == arp.end()) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("Group::read_attributes_reply"); throw DevFailed(errors); } GroupAttrReplyList reply; GroupAttrReplyList sub_reply; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || r->second) { sub_reply = (*it)->read_attributes_reply_i(ari, tmo); if (sub_reply.empty() == false) { reply.insert(reply.end(), sub_reply.begin(), sub_reply.end()); } if (sub_reply.has_failed_m) { reply.has_failed_m = true; } sub_reply.reset(); } } arp.erase(r); return reply; } //----------------------------------------------------------------------------- GroupReplyList Group::write_attribute (const DeviceAttribute& d, bool fwd) { long id = write_attribute_asynch_i(d, fwd, -1); return write_attribute_reply_i(id, 0); } //----------------------------------------------------------------------------- GroupReplyList Group::write_attribute (const std::vector& d, bool fwd) { long id = write_attribute_asynch_i(d, fwd, -1); return write_attribute_reply_i(id, 0); } //----------------------------------------------------------------------------- long Group::write_attribute_asynch (const DeviceAttribute& d, bool fwd) { return write_attribute_asynch_i(d, fwd, -1); } //----------------------------------------------------------------------------- long Group::write_attribute_asynch_i (const DeviceAttribute& d, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif if (id == -1) { id = next_asynch_request_id(); } GroupElements disconnected; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || fwd) { if((*it)->is_connected()) id = (*it)->write_attribute_asynch_i(d, fwd, id); else disconnected.push_back(*it); } } for(size_t i = 0; i < disconnected.size(); i++) id = disconnected[i]->write_attribute_asynch_i(d, fwd, id); push_async_request(id, fwd); return id; } //----------------------------------------------------------------------------- long Group::write_attribute_asynch (const std::vector& d, bool fwd) { return write_attribute_asynch_i(d, fwd, -1); } //----------------------------------------------------------------------------- long Group::write_attribute_asynch_i (const std::vector& d, bool fwd, long id) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif GroupReplyList rl; long gsize = get_size_i(fwd); if (gsize != static_cast(d.size())) { TangoSys_OMemStream desc; desc << "the size of the input argument list must equal the number of device in the group" << " [expected:" << gsize << " - got:" << d.size() << "]" << ends; ApiDataExcept::throw_exception((const char*)API_MethodArgument, (const char*)desc.str().c_str(), (const char*)"Group::write_attribute_asynch"); } if (id == -1) { id = next_asynch_request_id(); } for (unsigned int i = 0, j = 0; i < elements.size(); i++) { if (elements[i]->is_device_i()) { elements[i]->write_attribute_asynch_i(d[j++], false, id); } else if (fwd) { Tango::Group * g = reinterpret_cast(elements[i]); long gsize = g->get_size_i(fwd); std::vector sub_d(d.begin() + j, d.begin() + j + gsize); reinterpret_cast(elements[i])->write_attribute_asynch_i(sub_d, fwd, id); j += gsize; } } push_async_request(id, fwd); return id; } //----------------------------------------------------------------------------- GroupReplyList Group::write_attribute_reply (long ari, long tmo) { return write_attribute_reply_i(ari, tmo); } //----------------------------------------------------------------------------- GroupReplyList Group::write_attribute_reply_i (long ari, long tmo) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif AsynchRequestDescIt r = arp.find(ari); if (r == arp.end()) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("Group::write_attribute_reply"); throw DevFailed(errors); } GroupReplyList reply; GroupReplyList sub_reply; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end; ++it) { if ((*it)->is_device_i() || r->second) { sub_reply = (*it)->write_attribute_reply_i(ari, tmo); if (sub_reply.empty() == false) { reply.insert(reply.end(), sub_reply.begin(), sub_reply.end()); } if (sub_reply.has_failed_m) { reply.has_failed_m = true; } sub_reply.reset(); } } arp.erase(r); return reply; } //----------------------------------------------------------------------------- long Group::next_asynch_request_id () { asynch_req_id++; asynch_req_id %= (long)0x0FFF; return asynch_req_id; } //----------------------------------------------------------------------------- void Group::dump (int indent_level) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (int i = 0; i < indent_level ; i++) { cout << "\t"; } cout << "|- GROUP: " << get_fully_qualified_name() << " [" << get_size_i(false) << ":" << get_size_i(true) << "]" << endl; for (; it != end ; ++it) { (*it)->dump(indent_level + 1); } } //----------------------------------------------------------------------------- void Group::dump (TangoSys_OMemStream& oms, int indent_level) { #ifdef TANGO_GROUP_HAS_THREAD_SAFE_IMPL omni_mutex_lock guard(elements_mutex); #endif for (int i = 0; i < indent_level ; i++) { oms << "\t"; } oms << "|- GROUP: " << get_fully_qualified_name() << " [" << get_size_i(false) << ":" << get_size_i(true) << "]" << endl; GroupElementsIterator it = elements.begin(); GroupElementsIterator end = elements.end(); for (; it != end ; ++it) { (*it)->dump(oms, indent_level + 1); } if (indent_level == 0) { oms << ends; } } //----------------------------------------------------------------------------- bool Group::is_device_i () { return false; } //----------------------------------------------------------------------------- bool Group::is_group_i () { return true; } //----------------------------------------------------------------------------- void Group::push_async_request(long rid, bool forwarded) { arp.insert(AsynchRequestDescVal(rid, forwarded)); } //----------------------------------------------------------------------------- void Group::pop_async_request(long rid) { AsynchRequestDescIt r = arp.find(rid); if (r != arp.end()) { arp.erase(r); } } //============================================================================= // class GroupDeviceElement //============================================================================= GroupDeviceElement::GroupDeviceElement (const std::string& name) : GroupElement(name), dp(0) { try { connect(); } catch (...) { //- ignore error } } //----------------------------------------------------------------------------- GroupDeviceElement::GroupDeviceElement (const std::string& name, int tmo_ms) : GroupElement(name), dp(0) { try { connect(); set_timeout_millis(tmo_ms); } catch (...) { //- ignore error } } //----------------------------------------------------------------------------- GroupDeviceElement::~GroupDeviceElement () { disconnect(); arp.clear(); } //----------------------------------------------------------------------------- DeviceProxy* GroupDeviceElement::get_device (const std::string& _n) { try { std::string n(_n); std::transform(n.begin(),n.end(),n.begin(),::tolower); if (name_equals(n)) { return dev_proxy(); } } catch (...) { //- ignore exception then return null } return 0; } //----------------------------------------------------------------------------- DeviceProxy* GroupDeviceElement::get_device (long idx) { return ((--idx) == 0) ? dev_proxy() : 0; } //----------------------------------------------------------------------------- DeviceProxy* GroupDeviceElement::operator[] (long idx) { return get_device(idx); } //----------------------------------------------------------------------------- DeviceProxy* GroupDeviceElement::connect () { disconnect(); try { dp = new DeviceProxy(const_cast(get_name())); dp->set_transparency_reconnection(true); } catch (...) { disconnect(); throw; } return dp; } //----------------------------------------------------------------------------- void GroupDeviceElement::disconnect () { //-TODO: how to handle pending asynch calls ? if (dp) { delete dp; dp = 0; } } //----------------------------------------------------------------------------- bool GroupDeviceElement::ping (bool) { bool result = true; try { dev_proxy()->ping(); } catch (...) { result = false; } return result; } //----------------------------------------------------------------------------- long GroupDeviceElement::command_inout_asynch_i (const std::string& c, bool fgt, TANGO_UNUSED(bool fwd), long id) { if ( ! is_enabled() ) { if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(id, c, false))); } } else { try { long ari = dev_proxy()->command_inout_asynch(const_cast(c), fgt); if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(ari, c))); } } catch (const Tango::DevFailed& df) { if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, c, df))); } } catch (...) { if ( ! fgt ) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::command_inout_asynch"); DevFailed df(errors); arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, c, df))); } } } return id; } //----------------------------------------------------------------------------- long GroupDeviceElement::command_inout_asynch_i (const std::string& c, const DeviceData& d, bool fgt, TANGO_UNUSED(bool fwd), long id) { if ( ! is_enabled() ) { if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(id, c, false))); } } else { try { long ari = dev_proxy()->command_inout_asynch(const_cast(c), const_cast(d), fgt); if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(ari, c))); } } catch (const Tango::DevFailed& df) { if ( ! fgt ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, c, df))); } } catch (...) { if ( ! fgt ) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::command_inout_asynch"); DevFailed df(errors); arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, c, df))); } } } return id; } //----------------------------------------------------------------------------- GroupCmdReplyList GroupDeviceElement::command_inout_reply_i (long id, long tmo) { GroupCmdReplyList rl; //- search actual asynch request id in this' repository AsynchRequestRepIterator it = arp.find(id); if (it == arp.end()) { //- error description Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::command_inout_reply"); DevFailed df(errors); //- populate the returned vector rl.push_back(GroupCmdReply(get_name(), "unknown", df)); return rl; } //- no reply if this group element is diabled if ( ! is_enabled() ) { rl.push_back(GroupCmdReply(get_name(), it->second.obj_names[0], false)); //- remove request from repository arp.erase(it); return rl; } //- if got error during asynch call then previously stored exception is the reply if (it->second.rq_id == -1) { rl.push_back(GroupCmdReply(get_name(), it->second.obj_names[0], it->second.rq_ex)); //- remove request from repository arp.erase(it); return rl; } //- get reply from device try { DeviceData dd = dev_proxy()->command_inout_reply(it->second.rq_id, tmo); rl.push_back(GroupCmdReply(get_name(), it->second.obj_names[0], dd)); } catch (const Tango::DevFailed& df) { rl.push_back(GroupCmdReply(get_name(), it->second.obj_names[0], df)); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::command_inout_reply"); DevFailed df(errors); rl.push_back(GroupCmdReply(get_name(), it->second.obj_names[0], df)); } //- remove request from repository arp.erase(it); return rl; } //----------------------------------------------------------------------------- long GroupDeviceElement::read_attribute_asynch_i (const std::string& a, TANGO_UNUSED(bool fwd), long id) { if ( ! is_enabled() ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(id, a, false))); } else { try { long ari = dev_proxy()->read_attribute_asynch(const_cast(a)); arp.insert(AsynchRequestRepValue(id, AsynchRequest(ari, a))); } catch (const Tango::DevFailed& df) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, a, df))); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_asynch"); DevFailed df(errors); arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, a, df))); } } return id; } //----------------------------------------------------------------------------- GroupAttrReplyList GroupDeviceElement::read_attribute_reply_i (long id, long tmo) { GroupAttrReplyList rl; //- search actual asynch request id in this' repository AsynchRequestRepIterator it = arp.find(id); if (it == arp.end()) { //- error description Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); //- populate the returned vector rl.push_back(GroupAttrReply(get_name(), "unknown", df)); return rl; } //- no reply if this group element is diabled if ( ! is_enabled() ) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], false)); //- remove request from repository arp.erase(it); return rl; } //- if got error during asynch call then previously stored exception is the reply if (it->second.rq_id == -1) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], it->second.rq_ex)); //- remove request from repository arp.erase(it); return rl; } //- get reply from device try { DeviceAttribute* da = dev_proxy()->read_attribute_reply(it->second.rq_id, tmo); if (da == 0) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("internal error"); errors[0].reason = CORBA::string_dup("Tango::DeviceProxy::read_attribute_reply returned NULL"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], df)); } else { if (da->has_failed()) { DevFailed df(da->get_err_stack()); rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], df)); } else { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], *da)); } delete da; } } catch (const Tango::DevFailed& df) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], df)); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], df)); } //- remove request from repository arp.erase(it); return rl; } //----------------------------------------------------------------------------- long GroupDeviceElement::read_attributes_asynch_i (const std::vector& al, TANGO_UNUSED(bool fwd), long id) { if ( ! is_enabled() ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(id, al, false))); } else { try { long ari = dev_proxy()->read_attributes_asynch(const_cast&>(al)); arp.insert(AsynchRequestRepValue(id, AsynchRequest(ari, al))); } catch (const Tango::DevFailed& df) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, al, df))); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attributes_asynch"); DevFailed df(errors); arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, al, df))); } } return id; } //----------------------------------------------------------------------------- GroupAttrReplyList GroupDeviceElement::read_attributes_reply_i (long id, long tmo) { unsigned int a = 0; GroupAttrReplyList rl; //- search actual asynch request id in this' repository AsynchRequestRepIterator it = arp.find(id); if (it == arp.end()) { //- error description Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); //- populate the returned vector rl.push_back(GroupAttrReply(get_name(), "unknown", df)); return rl; } //- no reply if this group element is diabled if ( ! is_enabled() ) { for (a = 0; a < it->second.obj_names.size(); a++) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], false)); } //- remove request from repository arp.erase(it); return rl; } //- if got error during asynch call then previously stored exception is the reply if (it->second.rq_id == -1) { for (a = 0; a < it->second.obj_names.size(); a++) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], it->second.rq_ex)); } //- remove request from repository arp.erase(it); return rl; } //- get reply from device try { std::vector* dal = dev_proxy()->read_attributes_reply(it->second.rq_id, tmo); if (dal == 0) { Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("internal error"); errors[0].reason = CORBA::string_dup("Tango::DeviceProxy::read_attribute_reply returned NULL"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); for (a = 0; a < it->second.obj_names.size(); a++) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], df)); } } else { for (a = 0; a < it->second.obj_names.size(); a++) { if ((*dal)[a].has_failed()) { DevFailed df((*dal)[a].get_err_stack()); rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], df)); } else { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], (*dal)[a])); } } delete dal; } } catch (const Tango::DevFailed& df) { for (a = 0; a < it->second.obj_names.size(); a++) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], df)); } } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::read_attribute_reply"); DevFailed df(errors); for (a = 0; a < it->second.obj_names.size(); a++) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[a], df)); } } //- remove request from repository arp.erase(it); return rl; } //----------------------------------------------------------------------------- long GroupDeviceElement::write_attribute_asynch_i (const DeviceAttribute& d, TANGO_UNUSED(bool fwd), long id) { if ( ! is_enabled() ) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(id, const_cast(d).get_name(), false))); } else { try { long ari = dev_proxy()->write_attribute_asynch(const_cast(d)); arp.insert(AsynchRequestRepValue(id, AsynchRequest(ari, const_cast(d).get_name()))); } catch (const Tango::DevFailed& df) { arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, const_cast(d).get_name(), df))); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::write_attribute_asynch"); DevFailed df(errors); arp.insert(AsynchRequestRepValue(id, AsynchRequest(-1, const_cast(d).get_name(), df))); } } return id; } //----------------------------------------------------------------------------- GroupReplyList GroupDeviceElement::write_attribute_reply_i (long id, long tmo) { GroupReplyList rl; //- search actual asynch request id in this' repository AsynchRequestRepIterator it = arp.find(id); if (it == arp.end()) { //- error description Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup("API_BadAsynPollId"); errors[0].desc = CORBA::string_dup("Invalid asynch. request identifier specified"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::write_attribute_reply"); DevFailed df(errors); //- populate the returned vector rl.push_back(GroupReply(get_name(), "unknown", df)); return rl; } //- no reply if this group element is diabled if ( ! is_enabled() ) { rl.push_back(GroupAttrReply(get_name(), it->second.obj_names[0], false)); //- remove request from repository arp.erase(it); return rl; } //- if got error during asynch call then previously stored exception is the reply if (it->second.rq_id == -1) { rl.push_back(GroupReply(get_name(), it->second.obj_names[0], it->second.rq_ex)); //- remove request from repository arp.erase(it); return rl; } //- get reply from device try { dev_proxy()->write_attribute_reply(it->second.rq_id, tmo); rl.push_back(GroupReply(get_name(), it->second.obj_names[0])); } catch (const Tango::DevFailed& df) { rl.push_back(GroupReply(get_name(), it->second.obj_names[0], df)); } catch (...) { //- create a pseudo devfailed Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].desc = CORBA::string_dup("unknown error"); errors[0].reason = CORBA::string_dup("unknown exception caught"); errors[0].origin = CORBA::string_dup("GroupDeviceElement::write_attribute_reply"); DevFailed df(errors); rl.push_back(GroupReply(get_name(), it->second.obj_names[0], df)); } //- remove request from repository arp.erase(it); return rl; } //----------------------------------------------------------------------------- void GroupDeviceElement::dump (TANGO_UNUSED(int indent_level)) { #if defined(_LOCAL_DEBUGGING) for (int i = 0; i < indent_level ; i++) { cout << "\t"; } cout << "|- DEVICE: " << get_name() << endl; #endif } //----------------------------------------------------------------------------- void GroupDeviceElement::dump (TangoSys_OMemStream& oms, int indent_level) { for (int i = 0; i < indent_level ; i++) { oms << "\t"; } oms << "|- DEVICE: " << get_name() << endl; } //----------------------------------------------------------------------------- bool GroupDeviceElement::is_connected () { return dev_proxy()->is_connected(); } //----------------------------------------------------------------------------- bool GroupDeviceElement::is_device_i () { return true; } //----------------------------------------------------------------------------- bool GroupDeviceElement::is_group_i () { return false; } //----------------------------------------------------------------------------- long GroupDeviceElement::get_size_i (TANGO_UNUSED(bool fwd)) { return 1; } //----------------------------------------------------------------------------- // the following function could throw an exception, see DeviceProxy::set_timeout_millis() void GroupDeviceElement::set_timeout_millis (int tmo) { if ( tmo >= 0 ) dev_proxy()->set_timeout_millis(tmo); } } // namespace Tango tango-9.2.5a/lib/cpp/client/filedatabase.cpp0000644023471100065110000021624013034744772015664 00000000000000// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #include #include // DbInfo done // DbImportDevice // DbExportDevice // DbUnExportDevice // DbAddDevice // DbDeleteDevice // DbAddServer // DbDeleteServer // DbExportServer // DbUnExportServer // DbGetServerInfo // DbGetDeviceProperty done // DbPutDeviceProperty done // DbDeleteDeviceProperty done // DbGetDeviceAttributeProperty done // DbPutDeviceAttributeProperty done // DbDeleteDeviceAttributeProperty to check // DbGetClassProperty done // DbPutClassProperty done // DbDeleteClassProperty // DbGetClassAttributeProperty done // DbPutClassAttributeProperty done // DbDeleteClassAttributeProperty // DbGetDeviceList done // DbGetDeviceMemberList // DbGetDeviceExportedList // DbGetDeviceDomainList // DbGetDeviceFamilyList // DbGetProperty // DbPutProperty // DbDeleteProperty // DbGetAliasDevice // DbGetDeviceAlias // DbGetAttributeAlias // DbGetDeviceAliasList // DbGetAttributeAliasList // **************************************************** // Go to the next significant character // **************************************************** // **************************************************** // return the lexical classe of the next word */ // **************************************************** using namespace std; namespace Tango { const char* FileDatabase::lexical_word_null = "NULL"; const char* FileDatabase::lexical_word_number = "NUMBER"; const char* FileDatabase::lexical_word_string = "STRING"; const char* FileDatabase::lexical_word_coma = "COMA"; const char* FileDatabase::lexical_word_colon = "COLON"; const char* FileDatabase::lexical_word_slash = "SLASH"; const char* FileDatabase::lexical_word_backslash = "BackSLASH"; const char* FileDatabase::lexical_word_arrow = "->"; int FileDatabase::ReadBufferSize=4069; int FileDatabase::MaxWordLength=256; char chartolower(const char c) { if (c >= 'A' && c <= 'Z') return c - 'A' + 'a'; else return c; } bool equalsIgnoreCase(const string& s1, const string& s2) { bool ret = false; if (s1.size() == s2.size()) { int l = s1.size(); while (l) { ret = ( chartolower(s1.at(l-1)) == chartolower(s2.at(l-1)) ); l--; if (!ret) break; } } return ret; } t_device* search_device(t_server& s, string& name) { for (unsigned int j = 0; j < s.devices.size(); j++) { if (equalsIgnoreCase(s.devices[j]->name, name)) return s.devices[j]; }; return NULL; } t_tango_class* search_class(t_server& s, string& name) { for (unsigned int i = 0; i < s.classes.size(); i++) { if (equalsIgnoreCase(s.classes[i]->name, name)) return s.classes[i]; } return NULL; } t_attribute_property* search_dev_attr_prop(t_device* d, const string& name) { for (unsigned int i = 0; i < d->attribute_properties.size(); i++) { if (equalsIgnoreCase(d->attribute_properties[i]->attribute_name, name)) return d->attribute_properties[i]; } return NULL; } t_attribute_property* search_class_attr_prop(t_tango_class* d, const string& name) { for (unsigned int i = 0; i < d->attribute_properties.size(); i++) { if (equalsIgnoreCase(d->attribute_properties[i]->attribute_name, name)) return d->attribute_properties[i]; } return NULL; } std::string& trim(string& str) { // trim leading whitespace string::size_type notwhite = str.find_first_not_of(" \t\n"); str.erase(0,notwhite); // trim trailing whitespace notwhite = str.find_last_not_of(" \t\n"); str.erase(notwhite+1); return str; } std::vector& makeStringArray(const std::string& input, vector& results) { std::string delimiter = "\n"; int iPos = 0; int sizeS2 = delimiter.size(); int isize = input.size(); std::vector positions; int newPos = input.find (delimiter, 0); if( newPos < 0 ) { return results; } int numFound = 0; while( newPos > iPos ) { numFound++; positions.push_back(newPos); iPos = newPos; newPos = input.find (delimiter, iPos+sizeS2+1); } for(unsigned int i=0; i <= positions.size(); i++ ) { string s; if( i == 0 ) { s = input.substr( i, positions[i] ); } int offset = positions[i-1] + sizeS2; if( offset < isize ) { if( i == positions.size() ) { s = input.substr(offset); } else if( i > 0 ) { s = input.substr( positions[i-1] + sizeS2, positions[i] - positions[i-1] - sizeS2 ); } } if( s.size() > 0 ) { results.push_back(trim(s)); } } return results; } template bool hasName::operator() (T* obj) { return (Tango::equalsIgnoreCase(obj->name,name)); } template bool hasAttributeName::operator() (T* obj) { return (Tango::equalsIgnoreCase(obj->attribute_name,attribute_name)); } FileDatabaseExt::FileDatabaseExt() {} FileDatabaseExt::~FileDatabaseExt() {} FileDatabase::FileDatabase(const std::string& file_name) { cout4 << "FILEDATABASE: FileDatabase constructor" << endl; filename = file_name; parse_res_file(filename); } FileDatabase::~FileDatabase() { cout4 << "FILEDATABASE: FileDatabase destructor" << endl; // write_file(); std::vector::iterator i; for(i = m_server.devices.begin(); i != m_server.devices.end(); ++i) { std::vector::iterator p; for(p = (*i)->properties.begin(); p != (*i)->properties.end(); ++p) { delete (*p); } std::vector::iterator pa; for(pa = (*i)->attribute_properties.begin(); pa != (*i)->attribute_properties.end(); ++pa) { std::vector::iterator p; for(p = (*pa)->properties.begin(); p != (*pa)->properties.end(); ++p) { delete (*p); } delete (*pa); } delete (*i); } std::vector::iterator j; for(j = m_server.classes.begin(); j != m_server.classes.end(); ++j) { std::vector::iterator p; for(p = (*j)->properties.begin(); p != (*j)->properties.end(); ++p) { delete (*p); } std::vector::iterator pa; for(pa = (*j)->attribute_properties.begin(); pa != (*j)->attribute_properties.end(); ++pa) { std::vector::iterator p; for(p = (*pa)->properties.begin(); p != (*pa)->properties.end(); ++p) { delete (*p); } delete (*pa); } delete (*j); } } // **************************************************** // read the next character in the file // **************************************************** void FileDatabase :: read_char(ifstream& f) { CurrentChar=NextChar; if(!f.eof()) f.get(NextChar); else NextChar=0; if(CurrentChar=='\n') CrtLine++; } int FileDatabase :: class_lex(string& tmp_word) { /* exepction */ if(tmp_word.empty()) return 0; if(tmp_word.length()==0) return _TG_STRING; /* Special character */ if(tmp_word == "/") return _TG_SLASH; if(tmp_word == "\\") return _TG_ASLASH; if(tmp_word == ",") return _TG_COMA; if(tmp_word == ":") return _TG_COLON; if(tmp_word == "->") return _TG_ARROW; return _TG_STRING; } // **************************************************** // Go to the next line */ // **************************************************** void FileDatabase :: jump_line(ifstream& f) { while(CurrentChar!='\n' && CurrentChar!=0) read_char(f); read_char(f); } void FileDatabase :: jump_space(ifstream& f) { while((CurrentChar<=32) && (CurrentChar>0)) read_char(f); } // **************************************************** // Read the next word in the file */ // **************************************************** string FileDatabase :: read_word(ifstream& f) { string ret_word=""; /* Jump space and comments */ jump_space(f); while( CurrentChar=='#' ) { jump_line(f); jump_space(f); } /* Jump C like comments */ if( CurrentChar=='/' ) { read_char(f); if( CurrentChar=='*' ) { bool end=false; read_char(f); while(end) { while( CurrentChar!='*' ) read_char(f); read_char(f); end=(CurrentChar=='/'); } read_char(f); jump_space(f); } else { ret_word="/"; return ret_word; } } StartLine=CrtLine; /* Treat special character */ if( CurrentChar==':' || CurrentChar=='/' || CurrentChar==',' || CurrentChar=='\\' || ( CurrentChar=='-' && NextChar=='>' ) ) { if( CurrentChar!='-' ) { ret_word += CurrentChar; } else { ret_word += CurrentChar; read_char(f); ret_word += CurrentChar; } read_char(f); return ret_word; } /* Treat string */ if( CurrentChar=='"' ) { read_char(f); while( CurrentChar!='"' && CurrentChar!=0 && CurrentChar!='\n' ) { ret_word+=CurrentChar; read_char(f); } if(CurrentChar==0 || CurrentChar=='\n') { cout3 << "Error at line " << StartLine << endl; TangoSys_MemStream desc; desc << "File database: Error in file at line " << StartLine; desc << " in file " << filename << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::CHECK_LEX"); } read_char(f); return ret_word; } /* Treat other word */ while( CurrentChar>32 && CurrentChar!=':' && CurrentChar!='/' && CurrentChar!='\\' && CurrentChar!=',' ) { if( CurrentChar=='-' && NextChar=='>' ) break; ret_word+=CurrentChar; read_char(f); } if(ret_word.length()==0) { return string(lexical_word_null); } return ret_word; } // **************************************************** // Read the next word in the file // And allow / inside // **************************************************** string FileDatabase:: read_full_word(ifstream& f) { string ret_word; StartLine=CrtLine; jump_space(f); /* Treat special character */ if( CurrentChar==',' || CurrentChar=='\\' ) { ret_word += CurrentChar; read_char(f); return ret_word; } /* Treat string */ if( CurrentChar=='"' ) { read_char(f); while( CurrentChar!='"' && CurrentChar!=0 && CurrentChar!='\n') { if (CurrentChar=='\\') { read_char(f); ret_word += CurrentChar; } else ret_word += CurrentChar; read_char(f); } if( CurrentChar==0 || CurrentChar=='\n') { cout3 << "Warning: String too long at line " << StartLine << endl; TangoSys_MemStream desc; desc << "File database: String too long at line " << StartLine; desc << " in file " << filename << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::read_full_word"); } read_char(f); if (ret_word.length() == 0) ret_word = string(lexical_word_null); return ret_word; } /* Treat other word */ while( CurrentChar>32 && CurrentChar!='\\' && CurrentChar!=',') { ret_word += CurrentChar; read_char(f); } if(ret_word.length()==0) { ret_word = string(lexical_word_null); return ret_word; } return ret_word; } void FileDatabase:: CHECK_LEX(int lt,int le) { if( lt!=le ) { cout3 << "Error at line " << StartLine << endl; TangoSys_MemStream desc; desc << "File database: Error in file at line " << StartLine; desc << " in file " << filename << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::CHECK_LEX"); } } vector FileDatabase:: parse_resource_value(ifstream& f) { int lex; vector ret; int nbr; /* Resource value */ lex=_TG_COMA; nbr=0; while( (lex==_TG_COMA || lex==_TG_ASLASH) && word!="" ) { word=read_full_word(f); lex=class_lex(word); /* allow ... ,\ syntax */ if( lex==_TG_ASLASH ) { word=read_full_word(f); lex=class_lex(word); } CHECK_LEX(lex,_TG_STRING); ret.push_back(word); nbr++; word=read_word(f); lex=class_lex(word); } return ret; } // **************************************************** // Parse a resource file // Return error as String (zero length when sucess) // **************************************************** std::string FileDatabase::parse_res_file(const std::string &file_name) { ifstream f; bool eof=false; int lex; t_tango_class* un_class; t_device* un_device; string domain; string family; string member; string name; string prop_name; CrtLine=1; NextChar=' '; CurrentChar=' '; cout4 << "FILEDATABASE: entering parse_res_file" << endl; /* OPEN THE FILE */ f.open (file_name.c_str(), ifstream::in); if ( !f.good() ) { TangoSys_MemStream desc; desc << "FILEDATABASE could not open file " << file_name << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::parse_res_file"); } /* CHECK BEGINING OF CONFIG FILE */ word=read_word(f); if( word == "" ) { f.close(); return file_name + " is empty..."; } lex=class_lex(word); m_server.name = word; /* PARSE */ while( !eof ) { switch(lex) { /* Start a resource mame */ case _TG_STRING: /* Domain */ domain=word; word=read_word(f); lex=class_lex(word); //cout << "DOMAIN " << domain << endl;; CHECK_LEX(lex,_TG_SLASH); /* Family */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); family=word; //cout << "FAMILI " << family << endl; word=read_word(f); lex=class_lex(word); switch(lex) { case _TG_SLASH: /* Member */ word=read_word(f);lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); member=word; word=read_word(f); lex=class_lex(word); switch(lex) { case _TG_SLASH: /* We have a 4 fields name */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); name=word; word=read_word(f); lex=class_lex(word); switch(lex) { case _TG_COLON: { /* Device definition */ m_server.instance_name = family; vector values = parse_resource_value(f); lex=class_lex(word); //cout << "Class name : " << name << endl; un_class = new t_tango_class; un_class->name = name; m_server.classes.push_back(un_class); if( equalsIgnoreCase(member, "device") ) { /* Device definition */ for (unsigned int n = 0; n < values.size(); n++) { //cout << " Device: <" << values[n] << ">" << endl; un_device = new t_device; un_device->name = values[n]; m_server.devices.push_back(un_device); un_class->devices.push_back(un_device); } } } break; case _TG_ARROW: { /* We have an attribute property definition */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); prop_name=word; //cout << "Attribute property: " << prop_name << endl; /* jump : */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_COLON); /* Resource value */ vector values = parse_resource_value(f); lex=class_lex(word); /* Device attribute definition */ //cout << " " << domain << "/" << family << "/" << member << endl; string device_name = domain + "/" + family + "/" + member; t_device* d = search_device(m_server, device_name); t_attribute_property* un_dev_attr_prop = search_dev_attr_prop(d, name); if (un_dev_attr_prop == NULL) { un_dev_attr_prop = new t_attribute_property; un_dev_attr_prop->attribute_name = name; d->attribute_properties.push_back(un_dev_attr_prop); } t_property* prop = new t_property; prop->name = prop_name; for(unsigned int n = 0; n < values.size(); n++) { //cout << " <" << values[n] << ">" << endl; prop->value.push_back(values[n]); } un_dev_attr_prop->properties.push_back(prop); } break; default: return "COLON or -> expected at line " + StartLine; } break; case _TG_ARROW: { /* We have a device property or attribute class definition */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); prop_name=word; /* jump : */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_COLON); /* Resource value */ vector values = parse_resource_value(f); lex=class_lex(word); if(equalsIgnoreCase(domain, "class")) { /* Class attribute property definition */ //cout << "Class attribute property definition" << endl; //cout << " family,member,prop_name,values :" << family <<","<attribute_name = member; c->attribute_properties.push_back(un_class_attr_prop); } t_property* prop = new t_property; prop->name = prop_name; for(unsigned int n = 0; n < values.size(); n++) { //cout << " <" << values[n] << ">" << endl; prop->value.push_back(values[n]); } un_class_attr_prop->properties.push_back(prop); //put_tango_class_attr_prop(family,member,prop_name,values); } } else { /* Device property definition */ //cout << "Device property definition " << prop_name << endl; //cout << " " << domain << "/" << family << "/" << member << endl; string device_name = domain + "/" + family + "/" + member; t_device* d = search_device(m_server, device_name); if (d != NULL) { t_property* un_dev_prop = new t_property; un_dev_prop->name = prop_name; for(unsigned int n = 0; n < values.size(); n++) { //cout << " <" << values[n] << ">" << endl; un_dev_prop->value.push_back(values[n]); } d->properties.push_back(un_dev_prop); } } } break; default: return "SLASH or -> expected at line " + StartLine; } break; case _TG_ARROW: { /* We have a class property */ /* Member */ word=read_word(f); lex=class_lex(word); CHECK_LEX(lex,_TG_STRING); member=word; word=read_word(f); lex=class_lex(word); /* Resource value */ vector values = parse_resource_value(f); lex=class_lex(word); /* Class resource */ if( equalsIgnoreCase(domain, "class") ) { //cout << "Tango resource class " << endl; { un_class = search_class(m_server, family); if (un_class != NULL) { t_property* un_prop = new t_property; un_prop->name = member; //cout << "Proprieta : " << member << endl; for(unsigned int n = 0; n< values.size(); n++) { //cout << " " << member << "[" << n << "] = " << values[n] << endl; un_prop->value.push_back(values[n]); } un_class->properties.push_back(un_prop); } } } else if ( equalsIgnoreCase(domain, "free") ) { // cout << "Free Tango res" << endl; //put_free_tango_res(family,member,values); } else { return "Invlalid class property syntax on " + domain + "/" + family +"/"+ member; } } break; default: return "SLASH or -> expected at line " + StartLine; } break; default: return "Invalid resource name get instead of STRING al line " + StartLine; } eof=(word == lexical_word_null); } f.close(); return ""; } void FileDatabase:: display() { cout << " ************************** " << endl; cout << "server = " << m_server.name << endl; for (unsigned int i = 0; i < m_server.classes.size(); i++) { unsigned int j; cout << " class = " << m_server.classes[i]->name << endl; for (j = 0; j < m_server.classes[i]->devices.size(); j++) { unsigned int k; cout << " device = " << m_server.classes[i]->devices[j]->name << endl; for (k = 0; k < m_server.classes[i]->devices[j]->properties.size(); k++) { cout << " proper = " << m_server.classes[i]->devices[j]->properties[k]->name << " value: " << endl; for (unsigned int l = 0; l < m_server.classes[i]->devices[j]->properties[k]->value.size(); l++) { cout << " value[" << l << "] = " << m_server.classes[i]->devices[j]->properties[k]->value[l] << endl; } } for (k = 0; k < m_server.classes[i]->devices[j]->attribute_properties.size(); k++) { cout << " attribute = " << m_server.classes[i]->devices[j]->attribute_properties[k]->attribute_name << endl; for (unsigned int l = 0; l < m_server.classes[i]->devices[j]->attribute_properties[k]->properties.size(); l++) { cout << " property[" << l << "] = " << m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->name << endl; for (unsigned int m = 0; m < m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->value.size(); m++) cout << " value[" << m << "] = " << m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->value[m] << endl; } } } for (j = 0; j < m_server.classes[i]->properties.size(); j++) { cout << " proper = " << m_server.classes[i]->properties[j]->name << " value: " << endl; for (unsigned int l = 0; l < m_server.classes[i]->properties[j]->value.size(); l++) { cout << " value[" << l << "] = " << m_server.classes[i]->properties[j]->value[l] << endl; } } } } string FileDatabase :: get_display() { ostringstream ost; ost << " ************************** " << endl; ost << "server = " << m_server.name << endl; for (unsigned int i = 0; i < m_server.classes.size(); i++) { unsigned int j; ost << " class = " << m_server.classes[i]->name << endl; for (j = 0; j < m_server.classes[i]->devices.size(); j++) { unsigned int k; ost << " device = " << m_server.classes[i]->devices[j]->name << endl; for (k = 0; k < m_server.classes[i]->devices[j]->properties.size(); k++) { ost << " proper = " << m_server.classes[i]->devices[j]->properties[k]->name << " value: " << endl; for (unsigned int l = 0; l < m_server.classes[i]->devices[j]->properties[k]->value.size(); l++) { ost << " value[" << l << "] = " << m_server.classes[i]->devices[j]->properties[k]->value[l] << endl; } } for (k = 0; k < m_server.classes[i]->devices[j]->attribute_properties.size(); k++) { ost << " attribute = " << m_server.classes[i]->devices[j]->attribute_properties[k]->attribute_name << endl; for (unsigned int l = 0; l < m_server.classes[i]->devices[j]->attribute_properties[k]->properties.size(); l++) { ost << " property[" << l << "] = " << m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->name << endl; for (unsigned int m = 0; m < m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->value.size(); m++) ost << " value[" << m << "] = " << m_server.classes[i]->devices[j]->attribute_properties[k]->properties[l]->value[m] << endl; } } } for (j = 0; j < m_server.classes[i]->properties.size(); j++) { ost << " proper = " << m_server.classes[i]->properties[j]->name << " value: " << endl; for (unsigned int l = 0; l < m_server.classes[i]->properties[j]->value.size(); l++) { ost << " value[" << l << "] = " << m_server.classes[i]->properties[j]->value[l] << endl; } } } return ost.str(); } void FileDatabase :: write_file() { ofstream f; string f_name(filename); /* string::size_type pos; if ((pos = f_name.rfind('/')) == string::npos) f_name = "_" + f_name; else f_name.insert(pos + 1,"_",1); */ f.open (f_name.c_str()); vector::const_iterator it; for(it = m_server.classes.begin(); it != m_server.classes.end(); ++it) { f << m_server.name << "/" << m_server.instance_name << "/DEVICE/" << (*it)->name << ": " ; int margin = m_server.name.size() + 1 + m_server.instance_name.size() + 8 + (*it)->name.size() + 2; string margin_s(margin,' '); vector::iterator iterator_d = (*it)->devices.begin(); f << "\"" << (*iterator_d)->name << "\""; ++iterator_d; for(vector::iterator itd = iterator_d; itd != (*it)->devices.end(); ++itd) { f << ",\\" << endl; f << margin_s << "\"" << (*itd)->name << "\""; } f << endl; } f << endl; for(it = m_server.classes.begin(); it != m_server.classes.end(); ++it) { f << "#############################################" << endl; f << "# CLASS " << (*it)->name << endl; f << endl; for(vector::iterator itp = (*it)->properties.begin(); itp != (*it)->properties.end(); ++itp) { f << "CLASS/" << (*it)->name << "->" << (*itp)->name << ": " ; int margin = 6 + (*it)->name.size() + 2 + (*itp)->name.size() + 2; string margin_s(margin,' '); vector::iterator iterator_s = (*itp)->value.begin(); if ((*iterator_s).length() == 0) (*iterator_s)[0] = ' '; if (iterator_s != (*itp)->value.end()) { //f << "\"" << (*iterator_s) << "\""; if ((*iterator_s).length() == 0) f << "\"\""; else { if (iterator_s->find(' ', 0)!=string::npos) f << "\"" ; string str = (*iterator_s); escape_double_quote(str); f << str; if (iterator_s->find(' ', 0)!=string::npos) f << "\""; } ++iterator_s; for(vector::iterator its = iterator_s; its != (*itp)->value.end(); ++its) { f << ",\\" << endl; f << margin_s; if (its->find(' ', 0)!=string::npos) f << "\"" ; string str = (*its); escape_double_quote(str); f << str; if (its->find(' ', 0)!=string::npos) f << "\""; } } f << endl; } f << endl; f << "# CLASS " << (*it)->name << " attribute properties" << endl; f << endl; for(vector::const_iterator itap = (*it)->attribute_properties.begin(); itap != (*it)->attribute_properties.end(); ++itap) { for(vector::const_iterator itp = (*itap)->properties.begin(); itp != (*itap)->properties.end(); ++itp) { f << "CLASS/" << (*it)->name << "/" << (*itap)->attribute_name << "->" << (*itp)->name << ": "; int margin = 6 + (*it)->name.size() + 1 + (*itap)->attribute_name.size() + 2 + (*itp)->name.size() +2; vector::iterator iterator_s = (*itp)->value.begin(); if (iterator_s != (*itp)->value.end()) { if (iterator_s->find(' ', 0)!=string::npos) f << "\"" ; string str = (*iterator_s); escape_double_quote(str); f << str; if (iterator_s->find(' ', 0)!=string::npos) f << "\""; ++iterator_s; for(vector::iterator its = iterator_s; its != (*itp)->value.end(); ++its) { f << ",\\" << endl; string margin_s(margin,' '); f << margin_s; if (its->find(' ', 0)!=string::npos) f << "\"" ; string str = (*its); escape_double_quote(str); f << str; if (its->find(' ', 0)!=string::npos) f << "\""; } } f << endl; } } f << endl; } f << endl; for(vector::const_iterator ite = m_server.devices.begin(); ite != m_server.devices.end(); ++ite) { f << "# DEVICE " << (*ite)->name << " properties " << endl << endl; for(vector::const_iterator itp = (*ite)->properties.begin(); itp != (*ite)->properties.end(); ++itp) { f << (*ite)->name << "->" << (*itp)->name << ": "; vector::iterator iterator_s = (*itp)->value.begin(); if (iterator_s != (*itp)->value.end()) { int margin = (*ite)->name.size() + 1 + (*itp)->name.size() + 2; if (iterator_s->find(' ', 0)!=string::npos) f << "\"" ; string str = (*iterator_s); escape_double_quote(str); f << str; if (iterator_s->find(' ', 0)!=string::npos) f << "\""; ++iterator_s; for(vector::iterator its = iterator_s; its != (*itp)->value.end(); ++its) { f << ",\\" << endl; string margin_s(margin,' '); f << margin_s; if (its->find(' ', 0)!=string::npos) f << "\"" ; string str = (*its); escape_double_quote(str); f << str; if (its->find(' ', 0)!=string::npos) f << "\""; } } f << endl; } f << endl; f << "# DEVICE " << (*ite)->name << " attribute properties" << endl << endl; for(vector::const_iterator itap = (*ite)->attribute_properties.begin(); itap != (*ite)->attribute_properties.end(); ++itap) { for(vector::const_iterator itp = (*itap)->properties.begin(); itp != (*itap)->properties.end(); ++itp) { f << (*ite)->name << "/" << (*itap)->attribute_name << "->" << (*itp)->name << ": "; int margin = (*ite)->name.size() + 1 + (*itap)->attribute_name.size() + 2 + (*itp)->name.size() +2; vector::iterator iterator_s = (*itp)->value.begin(); if (iterator_s != (*itp)->value.end()) { if (iterator_s->find(' ', 0)!=string::npos) f << "\"" ; string str = (*iterator_s); escape_double_quote(str); f << str; if (iterator_s->find(' ', 0)!=string::npos) f << "\""; ++iterator_s; for(vector::iterator its = iterator_s; its != (*itp)->value.end(); ++its) { f << ",\\" << endl; string margin_s(margin,' '); f << margin_s; if (its->find(' ', 0)!=string::npos) f << "\"" ; string str = (*its); escape_double_quote(str); f << str; if (its->find(' ', 0)!=string::npos) f << "\""; } } f << endl; } } } f.close(); } void FileDatabase::escape_double_quote(string &_str) { int co = count(_str.begin(),_str.end(),'"'); if (co != 0) { string::size_type start = 0; for (int i = 0;i < co;i++) { string::size_type pos = _str.find('"',start); _str.insert(pos,1,'\\'); start = pos + 2; } } } CORBA::Any* FileDatabase :: DbGetDeviceProperty(CORBA::Any& send) { Tango::DevVarStringArray* data_out = new DevVarStringArray; const Tango::DevVarStringArray* data_in = NULL; char num_prop_str[256]; char num_vals_str[256]; unsigned int num_prop = 0; cout4 << "FILEDATABASE: entering DbGetDeviceProperty" << endl; send >>= data_in; CORBA::Any* any_ptr; any_ptr = new CORBA::Any(); int index = 0; data_out->length(2); (*data_out)[0] = CORBA::string_dup( (*data_in)[0] ); index++; num_prop = data_in->length() - 1; sprintf(num_prop_str,"%ud",num_prop); (*data_out)[index] = CORBA::string_dup(num_prop_str); index++; if (data_in->length() >= 2) { unsigned long nb_defined_dev = m_server.devices.size(); unsigned long i; int seq_length = 2; for(i = 0; i < nb_defined_dev; i++) { if ( equalsIgnoreCase((*data_in)[0].in(), m_server.devices[i]->name)) { for (unsigned int j = 1; j < data_in->length(); j++) { unsigned long m; unsigned long nb_defined_prop = m_server.devices[i]->properties.size(); for (m = 0; m < nb_defined_prop; m++) { //if ( strcmp((*data_in)[j], m_server.devices[i]->properties[m]->name.c_str()) == 0 ) if ( equalsIgnoreCase((*data_in)[j].in(), m_server.devices[i]->properties[m]->name)) { int num_val = 0; num_prop++; num_val = m_server.devices[i]->properties[m]->value.size(); seq_length = seq_length + 2 + m_server.devices[i]->properties[m]->value.size(); data_out->length(seq_length); (*data_out)[index] = CORBA::string_dup( m_server.devices[i]->properties[m]->name.c_str() );index++; sprintf(num_vals_str,"%d",num_val); (*data_out)[index] = CORBA::string_dup(num_vals_str); index++; for (int k=0; k < num_val; k++) { (*data_out)[index] = CORBA::string_dup( m_server.devices[i]->properties[m]->value[k].c_str());index++; } break; } } if (m == nb_defined_prop) { seq_length = seq_length + 3; data_out->length(seq_length); (*data_out)[index] = CORBA::string_dup((*data_in)[j].in());index++; (*data_out)[index] = CORBA::string_dup("0");index++; (*data_out)[index] = CORBA::string_dup(" ");index++; } } break; } } if (i == nb_defined_dev) { for (i = 0;i < num_prop;i++) { seq_length = seq_length + 3; data_out->length(seq_length); (*data_out)[index] = CORBA::string_dup((*data_in)[i + 1].in());index++; (*data_out)[index] = CORBA::string_dup("0");index++; (*data_out)[index] = CORBA::string_dup(" ");index++; } } } (*any_ptr) <<= data_out; //for (unsigned int i = 0; i < data_out->length(); i++) // cout << "data_out[" << i << "] = " << (*data_out)[i] << endl; return any_ptr; }; CORBA::Any* FileDatabase :: DbPutDeviceProperty(CORBA::Any& send) { cout4 << "FILEDATABASE: entering DbPutDeviceProperty" << endl; CORBA::Any* any_ptr = new CORBA::Any; const Tango::DevVarStringArray* data_in = NULL; unsigned int n_properties=0; int n_values=0; send >>= data_in; if ((*data_in).length() > 1) { int index = 0; std::vector::iterator it; it = find_if(m_server.devices.begin(), m_server.devices.end(), hasName(string((*data_in)[index])));index++; if (it == m_server.devices.end()) { cout4 << "Nome device " << (*data_in)[0] << " non trovato. " << endl; return any_ptr; } t_device& device_trovato = *(*(it)); sscanf((*data_in)[1],"%6d",&n_properties); index++; for (unsigned int i=0; i< n_properties; i++) { std::vector::iterator prop_it; prop_it = find_if(device_trovato.properties.begin(), device_trovato.properties.end(), hasName(string((*data_in)[index])));index++; if (prop_it != device_trovato.properties.end()) { /* we found a property */ t_property& prop = (*(*prop_it)); sscanf((*data_in)[index],"%6d",&n_values); index++; prop.value.resize(n_values); for(int j = 0; j< n_values; j++) { prop.value[j] = (*data_in)[index]; index++; } } else { /* it is a new property */ t_property* temp_property = new t_property; temp_property->name = (*data_in)[index-1]; sscanf((*data_in)[index],"%6d",&n_values); index++; for(int j = 0; j < n_values; j++) { temp_property->value.push_back(string((*data_in)[index])); index++; } device_trovato.properties.push_back(temp_property); } } } write_file(); return any_ptr; }; CORBA::Any* FileDatabase :: DbDeleteDeviceProperty(CORBA::Any& send) { cout4 << "FILEDATABASE: entering DbDeleteDeviceProperty" << endl; const Tango::DevVarStringArray* data_in = NULL; send >>= data_in; //for(unsigned int i = 0; i < (*data_in).length(); i++) // cout << "(*data_in)[" << i << "] = " << (*data_in)[i] << endl; std::vector::iterator it; it = find_if(m_server.devices.begin(), m_server.devices.end(), hasName(string((*data_in)[0]))); if (it != m_server.devices.end()) { for(unsigned int i = 1; i < (*data_in).length(); i++) { t_device& device_trovato = *(*(it)); std::vector::iterator itp; itp = find_if(device_trovato.properties.begin(), device_trovato.properties.end(), hasName(string((*data_in)[i]))); if (itp != device_trovato.properties.end()) { //cout << "found " << (*itp)->name << endl; device_trovato.properties.erase(itp, itp+1); } } } CORBA::Any* any_ptr = new CORBA::Any; write_file(); return any_ptr; }; CORBA::Any* FileDatabase :: DbGetDeviceAttributeProperty(CORBA::Any& send) { Tango::DevVarStringArray* data_out = new DevVarStringArray; const Tango::DevVarStringArray* data_in = NULL; char num_prop_str[256]; char num_attr_str[256]; unsigned int num_attr = 0; CORBA::Any* any_ptr; any_ptr = new CORBA::Any(); cout4 << "FILEDATABASE: entering DbGetDeviceAttributeProperty" << endl; send >>= data_in; //for(unsigned int i = 0; i < data_in->length(); i++) // cout << "send[" << i << "] = " << (*data_in)[i] << endl; int index = 0; data_out->length(2); (*data_out)[0] = CORBA::string_dup( (*data_in)[0] ); index++; num_attr = data_in->length() - 1; sprintf(num_attr_str, "%ud", num_attr); (*data_out)[index] = CORBA::string_dup( num_attr_str ); index++; std::vector::iterator dev_it; dev_it = find_if(m_server.devices.begin(), m_server.devices.end(), hasName(string((*data_in)[0]))); if (dev_it != m_server.devices.end()) { //cout << "Device " << (*dev_it)->name << " trovato." << endl; for(unsigned int k =0; k < num_attr; k++) { data_out->length(index+2); (*data_out)[index] = CORBA::string_dup((*data_in)[k+1]); index++; // attribute name (*data_out)[index] = CORBA::string_dup("0"); index++; // number of properties for(unsigned int j = 0; j < (*dev_it)->attribute_properties.size(); j++) { if (equalsIgnoreCase((*dev_it)->attribute_properties[j]->attribute_name, (*data_in)[k+1].in())) { unsigned int num_prop = 0; int num_attr_find = 0; //cout << "Proprieta' " << (*dev_it)->attribute_properties[j]->attribute_name << " trovata." << endl; num_prop = (*dev_it)->attribute_properties[j]->properties.size(); sprintf(num_prop_str, "%ud", num_prop); //cout << "num proprieta'= " << num_prop_str << endl; num_attr_find++; (*data_out)[index-1] = CORBA::string_dup(num_prop_str); for (unsigned int l = 0; l < num_prop; l++) { char num_val_str[256]; data_out->length(index + 1 + 1 + (*dev_it)->attribute_properties[j]->properties[l]->value.size()); (*data_out)[index] = CORBA::string_dup((*dev_it)->attribute_properties[j]->properties[l]->name.c_str());index++; #ifdef TANGO_LONG64 sprintf(num_val_str, "%lu", (*dev_it)->attribute_properties[j]->properties[l]->value.size()); #else sprintf(num_val_str, "%d", (*dev_it)->attribute_properties[j]->properties[l]->value.size()); #endif (*data_out)[index] = CORBA::string_dup(num_val_str); index++; for(unsigned int ii = 0; ii < (*dev_it)->attribute_properties[j]->properties[l]->value.size(); ii++) { //cout << ii << " = " << (*dev_it)->attribute_properties[j]->properties[l]->value[ii].c_str() << endl; (*data_out)[index] = CORBA::string_dup((*dev_it)->attribute_properties[j]->properties[l]->value[ii].c_str()); index++; } } } } } } else { data_out->length(index + 2 * num_attr); for(unsigned int i = 0; i < num_attr; i++) { (*data_out)[index] = CORBA::string_dup((*data_in)[i+1]); index++; (*data_out)[index] = CORBA::string_dup("0"); index++; } } //for(unsigned int i = 0; i < data_out->length(); i++) // cout << "data_out[" << i << "] = " << (*data_out)[i] << endl; (*any_ptr) <<= data_out; return any_ptr; }; CORBA::Any* FileDatabase :: DbPutDeviceAttributeProperty(CORBA::Any& send) { const Tango::DevVarStringArray* data_in = NULL; unsigned int num_prop = 0; unsigned int num_attr = 0; unsigned int num_vals = 0; CORBA::Any* ret = new CORBA::Any; cout4 << "FILEDATABASE: entering DbPutDeviceAttributeProperty" << endl; send >>= data_in; unsigned int index = 0; std::vector::iterator dev_it; dev_it = find_if(m_server.devices.begin(), m_server.devices.end(), hasName(string((*data_in)[index])));index++; if (dev_it != m_server.devices.end()) { sscanf((*data_in)[index],"%6d",&num_attr); index++; for(unsigned int j = 0; j < num_attr; j++) { t_attribute_property* temp_attribute_property; std::vector::iterator attr_prop_it; attr_prop_it = find_if((*dev_it)->attribute_properties.begin(),(*dev_it)->attribute_properties.end(), hasAttributeName(string((*data_in)[index]))); if (attr_prop_it != (*dev_it)->attribute_properties.end()) { temp_attribute_property = (*attr_prop_it); } else { // the property is not yet in the file: we add it temp_attribute_property = new t_attribute_property; temp_attribute_property->attribute_name = string((*data_in)[index]); (*dev_it)->attribute_properties.push_back(temp_attribute_property); } //if (equalsIgnoreCase((*dev_it)->attribute_properties[j]->attribute_name, (*data_in)[index].in())) index++; sscanf((*data_in)[index],"%6d",&num_prop); index++; for (unsigned int i = 0; i < num_prop; i++) { bool exist = false; for(unsigned int k = 0; k < temp_attribute_property->properties.size(); k++) { if (equalsIgnoreCase(temp_attribute_property->properties[k]->name, (*data_in)[index].in())) { index++; temp_attribute_property->properties[k]->value.erase(temp_attribute_property->properties[k]->value.begin(), temp_attribute_property->properties[k]->value.begin()+temp_attribute_property->properties[k]->value.size()); sscanf((*data_in)[index],"%6d",&num_vals); index++; for(unsigned int n = 0; n < num_vals; n++) { temp_attribute_property->properties[k]->value.push_back(string((*data_in)[index])); index++; } // (*dev_it)->attribute_properties[j]->properties[k]->value.push_back( string((*data_in)[index]) );index++; if (index >= data_in->length()) { write_file(); return ret; } exist = true; } } if ( !exist ) { t_property* new_prop = new t_property; new_prop->name = (*data_in)[index]; index++; sscanf((*data_in)[index],"%6d",&num_vals); index++; for(unsigned int n = 0; n < num_vals; n++) { new_prop->value.push_back(string((*data_in)[index])); index++; } //makeStringArray( string((*data_in)[index]), new_prop->value);index++; //new_prop->value.push_back( string((*data_in)[index]) );index++; temp_attribute_property->properties.push_back(new_prop); if (index >= data_in->length()) { write_file(); return ret; } } } } } write_file(); return ret; }; CORBA::Any* FileDatabase :: DbDeleteDeviceAttributeProperty(CORBA::Any& send) { cout4 << "FILEDATABASE: entering DbDeleteDeviceAttributeProperty" << endl; const Tango::DevVarStringArray* data_in = NULL; send >>= data_in; //for(unsigned int i = 0; i < (*data_in).length(); i++) // cout << "(*data_in)[" << i << "] = " << (*data_in)[i] << endl; std::vector::iterator it; it = find_if(m_server.devices.begin(), m_server.devices.end(), hasName(string((*data_in)[0]))); if (it != m_server.devices.end()) { t_device& device_trovato = *(*(it)); for(unsigned int j = 0; j < device_trovato.attribute_properties.size(); j++) { if (equalsIgnoreCase(device_trovato.attribute_properties[j]->attribute_name, (*data_in)[1].in())) { for(unsigned int m = 2; m < (*data_in).length(); m++) { std::vector::iterator itp; itp = find_if(device_trovato.attribute_properties[j]->properties.begin(), device_trovato.attribute_properties[j]->properties.end(), hasName(string((*data_in)[m]))); if (itp != device_trovato.attribute_properties[j]->properties.end()) { // cout << "found property" << (*itp)->name << "for attribute " << device_trovato.attribute_properties[j]->attribute_name << endl; device_trovato.attribute_properties[j]->properties.erase(itp, itp+1); } } } } } CORBA::Any* ret = new CORBA::Any; write_file(); return ret; }; CORBA::Any* FileDatabase :: DbGetClassProperty(CORBA::Any& send) { Tango::DevVarStringArray* data_out = new DevVarStringArray; const Tango::DevVarStringArray* data_in = NULL; char num_prop_str[256]; char num_vals_str[256]; unsigned int num_prop = 0; unsigned int num_val = 0; cout4 << "FILEDATABASE: entering DbGetClassProperty" << endl; send >>= data_in; CORBA::Any *any_ptr = new CORBA::Any(); int index = 0; int seq_length = 2; data_out->length(2); (*data_out)[0] = CORBA::string_dup((*data_in)[0]); index++; num_prop = data_in->length() - 1; sprintf(num_prop_str,"%ud",num_prop); (*data_out)[index] = CORBA::string_dup(num_prop_str); index++; unsigned long nb_classes_defined = m_server.classes.size(); unsigned long i; for(i = 0; i < nb_classes_defined; i++) { if (equalsIgnoreCase((*data_in)[0].in(), m_server.classes[i]->name)) { // m_server.classes[i] e' la classe che cerchiamo for (unsigned int j = 1; j < (*data_in).length(); j++) // in 0 c'e' il nome della classe e poi a seguire le proprieta { unsigned long nb_prop_defined = m_server.classes[i]->properties.size(); unsigned long m; for (m = 0; m < nb_prop_defined; m++) { if (equalsIgnoreCase((*data_in)[j].in(), m_server.classes[i]->properties[m]->name)) { num_prop++; num_val = m_server.classes[i]->properties[m]->value.size(); seq_length = seq_length + 2 + num_val; (*data_out).length(seq_length); (*data_out)[index] = CORBA::string_dup((*data_in)[j]); index++; #ifdef TANGO_LONG64 sprintf(num_vals_str,"%lu",m_server.classes[i]->properties[m]->value.size()); #else sprintf(num_vals_str,"%d",m_server.classes[i]->properties[m]->value.size()); #endif (*data_out)[index] = CORBA::string_dup(num_vals_str); index++; for (unsigned int n = 0; n < num_val; n++) { (*data_out)[index] = CORBA::string_dup(m_server.classes[i]->properties[m]->value[n].c_str()); index++; } break; } } if (m == nb_prop_defined) { seq_length = seq_length + 2; data_out->length(seq_length); (*data_out)[index] = CORBA::string_dup((*data_in)[i + 1].in());index++; (*data_out)[index] = CORBA::string_dup("0");index++; // (*data_out)[index] = CORBA::string_dup(" ");index++; } } break; } } if (i == nb_classes_defined) { for (i = 0;i < num_prop;i++) { seq_length = seq_length + 2; data_out->length(seq_length); (*data_out)[index] = CORBA::string_dup((*data_in)[i + 1].in());index++; (*data_out)[index] = CORBA::string_dup("0");index++; // (*data_out)[index] = CORBA::string_dup(" ");index++; } } (*any_ptr) <<= data_out; cout4 << "FILEDATABASE: ending DbGetClassProperty" << endl; return any_ptr; }; CORBA::Any* FileDatabase :: DbPutClassProperty(CORBA::Any& send) { CORBA::Any* ret = new CORBA::Any; const Tango::DevVarStringArray* data_in = NULL; unsigned int n_properties=0; int n_values=0; cout4 << "FILEDATABASE: entering DbPutClassProperty" << endl; send >>= data_in; // for(unsigned int n = 0; n < data_in->length(); n++) // cout << "DbPutProperty : " << string((*data_in)[n]) << endl; if ((*data_in).length() > 1) { unsigned int index = 0; std::vector::iterator it; it = find_if(m_server.classes.begin(), m_server.classes.end(), hasName(string((*data_in)[index])));index++; if (it == m_server.classes.end()) { cout4 << "Nome classe " << (*data_in)[0] << " non trovato. " << endl; return ret; } t_tango_class& classe_trovata = *(*(it)); sscanf((*data_in)[index],"%6d",&n_properties); index++; for (unsigned int i=0; i< n_properties; i++) { std::vector::iterator prop_it; prop_it = find_if(classe_trovata.properties.begin(), classe_trovata.properties.end(), hasName(string((*data_in)[index]))); if (prop_it != classe_trovata.properties.end()) { /* we found a property */ index++; t_property& prop = (*(*prop_it)); sscanf((*data_in)[index],"%6d",&n_values); index++; prop.value.resize(n_values); for(int j = 0; j< n_values; j++) { prop.value[j] = (*data_in)[index]; index++; //db_data[i] >> prop.value; } } else { /* it is a new property */ t_property* temp_property = new t_property; temp_property->name = (*data_in)[index]; index++; sscanf((*data_in)[index],"%6d",&n_values); index++; for(int j = 0; j < n_values; j++) { temp_property->value.push_back(string((*data_in)[index])); index++; } classe_trovata.properties.push_back(temp_property); if (index >= data_in->length()) { write_file(); return ret; } } } } write_file(); return ret; }; CORBA::Any* FileDatabase :: DbDeleteClassProperty(CORBA::Any& send) { cout4 << "FILEDATABASE: entering DbDeleteClassProperty" << endl; const Tango::DevVarStringArray* data_in = NULL; send >>= data_in; // for(unsigned int i = 0; i < (*data_in).length(); i++) // cout << "(*data_in)[" << i << "] = " << (*data_in)[i] << endl; std::vector::iterator it; it = find_if(m_server.classes.begin(), m_server.classes.end(), hasName(string((*data_in)[0]))); if (it != m_server.classes.end()) { for(unsigned int i = 1; i < (*data_in).length(); i++) { t_tango_class& classe_trovata = *(*(it)); std::vector::iterator itp; itp = find_if(classe_trovata.properties.begin(), classe_trovata.properties.end(), hasName(string((*data_in)[i]))); if (itp != classe_trovata.properties.end()) { //cout << "found " << (*itp)->name << endl; classe_trovata.properties.erase(itp, itp+1); } } } CORBA::Any* ret = new CORBA::Any; write_file(); return ret; }; CORBA::Any* FileDatabase :: DbGetClassAttributeProperty(CORBA::Any& send) { CORBA::Any* any_ptr = new CORBA::Any(); Tango::DevVarStringArray* data_out = new DevVarStringArray; const Tango::DevVarStringArray* data_in = NULL; unsigned int num_attr = 0; int num_prop = 0; char num_attr_str[256]; char num_prop_str[256]; cout4 << "FILEDATABASE: entering DbGetClassAttributeProperty" << endl; send >>= data_in; int index = 0; data_out->length(2); (*data_out)[0] = CORBA::string_dup((*data_in)[0]); index++; num_attr = data_in->length() - 1; sprintf(num_attr_str,"%ud",num_attr); (*data_out)[1] = CORBA::string_dup(num_attr_str); index++; std::vector::iterator it; it = find_if(m_server.classes.begin(), m_server.classes.end(), hasName(string((*data_in)[0]))); if (it == m_server.classes.end()) { cout4 << "Nome classe " << (*data_in)[0] << " non trovato. " << endl; data_out->length(index + num_attr*2); for(unsigned int j = 0; j < num_attr; j++) { (*data_out)[index] = CORBA::string_dup((*data_in)[j+1]); index++; (*data_out)[index] = CORBA::string_dup("0"); index++; } (*any_ptr) <<= data_out; return any_ptr; } t_tango_class& classe_trovata = *(*(it)); for(unsigned int k =0; k < num_attr; k++) { data_out->length(index+2); (*data_out)[index] = CORBA::string_dup((*data_in)[k+1]); index++; (*data_out)[index] = CORBA::string_dup("0"); index++; for(unsigned int j = 0; j < classe_trovata.attribute_properties.size(); j++) { if (equalsIgnoreCase(classe_trovata.attribute_properties[j]->attribute_name, (*data_in)[k+1].in())) { num_prop = classe_trovata.attribute_properties[j]->properties.size(); sprintf(num_prop_str, "%d", num_prop); //data_out->length(index + 2*num_prop); (*data_out)[index-1] = CORBA::string_dup(num_prop_str); for (unsigned int l = 0; l < classe_trovata.attribute_properties[j]->properties.size(); l++) { char num_val_str[256]; data_out->length(index + 1 + 1 + classe_trovata.attribute_properties[j]->properties[l]->value.size()); (*data_out)[index] = CORBA::string_dup(classe_trovata.attribute_properties[j]->properties[l]->name.c_str());index++; #ifdef TANGO_LONG64 sprintf(num_val_str, "%lu", classe_trovata.attribute_properties[j]->properties[l]->value.size()); #else sprintf(num_val_str, "%d", classe_trovata.attribute_properties[j]->properties[l]->value.size()); #endif (*data_out)[index] = CORBA::string_dup(num_val_str); index++; //(*data_out)[index] = CORBA::string_dup(classe_trovata.attribute_properties[j]->properties[l]->name.c_str());index++; //string temp_value(""); if (classe_trovata.attribute_properties[j]->properties[l]->value.size() > 0) { //temp_value += classe_trovata.attribute_properties[j]->properties[l]->value[0]; for (unsigned int m = 0; m < classe_trovata.attribute_properties[j]->properties[l]->value.size(); m++) { (*data_out)[index] = CORBA::string_dup(classe_trovata.attribute_properties[j]->properties[l]->value[m].c_str()); index++; //temp_value += "\n" + classe_trovata.attribute_properties[j]->properties[l]->value[m]; } } } } } } //for(unsigned int i = 0; i < data_out->length(); i++) // cout << "data_out[" << i << "] = " << (*data_out)[i] << endl; (*any_ptr) <<= data_out; return any_ptr; }; CORBA::Any* FileDatabase :: DbPutClassAttributeProperty(CORBA::Any& send) { CORBA::Any* ret = new CORBA::Any(); const Tango::DevVarStringArray* data_in = NULL; unsigned int num_attr = 0; unsigned int num_prop = 0; unsigned int num_vals = 0; unsigned int index = 0; cout4 << "FILEDATABASE: entering DbPutClassAttributeProperty" << endl; send >>= data_in; std::vector::iterator it; it = find_if(m_server.classes.begin(), m_server.classes.end(), hasName(string((*data_in)[index])));index++; if (it == m_server.classes.end()) { cout4 << "FILEDATABASE: DbPutClassAttributeProperty class " << string((*data_in)[0]) << " not found." << endl; } else { sscanf((*data_in)[index],"%6d",&num_attr); index++; t_tango_class& classe_trovata = *(*(it)); t_attribute_property* temp_attribute_property; std::vector::iterator attr_prop_it; for(unsigned int j = 0; j < num_attr; j++) { // search an attribute property for this attribute attr_prop_it = find_if(classe_trovata.attribute_properties.begin(),classe_trovata.attribute_properties.end(), hasAttributeName(string((*data_in)[index]))); if (attr_prop_it != classe_trovata.attribute_properties.end()) { temp_attribute_property = (*attr_prop_it); } else { // the property is not yet in the file: we add it temp_attribute_property = new t_attribute_property; temp_attribute_property->attribute_name = string((*data_in)[index]); classe_trovata.attribute_properties.push_back(temp_attribute_property); } index++; sscanf((*data_in)[index],"%6d",&num_prop); index++; for (unsigned int i = 0; i < num_prop; i++) { bool exist = false; for(unsigned int k = 0; k < temp_attribute_property->properties.size(); k++) { if (equalsIgnoreCase(temp_attribute_property->properties[k]->name, (*data_in)[index].in())) { index++; temp_attribute_property->properties[k]->value.erase(temp_attribute_property->properties[k]->value.begin(), temp_attribute_property->properties[k]->value.begin()+temp_attribute_property->properties[k]->value.size()); sscanf((*data_in)[index],"%6d",&num_vals); index++; for(unsigned int n = 0; n < num_vals; n++) { temp_attribute_property->properties[k]->value.push_back(string((*data_in)[index])); index++; } //(*dev_it)->attribute_properties[j]->properties[k]->value.push_back( string((*data_in)[index]) );index++; if (index >= data_in->length()) { write_file(); return ret; } exist = true; } } if ( !exist ) { t_property* new_prop = new t_property; new_prop->name = (*data_in)[index]; index++; sscanf((*data_in)[index],"%6d",&num_vals); index++; for(unsigned int n = 0; n < num_vals; n++) { new_prop->value.push_back(string((*data_in)[index])); index++; } //makeStringArray( string((*data_in)[index]), new_prop->value);index++; //new_prop->value.push_back( string((*data_in)[index]) );index++; temp_attribute_property->properties.push_back(new_prop); if (index >= data_in->length()) { write_file(); return ret; } } } } } write_file(); return ret; }; CORBA::Any* FileDatabase :: DbDeleteClassAttributeProperty(CORBA::Any&) { CORBA::Any* ret = new CORBA::Any; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbDeleteClassAttributeProperty"); return ret; }; CORBA::Any* FileDatabase :: DbGetDeviceList(CORBA::Any& send) { CORBA::Any* any_ptr = new CORBA::Any(); const Tango::DevVarStringArray* data_in = NULL; Tango::DevVarStringArray* data_out = new DevVarStringArray; cout4 << "FILEDATABASE: entering DbGetDeviceList" << endl; send >>= data_in; if (data_in->length() == 2) { if ( equalsIgnoreCase((*data_in)[0].in(), m_server.name + "/" + m_server.instance_name)) { unsigned int i; for(i = 0; i < m_server.classes.size(); i++) { //if ( strcmp((*data_in)[1], m_server.classes[i]->name.c_str()) == 0 ) if ( equalsIgnoreCase ((*data_in)[1].in(), m_server.classes[i]->name)) { data_out->length(m_server.classes[i]->devices.size()); for (unsigned int j = 0; j < m_server.classes[i]->devices.size(); j++) { (*data_out)[j] = CORBA::string_dup( m_server.classes[i]->devices[j]->name.c_str() ); } break; } } if (i == m_server.classes.size()) { delete any_ptr; delete data_out; TangoSys_MemStream desc; desc << "File database: Can't find class " << (*data_in)[1]; desc << " in file " << filename << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::DbGetDeviceList"); } } else { delete any_ptr; delete data_out; TangoSys_MemStream desc; desc << "File database: Can't find device server " << (*data_in)[0]; desc << " in file " << filename << "." << ends; ApiConnExcept::throw_exception((const char *)API_DatabaseFileError, desc.str(), (const char *)"FileDatabase::DbGetDeviceList"); } } (*any_ptr) <<= data_out; return any_ptr; }; CORBA::Any* FileDatabase :: DbInfo(CORBA::Any&){ CORBA::Any* any_ptr = new CORBA::Any(); Tango::DevVarStringArray* data_out = new DevVarStringArray; data_out->length(13); char temp_str[256]; sprintf(temp_str,"TANGO FileDatabase %s", filename.c_str()); (*data_out)[0] = CORBA::string_dup(temp_str); (*data_out)[1] = CORBA::string_dup(""); (*data_out)[2] = CORBA::string_dup("Running since ----"); (*data_out)[3] = CORBA::string_dup(""); #ifdef TANGO_LONG64 sprintf(temp_str,"Devices defined = %lu", m_server.devices.size()); #else sprintf(temp_str,"Devices defined = %d", m_server.devices.size()); #endif (*data_out)[4] = CORBA::string_dup(temp_str); #ifdef TANGO_LONG64 sprintf(temp_str,"Devices exported = %lu", m_server.devices.size()); #else sprintf(temp_str,"Devices exported = %d", m_server.devices.size()); #endif (*data_out)[5] = CORBA::string_dup(temp_str); (*data_out)[6] = CORBA::string_dup("Device servers defined = 1"); (*data_out)[7] = CORBA::string_dup("Device servers exported = 1"); (*data_out)[8] = CORBA::string_dup(""); long temp_long = 0; for(std::vector::iterator it = m_server.classes.begin(); it != m_server.classes.end(); ++it) temp_long += (*it)->properties.size(); sprintf(temp_str,"Class properties defined = %ld", temp_long); (*data_out)[9] = CORBA::string_dup(temp_str); temp_long = 0; for(std::vector::iterator ite = m_server.devices.begin(); ite != m_server.devices.end(); ++ite) temp_long += (*ite)->properties.size(); sprintf(temp_str,"Device properties defined = %ld", temp_long); (*data_out)[10] = CORBA::string_dup(temp_str); temp_long = 0; for(std::vector::iterator iter = m_server.classes.begin(); iter != m_server.classes.end(); ++iter) temp_long += (*iter)->attribute_properties.size(); sprintf(temp_str,"Class attribute properties defined = %ld", temp_long); (*data_out)[11] = CORBA::string_dup(temp_str); temp_long = 0; for(std::vector::iterator itera = m_server.devices.begin(); itera != m_server.devices.end(); ++itera) temp_long += (*itera)->attribute_properties.size(); sprintf(temp_str,"Device attribute properties defined = %ld", temp_long); (*data_out)[12] = CORBA::string_dup(temp_str); (*any_ptr) <<= data_out; return any_ptr; }; CORBA::Any* FileDatabase :: DbImportDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbImportDevice"); return ret; }; CORBA::Any* FileDatabase :: DbExportDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbExportDevice"); return ret; }; CORBA::Any* FileDatabase :: DbUnExportDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbUnExportDevice"); return ret; }; CORBA::Any* FileDatabase :: DbAddDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbAddDevice"); return ret; }; CORBA::Any* FileDatabase :: DbDeleteDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbDeleteDevice"); return ret; }; CORBA::Any* FileDatabase :: DbAddServer(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbAddServer"); return ret; }; CORBA::Any* FileDatabase :: DbDeleteServer(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbDeleteServer"); return ret; }; CORBA::Any* FileDatabase :: DbExportServer(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbExportServer"); return ret; }; CORBA::Any* FileDatabase :: DbUnExportServer(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbExportDevice"); return ret; }; CORBA::Any* FileDatabase :: DbGetServerInfo(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"Filedatabase::DbGetServerInfo"); return ret; }; CORBA::Any* FileDatabase :: DbGetDeviceMemberList(CORBA::Any&) { CORBA::Any* any_ptr = new CORBA::Any(); Tango::DevVarStringArray* argout = new Tango::DevVarStringArray(); argout->length(1); (*argout)[0] = CORBA::string_dup("NoMember"); (*any_ptr) <<= argout; return any_ptr; }; CORBA::Any* FileDatabase :: DbGetDeviceExportedList(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetDeviceExportedList"); return ret; }; CORBA::Any* FileDatabase :: DbGetDeviceFamilyList(CORBA::Any&) { CORBA::Any* any_ptr = new CORBA::Any(); Tango::DevVarStringArray* argout = new Tango::DevVarStringArray(); argout->length(1); (*argout)[0] = CORBA::string_dup("NoDevice"); (*any_ptr) <<= argout; return any_ptr; }; CORBA::Any* FileDatabase :: DbGetDeviceDomainList(CORBA::Any&) { CORBA::Any* any_ptr = new CORBA::Any(); Tango::DevVarStringArray* argout = new Tango::DevVarStringArray(); argout->length(1); (*argout)[0] = CORBA::string_dup("NoDevice"); (*any_ptr) <<= argout; return any_ptr; }; /** At the moment we have no information about general properties * so I put nothing out */ CORBA::Any* FileDatabase :: DbGetProperty(CORBA::Any& send) { CORBA::Any* any_ptr = new CORBA::Any(); const Tango::DevVarStringArray* data_in = NULL; Tango::DevVarStringArray* data_out = new DevVarStringArray; char num_attr_str[256]; const char* zero_str = "0"; cout4 << "FILEDATABASE: entering DbGetProperty" << endl; send >>= data_in; data_out->length(2); sprintf(num_attr_str,"%ud",data_in->length()-1); (*data_out)[0] = CORBA::string_dup((*data_in)[0]); (*data_out)[1] = CORBA::string_dup(zero_str); (*any_ptr) <<= data_out; return any_ptr; }; CORBA::Any* FileDatabase :: DbPutProperty(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbPutProperty"); return ret; }; CORBA::Any* FileDatabase :: DbDeleteProperty(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbDeleteProperty"); return ret; }; CORBA::Any* FileDatabase :: DbGetAliasDevice(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetAliasDevice"); return ret; }; CORBA::Any* FileDatabase :: DbGetDeviceAlias(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetDeviceAlias"); return ret; }; CORBA::Any* FileDatabase :: DbGetAttributeAlias(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetAttributeAlias"); return ret; }; CORBA::Any* FileDatabase :: DbGetDeviceAliasList(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetDeviceAliasList"); return ret; }; CORBA::Any* FileDatabase :: DbGetAttributeAliasList(CORBA::Any&) { CORBA::Any* ret = NULL; Tango::Except::throw_exception((const char *)API_NotSupported, (const char *)"Call to a Filedatabase not implemented.", (const char *)"DbGetAttributeAliasList"); return ret; }; CORBA::Any* FileDatabase::DbGetClassPipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbGetClassPipeProperty"); return ret; } CORBA::Any* FileDatabase::DbGetDevicePipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbGetDevicePipeProperty"); return ret; } CORBA::Any* FileDatabase::DbDeleteClassPipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbDeleteClassPipeProperty"); return ret; } CORBA::Any* FileDatabase::DbDeleteDevicePipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbDeleteDevicePipeProperty"); return ret; } CORBA::Any* FileDatabase::DbPutClassPipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbPutClassPipeProperty"); return ret; } CORBA::Any* FileDatabase::DbPutDevicePipeProperty(CORBA::Any&) { CORBA::Any* ret = Tango_nullptr; Tango::Except::throw_exception(API_NotSupported,"Call to a Filedatabase not implemented.","DbPutDevicePipeProperty"); return ret; } //----------------------------------------------------------------------------- // // method : FileDatabase::write_event_channel_ior() - // // description : Method to write the event channel ior into the file // // argument : in : ior_string : The event channel IOR // //----------------------------------------------------------------------------- void FileDatabase::write_event_channel_ior(string &ior_string) { // // Do we already have this info in file? // unsigned int i; for(i = 0; i < m_server.classes.size(); i++) { if ( equalsIgnoreCase (NOTIFD_CHANNEL, m_server.classes[i]->name)) { // // Yes, we have it, simply replace the old IOR by the new one (as device name!) // m_server.classes[i]->devices[0]->name = ior_string; break; } } if (i == m_server.classes.size()) { // // Add the pseudo notifd channel class // t_device *ps_dev = new t_device; ps_dev->name = ior_string; t_tango_class *tg_cl = new t_tango_class; tg_cl->devices.push_back(ps_dev); tg_cl->name = NOTIFD_CHANNEL; m_server.classes.push_back(tg_cl); } } } // end of namespace Tango tango-9.2.5a/lib/cpp/client/apiexcept.cpp0000644023471100065110000000706713034744772015247 00000000000000static const char *RcsId = "$Id: apiexcept.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //+============================================================================ // // file : apiexcept.cpp // // description : C++ source code for the NamedDevFailed and // MultiObjDevFailed classes. // These classes are used for exception thrown by the // write_attributes call where you can have one exception // for several devices which failed during the call // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include namespace Tango { NamedDevFailed::NamedDevFailed():idx_in_call(0) { } //+------------------------------------------------------------------------- // // method : NamedDevFailedList::NamedDevFailedList // // description : Constructor for the NamedDevFailedList class. // This exception is constructed from the CORBA // MultiDevFailed exception. Remember that CORBA does not // support inheriting for exceptions. // Within this exception, you find one NamedDevFailed // object for each device which failed and one DevFailed // object to summarize the exception // // argument : in : - corba_ex : The CORBA exception // - dev_name : The device name // - op_name : The API CORBA operation interface where the // exception has been catched // - reason : The summary DevFailed exception reason field // //-------------------------------------------------------------------------- NamedDevFailedList::NamedDevFailedList(const Tango::MultiDevFailed &corba_ex, string dev_name, const char *op_name, const char *reason) { unsigned int i; unsigned long nb_obj_failed = corba_ex.errors.length(); for (i = 0;i < nb_obj_failed;i++) { NamedDevFailed tmp_err(corba_ex.errors[i].err_list, corba_ex.errors[i].name.in(), corba_ex.errors[i].index_in_call); err_list.push_back(tmp_err); } // // Build an exception summary (as string) in the DevFailed part of this // exception. // TangoSys_OMemStream desc; desc << "Failed to execute " << op_name << " on device " << dev_name; desc << ", object(s) "; for (i = 0;i < nb_obj_failed;i++) { desc << corba_ex.errors[i].name; if (i != nb_obj_failed - 1) desc << ", "; } desc << ends; errors.length(1); errors[0].severity = Tango::ERR; errors[0].reason = CORBA::string_dup(reason); errors[0].origin = CORBA::string_dup(op_name); string st = desc.str(); errors[0].desc = CORBA::string_dup(st.c_str()); } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/accessproxy.cpp0000644023471100065110000002066013034744771015621 00000000000000//+====================================================================== // $Source$ // // Project: Tango // // Description: Cpp source code for the AccessProxy class definition . // // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 28853 $ // //-====================================================================== #if HAVE_CONFIG_H #include #endif #include #include #include #ifndef _TG_WINDOWS_ #include #endif namespace Tango { /** * This class is extends TangoApi.DeviceProxy * to manage Tango access device. * - Check if control access is requested. * - Check who is the user and the host. * - Check access for this user, this host and the specified device. * * @author verdier * @Revision */ //=============================================================== /** * Constructor for Access device proxy * * @param devname access device name */ //=============================================================== AccessProxy::AccessProxy(string &devname) : DeviceProxy(devname,false), forced(false) { real_ctor(); } AccessProxy::AccessProxy(const char *devname) : DeviceProxy(devname,false), forced(false) { real_ctor(); } void AccessProxy::real_ctor() { // // Check if forced mode // string super_tango; int ret = get_env_var("SUPER_TANGO",super_tango); if (ret == 0) { transform(super_tango.begin(),super_tango.end(),super_tango.begin(),::tolower); if (super_tango == "true") forced = true; } // // Build device proxy and check if present. // if (forced == false) ping(); set_access_control(ACCESS_WRITE); } //=============================================================== /** * Check access for specified device * * @param devname device name to check access */ //=============================================================== AccessControlType AccessProxy::check_access_control(string &devname) { if (forced) return ACCESS_WRITE; bool multi_ip = true; bool two_tries = false; omni_mutex_lock oml(only_one); while (two_tries == false) { try { // // If not already done, get user name. // I am using the effective UID in order to allow applications using the seteuid(0) system call // to change the effective user id and therefore to take someone else rights // if (user.empty() == true) { #ifndef _TG_WINDOWS_ uid_t user_id = geteuid(); struct passwd pw; struct passwd *pw_ptr; char buffer[__AC_BUFFER_SIZE]; if (getpwuid_r(user_id,&pw,buffer,sizeof(buffer),&pw_ptr) != 0) { cerr << "AccessProxy::check_access_control: Can't get the user UID !" << endl; cerr << "Access right set to ACCESS_READ" << endl; return ACCESS_READ; } if (pw_ptr == NULL) { cerr << "AccessProxy::check_access_control: Can't get the user UID !" << endl; cerr << "Access right set to ACCESS_READ" << endl; return ACCESS_READ; } user = pw.pw_name; transform(user.begin(),user.end(),user.begin(),::tolower); #else BOOL ret; TCHAR buffer[128]; DWORD nb = 128; ret = GetUserName(buffer,&nb); if (ret == 0) { cerr << "AccessProxy::check_access_control: Can't get the user name !" << endl; cerr << "Access right set to ACCESS_READ" << endl; return ACCESS_READ; } user = buffer; transform(user.begin(),user.end(),user.begin(),::tolower); #endif } // // If not already done, get host address // if (host_ips.empty() == true) { ApiUtil *au = ApiUtil::instance(); vector adrs; string at_least_one; try { au->get_ip_from_if(adrs); // // Filter out local address and IP v6 // for (unsigned int nb_adrs = 0;nb_adrs < adrs.size();nb_adrs++) { string &tmp_host = adrs[nb_adrs]; if (nb_adrs == 0) at_least_one = tmp_host; if (tmp_host.find("127.") == 0) {} else if (tmp_host.find(":") != string::npos) {} else host_ips.push_back(tmp_host); } if (host_ips.empty() == true) { host_ips.push_back(at_least_one); } } catch (DevFailed &) { cerr << "AccessProxy::check_access_control: Can't get my IP address !" << endl; cerr << "Access right set to ACCESS_READ" << endl; return ACCESS_READ; } } // // Check for user and host rights on specified device // DeviceData din,dout; DevVarStringArray dvsa; if (multi_ip == true) { dvsa.length(2 + host_ips.size()); dvsa[0] = CORBA::string_dup(user.c_str()); dvsa[1] = CORBA::string_dup(devname.c_str()); for (unsigned int i = 0;i < host_ips.size();i++) dvsa[2 + i] = CORBA::string_dup(host_ips[i].c_str()); din << dvsa; dout = command_inout("GetAccessForMultiIp",din); } else { two_tries = true; dvsa.length(3); dvsa[0] = CORBA::string_dup(user.c_str()); dvsa[1] = CORBA::string_dup(host_ips[0].c_str()); dvsa[2] = CORBA::string_dup(devname.c_str()); din << dvsa; dout = command_inout("GetAccess",din); } string right; dout >> right; if (right == "write") return ACCESS_WRITE; else return ACCESS_READ; } catch (Tango::DevFailed &e) { if (::strcmp(e.errors[0].reason.in(),API_CommandNotFound) == 0) { multi_ip = false; } else if (::strcmp(e.errors[0].reason.in(),API_DeviceNotExported) == 0) { Except::re_throw_exception(e,(const char *)API_CannotCheckAccessControl, (const char *)"Cannot import Access Control device !", (const char *)"AccessProxy::check_access_control()"); } else throw; } } return ACCESS_READ; } //=============================================================== /** * Check for specified device, the specified command is allowed. * * @param classname Specified device class name. * @param cmd Specified command name. */ //=============================================================== bool AccessProxy::is_command_allowed(string &classname,string &cmd) { bool ret = false; // // Try to find allowed commands for device class in map // map >::iterator pos; pos = allowed_cmd_table.find(classname); // // If allowed commands for this class not already in map, get them // vector allowed; if (pos == allowed_cmd_table.end()) get_allowed_commands(classname,allowed); else allowed = pos->second; // // If no cmd allowed returns false // if (allowed.empty() == true) ret = false; // // Else, check is the one passed as argument is allowed // else { for (unsigned int i = 0;i < allowed.size();++i) { if (TG_strcasecmp(allowed[i].c_str(),cmd.c_str()) == 0) { ret = true; break; } } } return ret; } //=============================================================== /** * query access device to know allowed commands for the class */ //=============================================================== void AccessProxy::get_allowed_commands(string &classname,vector &allowed) { try { DeviceData din,dout; din << classname; dout = command_inout("GetAllowedCommands", din); dout >> allowed; } catch (Tango::DevFailed &) { allowed.clear(); } allowed_cmd_table.insert(map >::value_type(classname, allowed)); } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/lockthread.cpp0000644023471100065110000002751513034744772015405 00000000000000static const char *RcsId = "$Id: lockthread.cpp 27410 2015-01-27 05:46:17Z taurel $"; //+================================================================================================================== // // file : LockThread.cpp // // description : C++ source code for the LockThread class. This class is used for the locking thread. The rule of // this thread is to regulary send the device locking command to a DS admin device // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //-================================================================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #ifndef _TG_WINDOWS_ #include #else #include #include #endif namespace Tango { //+------------------------------------------------------------------------------------------------------------------- // // method : // LockThread::LockThread // // description : // The locking thread constructor. // //-------------------------------------------------------------------------------------------------------------------- LockThread::LockThread(LockThCmd &cmd,TangoMonitor &m,DeviceProxy *adm,string &dev,DevLong per): shared_cmd(cmd),p_mon(m),admin_proxy(adm) { LockedDevice ld; ld.dev_name = dev; ld.validity = per; locked_devices.push_back(ld); local_cmd.cmd_pending = false; DevLong tmp_usec = (per * 1000000) - 500000; period = tmp_usec; period_ms = tmp_usec / 1000; sleep = period_ms; } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::run_undetached // // description : // The locking thread main code // //-------------------------------------------------------------------------------------------------------------------- void LockThread::run(TANGO_UNUSED(void *ptr)) { LockCmdType received; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); next_work.tv_sec = (unsigned long)now_win.time; next_work.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&next_work,NULL); #endif T_ADD(next_work,period); // // The infinite loop // while(1) { bool cmd_received; try { if (sleep != 0) received = get_command(sleep); else received = LOCK_TIME_OUT; switch (received) { case LOCK_COMMAND: execute_cmd(); cmd_received = true; break; case LOCK_TIME_OUT: one_more_lock(); cmd_received = false; break; } compute_sleep_time(cmd_received); } catch (omni_thread_fatal &) { cerr << "OUPS !! A omni thread fatal exception !!!!!!!!" << endl; #ifndef _TG_WINDOWS_ time_t t = time(NULL); cerr << ctime(&t); #endif cerr << "Trying to re-enter the main loop" << endl; } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::get_command // // description : // This method wait on the shared monitor for a new command to be sent to the polling thread. The thread waits // with a timeout. If the thread is awaken due to the timeout, false is returned. If the work list is empty, // the thread waits for ever. // // argument : // in : // - tout : The timeout in mS // // returns : // The command type enum: Is it a real command or a time-out // //------------------------------------------------------------------------------------------------------------------- LockCmdType LockThread::get_command(DevLong tout) { omni_mutex_lock sync(p_mon); LockCmdType ret; // // Wait on monitor // if (shared_cmd.cmd_pending == false) { if (locked_devices.empty() == true) p_mon.wait(); else { if (tout != -1) p_mon.wait(tout); } } // // Test if it is a new command. If yes, copy its data locally // if (shared_cmd.cmd_pending == true) { local_cmd = shared_cmd; ret = LOCK_COMMAND; } else ret = LOCK_TIME_OUT; return ret; } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::execute_cmd // // description : // This method is called when a command has been received. It execute the command! // //------------------------------------------------------------------------------------------------------------------- static bool LockThread_pred(LockedDevice lock_dev,string d_name) { return (lock_dev.dev_name == d_name); } void LockThread::execute_cmd() { bool need_exit = false; switch (local_cmd.cmd_code) { // // Add a new device // case Tango::LOCK_ADD_DEV : { LockedDevice ld; ld.dev_name = local_cmd.dev_name; ld.validity = local_cmd.lock_validity; if (locked_devices.empty() == false) { vector::iterator pos; pos = find_if(locked_devices.begin(),locked_devices.end(),bind2nd(ptr_fun(LockThread_pred),local_cmd.dev_name)); if (pos == locked_devices.end()) { locked_devices.push_back(ld); } } else locked_devices.push_back(ld); update_th_period(); break; } // // Remove an already locked device // case Tango::LOCK_REM_DEV : if (locked_devices.empty() == false) { vector::iterator pos; pos = find_if(locked_devices.begin(),locked_devices.end(),bind2nd(ptr_fun(LockThread_pred),local_cmd.dev_name)); if (pos != locked_devices.end()) { locked_devices.erase(pos); } if (locked_devices.empty() == false) update_th_period(); } break; // // Ask locking thread to unlock all its devices and to exit // case Tango::LOCK_UNLOCK_ALL_EXIT : unlock_all_devs(); need_exit = true; break; // // Ask locking thread to exit // case Tango::LOCK_EXIT : need_exit = true; break; } // // Inform requesting thread that the work is done // { omni_mutex_lock sync(p_mon); shared_cmd.cmd_pending = false; if (locked_devices.empty() == true) shared_cmd.suicide = true; p_mon.signal(); } // // If the command was an exit one, do it now // if (need_exit == true) { omni_thread::exit(); } // // If it is the last device, ask thread to exit buut delete the proxy first // if (locked_devices.empty() == true) { omni_thread::exit(); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::one_more_lock // // description : // Send ReLockDevices command to the admin device // //------------------------------------------------------------------------------------------------------------------- void LockThread::one_more_lock() { DeviceData d_in; if (re_lock_cmd_args.empty() == true) { for (unsigned long loop = 0;loop < locked_devices.size();++loop) re_lock_cmd_args.push_back(locked_devices[loop].dev_name); } d_in << re_lock_cmd_args; try { // cout << "Locking Thread: I am re-locking devices (" << re_lock_cmd_args.size() << ")" << endl; admin_proxy->command_inout("ReLockDevices",d_in); } catch (Tango::DevFailed &e) { // cout << "LockThread: Gasp, an exception while sending command to admin device" << endl; // // If we had a locking error, retrieve device name and remove it from the locked devices list // for (unsigned long loop = 0;loop < e.errors.length();loop++) { if ((::strcmp(e.errors[loop].reason.in(),API_DeviceLocked) == 0) || (::strcmp(e.errors[loop].reason.in(),API_DeviceNotLocked) == 0) || (::strcmp(e.errors[loop].reason.in(),API_DeviceNotExported) == 0)) { string error_message(e.errors[loop].desc.in()); string::size_type pos = error_message.find(':'); if (pos != string::npos) { string local_dev_name = error_message.substr(0,pos); vector::iterator ite; for (ite = locked_devices.begin();ite != locked_devices.end();++ite) { if (TG_strcasecmp(local_dev_name.c_str(),ite->dev_name.c_str()) == 0) { locked_devices.erase(ite); if (locked_devices.empty() == true) { local_cmd.cmd_code = LOCK_EXIT; execute_cmd(); } break; } } } } } } } //+------------------------------------------------------------------------------------------------------------------- // // method : // LockThread::unlock_all_devs // // description : // Unlock all devices handled by this thread // //-------------------------------------------------------------------------------------------------------------------- void LockThread::unlock_all_devs() { if (locked_devices.empty() == false) { string cmd("UnLockDevice"); DeviceData din; DevVarLongStringArray sent_data; unsigned int locked_devices_nb = locked_devices.size(); sent_data.svalue.length(locked_devices_nb); for (unsigned int loop = 0;loop < locked_devices_nb;loop++) sent_data.svalue[loop] = CORBA::string_dup(locked_devices[loop].dev_name.c_str()); sent_data.lvalue.length(1); sent_data.lvalue[0] = 1; din << sent_data; try { admin_proxy->command_inout("UnLockDevice",din); } catch (Tango::DevFailed &) {} } } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::update_th_period // // description : // This method manage the thread update period. The update period is the smallest lock validity of all the // locked device minus 0.5 sec // //------------------------------------------------------------------------------------------------------------------- void LockThread::update_th_period() { // // Clear the ReLock command args vector // re_lock_cmd_args.clear(); // // Find the smallest lock validity // vector::iterator ite; ite = min_element(locked_devices.begin(),locked_devices.end()); // // Compute new thread period // DevLong tmp_usec = (ite->validity * 1000000) - 500000; period = tmp_usec; period_ms = tmp_usec / 1000; } //+------------------------------------------------------------------------------------------------------------------ // // method : // LockThread::compute_sleep_time // // description : // This method computes how many mS the thread should sleep before the next lock time. // //-------------------------------------------------------------------------------------------------------------------- void LockThread::compute_sleep_time(bool cmd) { if (cmd == false) { sleep = period_ms; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); next_work.tv_sec = (unsigned long)now_win.time; next_work.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&next_work,NULL); #endif T_ADD(next_work,period); } else { struct timeval now; long diff; #ifdef _TG_WINDOWS_ struct _timeb now_win; _ftime(&now_win); now.tv_sec = (unsigned long)now_win.time; now.tv_usec = (long)now_win.millitm * 1000; #else gettimeofday(&now,NULL); #endif T_DIFF(now,next_work,diff); if (diff < 0) sleep = -1; else sleep = diff / 1000; } } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/event.cpp0000644023471100065110000035144213034744772014405 00000000000000static const char *RcsId = "$Id: event.cpp 30155 2016-09-16 15:31:47Z bourtemb $"; //==================================================================================================================== // // file : event.cpp // // description : C++ classes for implementing the event server and client singleton classes - EventConsumer. // // author(s) : A.Gotz (goetz@esrf.fr) // // original : 7 April 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 30155 $ // // //==================================================================================================================== #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #include #endif using namespace CORBA; namespace Tango { EventConsumerKeepAliveThread *EventConsumer::keep_alive_thread = NULL; map EventConsumer::device_channel_map; map EventConsumer::channel_map; map EventConsumer::event_callback_map; ReadersWritersLock EventConsumer::map_modification_lock; vector EventConsumer::event_not_connected; int EventConsumer::subscribe_event_id = 0; vector EventConsumer::env_var_fqdn_prefix; map EventConsumer::alias_map; KeepAliveThCmd EventConsumer::cmd; //+-------------------------------------------------------------------------------------------------------------------- // // function : // leavefunc // // description : // This function will be executed at process exit or when the main returned. It has to be executed to properly // shutdown and destroy the ORB used by as a server by the event system. The ORB loop is in EventConsumer thread. // Therefore, get a reference to it, shutdown the ORB and wait until the thread exit. It also destroys the // heartbeat filters // //-------------------------------------------------------------------------------------------------------------------- void leavefunc() { // flag to avoid calling leavefunc twice static bool already_executed = false; Tango::ApiUtil *au = ApiUtil::instance(); if (au->need_reset_already_flag() == true) already_executed = false; // // Kill locking threads (if any) // if (already_executed == false) au->clean_locking_threads(); // // Manage event stuff // NotifdEventConsumer *notifd_ec = au->get_notifd_event_consumer(); if (notifd_ec != NULL && already_executed == false) { notifd_ec->shutdown(); // // Shut-down the notifd ORB and wait for the thread to exit // int *rv; notifd_ec->orb_->shutdown(true); notifd_ec->join((void **)&rv); } ZmqEventConsumer *zmq_ec = au->get_zmq_event_consumer(); if (zmq_ec != NULL && already_executed == false) { zmq_ec->shutdown(); } // // Shutdown and destroy the ORB // if (already_executed == false) { if (notifd_ec == NULL) { CORBA::ORB_ptr orb = au->get_orb(); orb->shutdown(true); orb->destroy(); } already_executed = true; au->need_reset_already_flag(false); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::EventConsumer // // description : // Constructor for the EventConsumer class // //-------------------------------------------------------------------------------------------------------------------- EventConsumer::EventConsumer(ApiUtil *api_ptr) { // // Build and store the fqdn prefix for devices in the TANGO_HOST environment variable (in lower case letters) // if (env_var_fqdn_prefix.empty() == true) { try { Database *db = (api_ptr->get_db_vect())[api_ptr->get_db_ind()]; string prefix = "tango://" + db->get_db_host() + ':' + db->get_db_port() + '/' ; env_var_fqdn_prefix.push_back(prefix); if (db->is_multi_tango_host() == true) { vector &tango_hosts = db->get_multi_host(); vector &tango_ports = db->get_multi_port(); for (unsigned int i = 1;i < tango_hosts.size();i++) { string prefix = "tango://" + tango_hosts[i] + ':' + tango_ports[i] + '/' ; env_var_fqdn_prefix.push_back(prefix); } } for (size_t loop = 0;loop < env_var_fqdn_prefix.size();++loop) transform(env_var_fqdn_prefix[loop].begin(),env_var_fqdn_prefix[loop].end(),env_var_fqdn_prefix[loop].begin(),::tolower); // // Also get Db server defined in DB but not in the user TANGO_HOST env. variable // get_cs_tango_host(db); } catch (Tango::DevFailed &) { env_var_fqdn_prefix.push_back(TangoHostNotSet); } } // // initialise the unique event id for the client; // if (keep_alive_thread == NULL) subscribe_event_id = 0; // // Install a function to be executed at exit. This is the only way I found to properly shutdown and destroy the ORB. // Don't do this for windows DLL. // // Is this necessary when events are used within a server ? // #ifndef _USRDLL if ((api_ptr->in_server() == false) && (api_ptr->is_lock_exit_installed() == false)) { atexit(leavefunc); api_ptr->set_sig_handler(); api_ptr->set_lock_exit_installed(true); } #endif // // Miscellaneous init // cmd.cmd_pending = false; if (keep_alive_thread == NULL) api_ptr->need_reset_already_flag(true); thread_id = 0; // // Create and start the EventConsumerKeepAliveThread. Do this at the method's end because the keep_alive_thread // ptr is also used as a "init done" flag. // if (keep_alive_thread == NULL) { keep_alive_thread = new EventConsumerKeepAliveThread(cmd); keep_alive_thread->start(); } } //+-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::get_cs_tango_host() // // description : // Get from a Tango control system which TANGO_HOST are available. This info comes from the Tango CS database // // argument : // in : // - db : Control system database pointer // //-------------------------------------------------------------------------------------------------------------------- void EventConsumer::get_cs_tango_host(Database *db) { try { DeviceData dd; dd = db->command_inout("DbGetCSDbServerList"); vector vs; dd >> vs; // // Do we have a CS with a host alias used as TANGO_HOST? // It true and if we don't know this alias, store its definition in the alias map // if (vs.size() == 1) { string lower_vs(vs[0]); transform(lower_vs.begin(),lower_vs.end(),lower_vs.begin(),::tolower); string::size_type pos = lower_vs.find(':'); if (pos != string::npos) lower_vs.erase(pos); string tg_host(db->get_orig_tango_host()); transform(tg_host.begin(),tg_host.end(),tg_host.begin(),::tolower); if (tg_host.empty() == false && lower_vs != tg_host) { if (alias_map.find(tg_host) == alias_map.end()) { #ifdef INIT_LIST alias_map.insert({lower_vs,tg_host}); #else alias_map.insert(make_pair(lower_vs,tg_host)); #endif } } } // // Serveral Db servers for one TANGO_HOST case // vector::iterator pos; for (unsigned int i = 0;i < vs.size();i++) { transform(vs[i].begin(),vs[i].end(),vs[i].begin(),::tolower); #ifdef HAS_LAMBDA_FUNC pos = find_if(env_var_fqdn_prefix.begin(),env_var_fqdn_prefix.end(), [&] (string str) -> bool { if (str.find(vs[i]) != string::npos) return true; else return false; }); if (pos == env_var_fqdn_prefix.end()) { string prefix = "tango://" + vs[i] + '/' ; env_var_fqdn_prefix.push_back(prefix); } #else unsigned int j; for (j = 0;j < env_var_fqdn_prefix.size();++j) { if (env_var_fqdn_prefix[j].find(vs[i]) != string::npos) { break; } } if (j == env_var_fqdn_prefix.size()) { string prefix = "tango://" + vs[i] + '/'; env_var_fqdn_prefix.push_back(prefix); } #endif } } catch(...) {} } //+-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::shutdown() // // description : // Method to stop the keep alive thread and to disconnect from all used event channels // //-------------------------------------------------------------------------------------------------------------------- void EventConsumer::shutdown() { cout3 << "calling Tango::EventConsumer::shutdown() \n"; // // First, shutdown the keep alive thread // shutdown_keep_alive_thread(); // // cleanup map containers // cleanup_EventChannel_map(); } //+---------------------------------------------------------------------------- // // method : EventConsumer::shutdown_keep_alive_thread() // // description : Ask the KeepAliveThread to suicide and wait for this to // happen // //----------------------------------------------------------------------------- void EventConsumer::shutdown_keep_alive_thread() { // // Shut-down the KeepAliveThread and wait for it to exit // if (keep_alive_thread != NULL) { { omni_mutex_lock sync(cmd); cmd.cmd_pending = true; cmd.cmd_code = EXIT_TH; cmd.cond.signal(); } int *rv; keep_alive_thread->join((void **)&rv); keep_alive_thread = NULL; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::connect() // // description : // This method is a wrapper around the connection to the event channel (heartbeat event) // // argument : // in : // - device_proxy : The device handle // - d_name : The FQDN (lower case) // - dd : The server command result (Used by ZMQ event system only) // - adm_name : The admin device name // - necm : // //------------------------------------------------------------------------------------------------------------------ void EventConsumer::connect(DeviceProxy *device_proxy,string &d_name,DeviceData &dd,string &adm_name,bool &necm) { string channel_name = adm_name; if (device_proxy->get_from_env_var() == true) { channel_name.insert(0,env_var_fqdn_prefix[0]); } // // If no connection exists to this channel then connect to it. Sometimes, this method is called in order to reconnect // to the notifd. In such a case, the lock is already locked before the method is called // std::map::iterator ipos = channel_map.find(channel_name); if (ipos == channel_map.end()) { connect_event_channel(channel_name,device_proxy->get_device_db(),false,dd); } if (device_proxy->get_from_env_var() == true) { adm_name.insert(0,env_var_fqdn_prefix[0]); } // // Init adm device name in channel map entry // if (ipos == channel_map.end()) { channel_map[channel_name].full_adm_name = adm_name; necm = true; } // // Add entry in device_channel_map map // device_channel_map[d_name] = channel_name; } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::attr_to_device() // // description : // Method to initialize in the DeviceAttribute instance given to the user the attribute value which are received // in a AttrValUnion (or in a class inheriting from) // // argument : // in : // - attr_value : // - attr_value_3 : // - vers : // out : // - dev_attr : // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::attr_to_device(const AttributeValue *attr_value, const AttributeValue_3 *attr_value_3, long vers,DeviceAttribute *dev_attr) { const DevVarLongArray *tmp_seq_lo; CORBA::Long *tmp_lo; const DevVarLong64Array *tmp_seq_64; CORBA::LongLong *tmp_64; const DevVarShortArray *tmp_seq_sh; CORBA::Short *tmp_sh; const DevVarDoubleArray *tmp_seq_db; CORBA::Double *tmp_db; const DevVarStringArray *tmp_seq_str; char **tmp_str; const DevVarFloatArray *tmp_seq_fl; CORBA::Float *tmp_fl; const DevVarBooleanArray *tmp_seq_boo; CORBA::Boolean *tmp_boo; const DevVarUShortArray *tmp_seq_ush; CORBA::UShort *tmp_ush; const DevVarCharArray *tmp_seq_uch; CORBA::Octet *tmp_uch; const DevVarULongArray *tmp_seq_ulo; CORBA::ULong *tmp_ulo; const DevVarULong64Array *tmp_seq_u64; CORBA::ULongLong *tmp_ulolo; const DevVarStateArray *tmp_seq_state; Tango::DevState *tmp_state; CORBA::ULong max,len; if (vers == 3) { dev_attr->name = attr_value_3->name; dev_attr->quality = attr_value_3->quality; dev_attr->time = attr_value_3->time; dev_attr->dim_x = attr_value_3->r_dim.dim_x; dev_attr->dim_y = attr_value_3->r_dim.dim_y; dev_attr->set_w_dim_x(attr_value_3->w_dim.dim_x); dev_attr->set_w_dim_y(attr_value_3->w_dim.dim_y); dev_attr->err_list = new DevErrorList(attr_value_3->err_list); } else { dev_attr->name = attr_value->name; dev_attr->quality = attr_value->quality; dev_attr->time = attr_value->time; dev_attr->dim_x = attr_value->dim_x; dev_attr->dim_y = attr_value->dim_y; } if (dev_attr->quality != Tango::ATTR_INVALID) { CORBA::TypeCode_var ty; if (vers == 3) ty = attr_value_3->value.type(); else ty = attr_value->value.type(); if (ty->kind() == tk_enum) { attr_value_3->value >>= dev_attr->d_state; dev_attr->d_state_filled = true; } else { CORBA::TypeCode_var ty_alias = ty->content_type(); CORBA::TypeCode_var ty_seq = ty_alias->content_type(); switch (ty_seq->kind()) { case tk_long: if (vers == 3) attr_value_3->value >>= tmp_seq_lo; else attr_value->value >>= tmp_seq_lo; max = tmp_seq_lo->maximum(); len = tmp_seq_lo->length(); if (tmp_seq_lo->release() == true) { tmp_lo = (const_cast(tmp_seq_lo))->get_buffer((CORBA::Boolean)true); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,true); } else { tmp_lo = const_cast(tmp_seq_lo->get_buffer()); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,false); } break; case tk_longlong: if (vers == 3) attr_value_3->value >>= tmp_seq_64; else attr_value->value >>= tmp_seq_64; max = tmp_seq_64->maximum(); len = tmp_seq_64->length(); if (tmp_seq_64->release() == true) { tmp_64 = (const_cast(tmp_seq_64))->get_buffer((CORBA::Boolean)true); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_64,true); } else { tmp_64 = const_cast(tmp_seq_64->get_buffer()); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_64,false); } break; case tk_short: if (vers == 3) attr_value_3->value >>= tmp_seq_sh; else attr_value->value >>= tmp_seq_sh; max = tmp_seq_sh->maximum(); len = tmp_seq_sh->length(); if (tmp_seq_sh->release() == true) { tmp_sh = (const_cast(tmp_seq_sh))->get_buffer((CORBA::Boolean)true); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); } else { tmp_sh = const_cast(tmp_seq_sh->get_buffer()); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,false); } break; case tk_double: if (vers == 3) attr_value_3->value >>= tmp_seq_db; else attr_value->value >>= tmp_seq_db; max = tmp_seq_db->maximum(); len = tmp_seq_db->length(); if (tmp_seq_db->release() == true) { tmp_db = (const_cast(tmp_seq_db))->get_buffer((CORBA::Boolean)true); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); } else { tmp_db = const_cast(tmp_seq_db->get_buffer()); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,false); } break; case tk_string: if (vers == 3) attr_value_3->value >>= tmp_seq_str; else attr_value->value >>= tmp_seq_str; max = tmp_seq_str->maximum(); len = tmp_seq_str->length(); if (tmp_seq_str->release() == true) { tmp_str = (const_cast(tmp_seq_str))->get_buffer((CORBA::Boolean)true); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,true); } else { tmp_str = const_cast(tmp_seq_str->get_buffer()); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,false); } break; case tk_float: if (vers == 3) attr_value_3->value >>= tmp_seq_fl; else attr_value->value >>= tmp_seq_fl; max = tmp_seq_fl->maximum(); len = tmp_seq_fl->length(); if (tmp_seq_fl->release() == true) { tmp_fl = (const_cast(tmp_seq_fl))->get_buffer((CORBA::Boolean)true); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); } else { tmp_fl = const_cast(tmp_seq_fl->get_buffer()); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,false); } break; case tk_boolean: if (vers == 3) attr_value_3->value >>= tmp_seq_boo; else attr_value->value >>= tmp_seq_boo; max = tmp_seq_boo->maximum(); len = tmp_seq_boo->length(); if (tmp_seq_boo->release() == true) { tmp_boo = (const_cast(tmp_seq_boo))->get_buffer((CORBA::Boolean)true); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); } else { tmp_boo = const_cast(tmp_seq_boo->get_buffer()); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,false); } break; case tk_ushort: if (vers == 3) attr_value_3->value >>= tmp_seq_ush; else attr_value->value >>= tmp_seq_ush; max = tmp_seq_ush->maximum(); len = tmp_seq_ush->length(); if (tmp_seq_ush->release() == true) { tmp_ush = (const_cast(tmp_seq_ush))->get_buffer((CORBA::Boolean)true); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); } else { tmp_ush = const_cast(tmp_seq_ush->get_buffer()); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,false); } break; case tk_octet: if (vers == 3) attr_value_3->value >>= tmp_seq_uch; else attr_value->value >>= tmp_seq_uch; max = tmp_seq_uch->maximum(); len = tmp_seq_uch->length(); if (tmp_seq_uch->release() == true) { tmp_uch = (const_cast(tmp_seq_uch))->get_buffer((CORBA::Boolean)true); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); } else { tmp_uch = const_cast(tmp_seq_uch->get_buffer()); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,false); } break; case tk_ulong: if (vers == 3) attr_value_3->value >>= tmp_seq_ulo; else attr_value->value >>= tmp_seq_ulo; max = tmp_seq_ulo->maximum(); len = tmp_seq_ulo->length(); if (tmp_seq_ulo->release() == true) { tmp_ulo = (const_cast(tmp_seq_ulo))->get_buffer((CORBA::Boolean)true); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); } else { tmp_ulo = const_cast(tmp_seq_ulo->get_buffer()); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,false); } break; case tk_ulonglong: if (vers == 3) attr_value_3->value >>= tmp_seq_u64; else attr_value->value >>= tmp_seq_u64; max = tmp_seq_u64->maximum(); len = tmp_seq_u64->length(); if (tmp_seq_u64->release() == true) { tmp_ulolo = (const_cast(tmp_seq_u64))->get_buffer((CORBA::Boolean)true); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); } else { tmp_ulolo = const_cast(tmp_seq_u64->get_buffer()); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,false); } break; case tk_enum: if (vers == 3) attr_value_3->value >>= tmp_seq_state; else attr_value->value >>= tmp_seq_state; max = tmp_seq_state->maximum(); len = tmp_seq_state->length(); if (tmp_seq_state->release() == true) { tmp_state = (const_cast(tmp_seq_state))->get_buffer((CORBA::Boolean)true); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,true); } else { tmp_state = const_cast(tmp_seq_state->get_buffer()); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,false); } break; default: break; } } } } void EventConsumer::attr_to_device(const AttributeValue_4 *attr_value_4,DeviceAttribute *dev_attr) { dev_attr->name = attr_value_4->name; dev_attr->quality = attr_value_4->quality; dev_attr->time = attr_value_4->time; dev_attr->dim_x = attr_value_4->r_dim.dim_x; dev_attr->dim_y = attr_value_4->r_dim.dim_y; dev_attr->set_w_dim_x(attr_value_4->w_dim.dim_x); dev_attr->set_w_dim_y(attr_value_4->w_dim.dim_y); dev_attr->err_list = new DevErrorList(attr_value_4->err_list); if (dev_attr->quality != Tango::ATTR_INVALID) { att_union_to_device(&attr_value_4->value,dev_attr); } } void EventConsumer::attr_to_device(const ZmqAttributeValue_4 *attr_value_4,DeviceAttribute *dev_attr) { base_attr_to_device(attr_value_4,dev_attr); // // Warning: Since Tango 9, data type SHORT is used for both short attribute and enumeration attribute! // Therefore, we need to store somewhere which exact type it is. With IDL 5, it is easy, because the data type is // transferred on the network (modified IDL), For previous release, we do not have enumerated data type and therefore // the data type could be used only for SHORT. // dev_attr->data_type = Tango::DEV_SHORT; } void EventConsumer::attr_to_device(const ZmqAttributeValue_5 *attr_value_5,DeviceAttribute *dev_attr) { base_attr_to_device(attr_value_5,dev_attr); dev_attr->data_type = attr_value_5->data_type; } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::att_union_to_device() // // description : // Method to initialize in the DeviceAttribute instance given to the user the attribute value which are received // in a AttrValUnion (or in a class inheriting from) // // argument : // in : // - union_ptr : Pointer to the received union // out : // - dev_attr : Pointer to the DeviceAttribute which will be given to the user // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::att_union_to_device(const AttrValUnion *union_ptr,DeviceAttribute *dev_attr) { CORBA::Long *tmp_lo; CORBA::Short *tmp_sh; CORBA::Double *tmp_db; char **tmp_str; CORBA::Float *tmp_fl; CORBA::Boolean *tmp_boo; CORBA::UShort *tmp_ush; CORBA::Octet *tmp_uch; CORBA::LongLong *tmp_lolo; CORBA::ULong *tmp_ulo; CORBA::ULongLong *tmp_ulolo; Tango::DevState *tmp_state; Tango::DevState sta_dev; Tango::DevEncoded *tmp_enc; CORBA::ULong max,len; switch (union_ptr->_d()) { case ATT_BOOL: { const DevVarBooleanArray &tmp_seq = union_ptr->bool_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_boo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,true); } else { tmp_boo = const_cast(tmp_seq.get_buffer()); dev_attr->BooleanSeq = new DevVarBooleanArray(max,len,tmp_boo,false); } } break; case ATT_SHORT: { const DevVarShortArray &tmp_seq = union_ptr->short_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_sh = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,true); } else { tmp_sh = const_cast(tmp_seq.get_buffer()); dev_attr->ShortSeq = new DevVarShortArray(max,len,tmp_sh,false); } } break; case ATT_LONG: { const DevVarLongArray &tmp_seq = union_ptr->long_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_lo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,true); } else { tmp_lo = const_cast(tmp_seq.get_buffer()); dev_attr->LongSeq = new DevVarLongArray(max,len,tmp_lo,false); } } break; case ATT_LONG64: { const DevVarLong64Array &tmp_seq = union_ptr->long64_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_lolo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,true); } else { tmp_lolo = const_cast(tmp_seq.get_buffer()); dev_attr->Long64Seq = new DevVarLong64Array(max,len,tmp_lolo,false); } } break; case ATT_FLOAT: { const DevVarFloatArray &tmp_seq = union_ptr->float_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_fl = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,true); } else { tmp_fl = const_cast(tmp_seq.get_buffer()); dev_attr->FloatSeq = new DevVarFloatArray(max,len,tmp_fl,false); } } break; case ATT_DOUBLE: { const DevVarDoubleArray &tmp_seq = union_ptr->double_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_db = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,true); } else { tmp_db = const_cast(tmp_seq.get_buffer()); dev_attr->DoubleSeq = new DevVarDoubleArray(max,len,tmp_db,false); } } break; case ATT_UCHAR: { const DevVarCharArray &tmp_seq = union_ptr->uchar_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_uch = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,true); } else { tmp_uch = const_cast(tmp_seq.get_buffer()); dev_attr->UCharSeq = new DevVarCharArray(max,len,tmp_uch,false); } } break; case ATT_USHORT: { const DevVarUShortArray &tmp_seq = union_ptr->ushort_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ush = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,true); } else { tmp_ush = const_cast(tmp_seq.get_buffer()); dev_attr->UShortSeq = new DevVarUShortArray(max,len,tmp_ush,false); } } break; case ATT_ULONG: { const DevVarULongArray &tmp_seq = union_ptr->ulong_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ulo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,true); } else { tmp_ulo = const_cast(tmp_seq.get_buffer()); dev_attr->ULongSeq = new DevVarULongArray(max,len,tmp_ulo,false); } } break; case ATT_ULONG64: { const DevVarULong64Array &tmp_seq = union_ptr->ulong64_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_ulolo = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,true); } else { tmp_ulolo = const_cast(tmp_seq.get_buffer()); dev_attr->ULong64Seq = new DevVarULong64Array(max,len,tmp_ulolo,false); } } break; case ATT_STRING: { const DevVarStringArray &tmp_seq = union_ptr->string_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_str = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,true); } else { tmp_str = const_cast(tmp_seq.get_buffer()); dev_attr->StringSeq = new DevVarStringArray(max,len,tmp_str,false); } } break; case ATT_STATE: { const DevVarStateArray &tmp_seq = union_ptr->state_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_state = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,true); } else { tmp_state = const_cast(tmp_seq.get_buffer()); dev_attr->StateSeq = new DevVarStateArray(max,len,tmp_state,false); } } break; case DEVICE_STATE: sta_dev = union_ptr->dev_state_att(); dev_attr->d_state_filled = true; dev_attr->d_state = sta_dev; break; case ATT_NO_DATA: break; case ATT_ENCODED: { const DevVarEncodedArray &tmp_seq = union_ptr->encoded_att_value(); max = tmp_seq.maximum(); len = tmp_seq.length(); if (tmp_seq.release() == true) { tmp_enc = (const_cast(tmp_seq)).get_buffer((CORBA::Boolean)true); dev_attr->EncodedSeq = new DevVarEncodedArray(max,len,tmp_enc,true); } else { tmp_enc = const_cast(tmp_seq.get_buffer()); dev_attr->EncodedSeq = new DevVarEncodedArray(max,len,tmp_enc,false); } } break; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::subscribe_event() // // description : // Method to subscribe to an event with the callback mechanism. Can be called in a stateless way, that it even // works when the attribute is not available. // // argument : // in : // - device : The device handle // - attribute : The name of the attribute // - event : The type of event to subscribe for // - callback : A pointer to the callback object // - filters : Eventual event filter strings // - stateless : Flag to enable the stateless connection when set to true // //------------------------------------------------------------------------------------------------------------------- int EventConsumer::subscribe_event (DeviceProxy *device, const string &attribute, EventType event, CallBack *callback, const vector &filters, bool stateless) { if ((device == NULL) || (callback == NULL)) { EventSystemExcept::throw_exception(API_InvalidArgs, "Device or callback pointer NULL","EventConsumer::subscribe_event()"); } return (subscribe_event (device, attribute, event, callback, NULL, filters, stateless)); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::subscribe_event() // // description : // Method to subscribe to an event with the event_queue mechanism. Can be called in a stateless way, that it even // works when the attribute is not available. // // argument : // in : // - device : The device handle // - attribute : The name of the attribute // - event : The type of event to subscribe for // - event_queue_size: The size of the circular buffer for incoming events // - filters : Eventual event filter strings // - stateless : Flag to enable the stateless connection when set to true // //------------------------------------------------------------------------------------------------------------------- int EventConsumer::subscribe_event (DeviceProxy *device, const string &attribute, EventType event, int event_queue_size, const vector &filters, bool stateless) { if ((device == NULL) || (event_queue_size < 0)) { EventSystemExcept::throw_exception(API_InvalidArgs, "Device pointer is NULL or the event queue size is invalid", "EventConsumer::subscribe_event()"); } // create an event queue object EventQueue *ev_queue = new EventQueue(event_queue_size); return (subscribe_event (device, attribute, event, NULL, ev_queue, filters, stateless)); } //+------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::subscribe_event() // // description : // // argument : // in : // - device : Pointer to the DeviceProxy instance // - attribute : The attribute name // - event : The event type // - callback : Pointer to the callback object // - ev_queue : Pointer to the eveent queue // - filters : Event filter (unused starting with Tango 8) // - stateless : Stateless subsription flag // //-------------------------------------------------------------------------------------------------------------------- int EventConsumer::subscribe_event (DeviceProxy *device, const string &attribute, EventType event, CallBack *callback, EventQueue *ev_queue, const vector &filters, bool stateless) { string event_name; if (event == QUALITY_EVENT) { EventSystemExcept::throw_exception(API_InvalidArgs, "The quality change event does not exist any more. A change event is fired on a quality change!", "EventConsumer::subscribe_event()"); } else event_name = EventName[event]; // // Following code is for the case of event subscription in one event callback // In such a case, we have to do the subscription in a thread otherwise we have a deadlock due to the // event consumer thread which can not at the same time execute the call back and register the new event // if (thread_id != 0) { omni_thread::ensure_self se; if (omni_thread::self()->id() == thread_id) { if (stateless == false) { EventSystemExcept::throw_exception(API_InvalidArgs, "When subscribing to event within a event callback, only stateless subscription is allowed", "EventConsumer::subscribe_event()"); } subscribe_event_id++; int ret_event_id = subscribe_event_id; DelayedEventSubThread *th = new DelayedEventSubThread(this,device,attribute,event,callback,ev_queue,stateless,event_name,ret_event_id); th->start(); return ret_event_id; } } // // Take a writer lock right now and not in the connect_event method. In case of stateless subscription and if the // device is not there, the lock will still be valid when the data will be inserted into the vector of non-connected // events. Also ask the main ZMQ thread to delay all incoming event until this method exit. // A dead lock could happen if we don't do this (really experienced!) // DelayEvent de(this); WriterLock w(map_modification_lock); try { int event_id = connect_event (device,attribute,event,callback,ev_queue,filters,event_name); return event_id; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); // if the stateless flag is not true, rethrow the exception if ((stateless == false) || (reason == API_CommandNotFound)) { throw; } // when the subscribe event has not worked, store the connection data in a vector of not // yet connected events. // Retry to connect in the next heartbeat period. EventNotConnected conn_params; conn_params.device = device; conn_params.attribute = attribute; conn_params.event_type = event; conn_params.event_name = event_name; conn_params.callback = callback; conn_params.ev_queue = ev_queue; conn_params.filters = filters; conn_params.last_heartbeat = time(NULL); if (env_var_fqdn_prefix.empty() == false) conn_params.prefix = env_var_fqdn_prefix[0]; // protect the vector as the other maps! // create and save the unique event ID subscribe_event_id++; conn_params.event_id = subscribe_event_id; event_not_connected.push_back (conn_params); vector::iterator vpos = event_not_connected.end() - 1; time_t now = time(NULL); keep_alive_thread->stateless_subscription_failed(vpos,e,now); return subscribe_event_id; } } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::subscribe_event() // // description : // Method to subscribe to an event with the callback mechanism. Can be called in a stateless way, that it even // works when the attribute is not available. // // argument : // in : // - device : The device handle // - event : The type of event to subscribe for // - callback : A pointer to the callback object // - stateless : Flag to enable the stateless connection when set to true // //------------------------------------------------------------------------------------------------------------------- int EventConsumer::subscribe_event (DeviceProxy *device, EventType event, CallBack *callback, bool stateless) { if ((device == NULL) || (callback == NULL) || (event != INTERFACE_CHANGE_EVENT)) { EventSystemExcept::throw_exception(API_InvalidArgs, "Device,callback pointer NULL or unsupported event type","EventConsumer::subscribe_event()"); } vector filters; return (subscribe_event(device,"dummy",event,callback,NULL,filters,stateless)); } int EventConsumer::subscribe_event (DeviceProxy *device, EventType event, int event_queue_size, bool stateless) { if ((device == NULL) || (event != INTERFACE_CHANGE_EVENT)) { EventSystemExcept::throw_exception(API_InvalidArgs, "Device NULL or unsupported event type","EventConsumer::subscribe_event()"); } vector filters; // create an event queue object EventQueue *ev_queue = new EventQueue(event_queue_size); return (subscribe_event(device,"dummy",event,NULL,ev_queue,filters,stateless)); } //+------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::connect_event() // // description : // Main nethod called by the subsccribe_event call // // argument : // in : // - device : The device handle // - obj_name : The attribute or pipe name // - event : The type of event to subscribe for // - callback : A pointer to the callback object // - ev_queue : A pointer to the event queue // - filters : Eventual event filter strings // - event_name : The event name // - event_id : the unique event ID // //-------------------------------------------------------------------------------------------------------------------- int EventConsumer::connect_event(DeviceProxy *device, const string &obj_name, EventType event, CallBack *callback, EventQueue *ev_queue, const vector &filters, string &event_name, int event_id) { int ret_event_id = event_id; device_name = device->dev_name(); cout3 << "Tango::EventConsumer::connect_event(" << device_name << "," << obj_name <<"," << event << ")\n"; bool inter_event = false; if (event == INTERFACE_CHANGE_EVENT) inter_event = true; bool pipe_event = false; if (event == PIPE_EVENT) pipe_event = true; // // Build callback map key and local device name from fqdn // string local_device_name(device_name); if (device->get_from_env_var() == false) { string prot("tango://"); if (device->is_dbase_used() == false) { string &ho = device->get_dev_host(); if (ho.find('.') == string::npos) Connection::get_fqdn(ho); prot = prot + ho + ':' + device->get_dev_port() + '/'; } else prot = prot + device->get_db_host() + ':' + device->get_db_port() + '/'; device_name.insert(0,prot); if (device->is_dbase_used() == false) device_name = device_name + MODIFIER_DBASE_NO; } else { device_name.insert(0,env_var_fqdn_prefix[0]); } transform(device_name.begin(),device_name.end(),device_name.begin(),::tolower); obj_name_lower = obj_name; transform(obj_name_lower.begin(),obj_name_lower.end(),obj_name_lower.begin(),::tolower); string local_callback_key(device_name); string::size_type pos; if ((pos = local_callback_key.find('#')) == string::npos) { if (inter_event == true) local_callback_key = local_callback_key + "." + event_name; else local_callback_key = local_callback_key + "/" +obj_name_lower + "." + event_name; } else { local_callback_key.erase(pos); if (inter_event == true) local_callback_key = local_callback_key + MODIFIER_DBASE_NO + '.' + event_name; else local_callback_key = local_callback_key + "/" + obj_name_lower + MODIFIER_DBASE_NO + '.' + event_name; } // // Do we have to support event compatibility ? // bool add_compat_info = false; if (event == ATTR_CONF_EVENT || event == CHANGE_EVENT || event == PERIODIC_EVENT || event == ARCHIVE_EVENT || event == USER_EVENT) add_compat_info = true; // // Do we already have this event in the callback map? If yes, simply add this new callback to the event callback list // If it's a ATTR_CONF_EVENT, don't forget to look for the two different event kinds // EvCbIte iter = event_callback_map.find(local_callback_key); if (iter == event_callback_map.end() && add_compat_info == true) { for (int i = 0;i < ATT_CONF_REL_NB;i++) { string mod_local_callback_key(local_callback_key); string::size_type pos = mod_local_callback_key.rfind('.'); mod_local_callback_key.insert(pos + 1,EVENT_COMPAT_IDL5); iter = event_callback_map.find(mod_local_callback_key); if (iter != event_callback_map.end()) break; } } if (iter != event_callback_map.end()) { int new_event_id = add_new_callback(iter,callback,ev_queue,event_id); get_fire_sync_event(device,callback,ev_queue,event,event_name,obj_name,iter->second,local_callback_key); return new_event_id; } // // Inform server that we want to subscribe (we cannot use the asynchronous fire-and-forget // request so as not to block the client because it does not reconnect if the device is down !) // To do this, we need to build DS adm device proxy. If it is not the first call for this // DS, we should find it in map. Otherwise, get it. // DeviceData subscriber_in; vector subscriber_info; subscriber_info.push_back(local_device_name); subscriber_info.push_back(obj_name_lower); subscriber_info.push_back("subscribe"); subscriber_info.push_back(event_name); DeviceProxy *adm_dev = NULL; bool allocated = false; map::iterator ipos = device_channel_map.find(device_name); EvChanIte evt_it = channel_map.end(); string adm_name; if (ipos == device_channel_map.end()) { try { adm_name = device->adm_name(); adm_dev = new DeviceProxy(adm_name); allocated = true; } catch(...) { TangoSys_OMemStream o; o << "Can't subscribe to event for device " << device_name << "\n"; o << "Check that device server is running..." << ends; Except::throw_exception(API_CantConnectToDevice,o.str(),"EventConsumer::connect_event()"); } } else { evt_it = channel_map.find(ipos->second); if (evt_it == channel_map.end()) { TangoSys_OMemStream o; o << "Can't subscribe to event for device " << device_name << "\n"; o << "Corrupted internal map. Please report bug" << ends; Except::throw_exception(API_BadConfigurationProperty,o.str(),"EventConsumer::connect_event()"); } const EventChannelStruct &evt_ch = evt_it->second; { AutoTangoMonitor _mon(evt_ch.channel_monitor); adm_dev = evt_ch.adm_device_proxy; } } Tango::DeviceData dd; bool zmq_used = false; try { string cmd_name; get_subscription_command_name(cmd_name); if (cmd_name.find("Zmq") != string::npos) { zmq_used = true; stringstream ss; ss << DevVersion; subscriber_info.push_back(ss.str()); } subscriber_in << subscriber_info; dd = adm_dev->command_inout(cmd_name,subscriber_in); dd.reset_exceptions(DeviceData::isempty_flag); // // DS before Tango 7.1 does not send their Tango_host in the event // Refuse to subscribe to an event from a DS before Tango 7.1 if the device is in another CS than the one defined by // the TANGO_HOST env. variable // if (dd.is_empty() == true) { if (device->get_from_env_var() == false) { string::size_type pos = device_name.find("://"); pos = pos + 3; pos = device_name.find('/',pos); string fqdn_prefix = device_name.substr(0,pos + 1); transform(fqdn_prefix.begin(),fqdn_prefix.end(),fqdn_prefix.begin(),::tolower); if (fqdn_prefix != env_var_fqdn_prefix[0]) { TangoSys_OMemStream o; o << "Device server for device " << device_name; o << " is too old to generate event in a multi TANGO_HOST environment. Please, use Tango >= 7.1" << ends; EventSystemExcept::throw_exception(API_DSFailedRegisteringEvent,o.str(), "EventConsumer::connect_event()"); } } } } catch (Tango::DevFailed &e) { if (allocated == true) delete adm_dev; string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) throw; else EventSystemExcept::re_throw_exception(e,API_DSFailedRegisteringEvent, "Device server send exception while trying to register event", "EventConsumer::connect_event()"); } // // Some Zmq specific code (Check release compatibility,....) // zmq_specific(dd,adm_name,device,obj_name); // if (allocated == true) // delete adm_dev; // // Change event name if it is IDL 5 compatible: // This code is Tango 9 or more. If the remote device is IDL 5 (or more), insert tango IDL release number // at the beginning of event name. // const DevVarLongStringArray *dvlsa; bool dd_extract_ok = true; if ((dd >> dvlsa) == false) dd_extract_ok = false; if (dd_extract_ok == true && add_compat_info == true && dvlsa->lvalue[1] >= MIN_IDL_CONF5) { event_name = EVENT_COMPAT_IDL5 + event_name; string::size_type pos = local_callback_key.rfind('.'); local_callback_key.insert(pos + 1,EVENT_COMPAT_IDL5); } // // Search (or create) entry for channel map // int valid_endpoint_nb = 0; if (ipos == device_channel_map.end()) { cout3 << "device " << device_name << " is not connected, going to connect to the event channel !\n"; bool new_entry_in_channel_map = false; try { connect(device,device_name,dd,adm_name,new_entry_in_channel_map); } catch (Tango::DevFailed &e) { if (allocated == true) delete adm_dev; throw; } ipos = device_channel_map.find(device_name); if (ipos == device_channel_map.end()) { if (allocated == true) delete adm_dev; TangoSys_OMemStream o; o << "Failed to connect to event channel for device " << device_name << ends; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, o.str(), (const char*)"EventConsumer::connect_event()"); } if (evt_it == channel_map.end()) { evt_it = channel_map.find(ipos->second); evt_it->second.last_subscribed = time(NULL); valid_endpoint_nb = evt_it->second.valid_endpoint; if (new_entry_in_channel_map == true) { AutoTangoMonitor _mon(evt_it->second.channel_monitor); evt_it->second.adm_device_proxy = adm_dev; } else delete adm_dev; } } else { evt_it = channel_map.find(ipos->second); valid_endpoint_nb = evt_it->second.valid_endpoint; } // // Init device proxy in channel event map // /* { AutoTangoMonitor _mon(evt_it->second.channel_monitor); evt_it->second.adm_device_proxy = adm_dev; }*/ // // Now, connect to the event system // EventCallBackStruct new_event_callback; EventSubscribeStruct new_ess; new_event_callback.device = device; new_event_callback.obj_name = obj_name_lower; new_event_callback.event_name = event_name; new_event_callback.channel_name = evt_it->first; new_event_callback.alias_used = false; if (inter_event == true) new_event_callback.fully_qualified_event_name = device_name + '.' + event_name; else new_event_callback.fully_qualified_event_name = device_name + '/' + obj_name_lower + '.' + event_name; if (dd_extract_ok == false) new_event_callback.device_idl = 0; else { if (dvlsa->lvalue.length() >= 2) new_event_callback.device_idl = dvlsa->lvalue[1]; else new_event_callback.device_idl = 0; } new_event_callback.ctr = 0; new_event_callback.discarded_event = false; if (zmq_used == true) new_event_callback.endpoint = dvlsa->svalue[(valid_endpoint_nb << 1) + 1].in(); new_ess.callback = callback; new_ess.ev_queue = ev_queue; connect_event_system(device_name,obj_name_lower,event_name,filters,evt_it,new_event_callback,dd,valid_endpoint_nb); // // Check if this subscription is for a fwd attribute root attribute (when relevant) // new_event_callback.fwd_att = false; if (inter_event == false && pipe_event == false) { ApiUtil *au = ApiUtil::instance(); if (au->in_server() == true) { RootAttRegistry &rar = Util::instance()->get_root_att_reg(); string root_att_name = device_name; root_att_name = root_att_name + '/' + obj_name_lower; if (rar.is_root_attribute(root_att_name) == true) new_event_callback.fwd_att = true; } else new_event_callback.fwd_att = false; } else new_event_callback.fwd_att = false; // // if an event ID was passed to the method, reuse it! // if (ret_event_id <= 0) { subscribe_event_id++; ret_event_id = subscribe_event_id; } new_ess.id = ret_event_id; new_event_callback.callback_list.push_back(new_ess); // // Create a callback monitor and set its timeout to 1000ms not to block the event consumer for too long. // new_event_callback.callback_monitor = new TangoMonitor(); new_event_callback.callback_monitor->timeout(1000); // // If we have a CS for which TANGO_HOST is one alias (host name in alias map), set flag in map // pos = local_callback_key.find(':',6); string tg_host = local_callback_key.substr(8,pos - 8); map::iterator ite = alias_map.find(tg_host); if (ite != alias_map.end()) { new_event_callback.alias_used = true; } // // Insert new entry in map // pair ret = event_callback_map.insert(pair(local_callback_key, new_event_callback)); if (!ret.second) { TangoSys_OMemStream o; o << "Failed to connect to event channel for device " << device_name << "\nCorrupted internal map: event callback already exists. Please report bug!" << ends; EventSystemExcept::throw_exception(API_NotificationServiceFailed, o.str(), "EventConsumer::connect_event()"); } iter = ret.first; // // Read the attribute/pipe by a simple synchronous call.This is necessary for the first point in "change" mode // Force callback execution when it is done // get_fire_sync_event(device,callback,ev_queue,event,event_name,obj_name,iter->second,local_callback_key); // // Sleep for some mS (20) in order to give to ZMQ some times to propagate the subscription to the publisher // #ifndef _TG_WINDOWS_ struct timespec ts; ts.tv_nsec = 20000000; ts.tv_sec = 0; nanosleep(&ts,NULL); #else Sleep(20); #endif return ret_event_id; } //+------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::unsubscribe_event() // // description : // Method to unsubscribe from an event // // argument : // in : // - event_id : The event identifier // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::unsubscribe_event(int event_id) { if (event_id == 0) { EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::unsubscribe_event()"); } std::map::iterator epos; std::vector::iterator esspos; // // First, we need to check if the unsubscribe is not done within a callback // Do not take a WriterLock because the push_structured_event method already holds a Reader lock // In such a case, the real unsubscribe will be done later via a thread // { ReaderLock r(map_modification_lock); for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // // If the unsubscribe is done while the callback is being executed, mark the callback as unusable (event_id < 0) // and start a thread which will do the unsubscribe when the callback execution will be finished // if (thread_id != 0) { omni_thread::ensure_self se; if (omni_thread::self()->id() == thread_id) { // cout << event_id << ": Unsubscribing for an event while it is in its callback !!!!!!!!!!" << endl; esspos->id = -event_id; DelayedEventUnsubThread *th = new DelayedEventUnsubThread(this,event_id,epos->second.callback_monitor); th->start(); return; } } } } } } // // Ask the main ZMQ thread to delay all incoming event until this method exit. A dead lock could happen if we don't // do this (really experienced!) // DelayEvent de(this); WriterLock w(map_modification_lock); // // First remove the callback entry from the callback map // for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // // delete the event queue when used // delete esspos->ev_queue; // // Remove callback entry in vector // evt_cb.callback_list.erase(esspos); // // If the callback list is empty // if (evt_cb.callback_list.empty() == true) { EvChanIte evt_it = channel_map.find(evt_cb.channel_name); EventChannelStruct &evt_ch = evt_it->second; if (evt_ch.channel_type == NOTIFD) { try { CosNotifyFilter::Filter_var f = evt_ch.structuredProxyPushSupplier->get_filter(evt_cb.filter_id); evt_ch.structuredProxyPushSupplier->remove_filter(evt_cb.filter_id); f->destroy(); } catch (...) { EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, caught exception while calling remove_filter() or destroy() (hint: check the Notification daemon is running ", (const char*)"EventConsumer::unsubscribe_event()"); } } else { disconnect_event(evt_cb.fully_qualified_event_name,evt_cb.endpoint); } // delete the allocated callback monitor delete epos->second.callback_monitor; string deleted_channel_name = epos->second.channel_name; string deleted_event_endpoint = evt_cb.endpoint; event_callback_map.erase(epos); // // Check if there is another callback using the same channel // std::map::iterator cb_pos; bool channel_used_elsewhere = false; for (cb_pos = event_callback_map.begin(); cb_pos != event_callback_map.end(); ++cb_pos) { if (cb_pos->second.channel_name == deleted_channel_name) { channel_used_elsewhere = true; break; } } // // This channel is not used anymore in the app, remove its entry in the channel maps // if (channel_used_elsewhere == false) { std::map::iterator chan_pos; for (chan_pos = channel_map.begin(); chan_pos != channel_map.end(); ++chan_pos) { EventChannelStruct &evt_ch = chan_pos->second; if (chan_pos->first == deleted_channel_name) { if (evt_ch.adm_device_proxy != NULL) { if (evt_ch.channel_type == NOTIFD) { try { CosNotifyFilter::Filter_var f = evt_ch.structuredProxyPushSupplier->get_filter(evt_ch.heartbeat_filter_id); evt_ch.structuredProxyPushSupplier->remove_filter(evt_ch.heartbeat_filter_id); f->destroy(); try { omniORB::setClientCallTimeout(evt_ch.structuredProxyPushSupplier,1000); evt_ch.structuredProxyPushSupplier->disconnect_structured_push_supplier(); } catch(CORBA::TRANSIENT &c_t) { if (c_t.minor() != omni::TRANSIENT_CallTimedout) throw; } } catch (...) { EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, caught exception while calling remove_filter() or destroy() on the heartbeat filter (hint: check the Notification daemon is running ", (const char*)"EventConsumer::unsubscribe_event()"); } } else { disconnect_event_channel(deleted_channel_name,evt_ch.endpoint,deleted_event_endpoint); } delete evt_ch.adm_device_proxy; delete evt_ch.channel_monitor; } channel_map.erase(chan_pos); break; } } std::map::iterator dev_pos,dev_pos_del; for (dev_pos = device_channel_map.begin(); dev_pos != device_channel_map.end();) { if (dev_pos->second == deleted_channel_name) { dev_pos_del = dev_pos; ++dev_pos; device_channel_map.erase(dev_pos_del); // // Don't "break" the loop! There may be more than one! // } else ++dev_pos; } } } return; } } } // check also the vector of not yet connected events if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // delete the event queue when used delete vpos->ev_queue; // delete element from vector event_not_connected.erase(vpos); return; } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::unsubscribe_event()"); } void DelayedEventUnsubThread::run(TANGO_UNUSED(void *ptr)) { try { // // In case a callback is still in its execution, wait for it to terminate // the_mon->timeout(3000); the_mon->get_monitor(); the_mon->rel_monitor(); // // Unsubscribe the event // ev_cons->unsubscribe_event(-event_id); } catch(...) {} } void DelayedEventSubThread::run(TANGO_UNUSED(void *ptr)) { // // Subscribe to the event // vector v_s; try { DelayEvent de(ev_cons); WriterLock w(EventConsumer::get_map_modification_lock()); ev_cons->connect_event(device,attribute,et,callback,ev_queue,v_s,event_name,ev_id); } catch (Tango::DevFailed &e) { // // when the subscribe event has not worked, store the connection data in a vector of not // yet connected events. // Retry to connect in the next heartbeat period. // EventNotConnected conn_params; conn_params.device = device; conn_params.attribute = attribute; conn_params.event_type = et; conn_params.event_name = event_name; conn_params.callback = callback; conn_params.ev_queue = ev_queue; conn_params.filters = v_s; conn_params.last_heartbeat = time(NULL); conn_params.event_id = ev_id; ev_cons->add_not_connected_event(e,conn_params); } } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::add_not_connected_event() // // description : // Add a not connected event to the list of not connected event managed in the event consumer in order to // periodically retry the subscription. This method is supposed to be called when event are subscribed // within a event callback. In this case the subsciption is done in a thread (DelayedEventSubThread class) // // argument : // in : // - e : The thrown exception // - not_con : A structure describing the not connected event // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::add_not_connected_event(DevFailed &e,EventNotConnected ¬_con) { if (env_var_fqdn_prefix.empty() == false) not_con.prefix = env_var_fqdn_prefix[0]; event_not_connected.push_back (not_con); vector::iterator vpos = event_not_connected.end() - 1; time_t now = time(NULL); keep_alive_thread->stateless_subscription_failed(vpos,e,now); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Return a vector with all events stored in the event queue. Events are kept in the buffer since the last // extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::get_events (int event_id, EventDataList &event_list) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Return a vector with all attribute configuration events stored in the event queue. // Events are kept in the buffer since the last extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------ void EventConsumer::get_events (int event_id, AttrConfEventDataList &event_list) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Return a vector with all data ready events stored in the event queue. // Events are kept in the buffer since the last extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------ void EventConsumer::get_events (int event_id, DataReadyEventDataList &event_list) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Return a vector with all device interface change events stored in the event queue. // Events are kept in the buffer since the last extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------ void EventConsumer::get_events (int event_id, DevIntrChangeEventDataList &event_list) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception(API_EventQueues, o.str(),"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception(API_EventQueues, o.str(),"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception("API_EventNotFound", "Failed to get event, the event id specified does not correspond with any known one", "EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Return a vector with all pipe events stored in the event queue. // Events are kept in the buffer since the last extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------ void EventConsumer::get_events (int event_id, PipeEventDataList &event_list) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception(API_EventQueues, o.str(),"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (event_list); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception(API_EventQueues, o.str(),"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception("API_EventNotFound", "Failed to get event, the event id specified does not correspond with any known one", "EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_events() // // description : // Call the callback method for all events stored in the event queue. // Events are kept in the buffer since the last extraction with get_events(). // After returning the event data, the event queue gets emptied! // // argument : // in : // - event_id : The event identifier // out : // - event_list : A reference to an event data list to be filled // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::get_events (int event_id, CallBack *cb) { cout3 << "EventConsumer::get_events() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the events from the queue esspos->ev_queue->get_events (cb); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the events from the queue vpos->ev_queue->get_events (cb); return; } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_events()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_events()"); } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::event_queue_size() // // description : // Returns the number of events stored in the event queue // // argument : // in : // - event_id : The event identifier // //------------------------------------------------------------------------------------------------------------------- int EventConsumer::event_queue_size(int event_id) { cout3 << "EventConsumer::event_queue_size() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the event queue size return (esspos->ev_queue->size()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::event_queue_size()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the event queue size return (vpos->ev_queue->size()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::event_queue_size()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::event_queue_size()"); // Should never reach here. To make compiler happy int ret = -1; return ret; } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::is_event_queue_empty() // // description : // Returns true when the event queue is empty // // argument : // in : // - event_id : The event identifier // //------------------------------------------------------------------------------------------------------------------- bool EventConsumer::is_event_queue_empty(int event_id) { cout3 << "EventConsumer::is_event_queue_empty() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // check whether the event queue is empty return (esspos->ev_queue->is_empty()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::is_event_queue_empty()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // check whether the event queue is empty return (vpos->ev_queue->is_empty()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::is_event_queue_empty()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::is_event_queue_empty()"); // Should never reach here. To make compiler happy bool ret = true; return ret; } //+----------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::get_last_event_date() // // description : // Get the time stamp of the last inserted event // // argument : // in : // - event_id : The event identifier // //-------------------------------------------------------------------------------------------------------------------- TimeVal EventConsumer::get_last_event_date(int event_id) { cout3 << "EventConsumer::get_last_event_date() : event_id = " << event_id << endl; // lock the maps ReaderLock l(map_modification_lock); // // First search the event entry in the callback map // std::map::iterator epos; std::vector::iterator esspos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { if(esspos->id == event_id) { // check wether an event queue is used! if ( esspos->callback == NULL ) { // get the last insertion date return (esspos->ev_queue->get_last_event_date()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_last_event_date()"); } } } } // // check also the vector of not yet connected events // if ( event_not_connected.empty() == false ) { std::vector::iterator vpos; for (vpos = event_not_connected.begin(); vpos != event_not_connected.end(); ++vpos) { if ( vpos->event_id == event_id) { // check wether an event queue is used! if ( vpos->callback == NULL ) { // get the last insertion date return (vpos->ev_queue->get_last_event_date()); } else { TangoSys_OMemStream o; o << "No event queue specified during subscribe_event()\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventConsumer::get_last_event_date()"); } } } } // nothing was found! EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to get event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_last_event_date()"); // Should never reach here. To make compiler happy struct TimeVal tv; tv.tv_sec = tv.tv_usec = tv.tv_nsec = 0; return tv; } //+-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumer::add_new_callback() // // description : // Add a new callback to an already existing event entry in the callback map // // argument : // in : // - iter : Iterator in the callback map // - callback : Pointer to the Callback object // - ev_queue : Pointer to the event queue // - event_id : The event identifier // //-------------------------------------------------------------------------------------------------------------------- int EventConsumer::add_new_callback(EvCbIte &iter,CallBack *callback,EventQueue *ev_queue,int event_id) { EventSubscribeStruct ess; int ret_event_id = event_id; if (ret_event_id <= 0) { subscribe_event_id++; ret_event_id = subscribe_event_id; } ess.id = ret_event_id; ess.callback = callback; ess.ev_queue = ev_queue; iter->second.callback_list.push_back(ess); return ret_event_id; } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_fire_sync_event() // // description : // Get event data and fire a synchronous event // // argument : // in : // - device : The device pointer // - callback : The callback pointer // - ev_queue : The event queue // - event : The event type // - event_name : The event name // - obj_name : The attribute/pipe name // - cb : // - callback_key : // //------------------------------------------------------------------------------------------------------------------- void EventConsumer::get_fire_sync_event(DeviceProxy *device,CallBack *callback,EventQueue *ev_queue,EventType event, string &event_name,const string &obj_name,EventCallBackStruct &cb, string &callback_key) { // // A small 10 mS sleep here! This is required in case there is a push_event in the read_attribute (or pipe) // method on the device side. This sleep gives time to ZMQ to send its subscription message // #ifndef _TG_WINDOWS_ struct timespec to_wait,inter; to_wait.tv_sec = 0; to_wait.tv_nsec = 10000000; nanosleep(&to_wait,&inter); #else Sleep(25); #endif if ((event == CHANGE_EVENT) || (event == QUALITY_EVENT) || (event == ARCHIVE_EVENT) || (event == USER_EVENT) || (event == PERIODIC_EVENT)) { DevErrorList err; err.length(0); string domain_name; string::size_type pos; if ((pos = device_name.find(MODIFIER_DBASE_NO)) != string::npos) { domain_name = device_name; string tmp = '/' + obj_name_lower; domain_name.insert(pos,tmp); } else domain_name = device_name + '/' + obj_name_lower; AttributeValue_5 *av_5 = Tango_nullptr; DeviceAttribute *da = Tango_nullptr; FwdEventData *event_data; try { if (cb.fwd_att == true) { device->read_attribute(obj_name.c_str(),av_5); if (av_5->err_list.length() != 0) { err = av_5->err_list; err.length(err.length() - 1); } } else { da = new DeviceAttribute(); *da = device->read_attribute(obj_name.c_str()); if (da->has_failed() == true) { err = da->get_err_stack(); err.length(err.length() - 1); } } } catch (DevFailed &e) { err = e.errors; } string local_event_name = event_name; pos = local_event_name.find(EVENT_COMPAT); if (pos != string::npos) local_event_name.erase(0,EVENT_COMPAT_IDL5_SIZE); if (cb.fwd_att == true) { da = new DeviceAttribute(); event_data = new FwdEventData(device,domain_name,local_event_name,da,err); event_data->set_av_5(av_5); } else { event_data = new FwdEventData(device,domain_name,local_event_name,da,err); } AutoTangoMonitor _mon(cb.callback_monitor); // // If a callback method was specified, call it! // if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "EventConsumer::subscribe_event() exception in callback method of " << callback_key << endl; } delete event_data; if (cb.fwd_att == true) delete [] av_5; } // // No calback method, the event has to be inserted into the event queue // else { ev_queue->insert_event(event_data); } } else if (event == ATTR_CONF_EVENT) { DevErrorList err; err.length(0); string domain_name = device_name + "/" + obj_name_lower; AttributeInfoEx *aie = NULL; string local_event_name = event_name; string::size_type pos = local_event_name.find(EVENT_COMPAT); if (pos != string::npos) local_event_name.erase(0,EVENT_COMPAT_IDL5_SIZE); try { aie = new AttributeInfoEx(); *aie = device->get_attribute_config(const_cast(obj_name)); } catch (DevFailed &e) { err = e.errors; } FwdAttrConfEventData *event_data = new FwdAttrConfEventData(device, domain_name, local_event_name, aie, err); AutoTangoMonitor _mon(cb.callback_monitor); // // If a callback method was specified, call it! // if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "EventConsumer::subscribe_event() exception in callback method of " << callback_key << endl; } delete event_data; } // // No calback method, the event has to be inserted into the event queue // else { ev_queue->insert_event(event_data); } } else if (event == INTERFACE_CHANGE_EVENT) { DevErrorList err; err.length(0); CommandInfoList *c_list = Tango_nullptr; AttributeInfoListEx *a_list = Tango_nullptr; string ev_name(EventName[INTERFACE_CHANGE_EVENT]); try { c_list = device->command_list_query(); a_list = device->attribute_list_query_ex(); } catch (DevFailed &e) { delete c_list; c_list = Tango_nullptr; delete a_list; a_list = Tango_nullptr; err = e.errors; } DevIntrChangeEventData *event_data = new DevIntrChangeEventData(device, ev_name,device_name, c_list,a_list,true, err); AutoTangoMonitor _mon(cb.callback_monitor); // // if a callback method was specified, call it! // if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "EventConsumer::subscribe_event() exception in callback method of " << callback_key << endl; } delete event_data; delete c_list; delete a_list; } // // No calback method, the event has to be instered into the event queue // else { ev_queue->insert_event(event_data); } } else if (event == PIPE_EVENT) { DevErrorList err; err.length(0); string domain_name; string::size_type pos; if ((pos = device_name.find(MODIFIER_DBASE_NO)) != string::npos) { domain_name = device_name; string tmp = '/' + obj_name_lower; domain_name.insert(pos,tmp); } else domain_name = device_name + '/' + obj_name_lower; DevicePipe *da = Tango_nullptr; PipeEventData *event_data; try { da = new DevicePipe(); *da = device->read_pipe(obj_name); } catch (DevFailed &e) { err = e.errors; } event_data = new PipeEventData(device,domain_name,event_name,da,err); AutoTangoMonitor _mon(cb.callback_monitor); // // If a callback method was specified, call it! // if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "EventConsumer::subscribe_event() exception in callback method of " << callback_key << endl; } delete event_data; } // // No calback method, the event has to be inserted into the event queue // else { ev_queue->insert_event(event_data); } } } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventConsumer::get_event_system_for_event_id() // // description : // Get which event system is used by one event from its id // // argument : // in : // - event_id : The event id // // returns : // Event system type used by the event with the specified event id // //-------------------------------------------------------------------------------------------------------------------- ChannelType EventConsumer::get_event_system_for_event_id(int event_id) { ChannelType ret = Tango::ZMQ; EvCbIte epos; vector::iterator esspos; if (event_id == 0) { EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_event_system_for_event_id()"); } bool found = false; ReaderLock r(map_modification_lock); for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &ecs = epos->second; for (esspos = ecs.callback_list.begin(); esspos != ecs.callback_list.end(); ++esspos) { if(esspos->id == event_id) { found = true; EvChanIte evt_it = channel_map.find(ecs.channel_name); if (evt_it == channel_map.end()) { TangoSys_OMemStream o; o << "Can't unsubscribe to event with id " << event_id << "\n"; o << "Corrupted internal map. Please report bug" << ends; Except::throw_exception((const char *)API_BadConfigurationProperty, o.str(), (const char *)"EventConsumer::get_event_system_for_event_id()"); } EventChannelStruct &evt_ch = evt_it->second; ret = evt_ch.channel_type; break; } if (found == true) break; } } // // Also search in the not connected event vector. The returned value in this case is not relevant // if (found == false && event_not_connected.empty() == false) { std::vector::iterator vpos; for (vpos = event_not_connected.begin();vpos != event_not_connected.end();++vpos) { if (vpos->event_id == event_id) { found = true; break; } } } // // Throw exception if the event_id has not been found in maps // if (found == false) { EventSystemExcept::throw_exception((const char*)"API_EventNotFound", (const char*)"Failed to unsubscribe event, the event id specified does not correspond with any known one", (const char*)"EventConsumer::get_event_system_for_event_id()"); } return ret; } /************************************************************************/ /* */ /* EventData class */ /* --------------- */ /* */ /************************************************************************/ //+---------------------------------------------------------------------- // // EventData constructor // //----------------------------------------------------------------------- EventData::EventData(DeviceProxy *dev,string &nam,string &evt, Tango::DeviceAttribute *attr_value_in, DevErrorList &errors_in) : device(dev),attr_name(nam),event(evt),attr_value(attr_value_in), errors(errors_in) { if (errors.length()==0) err=false; else err = true; set_time(); } //+---------------------------------------------------------------------- // // EventData copy constructor // //----------------------------------------------------------------------- EventData::EventData(const EventData &sou) { device = sou.device; attr_name = sou.attr_name; event = sou.event; if (sou.attr_value) attr_value = new DeviceAttribute(*(sou.attr_value)); else attr_value = NULL; err = sou.err; errors = sou.errors; reception_date = sou.reception_date; } //+---------------------------------------------------------------------- // // EventData assignement operator // //----------------------------------------------------------------------- EventData & EventData::operator=(const EventData &ri) { if (&ri == this) return *this; device = ri.device; attr_name = ri.attr_name; event = ri.event; if (ri.attr_value) attr_value = new DeviceAttribute(*(ri.attr_value)); else attr_value = NULL; err = ri.err; errors = ri.errors; reception_date = ri.reception_date; return *this; } //+---------------------------------------------------------------------- // // EventData destructor // //----------------------------------------------------------------------- EventData::~EventData() { delete attr_value; } //+------------------------------------------------------------------------- // // method : EventData::set_time // // description : Set the event reception data // //-------------------------------------------------------------------------- void EventData::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); reception_date.tv_sec = (CORBA::Long)t.time; reception_date.tv_usec = (CORBA::Long)(t.millitm * 1000); reception_date.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); reception_date.tv_sec = (CORBA::Long)tv.tv_sec; reception_date.tv_usec = (CORBA::Long)tv.tv_usec; reception_date.tv_nsec = 0; #endif } FwdEventData::FwdEventData():EventData(),av_5(Tango_nullptr),event_data(Tango_nullptr) { } FwdEventData::FwdEventData(DeviceProxy *dev,string &_s1,string &_s2,Tango::DeviceAttribute *_da,DevErrorList &_del) : EventData(dev,_s1,_s2,_da,_del),av_5(Tango_nullptr),event_data(Tango_nullptr) { } FwdEventData::FwdEventData(DeviceProxy *dev,string &_s1,string &_s2,Tango::DeviceAttribute *_da,DevErrorList &_del,zmq::message_t *_m) : EventData(dev,_s1,_s2,_da,_del),av_5(Tango_nullptr),event_data(_m) { } /************************************************************************/ /* */ /* AttrConfEventData class */ /* ----------------- */ /* */ /************************************************************************/ //+---------------------------------------------------------------------- // // AttrConfEventData constructor // //----------------------------------------------------------------------- AttrConfEventData::AttrConfEventData(DeviceProxy *dev,string &nam,string &evt, Tango::AttributeInfoEx *attr_conf_in,DevErrorList &errors_in) : device(dev),attr_name(nam),event(evt),attr_conf(attr_conf_in), errors(errors_in) { if (errors.length()==0) err=false; else err = true; set_time(); } //+---------------------------------------------------------------------- // // AttrConfEventData copy constructor // //----------------------------------------------------------------------- AttrConfEventData::AttrConfEventData(const AttrConfEventData &sou) { device = sou.device; attr_name = sou.attr_name; event = sou.event; if (sou.attr_conf != NULL) { attr_conf = new (AttributeInfoEx); *attr_conf = *(sou.attr_conf); } else attr_conf = NULL; err = sou.err; errors = sou.errors; reception_date = sou.reception_date; } //+---------------------------------------------------------------------- // // AttrConfEventData assignement operator // //----------------------------------------------------------------------- AttrConfEventData & AttrConfEventData::operator=(const AttrConfEventData &ri) { if (&ri == this) return *this; device = ri.device; attr_name = ri.attr_name; event = ri.event; if (ri.attr_conf != NULL) { attr_conf = new (AttributeInfoEx); *attr_conf = *(ri.attr_conf); } else attr_conf = NULL; err = ri.err; errors = ri.errors; reception_date = ri.reception_date; return *this; } //+---------------------------------------------------------------------- // // AttrConfEventData destructor // //----------------------------------------------------------------------- AttrConfEventData::~AttrConfEventData() { delete attr_conf; } //+------------------------------------------------------------------------- // // method : AttrConfEventData::set_time // // description : Set the event reception data // //-------------------------------------------------------------------------- void AttrConfEventData::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); reception_date.tv_sec = (CORBA::Long)t.time; reception_date.tv_usec = (CORBA::Long)(t.millitm * 1000); reception_date.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); reception_date.tv_sec = (CORBA::Long)tv.tv_sec; reception_date.tv_usec = (CORBA::Long)tv.tv_usec; reception_date.tv_nsec = 0; #endif } FwdAttrConfEventData::FwdAttrConfEventData():AttrConfEventData(),fwd_attr_conf(Tango_nullptr) { } FwdAttrConfEventData::FwdAttrConfEventData(DeviceProxy *dev,string &nam,string &evt, Tango::AttributeInfoEx *attr_conf_in,DevErrorList &errors_in) : AttrConfEventData(dev,nam,evt,attr_conf_in,errors_in),fwd_attr_conf(Tango_nullptr) { } /************************************************************************/ /* */ /* DataReadyEventData class */ /* ------------------ */ /* */ /************************************************************************/ //+---------------------------------------------------------------------- // // DataReadyEventData constructor // //----------------------------------------------------------------------- DataReadyEventData::DataReadyEventData(DeviceProxy *dev,AttDataReady *dr,string &evt,DevErrorList &errors_in) :event(evt),errors(errors_in) { device = dev; if (dr != NULL) { attr_name = dr->name.in(); attr_data_type = dr->data_type; ctr = dr->ctr; } else { attr_name = "Unknown"; attr_data_type = -1; ctr = -1; } if (errors.length()==0) err = false; else err = true; } //+---------------------------------------------------------------------- // // DataReadyEventData copy constructor // //----------------------------------------------------------------------- DataReadyEventData::DataReadyEventData(const DataReadyEventData &sou) { device = sou.device; ctr = sou.ctr; attr_name = sou.attr_name; event = sou.event; attr_data_type = sou.attr_data_type; reception_date = sou.reception_date; err = sou.err; errors = sou.errors; } //+---------------------------------------------------------------------- // // DataReadyEventData assignement operator // //----------------------------------------------------------------------- DataReadyEventData & DataReadyEventData::operator=(const DataReadyEventData &ri) { if (&ri == this) return *this; device = ri.device; ctr = ri.ctr; attr_data_type = ri.attr_data_type; attr_name = ri.attr_name; event = ri.event; reception_date = ri.reception_date; err = ri.err; errors = ri.errors; return *this; } //+------------------------------------------------------------------------- // // method : DataReadyEventData::set_time // // description : Set the event reception data // //-------------------------------------------------------------------------- void DataReadyEventData::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); reception_date.tv_sec = (CORBA::Long)t.time; reception_date.tv_usec = (CORBA::Long)(t.millitm * 1000); reception_date.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); reception_date.tv_sec = (CORBA::Long)tv.tv_sec; reception_date.tv_usec = (CORBA::Long)tv.tv_usec; reception_date.tv_nsec = 0; #endif } /************************************************************************/ /* */ /* DevIntrChangeEventData class */ /* ---------------------- */ /* */ /************************************************************************/ //+---------------------------------------------------------------------- // // DevIntrChangeEventData constructor // //----------------------------------------------------------------------- DevIntrChangeEventData::DevIntrChangeEventData(DeviceProxy *dev,string &evt,string &d_name, DevCmdInfoList_2 *c_list,AttributeConfigList_5 *a_list, bool d_s,DevErrorList &errors_in) :event(evt),device_name(d_name),dev_started(d_s),errors(errors_in) { device = dev; if (errors.length()==0) err = false; else err = true; if (err == false) { // // Convert first command list and then attribute list // cmd_list.resize(c_list->length()); for (size_t i=0; i < c_list->length(); i++) { cmd_list[i].cmd_name = (*c_list)[i].cmd_name; cmd_list[i].cmd_tag = (*c_list)[i].cmd_tag; cmd_list[i].in_type = (*c_list)[i].in_type; cmd_list[i].out_type = (*c_list)[i].out_type; cmd_list[i].in_type_desc = (*c_list)[i].in_type_desc.in(); cmd_list[i].out_type_desc = (*c_list)[i].out_type_desc.in(); cmd_list[i].disp_level = (*c_list)[i].level; } att_list.resize(a_list->length()); AttributeConfigList_5_var a_list_var(a_list); for (size_t i=0; ilength(); i++) { COPY_BASE_CONFIG(att_list,a_list_var) for (size_t j=0; j<(*a_list)[i].sys_extensions.length(); j++) { att_list[i].sys_extensions[j] = (*a_list)[i].sys_extensions[j]; } att_list[i].disp_level = (*a_list)[i].level; att_list[i].min_alarm = (*a_list)[i].att_alarm.min_alarm; att_list[i].max_alarm = (*a_list)[i].att_alarm.max_alarm; att_list[i].root_attr_name = (*a_list)[i].root_attr_name; if ((*a_list)[i].memorized == false) att_list[i].memorized = NONE; else { if ((*a_list)[i].mem_init == false) att_list[i].memorized = MEMORIZED; else att_list[i].memorized = MEMORIZED_WRITE_INIT; } COPY_ALARM_CONFIG(att_list,a_list_var) COPY_EVENT_CONFIG(att_list,a_list_var) } a_list_var._retn(); } } DevIntrChangeEventData::DevIntrChangeEventData(DeviceProxy *dev,string &evt,string &d_name, CommandInfoList *c_list,AttributeInfoListEx *a_list, bool d_s,DevErrorList &errors_in) :event(evt),device_name(d_name),dev_started(d_s),errors(errors_in) { device = dev; if (errors.length()==0) err = false; else err = true; if (err == false) { cmd_list = *c_list; att_list = *a_list; } } //+---------------------------------------------------------------------- // // DevIntrChangeEventData copy constructor // //----------------------------------------------------------------------- DevIntrChangeEventData::DevIntrChangeEventData(const DevIntrChangeEventData &sou) { device = sou.device; event = sou.event; device_name = sou.device_name; cmd_list = sou.cmd_list; att_list = sou.att_list; dev_started = sou.dev_started; reception_date = sou.reception_date; err = sou.err; errors = sou.errors; } //+---------------------------------------------------------------------- // // DevIntrChangeEventData assignement operator // //----------------------------------------------------------------------- DevIntrChangeEventData & DevIntrChangeEventData::operator=(const DevIntrChangeEventData &ri) { if (&ri == this) return *this; device = ri.device; event = ri.event; device_name = ri.device_name; cmd_list = ri.cmd_list; att_list = ri.att_list; dev_started = ri.dev_started; reception_date = ri.reception_date; err = ri.err; errors = ri.errors; return *this; } //+------------------------------------------------------------------------- // // method : DevIntrChangeEventData::set_time // // description : Set the event reception data // //-------------------------------------------------------------------------- void DevIntrChangeEventData::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); reception_date.tv_sec = (CORBA::Long)t.time; reception_date.tv_usec = (CORBA::Long)(t.millitm * 1000); reception_date.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); reception_date.tv_sec = (CORBA::Long)tv.tv_sec; reception_date.tv_usec = (CORBA::Long)tv.tv_usec; reception_date.tv_nsec = 0; #endif } /************************************************************************/ /* */ /* PipepEventData class */ /* --------------- */ /* */ /************************************************************************/ //+---------------------------------------------------------------------- // // PipeEventData constructor // //----------------------------------------------------------------------- PipeEventData::PipeEventData(DeviceProxy *dev,string &nam,string &evt, Tango::DevicePipe *pipe_value_in, DevErrorList &errors_in) : device(dev),pipe_name(nam),event(evt),pipe_value(pipe_value_in), errors(errors_in) { if (errors.length()==0) err=false; else err = true; set_time(); } //+---------------------------------------------------------------------- // // PipeEventData copy constructor // //----------------------------------------------------------------------- PipeEventData::PipeEventData(const PipeEventData &sou) { device = sou.device; pipe_name = sou.pipe_name; event = sou.event; if (sou.pipe_value) pipe_value = new DevicePipe(*(sou.pipe_value)); else pipe_value = NULL; err = sou.err; errors = sou.errors; reception_date = sou.reception_date; } //+---------------------------------------------------------------------- // // PipeEventData assignement operator // //----------------------------------------------------------------------- PipeEventData & PipeEventData::operator=(const PipeEventData &ri) { if (&ri == this) return *this; device = ri.device; pipe_name = ri.pipe_name; event = ri.event; if (ri.pipe_value) pipe_value = new DevicePipe(*(ri.pipe_value)); else pipe_value = NULL; err = ri.err; errors = ri.errors; reception_date = ri.reception_date; return *this; } //+---------------------------------------------------------------------- // // PipeEventData destructor // //----------------------------------------------------------------------- PipeEventData::~PipeEventData() { delete pipe_value; } //+------------------------------------------------------------------------- // // method : PipeEventData::set_time // // description : Set the event reception data // //-------------------------------------------------------------------------- void PipeEventData::set_time() { #ifdef _TG_WINDOWS_ struct _timeb t; _ftime(&t); reception_date.tv_sec = (CORBA::Long)t.time; reception_date.tv_usec = (CORBA::Long)(t.millitm * 1000); reception_date.tv_nsec = 0; #else struct timezone tz; struct timeval tv; gettimeofday(&tv,&tz); reception_date.tv_sec = (CORBA::Long)tv.tv_sec; reception_date.tv_usec = (CORBA::Long)tv.tv_usec; reception_date.tv_nsec = 0; #endif } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/client/eventkeepalive.cpp0000644023471100065110000016152513034744772016274 00000000000000static const char *RcsId = "$Id: eventkeepalive.cpp 29816 2016-06-10 08:27:56Z taurel $"; //===================================================================================================================== // // file : event.cpp // // description : C++ classes for implementing the event system KeepAliveThread. This class cheks that the // heartbeat event are well received. It also manages the stateless subscription because this // is this class which will regularely re-try to subsribe to event in case it is needed. // Finally, it is also this class which generates the re-connection in case a device server // sending events is stopped and re-started // // author(s) : A.Gotz (goetz@esrf.fr) // // original : 7 April 2003 // // Copyright (C) : 2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 29816 $ // //==================================================================================================================== #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #include #endif using namespace CORBA; namespace Tango { /************************************************************************/ /* */ /* EventConsumerKeepAlive class */ /* ---------------------------- */ /* */ /************************************************************************/ //+------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::reconnect_to_channel() // // description : // Method to reconnect the process to an event channel in case of reconnection to a notifd // // argument : // in : // - ipos : An iterator to the EventChannel structure to reconnect to in the Event Channel map // - event_consumer : Pointer to the EventConsumer singleton // // return : // This method returns true if the reconnection succeeds. Otherwise, returns false // //-------------------------------------------------------------------------------------------------------------------- bool EventConsumerKeepAliveThread::reconnect_to_channel(EvChanIte &ipos,EventConsumer *event_consumer) { bool ret = true; EvCbIte epos; cout3 << "Entering KeepAliveThread::reconnect()" << endl; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first) { bool need_reconnect = false; vector:: iterator esspos; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if (esspos->callback != NULL || esspos->ev_queue != NULL) { need_reconnect = true; break; } } if (need_reconnect == true) { try { DeviceData dummy; string adm_name = ipos->second.full_adm_name; event_consumer->connect_event_channel(adm_name, epos->second.device->get_device_db(), true,dummy); if (ipos->second.adm_device_proxy != NULL) delete ipos->second.adm_device_proxy; ipos->second.adm_device_proxy = new DeviceProxy(ipos->second.full_adm_name); cout3 << "Reconnected to event channel" << endl; } catch(...) { ret = false; } break; } } } return ret; } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::reconnect_to_zmq_channel() // // description : // Method to reconnect the process to a ZMQ event channel in case of reconnection // // argument : // in : // - ipos : An iterator to the EventChannel structure to reconnect to in the Event Channel map // - event_consumer : Pointer to the EventConsumer singleton // - dd : // // return : // This method returns true if the reconnection succeeds. Otherwise, returns false // //--------------------------------------------------------------------------------------------------------------------- bool EventConsumerKeepAliveThread::reconnect_to_zmq_channel(EvChanIte &ipos,EventConsumer *event_consumer,DeviceData &dd) { bool ret = true; EvCbIte epos; cout3 << "Entering KeepAliveThread::reconnect_to_zmq_channel()" << endl; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first) { bool need_reconnect = false; vector:: iterator esspos; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if (esspos->callback != NULL || esspos->ev_queue != NULL) { need_reconnect = true; break; } } if (need_reconnect == true) { try { DeviceData subscriber_in,subscriber_out; vector subscriber_info; subscriber_info.push_back(epos->second.device->dev_name()); subscriber_info.push_back(epos->second.obj_name); subscriber_info.push_back("subscribe"); subscriber_info.push_back(epos->second.event_name); subscriber_info.push_back("0"); subscriber_in << subscriber_info; subscriber_out = ipos->second.adm_device_proxy->command_inout("ZmqEventSubscriptionChange",subscriber_in); string adm_name = ipos->second.full_adm_name; #ifdef ZMQ_HAS_DISCONNECT // // Forget exception which could happen during massive restart of device server process running on the same host // try { event_consumer->disconnect_event_channel(adm_name,ipos->second.endpoint,epos->second.endpoint); } catch (Tango::DevFailed &e) {} #endif event_consumer->connect_event_channel(adm_name, epos->second.device->get_device_db(), true,subscriber_out); dd = subscriber_out; if (ipos->second.adm_device_proxy != NULL) delete ipos->second.adm_device_proxy; ipos->second.adm_device_proxy = new DeviceProxy(ipos->second.full_adm_name); cout3 << "Reconnected to zmq event channel" << endl; } catch(...) { ret = false; } break; } } } return ret; } //-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::reconnect_to_event() // // description : // Method to reconnect each event associated to a specific event channel to the just reconnected event channel // // argument : // in : // - ipos : An iterator to the EventChannel structure in the Event Channel map // - event_consumer : Pointer to the EventConsumer singleton // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::reconnect_to_event(EvChanIte &ipos,EventConsumer *event_consumer) { EvCbIte epos; cout3 << "Entering KeepAliveThread::reconnect_to_event()" << endl; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first) { bool need_reconnect = false; vector:: iterator esspos; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if (esspos->callback != NULL || esspos->ev_queue != NULL) { need_reconnect = true; break; } } if (need_reconnect == true) { try { epos->second.callback_monitor->get_monitor(); try { re_subscribe_event(epos,ipos); epos->second.filter_ok = true; cout3 << "Reconnected to event" << endl; } catch(...) { epos->second.filter_ok = false; } epos->second.callback_monitor->rel_monitor(); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::reconnect_to_event() cannot get callback monitor for " << epos->first; au->print_error_message(ss.str().c_str()); } } } } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::re_subscribe_event() // // description : // Method to reconnect a specific event to an event channel just reconnected // // argument : // in : // - epos : An iterator to the EventCallback structure in the Event Callback map // - ipos : Pointer to the EventChannel structure in the Event Channel map // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::re_subscribe_event(EvCbIte &epos,EvChanIte &ipos) { // // Build a filter using the CORBA Notify constraint Language (use attribute name in lowercase letters) // CosNotifyFilter::FilterFactory_var ffp; CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); CosNotifyFilter::FilterID filter_id; string channel_name = epos->second.channel_name; try { ffp = ipos->second.eventChannel->default_filter_factory(); filter = ffp->create_filter("EXTENDED_TCL"); } catch (CORBA::COMM_FAILURE &) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught CORBA::COMM_FAILURE exception while creating event filter (check filter)", (const char*)"EventConsumerKeepAliveThread::re_subscribe_event()"); } catch (...) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while creating event filter (check filter)", (const char*)"EventConsumerKeepAliveThread::re_subscribe_event()"); } // // Construct a simple constraint expression; add it to fadmin // string constraint_expr = epos->second.filter_constraint; CosNotification::EventTypeSeq evs; CosNotifyFilter::ConstraintExpSeq exp; exp.length(1); exp[0].event_types = evs; exp[0].constraint_expr = CORBA::string_dup(constraint_expr.c_str()); CORBA::Boolean res = 0; // OK try { CosNotifyFilter::ConstraintInfoSeq_var dummy = filter->add_constraints(exp); filter_id = ipos->second.structuredProxyPushSupplier->add_filter(filter); epos->second.filter_id = filter_id; } catch(CosNotifyFilter::InvalidConstraint &) { //cerr << "Exception thrown : Invalid constraint given " // << (const char *)constraint_expr << endl; res = 1; } catch (...) { //cerr << "Exception thrown while adding constraint " // << (const char *)constraint_expr << endl; res = 1; } // // If error, destroy filter // if (res == 1) { try { filter->destroy(); } catch (...) { } filter = CosNotifyFilter::Filter::_nil(); EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while creating event filter (check filter)", (const char*)"EventConsumerKeepAliveThread::re_subscribe_event()"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::reconnect_to_zmq_event() // // description : // Method to reconnect each event associated to a specific event channel to the just reconnected event channel // // argument : // in : // - ipos : An iterator to the EventChannel structure in the Event Channel map // - event_consumer : Pointer to the EventConsumer singleton // - dd : // //------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::reconnect_to_zmq_event(EvChanIte &ipos,EventConsumer *event_consumer,DeviceData &dd) { EvCbIte epos; #ifdef ZMQ_HAS_DISCONNECT bool disconnect_called = false; #endif cout3 << "Entering KeepAliveThread::reconnect_to_zmq_event()" << endl; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first) { bool need_reconnect = false; vector:: iterator esspos; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if (esspos->callback != NULL || esspos->ev_queue != NULL) { need_reconnect = true; break; } } if (need_reconnect == true) { try { epos->second.callback_monitor->get_monitor(); try { EventCallBackStruct ecbs; vector vs; vs.push_back(string("reconnect")); string d_name = epos->second.device->dev_name(); string &fqen = epos->second.fully_qualified_event_name; string::size_type pos = fqen.find('/'); pos = pos + 2; pos = fqen.find('/',pos); string prefix = fqen.substr(0,pos + 1); d_name.insert(0,prefix); #ifdef ZMQ_HAS_DISCONNECT if (disconnect_called == false) { event_consumer->disconnect_event(epos->second.fully_qualified_event_name,epos->second.endpoint); disconnect_called = true; } #endif event_consumer->connect_event_system(d_name,epos->second.obj_name,epos->second.event_name, vs,ipos,ecbs,dd,ipos->second.valid_endpoint); const DevVarLongStringArray *dvlsa; dd >> dvlsa; epos->second.endpoint = dvlsa->svalue[(ipos->second.valid_endpoint << 1) + 1].in(); cout3 << "Reconnected to ZMQ event" << endl; } catch(...) { epos->second.filter_ok = false; } epos->second.callback_monitor->rel_monitor(); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::reconnect_to_zmq_event() cannot get callback monitor for " << epos->first; au->print_error_message(ss.str().c_str()); } } } } } //------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::run_undetached // // description : // The main code of the KeepAliveThread // //------------------------------------------------------------------------------------------------------------------- void *EventConsumerKeepAliveThread::run_undetached(TANGO_UNUSED(void *arg)) { int time_to_sleep; time_t now; ZmqEventConsumer *event_consumer; NotifdEventConsumer *notifd_event_consumer; // // first sleep 2 seconds to give the event system time to startup // #ifndef _TG_WINDOWS_ unsigned int time_left; time_left = ::sleep(2); if (time_left != 0) ::sleep(time_left); #else Sleep(2000L); #endif /* _TG_WINDOWS_ */ bool exit_th = false; event_consumer = ApiUtil::instance()->get_zmq_event_consumer(); notifd_event_consumer = ApiUtil::instance()->get_notifd_event_consumer(); while (exit_th == false) { time_to_sleep = EVENT_HEARTBEAT_PERIOD; // // Go to sleep until next heartbeat. Wait on a monitor. This allows another thread to wake-up this thread // before the end of the EVENT_HEARTBEAT_PERIOD time which is 10 seconds. Only one command can now be send to the // thread. It is a stop command // { omni_mutex_lock sync(shared_cmd); if (shared_cmd.cmd_pending == false) { unsigned long s,n; unsigned long nb_sec,nb_nanos; nb_sec = time_to_sleep ; nb_nanos = 0; omni_thread::get_time(&s,&n,nb_sec,nb_nanos); shared_cmd.cond.timedwait(s,n); } if (shared_cmd.cmd_pending == true) { exit_th = true; return (void *)NULL; } } // // Re-subscribe // cout4 << "KeepAliveThread at work" << endl; // // Be sure to have valid event consumer object (In case of long startup OS with some notifd event(s) subscribed at the // end of the process startup. Verified with some ESRF HdbEventHandler process) // if (event_consumer) event_consumer = ApiUtil::instance()->get_zmq_event_consumer(); if (notifd_event_consumer == NULL) notifd_event_consumer = ApiUtil::instance()->get_notifd_event_consumer(); now = time(NULL); if ( event_consumer->event_not_connected.empty() == false) { DelayEvent de(event_consumer); event_consumer->map_modification_lock.writerIn(); // // Check the list of not yet connected events and try to subscribe // not_conected_event(event_consumer,now,notifd_event_consumer); event_consumer->map_modification_lock.writerOut(); } // // Check for all other event reconnections // { // lock the maps only for reading ReaderLock r (event_consumer->map_modification_lock); std::map::iterator ipos; std::map::iterator epos; for (ipos = event_consumer->channel_map.begin(); ipos != event_consumer->channel_map.end(); ++ipos) { try { // lock the event channel ipos->second.channel_monitor->get_monitor(); // // Check if it is necessary for client to confirm its subscription. Note that starting with Tango 8.1 (and for ZMQ), // there is a new command in the admin device which allows a better (optimized) confirmation algorithm // if ((now - ipos->second.last_subscribed) > EVENT_RESUBSCRIBE_PERIOD/3) { confirm_subscription(event_consumer,ipos); } // // Check if a heartbeat have been skipped. If a heartbeat is missing, there are four possibilities : // 1 - The notifd is dead (or the crate is rebooting or has already reboot) // 2 - The server is dead // 3 - The network was down; // 4 - The server has been restarted on another host. // bool heartbeat_skipped; heartbeat_skipped = ((now - ipos->second.last_heartbeat) >= EVENT_HEARTBEAT_PERIOD); if (heartbeat_skipped || ipos->second.heartbeat_skipped || ipos->second.event_system_failed == true) { ipos->second.heartbeat_skipped = true; main_reconnect(event_consumer,notifd_event_consumer,epos,ipos); } else { // When the heartbeat has worked, mark the connection to the notifd as OK if (ipos->second.channel_type == NOTIFD) ipos->second.has_notifd_closed_the_connection = 0; } // release channel monitor ipos->second.channel_monitor->rel_monitor(); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() timeout on callback monitor of " << epos->first; au->print_error_message(ss.str().c_str()); } } } } // // If we arrive here, this means that we have received the exit thread command. // return (void *)NULL; } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::not_connected_event // // description : // Try to connect not yet connected event(s). Try first with ZMQ event consumer. // If ZMQ is not used (API_CommandNotFound exception), use notifd. // // argument : // in : // - event_consumer : The ZMQ event consumer object // - now : The date // - notifd_event_consumer : The notifd event consumer object // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::not_conected_event(ZmqEventConsumer *event_consumer,time_t now, NotifdEventConsumer *notifd_event_consumer) { if ( !event_consumer->event_not_connected.empty() ) { std::vector::iterator vpos; for (vpos = event_consumer->event_not_connected.begin(); vpos != event_consumer->event_not_connected.end(); /*vpos++*/) { bool inc_vpos = true; // // check wether it is necessary to try to subscribe again! // if ( (now - vpos->last_heartbeat) >= (EVENT_HEARTBEAT_PERIOD - 1) ) { try { // try to subscribe event_consumer->connect_event (vpos->device,vpos->attribute,vpos->event_type, vpos->callback, vpos->ev_queue, vpos->filters, vpos->event_name, vpos->event_id); // // delete element from vector when subscribe worked // vpos = event_consumer->event_not_connected.erase(vpos); inc_vpos = false; } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { try { if (notifd_event_consumer == NULL) { ApiUtil::instance()->create_notifd_event_consumer(); notifd_event_consumer = ApiUtil::instance()->get_notifd_event_consumer(); } notifd_event_consumer->connect_event(vpos->device,vpos->attribute,vpos->event_type, vpos->callback, vpos->ev_queue, vpos->filters, vpos->event_name, vpos->event_id); // // delete element from vector when subscribe worked // vpos = event_consumer->event_not_connected.erase(vpos); inc_vpos = false; } catch (Tango::DevFailed &e) { stateless_subscription_failed(vpos,e,now); } } else stateless_subscription_failed(vpos,e,now); } catch (...) { // // subscribe has not worked, try again in the next hearbeat period // vpos->last_heartbeat = now; ApiUtil *au = ApiUtil::instance(); au->print_error_message("During the event subscription an exception was sent which is not a Tango::DevFailed exception!"); } } if (inc_vpos) ++vpos; } } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::fwd_not_connected_event // // description : // Try to connect not yet connected event(s). This method is called only in case of forwarded attribute with // root attribute inside the same process than the fwd attribute! // // argument : // in : // - event_consumer : The ZMQ event consumer object // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::fwd_not_conected_event(ZmqEventConsumer *event_consumer) { // // lock the maps only for reading // event_consumer->map_modification_lock.writerIn(); if ( !event_consumer->event_not_connected.empty() ) { time_t now = time(NULL); std::vector::iterator vpos; for (vpos = event_consumer->event_not_connected.begin(); vpos != event_consumer->event_not_connected.end(); /*vpos++*/) { bool inc_vpos = true; // // check wether it is necessary to try to subscribe again! // try { // try to subscribe event_consumer->connect_event (vpos->device,vpos->attribute,vpos->event_type, vpos->callback, vpos->ev_queue, vpos->filters, vpos->event_name, vpos->event_id); // // delete element from vector when subscribe worked // vpos = event_consumer->event_not_connected.erase(vpos); inc_vpos = false; } catch (Tango::DevFailed &e) { stateless_subscription_failed(vpos,e,now); } catch (...) { // // subscribe has not worked, try again in the next hearbeat period // vpos->last_heartbeat = now; ApiUtil *au = ApiUtil::instance(); au->print_error_message("During the event subscription an exception was sent which is not a Tango::DevFailed exception!"); } if (inc_vpos) ++vpos; } } event_consumer->map_modification_lock.writerOut(); } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::confirm_subscription // // description : // Confirm event subscription for all events coming from a specified event channel (Device server) // // argument : // in : // - event_consumer : The ZMQ event consumer object // - ipos : Iterator on the EventChannel map // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::confirm_subscription(ZmqEventConsumer *event_consumer, map::iterator &ipos) { vector cmd_params; vector::difference_type> vd; std::map::iterator epos; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first ) { try { // // lock the callback // epos->second.callback_monitor->get_monitor(); if (ipos->second.channel_type == ZMQ) { cmd_params.push_back(epos->second.device->dev_name()); cmd_params.push_back(epos->second.obj_name); cmd_params.push_back(epos->second.event_name); vd.push_back(distance(event_consumer->event_callback_map.begin(),epos)); } else { DeviceData subscriber_in; vector subscriber_info; subscriber_info.push_back(epos->second.device->dev_name()); subscriber_info.push_back(epos->second.obj_name); subscriber_info.push_back("subscribe"); subscriber_info.push_back(epos->second.event_name); subscriber_in << subscriber_info; ipos->second.adm_device_proxy->command_inout("EventSubscriptionChange",subscriber_in); time_t ti = time(NULL); ipos->second.last_subscribed = ti; epos->second.last_subscribed = ti; } epos->second.callback_monitor->rel_monitor(); } catch (...) { epos->second.callback_monitor->rel_monitor(); } } } if (ipos->second.channel_type == ZMQ && cmd_params.empty() == false) { try { DeviceData sub_cmd_in; sub_cmd_in << cmd_params; ipos->second.adm_device_proxy->command_inout("EventConfirmSubscription",sub_cmd_in); time_t ti = time(NULL); ipos->second.last_subscribed = ti; for (unsigned int loop = 0;loop < vd.size();++loop) { epos = event_consumer->event_callback_map.begin(); advance(epos,vd[loop]); epos->second.callback_monitor->get_monitor(); epos->second.last_subscribed = ti; epos->second.callback_monitor->rel_monitor(); } } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == API_CommandNotFound) { // // We are connected to a Tango 8 server which do not implement the EventConfirmSubscription command // Send confirmation the old way // time_t ti = time(NULL); ipos->second.last_subscribed = ti; for (unsigned int loop = 0;loop < vd.size();++loop) { DeviceData subscriber_in; vector subscriber_info; subscriber_info.push_back(cmd_params[(loop * 3)]); subscriber_info.push_back(cmd_params[(loop * 3) + 1]); subscriber_info.push_back("subscribe"); subscriber_info.push_back(cmd_params[(loop * 3) + 2]); subscriber_info.push_back("0"); subscriber_in << subscriber_info; try { ipos->second.adm_device_proxy->command_inout("ZmqEventSubscriptionChange",subscriber_in); } catch(...) {} epos = event_consumer->event_callback_map.begin(); advance(epos,vd[loop]); epos->second.callback_monitor->get_monitor(); epos->second.last_subscribed = ti; epos->second.callback_monitor->rel_monitor(); } } } catch (...) {} cmd_params.clear(); } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::main_reconnect // // description : // Main method executed to send error to the user callback or to reconnect the event // // argument : // in : // - event_consumer : The ZMQ event consumer object // - notifd_event_consumer : The notifd event consumer object // - epos : Iterator on the EventCallback map // - ipos : Iterator on the EventChannel map // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::main_reconnect(ZmqEventConsumer *event_consumer, NotifdEventConsumer *notifd_event_consumer, map::iterator &epos, map::iterator &ipos) { // // First, try to reconnect // if (ipos->second.channel_type == NOTIFD) { // // Check notifd by trying to read an attribute of the event channel // try { // // Check if the device server is now running on a different host. In this case we have to reconnect to another // notification daemon. // DeviceInfo info; try { info = ipos->second.adm_device_proxy->info(); } catch (Tango::DevFailed &) { // in case of failure, just stay connected to the actual notifd info.server_host = ipos->second.notifyd_host; } if ( ipos->second.notifyd_host != info.server_host ) { ipos->second.event_system_failed = true; } else { CosNotifyChannelAdmin::EventChannelFactory_var ecf = ipos->second.eventChannel->MyFactory(); if (ipos->second.full_adm_name.find(MODIFIER_DBASE_NO) != string::npos) ipos->second.event_system_failed = true; } } catch (...) { ipos->second.event_system_failed = true; cout3 << "Notifd is dead !!!" << endl; } // // if the connection to the notify daemon is marked as ok, the device server is working fine but // the heartbeat is still not coming back since three periods: // The notify deamon might have closed the connection, try to reconnect! // if ( ipos->second.event_system_failed == false && ipos->second.has_notifd_closed_the_connection >= 3 ) { ipos->second.event_system_failed = true; } // // Re-build connection to the event channel. This is a two steps process. First, reconnect to the new event channel, // then reconnect callbacks to this new event channel // if ( ipos->second.event_system_failed == true ) { bool notifd_reco = reconnect_to_channel(ipos,notifd_event_consumer); if ( notifd_reco ) ipos->second.event_system_failed = false; else ipos->second.event_system_failed = true; if ( ipos->second.event_system_failed == false ) { reconnect_to_event(ipos,notifd_event_consumer); } } } else { DeviceData dd; bool zmq_reco = reconnect_to_zmq_channel(ipos,event_consumer,dd); if ( zmq_reco ) ipos->second.event_system_failed = false; else ipos->second.event_system_failed = true; if (ipos->second.event_system_failed == false) { reconnect_to_zmq_event(ipos,event_consumer,dd); } } Tango::DevErrorList errors(1); errors.length(1); errors[0].severity = Tango::ERR; errors[0].origin = CORBA::string_dup("EventConsumer::KeepAliveThread()"); errors[0].reason = CORBA::string_dup("API_EventTimeout"); errors[0].desc = CORBA::string_dup("Event channel is not responding anymore, maybe the server or event system is down"); DeviceAttribute *dev_attr = NULL; AttributeInfoEx *dev_attr_conf = NULL; DevicePipe *dev_pipe = NULL; for (epos = event_consumer->event_callback_map.begin(); epos != event_consumer->event_callback_map.end(); ++epos) { if (epos->second.channel_name == ipos->first) { bool need_reconnect = false; vector:: iterator esspos; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { if (esspos->callback != NULL || esspos->ev_queue != NULL) { need_reconnect = true; break; } } try { epos->second.callback_monitor->get_monitor(); if (need_reconnect == true) { if ((ipos->second.channel_type == NOTIFD) && (epos->second.filter_ok == false)) { try { re_subscribe_event(epos,ipos); epos->second.filter_ok = true; } catch(...) {} } } string domain_name; string event_name; string::size_type pos = epos->first.rfind('.'); if (pos == string::npos) { domain_name = "domain_name"; event_name = "event_name"; } else { domain_name = epos->first.substr(0,pos); event_name = epos->first.substr(pos + 1); string::size_type pos = event_name.find(EVENT_COMPAT); if (pos != string::npos) event_name.erase(0,EVENT_COMPAT_IDL5_SIZE); } for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { CallBack *callback = esspos->callback; EventQueue *ev_queue = esspos->ev_queue; // // Push an event with error set // if (event_name == CONF_TYPE_EVENT) { FwdAttrConfEventData *event_data = new FwdAttrConfEventData(epos->second.device, domain_name, event_name, dev_attr_conf, errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else if (event_name == DATA_READY_TYPE_EVENT) { DataReadyEventData *event_data = new DataReadyEventData(epos->second.device,NULL,event_name,errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else if (event_name == EventName[INTERFACE_CHANGE_EVENT]) { DevIntrChangeEventData *event_data = new DevIntrChangeEventData(epos->second.device, event_name,domain_name, (CommandInfoList *)NULL, (AttributeInfoListEx *)NULL, false,errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else if (event_name == EventName[PIPE_EVENT]) { PipeEventData *event_data = new PipeEventData(epos->second.device, domain_name, event_name, dev_pipe, errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else { FwdEventData *event_data = new FwdEventData(epos->second.device, domain_name, event_name, dev_attr, errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } } if ( ipos->second.event_system_failed == false ) { re_subscribe_after_reconnect(event_consumer,notifd_event_consumer,epos,ipos,domain_name); } // release callback monitor epos->second.callback_monitor->rel_monitor(); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() timeout on callback monitor of " << epos->first; au->print_error_message(ss.str().c_str()); } } } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::re_subscribe_after_reconnect // // description : // Re subscribe to the event after a successfull reconnection to the event channel (device server) // // argument : // in : // - event_consumer : The ZMQ event consumer object // - notifd_event_consumer : The notifd event consumer object // - epos : Iterator on the EventCallback map // - ipos : Iterator on the EventChannel map // - domain_name : // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::re_subscribe_after_reconnect(ZmqEventConsumer *event_consumer, NotifdEventConsumer *notifd_event_consumer, map::iterator &epos, map::iterator &ipos, string &domain_name) { DeviceData subscriber_in; vector subscriber_info; subscriber_info.push_back(epos->second.device->dev_name()); subscriber_info.push_back(epos->second.obj_name); subscriber_info.push_back("subscribe"); subscriber_info.push_back(epos->second.event_name); if (ipos->second.channel_type == ZMQ) subscriber_info.push_back("0"); subscriber_in << subscriber_info; bool ds_failed = false; try { if (ipos->second.channel_type == ZMQ) ipos->second.adm_device_proxy->command_inout("ZmqEventSubscriptionChange",subscriber_in); else ipos->second.adm_device_proxy->command_inout("EventSubscriptionChange",subscriber_in); ipos->second.heartbeat_skipped = false; ipos->second.last_subscribed = time(NULL); } catch (...) {ds_failed = true;} if (ds_failed == false) { // // Push an event with the value just read from the re-connected server // NOT NEEDED for the Data Ready event // vector:: iterator esspos; string ev_name(epos->second.event_name); string::size_type pos = ev_name.find(EVENT_COMPAT); if (pos != string::npos) ev_name.erase(0,EVENT_COMPAT_IDL5_SIZE); if ((ev_name == "change") || (ev_name == "quality") || (ev_name == "archive") || (ev_name == "user_event")) { // // For attribute data event // DeviceAttribute *da = NULL; DevErrorList err; err.length(0); bool old_transp = epos->second.device->get_transparency_reconnection(); epos->second.device->set_transparency_reconnection(true); try { da = new DeviceAttribute(); *da = epos->second.device->read_attribute(epos->second.obj_name.c_str()); if (da->has_failed() == true) err = da->get_err_stack(); // // The reconnection worked fine. The heartbeat should come back now, when the notifd has not closed the connection. // Increase the counter to detect when the heartbeat is not coming back. // if (ipos->second.channel_type == NOTIFD) ipos->second.has_notifd_closed_the_connection++; } catch (DevFailed &e) { err = e.errors; } epos->second.device->set_transparency_reconnection(old_transp); // if callback methods were specified, call them! unsigned int cb_nb = epos->second.callback_list.size(); unsigned int cb_ctr = 0; DeviceAttribute *da_copy = NULL; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { cb_ctr++; FwdEventData *event_data; if (cb_ctr != cb_nb) { da_copy = new DeviceAttribute(); da_copy->deep_copy(*da); event_data = new FwdEventData(epos->second.device, domain_name, epos->second.event_name, da_copy, err); } else { event_data = new FwdEventData(epos->second.device, domain_name, epos->second.event_name, da, err); } CallBack *callback = esspos->callback; EventQueue *ev_queue = esspos->ev_queue; if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } //event_data->attr_value = NULL; delete event_data; } // no calback method, the event has to be inserted // into the event queue else { ev_queue->insert_event(event_data); } } } else if (epos->second.event_name.find(CONF_TYPE_EVENT) != string::npos) { // // For attribute configuration event // AttributeInfoEx *aie = NULL; DevErrorList err; err.length(0); string prefix; if (ipos->second.channel_type == NOTIFD) prefix = notifd_event_consumer->env_var_fqdn_prefix[0]; else { if (epos->second.device->get_from_env_var() == false) { prefix = "tango://"; if (epos->second.device->is_dbase_used() == false) prefix = prefix + epos->second.device->get_dev_host() + ':' + epos->second.device->get_dev_port() + '/'; else prefix = prefix + epos->second.device->get_db_host() + ':' + epos->second.device->get_db_port() + '/'; } else { prefix = event_consumer->env_var_fqdn_prefix[0]; } } string dom_name = prefix + epos->second.device->dev_name(); if (epos->second.device->is_dbase_used() == false) dom_name = dom_name + MODIFIER_DBASE_NO; dom_name = dom_name + "/" + epos->second.obj_name; bool old_transp = epos->second.device->get_transparency_reconnection(); epos->second.device->set_transparency_reconnection(true); try { aie = new AttributeInfoEx(); *aie = epos->second.device->get_attribute_config(epos->second.obj_name); // // The reconnection worked fine. The heartbeat should come back now, when the notifd has not closed the connection. // Increase the counter to detect when the heartbeat is not coming back. // if (ipos->second.channel_type == NOTIFD) ipos->second.has_notifd_closed_the_connection++; } catch (DevFailed &e) { err = e.errors; } epos->second.device->set_transparency_reconnection(old_transp); unsigned int cb_nb = epos->second.callback_list.size(); unsigned int cb_ctr = 0; AttributeInfoEx *aie_copy = NULL; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { cb_ctr++; FwdAttrConfEventData *event_data; string ev_name(epos->second.event_name); string::size_type pos = ev_name.find(EVENT_COMPAT); if (pos != string::npos) ev_name.erase(0,EVENT_COMPAT_IDL5_SIZE); if (cb_ctr != cb_nb) { aie_copy = new AttributeInfoEx; *aie_copy = *aie; event_data = new FwdAttrConfEventData(epos->second.device, dom_name, ev_name, aie_copy, err); } else { event_data = new FwdAttrConfEventData(epos->second.device, dom_name, ev_name, aie, err); } CallBack *callback = esspos->callback; EventQueue *ev_queue = esspos->ev_queue; // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } } else if (epos->second.event_name == EventName[INTERFACE_CHANGE_EVENT]) { // // For device interface change event // AttributeInfoListEx *aie = Tango_nullptr; CommandInfoList *cil = Tango_nullptr; DevErrorList err; err.length(0); string prefix = event_consumer->env_var_fqdn_prefix[0]; string dom_name = prefix + epos->second.device->dev_name(); bool old_transp = epos->second.device->get_transparency_reconnection(); epos->second.device->set_transparency_reconnection(true); try { aie = epos->second.device->attribute_list_query_ex(); cil = epos->second.device->command_list_query(); } catch (DevFailed &e) { delete aie; aie = Tango_nullptr; delete cil; cil = Tango_nullptr; err = e.errors; } epos->second.device->set_transparency_reconnection(old_transp); unsigned int cb_nb = epos->second.callback_list.size(); unsigned int cb_ctr = 0; CommandInfoList *cil_copy = Tango_nullptr; AttributeInfoListEx *aie_copy = Tango_nullptr; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { cb_ctr++; DevIntrChangeEventData *event_data; string ev_name(epos->second.event_name); if (cb_ctr != cb_nb) { aie_copy = new AttributeInfoListEx; *aie_copy = *aie; cil_copy = new CommandInfoList; *cil_copy = *cil; event_data = new DevIntrChangeEventData(epos->second.device, ev_name,dom_name, cil_copy,aie_copy,true, err); } else { event_data = new DevIntrChangeEventData(epos->second.device, ev_name,dom_name, cil,aie,true, err); } CallBack *callback = esspos->callback; EventQueue *ev_queue = esspos->ev_queue; // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } if (cb_ctr != cb_nb) { delete aie_copy; delete cil_copy; } else { delete aie; delete cil; } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } } else if (epos->second.event_name == EventName[PIPE_EVENT]) { // // For pipe event // DevicePipe *dp = Tango_nullptr; DevErrorList err; err.length(0); bool old_transp = epos->second.device->get_transparency_reconnection(); epos->second.device->set_transparency_reconnection(true); try { dp = new DevicePipe(); *dp = epos->second.device->read_pipe(epos->second.obj_name); } catch (DevFailed &e) { err = e.errors; } epos->second.device->set_transparency_reconnection(old_transp); unsigned int cb_nb = epos->second.callback_list.size(); unsigned int cb_ctr = 0; DevicePipe *dp_copy = NULL; for (esspos = epos->second.callback_list.begin(); esspos != epos->second.callback_list.end(); ++esspos) { cb_ctr++; PipeEventData *event_data; if (cb_ctr != cb_nb) { dp_copy = new DevicePipe(); *dp_copy = *dp; event_data = new PipeEventData(epos->second.device, domain_name, epos->second.event_name, dp_copy, err); } else { event_data = new PipeEventData(epos->second.device, domain_name, epos->second.event_name, dp, err); } CallBack *callback = esspos->callback; EventQueue *ev_queue = esspos->ev_queue; if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::run_undetached() exception in callback method of " << epos->first; au->print_error_message(ss.str().c_str()); } delete event_data; } // no calback method, the event has to be inserted // into the event queue else { ev_queue->insert_event(event_data); } } } } } //--------------------------------------------------------------------------------------------------------------------- // // method : // EventConsumerKeepAliveThread::stateless_subscription_failed // // description : // // argument : // in : // - vpos : An iterator in the vector of non-connected event for the concerned event // - e : The received exception // - now : When the exception was received // //-------------------------------------------------------------------------------------------------------------------- void EventConsumerKeepAliveThread::stateless_subscription_failed(vector::iterator &vpos,DevFailed &e,time_t &now) { // // Subscribe has not worked, try again in the next hearbeat period // vpos->last_heartbeat = now; // // The event can still not be connected. Send the return error message as event to the client application. // Push an event with the error message! // DevErrorList err; err.length(0); string domain_name = vpos->prefix + vpos->device->dev_name(); if (vpos->event_name != EventName[INTERFACE_CHANGE_EVENT]) domain_name = domain_name + "/" + vpos->attribute; err = e.errors; // // For attribute data event // if ((vpos->event_name == "change") || (vpos->event_name == "quality") || (vpos->event_name == "archive") || (vpos->event_name == "periodic") || (vpos->event_name == "user_event")) { DeviceAttribute *da = NULL; FwdEventData *event_data = new FwdEventData(vpos->device, domain_name, vpos->event_name, da, err); // if a callback method was specified, call it! if (vpos->callback != NULL ) { try { vpos->callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::stateless_subscription_failed() exception in callback method of " << domain_name; au->print_error_message(ss.str().c_str()); } delete event_data; } // // no callback method, the event has to be instered into the event queue // else { vpos->ev_queue->insert_event(event_data); } } // // For attribute configuration event // else if (vpos->event_name == CONF_TYPE_EVENT) { AttributeInfoEx *aie = NULL; AttrConfEventData *event_data = new AttrConfEventData(vpos->device, domain_name, vpos->event_name, aie, err); // // If a callback method was specified, call it! // if (vpos->callback != NULL ) { try { vpos->callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::stateless_subscription_failed() exception in callback method of " << domain_name; au->print_error_message(ss.str().c_str()); } //event_data->attr_conf = NULL; delete event_data; } // // No calback method, the event has to be inserted into the event queue // else { vpos->ev_queue->insert_event(event_data); } } else if (vpos->event_name == DATA_READY_TYPE_EVENT) { DataReadyEventData *event_data = new DataReadyEventData(vpos->device,NULL,vpos->event_name,err); // // If a callback method was specified, call it! // if (vpos->callback != NULL ) { try { vpos->callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::stateless_subscription_failed() exception in callback method of " << domain_name; au->print_error_message(ss.str().c_str()); } delete event_data; } // // No callback method, the event has to be inserted into the event queue // else vpos->ev_queue->insert_event(event_data); } else if (vpos->event_name == EventName[INTERFACE_CHANGE_EVENT]) { DevIntrChangeEventData *event_data = new DevIntrChangeEventData(vpos->device,vpos->event_name, domain_name,(CommandInfoList *)NULL, (AttributeInfoListEx *)NULL,false,err); // // If a callback method was specified, call it! // if (vpos->callback != NULL ) { try { vpos->callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::stateless_subscription_failed() exception in callback method of " << domain_name; au->print_error_message(ss.str().c_str()); } delete event_data; } // // No callback method, the event has to be inserted into the event queue // else vpos->ev_queue->insert_event(event_data); } else if (vpos->event_name == EventName[PIPE_EVENT]) { PipeEventData *event_data = new PipeEventData(vpos->device,domain_name,vpos->event_name, (DevicePipe *)NULL,err); // // If a callback method was specified, call it! // if (vpos->callback != NULL ) { try { vpos->callback->push_event(event_data); } catch (...) { ApiUtil *au = ApiUtil::instance(); stringstream ss; ss << "EventConsumerKeepAliveThread::stateless_subscription_failed() exception in callback method of " << domain_name; au->print_error_message(ss.str().c_str()); } delete event_data; } // // No callback method, the event has to be inserted into the event queue // else vpos->ev_queue->insert_event(event_data); } } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/client/eventqueue.cpp0000644023471100065110000006122313034744772015445 00000000000000static const char *RcsId = "$Id: eventqueue.cpp 27410 2015-01-27 05:46:17Z taurel $\n$Name$"; //=================================================================================================================== // // file : eventqueue.cpp // // description : Implementation of the event queue classes for all Tango events // // project : TANGO // // author(s) : J. Meyer // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision: 27410 $ // //=================================================================================================================== #include #include namespace Tango { //////////////////////////////////////////////////////////////////////////// // EventQueue class implementation //////////////////////////////////////////////////////////////////////////// //+------------------------------------------------------------------------------------------------------------------ // // method : // EventQueue::EventQueue // // description : // Two constructors for the EventQueue class. The first one does not take any argument and will allow unlimited // event buffering. The second one creates a circular buffer with the maximum size given as argument. // // argument : // in : // - max_size : the maximum buffer size // //------------------------------------------------------------------------------------------------------------------ EventQueue::EventQueue() { max_elt = 0; insert_elt = 0; nb_elt = 0; } EventQueue::EventQueue(long max_size) { if ( max_size == 0 ) max_elt = 0; else max_elt = max_size; insert_elt = 0; nb_elt = 0; } //+------------------------------------------------------------------------------------------------------------------ // // method : // EventQueue::EventQueue // // description : // The class destructor. It frees all the memory allocated to store event data. // //------------------------------------------------------------------------------------------------------------------- EventQueue::~EventQueue() { cout3 << "Entering EventQueue::~EventQueue nb_elt = " << nb_elt << endl; // // lock the event queue // omni_mutex_lock l(modification_mutex); long nb = nb_elt; // // check whether the events are not attribute configuration events // if (event_buffer.size() > 0 ) { for (long i=0; i 0) { for (long i=0; iget_date(); } else { return event_buffer[insert_elt - 1]->get_date(); } } else { if ( conf_event_buffer.empty() == false ) { if (insert_elt == 0) { return conf_event_buffer[max_elt - 1]->get_date(); } else { return conf_event_buffer[insert_elt - 1]->get_date(); } } else { if ( ready_event_buffer.empty() == false ) { if (insert_elt == 0) return ready_event_buffer[max_elt - 1]->get_date(); else return conf_event_buffer[insert_elt - 1]->get_date(); } else { TangoSys_OMemStream o; o << "No new events available!\n"; o << "Cannot return any event date" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventQueue::get_last_event_date()"); } } } // Should never reach here. To make compiler happy struct TimeVal tv; tv.tv_sec = tv.tv_usec = tv.tv_nsec = 0; return tv; } //------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Return a vector with all events in the circular buffer. Events are kept in the buffer since the last extraction // with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // out : // - event_list : Reference to the array where events should be stored // //------------------------------------------------------------------------------------------------------------------ void EventQueue::get_events(EventDataList &event_list) { cout3 << "Entering EventQueue::get_events" << endl; // lock the event queue omni_mutex_lock l(modification_mutex); // // Set index to read the ring buffer and to initialise the vector // of pointers to return. // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = nb_elt - 1; // prepare the vector to be returned event_list.clear(); event_list.resize(nb_elt); // // Read buffer // for (long i=0; i < nb_elt; i++) { event_list[seq_index] = event_buffer[index]; // we do not want to free the event data when cleaning-up // the vector event_buffer[index] = NULL; if (index == 0) index = max_elt; index--; seq_index--; } // empty the event queue now event_buffer.clear(); insert_elt = 0; nb_elt = 0; cout3 << "EventQueue::get_events() : size = " << event_list.size() << endl; return; } //-------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Return a vector with all events in the circular buffer. Events are kept in the buffer since the last extraction // with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // out : // - event_list : Reference to the array where events should be stored // //-------------------------------------------------------------------------------------------------------------------- void EventQueue::get_events(AttrConfEventDataList &event_list) { cout3 << "Entering EventQueue::get_events" << endl; // lock the event queue omni_mutex_lock l(modification_mutex); // // Set index to read the ring buffer and to initialise the vector // of pointers to return. // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = nb_elt - 1; // prepare the vector to be returned event_list.clear(); event_list.resize(nb_elt); // // Read buffer // for (long i=0; i < nb_elt; i++) { event_list[seq_index] = conf_event_buffer[index]; // we do not want to free the event data when cleaning-up // the vector conf_event_buffer[index] = NULL; if (index == 0) index = max_elt; index--; seq_index--; } // empty the event queue now conf_event_buffer.clear(); insert_elt = 0; nb_elt = 0; cout3 << "EventQueue::get_events() : size = " << event_list.size() << endl; return; } //------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Return a vector with all events in the circular buffer. Events are kept in the buffer since the last extraction // with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // out : // - event_list : Reference to the array where events should be stored // //-------------------------------------------------------------------------------------------------------------------- void EventQueue::get_events(DataReadyEventDataList &event_list) { cout3 << "Entering EventQueue::get_events" << endl; // lock the event queue omni_mutex_lock l(modification_mutex); // // Set index to read the ring buffer and to initialise the vector // of pointers to return. // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = nb_elt - 1; // prepare the vector to be returned event_list.clear(); event_list.resize(nb_elt); // // Read buffer // for (long i=0; i < nb_elt; i++) { event_list[seq_index] = ready_event_buffer[index]; // we do not want to free the event data when cleaning-up // the vector ready_event_buffer[index] = NULL; if (index == 0) index = max_elt; index--; seq_index--; } // empty the event queue now ready_event_buffer.clear(); insert_elt = 0; nb_elt = 0; cout3 << "EventQueue::get_events() : size = " << event_list.size() << endl; return; } //------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Return a vector with all events in the circular buffer. Events are kept in the buffer since the last extraction // with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // out : // - event_list : Reference to the array where events should be stored // //-------------------------------------------------------------------------------------------------------------------- void EventQueue::get_events(DevIntrChangeEventDataList &event_list) { cout3 << "Entering EventQueue::get_events" << endl; // // lock the event queue // omni_mutex_lock l(modification_mutex); // // Set index to read the ring buffer and to initialise the vector of pointers to return. // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = nb_elt - 1; // // prepare the vector to be returned // event_list.clear(); event_list.resize(nb_elt); // // Read buffer // for (long i=0; i < nb_elt; i++) { event_list[seq_index] = dev_inter_event_buffer[index]; // // we do not want to free the event data when cleaning-up // the vector // dev_inter_event_buffer[index] = NULL; if (index == 0) index = max_elt; index--; seq_index--; } // // empty the event queue now // dev_inter_event_buffer.clear(); insert_elt = 0; nb_elt = 0; cout3 << "EventQueue::get_events() : size = " << event_list.size() << endl; return; } //------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Return a vector with all events in the circular buffer. Events are kept in the buffer since the last extraction // with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // out : // - event_list : Reference to the array where events should be stored // //-------------------------------------------------------------------------------------------------------------------- void EventQueue::get_events(PipeEventDataList &event_list) { cout3 << "Entering EventQueue::get_events" << endl; // // lock the event queue // omni_mutex_lock l(modification_mutex); // // Set index to read the ring buffer and to initialise the vector of pointers to return. // In the returned sequence , indice 0 is the oldest data // long index = insert_elt; if (index == 0) index = max_elt; index--; long seq_index = nb_elt - 1; // // prepare the vector to be returned // event_list.clear(); event_list.resize(nb_elt); // // Read buffer // for (long i=0; i < nb_elt; i++) { event_list[seq_index] = pipe_event_buffer[index]; // // we do not want to free the event data when cleaning-up // the vector // pipe_event_buffer[index] = NULL; if (index == 0) index = max_elt; index--; seq_index--; } // // empty the event queue now // pipe_event_buffer.clear(); insert_elt = 0; nb_elt = 0; cout3 << "EventQueue::get_events() : size = " << event_list.size() << endl; return; } //------------------------------------------------------------------------------------------------------------------- // // method : // EventQueue::get_events // // description : // Call the callback method for all events in the circular buffer. Events are kept in the buffer since the last // extraction with get_events(). After returning the event data, the circular buffer gets emptied! // // argument : // in : // - cb : CallBack object ptr // //------------------------------------------------------------------------------------------------------------------- void EventQueue::get_events(CallBack *cb) { cout3 << "Entering EventQueue::get_events" << endl; if ( cb == NULL ) { TangoSys_OMemStream o; o << "No callback object given!\n"; o << "Cannot return any event data" << ends; EventSystemExcept::throw_exception((const char *)API_EventQueues, o.str(), (const char *)"EventQueue::get_events()"); } // // Check the event type // if ( event_buffer.empty() == false ) { // // Get event data for a local data copy. The event reception should not be blocked in case of a problem in the callback // method! // EventDataList event_list; get_events (event_list); // // Loop over all events // EventDataList::iterator vpos; for (vpos=event_list.begin(); vpos!=event_list.end(); ++vpos) { // // call the callback method // try { cb->push_event(*vpos); } catch (...) { cerr << "Tango::EventQueue::get_events() exception in callback method \nfor attribute " << (*vpos)->attr_name << "with event type " << (*vpos)->event << endl; } } } else if ( conf_event_buffer.empty() == false ) { // // Get event data for a local data copy. The event reception should not be blocked in case of a problem in the callback // method! // AttrConfEventDataList attr_conf_event_list; get_events (attr_conf_event_list); // // Loop over all events // AttrConfEventDataList::iterator vpos; for (vpos=attr_conf_event_list.begin(); vpos!=attr_conf_event_list.end(); ++vpos) { // // call the callback method // try { cb->push_event(*vpos); } catch (...) { cerr << "Tango::EventQueue::get_events() exception in callback method \nfor attribute " << (*vpos)->attr_name << "with event type " << (*vpos)->event << endl; } } } else if ( dev_inter_event_buffer.empty() == false ) { // // Get event data for a local data copy. The event reception should not be blocked in case of a problem in the callback // method! // DevIntrChangeEventDataList dev_intr_event_list; get_events (dev_intr_event_list); // // Loop over all events // DevIntrChangeEventDataList::iterator vpos; for (vpos=dev_intr_event_list.begin(); vpos!=dev_intr_event_list.end(); ++vpos) { // // call the callback method // try { cb->push_event(*vpos); } catch (...) { cerr << "Tango::EventQueue::get_events() exception in callback method \nfor device " << (*vpos)->device_name << "with event type " << (*vpos)->event << endl; } } } else { // // Get event data for a local data copy. The event reception should not be blocked in case of a problem in the callback // method! // DataReadyEventDataList d_ready_event_list; get_events (d_ready_event_list); // // Loop over all events // DataReadyEventDataList::iterator vpos; for (vpos=d_ready_event_list.begin(); vpos!=d_ready_event_list.end(); ++vpos) { // // call the callback method // try { cb->push_event(*vpos); } catch (...) { cerr << "Tango::EventQueue::get_events() exception in callback method \nfor attribute " << (*vpos)->attr_name << "with event type " << (*vpos)->event << endl; } } } } } // End of Tango namespace tango-9.2.5a/lib/cpp/client/notifdeventconsumer.cpp0000644023471100065110000010431213034744772017355 00000000000000static const char *RcsId = "$Id$"; //////////////////////////////////////////////////////////////////////////////// /// /// file notifdeventconsumer.cpp /// /// C++ classes for implementing the event consumer /// singleton class when used with notifd /// /// author(s) : E.Taurel /// /// original : 16 August 2011 /// // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . /// /// $Revision$ /// /// //////////////////////////////////////////////////////////////////////////////// #include #include #include #ifdef _TG_WINDOWS_ #include #include #else #include #include #endif using namespace CORBA; namespace Tango { NotifdEventConsumer *NotifdEventConsumer::_instance = NULL; omni_mutex EventConsumer::ev_consumer_inst_mutex; void NotifdEventConsumer::disconnect_structured_push_consumer() { cout3 << "calling Tango::NotifdEventConsumer::disconnect_structured_push_consumer() \n"; } void NotifdEventConsumer::offer_change(TANGO_UNUSED(const CosNotification::EventTypeSeq& added), TANGO_UNUSED(const CosNotification::EventTypeSeq& deled)) { cout3 << "calling Tango::NotifdEventConsumer::subscription_change() \n"; } /************************************************************************/ /* */ /* NotifdEventConsumer class */ /* ------------------- */ /* */ /************************************************************************/ NotifdEventConsumer::NotifdEventConsumer(ApiUtil *ptr) : EventConsumer(ptr),omni_thread((void *)ptr) { cout3 << "calling Tango::NotifdEventConsumer::NotifdEventConsumer() \n"; orb_ = ptr->get_orb(); _instance = this; start_undetached(); } NotifdEventConsumer *NotifdEventConsumer::create() { omni_mutex_lock guard(ev_consumer_inst_mutex); // // check if the NotifdEventConsumer singleton exists, if so return it // if (_instance != NULL) { return _instance; } // // NotifdEventConsumer singleton does not exist, create it // ApiUtil *ptr = ApiUtil::instance(); return new NotifdEventConsumer(ptr); } //+---------------------------------------------------------------------------- // // method : NotifdEventConsumer::run_undetached() // // description : Activate the CORBA POA for the server embedded in client // when it receives events. // Run the CORBA orb. // //----------------------------------------------------------------------------- void *NotifdEventConsumer::run_undetached(void *arg) { // // activate POA and go into endless loop waiting for events to be pushed // this method should run as a separate thread so as not to block the client // ApiUtil *api_util_ptr = (ApiUtil *)arg; if (api_util_ptr->in_server() == false) { CORBA::Object_var obj = orb_->resolve_initial_references("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow(obj); PortableServer::POAManager_var pman = poa->the_POAManager(); pman->activate(); orb_->run(); orb_->destroy(); CORBA::release(orb_); } return (void *)NULL; } //+---------------------------------------------------------------------------- // // method : NotifdEventConsumer::cleanup_EventChannel_map() // // description : Method to destroy the DeviceProxy objects // stored in the EventChannel map // //----------------------------------------------------------------------------- void NotifdEventConsumer::cleanup_EventChannel_map() { std::map::iterator epos; EvChanIte evt_it; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { EventCallBackStruct &evt_cb = epos->second; evt_it = channel_map.find(evt_cb.channel_name); EventChannelStruct &evt_ch = evt_it->second; if (evt_ch.channel_type == NOTIFD) { try { CosNotifyFilter::Filter_var f = evt_ch.structuredProxyPushSupplier->get_filter(evt_cb.filter_id); evt_ch.structuredProxyPushSupplier->remove_filter(evt_cb.filter_id); f->destroy(); } catch(...) { cerr << "Could not remove filter from notification daemon for " << evt_cb.channel_name << endl; } } } for (evt_it = channel_map.begin(); evt_it != channel_map.end(); ++evt_it) { EventChannelStruct &evt_ch = evt_it->second; if (evt_ch.adm_device_proxy != NULL) { AutoTangoMonitor _mon(evt_ch.channel_monitor); if (evt_ch.channel_type == NOTIFD) { try { // Destroy the filter created in the // notification service for the heartbeat event CosNotifyFilter::Filter_var f = evt_ch.structuredProxyPushSupplier->get_filter(evt_ch.heartbeat_filter_id); evt_ch.structuredProxyPushSupplier->remove_filter(evt_ch.heartbeat_filter_id); f->destroy(); // disconnect the pushsupplier to stop receiving events //cout << "EventConsumer::cleanup_EventChannel_map(): Disconnect push supplier!" << endl; evt_ch.structuredProxyPushSupplier->disconnect_structured_push_supplier(); } catch(...) { cerr << "Could not remove heartbeat filter from notification daemon for " << evt_ch.full_adm_name << endl; } // Release the connection to the device server administration device delete evt_ch.adm_device_proxy; evt_ch.adm_device_proxy = NULL; } } } } //+---------------------------------------------------------------------------- // // method : EventConsumer::connect_event_system() // // description : Connect to the real event (archive, change, periodic,...) // // argument : in : - device_name : The device fqdn (lower case) // - att_name : The attribute name // - event_name : The event name // - filters : The event filters given by the user // - evt_it : Iterator pointing to the event channel entry // in channel_map map // - new_event_callback : Structure used for the event callback // entry in the event_callback_map // - dd : The data returned by the DS admin device // xxxSubscriptionChange command // - valid_end : Valid endpoint in case the DS has retruned several // possible endpoints // //----------------------------------------------------------------------------- void NotifdEventConsumer::connect_event_system(string &device_name,string &att_name,string &event_name, const vector &filters,EvChanIte &evt_it, EventCallBackStruct &new_event_callback,TANGO_UNUSED(DeviceData &dd), TANGO_UNUSED(size_t valid_end)) { // // Build a filter using the CORBA Notify constraint Language // (use attribute name in lowercase letters) // CosNotifyFilter::FilterFactory_var ffp; CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); CosNotifyFilter::FilterID filter_id; try { EventChannelStruct &evt_ch = evt_it->second; { AutoTangoMonitor _mon(evt_ch.channel_monitor); ffp = evt_ch.eventChannel->default_filter_factory(); filter = ffp->create_filter("EXTENDED_TCL"); } } catch (CORBA::COMM_FAILURE &) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught CORBA::COMM_FAILURE exception while creating event filter (check filter)", (const char*)"NotifdEventConsumer::connect_event_system()"); } catch (...) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while creating event filter (check filter)", (const char*)"NotifdEventConsumer::connect_event_system()"); } // // Construct a simple constraint expression; add it to fadmin // // The device name received by this method is the FQDN, remove the // protocol prefix // string tmp_dev_name(device_name); string::size_type pos; pos = tmp_dev_name.find("://"); pos = pos + 3; pos = tmp_dev_name.find('/',pos); ++pos; string d_name = tmp_dev_name.substr(pos,tmp_dev_name.size() - pos); char constraint_expr[512]; ::sprintf(constraint_expr,"$domain_name == \'%s/%s\' and $event_name == \'%s\'", d_name.c_str(),att_name.c_str(),event_name.c_str()); if (filters.size() != 0) { ::strcat(&(constraint_expr[strlen(constraint_expr)])," and (("); for (unsigned int i = 0;i < filters.size();i++) { ::strcat(&(constraint_expr[strlen(constraint_expr)]),filters[i].c_str()); if (i != filters.size() - 1) ::strcat(&(constraint_expr[strlen(constraint_expr)])," and "); } ::strcat(&(constraint_expr[strlen(constraint_expr)]),") or $forced_event > 0.5)"); } CosNotification::EventTypeSeq evs; CosNotifyFilter::ConstraintExpSeq exp; exp.length(1); exp[0].event_types = evs; exp[0].constraint_expr = CORBA::string_dup(constraint_expr); CORBA::Boolean res = 0; // OK try { CosNotifyFilter::ConstraintInfoSeq_var dummy = filter->add_constraints(exp); filter_id = evt_it->second.structuredProxyPushSupplier->add_filter(filter); new_event_callback.filter_id = filter_id; new_event_callback.filter_constraint = constraint_expr; } catch(CosNotifyFilter::InvalidConstraint &) { //cerr << "Exception thrown : Invalid constraint given " // << (const char *)constraint_expr << endl; res = 1; } catch (...) { //cerr << "Exception thrown while adding constraint " // << (const char *)constraint_expr << endl; res = 1; } // // If error, destroy filter. Else, set the filter_ok flag to true // if (res == 1) { try { filter->destroy(); } catch (...) { } filter = CosNotifyFilter::Filter::_nil(); EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while creating event filter (check filter)", (const char*)"NotifdEventConsumer::connect_event_system()"); } else { new_event_callback.filter_ok = true; } } //+---------------------------------------------------------------------------- // // method : NotifdEventConsumer::connect_event_channel() // // description : Connect to the event channel // This means connect to the heartbeat event // // Args in : - channel name : The event channel name (DS admin name) // - db : Database object // - reconnect: Flag set to true in case this method is called for // event reconnection purpose // - dd : The DS admin device command returned data // (ZmqEventSubscriptionChange command) // //----------------------------------------------------------------------------- void NotifdEventConsumer::connect_event_channel(string &channel_name,Database *db,bool reconnect,TANGO_UNUSED(DeviceData &dd)) { CORBA::Any_var received; const DevVarLongStringArray *dev_import_list; // // Get a reference to an EventChannel for this device server from the // TANGO database or from the DS admin device (for device in a DS // started with the -file option) // int channel_exported; string channel_ior; string hostname; if (db != NULL) { // // Remove extra info from channel name (protocol, dbase=xxx) // string local_channel_name(channel_name); string::size_type pos; if ((pos = local_channel_name.find('#')) != string::npos) local_channel_name.erase(pos); if ((pos = local_channel_name.find("://")) != string::npos) { pos = pos + 3; if ((pos = local_channel_name.find('/',pos)) != string::npos) local_channel_name.erase(0,pos + 1); } // // Import channel event // try { received = db->import_event(local_channel_name); } catch (...) { TangoSys_OMemStream o; o << channel_name; o << " has no event channel defined in the database\n"; o << "Maybe the server is not running or is not linked with Tango release 4.x (or above)... " << ends; Except::throw_exception((const char *)API_NotificationServiceFailed, o.str(), (const char *)"NotifdEventConsumer::connect_event_channel"); } received.inout() >>= dev_import_list; channel_ior = string((dev_import_list->svalue)[1]); channel_exported = dev_import_list->lvalue[0]; // get the hostname where the notifyd should be running hostname = string (dev_import_list->svalue[3]); } else { DeviceProxy adm(channel_name); try { DeviceData ddd; ddd = adm.command_inout("QueryEventChannelIOR"); ddd >> channel_ior; channel_exported = true; // get the hostname where the notifyd should be running DeviceInfo info = adm.info(); hostname = info.server_host; } catch (...) { TangoSys_OMemStream o; o << channel_name; o << " has no event channel\n"; o << "Maybe the server is not running or is not linked with Tango release 4.x (or above)... " << ends; Except::throw_exception((const char *)API_NotificationServiceFailed, o.str(), (const char *)"NotifdEventConsumer::connect_event_channel"); } } if (channel_exported) { try { CORBA::Object *event_channel_obj; event_channel_obj = orb_ -> string_to_object(channel_ior.c_str()); if (event_channel_obj -> _non_existent()) event_channel_obj = CORBA::Object::_nil(); eventChannel = CosNotifyChannelAdmin::EventChannel::_nil(); eventChannel = CosNotifyChannelAdmin::EventChannel::_narrow(event_channel_obj); if(CORBA::is_nil(eventChannel)) { channel_exported = 0; } } catch (...) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to narrow EventChannel from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } } else { EventSystemExcept::throw_exception((const char*)"API_EventChannelNotExported", (const char*)"Failed to narrow EventChannel (hint: make sure a notifd process is running on the server host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } // // Obtain a Consumer Admin // // // We'll use the channel's default Consumer admin // try { consumerAdmin = eventChannel->default_consumer_admin(); if (CORBA::is_nil(consumerAdmin)) { //cerr << "Could not get CosNotifyChannelAdmin::ConsumerAdmin" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to get default Consumer admin from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } } catch (...) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to get default Consumer admin from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } // // Obtain a Proxy Supplier // // // We are using the "Push" model and Structured data // try { proxySupplier = consumerAdmin -> obtain_notification_push_supplier(CosNotifyChannelAdmin::STRUCTURED_EVENT, proxyId); if (CORBA::is_nil(proxySupplier)) { //cerr << "Could not get CosNotifyChannelAdmin::ProxySupplier" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to obtain a push supplier from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } structuredProxyPushSupplier = CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow( proxySupplier); if (CORBA::is_nil(structuredProxyPushSupplier)) { //cerr << "Tango::NotifdEventConsumer::NotifdEventConsumer() could not get CosNotifyChannelAdmin::StructuredProxyPushSupplier" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to narrow the push supplier from notification daemon (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } // // Set a large timeout on this CORBA object // This is necessary in case of maany threads doing subscribe/unsubscribe as fast as they can // omniORB::setClientCallTimeout(structuredProxyPushSupplier,20000); } catch(const CosNotifyChannelAdmin::AdminLimitExceeded&) { EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Failed to get PushSupplier from notification daemon due to AdminLimitExceeded (hint: make sure the notifd process is running on this host)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } // // Connect to the Proxy Consumer // try { structuredProxyPushSupplier -> connect_structured_push_consumer(_this()); } catch(const CosEventChannelAdmin::AlreadyConnected&) { cerr << "Tango::NotifdEventConsumer::NotifdEventConsumer() caught AlreadyConnected exception" << endl; } EvChanIte evt_it = channel_map.end(); if (reconnect == true) { evt_it = channel_map.find(channel_name); EventChannelStruct &evt_ch = evt_it->second; evt_ch.eventChannel = eventChannel; evt_ch.structuredProxyPushSupplier = structuredProxyPushSupplier; evt_ch.last_heartbeat = time(NULL); evt_ch.heartbeat_skipped = false; evt_ch.notifyd_host = hostname; evt_ch.event_system_failed = false; evt_ch.has_notifd_closed_the_connection = 0; } else { EventChannelStruct new_event_channel_struct; new_event_channel_struct.eventChannel = eventChannel; new_event_channel_struct.structuredProxyPushSupplier = structuredProxyPushSupplier; new_event_channel_struct.last_heartbeat = time(NULL); new_event_channel_struct.heartbeat_skipped = false; new_event_channel_struct.adm_device_proxy = NULL; // create a channel monitor new_event_channel_struct.channel_monitor = new TangoMonitor(channel_name.c_str()); // set the timeout for the channel monitor to 1000ms not to block the event consumer for to long. new_event_channel_struct.channel_monitor->timeout(1000); set_channel_type(new_event_channel_struct); channel_map[channel_name] = new_event_channel_struct; evt_it = channel_map.find(channel_name); EventChannelStruct &evt_ch = evt_it->second; evt_ch.notifyd_host = hostname; evt_ch.event_system_failed = false; evt_ch.has_notifd_closed_the_connection = 0; } // // add a filter for heartbeat events // char constraint_expr[256]; ::sprintf(constraint_expr,"$event_name == \'heartbeat\'"); CosNotifyFilter::FilterFactory_var ffp; CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); try { ffp = evt_it->second.eventChannel->default_filter_factory(); filter = ffp->create_filter("EXTENDED_TCL"); } catch (...) { //cerr << "Caught exception obtaining filter object" << endl; EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while creating heartbeat filter (check filter)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } // // Construct a simple constraint expression; add it to fadmin // CosNotification::EventTypeSeq evs; CosNotifyFilter::ConstraintExpSeq exp; exp.length(1); exp[0].event_types = evs; exp[0].constraint_expr = CORBA::string_dup(constraint_expr); CORBA::Boolean res = 0; // OK try { CosNotifyFilter::ConstraintInfoSeq_var dummy = filter->add_constraints(exp); evt_it->second.heartbeat_filter_id = evt_it->second.structuredProxyPushSupplier->add_filter(filter); } catch (...) { res = 1; // error } // // If error, destroy filter // if (res == 1) { try { filter->destroy(); } catch (...) { } filter = CosNotifyFilter::Filter::_nil(); EventSystemExcept::throw_exception((const char*)API_NotificationServiceFailed, (const char*)"Caught exception while adding constraint for heartbeat (check filter)", (const char*)"NotifdEventConsumer::connect_event_channel()"); } } //+---------------------------------------------------------------------------- // // method : NotifdEventConsumer::push_structured_event() // // description : Method run when an event is received // // argument : in : event : The event itself... // //----------------------------------------------------------------------------- void NotifdEventConsumer::push_structured_event(const CosNotification::StructuredEvent& event) { string domain_name(event.header.fixed_header.event_type.domain_name); string event_type(event.header.fixed_header.event_type.type_name); string event_name(event.header.fixed_header.event_name); // cout << "Received event: domain_name = " << domain_name << ", event_type = " << event_type << ", event_name = " << event_name << endl; bool svr_send_tg_host = false; if (event_name == "heartbeat") { string fq_dev_name = domain_name; if (event_type.find("tango://") != string::npos) { if (event_type.find("#") == string::npos) fq_dev_name.insert(0,event_type); else { fq_dev_name.insert(0,event_type,0,event_type.size() - 1); fq_dev_name = fq_dev_name + MODIFIER_DBASE_NO; } svr_send_tg_host = true; } else fq_dev_name.insert(0,env_var_fqdn_prefix[0]); // only reading from the maps map_modification_lock.readerIn(); std::map::iterator ipos; ipos = channel_map.find(fq_dev_name); // // Search for entry within the channel_map map using // 1 - The fully qualified device name // 2 - The fully qualified device name but with the Tango database host name specifed without fqdn // (in case of) // 3 - The device name (for old servers) // if (ipos == channel_map.end()) { string::size_type pos,end; if ((pos = event_type.find('.')) != string::npos) { end = event_type.find(':',pos); fq_dev_name.erase(pos,end - pos); ipos = channel_map.find(fq_dev_name); if (ipos == channel_map.end()) ipos = channel_map.find(domain_name); } else { ipos = channel_map.find(domain_name); } } // // Special case for Tango system with multiple db server // // The event carry info for only one of the multiple db server // The client also has to know the list of db servers (via the TANGO_HOST) // Find the event db server in the client list of db server and if found, // replace in the fqdn the event db server with the first one in the client // list. The first db server is the one used to create the entry in the map // if (ipos == channel_map.end() && svr_send_tg_host == true) { string svc_tango_host = event_type.substr(8,event_type.size() - 9); unsigned int i = 0; for (i = 1;i < env_var_fqdn_prefix.size();i++) { if (env_var_fqdn_prefix[i].find(svc_tango_host) != string::npos) { fq_dev_name = domain_name; fq_dev_name.insert(0,env_var_fqdn_prefix[0]); break; } } if (i != env_var_fqdn_prefix.size()) { ipos = channel_map.find(fq_dev_name); } } if (ipos != channel_map.end()) { EventChannelStruct &evt_ch = ipos->second; try { AutoTangoMonitor _mon(evt_ch.channel_monitor); evt_ch.last_heartbeat = time(NULL); } catch (...) { cerr << "Tango::NotifdEventConsumer::push_structured_event() timeout on channel monitor of " << ipos->first << endl; } } map_modification_lock.readerOut(); } else { string fq_dev_name = domain_name; if (event_type.find("tango://") != string::npos) { if (event_type.find("#") == string::npos) fq_dev_name.insert(0,event_type); else { fq_dev_name.insert(0,event_type,0,event_type.size() - 1); fq_dev_name = fq_dev_name + MODIFIER_DBASE_NO; } svr_send_tg_host = true; } else fq_dev_name.insert(0,env_var_fqdn_prefix[0]); map_modification_lock.readerIn(); bool map_lock = true; // // Search for entry within the event_callback map using // 1 - The fully qualified attribute event name // 2 - The fully qualified attribute event name but with the Tango database host name specifed without fqdn // (in case of) // 3 - In case of Tango system with multi db server, replace the db server defined by // the event with the first one in the client list (like for the heartbeat event) // string attr_event_name = fq_dev_name + "." + event_name; map::iterator ipos; ipos = event_callback_map.find(attr_event_name); if (ipos == event_callback_map.end()) { string::size_type pos,end; if ((pos = event_type.find('.')) != string::npos) { end = event_type.find(':',pos); attr_event_name.erase(pos,end - pos); ipos = event_callback_map.find(attr_event_name); if (ipos == event_callback_map.end() && svr_send_tg_host == true) { string svc_tango_host = event_type.substr(8,event_type.size() - 9); unsigned int i = 0; for (i = 1;i < env_var_fqdn_prefix.size();i++) { if (env_var_fqdn_prefix[i].find(svc_tango_host) != string::npos) { fq_dev_name = domain_name; fq_dev_name.insert(0,env_var_fqdn_prefix[0]); attr_event_name = fq_dev_name + "." + event_name; break; } } if (i != env_var_fqdn_prefix.size()) ipos = event_callback_map.find(attr_event_name); } } } if (ipos != event_callback_map.end()) { EventCallBackStruct &evt_cb = ipos->second; try { AutoTangoMonitor _mon(evt_cb.callback_monitor); AttributeValue *attr_value = NULL; AttributeValue_3 *attr_value_3 = NULL; AttributeValue_4 *attr_value_4 = NULL; AttributeConfig_2 *attr_conf_2 = NULL; AttributeConfig_3 *attr_conf_3 = NULL; AttributeInfoEx *attr_info_ex = NULL; AttDataReady *att_ready = NULL; DevErrorList errors; bool ev_attr_conf = false; bool ev_attr_ready = false; const DevErrorList *err_ptr = NULL; // // Check if the event transmit error // DeviceAttribute *dev_attr = NULL; CORBA::TypeCode_var ty = event.remainder_of_body.type(); if (ty->kind() == tk_struct) { CORBA::String_var st_name; st_name = ty->name(); const char *tmp_ptr = st_name.in(); long vers; if (::strcmp(tmp_ptr,"AttributeValue_4") == 0) { dev_attr = new (DeviceAttribute); event.remainder_of_body >>= attr_value_4; vers = 4; attr_to_device(attr_value_4,dev_attr); } else if (::strcmp(tmp_ptr,"AttributeValue_3") == 0) { dev_attr = new (DeviceAttribute); event.remainder_of_body >>= attr_value_3; vers = 3; attr_to_device(attr_value,attr_value_3,vers,dev_attr); } else if (::strcmp(tmp_ptr,"AttributeValue") == 0) { dev_attr = new (DeviceAttribute); event.remainder_of_body >>= attr_value; vers = 2; attr_to_device(attr_value,attr_value_3,vers,dev_attr); } else if (::strcmp(tmp_ptr,"AttributeConfig_2") == 0) { event.remainder_of_body >>= attr_conf_2; vers = 2; attr_info_ex = new AttributeInfoEx(); *attr_info_ex = attr_conf_2; ev_attr_conf = true; } else if (::strcmp(tmp_ptr,"AttributeConfig_3") == 0) { event.remainder_of_body >>= attr_conf_3; vers = 3; attr_info_ex = new AttributeInfoEx(); *attr_info_ex = attr_conf_3; ev_attr_conf = true; } else if (::strcmp(tmp_ptr,"AttDataReady") == 0) { event.remainder_of_body >>= att_ready; ev_attr_conf = false; ev_attr_ready = true; } else { errors.length(1); errors[0].severity = Tango::ERR; errors[0].origin = CORBA::string_dup("NotifdEventConsumer::push_structured_event()"); errors[0].reason = CORBA::string_dup(API_IncompatibleAttrDataType); errors[0].desc = CORBA::string_dup("Unknown structure used to pass attribute value (Need compilation ?)"); dev_attr = NULL; } } else { event.remainder_of_body >>= err_ptr; errors = *err_ptr; // // We need to find which type of event we have received // string::size_type pos = attr_event_name.find('.'); string att_type = attr_event_name.substr(pos + 1); if (att_type == CONF_TYPE_EVENT) ev_attr_conf = true; else if (att_type == DATA_READY_TYPE_EVENT) ev_attr_ready = true; } // // Fire the user callback // vector::iterator esspos; unsigned int cb_nb = ipos->second.callback_list.size(); unsigned int cb_ctr = 0; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { cb_ctr++; if (esspos->id > 0) { CallBack *callback; callback = esspos->callback; EventQueue *ev_queue; ev_queue = esspos->ev_queue; if (cb_ctr == cb_nb) { map_lock = false; map_modification_lock.readerOut(); } if ((ev_attr_conf == false) && (ev_attr_ready == false)) { EventData *event_data; if (cb_ctr != cb_nb) { DeviceAttribute *dev_attr_copy = NULL; if (dev_attr != NULL) { dev_attr_copy = new DeviceAttribute(); dev_attr_copy->deep_copy(*dev_attr); } event_data = new EventData(event_callback_map[attr_event_name].device, fq_dev_name, event_name, dev_attr_copy, errors); } else { event_data = new EventData (event_callback_map[attr_event_name].device, fq_dev_name, event_name, dev_attr, errors); } // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "Tango::NotifdEventConsumer::push_structured_event() exception in callback method of " << ipos->first << endl; } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else if (ev_attr_ready == false) { AttrConfEventData *event_data; if (cb_ctr != cb_nb) { AttributeInfoEx *attr_info_copy = new AttributeInfoEx(); *attr_info_copy = *attr_info_ex; event_data = new AttrConfEventData(event_callback_map[attr_event_name].device, fq_dev_name, event_name, attr_info_copy, errors); } else { event_data = new AttrConfEventData(event_callback_map[attr_event_name].device, fq_dev_name, event_name, attr_info_ex, errors); } // if callback methods were specified, call them! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "Tango::NotifdEventConsumer::push_structured_event() exception in callback method of " << ipos->first << endl; } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } else { DataReadyEventData *event_data = new DataReadyEventData(event_callback_map[attr_event_name].device, att_ready,event_name,errors); // if a callback method was specified, call it! if (callback != NULL ) { try { callback->push_event(event_data); } catch (...) { cerr << "Tango::NotifdEventConsumer::push_structured_event() exception in callback method of " << ipos->first << endl; } delete event_data; } // no calback method, the event has to be instered // into the event queue else { ev_queue->insert_event(event_data); } } } else // id < 0 { if (cb_ctr == cb_nb) { map_lock = false; map_modification_lock.readerOut(); } if ((ev_attr_conf == false) && (ev_attr_ready == false)) delete dev_attr; else if (ev_attr_ready == false) delete attr_info_ex; } } // End of for } catch (...) { // free the map lock if not already done if ( map_lock == true ) { map_modification_lock.readerOut(); } cerr << "Tango::NotifdEventConsumer::push_structured_event() timeout on callback monitor of " << ipos->first << endl; } } else { // even if nothing was found in the map, free the lock map_modification_lock.readerOut(); } } } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/client/zmqeventconsumer.cpp0000644023471100065110000034773213034744772016720 00000000000000static const char *RcsId = "$Id$"; //===================================================================================================================== // // file : zmqeventconsumer.cpp // // description : C++ classes for implementing the event consumer singleton class when used with zmq // // author(s) : E.Taurel // // original : 16 August 2011 // // Copyright (C) : 2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with Tango. // If not, see . // // $Revision$ // // //==================================================================================================================== #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #include #include #include #else #include #include #include #include #include #include #endif using namespace CORBA; namespace Tango { ZmqEventConsumer *ZmqEventConsumer::_instance = NULL; //omni_mutex EventConsumer::ev_consumer_inst_mutex; /************************************************************************/ /* */ /* ZmqEventConsumer class */ /* ---------------- */ /* */ /************************************************************************/ ZmqEventConsumer::ZmqEventConsumer(ApiUtil *ptr) : EventConsumer(ptr), omni_thread((void *)ptr),zmq_context(1),ctrl_socket_bound(false) { cout3 << "calling Tango::ZmqEventConsumer::ZmqEventConsumer() \n"; _instance = this; // // Initialize the var references // av = new AttributeValue(); av3 = new AttributeValue_3(); ac2 = new AttributeConfig_2(); ac3 = new AttributeConfig_3(); ac5 = new AttributeConfig_5(); adr = new AttDataReady(); dic = new DevIntrChange(); del = new DevErrorList(); start_undetached(); } ZmqEventConsumer *ZmqEventConsumer::create() { omni_mutex_lock guard(ev_consumer_inst_mutex); // // check if the ZmqEventConsumer singleton exists, if so return it // if (_instance != NULL) { return _instance; } // // ZmqEventConsumer singleton does not exist, create it // ApiUtil *ptr = ApiUtil::instance(); return new ZmqEventConsumer(ptr); } //------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::run_undetached() // // description : // Main method for the ZMQ event system reciving thread // //------------------------------------------------------------------------------------------------------------------- void *ZmqEventConsumer::run_undetached(TANGO_UNUSED(void *arg)) { int linger = 0; int reconnect_ivl = -1; int send_hwm = SUB_SEND_HWM; // // Store thread ID // thread_id = self()->id(); // // Create the subscriber socket used to receive heartbeats coming from different DS. This socket subscribe to // everything because dedicated publishers are used to send the heartbeat events. This socket will be connected // to all needed publishers // heartbeat_sub_sock = new zmq::socket_t(zmq_context,ZMQ_SUB); heartbeat_sub_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); try { heartbeat_sub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } catch (zmq::error_t &) { reconnect_ivl = 30000; heartbeat_sub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); } heartbeat_sub_sock->setsockopt(ZMQ_SNDHWM,&send_hwm,sizeof(send_hwm)); // // Create the subscriber socket used to receive events coming from different DS. This socket subscribe to everything // because dedicated publishers are used to send the heartbeat events. This socket will be connected to all needed // publishers // event_sub_sock = new zmq::socket_t(zmq_context,ZMQ_SUB); event_sub_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); event_sub_sock->setsockopt(ZMQ_RECONNECT_IVL,&reconnect_ivl,sizeof(reconnect_ivl)); event_sub_sock->setsockopt(ZMQ_SNDHWM,&send_hwm,sizeof(send_hwm)); // // Create the control socket (REQ/REP pattern) and binds it // control_sock = new zmq::socket_t(zmq_context,ZMQ_REP); control_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); control_sock->bind(CTRL_SOCK_ENDPOINT); set_ctrl_sock_bound(); // // Initialize poll set // zmq::pollitem_t *items = new zmq::pollitem_t [MAX_SOCKET_SUB]; int nb_poll_item = 3; items[0].socket = *control_sock; items[1].socket = *heartbeat_sub_sock; items[2].socket = *event_sub_sock; for (int loop = 0;loop < nb_poll_item;loop++) { items[loop].fd = 0; items[loop].events = ZMQ_POLLIN; items[loop].revents = 0; } // // Enter the infinite loop // while(1) { zmq::message_t received_event_name,received_endian; zmq::message_t received_call,received_event_data; zmq::message_t received_ctrl; // // Init messages used by multicast event // zmq_msg_t mcast_received_event_name; zmq_msg_t mcast_received_endian; zmq_msg_t mcast_received_call; zmq_msg_t mcast_received_event_data; // // Wait for message. The try/catch is usefull when the process is running under gdb control // try { zmq::poll(items,nb_poll_item,-1); //cout << "Awaken !!!!!!!!" << endl; } catch(zmq::error_t &e) { if (e.num() == EINTR) continue; } // // Something received by the heartbeat socket ? // if (items[1].revents & ZMQ_POLLIN) { //cout << "For the heartbeat socket" << endl; bool res; try { res = heartbeat_sub_sock->recv(&received_event_name,ZMQ_DONTWAIT); if (res == false) { print_error_message("First Zmq recv call on heartbeat socket returned false! De-synchronized event system?"); items[1].revents = 0; continue; } res = heartbeat_sub_sock->recv(&received_endian,ZMQ_DONTWAIT); if (res == false) { print_error_message("Second Zmq recv call on heartbeat socket returned false! De-synchronized event system?"); items[1].revents = 0; continue; } res = heartbeat_sub_sock->recv(&received_call,ZMQ_DONTWAIT); if (res == false) { print_error_message("Third Zmq recv call on heartbeat socket returned false! De-synchronized event system?"); items[1].revents = 0; continue; } process_heartbeat(received_event_name,received_endian,received_call); } catch (zmq::error_t &e) { print_error_message("Zmq exception while receiving heartbeat data!"); cerr << "Error number: " << e.num() << ", error message: " << e.what() << endl; items[1].revents = 0; continue; } items[1].revents = 0; } // // Something received by the event socket (TCP transport)? // if (items[2].revents & ZMQ_POLLIN) { //cout << "For the event socket" << endl; bool res; try { res = event_sub_sock->recv(&received_event_name,ZMQ_DONTWAIT); if (res == false) { print_error_message("First Zmq recv call on event socket returned false! De-synchronized event system?"); items[2].revents = 0; continue; } res = event_sub_sock->recv(&received_endian,ZMQ_DONTWAIT); if (res == false) { print_error_message("Second Zmq recv call on event socket returned false! De-synchronized event system?"); items[2].revents = 0; continue; } res = event_sub_sock->recv(&received_call,ZMQ_DONTWAIT); if (res == false) { print_error_message("Third Zmq recv call on event socket returned false! De-synchronized event system?"); items[2].revents = 0; continue; } res = event_sub_sock->recv(&received_event_data,ZMQ_DONTWAIT); if (res == false) { print_error_message("Forth Zmq recv call on event socket returned false! De-synchronized event system?"); items[2].revents = 0; continue; } process_event(received_event_name,received_endian,received_call,received_event_data); } catch (zmq::error_t &e) { print_error_message("Zmq exception while receiving event data!"); cerr << "Error number: " << e.num() << ", error message: " << e.what() << endl; items[2].revents = 0; continue; } items[2].revents = 0; } // // Something received by the control socket? // if (items[0].revents & ZMQ_POLLIN) { //cout << "For the control socket" << endl; control_sock->recv(&received_ctrl); string ret_str; bool ret = false; try { ret = process_ctrl(received_ctrl,items,nb_poll_item); ret_str = "OK"; } catch (zmq::error_t &e) { ret_str = e.what(); } catch (Tango::DevFailed &e) { ret_str = e.errors[0].desc; } zmq::message_t reply(ret_str.size()); ::memcpy((void *)reply.data(),ret_str.data(),ret_str.size()); control_sock->send(reply); if (ret == true) { delete heartbeat_sub_sock; delete control_sock; delete [] items; break; } items[0].revents = 0; } // // Something received by the event socket (mcast transport)? // // What is stored in the zmq::pollitem_t structure is the real C zmq socket, not the C++ zmq::socket_t class instance. // There is no way to create a zmq::socket_t class instance from a C zmq socket. Only in 11/2012, some C++11 move // ctor/assignment operator has been added to the socket_t class allowing creation of zmq::socket_t class from C zmq // socket. Nevertheless, today (11/2012), it is still not official // for (int loop = 3;loop < nb_poll_item;loop++) { if (items[loop].revents & ZMQ_POLLIN) { zmq_msg_init(&mcast_received_event_name); zmq_msg_init(&mcast_received_endian); zmq_msg_init(&mcast_received_call); zmq_msg_init(&mcast_received_event_data); zmq_recvmsg(items[loop].socket,&mcast_received_event_name,0); zmq_recvmsg(items[loop].socket,&mcast_received_endian,0); zmq_recvmsg(items[loop].socket,&mcast_received_call,0); zmq_recvmsg(items[loop].socket,&mcast_received_event_data,0); process_event(mcast_received_event_name,mcast_received_endian,mcast_received_call,mcast_received_event_data); zmq_msg_close(&mcast_received_event_name); zmq_msg_close(&mcast_received_endian); zmq_msg_close(&mcast_received_call); zmq_msg_close(&mcast_received_event_data); items[loop].revents = 0; } } } return (void *)NULL; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::process_heartbeat() // // description : // Process execution when a message has been received by the heartbeat socket // // argument : // in : // - received_event_name : The full event name // - received_endian : The sender endianess // - received_call : The call informations (oid - method name...) // //--------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::process_heartbeat(zmq::message_t &received_event_name,zmq::message_t &received_endian,zmq::message_t &received_call) { // // For debug and logging purposes // if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: A heartbeat message has been received" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_event_name.data(),received_event_name.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_endian.data(),received_endian.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_call.data(),received_call.size()); } // // Extract data from messages // unsigned char endian = ((char *)received_endian.data())[0]; string event_name((char *)received_event_name.data(),(size_t)received_event_name.size()); cdrMemoryStream call_info((char *)received_call.data(),(size_t)received_call.size()); call_info.setByteSwapFlag(endian); ZmqCallInfo_var c_info_var = new ZmqCallInfo; try { (ZmqCallInfo &)c_info_var <<= call_info; } catch (...) { string st("Received a malformed heartbeat event: "); st = st + event_name; print_error_message(st.c_str()); unsigned char *tmp = (unsigned char *)received_call.data(); for (unsigned int loop = 0;loop < received_call.size();loop++) { cerr << "Heartbeat event data[" << loop << "] = " << hex << (int)tmp[loop] << dec << endl; } return; } // // Call the heartbeat method // push_heartbeat_event(event_name); } //------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::process_event() // // description : // Process execution when a message has been received by the event socket // // argument : // in : // - received_event_name : The full event name // - received_endian : The sender endianess // - received_call : The call informations (oid - method name...) // - event_data : The event data ! // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::process_event(zmq::message_t &received_event_name,zmq::message_t &received_endian,zmq::message_t &received_call,zmq::message_t &event_data) { //cout << "event name message adr = " << (void *)(&received_event_name) << " - size = " << received_event_name.size() << " - ptr = " << (void *)(received_event_name.data()) << endl; //cout << "endian message adr = " << (void *)(&received_endian) << " - size = " << received_endian.size() << " - ptr = " << (void *)(received_endian.data()) << endl; //cout << "call info message adr = " << (void *)(&received_call) << " - size = " << received_call.size() << " - ptr = " << (void *)(received_call.data()) << endl; //cout << "event data message adr = " << (void *)(&event_data) << " - size = " << event_data.size() << " - ptr = " << (void *)(event_data.data()) << endl; // // For debug and logging purposes // if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: A event message has been received" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_event_name.data(),received_event_name.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_endian.data(),received_endian.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_call.data(),received_call.size()); { omniORB::logger log; log << "ZMQ: Event data" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)event_data.data(),event_data.size()); } // // Extract data from messages // const ZmqCallInfo *receiv_call; unsigned char endian = ((char *)received_endian.data())[0]; string event_name((char *)received_event_name.data(),(size_t)received_event_name.size()); cdrMemoryStream call_info((char *)received_call.data(),(size_t)received_call.size()); call_info.setByteSwapFlag(endian); ZmqCallInfo_var c_info_var = new ZmqCallInfo; try { (ZmqCallInfo &)c_info_var <<= call_info; } catch (...) { string st("Received a malformed event call info data for event "); st = st + event_name; print_error_message(st.c_str()); unsigned char *tmp = (unsigned char *)received_call.data(); for (unsigned int loop = 0;loop < received_call.size();loop++) { cerr << "Event data[" << loop << "] = " << hex << (int)tmp[loop] << dec << endl; } return; } receiv_call = &c_info_var.in(); // // Call the event method // push_zmq_event(event_name,endian,event_data,receiv_call->call_is_except,receiv_call->ctr); } void ZmqEventConsumer::process_event(zmq_msg_t &received_event_name,zmq_msg_t &received_endian,zmq_msg_t &received_call,zmq_msg_t &event_data) { // // For debug and logging purposes // if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: A event message has been received" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)zmq_msg_data(&received_event_name),zmq_msg_size(&received_event_name)); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)zmq_msg_data(&received_endian),zmq_msg_size(&received_endian)); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)zmq_msg_data(&received_call),zmq_msg_size(&received_call)); { omniORB::logger log; log << "ZMQ: Event data" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)zmq_msg_data(&event_data),zmq_msg_size(&event_data)); } // // Extract data from messages // const ZmqCallInfo *receiv_call; unsigned char endian = ((char *)zmq_msg_data(&received_endian))[0]; string event_name((char *)zmq_msg_data(&received_event_name),zmq_msg_size(&received_event_name)); cdrMemoryStream call_info((char *)zmq_msg_data(&received_call),zmq_msg_size(&received_call)); call_info.setByteSwapFlag(endian); ZmqCallInfo_var c_info_var = new ZmqCallInfo; try { (ZmqCallInfo &)c_info_var <<= call_info; } catch (...) { string st("Received a malformed event call info data for event "); st = st + event_name; print_error_message(st.c_str()); unsigned char *tmp = (unsigned char *)zmq_msg_data(&received_call); for (unsigned int loop = 0;loop < zmq_msg_size(&received_call);loop++) { cerr << "Event data[" << loop << "] = " << hex << (int)tmp[loop] << dec << endl; } return; } receiv_call = &c_info_var.in(); // // Call the event method // zmq::message_t cpp_ev_data; cpp_ev_data.rebuild(zmq_msg_data(&event_data),zmq_msg_size(&event_data),NULL); push_zmq_event(event_name,endian,cpp_ev_data,receiv_call->call_is_except,receiv_call->ctr); } //------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::process_ctrl() // // description : // Process task when something has been received by the control socket // // argument : // in : // - received_ctrl : The received data // - poll_list : The ZMQ poll ed item list // - poll_nb : The item number in previous list // // return : // This method returns true if the calling thread has to exit (because a ZMQ_END command has been received). // Otherwise, it returns false // //-------------------------------------------------------------------------------------------------------------------- bool ZmqEventConsumer::process_ctrl(zmq::message_t &received_ctrl,zmq::pollitem_t *poll_list,int &poll_nb) { bool ret = false; // // For debug and logging purposes // if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: A control message has been received" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Control data " << '\n'; } omni::giopStream::dumpbuf((unsigned char *)received_ctrl.data(),received_ctrl.size()); } // // Extract cmd code from messages // const char *tmp_ptr = (const char *)received_ctrl.data(); char cmd_code = tmp_ptr[0]; // // Process each command // switch (cmd_code) { case ZMQ_END: { ret = true; } break; case ZMQ_CONNECT_HEARTBEAT: { // // First extract the endpoint and the event name from received buffer // char force_connect = tmp_ptr[1]; const char *endpoint = &(tmp_ptr[2]); int start = ::strlen(endpoint) + 3; const char *event_name = &(tmp_ptr[start]); // // Connect the heartbeat socket to the new publisher if not already done // bool connect_heart = false; if (connected_heartbeat.empty() == false) { if (force_connect == 1) connect_heart = true; else { vector::iterator pos; pos = find(connected_heartbeat.begin(),connected_heartbeat.end(),endpoint); if (pos == connected_heartbeat.end()) connect_heart = true; } } else connect_heart = true; if (connect_heart == true) { heartbeat_sub_sock->connect(endpoint); if (force_connect == 0) connected_heartbeat.push_back(endpoint); } // // Subscribe to the new heartbeat event // heartbeat_sub_sock->setsockopt(ZMQ_SUBSCRIBE,event_name,::strlen(event_name)); // // Most of the time, we have only one TANGO_HOST to take into account and we dont need to execute following code. // But there are some control system where several TANGO_HOST are defined // if (env_var_fqdn_prefix.size() > 1) { string base_name(event_name); multi_tango_host(heartbeat_sub_sock,SUBSCRIBE,base_name); } } break; case ZMQ_DISCONNECT_HEARTBEAT: { // // Get event name and endpoint name // const char *event_name = &(tmp_ptr[1]); #ifdef ZMQ_HAS_DISCONNECT const char *endpoint = &(tmp_ptr[1 + ::strlen(event_name) + 1]); const char *endpoint_event = &(tmp_ptr[1 + ::strlen(event_name) + ::strlen(endpoint) + 2]); #endif // // Unsubscribe this event from the heartbeat socket // heartbeat_sub_sock->setsockopt(ZMQ_UNSUBSCRIBE,event_name,::strlen(event_name)); // // Most of the time, we have only one TANGO_HOST to take into account and we don need to execute following code. // But there are some control system where several TANGO_HOST are defined // if (env_var_fqdn_prefix.size() > 1) { string base_name(event_name); multi_tango_host(heartbeat_sub_sock,UNSUBSCRIBE,base_name); } #ifdef ZMQ_HAS_DISCONNECT // // Remove the endpoint in the vector of already connected heartbeat and disconnect the socket to this endpoint // vector::iterator pos; string endpoint_str(endpoint); pos = find(connected_heartbeat.begin(),connected_heartbeat.end(),endpoint_str); if (pos != connected_heartbeat.end()) connected_heartbeat.erase(pos); heartbeat_sub_sock->disconnect(endpoint); // // Remove the event endpoint from the already connected event and disconnect the event socket // pos = find(connected_pub.begin(),connected_pub.end(),string(endpoint_event)); if (pos != connected_pub.end()) { connected_pub.erase(pos); event_sub_sock->disconnect(endpoint_event); } #endif } break; case ZMQ_CONNECT_EVENT: { // // First extract the endpoint and the event name from received buffer // char force_connect = tmp_ptr[1]; const char *endpoint = &(tmp_ptr[2]); int start = ::strlen(endpoint) + 3; const char *event_name = &(tmp_ptr[start]); start = start + ::strlen(event_name) + 1; Tango::DevLong sub_hwm; ::memcpy(&sub_hwm,&(tmp_ptr[start]),sizeof(Tango::DevLong)); // // Connect the socket to the publisher // bool connect_pub = false; if (connected_pub.empty() == false) { if (force_connect == 1) connect_pub = true; else { vector::iterator pos; pos = find(connected_pub.begin(),connected_pub.end(),endpoint); if (pos == connected_pub.end()) connect_pub = true; } } else connect_pub = true; if (connect_pub == true) { event_sub_sock->setsockopt(ZMQ_RCVHWM,&sub_hwm,sizeof(sub_hwm)); event_sub_sock->connect(endpoint); if (force_connect == 0) connected_pub.push_back(endpoint); } // // Subscribe to the new event // event_sub_sock->setsockopt(ZMQ_SUBSCRIBE,event_name,::strlen(event_name)); // // Most of the time, we have only one TANGO_HOST to take into account and we don't need to execute following code. // But there are some control system where several TANGO_HOST are defined! // if (env_var_fqdn_prefix.size() > 1) { string base_name(event_name); multi_tango_host(event_sub_sock,SUBSCRIBE,base_name); } } break; case ZMQ_DISCONNECT_EVENT: { // // Get event name // const char *event_name = &(tmp_ptr[1]); string ev_name(event_name); const char *endpoint = &(tmp_ptr[1 + ::strlen(event_name) + 1]); string endpoint_str(endpoint); // // Check if it is a multicast event // bool mcast = false; map::iterator pos; if (event_mcast.empty() != true) { pos = event_mcast.find(ev_name); if (pos != event_mcast.end()) mcast = true; } // // Unsubscribe this event from the socket // if (mcast == false) { event_sub_sock->setsockopt(ZMQ_UNSUBSCRIBE,event_name,::strlen(event_name)); // // Most of the time, we have only one TANGO_HOST to take into account and we don need to execute following code. // But there are some control system where several TANGO_HOST are defined // if (env_var_fqdn_prefix.size() > 1) { string base_name(event_name); multi_tango_host(event_sub_sock,UNSUBSCRIBE,base_name); } } else { delete pos->second; event_mcast.erase(pos); old_poll_nb--; } } break; case ZMQ_CONNECT_MCAST_EVENT: { // // First extract the endpoint and the event name from received buffer // const char *endpoint = &(tmp_ptr[2]); int start = ::strlen(endpoint) + 3; const char *event_name = &(tmp_ptr[start]); start = start + ::strlen(event_name) + 1; Tango::DevLong sub_hwm,rate,ivl; ::memcpy(&sub_hwm,&(tmp_ptr[start]),sizeof(Tango::DevLong)); start = start + sizeof(Tango::DevLong); ::memcpy(&rate,&(tmp_ptr[start]),sizeof(Tango::DevLong)); start = start + sizeof(Tango::DevLong); ::memcpy(&ivl,&(tmp_ptr[start]),sizeof(Tango::DevLong)); // // Connect the socket to the publisher // bool created_sub = false; string ev_name(event_name); map::iterator pos; if (event_mcast.empty() == false) { pos = event_mcast.find(ev_name); if (pos != event_mcast.end()) created_sub = true; } if (created_sub == false) { // // Check that we are not at the socket high limit // if (poll_nb == MAX_SOCKET_SUB) { Except::throw_exception((const char *)API_InternalError, (const char *)"Array to store sockets for zmq poll() call is already full", (const char *)"ZmqEventConsumer::process_control"); } // // Create the socket // zmq::socket_t *tmp_sock = new zmq::socket_t(zmq_context,ZMQ_SUB); // // Set socket rate, ivl linger and hwm // int local_rate = rate; tmp_sock->setsockopt(ZMQ_RATE,&local_rate,sizeof(local_rate)); int local_ivl = ivl; tmp_sock->setsockopt(ZMQ_RECOVERY_IVL,&local_ivl,sizeof(local_ivl)); int linger = 0; tmp_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); tmp_sock->setsockopt(ZMQ_RCVHWM,&sub_hwm,sizeof(sub_hwm)); // // Connect the socket // tmp_sock->connect(endpoint); // // Subscribe to the new event // tmp_sock->setsockopt(ZMQ_SUBSCRIBE,event_name,::strlen(event_name)); // // Store socket in map // if (event_mcast.insert(make_pair(ev_name,tmp_sock)).second == false) { delete tmp_sock; print_error_message("Error while inserting pair in map!"); Except::throw_exception((const char *)API_InternalError, (const char *)"Error while inserting pair in map", (const char *)"ZmqEventConsumer::process_control"); } // // Update poll item list // poll_list[old_poll_nb].socket = *tmp_sock; poll_list[old_poll_nb].fd = 0; poll_list[old_poll_nb].events = ZMQ_POLLIN; poll_list[old_poll_nb].revents = 0; old_poll_nb++; } } break; case ZMQ_DELAY_EVENT: { old_poll_nb = poll_nb; poll_nb = 1; } break; case ZMQ_RELEASE_EVENT: { poll_nb = old_poll_nb; } break; default: print_error_message("ZMQ main thread: Received an unknown command code from control socket!"); break; } return ret; } //--------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::multi_tango_host() // // description : // Method to execute a ZMQ socket command (actually only SUBSCRIBE or UNSUBSCRIBE) when several TANGO_HOST is // used in a control system // // argument : // in : // - sock : The ZMQ socket // - cmd : The command to be done on socket // - event_name: Event name // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::multi_tango_host(zmq::socket_t *sock,SocketCmd cmd,string &event_name) { size_t pos = event_name.find('/',8); string base_tango_host = event_name.substr(0,pos + 1); string ev_name = event_name.substr(pos + 1); for (unsigned int loop = 0;loop < env_var_fqdn_prefix.size();loop++) { if (env_var_fqdn_prefix[loop] == base_tango_host) continue; else { string new_tango_host = env_var_fqdn_prefix[loop] + ev_name; const char * tmp_ev_name = new_tango_host.c_str(); if (cmd == SUBSCRIBE) sock->setsockopt(ZMQ_SUBSCRIBE,tmp_ev_name,::strlen(tmp_ev_name)); else sock->setsockopt(ZMQ_UNSUBSCRIBE,tmp_ev_name,::strlen(tmp_ev_name)); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::cleanup_EventChannel_map() // // description : // Method to destroy the DeviceProxy objects stored in the EventChannel map. // It also destroys some allocated objects (to make valgrind happy) // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::cleanup_EventChannel_map() { EvChanIte evt_it; for (evt_it = channel_map.begin(); evt_it != channel_map.end(); ++evt_it) { EventChannelStruct &evt_ch = evt_it->second; if ((evt_ch.channel_type == ZMQ) && (evt_ch.adm_device_proxy != NULL)) { AutoTangoMonitor _mon(evt_ch.channel_monitor); // // Release the connection to the device server administration device // delete evt_ch.adm_device_proxy; evt_ch.adm_device_proxy = NULL; } delete evt_ch.channel_monitor; } // // Delete a Tango monitor in Callback structs // EvCbIte cb_it; for (cb_it = event_callback_map.begin(); cb_it != event_callback_map.end(); ++cb_it) { EventCallBackStruct &evt_cb = cb_it->second; delete evt_cb.callback_monitor; } // // Create and connect the REQ socket used to send message to the ZMQ main thread // zmq::message_t reply; try { zmq::socket_t sender(zmq_context,ZMQ_REQ); sender.connect(CTRL_SOCK_ENDPOINT); // // Build message sent to ZMQ main thread. In this case, this is only a command code // char buffer[10]; int length = 0; buffer[length] = ZMQ_END; length++; // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch(zmq::error_t &) {} } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::connect_event_channel() // // description : // Connect to the event channel. This means connect to the heartbeat event // // argument : // in : // - channel name : The event channel name (DS admin name) // - db : Database object // - reconnect: Flag set to true in case this method is called for event reconnection purpose // - dd : The DS admin device command returned data (ZmqEventSubscriptionChange command) // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::connect_event_channel(string &channel_name,TANGO_UNUSED(Database *db),bool reconnect,DeviceData &dd) { // // Extract server command result // const DevVarLongStringArray *ev_svr_data; dd >> ev_svr_data; // // Do we have this tango host info in the vector of possible TANGO_HOST. If not get them // string prefix = channel_name.substr(0,channel_name.find('/',8) + 1); bool found = false; #ifdef HAS_RANGE_BASE_FOR for (const auto &elem:env_var_fqdn_prefix) { if (elem == prefix) { found = true; break; } } #else vector::iterator ite; for (ite = env_var_fqdn_prefix.begin();ite != env_var_fqdn_prefix.end();++ite) { if (*ite == prefix) { found = true; break; } } #endif if (found == false && db != NULL) { get_cs_tango_host(db); } // // If the server has returned several possible ZMQ endpoints (because several NIC boards on server host), check which // one is correct // size_t nb_endpoint = ev_svr_data->svalue.length(); nb_endpoint = nb_endpoint >> 1; size_t valid_endpoint = 0; if (nb_endpoint != 1) { for (valid_endpoint = 0;valid_endpoint < nb_endpoint;valid_endpoint++) { string endpoint(ev_svr_data->svalue[valid_endpoint << 1]); if (check_zmq_endpoint(endpoint) == true) break; } if (valid_endpoint == nb_endpoint) { stringstream o; o << "Failed to create connection to event channel!\n"; o << "Impossible to create a network connection to any of the event endpoints returned by server"; Except::throw_exception(API_ZmqFailed,o.str(),"ZmqEventConsumer::connect_event_channel"); } } // // Create and connect the REQ socket used to send message to the ZMQ main thread // zmq::message_t reply; try { zmq::socket_t sender(zmq_context,ZMQ_REQ); // // In case this thread runs before the main ZMQ thread, it is possible to call connect before the main ZMQ thread has // binded its socket. In such a case, error code is set to ECONNREFUSED. // If this happens, give the main ZMQ thread a chance to run and retry the connect call // I have tried with a yield call but it still failed in some cases (when running the DS with a file as database for // instance). Replace the yield with a 10 mS sleep !!! // try { sender.connect(CTRL_SOCK_ENDPOINT); } catch (zmq::error_t &e) { if (e.num() == ECONNREFUSED) { #ifndef _TG_WINDOWS_ struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 10000000; nanosleep(&ts,NULL); #else Sleep(10); #endif sender.connect(CTRL_SOCK_ENDPOINT); } else throw; } // // Build message sent to ZMQ main thread // In this case, this is the command code, the publisher endpoint and the event name // char buffer[1024]; int length = 0; buffer[length] = ZMQ_CONNECT_HEARTBEAT; length++; #ifdef ZMQ_HAS_DISCONNECT buffer[length] = 0; #else if (reconnect == true) buffer[length] = 1; else buffer[length] = 0; #endif length++; ::strcpy(&(buffer[length]),ev_svr_data->svalue[valid_endpoint].in()); length = length + ::strlen(ev_svr_data->svalue[valid_endpoint].in()) + 1; string sub(channel_name); sub = sub + '.' + HEARTBEAT_EVENT_NAME; ::strcpy(&(buffer[length]),sub.c_str()); length = length + sub.size() + 1; // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch(zmq::error_t &e) { stringstream o; o << "Failed to create connection to event channel!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ error code = " << e.num() << "\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception(API_ZmqFailed,o.str(),"ZmqEventConsumer::connect_event_channel"); } // // Any error during ZMQ main thread socket operations? // if (reply.size() != 2) { char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; stringstream o; o << "Failed to create connection to event channel!\n"; o << "Error while trying to connect or subscribe the heartbeat ZMQ socket to the new publisher\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception(API_ZmqFailed,o.str(),"ZmqEventConsumer::connect_event_channel"); } // // Init (or create) EventChannelStruct // EvChanIte evt_it = channel_map.end(); if (reconnect == true) { evt_it = channel_map.find(channel_name); EventChannelStruct &evt_ch = evt_it->second; evt_ch.last_heartbeat = time(NULL); evt_ch.heartbeat_skipped = false; evt_ch.event_system_failed = false; evt_ch.endpoint = ev_svr_data->svalue[valid_endpoint].in(); evt_ch.valid_endpoint = valid_endpoint; } else { EventChannelStruct new_event_channel_struct; new_event_channel_struct.last_heartbeat = time(NULL); new_event_channel_struct.heartbeat_skipped = false; new_event_channel_struct.adm_device_proxy = NULL; // create a channel monitor new_event_channel_struct.channel_monitor = new TangoMonitor(channel_name.c_str()); // set the timeout for the channel monitor to 1000ms not to block the event consumer for to long. new_event_channel_struct.channel_monitor->timeout(1000); new_event_channel_struct.event_system_failed = false; set_channel_type(new_event_channel_struct); new_event_channel_struct.endpoint = ev_svr_data->svalue[valid_endpoint].in(); new_event_channel_struct.valid_endpoint = valid_endpoint; channel_map[channel_name] = new_event_channel_struct; } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::disconnect_event_channel() // // description : // Disconnect to the event channel. This means that the process should not receive the heartbeat event for this // channel. It will be filtered out by ZMQ // // argument : // in : // - channel name : The event channel name (DS admin name) // - endpoint : The ZMQ endpoint for the heartbeat publisher socket // - endpoint_event : The ZMQ endpoint for the event publisher socket // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::disconnect_event_channel(string &channel_name,string &endpoint,string &endpoint_event) { string unsub(channel_name); unsub = unsub + '.' + HEARTBEAT_EVENT_NAME; // // Create and connect the REQ socket used to send message to the ZMQ main thread // zmq::message_t reply; try { zmq::socket_t sender(zmq_context,ZMQ_REQ); sender.connect(CTRL_SOCK_ENDPOINT); // // Build message sent to ZMQ main thread // In this case, this is the command code, the publisher endpoint and the event name // char buffer[1024]; int length = 0; buffer[length] = ZMQ_DISCONNECT_HEARTBEAT; length++; ::strcpy(&(buffer[length]),unsub.c_str()); length = length + unsub.size() + 1; ::strcpy(&(buffer[length]),endpoint.c_str()); length = length + endpoint.size() + 1; ::strcpy(&(buffer[length]),endpoint_event.c_str()); length = length + endpoint_event.size() + 1; // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch (zmq::error_t &e) { TangoSys_OMemStream o; o << "Failed to disconnect from the event channel!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventConsumer::disconnect_event_channel"); } // // In case of error returned by the main ZMQ thread // if (reply.size() != 2) { char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; TangoSys_OMemStream o; o << "Failed to disconnect from event channel!\n"; o << "Error while trying to unsubscribe the heartbeat ZMQ socket from the channel heartbeat publisher\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventConsumer::disconnect_event_channel"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::disconnect_event() // // description : // Disconnect to the event. This means that the process should not receive the event any more // It will be filtered out by ZMQ // // argument : // in : // - event_name : The event name // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::disconnect_event(string &event_name,string &endpoint) { // // Create and connect the REQ socket used to send message to the ZMQ main thread // zmq::message_t reply; try { zmq::socket_t sender(zmq_context,ZMQ_REQ); sender.connect(CTRL_SOCK_ENDPOINT); // // Build message sent to ZMQ main thread // In this case, this is the command code, the publisher endpoint and the event name // char buffer[1024]; int length = 0; buffer[length] = ZMQ_DISCONNECT_EVENT; length++; ::strcpy(&(buffer[length]),event_name.c_str()); length = length + event_name.size() + 1; ::strcpy(&(buffer[length]),endpoint.c_str()); length = length + endpoint.size() + 1; // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch (zmq::error_t &e) { TangoSys_OMemStream o; o << "Failed to disconnect from event!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventConsumer::disconnect_event"); } // // In case of error returned by the main ZMQ thread // if (reply.size() != 2) { char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; TangoSys_OMemStream o; o << "Failed to disconnect from event!\n"; o << "Error while trying to unsubscribe the heartbeat ZMQ socket from the channel heartbeat publisher\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"ZmqEventConsumer::disconnect_event"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::connect_event_system() // // description : // Connect to the real event (change, archive,...) // // argument : // in : // - device_name : The device fqdn (lower case) // - obj_name : The attribute/pipe name // - event_name : The event name // - filters : The event filters given by the user // - evt_it : Iterator pointing to the event channel entry in channel_map map // - new_event_callback : Structure used for the event callback entry in the event_callback_map // - dd : The data returned by the DS admin device xxxSubscriptionChange command // - valid_end : The valid endpoint in the list of endpoint returned by ZMQEventSubscriptionChange command // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::connect_event_system(string &device_name,string &obj_name,string &event_name,TANGO_UNUSED(const vector &filters), TANGO_UNUSED(EvChanIte &eve_it),TANGO_UNUSED(EventCallBackStruct &new_event_callback), DeviceData &dd,size_t valid_end) { // // Build full event name // Don't forget case of device in a DS using file as database // string full_event_name; string::size_type pos; bool inter_event = false; if (event_name == EventName[INTERFACE_CHANGE_EVENT]) inter_event = true; if ((pos = device_name.find(MODIFIER_DBASE_NO)) != string::npos) { full_event_name = device_name; if (inter_event == false) { string tmp = '/' + obj_name; full_event_name.insert(pos,tmp); } full_event_name = full_event_name + '.' + event_name; } else { if (inter_event == true) full_event_name = device_name + '.' + event_name; else full_event_name = device_name + '/' + obj_name + '.' + event_name; } // // Extract server command result // const DevVarLongStringArray *ev_svr_data; dd >> ev_svr_data; // // Create and connect the REQ socket used to send message to the ZMQ main thread // zmq::message_t reply; try { zmq::socket_t sender(zmq_context,ZMQ_REQ); sender.connect(CTRL_SOCK_ENDPOINT); // // If the transport is multicast, add main IP interface address in endpoint // bool mcast_transport = false; ApiUtil *au = ApiUtil::instance(); string endpoint(ev_svr_data->svalue[(valid_end << 1) + 1].in()); if (endpoint.find(MCAST_PROT) != string::npos) { mcast_transport = true; vector adrs; au->get_ip_from_if(adrs); for (unsigned int i = 0;i < adrs.size();++i) { if (adrs[i].find("127.") == 0) continue; adrs[i] = adrs[i] + ';'; string::size_type pos = endpoint.find('/'); pos = pos + 2; endpoint.insert(pos,adrs[i]); break; } } // // Build message sent to ZMQ main thread // In this case, this is the command code, the publisher endpoint, the event name and the sub hwm // char buffer[1024]; int length = 0; if (mcast_transport == true) buffer[length] = ZMQ_CONNECT_MCAST_EVENT; else buffer[length] = ZMQ_CONNECT_EVENT; length++; #ifdef ZMQ_HAS_DISCONNECT buffer[length] = 0; #else if (filters.size() == 1 && filters[0] == "reconnect") buffer[length] = 1; else buffer[length] = 0; #endif length++; ::strcpy(&(buffer[length]),endpoint.c_str()); length = length + endpoint.size() + 1; ::strcpy(&(buffer[length]),full_event_name.c_str()); length = length + full_event_name.size() + 1; DevLong user_hwm = au->get_user_sub_hwm(); if (user_hwm != -1) ::memcpy(&(buffer[length]),&(user_hwm),sizeof(Tango::DevLong)); else ::memcpy(&(buffer[length]),&(ev_svr_data->lvalue[2]),sizeof(Tango::DevLong)); length = length + sizeof(Tango::DevLong); // // In case of multicasting, add rate and ivl parameters // if (mcast_transport == true) { ::memcpy(&(buffer[length]),&(ev_svr_data->lvalue[3]),sizeof(Tango::DevLong)); length = length + sizeof(Tango::DevLong); ::memcpy(&(buffer[length]),&(ev_svr_data->lvalue[4]),sizeof(Tango::DevLong)); length = length + sizeof(Tango::DevLong); } // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch(zmq::error_t &e) { stringstream o; o << "Failed to create connection to event!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception(API_ZmqFailed,o.str(),"ZmqEventConsumer::connect_event_system"); } // // Any error during ZMQ main thread socket operations? // if (reply.size() != 2) { char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; stringstream o; o << "Failed to create connection to event!\n"; o << "Error while trying to connect or subscribe the event ZMQ socket to the new publisher\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception(API_ZmqFailed,o.str(),"ZmqEventConsumer::connect_event_system"); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::push_heartbeat_event() // // description : // Method called when the heartbeat event is received. This method retrieve the channel entry in the channel_map // and update the last heartbeat date. // // argument : // in : // - ev_name : The fully qualifed event name // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::push_heartbeat_event(string &ev_name) { // // Remove ".heartbeat" at the end of event name // string::size_type pos = ev_name.find(".heartbeat"); if (pos == string::npos) { return; } ev_name.erase(pos); // // Only reading from the maps // map_modification_lock.readerIn(); std::map::iterator ipos; ipos = channel_map.find(ev_name); if (ipos != channel_map.end()) { EventChannelStruct &evt_ch = ipos->second; try { AutoTangoMonitor _mon(evt_ch.channel_monitor); evt_ch.last_heartbeat = time(NULL); } catch (...) { string st("Tango::ZmqEventConsumer::push_heartbeat_event() timeout on channel monitor of "); st = st + ipos->first; print_error_message(st.c_str()); } } else { unsigned int loop = 0; if (env_var_fqdn_prefix.size() > 1) { size_t pos = ev_name.find('/',8); string base_tango_host = ev_name.substr(0,pos + 1); string canon_ev_name = ev_name.substr(pos + 1); for (loop = 0;loop < env_var_fqdn_prefix.size();loop++) { if (env_var_fqdn_prefix[loop] == base_tango_host) continue; else { string new_tango_host = env_var_fqdn_prefix[loop] + canon_ev_name; ipos = channel_map.find(new_tango_host); if (ipos != channel_map.end()) { EventChannelStruct &evt_ch = ipos->second; try { AutoTangoMonitor _mon(evt_ch.channel_monitor); evt_ch.last_heartbeat = time(NULL); } catch (...) { string st("Tango::ZmqEventConsumer::push_heartbeat_event() timeout on channel monitor of "); st = st + ipos->first; print_error_message(st.c_str()); } break; } } } } if (loop == env_var_fqdn_prefix.size()) { string st("No entry in channel map for heartbeat "); st = st + ev_name; print_error_message(st.c_str()); } } map_modification_lock.readerOut(); } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::push_zmq_event() // // description : // Method called when the event is received. This method retrieve the channel entry in the channel_map // and update the last heartbeat date. // // argument : // in : // - ev_name : The fully qualifed event name // - endian : The sender host endianess // - event_data : The event data still in a ZMQ message // - error : Flag set to true if the event data is an error stack // - ctr : Event counter as received from server // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::push_zmq_event(string &ev_name,unsigned char endian,zmq::message_t &event_data,bool error,const DevULong &ds_ctr) { map_modification_lock.readerIn(); bool map_lock = true; // cout << "Lib: Received event for " << ev_name << endl; // for (const auto &elem : event_callback_map) // printf("Key in event_callback_map = %s\n",elem.first.c_str()); // for (const auto &elem : channel_map) // printf("Key in channel_map = %s\n",elem.first.c_str()); // // Search for entry within the event_callback map using the event name received in the event // map::iterator ipos; size_t loop; bool no_db_dev = false; bool first_search_succeed = false; size_t pos = ev_name.find('/',8); string base_tango_host = ev_name.substr(0,pos + 1); string canon_ev_name = ev_name.substr(pos + 1); if (ev_name.find(MODIFIER_DBASE_NO) != string::npos) no_db_dev = true; for (loop = 0;loop < env_var_fqdn_prefix.size() + 1;loop++) { // // Test different fully qualified event name depending on different TANGO_HOST defined for the control system // string new_tango_host; if (loop == 0 || no_db_dev == true) new_tango_host = ev_name; else new_tango_host = env_var_fqdn_prefix[loop - 1] + canon_ev_name; ipos = event_callback_map.find(new_tango_host); if (ipos != event_callback_map.end()) { if (loop == 0) first_search_succeed = true; const AttributeValue *attr_value = NULL; const AttributeValue_3 *attr_value_3 = NULL; const ZmqAttributeValue_4 *z_attr_value_4 = NULL; const ZmqAttributeValue_5 *z_attr_value_5 = NULL; const AttributeConfig_2 *attr_conf_2 = NULL; const AttributeConfig_3 *attr_conf_3 = NULL; const AttributeConfig_5 *attr_conf_5 = NULL; AttDataReady *att_ready = NULL; DevIntrChange *dev_intr_change = NULL; const DevErrorList *err_ptr; DevErrorList errors; AttributeInfoEx *attr_info_ex = NULL; bool ev_attr_conf = false; bool ev_attr_ready = false; bool ev_dev_intr = false; bool pipe_event = false; EventCallBackStruct &evt_cb = ipos->second; // // Miss some events? // Due to LIBZMQ Bug 283, the first event after a process startup is sent two times // with the same ctr value. Do not call the user callback for the second times. // bool err_missed_event = false; if (ds_ctr != 1 && evt_cb.ctr == 0) evt_cb.ctr = ds_ctr - 1; DevLong missed_event = ds_ctr - evt_cb.ctr; if (missed_event < 0) { missed_event = (UINT_MAX + missed_event) + 1; } if (missed_event >= 2) { err_missed_event = true; evt_cb.discarded_event = false; } else if (missed_event == 0) { if (evt_cb.discarded_event == false) { evt_cb.discarded_event = true; map_modification_lock.readerOut(); return; } else evt_cb.discarded_event = false; } else evt_cb.discarded_event = false; evt_cb.ctr = ds_ctr; // // Get which type of event data has been received (from the event type) // string::size_type pos = ev_name.rfind('.'); string event_name = ev_name.substr(pos + 1); string::size_type pos1 = event_name.find(EVENT_COMPAT); if (pos1 != string::npos) event_name.erase(0,EVENT_COMPAT_IDL5_SIZE); // // If the client TANGO_HOST is one alias, replace in the event name the host name by the alias // string full_att_name; if (evt_cb.alias_used == true) { pos = evt_cb.fully_qualified_event_name.rfind('.'); full_att_name = evt_cb.fully_qualified_event_name.substr(0,pos); string::size_type pos = full_att_name.find(':',8); string host = full_att_name.substr(8,pos - 8); map::iterator ite = alias_map.find(host); if (ite != alias_map.end()) full_att_name.replace(8,pos - 8,ite->second); } else { if (first_search_succeed == true) full_att_name = ev_name.substr(0,pos); else { pos = evt_cb.fully_qualified_event_name.rfind('.'); full_att_name = evt_cb.fully_qualified_event_name.substr(0,pos); } } pos = full_att_name.rfind('/'); string att_name = full_att_name.substr(pos + 1); UserDataEventType data_type; if (event_name.find(CONF_TYPE_EVENT) != string::npos) data_type = ATT_CONF; else if (event_name == DATA_READY_TYPE_EVENT) data_type = ATT_READY; else if (event_name == EventName[INTERFACE_CHANGE_EVENT]) data_type = DEV_INTR; else if (event_name == EventName[PIPE_EVENT]) data_type = PIPE; else data_type = ATT_VALUE; // // Unmarshal the event data // long vers = 0; DeviceAttribute *dev_attr = NULL; DevicePipe *dev_pipe = NULL; bool no_unmarshalling = false; if (evt_cb.fwd_att == true && data_type != ATT_CONF && error == false) { no_unmarshalling = true; } else { // // For 64 bits data (double, long64 and ulong64), omniORB unmarshalling // methods required that the 64 bits data are aligned on a 8 bytes memory address. // ZMQ returned memory which is sometimes aligned on a 8 bytes boundary but // not always (seems to depend on the host architecture) // The attribute data transfert starts with the union discriminator // (4 bytes), the elt nb (4 bytes) and the element themselves. // This means 8 bytes before the real data. // There is a trick here. // The buffer is always transferred with an extra 4 bytes added at the beginning // If the alignememnt is not correct (buffer aligned on a 8 bytes boundary // and 64 bits data type), shift the whole buffer by 4 bytes erasing the // additional 4 bytes sent. // // Note: The buffer is not correctly aligned if it is returned on a // 8 bytes boundary because we have the 4 extra bytes + 8 bytes for // union discriminator + elt nb. This means 64 bits data not on a // 8 bytes boundary // char *data_ptr = (char *)event_data.data(); size_t data_size = (size_t)event_data.size(); bool shift_zmq420 = false; int shift_mem = (unsigned long)data_ptr & 0x3; if (shift_mem != 0) { char *src = data_ptr + 4; size_t size_to_move = data_size - 4; if (data_type == PIPE) { src = src + 4; size_to_move = size_to_move - 4; } char *dest = src - shift_mem; if (((unsigned long)dest & 0x7) == 4) dest = dest - 4; memmove((void *)dest,(void *)src,size_to_move); shift_zmq420 = true; data_ptr = dest; } bool data64 = false; if (data_type == PIPE) data64 = true; else if (data_type == ATT_VALUE && error == false) { int disc = shift_zmq420 == true ? ((int *)data_ptr)[0] : ((int *)data_ptr)[1]; if (endian == 0) { char first_byte = disc & 0xFF; char second_byte = (disc & 0xFF00) >> 8; char third_byte = (disc & 0xFF0000) >> 16; char forth_byte = (disc & 0xFF000000) >> 24; disc = 0; disc = forth_byte + (third_byte << 8) + (second_byte << 16) + (first_byte << 24); } if (disc == ATT_DOUBLE || disc == ATT_LONG64 || disc == ATT_ULONG64) data64 = true; } bool buffer_aligned64 = false; if (data64 == true) { if (((unsigned long)data_ptr & 0x7) == 0) buffer_aligned64 = true; } // // Shift buffer if required // if (data_type == PIPE && data64 == true && buffer_aligned64 == false) { if (omniORB::trace(30)) { omniORB::logger log; log << "ZMQ: Pipe event -> Shifting received buffer to be aligned on a 8 bytes boundary" << '\n'; } char *src = data_ptr + 8; char *dest = data_ptr + 4; memmove((void *)dest,(void *)src,data_size - 8); data_ptr = data_ptr + 4; data_size = data_size - 4; } else if (data_type != PIPE && data64 == true && buffer_aligned64 == true && shift_zmq420 == false) { if (omniORB::trace(30)) { omniORB::logger log; log << "ZMQ: Classical event -> Shifting received buffer to be aligned on a 8 bytes boundary" << '\n'; } char *src = data_ptr + 4; char *dest = data_ptr; memmove((void *)dest,(void *)src,data_size - 4); data_size = data_size - 4; } else { if (data_type == PIPE) { if (shift_zmq420 == false) data_ptr = data_ptr + (sizeof(CORBA::Long) << 1); data_size = data_size - (sizeof(CORBA::Long) << 1); } else { if (shift_zmq420 == false) data_ptr = data_ptr + sizeof(CORBA::Long); data_size = data_size - sizeof(CORBA::Long); } } TangoCdrMemoryStream event_data_cdr(data_ptr,data_size); event_data_cdr.setByteSwapFlag(endian); // // Unmarshall the data // if (error == true) { switch (data_type) { case ATT_CONF: ev_attr_conf = true; break; case ATT_READY: ev_attr_ready = true; break; case DEV_INTR: ev_dev_intr = true; break; case PIPE: pipe_event = true; break; default: break; } try { (DevErrorList &)del <<= event_data_cdr; err_ptr = &del.in(); errors = *err_ptr; } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else { switch (data_type) { case ATT_CONF: if (evt_cb.device_idl > 4) { // // Event if the device sending the event is IDL 5 // try { ev_attr_conf = true; (AttributeConfig_5 &)ac5 <<= event_data_cdr; attr_conf_5 = &ac5.in(); vers = 5; attr_info_ex = new AttributeInfoEx(); *attr_info_ex = const_cast(attr_conf_5); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else if (evt_cb.device_idl > 2) { try { ev_attr_conf = true; (AttributeConfig_3 &)ac3 <<= event_data_cdr; attr_conf_3 = &ac3.in(); vers = 3; attr_info_ex = new AttributeInfoEx(); *attr_info_ex = const_cast(attr_conf_3); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else if (evt_cb.device_idl == 2) { ev_attr_conf = true; (AttributeConfig_2 &)ac2 <<= event_data_cdr; attr_conf_2 = &ac2.in(); vers = 2; attr_info_ex = new AttributeInfoEx(); *attr_info_ex = const_cast(attr_conf_2); } break; case ATT_READY: try { ev_attr_ready = true; (AttDataReady &)adr <<= event_data_cdr; att_ready = &adr.inout(); att_ready->name = full_att_name.c_str(); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } break; case DEV_INTR: try { ev_dev_intr = true; (DevIntrChange &)dic <<= event_data_cdr; dev_intr_change = &dic.inout(); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } break; case ATT_VALUE: if (evt_cb.device_idl >= 5) { event_data_cdr.set_un_marshal_type(TangoCdrMemoryStream::UN_ATT); try { vers = 5; zav5.operator<<=(event_data_cdr); z_attr_value_5 = &zav5; dev_attr = new (DeviceAttribute); attr_to_device(z_attr_value_5,dev_attr); // // Update name in DeviceAttribute in case it is not coherent with name received in first ZMQ message part. // This happens in case of forwarded attribute but also in case of DS started with file as database // string::size_type pos = att_name.find(MODIFIER_DBASE_NO); string a_name; if (pos != string::npos) a_name = att_name.substr(0,pos); else a_name = att_name; if (a_name != dev_attr->get_name()) dev_attr->set_name(a_name); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else if (evt_cb.device_idl == 4) { event_data_cdr.set_un_marshal_type(TangoCdrMemoryStream::UN_ATT); try { vers = 4; zav4.operator<<=(event_data_cdr); z_attr_value_4 = &zav4; dev_attr = new (DeviceAttribute); attr_to_device(z_attr_value_4,dev_attr); // // Update name in DeviceAttribute in case it is not coherent with name received in first ZMQ message part. // This happens in case of forwarded attribute but also in case of DS started with file as database // string::size_type pos = att_name.find(MODIFIER_DBASE_NO); string a_name; if (pos != string::npos) a_name = att_name.substr(0,pos); else a_name = att_name; if (a_name != dev_attr->get_name()) dev_attr->set_name(a_name); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else if (evt_cb.device_idl == 3) { event_data_cdr.set_un_marshal_type(TangoCdrMemoryStream::UN_ATT); try { vers = 3; (AttributeValue_3 &)av3 <<= event_data_cdr; attr_value_3 = &av3.in(); dev_attr = new (DeviceAttribute); attr_to_device(attr_value,attr_value_3,vers,dev_attr); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event (AttributeValue_3 -> Device_3Impl....) "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } else if (evt_cb.device_idl < 3) { try { vers = 2; (AttributeValue &)av <<= event_data_cdr; attr_value = &av.in(); dev_attr = new (DeviceAttribute); attr_to_device(attr_value,attr_value_3,vers,dev_attr); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event (AttributeValue -> Device_2Impl....) "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } } break; case PIPE: event_data_cdr.set_un_marshal_type(TangoCdrMemoryStream::UN_PIPE); try { pipe_event = true; zdpd.operator<<=(event_data_cdr); string pipe_name = zdpd.name.in(); string root_blob_name = zdpd.data_blob.name.in(); dev_pipe = new DevicePipe(pipe_name,root_blob_name); dev_pipe->set_time(zdpd.time); CORBA::ULong max,len; max = zdpd.data_blob.blob_data.maximum(); len = zdpd.data_blob.blob_data.length(); DevPipeDataElt *buf = zdpd.data_blob.blob_data.get_buffer((CORBA::Boolean)true); DevVarPipeDataEltArray *dvpdea = new DevVarPipeDataEltArray(max,len,buf,true); dev_pipe->get_root_blob().set_extract_data(dvpdea); dev_pipe->get_root_blob().set_extract_delete(true); } catch(...) { TangoSys_OMemStream o; o << "Received malformed data for event "; o << ev_name << ends; errors.length(1); errors[0].reason = API_WrongEventData; errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; errors[0].desc = CORBA::string_dup(o.str().c_str()); errors[0].severity = ERR; } break; } } } FwdEventData *missed_event_data = NULL; FwdAttrConfEventData *missed_conf_event_data = NULL; DataReadyEventData *missed_ready_event_data = NULL; DevIntrChangeEventData *missed_dev_intr_event_data = NULL; PipeEventData *missed_dev_pipe_data = NULL; try { AutoTangoMonitor _mon(evt_cb.callback_monitor); // // In case we have missed some event, prepare structure to send to callback to inform user of this bad behavior // if (err_missed_event == true) { DevErrorList missed_errors; missed_errors.length(1); missed_errors[0].reason = API_MissedEvents; missed_errors[0].origin = "ZmqEventConsumer::push_zmq_event()"; missed_errors[0].desc = "Missed some events! Zmq queue has reached HWM?"; missed_errors[0].severity = ERR; if ((ev_attr_conf == false) && (ev_attr_ready == false) && (ev_dev_intr == false) && (pipe_event == false)) missed_event_data = new FwdEventData (event_callback_map[ev_name].device, full_att_name,event_name,NULL,missed_errors); else if (ev_attr_ready == false && ev_dev_intr == false && pipe_event == false) missed_conf_event_data = new FwdAttrConfEventData(event_callback_map[ev_name].device, full_att_name,event_name, NULL,missed_errors); else if (ev_dev_intr == false && pipe_event == false) missed_ready_event_data = new DataReadyEventData(event_callback_map[ev_name].device, NULL,event_name,missed_errors); else if (ev_dev_intr == false) missed_dev_pipe_data = new PipeEventData(event_callback_map[ev_name].device,full_att_name, event_name,NULL,missed_errors); else missed_dev_intr_event_data = new DevIntrChangeEventData(event_callback_map[ev_name].device, event_name,full_att_name, (CommandInfoList *)NULL, (AttributeInfoListEx *)NULL, false,missed_errors); } // // Fire the user callback // vector::iterator esspos; unsigned int cb_nb = ipos->second.callback_list.size(); unsigned int cb_ctr = 0; for (esspos = evt_cb.callback_list.begin(); esspos != evt_cb.callback_list.end(); ++esspos) { cb_ctr++; if (esspos->id > 0) { CallBack *callback; callback = esspos->callback; EventQueue *ev_queue; ev_queue = esspos->ev_queue; if ((ev_attr_conf == false) && (ev_attr_ready == false) && (ev_dev_intr == false) && (pipe_event == false)) { FwdEventData *event_dat; // // In case we have several callbacks on the same event or if the event has to be stored in a queue, copy // the event data (Event data are in the ZMQ message) // if (cb_ctr != cb_nb) { DeviceAttribute *dev_attr_copy = NULL; if (dev_attr != NULL || (callback == NULL && vers >= 4)) { dev_attr_copy = new DeviceAttribute(); if (no_unmarshalling == false) dev_attr_copy->deep_copy(*dev_attr); } if (no_unmarshalling == false) event_dat = new FwdEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, dev_attr_copy, errors); else event_dat = new FwdEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, dev_attr_copy, errors, &event_data); } else { if (no_unmarshalling == true) { DeviceAttribute *dummy = new DeviceAttribute(); event_dat = new FwdEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, dummy, errors, &event_data); } else { if (callback == NULL && vers >= 4) { DeviceAttribute *dev_attr_copy = NULL; if (dev_attr != NULL) { dev_attr_copy = new DeviceAttribute(); dev_attr_copy->deep_copy(*dev_attr); } event_dat = new FwdEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, dev_attr_copy, errors); } else { event_dat = new FwdEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, dev_attr, errors); } } } // // If a callback method was specified, call it! // if (callback != NULL ) { try { if (err_missed_event == true) callback->push_event(missed_event_data); callback->push_event(event_dat); } catch (...) { string st("Tango::ZmqEventConsumer::push_structured_event() exception in callback method of "); st = st + ipos->first; print_error_message(st.c_str()); } delete event_dat; } // // No calback method, the event has to be inserted into the event queue // else { if (err_missed_event == true) { EventData *missed_event_data_copy = new FwdEventData; *missed_event_data_copy = *missed_event_data; ev_queue->insert_event(missed_event_data_copy); } ev_queue->insert_event(event_dat); if (vers >= 4 && cb_ctr == cb_nb) delete dev_attr; } } else if (ev_attr_ready == false && ev_dev_intr == false && pipe_event == false) { FwdAttrConfEventData *event_data_; if (cb_ctr != cb_nb) { AttributeInfoEx *attr_info_copy = new AttributeInfoEx(); *attr_info_copy = *attr_info_ex; event_data_ = new FwdAttrConfEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, attr_info_copy, errors); if (attr_conf_5 != NULL) event_data_->set_fwd_attr_conf(attr_conf_5); } else { event_data_ = new FwdAttrConfEventData(event_callback_map[new_tango_host].device, full_att_name, event_name, attr_info_ex, errors); if (attr_conf_5 != NULL) event_data_->set_fwd_attr_conf(attr_conf_5); } // if callback methods were specified, call them! if (callback != NULL ) { try { if (err_missed_event == true) callback->push_event(missed_conf_event_data); callback->push_event(event_data_); } catch (...) { string st("Tango::ZmqEventConsumer::push_structured_event() exception in callback method of "); st = st + ipos->first; print_error_message(st.c_str()); } delete event_data_; } // no calback method, the event has to be instered // into the event queue else { if (err_missed_event == true) { FwdAttrConfEventData *missed_conf_event_data_copy = new FwdAttrConfEventData; *missed_conf_event_data_copy = *missed_conf_event_data; ev_queue->insert_event(missed_conf_event_data_copy); } ev_queue->insert_event(event_data_); } } else if (ev_attr_ready == false && pipe_event == false) { DevIntrChangeEventData *event_data_ = new DevIntrChangeEventData(event_callback_map[new_tango_host].device, event_name,full_att_name,&dev_intr_change->cmds, &dev_intr_change->atts,dev_intr_change->dev_started,errors); // if a callback method was specified, call it! if (callback != NULL ) { try { if (err_missed_event == true) callback->push_event(missed_dev_intr_event_data); callback->push_event(event_data_); } catch (...) { string st("Tango::ZmqEventConsumer::push_structured_event() exception in callback method of "); st = st + ipos->first; print_error_message(st.c_str()); } delete event_data_; } // no calback method, the event has to be instered // into the event queue else { if (err_missed_event == true) { DevIntrChangeEventData *missed_dev_intr_data_copy = new DevIntrChangeEventData; *missed_dev_intr_data_copy = *missed_dev_intr_event_data; ev_queue->insert_event(missed_dev_intr_data_copy); } ev_queue->insert_event(event_data_); } } else if (ev_attr_ready == false) { PipeEventData *event_data_; if (cb_ctr != cb_nb) { DevicePipe *dev_pipe_copy = new DevicePipe(); *dev_pipe_copy = *dev_pipe; event_data_ = new PipeEventData(event_callback_map[new_tango_host].device,full_att_name, event_name,dev_pipe_copy,errors); } else { event_data_ = new PipeEventData(event_callback_map[new_tango_host].device, full_att_name,event_name,dev_pipe,errors); } // if a callback method was specified, call it! if (callback != NULL ) { try { if (err_missed_event == true) callback->push_event(missed_dev_pipe_data); callback->push_event(event_data_); } catch (...) { string st("Tango::ZmqEventConsumer::push_structured_event() exception in callback method of "); st = st + ipos->first; print_error_message(st.c_str()); } delete event_data_; } // no calback method, the event has to be instered // into the event queue else { if (err_missed_event == true) { PipeEventData *missed_dev_pipe_data_copy = new PipeEventData; *missed_dev_pipe_data_copy = *missed_dev_pipe_data; ev_queue->insert_event(missed_dev_pipe_data_copy); } ev_queue->insert_event(event_data_); } } else { DataReadyEventData *event_data_ = new DataReadyEventData(event_callback_map[new_tango_host].device, const_cast(att_ready),event_name,errors); // if a callback method was specified, call it! if (callback != NULL ) { try { if (err_missed_event == true) callback->push_event(missed_ready_event_data); callback->push_event(event_data_); } catch (...) { string st("Tango::ZmqEventConsumer::push_structured_event() exception in callback method of "); st = st + ipos->first; print_error_message(st.c_str()); } delete event_data_; } // no calback method, the event has to be instered // into the event queue else { if (err_missed_event == true) { DataReadyEventData *missed_ready_event_data_copy = new DataReadyEventData; *missed_ready_event_data_copy = *missed_ready_event_data; ev_queue->insert_event(missed_ready_event_data_copy); } ev_queue->insert_event(event_data_); } } } } // End of for map_lock = false; map_modification_lock.readerOut(); delete missed_event_data; delete missed_conf_event_data; delete missed_ready_event_data; delete missed_dev_intr_event_data; delete missed_dev_pipe_data; break; } catch (DevFailed &e) { delete missed_event_data; delete missed_conf_event_data; delete missed_ready_event_data; delete missed_dev_intr_event_data; delete missed_dev_pipe_data; // free the map lock if not already done if ( map_lock == true ) { map_modification_lock.readerOut(); } string reason = e.errors[0].reason.in(); if (reason == API_CommandTimedOut) { string st("Tango::ZmqEventConsumer::push_structured_event() timeout on callback monitor of "); st = st + ipos->first; print_error_message(st.c_str()); } break; } catch (...) { delete missed_event_data; delete missed_conf_event_data; delete missed_ready_event_data; delete missed_dev_intr_event_data; // free the map lock if not already done if ( map_lock == true ) { map_modification_lock.readerOut(); } string st("Tango::ZmqEventConsumer::push_structured_event(): - "); st = st + ipos->first; st = st + " - Unknown exception (Not a DevFailed) while calling Callback "; print_error_message(st.c_str()); break; } } } // // In case of error // if (loop == env_var_fqdn_prefix.size() + 1) { string st("Event "); st = st + ev_name; st = st + " not found in event callback map !!!"; print_error_message(st.c_str()); // even if nothing was found in the map, free the lock map_modification_lock.readerOut(); } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::zmq_specific() // // description : // Do some ZMQ specific tasks like checking release compatibility or lower case the admin device name // which is used in the heartbeat event name. // // argument : // in : // - dd : The result of the event subscription command // - adm_name : The admin device name used in the heartbeat event // - device : The device proxy pointer (for error message) // - obj_name : The attribute/pipe name (for error message) // - ev_type : Event type // - ev_name : Event name // out: // - mod_ev_name : Boolean set to true if the event name is modified // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::zmq_specific(DeviceData &dd,string &adm_name,DeviceProxy *device,const string &obj_name) { const DevVarLongStringArray *ev_svr_data; dd >> ev_svr_data; // // For event coming from server still using Tango 8.0.x, do not lowercase the adm_name // if (ev_svr_data->lvalue[0] >= 810) transform(adm_name.begin(),adm_name.end(),adm_name.begin(),::tolower); // // If the event is configured to use multicast, check ZMQ release // string endpoint(ev_svr_data->svalue[1].in()); int ds_zmq_release = 0; if (ev_svr_data->lvalue.length() >= 6) ds_zmq_release = (ev_svr_data->lvalue[5]); int zmq_major,zmq_minor,zmq_patch; zmq_version(&zmq_major,&zmq_minor,&zmq_patch); // // Check for ZMQ compatible release. Impossible to check if server does not send which ZMQ release it is using. // if (ds_zmq_release == 310) { if (zmq_major != 3 || zmq_minor != 1 || zmq_patch != 0) { Except::throw_exception((const char *)API_UnsupportedFeature, (const char *)"Incompatibility between ZMQ releases between client and server!", (const char *)"EventConsumer::connect_event"); } } if (zmq_major == 3 && zmq_minor == 1 && zmq_patch == 0) { if (ds_zmq_release != 0 && ds_zmq_release != 310) { Except::throw_exception((const char *)API_UnsupportedFeature, (const char *)"Incompatibility between ZMQ releases between client and server!", (const char *)"EventConsumer::connect_event"); } } // // Check if multicasting is available (requires zmq 3.2.x) // if (endpoint.find(MCAST_PROT) != string::npos) { if (zmq_major == 3 && zmq_minor < 2) { TangoSys_OMemStream o; o << "The process is using zmq release "; o << zmq_major << "." << zmq_minor << "." << zmq_patch; o << "\nThe event on attribute or pipe " << obj_name << " for device " << device->dev_name(); o << " is configured to use multicasting"; o << "\nMulticast event(s) not available with this ZMQ release" << ends; Except::throw_exception((const char *)API_UnsupportedFeature, o.str(), (const char *)"EventConsumer::connect_event"); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::check_zmq_endpoint() // // description : // Check if the endpoint returned by the ZMQEventSubscriptionChange DS admin device command are valid on the // client side. // // argument : // in : // - endpoint : The returned endpoint (contain // // return : // A boolean set to true if it is possible to establish a connection with this endpoint. Otherwise, returns false // //-------------------------------------------------------------------------------------------------------------------- bool ZmqEventConsumer::check_zmq_endpoint(const string &endpoint) { // // Isolate IP address in endpoint // string::size_type pos = endpoint.rfind(':'); string ip = endpoint.substr(6,pos - 6); string port_str = endpoint.substr(pos + 1); int port = atoi(port_str.c_str()); // // Open a socket // struct sockaddr_in address; int result, len; long arg; int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockfd < 0) return false; address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr(ip.c_str()); address.sin_port = htons(port); len = sizeof(address); #ifdef _TG_WINDOWS_ // // Put socket in non-blocking mode // u_long iMode=1; ioctlsocket(sockfd,FIONBIO,&iMode); // // Try to connect // result = ::connect(sockfd, (struct sockaddr *)&address, len); if (result == SOCKET_ERROR) { int err_code = WSAGetLastError(); if (err_code == WSAEWOULDBLOCK) { struct timeval tv; fd_set myset; int res; tv.tv_sec = 0; tv.tv_usec = 100000; FD_ZERO(&myset); FD_SET(sockfd,&myset); // // Because socket is in non-blocking mode, call select to get connection status // res = select(sockfd + 1,NULL,&myset,NULL,&tv); if (res == 0) { closesocket(sockfd); return false; } else if (res < 0) { closesocket(sockfd); return false; } else if (res > 0) { socklen_t lon = sizeof(int); int valopt = 0; if (getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(char*)(&valopt),&lon) < 0) { closesocket(sockfd); return false; } if (valopt) { closesocket(sockfd); return false; } } } else { closesocket(sockfd); return false; } } // // Connection is a success, return true // closesocket(sockfd); #else // // Put socket in non-blocking mode // if ((arg = fcntl(sockfd,F_GETFL,NULL)) < 0) { close(sockfd); return false; } arg |= O_NONBLOCK; if (fcntl(sockfd,F_SETFL,arg) < 0) { close(sockfd); return false; } // // Try to connect // result = ::connect(sockfd, (struct sockaddr *)&address, len); if (result < 0) { if (errno == EINPROGRESS) { struct timeval tv; fd_set myset; int res; tv.tv_sec = 0; tv.tv_usec = 100000; FD_ZERO(&myset); FD_SET(sockfd,&myset); // // Because socket is in non-blocking mode, call select to get connection status // res = select(sockfd + 1,NULL,&myset,NULL,&tv); if (res == 0) { close(sockfd); return false; } else if (res < 0 && errno != EINTR) { close(sockfd); return false; } else if (res > 0) { socklen_t lon = sizeof(int); int valopt = 0; if (getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(void*)(&valopt),&lon) < 0) { close(sockfd); return false; } if (valopt) { close(sockfd); return false; } } } else { close(sockfd); return false; } } // // Connection is a success, return true // close(sockfd); #endif return true; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqEventConsumer::get_subscribed_event_ids() // // description : // Get event id for the DeviceProxy given as parameter // // argument : // in : // - _dev : The DeviceProxy object // out : // - _ids : Vector of event id for the given DeviceProxy // //-------------------------------------------------------------------------------------------------------------------- void ZmqEventConsumer::get_subscribed_event_ids(DeviceProxy *_dev,vector &_ids) { if (_ids.empty() == false) _ids.clear(); // // Lock the maps only for reading // ReaderLock r(map_modification_lock); // // Search with the callback_list map // EvCbIte epos; for (epos = event_callback_map.begin(); epos != event_callback_map.end(); ++epos) { if (epos->second.device == _dev) { vector::iterator ite; for (ite = epos->second.callback_list.begin();ite != epos->second.callback_list.end();++ite) { _ids.push_back(ite->id); } } } // // Search as well in the not connected event(s) vector // vector::iterator ite; for (ite = event_not_connected.begin();ite != event_not_connected.end();++ite) { if (ite->device == _dev) { _ids.push_back(ite->event_id); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqAttrValUnion::operator<<=() // // description : // Write our own unmarshalling method. The omniORB one allocate memory and copy data. We already have memory // allocated in the ZMQ message. No need to allocate once more and to copy data. We are doing this only for // attribute data. For the remaining, keep using omniORB stuff // // argument : // in : // - n : // //------------------------------------------------------------------------------------------------------------------- void ZmqAttrValUnion::operator<<= (TangoCdrMemoryStream& _n) { char *data_ptr; if (_n.get_un_marshal_type() == TangoCdrMemoryStream::UN_ATT) data_ptr = (char *)_n.bufPtr(); else data_ptr = (char *)_n.get_mkr_in_buf(); // // Get union discriminator from cdr and if data type is string or device_state let omniORB do its stuff. // Don't forget to rewind memory ptr before returning to omniORB // AttributeDataType _pd__d = ATT_BOOL; (AttributeDataType&)_pd__d <<= _n; if (_pd__d == ATT_STRING || _pd__d == DEVICE_STATE) { if (_n.get_un_marshal_type() == TangoCdrMemoryStream::UN_ATT) _n.rewindPtrs(); else _n.rewind_in(4); AttrValUnion::operator<<=(_n); } else { // // Get data length from cdr // _CORBA_ULong length; if (_pd__d != ATT_NO_DATA) { length <<= _n; if (length == 0) return; } // // Get att data depending on type // switch (_pd__d) { case ATT_SHORT: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_2); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_DOUBLE: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_8); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_FLOAT: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_4); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_USHORT: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_2); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_BOOL: { init_seq(data_ptr,length,_n); } break; case ATT_LONG: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_4); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_LONG64: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_8); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_ULONG: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_4); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_ULONG64: { omni::ptr_arith_t in = (omni::ptr_arith_t)_n.get_mkr_in_buf(); omni::ptr_arith_t p1 = _n.align_to(in,omni::ALIGN_8); _n.set_mkr_in_buf((void *)p1); init_seq(data_ptr,length,_n); } break; case ATT_UCHAR: { init_seq(data_ptr,length,_n); } break; case ATT_STATE: { init_seq(data_ptr,length,_n); } break; // // We have special cases for DevEncoded (a structure) and ATT_NO_DATA // case ATT_ENCODED: { DevVarEncodedArray dummy_seq; encoded_att_value(dummy_seq); DevVarEncodedArray &dvea = encoded_att_value(); dvea.length(length); for (_CORBA_ULong i = 0;i < length;i++) { dvea[i].encoded_format = _n.unmarshalString(0); _CORBA_ULong seq_length; seq_length <<= _n; _CORBA_Octet *ptr = (_CORBA_Octet *)(data_ptr + _n.currentInputPtr()); dvea[i].encoded_data.replace(seq_length,seq_length,ptr,false); _n.tango_get_octet_array((seq_length * sizeof(_CORBA_Octet))); } } break; case ATT_NO_DATA: { DevBoolean bo; bo = _n.unmarshalBoolean(); union_no_data(bo); } break; default: assert(false); } } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqAttributeValue_4::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqAttributeValue_4::operator<<= (TangoCdrMemoryStream &_n) { (ZmqAttrValUnion&)zvalue <<= _n; (AttrQuality&)quality <<= _n; (AttrDataFormat&)data_format <<= _n; (TimeVal&)time <<= _n; name = _n.unmarshalString(0); (AttributeDim&)r_dim <<= _n; (AttributeDim&)w_dim <<= _n; (DevErrorList&)err_list <<= _n; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqAttributeValue_5::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqAttributeValue_5::operator<<= (TangoCdrMemoryStream &_n) { (ZmqAttrValUnion&)zvalue <<= _n; (AttrQuality&)quality <<= _n; (AttrDataFormat&)data_format <<= _n; data_type <<= _n; (TimeVal&)time <<= _n; name = _n.unmarshalString(0); (AttributeDim&)r_dim <<= _n; (AttributeDim&)w_dim <<= _n; (DevErrorList&)err_list <<= _n; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqDevPipeData::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqDevPipeData::operator<<= (TangoCdrMemoryStream &_n) { name = _n.unmarshalString(0); (TimeVal&)time <<= _n; (ZmqDevPipeBlob&)data_blob <<= _n; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqDevPipeBlob::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqDevPipeBlob::operator<<= (TangoCdrMemoryStream &_n) { name = _n.unmarshalString(0); (ZmqDevVarPipeDataEltArray&)blob_data <<= _n; } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqDevVarPipeDataEltArray::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqDevVarPipeDataEltArray::operator<<= (TangoCdrMemoryStream &_n) { _CORBA_ULong _l; _l <<= _n; if (!_n.checkInputOverrun(1,_l)) { _CORBA_marshal_sequence_range_check_error(_n); // never reach here } length(_l); for( _CORBA_ULong _i = 0; _i < _l; _i++ ) { DevPipeDataElt &dpde = pd_buf[_i]; ZmqDevPipeDataElt &z_dpde = static_cast(dpde); z_dpde <<= _n; } } //-------------------------------------------------------------------------------------------------------------------- // // method : // ZmqDevPipeDataElt::operator<<=() // // description : // // argument : // in : // //-------------------------------------------------------------------------------------------------------------------- void Tango::ZmqDevPipeDataElt::operator<<= (TangoCdrMemoryStream &_n) { name = _n.unmarshalString(0); (ZmqAttrValUnion&)value <<= _n; (ZmqDevVarPipeDataEltArray&)inner_blob <<= _n; inner_blob_name = _n.unmarshalString(0); } //--------------------------------------------------------------------------------------------------------------------- // // method : // DelayEvent::DelayEvent // // description : // A class to ask the ZMQ main thread to stop receiving external event. This is necessary to prevent a possible // deadlock which could happen if an event is received while a user is calling subscribe or unsubscribe event // // argument : // in : // - ec : Event consumer pointer // //-------------------------------------------------------------------------------------------------------------------- DelayEvent::DelayEvent(EventConsumer *ec):released(false),eve_con(NULL) { string str; ec->get_subscription_command_name(str); // // Do something only for ZMQ event system // if (str[0] == 'Z') { eve_con = static_cast(ec); zmq::message_t reply; try { zmq::socket_t sender(eve_con->zmq_context,ZMQ_REQ); // // In case this thread runs before the main ZMQ thread, it is possible to call connect before the main ZMQ thread has // binded its socket. In such a case, error code is set to ECONNREFUSED. If this happens, give the main ZMQ thread a // chance to run and retry the connect call. // I have tried with a yield call but it still failed in some cases (when running the DS with a file as database for // instance). Replace the yield with a 15 mS sleep !!! // // Since ZMQ 4, itÅ› possible to connect to the remote socket event if it is not yet bound but the remote // socket will hang in the its recev call!!!! // We still need the sleep call but not in the exception case // try { sender.connect(CTRL_SOCK_ENDPOINT); if (eve_con->is_ctrl_sock_bound() == false) { #ifndef _TG_WINDOWS_ struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 15000000; nanosleep(&ts,NULL); #else Sleep(20); #endif } } catch (zmq::error_t &e) { if (e.num() == ECONNREFUSED) { #ifndef _TG_WINDOWS_ struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 15000000; nanosleep(&ts,NULL); #else Sleep(20); #endif sender.connect(CTRL_SOCK_ENDPOINT); } else throw; } // // Build message sent to ZMQ main thread. In this case, this is only a command code // char buffer[10]; int length = 0; buffer[length] = ZMQ_DELAY_EVENT; length++; eve_con->subscription_monitor.get_monitor(); // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); } catch (zmq::error_t &e) { eve_con->subscription_monitor.rel_monitor(); TangoSys_OMemStream o; o << "Failed to delay event!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"DelayEvent::DelayEvent"); } // // In case of error returned by the main ZMQ thread // if (reply.size() != 2) { eve_con->subscription_monitor.rel_monitor(); char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; TangoSys_OMemStream o; o << "Failed to delay events!\n"; o << "Error while asking the ZMQ thread to delay events\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"DelayEvent::DelayEvent"); } } } DelayEvent::~DelayEvent() { if (released == false) release(); } void DelayEvent::release() { if (eve_con != NULL) { zmq::message_t reply; try { zmq::socket_t sender(eve_con->zmq_context,ZMQ_REQ); sender.connect(CTRL_SOCK_ENDPOINT); // // Build message sent to ZMQ main thread. In this case, this is only a command code // char buffer[10]; int length = 0; buffer[length] = ZMQ_RELEASE_EVENT; length++; // // Send command to main ZMQ thread // zmq::message_t send_data(length); ::memcpy(send_data.data(),buffer,length); sender.send(send_data); sender.recv(&reply); released = true; eve_con->subscription_monitor.rel_monitor(); } catch (zmq::error_t &e) { eve_con->subscription_monitor.rel_monitor(); TangoSys_OMemStream o; o << "Failed to delay event!\n"; o << "Error while communicating with the ZMQ main thread\n"; o << "ZMQ message: " << e.what() << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"DelayEvent::release"); } // // In case of error returned by the main ZMQ thread // if (reply.size() != 2) { char err_mess[512]; ::memcpy(err_mess,reply.data(),reply.size()); err_mess[reply.size()] = '\0'; TangoSys_OMemStream o; o << "Failed to release event!\n"; o << "Error while trying to ask the ZMQ thread to release events\n"; o << "ZMQ message: " << err_mess << ends; Except::throw_exception((const char *)API_ZmqFailed, o.str(), (const char *)"DelayEvent::release"); } } } } /* End of Tango namespace */ tango-9.2.5a/lib/cpp/client/helpers/0000755023471100065110000000000013034745260014262 500000000000000tango-9.2.5a/lib/cpp/client/helpers/Makefile.am0000644023471100065110000000033713034744771016247 00000000000000 tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = DeviceProxyHelper.h \ PogoHelper.h \ TangoExceptionsHelper.h \ Xstring.h tango-9.2.5a/lib/cpp/client/helpers/Makefile.in0000644023471100065110000004307713034745122016257 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/cpp/client/helpers DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(tangoinclude_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(tangoincludedir)" HEADERS = $(tangoinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = DeviceProxyHelper.h \ PogoHelper.h \ TangoExceptionsHelper.h \ Xstring.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/cpp/client/helpers/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/cpp/client/helpers/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tangoincludeHEADERS: $(tangoinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tangoincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tangoincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(tangoincludedir)" || exit $$?; \ done uninstall-tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(tangoincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-tangoincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-tangoincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool ctags distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-tangoincludeHEADERS installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags uninstall uninstall-am \ uninstall-tangoincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/cpp/client/helpers/DeviceProxyHelper.h0000644023471100065110000011260113034744771017763 00000000000000//+============================================================================= // // project : TANGO Utility // file : DeviceProxyHelper.h: // $Revision: 27410 $ // // // description : This utility class helps to use command_inout,read_attributes and write_attribute(s) // on a DeviceProxy , from a Tango C++ Client. // Its role is : // - to provide syntactic sugar to avoid the heavy manipulation of DeviceData objects // used to exchange data between a C++ client and a server // - to handle exception in an uniform way using the TangoExceptionHelper.h file // // Usage examples : // // Step 1) create a DeviceProxyHelper object (in your client init_device for instance) // // tangoCA = new DeviceProxyHelper("lucia/sls/tangoca",this); // ==> A DeviceProxy is internally created by DeviceProxyHelper ( note : the this pointer is used for logging purpose) // // Step 2) USE your remote Device !! // // FOR COMMANDS (Note that DEVVARSTRINGARRAY argin or argout types are not supported) // There are 4 methods: // -command (no argin,no argout) // -command_in (only argin) // -command_out (only argout) // -command_inout (argin and argout) // Note : the methods are Templates so you don't care about type (while they are supported by DeviceData!!!) // // COMMAND EXAMPLES : // a) execute Command Reset on the deviceProxy : No argin nor argout required // tangoCA->command("Reset"); // // b) execute Command GotoPosition on the deviceProxy with argin= 12.3 // tangoCA->command_in("GotoPosition", 12.3); // // c) execute Command ReadPosition on the deviceProxy : argout will be put in read_value // tangoCA->command_out("ReadPosition", read_value); // // d) execute Command ReadDoublePv on the deviceProxy : verticalGapPV.c_str() is the argin and *attr_VerticalGap_read is the argout. // tangoCA->command_inout("ReadDoublePV",verticalGapPV.c_str(), // *attr_VerticalGap_read) // ==> Automatically the CommandInOutHelper has done all the DeviceData encapsulation // and transfers the result of the command_inout in your argout // // // Handling of composite type like DEVVARSTRINGARRAY in argin and/or argout (with = LONG or DOUBLE): // The part and the STRING part must be seperated by user in two vectors, std::vector and std::vector. // The following must be called: // // - command with argin only: // void command_in ( // const std::string& cmd_name, // const std::vector<_IN>& _nv_in, // numerical part of the input DEVVARSTRINGARRAY // const std::vector& _sv_in // string part of the input DEVVARSTRINGARRAY // ) // // - command with argout only: // void command_out ( // const std::string& cmd_name, // std::vector<_OUT>& _nv_out, // numerical part of the ouput DEVVARSTRINGARRAY // std::vector& _sv_out // string part of the ouput DEVVARSTRINGARRAY // ) // // - command with argin and argout: // void command_inout ( // const std::string& cmd_name, // const std::vector<_IN>& _nv_in, // numerical part of the input DEVVARSTRINGARRAY // const std::vector& _sv_in, // string part of the input DEVVARSTRINGARRAY // std::vector<_OUT>& _nv_out, // numerical part of the ouput DEVVARSTRINGARRAY // std::vector& _sv_out // string part of the ouput DEVVARSTRINGARRAY // ) // // // ATTRIBUTES EXAMPLES : // a) execute read_attribute on the deviceProxy and store value in omega_on_axis variable // _omegaProxy_helper ->read_attribute("AxisCurrentPosition" , omega_on_axis); // // b) execute write_attribute on the deviceProxy and with argin = 12.3 // _omegaProxy_helper -> write_attribute("AxisCurrentPosition", 12.3); // // // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // $Revision: 27410 $ // // $Log$ // Revision 1.8 2010/09/21 12:08:44 taurel // - Added GPL header // // Revision 1.7 2008/03/31 07:22:46 jensmeyer // Added helper classes to Tango library. // // // Revision 1.6 2008/02/13 13:20:30 langlois // - merge from linux version // // Revision 1.1 2006/03/16 14:03:18 dupuy // soleil distrib 2 // // Revision 1.2 2006/03/14 14:58:42 hardion // * Update DeviceProxyHelper with Florent modification ( read the write part of an attribute) // // Revision 1.3 2005/04/27 10:22:28 buteau // - Under linux , for all methods of DeviceProxyHelper (i.e read_attribute, command_in, command_out , etc .. ) , the filename and the line number of client Device appears in Exceptions (instead of line number and filenmae in DeviceProxyHelper.h) // - under WIN32, VC++6 : same feature but only on read_attribute, write_attribute, command methods of DeviceProxyHelper // - minor fixes following E. Taurel remarks // // Revision 1.2 2004/08/06 09:20:45 langlois // - Added a getter for the DeviceProxy // // Revision 1.1.1.1 2004/07/13 15:39:53 root // inital import // // Revision 1.0 10/07/2003 langlois // - Changed the only one command_inout overloaded 4 times by four differents methods: // -command (no argin,no argout) // -command_inout (argin and argout) // -command_in (only argin) // -command_out (only argout) // // Revision 0.0 30/06/2003 langlois // - First version: 1 template methods command_inout overloaded 4 times // // #ifndef _DEVICE_PROXY_HELPER_H_ #define _DEVICE_PROXY_HELPER_H_ //============================================================================= // DEPENDENCIES //============================================================================= #include //============================================================================= // MACRO //============================================================================= #define FULL_CMD_NAME(C) device_proxy_->dev_name() + "::" + C #define FULL_ATTR_NAME(A) device_proxy_->dev_name() + "/" + A // // Definition of macros to benefit from expansion of __FILE__ and __LINE__ keywords in Device caller source file // #define read_attribute(ATTR_NAME, VALUE) internal_read_attribute (ATTR_NAME, VALUE, __FILE__, __LINE__) #define read_attribute_w(ATTR_NAME, VALUE) internal_read_attribute_w (ATTR_NAME, VALUE, __FILE__, __LINE__) #define write_attribute(ATTR_NAME, VALUE) internal_write_attribute (ATTR_NAME, VALUE, __FILE__, __LINE__) #define command(CMD_NAME) internal_command (CMD_NAME, __FILE__, __LINE__) // For VC++ 6 VA_ARG macro is not supported so ==>, we cannot override command_out functions #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_out internal_command_out #else // For compilers that support variable number of arguments #define command_out(CMD_NAME, OUT, ...) internal_command_out (CMD_NAME, OUT, ## __VA_ARGS__, __FILE__, __LINE__ ) #endif // For VC++ 6 VA_ARG macro is not supported so ==>, we cannot override command_in functions #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_in internal_command_in #else // For compilers that support variable number of arguments #define command_in(CMD_NAME, IN, ...) internal_command_in (CMD_NAME, IN, ## __VA_ARGS__, __FILE__, __LINE__ ) #endif // For VC++ 6 VA_ARG macro is not supported so ==>, we cannot override command_inout functions #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #else // For compilers that support variable number of arguments #define command_inout(CMD_NAME, ...) internal_command_inout (CMD_NAME, ## __VA_ARGS__, __FILE__, __LINE__ ) #endif namespace Tango { //============================================================================= // CLASS: HelperBase //============================================================================= class HelperBase : public Tango::LogAdapter { public: //--------------------------------------------------------------------------- // HelperBase::get_device_proxy // returns the underlying device //--------------------------------------------------------------------------- inline Tango::DeviceProxy* get_device_proxy (void) { return device_proxy_; } //--------------------------------------------------------------------------- // HelperBase::operator-> // returns the underlying device //--------------------------------------------------------------------------- inline Tango::DeviceProxy* operator-> (void) { return device_proxy_; } protected: //--------------------------------------------------------------------------- // HelperBase::HelperBase (ctor) // device_name : The name of the target device. // client_device : Reference to the client device (for logging purpose). //--------------------------------------------------------------------------- HelperBase (const std::string& device_name, Tango::DeviceImpl *client_device = 0) throw (Tango::DevFailed) : Tango::LogAdapter(client_device), device_proxy_(0) { _DEV_TRY_REACTION ( //- try device_proxy_ = new Tango::DeviceProxy(const_cast(device_name)), //- what do we tried std::string("new Tango::DeviceProxy on ") + device_name, //- origin "HelperBase::HelperBase", //- reaction if (device_proxy_) {delete device_proxy_; device_proxy_ = 0;} ); } //--------------------------------------------------------------------------- // HelperBase::~HelperBase (dtor) //--------------------------------------------------------------------------- virtual ~HelperBase () { if (device_proxy_) { delete device_proxy_; device_proxy_ = 0; } } //--------------------------------------------------------------------------- //- the underlying device //--------------------------------------------------------------------------- Tango::DeviceProxy* device_proxy_; }; //============================================================================= // CLASS: CommandInOutHelper //============================================================================= class CommandInOutHelper : public virtual HelperBase { public: //--------------------------------------------------------------------------- // CommandInOutHelper::CommandInOutHelper (ctor) // device_name : The name of the target device. // client_device : Reference to the client device (for logging purpose). //--------------------------------------------------------------------------- CommandInOutHelper (const std::string& device_name, Tango::DeviceImpl *client_device = 0) : HelperBase(device_name, client_device) { dd_out_.exceptions(Tango::DeviceData::isempty_flag | Tango::DeviceData::wrongtype_flag); } //--------------------------------------------------------------------------- // CommandInOutHelper::~CommandInOutHelper (dtor) //--------------------------------------------------------------------------- virtual ~CommandInOutHelper () { //- noop dtor } //--------------------------------------------------------------------------- // CommandInOutHelper::command // exec a DEV_VOID/DEV_VOID TANGO command on the underlying device // cmd_name : The name of the TANGO command //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif void internal_command (const std::string& cmd_name, std::string file, int line) throw (Tango::DevFailed) { if (device_proxy_) { _DEV_TRY_FILE_LINE ( //- try (device_proxy_->command_inout)(const_cast(cmd_name)), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // exec a ARG_OUT/ARG_IN TANGO command on the underlying device // cmd_name : the name of the TANGO command // argin : input argument // argout : output argument //--------------------------------------------------------------------------- // template arg _IN must be supported by DeviceData::operator<< // template arg _OUT must be supported by DeviceData::operator>> //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_inout (const std::string& cmd_name, const _IN& argin, _OUT& argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { Tango::DeviceData dd_in; dd_in << const_cast<_IN&>(argin); _DEV_TRY_FILE_LINE ( //- try dd_out_ = (device_proxy_->command_inout)(const_cast(cmd_name), dd_in), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_inout", file, line ); _DEV_TRY_FILE_LINE ( //- try dd_out_ >> argout, //- what do we tried std::string("DeviceData::operator>> on data returned by ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_inout", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // exec a DEVVARSTRINGARRAY/DEVVARSTRINGARRAY command on the underlying device // cmd_name : the name of the TANGO command // _nv_in : numerical part of the input DEVVARSTRINGARRAY // _sv_in : string part of the input DEVVARSTRINGARRAY // _nv_out : numerical part of the ouput DEVVARSTRINGARRAY // _sv_out : string part of the ouput DEVVARSTRINGARRAY //--------------------------------------------------------------------------- // template arg _IN must be supported by DeviceData::.insert // template arg _OUT must be supported by DeviceData::.insert //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_inout (const std::string& cmd_name, const std::vector<_IN>& _nv_in, const std::vector& _sv_in, std::vector<_OUT>& _nv_out, std::vector& _sv_out, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { Tango::DeviceData dd_in; dd_in.insert(const_cast&>(_nv_in), const_cast&>(_sv_in)); _DEV_TRY_FILE_LINE ( //- try dd_out_ = (device_proxy_->command_inout)(const_cast(cmd_name), dd_in), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_inout", file, line ); _DEV_TRY_FILE_LINE ( //- try dd_out_.extract(_nv_out, _sv_out), //- what do we tried std::string("DeviceData::extract on data returned by ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_inout", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // Overloaded commands to avoid usage of DevVarXX ARRAY for argout //--------------------------------------------------------------------------- template void internal_command_inout (const std::string& cmd_name, const _IN& argin, DevVarDoubleStringArray* argout,std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_inout:Use only STL vector instead of DevVarDoubleStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // Overloaded commands to avoid usage of DevVarXX ARRAY for argout //--------------------------------------------------------------------------- template void internal_command_inout (const std::string& cmd_name, const _IN& argin, DevVarLongStringArray* argout,std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_inout:Use only STL vector instead of DevVarLongStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // Overloaded commands to avoid usage of DevVarXX ARRAY for argout //--------------------------------------------------------------------------- template void internal_command_inout (const std::string& cmd_name, const _IN& argin, DevVarDoubleStringArray& argout,std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_inout:Use only STL vector instead of DevVarDoubleStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_inout // Overloaded commands to avoid usage of DevVarXX ARRAY for argout //--------------------------------------------------------------------------- template void internal_command_inout (const std::string& cmd_name, const _IN& argin, DevVarLongStringArray& argout,std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_inout:Use only STL vector instead of DevVarLongStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_in // exec a DEV_VOID/ARG_IN TANGO command on the underlying device // cmd_name : the name of the TANGO command // argin : input argument // dummy : used to have same number of parameter for the 2 command_in methods //--------------------------------------------------------------------------- // template arg _IN must be supported by DeviceData::operator<< //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_in (const std::string& cmd_name, const _IN& argin, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { Tango::DeviceData dd_in; dd_in << const_cast<_IN&>(argin); _DEV_TRY_FILE_LINE ( //- try (device_proxy_->command_inout)(const_cast(cmd_name), dd_in), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_in", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_in // exec a DEV_VOID/DEVVARSTRINGARRAY command on the underlying device // cmd_name : the name of the TANGO command // _nv_in : numerical part of the input DEVVARSTRINGARRAY // _sv_in : string part of the input DEVVARSTRINGARRAY //--------------------------------------------------------------------------- // template arg _IN must be supported by DeviceData::.insert //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_in (const std::string& cmd_name, const std::vector<_IN>& _nv_in, const std::vector& _sv_in, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { Tango::DeviceData dd_in; dd_in.insert(const_cast&>(_nv_in), const_cast&>(_sv_in)); _DEV_TRY_FILE_LINE ( //- try (device_proxy_->command_inout)(const_cast(cmd_name), dd_in), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_in", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_out // exec a ARG_OUT/DEV_VOID TANGO command on the underlying device // cmd_name : the name of the TANGO command // argout : output argument //--------------------------------------------------------------------------- // template arg _OUT must be supported by DeviceData::operator>> //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_out (const std::string& cmd_name, _OUT& argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { _DEV_TRY_FILE_LINE ( //- try dd_out_ = (device_proxy_->command_inout)(const_cast(cmd_name)), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_out", file, line ); _DEV_TRY_FILE_LINE ( //- try dd_out_ >> argout, //- what do we tried std::string("DeviceData::operator>> on data returned by ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_out", file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif //--------------------------------------------------------------------------- // CommandInOutHelper::command_out // Overloaded commands to avoid usage of DevVarDoubleStringArray ARRAY //--------------------------------------------------------------------------- template void internal_command_out(_OUT dummy, DevVarDoubleStringArray* argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_out:Use only STL vector instead of DevVarDoubleStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_out // Overloaded commands to avoid usage of DevVarLongStringArray ARRAY //--------------------------------------------------------------------------- template void internal_command_out (_OUT dummy, DevVarLongStringArray* argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_out:Use only STL vector instead of DevVarLongStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_out // Overloaded commands to avoid usage of DevVarDoubleStringArray ARRAY //--------------------------------------------------------------------------- template void internal_command_out(_OUT dummy, DevVarDoubleStringArray& argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_out:Use only STL vector instead of DevVarDoubleStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_out // Overloaded commands to avoid usage of DevVarLongStringArray ARRAY //--------------------------------------------------------------------------- template void internal_command_out (_OUT dummy, DevVarLongStringArray& argout, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { #if (defined(_MSC_VER) && _MSC_VER < 1300) #pragma message (" TANGO WARNING ***** command_out:Use only STL vector instead of DevVarLongStringArray *****") #endif TangoSys_OMemStream o; o << " [" << file << "::" << line << "]" << std::ends; Tango::Except::throw_exception(static_cast("TANGO_WRONG_DATA_ERROR"), static_cast("Use only STL vector instead of DevVarXXStringArray"), static_cast(o.str().c_str())); } //--------------------------------------------------------------------------- // CommandInOutHelper::command_in // exec a DEV_VOID/DEVVARSTRINGARRAY command on the underlying device // cmd_name : the name of the TANGO command // _nv_out : numerical part of the output DEVVARSTRINGARRAY // _sv_out : string part of the output DEVVARSTRINGARRAY //--------------------------------------------------------------------------- // template arg _OUT must be supported by DeviceData::.extract //--------------------------------------------------------------------------- #if (defined(_MSC_VER) && _MSC_VER < 1300) #undef command_inout // Must avoid macro expansion #endif template void internal_command_out (const std::string& cmd_name, std::vector<_OUT>& _nv_out, std::vector& _sv_out, std::string file= __FILE__, int line= __LINE__) throw (Tango::DevFailed) { if (device_proxy_) { _DEV_TRY_FILE_LINE ( //- try dd_out_ = (device_proxy_->command_inout)(const_cast(cmd_name)), //- what do we tried std::string("command_inout on ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_out", file, line ); _DEV_TRY_FILE_LINE ( //- try dd_out_.extract(_nv_out, _sv_out), //- what do we tried std::string("DeviceData::extract on data returned by ") + FULL_CMD_NAME(cmd_name), //- origin "CommandInOutHelper::command_out" , file, line ); } } #if (defined(_MSC_VER) && _MSC_VER < 1300) #define command_inout internal_command_inout #endif private: //- placed here as a workaround due to CORBA::any_var limitations Tango::DeviceData dd_out_; }; //============================================================================= // CLASS: AttributeHelper //============================================================================= class AttributeHelper : public virtual HelperBase { public: //--------------------------------------------------------------------------- // AttributeHelper::AttributeHelper (ctor) // device_name : name of the target device // client_device : reference to the client device (for logging purpose) //--------------------------------------------------------------------------- AttributeHelper (const std::string& device_name, Tango::DeviceImpl *client_device = 0) : HelperBase(device_name, client_device) { da_out_.exceptions(Tango::DeviceAttribute::isempty_flag | Tango::DeviceAttribute::wrongtype_flag); } //--------------------------------------------------------------------------- // AttributeHelper::~AttributeHelper (dtor) //--------------------------------------------------------------------------- virtual ~AttributeHelper () { //- noop dtor } //--------------------------------------------------------------------------- // AttributeHelper::get_device_attribute //--------------------------------------------------------------------------- Tango::DeviceAttribute get_device_attribute () { return da_out_; } //--------------------------------------------------------------------------- // AttributeHelper::write_attribute // writes the specified attribute // attr_name : name of the TANGO attribute to be written // attr_value : the attribute value //--------------------------------------------------------------------------- // template arg _VAL must be supported by DeviceAttribute::operator<< //--------------------------------------------------------------------------- template void internal_write_attribute (const std::string& attr_name, const _VAL& attr_value, std::string file, int line) throw (Tango::DevFailed) { if (device_proxy_) { DeviceAttribute da; da.set_name(const_cast(attr_name)); da << const_cast<_VAL&>(attr_value); _DEV_TRY_FILE_LINE ( //- try (device_proxy_->write_attribute)(da), //- what do we tried std::string("write_attribute on ") + FULL_ATTR_NAME(attr_name), //- origin "AttributeHelper::write_attribute", file, line ); } } //--------------------------------------------------------------------------- // AttributeHelper::read_attribute // reads the specified attribute // attr_name : the name of the TANGO attribute to be read // attr_value : the attribute value //--------------------------------------------------------------------------- // template arg _VAL must be supported by DeviceAttribute::operator>> //--------------------------------------------------------------------------- template void internal_read_attribute (const std::string& attr_name, _VAL& attr_value, std::string file, int line ) throw (Tango::DevFailed) { if (device_proxy_) { _DEV_TRY_FILE_LINE ( //- try da_out_ = (device_proxy_->read_attribute)(const_cast(attr_name)), //- what do we tried std::string("read_attribute on ") + FULL_ATTR_NAME(attr_name), //- origin "AttributeHelper::read_attribute", file, line ); _DEV_TRY_FILE_LINE ( //- try da_out_ >> attr_value, //- what do we tried std::string("DeviceAttribute::operator>> on data returned by ") + FULL_ATTR_NAME(attr_name), //- origin "AttributeHelper::read_attribute", file, line ); } } //--------------------------------------------------------------------------- // AttributeHelper::read_attribute_w // reads the specified attribute and get its write value // attr_name : the name of the TANGO attribute to be read // w_attr_value : the write attribute value //--------------------------------------------------------------------------- // template arg _VAL must be supported by DeviceAttribute::operator>> //--------------------------------------------------------------------------- template void internal_read_attribute_w (const std::string& attr_name, _VAL& w_attr_value, std::string file, int line ) throw (Tango::DevFailed) { if (device_proxy_) { _DEV_TRY_FILE_LINE ( //- try da_out_ = (device_proxy_->read_attribute)(const_cast(attr_name)), //- what do we tried std::string("read_attribute on ") + FULL_ATTR_NAME(attr_name), //- origin "AttributeHelper::read_attribute_w", file, line ); //=========================================================================== //== //== TEST BY FL //== //=========================================================================== //- Switch on attribute type try { switch(da_out_.get_type()) { case Tango::DEV_BOOLEAN: { w_attr_value = da_out_.BooleanSeq[1]; break; } case Tango::DEV_SHORT: case Tango::DEV_ENUM: { w_attr_value = da_out_.ShortSeq[1]; break; } case Tango::DEV_LONG: { w_attr_value = da_out_.LongSeq[1]; break; } case Tango::DEV_FLOAT: { w_attr_value = da_out_.FloatSeq[1]; break; } case Tango::DEV_DOUBLE: { w_attr_value = da_out_.DoubleSeq[1]; break; } default: { Tango::Except::throw_exception( static_cast("TANGO_NON_SUPPORTED_FEATURE_ERROR"), static_cast("This type is not supported"), static_cast("AttributeHelper::read_attribute_w")); break; } } //INFO_STREAM << "w_attr_value = " << w_attr_value << ENDLOG; } _HANDLE_DEV_EXCEPTION("get_type()","AttributeHelper::read_attribute_w"); //=========================================================================== //== //== END TEST BY FL //== //=========================================================================== } } private: //- placed here as a workaround due to CORBA::any_var limitations Tango::DeviceAttribute da_out_; }; //============================================================================= // CLASS: DeviceProxyHelper //============================================================================= class DeviceProxyHelper : public CommandInOutHelper, public AttributeHelper { public: //--------------------------------------------------------------------------- // DeviceProxyHelper::DeviceProxyHelper (ctor) // device_name : name of the target device // client_device : reference to the client device (for logging purpose) //--------------------------------------------------------------------------- DeviceProxyHelper (const std::string& device_name, DeviceImpl *client_device = 0) : HelperBase(device_name, client_device), CommandInOutHelper(device_name, client_device), AttributeHelper(device_name, client_device) { //- noop ctor } //--------------------------------------------------------------------------- // DeviceProxyHelper::~DeviceProxyHelper (dtor) //--------------------------------------------------------------------------- virtual ~DeviceProxyHelper () { //- noop dtor } }; } //- namespace tango #endif // _DEVICE_PROXY_HELPER_H_ tango-9.2.5a/lib/cpp/client/helpers/PogoHelper.h0000644023471100065110000001430113034744771016424 00000000000000//+============================================================================= // // project : TANGO Utility // file : PogoHelper.h: // $Revision: 27410 $ // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . // // description : This utility class helps to allocate and desallocate READ attributes // as POGO only generates pointers and let the Device developper manage memory allocation // // Note : these functions also initialise to a default value the allocated attributes // Usage examples : // // CREATE_SCALAR_ATTRIBUTE(attr_hCoordinate_read); // by default initialised to 0 // CREATE_SCALAR_ATTRIBUTE(attr_hCoordinate_read,1); // initialised to 1 // DELETE_SCALAR_ATTRIBUTE(attr_hCoordinate_read) // // CREATE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read,MAX_STRING_LENGTH);// by default initialised to "" // CREATE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read,MAX_STRING_LENGTH,"No U Matrix available"); // DELETE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read) // // CREATE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read,MAX_LENGTH);// by default initialised to 0 // CREATE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read,MAX_LENGTH, 1); // DELETE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read); //----------------------------------------------------------------------------- // // function to delete a scalar attribut : You must pass the pointer to the attributs // Usage : DELETE_SCALAR_ATTRIBUTE(attr_hCoordinate_read); //----------------------------------------------------------------------------- template void DELETE_SCALAR_ATTRIBUTE(_SCALAR* attributeName) { if(attributeName) { delete attributeName; attributeName = 0; } } //============================================================================= // function to allocate and initialise a read SCALAR attribute as generated by POGO // Usage : ex : CREATE_SCALAR_ATTRIBUTE(attr_hCoordinate_read); //============================================================================= template void CREATE_SCALAR_ATTRIBUTE(_SCALAR*& attributeName,_SCALAR default_value=0) { attributeName = new _SCALAR; if(attributeName == 0) { TangoSys_OMemStream o; o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends; Tango::Except::throw_exception ( (const char *)"OUT OF MEMORY", (const char *)"out of memory error", (const char *)(o.str().c_str())); } // then initialise scalar (*attributeName) = (_SCALAR) default_value; } //============================================================================= // function to allocate and initialise a DevString SCALAR attribute as generated by POGO // Usage : ex : CREATE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read,MAX_STRING_LENGTH,"No U Matrix available"); //============================================================================= inline void CREATE_DEVSTRING_ATTRIBUTE(Tango::DevString*& attributeName, const int length, const char* init_string="") { attributeName = new char*; if(attributeName == 0) { TangoSys_OMemStream o; o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends; Tango::Except::throw_exception ( (const char *)"OUT OF MEMORY", (const char *)"out of memory error", (const char *)(o.str().c_str())); } //std::cout << length << std::endl; (*attributeName) = new char[length]; if((*attributeName) == 0) { TangoSys_OMemStream o; o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends; Tango::Except::throw_exception ( (const char *)"OUT OF MEMORY", (const char *)"out of memory error", (const char *)(o.str().c_str())); } ::strcpy(*attributeName, init_string); } //----------------------------------------------------------------------------- // // function to delete a DevString attribut : You must pass the pointer to the attributs // Usage : DELETE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read) //----------------------------------------------------------------------------- inline void DELETE_DEVSTRING_ATTRIBUTE(Tango::DevString* attributeName) { if(attributeName) { if(*attributeName) delete [] (*attributeName); delete attributeName; attributeName = 0; } } //============================================================================= // function to allocate and initialise a read SPECTRUM attribute as generated by POGO // Usage : ex : CREATE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read,MAX_LENGTH); //============================================================================= // template void CREATE_SPECTRUM_ATTRIBUTE(_SPECTRUM *& attributeName, const int size, _SPECTRUM default_value=0) { attributeName = new _SPECTRUM[size]; if(attributeName == 0) { TangoSys_OMemStream o; o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends; Tango::Except::throw_exception ( (const char *)"OUT OF MEMORY", (const char *)"out of memory error", (const char *)(o.str().c_str())); } std::fill( attributeName, attributeName + size, default_value ); } //============================================================================= // function to desallocate a read SPECTRUM attribute as generated by POGO // Usage : ex : DELETE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read); //============================================================================= // template void DELETE_SPECTRUM_ATTRIBUTE(_SPECTRUM * attributeName ) { if(attributeName) { delete [] (attributeName); } } tango-9.2.5a/lib/cpp/client/helpers/TangoExceptionsHelper.h0000644023471100065110000002574713034744771020652 00000000000000// // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . //----------------------------------------------------------------------------- // WINDOWS PRAGMA //----------------------------------------------------------------------------- #if defined (WIN32) # pragma warning (disable : 4286) #endif //----------------------------------------------------------------------------- // DEFINE A SPECIAL VERSION OF TANGO ERROR_STREAM MACRO SO THAT FOLLOWING // MACROS CAN BE SAFELY USED FROM C++ (PURE) CLIENT WHERE THERE IS NO // INSTANCIATED LOGGER //----------------------------------------------------------------------------- #define _ERROR_STREAM \ if (get_logger() && get_logger()->is_error_enabled()) \ get_logger()->error_stream() << log4tango::LogInitiator::_begin_log //============================================================================= // _HANDLE_DEV_EXCEPTION MACRO //============================================================================= #define _HANDLE_DEV_EXCEPTION(_cmd, _origin) _HANDLE_DEV_EXCEPTION_FILE_LINE(_cmd,_origin, __FILE__, __LINE__) #define _HANDLE_DEV_EXCEPTION_FILE_LINE(_cmd, _origin, _file, _line) \ catch (Tango::ConnectionFailed &e) { \ TangoSys_OMemStream d; \ d << "Tango::ConnectionFailed exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_CONNECTION_FAILED"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::CommunicationFailed &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::CommunicationFailed exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_COMMUNICATION_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::WrongNameSyntax &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::WrongNameSyntax exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_WRONG_NAME_SYNTAX_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::NonDbDevice &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::NonDbDevice exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_NON_DB_DEVICE_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::WrongData &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::WrongData exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_WRONG_DATA_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::NonSupportedFeature &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::NonSupportedFeature exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_NON_SUPPORTED_FEATURE_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::AsynCall &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::AsynCall exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_ASYNC_CALL_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::AsynReplyNotArrived &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::EventSystemFailed exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_ASYNC_REPLY_NOT_ARRIVED_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::EventSystemFailed &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::EventSystemFailed exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << static_cast(e) << std::endl; \ Tango::Except::re_throw_exception(static_cast(e), \ static_cast("TANGO_EVENT_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (Tango::DevFailed &e) \ { \ TangoSys_OMemStream d; \ d << "Tango::DevFailed exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ _ERROR_STREAM << e << std::endl; \ Tango::Except::re_throw_exception(e, \ static_cast("TANGO_DEVICE_ERROR"), \ static_cast(d.str().c_str()), \ static_cast(o.str().c_str())); \ } \ catch (const std::bad_alloc &) \ { \ TangoSys_OMemStream d; \ d << "std::bad_alloc exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ Tango::DevErrorList errors(1); \ errors.length(1); \ errors[0].severity = Tango::ERR; \ errors[0].reason = CORBA::string_dup("OUT_OF_MEMORY"); \ errors[0].desc = CORBA::string_dup(d.str().c_str()); \ errors[0].origin = CORBA::string_dup(o.str().c_str()); \ Tango::DevFailed df(errors); \ _ERROR_STREAM << df << std::endl; \ throw df; \ } \ catch (...) \ { \ TangoSys_OMemStream d; \ d << "unknown exception caught while trying to execute " \ << _cmd \ << std::ends; \ TangoSys_OMemStream o; \ o << _origin << " [" << _file << "::" << _line << "]" << std::ends; \ Tango::DevErrorList errors(1); \ errors.length(1); \ errors[0].severity = Tango::ERR; \ errors[0].reason = CORBA::string_dup("UNKNOWN_ERROR"); \ errors[0].desc = CORBA::string_dup(d.str().c_str()); \ errors[0].origin = CORBA::string_dup(o.str().c_str()); \ Tango::DevFailed df(errors); \ _ERROR_STREAM << df << std::endl; \ throw df; \ } //============================================================================= // _DEV_TRY MACRO //============================================================================= #define _DEV_TRY_FILE_LINE(_invoke, _cmd, _origin, _file, _line) \ try \ { \ _invoke; \ } \ _HANDLE_DEV_EXCEPTION_FILE_LINE(_cmd, _origin, _file, _line) //============================================================================= // _DEV_TRY MACRO //============================================================================= #define _DEV_TRY(_invoke, _cmd, _origin) \ try \ { \ _invoke; \ } \ _HANDLE_DEV_EXCEPTION(_cmd, _origin) //============================================================================= // _HANDLE_ASL_EXCEPTION_REACTION MACRO //============================================================================= #define _HANDLE_DEV_EXCEPTION_REACTION(_cmd, _origin, _reaction) \ catch (...) \ { \ _reaction; \ _DEV_TRY(throw, _cmd, _origin) \ } //============================================================================= // _DEV_TRY_ACTION MACRO //============================================================================= #define _DEV_TRY_ACTION(_invoke, _cmd, _origin, _action ) \ try { \ _DEV_TRY(_invoke, _cmd, _origin) \ _action; \ } \ catch (...) { \ _action; \ throw; \ } //============================================================================= // _DEV_TRY_REACTION MACRO //============================================================================= #define _DEV_TRY_REACTION(_invoke, _cmd, _origin, _reaction) \ try { \ _DEV_TRY(_invoke, _cmd, _origin) \ } \ catch (...) { \ _reaction; \ throw; \ } tango-9.2.5a/lib/cpp/client/helpers/Xstring.h0000644023471100065110000000256213034744771016024 00000000000000// // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of Tango. // // Tango is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Tango is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Tango. If not, see . #ifndef XSTRING_H #define XSTRING_H #include #include template class XString{ public: static T convertFromString(const std::string& s) { std::istringstream in(s); T x; if (in >> x) return x; // some sort of error handling goes here... return 0; } // static std::string convertToString(const T & t) { std::ostringstream out ; if (out << std::fixed << t ) return out.str(); // some sort of error handling goes here... return 0; } }; #endif tango-9.2.5a/lib/idl/0000755023471100065110000000000013034745260011330 500000000000000tango-9.2.5a/lib/idl/README0000644023471100065110000000006413034744752012135 00000000000000This is the Tango CORBA IDL file. The Tango team tango-9.2.5a/lib/idl/Makefile.am0000644023471100065110000000012613034744752013310 00000000000000 idldir = ${pkgdatadir}/idl idl_DATA = tango.idl \ README EXTRA_DIST=$(idl_DATA) tango-9.2.5a/lib/idl/Makefile.in0000644023471100065110000003665113034745122013325 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/idl DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(idldir)" DATA = $(idl_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ idldir = ${pkgdatadir}/idl idl_DATA = tango.idl \ README EXTRA_DIST = $(idl_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/idl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/idl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-idlDATA: $(idl_DATA) @$(NORMAL_INSTALL) @list='$(idl_DATA)'; test -n "$(idldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(idldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(idldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(idldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(idldir)" || exit $$?; \ done uninstall-idlDATA: @$(NORMAL_UNINSTALL) @list='$(idl_DATA)'; test -n "$(idldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(idldir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(idldir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-idlDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-idlDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-idlDATA install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-idlDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/idl/tango.idl0000644023471100065110000007005613034744752013067 00000000000000 /** * This is the TANGO interface defined in IDL. * TANGO is an extension of old TACO. * The fundamental idea of a device as a network object which * has methods and data has been retained. However * in TANGO objects will be real C++/Java objects which can be instantiated * and accessed via their methods and data by the client as if they were local * objects. * Certain aspects of the old DSAPI application programmer's * interface have been suppressed in order to simplify the client (e.g. import, * free, data collector api). * Features which have been considered missing in old TACO have been added * e.g. signals, events and groups. * Asynchronism and groups have been foreseen right from the beginning * this time. * This interface is defined in CORBA IDL. * The fundamental interface is Device. * All TANGO control objects will be of this type i.e. they will implement and * offer the Device interface. * New classes of control objects e.g. PowerSupply, will be created by * wrapping the Device class appropriately. * The wrapper class will hide the calls to the Device interface from * the client so that the client will only see the wrapper class. * All CORBA details will be hidden from the client as far as possible. **/ module Tango { //------------------------------------------------------------------------- // // Basic types to transport command data // //------------------------------------------------------------------------- typedef boolean DevBoolean; typedef double DevDouble; typedef float DevFloat; typedef short DevShort; typedef long DevLong; typedef long long DevLong64; typedef string DevString; typedef octet DevUChar; typedef unsigned short DevUShort; typedef unsigned long DevULong; typedef unsigned long long DevULong64; typedef sequence DevVarBooleanArray; typedef sequence DevVarDoubleArray; typedef sequence DevVarFloatArray; typedef sequence DevVarShortArray; typedef sequence DevVarLongArray; typedef sequence DevVarLong64Array; typedef sequence DevVarCharArray; typedef sequence DevVarStringArray; typedef sequence DevVarUShortArray; typedef sequence DevVarULongArray; typedef sequence DevVarULong64Array; struct DevVarLongStringArray { DevVarLongArray lvalue; DevVarStringArray svalue; }; struct DevVarDoubleStringArray { DevVarDoubleArray dvalue; DevVarStringArray svalue; }; struct DevEncoded { DevString encoded_format; DevVarCharArray encoded_data; }; typedef sequence DevVarEncodedArray; //------------------------------------------------------------------------- // // Data types for client identification // //------------------------------------------------------------------------- typedef unsigned long long JavaUUID[2]; typedef unsigned long CppClntIdent; struct JavaClntIdent { string MainClass; JavaUUID uuid; }; enum LockerLanguage { CPP, JAVA }; union ClntIdent switch (LockerLanguage) { case CPP: CppClntIdent cpp_clnt; case JAVA: JavaClntIdent java_clnt; }; //------------------------------------------------------------------------- // // Some enumerations // //------------------------------------------------------------------------- enum AttrQuality { ATTR_VALID, ATTR_INVALID, ATTR_ALARM, ATTR_CHANGING, ATTR_WARNING }; enum AttrWriteType { READ, READ_WITH_WRITE, WRITE, READ_WRITE, WT_UNKNOWN }; enum AttrDataFormat { SCALAR, SPECTRUM, IMAGE, FMT_UNKNOWN }; enum DevSource { DEV, CACHE, CACHE_DEV }; enum ErrSeverity { WARN, ERR, PANIC }; enum DevState { ON, OFF, CLOSE, OPEN, INSERT, EXTRACT, MOVING, STANDBY, FAULT, INIT, RUNNING, ALARM, DISABLE, UNKNOWN }; enum DispLevel { OPERATOR, EXPERT, DL_UNKNOWN }; typedef sequence DevVarStateArray; //------------------------------------------------------------------------- // // Some miscellaneous structures definitions // //------------------------------------------------------------------------- struct TimeVal { long tv_sec; long tv_usec; long tv_nsec; }; //------------------------------------------------------------------------- // // For the command query device operation // //------------------------------------------------------------------------- struct DevCmdInfo { string cmd_name; long cmd_tag; long in_type; long out_type; string in_type_desc; string out_type_desc; }; struct DevCmdInfo_2 { string cmd_name; DispLevel level; long cmd_tag; long in_type; long out_type; string in_type_desc; string out_type_desc; }; typedef sequence DevCmdInfoList; typedef sequence DevCmdInfoList_2; //------------------------------------------------------------------------- // // For the DevFailed exceptions // //------------------------------------------------------------------------- struct DevError { string reason; ErrSeverity severity; string desc; string origin; }; typedef sequence DevErrorList; struct NamedDevError { string name; long index_in_call; DevErrorList err_list; }; typedef sequence NamedDevErrorList; exception DevFailed { DevErrorList errors; }; exception MultiDevFailed { NamedDevErrorList errors; }; //------------------------------------------------------------------------- // // For attribute management // //------------------------------------------------------------------------- struct AttributeConfig { string name; AttrWriteType writable; AttrDataFormat data_format; long data_type; long max_dim_x; long max_dim_y; string description; string label; string unit; string standard_unit; string display_unit; string format; string min_value; string max_value; string min_alarm; string max_alarm; string writable_attr_name; DevVarStringArray extensions; }; struct AttributeConfig_2 { string name; AttrWriteType writable; AttrDataFormat data_format; long data_type; long max_dim_x; long max_dim_y; string description; string label; string unit; string standard_unit; string display_unit; string format; string min_value; string max_value; string min_alarm; string max_alarm; string writable_attr_name; DispLevel level; DevVarStringArray extensions; }; struct AttributeValue { any value; AttrQuality quality; TimeVal time; string name; long dim_x; long dim_y; }; struct AttributeDim { long dim_x; long dim_y; }; struct AttributeValue_3 { any value; AttrQuality quality; TimeVal time; string name; AttributeDim r_dim; AttributeDim w_dim; DevErrorList err_list; }; enum AttributeDataType { ATT_BOOL, ATT_SHORT, ATT_LONG, ATT_LONG64, ATT_FLOAT, ATT_DOUBLE, ATT_UCHAR, ATT_USHORT, ATT_ULONG, ATT_ULONG64, ATT_STRING, ATT_STATE, DEVICE_STATE, ATT_ENCODED, ATT_NO_DATA }; union AttrValUnion switch (AttributeDataType) { case ATT_BOOL: DevVarBooleanArray bool_att_value; case ATT_SHORT: DevVarShortArray short_att_value; case ATT_LONG: DevVarLongArray long_att_value; case ATT_LONG64: DevVarLong64Array long64_att_value; case ATT_FLOAT: DevVarFloatArray float_att_value; case ATT_DOUBLE: DevVarDoubleArray double_att_value; case ATT_UCHAR: DevVarCharArray uchar_att_value; case ATT_USHORT: DevVarUShortArray ushort_att_value; case ATT_ULONG: DevVarULongArray ulong_att_value; case ATT_ULONG64: DevVarULong64Array ulong64_att_value; case ATT_STRING: DevVarStringArray string_att_value; case ATT_STATE: DevVarStateArray state_att_value; case DEVICE_STATE: DevState dev_state_att; case ATT_ENCODED: DevVarEncodedArray encoded_att_value; case ATT_NO_DATA: DevBoolean union_no_data; }; struct AttributeValue_4 { AttrValUnion value; AttrQuality quality; AttrDataFormat data_format; TimeVal time; string name; AttributeDim r_dim; AttributeDim w_dim; DevErrorList err_list; }; struct AttributeValue_5 { AttrValUnion value; AttrQuality quality; AttrDataFormat data_format; long data_type; TimeVal time; string name; AttributeDim r_dim; AttributeDim w_dim; DevErrorList err_list; }; struct ChangeEventProp { string rel_change; string abs_change; DevVarStringArray extensions; }; struct PeriodicEventProp { string period; DevVarStringArray extensions; }; struct ArchiveEventProp { string rel_change; string abs_change; string period; DevVarStringArray extensions; }; struct EventProperties { ChangeEventProp ch_event; PeriodicEventProp per_event; ArchiveEventProp arch_event; }; struct AttributeAlarm { string min_alarm; string max_alarm; string min_warning; string max_warning; string delta_t; string delta_val; DevVarStringArray extensions; }; struct AttributeConfig_3 { string name; AttrWriteType writable; AttrDataFormat data_format; long data_type; long max_dim_x; long max_dim_y; string description; string label; string unit; string standard_unit; string display_unit; string format; string min_value; string max_value; string writable_attr_name; DispLevel level; AttributeAlarm att_alarm; EventProperties event_prop; DevVarStringArray extensions; DevVarStringArray sys_extensions; }; struct AttributeConfig_5 { string name; AttrWriteType writable; AttrDataFormat data_format; long data_type; boolean memorized; boolean mem_init; long max_dim_x; long max_dim_y; string description; string label; string unit; string standard_unit; string display_unit; string format; string min_value; string max_value; string writable_attr_name; DispLevel level; string root_attr_name; DevVarStringArray enum_labels; AttributeAlarm att_alarm; EventProperties event_prop; DevVarStringArray extensions; DevVarStringArray sys_extensions; }; typedef sequence AttributeConfigList; typedef sequence AttributeConfigList_2; typedef sequence AttributeConfigList_3; typedef sequence AttributeConfigList_5; typedef sequence AttributeValueList; typedef sequence AttributeValueList_3; typedef sequence AttributeValueList_4; typedef sequence AttributeValueList_5; //------------------------------------------------------------------------- // // For pipe management // //------------------------------------------------------------------------- enum PipeWriteType { PIPE_READ, PIPE_READ_WRITE, PIPE_WT_UNKNOWN }; struct PipeConfig { string name; string description; string label; DispLevel level; PipeWriteType writable; DevVarStringArray extensions; }; typedef sequence PipeConfigList; struct DevPipeDataElt; typedef sequence DevVarPipeDataEltArray; struct DevPipeDataElt { string name; AttrValUnion value; DevVarPipeDataEltArray inner_blob; string inner_blob_name; }; struct DevPipeBlob { string name; DevVarPipeDataEltArray blob_data; }; struct DevPipeData { string name; TimeVal time; DevPipeBlob data_blob; }; //------------------------------------------------------------------------- // // For data ready event // //------------------------------------------------------------------------- struct AttDataReady { string name; long data_type; long ctr; }; //------------------------------------------------------------------------- // // For device interface change event // //------------------------------------------------------------------------- struct DevIntrChange { boolean dev_started; DevCmdInfoList_2 cmds; AttributeConfigList_5 atts; }; //------------------------------------------------------------------------- // // For device interface info operation // //------------------------------------------------------------------------- struct DevInfo { string dev_class; string server_id; string server_host; long server_version; string doc_url; }; struct DevInfo_3 { string dev_class; string server_id; string server_host; long server_version; string doc_url; string dev_type; }; //------------------------------------------------------------------------- // // For command and attribute history // //------------------------------------------------------------------------- struct DevCmdHistory { TimeVal time; boolean cmd_failed; any value; DevErrorList errors; }; typedef sequence DevCmdHistoryList; struct DevAttrHistory { boolean attr_failed; AttributeValue value; DevErrorList errors; }; struct DevAttrHistory_3 { boolean attr_failed; AttributeValue_3 value; }; struct EltInArray { long start; long nb_elt; }; typedef sequence EltInArrayList; typedef sequence TimeValList; typedef sequence AttrQualityList; typedef sequence AttributeDimList; typedef sequence DevErrorListList; struct DevAttrHistory_4 { string name; TimeValList dates; any value; AttrQualityList quals; EltInArrayList quals_array; AttributeDimList r_dims; EltInArrayList r_dims_array; AttributeDimList w_dims; EltInArrayList w_dims_array; DevErrorListList errors; EltInArrayList errors_array; }; struct DevAttrHistory_5 { string name; AttrDataFormat data_format; long data_type; TimeValList dates; any value; AttrQualityList quals; EltInArrayList quals_array; AttributeDimList r_dims; EltInArrayList r_dims_array; AttributeDimList w_dims; EltInArrayList w_dims_array; DevErrorListList errors; EltInArrayList errors_array; }; struct DevCmdHistory_4 { TimeValList dates; any value; AttributeDimList dims; EltInArrayList dims_array; DevErrorListList errors; EltInArrayList errors_array; long cmd_type; }; typedef sequence DevAttrHistoryList; typedef sequence DevAttrHistoryList_3; //------------------------------------------------------------------------- // // For ZMQ event system // //------------------------------------------------------------------------- struct ZmqCallInfo { long version; unsigned long ctr; string method_name; DevVarCharArray oid; boolean call_is_except; }; //------------------------------------------------------------------------- // // Include the device interface // //------------------------------------------------------------------------- /** * The fundamental interface for all TANGO objects. * Each Device is a network object which can be accessed locally or via * network. * The network protocol on the wire will be IIOP. * The Device interface implements all the basic functions needed for doing * generic synchronous and asynchronous I/O on a device. * A Device object has data and actions. * Data are represented in the form of Attributes. * Actions are represented in the form of Commands. * The CORBA Device interface offers attributes and methods to access * the attributes and commands. * A client will either use these methods directly from C++ or Java or access * them via a wrapper class. * The Device interface describes only the remote network interface. * Implementation features like threads, command security, priority * etc. are dealt with in server side of the device server model. **/ interface Device { /** * name (readonly) - unique ascii identifier **/ readonly attribute string name; /** * description (readonly) - general description of device **/ readonly attribute string description; /** * state (readonly) - device state **/ readonly attribute DevState state; /** * status (readonly) - device state as ascii string **/ readonly attribute string status; /** * adm_name (readonly) - administrator device unique ascii identifier **/ readonly attribute string adm_name; /** * execute a command on a device synchronously with * one input parameter and one output parameter @param command ascii string e.g. "On" @param argin command input parameter e.g. float @return command result. **/ any command_inout(in string command, in any argin) raises(DevFailed); /** * read the configuration for a variable list of attributes from a device @param name list of attribute names to read @return list of attribute configurations read **/ AttributeConfigList get_attribute_config(in DevVarStringArray names) raises(DevFailed); /** * set the configuration for a variable list of attributes from the device @param new_conf list of attribute configuration to be set @return nothing **/ void set_attribute_config(in AttributeConfigList new_conf) raises(DevFailed); /** * read a variable list of attributes from a device @param name list of attribute names to read @return list of attribute values read **/ AttributeValueList read_attributes(in DevVarStringArray names) raises(DevFailed); /** * write a variable list of attributes to a device @param values list of attribute values to write @return nothing **/ void write_attributes(in AttributeValueList values) raises(DevFailed); /** * ping a device to see if it alive **/ void ping() raises(DevFailed); /** * read list of last N commands executed by clients @param number of commands to return @return list of command and clients **/ DevVarStringArray black_box(in long n) raises(DevFailed); /** * return general information about object e.g. class, type, ... @return device info **/ DevInfo info() raises(DevFailed); /** * query device to see what commands it supports @return list of commands and their types **/ DevCmdInfoList command_list_query() raises(DevFailed); /** * query device to see command argument @return command and its types @param command name **/ DevCmdInfo command_query(in string command) raises(DevFailed); }; //------------------------------------------------------------------------- // // The Device_2 interface // //------------------------------------------------------------------------- /** * A new release of the basic Device interface. * This new release has been introduced mainly to support Tango device server * internal polling. Inheritance is used between this new release and the * old one. This release mainly defines a new release of the command_inout and * read_attributes calls with a new parameter. It also add a new call to read * command or attributes result history. **/ interface Device_2: Device { /** * Execute a command on a device synchronously with * one input parameter and one output parameter @param command ascii string e.g. "On" @param argin command input parameter e.g. float @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @return command result. **/ any command_inout_2(in string command, in any argin, in DevSource source) raises(DevFailed); /** * Read a variable list of attributes from a device @param name list of attribute names to read @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @return list of attribute values read **/ AttributeValueList read_attributes_2(in DevVarStringArray names, in DevSource source) raises(DevFailed); /** * Read the configuration for a variable list of attributes from a device. * Compared to the Device interface, the attribute configuration has one more * field (The display level) @param name list of attribute names to read @return list of attribute configurations read **/ AttributeConfigList_2 get_attribute_config_2(in DevVarStringArray names) raises(DevFailed); /** * Query device to see what commands it supports. * Compared to the Device interface, the command configuration has one more * field (The display level) @return list of commands and their types **/ DevCmdInfoList_2 command_list_query_2() raises(DevFailed); /** * Query device to see command argument. * Compared to the Device interface, the command configuration has one more * field (The display level) @return command and its types @param command name **/ DevCmdInfo_2 command_query_2(in string command) raises(DevFailed); /** * Get command history buffer. * Return command result history for polled command @param command ascii string e.g. "On" @param n The history depth @return command history. **/ DevCmdHistoryList command_inout_history_2(in string command, in long n) raises (DevFailed); /** * Get attribute value history buffer. * Return attribute value history for polled attribute @param name ascii string @param n The history depth @return attribute value history. **/ DevAttrHistoryList read_attribute_history_2(in string name, in long n) raises (DevFailed); }; //------------------------------------------------------------------------- // // The Device_3 interface (corresponding to Tango V5) // //------------------------------------------------------------------------- interface Device_3: Device_2 { /** * Read a variable list of attributes from a device @param name list of attribute names to read @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @return list of attribute values read **/ AttributeValueList_3 read_attributes_3(in DevVarStringArray names, in DevSource source) raises(DevFailed); /** * write a variable list of attributes to a device @param values list of attribute values to write @return nothing **/ void write_attributes_3(in AttributeValueList values) raises(DevFailed,MultiDevFailed); /** * Get attribute value history buffer. * Return attribute value history for polled attribute @param name ascii string @param n The history depth @return attribute value history. **/ DevAttrHistoryList_3 read_attribute_history_3(in string name, in long n) raises (DevFailed); /** * return general information about object e.g. class, type, ... @return device info **/ DevInfo_3 info_3() raises(DevFailed); /** * Read the configuration for a variable list of attributes from a device. * Compared to the Device interface, the attribute configuration has one more * field (The display level) @param name list of attribute names to read @return list of attribute configurations read **/ AttributeConfigList_3 get_attribute_config_3(in DevVarStringArray names) raises(DevFailed); /** * set the configuration for a variable list of attributes from the device @param new_conf list of attribute configuration to be set @return nothing **/ void set_attribute_config_3(in AttributeConfigList_3 new_conf) raises(DevFailed); }; //------------------------------------------------------------------------- // // The Device_4 interface (corresponding to Tango V7) // //------------------------------------------------------------------------- interface Device_4: Device_3 { /** * Get attribute value history buffer. * Return attribute value history for polled attribute @param name ascii string @param n The history depth @return attribute value history. **/ DevAttrHistory_4 read_attribute_history_4(in string name, in long n) raises (DevFailed); /** * Get command history buffer. * Return command result history for polled command @param command ascii string e.g. "On" @param n The history depth @return command history. **/ DevCmdHistory_4 command_inout_history_4(in string command, in long n) raises (DevFailed); /** * Execute a command on a device synchronously with * one input parameter and one output parameter @param command ascii string e.g. "On" @param argin command input parameter e.g. float @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @param cl_ident The client identificator @return command result. **/ any command_inout_4(in string command, in any argin, in DevSource source, in ClntIdent cl_ident) raises(DevFailed); /** * Read a variable list of attributes from a device @param name list of attribute names to read @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @return list of attribute values read **/ AttributeValueList_4 read_attributes_4(in DevVarStringArray names, in DevSource source,in ClntIdent cl_ident) raises(DevFailed); /** * write a variable list of attributes to a device @param values list of attribute values to write @return nothing **/ void write_attributes_4(in AttributeValueList_4 values,in ClntIdent cl_ident) raises(DevFailed,MultiDevFailed); /** * set the configuration for a variable list of attributes from the device @param new_conf list of attribute configuration to be set @return nothing **/ void set_attribute_config_4(in AttributeConfigList_3 new_conf,in ClntIdent cl_ident) raises(DevFailed); /** * Write then Read device attribute(s) @param values List of attribute values to be written @param cl_ident The client identificator @return Attributes value read **/ AttributeValueList_4 write_read_attributes_4(in AttributeValueList_4 values,in ClntIdent cl_ident) raises(DevFailed,MultiDevFailed); }; //------------------------------------------------------------------------- // // The Device_5 interface (corresponding to Tango V9) // //------------------------------------------------------------------------- interface Device_5: Device_4 { /** * Read the configuration for a variable list of attributes from a device. * Compared to the Device interface, the attribute configuration has one more * field (The display level) @param name list of attribute names to read @return list of attribute configurations read **/ AttributeConfigList_5 get_attribute_config_5(in DevVarStringArray names) raises(DevFailed); /** * set the configuration for a variable list of attributes from the device @param new_conf list of attribute configuration to be set @return nothing **/ void set_attribute_config_5(in AttributeConfigList_5 new_conf,in ClntIdent cl_ident) raises(DevFailed); /** * Read a variable list of attributes from a device @param name list of attribute names to read @param source The data source. Used to specify if the command result must be read from the polling cache buffer or from the device itself @return list of attribute values read **/ AttributeValueList_5 read_attributes_5(in DevVarStringArray names, in DevSource source,in ClntIdent cl_ident) raises(DevFailed); /** * Write then Read device attribute(s) @param values List of attribute values to be written @param cl_ident The client identificator @return Attributes value read **/ AttributeValueList_5 write_read_attributes_5(in AttributeValueList_4 values,in DevVarStringArray r_names,in ClntIdent cl_ident) raises(DevFailed,MultiDevFailed); /** * Get attribute value history buffer. * Return attribute value history for polled attribute @param name ascii string @param n The history depth @return attribute value history. **/ DevAttrHistory_5 read_attribute_history_5(in string name, in long n) raises (DevFailed); /** * Read the configuration for a variable list of pipes from a device. @param names list of pipe names to read @return list of pipe configurations read **/ PipeConfigList get_pipe_config_5(in DevVarStringArray names) raises(DevFailed); /** * set the configuration for a variable list of pipes from the device @param new_conf list of pipe configuration to be set @return nothing **/ void set_pipe_config_5(in PipeConfigList new_conf,in ClntIdent cl_ident) raises(DevFailed); /** * Read a pipe from a device @param name pipe name @param cl_ident client identifier @return pipe value **/ DevPipeData read_pipe_5(in string name,in ClntIdent cl_ident) raises(DevFailed); /** * write a pipe to a device @param value new pipe value @param cl_ident client identifier @return nothing **/ void write_pipe_5(in DevPipeData value,in ClntIdent cl_ident) raises(DevFailed); /** * write then read a pipe to a device @param value new pipe value @param cl_ident client identifier @return pipe value **/ DevPipeData write_read_pipe_5(in DevPipeData value,in ClntIdent cl_ident) raises(DevFailed); }; }; /* module tango */ tango-9.2.5a/lib/java/0000755023471100065110000000000013034745261011502 500000000000000tango-9.2.5a/lib/java/README0000644023471100065110000000026513034744715012310 00000000000000This direcory contains the jar files for the java Tango API and the main applications. The Java source code can be downloaded from: https://svn.code.sf.net/p/tango-cs/code tango-9.2.5a/lib/java/Makefile.am0000644023471100065110000000470713034744715013471 00000000000000 # In the java directory we don't want to do anything, just # make sure it is in the dist. Don't use EXTRA_DIST. It will copy # the link instead of keeping them as links javadir = $(datadir)/java dist_java_DATA=\ Astor-7.0.9.jar \ DeviceTree-1.9.6.jar \ ATKCore-9.1.22.jar \ Jive-7.10.jar \ org.tango.pogo-9.4.5.jar \ atkpanel-5.5.jar \ log4j-1.2.15.jar \ AtkTuning-2.8.jar \ LogViewer-2.0.4.jar \ JTango-9.1.2.jar \ ATKWidget-9.1.22.jar \ tool_panels-3.2.jar \ JSSHTerminal-1.10.jar \ DBBench-1.3.jar if TANGO_JAVA_ENABLED bin_SCRIPTS = \ astor \ jive \ pogo \ pogo-6 \ devicetree \ atkpanel \ logviewer \ atktuning \ jdraw \ synopticappli \ atkmoni \ tg_devtest \ TangoVers \ cvstag edit = sed \ -e 's|@SHELL[@]|$(SHELL)|g' \ -e 's|@TANGO_RC_FILE[@]|$(TANGO_RC_FILE)|g' \ -e 's|@JAVA[@]|$(JAVA)|g' \ -e 's|@DOXYGEN[@]|$(DOXYGEN)|g' \ -e 's|@libdir[@]|$(libdir)|g' \ -e 's|@prefix[@]|$(prefix)|g' #astor jive pogo pogo-6 devicetree atkpanel logviewer atktuning jdraw synopticappli atkmoni cvstag TangoVers tg_devtest: Makefile $(bin_SCRIPTS): Makefile rm -f $@ $@.tmp srcdir=''; \ test -f ./$@.in || srcdir=$(srcdir)/; \ $(edit) $${srcdir}$@.in >$@.tmp chmod +x $@.tmp chmod a-w $@.tmp mv $@.tmp $@ astor: $(srcdir)/astor.in jive: $(srcdir)/jive.in pogo: $(srcdir)/pogo.in pogo-6: $(srcdir)/pogo-6.in devicetree: $(srcdir)/devicetree.in atkpanel: $(srcdir)/atkpanel.in logviewer: $(srcdir)/logviewer.in atktuning: $(srcdir)/atktuning.in jdraw: $(srcdir)/jdraw.in synopticappli: $(srcdir)/synopticappli.in atkmoni: $(srcdir)/atkmoni.in cvstag: $(srcdir)/cvstag.in TangoVers: $(srcdir)/TangoVers.in tg_devtest: $(srcdir)/tg_devtest.in distclean-local: distclean-local-check .PHONY: distclean-local-check distclean-local-check: -rm -rf $(bin_SCRIPTS) endif # Make sure that all these go into the dist. EXTRA_DIST = \ astor.in \ jive.in \ pogo.in \ pogo-6.in \ devicetree.in \ atkpanel.in \ logviewer.in \ atktuning.in \ jdraw.in \ synopticappli.in \ atkmoni.in \ cvstag.in \ tg_devtest.in \ TangoVers.in # Even though we do not want to compile anything in the # java-directory, we still want to install the sources in # prefix/share/tango install-data-hook: (cd $(DESTDIR)$(javadir) ; \ for i in $(dist_java_DATA) ; do \ link_name=`echo $$i | @SED@ -e's/-[0-9.]*/./'` ; \ $(RM) $$link_name && @LN_S@ $$i $$link_name ; \ done \ ) tango-9.2.5a/lib/java/Makefile.in0000644023471100065110000005134513034745123013474 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # In the java directory we don't want to do anything, just # make sure it is in the dist. Don't use EXTRA_DIST. It will copy # the link instead of keeping them as links VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib/java DIST_COMMON = README $(dist_java_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(javadir)" SCRIPTS = $(bin_SCRIPTS) AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_java_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ javadir = $(datadir)/java dist_java_DATA = \ Astor-7.0.9.jar \ DeviceTree-1.9.6.jar \ ATKCore-9.1.22.jar \ Jive-7.10.jar \ org.tango.pogo-9.4.5.jar \ atkpanel-5.5.jar \ log4j-1.2.15.jar \ AtkTuning-2.8.jar \ LogViewer-2.0.4.jar \ JTango-9.1.2.jar \ ATKWidget-9.1.22.jar \ tool_panels-3.2.jar \ JSSHTerminal-1.10.jar \ DBBench-1.3.jar @TANGO_JAVA_ENABLED_TRUE@bin_SCRIPTS = \ @TANGO_JAVA_ENABLED_TRUE@ astor \ @TANGO_JAVA_ENABLED_TRUE@ jive \ @TANGO_JAVA_ENABLED_TRUE@ pogo \ @TANGO_JAVA_ENABLED_TRUE@ pogo-6 \ @TANGO_JAVA_ENABLED_TRUE@ devicetree \ @TANGO_JAVA_ENABLED_TRUE@ atkpanel \ @TANGO_JAVA_ENABLED_TRUE@ logviewer \ @TANGO_JAVA_ENABLED_TRUE@ atktuning \ @TANGO_JAVA_ENABLED_TRUE@ jdraw \ @TANGO_JAVA_ENABLED_TRUE@ synopticappli \ @TANGO_JAVA_ENABLED_TRUE@ atkmoni \ @TANGO_JAVA_ENABLED_TRUE@ tg_devtest \ @TANGO_JAVA_ENABLED_TRUE@ TangoVers \ @TANGO_JAVA_ENABLED_TRUE@ cvstag @TANGO_JAVA_ENABLED_TRUE@edit = sed \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@SHELL[@]|$(SHELL)|g' \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@TANGO_RC_FILE[@]|$(TANGO_RC_FILE)|g' \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@JAVA[@]|$(JAVA)|g' \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@DOXYGEN[@]|$(DOXYGEN)|g' \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@libdir[@]|$(libdir)|g' \ @TANGO_JAVA_ENABLED_TRUE@ -e 's|@prefix[@]|$(prefix)|g' # Make sure that all these go into the dist. EXTRA_DIST = \ astor.in \ jive.in \ pogo.in \ pogo-6.in \ devicetree.in \ atkpanel.in \ logviewer.in \ atktuning.in \ jdraw.in \ synopticappli.in \ atkmoni.in \ cvstag.in \ tg_devtest.in \ TangoVers.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/java/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/java/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_javaDATA: $(dist_java_DATA) @$(NORMAL_INSTALL) @list='$(dist_java_DATA)'; test -n "$(javadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(javadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(javadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(javadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(javadir)" || exit $$?; \ done uninstall-dist_javaDATA: @$(NORMAL_UNINSTALL) @list='$(dist_java_DATA)'; test -n "$(javadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(javadir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(javadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_JAVA_ENABLED_FALSE@distclean-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_javaDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binSCRIPTS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binSCRIPTS uninstall-dist_javaDATA .MAKE: install-am install-data-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binSCRIPTS install-data install-data-am \ install-data-hook install-dist_javaDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-binSCRIPTS \ uninstall-dist_javaDATA #astor jive pogo pogo-6 devicetree atkpanel logviewer atktuning jdraw synopticappli atkmoni cvstag TangoVers tg_devtest: Makefile @TANGO_JAVA_ENABLED_TRUE@$(bin_SCRIPTS): Makefile @TANGO_JAVA_ENABLED_TRUE@ rm -f $@ $@.tmp @TANGO_JAVA_ENABLED_TRUE@ srcdir=''; \ @TANGO_JAVA_ENABLED_TRUE@ test -f ./$@.in || srcdir=$(srcdir)/; \ @TANGO_JAVA_ENABLED_TRUE@ $(edit) $${srcdir}$@.in >$@.tmp @TANGO_JAVA_ENABLED_TRUE@ chmod +x $@.tmp @TANGO_JAVA_ENABLED_TRUE@ chmod a-w $@.tmp @TANGO_JAVA_ENABLED_TRUE@ mv $@.tmp $@ @TANGO_JAVA_ENABLED_TRUE@astor: $(srcdir)/astor.in @TANGO_JAVA_ENABLED_TRUE@jive: $(srcdir)/jive.in @TANGO_JAVA_ENABLED_TRUE@pogo: $(srcdir)/pogo.in @TANGO_JAVA_ENABLED_TRUE@pogo-6: $(srcdir)/pogo-6.in @TANGO_JAVA_ENABLED_TRUE@devicetree: $(srcdir)/devicetree.in @TANGO_JAVA_ENABLED_TRUE@atkpanel: $(srcdir)/atkpanel.in @TANGO_JAVA_ENABLED_TRUE@logviewer: $(srcdir)/logviewer.in @TANGO_JAVA_ENABLED_TRUE@atktuning: $(srcdir)/atktuning.in @TANGO_JAVA_ENABLED_TRUE@jdraw: $(srcdir)/jdraw.in @TANGO_JAVA_ENABLED_TRUE@synopticappli: $(srcdir)/synopticappli.in @TANGO_JAVA_ENABLED_TRUE@atkmoni: $(srcdir)/atkmoni.in @TANGO_JAVA_ENABLED_TRUE@cvstag: $(srcdir)/cvstag.in @TANGO_JAVA_ENABLED_TRUE@TangoVers: $(srcdir)/TangoVers.in @TANGO_JAVA_ENABLED_TRUE@tg_devtest: $(srcdir)/tg_devtest.in @TANGO_JAVA_ENABLED_TRUE@distclean-local: distclean-local-check @TANGO_JAVA_ENABLED_TRUE@.PHONY: distclean-local-check @TANGO_JAVA_ENABLED_TRUE@distclean-local-check: @TANGO_JAVA_ENABLED_TRUE@ -rm -rf $(bin_SCRIPTS) # Even though we do not want to compile anything in the # java-directory, we still want to install the sources in # prefix/share/tango install-data-hook: (cd $(DESTDIR)$(javadir) ; \ for i in $(dist_java_DATA) ; do \ link_name=`echo $$i | @SED@ -e's/-[0-9.]*/./'` ; \ $(RM) $$link_name && @LN_S@ $$i $$link_name ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/lib/java/astor.in0000755023471100065110000000360313034744715013112 00000000000000#!@SHELL@ #--------------------------------------------------------- # #--------------------------------------------------------- if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi #--------------------------------------------------------- # Check $DISPLAY variable #--------------------------------------------------------- if [ $DISPLAY ] then echo "Display is $DISPLAY" else echo "" echo "DISPLAY environment variable is not defined !" echo "Please, enter your DISPLAY name." read answer if [ $answer ] then # get the end of string to know if ":0" has been set start=`expr $answer : '.*:' \| $answer` echo "$start " if [ $start = $answer ] then DISPLAY=$answer:0 else DISPLAY=$answer fi export DISPLAY echo "Starting astor on $DISPLAY" else echo "DISPLAY is not defined ! Astor cannot start !" exit fi fi #--------------------------------------------------------- # Set the Class Path for Tango and Asor usage #--------------------------------------------------------- LIB_DIR=@prefix@/share/java; export LIB_DIR APP_DIR=@prefix@/share/java; export APP_DIR TANGO_CLASS=$LIB_DIR/JTango.jar; export TANGO_CLASS ASTOR_CLASS=$LIB_DIR/Astor.jar; export ASTOR_CLASS JIVE_CLASS=$LIB_DIR/Jive.jar; export JIVE_CLASS LOGVIEWER=$LIB_DIR/LogViewer.jar; export LOGVIEWER LOG4J=$LIB_DIR/log4j.jar; export LOG4J JSSHTERM=$LIB_DIR/JSSHTerminal.jar DBBENCH=$LIB_DIR/DBBench.jar ATK_CLASS=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar ATK_CLASS=$ATK_CLASS:$APP_DIR/atkpanel.jar:$APP_DIR/tool_panels.jar export ATK_CLASS CLASSPATH=$TANGO_CLASS:$ASTOR_CLASS:$JIVE_CLASS:$ATK_CLASS:$LOGVIEWER:$JSSHTERM:$DBBENCH:$LOG4J export CLASSPATH #--------------------------------------------------------- # Start the Astor process #--------------------------------------------------------- # @JAVA@ -mx128m -DTANGO_HOST=$TANGO_HOST admin.astor.Astor $* tango-9.2.5a/lib/java/jive.in0000755023471100065110000000103013034744714012706 00000000000000#!@SHELL@ applet_name=jive3.MainPanel if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi # # Define the CLASSPATH # JAVALIB=@prefix@/share/java; JAVABIN=@prefix@/share/java; ATK=$JAVALIB/ATKCore.jar:$JAVALIB/ATKWidget.jar:$JAVABIN/atkpanel.jar LOGVIEWER=$JAVALIB/LogViewer.jar ASTOR=$JAVALIB/Astor.jar:$JAVALIB/tools_panel.jar LOG4J=$JAVALIB/log4j.jar CLASSPATH=$JAVALIB/JTango.jar:$JAVABIN/Jive.jar:$ATK:$LOGVIEWER:$LOG4J:$ASTOR:. export CLASSPATH @JAVA@ -mx128m -DTANGO_HOST=$TANGO_HOST $applet_name $@ tango-9.2.5a/lib/java/pogo.in0000755023471100065110000000402013034744714012717 00000000000000#!@SHELL@ #--------------------------------------------------------- # Check $DISPLAY variable #--------------------------------------------------------- if [ $DISPLAY ] then echo "Display is $DISPLAY" else echo "" echo "DISPLAY environment variable is not defined !" echo "Please, enter your DISPLAY name." read answer if [ $answer ] then # get the end of string to know if ":0" has been set start=`expr $answer : '.*:' \| $answer` echo "$start " if [ $start = $answer ] then DISPLAY=$answer:0 else DISPLAY=$answer fi export DISPLAY echo "Starting astor on $DISPLAY" else echo "DISPLAY is not defined ! Astor cannot start !" exit fi fi #--------------------------------------------------------- # Add Doc path to $PATH (depends on OS used) #--------------------------------------------------------- TANGO_HOME=@prefix@; export TANGO_HOME MY_OS=`uname` export MY_OS CPP_DOC=@DOXYGEN@ #--------------------------------------------------------- # Set the template path #--------------------------------------------------------- TEMPLATES=@prefix@/share/pogo/templates export TEMPLATES #--------------------------------------------------------- # Set the Home Source Path #--------------------------------------------------------- SRC_PATH=../generated export SRC_PATH #--------------------------------------------------------- # Set the Class Path for Tango and pogo usage #--------------------------------------------------------- APP_DIR=@prefix@/share/java; export APP_DIR PREF_DIR=@prefix@/share/pogo/preferences; export PREF_DIR POGO_CLASS=$APP_DIR/org.tango.pogo.jar; export POGO_CLASS CLASSPATH=$PREF_DIR:$POGO_CLASS; export CLASSPATH #--------------------------------------------------------- # Start the Pogo process #--------------------------------------------------------- echo "Starting Pogo Appli under $MY_OS. " # @JAVA@ -DTEMPL_HOME=$TEMPLATES \ -DCPP_DOC_PATH=$CPP_DOC \ -DIN_LANG=$POGO_LANG \ -DEDITOR=$POGO_EDITOR \ -Dfile.encoding=ISO-8859-1 \ org.tango.pogo.pogo_gui.Pogo $* tango-9.2.5a/lib/java/pogo-6.in0000755023471100065110000000374013034744715013073 00000000000000#!@SHELL@ #--------------------------------------------------------- # Check $DISPLAY variable #--------------------------------------------------------- if [ $DISPLAY ] then echo "Display is $DISPLAY" else echo "" echo "DISPLAY environment variable is not defined !" echo "Please, enter your DISPLAY name." read answer if [ $answer ] then # get the end of string to know if ":0" has been set start=`expr $answer : '.*:' \| $answer` echo "$start " if [ $start = $answer ] then DISPLAY=$answer:0 else DISPLAY=$answer fi export DISPLAY echo "Starting astor on $DISPLAY" else echo "DISPLAY is not defined ! Astor cannot start !" exit fi fi #--------------------------------------------------------- # Add Doc path to $PATH (depends on OS used) #--------------------------------------------------------- TANGO_HOME=@prefix@; export TANGO_HOME MY_OS=`uname` export MY_OS CPP_DOC=@DOXYGEN@ #--------------------------------------------------------- # Set the template path #--------------------------------------------------------- TEMPLATES=@prefix@/share/pogo/templates export TEMPLATES #--------------------------------------------------------- # Set the Home Source Path #--------------------------------------------------------- SRC_PATH=../generated export SRC_PATH #--------------------------------------------------------- # Set the Class Path for Tango and pogo usage #--------------------------------------------------------- APP_DIR=@prefix@/share/java; export APP_DIR TANGO_CLASS=$APP_DIR/JTango.jar; export TANGO_CLASS POGO_CLASS=$APP_DIR/org.tango.pogo.jar; export POGO_CLASS CLASSPATH=$POGO_CLASS:$TANGO_CLASS; export CLASSPATH #--------------------------------------------------------- # Start the Pogo process #--------------------------------------------------------- echo "Starting Pogo Appli under $MY_OS. " # @JAVA@ -DTEMPL_HOME=$TEMPLATES \ -DCPP_DOC_PATH=$CPP_DOC \ -DIN_LANG=$POGO_LANG \ -DEDITOR=$POGO_EDITOR \ pogo.appli.PogoAppli $* tango-9.2.5a/lib/java/devicetree.in0000755023471100065110000000057513034744714014105 00000000000000#!@SHELL@ if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi JAVALIB=@prefix@/share/java; JAVABIN=@prefix@/share/java; CLASSPATH=$JAVALIB/JTango.jar:$JAVALIB/ATKWidget.jar:$JAVALIB/ATKCore.jar:$JAVABIN/Jive.jar:$JAVABIN/atkpanel.jar:$JAVABIN/DeviceTree.jar export CLASSPATH echo Running Device Tree... @JAVA@ -DTANGO_HOST=$TANGO_HOST explorer.Main $@ tango-9.2.5a/lib/java/atkpanel.in0000755023471100065110000000133113034744715013555 00000000000000#!@SHELL@ # TANGO_HOME=@prefix@; export TANGO_HOME if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi #--------------------------------------------------------- # Set the Class Path for Tango and AtkPanel usage #--------------------------------------------------------- LIB_DIR=@prefix@/share/java; export LIB_DIR TANGO=$LIB_DIR/JTango.jar TANGOATK=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar ATKPANEL=$LIB_DIR/atkpanel.jar CLASSPATH=$ATKPANEL:$TANGOATK:$TANGO export CLASSPATH #--------------------------------------------------------- # Start the atkpanel process #--------------------------------------------------------- @JAVA@ -mx128m -DTANGO_HOST=$TANGO_HOST atkpanel.MainPanel $* tango-9.2.5a/lib/java/logviewer.in0000755023471100065110000000071613034744714013766 00000000000000#!@SHELL@ applet_name=fr.esrf.logviewer.Main if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi # # Define the CLASSPATH # JAVALIB=@prefix@/share/java; JAVABIN=@prefix@/share/java; ATKBIN=@prefix@/share/java; TLVBIN=@prefix@/share/java; ATKJAR=$ATKBIN/ATKCore.jar:$ATKBIN/ATKWidget.jar:$ATKBIN/log4j.jar CLASSPATH=$JAVALIB/JTango.jar:$TLVBIN/LogViewer.jar:$ATKJAR:. export CLASSPATH @JAVA@ -DTANGO_HOST=$TANGO_HOST $applet_name $* tango-9.2.5a/lib/java/atktuning.in0000755023471100065110000000132413034744714013763 00000000000000#!@SHELL@ # TANGO_HOME=@prefix@; export TANGO_HOME if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi #--------------------------------------------------------- # Set the Class Path for Tango and AtkPanel usage #--------------------------------------------------------- LIB_DIR=@prefix@/share/java; export LIB_DIR TANGO=$LIB_DIR/JTango.jar TANGOATK=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar ATKPANEL=$LIB_DIR/AtkTuning.jar CLASSPATH=$ATKPANEL:$TANGOATK:$TANGO export CLASSPATH #--------------------------------------------------------- # Start the atktuning process #--------------------------------------------------------- @JAVA@ -DTANGO_HOST=$TANGO_HOST atktuning.MainPanel $* tango-9.2.5a/lib/java/jdraw.in0000755023471100065110000000162213034744714013067 00000000000000#!@SHELL@ #--------------------------------------------------------- # #--------------------------------------------------------- LIB_DIR=@prefix@/share/java; export LIB_DIR APP_DIR=@prefix@/share/java; export APP_DIR #--------------------------------------------------------- # Set the Class Path Jdraw usage #--------------------------------------------------------- TANGO=$LIB_DIR/JTango.jar TANGOATK=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar:$LIB_DIR/atkpanel.jar APPLI_PACKAGE=fr.esrf.tangoatk.widget.util.jdraw; export APPLI_PACKAGE APPLI_MAIN_CLASS=JDrawEditorFrame; export APPLI_MAIN_CLASS CLASSPATH=$TANGOATK:$TANGO export CLASSPATH echo "CLASSPATH=$CLASSPATH" echo Running Jdraw ... #--------------------------------------------------------- # Start the Jdraw process #--------------------------------------------------------- # @JAVA@ $APPLI_PACKAGE.$APPLI_MAIN_CLASS $@ tango-9.2.5a/lib/java/synopticappli.in0000755023471100065110000000212013034744715014651 00000000000000#!@SHELL@ #--------------------------------------------------------- # #--------------------------------------------------------- if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi LIB_DIR=@prefix@/share/java; export LIB_DIR APP_DIR=@prefix@/share/java; export APP_DIR #-------------------------------------------------------------------------- # Set the Class Path for Tango, ATK and Simple Synoptic Appli in ATK #-------------------------------------------------------------------------- TANGO=$LIB_DIR/JTango.jar TANGOATK=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar ATKPANEL=$APP_DIR/atkpanel.jar APPLI_PACKAGE=fr.esrf.tangoatk.widget.jdraw; export APPLI_PACKAGE APPLI_MAIN_CLASS=SimpleSynopticAppli; export APPLI_MAIN_CLASS CLASSPATH=$TACO:$TANGO:$TANGOATK:$ATKPANEL export CLASSPATH echo "CLASSPATH=$CLASSPATH" #--------------------------------------------------------- # Start the synoptic appli process #--------------------------------------------------------- # @JAVA@ -mx128m -DTANGO_HOST=$TANGO_HOST $APPLI_PACKAGE.$APPLI_MAIN_CLASS $* tango-9.2.5a/lib/java/atkmoni.in0000755023471100065110000000154213034744714013423 00000000000000#!@SHELL@ if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi #--------------------------------------------------------- # Set the Class Path for Tango, ATK and AtkMoni usage #--------------------------------------------------------- LIB_DIR=@prefix@/share/java; export LIB_DIR APP_DIR=@prefix@/share/java; export APP_DIR TANGO=$LIB_DIR/JTango.jar TANGOATK=$LIB_DIR/ATKCore.jar:$LIB_DIR/ATKWidget.jar APPLI_PACKAGE=fr.esrf.tangoatk.widget.attribute; export APPLI_PACKAGE APPLI_MAIN_CLASS=Trend; export APPLI_MAIN_CLASS CLASSPATH=$TANGO:$TACO:$TANGOATK export CLASSPATH echo "CLASSPATH=$CLASSPATH" #--------------------------------------------------------- # Start the atkmoni process #--------------------------------------------------------- # @JAVA@ -DTANGO_HOST=$TANGO_HOST $APPLI_PACKAGE.$APPLI_MAIN_CLASS $* tango-9.2.5a/lib/java/cvstag.in0000755023471100065110000000120213034744714013241 00000000000000#!@SHELL@ # # Define the CLASSPATH # JAVALIB=@prefix@/share/java; JAVABIN=@prefix@/share/java; #--------------------------------------------------------- # Set the Class Path for Tango and pogo usage #--------------------------------------------------------- APP_DIR=@prefix@/share/java; export APP_DIR TANGO_CLASS=$APP_DIR/JTango.jar; export TANGO_CLASS POGO_CLASS=$APP_DIR/Pogo.jar; export POGO_CLASS CLASSPATH=$POGO_CLASS:$TANGO_CLASS; export CLASSPATH #--------------------------------------------------------- # Execute java class #--------------------------------------------------------- @JAVA@ pogo.make_util.TagModule $@ tango-9.2.5a/lib/java/tg_devtest.in0000755023471100065110000000047513034744715014136 00000000000000#@SHELL@ if [ ! $TANGO_HOST ] && [ -f @TANGO_RC_FILE@ ]; then . @TANGO_RC_FILE@ fi JAVALIB=@prefix@/share/java; TANGOATK=$JAVALIB/ATKCore.jar:$JAVALIB/ATKWidget.jar CLASSPATH=$JAVALIB/JTango.jar:$JAVALIB/Jive.jar:$TANGOATK export CLASSPATH echo Starting... @JAVA@ -DTANGO_HOST=$TANGO_HOST jive.ExecDev $1 tango-9.2.5a/lib/java/TangoVers.in0000755023471100065110000000034613034744715013673 00000000000000#!@SHELL@ # # Set the Class Path # LIB_DIR=@prefix@/share/java; export LIB_DIR CLASSPATH=$LIB_DIR/JTango.jar:$LIB_DIR/Astor.jar export CLASSPATH # # Start the java virtual machine # @JAVA@ admin.astor.tango_release.JTangoVersion tango-9.2.5a/utils/0000755023471100065110000000000013034745261011153 500000000000000tango-9.2.5a/utils/Makefile.am0000644023471100065110000000002713034744702013125 00000000000000 SUBDIRS = tango_admin tango-9.2.5a/utils/Makefile.in0000644023471100065110000005035013034745123013140 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = utils DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = tango_admin all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu utils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu utils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/utils/tango_admin/0000755023471100065110000000000013034745261013433 500000000000000tango-9.2.5a/utils/tango_admin/Makefile.am0000644023471100065110000000100413034745034015400 00000000000000 AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) bin_PROGRAMS=tango_admin tango_admin_SOURCES=tango_admin.cpp \ anyoption.cpp \ anyoption.h tango-9.2.5a/utils/tango_admin/Makefile.in0000644023471100065110000005271613034745123015430 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = tango_admin$(EXEEXT) subdir = utils/tango_admin DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_tango_admin_OBJECTS = tango_admin.$(OBJEXT) anyoption.$(OBJEXT) tango_admin_OBJECTS = $(am_tango_admin_OBJECTS) tango_admin_LDADD = $(LDADD) am__DEPENDENCIES_1 = tango_admin_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(tango_admin_SOURCES) DIST_SOURCES = $(tango_admin_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) tango_admin_SOURCES = tango_admin.cpp \ anyoption.cpp \ anyoption.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu utils/tango_admin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu utils/tango_admin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list tango_admin$(EXEEXT): $(tango_admin_OBJECTS) $(tango_admin_DEPENDENCIES) $(EXTRA_tango_admin_DEPENDENCIES) @rm -f tango_admin$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(tango_admin_OBJECTS) $(tango_admin_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anyoption.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tango_admin.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/utils/tango_admin/tango_admin.cpp0000644023471100065110000010244013034745034016336 00000000000000static const char *RcsId = "$Id: tango_admin.cpp 27948 2015-05-05 14:29:24Z taurel $"; //+============================================================================ // // file : tango_admin.cpp // // description : C++ source code for the tango_admin utility // This utility is a Tango database command line interface // Obviously, not all the database features are interfaced // by this tool. Only the features needed for the Debian // packaging have been implemented. This means: // - ping the database server // - check if a device is defined in DB // - check if a server is defined in DB // - create a server in DB // - delete a server from the DB // - create a property in DB // - delete a property from DB // // project : TANGO // // author(s) : E.Taurel // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 27948 $ // //-============================================================================ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include using namespace std; int ping_database(int); int check_device(char *); int add_server(char *,char *,char *); void list2vect(string &,vector &); int check_server(char *); int server_list(); int server_instance_list(char *); int delete_server(char *,bool); int add_property(char *,char *,char *); int delete_property(char *,char *); int ping_network(int,bool); int check_net(bool); int tac_enabled(void); int ping_device(char *,int); int check_dev(char *); int main(int argc,char *argv[]) { AnyOption *opt = new AnyOption(); // // Add usage menu // opt->addUsage("Usage: " ); opt->addUsage(" --help Prints this help " ); opt->addUsage(" --ping-database [max_time (s)] Ping database " ); opt->addUsage(" --check-device Check if the device is defined in DB"); opt->addUsage(" --add-server Add a server in DB" ); opt->addUsage(" --delete-server [--with-properties] Delete a server from DB" ); opt->addUsage(" --check-server Check if a device server is defined in DB"); opt->addUsage(" --server-list Display list of server names"); opt->addUsage(" --server-instance-list Display list of server instances for the given server name"); opt->addUsage(" --add-property Add a device property in DB" ); opt->addUsage(" --delete-property Delete a device property from DB "); opt->addUsage(" --tac-enabled Check if the TAC (Tango Access Control) is enabled"); opt->addUsage(" --ping-device [max_time (s)] Check if the device is running"); opt->addUsage(" --ping-network [max_time (s)] [-v] Ping network "); // // Define the command line options // opt->setFlag("help",'h'); opt->setFlag("ping-database"); opt->setOption("add-server"); opt->setOption("delete-server"); opt->setFlag("with-properties"); opt->setOption("add-property"); opt->setOption("delete-property"); opt->setOption("check-device"); opt->setOption("check-server"); opt->setFlag("server-list"); opt->setOption("server-instance-list"); opt->setOption("ping-device"); opt->setFlag("ping-network"); opt->setFlag("tac-enabled"); // // Process cmd line // opt->processCommandArgs( argc, argv ); if (!opt->hasOptions()) { opt->printUsage(); delete opt; return 0; } // // --help option // if (opt->getFlag("help") || opt->getFlag('h')) { opt->printUsage(); delete opt; return 0; } // // --ping-database option // if (opt->getFlag("ping-database") == true) { if (opt->getValue("add-server") != NULL || opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --ping-database with other option(s)" << endl; if (argc > 3) { cout << "Bad argument number for option --ping-database" << endl; opt->printUsage(); delete opt; return 0; } int ret; if (argc == 2) ret = ping_database(0); else { int sec = atoi(argv[2]); ret = ping_database(sec); } delete opt; return ret; } // // --check-device option // else if (opt->getValue("check-device") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --add-server with other option(s)" << endl; else { if (argc != 3) { cout << "Bad argument number for option --check_device" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = check_device(opt->getValue("check-device")); delete opt; return ret; } } // // --add-server option // else if (opt->getValue("add-server") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --add-server with other option(s)" << endl; else { if (argc != 5) { cout << "Bad argument number for option --add-server" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = add_server(opt->getValue("add-server"),opt->getArgv(0),opt->getArgv(1)); delete opt; return ret; } } // // --check-server option // else if (opt->getValue("check-server") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-device") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --check-server with other option(s)" << endl; else { if (argc != 3) { cout << "Bad argument number for option --check_server" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = check_server(opt->getValue("check-server")); delete opt; return ret; } } // // --server-list option // else if (opt->getFlag("server-list") == true) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-device") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --server-list with other option(s)" << endl; else { if (argc != 2) { cout << "Bad argument number for option --server-list" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = server_list(); delete opt; return ret; } } // // --server-instance-list option // else if (opt->getValue("server-instance-list") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-device") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --server-instance-list with other option(s)" << endl; else { if (argc != 3) { cout << "Bad argument number for option --server-instance-list" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = server_instance_list(opt->getValue("server-instance-list")); delete opt; return ret; } } // // --delete-server option // else if (opt->getValue("delete-server") != NULL) { if (opt->getValue("add-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("check-server") != NULL || opt->getValue("check-device") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getValue("delete-property") != NULL) cout << "Can't mix option --delete-server with other option(s)" << endl; else { if ((argc < 3 || argc > 4) || (argc == 3 && strcmp(argv[2],"--with-properties") == 0) || (strcmp(opt->getValue("delete-server"),"--with-properties") == 0)) { cout << "Bad option delete-server usage" << endl; opt->printUsage(); delete opt; return 0; } int ret; if (opt->getFlag("with-properties") == true) ret = delete_server(opt->getValue("delete-server"),true); else ret = delete_server(opt->getValue("delete-server"),false); delete opt; return ret; } } // // --add-property option // else if (opt->getValue("add-property") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("with-properties") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("ping-network") == true || opt->getFlag("ping-database") == true) cout << "Can't mix option --add-property with other option(s)" << endl; else { if (argc != 5) { cout << "Bag argument number for option --add-property" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = add_property(opt->getValue("add-property"),opt->getArgv(0),opt->getArgv(1)); delete opt; return ret; } } // // --delete-property option // else if (opt->getValue("delete-property") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("with-properties") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("ping-database") == true) cout << "Can't mix option --delete-property with other option(s)" << endl; else { if (argc != 4) { cout << "Bag argument number for option --add-property" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = delete_property(opt->getValue("delete-property"),opt->getArgv(0)); delete opt; return ret; } } // // --ping-network option // if (opt->getFlag("ping-network") == true) { bool verbose = false; if (opt->getValue("add-server") != NULL || opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-database") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --ping-network with other option(s)" << endl; if (argc > 4) { cout << "Bad argument number for option --ping-network" << endl; opt->printUsage(); delete opt; return 0; } else if (argc == 4) { if (strcmp(argv[3],"-v") != 0) { cout << "Bad argument for option --ping-network" << endl; opt->printUsage(); delete opt; return 0; } else verbose = true; } else if (argc == 3) { if (strcmp(argv[2],"-v") == 0) { verbose = true; } } int ret; if (argc == 2) ret = ping_network(0,verbose); else { int sec = 0; sec = atoi(argv[2]); if ((verbose == false) && (sec == 0)) { cout << "Bad argument for option --ping-network" << endl; opt->printUsage(); delete opt; return 0; } ret = ping_network(sec,verbose); } delete opt; return ret; } // // --tac-enabled option // if (opt->getFlag("tac-enabled") == true) { if (opt->getValue("add-server") != NULL || opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("check-device") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --tac-enabled with other option(s)" << endl; if (argc > 2) { cout << "Bad argument number for option --tac-enabled" << endl; opt->printUsage(); delete opt; return 0; } int ret; ret = tac_enabled(); delete opt; return ret; } // // --ping-device option // if (opt->getValue("ping-device") != NULL) { if (opt->getValue("delete-server") != NULL || opt->getValue("add-property") != NULL || opt->getValue("delete-property") != NULL || opt->getValue("add-server") != NULL || opt->getValue("check-server") != NULL || opt->getValue("server-instance-list") != NULL || opt->getFlag("server-list") == true || opt->getFlag("ping-network") == true || opt->getFlag("tac-enabled") == true || opt->getFlag("with-properties") == true) cout << "Can't mix option --ping-device with other option(s)" << endl; else { int ret; int sec = 0; if (argc < 3 || argc > 4) { cout << "Bad argument number for option --ping_device" << endl; opt->printUsage(); delete opt; return 0; } else if (argc == 4) { sec = atoi(argv[3]); } ret = ping_device(opt->getValue("ping-device"),sec); delete opt; return ret; } } // // Unknown choice // else { cout << "Wrong usage" << endl; opt->printUsage(); } delete opt; } //+------------------------------------------------------------------------- // // method : ping_database // // description : This function connect to the database and executes // one of its command in order to check the database // connectivity. // // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int ping_database(int nb_sec) { int ret = 0; setenv("SUPER_TANGO","true",1); int nb_loop; bool infinite = false; if (nb_sec == 0) nb_loop = 1; else if (nb_sec < 0) { infinite = true; nb_loop = 2; } else nb_loop = nb_sec << 1; struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 500000000; // // First sleep for 1 sec before trying to access the db // This was needed when ported to Natty (Ubuntu 11.04) in the // tango-db startup script. Db process did not start if tango // admin starts pinging db device too early !! // if (nb_loop != 1) { ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts,NULL); } // // re-try the call every 500 mS // ts.tv_sec = 0; ts.tv_nsec = 500000000; while(nb_loop > 0) { try { Tango::Database db; string db_info; db_info = db.get_info(); ret = 0; nb_loop = 0; } catch (Tango::DevFailed &e) { ret = -1; if (infinite == false) --nb_loop; } if (nb_loop != 0) nanosleep(&ts,NULL); } return ret; } //+------------------------------------------------------------------------- // // method : check_device // // description : This function checks if a device is defined in the DB // // argument : in : - name : The device name // // The function returns 0 is the device is defined. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int check_device(char *name) { int ret = 0; try { Tango::Database db; string d_name(name); Tango::DbDevImportInfo dii = db.import_device(d_name); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : add_server // // description : This function adds a server definition in the DB // // argument : in : - d_name : The device server name (exec/inst) // - c_name : The class name // - d_list : The device list // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int add_server(char *d_name,char *c_name,char *d_list) { int ret = 0; // // Check ds name syntax // string ds_name(d_name); string::size_type pos; pos = ds_name.find('/'); #ifdef __SUNPRO_CC int n1 = 0; count(ds_name.begin(),ds_name.end(),'/',n1); if ((n1 != 1) || pos == 0 || pos == (ds_name.size() - 1)) { #else if ((count(ds_name.begin(),ds_name.end(),'/') != 1) || pos == 0 || pos == (ds_name.size() - 1)) { #endif cout << "Wrong syntax for ds name" << endl; ret = -1; return ret; } // // Check class name syntax // string class_name(c_name); #ifdef __SUNPRO_CC count(class_name.begin(),class_name.end(),'/',n1); if (n1 != 0) { #else if (count(class_name.begin(),class_name.end(),'/') != 0) { #endif cout << "Wrong syntax for class name" << endl; ret = -1; return ret; } // // Check device list and device syntax // string dev_list(d_list); vector dev_names; list2vect(dev_list,dev_names); for (unsigned int loop = 0;loop < dev_names.size();++loop) { #ifdef __SUNPRO_CC count(dev_names[loop].begin(),dev_names[loop].end(),'/',n1); if (n1 != 2) { #else if (count(dev_names[loop].begin(),dev_names[loop].end(),'/') != 2) { #endif cout << "Wrong syntax for device " << dev_names[loop] << endl; ret = -1; return ret; } string::size_type pos1,pos2; pos1 = dev_names[loop].find('/'); pos2 = dev_names[loop].rfind('/'); if (pos1 == 0 || pos2 == dev_names[loop].length() - 1 || pos2 == pos1 + 1) { cout << "Wrong syntax for device " << dev_names[loop] << endl; ret = -1; return ret; } } // // Create server in DB // Dont forget to add the admin device // setenv("SUPER_TANGO","true",1); try { Tango::Database db; Tango::DbDevInfos ddi; Tango::DbDevInfo tmp_dbi; for (unsigned int loop = 0;loop < dev_names.size();++loop) { tmp_dbi.name = dev_names[loop]; tmp_dbi._class = class_name; tmp_dbi.server = ds_name; ddi.push_back(tmp_dbi); } tmp_dbi.name = "dserver/" + ds_name; tmp_dbi._class = "DServer"; tmp_dbi.server = ds_name; ddi.push_back(tmp_dbi); db.add_server(ds_name,ddi); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : check_server // // description : This function checks if a device server is defined in the DB // // argument : in : - d_name : The device server name // // The function returns 0 is the device is defined. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int check_server(char *d_name) { int ret = 0; string dev_name = "dserver/"; string ds_name = d_name; dev_name = dev_name + ds_name; ret = check_device((char *)dev_name.c_str()); return ret; } //+------------------------------------------------------------------------- // // method : server_list // // description : This function lists all server names // // The function returns 0 if at least one server is defined. Otherwise returns -1 // //-------------------------------------------------------------------------- int server_list() { int ret = 0; try { Tango::Database db; vector servers; db.get_server_name_list() >> servers; for(int idx = 0; idx < servers.size(); ++idx) { cout << servers[idx] << " "; } cout << endl; } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : server_instance_list // // description : This function lists all server instances for the given // server name // // argument : in : - s_name : The server name // // The function returns 0 is the server name is defined. Otherwise returns -1 // //-------------------------------------------------------------------------- int server_instance_list(char *s_name) { int ret = 0; try { Tango::Database db; string server_name = s_name; size_t start_pos = server_name.size() + 1; server_name += "/*"; vector servers; db.get_server_list(server_name) >> servers; for(int idx = 0; idx < servers.size(); ++idx) { cout << servers[idx].substr(start_pos) << " "; } cout << endl; } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : delete_server // // description : This function deletes a device server from the DB // // argument : in : - d_name : The device server name // - with_res : If true, also delte device properties // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int delete_server(char *d_name,bool with_res) { int ret = 0; string ds_name(d_name); // // Check device server name syntax // string::size_type pos; pos = ds_name.find('/'); #ifdef __SUNPRO_CC int n1 = 0; count(ds_name.begin(),ds_name.end(),'/',n1); if (pos == 0 || pos == ds_name.size() - 1 || n1 != 1) { #else if (pos == 0 || pos == ds_name.size() - 1 || count(ds_name.begin(),ds_name.end(),'/') != 1) { #endif ret = -1; return ret; } ret = check_server(d_name); if (ret != 0) return ret; try { Tango::Database db; // // If we need to remove prop // if (with_res == true) { // // First get the ds class list // Tango::DbDatum db_res = db.get_device_class_list(ds_name); vector dev_list; db_res >> dev_list; // // Get device property name for each device // for (unsigned int loop = 0;loop < dev_list.size();++loop) { vector prop_list; db.get_device_property_list(dev_list[loop],"*",prop_list); // // Delete all device properties // if (prop_list.empty() == false) { Tango::DbData dbd; for (unsigned int ctr = 0;ctr < prop_list.size();++ctr) dbd.push_back(Tango::DbDatum(prop_list[ctr])); db.delete_device_property(dev_list[loop],dbd); } ++loop; } } // // Delete device server from db // db.delete_server(ds_name); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : add_property // // description : This function adds a device property in the DB // // argument : in : - d_name : The device name // - p_name : The property name // - p_val : The property value // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int add_property(char *d_name,char *p_name,char *p_val) { int ret = 0; // // Check dev name syntax // string dev_name(d_name); string::size_type pos1,pos2; pos1 = dev_name.find('/'); pos2 = dev_name.rfind('/'); #ifdef __SUNPRO_CC int n1 = 0; count(dev_name.begin(),dev_name.end(),'/',n1); if ((n1 != 2) || pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1) { #else if ((count(dev_name.begin(),dev_name.end(),'/') != 2) || pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1) { #endif cout << "Wrong syntax for device name" << endl; ret = -1; return ret; } // // Check if the device is defined // if (check_device(d_name) != 0) return -1; // // Convert prop value(s) into a vector // string prop_val(p_val); vector prop_val_list; list2vect(prop_val,prop_val_list); // // Create server in DB // Dont forget to add the admin device // try { Tango::Database db; Tango::DbData dbd; Tango::DbDatum db_s(p_name); db_s << prop_val_list; dbd.push_back(db_s); db.put_device_property(dev_name,dbd); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : delete_property // // description : This function deletes a device property from the DB // // argument : in : - d_name : The device name // - p_name : The property name // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int delete_property(char *d_name,char *p_name) { int ret = 0; // // Check dev name syntax // string dev_name(d_name); string::size_type pos1,pos2; pos1 = dev_name.find('/'); pos2 = dev_name.rfind('/'); #ifdef __SUNPRO_CC int n1 = 0; count(dev_name.begin(),dev_name.end(),'/',n1); if ((n1 != 2) || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1) { #else if ((count(dev_name.begin(),dev_name.end(),'/') != 2) || pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1) { #endif cout << "Wrong syntax for device name" << endl; ret = -1; return ret; } // // Check if the device is defined // if (check_device(d_name) != 0) return -1; // // Create server in DB // Dont forget to add the admin device // try { Tango::Database db; Tango::DbData dbd; dbd.push_back(Tango::DbDatum(p_name)); db.delete_device_property(dev_name,dbd); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : list2vect // // description : This function converts a comma separated // device list into a vector of strings with one // element for each device // // argument : in : - dev_list : The device list // - dev_names : The device vector // //-------------------------------------------------------------------------- void list2vect(string &dev_list,vector &dev_names) { string::size_type beg,end; bool end_loop = false; beg = 0; while (end_loop == false) { end = dev_list.find(',',beg); if (end == beg) { ++beg; continue; } if (end == string::npos) { end = dev_list.length(); end_loop = true; } string one_dev; one_dev = dev_list.substr(beg,end - beg); dev_names.push_back(one_dev); beg = end + 1; if (beg == dev_list.size()) end_loop = true; } } //+------------------------------------------------------------------------- // // method : ping_network // // description : This function periodically chechs the network avaibility // // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure // - verbose : Boolean flag set to true if some printing is required // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int ping_network(int nb_sec,bool verbose) { int ret = 0; int nb_loop; bool infinite = false; if (nb_sec == 0) nb_loop = 1; else if (nb_sec < 0) { infinite = true; nb_loop = 2; } else nb_loop = nb_sec << 1; // // re-try the call every 500 mS // struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 500000000; while(nb_loop > 0) { int res = check_net(verbose); if (res == 0) { ret = 0; nb_loop = 0; } else { ret = -1; if (infinite == false) --nb_loop; } if (nb_loop != 0) nanosleep(&ts,NULL); } return ret; } //+------------------------------------------------------------------------- // // method : check_net // // description : This function connect to the network and check if it is // fully ready. // // argument : in : - verbose : Flag set to true if some printing is required // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int check_net(bool verbose) { int ret = 0; char buffer[80]; string hostname; if (gethostname(buffer,80) == 0) { hostname = buffer; if (verbose == true) cout << "Host name returned by gethostname function: " << hostname << endl; struct addrinfo hints; memset(&hints,0,sizeof(struct addrinfo)); hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; struct addrinfo *info; struct addrinfo *ptr; char tmp_host[512]; int result; result = getaddrinfo(buffer, NULL, &hints, &info); if (result == 0) { ptr = info; if (verbose == true) cout << "getaddrinfo() is a success" << endl; while (ptr != NULL) { if (getnameinfo(ptr->ai_addr,ptr->ai_addrlen,tmp_host,512,0,0,0) != 0) { if (verbose == true) cout << "getnameinfo() call failed" << endl; ret = -1; break; } if (verbose == true) cout << "Host name as returned by getnameinfo call: " << tmp_host << endl; ptr = ptr->ai_next; } freeaddrinfo(info); } else { if (verbose == true) cout << "getaddrinfo() call failed with returned value = " << result << endl; ret = -1; } } else { cout << "Cant retrieve server host name" << endl; ret = -1; } return ret; } //+------------------------------------------------------------------------- // // method : tac_enabled // // description : This function check in DB if the TAC is enabled // // The function returns 0 if the TAC is disabled. Otherwise, it returns 1 // //-------------------------------------------------------------------------- int tac_enabled(void) { int ret = 1; setenv("SUPER_TANGO","true",1); try { Tango::Database db; string servicename("AccessControl"); string instname("tango"); Tango::DbDatum db_datum = db.get_services(servicename,instname); vector service_list; db_datum >> service_list; if (service_list.empty() == true) ret = 0; } catch (Tango::DevFailed &e) { ret = 0; } return ret; } //+------------------------------------------------------------------------- // // method : ping_device // // description : This function periodically chechs a device avaibility // // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure // - dev_name : The device name // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int ping_device(char *dev_name,int nb_sec) { int ret = 0; int nb_loop; bool infinite = false; if (nb_sec == 0) nb_loop = 1; else if (nb_sec < 0) { infinite = true; nb_loop = 2; } else nb_loop = nb_sec << 1; // // re-try the call every 500 mS // struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 500000000; while(nb_loop > 0) { int res = check_dev(dev_name); if (res == 0) { ret = 0; nb_loop = 0; } else { ret = -1; if (infinite == false) --nb_loop; } if (nb_loop != 0) nanosleep(&ts,NULL); } return ret; } //+------------------------------------------------------------------------- // // method : check_dev // // description : This function connect to a device and try to ping it // // argument : in : - dev_name : The device name // // The function returns 0 is everything is fine. Otherwise, it returns -1 // //-------------------------------------------------------------------------- int check_dev(char *dev_name) { int ret = 0; try { Tango::DeviceProxy dev(dev_name); dev.ping(); } catch (Tango::DevFailed &e) { ret = -1; } return ret; } tango-9.2.5a/utils/tango_admin/anyoption.cpp0000644023471100065110000006174113034745034016106 00000000000000static const char *RcsId = "$Id: anyoption.cpp 20288 2012-05-23 11:01:15Z taurel $"; //+============================================================================ // // file : anyoption.cpp // // description : C++ source code for the AnyOption // class. This class is used to manage the command line // line arguments. This code comes from the // http://www.hackorama.com/anyoption. // // project : TANGO // // author(s) : Kishan Thomas (E.Taurel) // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This code (and the associated include file) comes from the following // web page: http://www.hackorama.com/anyoption/ // // It is available there without any licensing informations. // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 20288 $ // //-============================================================================ #include "anyoption.h" AnyOption::AnyOption() { init(); } AnyOption::AnyOption(int maxopt) { init( maxopt , maxopt ); } AnyOption::AnyOption(int maxopt, int maxcharopt) { init( maxopt , maxcharopt ); } AnyOption::~AnyOption() { if( mem_allocated ) cleanup(); } void AnyOption::init() { init( DEFAULT_MAXOPTS , DEFAULT_MAXOPTS ); } void AnyOption::init(int maxopt, int maxcharopt ) { max_options = maxopt; max_char_options = maxcharopt; max_usage_lines = DEFAULT_MAXUSAGE; usage_lines = 0 ; argc = 0; argv = NULL; posix_style = true; verbose = false; filename = NULL; appname = NULL; option_counter = 0; optchar_counter = 0; new_argv = NULL; new_argc = 0 ; max_legal_args = 0 ; command_set = false; file_set = false; values = NULL; g_value_counter = 0; mem_allocated = false; command_set = false; file_set = false; opt_prefix_char = '-'; file_delimiter_char = ':'; file_comment_char = '#'; equalsign = '='; comment = '#' ; delimiter = ':' ; endofline = '\n'; whitespace = ' ' ; nullterminate = '\0'; set = false; once = true; hasoptions = false; autousage = false; ::strcpy( long_opt_prefix , "--" ); if( alloc() == false ){ cout << endl << "OPTIONS ERROR : Failed allocating memory" ; cout << endl ; cout << "Exiting." << endl ; exit (0); } } bool AnyOption::alloc() { int i = 0 ; int size = 0 ; if( mem_allocated ) return true; size = (max_options+1) * sizeof(const char*); options = (const char**)malloc( size ); optiontype = (int*) malloc( (max_options+1)*sizeof(int) ); optionindex = (int*) malloc( (max_options+1)*sizeof(int) ); if( options == NULL || optiontype == NULL || optionindex == NULL ) return false; else mem_allocated = true; for( i = 0 ; i < max_options ; i++ ){ options[i] = NULL; optiontype[i] = 0 ; optionindex[i] = -1 ; } optionchars = (char*) malloc( (max_char_options+1)*sizeof(char) ); optchartype = (int*) malloc( (max_char_options+1)*sizeof(int) ); optcharindex = (int*) malloc( (max_char_options+1)*sizeof(int) ); if( optionchars == NULL || optchartype == NULL || optcharindex == NULL ) { mem_allocated = false; return false; } for( i = 0 ; i < max_char_options ; i++ ){ optionchars[i] = '0'; optchartype[i] = 0 ; optcharindex[i] = -1 ; } size = (max_usage_lines+1) * sizeof(const char*) ; usage = (const char**) malloc( size ); if( usage == NULL ){ mem_allocated = false; return false; } for( i = 0 ; i < max_usage_lines ; i++ ) usage[i] = NULL; return true; } bool AnyOption::doubleOptStorage() { const char **tmp_ptr; int *tmp_ptr_int; tmp_ptr = options; options = (const char**)realloc( tmp_ptr, ((2*max_options)+1) * sizeof( const char*) ); if( options == NULL) { free(tmp_ptr); return false; } tmp_ptr_int = optiontype; optiontype = (int*) realloc( tmp_ptr_int , ((2 * max_options)+1)* sizeof(int) ); if( optiontype == NULL) { free(tmp_ptr_int); return false; } tmp_ptr_int = optionindex; optionindex = (int*) realloc( tmp_ptr_int, ((2 * max_options)+1) * sizeof(int) ); if (optionindex == NULL) { free(tmp_ptr_int); return false; } /* init new storage */ for( int i = max_options ; i < 2*max_options ; i++ ){ options[i] = NULL; optiontype[i] = 0 ; optionindex[i] = -1 ; } max_options = 2 * max_options ; return true; } bool AnyOption::doubleCharStorage() { char *tmp_ptr; int *tmp_ptr_int; tmp_ptr = optionchars; optionchars = (char*) realloc( tmp_ptr, ((2*max_char_options)+1)*sizeof(char) ); if( optionchars == NULL) { free(tmp_ptr); return false; } tmp_ptr_int = optchartype; optchartype = (int*) realloc( tmp_ptr_int, ((2*max_char_options)+1)*sizeof(int) ); if (optchartype == NULL) { free(tmp_ptr_int); return false; } tmp_ptr_int = optcharindex; optcharindex = (int*) realloc( tmp_ptr_int, ((2*max_char_options)+1)*sizeof(int) ); if (optcharindex == NULL) { free(tmp_ptr_int); return false; } /* init new storage */ for( int i = max_char_options ; i < 2*max_char_options ; i++ ){ optionchars[i] = '0'; optchartype[i] = 0 ; optcharindex[i] = -1 ; } max_char_options = 2 * max_char_options; return true; } bool AnyOption::doubleUsageStorage() { const char **new_usage = (const char**)realloc( usage, ((2*max_usage_lines)+1) * sizeof( const char*) ); if ( new_usage == NULL ) { free(usage); return false; } usage = new_usage; for( int i = max_usage_lines ; i < 2*max_usage_lines ; i++ ) usage[i] = NULL; max_usage_lines = 2 * max_usage_lines ; return true; } void AnyOption::cleanup() { if (options != NULL) free (options); if (optiontype != NULL) free (optiontype); if (optionindex != NULL) free (optionindex); if (optionchars != NULL) free (optionchars); if (optchartype != NULL) free (optchartype); if (optcharindex != NULL) free (optcharindex); if (usage != NULL) free (usage); if( values != NULL ) free (values); if( new_argv != NULL ) free (new_argv); } void AnyOption::setCommandPrefixChar( char _prefix ) { opt_prefix_char = _prefix; } void AnyOption::setCommandLongPrefix( char *_prefix ) { if( strlen( _prefix ) > MAX_LONG_PREFIX_LENGTH ){ *( _prefix + MAX_LONG_PREFIX_LENGTH ) = '\0'; } strcpy (long_opt_prefix, _prefix); } void AnyOption::setFileCommentChar( char _comment ) { file_delimiter_char = _comment; } void AnyOption::setFileDelimiterChar( char _delimiter ) { file_comment_char = _delimiter ; } bool AnyOption::CommandSet() { return( command_set ); } bool AnyOption::FileSet() { return( file_set ); } void AnyOption::noPOSIX() { posix_style = false; } bool AnyOption::POSIX() { return posix_style; } void AnyOption::setVerbose() { verbose = true ; } void AnyOption::printVerbose() { if( verbose ) cout << endl ; } void AnyOption::printVerbose( const char *msg ) { if( verbose ) cout << msg ; } void AnyOption::printVerbose( char *msg ) { if( verbose ) cout << msg ; } void AnyOption::printVerbose( char ch ) { if( verbose ) cout << ch ; } bool AnyOption::hasOptions() { return hasoptions; } void AnyOption::autoUsagePrint(bool _autousage) { autousage = _autousage; } void AnyOption::useCommandArgs( int _argc, char **_argv ) { argc = _argc; argv = _argv; command_set = true; appname = argv[0]; if(argc > 1) hasoptions = true; } void AnyOption::useFiileName( const char *_filename ) { filename = _filename; file_set = true; } /* * set methods for options */ void AnyOption::setCommandOption( const char *opt ) { addOption( opt , COMMAND_OPT ); g_value_counter++; } void AnyOption::setCommandOption( char opt ) { addOption( opt , COMMAND_OPT ); g_value_counter++; } void AnyOption::setCommandOption( const char *opt , char optchar ) { addOption( opt , COMMAND_OPT ); addOption( optchar , COMMAND_OPT ); g_value_counter++; } void AnyOption::setCommandFlag( const char *opt ) { addOption( opt , COMMAND_FLAG ); g_value_counter++; } void AnyOption::setCommandFlag( char opt ) { addOption( opt , COMMAND_FLAG ); g_value_counter++; } void AnyOption::setCommandFlag( const char *opt , char optchar ) { addOption( opt , COMMAND_FLAG ); addOption( optchar , COMMAND_FLAG ); g_value_counter++; } void AnyOption::setFileOption( const char *opt ) { addOption( opt , FILE_OPT ); g_value_counter++; } void AnyOption::setFileOption( char opt ) { addOption( opt , FILE_OPT ); g_value_counter++; } void AnyOption::setFileOption( const char *opt , char optchar ) { addOption( opt , FILE_OPT ); addOption( optchar, FILE_OPT ); g_value_counter++; } void AnyOption::setFileFlag( const char *opt ) { addOption( opt , FILE_FLAG ); g_value_counter++; } void AnyOption::setFileFlag( char opt ) { addOption( opt , FILE_FLAG ); g_value_counter++; } void AnyOption::setFileFlag( const char *opt , char optchar ) { addOption( opt , FILE_FLAG ); addOption( optchar , FILE_FLAG ); g_value_counter++; } void AnyOption::setOption( const char *opt ) { addOption( opt , COMMON_OPT ); g_value_counter++; } void AnyOption::setOption( char opt ) { addOption( opt , COMMON_OPT ); g_value_counter++; } void AnyOption::setOption( const char *opt , char optchar ) { addOption( opt , COMMON_OPT ); addOption( optchar , COMMON_OPT ); g_value_counter++; } void AnyOption::setFlag( const char *opt ) { addOption( opt , COMMON_FLAG ); g_value_counter++; } void AnyOption::setFlag( const char opt ) { addOption( opt , COMMON_FLAG ); g_value_counter++; } void AnyOption::setFlag( const char *opt , char optchar ) { addOption( opt , COMMON_FLAG ); addOption( optchar , COMMON_FLAG ); g_value_counter++; } void AnyOption::addOption( const char *opt, int type ) { if( option_counter >= max_options ){ if( doubleOptStorage() == false ){ addOptionError( opt ); return; } } options[ option_counter ] = opt ; optiontype[ option_counter ] = type ; optionindex[ option_counter ] = g_value_counter; option_counter++; } void AnyOption::addOption( char opt, int type ) { if( !POSIX() ){ printVerbose("Ignoring the option character \""); printVerbose( opt ); printVerbose( "\" ( POSIX options are turned off )" ); printVerbose(); return; } if( optchar_counter >= max_char_options ){ if( doubleCharStorage() == false ){ addOptionError( opt ); return; } } optionchars[ optchar_counter ] = opt ; optchartype[ optchar_counter ] = type ; optcharindex[ optchar_counter ] = g_value_counter; optchar_counter++; } void AnyOption::addOptionError( const char *opt ) { cout << endl ; cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ; cout << "While adding the option : \""<< opt << "\"" << endl; cout << "Exiting." << endl ; cout << endl ; exit(0); } void AnyOption::addOptionError( char opt ) { cout << endl ; cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ; cout << "While adding the option: \""<< opt << "\"" << endl; cout << "Exiting." << endl ; cout << endl ; exit(0); } void AnyOption::processOptions() { if( ! valueStoreOK() ) return; } void AnyOption::processCommandArgs(int max_args) { max_legal_args = max_args; processCommandArgs(); } void AnyOption::processCommandArgs( int _argc, char **_argv, int max_args ) { max_legal_args = max_args; processCommandArgs( _argc, _argv ); } void AnyOption::processCommandArgs( int _argc, char **_argv ) { useCommandArgs( _argc, _argv ); processCommandArgs(); } void AnyOption::processCommandArgs() { if( ! ( valueStoreOK() && CommandSet() ) ) return; if( max_legal_args == 0 ) max_legal_args = argc; new_argv = (int*) malloc( (max_legal_args+1) * sizeof(int) ); for( int i = 1 ; i < argc ; i++ ){/* ignore first argv */ if( argv[i][0] == long_opt_prefix[0] && argv[i][1] == long_opt_prefix[1] ) { /* long GNU option */ int match_at = parseGNU( argv[i]+2 ); /* skip -- */ if( match_at >= 0 && i < argc-1 ) /* found match */ setValue( options[match_at] , argv[++i] ); }else if( argv[i][0] == opt_prefix_char ) { /* POSIX char */ if( POSIX() ){ char ch = parsePOSIX( argv[i]+1 );/* skip - */ if( ch != '0' && i < argc-1 ) /* matching char */ setValue( ch , argv[++i] ); } else { /* treat it as GNU option with a - */ int match_at = parseGNU( argv[i]+1 ); /* skip - */ if( match_at >= 0 && i < argc-1 ) /* found match */ setValue( options[match_at] , argv[++i] ); } }else { /* not option but an argument keep index */ if( new_argc < max_legal_args ){ new_argv[ new_argc ] = i ; new_argc++; }else{ /* ignore extra arguments */ printVerbose( "Ignoring extra argument: " ); printVerbose( argv[i] ); printVerbose( ); printAutoUsage(); } printVerbose( "Unknown command argument option : " ); printVerbose( argv[i] ); printVerbose( ); printAutoUsage(); } } } char AnyOption::parsePOSIX( char* arg ) { for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){ char ch = arg[i] ; if( matchChar(ch) ) { /* keep matching flags till an option */ /*if last char argv[++i] is the value */ if( i == strlen(arg)-1 ){ return ch; }else{/* else the rest of arg is the value */ i++; /* skip any '=' and ' ' */ while( arg[i] == whitespace || arg[i] == equalsign ) i++; setValue( ch , arg+i ); return '0'; } } } printVerbose( "Unknown command argument option : " ); printVerbose( arg ); printVerbose( ); printAutoUsage(); return '0'; } int AnyOption::parseGNU( char *arg ) { int split_at = 0; /* if has a '=' sign get value */ for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){ if(arg[i] == equalsign ){ split_at = i ; /* store index */ i = strlen(arg); /* get out of loop */ } } if( split_at > 0 ){ /* it is an option value pair */ char* tmp = (char*) malloc( (split_at+1)*sizeof(char) ); for( int i = 0 ; i < split_at ; i++ ) tmp[i] = arg[i]; tmp[split_at] = '\0'; if ( matchOpt( tmp ) >= 0 ){ setValue( options[matchOpt(tmp)] , arg+split_at+1 ); free (tmp); }else{ printVerbose( "Unknown command argument option : " ); printVerbose( arg ); printVerbose( ); printAutoUsage(); free (tmp); return -1; } }else{ /* regular options with no '=' sign */ return matchOpt(arg); } return -1; } int AnyOption::matchOpt( char *opt ) { for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], opt ) == 0 ){ if( optiontype[i] == COMMON_OPT || optiontype[i] == COMMAND_OPT ) { /* found option return index */ return i; }else if( optiontype[i] == COMMON_FLAG || optiontype[i] == COMMAND_FLAG ) { /* found flag, set it */ setFlagOn( opt ); return -1; } } } printVerbose( "Unknown command argument option : " ); printVerbose( opt ) ; printVerbose( ); printAutoUsage(); return -1; } bool AnyOption::matchChar( char c ) { for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == c ) { /* found match */ if(optchartype[i] == COMMON_OPT || optchartype[i] == COMMAND_OPT ) { /* an option store and stop scanning */ return true; }else if( optchartype[i] == COMMON_FLAG || optchartype[i] == COMMAND_FLAG ) { /* a flag store and keep scanning */ setFlagOn( c ); return false; } } } printVerbose( "Unknown command argument option : " ); printVerbose( c ) ; printVerbose( ); printAutoUsage(); return false; } bool AnyOption::valueStoreOK( ) { if( !set ){ if( g_value_counter > 0 ){ int size = 0; size = g_value_counter * sizeof(char*); values = (char**)malloc( size ); for( int i = 0 ; i < g_value_counter ; i++) values[i] = NULL; set = true; } } return set; } /* * public get methods */ char* AnyOption::getValue( const char *option ) { if( !valueStoreOK() ) return NULL; for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], option ) == 0 ) return values[ optionindex[i] ]; } return NULL; } bool AnyOption::getFlag( const char *option ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], option ) == 0 ) return findFlag( values[ optionindex[i] ] ); } return false; } char* AnyOption::getValue( char option ) { if( !valueStoreOK() ) return NULL; for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == option ) return values[ optcharindex[i] ]; } return NULL; } bool AnyOption::getFlag( char option ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == option ) return findFlag( values[ optcharindex[i] ] ) ; } return false; } bool AnyOption::findFlag( char* val ) { if( val == NULL ) return false; if( strcmp( TRUE_FLAG , val ) == 0 ) return true; return false; } /* * private set methods */ bool AnyOption::setValue( const char *option , char *value ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], option ) == 0 ){ values[ optionindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char)); strcpy( values[ optionindex[i] ], value ); return true; } } return false; } bool AnyOption::setFlagOn( const char *option ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], option ) == 0 ){ values[ optionindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char)); strcpy( values[ optionindex[i] ] , TRUE_FLAG ); return true; } } return false; } bool AnyOption::setValue( char option , char *value ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == option ){ values[ optcharindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char)); strcpy( values[ optcharindex[i] ], value ); return true; } } return false; } bool AnyOption::setFlagOn( char option ) { if( !valueStoreOK() ) return false; for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == option ){ values[ optcharindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char)); strcpy( values[ optcharindex[i] ] , TRUE_FLAG ); return true; } } return false; } int AnyOption::getArgc( ) { return new_argc; } char* AnyOption::getArgv( int index ) { if( index < new_argc ){ return ( argv[ new_argv[ index ] ] ); } return NULL; } /* dotfile sub routines */ bool AnyOption::processFile() { if( ! (valueStoreOK() && FileSet()) ) return false; return ( consumeFile(readFile()) ); } bool AnyOption::processFile( const char *filename ) { useFiileName(filename ); return ( processFile() ); } char* AnyOption::readFile() { return ( readFile(filename) ); } /* * read the file contents to a character buffer */ char* AnyOption::readFile( const char* fname ) { int length; char *buffer; ifstream is; is.open ( fname , ifstream::in ); if( ! is.good() ){ is.close(); return NULL; } is.seekg (0, ios::end); length = is.tellg(); is.seekg (0, ios::beg); buffer = (char*) malloc(length*sizeof(char)); is.read (buffer,length); is.close(); return buffer; } /* * scans a char* buffer for lines that does not * start with the specified comment character. */ bool AnyOption::consumeFile( char *buffer ) { if( buffer == NULL ) return false; char *cursor = buffer;/* preserve the ptr */ char *pline = NULL ; int linelength = 0; bool newline = true; for( unsigned int i = 0 ; i < strlen( buffer ) ; i++ ){ if( *cursor == endofline ) { /* end of line */ if( pline != NULL ) /* valid line */ processLine( pline, linelength ); pline = NULL; newline = true; }else if( newline ){ /* start of line */ newline = false; if( (*cursor != comment ) ){ /* not a comment */ pline = cursor ; linelength = 0 ; } } cursor++; /* keep moving */ linelength++; } free (buffer); return true; } /* * find a valid type value pair separated by a delimiter * character and pass it to valuePairs() * any line which is not valid will be considered a value * and will get passed on to justValue() * * assuming delimiter is ':' the behaviour will be, * * width:10 - valid pair valuePairs( width, 10 ); * width : 10 - valid pair valuepairs( width, 10 ); * * :::: - not valid * width - not valid * :10 - not valid * width: - not valid * :: - not valid * : - not valid * */ void AnyOption::processLine( char *theline, int length ) { bool found = false; char *pline = (char*) malloc( (length+1)*sizeof(char) ); for( int i = 0 ; i < length ; i ++ ) pline[i]= *(theline++); pline[length] = nullterminate; char *cursor = pline ; /* preserve the ptr */ if( *cursor == delimiter || *(cursor+length-1) == delimiter ){ justValue( pline );/* line with start/end delimiter */ }else{ for( int i = 1 ; i < length-1 && !found ; i++){/* delimiter */ if( *cursor == delimiter ){ *(cursor-1) = nullterminate; /* two strings */ found = true; valuePairs( pline , cursor+1 ); } cursor++; } cursor++; if( !found ) /* not a pair */ justValue( pline ); } free (pline); } /* * removes trailing and preceeding whitespaces from a string */ char* AnyOption::chomp( char *str ) { while( *str == whitespace ) str++; char *end = str+strlen(str)-1; while( *end == whitespace ) end--; *(end+1) = nullterminate; return str; } void AnyOption::valuePairs( char *type, char *value ) { if ( strlen(chomp(type)) == 1 ){ /* this is a char option */ for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == type[0] ){ /* match */ if( optchartype[i] == COMMON_OPT || optchartype[i] == FILE_OPT ) { setValue( type[0] , chomp(value) ); return; } } } } /* if no char options matched */ for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], type ) == 0 ){ /* match */ if( optiontype[i] == COMMON_OPT || optiontype[i] == FILE_OPT ) { setValue( type , chomp(value) ); return; } } } printVerbose( "Unknown option in resourcefile : " ); printVerbose( type ); printVerbose( ); } void AnyOption::justValue( char *type ) { if ( strlen(chomp(type)) == 1 ){ /* this is a char option */ for( int i = 0 ; i < optchar_counter ; i++ ){ if( optionchars[i] == type[0] ){ /* match */ if( optchartype[i] == COMMON_FLAG || optchartype[i] == FILE_FLAG ) { setFlagOn( type[0] ); return; } } } } /* if no char options matched */ for( int i = 0 ; i < option_counter ; i++ ){ if( strcmp( options[i], type ) == 0 ){ /* match */ if( optiontype[i] == COMMON_FLAG || optiontype[i] == FILE_FLAG ) { setFlagOn( type ); return; } } } printVerbose( "Unknown option in resourcefile : " ); printVerbose( type ); printVerbose( ); } /* * usage and help */ void AnyOption::printAutoUsage() { if( autousage ) printUsage(); } void AnyOption::printUsage() { if( once ) { once = false ; cout << endl ; for( int i = 0 ; i < usage_lines ; i++ ) cout << usage[i] << endl ; cout << endl ; } } void AnyOption::addUsage( const char *line ) { if( usage_lines >= max_usage_lines ){ if( doubleUsageStorage() == false ){ addUsageError( line ); exit(1); } } usage[ usage_lines ] = line ; usage_lines++; } void AnyOption::addUsageError( const char *line ) { cout << endl ; cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ; cout << "While adding the usage/help : \""<< line << "\"" << endl; cout << "Exiting." << endl ; cout << endl ; exit(0); } tango-9.2.5a/utils/tango_admin/anyoption.h0000644023471100065110000002106213034745034015543 00000000000000// // anyoption.h - include file for command line options management // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . #ifndef _ANYOPTION_H #define _ANYOPTION_H #include #include #include #include #define COMMON_OPT 1 #define COMMAND_OPT 2 #define FILE_OPT 3 #define COMMON_FLAG 4 #define COMMAND_FLAG 5 #define FILE_FLAG 6 #define COMMAND_OPTION_TYPE 1 #define COMMAND_FLAG_TYPE 2 #define FILE_OPTION_TYPE 3 #define FILE_FLAG_TYPE 4 #define UNKNOWN_TYPE 5 #define DEFAULT_MAXOPTS 10 #define MAX_LONG_PREFIX_LENGTH 3 #define DEFAULT_MAXUSAGE 3 #define DEFAULT_MAXHELP 10 #define TRUE_FLAG "true" using namespace std; class AnyOption { public: /* the public interface */ AnyOption(); AnyOption(int maxoptions ); AnyOption(int maxoptions , int maxcharoptions); ~AnyOption(); /* * following set methods specifies the * special characters and delimiters * if not set traditional defaults will be used */ void setCommandPrefixChar( char _prefix ); /* '-' in "-w" */ void setCommandLongPrefix( char *_prefix ); /* '--' in "--width" */ void setFileCommentChar( char _comment ); /* '#' in shellscripts */ void setFileDelimiterChar( char _delimiter );/* ':' in "width : 100" */ /* * provide the input for the options * like argv[] for commndline and the * option file name to use; */ void useCommandArgs( int _argc, char **_argv ); void useFiileName( const char *_filename ); /* * turn off the POSIX style options * this means anything starting with a '-' or "--" * will be considered a valid option * which alo means you cannot add a bunch of * POIX options chars together like "-lr" for "-l -r" * */ void noPOSIX(); /* * prints warning verbose if you set anything wrong */ void setVerbose(); /* * there are two types of options * * Option - has an associated value ( -w 100 ) * Flag - no value, just a boolean flag ( -nogui ) * * the options can be either a string ( GNU style ) * or a character ( traditional POSIX style ) * or both ( --width, -w ) * * the options can be common to the commandline and * the optionfile, or can belong only to either of * commandline and optionfile * * following set methods, handle all the aboove * cases of options. */ /* options comman to command line and option file */ void setOption( const char *opt_string ); void setOption( char opt_char ); void setOption( const char *opt_string , char opt_char ); void setFlag( const char *opt_string ); void setFlag( char opt_char ); void setFlag( const char *opt_string , char opt_char ); /* options read from commandline only */ void setCommandOption( const char *opt_string ); void setCommandOption( char opt_char ); void setCommandOption( const char *opt_string , char opt_char ); void setCommandFlag( const char *opt_string ); void setCommandFlag( char opt_char ); void setCommandFlag( const char *opt_string , char opt_char ); /* options read from an option file only */ void setFileOption( const char *opt_string ); void setFileOption( char opt_char ); void setFileOption( const char *opt_string , char opt_char ); void setFileFlag( const char *opt_string ); void setFileFlag( char opt_char ); void setFileFlag( const char *opt_string , char opt_char ); /* * process the options, registerd using * useCommandArgs() and useFileName(); */ void processOptions(); void processCommandArgs(); void processCommandArgs( int max_args ); bool processFile(); /* * process the specified options */ void processCommandArgs( int _argc, char **_argv ); void processCommandArgs( int _argc, char **_argv, int max_args ); bool processFile( const char *_filename ); /* * get the value of the options * will return NULL if no value is set */ char *getValue( const char *_option ); bool getFlag( const char *_option ); char *getValue( char _optchar ); bool getFlag( char _optchar ); /* * Print Usage */ void printUsage(); void printAutoUsage(); void addUsage( const char *line ); void printHelp(); /* print auto usage printing for unknown options or flag */ void autoUsagePrint(bool flag); /* * get the argument count and arguments sans the options */ int getArgc(); char* getArgv( int index ); bool hasOptions(); private: /* the hidden data structure */ int argc; /* commandline arg count */ char **argv; /* commndline args */ const char* filename; /* the option file */ char* appname; /* the application name from argv[0] */ int *new_argv; /* arguments sans options (index to argv) */ int new_argc; /* argument count sans the options */ int max_legal_args; /* ignore extra arguments */ /* option strings storage + indexing */ int max_options; /* maximum number of options */ const char **options; /* storage */ int *optiontype; /* type - common, command, file */ int *optionindex; /* index into value storage */ int option_counter; /* counter for added options */ /* option chars storage + indexing */ int max_char_options; /* maximum number options */ char *optionchars; /* storage */ int *optchartype; /* type - common, command, file */ int *optcharindex; /* index into value storage */ int optchar_counter; /* counter for added options */ /* values */ char **values; /* common value storage */ int g_value_counter; /* globally updated value index LAME! */ /* help and usage */ const char **usage; /* usage */ int max_usage_lines; /* max usage lines reseverd */ int usage_lines; /* number of usage lines */ bool command_set; /* if argc/argv were provided */ bool file_set; /* if a filename was provided */ bool mem_allocated; /* if memory allocated in init() */ bool posix_style; /* enables to turn off POSIX style options */ bool verbose; /* silent|verbose */ bool print_usage; /* usage verbose */ bool print_help; /* help verbose */ char opt_prefix_char; /* '-' in "-w" */ char long_opt_prefix[MAX_LONG_PREFIX_LENGTH]; /* '--' in "--width" */ char file_delimiter_char; /* ':' in width : 100 */ char file_comment_char; /* '#' in "#this is a comment" */ char equalsign; char comment; char delimiter; char endofline; char whitespace; char nullterminate; bool set; //was static member bool once; //was static member bool hasoptions; bool autousage; private: /* the hidden utils */ void init(); void init(int maxopt, int maxcharopt ); bool alloc(); void cleanup(); bool valueStoreOK(); /* grow storage arrays as required */ bool doubleOptStorage(); bool doubleCharStorage(); bool doubleUsageStorage(); bool setValue( const char *option , char *value ); bool setFlagOn( const char *option ); bool setValue( char optchar , char *value); bool setFlagOn( char optchar ); void addOption( const char* option , int type ); void addOption( char optchar , int type ); void addOptionError( const char *opt); void addOptionError( char opt); bool findFlag( char* value ); void addUsageError( const char *line ); bool CommandSet(); bool FileSet(); bool POSIX(); char parsePOSIX( char* arg ); int parseGNU( char *arg ); bool matchChar( char c ); int matchOpt( char *opt ); /* dot file methods */ char *readFile(); char *readFile( const char* fname ); bool consumeFile( char *buffer ); void processLine( char *theline, int length ); char *chomp( char *str ); void valuePairs( char *type, char *value ); void justValue( char *value ); void printVerbose( const char *msg ); void printVerbose( char *msg ); void printVerbose( char ch ); void printVerbose( ); }; #endif /* ! _ANYOPTION_H */ tango-9.2.5a/cppserver/0000755023471100065110000000000013034745262012025 500000000000000tango-9.2.5a/cppserver/Makefile.am0000644023471100065110000000016113034744715014001 00000000000000 SUBDIRS = starter tangotest if TANGO_DB_SERVER_ENABLED SUBDIRS += database SUBDIRS += tangoaccesscontrol endif tango-9.2.5a/cppserver/Makefile.in0000644023471100065110000005062713034745121014016 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @TANGO_DB_SERVER_ENABLED_TRUE@am__append_1 = database \ @TANGO_DB_SERVER_ENABLED_TRUE@ tangoaccesscontrol subdir = cppserver DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = starter tangotest database tangoaccesscontrol DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = starter tangotest $(am__append_1) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/starter/0000755023471100065110000000000013034745261013510 500000000000000tango-9.2.5a/cppserver/starter/Makefile.am0000644023471100065110000000151113034745014015456 00000000000000 AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/client \ $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) bin_PROGRAMS=Starter Starter_SOURCES=ClassFactory.cpp \ Starter.cpp \ StarterClass.cpp \ StarterUtil.cpp \ StarterStateMachine.cpp \ main.cpp \ PingThread.cpp \ StartProcessThread.cpp \ CheckProcessUtil.cpp \ CheckProcessUtil.h \ PingThread.h \ StarterClass.h \ Starter.h \ StarterUtil.h tango-9.2.5a/cppserver/starter/Makefile.in0000644023471100065110000005464713034745121015510 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = Starter$(EXEEXT) subdir = cppserver/starter DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_Starter_OBJECTS = ClassFactory.$(OBJEXT) Starter.$(OBJEXT) \ StarterClass.$(OBJEXT) StarterUtil.$(OBJEXT) \ StarterStateMachine.$(OBJEXT) main.$(OBJEXT) \ PingThread.$(OBJEXT) StartProcessThread.$(OBJEXT) \ CheckProcessUtil.$(OBJEXT) Starter_OBJECTS = $(am_Starter_OBJECTS) Starter_LDADD = $(LDADD) am__DEPENDENCIES_1 = Starter_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(Starter_SOURCES) DIST_SOURCES = $(Starter_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/client \ $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) Starter_SOURCES = ClassFactory.cpp \ Starter.cpp \ StarterClass.cpp \ StarterUtil.cpp \ StarterStateMachine.cpp \ main.cpp \ PingThread.cpp \ StartProcessThread.cpp \ CheckProcessUtil.cpp \ CheckProcessUtil.h \ PingThread.h \ StarterClass.h \ Starter.h \ StarterUtil.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/starter/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/starter/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list Starter$(EXEEXT): $(Starter_OBJECTS) $(Starter_DEPENDENCIES) $(EXTRA_Starter_DEPENDENCIES) @rm -f Starter$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(Starter_OBJECTS) $(Starter_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CheckProcessUtil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClassFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PingThread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StartProcessThread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Starter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StarterClass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StarterStateMachine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StarterUtil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/starter/ClassFactory.cpp0000644023471100065110000000413213034745014016525 00000000000000/*----- PROTECTED REGION ID(Starter::ClassFactory.cpp) ENABLED START -----*/ static const char *RcsId = "$Header$"; //+============================================================================= // // file : ClassFactory.cpp // // description : C++ source for the class_factory method of the DServer // device class. This method is responsible to create // all class singletin for a device server. It is called // at device server startup // // project : TANGO Device Server // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // //============================================================================= #include #include /** * Create StarterClass singleton and store it in DServer object. * * @author $Author: pascal_verdier $ * @version $Revision: 28168 $ */ void Tango::DServer::class_factory() { add_class(Starter_ns::StarterClass::init("Starter")); } /*----- PROTECTED REGION END -----*/ // Starter::ClassFactory.cpp tango-9.2.5a/cppserver/starter/Starter.cpp0000644023471100065110000015334113034745014015563 00000000000000/*----- PROTECTED REGION ID(Starter.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: Starter.cpp 29529 2016-03-22 10:36:16Z pascal_verdier $"; //============================================================================= // // file : Starter.cpp // // description : C++ source for the Starter and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // Starter are implemented in this file. // // project : Starter for Tango Administration. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 29529 $ // $Date: 2016-03-22 11:36:16 +0100 (Tue, 22 Mar 2016) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include #include #include #include #include #include #include #include /*----- PROTECTED REGION END -----*/ // Starter.cpp /** * Starter class description: * This device server is able to control Tango components (database, device servers, clients...). * It is able to start or stop and to report the status of these components. */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | dev_state // Status | Inherited (no method) // DevStart | dev_start // DevStop | dev_stop // DevStartAll | dev_start_all // DevStopAll | dev_stop_all // DevGetRunningServers | dev_get_running_servers // DevGetStopServers | dev_get_stop_servers // DevReadLog | dev_read_log // HardKillServer | hard_kill_server // NotifyDaemonState | notify_daemon_state // ResetStatistics | reset_statistics // UpdateServersInfo | update_servers_info //================================================================ //================================================================ // Attributes managed are: //================================================================ // NotifdState | Tango::DevState Scalar // HostState | Tango::DevShort Scalar // RunningServers | Tango::DevString Spectrum ( max = 200) // StoppedServers | Tango::DevString Spectrum ( max = 200) // Servers | Tango::DevString Spectrum ( max = 1024) //================================================================ namespace Starter_ns { /*----- PROTECTED REGION ID(Starter::namespace_starting) ENABLED START -----*/ // static initializations /*----- PROTECTED REGION END -----*/ // Starter::namespace_starting //-------------------------------------------------------- /** * Method : Starter::Starter() * Description : Constructors for a Tango device * implementing the classStarter */ //-------------------------------------------------------- Starter::Starter(Tango::DeviceClass *cl, string &s) : TANGO_BASE_CLASS(cl, s.c_str()) { /*----- PROTECTED REGION ID(Starter::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // Starter::constructor_1 } //-------------------------------------------------------- Starter::Starter(Tango::DeviceClass *cl, const char *s) : TANGO_BASE_CLASS(cl, s) { /*----- PROTECTED REGION ID(Starter::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // Starter::constructor_2 } //-------------------------------------------------------- Starter::Starter(Tango::DeviceClass *cl, const char *s, const char *d) : TANGO_BASE_CLASS(cl, s, d) { /*----- PROTECTED REGION ID(Starter::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // Starter::constructor_3 } //-------------------------------------------------------- /** * Method : Starter::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void Starter::delete_device() { DEBUG_STREAM << "Starter::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(Starter::delete_device) ENABLED START -----*/ // Check if shutting down (or Init command) if (Tango::Util::instance()->is_svr_shutting_down() || Tango::Util::instance()->is_device_restarting(get_name())) { util->log_starter_info("Starter shutdown"); // Stop ping threads vector::iterator it; for (it=servers.begin() ; itthread_data->set_stop_thread(); util->proc_util->stop_it(); for (it=servers.begin() ; itthread->join(NULL); util->proc_util->join(NULL); // Delete device allocated objects delete dbase; delete util; delete[] attr_HostState_read; delete[] attr_NotifdState_read; delete start_proc_data; } /*----- PROTECTED REGION END -----*/ // Starter::delete_device } //-------------------------------------------------------- /** * Method : Starter::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void Starter::init_device() { DEBUG_STREAM << "Starter::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(Starter::init_device_before) ENABLED START -----*/ // Initialization before get_device_property() call cout << "Starter::Starter() init device " << device_name << endl; /*----- PROTECTED REGION END -----*/ // Starter::init_device_before // Get the device properties from database get_device_property(); /*----- PROTECTED REGION ID(Starter::init_device) ENABLED START -----*/ debug = false; char *dbg = (char *)getenv("DEBUG"); if (dbg!=NULL) if (strcmp(dbg, "true")==0) { debug = true; cout << "!!! Debug mode is set !!!" << endl; } if (serverStartupTimeoutis_svr_starting() || Tango::Util::instance()->is_device_restarting(get_name())) { // Get database server name //-------------------------------------- Tango::Util *tg = Tango::Util::instance(); char *dbname = tg->get_database()->get_dbase()->name(); // And connect database as DeviceProxy //-------------------------------------- dbase = new Tango::DeviceProxy(dbname); CORBA::string_free(dbname); // Build a shared data for StartProcessShared start_proc_data = new StartProcessShared(); // Get hostname (In case of cluster host could be multiple) //------------------------------------------------------------- vector hosts_list; char *env = (char *)getenv("TANGO_CLUSTER"); if (env==NULL) hosts_list.push_back(tg->get_host_name()); else if (strlen(env)==0) hosts_list.push_back(tg->get_host_name()); else { // If MULTI_HOST is defined, parse host names //-------------------------------------------------- string str_list(env); cout << "hosts_list = " << str_list << endl; int start = 0; int end = 0; while ((end=str_list.find_first_of(":", start))>0) { string s = str_list.substr(start, end-start); hosts_list.push_back(s); start = end+1; } string s = str_list.substr(start, str_list.length()-start); hosts_list.push_back(s); for (unsigned int i=0 ; ilog_starter_info("Starter startup"); // Initialize Attribute data member attr_HostState_read = new Tango::DevShort[1]; attr_NotifdState_read = new Tango::DevState[1]; attr_NotifdState_read[0] = notifyd_state = Tango::UNKNOWN; // Do not want exception during startup throwable = false; // Wait a bit if necessary if (waitForDriverStartup>0) { cout << "Waiting " << waitForDriverStartup << " seconds before starting (wait for drivers)." << endl; ms_sleep(1000*waitForDriverStartup); } // Start notify daemon if not desabled and not already running if (useEvents) { try { cout << "Checking " << util->notifyd_name << endl; if (util->is_notifyd_alive()!=Tango::ON) { string name(NOTIFY_DAEMON_SCRIPT); name += "/"; name += tg->get_host_name(); cout << "Starting " << name << endl; dev_start((char*)name.c_str()); } } catch (...) {} } // query database for controlled objects // Wait for Database device is OK bool done = false; while (!done) { try { util->build_server_ctrl_object(&servers); do_update_from_db = false; done = true; } catch(Tango::DevFailed &e) { Tango::Except::print_exception(e); } # ifdef _TG_WINDOWS_ _sleep(1000); # else sleep(1); # endif } // A a wait for first ping timeout !!!! # ifdef _TG_WINDOWS_ _sleep(3000); # else sleep(3); # endif // And Start servers for all startup levels. // The interStartupLevelWait value will be managed // by the start process thread. //--------------------------------------------------- int nb_levels = ((static_cast(get_device_class()))->nbStartupLevels); if (startServersAtStartup==true) { // Update state before for (unsigned int i=0 ; istate = server->thread_data->get_state(); } // And then starl-c16-1 (ZMQ)t levels for (int level=1 ; level<=nb_levels ; level++) { throwable = false; try { dev_start_all(level); } catch (Tango::DevFailed &e) { cerr << e.errors[0].desc << endl; } ms_sleep(50); } } // Want exception during normal run throwable = true; // Set the default state //------------------------------- set_state(Tango::MOVING); *attr_HostState_read = get_state(); check_log_dir(); // Update Loggs WARN_STREAM << "Starter Server Started !" << endl; } /*----- PROTECTED REGION END -----*/ // Starter::init_device } //-------------------------------------------------------- /** * Method : Starter::get_device_property() * Description : Read database to initialize property data members. */ //-------------------------------------------------------- void Starter::get_device_property() { /*----- PROTECTED REGION ID(Starter::get_device_property_before) ENABLED START -----*/ // Initialize property data members fireFromDbase = true; /*----- PROTECTED REGION END -----*/ // Starter::get_device_property_before // Read device properties from database. Tango::DbData dev_prop; dev_prop.push_back(Tango::DbDatum("AutoRestartDuration")); dev_prop.push_back(Tango::DbDatum("InterStartupLevelWait")); dev_prop.push_back(Tango::DbDatum("KeepLogFiles")); dev_prop.push_back(Tango::DbDatum("LogFileHome")); dev_prop.push_back(Tango::DbDatum("ServerStartupTimeout")); dev_prop.push_back(Tango::DbDatum("StartDsPath")); dev_prop.push_back(Tango::DbDatum("StartServersAtStartup")); dev_prop.push_back(Tango::DbDatum("UseEvents")); dev_prop.push_back(Tango::DbDatum("WaitForDriverStartup")); // is there at least one property to be read ? if (dev_prop.size()>0) { // Call database and extract values if (Tango::Util::instance()->_UseDb==true) get_db_device()->get_property(dev_prop); // get instance on StarterClass to get class property Tango::DbDatum def_prop, cl_prop; StarterClass *ds_class = (static_cast(get_device_class())); int i = -1; // Try to initialize AutoRestartDuration from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> autoRestartDuration; else { // Try to initialize AutoRestartDuration from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> autoRestartDuration; } // And try to extract AutoRestartDuration value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> autoRestartDuration; // Try to initialize InterStartupLevelWait from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> interStartupLevelWait; else { // Try to initialize InterStartupLevelWait from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> interStartupLevelWait; } // And try to extract InterStartupLevelWait value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> interStartupLevelWait; // Try to initialize KeepLogFiles from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> keepLogFiles; else { // Try to initialize KeepLogFiles from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> keepLogFiles; } // And try to extract KeepLogFiles value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> keepLogFiles; // Try to initialize LogFileHome from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> logFileHome; else { // Try to initialize LogFileHome from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> logFileHome; } // And try to extract LogFileHome value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> logFileHome; // Try to initialize ServerStartupTimeout from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> serverStartupTimeout; else { // Try to initialize ServerStartupTimeout from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> serverStartupTimeout; } // And try to extract ServerStartupTimeout value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> serverStartupTimeout; // Try to initialize StartDsPath from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> startDsPath; else { // Try to initialize StartDsPath from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> startDsPath; } // And try to extract StartDsPath value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> startDsPath; // Try to initialize StartServersAtStartup from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> startServersAtStartup; else { // Try to initialize StartServersAtStartup from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> startServersAtStartup; } // And try to extract StartServersAtStartup value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> startServersAtStartup; // Try to initialize UseEvents from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> useEvents; else { // Try to initialize UseEvents from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> useEvents; } // And try to extract UseEvents value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> useEvents; // Try to initialize WaitForDriverStartup from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> waitForDriverStartup; else { // Try to initialize WaitForDriverStartup from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> waitForDriverStartup; } // And try to extract WaitForDriverStartup value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> waitForDriverStartup; } /*----- PROTECTED REGION ID(Starter::get_device_property_after) ENABLED START -----*/ // Check device property data members init if (startDsPath.empty()) startDsPath.push_back("."); else for (unsigned int i=0 ; iget_database()->get_property("Default", data); string tmp; if (data[0].is_empty()==false) data[0] >> tmp; transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); if (tmp=="false") fireFromDbase = false; cout << "fireFromDbase = " << fireFromDbase << endl; cout << "logFileHome = " << logFileHome << endl; cout << "StartServersAtStartup = " << startServersAtStartup << endl; cout << "AutoRestartDuration = " << autoRestartDuration << endl; /*----- PROTECTED REGION END -----*/ // Starter::get_device_property_after } //-------------------------------------------------------- /** * Method : Starter::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void Starter::always_executed_hook() { DEBUG_STREAM << "Starter::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(Starter::always_executed_hook) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::always_executed_hook } //-------------------------------------------------------- /** * Method : Starter::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void Starter::read_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "Starter::read_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(Starter::read_attr_hardware) ENABLED START -----*/ // Update if Servers attribute (polled) is called. for (unsigned int i=0 ; i < attr_list.size() ; i++) { Tango::WAttribute &att = dev_attr->get_w_attr_by_ind(attr_list[i]); string attr_name = att.get_name(); if (attr_name == "Servers") for (unsigned int j=0 ; jget_state(); // Check if state has changed. if (previous_state!=servers[j].state) manage_changing_state(&servers[j], previous_state); //cout << "read_attr_hardware:[" << servers[j].name << "] " << // Tango::DevStateName[servers[j].state] << endl; } } /*----- PROTECTED REGION END -----*/ // Starter::read_attr_hardware } //-------------------------------------------------------- /** * Read attribute NotifdState related method * Description: return ON or FAULT if notify daemon is running or not. * * Data type: Tango::DevState * Attr type: Scalar */ //-------------------------------------------------------- void Starter::read_NotifdState(Tango::Attribute &attr) { DEBUG_STREAM << "Starter::read_NotifdState(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(Starter::read_NotifdState) ENABLED START -----*/ // Set the attribute value attr_NotifdState_read[0] = notifyd_state; attr.set_value(attr_NotifdState_read); /*----- PROTECTED REGION END -----*/ // Starter::read_NotifdState } //-------------------------------------------------------- /** * Read attribute HostState related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void Starter::read_HostState(Tango::Attribute &attr) { DEBUG_STREAM << "Starter::read_HostState(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(Starter::read_HostState) ENABLED START -----*/ // Set the attribute value *attr_HostState_read = (short) get_state(); DEBUG_STREAM << "HostState = " << attr_HostState_read[0] << endl; attr.set_value(attr_HostState_read); /*----- PROTECTED REGION END -----*/ // Starter::read_HostState } //-------------------------------------------------------- /** * Read attribute RunningServers related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 200 */ //-------------------------------------------------------- void Starter::read_RunningServers(Tango::Attribute &attr) { DEBUG_STREAM << "Starter::read_RunningServers(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(Starter::read_RunningServers) ENABLED START -----*/ // Check running ones vector runnings; for (unsigned int i=0 ; i stopped; for (unsigned int i=0 ; i vs; for (unsigned int i=0 ; idevice_state data member) and returns it to the caller. * * @returns State Code */ //-------------------------------------------------------- Tango::DevState Starter::dev_state() { DEBUG_STREAM << "Starter::State() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_state) ENABLED START -----*/ Tango::DevState argout = DeviceImpl::dev_state(); // Add your own state management // Check if last command is more than readInfoDbPeriod class property int period = ((static_cast(get_device_class()))->readInfoDbPeriod); // If not fired -> do it myself by polling //--------------------------------------------- if (fireFromDbase==false) { static time_t t0 = 0; time_t t1 = time(NULL); // If less -> no update if (t1-t0 >= period) { t0 = t1; // Update control obj from database (could have been modified) INFO_STREAM << "Updating from data base" << endl; util->build_server_ctrl_object(&servers); } } else if (do_update_from_db) { // Has been fired from Dbase util->build_server_ctrl_object(&servers); do_update_from_db = false; } // Check for notify daemon state if requested //--------------------------------------------- if (useEvents) notifyd_state = util->is_notifyd_alive(); else notifyd_state = Tango::ON; // Check if servers object initilized //--------------------------------------- if (servers.empty()) { INFO_STREAM << "Exiting dev_state() with servers.size() null" << endl; if (notifyd_state==Tango::ON) argout = Tango::ON; else argout = Tango::ALARM; } else { // Check hown many servers are running //----------------------------------------------------------- ControlledServer *p_serv; int nb_running = 0; int nb_controlled = 0; int nb_starting = 0; int nb_stopped = 0; for (unsigned int i=0 ; icontrolled) { nb_controlled++; // Fixe witch one is running and count how many controlled are running if ((p_serv->state==Tango::ON)) nb_running++; else if (p_serv->state==Tango::MOVING) nb_starting++; else nb_stopped++; } } // compare nb running with nb_controlled to set state if (nb_starting>0 || start_proc_data->get_starting_processes()>0) argout = Tango::MOVING; else if (nb_running==nb_controlled && notifyd_state==Tango::ON) argout = Tango::ON; else if (nb_stopped==nb_controlled) argout = Tango::OFF; else argout = Tango::ALARM; } if (argout==Tango::ON) { set_status("All controlled servers are running"); } else if (argout==Tango::ALARM) { set_status("At least one of the controlled servers is not running"); } else if (argout==Tango::OFF) { set_status("All controlled servers are not running"); } else if (argout==Tango::MOVING) { set_status("At least one of the controlled servers is running but not responding"); } else set_status("Starter state is unknown..."); /*----- PROTECTED REGION END -----*/ // Starter::dev_state set_state(argout); // Give the state to Tango. if (argout!=Tango::ALARM) DeviceImpl::dev_state(); return get_state(); // Return it after Tango management. } //-------------------------------------------------------- /** * Command DevStart related method * Description: Start the specified server. * * @param argin Server to be started. */ //-------------------------------------------------------- void Starter::dev_start(Tango::DevString argin) { DEBUG_STREAM << "Starter::DevStart() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_start) ENABLED START -----*/ // Add your own code try { NewProcess *np = processCouldStart(argin); if (np==NULL) return; // Build a vector to start process vector processes; processes.push_back(np); startProcesses(processes, 0); // Started with starter -> stopped switched to false. string servname(argin); ControlledServer *server = util->get_server_by_name(servname, servers); if (server!=NULL) { server->stopped = false; server->started_time = time(NULL); } } catch (Tango::DevFailed &) { throw; } catch (exception &e) { cerr << "================================" << endl; cerr << e.what() << endl; cerr << "================================" << endl; TangoSys_OMemStream tms; tms << "Starting process failed: " << e.what(); Tango::Except::throw_exception( (const char *)"START_PROCASS_FAILDE", tms.str().c_str(), (const char *)"Starter::dev_start()"); } catch (...) { cerr << "================================" << endl << " Unknown exception catched" << endl << "================================" << endl; Tango::Except::throw_exception( (const char *)"START_PROCASS_FAILDE", (const char *)"Starting process failed: Unknown exception catched", (const char *)"Starter::dev_start()"); } /*----- PROTECTED REGION END -----*/ // Starter::dev_start } //-------------------------------------------------------- /** * Command DevStop related method * Description: Stop the specified server. * * @param argin Server be stopped. */ //-------------------------------------------------------- void Starter::dev_stop(Tango::DevString argin) { DEBUG_STREAM << "Starter::DevStop() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_stop) ENABLED START -----*/ // Add your own code // Check if servers object initilized //--------------------------------------- if (servers.empty()) { TangoSys_OMemStream out_stream; out_stream << argin << ": Server not controlled !" << ends; Tango::Except::throw_exception(out_stream.str(), out_stream.str(), (const char *)"Starter::dev_stop()"); return; } // Check Argin as server name //---------------------------------- string name(argin); ControlledServer *server = util->get_server_by_name(name, servers); if (server==NULL) { TangoSys_OMemStream out_stream; out_stream << argin << ": Unknown Server !" << ends; Tango::Except::throw_exception(out_stream.str(), out_stream.str(), (const char *)"Starter::dev_stop()"); return; } // Make shure that it's running. //--------------------------------------- if (server->state==Tango::ON) { // And Kill it with kill signal Tango::DeviceProxy *dev = NULL; try { dev = new Tango::DeviceProxy(server->admin_name); dev->command_inout("Kill"); delete dev; } catch (Tango::DevFailed &e) { if (dev!=NULL) delete dev; throw e; } TangoSys_OMemStream out_stream; out_stream << argin << " stopped"; WARN_STREAM << out_stream.str() << endl; cout << out_stream.str() << endl; util->log_starter_info(out_stream.str()); server->stopped = true; } else if (server->state==Tango::MOVING) { TangoSys_OMemStream out_stream; out_stream << argin << " is running but not responding !" << ends; Tango::Except::throw_exception( (const char *)"SERVER_NOT_RESPONDING", out_stream.str(), (const char *)"Starter::dev_stop()"); return; } else { TangoSys_OMemStream out_stream; out_stream << argin << " is NOT running !" << ends; Tango::Except::throw_exception( (const char *)"SERVER_NOT_RUNNING", out_stream.str(), (const char *)"Starter::dev_stop()"); return; } /*----- PROTECTED REGION END -----*/ // Starter::dev_stop } //-------------------------------------------------------- /** * Command DevStartAll related method * Description: Start all device servers controled on the host for the argin level. * * @param argin Startup level. */ //-------------------------------------------------------- void Starter::dev_start_all(Tango::DevShort argin) { DEBUG_STREAM << "Starter::DevStartAll() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_start_all) ENABLED START -----*/ // Add your own code Tango::DevShort level = argin; cout << "Starter::dev_start_all(): entering for level "<< level <<"... !" << endl; // Check if servers object initialized //--------------------------------------- if (servers.empty()) { if (throwable) { TangoSys_OMemStream out_stream; out_stream << "NO Server controlled !" << ends; Tango::Except::throw_exception(out_stream.str(), out_stream.str(), (const char *)"Starter::dev_start_all()"); } } // Do not want exception during start up throwable = false; // And start the stopped ones //--------------------------------------------------- vector processes; for (unsigned int i=0 ; irunning could not be initialized if (server->controlled && server->startup_level==level) { cout << "Check startup for " << server->name << endl; if (server->state==Tango::FAULT) { NewProcess *np = processCouldStart((char*)server->name.c_str()); if (np!=NULL) { processes.push_back(np); cout << "Try to start " << np->servname << endl; } else cout << "np is null (?)" << endl; } else cout << " Already running...."<< endl; } } if (processes.empty()==false) startProcesses(processes, level); // Want exception during normal run throwable = true; /*----- PROTECTED REGION END -----*/ // Starter::dev_start_all } //-------------------------------------------------------- /** * Command DevStopAll related method * Description: Stop all device servers controled on the host for the argin level. * * @param argin Startup Level. */ //-------------------------------------------------------- void Starter::dev_stop_all(Tango::DevShort argin) { DEBUG_STREAM << "Starter::DevStopAll() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_stop_all) ENABLED START -----*/ // Add your own code Tango::DevShort level = argin; // Check if servers object initialized if (servers.empty()) { TangoSys_OMemStream out_stream; out_stream << "NO Server controlled !" << ends; Tango::Except::throw_exception(out_stream.str(), out_stream.str(), (const char *)"Starter::dev_stop_all()"); return; } // Remove level from list to be started cout << "Starter removing level " << level << endl; start_proc_data->remove_level(level); // And stop the running ones for (unsigned int i=0 ; icontrolled && server->startup_level==level && server->state==Tango::ON) dev_stop((char*)server->name.c_str()); } /*----- PROTECTED REGION END -----*/ // Starter::dev_stop_all } //-------------------------------------------------------- /** * Command DevGetRunningServers related method * Description: Control the running process from property list. * And return the list of the processes which are really running. * * @param argin True for all servers. False for controled servers only. * @returns List of the processes which are running. */ //-------------------------------------------------------- Tango::DevVarStringArray *Starter::dev_get_running_servers(Tango::DevBoolean argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "Starter::DevGetRunningServers() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_get_running_servers) ENABLED START -----*/ // Add your own code Tango::DevBoolean all_serv = argin; argout = new Tango::DevVarStringArray; INFO_STREAM << "Starter::dev_get_running_server(): entering... !" << endl; // Check if servers object initilized //--------------------------------------- if (servers.empty()) { return argout; } // prepare the argout for running servers list //----------------------------------------------------------- int nb = 0; int x; unsigned int i; for (i=0 ; ilength(nb); for (i=0, x=0 ; ilength(0); return argout; } // prepeare the argout for NOT running servers list //----------------------------------------------------------- int nb = 0; int x; unsigned int i; for (i=0 ; ilength(nb); for (i=0, x=0 ; i return Starter logg file content. * If argin ==``Statistics`` -> return Starter statistics file content. * @returns String found in log file. */ //-------------------------------------------------------- Tango::ConstDevString Starter::dev_read_log(Tango::DevString argin) { Tango::ConstDevString argout; DEBUG_STREAM << "Starter::DevReadLog() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::dev_read_log) ENABLED START -----*/ // Add your own code string filename; bool on_starter; // Check if for Starter itself if (strcmp(argin, "Starter")==0) { on_starter = true; filename = util->starter_log_file; } else if (strcmp(argin, "Statistics")==0) { on_starter = true; filename = util->starter_stat_file; } else { on_starter = false; filename = util->build_log_file_name(argin); } // Try to open log file ifstream ifs((char *)filename.c_str()); if (!ifs) { // Open log file failed -> Throw exception //---------------------------------------------- TangoSys_OMemStream reason; TangoSys_OMemStream description; reason << "Cannot open " << filename << ends; description << strerror(errno); Tango::Except::throw_exception(reason.str(), description.str(), (const char *)"Starter::dev_read_log"); } // Read and close log file, and return string read from it. //------------------------------------------------------------- stringstream strlog; if (!on_starter) { strlog << filename << endl; strlog << util->get_file_date((char *)filename.c_str()) << endl << endl; } strlog << ifs.rdbuf() << ends; ifs.close(); returned_str = strlog.str(); argout = returned_str.c_str(); /*----- PROTECTED REGION END -----*/ // Starter::dev_read_log return argout; } //-------------------------------------------------------- /** * Command HardKillServer related method * Description: Hard kill a server (kill -9) * * @param argin Server name */ //-------------------------------------------------------- void Starter::hard_kill_server(Tango::DevString argin) { DEBUG_STREAM << "Starter::HardKillServer() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::hard_kill_server) ENABLED START -----*/ // Add your own code string servname(argin); int pid = util->proc_util->get_server_pid(servname); if (pid<0) { TangoSys_OMemStream tms; tms << "Server " << argin << " is not running !"; Tango::Except::throw_exception( (const char *)"SERVER_NOT_RUNNING", tms.str().c_str(), (const char *)"Starter::hard_kill_server()"); } #ifdef _TG_WINDOWS_ HANDLE handle = NULL; //- process addr (in the heap) if( (handle=OpenProcess(PROCESS_TERMINATE, false, pid)) == NULL) { TangoSys_OMemStream tms; tms << "Open handle on server " << argin << " failed !"; Tango::Except::throw_exception( (const char *)"KILL_DERVER_FAILED", tms.str().c_str(), (const char *)"Starter::hard_kill_server()"); } TerminateProcess(handle, 0); CloseHandle(handle); if (GetLastError()!= ERROR_SUCCESS) { TangoSys_OMemStream tms; tms << "Kill server " << argin << " failed !"; Tango::Except::throw_exception( (const char *)"KILL_DERVER_FAILED", tms.str().c_str(), (const char *)"Starter::hard_kill_server()"); } #else TangoSys_OMemStream cmd; cmd << "kill -9 " << pid; if (system(cmd.str().c_str())<0) { TangoSys_OMemStream tms; tms << "Kill server " << argin << " failed !"; Tango::Except::throw_exception( (const char *)"KILL_DERVER_FAILED", tms.str().c_str(), (const char *)"Starter::hard_kill_server()"); } #endif /*----- PROTECTED REGION END -----*/ // Starter::hard_kill_server } //-------------------------------------------------------- /** * Command NotifyDaemonState related method * Description: Returns the Notify Daemon state. * * @returns Tango::ON if Notify daemon is running else Tango::FAULT. */ //-------------------------------------------------------- Tango::DevState Starter::notify_daemon_state() { Tango::DevState argout; DEBUG_STREAM << "Starter::NotifyDaemonState() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::notify_daemon_state) ENABLED START -----*/ // Add your own code if (useEvents==false) Tango::Except::throw_exception( (const char *)"NOTIFY_NOT_AVAILABLE", (const char *)"Notify Daemon control is disabled", (const char *)"Starter::notify_daemon_state()"); argout = notifyd_state; /*----- PROTECTED REGION END -----*/ // Starter::notify_daemon_state return argout; } //-------------------------------------------------------- /** * Command ResetStatistics related method * Description: Reset statistics file. * */ //-------------------------------------------------------- void Starter::reset_statistics() { DEBUG_STREAM << "Starter::ResetStatistics() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::reset_statistics) ENABLED START -----*/ // Add your own code util->reset_starter_stat_file(&servers);; /*----- PROTECTED REGION END -----*/ // Starter::reset_statistics } //-------------------------------------------------------- /** * Command UpdateServersInfo related method * Description: Indicate to the device server than the information about servers to be controlled has been modified. * The device server must read the database to update the servers info list. * If the default case, this command is sent by Database server itself. * */ //-------------------------------------------------------- void Starter::update_servers_info() { DEBUG_STREAM << "Starter::UpdateServersInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(Starter::update_servers_info) ENABLED START -----*/ // Add your own code do_update_from_db = true; /*----- PROTECTED REGION END -----*/ // Starter::update_servers_info } /*----- PROTECTED REGION ID(Starter::namespace_ending) ENABLED START -----*/ // Additional Methods //+------------------------------------------------------------------ /** * Check if a process could be started (file exists, is not running, ...) */ //+------------------------------------------------------------------ NewProcess *Starter::processCouldStart(char *argin) { INFO_STREAM << "Starter::processCouldStart(\""<< argin << "\"): entering... !" << endl; // Make sure that it's not running. //--------------------------------------- if (servers.empty()==false) { string name(argin); ControlledServer *server = util->get_server_by_name(name, servers); if (server!=NULL) if (server->state!=Tango::FAULT) { INFO_STREAM << argin << " is already running !" <get_server_name(argin) ; char *instancename = util->get_instance_name(argin); char *adminname = new char[strlen(servname)+ strlen(instancename)+10]; sprintf(adminname, "dserver/%s/%s", servname, instancename); char *filename; try { filename = util->check_exe_file(servname, startDsPath); } catch(Tango::DevFailed &e) { delete[] servname; delete[] instancename; delete[] adminname; if (throwable) throw; else { cerr << e.errors[0].desc << endl; return NULL; } } delete[] servname; check_log_dir(); string log_file = util->build_log_file_name(argin); NewProcess *np = new NewProcess; np->servname = filename; np->instancename = instancename; np->adminname = adminname; np->logfile = new char[log_file.length()+1]; np->logfile = strcpy(np->logfile, log_file.c_str()); INFO_STREAM << "LOG file : " << log_file << endl; return np; } //+------------------------------------------------------------------ //+------------------------------------------------------------------ void Starter::startProcesses(vector v_np, int level) { // Start process to start processes //------------------------------------- try { start_proc_data->push_back_level(level); StartProcessThread *pt = new StartProcessThread(v_np, level, this); pt->start(); } catch(omni_thread_fatal &e) { TangoSys_OMemStream tms; tms << "Starting process thread failed: " << e.error; Tango::Except::throw_exception( (const char *)"THREAD_FAILDE", tms.str().c_str(), (const char *)"Starter::startProcesses()"); } catch(omni_thread_invalid &e) { TangoSys_OMemStream tms; tms << "Starting process thread failed: omni_thread_invalid"; Tango::Except::throw_exception( (const char *)"THREAD_FAILDE", tms.str().c_str(), (const char *)"Starter::startProcesses()"); } catch(...) { TangoSys_OMemStream tms; tms << "Starting process thread failed"; Tango::Except::throw_exception( (const char *)"THREAD_FAILDE", tms.str().c_str(), (const char *)"Starter::startProcesses()"); } } //+------------------------------------------------------------------ /** * Return how many servers to start for specified level. */ //+------------------------------------------------------------------ int Starter::nb_servers_to_start(int level) { int cnt = 0; for (unsigned int i=0 ; irunning could not be initialized if (server->controlled && server->startup_level==level) if (server->state!=Tango::ON) cnt++; } return cnt; } //================================================================= //================================================================= void Starter::check_host() { string hostname = Tango::Util::instance()->get_host_name(); transform(hostname.begin(), hostname.end(), hostname.begin(), ::tolower); // remove FQDN string::size_type pos = hostname.find('.'); if (pos!=string::npos) hostname = hostname.substr(0, pos); string devname = device_name; transform(devname.begin(), devname.end(), devname.begin(), ::tolower); // Get only member pos = devname.find('/'); if (pos!=string::npos) { pos = devname.find('/', pos+1); if (pos!=string::npos) devname = devname.substr(pos+1); } //cout << hostname << " == " << devname << endl; if (devname != hostname) { TangoSys_OMemStream tms; tms << "This server must run on " << devname << " and not on " << hostname; string descr(tms.str()); Tango::Except::throw_exception( (const char *)"BAD_PARAM", (const char *) descr.c_str(), (const char *)"Starter::check_host()"); } } //================================================================= //================================================================= void Starter::check_log_dir() { // Check if log dir already exists. //------------------------------------- string logpath; LogPath(logpath,logFileHome); if (chdir(logpath.c_str())==-1) { if (errno==ENOENT) { // Create directory //------------------------- cerr << "ENOENT" << endl; cerr << errno << " " << strerror(errno) << endl; #ifdef _TG_WINDOWS_ mkdir(TmpRoot); int r = mkdir(logpath.c_str()); #else # ifdef linux int r = mkdir(logpath.c_str(), (mode_t)(0775) ); # else int r = mkdir(logpath.c_str(), (mode_t)(O_RDWR | O_CREAT, 0775) ); # endif #endif if (r<0) { TangoSys_OMemStream message; message << "Cannot create error log directory:\n"; message << logpath; message << "\n" << strerror(errno) << endl; cerr << message.str() << endl;; set_status(message.str()); Tango::Except::throw_exception( (const char *)"CANNOT_CREATE_LOG_FILE", message.str(), (const char *)"Starter::dev_start"); } else { TangoSys_OMemStream tms; tms << logpath << " Created !" << endl; INFO_STREAM << tms.str() << endl; set_status(tms.str()); } } else { TangoSys_OMemStream tms; tms << "Cannot change to log directory:\n"; tms << logpath; tms << "\n" << strerror(errno) << endl; cerr << tms.str() << endl;; set_status(tms.str()); } } } //================================================================= //================================================================= void Starter::manage_changing_state(ControlledServer *server, TANGO_UNUSED(Tango::DevState previous_state)) { // Do it only if server is controlled. if (server->controlled==false || server->startup_level==0) return; Tango::DevState state = server->state; //cout << "manage_changing_state:[" << server->name << "] " << // Tango::DevStateName[previous_state] << " --> " << Tango::DevStateName[state] << endl; switch(state) { case Tango::ON: server->started_time = time(NULL); // Log statistics util->log_starter_statistics(server); if (server->failure_time>0) { cout << "Failure duration: " << (server->started_time-server->failure_time) << " sec." << endl; server->failure_time = -1; } break; case Tango::FAULT: if (server->stopped==false) // Has failed { server->failure_time = time(NULL); // Log statistics util->log_starter_statistics(server); // Check auto restart if (autoRestartDuration>0) { int minDuration = autoRestartDuration; if (debug==false) minDuration *= 60; // minutes to seconds int runDuration = server->failure_time - server->started_time; cout << "Has run " << runDuration << " sec. (> " << minDuration << " ?)" << endl; if (runDuration>minDuration) { try { // Restart it cout << " YES: Restart it !!" << endl; server->auto_start = true; dev_start((char *)server->name.c_str()); } catch(Tango::DevFailed &e) { Tango::Except::print_exception(e); } } } } break; default: // Do nothing break; } } /*----- PROTECTED REGION END -----*/ // Starter::namespace_ending } // namespace tango-9.2.5a/cppserver/starter/StarterClass.cpp0000644023471100065110000012515513034745014016553 00000000000000/*----- PROTECTED REGION ID(StarterClass.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: StarterClass.cpp 29529 2016-03-22 10:36:16Z pascal_verdier $"; static const char *TagName = "$Name: Starter-Release-6.9 $"; static const char *CvsPath = "$Source: $"; static const char *SvnPath = "$HeadURL: https://tango-cs.svn.sourceforge.net/svnroot/tango-cs/classes/cpp/starter $"; static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; //============================================================================= // // file : StarterClass.cpp // // description : C++ source for the StarterClass. A singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the �name� once per process. // // project : Starter for Tango Administration. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 29529 $ // $Date: 2016-03-22 11:36:16 +0100 (Tue, 22 Mar 2016) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include /*----- PROTECTED REGION END -----*/ // StarterClass.cpp //------------------------------------------------------------------- /** * Create StarterClass singleton and * return it in a C function for Python usage */ //------------------------------------------------------------------- extern "C" { #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif Tango::DeviceClass *_create_Starter_class(const char *name) { return Starter_ns::StarterClass::init(name); } } namespace Starter_ns { //=================================================================== // Initialize pointer for singleton pattern //=================================================================== StarterClass *StarterClass::_instance = NULL; //-------------------------------------------------------- /** * method : StarterClass::StarterClass(string &s) * description : constructor for the StarterClass * * @param s The class name */ //-------------------------------------------------------- StarterClass::StarterClass(string &s):Tango::DeviceClass(s) { cout2 << "Entering StarterClass constructor" << endl; set_default_property(); get_class_property(); write_class_property(); /*----- PROTECTED REGION ID(StarterClass::constructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::constructor cout2 << "Leaving StarterClass constructor" << endl; } //-------------------------------------------------------- /** * method : StarterClass::~StarterClass() * description : destructor for the StarterClass */ //-------------------------------------------------------- StarterClass::~StarterClass() { /*----- PROTECTED REGION ID(StarterClass::destructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::destructor _instance = NULL; } //-------------------------------------------------------- /** * method : StarterClass::init * description : Create the object if not already done. * Otherwise, just return a pointer to the object * * @param name The class name */ //-------------------------------------------------------- StarterClass *StarterClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new StarterClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //-------------------------------------------------------- /** * method : StarterClass::instance * description : Check if object already created, * and return a pointer to the object */ //-------------------------------------------------------- StarterClass *StarterClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //=================================================================== // Command execution method calls //=================================================================== //-------------------------------------------------------- /** * method : DevStartClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevStartClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevStartClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->dev_start(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DevStopClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevStopClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevStopClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->dev_stop(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DevStartAllClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevStartAllClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevStartAllClass::execute(): arrived" << endl; Tango::DevShort argin; extract(in_any, argin); ((static_cast(device))->dev_start_all(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DevStopAllClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevStopAllClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevStopAllClass::execute(): arrived" << endl; Tango::DevShort argin; extract(in_any, argin); ((static_cast(device))->dev_stop_all(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DevGetRunningServersClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevGetRunningServersClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevGetRunningServersClass::execute(): arrived" << endl; Tango::DevBoolean argin; extract(in_any, argin); return insert((static_cast(device))->dev_get_running_servers(argin)); } //-------------------------------------------------------- /** * method : DevGetStopServersClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevGetStopServersClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevGetStopServersClass::execute(): arrived" << endl; Tango::DevBoolean argin; extract(in_any, argin); return insert((static_cast(device))->dev_get_stop_servers(argin)); } //-------------------------------------------------------- /** * method : DevReadLogClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevReadLogClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevReadLogClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->dev_read_log(argin)); } //-------------------------------------------------------- /** * method : HardKillServerClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *HardKillServerClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "HardKillServerClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->hard_kill_server(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : NotifyDaemonStateClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *NotifyDaemonStateClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "NotifyDaemonStateClass::execute(): arrived" << endl; return insert((static_cast(device))->notify_daemon_state()); } //-------------------------------------------------------- /** * method : ResetStatisticsClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "ResetStatisticsClass::execute(): arrived" << endl; ((static_cast(device))->reset_statistics()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : UpdateServersInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *UpdateServersInfoClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "UpdateServersInfoClass::execute(): arrived" << endl; ((static_cast(device))->update_servers_info()); return new CORBA::Any(); } //=================================================================== // Properties management //=================================================================== //-------------------------------------------------------- /** * Method : StarterClass::get_class_property() * Description : Get the class property for specified name. */ //-------------------------------------------------------- Tango::DbDatum StarterClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; i_UseDb==true) get_db_class()->get_property(cl_prop); Tango::DbDatum def_prop; int i = -1; // Try to extract AutoRestartDuration value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> autoRestartDuration; else { // Check default value for AutoRestartDuration def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> autoRestartDuration; cl_prop[i] << autoRestartDuration; } } // Try to extract LogFileHome value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> logFileHome; else { // Check default value for LogFileHome def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> logFileHome; cl_prop[i] << logFileHome; } } // Try to extract NbStartupLevels value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> nbStartupLevels; else { // Check default value for NbStartupLevels def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> nbStartupLevels; cl_prop[i] << nbStartupLevels; } } // Try to extract ReadInfoDbPeriod value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> readInfoDbPeriod; else { // Check default value for ReadInfoDbPeriod def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> readInfoDbPeriod; cl_prop[i] << readInfoDbPeriod; } } // Try to extract ServerStartupTimeout value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> serverStartupTimeout; else { // Check default value for ServerStartupTimeout def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> serverStartupTimeout; cl_prop[i] << serverStartupTimeout; } } // Try to extract StartServersAtStartup value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> startServersAtStartup; else { // Check default value for StartServersAtStartup def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> startServersAtStartup; cl_prop[i] << startServersAtStartup; } } // Try to extract UseEvents value if (cl_prop[++i].is_empty()==false) cl_prop[i] >> useEvents; else { // Check default value for UseEvents def_prop = get_default_class_property(cl_prop[i].name); if (def_prop.is_empty()==false) { def_prop >> useEvents; cl_prop[i] << useEvents; } } /*----- PROTECTED REGION ID(StarterClass::get_class_property_after) ENABLED START -----*/ // Check class property data members init cout2 << "readInfoDbPeriod = " << readInfoDbPeriod << endl; cout2 << "nbStartupLevels = " << nbStartupLevels << endl; cout2 << "useEvents = " << ((useEvents)? "True":"False") << endl; cout2 << "logFileHome = " << logFileHome << endl; // Put the value (depends on OS) in cl_prop to be set as default value for device property.. for (unsigned int i=0 ; i vect_data; // Set Default Class Properties prop_name = "AutoRestartDuration"; prop_desc = "If this property is greater than 0, if a server has been running more than the specified value (in minutes), and has failed, it will be restart automaticly."; prop_def = "0"; vect_data.clear(); vect_data.push_back("0"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "LogFileHome"; prop_desc = "The home directory to log servers traces.\nFor Linux the default value is /var/tmp\nFor Win32 it is c:\temp"; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "NbStartupLevels"; prop_desc = "Number of startup levels managed by starter."; prop_def = "5"; vect_data.clear(); vect_data.push_back("5"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "ReadInfoDbPeriod"; prop_desc = "Period to read database for new info if not fired from Database server."; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "ServerStartupTimeout"; prop_desc = "Timeout on device server startup in seconds."; prop_def = "1"; vect_data.clear(); vect_data.push_back("1"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "StartServersAtStartup"; prop_desc = "Skip starting servers at startup if false. It a way to do not have a big re-start of many servers after a power cut."; prop_def = "true"; vect_data.clear(); vect_data.push_back("true"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); prop_name = "UseEvents"; prop_desc = "Use events if not null."; prop_def = "0"; vect_data.clear(); vect_data.push_back("0"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; cl_def_prop.push_back(data); add_wiz_class_prop(prop_name, prop_desc, prop_def); } else add_wiz_class_prop(prop_name, prop_desc); // Set Default device Properties prop_name = "AutoRestartDuration"; prop_desc = "If this property is greater than 0, if a server has been running more than the specified value (in minutes), and has failed, it will be restart automaticly."; prop_def = "0"; vect_data.clear(); vect_data.push_back("0"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "InterStartupLevelWait"; prop_desc = "Time to wait before two startup levels in seconds."; prop_def = "1"; vect_data.clear(); vect_data.push_back("1"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "KeepLogFiles"; prop_desc = "Number of log file kept."; prop_def = "3"; vect_data.clear(); vect_data.push_back("3"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "LogFileHome"; prop_desc = "The home directory to log servers traces.\nFor Linux the default value is /var/tmp\nFor Win32 it is c:\temp"; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "ServerStartupTimeout"; prop_desc = "Timeout on device server startup in seconds."; prop_def = "5"; vect_data.clear(); vect_data.push_back("5"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "StartDsPath"; prop_desc = "Path to find executable files\nto start device servers"; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "StartServersAtStartup"; prop_desc = "Skip starting servers at startup if false."; prop_def = "true"; vect_data.clear(); vect_data.push_back("true"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "UseEvents"; prop_desc = "Use events if not null."; prop_def = "0"; vect_data.clear(); vect_data.push_back("0"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "WaitForDriverStartup"; prop_desc = "The Starter will wait a bit before starting servers, to be sure than the drivers\nare started.This time is in seconds."; prop_def = "0"; vect_data.clear(); vect_data.push_back("0"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); } //-------------------------------------------------------- /** * Method : StarterClass::write_class_property() * Description : Set class description fields as property in database */ //-------------------------------------------------------- void StarterClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("Starter for Tango Administration"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector str_desc; str_desc.push_back("This device server is able to control Tango components (database, device servers, clients...)."); str_desc.push_back("It is able to start or stop and to report the status of these components."); description << str_desc; data.push_back(description); // put cvs or svn location string filename("Starter"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector inheritance; inheritance.push_back("TANGO_BASE_CLASS"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); } //=================================================================== // Factory methods //=================================================================== //-------------------------------------------------------- /** * Method : StarterClass::device_factory() * Description : Create the device object(s) * and store them in the device list */ //-------------------------------------------------------- void StarterClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { /*----- PROTECTED REGION ID(StarterClass::device_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // StarterClass::device_factory_before // Create devices and add it into the device list for (unsigned long i=0 ; ilength() ; i++) { cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; device_list.push_back(new Starter(this, (*devlist_ptr)[i])); } // Manage dynamic attributes if any erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); // Export devices to the outside world for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) { // Add dynamic attributes if any Starter *dev = static_cast(device_list[device_list.size()-i]); dev->add_dynamic_attributes(); // Check before if database used. if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) export_device(dev); else export_device(dev, dev->get_name().c_str()); } /*----- PROTECTED REGION ID(StarterClass::device_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // StarterClass::device_factory_after } //-------------------------------------------------------- /** * Method : StarterClass::attribute_factory() * Description : Create the attribute object(s) * and store them in the attribute list */ //-------------------------------------------------------- void StarterClass::attribute_factory(vector &att_list) { /*----- PROTECTED REGION ID(StarterClass::attribute_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // StarterClass::attribute_factory_before // Attribute : NotifdState NotifdStateAttrib *notifdstate = new NotifdStateAttrib(); Tango::UserDefaultAttrProp notifdstate_prop; notifdstate_prop.set_description("return ON or FAULT if notify daemon is running or not."); notifdstate_prop.set_label("Notifd State"); // unit not set for NotifdState // standard_unit not set for NotifdState // display_unit not set for NotifdState // format not set for NotifdState // max_value not set for NotifdState // min_value not set for NotifdState // max_alarm not set for NotifdState // min_alarm not set for NotifdState // max_warning not set for NotifdState // min_warning not set for NotifdState // delta_t not set for NotifdState // delta_val not set for NotifdState notifdstate->set_default_properties(notifdstate_prop); notifdstate->set_polling_period(1000); notifdstate->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(notifdstate); // Attribute : HostState HostStateAttrib *hoststate = new HostStateAttrib(); Tango::UserDefaultAttrProp hoststate_prop; // description not set for HostState // label not set for HostState // unit not set for HostState // standard_unit not set for HostState // display_unit not set for HostState // format not set for HostState // max_value not set for HostState // min_value not set for HostState // max_alarm not set for HostState // min_alarm not set for HostState // max_warning not set for HostState // min_warning not set for HostState // delta_t not set for HostState // delta_val not set for HostState hoststate->set_default_properties(hoststate_prop); hoststate->set_polling_period(1000); hoststate->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(hoststate); // Attribute : RunningServers RunningServersAttrib *runningservers = new RunningServersAttrib(); Tango::UserDefaultAttrProp runningservers_prop; // description not set for RunningServers // label not set for RunningServers // unit not set for RunningServers // standard_unit not set for RunningServers // display_unit not set for RunningServers // format not set for RunningServers // max_value not set for RunningServers // min_value not set for RunningServers // max_alarm not set for RunningServers // min_alarm not set for RunningServers // max_warning not set for RunningServers // min_warning not set for RunningServers // delta_t not set for RunningServers // delta_val not set for RunningServers runningservers->set_default_properties(runningservers_prop); runningservers->set_polling_period(1000); runningservers->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(runningservers); // Attribute : StoppedServers StoppedServersAttrib *stoppedservers = new StoppedServersAttrib(); Tango::UserDefaultAttrProp stoppedservers_prop; stoppedservers_prop.set_description("Return all the Stopped servers.\n"); stoppedservers_prop.set_label("All Stopped Servers"); // unit not set for StoppedServers // standard_unit not set for StoppedServers // display_unit not set for StoppedServers // format not set for StoppedServers // max_value not set for StoppedServers // min_value not set for StoppedServers // max_alarm not set for StoppedServers // min_alarm not set for StoppedServers // max_warning not set for StoppedServers // min_warning not set for StoppedServers // delta_t not set for StoppedServers // delta_val not set for StoppedServers stoppedservers->set_default_properties(stoppedservers_prop); stoppedservers->set_polling_period(1000); stoppedservers->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(stoppedservers); // Attribute : Servers ServersAttrib *servers = new ServersAttrib(); Tango::UserDefaultAttrProp servers_prop; servers_prop.set_description("Return all registred servers for this host.\nServer names are followed by their states and controls"); servers_prop.set_label("Servers"); // unit not set for Servers // standard_unit not set for Servers // display_unit not set for Servers // format not set for Servers // max_value not set for Servers // min_value not set for Servers // max_alarm not set for Servers // min_alarm not set for Servers // max_warning not set for Servers // min_warning not set for Servers // delta_t not set for Servers // delta_val not set for Servers servers->set_default_properties(servers_prop); servers->set_polling_period(1000); servers->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(servers); // Create a list of static attributes create_static_attribute_list(get_class_attr()->get_attr_list()); /*----- PROTECTED REGION ID(StarterClass::attribute_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // StarterClass::attribute_factory_after } //-------------------------------------------------------- /** * Method : StarterClass::command_factory() * Description : Create the command object(s) * and store them in the command list */ //-------------------------------------------------------- void StarterClass::command_factory() { /*----- PROTECTED REGION ID(StarterClass::command_factory_before) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::command_factory_before // Set polling perod for command State Tango::Command &stateCmd = get_cmd_by_name("State"); stateCmd.set_polling_period(1000); // Command DevStart DevStartClass *pDevStartCmd = new DevStartClass("DevStart", Tango::DEV_STRING, Tango::DEV_VOID, "Server to be started.", "", Tango::OPERATOR); command_list.push_back(pDevStartCmd); // Command DevStop DevStopClass *pDevStopCmd = new DevStopClass("DevStop", Tango::DEV_STRING, Tango::DEV_VOID, "Servero be stopped.", "", Tango::OPERATOR); command_list.push_back(pDevStopCmd); // Command DevStartAll DevStartAllClass *pDevStartAllCmd = new DevStartAllClass("DevStartAll", Tango::DEV_SHORT, Tango::DEV_VOID, "Startup level.", "", Tango::OPERATOR); command_list.push_back(pDevStartAllCmd); // Command DevStopAll DevStopAllClass *pDevStopAllCmd = new DevStopAllClass("DevStopAll", Tango::DEV_SHORT, Tango::DEV_VOID, "Startup Level.", "", Tango::OPERATOR); command_list.push_back(pDevStopAllCmd); // Command DevGetRunningServers DevGetRunningServersClass *pDevGetRunningServersCmd = new DevGetRunningServersClass("DevGetRunningServers", Tango::DEV_BOOLEAN, Tango::DEVVAR_STRINGARRAY, "True for all servers. False for controled servers only.", "List of the processes which are running.", Tango::OPERATOR); command_list.push_back(pDevGetRunningServersCmd); // Command DevGetStopServers DevGetStopServersClass *pDevGetStopServersCmd = new DevGetStopServersClass("DevGetStopServers", Tango::DEV_BOOLEAN, Tango::DEVVAR_STRINGARRAY, "True for all servers. False for controled servers only.", "List of the processes which are not running.", Tango::OPERATOR); command_list.push_back(pDevGetStopServersCmd); // Command DevReadLog DevReadLogClass *pDevReadLogCmd = new DevReadLogClass("DevReadLog", Tango::DEV_STRING, Tango::CONST_DEV_STRING, "server name and domain (e.g. Starter/corvus)\nIf argin ==``Starter`` -> return Starter logg file content.\nIf argin ==``Statistics`` -> return Starter statistics file content.", "String found in log file.", Tango::OPERATOR); command_list.push_back(pDevReadLogCmd); // Command HardKillServer HardKillServerClass *pHardKillServerCmd = new HardKillServerClass("HardKillServer", Tango::DEV_STRING, Tango::DEV_VOID, "Server name", "", Tango::OPERATOR); command_list.push_back(pHardKillServerCmd); // Command NotifyDaemonState NotifyDaemonStateClass *pNotifyDaemonStateCmd = new NotifyDaemonStateClass("NotifyDaemonState", Tango::DEV_VOID, Tango::DEV_STATE, "", "Tango::ON if Notify daemon is running else Tango::FAULT.", Tango::OPERATOR); command_list.push_back(pNotifyDaemonStateCmd); // Command ResetStatistics ResetStatisticsClass *pResetStatisticsCmd = new ResetStatisticsClass("ResetStatistics", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::EXPERT); command_list.push_back(pResetStatisticsCmd); // Command UpdateServersInfo UpdateServersInfoClass *pUpdateServersInfoCmd = new UpdateServersInfoClass("UpdateServersInfo", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::OPERATOR); command_list.push_back(pUpdateServersInfoCmd); /*----- PROTECTED REGION ID(StarterClass::command_factory_after) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::command_factory_after } //=================================================================== // Dynamic attributes related methods //=================================================================== //-------------------------------------------------------- /** * method : StarterClass::create_static_attribute_list * description : Create the a list of static attributes * * @param att_list the ceated attribute list */ //-------------------------------------------------------- void StarterClass::create_static_attribute_list(vector &att_list) { for (unsigned long i=0 ; iget_name()); transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); defaultAttList.push_back(att_name); } cout2 << defaultAttList.size() << " attributes in default list" << endl; /*----- PROTECTED REGION ID(StarterClass::create_static_att_list) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::create_static_att_list } //-------------------------------------------------------- /** * method : StarterClass::erase_dynamic_attributes * description : delete the dynamic attributes if any. * * @param devlist_ptr the device list pointer * @param list of all attributes */ //-------------------------------------------------------- void StarterClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector &att_list) { Tango::Util *tg = Tango::Util::instance(); for (unsigned long i=0 ; ilength() ; i++) { Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); Starter *dev = static_cast (dev_impl); vector &dev_att_list = dev->get_device_attr()->get_attribute_list(); vector::iterator ite_att; for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) { string att_name((*ite_att)->get_name_lower()); if ((att_name == "state") || (att_name == "status")) continue; vector::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); if (ite_str == defaultAttList.end()) { cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); dev->remove_attribute(att_list[att.get_attr_idx()], true, false); --ite_att; } } } /*----- PROTECTED REGION ID(StarterClass::erase_dynamic_attributes) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::erase_dynamic_attributes } //-------------------------------------------------------- /** * Method : StarterClass::get_attr_by_name() * Description : returns Tango::Attr * object found by name */ //-------------------------------------------------------- Tango::Attr *StarterClass::get_attr_object_by_name(vector &att_list, string attname) { vector::iterator it; for (it=att_list.begin() ; itget_name()==attname) return (*it); // Attr does not exist return NULL; } /*----- PROTECTED REGION ID(StarterClass::Additional Methods) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::Additional Methods } // namespace tango-9.2.5a/cppserver/starter/StarterUtil.cpp0000644023471100065110000006054413034745014016423 00000000000000static const char *RcsId = "$Header$"; //+============================================================================= // // file : StarterUtil.cpp // // description : C++ source for tools used by the Starter device server. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //-============================================================================= #include #include #include #include #include #include #include #ifndef _TG_WINDOWS_ # include #endif #include #include namespace Starter_ns { int StarterUtil::elapsed; #ifndef _TG_WINDOWS_ struct timeval StarterUtil::before, StarterUtil::after; #else #endif /* _TG_WINDOWS_ */ //+------------------------------------------------------------------ /** * Contructor - Initialize data members. */ //+------------------------------------------------------------------ StarterUtil::StarterUtil(Tango::DeviceProxy *database, vector host_names, string logHome) { dbase = database; notifyd_name = "notifd/factory/"; notifyd_name += host_names[0]; ch_factory = NULL; log_home = logHome; // Remove the Fully Qualify Domain Name for tango less than 5.2 compatibility for (unsigned int i=0 ; istart(); // Wait a bit to be sure // that runningp rocess list is updated. #ifdef _TG_WINDOWS_ _sleep(1000); #else sleep(1); #endif // Build starter log file name. LogPath(starter_log_file, logHome); starter_log_file += "/Starter.log"; LogPath(starter_stat_file, logHome); starter_stat_file += "/Starter.stat"; cout << "----> starter_log_file = " << starter_log_file << endl; cout << "----> starter_stat_file = " << starter_stat_file << endl; } //+------------------------------------------------------------------ /** * Remove the Fully Qualify Domain Name for tango less than 5.2 compatibility */ //+------------------------------------------------------------------ string StarterUtil::removeFQDN(string s) { string::size_type pos = s.find('.'); if (pos == string::npos) return s; else return s.substr(0, pos); } //+------------------------------------------------------------------ /** * Extract server name from input parameter (servname/instance). */ //+------------------------------------------------------------------ char *StarterUtil::get_server_name(char *argin) { string fullName(argin); string serverName; string::size_type pos = fullName.find('/'); if (pos == string::npos) serverName = fullName; else serverName = fullName.substr(0, pos); char *servname = new char[serverName.length()+1]; strcpy(servname, serverName.c_str()); return servname; } //+------------------------------------------------------------------ /** * Extract instance name from input parameter (servname/instance). */ //+------------------------------------------------------------------ char *StarterUtil::get_instance_name(char *argin) { string fullName(argin); string instanceName; string::size_type pos = fullName.find('/'); if (pos == string::npos) instanceName = fullName; else instanceName = fullName.substr(pos+1); char *instancename = new char[instanceName.length()+1]; strcpy(instancename, instanceName.c_str()); return instancename; } //+---------------------------------------------------------------------------- // // method : StarterUtil::check_file() // // description : Check if executable file exists // and return its full name with good path. // //----------------------------------------------------------------------------- char *StarterUtil::check_exe_file(string name) { string filename(name); #ifdef _TG_WINDOWS_ filename += ".exe"; #endif //cout << "Checking " << filename << endl; ifstream ifs(filename.c_str()); if (ifs) { ifs.close(); char *exeFullName = new char[strlen(filename.c_str())+1]; strcpy(exeFullName, filename.c_str()); return exeFullName; } #ifdef _TG_WINDOWS_ // Check for batch file filename = name; filename += ".bat"; //cout << "Checking " << filename << endl; ifstream ifs2(filename.c_str()); if (ifs2) { ifs2.close(); char *exeFullName = new char[strlen(filename.c_str())+1]; strcpy(exeFullName, filename.c_str()); return exeFullName; } #endif return NULL; } //+---------------------------------------------------------------------------- // // method : StarterUtil::check_file() // // description : Check if executable file exists // and return its full name with good path. // //----------------------------------------------------------------------------- char *StarterUtil::check_exe_file(char *servname, vectorv_path) { unsigned int i; for (i=0 ; itm_year>=100) st->tm_year -= 100 ; sprintf (str, "%02d/%02d/%02d %02d:%02d:%02d", st->tm_mday, st->tm_mon+1, st->tm_year, st->tm_hour, st->tm_min, st->tm_sec ) ; return str ; } //+------------------------------------------------------------------ /** * Get the last modification on a file and return it in a string. * @param filename file's name to get the date. */ //+------------------------------------------------------------------ char *StarterUtil::get_file_date(char *filename) { struct stat info; stat(filename, &info); return strtime(info.st_mtime); } //+------------------------------------------------------------------ /** * Log info for starter. * @param message mesage to be logged */ //+------------------------------------------------------------------ void StarterUtil::log_starter_info(string message) { stringstream strlog; strlog << strtime(time(NULL)) << "\t" << message << endl; // Read and close log file. ifstream ifs((char *)starter_log_file.c_str()); if (ifs) { strlog << ifs.rdbuf(); ifs.close(); } // Check for nb lines string str(strlog.str()); string::size_type pos = 0; int nb = 0; while (nb *servers) { // build present situation log stringstream strlog; vector::iterator it; for (it=servers->begin() ; itend() ; ++it) { if (it->controlled && it->startup_level>0) { time_t failure_time = it->failure_time; if (failure_time<0) failure_time = time(NULL); strlog << it->name << "\t" << ((it->state==Tango::ON)? "ON\t" : "FAULT\t") << it->started_time << "\t" << failure_time << "\t" << "false" << endl; } } // Write an empty statistics file ofstream ofs((char *)starter_stat_file.c_str()); ofs << strlog.str(); ofs.close(); } //+------------------------------------------------------------------ /** * Log statistica for starter. * @param message mesage to be logged */ //+------------------------------------------------------------------ void StarterUtil::log_starter_statistics(ControlledServer *server) { stringstream strlog; strlog << server->name << "\t" << ((server->state==Tango::ON)? "ON\t" : "FAULT\t") << server->started_time << "\t" << server->failure_time << "\t" << ((server->auto_start)? "true" : "false") << endl; server->auto_start = false; // Read and close log file. ifstream ifs((char *)starter_stat_file.c_str()); if (ifs) { strlog << ifs.rdbuf(); ifs.close(); } // Check for nb lines string str(strlog.str()); string::size_type pos = 0; int nb = 0; while (nb do nothing // Get the log file list vector list = get_log_file_list(log_file); //for (unsigned int i=0 ; i delete while (list.size()>((unsigned int)nb_max-1)) // -1 because a new one will exist bellow { //cout << "Removing " << list[0] << endl; if (remove(list[0].c_str())<0) cerr << "remove failed : " << strerror(errno) << endl; list.erase(list.begin()); } // Build date and time (of file creation) part struct stat info; stat(filename, &info); struct tm *st = localtime(&info.st_mtime) ; if (st->tm_year>=100) st->tm_year -= 100 ; char strdate[32]; sprintf (strdate, "_[20%02d-%02d-%02d_%02d-%02d-%02d]", st->tm_year, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec ) ; // search position to insert (before extention) string str(filename); string::size_type pos = str.rfind(".log"); if (pos != string::npos) str = str.substr(0, pos); char *new_filename = new char[strlen(filename) + strlen(strdate) +1]; strcpy(new_filename, str.c_str()); strcat(new_filename, strdate); strcat(new_filename, ".log"); int ret = rename(filename, new_filename); if (ret<0) cerr << "Renaming " << filename << " to " << new_filename << " failed : " << strerror(errno) << endl; //else // cout << "Renaming " << filename << " to " << new_filename << " done." << endl; delete [] new_filename; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool alphabetical(string a,string b) { // returns alphabetic order. return (a < b); } //+------------------------------------------------------------------ /** * Rename log file list * @param filename log file name */ //+------------------------------------------------------------------ vector StarterUtil::get_log_file_list(string logfile) { vector list; // Split path and file name string::size_type pos = logfile.rfind(slash); if (pos != string::npos) { string path = logfile.substr(0, pos); pos++; // remove extention string str = logfile.substr(pos); pos = str.rfind('.'); string filter = str.substr(0, pos); filter += "_["; #ifndef _TG_WINDOWS_ //cout << "Searching " << filter << " in " << path << endl; DIR *dir = opendir ((char *)path.c_str()) ; if(dir==NULL) { string desc; // error switch(errno) { case EACCES: desc = "Permission denied."; break; case EMFILE: desc = "Too many file descriptors in use by process."; break; case ENFILE: desc = "Too many file are currently open in the system."; break; case ENOENT: desc = "Directory does not exist or NAME is an empty string."; break; case ENOMEM: desc = "Insufficient memory to complete the operation."; break; case ENOTDIR:desc = "NAME is not a directory."; break; } Tango::Except::throw_exception( (const char *)"READ_FILE_LIST_FAILED", desc, (const char *)"StarterUtil::get_log_file_list()"); } struct dirent *ent; while ( (ent=readdir(dir)) ) { string name(ent->d_name); pos = name.find(filter); if (pos == 0) { string full_name(path); full_name += "/"; full_name += name; list.push_back(full_name); } } closedir(dir); #else //cout << "Searching " << filter << " in " << path << endl; path += "\\"; path += filter; path += "*"; WCHAR *w_path = ProcessData::string2wchar(path); WIN32_FIND_DATA fd; DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY; HANDLE hFind = FindFirstFile(w_path, &fd); if(hFind != INVALID_HANDLE_VALUE) { do { string s = ProcessData::wchar2string(fd.cFileName); list.push_back(s); } while (FindNextFile( hFind, &fd)); FindClose( hFind); } else { string desc = ProcessData::errorCodeToString(GetLastError(), "FindFirstFile()" ); cerr << "Invalid Handle value " << desc << endl; } delete w_path; #endif } sort(list.begin(), list.end(), alphabetical); return list; } //+------------------------------------------------------------------ /** * method: StarterUtil::build_log_file_name * * description: Build the error log file name from server name and intancename. * * @param path path to write file * @param server name of the server */ //+------------------------------------------------------------------ string StarterUtil::build_log_file_name(char *server) { // Separate server name and intance name. //----------------------------------------- char servname[50]; char intancename[50]; char *p1 = server; char *p2 = servname; while (*p1 && *p1!='/') *p2++ = *p1++; *p2++ = '\0'; p1++; p2 = intancename; while (*p1) *p2++ = *p1++; *p2++ = '\0'; // And create full name with path //----------------------------------------- string log_file; LogPath(log_file,log_home); log_file += slash; log_file += servname; log_file += "_"; log_file += intancename; log_file += ".log"; return log_file; } //==================================================================== // // The controlled Servers Object management // //==================================================================== //+------------------------------------------------------------------ /** * Get host device servers list from database. * * @param dbase Database device as a DeviceProxy for not implemented API commands. */ //+------------------------------------------------------------------ vector StarterUtil::get_host_ds_list() { // Read server info from database. vector servnames; for (unsigned int i=0 ; icommand_inout("DbGetHostServerList", argin); vector tmp; argout >> tmp; // Check servers really used (Erase this one and database server vector::iterator pos; for (pos=tmp.begin() ; pos0) { // Get process name only in lower case before compeare string s = (*pos).substr(0, idx); transform(s.begin(), s.end(), s.begin(), ::tolower); if (s=="starter" || s=="databaseds" || s=="tangoaccesscontrol" || s=="logconsumer") { tmp.erase(pos); --pos; // because erase decrease size ! } } } // Copy to global vector for (unsigned int j=0 ; jname; Tango::DeviceData argout = dbase->command_inout("DbGetServerInfo", argin); vector result; argout >> result; server->controlled = (atoi(result[2].c_str())==0)? false: true; server->startup_level = atoi(result[3].c_str()); } catch(Tango::DevFailed &e) { Tango::Except::print_exception(e); server->controlled = false; server->startup_level = 0; } //cout << server->name << " - " << ((server->controlled)? "true": "false"); //cout << " ----> Startup level " << server->startup_level < *servers) { bool trace = false; if (trace) cout << "build_server_ctrl_object()" << endl; unsigned int i; vector result_from_db; for (i=0 ; icommand_inout("DbGetHostServersInfo", argin); argout >> result_from_db; } if (trace) cout << "-------------- Check if list of servers modified --------------" << endl; // Check servers really used (erase this one and database server) vector::iterator pos; vector result; for (pos=result_from_db.begin() ; pos0) { // Get process name only in lower case before compare string s = (*pos).substr(0, idx); transform(s.begin(), s.end(), s.begin(), ::tolower); if (s!="starter" && s!="databaseds" && s!="tangoaccesscontrol" && s!="logconsumer") { result.push_back(*pos); // Server name result.push_back(*(pos+1)); // Controlled/Not Controlled result.push_back(*(pos+2)); // Startup Level } } } // Check if some servers have disappeared vector::iterator it; bool redo = true; // Iterators management seems to have changed // between vc6 and vc8 (??) while (redo) { redo = false; for (it=servers->begin() ; itend() ; ++it) { string s1(it->name); bool found = false; for (i=0 ; !found && ithread_data->set_stop_thread(); it->thread->join(0); servers->erase(it); redo = true; break; // get out of loop (vector size has changed). } } } // Check if new servers appeared for (pos=result.begin() ; posstart(); servers->push_back(server); ms_sleep(50); // wait for server updated. } else { // Update levels p_serv->controlled = (atoi((*pos++).c_str())==0)? false: true; p_serv->startup_level = atoi((*pos++).c_str()); } } } //+------------------------------------------------------------------ /** * search a server in ControlledServer array by it's name . * * @param servname Server searched name. */ //+------------------------------------------------------------------ ControlledServer *StarterUtil::get_server_by_name(string &servname, vector &servers) { string serverName(servname); transform(serverName.begin(), serverName.end(), serverName.begin(), ::tolower); for (unsigned int i=0 ; iname); transform(ctrlName.begin(), ctrlName.end(), ctrlName.begin(), ::tolower); if (ctrlName == serverName) return server; } return NULL; } //+---------------------------------------------------------------------------- // // method : StarterUtil:: // // description : Return true if Notify Daemon is alive // //----------------------------------------------------------------------------- void StarterUtil::import_notifyd() { // Get info about notify daemon Tango::DeviceData argin; argin << notifyd_name; Tango::DeviceData import_argout = dbase->command_inout("DbImportEvent", argin); const Tango::DevVarLongStringArray *lsa; import_argout >> lsa; // store ior string factory_ior = string((lsa->svalue)[1]); // Try to connect Tango::Util *tu = Tango::Util::instance(); CORBA::ORB_ptr _orb = tu->get_orb(); CORBA::Object *event_factory_obj = _orb -> string_to_object(factory_ior.c_str()); if (event_factory_obj -> _non_existent()) event_factory_obj = CORBA::Object::_nil(); // Narrow the CORBA_Object reference to an EventChannelFactory // reference so we can invoke its methods //CORBA::Object *_eventChannelFactory = event_factory_obj; // Test the connection ch_factory = CosNotifyChannelAdmin::EventChannelFactory::_narrow(event_factory_obj); } //+---------------------------------------------------------------------------- // // method : StarterUtil:: // // description : Return true if Notify Daemon is alive // //----------------------------------------------------------------------------- Tango::DevState StarterUtil::is_notifyd_alive() { string notify_procname("notifd"); Tango::DevState notifd_state; if (proc_util->is_process_running(notify_procname)) { try { //cout << notify_procname << " is running" << endl; if (ch_factory==NULL) import_notifyd(); CosNotifyChannelAdmin::ChannelIDSeq *ch_id = ch_factory->get_all_channels(); delete ch_id; cout2 << notifyd_name << "EventChannelFactory is ON" << endl; notifd_state = Tango::ON; } catch (...) { cerr << notify_procname << " is running BUT not responding" << endl; //cerr << "Failed to narrow the EventChannelFactory on " << notifyd_name << endl; ch_factory = NULL; notifd_state = Tango::UNKNOWN; } } else { //cout << notify_procname << " is NOT running" << endl; notifd_state = Tango::FAULT; } return notifd_state; } //----------------------------------------------------------------------------- } // namespace tango-9.2.5a/cppserver/starter/StarterStateMachine.cpp0000644023471100065110000002650113034745014020046 00000000000000/*----- PROTECTED REGION ID(StarterStateMachine.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: StarterStateMachine.cpp 28168 2015-06-30 07:27:09Z pascal_verdier $"; //============================================================================= // // file : StarterStateMachine.cpp // // description : C++ source for the �name� and its alowed // methods for commands and attributes // // project : Starter for Tango Administration. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility,2015 // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /*----- PROTECTED REGION END -----*/ // Starter::StarterStateMachine.cpp //================================================================ // States | Description //================================================================ // UNKNOWN | This device server has NOT been correctly initialised. // ON | All controlled servers are running. // ALARM | At least one controled device server is not running. // MOVING | The Sarter is starting servers. namespace Starter_ns { //================================================= // Attributes Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : Starter::is_NotifdState_allowed() * Description : Execution allowed for NotifdState attribute */ //-------------------------------------------------------- bool Starter::is_NotifdState_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for NotifdState attribute in read access. /*----- PROTECTED REGION ID(Starter::NotifdStateStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::NotifdStateStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : Starter::is_HostState_allowed() * Description : Execution allowed for HostState attribute */ //-------------------------------------------------------- bool Starter::is_HostState_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for HostState attribute in read access. /*----- PROTECTED REGION ID(Starter::HostStateStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::HostStateStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : Starter::is_RunningServers_allowed() * Description : Execution allowed for RunningServers attribute */ //-------------------------------------------------------- bool Starter::is_RunningServers_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for RunningServers attribute in read access. /*----- PROTECTED REGION ID(Starter::RunningServersStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::RunningServersStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : Starter::is_StoppedServers_allowed() * Description : Execution allowed for StoppedServers attribute */ //-------------------------------------------------------- bool Starter::is_StoppedServers_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for StoppedServers attribute in read access. /*----- PROTECTED REGION ID(Starter::StoppedServersStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::StoppedServersStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : Starter::is_Servers_allowed() * Description : Execution allowed for Servers attribute */ //-------------------------------------------------------- bool Starter::is_Servers_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Servers attribute in read access. /*----- PROTECTED REGION ID(Starter::ServersStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::ServersStateAllowed_READ return true; } //================================================= // Commands Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : Starter::is_DevStart_allowed() * Description : Execution allowed for DevStart attribute */ //-------------------------------------------------------- bool Starter::is_DevStart_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevStart command. /*----- PROTECTED REGION ID(Starter::DevStartStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevStartStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevStop_allowed() * Description : Execution allowed for DevStop attribute */ //-------------------------------------------------------- bool Starter::is_DevStop_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevStop command. /*----- PROTECTED REGION ID(Starter::DevStopStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevStopStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevStartAll_allowed() * Description : Execution allowed for DevStartAll attribute */ //-------------------------------------------------------- bool Starter::is_DevStartAll_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevStartAll command. /*----- PROTECTED REGION ID(Starter::DevStartAllStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevStartAllStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevStopAll_allowed() * Description : Execution allowed for DevStopAll attribute */ //-------------------------------------------------------- bool Starter::is_DevStopAll_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevStopAll command. /*----- PROTECTED REGION ID(Starter::DevStopAllStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevStopAllStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevGetRunningServers_allowed() * Description : Execution allowed for DevGetRunningServers attribute */ //-------------------------------------------------------- bool Starter::is_DevGetRunningServers_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevGetRunningServers command. /*----- PROTECTED REGION ID(Starter::DevGetRunningServersStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevGetRunningServersStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevGetStopServers_allowed() * Description : Execution allowed for DevGetStopServers attribute */ //-------------------------------------------------------- bool Starter::is_DevGetStopServers_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevGetStopServers command. /*----- PROTECTED REGION ID(Starter::DevGetStopServersStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevGetStopServersStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_DevReadLog_allowed() * Description : Execution allowed for DevReadLog attribute */ //-------------------------------------------------------- bool Starter::is_DevReadLog_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevReadLog command. /*----- PROTECTED REGION ID(Starter::DevReadLogStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::DevReadLogStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_HardKillServer_allowed() * Description : Execution allowed for HardKillServer attribute */ //-------------------------------------------------------- bool Starter::is_HardKillServer_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for HardKillServer command. /*----- PROTECTED REGION ID(Starter::HardKillServerStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::HardKillServerStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_NotifyDaemonState_allowed() * Description : Execution allowed for NotifyDaemonState attribute */ //-------------------------------------------------------- bool Starter::is_NotifyDaemonState_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for NotifyDaemonState command. /*----- PROTECTED REGION ID(Starter::NotifyDaemonStateStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::NotifyDaemonStateStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_ResetStatistics_allowed() * Description : Execution allowed for ResetStatistics attribute */ //-------------------------------------------------------- bool Starter::is_ResetStatistics_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for ResetStatistics command. /*----- PROTECTED REGION ID(Starter::ResetStatisticsStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::ResetStatisticsStateAllowed return true; } //-------------------------------------------------------- /** * Method : Starter::is_UpdateServersInfo_allowed() * Description : Execution allowed for UpdateServersInfo attribute */ //-------------------------------------------------------- bool Starter::is_UpdateServersInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for UpdateServersInfo command. /*----- PROTECTED REGION ID(Starter::UpdateServersInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // Starter::UpdateServersInfoStateAllowed return true; } } // End of namespace tango-9.2.5a/cppserver/starter/main.cpp0000644023471100065110000000771413034745014015065 00000000000000/*PROTECTED REGION ID(Starter::main.cpp) ENABLED START*/ static const char *RcsId = "$Id: main.cpp 29529 2016-03-22 10:36:16Z pascal_verdier $"; //============================================================================= // // file : main.cpp // // description : C++ source for a TANGO device server main. // The main rule is to initialise (and create) the Tango // system and to create the DServerClass singleton. // The main should be the same for every Tango device server. // // project : Starter for Tango Administration. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 29529 $ // $Date: 2016-03-22 11:36:16 +0100 (Tue, 22 Mar 2016) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #ifdef _TG_WINDOWS_ //#define USE_SERVICE #endif #ifndef _TG_WINDOWS_ # include #endif #include #include #ifdef USE_SERVICE #include using namespace std; #endif #ifdef _TG_WINDOWS__DBG #include "Stackwalker.h" #endif int main(int argc,char *argv[]) { // First time set SIGINT to default to do not block // signal handling for child processes //--------------------------------------------------- #ifndef _TG_WINDOWS_ //sigset(SIGINT, SIG_DFL); struct sigaction sa; sa.sa_flags = 0; sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); if (sigaction(SIGINT,&sa,NULL) == -1) cerr << "Starter main() --> Can't reset default action for SIGINT to SIG_DFL" << endl; #endif // Check for hostname //--------------------------------- if (argc>1) { char *p; for (p=argv[1] ; *p ; p++) if (*p=='.') *p = '\0'; // Take off extension (eg:.esrf.fr) } // Set an automatic retry on database connection //--------------------------------------------------- Tango::Util::_daemon = true; Tango::Util::_sleep_between_connect = 5; #ifdef USE_SERVICE StarterService service(argv[0]); int ret; if ((ret=service.options(argc, argv))<=0) return ret; service.run(argc, argv); return 0; #else try { // Initialise the device server //---------------------------------------- Tango::Util *tg = Tango::Util::init(argc,argv); // Create the device server singleton // which will create everything //---------------------------------------- tg->server_init(); cout << "Ready to accept request" << endl; // Run the endless loop //---------------------------------------- #ifdef WIN32_DBG InitAllocCheck(ACOutput_XML); #endif tg->server_run(); } catch (bad_alloc) { cerr << "Can't allocate memory to store device object !!!" << endl; cerr << "Exiting" << endl; } catch (CORBA::Exception &e) { Tango::Except::print_exception(e); cerr << "Received a CORBA_Exception" << endl; cerr << "Exiting" << endl; } Tango::Util::instance()->server_cleanup(); #ifdef WIN32_DBG DeInitAllocCheck(); #endif return(0); #endif } /*PROTECTED REGION END*/ // Starter::main.cpp tango-9.2.5a/cppserver/starter/PingThread.cpp0000644023471100065110000001534713034745014016167 00000000000000static const char *RcsId = "$Header$"; //+============================================================================= // // file : StarterUtil.cpp // // description : C++ source for tools used by the Starter device server. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //-============================================================================= #include #include #include #include #include #include #include #ifndef _TG_WINDOWS_ # include #endif #include #include #ifndef TIME_VAR #ifndef _TG_WINDOWS_ # define TimeVal struct timeval # define GetTime(t) gettimeofday(&t, NULL); # define Elapsed(before, after) \ 1000.0*(after.tv_sec-before.tv_sec) + \ ((double)after.tv_usec-before.tv_usec) / 1000 #else # define TimeVal struct _timeb # define GetTime(t) _ftime(&t); # define Elapsed(before, after) \ 1000*(after.time - before.time) + (after.millitm - before.millitm) #endif /* _TG_WINDOWS_ */ #endif /* TIME_VAR */ namespace Starter_ns { //+---------------------------------------------------------------------------- /** * Constructor */ //+---------------------------------------------------------------------------- PingThreadData::PingThreadData(string sname) { servname = sname; stop_thread = false; last_write_time = time(NULL); state = Tango::ON; } //+---------------------------------------------------------------------------- /** * Get the server name */ //+---------------------------------------------------------------------------- string PingThreadData::get_server_name() { omni_mutex_lock sync(*this); return servname; } //+---------------------------------------------------------------------------- /** * command to stop thread */ //+---------------------------------------------------------------------------- void PingThreadData::set_stop_thread() { omni_mutex_lock sync(*this); stop_thread = true; signal(); } //+---------------------------------------------------------------------------- /** * get stop thread status */ //+---------------------------------------------------------------------------- bool PingThreadData::get_stop_thread() { omni_mutex_lock sync(*this); return stop_thread; } //+---------------------------------------------------------------------------- /** * Return the elapsed time from last write. */ //+---------------------------------------------------------------------------- time_t PingThreadData::get_last_write_time() { omni_mutex_lock sync(*this); return last_write_time; } //+---------------------------------------------------------------------------- /** * Set the ping result. */ //+---------------------------------------------------------------------------- void PingThreadData::set_state(Tango::DevState st) { omni_mutex_lock sync(*this); state = st; last_write_time = time(NULL); } //+---------------------------------------------------------------------------- /** * Set the ping result. */ //+---------------------------------------------------------------------------- Tango::DevState PingThreadData::get_state() { omni_mutex_lock sync(*this); return state; } //+---------------------------------------------------------------------------- /** * Force thread to update data. */ //+---------------------------------------------------------------------------- void PingThreadData::wake_up() { omni_mutex_lock sync(*this); signal(); } //+---------------------------------------------------------------------------- //+---------------------------------------------------------------------------- //+---------------------------------------------------------------------------- /** * Execute the thread loop. */ //+---------------------------------------------------------------------------- void *PingThread::run_undetached(TANGO_UNUSED(void *ptr)) { bool trace = false; if (trace) cout << "Start a thread to ping " << servname << endl; TimeVal before, after; Tango::DeviceProxy *dev = NULL; Tango::DevState state = Tango::FAULT; bool stop_thread = false; string adm_devname("dserver/"); adm_devname += servname; while(!stop_thread) { GetTime(before); // Check before if server running or failed if (process_util->is_server_running(servname)) { // try to build DeviceProxy if (dev==NULL) { try { if (dev==NULL) dev = new Tango::DeviceProxy(adm_devname); } catch(Tango::DevFailed &e) { Tango::Except::print_exception(e); } catch(...) { cout << "============================================" << endl; cout << " Exception catch !!!!!!" << endl; cout << "============================================" << endl; } } if (dev!=NULL) { try { dev->ping(); state = Tango::ON; } catch(Tango::DevFailed &) { cout << servname << " is running but not responding !!!" << endl; //Tango::Except::print_exception(e); state = Tango::MOVING; } } } else state = Tango::FAULT; shared->set_state(state); if (trace) cout << "Ping thread:[" << servname << "] " << Tango::DevStateName[state] << endl; // Compute time to sleep GetTime(after); double dt = (double)Elapsed(before, after); long time_to_sleep = 2000 - (int)dt; if (time_to_sleep<10) time_to_sleep = 10; // Check if thread must be stopped. stop_thread = shared->get_stop_thread(); if (!stop_thread) { // And wait for next ping omni_mutex_lock sync(*shared); shared->wait(time_to_sleep); } stop_thread = shared->get_stop_thread(); } delete shared; if (dev!=NULL) delete dev; if (trace) cout << "Ping thread:[" << servname << "] - leaving...." << endl; return NULL; } //+---------------------------------------------------------------------------- } // namespace tango-9.2.5a/cppserver/starter/StartProcessThread.cpp0000755023471100065110000002644413034745014017731 00000000000000static const char *RcsId = "$Header$"; //+============================================================================= // // file : StartProcessThread.cpp // // description : C++ source for the Starter start process thread. // // project : TANGO Device Server // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 29529 $ // $Date: 2016-03-22 11:36:16 +0100 (Tue, 22 Mar 2016) $ // //+============================================================================= #include #ifdef _TG_WINDOWS_ # include # include # include #else # include # include #endif #include #include namespace Starter_ns { //+------------------------------------------------------------------ /** * Thread constructor */ //+------------------------------------------------------------------ StartProcessThread::StartProcessThread(vector v_np, int level, Starter *st) { for (unsigned int i=0 ; iutil->proc_util; // Check if a previous level thread is terminated if (thread_level>1) { while (starter->start_proc_data->get_current_level()!=thread_level && starter->start_proc_data->level_is_still_active(thread_level) ) { //cout << " level " << thread_level << // " wait for end for level " << starter->start_proc_data->get_current_level() << endl; ms_sleep(500); } } // Start the level process start loop for (i=0 ; istart_proc_data->level_is_still_active(thread_level) ; i++) { start_process(processes[i]); // Build server name from admin name char *p = processes[i]->adminname + strlen("dserver/"); string servname(p); bool failed = false; // Sleep a bit between start ups // to do not overload database bool started = false; time_t t0 = time(NULL); time_t t1 = t0; Tango::DeviceProxy *serv; while (failed==false && started==false && (t1-t0)serverStartupTimeout) { # ifdef _TG_WINDOWS_ _sleep(1000); # else sleep(1); # endif // do not test before 4 seconds to be sure // process list has been updated. t1 = time(NULL); if ((t1-t0)>=4) { // Check if server running or failed if (process_util->is_server_running(servname)==false) failed = true; else { // if not failed check if start up is terminated serv = NULL; try { serv = new Tango::DeviceProxy(processes[i]->adminname); serv->ping(); started = true; } catch(Tango::DevFailed &) { //cout << e.errors[0].desc << endl; } if (serv!=NULL) delete serv; t1 = time(NULL); } } } if (started) { TangoSys_OMemStream out_stream; out_stream << servname << " started"; starter->util->log_starter_info(out_stream.str()); //cout << "----- " << servname << " started in " << (t1-t0) << " sec." << endl; } else if (failed) cout << "----- " << servname << " failed in " << (t1-t0) << " sec." << endl; else cout << "----- " << servname << " Timeout = " << (t1-t0) << endl; // Wait a bit betwee 2 startup (not for last one) if (thread_level>0 && i0 && starter->interStartupLevelWait>0 && starter->start_proc_data->level_is_still_active(thread_level)) { //cout << "Thread level " << thread_level << // " wait for " << starter->interStartupLevelWait << endl; ms_sleep(starter->interStartupLevelWait*1000); } // Free the process structure field for (i=0 ; iservname; delete[] processes[i]->instancename; delete[] processes[i]->adminname; delete[] processes[i]->logfile; delete processes[i]; } // remove in level vector to start another level starter->start_proc_data->remove_level(thread_level); } #ifndef _TG_WINDOWS_ //+------------------------------------------------------------------ /** * Start one process */ //+------------------------------------------------------------------ void StartProcessThread::start_process(NewProcess *process) { char *argv[4]; int i = 0; argv[i++] = process->servname; argv[i++] = process->instancename; //argv[i++] = "-v5"; argv[i++] = NULL; // Fork a child process to start the device server int fork_id = fork(); switch(fork_id) { case -1: cerr << "Fork Failed !" << endl; break; case 0: // Double fork to prevent defunct child processes switch(fork()) { case -1: cerr << "Fork Failed !" << endl; break; case 0: { // Change process group and close control tty #if defined(__darwin__) || defined( __MACOS__) setpgrp(); #elif defined (__freebsd__) setpgrp(0,setsid()); #else setpgrp(); // Call setsid() to do NOT stop children if Starter is killed. setsid(); #endif // Close standard out close(1); open("/dev/null", O_RDWR | O_CREAT, 0664); // Close the stderr and re-open it on a log file. close(2); starter->util->manage_log_file_history( process->logfile, starter->keepLogFiles); open(process->logfile, O_RDWR | O_CREAT, 0664); // Start the execution of the device server if (execvp(argv[0], argv)<0) { ofstream of(process->logfile); of << "Exec(" << argv[0] << ") failed " << endl; of << strerror(errno) << endl; of.close(); } _exit(0); } break; default: //cout << fork_id << " exit()" << endl; _exit(0); break; } break; default: int res_wait; wait(&res_wait); break; } } #else // _TG_WINDOWS_ //+---------------------------------------------------------- // WIN 32 methods to fork a sub process //+---------------------------------------------------------- void StartProcessThread::start_process(NewProcess *process) { /***** On Win32 problem with permission denied ! It seems that this not necessary because there is nothing in file. starter->util->manage_log_file_history( process->logfile, starter->keepLogFiles); */ StartWinThread *win_thread = new StartWinThread(process, starter); win_thread->start(); } //+------------------------------------------------------------------ /** * Set the path between cotes for windows. * * @param servname server name */ //+------------------------------------------------------------------ string StartWinThread::get_server_name_with_cotes(string servname) { string::size_type pos = servname.find_last_of("/\\"); if (pos!=string::npos) { string str("\""); str += servname.substr(0, pos); str += "\""; str += servname.substr(pos); return str; } else return servname; } //+---------------------------------------------------------- // WIN 32 Thread to fork a sub process // If batch file, the spawnv is blocking !!! //+---------------------------------------------------------- void StartWinThread::run(void *ptr) { // Check if batch file string str_server(process->servname); string str_with_cotes = get_server_name_with_cotes(process->servname); string cmd(str_with_cotes); cmd += " "; cmd += process->instancename; cout << "system(" << cmd << ");" << endl; system(cmd.c_str()); return; } #endif // _TG_WINDOWS_ //+------------------------------------------------------------------ //+------------------------------------------------------------------ int StartProcessShared::get_starting_processes() { omni_mutex_lock sync(*this); return starting_processes; } //+------------------------------------------------------------------ /** * StartProcessShared::push_back_level(int level) */ //+------------------------------------------------------------------ void StartProcessShared::push_back_level(int level) { omni_mutex_lock sync(*this); start_process_thread_levels.push_back(level); starting_processes++; } //+------------------------------------------------------------------ /** * StartProcessShared::get_current_level() */ //+------------------------------------------------------------------ int StartProcessShared::get_current_level() { omni_mutex_lock sync(*this); return start_process_thread_levels[0]; } //+------------------------------------------------------------------ /** * StartProcessShared::level_is_still_active(int level) */ //+------------------------------------------------------------------ bool StartProcessShared::level_is_still_active(int level) { omni_mutex_lock sync(*this); vector::iterator it = start_process_thread_levels.begin(); for ( ; it::iterator it = start_process_thread_levels.begin(); for ( ; it. // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //-============================================================================= #include #ifndef TIME_VAR #ifndef _TG_WINDOWS_ # define TimeVal struct timeval # define GetTime(t) gettimeofday(&t, NULL); # define Elapsed(before, after) \ 1000.0*(after.tv_sec-before.tv_sec) + \ ((double)after.tv_usec-before.tv_usec) / 1000 #else # define TimeVal struct _timeb # define GetTime(t) _ftime(&t); # define Elapsed(before, after) \ 1000*(after.time - before.time) + (after.millitm - before.millitm) #endif /* _TG_WINDOWS_ */ #endif /* TIME_VAR */ #ifdef _TG_WINDOWS_ typedef LONG (WINAPI *TNtQueryInformationProcess)(HANDLE,UINT,PVOID,ULONG,PULONG); #endif namespace Starter_ns { //============================================================= //============================================================= ProcessData::ProcessData() { #ifdef _TG_WINDOWS_ // Under win 2000 or before the process name is shorted to 15 char // If win 2000, take it from command line. win2000 = isWin2000(); #endif /* _TG_WINDOWS_ */ } //============================================================= //============================================================= ProcessData::~ProcessData() { // clear previous list for (unsigned int i=0 ; iname = full_name.substr(0, pos); else process->name = full_name; // Parse name frome cmd line because file manager truncate it at 15 chars if (win2000 && process->name.length()>13) process->name = parseNameFromCmdLine(process->name, cmdline); // On win32 -> exe file is case unsesitive transform(process->name.begin(), process->name.end(), process->name.begin(), ::tolower); // add pid and cmd line process->pid = pe32.th32ProcessID; process->line = cmdline; proc_list.push_back(process); } } while ( Process32Next(hProcessSnap, &pe32) ); CloseHandle(hProcessSnap); #else //============================================================================= // Take a snapshot of all processes in the system. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPMODULE, 0); if( hProcessSnap == INVALID_HANDLE_VALUE) { string desc = errorCodeToString(GetLastError(), "CreateToolhelp32Snapshot" ); Tango::Except::throw_exception( (const char *)"PROCESS_LIST_FAILED", (const char *) desc.c_str(), (const char *)"Starter::get_process_list()"); } // Set the size of the structure before using it. PROCESSENTRY32 pe32; pe32.dwSize = sizeof( PROCESSENTRY32 ); // Retrieve information about the first process, // and exit if unsuccessful if( !Process32First( hProcessSnap, &pe32 ) ) { string desc = errorCodeToString(GetLastError(), "Process32First" ); // Show cause of failure CloseHandle( hProcessSnap ); // Must clean up the snapshot object! Tango::Except::throw_exception( (const char *)"PROCESS_LIST_FAILED", (const char *) desc.c_str(), (const char *)"Starter::get_process_list()"); } // Get module ntdll NTQIP *lpfnNtQueryInformationProcess; HINSTANCE hLibrary = GetModuleHandleA("ntdll.dll"); if (hLibrary != NULL) { lpfnNtQueryInformationProcess = (NTQIP *)GetProcAddress(hLibrary, "ZwQueryInformationProcess"); } else { string desc = errorCodeToString(GetLastError(), "GetModuleHandle() "); Tango::Except::throw_exception( (const char *)"PROCESS_LIST_FAILED", (const char *) desc.c_str(), (const char *)"Starter::get_process_list()"); } do { // Retrieve the priority class. //HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID ); HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID ); if( hProcess != NULL ) { string strLine(""); // Get PEB address PVOID pebAddress = getPebAddress(hProcess); // Get the address of parameters PVOID rtlUserProcParamsAddress = getPebStructure(hProcess, pebAddress); if (rtlUserProcParamsAddress!=NULL) { // Read the command line in UNICODE structure UNICODE_STRING commandLine = getUnicodeCommandLine(hProcess, rtlUserProcParamsAddress); // Convert the command line WCHAR *commandLineContents = new WCHAR[commandLine.Length]; if (ReadProcessMemory(hProcess, commandLine.Buffer, commandLineContents, commandLine.Length, NULL)) { strLine = wchar2string( commandLineContents, commandLine.Length/2); } else errorCodeToString(GetLastError(), "Cannot convert the command line" ); delete [] commandLineContents; } else errorCodeToString(GetLastError(), "Cannot get the address of parameters" ); CloseHandle( hProcess ); // build process object to be added in vector Process *process = new Process(); // Remove extention from exe name string full_name = wchar2string(pe32.szExeFile); string::size_type pos = full_name.find('.'); if (pos!=string::npos) process->name = full_name.substr(0, pos); else process->name = full_name; // Parse name frome cmd line because file manager truncate it at 15 chars if (win2000 && process->name.length()>13) process->name = parseNameFromCmdLine(process->name, strLine); // On win32 -> exe file is case unsesitive transform(process->name.begin(), process->name.end(), process->name.begin(), ::tolower); // add pid and cmd line process->pid = pe32.th32ProcessID; process->line = strLine; proc_list.push_back(process); } } while ( Process32Next(hProcessSnap, &pe32) ); CloseHandle(hProcessSnap); #endif } //============================================================================ //============================================================================ UNICODE_STRING ProcessData::getUnicodeCommandLine(HANDLE hProcess, PVOID paramAddress) { UNICODE_STRING commandLine; #if (_MSC_VER >= 1600) // VC10 RTL_USER_PROCESS_PARAMETERS *pProcessParam = (RTL_USER_PROCESS_PARAMETERS *) paramAddress; ReadProcessMemory(hProcess, (PCHAR) &pProcessParam->CommandLine, &commandLine, sizeof(commandLine), NULL); #else ReadProcessMemory(hProcess, (PCHAR) paramAddress + 0x40, &commandLine, sizeof(commandLine), NULL); #endif return commandLine; } //============================================================================ //============================================================================ PVOID ProcessData::getPebStructure(HANDLE hProcess, PVOID pebAddress) { PVOID rtlUserProcParamsAddress = NULL; #if (_MSC_VER >= 1600) // VC10 PEB *peb = (PEB *)pebAddress; ReadProcessMemory(hProcess, (PCHAR)&peb->ProcessParameters, &rtlUserProcParamsAddress, sizeof(PVOID), NULL); #else ReadProcessMemory(hProcess, (PCHAR)pebAddress+0x10, &rtlUserProcParamsAddress, sizeof(PVOID), NULL); #endif return rtlUserProcParamsAddress; } //============================================================================ //============================================================================ PVOID ProcessData::getPebAddress(HANDLE pHandle) { NTQIP *ntQueryInformationProcess = (NTQIP *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess"); PROCESS_BASIC_INFORMATION pbi; ntQueryInformationProcess(pHandle, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); return pbi.PebBaseAddress; } // ============================================================================ // Win32ProcessManager::errorCodeToString // ============================================================================ string ProcessData::errorCodeToString (DWORD err_code, string src) { WCHAR *buff; string msg; if(err_code != ERROR_SUCCESS) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err_code, 0, // Default language (LPTSTR) &buff, 0, NULL ); msg = src + string(" failed : "); msg += wchar2string(buff); // Free the buffer. LocalFree(buff); } else msg = "No Error"; cerr << msg << endl; return msg; } #else // _TG_WINDOWS_ //============================================================= //============================================================= void ProcessData::read_process_list_from_sys() { // clear previous list for (unsigned int i=0 ; id_name[0])) { // Get PID Process *process = new Process(); process->pid = atoi(ent->d_name); try { // if process can be read, add process object to vector if (manageProcFiles(process)) proc_list.push_back(process); else delete process; } catch(Tango::DevFailed &e) { cout << "Excepion catch during manageProcFiles for pid = " << process->pid << endl; cout << e.errors[0].desc; delete process; } catch(...) { cout << "Excepion catch during manageProcFiles for pid = " << process->pid << endl; delete process; } } } closedir(proc); } //============================================================= /** * Manage the /proc files */ //============================================================= bool ProcessData::manageProcFiles(Process *process) { #if (defined __GLIBC__) || (defined __darwin__) || (defined __freebsd__) // Read command line file TangoSys_OMemStream fname; fname << "/proc/" << process->pid <<"/cmdline"; // Read file ifstream ifs((char *)fname.str().c_str()); if (ifs) { TangoSys_OMemStream sstr; sstr << ifs.rdbuf() << ends; ifs.close(); // Get command line process->line = sstr.str(); // Replace NULL with SPACE char string::size_type pos; while ((pos=process->line.find('\0'))!=string::npos) process->line.replace(pos, 1, " "); return true; } else { cerr << fname.str() << ": " << strerror(errno) << endl; return false; } #else // solaris // Read psinfo file TangoSys_OMemStream fname; fname << "/proc/" << process->pid <<"/psinfo"; int fid; struct psinfo ps; if ((fid=open(fname.str().c_str(), O_RDONLY))!=-1) { read(fid, (void *) &ps, sizeof(struct psinfo)); close(fid); process->name = ps.pr_fname; // Check if a real process or a shell (cannot be a server) if (process->name=="ssh" || process->name=="bash" || process->name=="sh") return false; uid_t euid = geteuid(); if ((euid==0) || (euid == ps.pr_euid)) { /* * To get the argv vector and environment variables * for the process you need to be either root or the owner of the process. * Otherwise you will not be able to open the processes memory. */ int fdesc; TangoSys_OMemStream filepath; filepath << "/proc/" << process->pid <<"/as"; if ( (fdesc = open(filepath.str().c_str(), O_RDONLY|O_NONBLOCK)) < 0 ) { TangoSys_OMemStream tms; tms << "Cannot open " << filepath.str() << ": " << strerror(errno) << endl; #ifdef TRACE cerr << tms.str(); #endif Tango::Except::throw_exception( (const char *)"PROCESS_READ_FAILED", (const char *) tms.str().c_str(), (const char *)"Starter::manageProcFiles()"); } else { // Allocate a pointer array size_t size = sizeof(char *) * (ps.pr_argc+1); char **argvp = (char **) malloc(size); // And initialize if (pread(fdesc, argvp, size, ps.pr_argv)>0) { TangoSys_OMemStream line; // If argv[n] read -> append to command line char buff[0x100]; for (int n=0; n0) line << buff << " "; process->line = line.str(); free(argvp); close(fdesc); } else { free(argvp); close(fdesc); TangoSys_OMemStream tms; tms << "pread failed when getting command line arguments " << " from memory for process " << process->name << " (" << filepath.str() << ")\n" << strerror(errno) << endl; cerr << tms.str(); Tango::Except::throw_exception( (const char *)"PROCESS_READ_FAILED", (const char *) tms.str().c_str(), (const char *)"Starter::manageProcFiles()"); } } } else { // Not Owner -> get only the ps.pr_psargs process->line = ps.pr_psargs; close(fid); } } else { TangoSys_OMemStream tms; tms << "open(" << fname.str() << ") failed\n" << strerror(errno) << endl; cerr << tms.str(); Tango::Except::throw_exception( (const char *)"PROCESS_READ_FAILED", (const char *) tms.str().c_str(), (const char *)"Starter::manageProcFiles()"); } return true; #endif } #endif // _TG_WINDOWS_ //============================================================= /** * Not only cpp * Check for other than java and python processes */ //============================================================= void ProcessData::check_cpp_process(Process* process) { // Remove path #ifndef _TG_WINDOWS_ if (process->line_args.size()==0) process->name = ""; else process->name = name_from_path(process->line_args[0]); #endif for (unsigned int i=1 ; iline_args.size() ; i++) process->proc_args.push_back(process->line_args[i]); } //============================================================= /** * Check for java processes */ //============================================================= bool ProcessData::check_java_process(Process* process) { if (process->line_args.size()==0) return false; #ifdef _TG_WINDOWS_ if (process->name!="java" && process->name!="javaw") return false; #else if (name_from_path(process->line_args[0])!="java") return false; #endif // Parse class and instance name bool found=false; for (int i=process->line_args.size()-1 ; !found && i>0 ; i--) { if (process->line_args[i]!="" && process->line_args[i].c_str()[0]!='-') { if (i>1) { // To get class name, remove package name of previous arg string full_name(process->line_args[i-1]); string::size_type start = 0; string::size_type end; while ((end=full_name.find('.', start))!=string::npos) start = end+1; // Get last one process->name = full_name.substr(start); // and take this one as instance process->proc_args.push_back(process->line_args[i]); found = true; } } } return true; } //============================================================= /** * Check for python processes */ //============================================================= bool ProcessData::check_python_process(Process* process) { if (process->line_args.size()==0) return false; // Check id process is python (must start with "python") string processName; #ifdef _TG_WINDOWS_ processName = process->name; // if (process->name!="python") // return false; #else processName = name_from_path(process->line_args[0]); // if (name_from_path(process->line_args[0])!="python") // return false; #endif if (processName.find("python")!=0) return false; if (process->line_args.size()<2) return false; // No module loaded // To get python module name bool found_py_module = false; unsigned int args_idx = 1; for (; args_idx < process->line_args.size()-1 ; args_idx++) { const string &arg = process->line_args[args_idx]; if (arg.size() == 0) continue; if (arg[0] == '-') { // special python arguments that receive and additional parameter if (arg.size() > 1 && (arg[1] == 'Q' || arg[1] == 'W')) args_idx++; continue; } // we reached the python file in execution found_py_module = true; string::size_type start = arg.rfind('/'); if (start == string::npos) start = arg.rfind('\\'); if (start == string::npos) start = 0; else start++; string::size_type end = arg.rfind(".py"); if (end == string::npos) process->name = arg.substr(start); else process->name = arg.substr(start, end-start); // everything from now on is an argument args_idx++; break; } if (!found_py_module) return false; for (unsigned int i=args_idx ; iline_args.size() ; i++) process->proc_args.push_back(process->line_args[i]); return true; } //============================================================= //============================================================= string ProcessData::name_from_path(string full_name) { string::size_type start = 0; string::size_type end; while ((end=full_name.find('/', start))!=string::npos) start = end+1; // Get last one return full_name.substr(start); } //============================================================= //============================================================= void ProcessData::build_server_names(Process* process) { // server is a process with at least one arg if (process->proc_args.size()>0) { process->servname = process->name; process->servname += "/"; string instance(process->proc_args[0]); transform(instance.begin(), instance.end(), instance.begin(), ::tolower); process->servname += instance; #ifdef _TG_WINDOWS_ // Wain32 is case unsensitive transform(process->servname.begin(), process->servname.end(), process->servname.begin(), ::tolower); #endif } else process->servname = ""; } //============================================================= //============================================================= //============================================================= /** * Public method to update and build process process */ //============================================================= //#define TRACE void ProcessData::update_process_list() { omni_mutex_lock sync(*this); TimeVal t0, t1; GetTime(t0); read_process_list_from_sys(); GetTime(t1); #ifdef TRACE TimeVal t2, t3; double max_t = 0; Process *max_t_proc; cout << " Reading process list = " << Elapsed(t0, t1) << " ms" << endl; #endif for (unsigned int i=0 ; iline.find(' ', start))!=string::npos) { string s = process->line.substr(start, (end-start)); start = end+1; // Check if not empty if (s!="" && s!=" " && s!="\t") { // Check if between cotes if (in_cotes==false && s.find('\"')!=string::npos) // starting { process->line_args.push_back(s); in_cotes = true; } else if (in_cotes==true) // inside { // Get last arg and concat with new one string arg = process->line_args.back(); arg += " " + s; // And replace process->line_args.pop_back(); process->line_args.push_back(arg); if (s.find('\"')!=string::npos) // ending in_cotes = false; } else process->line_args.push_back(s); } } // Get last one string s = process->line.substr(start); if (s!="") process->line_args.push_back(s); #ifndef _TG_WINDOWS_ if (process->line_args.empty()==false) process->name = process->line_args[0]; else process->name = ""; #endif // Check if java or python process if (check_java_process(process)==false) if(check_python_process(process)==false) check_cpp_process(process); build_server_names(process); #ifdef TRACE2 cout << process->pid << " " << process->name; if (process->proc_args.empty()==false) cout << " " << process->proc_args[0]; cout << endl; #endif #ifdef TRACE GetTime(t3); double t = Elapsed(t2, t3); if (t>max_t) { max_t = t; max_t_proc = process; } #endif } #ifdef TRACE GetTime(t1); cout << " total = " << Elapsed(t0, t1) << " ms" << endl; cout << " max: " << max_t << " for " << max_t_proc->name << " (" << max_t_proc->pid << ")" << endl; #endif } //============================================================= //============================================================= int ProcessData::get_server_pid(string argin) { omni_mutex_lock sync(*this); for (unsigned int i=0 ; iproc_args.empty()==false) { string servname(process->name); servname += "/"; servname += process->proc_args[0]; //cout << servname << "==" << argin << endl; if (servname == argin) return process->pid; } } return -1; } //============================================================= /** * Returs true if server running */ //============================================================= bool ProcessData::is_server_running(string argin) { omni_mutex_lock sync(*this); for (unsigned int i=0 ; iservname == argin) return true; } return false; } //============================================================= /** * Returs true if process running (do not check instance name) */ //============================================================= bool ProcessData::is_process_running(string argin) { omni_mutex_lock sync(*this); for (unsigned int i=0 ; iname == argin) return true; } return false; } //============================================================= //============================================================= vector ProcessData::get_process_list() { omni_mutex_lock sync(*this); // copy list vector ret; for (unsigned int i=0 ; iget_server_pid(argin); } //============================================================= /** * Returs true if server running */ //============================================================= bool CheckProcessUtil::is_server_running(string argin) { // Make sure instance is lower case string::size_type pos = argin.find('/'); if (pos==string::npos) return false; // Not a server name pos++; string dsname(argin.substr(0, pos)); #ifdef _TG_WINDOWS_ // Wain32 is case unsensitive transform(dsname.begin(), dsname.end(), dsname.begin(), ::tolower); #endif string instance(argin.substr(pos)); transform(instance.begin(), instance.end(), instance.begin(), ::tolower); dsname += instance; return data->is_server_running(dsname); } //============================================================= /** * Returs true if process running (do not check instance name) */ //============================================================= bool CheckProcessUtil::is_process_running(string argin) { return data->is_process_running(argin); } //============================================================= //============================================================= vector CheckProcessUtil::get_process_list() { return data->get_process_list(); } //============================================================= //============================================================= void *CheckProcessUtil::run_undetached(TANGO_UNUSED(void *ptr)) { while (stop_thread==false) { try { data->update_process_list(); } catch(Tango::DevFailed &e) { Tango::Except::print_exception(e); } // And wait n times for next loop for (int i=0 ; i<2 && stop_thread==false ; i++) { omni_mutex_lock sync(*data); data->wait(1000); } } delete data; return NULL; } //============================================================= //============================================================= } // namespace tango-9.2.5a/cppserver/starter/CheckProcessUtil.h0000644023471100065110000001017213034745014017010 00000000000000//============================================================================= // // file : CheckProcess.h // // description : Include for the CheckProcess class. // // project : Check Process // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= #ifndef _CHECKPROCESS_UTIL_H #define _CHECKPROCESS_UTIL_H #ifdef _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #endif #include #ifdef _TG_WINDOWS_ # include # include # include # include # include #else # include # include # include # include # include # include # include # if (!defined __GLIBC__) && (!defined __darwin__) && (!defined __freebsd__) /* solaris */ # include # include # endif #endif /** * @author $Author: pascal_verdier $ * @version $Revision: 28168 $ */ // Add your own constant definitions here. //----------------------------------------------- typedef struct { string line; string name; string servname; vector line_args; vector proc_args; long pid; } Process; #ifdef _TG_WINDOWS_ # include typedef LONG (NTAPI NTQIP) \ (HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); #endif namespace Starter_ns { //======================================================= //======================================================= class ProcessData: public Tango::TangoMonitor { private: vector proc_list; void read_process_list_from_sys(); bool check_java_process(Process* process); bool check_python_process(Process* process); void check_cpp_process(Process* process); void build_server_names(Process* process); string name_from_path(string full_name); #ifdef _TG_WINDOWS_ bool win2000; bool isWin2000(); string parseNameFromCmdLine(string name, string cmdline); PVOID getPebAddress(HANDLE pHandle); PVOID getPebStructure(HANDLE hProcess, PVOID pebAddress); UNICODE_STRING getUnicodeCommandLine(HANDLE hProcess, PVOID paramAddress); #else bool manageProcFiles(Process *process); #endif public: ProcessData(); ~ProcessData(); void update_process_list(); bool is_server_running(string argin); bool is_process_running(string argin); int get_server_pid(string argin); vector get_process_list(); #ifdef _TG_WINDOWS_ static string wchar2string(WCHAR *wch, int size=0x100); static WCHAR *string2wchar(string str); static string errorCodeToString(DWORD err_code, string src); #endif }; //======================================================= //======================================================= class CheckProcessUtil: public omni_thread { private: ProcessData *data; bool stop_thread; public: CheckProcessUtil() { data=new ProcessData(); stop_thread=false;}; bool is_server_running(string argin); bool is_process_running(string argin); int get_server_pid(string argin); vector get_process_list(); void stop_it() { stop_thread= true; }; /** * Execute the thread loop. */ void *run_undetached(void *); void start() {start_undetached();} }; } // namespace_ns #endif // _CHECKPROCESS_H tango-9.2.5a/cppserver/starter/PingThread.h0000644023471100065110000000627113034745014015630 00000000000000//============================================================================= // // file : StarterUtil.h // // description : Include for the StarterUtil class. // // project : Starter for Tango Administration // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= #ifndef _PING_THREAD_H #define _PING_THREAD_H #include #include /** * @author $Author: pascal_verdier $ * @version $Revision: 28168 $ */ /** * Class Description: * This class is a thread to ping server. */ namespace Starter_ns { //========================================================= /** * Shared data between DS and ping thread. */ //========================================================= class PingThreadData: public Tango::TangoMonitor { private: string servname; bool stop_thread; time_t last_write_time; Tango::DevState state; public: PingThreadData(string name); /** * Get the server name */ string get_server_name(); /** * command to stop thread */ void set_stop_thread(); /** * get stop thread status */ bool get_stop_thread(); /** * Get the last command time */ time_t get_last_write_time(); /** * Set the ping result */ void set_state(Tango::DevState st); /** * get the ping result */ Tango::DevState get_state(); /** * Force thread to update data. */ void wake_up(); }; //========================================================= /** * Create a thread to ping server. */ //========================================================= class PingThread: public omni_thread { private: /** * Shared data */ PingThreadData *shared; CheckProcessUtil *process_util; /** * The pinged server name */ string servname; public: /** * Create a thread to ping server * * @param shared pointer on shared data between thread and DS. * @param name The pinged server name * @param timeout timeout value in milliseconds for ping command. */ PingThread(PingThreadData *sd, string name, CheckProcessUtil *proc_util)\ {\ shared = sd; servname = name; process_util = proc_util;\ }; /** * Execute the thread loop. */ void *run_undetached(void *); void start() {start_undetached();} }; } // namespace #endif // _PING_THREAD_H tango-9.2.5a/cppserver/starter/StarterClass.h0000644023471100065110000003641613034745014016221 00000000000000/*----- PROTECTED REGION ID(StarterClass.h) ENABLED START -----*/ //============================================================================= // // file : StarterClass.h // // description : Include for the StarterClass root class. // This class is the singleton class for. // the Starter device class.. // It contains all properties and methods which the . // Starter requires only once e.g. the commands. // // project : Starter for Tango Administration. // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: pascal_verdier $ // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef STARTERCLASS_H #define STARTERCLASS_H #include #include /*----- PROTECTED REGION END -----*/ // StarterClass.h namespace Starter_ns { /*----- PROTECTED REGION ID(StarterClass::classes for dynamic creation) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // StarterClass::classes for dynamic creation //========================================= // Define classes for attributes //========================================= // Attribute NotifdState class definition class NotifdStateAttrib: public Tango::Attr { public: NotifdStateAttrib():Attr("NotifdState", Tango::DEV_STATE, Tango::READ) {}; ~NotifdStateAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_NotifdState(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_NotifdState_allowed(ty);} }; // Attribute HostState class definition class HostStateAttrib: public Tango::Attr { public: HostStateAttrib():Attr("HostState", Tango::DEV_SHORT, Tango::READ) {}; ~HostStateAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_HostState(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_HostState_allowed(ty);} }; // Attribute RunningServers class definition class RunningServersAttrib: public Tango::SpectrumAttr { public: RunningServersAttrib():SpectrumAttr("RunningServers", Tango::DEV_STRING, Tango::READ, 200) {}; ~RunningServersAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_RunningServers(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_RunningServers_allowed(ty);} }; // Attribute StoppedServers class definition class StoppedServersAttrib: public Tango::SpectrumAttr { public: StoppedServersAttrib():SpectrumAttr("StoppedServers", Tango::DEV_STRING, Tango::READ, 200) {}; ~StoppedServersAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_StoppedServers(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_StoppedServers_allowed(ty);} }; // Attribute Servers class definition class ServersAttrib: public Tango::SpectrumAttr { public: ServersAttrib():SpectrumAttr("Servers", Tango::DEV_STRING, Tango::READ, 1024) {}; ~ServersAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Servers(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Servers_allowed(ty);} }; //========================================= // Define classes for commands //========================================= // Command DevStart class definition class DevStartClass : public Tango::Command { public: DevStartClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevStartClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevStartClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevStart_allowed(any);} }; // Command DevStop class definition class DevStopClass : public Tango::Command { public: DevStopClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevStopClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevStopClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevStop_allowed(any);} }; // Command DevStartAll class definition class DevStartAllClass : public Tango::Command { public: DevStartAllClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevStartAllClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevStartAllClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevStartAll_allowed(any);} }; // Command DevStopAll class definition class DevStopAllClass : public Tango::Command { public: DevStopAllClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevStopAllClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevStopAllClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevStopAll_allowed(any);} }; // Command DevGetRunningServers class definition class DevGetRunningServersClass : public Tango::Command { public: DevGetRunningServersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevGetRunningServersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevGetRunningServersClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevGetRunningServers_allowed(any);} }; // Command DevGetStopServers class definition class DevGetStopServersClass : public Tango::Command { public: DevGetStopServersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevGetStopServersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevGetStopServersClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevGetStopServers_allowed(any);} }; // Command DevReadLog class definition class DevReadLogClass : public Tango::Command { public: DevReadLogClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevReadLogClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevReadLogClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevReadLog_allowed(any);} }; // Command HardKillServer class definition class HardKillServerClass : public Tango::Command { public: HardKillServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; HardKillServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~HardKillServerClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_HardKillServer_allowed(any);} }; // Command NotifyDaemonState class definition class NotifyDaemonStateClass : public Tango::Command { public: NotifyDaemonStateClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; NotifyDaemonStateClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~NotifyDaemonStateClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_NotifyDaemonState_allowed(any);} }; // Command ResetStatistics class definition class ResetStatisticsClass : public Tango::Command { public: ResetStatisticsClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; ResetStatisticsClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~ResetStatisticsClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_ResetStatistics_allowed(any);} }; // Command UpdateServersInfo class definition class UpdateServersInfoClass : public Tango::Command { public: UpdateServersInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; UpdateServersInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~UpdateServersInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_UpdateServersInfo_allowed(any);} }; /** * The StarterClass singleton definition */ #ifdef _TG_WINDOWS_ class __declspec(dllexport) StarterClass : public Tango::DeviceClass #else class StarterClass : public Tango::DeviceClass #endif { /*----- PROTECTED REGION ID(StarterClass::Additionnal DServer data members) ENABLED START -----*/ public: /*----- PROTECTED REGION END -----*/ // StarterClass::Additionnal DServer data members // Class properties data members public: // AutoRestartDuration: If this property is greater than 0, if a server has been running more than the specified value (in minutes), and has failed, it will be restart automaticly. Tango::DevLong autoRestartDuration; // LogFileHome: The home directory to log servers traces. // For Linux the default value is /var/tmp // For Win32 it is c:\temp string logFileHome; // NbStartupLevels: Number of startup levels managed by starter. Tango::DevShort nbStartupLevels; // ReadInfoDbPeriod: Period to read database for new info if not fired from Database server. Tango::DevShort readInfoDbPeriod; // ServerStartupTimeout: Timeout on device server startup in seconds. Tango::DevLong serverStartupTimeout; // StartServersAtStartup: Skip starting servers at startup if false. It a way to do not have a big re-start of many servers after a power cut. Tango::DevBoolean startServersAtStartup; // UseEvents: Use events if not null. Tango::DevShort useEvents; public: // write class properties data members Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static StarterClass *init(const char *); static StarterClass *instance(); ~StarterClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: StarterClass(string &); static StarterClass *_instance; void command_factory(); void attribute_factory(vector &); void write_class_property(); void set_default_property(); void get_class_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); void create_static_attribute_list(vector &); void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector &); vector defaultAttList; Tango::Attr *get_attr_object_by_name(vector &att_list, string attname); }; } // End of namespace #endif // Starter_H tango-9.2.5a/cppserver/starter/Starter.h0000644023471100065110000003601513034745014015226 00000000000000/*----- PROTECTED REGION ID(Starter.h) ENABLED START -----*/ //============================================================================= // // file : Starter.h // // description : Include for the Starter class. // // project : Starter for Tango Administration. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef STARTER_H #define STARTER_H #include #include #include #define PING_TIMEOUT 3 // seconds #define TIME_BETWEEN_STARTUPS 500 // Milli seconds #define NOTIFY_DAEMON_SCRIPT "notify_daemon" // Used onlyduring the Cpp Api bug fixing on // specAtt->get_max_x() method. #define NB_SERVERS_MAX 200 #define SERVER_TIMEOUT 30 // Timeout Minimum at server startup #ifdef _TG_WINDOWS_ # define LOG_HOME "c:\\temp" #else # define LOG_HOME "/var/tmp" #endif // Structure to difine a new process to start typedef struct { bool could_start; char *adminname; char *servname; char *instancename; char *logfile; } NewProcess; /*----- PROTECTED REGION END -----*/ // Starter.h /** * Starter class description: * This device server is able to control Tango components (database, device servers, clients...). * It is able to start or stop and to report the status of these components. */ namespace Starter_ns { /*----- PROTECTED REGION ID(Starter::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations class StartProcessShared; /*----- PROTECTED REGION END -----*/ // Starter::Additional Class Declarations class Starter : public TANGO_BASE_CLASS { /*----- PROTECTED REGION ID(Starter::Data Members) ENABLED START -----*/ // Add your own data members public: /** * Manage the PollingState object startup */ void manage_PollingState_startup(); /** * Start process thread Shared data */ StartProcessShared *start_proc_data; /** * StarterUtil instance to be used everywhere. */ StarterUtil *util; /** * Structures defining servers to be controlled */ vector servers; /** * Exception must be or not thrown. */ Tango::DevBoolean throwable; /** * Static string to be returned. */ string returned_str; /** * Database device (as DeviceProxy) for not implemented API commands. */ Tango::DeviceProxy *dbase; /** * Notify daemon State. */ Tango::DevState notifyd_state; /** * Is server list modification fired from DB ds. */ Tango::DevShort fireFromDbase; bool do_update_from_db; Tango::DevString dummyStringArray[1]; Tango::DevVarStringArray stringArrayRunning; Tango::DevVarStringArray stringArrayStopped; Tango::DevVarStringArray stringArrayServers; bool debug; /*----- PROTECTED REGION END -----*/ // Starter::Data Members // Device property data members public: // AutoRestartDuration: If this property is greater than 0, if a server has been running more than the specified value (in minutes), and has failed, it will be restart automaticly. Tango::DevLong autoRestartDuration; // InterStartupLevelWait: Time to wait before two startup levels in seconds. Tango::DevLong interStartupLevelWait; // KeepLogFiles: Number of log file kept. Tango::DevLong keepLogFiles; // LogFileHome: The home directory to log servers traces. // For Linux the default value is /var/tmp // For Win32 it is c:\temp string logFileHome; // ServerStartupTimeout: Timeout on device server startup in seconds. Tango::DevLong serverStartupTimeout; // StartDsPath: Path to find executable files // to start device servers vector startDsPath; // StartServersAtStartup: Skip starting servers at startup if false. Tango::DevBoolean startServersAtStartup; // UseEvents: Use events if not null. Tango::DevShort useEvents; // WaitForDriverStartup: The Starter will wait a bit before starting servers, to be sure than the drivers // are started.This time is in seconds. Tango::DevShort waitForDriverStartup; // Attribute data members public: Tango::DevState *attr_NotifdState_read; Tango::DevShort *attr_HostState_read; Tango::DevString *attr_RunningServers_read; Tango::DevString *attr_StoppedServers_read; Tango::DevString *attr_Servers_read; // Constructors and destructors public: /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ Starter(Tango::DeviceClass *cl,string &s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ Starter(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device name * @param d Device description. */ Starter(Tango::DeviceClass *cl,const char *s,const char *d); /** * The device object destructor. */ ~Starter() {delete_device();}; // Miscellaneous methods public: /* * will be called at device destruction or at init command. */ void delete_device(); /* * Initialize the device */ virtual void init_device(); /* * Read the device properties from database */ void get_device_property(); /* * Always executed method before execution command method. */ virtual void always_executed_hook(); // Attribute methods public: //-------------------------------------------------------- /* * Method : Starter::read_attr_hardware() * Description : Hardware acquisition for attributes. */ //-------------------------------------------------------- virtual void read_attr_hardware(vector &attr_list); /** * Attribute NotifdState related methods * Description: return ON or FAULT if notify daemon is running or not. * * Data type: Tango::DevState * Attr type: Scalar */ virtual void read_NotifdState(Tango::Attribute &attr); virtual bool is_NotifdState_allowed(Tango::AttReqType type); /** * Attribute HostState related methods * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ virtual void read_HostState(Tango::Attribute &attr); virtual bool is_HostState_allowed(Tango::AttReqType type); /** * Attribute RunningServers related methods * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 200 */ virtual void read_RunningServers(Tango::Attribute &attr); virtual bool is_RunningServers_allowed(Tango::AttReqType type); /** * Attribute StoppedServers related methods * Description: Return all the Stopped servers.\n * * Data type: Tango::DevString * Attr type: Spectrum max = 200 */ virtual void read_StoppedServers(Tango::Attribute &attr); virtual bool is_StoppedServers_allowed(Tango::AttReqType type); /** * Attribute Servers related methods * Description: Return all registred servers for this host.\nServer names are followed by their states and controls * * Data type: Tango::DevString * Attr type: Spectrum max = 1024 */ virtual void read_Servers(Tango::Attribute &attr); virtual bool is_Servers_allowed(Tango::AttReqType type); //-------------------------------------------------------- /** * Method : Starter::add_dynamic_attributes() * Description : Add dynamic attributes if any. */ //-------------------------------------------------------- void add_dynamic_attributes(); // Command related methods public: /** * Command State related method * Description: This command gets the device state (stored in its device_state data member) and returns it to the caller. * * @returns State Code */ virtual Tango::DevState dev_state(); /** * Command DevStart related method * Description: Start the specified server. * * @param argin Server to be started. */ virtual void dev_start(Tango::DevString argin); virtual bool is_DevStart_allowed(const CORBA::Any &any); /** * Command DevStop related method * Description: Stop the specified server. * * @param argin Servero be stopped. */ virtual void dev_stop(Tango::DevString argin); virtual bool is_DevStop_allowed(const CORBA::Any &any); /** * Command DevStartAll related method * Description: Start all device servers controled on the host for the argin level. * * @param argin Startup level. */ virtual void dev_start_all(Tango::DevShort argin); virtual bool is_DevStartAll_allowed(const CORBA::Any &any); /** * Command DevStopAll related method * Description: Stop all device servers controled on the host for the argin level. * * @param argin Startup Level. */ virtual void dev_stop_all(Tango::DevShort argin); virtual bool is_DevStopAll_allowed(const CORBA::Any &any); /** * Command DevGetRunningServers related method * Description: Control the running process from property list. * And return the list of the processes which are really running. * * @param argin True for all servers. False for controled servers only. * @returns List of the processes which are running. */ virtual Tango::DevVarStringArray *dev_get_running_servers(Tango::DevBoolean argin); virtual bool is_DevGetRunningServers_allowed(const CORBA::Any &any); /** * Command DevGetStopServers related method * Description: Control the running process from property list. * And return the list of the processes which are not running. * * @param argin True for all servers. False for controled servers only. * @returns List of the processes which are not running. */ virtual Tango::DevVarStringArray *dev_get_stop_servers(Tango::DevBoolean argin); virtual bool is_DevGetStopServers_allowed(const CORBA::Any &any); /** * Command DevReadLog related method * Description: At server startup, its standard error is redirected to a log file. * This command will read this file and return the read string from the file. * * @param argin server name and domain (e.g. Starter/corvus) * If argin ==``Starter`` -> return Starter logg file content. * If argin ==``Statistics`` -> return Starter statistics file content. * @returns String found in log file. */ virtual Tango::ConstDevString dev_read_log(Tango::DevString argin); virtual bool is_DevReadLog_allowed(const CORBA::Any &any); /** * Command HardKillServer related method * Description: Hard kill a server (kill -9) * * @param argin Server name */ virtual void hard_kill_server(Tango::DevString argin); virtual bool is_HardKillServer_allowed(const CORBA::Any &any); /** * Command NotifyDaemonState related method * Description: Returns the Notify Daemon state. * * @returns Tango::ON if Notify daemon is running else Tango::FAULT. */ virtual Tango::DevState notify_daemon_state(); virtual bool is_NotifyDaemonState_allowed(const CORBA::Any &any); /** * Command ResetStatistics related method * Description: Reset statistics file. * */ virtual void reset_statistics(); virtual bool is_ResetStatistics_allowed(const CORBA::Any &any); /** * Command UpdateServersInfo related method * Description: Indicate to the device server than the information about servers to be controlled has been modified. * The device server must read the database to update the servers info list. * If the default case, this command is sent by Database server itself. * */ virtual void update_servers_info(); virtual bool is_UpdateServersInfo_allowed(const CORBA::Any &any); /*----- PROTECTED REGION ID(Starter::Additional Method prototypes) ENABLED START -----*/ // Additional Method prototypes protected : /** * @name private methods prototypes */ //@{ /** * Allocate and fill the servers controlled object */ void build_server_ctrl_object(void); /** * Return how many servers to start for specified level. */ int nb_servers_to_start(int level); /** * Check if a process could be started (file exists, is not running, ...) */ NewProcess *processCouldStart(char *); /** * Start a thread to start processes */ void startProcesses(vector, int level); /** * check if instance and host name are coherent */ void check_host(); /** * check if log dir already exists (else create it */ void check_log_dir(); void manage_changing_state(ControlledServer *server, Tango::DevState previous_state); //@} /*----- PROTECTED REGION END -----*/ // Starter::Additional Method prototypes }; /*----- PROTECTED REGION ID(Starter::Additional Classes Definitions) ENABLED START -----*/ // Additional Classes definitions //========================================================= /** * Shared data between DS and StartProcess thread. */ //========================================================= class StartProcessShared: public Tango::TangoMonitor { private: /** * Manage levels thread * To be sure that (level) threads are not concurrent */ vector start_process_thread_levels; /** * Starter is MOVING (starting servers) when > 0; */ int starting_processes; public: StartProcessShared() {starting_processes=0;}; void push_back_level(int level); int get_current_level(); int get_starting_processes(); void remove_level(int level); bool level_is_still_active(int level); }; #ifdef _TG_WINDOWS_ class StartWinThread: public omni_thread { NewProcess *process; Starter *starter; public: StartWinThread(NewProcess* proc, Starter *st) { process = proc; starter=st;}; // Set the path between cotes for windows. string get_server_name_with_cotes(string servname); void run(void *); //void start() {start_undetached();} }; #endif //========================================================= /** * Create a thread to fork a sub-process (new device server) */ //========================================================= class StartProcessThread: public omni_thread { vector processes; Starter *starter; int thread_level; public: /** * Initialize the sub process parameters (name, domain, log_file). */ StartProcessThread(vector v_np, int level, Starter *st); /** * Execute the fork of the sub process in a thread. */ void run(void *); //void start() {start_undetached();} /** * Start one process */ void start_process(NewProcess *); }; /*----- PROTECTED REGION END -----*/ // Starter::Additional Classes Definitions } // End of namespace #endif // Starter_H tango-9.2.5a/cppserver/starter/StarterUtil.h0000644023471100065110000001513313034745014016062 00000000000000//============================================================================= // // file : StarterUtil.h // // description : Include for the StarterUtil class. // // project : Starter for Tango Administration // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28168 $ // $Date: 2015-06-30 09:27:09 +0200 (Tue, 30 Jun 2015) $ // //============================================================================= #ifndef _STARTER_UTIL_H #define _STARTER_UTIL_H #include #include #include #include /** * $Author: pascal_verdier $ * $Revision: 28168 $ */ /** * Class Description: * This class is a group of utility methods used by Starter Device Server. */ namespace Starter_ns { // Add your own constants definitions here. //----------------------------------------------- #ifndef _TG_WINDOWS_ typedef unsigned char boolean; #endif class ControlledServer { public: string name; string admin_name; bool controlled; short startup_level; PingThreadData *thread_data; PingThread *thread; Tango::DevState state; bool stopped; bool auto_start; time_t started_time; time_t failure_time; }; // Millisecond sleep platform independent. //-------------------------------------------- # ifdef _TG_WINDOWS_ # define ms_sleep(ms) _sleep(ms); # else # define ms_sleep(ms) {\ struct timespec ts; \ ts.tv_sec = ms / 1000; \ ts.tv_nsec = (ms - (ts.tv_sec * 1000)) * 1000000; \ nanosleep(&ts,NULL); \ } # endif // Definitions for separators //---------------------------------- #ifdef _TG_WINDOWS_ # define slash '\\' # define TmpRoot "c:\\temp" #else # define slash '/' # define TmpRoot "/var/tmp" #endif #define LogPath(s,home) \ s = home; \ s += slash; \ s += "ds.log"; #define STARTER_LOG_DEPTH 400 #define STARTER_STAT_DEPTH 2000 class Starter; class StarterUtil { public : string notifyd_name; string log_home; string starter_log_file; // History log file string starter_stat_file; // Statistics file CheckProcessUtil *proc_util; /** * the event channel factory used to test if notifd is alive. */ CosNotifyChannelAdmin::EventChannelFactory_var ch_factory; /** * @Constructor methods * Constructor methods */ //@{ /** * Default constructor. */ StarterUtil(Tango::DeviceProxy *dev, vector host_name, string logHome); //@} /** * @name methods * Tools methods */ //@{ /** * Extract server name from input parameter (servname/instance). */ string removeFQDN(string s); /** * Extract server name from input parameter (servname/instance). * * @param argin servname/instance */ char *get_server_name(char *argin); /** * Extract instance name from input parameter (servname/instance). * * @param argin servname/instance */ char *get_instance_name(char *argin); /** * Check if executable file exists * and return its full name with good path. * * @param servname Server name * @param fullpath Path from property */ char *check_exe_file(char *servname, vector v_path); char *check_exe_file(string filename); /** * Build the error log file name from server name and domain. * * @param server name of the server */ string build_log_file_name(char *); /** * Rename log file list * @param filename log file name */ vector get_log_file_list(string filename); /** * returns log file * @param filename file's name to get the date and rename. */ void manage_log_file_history(char *filename, int nb_max); /** * Get the last modification on a file and return it in a string. * @param filename file's name to get the date. */ char *get_file_date(char *filename); /** * Log info for starter. */ void log_starter_info(string message); /** * Log statistics for specified server obsevrved by starter.. */ void log_starter_statistics(ControlledServer *); /** * Resetstatistics for all servers. */ void reset_starter_stat_file(vector *servers); /** * Format the date and time in the argin value (Ux format) as string. */ char *strtime(time_t t); /** * search a server in ControlledServer array by it's name in an array. * * @param servname Server searched name. * @param servers Array of structure to search name. */ ControlledServer *get_server_by_name(string&, vector&); /** * Get host device servers list from database. * * @param dbase Database device as a DeviceProxy for not implemented API commands. * @param hostname Host's name to get the device servers list. */ vector get_host_ds_list(); /** * Read DS info from database to know if it is controlled * and it's starting level. * * @param devname device to get info. * @param server object to be updated from db read. */ void get_server_info(ControlledServer *); /** * Allocate and fill the servers controlled object */ void build_server_ctrl_object(vector *servers); /** * check if Notify Daemon is alive. */ Tango::DevState is_notifyd_alive(); void import_notifyd(); //@} private: static int elapsed; vector hostnames; /** * Database device (as DeviceProxy) for not implemented API commands. */ Tango::DeviceProxy *dbase; #ifndef _TG_WINDOWS_ static struct timeval before, after; #else #endif /* _TG_WINDOWS_ */ }; //========================================================= /** * Shared data between DS and thread. */ //========================================================= class SharedData: public Tango::TangoMonitor { private: time_t last_cmd_time; /** * Polling thread ID */ omni_thread *polling_id; public: SharedData(); /** * Get the last command time */ time_t get_timer(); /** * Set the last command time */ void set_timer(); }; } // namespace #endif // _STARTER_UTIL_H tango-9.2.5a/cppserver/tangotest/0000755023471100065110000000000013034745261014034 500000000000000tango-9.2.5a/cppserver/tangotest/README0000644023471100065110000000364613034745031014640 00000000000000//-============================================================ // // This class has been generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================= Files generated: =============== TangoTest.cpp: Source code for the TangoTest class and its commands. This class is derived from DeviceImpl_2 class. It represents the CORBA servant obbject which will be accessed from the network. All commands which can be executed on the TangoTest are implemented in this file. TangoTest.h: Include for the TangoTest class. Server class prototypes and descriptions. TangoTestClass.cpp: A singleton class derived fromTangoTest. It implements the command list and all properties and methods required by the TangoTest once per process TangoTestClass.h: Include for the TangoTestClass root class. This class is represents the singleton class for the TangoTest device class. It contains all properties and methods which the TangoTest requires only once e.g. the commands. main.cpp: C++ source for a TANGO device server main. The main rule is to initialise (and create) the Tango system and to create the DServerClass singleton. The main should be the same for every Tango device server. ClassFactory.cpp: C++ source for the class_factory method of the DServer device class. This method is responsible to create all class singletin for a device server. It is called at device server startup tango-9.2.5a/cppserver/tangotest/Makefile.am0000644023471100065110000000135113034745031016003 00000000000000 AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) bin_PROGRAMS=TangoTest TangoTest_SOURCES=ClassFactory.cpp \ TangoTestClass.cpp \ TangoTest.cpp \ TangoTestStateMachine.cpp \ main.cpp tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = TangoTestClass.h \ TangoTest.h tango-9.2.5a/cppserver/tangotest/Makefile.in0000644023471100065110000005707313034745121016030 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = TangoTest$(EXEEXT) subdir = cppserver/tangotest DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(tangoinclude_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(tangoincludedir)" PROGRAMS = $(bin_PROGRAMS) am_TangoTest_OBJECTS = ClassFactory.$(OBJEXT) TangoTestClass.$(OBJEXT) \ TangoTest.$(OBJEXT) TangoTestStateMachine.$(OBJEXT) \ main.$(OBJEXT) TangoTest_OBJECTS = $(am_TangoTest_OBJECTS) TangoTest_LDADD = $(LDADD) am__DEPENDENCIES_1 = TangoTest_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(TangoTest_SOURCES) DIST_SOURCES = $(TangoTest_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } HEADERS = $(tangoinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_builddir)/lib/cpp/log4tango/include $(LIBZMQ_CFLAGS) LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(LIBZMQ_LIBS) TangoTest_SOURCES = ClassFactory.cpp \ TangoTestClass.cpp \ TangoTest.cpp \ TangoTestStateMachine.cpp \ main.cpp tangoincludedir = $(includedir)/tango tangoinclude_HEADERS = TangoTestClass.h \ TangoTest.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/tangotest/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/tangotest/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list TangoTest$(EXEEXT): $(TangoTest_OBJECTS) $(TangoTest_DEPENDENCIES) $(EXTRA_TangoTest_DEPENDENCIES) @rm -f TangoTest$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TangoTest_OBJECTS) $(TangoTest_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClassFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoTestClass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoTestStateMachine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tangoincludeHEADERS: $(tangoinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(tangoincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(tangoincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(tangoincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(tangoincludedir)" || exit $$?; \ done uninstall-tangoincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(tangoinclude_HEADERS)'; test -n "$(tangoincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(tangoincludedir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(tangoincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-tangoincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-tangoincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip install-tangoincludeHEADERS installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-tangoincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/tangotest/TangoTestClass.h0000644023471100065110000016426613034745031017035 00000000000000/*----- PROTECTED REGION ID(TangoTestClass.h) ENABLED START -----*/ //============================================================================= // // file : TangoTestClass.h // // description : Include for the TangoTest root class. // This class is the singleton class for // the TangoTest device class. // It contains all properties and methods which the // TangoTest requires only once e.g. the commands. // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 28108 $ // $Date: 2015-06-24 14:29:54 +0200 (Wed, 24 Jun 2015) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef TangoTestClass_H #define TangoTestClass_H #include #include /*----- PROTECTED REGION END -----*/ // TangoTestClass.h namespace TangoTest_ns { /*----- PROTECTED REGION ID(TangoTestClass::classes for dynamic creation) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::classes for dynamic creation //========================================= // Define classes for attributes //========================================= // Attribute ampli class definition class ampliAttrib: public Tango::Attr { public: ampliAttrib():Attr("ampli", Tango::DEV_DOUBLE, Tango::WRITE) {}; ~ampliAttrib() {}; virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ampli(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ampli_allowed(ty);} }; // Attribute boolean_scalar class definition class boolean_scalarAttrib: public Tango::Attr { public: boolean_scalarAttrib():Attr("boolean_scalar", Tango::DEV_BOOLEAN, Tango::READ_WRITE) {}; ~boolean_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_boolean_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_boolean_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_boolean_scalar_allowed(ty);} }; // Attribute double_scalar class definition class double_scalarAttrib: public Tango::Attr { public: double_scalarAttrib():Attr("double_scalar", Tango::DEV_DOUBLE, Tango::READ_WRITE) {}; ~double_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_double_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_scalar_allowed(ty);} }; // Attribute double_scalar_rww class definition class double_scalar_rwwAttrib: public Tango::Attr { public: double_scalar_rwwAttrib():Attr("double_scalar_rww", Tango::DEV_DOUBLE, Tango::READ_WITH_WRITE, "double_scalar_w") {}; ~double_scalar_rwwAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_scalar_rww(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_double_scalar_rww(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_scalar_rww_allowed(ty);} }; // Attribute double_scalar_w class definition class double_scalar_wAttrib: public Tango::Attr { public: double_scalar_wAttrib():Attr("double_scalar_w", Tango::DEV_DOUBLE, Tango::WRITE) {}; ~double_scalar_wAttrib() {}; virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_double_scalar_w(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_scalar_w_allowed(ty);} }; // Attribute float_scalar class definition class float_scalarAttrib: public Tango::Attr { public: float_scalarAttrib():Attr("float_scalar", Tango::DEV_FLOAT, Tango::READ_WRITE) {}; ~float_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_float_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_float_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_float_scalar_allowed(ty);} }; // Attribute long64_scalar class definition class long64_scalarAttrib: public Tango::Attr { public: long64_scalarAttrib():Attr("long64_scalar", Tango::DEV_LONG64, Tango::READ_WRITE) {}; ~long64_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long64_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long64_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long64_scalar_allowed(ty);} }; // Attribute long_scalar class definition class long_scalarAttrib: public Tango::Attr { public: long_scalarAttrib():Attr("long_scalar", Tango::DEV_LONG, Tango::READ_WRITE) {}; ~long_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_scalar_allowed(ty);} }; // Attribute long_scalar_rww class definition class long_scalar_rwwAttrib: public Tango::Attr { public: long_scalar_rwwAttrib():Attr("long_scalar_rww", Tango::DEV_LONG, Tango::READ_WITH_WRITE, "long_scalar_w") {}; ~long_scalar_rwwAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_scalar_rww(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long_scalar_rww(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_scalar_rww_allowed(ty);} }; // Attribute long_scalar_w class definition class long_scalar_wAttrib: public Tango::Attr { public: long_scalar_wAttrib():Attr("long_scalar_w", Tango::DEV_LONG, Tango::WRITE) {}; ~long_scalar_wAttrib() {}; virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long_scalar_w(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_scalar_w_allowed(ty);} }; // Attribute no_value class definition class no_valueAttrib: public Tango::Attr { public: no_valueAttrib():Attr("no_value", Tango::DEV_LONG, Tango::READ) {}; ~no_valueAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_no_value(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_no_value_allowed(ty);} }; // Attribute short_scalar class definition class short_scalarAttrib: public Tango::Attr { public: short_scalarAttrib():Attr("short_scalar", Tango::DEV_SHORT, Tango::READ_WRITE) {}; ~short_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_short_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_scalar_allowed(ty);} }; // Attribute short_scalar_ro class definition class short_scalar_roAttrib: public Tango::Attr { public: short_scalar_roAttrib():Attr("short_scalar_ro", Tango::DEV_SHORT, Tango::READ) {}; ~short_scalar_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_scalar_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_scalar_ro_allowed(ty);} }; // Attribute short_scalar_rww class definition class short_scalar_rwwAttrib: public Tango::Attr { public: short_scalar_rwwAttrib():Attr("short_scalar_rww", Tango::DEV_SHORT, Tango::READ_WITH_WRITE, "short_scalar_w") {}; ~short_scalar_rwwAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_scalar_rww(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_short_scalar_rww(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_scalar_rww_allowed(ty);} }; // Attribute short_scalar_w class definition class short_scalar_wAttrib: public Tango::Attr { public: short_scalar_wAttrib():Attr("short_scalar_w", Tango::DEV_SHORT, Tango::WRITE) {}; ~short_scalar_wAttrib() {}; virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_short_scalar_w(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_scalar_w_allowed(ty);} }; // Attribute string_scalar class definition class string_scalarAttrib: public Tango::Attr { public: string_scalarAttrib():Attr("string_scalar", Tango::DEV_STRING, Tango::READ_WRITE) {}; ~string_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_string_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_string_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_string_scalar_allowed(ty);} }; // Attribute throw_exception class definition class throw_exceptionAttrib: public Tango::Attr { public: throw_exceptionAttrib():Attr("throw_exception", Tango::DEV_LONG, Tango::READ) {}; ~throw_exceptionAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_throw_exception(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_throw_exception_allowed(ty);} }; // Attribute uchar_scalar class definition class uchar_scalarAttrib: public Tango::Attr { public: uchar_scalarAttrib():Attr("uchar_scalar", Tango::DEV_UCHAR, Tango::READ_WRITE) {}; ~uchar_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_uchar_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_uchar_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_uchar_scalar_allowed(ty);} }; // Attribute ulong64_scalar class definition class ulong64_scalarAttrib: public Tango::Attr { public: ulong64_scalarAttrib():Attr("ulong64_scalar", Tango::DEV_ULONG64, Tango::READ_WRITE) {}; ~ulong64_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong64_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ulong64_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong64_scalar_allowed(ty);} }; // Attribute ushort_scalar class definition class ushort_scalarAttrib: public Tango::Attr { public: ushort_scalarAttrib():Attr("ushort_scalar", Tango::DEV_USHORT, Tango::READ_WRITE) {}; ~ushort_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ushort_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ushort_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ushort_scalar_allowed(ty);} }; // Attribute ulong_scalar class definition class ulong_scalarAttrib: public Tango::Attr { public: ulong_scalarAttrib():Attr("ulong_scalar", Tango::DEV_ULONG, Tango::READ_WRITE) {}; ~ulong_scalarAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong_scalar(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ulong_scalar(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong_scalar_allowed(ty);} }; // Attribute boolean_spectrum class definition class boolean_spectrumAttrib: public Tango::SpectrumAttr { public: boolean_spectrumAttrib():SpectrumAttr("boolean_spectrum", Tango::DEV_BOOLEAN, Tango::READ_WRITE, 4096) {}; ~boolean_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_boolean_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_boolean_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_boolean_spectrum_allowed(ty);} }; // Attribute boolean_spectrum_ro class definition class boolean_spectrum_roAttrib: public Tango::SpectrumAttr { public: boolean_spectrum_roAttrib():SpectrumAttr("boolean_spectrum_ro", Tango::DEV_BOOLEAN, Tango::READ, 4096) {}; ~boolean_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_boolean_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_boolean_spectrum_ro_allowed(ty);} }; // Attribute double_spectrum class definition class double_spectrumAttrib: public Tango::SpectrumAttr { public: double_spectrumAttrib():SpectrumAttr("double_spectrum", Tango::DEV_DOUBLE, Tango::READ_WRITE, 4096) {}; ~double_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_double_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_spectrum_allowed(ty);} }; // Attribute double_spectrum_ro class definition class double_spectrum_roAttrib: public Tango::SpectrumAttr { public: double_spectrum_roAttrib():SpectrumAttr("double_spectrum_ro", Tango::DEV_DOUBLE, Tango::READ, 4096) {}; ~double_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_spectrum_ro_allowed(ty);} }; // Attribute float_spectrum class definition class float_spectrumAttrib: public Tango::SpectrumAttr { public: float_spectrumAttrib():SpectrumAttr("float_spectrum", Tango::DEV_FLOAT, Tango::READ_WRITE, 4096) {}; ~float_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_float_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_float_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_float_spectrum_allowed(ty);} }; // Attribute float_spectrum_ro class definition class float_spectrum_roAttrib: public Tango::SpectrumAttr { public: float_spectrum_roAttrib():SpectrumAttr("float_spectrum_ro", Tango::DEV_FLOAT, Tango::READ, 4096) {}; ~float_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_float_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_float_spectrum_ro_allowed(ty);} }; // Attribute long64_spectrum_ro class definition class long64_spectrum_roAttrib: public Tango::SpectrumAttr { public: long64_spectrum_roAttrib():SpectrumAttr("long64_spectrum_ro", Tango::DEV_LONG64, Tango::READ, 4096) {}; ~long64_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long64_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long64_spectrum_ro_allowed(ty);} }; // Attribute long_spectrum class definition class long_spectrumAttrib: public Tango::SpectrumAttr { public: long_spectrumAttrib():SpectrumAttr("long_spectrum", Tango::DEV_LONG, Tango::READ_WRITE, 4096) {}; ~long_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_spectrum_allowed(ty);} }; // Attribute long_spectrum_ro class definition class long_spectrum_roAttrib: public Tango::SpectrumAttr { public: long_spectrum_roAttrib():SpectrumAttr("long_spectrum_ro", Tango::DEV_LONG, Tango::READ, 4096) {}; ~long_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_spectrum_ro_allowed(ty);} }; // Attribute short_spectrum class definition class short_spectrumAttrib: public Tango::SpectrumAttr { public: short_spectrumAttrib():SpectrumAttr("short_spectrum", Tango::DEV_SHORT, Tango::READ_WRITE, 4096) {}; ~short_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_short_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_spectrum_allowed(ty);} }; // Attribute short_spectrum_ro class definition class short_spectrum_roAttrib: public Tango::SpectrumAttr { public: short_spectrum_roAttrib():SpectrumAttr("short_spectrum_ro", Tango::DEV_SHORT, Tango::READ, 4096) {}; ~short_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_spectrum_ro_allowed(ty);} }; // Attribute string_spectrum class definition class string_spectrumAttrib: public Tango::SpectrumAttr { public: string_spectrumAttrib():SpectrumAttr("string_spectrum", Tango::DEV_STRING, Tango::READ_WRITE, 256) {}; ~string_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_string_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_string_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_string_spectrum_allowed(ty);} }; // Attribute string_spectrum_ro class definition class string_spectrum_roAttrib: public Tango::SpectrumAttr { public: string_spectrum_roAttrib():SpectrumAttr("string_spectrum_ro", Tango::DEV_STRING, Tango::READ, 256) {}; ~string_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_string_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_string_spectrum_ro_allowed(ty);} }; // Attribute uchar_spectrum class definition class uchar_spectrumAttrib: public Tango::SpectrumAttr { public: uchar_spectrumAttrib():SpectrumAttr("uchar_spectrum", Tango::DEV_UCHAR, Tango::READ_WRITE, 4096) {}; ~uchar_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_uchar_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_uchar_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_uchar_spectrum_allowed(ty);} }; // Attribute uchar_spectrum_ro class definition class uchar_spectrum_roAttrib: public Tango::SpectrumAttr { public: uchar_spectrum_roAttrib():SpectrumAttr("uchar_spectrum_ro", Tango::DEV_UCHAR, Tango::READ, 4096) {}; ~uchar_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_uchar_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_uchar_spectrum_ro_allowed(ty);} }; // Attribute ulong64_spectrum_ro class definition class ulong64_spectrum_roAttrib: public Tango::SpectrumAttr { public: ulong64_spectrum_roAttrib():SpectrumAttr("ulong64_spectrum_ro", Tango::DEV_ULONG64, Tango::READ, 4096) {}; ~ulong64_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong64_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong64_spectrum_ro_allowed(ty);} }; // Attribute ulong_spectrum_ro class definition class ulong_spectrum_roAttrib: public Tango::SpectrumAttr { public: ulong_spectrum_roAttrib():SpectrumAttr("ulong_spectrum_ro", Tango::DEV_ULONG, Tango::READ, 4096) {}; ~ulong_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong_spectrum_ro_allowed(ty);} }; // Attribute ushort_spectrum class definition class ushort_spectrumAttrib: public Tango::SpectrumAttr { public: ushort_spectrumAttrib():SpectrumAttr("ushort_spectrum", Tango::DEV_USHORT, Tango::READ_WRITE, 4096) {}; ~ushort_spectrumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ushort_spectrum(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ushort_spectrum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ushort_spectrum_allowed(ty);} }; // Attribute ushort_spectrum_ro class definition class ushort_spectrum_roAttrib: public Tango::SpectrumAttr { public: ushort_spectrum_roAttrib():SpectrumAttr("ushort_spectrum_ro", Tango::DEV_USHORT, Tango::READ, 4096) {}; ~ushort_spectrum_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ushort_spectrum_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ushort_spectrum_ro_allowed(ty);} }; // Attribute wave class definition class waveAttrib: public Tango::SpectrumAttr { public: waveAttrib():SpectrumAttr("wave", Tango::DEV_DOUBLE, Tango::READ, 4096) {}; ~waveAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_wave(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_wave_allowed(ty);} }; // Attribute boolean_image class definition class boolean_imageAttrib: public Tango::ImageAttr { public: boolean_imageAttrib():ImageAttr("boolean_image", Tango::DEV_BOOLEAN, Tango::READ_WRITE, 251, 251) {}; ~boolean_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_boolean_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_boolean_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_boolean_image_allowed(ty);} }; // Attribute boolean_image_ro class definition class boolean_image_roAttrib: public Tango::ImageAttr { public: boolean_image_roAttrib():ImageAttr("boolean_image_ro", Tango::DEV_BOOLEAN, Tango::READ, 251, 251) {}; ~boolean_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_boolean_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_boolean_image_ro_allowed(ty);} }; // Attribute double_image class definition class double_imageAttrib: public Tango::ImageAttr { public: double_imageAttrib():ImageAttr("double_image", Tango::DEV_DOUBLE, Tango::READ_WRITE, 251, 251) {}; ~double_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_double_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_image_allowed(ty);} }; // Attribute double_image_ro class definition class double_image_roAttrib: public Tango::ImageAttr { public: double_image_roAttrib():ImageAttr("double_image_ro", Tango::DEV_DOUBLE, Tango::READ, 251, 251) {}; ~double_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_double_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_double_image_ro_allowed(ty);} }; // Attribute float_image class definition class float_imageAttrib: public Tango::ImageAttr { public: float_imageAttrib():ImageAttr("float_image", Tango::DEV_FLOAT, Tango::READ_WRITE, 251, 251) {}; ~float_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_float_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_float_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_float_image_allowed(ty);} }; // Attribute float_image_ro class definition class float_image_roAttrib: public Tango::ImageAttr { public: float_image_roAttrib():ImageAttr("float_image_ro", Tango::DEV_FLOAT, Tango::READ, 251, 251) {}; ~float_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_float_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_float_image_ro_allowed(ty);} }; // Attribute long64_image_ro class definition class long64_image_roAttrib: public Tango::ImageAttr { public: long64_image_roAttrib():ImageAttr("long64_image_ro", Tango::DEV_LONG64, Tango::READ, 251, 251) {}; ~long64_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long64_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long64_image_ro_allowed(ty);} }; // Attribute long_image class definition class long_imageAttrib: public Tango::ImageAttr { public: long_imageAttrib():ImageAttr("long_image", Tango::DEV_LONG, Tango::READ_WRITE, 251, 251) {}; ~long_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_long_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_image_allowed(ty);} }; // Attribute long_image_ro class definition class long_image_roAttrib: public Tango::ImageAttr { public: long_image_roAttrib():ImageAttr("long_image_ro", Tango::DEV_LONG, Tango::READ, 251, 251) {}; ~long_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_long_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_long_image_ro_allowed(ty);} }; // Attribute short_image class definition class short_imageAttrib: public Tango::ImageAttr { public: short_imageAttrib():ImageAttr("short_image", Tango::DEV_SHORT, Tango::READ_WRITE, 251, 251) {}; ~short_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_short_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_image_allowed(ty);} }; // Attribute short_image_ro class definition class short_image_roAttrib: public Tango::ImageAttr { public: short_image_roAttrib():ImageAttr("short_image_ro", Tango::DEV_SHORT, Tango::READ, 251, 251) {}; ~short_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_short_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_short_image_ro_allowed(ty);} }; // Attribute string_image class definition class string_imageAttrib: public Tango::ImageAttr { public: string_imageAttrib():ImageAttr("string_image", Tango::DEV_STRING, Tango::READ_WRITE, 256, 256) {}; ~string_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_string_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_string_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_string_image_allowed(ty);} }; // Attribute string_image_ro class definition class string_image_roAttrib: public Tango::ImageAttr { public: string_image_roAttrib():ImageAttr("string_image_ro", Tango::DEV_STRING, Tango::READ, 256, 256) {}; ~string_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_string_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_string_image_ro_allowed(ty);} }; // Attribute uchar_image class definition class uchar_imageAttrib: public Tango::ImageAttr { public: uchar_imageAttrib():ImageAttr("uchar_image", Tango::DEV_UCHAR, Tango::READ_WRITE, 251, 251) {}; ~uchar_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_uchar_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_uchar_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_uchar_image_allowed(ty);} }; // Attribute uchar_image_ro class definition class uchar_image_roAttrib: public Tango::ImageAttr { public: uchar_image_roAttrib():ImageAttr("uchar_image_ro", Tango::DEV_UCHAR, Tango::READ, 251, 251) {}; ~uchar_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_uchar_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_uchar_image_ro_allowed(ty);} }; // Attribute ulong64_image_ro class definition class ulong64_image_roAttrib: public Tango::ImageAttr { public: ulong64_image_roAttrib():ImageAttr("ulong64_image_ro", Tango::DEV_ULONG64, Tango::READ, 251, 251) {}; ~ulong64_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong64_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong64_image_ro_allowed(ty);} }; // Attribute ulong_image_ro class definition class ulong_image_roAttrib: public Tango::ImageAttr { public: ulong_image_roAttrib():ImageAttr("ulong_image_ro", Tango::DEV_ULONG, Tango::READ, 251, 251) {}; ~ulong_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ulong_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ulong_image_ro_allowed(ty);} }; // Attribute ushort_image class definition class ushort_imageAttrib: public Tango::ImageAttr { public: ushort_imageAttrib():ImageAttr("ushort_image", Tango::DEV_USHORT, Tango::READ_WRITE, 251, 251) {}; ~ushort_imageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ushort_image(att);} virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) {(static_cast(dev))->write_ushort_image(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ushort_image_allowed(ty);} }; // Attribute ushort_image_ro class definition class ushort_image_roAttrib: public Tango::ImageAttr { public: ushort_image_roAttrib():ImageAttr("ushort_image_ro", Tango::DEV_USHORT, Tango::READ, 8192, 8192) {}; ~ushort_image_roAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_ushort_image_ro(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_ushort_image_ro_allowed(ty);} }; //========================================= // Define classes for pipes //========================================= // Pipe string_long_short_ro class definition class string_long_short_roClass: public Tango::Pipe { public: string_long_short_roClass(const string &name, Tango::DispLevel level) :Pipe(name, level) {}; ~string_long_short_roClass() {}; virtual bool is_allowed (Tango::DeviceImpl *dev,Tango::PipeReqType _prt) {return (static_cast(dev))->is_string_long_short_ro_allowed(_prt);} virtual void read(Tango::DeviceImpl *dev) {(static_cast(dev))->read_string_long_short_ro(*this);} }; //========================================= // Define classes for commands //========================================= // Command CrashFromDevelopperThread class definition class CrashFromDevelopperThreadClass : public Tango::Command { public: CrashFromDevelopperThreadClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; CrashFromDevelopperThreadClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~CrashFromDevelopperThreadClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_CrashFromDevelopperThread_allowed(any);} }; // Command CrashFromOmniThread class definition class CrashFromOmniThreadClass : public Tango::Command { public: CrashFromOmniThreadClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; CrashFromOmniThreadClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~CrashFromOmniThreadClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_CrashFromOmniThread_allowed(any);} }; // Command DevBoolean class definition class DevBooleanClass : public Tango::Command { public: DevBooleanClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevBooleanClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevBooleanClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevBoolean_allowed(any);} }; // Command DevDouble class definition class DevDoubleClass : public Tango::Command { public: DevDoubleClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevDoubleClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevDoubleClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevDouble_allowed(any);} }; // Command DevFloat class definition class DevFloatClass : public Tango::Command { public: DevFloatClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevFloatClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevFloatClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevFloat_allowed(any);} }; // Command DevLong class definition class DevLongClass : public Tango::Command { public: DevLongClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevLongClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevLongClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevLong_allowed(any);} }; // Command DevLong64 class definition class DevLong64Class : public Tango::Command { public: DevLong64Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevLong64Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevLong64Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevLong64_allowed(any);} }; // Command DevShort class definition class DevShortClass : public Tango::Command { public: DevShortClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevShortClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevShortClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevShort_allowed(any);} }; // Command DevString class definition class DevStringClass : public Tango::Command { public: DevStringClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevStringClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevStringClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevString_allowed(any);} }; // Command DevULong class definition class DevULongClass : public Tango::Command { public: DevULongClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevULongClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevULongClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevULong_allowed(any);} }; // Command DevULong64 class definition class DevULong64Class : public Tango::Command { public: DevULong64Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevULong64Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevULong64Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevULong64_allowed(any);} }; // Command DevUShort class definition class DevUShortClass : public Tango::Command { public: DevUShortClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevUShortClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevUShortClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevUShort_allowed(any);} }; // Command DevVarCharArray class definition class DevVarCharArrayClass : public Tango::Command { public: DevVarCharArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarCharArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarCharArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarCharArray_allowed(any);} }; // Command DevVarDoubleArray class definition class DevVarDoubleArrayClass : public Tango::Command { public: DevVarDoubleArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarDoubleArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarDoubleArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarDoubleArray_allowed(any);} }; // Command DevVarDoubleStringArray class definition class DevVarDoubleStringArrayClass : public Tango::Command { public: DevVarDoubleStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarDoubleStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarDoubleStringArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarDoubleStringArray_allowed(any);} }; // Command DevVarFloatArray class definition class DevVarFloatArrayClass : public Tango::Command { public: DevVarFloatArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarFloatArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarFloatArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarFloatArray_allowed(any);} }; // Command DevVarLong64Array class definition class DevVarLong64ArrayClass : public Tango::Command { public: DevVarLong64ArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarLong64ArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarLong64ArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarLong64Array_allowed(any);} }; // Command DevVarLongArray class definition class DevVarLongArrayClass : public Tango::Command { public: DevVarLongArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarLongArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarLongArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarLongArray_allowed(any);} }; // Command DevVarLongStringArray class definition class DevVarLongStringArrayClass : public Tango::Command { public: DevVarLongStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarLongStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarLongStringArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarLongStringArray_allowed(any);} }; // Command DevVarShortArray class definition class DevVarShortArrayClass : public Tango::Command { public: DevVarShortArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarShortArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarShortArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarShortArray_allowed(any);} }; // Command DevVarStringArray class definition class DevVarStringArrayClass : public Tango::Command { public: DevVarStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarStringArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarStringArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarStringArray_allowed(any);} }; // Command DevVarULong64Array class definition class DevVarULong64ArrayClass : public Tango::Command { public: DevVarULong64ArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarULong64ArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarULong64ArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarULong64Array_allowed(any);} }; // Command DevVarULongArray class definition class DevVarULongArrayClass : public Tango::Command { public: DevVarULongArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarULongArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarULongArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarULongArray_allowed(any);} }; // Command DevVarUShortArray class definition class DevVarUShortArrayClass : public Tango::Command { public: DevVarUShortArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVarUShortArrayClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVarUShortArrayClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVarUShortArray_allowed(any);} }; // Command DevVoid class definition class DevVoidClass : public Tango::Command { public: DevVoidClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DevVoidClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DevVoidClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DevVoid_allowed(any);} }; // Command DumpExecutionState class definition class DumpExecutionStateClass : public Tango::Command { public: DumpExecutionStateClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DumpExecutionStateClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DumpExecutionStateClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DumpExecutionState_allowed(any);} }; // Command SwitchStates class definition class SwitchStatesClass : public Tango::Command { public: SwitchStatesClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; SwitchStatesClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~SwitchStatesClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_SwitchStates_allowed(any);} }; /** * The TangoTestClass singleton definition */ #ifdef _TG_WINDOWS_ class __declspec(dllexport) TangoTestClass : public Tango::DeviceClass #else class TangoTestClass : public Tango::DeviceClass #endif { /*----- PROTECTED REGION ID(TangoTestClass::Additionnal DServer data members) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::Additionnal DServer data members public: // write class properties data members Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static TangoTestClass *init(const char *); static TangoTestClass *instance(); ~TangoTestClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: TangoTestClass(string &); static TangoTestClass *_instance; void command_factory(); void attribute_factory(vector &); void pipe_factory(); void write_class_property(); void set_default_property(); void get_class_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); void create_static_attribute_list(vector &); void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector &); vector defaultAttList; Tango::Attr *get_attr_object_by_name(vector &att_list, string attname); }; } // End of namespace #endif // TangoTest_H tango-9.2.5a/cppserver/tangotest/TangoTest.h0000644023471100065110000010403213034745031016030 00000000000000/*----- PROTECTED REGION ID(TangoTest.h) ENABLED START -----*/ //============================================================================= // // file : TangoTest.h // // description : Include file for the TangoTest class // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 28143 $ // $Date: 2015-06-26 14:30:53 +0200 (Fri, 26 Jun 2015) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef TangoTest_H #define TangoTest_H #include #ifndef TANGO_UNUSED #ifdef _TG_WINDOWS_ #define TANGO_UNUSED(var) var #else #if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #elif __GNUC__ > 3 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #else #define TANGO_UNUSED(var) var #endif #endif #endif /*----- PROTECTED REGION END -----*/ // TangoTest.h /** * TangoTest class description: * A device to test generic clients. It offers a \"echo\" like command for * each TANGO data type (i.e. each command returns an exact copy of ). */ namespace TangoTest_ns { /*----- PROTECTED REGION ID(TangoTest::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations class DataGenerator; } namespace TangoTest_ns { /*----- PROTECTED REGION END -----*/ // TangoTest::Additional Class Declarations class TangoTest : public TANGO_BASE_CLASS { /*----- PROTECTED REGION ID(TangoTest::Data Members) ENABLED START -----*/ // Add your own data members public: friend class DataGenerator; Tango::DevShort attr_short_scalar_w_write; Tango::DevLong attr_long_scalar_w_write; Tango::DevDouble attr_double_scalar_w_write; Tango::DevShort attr_short_scalar_write; Tango::DevLong attr_long_scalar_write; Tango::DevDouble attr_double_scalar_write; Tango::DevFloat attr_float_scalar_write; Tango::DevULong attr_ulong_scalar_write; Tango::DevUShort attr_ushort_scalar_write; Tango::DevUChar attr_uchar_scalar_write; Tango::DevDouble attr_ampli_write; Tango::DevLong64 attr_long64_scalar_write; Tango::DevULong64 attr_ulong64_scalar_write; Tango::DevString attr_string_scalar_write; Tango::DevBoolean attr_boolean_scalar_write; Tango::DevString attr_string_spectrum_write; Tango::DevString attr_string_image_write; string pi_str; Tango::DevLong pi_long; Tango::DevShort pi_short; /*----- PROTECTED REGION END -----*/ // TangoTest::Data Members // Device property data members public: // Mthreaded_impl: Multi-threaded implementation (true/false Tango::DevShort mthreaded_impl; // Sleep_period: Data generation period (in ms Tango::DevLong sleep_period; // UShort_image_ro_size: Size of the ushort_image_ro attribute Tango::DevLong uShort_image_ro_size; // Attribute data members public: Tango::DevBoolean *attr_boolean_scalar_read; Tango::DevDouble *attr_double_scalar_read; Tango::DevDouble *attr_double_scalar_rww_read; Tango::DevFloat *attr_float_scalar_read; Tango::DevLong64 *attr_long64_scalar_read; Tango::DevLong *attr_long_scalar_read; Tango::DevLong *attr_long_scalar_rww_read; Tango::DevLong *attr_no_value_read; Tango::DevShort *attr_short_scalar_read; Tango::DevShort *attr_short_scalar_ro_read; Tango::DevShort *attr_short_scalar_rww_read; Tango::DevString *attr_string_scalar_read; Tango::DevLong *attr_throw_exception_read; Tango::DevUChar *attr_uchar_scalar_read; Tango::DevULong64 *attr_ulong64_scalar_read; Tango::DevUShort *attr_ushort_scalar_read; Tango::DevULong *attr_ulong_scalar_read; Tango::DevBoolean *attr_boolean_spectrum_read; Tango::DevBoolean *attr_boolean_spectrum_ro_read; Tango::DevDouble *attr_double_spectrum_read; Tango::DevDouble *attr_double_spectrum_ro_read; Tango::DevFloat *attr_float_spectrum_read; Tango::DevFloat *attr_float_spectrum_ro_read; Tango::DevLong64 *attr_long64_spectrum_ro_read; Tango::DevLong *attr_long_spectrum_read; Tango::DevLong *attr_long_spectrum_ro_read; Tango::DevShort *attr_short_spectrum_read; Tango::DevShort *attr_short_spectrum_ro_read; Tango::DevString *attr_string_spectrum_read; Tango::DevString *attr_string_spectrum_ro_read; Tango::DevUChar *attr_uchar_spectrum_read; Tango::DevUChar *attr_uchar_spectrum_ro_read; Tango::DevULong64 *attr_ulong64_spectrum_ro_read; Tango::DevULong *attr_ulong_spectrum_ro_read; Tango::DevUShort *attr_ushort_spectrum_read; Tango::DevUShort *attr_ushort_spectrum_ro_read; Tango::DevDouble *attr_wave_read; Tango::DevBoolean *attr_boolean_image_read; Tango::DevBoolean *attr_boolean_image_ro_read; Tango::DevDouble *attr_double_image_read; Tango::DevDouble *attr_double_image_ro_read; Tango::DevFloat *attr_float_image_read; Tango::DevFloat *attr_float_image_ro_read; Tango::DevLong64 *attr_long64_image_ro_read; Tango::DevLong *attr_long_image_read; Tango::DevLong *attr_long_image_ro_read; Tango::DevShort *attr_short_image_read; Tango::DevShort *attr_short_image_ro_read; Tango::DevString *attr_string_image_read; Tango::DevString *attr_string_image_ro_read; Tango::DevUChar *attr_uchar_image_read; Tango::DevUChar *attr_uchar_image_ro_read; Tango::DevULong64 *attr_ulong64_image_ro_read; Tango::DevULong *attr_ulong_image_ro_read; Tango::DevUShort *attr_ushort_image_read; Tango::DevUShort *attr_ushort_image_ro_read; // Constructors and destructors public: /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ TangoTest(Tango::DeviceClass *cl,string &s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ TangoTest(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device name * @param d Device description. */ TangoTest(Tango::DeviceClass *cl,const char *s,const char *d); /** * The device object destructor. */ ~TangoTest() {delete_device();}; // Miscellaneous methods public: /* * will be called at device destruction or at init command. */ void delete_device(); /* * Initialize the device */ virtual void init_device(); /* * Read the device properties from database */ void get_device_property(); /* * Always executed method before execution command method. */ virtual void always_executed_hook(); // Attribute methods public: //-------------------------------------------------------- /* * Method : TangoTest::read_attr_hardware() * Description : Hardware acquisition for attributes. */ //-------------------------------------------------------- virtual void read_attr_hardware(vector &attr_list); //-------------------------------------------------------- /* * Method : TangoTest::write_attr_hardware() * Description : Hardware writing for attributes. */ //-------------------------------------------------------- virtual void write_attr_hardware(vector &attr_list); /** * Attribute ampli related methods * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ virtual void write_ampli(Tango::WAttribute &attr); virtual bool is_ampli_allowed(Tango::AttReqType type); /** * Attribute boolean_scalar related methods * Description: A boolean scalar attribute * * Data type: Tango::DevBoolean * Attr type: Scalar */ virtual void read_boolean_scalar(Tango::Attribute &attr); virtual void write_boolean_scalar(Tango::WAttribute &attr); virtual bool is_boolean_scalar_allowed(Tango::AttReqType type); /** * Attribute double_scalar related methods * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ virtual void read_double_scalar(Tango::Attribute &attr); virtual void write_double_scalar(Tango::WAttribute &attr); virtual bool is_double_scalar_allowed(Tango::AttReqType type); /** * Attribute double_scalar_rww related methods * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ virtual void read_double_scalar_rww(Tango::Attribute &attr); virtual void write_double_scalar_rww(Tango::WAttribute &attr); virtual bool is_double_scalar_rww_allowed(Tango::AttReqType type); /** * Attribute double_scalar_w related methods * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ virtual void write_double_scalar_w(Tango::WAttribute &attr); virtual bool is_double_scalar_w_allowed(Tango::AttReqType type); /** * Attribute float_scalar related methods * Description: A float attribute * * Data type: Tango::DevFloat * Attr type: Scalar */ virtual void read_float_scalar(Tango::Attribute &attr); virtual void write_float_scalar(Tango::WAttribute &attr); virtual bool is_float_scalar_allowed(Tango::AttReqType type); /** * Attribute long64_scalar related methods * Description: * * Data type: Tango::DevLong64 * Attr type: Scalar */ virtual void read_long64_scalar(Tango::Attribute &attr); virtual void write_long64_scalar(Tango::WAttribute &attr); virtual bool is_long64_scalar_allowed(Tango::AttReqType type); /** * Attribute long_scalar related methods * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ virtual void read_long_scalar(Tango::Attribute &attr); virtual void write_long_scalar(Tango::WAttribute &attr); virtual bool is_long_scalar_allowed(Tango::AttReqType type); /** * Attribute long_scalar_rww related methods * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ virtual void read_long_scalar_rww(Tango::Attribute &attr); virtual void write_long_scalar_rww(Tango::WAttribute &attr); virtual bool is_long_scalar_rww_allowed(Tango::AttReqType type); /** * Attribute long_scalar_w related methods * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ virtual void write_long_scalar_w(Tango::WAttribute &attr); virtual bool is_long_scalar_w_allowed(Tango::AttReqType type); /** * Attribute no_value related methods * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ virtual void read_no_value(Tango::Attribute &attr); virtual bool is_no_value_allowed(Tango::AttReqType type); /** * Attribute short_scalar related methods * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ virtual void read_short_scalar(Tango::Attribute &attr); virtual void write_short_scalar(Tango::WAttribute &attr); virtual bool is_short_scalar_allowed(Tango::AttReqType type); /** * Attribute short_scalar_ro related methods * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ virtual void read_short_scalar_ro(Tango::Attribute &attr); virtual bool is_short_scalar_ro_allowed(Tango::AttReqType type); /** * Attribute short_scalar_rww related methods * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ virtual void read_short_scalar_rww(Tango::Attribute &attr); virtual void write_short_scalar_rww(Tango::WAttribute &attr); virtual bool is_short_scalar_rww_allowed(Tango::AttReqType type); /** * Attribute short_scalar_w related methods * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ virtual void write_short_scalar_w(Tango::WAttribute &attr); virtual bool is_short_scalar_w_allowed(Tango::AttReqType type); /** * Attribute string_scalar related methods * Description: * * Data type: Tango::DevString * Attr type: Scalar */ virtual void read_string_scalar(Tango::Attribute &attr); virtual void write_string_scalar(Tango::WAttribute &attr); virtual bool is_string_scalar_allowed(Tango::AttReqType type); /** * Attribute throw_exception related methods * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ virtual void read_throw_exception(Tango::Attribute &attr); virtual bool is_throw_exception_allowed(Tango::AttReqType type); /** * Attribute uchar_scalar related methods * Description: * * Data type: Tango::DevUChar * Attr type: Scalar */ virtual void read_uchar_scalar(Tango::Attribute &attr); virtual void write_uchar_scalar(Tango::WAttribute &attr); virtual bool is_uchar_scalar_allowed(Tango::AttReqType type); /** * Attribute ulong64_scalar related methods * Description: * * Data type: Tango::DevULong64 * Attr type: Scalar */ virtual void read_ulong64_scalar(Tango::Attribute &attr); virtual void write_ulong64_scalar(Tango::WAttribute &attr); virtual bool is_ulong64_scalar_allowed(Tango::AttReqType type); /** * Attribute ushort_scalar related methods * Description: * * Data type: Tango::DevUShort * Attr type: Scalar */ virtual void read_ushort_scalar(Tango::Attribute &attr); virtual void write_ushort_scalar(Tango::WAttribute &attr); virtual bool is_ushort_scalar_allowed(Tango::AttReqType type); /** * Attribute ulong_scalar related methods * Description: * * Data type: Tango::DevULong * Attr type: Scalar */ virtual void read_ulong_scalar(Tango::Attribute &attr); virtual void write_ulong_scalar(Tango::WAttribute &attr); virtual bool is_ulong_scalar_allowed(Tango::AttReqType type); /** * Attribute boolean_spectrum related methods * Description: * * Data type: Tango::DevBoolean * Attr type: Spectrum max = 4096 */ virtual void read_boolean_spectrum(Tango::Attribute &attr); virtual void write_boolean_spectrum(Tango::WAttribute &attr); virtual bool is_boolean_spectrum_allowed(Tango::AttReqType type); /** * Attribute boolean_spectrum_ro related methods * Description: * * Data type: Tango::DevBoolean * Attr type: Spectrum max = 4096 */ virtual void read_boolean_spectrum_ro(Tango::Attribute &attr); virtual bool is_boolean_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute double_spectrum related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ virtual void read_double_spectrum(Tango::Attribute &attr); virtual void write_double_spectrum(Tango::WAttribute &attr); virtual bool is_double_spectrum_allowed(Tango::AttReqType type); /** * Attribute double_spectrum_ro related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ virtual void read_double_spectrum_ro(Tango::Attribute &attr); virtual bool is_double_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute float_spectrum related methods * Description: A float spectrum attribute * * Data type: Tango::DevFloat * Attr type: Spectrum max = 4096 */ virtual void read_float_spectrum(Tango::Attribute &attr); virtual void write_float_spectrum(Tango::WAttribute &attr); virtual bool is_float_spectrum_allowed(Tango::AttReqType type); /** * Attribute float_spectrum_ro related methods * Description: * * Data type: Tango::DevFloat * Attr type: Spectrum max = 4096 */ virtual void read_float_spectrum_ro(Tango::Attribute &attr); virtual bool is_float_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute long64_spectrum_ro related methods * Description: * * Data type: Tango::DevLong64 * Attr type: Spectrum max = 4096 */ virtual void read_long64_spectrum_ro(Tango::Attribute &attr); virtual bool is_long64_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute long_spectrum related methods * Description: * * Data type: Tango::DevLong * Attr type: Spectrum max = 4096 */ virtual void read_long_spectrum(Tango::Attribute &attr); virtual void write_long_spectrum(Tango::WAttribute &attr); virtual bool is_long_spectrum_allowed(Tango::AttReqType type); /** * Attribute long_spectrum_ro related methods * Description: * * Data type: Tango::DevLong * Attr type: Spectrum max = 4096 */ virtual void read_long_spectrum_ro(Tango::Attribute &attr); virtual bool is_long_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute short_spectrum related methods * Description: * * Data type: Tango::DevShort * Attr type: Spectrum max = 4096 */ virtual void read_short_spectrum(Tango::Attribute &attr); virtual void write_short_spectrum(Tango::WAttribute &attr); virtual bool is_short_spectrum_allowed(Tango::AttReqType type); /** * Attribute short_spectrum_ro related methods * Description: * * Data type: Tango::DevShort * Attr type: Spectrum max = 4096 */ virtual void read_short_spectrum_ro(Tango::Attribute &attr); virtual bool is_short_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute string_spectrum related methods * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 256 */ virtual void read_string_spectrum(Tango::Attribute &attr); virtual void write_string_spectrum(Tango::WAttribute &attr); virtual bool is_string_spectrum_allowed(Tango::AttReqType type); /** * Attribute string_spectrum_ro related methods * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 256 */ virtual void read_string_spectrum_ro(Tango::Attribute &attr); virtual bool is_string_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute uchar_spectrum related methods * Description: An unsigned char spectrum attribute * * Data type: Tango::DevUChar * Attr type: Spectrum max = 4096 */ virtual void read_uchar_spectrum(Tango::Attribute &attr); virtual void write_uchar_spectrum(Tango::WAttribute &attr); virtual bool is_uchar_spectrum_allowed(Tango::AttReqType type); /** * Attribute uchar_spectrum_ro related methods * Description: * * Data type: Tango::DevUChar * Attr type: Spectrum max = 4096 */ virtual void read_uchar_spectrum_ro(Tango::Attribute &attr); virtual bool is_uchar_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute ulong64_spectrum_ro related methods * Description: * * Data type: Tango::DevULong64 * Attr type: Spectrum max = 4096 */ virtual void read_ulong64_spectrum_ro(Tango::Attribute &attr); virtual bool is_ulong64_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute ulong_spectrum_ro related methods * Description: * * Data type: Tango::DevULong * Attr type: Spectrum max = 4096 */ virtual void read_ulong_spectrum_ro(Tango::Attribute &attr); virtual bool is_ulong_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute ushort_spectrum related methods * Description: An unsigned short spectrum attribute * * Data type: Tango::DevUShort * Attr type: Spectrum max = 4096 */ virtual void read_ushort_spectrum(Tango::Attribute &attr); virtual void write_ushort_spectrum(Tango::WAttribute &attr); virtual bool is_ushort_spectrum_allowed(Tango::AttReqType type); /** * Attribute ushort_spectrum_ro related methods * Description: * * Data type: Tango::DevUShort * Attr type: Spectrum max = 4096 */ virtual void read_ushort_spectrum_ro(Tango::Attribute &attr); virtual bool is_ushort_spectrum_ro_allowed(Tango::AttReqType type); /** * Attribute wave related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ virtual void read_wave(Tango::Attribute &attr); virtual bool is_wave_allowed(Tango::AttReqType type); /** * Attribute boolean_image related methods * Description: * * Data type: Tango::DevBoolean * Attr type: Image max = 251 x 251 */ virtual void read_boolean_image(Tango::Attribute &attr); virtual void write_boolean_image(Tango::WAttribute &attr); virtual bool is_boolean_image_allowed(Tango::AttReqType type); /** * Attribute boolean_image_ro related methods * Description: * * Data type: Tango::DevBoolean * Attr type: Image max = 251 x 251 */ virtual void read_boolean_image_ro(Tango::Attribute &attr); virtual bool is_boolean_image_ro_allowed(Tango::AttReqType type); /** * Attribute double_image related methods * Description: * * Data type: Tango::DevDouble * Attr type: Image max = 251 x 251 */ virtual void read_double_image(Tango::Attribute &attr); virtual void write_double_image(Tango::WAttribute &attr); virtual bool is_double_image_allowed(Tango::AttReqType type); /** * Attribute double_image_ro related methods * Description: * * Data type: Tango::DevDouble * Attr type: Image max = 251 x 251 */ virtual void read_double_image_ro(Tango::Attribute &attr); virtual bool is_double_image_ro_allowed(Tango::AttReqType type); /** * Attribute float_image related methods * Description: * * Data type: Tango::DevFloat * Attr type: Image max = 251 x 251 */ virtual void read_float_image(Tango::Attribute &attr); virtual void write_float_image(Tango::WAttribute &attr); virtual bool is_float_image_allowed(Tango::AttReqType type); /** * Attribute float_image_ro related methods * Description: A float image attribute * * Data type: Tango::DevFloat * Attr type: Image max = 251 x 251 */ virtual void read_float_image_ro(Tango::Attribute &attr); virtual bool is_float_image_ro_allowed(Tango::AttReqType type); /** * Attribute long64_image_ro related methods * Description: * * Data type: Tango::DevLong64 * Attr type: Image max = 251 x 251 */ virtual void read_long64_image_ro(Tango::Attribute &attr); virtual bool is_long64_image_ro_allowed(Tango::AttReqType type); /** * Attribute long_image related methods * Description: * * Data type: Tango::DevLong * Attr type: Image max = 251 x 251 */ virtual void read_long_image(Tango::Attribute &attr); virtual void write_long_image(Tango::WAttribute &attr); virtual bool is_long_image_allowed(Tango::AttReqType type); /** * Attribute long_image_ro related methods * Description: * * Data type: Tango::DevLong * Attr type: Image max = 251 x 251 */ virtual void read_long_image_ro(Tango::Attribute &attr); virtual bool is_long_image_ro_allowed(Tango::AttReqType type); /** * Attribute short_image related methods * Description: * * Data type: Tango::DevShort * Attr type: Image max = 251 x 251 */ virtual void read_short_image(Tango::Attribute &attr); virtual void write_short_image(Tango::WAttribute &attr); virtual bool is_short_image_allowed(Tango::AttReqType type); /** * Attribute short_image_ro related methods * Description: * * Data type: Tango::DevShort * Attr type: Image max = 251 x 251 */ virtual void read_short_image_ro(Tango::Attribute &attr); virtual bool is_short_image_ro_allowed(Tango::AttReqType type); /** * Attribute string_image related methods * Description: * * Data type: Tango::DevString * Attr type: Image max = 256 x 256 */ virtual void read_string_image(Tango::Attribute &attr); virtual void write_string_image(Tango::WAttribute &attr); virtual bool is_string_image_allowed(Tango::AttReqType type); /** * Attribute string_image_ro related methods * Description: * * Data type: Tango::DevString * Attr type: Image max = 256 x 256 */ virtual void read_string_image_ro(Tango::Attribute &attr); virtual bool is_string_image_ro_allowed(Tango::AttReqType type); /** * Attribute uchar_image related methods * Description: * * Data type: Tango::DevUChar * Attr type: Image max = 251 x 251 */ virtual void read_uchar_image(Tango::Attribute &attr); virtual void write_uchar_image(Tango::WAttribute &attr); virtual bool is_uchar_image_allowed(Tango::AttReqType type); /** * Attribute uchar_image_ro related methods * Description: An unsigned char image attribute * * Data type: Tango::DevUChar * Attr type: Image max = 251 x 251 */ virtual void read_uchar_image_ro(Tango::Attribute &attr); virtual bool is_uchar_image_ro_allowed(Tango::AttReqType type); /** * Attribute ulong64_image_ro related methods * Description: * * Data type: Tango::DevULong64 * Attr type: Image max = 251 x 251 */ virtual void read_ulong64_image_ro(Tango::Attribute &attr); virtual bool is_ulong64_image_ro_allowed(Tango::AttReqType type); /** * Attribute ulong_image_ro related methods * Description: * * Data type: Tango::DevULong * Attr type: Image max = 251 x 251 */ virtual void read_ulong_image_ro(Tango::Attribute &attr); virtual bool is_ulong_image_ro_allowed(Tango::AttReqType type); /** * Attribute ushort_image related methods * Description: * * Data type: Tango::DevUShort * Attr type: Image max = 251 x 251 */ virtual void read_ushort_image(Tango::Attribute &attr); virtual void write_ushort_image(Tango::WAttribute &attr); virtual bool is_ushort_image_allowed(Tango::AttReqType type); /** * Attribute ushort_image_ro related methods * Description: An unsigned short image attribute * * Data type: Tango::DevUShort * Attr type: Image max = 8192 x 8192 */ virtual void read_ushort_image_ro(Tango::Attribute &attr); virtual bool is_ushort_image_ro_allowed(Tango::AttReqType type); //-------------------------------------------------------- /** * Method : TangoTest::add_dynamic_attributes() * Description : Add dynamic attributes if any. */ //-------------------------------------------------------- void add_dynamic_attributes(); // pipe related methods public: // Pipe string_long_short_ro bool is_string_long_short_ro_allowed(Tango::PipeReqType); void read_string_long_short_ro(Tango::Pipe &); // Command related methods public: /** * Command CrashFromDevelopperThread related method * Description: Crashes the device! * */ virtual void crash_from_developper_thread(); virtual bool is_CrashFromDevelopperThread_allowed(const CORBA::Any &any); /** * Command CrashFromOmniThread related method * Description: Crashes the device! * */ virtual void crash_from_omni_thread(); virtual bool is_CrashFromOmniThread_allowed(const CORBA::Any &any); /** * Command DevBoolean related method * Description: A DevBoolean comand example * * @param argin Any boolean value * @returns Echo of the argin value */ virtual Tango::DevBoolean dev_boolean(Tango::DevBoolean argin); virtual bool is_DevBoolean_allowed(const CORBA::Any &any); /** * Command DevDouble related method * Description: A DevDouble command example * * @param argin Any DevDouble value * @returns Echo of the argin value */ virtual Tango::DevDouble dev_double(Tango::DevDouble argin); virtual bool is_DevDouble_allowed(const CORBA::Any &any); /** * Command DevFloat related method * Description: A DevFloat command example * * @param argin Any DevFloat value * @returns Echo of the argin value */ virtual Tango::DevFloat dev_float(Tango::DevFloat argin); virtual bool is_DevFloat_allowed(const CORBA::Any &any); /** * Command DevLong related method * Description: A DevLong command example * * @param argin Any DevLong value * @returns Echo of the argin value */ virtual Tango::DevLong dev_long(Tango::DevLong argin); virtual bool is_DevLong_allowed(const CORBA::Any &any); /** * Command DevLong64 related method * Description: A DevLong command example * * @param argin Any DevLong64 value * @returns Echo of the argin value */ virtual Tango::DevLong64 dev_long64(Tango::DevLong64 argin); virtual bool is_DevLong64_allowed(const CORBA::Any &any); /** * Command DevShort related method * Description: A DevShort command example * * @param argin Any DevShort value * @returns Echo of the argin value */ virtual Tango::DevShort dev_short(Tango::DevShort argin); virtual bool is_DevShort_allowed(const CORBA::Any &any); /** * Command DevString related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevString dev_string(Tango::DevString argin); virtual bool is_DevString_allowed(const CORBA::Any &any); /** * Command DevULong related method * Description: A DevULong command example * * @param argin Any DevULong * @returns Echo of the argin value */ virtual Tango::DevULong dev_ulong(Tango::DevULong argin); virtual bool is_DevULong_allowed(const CORBA::Any &any); /** * Command DevULong64 related method * Description: A DevULong64 command example * * @param argin Any DevULong64 value * @returns Echo of the argin value */ virtual Tango::DevULong64 dev_ulong64(Tango::DevULong64 argin); virtual bool is_DevULong64_allowed(const CORBA::Any &any); /** * Command DevUShort related method * Description: A DevUShort command example * * @param argin Any DevUShort value * @returns Echo of the argin value */ virtual Tango::DevUShort dev_ushort(Tango::DevUShort argin); virtual bool is_DevUShort_allowed(const CORBA::Any &any); /** * Command DevVarCharArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarCharArray *dev_var_char_array(const Tango::DevVarCharArray *argin); virtual bool is_DevVarCharArray_allowed(const CORBA::Any &any); /** * Command DevVarDoubleArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarDoubleArray *dev_var_double_array(const Tango::DevVarDoubleArray *argin); virtual bool is_DevVarDoubleArray_allowed(const CORBA::Any &any); /** * Command DevVarDoubleStringArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarDoubleStringArray *dev_var_double_string_array(const Tango::DevVarDoubleStringArray *argin); virtual bool is_DevVarDoubleStringArray_allowed(const CORBA::Any &any); /** * Command DevVarFloatArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarFloatArray *dev_var_float_array(const Tango::DevVarFloatArray *argin); virtual bool is_DevVarFloatArray_allowed(const CORBA::Any &any); /** * Command DevVarLong64Array related method * Description: * * @param argin * @returns */ virtual Tango::DevVarLong64Array *dev_var_long64_array(const Tango::DevVarLong64Array *argin); virtual bool is_DevVarLong64Array_allowed(const CORBA::Any &any); /** * Command DevVarLongArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarLongArray *dev_var_long_array(const Tango::DevVarLongArray *argin); virtual bool is_DevVarLongArray_allowed(const CORBA::Any &any); /** * Command DevVarLongStringArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarLongStringArray *dev_var_long_string_array(const Tango::DevVarLongStringArray *argin); virtual bool is_DevVarLongStringArray_allowed(const CORBA::Any &any); /** * Command DevVarShortArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarShortArray *dev_var_short_array(const Tango::DevVarShortArray *argin); virtual bool is_DevVarShortArray_allowed(const CORBA::Any &any); /** * Command DevVarStringArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarStringArray *dev_var_string_array(const Tango::DevVarStringArray *argin); virtual bool is_DevVarStringArray_allowed(const CORBA::Any &any); /** * Command DevVarULong64Array related method * Description: * * @param argin * @returns */ virtual Tango::DevVarULong64Array *dev_var_ulong64_array(const Tango::DevVarULong64Array *argin); virtual bool is_DevVarULong64Array_allowed(const CORBA::Any &any); /** * Command DevVarULongArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarULongArray *dev_var_ulong_array(const Tango::DevVarULongArray *argin); virtual bool is_DevVarULongArray_allowed(const CORBA::Any &any); /** * Command DevVarUShortArray related method * Description: none * * @param argin - * @returns - */ virtual Tango::DevVarUShortArray *dev_var_ushort_array(const Tango::DevVarUShortArray *argin); virtual bool is_DevVarUShortArray_allowed(const CORBA::Any &any); /** * Command DevVoid related method * Description: A DevVoid comand example * */ virtual void dev_void(); virtual bool is_DevVoid_allowed(const CORBA::Any &any); /** * Command DumpExecutionState related method * Description: Forces mini dump generation * */ virtual void dump_execution_state(); virtual bool is_DumpExecutionState_allowed(const CORBA::Any &any); /** * Command SwitchStates related method * Description: This command changes the device state from RUNNING to FAULT or from FAULT to RUNNING * */ virtual void switch_states(); virtual bool is_SwitchStates_allowed(const CORBA::Any &any); //-------------------------------------------------------- /** * Method : TangoTest::add_dynamic_commands() * Description : Add dynamic commands if any. */ //-------------------------------------------------------- void add_dynamic_commands(); /*----- PROTECTED REGION ID(TangoTest::Additional Method prototypes) ENABLED START -----*/ // Additional Method prototypes /** * Generates dummy attribute values */ void gen_data (void); protected : //- A mutex to protect the device against race conditions omni_mutex lock; // Mutexes to protec images attributes filled in by thread omni_mutex boolean_image_lock; omni_mutex double_image_lock; omni_mutex float_image_lock; omni_mutex long64_image_lock; omni_mutex long_image_lock; omni_mutex short_image_lock; omni_mutex uchar_image_lock; omni_mutex ulong64_image_lock; omni_mutex ulong_image_lock; omni_mutex ushort_image_lock; // The data generator (thread) DataGenerator * data_gen; long dimShortSpectrum; long dimLongSpectrum; long dimUcharSpectrum; long dimUshortSpectrum; long dimDoubleSpectrum; long dimFloatSpectrum; long dimBooleanSpectrum; long dimStringSpectrum; long dimXShortImage; long dimXLongImage; long dimXFloatImage; long dimXUcharImage; long dimXUshortImage; long dimXDoubleImage; long dimXBooleanImage; long dimXStringImage; long dimYShortImage; long dimYLongImage; long dimYFloatImage; long dimYUcharImage; long dimYUshortImage; long dimYDoubleImage; long dimYBooleanImage; long dimYStringImage; /*----- PROTECTED REGION END -----*/ // TangoTest::Additional Method prototypes }; /*----- PROTECTED REGION ID(TangoTest::Additional Classes Definitions) ENABLED START -----*/ // Additional Classes Definitions /*----- PROTECTED REGION END -----*/ // TangoTest::Additional Classes Definitions } // End of namespace #endif // TangoTest_H tango-9.2.5a/cppserver/tangotest/ClassFactory.cpp0000644023471100065110000000444513034745031017057 00000000000000/*----- PROTECTED REGION ID(TangoTest::ClassFactory.cpp) ENABLED START -----*/ static const char *RcsId = "$Header$"; //+============================================================================= // // file : ClassFactory.cpp // // description : C++ source for the class_factory method of the DServer // device class. This method is responsible to create // all class singletin for a device server. It is called // at device server startup // // project : TANGO Device Server // // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010 // Synchrotron SOLEIL // L'Orme des Merisiers // Saint-Aubin - BP 48 - France // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 22520 $ // // $Log$ // Revision 1.5 2007/12/11 19:07:52 nleclercq // added a "no_value" and a "throw_exception" attribute // // Revision 1.6 2006/05/17 17:07:53 leclercq // Update NL du 17.05.06 (Tango 5.4.2) // // Revision 1.4 2006/02/08 16:14:26 nleclercq // Minor modifs in RW spectrum and image attributes // //-============================================================================= // // This file is generated by POGO // (Program Obviously used to Generate tango Object) // // (c) - Software Engineering Group - ESRF //============================================================================= #include #include /** * Create TangoTestClass singleton and store it in DServer object. */ void Tango::DServer::class_factory() { add_class(TangoTest_ns::TangoTestClass::init("TangoTest")); } /*----- PROTECTED REGION END -----*/ // TangoTest::ClassFactory.cpp tango-9.2.5a/cppserver/tangotest/TangoTestClass.cpp0000644023471100065110000030334413034745031017360 00000000000000/*----- PROTECTED REGION ID(TangoTestClass.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoTestClass.cpp 28108 2015-06-24 12:29:54Z taurel $"; static const char *TagName = "$Name: $"; static const char *CvsPath = "$Source: $"; static const char *SvnPath = "$HeadURL: $"; static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; //============================================================================= // // file : TangoTestClass.cpp // // description : C++ source for the TangoTestClass. // A singleton class derived from DeviceClass. // It implements the command and attribute list // and all properties and methods required // by the TangoTest once per process. // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 28108 $ // $Date: 2015-06-24 14:29:54 +0200 (Wed, 24 Jun 2015) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include /*----- PROTECTED REGION END -----*/ // TangoTestClass.cpp //------------------------------------------------------------------- /** * Create TangoTestClass singleton and * return it in a C function for Python usage */ //------------------------------------------------------------------- extern "C" { #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif Tango::DeviceClass *_create_TangoTest_class(const char *name) { return TangoTest_ns::TangoTestClass::init(name); } } namespace TangoTest_ns { //=================================================================== // Initialize pointer for singleton pattern //=================================================================== TangoTestClass *TangoTestClass::_instance = NULL; //-------------------------------------------------------- /** * method : TangoTestClass::TangoTestClass(string &s) * description : constructor for the TangoTestClass * * @param s The class name */ //-------------------------------------------------------- TangoTestClass::TangoTestClass(string &s):Tango::DeviceClass(s) { cout2 << "Entering TangoTestClass constructor" << endl; set_default_property(); write_class_property(); /*----- PROTECTED REGION ID(TangoTestClass::constructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::constructor cout2 << "Leaving TangoTestClass constructor" << endl; } //-------------------------------------------------------- /** * method : TangoTestClass::~TangoTestClass() * description : destructor for the TangoTestClass */ //-------------------------------------------------------- TangoTestClass::~TangoTestClass() { /*----- PROTECTED REGION ID(TangoTestClass::destructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::destructor _instance = NULL; } //-------------------------------------------------------- /** * method : TangoTestClass::init * description : Create the object if not already done. * Otherwise, just return a pointer to the object * * @param name The class name */ //-------------------------------------------------------- TangoTestClass *TangoTestClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new TangoTestClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //-------------------------------------------------------- /** * method : TangoTestClass::instance * description : Check if object already created, * and return a pointer to the object */ //-------------------------------------------------------- TangoTestClass *TangoTestClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //=================================================================== // Command execution method calls //=================================================================== //-------------------------------------------------------- /** * method : CrashFromDevelopperThreadClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *CrashFromDevelopperThreadClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "CrashFromDevelopperThreadClass::execute(): arrived" << endl; ((static_cast(device))->crash_from_developper_thread()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : CrashFromOmniThreadClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *CrashFromOmniThreadClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "CrashFromOmniThreadClass::execute(): arrived" << endl; ((static_cast(device))->crash_from_omni_thread()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DevBooleanClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevBooleanClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevBooleanClass::execute(): arrived" << endl; Tango::DevBoolean argin; extract(in_any, argin); return insert((static_cast(device))->dev_boolean(argin)); } //-------------------------------------------------------- /** * method : DevDoubleClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevDoubleClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevDoubleClass::execute(): arrived" << endl; Tango::DevDouble argin; extract(in_any, argin); return insert((static_cast(device))->dev_double(argin)); } //-------------------------------------------------------- /** * method : DevFloatClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevFloatClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevFloatClass::execute(): arrived" << endl; Tango::DevFloat argin; extract(in_any, argin); return insert((static_cast(device))->dev_float(argin)); } //-------------------------------------------------------- /** * method : DevLongClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevLongClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevLongClass::execute(): arrived" << endl; Tango::DevLong argin; extract(in_any, argin); return insert((static_cast(device))->dev_long(argin)); } //-------------------------------------------------------- /** * method : DevLong64Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevLong64Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevLong64Class::execute(): arrived" << endl; Tango::DevLong64 argin; extract(in_any, argin); return insert((static_cast(device))->dev_long64(argin)); } //-------------------------------------------------------- /** * method : DevShortClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevShortClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevShortClass::execute(): arrived" << endl; Tango::DevShort argin; extract(in_any, argin); return insert((static_cast(device))->dev_short(argin)); } //-------------------------------------------------------- /** * method : DevStringClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevStringClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevStringClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->dev_string(argin)); } //-------------------------------------------------------- /** * method : DevULongClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevULongClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevULongClass::execute(): arrived" << endl; Tango::DevULong argin; extract(in_any, argin); return insert((static_cast(device))->dev_ulong(argin)); } //-------------------------------------------------------- /** * method : DevULong64Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevULong64Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevULong64Class::execute(): arrived" << endl; Tango::DevULong64 argin; extract(in_any, argin); return insert((static_cast(device))->dev_ulong64(argin)); } //-------------------------------------------------------- /** * method : DevUShortClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevUShortClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevUShortClass::execute(): arrived" << endl; Tango::DevUShort argin; extract(in_any, argin); return insert((static_cast(device))->dev_ushort(argin)); } //-------------------------------------------------------- /** * method : DevVarCharArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarCharArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarCharArrayClass::execute(): arrived" << endl; const Tango::DevVarCharArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_char_array(argin)); } //-------------------------------------------------------- /** * method : DevVarDoubleArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarDoubleArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarDoubleArrayClass::execute(): arrived" << endl; const Tango::DevVarDoubleArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_double_array(argin)); } //-------------------------------------------------------- /** * method : DevVarDoubleStringArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarDoubleStringArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarDoubleStringArrayClass::execute(): arrived" << endl; const Tango::DevVarDoubleStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_double_string_array(argin)); } //-------------------------------------------------------- /** * method : DevVarFloatArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarFloatArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarFloatArrayClass::execute(): arrived" << endl; const Tango::DevVarFloatArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_float_array(argin)); } //-------------------------------------------------------- /** * method : DevVarLong64ArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarLong64ArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarLong64ArrayClass::execute(): arrived" << endl; const Tango::DevVarLong64Array *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_long64_array(argin)); } //-------------------------------------------------------- /** * method : DevVarLongArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarLongArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarLongArrayClass::execute(): arrived" << endl; const Tango::DevVarLongArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_long_array(argin)); } //-------------------------------------------------------- /** * method : DevVarLongStringArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarLongStringArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarLongStringArrayClass::execute(): arrived" << endl; const Tango::DevVarLongStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_long_string_array(argin)); } //-------------------------------------------------------- /** * method : DevVarShortArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarShortArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarShortArrayClass::execute(): arrived" << endl; const Tango::DevVarShortArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_short_array(argin)); } //-------------------------------------------------------- /** * method : DevVarStringArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarStringArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarStringArrayClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_string_array(argin)); } //-------------------------------------------------------- /** * method : DevVarULong64ArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarULong64ArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarULong64ArrayClass::execute(): arrived" << endl; const Tango::DevVarULong64Array *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_ulong64_array(argin)); } //-------------------------------------------------------- /** * method : DevVarULongArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarULongArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarULongArrayClass::execute(): arrived" << endl; const Tango::DevVarULongArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_ulong_array(argin)); } //-------------------------------------------------------- /** * method : DevVarUShortArrayClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVarUShortArrayClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DevVarUShortArrayClass::execute(): arrived" << endl; const Tango::DevVarUShortArray *argin; extract(in_any, argin); return insert((static_cast(device))->dev_var_ushort_array(argin)); } //-------------------------------------------------------- /** * method : DevVoidClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DevVoidClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "DevVoidClass::execute(): arrived" << endl; ((static_cast(device))->dev_void()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DumpExecutionStateClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DumpExecutionStateClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "DumpExecutionStateClass::execute(): arrived" << endl; ((static_cast(device))->dump_execution_state()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : SwitchStatesClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *SwitchStatesClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "SwitchStatesClass::execute(): arrived" << endl; ((static_cast(device))->switch_states()); return new CORBA::Any(); } //=================================================================== // Properties management //=================================================================== //-------------------------------------------------------- /** * Method : TangoTestClass::get_class_property() * Description : Get the class property for specified name. */ //-------------------------------------------------------- Tango::DbDatum TangoTestClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; i vect_data; // Set Default Class Properties // Set Default device Properties prop_name = "Mthreaded_impl"; prop_desc = "Multi-threaded implementation (true/false"; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "Sleep_period"; prop_desc = "Data generation period (in ms"; prop_def = ""; vect_data.clear(); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); prop_name = "UShort_image_ro_size"; prop_desc = "Size of the ushort_image_ro attribute"; prop_def = "251"; vect_data.clear(); vect_data.push_back("251"); if (prop_def.length()>0) { Tango::DbDatum data(prop_name); data << vect_data ; dev_def_prop.push_back(data); add_wiz_dev_prop(prop_name, prop_desc, prop_def); } else add_wiz_dev_prop(prop_name, prop_desc); } //-------------------------------------------------------- /** * Method : TangoTestClass::write_class_property() * Description : Set class description fields as property in database */ //-------------------------------------------------------- void TangoTestClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("TANGO Device Server for testing generic clients"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector str_desc; str_desc.push_back("A device to test generic clients. It offers a \"echo\" like command for"); str_desc.push_back("each TANGO data type (i.e. each command returns an exact copy of )."); description << str_desc; data.push_back(description); // put cvs or svn location string filename("TangoTest"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector inheritance; inheritance.push_back("TANGO_BASE_CLASS"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); } //=================================================================== // Factory methods //=================================================================== //-------------------------------------------------------- /** * Method : TangoTestClass::device_factory() * Description : Create the device object(s) * and store them in the device list */ //-------------------------------------------------------- void TangoTestClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { /*----- PROTECTED REGION ID(TangoTestClass::device_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::device_factory_before // Create devices and add it into the device list for (unsigned long i=0 ; ilength() ; i++) { cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; device_list.push_back(new TangoTest(this, (*devlist_ptr)[i])); } // Manage dynamic attributes if any erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); // Export devices to the outside world for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) { // Add dynamic attributes if any TangoTest *dev = static_cast(device_list[device_list.size()-i]); dev->add_dynamic_attributes(); // Check before if database used. if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) export_device(dev); else export_device(dev, dev->get_name().c_str()); } /*----- PROTECTED REGION ID(TangoTestClass::device_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::device_factory_after } //-------------------------------------------------------- /** * Method : TangoTestClass::attribute_factory() * Description : Create the attribute object(s) * and store them in the attribute list */ //-------------------------------------------------------- void TangoTestClass::attribute_factory(vector &att_list) { /*----- PROTECTED REGION ID(TangoTestClass::attribute_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::attribute_factory_before // Attribute : ampli ampliAttrib *ampli = new ampliAttrib(); Tango::UserDefaultAttrProp ampli_prop; // description not set for ampli // label not set for ampli // unit not set for ampli // standard_unit not set for ampli // display_unit not set for ampli // format not set for ampli // max_value not set for ampli // min_value not set for ampli // max_alarm not set for ampli // min_alarm not set for ampli // max_warning not set for ampli // min_warning not set for ampli // delta_t not set for ampli // delta_val not set for ampli ampli->set_default_properties(ampli_prop); // Not Polled ampli->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ampli); // Attribute : boolean_scalar boolean_scalarAttrib *boolean_scalar = new boolean_scalarAttrib(); Tango::UserDefaultAttrProp boolean_scalar_prop; boolean_scalar_prop.set_description("A boolean scalar attribute"); boolean_scalar_prop.set_label("boolean_scalar"); // unit not set for boolean_scalar // standard_unit not set for boolean_scalar // display_unit not set for boolean_scalar // format not set for boolean_scalar // max_value not set for boolean_scalar // min_value not set for boolean_scalar // max_alarm not set for boolean_scalar // min_alarm not set for boolean_scalar // max_warning not set for boolean_scalar // min_warning not set for boolean_scalar // delta_t not set for boolean_scalar // delta_val not set for boolean_scalar boolean_scalar->set_default_properties(boolean_scalar_prop); // Not Polled boolean_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(boolean_scalar); // Attribute : double_scalar double_scalarAttrib *double_scalar = new double_scalarAttrib(); Tango::UserDefaultAttrProp double_scalar_prop; // description not set for double_scalar // label not set for double_scalar // unit not set for double_scalar // standard_unit not set for double_scalar // display_unit not set for double_scalar // format not set for double_scalar // max_value not set for double_scalar // min_value not set for double_scalar // max_alarm not set for double_scalar // min_alarm not set for double_scalar // max_warning not set for double_scalar // min_warning not set for double_scalar // delta_t not set for double_scalar // delta_val not set for double_scalar double_scalar->set_default_properties(double_scalar_prop); // Not Polled double_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_scalar); // Attribute : double_scalar_rww double_scalar_rwwAttrib *double_scalar_rww = new double_scalar_rwwAttrib(); Tango::UserDefaultAttrProp double_scalar_rww_prop; // description not set for double_scalar_rww // label not set for double_scalar_rww // unit not set for double_scalar_rww // standard_unit not set for double_scalar_rww // display_unit not set for double_scalar_rww // format not set for double_scalar_rww // max_value not set for double_scalar_rww // min_value not set for double_scalar_rww // max_alarm not set for double_scalar_rww // min_alarm not set for double_scalar_rww // max_warning not set for double_scalar_rww // min_warning not set for double_scalar_rww // delta_t not set for double_scalar_rww // delta_val not set for double_scalar_rww double_scalar_rww->set_default_properties(double_scalar_rww_prop); // Not Polled double_scalar_rww->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_scalar_rww); // Attribute : double_scalar_w double_scalar_wAttrib *double_scalar_w = new double_scalar_wAttrib(); Tango::UserDefaultAttrProp double_scalar_w_prop; // description not set for double_scalar_w // label not set for double_scalar_w // unit not set for double_scalar_w // standard_unit not set for double_scalar_w // display_unit not set for double_scalar_w // format not set for double_scalar_w // max_value not set for double_scalar_w // min_value not set for double_scalar_w // max_alarm not set for double_scalar_w // min_alarm not set for double_scalar_w // max_warning not set for double_scalar_w // min_warning not set for double_scalar_w // delta_t not set for double_scalar_w // delta_val not set for double_scalar_w double_scalar_w->set_default_properties(double_scalar_w_prop); // Not Polled double_scalar_w->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_scalar_w); // Attribute : float_scalar float_scalarAttrib *float_scalar = new float_scalarAttrib(); Tango::UserDefaultAttrProp float_scalar_prop; float_scalar_prop.set_description("A float attribute"); float_scalar_prop.set_label("float_scalar"); // unit not set for float_scalar // standard_unit not set for float_scalar // display_unit not set for float_scalar // format not set for float_scalar // max_value not set for float_scalar // min_value not set for float_scalar // max_alarm not set for float_scalar // min_alarm not set for float_scalar // max_warning not set for float_scalar // min_warning not set for float_scalar // delta_t not set for float_scalar // delta_val not set for float_scalar float_scalar->set_default_properties(float_scalar_prop); // Not Polled float_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(float_scalar); // Attribute : long64_scalar long64_scalarAttrib *long64_scalar = new long64_scalarAttrib(); Tango::UserDefaultAttrProp long64_scalar_prop; // description not set for long64_scalar // label not set for long64_scalar // unit not set for long64_scalar // standard_unit not set for long64_scalar // display_unit not set for long64_scalar // format not set for long64_scalar // max_value not set for long64_scalar // min_value not set for long64_scalar // max_alarm not set for long64_scalar // min_alarm not set for long64_scalar // max_warning not set for long64_scalar // min_warning not set for long64_scalar // delta_t not set for long64_scalar // delta_val not set for long64_scalar long64_scalar->set_default_properties(long64_scalar_prop); // Not Polled long64_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long64_scalar); // Attribute : long_scalar long_scalarAttrib *long_scalar = new long_scalarAttrib(); Tango::UserDefaultAttrProp long_scalar_prop; // description not set for long_scalar // label not set for long_scalar // unit not set for long_scalar // standard_unit not set for long_scalar // display_unit not set for long_scalar // format not set for long_scalar // max_value not set for long_scalar // min_value not set for long_scalar // max_alarm not set for long_scalar // min_alarm not set for long_scalar // max_warning not set for long_scalar // min_warning not set for long_scalar // delta_t not set for long_scalar // delta_val not set for long_scalar long_scalar->set_default_properties(long_scalar_prop); // Not Polled long_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_scalar); // Attribute : long_scalar_rww long_scalar_rwwAttrib *long_scalar_rww = new long_scalar_rwwAttrib(); Tango::UserDefaultAttrProp long_scalar_rww_prop; // description not set for long_scalar_rww // label not set for long_scalar_rww // unit not set for long_scalar_rww // standard_unit not set for long_scalar_rww // display_unit not set for long_scalar_rww // format not set for long_scalar_rww // max_value not set for long_scalar_rww // min_value not set for long_scalar_rww // max_alarm not set for long_scalar_rww // min_alarm not set for long_scalar_rww // max_warning not set for long_scalar_rww // min_warning not set for long_scalar_rww // delta_t not set for long_scalar_rww // delta_val not set for long_scalar_rww long_scalar_rww->set_default_properties(long_scalar_rww_prop); // Not Polled long_scalar_rww->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_scalar_rww); // Attribute : long_scalar_w long_scalar_wAttrib *long_scalar_w = new long_scalar_wAttrib(); Tango::UserDefaultAttrProp long_scalar_w_prop; // description not set for long_scalar_w // label not set for long_scalar_w // unit not set for long_scalar_w // standard_unit not set for long_scalar_w // display_unit not set for long_scalar_w // format not set for long_scalar_w // max_value not set for long_scalar_w // min_value not set for long_scalar_w // max_alarm not set for long_scalar_w // min_alarm not set for long_scalar_w // max_warning not set for long_scalar_w // min_warning not set for long_scalar_w // delta_t not set for long_scalar_w // delta_val not set for long_scalar_w long_scalar_w->set_default_properties(long_scalar_w_prop); // Not Polled long_scalar_w->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_scalar_w); // Attribute : no_value no_valueAttrib *no_value = new no_valueAttrib(); Tango::UserDefaultAttrProp no_value_prop; // description not set for no_value // label not set for no_value // unit not set for no_value // standard_unit not set for no_value // display_unit not set for no_value // format not set for no_value // max_value not set for no_value // min_value not set for no_value // max_alarm not set for no_value // min_alarm not set for no_value // max_warning not set for no_value // min_warning not set for no_value // delta_t not set for no_value // delta_val not set for no_value no_value->set_default_properties(no_value_prop); // Not Polled no_value->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(no_value); // Attribute : short_scalar short_scalarAttrib *short_scalar = new short_scalarAttrib(); Tango::UserDefaultAttrProp short_scalar_prop; // description not set for short_scalar // label not set for short_scalar // unit not set for short_scalar // standard_unit not set for short_scalar // display_unit not set for short_scalar // format not set for short_scalar // max_value not set for short_scalar // min_value not set for short_scalar // max_alarm not set for short_scalar // min_alarm not set for short_scalar // max_warning not set for short_scalar // min_warning not set for short_scalar // delta_t not set for short_scalar // delta_val not set for short_scalar short_scalar->set_default_properties(short_scalar_prop); // Not Polled short_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_scalar); // Attribute : short_scalar_ro short_scalar_roAttrib *short_scalar_ro = new short_scalar_roAttrib(); Tango::UserDefaultAttrProp short_scalar_ro_prop; // description not set for short_scalar_ro // label not set for short_scalar_ro // unit not set for short_scalar_ro // standard_unit not set for short_scalar_ro // display_unit not set for short_scalar_ro // format not set for short_scalar_ro // max_value not set for short_scalar_ro // min_value not set for short_scalar_ro // max_alarm not set for short_scalar_ro // min_alarm not set for short_scalar_ro // max_warning not set for short_scalar_ro // min_warning not set for short_scalar_ro // delta_t not set for short_scalar_ro // delta_val not set for short_scalar_ro short_scalar_ro->set_default_properties(short_scalar_ro_prop); // Not Polled short_scalar_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_scalar_ro); // Attribute : short_scalar_rww short_scalar_rwwAttrib *short_scalar_rww = new short_scalar_rwwAttrib(); Tango::UserDefaultAttrProp short_scalar_rww_prop; // description not set for short_scalar_rww // label not set for short_scalar_rww // unit not set for short_scalar_rww // standard_unit not set for short_scalar_rww // display_unit not set for short_scalar_rww // format not set for short_scalar_rww // max_value not set for short_scalar_rww // min_value not set for short_scalar_rww // max_alarm not set for short_scalar_rww // min_alarm not set for short_scalar_rww // max_warning not set for short_scalar_rww // min_warning not set for short_scalar_rww // delta_t not set for short_scalar_rww // delta_val not set for short_scalar_rww short_scalar_rww->set_default_properties(short_scalar_rww_prop); // Not Polled short_scalar_rww->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_scalar_rww); // Attribute : short_scalar_w short_scalar_wAttrib *short_scalar_w = new short_scalar_wAttrib(); Tango::UserDefaultAttrProp short_scalar_w_prop; // description not set for short_scalar_w // label not set for short_scalar_w // unit not set for short_scalar_w // standard_unit not set for short_scalar_w // display_unit not set for short_scalar_w // format not set for short_scalar_w // max_value not set for short_scalar_w // min_value not set for short_scalar_w // max_alarm not set for short_scalar_w // min_alarm not set for short_scalar_w // max_warning not set for short_scalar_w // min_warning not set for short_scalar_w // delta_t not set for short_scalar_w // delta_val not set for short_scalar_w short_scalar_w->set_default_properties(short_scalar_w_prop); // Not Polled short_scalar_w->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_scalar_w); // Attribute : string_scalar string_scalarAttrib *string_scalar = new string_scalarAttrib(); Tango::UserDefaultAttrProp string_scalar_prop; // description not set for string_scalar // label not set for string_scalar // unit not set for string_scalar // standard_unit not set for string_scalar // display_unit not set for string_scalar // format not set for string_scalar // max_value not set for string_scalar // min_value not set for string_scalar // max_alarm not set for string_scalar // min_alarm not set for string_scalar // max_warning not set for string_scalar // min_warning not set for string_scalar // delta_t not set for string_scalar // delta_val not set for string_scalar string_scalar->set_default_properties(string_scalar_prop); // Not Polled string_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(string_scalar); // Attribute : throw_exception throw_exceptionAttrib *throw_exception = new throw_exceptionAttrib(); Tango::UserDefaultAttrProp throw_exception_prop; // description not set for throw_exception // label not set for throw_exception // unit not set for throw_exception // standard_unit not set for throw_exception // display_unit not set for throw_exception // format not set for throw_exception // max_value not set for throw_exception // min_value not set for throw_exception // max_alarm not set for throw_exception // min_alarm not set for throw_exception // max_warning not set for throw_exception // min_warning not set for throw_exception // delta_t not set for throw_exception // delta_val not set for throw_exception throw_exception->set_default_properties(throw_exception_prop); // Not Polled throw_exception->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(throw_exception); // Attribute : uchar_scalar uchar_scalarAttrib *uchar_scalar = new uchar_scalarAttrib(); Tango::UserDefaultAttrProp uchar_scalar_prop; // description not set for uchar_scalar uchar_scalar_prop.set_label("uchar_scalar"); // unit not set for uchar_scalar // standard_unit not set for uchar_scalar // display_unit not set for uchar_scalar // format not set for uchar_scalar // max_value not set for uchar_scalar // min_value not set for uchar_scalar // max_alarm not set for uchar_scalar // min_alarm not set for uchar_scalar // max_warning not set for uchar_scalar // min_warning not set for uchar_scalar // delta_t not set for uchar_scalar // delta_val not set for uchar_scalar uchar_scalar->set_default_properties(uchar_scalar_prop); // Not Polled uchar_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(uchar_scalar); // Attribute : ulong64_scalar ulong64_scalarAttrib *ulong64_scalar = new ulong64_scalarAttrib(); Tango::UserDefaultAttrProp ulong64_scalar_prop; // description not set for ulong64_scalar // label not set for ulong64_scalar // unit not set for ulong64_scalar // standard_unit not set for ulong64_scalar // display_unit not set for ulong64_scalar // format not set for ulong64_scalar // max_value not set for ulong64_scalar // min_value not set for ulong64_scalar // max_alarm not set for ulong64_scalar // min_alarm not set for ulong64_scalar // max_warning not set for ulong64_scalar // min_warning not set for ulong64_scalar // delta_t not set for ulong64_scalar // delta_val not set for ulong64_scalar ulong64_scalar->set_default_properties(ulong64_scalar_prop); // Not Polled ulong64_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong64_scalar); // Attribute : ushort_scalar ushort_scalarAttrib *ushort_scalar = new ushort_scalarAttrib(); Tango::UserDefaultAttrProp ushort_scalar_prop; // description not set for ushort_scalar ushort_scalar_prop.set_label("ushort_scalar"); // unit not set for ushort_scalar // standard_unit not set for ushort_scalar // display_unit not set for ushort_scalar // format not set for ushort_scalar // max_value not set for ushort_scalar // min_value not set for ushort_scalar // max_alarm not set for ushort_scalar // min_alarm not set for ushort_scalar // max_warning not set for ushort_scalar // min_warning not set for ushort_scalar // delta_t not set for ushort_scalar // delta_val not set for ushort_scalar ushort_scalar->set_default_properties(ushort_scalar_prop); // Not Polled ushort_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ushort_scalar); // Attribute : ulong_scalar ulong_scalarAttrib *ulong_scalar = new ulong_scalarAttrib(); Tango::UserDefaultAttrProp ulong_scalar_prop; // description not set for ulong_scalar // label not set for ulong_scalar // unit not set for ulong_scalar // standard_unit not set for ulong_scalar // display_unit not set for ulong_scalar // format not set for ulong_scalar // max_value not set for ulong_scalar // min_value not set for ulong_scalar // max_alarm not set for ulong_scalar // min_alarm not set for ulong_scalar // max_warning not set for ulong_scalar // min_warning not set for ulong_scalar // delta_t not set for ulong_scalar // delta_val not set for ulong_scalar ulong_scalar->set_default_properties(ulong_scalar_prop); // Not Polled ulong_scalar->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong_scalar); // Attribute : boolean_spectrum boolean_spectrumAttrib *boolean_spectrum = new boolean_spectrumAttrib(); Tango::UserDefaultAttrProp boolean_spectrum_prop; // description not set for boolean_spectrum boolean_spectrum_prop.set_label("boolean_spectrum"); // unit not set for boolean_spectrum // standard_unit not set for boolean_spectrum // display_unit not set for boolean_spectrum // format not set for boolean_spectrum // max_value not set for boolean_spectrum // min_value not set for boolean_spectrum // max_alarm not set for boolean_spectrum // min_alarm not set for boolean_spectrum // max_warning not set for boolean_spectrum // min_warning not set for boolean_spectrum // delta_t not set for boolean_spectrum // delta_val not set for boolean_spectrum boolean_spectrum->set_default_properties(boolean_spectrum_prop); // Not Polled boolean_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(boolean_spectrum); // Attribute : boolean_spectrum_ro boolean_spectrum_roAttrib *boolean_spectrum_ro = new boolean_spectrum_roAttrib(); Tango::UserDefaultAttrProp boolean_spectrum_ro_prop; // description not set for boolean_spectrum_ro // label not set for boolean_spectrum_ro // unit not set for boolean_spectrum_ro // standard_unit not set for boolean_spectrum_ro // display_unit not set for boolean_spectrum_ro // format not set for boolean_spectrum_ro // max_value not set for boolean_spectrum_ro // min_value not set for boolean_spectrum_ro // max_alarm not set for boolean_spectrum_ro // min_alarm not set for boolean_spectrum_ro // max_warning not set for boolean_spectrum_ro // min_warning not set for boolean_spectrum_ro // delta_t not set for boolean_spectrum_ro // delta_val not set for boolean_spectrum_ro boolean_spectrum_ro->set_default_properties(boolean_spectrum_ro_prop); // Not Polled boolean_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(boolean_spectrum_ro); // Attribute : double_spectrum double_spectrumAttrib *double_spectrum = new double_spectrumAttrib(); Tango::UserDefaultAttrProp double_spectrum_prop; // description not set for double_spectrum // label not set for double_spectrum // unit not set for double_spectrum // standard_unit not set for double_spectrum // display_unit not set for double_spectrum // format not set for double_spectrum // max_value not set for double_spectrum // min_value not set for double_spectrum // max_alarm not set for double_spectrum // min_alarm not set for double_spectrum // max_warning not set for double_spectrum // min_warning not set for double_spectrum // delta_t not set for double_spectrum // delta_val not set for double_spectrum double_spectrum->set_default_properties(double_spectrum_prop); // Not Polled double_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_spectrum); // Attribute : double_spectrum_ro double_spectrum_roAttrib *double_spectrum_ro = new double_spectrum_roAttrib(); Tango::UserDefaultAttrProp double_spectrum_ro_prop; // description not set for double_spectrum_ro // label not set for double_spectrum_ro // unit not set for double_spectrum_ro // standard_unit not set for double_spectrum_ro // display_unit not set for double_spectrum_ro // format not set for double_spectrum_ro // max_value not set for double_spectrum_ro // min_value not set for double_spectrum_ro // max_alarm not set for double_spectrum_ro // min_alarm not set for double_spectrum_ro // max_warning not set for double_spectrum_ro // min_warning not set for double_spectrum_ro // delta_t not set for double_spectrum_ro // delta_val not set for double_spectrum_ro double_spectrum_ro->set_default_properties(double_spectrum_ro_prop); // Not Polled double_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_spectrum_ro); // Attribute : float_spectrum float_spectrumAttrib *float_spectrum = new float_spectrumAttrib(); Tango::UserDefaultAttrProp float_spectrum_prop; float_spectrum_prop.set_description("A float spectrum attribute"); float_spectrum_prop.set_label("float_spectrum"); // unit not set for float_spectrum // standard_unit not set for float_spectrum // display_unit not set for float_spectrum // format not set for float_spectrum // max_value not set for float_spectrum // min_value not set for float_spectrum // max_alarm not set for float_spectrum // min_alarm not set for float_spectrum // max_warning not set for float_spectrum // min_warning not set for float_spectrum // delta_t not set for float_spectrum // delta_val not set for float_spectrum float_spectrum->set_default_properties(float_spectrum_prop); // Not Polled float_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(float_spectrum); // Attribute : float_spectrum_ro float_spectrum_roAttrib *float_spectrum_ro = new float_spectrum_roAttrib(); Tango::UserDefaultAttrProp float_spectrum_ro_prop; // description not set for float_spectrum_ro // label not set for float_spectrum_ro // unit not set for float_spectrum_ro // standard_unit not set for float_spectrum_ro // display_unit not set for float_spectrum_ro // format not set for float_spectrum_ro // max_value not set for float_spectrum_ro // min_value not set for float_spectrum_ro // max_alarm not set for float_spectrum_ro // min_alarm not set for float_spectrum_ro // max_warning not set for float_spectrum_ro // min_warning not set for float_spectrum_ro // delta_t not set for float_spectrum_ro // delta_val not set for float_spectrum_ro float_spectrum_ro->set_default_properties(float_spectrum_ro_prop); // Not Polled float_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(float_spectrum_ro); // Attribute : long64_spectrum_ro long64_spectrum_roAttrib *long64_spectrum_ro = new long64_spectrum_roAttrib(); Tango::UserDefaultAttrProp long64_spectrum_ro_prop; // description not set for long64_spectrum_ro // label not set for long64_spectrum_ro // unit not set for long64_spectrum_ro // standard_unit not set for long64_spectrum_ro // display_unit not set for long64_spectrum_ro // format not set for long64_spectrum_ro // max_value not set for long64_spectrum_ro // min_value not set for long64_spectrum_ro // max_alarm not set for long64_spectrum_ro // min_alarm not set for long64_spectrum_ro // max_warning not set for long64_spectrum_ro // min_warning not set for long64_spectrum_ro // delta_t not set for long64_spectrum_ro // delta_val not set for long64_spectrum_ro long64_spectrum_ro->set_default_properties(long64_spectrum_ro_prop); // Not Polled long64_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long64_spectrum_ro); // Attribute : long_spectrum long_spectrumAttrib *long_spectrum = new long_spectrumAttrib(); Tango::UserDefaultAttrProp long_spectrum_prop; // description not set for long_spectrum // label not set for long_spectrum // unit not set for long_spectrum // standard_unit not set for long_spectrum // display_unit not set for long_spectrum // format not set for long_spectrum // max_value not set for long_spectrum // min_value not set for long_spectrum // max_alarm not set for long_spectrum // min_alarm not set for long_spectrum // max_warning not set for long_spectrum // min_warning not set for long_spectrum // delta_t not set for long_spectrum // delta_val not set for long_spectrum long_spectrum->set_default_properties(long_spectrum_prop); // Not Polled long_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_spectrum); // Attribute : long_spectrum_ro long_spectrum_roAttrib *long_spectrum_ro = new long_spectrum_roAttrib(); Tango::UserDefaultAttrProp long_spectrum_ro_prop; // description not set for long_spectrum_ro // label not set for long_spectrum_ro // unit not set for long_spectrum_ro // standard_unit not set for long_spectrum_ro // display_unit not set for long_spectrum_ro // format not set for long_spectrum_ro // max_value not set for long_spectrum_ro // min_value not set for long_spectrum_ro // max_alarm not set for long_spectrum_ro // min_alarm not set for long_spectrum_ro // max_warning not set for long_spectrum_ro // min_warning not set for long_spectrum_ro // delta_t not set for long_spectrum_ro // delta_val not set for long_spectrum_ro long_spectrum_ro->set_default_properties(long_spectrum_ro_prop); // Not Polled long_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_spectrum_ro); // Attribute : short_spectrum short_spectrumAttrib *short_spectrum = new short_spectrumAttrib(); Tango::UserDefaultAttrProp short_spectrum_prop; // description not set for short_spectrum // label not set for short_spectrum // unit not set for short_spectrum // standard_unit not set for short_spectrum // display_unit not set for short_spectrum // format not set for short_spectrum // max_value not set for short_spectrum // min_value not set for short_spectrum // max_alarm not set for short_spectrum // min_alarm not set for short_spectrum // max_warning not set for short_spectrum // min_warning not set for short_spectrum // delta_t not set for short_spectrum // delta_val not set for short_spectrum short_spectrum->set_default_properties(short_spectrum_prop); // Not Polled short_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_spectrum); // Attribute : short_spectrum_ro short_spectrum_roAttrib *short_spectrum_ro = new short_spectrum_roAttrib(); Tango::UserDefaultAttrProp short_spectrum_ro_prop; // description not set for short_spectrum_ro // label not set for short_spectrum_ro // unit not set for short_spectrum_ro // standard_unit not set for short_spectrum_ro // display_unit not set for short_spectrum_ro // format not set for short_spectrum_ro // max_value not set for short_spectrum_ro // min_value not set for short_spectrum_ro // max_alarm not set for short_spectrum_ro // min_alarm not set for short_spectrum_ro // max_warning not set for short_spectrum_ro // min_warning not set for short_spectrum_ro // delta_t not set for short_spectrum_ro // delta_val not set for short_spectrum_ro short_spectrum_ro->set_default_properties(short_spectrum_ro_prop); // Not Polled short_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_spectrum_ro); // Attribute : string_spectrum string_spectrumAttrib *string_spectrum = new string_spectrumAttrib(); Tango::UserDefaultAttrProp string_spectrum_prop; // description not set for string_spectrum // label not set for string_spectrum // unit not set for string_spectrum // standard_unit not set for string_spectrum // display_unit not set for string_spectrum // format not set for string_spectrum // max_value not set for string_spectrum // min_value not set for string_spectrum // max_alarm not set for string_spectrum // min_alarm not set for string_spectrum // max_warning not set for string_spectrum // min_warning not set for string_spectrum // delta_t not set for string_spectrum // delta_val not set for string_spectrum string_spectrum->set_default_properties(string_spectrum_prop); // Not Polled string_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(string_spectrum); // Attribute : string_spectrum_ro string_spectrum_roAttrib *string_spectrum_ro = new string_spectrum_roAttrib(); Tango::UserDefaultAttrProp string_spectrum_ro_prop; // description not set for string_spectrum_ro // label not set for string_spectrum_ro // unit not set for string_spectrum_ro // standard_unit not set for string_spectrum_ro // display_unit not set for string_spectrum_ro // format not set for string_spectrum_ro // max_value not set for string_spectrum_ro // min_value not set for string_spectrum_ro // max_alarm not set for string_spectrum_ro // min_alarm not set for string_spectrum_ro // max_warning not set for string_spectrum_ro // min_warning not set for string_spectrum_ro // delta_t not set for string_spectrum_ro // delta_val not set for string_spectrum_ro string_spectrum_ro->set_default_properties(string_spectrum_ro_prop); // Not Polled string_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(string_spectrum_ro); // Attribute : uchar_spectrum uchar_spectrumAttrib *uchar_spectrum = new uchar_spectrumAttrib(); Tango::UserDefaultAttrProp uchar_spectrum_prop; uchar_spectrum_prop.set_description("An unsigned char spectrum attribute"); uchar_spectrum_prop.set_label("uchar_spectrum"); // unit not set for uchar_spectrum // standard_unit not set for uchar_spectrum // display_unit not set for uchar_spectrum // format not set for uchar_spectrum uchar_spectrum_prop.set_max_value("255"); uchar_spectrum_prop.set_min_value("0"); // max_alarm not set for uchar_spectrum // min_alarm not set for uchar_spectrum // max_warning not set for uchar_spectrum // min_warning not set for uchar_spectrum // delta_t not set for uchar_spectrum // delta_val not set for uchar_spectrum uchar_spectrum->set_default_properties(uchar_spectrum_prop); // Not Polled uchar_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(uchar_spectrum); // Attribute : uchar_spectrum_ro uchar_spectrum_roAttrib *uchar_spectrum_ro = new uchar_spectrum_roAttrib(); Tango::UserDefaultAttrProp uchar_spectrum_ro_prop; // description not set for uchar_spectrum_ro // label not set for uchar_spectrum_ro // unit not set for uchar_spectrum_ro // standard_unit not set for uchar_spectrum_ro // display_unit not set for uchar_spectrum_ro // format not set for uchar_spectrum_ro // max_value not set for uchar_spectrum_ro // min_value not set for uchar_spectrum_ro // max_alarm not set for uchar_spectrum_ro // min_alarm not set for uchar_spectrum_ro // max_warning not set for uchar_spectrum_ro // min_warning not set for uchar_spectrum_ro // delta_t not set for uchar_spectrum_ro // delta_val not set for uchar_spectrum_ro uchar_spectrum_ro->set_default_properties(uchar_spectrum_ro_prop); // Not Polled uchar_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(uchar_spectrum_ro); // Attribute : ulong64_spectrum_ro ulong64_spectrum_roAttrib *ulong64_spectrum_ro = new ulong64_spectrum_roAttrib(); Tango::UserDefaultAttrProp ulong64_spectrum_ro_prop; // description not set for ulong64_spectrum_ro // label not set for ulong64_spectrum_ro // unit not set for ulong64_spectrum_ro // standard_unit not set for ulong64_spectrum_ro // display_unit not set for ulong64_spectrum_ro // format not set for ulong64_spectrum_ro // max_value not set for ulong64_spectrum_ro // min_value not set for ulong64_spectrum_ro // max_alarm not set for ulong64_spectrum_ro // min_alarm not set for ulong64_spectrum_ro // max_warning not set for ulong64_spectrum_ro // min_warning not set for ulong64_spectrum_ro // delta_t not set for ulong64_spectrum_ro // delta_val not set for ulong64_spectrum_ro ulong64_spectrum_ro->set_default_properties(ulong64_spectrum_ro_prop); // Not Polled ulong64_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong64_spectrum_ro); // Attribute : ulong_spectrum_ro ulong_spectrum_roAttrib *ulong_spectrum_ro = new ulong_spectrum_roAttrib(); Tango::UserDefaultAttrProp ulong_spectrum_ro_prop; // description not set for ulong_spectrum_ro // label not set for ulong_spectrum_ro // unit not set for ulong_spectrum_ro // standard_unit not set for ulong_spectrum_ro // display_unit not set for ulong_spectrum_ro // format not set for ulong_spectrum_ro // max_value not set for ulong_spectrum_ro // min_value not set for ulong_spectrum_ro // max_alarm not set for ulong_spectrum_ro // min_alarm not set for ulong_spectrum_ro // max_warning not set for ulong_spectrum_ro // min_warning not set for ulong_spectrum_ro // delta_t not set for ulong_spectrum_ro // delta_val not set for ulong_spectrum_ro ulong_spectrum_ro->set_default_properties(ulong_spectrum_ro_prop); // Not Polled ulong_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong_spectrum_ro); // Attribute : ushort_spectrum ushort_spectrumAttrib *ushort_spectrum = new ushort_spectrumAttrib(); Tango::UserDefaultAttrProp ushort_spectrum_prop; ushort_spectrum_prop.set_description("An unsigned short spectrum attribute"); ushort_spectrum_prop.set_label("ushort_spectrum"); // unit not set for ushort_spectrum // standard_unit not set for ushort_spectrum // display_unit not set for ushort_spectrum // format not set for ushort_spectrum // max_value not set for ushort_spectrum // min_value not set for ushort_spectrum // max_alarm not set for ushort_spectrum // min_alarm not set for ushort_spectrum // max_warning not set for ushort_spectrum // min_warning not set for ushort_spectrum // delta_t not set for ushort_spectrum // delta_val not set for ushort_spectrum ushort_spectrum->set_default_properties(ushort_spectrum_prop); // Not Polled ushort_spectrum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ushort_spectrum); // Attribute : ushort_spectrum_ro ushort_spectrum_roAttrib *ushort_spectrum_ro = new ushort_spectrum_roAttrib(); Tango::UserDefaultAttrProp ushort_spectrum_ro_prop; // description not set for ushort_spectrum_ro // label not set for ushort_spectrum_ro // unit not set for ushort_spectrum_ro // standard_unit not set for ushort_spectrum_ro // display_unit not set for ushort_spectrum_ro // format not set for ushort_spectrum_ro // max_value not set for ushort_spectrum_ro // min_value not set for ushort_spectrum_ro // max_alarm not set for ushort_spectrum_ro // min_alarm not set for ushort_spectrum_ro // max_warning not set for ushort_spectrum_ro // min_warning not set for ushort_spectrum_ro // delta_t not set for ushort_spectrum_ro // delta_val not set for ushort_spectrum_ro ushort_spectrum_ro->set_default_properties(ushort_spectrum_ro_prop); // Not Polled ushort_spectrum_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ushort_spectrum_ro); // Attribute : wave waveAttrib *wave = new waveAttrib(); Tango::UserDefaultAttrProp wave_prop; // description not set for wave // label not set for wave // unit not set for wave // standard_unit not set for wave // display_unit not set for wave // format not set for wave // max_value not set for wave // min_value not set for wave // max_alarm not set for wave // min_alarm not set for wave // max_warning not set for wave // min_warning not set for wave // delta_t not set for wave // delta_val not set for wave wave->set_default_properties(wave_prop); // Not Polled wave->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(wave); // Attribute : boolean_image boolean_imageAttrib *boolean_image = new boolean_imageAttrib(); Tango::UserDefaultAttrProp boolean_image_prop; // description not set for boolean_image // label not set for boolean_image // unit not set for boolean_image // standard_unit not set for boolean_image // display_unit not set for boolean_image // format not set for boolean_image // max_value not set for boolean_image // min_value not set for boolean_image // max_alarm not set for boolean_image // min_alarm not set for boolean_image // max_warning not set for boolean_image // min_warning not set for boolean_image // delta_t not set for boolean_image // delta_val not set for boolean_image boolean_image->set_default_properties(boolean_image_prop); // Not Polled boolean_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(boolean_image); // Attribute : boolean_image_ro boolean_image_roAttrib *boolean_image_ro = new boolean_image_roAttrib(); Tango::UserDefaultAttrProp boolean_image_ro_prop; // description not set for boolean_image_ro boolean_image_ro_prop.set_label("boolean_image"); // unit not set for boolean_image_ro // standard_unit not set for boolean_image_ro // display_unit not set for boolean_image_ro // format not set for boolean_image_ro // max_value not set for boolean_image_ro // min_value not set for boolean_image_ro // max_alarm not set for boolean_image_ro // min_alarm not set for boolean_image_ro // max_warning not set for boolean_image_ro // min_warning not set for boolean_image_ro // delta_t not set for boolean_image_ro // delta_val not set for boolean_image_ro boolean_image_ro->set_default_properties(boolean_image_ro_prop); // Not Polled boolean_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(boolean_image_ro); // Attribute : double_image double_imageAttrib *double_image = new double_imageAttrib(); Tango::UserDefaultAttrProp double_image_prop; // description not set for double_image // label not set for double_image // unit not set for double_image // standard_unit not set for double_image // display_unit not set for double_image // format not set for double_image // max_value not set for double_image // min_value not set for double_image // max_alarm not set for double_image // min_alarm not set for double_image // max_warning not set for double_image // min_warning not set for double_image // delta_t not set for double_image // delta_val not set for double_image double_image->set_default_properties(double_image_prop); // Not Polled double_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_image); // Attribute : double_image_ro double_image_roAttrib *double_image_ro = new double_image_roAttrib(); Tango::UserDefaultAttrProp double_image_ro_prop; // description not set for double_image_ro // label not set for double_image_ro // unit not set for double_image_ro // standard_unit not set for double_image_ro // display_unit not set for double_image_ro // format not set for double_image_ro // max_value not set for double_image_ro // min_value not set for double_image_ro // max_alarm not set for double_image_ro // min_alarm not set for double_image_ro // max_warning not set for double_image_ro // min_warning not set for double_image_ro // delta_t not set for double_image_ro // delta_val not set for double_image_ro double_image_ro->set_default_properties(double_image_ro_prop); // Not Polled double_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(double_image_ro); // Attribute : float_image float_imageAttrib *float_image = new float_imageAttrib(); Tango::UserDefaultAttrProp float_image_prop; // description not set for float_image // label not set for float_image // unit not set for float_image // standard_unit not set for float_image // display_unit not set for float_image // format not set for float_image // max_value not set for float_image // min_value not set for float_image // max_alarm not set for float_image // min_alarm not set for float_image // max_warning not set for float_image // min_warning not set for float_image // delta_t not set for float_image // delta_val not set for float_image float_image->set_default_properties(float_image_prop); // Not Polled float_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(float_image); // Attribute : float_image_ro float_image_roAttrib *float_image_ro = new float_image_roAttrib(); Tango::UserDefaultAttrProp float_image_ro_prop; float_image_ro_prop.set_description("A float image attribute"); float_image_ro_prop.set_label("float_image"); // unit not set for float_image_ro // standard_unit not set for float_image_ro // display_unit not set for float_image_ro // format not set for float_image_ro float_image_ro_prop.set_max_value("255"); float_image_ro_prop.set_min_value("0"); // max_alarm not set for float_image_ro // min_alarm not set for float_image_ro // max_warning not set for float_image_ro // min_warning not set for float_image_ro // delta_t not set for float_image_ro // delta_val not set for float_image_ro float_image_ro->set_default_properties(float_image_ro_prop); // Not Polled float_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(float_image_ro); // Attribute : long64_image_ro long64_image_roAttrib *long64_image_ro = new long64_image_roAttrib(); Tango::UserDefaultAttrProp long64_image_ro_prop; // description not set for long64_image_ro // label not set for long64_image_ro // unit not set for long64_image_ro // standard_unit not set for long64_image_ro // display_unit not set for long64_image_ro // format not set for long64_image_ro // max_value not set for long64_image_ro // min_value not set for long64_image_ro // max_alarm not set for long64_image_ro // min_alarm not set for long64_image_ro // max_warning not set for long64_image_ro // min_warning not set for long64_image_ro // delta_t not set for long64_image_ro // delta_val not set for long64_image_ro long64_image_ro->set_default_properties(long64_image_ro_prop); // Not Polled long64_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long64_image_ro); // Attribute : long_image long_imageAttrib *long_image = new long_imageAttrib(); Tango::UserDefaultAttrProp long_image_prop; // description not set for long_image // label not set for long_image // unit not set for long_image // standard_unit not set for long_image // display_unit not set for long_image // format not set for long_image // max_value not set for long_image // min_value not set for long_image // max_alarm not set for long_image // min_alarm not set for long_image // max_warning not set for long_image // min_warning not set for long_image // delta_t not set for long_image // delta_val not set for long_image long_image->set_default_properties(long_image_prop); // Not Polled long_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_image); // Attribute : long_image_ro long_image_roAttrib *long_image_ro = new long_image_roAttrib(); Tango::UserDefaultAttrProp long_image_ro_prop; // description not set for long_image_ro // label not set for long_image_ro // unit not set for long_image_ro // standard_unit not set for long_image_ro // display_unit not set for long_image_ro // format not set for long_image_ro // max_value not set for long_image_ro // min_value not set for long_image_ro // max_alarm not set for long_image_ro // min_alarm not set for long_image_ro // max_warning not set for long_image_ro // min_warning not set for long_image_ro // delta_t not set for long_image_ro // delta_val not set for long_image_ro long_image_ro->set_default_properties(long_image_ro_prop); // Not Polled long_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(long_image_ro); // Attribute : short_image short_imageAttrib *short_image = new short_imageAttrib(); Tango::UserDefaultAttrProp short_image_prop; // description not set for short_image // label not set for short_image // unit not set for short_image // standard_unit not set for short_image // display_unit not set for short_image // format not set for short_image // max_value not set for short_image // min_value not set for short_image // max_alarm not set for short_image // min_alarm not set for short_image // max_warning not set for short_image // min_warning not set for short_image // delta_t not set for short_image // delta_val not set for short_image short_image->set_default_properties(short_image_prop); // Not Polled short_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_image); // Attribute : short_image_ro short_image_roAttrib *short_image_ro = new short_image_roAttrib(); Tango::UserDefaultAttrProp short_image_ro_prop; // description not set for short_image_ro // label not set for short_image_ro // unit not set for short_image_ro // standard_unit not set for short_image_ro // display_unit not set for short_image_ro // format not set for short_image_ro // max_value not set for short_image_ro // min_value not set for short_image_ro // max_alarm not set for short_image_ro // min_alarm not set for short_image_ro // max_warning not set for short_image_ro // min_warning not set for short_image_ro // delta_t not set for short_image_ro // delta_val not set for short_image_ro short_image_ro->set_default_properties(short_image_ro_prop); // Not Polled short_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(short_image_ro); // Attribute : string_image string_imageAttrib *string_image = new string_imageAttrib(); Tango::UserDefaultAttrProp string_image_prop; // description not set for string_image // label not set for string_image // unit not set for string_image // standard_unit not set for string_image // display_unit not set for string_image // format not set for string_image // max_value not set for string_image // min_value not set for string_image // max_alarm not set for string_image // min_alarm not set for string_image // max_warning not set for string_image // min_warning not set for string_image // delta_t not set for string_image // delta_val not set for string_image string_image->set_default_properties(string_image_prop); // Not Polled string_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(string_image); // Attribute : string_image_ro string_image_roAttrib *string_image_ro = new string_image_roAttrib(); Tango::UserDefaultAttrProp string_image_ro_prop; // description not set for string_image_ro // label not set for string_image_ro // unit not set for string_image_ro // standard_unit not set for string_image_ro // display_unit not set for string_image_ro // format not set for string_image_ro // max_value not set for string_image_ro // min_value not set for string_image_ro // max_alarm not set for string_image_ro // min_alarm not set for string_image_ro // max_warning not set for string_image_ro // min_warning not set for string_image_ro // delta_t not set for string_image_ro // delta_val not set for string_image_ro string_image_ro->set_default_properties(string_image_ro_prop); // Not Polled string_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(string_image_ro); // Attribute : uchar_image uchar_imageAttrib *uchar_image = new uchar_imageAttrib(); Tango::UserDefaultAttrProp uchar_image_prop; // description not set for uchar_image // label not set for uchar_image // unit not set for uchar_image // standard_unit not set for uchar_image // display_unit not set for uchar_image // format not set for uchar_image // max_value not set for uchar_image // min_value not set for uchar_image // max_alarm not set for uchar_image // min_alarm not set for uchar_image // max_warning not set for uchar_image // min_warning not set for uchar_image // delta_t not set for uchar_image // delta_val not set for uchar_image uchar_image->set_default_properties(uchar_image_prop); // Not Polled uchar_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(uchar_image); // Attribute : uchar_image_ro uchar_image_roAttrib *uchar_image_ro = new uchar_image_roAttrib(); Tango::UserDefaultAttrProp uchar_image_ro_prop; uchar_image_ro_prop.set_description("An unsigned char image attribute"); uchar_image_ro_prop.set_label("uchar_image"); // unit not set for uchar_image_ro // standard_unit not set for uchar_image_ro // display_unit not set for uchar_image_ro // format not set for uchar_image_ro uchar_image_ro_prop.set_max_value("255"); uchar_image_ro_prop.set_min_value("0"); // max_alarm not set for uchar_image_ro // min_alarm not set for uchar_image_ro // max_warning not set for uchar_image_ro // min_warning not set for uchar_image_ro // delta_t not set for uchar_image_ro // delta_val not set for uchar_image_ro uchar_image_ro->set_default_properties(uchar_image_ro_prop); // Not Polled uchar_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(uchar_image_ro); // Attribute : ulong64_image_ro ulong64_image_roAttrib *ulong64_image_ro = new ulong64_image_roAttrib(); Tango::UserDefaultAttrProp ulong64_image_ro_prop; // description not set for ulong64_image_ro // label not set for ulong64_image_ro // unit not set for ulong64_image_ro // standard_unit not set for ulong64_image_ro // display_unit not set for ulong64_image_ro // format not set for ulong64_image_ro // max_value not set for ulong64_image_ro // min_value not set for ulong64_image_ro // max_alarm not set for ulong64_image_ro // min_alarm not set for ulong64_image_ro // max_warning not set for ulong64_image_ro // min_warning not set for ulong64_image_ro // delta_t not set for ulong64_image_ro // delta_val not set for ulong64_image_ro ulong64_image_ro->set_default_properties(ulong64_image_ro_prop); // Not Polled ulong64_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong64_image_ro); // Attribute : ulong_image_ro ulong_image_roAttrib *ulong_image_ro = new ulong_image_roAttrib(); Tango::UserDefaultAttrProp ulong_image_ro_prop; // description not set for ulong_image_ro // label not set for ulong_image_ro // unit not set for ulong_image_ro // standard_unit not set for ulong_image_ro // display_unit not set for ulong_image_ro // format not set for ulong_image_ro // max_value not set for ulong_image_ro // min_value not set for ulong_image_ro // max_alarm not set for ulong_image_ro // min_alarm not set for ulong_image_ro // max_warning not set for ulong_image_ro // min_warning not set for ulong_image_ro // delta_t not set for ulong_image_ro // delta_val not set for ulong_image_ro ulong_image_ro->set_default_properties(ulong_image_ro_prop); // Not Polled ulong_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ulong_image_ro); // Attribute : ushort_image ushort_imageAttrib *ushort_image = new ushort_imageAttrib(); Tango::UserDefaultAttrProp ushort_image_prop; // description not set for ushort_image // label not set for ushort_image // unit not set for ushort_image // standard_unit not set for ushort_image // display_unit not set for ushort_image // format not set for ushort_image // max_value not set for ushort_image // min_value not set for ushort_image // max_alarm not set for ushort_image // min_alarm not set for ushort_image // max_warning not set for ushort_image // min_warning not set for ushort_image // delta_t not set for ushort_image // delta_val not set for ushort_image ushort_image->set_default_properties(ushort_image_prop); // Not Polled ushort_image->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ushort_image); // Attribute : ushort_image_ro ushort_image_roAttrib *ushort_image_ro = new ushort_image_roAttrib(); Tango::UserDefaultAttrProp ushort_image_ro_prop; ushort_image_ro_prop.set_description("An unsigned short image attribute"); ushort_image_ro_prop.set_label("ushort_image_ro"); // unit not set for ushort_image_ro // standard_unit not set for ushort_image_ro // display_unit not set for ushort_image_ro // format not set for ushort_image_ro ushort_image_ro_prop.set_max_value("255"); ushort_image_ro_prop.set_min_value("0"); // max_alarm not set for ushort_image_ro // min_alarm not set for ushort_image_ro // max_warning not set for ushort_image_ro // min_warning not set for ushort_image_ro // delta_t not set for ushort_image_ro // delta_val not set for ushort_image_ro ushort_image_ro->set_default_properties(ushort_image_ro_prop); // Not Polled ushort_image_ro->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(ushort_image_ro); // Create a list of static attributes create_static_attribute_list(get_class_attr()->get_attr_list()); /*----- PROTECTED REGION ID(TangoTestClass::attribute_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::attribute_factory_after } //-------------------------------------------------------- /** * Method : TangoTestClass::pipe_factory() * Description : Create the pipe object(s) * and store them in the pipe list */ //-------------------------------------------------------- void TangoTestClass::pipe_factory() { /*----- PROTECTED REGION ID(TangoTestClass::pipe_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::pipe_factory_before Tango::UserDefaultPipeProp udpp; string_long_short_roClass *pstring_long_short_ro = new string_long_short_roClass("string_long_short_ro",Tango::OPERATOR); udpp.set_description("Pipe example"); udpp.set_label(""); pstring_long_short_ro->set_default_properties(udpp); pipe_list.push_back(pstring_long_short_ro); /*----- PROTECTED REGION ID(TangoTestClass::pipe_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::pipe_factory_after } //-------------------------------------------------------- /** * Method : TangoTestClass::command_factory() * Description : Create the command object(s) * and store them in the command list */ //-------------------------------------------------------- void TangoTestClass::command_factory() { /*----- PROTECTED REGION ID(TangoTestClass::command_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::command_factory_before // Command CrashFromDevelopperThread CrashFromDevelopperThreadClass *pCrashFromDevelopperThreadCmd = new CrashFromDevelopperThreadClass("CrashFromDevelopperThread", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::EXPERT); command_list.push_back(pCrashFromDevelopperThreadCmd); // Command CrashFromOmniThread CrashFromOmniThreadClass *pCrashFromOmniThreadCmd = new CrashFromOmniThreadClass("CrashFromOmniThread", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::EXPERT); command_list.push_back(pCrashFromOmniThreadCmd); // Command DevBoolean DevBooleanClass *pDevBooleanCmd = new DevBooleanClass("DevBoolean", Tango::DEV_BOOLEAN, Tango::DEV_BOOLEAN, "Any boolean value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevBooleanCmd); // Command DevDouble DevDoubleClass *pDevDoubleCmd = new DevDoubleClass("DevDouble", Tango::DEV_DOUBLE, Tango::DEV_DOUBLE, "Any DevDouble value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevDoubleCmd); // Command DevFloat DevFloatClass *pDevFloatCmd = new DevFloatClass("DevFloat", Tango::DEV_FLOAT, Tango::DEV_FLOAT, "Any DevFloat value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevFloatCmd); // Command DevLong DevLongClass *pDevLongCmd = new DevLongClass("DevLong", Tango::DEV_LONG, Tango::DEV_LONG, "Any DevLong value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevLongCmd); // Command DevLong64 DevLong64Class *pDevLong64Cmd = new DevLong64Class("DevLong64", Tango::DEV_LONG64, Tango::DEV_LONG64, "Any DevLong64 value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevLong64Cmd); // Command DevShort DevShortClass *pDevShortCmd = new DevShortClass("DevShort", Tango::DEV_SHORT, Tango::DEV_SHORT, "Any DevShort value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevShortCmd); // Command DevString DevStringClass *pDevStringCmd = new DevStringClass("DevString", Tango::DEV_STRING, Tango::DEV_STRING, "-", "-", Tango::OPERATOR); command_list.push_back(pDevStringCmd); // Command DevULong DevULongClass *pDevULongCmd = new DevULongClass("DevULong", Tango::DEV_ULONG, Tango::DEV_ULONG, "Any DevULong", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevULongCmd); // Command DevULong64 DevULong64Class *pDevULong64Cmd = new DevULong64Class("DevULong64", Tango::DEV_ULONG64, Tango::DEV_ULONG64, "Any DevULong64 value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevULong64Cmd); // Command DevUShort DevUShortClass *pDevUShortCmd = new DevUShortClass("DevUShort", Tango::DEV_USHORT, Tango::DEV_USHORT, "Any DevUShort value", "Echo of the argin value", Tango::OPERATOR); command_list.push_back(pDevUShortCmd); // Command DevVarCharArray DevVarCharArrayClass *pDevVarCharArrayCmd = new DevVarCharArrayClass("DevVarCharArray", Tango::DEVVAR_CHARARRAY, Tango::DEVVAR_CHARARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarCharArrayCmd); // Command DevVarDoubleArray DevVarDoubleArrayClass *pDevVarDoubleArrayCmd = new DevVarDoubleArrayClass("DevVarDoubleArray", Tango::DEVVAR_DOUBLEARRAY, Tango::DEVVAR_DOUBLEARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarDoubleArrayCmd); // Command DevVarDoubleStringArray DevVarDoubleStringArrayClass *pDevVarDoubleStringArrayCmd = new DevVarDoubleStringArrayClass("DevVarDoubleStringArray", Tango::DEVVAR_DOUBLESTRINGARRAY, Tango::DEVVAR_DOUBLESTRINGARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarDoubleStringArrayCmd); // Command DevVarFloatArray DevVarFloatArrayClass *pDevVarFloatArrayCmd = new DevVarFloatArrayClass("DevVarFloatArray", Tango::DEVVAR_FLOATARRAY, Tango::DEVVAR_FLOATARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarFloatArrayCmd); // Command DevVarLong64Array DevVarLong64ArrayClass *pDevVarLong64ArrayCmd = new DevVarLong64ArrayClass("DevVarLong64Array", Tango::DEVVAR_LONG64ARRAY, Tango::DEVVAR_LONG64ARRAY, "", "", Tango::OPERATOR); command_list.push_back(pDevVarLong64ArrayCmd); // Command DevVarLongArray DevVarLongArrayClass *pDevVarLongArrayCmd = new DevVarLongArrayClass("DevVarLongArray", Tango::DEVVAR_LONGARRAY, Tango::DEVVAR_LONGARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarLongArrayCmd); // Command DevVarLongStringArray DevVarLongStringArrayClass *pDevVarLongStringArrayCmd = new DevVarLongStringArrayClass("DevVarLongStringArray", Tango::DEVVAR_LONGSTRINGARRAY, Tango::DEVVAR_LONGSTRINGARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarLongStringArrayCmd); // Command DevVarShortArray DevVarShortArrayClass *pDevVarShortArrayCmd = new DevVarShortArrayClass("DevVarShortArray", Tango::DEVVAR_SHORTARRAY, Tango::DEVVAR_SHORTARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarShortArrayCmd); // Command DevVarStringArray DevVarStringArrayClass *pDevVarStringArrayCmd = new DevVarStringArrayClass("DevVarStringArray", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarStringArrayCmd); // Command DevVarULong64Array DevVarULong64ArrayClass *pDevVarULong64ArrayCmd = new DevVarULong64ArrayClass("DevVarULong64Array", Tango::DEVVAR_ULONG64ARRAY, Tango::DEVVAR_ULONG64ARRAY, "", "", Tango::OPERATOR); command_list.push_back(pDevVarULong64ArrayCmd); // Command DevVarULongArray DevVarULongArrayClass *pDevVarULongArrayCmd = new DevVarULongArrayClass("DevVarULongArray", Tango::DEVVAR_ULONGARRAY, Tango::DEVVAR_ULONGARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarULongArrayCmd); // Command DevVarUShortArray DevVarUShortArrayClass *pDevVarUShortArrayCmd = new DevVarUShortArrayClass("DevVarUShortArray", Tango::DEVVAR_USHORTARRAY, Tango::DEVVAR_USHORTARRAY, "-", "-", Tango::OPERATOR); command_list.push_back(pDevVarUShortArrayCmd); // Command DevVoid DevVoidClass *pDevVoidCmd = new DevVoidClass("DevVoid", Tango::DEV_VOID, Tango::DEV_VOID, "N/A", "N/A", Tango::OPERATOR); command_list.push_back(pDevVoidCmd); // Command DumpExecutionState DumpExecutionStateClass *pDumpExecutionStateCmd = new DumpExecutionStateClass("DumpExecutionState", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::EXPERT); command_list.push_back(pDumpExecutionStateCmd); // Command SwitchStates SwitchStatesClass *pSwitchStatesCmd = new SwitchStatesClass("SwitchStates", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::OPERATOR); command_list.push_back(pSwitchStatesCmd); /*----- PROTECTED REGION ID(TangoTestClass::command_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTestClass::command_factory_after } //=================================================================== // Dynamic attributes related methods //=================================================================== //-------------------------------------------------------- /** * method : TangoTestClass::create_static_attribute_list * description : Create the a list of static attributes * * @param att_list the ceated attribute list */ //-------------------------------------------------------- void TangoTestClass::create_static_attribute_list(vector &att_list) { for (unsigned long i=0 ; iget_name()); transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); defaultAttList.push_back(att_name); } cout2 << defaultAttList.size() << " attributes in default list" << endl; /*----- PROTECTED REGION ID(TangoTestClass::create_static_att_list) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::create_static_att_list } //-------------------------------------------------------- /** * method : TangoTestClass::erase_dynamic_attributes * description : delete the dynamic attributes if any. * * @param devlist_ptr the device list pointer * @param list of all attributes */ //-------------------------------------------------------- void TangoTestClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector &att_list) { Tango::Util *tg = Tango::Util::instance(); for (unsigned long i=0 ; ilength() ; i++) { Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); TangoTest *dev = static_cast (dev_impl); vector &dev_att_list = dev->get_device_attr()->get_attribute_list(); vector::iterator ite_att; for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) { string att_name((*ite_att)->get_name_lower()); if ((att_name == "state") || (att_name == "status")) continue; vector::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); if (ite_str == defaultAttList.end()) { cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); dev->remove_attribute(att_list[att.get_attr_idx()], true, false); --ite_att; } } } /*----- PROTECTED REGION ID(TangoTestClass::erase_dynamic_attributes) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::erase_dynamic_attributes } //-------------------------------------------------------- /** * Method : TangoTestClass::get_attr_by_name() * Description : returns Tango::Attr * object found by name */ //-------------------------------------------------------- Tango::Attr *TangoTestClass::get_attr_object_by_name(vector &att_list, string attname) { vector::iterator it; for (it=att_list.begin() ; itget_name()==attname) return (*it); // Attr does not exist return NULL; } /*----- PROTECTED REGION ID(TangoTestClass::Additional Methods) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTestClass::Additional Methods } // namespace tango-9.2.5a/cppserver/tangotest/TangoTest.cpp0000644023471100065110000042010313034745031016363 00000000000000/*----- PROTECTED REGION ID(TangoTest.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoTest.cpp 28871 2015-12-11 14:23:23Z taurel $"; //============================================================================= // // file : TangoTest.cpp // // description : C++ source for the TangoTest class and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // TangoTest are implemented in this file. // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 28871 $ // $Date: 2015-12-11 15:23:23 +0100 (Fri, 11 Dec 2015) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include #include #if defined(ENABLE_CRASH_REPORT) # include #endif static const long kSpecLen = 256; static const long kImagLen = 251; /*----- PROTECTED REGION END -----*/ // TangoTest.cpp /** * TangoTest class description: * A device to test generic clients. It offers a \"echo\" like command for * each TANGO data type (i.e. each command returns an exact copy of ). */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | Inherited (no method) // Status | Inherited (no method) // CrashFromDevelopperThread | crash_from_developper_thread // CrashFromOmniThread | crash_from_omni_thread // DevBoolean | dev_boolean // DevDouble | dev_double // DevFloat | dev_float // DevLong | dev_long // DevLong64 | dev_long64 // DevShort | dev_short // DevString | dev_string // DevULong | dev_ulong // DevULong64 | dev_ulong64 // DevUShort | dev_ushort // DevVarCharArray | dev_var_char_array // DevVarDoubleArray | dev_var_double_array // DevVarDoubleStringArray | dev_var_double_string_array // DevVarFloatArray | dev_var_float_array // DevVarLong64Array | dev_var_long64_array // DevVarLongArray | dev_var_long_array // DevVarLongStringArray | dev_var_long_string_array // DevVarShortArray | dev_var_short_array // DevVarStringArray | dev_var_string_array // DevVarULong64Array | dev_var_ulong64_array // DevVarULongArray | dev_var_ulong_array // DevVarUShortArray | dev_var_ushort_array // DevVoid | dev_void // DumpExecutionState | dump_execution_state // SwitchStates | switch_states //================================================================ //================================================================ // Attributes managed are: //================================================================ // ampli | Tango::DevDouble Scalar // boolean_scalar | Tango::DevBoolean Scalar // double_scalar | Tango::DevDouble Scalar // double_scalar_rww | Tango::DevDouble Scalar // double_scalar_w | Tango::DevDouble Scalar // float_scalar | Tango::DevFloat Scalar // long64_scalar | Tango::DevLong64 Scalar // long_scalar | Tango::DevLong Scalar // long_scalar_rww | Tango::DevLong Scalar // long_scalar_w | Tango::DevLong Scalar // no_value | Tango::DevLong Scalar // short_scalar | Tango::DevShort Scalar // short_scalar_ro | Tango::DevShort Scalar // short_scalar_rww | Tango::DevShort Scalar // short_scalar_w | Tango::DevShort Scalar // string_scalar | Tango::DevString Scalar // throw_exception | Tango::DevLong Scalar // uchar_scalar | Tango::DevUChar Scalar // ulong64_scalar | Tango::DevULong64 Scalar // ushort_scalar | Tango::DevUShort Scalar // ulong_scalar | Tango::DevULong Scalar // boolean_spectrum | Tango::DevBoolean Spectrum ( max = 4096) // boolean_spectrum_ro | Tango::DevBoolean Spectrum ( max = 4096) // double_spectrum | Tango::DevDouble Spectrum ( max = 4096) // double_spectrum_ro | Tango::DevDouble Spectrum ( max = 4096) // float_spectrum | Tango::DevFloat Spectrum ( max = 4096) // float_spectrum_ro | Tango::DevFloat Spectrum ( max = 4096) // long64_spectrum_ro | Tango::DevLong64 Spectrum ( max = 4096) // long_spectrum | Tango::DevLong Spectrum ( max = 4096) // long_spectrum_ro | Tango::DevLong Spectrum ( max = 4096) // short_spectrum | Tango::DevShort Spectrum ( max = 4096) // short_spectrum_ro | Tango::DevShort Spectrum ( max = 4096) // string_spectrum | Tango::DevString Spectrum ( max = 256) // string_spectrum_ro | Tango::DevString Spectrum ( max = 256) // uchar_spectrum | Tango::DevUChar Spectrum ( max = 4096) // uchar_spectrum_ro | Tango::DevUChar Spectrum ( max = 4096) // ulong64_spectrum_ro | Tango::DevULong64 Spectrum ( max = 4096) // ulong_spectrum_ro | Tango::DevULong Spectrum ( max = 4096) // ushort_spectrum | Tango::DevUShort Spectrum ( max = 4096) // ushort_spectrum_ro | Tango::DevUShort Spectrum ( max = 4096) // wave | Tango::DevDouble Spectrum ( max = 4096) // boolean_image | Tango::DevBoolean Image ( max = 251 x 251) // boolean_image_ro | Tango::DevBoolean Image ( max = 251 x 251) // double_image | Tango::DevDouble Image ( max = 251 x 251) // double_image_ro | Tango::DevDouble Image ( max = 251 x 251) // float_image | Tango::DevFloat Image ( max = 251 x 251) // float_image_ro | Tango::DevFloat Image ( max = 251 x 251) // long64_image_ro | Tango::DevLong64 Image ( max = 251 x 251) // long_image | Tango::DevLong Image ( max = 251 x 251) // long_image_ro | Tango::DevLong Image ( max = 251 x 251) // short_image | Tango::DevShort Image ( max = 251 x 251) // short_image_ro | Tango::DevShort Image ( max = 251 x 251) // string_image | Tango::DevString Image ( max = 256 x 256) // string_image_ro | Tango::DevString Image ( max = 256 x 256) // uchar_image | Tango::DevUChar Image ( max = 251 x 251) // uchar_image_ro | Tango::DevUChar Image ( max = 251 x 251) // ulong64_image_ro | Tango::DevULong64 Image ( max = 251 x 251) // ulong_image_ro | Tango::DevULong Image ( max = 251 x 251) // ushort_image | Tango::DevUShort Image ( max = 251 x 251) // ushort_image_ro | Tango::DevUShort Image ( max = 8192 x 8192) //================================================================ namespace TangoTest_ns { /*----- PROTECTED REGION ID(TangoTest::namespace_starting) ENABLED START -----*/ // static initializations //============================================================================= // Class: DataGenerator (thread) //============================================================================= class DataGenerator : public omni_thread, public Tango::LogAdapter { public: DataGenerator (TangoTest& dev, long sleep_time) : omni_thread(), Tango::LogAdapter(&dev), go_on_(1), dev_(dev), sleep_time_(sleep_time), generate_crash_ (false) { // noop ctor } void go (void) { DEBUG_STREAM << "DataGenerator::go" << endl; start_undetached(); } void crash (void) { WARN_STREAM << "DataGenerator::crash" << endl; generate_crash_ = true; } virtual void* run_undetached (void *) { static int * __invalid_ptr__ = 0; DEBUG_STREAM << "DataGenerator::run_undetached" << endl; do { if (generate_crash_) *__invalid_ptr__ = 0; { //- enter critical section omni_mutex_lock guard(dev_.lock); if (! go_on_) break; DEBUG_STREAM << "DataGenerator::generating data" << endl; dev_.gen_data(); } //- leave critical section sleep(0, sleep_time_ * 1000000); } while (go_on_); return 0; } void abort (void) { DEBUG_STREAM << "DataGenerator::abort" << endl; go_on_ = 0; } protected: virtual ~DataGenerator (void) { // noop dtor } private: int go_on_; TangoTest& dev_; long sleep_time_; bool generate_crash_; } ; /*----- PROTECTED REGION END -----*/ // TangoTest::namespace_starting //-------------------------------------------------------- /** * Method : TangoTest::TangoTest() * Description : Constructors for a Tango device * implementing the classTangoTest */ //-------------------------------------------------------- TangoTest::TangoTest(Tango::DeviceClass *cl, string &s) : TANGO_BASE_CLASS(cl, s.c_str()) { /*----- PROTECTED REGION ID(TangoTest::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoTest::constructor_1 } //-------------------------------------------------------- TangoTest::TangoTest(Tango::DeviceClass *cl, const char *s) : TANGO_BASE_CLASS(cl, s) { /*----- PROTECTED REGION ID(TangoTest::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoTest::constructor_2 } //-------------------------------------------------------- TangoTest::TangoTest(Tango::DeviceClass *cl, const char *s, const char *d) : TANGO_BASE_CLASS(cl, s, d) { /*----- PROTECTED REGION ID(TangoTest::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoTest::constructor_3 } //-------------------------------------------------------- /** * Method : TangoTest::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void TangoTest::delete_device() { DEBUG_STREAM << "TangoTest::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::delete_device) ENABLED START -----*/ // Delete device allocated objects omni_mutex_lock guard(lock); if (mthreaded_impl && data_gen) { data_gen->abort(); data_gen->join(0); data_gen = 0; } if (attr_short_scalar_ro_read) { delete attr_short_scalar_ro_read; attr_short_scalar_ro_read = 0; } if (attr_short_scalar_read) { delete attr_short_scalar_read; attr_short_scalar_read = 0; } if (attr_short_scalar_rww_read) { delete attr_short_scalar_rww_read; attr_short_scalar_rww_read = 0; } if (attr_long_scalar_read) { delete attr_long_scalar_read; attr_long_scalar_read = 0; } if (attr_ulong_scalar_read) { delete attr_ulong_scalar_read; attr_ulong_scalar_read = 0; } if (attr_long64_scalar_read) { delete attr_long64_scalar_read; attr_long64_scalar_read = 0; } if (attr_ulong64_scalar_read) { delete attr_ulong64_scalar_read; attr_ulong64_scalar_read = 0; } if (attr_long_scalar_rww_read) { delete attr_long_scalar_rww_read; attr_long_scalar_rww_read = 0; } if (attr_double_scalar_read) { delete attr_double_scalar_read; attr_double_scalar_read = 0; } if (attr_double_scalar_rww_read) { delete attr_double_scalar_rww_read; attr_double_scalar_rww_read = 0; } if (*attr_string_scalar_read) { delete *attr_string_scalar_read; } if (attr_string_scalar_read) { delete[] attr_string_scalar_read; attr_string_scalar_read = 0; } if (attr_boolean_scalar_read) { delete attr_boolean_scalar_read; attr_boolean_scalar_read = 0; } if (attr_float_scalar_read) { delete attr_float_scalar_read; attr_float_scalar_read = 0; } if (attr_uchar_scalar_read) { delete attr_uchar_scalar_read; attr_uchar_scalar_read = 0; } if (attr_ushort_scalar_read) { delete attr_ushort_scalar_read; attr_ushort_scalar_read = 0; } //- spectrum if (attr_short_spectrum_read) { delete[] attr_short_spectrum_read; attr_short_spectrum_read = 0; } if (attr_short_spectrum_ro_read) { delete[] attr_short_spectrum_ro_read; attr_short_spectrum_ro_read = 0; } if (attr_long_spectrum_read) { delete[] attr_long_spectrum_read; attr_long_spectrum_read = 0; } if (attr_long_spectrum_ro_read) { delete[] attr_long_spectrum_ro_read; attr_long_spectrum_ro_read = 0; } if (attr_ulong_spectrum_ro_read) { delete[] attr_ulong_spectrum_ro_read; attr_ulong_spectrum_ro_read = 0; } if (attr_ulong_spectrum_ro_read) { delete[] attr_ulong_spectrum_ro_read; attr_ulong_spectrum_ro_read = 0; } if (attr_ulong64_spectrum_ro_read) { delete[] attr_ulong64_spectrum_ro_read; attr_ulong64_spectrum_ro_read = 0; } if (attr_double_spectrum_read) { delete[] attr_double_spectrum_read; attr_double_spectrum_read = 0; } if (attr_long64_spectrum_ro_read) { delete[] attr_long64_spectrum_ro_read; attr_long64_spectrum_ro_read = 0; } if (attr_double_spectrum_ro_read) { delete[] attr_double_spectrum_ro_read; attr_double_spectrum_ro_read = 0; } if (attr_boolean_spectrum_read) { delete[] attr_boolean_spectrum_read; attr_boolean_spectrum_read = 0; } if (attr_boolean_spectrum_ro_read) { delete[] attr_boolean_spectrum_ro_read; attr_boolean_spectrum_ro_read = 0; } if (attr_uchar_spectrum_read) { delete[] attr_uchar_spectrum_read; attr_uchar_spectrum_read = 0; } if (attr_uchar_spectrum_ro_read) { delete[] attr_uchar_spectrum_ro_read; attr_uchar_spectrum_ro_read = 0; } if (attr_ushort_spectrum_read) { delete[] attr_ushort_spectrum_read; attr_ushort_spectrum_read = 0; } if (attr_ushort_spectrum_ro_read) { delete[] attr_ushort_spectrum_ro_read; attr_ushort_spectrum_ro_read = 0; } if (attr_float_spectrum_read) { delete[] attr_float_spectrum_read; attr_float_spectrum_read = 0; } if (attr_float_spectrum_ro_read) { delete[] attr_float_spectrum_ro_read; attr_float_spectrum_ro_read = 0; } int s = 0; if (attr_string_spectrum_ro_read) { for (s = 0; s < kSpecLen; s++) CORBA::string_free(attr_string_spectrum_ro_read[s]); delete[] attr_string_spectrum_ro_read; attr_string_spectrum_ro_read = 0; } if (attr_string_spectrum_read) { for (s = 0; s < kSpecLen; s++) CORBA::string_free(attr_string_spectrum_read[s]); delete[] attr_string_spectrum_read; attr_string_spectrum_read = 0; } //- image if (attr_short_image_read) { delete[] attr_short_image_read; attr_short_image_read = 0; } if (attr_long_image_read) { delete[] attr_long_image_read; attr_long_image_read = 0; } if (attr_double_image_read) { delete[] attr_double_image_read; attr_double_image_read = 0; } if (attr_boolean_image_read) { delete[] attr_boolean_image_read; attr_boolean_image_read = 0; } if (attr_uchar_image_read) { delete[] attr_uchar_image_read; attr_uchar_image_read = 0; } if (attr_ushort_image_read) { delete[] attr_ushort_image_read; attr_ushort_image_read = 0; } if (attr_float_image_read) { delete[] attr_float_image_read; attr_float_image_read = 0; } // if (attr_short_image_ro_read) { delete[] attr_short_image_ro_read; attr_short_image_ro_read = 0; } if (attr_long_image_ro_read) { delete[] attr_long_image_ro_read; attr_long_image_ro_read = 0; } if (attr_ulong_image_ro_read) { delete[] attr_ulong_image_ro_read; attr_ulong_image_ro_read = 0; } if (attr_long64_image_ro_read) { delete[] attr_long64_image_ro_read; attr_long64_image_ro_read = 0; } if (attr_ulong64_image_ro_read) { delete[] attr_ulong64_image_ro_read; attr_ulong64_image_ro_read = 0; } if (attr_double_image_ro_read) { delete[] attr_double_image_ro_read; attr_double_image_ro_read = 0; } if (attr_boolean_image_ro_read) { delete[] attr_boolean_image_ro_read; attr_boolean_image_ro_read = 0; } if (attr_uchar_image_ro_read) { delete[] attr_uchar_image_ro_read; attr_uchar_image_ro_read = 0; } if (attr_ushort_image_ro_read) { delete[] attr_ushort_image_ro_read; attr_ushort_image_ro_read = 0; } if (attr_float_image_ro_read) { delete[] attr_float_image_ro_read; attr_float_image_ro_read = 0; } if (attr_string_image_ro_read) { for (s = 0; s < kImagLen * kImagLen; s++) CORBA::string_free(attr_string_image_ro_read[s]); delete[] attr_string_image_ro_read; attr_string_image_ro_read = 0; } if (attr_string_image_read) { for (s = 0; s < kImagLen * kImagLen; s++) CORBA::string_free(attr_string_image_read[s]); delete[] attr_string_image_read; attr_string_image_read = 0; } if (attr_wave_read) { delete[] attr_wave_read; attr_wave_read = 0; } /*----- PROTECTED REGION END -----*/ // TangoTest::delete_device } //-------------------------------------------------------- /** * Method : TangoTest::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void TangoTest::init_device() { DEBUG_STREAM << "TangoTest::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::init_device_before) ENABLED START -----*/ // Initialization before get_device_property() call LOG_INFO(("TangoTest::init_device::init device %s", device_name.c_str())); // Two lines of code ONLY to make the Debian hardening_check command // happy. Required for Debian packaging char host[256]; gethostname(host,sizeof(host)); omni_mutex_lock guard(lock); //------------------------------------------------------- // Get device property from database /*----- PROTECTED REGION END -----*/ // TangoTest::init_device_before // Get the device properties from database get_device_property(); /*----- PROTECTED REGION ID(TangoTest::init_device) ENABLED START -----*/ // Initialize device // Allocate/initialize read part for each readable attribute // Initialize write part for each writable attribute //- Scalar attr_short_scalar_ro_read = new Tango::DevShort; *attr_short_scalar_ro_read = 0; attr_short_scalar_read = new Tango::DevShort; *attr_short_scalar_read = 0; attr_short_scalar_write = 256; attr_short_scalar_w_write = 256; attr_short_scalar_rww_read = new Tango::DevShort; *attr_short_scalar_rww_read = 0; attr_long_scalar_read = new Tango::DevLong; *attr_long_scalar_read = 0; attr_long_scalar_write = 256; attr_ulong_scalar_read = new Tango::DevULong; *attr_ulong_scalar_read = 0; attr_ulong_scalar_write = 256; attr_long64_scalar_read = new Tango::DevLong64; *attr_long64_scalar_read = 0; attr_long64_scalar_write = 256; attr_ulong64_scalar_read = new Tango::DevULong64; *attr_ulong64_scalar_read = 0; attr_ulong64_scalar_write = 256; attr_long_scalar_w_write = 256; attr_long_scalar_rww_read = new Tango::DevLong; *attr_long_scalar_rww_read = 0; attr_double_scalar_read = new Tango::DevDouble; *attr_double_scalar_read = 0; attr_double_scalar_write = 256; attr_double_scalar_w_write = 256; attr_double_scalar_rww_read = new Tango::DevDouble; *attr_double_scalar_rww_read = 0; attr_string_scalar_read = new char*; *attr_string_scalar_read = new char[256]; ::strcpy(*attr_string_scalar_read, "Default string"); attr_string_scalar_write = 0; attr_boolean_scalar_read = new Tango::DevBoolean; *attr_boolean_scalar_read = true; attr_boolean_scalar_write = false; attr_float_scalar_read = new Tango::DevFloat; *attr_float_scalar_read = 0; attr_float_scalar_write = 0; attr_uchar_scalar_read = new Tango::DevUChar; *attr_uchar_scalar_read = 0; attr_uchar_scalar_write = 0; attr_ushort_scalar_read = new Tango::DevUShort; *attr_ushort_scalar_read = 0; attr_ushort_scalar_write = 0; //- Spectrum attr_short_spectrum_ro_read = new Tango::DevShort[kSpecLen]; ::memset(attr_short_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevShort)); attr_short_spectrum_read = new Tango::DevShort[kSpecLen]; ::memset(attr_short_spectrum_read, 0, kSpecLen * sizeof(Tango::DevShort)); dimShortSpectrum = kSpecLen; attr_long_spectrum_ro_read = new Tango::DevLong[kSpecLen]; ::memset(attr_long_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevLong)); attr_ulong_spectrum_ro_read = new Tango::DevULong[kSpecLen]; ::memset(attr_ulong_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevULong)); attr_long64_spectrum_ro_read = new Tango::DevLong64[kSpecLen]; ::memset(attr_long64_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevLong64)); attr_ulong64_spectrum_ro_read = new Tango::DevULong64[kSpecLen]; ::memset(attr_ulong64_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevULong64)); attr_long_spectrum_read = new Tango::DevLong[kSpecLen]; ::memset(attr_long_spectrum_read, 0, kSpecLen * sizeof(Tango::DevLong)); dimLongSpectrum = kSpecLen; attr_double_spectrum_ro_read = new Tango::DevDouble[kSpecLen]; ::memset(attr_double_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevDouble)); attr_double_spectrum_read = new Tango::DevDouble[kSpecLen]; ::memset(attr_double_spectrum_read, 0, kSpecLen * sizeof(Tango::DevDouble)); dimDoubleSpectrum = kSpecLen; attr_string_spectrum_ro_read = new Tango::DevString[kSpecLen]; int s; for (s = 0; s < kSpecLen; s++) { attr_string_spectrum_ro_read[s] = CORBA::string_alloc(kSpecLen); ::memset(attr_string_spectrum_ro_read[s], 0, kSpecLen * sizeof(char)); } attr_string_spectrum_read = new Tango::DevString[kSpecLen]; for (s = 0; s < kSpecLen; s++) { attr_string_spectrum_read[s] = CORBA::string_alloc(kSpecLen); ::memset(attr_string_spectrum_read[s], 0, kSpecLen * sizeof(char)); } attr_string_spectrum_write = 0; dimStringSpectrum = kSpecLen; attr_wave_read = new Tango::DevDouble[kSpecLen]; ::memset(attr_wave_read, 0, kSpecLen * sizeof(Tango::DevDouble)); attr_ampli_write= 1; attr_boolean_spectrum_ro_read = new Tango::DevBoolean[kSpecLen]; ::memset(attr_boolean_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevBoolean)); attr_boolean_spectrum_read = new Tango::DevBoolean[kSpecLen]; ::memset(attr_boolean_spectrum_read, 0, kSpecLen * sizeof(Tango::DevBoolean)); dimBooleanSpectrum = kSpecLen; attr_ushort_spectrum_ro_read = new Tango::DevUShort[kSpecLen]; ::memset(attr_ushort_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevUShort)); attr_ushort_spectrum_read = new Tango::DevUShort[kSpecLen]; ::memset(attr_ushort_spectrum_read, 0, kSpecLen * sizeof(Tango::DevUShort)); dimUshortSpectrum = kSpecLen; attr_uchar_spectrum_ro_read = new Tango::DevUChar[kSpecLen]; ::memset(attr_uchar_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevUChar)); attr_uchar_spectrum_read = new Tango::DevUChar[kSpecLen]; ::memset(attr_uchar_spectrum_read, 0, kSpecLen * sizeof(Tango::DevUChar)); dimUcharSpectrum = kSpecLen; attr_float_spectrum_ro_read = new Tango::DevFloat[kSpecLen]; ::memset(attr_float_spectrum_ro_read, 0, kSpecLen * sizeof(Tango::DevFloat)); attr_float_spectrum_read = new Tango::DevFloat[kSpecLen]; ::memset(attr_float_spectrum_read, 0, kSpecLen * sizeof(Tango::DevFloat)); dimFloatSpectrum = kSpecLen; //- Images attr_short_image_read = new Tango::DevShort[kImagLen * kImagLen]; ::memset(attr_short_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevShort)); dimXShortImage = kImagLen; dimYShortImage = kImagLen; attr_long_image_read = new Tango::DevLong[kImagLen * kImagLen]; ::memset(attr_long_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevLong)); dimXLongImage = kImagLen; dimYLongImage = kImagLen; attr_double_image_read = new Tango::DevDouble[kImagLen * kImagLen]; ::memset(attr_double_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevDouble)); dimXDoubleImage = kImagLen; dimYDoubleImage = kImagLen; attr_uchar_image_read = new Tango::DevUChar[kImagLen * kImagLen]; ::memset(attr_uchar_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevUChar)); dimXUcharImage = kImagLen; dimYUcharImage = kImagLen; attr_ushort_image_read = new Tango::DevUShort[kImagLen * kImagLen]; ::memset(attr_ushort_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevUShort)); dimXUshortImage = kImagLen; dimYUshortImage = kImagLen; attr_float_image_read = new Tango::DevFloat[kImagLen * kImagLen]; ::memset(attr_float_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevFloat)); dimXFloatImage = kImagLen; dimYFloatImage = kImagLen; attr_boolean_image_read = new Tango::DevBoolean[kImagLen * kImagLen]; ::memset(attr_boolean_image_read, 0, kImagLen * kImagLen * sizeof(Tango::DevBoolean)); dimXBooleanImage = kImagLen; dimYBooleanImage = kImagLen; attr_short_image_ro_read = new Tango::DevShort[kImagLen * kImagLen]; ::memset(attr_short_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevShort)); attr_long_image_ro_read = new Tango::DevLong[kImagLen * kImagLen]; ::memset(attr_long_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevLong)); attr_ulong_image_ro_read = new Tango::DevULong[kImagLen * kImagLen]; ::memset(attr_ulong_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevULong)); attr_long64_image_ro_read = new Tango::DevLong64[kImagLen * kImagLen]; ::memset(attr_long64_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevLong64)); attr_ulong64_image_ro_read = new Tango::DevULong64[kImagLen * kImagLen]; ::memset(attr_ulong64_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevULong64)); attr_double_image_ro_read = new Tango::DevDouble[kImagLen * kImagLen]; ::memset(attr_double_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevDouble)); attr_uchar_image_ro_read = new Tango::DevUChar[kImagLen * kImagLen]; ::memset(attr_uchar_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevUChar)); attr_ushort_image_ro_read = new Tango::DevUShort[uShort_image_ro_size * uShort_image_ro_size]; ::memset(attr_ushort_image_ro_read, 0, uShort_image_ro_size * uShort_image_ro_size * sizeof(Tango::DevUShort)); attr_float_image_ro_read = new Tango::DevFloat[kImagLen * kImagLen]; ::memset(attr_float_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevFloat)); attr_boolean_image_ro_read = new Tango::DevBoolean[kImagLen * kImagLen]; ::memset(attr_boolean_image_ro_read, 0, kImagLen * kImagLen * sizeof(Tango::DevBoolean)); attr_string_image_ro_read = new char*[kImagLen * kImagLen]; for (s = 0; s < kImagLen * kImagLen; s++) { attr_string_image_ro_read[s] = CORBA::string_alloc(kSpecLen); ::memset(attr_string_image_ro_read[s], 0, kSpecLen * sizeof(char)); } attr_string_image_read = new char*[kImagLen * kImagLen]; for (s = 0; s < kImagLen * kImagLen; s++) { attr_string_image_read[s] = CORBA::string_alloc(kSpecLen); ::memset(attr_string_image_read[s], 0, kSpecLen * sizeof(char)); } attr_string_image_write = 0; dimXStringImage = kImagLen; dimYStringImage = kImagLen; // Multithreaded implementation stuffs if (mthreaded_impl == 0) { data_gen = 0; return; } Tango::Attribute &att1 = dev_attr->get_attr_by_name("short_image_ro"); att1.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att2 = dev_attr->get_attr_by_name("long_image_ro"); att2.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att3 = dev_attr->get_attr_by_name("ulong_image_ro"); att3.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att4 = dev_attr->get_attr_by_name("long64_image_ro"); att4.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att5 = dev_attr->get_attr_by_name("ulong64_image_ro"); att5.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att6 = dev_attr->get_attr_by_name("float_image_ro"); att6.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att7 = dev_attr->get_attr_by_name("double_image_ro"); att7.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att8 = dev_attr->get_attr_by_name("boolean_image_ro"); att8.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att9 = dev_attr->get_attr_by_name("uchar_image_ro"); att9.set_attr_serial_model(Tango::ATTR_BY_USER); Tango::Attribute &att10 = dev_attr->get_attr_by_name("ushort_image_ro"); att10.set_attr_serial_model(Tango::ATTR_BY_USER); data_gen = new DataGenerator(*this, sleep_period); data_gen->go(); // pipe pi_str = "The string"; pi_long = 666; pi_short = (Tango::DevShort)12; set_state(Tango::RUNNING); /*----- PROTECTED REGION END -----*/ // TangoTest::init_device } //-------------------------------------------------------- /** * Method : TangoTest::get_device_property() * Description : Read database to initialize property data members. */ //-------------------------------------------------------- void TangoTest::get_device_property() { /*----- PROTECTED REGION ID(TangoTest::get_device_property_before) ENABLED START -----*/ // Initialize property data members mthreaded_impl = 1; sleep_period = 2000; uShort_image_ro_size = kImagLen; /*----- PROTECTED REGION END -----*/ // TangoTest::get_device_property_before // Read device properties from database. Tango::DbData dev_prop; dev_prop.push_back(Tango::DbDatum("Mthreaded_impl")); dev_prop.push_back(Tango::DbDatum("Sleep_period")); dev_prop.push_back(Tango::DbDatum("UShort_image_ro_size")); // is there at least one property to be read ? if (dev_prop.size()>0) { // Call database and extract values if (Tango::Util::instance()->_UseDb==true) get_db_device()->get_property(dev_prop); // get instance on TangoTestClass to get class property Tango::DbDatum def_prop, cl_prop; TangoTestClass *ds_class = (static_cast(get_device_class())); int i = -1; // Try to initialize Mthreaded_impl from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> mthreaded_impl; else { // Try to initialize Mthreaded_impl from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> mthreaded_impl; } // And try to extract Mthreaded_impl value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> mthreaded_impl; // Try to initialize Sleep_period from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> sleep_period; else { // Try to initialize Sleep_period from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> sleep_period; } // And try to extract Sleep_period value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> sleep_period; // Try to initialize UShort_image_ro_size from class property cl_prop = ds_class->get_class_property(dev_prop[++i].name); if (cl_prop.is_empty()==false) cl_prop >> uShort_image_ro_size; else { // Try to initialize UShort_image_ro_size from default device value def_prop = ds_class->get_default_device_property(dev_prop[i].name); if (def_prop.is_empty()==false) def_prop >> uShort_image_ro_size; } // And try to extract UShort_image_ro_size value from database if (dev_prop[i].is_empty()==false) dev_prop[i] >> uShort_image_ro_size; } /*----- PROTECTED REGION ID(TangoTest::get_device_property_after) ENABLED START -----*/ // Check device property data members init DEBUG_STREAM << "sleep_period=" << sleep_period << endl; DEBUG_STREAM << "mthreaded_impl=" << mthreaded_impl << endl; DEBUG_STREAM << "uShort_image_ro_size=" << uShort_image_ro_size << endl; /*----- PROTECTED REGION END -----*/ // TangoTest::get_device_property_after } //-------------------------------------------------------- /** * Method : TangoTest::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void TangoTest::always_executed_hook() { DEBUG_STREAM << "TangoTest::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::always_executed_hook) ENABLED START -----*/ // code always executed before all requests /*----- PROTECTED REGION END -----*/ // TangoTest::always_executed_hook } //-------------------------------------------------------- /** * Method : TangoTest::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void TangoTest::read_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "TangoTest::read_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_attr_hardware) ENABLED START -----*/ // Add your own code LOG_DEBUG(("In read_attr_hardware for %d attributes",attr_list.size())); // Generate data for all attributes if (mthreaded_impl == 0) { gen_data(); } /*----- PROTECTED REGION END -----*/ // TangoTest::read_attr_hardware } //-------------------------------------------------------- /** * Method : TangoTest::write_attr_hardware() * Description : Hardware writing for attributes */ //-------------------------------------------------------- void TangoTest::write_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "TangoTest::write_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::write_attr_hardware) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoTest::write_attr_hardware } //-------------------------------------------------------- /** * Write attribute ampli related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_ampli(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ampli(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevDouble w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ampli) ENABLED START -----*/ DEBUG_STREAM << "ampli = " << w_val << endl; attr_ampli_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_ampli } //-------------------------------------------------------- /** * Read attribute boolean_scalar related method * Description: A boolean scalar attribute * * Data type: Tango::DevBoolean * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_boolean_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_boolean_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_boolean_scalar) ENABLED START -----*/ attr.set_value(attr_boolean_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_boolean_scalar } //-------------------------------------------------------- /** * Write attribute boolean_scalar related method * Description: A boolean scalar attribute * * Data type: Tango::DevBoolean * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_boolean_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_boolean_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevBoolean w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_boolean_scalar) ENABLED START -----*/ *attr_boolean_scalar_read = w_val; attr_boolean_scalar_write = w_val; DEBUG_STREAM << "Read and write attributes were set to the same value" << endl; DEBUG_STREAM << "w_val = " << w_val << endl; DEBUG_STREAM << "attr_boolean_scalar_read = " << *attr_boolean_scalar_read << endl; /*----- PROTECTED REGION END -----*/ // TangoTest::write_boolean_scalar } //-------------------------------------------------------- /** * Read attribute double_scalar related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_double_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_scalar) ENABLED START -----*/ attr.set_value(attr_double_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_scalar } //-------------------------------------------------------- /** * Write attribute double_scalar related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_double_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_double_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevDouble w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_double_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_double_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_double_scalar } //-------------------------------------------------------- /** * Read attribute double_scalar_rww related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_double_scalar_rww(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_scalar_rww(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_scalar_rww) ENABLED START -----*/ attr.set_value(attr_double_scalar_rww_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_scalar_rww } //-------------------------------------------------------- /** * Write attribute double_scalar_rww related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_double_scalar_rww(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_double_scalar_rww(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevDouble w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_double_scalar_rww) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::write_double_scalar_rww } //-------------------------------------------------------- /** * Write attribute double_scalar_w related method * Description: * * Data type: Tango::DevDouble * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_double_scalar_w(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_double_scalar_w(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevDouble w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_double_scalar_w) ENABLED START -----*/ DEBUG_STREAM << "double_scalar_w = " << w_val << endl; attr_double_scalar_w_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_double_scalar_w } //-------------------------------------------------------- /** * Read attribute float_scalar related method * Description: A float attribute * * Data type: Tango::DevFloat * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_float_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_float_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_float_scalar) ENABLED START -----*/ attr.set_value(attr_float_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_float_scalar } //-------------------------------------------------------- /** * Write attribute float_scalar related method * Description: A float attribute * * Data type: Tango::DevFloat * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_float_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_float_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevFloat w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_float_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_float_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_float_scalar } //-------------------------------------------------------- /** * Read attribute long64_scalar related method * Description: * * Data type: Tango::DevLong64 * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_long64_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long64_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long64_scalar) ENABLED START -----*/ attr.set_value(attr_long64_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long64_scalar } //-------------------------------------------------------- /** * Write attribute long64_scalar related method * Description: * * Data type: Tango::DevLong64 * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_long64_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long64_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevLong64 w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long64_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_long64_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_long64_scalar } //-------------------------------------------------------- /** * Read attribute long_scalar related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_long_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_scalar) ENABLED START -----*/ attr.set_value(attr_long_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_scalar } //-------------------------------------------------------- /** * Write attribute long_scalar related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_long_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevLong w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_long_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_long_scalar } //-------------------------------------------------------- /** * Read attribute long_scalar_rww related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_long_scalar_rww(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_scalar_rww(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_scalar_rww) ENABLED START -----*/ attr.set_value(attr_long_scalar_rww_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_scalar_rww } //-------------------------------------------------------- /** * Write attribute long_scalar_rww related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_long_scalar_rww(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long_scalar_rww(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevLong w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long_scalar_rww) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::write_long_scalar_rww } //-------------------------------------------------------- /** * Write attribute long_scalar_w related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_long_scalar_w(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long_scalar_w(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevLong w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long_scalar_w) ENABLED START -----*/ DEBUG_STREAM << "long_scalar_w = " << w_val << endl; attr_long_scalar_w_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_long_scalar_w } //-------------------------------------------------------- /** * Read attribute no_value related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_no_value(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_no_value(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_no_value) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::read_no_value } //-------------------------------------------------------- /** * Read attribute short_scalar related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_short_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_scalar) ENABLED START -----*/ attr.set_value(attr_short_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_scalar } //-------------------------------------------------------- /** * Write attribute short_scalar related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_short_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_short_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevShort w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_short_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_short_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_short_scalar } //-------------------------------------------------------- /** * Read attribute short_scalar_ro related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_short_scalar_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_scalar_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_scalar_ro) ENABLED START -----*/ attr.set_value(attr_short_scalar_ro_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_scalar_ro } //-------------------------------------------------------- /** * Read attribute short_scalar_rww related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_short_scalar_rww(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_scalar_rww(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_scalar_rww) ENABLED START -----*/ attr.set_value(attr_short_scalar_rww_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_scalar_rww } //-------------------------------------------------------- /** * Write attribute short_scalar_rww related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_short_scalar_rww(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_short_scalar_rww(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevShort w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_short_scalar_rww) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::write_short_scalar_rww } //-------------------------------------------------------- /** * Write attribute short_scalar_w related method * Description: * * Data type: Tango::DevShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_short_scalar_w(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_short_scalar_w(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevShort w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_short_scalar_w) ENABLED START -----*/ DEBUG_STREAM << "short_scalar_w = " << w_val << endl; attr_short_scalar_w_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_short_scalar_w } //-------------------------------------------------------- /** * Read attribute string_scalar related method * Description: * * Data type: Tango::DevString * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_string_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_string_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_scalar) ENABLED START -----*/ attr.set_value(attr_string_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_scalar } //-------------------------------------------------------- /** * Write attribute string_scalar related method * Description: * * Data type: Tango::DevString * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_string_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_string_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevString w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_string_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_string_scalar_write = w_val; if (*attr_string_scalar_read) { delete[] *attr_string_scalar_read; size_t len = ::strlen(w_val) + 1; *attr_string_scalar_read = new char[len]; if (*attr_string_scalar_read) { ::memset(*attr_string_scalar_read, 0, len * sizeof(char)); ::strcpy(*attr_string_scalar_read, w_val); } } /*----- PROTECTED REGION END -----*/ // TangoTest::write_string_scalar } //-------------------------------------------------------- /** * Read attribute throw_exception related method * Description: * * Data type: Tango::DevLong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_throw_exception(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_throw_exception(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_throw_exception) ENABLED START -----*/ Tango::Except::throw_exception((const char *)"exception test", (const char *)"here is the exception you requested", (const char *)"TangoTest::read_throw_exception"); /*----- PROTECTED REGION END -----*/ // TangoTest::read_throw_exception } //-------------------------------------------------------- /** * Read attribute uchar_scalar related method * Description: * * Data type: Tango::DevUChar * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_uchar_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_uchar_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_uchar_scalar) ENABLED START -----*/ attr.set_value(attr_uchar_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_uchar_scalar } //-------------------------------------------------------- /** * Write attribute uchar_scalar related method * Description: * * Data type: Tango::DevUChar * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_uchar_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_uchar_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevUChar w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_uchar_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_uchar_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_uchar_scalar } //-------------------------------------------------------- /** * Read attribute ulong64_scalar related method * Description: * * Data type: Tango::DevULong64 * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_ulong64_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong64_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong64_scalar) ENABLED START -----*/ attr.set_value(attr_ulong64_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong64_scalar } //-------------------------------------------------------- /** * Write attribute ulong64_scalar related method * Description: * * Data type: Tango::DevULong64 * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_ulong64_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ulong64_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevULong64 w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ulong64_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_ulong64_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_ulong64_scalar } //-------------------------------------------------------- /** * Read attribute ushort_scalar related method * Description: * * Data type: Tango::DevUShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_ushort_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ushort_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ushort_scalar) ENABLED START -----*/ attr.set_value(attr_ushort_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ushort_scalar } //-------------------------------------------------------- /** * Write attribute ushort_scalar related method * Description: * * Data type: Tango::DevUShort * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_ushort_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ushort_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevUShort w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ushort_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_ushort_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_ushort_scalar } //-------------------------------------------------------- /** * Read attribute ulong_scalar related method * Description: * * Data type: Tango::DevULong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::read_ulong_scalar(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong_scalar(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong_scalar) ENABLED START -----*/ attr.set_value(attr_ulong_scalar_read); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong_scalar } //-------------------------------------------------------- /** * Write attribute ulong_scalar related method * Description: * * Data type: Tango::DevULong * Attr type: Scalar */ //-------------------------------------------------------- void TangoTest::write_ulong_scalar(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ulong_scalar(Tango::WAttribute &attr) entering... " << endl; // Retrieve write value Tango::DevULong w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ulong_scalar) ENABLED START -----*/ DEBUG_STREAM << "w_val = " << w_val << endl; attr_ulong_scalar_write = w_val; /*----- PROTECTED REGION END -----*/ // TangoTest::write_ulong_scalar } //-------------------------------------------------------- /** * Read attribute boolean_spectrum related method * Description: * * Data type: Tango::DevBoolean * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_boolean_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_boolean_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_boolean_spectrum) ENABLED START -----*/ attr.set_value(attr_boolean_spectrum_read, dimBooleanSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_boolean_spectrum } //-------------------------------------------------------- /** * Write attribute boolean_spectrum related method * Description: * * Data type: Tango::DevBoolean * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_boolean_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_boolean_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevBoolean *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_boolean_spectrum) ENABLED START -----*/ const bool * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_boolean_spectrum_read, p, len * sizeof(Tango::DevBoolean)); dimBooleanSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_boolean_spectrum } //-------------------------------------------------------- /** * Read attribute boolean_spectrum_ro related method * Description: * * Data type: Tango::DevBoolean * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_boolean_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_boolean_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_boolean_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_boolean_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_boolean_spectrum_ro } //-------------------------------------------------------- /** * Read attribute double_spectrum related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_double_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_spectrum) ENABLED START -----*/ attr.set_value(attr_double_spectrum_read, dimDoubleSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_spectrum } //-------------------------------------------------------- /** * Write attribute double_spectrum related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_double_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_double_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevDouble *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_double_spectrum) ENABLED START -----*/ const double * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_double_spectrum_read, p, len * sizeof(Tango::DevDouble)); dimDoubleSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_double_spectrum } //-------------------------------------------------------- /** * Read attribute double_spectrum_ro related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_double_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_double_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_spectrum_ro } //-------------------------------------------------------- /** * Read attribute float_spectrum related method * Description: A float spectrum attribute * * Data type: Tango::DevFloat * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_float_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_float_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_float_spectrum) ENABLED START -----*/ attr.set_value(attr_float_spectrum_read, dimFloatSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_float_spectrum } //-------------------------------------------------------- /** * Write attribute float_spectrum related method * Description: A float spectrum attribute * * Data type: Tango::DevFloat * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_float_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_float_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevFloat *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_float_spectrum) ENABLED START -----*/ const float * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_float_spectrum_read, p, len * sizeof(Tango::DevFloat)); dimFloatSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_float_spectrum } //-------------------------------------------------------- /** * Read attribute float_spectrum_ro related method * Description: * * Data type: Tango::DevFloat * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_float_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_float_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_float_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_float_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_float_spectrum_ro } //-------------------------------------------------------- /** * Read attribute long64_spectrum_ro related method * Description: * * Data type: Tango::DevLong64 * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_long64_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long64_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long64_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_long64_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long64_spectrum_ro } //-------------------------------------------------------- /** * Read attribute long_spectrum related method * Description: * * Data type: Tango::DevLong * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_long_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_spectrum) ENABLED START -----*/ attr.set_value(attr_long_spectrum_read, dimLongSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_spectrum } //-------------------------------------------------------- /** * Write attribute long_spectrum related method * Description: * * Data type: Tango::DevLong * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_long_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevLong *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long_spectrum) ENABLED START -----*/ const Tango::DevLong * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_long_spectrum_read, p, len * sizeof(Tango::DevLong)); dimLongSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_long_spectrum } //-------------------------------------------------------- /** * Read attribute long_spectrum_ro related method * Description: * * Data type: Tango::DevLong * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_long_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_long_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_spectrum_ro } //-------------------------------------------------------- /** * Read attribute short_spectrum related method * Description: * * Data type: Tango::DevShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_short_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_spectrum) ENABLED START -----*/ attr.set_value(attr_short_spectrum_read, dimShortSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_spectrum } //-------------------------------------------------------- /** * Write attribute short_spectrum related method * Description: * * Data type: Tango::DevShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_short_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_short_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevShort *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_short_spectrum) ENABLED START -----*/ long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; const short * p; attr.get_write_value(p); len = attr.get_write_value_length(); DEBUG_STREAM << "Length from get_write_value_length:" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; DEBUG_STREAM << "Final length:" << len << endl; ::memcpy(attr_short_spectrum_read, p, len * sizeof(Tango::DevShort)); dimShortSpectrum = len; //::memcpy(attr_short_spectrum_read, p, len * sizeof(Tango::DevShort)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_short_spectrum } //-------------------------------------------------------- /** * Read attribute short_spectrum_ro related method * Description: * * Data type: Tango::DevShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_short_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_short_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_spectrum_ro } //-------------------------------------------------------- /** * Read attribute string_spectrum related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 256 */ //-------------------------------------------------------- void TangoTest::read_string_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_string_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_spectrum) ENABLED START -----*/ attr.set_value(attr_string_spectrum_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_spectrum } //-------------------------------------------------------- /** * Write attribute string_spectrum related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 256 */ //-------------------------------------------------------- void TangoTest::write_string_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_string_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::ConstDevString *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_string_spectrum) ENABLED START -----*/ const Tango::ConstDevString *p=NULL; attr.get_write_value(p); int len = attr.get_w_dim_x(); if (len > kSpecLen) len = kSpecLen; for (int i = 0; i < len; i++) { CORBA::string_free(attr_string_spectrum_read[i]); attr_string_spectrum_read[i] = CORBA::string_dup(p[i]); } /*----- PROTECTED REGION END -----*/ // TangoTest::write_string_spectrum } //-------------------------------------------------------- /** * Read attribute string_spectrum_ro related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 256 */ //-------------------------------------------------------- void TangoTest::read_string_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_string_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_string_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_spectrum_ro } //-------------------------------------------------------- /** * Read attribute uchar_spectrum related method * Description: An unsigned char spectrum attribute * * Data type: Tango::DevUChar * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_uchar_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_uchar_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_uchar_spectrum) ENABLED START -----*/ attr.set_value(attr_uchar_spectrum_read, dimUcharSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_uchar_spectrum } //-------------------------------------------------------- /** * Write attribute uchar_spectrum related method * Description: An unsigned char spectrum attribute * * Data type: Tango::DevUChar * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_uchar_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_uchar_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevUChar *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_uchar_spectrum) ENABLED START -----*/ const unsigned char * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_uchar_spectrum_read, p, len * sizeof(Tango::DevUChar)); dimUcharSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_uchar_spectrum } //-------------------------------------------------------- /** * Read attribute uchar_spectrum_ro related method * Description: * * Data type: Tango::DevUChar * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_uchar_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_uchar_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_uchar_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_uchar_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_uchar_spectrum_ro } //-------------------------------------------------------- /** * Read attribute ulong64_spectrum_ro related method * Description: * * Data type: Tango::DevULong64 * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_ulong64_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong64_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong64_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_ulong64_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong64_spectrum_ro } //-------------------------------------------------------- /** * Read attribute ulong_spectrum_ro related method * Description: * * Data type: Tango::DevULong * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_ulong_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_ulong_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong_spectrum_ro } //-------------------------------------------------------- /** * Read attribute ushort_spectrum related method * Description: An unsigned short spectrum attribute * * Data type: Tango::DevUShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_ushort_spectrum(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ushort_spectrum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ushort_spectrum) ENABLED START -----*/ attr.set_value(attr_ushort_spectrum_read, dimUshortSpectrum); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ushort_spectrum } //-------------------------------------------------------- /** * Write attribute ushort_spectrum related method * Description: An unsigned short spectrum attribute * * Data type: Tango::DevUShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::write_ushort_spectrum(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ushort_spectrum(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevUShort *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ushort_spectrum) ENABLED START -----*/ const unsigned short * p; attr.get_write_value(p); long len = attr.get_write_value_length(); DEBUG_STREAM << "Length :" << len << endl; len = (len <= kSpecLen) ? len : kSpecLen; ::memcpy(attr_ushort_spectrum_read, p, len * sizeof(Tango::DevUShort)); dimUshortSpectrum = len; /*----- PROTECTED REGION END -----*/ // TangoTest::write_ushort_spectrum } //-------------------------------------------------------- /** * Read attribute ushort_spectrum_ro related method * Description: * * Data type: Tango::DevUShort * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_ushort_spectrum_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ushort_spectrum_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ushort_spectrum_ro) ENABLED START -----*/ attr.set_value(attr_ushort_spectrum_ro_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ushort_spectrum_ro } //-------------------------------------------------------- /** * Read attribute wave related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 4096 */ //-------------------------------------------------------- void TangoTest::read_wave(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_wave(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_wave) ENABLED START -----*/ attr.set_value(attr_wave_read, kSpecLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_wave } //-------------------------------------------------------- /** * Read attribute boolean_image related method * Description: * * Data type: Tango::DevBoolean * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_boolean_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_boolean_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_boolean_image) ENABLED START -----*/ attr.set_value(attr_boolean_image_read, dimXBooleanImage, dimYBooleanImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_boolean_image } //-------------------------------------------------------- /** * Write attribute boolean_image related method * Description: * * Data type: Tango::DevBoolean * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_boolean_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_boolean_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevBoolean *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_boolean_image) ENABLED START -----*/ const bool * p; attr.get_write_value(p); dimXBooleanImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXBooleanImage << endl; dimYBooleanImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYBooleanImage << endl; long len = dimXBooleanImage * dimYBooleanImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_boolean_image_read, p, len * sizeof(Tango::DevBoolean)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_boolean_image } //-------------------------------------------------------- /** * Read attribute boolean_image_ro related method * Description: * * Data type: Tango::DevBoolean * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_boolean_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_boolean_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_boolean_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) boolean_image_lock.lock(); attr.set_value(attr_boolean_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&boolean_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_boolean_image_ro } //-------------------------------------------------------- /** * Read attribute double_image related method * Description: * * Data type: Tango::DevDouble * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_double_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_image) ENABLED START -----*/ attr.set_value(attr_double_image_read, dimXDoubleImage, dimYDoubleImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_image } //-------------------------------------------------------- /** * Write attribute double_image related method * Description: * * Data type: Tango::DevDouble * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_double_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_double_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevDouble *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_double_image) ENABLED START -----*/ const double * p; attr.get_write_value(p); dimXDoubleImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXDoubleImage << endl; dimYDoubleImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYDoubleImage << endl; long len = dimXDoubleImage * dimYDoubleImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_double_image_read, p, len * sizeof(Tango::DevDouble)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_double_image } //-------------------------------------------------------- /** * Read attribute double_image_ro related method * Description: * * Data type: Tango::DevDouble * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_double_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_double_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_double_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) double_image_lock.lock(); attr.set_value(attr_double_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&double_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_double_image_ro } //-------------------------------------------------------- /** * Read attribute float_image related method * Description: * * Data type: Tango::DevFloat * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_float_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_float_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_float_image) ENABLED START -----*/ attr.set_value(attr_float_image_read, dimXFloatImage, dimYFloatImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_float_image } //-------------------------------------------------------- /** * Write attribute float_image related method * Description: * * Data type: Tango::DevFloat * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_float_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_float_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevFloat *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_float_image) ENABLED START -----*/ const float * p; attr.get_write_value(p); dimXFloatImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXFloatImage << endl; dimYFloatImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYFloatImage << endl; long len = dimXFloatImage * dimYFloatImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_float_image_read, p, len * sizeof(Tango::DevFloat)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_float_image } //-------------------------------------------------------- /** * Read attribute float_image_ro related method * Description: A float image attribute * * Data type: Tango::DevFloat * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_float_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_float_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_float_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) float_image_lock.lock(); attr.set_value(attr_float_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&float_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_float_image_ro } //-------------------------------------------------------- /** * Read attribute long64_image_ro related method * Description: * * Data type: Tango::DevLong64 * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_long64_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long64_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long64_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) long64_image_lock.lock(); attr.set_value(attr_long64_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&long64_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long64_image_ro } //-------------------------------------------------------- /** * Read attribute long_image related method * Description: * * Data type: Tango::DevLong * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_long_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_image) ENABLED START -----*/ attr.set_value(attr_long_image_read, kImagLen, kImagLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_image } //-------------------------------------------------------- /** * Write attribute long_image related method * Description: * * Data type: Tango::DevLong * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_long_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_long_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevLong *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_long_image) ENABLED START -----*/ const long * p; attr.get_write_value(p); dimXLongImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXLongImage << endl; dimYLongImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYLongImage << endl; long len = dimXLongImage * dimYLongImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_long_image_read, p, len * sizeof(Tango::DevLong)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_long_image } //-------------------------------------------------------- /** * Read attribute long_image_ro related method * Description: * * Data type: Tango::DevLong * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_long_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_long_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_long_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) long_image_lock.lock(); attr.set_value(attr_long_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&long_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_long_image_ro } //-------------------------------------------------------- /** * Read attribute short_image related method * Description: * * Data type: Tango::DevShort * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_short_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_image) ENABLED START -----*/ attr.set_value(attr_short_image_read, dimXShortImage, dimYShortImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_image } //-------------------------------------------------------- /** * Write attribute short_image related method * Description: * * Data type: Tango::DevShort * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_short_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_short_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevShort *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_short_image) ENABLED START -----*/ const short * p; attr.get_write_value(p); dimXShortImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXShortImage << endl; dimYShortImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYShortImage << endl; long len = dimXShortImage * dimYShortImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_short_image_read, p, len * sizeof(Tango::DevShort)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_short_image } //-------------------------------------------------------- /** * Read attribute short_image_ro related method * Description: * * Data type: Tango::DevShort * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_short_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_short_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_short_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) short_image_lock.lock(); attr.set_value(attr_short_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&short_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_short_image_ro } //-------------------------------------------------------- /** * Read attribute string_image related method * Description: * * Data type: Tango::DevString * Attr type: Image max = 256 x 256 */ //-------------------------------------------------------- void TangoTest::read_string_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_string_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_image) ENABLED START -----*/ attr.set_value(attr_string_image_read, dimXStringImage, dimYStringImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_image } //-------------------------------------------------------- /** * Write attribute string_image related method * Description: * * Data type: Tango::DevString * Attr type: Image max = 256 x 256 */ //-------------------------------------------------------- void TangoTest::write_string_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_string_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::ConstDevString *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_string_image) ENABLED START -----*/ const Tango::ConstDevString *p=NULL; attr.get_write_value(p); dimXStringImage = attr.get_w_dim_x(); if (dimXStringImage > kImagLen) dimXStringImage = kImagLen; DEBUG_STREAM << "X :" << dimXStringImage << endl; dimYStringImage = attr.get_w_dim_y(); if (dimYStringImage > kImagLen) dimYStringImage = kImagLen; DEBUG_STREAM << "Y :" << dimYStringImage << endl; int i ,j, str_index; for (j = 0; j < dimYStringImage; j++) { for (i = 0; i < dimXStringImage; i++) { str_index = i + j * dimXStringImage; CORBA::string_free(attr_string_image_read[str_index]); attr_string_image_read[str_index] = CORBA::string_dup(p[str_index]); } } /*----- PROTECTED REGION END -----*/ // TangoTest::write_string_image } //-------------------------------------------------------- /** * Read attribute string_image_ro related method * Description: * * Data type: Tango::DevString * Attr type: Image max = 256 x 256 */ //-------------------------------------------------------- void TangoTest::read_string_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_string_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_image_ro) ENABLED START -----*/ attr.set_value(attr_string_image_ro_read, kImagLen, kImagLen); /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_image_ro } //-------------------------------------------------------- /** * Read attribute uchar_image related method * Description: * * Data type: Tango::DevUChar * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_uchar_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_uchar_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_uchar_image) ENABLED START -----*/ attr.set_value(attr_uchar_image_read, dimXUcharImage, dimYUcharImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_uchar_image } //-------------------------------------------------------- /** * Write attribute uchar_image related method * Description: * * Data type: Tango::DevUChar * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_uchar_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_uchar_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevUChar *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_uchar_image) ENABLED START -----*/ const unsigned char * p; attr.get_write_value(p); dimXUcharImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXUcharImage << endl; dimYUcharImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYUcharImage << endl; long len = dimXUcharImage * dimYUcharImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_uchar_image_read, p, len * sizeof(Tango::DevUChar)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_uchar_image } //-------------------------------------------------------- /** * Read attribute uchar_image_ro related method * Description: An unsigned char image attribute * * Data type: Tango::DevUChar * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_uchar_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_uchar_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_uchar_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) uchar_image_lock.lock(); attr.set_value(attr_uchar_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&uchar_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_uchar_image_ro } //-------------------------------------------------------- /** * Read attribute ulong64_image_ro related method * Description: * * Data type: Tango::DevULong64 * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_ulong64_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong64_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong64_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) ulong64_image_lock.lock(); attr.set_value(attr_ulong64_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&ulong64_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong64_image_ro } //-------------------------------------------------------- /** * Read attribute ulong_image_ro related method * Description: * * Data type: Tango::DevULong * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_ulong_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ulong_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ulong_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) ulong_image_lock.lock(); attr.set_value(attr_ulong_image_ro_read, kImagLen, kImagLen); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&ulong_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ulong_image_ro } //-------------------------------------------------------- /** * Read attribute ushort_image related method * Description: * * Data type: Tango::DevUShort * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::read_ushort_image(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ushort_image(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ushort_image) ENABLED START -----*/ attr.set_value(attr_ushort_image_read, dimXUshortImage, dimYUshortImage); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ushort_image } //-------------------------------------------------------- /** * Write attribute ushort_image related method * Description: * * Data type: Tango::DevUShort * Attr type: Image max = 251 x 251 */ //-------------------------------------------------------- void TangoTest::write_ushort_image(Tango::WAttribute &attr) { DEBUG_STREAM << "TangoTest::write_ushort_image(Tango::WAttribute &attr) entering... " << endl; // Retrieve number of write values int w_length = attr.get_write_value_length(); // Retrieve pointer on write values (Do not delete !) const Tango::DevUShort *w_val; attr.get_write_value(w_val); /*----- PROTECTED REGION ID(TangoTest::write_ushort_image) ENABLED START -----*/ const unsigned short * p; attr.get_write_value(p); dimXUshortImage = attr.get_w_dim_x(); DEBUG_STREAM << "X :" << dimXUshortImage << endl; dimYUshortImage = attr.get_w_dim_y(); DEBUG_STREAM << "Y :" << dimYUshortImage << endl; long len = dimXUshortImage * dimYUshortImage; len = (len <= kImagLen * kImagLen) ? len : kImagLen * kImagLen; ::memcpy(attr_ushort_image_read, p, len * sizeof(Tango::DevUShort)); /*----- PROTECTED REGION END -----*/ // TangoTest::write_ushort_image } //-------------------------------------------------------- /** * Read attribute ushort_image_ro related method * Description: An unsigned short image attribute * * Data type: Tango::DevUShort * Attr type: Image max = 8192 x 8192 */ //-------------------------------------------------------- void TangoTest::read_ushort_image_ro(Tango::Attribute &attr) { DEBUG_STREAM << "TangoTest::read_ushort_image_ro(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_ushort_image_ro) ENABLED START -----*/ if (mthreaded_impl != 0) ushort_image_lock.lock(); attr.set_value(attr_ushort_image_ro_read, uShort_image_ro_size, uShort_image_ro_size); if (mthreaded_impl != 0) attr.set_user_attr_mutex(&ushort_image_lock); /*----- PROTECTED REGION END -----*/ // TangoTest::read_ushort_image_ro } //-------------------------------------------------------- /** * Method : TangoTest::add_dynamic_attributes() * Description : Create the dynamic attributes if any * for specified device. */ //-------------------------------------------------------- void TangoTest::add_dynamic_attributes() { /*----- PROTECTED REGION ID(TangoTest::add_dynamic_attributes) ENABLED START -----*/ // Add your own code to create and add dynamic attributes if any /*----- PROTECTED REGION END -----*/ // TangoTest::add_dynamic_attributes } //-------------------------------------------------------- /** * Read pipe string_long_short_ro related method * Description: Pipe example */ //-------------------------------------------------------- void TangoTest::read_string_long_short_ro(Tango::Pipe &pipe) { DEBUG_STREAM << "TangoTest::read_string_long_short_ro(Tango::Pipe &pipe) entering... " << endl; /*----- PROTECTED REGION ID(TangoTest::read_string_long_short_ro) ENABLED START -----*/ vector de_names; de_names.push_back("FirstDE"); de_names.push_back("SecondDE"); de_names.push_back("ThirdDE"); pipe.set_data_elt_names(de_names); pipe << pi_str << pi_long << pi_short; /*----- PROTECTED REGION END -----*/ // TangoTest::read_string_long_short_ro } //-------------------------------------------------------- /** * Command CrashFromDevelopperThread related method * Description: Crashes the device! * */ //-------------------------------------------------------- void TangoTest::crash_from_developper_thread() { DEBUG_STREAM << "TangoTest::CrashFromDevelopperThread() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::crash_from_developper_thread) ENABLED START -----*/ // Add your own code #if defined(ENABLE_CRASH_REPORT) if (data_gen) data_gen->crash(); #else ERROR_STREAM << "Crash report disabled " << "[rebuild this device with ENABLE_CRASH_REPORT defined " << "and link against the breakpad_client library" << std::endl; #endif /*----- PROTECTED REGION END -----*/ // TangoTest::crash_from_developper_thread } //-------------------------------------------------------- /** * Command CrashFromOmniThread related method * Description: Crashes the device! * */ //-------------------------------------------------------- void TangoTest::crash_from_omni_thread() { DEBUG_STREAM << "TangoTest::CrashFromOmniThread() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::crash_from_omni_thread) ENABLED START -----*/ // Add your own code #if defined(ENABLE_CRASH_REPORT) // Add your own code to control device here int * invalid_ptr = 0; *invalid_ptr = 0; #else ERROR_STREAM << "Crash report disabled " << "[rebuild this device with ENABLE_CRASH_REPORT defined " << "and link against the breakpad_client library" << std::endl; #endif /*----- PROTECTED REGION END -----*/ // TangoTest::crash_from_omni_thread } //-------------------------------------------------------- /** * Command DevBoolean related method * Description: A DevBoolean comand example * * @param argin Any boolean value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevBoolean TangoTest::dev_boolean(Tango::DevBoolean argin) { Tango::DevBoolean argout; DEBUG_STREAM << "TangoTest::DevBoolean() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_boolean) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_boolean return argout; } //-------------------------------------------------------- /** * Command DevDouble related method * Description: A DevDouble command example * * @param argin Any DevDouble value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevDouble TangoTest::dev_double(Tango::DevDouble argin) { Tango::DevDouble argout; DEBUG_STREAM << "TangoTest::DevDouble() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_double) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_double return argout; } //-------------------------------------------------------- /** * Command DevFloat related method * Description: A DevFloat command example * * @param argin Any DevFloat value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevFloat TangoTest::dev_float(Tango::DevFloat argin) { Tango::DevFloat argout; DEBUG_STREAM << "TangoTest::DevFloat() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_float) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_float return argout; } //-------------------------------------------------------- /** * Command DevLong related method * Description: A DevLong command example * * @param argin Any DevLong value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevLong TangoTest::dev_long(Tango::DevLong argin) { Tango::DevLong argout; DEBUG_STREAM << "TangoTest::DevLong() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_long) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_long return argout; } //-------------------------------------------------------- /** * Command DevLong64 related method * Description: A DevLong command example * * @param argin Any DevLong64 value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevLong64 TangoTest::dev_long64(Tango::DevLong64 argin) { Tango::DevLong64 argout; DEBUG_STREAM << "TangoTest::DevLong64() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_long64) ENABLED START -----*/ // Add your own code return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_long64 return argout; } //-------------------------------------------------------- /** * Command DevShort related method * Description: A DevShort command example * * @param argin Any DevShort value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevShort TangoTest::dev_short(Tango::DevShort argin) { Tango::DevShort argout; DEBUG_STREAM << "TangoTest::DevShort() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_short) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_short return argout; } //-------------------------------------------------------- /** * Command DevString related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevString TangoTest::dev_string(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "TangoTest::DevString() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_string) ENABLED START -----*/ // Add your own code // Allocate argout argout = new char [::strlen(argin) + 1]; if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevString" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_string"); } // Tangotest : just send back input argument ::strcpy(argout, argin); /*----- PROTECTED REGION END -----*/ // TangoTest::dev_string return argout; } //-------------------------------------------------------- /** * Command DevULong related method * Description: A DevULong command example * * @param argin Any DevULong * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevULong TangoTest::dev_ulong(Tango::DevULong argin) { Tango::DevULong argout; DEBUG_STREAM << "TangoTest::DevULong() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_ulong) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_ulong return argout; } //-------------------------------------------------------- /** * Command DevULong64 related method * Description: A DevULong64 command example * * @param argin Any DevULong64 value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevULong64 TangoTest::dev_ulong64(Tango::DevULong64 argin) { Tango::DevULong64 argout; DEBUG_STREAM << "TangoTest::DevULong64() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_ulong64) ENABLED START -----*/ // Add your own code return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_ulong64 return argout; } //-------------------------------------------------------- /** * Command DevUShort related method * Description: A DevUShort command example * * @param argin Any DevUShort value * @returns Echo of the argin value */ //-------------------------------------------------------- Tango::DevUShort TangoTest::dev_ushort(Tango::DevUShort argin) { Tango::DevUShort argout; DEBUG_STREAM << "TangoTest::DevUShort() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_ushort) ENABLED START -----*/ // Add your own code // Tangotest : just send back input argument return argin; /*----- PROTECTED REGION END -----*/ // TangoTest::dev_ushort return argout; } //-------------------------------------------------------- /** * Command DevVarCharArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarCharArray *TangoTest::dev_var_char_array(const Tango::DevVarCharArray *argin) { Tango::DevVarCharArray *argout; DEBUG_STREAM << "TangoTest::DevVarCharArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_char_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarCharArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarCharArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_char_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_char_array return argout; } //-------------------------------------------------------- /** * Command DevVarDoubleArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarDoubleArray *TangoTest::dev_var_double_array(const Tango::DevVarDoubleArray *argin) { Tango::DevVarDoubleArray *argout; DEBUG_STREAM << "TangoTest::DevVarDoubleArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_double_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarDoubleArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarDoubleArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_double_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_double_array return argout; } //-------------------------------------------------------- /** * Command DevVarDoubleStringArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarDoubleStringArray *TangoTest::dev_var_double_string_array(const Tango::DevVarDoubleStringArray *argin) { Tango::DevVarDoubleStringArray *argout; DEBUG_STREAM << "TangoTest::DevVarDoubleStringArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_double_string_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarDoubleStringArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarDoubleStringArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_double_string_array"); } // Tangotest : just send back input argument argout->dvalue = argin->dvalue; argout->svalue.length(argin->svalue.length()); for (unsigned int i = 0; i < argin->svalue.length(); i++) { argout->svalue[i] = CORBA::string_dup(argin->svalue[i]); } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_double_string_array return argout; } //-------------------------------------------------------- /** * Command DevVarFloatArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarFloatArray *TangoTest::dev_var_float_array(const Tango::DevVarFloatArray *argin) { Tango::DevVarFloatArray *argout; DEBUG_STREAM << "TangoTest::DevVarFloatArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_float_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarFloatArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarFloatArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_float_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_float_array return argout; } //-------------------------------------------------------- /** * Command DevVarLong64Array related method * Description: * * @param argin * @returns */ //-------------------------------------------------------- Tango::DevVarLong64Array *TangoTest::dev_var_long64_array(const Tango::DevVarLong64Array *argin) { Tango::DevVarLong64Array *argout; DEBUG_STREAM << "TangoTest::DevVarLong64Array() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_long64_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarLong64Array(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarLong64Array" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_long64_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) (*argout)[i] = (*argin)[i]; // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_long64_array return argout; } //-------------------------------------------------------- /** * Command DevVarLongArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarLongArray *TangoTest::dev_var_long_array(const Tango::DevVarLongArray *argin) { Tango::DevVarLongArray *argout; DEBUG_STREAM << "TangoTest::DevVarLongArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_long_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarLongArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarLongArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_long_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_long_array return argout; } //-------------------------------------------------------- /** * Command DevVarLongStringArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarLongStringArray *TangoTest::dev_var_long_string_array(const Tango::DevVarLongStringArray *argin) { Tango::DevVarLongStringArray *argout; DEBUG_STREAM << "TangoTest::DevVarLongStringArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_long_string_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarLongStringArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarLongStringArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_long_string_array"); } // Tangotest : just send back input argument argout->lvalue = argin->lvalue; argout->svalue.length(argin->svalue.length()); for (unsigned int i = 0; i < argin->svalue.length(); i++) { argout->svalue[i] = CORBA::string_dup(argin->svalue[i]); } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_long_string_array return argout; } //-------------------------------------------------------- /** * Command DevVarShortArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarShortArray *TangoTest::dev_var_short_array(const Tango::DevVarShortArray *argin) { Tango::DevVarShortArray *argout; DEBUG_STREAM << "TangoTest::DevVarShortArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_short_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarShortArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarShortArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_short_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_short_array return argout; } //-------------------------------------------------------- /** * Command DevVarStringArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarStringArray *TangoTest::dev_var_string_array(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "TangoTest::DevVarStringArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_string_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarStringArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarStringArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_string_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = CORBA::string_dup((*argin)[i]); } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_string_array return argout; } //-------------------------------------------------------- /** * Command DevVarULong64Array related method * Description: * * @param argin * @returns */ //-------------------------------------------------------- Tango::DevVarULong64Array *TangoTest::dev_var_ulong64_array(const Tango::DevVarULong64Array *argin) { Tango::DevVarULong64Array *argout; DEBUG_STREAM << "TangoTest::DevVarULong64Array() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_ulong64_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarULong64Array(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarULong64Array" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_ulong64_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) (*argout)[i] = (*argin)[i]; // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_ulong64_array return argout; } //-------------------------------------------------------- /** * Command DevVarULongArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarULongArray *TangoTest::dev_var_ulong_array(const Tango::DevVarULongArray *argin) { Tango::DevVarULongArray *argout; DEBUG_STREAM << "TangoTest::DevVarULongArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_ulong_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarULongArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarULongArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_ulong_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_ulong_array return argout; } //-------------------------------------------------------- /** * Command DevVarUShortArray related method * Description: none * * @param argin - * @returns - */ //-------------------------------------------------------- Tango::DevVarUShortArray *TangoTest::dev_var_ushort_array(const Tango::DevVarUShortArray *argin) { Tango::DevVarUShortArray *argout; DEBUG_STREAM << "TangoTest::DevVarUShortArray() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_var_ushort_array) ENABLED START -----*/ // Add your own code // Allocate argout argout = new Tango::DevVarUShortArray(); if (argout == 0) { TangoSys_OMemStream o; o << "Failed to allocate Tango::DevVarUShortArray" << ends; LOG_ERROR((o.str())); Tango::Except::throw_exception((const char *)"Out of memory error", o.str(), (const char *)"TangoTest::dev_var_ushort_array"); } // Tangotest : just send back input argument argout->length(argin->length()); for (unsigned int i = 0; i < argin->length(); i++) { (*argout)[i] = (*argin)[i]; } // DO NOT DELETE // See the TANGO programmer's manual section 7.2.3 // for more info about C++ memory management. /*----- PROTECTED REGION END -----*/ // TangoTest::dev_var_ushort_array return argout; } //-------------------------------------------------------- /** * Command DevVoid related method * Description: A DevVoid comand example * */ //-------------------------------------------------------- void TangoTest::dev_void() { DEBUG_STREAM << "TangoTest::DevVoid() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dev_void) ENABLED START -----*/ // Add your own code // Add your own code to control device here /*----- PROTECTED REGION END -----*/ // TangoTest::dev_void } //-------------------------------------------------------- /** * Command DumpExecutionState related method * Description: Forces mini dump generation * */ //-------------------------------------------------------- void TangoTest::dump_execution_state() { DEBUG_STREAM << "TangoTest::DumpExecutionState() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::dump_execution_state) ENABLED START -----*/ // Add your own code #if defined(ENABLE_CRASH_REPORT) TangoCrashHandler::dump_current_exec_state(); #else ERROR_STREAM << "Crash report disabled " << "[rebuild this device with ENABLE_CRASH_REPORT defined " << "and link against the breakpad_client library" << std::endl; #endif /*----- PROTECTED REGION END -----*/ // TangoTest::dump_execution_state } //-------------------------------------------------------- /** * Command SwitchStates related method * Description: This command changes the device state from RUNNING to FAULT or from FAULT to RUNNING * */ //-------------------------------------------------------- void TangoTest::switch_states() { DEBUG_STREAM << "TangoTest::SwitchStates() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoTest::switch_states) ENABLED START -----*/ // Add your own code if(get_state() == Tango::RUNNING) { set_state(Tango::FAULT); } else { set_state(Tango::RUNNING); } /*----- PROTECTED REGION END -----*/ // TangoTest::switch_states } //-------------------------------------------------------- /** * Method : TangoTest::add_dynamic_commands() * Description : Create the dynamic commands if any * for specified device. */ //-------------------------------------------------------- void TangoTest::add_dynamic_commands() { /*----- PROTECTED REGION ID(TangoTest::add_dynamic_commands) ENABLED START -----*/ // Add your own code to create and add dynamic commands if any /*----- PROTECTED REGION END -----*/ // TangoTest::add_dynamic_commands } /*----- PROTECTED REGION ID(TangoTest::namespace_ending) ENABLED START -----*/ // Additional Methods //============================================================================= // Standalone template function: generates a random in the range [0, max] //============================================================================= template inline T randomize (T max) { if (max > 1) { int r = ::rand(); r = r < 0 ? -r : r; return static_cast(r % static_cast(max)); } return 0; } //============================================================================= // Standalone template function: generates a random image //============================================================================= template void generate_full_image (T* buffer, long max_xy, long max_value, omni_mutex &lock) { lock.lock(); // For each pixel, we need to generate a random value between [0, max_value] for(long i=0; i void generate_image (T* buffer, long max_xy, omni_mutex &lock) { lock.lock(); long bimg_center_x = ::rand() % (int)(max_xy * 0.05); if (::rand() % 2) { bimg_center_x *= -1; } long bimg_center_y = ::rand() % (int)(max_xy * 0.05); if (::rand() % 2) { bimg_center_y *= -1; } long bimg_offset_to_zero = (max_xy - 1) / 2; long bimg_x_offset_to_zero = bimg_offset_to_zero + bimg_center_x; long bimg_y_offset_to_zero = bimg_offset_to_zero + bimg_center_y; long limit = max_xy / 8; long noise = ::rand() % (int)(limit * 0.2); if (::rand() % 2) { noise *= -1; } limit += noise; // Reset image content ::memset(buffer, 0, max_xy * max_xy * sizeof(T)); // Fill image buffer long i, j, x, y, value; for (i = -limit; i < limit; i++) { y = i + bimg_y_offset_to_zero; if (y >= 0 && y < max_xy) { for (j = -limit; j < limit; j++) { x = j + bimg_x_offset_to_zero; if (x >= 0 && x < max_xy) { value = (long)::sqrt((double)(i * i + j * j)); buffer[x * max_xy + y] = (T) ((value < limit) ? limit - value : 0); } } } } lock.unlock(); } //============================================================================= // TangoTest::gen_data //============================================================================= void TangoTest::gen_data () { // Generate data for all attributes static long k = 0; static const double kpi_deg = 3.14159 / 180.0; static const int boolean_generation_max_value = 2; static const int int_generation_max_value = 256; *attr_short_scalar_rww_read = randomize(attr_short_scalar_w_write); *attr_long_scalar_rww_read = randomize(attr_long_scalar_w_write); *attr_double_scalar_rww_read = attr_double_scalar_w_write * ::sin(kpi_deg * (k%360)); *attr_short_scalar_ro_read = randomize(attr_short_scalar_write); *attr_short_scalar_read = randomize(attr_short_scalar_write); *attr_long_scalar_read = randomize(attr_long_scalar_write); *attr_ulong_scalar_read = randomize(attr_ulong_scalar_write); *attr_long64_scalar_read = randomize(attr_long_scalar_write); *attr_ulong64_scalar_read = randomize(attr_ulong_scalar_write); *attr_double_scalar_read = attr_double_scalar_write * ::sin(kpi_deg * (k%360)); *attr_ushort_scalar_read = randomize(attr_ushort_scalar_write); *attr_uchar_scalar_read = randomize(attr_uchar_scalar_write); *attr_float_scalar_read = randomize(attr_float_scalar_write); int i, j; for (i = 0; i < kSpecLen; i++) attr_short_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_long_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_ulong_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_long64_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_ulong64_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_double_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_wave_read[i] = attr_ampli_write * ::sin(kpi_deg * (i + (k%360))); for (i = 0; i < kSpecLen; i++) attr_boolean_spectrum_ro_read[i] = randomize(boolean_generation_max_value) ? true : false; for (i = 0; i < kSpecLen; i++) attr_ushort_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_uchar_spectrum_ro_read[i] = randomize(int_generation_max_value); for (i = 0; i < kSpecLen; i++) attr_float_spectrum_ro_read[i] = (float) randomize(int_generation_max_value); generate_image(attr_short_image_ro_read, kImagLen, short_image_lock); generate_image(attr_long_image_ro_read, kImagLen, long_image_lock); generate_image(attr_ulong_image_ro_read, kImagLen, ulong64_image_lock); generate_image(attr_long64_image_ro_read, kImagLen, long64_image_lock); generate_image(attr_ulong64_image_ro_read, kImagLen, ulong64_image_lock); generate_image(attr_float_image_ro_read, kImagLen, float_image_lock); generate_image(attr_double_image_ro_read, kImagLen, double_image_lock); generate_full_image(attr_boolean_image_ro_read, kImagLen, boolean_generation_max_value, boolean_image_lock); generate_full_image(attr_uchar_image_ro_read, kImagLen, int_generation_max_value, uchar_image_lock); generate_full_image(attr_ushort_image_ro_read, uShort_image_ro_size, int_generation_max_value, ushort_image_lock); for (i = 0; i < kSpecLen; i++) ::sprintf(attr_string_spectrum_ro_read[i],"[%.2d]::hello-world-%.4d", i, randomize(int_generation_max_value)); for (j = 0; j < kImagLen; j++) for (i = 0; i < kImagLen; i++) ::sprintf(attr_string_image_ro_read[ i + j * kImagLen], "[%.2d][%.2d]::hello world::%.4d", i, j, randomize(int_generation_max_value)); k++; } /*----- PROTECTED REGION END -----*/ // TangoTest::namespace_ending } // namespace tango-9.2.5a/cppserver/tangotest/TangoTestStateMachine.cpp0000644023471100065110000017106613034745031020664 00000000000000/*----- PROTECTED REGION ID(TangoTestStateMachine.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoTestStateMachine.cpp 28108 2015-06-24 12:29:54Z taurel $"; //============================================================================= // // file : TangoTestStateMachine.cpp // // description : State machine file for the TangoTest class // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 28108 $ // $Date: 2015-06-24 14:29:54 +0200 (Wed, 24 Jun 2015) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include /*----- PROTECTED REGION END -----*/ // TangoTest::TangoTestStateMachine.cpp //================================================================ // States | Description //================================================================ // FAULT | This state disables all commands // RUNNING | This state allows all the commands to be sent namespace TangoTest_ns { //================================================= // Attributes Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : TangoTest::is_ampli_allowed() * Description : Execution allowed for ampli attribute */ //-------------------------------------------------------- bool TangoTest::is_ampli_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ampli attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ampliStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ampliStateAllowed_WRITE return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_boolean_scalar_allowed() * Description : Execution allowed for boolean_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_boolean_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for boolean_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::boolean_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_scalarStateAllowed_WRITE // Not any excluded states for boolean_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::boolean_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_scalar_allowed() * Description : Execution allowed for double_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_double_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::double_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_scalarStateAllowed_WRITE // Not any excluded states for double_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_scalar_rww_allowed() * Description : Execution allowed for double_scalar_rww attribute */ //-------------------------------------------------------- bool TangoTest::is_double_scalar_rww_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_scalar_rww attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::double_scalar_rwwStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_scalar_rwwStateAllowed_WRITE // Not any excluded states for double_scalar_rww attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_scalar_rwwStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_scalar_rwwStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_scalar_w_allowed() * Description : Execution allowed for double_scalar_w attribute */ //-------------------------------------------------------- bool TangoTest::is_double_scalar_w_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_scalar_w attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::double_scalar_wStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_scalar_wStateAllowed_WRITE return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_float_scalar_allowed() * Description : Execution allowed for float_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_float_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for float_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::float_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_scalarStateAllowed_WRITE // Not any excluded states for float_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::float_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long64_scalar_allowed() * Description : Execution allowed for long64_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_long64_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long64_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long64_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long64_scalarStateAllowed_WRITE // Not any excluded states for long64_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long64_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long64_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_scalar_allowed() * Description : Execution allowed for long_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_long_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_scalarStateAllowed_WRITE // Not any excluded states for long_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_scalar_rww_allowed() * Description : Execution allowed for long_scalar_rww attribute */ //-------------------------------------------------------- bool TangoTest::is_long_scalar_rww_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_scalar_rww attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long_scalar_rwwStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_scalar_rwwStateAllowed_WRITE // Not any excluded states for long_scalar_rww attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_scalar_rwwStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_scalar_rwwStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_scalar_w_allowed() * Description : Execution allowed for long_scalar_w attribute */ //-------------------------------------------------------- bool TangoTest::is_long_scalar_w_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_scalar_w attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long_scalar_wStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_scalar_wStateAllowed_WRITE return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_no_value_allowed() * Description : Execution allowed for no_value attribute */ //-------------------------------------------------------- bool TangoTest::is_no_value_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for no_value attribute in read access. /*----- PROTECTED REGION ID(TangoTest::no_valueStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::no_valueStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_scalar_allowed() * Description : Execution allowed for short_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_short_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::short_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalarStateAllowed_WRITE // Not any excluded states for short_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_scalar_ro_allowed() * Description : Execution allowed for short_scalar_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_short_scalar_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_scalar_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_scalar_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalar_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_scalar_rww_allowed() * Description : Execution allowed for short_scalar_rww attribute */ //-------------------------------------------------------- bool TangoTest::is_short_scalar_rww_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_scalar_rww attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::short_scalar_rwwStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalar_rwwStateAllowed_WRITE // Not any excluded states for short_scalar_rww attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_scalar_rwwStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalar_rwwStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_scalar_w_allowed() * Description : Execution allowed for short_scalar_w attribute */ //-------------------------------------------------------- bool TangoTest::is_short_scalar_w_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_scalar_w attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::short_scalar_wStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_scalar_wStateAllowed_WRITE return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_string_scalar_allowed() * Description : Execution allowed for string_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_string_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for string_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::string_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_scalarStateAllowed_WRITE // Not any excluded states for string_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::string_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_throw_exception_allowed() * Description : Execution allowed for throw_exception attribute */ //-------------------------------------------------------- bool TangoTest::is_throw_exception_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for throw_exception attribute in read access. /*----- PROTECTED REGION ID(TangoTest::throw_exceptionStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::throw_exceptionStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_uchar_scalar_allowed() * Description : Execution allowed for uchar_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_uchar_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for uchar_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::uchar_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_scalarStateAllowed_WRITE // Not any excluded states for uchar_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::uchar_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong64_scalar_allowed() * Description : Execution allowed for ulong64_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong64_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong64_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ulong64_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong64_scalarStateAllowed_WRITE // Not any excluded states for ulong64_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong64_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong64_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ushort_scalar_allowed() * Description : Execution allowed for ushort_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_ushort_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ushort_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ushort_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_scalarStateAllowed_WRITE // Not any excluded states for ushort_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ushort_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong_scalar_allowed() * Description : Execution allowed for ulong_scalar attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong_scalar_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong_scalar attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ulong_scalarStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong_scalarStateAllowed_WRITE // Not any excluded states for ulong_scalar attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong_scalarStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong_scalarStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_boolean_spectrum_allowed() * Description : Execution allowed for boolean_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_boolean_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for boolean_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::boolean_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_spectrumStateAllowed_WRITE // Not any excluded states for boolean_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::boolean_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_boolean_spectrum_ro_allowed() * Description : Execution allowed for boolean_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_boolean_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for boolean_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::boolean_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_spectrum_allowed() * Description : Execution allowed for double_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_double_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::double_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_spectrumStateAllowed_WRITE // Not any excluded states for double_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_spectrum_ro_allowed() * Description : Execution allowed for double_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_double_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_float_spectrum_allowed() * Description : Execution allowed for float_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_float_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for float_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::float_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_spectrumStateAllowed_WRITE // Not any excluded states for float_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::float_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_float_spectrum_ro_allowed() * Description : Execution allowed for float_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_float_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for float_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::float_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long64_spectrum_ro_allowed() * Description : Execution allowed for long64_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_long64_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long64_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long64_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long64_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_spectrum_allowed() * Description : Execution allowed for long_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_long_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_spectrumStateAllowed_WRITE // Not any excluded states for long_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_spectrum_ro_allowed() * Description : Execution allowed for long_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_long_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_spectrum_allowed() * Description : Execution allowed for short_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_short_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::short_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_spectrumStateAllowed_WRITE // Not any excluded states for short_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_spectrum_ro_allowed() * Description : Execution allowed for short_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_short_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_string_spectrum_allowed() * Description : Execution allowed for string_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_string_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for string_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::string_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_spectrumStateAllowed_WRITE // Not any excluded states for string_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::string_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_string_spectrum_ro_allowed() * Description : Execution allowed for string_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_string_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for string_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::string_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_uchar_spectrum_allowed() * Description : Execution allowed for uchar_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_uchar_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for uchar_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::uchar_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_spectrumStateAllowed_WRITE // Not any excluded states for uchar_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::uchar_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_uchar_spectrum_ro_allowed() * Description : Execution allowed for uchar_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_uchar_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for uchar_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::uchar_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong64_spectrum_ro_allowed() * Description : Execution allowed for ulong64_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong64_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong64_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong64_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong64_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong_spectrum_ro_allowed() * Description : Execution allowed for ulong_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ushort_spectrum_allowed() * Description : Execution allowed for ushort_spectrum attribute */ //-------------------------------------------------------- bool TangoTest::is_ushort_spectrum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ushort_spectrum attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ushort_spectrumStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_spectrumStateAllowed_WRITE // Not any excluded states for ushort_spectrum attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ushort_spectrumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_spectrumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ushort_spectrum_ro_allowed() * Description : Execution allowed for ushort_spectrum_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ushort_spectrum_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ushort_spectrum_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ushort_spectrum_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_spectrum_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_wave_allowed() * Description : Execution allowed for wave attribute */ //-------------------------------------------------------- bool TangoTest::is_wave_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for wave attribute in read access. /*----- PROTECTED REGION ID(TangoTest::waveStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::waveStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_boolean_image_allowed() * Description : Execution allowed for boolean_image attribute */ //-------------------------------------------------------- bool TangoTest::is_boolean_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for boolean_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::boolean_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_imageStateAllowed_WRITE // Not any excluded states for boolean_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::boolean_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_boolean_image_ro_allowed() * Description : Execution allowed for boolean_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_boolean_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for boolean_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::boolean_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::boolean_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_image_allowed() * Description : Execution allowed for double_image attribute */ //-------------------------------------------------------- bool TangoTest::is_double_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::double_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_imageStateAllowed_WRITE // Not any excluded states for double_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_double_image_ro_allowed() * Description : Execution allowed for double_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_double_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for double_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::double_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::double_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_float_image_allowed() * Description : Execution allowed for float_image attribute */ //-------------------------------------------------------- bool TangoTest::is_float_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for float_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::float_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_imageStateAllowed_WRITE // Not any excluded states for float_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::float_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_float_image_ro_allowed() * Description : Execution allowed for float_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_float_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for float_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::float_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::float_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long64_image_ro_allowed() * Description : Execution allowed for long64_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_long64_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long64_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long64_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long64_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_image_allowed() * Description : Execution allowed for long_image attribute */ //-------------------------------------------------------- bool TangoTest::is_long_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::long_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_imageStateAllowed_WRITE // Not any excluded states for long_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_long_image_ro_allowed() * Description : Execution allowed for long_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_long_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for long_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::long_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::long_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_image_allowed() * Description : Execution allowed for short_image attribute */ //-------------------------------------------------------- bool TangoTest::is_short_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::short_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_imageStateAllowed_WRITE // Not any excluded states for short_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_short_image_ro_allowed() * Description : Execution allowed for short_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_short_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for short_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::short_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::short_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_string_image_allowed() * Description : Execution allowed for string_image attribute */ //-------------------------------------------------------- bool TangoTest::is_string_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for string_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::string_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_imageStateAllowed_WRITE // Not any excluded states for string_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::string_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_string_image_ro_allowed() * Description : Execution allowed for string_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_string_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for string_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::string_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_uchar_image_allowed() * Description : Execution allowed for uchar_image attribute */ //-------------------------------------------------------- bool TangoTest::is_uchar_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for uchar_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::uchar_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_imageStateAllowed_WRITE // Not any excluded states for uchar_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::uchar_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_uchar_image_ro_allowed() * Description : Execution allowed for uchar_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_uchar_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for uchar_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::uchar_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::uchar_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong64_image_ro_allowed() * Description : Execution allowed for ulong64_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong64_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong64_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong64_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong64_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ulong_image_ro_allowed() * Description : Execution allowed for ulong_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ulong_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ulong_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ulong_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ulong_image_roStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ushort_image_allowed() * Description : Execution allowed for ushort_image attribute */ //-------------------------------------------------------- bool TangoTest::is_ushort_image_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ushort_image attribute in Write access. /*----- PROTECTED REGION ID(TangoTest::ushort_imageStateAllowed_WRITE) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_imageStateAllowed_WRITE // Not any excluded states for ushort_image attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ushort_imageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_imageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_ushort_image_ro_allowed() * Description : Execution allowed for ushort_image_ro attribute */ //-------------------------------------------------------- bool TangoTest::is_ushort_image_ro_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for ushort_image_ro attribute in read access. /*----- PROTECTED REGION ID(TangoTest::ushort_image_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::ushort_image_roStateAllowed_READ return true; } //================================================= // pipe Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : TangoTest::is_string_long_short_ro_allowed() * Description : Execution allowed for string_long_short_ro pipe */ //-------------------------------------------------------- bool TangoTest::is_string_long_short_ro_allowed(TANGO_UNUSED(Tango::PipeReqType type)) { // Not any excluded states for string_long_short_ro pipe in read access. /*----- PROTECTED REGION ID(TangoTest::string_long_short_roStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::string_long_short_roStateAllowed_READ return true; } //================================================= // Commands Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : TangoTest::is_CrashFromDevelopperThread_allowed() * Description : Execution allowed for CrashFromDevelopperThread attribute */ //-------------------------------------------------------- bool TangoTest::is_CrashFromDevelopperThread_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for CrashFromDevelopperThread command. /*----- PROTECTED REGION ID(TangoTest::CrashFromDevelopperThreadStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::CrashFromDevelopperThreadStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_CrashFromOmniThread_allowed() * Description : Execution allowed for CrashFromOmniThread attribute */ //-------------------------------------------------------- bool TangoTest::is_CrashFromOmniThread_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for CrashFromOmniThread command. /*----- PROTECTED REGION ID(TangoTest::CrashFromOmniThreadStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::CrashFromOmniThreadStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevBoolean_allowed() * Description : Execution allowed for DevBoolean attribute */ //-------------------------------------------------------- bool TangoTest::is_DevBoolean_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevBoolean command. /*----- PROTECTED REGION ID(TangoTest::DevBooleanStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevBooleanStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevDouble_allowed() * Description : Execution allowed for DevDouble attribute */ //-------------------------------------------------------- bool TangoTest::is_DevDouble_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevDouble command. /*----- PROTECTED REGION ID(TangoTest::DevDoubleStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevDoubleStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevFloat_allowed() * Description : Execution allowed for DevFloat attribute */ //-------------------------------------------------------- bool TangoTest::is_DevFloat_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevFloat command. /*----- PROTECTED REGION ID(TangoTest::DevFloatStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevFloatStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevLong_allowed() * Description : Execution allowed for DevLong attribute */ //-------------------------------------------------------- bool TangoTest::is_DevLong_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevLong command. /*----- PROTECTED REGION ID(TangoTest::DevLongStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevLongStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevLong64_allowed() * Description : Execution allowed for DevLong64 attribute */ //-------------------------------------------------------- bool TangoTest::is_DevLong64_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevLong64 command. /*----- PROTECTED REGION ID(TangoTest::DevLong64StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevLong64StateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevShort_allowed() * Description : Execution allowed for DevShort attribute */ //-------------------------------------------------------- bool TangoTest::is_DevShort_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevShort command. /*----- PROTECTED REGION ID(TangoTest::DevShortStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevShortStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevString_allowed() * Description : Execution allowed for DevString attribute */ //-------------------------------------------------------- bool TangoTest::is_DevString_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevString command. /*----- PROTECTED REGION ID(TangoTest::DevStringStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevStringStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevULong_allowed() * Description : Execution allowed for DevULong attribute */ //-------------------------------------------------------- bool TangoTest::is_DevULong_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevULong command. /*----- PROTECTED REGION ID(TangoTest::DevULongStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevULongStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevULong64_allowed() * Description : Execution allowed for DevULong64 attribute */ //-------------------------------------------------------- bool TangoTest::is_DevULong64_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevULong64 command. /*----- PROTECTED REGION ID(TangoTest::DevULong64StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevULong64StateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevUShort_allowed() * Description : Execution allowed for DevUShort attribute */ //-------------------------------------------------------- bool TangoTest::is_DevUShort_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevUShort command. /*----- PROTECTED REGION ID(TangoTest::DevUShortStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevUShortStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarCharArray_allowed() * Description : Execution allowed for DevVarCharArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarCharArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarCharArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarCharArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarCharArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarDoubleArray_allowed() * Description : Execution allowed for DevVarDoubleArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarDoubleArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarDoubleArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarDoubleArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarDoubleArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarDoubleStringArray_allowed() * Description : Execution allowed for DevVarDoubleStringArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarDoubleStringArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarDoubleStringArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarDoubleStringArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarDoubleStringArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarFloatArray_allowed() * Description : Execution allowed for DevVarFloatArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarFloatArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarFloatArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarFloatArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarFloatArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarLong64Array_allowed() * Description : Execution allowed for DevVarLong64Array attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarLong64Array_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarLong64Array command. /*----- PROTECTED REGION ID(TangoTest::DevVarLong64ArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarLong64ArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarLongArray_allowed() * Description : Execution allowed for DevVarLongArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarLongArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarLongArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarLongArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarLongArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarLongStringArray_allowed() * Description : Execution allowed for DevVarLongStringArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarLongStringArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarLongStringArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarLongStringArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarLongStringArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarShortArray_allowed() * Description : Execution allowed for DevVarShortArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarShortArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarShortArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarShortArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarShortArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarStringArray_allowed() * Description : Execution allowed for DevVarStringArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarStringArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarStringArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarStringArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarStringArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarULong64Array_allowed() * Description : Execution allowed for DevVarULong64Array attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarULong64Array_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarULong64Array command. /*----- PROTECTED REGION ID(TangoTest::DevVarULong64ArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarULong64ArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarULongArray_allowed() * Description : Execution allowed for DevVarULongArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarULongArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarULongArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarULongArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarULongArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVarUShortArray_allowed() * Description : Execution allowed for DevVarUShortArray attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVarUShortArray_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVarUShortArray command. /*----- PROTECTED REGION ID(TangoTest::DevVarUShortArrayStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVarUShortArrayStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DevVoid_allowed() * Description : Execution allowed for DevVoid attribute */ //-------------------------------------------------------- bool TangoTest::is_DevVoid_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DevVoid command. /*----- PROTECTED REGION ID(TangoTest::DevVoidStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DevVoidStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_DumpExecutionState_allowed() * Description : Execution allowed for DumpExecutionState attribute */ //-------------------------------------------------------- bool TangoTest::is_DumpExecutionState_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DumpExecutionState command. /*----- PROTECTED REGION ID(TangoTest::DumpExecutionStateStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::DumpExecutionStateStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoTest::is_SwitchStates_allowed() * Description : Execution allowed for SwitchStates attribute */ //-------------------------------------------------------- bool TangoTest::is_SwitchStates_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for SwitchStates command. /*----- PROTECTED REGION ID(TangoTest::SwitchStatesStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoTest::SwitchStatesStateAllowed return true; } } // End of namespace tango-9.2.5a/cppserver/tangotest/main.cpp0000644023471100065110000000545613034745031015411 00000000000000/*----- PROTECTED REGION ID(TangoTest::main.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: main.cpp 22520 2013-04-25 08:38:15Z taurel $"; //============================================================================= // // file : main.cpp // // description : C++ source for the TangoTest device server main. // The main rule is to initialise (and create) the Tango // system and to create the DServerClass singleton. // The main should be the same for every Tango device server. // // project : TANGO Device Server for testing generic clients // // This file is part of Tango device class. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: taurel $ // // $Revision: 22520 $ // $Date: 2013-04-25 10:38:15 +0200 (Thu, 25 Apr 2013) $ // // $HeadURL: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #if defined(ENABLE_CRASH_REPORT) # include #else # define DECLARE_CRASH_HANDLER # define INSTALL_CRASH_HANDLER #endif DECLARE_CRASH_HANDLER; int main(int argc, char *argv[]) { INSTALL_CRASH_HANDLER; Tango::Util *tg = NULL; try { // Initialise the device server //---------------------------------------- tg = Tango::Util::init(argc,argv); // Create the device server singleton // which will create everything //---------------------------------------- tg->server_init(false); // Run the endless loop //---------------------------------------- cout << "Ready to accept request" << endl; tg->server_run(); } catch (bad_alloc) { cout << "Can't allocate memory to store device object !!!" << endl; cout << "Exiting" << endl; } catch (CORBA::Exception &e) { Tango::Except::print_exception(e); cout << "Received a CORBA_Exception" << endl; cout << "Exiting" << endl; } catch (...) { cout << "Received an unknown exception" << endl; cout << "Exiting" << endl; } tg->server_cleanup(); return(0); } /*----- PROTECTED REGION END -----*/ // TangoTest::main.cpp tango-9.2.5a/cppserver/database/0000755023471100065110000000000013034745261013570 500000000000000tango-9.2.5a/cppserver/database/Makefile.am0000644023471100065110000000334313034745007015545 00000000000000AM_CPPFLAGS = $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server \ $(DB_CFLAGS) \ $(ZLIB_CPPFLAGS) AM_CXXFLAGS= -Wall -D_FORTIFY_SOURCE=2 -O1 -fPIE LDADD = -L$(top_builddir)/lib/cpp/client -ltango -L$(top_builddir)/lib/cpp/log4tango/src \ -llog4tango $(DB_LDFLAGS) \ $(DB_LDLIBS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) $(LIBZMQ_LIBS) AM_LDFLAGS = -Wl,-z,now -pie bin_PROGRAMS=DataBaseds DataBaseds_SOURCES=ClassFactory.cpp \ DataBaseClass.cpp \ DataBase.cpp \ DataBaseStateMachine.cpp \ main.cpp \ update_starter.cpp \ DataBaseUtils.cpp \ DataBase.h \ DataBaseClass.h \ update_starter.h if TANGO_DB_CREATE_ENABLED dbdir=${pkgdatadir}/db db_DATA=create_db.sh create_db.sql my.cnf create_db_tables.sql stored_proc.sql update_db.sh update_db.sql update_db8.sql update_db7.sql rem_history.sql ## This is to make sure that the create-db script is run on each make all. ## See create_db.sh for more information. all-local: .force $(SHELL) ${top_builddir}/cppserver/database/create_db.sh < ${top_builddir}/cppserver/database/create_db.sql endif EXTRA_DIST = create_db.sh.in create_db.sql.in my.cnf.in create_db_tables.sql.in stored_proc.sql.in \ update_db.sh.in update_db8.sql.in update_db7.sql.in update_db.sql.in rem_history.sql.in .force: tango-9.2.5a/cppserver/database/Makefile.in0000644023471100065110000006603513034745121015562 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = DataBaseds$(EXEEXT) subdir = cppserver/database DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/create_db.sh.in $(srcdir)/create_db.sql.in \ $(srcdir)/create_db_tables.sql.in $(srcdir)/my.cnf.in \ $(srcdir)/rem_history.sql.in $(srcdir)/stored_proc.sql.in \ $(srcdir)/update_db.sh.in $(srcdir)/update_db.sql.in \ $(srcdir)/update_db7.sql.in $(srcdir)/update_db8.sql.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = create_db.sql create_db.sh my.cnf stored_proc.sql \ create_db_tables.sql update_db.sh update_db.sql update_db8.sql \ update_db7.sql rem_history.sql CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dbdir)" PROGRAMS = $(bin_PROGRAMS) am_DataBaseds_OBJECTS = ClassFactory.$(OBJEXT) DataBaseClass.$(OBJEXT) \ DataBase.$(OBJEXT) DataBaseStateMachine.$(OBJEXT) \ main.$(OBJEXT) update_starter.$(OBJEXT) \ DataBaseUtils.$(OBJEXT) DataBaseds_OBJECTS = $(am_DataBaseds_OBJECTS) DataBaseds_LDADD = $(LDADD) am__DEPENDENCIES_1 = DataBaseds_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(DataBaseds_SOURCES) DIST_SOURCES = $(DataBaseds_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } DATA = $(db_DATA) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = $(ORB_INCLUDE_PREFIX) $(LIBZMQ_CFLAGS) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server \ $(DB_CFLAGS) \ $(ZLIB_CPPFLAGS) AM_CXXFLAGS = -Wall -D_FORTIFY_SOURCE=2 -O1 -fPIE LDADD = -L$(top_builddir)/lib/cpp/client -ltango -L$(top_builddir)/lib/cpp/log4tango/src \ -llog4tango $(DB_LDFLAGS) \ $(DB_LDLIBS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS) $(LIBZMQ_LIBS) AM_LDFLAGS = -Wl,-z,now -pie DataBaseds_SOURCES = ClassFactory.cpp \ DataBaseClass.cpp \ DataBase.cpp \ DataBaseStateMachine.cpp \ main.cpp \ update_starter.cpp \ DataBaseUtils.cpp \ DataBase.h \ DataBaseClass.h \ update_starter.h @TANGO_DB_CREATE_ENABLED_TRUE@dbdir = ${pkgdatadir}/db @TANGO_DB_CREATE_ENABLED_TRUE@db_DATA = create_db.sh create_db.sql my.cnf create_db_tables.sql stored_proc.sql update_db.sh update_db.sql update_db8.sql update_db7.sql rem_history.sql EXTRA_DIST = create_db.sh.in create_db.sql.in my.cnf.in create_db_tables.sql.in stored_proc.sql.in \ update_db.sh.in update_db8.sql.in update_db7.sql.in update_db.sql.in rem_history.sql.in all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/database/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/database/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): create_db.sql: $(top_builddir)/config.status $(srcdir)/create_db.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ create_db.sh: $(top_builddir)/config.status $(srcdir)/create_db.sh.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ my.cnf: $(top_builddir)/config.status $(srcdir)/my.cnf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ stored_proc.sql: $(top_builddir)/config.status $(srcdir)/stored_proc.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ create_db_tables.sql: $(top_builddir)/config.status $(srcdir)/create_db_tables.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ update_db.sh: $(top_builddir)/config.status $(srcdir)/update_db.sh.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ update_db.sql: $(top_builddir)/config.status $(srcdir)/update_db.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ update_db8.sql: $(top_builddir)/config.status $(srcdir)/update_db8.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ update_db7.sql: $(top_builddir)/config.status $(srcdir)/update_db7.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rem_history.sql: $(top_builddir)/config.status $(srcdir)/rem_history.sql.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list DataBaseds$(EXEEXT): $(DataBaseds_OBJECTS) $(DataBaseds_DEPENDENCIES) $(EXTRA_DataBaseds_DEPENDENCIES) @rm -f DataBaseds$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(DataBaseds_OBJECTS) $(DataBaseds_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClassFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataBase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataBaseClass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataBaseStateMachine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataBaseUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update_starter.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dbDATA: $(db_DATA) @$(NORMAL_INSTALL) @list='$(db_DATA)'; test -n "$(dbdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dbdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dbdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbdir)" || exit $$?; \ done uninstall-dbDATA: @$(NORMAL_UNINSTALL) @list='$(db_DATA)'; test -n "$(dbdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(dbdir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am @TANGO_DB_CREATE_ENABLED_FALSE@all-local: all-am: Makefile $(PROGRAMS) $(DATA) all-local installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dbdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dbDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-dbDATA .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am all-local check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dbDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-dbDATA @TANGO_DB_CREATE_ENABLED_TRUE@all-local: .force @TANGO_DB_CREATE_ENABLED_TRUE@ $(SHELL) ${top_builddir}/cppserver/database/create_db.sh < ${top_builddir}/cppserver/database/create_db.sql .force: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/database/create_db.sh.in0000644023471100065110000000165613034745006016366 00000000000000mysql=@MYSQL@ mysql_admin=@MYSQL_ADMIN@ mysql_admin_passwd=@MYSQL_ADMIN_PASSWD@ mysql_host=@MYSQL_HOST@ db_name=@TANGO_DB_NAME@ srcdir=@srcdir@ if test "x$mysql_admin" = "x"; then user_switch=""; else user_switch="-u$x$mysql_admin"; fi if test "x$mysql_admin_passwd" = "x"; then passwd_switch=""; else passwd_switch="-p$mysql_admin_passwd" fi if test "x$mysql_host" = "x"; then host_switch=""; else host_switch="-h$mysql_host"; fi connect="$mysql $user_switch $passwd_switch $host_switch $db_name" if `echo quit | $connect >/dev/null 2>&1`; then if test "x$mysql_host" = "x"; then echo "The $db_name database is already defined on this host" else echo "The $db_name database is already defined on $mysql_host" fi echo "Please run " echo "$connect < ./update_db.sql" echo "manually to force a db update" else $mysql $user_switch $passwd_switch $host_switch < ./create_db.sql > /dev/null fi tango-9.2.5a/cppserver/database/create_db.sql.in0000644023471100065110000002172113034745007016547 00000000000000 CREATE DATABASE @TANGO_DB_NAME@; USE @TANGO_DB_NAME@; # # Create all database tables # source create_db_tables.sql # # Load the stored procedures # source stored_proc.sql # # Init the history identifiers # CALL init_history_ids(); # # Create entry for database device server in device table # DELETE FROM device WHERE server='DataBaseds/2'; INSERT INTO device VALUES ('sys/database/2',NULL,'sys','database','2',0,'nada','nada','DataBaseds/2',0,'DataBase','nada',NULL,NULL,'nada'); INSERT INTO device VALUES ('dserver/DataBaseds/2',NULL,'dserver','DataBaseds','2',0,'nada','nada','DataBaseds/2',0,'DServer','nada',NULL,NULL,'nada'); # # Create entry for test device server in device table # DELETE FROM device WHERE server='TangoTest/test'; INSERT INTO device VALUES ('sys/tg_test/1',NULL,'sys','tg_test','1',0,'nada','nada','TangoTest/test',0,'TangoTest','nada',NULL,NULL,'nada'); INSERT INTO device VALUES ('dserver/TangoTest/test',NULL,'dserver','TangoTest','test',0,'nada','nada','TangoTest/test',0,'DServer','nada',NULL,NULL,'nada'); # # Create entry for Tango Control Access in device table # DELETE FROM device WHERE server='TangoAccessControl/1'; DELETE FROM server WHERE name='tangoaccesscontrol/1'; INSERT INTO device VALUES ('sys/access_control/1',NULL,'sys','access_control','1',0,'nada','nada','TangoAccessControl/1',0,'TangoAccessControl','nada',NULL,NULL,'nada'); INSERT INTO device VALUES ('dserver/TangoAccessControl/1',NULL,'dserver','TangoAccessControl','1',0,'nada','nada','TangoAccessControl/1',0,'DServer','nada',NULL,NULL,'nada'); INSERT INTO server VALUES ('tangoaccesscontrol/1','',0,0); # # Create default user access # CALL @TANGO_DB_NAME@.init_tac_tables(); # # Create entries in the property_class tables for controlled access service # DELETE FROM property_class WHERE class='Database'; INSERT INTO property_class VALUES('Database','AllowedAccessCmd',1,'DbGetServerInfo',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',2,'DbGetServerNameList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',3,'DbGetInstanceNameList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',4,'DbGetDeviceServerClassList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',5,'DbGetDeviceList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',6,'DbGetDeviceDomainList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',7,'DbGetDeviceFamilyList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',8,'DbGetDeviceMemberList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',9,'DbGetClassList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',10,'DbGetDeviceAliasList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',11,'DbGetObjectList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',12,'DbGetPropertyList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',13,'DbGetProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',14,'DbGetClassPropertyList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',15,'DbGetClassProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',16,'DbGetDevicePropertyList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',17,'DbGetDeviceProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',18,'DbGetClassAttributeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',19,'DbGetDeviceAttributeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',20,'DbGetDeviceAttributeProperty2',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',21,'DbGetLoggingLevel',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',22,'DbGetAliasDevice',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',23,'DbGetClassForDevice',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',24,'DbGetClassInheritanceForDevice',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',25,'DbGetDataForServerCache',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',26,'DbInfo',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',27,'DbGetClassAttributeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',28,'DbGetClassAttributeProperty2',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',29,'DbMysqlSelect',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',30,'DbGetDeviceInfo',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',31,'DbGetDeviceWideList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',32,'DbImportEvent',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',33,'DbGetDeviceAlias',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',34,'DbGetCSDbServerList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',35,'DbGetDeviceClassList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',36,'DbGetDeviceExportedList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',37,'DbGetHostServerList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',38,'DbGetAttributeAlias2',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',39,'DbGetAliasAttribute',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',40,'DbGetClassPipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',41,'DbGetDevicePipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',42,'DbGetClassPipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',43,'DbGetDevicePipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',44,'DbGetAttributeAliasList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',45,'DbGetForwardedAttributeListForDevice',NOW(),NOW(),NULL); # # # DELETE FROM property_class WHERE class='DServer'; INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',1,'QueryClass',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',2,'QueryDevice',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',3,'EventSubscriptionChange',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',4,'DevPollStatus',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',5,'GetLoggingLevel',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',6,'GetLoggingTarget',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',7,'QueryWizardDevProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',8,'QueryWizardClassProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',9,'QuerySubDevice',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',10,'ZMQEventSubscriptionChange',NOW(),NOW(),NULL); # # # DELETE FROM property_class WHERE class='Starter'; INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',1,'DevReadLog',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',2,'DevStart',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',3,'DevGetRunningServers',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',4,'DevGetStopServers',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',5,'UpdateServersInfo',NOW(),NOW(),NULL); # # # DELETE FROM property_class WHERE class='TangoAccessControl'; INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',1,'GetUsers',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',2,'GetAddressByUser',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',3,'GetDeviceByUser',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',4,'GetAccess',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',5,'GetAllowedCommands',NOW(),NOW(),NULL); INSERT INTO property_class VALUES ('TangoAccessControl','AllowedAccessCmd',6,'GetAllowedCommandClassList',NOW(),NOW(),NULL); tango-9.2.5a/cppserver/database/create_db_tables.sql.in0000644023471100065110000002351713034745006020105 00000000000000 # # Table structure for table 'access_address' # CREATE TABLE IF NOT EXISTS access_address ( user varchar(255) default NULL, address varchar(255) default NULL, netmask varchar(255) default 'FF.FF.FF.FF', updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00' ) ENGINE=MyISAM; # # Table structure for table 'access_device' # CREATE TABLE IF NOT EXISTS access_device ( user varchar(255) default NULL, device varchar(255) default NULL, rights varchar(255) default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00' ) ENGINE=MyISAM; # # Table structure for table 'attribute_alias' # CREATE TABLE IF NOT EXISTS attribute_alias ( alias varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', device varchar(255) NOT NULL default '', attribute varchar(255) NOT NULL default '', updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_attribute_alias (alias(64),name(64)) ) ENGINE=MyISAM; # # Table structure for table 'attribute_class' # CREATE TABLE IF NOT EXISTS attribute_class ( class varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_attribute_class (class(64),name(64)) ) ENGINE=MyISAM; # # Table structure for table 'device' # CREATE TABLE IF NOT EXISTS device ( name varchar(255) NOT NULL default 'nada', alias varchar(255) default NULL, domain varchar(85) NOT NULL default 'nada', family varchar(85) NOT NULL default 'nada', member varchar(85) NOT NULL default 'nada', exported int(11) default 0, ior text, host varchar(255) NOT NULL default 'nada', server varchar(255) NOT NULL default 'nada', pid int(11) default 0, class varchar(255) NOT NULL default 'nada', version varchar(8) NOT NULL default 'nada', started datetime NULL default NULL, stopped datetime NULL default NULL, comment text, KEY name (name(64),alias(64)) ) ENGINE=MyISAM; # # Table structure for table 'event' # CREATE TABLE IF NOT EXISTS event ( name varchar(255) default NULL, exported int(11) default NULL, ior text, host varchar(255) default NULL, server varchar(255) default NULL, pid int(11) default NULL, version varchar(8) default NULL, started datetime NULL default NULL, stopped datetime NULL default NULL, KEY index_name (name(64)) ) ENGINE=MyISAM; # # Table structure for table 'property' # CREATE TABLE IF NOT EXISTS property ( object varchar(255) default NULL, name varchar(255) default NULL, count int(11) default NULL, value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_name (object(64),name(64)) ) ENGINE=MyISAM; # # Table structure for table 'property_attribute_class' # CREATE TABLE IF NOT EXISTS property_attribute_class ( class varchar(255) NOT NULL default '', attribute varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_property_attribute_class (class(64),attribute(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_attribute_device' # CREATE TABLE IF NOT EXISTS property_attribute_device ( device varchar(255) NOT NULL default '', attribute varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_property_attribute_device (device(64),attribute(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_class' # CREATE TABLE IF NOT EXISTS property_class ( class varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_property (class(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_device' # CREATE TABLE IF NOT EXISTS property_device ( device varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', domain varchar(255) NOT NULL default '', family varchar(255) NOT NULL default '', member varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_resource (device(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_pipe_class' # CREATE TABLE IF NOT EXISTS property_pipe_class ( class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_property_pipe_class (class(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_pipe_device' # CREATE TABLE IF NOT EXISTS property_pipe_device ( device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL default '2000-01-01 00:00:00', comment text, KEY index_property_pipe_device (device(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'server' # CREATE TABLE IF NOT EXISTS server ( name varchar(255) NOT NULL default '', host varchar(255) NOT NULL default '', mode int(11) default '0', level int(11) default '0', KEY index_name (name(64)) ) ENGINE=MyISAM; # # Tables for history identifiers # CREATE TABLE IF NOT EXISTS device_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS device_attribute_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS device_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS class_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS class_attribute_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS class_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS object_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; # # Tables for history # CREATE TABLE IF NOT EXISTS property_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, object varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_object (object), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_device_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, device varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_device (device), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_class_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, class varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_class (class), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_attribute_class_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, class varchar(255) NOT NULL default '', attribute varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_class (class), KEY index_attribute (attribute), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_attribute_device_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, device varchar(255) NOT NULL default '', attribute varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_device (device), KEY index_attribute (attribute), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_pipe_class_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_class (class), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_pipe_device_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_device (device), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; tango-9.2.5a/cppserver/database/my.cnf.in0000644023471100065110000005105613034745006015236 00000000000000#BEGIN CONFIG INFO #DESCR: 4GB RAM, InnoDB only, ACID, few connections, heavy queries #TYPE: SYSTEM #END CONFIG INFO # # This is a MySQL example config file for systems with 4GB of memory # running mostly MySQL using InnoDB only tables and performing complex # queries with few connections. # # You can copy this file to /etc/my.cnf to set global options, # mysql-data-dir/my.cnf to set server-specific options # (/usr/local/mysql/data for this installation) or to # ~/.my.cnf to set user-specific options. # # In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program # with the "--help" option. # # More detailed information about the individual options can also be # found in the manual. # # # The following options will be read by MySQL client applications. # Note that only client applications shipped by MySQL are guaranteed # to read this section. If you want your own MySQL client program to # honor these values, you need to specify it as an option during the # MySQL client library initialization. # [client] #password = [your_password] #user = [your_user] port = 3306 socket = /tmp/mysql.sock # *** Application-specific options follow here *** # # The MySQL server # [mysqld] # generic configuration options port = 3306 socket = /tmp/mysql.sock # back_log is the number of connections the operating system can keep in # the listen queue, before the MySQL connection manager thread has # processed them. If you have a very high connection rate and experience # "connection refused" errors, you might need to increase this value. # Check your OS documentation for the maximum value of this parameter. # Attempting to set back_log higher than your operating system limit # will have no effect. back_log = 50 # Don't listen on a TCP/IP port at all. This can be a security # enhancement, if all processes that need to connect to mysqld run # on the same host. All interaction with mysqld must be made via Unix # sockets or named pipes. # Note that using this option without enabling named pipes on Windows # (via the "enable-named-pipe" option) will render mysqld useless! #skip-networking #bind-address = 160.103.10.102 # The maximum amount of concurrent sessions the MySQL server will # allow. One of these connections will be reserved for a user with # SUPER privileges to allow the administrator to login even if the # connection limit has been reached. max_connections = 100 # Maximum amount of errors allowed per host. If this limit is reached, # the host will be blocked from connecting to the MySQL server until # "FLUSH HOSTS" has been run or the server was restarted. Invalid # passwords and other errors during the connect phase result in # increasing this value. See the "Aborted_connects" status variable for # global counter. max_connect_errors = 10 # The number of open tables for all threads. Increasing this value # increases the number of file descriptors that mysqld requires. # Therefore you have to make sure to set the amount of open files # allowed to at least 4096 in the variable "open-files-limit" in # section [mysqld_safe] table_cache = 512 # Enable external file level locking. Enabled file locking will have a # negative impact on performance, so only use it in case you have # multiple database instances running on the same files (note some # restrictions still apply!) or if you use other software relying on # locking MyISAM tables on file level. #external-locking skip-locking # The maximum size of a query packet the server can handle as well as # maximum query size server can process (Important when working with # large BLOBs). enlarged dynamically, for each connection. max_allowed_packet = 1M # The size of the cache to hold the SQL statements for the binary log # during a transaction. If you often use big, multi-statement # transactions you can increase this value to get more performance. All # statements from transactions are buffered in the binary log cache and # are being written to the binary log at once after the COMMIT. If the # transaction is larger than this value, temporary file on disk is used # instead. This buffer is allocated per connection on first update # statement in transaction #binlog_cache_size = 32K # Maximum allowed size for a single HEAP (in memory) table. This option # is a protection against the accidential creation of a very large HEAP # table which could otherwise use up all memory resources. #max_heap_table_size = 64M # Sort buffer is used to perform sorts for some ORDER BY and GROUP BY # queries. If sorted data does not fit into the sort buffer, a disk # based merge sort is used instead - See the "Sort_merge_passes" # status variable. Allocated per thread if sort is needed. sort_buffer_size = 8M # This buffer is used for the optimization of full JOINs (JOINs without # indexes). Such JOINs are very bad for performance in most cases # anyway, but setting this variable to a large value reduces the # performance impact. See the "Select_full_join" status variable for a # count of full JOINs. Allocated per thread if full join is found #join_buffer_size = 8M # How many threads we should keep in a cache for reuse. When a client # disconnects, the client's threads are put in the cache if there aren't # more than thread_cache_size threads from before. This greatly reduces # the amount of thread creations needed if you have a lot of new # connections. (Normally this doesn't give a notable performance # improvement if you have a good thread implementation.) thread_cache_size = 32 # This permits the application to give the threads system a hint for the # desired number of threads that should be run at the same time. This # value only makes sense on systems that support the thread_concurrency() # function call (Sun Solaris, for example). # You should try [number of CPUs]*(2..4) for thread_concurrency thread_concurrency = 8 # Query cache is used to cache SELECT results and later return them # without actual executing the same query once again. Having the query # cache enabled may result in significant speed improvements, if your # have a lot of identical queries and rarely changing tables. See the # "Qcache_lowmem_prunes" status variable to check if the current value # is high enough for your load. # Note: In case your tables change very often or if your queries are # textually different every time, the query cache may result in a # slowdown instead of a performance improvement. query_cache_size = 64M # Only cache result sets that are smaller than this limit. This is to # protect the query cache of a very large result set overwriting all # other query results. query_cache_limit = 1M # Minimum word length to be indexed by the full text search index. # You might wish to decrease it if you need to search for shorter words. # Note that you need to rebuild your FULLTEXT index, after you have # modified this value. #ft_min_word_len = 4 # If your system supports the memlock() function call, you might want to # enable this option while running MySQL to keep it locked in memory and # to avoid potential swapping out in case of high memory pressure. Good # for performance. #memlock # Table type which is used by default when creating new tables, if not # specified differently during the CREATE TABLE statement. default_table_type = MYISAM # Thread stack size to use. This amount of memory is always reserved at # connection time. MySQL itself usually needs no more than 64K of # memory, while if you use your own stack hungry UDF functions or your # OS requires more stack for some operations, you might need to set this # to a higher value. #thread_stack = 192K # Set the default transaction isolation level. Levels available are: # READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE #transaction_isolation = REPEATABLE-READ # Maximum size for internal (in-memory) temporary tables. If a table # grows larger than this value, it is automatically converted to disk # based table This limitation is for a single table. There can be many # of them. tmp_table_size = 64M # Enable binary logging. This is required for acting as a MASTER in a # replication configuration. You also need the binary log if you need # the ability to do point in time recovery from your latest backup. #log-bin=mysql-bin # If you're using replication with chained slaves (A->B->C), you need to # enable this option on server B. It enables logging of updates done by # the slave thread into the slave's binary log. #log_slave_updates # Enable the full query log. Every query (even ones with incorrect # syntax) that the server receives will be logged. This is useful for # debugging, it is usually disabled in production use. #log # Print warnings to the error log file. If you have any problem with # MySQL you should enable logging of warnings and examine the error log # for possible explanations. #log_warnings # Log slow queries. Slow queries are queries which take more than the # amount of time defined in "long_query_time" or which do not use # indexes well, if log_long_format is enabled. It is normally good idea # to have this turned on if you frequently add new queries to the # system. #log_slow_queries # All queries taking more than this amount of time (in seconds) will be # trated as slow. Do not use "1" as a value here, as this will result in # even very fast queries being logged from time to time (as MySQL # currently measures time with second accuracy only). #long_query_time = 2 # Log more information in the slow query log. Normally it is good to # have this turned on. This will enable logging of queries that are not # using indexes in addition to long running queries. #log_long_format # The directory used by MySQL for storing temporary files. For example, # it is used to perform disk based large sorts, as well as for internal # and explicit temporary tables. It might be good to put it on a # swapfs/tmpfs filesystem, if you do not create very large temporary # files. Alternatively you can put it on dedicated disk. You can # specify multiple paths here by separating them by ";" - they will then # be used in a round-robin fashion. #tmpdir = /tmp # *** Replication related settings # Unique server identification number between 1 and 2^32-1. This value # is required for both master and slave hosts. It defaults to 1 if # "master-host" is not set, but will MySQL will not function as a master # if it is omitted. server-id = 1 # Replication Slave (comment out master section to use this) # # To configure this host as a replication slave, you can choose between # two methods : # # 1) Use the CHANGE MASTER TO command (fully described in our manual) - # the syntax is: # # CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=, # MASTER_USER=, MASTER_PASSWORD= ; # # where you replace , , by quoted strings and # by the master's port number (3306 by default). # # Example: # # CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306, # MASTER_USER='joe', MASTER_PASSWORD='secret'; # # OR # # 2) Set the variables below. However, in case you choose this method, then # start replication for the first time (even unsuccessfully, for example # if you mistyped the password in master-password and the slave fails to # connect), the slave will create a master.info file, and any later # changes in this file to the variable values below will be ignored and # overridden by the content of the master.info file, unless you shutdown # the slave server, delete master.info and restart the slaver server. # For that reason, you may want to leave the lines below untouched # (commented) and instead use CHANGE MASTER TO (see above) # # required unique id between 2 and 2^32 - 1 # (and different from the master) # defaults to 2 if master-host is set # but will not function as a slave if omitted #server-id = 2 # # The replication master for this slave - required #master-host = # # The username the slave will use for authentication when connecting # to the master - required #master-user = # # The password the slave will authenticate with when connecting to # the master - required #master-password = # # The port the master is listening on. # optional - defaults to 3306 #master-port = # Make the slave read-only. Only users with the SUPER privilege and the # replication slave thread will be able to modify data on it. You can # use this to ensure that no applications will accidently modify data on # the slave instead of the master #read_only #*** MyISAM Specific options # Size of the Key Buffer, used to cache index blocks for MyISAM tables. # Do not set it larger than 30% of your available memory, as some memory # is also required by the OS to cache rows. Even if you're not using # MyISAM tables, you should still set it to 8-64M as it will also be # used for internal temporary disk tables. key_buffer_size = 64M # Size of the buffer used for doing full table scans of MyISAM tables. # Allocated per thread, if a full scan is needed. read_buffer_size = 8M # When reading rows in sorted order after a sort, the rows are read # through this buffer to avoid disk seeks. You can improve ORDER BY # performance a lot, if set this to a high value. # Allocated per thread, when needed. read_rnd_buffer_size = 8M # MyISAM uses special tree-like cache to make bulk inserts (that is, # INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA # INFILE) faster. This variable limits the size of the cache tree in # bytes per thread. Setting it to 0 will disable this optimisation. Do # not set it larger than "key_buffer_size" for optimal performance. # This buffer is allocated when a bulk insert is detected. bulk_insert_buffer_size = 16M # This buffer is allocated when MySQL needs to rebuild the index in # REPAIR, OPTIMIZE, ALTER table statements as well as in LOAD DATA INFILE # into an empty table. It is allocated per thread so be careful with # large settings. myisam_sort_buffer_size = 64M # The maximum size of the temporary file MySQL is allowed to use while # recreating the index (during REPAIR, ALTER TABLE or LOAD DATA INFILE. # If the file-size would be bigger than this, the index will be created # through the key cache (which is slower). #myisam_max_sort_file_size = 10G # If the temporary file used for fast index creation would be bigger # than using the key cache by the amount specified here, then prefer the # key cache method. This is mainly used to force long character keys in # large tables to use the slower key cache method to create the index. #myisam_max_extra_sort_file_size = 10G # If a table has more than one index, MyISAM can use more than one # thread to repair them by sorting in parallel. This makes sense if you # have multiple CPUs and plenty of memory. myisam_repair_threads = 1 # Automatically check and repair not properly closed MyISAM tables. myisam_recover # *** BDB Specific options *** # Use this option if you run a MySQL server with BDB support enabled but # you do not plan to use it. This will save memory and may speed up some # things. skip-bdb # *** INNODB Specific options *** # Use this option if you have a MySQL server with InnoDB support enabled # but you do not plan to use it. This will save memory and disk space # and speed up some things. #skip-innodb # Additional memory pool that is used by InnoDB to store metadata # information. If InnoDB requires more memory for this purpose it will # start to allocate it from the OS. As this is fast enough on most # recent operating systems, you normally do not need to change this # value. SHOW INNODB STATUS will display the current amount used. #innodb_additional_mem_pool_size = 16M # InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and # row data. The bigger you set this the less disk I/O is needed to # access data in tables. On a dedicated database server you may set this # parameter up to 80% of the machine physical memory size. Do not set it # too large, though, because competition of the physical memory may # cause paging in the operating system. Note that on 32bit systems you # might be limited to 2-3.5G of user level memory per process, so do not # set it too high. #innodb_buffer_pool_size = 2G # InnoDB stores data in one or more data files forming the tablespace. # If you have a single logical drive for your data, a single # autoextending file would be good enough. In other cases, a single file # per device is often a good choice. You can configure InnoDB to use raw # disk partitions as well - please refer to the manual for more info # about this. #innodb_data_file_path = ibdata1:10M:autoextend # Set this option if you would like the InnoDB tablespace files to be # stored in another location. By default this is the MySQL datadir. #innodb_data_home_dir = # Number of IO threads to use for async IO operations. This value is # hardcoded to 4 on Unix, but on Windows disk I/O may benefit from a # larger number. #innodb_file_io_threads = 4 # If you run into InnoDB tablespace corruption, setting this to a nonzero # value will likely help you to dump your tables. Start from value 1 and # increase it until you're able to dump the table successfully. #innodb_force_recovery=1 # Number of threads allowed inside the InnoDB kernel. The optimal value # depends highly on the application, hardware as well as the OS # scheduler properties. A too high value may lead to thread thrashing. #innodb_thread_concurrency = 16 # If set to 1, InnoDB will flush (fsync) the transaction logs to the # disk at each commit, which offers full ACID behavior. If you are # willing to compromise this safety, and you are running small # transactions, you may set this to 0 or 2 to reduce disk I/O to the # logs. Value 0 means that the log is only written to the log file and # the log file flushed to disk approximately once per second. Value 2 # means the log is written to the log file at each commit, but the log # file is only flushed to disk approximately once per second. #innodb_flush_log_at_trx_commit = 1 # Speed up InnoDB shutdown. This will disable InnoDB to do a full purge # and insert buffer merge on shutdown. It may increase shutdown time a # lot, but InnoDB will have to do it on the next startup instead. #innodb_fast_shutdown # The size of the buffer InnoDB uses for buffering log data. As soon as # it is full, InnoDB will have to flush it to disk. As it is flushed # once per second anyway, it does not make sense to have it very large # (even with long transactions). #innodb_log_buffer_size = 8M # Size of each log file in a log group. You should set the combined size # of log files to about 25%-100% of your buffer pool size to avoid # unneeded buffer pool flush activity on log file overwrite. However, # note that a larger logfile size will increase the time needed for the # recovery process. #innodb_log_file_size = 256M # Total number of files in the log group. A value of 2-3 is usually good # enough. #innodb_log_files_in_group = 3 # Location of the InnoDB log files. Default is the MySQL datadir. You # may wish to point it to a dedicated hard drive or a RAID1 volume for # improved performance #innodb_log_group_home_dir # Maximum allowed percentage of dirty pages in the InnoDB buffer pool. # If it is reached, InnoDB will start flushing them out agressively to # not run out of clean pages at all. This is a soft limit, not # guaranteed to be held. #innodb_max_dirty_pages_pct = 90 # The flush method InnoDB will use for Log. The tablespace always uses # doublewrite flush logic. The default value is "fdatasync", another # option is "O_DSYNC". #innodb_flush_method=O_DSYNC # How long an InnoDB transaction should wait for a lock to be granted # before being rolled back. InnoDB automatically detects transaction # deadlocks in its own lock table and rolls back the transaction. If you # use the LOCK TABLES command, or other transaction-safe storage engines # than InnoDB in the same transaction, then a deadlock may arise which # InnoDB cannot notice. In cases like this the timeout is useful to # resolve the situation. #innodb_lock_wait_timeout = 120 [mysqldump] # Do not buffer the whole result set in memory before writing it to # file. Required for dumping very large tables quick max_allowed_packet = 16M [mysql] no-auto-rehash # Only allow UPDATEs and DELETEs that use keys. #safe-updates [isamchk] key_buffer = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M [myisamchk] key_buffer = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout [mysqld_safe] # Increase the amount of open files allowed per process. Warning: Make # sure you have set the global system limit high enough! The high value # is required for a large number of opened tables #open-files-limit = 8192 pid-file=/usr/local/mysql/mysqld.pid tango-9.2.5a/cppserver/database/rem_history.sql.in0000644023471100065110000000115413034745007017201 00000000000000USE @TANGO_DB_NAME@; # # Update all history ids to 0 # UPDATE class_attribute_history_id SET id=0; UPDATE class_history_id SET id=0; UPDATE class_pipe_history_id SET id=0; UPDATE device_attribute_history_id SET id=0; UPDATE device_history_id SET id=0; UPDATE device_pipe_history_id SET id=0; UPDATE object_history_id SET id=0; # # Clean up history tables # DELETE FROM property_attribute_class_hist; DELETE FROM property_attribute_device_hist; DELETE FROM property_class_hist; DELETE FROM property_device_hist; DELETE FROM property_hist; DELETE FROM property_pipe_class_hist; DELETE FROM property_pipe_device_hist; tango-9.2.5a/cppserver/database/stored_proc.sql.in0000644023471100065110000010134613034745006017163 00000000000000DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.ds_start; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.import_event; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.import_device; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.class_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.dev_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.class_att_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.get_dev_list; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.dev_att_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.obj_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.class_pipe_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.dev_pipe_prop; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.proc_release_nb; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.init_history_ids; DROP PROCEDURE IF EXISTS @TANGO_DB_NAME@.init_tac_tables; ######################################################### # # # MAIN PROCEDURE # # # # Procedure input parameters: # # 1 - Device server name (executable/inst_name) # # 2 - Host name # # Procedure output parameters: # # 1 - A huge string with several elements and a # # separator set to 0 (binary 0) # # # ######################################################### # # If you change something in these procedures, do not forget # to also change the COMMENT part of the ds_start procedure # CREATE command # DELIMITER | CREATE PROCEDURE @TANGO_DB_NAME@.ds_start (IN ds_name VARCHAR(255), IN recev_host VARCHAR(255), OUT res_str MEDIUMBLOB) READS SQL DATA COMMENT 'release 1.13' proc: BEGIN DECLARE notifd_event_name VARCHAR(255) DEFAULT 'notifd/factory/'; DECLARE adm_dev_name VARCHAR(255) DEFAULT 'dserver/'; DECLARE done, dev_nb,class_nb INT DEFAULT 0; DECLARE tmp_class,d_name,rel_str VARCHAR(255); DECLARE dev_list BLOB; DECLARE start,pos,ds_pipe INT DEFAULT 1; DECLARE class_nb_pos INT; DECLARE ca_dev_name VARCHAR(255); DECLARE host VARCHAR(255); DECLARE cur_class_list CURSOR FOR SELECT DISTINCT class FROM @TANGO_DB_NAME@.device WHERE server = ds_name; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET adm_dev_name = CONCAT(adm_dev_name,ds_name); # # Do we have Tango release added in host name? # SET pos = LOCATE('%%',recev_host); IF pos != 0 THEN SET rel_str = SUBSTRING(recev_host,pos+2); SET host = SUBSTRING(recev_host,1,pos-1); IF rel_str >= 9 THEN SET ds_pipe = 1; ELSE SET ds_pipe = 0; END IF; ELSE SET ds_pipe = 0; SET host = recev_host; END IF; # # get procedure release number # IF ds_pipe = 1 THEN CALL @TANGO_DB_NAME@.proc_release_nb(res_str); END IF; # # import admin device # CALL @TANGO_DB_NAME@.import_device(adm_dev_name,res_str); IF LOCATE('Not Found',res_str) != 0 OR LOCATE('MySQL Error',res_str) != 0 THEN LEAVE proc; END IF; # # import event factory for notification service running on that host # SET notifd_event_name = CONCAT(notifd_event_name,host); CALL @TANGO_DB_NAME@.import_event(notifd_event_name,res_str); SET done = 0; IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR during import_event procedure for event factory'; LEAVE proc; END IF; # # import event channel for this server # CALL @TANGO_DB_NAME@.import_event(adm_dev_name,res_str); SET done = 0; IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR during import_event procedure for DS event channel'; LEAVE proc; END IF; # # Get all class properties for DServer class # CALL @TANGO_DB_NAME@.class_prop('DServer',res_str); SET done = 0; IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting DServer class property(ies)'; LEAVE proc; END IF; # # Get all class properties for Default class # CALL @TANGO_DB_NAME@.class_prop('Default',res_str); SET done = 0; IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting Default class property(ies)'; LEAVE proc; END IF; # # Get all device properties for admin device # CALL @TANGO_DB_NAME@.dev_prop(adm_dev_name,res_str); SET done = 0; # # # SET res_str = CONCAT_WS(CHAR(0),res_str,ds_name); SET class_nb_pos = LENGTH(res_str); # # A loop for each class embedded within the server # OPEN cur_class_list; REPEAT FETCH cur_class_list INTO tmp_class; IF NOT done THEN IF tmp_class != 'dserver' THEN SET class_nb = class_nb + 1; CALL @TANGO_DB_NAME@.class_prop(tmp_class,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting DS class(es) property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; CALL @TANGO_DB_NAME@.class_att_prop(tmp_class,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting DS class(es) attribute(s) property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; IF ds_pipe = 1 THEN CALL @TANGO_DB_NAME@.class_pipe_prop(tmp_class,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting DS class(es) pipe(s) property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; END IF; CALL @TANGO_DB_NAME@.get_dev_list(tmp_class,ds_name,res_str,dev_list,dev_nb); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting DS class(es) device list'; CLOSE cur_class_list; LEAVE proc; END IF; # # A loop for each device in the class # WHILE dev_nb > 0 DO SET pos = LOCATE(CHAR(0),dev_list,start); IF pos = 0 THEN SET d_name = SUBSTRING(dev_list,start); ELSE SET d_name = SUBSTRING(dev_list,start,pos-start); SET start = pos + 1; END IF; # select dev_list,d_name,pos,start; CALL @TANGO_DB_NAME@.dev_prop(d_name,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting device property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; CALL @TANGO_DB_NAME@.dev_att_prop(d_name,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting device attribute property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; IF ds_pipe = 1 THEN CALL @TANGO_DB_NAME@.dev_pipe_prop(d_name,res_str); IF LOCATE('MySQL Error',res_str) != 0 THEN SET res_str = 'MySQL ERROR while getting device pipe property(ies)'; CLOSE cur_class_list; LEAVE proc; END IF; END IF; SET dev_nb = dev_nb - 1; END WHILE; SET start = 1; END IF; END IF; UNTIL done END REPEAT; CLOSE cur_class_list; SET res_str = INSERT(res_str,class_nb_pos+1,1,CONCAT_WS(CONCAT(class_nb),CHAR(0),CHAR(0))); # # Get service(s) property # SET ca_dev_name = 'Empty'; CALL @TANGO_DB_NAME@.obj_prop('CtrlSystem',ca_dev_name,res_str); IF ca_dev_name != 'Empty' THEN # # import control access service device # CALL @TANGO_DB_NAME@.import_device(ca_dev_name,res_str); END IF; END proc| ######################################################### # # # IMPORT EVENT PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.import_event (IN ev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_ior TEXT; DECLARE tmp_version VARCHAR(8); DECLARE tmp_host VARCHAR(255); DECLARE tmp_ev_name VARCHAR(255); DECLARE tmp_ev_name_canon VARCHAR(255); DECLARE tmp_exp, tmp_pid, dot INT; DECLARE not_found INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET tmp_ev_name = ev_name; SET tmp_ev_name = REPLACE(tmp_ev_name,'_','\_'); SELECT exported,ior,version,pid,host INTO tmp_exp,tmp_ior,tmp_version,tmp_pid,tmp_host FROM @TANGO_DB_NAME@.event WHERE name = tmp_ev_name; IF not_found = 1 THEN SET dot = LOCATE('.',tmp_ev_name); IF dot != 0 THEN SET tmp_ev_name_canon = SUBSTRING(tmp_ev_name,1,dot - 1); SET not_found = 0; SELECT exported,ior,version,pid,host INTO tmp_exp,tmp_ior,tmp_version,tmp_pid,tmp_host FROM @TANGO_DB_NAME@.event WHERE name = tmp_ev_name_canon; IF not_found = 1 THEN SET res_str = CONCAT_WS(CHAR(0),res_str,ev_name,'Not Found'); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,ev_name,tmp_ior,tmp_version,tmp_host,CONCAT(tmp_exp),CONCAT(tmp_pid)); END IF; ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,ev_name,'Not Found'); END IF; ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,ev_name,tmp_ior,tmp_version,tmp_host,CONCAT(tmp_exp),CONCAT(tmp_pid)); END IF; END | ######################################################### # # # IMPORT DEVICE PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.import_device (IN dev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA imp_proc: BEGIN DECLARE tmp_ior TEXT; DECLARE tmp_version VARCHAR(8); DECLARE tmp_host,tmp_server,tmp_class VARCHAR(255); DECLARE tmp_exp, tmp_pid INT; DECLARE not_found INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SELECT exported,ior,version,pid,server,host,class INTO tmp_exp,tmp_ior,tmp_version,tmp_pid,tmp_server,tmp_host,tmp_class FROM @TANGO_DB_NAME@.device WHERE name = dev_name; SET res_str = CONCAT_WS(CHAR(0),res_str,dev_name); IF not_found = 1 THEN SET res_str = CONCAT_WS(CHAR(0),res_str,'Not Found'); LEAVE imp_proc; END IF; IF tmp_ior IS NULL THEN SET res_str = CONCAT_WS(CHAR(0),res_str,''); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_ior); END IF; IF tmp_version IS NULL THEN SET res_str = CONCAT_WS(CHAR(0),res_str,''); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_version); END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_server,tmp_host,CONCAT(tmp_exp)); IF tmp_pid IS NULL THEN SET res_str = CONCAT_WS(CHAR(0),res_str,''); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,CONCAT(tmp_pid)); END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_class); END imp_proc | ######################################################### # # # GET CLASS PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.class_prop (IN class_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name VARCHAR(255); DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,prop_elt_nb INT DEFAULT 0; DECLARE class_name_pos,prop_name_pos INT; DECLARE cur_class CURSOR FOR SELECT name,count,value FROM @TANGO_DB_NAME@.property_class WHERE class = class_name ORDER BY name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,class_name); SET class_name_pos = LENGTH(res_str); OPEN cur_class; REPEAT FETCH cur_class INTO tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_class; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,class_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # GET DEVICE PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.dev_prop (IN dev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name VARCHAR(255); DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,prop_elt_nb INT DEFAULT 0; DECLARE dev_name_pos,prop_name_pos INT; DECLARE cur_dev CURSOR FOR SELECT name,count,value FROM @TANGO_DB_NAME@.property_device WHERE device = dev_name ORDER BY name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,dev_name); SET dev_name_pos = LENGTH(res_str); OPEN cur_dev; REPEAT FETCH cur_dev INTO tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_dev; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,dev_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # GET CLASS ATTRIBUTE PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.class_att_prop (IN class_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name,tmp_attribute VARCHAR(255); DECLARE known_att VARCHAR(255) DEFAULT ''; DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,att_nb,prop_elt_nb INT DEFAULT 0; DECLARE class_name_pos,att_name_pos,prop_name_pos INT; DECLARE cur_class_att_prop CURSOR FOR SELECT attribute,name,count,value FROM @TANGO_DB_NAME@.property_attribute_class WHERE class = class_name ORDER BY attribute,name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,class_name); SET class_name_pos = LENGTH(res_str); OPEN cur_class_att_prop; REPEAT FETCH cur_class_att_prop INTO tmp_attribute,tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_attribute != known_att THEN IF prop_nb != 0 THEN SET res_str = INSERT(res_str,att_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; END IF; SET known_att = tmp_attribute; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_attribute); SET att_name_pos = LENGTH(res_str); SET att_nb = att_nb + 1; SET prop_nb = 0; END IF; IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); IF prop_nb = 0 THEN IF prop_elt_nb < 10 THEN SET att_name_pos = att_name_pos + 2; ELSEIF prop_elt_nb < 100 THEN SET att_name_pos = att_name_pos + 3; ELSE SET att_name_pos = att_name_pos + 4; END IF; END IF; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_class_att_prop; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,att_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; END IF; IF att_nb != 0 THEN SET res_str = INSERT(res_str,class_name_pos+1,1,CONCAT_WS(CONCAT(att_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # GET DEVICE ATTRIBUTE PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.dev_att_prop (IN dev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name,tmp_attribute VARCHAR(255); DECLARE known_att VARCHAR(255) DEFAULT ''; DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,att_nb,prop_elt_nb INT DEFAULT 0; DECLARE dev_name_pos,att_name_pos,prop_name_pos INT; DECLARE cur_dev_att_prop CURSOR FOR SELECT attribute,name,count,value FROM @TANGO_DB_NAME@.property_attribute_device WHERE device = dev_name ORDER BY attribute,name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,dev_name); SET dev_name_pos = LENGTH(res_str); OPEN cur_dev_att_prop; REPEAT FETCH cur_dev_att_prop INTO tmp_attribute,tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_attribute != known_att THEN IF prop_nb != 0 THEN SET res_str = INSERT(res_str,att_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; END IF; SET known_att = tmp_attribute; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_attribute); SET att_name_pos = LENGTH(res_str); SET att_nb = att_nb + 1; SET prop_nb = 0; END IF; IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); IF prop_nb = 0 THEN IF prop_elt_nb < 10 THEN SET att_name_pos = att_name_pos + 2; ELSEIF prop_elt_nb < 100 THEN SET att_name_pos = att_name_pos + 3; ELSE SET att_name_pos = att_name_pos + 4; END IF; END IF; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_dev_att_prop; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,att_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; END IF; IF att_nb != 0 THEN SET res_str = INSERT(res_str,dev_name_pos+1,1,CONCAT_WS(CONCAT(att_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # GET DEVICE LIST PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.get_dev_list (IN class_name VARCHAR(255), IN serv VARCHAR(255), INOUT res_str MEDIUMBLOB, OUT d_list TEXT, OUT d_num INT) READS SQL DATA BEGIN DECLARE tmp_name VARCHAR(255); DECLARE done INT DEFAULT 0; DECLARE nb_dev INT DEFAULT 0; DECLARE class_name_pos INT; DECLARE cur_dev_list CURSOR FOR SELECT DISTINCT name FROM @TANGO_DB_NAME@.device WHERE class = class_name AND server = serv ORDER BY name; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,class_name); SET class_name_pos = LENGTH(res_str); OPEN cur_dev_list; REPEAT FETCH cur_dev_list INTO tmp_name; IF NOT done THEN SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); IF nb_dev = 0 THEN SET d_list = CONCAT_WS("",d_list,tmp_name); ELSE SET d_list = CONCAT_WS(CHAR(0),d_list,tmp_name); END IF; SET nb_dev = nb_dev + 1; END IF; UNTIL done END REPEAT; CLOSE cur_dev_list; SET res_str = INSERT(res_str,class_name_pos+1,1,CONCAT_WS(CONCAT(nb_dev),CHAR(0),CHAR(0))); SET d_num = nb_dev; END | ######################################################### # # # GET CLASS PIPE PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.class_pipe_prop (IN class_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name,tmp_pipe VARCHAR(255); DECLARE known_pipe VARCHAR(255) DEFAULT ''; DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,pipe_nb,prop_elt_nb INT DEFAULT 0; DECLARE class_name_pos,pipe_name_pos,prop_name_pos INT; DECLARE cur_class_pipe_prop CURSOR FOR SELECT pipe,name,count,value FROM @TANGO_DB_NAME@.property_pipe_class WHERE class = class_name ORDER BY pipe,name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,class_name); SET class_name_pos = LENGTH(res_str); OPEN cur_class_pipe_prop; REPEAT FETCH cur_class_pipe_prop INTO tmp_pipe,tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_pipe != known_pipe THEN IF prop_nb != 0 THEN SET res_str = INSERT(res_str,pipe_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; END IF; SET known_pipe = tmp_pipe; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_pipe); SET pipe_name_pos = LENGTH(res_str); SET pipe_nb = pipe_nb + 1; SET prop_nb = 0; END IF; IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); IF prop_nb = 0 THEN IF prop_elt_nb < 10 THEN SET pipe_name_pos = pipe_name_pos + 2; ELSEIF prop_elt_nb < 100 THEN SET pipe_name_pos = pipe_name_pos + 3; ELSE SET pipe_name_pos = pipe_name_pos + 4; END IF; END IF; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_class_pipe_prop; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,pipe_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; END IF; IF pipe_nb != 0 THEN SET res_str = INSERT(res_str,class_name_pos+1,1,CONCAT_WS(CONCAT(pipe_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # GET DEVICE PIPE PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.dev_pipe_prop (IN dev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name,tmp_pipe VARCHAR(255); DECLARE known_pipe VARCHAR(255) DEFAULT ''; DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,pipe_nb,prop_elt_nb INT DEFAULT 0; DECLARE dev_name_pos,pipe_name_pos,prop_name_pos INT; DECLARE cur_dev_pipe_prop CURSOR FOR SELECT pipe,name,count,value FROM @TANGO_DB_NAME@.property_pipe_device WHERE device = dev_name ORDER BY pipe,name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,dev_name); SET dev_name_pos = LENGTH(res_str); OPEN cur_dev_pipe_prop; REPEAT FETCH cur_dev_pipe_prop INTO tmp_pipe,tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_pipe != known_pipe THEN IF prop_nb != 0 THEN SET res_str = INSERT(res_str,pipe_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; END IF; SET known_pipe = tmp_pipe; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_pipe); SET pipe_name_pos = LENGTH(res_str); SET pipe_nb = pipe_nb + 1; SET prop_nb = 0; END IF; IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); IF prop_nb = 0 THEN IF prop_elt_nb < 10 THEN SET pipe_name_pos = pipe_name_pos + 2; ELSEIF prop_elt_nb < 100 THEN SET pipe_name_pos = pipe_name_pos + 3; ELSE SET pipe_name_pos = pipe_name_pos + 4; END IF; END IF; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_dev_pipe_prop; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,pipe_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); IF prop_nb < 10 THEN SET prop_name_pos = prop_name_pos + 2; ELSEIF prop_nb < 100 THEN SET prop_name_pos = prop_name_pos + 3; ELSE SET prop_name_pos = prop_name_pos + 4; END IF; IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; END IF; IF pipe_nb != 0 THEN SET res_str = INSERT(res_str,dev_name_pos+1,1,CONCAT_WS(CONCAT(pipe_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ######################################################### # # # STORED PROCEDURE RELEASE PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.proc_release_nb (INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_rel VARCHAR(255); DECLARE not_found INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SELECT ROUTINE_COMMENT INTO tmp_rel FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'ds_start' AND ROUTINE_SCHEMA = '@TANGO_DB_NAME@'; IF not_found = 1 THEN SET res_str = CONCAT_WS(CHAR(0),res_str,'Not Found'); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_rel); END IF; END | ######################################################### # # # GET OBJECT PROPERTIES PROCEDURE # # # ######################################################### CREATE PROCEDURE @TANGO_DB_NAME@.obj_prop (IN obj_name VARCHAR(255),OUT serv_dev_name VARCHAR(255), INOUT res_str MEDIUMBLOB) READS SQL DATA BEGIN DECLARE tmp_name VARCHAR(255); DECLARE tmp_value TEXT; DECLARE tmp_count INT; DECLARE done,prop_nb,prop_elt_nb INT DEFAULT 0; DECLARE dev_name_pos,prop_name_pos INT; DECLARE serv_defined INT DEFAULT 0; DECLARE cur_dev CURSOR FOR SELECT name,count,value FROM @TANGO_DB_NAME@.property WHERE object = obj_name ORDER BY name,count; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET res_str = CONCAT_WS(CHAR(0),res_str,'MySQL Error'); SET res_str = CONCAT_WS(CHAR(0),res_str,obj_name); SET dev_name_pos = LENGTH(res_str); OPEN cur_dev; REPEAT FETCH cur_dev INTO tmp_name,tmp_count,tmp_value; IF NOT done THEN IF tmp_count = 1 THEN IF prop_elt_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_name); SET prop_name_pos = LENGTH(res_str); SET prop_nb = prop_nb + 1; SET prop_elt_nb = 0; IF tmp_name = 'Services' THEN SET serv_defined = 1; ELSE SET serv_defined = 0; END IF; END IF; IF serv_defined = 1 THEN IF LOCATE('AccessControl/tango:',tmp_value) != 0 THEN SET serv_dev_name = SUBSTRING(tmp_value,21); IF LOCATE('tango://',serv_dev_name) != 0 THEN SET serv_dev_name = SUBSTRING_INDEX(serv_dev_name,'/',-3); END IF; END IF; END IF; SET res_str = CONCAT_WS(CHAR(0),res_str,tmp_value); SET prop_elt_nb = prop_elt_nb + 1; END IF; UNTIL done END REPEAT; CLOSE cur_dev; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,prop_name_pos+1,1,CONCAT_WS(CONCAT(prop_elt_nb),CHAR(0),CHAR(0))); END IF; IF prop_nb != 0 THEN SET res_str = INSERT(res_str,dev_name_pos+1,1,CONCAT_WS(CONCAT(prop_nb),CHAR(0),CHAR(0))); ELSE SET res_str = CONCAT_WS(CHAR(0),res_str,0); END IF; END | ############################################################### # # # INIT HISTORY ID IN HISTORY TABLES IF NOT ALREADY DONE # # # ############################################################### CREATE PROCEDURE @TANGO_DB_NAME@.init_history_ids() BEGIN DECLARE ret_id INT DEFAULT -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.object_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.object_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.class_attribute_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.class_attribute_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.class_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.class_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.class_pipe_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.class_pipe_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.device_attribute_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.device_attribute_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.device_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.device_history_id VALUES (0); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.device_pipe_history_id; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.device_pipe_history_id VALUES (0); END IF; END | ############################################################### # # # INIT TAC RELATED TABLES IF NOT ALREADY DONE # # # ############################################################### CREATE PROCEDURE @TANGO_DB_NAME@.init_tac_tables() BEGIN DECLARE ret_id INT DEFAULT -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.access_address WHERE user='*' and address='*.*.*.*'; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.access_address VALUES ('*','*.*.*.*','FF.FF.FF.FF',20060824131221,20060824131221); END IF; SET ret_id = -1; SELECT COUNT(*) INTO ret_id FROM @TANGO_DB_NAME@.access_device WHERE user='*' and device='*/*/*'; IF ret_id = 0 THEN INSERT INTO @TANGO_DB_NAME@.access_device VALUES ('*','*/*/*','write',20060824131221,20060824131221); END IF; END | DELIMITER ; tango-9.2.5a/cppserver/database/update_db.sh.in0000755023471100065110000000101713034745007016400 00000000000000mysql=@MYSQL@ mysql_admin=@MYSQL_ADMIN@ mysql_admin_passwd=@MYSQL_ADMIN_PASSWD@ mysql_host=@MYSQL_HOST@ db_name=@TANGO_DB_NAME@ srcdir=@srcdir@ if test "x$mysql_admin" = "x"; then user_switch=""; else user_switch="-u$x$mysql_admin"; fi if test "x$mysql_admin_passwd" = "x"; then passwd_switch=""; else passwd_switch="-p$mysql_admin_passwd" fi if test "x$mysql_host" = "x"; then host_switch=""; else host_switch="-h$mysql_host"; fi $mysql $user_switch $passwd_switch $host_switch < ./update_db.sql > /dev/null tango-9.2.5a/cppserver/database/update_db.sql.in0000644023471100065110000000012413034745006016557 00000000000000USE @TANGO_DB_NAME@; # # Load the new stored procedures # source stored_proc.sql tango-9.2.5a/cppserver/database/update_db7.sql.in0000644023471100065110000001174113034745006016655 00000000000000USE @TANGO_DB_NAME@; # # Table structure for table 'property_pipe_class' # CREATE TABLE IF NOT EXISTS property_pipe_class ( class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL, comment text, KEY index_property_pipe_class (class(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_pipe_device' # CREATE TABLE IF NOT EXISTS property_pipe_device ( device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL, comment text, KEY index_property_pipe_device (device(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # For history ID # CREATE TABLE IF NOT EXISTS device_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS class_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; # # History tables # CREATE TABLE IF NOT EXISTS property_pipe_class_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_class (class), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_pipe_device_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_device (device), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; # # Load the new stored procedures # source stored_proc.sql # # Init new history ID # CALL init_history_ids(); # # Update history id columns to support id on more than 32 bits # ALTER TABLE property_attribute_device_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_attribute_class_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_class_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_device_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE class_attribute_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE class_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE device_attribute_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE device_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE object_history_id MODIFY id bigint unsigned NOT NULL default '0'; # # Create entries in the property_class tables for controlled access service # DELETE FROM property_class WHERE class='Database' AND count >= 32; INSERT INTO property_class VALUES('Database','AllowedAccessCmd',32,'DbImportEvent',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',33,'DbGetDeviceAlias',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',34,'DbGetCSDbServerList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',35,'DbGetDeviceClassList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',36,'DbGetDeviceExportedList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',37,'DbGetHostServerList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',38,'DbGetAttributeAlias2',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',39,'DbGetAliasAttribute',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',40,'DbGetClassPipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',41,'DbGetDevicePipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',42,'DbGetClassPipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',43,'DbGetDevicePipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',44,'DbGetAttributeAliasList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',45,'DbGetForwardedAttributeListForDevice',NOW(),NOW(),NULL); DELETE FROM property_class WHERE class='DServer' AND count >= 10; INSERT INTO property_class VALUES('DServer','AllowedAccessCmd',10,'ZMQEventSubscriptionChange',NOW(),NOW(),NULL); DELETE FROM property_class WHERE class='Starter' AND count >= 5; INSERT INTO property_class VALUES('Starter','AllowedAccessCmd',5,'UpdateServerList',NOW(),NOW(),NULL); tango-9.2.5a/cppserver/database/update_db8.sql.in0000644023471100065110000001072013034745006016652 00000000000000USE @TANGO_DB_NAME@; # # Table structure for table 'property_pipe_class' # CREATE TABLE IF NOT EXISTS property_pipe_class ( class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL, comment text, KEY index_property_pipe_class (class(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # Table structure for table 'property_pipe_device' # CREATE TABLE IF NOT EXISTS property_pipe_device ( device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text default NULL, updated timestamp NOT NULL, accessed timestamp NOT NULL, comment text, KEY index_property_pipe_device (device(64),pipe(64),name(64),count) ) ENGINE=MyISAM; # # For history ID # CREATE TABLE IF NOT EXISTS device_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS class_pipe_history_id ( id bigint unsigned NOT NULL default '0' ) ENGINE=MyISAM; # # History tables # CREATE TABLE IF NOT EXISTS property_pipe_class_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, class varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_class (class), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; CREATE TABLE IF NOT EXISTS property_pipe_device_hist ( id bigint unsigned NOT NULL default '0', date timestamp NOT NULL, device varchar(255) NOT NULL default '', pipe varchar(255) NOT NULL default '', name varchar(255) NOT NULL default '', count int(11) NOT NULL default '0', value text, KEY index_id (id), KEY index_device (device), KEY index_pipe (pipe), KEY index_name (name) ) ENGINE=MyISAM; # # Load the new stored procedures # source stored_proc.sql # # Init new history ID # CALL init_history_ids(); # # Update history id columns to support id on more than 32 bits # ALTER TABLE property_attribute_device_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_attribute_class_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_class_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_device_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE property_hist MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE class_attribute_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE class_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE device_attribute_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE device_history_id MODIFY id bigint unsigned NOT NULL default '0'; ALTER TABLE object_history_id MODIFY id bigint unsigned NOT NULL default '0'; # # Update entries in the property_class tables for database # DELETE FROM property_class WHERE class='Database' AND count >= 35; INSERT INTO property_class VALUES('Database','AllowedAccessCmd',35,'DbGetDeviceClassList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',36,'DbGetDeviceExportedList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',37,'DbGetHostServerList',NOW(),NoW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',38,'DbGetAttributeAlias2',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',39,'DbGetAliasAttribute',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',40,'DbGetClassPipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',41,'DbGetDevicePipeProperty',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',42,'DbGetClassPipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',43,'DbGetDevicePipeList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',44,'DbGetAttributeAliasList',NOW(),NOW(),NULL); INSERT INTO property_class VALUES('Database','AllowedAccessCmd',45,'DbGetForwardedAttributeListForDevice',NOW(),NOW(),NULL); # # Remove history entries for the property used by memorized attribute # DELETE FROM property_attribute_device_hist WHERE count=1 AND name='__value'; tango-9.2.5a/cppserver/database/ClassFactory.cpp0000644023471100065110000001026513034745007016613 00000000000000/*----- PROTECTED REGION ID(DataBase::ClassFactory.cpp) ENABLED START -----*/ static const char *RcsId = "$Header$"; //+============================================================================= // // file : ClassFactory.cpp // // description : C++ source for the class_factory method of the DServer // device class. This method is responsible to create // all class singletin for a device server. It is called // at device server startup // // project : TANGO Device Server // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 22233 $ // // $Log$ // Revision 2.20 2010/09/21 11:43:20 taurel // - Add GPL stuff // // Revision 2.19 2007/11/06 07:24:05 taurel // - Added the DbGetDataForServerCache command (with timing stats) // - Add timing stats for the DbPutClassProperty command // // Revision 2.18 2006/07/31 12:19:49 jlpons // Correction // // Revision 2.17 2006/06/22 15:25:32 jlpons // Added history commands // // Revision 2.16 2005/07/21 20:12:23 andy_gotz // added attributes to return timing information for the DbImportDevice command // // Revision 2.15 2003/01/16 14:30:40 goetz // ported Makefile to omniorb // // Revision 2.14 2002/11/26 10:00:58 goetz // added delete_class_attribute_property; changed Solaris to CC; added pid to import_device // // Revision 2.13 2002/09/16 08:39:36 goetz // added GetObjectList and GetPropertyList commands // // Revision 2.12 2002/02/04 17:09:08 goetz // updated Windows port // // Revision 2.10 2001/07/12 12:15:18 goetz // changed db_get_class_list() and db_delete_device_attribute_property() // // Revision 2.9 2001/07/04 05:17:03 goetz // dserver device domain,family,member corrected; wildcards for DbGetClassList // // Revision 2.8 2001/07/04 04:42:24 goetz // delete all properties before updating them // // Revision 2.7 2001/06/11 15:38:13 goetz // added check on no. of arguments in GetDeviceProperty // // Revision 2.6 2001/03/22 12:56:52 goetz // fixed bug in DbAddDevice command, device name now unique in device table // // Revision 2.5 2001/03/06 12:05:43 goetz // added DbGetDeviceExportedList; DbExportDevice updates host info in server table // // Revision 2.4 2001/03/06 11:01:55 goetz // added DbGetDeviceExportedList command; DbExportDevice updates host in server table // // Revision 2.3 2001/03/05 12:10:52 goetz // checking in before going to add new command(s) // // Revision 2.2 2001/01/03 11:58:28 goetz // E.Taurel modified version for new TACO exception class // // Revision 2.1 2000/11/02 14:35:21 goetz // added commands for server info // // Revision 2.0 2000/10/19 07:31:07 goetz // changed major version number to 2 // // Revision 1.16 2000/10/19 07:30:27 goetz // ported Database to TANGO V2.0 // //-============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /** * Create DataBaseClass singleton and store it in DServer object. * * @author $Author: pascal_verdier $ * @version $Revision: 22233 $ */ void Tango::DServer::class_factory() { add_class(DataBase_ns::DataBaseClass::init("DataBase")); } /*----- PROTECTED REGION END -----*/ // DataBase::ClassFactory.cpp tango-9.2.5a/cppserver/database/DataBaseClass.cpp0000644023471100065110000040632413034745007016655 00000000000000/*----- PROTECTED REGION ID(DataBaseClass.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: DataBaseClass.cpp 28924 2015-12-15 15:29:26Z pascal_verdier $"; static const char *TagName = "$Name: Database-Release-4.17 $"; static const char *CvsPath = "$Source: $"; static const char *SvnPath = "$HeadURL: https://svn.code.sf.net/p/tango-cs/code/classes/cpp/dbase/tags/DataBase-Release-5.6/DataBaseClass.cpp $"; static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; //============================================================================= // // file : DataBaseClass.cpp // // description : C++ source for the DataBaseClass. A singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the �name� once per process. // // project : TANGO. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28924 $ // $Date: 2015-12-15 16:29:26 +0100 (Tue, 15 Dec 2015) $ // // $HeadURL: https://svn.code.sf.net/p/tango-cs/code/classes/cpp/dbase/tags/DataBase-Release-5.6/DataBaseClass.cpp $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include /*----- PROTECTED REGION END -----*/ // DataBaseClass.cpp //------------------------------------------------------------------- /** * Create DataBaseClass singleton and * return it in a C function for Python usage */ //------------------------------------------------------------------- extern "C" { #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif Tango::DeviceClass *_create_DataBase_class(const char *name) { return DataBase_ns::DataBaseClass::init(name); } } namespace DataBase_ns { //=================================================================== // Initialize pointer for singleton pattern //=================================================================== DataBaseClass *DataBaseClass::_instance = NULL; //-------------------------------------------------------- /** * method : DataBaseClass::DataBaseClass(string &s) * description : constructor for the DataBaseClass * * @param s The class name */ //-------------------------------------------------------- DataBaseClass::DataBaseClass(string &s):Tango::DeviceClass(s) { cout2 << "Entering DataBaseClass constructor" << endl; set_default_property(); write_class_property(); /*----- PROTECTED REGION ID(DataBaseClass::constructor) ENABLED START -----*/ string str_rcs(RcsId); /*----- PROTECTED REGION END -----*/ // DataBaseClass::constructor cout2 << "Leaving DataBaseClass constructor" << endl; } //-------------------------------------------------------- /** * method : DataBaseClass::~DataBaseClass() * description : destructor for the DataBaseClass */ //-------------------------------------------------------- DataBaseClass::~DataBaseClass() { /*----- PROTECTED REGION ID(DataBaseClass::destructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::destructor _instance = NULL; } //-------------------------------------------------------- /** * method : DataBaseClass::init * description : Create the object if not already done. * Otherwise, just return a pointer to the object * * @param name The class name */ //-------------------------------------------------------- DataBaseClass *DataBaseClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new DataBaseClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //-------------------------------------------------------- /** * method : DataBaseClass::instance * description : Check if object already created, * and return a pointer to the object */ //-------------------------------------------------------- DataBaseClass *DataBaseClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //=================================================================== // Command execution method calls //=================================================================== //-------------------------------------------------------- /** * method : DbAddDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbAddDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbAddDeviceClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_add_device(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbAddServerClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbAddServerClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbAddServerClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_add_server(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteAttributeAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteAttributeAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteAttributeAliasClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_delete_attribute_alias(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteClassAttributeClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteClassAttributeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteClassAttributeClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_class_attribute(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteClassAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteClassAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteClassAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_class_attribute_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteClassPropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteClassPropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteClassPropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_class_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_delete_device(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDeviceAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDeviceAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDeviceAliasClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_alias(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDeviceAttributeClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDeviceAttributeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDeviceAttributeClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_attribute(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDeviceAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDeviceAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDeviceAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_attribute_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDevicePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDevicePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDevicePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeletePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeletePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeletePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteServerClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteServerClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteServerClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_delete_server(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteServerInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteServerInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteServerInfoClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_delete_server_info(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbExportDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbExportDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbExportDeviceClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_export_device(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbExportEventClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbExportEventClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbExportEventClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_export_event(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbGetAliasDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetAliasDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetAliasDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_alias_device(argin)); } //-------------------------------------------------------- /** * method : DbGetAttributeAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetAttributeAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetAttributeAliasClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_attribute_alias(argin)); } //-------------------------------------------------------- /** * method : DbGetAttributeAliasListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetAttributeAliasListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetAttributeAliasListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_attribute_alias_list(argin)); } //-------------------------------------------------------- /** * method : DbGetClassAttributeListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassAttributeListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassAttributeListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_attribute_list(argin)); } //-------------------------------------------------------- /** * method : DbGetClassAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_attribute_property(argin)); } //-------------------------------------------------------- /** * method : DbGetClassAttributeProperty2Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassAttributeProperty2Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassAttributeProperty2Class::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_attribute_property2(argin)); } //-------------------------------------------------------- /** * method : DbGetClassAttributePropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassAttributePropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassAttributePropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_attribute_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetClassForDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassForDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassForDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_for_device(argin)); } //-------------------------------------------------------- /** * method : DbGetClassInheritanceForDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassInheritanceForDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassInheritanceForDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_inheritance_for_device(argin)); } //-------------------------------------------------------- /** * method : DbGetClassListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_list(argin)); } //-------------------------------------------------------- /** * method : DbGetClassPropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_property(argin)); } //-------------------------------------------------------- /** * method : DbGetClassPropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetClassPropertyListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPropertyListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPropertyListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_property_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAliasClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_alias(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAliasListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAliasListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAliasListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_alias_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAttributeListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAttributeListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAttributeListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_attribute_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_attribute_property(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAttributeProperty2Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAttributeProperty2Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAttributeProperty2Class::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_attribute_property2(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceAttributePropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceAttributePropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceAttributePropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_attribute_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceClassListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceClassListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceClassListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_class_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceDomainListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceDomainListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceDomainListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_domain_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceExportedListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceExportedListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceExportedListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_exported_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceFamilyListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceFamilyListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceFamilyListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_family_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceInfoClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_info(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceWideListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceWideListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceWideListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_wide_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceMemberListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceMemberListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceMemberListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_member_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_property(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePropertyListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePropertyListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePropertyListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_property_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDeviceServerClassListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDeviceServerClassListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDeviceServerClassListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_server_class_list(argin)); } //-------------------------------------------------------- /** * method : DbGetExportdDeviceListForClassClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetExportdDeviceListForClassClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetExportdDeviceListForClassClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_exportd_device_list_for_class(argin)); } //-------------------------------------------------------- /** * method : DbGetHostListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetHostListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetHostListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_host_list(argin)); } //-------------------------------------------------------- /** * method : DbGetHostServerListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetHostServerListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetHostServerListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_host_server_list(argin)); } //-------------------------------------------------------- /** * method : DbGetHostServersInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetHostServersInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetHostServersInfoClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_host_servers_info(argin)); } //-------------------------------------------------------- /** * method : DbGetInstanceNameListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetInstanceNameListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetInstanceNameListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_instance_name_list(argin)); } //-------------------------------------------------------- /** * method : DbGetObjectListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetObjectListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetObjectListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_object_list(argin)); } //-------------------------------------------------------- /** * method : DbGetPropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetPropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetPropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_property(argin)); } //-------------------------------------------------------- /** * method : DbGetPropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetPropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetPropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetPropertyListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetPropertyListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetPropertyListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_property_list(argin)); } //-------------------------------------------------------- /** * method : DbGetServerInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetServerInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetServerInfoClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_server_info(argin)); } //-------------------------------------------------------- /** * method : DbGetServerListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetServerListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetServerListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_server_list(argin)); } //-------------------------------------------------------- /** * method : DbGetServerNameListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetServerNameListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetServerNameListClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_server_name_list(argin)); } //-------------------------------------------------------- /** * method : DbImportDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbImportDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbImportDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_import_device(argin)); } //-------------------------------------------------------- /** * method : DbImportEventClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbImportEventClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbImportEventClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_import_event(argin)); } //-------------------------------------------------------- /** * method : DbInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbInfoClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "DbInfoClass::execute(): arrived" << endl; return insert((static_cast(device))->db_info()); } //-------------------------------------------------------- /** * method : DbPutAttributeAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutAttributeAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutAttributeAliasClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_attribute_alias(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutClassAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutClassAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutClassAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_class_attribute_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutClassAttributeProperty2Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutClassAttributeProperty2Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutClassAttributeProperty2Class::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_class_attribute_property2(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutClassPropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutClassPropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutClassPropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_class_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutDeviceAliasClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutDeviceAliasClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutDeviceAliasClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_device_alias(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutDeviceAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutDeviceAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutDeviceAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_device_attribute_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutDeviceAttributeProperty2Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutDeviceAttributeProperty2Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutDeviceAttributeProperty2Class::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_device_attribute_property2(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutDevicePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutDevicePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutDevicePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_device_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutPropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutPropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutPropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutServerInfoClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutServerInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutServerInfoClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_server_info(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbUnExportDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbUnExportDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbUnExportDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_un_export_device(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbUnExportEventClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbUnExportEventClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbUnExportEventClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_un_export_event(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbUnExportServerClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbUnExportServerClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbUnExportServerClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->db_un_export_server(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : ResetTimingValuesClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *ResetTimingValuesClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "ResetTimingValuesClass::execute(): arrived" << endl; ((static_cast(device))->reset_timing_values()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbGetDataForServerCacheClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDataForServerCacheClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDataForServerCacheClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_data_for_server_cache(argin)); } //-------------------------------------------------------- /** * method : DbDeleteAllDeviceAttributePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteAllDeviceAttributePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteAllDeviceAttributePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_all_device_attribute_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbMySqlSelectClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbMySqlSelectClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbMySqlSelectClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_my_sql_select(argin)); } //-------------------------------------------------------- /** * method : DbGetCSDbServerListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetCSDbServerListClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "DbGetCSDbServerListClass::execute(): arrived" << endl; return insert((static_cast(device))->db_get_csdb_server_list()); } //-------------------------------------------------------- /** * method : DbGetAttributeAlias2Class::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetAttributeAlias2Class::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetAttributeAlias2Class::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_attribute_alias2(argin)); } //-------------------------------------------------------- /** * method : DbGetAliasAttributeClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetAliasAttributeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetAliasAttributeClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_alias_attribute(argin)); } //-------------------------------------------------------- /** * method : DbRenameServerClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbRenameServerClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbRenameServerClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_rename_server(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbGetClassPipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_pipe_property(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_pipe_property(argin)); } //-------------------------------------------------------- /** * method : DbDeleteClassPipeClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteClassPipeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteClassPipeClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_class_pipe(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDevicePipeClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDevicePipeClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDevicePipeClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_pipe(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteClassPipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteClassPipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteClassPipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_class_pipe_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbDeleteDevicePipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteDevicePipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteDevicePipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_device_pipe_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbGetClassPipeListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPipeListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPipeListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_pipe_list(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePipeListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePipeListClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePipeListClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_pipe_list(argin)); } //-------------------------------------------------------- /** * method : DbDeleteAllDevicePipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbDeleteAllDevicePipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbDeleteAllDevicePipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_delete_all_device_pipe_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutClassPipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutClassPipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutClassPipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_class_pipe_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbPutDevicePipePropertyClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbPutDevicePipePropertyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbPutDevicePipePropertyClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->db_put_device_pipe_property(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : DbGetClassPipePropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetClassPipePropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetClassPipePropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_class_pipe_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetDevicePipePropertyHistClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetDevicePipePropertyHistClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetDevicePipePropertyHistClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->db_get_device_pipe_property_hist(argin)); } //-------------------------------------------------------- /** * method : DbGetForwardedAttributeListForDeviceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *DbGetForwardedAttributeListForDeviceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "DbGetForwardedAttributeListForDeviceClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->db_get_forwarded_attribute_list_for_device(argin)); } //=================================================================== // Properties management //=================================================================== //-------------------------------------------------------- /** * Method : DataBaseClass::get_class_property() * Description : Get the class property for specified name. */ //-------------------------------------------------------- Tango::DbDatum DataBaseClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; i vect_data; // Set Default Class Properties // Set Default device Properties } //-------------------------------------------------------- /** * Method : DataBaseClass::write_class_property() * Description : Set class description fields as property in database */ //-------------------------------------------------------- void DataBaseClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("TANGO"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector str_desc; str_desc.push_back("This class manage the TANGO database."); description << str_desc; data.push_back(description); // put cvs or svn location string filename("DataBase"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector inheritance; inheritance.push_back("TANGO_BASE_CLASS"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); } //=================================================================== // Factory methods //=================================================================== //-------------------------------------------------------- /** * Method : DataBaseClass::device_factory() * Description : Create the device object(s) * and store them in the device list */ //-------------------------------------------------------- void DataBaseClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { device_list.push_back(new DataBase(this, DataBase::db_name.c_str(), "TANGO database device server")); export_device(device_list[0],"database"); } //-------------------------------------------------------- /** * Method : DataBaseClass::attribute_factory() * Description : Create the attribute object(s) * and store them in the attribute list */ //-------------------------------------------------------- void DataBaseClass::attribute_factory(vector &att_list) { /*----- PROTECTED REGION ID(DataBaseClass::attribute_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // DataBaseClass::attribute_factory_before // Attribute : StoredProcedureRelease StoredProcedureReleaseAttrib *storedprocedurerelease = new StoredProcedureReleaseAttrib(); Tango::UserDefaultAttrProp storedprocedurerelease_prop; // description not set for StoredProcedureRelease // label not set for StoredProcedureRelease // unit not set for StoredProcedureRelease // standard_unit not set for StoredProcedureRelease // display_unit not set for StoredProcedureRelease // format not set for StoredProcedureRelease // max_value not set for StoredProcedureRelease // min_value not set for StoredProcedureRelease // max_alarm not set for StoredProcedureRelease // min_alarm not set for StoredProcedureRelease // max_warning not set for StoredProcedureRelease // min_warning not set for StoredProcedureRelease // delta_t not set for StoredProcedureRelease // delta_val not set for StoredProcedureRelease storedprocedurerelease->set_default_properties(storedprocedurerelease_prop); // Not Polled storedprocedurerelease->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(storedprocedurerelease); // Attribute : Timing_average Timing_averageAttrib *timing_average = new Timing_averageAttrib(); Tango::UserDefaultAttrProp timing_average_prop; // description not set for Timing_average // label not set for Timing_average // unit not set for Timing_average // standard_unit not set for Timing_average // display_unit not set for Timing_average // format not set for Timing_average // max_value not set for Timing_average // min_value not set for Timing_average // max_alarm not set for Timing_average // min_alarm not set for Timing_average // max_warning not set for Timing_average // min_warning not set for Timing_average // delta_t not set for Timing_average // delta_val not set for Timing_average timing_average->set_default_properties(timing_average_prop); // Not Polled timing_average->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_average); // Attribute : Timing_minimum Timing_minimumAttrib *timing_minimum = new Timing_minimumAttrib(); Tango::UserDefaultAttrProp timing_minimum_prop; // description not set for Timing_minimum // label not set for Timing_minimum // unit not set for Timing_minimum // standard_unit not set for Timing_minimum // display_unit not set for Timing_minimum // format not set for Timing_minimum // max_value not set for Timing_minimum // min_value not set for Timing_minimum // max_alarm not set for Timing_minimum // min_alarm not set for Timing_minimum // max_warning not set for Timing_minimum // min_warning not set for Timing_minimum // delta_t not set for Timing_minimum // delta_val not set for Timing_minimum timing_minimum->set_default_properties(timing_minimum_prop); // Not Polled timing_minimum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_minimum); // Attribute : Timing_maximum Timing_maximumAttrib *timing_maximum = new Timing_maximumAttrib(); Tango::UserDefaultAttrProp timing_maximum_prop; // description not set for Timing_maximum // label not set for Timing_maximum // unit not set for Timing_maximum // standard_unit not set for Timing_maximum // display_unit not set for Timing_maximum // format not set for Timing_maximum // max_value not set for Timing_maximum // min_value not set for Timing_maximum // max_alarm not set for Timing_maximum // min_alarm not set for Timing_maximum // max_warning not set for Timing_maximum // min_warning not set for Timing_maximum // delta_t not set for Timing_maximum // delta_val not set for Timing_maximum timing_maximum->set_default_properties(timing_maximum_prop); // Not Polled timing_maximum->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_maximum); // Attribute : Timing_calls Timing_callsAttrib *timing_calls = new Timing_callsAttrib(); Tango::UserDefaultAttrProp timing_calls_prop; // description not set for Timing_calls // label not set for Timing_calls // unit not set for Timing_calls // standard_unit not set for Timing_calls // display_unit not set for Timing_calls // format not set for Timing_calls // max_value not set for Timing_calls // min_value not set for Timing_calls // max_alarm not set for Timing_calls // min_alarm not set for Timing_calls // max_warning not set for Timing_calls // min_warning not set for Timing_calls // delta_t not set for Timing_calls // delta_val not set for Timing_calls timing_calls->set_default_properties(timing_calls_prop); // Not Polled timing_calls->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_calls); // Attribute : Timing_index Timing_indexAttrib *timing_index = new Timing_indexAttrib(); Tango::UserDefaultAttrProp timing_index_prop; // description not set for Timing_index // label not set for Timing_index // unit not set for Timing_index // standard_unit not set for Timing_index // display_unit not set for Timing_index // format not set for Timing_index // max_value not set for Timing_index // min_value not set for Timing_index // max_alarm not set for Timing_index // min_alarm not set for Timing_index // max_warning not set for Timing_index // min_warning not set for Timing_index // delta_t not set for Timing_index // delta_val not set for Timing_index timing_index->set_default_properties(timing_index_prop); // Not Polled timing_index->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_index); // Attribute : Timing_info Timing_infoAttrib *timing_info = new Timing_infoAttrib(); Tango::UserDefaultAttrProp timing_info_prop; // description not set for Timing_info // label not set for Timing_info // unit not set for Timing_info // standard_unit not set for Timing_info // display_unit not set for Timing_info // format not set for Timing_info // max_value not set for Timing_info // min_value not set for Timing_info // max_alarm not set for Timing_info // min_alarm not set for Timing_info // max_warning not set for Timing_info // min_warning not set for Timing_info // delta_t not set for Timing_info // delta_val not set for Timing_info timing_info->set_default_properties(timing_info_prop); // Not Polled timing_info->set_disp_level(Tango::OPERATOR); // Not Memorized att_list.push_back(timing_info); // Create a list of static attributes create_static_attribute_list(get_class_attr()->get_attr_list()); /*----- PROTECTED REGION ID(DataBaseClass::attribute_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // DataBaseClass::attribute_factory_after } //-------------------------------------------------------- /** * Method : DataBaseClass::pipe_factory() * Description : Create the pipe object(s) * and store them in the pipe list */ //-------------------------------------------------------- void DataBaseClass::pipe_factory() { /*----- PROTECTED REGION ID(DataBaseClass::pipe_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // DataBaseClass::pipe_factory_before /*----- PROTECTED REGION ID(DataBaseClass::pipe_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // DataBaseClass::pipe_factory_after } //-------------------------------------------------------- /** * Method : DataBaseClass::command_factory() * Description : Create the command object(s) * and store them in the command list */ //-------------------------------------------------------- void DataBaseClass::command_factory() { /*----- PROTECTED REGION ID(DataBaseClass::command_factory_before) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::command_factory_before // Command DbAddDevice DbAddDeviceClass *pDbAddDeviceCmd = new DbAddDeviceClass("DbAddDevice", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Full device server process name\nStr[1] = Device name\nStr[2] = Tango class name", "", Tango::OPERATOR); command_list.push_back(pDbAddDeviceCmd); // Command DbAddServer DbAddServerClass *pDbAddServerCmd = new DbAddServerClass("DbAddServer", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Full device server name\nStr[1] = Device(s) name\nStr[2] = Tango class name\nStr[n] = Device name\nStr[n + 1] = Tango class name", "", Tango::OPERATOR); command_list.push_back(pDbAddServerCmd); // Command DbDeleteAttributeAlias DbDeleteAttributeAliasClass *pDbDeleteAttributeAliasCmd = new DbDeleteAttributeAliasClass("DbDeleteAttributeAlias", Tango::DEV_STRING, Tango::DEV_VOID, "Attriibute alias name.", "", Tango::OPERATOR); command_list.push_back(pDbDeleteAttributeAliasCmd); // Command DbDeleteClassAttribute DbDeleteClassAttributeClass *pDbDeleteClassAttributeCmd = new DbDeleteClassAttributeClass("DbDeleteClassAttribute", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Attribute name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteClassAttributeCmd); // Command DbDeleteClassAttributeProperty DbDeleteClassAttributePropertyClass *pDbDeleteClassAttributePropertyCmd = new DbDeleteClassAttributePropertyClass("DbDeleteClassAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Attribute name\nStr[2] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteClassAttributePropertyCmd); // Command DbDeleteClassProperty DbDeleteClassPropertyClass *pDbDeleteClassPropertyCmd = new DbDeleteClassPropertyClass("DbDeleteClassProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteClassPropertyCmd); // Command DbDeleteDevice DbDeleteDeviceClass *pDbDeleteDeviceCmd = new DbDeleteDeviceClass("DbDeleteDevice", Tango::DEV_STRING, Tango::DEV_VOID, "device name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDeviceCmd); // Command DbDeleteDeviceAlias DbDeleteDeviceAliasClass *pDbDeleteDeviceAliasCmd = new DbDeleteDeviceAliasClass("DbDeleteDeviceAlias", Tango::DEV_STRING, Tango::DEV_VOID, "device alias name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDeviceAliasCmd); // Command DbDeleteDeviceAttribute DbDeleteDeviceAttributeClass *pDbDeleteDeviceAttributeCmd = new DbDeleteDeviceAttributeClass("DbDeleteDeviceAttribute", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Attribute name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDeviceAttributeCmd); // Command DbDeleteDeviceAttributeProperty DbDeleteDeviceAttributePropertyClass *pDbDeleteDeviceAttributePropertyCmd = new DbDeleteDeviceAttributePropertyClass("DbDeleteDeviceAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Attribute name\nStr[2] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDeviceAttributePropertyCmd); // Command DbDeleteDeviceProperty DbDeleteDevicePropertyClass *pDbDeleteDevicePropertyCmd = new DbDeleteDevicePropertyClass("DbDeleteDeviceProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDevicePropertyCmd); // Command DbDeleteProperty DbDeletePropertyClass *pDbDeletePropertyCmd = new DbDeletePropertyClass("DbDeleteProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Object name\nStr[1] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeletePropertyCmd); // Command DbDeleteServer DbDeleteServerClass *pDbDeleteServerCmd = new DbDeleteServerClass("DbDeleteServer", Tango::DEV_STRING, Tango::DEV_VOID, "Device server name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteServerCmd); // Command DbDeleteServerInfo DbDeleteServerInfoClass *pDbDeleteServerInfoCmd = new DbDeleteServerInfoClass("DbDeleteServerInfo", Tango::DEV_STRING, Tango::DEV_VOID, "Device server name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteServerInfoCmd); // Command DbExportDevice DbExportDeviceClass *pDbExportDeviceCmd = new DbExportDeviceClass("DbExportDevice", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = CORBA IOR\nStr[2] = Device server process host name\nStr[3] = Device server process PID or string ``null``\nStr[4] = Device server process version", "", Tango::OPERATOR); command_list.push_back(pDbExportDeviceCmd); // Command DbExportEvent DbExportEventClass *pDbExportEventCmd = new DbExportEventClass("DbExportEvent", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = event channel name (or factory name)\nStr[1] = CORBA IOR\nStr[2] = Notifd host name\nStr[3] = Notifd pid\nStr[4] = Notifd version", "", Tango::OPERATOR); command_list.push_back(pDbExportEventCmd); // Command DbGetAliasDevice DbGetAliasDeviceClass *pDbGetAliasDeviceCmd = new DbGetAliasDeviceClass("DbGetAliasDevice", Tango::DEV_STRING, Tango::DEV_STRING, "Alias name", "Device name", Tango::OPERATOR); command_list.push_back(pDbGetAliasDeviceCmd); // Command DbGetAttributeAlias DbGetAttributeAliasClass *pDbGetAttributeAliasCmd = new DbGetAttributeAliasClass("DbGetAttributeAlias", Tango::DEV_STRING, Tango::DEV_STRING, "The attribute alias name", "The attribute name (device/attribute)", Tango::OPERATOR); command_list.push_back(pDbGetAttributeAliasCmd); // Command DbGetAttributeAliasList DbGetAttributeAliasListClass *pDbGetAttributeAliasListCmd = new DbGetAttributeAliasListClass("DbGetAttributeAliasList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "attribute alias filter string (eg: att*)", "attribute aliases", Tango::OPERATOR); command_list.push_back(pDbGetAttributeAliasListCmd); // Command DbGetClassAttributeList DbGetClassAttributeListClass *pDbGetClassAttributeListCmd = new DbGetClassAttributeListClass("DbGetClassAttributeList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class name\nStr[1] = Attribute name filter (eg: att*)", "Str[0] = Class attribute name\nStr[n] = Class attribute name", Tango::OPERATOR); command_list.push_back(pDbGetClassAttributeListCmd); // Command DbGetClassAttributeProperty DbGetClassAttributePropertyClass *pDbGetClassAttributePropertyCmd = new DbGetClassAttributePropertyClass("DbGetClassAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class name\nStr[1] = Attribute name\nStr[n] = Attribute name", "Str[0] = Tango class name\nStr[1] = Attribute property number\nStr[2] = Attribute property 1 name\nStr[3] = Attribute property 1 value\nStr[n + 1] = Attribute property 2 name\nStr[n + 2] = Attribute property 2 value", Tango::OPERATOR); command_list.push_back(pDbGetClassAttributePropertyCmd); // Command DbGetClassAttributeProperty2 DbGetClassAttributeProperty2Class *pDbGetClassAttributeProperty2Cmd = new DbGetClassAttributeProperty2Class("DbGetClassAttributeProperty2", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class name\nStr[1] = Attribute name\nStr[n] = Attribute name", "Str[0] = Tango class name\nStr[1] = Attribute property number\nStr[2] = Attribute property 1 name\nStr[3] = Attribute property 1 value number (array case)\nStr[4] = Attribute property 1 value\nStr[n] = Attribute property 1 value (array case)\nStr[n + 1] = Attribute property 2 name\nStr[n + 2] = Attribute property 2 value number (array case)\nStr[n + 3] = Attribute property 2 value\nStr[n + m] = Attribute property 2 value (array case)", Tango::OPERATOR); command_list.push_back(pDbGetClassAttributeProperty2Cmd); // Command DbGetClassAttributePropertyHist DbGetClassAttributePropertyHistClass *pDbGetClassAttributePropertyHistCmd = new DbGetClassAttributePropertyHistClass("DbGetClassAttributePropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class\nStr[1] = Attribute name\nStr[2] = Property name", "Str[0] = Attribute name\nStr[1] = Property name\nStr[2] = date\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetClassAttributePropertyHistCmd); // Command DbGetClassForDevice DbGetClassForDeviceClass *pDbGetClassForDeviceCmd = new DbGetClassForDeviceClass("DbGetClassForDevice", Tango::DEV_STRING, Tango::DEV_STRING, "Device name", "Device Tango class", Tango::OPERATOR); command_list.push_back(pDbGetClassForDeviceCmd); // Command DbGetClassInheritanceForDevice DbGetClassInheritanceForDeviceClass *pDbGetClassInheritanceForDeviceCmd = new DbGetClassInheritanceForDeviceClass("DbGetClassInheritanceForDevice", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Device name", "Classes off the specified device.\n[0] - is the class of the device.\n[1] - is the class from the device class is inherited.\n........and so on", Tango::OPERATOR); command_list.push_back(pDbGetClassInheritanceForDeviceCmd); // Command DbGetClassList DbGetClassListClass *pDbGetClassListCmd = new DbGetClassListClass("DbGetClassList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Filter", "Class list", Tango::OPERATOR); command_list.push_back(pDbGetClassListCmd); // Command DbGetClassProperty DbGetClassPropertyClass *pDbGetClassPropertyCmd = new DbGetClassPropertyClass("DbGetClassProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class\nStr[1] = Property name\nStr[2] = Property name", "Str[0] = Tango class\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number (array case)\nStr[4] = Property value\nStr[n] = Propery value (array case)\n....", Tango::OPERATOR); command_list.push_back(pDbGetClassPropertyCmd); // Command DbGetClassPropertyHist DbGetClassPropertyHistClass *pDbGetClassPropertyHistCmd = new DbGetClassPropertyHistClass("DbGetClassPropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class\nStr[1] = Property name", "Str[0] = Property name\nStr[1] = date\nStr[2] = Property value number (array case)\nStr[3] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetClassPropertyHistCmd); // Command DbGetClassPropertyList DbGetClassPropertyListClass *pDbGetClassPropertyListCmd = new DbGetClassPropertyListClass("DbGetClassPropertyList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Property name list", Tango::OPERATOR); command_list.push_back(pDbGetClassPropertyListCmd); // Command DbGetDeviceAlias DbGetDeviceAliasClass *pDbGetDeviceAliasCmd = new DbGetDeviceAliasClass("DbGetDeviceAlias", Tango::DEV_STRING, Tango::DEV_STRING, "The device name", "The alias found", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAliasCmd); // Command DbGetDeviceAliasList DbGetDeviceAliasListClass *pDbGetDeviceAliasListCmd = new DbGetDeviceAliasListClass("DbGetDeviceAliasList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Device alias list", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAliasListCmd); // Command DbGetDeviceAttributeList DbGetDeviceAttributeListClass *pDbGetDeviceAttributeListCmd = new DbGetDeviceAttributeListClass("DbGetDeviceAttributeList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Wildcard", "attribute name list", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAttributeListCmd); // Command DbGetDeviceAttributeProperty DbGetDeviceAttributePropertyClass *pDbGetDeviceAttributePropertyCmd = new DbGetDeviceAttributePropertyClass("DbGetDeviceAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Attribute name\nStr[n] = Attribute name", "Str[0] = Device name\nStr[1] = Attribute property number\nStr[2] = Attribute property 1 name\nStr[3] = Attribute property 1 value\nStr[n + 1] = Attribute property 2 name\nStr[n + 2] = Attribute property 2 value", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAttributePropertyCmd); // Command DbGetDeviceAttributeProperty2 DbGetDeviceAttributeProperty2Class *pDbGetDeviceAttributeProperty2Cmd = new DbGetDeviceAttributeProperty2Class("DbGetDeviceAttributeProperty2", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Attribute name\nStr[n] = Attribute name", "Str[0] = Device name\nStr[1] = Attribute property number\nStr[2] = Attribute property 1 name\nStr[3] = Attribute property 1 value number (array case)\nStr[4] = Attribute property 1 value\nStr[n] = Attribute property 1 value (array case)\nStr[n + 1] = Attribute property 2 name\nStr[n + 2] = Attribute property 2 value number (array case)\nStr[n + 3] = Attribute property 2 value\nStr[n + m] = Attribute property 2 value (array case)", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAttributeProperty2Cmd); // Command DbGetDeviceAttributePropertyHist DbGetDeviceAttributePropertyHistClass *pDbGetDeviceAttributePropertyHistCmd = new DbGetDeviceAttributePropertyHistClass("DbGetDeviceAttributePropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Attribute name\nStr[2] = Property name", "Str[0] = Attribute name\nStr[1] = Property name\nStr[2] = date\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetDeviceAttributePropertyHistCmd); // Command DbGetDeviceClassList DbGetDeviceClassListClass *pDbGetDeviceClassListCmd = new DbGetDeviceClassListClass("DbGetDeviceClassList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Device server process name", "Str[0] = Device name\nStr[1] = Tango class\nStr[n] = Device name\nStr[n + 1] = Tango class", Tango::OPERATOR); command_list.push_back(pDbGetDeviceClassListCmd); // Command DbGetDeviceDomainList DbGetDeviceDomainListClass *pDbGetDeviceDomainListCmd = new DbGetDeviceDomainListClass("DbGetDeviceDomainList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The wildcard", "Device name domain list", Tango::OPERATOR); command_list.push_back(pDbGetDeviceDomainListCmd); // Command DbGetDeviceExportedList DbGetDeviceExportedListClass *pDbGetDeviceExportedListCmd = new DbGetDeviceExportedListClass("DbGetDeviceExportedList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "filter", "list of exported devices", Tango::OPERATOR); command_list.push_back(pDbGetDeviceExportedListCmd); // Command DbGetDeviceFamilyList DbGetDeviceFamilyListClass *pDbGetDeviceFamilyListCmd = new DbGetDeviceFamilyListClass("DbGetDeviceFamilyList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The wildcard", "Family list", Tango::OPERATOR); command_list.push_back(pDbGetDeviceFamilyListCmd); // Command DbGetDeviceInfo DbGetDeviceInfoClass *pDbGetDeviceInfoCmd = new DbGetDeviceInfoClass("DbGetDeviceInfo", Tango::DEV_STRING, Tango::DEVVAR_LONGSTRINGARRAY, "Device name", "Str[0] = Device name\nStr[1] = CORBA IOR\nStr[2] = Device version\nStr[3] = Device Server name\nStr[4] = Device Server process host name\nStr[5] = Started date (or ? if not set)\nStr[6] = Stopped date (or ? if not set)\nStr[7] = Device class\n\nLg[0] = Device exported flag\nLg[1] = Device Server process PID (or -1 if not set)", Tango::OPERATOR); command_list.push_back(pDbGetDeviceInfoCmd); // Command DbGetDeviceList DbGetDeviceListClass *pDbGetDeviceListCmd = new DbGetDeviceListClass("DbGetDeviceList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "argin[0] : server name\nargin[1] : class name", "The list of devices for specified server and class.", Tango::OPERATOR); command_list.push_back(pDbGetDeviceListCmd); // Command DbGetDeviceWideList DbGetDeviceWideListClass *pDbGetDeviceWideListCmd = new DbGetDeviceWideListClass("DbGetDeviceWideList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "filter", "list of exported devices", Tango::OPERATOR); command_list.push_back(pDbGetDeviceWideListCmd); // Command DbGetDeviceMemberList DbGetDeviceMemberListClass *pDbGetDeviceMemberListCmd = new DbGetDeviceMemberListClass("DbGetDeviceMemberList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Device names member list", Tango::OPERATOR); command_list.push_back(pDbGetDeviceMemberListCmd); // Command DbGetDeviceProperty DbGetDevicePropertyClass *pDbGetDevicePropertyCmd = new DbGetDevicePropertyClass("DbGetDeviceProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Property name\nStr[n] = Property name", "Str[0] = Device name\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n (array case)\nStr[n + 1] = Property name\nStr[n + 2] = Property value number (array case)\nStr[n + 3] = Property value 1\nStr[n + m] = Property value m", Tango::OPERATOR); command_list.push_back(pDbGetDevicePropertyCmd); // Command DbGetDevicePropertyHist DbGetDevicePropertyHistClass *pDbGetDevicePropertyHistCmd = new DbGetDevicePropertyHistClass("DbGetDevicePropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[2] = Property name", "Str[0] = Property name\nStr[1] = date\nStr[2] = Property value number (array case)\nStr[3] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetDevicePropertyHistCmd); // Command DbGetDevicePropertyList DbGetDevicePropertyListClass *pDbGetDevicePropertyListCmd = new DbGetDevicePropertyListClass("DbGetDevicePropertyList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = device name\nStr[1] = Filter", "Property name list", Tango::OPERATOR); command_list.push_back(pDbGetDevicePropertyListCmd); // Command DbGetDeviceServerClassList DbGetDeviceServerClassListClass *pDbGetDeviceServerClassListCmd = new DbGetDeviceServerClassListClass("DbGetDeviceServerClassList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "device server process name", "list of classes for this device server", Tango::OPERATOR); command_list.push_back(pDbGetDeviceServerClassListCmd); // Command DbGetExportdDeviceListForClass DbGetExportdDeviceListForClassClass *pDbGetExportdDeviceListForClassCmd = new DbGetExportdDeviceListForClassClass("DbGetExportdDeviceListForClass", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Class name", "Device exported list", Tango::OPERATOR); command_list.push_back(pDbGetExportdDeviceListForClassCmd); // Command DbGetHostList DbGetHostListClass *pDbGetHostListCmd = new DbGetHostListClass("DbGetHostList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Host name list", Tango::OPERATOR); command_list.push_back(pDbGetHostListCmd); // Command DbGetHostServerList DbGetHostServerListClass *pDbGetHostServerListCmd = new DbGetHostServerListClass("DbGetHostServerList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Device server process name list", Tango::OPERATOR); command_list.push_back(pDbGetHostServerListCmd); // Command DbGetHostServersInfo DbGetHostServersInfoClass *pDbGetHostServersInfoCmd = new DbGetHostServersInfoClass("DbGetHostServersInfo", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Host name", "Server info for all servers running on specified host", Tango::OPERATOR); command_list.push_back(pDbGetHostServersInfoCmd); // Command DbGetInstanceNameList DbGetInstanceNameListClass *pDbGetInstanceNameListCmd = new DbGetInstanceNameListClass("DbGetInstanceNameList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Server name", "The instance names found for specified server.", Tango::OPERATOR); command_list.push_back(pDbGetInstanceNameListCmd); // Command DbGetObjectList DbGetObjectListClass *pDbGetObjectListCmd = new DbGetObjectListClass("DbGetObjectList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Object name list", Tango::OPERATOR); command_list.push_back(pDbGetObjectListCmd); // Command DbGetProperty DbGetPropertyClass *pDbGetPropertyCmd = new DbGetPropertyClass("DbGetProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Object name\nStr[1] = Property name\nStr[n] = Property name", "Str[0] = Object name\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n (array case)\nStr[n + 1] = Property name\nStr[n + 2] = Property value number (array case)\nStr[n + 3] = Property value 1\nStr[n + m] = Property value m", Tango::OPERATOR); command_list.push_back(pDbGetPropertyCmd); // Command DbGetPropertyHist DbGetPropertyHistClass *pDbGetPropertyHistCmd = new DbGetPropertyHistClass("DbGetPropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Object name\nStr[2] = Property name", "Str[0] = Property name\nStr[1] = date\nStr[2] = Property value number (array case)\nStr[3] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetPropertyHistCmd); // Command DbGetPropertyList DbGetPropertyListClass *pDbGetPropertyListCmd = new DbGetPropertyListClass("DbGetPropertyList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Object name\nStr[1] = filter", "Property name list", Tango::OPERATOR); command_list.push_back(pDbGetPropertyListCmd); // Command DbGetServerInfo DbGetServerInfoClass *pDbGetServerInfoCmd = new DbGetServerInfoClass("DbGetServerInfo", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "server name", "server info", Tango::OPERATOR); command_list.push_back(pDbGetServerInfoCmd); // Command DbGetServerList DbGetServerListClass *pDbGetServerListCmd = new DbGetServerListClass("DbGetServerList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The filter", "Device server process name list", Tango::OPERATOR); command_list.push_back(pDbGetServerListCmd); // Command DbGetServerNameList DbGetServerNameListClass *pDbGetServerNameListCmd = new DbGetServerNameListClass("DbGetServerNameList", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "wildcard for server names.", "server names found.", Tango::OPERATOR); command_list.push_back(pDbGetServerNameListCmd); // Command DbImportDevice DbImportDeviceClass *pDbImportDeviceCmd = new DbImportDeviceClass("DbImportDevice", Tango::DEV_STRING, Tango::DEVVAR_LONGSTRINGARRAY, "Device name (or alias)", "Str[0] = device name\nStr[1] = CORBA IOR\nStr[2] = device version\nStr[3] = device server process name\nStr[4] = host name\nStr[5] = Tango class name\n\nLg[0] = Exported flag\nLg[1] = Device server process PID", Tango::OPERATOR); command_list.push_back(pDbImportDeviceCmd); // Command DbImportEvent DbImportEventClass *pDbImportEventCmd = new DbImportEventClass("DbImportEvent", Tango::DEV_STRING, Tango::DEVVAR_LONGSTRINGARRAY, "name of event channel or factory", "export information e.g. IOR", Tango::OPERATOR); command_list.push_back(pDbImportEventCmd); // Command DbInfo DbInfoClass *pDbInfoCmd = new DbInfoClass("DbInfo", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "", "Miscellaneous info like:\n- Device defined in database\n- Device marked as exported in database\n- Device server process defined in database\n- Device server process marked as exported in database\n- Device properties defined in database\n- Class properties defined in database\n- Device attribute properties defined in database\n- Class attribute properties defined in database\n- Object properties defined in database", Tango::OPERATOR); command_list.push_back(pDbInfoCmd); // Command DbPutAttributeAlias DbPutAttributeAliasClass *pDbPutAttributeAliasCmd = new DbPutAttributeAliasClass("DbPutAttributeAlias", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = attribute name\nStr[1] = attribute alias", "", Tango::OPERATOR); command_list.push_back(pDbPutAttributeAliasCmd); // Command DbPutClassAttributeProperty DbPutClassAttributePropertyClass *pDbPutClassAttributePropertyCmd = new DbPutClassAttributePropertyClass("DbPutClassAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Attribute number\nStr[2] = Attribute name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value\n.....", "", Tango::OPERATOR); command_list.push_back(pDbPutClassAttributePropertyCmd); // Command DbPutClassAttributeProperty2 DbPutClassAttributeProperty2Class *pDbPutClassAttributeProperty2Cmd = new DbPutClassAttributeProperty2Class("DbPutClassAttributeProperty2", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Attribute number\nStr[2] = Attribute name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value number (array case)\nStr[5] = Property value 1\nStr[n] = Property value n (array case)\n.....", "", Tango::OPERATOR); command_list.push_back(pDbPutClassAttributeProperty2Cmd); // Command DbPutClassProperty DbPutClassPropertyClass *pDbPutClassPropertyCmd = new DbPutClassPropertyClass("DbPutClassProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number\nStr[4] = Property value 1\nStr[n] = Property value n\n....", "", Tango::OPERATOR); command_list.push_back(pDbPutClassPropertyCmd); // Command DbPutDeviceAlias DbPutDeviceAliasClass *pDbPutDeviceAliasCmd = new DbPutDeviceAliasClass("DbPutDeviceAlias", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = device name\nStr[1] = alias name", "", Tango::OPERATOR); command_list.push_back(pDbPutDeviceAliasCmd); // Command DbPutDeviceAttributeProperty DbPutDeviceAttributePropertyClass *pDbPutDeviceAttributePropertyCmd = new DbPutDeviceAttributePropertyClass("DbPutDeviceAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Attribute number\nStr[2] = Attribute name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value\n.....", "", Tango::OPERATOR); command_list.push_back(pDbPutDeviceAttributePropertyCmd); // Command DbPutDeviceAttributeProperty2 DbPutDeviceAttributeProperty2Class *pDbPutDeviceAttributeProperty2Cmd = new DbPutDeviceAttributeProperty2Class("DbPutDeviceAttributeProperty2", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Attribute number\nStr[2] = Attribute name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value number (array case)\nStr[5] = Property value 1\nStr[n] = Property value n (array case)\n.....", "", Tango::OPERATOR); command_list.push_back(pDbPutDeviceAttributeProperty2Cmd); // Command DbPutDeviceProperty DbPutDevicePropertyClass *pDbPutDevicePropertyCmd = new DbPutDevicePropertyClass("DbPutDeviceProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango device name\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number\nStr[4] = Property value 1\nStr[n] = Property value n\n....", "", Tango::OPERATOR); command_list.push_back(pDbPutDevicePropertyCmd); // Command DbPutProperty DbPutPropertyClass *pDbPutPropertyCmd = new DbPutPropertyClass("DbPutProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Object name\nStr[1] = Property number\nStr[2] = Property name\nStr[3] = Property value number\nStr[4] = Property value 1\nStr[n] = Property value n\n....", "", Tango::OPERATOR); command_list.push_back(pDbPutPropertyCmd); // Command DbPutServerInfo DbPutServerInfoClass *pDbPutServerInfoCmd = new DbPutServerInfoClass("DbPutServerInfo", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "server info", "", Tango::OPERATOR); command_list.push_back(pDbPutServerInfoCmd); // Command DbUnExportDevice DbUnExportDeviceClass *pDbUnExportDeviceCmd = new DbUnExportDeviceClass("DbUnExportDevice", Tango::DEV_STRING, Tango::DEV_VOID, "Device name", "", Tango::OPERATOR); command_list.push_back(pDbUnExportDeviceCmd); // Command DbUnExportEvent DbUnExportEventClass *pDbUnExportEventCmd = new DbUnExportEventClass("DbUnExportEvent", Tango::DEV_STRING, Tango::DEV_VOID, "name of event channel or factory to unexport", "none", Tango::OPERATOR); command_list.push_back(pDbUnExportEventCmd); // Command DbUnExportServer DbUnExportServerClass *pDbUnExportServerCmd = new DbUnExportServerClass("DbUnExportServer", Tango::DEV_STRING, Tango::DEV_VOID, "Device server name (executable/instance)", "", Tango::OPERATOR); command_list.push_back(pDbUnExportServerCmd); // Command ResetTimingValues ResetTimingValuesClass *pResetTimingValuesCmd = new ResetTimingValuesClass("ResetTimingValues", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::OPERATOR); command_list.push_back(pResetTimingValuesCmd); // Command DbGetDataForServerCache DbGetDataForServerCacheClass *pDbGetDataForServerCacheCmd = new DbGetDataForServerCacheClass("DbGetDataForServerCache", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Elt[0] = DS name (exec_name/inst_name), Elt[1] = Host name", "All the data needed by the device server during its startup sequence. Precise list depend on the device server", Tango::OPERATOR); command_list.push_back(pDbGetDataForServerCacheCmd); // Command DbDeleteAllDeviceAttributeProperty DbDeleteAllDeviceAttributePropertyClass *pDbDeleteAllDeviceAttributePropertyCmd = new DbDeleteAllDeviceAttributePropertyClass("DbDeleteAllDeviceAttributeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "str[0] = device name\nStr[1]...str[n] = attribute name(s)", "", Tango::OPERATOR); command_list.push_back(pDbDeleteAllDeviceAttributePropertyCmd); // Command DbMySqlSelect DbMySqlSelectClass *pDbMySqlSelectCmd = new DbMySqlSelectClass("DbMySqlSelect", Tango::DEV_STRING, Tango::DEVVAR_LONGSTRINGARRAY, "MySql Select command", "MySql Select command result\n - svalues : select results\n - lvalue[n] : =0 if svalue[n] is null else =1\n (last lvalue -1) is number of rows, (last lvalue) is number of fields", Tango::OPERATOR); command_list.push_back(pDbMySqlSelectCmd); // Command DbGetCSDbServerList DbGetCSDbServerListClass *pDbGetCSDbServerListCmd = new DbGetCSDbServerListClass("DbGetCSDbServerList", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "", "List of host:port with one element for each database server", Tango::OPERATOR); command_list.push_back(pDbGetCSDbServerListCmd); // Command DbGetAttributeAlias2 DbGetAttributeAlias2Class *pDbGetAttributeAlias2Cmd = new DbGetAttributeAlias2Class("DbGetAttributeAlias2", Tango::DEV_STRING, Tango::DEV_STRING, "The attribute name (dev_name/att_name)", "The attribute alias name (or empty string)", Tango::OPERATOR); command_list.push_back(pDbGetAttributeAlias2Cmd); // Command DbGetAliasAttribute DbGetAliasAttributeClass *pDbGetAliasAttributeCmd = new DbGetAliasAttributeClass("DbGetAliasAttribute", Tango::DEV_STRING, Tango::DEV_STRING, "The attribute alias", "The attribute name (dev_name/att_name)", Tango::OPERATOR); command_list.push_back(pDbGetAliasAttributeCmd); // Command DbRenameServer DbRenameServerClass *pDbRenameServerCmd = new DbRenameServerClass("DbRenameServer", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "s[0] = old device server name (exec/instance)\ns[1] = new device server name (exec/instance)", "", Tango::OPERATOR); command_list.push_back(pDbRenameServerCmd); // Command DbGetClassPipeProperty DbGetClassPipePropertyClass *pDbGetClassPipePropertyCmd = new DbGetClassPipePropertyClass("DbGetClassPipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class name\nStr[1] = Pipe name\nStr[n] = Pipe name", "Str[0] = Tango class name\nStr[1] = Pipe property number\nStr[2] = Pipe property 1 name\nStr[3] = Pipe property 1 value number (array case)\nStr[4] = Pipe property 1 value\nStr[n] = Pipe property 1 value (array case)\nStr[n + 1] = Pipe property 2 name\nStr[n + 2] = Pipe property 2 value number (array case)\nStr[n + 3] = Pipe property 2 value\nStr[n + m] = Pipe property 2 value (array case)", Tango::OPERATOR); command_list.push_back(pDbGetClassPipePropertyCmd); // Command DbGetDevicePipeProperty DbGetDevicePipePropertyClass *pDbGetDevicePipePropertyCmd = new DbGetDevicePipePropertyClass("DbGetDevicePipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Pipe name\nStr[n] = Pipe name", "Str[0] = Device name\nStr[1] = Pipe property number\nStr[2] = Pipe property 1 name\nStr[3] = Pipe property 1 value number (array case)\nStr[4] = Pipe property 1 value\nStr[n] = Pipe property 1 value (array case)\nStr[n + 1] = Pipe property 2 name\nStr[n + 2] = Pipe property 2 value number (array case)\nStr[n + 3] = Pipe property 2 value\nStr[n + m] = Pipe property 2 value (array case)", Tango::OPERATOR); command_list.push_back(pDbGetDevicePipePropertyCmd); // Command DbDeleteClassPipe DbDeleteClassPipeClass *pDbDeleteClassPipeCmd = new DbDeleteClassPipeClass("DbDeleteClassPipe", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Pipe name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteClassPipeCmd); // Command DbDeleteDevicePipe DbDeleteDevicePipeClass *pDbDeleteDevicePipeCmd = new DbDeleteDevicePipeClass("DbDeleteDevicePipe", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Pipe name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDevicePipeCmd); // Command DbDeleteClassPipeProperty DbDeleteClassPipePropertyClass *pDbDeleteClassPipePropertyCmd = new DbDeleteClassPipePropertyClass("DbDeleteClassPipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Pipe name\nStr[2] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteClassPipePropertyCmd); // Command DbDeleteDevicePipeProperty DbDeleteDevicePipePropertyClass *pDbDeleteDevicePipePropertyCmd = new DbDeleteDevicePipePropertyClass("DbDeleteDevicePipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Pipe name\nStr[2] = Property name\nStr[n] = Property name", "", Tango::OPERATOR); command_list.push_back(pDbDeleteDevicePipePropertyCmd); // Command DbGetClassPipeList DbGetClassPipeListClass *pDbGetClassPipeListCmd = new DbGetClassPipeListClass("DbGetClassPipeList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class name\nStr[1] = Pipe name filter (eg: pip*)", "Str[0] = Class pipe name\nStr[n] = Class pipe name", Tango::OPERATOR); command_list.push_back(pDbGetClassPipeListCmd); // Command DbGetDevicePipeList DbGetDevicePipeListClass *pDbGetDevicePipeListCmd = new DbGetDevicePipeListClass("DbGetDevicePipeList", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Wildcard", "Pipe name list", Tango::OPERATOR); command_list.push_back(pDbGetDevicePipeListCmd); // Command DbDeleteAllDevicePipeProperty DbDeleteAllDevicePipePropertyClass *pDbDeleteAllDevicePipePropertyCmd = new DbDeleteAllDevicePipePropertyClass("DbDeleteAllDevicePipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "str[0] = device name\nStr[1]...str[n] = pipe name(s)", "", Tango::OPERATOR); command_list.push_back(pDbDeleteAllDevicePipePropertyCmd); // Command DbPutClassPipeProperty DbPutClassPipePropertyClass *pDbPutClassPipePropertyCmd = new DbPutClassPipePropertyClass("DbPutClassPipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Tango class name\nStr[1] = Pipe number\nStr[2] = Pipe name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value number (array case)\nStr[5] = Property value 1\nStr[n] = Property value n (array case)", "", Tango::OPERATOR); command_list.push_back(pDbPutClassPipePropertyCmd); // Command DbPutDevicePipeProperty DbPutDevicePipePropertyClass *pDbPutDevicePipePropertyCmd = new DbPutDevicePipePropertyClass("DbPutDevicePipeProperty", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "Str[0] = Device name\nStr[1] = Pipe number\nStr[2] = Pipe name\nStr[3] = Property number\nStr[4] = Property name\nStr[5] = Property value number (array case)\nStr[6] = Property value 1\nStr[n] = Property value n (array case)", "", Tango::OPERATOR); command_list.push_back(pDbPutDevicePipePropertyCmd); // Command DbGetClassPipePropertyHist DbGetClassPipePropertyHistClass *pDbGetClassPipePropertyHistCmd = new DbGetClassPipePropertyHistClass("DbGetClassPipePropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Tango class\nStr[1] = Pipe name\nStr[2] = Property name", "Str[0] = Pipe name\nStr[1] = Property name\nStr[2] = date\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetClassPipePropertyHistCmd); // Command DbGetDevicePipePropertyHist DbGetDevicePipePropertyHistClass *pDbGetDevicePipePropertyHistCmd = new DbGetDevicePipePropertyHistClass("DbGetDevicePipePropertyHist", Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_STRINGARRAY, "Str[0] = Device name\nStr[1] = Pipe name\nStr[2] = Property name", "Str[0] = Pipe name\nStr[1] = Property name\nStr[2] = date\nStr[3] = Property value number (array case)\nStr[4] = Property value 1\nStr[n] = Property value n", Tango::OPERATOR); command_list.push_back(pDbGetDevicePipePropertyHistCmd); // Command DbGetForwardedAttributeListForDevice DbGetForwardedAttributeListForDeviceClass *pDbGetForwardedAttributeListForDeviceCmd = new DbGetForwardedAttributeListForDeviceClass("DbGetForwardedAttributeListForDevice", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "The specified device name", "argout[n] : device name\nargout[n+1] :the forwardef attribute\nargout[n+2] :the root attribute (__root_att)", Tango::OPERATOR); command_list.push_back(pDbGetForwardedAttributeListForDeviceCmd); /*----- PROTECTED REGION ID(DataBaseClass::command_factory_after) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::command_factory_after } //=================================================================== // Dynamic attributes related methods //=================================================================== //-------------------------------------------------------- /** * method : DataBaseClass::create_static_attribute_list * description : Create the a list of static attributes * * @param att_list the ceated attribute list */ //-------------------------------------------------------- void DataBaseClass::create_static_attribute_list(vector &att_list) { for (unsigned long i=0 ; iget_name()); transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); defaultAttList.push_back(att_name); } cout2 << defaultAttList.size() << " attributes in default list" << endl; /*----- PROTECTED REGION ID(DataBaseClass::create_static_att_list) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::create_static_att_list } //-------------------------------------------------------- /** * method : DataBaseClass::erase_dynamic_attributes * description : delete the dynamic attributes if any. * * @param devlist_ptr the device list pointer * @param list of all attributes */ //-------------------------------------------------------- void DataBaseClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector &att_list) { Tango::Util *tg = Tango::Util::instance(); for (unsigned long i=0 ; ilength() ; i++) { Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); DataBase *dev = static_cast (dev_impl); vector &dev_att_list = dev->get_device_attr()->get_attribute_list(); vector::iterator ite_att; for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) { string att_name((*ite_att)->get_name_lower()); if ((att_name == "state") || (att_name == "status")) continue; vector::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); if (ite_str == defaultAttList.end()) { cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); dev->remove_attribute(att_list[att.get_attr_idx()], true, false); --ite_att; } } } /*----- PROTECTED REGION ID(DataBaseClass::erase_dynamic_attributes) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::erase_dynamic_attributes } //-------------------------------------------------------- /** * Method : DataBaseClass::get_attr_by_name() * Description : returns Tango::Attr * object found by name */ //-------------------------------------------------------- Tango::Attr *DataBaseClass::get_attr_object_by_name(vector &att_list, string attname) { vector::iterator it; for (it=att_list.begin() ; itget_name()==attname) return (*it); // Attr does not exist return NULL; } /*----- PROTECTED REGION ID(DataBaseClass::Additional Methods) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::Additional Methods } // namespace tango-9.2.5a/cppserver/database/DataBase.cpp0000644023471100065110000121770013034745006015665 00000000000000/*----- PROTECTED REGION ID(DataBase.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: DataBase.cpp 30129 2016-09-06 13:57:58Z taurel $"; //============================================================================= // // file : DataBase.cpp // // description : C++ source for the DataBase and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // DataBase are implemented in this file. // // project : TANGO Database server. // // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 30129 $ // $Date: 2016-09-06 15:57:58 +0200 (Tue, 06 Sep 2016) $ // // $HeadURL: https://svn.code.sf.net/p/tango-cs/code/classes/cpp/dbase/tags/DataBase-Release-5.6/DataBase.cpp $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include #include #include /*----- PROTECTED REGION END -----*/ // DataBase.cpp /** * DataBase class description: * This class manage the TANGO database. */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | dev_state // Status | Inherited (no method) // DbAddDevice | db_add_device // DbAddServer | db_add_server // DbDeleteAttributeAlias | db_delete_attribute_alias // DbDeleteClassAttribute | db_delete_class_attribute // DbDeleteClassAttributeProperty | db_delete_class_attribute_property // DbDeleteClassProperty | db_delete_class_property // DbDeleteDevice | db_delete_device // DbDeleteDeviceAlias | db_delete_device_alias // DbDeleteDeviceAttribute | db_delete_device_attribute // DbDeleteDeviceAttributeProperty | db_delete_device_attribute_property // DbDeleteDeviceProperty | db_delete_device_property // DbDeleteProperty | db_delete_property // DbDeleteServer | db_delete_server // DbDeleteServerInfo | db_delete_server_info // DbExportDevice | db_export_device // DbExportEvent | db_export_event // DbGetAliasDevice | db_get_alias_device // DbGetAttributeAlias | db_get_attribute_alias // DbGetAttributeAliasList | db_get_attribute_alias_list // DbGetClassAttributeList | db_get_class_attribute_list // DbGetClassAttributeProperty | db_get_class_attribute_property // DbGetClassAttributeProperty2 | db_get_class_attribute_property2 // DbGetClassAttributePropertyHist | db_get_class_attribute_property_hist // DbGetClassForDevice | db_get_class_for_device // DbGetClassInheritanceForDevice | db_get_class_inheritance_for_device // DbGetClassList | db_get_class_list // DbGetClassProperty | db_get_class_property // DbGetClassPropertyHist | db_get_class_property_hist // DbGetClassPropertyList | db_get_class_property_list // DbGetDeviceAlias | db_get_device_alias // DbGetDeviceAliasList | db_get_device_alias_list // DbGetDeviceAttributeList | db_get_device_attribute_list // DbGetDeviceAttributeProperty | db_get_device_attribute_property // DbGetDeviceAttributeProperty2 | db_get_device_attribute_property2 // DbGetDeviceAttributePropertyHist | db_get_device_attribute_property_hist // DbGetDeviceClassList | db_get_device_class_list // DbGetDeviceDomainList | db_get_device_domain_list // DbGetDeviceExportedList | db_get_device_exported_list // DbGetDeviceFamilyList | db_get_device_family_list // DbGetDeviceInfo | db_get_device_info // DbGetDeviceList | db_get_device_list // DbGetDeviceWideList | db_get_device_wide_list // DbGetDeviceMemberList | db_get_device_member_list // DbGetDeviceProperty | db_get_device_property // DbGetDevicePropertyHist | db_get_device_property_hist // DbGetDevicePropertyList | db_get_device_property_list // DbGetDeviceServerClassList | db_get_device_server_class_list // DbGetExportdDeviceListForClass | db_get_exportd_device_list_for_class // DbGetHostList | db_get_host_list // DbGetHostServerList | db_get_host_server_list // DbGetHostServersInfo | db_get_host_servers_info // DbGetInstanceNameList | db_get_instance_name_list // DbGetObjectList | db_get_object_list // DbGetProperty | db_get_property // DbGetPropertyHist | db_get_property_hist // DbGetPropertyList | db_get_property_list // DbGetServerInfo | db_get_server_info // DbGetServerList | db_get_server_list // DbGetServerNameList | db_get_server_name_list // DbImportDevice | db_import_device // DbImportEvent | db_import_event // DbInfo | db_info // DbPutAttributeAlias | db_put_attribute_alias // DbPutClassAttributeProperty | db_put_class_attribute_property // DbPutClassAttributeProperty2 | db_put_class_attribute_property2 // DbPutClassProperty | db_put_class_property // DbPutDeviceAlias | db_put_device_alias // DbPutDeviceAttributeProperty | db_put_device_attribute_property // DbPutDeviceAttributeProperty2 | db_put_device_attribute_property2 // DbPutDeviceProperty | db_put_device_property // DbPutProperty | db_put_property // DbPutServerInfo | db_put_server_info // DbUnExportDevice | db_un_export_device // DbUnExportEvent | db_un_export_event // DbUnExportServer | db_un_export_server // ResetTimingValues | reset_timing_values // DbGetDataForServerCache | db_get_data_for_server_cache // DbDeleteAllDeviceAttributeProperty | db_delete_all_device_attribute_property // DbMySqlSelect | db_my_sql_select // DbGetCSDbServerList | db_get_csdb_server_list // DbGetAttributeAlias2 | db_get_attribute_alias2 // DbGetAliasAttribute | db_get_alias_attribute // DbRenameServer | db_rename_server // DbGetClassPipeProperty | db_get_class_pipe_property // DbGetDevicePipeProperty | db_get_device_pipe_property // DbDeleteClassPipe | db_delete_class_pipe // DbDeleteDevicePipe | db_delete_device_pipe // DbDeleteClassPipeProperty | db_delete_class_pipe_property // DbDeleteDevicePipeProperty | db_delete_device_pipe_property // DbGetClassPipeList | db_get_class_pipe_list // DbGetDevicePipeList | db_get_device_pipe_list // DbDeleteAllDevicePipeProperty | db_delete_all_device_pipe_property // DbPutClassPipeProperty | db_put_class_pipe_property // DbPutDevicePipeProperty | db_put_device_pipe_property // DbGetClassPipePropertyHist | db_get_class_pipe_property_hist // DbGetDevicePipePropertyHist | db_get_device_pipe_property_hist // DbGetForwardedAttributeListForDevice | db_get_forwarded_attribute_list_for_device //================================================================ //================================================================ // Attributes managed are: //================================================================ // StoredProcedureRelease | Tango::DevString Scalar // Timing_average | Tango::DevDouble Spectrum ( max = 64) // Timing_minimum | Tango::DevDouble Spectrum ( max = 64) // Timing_maximum | Tango::DevDouble Spectrum ( max = 64) // Timing_calls | Tango::DevDouble Spectrum ( max = 64) // Timing_index | Tango::DevString Spectrum ( max = 64) // Timing_info | Tango::DevString Spectrum ( max = 64) //================================================================ namespace DataBase_ns { /*----- PROTECTED REGION ID(DataBase::namespace_starting) ENABLED START -----*/ // static initializations string DataBase::db_name("sys/database/1"); bool nocase_compare(char c1, char c2) { return toupper(c1) == toupper(c2); } /*----- PROTECTED REGION END -----*/ // DataBase::namespace_starting //-------------------------------------------------------- /** * Method : DataBase::DataBase() * Description : Constructors for a Tango device * implementing the classDataBase */ //-------------------------------------------------------- DataBase::DataBase(Tango::DeviceClass *cl, string &s) : TANGO_BASE_CLASS(cl, s.c_str()) { /*----- PROTECTED REGION ID(DataBase::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // DataBase::constructor_1 } //-------------------------------------------------------- DataBase::DataBase(Tango::DeviceClass *cl, const char *s) : TANGO_BASE_CLASS(cl, s) { /*----- PROTECTED REGION ID(DataBase::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // DataBase::constructor_2 } //-------------------------------------------------------- DataBase::DataBase(Tango::DeviceClass *cl, const char *s, const char *d) : TANGO_BASE_CLASS(cl, s, d) { /*----- PROTECTED REGION ID(DataBase::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // DataBase::constructor_3 } //-------------------------------------------------------- /** * Method : DataBase::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void DataBase::delete_device() { DEBUG_STREAM << "DataBase::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::delete_device) ENABLED START -----*/ // Mark the server as non-exported in db if (get_state() == Tango::ON) { Tango::Util *tg = Tango::Util::instance(); string &ds_name = tg->get_ds_name(); char *tmp_ds_name = const_cast(ds_name.c_str()); db_un_export_server(tmp_ds_name); } // Delete device allocated objects // Delete device's allocated object delete [] timing_stats_average; delete [] timing_stats_minimum; delete [] timing_stats_maximum; delete [] timing_stats_calls; for (unsigned int i = 0;i < timing_stats_map.size();i++) free(timing_stats_index[i]); delete [] timing_stats_index; std::map::iterator iter; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) delete iter->second; for (int loop = 0;loop < conn_pool_size;loop++) { if (conn_pool[loop].db != NULL) mysql_close(conn_pool[loop].db); } delete [] conn_pool; /*----- PROTECTED REGION END -----*/ // DataBase::delete_device } //-------------------------------------------------------- /** * Method : DataBase::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void DataBase::init_device() { DEBUG_STREAM << "DataBase::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::init_device_before) ENABLED START -----*/ // Initialization before get_device_property() call /*----- PROTECTED REGION END -----*/ // DataBase::init_device_before // No device property to be read from database /*----- PROTECTED REGION ID(DataBase::init_device) ENABLED START -----*/ // // Just to keep the rcsId string (Some compilers optimize it away) // string str_rcs(RcsId); // // Initialize device // const char *mysql_user = NULL; const char *mysql_password = NULL; const char *mysql_host = NULL; const char *mysql_name = NULL; WARN_STREAM << "DataBase::DataBase() create database device " << device_name << endl; // // Check if we are using the thread safe release of the MySQL library // if (mysql_thread_safe() == 0) { ERROR_STREAM << "MySQL library used by this process is not tread safe. Please, use libmysqlclient_r" << endl; Tango::Except::throw_exception((const char *)DB_MySQLLibNotThreadSafe, (const char *)"MySQL library used by this process is not thread safe. Please, use libmysqlclient_r or use DataBase release < 4.x", (const char *)"DataBase::DataBase()"); } // // Get user environment variables if defined // DummyDev d; string my_user,my_password,my_host,my_name; if (d.get_env_var("MYSQL_USER",my_user) != -1) { mysql_user = my_user.c_str(); } if (d.get_env_var("MYSQL_PASSWORD",my_password) != -1) { mysql_password = my_password.c_str(); } if (d.get_env_var("MYSQL_HOST",my_host) != -1) { mysql_host = my_host.c_str(); } if (d.get_env_var("MYSQL_DATABASE",my_name) != -1) { mysql_name = my_name.c_str(); } // // Create the connection pool after some initialisation // conn_pool = new DbConnection[conn_pool_size]; for (int loop = 0;loop < conn_pool_size;loop++) conn_pool[loop].db = NULL; mysql_svr_version = 0; create_connection_pool(mysql_user,mysql_password,mysql_host,mysql_name); // // Do we need to propagate info to Starter // try { // Check if controlled server list modification must be fired to starter Tango::DevVarStringArray *argin = new Tango::DevVarStringArray(); argin->length(2); (*argin)[0] = CORBA::string_dup("Default"); (*argin)[1] = CORBA::string_dup("FireToStarter"); Tango::DevVarStringArray *argout = db_get_property(argin); if ((*argout)[3] == 0) // Not defined fireToStarter = true; else { // Get property value string value((*argout)[4]); transform(value.begin(), value.end(), value.begin(), ::tolower); if (value=="false") fireToStarter = false; else fireToStarter = true; } delete argin; delete argout; } catch(Tango::DevFailed &) { fireToStarter = true; } WARN_STREAM << "fireToStarter = " << fireToStarter << endl; // If fire to starter is true if (fireToStarter==true) { // Build shared data and thread to update Starter in case of // change of controlled servers conditions starter_shared = new UpdStarterData(); upd_starter_thread = new UpdateStarter(starter_shared); upd_starter_thread->start(); } // Load history depth property historyDepth = 10; try { Tango::DevVarStringArray *argin = new Tango::DevVarStringArray(); argin->length(2); (*argin)[0] = CORBA::string_dup(get_name().c_str()); (*argin)[1] = CORBA::string_dup("historyDepth"); Tango::DevVarStringArray *argout = db_get_device_property(argin); if ((*argout)[3] != 0) { if(strcmp((*argout)[4]," ")!=0) { stringstream ss; ss << (*argout)[4]; ss >> historyDepth; if( historyDepth == 0 ) { cout << "Warning, Invalid historyDepth property, reseting to default value (10)" << endl; historyDepth = 10; } } } delete argin; delete argout; } catch(Tango::DevFailed &) {} // Check history tables check_history_tables(); init_timing_stats(); stored_release_ptr = &(stored_release[0]); attr_StoredProcedureRelease_read = &stored_release_ptr; set_state(Tango::ON); set_status("Device is OK"); /*----- PROTECTED REGION END -----*/ // DataBase::init_device } //-------------------------------------------------------- /** * Method : DataBase::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void DataBase::always_executed_hook() { DEBUG_STREAM << "DataBase::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::always_executed_hook) ENABLED START -----*/ // code always executed before all requests /*----- PROTECTED REGION END -----*/ // DataBase::always_executed_hook } //-------------------------------------------------------- /** * Method : DataBase::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void DataBase::read_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "DataBase::read_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_attr_hardware) ENABLED START -----*/ // Add your own code // Add your own code here /*----- PROTECTED REGION END -----*/ // DataBase::read_attr_hardware } //-------------------------------------------------------- /** * Read attribute StoredProcedureRelease related method * Description: * * Data type: Tango::DevString * Attr type: Scalar */ //-------------------------------------------------------- void DataBase::read_StoredProcedureRelease(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_StoredProcedureRelease(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_StoredProcedureRelease) ENABLED START -----*/ TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_fields; sql_query_stream << "SHOW PROCEDURE STATUS WHERE Db LIKE \""; sql_query_stream << mysql_db_name; sql_query_stream << "\" AND Name LIKE \"ds_start\""; DEBUG_STREAM << "DataBase::read_StoredProcedureRelease(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"read_StoredProcedureRelease()"); n_fields = mysql_num_fields(result); DEBUG_STREAM << "DataBase::read_StoreProcedureRelease(): mysql_num_fields() " << n_fields << endl; if (n_fields > 7) { unsigned long *lengths; if ((row = mysql_fetch_row(result)) != NULL) { lengths = mysql_fetch_lengths(result); strcpy(stored_release,row[7]); stored_release[lengths[7]] = '\0'; } else { mysql_free_result(result); Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"Can't fetch row from the returned result", (const char *)"DataBase::read_StoredProcedureRelease()"); } } else { mysql_free_result(result); Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"Wrong fields number in the data returned by the query", (const char *)"DataBase::read_StoredProcedureRelease()"); } mysql_free_result(result); attr.set_value(attr_StoredProcedureRelease_read); /*----- PROTECTED REGION END -----*/ // DataBase::read_StoredProcedureRelease } //-------------------------------------------------------- /** * Read attribute Timing_average related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_average(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_average(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_average) ENABLED START -----*/ std::map::iterator iter; { omni_mutex_lock guard(timing_stats_mutex); int i = 0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { timing_stats_average[i] = iter->second->average; i++; } } attr.set_value(timing_stats_average, timing_stats_size); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_average } //-------------------------------------------------------- /** * Read attribute Timing_minimum related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_minimum(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_minimum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_minimum) ENABLED START -----*/ std::map::iterator iter; { omni_mutex_lock guard(timing_stats_mutex); int i = 0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { timing_stats_minimum[i] = iter->second->minimum; i++; } } attr.set_value(timing_stats_minimum, timing_stats_size); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_minimum } //-------------------------------------------------------- /** * Read attribute Timing_maximum related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_maximum(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_maximum(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_maximum) ENABLED START -----*/ std::map::iterator iter; { omni_mutex_lock guard(timing_stats_mutex); int i = 0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { timing_stats_maximum[i] = iter->second->maximum; i++; } } attr.set_value(timing_stats_maximum, timing_stats_size); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_maximum } //-------------------------------------------------------- /** * Read attribute Timing_calls related method * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_calls(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_calls(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_calls) ENABLED START -----*/ std::map::iterator iter; { omni_mutex_lock guard(timing_stats_mutex); int i = 0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { timing_stats_calls[i] = iter->second->calls; i++; } } attr.set_value(timing_stats_calls, timing_stats_size); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_calls } //-------------------------------------------------------- /** * Read attribute Timing_index related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_index(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_index(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_index) ENABLED START -----*/ attr.set_value(timing_stats_index, timing_stats_size); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_index } //-------------------------------------------------------- /** * Read attribute Timing_info related method * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 64 */ //-------------------------------------------------------- void DataBase::read_Timing_info(Tango::Attribute &attr) { DEBUG_STREAM << "DataBase::read_Timing_info(Tango::Attribute &attr) entering... " << endl; /*----- PROTECTED REGION ID(DataBase::read_Timing_info) ENABLED START -----*/ char info_str[256]; char hostname[256]; Tango::DevString *timing_info = new Tango::DevString[timing_stats_size+4]; gethostname(hostname, sizeof(hostname)); sprintf(info_str,"TANGO Database Timing info on host %s",hostname); timing_info[0] = CORBA::string_dup(info_str); // newline timing_info[1] = CORBA::string_dup(" "); timing_info[2] = CORBA::string_dup("command average minimum maximum calls"); timing_info[3] = CORBA::string_dup(" "); std::map::iterator iter; { omni_mutex_lock guard(timing_stats_mutex); int i = 0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { sprintf(info_str,"%s\t%6.3f\t%6.3f\t%6.3f\t%.0f", iter->first.c_str(), iter->second->average, iter->second->minimum, iter->second->maximum, iter->second->calls); timing_info[i+4] = CORBA::string_dup(info_str); i++; } } attr.set_value(timing_info,timing_stats_size+4,0,true); /*----- PROTECTED REGION END -----*/ // DataBase::read_Timing_info } //-------------------------------------------------------- /** * Method : DataBase::add_dynamic_attributes() * Description : Create the dynamic attributes if any * for specified device. */ //-------------------------------------------------------- void DataBase::add_dynamic_attributes() { /*----- PROTECTED REGION ID(DataBase::add_dynamic_attributes) ENABLED START -----*/ // Add your own code to create and add dynamic attributes if any /*----- PROTECTED REGION END -----*/ // DataBase::add_dynamic_attributes } //-------------------------------------------------------- /** * Command State related method * Description: This command gets the device state (stored in its device_state data member) and returns it to the caller. * * @returns State Code */ //-------------------------------------------------------- Tango::DevState DataBase::dev_state() { DEBUG_STREAM << "DataBase::State() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::dev_state) ENABLED START -----*/ Tango::DevState argout = DeviceImpl::dev_state(); // Add your own state management return device_state; /*----- PROTECTED REGION END -----*/ // DataBase::dev_state set_state(argout); // Give the state to Tango. if (argout!=Tango::ALARM) DeviceImpl::dev_state(); return get_state(); // Return it after Tango management. } //-------------------------------------------------------- /** * Command DbAddDevice related method * Description: Add a Tango class device to a specific device server * * @param argin Str[0] = Full device server process name * Str[1] = Device name * Str[2] = Tango class name */ //-------------------------------------------------------- void DataBase::db_add_device(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbAddDevice() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_add_device) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *server_device = argin; TangoSys_MemStream sql_query_stream; char domain[256], family[256], member[256]; const char *tmp_server, *tmp_class, *tmp_alias = NULL; string tmp_device; string dserver_name; MYSQL_RES *result; if (server_device->length() < 3) { WARN_STREAM << "DataBase::AddDevice(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs at least 3 (server,device,class)", (const char *)"DataBase::AddDevice()"); } INFO_STREAM << "DataBase::AddDevice(): insert " << (*server_device)[0] << " server with device " << (*server_device)[1] << endl; tmp_server = (*server_device)[0]; tmp_device = (*server_device)[1]; tmp_class = (*server_device)[2]; if (server_device->length() > 3) { tmp_alias = (*server_device)[3]; } if (!check_device_name(tmp_device)) { TangoSys_OMemStream o; o << "device name (" << tmp_device << ") syntax error (should be [tango:][//instance/]domain/family/member)"; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, o.str(), (const char *)"DataBase::AddDevice()"); } device_name_to_dfm(tmp_device, domain, family, member); { AutoLock al("LOCK TABLE device WRITE",this); int n_rows=0; // first delete the tuple (device,name) from the device table sql_query_stream << "DELETE FROM device WHERE name LIKE \"" << tmp_device << "\""; DEBUG_STREAM << "DataBase::AddDevice(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_device()",al.get_con_nb()); // then insert the new value for this tuple sql_query_stream.str(""); if (server_device->length() < 4) { sql_query_stream << "INSERT INTO device SET name=\"" << tmp_device << "\",domain=\"" << domain << "\",family=\"" << family << "\",member=\"" << member << "\",exported=0,ior=\"nada\",host=\"nada\",server=\"" << tmp_server << "\",pid=0,class=\"" << tmp_class << "\",version=\"0\",started=NULL,stopped=NULL"; } else { sql_query_stream << "INSERT INTO device SET name=\"" << tmp_device << "\",domain=\"" << domain << "\",family=\"" << family << "\",member=\"" << member << "\",exported=0,ior=\"nada\",host=\"nada\",server=\"" << tmp_server << "\",pid=0,class=\"" << tmp_class << "\",alias=\"" << tmp_alias << "\",version=\"0\",started=NULL,stopped=NULL"; } DEBUG_STREAM << "DataBase::AddDevice(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_device()",al.get_con_nb()); // // Check if a DServer device entry for the process already exists // sql_query_stream.str(""); sql_query_stream << "SELECT name FROM device WHERE server LIKE \"" << tmp_server << "\" AND class LIKE \"DServer\""; DEBUG_STREAM << "DataBase::AddDevice(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_add_device()",al.get_con_nb()); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::AddDevice(): mysql_num_rows() " << n_rows << endl; // // If there is no admin device for the device's server, create one // if (n_rows == 0) { dserver_name = "dserver/"; dserver_name = dserver_name + string(tmp_server); device_name_to_dfm(dserver_name, domain, family, member); sql_query_stream.str(""); sql_query_stream << "INSERT INTO device SET name=\"dserver/" << tmp_server << "\",domain=\"" << domain << "\",family=\"" << family << "\",member=\"" << member << "\",exported=0,ior=\"nada\",host=\"nada\",server=\"" << tmp_server << "\",pid=0,class=\"DServer\",version=\"0\",started=NULL,stopped=NULL"; DEBUG_STREAM << "DataBase::AddDevice(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_device()",al.get_con_nb()); } mysql_free_result(result); } return; /*----- PROTECTED REGION END -----*/ // DataBase::db_add_device } //-------------------------------------------------------- /** * Command DbAddServer related method * Description: Create a device server process entry in database * * @param argin Str[0] = Full device server name * Str[1] = Device(s) name * Str[2] = Tango class name * Str[n] = Device name * Str[n + 1] = Tango class name */ //-------------------------------------------------------- void DataBase::db_add_server(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbAddServer() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_add_server) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *server_device_list = argin; TangoSys_MemStream sql_query_stream; char domain[256], family[256], member[256]; const char *tmp_server, *tmp_class; if (server_device_list->length() < 3) { WARN_STREAM << "DataBase::AddServer(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs at least 3 (server,device,class)", (const char *)"DataBase::AddServer()"); } INFO_STREAM << "DataBase::AddServer(): insert " << (*server_device_list)[0] << " server with device " << (*server_device_list)[1] << endl; tmp_server = (*server_device_list)[0]; { AutoLock al("LOCK TABLE device WRITE",this); for (unsigned int i=0; i<(server_device_list->length()-1)/2; i++) { string tmp_device((*server_device_list)[i*2+1].in()); tmp_class = (*server_device_list)[i*2+2]; if (!check_device_name(tmp_device)) { TangoSys_OMemStream o; o << "device name (" << tmp_device << ") syntax error (should be [tango:][//instance/]domain/family/member)"; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, o.str(), (const char *)"DataBase::AddServer()"); } device_name_to_dfm(tmp_device, domain, family, member); // first delete the tuple (device,name,count) from the device table sql_query_stream.str(""); sql_query_stream << "DELETE FROM device WHERE server=\"" << tmp_server << "\" AND name=\"" << tmp_device << "\" "; DEBUG_STREAM << "DataBase::AddServer(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_server()",al.get_con_nb()); // then insert the new value for this tuple sql_query_stream.str(""); sql_query_stream << "INSERT INTO device SET name=\"" << tmp_device << "\",domain=\"" << domain << "\",family=\"" << family << "\",member=\"" << member << "\",exported=0,ior=\"nada\",host=\"nada\",server=\"" << tmp_server << "\",pid=0,class=\"" << tmp_class << "\",version=0,started=NULL,stopped=NULL"; DEBUG_STREAM << "DataBase::AddServer(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_server()",al.get_con_nb()); } // Finally, add the admin device string tmp_device("dserver/"); tmp_device = tmp_device + tmp_server; device_name_to_dfm(tmp_device,domain,family,member); sql_query_stream.str(""); sql_query_stream << "DELETE FROM device WHERE server=\"" << tmp_server << "\" AND name=\"" << tmp_device << "\" "; DEBUG_STREAM << "DataBase::AddServer(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_server()",al.get_con_nb()); tmp_class = "DServer"; sql_query_stream.str(""); sql_query_stream << "INSERT INTO device SET name =\"" << tmp_device << "\",domain=\"" << domain << "\",family=\"" << family << "\",member=\"" << member << "\",exported=0,ior=\"nada\",host=\"nada\",server=\"" << tmp_server << "\",pid=0,class=\"" << tmp_class << "\",version=0,started=NULL,stopped=NULL"; DEBUG_STREAM << "DataBase::AddServer(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_add_server()",al.get_con_nb()); } return; /*----- PROTECTED REGION END -----*/ // DataBase::db_add_server } //-------------------------------------------------------- /** * Command DbDeleteAttributeAlias related method * Description: Delete an attribute alias. * * @param argin Attriibute alias name. */ //-------------------------------------------------------- void DataBase::db_delete_attribute_alias(Tango::DevString argin) { DEBUG_STREAM << "DataBase::DbDeleteAttributeAlias() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_attribute_alias) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; // first check to see if this alias exists sql_query_stream << "DELETE FROM attribute_alias WHERE alias=\'" << argin << "\' "; DEBUG_STREAM << "DataBase::db_delete_attribute_alias(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_attribute_alias()"); /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_attribute_alias } //-------------------------------------------------------- /** * Command DbDeleteClassAttribute related method * Description: delete a class attribute and all its properties from database * * @param argin Str[0] = Tango class name * Str[1] = Attribute name */ //-------------------------------------------------------- void DataBase::db_delete_class_attribute(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteClassAttribute() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_class_attribute) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *attribute; string tmp_class; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_delete_class_attribute(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient number of arguments to delete class attribute", (const char *)"DataBase::db_delete_class_attribute()"); } tmp_class = (*argin)[0]; attribute = (*argin)[1]; INFO_STREAM << "DataBase::db_delete_class_attribute(): delete " << tmp_class << " from database" << endl; // then delete class from the property_attribute_class table sql_query_stream << "DELETE FROM property_attribute_class WHERE class LIKE \"" << tmp_class << "\" AND attribute LIKE \"" << attribute << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_attribute(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_attribute()"); return; /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_class_attribute } //-------------------------------------------------------- /** * Command DbDeleteClassAttributeProperty related method * Description: delete class attribute properties from database * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[2] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_class_attribute_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteClassAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_class_attribute_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *attribute, *property; string tmp_class; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 3) { WARN_STREAM << "DataBase::db_delete_class_attribute_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient number of arguments to delete class attribute property", (const char *)"DataBase::db_delete_class_attribute_property()"); } tmp_class = (*argin)[0]; attribute = (*argin)[1]; { AutoLock al("LOCK TABLES property_attribute_class WRITE,property_attribute_class_hist WRITE,class_attribute_history_id WRITE",this); for (unsigned int i=0; ilength()-2; i++) { property = (*argin)[i+2]; INFO_STREAM << "DataBase::db_delete_class_attribute_property(): delete class " << tmp_class ; INFO_STREAM << " attribute " << attribute << " property[" << i <<"] " << property << " from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT count(*) FROM property_attribute_class WHERE class = \"" << tmp_class << "\" AND attribute = \"" << attribute << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_attribute_property(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_delete_class_attribute_property()",al.get_con_nb()); row = mysql_fetch_row(result); int count; stringstream ss; ss << row[0]; ss >> count; mysql_free_result(result); if(count) { // then delete property from the property_attribute_class table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_attribute_class WHERE class = \"" << tmp_class << "\" AND attribute = \"" << attribute << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_attribute_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_attribute_property()",al.get_con_nb()); // Mark this property as deleted Tango::DevULong64 class_attribute_property_hist_id = get_id("class_attribute",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "INSERT INTO property_attribute_class_hist SET class='" << tmp_class \ << "',attribute='" << attribute \ << "',name='" << property \ << "',id='" << class_attribute_property_hist_id \ << "',count='0',value='DELETED'"; DEBUG_STREAM << "DataBase::db_delete_class_attribute_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_attribute_property()",al.get_con_nb()); } purge_att_property("property_attribute_class_hist","class",tmp_class.c_str(),attribute,property,al.get_con_nb()); } } return; /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_class_attribute_property } //-------------------------------------------------------- /** * Command DbDeleteClassProperty related method * Description: Delete class properties from database * * @param argin Str[0] = Tango class name * Str[1] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_class_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteClassProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_class_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_list = argin; TangoSys_MemStream sql_query_stream; int n_properties=0; const char *tmp_class; string tmp_name; MYSQL_RES *result; MYSQL_ROW row; n_properties = property_list->length() - 1; INFO_STREAM << "DataBase::DeleteClassProperty(): delete " << n_properties << " properties for class " << (*property_list)[0] << endl; { AutoLock al("LOCK TABLES property_class WRITE,property_class_hist WRITE,class_history_id WRITE",this); int i,j; for (i=0; ilength() < 2) { WARN_STREAM << "DataBase::db_delete_device_attribute(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient number of arguments to delete device attribute", (const char *)"DataBase::db_delete_device_attribute()"); } tmp_device = (*argin)[0].in(); attribute = (*argin)[1]; INFO_STREAM << "DataBase::db_delete_device(): delete " << tmp_device << " from database" << endl; // first check the device name if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_device_attribute(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, (const char *)"failed to delete device attribute, device name incorrect", (const char *)"DataBase::db_delete_device_attribute()"); } // replace database wildcards (% and _) string tmp_wildcard = replace_wildcard(tmp_device.c_str()); // then delete device from the property_attribute_device table sql_query_stream << "DELETE FROM property_attribute_device WHERE device LIKE \"" << tmp_wildcard << "\" AND attribute LIKE \"" << attribute << "\" "; DEBUG_STREAM << "DataBase::db_delete_device_attribute(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_attribute()"); return; /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_device_attribute } //-------------------------------------------------------- /** * Command DbDeleteDeviceAttributeProperty related method * Description: delete a device attribute property from the database * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[2] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_device_attribute_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteDeviceAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_device_attribute_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *attribute, *property; string tmp_device; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 3) { WARN_STREAM << "DataBase::db_delete_device_attribute_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient number of arguments to delete device attribute property", (const char *)"DataBase::db_delete_device_attribute_property()"); } tmp_device = (*argin)[0]; if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_device_attribute(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, (const char *)"failed to delete device attribute, device name incorrect", (const char *)"DataBase::db_delete_device_attribute()"); } attribute = (*argin)[1]; { AutoLock al("LOCK TABLES property_attribute_device WRITE, property_attribute_device_hist WRITE,device_attribute_history_id WRITE",this); unsigned int i; for (i=0; ilength()-2; i++) { property = (*argin)[i+2]; INFO_STREAM << "DataBase::db_delete_device_attribute_property(): delete device " << tmp_device ; INFO_STREAM << " attribute " << attribute << " property[" << i <<"] " << property << " from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT count(*) FROM property_attribute_device WHERE device = \"" << tmp_device <<"\" AND attribute = \"" << attribute << "\" AND name = \"" << property << "\" "; result = query(sql_query_stream.str(),"db_delete_device_attribute_property()",al.get_con_nb()); row = mysql_fetch_row(result); int count; stringstream ss; ss << row[0]; ss >> count; mysql_free_result(result); if(count) { // then delete property from the property_attribute_device table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_attribute_device WHERE device = \"" << tmp_device <<"\" AND attribute = \"" << attribute << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_device_attribute_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_attribute_property()",al.get_con_nb()); // Mark this property as deleted Tango::DevULong64 device_attribute_property_hist_id = get_id("device_attribute",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "INSERT INTO property_attribute_device_hist SET device='" << tmp_device << "',attribute='" << attribute << "',name='" << property << "',id='" << device_attribute_property_hist_id << "',count='0',value='DELETED'"; DEBUG_STREAM << "DataBase::PutAttributeProperty(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_attribute_property()",al.get_con_nb()); } purge_att_property("property_attribute_device_hist","device",tmp_device.c_str(),attribute,property,al.get_con_nb()); } } return; /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_device_attribute_property } //-------------------------------------------------------- /** * Command DbDeleteDeviceProperty related method * Description: Delete device property(ies) * * @param argin Str[0] = Device name * Str[1] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_device_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteDeviceProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_device_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_list = argin; TangoSys_MemStream sql_query_stream; int n_properties=0; const char *tmp_device; string tmp_name; MYSQL_RES *result; MYSQL_ROW row; TimeVal before, after; GetTime(before); n_properties = property_list->length() - 1; INFO_STREAM << "DataBase::DeleteDeviceProperty(): delete " << n_properties << " properties for device " << (*property_list)[0] << endl; { AutoLock al("LOCK TABLES property_device WRITE, property_device_hist WRITE,device_history_id WRITE",this); int i,j; for (i=0; ilength() - 1; INFO_STREAM << "DataBase::db_delete_property(): put " << n_properties << " properties for device " << (*property_list)[0] << endl; { AutoLock al("LOCK TABLES property WRITE, property_hist WRITE,object_history_id WRITE",this); int i,j; for (i=0; i 0) { for (int loop = 0;loop < n_rows;loop++) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "Database::db_deleet_server(): Deleting device " << row[0] << endl; db_delete_device(row[0]); } } } mysql_free_result(result); // // Update host's starter to update controlled servers list // if (fireToStarter==true) { omni_mutex_lock oml(starter_mutex); vector hosts; if (previous_host!="") { hosts.push_back(previous_host); starter_shared->send_starter_cmd(hosts); } } /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_server } //-------------------------------------------------------- /** * Command DbDeleteServerInfo related method * Description: delete info related to a Tango devvice server process * * @param argin Device server name */ //-------------------------------------------------------- void DataBase::db_delete_server_info(Tango::DevString argin) { DEBUG_STREAM << "DataBase::DbDeleteServerInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_server_info) ENABLED START -----*/ // Add your own code Tango::DevString server_name = argin; TangoSys_MemStream sql_query_stream; INFO_STREAM << "DataBase::db_delete_server_info(): delete " << server_name << " from database" << endl; // replace database wildcards (% and _) // string tmp_wildcard = replace_wildcard(server_name); // then delete the device from the device table sql_query_stream << "DELETE FROM server WHERE name = \"" << server_name << "\""; DEBUG_STREAM << "DataBase::db_delete_server_info(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_server_info()"); /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_server_info } //-------------------------------------------------------- /** * Command DbExportDevice related method * Description: Export a device to the database * * @param argin Str[0] = Device name * Str[1] = CORBA IOR * Str[2] = Device server process host name * Str[3] = Device server process PID or string ``null`` * Str[4] = Device server process version */ //-------------------------------------------------------- void DataBase::db_export_device(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbExportDevice() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_export_device) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *export_info = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_ior, *tmp_host, *tmp_pid, *tmp_version; string tmp_device, tmp_server; TimeVal before, after; GetTime(before); if (export_info->length() < 5) { WARN_STREAM << "DataBase::DbExportDevice(): insufficient export info for device "; WARN_STREAM << tmp_device << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"Insufficient export info for device", (const char *)"DataBase::DbExportDevice()"); } INFO_STREAM << "DataBase::ExportDevice(): put " << export_info->length()-1 << " export info for device " << (*export_info)[0] << endl; tmp_device = (*export_info)[0]; for (unsigned int i=0; i get previous host where running // bool do_fire = false; string previous_host; { AutoLock al("LOCK TABLES device WRITE, server WRITE",this); if (fireToStarter==true) { if (tmp_device.substr(0,8) == "dserver/") { omni_mutex_lock oml(starter_mutex); // Get database server name //-------------------------------------- Tango::Util *tg = Tango::Util::instance(); string db_serv = tg->get_ds_name(); transform(db_serv.begin(), db_serv.end(), db_serv.begin(), ::tolower); string adm_dev("dserver/"); adm_dev += db_serv; // Check if not database or starter servers if (tmp_device != adm_dev && tmp_device.substr(0,16) != "dserver/starter/" ) { do_fire = true; char *tmp_ptr = db_get_device_host((Tango::DevString)tmp_device.c_str(),al.get_con_nb()); previous_host = tmp_ptr; DEBUG_STREAM << tmp_device << " was running on " << previous_host << endl; CORBA::string_free(tmp_ptr); } } } // // check if device is defined and if so get server name in order to // update server table // sql_query_stream << "SELECT server FROM device WHERE name LIKE \"" << tmp_device << "\" "; DEBUG_STREAM << "DataBase::ExportDevice(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_export_device()",al.get_con_nb()); long n_rows=0; n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::ExportDevice(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::ExportDevice(): device "<< tmp_device << " server name " << row[0] << endl; tmp_server = row[0]; } } else { INFO_STREAM << "DataBase::ExportDevice(): device not defined !" << endl; TangoSys_OMemStream o; o << "device " << tmp_device << " not defined in the database !"; mysql_free_result(result); Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::ExportDevice()"); } mysql_free_result(result); // update the new value for this tuple sql_query_stream.str(""); sql_query_stream << "UPDATE device set exported=1,ior=\'" << tmp_ior << "\',host=\'" << tmp_host << "\',pid=\'" << tmp_pid << "\',version=\'" << tmp_version << "\',started=NOW() where name LIKE \'" << tmp_device << "\'"; DEBUG_STREAM << "DataBase::ExportDevice(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_export_device()",al.get_con_nb()); // update host name in server table sql_query_stream.str(""); sql_query_stream << "UPDATE server set host=\'" << tmp_host << "\' where name LIKE \'" << tmp_server << "\'"; DEBUG_STREAM << "DataBase::ExportDevice(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_export_device()",al.get_con_nb()); } // Check if a server has been started. if (do_fire) { // Update host's starter to update controlled servers list vector hosts; hosts.push_back(tmp_host); DEBUG_STREAM << "New Host is " << tmp_host << endl; if (previous_host!="" && previous_host!="nada" && previous_host!=tmp_host) hosts.push_back(previous_host); starter_shared->send_starter_cmd(hosts); } GetTime(after); update_timing_stats(before, after, "DbExportDevice"); return; /*----- PROTECTED REGION END -----*/ // DataBase::db_export_device } //-------------------------------------------------------- /** * Command DbExportEvent related method * Description: Export Event channel to database * * @param argin Str[0] = event channel name (or factory name) * Str[1] = CORBA IOR * Str[2] = Notifd host name * Str[3] = Notifd pid * Str[4] = Notifd version */ //-------------------------------------------------------- void DataBase::db_export_event(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbExportEvent() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_export_event) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *export_info = argin; TangoSys_MemStream sql_query_stream; const char *tmp_ior, *tmp_host, *tmp_pid, *tmp_version; string tmp_event, tmp_server; TimeVal before, after; GetTime(before); if (export_info->length() < 5) { WARN_STREAM << "DataBase::db_export_event(): insufficient export info for event "; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient export info for event", (const char *)"DataBase::db_export_event()"); } INFO_STREAM << "DataBase::db_export_event(): put " << export_info->length()-1 << " export info for event " << (*export_info)[0] << endl; tmp_event = (*export_info)[0]; for (unsigned int i=0; i 0) { if ((row = mysql_fetch_row(result)) != NULL) { argout = CORBA::string_dup(row[0]); } mysql_free_result(result); } else { mysql_free_result(result); TangoSys_OMemStream o; o << "No device found for alias \'" << argin << "\'"; string msg = o.str(); WARN_STREAM << msg << endl; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, msg, (const char *)"DataBase::db_get_alias_device()"); } /*----- PROTECTED REGION END -----*/ // DataBase::db_get_alias_device return argout; } //-------------------------------------------------------- /** * Command DbGetAttributeAlias related method * Description: Get the attribute name for the given alias. * If alias not found in database, returns an empty string. * * @param argin The attribute alias name * @returns The attribute name (device/attribute) */ //-------------------------------------------------------- Tango::DevString DataBase::db_get_attribute_alias(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "DataBase::DbGetAttributeAlias() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_attribute_alias) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; long n_rows=0; argout = new char[256]; INFO_STREAM << "DataBase::db_get_attribute_alias(): put " << argin << endl; // first check to see if this alias exists sql_query_stream << "SELECT name from attribute_alias WHERE alias LIKE \'" << argin << "\' "; DEBUG_STREAM << "DataBase::db_get_attribute_alias(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_attribute_alias()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_attribute_alias(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_get_attribute_alias(): attribute name "<< row[0] << endl; strcpy(argout,row[0]); } } else { //strcpy(argout,""); TangoSys_OMemStream o; o << "No attribute found for alias \'" << argin << "\'"; mysql_free_result(result); delete [] argout; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_get_attribute_alias()"); } // Add your own code to control device here mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_attribute_alias return argout; } //-------------------------------------------------------- /** * Command DbGetAttributeAliasList related method * Description: Get attribute alias list for a specified filter * * @param argin attribute alias filter string (eg: att*) * @returns attribute aliases */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_attribute_alias_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetAttributeAliasList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_attribute_alias_list) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; INFO_STREAM << "DataBase::db_get_attribute_alias_list(): alias " << argin; WARN_STREAM << " wildcard " << argin << endl; if (argin == NULL) { sql_query_stream << "SELECT DISTINCT alias,attribute FROM attribute_alias WHERE alias LIKE \"%\" ORDER BY attribute"; } else { tmp_wildcard = replace_wildcard (argin); sql_query_stream << "SELECT DISTINCT alias,attribute FROM attribute_alias WHERE alias LIKE \"" << tmp_wildcard << "\" ORDER BY attribute"; } DEBUG_STREAM << "DataBase::db_get_attribute_alias_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_attribute_alias_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_attribute_alias_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_attribute_alias_list return argout; } //-------------------------------------------------------- /** * Command DbGetClassAttributeList related method * Description: Get attrilute list for a given Tango class with a specified filter * * @param argin Str[0] = Tango class name * Str[1] = Attribute name filter (eg: att*) * @returns Str[0] = Class attribute name * Str[n] = Class attribute name */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_attribute_list(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassAttributeList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_attribute_list) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *class_wildcard = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0; argout = new Tango::DevVarStringArray; const char *class_name, *wildcard; string tmp_wildcard; class_name = (*class_wildcard)[0]; INFO_STREAM << "DataBase::db_get_class_attribute(): get attributes for class " << class_name << endl; wildcard = (*class_wildcard)[1]; if (wildcard == NULL) { #ifdef WIN32 sql_query_stream << "SELECT DISTINCT attribute FROM property_attribute_class WHERE class = \"" << class_name << "\" AND attribute like \"\\%\""; #else sql_query_stream << "SELECT DISTINCT attribute FROM property_attribute_class WHERE class = \"" << class_name << "\" AND attribute like \"%%\""; #endif /* WIN32 */ } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT attribute FROM property_attribute_class WHERE class = \"" << class_name << "\" AND attribute like \"" << tmp_wildcard << "\""; } DEBUG_STREAM << "DataBase::GetClassAttributeList(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_attribute_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetClassAttributeList(): num_rows() " << n_rows << endl; if (n_rows > 0) { int n_attrs=0; for (int j=0; jlength(n_attrs); (*argout)[n_attrs-1] = CORBA::string_dup(row[0]); } } } mysql_free_result(result); DEBUG_STREAM << "DataBase::GetClassAttributeList(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_attribute_list return argout; } //-------------------------------------------------------- /** * Command DbGetClassAttributeProperty related method * Description: Get Tango class property(ies) value * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Tango class name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_attribute_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_attribute_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_attributes_str[256]; char n_rows_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_class, *tmp_attribute; INFO_STREAM << "DataBase::GetAttributeProperty(): get " << property_names->length()-1 << " attributes for class " << (*property_names)[0] << endl; tmp_class = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_attributes_str, "%lu", property_names->length()-1); #else sprintf(n_attributes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_class); (*argout)[n_props-1] = CORBA::string_dup(n_attributes_str); for (unsigned int i=1; ilength(); i++) { tmp_attribute = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_attribute_class WHERE class = \"" << tmp_class << "\" AND attribute LIKE \"" << tmp_attribute << "\" "; DEBUG_STREAM << "DataBase::GetAttributeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_attribute_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetAttributeProperty(): mysql_num_rows() " << n_rows << endl; sprintf(n_rows_str,"%d",n_rows); n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_attribute); (*argout)[n_props-1] = CORBA::string_dup(n_rows_str); if (n_rows > 0) { for (int j=0; jlength(n_props); (*argout)[n_props-2] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); } } } mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetClassProperty(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_attribute_property return argout; } //-------------------------------------------------------- /** * Command DbGetClassAttributeProperty2 related method * Description: This command supports array property compared to the old command called * DbGetClassAttributeProperty. The old command has not been deleted from the * server for compatibility reasons. * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Tango class name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value number (array case) * Str[4] = Attribute property 1 value * Str[n] = Attribute property 1 value (array case) * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value number (array case) * Str[n + 3] = Attribute property 2 value * Str[n + m] = Attribute property 2 value (array case) */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_attribute_property2(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassAttributeProperty2() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_attribute_property2) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; // POGO has generated a method core with argout allocation. // If you would like to use a static reference without copying, // See "TANGO Device Server Programmer's Manual" // (chapter : Writing a TANGO DS / Exchanging data) //------------------------------------------------------------ DEBUG_STREAM << "DataBase::db_get_class_attribute_property2(): entering... !" << endl; // Add your own code to control device here TangoSys_MemStream sql_query_stream; char n_attributes_str[256]; char n_rows_str[256]; char prop_size_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_class, *tmp_attribute; INFO_STREAM << "DataBase::GetClassAttributeProperty2(): get " << property_names->length()-1 << " properties for device " << (*property_names)[0] << endl; tmp_class = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_attributes_str, "%lu", property_names->length()-1); #else sprintf(n_attributes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_class); (*argout)[n_props-1] = CORBA::string_dup(n_attributes_str); for (unsigned int i=1; ilength(); i++) { tmp_attribute = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_attribute_class WHERE class = \"" << tmp_class << "\" AND attribute LIKE \"" << tmp_attribute << "\" ORDER BY name,count"; DEBUG_STREAM << "DataBase::GetClassAttributeProperty2(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_attribute_property2()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetClassAttributeProperty2(): mysql_num_rows() " << n_rows << endl; n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_attribute); int prop_number_idx = n_props-1; int prop_number = 0; if (n_rows > 0) { string name, old_name; bool new_prop = true; int prop_size_idx = 0; int prop_size = 0; for (int j=0; jlength(n_props); (*argout)[n_props-3] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } prop_size_idx = n_props - 2; prop_size = 1; } else { n_props = n_props + 1; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); prop_size++; } } } if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } } sprintf(n_rows_str,"%d",prop_number); (*argout)[prop_number_idx] = CORBA::string_dup(n_rows_str); mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetClassAttributeProperty2(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_attribute_property2 return argout; } //-------------------------------------------------------- /** * Command DbGetClassAttributePropertyHist related method * Description: Retrieve Tango class attribute property history * * @param argin Str[0] = Tango class * Str[1] = Attribute name * Str[2] = Property name * @returns Str[0] = Attribute name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_attribute_property_hist(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassAttributePropertyHist() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_attribute_property_hist) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *ids; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_class; string tmp_attribute; string tmp_name; if (argin->length() != 3) { WARN_STREAM << "DataBase::DbGetClassAttributePropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 3 (class,attribute,property)", (const char *)"DataBase::DbGetClassAttributePropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_class = (*argin)[0]; tmp_attribute = replace_wildcard((*argin)[1]); tmp_name = replace_wildcard((*argin)[2]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_attribute_class_hist WHERE class = \"" << tmp_class << "\" AND attribute LIKE \"" << tmp_attribute << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_attribute_class_hist READ",this); ids = query(sql_query_stream.str(),"db_get_class_attribute_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,attribute,name,count FROM property_attribute_class_hist WHERE id = \"" << id << "\" AND class = \"" << tmp_class << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_class_attribute_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[4]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+4+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[3]); (*argout)[nb_item+2] = CORBA::string_dup(row[0]); (*argout)[nb_item+3] = CORBA::string_dup(n_rows_str); for(int j=0;j 0) for (int i=0; ilength(2); (*array)[0] = CORBA::string_dup(classname.c_str()); (*array)[1] = CORBA::string_dup("InheritedFrom"); Tango::DevVarStringArray *props = db_get_class_property(array); // Put in argout argout = new Tango::DevVarStringArray(); argout->length(props->length()-3); (*argout)[0] = CORBA::string_dup(classname.c_str()); for (unsigned int i=4 ; ilength() ; i++) (*argout)[i-3] = CORBA::string_dup((*props)[i]); delete array; delete props; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_inheritance_for_device return argout; } //-------------------------------------------------------- /** * Command DbGetClassList related method * Description: Get Tango class list with a specified filter * * @param argin Filter * @returns Class list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_list) ENABLED START -----*/ // Add your own code Tango::DevString server = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows; string tmp_server; INFO_STREAM << "DataBase::db_get_class_list(): server " << server << endl; tmp_server = replace_wildcard(server); sql_query_stream << "SELECT DISTINCT class FROM device WHERE class LIKE \"" << tmp_server << "\" ORDER BY class"; DEBUG_STREAM << "DataBase::db_get_class_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_class_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_list return argout; } //-------------------------------------------------------- /** * Command DbGetClassProperty related method * Description: * * @param argin Str[0] = Tango class * Str[1] = Property name * Str[2] = Property name * @returns Str[0] = Tango class * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value * Str[n] = Propery value (array case) * .... */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_properties_str[256]; char n_rows_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_class, *tmp_name; INFO_STREAM << "DataBase::GetClassProperty(): get " << property_names->length()-1 << " properties for device " << (*property_names)[0] << endl; tmp_class = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_properties_str, "%lu", property_names->length()-1); #else sprintf(n_properties_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[0] = CORBA::string_dup(tmp_class); (*argout)[1] = CORBA::string_dup(n_properties_str); for (unsigned int i=1; ilength(); i++) { tmp_name = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT count,value FROM property_class WHERE class = \"" << tmp_class << "\" AND name LIKE \"" << tmp_name << "\" ORDER BY count"; DEBUG_STREAM << "DataBase::GetClassProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetClassProperty(): mysql_num_rows() " << n_rows << endl; sprintf(n_rows_str,"%d",n_rows); n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_name); (*argout)[n_props-1] = CORBA::string_dup(n_rows_str); if (n_rows > 0) { for (int j=0; jlength(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); } } } mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetClassProperty(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_property return argout; } //-------------------------------------------------------- /** * Command DbGetClassPropertyHist related method * Description: Retrieve Tango class property history * * @param argin Str[0] = Tango class * Str[1] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_property_hist(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassPropertyHist() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_property_hist) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *ids; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_class; string tmp_name; if (argin->length() != 2) { WARN_STREAM << "DataBase::DbGetClassPropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 2 (class,property)", (const char *)"DataBase::DbGetClassPropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_class = (*argin)[0]; tmp_name = replace_wildcard((*argin)[1]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_class_hist WHERE class = \"" << tmp_class << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_class_hist READ",this); ids = query(sql_query_stream.str(),"db_get_class_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,name,count FROM property_class_hist WHERE id = \"" << id << "\" AND class = \"" << tmp_class << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_class_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[3]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+3+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[0]); (*argout)[nb_item+2] = CORBA::string_dup(n_rows_str); for(int j=0;j 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetClassPropertyList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_property_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAlias related method * Description: Return alias for device name if found. * * @param argin The device name * @returns The alias found */ //-------------------------------------------------------- Tango::DevString DataBase::db_get_device_alias(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "DataBase::DbGetDeviceAlias() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_alias) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; string devname(argin); string tmp_devname; MYSQL_RES *result; MYSQL_ROW row; int n_rows; argout = NULL; INFO_STREAM << "DataBase::db_get_device_alias(): devname " << devname << endl; if (!check_device_name(devname)) { WARN_STREAM << "DataBase::db_get_device_alias(): device name " << devname << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, (const char *)"failed to find alias, device name incorrect", (const char *)"DataBase::db_get_device_alias()"); } tmp_devname = replace_wildcard(devname.c_str()); sql_query_stream << "SELECT DISTINCT alias FROM device WHERE name LIKE \"" << tmp_devname << "\" ORDER BY alias"; DEBUG_STREAM << "DataBase::db_get_device_alias(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_alias()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_alias_(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { if (row[0]==NULL) { mysql_free_result(result); TangoSys_OMemStream o; o << "No alias found for device \'" << devname << "\'"; string msg = o.str(); WARN_STREAM << msg << endl; Tango::Except::throw_exception((const char *)DB_AliasNotDefined, msg, (const char *)"DataBase::db_get_device_alias()"); } else argout = CORBA::string_dup(row[0]); } } else { mysql_free_result(result); TangoSys_OMemStream o; o << "No alias found for device \'" << devname << "\'"; string msg = o.str(); WARN_STREAM << msg << endl; Tango::Except::throw_exception((const char *)DB_AliasNotDefined, msg, (const char *)"DataBase::db_get_device_alias()"); } mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_alias return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAliasList related method * Description: Get device alias name with a specific filter * * @param argin The filter * @returns Device alias list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_alias_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceAliasList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_alias_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; INFO_STREAM << "DataBase::db_get_device_alias_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT alias FROM device WHERE alias LIKE \"%\" ORDER BY alias"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT alias FROM device WHERE alias LIKE \"" << tmp_wildcard << "\" ORDER BY alias"; } DEBUG_STREAM << "DataBase::db_get_device_alias_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_alias_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_alias_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_alias_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAttributeList related method * Description: Return list of attributes matching the wildcard * for the specified device * * @param argin Str[0] = Device name * Str[1] = Wildcard * @returns attribute name list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_attribute_list(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceAttributeList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_attribute_list) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *device_wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; const char *device, *wildcard; device = (*device_wildcard)[0]; wildcard = (*device_wildcard)[1]; INFO_STREAM << "DataBase::db_get_device_attribute_list(): device " << device; WARN_STREAM << " wildcard " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT attribute FROM property_attribute_device WHERE device=\"" << device << "\" AND attribute LIKE \"%\" ORDER BY attribute"; } else { tmp_wildcard = replace_wildcard (wildcard); sql_query_stream << "SELECT DISTINCT attribute FROM property_attribute_device WHERE device=\"" << device << "\" AND attribute LIKE \"" << tmp_wildcard << "\" ORDER BY attribute"; } DEBUG_STREAM << "DataBase::db_get_device_attrribute_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_attribute_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_attribute_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_attribute_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAttributeProperty related method * Description: Get device attribute property(ies) value * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Device name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_attribute_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_attribute_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_attributes_str[256]; char n_rows_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_device, *tmp_attribute; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::GetAttributeProperty(): get " << property_names->length()-1 << " properties for device " << (*property_names)[0] << endl; tmp_device = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_attributes_str, "%lu", property_names->length()-1); #else sprintf(n_attributes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_device); (*argout)[n_props-1] = CORBA::string_dup(n_attributes_str); for (unsigned int i=1; ilength(); i++) { tmp_attribute = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_attribute_device WHERE device = \"" << tmp_device << "\" AND attribute LIKE \"" << tmp_attribute << "\" "; DEBUG_STREAM << "DataBase::GetAttributeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_attribute_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetAttributeProperty(): mysql_num_rows() " << n_rows << endl; sprintf(n_rows_str,"%d",n_rows); n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_attribute); (*argout)[n_props-1] = CORBA::string_dup(n_rows_str); if (n_rows > 0) { for (int j=0; jlength(n_props); (*argout)[n_props-2] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); } } } mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetDeviceProperty(): argout->length() "<< argout->length() << endl; GetTime(after); update_timing_stats(before, after, "DbGetDeviceAttributeProperty"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_attribute_property return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAttributeProperty2 related method * Description: Retrieve device attribute properties. This command has the possibility to retrieve * device attribute properties which are arrays. It is not possible with the old * DbGetDeviceAttributeProperty command. Nevertheless, the old command has not been * deleted for compatibility reason * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Device name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value number (array case) * Str[4] = Attribute property 1 value * Str[n] = Attribute property 1 value (array case) * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value number (array case) * Str[n + 3] = Attribute property 2 value * Str[n + m] = Attribute property 2 value (array case) */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_attribute_property2(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceAttributeProperty2() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_attribute_property2) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_attributes_str[256]; char n_rows_str[256]; char prop_size_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_device, *tmp_attribute; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::GetDeviceAttributeProperty2(): get " << property_names->length()-1 << " properties for device " << (*property_names)[0] << endl; tmp_device = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_attributes_str, "%lu", property_names->length()-1); #else sprintf(n_attributes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_device); (*argout)[n_props-1] = CORBA::string_dup(n_attributes_str); // // First, get how many attributes belonging to the device have // properties defined in the db // bool all_attr = false; sql_query_stream << "SELECT COUNT(DISTINCT attribute) FROM property_attribute_device WHERE device = \"" << tmp_device << "\""; DEBUG_STREAM << "Database::GetDeviceAttributeProperty2(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_attribute_property2()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): mysql_num_rows() " << n_rows << endl; if (n_rows != 0) { if ((row = mysql_fetch_row(result)) != NULL) { stringstream tmp_str; string nb_attr_str = row[0]; tmp_str << nb_attr_str; unsigned int nb_attr = 0; tmp_str >> nb_attr; if (property_names->length()-1 >= nb_attr) all_attr = true; mysql_free_result(result); } } if (all_attr == true) { DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): Get attribute properties for all attribute(s)" << endl; } if (all_attr == false) { for (unsigned int i=1; ilength(); i++) { tmp_attribute = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_attribute_device WHERE device = \"" << tmp_device << "\" AND attribute LIKE \"" << tmp_attribute << "\" ORDER BY name,count"; DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_attribute_property2()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): mysql_num_rows() " << n_rows << endl; n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_attribute); int prop_number_idx = n_props-1; int prop_number = 0; if (n_rows > 0) { string name, old_name; bool new_prop = true; int prop_size_idx = 0; int prop_size = 0; for (int j=0; jlength(n_props); (*argout)[n_props-3] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } prop_size_idx = n_props - 2; prop_size = 1; } else { n_props = n_props + 1; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); prop_size++; } } } if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } } sprintf(n_rows_str,"%d",prop_number); (*argout)[prop_number_idx] = CORBA::string_dup(n_rows_str); mysql_free_result(result); } } else { sql_query_stream.str(""); sql_query_stream << "SELECT attribute,name,value FROM property_attribute_device WHERE device = \"" << tmp_device << "\" ORDER BY attribute,name,count"; DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_attribute_property2()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): mysql_num_rows() " << n_rows << endl; map > db_data; string att,prev_att; string p_name,prev_p_name; string value; PropDef prop; vector att_props; // // Create a map with data coming from db // for (int j = 0;j < n_rows;j++) { if ((row = mysql_fetch_row(result)) != NULL) { att = row[0]; transform(att.begin(),att.end(),att.begin(),::tolower); if (att != prev_att) { if (j != 0) { att_props.push_back(prop); db_data.insert(make_pair(prev_att,att_props)); prop.prop_val.clear(); att_props.clear(); } p_name = row[1]; prop.prop_name_cd = p_name; transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); prop.prop_name = p_name; value = row[2]; prop.prop_val.push_back(value); prev_p_name = p_name; prev_att = att; } else { p_name = row[1]; transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); if (p_name != prev_p_name) { att_props.push_back(prop); prop.prop_val.clear(); prop.prop_name = p_name; prop.prop_name_cd = row[1]; value = row[2]; prop.prop_val.push_back(value); prev_p_name = p_name; } else { value = row[2]; prop.prop_val.push_back(value); } } } } mysql_free_result(result); if (n_rows != 0) { att_props.push_back(prop); db_data.insert(make_pair(att,att_props)); } // // Initialized data returned to caller // for (unsigned int i=1; ilength(); i++) { string tmp_attribute((*property_names)[i]); string tmp_att_lower(tmp_attribute); transform(tmp_att_lower.begin(),tmp_att_lower.end(),tmp_att_lower.begin(),::tolower); map >::iterator pos = db_data.find(tmp_att_lower); // // Data for this attribute in map? // if (pos == db_data.end()) { n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_attribute.c_str()); (*argout)[n_props-1] = CORBA::string_dup("0"); } else { int prop_nb = pos->second.size(); n_props = n_props + 2; argout->length(n_props); (*argout)[n_props - 2] = CORBA::string_dup(tmp_attribute.c_str()); sprintf(n_rows_str,"%d",prop_nb); (*argout)[n_props - 1] = CORBA::string_dup(n_rows_str); for (int i = 0;i < prop_nb;i++) { PropDef &pd = (pos->second)[i]; int prop_size = pd.prop_val.size(); int old_n_props = n_props; n_props = n_props + 2 + prop_size; argout->length(n_props); (*argout)[old_n_props++] = CORBA::string_dup(pd.prop_name_cd.c_str()); sprintf(n_rows_str,"%d",prop_size); (*argout)[old_n_props++] = CORBA::string_dup(n_rows_str); for (int j = 0;j < prop_size;j++) { (*argout)[old_n_props++] = CORBA::string_dup(pd.prop_val[j].c_str()); } } } } } DEBUG_STREAM << "DataBase::GetDeviceAttributeProperty2(): argout->length() "<< argout->length() << endl; GetTime(after); update_timing_stats(before, after, "DbGetDeviceAttributeProperty2"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_attribute_property2 return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceAttributePropertyHist related method * Description: Retrieve device attribute property history * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[2] = Property name * @returns Str[0] = Attribute name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_attribute_property_hist(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceAttributePropertyHist() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_attribute_property_hist) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *ids; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_device; string tmp_attribute; string tmp_name; if (argin->length() != 3) { WARN_STREAM << "DataBase::DbGetDeviceAttributePropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 3 (device,attribute,property)", (const char *)"DataBase::DbGetDeviceAttributePropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_device = (*argin)[0]; tmp_attribute = replace_wildcard((*argin)[1]); tmp_name = replace_wildcard((*argin)[2]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_attribute_device_hist WHERE device = \"" << tmp_device << "\" AND attribute LIKE \"" << tmp_attribute << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_attribute_device_hist READ",this); ids = query(sql_query_stream.str(),"db_get_device_attribute_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,attribute,name,count FROM property_attribute_device_hist WHERE id = \"" << id << "\" AND device = \"" << tmp_device << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_device_attribute_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[4]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+4+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[3]); (*argout)[nb_item+2] = CORBA::string_dup(row[0]); (*argout)[nb_item+3] = CORBA::string_dup(n_rows_str); for(int j=0;j 0) { argout->length(n_rows*2); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDeviceClassList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_class_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceDomainList related method * Description: Get list of device domain name matching the specified * * @param argin The wildcard * @returns Device name domain list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_domain_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceDomainList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_domain_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_device_domain_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT domain FROM device WHERE name LIKE \"%\" ORDER BY domain"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT domain FROM device WHERE name LIKE \"" << tmp_wildcard << "\" OR alias LIKE \"" << tmp_wildcard << "\" ORDER BY domain"; } DEBUG_STREAM << "DataBase::db_get_device_domain_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_domain_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_domain_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDeviceDomainList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_domain_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceExportedList related method * Description: Get a list of exported devices whose names satisfy the filter (wildcard is * * @param argin filter * @returns list of exported devices */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_exported_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceExportedList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_exported_list) ENABLED START -----*/ // Add your own code Tango::DevString filter = argin; TangoSys_MemStream sql_query_stream; string tmp_filter; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_device_exported_list(): filter " << filter << endl; if (filter == NULL) { sql_query_stream << "SELECT DISTINCT name FROM device WHERE name LIKE \"%\" AND exported=1 ORDER BY name"; } else { tmp_filter = replace_wildcard(filter); sql_query_stream << "SELECT DISTINCT name FROM device WHERE (name LIKE \"" << tmp_filter << "\" OR alias LIKE \"" << tmp_filter << "\") AND exported=1 ORDER BY name"; } DEBUG_STREAM << "DataBase::db_get_device_exported_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_exported_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_exported_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDeviceExportedList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_exported_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceFamilyList related method * Description: Get a list of device name families for device name matching the * specified wildcard * * @param argin The wildcard * @returns Family list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_family_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceFamilyList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_family_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_device_family_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT family FROM device WHERE name LIKE \"%\" ORDER BY family"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT family FROM device WHERE name LIKE \"" << tmp_wildcard << "\" OR alias LIKE \"" << tmp_wildcard << "\" ORDER BY family"; } DEBUG_STREAM << "DataBase::db_get_device_family_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_family_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_family_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDeviceFamilyList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_family_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceInfo related method * Description: Returns info from DbImportDevice and started/stopped dates. * * @param argin Device name * @returns Str[0] = Device name * Str[1] = CORBA IOR * Str[2] = Device version * Str[3] = Device Server name * Str[4] = Device Server process host name * Str[5] = Started date (or ? if not set) * Str[6] = Stopped date (or ? if not set) * Str[7] = Device class * * Lg[0] = Device exported flag * Lg[1] = Device Server process PID (or -1 if not set) */ //-------------------------------------------------------- Tango::DevVarLongStringArray *DataBase::db_get_device_info(Tango::DevString argin) { Tango::DevVarLongStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_info) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0; int exported, pid; string tmp_device; INFO_STREAM << "DataBase::ImportDevice(): get import info for " << argin << " device " << endl; tmp_device = argin; for (unsigned int i=0; i 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::ImportDeviceList(): exported " << row[0] << " version " << row[2] << " server " << row[4] << " host " << row[5] << endl; int n_svalues=0, n_lvalues=0; n_svalues = 8; if ((row[4] == NULL) || (row[5] == NULL)) { TangoSys_OMemStream o; o << "Wrong info in database for device " << tmp_device; o << "Database entry seems corrupted (server or host column NULL)" << ends; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::GetDeviceInfo()"); } (argout->svalue).length(n_svalues); (argout->svalue)[0] = CORBA::string_dup(tmp_device.c_str()); (argout->svalue)[2] = CORBA::string_dup(row[2]); (argout->svalue)[3] = CORBA::string_dup(row[4]); (argout->svalue)[4] = CORBA::string_dup(row[5]); (argout->svalue)[7] = CORBA::string_dup(row[8]); // IOR Check if (row[1]!=NULL) (argout->svalue)[1] = CORBA::string_dup(row[1]); else (argout->svalue)[1] = CORBA::string_dup(""); // Convert date format char *format = (char *)"%D %M %Y at %H:%i:%s"; MYSQL_RES *result2; MYSQL_ROW row2; for (int x=0 ; x<2 ; x++) { if (row[x+6]!=NULL) { sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(\'" << row[x+6] << "\',\'" << format << "\')"; result2 = query(sql_query_stream.str(),"db_get_device_info()"); int nb = mysql_num_rows(result2); if (nb > 0) { if ((row2 = mysql_fetch_row(result2)) != NULL && row2[0] != NULL) //add extra check for MySQL 5 (argout->svalue)[5+x] = CORBA::string_dup(row2[0]); else (argout->svalue)[5+x] = CORBA::string_dup("?"); // empty date-> row2[0]==NULL !!! } else (argout->svalue)[5+x] = CORBA::string_dup("?"); mysql_free_result(result2); } else (argout->svalue)[5+x] = CORBA::string_dup("?"); } exported = -1; if (row[0] != NULL) sscanf(row[0],"%6d",&exported); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = exported; pid = -1; if (row[3] != NULL) sscanf(row[3],"%6d",&pid); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = pid; } else { INFO_STREAM << "DataBase::ImportDevice(): info not defined !" << endl; TangoSys_OMemStream o; o << "device " << tmp_device << " import info not found in the database !"; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::GetDeviceInfo()"); } } else { INFO_STREAM << "DataBase::ImportDevice(): device not defined !" << endl; TangoSys_OMemStream o; o << "device " << tmp_device << " not defined in the database !"; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::GetDeviceInfo()"); } mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_info return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceList related method * Description: Get a list of devices for specified server and class. * * @param argin argin[0] : server name * argin[1] : class name * @returns The list of devices for specified server and class. */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_list(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_list) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *server_class = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows; string tmp_server; string tmp_class; if (server_class->length() != 2) { WARN_STREAM << "DataBase::db_get_device_list(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 2 (server,class)", (const char *)"DataBase::GetDeviceList()"); } tmp_server = replace_wildcard((*server_class)[0]); tmp_class = replace_wildcard((*server_class)[1]); INFO_STREAM << "DataBase::GetClassList(): server " << tmp_server << endl; sql_query_stream << "SELECT DISTINCT name FROM device WHERE server LIKE \"" << tmp_server << "\" AND class LIKE \"" << tmp_class << "\" ORDER BY name"; DEBUG_STREAM << "DataBase::GetDeviceList(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDeviceList(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceWideList related method * Description: Get a list of devices whose names satisfy the filter. * * @param argin filter * @returns list of exported devices */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_wide_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceWideList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_wide_list) ENABLED START -----*/ // Add your own code Tango::DevString filter = argin; TangoSys_MemStream sql_query_stream; string tmp_filter; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_device_wide_list(): filter " << filter << endl; if (filter == NULL) { sql_query_stream << "SELECT DISTINCT name FROM device WHERE name LIKE \"%\" ORDER BY name"; } else { tmp_filter = replace_wildcard(filter); sql_query_stream << "SELECT DISTINCT name FROM device WHERE name LIKE \"" << tmp_filter << "\" ORDER BY name"; } DEBUG_STREAM << "DataBase::db_get_device_wide_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_wide_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_wide_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_wide_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceMemberList related method * Description: Get a list of device name members for device name matching the * specified filter * * @param argin The filter * @returns Device names member list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_member_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceMemberList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_member_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_device_member_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT member FROM device WHERE name LIKE \"%\" ORDER BY member"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT member FROM device WHERE name LIKE \"" << tmp_wildcard << "\" OR alias LIKE \"" << tmp_wildcard << "\" ORDER BY member"; } DEBUG_STREAM << "DataBase::db_get_device_member_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_member_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_member_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDeviceMemberList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_member_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceProperty related method * Description: * * @param argin Str[0] = Device name * Str[1] = Property name * Str[n] = Property name * @returns Str[0] = Device name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n (array case) * Str[n + 1] = Property name * Str[n + 2] = Property value number (array case) * Str[n + 3] = Property value 1 * Str[n + m] = Property value m */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_properties_str[256]; char n_rows_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; const char *tmp_device; string tmp_name; string prop_name; TimeVal before, after; GetTime(before); if (property_names->length() < 2) { WARN_STREAM << "DataBase::GetDeviceProperty(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs at least 2 (device,property)", (const char *)"DataBase::GetDeviceProperty()"); } INFO_STREAM << "DataBase::GetDeviceProperty(): get " << property_names->length()-1 << " properties for device " << (*property_names)[0] << endl; argout = new Tango::DevVarStringArray; tmp_device = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_properties_str, "%lu", property_names->length()-1); #else sprintf(n_properties_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[0] = CORBA::string_dup(tmp_device); (*argout)[1] = CORBA::string_dup(n_properties_str); for (unsigned int i=1; ilength(); i++) { prop_name = (*property_names)[i]; tmp_name = replace_wildcard((*property_names)[i]); sql_query_stream.str(""); sql_query_stream << "SELECT count,value,name FROM property_device WHERE device = \"" << tmp_device << "\" AND name LIKE \"" << tmp_name << "\" ORDER BY count"; DEBUG_STREAM << "DataBase::GetDeviceProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDeviceProperty(): mysql_num_rows() " << n_rows << endl; sprintf(n_rows_str,"%d",n_rows); n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(prop_name.c_str()); (*argout)[n_props-1] = CORBA::string_dup(n_rows_str); if (n_rows > 0) { for (int j=0; jlength(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); } } } else { n_props++; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(" "); } mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetDeviceProperty(): argout->length() "<< argout->length() << endl; GetTime(after); update_timing_stats(before, after, "DbGetDeviceProperty"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_property return argout; } //-------------------------------------------------------- /** * Command DbGetDevicePropertyHist related method * Description: Retrieve device property history * * @param argin Str[0] = Device name * Str[2] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_property_hist(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDevicePropertyHist() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_property_hist) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *ids; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_device; string tmp_name; if (argin->length() != 2) { WARN_STREAM << "DataBase::GetDevicePropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 2 (device,property)", (const char *)"DataBase::GetDevicePropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_device = (*argin)[0]; tmp_name = replace_wildcard((*argin)[1]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_device_hist WHERE device = \"" << tmp_device << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_device_hist READ",this); ids = query(sql_query_stream.str(),"db_get_device_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,name,count FROM property_device_hist WHERE id = \"" << id << "\" AND device = \"" << tmp_device << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_device_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[3]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+3+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[0]); (*argout)[nb_item+2] = CORBA::string_dup(n_rows_str); for(int j=0;j 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetDevicePropertyList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_property_list return argout; } //-------------------------------------------------------- /** * Command DbGetDeviceServerClassList related method * Description: Get list of Tango classes for a device server * * @param argin device server process name * @returns list of classes for this device server */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_server_class_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDeviceServerClassList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_server_class_list) ENABLED START -----*/ // Add your own code Tango::DevString server = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows; string tmp_server; INFO_STREAM << "DataBase::db_get_device_server_class_list(): server " << server << endl; tmp_server = replace_wildcard(server); sql_query_stream << "SELECT DISTINCT class FROM device WHERE server LIKE \"" << tmp_server << "\" ORDER BY class"; DEBUG_STREAM << "DataBase::db_get_device_server_class_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_server_class_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_server_class_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_server_class_list return argout; } //-------------------------------------------------------- /** * Command DbGetExportdDeviceListForClass related method * Description: Query the database for device exported for the specified class. * * @param argin Class name * @returns Device exported list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_exportd_device_list_for_class(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetExportdDeviceListForClass() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_exportd_device_list_for_class) ENABLED START -----*/ // Add your own code Tango::DevString classname = argin; TangoSys_MemStream sql_query_stream; string tmp_classname; MYSQL_RES *result; MYSQL_ROW row; int n_rows; INFO_STREAM << "DataBase::db_get_device_exported_list(): classname " << classname << endl; if (classname == NULL) { sql_query_stream << "SELECT DISTINCT name FROM device WHERE class LIKE \"%\" AND exported=1 ORDER BY name"; } else { tmp_classname = replace_wildcard(classname); sql_query_stream << "SELECT DISTINCT name FROM device WHERE class LIKE \"" << tmp_classname << "\" AND exported=1 ORDER BY name"; } DEBUG_STREAM << "DataBase::db_get_device_exported_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_exportd_device_list_for_class()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_exported_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_exportd_device_list_for_class return argout; } //-------------------------------------------------------- /** * Command DbGetHostList related method * Description: Get host list with name matching the specified filter * * @param argin The filter * @returns Host name list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_host_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetHostList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_host_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_host_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT host FROM device WHERE host LIKE \"%\" ORDER BY host"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT host FROM device WHERE host LIKE \"" << tmp_wildcard << "\" ORDER BY host"; } DEBUG_STREAM << "DataBase::db_get_host_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_host_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_host_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetHostList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_host_list return argout; } //-------------------------------------------------------- /** * Command DbGetHostServerList related method * Description: Get list of device server process name running on host with name matching * the specified filter * * @param argin The filter * @returns Device server process name list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_host_server_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetHostServerList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_host_server_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_host_server_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT server FROM device WHERE host LIKE \"%\" ORDER BY server"; } else { tmp_wildcard = replace_wildcard(wildcard); // For compatibility reason between before and after Tang-5.2 // Will check with and without Fully Qualify Domain Name. sql_query_stream << "SELECT DISTINCT server FROM device WHERE (host LIKE \"" << tmp_wildcard << "\" or host LIKE \"" << tmp_wildcard << ".%%\") AND name LIKE \"dserver/%%\" ORDER BY server"; } DEBUG_STREAM << "DataBase::db_get_host_server_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_host_server_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_host_server_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetHostServerList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_host_server_list return argout; } //-------------------------------------------------------- /** * Command DbGetHostServersInfo related method * Description: Get info about all servers running on specified host, name, mode and level * * @param argin Host name * @returns Server info for all servers running on specified host */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_host_servers_info(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetHostServersInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_host_servers_info) ENABLED START -----*/ // Add your own code //- struct timeval t0, t; //- gettimeofday(&t0, NULL); INFO_STREAM << "DataBase::db_get_host_servers_info(): entering... !" << endl; // Get server list Tango::DevVarStringArray *servers = db_get_host_server_list(argin); argout = new Tango::DevVarStringArray(); argout->length(servers->length()*3); int idx = 0; for (unsigned int i=0 ; ilength() ; i++) { // Get info for each server Tango::DevVarStringArray *info = db_get_server_info((*servers)[i]); (*argout)[idx++] = CORBA::string_dup((*servers)[i]);// Server name (*argout)[idx++] = CORBA::string_dup((*info)[2]); // Controlled ? (*argout)[idx++] = CORBA::string_dup((*info)[3]); // Startup level delete info; } delete servers; // Check execution duration //- gettimeofday(&t, NULL); //- WARN_STREAM << argin << "; " << 1000.0*(t.tv_sec - t0.tv_sec) + //- ((double)t.tv_usec - t0.tv_usec) / 1000 << " ms" << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_host_servers_info return argout; } //-------------------------------------------------------- /** * Command DbGetInstanceNameList related method * Description: Returns the instance names found for specified server. * * @param argin Server name * @returns The instance names found for specified server. */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_instance_name_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetInstanceNameList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_instance_name_list) ENABLED START -----*/ // Add your own code // Build a wildcard wing arg in char *wildcard = new char[strlen(argin) + 3]; strcpy(wildcard, argin); strcat(wildcard, "/*"); Tango::DevVarStringArray *server_list = db_get_server_list(wildcard); vector instance_names; for (unsigned int i=0 ; ilength() ; i++) { // Take only server name string str((*server_list)[i]); string::size_type idx; if ((idx=str.find("/"))!= string::npos) { str = str.substr(idx+1); instance_names.push_back(str); } } delete server_list; // copy result vector to arg out. argout = new Tango::DevVarStringArray; argout->length(instance_names.size()); for (unsigned int i = 0 ; i 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_object_list return argout; } //-------------------------------------------------------- /** * Command DbGetProperty related method * Description: Get free object property * * @param argin Str[0] = Object name * Str[1] = Property name * Str[n] = Property name * @returns Str[0] = Object name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n (array case) * Str[n + 1] = Property name * Str[n + 2] = Property value number (array case) * Str[n + 3] = Property value 1 * Str[n + m] = Property value m */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_properties_str[256]; char n_rows_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_object; string tmp_name; INFO_STREAM << "DataBase::db_get_property(): get " << property_names->length()-1 << " properties for object " << (*property_names)[0] << endl; tmp_object = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_properties_str, "%lu", property_names->length()-1); #else sprintf(n_properties_str, "%u", property_names->length()-1); #endif argout->length(2); (*argout)[0] = CORBA::string_dup(tmp_object); (*argout)[1] = CORBA::string_dup(n_properties_str); n_props = 2; for (unsigned int i=1; ilength(); i++) { tmp_name = replace_wildcard((*property_names)[i]); sql_query_stream.str(""); sql_query_stream << "SELECT count,value,name FROM property WHERE object = \"" << tmp_object << "\" AND name LIKE \"" << tmp_name << "\" ORDER BY count"; DEBUG_STREAM << "DataBase::db_get_property(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_property(): mysql_num_rows() " << n_rows << endl; sprintf(n_rows_str,"%d",n_rows); n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup((*property_names)[i]); (*argout)[n_props-1] = CORBA::string_dup(n_rows_str); if (n_rows > 0) { for (int j=0; jlength(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); } } } else { n_props++; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(" "); } mysql_free_result(result); } DEBUG_STREAM << "DataBase::db_get_property(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_property return argout; } //-------------------------------------------------------- /** * Command DbGetPropertyHist related method * Description: Retrieve object property history * * @param argin Str[0] = Object name * Str[2] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_property_hist(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetPropertyHist() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_property_hist) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *ids; MYSQL_RES *result; MYSQL_ROW row; const char *tmp_object; string tmp_name; if (argin->length() != 2) { WARN_STREAM << "DataBase::DbGetPropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 2 (object,property)", (const char *)"DataBase::DbGetPropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_object = (*argin)[0]; tmp_name = replace_wildcard((*argin)[1]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_hist WHERE object = \"" << tmp_object << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date"; { AutoLock al("LOCK TABLE property_hist READ",this); ids = query(sql_query_stream.str(),"db_get_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,name,count FROM property_hist WHERE id = \"" << id << "\" AND object = \"" << tmp_object << "\" ORDER BY count"; result = query(sql_query_stream.str(),"db_get_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[3]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+3+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[0]); (*argout)[nb_item+2] = CORBA::string_dup(n_rows_str); for(int j=0;jlength() != 2) { WARN_STREAM << "DataBase::db_get_property_list(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"incorrect no. of input arguments, needs 2 (object,wildcard)", (const char *)"DataBase::GetPropertyList()"); } object = (*object_wildcard)[0]; wildcard = (*object_wildcard)[1]; INFO_STREAM << "DataBase::db_get_property_list(): object " << object << endl; if (object == NULL) { sql_query_stream << "SELECT DISTINCT name FROM property WHERE object LIKE \"%\" ORDER BY name"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT name FROM property WHERE object LIKE \"" << object << "\" AND name LIKE \"" << tmp_wildcard << "\" ORDER BY name"; } DEBUG_STREAM << "DataBase::db_get_property_list(): sql_query " << sql_query_stream.str() << endl; result = query( sql_query_stream.str() , "db_get_property_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_property_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_property_list return argout; } //-------------------------------------------------------- /** * Command DbGetServerInfo related method * Description: Get info about host, mode and level for specified server * * @param argin server name * @returns server info */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_server_info(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetServerInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_server_info) ENABLED START -----*/ // Add your own code Tango::DevString server_name = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0; argout = new Tango::DevVarStringArray; string tmp_name; INFO_STREAM << "DataBase::db_get_server_info(): server " << server_name << endl; argout->length(4); (*argout)[0] = CORBA::string_dup(server_name); // tmp_name = replace_wildcard(server_name); sql_query_stream << "SELECT host,mode,level FROM server WHERE name = '" << server_name << "';"; DEBUG_STREAM << "DataBase::db_get_server_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_server_info()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_server_info(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_get_server_info(): host "<< row[0] << " mode " << row[1] << " level " << row[2] << endl; (*argout)[1] = CORBA::string_dup(row[0]); (*argout)[2] = CORBA::string_dup(row[1]); (*argout)[3] = CORBA::string_dup(row[2]); } } else { (*argout)[1] = CORBA::string_dup(" "); (*argout)[2] = CORBA::string_dup(" "); (*argout)[3] = CORBA::string_dup(" "); } mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_server_info return argout; } //-------------------------------------------------------- /** * Command DbGetServerList related method * Description: Get list of device server process defined in database * with name matching the specified filter * * @param argin The filter * @returns Device server process name list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_server_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetServerList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_server_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_get_server_list(): wild card " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT server FROM device WHERE server LIKE \"%\" ORDER BY server"; } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT server FROM device WHERE server LIKE \"" << tmp_wildcard << "\" ORDER BY server"; } DEBUG_STREAM << "DataBase::db_get_server_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_server_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_server_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbGetServerList"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_server_list return argout; } //-------------------------------------------------------- /** * Command DbGetServerNameList related method * Description: Returns the list of server names found for the wildcard specified. * It returns only the server executable name without instance name as DbGetServerList. * * @param argin wildcard for server names. * @returns server names found. */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_server_name_list(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetServerNameList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_server_name_list) ENABLED START -----*/ // Add your own code Tango::DevString wildcard = argin; Tango::DevVarStringArray *server_list = db_get_server_list(wildcard); vector server_names; for (unsigned int i = 0 ; ilength() ; i++) { // Take only server name string str((*server_list)[i]); string::size_type idx; if ((idx=str.find("/"))!= string::npos) { str = str.substr(0, idx); // Search if already in vector bool found = false; for(unsigned int j=0 ; jlength(server_names.size()); for (unsigned int i = 0 ; i 0) { if ((row = mysql_fetch_row(result)) != NULL) { int n_svalues=0, n_lvalues=0; DEBUG_STREAM << "DataBase::ImportDevice(): device exported " << row[0] << " version " << row[2] << " server " << row[4] << " host " << row[5] << endl; n_svalues = n_svalues+6; (argout->svalue).length(n_svalues); (argout->svalue)[n_svalues-6] = CORBA::string_dup(tmp_device.c_str()); (argout->svalue)[n_svalues-4] = CORBA::string_dup(row[2]); (argout->svalue)[n_svalues-3] = CORBA::string_dup(row[4]); (argout->svalue)[n_svalues-2] = CORBA::string_dup(row[5]); (argout->svalue)[n_svalues-1] = CORBA::string_dup(row[6]); // IOR Check if (row[1]!=NULL) (argout->svalue)[n_svalues-5] = CORBA::string_dup(row[1]); else (argout->svalue)[n_svalues-5] = CORBA::string_dup(""); exported = -1; if (row[0] != NULL) sscanf(row[0],"%6d",&exported); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = exported; pid = -1; if (row[3] != NULL) sscanf(row[3],"%6d",&pid); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = pid; } else { INFO_STREAM << "DataBase::ImportDevice(" << tmp_device << "): info not defined !" << endl; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, (const char *)"Device import info not found in the database !", (const char *)"DataBase::ImportDevice()"); } } else { INFO_STREAM << "DataBase::ImportDevice(" << tmp_device << "): device not defined !" << endl; TangoSys_OMemStream o; o << "device " << tmp_device << " not defined in the database !"; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::ImportDevice()"); } mysql_free_result(result); /* * calculate elapsed time and update timing variables */ GetTime(after); update_timing_stats(before, after, "DbImportDevice"); /*----- PROTECTED REGION END -----*/ // DataBase::db_import_device return argout; } //-------------------------------------------------------- /** * Command DbImportEvent related method * Description: Get event channel info from database * * @param argin name of event channel or factory * @returns export information e.g. IOR */ //-------------------------------------------------------- Tango::DevVarLongStringArray *DataBase::db_import_event(Tango::DevString argin) { Tango::DevVarLongStringArray *argout; DEBUG_STREAM << "DataBase::DbImportEvent() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_import_event) ENABLED START -----*/ // Add your own code Tango::DevString event_name = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0; int exported, pid; string tmp_event; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_import_event(): get import info for " << event_name << endl; tmp_event = event_name; for (unsigned int i=0; i 0) { if ((row = mysql_fetch_row(result)) != NULL) { int n_svalues=0, n_lvalues=0; DEBUG_STREAM << "DataBase::db_import_event(): device exported " << row[0] << " IOR " << row[1] << " version " << row[2] << endl; n_svalues = n_svalues+4; (argout->svalue).length(n_svalues); (argout->svalue)[n_svalues-4] = CORBA::string_dup(tmp_event.c_str()); (argout->svalue)[n_svalues-3] = CORBA::string_dup(row[1]); (argout->svalue)[n_svalues-2] = CORBA::string_dup(row[2]); (argout->svalue)[n_svalues-1] = CORBA::string_dup(row[4]); exported = -1; if (row[0] != NULL) sscanf(row[0],"%6d",&exported); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = exported; pid = -1; if (row[3] != NULL) sscanf(row[3],"%6d",&pid); n_lvalues++; (argout->lvalue).length(n_lvalues); (argout->lvalue)[n_lvalues-1] = pid; } } else { INFO_STREAM << "DataBase::db_import_event(): event not defined !" << endl; TangoSys_OMemStream o; o << "event " << tmp_event << " not defined in the database !"; mysql_free_result(result); delete argout; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, o.str(), (const char *)"DataBase::db_import_event()"); } mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbImportEvent"); /*----- PROTECTED REGION END -----*/ // DataBase::db_import_event return argout; } //-------------------------------------------------------- /** * Command DbInfo related method * Description: Get miscellaneous numbers on information * stored in database * * @returns Miscellaneous info like: * - Device defined in database * - Device marked as exported in database * - Device server process defined in database * - Device server process marked as exported in database * - Device properties defined in database * - Class properties defined in database * - Device attribute properties defined in database * - Class attribute properties defined in database * - Object properties defined in database */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_info() { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbInfo() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_info) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; char info_str[256]; char info2_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_infos=0; argout = new Tango::DevVarStringArray; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::db_info(): get general database infos" << endl; sprintf(info_str,"TANGO Database %s",DataBase::db_name.c_str()); n_infos = 1; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // newline n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(" "); // get start time of database sql_query_stream << "SELECT started FROM device WHERE name = \"" << DataBase::db_name << "\" "; // DEBUG_STREAM << "DataBase::db_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_info()"); sprintf(info_str,"Running since ..."); n_rows = mysql_num_rows(result); if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_info(): database started " << row[0] << endl; sprintf(info_str,"Running since %s",row[0]); } } mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // newline n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(" "); // get number of devices defined sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM device "; // DEBUG_STREAM << "DataBase::db_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_info()"); sprintf(info_str,"Devices defined ..."); n_rows = mysql_num_rows(result); if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_info(): no. of devices " << row[0] << endl; sprintf(info_str,"Devices defined = %s",row[0]); } } mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of devices exported sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM device WHERE exported = 1 "; // DEBUG_STREAM << "DataBase::db_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_info()"); sprintf(info_str,"Devices exported ..."); n_rows = mysql_num_rows(result); if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_info(): no. of devices exported " << row[0] << endl; sprintf(info_str,"Devices exported = %s",row[0]); } } mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of devices servers defined sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM device WHERE class = \"DServer\" "; // DEBUG_STREAM << "DataBase::db_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_info()"); sprintf(info_str,"Device servers defined ..."); n_rows = mysql_num_rows(result); if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_info(): no. of device servers defined " << row[0] << endl; sprintf(info_str,"Device servers defined = %s",row[0]); } } mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of devices servers exported sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM device WHERE class = \"DServer\" AND exported = 1 "; // DEBUG_STREAM << "DataBase::db_info(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_info()"); sprintf(info_str,"Device servers exported ..."); n_rows = mysql_num_rows(result); if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_info(): no. of device servers exported " << row[0] << endl; sprintf(info_str,"Device servers exported = %s",row[0]); } } mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // newline n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(" "); // ------------------------------------------------------------------------------------- // get number of device properties sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_device "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info_str,"Device properties defined = %s",row[0]); mysql_free_result(result); sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_device_hist "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info2_str," [History lgth = %s]",row[0]); strcat(info_str,info2_str); mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of class properties sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_class "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info_str,"Class properties defined = %s",row[0]); mysql_free_result(result); sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_class_hist "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info2_str," [History lgth = %s]",row[0]); strcat(info_str,info2_str); mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of device attribute properties sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_attribute_device "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info_str,"Device attribute properties defined = %s",row[0]); mysql_free_result(result); sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_attribute_device_hist "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info2_str," [History lgth = %s]",row[0]); strcat(info_str,info2_str); mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of class attribute properties sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_attribute_class "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info_str,"Class attribute properties defined = %s",row[0]); mysql_free_result(result); sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_attribute_class_hist "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info2_str," [History lgth = %s]",row[0]); strcat(info_str,info2_str); mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); // get number of object properties sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info_str,"Object properties defined = %s",row[0]); mysql_free_result(result); sql_query_stream.str(""); sql_query_stream << "SELECT COUNT(*) FROM property_hist "; result = query(sql_query_stream.str(),"db_info()"); row = mysql_fetch_row(result); sprintf(info2_str," [History lgth = %s]",row[0]); strcat(info_str,info2_str); mysql_free_result(result); n_infos++; argout->length(n_infos); (*argout)[n_infos-1] = CORBA::string_dup(info_str); DEBUG_STREAM << "DataBase::db_info(): argout->length() "<< argout->length() << endl; GetTime(after); update_timing_stats(before, after, "DbInfo"); /*----- PROTECTED REGION END -----*/ // DataBase::db_info return argout; } //-------------------------------------------------------- /** * Command DbPutAttributeAlias related method * Description: Define an alias for an attribute * * @param argin Str[0] = attribute name * Str[1] = attribute alias */ //-------------------------------------------------------- void DataBase::db_put_attribute_alias(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbPutAttributeAlias() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_put_attribute_alias) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; string tmp_alias; string tmp_name, tmp_attribute, tmp_device; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_put_attribute_alias(): insufficient alias info for attribute "; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient alias info for attribute", (const char *)"DataBase::db_put_attribute_alias()"); } tmp_name = (*argin)[0]; tmp_alias = (*argin)[1]; for (unsigned int i=0; i \'" << tmp_name << "\'"; DEBUG_STREAM << "DataBase::db_put_attribute_alias(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_put_attribute_alias()",al.get_con_nb()); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_put_attribute_alias(): mysql_num_rows() " << n_rows << endl; mysql_free_result(result); if (n_rows > 0) { WARN_STREAM << "DataBase::db_put_attribute_alias(): this alias exists already !" << endl; TangoSys_OMemStream o; o << "alias " << tmp_alias << " already exists !"; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_put_attribute_alias()"); } string::size_type pos=0; int nsep=0; do { if (pos != 0) pos++; pos = tmp_name.find("/",pos); if (pos != string::npos) nsep++; WARN_STREAM << "DataBase::db_put_attribute_alias(): found " << nsep << " separators , remaining string " << tmp_name.substr(pos+1) << endl; } while (pos != string::npos); if (nsep != 3) { WARN_STREAM << "DataBase::db_put_attribute_alias(): attribute name has bad syntax, must have 3 / in it" << endl; TangoSys_OMemStream o; o << "attribute name " << tmp_name << " has bad syntax, must have 3 / in it"; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_put_attribute_alias()"); } tmp_device = tmp_name.substr(0,tmp_name.rfind("/")); tmp_attribute = tmp_name.substr(tmp_name.rfind("/")+1); // first delete the current entry (if any) sql_query_stream.str(""); sql_query_stream << "DELETE FROM attribute_alias WHERE name=\'" << tmp_name << "\'"; DEBUG_STREAM << "DataBase::db_put_attribute_alias(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_put_attribute_alias()",al.get_con_nb()); // update the new value for this tuple sql_query_stream.str(""); sql_query_stream << "INSERT attribute_alias SET alias=\'" << tmp_alias << "\',name=\'" << tmp_name << "\',device=\'" << tmp_device << "\',attribute=\'" << tmp_attribute << "\',updated=NOW()"; DEBUG_STREAM << "DataBase::db_put_attribute_alias(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_put_attribute_alias()",al.get_con_nb()); } /*----- PROTECTED REGION END -----*/ // DataBase::db_put_attribute_alias } //-------------------------------------------------------- /** * Command DbPutClassAttributeProperty related method * Description: Create/Update class attribute property(ies) in database * * @param argin Str[0] = Tango class name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value * ..... */ //-------------------------------------------------------- void DataBase::db_put_class_attribute_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbPutClassAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_put_class_attribute_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_list = argin; TangoSys_MemStream sql_query_stream; int n_attributes, n_properties=0; const char *tmp_class, *tmp_attribute, *tmp_name; sscanf((*property_list)[1],"%6d",&n_attributes); INFO_STREAM << "DataBase::PutAttributeProperty(): put " << n_attributes << " attributes for device " << (*property_list)[0] << endl; { AutoLock al("LOCK TABLES property_attribute_class WRITE, property_attribute_class_hist WRITE,class_attribute_history_id WRITE",this); int i, j, k; k = 2; for (i=0; ilength() < 2) { WARN_STREAM << "DataBase::db_put_device_alias(): insufficient alias info for device "; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient alias info for device", (const char *)"DataBase::db_put_device_alias()"); } tmp_device = (*device_alias)[0]; tmp_alias = (*device_alias)[1]; for (unsigned int i=0; i \'" << tmp_device << "\'"; DEBUG_STREAM << "DataBase::db_put_device_alias(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_put_device_alias()",al.get_con_nb()); long n_rows=0; n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_put_device_alias(): mysql_num_rows() " << n_rows << endl; mysql_free_result(result); if (n_rows > 0) { WARN_STREAM << "DataBase::db_put_device_alias(): this alias exists already !" << endl; TangoSys_OMemStream o; o << "alias " << tmp_alias << " already exists !"; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_put_device_alias()"); } // update the new value for this tuple sql_query_stream.str(""); sql_query_stream << "UPDATE device set alias=\'" << tmp_alias << "\',started=NOW() where name LIKE \'" << tmp_device << "\'"; DEBUG_STREAM << "DataBase::db_put_device_alias(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_put_device_alias()",al.get_con_nb()); } /*----- PROTECTED REGION END -----*/ // DataBase::db_put_device_alias } //-------------------------------------------------------- /** * Command DbPutDeviceAttributeProperty related method * Description: Create/Update device attribute property(ies) in database * * @param argin Str[0] = Device name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value * ..... */ //-------------------------------------------------------- void DataBase::db_put_device_attribute_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbPutDeviceAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_put_device_attribute_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_list = argin; TangoSys_MemStream sql_query_stream; int n_attributes, n_properties=0; const char *tmp_device, *tmp_attribute, *tmp_name; TimeVal before, after; GetTime(before); sscanf((*property_list)[1],"%6d",&n_attributes); INFO_STREAM << "DataBase::PutAttributeProperty(): put " << n_attributes << " attributes for device " << (*property_list)[0] << endl; { AutoLock al("LOCK TABLES property_attribute_device WRITE, property_attribute_device_hist WRITE,device_attribute_history_id WRITE",this); int i, j, k; k = 2; for (i=0; ilength() == 7 && ::strcmp((*argin)[1].in(),"1") == 0 && ::strcmp((*argin)[3].in(),"1") == 0 && ::strcmp((*argin)[4].in(),"__value") == 0 && ::strcmp((*argin)[5].in(),"1") == 0) { create_update_mem_att(argin); } else { sscanf((*argin)[1],"%6d",&n_attributes); INFO_STREAM << "DataBase::PutAttributeProperty2(): put " << n_attributes << " attributes for device " << (*argin)[0] << endl; { AutoLock al("LOCK TABLES property_attribute_device WRITE, property_attribute_device_hist WRITE,device_attribute_history_id WRITE",this); int tmp_count, i, j, k, l, jj; k = 2; for (i=0; ilength() < 4) { WARN_STREAM << "DataBase::db_put_server_info(): insufficient info for server "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient server info", (const char *)"DataBase::db_put_server_info()"); } INFO_STREAM << "DataBase::db_put_server_info(): put " << server_info->length()-1 << " export info for device " << (*server_info)[0] << endl; tmp_server = (*server_info)[0]; // replace uppercase by lowercase for (unsigned int i=0; i get previous host where running // string previous_host(""); { AutoLock al("LOCK TABLES device READ, server WRITE",this); if (fireToStarter==true) { if (tmp_host[0] == '\0') { omni_mutex_lock oml(starter_mutex); // Get database server name //-------------------------------------- Tango::Util *tg = Tango::Util::instance(); string db_serv = tg->get_ds_name(); transform(db_serv.begin(), db_serv.end(), db_serv.begin(), ::tolower); string adm_dev = "dserver/"; adm_dev += tmp_server; char *tmp_ptr = db_get_device_host((Tango::DevString)adm_dev.c_str(),al.get_con_nb()); previous_host = tmp_ptr; DEBUG_STREAM << tmp_server << " was running on " << previous_host << endl; CORBA::string_free(tmp_ptr); } } // first delete the server from the server table sql_query_stream << "DELETE FROM server WHERE name = \"" << tmp_server << "\""; DEBUG_STREAM << "DataBase::db_put_server_info(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_put_server_info()",al.get_con_nb()); // insert the new info for this server sql_query_stream.str(""); sql_query_stream << "INSERT INTO server SET name=\'" << tmp_server << "\',host=\'" << tmp_host << "\',mode=\'" << tmp_mode << "\',level=\'" << tmp_level << "\'"; DEBUG_STREAM << "DataBase::db_put_server_info(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_put_server_info()",al.get_con_nb()); } // Update host's starter to update controlled servers list if (fireToStarter==true) { omni_mutex_lock oml(starter_mutex); vector hosts; if (previous_host=="") hosts.push_back(tmp_host); else hosts.push_back(previous_host); starter_shared->send_starter_cmd(hosts); } /*----- PROTECTED REGION END -----*/ // DataBase::db_put_server_info } //-------------------------------------------------------- /** * Command DbUnExportDevice related method * Description: Mark a device as non exported in database * * @param argin Device name */ //-------------------------------------------------------- void DataBase::db_un_export_device(Tango::DevString argin) { DEBUG_STREAM << "DataBase::DbUnExportDevice() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_un_export_device) ENABLED START -----*/ // Add your own code Tango::DevString devname = argin; TangoSys_MemStream sql_query_stream; char *tmp_device; INFO_STREAM << "DataBase::UnExportDevice(): un-export " << devname << " device " << endl; tmp_device = (char*)malloc(strlen(devname)+1); sprintf(tmp_device,"%s",devname); for (unsigned int i=0; i::iterator iter; for (iter=timing_stats_map.begin(); iter!=timing_stats_map.end(); iter++) { iter->second->average = iter->second->minimum = iter->second->maximum = iter->second->total_elapsed = iter->second->calls = 0.0; } timing_stats_mutex.unlock(); /*----- PROTECTED REGION END -----*/ // DataBase::reset_timing_values } //-------------------------------------------------------- /** * Command DbGetDataForServerCache related method * Description: This command returns all the data needed by a device server process during its * startup sequence. The aim of this command is to minimize database access during * device server startup sequence. * * @param argin Elt[0] = DS name (exec_name/inst_name), Elt[1] = Host name * @returns All the data needed by the device server during its startup sequence. Precise list depend on the device server */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_data_for_server_cache(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDataForServerCache() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_data_for_server_cache) ENABLED START -----*/ // Add your own code // POGO has generated a method core with argout allocation. // If you would like to use a static reference without copying, // See "TANGO Device Server Programmer's Manual" // (chapter : Writing a TANGO DS / Exchanging data) //------------------------------------------------------------ DEBUG_STREAM << "DataBase::db_get_data_for_server_cache(): entering... !" << endl; // Add your own code to control device here if (argin->length() != 2) { WARN_STREAM << "DataBase::DbGetDataForServerCache(): incorrect number of input arguments " << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"Incorrect no. of input arguments, needs 2 (ds_name,host_name)", (const char *)"DataBase::DbGetDataForServerCache()"); } if (mysql_svr_version < 50000) { WARN_STREAM << "DataBase::DbGetDataForServerCache(): MySQL server too old for this command" << endl; Tango::Except::throw_exception((const char *)"DB_MySQLServerTooOld", (const char *)"The MySQL server release does not support stored procedure. Update MySQL to release >= 5", (const char *)"DataBase::DbGetDataForServerCache()"); } argout = new Tango::DevVarStringArray(); TimeVal before, after; GetTime(before); string sql_query; string svc((*argin)[0]); string host((*argin)[1]); MYSQL_RES *res; MYSQL_ROW row; Tango::Util *tg = Tango::Util::instance(); string &db_inst_name = tg->get_ds_inst_name(); string tmp_var_name("@param_out"); tmp_var_name = tmp_var_name + db_inst_name; // // Do not use methods query() or simple_query() because we are // calling a stored procedure. // Calling a stored procedure needs special care to retrieve its OUT // parameter(s). We have to code a loop using mysql_next_result // function. The first result with data is the one we are // interested in // sql_query = "CALL "; sql_query = sql_query + mysql_db_name; sql_query = sql_query + ".ds_start('" + svc + "','" + host + "'," + tmp_var_name + ")"; sql_query = sql_query + ";SELECT " + tmp_var_name; // cout << "Query = " << sql_query << endl; int con_nb = get_connection(); if (mysql_real_query(conn_pool[con_nb].db, sql_query.c_str(),sql_query.length()) != 0) { delete argout; TangoSys_OMemStream o; WARN_STREAM << "DataBase::db_get_data_for_server_cache failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o << "\nThe query was: " << sql_query << ends; release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(), (const char *)"DataBase::DbGetDataForServerCache()"); } int status; do { if ((res = mysql_store_result(conn_pool[con_nb].db)) != NULL) { break; } else { if (mysql_field_count(conn_pool[con_nb].db) != 0) { delete argout; TangoSys_OMemStream o; WARN_STREAM << "DataBase::db_get_data_for_server_cache: mysql_store_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "mysql_store_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")"; release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(), (const char *)"DataBase::DbGetDataForServerCache()"); } if ((status = mysql_next_result(conn_pool[con_nb].db)) > 0) { delete argout; TangoSys_OMemStream o; WARN_STREAM << "DataBase::db_get_data_for_server_cache: mysql_next_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "mysql_next_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")"; release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(), (const char *)"DataBase::DbGetDataForServerCache()"); } } }while (status == 0); release_connection(con_nb); row = mysql_fetch_row(res); unsigned long *length_ptr = mysql_fetch_lengths(res); string str(row[0],length_ptr[0]); #ifdef __SUNPRO_CC int nb_field; count(str.begin(),str.end(),'\0',nb_field); #else int nb_field = count(str.begin(),str.end(),'\0'); #endif if (nb_field == 0) { if (str.size() == 0) { delete argout; mysql_free_result(res); WARN_STREAM << "DataBase::DbGetDataForServerCache(): Stored procedure does not return any result!!!" << endl; Tango::Except::throw_exception((const char *)"DB_StoredProcedureNoResult", (const char *)"The stored procedure did not return any results!!!", (const char *)"DataBase::DbGetDataForServerCache()"); } else { delete argout; mysql_free_result(res); WARN_STREAM << "DataBase::DbGetDataForServerCache(): Stored procedure failed with a MySQL error!!!" << endl; Tango::Except::throw_exception((const char *)"DB_StoredProcedureFailed", (const char *)"The stored procedure failed with a MySQL error!!!", (const char *)"DataBase::DbGetDataForServerCache()"); } } argout->length(nb_field + 1); string::size_type pos = 0; string::size_type start = 0; int idx = 0; string tmp_elt; pos = str.find('\0'); while (pos != string::npos) { tmp_elt = str.substr(start,pos - start); (*argout)[idx] = CORBA::string_dup(tmp_elt.c_str()); start = pos + 1; idx++; pos = str.find('\0',start); } tmp_elt = str.substr(start); (*argout)[idx] = CORBA::string_dup(tmp_elt.c_str()); mysql_free_result(res); GetTime(after); update_timing_stats(before, after, "DbGetDataForServerCache"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_data_for_server_cache return argout; } //-------------------------------------------------------- /** * Command DbDeleteAllDeviceAttributeProperty related method * Description: Delete all attribute properties for the specified device attribute(s) * * @param argin str[0] = device name * Str[1]...str[n] = attribute name(s) */ //-------------------------------------------------------- void DataBase::db_delete_all_device_attribute_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteAllDeviceAttributeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_all_device_attribute_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *attribute; string tmp_device; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_delete_all_device_attribute_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, (const char *)"insufficient number of arguments to delete all device attribute(s) property", (const char *)"DataBase::db_delete_all_device_attribute_property()"); } tmp_device = (*argin)[0]; if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_all_device_attribute(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception((const char *)DB_IncorrectDeviceName, (const char *)"Failed to delete all device attribute(s) property, device name incorrect", (const char *)"DataBase::db_delete_all_device_attribute()"); } { AutoLock al("LOCK TABLES property_attribute_device WRITE, property_attribute_device_hist WRITE,device_attribute_history_id WRITE",this); for (unsigned int i=0; ilength()-1; i++) { attribute = (*argin)[i+1]; INFO_STREAM << "DataBase::db_delete_all_device_attribute_property(): delete device " << tmp_device ; INFO_STREAM << " attribute " << attribute << " property(ies) from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT DISTINCT name FROM property_attribute_device WHERE device = \"" << tmp_device <<"\" AND attribute = \"" << attribute << "\" "; result = query(sql_query_stream.str(),"db_delete_all_device_attribute_property()",al.get_con_nb()); my_ulonglong count = mysql_num_rows(result); if (count != 0) { // then delete property from the property_attribute_device table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_attribute_device WHERE device = \"" << tmp_device <<"\" AND attribute = \"" << attribute << "\" "; DEBUG_STREAM << "DataBase::db_delete_all_device_attribute_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_all_device_attribute_property()",al.get_con_nb()); // Mark this property as deleted for(unsigned int j=0;j (idx + 1))) { TangoSys_OMemStream o; o << "SQL command not valid: \'" << argin << "\'"; string msg = o.str(); WARN_STREAM << msg << endl; Tango::Except::throw_exception((const char *)DB_IncorrectArguments, msg, (const char *)"DataBase::db_my_sql_select()"); } INFO_STREAM << "DataBase::db_my_sql_select(): \ncmd: " << cmd << endl; MYSQL_RES *result = query(cmd, "db_my_sql_select()"); int nb_rows = mysql_num_rows(result); int nb_fields = mysql_num_fields(result); int nb_data = nb_rows*nb_fields; DEBUG_STREAM << "DataBase::db_my_sql_select(): mysql_num_rows() " << nb_rows << endl; argout = new Tango::DevVarLongStringArray; (argout->svalue).length(nb_data); (argout->lvalue).length(nb_data+2); MYSQL_ROW row; idx = 0; if (nb_rows>0) { for (int i=0; isvalue)[idx] = CORBA::string_dup(""); (argout->lvalue)[idx++] = 0; // data is null } else if (row[j]==NULL) (argout->svalue)[idx] = CORBA::string_dup(""); // data is null else (argout->svalue)[idx] = CORBA::string_dup(row[j]); // data is NOT null (argout->lvalue)[idx++] = (row[j]!=NULL); } } } // Add nb rows and nb fields at end of lvalue. (argout->lvalue)[idx++] = nb_rows; (argout->lvalue)[idx++] = nb_fields; mysql_free_result(result); GetTime(after); update_timing_stats(before, after, "DbMySqlSelect"); /*----- PROTECTED REGION END -----*/ // DataBase::db_my_sql_select return argout; } //-------------------------------------------------------- /** * Command DbGetCSDbServerList related method * Description: Get a list of host:port for all database server defined in the control system * * @returns List of host:port with one element for each database server */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_csdb_server_list() { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetCSDbServerList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_csdb_server_list) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows; sql_query_stream << "SELECT DISTINCT ior FROM device WHERE exported=1 AND domain=\'sys\' AND family=\'database\'"; DEBUG_STREAM << "DataBase::db_get_csdb_server_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_csdb_server_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_csdb_server_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_csdb_server_list return argout; } //-------------------------------------------------------- /** * Command DbGetAttributeAlias2 related method * Description: Get the attribute alias from the attribute name. * Returns one empty string if nothing found in database * * @param argin The attribute name (dev_name/att_name) * @returns The attribute alias name (or empty string) */ //-------------------------------------------------------- Tango::DevString DataBase::db_get_attribute_alias2(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "DataBase::DbGetAttributeAlias2() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_attribute_alias2) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; long n_rows=0; argout = new char[256]; INFO_STREAM << "DataBase::db_get_attribute_alias2(): get " << argin << endl; // first check to see if this alias exists sql_query_stream << "SELECT alias from attribute_alias WHERE name LIKE \'" << argin << "\' "; DEBUG_STREAM << "DataBase::db_get_attribute_alias2(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_attribute_alias2()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_attribute_alias2(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_get_attribute_alias2(): attribute name "<< row[0] << endl; strcpy(argout,row[0]); } } else { //strcpy(argout,""); TangoSys_OMemStream o; o << "No alias found for attribute \'" << argin << "\'"; mysql_free_result(result); delete [] argout; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_get_attribute_alias2()"); } /*----- PROTECTED REGION END -----*/ // DataBase::db_get_attribute_alias2 return argout; } //-------------------------------------------------------- /** * Command DbGetAliasAttribute related method * Description: Get the attribute name from the given alias. * If the given alias is not found in database, returns an empty string * * @param argin The attribute alias * @returns The attribute name (dev_name/att_name) */ //-------------------------------------------------------- Tango::DevString DataBase::db_get_alias_attribute(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "DataBase::DbGetAliasAttribute() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_alias_attribute) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; long n_rows=0; argout = new char[256]; INFO_STREAM << "DataBase::db_get_alias_attribute(): get " << argin << endl; // first check to see if this alias exists sql_query_stream << "SELECT name from attribute_alias WHERE alias LIKE \'" << argin << "\' "; DEBUG_STREAM << "DataBase::db_get_alias_attribute(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_alias_attribute()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_alias_attribute(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { if ((row = mysql_fetch_row(result)) != NULL) { DEBUG_STREAM << "DataBase::db_get_alias_attribute(): attribute name "<< row[0] << endl; strcpy(argout,row[0]); } } else { //strcpy(argout,""); TangoSys_OMemStream o; o << "No attribute found for alias \'" << argin << "\'"; mysql_free_result(result); delete [] argout; Tango::Except::throw_exception((const char *)DB_SQLError, o.str(), (const char *)"DataBase::db_get_alias_attribute()"); } // Add your own code to control device here mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_alias_attribute return argout; } //-------------------------------------------------------- /** * Command DbRenameServer related method * Description: Rename a device server process * * @param argin s[0] = old device server name (exec/instance) * s[1] = new device server name (exec/instance) */ //-------------------------------------------------------- void DataBase::db_rename_server(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbRenameServer() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_rename_server) ENABLED START -----*/ // Add your own code // // Check argument validity // if (argin->length() != 2) { Tango::Except::throw_exception("DB_WrongArgNUmber", "Wrong number of args (two required: old name and new name)", "DataBase::db_rename_server()"); } string old_name((*argin)[0]); string new_name((*argin)[1]); string::size_type pos_old,pos_new; pos_old = old_name.find('/'); pos_new = new_name.find('/'); if ((pos_old == string::npos) || (pos_new == string::npos)) { Tango::Except::throw_exception("Db_WrongArgument","Wrong syntax in command args (ds_exec_name/inst_name)", "DataBase::db_rename_server()"); } // // Check that the new name is not already used // string new_adm_name("dserver/"); new_adm_name = new_adm_name + new_name; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; long n_rows=0; sql_query_stream << "SELECT name from device WHERE name = \'" << new_adm_name << "\' "; DEBUG_STREAM << "DataBase::db_rename_server(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_rename_server()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_rename_server(): mysql_num_rows() " << n_rows << endl; if (n_rows > 0) { mysql_free_result(result); stringstream ss; ss << "Device server process name " << new_name << " is already used"; Tango::Except::throw_exception("Db_WrongArgument",ss.str(),"DataBase::db_rename_server()"); } // // get host where running // string previous_host(""); if (fireToStarter==true) { omni_mutex_lock oml(starter_mutex); string adm_dev("dserver/"); adm_dev += old_name; try { char *tmp_ptr = db_get_device_host((Tango::DevString)adm_dev.c_str()); previous_host = tmp_ptr; DEBUG_STREAM << old_name << " was running on " << previous_host << endl; CORBA::string_free(tmp_ptr); } catch (Tango::DevFailed &e) { string reason(e.errors[0].reason.in()); if (reason == DB_DeviceNotDefined) { WARN_STREAM << "DataBase::db_delete_server(): server " << old_name << " not defined in DB" << endl; TangoSys_OMemStream o; o << "Server " << old_name << " not defined in database !"; Tango::Except::throw_exception((const char *)DB_IncorrectServerName,o.str(), (const char *)"DataBase::db_delete_server()"); } } } // // Change ds exec name. This means // 1 - Update the device's server column // 2 - Change the ds admin device name // 3 - Change admin device property (if any) // 4 - Change admin device attribute property (if any) // string old_adm_name("dserver/"); old_adm_name = old_adm_name + old_name; string new_exec = new_name.substr(0,pos_new); string new_inst = new_name.substr(pos_new + 1); { AutoLock al("LOCK TABLES device WRITE, property_device WRITE, property_attribute_device WRITE",this); sql_query_stream.str(""); sql_query_stream << "UPDATE device set server=\'" << new_name << "\' where server=\'" << old_name << "\'"; DEBUG_STREAM << "DataBase::db_rename_server(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_rename_server()",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "UPDATE device set name=\'" << new_adm_name; sql_query_stream << "\', family=\'" << new_exec; sql_query_stream << "\', member=\'" << new_inst; sql_query_stream << "\' where name=\'" << old_adm_name << "\'"; DEBUG_STREAM << "DataBase::db_rename_server(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_rename_server()",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "UPDATE property_device set device=\'" << new_adm_name; sql_query_stream << "\' where device=\'" << old_adm_name << "\'"; DEBUG_STREAM << "DataBase::db_rename_server(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_rename_server()",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "UPDATE property_attribute_device set device=\'" << new_adm_name; sql_query_stream << "\' where device=\'" << old_adm_name << "\'"; DEBUG_STREAM << "DataBase::db_rename_server(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_rename_server()",al.get_con_nb()); } // // Update host's starter to update controlled servers list // if (fireToStarter==true) { omni_mutex_lock oml(starter_mutex); vector hosts; if (previous_host!="") { hosts.push_back(previous_host); starter_shared->send_starter_cmd(hosts); } } /*----- PROTECTED REGION END -----*/ // DataBase::db_rename_server } //-------------------------------------------------------- /** * Command DbGetClassPipeProperty related method * Description: Retrieve class pipe properties * * @param argin Str[0] = Tango class name * Str[1] = Pipe name * Str[n] = Pipe name * @returns Str[0] = Tango class name * Str[1] = Pipe property number * Str[2] = Pipe property 1 name * Str[3] = Pipe property 1 value number (array case) * Str[4] = Pipe property 1 value * Str[n] = Pipe property 1 value (array case) * Str[n + 1] = Pipe property 2 name * Str[n + 2] = Pipe property 2 value number (array case) * Str[n + 3] = Pipe property 2 value * Str[n + m] = Pipe property 2 value (array case) */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_pipe_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassPipeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_pipe_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; DEBUG_STREAM << "DataBase::db_get_class_pipe_property(): entering... !" << endl; TangoSys_MemStream sql_query_stream; char n_pipes_str[256]; char n_rows_str[256]; char prop_size_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_class, *tmp_pipe; INFO_STREAM << "DataBase::GetClassPipeProperty(): get properties for " << property_names->length()-1 << " pipe(s) for class " << (*property_names)[0] << endl; tmp_class = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_pipes_str, "%lu", property_names->length()-1); #else sprintf(n_pipes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_class); (*argout)[n_props-1] = CORBA::string_dup(n_pipes_str); for (unsigned int i=1; ilength(); i++) { tmp_pipe = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_pipe_class WHERE class = \"" << tmp_class << "\" AND pipe LIKE \"" << tmp_pipe << "\" ORDER BY name,count"; DEBUG_STREAM << "DataBase::GetClassPipeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_pipe_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetClassPipeProperty(): mysql_num_rows() " << n_rows << endl; n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_pipe); int prop_number_idx = n_props-1; int prop_number = 0; if (n_rows > 0) { string name, old_name; bool new_prop = true; int prop_size_idx = 0; int prop_size = 0; for (int j=0; jlength(n_props); (*argout)[n_props-3] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } prop_size_idx = n_props - 2; prop_size = 1; } else { n_props = n_props + 1; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); prop_size++; } } } if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } } sprintf(n_rows_str,"%d",prop_number); (*argout)[prop_number_idx] = CORBA::string_dup(n_rows_str); mysql_free_result(result); } DEBUG_STREAM << "DataBase::GetClassPipeProperty(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_pipe_property return argout; } //-------------------------------------------------------- /** * Command DbGetDevicePipeProperty related method * Description: Retrieve device pipe properties * * @param argin Str[0] = Device name * Str[1] = Pipe name * Str[n] = Pipe name * @returns Str[0] = Device name * Str[1] = Pipe property number * Str[2] = Pipe property 1 name * Str[3] = Pipe property 1 value number (array case) * Str[4] = Pipe property 1 value * Str[n] = Pipe property 1 value (array case) * Str[n + 1] = Pipe property 2 name * Str[n + 2] = Pipe property 2 value number (array case) * Str[n + 3] = Pipe property 2 value * Str[n + m] = Pipe property 2 value (array case) */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_pipe_property(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDevicePipeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_pipe_property) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *property_names = argin; TangoSys_MemStream sql_query_stream; char n_pipes_str[256]; char n_rows_str[256]; char prop_size_str[256]; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0, n_props=0; argout = new Tango::DevVarStringArray; const char *tmp_device, *tmp_pipe; TimeVal before, after; GetTime(before); INFO_STREAM << "DataBase::GetDevicePipeProperty(): get properties for " << property_names->length()-1 << " pipe(s) for device " << (*property_names)[0] << endl; tmp_device = (*property_names)[0]; #ifdef TANGO_LONG32 sprintf(n_pipes_str, "%lu", property_names->length()-1); #else sprintf(n_pipes_str, "%u", property_names->length()-1); #endif n_props = 2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_device); (*argout)[n_props-1] = CORBA::string_dup(n_pipes_str); // // First, get how many pipes belonging to the device have // properties defined in the db // bool all_pipe = false; sql_query_stream << "SELECT COUNT(DISTINCT pipe) FROM property_pipe_device WHERE device = \"" << tmp_device << "\""; DEBUG_STREAM << "Database::GetDevicePipeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_pipe_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): mysql_num_rows() " << n_rows << endl; if (n_rows != 0) { if ((row = mysql_fetch_row(result)) != NULL) { stringstream tmp_str; string nb_pipe_str = row[0]; tmp_str << nb_pipe_str; unsigned int nb_pipe = 0; tmp_str >> nb_pipe; if (property_names->length()-1 >= nb_pipe) all_pipe = true; mysql_free_result(result); } } if (all_pipe == true) { DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): Get pipe properties for all pipe(s)" << endl; } if (all_pipe == false) { for (unsigned int i=1; ilength(); i++) { tmp_pipe = (*property_names)[i]; sql_query_stream.str(""); sql_query_stream << "SELECT name,value FROM property_pipe_device WHERE device = \"" << tmp_device << "\" AND pipe LIKE \"" << tmp_pipe << "\" ORDER BY name,count"; DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_pipe_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): mysql_num_rows() " << n_rows << endl; n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_pipe); int prop_number_idx = n_props-1; int prop_number = 0; if (n_rows > 0) { string name, old_name; bool new_prop = true; int prop_size_idx = 0; int prop_size = 0; for (int j=0; jlength(n_props); (*argout)[n_props-3] = CORBA::string_dup(row[0]); (*argout)[n_props-1] = CORBA::string_dup(row[1]); if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } prop_size_idx = n_props - 2; prop_size = 1; } else { n_props = n_props + 1; argout->length(n_props); (*argout)[n_props-1] = CORBA::string_dup(row[1]); prop_size++; } } } if (prop_size != 0) { sprintf(prop_size_str,"%d",prop_size); (*argout)[prop_size_idx] = CORBA::string_dup(prop_size_str); prop_number++; } } sprintf(n_rows_str,"%d",prop_number); (*argout)[prop_number_idx] = CORBA::string_dup(n_rows_str); mysql_free_result(result); } } else { sql_query_stream.str(""); sql_query_stream << "SELECT pipe,name,value FROM property_pipe_device WHERE device = \"" << tmp_device << "\" ORDER BY pipe,name,count"; DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_pipe_property()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): mysql_num_rows() " << n_rows << endl; map > db_data; string pipe,prev_pipe; string p_name,prev_p_name; string value; PropDef prop; vector pipe_props; // // Create a map with data coming from db // for (int j = 0;j < n_rows;j++) { if ((row = mysql_fetch_row(result)) != NULL) { pipe = row[0]; transform(pipe.begin(),pipe.end(),pipe.begin(),::tolower); if (pipe != prev_pipe) { if (j != 0) { pipe_props.push_back(prop); db_data.insert(make_pair(prev_pipe,pipe_props)); prop.prop_val.clear(); pipe_props.clear(); } p_name = row[1]; prop.prop_name_cd = p_name; transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); prop.prop_name = p_name; value = row[2]; prop.prop_val.push_back(value); prev_p_name = p_name; prev_pipe = pipe; } else { p_name = row[1]; transform(p_name.begin(),p_name.end(),p_name.begin(),::tolower); if (p_name != prev_p_name) { pipe_props.push_back(prop); prop.prop_val.clear(); prop.prop_name = p_name; prop.prop_name_cd = row[1]; value = row[2]; prop.prop_val.push_back(value); prev_p_name = p_name; } else { value = row[2]; prop.prop_val.push_back(value); } } } } mysql_free_result(result); if (n_rows != 0) { pipe_props.push_back(prop); db_data.insert(make_pair(pipe,pipe_props)); } // // Initialized data returned to caller // for (unsigned int i=1; ilength(); i++) { string tmp_pipe((*property_names)[i]); string tmp_pipe_lower(tmp_pipe); transform(tmp_pipe_lower.begin(),tmp_pipe_lower.end(),tmp_pipe_lower.begin(),::tolower); map >::iterator pos = db_data.find(tmp_pipe_lower); // // Data for this pipe in map? // if (pos == db_data.end()) { n_props = n_props+2; argout->length(n_props); (*argout)[n_props-2] = CORBA::string_dup(tmp_pipe.c_str()); (*argout)[n_props-1] = CORBA::string_dup("0"); } else { int prop_nb = pos->second.size(); n_props = n_props + 2; argout->length(n_props); (*argout)[n_props - 2] = CORBA::string_dup(tmp_pipe.c_str()); sprintf(n_rows_str,"%d",prop_nb); (*argout)[n_props - 1] = CORBA::string_dup(n_rows_str); for (int i = 0;i < prop_nb;i++) { PropDef &pd = (pos->second)[i]; int prop_size = pd.prop_val.size(); int old_n_props = n_props; n_props = n_props + 2 + prop_size; argout->length(n_props); (*argout)[old_n_props++] = CORBA::string_dup(pd.prop_name_cd.c_str()); sprintf(n_rows_str,"%d",prop_size); (*argout)[old_n_props++] = CORBA::string_dup(n_rows_str); for (int j = 0;j < prop_size;j++) { (*argout)[old_n_props++] = CORBA::string_dup(pd.prop_val[j].c_str()); } } } } } DEBUG_STREAM << "DataBase::GetDevicePipeProperty(): argout->length() "<< argout->length() << endl; GetTime(after); update_timing_stats(before, after, "DbGetDevicePipeProperty"); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_pipe_property return argout; } //-------------------------------------------------------- /** * Command DbDeleteClassPipe related method * Description: Delete a class pipe and all its properties from database * * @param argin Str[0] = Tango class name * Str[1] = Pipe name */ //-------------------------------------------------------- void DataBase::db_delete_class_pipe(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteClassPipe() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_class_pipe) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *pipe; string tmp_class; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_delete_class_pipe(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "insufficient number of arguments to delete class pipe", "DataBase::db_delete_class_pipe()"); } tmp_class = (*argin)[0]; pipe = (*argin)[1]; INFO_STREAM << "DataBase::db_delete_class_pipe(): delete " << tmp_class << " from database" << endl; // then delete class from the property_pipe_class table sql_query_stream << "DELETE FROM property_pipe_class WHERE class LIKE \"" << tmp_class << "\" AND pipe LIKE \"" << pipe << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_pipe(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_pipe()"); /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_class_pipe } //-------------------------------------------------------- /** * Command DbDeleteDevicePipe related method * Description: Delete device pipe properties from database * * @param argin Str[0] = Device name * Str[1] = Pipe name */ //-------------------------------------------------------- void DataBase::db_delete_device_pipe(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteDevicePipe() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_device_pipe) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *pipe; string tmp_device; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_delete_device_pipe(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "insufficient number of arguments to delete device pipe", "DataBase::db_delete_device_pipe()"); } tmp_device = (*argin)[0].in(); pipe = (*argin)[1]; INFO_STREAM << "DataBase::db_delete_device_pipe(): delete pipe " << pipe << " for device " << tmp_device << " from database" << endl; // first check the device name if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_device_pipe(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectDeviceName, "Failed to delete device pipe, device name incorrect", "DataBase::db_delete_device_pipe()"); } // replace database wildcards (% and _) string tmp_wildcard = replace_wildcard(tmp_device.c_str()); // then delete device from the property_attribute_device table sql_query_stream << "DELETE FROM property_pipe_device WHERE device LIKE \"" << tmp_wildcard << "\" AND pipe LIKE \"" << pipe << "\" "; DEBUG_STREAM << "DataBase::db_delete_device_pipe(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_pipe()"); /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_device_pipe } //-------------------------------------------------------- /** * Command DbDeleteClassPipeProperty related method * Description: Delete class pipe properties from database * * @param argin Str[0] = Tango class name * Str[1] = Pipe name * Str[2] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_class_pipe_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteClassPipeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_class_pipe_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *pipe, *property; string tmp_class; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 3) { WARN_STREAM << "DataBase::db_delete_class_pipe_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "Insufficient number of arguments to delete class pipe property", "DataBase::db_delete_class_pipe_property()"); } tmp_class = (*argin)[0]; pipe = (*argin)[1]; { AutoLock al("LOCK TABLES property_pipe_class WRITE,property_pipe_class_hist WRITE,class_pipe_history_id WRITE",this); for (unsigned int i=0; ilength()-2; i++) { property = (*argin)[i+2]; INFO_STREAM << "DataBase::db_delete_class_pipe_property(): delete class " << tmp_class ; INFO_STREAM << " pipe " << pipe << " property[" << i <<"] " << property << " from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT count(*) FROM property_pipe_class WHERE class = \"" << tmp_class << "\" AND pipe = \"" << pipe << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_pipe_property(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_delete_class_pipe_property()",al.get_con_nb()); row = mysql_fetch_row(result); int count; stringstream ss; ss << row[0]; ss >> count; mysql_free_result(result); if(count) { // then delete property from the property_attribute_class table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_pipe_class WHERE class = \"" << tmp_class << "\" AND pipe = \"" << pipe << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_class_pipe_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_pipe_property()",al.get_con_nb()); // Mark this property as deleted Tango::DevULong64 class_pipe_property_hist_id = get_id("class_pipe",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "INSERT INTO property_pipe_class_hist SET class='" << tmp_class \ << "',pipe='" << pipe \ << "',name='" << property \ << "',id='" << class_pipe_property_hist_id \ << "',count='0',value='DELETED'"; DEBUG_STREAM << "DataBase::db_delete_class_pipe_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_class_pipe_property()",al.get_con_nb()); } purge_pipe_property("property_pipe_class_hist","class",tmp_class.c_str(),pipe,property,al.get_con_nb()); } } /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_class_pipe_property } //-------------------------------------------------------- /** * Command DbDeleteDevicePipeProperty related method * Description: Delete device pipe properties from database * * @param argin Str[0] = Device name * Str[1] = Pipe name * Str[2] = Property name * Str[n] = Property name */ //-------------------------------------------------------- void DataBase::db_delete_device_pipe_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteDevicePipeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_device_pipe_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *pipe, *property; string tmp_device; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 3) { WARN_STREAM << "DataBase::db_delete_device_pipe_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "Insufficient number of arguments to delete device pipe property", "DataBase::db_delete_device_pipe_property()"); } tmp_device = (*argin)[0]; if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_device_pipe(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectDeviceName, "Failed to delete device pipe, device name incorrect", "DataBase::db_delete_device_pipe_property()"); } pipe = (*argin)[1]; { AutoLock al("LOCK TABLES property_pipe_device WRITE, property_pipe_device_hist WRITE,device_pipe_history_id WRITE",this); unsigned int i; for (i=0; ilength()-2; i++) { property = (*argin)[i+2]; INFO_STREAM << "DataBase::db_delete_device_pipe_property(): delete device " << tmp_device ; INFO_STREAM << " pipe " << pipe << " property[" << i <<"] " << property << " from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT count(*) FROM property_pipe_device WHERE device = \"" << tmp_device <<"\" AND pipe = \"" << pipe << "\" AND name = \"" << property << "\" "; result = query(sql_query_stream.str(),"db_delete_device_pipe_property()",al.get_con_nb()); row = mysql_fetch_row(result); int count; stringstream ss; ss << row[0]; ss >> count; mysql_free_result(result); if(count) { // then delete property from the property_pipe_device table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_pipe_device WHERE device = \"" << tmp_device <<"\" AND pipe = \"" << pipe << "\" AND name = \"" << property << "\" "; DEBUG_STREAM << "DataBase::db_delete_device_pipe_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_pipe_property()",al.get_con_nb()); // Mark this property as deleted Tango::DevULong64 device_pipe_property_hist_id = get_id("device_pipe",al.get_con_nb()); sql_query_stream.str(""); sql_query_stream << "INSERT INTO property_pipe_device_hist SET device='" << tmp_device << "',pipe='" << pipe << "',name='" << property << "',id='" << device_pipe_property_hist_id << "',count='0',value='DELETED'"; DEBUG_STREAM << "DataBase::DbDeleteDevicePipeProperty(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_device_pipe_property()",al.get_con_nb()); } purge_pipe_property("property_pipe_device_hist","device",tmp_device.c_str(),pipe,property,al.get_con_nb()); } } /*----- PROTECTED REGION END -----*/ // DataBase::db_delete_device_pipe_property } //-------------------------------------------------------- /** * Command DbGetClassPipeList related method * Description: Get pipe list for a given Tango class with a specified filter * * @param argin Str[0] = Tango class name * Str[1] = Pipe name filter (eg: pip*) * @returns Str[0] = Class pipe name * Str[n] = Class pipe name */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_class_pipe_list(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetClassPipeList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_class_pipe_list) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *class_wildcard = argin; TangoSys_MemStream sql_query_stream; MYSQL_RES *result; MYSQL_ROW row; int n_rows=0; argout = new Tango::DevVarStringArray; const char *class_name, *wildcard; string tmp_wildcard; class_name = (*class_wildcard)[0]; INFO_STREAM << "DataBase::db_get_class_pipe_list(): get pipes for class " << class_name << endl; wildcard = (*class_wildcard)[1]; if (wildcard == NULL) { #ifdef WIN32 sql_query_stream << "SELECT DISTINCT pipe FROM property_pipe_class WHERE class = \"" << class_name << "\" AND pipe like \"\\%\""; #else sql_query_stream << "SELECT DISTINCT pipe FROM property_pipe_class WHERE class = \"" << class_name << "\" AND pipe like \"%%\""; #endif /* WIN32 */ } else { tmp_wildcard = replace_wildcard(wildcard); sql_query_stream << "SELECT DISTINCT pipe FROM property_pipe_class WHERE class = \"" << class_name << "\" AND pipe like \"" << tmp_wildcard << "\""; } DEBUG_STREAM << "DataBase::DbGetClassPipeList(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_class_pipe_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::DbGetClassPipeList(): num_rows() " << n_rows << endl; if (n_rows > 0) { int n_pipes=0; for (int j=0; jlength(n_pipes); (*argout)[n_pipes-1] = CORBA::string_dup(row[0]); } } } mysql_free_result(result); DEBUG_STREAM << "DataBase::DbGetClassPipeList(): argout->length() "<< argout->length() << endl; /*----- PROTECTED REGION END -----*/ // DataBase::db_get_class_pipe_list return argout; } //-------------------------------------------------------- /** * Command DbGetDevicePipeList related method * Description: Return list of pipes matching the wildcard for the specified device * * @param argin Str[0] = Device name * Str[1] = Wildcard * @returns Pipe name list */ //-------------------------------------------------------- Tango::DevVarStringArray *DataBase::db_get_device_pipe_list(const Tango::DevVarStringArray *argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "DataBase::DbGetDevicePipeList() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_get_device_pipe_list) ENABLED START -----*/ // Add your own code const Tango::DevVarStringArray *device_wildcard = argin; TangoSys_MemStream sql_query_stream; string tmp_wildcard; MYSQL_RES *result; MYSQL_ROW row; int n_rows; const char *device, *wildcard; device = (*device_wildcard)[0]; wildcard = (*device_wildcard)[1]; INFO_STREAM << "DataBase::db_get_device_pipe_list(): device " << device; WARN_STREAM << " wildcard " << wildcard << endl; if (wildcard == NULL) { sql_query_stream << "SELECT DISTINCT pipe FROM property_pipe_device WHERE device=\"" << device << "\" AND pipe LIKE \"%\" ORDER BY pipe"; } else { tmp_wildcard = replace_wildcard (wildcard); sql_query_stream << "SELECT DISTINCT pipe FROM property_pipe_device WHERE device=\"" << device << "\" AND pipe LIKE \"" << tmp_wildcard << "\" ORDER BY pipe"; } DEBUG_STREAM << "DataBase::db_get_device_attrribute_list(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"db_get_device_pipe_list()"); n_rows = mysql_num_rows(result); DEBUG_STREAM << "DataBase::db_get_device_pipe_list(): mysql_num_rows() " << n_rows << endl; argout = new Tango::DevVarStringArray; if (n_rows > 0) { argout->length(n_rows); for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // DataBase::db_get_device_pipe_list return argout; } //-------------------------------------------------------- /** * Command DbDeleteAllDevicePipeProperty related method * Description: Delete all pipe properties for the specified device pipe(s) * * @param argin str[0] = device name * Str[1]...str[n] = pipe name(s) */ //-------------------------------------------------------- void DataBase::db_delete_all_device_pipe_property(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "DataBase::DbDeleteAllDevicePipeProperty() - " << device_name << endl; /*----- PROTECTED REGION ID(DataBase::db_delete_all_device_pipe_property) ENABLED START -----*/ // Add your own code TangoSys_MemStream sql_query_stream; const char *pipe; string tmp_device; MYSQL_RES *result; MYSQL_ROW row; if (argin->length() < 2) { WARN_STREAM << "DataBase::db_delete_all_device_pipe_property(): insufficient number of arguments "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "Insufficient number of arguments to delete all device pipe(s) property", "DataBase::db_delete_all_device_pipe_property()"); } tmp_device = (*argin)[0]; if (!check_device_name(tmp_device)) { WARN_STREAM << "DataBase::db_delete_all_device_pipe(): device name " << tmp_device << " incorrect "; WARN_STREAM << endl; Tango::Except::throw_exception(DB_IncorrectDeviceName, "Failed to delete all device pipe(s) property, device name incorrect", "DataBase::db_delete_all_device_pipe()"); } { AutoLock al("LOCK TABLES property_pipe_device WRITE, property_pipe_device_hist WRITE,device_pipe_history_id WRITE",this); for (unsigned int i=0; ilength()-1; i++) { pipe = (*argin)[i+1]; INFO_STREAM << "DataBase::db_delete_all_device_pipe_property(): delete device " << tmp_device ; INFO_STREAM << " pipe " << pipe << " property(ies) from database" << endl; // Is there something to delete ? sql_query_stream.str(""); sql_query_stream << "SELECT DISTINCT name FROM property_pipe_device WHERE device = \"" << tmp_device <<"\" AND pipe = \"" << pipe << "\" "; result = query(sql_query_stream.str(),"db_delete_all_device_pipe_property()",al.get_con_nb()); my_ulonglong count = mysql_num_rows(result); if (count != 0) { // then delete property from the property_pipe_device table sql_query_stream.str(""); sql_query_stream << "DELETE FROM property_pipe_device WHERE device = \"" << tmp_device <<"\" AND pipe = \"" << pipe << "\" "; DEBUG_STREAM << "DataBase::db_delete_all_device_pipe_property(): sql_query " << sql_query_stream.str() << endl; simple_query(sql_query_stream.str(),"db_delete_all_device_pipe_property()",al.get_con_nb()); // Mark this property as deleted for(unsigned int j=0;jlength() != 3) { WARN_STREAM << "DataBase::DbGetClassPipePropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "Incorrect no. of input arguments, needs 3 (class,pipe,property)", "DataBase::DbGetClassPipePropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_class = (*argin)[0]; tmp_pipe = replace_wildcard((*argin)[1]); tmp_name = replace_wildcard((*argin)[2]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_pipe_class_hist WHERE class = \"" << tmp_class << "\" AND pipe LIKE \"" << tmp_pipe << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_pipe_class_hist READ",this); ids = query(sql_query_stream.str(),"db_get_class_pipe_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,pipe,name,count FROM property_pipe_class_hist WHERE id = \"" << id << "\" AND class = \"" << tmp_class << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_class_pipe_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[4]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+4+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[3]); (*argout)[nb_item+2] = CORBA::string_dup(row[0]); (*argout)[nb_item+3] = CORBA::string_dup(n_rows_str); for(int j=0;jlength() != 3) { WARN_STREAM << "DataBase::DbGetDevicePipePropertyHist(): incorrect number of input arguments " << endl; Tango::Except::throw_exception(DB_IncorrectArguments, "Incorrect no. of input arguments, needs 3 (device,pipe,property)", "DataBase::DbGetDevicePipePropertyHist()"); } argout = new Tango::DevVarStringArray; tmp_device = (*argin)[0]; tmp_pipe = replace_wildcard((*argin)[1]); tmp_name = replace_wildcard((*argin)[2]); // Get id list sql_query_stream << "SELECT DISTINCT id,date FROM property_pipe_device_hist WHERE device = \"" << tmp_device << "\" AND pipe LIKE \"" << tmp_pipe << "\" AND name LIKE \"" << tmp_name << "\" ORDER by date ASC"; { AutoLock al("LOCK TABLE property_pipe_device_hist READ",this); ids = query(sql_query_stream.str(),"db_get_device_pipe_property_hist()",al.get_con_nb()); // Retreive history int nb_item = 0; argout->length(0); for (unsigned int i=0; i> id; sql_query_stream.str(""); sql_query_stream << "SELECT DATE_FORMAT(date,'%Y-%m-%d %H:%i:%s'),value,pipe,name,count FROM property_pipe_device_hist WHERE id = \"" << id << "\" AND device = \"" << tmp_device << "\" ORDER BY count ASC"; result = query(sql_query_stream.str(),"db_get_device_pipe_property_hist()",al.get_con_nb()); int count = mysql_num_rows(result); row = mysql_fetch_row(result); int deleted = (atoi(row[4]) == 0); // count=0 for deleted property if(deleted) count = 0; char n_rows_str[256]; sprintf(n_rows_str,"%d",count); argout->length(nb_item+4+count); (*argout)[nb_item+0] = CORBA::string_dup(row[2]); (*argout)[nb_item+1] = CORBA::string_dup(row[3]); (*argout)[nb_item+2] = CORBA::string_dup(row[0]); (*argout)[nb_item+3] = CORBA::string_dup(n_rows_str); for(int j=0;jlength(n_rows*3); MYSQL_ROW row; if (n_rows > 0) { for (int i=0; i 0) { if ((row = mysql_fetch_row(result)) != NULL) { argout = CORBA::string_dup(row[0]); } } else { mysql_free_result(result); TangoSys_OMemStream o; o << "No host found for device \'" << argin << "\'"; string msg = o.str(); WARN_STREAM << msg << endl; Tango::Except::throw_exception((const char *)DB_DeviceNotDefined, msg, (const char *)"DataBase::db_get_device_host()"); } mysql_free_result(result); //C.S. 05-10-2004 return argout; } //-------------------------------------------------------------- /** * Method : DataBase::create_udate_mem_att() * Description : Update or create (if not already there) entry * in the property_attribute_device table for * memorized attribute. * Don't use the simple_query() method because * we need to know if the UPDATE done first has * modified something in DB and we need to keep the * same DB connection */ //-------------------------------------------------------------- void DataBase::create_update_mem_att(const Tango::DevVarStringArray *argin) { const char *tmp_device = (*argin)[0]; const char *tmp_attribute = (*argin)[2]; // // First the update // stringstream sql_query_stream; string tmp_escaped_string = escape_string((*argin)[6]); sql_query_stream << "UPDATE property_attribute_device SET value=\"" << tmp_escaped_string << "\" WHERE device=\"" << tmp_device << "\" AND attribute=\"" << tmp_attribute << "\" AND name=\"__value\" AND count=1"; DEBUG_STREAM << "DataBase::PutAttributeProperty2(): sql_query " << sql_query_stream.str() << endl; int con_nb = get_connection(); string sql_query = sql_query_stream.str(); if (mysql_real_query(conn_pool[con_nb].db, sql_query.c_str(),sql_query.length()) != 0) { stringstream o; WARN_STREAM << "DataBase::db_put_device_attribute_property2() failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o << "\n.The query was: " << sql_query << ends; release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),"Database::db_put_device_attribute_property2()"); } my_ulonglong nb_rows = mysql_affected_rows(conn_pool[con_nb].db); if (nb_rows == 0) { // // The update hasn't changed anything in DB (0 rows affected). This means that the property is not yet // created in DB. Therefore, create it now // sql_query_stream.str(""); sql_query_stream << "INSERT INTO property_attribute_device SET device=\'" << tmp_device << "\',attribute=\'" << tmp_attribute << "\',name=\'__value\',count=1,value=\'" << tmp_escaped_string << "\',updated=NOW(),accessed=NOW()"; DEBUG_STREAM << "DataBase::PutAttributeProperty(): sql_query " << sql_query_stream.str() << endl; sql_query = sql_query_stream.str(); if (mysql_real_query(conn_pool[con_nb].db, sql_query.c_str(),sql_query.length()) != 0) { stringstream o; WARN_STREAM << "DataBase::db_put_device_attribute_property2() failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o << "\n.The query was: " << sql_query << ends; release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),"Database::db_put_device_attribute_property2()"); } } release_connection(con_nb); } /*----- PROTECTED REGION END -----*/ // DataBase::namespace_ending } // namespace tango-9.2.5a/cppserver/database/DataBaseStateMachine.cpp0000644023471100065110000017756513034745007020171 00000000000000/*----- PROTECTED REGION ID(DataBaseStateMachine.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: DataBaseStateMachine.cpp 28921 2015-12-15 15:03:51Z pascal_verdier $"; //============================================================================= // // file : DataBaseStateMachine.cpp // // description : C++ source for the �name� and its alowed // methods for commands and attributes // // project : TANGO. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28921 $ // $Date: 2015-12-15 16:03:51 +0100 (Tue, 15 Dec 2015) $ // // $HeadURL:$ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /*----- PROTECTED REGION END -----*/ // DataBase::DataBaseStateMachine.cpp //================================================================ // States | Description //================================================================ namespace DataBase_ns { //================================================= // Attributes Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : DataBase::is_StoredProcedureRelease_allowed() * Description : Execution allowed for StoredProcedureRelease attribute */ //-------------------------------------------------------- bool DataBase::is_StoredProcedureRelease_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for StoredProcedureRelease attribute in read access. /*----- PROTECTED REGION ID(DataBase::StoredProcedureReleaseStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::StoredProcedureReleaseStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_average_allowed() * Description : Execution allowed for Timing_average attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_average_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_average attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_averageStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_averageStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_minimum_allowed() * Description : Execution allowed for Timing_minimum attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_minimum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_minimum attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_minimumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_minimumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_maximum_allowed() * Description : Execution allowed for Timing_maximum attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_maximum_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_maximum attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_maximumStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_maximumStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_calls_allowed() * Description : Execution allowed for Timing_calls attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_calls_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_calls attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_callsStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_callsStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_index_allowed() * Description : Execution allowed for Timing_index attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_index_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_index attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_indexStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_indexStateAllowed_READ return true; } //-------------------------------------------------------- /** * Method : DataBase::is_Timing_info_allowed() * Description : Execution allowed for Timing_info attribute */ //-------------------------------------------------------- bool DataBase::is_Timing_info_allowed(TANGO_UNUSED(Tango::AttReqType type)) { // Not any excluded states for Timing_info attribute in read access. /*----- PROTECTED REGION ID(DataBase::Timing_infoStateAllowed_READ) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::Timing_infoStateAllowed_READ return true; } //================================================= // Commands Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : DataBase::is_DbAddDevice_allowed() * Description : Execution allowed for DbAddDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbAddDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbAddDevice command. /*----- PROTECTED REGION ID(DataBase::DbAddDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbAddDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbAddServer_allowed() * Description : Execution allowed for DbAddServer attribute */ //-------------------------------------------------------- bool DataBase::is_DbAddServer_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbAddServer command. /*----- PROTECTED REGION ID(DataBase::DbAddServerStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbAddServerStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteAttributeAlias_allowed() * Description : Execution allowed for DbDeleteAttributeAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteAttributeAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteAttributeAlias command. /*----- PROTECTED REGION ID(DataBase::DbDeleteAttributeAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteAttributeAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteClassAttribute_allowed() * Description : Execution allowed for DbDeleteClassAttribute attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteClassAttribute_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteClassAttribute command. /*----- PROTECTED REGION ID(DataBase::DbDeleteClassAttributeStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteClassAttributeStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteClassAttributeProperty_allowed() * Description : Execution allowed for DbDeleteClassAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteClassAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteClassAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteClassAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteClassAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteClassProperty_allowed() * Description : Execution allowed for DbDeleteClassProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteClassProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteClassProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteClassPropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteClassPropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDevice_allowed() * Description : Execution allowed for DbDeleteDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDevice command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDeviceAlias_allowed() * Description : Execution allowed for DbDeleteDeviceAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDeviceAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDeviceAlias command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDeviceAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDeviceAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDeviceAttribute_allowed() * Description : Execution allowed for DbDeleteDeviceAttribute attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDeviceAttribute_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDeviceAttribute command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDeviceAttributeStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDeviceAttributeStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDeviceAttributeProperty_allowed() * Description : Execution allowed for DbDeleteDeviceAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDeviceAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDeviceAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDeviceAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDeviceAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDeviceProperty_allowed() * Description : Execution allowed for DbDeleteDeviceProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDeviceProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDeviceProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDevicePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDevicePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteProperty_allowed() * Description : Execution allowed for DbDeleteProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeletePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeletePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteServer_allowed() * Description : Execution allowed for DbDeleteServer attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteServer_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteServer command. /*----- PROTECTED REGION ID(DataBase::DbDeleteServerStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteServerStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteServerInfo_allowed() * Description : Execution allowed for DbDeleteServerInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteServerInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteServerInfo command. /*----- PROTECTED REGION ID(DataBase::DbDeleteServerInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteServerInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbExportDevice_allowed() * Description : Execution allowed for DbExportDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbExportDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbExportDevice command. /*----- PROTECTED REGION ID(DataBase::DbExportDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbExportDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbExportEvent_allowed() * Description : Execution allowed for DbExportEvent attribute */ //-------------------------------------------------------- bool DataBase::is_DbExportEvent_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbExportEvent command. /*----- PROTECTED REGION ID(DataBase::DbExportEventStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbExportEventStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetAliasDevice_allowed() * Description : Execution allowed for DbGetAliasDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetAliasDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetAliasDevice command. /*----- PROTECTED REGION ID(DataBase::DbGetAliasDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetAliasDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetAttributeAlias_allowed() * Description : Execution allowed for DbGetAttributeAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetAttributeAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetAttributeAlias command. /*----- PROTECTED REGION ID(DataBase::DbGetAttributeAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetAttributeAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetAttributeAliasList_allowed() * Description : Execution allowed for DbGetAttributeAliasList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetAttributeAliasList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetAttributeAliasList command. /*----- PROTECTED REGION ID(DataBase::DbGetAttributeAliasListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetAttributeAliasListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassAttributeList_allowed() * Description : Execution allowed for DbGetClassAttributeList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassAttributeList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassAttributeList command. /*----- PROTECTED REGION ID(DataBase::DbGetClassAttributeListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassAttributeListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassAttributeProperty_allowed() * Description : Execution allowed for DbGetClassAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetClassAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassAttributeProperty2_allowed() * Description : Execution allowed for DbGetClassAttributeProperty2 attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassAttributeProperty2_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassAttributeProperty2 command. /*----- PROTECTED REGION ID(DataBase::DbGetClassAttributeProperty2StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassAttributeProperty2StateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassAttributePropertyHist_allowed() * Description : Execution allowed for DbGetClassAttributePropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassAttributePropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassAttributePropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetClassAttributePropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassAttributePropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassForDevice_allowed() * Description : Execution allowed for DbGetClassForDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassForDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassForDevice command. /*----- PROTECTED REGION ID(DataBase::DbGetClassForDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassForDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassInheritanceForDevice_allowed() * Description : Execution allowed for DbGetClassInheritanceForDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassInheritanceForDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassInheritanceForDevice command. /*----- PROTECTED REGION ID(DataBase::DbGetClassInheritanceForDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassInheritanceForDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassList_allowed() * Description : Execution allowed for DbGetClassList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassList command. /*----- PROTECTED REGION ID(DataBase::DbGetClassListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassProperty_allowed() * Description : Execution allowed for DbGetClassProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassPropertyHist_allowed() * Description : Execution allowed for DbGetClassPropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassPropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassPropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassPropertyList_allowed() * Description : Execution allowed for DbGetClassPropertyList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassPropertyList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassPropertyList command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPropertyListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPropertyListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAlias_allowed() * Description : Execution allowed for DbGetDeviceAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAlias command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAliasList_allowed() * Description : Execution allowed for DbGetDeviceAliasList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAliasList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAliasList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAliasListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAliasListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAttributeList_allowed() * Description : Execution allowed for DbGetDeviceAttributeList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAttributeList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAttributeList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAttributeListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAttributeListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAttributeProperty_allowed() * Description : Execution allowed for DbGetDeviceAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAttributeProperty2_allowed() * Description : Execution allowed for DbGetDeviceAttributeProperty2 attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAttributeProperty2_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAttributeProperty2 command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAttributeProperty2StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAttributeProperty2StateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceAttributePropertyHist_allowed() * Description : Execution allowed for DbGetDeviceAttributePropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceAttributePropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceAttributePropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceAttributePropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceAttributePropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceClassList_allowed() * Description : Execution allowed for DbGetDeviceClassList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceClassList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceClassList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceClassListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceClassListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceDomainList_allowed() * Description : Execution allowed for DbGetDeviceDomainList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceDomainList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceDomainList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceDomainListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceDomainListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceExportedList_allowed() * Description : Execution allowed for DbGetDeviceExportedList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceExportedList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceExportedList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceExportedListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceExportedListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceFamilyList_allowed() * Description : Execution allowed for DbGetDeviceFamilyList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceFamilyList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceFamilyList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceFamilyListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceFamilyListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceInfo_allowed() * Description : Execution allowed for DbGetDeviceInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceInfo command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceList_allowed() * Description : Execution allowed for DbGetDeviceList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceWideList_allowed() * Description : Execution allowed for DbGetDeviceWideList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceWideList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceWideList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceWideListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceWideListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceMemberList_allowed() * Description : Execution allowed for DbGetDeviceMemberList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceMemberList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceMemberList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceMemberListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceMemberListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceProperty_allowed() * Description : Execution allowed for DbGetDeviceProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDevicePropertyHist_allowed() * Description : Execution allowed for DbGetDevicePropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDevicePropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDevicePropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDevicePropertyList_allowed() * Description : Execution allowed for DbGetDevicePropertyList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDevicePropertyList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDevicePropertyList command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePropertyListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePropertyListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDeviceServerClassList_allowed() * Description : Execution allowed for DbGetDeviceServerClassList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDeviceServerClassList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDeviceServerClassList command. /*----- PROTECTED REGION ID(DataBase::DbGetDeviceServerClassListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDeviceServerClassListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetExportdDeviceListForClass_allowed() * Description : Execution allowed for DbGetExportdDeviceListForClass attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetExportdDeviceListForClass_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetExportdDeviceListForClass command. /*----- PROTECTED REGION ID(DataBase::DbGetExportdDeviceListForClassStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetExportdDeviceListForClassStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetHostList_allowed() * Description : Execution allowed for DbGetHostList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetHostList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetHostList command. /*----- PROTECTED REGION ID(DataBase::DbGetHostListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetHostListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetHostServerList_allowed() * Description : Execution allowed for DbGetHostServerList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetHostServerList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetHostServerList command. /*----- PROTECTED REGION ID(DataBase::DbGetHostServerListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetHostServerListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetHostServersInfo_allowed() * Description : Execution allowed for DbGetHostServersInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetHostServersInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetHostServersInfo command. /*----- PROTECTED REGION ID(DataBase::DbGetHostServersInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetHostServersInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetInstanceNameList_allowed() * Description : Execution allowed for DbGetInstanceNameList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetInstanceNameList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetInstanceNameList command. /*----- PROTECTED REGION ID(DataBase::DbGetInstanceNameListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetInstanceNameListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetObjectList_allowed() * Description : Execution allowed for DbGetObjectList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetObjectList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetObjectList command. /*----- PROTECTED REGION ID(DataBase::DbGetObjectListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetObjectListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetProperty_allowed() * Description : Execution allowed for DbGetProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetPropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetPropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetPropertyHist_allowed() * Description : Execution allowed for DbGetPropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetPropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetPropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetPropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetPropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetPropertyList_allowed() * Description : Execution allowed for DbGetPropertyList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetPropertyList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetPropertyList command. /*----- PROTECTED REGION ID(DataBase::DbGetPropertyListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetPropertyListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetServerInfo_allowed() * Description : Execution allowed for DbGetServerInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetServerInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetServerInfo command. /*----- PROTECTED REGION ID(DataBase::DbGetServerInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetServerInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetServerList_allowed() * Description : Execution allowed for DbGetServerList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetServerList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetServerList command. /*----- PROTECTED REGION ID(DataBase::DbGetServerListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetServerListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetServerNameList_allowed() * Description : Execution allowed for DbGetServerNameList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetServerNameList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetServerNameList command. /*----- PROTECTED REGION ID(DataBase::DbGetServerNameListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetServerNameListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbImportDevice_allowed() * Description : Execution allowed for DbImportDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbImportDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbImportDevice command. /*----- PROTECTED REGION ID(DataBase::DbImportDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbImportDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbImportEvent_allowed() * Description : Execution allowed for DbImportEvent attribute */ //-------------------------------------------------------- bool DataBase::is_DbImportEvent_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbImportEvent command. /*----- PROTECTED REGION ID(DataBase::DbImportEventStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbImportEventStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbInfo_allowed() * Description : Execution allowed for DbInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbInfo command. /*----- PROTECTED REGION ID(DataBase::DbInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutAttributeAlias_allowed() * Description : Execution allowed for DbPutAttributeAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutAttributeAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutAttributeAlias command. /*----- PROTECTED REGION ID(DataBase::DbPutAttributeAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutAttributeAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutClassAttributeProperty_allowed() * Description : Execution allowed for DbPutClassAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutClassAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutClassAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutClassAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutClassAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutClassAttributeProperty2_allowed() * Description : Execution allowed for DbPutClassAttributeProperty2 attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutClassAttributeProperty2_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutClassAttributeProperty2 command. /*----- PROTECTED REGION ID(DataBase::DbPutClassAttributeProperty2StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutClassAttributeProperty2StateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutClassProperty_allowed() * Description : Execution allowed for DbPutClassProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutClassProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutClassProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutClassPropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutClassPropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutDeviceAlias_allowed() * Description : Execution allowed for DbPutDeviceAlias attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutDeviceAlias_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutDeviceAlias command. /*----- PROTECTED REGION ID(DataBase::DbPutDeviceAliasStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutDeviceAliasStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutDeviceAttributeProperty_allowed() * Description : Execution allowed for DbPutDeviceAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutDeviceAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutDeviceAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutDeviceAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutDeviceAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutDeviceAttributeProperty2_allowed() * Description : Execution allowed for DbPutDeviceAttributeProperty2 attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutDeviceAttributeProperty2_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutDeviceAttributeProperty2 command. /*----- PROTECTED REGION ID(DataBase::DbPutDeviceAttributeProperty2StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutDeviceAttributeProperty2StateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutDeviceProperty_allowed() * Description : Execution allowed for DbPutDeviceProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutDeviceProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutDeviceProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutDevicePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutDevicePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutProperty_allowed() * Description : Execution allowed for DbPutProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutPropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutPropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutServerInfo_allowed() * Description : Execution allowed for DbPutServerInfo attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutServerInfo_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutServerInfo command. /*----- PROTECTED REGION ID(DataBase::DbPutServerInfoStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutServerInfoStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbUnExportDevice_allowed() * Description : Execution allowed for DbUnExportDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbUnExportDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbUnExportDevice command. /*----- PROTECTED REGION ID(DataBase::DbUnExportDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbUnExportDeviceStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbUnExportEvent_allowed() * Description : Execution allowed for DbUnExportEvent attribute */ //-------------------------------------------------------- bool DataBase::is_DbUnExportEvent_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbUnExportEvent command. /*----- PROTECTED REGION ID(DataBase::DbUnExportEventStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbUnExportEventStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbUnExportServer_allowed() * Description : Execution allowed for DbUnExportServer attribute */ //-------------------------------------------------------- bool DataBase::is_DbUnExportServer_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbUnExportServer command. /*----- PROTECTED REGION ID(DataBase::DbUnExportServerStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbUnExportServerStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_ResetTimingValues_allowed() * Description : Execution allowed for ResetTimingValues attribute */ //-------------------------------------------------------- bool DataBase::is_ResetTimingValues_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for ResetTimingValues command. /*----- PROTECTED REGION ID(DataBase::ResetTimingValuesStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::ResetTimingValuesStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDataForServerCache_allowed() * Description : Execution allowed for DbGetDataForServerCache attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDataForServerCache_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDataForServerCache command. /*----- PROTECTED REGION ID(DataBase::DbGetDataForServerCacheStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDataForServerCacheStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteAllDeviceAttributeProperty_allowed() * Description : Execution allowed for DbDeleteAllDeviceAttributeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteAllDeviceAttributeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteAllDeviceAttributeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteAllDeviceAttributePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteAllDeviceAttributePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbMySqlSelect_allowed() * Description : Execution allowed for DbMySqlSelect attribute */ //-------------------------------------------------------- bool DataBase::is_DbMySqlSelect_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbMySqlSelect command. /*----- PROTECTED REGION ID(DataBase::DbMySqlSelectStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbMySqlSelectStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetCSDbServerList_allowed() * Description : Execution allowed for DbGetCSDbServerList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetCSDbServerList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetCSDbServerList command. /*----- PROTECTED REGION ID(DataBase::DbGetCSDbServerListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetCSDbServerListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetAttributeAlias2_allowed() * Description : Execution allowed for DbGetAttributeAlias2 attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetAttributeAlias2_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetAttributeAlias2 command. /*----- PROTECTED REGION ID(DataBase::DbGetAttributeAlias2StateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetAttributeAlias2StateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetAliasAttribute_allowed() * Description : Execution allowed for DbGetAliasAttribute attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetAliasAttribute_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetAliasAttribute command. /*----- PROTECTED REGION ID(DataBase::DbGetAliasAttributeStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetAliasAttributeStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbRenameServer_allowed() * Description : Execution allowed for DbRenameServer attribute */ //-------------------------------------------------------- bool DataBase::is_DbRenameServer_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbRenameServer command. /*----- PROTECTED REGION ID(DataBase::DbRenameServerStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbRenameServerStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassPipeProperty_allowed() * Description : Execution allowed for DbGetClassPipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassPipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassPipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDevicePipeProperty_allowed() * Description : Execution allowed for DbGetDevicePipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDevicePipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDevicePipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteClassPipe_allowed() * Description : Execution allowed for DbDeleteClassPipe attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteClassPipe_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteClassPipe command. /*----- PROTECTED REGION ID(DataBase::DbDeleteClassPipeStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteClassPipeStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDevicePipe_allowed() * Description : Execution allowed for DbDeleteDevicePipe attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDevicePipe_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDevicePipe command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDevicePipeStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDevicePipeStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteClassPipeProperty_allowed() * Description : Execution allowed for DbDeleteClassPipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteClassPipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteClassPipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteClassPipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteClassPipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteDevicePipeProperty_allowed() * Description : Execution allowed for DbDeleteDevicePipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteDevicePipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteDevicePipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteDevicePipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteDevicePipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassPipeList_allowed() * Description : Execution allowed for DbGetClassPipeList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassPipeList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassPipeList command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPipeListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPipeListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDevicePipeList_allowed() * Description : Execution allowed for DbGetDevicePipeList attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDevicePipeList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDevicePipeList command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePipeListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePipeListStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbDeleteAllDevicePipeProperty_allowed() * Description : Execution allowed for DbDeleteAllDevicePipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbDeleteAllDevicePipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbDeleteAllDevicePipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbDeleteAllDevicePipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbDeleteAllDevicePipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutClassPipeProperty_allowed() * Description : Execution allowed for DbPutClassPipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutClassPipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutClassPipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutClassPipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutClassPipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbPutDevicePipeProperty_allowed() * Description : Execution allowed for DbPutDevicePipeProperty attribute */ //-------------------------------------------------------- bool DataBase::is_DbPutDevicePipeProperty_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbPutDevicePipeProperty command. /*----- PROTECTED REGION ID(DataBase::DbPutDevicePipePropertyStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbPutDevicePipePropertyStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetClassPipePropertyHist_allowed() * Description : Execution allowed for DbGetClassPipePropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetClassPipePropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetClassPipePropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetClassPipePropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetClassPipePropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetDevicePipePropertyHist_allowed() * Description : Execution allowed for DbGetDevicePipePropertyHist attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetDevicePipePropertyHist_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetDevicePipePropertyHist command. /*----- PROTECTED REGION ID(DataBase::DbGetDevicePipePropertyHistStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetDevicePipePropertyHistStateAllowed return true; } //-------------------------------------------------------- /** * Method : DataBase::is_DbGetForwardedAttributeListForDevice_allowed() * Description : Execution allowed for DbGetForwardedAttributeListForDevice attribute */ //-------------------------------------------------------- bool DataBase::is_DbGetForwardedAttributeListForDevice_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for DbGetForwardedAttributeListForDevice command. /*----- PROTECTED REGION ID(DataBase::DbGetForwardedAttributeListForDeviceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBase::DbGetForwardedAttributeListForDeviceStateAllowed return true; } /*----- PROTECTED REGION ID(DataBase::DataBaseStateAllowed.AdditionalMethods) ENABLED START -----*/ // Additional Methods /*----- PROTECTED REGION END -----*/ // DataBase::DataBaseStateAllowed.AdditionalMethods } // End of namespace tango-9.2.5a/cppserver/database/main.cpp0000644023471100065110000001473713034745006015151 00000000000000/*PROTECTED REGION ID(DataBase::main.cpp) ENABLED START*/ static const char *RcsId = "$Id: main.cpp 26081 2014-07-17 15:02:38Z taurel $"; //============================================================================= // // file : DataBase.cpp // // description : C++ source for the DataBase device server main. // The main rule is to initialise (and create) the Tango // system and to create the DServerClass singleton. // The main should be the same for every Tango device server. // // project : TANGO. // // $Author: taurel $ // // $Revision: 26081 $ // $Date: 2014-07-17 17:02:38 +0200 (Thu, 17 Jul 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source: $ // $Log: $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // #include #include #include #ifndef WIN32 #include #endif int DataBase_ns::DataBase::conn_pool_size; int main(int argc,char *argv[]) { cout << "main(): arrived " << endl; Tango::Util *tango_util; Tango::Util::_UseDb = false; // suppress database use #ifndef WIN32 // Setting maximum number of opened file // Default limit struct rlimit limit; limit.rlim_cur = 1024; limit.rlim_max = 1024; // Browse argv and try to find the -maxFile option int found = 0; int i = 0; while(i=argc-1) { cout << "Invalid flimit parameter." << endl; return -1; } int flimit = atoi(argv[i+1]); if(flimit==0) { cout << "Invalid flimit parameter." << endl; return -1; } limit.rlim_cur = flimit; limit.rlim_max = flimit; } // Apply the max open file limit if( setrlimit(RLIMIT_NOFILE,&limit) != 0 ) { cout << "setrlimit(RLIMIT_NOFILE," << (int)limit.rlim_cur << ") failed." << endl; if(errno==EPERM) { cout << "You may need to increase maximum number of opened file system limit." << endl; } else { cout << "setrlimit() failed with error code : " << (int)errno << endl; } return -1; } #endif // Browse argv and try to find the -connPoolSize option int j = 0; int found_conn = 0; int conn_size = DEFAULT_CONN_POOL_SIZE; while(j=argc-1) { cout << "Invalid poolSize parameter." << endl; return -1; } conn_size = atoi(argv[j+1]); if(conn_size<=0) { cout << "Invalid poolSize parameter." << endl; return -1; } } DataBase_ns::DataBase::set_conn_pool_size(conn_size); try { // // Initialise the device server // cout1 << "main(): calling Tango::Util::Init(argc,argv)" << endl; tango_util = Tango::Util::init(argc,argv); // construct database name DataBase_ns::DataBase::db_name = "sys/database/"; DataBase_ns::DataBase::db_name.append(argv[1]); cout1 << "main(): create DataBase " << DataBase_ns::DataBase::db_name << endl; // // Create and install interceptors // DataBase_ns::DbInter *dbi = new DataBase_ns::DbInter(); tango_util->set_interceptors(dbi); // // Set the serialization method // tango_util->set_serial_model(Tango::NO_SYNC); // // Create the device server singleton which will create everything // cout1 << "main(): calling tango_util->server_init()" << endl; tango_util->server_init(); // // Export devices to the outside world as CORBA named servant and to TANGO // database // Tango::DeviceImpl *dbase, *dserver; Tango::DevVarStringArray *export_parms = new Tango::DevVarStringArray(); dserver = tango_util->get_dserver_device(); dbase = tango_util->get_device_by_name(DataBase_ns::DataBase::db_name); // // export database as named servant // cout << "main(): export DataBase as named servant (name=database)" << endl; export_parms->length(5); // export dserver object to TANGO database Tango::Device_var d = dserver->_this(); dserver->set_d_var(Tango::Device::_duplicate(d)); (*export_parms)[0] = CORBA::string_dup(dserver->get_name().c_str()); const char *dserver_str_ior = Tango::Util::instance()->get_orb()->object_to_string(d); (*export_parms)[1] = CORBA::string_dup(dserver_str_ior); delete [] dserver_str_ior; (*export_parms)[2] = CORBA::string_dup(tango_util->get_host_name().c_str()); (*export_parms)[3] = CORBA::string_dup(tango_util->get_pid_str().c_str()); (*export_parms)[4] = CORBA::string_dup(tango_util->get_version_str().c_str()); (static_cast(dbase))->db_export_device(export_parms); // export database object to TANGO database (*export_parms)[0] = CORBA::string_dup(dbase->get_name().c_str()); const char *str_ior = Tango::Util::instance()->get_orb()->object_to_string(dbase->get_d_var()); (*export_parms)[1] = CORBA::string_dup(str_ior); delete [] str_ior; ((DataBase_ns::DataBase*)dbase)->db_export_device(export_parms); delete export_parms; // // Run the endless loop // cout << "Ready to accept request" << endl; (tango_util->get_orb())->run(); } catch (bad_alloc) { cout << "Can't allocate memory to store device object !!!" << endl; cout << "Exiting" << endl; } catch (CORBA::Exception &e) { cout << "Received a CORBA::Exception" << endl; Tango::Except::print_exception(e); cout << "Exiting" << endl; } return(0); } /*PROTECTED REGION END*/ // DataBase::main.cpp tango-9.2.5a/cppserver/database/update_starter.cpp0000644023471100065110000001024113034745007017236 00000000000000//============================================================================= // // file : update_starter.cpp // // description : thread to inform Strater to update from database // in case of controlled servers list modification. // // project : Starter for Tango Administration // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 22233 $ // $Date: 2013-03-08 13:35:56 +0100 (Fri, 08 Mar 2013) $ // // $HeadURL:$ // //============================================================================= #include namespace DataBase_ns { //============================================================================= //============================================================================= UpdStarterData::UpdStarterData() { /* starter_devnames[0] = ""; starter_devnames[1] = ""; */ } //============================================================================= //============================================================================= vector UpdStarterData::get_starter_devname() { omni_mutex_lock sync(*this); return starter_devnames; } //============================================================================= //============================================================================= void UpdStarterData::send_starter_cmd(vector hostname) { omni_mutex_lock sync(*this); // Build starter devices to update starter_devnames.clear(); for (unsigned int i=0 ; i devnames = shared->get_starter_devname(); for (unsigned int i=0 ; icommand_inout("UpdateServersInfo"); cout << "dev->command_inout(UpdateServersInfo) sent to " << devnames[i] << endl; } catch(Tango::DevFailed &e) { //Tango::Except::print_exception(e); cout << e.errors[0].desc << endl; } delete dev; } } // Wait until next command. { omni_mutex_lock sync(*shared); shared->wait(); } cout2 << "Thread update_starter awaken !" << endl; } return NULL; } //============================================================================= //============================================================================= } // namespace tango-9.2.5a/cppserver/database/DataBaseUtils.cpp0000755023471100065110000007477613034745007016727 00000000000000static const char *RcsId = "$Header$"; //+============================================================================= // // file : DataBaseUtils.cpp // // description : Various utility for the DataBase. // // project : TANGO Device Servers // // author(s) : A.Gotz, P.Verdier, JL Pons // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 30129 $ // $Date: 2016-09-06 15:57:58 +0200 (Tue, 06 Sep 2016) $ // // $HeadURL:$ // //============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #ifdef _TG_WINDOWS_ #include #else #include #include #include #include #endif using namespace std; namespace DataBase_ns { //+---------------------------------------------------------------------------- // // method : DataBase::replace_wildcard(char *wildcard_c_str) // // description : utility method to replace all occurrences of // wildcards (*) with SQL wildcards % and to escape // all occurrences of '%' and '_' with '\' // // in : string **wildcard_c_str - wildcard C string // // out : void - nothing // //----------------------------------------------------------------------------- string DataBase::replace_wildcard(const char *wildcard_c_str) { string wildcard(wildcard_c_str); string::size_type index; DEBUG_STREAM << "DataBase::replace_wildcard() wildcard in " << wildcard << endl; // escape % index = 0; while ((index = wildcard.find('%',index)) != string::npos) { wildcard.insert(index, 1, '\\'); index = index+2; } // escape _ index = 0; while ((index = wildcard.find('_',index)) != string::npos) { wildcard.insert(index, 1, '\\'); index = index+2; } // escape " index = 0; while ((index = wildcard.find('"',index)) != string::npos) { wildcard.insert(index, 1, '\\'); index = index+2; } // escape ' index = 0; while ((index = wildcard.find('\'',index)) != string::npos) { wildcard.insert(index, 1, '\\'); index = index+2; } // replace wildcard * with % while ((index = wildcard.find('*')) != string::npos) { wildcard.replace(index, 1, 1, '%'); } DEBUG_STREAM << "DataBase::replace_wildcard() wildcard out " << wildcard << endl; return wildcard; } //+---------------------------------------------------------------------------- // // method : DataBase::escape_string(char *string_c_str) // // description : utility method to escape all occurrences // of ' and " with '\' // // in : const char *string_c_str - C string to be modified. // // out : string - The result string . // //----------------------------------------------------------------------------- string DataBase::escape_string(const char *string_c_str) { string escaped_string(string_c_str); string::size_type index; DEBUG_STREAM << "DataBase::escape_string() string in : " << escaped_string << endl; // escape bakckslash index = 0; while ((index = escaped_string.find('\\',index)) != string::npos) { // Check if double backslash already treated by client string s = escaped_string.substr(index+1); // Check if another escape sequence treated by client if (s.find('\"')==0 || s.find('\'')==0) index++; else { escaped_string.insert(index, 1, '\\'); index += 2; } } // escape " index = 0; while ((index = escaped_string.find('"',index)) != string::npos) { if (index==0) // Cannot have '\' at -1 ! { escaped_string.insert(index, 1, '\\'); index += 2; } else { // Check if double quotes already treated by client string s = escaped_string.substr(index-1); if (s.find('\\')==0) index++; else { escaped_string.insert(index, 1, '\\'); index += 2; } } } // escape ' index = 0; while ((index = escaped_string.find('\'',index)) != string::npos) { if (index==0) // Cannot have '\' at -1 ! { escaped_string.insert(index, 1, '\\'); index += 2; } else { // Check if simple quotes already treated by client string s = escaped_string.substr(index-1); if (s.find('\\')==0) index++; else { escaped_string.insert(index, 1, '\\'); index += 2; } } } DEBUG_STREAM << "DataBase::escaped_string() wildcard out : " << escaped_string << endl; return escaped_string; } //+---------------------------------------------------------------------------- // // method : DataBase::device_name_to_dfm(string &device_name, // char **domain, char **family, char **member) // // description : utility function to return domain, family and member // from device name. Assumes device name has (optional) // protocol and instance stripped off i.e. conforms // to domain/family/member // // in : char *devname - device name // // out : bool - true or false // //----------------------------------------------------------------------------- bool DataBase::device_name_to_dfm(string &devname, char domain[], char family[], char member[]) { string::size_type index, index2; DEBUG_STREAM << "DataBase::device_name_to_dfm() device name in " << devname << endl; index = devname.find('/'); index2 = devname.find('/', index+1); (devname.substr(0,index)).copy(domain,index); domain[index] = '\0'; (devname.substr(index+1,index2-index)).copy(family,index2-index); family[index2-index-1] = '\0'; (devname.substr(index2+1)).copy(member,devname.length()-index2); member[devname.length()-index2-1] = '\0'; DEBUG_STREAM << "DataBase::device_name_to_dfm() domain/family/member out " << domain << "/" << family << "/" << member << endl; return true; } //+---------------------------------------------------------------------------- // // method : DataBase::check_device_name(string *device_name) // // description : utility function to check whether device name conforms // to the TANGO naming convention of // // [tango!taco:][//instance/]domain/family/member // // in : string *device_name - device name // // out : bool - true or false // //----------------------------------------------------------------------------- bool DataBase::check_device_name(string &device_name_str) { string devname(device_name_str); string::size_type index, index2; DEBUG_STREAM << "DataBase::check_device_name(): device_name in " << devname << endl; // check there are no special characters which could be interpreted // as wildcards or which are otherwise excluded if (devname.find('*') != string::npos) return false; // check protocol - "tango:" | "taco:" if (devname.substr(0,6) == "tango:") { devname.erase(0,6); } else { if (devname.substr(0,5) == "taco:") { devname.erase(0,5); } } // check instance - "//instance/" if (devname.substr(0,2) == "//") { index = devname.find('/',(string::size_type)2); if (index == 0 || index == string::npos) { return false; } devname.erase(0,index+1); } // check name conforms to "D/F/M" index = devname.find('/'); index2 = devname.find('/',index+1); if (index == 0 || index == string::npos || index2 == string::npos || index2-index <= 0 || devname.length() - index2 <= 0) { return false; } device_name_str = devname; DEBUG_STREAM << "DataBase::check_device_name(): device_name out " << device_name_str << endl; return true; } //+------------------------------------------------------------------ /** * method: DataBase::init_timing_stats * * description: method to initialise the timing statistics variables * Returns void * * @param none * @return void * */ //+------------------------------------------------------------------ void DataBase::init_timing_stats() { TimingStatsStruct new_timing_stats = {0.0, 0.0, 0.0, 0.0, 0.0}; timing_stats_mutex.lock(); timing_stats_map["DbImportDevice"] = new TimingStatsStruct; timing_stats_map["DbExportDevice"] = new TimingStatsStruct; timing_stats_map["DbGetHostServerList"] = new TimingStatsStruct; timing_stats_map["DbGetHostList"] = new TimingStatsStruct; timing_stats_map["DbGetServerList"] = new TimingStatsStruct; timing_stats_map["DbGetDevicePropertyList"] = new TimingStatsStruct; timing_stats_map["DbGetClassPropertyList"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceMemberList"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceFamilyList"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceDomainList"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceProperty"] = new TimingStatsStruct; timing_stats_map["DbPutDeviceProperty"] = new TimingStatsStruct; timing_stats_map["DbDeleteDeviceProperty"] = new TimingStatsStruct; timing_stats_map["DbInfo"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceClassList"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceAttributeProperty"] = new TimingStatsStruct; timing_stats_map["DbPutDeviceAttributeProperty"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceAttributeProperty2"] = new TimingStatsStruct; timing_stats_map["DbPutDeviceAttributeProperty2"] = new TimingStatsStruct; timing_stats_map["DbUnExportServer"] = new TimingStatsStruct; timing_stats_map["DbGetDeviceExportedList"] = new TimingStatsStruct; timing_stats_map["DbExportEvent"] = new TimingStatsStruct; timing_stats_map["DbImportEvent"] = new TimingStatsStruct; timing_stats_map["DbGetDataForServerCache"] = new TimingStatsStruct; timing_stats_map["DbPutClassProperty"] = new TimingStatsStruct; timing_stats_map["DbMySqlSelect"] = new TimingStatsStruct; timing_stats_map["DbGetDevicePipeProperty"] = new TimingStatsStruct; timing_stats_map["DbPutDevicePipeProperty"] = new TimingStatsStruct; timing_stats_size = timing_stats_map.size(); timing_stats_average = new double[timing_stats_size]; timing_stats_minimum = new double[timing_stats_size]; timing_stats_maximum = new double[timing_stats_size]; timing_stats_calls = new double[timing_stats_size]; timing_stats_index = new Tango::DevString[timing_stats_size]; // now loop over map and initialise remaining variables std::map::iterator iter; int i=0; for (iter = timing_stats_map.begin(); iter != timing_stats_map.end(); iter++) { *(iter->second) = new_timing_stats; timing_stats_index[i] = (char*)malloc(strlen(iter->first.c_str())+1); strcpy(timing_stats_index[i],iter->first.c_str()); i++; } timing_stats_mutex.unlock(); } //+---------------------------------------------------------------------------- // // method : DataBase::check_history_tables() // // description : Return history id // //----------------------------------------------------------------------------- void DataBase::check_history_tables() { TangoSys_MemStream sql_query_stream; MYSQL_RES *result; INFO_STREAM << "DataBase::check_history_tables(): entering" << endl; sql_query_stream.str(""); sql_query_stream << "SELECT count(*) FROM property_device_hist"; DEBUG_STREAM << "DataBase::check_history_tables(): sql_query " << sql_query_stream.str() << endl; result = query(sql_query_stream.str(),"check_history_tables()"); mysql_free_result(result); } //+---------------------------------------------------------------------------- // // method : DataBase::get_id() // // description : Return history id // In this method, we don't use the classical query() // method in order to be sure that the UPDATE and the following // mysql_insert_id() are done using the same MySQL connection // //----------------------------------------------------------------------------- Tango::DevULong64 DataBase::get_id(const char *name,int con_nb) { TangoSys_MemStream sql_query; // // If no MySQL connection passed to this method, // get one // bool need_release = false; if (con_nb == -1) { con_nb = get_connection(); need_release = true; } sql_query.str(""); sql_query << "UPDATE " << name << "_history_id SET id=LAST_INSERT_ID(id+1)"; string tmp_str = sql_query.str(); if (mysql_real_query(conn_pool[con_nb].db, tmp_str.c_str(),tmp_str.length()) != 0) { TangoSys_OMemStream o; WARN_STREAM << "DataBase::get_id() failed to query TANGO database:" << endl; WARN_STREAM << " query = " << tmp_str << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")" << ends; if (need_release == true) release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),(const char *)"DataBase::get_id()"); } my_ulonglong val = mysql_insert_id(conn_pool[con_nb].db); if (val == 0) { TangoSys_OMemStream o; o << "Failed to get history id : " << name; if (need_release == true) release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),(const char *)"DataBase::get_id()"); } if (need_release == true) release_connection(con_nb); return (Tango::DevULong64)val; } //+---------------------------------------------------------------------------- // // method : DataBase::simple_query() // // description : Execute a SQL query , ignore the result. // //----------------------------------------------------------------------------- void DataBase::simple_query(string sql_query,const char *method,int con_nb) { // // If no MySQL connection passed to this method, // get one // bool need_release = false; if (con_nb == -1) { con_nb = get_connection(); need_release = true; } DEBUG_STREAM << "Using MySQL connection with semaphore " << con_nb << endl; // // Call MySQL // if (mysql_real_query(conn_pool[con_nb].db, sql_query.c_str(),sql_query.length()) != 0) { TangoSys_OMemStream o; TangoSys_OMemStream o2; WARN_STREAM << "DataBase::" << method << " failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o << "\n.The query was: " << sql_query << ends; o2 << "DataBase::" << method << ends; if (need_release == true) release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),o2.str()); } if (need_release) release_connection(con_nb); } //+---------------------------------------------------------------------------- // // method : DataBase::query() // // description : Execute a SQL query and return the result. // //----------------------------------------------------------------------------- MYSQL_RES *DataBase::query(string sql_query,const char *method,int con_nb) { MYSQL_RES *result; // // If no MySQL connection passed to this method, // get one // bool need_release = false; if (con_nb == -1) { con_nb = get_connection(); need_release = true; } DEBUG_STREAM << "Using MySQL connection with semaphore " << con_nb << endl; // // Call MySQL // if (mysql_real_query(conn_pool[con_nb].db, sql_query.c_str(),sql_query.length()) != 0) { TangoSys_OMemStream o; TangoSys_OMemStream o2; WARN_STREAM << "DataBase::" << method << " failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o << "\nThe query was: " << sql_query << ends; o2 << "DataBase::" << method << ends; if (need_release == true) release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),o2.str()); } if ((result = mysql_store_result(conn_pool[con_nb].db)) == NULL) { TangoSys_OMemStream o; TangoSys_OMemStream o2; WARN_STREAM << "DataBase:: " << method << " : mysql_store_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")" << endl; o << "mysql_store_result() failed (error=" << mysql_error(conn_pool[con_nb].db) << ")"; o2 << "DataBase::" << method; if (need_release == true) release_connection(con_nb); Tango::Except::throw_exception((const char *)DB_SQLError,o.str(),o2.str()); } if (need_release) release_connection(con_nb); return result; } //+---------------------------------------------------------------------------- // // method : DataBase::get_connection() // // description : Get a MySQl connection from the connection pool // //----------------------------------------------------------------------------- int DataBase::get_connection() { // // Get a MySQL connection and lock it // If none available, wait for one // int loop = 0; while (conn_pool[loop].the_sema.trywait() == 0) { loop++; if (loop == conn_pool_size) { int sem_to_wait; { omni_mutex_lock oml(sem_wait_mutex); sem_to_wait = last_sem_wait++; if (last_sem_wait == conn_pool_size) last_sem_wait = 0; } loop = sem_to_wait; WARN_STREAM << "Waiting for one free MySQL connection on semaphore " << loop << endl; conn_pool[loop].the_sema.wait(); break; } } return loop; } //+------------------------------------------------------------------ /** * method: purge_property() * * description: purge a property history table. * */ //+------------------------------------------------------------------ void DataBase::purge_property(const char *table,const char *field,const char *object,const char *name,int con_nb) { TangoSys_MemStream sql_query; MYSQL_RES *result; MYSQL_ROW row2; sql_query.str(""); sql_query << "SELECT DISTINCT id,date FROM " << table << " WHERE " << field << "=\"" << object << "\" AND name=\"" << name << "\" ORDER by date"; result = query(sql_query.str(),"purge_property()",con_nb); int nb_item = mysql_num_rows(result); if(nb_item>historyDepth) { // Purge int toDelete = nb_item-historyDepth; for(int j=0;jhistoryDepth) { // Purge int toDelete = nb_item-historyDepth; for(int j=0;jhistoryDepth) { // Purge int toDelete = nb_item-historyDepth; for(int j=0;j 50000) //C. Scafuri: auto reconnection has been off since 5.0.3. From 5.0.13 it is possible to set it as an option // with reconnection enabled DataBase keeps working after timeouts and mysql shutdown/restart if(mysql_get_client_version() >= 50013) { my_bool my_auto_reconnect=1; if (mysql_options(conn_pool[loop].db,MYSQL_OPT_RECONNECT,&my_auto_reconnect) !=0) { ERROR_STREAM << "DataBase: error setting mysql auto reconnection: " << mysql_error(conn_pool[loop].db) << endl; } else { WARN_STREAM << "DataBase: set mysql auto reconnect to true" << endl; } } #endif } //+------------------------------------------------------------------ /** * method: create_connection_pool() * * description: Create the MySQL connections pool * */ //+------------------------------------------------------------------ void DataBase::create_connection_pool(const char *mysql_user, const char *mysql_password, const char *mysql_host, const char *mysql_name) { #ifndef HAVE_CONFIG_H char *database = (char *)"tango"; #else char *database = (char *)TANGO_DB_NAME; #endif // // Init MySQL db name (locally and as data member) // if (mysql_name != NULL) { database = const_cast(mysql_name); } mysql_db_name = database; // // Check on provided MySQl user and password // if (mysql_user != NULL && mysql_password != NULL) { WARN_STREAM << "DataBase::create_connection_pool(): mysql database user = " << mysql_user << " , password = " << mysql_password << endl; } const char *host; string my_host; string ho,port; unsigned int port_num = 0; if (mysql_host != NULL) { my_host = mysql_host; WARN_STREAM << "DataBase::create_connection_pool(): mysql host = " << mysql_host << endl; string::size_type pos = my_host.find(':'); if (pos != string::npos) { ho = my_host.substr(0,pos); pos++; port = my_host.substr(pos); stringstream ss(port); ss >> port_num; if (!ss) port_num = 0; host = ho.c_str(); } else host = my_host.c_str(); WARN_STREAM << "DataBase::create_connection_pool(): mysql host = " << host << ", port = " << port_num << endl; } else host = NULL; for (int loop = 0;loop < conn_pool_size;loop++) { base_connect(loop); // // Inmplement a retry. On some OS (Ubuntu 10.10), it may happens that MySQl needs some time to start. // This retry should cover this case // We also have to support case when this server is started while mysql is not ready yet // (this has been experienced on Ubuntu after a reboot when the ureadahead cache being invalidated // by a package installing file in /etc/init.d // Bloody problem!!! // WARN_STREAM << "Going to connect to MySQL for conn. " << loop << endl; if (!mysql_real_connect(conn_pool[loop].db, host, mysql_user, mysql_password, database, port_num, NULL, CLIENT_MULTI_STATEMENTS | CLIENT_FOUND_ROWS)) { if (loop == 0) { int retry = 5; while (retry > 0) { sleep(1); int db_err = mysql_errno(conn_pool[loop].db); WARN_STREAM << "Connection to MySQL failed with error " << db_err << endl; if (db_err == CR_CONNECTION_ERROR || db_err == CR_CONN_HOST_ERROR) { mysql_close(conn_pool[loop].db); conn_pool[loop].db = NULL; base_connect(loop); } WARN_STREAM << "Going to retry to connect to MySQL for connection " << loop << endl; if (!mysql_real_connect(conn_pool[loop].db, host, mysql_user, mysql_password, database, port_num, NULL, CLIENT_MULTI_STATEMENTS | CLIENT_FOUND_ROWS)) { WARN_STREAM << "Connection to MySQL (re-try) failed with error " << mysql_errno(conn_pool[loop].db) << endl; retry--; if (retry == 0) { WARN_STREAM << "Throw exception because no MySQL connection possible after 5 re-tries" << endl; TangoSys_MemStream out_stream; out_stream << "Failed to connect to TANGO database (error = " << mysql_error(conn_pool[loop].db) << ")" << ends; Tango::Except::throw_exception((const char *)"CANNOT_CONNECT_MYSQL", out_stream.str(), (const char *)"DataBase::init_device()"); } } else { WARN_STREAM << "MySQL connection succeed after retry" << endl; retry = 0; } } } else { WARN_STREAM << "Failed to connect to MySQL for conn. " << loop << ". No re-try in this case" << endl; TangoSys_MemStream out_stream; out_stream << "Failed to connect to TANGO database (error = " << mysql_error(conn_pool[loop].db) << ")" << ends; Tango::Except::throw_exception((const char *)"CANNOT_CONNECT_MYSQL", out_stream.str(), (const char *)"DataBase::init_device()"); } } } mysql_svr_version = mysql_get_server_version(conn_pool[0].db); last_sem_wait = 0; } //+------------------------------------------------------------------ /** * method: host_port_from_ior() * * description: Get host and port from a device IOR * */ //+------------------------------------------------------------------ bool DataBase::host_port_from_ior(const char *iorstr,string &h_p) { size_t s = (iorstr ? strlen(iorstr) : 0); if (s < 4) return false; const char *p = iorstr; if (p[0] != 'I' || p[1] != 'O' || p[2] != 'R' || p[3] != ':') return false; s = (s - 4) / 2; // how many octets are there in the string p += 4; cdrMemoryStream buf((CORBA::ULong)s,0); for (int i=0; i<(int)s; i++) { int j = i*2; CORBA::Octet v; if (p[j] >= '0' && p[j] <= '9') { v = ((p[j] - '0') << 4); } else if (p[j] >= 'a' && p[j] <= 'f') { v = ((p[j] - 'a' + 10) << 4); } else if (p[j] >= 'A' && p[j] <= 'F') { v = ((p[j] - 'A' + 10) << 4); } else return false; if (p[j+1] >= '0' && p[j+1] <= '9') { v += (p[j+1] - '0'); } else if (p[j+1] >= 'a' && p[j+1] <= 'f') { v += (p[j+1] - 'a' + 10); } else if (p[j+1] >= 'A' && p[j+1] <= 'F') { v += (p[j+1] - 'A' + 10); } else return false; buf.marshalOctet(v); } buf.rewindInputPtr(); CORBA::Boolean b = buf.unmarshalBoolean(); buf.setByteSwapFlag(b); IOP::IOR ior; ior.type_id = IOP::IOR::unmarshaltype_id(buf); ior.profiles <<= buf; if (ior.profiles.length() == 0 && strlen(ior.type_id) == 0) { return false; } else { for (unsigned long count=0; count < ior.profiles.length(); count++) { if (ior.profiles[count].tag == IOP::TAG_INTERNET_IOP) { IIOP::ProfileBody pBody; IIOP::unmarshalProfile(ior.profiles[count],pBody); // // Three possible cases for host name: // 1 - The host is stored in IOR as IP numbers // 2 - The host name is stored in IOR as the canonical host name // 3 - The FQDN is stored in IOR // We allways try to get the host name as the FQDN // ho = pBody.address.host.in(); bool host_is_name = false; string::size_type pos = ho.find('.'); if (pos == string::npos) host_is_name = true; else { for (unsigned int loop =0;loop < pos;++loop) { if (isdigit((int)ho[loop]) == 0) { host_is_name = true; break; } } } if (host_is_name == false) { struct sockaddr_in s; char service[20]; s.sin_family = AF_INET; int res; #ifdef _TG_WINDOWS_ s.sin_addr.s_addr = inet_addr(ho.c_str()); if (s.sin_addr.s_addr != INADDR_NONE) #else res = inet_pton(AF_INET,ho.c_str(),&(s.sin_addr.s_addr)); if (res == 1) #endif { res = getnameinfo((const struct sockaddr *)&s,sizeof(s),ho_name,sizeof(ho_name),service,sizeof(service),0); if (res == 0) { h_p = ho_name; h_p = h_p + ':'; } else h_p = ho + ':'; } else h_p = ho + ':'; } else { if (pos == string::npos) { Tango::DeviceProxy::get_fqdn(ho); } h_p = ho + ':'; } // // Add port number // stringstream ss; ss << pBody.address.port; h_p = h_p + ss.str(); break; } } } return true; } //+------------------------------------------------------------------ /** * method: AutoLock class ctor and dtor * * description: AutoLock is a small helper class which get a * MySQL connection from the pool and which lock * table(s). The exact lock statemen is passed to the * ctor as a parameter * The dtor release the table(s) lock * */ //+------------------------------------------------------------------ AutoLock::AutoLock(const char *lock_cmd,DataBase *db):the_db(db) { con_nb = the_db->get_connection(); TangoSys_MemStream sql_query_stream; sql_query_stream << lock_cmd; try { the_db->simple_query(sql_query_stream.str(),"AutoLock",con_nb); } catch (...) { the_db->release_connection(con_nb); throw; } } AutoLock::~AutoLock() { TangoSys_MemStream sql_query_stream; sql_query_stream << "UNLOCK TABLES"; the_db->simple_query(sql_query_stream.str(),"~AutoLock",con_nb); the_db->release_connection(con_nb); } } tango-9.2.5a/cppserver/database/DataBase.h0000644023471100065110000016563713034745006015344 00000000000000/*----- PROTECTED REGION ID(DataBase.h) ENABLED START -----*/ //============================================================================= // // file : DataBase.h // // description : Include for the DataBase class. // // project : TANGO Database server. // // $Author: taurel $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 29137 $ // $Date: 2016-02-08 14:23:41 +0100 (Mon, 08 Feb 2016) $ // // $HeadURL:$ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef DATABASE_H #define DATABASE_H #include #ifdef WIN32 #include #endif #include #include #define DB_SQLError "DB_SQLError" #define DB_IncorrectArguments "DB_IncorrectArguments" #define DB_IncorrectDeviceName "DB_IncorrectDeviceName" #define DB_IncorrectServerName "DB_IncorrectServerName" #define DB_DeviceNotDefined "DB_DeviceNotDefined" #define DB_AliasNotDefined "DB_AliasNotDefined" #define DB_NoFreeMySQLConnection "DB_NoFreeMySQLConnection" #define DB_MySQLLibNotThreadSafe "DB_MySQLLibNotThreadSafe" #define STARTER_DEVNAME_HEADER "tango/admin/" #define DEFAULT_CONN_POOL_SIZE 20 // Define time measuremnt type (depends on OS) #ifndef WIN32 # define TimeVal struct timeval # define GetTime(t) gettimeofday(&t, NULL); # define Elapsed(before, after) \ 1000.0*(after.tv_sec-before.tv_sec) + \ ((double)after.tv_usec-before.tv_usec) / 1000 #else static LARGE_INTEGER cpu_freq; # define TimeVal LARGE_INTEGER # define GetTime(t) w_gettimeofday(&t); # define Elapsed(before, after) \ (cpu_freq.QuadPart==0) ? 0.0 : \ (double) (after.QuadPart - before.QuadPart)/cpu_freq.QuadPart * 1000; #endif /* WIN32 */ /*----- PROTECTED REGION END -----*/ // DataBase.h /** * DataBase class description: * This class manage the TANGO database. */ namespace DataBase_ns { /*----- PROTECTED REGION ID(DataBase::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations class DummyDev: public Tango::Connection { public: DummyDev():Tango::Connection(true) {}; virtual string get_corba_name(bool) {string str;return str;} virtual string build_corba_name() {string str;return str;} virtual int get_lock_ctr() {return 0;} virtual void set_lock_ctr(int) {}; virtual string dev_name() {string str;return str;} int get_env_var(const char *cc,string &str_ref) {return Tango::Connection::get_env_var(cc,str_ref);} }; /*----- PROTECTED REGION END -----*/ // DataBase::Additional Class Declarations class DataBase : public TANGO_BASE_CLASS { /*----- PROTECTED REGION ID(DataBase::Data Members) ENABLED START -----*/ // Add your own data members public: /** * current incarnation of database */ static string db_name; /** * Will be set by property of Default object */ bool fireToStarter; /** * Database value history depth */ int historyDepth; /** * Shared data for update starter thread */ UpdStarterData *starter_shared; /** * update starter thread instance */ UpdateStarter *upd_starter_thread; /* * timing related variables */ typedef struct timing_stats_struct { double calls; double total_elapsed; double average; double minimum; double maximum; } TimingStatsStruct; map timing_stats_map; int timing_stats_size; double *timing_stats_average; double *timing_stats_minimum; double *timing_stats_maximum; double *timing_stats_calls; char **timing_stats_index; /* * For the DbGetDeviceAttributeProperty2 command */ typedef struct prop_def { string prop_name; string prop_name_cd; vector prop_val; } PropDef; private: string mysql_db_name; /*----- PROTECTED REGION END -----*/ // DataBase::Data Members // Attribute data members public: Tango::DevString *attr_StoredProcedureRelease_read; Tango::DevDouble *attr_Timing_average_read; Tango::DevDouble *attr_Timing_minimum_read; Tango::DevDouble *attr_Timing_maximum_read; Tango::DevDouble *attr_Timing_calls_read; Tango::DevString *attr_Timing_index_read; Tango::DevString *attr_Timing_info_read; // Constructors and destructors public: /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ DataBase(Tango::DeviceClass *cl,string &s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ DataBase(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device name * @param d Device description. */ DataBase(Tango::DeviceClass *cl,const char *s,const char *d); /** * The device object destructor. */ ~DataBase() {delete_device();}; // Miscellaneous methods public: /* * will be called at device destruction or at init command. */ void delete_device(); /* * Initialize the device */ virtual void init_device(); /* * Always executed method before execution command method. */ virtual void always_executed_hook(); // Attribute methods public: //-------------------------------------------------------- /* * Method : DataBase::read_attr_hardware() * Description : Hardware acquisition for attributes. */ //-------------------------------------------------------- virtual void read_attr_hardware(vector &attr_list); /** * Attribute StoredProcedureRelease related methods * Description: * * Data type: Tango::DevString * Attr type: Scalar */ virtual void read_StoredProcedureRelease(Tango::Attribute &attr); virtual bool is_StoredProcedureRelease_allowed(Tango::AttReqType type); /** * Attribute Timing_average related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ virtual void read_Timing_average(Tango::Attribute &attr); virtual bool is_Timing_average_allowed(Tango::AttReqType type); /** * Attribute Timing_minimum related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ virtual void read_Timing_minimum(Tango::Attribute &attr); virtual bool is_Timing_minimum_allowed(Tango::AttReqType type); /** * Attribute Timing_maximum related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ virtual void read_Timing_maximum(Tango::Attribute &attr); virtual bool is_Timing_maximum_allowed(Tango::AttReqType type); /** * Attribute Timing_calls related methods * Description: * * Data type: Tango::DevDouble * Attr type: Spectrum max = 64 */ virtual void read_Timing_calls(Tango::Attribute &attr); virtual bool is_Timing_calls_allowed(Tango::AttReqType type); /** * Attribute Timing_index related methods * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 64 */ virtual void read_Timing_index(Tango::Attribute &attr); virtual bool is_Timing_index_allowed(Tango::AttReqType type); /** * Attribute Timing_info related methods * Description: * * Data type: Tango::DevString * Attr type: Spectrum max = 64 */ virtual void read_Timing_info(Tango::Attribute &attr); virtual bool is_Timing_info_allowed(Tango::AttReqType type); //-------------------------------------------------------- /** * Method : DataBase::add_dynamic_attributes() * Description : Add dynamic attributes if any. */ //-------------------------------------------------------- void add_dynamic_attributes(); // Command related methods public: /** * Command State related method * Description: This command gets the device state (stored in its device_state data member) and returns it to the caller. * * @returns State Code */ virtual Tango::DevState dev_state(); /** * Command DbAddDevice related method * Description: Add a Tango class device to a specific device server * * @param argin Str[0] = Full device server process name * Str[1] = Device name * Str[2] = Tango class name */ virtual void db_add_device(const Tango::DevVarStringArray *argin); virtual bool is_DbAddDevice_allowed(const CORBA::Any &any); /** * Command DbAddServer related method * Description: Create a device server process entry in database * * @param argin Str[0] = Full device server name * Str[1] = Device(s) name * Str[2] = Tango class name * Str[n] = Device name * Str[n + 1] = Tango class name */ virtual void db_add_server(const Tango::DevVarStringArray *argin); virtual bool is_DbAddServer_allowed(const CORBA::Any &any); /** * Command DbDeleteAttributeAlias related method * Description: Delete an attribute alias. * * @param argin Attriibute alias name. */ virtual void db_delete_attribute_alias(Tango::DevString argin); virtual bool is_DbDeleteAttributeAlias_allowed(const CORBA::Any &any); /** * Command DbDeleteClassAttribute related method * Description: delete a class attribute and all its properties from database * * @param argin Str[0] = Tango class name * Str[1] = Attribute name */ virtual void db_delete_class_attribute(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteClassAttribute_allowed(const CORBA::Any &any); /** * Command DbDeleteClassAttributeProperty related method * Description: delete class attribute properties from database * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[2] = Property name * Str[n] = Property name */ virtual void db_delete_class_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteClassAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteClassProperty related method * Description: Delete class properties from database * * @param argin Str[0] = Tango class name * Str[1] = Property name * Str[n] = Property name */ virtual void db_delete_class_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteClassProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteDevice related method * Description: Delete a device from database * * @param argin device name */ virtual void db_delete_device(Tango::DevString argin); virtual bool is_DbDeleteDevice_allowed(const CORBA::Any &any); /** * Command DbDeleteDeviceAlias related method * Description: Delete a device alias. * * @param argin device alias name */ virtual void db_delete_device_alias(Tango::DevString argin); virtual bool is_DbDeleteDeviceAlias_allowed(const CORBA::Any &any); /** * Command DbDeleteDeviceAttribute related method * Description: Delete device attribute properties from database * * @param argin Str[0] = Device name * Str[1] = Attribute name */ virtual void db_delete_device_attribute(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteDeviceAttribute_allowed(const CORBA::Any &any); /** * Command DbDeleteDeviceAttributeProperty related method * Description: delete a device attribute property from the database * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[2] = Property name * Str[n] = Property name */ virtual void db_delete_device_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteDeviceAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteDeviceProperty related method * Description: Delete device property(ies) * * @param argin Str[0] = Device name * Str[1] = Property name * Str[n] = Property name */ virtual void db_delete_device_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteDeviceProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteProperty related method * Description: Delete free property from database * * @param argin Str[0] = Object name * Str[1] = Property name * Str[n] = Property name */ virtual void db_delete_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteServer related method * Description: Delete server from the database but dont delete device properties * * @param argin Device server name */ virtual void db_delete_server(Tango::DevString argin); virtual bool is_DbDeleteServer_allowed(const CORBA::Any &any); /** * Command DbDeleteServerInfo related method * Description: delete info related to a Tango devvice server process * * @param argin Device server name */ virtual void db_delete_server_info(Tango::DevString argin); virtual bool is_DbDeleteServerInfo_allowed(const CORBA::Any &any); /** * Command DbExportDevice related method * Description: Export a device to the database * * @param argin Str[0] = Device name * Str[1] = CORBA IOR * Str[2] = Device server process host name * Str[3] = Device server process PID or string ``null`` * Str[4] = Device server process version */ virtual void db_export_device(const Tango::DevVarStringArray *argin); virtual bool is_DbExportDevice_allowed(const CORBA::Any &any); /** * Command DbExportEvent related method * Description: Export Event channel to database * * @param argin Str[0] = event channel name (or factory name) * Str[1] = CORBA IOR * Str[2] = Notifd host name * Str[3] = Notifd pid * Str[4] = Notifd version */ virtual void db_export_event(const Tango::DevVarStringArray *argin); virtual bool is_DbExportEvent_allowed(const CORBA::Any &any); /** * Command DbGetAliasDevice related method * Description: Get device name from its alias. * * @param argin Alias name * @returns Device name */ virtual Tango::DevString db_get_alias_device(Tango::DevString argin); virtual bool is_DbGetAliasDevice_allowed(const CORBA::Any &any); /** * Command DbGetAttributeAlias related method * Description: Get the attribute name for the given alias. * If alias not found in database, returns an empty string. * * @param argin The attribute alias name * @returns The attribute name (device/attribute) */ virtual Tango::DevString db_get_attribute_alias(Tango::DevString argin); virtual bool is_DbGetAttributeAlias_allowed(const CORBA::Any &any); /** * Command DbGetAttributeAliasList related method * Description: Get attribute alias list for a specified filter * * @param argin attribute alias filter string (eg: att*) * @returns attribute aliases */ virtual Tango::DevVarStringArray *db_get_attribute_alias_list(Tango::DevString argin); virtual bool is_DbGetAttributeAliasList_allowed(const CORBA::Any &any); /** * Command DbGetClassAttributeList related method * Description: Get attrilute list for a given Tango class with a specified filter * * @param argin Str[0] = Tango class name * Str[1] = Attribute name filter (eg: att*) * @returns Str[0] = Class attribute name * Str[n] = Class attribute name */ virtual Tango::DevVarStringArray *db_get_class_attribute_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassAttributeList_allowed(const CORBA::Any &any); /** * Command DbGetClassAttributeProperty related method * Description: Get Tango class property(ies) value * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Tango class name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value */ virtual Tango::DevVarStringArray *db_get_class_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbGetClassAttributeProperty2 related method * Description: This command supports array property compared to the old command called * DbGetClassAttributeProperty. The old command has not been deleted from the * server for compatibility reasons. * * @param argin Str[0] = Tango class name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Tango class name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value number (array case) * Str[4] = Attribute property 1 value * Str[n] = Attribute property 1 value (array case) * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value number (array case) * Str[n + 3] = Attribute property 2 value * Str[n + m] = Attribute property 2 value (array case) */ virtual Tango::DevVarStringArray *db_get_class_attribute_property2(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassAttributeProperty2_allowed(const CORBA::Any &any); /** * Command DbGetClassAttributePropertyHist related method * Description: Retrieve Tango class attribute property history * * @param argin Str[0] = Tango class * Str[1] = Attribute name * Str[2] = Property name * @returns Str[0] = Attribute name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_class_attribute_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassAttributePropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetClassForDevice related method * Description: Get Tango class for the specified device. * * @param argin Device name * @returns Device Tango class */ virtual Tango::DevString db_get_class_for_device(Tango::DevString argin); virtual bool is_DbGetClassForDevice_allowed(const CORBA::Any &any); /** * Command DbGetClassInheritanceForDevice related method * Description: Get class inheritance for the specified device. * * @param argin Device name * @returns Classes off the specified device. * [0] - is the class of the device. * [1] - is the class from the device class is inherited. * ........and so on */ virtual Tango::DevVarStringArray *db_get_class_inheritance_for_device(Tango::DevString argin); virtual bool is_DbGetClassInheritanceForDevice_allowed(const CORBA::Any &any); /** * Command DbGetClassList related method * Description: Get Tango class list with a specified filter * * @param argin Filter * @returns Class list */ virtual Tango::DevVarStringArray *db_get_class_list(Tango::DevString argin); virtual bool is_DbGetClassList_allowed(const CORBA::Any &any); /** * Command DbGetClassProperty related method * Description: * * @param argin Str[0] = Tango class * Str[1] = Property name * Str[2] = Property name * @returns Str[0] = Tango class * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value * Str[n] = Propery value (array case) * .... */ virtual Tango::DevVarStringArray *db_get_class_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassProperty_allowed(const CORBA::Any &any); /** * Command DbGetClassPropertyHist related method * Description: Retrieve Tango class property history * * @param argin Str[0] = Tango class * Str[1] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_class_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassPropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetClassPropertyList related method * Description: Get property list for a given Tango class with a specified filter * * @param argin The filter * @returns Property name list */ virtual Tango::DevVarStringArray *db_get_class_property_list(Tango::DevString argin); virtual bool is_DbGetClassPropertyList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAlias related method * Description: Return alias for device name if found. * * @param argin The device name * @returns The alias found */ virtual Tango::DevString db_get_device_alias(Tango::DevString argin); virtual bool is_DbGetDeviceAlias_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAliasList related method * Description: Get device alias name with a specific filter * * @param argin The filter * @returns Device alias list */ virtual Tango::DevVarStringArray *db_get_device_alias_list(Tango::DevString argin); virtual bool is_DbGetDeviceAliasList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAttributeList related method * Description: Return list of attributes matching the wildcard * for the specified device * * @param argin Str[0] = Device name * Str[1] = Wildcard * @returns attribute name list */ virtual Tango::DevVarStringArray *db_get_device_attribute_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceAttributeList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAttributeProperty related method * Description: Get device attribute property(ies) value * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Device name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value */ virtual Tango::DevVarStringArray *db_get_device_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAttributeProperty2 related method * Description: Retrieve device attribute properties. This command has the possibility to retrieve * device attribute properties which are arrays. It is not possible with the old * DbGetDeviceAttributeProperty command. Nevertheless, the old command has not been * deleted for compatibility reason * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[n] = Attribute name * @returns Str[0] = Device name * Str[1] = Attribute property number * Str[2] = Attribute property 1 name * Str[3] = Attribute property 1 value number (array case) * Str[4] = Attribute property 1 value * Str[n] = Attribute property 1 value (array case) * Str[n + 1] = Attribute property 2 name * Str[n + 2] = Attribute property 2 value number (array case) * Str[n + 3] = Attribute property 2 value * Str[n + m] = Attribute property 2 value (array case) */ virtual Tango::DevVarStringArray *db_get_device_attribute_property2(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceAttributeProperty2_allowed(const CORBA::Any &any); /** * Command DbGetDeviceAttributePropertyHist related method * Description: Retrieve device attribute property history * * @param argin Str[0] = Device name * Str[1] = Attribute name * Str[2] = Property name * @returns Str[0] = Attribute name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_device_attribute_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceAttributePropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetDeviceClassList related method * Description: Get Tango classes/device list embedded in a specific device server * * @param argin Device server process name * @returns Str[0] = Device name * Str[1] = Tango class * Str[n] = Device name * Str[n + 1] = Tango class */ virtual Tango::DevVarStringArray *db_get_device_class_list(Tango::DevString argin); virtual bool is_DbGetDeviceClassList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceDomainList related method * Description: Get list of device domain name matching the specified * * @param argin The wildcard * @returns Device name domain list */ virtual Tango::DevVarStringArray *db_get_device_domain_list(Tango::DevString argin); virtual bool is_DbGetDeviceDomainList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceExportedList related method * Description: Get a list of exported devices whose names satisfy the filter (wildcard is * * @param argin filter * @returns list of exported devices */ virtual Tango::DevVarStringArray *db_get_device_exported_list(Tango::DevString argin); virtual bool is_DbGetDeviceExportedList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceFamilyList related method * Description: Get a list of device name families for device name matching the * specified wildcard * * @param argin The wildcard * @returns Family list */ virtual Tango::DevVarStringArray *db_get_device_family_list(Tango::DevString argin); virtual bool is_DbGetDeviceFamilyList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceInfo related method * Description: Returns info from DbImportDevice and started/stopped dates. * * @param argin Device name * @returns Str[0] = Device name * Str[1] = CORBA IOR * Str[2] = Device version * Str[3] = Device Server name * Str[4] = Device Server process host name * Str[5] = Started date (or ? if not set) * Str[6] = Stopped date (or ? if not set) * Str[7] = Device class * * Lg[0] = Device exported flag * Lg[1] = Device Server process PID (or -1 if not set) */ virtual Tango::DevVarLongStringArray *db_get_device_info(Tango::DevString argin); virtual bool is_DbGetDeviceInfo_allowed(const CORBA::Any &any); /** * Command DbGetDeviceList related method * Description: Get a list of devices for specified server and class. * * @param argin argin[0] : server name * argin[1] : class name * @returns The list of devices for specified server and class. */ virtual Tango::DevVarStringArray *db_get_device_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceWideList related method * Description: Get a list of devices whose names satisfy the filter. * * @param argin filter * @returns list of exported devices */ virtual Tango::DevVarStringArray *db_get_device_wide_list(Tango::DevString argin); virtual bool is_DbGetDeviceWideList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceMemberList related method * Description: Get a list of device name members for device name matching the * specified filter * * @param argin The filter * @returns Device names member list */ virtual Tango::DevVarStringArray *db_get_device_member_list(Tango::DevString argin); virtual bool is_DbGetDeviceMemberList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceProperty related method * Description: * * @param argin Str[0] = Device name * Str[1] = Property name * Str[n] = Property name * @returns Str[0] = Device name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n (array case) * Str[n + 1] = Property name * Str[n + 2] = Property value number (array case) * Str[n + 3] = Property value 1 * Str[n + m] = Property value m */ virtual Tango::DevVarStringArray *db_get_device_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDeviceProperty_allowed(const CORBA::Any &any); /** * Command DbGetDevicePropertyHist related method * Description: Retrieve device property history * * @param argin Str[0] = Device name * Str[2] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_device_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDevicePropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetDevicePropertyList related method * Description: Get property list belonging to the specified device and with * name matching the specified filter * * @param argin Str[0] = device name * Str[1] = Filter * @returns Property name list */ virtual Tango::DevVarStringArray *db_get_device_property_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDevicePropertyList_allowed(const CORBA::Any &any); /** * Command DbGetDeviceServerClassList related method * Description: Get list of Tango classes for a device server * * @param argin device server process name * @returns list of classes for this device server */ virtual Tango::DevVarStringArray *db_get_device_server_class_list(Tango::DevString argin); virtual bool is_DbGetDeviceServerClassList_allowed(const CORBA::Any &any); /** * Command DbGetExportdDeviceListForClass related method * Description: Query the database for device exported for the specified class. * * @param argin Class name * @returns Device exported list */ virtual Tango::DevVarStringArray *db_get_exportd_device_list_for_class(Tango::DevString argin); virtual bool is_DbGetExportdDeviceListForClass_allowed(const CORBA::Any &any); /** * Command DbGetHostList related method * Description: Get host list with name matching the specified filter * * @param argin The filter * @returns Host name list */ virtual Tango::DevVarStringArray *db_get_host_list(Tango::DevString argin); virtual bool is_DbGetHostList_allowed(const CORBA::Any &any); /** * Command DbGetHostServerList related method * Description: Get list of device server process name running on host with name matching * the specified filter * * @param argin The filter * @returns Device server process name list */ virtual Tango::DevVarStringArray *db_get_host_server_list(Tango::DevString argin); virtual bool is_DbGetHostServerList_allowed(const CORBA::Any &any); /** * Command DbGetHostServersInfo related method * Description: Get info about all servers running on specified host, name, mode and level * * @param argin Host name * @returns Server info for all servers running on specified host */ virtual Tango::DevVarStringArray *db_get_host_servers_info(Tango::DevString argin); virtual bool is_DbGetHostServersInfo_allowed(const CORBA::Any &any); /** * Command DbGetInstanceNameList related method * Description: Returns the instance names found for specified server. * * @param argin Server name * @returns The instance names found for specified server. */ virtual Tango::DevVarStringArray *db_get_instance_name_list(Tango::DevString argin); virtual bool is_DbGetInstanceNameList_allowed(const CORBA::Any &any); /** * Command DbGetObjectList related method * Description: Get list of free object defined in database with name * matching the specified filter * * @param argin The filter * @returns Object name list */ virtual Tango::DevVarStringArray *db_get_object_list(Tango::DevString argin); virtual bool is_DbGetObjectList_allowed(const CORBA::Any &any); /** * Command DbGetProperty related method * Description: Get free object property * * @param argin Str[0] = Object name * Str[1] = Property name * Str[n] = Property name * @returns Str[0] = Object name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n (array case) * Str[n + 1] = Property name * Str[n + 2] = Property value number (array case) * Str[n + 3] = Property value 1 * Str[n + m] = Property value m */ virtual Tango::DevVarStringArray *db_get_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetProperty_allowed(const CORBA::Any &any); /** * Command DbGetPropertyHist related method * Description: Retrieve object property history * * @param argin Str[0] = Object name * Str[2] = Property name * @returns Str[0] = Property name * Str[1] = date * Str[2] = Property value number (array case) * Str[3] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetPropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetPropertyList related method * Description: Get list of property defined for a free object and matching the * specified filter * * @param argin Str[0] = Object name * Str[1] = filter * @returns Property name list */ virtual Tango::DevVarStringArray *db_get_property_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetPropertyList_allowed(const CORBA::Any &any); /** * Command DbGetServerInfo related method * Description: Get info about host, mode and level for specified server * * @param argin server name * @returns server info */ virtual Tango::DevVarStringArray *db_get_server_info(Tango::DevString argin); virtual bool is_DbGetServerInfo_allowed(const CORBA::Any &any); /** * Command DbGetServerList related method * Description: Get list of device server process defined in database * with name matching the specified filter * * @param argin The filter * @returns Device server process name list */ virtual Tango::DevVarStringArray *db_get_server_list(Tango::DevString argin); virtual bool is_DbGetServerList_allowed(const CORBA::Any &any); /** * Command DbGetServerNameList related method * Description: Returns the list of server names found for the wildcard specified. * It returns only the server executable name without instance name as DbGetServerList. * * @param argin wildcard for server names. * @returns server names found. */ virtual Tango::DevVarStringArray *db_get_server_name_list(Tango::DevString argin); virtual bool is_DbGetServerNameList_allowed(const CORBA::Any &any); /** * Command DbImportDevice related method * Description: Import a device from the database * * @param argin Device name (or alias) * @returns Str[0] = device name * Str[1] = CORBA IOR * Str[2] = device version * Str[3] = device server process name * Str[4] = host name * Str[5] = Tango class name * * Lg[0] = Exported flag * Lg[1] = Device server process PID */ virtual Tango::DevVarLongStringArray *db_import_device(Tango::DevString argin); virtual bool is_DbImportDevice_allowed(const CORBA::Any &any); /** * Command DbImportEvent related method * Description: Get event channel info from database * * @param argin name of event channel or factory * @returns export information e.g. IOR */ virtual Tango::DevVarLongStringArray *db_import_event(Tango::DevString argin); virtual bool is_DbImportEvent_allowed(const CORBA::Any &any); /** * Command DbInfo related method * Description: Get miscellaneous numbers on information * stored in database * * @returns Miscellaneous info like: * - Device defined in database * - Device marked as exported in database * - Device server process defined in database * - Device server process marked as exported in database * - Device properties defined in database * - Class properties defined in database * - Device attribute properties defined in database * - Class attribute properties defined in database * - Object properties defined in database */ virtual Tango::DevVarStringArray *db_info(); virtual bool is_DbInfo_allowed(const CORBA::Any &any); /** * Command DbPutAttributeAlias related method * Description: Define an alias for an attribute * * @param argin Str[0] = attribute name * Str[1] = attribute alias */ virtual void db_put_attribute_alias(const Tango::DevVarStringArray *argin); virtual bool is_DbPutAttributeAlias_allowed(const CORBA::Any &any); /** * Command DbPutClassAttributeProperty related method * Description: Create/Update class attribute property(ies) in database * * @param argin Str[0] = Tango class name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value * ..... */ virtual void db_put_class_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutClassAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbPutClassAttributeProperty2 related method * Description: This command adds support for array properties compared to the previous one * called DbPutClassAttributeProperty. The old comman is still there for compatibility reason * * @param argin Str[0] = Tango class name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value number (array case) * Str[5] = Property value 1 * Str[n] = Property value n (array case) * ..... */ virtual void db_put_class_attribute_property2(const Tango::DevVarStringArray *argin); virtual bool is_DbPutClassAttributeProperty2_allowed(const CORBA::Any &any); /** * Command DbPutClassProperty related method * Description: Create / Update class property(ies) * * @param argin Str[0] = Tango class name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number * Str[4] = Property value 1 * Str[n] = Property value n * .... */ virtual void db_put_class_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutClassProperty_allowed(const CORBA::Any &any); /** * Command DbPutDeviceAlias related method * Description: Define alias for a given device name * * @param argin Str[0] = device name * Str[1] = alias name */ virtual void db_put_device_alias(const Tango::DevVarStringArray *argin); virtual bool is_DbPutDeviceAlias_allowed(const CORBA::Any &any); /** * Command DbPutDeviceAttributeProperty related method * Description: Create/Update device attribute property(ies) in database * * @param argin Str[0] = Device name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value * ..... */ virtual void db_put_device_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutDeviceAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbPutDeviceAttributeProperty2 related method * Description: Put device attribute property. This command adds the possibility to have attribute property * which are arrays. Not possible with the old DbPutDeviceAttributeProperty command. * This old command is not deleted for compatibility reasons. * * @param argin Str[0] = Device name * Str[1] = Attribute number * Str[2] = Attribute name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value number (array case) * Str[5] = Property value 1 * Str[n] = Property value n (array case) * ..... */ virtual void db_put_device_attribute_property2(const Tango::DevVarStringArray *argin); virtual bool is_DbPutDeviceAttributeProperty2_allowed(const CORBA::Any &any); /** * Command DbPutDeviceProperty related method * Description: Create / Update device property(ies) * * @param argin Str[0] = Tango device name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number * Str[4] = Property value 1 * Str[n] = Property value n * .... */ virtual void db_put_device_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutDeviceProperty_allowed(const CORBA::Any &any); /** * Command DbPutProperty related method * Description: Create / Update free object property(ies) * * @param argin Str[0] = Object name * Str[1] = Property number * Str[2] = Property name * Str[3] = Property value number * Str[4] = Property value 1 * Str[n] = Property value n * .... */ virtual void db_put_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutProperty_allowed(const CORBA::Any &any); /** * Command DbPutServerInfo related method * Description: Update server info including host, mode and level * * @param argin server info */ virtual void db_put_server_info(const Tango::DevVarStringArray *argin); virtual bool is_DbPutServerInfo_allowed(const CORBA::Any &any); /** * Command DbUnExportDevice related method * Description: Mark a device as non exported in database * * @param argin Device name */ virtual void db_un_export_device(Tango::DevString argin); virtual bool is_DbUnExportDevice_allowed(const CORBA::Any &any); /** * Command DbUnExportEvent related method * Description: Mark one event channel as non exported in database * * @param argin name of event channel or factory to unexport */ virtual void db_un_export_event(Tango::DevString argin); virtual bool is_DbUnExportEvent_allowed(const CORBA::Any &any); /** * Command DbUnExportServer related method * Description: Mark all devices belonging to a specified device server * process as non exported * * @param argin Device server name (executable/instance) */ virtual void db_un_export_server(Tango::DevString argin); virtual bool is_DbUnExportServer_allowed(const CORBA::Any &any); /** * Command ResetTimingValues related method * Description: Reset the timing attribute values. * */ virtual void reset_timing_values(); virtual bool is_ResetTimingValues_allowed(const CORBA::Any &any); /** * Command DbGetDataForServerCache related method * Description: This command returns all the data needed by a device server process during its * startup sequence. The aim of this command is to minimize database access during * device server startup sequence. * * @param argin Elt[0] = DS name (exec_name/inst_name), Elt[1] = Host name * @returns All the data needed by the device server during its startup sequence. Precise list depend on the device server */ virtual Tango::DevVarStringArray *db_get_data_for_server_cache(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDataForServerCache_allowed(const CORBA::Any &any); /** * Command DbDeleteAllDeviceAttributeProperty related method * Description: Delete all attribute properties for the specified device attribute(s) * * @param argin str[0] = device name * Str[1]...str[n] = attribute name(s) */ virtual void db_delete_all_device_attribute_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteAllDeviceAttributeProperty_allowed(const CORBA::Any &any); /** * Command DbMySqlSelect related method * Description: This is a very low level command. * It executes the specified SELECT command on TANGO database and returns its result without filter. * * @param argin MySql Select command * @returns MySql Select command result * - svalues : select results * - lvalue[n] : =0 if svalue[n] is null else =1 * (last lvalue -1) is number of rows, (last lvalue) is number of fields */ virtual Tango::DevVarLongStringArray *db_my_sql_select(Tango::DevString argin); virtual bool is_DbMySqlSelect_allowed(const CORBA::Any &any); /** * Command DbGetCSDbServerList related method * Description: Get a list of host:port for all database server defined in the control system * * @returns List of host:port with one element for each database server */ virtual Tango::DevVarStringArray *db_get_csdb_server_list(); virtual bool is_DbGetCSDbServerList_allowed(const CORBA::Any &any); /** * Command DbGetAttributeAlias2 related method * Description: Get the attribute alias from the attribute name. * Returns one empty string if nothing found in database * * @param argin The attribute name (dev_name/att_name) * @returns The attribute alias name (or empty string) */ virtual Tango::DevString db_get_attribute_alias2(Tango::DevString argin); virtual bool is_DbGetAttributeAlias2_allowed(const CORBA::Any &any); /** * Command DbGetAliasAttribute related method * Description: Get the attribute name from the given alias. * If the given alias is not found in database, returns an empty string * * @param argin The attribute alias * @returns The attribute name (dev_name/att_name) */ virtual Tango::DevString db_get_alias_attribute(Tango::DevString argin); virtual bool is_DbGetAliasAttribute_allowed(const CORBA::Any &any); /** * Command DbRenameServer related method * Description: Rename a device server process * * @param argin s[0] = old device server name (exec/instance) * s[1] = new device server name (exec/instance) */ virtual void db_rename_server(const Tango::DevVarStringArray *argin); virtual bool is_DbRenameServer_allowed(const CORBA::Any &any); /** * Command DbGetClassPipeProperty related method * Description: Retrieve class pipe properties * * @param argin Str[0] = Tango class name * Str[1] = Pipe name * Str[n] = Pipe name * @returns Str[0] = Tango class name * Str[1] = Pipe property number * Str[2] = Pipe property 1 name * Str[3] = Pipe property 1 value number (array case) * Str[4] = Pipe property 1 value * Str[n] = Pipe property 1 value (array case) * Str[n + 1] = Pipe property 2 name * Str[n + 2] = Pipe property 2 value number (array case) * Str[n + 3] = Pipe property 2 value * Str[n + m] = Pipe property 2 value (array case) */ virtual Tango::DevVarStringArray *db_get_class_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassPipeProperty_allowed(const CORBA::Any &any); /** * Command DbGetDevicePipeProperty related method * Description: Retrieve device pipe properties * * @param argin Str[0] = Device name * Str[1] = Pipe name * Str[n] = Pipe name * @returns Str[0] = Device name * Str[1] = Pipe property number * Str[2] = Pipe property 1 name * Str[3] = Pipe property 1 value number (array case) * Str[4] = Pipe property 1 value * Str[n] = Pipe property 1 value (array case) * Str[n + 1] = Pipe property 2 name * Str[n + 2] = Pipe property 2 value number (array case) * Str[n + 3] = Pipe property 2 value * Str[n + m] = Pipe property 2 value (array case) */ virtual Tango::DevVarStringArray *db_get_device_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDevicePipeProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteClassPipe related method * Description: Delete a class pipe and all its properties from database * * @param argin Str[0] = Tango class name * Str[1] = Pipe name */ virtual void db_delete_class_pipe(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteClassPipe_allowed(const CORBA::Any &any); /** * Command DbDeleteDevicePipe related method * Description: Delete device pipe properties from database * * @param argin Str[0] = Device name * Str[1] = Pipe name */ virtual void db_delete_device_pipe(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteDevicePipe_allowed(const CORBA::Any &any); /** * Command DbDeleteClassPipeProperty related method * Description: Delete class pipe properties from database * * @param argin Str[0] = Tango class name * Str[1] = Pipe name * Str[2] = Property name * Str[n] = Property name */ virtual void db_delete_class_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteClassPipeProperty_allowed(const CORBA::Any &any); /** * Command DbDeleteDevicePipeProperty related method * Description: Delete device pipe properties from database * * @param argin Str[0] = Device name * Str[1] = Pipe name * Str[2] = Property name * Str[n] = Property name */ virtual void db_delete_device_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteDevicePipeProperty_allowed(const CORBA::Any &any); /** * Command DbGetClassPipeList related method * Description: Get pipe list for a given Tango class with a specified filter * * @param argin Str[0] = Tango class name * Str[1] = Pipe name filter (eg: pip*) * @returns Str[0] = Class pipe name * Str[n] = Class pipe name */ virtual Tango::DevVarStringArray *db_get_class_pipe_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassPipeList_allowed(const CORBA::Any &any); /** * Command DbGetDevicePipeList related method * Description: Return list of pipes matching the wildcard for the specified device * * @param argin Str[0] = Device name * Str[1] = Wildcard * @returns Pipe name list */ virtual Tango::DevVarStringArray *db_get_device_pipe_list(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDevicePipeList_allowed(const CORBA::Any &any); /** * Command DbDeleteAllDevicePipeProperty related method * Description: Delete all pipe properties for the specified device pipe(s) * * @param argin str[0] = device name * Str[1]...str[n] = pipe name(s) */ virtual void db_delete_all_device_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbDeleteAllDevicePipeProperty_allowed(const CORBA::Any &any); /** * Command DbPutClassPipeProperty related method * Description: Create/Update class pipe property(ies) in database * * @param argin Str[0] = Tango class name * Str[1] = Pipe number * Str[2] = Pipe name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value number (array case) * Str[5] = Property value 1 * Str[n] = Property value n (array case) */ virtual void db_put_class_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutClassPipeProperty_allowed(const CORBA::Any &any); /** * Command DbPutDevicePipeProperty related method * Description: Create/Update device pipe property(ies) in database * * @param argin Str[0] = Device name * Str[1] = Pipe number * Str[2] = Pipe name * Str[3] = Property number * Str[4] = Property name * Str[5] = Property value number (array case) * Str[6] = Property value 1 * Str[n] = Property value n (array case) */ virtual void db_put_device_pipe_property(const Tango::DevVarStringArray *argin); virtual bool is_DbPutDevicePipeProperty_allowed(const CORBA::Any &any); /** * Command DbGetClassPipePropertyHist related method * Description: Retrieve Tango class pipe property history * * @param argin Str[0] = Tango class * Str[1] = Pipe name * Str[2] = Property name * @returns Str[0] = Pipe name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_class_pipe_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetClassPipePropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetDevicePipePropertyHist related method * Description: Retrieve device pipe property history * * @param argin Str[0] = Device name * Str[1] = Pipe name * Str[2] = Property name * @returns Str[0] = Pipe name * Str[1] = Property name * Str[2] = date * Str[3] = Property value number (array case) * Str[4] = Property value 1 * Str[n] = Property value n */ virtual Tango::DevVarStringArray *db_get_device_pipe_property_hist(const Tango::DevVarStringArray *argin); virtual bool is_DbGetDevicePipePropertyHist_allowed(const CORBA::Any &any); /** * Command DbGetForwardedAttributeListForDevice related method * Description: Get the list of devices using forwarded attribute(s) from specified device * * @param argin The specified device name * @returns argout[n] : device name * argout[n+1] :the forwardef attribute * argout[n+2] :the root attribute (__root_att) */ virtual Tango::DevVarStringArray *db_get_forwarded_attribute_list_for_device(Tango::DevString argin); virtual bool is_DbGetForwardedAttributeListForDevice_allowed(const CORBA::Any &any); //-------------------------------------------------------- /** * Method : DataBase::add_dynamic_commands() * Description : Add dynamic commands if any. */ //-------------------------------------------------------- void add_dynamic_commands(); /*----- PROTECTED REGION ID(DataBase::Additional Method prototypes) ENABLED START -----*/ // Additional Method prototypes protected : unsigned long mysql_svr_version; bool check_device_name(string &); bool device_name_to_dfm(string &device_name, char domain[], char family[], char member[]); string replace_wildcard(const char*); Tango::DevString db_get_device_host(Tango::DevString,int con_nb=-1); string escape_string(const char *string_c_str); void init_timing_stats(); Tango::DevULong64 get_id(const char *name,int con_nb=-1); void check_history_tables(); void purge_property(const char *table,const char *field,const char *object,const char *name,int con_nb=-1); void purge_att_property(const char *table,const char *field,const char *object,const char *attribute,const char *name,int con_nb=-1); void purge_pipe_property(const char *table,const char *field,const char *object,const char *pipe,const char *name,int con_nb=-1); typedef struct { MYSQL *db; omni_semaphore the_sema; }DbConnection; DbConnection *conn_pool; int last_sem_wait; static int conn_pool_size; char *stored_release_ptr; char stored_release[128]; string ho; char ho_name[1024]; omni_mutex timing_stats_mutex; omni_mutex starter_mutex; omni_mutex sem_wait_mutex; void create_connection_pool(const char *,const char *,const char *,const char *); void base_connect(int); bool host_port_from_ior(const char *,string &); void create_update_mem_att(const Tango::DevVarStringArray *); inline void update_timing_stats(TimeVal before, TimeVal after, std::string command) { double time_elapsed = Elapsed(before, after); timing_stats_mutex.lock(); TimingStatsStruct *timing_stats = timing_stats_map[command]; if (timing_stats != NULL) { timing_stats->calls++; timing_stats->total_elapsed = timing_stats->total_elapsed+time_elapsed; timing_stats->average = timing_stats->total_elapsed/timing_stats->calls; if (time_elapsed > timing_stats->maximum) timing_stats->maximum = time_elapsed; if (time_elapsed < timing_stats->minimum || timing_stats->minimum == 0.0) timing_stats->minimum = time_elapsed; } timing_stats_mutex.unlock(); } #ifdef WIN32 inline static void w_gettimeofday(LARGE_INTEGER *t) { static int status = 0; if (status==0) // Initialize status = QueryPerformanceFrequency(&cpu_freq); if (status!=0) QueryPerformanceCounter(t); // Get micro-second time else t->QuadPart = 0; } #endif public: void simple_query(string sql_query,const char *method,int con_nb=-1); MYSQL_RES *query(string sql_query,const char *method,int con_nb=-1); static void set_conn_pool_size(int si) {conn_pool_size = si;} int get_connection(); void release_connection(int con_nb) {conn_pool[con_nb].the_sema.post();} /*----- PROTECTED REGION END -----*/ // DataBase::Additional Method prototypes }; /*----- PROTECTED REGION ID(DataBase::Additional Classes Definitions) ENABLED START -----*/ // Additional Classes definitions class AutoLock { public: AutoLock(const char *,DataBase *); ~AutoLock(); int get_con_nb() {return con_nb;} private: DataBase *the_db; int con_nb; }; class DbInter: public Tango::Interceptors { public: DbInter() {} ~DbInter() {} virtual void create_thread() { if (Tango::Util::instance()->is_svr_starting() == false) mysql_thread_init(); } virtual void delete_thread() { if (Tango::Util::instance()->is_svr_starting() == false) mysql_thread_end(); } }; /*----- PROTECTED REGION END -----*/ // DataBase::Additional Classes Definitions } // End of namespace #endif // DataBase_H tango-9.2.5a/cppserver/database/DataBaseClass.h0000644023471100065110000024623213034745006016321 00000000000000/*----- PROTECTED REGION ID(DataBaseClass.h) ENABLED START -----*/ //============================================================================= // // file : DataBaseClass.h // // description : Include for the DataBaseClass root class. // This class is the singleton class for. // the DataBase device class.. // It contains all properties and methods which the . // DataBase requires only once e.g. the commands. // // project : TANGO. // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 28921 $ // $Date: 2015-12-15 16:03:51 +0100 (Tue, 15 Dec 2015) $ // // $HeadURL:$ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef DATABASECLASS_H #define DATABASECLASS_H #include #include /*----- PROTECTED REGION END -----*/ // DataBaseClass.h namespace DataBase_ns { /*----- PROTECTED REGION ID(DataBaseClass::classes for dynamic creation) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // DataBaseClass::classes for dynamic creation //========================================= // Define classes for attributes //========================================= // Attribute StoredProcedureRelease class definition class StoredProcedureReleaseAttrib: public Tango::Attr { public: StoredProcedureReleaseAttrib():Attr("StoredProcedureRelease", Tango::DEV_STRING, Tango::READ) {}; ~StoredProcedureReleaseAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_StoredProcedureRelease(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_StoredProcedureRelease_allowed(ty);} }; // Attribute Timing_average class definition class Timing_averageAttrib: public Tango::SpectrumAttr { public: Timing_averageAttrib():SpectrumAttr("Timing_average", Tango::DEV_DOUBLE, Tango::READ, 64) {}; ~Timing_averageAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_average(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_average_allowed(ty);} }; // Attribute Timing_minimum class definition class Timing_minimumAttrib: public Tango::SpectrumAttr { public: Timing_minimumAttrib():SpectrumAttr("Timing_minimum", Tango::DEV_DOUBLE, Tango::READ, 64) {}; ~Timing_minimumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_minimum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_minimum_allowed(ty);} }; // Attribute Timing_maximum class definition class Timing_maximumAttrib: public Tango::SpectrumAttr { public: Timing_maximumAttrib():SpectrumAttr("Timing_maximum", Tango::DEV_DOUBLE, Tango::READ, 64) {}; ~Timing_maximumAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_maximum(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_maximum_allowed(ty);} }; // Attribute Timing_calls class definition class Timing_callsAttrib: public Tango::SpectrumAttr { public: Timing_callsAttrib():SpectrumAttr("Timing_calls", Tango::DEV_DOUBLE, Tango::READ, 64) {}; ~Timing_callsAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_calls(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_calls_allowed(ty);} }; // Attribute Timing_index class definition class Timing_indexAttrib: public Tango::SpectrumAttr { public: Timing_indexAttrib():SpectrumAttr("Timing_index", Tango::DEV_STRING, Tango::READ, 64) {}; ~Timing_indexAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_index(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_index_allowed(ty);} }; // Attribute Timing_info class definition class Timing_infoAttrib: public Tango::SpectrumAttr { public: Timing_infoAttrib():SpectrumAttr("Timing_info", Tango::DEV_STRING, Tango::READ, 64) {}; ~Timing_infoAttrib() {}; virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) {(static_cast(dev))->read_Timing_info(att);} virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) {return (static_cast(dev))->is_Timing_info_allowed(ty);} }; //========================================= // Define classes for commands //========================================= // Command DbAddDevice class definition class DbAddDeviceClass : public Tango::Command { public: DbAddDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbAddDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbAddDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbAddDevice_allowed(any);} }; // Command DbAddServer class definition class DbAddServerClass : public Tango::Command { public: DbAddServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbAddServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbAddServerClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbAddServer_allowed(any);} }; // Command DbDeleteAttributeAlias class definition class DbDeleteAttributeAliasClass : public Tango::Command { public: DbDeleteAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteAttributeAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteAttributeAlias_allowed(any);} }; // Command DbDeleteClassAttribute class definition class DbDeleteClassAttributeClass : public Tango::Command { public: DbDeleteClassAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteClassAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteClassAttributeClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteClassAttribute_allowed(any);} }; // Command DbDeleteClassAttributeProperty class definition class DbDeleteClassAttributePropertyClass : public Tango::Command { public: DbDeleteClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteClassAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteClassAttributeProperty_allowed(any);} }; // Command DbDeleteClassProperty class definition class DbDeleteClassPropertyClass : public Tango::Command { public: DbDeleteClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteClassPropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteClassProperty_allowed(any);} }; // Command DbDeleteDevice class definition class DbDeleteDeviceClass : public Tango::Command { public: DbDeleteDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDevice_allowed(any);} }; // Command DbDeleteDeviceAlias class definition class DbDeleteDeviceAliasClass : public Tango::Command { public: DbDeleteDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDeviceAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDeviceAlias_allowed(any);} }; // Command DbDeleteDeviceAttribute class definition class DbDeleteDeviceAttributeClass : public Tango::Command { public: DbDeleteDeviceAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDeviceAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDeviceAttributeClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDeviceAttribute_allowed(any);} }; // Command DbDeleteDeviceAttributeProperty class definition class DbDeleteDeviceAttributePropertyClass : public Tango::Command { public: DbDeleteDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDeviceAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDeviceAttributeProperty_allowed(any);} }; // Command DbDeleteDeviceProperty class definition class DbDeleteDevicePropertyClass : public Tango::Command { public: DbDeleteDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDevicePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDeviceProperty_allowed(any);} }; // Command DbDeleteProperty class definition class DbDeletePropertyClass : public Tango::Command { public: DbDeletePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeletePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeletePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteProperty_allowed(any);} }; // Command DbDeleteServer class definition class DbDeleteServerClass : public Tango::Command { public: DbDeleteServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteServerClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteServer_allowed(any);} }; // Command DbDeleteServerInfo class definition class DbDeleteServerInfoClass : public Tango::Command { public: DbDeleteServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteServerInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteServerInfo_allowed(any);} }; // Command DbExportDevice class definition class DbExportDeviceClass : public Tango::Command { public: DbExportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbExportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbExportDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbExportDevice_allowed(any);} }; // Command DbExportEvent class definition class DbExportEventClass : public Tango::Command { public: DbExportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbExportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbExportEventClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbExportEvent_allowed(any);} }; // Command DbGetAliasDevice class definition class DbGetAliasDeviceClass : public Tango::Command { public: DbGetAliasDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetAliasDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetAliasDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetAliasDevice_allowed(any);} }; // Command DbGetAttributeAlias class definition class DbGetAttributeAliasClass : public Tango::Command { public: DbGetAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetAttributeAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetAttributeAlias_allowed(any);} }; // Command DbGetAttributeAliasList class definition class DbGetAttributeAliasListClass : public Tango::Command { public: DbGetAttributeAliasListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetAttributeAliasListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetAttributeAliasListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetAttributeAliasList_allowed(any);} }; // Command DbGetClassAttributeList class definition class DbGetClassAttributeListClass : public Tango::Command { public: DbGetClassAttributeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassAttributeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassAttributeListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassAttributeList_allowed(any);} }; // Command DbGetClassAttributeProperty class definition class DbGetClassAttributePropertyClass : public Tango::Command { public: DbGetClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassAttributeProperty_allowed(any);} }; // Command DbGetClassAttributeProperty2 class definition class DbGetClassAttributeProperty2Class : public Tango::Command { public: DbGetClassAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassAttributeProperty2Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassAttributeProperty2_allowed(any);} }; // Command DbGetClassAttributePropertyHist class definition class DbGetClassAttributePropertyHistClass : public Tango::Command { public: DbGetClassAttributePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassAttributePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassAttributePropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassAttributePropertyHist_allowed(any);} }; // Command DbGetClassForDevice class definition class DbGetClassForDeviceClass : public Tango::Command { public: DbGetClassForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassForDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassForDevice_allowed(any);} }; // Command DbGetClassInheritanceForDevice class definition class DbGetClassInheritanceForDeviceClass : public Tango::Command { public: DbGetClassInheritanceForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassInheritanceForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassInheritanceForDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassInheritanceForDevice_allowed(any);} }; // Command DbGetClassList class definition class DbGetClassListClass : public Tango::Command { public: DbGetClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassList_allowed(any);} }; // Command DbGetClassProperty class definition class DbGetClassPropertyClass : public Tango::Command { public: DbGetClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassProperty_allowed(any);} }; // Command DbGetClassPropertyHist class definition class DbGetClassPropertyHistClass : public Tango::Command { public: DbGetClassPropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassPropertyHist_allowed(any);} }; // Command DbGetClassPropertyList class definition class DbGetClassPropertyListClass : public Tango::Command { public: DbGetClassPropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPropertyListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassPropertyList_allowed(any);} }; // Command DbGetDeviceAlias class definition class DbGetDeviceAliasClass : public Tango::Command { public: DbGetDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAlias_allowed(any);} }; // Command DbGetDeviceAliasList class definition class DbGetDeviceAliasListClass : public Tango::Command { public: DbGetDeviceAliasListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAliasListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAliasListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAliasList_allowed(any);} }; // Command DbGetDeviceAttributeList class definition class DbGetDeviceAttributeListClass : public Tango::Command { public: DbGetDeviceAttributeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAttributeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAttributeListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAttributeList_allowed(any);} }; // Command DbGetDeviceAttributeProperty class definition class DbGetDeviceAttributePropertyClass : public Tango::Command { public: DbGetDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAttributeProperty_allowed(any);} }; // Command DbGetDeviceAttributeProperty2 class definition class DbGetDeviceAttributeProperty2Class : public Tango::Command { public: DbGetDeviceAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAttributeProperty2Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAttributeProperty2_allowed(any);} }; // Command DbGetDeviceAttributePropertyHist class definition class DbGetDeviceAttributePropertyHistClass : public Tango::Command { public: DbGetDeviceAttributePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceAttributePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceAttributePropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceAttributePropertyHist_allowed(any);} }; // Command DbGetDeviceClassList class definition class DbGetDeviceClassListClass : public Tango::Command { public: DbGetDeviceClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceClassListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceClassList_allowed(any);} }; // Command DbGetDeviceDomainList class definition class DbGetDeviceDomainListClass : public Tango::Command { public: DbGetDeviceDomainListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceDomainListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceDomainListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceDomainList_allowed(any);} }; // Command DbGetDeviceExportedList class definition class DbGetDeviceExportedListClass : public Tango::Command { public: DbGetDeviceExportedListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceExportedListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceExportedListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceExportedList_allowed(any);} }; // Command DbGetDeviceFamilyList class definition class DbGetDeviceFamilyListClass : public Tango::Command { public: DbGetDeviceFamilyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceFamilyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceFamilyListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceFamilyList_allowed(any);} }; // Command DbGetDeviceInfo class definition class DbGetDeviceInfoClass : public Tango::Command { public: DbGetDeviceInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceInfo_allowed(any);} }; // Command DbGetDeviceList class definition class DbGetDeviceListClass : public Tango::Command { public: DbGetDeviceListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceList_allowed(any);} }; // Command DbGetDeviceWideList class definition class DbGetDeviceWideListClass : public Tango::Command { public: DbGetDeviceWideListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceWideListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceWideListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceWideList_allowed(any);} }; // Command DbGetDeviceMemberList class definition class DbGetDeviceMemberListClass : public Tango::Command { public: DbGetDeviceMemberListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceMemberListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceMemberListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceMemberList_allowed(any);} }; // Command DbGetDeviceProperty class definition class DbGetDevicePropertyClass : public Tango::Command { public: DbGetDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceProperty_allowed(any);} }; // Command DbGetDevicePropertyHist class definition class DbGetDevicePropertyHistClass : public Tango::Command { public: DbGetDevicePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDevicePropertyHist_allowed(any);} }; // Command DbGetDevicePropertyList class definition class DbGetDevicePropertyListClass : public Tango::Command { public: DbGetDevicePropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePropertyListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDevicePropertyList_allowed(any);} }; // Command DbGetDeviceServerClassList class definition class DbGetDeviceServerClassListClass : public Tango::Command { public: DbGetDeviceServerClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDeviceServerClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDeviceServerClassListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDeviceServerClassList_allowed(any);} }; // Command DbGetExportdDeviceListForClass class definition class DbGetExportdDeviceListForClassClass : public Tango::Command { public: DbGetExportdDeviceListForClassClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetExportdDeviceListForClassClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetExportdDeviceListForClassClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetExportdDeviceListForClass_allowed(any);} }; // Command DbGetHostList class definition class DbGetHostListClass : public Tango::Command { public: DbGetHostListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetHostListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetHostListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetHostList_allowed(any);} }; // Command DbGetHostServerList class definition class DbGetHostServerListClass : public Tango::Command { public: DbGetHostServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetHostServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetHostServerListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetHostServerList_allowed(any);} }; // Command DbGetHostServersInfo class definition class DbGetHostServersInfoClass : public Tango::Command { public: DbGetHostServersInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetHostServersInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetHostServersInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetHostServersInfo_allowed(any);} }; // Command DbGetInstanceNameList class definition class DbGetInstanceNameListClass : public Tango::Command { public: DbGetInstanceNameListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetInstanceNameListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetInstanceNameListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetInstanceNameList_allowed(any);} }; // Command DbGetObjectList class definition class DbGetObjectListClass : public Tango::Command { public: DbGetObjectListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetObjectListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetObjectListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetObjectList_allowed(any);} }; // Command DbGetProperty class definition class DbGetPropertyClass : public Tango::Command { public: DbGetPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetPropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetProperty_allowed(any);} }; // Command DbGetPropertyHist class definition class DbGetPropertyHistClass : public Tango::Command { public: DbGetPropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetPropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetPropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetPropertyHist_allowed(any);} }; // Command DbGetPropertyList class definition class DbGetPropertyListClass : public Tango::Command { public: DbGetPropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetPropertyListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetPropertyListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetPropertyList_allowed(any);} }; // Command DbGetServerInfo class definition class DbGetServerInfoClass : public Tango::Command { public: DbGetServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetServerInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetServerInfo_allowed(any);} }; // Command DbGetServerList class definition class DbGetServerListClass : public Tango::Command { public: DbGetServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetServerListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetServerList_allowed(any);} }; // Command DbGetServerNameList class definition class DbGetServerNameListClass : public Tango::Command { public: DbGetServerNameListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetServerNameListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetServerNameListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetServerNameList_allowed(any);} }; // Command DbImportDevice class definition class DbImportDeviceClass : public Tango::Command { public: DbImportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbImportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbImportDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbImportDevice_allowed(any);} }; // Command DbImportEvent class definition class DbImportEventClass : public Tango::Command { public: DbImportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbImportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbImportEventClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbImportEvent_allowed(any);} }; // Command DbInfo class definition class DbInfoClass : public Tango::Command { public: DbInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbInfo_allowed(any);} }; // Command DbPutAttributeAlias class definition class DbPutAttributeAliasClass : public Tango::Command { public: DbPutAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutAttributeAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutAttributeAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutAttributeAlias_allowed(any);} }; // Command DbPutClassAttributeProperty class definition class DbPutClassAttributePropertyClass : public Tango::Command { public: DbPutClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutClassAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutClassAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutClassAttributeProperty_allowed(any);} }; // Command DbPutClassAttributeProperty2 class definition class DbPutClassAttributeProperty2Class : public Tango::Command { public: DbPutClassAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutClassAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutClassAttributeProperty2Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutClassAttributeProperty2_allowed(any);} }; // Command DbPutClassProperty class definition class DbPutClassPropertyClass : public Tango::Command { public: DbPutClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutClassPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutClassPropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutClassProperty_allowed(any);} }; // Command DbPutDeviceAlias class definition class DbPutDeviceAliasClass : public Tango::Command { public: DbPutDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutDeviceAliasClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutDeviceAliasClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutDeviceAlias_allowed(any);} }; // Command DbPutDeviceAttributeProperty class definition class DbPutDeviceAttributePropertyClass : public Tango::Command { public: DbPutDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutDeviceAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutDeviceAttributeProperty_allowed(any);} }; // Command DbPutDeviceAttributeProperty2 class definition class DbPutDeviceAttributeProperty2Class : public Tango::Command { public: DbPutDeviceAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutDeviceAttributeProperty2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutDeviceAttributeProperty2Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutDeviceAttributeProperty2_allowed(any);} }; // Command DbPutDeviceProperty class definition class DbPutDevicePropertyClass : public Tango::Command { public: DbPutDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutDevicePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutDevicePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutDeviceProperty_allowed(any);} }; // Command DbPutProperty class definition class DbPutPropertyClass : public Tango::Command { public: DbPutPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutPropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutPropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutProperty_allowed(any);} }; // Command DbPutServerInfo class definition class DbPutServerInfoClass : public Tango::Command { public: DbPutServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutServerInfoClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutServerInfoClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutServerInfo_allowed(any);} }; // Command DbUnExportDevice class definition class DbUnExportDeviceClass : public Tango::Command { public: DbUnExportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbUnExportDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbUnExportDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbUnExportDevice_allowed(any);} }; // Command DbUnExportEvent class definition class DbUnExportEventClass : public Tango::Command { public: DbUnExportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbUnExportEventClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbUnExportEventClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbUnExportEvent_allowed(any);} }; // Command DbUnExportServer class definition class DbUnExportServerClass : public Tango::Command { public: DbUnExportServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbUnExportServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbUnExportServerClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbUnExportServer_allowed(any);} }; // Command ResetTimingValues class definition class ResetTimingValuesClass : public Tango::Command { public: ResetTimingValuesClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; ResetTimingValuesClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~ResetTimingValuesClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_ResetTimingValues_allowed(any);} }; // Command DbGetDataForServerCache class definition class DbGetDataForServerCacheClass : public Tango::Command { public: DbGetDataForServerCacheClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDataForServerCacheClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDataForServerCacheClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDataForServerCache_allowed(any);} }; // Command DbDeleteAllDeviceAttributeProperty class definition class DbDeleteAllDeviceAttributePropertyClass : public Tango::Command { public: DbDeleteAllDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteAllDeviceAttributePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteAllDeviceAttributePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteAllDeviceAttributeProperty_allowed(any);} }; // Command DbMySqlSelect class definition class DbMySqlSelectClass : public Tango::Command { public: DbMySqlSelectClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbMySqlSelectClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbMySqlSelectClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbMySqlSelect_allowed(any);} }; // Command DbGetCSDbServerList class definition class DbGetCSDbServerListClass : public Tango::Command { public: DbGetCSDbServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetCSDbServerListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetCSDbServerListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetCSDbServerList_allowed(any);} }; // Command DbGetAttributeAlias2 class definition class DbGetAttributeAlias2Class : public Tango::Command { public: DbGetAttributeAlias2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetAttributeAlias2Class(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetAttributeAlias2Class() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetAttributeAlias2_allowed(any);} }; // Command DbGetAliasAttribute class definition class DbGetAliasAttributeClass : public Tango::Command { public: DbGetAliasAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetAliasAttributeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetAliasAttributeClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetAliasAttribute_allowed(any);} }; // Command DbRenameServer class definition class DbRenameServerClass : public Tango::Command { public: DbRenameServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbRenameServerClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbRenameServerClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbRenameServer_allowed(any);} }; // Command DbGetClassPipeProperty class definition class DbGetClassPipePropertyClass : public Tango::Command { public: DbGetClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassPipeProperty_allowed(any);} }; // Command DbGetDevicePipeProperty class definition class DbGetDevicePipePropertyClass : public Tango::Command { public: DbGetDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDevicePipeProperty_allowed(any);} }; // Command DbDeleteClassPipe class definition class DbDeleteClassPipeClass : public Tango::Command { public: DbDeleteClassPipeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteClassPipeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteClassPipeClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteClassPipe_allowed(any);} }; // Command DbDeleteDevicePipe class definition class DbDeleteDevicePipeClass : public Tango::Command { public: DbDeleteDevicePipeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDevicePipeClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDevicePipeClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDevicePipe_allowed(any);} }; // Command DbDeleteClassPipeProperty class definition class DbDeleteClassPipePropertyClass : public Tango::Command { public: DbDeleteClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteClassPipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteClassPipeProperty_allowed(any);} }; // Command DbDeleteDevicePipeProperty class definition class DbDeleteDevicePipePropertyClass : public Tango::Command { public: DbDeleteDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteDevicePipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteDevicePipeProperty_allowed(any);} }; // Command DbGetClassPipeList class definition class DbGetClassPipeListClass : public Tango::Command { public: DbGetClassPipeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPipeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPipeListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassPipeList_allowed(any);} }; // Command DbGetDevicePipeList class definition class DbGetDevicePipeListClass : public Tango::Command { public: DbGetDevicePipeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePipeListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePipeListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDevicePipeList_allowed(any);} }; // Command DbDeleteAllDevicePipeProperty class definition class DbDeleteAllDevicePipePropertyClass : public Tango::Command { public: DbDeleteAllDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbDeleteAllDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbDeleteAllDevicePipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbDeleteAllDevicePipeProperty_allowed(any);} }; // Command DbPutClassPipeProperty class definition class DbPutClassPipePropertyClass : public Tango::Command { public: DbPutClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutClassPipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutClassPipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutClassPipeProperty_allowed(any);} }; // Command DbPutDevicePipeProperty class definition class DbPutDevicePipePropertyClass : public Tango::Command { public: DbPutDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbPutDevicePipePropertyClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbPutDevicePipePropertyClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbPutDevicePipeProperty_allowed(any);} }; // Command DbGetClassPipePropertyHist class definition class DbGetClassPipePropertyHistClass : public Tango::Command { public: DbGetClassPipePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetClassPipePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetClassPipePropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetClassPipePropertyHist_allowed(any);} }; // Command DbGetDevicePipePropertyHist class definition class DbGetDevicePipePropertyHistClass : public Tango::Command { public: DbGetDevicePipePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetDevicePipePropertyHistClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetDevicePipePropertyHistClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetDevicePipePropertyHist_allowed(any);} }; // Command DbGetForwardedAttributeListForDevice class definition class DbGetForwardedAttributeListForDeviceClass : public Tango::Command { public: DbGetForwardedAttributeListForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; DbGetForwardedAttributeListForDeviceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~DbGetForwardedAttributeListForDeviceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_DbGetForwardedAttributeListForDevice_allowed(any);} }; /** * The DataBaseClass singleton definition */ #ifdef _TG_WINDOWS_ class __declspec(dllexport) DataBaseClass : public Tango::DeviceClass #else class DataBaseClass : public Tango::DeviceClass #endif { /*----- PROTECTED REGION ID(DataBaseClass::Additionnal DServer data members) ENABLED START -----*/ public: /*----- PROTECTED REGION END -----*/ // DataBaseClass::Additionnal DServer data members public: // write class properties data members Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static DataBaseClass *init(const char *); static DataBaseClass *instance(); ~DataBaseClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: DataBaseClass(string &); static DataBaseClass *_instance; void command_factory(); void attribute_factory(vector &); void pipe_factory(); void write_class_property(); void set_default_property(); void get_class_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); void create_static_attribute_list(vector &); void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector &); vector defaultAttList; Tango::Attr *get_attr_object_by_name(vector &att_list, string attname); }; } // End of namespace #endif // DataBase_H tango-9.2.5a/cppserver/database/update_starter.h0000644023471100065110000000474313034745007016715 00000000000000//============================================================================= // // file : UpdateStarter.h // // description : include for thread to inform Strater to update from database // // project : Starter for Tango Administration // // $Author: pascal_verdier $ // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Revision: 22233 $ // $Date: 2013-03-08 13:35:56 +0100 (Fri, 08 Mar 2013) $ // // $HeadURL:$ // //============================================================================= #ifndef _UPD_STARTER_THREAD_H #define _UPD_STARTER_THREAD_H #include namespace DataBase_ns { /** * @author $Author: pascal_verdier $ * @version $Revision: 22233 $ */ //========================================================= /** * Shared data between DS and thread. */ //========================================================= class UpdStarterData: public Tango::TangoMonitor { private: vector starter_devnames; public: UpdStarterData(); /** * Get the host name to send cmd */ vector get_starter_devname(); /** * Set the host name to send cmd */ void send_starter_cmd(vector hostname); }; //========================================================= /** * Create a thread to prevent starter to update from database */ //========================================================= class UpdateStarter: public omni_thread { private: /** * Shared data */ UpdStarterData *shared; public: /** * Create a thread to prevent starter to update from database */ UpdateStarter(UpdStarterData *); /** * Execute the thread loop. */ void *run_undetached(void *); void start() {start_undetached();} }; } // namespace #endif // _UPD_STARTER_THREAD_H tango-9.2.5a/cppserver/tangoaccesscontrol/0000755023471100065110000000000013034745262015720 500000000000000tango-9.2.5a/cppserver/tangoaccesscontrol/Makefile.am0000644023471100065110000000177613034745020017677 00000000000000SUBDIRS = ../AbstractClass AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/cppserver/AbstractClass/AccessControl \ $(DB_CFLAGS) $(LIBZMQ_CFLAGS) bin_PROGRAMS=TangoAccessControl TangoAccessControl_SOURCES=ClassFactory.cpp \ TangoAccessControlClass.cpp \ TangoAccessControl.cpp \ TangoAccessControlStateMachine.cpp \ DbUtils.cpp \ main.cpp \ TangoAccessControl.h \ TangoAccessControlClass.h TangoAccessControl_LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(DB_LDFLAGS) $(DB_LDLIBS) $(LIBZMQ_LIBS) \ ../AbstractClass/AccessControl/libaccesscontrol.la tango-9.2.5a/cppserver/tangoaccesscontrol/Makefile.in0000644023471100065110000006754113034745121017714 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = TangoAccessControl$(EXEEXT) subdir = cppserver/tangoaccesscontrol DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_TangoAccessControl_OBJECTS = ClassFactory.$(OBJEXT) \ TangoAccessControlClass.$(OBJEXT) TangoAccessControl.$(OBJEXT) \ TangoAccessControlStateMachine.$(OBJEXT) DbUtils.$(OBJEXT) \ main.$(OBJEXT) TangoAccessControl_OBJECTS = $(am_TangoAccessControl_OBJECTS) am__DEPENDENCIES_1 = TangoAccessControl_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ ../AbstractClass/AccessControl/libaccesscontrol.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(TangoAccessControl_SOURCES) DIST_SOURCES = $(TangoAccessControl_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = ../AbstractClass AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server \ -I$(top_srcdir)/cppserver/AbstractClass/AccessControl \ $(DB_CFLAGS) $(LIBZMQ_CFLAGS) TangoAccessControl_SOURCES = ClassFactory.cpp \ TangoAccessControlClass.cpp \ TangoAccessControl.cpp \ TangoAccessControlStateMachine.cpp \ DbUtils.cpp \ main.cpp \ TangoAccessControl.h \ TangoAccessControlClass.h TangoAccessControl_LDADD = -L$(top_builddir)/lib/cpp/client -ltango \ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango \ $(DB_LDFLAGS) $(DB_LDLIBS) $(LIBZMQ_LIBS) \ ../AbstractClass/AccessControl/libaccesscontrol.la all: all-recursive .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/tangoaccesscontrol/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/tangoaccesscontrol/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list TangoAccessControl$(EXEEXT): $(TangoAccessControl_OBJECTS) $(TangoAccessControl_DEPENDENCIES) $(EXTRA_TangoAccessControl_DEPENDENCIES) @rm -f TangoAccessControl$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TangoAccessControl_OBJECTS) $(TangoAccessControl_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClassFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DbUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoAccessControl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoAccessControlClass.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TangoAccessControlStateMachine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am \ uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/tangoaccesscontrol/ClassFactory.cpp0000644023471100065110000000417313034745020020736 00000000000000/*----- PROTECTED REGION ID(TangoAccessControl::ClassFactory.cpp) ENABLED START -----*/ static const char *RcsId = "$Header$"; //+============================================================================= // // file : ClassFactory.cpp // // description : C++ source for the class_factory method of the DServer // device class. This method is responsible to create // all class singletin for a device server. It is called // at device server startup // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /** * Create TangoAccessControlClass singleton and store it in DServer object. */ void Tango::DServer::class_factory() { add_class(TangoAccessControl_ns::TangoAccessControlClass::init("TangoAccessControl")); } /*----- PROTECTED REGION END -----*/ // TangoAccessControl::ClassFactory.cpp tango-9.2.5a/cppserver/tangoaccesscontrol/TangoAccessControlClass.cpp0000644023471100065110000011206713034745020023064 00000000000000/*----- PROTECTED REGION ID(TangoAccessControlClass.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoAccessControlClass.cpp 25304 2014-03-25 12:48:26Z pascal_verdier $"; static const char *TagName = "$Name: TangoAccessControl-Release-2.10$"; static const char *CvsPath = "$Source: $"; static const char *SvnPath = "$HeadURL: $"; static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; //============================================================================= // // file : TangoAccessControlClass.cpp // // description : C++ source for the TangoAccessControlClass. A singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the �name� once per process. // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass.cpp //------------------------------------------------------------------- /** * Create TangoAccessControlClass singleton and * return it in a C function for Python usage */ //------------------------------------------------------------------- extern "C" { #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif Tango::DeviceClass *_create_TangoAccessControl_class(const char *name) { return TangoAccessControl_ns::TangoAccessControlClass::init(name); } } namespace TangoAccessControl_ns { //=================================================================== // Initialize pointer for singleton pattern //=================================================================== TangoAccessControlClass *TangoAccessControlClass::_instance = NULL; //-------------------------------------------------------- /** * method : TangoAccessControlClass::TangoAccessControlClass(string &s) * description : constructor for the TangoAccessControlClass * * @param s The class name */ //-------------------------------------------------------- TangoAccessControlClass::TangoAccessControlClass(string &s):AccessControl_ns::AccessControlClass(s) { cout2 << "Entering TangoAccessControlClass constructor" << endl; set_default_property(); write_class_property(); /*----- PROTECTED REGION ID(TangoAccessControlClass::constructor) ENABLED START -----*/ string str_rcs(RcsId); /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::constructor cout2 << "Leaving TangoAccessControlClass constructor" << endl; } //-------------------------------------------------------- /** * method : TangoAccessControlClass::~TangoAccessControlClass() * description : destructor for the TangoAccessControlClass */ //-------------------------------------------------------- TangoAccessControlClass::~TangoAccessControlClass() { /*----- PROTECTED REGION ID(TangoAccessControlClass::destructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::destructor _instance = NULL; } //-------------------------------------------------------- /** * method : TangoAccessControlClass::init * description : Create the object if not already done. * Otherwise, just return a pointer to the object * * @param name The class name */ //-------------------------------------------------------- TangoAccessControlClass *TangoAccessControlClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new TangoAccessControlClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //-------------------------------------------------------- /** * method : TangoAccessControlClass::instance * description : Check if object already created, * and return a pointer to the object */ //-------------------------------------------------------- TangoAccessControlClass *TangoAccessControlClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //=================================================================== // Command execution method calls //=================================================================== //-------------------------------------------------------- /** * method : AddAddressForUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *AddAddressForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "AddAddressForUserClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->add_address_for_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : AddDeviceForUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *AddDeviceForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "AddDeviceForUserClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->add_device_for_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : CloneUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *CloneUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "CloneUserClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->clone_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : GetAccessClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetAccessClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetAccessClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->get_access(argin)); } //-------------------------------------------------------- /** * method : GetAccessForMultiIPClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetAccessForMultiIPClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetAccessForMultiIPClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); return insert((static_cast(device))->get_access_for_multi_ip(argin)); } //-------------------------------------------------------- /** * method : GetAddressByUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetAddressByUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetAddressByUserClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->get_address_by_user(argin)); } //-------------------------------------------------------- /** * method : GetAllowedCommandClassListClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetAllowedCommandClassListClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "GetAllowedCommandClassListClass::execute(): arrived" << endl; return insert((static_cast(device))->get_allowed_command_class_list()); } //-------------------------------------------------------- /** * method : GetAllowedCommandsClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetAllowedCommandsClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetAllowedCommandsClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->get_allowed_commands(argin)); } //-------------------------------------------------------- /** * method : GetDeviceByUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetDeviceByUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetDeviceByUserClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->get_device_by_user(argin)); } //-------------------------------------------------------- /** * method : GetDeviceClassClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetDeviceClassClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "GetDeviceClassClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); return insert((static_cast(device))->get_device_class(argin)); } //-------------------------------------------------------- /** * method : GetUsersClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *GetUsersClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "GetUsersClass::execute(): arrived" << endl; return insert((static_cast(device))->get_users()); } //-------------------------------------------------------- /** * method : RegisterServiceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *RegisterServiceClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "RegisterServiceClass::execute(): arrived" << endl; ((static_cast(device))->register_service()); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : RemoveAddressForUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *RemoveAddressForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "RemoveAddressForUserClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->remove_address_for_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : RemoveDeviceForUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *RemoveDeviceForUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "RemoveDeviceForUserClass::execute(): arrived" << endl; const Tango::DevVarStringArray *argin; extract(in_any, argin); ((static_cast(device))->remove_device_for_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : RemoveUserClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *RemoveUserClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) { cout2 << "RemoveUserClass::execute(): arrived" << endl; Tango::DevString argin; extract(in_any, argin); ((static_cast(device))->remove_user(argin)); return new CORBA::Any(); } //-------------------------------------------------------- /** * method : UnregisterServiceClass::execute() * description : method to trigger the execution of the command. * * @param device The device on which the command must be executed * @param in_any The command input data * * returns The command output data (packed in the Any object) */ //-------------------------------------------------------- CORBA::Any *UnregisterServiceClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) { cout2 << "UnregisterServiceClass::execute(): arrived" << endl; ((static_cast(device))->unregister_service()); return new CORBA::Any(); } //=================================================================== // Properties management //=================================================================== //-------------------------------------------------------- /** * Method : TangoAccessControlClass::get_class_property() * Description : Get the class property for specified name. */ //-------------------------------------------------------- Tango::DbDatum TangoAccessControlClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; i vect_data; // Set Default Class Properties // Set Default device Properties } //-------------------------------------------------------- /** * Method : TangoAccessControlClass::write_class_property() * Description : Set class description fields as property in database */ //-------------------------------------------------------- void TangoAccessControlClass::write_class_property() { // First time, check if database used if (Tango::Util::_UseDb == false) return; Tango::DbData data; string classname = get_name(); string header; string::size_type start, end; // Put title Tango::DbDatum title("ProjectTitle"); string str_title("Tango Access Control Management"); title << str_title; data.push_back(title); // Put Description Tango::DbDatum description("Description"); vector str_desc; str_desc.push_back("This class is a conceate class inherited from AccessControl abstract class.
"); str_desc.push_back("
"); str_desc.push_back("This class defines how to manage the TANGO access control.
"); str_desc.push_back("It implements commands for tool to defines access for users, devices and IP addresses.
"); str_desc.push_back("It implements also commands used by client API to check access for specified user, device and address.
"); str_desc.push_back("And it implements register and unregister it as TANGO service."); description << str_desc; data.push_back(description); // put cvs or svn location string filename("TangoAccessControl"); filename += "Class.cpp"; // check for cvs information string src_path(CvsPath); start = src_path.find("/"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { string strloc = src_path.substr(start, end-start); // Check if specific repository start = strloc.find("/cvsroot/"); if (start!=string::npos && start>0) { string repository = strloc.substr(0, start); if (repository.find("/segfs/")!=string::npos) strloc = "ESRF:" + strloc.substr(start, strloc.length()-start); } Tango::DbDatum cvs_loc("cvs_location"); cvs_loc << strloc; data.push_back(cvs_loc); } } // check for svn information else { string src_path(SvnPath); start = src_path.find("://"); if (start!=string::npos) { end = src_path.find(filename); if (end>start) { header = "$HeadURL: "; start = header.length(); string strloc = src_path.substr(start, (end-start)); Tango::DbDatum svn_loc("svn_location"); svn_loc << strloc; data.push_back(svn_loc); } } } // Get CVS or SVN revision tag // CVS tag string tagname(TagName); header = "$Name: "; start = header.length(); string endstr(" $"); end = tagname.find(endstr); if (end!=string::npos && end>start) { string strtag = tagname.substr(start, end-start); Tango::DbDatum cvs_tag("cvs_tag"); cvs_tag << strtag; data.push_back(cvs_tag); } // SVN tag string svnpath(SvnPath); header = "$HeadURL: "; start = header.length(); end = svnpath.find(endstr); if (end!=string::npos && end>start) { string strloc = svnpath.substr(start, end-start); string tagstr ("/tags/"); start = strloc.find(tagstr); if ( start!=string::npos ) { start = start + tagstr.length(); end = strloc.find(filename); string strtag = strloc.substr(start, end-start-1); Tango::DbDatum svn_tag("svn_tag"); svn_tag << strtag; data.push_back(svn_tag); } } // Get URL location string httpServ(HttpServer); if (httpServ.length()>0) { Tango::DbDatum db_doc_url("doc_url"); db_doc_url << httpServ; data.push_back(db_doc_url); } // Put inheritance Tango::DbDatum inher_datum("InheritedFrom"); vector inheritance; inheritance.push_back("Tango::Device_4Impl"); inher_datum << inheritance; data.push_back(inher_datum); // Call database and and values get_db_class()->put_property(data); } //=================================================================== // Factory methods //=================================================================== //-------------------------------------------------------- /** * Method : TangoAccessControlClass::device_factory() * Description : Create the device object(s) * and store them in the device list */ //-------------------------------------------------------- void TangoAccessControlClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { /*----- PROTECTED REGION ID(TangoAccessControlClass::device_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::device_factory_before // Create devices and add it into the device list for (unsigned long i=0 ; ilength() ; i++) { cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; device_list.push_back(new TangoAccessControl(this, (*devlist_ptr)[i])); } // Manage dynamic attributes if any erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); // Export devices to the outside world for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) { // Add dynamic attributes if any TangoAccessControl *dev = static_cast(device_list[device_list.size()-i]); dev->add_dynamic_attributes(); // Check before if database used. if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) export_device(dev); else export_device(dev, dev->get_name().c_str()); } /*----- PROTECTED REGION ID(TangoAccessControlClass::device_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::device_factory_after } //-------------------------------------------------------- /** * Method : TangoAccessControlClass::attribute_factory() * Description : Create the attribute object(s) * and store them in the attribute list */ //-------------------------------------------------------- void TangoAccessControlClass::attribute_factory(vector &att_list) { /*----- PROTECTED REGION ID(TangoAccessControlClass::attribute_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::attribute_factory_before // Call atribute_factory for inherited class AccessControl_ns::AccessControlClass::attribute_factory(att_list); // Create a list of static attributes create_static_attribute_list(get_class_attr()->get_attr_list()); /*----- PROTECTED REGION ID(TangoAccessControlClass::attribute_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::attribute_factory_after } //-------------------------------------------------------- /** * Method : TangoAccessControlClass::command_factory() * Description : Create the command object(s) * and store them in the command list */ //-------------------------------------------------------- void TangoAccessControlClass::command_factory() { /*----- PROTECTED REGION ID(TangoAccessControlClass::command_factory_before) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::command_factory_before // Call command_factory for inherited class AccessControl_ns::AccessControlClass::command_factory(); // Get inherited Command object AddAddressForUser if already created try { get_cmd_by_name("AddAddressForUser"); } catch (Tango::DevFailed &e) { // Create AddAddressForUser command object AddAddressForUserClass *pAddAddressForUserCmd = new AddAddressForUserClass("AddAddressForUser", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "user name, address", "", Tango::OPERATOR); command_list.push_back(pAddAddressForUserCmd); } // Get inherited Command object AddDeviceForUser if already created try { get_cmd_by_name("AddDeviceForUser"); } catch (Tango::DevFailed &e) { // Create AddDeviceForUser command object AddDeviceForUserClass *pAddDeviceForUserCmd = new AddDeviceForUserClass("AddDeviceForUser", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "user name, device adn value", "", Tango::OPERATOR); command_list.push_back(pAddDeviceForUserCmd); } // Get inherited Command object CloneUser if already created try { get_cmd_by_name("CloneUser"); } catch (Tango::DevFailed &e) { // Create CloneUser command object CloneUserClass *pCloneUserCmd = new CloneUserClass("CloneUser", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "[0] - source user name.\n[1] - target user name.", "", Tango::OPERATOR); command_list.push_back(pCloneUserCmd); } // Get inherited Command object GetAccess if already created try { get_cmd_by_name("GetAccess"); } catch (Tango::DevFailed &e) { // Create GetAccess command object GetAccessClass *pGetAccessCmd = new GetAccessClass("GetAccess", Tango::DEVVAR_STRINGARRAY, Tango::DEV_STRING, "[0] - User name\n[1] - IP Address\n[2] - Device", "access for specified inputs read/write.", Tango::OPERATOR); command_list.push_back(pGetAccessCmd); } // Get inherited Command object GetAccessForMultiIP if already created try { get_cmd_by_name("GetAccessForMultiIP"); } catch (Tango::DevFailed &e) { // Create GetAccessForMultiIP command object GetAccessForMultiIPClass *pGetAccessForMultiIPCmd = new GetAccessForMultiIPClass("GetAccessForMultiIP", Tango::DEVVAR_STRINGARRAY, Tango::DEV_STRING, "[0] - User name\n[1] - Device\n[2] - IP Address #1\n[3] - IP Address #2\n[4] - IP Address #3\n[5] - IP Address #4\n......", "access for specified inputs read/write.", Tango::OPERATOR); command_list.push_back(pGetAccessForMultiIPCmd); } // Get inherited Command object GetAddressByUser if already created try { get_cmd_by_name("GetAddressByUser"); } catch (Tango::DevFailed &e) { // Create GetAddressByUser command object GetAddressByUserClass *pGetAddressByUserCmd = new GetAddressByUserClass("GetAddressByUser", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "user name.", "Addresses found for the specified user.", Tango::OPERATOR); command_list.push_back(pGetAddressByUserCmd); } // Get inherited Command object GetAllowedCommandClassList if already created try { get_cmd_by_name("GetAllowedCommandClassList"); } catch (Tango::DevFailed &e) { // Create GetAllowedCommandClassList command object GetAllowedCommandClassListClass *pGetAllowedCommandClassListCmd = new GetAllowedCommandClassListClass("GetAllowedCommandClassList", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "", "Class names which have AllowedAccessCmd property defined.", Tango::OPERATOR); command_list.push_back(pGetAllowedCommandClassListCmd); } // Get inherited Command object GetAllowedCommands if already created try { get_cmd_by_name("GetAllowedCommands"); } catch (Tango::DevFailed &e) { // Create GetAllowedCommands command object GetAllowedCommandsClass *pGetAllowedCommandsCmd = new GetAllowedCommandsClass("GetAllowedCommands", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "Device name OR Device Class name", "Allowed commands found in database for specified device", Tango::OPERATOR); command_list.push_back(pGetAllowedCommandsCmd); } // Get inherited Command object GetDeviceByUser if already created try { get_cmd_by_name("GetDeviceByUser"); } catch (Tango::DevFailed &e) { // Create GetDeviceByUser command object GetDeviceByUserClass *pGetDeviceByUserCmd = new GetDeviceByUserClass("GetDeviceByUser", Tango::DEV_STRING, Tango::DEVVAR_STRINGARRAY, "user name.", "devices and rights found for the specified user.", Tango::OPERATOR); command_list.push_back(pGetDeviceByUserCmd); } // Get inherited Command object GetDeviceClass if already created try { get_cmd_by_name("GetDeviceClass"); } catch (Tango::DevFailed &e) { // Create GetDeviceClass command object GetDeviceClassClass *pGetDeviceClassCmd = new GetDeviceClassClass("GetDeviceClass", Tango::DEV_STRING, Tango::DEV_STRING, "Device name", "Class found in database for specified device", Tango::OPERATOR); command_list.push_back(pGetDeviceClassCmd); } // Get inherited Command object GetUsers if already created try { get_cmd_by_name("GetUsers"); } catch (Tango::DevFailed &e) { // Create GetUsers command object GetUsersClass *pGetUsersCmd = new GetUsersClass("GetUsers", Tango::DEV_VOID, Tango::DEVVAR_STRINGARRAY, "", "Users find in table access_address.", Tango::OPERATOR); command_list.push_back(pGetUsersCmd); } // Get inherited Command object RegisterService if already created try { get_cmd_by_name("RegisterService"); } catch (Tango::DevFailed &e) { // Create RegisterService command object RegisterServiceClass *pRegisterServiceCmd = new RegisterServiceClass("RegisterService", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::OPERATOR); command_list.push_back(pRegisterServiceCmd); } // Get inherited Command object RemoveAddressForUser if already created try { get_cmd_by_name("RemoveAddressForUser"); } catch (Tango::DevFailed &e) { // Create RemoveAddressForUser command object RemoveAddressForUserClass *pRemoveAddressForUserCmd = new RemoveAddressForUserClass("RemoveAddressForUser", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "user name, address", "", Tango::OPERATOR); command_list.push_back(pRemoveAddressForUserCmd); } // Get inherited Command object RemoveDeviceForUser if already created try { get_cmd_by_name("RemoveDeviceForUser"); } catch (Tango::DevFailed &e) { // Create RemoveDeviceForUser command object RemoveDeviceForUserClass *pRemoveDeviceForUserCmd = new RemoveDeviceForUserClass("RemoveDeviceForUser", Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, "user name, device and value", "", Tango::OPERATOR); command_list.push_back(pRemoveDeviceForUserCmd); } // Get inherited Command object RemoveUser if already created try { get_cmd_by_name("RemoveUser"); } catch (Tango::DevFailed &e) { // Create RemoveUser command object RemoveUserClass *pRemoveUserCmd = new RemoveUserClass("RemoveUser", Tango::DEV_STRING, Tango::DEV_VOID, "user name", "", Tango::OPERATOR); command_list.push_back(pRemoveUserCmd); } // Get inherited Command object UnregisterService if already created try { get_cmd_by_name("UnregisterService"); } catch (Tango::DevFailed &e) { // Create UnregisterService command object UnregisterServiceClass *pUnregisterServiceCmd = new UnregisterServiceClass("UnregisterService", Tango::DEV_VOID, Tango::DEV_VOID, "", "", Tango::OPERATOR); command_list.push_back(pUnregisterServiceCmd); } /*----- PROTECTED REGION ID(TangoAccessControlClass::command_factory_after) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::command_factory_after } //=================================================================== // Dynamic attributes related methods //=================================================================== //-------------------------------------------------------- /** * method : TangoAccessControlClass::create_static_attribute_list * description : Create the a list of static attributes * * @param att_list the ceated attribute list */ //-------------------------------------------------------- void TangoAccessControlClass::create_static_attribute_list(vector &att_list) { for (unsigned long i=0 ; iget_name()); transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); defaultAttList.push_back(att_name); } cout2 << defaultAttList.size() << " attributes in default list" << endl; /*----- PROTECTED REGION ID(TangoAccessControlClass::create_static_att_list) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::create_static_att_list } //-------------------------------------------------------- /** * method : TangoAccessControlClass::erase_dynamic_attributes * description : delete the dynamic attributes if any. * * @param devlist_ptr the device list pointer * @param list of all attributes */ //-------------------------------------------------------- void TangoAccessControlClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector &att_list) { Tango::Util *tg = Tango::Util::instance(); for (unsigned long i=0 ; ilength() ; i++) { Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); TangoAccessControl *dev = static_cast (dev_impl); vector &dev_att_list = dev->get_device_attr()->get_attribute_list(); vector::iterator ite_att; for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) { string att_name((*ite_att)->get_name_lower()); if ((att_name == "state") || (att_name == "status")) continue; vector::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); if (ite_str == defaultAttList.end()) { cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); dev->remove_attribute(att_list[att.get_attr_idx()], true, false); --ite_att; } } } /*----- PROTECTED REGION ID(TangoAccessControlClass::erase_dynamic_attributes) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::erase_dynamic_attributes } //-------------------------------------------------------- /** * Method : TangoAccessControlClass::get_attr_by_name() * Description : returns Tango::Attr * object found by name */ //-------------------------------------------------------- Tango::Attr *TangoAccessControlClass::get_attr_object_by_name(vector &att_list, string attname) { vector::iterator it; for (it=att_list.begin() ; itget_name()==attname) return (*it); // Attr does not exist return NULL; } /*----- PROTECTED REGION ID(TangoAccessControlClass::Additional Methods) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::Additional Methods } // namespace tango-9.2.5a/cppserver/tangoaccesscontrol/TangoAccessControl.cpp0000644023471100065110000010616713034745020022102 00000000000000/*----- PROTECTED REGION ID(TangoAccessControl.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoAccessControl.cpp 25304 2014-03-25 12:48:26Z pascal_verdier $"; //============================================================================= // // file : TangoAccessControl.cpp // // description : C++ source for the TangoAccessControl and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // TangoAccessControl are implemented in this file. // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include #include /*----- PROTECTED REGION END -----*/ // TangoAccessControl.cpp /** * TangoAccessControl class description: * This class is a conceate class inherited from AccessControl abstract class.
*
* This class defines how to manage the TANGO access control.
* It implements commands for tool to defines access for users, devices and IP addresses.
* It implements also commands used by client API to check access for specified user, device and address.
* And it implements register and unregister it as TANGO service. */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | Inherited (no method) // Status | Inherited (no method) // AddAddressForUser | add_address_for_user // AddDeviceForUser | add_device_for_user // CloneUser | clone_user // GetAccess | get_access // GetAccessForMultiIP | get_access_for_multi_ip // GetAddressByUser | get_address_by_user // GetAllowedCommandClassList | get_allowed_command_class_list // GetAllowedCommands | get_allowed_commands // GetDeviceByUser | get_device_by_user // GetDeviceClass | get_device_class // GetUsers | get_users // RegisterService | register_service // RemoveAddressForUser | remove_address_for_user // RemoveDeviceForUser | remove_device_for_user // RemoveUser | remove_user // UnregisterService | unregister_service //================================================================ //================================================================ // Attributes managed is: //================================================================ //================================================================ namespace TangoAccessControl_ns { /*----- PROTECTED REGION ID(TangoAccessControl::namespace_starting) ENABLED START -----*/ // static initializations /*----- PROTECTED REGION END -----*/ // TangoAccessControl::namespace_starting //-------------------------------------------------------- /** * Method : TangoAccessControl::TangoAccessControl() * Description : Constructors for a Tango device * implementing the classTangoAccessControl */ //-------------------------------------------------------- TangoAccessControl::TangoAccessControl(Tango::DeviceClass *cl, string &s) : AccessControl(cl, s.c_str()) { /*----- PROTECTED REGION ID(TangoAccessControl::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::constructor_1 } //-------------------------------------------------------- TangoAccessControl::TangoAccessControl(Tango::DeviceClass *cl, const char *s) : AccessControl(cl, s) { /*----- PROTECTED REGION ID(TangoAccessControl::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::constructor_2 } //-------------------------------------------------------- TangoAccessControl::TangoAccessControl(Tango::DeviceClass *cl, const char *s, const char *d) : AccessControl(cl, s, d) { /*----- PROTECTED REGION ID(TangoAccessControl::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::constructor_3 } //-------------------------------------------------------- /** * Method : TangoAccessControl::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void TangoAccessControl::delete_device() { DEBUG_STREAM << "TangoAccessControl::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::delete_device) ENABLED START -----*/ // Delete device allocated objects // Delete device's allocated object /*----- PROTECTED REGION END -----*/ // TangoAccessControl::delete_device if (Tango::Util::instance()->is_svr_shutting_down() == false && Tango::Util::instance()->is_device_restarting(device_name)==false) { // If not shutting down call delete device for inherited object AccessControl_ns::AccessControl::delete_device(); } } //-------------------------------------------------------- /** * Method : TangoAccessControl::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void TangoAccessControl::init_device() { DEBUG_STREAM << "TangoAccessControl::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::init_device_before) ENABLED START -----*/ // Initialization before get_device_property() call /*----- PROTECTED REGION END -----*/ // TangoAccessControl::init_device_before if (Tango::Util::instance()->is_svr_starting() == false && Tango::Util::instance()->is_device_restarting(device_name)==false) { // If not starting up call init device for inherited object AccessControl_ns::AccessControl::init_device(); } // No device property to be read from database /*----- PROTECTED REGION ID(TangoAccessControl::init_device) ENABLED START -----*/ // These lines have obsolutely no other goals than to make the // hardening_check command happy. Without them, this command will return // missing stack-protection and missing "Fortify source" // This is for Debian packages hardening effort char host[256]; gethostname(host,sizeof(host)); sprintf(host,"Hello world\n"); // Initialize device // Initialise variables to default values //-------------------------------------------- string str_rcs(RcsId); mysql_connection(); set_state(Tango::ON); set_status("Device is OK"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::init_device } //-------------------------------------------------------- /** * Method : TangoAccessControl::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void TangoAccessControl::always_executed_hook() { INFO_STREAM << "TangoAccessControl::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::always_executed_hook) ENABLED START -----*/ // code always executed before all requests /*----- PROTECTED REGION END -----*/ // TangoAccessControl::always_executed_hook } //-------------------------------------------------------- /** * Method : TangoAccessControl::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void TangoAccessControl::read_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "TangoAccessControl::read_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(TangoAccessControl::read_attr_hardware) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // TangoAccessControl::read_attr_hardware } //-------------------------------------------------------- /** * Method : TangoAccessControl::add_dynamic_attributes() * Description : Create the dynamic attributes if any * for specified device. */ //-------------------------------------------------------- void TangoAccessControl::add_dynamic_attributes() { /*----- PROTECTED REGION ID(TangoAccessControl::add_dynamic_attributes) ENABLED START -----*/ // Add your own code to create and add dynamic attributes if any /*----- PROTECTED REGION END -----*/ // TangoAccessControl::add_dynamic_attributes } //-------------------------------------------------------- /** * Command AddAddressForUser related method * Description: Add an address for the specified user.. * * @param argin user name, address * @returns */ //-------------------------------------------------------- void TangoAccessControl::add_address_for_user(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "TangoAccessControl::AddAddressForUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::add_address_for_user) ENABLED START -----*/ if (argin->length() < 2) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 2 input arguments", (const char *)"AccessControl::add_address_for_user()"); int x = 0; string username((*argin)[x++]); string ip_add ((*argin)[x++]); // Check before if already exists TangoSys_MemStream tms; tms << "SELECT DISTINCT address FROM access_address WHERE " << "user=\"" << username << "\" AND " << "address=\"" << ip_add << "\""; DEBUG_STREAM << "add_address_for_user(): sql_query " << tms.str() << endl; MYSQL_RES *check = query(tms.str(), "add_address_for_user()"); int n_rows = mysql_num_rows(check); bool already_exists = (n_rows > 0); mysql_free_result(check); if (already_exists) Tango::Except::throw_exception((const char *)AC_AlreadyExists, (const char *)"This record already exists in database", (const char *)"AccessControl::add_address_for_user()"); // If not exists, insert it tms.str(""); tms << "INSERT INTO access_address SET user=\"" << username << "\",address=\"" << ip_add << "\""; DEBUG_STREAM << "AccessControl::add_address_for_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"add_address_for_user()"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::add_address_for_user } //-------------------------------------------------------- /** * Command AddDeviceForUser related method * Description: Add a device and rights for the specified user.. * * @param argin user name, device adn value * @returns */ //-------------------------------------------------------- void TangoAccessControl::add_device_for_user(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "TangoAccessControl::AddDeviceForUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::add_device_for_user) ENABLED START -----*/ if (argin->length() < 3) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 3 input arguments", (const char *)"AccessControl::ac_add_device_for_user()"); int x = 0; string username((*argin)[x++]); string device ((*argin)[x++]); string rights ((*argin)[x++]); // Check before if already exists TangoSys_MemStream tms; tms << "SELECT DISTINCT device FROM access_device WHERE " << "user=\"" << username << "\" AND " << "device=\"" << device << "\" AND " << "rights=\"" << rights << "\""; DEBUG_STREAM << "ac_add_device_for_user(): sql_query " << tms.str() << endl; MYSQL_RES *check = query(tms.str(), "ac_add_device_for_user()"); int n_rows = mysql_num_rows(check); bool already_exists = (n_rows > 0); mysql_free_result(check); if (already_exists) Tango::Except::throw_exception((const char *)AC_AlreadyExists, (const char *)"This record already exists in database", (const char *)"AccessControl::ac_add_device_for_user()"); // If not exists, insert it tms.str(""); tms << "INSERT INTO access_device SET user=\"" << username << "\",device=\"" << device << "\",rights=\"" << rights << "\""; DEBUG_STREAM << "AccessControl::ac_add_device_for_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"ac_add_device_for_user()"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::add_device_for_user } //-------------------------------------------------------- /** * Command CloneUser related method * Description: Copy addresses and devices from source user to target user. * * @param argin [0] - source user name.\n[1] - target user name. * @returns */ //-------------------------------------------------------- void TangoAccessControl::clone_user(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "TangoAccessControl::CloneUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::clone_user) ENABLED START -----*/ if (argin->length() < 2) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 2 input arguments", (const char *)"AccessControl::clone_user()"); int x = 0; string src_user((*argin)[x++]); string new_user((*argin)[x++]); // remove new user if already exists remove_user((char *)new_user.c_str()); // Get address for source user TangoSys_MemStream tms; tms << "SELECT DISTINCT address FROM access_address WHERE user" << "=\"" << src_user << "\" ORDER BY address"; DEBUG_STREAM << "AccessControl::clone_user(): sql_query " << tms.str() << endl; MYSQL_RES *result = query(tms.str(), "clone_user()"); int n_rows = mysql_num_rows(result); vector v_add; if (n_rows > 0) for (int i=0; i v_dev; if (n_rows > 0) for (int j=0; jlength() < 3) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 3 input arguments", (const char *)"AccessControl::get_access()"); int x = 0; string user((*argin)[x++]); string ip_add((*argin)[x++]); string device((*argin)[x++]); // First pass, Check if User,address is defined (autorized) vector as_read = get_access_for_user_address(user, ip_add); // Check if first pass has results if (as_read.empty()==true) { argout = CORBA::string_dup("read"); return argout; } /* for (int i=0 ; i // second pass, Check if User,device is defined string result = get_access_for_user_device(user, device);; argout = CORBA::string_dup(result.c_str()); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::get_access return argout; } //-------------------------------------------------------- /** * Command GetAccessForMultiIP related method * Description: Check access for specified user, device and addresses * and returns access (read or write). * * @param argin [0] - User name * [1] - Device * [2] - IP Address #1 * [3] - IP Address #2 * [4] - IP Address #3 * [5] - IP Address #4 * ...... * @returns access for specified inputs read/write. */ //-------------------------------------------------------- Tango::DevString TangoAccessControl::get_access_for_multi_ip(const Tango::DevVarStringArray *argin) { Tango::DevString argout; DEBUG_STREAM << "TangoAccessControl::GetAccessForMultiIP() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::get_access_for_multi_ip) ENABLED START -----*/ if (argin->length() < 3) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 3 input arguments", (const char *)"AccessControl::get_access()"); unsigned int x = 0; string user((*argin)[x++]); string device((*argin)[x++]); // First pass, Check if User and at least one of the addresses is defined (autorized) bool ip_found = false; while (x < argin->length() && !ip_found) { string ip_add((*argin)[x++]); vector as_read = get_access_for_user_address(user, ip_add); // Check if first pass has results if (as_read.empty()==false) { ip_found = true; /* for (int i=0 ; i // second pass, Check if User,device is defined string result = get_access_for_user_device(user, device);; argout = CORBA::string_dup(result.c_str()); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::get_access_for_multi_ip return argout; } //-------------------------------------------------------- /** * Command GetAddressByUser related method * Description: Returns address list found for the specified user. * * @param argin user name. * @returns Addresses found for the specified user. */ //-------------------------------------------------------- Tango::DevVarStringArray *TangoAccessControl::get_address_by_user(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "TangoAccessControl::GetAddressByUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::get_address_by_user) ENABLED START -----*/ string username(argin); TangoSys_MemStream tms; tms << "SELECT DISTINCT address FROM access_address WHERE user" << "=\"" << username << "\" ORDER BY address"; DEBUG_STREAM << "AccessControl::get_address_by_user(): sql_query " << tms.str() << endl; MYSQL_RES *result = query(tms.str(), "get_address_by_user()"); int n_rows = mysql_num_rows(result); argout = new Tango::DevVarStringArray; if (n_rows > 0) { int nb_col = 1; argout->length(n_rows*nb_col); int nb=0; for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::get_address_by_user return argout; } //-------------------------------------------------------- /** * Command GetAllowedCommandClassList related method * Description: Returns the class names which have AllowedAccessCmd property defined. * * @param argin * @returns Class names which have AllowedAccessCmd property defined. */ //-------------------------------------------------------- Tango::DevVarStringArray *TangoAccessControl::get_allowed_command_class_list() { Tango::DevVarStringArray *argout; DEBUG_STREAM << "TangoAccessControl::GetAllowedCommandClassList() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::get_allowed_command_class_list) ENABLED START -----*/ TangoSys_MemStream tms; tms << "SELECT DISTINCT class FROM property_class WHERE name = \"AllowedAccessCmd\" ORDER BY class"; DEBUG_STREAM << "AccessControl::get_allowed_commands(): sql_query " << tms.str() << endl; MYSQL_RES *result = query(tms.str(),"get_allowed_commands_class_list()"); int n_rows = mysql_num_rows(result); argout = new Tango::DevVarStringArray; argout->length(n_rows); if (n_rows > 0) { for (int i=0; iAllowedAccessCmd * * @param argin Device name OR Device Class name * @returns Allowed commands found in database for specified device */ //-------------------------------------------------------- Tango::DevVarStringArray *TangoAccessControl::get_allowed_commands(Tango::DevString argin) { Tango::DevVarStringArray *argout; DEBUG_STREAM << "TangoAccessControl::GetAllowedCommands() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::get_allowed_commands) ENABLED START -----*/ string classname; string full_dev_name(argin); if (full_dev_name.find('/') == string::npos) classname = argin; else classname = get_device_class(argin); TangoSys_MemStream tms; tms << "SELECT value FROM property_class WHERE class = \"" << classname.c_str() << "\" AND name =\"AllowedAccessCmd\" ORDER by value"; DEBUG_STREAM << "AccessControl::get_allowed_commands(): sql_query " << tms.str() << endl; MYSQL_RES *result = query(tms.str(),"get_allowed_commands()"); int n_rows = mysql_num_rows(result); argout = new Tango::DevVarStringArray; argout->length(n_rows+2); // Add State and Status commands for all classe and devices (*argout)[0] = CORBA::string_dup("State"); (*argout)[1] = CORBA::string_dup("Status"); if (n_rows > 0) { for (int i=0; i 0) { int nb_col = 2; argout->length(n_rows*nb_col); int nb=0; for (int i=0; ilength(0); mysql_free_result(result); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::get_device_by_user return argout; } //-------------------------------------------------------- /** * Command GetDeviceClass related method * Description: Returns class for specified device. * * @param argin Device name * @returns Class found in database for specified device */ //-------------------------------------------------------- Tango::DevString TangoAccessControl::get_device_class(Tango::DevString argin) { Tango::DevString argout; DEBUG_STREAM << "TangoAccessControl::GetDeviceClass() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::get_device_class) ENABLED START -----*/ argout = NULL; // Get class for device TangoSys_MemStream tms; tms << "SELECT DISTINCT class FROM device WHERE name=\"" << argin << "\""; DEBUG_STREAM << "AccessControl::get_device_class(): sql_query " << tms.str() << endl; MYSQL_RES *result = query(tms.str(), "get_device_class()"); int n_rows = mysql_num_rows(result); if (n_rows==0) { TangoSys_MemStream tms; tms << "Class not found for " << argin; Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)tms.str().c_str(), (const char *)"AccessControl::get_device_class()"); } if (n_rows > 0) for (int i=0; i users; if (n_rows > 0) for (int i=0; i 0) for (int i=0; ilength(users.size()); for (unsigned int i=0 ; ilength() < 2) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 2 input arguments", (const char *)"AccessControl::remove_address_for_user()"); int x = 0; string username((*argin)[x++]); string ip_add ((*argin)[x++]); TangoSys_MemStream tms; tms << "DELETE FROM access_address WHERE user=\"" << username << "\" AND address=\"" << ip_add << "\""; DEBUG_STREAM << "AccessControl::remove_address_for_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"remove_address_for_user()"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::remove_address_for_user } //-------------------------------------------------------- /** * Command RemoveDeviceForUser related method * Description: Remove a device and its rights for the specified user.. * * @param argin user name, device and value * @returns */ //-------------------------------------------------------- void TangoAccessControl::remove_device_for_user(const Tango::DevVarStringArray *argin) { DEBUG_STREAM << "TangoAccessControl::RemoveDeviceForUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::remove_device_for_user) ENABLED START -----*/ if (argin->length() < 3) Tango::Except::throw_exception((const char *)AC_IncorrectArguments, (const char *)"Needs at least 3 input arguments", (const char *)"AccessControl::remove_device_for_user()"); int x = 0; string username((*argin)[x++]); string device ((*argin)[x++]); string rights ((*argin)[x++]); TangoSys_MemStream tms; tms << "DELETE FROM access_device WHERE user=\"" << username << "\" AND device=\"" << device << "\" AND rights=\"" << rights << "\""; DEBUG_STREAM << "AccessControl::remove_device_for_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"remove_device_for_user()"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::remove_device_for_user } //-------------------------------------------------------- /** * Command RemoveUser related method * Description: Remove all records for specified user. * * @param argin user name * @returns */ //-------------------------------------------------------- void TangoAccessControl::remove_user(Tango::DevString argin) { DEBUG_STREAM << "TangoAccessControl::RemoveUser() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::remove_user) ENABLED START -----*/ // remove user if already exists in address table TangoSys_MemStream tms; tms << "DELETE FROM access_device WHERE user=\"" << argin << "\" AND device LIKE \"%\"" << " AND rights LIKE \"%\""; DEBUG_STREAM << "AccessControl::clone_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"clone_user()"); // remove user if already exists in device table tms.str(""); tms << "DELETE FROM access_address WHERE user=\"" << argin << "\" AND address LIKE \"%\""; DEBUG_STREAM << "AccessControl::clone_user(): sql_query " << tms.str() << endl; simple_query(tms.str(),"clone_user()"); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::remove_user } //-------------------------------------------------------- /** * Command UnregisterService related method * Description: Unregister device as a TANGO service. * * @param argin * @returns */ //-------------------------------------------------------- void TangoAccessControl::unregister_service() { DEBUG_STREAM << "TangoAccessControl::UnregisterService() - " << device_name << endl; /*----- PROTECTED REGION ID(TangoAccessControl::unregister_service) ENABLED START -----*/ unregister_service(ServiceName, InatanceName, device_name); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::unregister_service } /*----- PROTECTED REGION ID(TangoAccessControl::namespace_ending) ENABLED START -----*/ // Additional Methods /*----- PROTECTED REGION END -----*/ // TangoAccessControl::namespace_ending } // namespace tango-9.2.5a/cppserver/tangoaccesscontrol/TangoAccessControlStateMachine.cpp0000644023471100065110000003112513034745020024357 00000000000000/*----- PROTECTED REGION ID(TangoAccessControlStateMachine.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: TangoAccessControlStateMachine.cpp 25304 2014-03-25 12:48:26Z pascal_verdier $"; //============================================================================= // // file : TangoAccessControlStateMachine.cpp // // description : C++ source for the �name� and its alowed // methods for commands and attributes // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /*----- PROTECTED REGION END -----*/ // TangoAccessControl::TangoAccessControlStateMachine.cpp //================================================================ // States | Description //================================================================ // ON | The MySql database handle is OK. // FAULT | The MySql database handle is not OK. namespace TangoAccessControl_ns { //================================================= // Attributes Allowed Methods //================================================= //================================================= // Commands Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : TangoAccessControl::is_AddAddressForUser_allowed() * Description : Execution allowed for AddAddressForUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_AddAddressForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::AddAddressForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::AddAddressForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_AddDeviceForUser_allowed() * Description : Execution allowed for AddDeviceForUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_AddDeviceForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::AddDeviceForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::AddDeviceForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_CloneUser_allowed() * Description : Execution allowed for CloneUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_CloneUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::CloneUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::CloneUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetAccess_allowed() * Description : Execution allowed for GetAccess attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetAccess_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for GetAccess command. /*----- PROTECTED REGION ID(TangoAccessControl::GetAccessStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetAccessStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetAccessForMultiIP_allowed() * Description : Execution allowed for GetAccessForMultiIP attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetAccessForMultiIP_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for GetAccessForMultiIP command. /*----- PROTECTED REGION ID(TangoAccessControl::GetAccessForMultiIPStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetAccessForMultiIPStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetAddressByUser_allowed() * Description : Execution allowed for GetAddressByUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetAddressByUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::GetAddressByUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetAddressByUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetAllowedCommandClassList_allowed() * Description : Execution allowed for GetAllowedCommandClassList attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetAllowedCommandClassList_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for GetAllowedCommandClassList command. /*----- PROTECTED REGION ID(TangoAccessControl::GetAllowedCommandClassListStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetAllowedCommandClassListStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetAllowedCommands_allowed() * Description : Execution allowed for GetAllowedCommands attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetAllowedCommands_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::GetAllowedCommandsStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetAllowedCommandsStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetDeviceByUser_allowed() * Description : Execution allowed for GetDeviceByUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetDeviceByUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::GetDeviceByUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetDeviceByUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetDeviceClass_allowed() * Description : Execution allowed for GetDeviceClass attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetDeviceClass_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::GetDeviceClassStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetDeviceClassStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_GetUsers_allowed() * Description : Execution allowed for GetUsers attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_GetUsers_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::GetUsersStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::GetUsersStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_RegisterService_allowed() * Description : Execution allowed for RegisterService attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_RegisterService_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for RegisterService command. /*----- PROTECTED REGION ID(TangoAccessControl::RegisterServiceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::RegisterServiceStateAllowed return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_RemoveAddressForUser_allowed() * Description : Execution allowed for RemoveAddressForUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_RemoveAddressForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::RemoveAddressForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::RemoveAddressForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_RemoveDeviceForUser_allowed() * Description : Execution allowed for RemoveDeviceForUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_RemoveDeviceForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::RemoveDeviceForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::RemoveDeviceForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_RemoveUser_allowed() * Description : Execution allowed for RemoveUser attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_RemoveUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(TangoAccessControl::RemoveUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::RemoveUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : TangoAccessControl::is_UnregisterService_allowed() * Description : Execution allowed for UnregisterService attribute */ //-------------------------------------------------------- bool TangoAccessControl::is_UnregisterService_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for UnregisterService command. /*----- PROTECTED REGION ID(TangoAccessControl::UnregisterServiceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControl::UnregisterServiceStateAllowed return true; } } // End of namespace tango-9.2.5a/cppserver/tangoaccesscontrol/DbUtils.cpp0000644023471100065110000003741313034745020017712 00000000000000static const char *RcsId = "$Id: DbUtils.cpp 28800 2015-11-27 13:16:34Z taurel $"; //+============================================================================= // // file : DbUtils.cpp // // description : C++ source for the DbUtils. // // project : TANGO Device Server // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: taurel $ // // $Revision: 28800 $ // $Date: 2015-11-27 14:16:34 +0100 (Fri, 27 Nov 2015) $ // //============================================================================= #if HAVE_CONFIG_H #include #endif #include #include #include namespace TangoAccessControl_ns { //+------------------------------------------------------------------ /** * Remove the Fully Qualify Domain Name for tango less than 5.2 compatibility */ //+------------------------------------------------------------------ string TangoAccessControl::removeFQDN(string s) { string::size_type pos = s.find('.'); if (pos == string::npos) return s; else return s.substr(0, pos); } //+---------------------------------------------------------------------------- // // method : TangoAccessControl::mysql_connection() // // description : Execute a SQL query , ignore the result. // //----------------------------------------------------------------------------- void TangoAccessControl::mysql_connection() { // Initialise variables to default values //-------------------------------------------- #ifndef HAVE_CONFIG_H char *database = (char *)"tango"; #else char *database = (char *)TANGO_DB_NAME; #endif const char *mysql_user = NULL; const char *mysql_password = NULL; const char *mysql_host = NULL; const char *mysql_name = NULL; unsigned int port_num = 0; WARN_STREAM << "AccessControl::init_device() create database device " << device_name << endl; // Initialise mysql database structure and connect to TANGO database mysql_init(&mysql); DummyDev d; string my_user,my_password,my_host,my_name; string ho,port; if (d.get_env_var("MYSQL_USER",my_user) != -1) { mysql_user = my_user.c_str(); } if (d.get_env_var("MYSQL_PASSWORD",my_password) != -1) { mysql_password = my_password.c_str(); } if (d.get_env_var("MYSQL_HOST",my_host) != -1) { string::size_type pos = my_host.find(':'); if (pos != string::npos) { ho = my_host.substr(0,pos); pos++; port = my_host.substr(pos); stringstream ss(port); ss >> port_num; if (!ss) port_num = 0; mysql_host = ho.c_str(); } else mysql_host = my_host.c_str(); } if (d.get_env_var("MYSQL_DATABASE",my_name) != -1) { mysql_name = my_name.c_str(); } if (mysql_name != NULL) { database = const_cast(mysql_name); } WARN_STREAM << "AccessControl::init_device() mysql database user = " << mysql_user << " , password = " << mysql_password << endl; mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); #if (MYSQL_VERSION_ID > 50000) if(mysql_get_client_version() >= 50013) { my_bool my_auto_reconnect=1; if (mysql_options(&mysql,MYSQL_OPT_RECONNECT,&my_auto_reconnect) !=0) { ERROR_STREAM << "AccessControl: error setting mysql auto reconnection: " << mysql_error(&mysql) << endl; } else { WARN_STREAM << "AccessControl: set mysql auto reconnect to true" << endl; } } #endif if (!mysql_real_connect(&mysql, mysql_host, mysql_user, mysql_password, database, port_num, NULL, 0)) { TangoSys_MemStream out_stream; out_stream << "Failed to connect to TANGO database (error = " << mysql_error(&mysql) << ")" << ends; Tango::Except::throw_exception( (const char *)"CANNOT_CONNECT_MYSQL", out_stream.str(), (const char *)"AccessControl::init_device()"); } } //+---------------------------------------------------------------------------- // // method : TangoAccessControl::simple_query() // // description : Execute a SQL query , ignore the result. // //----------------------------------------------------------------------------- void TangoAccessControl::simple_query(string sql_query,const char *method) { TangoSys_OMemStream o; TangoSys_OMemStream o2; if (mysql_real_query(&mysql, sql_query.c_str(),sql_query.length()) != 0) { WARN_STREAM << "TangoAccessControl::" << method << " failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(&mysql) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(&mysql) << ")"; o2 << "TangoAccessControl::" << method; Tango::Except::throw_exception((const char *)AC_SQLError,o.str(),o2.str()); } } //+---------------------------------------------------------------------------- // // method : TangoAccessControl::query() // // description : Execute a SQL query and return the result. // //----------------------------------------------------------------------------- MYSQL_RES *TangoAccessControl::query(string sql_query,const char *method) { TangoSys_OMemStream o; TangoSys_OMemStream o2; MYSQL_RES *result; if (mysql_real_query(&mysql, sql_query.c_str(),sql_query.length()) != 0) { WARN_STREAM << "TangoAccessControl::" << method << " failed to query TANGO database:" << endl; WARN_STREAM << " query = " << sql_query << endl; WARN_STREAM << " (SQL error=" << mysql_error(&mysql) << ")" << endl; o << "Failed to query TANGO database (error=" << mysql_error(&mysql) << ")"; o2 << "TangoAccessControl::" << method; Tango::Except::throw_exception((const char *)AC_SQLError,o.str(),o2.str()); } if ((result = mysql_store_result(&mysql)) == NULL) { WARN_STREAM << "TangoAccessControl:: " << method << " : mysql_store_result() failed (error=" << mysql_error(&mysql) << ")" << endl; o << "mysql_store_result() failed (error=" << mysql_error(&mysql) << ")"; o2 << "TangoAccessControl::" << method; Tango::Except::throw_exception((const char *)AC_SQLError,o.str(),o2.str()); } return result; } //============================================================ /** * split device name in domain faily member in a vector. */ //============================================================ vector TangoAccessControl::get_dev_members(string &devname) { vector v; string::size_type pos = devname.find('/'); string::size_type pos2 = devname.find('/', pos+1); // domain v.push_back(devname.substr(0, pos)); pos++; // family v.push_back(devname.substr(pos, pos2-pos)); pos2++; // member v.push_back(devname.substr(pos2, devname.length()-pos2)); return v; } //============================================================ /** * split IP address in members in a vector. */ //============================================================ vector TangoAccessControl::get_ip_add_members(string &devname) { vector v; string::size_type pos = devname.find('.'); string::size_type pos1 = devname.find('.', pos+1); string::size_type pos2 = devname.find('.', pos1+1); v.push_back(devname.substr(0, pos)); pos++; v.push_back(devname.substr(pos, pos1-pos)); pos1++; v.push_back(devname.substr(pos1, pos2-pos1)); pos2++; v.push_back(devname.substr(pos2, devname.length()-pos2)); return v; } //============================================================ //============================================================ vector TangoAccessControl::get_access_for_user_address(string &user, string &ip_add) { vector v_add = get_ip_add_members(ip_add); vector as_read; TangoSys_MemStream sql_query_stream; // First, check if something defined for user. sql_query_stream << "SELECT count(*) FROM access_address WHERE user=\"" << user << "\""; MYSQL_RES *res = query(sql_query_stream.str(), "ac_get_device_by_user()"); MYSQL_ROW ro = mysql_fetch_row(res); sql_query_stream.str(""); sql_query_stream << "SELECT DISTINCT address FROM access_address WHERE "; if ((ro[0])[0] != '0') { // Something found. // User definition sql_query_stream << "(user=\"" << user << "\") AND "; } else { // User definition sql_query_stream << "(user=\"" << user << "\" OR user=\"*\") AND "; } // IP address definition sql_query_stream << "(address=\"*.*.*.*\" OR " << "address=\"" << v_add[0] << ".*.*.*\" OR " << "address=\"" << v_add[0] << "." << v_add[1] << ".*.*\" OR " << "address=\"" << v_add[0] << "." << v_add[1] << "." << v_add[2] <<".*\" OR " << "address=\"" << ip_add << "\" ) ORDER BY address DESC"; //cout << "ac_get_access(): sql_query " << sql_query_stream.str() << endl; MYSQL_RES *result = query(sql_query_stream.str(), "ac_get_device_by_user()"); int n_rows = mysql_num_rows(result); if (n_rows > 0) { for (int i=0; i members = get_dev_members(deviceLower); string retval("read"); TangoSys_MemStream sql_query_stream; sql_query_stream << "SELECT DISTINCT user,device,rights FROM access_device WHERE " << "(user=\"" << user << "\" OR user=\"*\") ORDER BY device"; //cout << "ac_get_access(): sql_query " << sql_query_stream.str() << endl; MYSQL_RES *result = query(sql_query_stream.str(), "ac_get_device_by_user()"); int n_rows = mysql_num_rows(result); vector as_user; vector as_all; if (n_rows > 0) { for (int i=0; i read if (as_user.empty() && as_all.empty()) return retval; // Get user rigths string user_rights = get_rigths(as_user, members); if (user_rights != "unknown") { //cout << user << " " << user_rights << endl; // if right has been matched -> return it return user_rights; } else { // Else return rights for all users string all_rights = get_rigths(as_all, members); if (all_rights != "unknown" && all_rights != "write") { all_rights = "read"; } return all_rights; } } //============================================================ //============================================================ string TangoAccessControl::get_rigths(vector as, vector members) { vector matches; // Get list of structure matching device name for (unsigned int i=0 ; i expMembers = get_dev_members(as[i].device); bool found = true; for (unsigned int j=0 ; found && j services; Tango::DbData data; data.push_back(Tango::DbDatum(SERVICE_PROP_NAME)); Tango::Util *tg = Tango::Util::instance(); tg->get_database()->get_property(CONTROL_SYSTEM, data); if (data[0].is_empty()==false) data[0] >> services; // Build what to be searched TangoSys_MemStream new_line; new_line << servicename << "/" << instname; string target(new_line.str()); transform(target.begin(), target.end(), target.begin(), ::tolower); new_line << ":" << devname; // Search if already exists bool exists = false; vector::iterator pos = services.begin(); for (unsigned int i=0 ; i replace pos = services.erase(pos); services.insert(pos, new_line.str()); exists = true; } } } // Else add it if (!exists) services.push_back(new_line.str()); data[0] << services; tg->get_database()->put_property(CONTROL_SYSTEM, data); } //============================================================ //============================================================ void TangoAccessControl::unregister_service(string servicename, string instname, string devname) { // Get service property vector services; Tango::DbData data; data.push_back(Tango::DbDatum(SERVICE_PROP_NAME)); Tango::Util *tg = Tango::Util::instance(); tg->get_database()->get_property(CONTROL_SYSTEM, data); if (data[0].is_empty()==false) data[0] >> services; // Build what to be searched TangoSys_MemStream line; line << servicename << "/" << instname << ":" << devname; string target(line.str()); transform(target.begin(), target.end(), target.begin(), ::tolower); // Search if exists vector::iterator pos = services.begin(); for (unsigned int i=0 ; i remove services.erase(pos); } } data[0] << services; tg->get_database()->put_property(CONTROL_SYSTEM, data); } } // namespace tango-9.2.5a/cppserver/tangoaccesscontrol/main.cpp0000644023471100065110000000530313034745020017261 00000000000000/*PROTECTED REGION ID(TangoAccessControl::main.cpp) ENABLED START*/ static const char *RcsId = "$Id: main.cpp 25304 2014-03-25 12:48:26Z pascal_verdier $"; //============================================================================= // // file : TangoAccessControl.cpp // // description : C++ source for the TangoAccessControl device server main. // The main rule is to initialise (and create) the Tango // system and to create the DServerClass singleton. // The main should be the same for every Tango device server. // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include int main(int argc,char *argv[]) { Tango::Util *tg = NULL; try { // Initialise the device server //---------------------------------------- tg = Tango::Util::init(argc,argv); // Create the device server singleton // which will create everything //---------------------------------------- tg->server_init(false); // Run the endless loop //---------------------------------------- cout << "Ready to accept request" << endl; tg->server_run(); } catch (bad_alloc) { cout << "Can't allocate memory to store device object !!!" << endl; cout << "Exiting" << endl; } catch (CORBA::Exception &e) { Tango::Except::print_exception(e); cout << "Received a CORBA_Exception" << endl; cout << "Exiting" << endl; } tg->server_cleanup(); return(0); } /*PROTECTED REGION END*/ // TangoAccessControl::main.cpp tango-9.2.5a/cppserver/tangoaccesscontrol/TangoAccessControl.h0000644023471100065110000003103413034745020021535 00000000000000/*----- PROTECTED REGION ID(TangoAccessControl.h) ENABLED START -----*/ //============================================================================= // // file : TangoAccessControl.h // // description : Include for the TangoAccessControl class. // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef TANGOACCESSCONTROL_H #define TANGOACCESSCONTROL_H #include #include #include #define CONTROL_SYSTEM "CtrlSystem" #define SERVICE_PROP_NAME "Services" #define ServiceName "AccessControl" #define InatanceName "tango" #define AC_SQLError "AC_SQLError" #define AC_IncorrectArguments "AC_IncorrectArguments" #define AC_AlreadyExists "AC_AlreadyExists" #define STARTER_DEVNAME_HEADER "tango/admin/" typedef struct { string user; string device; string address; string rights; } AccessStruct; // Define time measuremnt type (depends on OS) #ifndef WIN32 # define TimeVal struct timeval # define GetTime(t) gettimeofday(&t, NULL); # define Elapsed(before, after) \ 1000.0*(after.tv_sec-before.tv_sec) + \ ((double)after.tv_usec-before.tv_usec) / 1000 #else static LARGE_INTEGER cpu_freq; # define TimeVal LARGE_INTEGER # define GetTime(t) w_gettimeofday(&t); # define Elapsed(before, after) \ (cpu_freq.QuadPart==0) ? 0.0 : \ (double) (after.QuadPart - before.QuadPart)/cpu_freq.QuadPart * 1000; #endif /* WIN32 */ /*----- PROTECTED REGION END -----*/ // TangoAccessControl.h /** * TangoAccessControl class description: * This class is a conceate class inherited from AccessControl abstract class.
*
* This class defines how to manage the TANGO access control.
* It implements commands for tool to defines access for users, devices and IP addresses.
* It implements also commands used by client API to check access for specified user, device and address.
* And it implements register and unregister it as TANGO service. */ namespace TangoAccessControl_ns { /*----- PROTECTED REGION ID(TangoAccessControl::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations class DummyDev: public Tango::Connection { public: DummyDev():Tango::Connection(true) {}; virtual string get_corba_name(bool) {string str;return str;} virtual string build_corba_name() {string str;return str;} virtual int get_lock_ctr() {return 0;} virtual void set_lock_ctr(int) {}; virtual string dev_name() {string str;return str;} int get_env_var(const char *cc,string &str_ref) {return Tango::Connection::get_env_var(cc,str_ref);} }; /*----- PROTECTED REGION END -----*/ // TangoAccessControl::Additional Class Declarations class TangoAccessControl : public AccessControl_ns::AccessControl { /*----- PROTECTED REGION ID(TangoAccessControl::Data Members) ENABLED START -----*/ // Add your own data members public: /*----- PROTECTED REGION END -----*/ // TangoAccessControl::Data Members // Constructors and destructors public: /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ TangoAccessControl(Tango::DeviceClass *cl,string &s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ TangoAccessControl(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device name * @param d Device description. */ TangoAccessControl(Tango::DeviceClass *cl,const char *s,const char *d); /** * The device object destructor. */ ~TangoAccessControl() {delete_device();}; // Miscellaneous methods public: /** * will be called at device destruction or at init command. */ void delete_device(); /** * Initialize the device */ virtual void init_device(); /** * Always executed method before execution command method. */ virtual void always_executed_hook(); // Attribute methods public: //-------------------------------------------------------- /** * Method : TangoAccessControl::read_attr_hardware() * Description : Hardware acquisition for attributes. */ //-------------------------------------------------------- virtual void read_attr_hardware(vector &attr_list); //-------------------------------------------------------- /** * Method : TangoAccessControl::add_dynamic_attributes() * Description : Add dynamic attributes if any. */ //-------------------------------------------------------- void add_dynamic_attributes(); // Command related methods public: /** * Command AddAddressForUser related method * Description: Add an address for the specified user.. * * @param argin user name, address * @returns */ virtual void add_address_for_user(const Tango::DevVarStringArray *argin); virtual bool is_AddAddressForUser_allowed(const CORBA::Any &any); /** * Command AddDeviceForUser related method * Description: Add a device and rights for the specified user.. * * @param argin user name, device adn value * @returns */ virtual void add_device_for_user(const Tango::DevVarStringArray *argin); virtual bool is_AddDeviceForUser_allowed(const CORBA::Any &any); /** * Command CloneUser related method * Description: Copy addresses and devices from source user to target user. * * @param argin [0] - source user name.\n[1] - target user name. * @returns */ virtual void clone_user(const Tango::DevVarStringArray *argin); virtual bool is_CloneUser_allowed(const CORBA::Any &any); /** * Command GetAccess related method * Description: Check access for specified user, device, address * and returns access (read or write). * * @param argin [0] - User name * [1] - IP Address * [2] - Device * @returns access for specified inputs read/write. */ virtual Tango::DevString get_access(const Tango::DevVarStringArray *argin); virtual bool is_GetAccess_allowed(const CORBA::Any &any); /** * Command GetAccessForMultiIP related method * Description: Check access for specified user, device and addresses * and returns access (read or write). * * @param argin [0] - User name * [1] - Device * [2] - IP Address #1 * [3] - IP Address #2 * [4] - IP Address #3 * [5] - IP Address #4 * ...... * @returns access for specified inputs read/write. */ virtual Tango::DevString get_access_for_multi_ip(const Tango::DevVarStringArray *argin); virtual bool is_GetAccessForMultiIP_allowed(const CORBA::Any &any); /** * Command GetAddressByUser related method * Description: Returns address list found for the specified user. * * @param argin user name. * @returns Addresses found for the specified user. */ virtual Tango::DevVarStringArray *get_address_by_user(Tango::DevString argin); virtual bool is_GetAddressByUser_allowed(const CORBA::Any &any); /** * Command GetAllowedCommandClassList related method * Description: Returns the class names which have AllowedAccessCmd property defined. * * @param argin * @returns Class names which have AllowedAccessCmd property defined. */ virtual Tango::DevVarStringArray *get_allowed_command_class_list(); virtual bool is_GetAllowedCommandClassList_allowed(const CORBA::Any &any); /** * Command GetAllowedCommands related method * Description: Returns allowed command list found in database for specified device * It search the class of the specified device and then uses the class property AllowedAccessCmd * * @param argin Device name OR Device Class name * @returns Allowed commands found in database for specified device */ virtual Tango::DevVarStringArray *get_allowed_commands(Tango::DevString argin); virtual bool is_GetAllowedCommands_allowed(const CORBA::Any &any); /** * Command GetDeviceByUser related method * Description: Returns devices and rights found for the specified user. * * @param argin user name. * @returns devices and rights found for the specified user. */ virtual Tango::DevVarStringArray *get_device_by_user(Tango::DevString argin); virtual bool is_GetDeviceByUser_allowed(const CORBA::Any &any); /** * Command GetDeviceClass related method * Description: Returns class for specified device. * * @param argin Device name * @returns Class found in database for specified device */ virtual Tango::DevString get_device_class(Tango::DevString argin); virtual bool is_GetDeviceClass_allowed(const CORBA::Any &any); /** * Command GetUsers related method * Description: Returns user list found in table access_address. * * @param argin * @returns Users find in table access_address. */ virtual Tango::DevVarStringArray *get_users(); virtual bool is_GetUsers_allowed(const CORBA::Any &any); /** * Command RegisterService related method * Description: Register device as a TANGO service. * * @param argin * @returns */ virtual void register_service(); virtual bool is_RegisterService_allowed(const CORBA::Any &any); /** * Command RemoveAddressForUser related method * Description: Remove an address for the specified user.. * * @param argin user name, address * @returns */ virtual void remove_address_for_user(const Tango::DevVarStringArray *argin); virtual bool is_RemoveAddressForUser_allowed(const CORBA::Any &any); /** * Command RemoveDeviceForUser related method * Description: Remove a device and its rights for the specified user.. * * @param argin user name, device and value * @returns */ virtual void remove_device_for_user(const Tango::DevVarStringArray *argin); virtual bool is_RemoveDeviceForUser_allowed(const CORBA::Any &any); /** * Command RemoveUser related method * Description: Remove all records for specified user. * * @param argin user name * @returns */ virtual void remove_user(Tango::DevString argin); virtual bool is_RemoveUser_allowed(const CORBA::Any &any); /** * Command UnregisterService related method * Description: Unregister device as a TANGO service. * * @param argin * @returns */ virtual void unregister_service(); virtual bool is_UnregisterService_allowed(const CORBA::Any &any); /*----- PROTECTED REGION ID(TangoAccessControl::Additional Method prototypes) ENABLED START -----*/ // Additional Method prototypes protected : MYSQL mysql; string removeFQDN(string s); void mysql_connection(); void simple_query(string sql_query,const char *method); MYSQL_RES *query(string sql_query,const char *method); vector get_dev_members(string &devname); vector get_ip_add_members(string &devname); vector get_access_for_user_address(string &user, string &ip_add); string get_access_for_user_device(string &user, string &device); string get_rigths(vector as, vector members); bool match(string expression, string member); void register_service(string servicename, string instname, string devname); void unregister_service(string servicename, string instname, string devname); /*----- PROTECTED REGION END -----*/ // TangoAccessControl::Additional Method prototypes }; /*----- PROTECTED REGION ID(TangoAccessControl::Additional Classes Definitions) ENABLED START -----*/ // Additional Classes definitions /*----- PROTECTED REGION END -----*/ // TangoAccessControl::Additional Classes Definitions } // End of namespace #endif // TangoAccessControl_H tango-9.2.5a/cppserver/tangoaccesscontrol/TangoAccessControlClass.h0000644023471100065110000004027313034745020022530 00000000000000/*----- PROTECTED REGION ID(TangoAccessControlClass.h) ENABLED START -----*/ //============================================================================= // // file : TangoAccessControlClass.h // // description : Include for the TangoAccessControlClass root class. // This class is the singleton class for. // the TangoAccessControl device class.. // It contains all properties and methods which the . // TangoAccessControl requires only once e.g. the commands. // // project : Tango Access Control Management. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: pascal_verdier $ // // $Revision: 25304 $ // $Date: 2014-03-25 13:48:26 +0100 (Tue, 25 Mar 2014) $ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef TANGOACCESSCONTROLCLASS_H #define TANGOACCESSCONTROLCLASS_H #include #include #include /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass.h namespace TangoAccessControl_ns { /*----- PROTECTED REGION ID(TangoAccessControlClass::classes for dynamic creation) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::classes for dynamic creation //========================================= // Define classes for commands //========================================= // Command AddAddressForUser class definition class AddAddressForUserClass : public Tango::Command { public: AddAddressForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; AddAddressForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~AddAddressForUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_AddAddressForUser_allowed(any);} }; // Command AddDeviceForUser class definition class AddDeviceForUserClass : public Tango::Command { public: AddDeviceForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; AddDeviceForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~AddDeviceForUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_AddDeviceForUser_allowed(any);} }; // Command CloneUser class definition class CloneUserClass : public Tango::Command { public: CloneUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; CloneUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~CloneUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_CloneUser_allowed(any);} }; // Command GetAccess class definition class GetAccessClass : public Tango::Command { public: GetAccessClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetAccessClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetAccessClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetAccess_allowed(any);} }; // Command GetAccessForMultiIP class definition class GetAccessForMultiIPClass : public Tango::Command { public: GetAccessForMultiIPClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetAccessForMultiIPClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetAccessForMultiIPClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetAccessForMultiIP_allowed(any);} }; // Command GetAddressByUser class definition class GetAddressByUserClass : public Tango::Command { public: GetAddressByUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetAddressByUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetAddressByUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetAddressByUser_allowed(any);} }; // Command GetAllowedCommandClassList class definition class GetAllowedCommandClassListClass : public Tango::Command { public: GetAllowedCommandClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetAllowedCommandClassListClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetAllowedCommandClassListClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetAllowedCommandClassList_allowed(any);} }; // Command GetAllowedCommands class definition class GetAllowedCommandsClass : public Tango::Command { public: GetAllowedCommandsClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetAllowedCommandsClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetAllowedCommandsClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetAllowedCommands_allowed(any);} }; // Command GetDeviceByUser class definition class GetDeviceByUserClass : public Tango::Command { public: GetDeviceByUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetDeviceByUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetDeviceByUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetDeviceByUser_allowed(any);} }; // Command GetDeviceClass class definition class GetDeviceClassClass : public Tango::Command { public: GetDeviceClassClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetDeviceClassClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetDeviceClassClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetDeviceClass_allowed(any);} }; // Command GetUsers class definition class GetUsersClass : public Tango::Command { public: GetUsersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; GetUsersClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~GetUsersClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_GetUsers_allowed(any);} }; // Command RegisterService class definition class RegisterServiceClass : public Tango::Command { public: RegisterServiceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; RegisterServiceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~RegisterServiceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_RegisterService_allowed(any);} }; // Command RemoveAddressForUser class definition class RemoveAddressForUserClass : public Tango::Command { public: RemoveAddressForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; RemoveAddressForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~RemoveAddressForUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_RemoveAddressForUser_allowed(any);} }; // Command RemoveDeviceForUser class definition class RemoveDeviceForUserClass : public Tango::Command { public: RemoveDeviceForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; RemoveDeviceForUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~RemoveDeviceForUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_RemoveDeviceForUser_allowed(any);} }; // Command RemoveUser class definition class RemoveUserClass : public Tango::Command { public: RemoveUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; RemoveUserClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~RemoveUserClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_RemoveUser_allowed(any);} }; // Command UnregisterService class definition class UnregisterServiceClass : public Tango::Command { public: UnregisterServiceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out, const char *in_desc, const char *out_desc, Tango::DispLevel level) :Command(name,in,out,in_desc,out_desc, level) {}; UnregisterServiceClass(const char *name, Tango::CmdArgType in, Tango::CmdArgType out) :Command(name,in,out) {}; ~UnregisterServiceClass() {}; virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) {return (static_cast(dev))->is_UnregisterService_allowed(any);} }; /** * The TangoAccessControlClass singleton definition */ #ifdef _TG_WINDOWS_ class __declspec(dllexport) TangoAccessControlClass : public AccessControl_ns::AccessControlClass #else class TangoAccessControlClass : public AccessControl_ns::AccessControlClass #endif { /*----- PROTECTED REGION ID(TangoAccessControlClass::Additionnal DServer data members) ENABLED START -----*/ public: /*----- PROTECTED REGION END -----*/ // TangoAccessControlClass::Additionnal DServer data members public: // write class properties data members Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static TangoAccessControlClass *init(const char *); static TangoAccessControlClass *instance(); ~TangoAccessControlClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: TangoAccessControlClass(string &); static TangoAccessControlClass *_instance; void command_factory(); void attribute_factory(vector &); void write_class_property(); void set_default_property(); void get_class_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); void create_static_attribute_list(vector &); void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector &); vector defaultAttList; Tango::Attr *get_attr_object_by_name(vector &att_list, string attname); }; } // End of namespace #endif // TangoAccessControl_H tango-9.2.5a/cppserver/AbstractClass/0000755023471100065110000000000013034745262014556 500000000000000tango-9.2.5a/cppserver/AbstractClass/Makefile.am0000644023471100065110000000022213034744715016530 00000000000000SUBDIRS = AccessControl dist-hook: cp -R $(top_srcdir)/cppserver/AbstractClass/AccessControl $(distdir); \ rm -rf `find $(distdir) -name .svn` tango-9.2.5a/cppserver/AbstractClass/Makefile.in0000644023471100065110000005100313034745121016534 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = cppserver/AbstractClass DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = AccessControl all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/AbstractClass/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/AbstractClass/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive dist-hook distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am dist-hook: cp -R $(top_srcdir)/cppserver/AbstractClass/AccessControl $(distdir); \ rm -rf `find $(distdir) -name .svn` # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/AbstractClass/AccessControl/0000755023471100065110000000000013034745262017320 500000000000000tango-9.2.5a/cppserver/AbstractClass/AccessControl/Makefile.am0000644023471100065110000000122513034745262021274 00000000000000 AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ $(LIBZMQ_CFLAGS) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libaccesscontrol.la # These are the sources for the library. libaccesscontrol_la_SOURCES = AccessControl.cpp \ AccessControlClass.cpp \ AccessControlStateMachine.cpp \ AccessControl.h \ AccessControlClass.h tango-9.2.5a/cppserver/AbstractClass/AccessControl/Makefile.in0000644023471100065110000004774513034745262021326 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = cppserver/AbstractClass/AccessControl DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libaccesscontrol_la_LIBADD = am_libaccesscontrol_la_OBJECTS = AccessControl.lo \ AccessControlClass.lo AccessControlStateMachine.lo libaccesscontrol_la_OBJECTS = $(am_libaccesscontrol_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libaccesscontrol_la_SOURCES) DIST_SOURCES = $(libaccesscontrol_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/lib/cpp/client \ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \ $(LIBZMQ_CFLAGS) \ -I$(top_srcdir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/log4tango/include \ -I$(top_builddir)/lib/cpp/server # We're making a libtool convenience library which is not to be installed, # therefore the automake noinst variable noinst_LTLIBRARIES = libaccesscontrol.la # These are the sources for the library. libaccesscontrol_la_SOURCES = AccessControl.cpp \ AccessControlClass.cpp \ AccessControlStateMachine.cpp \ AccessControl.h \ AccessControlClass.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cppserver/AbstractClass/AccessControl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cppserver/AbstractClass/AccessControl/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libaccesscontrol.la: $(libaccesscontrol_la_OBJECTS) $(libaccesscontrol_la_DEPENDENCIES) $(EXTRA_libaccesscontrol_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libaccesscontrol_la_OBJECTS) $(libaccesscontrol_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AccessControl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AccessControlClass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AccessControlStateMachine.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControl.cpp0000644023471100065110000002122413034745262022507 00000000000000/*----- PROTECTED REGION ID(AccessControl.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: AccessControl.cpp 26622 2014-10-02 12:26:29Z pascal_verdier $"; //============================================================================= // // file : AccessControl.cpp // // description : C++ source for the AccessControl and its commands. // The class is derived from Device. It represents the // CORBA servant object which will be accessed from the // network. All commands which can be executed on the // AccessControl are implemented in this file. // // project : Access Control abstract class. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // $Author: pascal_verdier $ // // $Revision: 26622 $ // $Date: 2014-10-02 14:26:29 +0200 (Thu, 02 Oct 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 1.2 2011/02/11 14:20:27 pascal_verdier // GetAccessForMutiIP command added. // // Revision 1.1 2011/02/11 13:43:12 pascal_verdier // Pogo-7 compatibility. // // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /*----- PROTECTED REGION END -----*/ // AccessControl.cpp /** * AccessControl class description: * This class defines how to manage the TANGO access control. * It interfaces commands for tool to defines access for users, devices and IP addresses. * It interfaces also commands used by client API to check access for specified user, device and address. * And it insterfaces to register and unregister it as TANGO service. */ //================================================================ // The following table gives the correspondence // between command and method names. // // Command name | Method name //================================================================ // State | Inherited (no method) // Status | Inherited (no method) // AddAddressForUser | Inherited (no method) // AddDeviceForUser | Inherited (no method) // CloneUser | Inherited (no method) // GetAccess | Inherited (no method) // GetAccessForMultiIP | Inherited (no method) // GetAddressByUser | Inherited (no method) // GetAllowedCommands | Inherited (no method) // GetDeviceByUser | Inherited (no method) // GetDeviceClass | Inherited (no method) // GetUsers | Inherited (no method) // RegisterService | Inherited (no method) // RemoveAddressForUser | Inherited (no method) // RemoveDeviceForUser | Inherited (no method) // RemoveUser | Inherited (no method) // UnregisterService | Inherited (no method) //================================================================ //================================================================ // Attributes managed is: //================================================================ //================================================================ namespace AccessControl_ns { /*----- PROTECTED REGION ID(AccessControl::namespace_starting) ENABLED START -----*/ // static initializations /*----- PROTECTED REGION END -----*/ // AccessControl::namespace_starting //-------------------------------------------------------- /** * Method : AccessControl::AccessControl() * Description : Constructors for a Tango device * implementing the classAccessControl */ //-------------------------------------------------------- AccessControl::AccessControl(Tango::DeviceClass *cl, string &s) : TANGO_BASE_CLASS(cl, s.c_str()) { /*----- PROTECTED REGION ID(AccessControl::constructor_1) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AccessControl::constructor_1 } //-------------------------------------------------------- AccessControl::AccessControl(Tango::DeviceClass *cl, const char *s) : TANGO_BASE_CLASS(cl, s) { /*----- PROTECTED REGION ID(AccessControl::constructor_2) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AccessControl::constructor_2 } //-------------------------------------------------------- AccessControl::AccessControl(Tango::DeviceClass *cl, const char *s, const char *d) : TANGO_BASE_CLASS(cl, s, d) { /*----- PROTECTED REGION ID(AccessControl::constructor_3) ENABLED START -----*/ init_device(); /*----- PROTECTED REGION END -----*/ // AccessControl::constructor_3 } //-------------------------------------------------------- /** * Method : AccessControl::delete_device() * Description : will be called at device destruction or at init command */ //-------------------------------------------------------- void AccessControl::delete_device() { DEBUG_STREAM << "AccessControl::delete_device() " << device_name << endl; /*----- PROTECTED REGION ID(AccessControl::delete_device) ENABLED START -----*/ // Delete device allocated objects /*----- PROTECTED REGION END -----*/ // AccessControl::delete_device } //-------------------------------------------------------- /** * Method : AccessControl::init_device() * Description : will be called at device initialization. */ //-------------------------------------------------------- void AccessControl::init_device() { DEBUG_STREAM << "AccessControl::init_device() create device " << device_name << endl; /*----- PROTECTED REGION ID(AccessControl::init_device_before) ENABLED START -----*/ // Initialization before get_device_property() call /*----- PROTECTED REGION END -----*/ // AccessControl::init_device_before // No device property to be read from database /*----- PROTECTED REGION ID(AccessControl::init_device) ENABLED START -----*/ // Initialize device /*----- PROTECTED REGION END -----*/ // AccessControl::init_device } //-------------------------------------------------------- /** * Method : AccessControl::always_executed_hook() * Description : method always executed before any command is executed */ //-------------------------------------------------------- void AccessControl::always_executed_hook() { DEBUG_STREAM << "AccessControl::always_executed_hook() " << device_name << endl; /*----- PROTECTED REGION ID(AccessControl::always_executed_hook) ENABLED START -----*/ // code always executed before all requests /*----- PROTECTED REGION END -----*/ // AccessControl::always_executed_hook } //-------------------------------------------------------- /** * Method : AccessControl::read_attr_hardware() * Description : Hardware acquisition for attributes */ //-------------------------------------------------------- void AccessControl::read_attr_hardware(TANGO_UNUSED(vector &attr_list)) { DEBUG_STREAM << "AccessControl::read_attr_hardware(vector &attr_list) entering... " << endl; /*----- PROTECTED REGION ID(AccessControl::read_attr_hardware) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AccessControl::read_attr_hardware } //-------------------------------------------------------- /** * Method : AccessControl::add_dynamic_attributes() * Description : Create the dynamic attributes if any * for specified device. */ //-------------------------------------------------------- void AccessControl::add_dynamic_attributes() { /*----- PROTECTED REGION ID(AccessControl::add_dynamic_attributes) ENABLED START -----*/ // Add your own code to create and add dynamic attributes if any /*----- PROTECTED REGION END -----*/ // AccessControl::add_dynamic_attributes } /*----- PROTECTED REGION ID(AccessControl::namespace_ending) ENABLED START -----*/ // Additional Methods /*----- PROTECTED REGION END -----*/ // AccessControl::namespace_ending } // namespace tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControlClass.cpp0000644023471100065110000002536113034745262023503 00000000000000/*----- PROTECTED REGION ID(AccessControlClass.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: AccessControlClass.cpp 26622 2014-10-02 12:26:29Z pascal_verdier $"; static const char *TagName = "$Name$"; static const char *CvsPath = "$Source$"; static const char *SvnPath = "$HeadURL: $"; static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/"; //============================================================================= // // file : AccessControlClass.cpp // // description : C++ source for the AccessControlClass. A singleton // class derived from DeviceClass. It implements the // command list and all properties and methods required // by the «name» once per process. // // project : Access Control abstract class. // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 26622 $ // $Date: 2014-10-02 14:26:29 +0200 (Thu, 02 Oct 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include /*----- PROTECTED REGION END -----*/ // AccessControlClass.cpp //------------------------------------------------------------------- /** * Create AccessControlClass singleton and * return it in a C function for Python usage */ //------------------------------------------------------------------- extern "C" { #ifdef _TG_WINDOWS_ __declspec(dllexport) #endif Tango::DeviceClass *_create_AccessControl_class(const char *name) { return AccessControl_ns::AccessControlClass::init(name); } } namespace AccessControl_ns { //=================================================================== // Initialize pointer for singleton pattern //=================================================================== AccessControlClass *AccessControlClass::_instance = NULL; //-------------------------------------------------------- /** * method : AccessControlClass::AccessControlClass(string &s) * description : constructor for the AccessControlClass * * @param s The class name */ //-------------------------------------------------------- AccessControlClass::AccessControlClass(string &s):Tango::DeviceClass(s) { cout2 << "Entering AccessControlClass constructor" << endl; set_default_property(); write_class_property(); /*----- PROTECTED REGION ID(AccessControlClass::constructor) ENABLED START -----*/ string str_rcs(RcsId); /*----- PROTECTED REGION END -----*/ // AccessControlClass::constructor cout2 << "Leaving AccessControlClass constructor" << endl; } //-------------------------------------------------------- /** * method : AccessControlClass::~AccessControlClass() * description : destructor for the AccessControlClass */ //-------------------------------------------------------- AccessControlClass::~AccessControlClass() { /*----- PROTECTED REGION ID(AccessControlClass::destructor) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::destructor _instance = NULL; } //-------------------------------------------------------- /** * method : AccessControlClass::init * description : Create the object if not already done. * Otherwise, just return a pointer to the object * * @param name The class name */ //-------------------------------------------------------- AccessControlClass *AccessControlClass::init(const char *name) { if (_instance == NULL) { try { string s(name); _instance = new AccessControlClass(s); } catch (bad_alloc &) { throw; } } return _instance; } //-------------------------------------------------------- /** * method : AccessControlClass::instance * description : Check if object already created, * and return a pointer to the object */ //-------------------------------------------------------- AccessControlClass *AccessControlClass::instance() { if (_instance == NULL) { cerr << "Class is not initialised !!" << endl; exit(-1); } return _instance; } //=================================================================== // Command execution method calls //=================================================================== //=================================================================== // Properties management //=================================================================== //-------------------------------------------------------- /** * Method : AccessControlClass::get_class_property() * Description : Get the class property for specified name. */ //-------------------------------------------------------- Tango::DbDatum AccessControlClass::get_class_property(string &prop_name) { for (unsigned int i=0 ; i vect_data; // Set Default Class Properties // Set Default device Properties } //-------------------------------------------------------- /** * Method : AccessControlClass::write_class_property() * Description : Set class description fields as property in database */ //-------------------------------------------------------- void AccessControlClass::write_class_property() { } //=================================================================== // Factory methods //=================================================================== //-------------------------------------------------------- /** * Method : AccessControlClass::device_factory() * Description : Create the device object(s) * and store them in the device list */ //-------------------------------------------------------- void AccessControlClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) { // This class is not concrete and cannot implement devices } //-------------------------------------------------------- /** * Method : AccessControlClass::attribute_factory() * Description : Create the attribute object(s) * and store them in the attribute list */ //-------------------------------------------------------- void AccessControlClass::attribute_factory(vector &att_list) { /*----- PROTECTED REGION ID(AccessControlClass::attribute_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AccessControlClass::attribute_factory_before /*----- PROTECTED REGION ID(AccessControlClass::attribute_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AccessControlClass::attribute_factory_after } //-------------------------------------------------------- /** * Method : AccessControlClass::pipe_factory() * Description : Create the pipe object(s) * and store them in the pipe list */ //-------------------------------------------------------- void AccessControlClass::pipe_factory() { /*----- PROTECTED REGION ID(AccessControlClass::pipe_factory_before) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AccessControlClass::pipe_factory_before /*----- PROTECTED REGION ID(AccessControlClass::pipe_factory_after) ENABLED START -----*/ // Add your own code /*----- PROTECTED REGION END -----*/ // AccessControlClass::pipe_factory_after } //-------------------------------------------------------- /** * Method : AccessControlClass::command_factory() * Description : Create the command object(s) * and store them in the command list */ //-------------------------------------------------------- void AccessControlClass::command_factory() { /*----- PROTECTED REGION ID(AccessControlClass::command_factory_before) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::command_factory_before /*----- PROTECTED REGION ID(AccessControlClass::command_factory_after) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::command_factory_after } /*----- PROTECTED REGION ID(AccessControlClass::Additional Methods) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::Additional Methods } // namespace tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControlStateMachine.cpp0000644023471100065110000002747613034745262025014 00000000000000/*----- PROTECTED REGION ID(AccessControlStateMachine.cpp) ENABLED START -----*/ static const char *RcsId = "$Id: AccessControlStateMachine.cpp 26622 2014-10-02 12:26:29Z pascal_verdier $"; //============================================================================= // // file : AccessControlStateMachine.cpp // // description : C++ source for the «name» and its alowed // methods for commands and attributes // // project : Access Control abstract class. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // $Author: pascal_verdier $ // // $Revision: 26622 $ // $Date: 2014-10-02 14:26:29 +0200 (Thu, 02 Oct 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 1.4 2011/02/11 14:20:27 pascal_verdier // GetAccessForMutiIP command added. // // Revision 1.3 2011/02/11 13:43:12 pascal_verdier // Pogo-7 compatibility. // // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #include #include /*----- PROTECTED REGION END -----*/ // AccessControl::AccessControlStateMachine.cpp //================================================================ // States | Description //================================================================ // ON | The MySql database handle is OK. // FAULT | The MySql database handle is not OK. namespace AccessControl_ns { //================================================= // Attributes Allowed Methods //================================================= //================================================= // Commands Allowed Methods //================================================= //-------------------------------------------------------- /** * Method : AccessControl::is_AddAddressForUser_allowed() * Description : Execution allowed for AddAddressForUser attribute */ //-------------------------------------------------------- bool AccessControl::is_AddAddressForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::AddAddressForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::AddAddressForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_AddDeviceForUser_allowed() * Description : Execution allowed for AddDeviceForUser attribute */ //-------------------------------------------------------- bool AccessControl::is_AddDeviceForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::AddDeviceForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::AddDeviceForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_CloneUser_allowed() * Description : Execution allowed for CloneUser attribute */ //-------------------------------------------------------- bool AccessControl::is_CloneUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::CloneUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::CloneUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetAccess_allowed() * Description : Execution allowed for GetAccess attribute */ //-------------------------------------------------------- bool AccessControl::is_GetAccess_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for GetAccess command. /*----- PROTECTED REGION ID(AccessControl::GetAccessStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetAccessStateAllowed return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetAccessForMultiIP_allowed() * Description : Execution allowed for GetAccessForMultiIP attribute */ //-------------------------------------------------------- bool AccessControl::is_GetAccessForMultiIP_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for GetAccessForMultiIP command. /*----- PROTECTED REGION ID(AccessControl::GetAccessForMultiIPStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetAccessForMultiIPStateAllowed return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetAddressByUser_allowed() * Description : Execution allowed for GetAddressByUser attribute */ //-------------------------------------------------------- bool AccessControl::is_GetAddressByUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::GetAddressByUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetAddressByUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetAllowedCommands_allowed() * Description : Execution allowed for GetAllowedCommands attribute */ //-------------------------------------------------------- bool AccessControl::is_GetAllowedCommands_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::GetAllowedCommandsStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetAllowedCommandsStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetDeviceByUser_allowed() * Description : Execution allowed for GetDeviceByUser attribute */ //-------------------------------------------------------- bool AccessControl::is_GetDeviceByUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::GetDeviceByUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetDeviceByUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetDeviceClass_allowed() * Description : Execution allowed for GetDeviceClass attribute */ //-------------------------------------------------------- bool AccessControl::is_GetDeviceClass_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::GetDeviceClassStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetDeviceClassStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_GetUsers_allowed() * Description : Execution allowed for GetUsers attribute */ //-------------------------------------------------------- bool AccessControl::is_GetUsers_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::GetUsersStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::GetUsersStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_RegisterService_allowed() * Description : Execution allowed for RegisterService attribute */ //-------------------------------------------------------- bool AccessControl::is_RegisterService_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for RegisterService command. /*----- PROTECTED REGION ID(AccessControl::RegisterServiceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::RegisterServiceStateAllowed return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_RemoveAddressForUser_allowed() * Description : Execution allowed for RemoveAddressForUser attribute */ //-------------------------------------------------------- bool AccessControl::is_RemoveAddressForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::RemoveAddressForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::RemoveAddressForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_RemoveDeviceForUser_allowed() * Description : Execution allowed for RemoveDeviceForUser attribute */ //-------------------------------------------------------- bool AccessControl::is_RemoveDeviceForUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::RemoveDeviceForUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::RemoveDeviceForUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_RemoveUser_allowed() * Description : Execution allowed for RemoveUser attribute */ //-------------------------------------------------------- bool AccessControl::is_RemoveUser_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Compare device state with not allowed states. if (get_state()==Tango::FAULT) { /*----- PROTECTED REGION ID(AccessControl::RemoveUserStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::RemoveUserStateAllowed return false; } return true; } //-------------------------------------------------------- /** * Method : AccessControl::is_UnregisterService_allowed() * Description : Execution allowed for UnregisterService attribute */ //-------------------------------------------------------- bool AccessControl::is_UnregisterService_allowed(TANGO_UNUSED(const CORBA::Any &any)) { // Not any excluded states for UnregisterService command. /*----- PROTECTED REGION ID(AccessControl::UnregisterServiceStateAllowed) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControl::UnregisterServiceStateAllowed return true; } } // End of namespace tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControl.h0000644023471100065110000002463613034745262022166 00000000000000/*----- PROTECTED REGION ID(AccessControl.h) ENABLED START -----*/ //============================================================================= // // file : AccessControl.h // // description : Include for the AccessControl class. // // project : Access Control abstract class. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // // $Author: pascal_verdier $ // // $Revision: 26622 $ // $Date: 2014-10-02 14:26:29 +0200 (Thu, 02 Oct 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // Revision 1.5 2011/02/11 14:20:27 pascal_verdier // GetAccessForMutiIP command added. // // Revision 1.4 2011/02/11 13:43:12 pascal_verdier // Pogo-7 compatibility. // // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef ACCESSCONTROL_H #define ACCESSCONTROL_H #include #ifndef TANGO_UNUSED #ifdef _TG_WINDOWS_ #define TANGO_UNUSED(var) var #else #if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #elif __GNUC__ > 3 #define TANGO_UNUSED(var) var __attribute__ ((unused)) #else #define TANGO_UNUSED(var) var #endif #endif #endif /*----- PROTECTED REGION END -----*/ // AccessControl.h /** * AccessControl class description: * This class defines how to manage the TANGO access control. * It interfaces commands for tool to defines access for users, devices and IP addresses. * It interfaces also commands used by client API to check access for specified user, device and address. * And it insterfaces to register and unregister it as TANGO service. */ namespace AccessControl_ns { /*----- PROTECTED REGION ID(AccessControl::Additional Class Declarations) ENABLED START -----*/ // Additional Class Declarations /*----- PROTECTED REGION END -----*/ // AccessControl::Additional Class Declarations class AccessControl : public TANGO_BASE_CLASS { /*----- PROTECTED REGION ID(AccessControl::Data Members) ENABLED START -----*/ // Add your own data members /*----- PROTECTED REGION END -----*/ // AccessControl::Data Members // Constructors and destructors public: /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ AccessControl(Tango::DeviceClass *cl,string &s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device Name */ AccessControl(Tango::DeviceClass *cl,const char *s); /** * Constructs a newly device object. * * @param cl Class. * @param s Device name * @param d Device description. */ AccessControl(Tango::DeviceClass *cl,const char *s,const char *d); /** * The device object destructor. */ ~AccessControl() {delete_device();}; // Miscellaneous methods public: /* * will be called at device destruction or at init command. */ void delete_device(); /* * Initialize the device */ virtual void init_device(); /* * Always executed method before execution command method. */ virtual void always_executed_hook(); // Attribute methods public: //-------------------------------------------------------- /* * Method : AccessControl::read_attr_hardware() * Description : Hardware acquisition for attributes. */ //-------------------------------------------------------- virtual void read_attr_hardware(vector &attr_list); //-------------------------------------------------------- /** * Method : AccessControl::add_dynamic_attributes() * Description : Add dynamic attributes if any. */ //-------------------------------------------------------- void add_dynamic_attributes(); // Command related methods public: /** * Command AddAddressForUser related method * Description: Add an address for the specified user.. * * @param argin user name, address */ virtual void add_address_for_user(const Tango::DevVarStringArray *argin) = 0; virtual bool is_AddAddressForUser_allowed(const CORBA::Any &any); /** * Command AddDeviceForUser related method * Description: Add a device and rights for the specified user.. * * @param argin user name, device adn value */ virtual void add_device_for_user(const Tango::DevVarStringArray *argin) = 0; virtual bool is_AddDeviceForUser_allowed(const CORBA::Any &any); /** * Command CloneUser related method * Description: Copy addresses and devices from source user to target user. * * @param argin [0] - source user name.\n[1] - target user name. */ virtual void clone_user(const Tango::DevVarStringArray *argin) = 0; virtual bool is_CloneUser_allowed(const CORBA::Any &any); /** * Command GetAccess related method * Description: Check access for specified user, device, address * and returns access (read or write). * * @param argin [0] - User name * [1] - IP Address * [2] - Device * @returns access for specified inputs read/write. */ virtual Tango::DevString get_access(const Tango::DevVarStringArray *argin) = 0; virtual bool is_GetAccess_allowed(const CORBA::Any &any); /** * Command GetAccessForMultiIP related method * Description: Check access for specified user, device and addresses * and returns access (read or write). * * @param argin [0] - User name * [1] - Device * [2] - IP Address #1 * [3] - IP Address #2 * [4] - IP Address #3 * [5] - IP Address #4 * ...... * @returns access for specified inputs read/write. */ virtual Tango::DevString get_access_for_multi_ip(const Tango::DevVarStringArray *argin) = 0; virtual bool is_GetAccessForMultiIP_allowed(const CORBA::Any &any); /** * Command GetAddressByUser related method * Description: Returns address list found for the specified user. * * @param argin user name. * @returns Addresses found for the specified user. */ virtual Tango::DevVarStringArray *get_address_by_user(Tango::DevString argin) = 0; virtual bool is_GetAddressByUser_allowed(const CORBA::Any &any); /** * Command GetAllowedCommands related method * Description: Returns allowed command list found in database for specified device * It search the class of the specified device and then uses the class property AllowedAccessCmd * * @param argin Device name * @returns Allowed commands found in database for specified device */ virtual Tango::DevVarStringArray *get_allowed_commands(Tango::DevString argin) = 0; virtual bool is_GetAllowedCommands_allowed(const CORBA::Any &any); /** * Command GetDeviceByUser related method * Description: Returns devices and rights found for the specified user. * * @param argin user name. * @returns devices and rights found for the specified user. */ virtual Tango::DevVarStringArray *get_device_by_user(Tango::DevString argin) = 0; virtual bool is_GetDeviceByUser_allowed(const CORBA::Any &any); /** * Command GetDeviceClass related method * Description: Returns class for specified device. * * @param argin Device name * @returns Class found in database for specified device */ virtual Tango::DevString get_device_class(Tango::DevString argin) = 0; virtual bool is_GetDeviceClass_allowed(const CORBA::Any &any); /** * Command GetUsers related method * Description: Returns user list found in table access_address. * * @returns Users find in table access_address. */ virtual Tango::DevVarStringArray *get_users() = 0; virtual bool is_GetUsers_allowed(const CORBA::Any &any); /** * Command RegisterService related method * Description: Register device as a TANGO service. * */ virtual void register_service() = 0; virtual bool is_RegisterService_allowed(const CORBA::Any &any); /** * Command RemoveAddressForUser related method * Description: Remove an address for the specified user.. * * @param argin user name, address */ virtual void remove_address_for_user(const Tango::DevVarStringArray *argin) = 0; virtual bool is_RemoveAddressForUser_allowed(const CORBA::Any &any); /** * Command RemoveDeviceForUser related method * Description: Remove a device and its rights for the specified user.. * * @param argin user name, device and value */ virtual void remove_device_for_user(const Tango::DevVarStringArray *argin) = 0; virtual bool is_RemoveDeviceForUser_allowed(const CORBA::Any &any); /** * Command RemoveUser related method * Description: Remove all records for specified user. * * @param argin user name */ virtual void remove_user(Tango::DevString argin) = 0; virtual bool is_RemoveUser_allowed(const CORBA::Any &any); /** * Command UnregisterService related method * Description: Unregister device as a TANGO service. * */ virtual void unregister_service() = 0; virtual bool is_UnregisterService_allowed(const CORBA::Any &any); //-------------------------------------------------------- /** * Method : AccessControl::add_dynamic_commands() * Description : Add dynamic commands if any. */ //-------------------------------------------------------- void add_dynamic_commands(); /*----- PROTECTED REGION ID(AccessControl::Additional Method prototypes) ENABLED START -----*/ // Additional Method prototypes /*----- PROTECTED REGION END -----*/ // AccessControl::Additional Method prototypes }; /*----- PROTECTED REGION ID(AccessControl::Additional Classes Definitions) ENABLED START -----*/ // Additional Classes definitions /*----- PROTECTED REGION END -----*/ // AccessControl::Additional Classes Definitions } // End of namespace #endif // AccessControl_H tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControlClass.h0000644023471100065110000000714613034745262023151 00000000000000/*----- PROTECTED REGION ID(AccessControlClass.h) ENABLED START -----*/ //============================================================================= // // file : AccessControlClass.h // // description : Include for the AccessControlClass root class. // This class is the singleton class for. // the AccessControl device class.. // It contains all properties and methods which the . // AccessControl requires only once e.g. the commands. // // project : cess Control abstract class. // // // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011 // European Synchrotron Radiation Facility // BP 220, Grenoble 38043 // FRANCE // // This file is part of Tango. // // Tango 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. // // Tango is distributed in the hope that 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 Tango. If not, see . // // // // $Author: pascal_verdier $ // // $Revision: 26622 $ // $Date: 2014-10-02 14:26:29 +0200 (Thu, 02 Oct 2014) $ // // SVN only: // $HeadURL: $ // // CVS only: // $Source$ // $Log$ // //============================================================================= // This file is generated by POGO // (Program Obviously used to Generate tango Object) //============================================================================= #ifndef ACCESSCONTROLCLASS_H #define ACCESSCONTROLCLASS_H #include #include /*----- PROTECTED REGION END -----*/ // AccessControlClass.h namespace AccessControl_ns { /*----- PROTECTED REGION ID(AccessControlClass::classes for dynamic creation) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::classes for dynamic creation //========================================= // Define classes for commands //========================================= /** * The AccessControlClass singleton definition */ #ifdef _TG_WINDOWS_ class __declspec(dllexport) AccessControlClass : public Tango::DeviceClass #else class AccessControlClass : public Tango::DeviceClass #endif { /*----- PROTECTED REGION ID(AccessControlClass::Additionnal DServer data members) ENABLED START -----*/ /*----- PROTECTED REGION END -----*/ // AccessControlClass::Additionnal DServer data members public: // write class properties data members Tango::DbData cl_prop; Tango::DbData cl_def_prop; Tango::DbData dev_def_prop; // Method prototypes static AccessControlClass *init(const char *); static AccessControlClass *instance(); ~AccessControlClass(); Tango::DbDatum get_class_property(string &); Tango::DbDatum get_default_device_property(string &); Tango::DbDatum get_default_class_property(string &); protected: AccessControlClass(string &); static AccessControlClass *_instance; void command_factory(); void attribute_factory(vector &); void pipe_factory(); void write_class_property(); void set_default_property(); void get_class_property(); string get_cvstag(); string get_cvsroot(); private: void device_factory(const Tango::DevVarStringArray *); }; } // End of namespace #endif // AccessControl_H tango-9.2.5a/cppserver/AbstractClass/AccessControl/AccessControl.xmi0000644023471100065110000002410413034745262022522 00000000000000 FAULT FAULT FAULT FAULT FAULT FAULT FAULT FAULT FAULT FAULT FAULT tango-9.2.5a/scripts/0000755023471100065110000000000013034745262011503 500000000000000tango-9.2.5a/scripts/Makefile.am0000644023471100065110000000020413034744702013451 00000000000000# The scripts to be created. They will be installed in $prefix/bin if TANGO_DB_SERVER_ENABLED bin_SCRIPTS = tango tango_wca endif tango-9.2.5a/scripts/Makefile.in0000644023471100065110000004067513034745123013500 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # The scripts to be created. They will be installed in $prefix/bin VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = scripts DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/tango.in $(srcdir)/tango_wca.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = tango tango_wca CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(bindir)" SCRIPTS = $(bin_SCRIPTS) AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @TANGO_DB_SERVER_ENABLED_TRUE@bin_SCRIPTS = tango tango_wca all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu scripts/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tango: $(top_builddir)/config.status $(srcdir)/tango.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tango_wca: $(top_builddir)/config.status $(srcdir)/tango_wca.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binSCRIPTS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binSCRIPTS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-binSCRIPTS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/scripts/tango.in0000755023471100065110000000626513034744702013075 00000000000000#!@SHELL@ # # script to start TANGO database # TANGO_DB_PORT=10000 # # Internal functions # checkmysql() { NB=`$PS -ef | $GREP mysqld| $GREP -v $GREP | wc -l` export NB if [ $NB = 0 ] then return=1 export return else return=0 export return fi } findproc() { pid=`$PS -e | $GREP "$1" | $SED -e 's/^ *//' -e 's/ .*//'` } checkdatabaseds() { NB=`$PS -ef | $GREP -i databaseds | $GREP -v $GREP | wc -l` export NB if [ $NB = 0 ] then return=1 else return=0 fi } killproc() { pid=`$PS -e | $GREP "$1" | $SED -e 's/^ *//' -e 's/ .*//'` [ "$pid" != "" ] && kill -9 $pid } # # Check the platform used # OS=`uname -s` # # Settings common to all platforms # DATABASEDSHOME=@prefix@/bin LD_LIBRARY_PATH=@prefix@/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH # # Platform specific settings # case "${OS}" in "Linux") PS="/bin/ps" ECHO="/bin/echo -e" GREP="grep" SED="sed" TANGO_LOG="/tmp/tango.log" ;; "SunOS") rc_failed=" failed" rc_done=" OK" PS="/bin/ps" ECHO="/usr/ucb/echo" GREP="grep" SED="sed" TANGO_LOG=/tmp/tango.log ;; "HP-UX") test -f /etc/rc.config && . /etc/rc.config PS="/usr/bin/ps" ECHO="/bin/echo " GREP="/usr/bin/grep" SED="/usr/bin/sed" TANGO_LOG="/tmp/tango.log" ;; *) echo "Not supporting operating system: " ${OS} exit 1 esac # # Main part # case "$1" in start) ${ECHO} "Starting TANGO database" # first check the MySQL server checkmysql export return if [ ${return} = 1 ] then sleep 3 checkmysql if [ ${return} = 1 ] then # MySQL is not there, we can't start Tango db ${ECHO} "PLEASE Start MySQL server\n" 'date' >> ${TANGO_LOG} ${ECHO} "Failed to start Tango database server" >> ${TANGO_LOG} ${ECHO} "MySQL is not running !!!" >> ${TANGO_LOG} ${ECHO} "$rc_failed" exit 1 fi fi # Start the database device server if needed findproc DataBase if [ "$pid" != "" ]; then ${ECHO} "Database Server already running, exiting" 'date' >> ${TANGO_LOG} ${ECHO} "Database Server already running, exiting" >> ${TANGO_LOG} else ${DATABASEDSHOME}/DataBaseds 2 -ORBendPoint giop:tcp::$TANGO_DB_PORT & ${ECHO} "Starting TANGO Database Server" 'date' >> ${TANGO_LOG} ${ECHO} "Starting TANGO Database Server" >> ${TANGO_LOG} # wait for a while before checking status sleep 3 findproc DataBase if [ "$pid" = "" ]; then ${ECHO} "Failed to start Tango database server" 'date' >> ${TANGO_LOG} ${ECHO} "Failed to start Tango database server" >> ${TANGO_LOG} exit 1 fi ${ECHO} "$rc_done" fi ;; stop) ${ECHO} "Shutting down TANGO database" # first shutdown the database device server 'date' >> ${TANGO_LOG} ${ECHO} "Stopping TANGO Database Server" >> ${TANGO_LOG} killproc DataBaseds ${ECHO} "$rc_done" ;; restart) $0 stop && sleep 3 && $0 start ;; status) checkmysql if [ ${return} = 0 ] then ${ECHO} "MySQL OK" else ${ECHO} "MySQL : No process" fi findproc DataBase if [ "$pid" != "" ]; then ${ECHO} "TANGO Database server OK" else ${ECHO} "TANGO Database server : No process" fi ;; *) ${ECHO} "Usage: $0 {start|stop|status|restart}" exit 1 esac exit 0 tango-9.2.5a/scripts/tango_wca.in0000755023471100065110000001046213034744702013721 00000000000000#!@SHELL@ # # script to start TANGO database # TANGO_DB_PORT=10000 # # Internal functions # checkmysql() { NB=`$PS -ef | $GREP mysqld| $GREP -v $GREP | wc -l` export NB if [ $NB = 0 ] then return=1 export return else return=0 export return fi } findproc() { pid=`$PS -e | $GREP "$1" | $SED -e 's/^ *//' -e 's/ .*//'` } checkdatabaseds() { NB=`$PS -ef | $GREP -i databaseds | $GREP -v $GREP | wc -l` export NB if [ $NB = 0 ] then return=1 else return=0 fi } killproc() { pid=`$PS -e | $GREP "$1" | $SED -e 's/^ *//' -e 's/ .*//'` [ "$pid" != "" ] && kill -9 $pid } # # Check the platform used # OS=`uname -s` # # Settings common to all platforms # DATABASEDSHOME=@prefix@/bin ACCESSCONTROLHOME=@prefix@/bin LD_LIBRARY_PATH=@prefix@/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH # # Platform specific settings # case "${OS}" in "Linux") PS="/bin/ps" ECHO="/bin/echo -e" GREP="grep" SED="sed" TANGO_LOG="/tmp/tango.log" ;; "SunOS") rc_failed=" failed" rc_done=" OK" PS="/bin/ps" ECHO="/usr/ucb/echo" GREP="grep" SED="sed" TANGO_LOG=/tmp/tango.log ;; "HP-UX") test -f /etc/rc.config && . /etc/rc.config PS="/usr/bin/ps" ECHO="/bin/echo " GREP="/usr/bin/grep" SED="/usr/bin/sed" TANGO_LOG="/tmp/tango.log" ;; *) echo "Not supporting operating system: " ${OS} exit 1 esac # # Main part # case "$1" in start) ${ECHO} "Starting TANGO database" # first check the MySQL server checkmysql export return if [ ${return} = 1 ] then sleep 3 checkmysql if [ ${return} = 1 ] then # MySQL is not there, we can't start Tango db ${ECHO} "PLEASE Start MySQL server\n" 'date' >> ${TANGO_LOG} ${ECHO} "Failed to start Tango database server" >> ${TANGO_LOG} ${ECHO} "MySQL is not running !!!" >> ${TANGO_LOG} ${ECHO} "$rc_failed" exit 1 fi fi # Start the database device server if needed findproc DataBase if [ "$pid" != "" ]; then ${ECHO} "Database Server already running" 'date' >> ${TANGO_LOG} ${ECHO} "Database Server already running" >> ${TANGO_LOG} else ${DATABASEDSHOME}/DataBaseds 2 -ORBendPoint giop:tcp::$TANGO_DB_PORT & ${ECHO} "Starting TANGO Database Server" 'date' >> ${TANGO_LOG} ${ECHO} "Starting TANGO Database Server" >> ${TANGO_LOG} # wait for a while before checking status sleep 3 findproc DataBase if [ "$pid" = "" ]; then ${ECHO} "Failed to start Tango database server" 'date' >> ${TANGO_LOG} ${ECHO} "Failed to start Tango database server" >> ${TANGO_LOG} exit 1 fi ${ECHO} "$rc_done" fi # Start the tango control access server if needed findproc TangogAccessC if [ "$pid" != "" ]; then ${ECHO} "TangoAccessControl Server already running, exiting" 'date' >> ${TANGO_LOG} ${ECHO} "TangoAccessControl Server already running, exiting" >> ${TANGO_LOG} else export SUPER_TANGO=true ${ACCESSCONTROLHOME}/TangoAccessControl 1 & ${ECHO} "Starting TANGO Control Access Server" 'date' >> ${TANGO_LOG} ${ECHO} "Starting TANGO Control Access Server" >> ${TANGO_LOG} # wait for a while before checking status sleep 2 findproc TangoAccessControl if [ "$pid" = "" ]; then ${ECHO} "Failed to start Tango access control server" 'date' >> ${TANGO_LOG} ${ECHO} "Failed to start Tango access control server" >> ${TANGO_LOG} exit 1 fi ${ECHO} "$rc_done" fi ;; stop) ${ECHO} "Shutting down TANGO control system" # first shutdown the control access device server 'date' >> ${TANGO_LOG} ${ECHO} "Stopping TANGO Control Access Server" >> ${TANGO_LOG} killproc TangoAccessControl # then shutdown the database device server 'date' >> ${TANGO_LOG} ${ECHO} "Stopping TANGO Database Server" >> ${TANGO_LOG} killproc DataBaseds ${ECHO} "$rc_done" ;; restart) $0 stop && sleep 2 && $0 start ;; status) checkmysql if [ ${return} = 0 ] then ${ECHO} "MySQL OK" else ${ECHO} "MySQL : No process" fi findproc DataBase if [ "$pid" != "" ]; then ${ECHO} "TANGO Database server OK" else ${ECHO} "TANGO Database server : No process" fi findproc TangoAccessC if [ "$pid" != "" ]; then ${ECHO} "TANGO Access Control server OK" else ${ECHO} "TANGO Access Control server : No process" fi ;; *) ${ECHO} "Usage: $0 {start|stop|status|restart}" exit 1 esac exit 0 tango-9.2.5a/doc/0000755023471100065110000000000013034745263010562 500000000000000tango-9.2.5a/doc/Makefile.am0000644023471100065110000000104113034744704012531 00000000000000 DOCS = tango.pdf SUBDIRS = man src install-data-local: mkdir -p $(DESTDIR)/$(docdir) for file in $(DOCS); do \ cp -f $(srcdir)/$$file $(DESTDIR)/$(docdir)/$$file; \ chmod u+w $(DESTDIR)/$(docdir)/$$file; \ done; uninstall-local: for file in $(DOCS);do \ rm $(DESTDIR)/$(docdir)/$$file; \ done; dist-hook: for file in $(DOCS); do \ cp $(top_srcdir)/doc/$$file $(distdir)/$$file; \ done; \ cp -R $(top_srcdir)/doc/src $(distdir); \ rm -rf `find $(distdir) -name .svn` tango-9.2.5a/doc/Makefile.in0000644023471100065110000005163313034745121012550 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DOCS = tango.pdf SUBDIRS = man src all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive dist-hook distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-local install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-local install-data-local: mkdir -p $(DESTDIR)/$(docdir) for file in $(DOCS); do \ cp -f $(srcdir)/$$file $(DESTDIR)/$(docdir)/$$file; \ chmod u+w $(DESTDIR)/$(docdir)/$$file; \ done; uninstall-local: for file in $(DOCS);do \ rm $(DESTDIR)/$(docdir)/$$file; \ done; dist-hook: for file in $(DOCS); do \ cp $(top_srcdir)/doc/$$file $(distdir)/$$file; \ done; \ cp -R $(top_srcdir)/doc/src $(distdir); \ rm -rf `find $(distdir) -name .svn` # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/man/0000755023471100065110000000000013034745262011334 500000000000000tango-9.2.5a/doc/man/astor.10000644023471100065110000000107213034744703012465 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH ASTOR "1" "September 2009" "Tango tools" "User Commands" .SH NAME astor \- Administrate a Tango control system .SH SYNOPSIS .B astor .SH DESCRIPTION Graphical tool to administrate a Tango control system .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/atkmoni.10000644023471100065110000000136113034744703013000 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH ATKMONI "1" "September 2009" "Tango tools" "User Commands" .SH NAME atkmoni \- Monitor Tango device attributes .SH SYNOPSIS .B atkmoni [\fIfile-name\fR] .SH DESCRIPTION Graphical tool to monitor Tango device(s) attribute(s). .TP \fBfile-name\fR File describing the atkmoni configuration. If omitted, a Tango devices tree is displayed allowing the user to select devices and attributes. .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/atkpanel.10000644023471100065110000000137613034744703013143 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH ATKPANEL "1" "September 2009" "Tango tools" "User Commands" .SH NAME atkpanel \- Monitor a Tango device .SH SYNOPSIS .B atkpanel [\fIdevice-name\fR] .SH DESCRIPTION Graphical tool to monitor a single Tango device. It displays all device attributes and allow the user to execute any device commands .TP \fBdevice-name\fR Specify the device name. If omitted, a window pops-up asking for a device name .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/atktuning.10000644023471100065110000000150213034744703013337 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH ATKTUNING "1" "September 2009" "Tango tools" "User Commands" .SH NAME atktuning \- Display several tango device(s) scalar attribute(s) in a single window .SH SYNOPSIS .B atktuning [\fI-nocmd\fR] .B .SH DESCRIPTION Graphical tool to display several tango device(s) scalar attribute(s) in a single window. The file given as parameter contains the attribute names and the column in which they are displayed .TP \fB\-nocmd\fR Do not display command button(s) .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/devicetree.10000644023471100065110000000137113034744703013456 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH DEVICETREE "1" "September 2009" "Tango tools" "User Commands" .SH NAME devicetree \- Build/Run simple Tango related graphical panels .SH SYNOPSIS .B devicetree [\fIfile-name\fR] .SH DESCRIPTION Graphical tool to build or run simple graphical panel with Tango device(s) attribute(s) and/or command(s) .TP \fBfile-name\fR Start devicetree in "run" mode for the panel described in \fIfile_name\fR .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/jdraw.10000644023471100065110000000120413034744703012441 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH JDRAW "1" "September 2009" "Tango tools" "User Commands" .SH NAME jdraw \- Tango synoptic design tool .SH SYNOPSIS .B jdraw [\fIfile-name\fR] .SH DESCRIPTION Graphical tool to design a Tango synoptic for the Tango ATK package. .TP \fBfile-name\fR File describing the synoptic. .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/jive.10000644023471100065110000000116113034744703012271 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH JIVE "1" "September 2009" "Tango tools" "User Commands" .SH NAME jive \- Browse the Tango database .SH SYNOPSIS .B jive [\fI-r\fR] .SH DESCRIPTION Graphical tool to browse the Tango database .TP \fB\-r\fR Read only mode (No write access to database allowed) .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/logviewer.10000644023471100065110000000157313034744703013346 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH LOGVIEWER "1" "September 2009" "Tango tools" "User Commands" .SH NAME logviewer \- Browse the Tango database .SH SYNOPSIS .B logviewer [\fIdevice_name\fR] .SH DESCRIPTION Graphical tool to display Tango logging message .TP \fBdevice_name\fR Device name is the name of the log consumer device implemented by this logviewer. Only devices sending message to this log consumer device will be displayed. If ommited, a device tree is displayed allowing the user to select device(s) for which he want to display logging messages. .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/pogo.10000644023471100065110000000175513034744703012311 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH POGO "1" "September 2009" "Tango tools" "User Commands" .SH NAME pogo \- Tango class code generator .SH SYNOPSIS .B pogo [\fI-src file_name\fR] [\fI-doc file_name\fR] .SH DESCRIPTION Graphical tool to generate Tango class code skeleton .TP \fB\-src file_name\fR Do not start the GUI. Re-generate source files from the Tango class description in \fIfile_name\fR. Source files will be written in the path given for \fIfile_name\fR. .TP \fB\-doc file_name\fR Do not start the GUI. Re-generate documentation files from the Tango class description in \fIfile_name\fR. Documentation files will be written in the path given for \fIfile_name\fR. .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/synopticappli.10000644023471100065110000000127413034744703014237 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH SYNOPTICAPPLI "1" "September 2009" "Tango tools" "User Commands" .SH NAME synopticappli \- Tango synoptic display tool .SH SYNOPSIS .B synopticappli [\fIfile-name\fR] .SH DESCRIPTION Graphical tool to display and animate a Tango synoptic. .TP \fBfile-name\fR File describing the synoptic. If ommitted, a file chooser window pops-up. .SH "AUTHOR" The Tango team .SH "SEE ALSO" The full documentation for .B Tango is maintained as a pdf file. If .B Tango is properly installed at your site, this pdf file should be available in /doc. You can also look at the Tango web site at .B http://www.tango-controls.org. tango-9.2.5a/doc/man/Makefile.am0000644023471100065110000000027313034744703013311 00000000000000 dist_man1_MANS = astor.1 \ atkmoni.1 \ atkpanel.1 \ atktuning.1 \ devicetree.1 \ jdraw.1 \ jive.1 \ logviewer.1 \ pogo.1 \ synopticappli.1 tango-9.2.5a/doc/man/Makefile.in0000644023471100065110000004215113034745121013316 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/man DIST_COMMON = $(dist_man1_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(dist_man1_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man1_MANS = astor.1 \ atkmoni.1 \ atkpanel.1 \ atktuning.1 \ devicetree.1 \ jdraw.1 \ jive.1 \ logviewer.1 \ pogo.1 \ synopticappli.1 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/man/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man1_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man1_MANS)'; \ list2=''; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/0000755023471100065110000000000013034745265011353 500000000000000tango-9.2.5a/doc/src/Makefile.am0000644023471100065110000000032613034745265013330 00000000000000SUBDIRS = ds_writing ds_model dance java_api gen_api advanced if TANGO_DOC_ENABLED pdf-local: tango.pdf endif tango.pdf: $(srcdir)/tango.lyx cd $(srcdir); @LYX@ --export pdf2 tango.lyx mv $(srcdir)/tango.pdf . tango-9.2.5a/doc/src/Makefile.in0000644023471100065110000005074313034745265013351 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = ds_writing ds_model dance java_api gen_api advanced all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: pdf-local ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am tags \ tags-recursive uninstall uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: tango.pdf tango.pdf: $(srcdir)/tango.lyx cd $(srcdir); @LYX@ --export pdf2 tango.lyx mv $(srcdir)/tango.pdf . # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/ds_writing/0000755023471100065110000000000013034745265013524 500000000000000tango-9.2.5a/doc/src/ds_writing/Makefile.am0000644023471100065110000000046013034745265015500 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ command \ r_pipe \ device_et \ w_attribute \ r_attribute \ complete_server \ w_pipe \ startup img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/ds_writing/Makefile.in0000644023471100065110000003313513034745264015515 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/ds_writing DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ command \ r_pipe \ device_et \ w_attribute \ r_attribute \ complete_server \ w_pipe \ startup all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/ds_writing/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/ds_writing/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/ds_writing/nt_server/0000755023471100065110000000000013034745265015533 500000000000000tango-9.2.5a/doc/src/ds_writing/nt_server/cons.ps0000644023471100065110000266455713034745264017011 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /mntdirect/_segfs/tango/doc/manual/programmer/nt_server/cnos.ps %%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley %%BoundingBox: 9 315 587 527 %%Pages: 1 %%DocumentFonts: %%EndComments %%EndProlog %%Page: 1 1 % remember original state /origstate save def % build a temporary dictionary 20 dict begin % define string to hold a scanline's worth of data /pix 1734 string def % define space for color conversions /grays 578 string def % space for gray scale line /npixls 0 def /rgbindx 0 def % lower left corner 9 315 translate % size of image (on paper, in 1/72inch coords) 578.01600 211.96800 scale % define 'colorimage' if it isn't defined % ('colortogray' and 'mergeprocs' come from xwd2ps % via xgrab) /colorimage where % do we know about 'colorimage'? { pop } % yes: pop off the 'dict' returned { % no: define one /colortogray { % define an RGB->I function /rgbdata exch store % call input 'rgbdata' rgbdata length 3 idiv /npixls exch store /rgbindx 0 store 0 1 npixls 1 sub { grays exch rgbdata rgbindx get 20 mul % Red rgbdata rgbindx 1 add get 32 mul % Green rgbdata rgbindx 2 add get 12 mul % Blue add add 64 idiv % I = .5G + .31R + .18B put /rgbindx rgbindx 3 add store } for grays 0 npixls getinterval } bind def % Utility procedure for colorimage operator. % This procedure takes two procedures off the % stack and merges them into a single procedure. /mergeprocs { % def dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def /colorimage { % def pop pop % remove 'false 3' operands {colortogray} mergeprocs image } bind def } ifelse % end of 'false' case 578 212 8 % dimensions of data [578 0 0 -212 0 212] % mapping matrix {currentfile pix readhexstring pop} false 3 colorimage c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 ffffffffffff c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 ffffffffffff000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080ffffffffffff000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080ffffff ffffff000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 ffffffffffff000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080ffffffffffff000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080ffffff ffffff000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 ffffffffffff000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080ffffffffffff000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080ffffffffffff 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080ffffff ffffff000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080ffffffffffffffffffffffff ffffff000080000080000080ffffffffffffffffffffffffffffffffffff000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080000080ffffff ffffff000080000080000080000080ffffffffffffffffffffffffffffff000080000080 000080ffffffffffffffffffffffffffffff000080000080000080000080ffffffffffff ffffffffffffffffffffffff000080ffffffffffff000080000080000080000080ffffff ffffff000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff ffffffffffffffffff000080000080000080000080ffffffffffffffffffffffff000080 000080000080000080ffffffffffffffffffffffffffffff000080000080000080ffffff ffffff000080000080000080ffffffffffffffffffffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffffffffff000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffffffffff000080ffffffffffff000080000080ffffffffffff000080 000080ffffffffffffffffff000080ffffffffffff000080000080000080000080ffffff ffffff000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff ffffff000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080000080000080000080000080000080ffffff ffffff000080000080000080000080ffffffffffffffffffffffffffffffffffff000080 000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080 000080000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff 000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080 000080000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080000080ffffffffffffffffffffffff000080 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffffffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080 000080000080ffffffffffff000080000080000080ffffffffffffffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080ffffffffffff 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080000080000080000080000080ffffffffffff 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffffffffff000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080 000080ffffffffffffffffff000080000080000080ffffffffffffffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080ffffffffffff000080000080ffffffffffff 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080ffffffffffffffffffffffff ffffff000080000080000080ffffffffffffffffffffffffffffffffffff000080000080 000080000080ffffffffffffffffffffffffffffff000080000080ffffffffffff000080 000080000080000080000080000080ffffffffffffffffffffffffffffffffffffffffff 000080ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff ffffffffffffffffffffffff000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff 000080000080ffffffffffff000080000080000080ffffffffffffffffffffffff000080 000080000080000080ffffffffffffffffffffffffffffff000080000080000080ffffff ffffff000080000080000080ffffffffffffffffffffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080ffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080ffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080ffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080ffffffffffffffffff000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000000000000000000000000000 ffffff000000000000ffffffffffff000000000000ffffff000000000000000000ffffff ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0000000000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000000000000000000000 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffffffffffffffff000000000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffff000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffff ffffff000000000000ffffff000000000000000000ffffffffffff000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000000000 000000000000000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000000000ffffffffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000000000000000 000000000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000000000000000000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000000000000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000000000000000ffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000000000 ffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffff000000000000ffffffffffff000000000000ffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffffffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffff000000000000 000000000000000000000000ffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffff000000000000ffffffffffffffffff000000000000000000000000 000000000000000000000000000000000000000000000000ffffff000000000000ffffff 000000000000000000ffffff000000000000ffffffffffff000000000000ffffff000000 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffff000000000000000000000000000000000000ffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffff000000000000ffffff000000000000000000ffffffffffff ffffffffffffffffff000000000000000000000000000000ffffffffffff000000000000 000000000000000000000000ffffff000000000000ffffff000000000000000000ffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffff000000000000000000000000000000000000 ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffff000000000000000000 000000000000000000ffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffff000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000000000000000000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffff000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffff000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000ffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000ffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000ffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000000000000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000000000000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000 000000000000000000ffffffffffffffffffffffffffffffffffff000000000000000000 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000000000000000000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffff 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000000000ffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000000000ffffffffffffffffff000000000000000000ffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff000000 000000000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffff 000000000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000000000000000ffffff000000000000ffffffffffff 000000000000000000000000000000ffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffff000000000000000000 ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffff000000000000000000000000000000000000ffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffff000000000000000000000000000000000000000000000000000000 000000000000000000ffffff000000000000ffffff000000000000000000ffffff000000 000000ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000000000 000000000000000000000000ffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 000000000000000000ffffffffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffffffffff000000000000 000000000000000000ffffffffffff000000000000000000000000000000000000ffffff 000000000000ffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffff000000000000000000000000000000000000ffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffff000000000000ffffff000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000ffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000000000000000000000ffffffffffff000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000ffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000000000000000000000000000000000 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffff000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffff000000000000 ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000ffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000ffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000ffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000000000ffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffff ffffff000000000000000000ffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 000000000000ffffff000000000000ffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000ffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000000000000000ffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffff000000000000 000000000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000ffffff 000000000000ffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff 000000000000ffffff000000000000000000ffffffffffffffffff000000000000000000 000000ffffffffffffffffffffffffffffff000000000000000000000000000000000000 ffffffffffff000000000000000000000000000000000000ffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffff000000000000ffffff000000000000000000ffffffffffffffffffffffffffffff ffffff000000000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff 000000000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000ffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000000000000000000000 000000000000000000ffffffffffffffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000000000 000000000000000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 000000000000000000000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000000000000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffff000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000ffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffff000000000000000000ffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000000000ffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffff000000000000 000000000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000000000ffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000ffffff 000000000000ffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffff000000000000000000000000000000ffffff 000000000000ffffffffffffffffff000000000000000000ffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffffffffff000000000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffff000000000000ffffff000000000000000000ffffffffffffffffffffffffffffff ffffff000000000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffff000000000000 000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff 000000000000000000ffffff000000000000ffffff000000000000000000ffffff000000 000000ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000000000000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000000000000000 000000000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000000000000000000000000000000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000000000000000000000ffffff 000000000000ffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffff000000000000ffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000 000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffff000000000000000000000000000000000000ffffffffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000000000 ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffff000000000000000000000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffff000000000000000000000000000000 000000ffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000000000000000000000ffffffffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000000000000000000000000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffff000000000000 ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000000000000000000000ffffff000000000000ffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000000000 ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffff000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffff000000000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000000000000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffffffffff000000000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffff000000000000 000000000000000000000000000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff 000000000000000000ffffff000000000000ffffff000000000000000000ffffff000000 000000ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000000000 ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000000000000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000000000000000000000 000000000000000000ffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000000000000000000000000000000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000 000000000000ffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000000000000000000000ffffff 000000000000ffffffffffff000000000000000000000000000000ffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000000000000000000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff000000 000000ffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff000000 000000ffffffffffffffffffffffff000000000000000000000000000000ffffffffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffff000000000000ffffff000000000000ffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000 000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000000000000000000ffffff ffffffffffffffffffffffff000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffff000000000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff ffffff000000000000000000000000000000000000ffffffffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000000000 ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffff000000000000000000000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffff000000000000ffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff000000 000000000000ffffffffffff000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000ffffffffffffffffff000000000000000000000000000000 000000ffffff000000000000ffffff000000000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000 ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000000000ffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffffffffffffffffffffff000000000000000000000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000000000000000000000ffffffffffff000000000000 000000ffffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000000000000000000000000000000000 000000ffffffffffffffffff000000000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000000000000000000000000000000000000000ffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 000000000000000000000000000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 000000000000000000000000000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffff000000000000ffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffff000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffff000000000000ffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff 000000000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000ffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff 000000000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000 ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000000000ffffffffffff000000 000000ffffffffffffffffffffffff000000000000ffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000ffffffffffff000000000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffffffffff000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff 000000000000ffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffff000000 000000ffffffffffffffffff000000000000ffffffffffffffffff000000000000ffffff ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffff000000000000ffffffffffffffffffffffff000000 000000ffffffffffff000000000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0000000000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff000000000000000000000000 000000000000000000000000ffffffffffffffffff000000000000000000000000000000 ffffffffffffffffffffffff000000000000000000000000000000ffffff000000000000 ffffffffffffffffff000000000000000000ffffffffffffffffffffffff000000000000 ffffffffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff ffffffffffffffffff000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000000000ffffffffffffffffff ffffffffffff000000000000000000ffffffffffffffffffffffff000000000000ffffff ffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffff000000000000ffffffffffff ffffff000000000000000000000000000000ffffff000000000000ffffffffffff000000 000000000000000000000000ffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000000000ffffffffffff000000000000ffffff ffffffffffffffffff000000000000ffffff000000000000ffffff000000000000000000 ffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffff000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffff000000000000 000000ffffffffffffffffffffffff000000000000ffffffffffffffffffffffff000000 000000000000000000ffffffffffffffffffffffffffffff000000000000000000000000 000000ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffff000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffff 000000000000000000000000000000ffffffffffffffffffffffffffffff000000000000 000000ffffff000000000000ffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffff 000000000000000000ffffff000000000000ffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffff ffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff000000000000000000000000000000000000000000000000000000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000ffffffffffffffffff000000000000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000ffffff ffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000000000000000000000000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 ffffffffffff c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080000000 ffffffffffff 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff showpage % stop using temporary dictionary end % restore original state origstate restore %%Trailer tango-9.2.5a/doc/src/ds_writing/nt_server/main.ps0000644023471100065110000357123413034745264016761 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /mntdirect/_segfs/tango/doc/manual/programmer/nt_server/main.ps %%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley %%BoundingBox: 104 213 491 628 %%Pages: 1 %%DocumentFonts: %%EndComments %%EndProlog %%Page: 1 1 % remember original state /origstate save def % build a temporary dictionary 20 dict begin % define string to hold a scanline's worth of data /pix 1161 string def % define space for color conversions /grays 387 string def % space for gray scale line /npixls 0 def /rgbindx 0 def % lower left corner 104 213 translate % size of image (on paper, in 1/72inch coords) 387.00000 415.00800 scale % define 'colorimage' if it isn't defined % ('colortogray' and 'mergeprocs' come from xwd2ps % via xgrab) /colorimage where % do we know about 'colorimage'? { pop } % yes: pop off the 'dict' returned { % no: define one /colortogray { % define an RGB->I function /rgbdata exch store % call input 'rgbdata' rgbdata length 3 idiv /npixls exch store /rgbindx 0 store 0 1 npixls 1 sub { grays exch rgbdata rgbindx get 20 mul % Red rgbdata rgbindx 1 add get 32 mul % Green rgbdata rgbindx 2 add get 12 mul % Blue add add 64 idiv % I = .5G + .31R + .18B put /rgbindx rgbindx 3 add store } for grays 0 npixls getinterval } bind def % Utility procedure for colorimage operator. % This procedure takes two procedures off the % stack and merges them into a single procedure. /mergeprocs { % def dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def /colorimage { % def pop pop % remove 'false 3' operands {colortogray} mergeprocs image } bind def } ifelse % end of 'false' case 387 415 8 % dimensions of data [387 0 0 -415 0 415] % mapping matrix {currentfile pix readhexstring pop} false 3 colorimage c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffff c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff000000000080000080ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ff00ffff00ffff00ffff00ffff00ff ff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ff00ffff00ffff00ffff00ffff00ff ff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff000080000080000080 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080ffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffffffff000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080ff00ffff00ffff00ffff00ffff00ff ff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ffff00ff000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080ffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffffffff000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080ffffffffffff000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffffffff000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0000000000000c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080008080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 ffffffffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff ffffff000080000080000080000080ffffffffffffffffffffffffffffffffffff000080 000080000080ffffffffffffffffffffffffffffff000080000080000080000080000080 000080000080000080ffffffffffffffffffffffffffffffffffff000080000080000080 ffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080000080 000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffffffffff ffffffffffff000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080ffffffffffffffffffffffff000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff ffffffffffffffffffffffff000080000080000080000080ffffffffffff000080000080 ffffffffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffff 000080000080000080000080000080ffffffffffff000080000080000080000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff ffffffffffffffffffffffff000080000080000080000080ffffffffffffffffffffffff ffffff000080000080000080000080ffffffffffff000080000080000080000080ffffff ffffffffffffffffffffffff000080000080000080ffffffffffffffffffffffffffffff 000080000080000080000080ffffffffffffffffffffffffffffffffffff000080ffffff ffffff000080000080000080000080ffffffffffff000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080008080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffffffffff000080 ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080ffffffffffffffffff000080000080ffffff ffffff000080000080000080ffffffffffff000080ffffffffffff000080000080000080 000080ffffffffffff000080ffffffffffff000080000080ffffffffffff000080000080 000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffff000080 000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff ffffff000080ffffffffffff000080000080000080000080ffffffffffff000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080000080 ffffffffffff000080000080000080ffffffffffff000080000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffffffffff000080ffffff ffffff000080000080ffffffffffff000080000080ffffffffffffffffff000080ffffff ffffff000080000080000080000080ffffffffffff000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 ffffffffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080ffffffffffff000080000080000080ffffffffffff000080 000080000080000080000080000080ffffffffffff000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080 000080000080000080000080000080ffffffffffff000080000080000080000080ffffff ffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffffffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080ffffffffffffffffffffffffffffffffffffffffff000080 000080000080000080000080000080000080ffffffffffffffffffffffff000080000080 000080ffffffffffffffffffffffffffffffffffffffffff000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff ffffffffffffffffffffffffffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0000000000000c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080000080ffffffffffff000080000080ffffff ffffff000080000080000080000080000080000080000080000080ffffffffffffffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080ffffffffffff000080 000080ffffffffffff000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff ffffff000080000080000080000080000080000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080000080ffffffffffff000080000080 000080ffffffffffffffffffffffff000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080000080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 ffffffffffff000080000080ffffffffffff000080000080ffffffffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080000080000080 000080000080ffffffffffff000080000080ffffffffffffffffff000080000080ffffff ffffff000080000080000080ffffffffffff000080000080000080ffffffffffffffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 000080ffffffffffff000080ffffffffffff000080000080000080ffffffffffff000080 000080000080000080000080000080ffffffffffff000080000080ffffffffffff000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff 000080000080000080000080ffffffffffffffffffffffff000080000080000080ffffff ffffff000080000080000080ffffffffffff000080000080ffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080ffffffffffff000080000080ffffffffffff ffffff000080000080ffffffffffff000080000080ffffffffffff000080000080000080 ffffffffffff000080000080ffffffffffff000080000080000080000080ffffffffffff 000080000080000080ffffffffffff000080000080ffffffffffff000080000080ffffff ffffff000080000080ffffffffffff000080000080ffffffffffffffffff000080000080 000080ffffffffffffffffffffffff000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080008080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080ffffffffffff000080000080000080000080000080000080 ffffffffffffffffffffffffffffffffffffffffff000080ffffffffffff000080000080 ffffffffffff000080000080000080ffffffffffffffffffffffffffffffffffff000080 000080000080ffffffffffffffffffffffffffffff000080000080000080000080000080 000080000080000080ffffffffffffffffffffffffffffffffffff000080000080000080 ffffffffffffffffffffffffffffff000080000080000080000080000080ffffffffffff 000080000080000080000080ffffffffffff000080000080000080ffffffffffffffffff ffffffffffff000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080ffffffffffffffffffffffff000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff 000080000080000080000080000080ffffffffffff000080000080000080000080000080 ffffffffffffffffffffffffffffff000080000080000080ffffffffffff000080000080 000080000080000080000080000080ffffffffffff000080000080000080000080000080 000080000080ffffffffffffffffffffffffffffff000080000080000080ffffffffffff ffffffffffffffffffffffff000080000080000080000080ffffffffffffffffffffffff ffffff000080000080ffffffffffff000080000080000080000080000080000080ffffff ffffffffffffffffffffffffffffffffffff000080ffffffffffff000080000080ffffff ffffff000080000080000080ffffffffffffffffffffffffffffffffffff000080000080 000080000080ffffffffffff000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000080000080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080008080008080008080 ff00ffff00ffff00ff008080008080008080008080008080008080008080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080ffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080ffffffffffff000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080ffffff808080808080808080808080808080 808080808080808080808080808080808080808080808080808080000000ffffff808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000000080000080ffffff808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 008080008080008080008080008080008080008080008080008080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080ffffffffffff000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080ffffffffffff000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080ffffffffffff000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000080000080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080ffffffffffffffffffffffffffffff000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080ffffffffffff 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080ffffff ffffffffffff000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080000080000080 000080000080000080000080000080000080000080000080000080000080c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000 000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080808080808080808080808080808080808080808080 808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000000000808080000000808080000000000000808080000000808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080000000808080000000000000808080808080808080808080808080 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080000000000000808080000000808080000000000000808080000000000000808080 808080000000c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 000000000000ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffff 808080808080808080808080c0c0c0c0c0c0808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000808080808080808080 808080808080808080000000000000000000000000000000808080808080000000808080 000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080 000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0808080808080808080808080000000808080000000808080000000000000 000000808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffff ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000808080 808080808080000000000000000000000000000000000000808080000000808080808080 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0000000 000000808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 000000808080808080000000808080808080000000000000000000808080808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0 c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080808080000000808080 000000000000000000808080000000000000000000000000000000000000000000808080 808080000000000000808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0000000000000 000000808080000000808080c0c0c0c0c0c0808080808080808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000808080808080808080 000000000000808080000000000000000000000000808080000000000000000000000000 000000808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffffffff ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0 c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080808080808080808080000000808080 000000000000000000000000000000000000000000000000000000808080000000808080 808080808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080ffffffc0c0c0c0c0c0ffffff808080000000000000 808080808080808080000000000000000000000000000000808080000000000000808080 000000808080808080808080808080000000808080000000808080000000808080000000 000000000000000000000000808080000000000000000000000000000000808080000000 000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffff000000808080808080808080808080808080808080000000808080 000000000000000000000000000000000000000000000000808080000000000000000000 808080808080000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000 000000000000808080808080808080808080808080000000808080000000000000808080 000000808080000000808080000000000000808080000000000000000000000000000000 000000808080000000000000000000000000000000000000000000808080808080000000 000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffff ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000808080808080808080808080808080808080808080000000000000 000000000000000000000000000000808080000000000000000000000000000000808080 808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080000000 808080000000000000000000000000808080000000000000808080000000808080000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffc0c0c0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080000000808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080000000 c0c0c0000000000000808080808080808080808080808080000000808080000000000000 000000000000808080000000000000000000000000808080000000000000000000808080 000000000000000000808080000000000000000000000000000000808080000000808080 000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffff c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000808080808080808080000000808080808080808080808080000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000808080000000808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080000000000000808080000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 808080808080000000000000000000000000000000000000000000808080c0c0c0000000 000000000000000000808080000000000000000000000000808080000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffff c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffff ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080808080808080808080808080808080000000808080000000808080 808080808080000000000000000000000000808080000000000000808080000000000000 808080808080808080808080000000c0c0c0808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080000000000000000000c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 808080c0c0c0000000000000000000808080808080808080808080000000000000808080 000000000000000000000000000000000000000000000000000000808080000000808080 000000000000808080000000000000000000808080000000000000000000808080000000 000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffff808080808080 808080808080808080808080808080808080808080808080808080808080808080000000 000000808080808080000000808080000000000000000000808080000000000000808080 808080808080808080000000808080808080808080000000808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080 808080000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080c0c0c0000000000000000000000000000000000000000000000000000000808080 808080000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000808080808080000000 000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffff ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffff ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff000000808080 808080808080808080808080808080808080808080808080808080808080808080808080 000000808080808080000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000808080000000808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080ffffffc0c0c0c0c0c0808080808080000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080808080808080000000000000000000000000808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080000000000000808080000000000000000000000000000000000000000000000000 000000808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffff ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffc0c0c0 ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080808080808080808080808080808080808080808080808080808080000000 808080000000000000808080000000808080000000000000000000808080000000000000 000000000000000000000000000000808080000000000000000000808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080000000000000808080000000000000808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080c0c0c0000000000000000000808080808080808080000000808080000000 808080c0c0c0808080000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffff ffffffffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffff ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffff ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0808080808080808080 808080808080808080808080808080808080808080808080808080000000808080808080 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080ffffff000000000000000000000000808080000000000000000000c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000808080000000000000000000000000000000 000000000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000808080000000808080c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080 808080808080ffffff808080000000000000000000000000c0c0c0808080808080000000 000000000000000000c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffff ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080 808080808080808080808080808080808080808080808080000000808080808080000000 808080808080000000000000000000000000808080808080000000000000000000000000 000000808080000000000000000000808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080c0c0c0c0c0c0808080000000000000808080000000808080000000000000000000 808080c0c0c0000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080000000808080000000808080808080000000000000000000000000000000 808080000000808080000000000000808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080808080c0c0c0808080808080c0c0c0c0c0c0808080808080808080 808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080808080 808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0 808080c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000808080808080 808080000000000000000000808080808080000000000000000000000000000000000000 000000000000000000000000000000808080808080000000000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080000000000000 808080808080808080000000000000808080000000000000808080808080000000000000 808080000000808080000000808080808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff 808080000000000000000000000000808080808080c0c0c0808080c0c0c0808080808080 808080808080808080c0c0c0808080808080808080808080808080808080808080808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 000000c0c0c0c0c0c0c0c0c0808080808080000000000000000000808080000000000000 000000000000808080c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080808080 000000808080808080808080808080808080000000808080808080808080808080808080 808080808080808080000000808080000000808080000000000000808080000000000000 000000808080000000808080808080000000808080808080000000808080808080808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000808080808080808080808080808080808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080808080808080808080 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080808080808080808080 000000c0c0c0c0c0c0c0c0c0808080808080000000000000808080808080000000000000 808080808080000000000000000000000000808080000000000000000000000000000000 000000000000000000808080000000000000000000808080000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 ffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0808080808080000000808080000000 000000000000808080000000808080000000000000000000808080000000000000000000 000000808080808080808080808080808080808080000000000000000000000000000000 000000808080808080000000000000808080808080808080808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080 c0c0c0c0c0c0808080808080808080000000808080808080808080808080808080c0c0c0 808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080808080 808080ffffffc0c0c0c0c0c0808080000000808080000000808080000000808080000000 000000000000000000000000808080808080000000808080000000808080808080000000 000000000000000000000000808080000000000000000000000000000000808080000000 000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffc0c0c0ffffffc0c0c0ffffff808080808080808080808080000000 000000000000000000000000000000808080000000000000000000808080000000000000 808080808080808080808080000000808080808080000000000000000000000000000000 808080000000000000808080000000808080808080000000000000000000808080808080 808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080000000000000000000808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080 808080c0c0c0c0c0c0ffffff808080000000000000000000000000000000808080000000 000000000000808080808080000000000000000000808080808080000000808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffffffff c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0808080808080808080000000808080 000000808080000000000000000000000000000000000000000000000000000000000000 808080000000808080000000000000000000808080808080000000000000000000000000 808080000000000000000000000000808080000000808080000000808080808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 000000000000000000000000000000000000808080808080808080808080808080808080 808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0000000808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000808080000000000000000000 808080000000000000000000000000000000808080808080000000000000000000808080 000000000000000000000000000000000000808080808080000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000000000 000000000000808080000000000000000000808080000000000000000000000000000000 000000000000808080000000000000000000808080000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080808080808080808080808080808080808080808080000000 000000000000000000000000000000000000000000000000808080808080808080c0c0c0 808080808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0ffffff808080000000000000000000000000000000000000000000 808080000000000000808080000000808080000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffff ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffffffffff c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffffffffffffff808080808080808080000000000000000000 000000000000808080000000000000000000808080808080000000000000000000000000 000000000000000000000000000000000000000000808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080000000 ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000808080000000000000 808080000000000000808080000000808080000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0 ffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffff808080808080808080000000808080000000000000000000000000 000000808080808080000000000000808080000000808080000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffff000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 808080808080808080808080808080808080808080808080808080000000808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 808080000000000000000000000000808080000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000808080808080000000808080808080000000000000000000000000 000000000000808080000000000000000000808080000000000000000000808080000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000808080808080000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000808080 808080808080808080808080808080808080000000808080000000808080000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 808080000000000000000000000000808080000000000000000000000000000000808080 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0 808080808080808080808080808080000000808080000000000000000000808080000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000808080808080 808080808080808080808080c0c0c0808080808080000000000000808080000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000808080000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0 ffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffff ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0 c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080808080000000808080000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000c0c0c0ffffff808080 808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffff000000808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080000000000000808080808080 808080808080808080808080808080000000808080000000000000000000000000ffffff 808080808080c0c0c0ffffff808080808080000000000000000000808080000000000000 808080000000000000000000000000808080000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffff ffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffff c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff808080 808080808080808080808080000000000000808080808080000000808080000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080808080ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000808080000000808080808080808080000000808080808080 808080808080808080808080c0c0c0808080000000808080808080000000808080c0c0c0 000000000000000000c0c0c0c0c0c0808080808080000000000000000000000000000000 808080000000808080000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffff ffffffc0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffff808080808080 808080808080000000808080000000000000000000000000808080808080000000808080 808080000000000000808080808080000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000808080808080000000808080808080 808080808080808080808080808080808080000000808080c0c0c0000000ffffffc0c0c0 000000000000000000000000808080808080808080000000000000808080000000000000 808080000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffff ffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffff808080808080 808080000000808080000000000000000000000000000000808080000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000808080000000000000000000000000808080808080808080 808080808080808080000000808080000000000000c0c0c0808080c0c0c0c0c0c0c0c0c0 808080808080808080000000808080808080808080000000000000000000000000000000 000000000000808080000000000000808080000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffff ffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080808080 808080000000000000000000000000000000000000000000000000808080000000808080 808080000000808080000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080000000c0c0c0c0c0c0ffffff808080 808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080808080 000000000000000000000000000000808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000808080000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080000000000000808080000000808080000000000000000000000000808080808080 808080000000808080000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000808080000000808080c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000808080808080808080000000000000000000000000000000808080000000 000000000000000000000000000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080000000000000000000000000000000808080 000000000000000000000000000000808080000000808080000000000000000000808080 000000808080000000808080000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080000000808080000000000000000000000000000000000000000000000000000000 000000808080808080000000000000808080000000000000000000808080808080000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000808080000000000000000000000000000000000000808080808080c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080808080808080808080000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000808080000000000000 000000808080000000000000000000000000808080808080c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080000000000000808080 000000000000808080000000000000000000000000808080000000000000000000000000 000000808080000000000000808080000000000000808080000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000 808080000000000000000000808080000000000000000000000000808080808080000000 000000808080000000808080000000000000808080808080000000808080000000000000 000000000000808080000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000808080000000808080808080c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffff808080808080808080808080000000000000000000 000000000000000000000000808080000000000000000000000000000000000000808080 000000808080000000000000000000808080000000c0c0c0000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000808080 000000000000000000000000000000000000000000808080000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000808080000000808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 c0c0c0c0c0c0ffffffc0c0c0808080808080808080808080000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000808080000000000000000000808080000000c0c0c0808080000000808080 000000000000000000000000000000000000000000808080808080ffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffff c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000808080808080808080000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000808080808080808080808080000000808080000000000000 000000000000000000000000000000000000000000808080000000000000808080000000 000000000000000000808080000000000000000000000000000000808080808080000000 000000808080000000000000000000000000000000000000000000ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000808080808080 000000808080000000000000000000000000000000808080000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0808080 000000000000808080000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000808080000000ffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000808080000000000000808080000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffff ffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000808080 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000ffffffc0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000808080000000 000000808080000000000000808080000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000808080000000000000000000000000000000000000000000 000000808080808080000000000000000000000000000000000000000000000000808080 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080808080808080808080000000808080808080000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000808080808080000000ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffffffff ffffffffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffff ffffffc0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000808080000000000000000000 000000000000000000808080000000808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000808080808080ffffffc0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffff808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000808080808080808080000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffff ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000808080808080000000000000000000 000000000000000000000000808080808080c0c0c0808080000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000808080000000808080000000000000000000000000000000c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000 808080000000000000000000000000000000000000000000000000000000000000808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000808080000000000000808080808080000000808080000000000000000000 000000808080808080000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000808080c0c0c0808080 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080000000000000808080 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000808080c0c0c0000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffff808080c0c0c0c0c0c0c0c0c0ffffff000000000000808080000000808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 808080000000000000000000000000000000808080c0c0c0c0c0c0808080000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffff ffffffffffff808080c0c0c0808080808080c0c0c0808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000808080808080808080808080c0c0c0c0c0c0c0c0c0808080808080000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff ffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffffffff ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0000000 000000000000000000000000808080000000000000000000000000000000000000808080 000000000000000000000000808080000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080808080 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000808080808080000000000000 000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000808080808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080808080 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000000000808080000000808080000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080000000000000808080808080000000000000808080808080000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000808080808080000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0808080000000000000808080000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0808080808080808080808080808080808080808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080808080ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000000000000000808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000000000808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0808080808080808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffff ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0000000 c0c0c0808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000808080808080c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0808080c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080808080808080808080808080c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080808080808080808080808080808080808080808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 808080000000808080808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080808080808080808080808080808080808080808080808080808080808080 808080808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0 c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080808080 808080808080808080808080808080808080c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080000000000000000000000000000000000000 000000808080000000000000000000000000808080000000000000000000808080000000 000000000000000000000000808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080000000000000808080808080000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080808080000000808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080c0c0c0808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080808080c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080000000808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000808080000000808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080c0c0c0808080808080c0c0c0808080 808080c0c0c0808080808080808080808080808080c0c0c0808080808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080000000808080 000000808080808080808080808080808080000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000808080808080808080808080808080808080 c0c0c0808080808080808080808080808080c0c0c0808080808080c0c0c0808080808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000808080000000 000000000000000000808080000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffff c0c0c0808080808080808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080000000c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffff808080ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0808080808080808080808080808080c0c0c0808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080808080808080808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0ffffffc0c0c0ffffffffffff808080808080808080808080808080 808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000808080c0c0c0c0c0c0808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0 808080000000808080808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0808080ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0ffffffc0c0c0808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000808080808080c0c0c0c0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080 808080808080808080808080000000000000808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0000000000000000000000000808080 000000000000000000000000808080000000000000808080000000808080000000808080 808080000000c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080000000808080000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000808080000000000000000000 000000000000000000000000000000000000000000808080000000000000000000808080 000000c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080808080808080000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0 808080808080808080808080808080000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080000000808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0c0c0c0808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000808080 808080000000000000000000000000000000000000000000000000808080000000808080 808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080 c0c0c0808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000808080c0c0c0808080808080808080808080808080808080808080808080 808080808080808080808080808080000000808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0ffffffc0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080808080808080808080808080000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080808080 000000808080808080808080c0c0c0808080808080000000808080000000000000808080 000000000000808080000000808080000000000000000000000000000000000000808080 000000000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080c0c0c0808080000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080c0c0c0808080000000808080 808080808080808080808080808080000000808080000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0 c0c0c0808080c0c0c0808080000000000000808080000000c0c0c0808080000000000000 000000808080000000808080808080000000808080808080000000000000000000808080 808080000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000808080000000808080808080 808080808080000000000000000000000000808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000808080000000000000000000 000000000000000000000000000000000000c0c0c0c0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080000000000000 808080000000000000808080808080000000000000000000000000000000000000000000 000000c0c0c0808080808080000000c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0808080000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080808080c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080000000 808080000000808080808080000000000000000000808080000000000000000000000000 000000808080808080808080808080808080c0c0c0808080808080ffffff808080808080 808080808080808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080808080ffffff808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080c0c0c0000000000000000000808080808080808080c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0000000 808080808080000000808080000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000808080808080c0c0c0808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080c0c0c0808080c0c0c0808080808080 c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080 000000808080000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000808080ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0000000000000808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000808080000000000000 000000000000808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080c0c0c0c0c0c0 808080000000808080000000808080000000000000808080808080000000808080000000 808080000000000000000000000000000000000000000000000000000000000000000000 808080000000808080808080000000000000808080000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000808080 000000000000000000000000808080808080808080808080808080808080808080808080 c0c0c0808080808080808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000808080000000000000000000000000808080000000000000000000 000000808080000000000000808080000000000000808080808080000000000000000000 000000808080808080000000808080808080000000808080000000000000000000000000 000000000000808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000808080000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0000000000000808080000000000000808080000000 808080808080808080808080000000000000808080808080808080000000000000808080 808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000c0c0c0 ffffffc0c0c0c0c0c0c0c0c0808080808080808080000000808080000000000000000000 000000808080c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0808080808080000000000000000000808080808080808080 808080808080808080808080c0c0c0808080808080c0c0c0808080000000c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0ffffffc0c0c0 808080c0c0c0808080808080000000000000000000808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080000000808080000000000000 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0808080000000808080808080808080808080000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0 c0c0c0808080808080c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000808080000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 000000000000808080808080c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080808080808080000000808080000000000000000000000000000000808080 808080000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080000000 808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000808080808080 808080808080808080808080808080000000000000000000000000000000000000808080 000000000000000000000000000000000000000000c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080ffffffc0c0c0c0c0c0808080000000808080c0c0c0 808080c0c0c0c0c0c0808080000000000000000000000000808080c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000808080000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0ffffff808080808080 000000000000000000000000000000000000808080808080000000000000808080000000 808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080c0c0c0c0c0c0808080 808080c0c0c0808080808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000000000808080 c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0808080808080808080c0c0c0 c0c0c0808080000000808080808080808080c0c0c0ffffff808080c0c0c0808080c0c0c0 c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080c0c0c0808080808080c0c0c0000000000000000000000000000000000000 000000808080000000808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0808080808080000000000000000000000000808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080c0c0c0808080808080808080808080808080808080000000000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000000000 000000000000000000808080c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080000000808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000c0c0c0808080c0c0c0808080000000808080808080000000000000000000 000000000000000000c0c0c0808080808080808080808080808080000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000000000 000000808080808080808080808080000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000808080000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000808080c0c0c0808080000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0808080808080808080000000000000000000000000808080000000000000000000 000000000000000000000000000000000000808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000808080808080000000808080808080808080000000000000 808080808080808080000000000000808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000808080000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000808080808080c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080000000000000000000 000000000000000000000000000000000000000000000000808080c0c0c0808080808080 808080ffffffc0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080808080c0c0c0c0c0c0000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080000000000000000000000000 000000000000808080000000808080000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000 000000000000000000000000808080808080000000000000000000000000808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000808080000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080000000808080808080000000000000 808080000000000000000000000000c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080000000 c0c0c0c0c0c0808080c0c0c0808080808080808080808080c0c0c0808080000000000000 000000000000808080808080000000000000000000000000000000808080000000000000 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000808080000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 808080000000808080000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0808080808080808080808080808080808080 808080808080c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0 808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080000000 c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080000000000000808080808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080808080808080808080808080808080000000000000808080808080808080 808080808080c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0808080808080 808080808080c0c0c0808080c0c0c0808080c0c0c0808080808080808080808080000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080808080808080 808080808080000000000000000000808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000808080000000 000000000000000000808080000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080808080 808080808080000000808080808080808080c0c0c0808080808080808080808080c0c0c0 808080808080808080000000808080808080808080808080808080c0c0c0808080808080 808080808080808080808080000000c0c0c0808080808080808080c0c0c0808080808080 000000000000000000000000000000000000000000000000000000808080000000000000 808080000000000000000000000000000000000000808080000000808080000000000000 000000000000808080000000000000000000808080000000808080000000000000000000 000000808080000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0808080c0c0c0 808080808080000000808080c0c0c0808080808080c0c0c0808080808080808080808080 000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 000000808080000000000000000000000000000000c0c0c0c0c0c0808080c0c0c0000000 808080808080808080808080000000000000000000000000000000000000808080000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000808080000000000000 000000000000808080c0c0c0808080808080808080808080808080808080808080808080 808080000000000000808080808080000000808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000808080808080000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000 000000000000c0c0c0808080c0c0c0808080808080808080808080808080000000808080 808080808080808080808080808080000000808080808080808080808080000000808080 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000808080000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080c0c0c0808080c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080000000808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080808080808080 808080808080808080808080808080808080000000000000808080808080808080808080 808080808080000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000808080000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080808080c0c0c0808080808080c0c0c0ffffffffffff 808080000000808080c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0808080c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0808080808080808080000000808080000000808080808080 808080808080808080c0c0c0808080808080808080808080000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000808080000000000000808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 808080808080000000000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080 808080808080c0c0c0808080c0c0c0808080000000808080808080808080808080808080 808080808080808080808080c0c0c0808080808080808080000000000000000000808080 000000808080808080808080808080808080808080808080c0c0c0808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080808080808080 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080 808080808080808080808080808080808080808080c0c0c0c0c0c0808080808080808080 000000000000808080000000000000000000000000000000000000000000808080808080 808080c0c0c0808080000000808080000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080000000 000000000000000000808080000000000000808080808080808080808080808080808080 808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0808080808080808080808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0ffffffc0c0c0c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0808080 808080808080808080808080808080808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000808080000000000000000000000000000000808080 000000000000808080000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080000000000000 000000000000000000808080c0c0c0808080808080000000808080808080808080000000 000000000000000000808080000000000000000000000000808080808080808080c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080808080808080000000808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000808080000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080000000 000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080c0c0c0c0c0c0808080808080808080808080000000808080000000 000000000000000000000000808080808080808080808080808080808080ffffffc0c0c0 808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0ffffffc0c0c0808080c0c0c0808080808080808080808080808080000000 000000808080808080c0c0c0808080000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080000000 000000000000000000808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080 808080000000808080808080000000808080c0c0c0808080000000ffffffc0c0c0c0c0c0 c0c0c0808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0808080000000808080808080808080808080c0c0c0808080c0c0c0c0c0c0 808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080808080808080 c0c0c0808080000000808080808080c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000808080000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0808080c0c0c0c0c0c0c0c0c0808080808080000000 000000000000808080808080808080c0c0c0c0c0c0808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffffffffc0c0c0808080808080ffffffffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080000000808080808080808080 c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0808080808080808080808080000000808080808080808080000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000808080000000000000000000808080000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080000000000000c0c0c0808080 c0c0c0808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080 000000808080000000c0c0c0808080c0c0c0808080c0c0c0808080808080c0c0c0808080 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080ffffff808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080808080808080808080c0c0c0000000808080808080808080c0c0c0808080 808080808080808080c0c0c0c0c0c0808080000000000000808080808080000000808080 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080000000808080808080808080000000808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080c0c0c0c0c0c0000000000000808080 c0c0c0000000808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0c0c0c0808080808080808080000000808080808080808080 808080000000808080000000808080808080808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 808080000000808080000000808080808080000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000808080808080808080000000808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080 808080808080808080808080808080c0c0c0808080808080000000808080c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 c0c0c0c0c0c0000000808080808080808080808080808080000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000808080000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0808080808080808080c0c0c0 808080808080808080c0c0c0000000000000808080000000808080000000808080808080 808080808080c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080808080808080 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000808080000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080808080c0c0c0c0c0c0808080808080808080808080000000808080 000000000000000000000000000000808080808080808080808080808080808080000000 000000808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0808080c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080000000808080 808080808080808080808080000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 808080000000808080000000808080000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080808080808080808080808080808080808080808080c0c0c0808080808080 000000808080ffffff808080c0c0c0808080ffffffc0c0c0c0c0c0ffffffc0c0c0808080 808080808080808080808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000808080000000000000808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0808080808080c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080 808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff808080c0c0c0808080808080808080808080808080808080 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 808080000000808080000000808080000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 000000808080808080808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0ffffff808080808080808080808080 808080808080808080808080808080808080808080808080c0c0c0808080000000000000 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080000000808080000000808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080c0c0c0c0c0c0808080808080808080808080808080808080808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080 c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0808080808080c0c0c0808080808080808080c0c0c0808080808080808080 808080808080808080c0c0c0808080808080808080808080808080808080808080808080 808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0 808080000000808080808080000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000808080808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080808080808080 808080000000808080808080000000000000808080808080000000000000808080000000 808080808080000000c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0ffffffffffffffffff c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000808080808080c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000808080000000808080808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080000000000000808080808080808080808080808080808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 c0c0c0808080808080808080000000c0c0c0808080808080808080808080c0c0c0808080 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0808080ffffff808080808080c0c0c0 808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffff808080 c0c0c0c0c0c0c0c0c0000000808080c0c0c0808080c0c0c0000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000808080000000808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0808080ffffff808080 c0c0c0808080808080808080808080808080808080808080808080808080c0c0c0808080 c0c0c0c0c0c0c0c0c0808080000000808080808080808080808080808080808080ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffff808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0808080c0c0c0c0c0c0ffffffc0c0c0ffffff808080 808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080c0c0c0808080808080808080808080000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080808080000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0ffffff808080808080808080808080808080808080808080 808080000000000000808080000000000000808080808080808080808080808080808080 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0ffffff808080c0c0c0808080808080c0c0c0c0c0c0ffffffc0c0c0808080 c0c0c0808080ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0c0c0c0808080000000808080 808080808080000000808080808080808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000808080000000000000808080808080808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080000000808080808080808080808080c0c0c0c0c0c0 ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 c0c0c0808080c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffff 808080808080808080808080c0c0c0ffffffffffffc0c0c0c0c0c0808080c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0808080 808080c0c0c0c0c0c0000000c0c0c0808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff808080000000000000808080c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080 808080808080808080808080808080c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff808080 c0c0c0c0c0c0ffffffc0c0c0808080c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0808080808080c0c0c0000000808080808080808080808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080c0c0c0808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0808080808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffff808080ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0ffffffffffffc0c0c0808080 c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0ffffff808080c0c0c0808080ffffffffffffc0c0c0808080 c0c0c0808080000000808080808080000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0000000808080808080000000c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080c0c0c0 c0c0c0808080000000808080000000000000000000c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080c0c0c0808080c0c0c0808080808080808080808080000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080ffffffffffffc0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0808080c0c0c0808080ffffffc0c0c0c0c0c0808080808080808080808080 808080808080808080000000808080000000808080000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffffffff808080 808080808080000000808080808080808080c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0 808080000000808080808080808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080808080c0c0c0 808080808080808080808080000000c0c0c0808080808080808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080000000000000 808080000000c0c0c0c0c0c0c0c0c0000000808080808080808080808080000000c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0808080808080000000808080808080808080808080c0c0c0c0c0c0808080808080 000000808080c0c0c0ffffffffffff808080c0c0c0808080808080c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080808080 c0c0c0808080808080808080808080808080808080000000808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0808080ffffffc0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0808080 000000808080808080000000808080000000000000000000808080808080808080000000 000000000000000000000000000000808080000000c0c0c0808080ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0 808080808080808080808080808080808080808080000000808080808080808080808080 808080c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080ffffffffffffc0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0ffffff808080808080808080c0c0c0 c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0ffffff 000000c0c0c0000000808080808080000000808080000000808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000808080000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080ffffffc0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080808080808080c0c0c0808080808080c0c0c0808080808080808080808080 808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0808080 808080c0c0c0c0c0c0ffffffc0c0c0808080c0c0c0808080ffffffc0c0c0808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080808080000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080c0c0c0808080808080c0c0c0808080c0c0c0 808080808080000000808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080 c0c0c0c0c0c0808080808080808080808080808080000000808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffff c0c0c0ffffff808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0808080ffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffff808080808080808080808080808080808080808080808080808080c0c0c0808080 808080c0c0c0808080000000808080000000000000c0c0c0808080c0c0c0ffffffc0c0c0 c0c0c0808080808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 ffffffffffffffffffc0c0c0808080c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080808080808080808080808080808080808080000000808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080000000000000808080808080000000808080000000808080 c0c0c0808080c0c0c0c0c0c0808080808080808080000000808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080 c0c0c0808080808080808080808080808080808080808080808080808080000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080808080000000000000808080808080808080808080000000808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff000000000000808080808080808080808080808080808080808080808080 808080808080808080808080c0c0c0c0c0c0808080c0c0c0808080808080808080808080 808080808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080c0c0c0c0c0c0 ffffffc0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 808080808080808080808080808080c0c0c0808080808080808080000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0808080000000808080000000000000000000 808080808080808080808080808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080 808080808080808080808080000000000000000000808080808080808080808080c0c0c0 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0808080808080808080808080808080000000808080808080808080808080 808080000000808080808080808080c0c0c0808080c0c0c0c0c0c0808080808080808080 808080808080808080000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0 808080808080c0c0c0808080808080808080808080808080808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0808080 808080c0c0c0c0c0c0000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080000000 c0c0c0808080808080808080c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0ffffff ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000808080808080808080808080000000808080808080 808080808080808080808080808080808080000000808080808080c0c0c0c0c0c0c0c0c0 ffffff808080808080000000000000808080808080808080c0c0c0c0c0c0ffffffc0c0c0 808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0 c0c0c0808080808080808080808080808080808080000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080ffffffffffffffffffffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080c0c0c0ffffffc0c0c0ffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0ffffff808080808080808080808080000000808080808080000000000000 808080808080808080808080808080808080808080808080808080000000808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0808080c0c0c0 808080808080808080808080808080c0c0c0808080808080808080808080c0c0c0000000 808080808080808080808080808080808080000000808080808080000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000808080000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0 ffffffffffff808080808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 808080000000808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000808080000000808080808080 808080808080000000000000000000808080808080808080808080808080808080808080 808080c0c0c0808080ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080c0c0c0 000000808080000000808080808080808080808080808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080 808080808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff ffffffffffffffffffffffff808080808080808080808080808080000000000000808080 000000808080808080808080808080808080000000000000808080808080808080808080 808080808080000000000000808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080 c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0000000808080808080 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000808080000000000000000000000000000000 808080000000000000000000000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000808080000000c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0808080808080808080000000000000808080000000 808080808080808080808080000000000000000000000000000000000000808080808080 808080808080808080c0c0c0808080000000808080808080808080808080808080ffffff c0c0c0808080808080808080808080c0c0c0808080808080808080c0c0c0808080808080 808080808080808080808080c0c0c0000000808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080000000000000808080c0c0c0808080c0c0c0c0c0c0 ffffffc0c0c0808080c0c0c0c0c0c0ffffffc0c0c0ffffffffffff808080808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0ffffffffffff ffffffffffffffffffffffffffffff808080808080808080808080000000000000000000 000000000000000000000000808080808080000000808080000000000000000000000000 000000808080808080808080808080c0c0c0808080808080808080000000808080808080 808080c0c0c0c0c0c0808080808080808080808080808080808080808080c0c0c0808080 808080808080808080c0c0c0000000808080808080000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0 808080808080000000808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0ffffffffffffffffff808080808080000000808080808080000000000000 000000000000000000000000000000808080808080808080808080808080808080000000 808080808080000000808080808080808080808080808080808080808080000000808080 808080808080c0c0c0808080808080808080808080c0c0c0808080808080c0c0c0808080 808080808080808080000000808080000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080 808080000000808080808080000000808080808080808080808080808080000000000000 000000000000000000808080808080808080808080c0c0c0808080c0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffffffffffffffc0c0c0c0c0c0ffffff808080808080000000808080000000000000 000000000000808080c0c0c0808080808080808080808080808080808080808080808080 808080808080000000000000000000808080808080c0c0c0000000808080c0c0c0000000 808080000000808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffffffffc0c0c0c0c0c0ffffff808080808080000000808080000000000000 000000808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080c0c0c0808080 808080808080808080808080808080808080808080808080000000808080808080808080 808080808080808080808080000000808080000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff c0c0c0808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffff ffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0 ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0808080000000808080000000808080 808080808080808080808080808080c0c0c0808080808080808080808080808080808080 000000000000808080808080808080c0c0c0c0c0c0808080808080808080808080808080 c0c0c0808080808080808080808080808080808080808080808080c0c0c0808080808080 000000000000808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffffffffffffffc0c0c0ffffffc0c0c0808080000000808080808080000000 808080808080808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0 808080808080000000000000000000000000808080808080808080808080808080808080 000000808080808080808080000000808080808080000000808080808080808080808080 808080808080000000808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffff c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080000000808080808080000000000000808080000000000000000000808080 000000000000808080000000808080808080808080808080000000808080808080808080 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffff808080c0c0c0808080000000ffffff ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0808080808080808080808080808080808080000000000000000000 808080000000808080000000808080000000808080000000000000808080808080808080 808080808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff ffffffffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080 808080c0c0c0808080c0c0c0808080808080808080808080808080808080000000808080 000000808080000000808080000000808080000000808080000000808080808080808080 808080000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0808080808080808080808080000000808080 808080808080808080808080000000808080ffffff808080808080808080808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0000000808080808080808080 808080000000808080000000000000000000808080808080808080808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080 808080808080808080808080808080808080808080808080808080808080808080808080 000000808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080808080 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0ffffffc0c0c0808080808080c0c0c0808080808080808080 c0c0c0000000ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0808080808080c0c0c0c0c0c0ffffffc0c0c0808080808080808080 808080808080808080808080808080808080000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080ffffff808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff000000 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080000000808080808080000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080c0c0c0c0c0c0ffffffc0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffff808080c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0000000808080c0c0c0808080808080808080000000808080000000808080 808080000000808080000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffff808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080808080 808080c0c0c0808080c0c0c0808080808080c0c0c0808080808080808080808080c0c0c0 808080808080808080808080808080000000808080808080808080808080808080808080 000000000000808080808080000000808080000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffff c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffff808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0 c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080808080 c0c0c0808080c0c0c0808080808080c0c0c0808080808080808080808080808080808080 c0c0c0808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000808080000000000000000000000000000000c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffff c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0808080000000808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0808080c0c0c0808080c0c0c0 808080808080808080c0c0c0808080808080c0c0c0808080808080808080808080808080 808080000000808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000808080ffffff c0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff ffffffc0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0 c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffffffffc0c0c0ffffff000000808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080808080808080808080808080000000808080c0c0c0808080808080808080 808080000000808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0 c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 ffffffc0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080c0c0c0 c0c0c0808080808080c0c0c0c0c0c0808080808080808080808080808080808080808080 000000808080000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffc0c0c0808080 c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0808080808080 808080808080c0c0c0808080808080808080808080808080808080808080808080000000 808080808080808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0 808080c0c0c0808080c0c0c0808080808080808080808080808080000000808080c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080c0c0c0ffffffc0c0c0c0c0c0 c0c0c0808080c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080808080808080c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080808080808080808080808080808080808080000000808080808080 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000ffffffffffffffffffffffffc0c0c0 c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff 808080808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080808080808080808080ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0808080c0c0c0 808080808080808080c0c0c0000000808080808080808080808080808080808080808080 808080808080000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffffffffc0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffff000000808080808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0808080000000c0c0c0808080 808080808080808080000000808080808080808080808080000000000000808080000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffff ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080808080808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0 808080c0c0c0808080808080c0c0c0c0c0c0808080808080c0c0c0808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000000000000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0ffffffffffffffffff c0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffff ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080808080808080808080808080808080808080c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080 808080c0c0c0808080c0c0c0808080808080808080808080808080808080808080c0c0c0 808080808080808080808080808080808080808080000000808080808080808080000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0 ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffff ffffff000000808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080808080808080c0c0c0 808080808080808080000000000000000000000000000000000000808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff 808080808080808080808080808080808080808080808080ffffffc0c0c0808080c0c0c0 808080c0c0c0808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080c0c0c0808080c0c0c0808080808080808080 808080808080000000808080808080808080000000808080808080000000000000000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000808080808080808080808080808080808080ffffffc0c0c0c0c0c0c0c0c0808080 c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080808080000000808080808080 808080808080808080c0c0c0808080808080000000808080808080000000808080808080 808080000000808080808080808080808080808080808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffff000000 808080808080808080808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080 808080808080808080808080808080808080c0c0c0808080808080808080808080808080 808080808080808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080 808080808080808080808080808080808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0808080808080c0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff ffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffff808080808080808080 808080808080c0c0c0808080808080000000c0c0c0c0c0c0c0c0c0c0c0c0808080808080 c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080c0c0c0808080808080808080808080808080808080808080808080 808080808080c0c0c0808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000c0c0c0 ffffffc0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0808080808080808080 808080808080808080808080808080000000ffffffc0c0c0808080808080c0c0c0808080 808080808080808080808080808080c0c0c0808080808080808080808080808080808080 808080808080808080000000808080808080808080000000808080000000808080808080 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffff c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffc0c0c0ffffffffffffffffffffffff808080808080c0c0c0808080 808080808080808080808080808080000000ffffff808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0808080000000808080808080808080808080808080808080808080 808080808080808080000000808080808080808080808080808080808080c0c0c0c0c0c0 808080808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0808080 808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffff ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff808080808080808080808080c0c0c0 808080808080808080808080808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0808080808080c0c0c0808080 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080000000808080808080808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffffffffff c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff ffffffffffffc0c0c0ffffffffffffc0c0c0808080808080808080808080808080808080 c0c0c0c0c0c0808080808080808080000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080000000000000808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0 ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffff ffffffffffffc0c0c0ffffffc0c0c0c0c0c0000000808080808080808080808080808080 808080c0c0c0808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000000000 000000808080808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000c0c0c0c0c0c0ffffffc0c0c0c0c0c0 808080c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000808080808080808080808080808080808080 808080808080808080808080000000808080808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080000000000000000000808080 808080c0c0c0808080000000808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000ffffffffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffff c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffff808080808080808080808080808080808080808080808080 808080808080808080000000808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080000000000000000000000000808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ffffffff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000808080808080808080808080808080808080 808080808080808080000000808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080 808080808080000000000000000000000000808080808080c0c0c0808080808080808080 808080000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffff000000808080808080808080808080808080808080808080808080 808080000000000000000000808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080000000808080808080808080000000 808080808080808080808080808080808080808080808080808080808080000000000000 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0ffffff808080808080808080808080808080808080808080808080808080808080 000000000000000000808080808080808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080000000000000000000808080808080 808080808080808080000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0808080000000808080808080808080808080808080808080808080808080000000 000000000000808080808080808080808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080 808080808080c0c0c0c0c0c0808080000000000000808080000000c0c0c0808080808080 808080808080000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080808080000000000000 000000808080808080808080808080c0c0c0808080c0c0c0808080808080808080808080 c0c0c0c0c0c0808080808080c0c0c0808080808080c0c0c0808080808080808080c0c0c0 808080808080808080000000808080808080808080808080808080808080808080c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0ffffff000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0 ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0ffffffffffff 808080000000808080808080808080808080808080808080808080808080000000000000 000000808080808080808080808080808080808080808080808080c0c0c0808080808080 808080808080c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000ffffffc0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffff ffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffff ffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffff808080 808080808080808080808080808080808080808080808080808080000000000000000000 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 808080808080808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080808080808080 808080808080808080000000808080c0c0c0808080808080808080000000808080808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffff c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffff808080808080 808080808080808080808080808080808080808080000000808080000000000000808080 808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 808080808080808080000000000000808080808080808080c0c0c0808080808080808080 808080808080c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffffffffffffffc0c0c0ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000 808080808080000000808080808080808080000000000000000000000000808080808080 808080808080808080808080c0c0c0c0c0c0808080c0c0c0808080808080808080808080 808080808080808080808080000000000000000000808080c0c0c0c0c0c0c0c0c0808080 808080c0c0c0808080808080808080808080c0c0c0808080808080808080808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff808080000000000000000000 000000808080808080808080808080808080808080000000000000000000808080808080 808080808080808080c0c0c0808080808080c0c0c0808080808080808080808080808080 808080808080000000000000000000000000000000000000808080808080808080808080 808080c0c0c0c0c0c0808080c0c0c0808080808080000000808080808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000808080000000808080 000000808080808080808080000000000000000000000000000000808080808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080808080000000000000000000000000808080c0c0c0ffffff808080000000 000000000000000000808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 808080808080808080808080808080808080808080808080808080808080808080c0c0c0 808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000808080000000000000000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffffffff808080808080000000808080000000000000000000 000000000000000000000000000000000000000000000000808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 000000000000000000808080000000000000000000ffffffc0c0c0ffffff000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0 808080808080000000000000000000000000808080808080000000808080808080808080 808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffff c0c0c0ffffffffffffffffffc0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080c0c0c0 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080000000000000000000000000c0c0c0c0c0c0ffffff808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffff ffffffc0c0c0ffffffffffffffffffffffffc0c0c0ffffffffffffffffffffffffc0c0c0 ffffff808080000000000000000000000000000000000000000000000000000000808080 808080000000000000000000000000000000000000808080808080808080808080808080 808080808080c0c0c0c0c0c0808080808080808080808080808080808080808080808080 808080000000000000000000000000000000ffffffffffffc0c0c0000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080ffffffffffffc0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0 000000808080808080808080808080808080000000808080000000000000000000000000 000000000000000000000000000000000000000000808080808080808080808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080808080808080808080 808080000000000000000000000000c0c0c0c0c0c0ffffff000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0ffffff c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0ffffff808080 808080c0c0c0808080808080808080808080000000000000808080000000000000000000 000000000000000000000000000000000000808080808080808080808080808080808080 808080c0c0c0808080c0c0c0808080808080808080808080808080808080808080000000 000000000000000000000000000000ffffffc0c0c0c0c0c0000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0 c0c0c0ffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff808080000000 808080808080808080808080c0c0c0808080808080808080000000808080808080000000 000000000000000000000000000000000000808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080000000808080 000000000000000000000000ffffffc0c0c0c0c0c0000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffc0c0c0 ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffffffffffffffc0c0c0ffffffffffffffffff808080808080c0c0c0808080808080 808080808080808080c0c0c0c0c0c0808080000000808080000000808080808080000000 000000000000000000000000000000000000808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080000000 000000000000000000808080c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffc0c0c0 ffffffffffffffffffc0c0c0c0c0c0ffffffffffff808080808080808080000000000000 808080808080808080c0c0c0808080808080000000000000000000808080808080000000 808080808080808080000000000000000000808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080000000000000 000000000000000000ffffffc0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffff c0c0c0ffffffffffffffffffc0c0c0ffffffffffffffffffc0c0c0808080808080000000 808080808080c0c0c0000000000000808080000000000000000000000000000000000000 000000000000000000000000000000808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000ffffffffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0ffffffffffffffffff ffffffffffffffffffffffffc0c0c0ffffffc0c0c0c0c0c0ffffff808080808080000000 808080c0c0c0000000000000000000000000000000000000808080808080000000000000 808080000000000000000000000000808080808080808080808080808080808080808080 c0c0c0808080808080808080808080808080000000000000000000000000000000808080 000000808080c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffffffffffc0c0c0 ffffffffffffffffffffffffc0c0c0c0c0c0ffffffffffff808080808080808080808080 c0c0c0808080808080000000000000000000000000000000000000000000808080000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080808080808080808080808080808080000000000000000000000000000000000000 000000ffffffc0c0c0c0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000000000000000ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0ffffffffffffc0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffff ffffffffffffc0c0c0c0c0c0ffffffffffffffffffffffff808080808080808080808080 808080000000808080000000000000808080808080000000808080808080808080000000 000000000000000000000000000000808080808080808080808080808080808080808080 808080808080808080808080000000000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0ffffffc0c0c0ffffffc0c0c0000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffc0c0c0c0c0c0c0c0c0ffffffffffffffffff808080808080808080c0c0c0 000000808080000000000000000000000000000000808080000000808080808080000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080808080000000000000000000000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080000000000000000000000000000000000000000000000000000000000000808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffff c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080808080 000000000000000000000000000000808080000000808080808080808080000000000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080000000808080000000000000000000000000000000000000000000808080c0c0c0 c0c0c0c0c0c0ffffff000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000 000000000000808080000000000000000000808080808080000000808080000000000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080000000000000000000000000000000000000000000000000808080c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080808080808080808080000000 808080000000000000000000808080808080808080808080808080808080000000000000 000000000000000000808080808080808080808080808080808080808080808080808080 000000000000000000808080000000000000808080000000808080c0c0c0c0c0c0c0c0c0 ffffff808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffffffffffffffff808080808080808080808080808080 808080000000000000000000000000000000000000808080808080000000000000000000 000000000000000000808080808080808080808080808080808080808080808080808080 000000000000000000000000000000808080000000808080c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffff808080808080000000c0c0c0808080 000000808080808080808080000000000000808080000000000000000000000000000000 000000808080808080808080808080808080808080808080808080808080808080000000 000000000000000000000000000000000000808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff808080808080808080c0c0c0808080808080 c0c0c0808080808080808080808080808080808080000000000000000000808080000000 000000000000808080808080808080808080808080808080808080808080000000000000 000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0ffffff c0c0c0ffffffffffffffffffffffffc0c0c0808080808080c0c0c0c0c0c0c0c0c0808080 c0c0c0808080808080808080808080808080808080000000000000000000000000000000 000000000000000000808080808080808080808080808080808080000000000000000000 000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080ffffffc0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffffffffc0c0c0ffffffffffff ffffffffffffffffffffffffffffffffffff808080c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0808080808080808080808080000000808080000000000000000000000000 000000808080808080808080808080808080000000000000808080000000000000000000 000000000000000000808080ffffffc0c0c0c0c0c0c0c0c0ffffff000000808080808080 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffc0c0c0 ffffffffffffc0c0c0ffffffc0c0c0808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0ffffff808080808080808080000000000000000000000000000000000000 000000808080808080808080808080808080808080808080000000000000000000000000 000000000000808080ffffffffffffc0c0c0c0c0c0c0c0c0808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080ffffffc0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffffffffc0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000808080000000808080000000000000000000000000808080 000000808080808080808080808080808080808080808080000000808080000000000000 000000808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000000000000000808080000000000000000000000000 808080808080000000808080000000000000000000000000000000000000000000000000 808080c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffff ffffffc0c0c0c0c0c0ffffff808080c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0808080808080000000000000808080000000000000000000000000000000 808080000000808080000000000000000000808080000000000000000000000000808080 ffffffc0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffffc0c0c0ffffff c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080808080808080 808080c0c0c0808080808080000000808080808080000000808080000000000000000000 808080808080808080000000000000000000000000000000000000000000808080ffffff c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffff808080808080808080c0c0c0808080808080808080c0c0c0c0c0c0 808080808080808080000000000000000000808080000000000000000000000000808080 808080808080808080000000000000000000000000000000000000808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0808080808080808080000000000000000000000000000000808080000000808080 808080808080000000000000000000000000000000000000808080c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0ffffff808080808080808080808080808080000000000000808080808080808080 808080808080808080808080808080000000000000000000000000000000808080000000 000000000000000000000000808080000000000000c0c0c0ffffffc0c0c0c0c0c0ffffff ffffffffffffffffffc0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0ffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0ffffff c0c0c0ffffff808080808080808080808080808080808080808080000000808080808080 808080808080000000000000000000000000000000808080000000000000808080000000 000000000000000000808080000000000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff c0c0c0c0c0c0808080c0c0c0808080808080808080000000000000808080000000808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0ffffff000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080000000000000000000000000000000000000000000 000000000000000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080808080808080000000808080 000000000000000000808080000000000000808080808080000000000000808080000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080808080000000808080 000000808080000000000000808080000000000000000000808080000000000000808080 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080808080808080808080 808080808080000000000000000000000000000000808080000000808080000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080808080c0c0c0808080808080 808080808080808080000000808080000000000000000000000000000000000000000000 000000c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080000000808080000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0808080c0c0c0808080 808080808080808080808080000000000000000000000000808080000000808080000000 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffc0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080808080808080 c0c0c0808080808080000000808080000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080000000000000000000000000c0c0c0 c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0808080808080 808080808080808080808080000000000000000000000000000000808080c0c0c0c0c0c0 c0c0c0c0c0c0ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffff808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0808080c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0ffffffc0c0c0 c0c0c0c0c0c0c0c0c0ffffff808080808080808080808080808080808080808080808080 808080808080808080000000808080000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000ffffff808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080808080000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080808080808080 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080808080808080 808080808080808080000000808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080c0c0c0808080c0c0c0 808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080808080808080 808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000000000 000000000000000000808080000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080808080 808080808080808080000000000000000000000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000808080808080c0c0c0808080 808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0 808080808080808080c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080808080808080 808080c0c0c0000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080808080808080808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0808080808080 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0 808080808080808080808080c0c0c0000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080808080808080808080808080 808080808080000000000000808080000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000 000000000000000000000000000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000808080808080808080808080c0c0c0 808080808080808080c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0808080808080 808080808080808080808080808080c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080 c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0808080c0c0c0808080 808080c0c0c0808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080000000000000000000000000000000000000808080 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080000000000000808080808080808080 808080000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080808080808080808080808080 808080808080808080808080c0c0c0808080808080808080808080808080c0c0c0808080 c0c0c0c0c0c0808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080 c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080c0c0c0 808080c0c0c0808080808080c0c0c0808080808080c0c0c0808080808080808080808080 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080000000000000000000000000000000000000000000 c0c0c0c0c0c0000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000808080808080808080808080000000000000000000 000000000000000000000000000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080000000000000000000000000000000 000000000000000000000000808080000000000000808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000808080808080808080c0c0c0c0c0c0808080 808080808080808080808080808080808080c0c0c0808080808080808080808080808080 808080808080808080c0c0c0808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0808080c0c0c0808080808080c0c0c0000000c0c0c0c0c0c0808080 808080808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080808080808080c0c0c0 808080808080808080808080808080808080808080000000808080808080808080c0c0c0 808080c0c0c0808080c0c0c0808080c0c0c0000000808080808080808080808080808080 808080c0c0c0808080808080808080808080808080c0c0c0808080808080808080808080 808080808080808080000000808080000000000000000000000000000000000000000000 c0c0c0808080808080000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080808080808080808080000000000000000000000000 000000000000000000000000000000808080c0c0c0808080808080000000000000808080 c0c0c0c0c0c0808080808080c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080c0c0c0808080 808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0 c0c0c0c0c0c0808080808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080808080c0c0c0808080 808080c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0808080 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080000000000000000000000000000000000000 808080808080c0c0c0000000000000000000c0c0c0808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0 c0c0c0c0c0c0808080808080808080808080808080808080000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080c0c0c0808080000000000000000000000000000000000000000000 000000000000000000000000808080808080000000000000000000000000000000000000 000000808080000000808080000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080808080808080808080808080000000 808080808080808080808080808080808080808080808080808080c0c0c0808080c0c0c0 808080808080808080808080c0c0c0808080808080808080808080808080c0c0c0808080 808080808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080808080 808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080 808080808080808080808080808080808080000000000000000000000000000000000000 808080c0c0c0808080808080808080000000808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080808080000000000000000000000000000000000000000000000000 000000000000808080808080c0c0c0808080000000000000000000000000000000000000 000000000000000000808080000000808080000000000000000000000000000000000000 000000000000000000808080808080808080808080808080c0c0c0808080808080808080 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0808080 808080c0c0c0808080c0c0c0808080808080808080808080808080808080808080c0c0c0 808080808080c0c0c0808080808080808080808080808080808080808080c0c0c0c0c0c0 808080c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0808080808080808080808080 808080c0c0c0808080808080808080808080c0c0c0808080808080808080808080808080 808080c0c0c0808080808080808080808080808080c0c0c0808080000000000000000000 000000000000808080808080000000000000808080c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080808080c0c0c0808080c0c0c0808080000000808080000000808080000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000808080808080808080000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000808080000000808080808080808080808080808080808080c0c0c0c0c0c0808080 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 808080c0c0c0808080808080c0c0c0808080c0c0c0808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080c0c0c0808080808080 808080c0c0c0808080c0c0c0c0c0c0808080808080808080c0c0c0808080808080808080 808080808080808080808080808080808080c0c0c0808080808080808080c0c0c0c0c0c0 808080808080808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080 808080808080808080808080808080808080808080808080808080808080000000000000 000000808080000000000000808080c0c0c0808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000c0c0c0808080c0c0c0808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080000000000000000000000000000000000000000000000000000000000000 000000000000808080c0c0c0000000000000000000000000000000000000000000000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 c0c0c0808080808080808080c0c0c0808080808080808080808080c0c0c0c0c0c0808080 c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080c0c0c0 808080c0c0c0808080808080808080c0c0c0c0c0c0808080808080808080808080c0c0c0 c0c0c0808080808080808080c0c0c0808080808080808080808080808080c0c0c0c0c0c0 808080808080808080808080808080c0c0c0808080c0c0c0808080808080c0c0c0808080 808080808080808080c0c0c0c0c0c0808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080c0c0c0 808080808080c0c0c0808080808080808080808080808080808080808080000000000000 000000808080808080808080000000808080808080808080c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0808080 000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000808080c0c0c0000000000000000000000000000000000000000000000000000000 000000000000808080000000808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080c0c0c0808080808080808080808080c0c0c0808080808080808080808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080 808080808080c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0808080c0c0c0 808080808080808080c0c0c0808080c0c0c0808080808080c0c0c0808080808080c0c0c0 808080808080808080808080808080808080808080808080c0c0c0808080808080808080 808080c0c0c0808080808080808080c0c0c0808080808080808080808080808080808080 c0c0c0808080808080808080808080808080c0c0c0808080808080808080808080808080 c0c0c0c0c0c0808080808080808080808080808080808080808080808080000000000000 000000808080c0c0c0808080808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 000000c0c0c0808080c0c0c0000000808080000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080808080808080000000000000000000000000000000000000000000000000000000 808080000000808080000000808080000000808080808080808080808080808080808080 808080808080808080808080808080c0c0c0808080808080808080808080c0c0c0808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080808080808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0c0c0c0808080808080808080 808080808080808080808080808080808080c0c0c0808080808080808080808080c0c0c0 808080808080c0c0c0808080808080808080808080808080c0c0c0808080808080808080 808080808080808080808080808080808080808080c0c0c0808080c0c0c0808080808080 c0c0c0808080c0c0c0808080808080808080808080808080808080000000808080000000 000000000000000000808080808080808080808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 808080c0c0c0000000000000000000000000000000000000000000808080000000000000 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0808080808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080 808080c0c0c0808080c0c0c0808080808080808080808080808080808080c0c0c0c0c0c0 808080808080808080808080c0c0c0808080808080808080808080c0c0c0808080808080 808080c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080808080808080c0c0c0808080c0c0c0808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080c0c0c0808080 c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080808080808080000000 000000000000000000000000808080808080808080000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000808080 c0c0c0000000000000000000000000000000000000000000000000808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080808080 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0808080808080808080808080808080c0c0c0c0c0c0808080c0c0c0808080808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 000000000000808080808080808080000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 000000808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080808080808080 808080000000000000000000000000000000000000808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 000000808080808080000000808080808080808080808080808080808080000000808080 808080808080c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 808080808080808080808080808080c0c0c0808080808080c0c0c0808080808080808080 808080808080808080c0c0c0808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080c0c0c0808080808080808080 808080808080808080808080808080808080000000808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 000000000000808080000000000000000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000000000000000000000000000000000000000808080000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080000000000000808080808080808080808080 000000000000000000000000000000000000000000000000000000808080808080000000 000000000000808080808080808080808080808080808080808080808080808080808080 c0c0c0808080808080808080808080808080808080c0c0c0808080808080c0c0c0808080 c0c0c0808080808080c0c0c0808080c0c0c0808080808080808080808080808080808080 808080808080808080c0c0c0808080808080808080c0c0c0808080808080808080808080 808080808080808080808080808080808080c0c0c0808080808080808080808080808080 808080c0c0c0808080808080c0c0c0808080808080808080808080808080808080808080 808080808080c0c0c0808080808080808080c0c0c0808080808080c0c0c0808080808080 808080808080808080c0c0c0808080808080808080808080808080808080808080808080 808080c0c0c0808080c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080 000000000000000000000000000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000808080808080808080000000 000000000000000000000000000000000000000000808080808080808080808080808080 808080808080c0c0c0808080808080808080808080808080c0c0c0c0c0c0808080808080 808080808080808080808080808080808080808080808080c0c0c0808080808080c0c0c0 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080 c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080808080 808080808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080808080 c0c0c0808080808080808080808080808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080808080808080c0c0c0c0c0c0808080808080808080 808080808080808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080808080 808080808080c0c0c0808080808080808080808080808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 000000000000000000808080808080000000000000808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080808080000000000000000000000000000000000000000000808080000000000000 000000000000000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000808080808080808080000000000000 000000000000000000000000000000808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080c0c0c0 808080808080808080808080808080808080808080808080808080808080c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080808080808080 808080808080808080808080c0c0c0808080c0c0c0808080808080c0c0c0808080808080 c0c0c0c0c0c0808080c0c0c0808080808080808080808080c0c0c0c0c0c0808080c0c0c0 c0c0c0808080808080808080808080c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0808080 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 808080000000808080000000000000000000000000000000c0c0c0808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000808080808080000000808080c0c0c0000000000000000000 000000000000000000000000808080808080808080808080c0c0c0808080c0c0c0808080 808080808080808080808080808080808080808080c0c0c0808080808080c0c0c0808080 c0c0c0c0c0c0808080808080808080808080808080c0c0c0c0c0c0c0c0c0808080808080 808080808080c0c0c0808080808080808080808080c0c0c0808080808080808080808080 808080c0c0c0808080808080808080808080808080808080c0c0c0808080808080c0c0c0 c0c0c0c0c0c0808080808080c0c0c0808080808080808080808080808080808080808080 808080808080c0c0c0808080808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0808080 808080c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0808080808080 808080c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080 808080000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080 808080808080808080000000000000000000000000000000000000000000000000000000 000000000000000000000000000000808080808080000000808080808080000000000000 000000000000000000000000808080808080808080808080808080808080808080808080 808080c0c0c0808080808080808080808080808080808080c0c0c0808080808080c0c0c0 c0c0c0808080808080c0c0c0808080c0c0c0808080808080808080808080808080808080 808080808080808080808080808080808080c0c0c0808080808080c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080c0c0c0808080c0c0c0808080 808080808080c0c0c0808080808080c0c0c0808080808080c0c0c0808080c0c0c0808080 808080c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080808080808080808080808080c0c0c0808080808080c0c0c0c0c0c0808080 c0c0c0808080c0c0c0808080c0c0c0808080808080808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080000000000000000000000000808080808080000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000808080000000c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0808080808080808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000808080808080000000000000000000 000000000000000000808080808080808080808080808080c0c0c0c0c0c0808080808080 c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0808080808080808080808080 808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080 c0c0c0c0c0c0808080c0c0c0808080c0c0c0808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0808080 c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0 c0c0c0808080808080808080808080000000808080808080808080808080c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000808080808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000000000808080c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000808080000000000000 000000000000808080808080808080808080808080c0c0c0808080808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0 808080808080808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 808080808080808080808080808080808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000000000000000808080808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000 000000808080000000000000000000000000000000000000808080808080000000808080 000000808080808080808080808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0 808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0808080c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0808080808080 808080c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 ffffffc0c0c0c0c0c0c0c0c0000000000000000000000000808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000000000 000000000000000000000000000000000000808080000000808080000000808080000000 808080808080808080c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0808080c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0808080000000000000000000000000000000 000000000000000000000000000000000000000000808080000000000000000000808080 808080808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0 808080808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0808080808080808080000000808080808080000000000000 000000000000000000000000000000000000808080000000000000000000000000808080 808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000808080808080808080808080 000000000000000000808080808080c0c0c0808080000000000000000000808080808080 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080808080808080c0c0c0 808080000000808080808080000000000000000000000000000000808080808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080808080808080c0c0c0 c0c0c0000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080808080c0c0c0c0c0c0808080c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000000000000000000000 000000000000000000000000000000000000808080808080808080808080c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 c0c0c0c0c0c0808080c0c0c0808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0 808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080 c0c0c0808080808080808080808080808080808080c0c0c0808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080000000000000 000000808080808080000000808080000000808080000000808080000000808080000000 000000000000808080000000808080808080000000808080808080808080808080808080 808080808080808080808080000000808080808080808080808080808080808080808080 808080808080000000808080808080808080808080000000808080808080808080000000 808080808080000000000000000000000000808080000000000000000000000000000000 000000000000000000000000000000000000000000000000000000ffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffff0000ffffffff0000ffffffffffffff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffffffffffffffff 0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ffffffff0000ff0000ffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffff0000ffffffff0000ff0000ffffffffffffffffffff ffffff0000ff0000ff0000ff0000ffffffffffffff0000ffffffff0000ff0000ffffffff ffffffffffff0000ffffffff0000ffffffffffffff0000ff0000ff0000ff0000ffffffff ffffff0000ff0000ff0000ffffffff0000ffffffff0000ffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffff0000ffffffff0000ff0000ffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffff ffffffffffff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff 0000ffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffff0000ff0000ff0000ffffffff0000ffffffffffffffffffff0000ff 0000ff0000ff0000ffffffffffffffffffff0000ffffffff0000ff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff0000ff 0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff ffffffffffff0000ff0000ff0000ffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffff0000ff0000ffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffff0000ff0000ffffffffffffff0000ff ffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffff0000ff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff 0000ffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffff ffffffffffffffffff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff ffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ff0000ffffffffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffff0000ffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffff0000ff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffff0000ffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff0000ffffffff 0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffffffffffffffff 0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffff0000ffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffff ffffffffffffffffff0000ffffffff0000ffffffffffffffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ff0000ff0000ff0000ffffffff0000ffffffffffffff0000ff0000ff 0000ffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff 0000ffffffff0000ffffffffffffff0000ffffffff0000ffffffffffffffffffff0000ff 0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffff0000ff0000ff0000ff0000ffffffff0000ffffffffffffff0000ff0000ff0000ff 0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffff0000ffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffff ffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffff0000ffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ffffffff0000ff 0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffff ffffffffffff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffffffffffffffff 0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffffffffff 0000ffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffff ffffff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff 0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffff ffffffffffff0000ffffffff0000ff0000ffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ff0000ff0000ff0000ffffffffffffffffffff0000ffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffff0000ffffffffffffffffffffffffffffffff 0000ffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ff0000ffffffff0000ffffffffffffffffffffffffffffffff0000ff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff0000ffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffff ffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffff0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff 0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff 0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff 0000ff0000ff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ff ffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffff ffffff0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff ffffffffffff0000ffffffff0000ffffffffffffffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffffff 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffff0000ffffffff0000ffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffffffffffffffff0000ffffffff0000ffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffffffffff0000ff ffffffffffffffffffffffff0000ffffffffffffffffffff0000ffffffff0000ffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff 0000ffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffff0000ffffffffffffffffffffffffff0000ffffffff0000ffffffffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff0000ffffffff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff0000ff 0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffff0000ff ffffffffffff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffffffffffffffff 0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffff ffffff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffff 0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffff ffffffffffff0000ff0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff ffffffffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff 0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffff ffffff0000ffffffff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffffffffffffffff0000ffffffff0000ff0000ffffffffffffffffffffffffff0000ff 0000ff0000ffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ffffffff ffffffffffffffffffffffff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffffffffffffffff 0000ffffffff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffff0000ffffffffffffffffffffffffffffffff0000ffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffff ffffff0000ff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffff ffffffffffffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ff0000ffffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ff0000ff 0000ff0000ff0000ff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ff0000ff0000ff0000ff 0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff ffffffffffffffffffffffff0000ffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffff0000ffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff ffffff0000ffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffff ffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffffffffff0000ffffffff0000ffffffffffffffffffff0000ffffffff ffffffffffffffffff0000ffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffff ffffff0000ff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffffffffff ffffffffffff0000ffffffffffffff0000ffffffffffffffffffff0000ff0000ffffffff ffffffffffffffffffffffff0000ff0000ffffffffffffffffffff0000ffffffffffffff ffffff0000ffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff 0000ffffffffffffff0000ffffffffffffffffffff0000ffffffffffffff0000ffffffff ffffffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffff0000ffffffffffffffffffff ffffff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffffffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff 0000ff0000ff0000ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff0000ff 0000ff0000ff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffff ffffff0000ffffffff0000ff0000ff0000ffffffffffffffffffffffffff0000ff0000ff 0000ff0000ffffffffffffffffffffffffff0000ff0000ff0000ffffffff0000ffffffff ffffffffffffffffffffffff0000ffffffff0000ff0000ff0000ffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff ffffff0000ffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff0000ff 0000ff0000ffffffff0000ffffffffffffffffffff0000ff0000ff0000ff0000ffffffff ffffffffffffffffffffffffffffffffffff0000ffffffffffffff0000ff0000ff0000ff 0000ffffffffffffffffffffffffff0000ff0000ff0000ff0000ffffffff0000ffffffff 0000ffffffffffffffffffff0000ffffffffffffffffffff0000ffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff ffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ff 0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 808080000000ffffff c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080000000ffffff showpage % stop using temporary dictionary end % restore original state origstate restore %%Trailer tango-9.2.5a/doc/src/ds_writing/nt_server/help.ps0000644023471100065110000224712113034745264016757 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: /mntdirect/_segfs/tango/doc/manual/programmer/nt_server/help.ps %%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley %%BoundingBox: 9 269 396 527 %%Pages: 1 %%DocumentFonts: %%EndComments %%EndProlog %%Page: 1 1 % remember original state /origstate save def % build a temporary dictionary 20 dict begin % define string to hold a scanline's worth of data /pix 1161 string def % define space for color conversions /grays 387 string def % space for gray scale line /npixls 0 def /rgbindx 0 def % lower left corner 9 269 translate % size of image (on paper, in 1/72inch coords) 387.00000 257.97600 scale % define 'colorimage' if it isn't defined % ('colortogray' and 'mergeprocs' come from xwd2ps % via xgrab) /colorimage where % do we know about 'colorimage'? { pop } % yes: pop off the 'dict' returned { % no: define one /colortogray { % define an RGB->I function /rgbdata exch store % call input 'rgbdata' rgbdata length 3 idiv /npixls exch store /rgbindx 0 store 0 1 npixls 1 sub { grays exch rgbdata rgbindx get 20 mul % Red rgbdata rgbindx 1 add get 32 mul % Green rgbdata rgbindx 2 add get 12 mul % Blue add add 64 idiv % I = .5G + .31R + .18B put /rgbindx rgbindx 3 add store } for grays 0 npixls getinterval } bind def % Utility procedure for colorimage operator. % This procedure takes two procedures off the % stack and merges them into a single procedure. /mergeprocs { % def dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def /colorimage { % def pop pop % remove 'false 3' operands {colortogray} mergeprocs image } bind def } ifelse % end of 'false' case 387 258 8 % dimensions of data [387 0 0 -258 0 258] % mapping matrix {currentfile pix readhexstring pop} false 3 colorimage c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0 c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffff808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000 ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000 000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffff0000ffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ffffffff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffffffff ff0000ff0000ffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ffffffffffffffffffff0000 ff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ff0000 ffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffff0000 ff0000ff0000ff0000ff0000ffffffffffffff0000ff0000ff0000ff0000ff0000ffffff ffffffffffffffffffffffffffffffff0000ff0000ff0000ff0000ff0000ff0000ffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000 000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000000000000000c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0000000 c0c0c0c0c0c0000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000000000000000 c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0000000000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0c0c0c0000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0000000000000000000000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0000000000000000000c0c0c0000000 c0c0c0000000c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000000000000000 c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000 000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0 c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000000000000000000000 c0c0c0c0c0c0c0c0c0000000000000c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0000000 000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0 c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0000000c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000000000000000 c0c0c0000000c0c0c0c0c0c0000000000000000000c0c0c0000000c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0000000c0c0c0c0c0c0000000 c0c0c0000000c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000000000c0c0c0 000000c0c0c0c0c0c0000000000000000000000000c0c0c0c0c0c0000000c0c0c0c0c0c0 000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000 000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0000000000000000000 000000000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffff000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0000000c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0 c0c0c0000000c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000000000000000 000000c0c0c0c0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000c0c0c0000000 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000ffffff808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 c0c0c0c0c0c0808080 c0c0c0808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080808080808080808080808080808080808080808080808080808080 808080808080808080 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000 showpage % stop using temporary dictionary end % restore original state origstate restore %%Trailer tango-9.2.5a/doc/src/ds_writing/w_attribute.eps0000644023471100065110000001772213034745264016516 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Title: w_attribute.fig %%Creator: fig2dev Version 3.2 Patchlevel 5d %%CreationDate: Thu May 30 13:10:09 2013 %%BoundingBox: 0 0 594 362 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 362 moveto 0 0 lineto 594 0 lineto 594 362 lineto closepath clip newpath -27.6 391.9 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 100 % Polyline 0 slj 0 slc 7.500 slw n 2340 990 m 2340 1170 l gs col0 s gr % Polyline gs clippath 1933 1200 m 2085 1200 l 2085 1140 l 1933 1140 l 1933 1140 l 2053 1170 l 1933 1200 l cp eoclip n 990 1170 m 2070 1170 l gs col0 s gr gr % arrowhead n 1933 1200 m 2053 1170 l 1933 1140 l col0 s % Polyline n 8640 1350 m 9000 1350 l 9000 1930 l 8640 1930 l cp gs col0 s gr % Polyline n 8640 2970 m 9000 2970 l 9000 3550 l 8640 3550 l cp gs col0 s gr % Polyline n 8640 3780 m 9000 3780 l 9000 4360 l 8640 4360 l cp gs col0 s gr % Polyline n 5400 2880 m 5760 2880 l 5760 3590 l 5400 3590 l cp gs col0 s gr % Polyline n 5400 3690 m 5760 3690 l 5760 4400 l 5400 4400 l cp gs col0 s gr % Polyline n 8640 5135 m 9000 5135 l 9000 5715 l 8640 5715 l cp gs col0 s gr /Times-Roman ff 190.50 scf sf 1710 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 190.50 scf sf 4860 810 m gs 1 -1 sc (PositionAttr class) col0 sh gr /Times-Roman ff 190.50 scf sf 2700 1260 m gs 1 -1 sc (always_executed_hook) col0 sh gr % here ends figure; % % here starts figure with depth 50 % Polyline 0 slj 0 slc 7.500 slw n 8820 1080 m 8820 1350 l gs col0 s gr % Polyline n 8820 3600 m 8820 3780 l gs col0 s gr % Polyline gs clippath 8413 1380 m 8565 1380 l 8565 1320 l 8413 1320 l 8413 1320 l 8533 1350 l 8413 1380 l cp eoclip n 2610 1350 m 8550 1350 l gs col0 s gr gr % arrowhead n 8413 1380 m 8533 1350 l 8413 1320 l col0 s % Polyline gs clippath 2747 1860 m 2595 1860 l 2595 1920 l 2747 1920 l 2747 1920 l 2627 1890 l 2747 1860 l cp eoclip n 8550 1890 m 2610 1890 l gs col0 s gr gr % arrowhead n 2747 1860 m 2627 1890 l 2747 1920 l col0 s % Polyline gs clippath 8413 3000 m 8565 3000 l 8565 2940 l 8413 2940 l 8413 2940 l 8533 2970 l 8413 3000 l cp eoclip n 5850 2970 m 8550 2970 l gs col0 s gr gr % arrowhead n 8413 3000 m 8533 2970 l 8413 2940 l col0 s % Polyline gs clippath 5987 3480 m 5835 3480 l 5835 3540 l 5987 3540 l 5987 3540 l 5867 3510 l 5987 3480 l cp eoclip n 8550 3510 m 5850 3510 l gs col0 s gr gr % arrowhead n 5987 3480 m 5867 3510 l 5987 3540 l col0 s % Polyline gs clippath 5987 4290 m 5835 4290 l 5835 4350 l 5987 4350 l 5987 4350 l 5867 4320 l 5987 4290 l cp eoclip n 8550 4320 m 5850 4320 l gs col0 s gr gr % arrowhead n 5987 4290 m 5867 4320 l 5987 4350 l col0 s % Polyline n 5580 2790 m 5580 2880 l gs col0 s gr % Polyline n 5580 3600 m 5580 3690 l gs col0 s gr % Polyline n 5580 1080 m 5580 1260 l gs col0 s gr % Polyline gs clippath 5173 2910 m 5325 2910 l 5325 2850 l 5173 2850 l 5173 2850 l 5293 2880 l 5173 2910 l cp eoclip n 2700 2880 m 5310 2880 l gs col0 s gr gr % arrowhead n 5173 2910 m 5293 2880 l 5173 2850 l col0 s % Polyline gs clippath 2747 3570 m 2595 3570 l 2595 3630 l 2747 3630 l 2747 3630 l 2627 3600 l 2747 3570 l cp eoclip n 5310 3600 m 2610 3600 l gs col0 s gr gr % arrowhead n 2747 3570 m 2627 3600 l 2747 3630 l col0 s % Polyline gs clippath 5173 3720 m 5325 3720 l 5325 3660 l 5173 3660 l 5173 3660 l 5293 3690 l 5173 3720 l cp eoclip n 2610 3690 m 5310 3690 l gs col0 s gr gr % arrowhead n 5173 3720 m 5293 3690 l 5173 3660 l col0 s % Polyline gs clippath 2747 4380 m 2595 4380 l 2595 4440 l 2747 4440 l 2747 4440 l 2627 4410 l 2747 4380 l cp eoclip n 5310 4410 m 2610 4410 l gs col0 s gr gr % arrowhead n 2747 4380 m 2627 4410 l 2747 4440 l col0 s % Polyline gs clippath 8413 3810 m 8565 3810 l 8565 3750 l 8413 3750 l 8413 3750 l 8533 3780 l 8413 3810 l cp eoclip n 5850 3780 m 8550 3780 l gs col0 s gr gr % arrowhead n 8413 3810 m 8533 3780 l 8413 3750 l col0 s % Polyline n 5580 1980 m 5580 2880 l gs col0 s gr % Polyline n 5580 1395 m 5580 1800 l gs col0 s gr % Polyline n 8820 2025 m 8820 2970 l gs col0 s gr % Polyline n 8820 4455 m 8820 5130 l gs col0 s gr % Polyline n 8820 5805 m 8820 6030 l gs col0 s gr % Polyline n 2205 1170 m 2475 1170 l 2475 5670 l 2205 5670 l cp gs col0 s gr % Polyline n 2340 5670 m 2340 5850 l gs col0 s gr % Polyline gs clippath 2747 5595 m 2595 5595 l 2595 5655 l 2747 5655 l 2747 5655 l 2627 5625 l 2747 5595 l cp eoclip n 8550 5625 m 2610 5625 l gs col0 s gr gr % arrowhead n 2747 5595 m 2627 5625 l 2747 5655 l col0 s % Polyline gs clippath 8413 5205 m 8565 5205 l 8565 5145 l 8413 5145 l 8413 5145 l 8533 5175 l 8413 5205 l cp eoclip n 2610 5175 m 8550 5175 l gs col0 s gr gr % arrowhead n 8413 5205 m 8533 5175 l 8413 5145 l col0 s % Polyline n 5580 4410 m 5580 5040 l gs col0 s gr % Polyline n 5580 5265 m 5580 5535 l gs col0 s gr % Polyline n 5580 5760 m 5580 5940 l gs col0 s gr % Polyline n 450 495 m 9855 495 l 9855 6210 l 450 6210 l cp gs col0 s gr /Times-Roman ff 190.50 scf sf 2700 3060 m gs 1 -1 sc (is_allowed) col0 sh gr /Times-Roman ff 190.50 scf sf 5940 2880 m gs 1 -1 sc (is_Position_allowed) col0 sh gr /Times-Roman ff 190.50 scf sf 7920 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 190.50 scf sf 2700 3870 m gs 1 -1 sc (write) col0 sh gr /Times-Roman ff 190.50 scf sf 5940 3735 m gs 1 -1 sc (write_Position) col0 sh gr /Times-Roman ff 190.50 scf sf 765 1080 m gs 1 -1 sc (write_attribute) col0 sh gr /Times-Roman ff 190.50 scf sf 2745 5085 m gs 1 -1 sc (write_attr_hardware) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/ds_writing/r_pipe.fig0000644023471100065110000000552113034745264015413 00000000000000#FIG 3.2 Produced by xfig version 3.2.5c Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 2340 990 2340 1170 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1170 2070 1170 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2340 4590 2340 4770 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 1350 9000 1350 9000 1930 8640 1930 8640 1350 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 3780 9000 3780 9000 4360 8640 4360 8640 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 1080 8820 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 4410 8820 4680 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 4320 5850 4320 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 4410 5580 4590 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1080 5580 1260 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 3690 5310 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 4410 2610 4410 2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 540 360 9810 360 9810 5040 540 5040 540 360 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 2160 1170 2520 1170 2520 4590 2160 4590 2160 1170 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 1890 2610 1890 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 2475 5760 2475 5760 3185 5400 3185 5400 2475 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 1350 8550 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 3060 5850 3060 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2655 2520 5265 2520 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 3150 2610 3150 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 1440 5580 1755 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 2025 5580 2475 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 2475 9000 2475 9000 3055 8640 3055 8640 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 2070 8820 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 3240 8820 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5895 3825 8595 3825 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 2565 8550 2565 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 3690 5760 3690 5760 4400 5400 4400 5400 3690 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 3375 5580 3690 4 0 0 100 0 0 12 0.0000 4 165 1800 2700 1260 always_executed_hook\001 4 0 0 50 0 0 12 0.0000 4 135 360 2700 3870 read\001 4 0 0 50 0 0 12 0.0000 4 165 1710 7920 810 StepperMotor object\001 4 0 0 50 0 0 12 0.0000 4 150 900 2745 2385 is_allowed\001 4 0 0 50 -1 0 12 0.0000 4 165 1080 1845 855 Device_5Impl\001 4 0 0 50 -1 0 14 0.0000 4 165 810 810 1035 read_pipe\001 4 0 0 50 -1 0 14 0.0000 4 165 1530 4905 900 DynDataPipe class\001 4 0 0 50 -1 0 14 0.0000 4 165 1620 5940 2385 is_DynData_allowed\001 4 0 0 50 -1 0 14 0.0000 4 165 1080 5985 3555 read_DynData\001 tango-9.2.5a/doc/src/ds_writing/ds_writing.lyx0000644023471100065110000125762113034745264016370 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter Writing a TANGO device server \end_layout \begin_layout Section The device server framework \end_layout \begin_layout Standard This chapter will present the TANGO device server framework. It will introduce what is the device server pattern and then it will describe a complete device server framework. A definition of classes used by the device server framework is given in this chapter. This manual is not intended to give the complete and detailed description of classes data member or methods, refer to \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset to get this full description. But first, the naming convention used in this project is detailed. \end_layout \begin_layout Standard The aim of the class definition given in this chapter is only to help the reader to understand how a TANGO device server works. For a detailed description of these classes (and their methods), refer to chapter \begin_inset CommandInset ref LatexCommand ref reference "Writing_chapter" \end_inset or to \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . \end_layout \begin_layout Subsection Naming convention and programming language \end_layout \begin_layout Standard TANGO fully supports three different programming languages which are \series bold C++, Java \series default and \series bold Python \series default . This documentation focuses on C++ Tango class. For Java and Python Tango class, have a look at the \begin_inset CommandInset href LatexCommand href name "Tango web" target "http://www.tango-controls.org" \end_inset pages where similar chapter for Java and Python are available. \end_layout \begin_layout Standard Every software project needs a naming \begin_inset Index idx status collapsed \begin_layout Plain Layout naming \end_layout \end_inset convention. The naming convention adopted for the TDSOM is very simple and only defines two guidelines which are: \end_layout \begin_layout Itemize Class names start with uppercase and use capitalization for compound words (For instance MyClassName). \end_layout \begin_layout Itemize Method names are in lowercase and use underscores for compound words (For instance my_method_name). \end_layout \begin_layout Subsection The device pattern \end_layout \begin_layout Standard Device server are written using the Device pattern \begin_inset Index idx status collapsed \begin_layout Plain Layout pattern \end_layout \end_inset . The aim of this pattern is to provide the control programmer with a framework in which s/he can develop new control objects. The device pattern uses other design patterns like the Singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset and Command patterns. These patterns are fully described in \begin_inset CommandInset citation LatexCommand cite key "Patterns" \end_inset . The device pattern class diagram for stepper motor device is drawn in figure \begin_inset CommandInset ref LatexCommand ref reference "Dvice pattern figure" \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Device pattern class diagram \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Graphics filename device_et.eps width 14cm height 18cm \end_inset \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Device pattern class diagram \begin_inset CommandInset label LatexCommand label name "Dvice pattern figure" \end_inset \end_layout \end_inset \end_layout \end_inset . In this figure, only classes surrounded with a dash line square are device specific. All the other classes are part of the TDSOM core and are developed by the Tango system team. Different kind of classes are used by the device pattern. \end_layout \begin_layout Itemize Three of them are root classes and it is only necessary to inherit from them. These classes are the \series bold DeviceImpl \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset , \series bold DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset \series default and \series bold Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset \series default classes. \end_layout \begin_layout Itemize Classes necessary to implement commands \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset . The TDSOM supports two ways to create command : Using inheritance \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset or using the template \begin_inset Index idx status collapsed \begin_layout Plain Layout template \end_layout \end_inset command model. It is possible to mix model within the same device pattern \end_layout \begin_deeper \begin_layout Enumerate Using \series bold inheritance \series default . This model of creating command heavily used the polymorphism offered by each modern object oriented programming language. In this schema, each command supported by a device via the command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset or command_inout_async \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-async \end_layout \end_inset operation is implemented by a separate class. The Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset class is the root class for each of these classes. It is an abstract class. A \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default method must be defined in each sub-class. A \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method may also be re-defined in each class if the default one does not fulfill all the needs \begin_inset Foot status open \begin_layout Plain Layout The default is_allowed method behavior is to always allows the command \end_layout \end_inset . In our stepper motor device server example, the DevReadPosition command follows this model. \end_layout \begin_layout Enumerate Using the \series bold template command \series default model. Using this model, it is not necessary to write one class for each command. You create one instance of classes already defined in the TDSOM for each command. The link between command name and method which need to be executed is done through pointers to method. To support different kind of command, four classes are part of the TDSOM. These classes are : \end_layout \begin_deeper \begin_layout Enumerate The \series bold TemplCommand \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommand \end_layout \end_inset \series default class for command without input or output parameter \end_layout \begin_layout Enumerate The \series bold TemplCommandIn \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandIn \end_layout \end_inset \series default class for command with input parameter but without output parameter \end_layout \begin_layout Enumerate The \series bold TemplCommandOu \series default t \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandOut \end_layout \end_inset class for command with output parameter but without input parameter \end_layout \begin_layout Enumerate The \series bold TemplCommandInOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandInOut \end_layout \end_inset \series default class for all the remaining commands \end_layout \end_deeper \end_deeper \begin_layout Itemize Classes necessary to implement TANGO device attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset . All these classes are part of the TANGO core classes. These classes are the \series bold MultiAttribute \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout MultiAttribute \end_layout \end_inset , \series bold Attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout Attribute \end_layout \end_inset \series default , \series bold WAttribute \begin_inset Index idx status collapsed \begin_layout Plain Layout WAttribute \end_layout \end_inset \series default , \series bold Attr \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout Attr \end_layout \end_inset , \series bold SpectrumAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout SpectrumAttr \end_layout \end_inset \series default and \series bold ImageAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout ImageAttr \end_layout \end_inset \series default classes. The last three are used to create user attribute. Each attribute supported by a device is implemented by a separate class. The Attr class is the root class for each of these classes. According to the attribute data format, the user class implementing the attribute must inherit from the Attr, SpectrumAttr or ImageAtttr class. SpectrumAttr class inherits from Attr class and Image Attr class inherits from the SpectrumAttr class. The Attr base class defined three methods called \emph on is_allowed \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset , \emph on read \begin_inset Index idx status collapsed \begin_layout Plain Layout read \end_layout \end_inset \emph default and \emph on write \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout write \end_layout \end_inset . These methods may be redefined in sub-classes in order to implement the attribute specific behaviour. \end_layout \begin_layout Itemize The other are device specific. For stepper motor device, they are named StepperMotor, StepperMotorClass and DevReadPosition. \end_layout \begin_layout Subsubsection The Tango base class (DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset class) \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class is the device root class and is the link between the Device pattern \begin_inset Index idx status collapsed \begin_layout Plain Layout pattern \end_layout \end_inset and CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset . It inherits from CORBA classes and implements all the methods needed to execute CORBA operations and attributes. For instance, its method \emph on command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset \emph default is executed when a client requests a command_inout operation. The method \emph on name \begin_inset Index idx status collapsed \begin_layout Plain Layout name \end_layout \end_inset \emph default of the DeviceImpl class is executed when a client requests the name CORBA attribute. This class also encapsulates some key device data like its name \begin_inset Index idx status collapsed \begin_layout Plain Layout name \end_layout \end_inset , its state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset , its status \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset , its black box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset .... This class is an abstract class and cannot be instantiated as is. \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard The contents of this class can be summarized as : \end_layout \begin_layout Itemize Different constructors and one destructor \end_layout \begin_layout Itemize Methods to access instance data members outside the class or its derivate classes. These methods are necessary because data members are declared as protected. \end_layout \begin_layout Itemize Methods triggered by CORBA attribute request \end_layout \begin_layout Itemize Methods triggered by CORBA operation \begin_inset Index idx status collapsed \begin_layout Plain Layout operation \end_layout \end_inset request \end_layout \begin_layout Itemize The \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset () \emph default method. This method makes the class abstract. It should be implemented by a sub-class. It is used by the inherited classes constructors. \end_layout \begin_layout Itemize Methods triggered by the automatically added State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset and Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset commands. These methods are declared virtual and therefore can be redefined in sub-classe s. These two commands are automatically added to the list of commands defined for a class of devices. They are discussed in chapter \begin_inset CommandInset ref LatexCommand ref reference "Auto_cmd" \end_inset \end_layout \begin_layout Itemize A method called \emph on always_executed_hook() \begin_inset Index idx status collapsed \begin_layout Plain Layout always-executed-hook \end_layout \end_inset \emph default always executed for each command before the device state is tested for command execution. This method gives the programmer a hook where he(she) can program some mandatory action which must be done before any command execution. An example of the such action is an hardware access to the device to read its real hardware state. \end_layout \begin_layout Itemize A method called \emph on read_attr_hardware() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attr-hardware \end_layout \end_inset triggered by the read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset CORBA operation. This method is called once for each read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset call. This method is virtual and may be redefined in sub-classes. \end_layout \begin_layout Itemize A method called \emph on write_attr_hardware() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attr-hardware \end_layout \end_inset triggered by the write_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset CORBA operation. This method is called once for each write_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset call. This method is virtual and may be redefined in sub-classes. \end_layout \begin_layout Itemize Methods for signal \begin_inset Index idx status collapsed \begin_layout Plain Layout signal \end_layout \end_inset management (C++ specific) \end_layout \begin_layout Itemize Data members like the device name \begin_inset Index idx status collapsed \begin_layout Plain Layout name \end_layout \end_inset , the device status \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset , the device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset \end_layout \begin_layout Itemize Some private methods and data members \end_layout \begin_layout Subsubsection The DbDevice class \end_layout \begin_layout Standard Each DeviceImpl instance is an aggregate with one instance of the DbDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout DbDevice \end_layout \end_inset class. This DbDevice class can be used to query or modify device properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset . It provides an easy to use interface for device objects in the database. The description of this class can be found in the Tango API reference documenta tion available on the Tango WEB pages. \end_layout \begin_layout Subsubsection The Command class \end_layout \begin_layout Paragraph Description of the inheritance \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset model \end_layout \begin_layout Standard Within the TDSOM, each command \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset supported by a device and implemented using the inheritance model is implemente d by a separate class. The Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset class is the root class for each of these classes. It is an abstract class. It stores the command name, the command argument types and description and mainly defines two methods which are the \emph on execute \emph default and \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default methods. The \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default method should be implemented in each sub-class. A default \emph on is_allowed \emph default method exists for command always allowed. A command also stores a parameter which is the command display type. It is also used to select if the command must be displayed according to the application mode (every day operation or expert mode). \end_layout \begin_layout Paragraph Description of the template model \end_layout \begin_layout Standard Using this method, it is not necessary to create a separate class for each device command. In this method, each command is represented by an instance of one of the template \begin_inset Index idx status collapsed \begin_layout Plain Layout template \end_layout \end_inset command classes. They are four template command classes. All these classes inherits from the Command class. These four classes are : \end_layout \begin_layout Enumerate The \series bold TemplCommand \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommand \end_layout \end_inset \series default class. One object of this class must be created for each command without input nor output parameters \end_layout \begin_layout Enumerate The \series bold TemplCommandIn \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandIn \end_layout \end_inset \series default class. One object of this class must be created for each command without output parameter but with input parameter \end_layout \begin_layout Enumerate The \series bold TemplCommandOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandOut \end_layout \end_inset \series default class. One object of this class must be created for each command without input parameter but with output parameter \end_layout \begin_layout Enumerate The \series bold TemplCommandInOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandInOut \end_layout \end_inset \series default class. One object of this class must be created for each command with input and output parameters \end_layout \begin_layout Standard These four classes redefine the \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default and \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method of the Command class. These classes provides constructors which allow the user to : \end_layout \begin_layout Itemize specify which method must be executed by these classes \emph on execute \emph default method \end_layout \begin_layout Itemize optionally specify which method must be executed by these classes \emph on is_allowed \emph default method. \end_layout \begin_layout Standard The method specification is done via pointer to method. \end_layout \begin_layout Standard Remember that it is possible to mix command implementation method within the same device pattern. \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard The content of this class can be summarizes as : \end_layout \begin_layout Itemize Class constructors and destructor \end_layout \begin_layout Itemize Declaration of the \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default method \end_layout \begin_layout Itemize Declaration of the \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method \end_layout \begin_layout Itemize Methods to read/set class data members \end_layout \begin_layout Itemize Methods to extract \begin_inset Index idx status collapsed \begin_layout Plain Layout extract \end_layout \end_inset data from the object used to transfer data on the network \end_layout \begin_layout Itemize Methods to insert \begin_inset Index idx status collapsed \begin_layout Plain Layout insert \end_layout \end_inset data into the object used to transfer data on the network \end_layout \begin_layout Itemize Class data members like command name, command input data type, command input data description... \end_layout \begin_layout Subsubsection The DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class implements all what is specific for a controlled object class. For instance, every device of the same class supports the same list of commands \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset and therefore, this list of available commands is stored in this DeviceClass. The structure returned by the info operation contains a documentation URL \begin_inset Foot status open \begin_layout Plain Layout URL stands for \series bold U \series default niform \series bold R \series default esource \series bold L \series default ocator \end_layout \end_inset . This documentation \begin_inset Index idx status collapsed \begin_layout Plain Layout documentation \end_layout \end_inset URL \begin_inset Index idx status collapsed \begin_layout Plain Layout URL \end_layout \end_inset is the same for every device of the same class. Therefore, the documentation URL is a data member of this class. There should have only one instance of this class per device pattern implementa tion. The device list is also stored in this class. It is an abstract class because the two methods \emph on device_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset () \emph default and \emph on command_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset () \emph default are declared as pure virtual. The rule of the \emph on device_factory() \emph default method is to create all the devices belonging to the device class. The rule of the \emph on command_factory() \emph default method is to create one instance of all the classes needed to support device commands. This class also stored the \emph on attribute_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute-factory \end_layout \end_inset \emph default method. The rule of this method is to store in a vector of strings, the name of all the device attributes. This method has a default implementation which is an empty body for device without attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset . \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard The contents of this class can be summarize as : \end_layout \begin_layout Itemize The \emph on command_handler \begin_inset Index idx status collapsed \begin_layout Plain Layout command-handler \end_layout \end_inset \emph default method \end_layout \begin_layout Itemize Methods to access data members. \end_layout \begin_layout Itemize Signal \begin_inset Index idx status collapsed \begin_layout Plain Layout signal \end_layout \end_inset related method (C++ specific) \end_layout \begin_layout Itemize Class constructor. It is protected to implements the Singleton pattern \end_layout \begin_layout Itemize Class data members like the class command list, the device list... \end_layout \begin_layout Subsubsection The DbClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DbClass \end_layout \end_inset class \end_layout \begin_layout Standard Each DeviceClass instance is an aggregate with one instance of the DbClass class. This DbClass class can be used to query or modify class properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset . It provides an easy to use interface for device objects in the database. The description of this class can be found in the reference Tango C++ API documentation available in the Tango WEB pages. \end_layout \begin_layout Subsubsection The MultiAttribute \begin_inset Index idx status collapsed \begin_layout Plain Layout MultiAttribute \end_layout \end_inset class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class is a container for all the TANGO attributes defined for the device. There is one instance of this class for each device. This class is mainly an aggregate of Attribute object(s). It has been developed to ease TANGO attribute management. \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard The class contents could be summarizes as : \end_layout \begin_layout Itemize Miscellaneous methods to retrieve one attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset object in the aggregate \end_layout \begin_layout Itemize Method to retrieve a list of attribute with an alarm level defined \end_layout \begin_layout Itemize Get attribute number method \end_layout \begin_layout Itemize Miscellaneous methods to check if an attribute value is outside the authorized limits \end_layout \begin_layout Itemize Method to add messages for all attribute with an alarm set \end_layout \begin_layout Itemize Data members with the attribute list \end_layout \begin_layout Subsubsection The Attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout Attribute \end_layout \end_inset class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard There is one object of this class for each device attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset . This class is used to store all the attribute properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset , the attribute value and all the alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout alarm \end_layout \end_inset related data. Like commands, this class also stores th attribute display type. It is foreseen to be used by future Tango graphical application toolkit to select if the attribute must be displayed according to the application mode (every day operation or expert mode). \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Itemize Miscellaneous method to get boolean attribute information \end_layout \begin_layout Itemize Methods to access some data members \end_layout \begin_layout Itemize Methods to get/set attribute properties \end_layout \begin_layout Itemize Method to check if the attribute is in alarm condition \end_layout \begin_layout Itemize Methods related to attribute data \end_layout \begin_layout Itemize Friend function to print attribute properties \end_layout \begin_layout Itemize Data members (properties value and attribute data) \end_layout \begin_layout Subsubsection The WAttribute \begin_inset Index idx status collapsed \begin_layout Plain Layout WAttribute \end_layout \end_inset class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class inherits from the Attribute class. There is one instance of this class for each writable \begin_inset Index idx status collapsed \begin_layout Plain Layout writable \end_layout \end_inset device attribute. On top of all the data already managed by the Attribute class, this class stores the attribute set value. \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard Within this class, you will mainly find methods related to attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset set value storage and some data members. \end_layout \begin_layout Subsubsection The Attr class \end_layout \begin_layout Standard Within the TDSOM, each attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset supported by a device is implemented by a separate class. The Attr \begin_inset Index idx status collapsed \begin_layout Plain Layout Attr \end_layout \end_inset class is the root class for each of these classes. It is used in conjonction with the Attribute and Wattribute classes to implement Tango attribute behaviour. It defines three methods which are the \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset , read \emph default and \emph on write \emph default methods. A default \emph on is_allowed \emph default method exists for attribute always allowed. Default \emph on read \emph default and \emph on write \emph default empty methods are defined. For readable attribute, it is necessary to overwrite the \emph on read \emph default method. For writable attribute, it is necessary to overwrite the \emph on write \emph default method and for read and write attribute, both methods must be overwritten. \end_layout \begin_layout Subsubsection The SpectrumAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout SpectrumAttr \end_layout \end_inset class \end_layout \begin_layout Standard This class inherits from the Attr class. It is the base class for user spectrum attribute. It is used in conjonction with the Attribute and WAttribute class to implement Tango spectrum attribute behaviour. From the Attr class, it inherits the Attr \emph on is_allowed \emph default , \emph on read \emph default and \emph on write \emph default methods. \end_layout \begin_layout Subsubsection The ImageAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout ImageAttr \end_layout \end_inset class \end_layout \begin_layout Standard This class inherits from the SpectrumAttr class. It is the base class for user image attribute. It is used in conjonction with the Attribute and WAttribute class to implement Tango image attribute behaviour. From the Attr class, it inherits the Attr \emph on is_allowed \emph default , \emph on read \emph default and \emph on write \emph default methods. \end_layout \begin_layout Subsubsection The StepperMotor class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class inherits from the DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset class and is the class implementing the controlled object behavior. Each command will trigger a method in this class written by the device server programmer and specific to the object to be controlled. This class also stores all the device specific data. \end_layout \begin_layout Paragraph Definition \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 class StepperMotor: public TANGO_BASE_CLASS \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 public : \end_layout \begin_layout LyX-Code 4 StepperMotor(Tango::DeviceClass *,string &); \end_layout \begin_layout LyX-Code 5 StepperMotor(Tango::DeviceClass *,const char *); \end_layout \begin_layout LyX-Code 6 StepperMotor(Tango::DeviceClass *,const char *,const char *); \end_layout \begin_layout LyX-Code 7 ~StepperMotor() {}; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 DevLong dev_read_position(DevLong); \end_layout \begin_layout LyX-Code 10 DevLong dev_read_direction(DevLong); \end_layout \begin_layout LyX-Code 11 bool direct_cmd_allowed(const CORBA::Any &); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 virtual Tango::DevState dev_state(); \end_layout \begin_layout LyX-Code 14 virtual Tango::ConstDevString dev_status(); \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 virtual void always_executed_hook(); \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 virtual void read_attr_hardware(vector &attr_list); \end_layout \begin_layout LyX-Code 19 virtual void write_attr_hardware(vector &attr_list); \end_layout \begin_layout LyX-Code 20 \end_layout \begin_layout LyX-Code 21 void read_position(Tango::Attribute &); \end_layout \begin_layout LyX-Code 22 bool is_Position_allowed(Tango::AttReqType req); \end_layout \begin_layout LyX-Code 23 void write_SetPosition(Tango::WAttribute &); \end_layout \begin_layout LyX-Code 24 void read_Direction(Tango::Attribute &); \end_layout \begin_layout LyX-Code 25 \end_layout \begin_layout LyX-Code 26 virtual void init_device(); \end_layout \begin_layout LyX-Code 27 virtual void delete_device(); \end_layout \begin_layout LyX-Code 28 \end_layout \begin_layout LyX-Code 29 void get_device_properties(); \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 protected : \end_layout \begin_layout LyX-Code 32 long axis[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 33 DevLong position[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 34 DevLong direction[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 35 long state[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 36 \end_layout \begin_layout LyX-Code 37 Tango::DevLong *attr_Position_read; \end_layout \begin_layout LyX-Code 38 Tango::DevLong *attr_Direction_read; \end_layout \begin_layout LyX-Code 38 Tango::DevLong attr_SetPosition_write; \end_layout \begin_layout LyX-Code 40 \end_layout \begin_layout LyX-Code 41 Tango::DevLong min; \end_layout \begin_layout LyX-Code 42 Tango::DevLong max; \end_layout \begin_layout LyX-Code 43 \end_layout \begin_layout LyX-Code 44 Tango::DevLong *ptr; \end_layout \begin_layout LyX-Code 45 }; \end_layout \begin_layout LyX-Code 46 \end_layout \begin_layout LyX-Code 47 } /* End of StepperMotor namespace */ \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : The StepperMotor class inherits from the DeviceImpl class \end_layout \begin_layout Standard Line 4-7 : Class constructors and destructor \end_layout \begin_layout Standard Line 9 : Method triggered by the DevReadPosition command \end_layout \begin_layout Standard Line 10-11 : Methods triggered by the DevReadDirection command \end_layout \begin_layout Standard Line 13 : Redefinition of the \emph on dev_state \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-state \end_layout \end_inset \emph default method of the DeviceImpl class. This method will be triggered by the State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset command \end_layout \begin_layout Standard Line 14 : Redefinition of the \emph on dev_statu \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-status \end_layout \end_inset s method of the DeviceImpl class. This method will be triggered by the Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset command \end_layout \begin_layout Standard Line 16 : Redefinition of the \emph on always_executed_hook \begin_inset Index idx status collapsed \begin_layout Plain Layout always-executed-hook \end_layout \end_inset \emph default method. \end_layout \begin_layout Standard Line 26 : Definition of the \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset \emph default method (declared as pure virtual by the DeviceImpl class) \end_layout \begin_layout Standard Line 27 : Definition of the \emph on delete_device \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout delet-device \end_layout \end_inset method \end_layout \begin_layout Standard Line 31-45 : Device data \end_layout \begin_layout Subsubsection The StepperMotorClass class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class inherits from the DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset class. Like the DeviceClass class, there should be only one instance of the StepperMot orClass. This is ensured because this class is written following the Singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset pattern as defined in \begin_inset CommandInset citation LatexCommand cite key "Patterns" \end_inset . All controlled object class data which should be defined only once per class must be stored in this object. \end_layout \begin_layout Paragraph Definition \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Standard 1 class StepperMotorClass : public DeviceClass \end_layout \begin_layout Standard 2 { \end_layout \begin_layout Standard 3 public: \end_layout \begin_layout Standard 4 static StepperMotorClass *init(const char *); \end_layout \begin_layout Standard 5 static StepperMotorClass *instance(); \end_layout \begin_layout Standard 6 ~StepperMotorClass() {_instance = NULL;} \end_layout \begin_layout Standard 7 \end_layout \begin_layout Standard 8 protected: \end_layout \begin_layout Standard 9 StepperMotorClass(string &); \end_layout \begin_layout Standard 10 static StepperMotorClass *_instance; \end_layout \begin_layout Standard 11 void command_factory(); \end_layout \begin_layout Standard 12 \end_layout \begin_layout Standard 13 private: \end_layout \begin_layout Standard 14 void device_factory(Tango_DevVarStringArray *); \end_layout \begin_layout Standard 15 }; \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Standard Line 1 : This class is a sub-class of the DeviceClass class \end_layout \begin_layout Standard Line 4-5 and 9-10: Methods and data member necessary for the Singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset pattern \end_layout \begin_layout Standard Line 6 : Class destructor \end_layout \begin_layout Standard Line 11 : Definition of the \emph on command_factor \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset y \emph default method declared as pure virtual in the DeviceClass call \end_layout \begin_layout Standard Line 13-14 : Definition of the \emph on device_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset \emph default method declared as pure virtual in the DeviceClass class \end_layout \begin_layout Subsubsection The DevReadPosition class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This is the class for the DevReadPosition command. This class implements the \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default and \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default methods defined by the Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset class. This class is necessary because this command is implemented using the inheritan ce \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset model. \end_layout \begin_layout Paragraph Definition \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 class DevReadPositionCmd : public Command \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 public: \end_layout \begin_layout LyX-Code 4 DevReadPositionCmd(const char *,Tango_CmdArgType, Tango_CmdArgType, const char *, const char*); \end_layout \begin_layout LyX-Code 5 ~DevReadPositionCmd() {}; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 virtual bool is_allowed (DeviceImpl *, const CORBA::Any &); \end_layout \begin_layout LyX-Code 8 virtual CORBA::Any *execute (DeviceImpl *, const CORBA::Any &); \end_layout \begin_layout LyX-Code 9 }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : The class is a sub class of the Command class \end_layout \begin_layout Standard Line 4-5 : Class constructor and destructor \end_layout \begin_layout Standard Line 7-8 : Definition of the \emph on is_allowed \emph default and \emph on execute \emph default method declared as pure virtual in the Command class. \end_layout \begin_layout Subsubsection The PositionAttr class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This is the class for the Position attribute. This attribute is a scalar attribute and therefore inherits from the Attr base class. This class implements the \emph on read \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default and \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default methods defined by the Attr \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset class. \end_layout \begin_layout Paragraph Definition \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 class PositionAttr: public Tango::Attr \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 public: \end_layout \begin_layout LyX-Code 4 PositionAttr():Attr("Position",Tango::DEV_LONG,Tango::READ); \end_layout \begin_layout LyX-Code 5 ~PositionAttr() {}; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) \end_layout \begin_layout LyX-Code 8 {(static_cast(dev))->read_Position(att);} \end_layout \begin_layout LyX-Code 9 virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) \end_layout \begin_layout LyX-Code 10 {return (static_cast(dev))->is_Position_allowed(ty);} \end_layout \begin_layout LyX-Code 11 }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : The class is a sub class of the Attr class \end_layout \begin_layout Standard Line 4-5 : Class constructor and destructor \end_layout \begin_layout Standard Line 7 : Re-definition of the \emph on read \emph default method defined in the Attr class. This is simply a "forward" to the \emph on read_Position \emph default method of the StepperMotor class \end_layout \begin_layout Standard Line 9 : Re-definition of the \emph on is_allowed \emph default method defined in the Attr class. This is also a "forward" to the \emph on is_Position_allowed \emph default method of the StepperMotor class \end_layout \begin_layout Subsection Startup of a device pattern \begin_inset CommandInset label LatexCommand label name "Pattern startup" \end_inset \end_layout \begin_layout Standard To start the device pattern implementation for stepper motor device, four methods of the StepperMotorClass class must be executed. These methods are : \end_layout \begin_layout Enumerate The creation of the StepperMethodClass singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset via its \emph on init \emph default () method \end_layout \begin_layout Enumerate The \emph on command_factory \emph default () \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset method of the StepperMotorClass class \end_layout \begin_layout Enumerate The \emph on attribute_factory \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute-factory \end_layout \end_inset () method of the StepperMotorClass class. This method has a default empty body for device class without attributes. \end_layout \begin_layout Enumerate The \emph on device_factory \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset () method of the StepperMotorClass class \end_layout \begin_layout Standard This startup procedure is described in figure \begin_inset CommandInset ref LatexCommand ref reference "pattern_startup_fig" \end_inset \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename startup.eps width 14cm height 10cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Device pattern startup sequence \begin_inset CommandInset label LatexCommand label name "pattern_startup_fig" \end_inset \end_layout \end_inset \end_layout \end_inset . The creation of the StepperMotorClass will automatically create an instance of the DeviceClass class. The constructor of the DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset class will create the Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset , State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset and Init \begin_inset Index idx status collapsed \begin_layout Plain Layout Init \end_layout \end_inset command objects and store them in its command list. \end_layout \begin_layout Standard The \emph on command_factory \emph default () method will simply create all the user defined commands and add them in the command list. \end_layout \begin_layout Standard The \emph on attribute_factory \emph default () method will simply build a list of device attribute names. \end_layout \begin_layout Standard The \emph on device_factory \emph default () method will create each StepperMotor object and store them in the StepperMoto rClass instance device list. The list of devices to be created and their names is passed to the \emph on device_factory \emph default method in its input argument. StepperMotor is a sub-class of DeviceImpl class. Therefore, when a StepperMotor object is created, a DeviceImpl object is also created. The DeviceImpl constructor builds all the device attribute object(s) from the attribute list built by the \emph on attribute_factory() \emph default method. \end_layout \begin_layout Subsection Command execution sequence \end_layout \begin_layout Standard The figure \begin_inset CommandInset ref LatexCommand ref reference "command_timing_fig" \end_inset \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename command.eps width 14cm height 8cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Command execution timing \begin_inset CommandInset label LatexCommand label name "command_timing_fig" \end_inset \end_layout \end_inset \end_layout \end_inset described how the method implementing a command is executed when a command_inou t \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset CORBA operation is requested by a client. The \emph on command_inout \emph default method of the StepperMotor object (inherited from the DeviceImpl class) is triggered by an instance of a class generated by the CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset IDL compiler. This method calls the \emph on command_handler \emph default () \begin_inset Index idx status collapsed \begin_layout Plain Layout command-handler \end_layout \end_inset method of the StepperMotorClass object (inherited from the DeviceClass class). The \emph on command_handler \emph default method searches in its command \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset list for the wanted command (using its name). If the command is found, the \emph on always_executed_hook \begin_inset Index idx status collapsed \begin_layout Plain Layout always-executed-hook \end_layout \end_inset \emph default method of the StepperMotor object is called. Then, the \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method of the wanted command is executed. If the \emph on is_allowed \emph default method returns correctly, the \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default method is executed. The \emph on execute \emph default method extracts the incoming data from the CORBA object use to transmit data over the network and calls the user written method which implements the command. \end_layout \begin_layout Subsection The automatically added commands \begin_inset CommandInset label LatexCommand label name "Auto_cmd" \end_inset \end_layout \begin_layout Standard In order to increase the common behavior of every kind of devices in a TANGO control system, three commands are automatically added to each class of devices. These commands are : \end_layout \begin_layout Itemize State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset \end_layout \begin_layout Itemize Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset \end_layout \begin_layout Itemize Init \begin_inset Index idx status collapsed \begin_layout Plain Layout Init \end_layout \end_inset \end_layout \begin_layout Standard The default behavior of the method called by the State command depends on the device state. If the device state is ON or ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset , the method will : \end_layout \begin_layout Itemize read the attribute(s) with an alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout alarm \end_layout \end_inset level defined \end_layout \begin_layout Itemize check if the read value is above/below the alarm level and eventually change the device state to ALARM. \end_layout \begin_layout Itemize returns the device state. \end_layout \begin_layout Standard For all the other device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset , the method simply returns the device state stored in the DeviceImpl class. Nevertheless, the method used to return this state (called \emph on dev_state \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset ) is defined as virtual and can be redefined in DeviceImpl sub-class. The difference between the default State command and the state CORBA attribute is the ability of the State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset command to signal an error to the caller by throwing an exception. \end_layout \begin_layout Standard The default behavior of the method called by the Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset command depends on the device state. If the device state is ON or ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset , the method returns the device status stored in the DeviceImpl class plus additional message(s) for all the attributes which are in alarm condition. For all the other device state, the method simply returns the device status as it is stored in the DeviceImpl class. Nevertheless, the method used to return this status (called \emph on dev_status \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset ) is defined as virtual and can be redefined in DeviceImpl sub-class. The difference between the default Status command and the status CORBA attribute is the ability of the Status command to signal an error to the caller by throwing an exception. \end_layout \begin_layout Standard The Init \begin_inset Index idx status collapsed \begin_layout Plain Layout Init \end_layout \end_inset command is used to re-initialize a device without changing its network connection. This command calls the device \emph on delete_device \begin_inset Index idx status collapsed \begin_layout Plain Layout delete-device \end_layout \end_inset \emph default method and the device \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset \emph default method. The rule of the \emph on delete_device \emph default method is to free memory allocated in the \emph on init_device \emph default method in order to avoid memory leak. \end_layout \begin_layout Subsection Reading/Writing attributes \end_layout \begin_layout Subsubsection Reading attributes \end_layout \begin_layout Standard A Tango client is able to read Tango attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset (s) with the CORBA read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset call. Inside the device server, this call will trigger several methods of the device class (StepperMotor in our example) : \end_layout \begin_layout Enumerate The \emph on always_executed_hook() \begin_inset Index idx status collapsed \begin_layout Plain Layout allways-executed-hook \end_layout \end_inset \emph default method. \end_layout \begin_layout Enumerate A method call \emph on read_attr_hardware() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attr-hardware \end_layout \end_inset . This method is called one time per read_attributes CORBA call. The aim of this method is to read the device hardware and to store the result in a device class data member. \end_layout \begin_layout Enumerate For each attribute to be read \end_layout \begin_deeper \begin_layout Enumerate A method called \emph on is__allowed() \emph default . The rule of this method is to allow (or disallow) the next method to be executed. It is usefull for device with some attributes which can be read only in some precise conditions. It has one parameter which is the request type (read or write) \end_layout \begin_layout Enumerate A method called \emph on read_() \emph default . The aim of this method is to extract the real attribute value from the hardware read-out and to store the attribute value into the attribute object. It has one parameter which is a reference to the Attribute object to be read. \end_layout \end_deeper \begin_layout Standard The figure \begin_inset CommandInset ref LatexCommand ref reference "r_attribute_timing_fig" \end_inset is a drawing of these method calls sequencing. For attribute always readable, a default \emph on is_allowed \emph default method is provided. This method always returns true. \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename r_attribute.eps scale 70 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Read attribute sequencing \begin_inset CommandInset label LatexCommand label name "r_attribute_timing_fig" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Subsubsection Writing attributes \end_layout \begin_layout Standard A Tango client is able to write Tango attribute(s) with the CORBA write_attribut es \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset call. Inside a device server, this call will trigger several methods of the device class (StepperMotor in our example) \end_layout \begin_layout Enumerate The \emph on always_executed_hook() \begin_inset Index idx status collapsed \begin_layout Plain Layout allways-executed-hook \end_layout \end_inset \emph default method. \end_layout \begin_layout Enumerate For each attribute to be written \end_layout \begin_deeper \begin_layout Enumerate A method called \emph on is__allowed() \emph default . The rule of this method is to allow (or disallow) the next method to be executed. It is usefull for device with some attributes which can be written only in some precise conditions. It has one parameter which is the request type (read or write) \end_layout \begin_layout Enumerate A method called \emph on write_() \emph default . It has one parameter which is a reference to the WAttribute object to be written. The aim of this method is to get the data to be written from the WAttribute object and to write this value into the corresponding hardware. If the hardware support writing several data in one go, code the hardware access in the \emph on write_attr_harware() \emph default method. \end_layout \end_deeper \begin_layout Enumerate The write_attr_hardware() \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attr-hardware \end_layout \end_inset method. The rule of this method is to effectively write the hardware in case it is able to support writing several data in one go. If this is not the case, don't code this method (a default implementation is coded in the Tango base class) and code the real hardware access in each \emph on write_() \emph default method. \end_layout \begin_layout Standard The figure \begin_inset CommandInset ref LatexCommand ref reference "w_attribute_timing_fig" \end_inset is a drawing of these method calls sequencing. For attribute always writeable, a default is_allowed method is provided. This method always allways returns true. \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename w_attribute.eps scale 70 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Write attribute sequencing \begin_inset CommandInset label LatexCommand label name "w_attribute_timing_fig" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Subsection The device server framework \end_layout \begin_layout Subsubsection Vocabulary \begin_inset CommandInset label LatexCommand label name "Voc" \end_inset \end_layout \begin_layout Standard A device server \begin_inset Index idx status collapsed \begin_layout Plain Layout server \end_layout \end_inset pattern implementation is embedded in a process called a \series bold device server \series default . Several instances of the same device server process can be used in a TANGO control system. To identify instances, a device server process is started with an \series bold instance name \series default which is different for each instance. The device server name is the couple device server executable \begin_inset Index idx status collapsed \begin_layout Plain Layout executable \end_layout \end_inset name/device server instance \begin_inset Index idx status collapsed \begin_layout Plain Layout instance \end_layout \end_inset name. For instance, a device server started with the following command \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset Perkin id11 \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset starts a device server process with an instance name id11, an executable name Perkin and a device server name Perkin/id11. \end_layout \begin_layout Subsubsection The DServer class \begin_inset CommandInset label LatexCommand label name "DServer_class" \end_inset \end_layout \begin_layout Standard In order to simplify device server process administration, a device of the DServer \begin_inset Index idx status collapsed \begin_layout Plain Layout DServer \end_layout \end_inset class is automatically added to each device server process. Thus, every device server process supports the same set of administration \begin_inset Index idx status collapsed \begin_layout Plain Layout administration \end_layout \end_inset commands. The implementation of this DServer class follows the device pattern and therefore, its device behaves like any other devices. The device name is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset dserver/device server executable name/device server instance name \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset For instance, for the device server process described in chapter \begin_inset CommandInset ref LatexCommand ref reference "Voc" \end_inset , the dserver device name is dserver/perkin/id11. This name is returned by the adm_name \begin_inset Index idx status collapsed \begin_layout Plain Layout adm-name \end_layout \end_inset CORBA attribute available for every device. On top of the three automatically added commands, this device supports the following commands : \end_layout \begin_layout Itemize DevRestart \begin_inset Index idx status collapsed \begin_layout Plain Layout DevRestart \end_layout \end_inset \end_layout \begin_layout Itemize RestartServer \begin_inset Index idx status collapsed \begin_layout Plain Layout RestartServer \end_layout \end_inset \end_layout \begin_layout Itemize QueryClass \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryClass \end_layout \end_inset \end_layout \begin_layout Itemize QueryDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryDevice \end_layout \end_inset \end_layout \begin_layout Itemize Kill \begin_inset Index idx status collapsed \begin_layout Plain Layout Kill \end_layout \end_inset \end_layout \begin_layout Itemize AddLoggingTarget (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout AddLoggingTarget \end_layout \end_inset \end_layout \begin_layout Itemize RemoveLoggingTarget (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout RemoveLoggingTarget \end_layout \end_inset \end_layout \begin_layout Itemize GetLoggingTarget (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingTarget \end_layout \end_inset \end_layout \begin_layout Itemize GetLoggingLevel (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingLevel \end_layout \end_inset \end_layout \begin_layout Itemize SetLoggingLevel (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout SetLoggingLevel \end_layout \end_inset \end_layout \begin_layout Itemize StopLogging (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout StopLogging \end_layout \end_inset \end_layout \begin_layout Itemize StartLogging (C++ server only) \begin_inset Index idx status collapsed \begin_layout Plain Layout StartLogging \end_layout \end_inset \end_layout \begin_layout Itemize PolledDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout PolledDevice \end_layout \end_inset \end_layout \begin_layout Itemize DevPollStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevPollStatus \end_layout \end_inset \end_layout \begin_layout Itemize AddObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout AddObjPolling \end_layout \end_inset \end_layout \begin_layout Itemize RemObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout RemObjPolling \end_layout \end_inset \end_layout \begin_layout Itemize UpdObjPollingPeriod \begin_inset Index idx status collapsed \begin_layout Plain Layout UpdObjPollingPeriod \end_layout \end_inset \end_layout \begin_layout Itemize StartPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StartPolling \end_layout \end_inset \end_layout \begin_layout Itemize StopPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StopPolling \end_layout \end_inset \end_layout \begin_layout Itemize EventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout EventSubscriptionChange \end_layout \end_inset \end_layout \begin_layout Itemize ZmqEventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout ZmqEventSubscriptionChange \end_layout \end_inset \end_layout \begin_layout Itemize LockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout LockDevice \end_layout \end_inset \end_layout \begin_layout Itemize UnLockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout UnLockDevice \end_layout \end_inset \end_layout \begin_layout Itemize ReLockDevices \begin_inset Index idx status collapsed \begin_layout Plain Layout ReLockDevices \end_layout \end_inset \end_layout \begin_layout Itemize DevLockStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevLockStatus \end_layout \end_inset \end_layout \begin_layout Standard These commands will be fully described later in this document. \end_layout \begin_layout Standard Several controlled object classes can be embedded within the same device server process and it is the rule of this device to create all these device server patterns and to call their command and device factories as described in \begin_inset CommandInset ref LatexCommand ref reference "Pattern startup" \end_inset . The name and number of all the classes to be created is known to this device after the execution of a method called \emph on class_factory \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout class-factory \end_layout \end_inset . It is the user responsibility to write this method. \end_layout \begin_layout Subsubsection The Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset class \end_layout \begin_layout Paragraph Description \end_layout \begin_layout Standard This class merges a complete set of utilities in the same class. It is implemented as a singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset and there is only one instance of this class per device server process. It is mandatory to create this instance in order to run a device server. The description of all the methods implemented in this class can be found in \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . \end_layout \begin_layout Paragraph Contents \end_layout \begin_layout Standard Within this class, you can find : \end_layout \begin_layout Itemize Static method to create/retrieve the singleton object \end_layout \begin_layout Itemize Miscellaneous utility methods like getting the server output trace level, getting the CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset ORB pointer, retrieving device server instance name, getting the server PID and more. Please, refer to \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset to get a complete list of all these utility methods. \end_layout \begin_layout Itemize Method to create the device pattern implementing the DServer class ( \emph on server_init() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset ) \end_layout \begin_layout Itemize Method to start the server ( \emph on server_run() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout server-run \end_layout \end_inset ) \end_layout \begin_layout Itemize TANGO database related methods \end_layout \begin_layout Subsubsection A complete device server \end_layout \begin_layout Standard Within a complete device server, at least two implementations of the device server pattern are created (one for the dserver object and the other for the class of devices to control). On top of that, one instance of the Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset class must also be created. \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename complete_server.eps width 14cm height 10cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout A complete device server \begin_inset CommandInset label LatexCommand label name "completeDS" \end_inset \end_layout \end_inset \end_layout \end_inset A drawing of a complete device server is in figure \begin_inset CommandInset ref LatexCommand ref reference "completeDS" \end_inset \end_layout \begin_layout Subsubsection Device server startup sequence \begin_inset CommandInset label LatexCommand label name "Server_startup" \end_inset \end_layout \begin_layout Standard The device server startup sequence is the following : \end_layout \begin_layout Enumerate Create an instance of the Tango::Util class. This will initialize the CORBA Object Request Broker \end_layout \begin_layout Enumerate Called the \emph on server_init \begin_inset Index idx status collapsed \begin_layout Plain Layout init \end_layout \end_inset \emph default method of the Tango::Util instance The call to this method will : \end_layout \begin_deeper \begin_layout Enumerate Create the DServerClass object of the device pattern implementing the DServer \begin_inset Index idx status collapsed \begin_layout Plain Layout DServer \end_layout \end_inset class. This will create the dserver object which during its construction will : \end_layout \begin_deeper \begin_layout Enumerate Called the \emph on class_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout class-factory \end_layout \end_inset \emph default method of the DServer object. This method must create all the xxxClass instance for all the device pattern implementation embedded in the device server process. \end_layout \begin_layout Enumerate Call the \emph on command_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset \emph default and \emph on device_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset \emph default of all the classes previously created. The list of devices passed to each call to the \emph on device_factory \emph default method is retrieved from the TANGO database. \end_layout \end_deeper \end_deeper \begin_layout Enumerate Wait for incoming request with the \emph on server_run() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-run \end_layout \end_inset \emph default method of the Tango::Util class. \end_layout \begin_layout Section Exchanging data between client and server \begin_inset CommandInset label LatexCommand label name "Data exchange" \end_inset \end_layout \begin_layout Standard Exchanging data between clients and server means most of the time passing data between processes running on different computer using the network. Tango limits the type of data exchanged between client and server and defines a way to exchange these data. This chapter details these features. Memory allocation and error reporting are also discussed. \end_layout \begin_layout Standard \series bold All the rules described in this chapter are valid only for data exchanged between client and server. For device server internal data, classical C++ types can be used. \end_layout \begin_layout Subsection Command / Attribute data types \end_layout \begin_layout Standard Commands have a fixed calling syntax - consisting of one input argument and one output argument. Arguments type must be chosen out of a fixed set of 24 data types. Attributes support a sub-set of these data types (those are the data type with the (1) note) plus the DevEnum data type. The following table details type name, code and the corresponding CORBA IDL types. \end_layout \begin_layout Standard The type name used in the type name column of this table is the C++ name. In the IDL file, all the Tango definition are grouped in a IDL \begin_inset Index idx status collapsed \begin_layout Plain Layout IDL \end_layout \end_inset module named Tango. The IDL module maps to C++ namespace \begin_inset Index idx status collapsed \begin_layout Plain Layout namespace \end_layout \end_inset . Therefore, all the data type are parts of a namespace called Tango. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Text \begin_layout Standard \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Type name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout IDL type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevBoolean (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout boolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevShort (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevEnum (2) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short (See chapter on advanced features) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong64 (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevFloat (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevDouble (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevUShort (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong64 (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarCharArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLong64Array \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarFloatArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarUShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarULongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of unsigned long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarULong64Array \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of unsigned long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sequence of string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout structure with a sequence of long and a sequence of string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout structure with a sequence of double and a sequence of string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevState (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout enumeration \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevEncoded (1) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout structure with a string and a sequence of char \end_layout \end_inset \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The CORBA Interface Definition Language uses a type called \series bold sequence \series default for variable length array. The Tango::DevUxxx types are used for unsigned types. The Tango::DevVarxxxxArray must be used when the data to be transferred are variable length array. The Tango::DevVarLongStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset and Tango::DevVarDoubleStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset are structures with two fields which are variable length array of Tango long (32 bits) and variable length array of strings for the Tango::DevVarLongSt ringArray and variable length array of double and variable length array of string for the Tango::DevVarDoubleStringArray. The Tango::State \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevState \end_layout \end_inset type is used by the State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset command to return the device state. \end_layout \begin_layout Subsubsection Using data types with C++ \end_layout \begin_layout Standard Unfortunately, the mapping between IDL and C++ was defined before the C++ class library had been standardized. This explains why the standard C++ string class or vector classes are not used in the IDL to C++ mapping. \end_layout \begin_layout Standard TANGO commands/attributes argument types can be grouped on five groups depending on the IDL data type used. These groups are : \end_layout \begin_layout Enumerate Data type using basic types (Tango::DevBoolean, Tango::DevShort, Tango::DevEnum, Tango::DevLong, Tango::DevFloat, Tango::DevDouble, Tango::DevUshort and Tango::DevULong) \end_layout \begin_layout Enumerate Data type using strings (Tango::DevString type) \end_layout \begin_layout Enumerate Data types using sequences \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset (Tango::DevVarxxxArray types except Tango::DevVarLongStringArray and Tango::Dev VarDoubleStringArray) \end_layout \begin_layout Enumerate Data types using structures (Tango::DevVarLongStringArray and Tango::DevVarDoubl eStringArray types) \end_layout \begin_layout Enumerate Data type using IDL enumeration (Tango::DevState type) \end_layout \begin_layout Standard In the following sub chapters, only summaries of the IDL to C++ mapping are given. For a full description of the C++ mapping, please refer to \begin_inset CommandInset citation LatexCommand cite key "Henning" \end_inset \end_layout \begin_layout Paragraph Basic types \end_layout \begin_layout Standard For these types, the mapping between IDL and C++ is obvious and defined in the following table. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Tango type name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout IDL type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout C++ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout typedef \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevBoolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout boolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Boolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevEnum \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout int \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::LongLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long long or long (64 bits chip) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevFloat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevDouble \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::Double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevUShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::UShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA::ULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA:ULongLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long long or unsigned long (64 bits chip) \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The types defined in the column named C++ should be used for a better portabilit y. All these types are defined in the CORBA namespace and therefore their qualified names is CORBA::xxx. The Tango data type DevEnum \begin_inset Index idx status collapsed \begin_layout Plain Layout DevEnum \end_layout \end_inset is a special case described in detail in the chapter about advanced features. \end_layout \begin_layout Paragraph Strings \end_layout \begin_layout Standard Strings are mapped to \series bold char * \series default . The use of \emph on new \emph default and \emph on delete \emph default for dynamic allocation of strings is not portable. Instead, you must use helper functions defined by CORBA (in the CORBA namespace ). These functions are : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code char *CORBA::string_alloc(unsigned long len); \end_layout \begin_layout LyX-Code char *CORBA::string_dup(const char *); \end_layout \begin_layout LyX-Code void CORBA::string_free(char *); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard These functions handle dynamic memory for strings. The \emph on string_alloc \begin_inset Index idx status collapsed \begin_layout Plain Layout string-alloc \end_layout \end_inset \emph default function allocates one more byte than requested by the len parameter (for the trailing 0). The function \emph on string_dup \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset \emph default combines the allocation and copy. Both \emph on string_alloc \emph default and \emph on string_dup \emph default return a null pointer if allocation fails. The \emph on string_free \begin_inset Index idx status collapsed \begin_layout Plain Layout string-free \end_layout \end_inset \emph default function must be used to free memory allocated with \emph on string_alloc \emph default and \emph on string_dup \emph default . Calling \emph on string_free \emph default for a null pointer is safe and does nothing. The following code fragment is an example of the Tango::DevString \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevString \end_layout \end_inset type usage \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevString str = CORBA::string_alloc(5); \end_layout \begin_layout LyX-Code 2 strcpy(str,"TANGO"); \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 Tango::DevString str1 = CORBA::string_dup("Do you want to danse TANGO?"); \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 CORBA::string_free(str); \end_layout \begin_layout LyX-Code 7 CORBA::string_free(str1); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-2 : TANGO is a five letters string. The CORBA::string_alloc function parameter is 5 but the function allocates 6 bytes \end_layout \begin_layout Standard Line 4 : Example of the CORBA::string_dup function \end_layout \begin_layout Standard Line 6-7 : Memory deallocation \end_layout \begin_layout Paragraph Sequences \end_layout \begin_layout Standard IDL sequences \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset are mapped to C++ classes that behave like vectors with a variable number of elements. Each IDL sequence type results in a separate C++ class. Within each class representing a IDL sequence types, you find the following method (only the main methods are related here) : \end_layout \begin_layout Enumerate Four constructors. \end_layout \begin_deeper \begin_layout Enumerate A default constructor which creates an empty sequence. \end_layout \begin_layout Enumerate The maximum constructor which creates a sequence with memory allocated for at least the number of elements passed as argument. This does not limit the number of element in the sequence but only the way how memory is allocated to store element \end_layout \begin_layout Enumerate A sophisticated constructor where it is possible to assign the memory used by the sequence with a preallocated buffer. \end_layout \begin_layout Enumerate A copy constructor which does a deep copy \end_layout \end_deeper \begin_layout Enumerate An assignment operator which does a deep copy \end_layout \begin_layout Enumerate A \emph on length \emph default accessor which simply returns the current number of elements in the sequence \end_layout \begin_layout Enumerate A \emph on length \begin_inset Index idx status collapsed \begin_layout Plain Layout length \end_layout \end_inset \emph default modifier which changes the length of the sequence (which is different than the number of elements in the sequence) \end_layout \begin_layout Enumerate Overloading of the [] operator. The subscript operator [] provides access to the sequence element. For a sequence containing elements of type T, the [] operator is overloaded twice to return value of type T & and const T &. Insertion into a sequence using the [] operator for the const T & make a deep copy. Sequence are numbered between 0 and \emph on length \emph default () -1. \end_layout \begin_layout Standard Note that using the maximum constructor will not prevent you from setting the length of the sequence with a call to the length modifier. The following code fragment is an example of how to use a Tango::DevVarLongArra y \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset type \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarLongArray *mylongseq_ptr; \end_layout \begin_layout LyX-Code 2 mylongseq_ptr = new Tango::DevVarLongArray(); \end_layout \begin_layout LyX-Code 3 mylongseq_ptr->length(4); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 (*mylongseq_ptr)[0] = 1; \end_layout \begin_layout LyX-Code 6 (*mylongseq_ptr)[1] = 2; \end_layout \begin_layout LyX-Code 7 (*mylongseq_ptr)[2] = 3; \end_layout \begin_layout LyX-Code 8 (*mylongseq_ptr)[3] = 4; \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 // (*mylongseq_ptr)[4] = 5; \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 CORBA::Long nb_elt = mylongseq_ptr->length(); \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 mylongseq_ptr->length(5); \end_layout \begin_layout LyX-Code 15 (*mylongseq_ptr)[4] = 5; \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 for (int i = 0;i < mylongseq_ptr->length();i++) \end_layout \begin_layout LyX-Code 18 cout << "Sequence elt " << i + 1 << " = " << (*mylongseq_ptr)[i] << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Declare a pointer to Tango::DevVarLongArray type which is a sequence of long \end_layout \begin_layout Standard Line 2 : Create an empty sequence \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset \end_layout \begin_layout Standard Line 3 : Change the length \begin_inset Index idx status collapsed \begin_layout Plain Layout length \end_layout \end_inset of the sequence to 4 \end_layout \begin_layout Standard Line 5 - 8 : Initialize sequence elements \end_layout \begin_layout Standard Line 10 ; Oups !!! The length of the sequence is 4. The behavior of this line is undefined and may be a core can be dumped at run time \end_layout \begin_layout Standard Line 12 : Get the number of element actually stored in the sequence \end_layout \begin_layout Standard Line 14-15 : Grow the sequence to five elements and initialize element number 5 \end_layout \begin_layout Standard Line 17-18 : Print sequence element \end_layout \begin_layout Standard Another example for the Tango::DevVarStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset type is given \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarStringArray mystrseq(4); \end_layout \begin_layout LyX-Code 2 mystrseq.length(4); \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 mystrseq[0] = CORBA::string_dup("Rock and Roll"); \end_layout \begin_layout LyX-Code 5 mystrseq[1] = CORBA::string_dup("Bossa Nova"); \end_layout \begin_layout LyX-Code 6 mystrseq[2] = CORBA::string_dup( \begin_inset Quotes eld \end_inset Waltz \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 7 mystrseq[3] = CORBA::string_dup("Tango"); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 CORBA::Long nb_elt = mystrseq.length(); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 for (int i = 0;i < mystrseq.length();i++) \end_layout \begin_layout LyX-Code 12 cout << "Sequence elt " << i + 1 << " = " << mystrseq[i] << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Create a sequence using the maximum constructor \end_layout \begin_layout Standard Line 2 : Set the sequence length to 4. This is mandatory even if you used the maximum constructor. \end_layout \begin_layout Standard Line 4-7 : Populate the sequence \end_layout \begin_layout Standard Line 9 : Get how many strings are stored into the sequence \end_layout \begin_layout Standard Line 11-12 : Print sequence elements. \end_layout \begin_layout Paragraph Structures \end_layout \begin_layout Standard Only three TANGO types are defined as structures. These types are the Tango::DevVarLongStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset , the Tango::DevVarDoubleStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset and the Tango::DevEncoded \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevEncoded \end_layout \end_inset data type. IDL structures map to C++ structures with corresponding members. For the Tango::DevVarLongStringArray, the two members are named \emph on svalue \begin_inset Index idx status collapsed \begin_layout Plain Layout svalue \end_layout \end_inset \emph default for the sequence of strings and \emph on lvalue \begin_inset Index idx status collapsed \begin_layout Plain Layout lvalue \end_layout \end_inset \emph default for the sequence of longs. For the Tango::DevVarDoubleStringArray, the two structure members are called \emph on svalue \emph default for the sequence of strings and \emph on dvalue \begin_inset Index idx status collapsed \begin_layout Plain Layout dvalue \end_layout \end_inset \emph default for the sequence of double. For the Tango::DevEncoded, the two structure members are called \emph on encoded_format \begin_inset Index idx status collapsed \begin_layout Plain Layout encoded-format \end_layout \end_inset \emph default for a string describing the data coding and \emph on encoded_data \begin_inset Index idx status collapsed \begin_layout Plain Layout encoded-data \end_layout \end_inset \emph default for the data themselves. The encoded_data field type is a Tango::DevVarCharArray. An example of the usage of the Tango::DevVarLongStringArray type is detailed below. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarLongStringArray my_vl; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 myvl.svalue.length(2); \end_layout \begin_layout LyX-Code 4 myvl.svalue[0] = CORBA_string_dup("Samba"); \end_layout \begin_layout LyX-Code 5 myvl.svalue[1] = CORBA_string_dup("Rumba"); \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 myvl.lvalue.length(1); \end_layout \begin_layout LyX-Code 8 myvl.lvalue[0] = 10; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Declaration of the structure \end_layout \begin_layout Standard Line 3-5 : Initialization of two strings in the sequence of string member \end_layout \begin_layout Standard Line 7-8 : Initialization of one long in the sequence of long member \end_layout \begin_layout Paragraph The DevState data type \end_layout \begin_layout Standard The Tango::DevState \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevState \end_layout \end_inset data type is used to transfer device state between client and server. It is a IDL enumeration. IDL enumerated types map to C++ enumerations (amazing no!) with a trailing dummy enumerator to force enumeration to be a 32 bit type. The first enumerator will have the value 0, the next one will have the value 1 and so on. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevState state; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 state = Tango::ON; \end_layout \begin_layout LyX-Code 4 state = Tango::FAULT; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsection Passing data between client and server \end_layout \begin_layout Standard In order to have one definition of the CORBA operation used to send a command to a device whatever the command data type is, TANGO uses CORBA IDL \series bold any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset \series default object. The IDL type \emph on any \emph default provides a universal type that can hold a value of arbitrary IDL types. Type \emph on any \emph default therefore allows you to send and receive values whose types are not fixed at compile time. \end_layout \begin_layout Standard Type \emph on any \emph default is often compared to a void * in C. Like a pointer to void, an \emph on any \emph default value can denote a datum of any type. However, there is an important difference; whereas a void * denotes a completel y untyped value that can be interpreted only with advance knowledge of its type, values of type \emph on any \emph default maintain type safety. For example, if a sender places a string value into an \emph on any \emph default , the receiver cannot extract the string as a value of the wrong type. Attempt to read the contents of an \emph on any \emph default as the wrong type cause a run-time error. \end_layout \begin_layout Standard Internally, a value of type \emph on any \emph default consists of a pair of values. One member of the pair is the actual value contained inside the \emph on any \emph default and the other member of the pair is the type code. The type code is a description of the value's type. The type description is used to enforce type safety when the receiver extracts the value. Extraction of the value succeeds only if the receiver extracts the value as a type that matches the information in the type code. \end_layout \begin_layout Standard Within TANGO, the command input and output parameters are objects of the IDL \emph on any \emph default type. Only insertion/extraction of all types defined as command data types is possible into/from these \emph on any \emph default objects. \end_layout \begin_layout Subsubsection C++ mapping for IDL any type \end_layout \begin_layout Standard The IDL any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset maps to the C++ class \series bold CORBA::Any \series default . This class contains a large number of methods with mainly methods to insert/ext ract data into/from the any. It provides a default constructor which builds an any which contains no value and a type code that indicates \begin_inset Quotes eld \end_inset no value \begin_inset Quotes erd \end_inset . Such an any must be used for command which does not need input or output parameter. The operator \series bold <<= \series default is overloaded many times to insert data into an any object. The operator \series bold >>= \series default is overloaded many times to extract data from an any object. \end_layout \begin_layout Paragraph Inserting/Extracting TANGO basic types \end_layout \begin_layout Standard The insertion or extraction of TANGO basic types is straight forward using the <<= or >>= operators. Nevertheless, the Tango::DevBoolean type is mapped to a unsigned char and other IDL types are also mapped to char C++ type (The unsigned is not taken into account in the C++ overloading algorithm). Therefore, it is not possible to use operator overloading for these IDL types which map to C++ char. For the Tango::DevBoolean type, you must use the \emph on CORBA::Any::from_boolean \emph default or \emph on CORBA::Any::to_boolean \emph default intermediate objects defined in the CORBA::Any class. \end_layout \begin_layout Paragraph Inserting/Extracting TANGO strings \end_layout \begin_layout Standard The <<= operator is overloaded for const char * and always makes a deep copy. This deep copy is done using the CORBA:: \emph on string_dup \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset \emph default function. The extraction of strings uses the >>= overloaded operator. The main point is that the Any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset object retains ownership of the string, so the returned pointer points at memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset inside the Any. This means that you must not deallocate the extracted string and you must treat the extracted string as read-only. \end_layout \begin_layout Paragraph Inserting/Extracting TANGO sequences \end_layout \begin_layout Standard Insertion and extraction of sequences \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset also uses the overloaded <<= and >>= operators. The insertion operator is overloaded twice: once for insertion by reference and once for insertion by pointer. If you insert a value by reference, the insertion makes a deep copy. If you insert a value by pointer, the Any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset assumes the ownership of the pointed-to memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset . \end_layout \begin_layout Standard Extraction is always by pointer. As with strings, you must treat the extracted pointer as read-only and must not deallocate it because the pointer points at memory internal to the Any. \end_layout \begin_layout Paragraph Inserting/Extracting TANGO structures \end_layout \begin_layout Standard This is identical to inserting/extracting sequences. \end_layout \begin_layout Paragraph Inserting/Extracting TANGO enumeration \end_layout \begin_layout Standard This is identical to inserting/extracting basic types \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 CORBA::Any a; \end_layout \begin_layout LyX-Code 2 Tango::DevLong l1,l2; \end_layout \begin_layout LyX-Code 3 l1 = 2; \end_layout \begin_layout LyX-Code 4 a <<= l1; \end_layout \begin_layout LyX-Code 5 a >>= l2; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 CORBA::Any b; \end_layout \begin_layout LyX-Code 8 Tango::DevBoolean b1,b2; \end_layout \begin_layout LyX-Code 9 b1 = true; \end_layout \begin_layout LyX-Code 10 b <<= CORBA::Any::from_boolean(b1); \end_layout \begin_layout LyX-Code 11 b >>= CORBA::Any::to_boolean(b2); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 CORBA::Any s; \end_layout \begin_layout LyX-Code 14 Tango::DevString str1,str2; \end_layout \begin_layout LyX-Code 15 str1 = "I like dancing TANGO"; \end_layout \begin_layout LyX-Code 16 s <<= str1; \end_layout \begin_layout LyX-Code 17 s >>= str2; \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 // CORBA::string_free(str2); \end_layout \begin_layout LyX-Code 20 // a <<= CORBA::string_dup("Oups"); \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 CORBA::Any seq; \end_layout \begin_layout LyX-Code 23 Tango::DevVarFloatArray fl_arr1; \end_layout \begin_layout LyX-Code 24 fl_arr1.length(2); \end_layout \begin_layout LyX-Code 25 fl_arr1[0] = 1.0; \end_layout \begin_layout LyX-Code 26 fl_arr1[1] = 2.0; \end_layout \begin_layout LyX-Code 27 seq <<= fl_arr1; \end_layout \begin_layout LyX-Code 28 const Tango::DevVarFloatArray *fl_arr_ptr; \end_layout \begin_layout LyX-Code 29 seq >>= fl_arr_ptr; \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 // delete fl_arr_ptr; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-5 : Insertion and extraction of Tango::DevLong type \end_layout \begin_layout Standard Line 7-11 Insertion and extraction of Tango::DevBoolean type using the CORBA::An y::from_boolean and CORBA::Any::to_boolean intermediate structure \end_layout \begin_layout Standard Line 13-17 : Insertion and extraction of Tango::DevString type \end_layout \begin_layout Standard Line 19 : Wrong ! You should not deallocate a string extracted from an any \end_layout \begin_layout Standard Line 20 : Wrong ! Memory leak because the <<= operator will do the copy. \end_layout \begin_layout Standard Line 22-29 : Insertion and extraction of Tango::DevVarxxxArray types. This is an insertion by reference and the use of the <<= operator makes a deep copy of the sequence. Therefore, after line 27, it is possible to deallocate the sequence \end_layout \begin_layout Standard Line 31: Wrong.! You should not deallocate a sequence extracted from an any \end_layout \begin_layout Subsubsection The insert and extract methods of the Command class \end_layout \begin_layout Standard In order to simplify the insertion/extraction into/from Any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset objects, small helper methods have been written in the Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset class. The signatures of these methods are : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void extract \begin_inset Index idx status collapsed \begin_layout Plain Layout extract \end_layout \end_inset (const CORBA::Any &, &); \end_layout \begin_layout LyX-Code 2 CORBA::Any *insert \begin_inset Index idx status collapsed \begin_layout Plain Layout insert \end_layout \end_inset (); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard An \emph on extract \emph default method has been written for all Tango types. These method extract the data from the Any object passed as parameter and throw an exception if the Any data type is incompatible with the awaiting type. An \emph on insert \emph default method have been written for all Tango types. These method create an Any object, insert the data into the Any and return a pointer to the created Any. For Tango types mapped to sequences or structures, two \emph on insert \emph default methods have been written: one for the insertion from pointer and the other for the insertion from reference. For Tango strings, two \emph on insert \emph default methods have been written: one for insertion from a classical Tango::DevString type and the other from a const Tango::DevString type. The first one deallocate the memory after the insert into the Any object. The second one only inserts the string into the Any object. \end_layout \begin_layout Standard The previous example can be rewritten using the insert/extract helper methods (We suppose that we can use the Command class insert/extract methods) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevLong l1,l2; \end_layout \begin_layout LyX-Code 2 l1 = 2; \end_layout \begin_layout LyX-Code 3 CORBA::Any *a_ptr = insert(l1); \end_layout \begin_layout LyX-Code 4 extract(*a_ptr,l2); \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 Tango::DevBoolean b1,b2; \end_layout \begin_layout LyX-Code 7 b1 = true; \end_layout \begin_layout LyX-Code 8 CORBA::Any *b_ptr = insert(b1); \end_layout \begin_layout LyX-Code 9 extract(*b_ptr,b2); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 Tango::DevString str1,str2; \end_layout \begin_layout LyX-Code 12 str1 = "I like dancing TANGO"; \end_layout \begin_layout LyX-Code 13 CORBA::Any *s_ptr = insert(str1); \end_layout \begin_layout LyX-Code 14 extract(*s_ptr,str2); \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 Tango::DevVarFloatArray fl_arr1; \end_layout \begin_layout LyX-Code 17 fl_arr1.length(2); \end_layout \begin_layout LyX-Code 18 fl_arr1[0] = 1.0; \end_layout \begin_layout LyX-Code 19 fl_arr1[1] = 2.0; \end_layout \begin_layout LyX-Code 20 insert(fl_arr1); \end_layout \begin_layout LyX-Code 21 CORBA::Any *seq_ptr = insert(fl_arr1); \end_layout \begin_layout LyX-Code 22 Tango::DevVarFloatArray *fl_arr_ptr; \end_layout \begin_layout LyX-Code 23 extract(*seq_ptr,fl_arr_ptr); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-4 : Insertion and extraction of Tango::DevLong type \end_layout \begin_layout Standard Line 6-9 : Insertion and extraction of Tango::DevBoolean type \end_layout \begin_layout Standard Line 11-14 : Insertion and extraction of Tango::DevString type \end_layout \begin_layout Standard Line 16-23 : Insertion and extraction of Tango::DevVarxxxArray types. This is an insertion by reference which makes a deep copy of the sequence. Therefore, after line 20, it is possible to deallocate the sequence \end_layout \begin_layout Subsection C++ memory management \end_layout \begin_layout Standard The rule described here are valid for variable length command data types like Tango::DevString or all the Tango:: DevVarxxxxArray types. \end_layout \begin_layout Standard The method executing the command must allocate the memory used to pass data back to the client or use static memory (like buffer declares as object data member. If necessary, the ORB will deallocate this memory after the data have been sent to the caller. Fortunately, for incoming data, the method have no memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset management responsibilities. The details about memory management given in this chapter assume that the insert/extract methods of the Tango::Command class are used and only the method in the device object is discussed. \end_layout \begin_layout Subsubsection For string \end_layout \begin_layout Standard Example of a method receiving a Tango::DevString \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevString \end_layout \end_inset and returning a Tango::DevString is detailed just below \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevString MyDev::dev_string(Tango::DevString argin) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DevString argout; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 cout << "the received string is " << argin << endl; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 string str("Am I a good Tango dancer ?"); \end_layout \begin_layout LyX-Code 8 argout = new char[str.size() + 1]; \end_layout \begin_layout LyX-Code 9 strcpy(argout,str.c_str()); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 return argout; \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Note that there is no need to deallocate the memory used by the incoming string. Memory for the outgoing string is allocated at line 8, then it is initialized at the following line. The memory allocated at line 8 will be automatically freed by the usage of the \emph on Command::insert \begin_inset Index idx status collapsed \begin_layout Plain Layout insert \end_layout \end_inset () \emph default method. Using this schema, memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset is allocated/freed each time the command is executed. For constant string length, a statically allocated buffer can be used. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::ConstDevString MyDev::dev_string(Tango::DevString argin) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::ConstDevString argout; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 cout << "the received string is " << argin << endl; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 argout = "Hello world"; \end_layout \begin_layout LyX-Code 8 return argout; \end_layout \begin_layout LyX-Code 9 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard A Tango::ConstDevString \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::ConstDevString \end_layout \end_inset data type is used. It is not a new data Tango data type. It has been introduced only to allows \emph on Command::insert() \emph default method overloading. The argout pointer is initialized at line 7 with memory statically allocated. In this case, no memory will be freed by the \emph on Command::insert() \emph default method. There is also no memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset copy in the contrary of the previous example. A buffer defined as object data member can also be used to set the argout pointer. \end_layout \begin_layout Subsubsection For array/sequence \end_layout \begin_layout Standard Example of a method returning a Tango::DevVarLongArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset is detailed just below \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarLongArray *MyDev::dev_array() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DevVarLongArray *argout = new Tango::DevVarLongArray(); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 long output_array_length = ...; \end_layout \begin_layout LyX-Code 6 argout->length(output_array_length); \end_layout \begin_layout LyX-Code 7 for (int i = 0;i < output_array_length;i++) \end_layout \begin_layout LyX-Code 8 (*argout)[i] = i; \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 return argout; \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard In this case, memory is allocated at line 3 and 6. Then, the sequence \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset is populated. The sequence is created and returned using pointer. The \emph on Command::insert() \emph default method will insert the sequence into the CORBA::Any object using this pointer. Therefore, the CORBA::Any object will take ownership of the allocated memory. It will free it when it will be destroyed by the CORBA ORB after the data have been sent away. It is also possible to use a statically allocated memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset and to avoid copying in the sequence used to returned the data. This is explained in the following example assuming a buffer of long data is declared as device data member and named buffer. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarLongArray *MyDev::dev_array() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DevVarLongArray *argout; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 long output_array_length = ...; \end_layout \begin_layout LyX-Code 6 argout = create_DevVarLongArray(buffer,output_array_length); \end_layout \begin_layout LyX-Code 7 return argout; \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard At line 3 only a pointer to a DevVarLongArray is defined. This pointer is set at line 6 using the \emph on create_DevVarLongArray() \begin_inset Index idx status collapsed \begin_layout Plain Layout create-DevVarLongArray \end_layout \end_inset \emph default method. This method will create a sequence using this buffer without memory allocation and with minimum copying. The \emph on Command::insert() \emph default method used here is the same than the one used in the previous example. The sequence is created in a way that the destruction of the CORBA::Any object in which the sequence will be inserted will not destroy the buffer. The following create_xxx methods are defined in the DeviceImpl class : \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Method name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarCharArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarShortArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarLongArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarLong64Array() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevLong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarFloatArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarDoubleArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarUShortArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarULongArray() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout create_DevVarULong64Array() \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevULong64 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsubsection For string array/sequence \end_layout \begin_layout Standard Example of a method returning a Tango::DevVarStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset is detailed just below \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarStringArray *MyDev::dev_str_array() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DevVarStringArray *argout = new Tango::DevVarStringArray(); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 argout->length(3); \end_layout \begin_layout LyX-Code 6 (*argout)[0] = CORBA::string_dup("Rumba"); \end_layout \begin_layout LyX-Code 7 (*argout)[1] = CORBA::string_dup("Waltz"); \end_layout \begin_layout LyX-Code 8 string str("Jerck"); \end_layout \begin_layout LyX-Code 9 (*argout)[2] = CORBA::string_dup(str.c_str()); \end_layout \begin_layout LyX-Code 10 return argout; \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Memory is allocated at line 3 and 5. Then, the sequence \begin_inset Index idx status collapsed \begin_layout Plain Layout sequence \end_layout \end_inset is populated at lines 6,7 and 9. The usage of the \emph on CORBA::string_dup \emph default function also allocates memory. The sequence is created and returned using pointer. The \emph on Command::insert() \emph default method will insert the sequence into the CORBA::Any object using this pointer. Therefore, the CORBA::Any object will take ownership of the allocated memory. It will free it when it will be destroyed by the CORBA ORB after the data have been sent away. For portability reason, the ORB uses the \emph on CORBA::string_free \begin_inset Index idx status collapsed \begin_layout Plain Layout string-free \end_layout \end_inset \emph default function to free the memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset allocated for each string. This is why the corresponding \emph on CORBA::string_du \emph default p \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset or \emph on CORBA::string_alloc \emph default function must be used to reserve this memory.It is also possible to use a statically allocated memory and to avoid copying in the sequence used to returned the data. This is explained in the following example assuming a buffer of pointer to char is declared as device data member and named int_buffer. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarStringArray *DocDs::dev_str_array() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 int_buffer[0] = "first"; \end_layout \begin_layout LyX-Code 4 int_buffer[1] = "second"; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 Tango::DevVarStringArray *argout; \end_layout \begin_layout LyX-Code 7 argout = create_DevVarStringArray(int_buffer,2); \end_layout \begin_layout LyX-Code 8 return argout; \end_layout \begin_layout LyX-Code 9 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The intermediate buffer is initialized with statically allocated memory at lines 3 and 4. The returned sequence is created at line 7 with the \emph on create_DevVarStringArray() \begin_inset Index idx status collapsed \begin_layout Plain Layout create-DevVarStringArray \end_layout \end_inset \emph default method. Like for classical array, the sequence is created in a way that the destruction of the CORBA::Any \begin_inset Index idx status collapsed \begin_layout Plain Layout any \end_layout \end_inset object in which the sequence will be inserted will not destroy the buffer. \end_layout \begin_layout Subsubsection For Tango composed types \end_layout \begin_layout Standard Tango supports only two composed types which are Tango::DevVarLongStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset and Tango::DevVarDoubleStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset . These types are translated to C++ structure with two sequences. It is not possible to use memory statically allocated for these types. Each structure element must be initialized as described in the previous sub-chapters using the dynamically allocated memory case. \end_layout \begin_layout Subsection Reporting errors \begin_inset CommandInset label LatexCommand label name "sub:Reporting-errors" \end_inset \end_layout \begin_layout Standard Tango uses the C++ try/catch plus exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset mechanism to report errors. Two kind of errors can be transmitted between client and server : \end_layout \begin_layout Enumerate CORBA system error. These exceptions are raised by the ORB and indicates major failures (A communication failure, An invalid object reference...) \end_layout \begin_layout Enumerate CORBA user exception. These kind of exceptions are defined in the IDL file. This allows an exception to contain an arbitrary amount of error information of arbitrary type. \end_layout \begin_layout Standard TANGO defines one user exception called \series bold DevFailed \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout DevFailed \end_layout \end_inset . This exception is a variable length array of \series bold DevError \begin_inset Index idx status collapsed \begin_layout Plain Layout DevError \end_layout \end_inset \series default type (a sequence of DevError). The DevError type is a four fields structure. These fields are : \end_layout \begin_layout Enumerate A string describing the type of the error. This string replaces an error code and allows a more easy management of include files. \end_layout \begin_layout Enumerate The error severity. It is an enumeration with the three values which are WARN, ERR or PANIC. \end_layout \begin_layout Enumerate A string describing in plain text the reason of the error \end_layout \begin_layout Enumerate A string describing the origin of the error \begin_inset Index idx status collapsed \begin_layout Plain Layout error \end_layout \end_inset \end_layout \begin_layout Standard The Tango::DevFailed type is a sequence of DevError structures in order to transmit to the client what is the primary error reason when several classes are used within a command. The sequence element 0 must be the DevError structure describing the primary error. A method called \emph on print_exception \emph default () \begin_inset Index idx status collapsed \begin_layout Plain Layout print-exception \end_layout \end_inset defined in the Tango::Except \begin_inset Index idx status collapsed \begin_layout Plain Layout Except \end_layout \end_inset class prints the content of exception (CORBA system exception or Tango::DevFail ed exception). Some static methods of the Tango::Except class called \emph on throw_exception \emph default () \begin_inset Index idx status collapsed \begin_layout Plain Layout throw-exception \end_layout \end_inset can be used to throw Tango::DevFailed exception. Some other static methods called \emph on re_throw_exception() \begin_inset Index idx status collapsed \begin_layout Plain Layout re-throw-exception \end_layout \end_inset \emph default may also be used when the user want to add a new element in the exception sequence and re-throw the exception. Details on these methods can be found in \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . \end_layout \begin_layout Subsubsection Example of throwing exception \end_layout \begin_layout Standard This example is a piece of code from the \emph on command_handler \emph default () method of the DeviceImpl class. An exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset is thrown to the client to indicate that the requested command is not defined in the command list. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 TangoSys_OMemStream o; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 o << "Command " << command << " not found" << ends; \end_layout \begin_layout LyX-Code 4 Tango::Except::throw_exception("API_CommandNotFound", \end_layout \begin_layout LyX-Code 5 o.str(), \end_layout \begin_layout LyX-Code 6 "DeviceClass::command_handler"); \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 try \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 ..... \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 catch (Tango::DevFailed &e) \end_layout \begin_layout LyX-Code 14 { \end_layout \begin_layout LyX-Code 15 TangoSys_OMemStream o; \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 o << "Command " << command << " not found" << ends; \end_layout \begin_layout LyX-Code 18 Tango::Except::re_throw_exception(e, \end_layout \begin_layout LyX-Code 19 "API_CommandNotFound", \end_layout \begin_layout LyX-Code 20 o.str(), \end_layout \begin_layout LyX-Code 21 "DeviceClass::command_handler"); \end_layout \begin_layout LyX-Code 22 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Build a memory stream. Use the TangoSys_MemStream because memory streams are not managed the same way between Windows and Unix \end_layout \begin_layout Standard Line 3 : Build the reason string in the memory stream \end_layout \begin_layout Standard Line 4-5 : Throw the exception to client using one of the \emph on throw_exception \begin_inset Index idx status collapsed \begin_layout Plain Layout throw-exception \end_layout \end_inset \emph default static method of the Except \begin_inset Index idx status collapsed \begin_layout Plain Layout Except \end_layout \end_inset class. This throw_exception method used here allows the definition of the error type string, the reason string and the origin string of the DevError structure. The remaining DevError field (the error severity) will be set to its default value. Note that the first and third parameters are casted to a \emph on const char * \emph default . Standard C++ defines that such a string is already a \emph on const char * \emph default but the GNU C++ compiler (release 2.95) does not use this type inside its function overloading but rather uses a \emph on char * \emph default which leads to calling the wrong function. \end_layout \begin_layout Standard Line 13-22 : Re-throw an already catched tango::DevFailed exception with one more element in the exception sequence. \end_layout \begin_layout Section The Tango Logging \begin_inset Index idx status collapsed \begin_layout Plain Layout logging \end_layout \end_inset Service \begin_inset CommandInset label LatexCommand label name "The-Tango-Logging chapter" \end_inset \end_layout \begin_layout Standard A first introduction about this logging service has been done in chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:The-Tango-Logging" \end_inset \end_layout \begin_layout Standard The TANGO Logging Service (TLS) gives the user the control over how much information is actually generated and to where it goes. In practice, the TLS allows to select both the logging level and targets of any device within the control system. \end_layout \begin_layout Subsection Logging Targets \end_layout \begin_layout Standard The TLS implementation allows each device logging requests to print simultaneous ly to multiple destinations. In the TANGO terminology, an output destination is called a \series bold logging target \series default . Currently, targets exist for console, file and log consumer device. \end_layout \begin_layout Standard CONSOLE: logs are printed to the console (i.e. the standard output), \end_layout \begin_layout Standard FILE: logs are stored in a XML file. A rolling mechanism is used to backup the log file when it reaches a certain size (see below), \end_layout \begin_layout Standard DEVICE: logs are sent to a device implementing a well known TANGO interface (see section \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango-log-consumer" \end_inset for a definition of the log consumer interface). One implementation of a log consumer associated to a graphical user interface is available within the Tango package. It is called the LogViewer \begin_inset Index idx status collapsed \begin_layout Plain Layout LogViewer \end_layout \end_inset . \end_layout \begin_layout Standard The device's logging behavior can be control by adding and/or removing targets. \end_layout \begin_layout Standard Note : When the size of a log file (for file logging target) reaches the so-called rolling-file-threshold (rft), it is backuped as "current_log_file_nam e" + "_1" and a new "current_log_file_name" is opened. Obviously, there is only one backup file at a time (i.e. any existing backup is destroyed before the current log file is backuped). The default threshold is 20 Mb, the minimum is 500 Kb and the maximum is 1000 Mb. \end_layout \begin_layout Subsection Logging Levels \end_layout \begin_layout Standard Devices can be assigned a logging level. It acts as a filter to control the kind of information sent to the targets. Since, there are (usually) much more low level log statements than high level statements, the logging level also control the amount of information produced by the device. The TLS provides the following levels (semantic is just given to be indicative of what could be log at each level): \end_layout \begin_layout Standard OFF: Nothing is logged \end_layout \begin_layout Standard FATAL: A fatal error occurred. The process is about to abort \end_layout \begin_layout Standard ERROR: An (unrecoverable) error occurred but the process is still alive \end_layout \begin_layout Standard WARN: An error occurred but could be recovered locally \end_layout \begin_layout Standard INFO: Provides information on important actions performed \end_layout \begin_layout Standard DEBUG: Generates detailed information describing the internal behavior of a device \end_layout \begin_layout Standard Levels are ordered the following way: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset DEBUG < INFO < WARN < ERROR < FATAL < OFF \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard For a given device, a level is said to be enabled if it is greater or equal to the logging level assigned to this device. In other words, any logging request which level is lower than the device's logging level is ignored. \end_layout \begin_layout Standard Note: The logging level can't be controlled at target level. The device's targets shared the same device logging level. \end_layout \begin_layout Subsection Sending TANGO Logging Messages \end_layout \begin_layout Subsubsection Logging macros in C++ \end_layout \begin_layout Standard The TLS provides the user with easy to use C++ macros with \emph on printf \emph default and \emph on stream \emph default like syntax. For each logging level, a macro is defined in both styles: \end_layout \begin_layout Itemize LOG_{FATAL, ERROR, WARN, INFO or DEBUG} \end_layout \begin_layout Itemize {FATAL, ERROR, WARN, INFO or DEBUG}_STREAM \end_layout \begin_layout Standard These macros are supposed to be used within the device's main implementation class (i.e. the class that inherits (directly or indirectly) from the Tango::DeviceImpl class). In this context, they produce logging messages containing the device name. In other words, they automatically identify the log source. Section \begin_inset CommandInset ref LatexCommand ref reference "sub:C++-logging-in" \end_inset gives a trick to log in the name of device outside its main implementation class. Printf like example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard LOG_DEBUG(("Msg#%d - Hello world", i++)); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Stream like example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard DEBUG_STREAM << "Msg#" << i++ << "- Hello world" << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard These two logging requests are equivalent. Note the double parenthesis in the printf version. \end_layout \begin_layout Subsubsection C++ logging in the name of a device \begin_inset CommandInset label LatexCommand label name "sub:C++-logging-in" \end_inset \end_layout \begin_layout Standard A device implementation is sometimes spread over several classes. Since all these classes implement the same device, their logging requests should be associated with this device name. Unfortunately, the C++ logging macros can't be used because they are outside the device's main implementation class. The Tango::LogAdapter class is a workaround for this limitation. \end_layout \begin_layout Standard Any method not member of the device's main implementation class, which send log messages associated to a device must be a member of a class inheriting from the Tango::LogAdapter class. Here is an example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 class MyDeviceActualImpl: public Tango::LogAdapter \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 public : \end_layout \begin_layout LyX-Code 4 MyDeviceActualImpl(...,Tango::DeviceImpl *device,...) \end_layout \begin_layout LyX-Code 5 :Tango::LogAdpater(device) \end_layout \begin_layout LyX-Code 6 { \end_layout \begin_layout LyX-Code 7 .... \end_layout \begin_layout LyX-Code 8 // \end_layout \begin_layout LyX-Code 9 // The following log is associated to the device passed to the constructor \end_layout \begin_layout LyX-Code 10 // \end_layout \begin_layout LyX-Code 11 DEBUG_STREAM << "In MyDeviceActualImpl constructor" << endl; \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 .... \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Writing a device server process \begin_inset CommandInset label LatexCommand label name "Writing_chapter" \end_inset \end_layout \begin_layout Standard Writing a device server can be made easier by adopting the correct approach. This chapter will describe how to write a device server process. It is divided into the following parts : understanding the device, defining device commands/attributes/pipes, choosing device state and writing the necessary classes. All along this chapter, examples will be given using the stepper motor device server. Writing a device server for our stepper motor example device means writing : \end_layout \begin_layout Itemize The \emph on main \emph default function \end_layout \begin_layout Itemize The \emph on class_factory \emph default method (only for C++ device server) \end_layout \begin_layout Itemize The \emph on StepperMotorClass \emph default class \end_layout \begin_layout Itemize The \emph on DevReadPositionCmd \emph default and \emph on DevReadDirectionCmd \emph default classes \end_layout \begin_layout Itemize The \emph on PositionAttr \emph default , \emph on SetPositionAttr \emph default and \emph on DirectionAttr \emph default classes \end_layout \begin_layout Itemize The \emph on StepperMotor \emph default class. \end_layout \begin_layout Standard All these functions and classes will be detailed. The stepper motor device server described in this chapter supports 2 commands and 3 attributes which are : \end_layout \begin_layout Itemize Command DevReadPosition implemented using the inheritance \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset model \end_layout \begin_layout Itemize Command DevReadDirection implemented using the template \begin_inset Index idx status collapsed \begin_layout Plain Layout template \end_layout \end_inset command model \end_layout \begin_layout Itemize Attribute Position (position of the first motor). This attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset is readable and is linked with a writable attribute (called SetPosition). When the value of this attribute is requested by the client, the value of the associated writable attribute is also returned. \end_layout \begin_layout Itemize Attribute SetPosition (writable attribute linked with the Position attribute). This attribute has some properties with user defined default value. \end_layout \begin_layout Itemize Attribute Direction (direction of the first motor) \end_layout \begin_layout Standard As the reader will understand during the reading of the following sub-chapters, the command and attributes classes ( \emph on DevReadPositionCmd \emph default , \emph on DevReadDirectionCmd \emph default , \emph on PositionAttr \emph default , \emph on SetPositionAttr \emph default and \emph on DirectionAttr \emph default ) are very simple classes. A tool called \series bold Pogo \series default has been developped to automatically generate/maintain these classes and to write part of the code needed in the remaining one. See xx to know more on this Pogo tool. \end_layout \begin_layout Standard In order to also gives an example of how the database objects part of the Tango device pattern could be used, our device have two properties. These properties are of the Tango long data types and are named \begin_inset Quotes eld \end_inset Max \begin_inset Quotes erd \end_inset and \begin_inset Quotes eld \end_inset Min \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Subsection Understanding the device \end_layout \begin_layout Standard The first step before writing a device server is to develop an understanding of the hardware to be programmed. The Equipment Responsible should have description of the hardware and its operating modes (manuals, spec sheets etc.). The Equipment Responsible must also provide specifications of what the device server should do. The Device Server Programmer should demand an exact description of the registers, alarms, interlocks and any timing constraints which have to be kept. It is very important to have a good understanding of the device interfacing before starting designing a new class. \end_layout \begin_layout Standard Once the Device Server Programmer has understood the hardware the next important step is to define what is a logical device i.e. what part of the hardware will be abstracted out and treated as a logical device. In doing so the following points of the TDSOM should be kept in mind \end_layout \begin_layout Itemize Each device is known and accessed by its ascii name. \end_layout \begin_layout Itemize The device is exported onto the network to be imported by applications. \end_layout \begin_layout Itemize Each device belongs to a class. \end_layout \begin_layout Itemize A list of commands exists per device. \end_layout \begin_layout Itemize Applications use the device server api to execute commands on a device. \end_layout \begin_layout Standard The above points have to be taken into account when designing the level of device abstraction. The definition of what is a device for a certain hardware is primarily the job of the Device Server Programmer and the Applications Programmer but can also involve the Equipment Responsible. The Device Server Programmer should make sure that the Applications Programmer agrees with her definition of what is a device. \end_layout \begin_layout Standard Here are some guidelines to follow while defining the level of device abstractio n - \end_layout \begin_layout Itemize \series bold efficiency \series default , make sure that not a too fine level of device abstraction has been chosen. If possible group as many attributes together to form a device. Discuss this with the Applications Programmer to find out what is efficient for her application. \end_layout \begin_layout Itemize \series bold hardware independency \series default , one of the main reasons for writing device servers is to provide the Applicati ons Programmer with a \emph on software \emph default interface as opposed to a \emph on hardware \emph default interface. Hide the hardware structure of the device. For example if the user is only interested in a single channel of a multichanne l device then define each channel to be a logical device. The user should not be aware of hardware addresses or cabling details. The user is very often a scientist who has a physics-oriented world view and not a hardware-oriented world view. Hardware independency also has the advantage that applications are immune to hardware changes to the device \end_layout \begin_layout Itemize \series bold object oriented world view \series default , another \emph on raison d'etre \emph default behind the device server model is to build up an object oriented view of the world. The device should resemble the user's view of the object as closely as possible. In the case of the ESRF's beam lines for example, the devices should resemble beam line scientist's view of the machine. \end_layout \begin_layout Itemize \series bold atomism \series default , each device can be considered like an atom - is a independent object. It should appear independent to the client even if behind the scenes it shares some hardware or software with other objects. This is often the case with multichannel devices where the user would like to see each channel as a device but it is obvious that the channels cannot be programmed completely independently. The logical device is there to hide or make transparent this fact. If it is impossible to send commands to one device without modifying another device then a single device should be made out the two devices. \end_layout \begin_layout Itemize \series bold tailored \series default \emph on vs \emph default \series bold general \series default , one of the philosophies of the TDSOM is to provide tailored solutions. For example instead of writing one \emph on serial line \emph default class which treats the general case of a serial line device and leaving the device protocol to be implemented in the client the TDSOM advocates implementing a device class which handles the protocol of the device. This way the client only has to know the commands of the class and not the details of the protocol. Nothing prevents the device class from using a general purpose serial line class if it exists of course. \end_layout \begin_layout Subsection Defining device commands \end_layout \begin_layout Standard Each device has a list of commands which can be executed by the application across the network or locally. These commands are the Application Programmer's network knobs and dials for interacting with the device. \end_layout \begin_layout Standard The list of commands to be implemented depends on the capabilities of the hardware, the list of sensible functions which can be executed at a distance and of course the functionality required by the application. This implies a close collaboration between the Equipment Responsible, Device Server Programmer and the Application Programmer. \end_layout \begin_layout Standard When drawing up the list of commands particular attention should be paid to the following points \end_layout \begin_layout Itemize \series bold performance \series default , no single command should monopolize the device server for a long time (a nominal value for long is one second). Commands should be implemented in such a way that it executes immediately returning with a response. At best try to keep command execution time down to less than the typical overhead of an rpc call i.e. som milliseconds. This of course is not always possible e.g. a serial line device could require 100 milliseconds of protocol exchange. The Device Server Programmer should find the best trade-off between the users requirements and the devices capabilities. If a command implies a sequence of events which could last for a long time then implement the sequence of events in another thread - don't block the device server. \end_layout \begin_layout Itemize \series bold robustness \series default , should be provided which allow the client to recover from error conditions and or do a warm startup. \end_layout \begin_layout Subsubsection Standard commands \end_layout \begin_layout Standard A minimum set of three commands exist for all devices. These commands are \end_layout \begin_layout Itemize State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset which returns the state of a device \end_layout \begin_layout Itemize Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset which returns the status of the device as a formatted ascii string \end_layout \begin_layout Itemize Init \begin_inset Index idx status collapsed \begin_layout Plain Layout Init \end_layout \end_inset which re-initialize a device without changing its network connection \end_layout \begin_layout Standard These commands have already been discussed in \begin_inset CommandInset ref LatexCommand ref reference "Auto_cmd" \end_inset \end_layout \begin_layout Subsection Choosing device state \end_layout \begin_layout Standard The device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset is a number which reflects the availability of the device. To simplify the coding for generic application, a predefined set of states \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset are supported by TANGO. This list has 14 members which are \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout State name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ON \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout OFF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CLOSE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout OPEN \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout INSERT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EXTRACT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MOVING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout STANDBY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout FAULT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout INIT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RUNNING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ALARM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DISABLE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout UNKNOWN \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The names used here have obvious meaning. \end_layout \begin_layout Subsection Device server utilities to ease coding/debugging \end_layout \begin_layout Standard The device server framework supports one set of utilities to ease the process of coding and debugging \begin_inset Index idx status collapsed \begin_layout Plain Layout debug \end_layout \end_inset device server code. This utility is : \end_layout \begin_layout Enumerate The device server verbose \begin_inset Index idx status collapsed \begin_layout Plain Layout verbose \end_layout \end_inset option \end_layout \begin_layout Standard Using this facility avoids the usage of the classical \begin_inset Quotes eld \end_inset #ifdef DEBUG \begin_inset Quotes erd \end_inset style which makes code less readable. \end_layout \begin_layout Subsubsection The device server verbose option \end_layout \begin_layout Standard Each device server supports a verbose \begin_inset Index idx status collapsed \begin_layout Plain Layout verbose \end_layout \end_inset option called \series bold -v \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout -v \end_layout \end_inset . Four verbose levels are defined from 1 to 4. Level 4 is the most talkative one. If you use the -v option without specifying level, level 4 will be assumed. \end_layout \begin_layout Standard Since Tango release 3, a Tango Logging Service has been introduced (detailed in chapter \begin_inset CommandInset ref LatexCommand ref reference "The-Tango-Logging chapter" \end_inset ). This -v option set-up the logging service. If it used, it will automatically add a \emph on console \emph default target to all devices embedded within the device server process. Level 1 and 2 will set the logging level to all devices embedded within the device server to INFO. Level 3 and 4 will set the logging \begin_inset Index idx status collapsed \begin_layout Plain Layout logging \end_layout \end_inset level to all devices embedded within the device server to DEBUG. All messages sent by the API layer are associated to the administration device. \end_layout \begin_layout Subsubsection C++ utilities to ease device server coding \end_layout \begin_layout Standard Some utilities functions have been added in the C++ release to ease Tango device server development. These utilities allow the user to \end_layout \begin_layout Itemize Init a C++ vector from a data of one of the Tango DevVarXXXArray data types \end_layout \begin_layout Itemize Init a data of one of the Tango::DevVarxxxArray data type from a C++ vector \end_layout \begin_layout Itemize Print a data of one of Tango::DevVarxxxArray data type \end_layout \begin_layout Standard They mainly used the \begin_inset Quotes eld \end_inset << \begin_inset Quotes erd \end_inset \begin_inset Index idx status collapsed \begin_layout Plain Layout << \end_layout \end_inset operator overloading features. The following code lines are an example of usage of these utilities. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 vector v1; \end_layout \begin_layout LyX-Code 2 v1.push_back("one"); \end_layout \begin_layout LyX-Code 3 v1.push_back("two"); \end_layout \begin_layout LyX-Code 4 v1.push_back("three"); \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 Tango::DevVarStringArray s; \end_layout \begin_layout LyX-Code 7 s << v1; \end_layout \begin_layout LyX-Code 8 cout << s << endl; \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 vector v2; \end_layout \begin_layout LyX-Code 11 v2 << s; \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 for (int i = 0;i < v2.size();i++) \end_layout \begin_layout LyX-Code 14 cout << "vector element = " << v2[i] << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-4 : Create and Init a C++ string vector \end_layout \begin_layout Standard Line 7 : Init a Tango::DevVarStringArray data from the C++ vector \end_layout \begin_layout Standard Line 8 : Print all the Tango::DevVarStringArray element in one line of code. \end_layout \begin_layout Standard Line 11 : Init a second empty C++ string vector with the content of the Tango::DevVarStringArray \end_layout \begin_layout Standard Line 13-14 : Print vector element \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold Warning \series default : Note that due to a strange behavior of the Windows VC++ compiler compared to other compilers, to use these utilities with the Windows VC++ compiler, you must add the line \begin_inset Quotes eld \end_inset using namespace tango \begin_inset Quotes erd \end_inset at the beginning of your source file. \end_layout \begin_layout Subsection Avoiding name conflicts \end_layout \begin_layout Standard Namespace are used to avoid name conflicts. Each device pattern implementation is defined within its own namespace \begin_inset Index idx status collapsed \begin_layout Plain Layout namespace \end_layout \end_inset . The name of the namespace is the device pattern class name. In our example, the namespace name is \emph on StepperMotor. \end_layout \begin_layout Subsection The device server main function \end_layout \begin_layout Standard A device server main \begin_inset Index idx status collapsed \begin_layout Plain Layout main \end_layout \end_inset function (or method) always follows the same framework. It exactly implements all the action described in chapter \begin_inset CommandInset ref LatexCommand ref reference "Server_startup" \end_inset . Even if it could be always the same, it has not been included in the library because some linkers are perturbed by the presence of two main functions. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 int main(int argc,char *argv[]) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 Tango::Util *tg; \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 try \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 tg = Tango::Util::init(argc,argv); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 tg->server_init(); \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 cout << "Ready to accept request" << endl; \end_layout \begin_layout LyX-Code 16 tg->server_run(); \end_layout \begin_layout LyX-Code 17 } \end_layout \begin_layout LyX-Code 18 catch (bad_alloc) \end_layout \begin_layout LyX-Code 19 { \end_layout \begin_layout LyX-Code 20 cout << "Can't allocate memory!!!" << endl; \end_layout \begin_layout LyX-Code 21 cout << "Exiting" << endl; \end_layout \begin_layout LyX-Code 22 } \end_layout \begin_layout LyX-Code 23 catch (CORBA::Exception &e) \end_layout \begin_layout LyX-Code 24 { \end_layout \begin_layout LyX-Code 25 Tango::Except::print_exception(e); \end_layout \begin_layout LyX-Code 26 \end_layout \begin_layout LyX-Code 27 cout << "Received a CORBA::Exception" << endl; \end_layout \begin_layout LyX-Code 28 cout << "Exiting" << endl; \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 tg->server_cleanup(); \end_layout \begin_layout LyX-Code 32 \end_layout \begin_layout LyX-Code 33 return(0); \end_layout \begin_layout LyX-Code 34 } \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Include the \series bold tango.h \series default file. This file is a master include file. It includes several other files. The list of files included by tango.h can be found in \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset \end_layout \begin_layout Standard Line 11 : Create the instance of the Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset class (a singleton). Passing argc,argv to this method is mandatory because the device server command line is checked when the Tango::Util object is constructed. \end_layout \begin_layout Standard Line 13 : Start all the device pattern creation and initialization with the \emph on server_init() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset \emph default method \end_layout \begin_layout Standard Line 16 : Put the server in a endless waiting loop with the \emph on server_run() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-run \end_layout \end_inset \emph default method. In normal case, the process should never returns from this line. \end_layout \begin_layout Standard Line 18-22 : Catch all exceptions due to memory allocation error, display a message to the user and exit \end_layout \begin_layout Standard Line 23 : Catch all standard TANGO exception which could occur during device pattern creation and initialization \end_layout \begin_layout Standard Line 25 : Print exception parameters \end_layout \begin_layout Standard Line 27-28 : Print an additional message \end_layout \begin_layout Standard Line 31 : Cleanup the server before exiting by calling the \emph on server_cleanup() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-cleanup \end_layout \end_inset \emph default method. \end_layout \begin_layout Subsection The DServer::class_factory method \end_layout \begin_layout Standard As described in chapter \begin_inset CommandInset ref LatexCommand ref reference "DServer_class" \end_inset , C++ device server needs a \emph on class_factory \emph default () method. This method creates all the device pattern implemented in the device server by calling their \emph on init \emph default () \begin_inset Index idx status collapsed \begin_layout Plain Layout init \end_layout \end_inset method. The following is an example of a \emph on class_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout class-factory \end_layout \end_inset \emph default method for a device server with one implementation of the device server pattern for stepper motor device. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 void Tango::DServer::class_factory() \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 add_class(StepperMotor::StepperMotorClass::init("StepperMotor")); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Include the Tango master include file \end_layout \begin_layout Standard Line 2 : Include the steppermotorclass class definition file \end_layout \begin_layout Standard Line 7 : Create the StepperMotorClass singleton by calling its \emph on init \begin_inset Index idx status collapsed \begin_layout Plain Layout init \end_layout \end_inset \emph default method and stores the returned pointer into the DServer object. Remember that all classes for the device pattern implementation for the stepper motor class is defined within a namespace \begin_inset Index idx status collapsed \begin_layout Plain Layout namespace \end_layout \end_inset called \emph on StepperMotor \emph default . \end_layout \begin_layout Subsection Writing the StepperMotorClass class \begin_inset CommandInset label LatexCommand label name "Command fact" \end_inset \end_layout \begin_layout Subsubsection The class declaration file \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 namespace StepperMotor \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 class StepperMotorClass : public Tango::DeviceClass \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 public: \end_layout \begin_layout LyX-Code 9 static StepperMotorClass *init(const char *); \end_layout \begin_layout LyX-Code 10 static StepperMotorClass *instance(); \end_layout \begin_layout LyX-Code 11 ~StepperMotorClass() {_instance = NULL;} \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 protected: \end_layout \begin_layout LyX-Code 14 StepperMotorClass(string &); \end_layout \begin_layout LyX-Code 15 static StepperMotorClass *_instance; \end_layout \begin_layout LyX-Code 16 void command_factory(); \end_layout \begin_layout LyX-Code 17 void attribute_factory(vector &); \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 public: \end_layout \begin_layout LyX-Code 20 void device_factory(const Tango::DevVarStringArray *); \end_layout \begin_layout LyX-Code 21 }; \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 } /* End of StepperMotor namespace */ \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Include the Tango master include file \end_layout \begin_layout Standard Line 3 : This class is defined within the \emph on StepperMotor \emph default namespace \end_layout \begin_layout Standard Line 6 : Class StepperMotorClass inherits from Tango::DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset \end_layout \begin_layout Standard Line 9-10 : Definition of the \emph on init \begin_inset Index idx status collapsed \begin_layout Plain Layout init \end_layout \end_inset \emph default and \emph on instance \begin_inset Index idx status collapsed \begin_layout Plain Layout instance \end_layout \end_inset \emph default methods. These methods are static and can be called even if the object is not already constructed. \end_layout \begin_layout Standard Line 11: The destructor \end_layout \begin_layout Standard Line 14 : The class constructor. It is protected and can't be called from outside the class. Only the \emph on init \emph default method allows a user to create an instance of this class. See \begin_inset CommandInset citation LatexCommand cite key "Patterns" \end_inset to get details about the singleton design pattern. \end_layout \begin_layout Standard Line 15 : The instance pointer. It is static in order to set it to NULL during process initialization phase \end_layout \begin_layout Standard Line 16 : Definition of the \emph on command_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset \emph default method \end_layout \begin_layout Standard Line 17 : Definition of the \emph on attribute_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute-factory \end_layout \end_inset \emph default method \end_layout \begin_layout Standard Line 20 : Definition of the \emph on device_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset \emph default method \end_layout \begin_layout Subsubsection The singleton related methods \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 #include \end_layout \begin_layout LyX-Code 4 #include \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 namespace StepperMotor \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 StepperMotorClass *StepperMotorClass::_instance = NULL; \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 StepperMotorClass::StepperMotorClass(string &s): \end_layout \begin_layout LyX-Code 12 Tango::DeviceClass(s) \end_layout \begin_layout LyX-Code 13 { \end_layout \begin_layout LyX-Code 14 INFO_STREAM << "Entering StepperMotorClass constructor" << endl; \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 INFO_STREAM << "Leaving StepperMotorClass constructor" << endl; \end_layout \begin_layout LyX-Code 17 } \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 StepperMotorClass *StepperMotorClass::init(const char *name) \end_layout \begin_layout LyX-Code 21 { \end_layout \begin_layout LyX-Code 22 if (_instance == NULL) \end_layout \begin_layout LyX-Code 23 { \end_layout \begin_layout LyX-Code 24 try \end_layout \begin_layout LyX-Code 25 { \end_layout \begin_layout LyX-Code 26 string s(name); \end_layout \begin_layout LyX-Code 27 _instance = new StepperMotorClass(s); \end_layout \begin_layout LyX-Code 28 } \end_layout \begin_layout LyX-Code 29 catch (bad_alloc) \end_layout \begin_layout LyX-Code 30 { \end_layout \begin_layout LyX-Code 31 throw; \end_layout \begin_layout LyX-Code 32 } \end_layout \begin_layout LyX-Code 33 } \end_layout \begin_layout LyX-Code 34 return _instance; \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout LyX-Code 36 \end_layout \begin_layout LyX-Code 37 StepperMotorClass *StepperMotorClass::instance() \end_layout \begin_layout LyX-Code 38 { \end_layout \begin_layout LyX-Code 39 if (_instance == NULL) \end_layout \begin_layout LyX-Code 40 { \end_layout \begin_layout LyX-Code 41 cerr << "Class is not initialised !!" << endl; \end_layout \begin_layout LyX-Code 42 exit(-1); \end_layout \begin_layout LyX-Code 43 } \end_layout \begin_layout LyX-Code 44 return _instance; \end_layout \begin_layout LyX-Code 45 } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-4 : include files: the Tango master include file (tango.h), the StepperMot orClass class definition file (steppermotorclass.h) and the StepperMotor class definition file (steppermotor.h) \end_layout \begin_layout Standard Line 6 : Open the \emph on StepperMotor \emph default namespace. \end_layout \begin_layout Standard Line 9 : Initialize the static _instance field of the StepperMotorClass class to NULL \end_layout \begin_layout Standard Line 11-18 : The class constructor. It takes an input parameter which is the controlled device class name. This parameter is passed to the constructor of the DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset class. Otherwise, the constructor does nothing except printing a message \end_layout \begin_layout Standard Line 20-35 : The \emph on init \begin_inset Index idx status collapsed \begin_layout Plain Layout init \end_layout \end_inset \emph default method. This method needs an input parameter which is the controlled device class name (StepperMotor in this case). This method checks is the instance is already constructed by testing the _instance data member. If the instance is not constructed, it creates one. If the instance is already constructed, the method simply returns a pointer to it. \end_layout \begin_layout Standard Line 37-45 : The \emph on instance \emph default method. This method is very similar to the \emph on init \emph default method except that if the instance is not already constructed. the method print a message and abort the process. \end_layout \begin_layout Standard As you can understand, it is not possible to construct more than one instance of the StepperMotorClass (it is a singleton \begin_inset Index idx status collapsed \begin_layout Plain Layout singleton \end_layout \end_inset ) and the \emph on init \emph default method must be called prior to any other method. \end_layout \begin_layout Subsubsection The command_factory method \end_layout \begin_layout Standard Within our example, the stepper motor device supports two commands \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset which are called DevReadPosition and DevReadDirection. These two command takes a Tango::DevLong argument as input and output parameter. The first command is created using the inheritance \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset model and the second command is created using the template \begin_inset Index idx status collapsed \begin_layout Plain Layout template \end_layout \end_inset command model. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 \end_layout \begin_layout LyX-Code 2 void StepperMotorClass::command_factory() \end_layout \begin_layout LyX-Code 3 { \end_layout \begin_layout LyX-Code 4 command_list.push_back(new DevReadPositionCmd("DevReadPosition", \end_layout \begin_layout LyX-Code 5 Tango::DEV_LONG, \end_layout \begin_layout LyX-Code 6 Tango::DEV_LONG, \end_layout \begin_layout LyX-Code 7 "Motor number (0-7)", \end_layout \begin_layout LyX-Code 8 "Motor position")) ; \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 command_list.push_back( \end_layout \begin_layout LyX-Code 11 new TemplCommandInOut \end_layout \begin_layout LyX-Code 12 ((const char *)"DevReadDirection", \end_layout \begin_layout LyX-Code 13 static_cast \end_layout \begin_layout LyX-Code 14 (&StepperMotor::dev_read_direction), \end_layout \begin_layout LyX-Code 15 static_cast \end_layout \begin_layout LyX-Code 16 (&StepperMotor::direct_cmd_allowed)) \end_layout \begin_layout LyX-Code 17 ); \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4 : Creation of one instance of the DevReadPositionCmd class. The class is created with five arguments which are the command name, the command type code for its input and output parameters and two strings which are the command input and output parameters description. The pointer returned by the new C++ keyword is added to the vector of available command. \end_layout \begin_layout Standard Line 10-14 : Creation of the object used for the DevReadDirection command. This command has one input and output parameter. Therefore the created object is an instance of the TemplCommandInOut class. This class is a C++ template class. The first template parameter is the command input parameter type, the second template parameter is the command output parameter type. The second TemplCommandInOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandInOut \end_layout \end_inset class constructor parameter (set at line 13) is a pointer to the method to be executed when the command is requested. A casting is necessary to store this pointer as a pointer to a method of the DeviceImpl class \begin_inset Foot status open \begin_layout Plain Layout The StepperMotor class inherits from the DeviceImpl class and therefore is a DeviceImpl \end_layout \end_inset . The third TemplCommandInOut class constructor parameter (set at line 15) is a pointer to the method to be executed to check if the command is allowed. This is necessary only if the default behavior (command always allowed) does not fulfill the needs. A casting is necessary to store this pointer as a pointer to a method of the DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset class. When a command is created using the template command method, the input and output parameters type are determined from the template C++ class parameter s. \end_layout \begin_layout Subsubsection The device_factory method \end_layout \begin_layout Standard The \emph on device_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout device-factory \end_layout \end_inset \emph default method has one input parameter. It is a pointer to Tango::DevVarStringArray data which is the device name list for this class and the instance of the device server process. This list is fetch from the Tango database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotorClass::device_factory(const Tango::_DevVarStringArray *devlist_ptr) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 for (long i = 0;i < devlist_ptr->length();i++) \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 DEBUG_STREAM << "Device name : " << (*devlist_ptr)[i] << endl; \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 device_list.push_back(new StepperMotor(this,(*devlist_ptr)[i])); 9 \end_layout \begin_layout LyX-Code 10 if (Tango::Util::_UseDb == true) \end_layout \begin_layout LyX-Code 11 export_device(device_list.back()); \end_layout \begin_layout LyX-Code 12 else \end_layout \begin_layout LyX-Code 13 export_device(device_list.back(),(*devlist_ptr[i])); \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4 : A loop for each device \end_layout \begin_layout Standard Line 8 : Create the device object using a StepperMotor class constructor which needs two arguments. These two arguments are a pointer to the StepperMotorClass instance and the device name. The pointer to the constructed object is then added to the device list vector \end_layout \begin_layout Standard Line 10-13 : Export device to the outside world using the \emph on export_device \begin_inset Index idx status collapsed \begin_layout Plain Layout export-device \end_layout \end_inset \emph default method of the DeviceClass class. \end_layout \begin_layout Subsubsection The attribute_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute-factory \end_layout \end_inset method \end_layout \begin_layout Standard The rule of this method is to fulfill a vector of pointer to attributes. A reference to this vector is passed as argument to this method. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotorClass::attribute_factory(vector &att_list) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 att_list.push_back(new PositionAttr()); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 Tango::UserDefaultAttrProp def_prop; \end_layout \begin_layout LyX-Code 6 def_prop.set_label("Set the motor position"); \end_layout \begin_layout LyX-Code 7 def_prop.set_format("scientific;setprecision(4)"); \end_layout \begin_layout LyX-Code 8 Tango::Attr *at = new SetPositionAttr(); \end_layout \begin_layout LyX-Code 9 at->set_default_properties(def_prop); \end_layout \begin_layout LyX-Code 10 att_list.push_back(at); \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 att_list.push_back(new DirectcionAttr()); \end_layout \begin_layout LyX-Code 13 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 3 : Create the PositionAttr class and store the pointer to this object into the attribute pointer vector. \end_layout \begin_layout Standard Line 5-7 : Create a Tango::UserDefaultAttrProp instance and set the label and format properties default values in this object \end_layout \begin_layout Standard Line 8 : Create the SetPositionAttr attribute. \end_layout \begin_layout Standard Line 9 : Set attribute user default value with the \emph on set_default_properties() \begin_inset Index idx status collapsed \begin_layout Plain Layout set-default-properties \end_layout \end_inset \emph default method of the Tango::Attr class. \end_layout \begin_layout Standard Line 10 : Store the pointer to this object into the attribute pointer vector. \end_layout \begin_layout Standard Line 12 : Create the DirectionAttr class and store the pointer to this object into the attribute pointer vector. \end_layout \begin_layout Standard Please, note that in some rare case, it is necessary to add attribute to this list during the device server life cycle. This \emph on attribute_factory() \emph default method is called once during device server start-up. A method \emph on add_attribute() \emph default of the DeviceImpl class allows the user to add a new attribute to the attribute list outside of this \emph on attribute_factory() \emph default method. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for more information on this method. \end_layout \begin_layout Subsection The DevReadPositionCmd class \end_layout \begin_layout Subsubsection The class declaration file \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 namespace StepperMotor \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 class DevReadPositionCmd : public Tango::Command \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 public: \end_layout \begin_layout LyX-Code 9 DevReadPositionCmd(const char *,Tango::CmdArgType, \end_layout \begin_layout LyX-Code 10 Tango::CmdArgType, \end_layout \begin_layout LyX-Code 11 const char *,const char *); \end_layout \begin_layout LyX-Code 12 ~DevReadPositionCmd() {}; \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 virtual bool is_allowed (Tango::DeviceImpl *, const CORBA::Any &); \end_layout \begin_layout LyX-Code 15 virtual CORBA::Any *execute (Tango::DeviceImpl *, const CORBA::Any &); \end_layout \begin_layout LyX-Code 16 }; \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 } /* End of StepperMotor namespace */ \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Include the tango master include file \end_layout \begin_layout Standard Line 3 : Open the \emph on StepperMotor \emph default namespace. \end_layout \begin_layout Standard Line 6 : The DevReadPositionCmd class inherits from the Tango::Command class \end_layout \begin_layout Standard Line 9 : The constructor \end_layout \begin_layout Standard Line 12 : The destructor \end_layout \begin_layout Standard Line 14 : The definition of the \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method. This method is not necessary if the default behavior implemented by the default \emph on is_allowed \emph default method fulfill the requirements. The default behavior is to always allows the command execution (always return true). \end_layout \begin_layout Standard Line 15: The definition of the \emph on execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset \emph default method \end_layout \begin_layout Subsubsection The class constructor \end_layout \begin_layout Standard The class constructor does nothing. It simply invoke the Command \begin_inset Index idx status collapsed \begin_layout Plain Layout Command \end_layout \end_inset constructor by passing it its five arguments which are: \end_layout \begin_layout Enumerate The command name \end_layout \begin_layout Enumerate The command \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset input type code \end_layout \begin_layout Enumerate The command output type code \end_layout \begin_layout Enumerate The command input parameter description \end_layout \begin_layout Enumerate The command output parameter description \end_layout \begin_layout Standard With this 5 parameters command class constructor, the command display level is not specified. Therefore it is set to its default value (OPERATOR). If the command does not have input or output parameter, it is not possible to use the Command class constructor defined with five parameters. In this case, the command constructor execute the Command class constructor with three elements (class name, input type, output type) and set the input or output parameter description fields with the \emph on set_in_type_desc \begin_inset Index idx status collapsed \begin_layout Plain Layout set-in-type-desc \end_layout \end_inset \emph default or \emph on set_out_type_desc \begin_inset Index idx status collapsed \begin_layout Plain Layout set-out-type-desc \end_layout \end_inset \emph default Command class methods. To set the command display level, it is possible to use a 6 parameters constructor or it is also possible to set it in the constructor code with the \emph on set_disp_level \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout set-disp-level \end_layout \end_inset method. Many Command class constructors are defined. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete list. \end_layout \begin_layout Subsubsection The is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset method \end_layout \begin_layout Standard In our example, the DevReadPosition command is allowed only if the device is in the ON state. This method receives two argument which are a pointer to the device object on which the command must be executed and a reference to the command input Any object. This method returns a boolean which must be set to true if the command is allowed. If this boolean is set to false, the DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset \emph on command_handle \emph default r \begin_inset Index idx status collapsed \begin_layout Plain Layout command-handler \end_layout \end_inset method will automatically send an exception to the caller. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 bool DevReadPositionCmd::is_allowed(Tango::DeviceImpl *device, \end_layout \begin_layout LyX-Code 2 const CORBA::Any &in_any) \end_layout \begin_layout LyX-Code 3 { \end_layout \begin_layout LyX-Code 4 if (device->get_state() == Tango::ON) \end_layout \begin_layout LyX-Code 5 return true; \end_layout \begin_layout LyX-Code 6 else \end_layout \begin_layout LyX-Code 7 return false; \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4 : Call the \emph on get_state \emph default method of the DeviceImpl class which simply returns the device state \end_layout \begin_layout Standard Line 5 : Authorize command if the device state is ON \end_layout \begin_layout Standard Line 7 : Refuse command execution in all other cases. \end_layout \begin_layout Subsubsection The execute \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset method \end_layout \begin_layout Standard This method receives two arguments which are a pointer to the device object on which the command must be executed and a reference to the command input Any object. This method returns a pointer to an any object which must be initialized with the data to be returned to the caller. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 CORBA::Any *DevReadPositionCmd::execute( \end_layout \begin_layout LyX-Code 2 Tango::DeviceImpl *device, \end_layout \begin_layout LyX-Code 3 const CORBA::Any &in_any) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 INFO_STREAM << "DevReadPositionCmd::execute(): arrived" << endl; \end_layout \begin_layout LyX-Code 6 Tango::DevLong motor; \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 extract(in_any,motor); \end_layout \begin_layout LyX-Code 9 return insert( \end_layout \begin_layout LyX-Code 10 (static_cast(device))->dev_read_position(motor)) ; \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 8 : Extract incoming data from the input any object using a Command class \emph on extract \emph default helper method. If the type of the data in the Any object is not a Tango::DevLong, the \emph on extract \begin_inset Index idx status collapsed \begin_layout Plain Layout extract \end_layout \end_inset \emph default method will throw an exception to the client. \end_layout \begin_layout Standard Line 9 : Call the stepper motor object method which execute the DevReadPosition command and insert the returned value into an allocated Any object. The Any object allocation is done by the \emph on insert \begin_inset Index idx status collapsed \begin_layout Plain Layout insert \end_layout \end_inset \emph default method which return a pointer to this Any. \end_layout \begin_layout Subsection The PositionAttr class \end_layout \begin_layout Subsubsection The class declaration file \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 namespace StepperMotor \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 class PositionAttr: public Tango::Attr \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 public: \end_layout \begin_layout LyX-Code 11 PositionAttr():Attr("Position", \end_layout \begin_layout LyX-Code 12 Tango::DEV_LONG, \end_layout \begin_layout LyX-Code 13 Tango::READ_WITH_WRITE, \end_layout \begin_layout LyX-Code 14 "SetPosition") {}; \end_layout \begin_layout LyX-Code 15 ~PositionAttr() {}; \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) \end_layout \begin_layout LyX-Code 18 {(static_cast(dev))->read_Position(att);} \end_layout \begin_layout LyX-Code 19 virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) \end_layout \begin_layout LyX-Code 20 {return (static_cast(dev))->is_Position_allowed(ty); } \end_layout \begin_layout LyX-Code 21 }; \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 } /* End of StepperMotor namespace */ \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 #endif // _STEPPERMOTORCLASS_H \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-2 : Include the tango master include file and the steppermotor class definition include file \end_layout \begin_layout Standard Line 4 : Open the \emph on StepperMotor \emph default namespace. \end_layout \begin_layout Standard Line 8 : The PosiitionAttr class inherits from the Tango::Attr class \end_layout \begin_layout Standard Line 11-14 : The constructor with 4 arguments \end_layout \begin_layout Standard Line 15 : The destructor \end_layout \begin_layout Standard Line 17 : The definition of the \emph on read \emph default method. This method forwards the call to a StepperMotor class method called \emph on read_Position() \end_layout \begin_layout Standard Line 19 : The definition of the \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method. This method is not necessary if the default behaviour implemented by the default \emph on is_allowed \emph default method fulfills the requirements. The default behaviour is to always allows the attribute reading (always return true). This method forwards the call to a StepperMotor class method called \emph on is_Position_allowed() \end_layout \begin_layout Subsubsection The class constructor \end_layout \begin_layout Standard The class constructor does nothing. It simply invoke the Attr \begin_inset Index idx status collapsed \begin_layout Plain Layout Attr \end_layout \end_inset constructor by passing it its four arguments which are: \end_layout \begin_layout Enumerate The attribute name \end_layout \begin_layout Enumerate The attribute data type code \end_layout \begin_layout Enumerate The attribute writable type code \end_layout \begin_layout Enumerate The name of the associated write attribute \end_layout \begin_layout Standard With this 4 parameters Attr class constructor, the attribute display level is not specified. Therefore it is set to its default value (OPERATOR). To set the attribute display level, it is possible to use in the constructor code the \emph on set_disp_level \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout set-disp-level \end_layout \end_inset method. Many Attr class constructors are defined. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete list. \end_layout \begin_layout Standard This Position attribute is a scalar attribute. For spectrum attribute, instead of inheriting from the Attr class, the class must inherits from the SpectrumAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout SpectrumAttr \end_layout \end_inset class. Many SpectrumAttr class constructors are defined. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete list. \end_layout \begin_layout Standard For Image attribute, instead of inheriting from the Attr class, the class must inherits from the ImageAttr class. Many ImageAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout ImageAttr \end_layout \end_inset class constructors are defined. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete list. \end_layout \begin_layout Subsubsection The is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset method \end_layout \begin_layout Standard This method receives two argument which are a pointer to the device object to which the attribute belongs to and the type of request (read or write). In the PositionAttr class, this method simply "forwards" the request to a method of the StepperMotor class called \emph on is_Position_allowed() \emph default passing the request type to this method. This method returns a boolean which must be set to true if the attribute is allowed. If this boolean is set to false, the DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset read_attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute \end_layout \end_inset method will automatically send an exception to the caller. \end_layout \begin_layout Subsubsection The read \begin_inset Index idx status collapsed \begin_layout Plain Layout execute \end_layout \end_inset method \end_layout \begin_layout Standard This method receives two arguments which are a pointer to the device object to which the attribute belongs to and a reference to the corresponding attribute object. This method "forwards" the request to a StepperMotor class called \emph on read_Position() \emph default passing it the reference on the attribute object. \end_layout \begin_layout Standard \end_layout \begin_layout Subsection The StepperMotor class \end_layout \begin_layout Subsubsection The class declaration file \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 #define AGSM_MAX_MOTORS 8 // maximum number of motors per device \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 namespace StepperMotor \end_layout \begin_layout LyX-Code 6 { \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 class StepperMotor: public TANGO_BASE_CLASS \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 public : \end_layout \begin_layout LyX-Code 11 StepperMotor(Tango::DeviceClass *,string &); \end_layout \begin_layout LyX-Code 12 StepperMotor(Tango::DeviceClass *,const char *); \end_layout \begin_layout LyX-Code 13 StepperMotor(Tango::DeviceClass *,const char *,const char *); \end_layout \begin_layout LyX-Code 14 ~StepperMotor() {}; \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 DevLong dev_read_position(DevLong); \end_layout \begin_layout LyX-Code 17 DevLong dev_read_direction(DevLong); \end_layout \begin_layout LyX-Code 18 bool direct_cmd_allowed(const CORBA::Any &); \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 virtual Tango::DevState dev_state(); \end_layout \begin_layout LyX-Code 21 virtual Tango::ConstDevString dev_status(); \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 virtual void always_executed_hook(); \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 virtual void read_attr_hardware(vector &attr_list); \end_layout \begin_layout LyX-Code 26 virtual void write_attr_hardware(vector &attr_list); \end_layout \begin_layout LyX-Code 27 \end_layout \begin_layout LyX-Code 28 void read_position(Tango::Attribute &); \end_layout \begin_layout LyX-Code 29 bool is_Position_allowed(Tango::AttReqType req); \end_layout \begin_layout LyX-Code 30 void write_SetPosition(Tango::WAttribute &); \end_layout \begin_layout LyX-Code 31 void read_Direction(Tango::Attribute &); \end_layout \begin_layout LyX-Code 32 \end_layout \begin_layout LyX-Code 33 virtual void init_device(); \end_layout \begin_layout LyX-Code 34 virtual void delete_device(); \end_layout \begin_layout LyX-Code 35 \end_layout \begin_layout LyX-Code 36 void get_device_properties(); \end_layout \begin_layout LyX-Code 37 \end_layout \begin_layout LyX-Code 38 protected : \end_layout \begin_layout LyX-Code 39 long axis[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 40 DevLong position[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 41 DevLong direction[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 42 long state[AGSM_MAX_MOTORS]; \end_layout \begin_layout LyX-Code 43 \end_layout \begin_layout LyX-Code 44 Tango::DevLong *attr_Position_read; \end_layout \begin_layout LyX-Code 45 Tango::DevLong *attr_Direction_read; \end_layout \begin_layout LyX-Code 46 Tango::DevLong attr_SetPosition_write; \end_layout \begin_layout LyX-Code 47 \end_layout \begin_layout LyX-Code 48 Tango::DevLong min; \end_layout \begin_layout LyX-Code 49 Tango::DevLong max; \end_layout \begin_layout LyX-Code 50 \end_layout \begin_layout LyX-Code 51 Tango::DevLong *ptr; \end_layout \begin_layout LyX-Code 52 }; \end_layout \begin_layout LyX-Code 53 \end_layout \begin_layout LyX-Code 54 } /* End of StepperMotor namespace */ \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Include the Tango master include file \end_layout \begin_layout Standard Line 5 : Open the \emph on StepperMotor \emph default namespace. \end_layout \begin_layout Standard Line 8 : The StepperMotor class inherits from a Tango base class \end_layout \begin_layout Standard Line 11-13 : Three different object constructors \end_layout \begin_layout Standard Line 14 : The destructor which calls the \emph on delete_device() \emph default method \end_layout \begin_layout Standard Line 16 : The method to be called for the execution of the DevReadPosition command. This method must be declared as virtual if it is needed to redefine it in a class inheriting from StepperMotor. See chapter \begin_inset CommandInset ref LatexCommand ref reference "Inheriting" \end_inset for more details about inheriting. \end_layout \begin_layout Standard Line 17 : The method to be called for the execution of the DevReadDirection command \end_layout \begin_layout Standard Line 18 : The method called to check if the execution of the DevReadDirection command is allowed. This method is necessary because the DevReadDirection command is created using the template command method and the default behavior is not acceptable \end_layout \begin_layout Standard Line 20 : Redefinition of the \emph on dev_state \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-state \end_layout \end_inset . This method is used by the State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset command \end_layout \begin_layout Standard Line 21 : Redefinition of the \emph on dev_status \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-status \end_layout \end_inset . This method is used by the Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset command \end_layout \begin_layout Standard Line 23 : Redefinition of the \emph on always_executed_hook \begin_inset Index idx status collapsed \begin_layout Plain Layout always-executed-hook \end_layout \end_inset \emph default method. This method is the place to code mandatory action which must be executed prior to any command. \end_layout \begin_layout Standard Line 25-31 : Attribute related methods \end_layout \begin_layout Standard Line 32 : Definition of the \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset \emph default method. \end_layout \begin_layout Standard Line 33 : Definition of the \emph on delete_device \begin_inset Index idx status collapsed \begin_layout Plain Layout delete-device \end_layout \end_inset \emph default method \end_layout \begin_layout Standard Line 35 : Definition of the \emph on get_device_properties \emph default method \end_layout \begin_layout Standard Line 38-50 : Data members. \end_layout \begin_layout Standard Line 43-44 : Pointers to data for readable attributes Position and Direction \end_layout \begin_layout Standard Line 45 : Data for the SetPosition attribute \end_layout \begin_layout Standard Line 47-48 : Data members for the two device properties \end_layout \begin_layout Subsubsection The constructors \end_layout \begin_layout Standard Three constructors are defined here. It is not mandatory to defined three constructors. But at least one is mandatory. The three constructors take a pointer to the StepperMotorClass instance as first parameter \begin_inset Foot status open \begin_layout Plain Layout The StepperMotorClass inherits from the DeviceClass and therefore is a DeviceCla ss \end_layout \end_inset . The second parameter is the device name as a C++ string or as a classical pointer to char array. The third parameter necessary only for the third form of constructor is the device description string passed as a classical pointer to a char array. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 namespace StepperMotor \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 StepperMotor::StepperMotor(Tango::DeviceClass *cl,string &s) \end_layout \begin_layout LyX-Code 8 :TANGO_BASE_CLASS(cl,s.c_str()) \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 init_device(); \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 StepperMotor::StepperMotor(Tango::DeviceClass *cl,const char *s) \end_layout \begin_layout LyX-Code 14 :TANGO_BASE_CLASS(cl,s) \end_layout \begin_layout LyX-Code 15 { \end_layout \begin_layout LyX-Code 16 init_device(); \end_layout \begin_layout LyX-Code 17 } \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 StepperMotor::StepperMotor(Tango::DeviceClass *cl,const char *s,const char *d) \end_layout \begin_layout LyX-Code 20 :TANGO_BASE_CLASS(cl,s,d) \end_layout \begin_layout LyX-Code 21 { \end_layout \begin_layout LyX-Code 22 init_device(); \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 void StepperMotor::init_device() \end_layout \begin_layout LyX-Code 26 { \end_layout \begin_layout LyX-Code 27 cout << "StepperMotor::StepperMotor() create " << device_name << endl; \end_layout \begin_layout LyX-Code 28 \end_layout \begin_layout LyX-Code 29 long i; \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 for (i=0; i< AGSM_MAX_MOTORS; i++) \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 axis[i] = 0; \end_layout \begin_layout LyX-Code 34 position[i] = 0; \end_layout \begin_layout LyX-Code 35 direction[i] = 0; \end_layout \begin_layout LyX-Code 36 } \end_layout \begin_layout LyX-Code 37 \end_layout \begin_layout LyX-Code 38 ptr = new Tango::DevLong[10]; \end_layout \begin_layout LyX-Code 39 \end_layout \begin_layout LyX-Code 40 get_device_properties(); \end_layout \begin_layout LyX-Code 41 } \end_layout \begin_layout LyX-Code 42 \end_layout \begin_layout LyX-Code 43 void StepperMotor::delete_device() \end_layout \begin_layout LyX-Code 44 { \end_layout \begin_layout LyX-Code 45 delete [] ptr; \end_layout \begin_layout LyX-Code 46 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-2 : Include the Tango master include file (tango.h) and the StepperMotor class definition file (steppermotor.h) \end_layout \begin_layout Standard Line 4 : Open the \emph on StepperMotor \emph default namespace \end_layout \begin_layout Standard Line 7-11 : The first form of the class constructor. It execute the Tango base class constructor with the two parameters. Note that the device name passed to this constructor as a C++ string is passed to the Tango::DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset constructor as a classical C string. Then the \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset \emph default method is executed. \end_layout \begin_layout Standard Line 13-17 : The second form of the class constructor. It execute the Tango base class constructor with its two parameters. Then the \emph on init_device \emph default method is executed. \end_layout \begin_layout Standard Line 19-23: The third form of constructor. Again, it execute the Tango base class constructor with its three parameters. Then the \emph on init_device \emph default method is executed. \end_layout \begin_layout Standard Line 25-41 : The \emph on init_device \begin_inset Index idx status collapsed \begin_layout Plain Layout init-device \end_layout \end_inset \emph default method. All the device data initialization is done in this method. The device properties are also retrieved from database with a call to the \emph on get_device_properties \emph default method at line 40. The device data member called \emph on ptr \emph default is initialized with allocated memory at line 38. It is not needed to have this pointer, it has been added only for educational purpose. \end_layout \begin_layout Standard Line 43-46 : The \emph on delete_device \begin_inset Index idx status collapsed \begin_layout Plain Layout delete-device \end_layout \end_inset \emph default method. The rule of this method is to free memory allocated in the \emph on init_device \emph default method. In our case , only the device data member \emph on ptr \emph default is allocated in the \emph on init_device \emph default method. Therefore, its memory is freed at line 45. This method is called by the automatically added Init command before it calls the \emph on init_device \emph default method. It is also called by the device destructor. \end_layout \begin_layout Subsubsection The methods used for the DevReadDirection command \end_layout \begin_layout Standard The DevReadDirection command is created using the template command method. Therefore, there is no specific class needed for this command but only one object of the TemplCommandInOut class. This command needs two methods which are the \emph on dev_read_direction \emph default method and the \emph on direct_cmd_allowed \emph default method. The \emph on direct_cmd_allowed \emph default method defines here implements exactly the same behavior than the default one. This method has been used only for pedagogic issue. The \emph on dev_read_direction \emph default method will be executed by the \emph on execute \emph default method of the TemplCommandInOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandInOut \end_layout \end_inset class. The \emph on direct_cmd_allowed \emph default method will be executed by the \emph on is_allowed \emph default method of the TemplCommandInOut class. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevLong StepperMotor::dev_read_direction(DevLong axis) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 if (axis < 0 || axis > AGSM_MAX_MOTORS) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 WARNING_STREAM << "Steppermotor::dev_read_direction(): axis out of range !"; \end_layout \begin_layout LyX-Code 6 WARNING_STREAM << endl; \end_layout \begin_layout LyX-Code 7 TangoSys_OMemStream o; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 o << "Axis number " << axis << " out of range" << ends; \end_layout \begin_layout LyX-Code 10 throw_exception("StepperMotor_OutOfRange", \end_layout \begin_layout LyX-Code 11 o.str(), \end_layout \begin_layout LyX-Code 12 "StepperMotor::dev_read_direction"); \end_layout \begin_layout LyX-Code 13 } \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 return direction[axis]; \end_layout \begin_layout LyX-Code 16 } \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 bool StepperMotor::direct_cmd_allowed(const CORBA::Any &in_data) \end_layout \begin_layout LyX-Code 20 { \end_layout \begin_layout LyX-Code 21 INFO_STREAM << "In direct_cmd_allowed() method" << endl; \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 return true; \end_layout \begin_layout LyX-Code 24 } \end_layout \begin_layout LyX-Code 25 \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-16 : The \emph on dev_read_direction \emph default method \end_layout \begin_layout Standard Line 5-12 : Throw exception to client if the received axis number is out of range \end_layout \begin_layout Standard Line 7 : A TangoSys_OMemStream is used as stream. The TangoSys_OMemStream has been defined in improve portability across platform. For Unix like operating system, it is a ostrtream type. For operating system with a full implementation of the standard library, it is a ostringstream type. \end_layout \begin_layout Standard Line 19-24 : The \emph on direct_cmd_allowed \emph default method. The command input data is passed to this method in case of it is needed to take the decision. This data is still packed into the CORBA Any object. \end_layout \begin_layout Subsubsection The methods used for the Position attribute \end_layout \begin_layout Standard To enable reading of attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset , the StepperMotor class must re-define two or three methods called \emph on read_attr_hardware \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attr-hardware \end_layout \end_inset (), read_() \begin_inset Index idx status collapsed \begin_layout Plain Layout read-Position \end_layout \end_inset \emph default and if necessary a method called \begin_inset Newline newline \end_inset \emph on is__allowed(). \emph default The aim of the first one is to read the hardware. It will be called only once at the beginning of each read_attribute CORBA call. The second method aim is to build the exact data for the wanted attribute and to store this value into the Attribute object. Special care has been taken in order to minimize the number of data copy and allocation. The data passed to the Attribute object as attribute value is passed using pointers. It must be allocated by the method \begin_inset Foot status open \begin_layout Plain Layout It can also be data declared as object data members or memory declared as static \end_layout \end_inset and the Attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout Attribute \end_layout \end_inset object will not free this memory. Data members called attr__read are foreseen for this usage. The \emph on read_attr_hardware() \emph default method receives a vector of long which are indexes into the main attributes vector of the attributes to be read. The \emph on read_Position() \emph default method receives a reference to the Attribute object. The third method ( \emph on is_Position_allowed() \emph default ) aim is to allow or dis-allow, the attribute reading. In some cases, some attributes can be read only if some conditions are met. If this method returns true, the \emph on read_() \emph default method will be called. Otherwise, an error will be generated for the attribute. This method receives one argument which is an emumeration describing the attribute request type (read or write). In our example, the reading of the Position attribute is allowed only if the device state is ON. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotor::read_attr_hardware(vector &attr_list) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 INFO_STREAM << "In read_attr_hardware for " << attr_list.size(); \end_layout \begin_layout LyX-Code 4 INFO_STREAM << " attribute(s)" << endl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 for (long i = 0;i < attr_list.size();i++) \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 string attr_name; \end_layout \begin_layout LyX-Code 9 attr_name = dev_attr->get_attr_by_ind(attr_list[i]).get_name(); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 if (attr_name == "Position") \end_layout \begin_layout LyX-Code 12 { \end_layout \begin_layout LyX-Code 13 attr_Position_read = &(position[0]); \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 else if (attr_name == "Direction") \end_layout \begin_layout LyX-Code 16 { \end_layout \begin_layout LyX-Code 17 attr_Direction_read = &(direction[0]); \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout LyX-Code 19 } \end_layout \begin_layout LyX-Code 20 } \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 void read_Position(Tango::Attribute &att) \end_layout \begin_layout LyX-Code 23 { \end_layout \begin_layout LyX-Code 24 att.set_value(attr_Position_read); \end_layout \begin_layout LyX-Code 25 } \end_layout \begin_layout LyX-Code 26 \end_layout \begin_layout LyX-Code 27 bool is_Position_allowed(Tango::AttReqType req) \end_layout \begin_layout LyX-Code 28 { \end_layout \begin_layout LyX-Code 29 if (req == Tango::WRITE_REQ) \end_layout \begin_layout LyX-Code 30 return false; \end_layout \begin_layout LyX-Code 31 else \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 if (get_state() == Tango::ON) \end_layout \begin_layout LyX-Code 34 return true; \end_layout \begin_layout LyX-Code 35 else \end_layout \begin_layout LyX-Code 36 return false; \end_layout \begin_layout LyX-Code 37 } \end_layout \begin_layout LyX-Code 38 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 6 : A loop on each attribute to be read \end_layout \begin_layout Standard Line 9 : Get attribute name \end_layout \begin_layout Standard Line 11 : Test on attribute name \end_layout \begin_layout Standard Line 13 : Read hardware (pretty simple in our case) \end_layout \begin_layout Standard Line 24 : Set attribute value in Attribute object using the \emph on set_value() \begin_inset Index idx status collapsed \begin_layout Plain Layout set-value \end_layout \end_inset \emph default method. This method will also initializes the attribute quality factor to Tango::ATTR_V ALID \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-VALID \end_layout \end_inset if no alarm level are defined and will set the attribute returned date. It is also possible to use a method called \emph on set_value_date_quality() \begin_inset Index idx status collapsed \begin_layout Plain Layout set-value-date-quality \end_layout \end_inset \emph default which allows the user to set the attribute quality factor as well as the attribute date. \end_layout \begin_layout Standard Line 33 : Test on device state \end_layout \begin_layout Subsubsection The methods used for the SetPosition attribute \end_layout \begin_layout Standard To enable writing of attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset , the StepperMotor class must re-define one or two methods called \emph on write_() \emph default and if necessary a method called \emph on is__allowed(). \emph default The aim of the first one is to write the hardware. The \emph on write_Position() \emph default method receives a reference to the WAttribute object. The value to write is in this WAttribute object. The third method ( \emph on is_Position_allowed() \emph default ) aim is to allow or dis-allow, the attribute writing. In some cases, some attributes can be write only if some conditions are met. If this method returns true, the \emph on write_() \emph default method will be called. Otherwise, an error will be generated for the attribute. This method receives one argument which is an emumeration describing the attribute request type (read or write). For read/write attribute, this method is the same for reading and writing. The input argument value makes the difference. \end_layout \begin_layout Standard For our example, it is always possible to write the SetPosition attribute. Therefore, the StepperMotor class only defines a \emph on write_SetPosition() \emph default method. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotor::write_SetPosition(Tango::WAttribute &att) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 att.get_write_value(sttr_SetPosition_write); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 DEBUG_STREAM << "Attribute SetPosition value = "; \end_layout \begin_layout LyX-Code 6 DEBUG_STREAM << attr_SetPosition_write << endl; \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 position[0] = attr_SetPosition_write; \end_layout \begin_layout LyX-Code 9 } \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 void StepperMotor::write_attr_hardware(vector &attr_list) \end_layout \begin_layout LyX-Code 12 { \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 3 : Retrieve new attribute value \end_layout \begin_layout Standard Line 5-6 : Send some messages using Tango Logging system \end_layout \begin_layout Standard Line 8 : Set the hardware (pretty simple in our case) \end_layout \begin_layout Standard Line 11 - 14: The write_attr_hardware() method. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard In our case, we don't have to do anything in the \emph on write_attr_hardware() \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attr-hardware \end_layout \end_inset \emph default method. It is coded here just for educational purpose. When itÅ› not needed, this method has a default implementation in the Tango base class and it is not mandatory to declare and defin it in your own Tango class \end_layout \begin_layout Subsubsection Retrieving device properties \end_layout \begin_layout Standard Retrieving properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset is fairly simple with the use of the database object. Each Tango device is an aggregate with a DbDevice object (see figure \begin_inset CommandInset ref LatexCommand ref reference "Dvice pattern figure" \end_inset ). This has been grouped in a method called \emph on get_device_properties \emph default (). The classes and methods of the Dbxxx objects are described in the Tango API documentation. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void DocDs::get_device_property() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DbData data; \end_layout \begin_layout LyX-Code 4 data.push_back(DbDatum("Max")); \end_layout \begin_layout LyX-Code 5 data.push_back(DbDatum("Min")); \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 get_db_device()->get_property(data); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 if (data[0].is_empty()==false) \end_layout \begin_layout LyX-Code 10 data[0] >> max; \end_layout \begin_layout LyX-Code 11 if (data[1].is_empty()==false) \end_layout \begin_layout LyX-Code 12 data[1] >> min; \end_layout \begin_layout LyX-Code 13 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4-5 : Two DbDatum (one per property) are stored into a DbData object \end_layout \begin_layout Standard Line 7 : Call the database to retrieve properties value \end_layout \begin_layout Standard Line 9-10 : If the Max property is defined in the database, extract its value from the DbDatum object and store it in a device data member \end_layout \begin_layout Standard Line 11-12 : If the Min property is defined in the database, extract its value from the DbDatum object and store it in a device data member \end_layout \begin_layout Subsubsection The remaining methods \end_layout \begin_layout Standard The remaining methods are the \emph on dev_state, dev_status, always_executed_hook \emph default , \emph on dev_read_position \emph default and \emph on read_Direction() \emph default methods. The \emph on dev_state \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-state \end_layout \end_inset \emph default method parameters are fixed. It does not receive any input parameter and must return a Tango_DevState data type. The \emph on dev_status \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-status \end_layout \end_inset \emph default parameters are also fixed. It does not receive any input parameter and must return a Tango string. The \emph on always_executed_hook \begin_inset Index idx status collapsed \begin_layout Plain Layout always-executed-hook \end_layout \end_inset \emph default receives nothing and return nothing. The \emph on dev_read_position \emph default method input parameter is the motor number as a long and the returned parameter is the motor position also as a long data type. The \emph on read_Direction() \emph default method is the method for reading the Direction attribute. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevLong StepperMotor::dev_read_position(DevLong axis) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 if (axis < 0 || axis > AGSM_MAX_MOTORS) \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 WARNING_STREAM << "Steppermotor::dev_read_position(): axis out of range !"; \end_layout \begin_layout LyX-Code 7 WARNING_STREAM << endl; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 TangoSys_OMemStream o; \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 o << "Axis number " << axis << " out of range" << ends; \end_layout \begin_layout LyX-Code 12 throw_exception("StepperMotor_OutOfRange", \end_layout \begin_layout LyX-Code 13 o.str(), \end_layout \begin_layout LyX-Code 14 "StepperMotor::dev_read_position"); \end_layout \begin_layout LyX-Code 15 } \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 return position[axis]; \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 void always_executed_hook() \end_layout \begin_layout LyX-Code 21 { \end_layout \begin_layout LyX-Code 22 INFO_STREAM << "In the always_executed_hook method << endl; \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 Tango_DevState StepperMotor::dev_state() \end_layout \begin_layout LyX-Code 26 { \end_layout \begin_layout LyX-Code 27 INFO_STREAM << "In StepperMotor state command" << endl; \end_layout \begin_layout LyX-Code 28 return DeviceImpl::dev_state(); \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 Tango_DevString StepperMotor::dev_status() \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 INFO_STREAM << "In StepperMotor status command" << endl; \end_layout \begin_layout LyX-Code 34 return DeviceImpl::dev_status(); \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout LyX-Code 36 \end_layout \begin_layout LyX-Code 37 void read_Direction(Tango::Attribute att) \end_layout \begin_layout LyX-Code 38 { \end_layout \begin_layout LyX-Code 39 att.set_value(attr_Direction_read); \end_layout \begin_layout LyX-Code 40 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-18 : The \emph on dev_read_position \emph default method \end_layout \begin_layout Standard Line 6-14 : Throw exception to client if the received axis number is out of range \end_layout \begin_layout Standard Line 9 : A TangoSys_OMemStream is used as stream. The TangoSys_OMemStream has been defined in improve portability across platform. For Unix like operating system, it is a ostrtream type. For operating system with a full implementation of the standard library, it is a ostringstream type. \end_layout \begin_layout Standard Line 20-23 : The \emph on always_executed_hook \emph default method. It does nothing. It has been included here only as pedagogic usage. \end_layout \begin_layout Standard Line 25-29 : The \emph on dev_state \emph default method. It does exactly what the default \emph on dev_state \emph default does. It has been included here only as pedagogic usage \end_layout \begin_layout Standard Line 31-35 : The \emph on dev_status \emph default method. It does exactly what the default \emph on dev_statu \emph default s does. It has been included here only as pedagogic usage \end_layout \begin_layout Standard Line 37-40 : The \emph on read_Direction \emph default method. Simply set the Attribute object internal value \end_layout \begin_layout Section Device server under Windows \end_layout \begin_layout Standard Two kind of programs are available under Windows \begin_inset Index idx status collapsed \begin_layout Plain Layout Windows \end_layout \end_inset . These kinds of programs are called console \begin_inset Index idx status collapsed \begin_layout Plain Layout console \end_layout \end_inset application or Windows application. A console application is started from a MS-DOS window and is very similar to classical UNIX program. A Windows application is most of the time not started from a MS-DOS window and is generally a graphical application without standard input/output. Writing a device server in a console application is straight forward following the rules described in the previous sub-chapters. Writing a device server in a Windows application needs some changes detailed in the following sub-chapters. \end_layout \begin_layout Subsection The Tango device server graphical \begin_inset Index idx status collapsed \begin_layout Plain Layout graphical \end_layout \end_inset interface \end_layout \begin_layout Standard Within the Windows operating system, most of the running application has a window user interface. This is also true for the Windows Tango device server. Using or not this interface is up to the device server programmer. The choice is done with an argument to the \emph on server_init \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset () \emph default method of the Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset class. This interface is pretty simple and is based on three windows which are : \end_layout \begin_layout Itemize The device server main window \end_layout \begin_layout Itemize The device server console window \end_layout \begin_layout Itemize The device server help window \end_layout \begin_layout Subsubsection The device server main window \end_layout \begin_layout Standard This window looks like : \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Float figure wide false sideways false status open \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Tango device server main window \end_layout \end_inset \end_layout \begin_layout Plain Layout \begin_inset Graphics filename nt_server/main.ps width 10cm \end_inset \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Four menus are available in this window. The File menu allows the user to exit the device server. The View menu allows you to display/hide the device server console window. The Debug menu allows the user to change the server output verbose \begin_inset Index idx status collapsed \begin_layout Plain Layout verbose \end_layout \end_inset level. All the outputs goes to the console window even if it is hidden. The Help menu displays the help window. The device server name is displayed in the window title. The text displayed at the bottom of the window has a default value (the one displayed in this window dump) but may be changed by the device server programmer using the \emph on set_main_window_text( \begin_inset Index idx status collapsed \begin_layout Plain Layout set-main-window-text \end_layout \end_inset ) \emph default method of the Tango::Util class. If used, this method must be called prior to the call of the \emph on server_init() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset \emph default method. Refer to \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete description of this method. \end_layout \begin_layout Subsubsection The console window \end_layout \begin_layout Standard This window looks like : \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename nt_server/cons.ps width 14cm \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard It simply displays all the logging \emph on \begin_inset Index idx status collapsed \begin_layout Plain Layout logging \end_layout \end_inset \emph default message when a console target is used in the device server. \end_layout \begin_layout Subsubsection The help window \end_layout \begin_layout Standard This window looks like : \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename nt_server/help.ps width 9cm \end_inset \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard This window displays \end_layout \begin_layout Itemize The device server name \end_layout \begin_layout Itemize The Tango library release \end_layout \begin_layout Itemize The Tango IDL definition release \end_layout \begin_layout Itemize The device server release. The device server programmer may set this release number using the \emph on set_server_version() \begin_inset Index idx status collapsed \begin_layout Plain Layout set-server-version \end_layout \end_inset \emph default method of the Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset class. If used, this must be done prior to the call of the \emph on server_init() \emph default method. If the \emph on set_server_version() \emph default method is not used, x.y is displays as version number. Refer to \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for a complete description of this method. \end_layout \begin_layout Subsection MFC device server \end_layout \begin_layout Standard There is no \emph on main \emph default function within a classical MFC \begin_inset Index idx status collapsed \begin_layout Plain Layout MFC \end_layout \end_inset program. Most of the time, your application is represented by one instance of a C++ class which inherits from the MFC CWinApp class. This CWinApp class has several methods that you may overload in your applicatio n class. For a device server to run correctly, you must overload two methods of the CWinApp class. These methods are the \emph on InitInstance() \begin_inset Index idx status collapsed \begin_layout Plain Layout InitInstance \end_layout \end_inset \emph default and \emph on ExitInstance() \begin_inset Index idx status collapsed \begin_layout Plain Layout ExitInstance \end_layout \end_inset \emph default methods. The rule of these methods is obvious following their names. \end_layout \begin_layout Standard \series bold Remember that if the Tango device server graphical user interface is used, you must link your device server with the Tango windows resource \begin_inset Index idx status collapsed \begin_layout Plain Layout resource \end_layout \end_inset file \series default . This is done by adding the Tango resource file to the Project Settings/Link/Inp ut/Object, library modules window in VC++. \end_layout \begin_layout Subsubsection The InitInstance method \end_layout \begin_layout Standard The code to be added here is the equivalent of the code written in a classical \emph on main() \emph default function. Don't forget to add the \emph on tango.h \emph default file in the list of included files. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 BOOL FluidsApp::InitInstance() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 AfxEnableControlContainer(); \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 // Standard initialization \end_layout \begin_layout LyX-Code 6 // If you are not using these features and wish to reduce the size \end_layout \begin_layout LyX-Code 7 // of your final executable, you should remove from the following \end_layout \begin_layout LyX-Code 8 // the specific initialization routines you do not need. \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 #ifdef _AFXDLL \end_layout \begin_layout LyX-Code 11 Enable3dControls(); // Call this when using MFC in a shared DLL \end_layout \begin_layout LyX-Code 12 #else \end_layout \begin_layout LyX-Code 13 Enable3dControlsStatic(); // Call this when linking to MFC statically \end_layout \begin_layout LyX-Code 14 #endif \end_layout \begin_layout LyX-Code 15 Tango::Util *tg; \end_layout \begin_layout LyX-Code 16 try \end_layout \begin_layout LyX-Code 17 { \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 tg = Tango::Util::init(m_hInstance,m_nCmdShow); \end_layout \begin_layout LyX-Code 20 \end_layout \begin_layout LyX-Code 21 tg->server_init(true); \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 tg->server_run(); \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 } \end_layout \begin_layout LyX-Code 26 catch (bad_alloc) \end_layout \begin_layout LyX-Code 27 { \end_layout \begin_layout LyX-Code 28 MessageBox((HWND)NULL,"Memory error","Command line",MB_ICONSTOP); \end_layout \begin_layout LyX-Code 29 return(FALSE); \end_layout \begin_layout LyX-Code 30 } \end_layout \begin_layout LyX-Code 31 catch (Tango::DevFailed &e) \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 MessageBox((HWND)NULL,,e.errors[0].desc.in(),"Command line",MB_ICONST OP); \end_layout \begin_layout LyX-Code 34 return(FALSE); \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout LyX-Code 36 catch (CORBA::Exception &) \end_layout \begin_layout LyX-Code 37 { \end_layout \begin_layout LyX-Code 38 MessageBox((HWND)NULL,"Exception CORBA","Command line",MB_ICONSTOP ); \end_layout \begin_layout LyX-Code 39 return(FALSE); \end_layout \begin_layout LyX-Code 40 } \end_layout \begin_layout LyX-Code 41 \end_layout \begin_layout LyX-Code 42 m_pMainWnd = new CWnd; \end_layout \begin_layout LyX-Code 43 m_pMainWnd->Attach(tg->get_ds_main_window()); \end_layout \begin_layout LyX-Code 44 \end_layout \begin_layout LyX-Code 45 return TRUE; \end_layout \begin_layout LyX-Code 46 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 19 : Initialise Tango system. This method also analises the argument used in command line. \end_layout \begin_layout Standard Line 21 : Create Tango classes requesting the Tango Windows graphical \begin_inset Index idx status collapsed \begin_layout Plain Layout graphical \end_layout \end_inset interface to be used \end_layout \begin_layout Standard Line 23 : Start Network listener. Note that under NT, this call returns in the contrary of UNIX like operating system. \end_layout \begin_layout Standard Line 26-30 : Display a message box in case of memory allocation error and leave method with a return value set to false in order to stop the process \end_layout \begin_layout Standard Line 31-35 : Display a message box in case of error during server initialization phase. \end_layout \begin_layout Standard Line 36-40 : Display a message box in case of error other than memory allocation. Leave method with a return value set to false in order to stop the process. \end_layout \begin_layout Standard Line 37-38 : Create a MFC \begin_inset Index idx status collapsed \begin_layout Plain Layout MFC \end_layout \end_inset main window and attach the Tango graphical interface main window to this MFC window. \end_layout \begin_layout Subsubsection The ExitInstance \begin_inset Index idx status collapsed \begin_layout Plain Layout ExitInstance \end_layout \end_inset method \end_layout \begin_layout Standard This method is called when the application is stopped. For Tango device server, its rule is to destroy the Tango::Util singleton if this one has been correctly constructed. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 int FluidsApp::ExitInstance() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 bool del = true; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 try \end_layout \begin_layout LyX-Code 6 { \end_layout \begin_layout LyX-Code 7 Tango::Util *tg = Tango::Util::instance(); \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout LyX-Code 9 catch(Tango::DevFailed) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 del = false; \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 if (del == true) \end_layout \begin_layout LyX-Code 15 delete (Tango::Util::instance()); \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 return CWinApp::ExitInstance(); \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 7 : Try to retrieve the Tango::Util singleton. If this one has not been constructed correctly, this call will throw an exception. \end_layout \begin_layout Standard Line 9-12 : Catch the exception in case of incomplete Tango::Util singleton construction \end_layout \begin_layout Standard Line 14-15 : Delete the Tango::Util singleton. This will unregister the Tango device server from the Tango database. \end_layout \begin_layout Standard Line 17 : Execute the \emph on ExitInstance \emph default method of the CWinApp class. \end_layout \begin_layout Standard If you don't want to use the Tango device server graphical interface, do not pass any parameter to the \emph on server_init() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset \emph default method and instead of the code display in lines 37 and 38 in the previous example of the \emph on InitInstance() \emph default method, use your own code to initialize your own application. \end_layout \begin_layout Subsubsection Example of how to build a Windows device server MFC based \end_layout \begin_layout Standard This sub-chapter gives an example of what it is needed to do to build a MFC Windows device server. Rather than being a list of actions to strictly follow, this is some general rules of how using VC++ to build a Tango device server using MFC. \end_layout \begin_layout Enumerate Create your device server using Pogo. For a class named MyMotor, the following files will be needed : \emph on class_factory.cpp \emph default , \emph on MyMotorClass.h \emph default , \emph on MyMotorClass.cpp \emph default , \emph on MyMotor.h \emph default and \emph on MyMotor.cpp. \end_layout \begin_layout Enumerate On a Windows computer running VC++, create a new project of type \begin_inset Quotes eld \end_inset MFC app Wizard (exe) \begin_inset Quotes erd \end_inset using static MFC \begin_inset Index idx status collapsed \begin_layout Plain Layout MFC \end_layout \end_inset libs. Ask for a dialog based project without ActiveX controls. \end_layout \begin_layout Enumerate Copy the five files generated by Pogo to the Windows computer and add them to your project \end_layout \begin_layout Enumerate Remove the dialog window files (xxxDlg.cpp and xxxDlg.h), the Resource include file and the resource script file from your project \end_layout \begin_layout Enumerate Add #include as first line of the include files list in \emph on class_factory.cpp \emph default , \emph on MyMotorClass.cpp \emph default and \emph on MyMotor.cpp \emph default file. Also add your own directory and the Tango include directory to the project pre-compiler include directories list. \end_layout \begin_layout Enumerate Enable RTTI in your project settings (see chapter \begin_inset CommandInset ref LatexCommand ref reference "Compiling NT" \end_inset ) \end_layout \begin_layout Enumerate Change your application class: \end_layout \begin_deeper \begin_layout Enumerate Add the definition of an \emph on ExitInstance \emph default method in the declaration file. (xxx.h file) \end_layout \begin_layout Enumerate Remove the include of the dialog window file in the xxx.cpp file and add an include of the Tango master include files (tango.h) \end_layout \begin_layout Enumerate Replace the \emph on InitInstance \emph default () method as described in previous sub-chapter. (xx.cpp file) \end_layout \begin_layout Enumerate Add an \emph on ExitInstance() \emph default method as described in previous sub-chapter (xxx.cpp file) \end_layout \end_deeper \begin_layout Enumerate Add all the libraries needed to compile a Tango device server (see chapter \begin_inset CommandInset ref LatexCommand ref reference "Compiling NT" \end_inset ) and the Tango resource file to the linker Object/Libraries modules. \end_layout \begin_layout Subsection Win32 application \end_layout \begin_layout Standard Even if it is more natural to use the C++ structure of the MFC class to write a Tango device server, it is possible to write a device server as a Win32 \begin_inset Index idx status collapsed \begin_layout Plain Layout Win32 \end_layout \end_inset application. Instead of having a \emph on main() \emph default function as the application entry point, the operating system, provides a \emph on WinMain() \emph default function as the application entry point. Some code must be added to this \emph on WinMain \begin_inset Index idx status collapsed \begin_layout Plain Layout WinMain \end_layout \end_inset \emph default function in order to support Tango device server. Don't forget to add the \emph on tango \emph default . \emph on h \emph default file in the list of included files. If you are using the project files generated by Pogo, don't forget to change the linker SUBSYSTEM option to "Windows" (Under Linker/System in the project properties window). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 int APIENTRY WinMain(HINSTANCE hInstance, \end_layout \begin_layout LyX-Code 2 HINSTANCE hPrevInstance, \end_layout \begin_layout LyX-Code 3 LPSTR lpCmdLine, \end_layout \begin_layout LyX-Code 4 int nCmdShow) \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 MSG msg; \end_layout \begin_layout LyX-Code 7 Tango::Util *tg; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 try \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 tg = Tango::Util::init(hInstance,nCmdShow); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 string txt; \end_layout \begin_layout LyX-Code 14 txt = "Blabla first line \backslash n"; \end_layout \begin_layout LyX-Code 15 txt = txt + "Blabla second line \backslash n"; \end_layout \begin_layout LyX-Code 16 txt = txt + "Blabla third line \backslash n"; \end_layout \begin_layout LyX-Code 17 tg->set_main_window_text(txt); \end_layout \begin_layout LyX-Code 18 tg->set_server_version("2.2"); \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 tg->server_init(true); \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 tg->server_run(); \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 } \end_layout \begin_layout LyX-Code 25 catch (bad_alloc) \end_layout \begin_layout LyX-Code 26 { \end_layout \begin_layout LyX-Code 27 MessageBox((HWND)NULL,"Memory error","Command line",MB_ICONSTOP); \end_layout \begin_layout LyX-Code 28 return (FALSE); \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout LyX-Code 30 catch (Tango::DevFailed &e) \end_layout \begin_layout LyX-Code 31 { \end_layout \begin_layout LyX-Code 32 MessageBox((HWND)NULL,e.errors[0].desc.in(),"Command line",MB_ICONST OP); \end_layout \begin_layout LyX-Code 33 return (FALSE); \end_layout \begin_layout LyX-Code 34 } \end_layout \begin_layout LyX-Code 35 catch (CORBA::Exception &) \end_layout \begin_layout LyX-Code 36 { \end_layout \begin_layout LyX-Code 37 MessageBox((HWND)NULL,"Exception CORBA","Command line",MB_ICONSTO P); \end_layout \begin_layout LyX-Code 38 return(FALSE); \end_layout \begin_layout LyX-Code 39 } \end_layout \begin_layout LyX-Code 40 \end_layout \begin_layout LyX-Code 41 while (GetMessage(&msg, NULL, 0, 0)) \end_layout \begin_layout LyX-Code 42 { \end_layout \begin_layout LyX-Code 43 TranslateMessage(&msg); \end_layout \begin_layout LyX-Code 44 DispatchMessage(&msg); \end_layout \begin_layout LyX-Code 45 } \end_layout \begin_layout LyX-Code 46 \end_layout \begin_layout LyX-Code 47 delete tg; \end_layout \begin_layout LyX-Code 48 \end_layout \begin_layout LyX-Code 49 return msg.wParam; \end_layout \begin_layout LyX-Code 50 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 11 : Create the Tango::Util \begin_inset Index idx status collapsed \begin_layout Plain Layout Util \end_layout \end_inset singleton \end_layout \begin_layout Standard Line 13-18 : Set parameters for the graphical interface \end_layout \begin_layout Standard Line 20 : Initialize Tango device server requesting the display of the graphical interface \end_layout \begin_layout Standard Line 22 : Run the device server \end_layout \begin_layout Standard Line 25-39 : Display a message box for all the kinds of error during Tango device server initialization phase and exit WinMain \begin_inset Index idx status collapsed \begin_layout Plain Layout WinMain \end_layout \end_inset function. \end_layout \begin_layout Standard Line 41-45 : The Windows message loop \end_layout \begin_layout Standard Line 47 : Delete the Tango::Util singleton. This class destructor unregisters the device server from the Tango database. \end_layout \begin_layout Standard \series bold Remember that if the Tango device server graphical user interface is used, you must add the Tango windows resource \begin_inset Index idx status collapsed \begin_layout Plain Layout resource \end_layout \end_inset file \series default \series bold to your project \series default . \end_layout \begin_layout Standard If you don't want to use the tango device server graphical user interface, do not use any parameter in the call of the \emph on server_init() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-init \end_layout \end_inset \emph default method and do not link your device server with the Tango Windows resource file. \end_layout \begin_layout Subsection Device server as service \end_layout \begin_layout Standard With Windows, if you want to have processes which survive to logoff sequence and/or are automatically started during computer startup sequence, you have to write them as service \begin_inset Index idx status collapsed \begin_layout Plain Layout service \end_layout \end_inset . It is possible to write Tango device server as service. You need to \end_layout \begin_layout Enumerate Write a class which inherits from a pre-written Tango class called NTService. This class must have a \emph on start \begin_inset Index idx status collapsed \begin_layout Plain Layout start \end_layout \end_inset \emph default method. \end_layout \begin_layout Enumerate Write a main function following a predefined skeleton. \end_layout \begin_layout Subsubsection The service class \end_layout \begin_layout Standard It must inherits from the \emph on NTService \emph default class and defines a \emph on start \emph default method. The NTService \begin_inset Index idx status collapsed \begin_layout Plain Layout NTService \end_layout \end_inset class must be constructed with one argument which is the device server executable \begin_inset Index idx status collapsed \begin_layout Plain Layout executable \end_layout \end_inset name. The \emph on start \emph default method has three arguments which are the number of arguments passed to the method, the argument list and a reference to an object used to log info in the NT event system. The first two args must be passed to the Tango::Util::init method and the last one is used to log error or info messages. The class definition file looks like \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 class MYService: public Tango::NTService \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 public: \end_layout \begin_layout LyX-Code 7 MYService(char *); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 void start(int,char **,Tango::NTEventLogger *); \end_layout \begin_layout LyX-Code 10 }; \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1-2 : Some include files \end_layout \begin_layout Standard Line 4 : The MYService class inherits from \emph on Tango::NTService \emph default class \end_layout \begin_layout Standard Line 7 : Constructor with one parameter \end_layout \begin_layout Standard Line 9 : The \emph on start() \begin_inset Index idx status collapsed \begin_layout Plain Layout start \end_layout \end_inset \emph default method \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The class source code looks like \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 using namespace std; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 MYService::MYService(char *exec_name):NTService(exec_name) \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 void MYService::start(int argc,char **argv,Tango::NTEventLogger *logger) \end_layout \begin_layout LyX-Code 11 { \end_layout \begin_layout LyX-Code 12 Tango::Util *tg; \end_layout \begin_layout LyX-Code 13 try \end_layout \begin_layout LyX-Code 14 { \end_layout \begin_layout LyX-Code 15 Tango::Util::_service = true; \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 tg = Tango::Util::init(argc,argv); \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 tg->server_init(); \end_layout \begin_layout LyX-Code 20 \end_layout \begin_layout LyX-Code 21 tg->server_run(); \end_layout \begin_layout LyX-Code 22 } \end_layout \begin_layout LyX-Code 23 catch (bad_alloc) \end_layout \begin_layout LyX-Code 24 { \end_layout \begin_layout LyX-Code 25 logger->error("Can't allocate memory to store device object"); \end_layout \begin_layout LyX-Code 26 } \end_layout \begin_layout LyX-Code 27 catch (Tango::DevFailed &e) \end_layout \begin_layout LyX-Code 28 { \end_layout \begin_layout LyX-Code 29 logger->error(e.errors[0].desc.in()); \end_layout \begin_layout LyX-Code 30 } \end_layout \begin_layout LyX-Code 31 catch (CORBA::Exception &) \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 logger->error("CORBA Exception"); \end_layout \begin_layout LyX-Code 34 } \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout Standard \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 6-8 : The MYService class constructor code. \end_layout \begin_layout Standard Line 15 : Set to true the \emph on _service \emph default static variable of the \emph on Tango::Util \emph default class. \end_layout \begin_layout Standard Line 17-21 : Classical Tango device server startup code \end_layout \begin_layout Standard Line 23-34 : Exception management. Please, note that within a service. it is not possible to print data on a console. This method receives a reference to a logger \begin_inset Index idx status collapsed \begin_layout Plain Layout logger \end_layout \end_inset object. This object sends all its output to the Windows event \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset system. It is used to send messages when an exception has occurred. \end_layout \begin_layout Subsubsection The main function \end_layout \begin_layout Standard The main function is used to create one instance of the class describing the service, to check the service option and to run the service. The code looks like : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 #include \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 using namespace std; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 int main(int argc,char *argv[]) \end_layout \begin_layout LyX-Code 8 { \end_layout \begin_layout LyX-Code 9 MYService service(argv[0]); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 int ret; \end_layout \begin_layout LyX-Code 12 if ((ret = service.options(argc,argv)) <= 0) \end_layout \begin_layout LyX-Code 13 return ret; \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 service.run(argc,argv); \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 return 0; \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 9 : Create one instance of the MYService class with the executable name as parameter \end_layout \begin_layout Standard Line 12 : Check service option with the \emph on options() \emph default method inherited from the NTService \begin_inset Index idx status collapsed \begin_layout Plain Layout NTService \end_layout \end_inset class. \end_layout \begin_layout Standard Line 15 : Run the service. The \emph on run() \emph default method is inherited from the NTService class. This method will after some NT initialization sequence execute the user \emph on start() \begin_inset Index idx status collapsed \begin_layout Plain Layout start \end_layout \end_inset \emph default method. \end_layout \begin_layout Subsubsection Service options and messages \end_layout \begin_layout Standard When a Tango device server is written as a Windows service, it supports several new options. These option are linked to Windows service \begin_inset Index idx status collapsed \begin_layout Plain Layout service \end_layout \end_inset usage. \end_layout \begin_layout Standard Before it can be used, a service must be installed. A name and a title is associated to each service. For Tango device server used as service, the service name is build from the executable name followed by the underscore character and the instance name. For example, a device server service executable file named \begin_inset Quotes eld \end_inset opc \begin_inset Quotes erd \end_inset and started with \begin_inset Quotes eld \end_inset fluids \begin_inset Quotes erd \end_inset as instance name, will be named \begin_inset Quotes eld \end_inset opc_fluids \begin_inset Quotes erd \end_inset . The title string is built from the service executable name followed by the sentence \begin_inset Quotes eld \end_inset Tango device server \begin_inset Quotes erd \end_inset and the instance name between parenthesis. In the previous example, the service title will be \begin_inset Quotes eld \end_inset opc Tango device server (fluids) \begin_inset Quotes erd \end_inset . Once a service is installed, you can configure it with the \begin_inset Quotes eld \end_inset Services \begin_inset Quotes erd \end_inset application of the control panel. Services title are displayed by this application and allow the user to select one specific service. Once a service is selected, it is possible to start/stop it and to configure its startup type as manual (with the Services application) or as automatic. When the automatic mode is chosen, the service starts when the computer is started. In this case, the service executable code must resides on the computer local disk. \end_layout \begin_layout Standard Tango device server logs message in the Windows event \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset system when the service is started or stopped. You can see these messages with the \begin_inset Quotes eld \end_inset Event Viewer \begin_inset Quotes erd \end_inset application (Start->Programs->Administrative tools->Event Viewer) and choose the Application events. \end_layout \begin_layout Standard The new options are -i, -s, -u, -h and -d. \end_layout \begin_layout Itemize -i : Install the service \begin_inset Index idx status collapsed \begin_layout Plain Layout service \end_layout \end_inset \end_layout \begin_layout Itemize -s : Install the service and choose the automatic startup mode \end_layout \begin_layout Itemize -u : Un-install the service \end_layout \begin_layout Itemize -dbg : Run in console mode to debug service. The service must have been installed prior to used it. The classical -v device server option can be used with the -d option. \end_layout \begin_layout Standard On the command line, all these options must be used after the device server instance name ( \begin_inset Quotes eld \end_inset opc fluids -i \begin_inset Quotes erd \end_inset to install the service, \begin_inset Quotes eld \end_inset opc fluids -u \begin_inset Quotes erd \end_inset to un-install the service, \begin_inset Quotes eld \end_inset opc fluids -v -d \begin_inset Quotes erd \end_inset to debug the service) \end_layout \begin_layout Subsubsection Tango device server using MFC as Windows service \end_layout \begin_layout Standard If your Tango device server uses MFC \begin_inset Index idx status collapsed \begin_layout Plain Layout MFC \end_layout \end_inset and must be written as a Windows NT service, follow these rules : \end_layout \begin_layout Itemize Don't forget to add the \emph on stdafx.h \emph default file as the first file included in all the source files making the project. \end_layout \begin_layout Itemize Comment out the definition of VC_EXTRALEAN in the \emph on stdafx.h \emph default file. \end_layout \begin_layout Itemize Change the pre-processor definitions, replace _WINDOWS by _CONSOLE \end_layout \begin_layout Itemize Add the /SUBSYSTEM:CONSOLE option in the linker options window of the project settings. \end_layout \begin_layout Itemize Add a call to initialize the MFC ( \emph on AfxWinInit() \emph default ) in the service main function \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 int main(int argc,char *argv[]) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 if (!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0)) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 cerr << "Can't initialise MFC !" << endl; \end_layout \begin_layout LyX-Code 6 return -1; \end_layout \begin_layout LyX-Code 7 } \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 service serv(argv[0]); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 int ret; \end_layout \begin_layout LyX-Code 12 if ((ret = serv.options(argc,argv)) <= 0) \end_layout \begin_layout LyX-Code 13 return ret; \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 serv.run(argc,argv); \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 return 0; \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 3 : The MFC classes are initialized with the \emph on AfxWinInit() \emph default function call. \end_layout \begin_layout Section Compiling, linking and executing a TANGO device server process \begin_inset CommandInset label LatexCommand label name "sec:Compiling,-linking-and" \end_inset \end_layout \begin_layout Subsection Compiling and linking a C++ device server \end_layout \begin_layout Subsubsection On UNIX like operating system \end_layout \begin_layout Paragraph Supported development tools \end_layout \begin_layout Standard The supported compiler for Linux is \series bold gcc \begin_inset Index idx status collapsed \begin_layout Plain Layout gcc \end_layout \end_inset \series default release 3.3 and above. Please, note that to debug a Tango device server running under Linux \begin_inset Index idx status collapsed \begin_layout Plain Layout Linux \end_layout \end_inset , \series bold gdb \begin_inset Index idx status collapsed \begin_layout Plain Layout gdb \end_layout \end_inset \series default release 7 and above is needed in order to correctly handle threads. \end_layout \begin_layout Paragraph Compiling \begin_inset Index idx status collapsed \begin_layout Plain Layout compiling \end_layout \end_inset \end_layout \begin_layout Standard TANGO for C++ uses omniORB (release 4) as underlying CORBA Object Request Broker \begin_inset CommandInset citation LatexCommand cite key "OOC page" \end_inset and starting with Tango 8, the ZMQ library. To compile a TANGO device server, your include search path must be set to : \end_layout \begin_layout Itemize The omniORB include directory \end_layout \begin_layout Itemize The ZMQ \begin_inset Index idx status collapsed \begin_layout Plain Layout ZMQ \end_layout \end_inset include directory \end_layout \begin_layout Itemize The Tango include directory \end_layout \begin_layout Itemize Your development directory \end_layout \begin_layout Paragraph Linking \begin_inset Index idx status collapsed \begin_layout Plain Layout linking \end_layout \end_inset \end_layout \begin_layout Standard To build a running device server process, you need to link your code with several libraries. Nine of them are always the same whatever the operating system used is. These nine libraries are: \end_layout \begin_layout Itemize The Tango libraries (called \series bold libtango \series default and \series bold liblog4tango \series default ) \end_layout \begin_layout Itemize Three omniORB \begin_inset Index idx status collapsed \begin_layout Plain Layout omniORB \end_layout \end_inset package libraries (called \series bold libomniORB4 \series default , \series bold libomniDynamic4 \series default and \series bold libCOS4) \end_layout \begin_layout Itemize The omniORB threading library (called \series bold libomnithread \series default ) \end_layout \begin_layout Itemize The ZMQ library (callled \series bold libzmq \series default ) \end_layout \begin_layout Standard On top of that, you need additional libraries depending on the operating system : \end_layout \begin_layout Itemize For Linux, add the posix thread library ( \series bold libpthread \series default ) \end_layout \begin_layout Standard The following table summarizes the necessary options to compile a Tango C++ device server. Please, note that starting with Tango 8 and for gcc release 4.3 and later, some C++11 \begin_inset Index idx status collapsed \begin_layout Plain Layout C++11 \end_layout \end_inset code has been used. This requires the compiler option "-std=c++0x". Obviously, the options -I and -L must be updated to reflect your file system organization. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Operating system \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Compiling option \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Linking option \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Linux gcc \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -D_REENTRANT -std=c++0x -I.. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout -L.. -ltango -llog4tango -lomniORB4 -lomniDynamic4 -lCOS4 -lomnithread -lzmq -lpthread \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The following is an example of a Makefile for Linux. Obviously, all the paths are set to the ESRF file system structure. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 # \end_layout \begin_layout LyX-Code 2 # Makefile to generate a Tango server \end_layout \begin_layout LyX-Code 3 # \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 CC = c++ \end_layout \begin_layout LyX-Code 6 BIN_DIR = ubuntu1104 \end_layout \begin_layout LyX-Code 7 TANGO_HOME = /segfs/tango \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 INCLUDE_DIRS = -I $(TANGO_HOME)/include/$(BIN_DIR) -I . \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 LIB_DIRS = -L $(TANGO_HOME)/lib/$(BIN_DIR) \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 CXXFLAGS = -D_REENTRANT -std=c++0x $(INCLUDE_DIRS) \end_layout \begin_layout LyX-Code 16 LFLAGS = $(LIB_DIRS) -ltango \backslash \end_layout \begin_layout LyX-Code 17 -llog4tango \backslash \end_layout \begin_layout LyX-Code 18 -lomniORB4 \backslash \end_layout \begin_layout LyX-Code 19 -lomniDynamic4 \backslash \end_layout \begin_layout LyX-Code 20 -lCOS4 \backslash \end_layout \begin_layout LyX-Code 21 -lomnithread \backslash \end_layout \begin_layout LyX-Code 22 -lzmq \backslash \end_layout \begin_layout LyX-Code 23 -lpthread \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 \end_layout \begin_layout LyX-Code 26 SVC_OBJS = main.o \backslash \end_layout \begin_layout LyX-Code 27 ClassFactory.o \backslash \end_layout \begin_layout LyX-Code 28 SteppermotorClass.o \backslash \end_layout \begin_layout LyX-Code 29 Steppermotor.o \backslash \end_layout \begin_layout LyX-Code 30 SteppermotorStateMachine.o \end_layout \begin_layout LyX-Code 31 \end_layout \begin_layout LyX-Code 32 \end_layout \begin_layout LyX-Code 33 .SUFFIXES: .o .cpp \end_layout \begin_layout LyX-Code 34 .cpp.o: \end_layout \begin_layout LyX-Code 35 $(CC) $(CXXFLAGS) -c $< \end_layout \begin_layout LyX-Code 36 \end_layout \begin_layout LyX-Code 37 \end_layout \begin_layout LyX-Code 38 all: StepperMotor \end_layout \begin_layout LyX-Code 39 \end_layout \begin_layout LyX-Code 40 StepperMotor: $(SVC_OBJS) \end_layout \begin_layout LyX-Code 41 $(CC) $(SVC_OBJS) -o $(BIN_DIR)/StepperMotor $(LFLAGS) \end_layout \begin_layout LyX-Code 42 \end_layout \begin_layout LyX-Code 43 clean: \end_layout \begin_layout LyX-Code 44 rm -f *.o core \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \end_layout \begin_layout Standard Line 5-7 : Define Makefile macros \end_layout \begin_layout Standard Line 9-10 : Set the include file search path \end_layout \begin_layout Standard Line 12 : Set the linker library search path \end_layout \begin_layout Standard Line 15 : The compiler option setting \end_layout \begin_layout Standard Line 16-23 : The linker option setting \end_layout \begin_layout Standard Line 26-30 : All the object files needed to build the executable \end_layout \begin_layout Standard Line 33-35 : Define rules to generate object files \end_layout \begin_layout Standard Line 38 : Define a \begin_inset Quotes eld \end_inset all \begin_inset Quotes erd \end_inset dependency \end_layout \begin_layout Standard Line 40-41 : How to generate the StepperMotor device server executable \end_layout \begin_layout Standard Line 43-44 : Define a \begin_inset Quotes eld \end_inset clean \begin_inset Quotes erd \end_inset dependency \end_layout \begin_layout Subsubsection On Windows using Visual Studio \begin_inset CommandInset label LatexCommand label name "Compiling NT" \end_inset \end_layout \begin_layout Standard Supported Windows \begin_inset Index idx status collapsed \begin_layout Plain Layout Windows \end_layout \end_inset compiler for Tango is Visual Studio 2008 (VC 9), Visual Studio 2010 (VC10) and Visual Studio 2013 (VC12). Most problems in building a Windows device server revolve around the /M compiler switch family. This switch family controls which run-time library names are embedded in the object files, and consequently which libraries are used during linking \begin_inset Index idx status collapsed \begin_layout Plain Layout linking \end_layout \end_inset . Attempt to mix and match compiler settings and libraries can cause link error and even if successful, may produce undefined run-time behavior. \end_layout \begin_layout Standard Selecting the correct /M switch in Visual Studio is done through a dialog box. To open this dialog box, click on the \begin_inset Quotes eld \end_inset Project \begin_inset Quotes erd \end_inset menu (once the correct project is selected in the Solution Explorer window) and select the \begin_inset Quotes eld \end_inset Properties \begin_inset Quotes erd \end_inset option. To change the compiler switch open the \begin_inset Quotes eld \end_inset C/C++ \begin_inset Quotes erd \end_inset tree and select \begin_inset Quotes eld \end_inset Code Generation \begin_inset Quotes erd \end_inset . The following options are supported. \end_layout \begin_layout Itemize Multithreaded = /MT \end_layout \begin_layout Itemize Multithreaded DLL = /MD \end_layout \begin_layout Itemize Debug Multithreaded = /MTd \end_layout \begin_layout Itemize Debug Multithreaded DLL = /MDd \end_layout \begin_layout Standard Compiling a file with a value of the /M switch family will impose at link phase the use of libraries also compiled with the same value of the /M switch family. If you compiled your source code with the /MT option (Multithreaded), you must link it with libraries also compiled with the /MT option. \end_layout \begin_layout Standard On both 32 or 64 bits computer, omniORB and TANGO relies on the preprocessor identifier \series bold WIN32 \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout WIN32 \end_layout \end_inset being defined in order to configure itself. If you build an application using static libraries (option /MT or /MTd), you must add \series bold _WINSTATIC \series default to the list of the preprocessor identifiers. If you build an application using DLL \begin_inset Index idx status collapsed \begin_layout Plain Layout DLL \end_layout \end_inset (option /MD or /MDd), you must add \series bold LOG4TANGO_HAS_DLL \series default and \series bold TANGO_HAS_DLL \series default to the list of preprocessor identifiers. \end_layout \begin_layout Standard To build a running device server process, you need to link your code with several libraries on top of the Windows libraries. These libraries are: \end_layout \begin_layout Itemize The Tango libraries (called \series bold tango.lib \series default and \series bold log4tango.lib \series default or \series bold tangod.lib \series default and \series bold log4tangod.lib \series default for debug mode) \end_layout \begin_layout Itemize The omniORB \begin_inset Index idx status collapsed \begin_layout Plain Layout omniORB \end_layout \end_inset package libraries (see next table) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Compile mode \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Libraries \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Debug Multithreaded \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout omniORB4d.lib, omniDynamic4d.lib, omnithreadd.lib and COS4d.lib \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Multithreaded \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout omniORB4.lib, omniDynamic4.lib, omnithread.lib and COS4.lib \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Debug Multithreaded DLL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout omniORB420_rtd.lib, omniDynamic420_rtd.lib, omnithread40_rtd.lib, \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and COS420_rtd.lib \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Multithreaded DLL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout omniORB420_rt.lib, omniDynamic420_rt.lib, omnithread40_rt.lib \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and COS420_rt.lib \end_layout \end_inset \end_inset \end_layout \begin_layout Itemize The ZMQ library ( \series bold zmq.lib \series default or \series bold zmqd.lib \series default for debug mode) \end_layout \begin_layout Itemize Windows network libraries ( \series bold mswsock.lib \series default and \series bold ws2_32.lib \series default ) \end_layout \begin_layout Itemize Windows graphic library ( \series bold comctl32.lib \series default ) \end_layout \begin_layout Standard To add these libraries in Visual Studio, open the project property pages dialog box and open the \begin_inset Quotes eld \end_inset Link \begin_inset Quotes erd \end_inset tree. Select \begin_inset Quotes eld \end_inset Input \begin_inset Quotes erd \end_inset and add these library names to the list of library in the \begin_inset Quotes eld \end_inset Additional Dependencies \begin_inset Quotes erd \end_inset box. \end_layout \begin_layout Standard The \begin_inset Quotes eld \end_inset Win32 Debug \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset Win32 Release \begin_inset Quotes erd \end_inset configuration that you change within the "Configuration Manager" window changes the /M switch compiler. For instance, if you select a \begin_inset Quotes eld \end_inset Win32 Debug \begin_inset Quotes erd \end_inset configuration in a "non-DLL" project, use the omniORB4d.lib, omniDynamic4d.lib and omnithreadd.lib libraries plus the tangod.lib, log4tangod.lib and zmqd.lib libraries. If you select the \begin_inset Quotes eld \end_inset Win32 Release \begin_inset Quotes erd \end_inset configuration, use the omniORB4.lib, omniDynamic4.lib and omnithread.lib libraries plus the tango.lib, log4tango.lib and zmq.lib libraries. \end_layout \begin_layout Standard \series bold WARNING \series default : In some cases, the Microsoft Visual Studio wizard used during project creation generates one include file called \emph on Stdafx.h \emph default . If this file itself includes windows.h file, you have to add the preprocessor macro _WIN32_WINNT \begin_inset Index idx status collapsed \begin_layout Plain Layout -WIN32-WINNT \end_layout \end_inset and set it to 0x0500. \end_layout \begin_layout Subsection Running a C++ device server \begin_inset CommandInset label LatexCommand label name "Env variable" \end_inset \end_layout \begin_layout Standard To run a C++ Tango device server, you must set an environment variable. This environment variable is called \series bold TANGO_HOST \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-HOST \end_layout \end_inset \series default and has a fixed syntax which is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset TANGO_HOST=: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset The host field is the host name where the TANGO database device server is running. The port field is the port number on which this server is listening. For instance, a valid syntax is TANGO_HOST=dumela:10000. For UNIX like operating system, setting environment variable is possible with the \emph on export \emph default or \emph on setenv \emph default command depending on the shell used. For Windows, setting environment variable is possible with the \begin_inset Quotes eld \end_inset Environment \begin_inset Quotes erd \end_inset tab of the \begin_inset Quotes eld \end_inset System \begin_inset Quotes erd \end_inset application in the control panel. \end_layout \begin_layout Standard If you need to start a Tango device server on a pre-defined port \begin_inset Index idx status collapsed \begin_layout Plain Layout port \end_layout \end_inset (For Tango database device server or device server without database usage), you must use one of the underlying ORB option \emph on endPoint \emph default like \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset myserver myinstance_name -ORBendPoint giop:tcp:: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Section Advanced programming techniques \end_layout \begin_layout Standard The basic techniques for implementing device server pattern are required by each device server programmer. In certain situations, it is however necessary to do things out of the ordinary. This chapter will look into programming techniques which permit the device server serve more than simply the network. \end_layout \begin_layout Subsection Receiving signal \end_layout \begin_layout Standard It is \series bold UNSAFE \series default to use any CORBA call in a signal handler. It is also UNSAFE to use some system calls in a signal handler. Tango device server solved this problem by using threads \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset . A specific thread is started to handle signals \begin_inset Index idx status collapsed \begin_layout Plain Layout signal \end_layout \end_inset . Therefore, every Tango device server is automatically a threaded process. This allows the programmer to write the code which must be executed when a signal is received as ordinary code. All device server threads masks all signals except the specific signal thread which is permanently waiting for signal. If a signal is sent to a device server process, only the signal thread will receive it because it is the single thread which does not mask signals. \end_layout \begin_layout Standard Nevertheless, signal management is not trivial and some care have to be taken. The signal management differs from operating system to operating system. It is not recommended that you install your own signal routine using any of the signal routines provided by the operating system calls or library. \end_layout \begin_layout Subsubsection Using signal \end_layout \begin_layout Standard It is possible for C++ device server to receive signals from drivers or other processes. The TDSOM supports receiving signal at two levels: the device level and the class level. Supporting signal at the device level means that it is possible to specify interest into receiving signal on a device basis. This feature is supported via three methods defined in the DeviceImpl \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceImpl \end_layout \end_inset class. These methods are called \emph on register_signal \emph default , \emph on unregister_signal \emph default and s \emph on ignal_handler \emph default . \end_layout \begin_layout Standard The \series bold \emph on register_signal \begin_inset Index idx status collapsed \begin_layout Plain Layout register-signal \end_layout \end_inset \series default \emph default method has one parameter which is the signal number. This method informs the device server signal system that the device want to be informed when the signal passed as parameter is received by the process. There is a special case for Linux as explained in the previous sub-chapter. It is possible to register a signal to be executed in the a signal handler context (with all its restrictions). This is done with a second parameter to this \emph on register_signal \emph default method. This second parameter is simply a boolean data. If it is true, the signal_handler will be executed in a signal handler context in the device server main thread. A default value (false) has been defined for this parameter. \end_layout \begin_layout Standard The \series bold \emph on unregister_signal \begin_inset Index idx status collapsed \begin_layout Plain Layout unregister-signal \end_layout \end_inset \series default \emph default method also have an input parameter which is the signal number. This method removes the device from the list of object which should be warned when the signal is received by the process. \end_layout \begin_layout Standard The \series bold \emph on signal_handler \begin_inset Index idx status collapsed \begin_layout Plain Layout signal-handler \end_layout \end_inset \series default \emph default method is the method which is triggered when a signal is received if the corresponding \emph on register_signal \emph default has been executed. This method is defined as virtual and can be redefined by the user. It has one input argument which is the signal number. \end_layout \begin_layout Standard The same three methods also exist in the DeviceClass \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceClass \end_layout \end_inset class. Their action and their usage are similar to the DeviceImpl class methods. Installing a signal at the class level does not mean that all the device belonging to this class will receive the signal. This only means that the \emph on signal_handler \emph default method of the DeviceClass instance will be executed. This is useful if an action has to be executed once for a class of devices when a signal is received. \end_layout \begin_layout Standard The following code is an example with our stepper motor device server configured via the database to serve three motors. These motors have the following names : id04/motor/01, id04/motor/02 and id04/motor/03. The signal SIGALRM (alarm signal) must be propagated only to the motor number 2 (id04/motor/02) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotor::init_device() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 cout << "StepperMotor::StepperMotor() create motor " << dev_name << endl; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 long i; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 for (i=0; i< AGSM_MAX_MOTORS; i++) \end_layout \begin_layout LyX-Code 8 { \end_layout \begin_layout LyX-Code 9 axis[i] = 0; \end_layout \begin_layout LyX-Code 10 position[i] = 0; \end_layout \begin_layout LyX-Code 11 direction[i] = 0; \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 if (dev_name == "id04/motor/02") \end_layout \begin_layout LyX-Code 15 register_signal(SIGALRM); \end_layout \begin_layout LyX-Code 16 } \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 StepperMotor::~StepperMotor() \end_layout \begin_layout LyX-Code 19 { \end_layout \begin_layout LyX-Code 20 unregister_signal(SIGALRM); \end_layout \begin_layout LyX-Code 21 } \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 void StepperMotor::signal_handler(long signo) \end_layout \begin_layout LyX-Code 24 { \end_layout \begin_layout LyX-Code 25 INFO_STREAM << "Inside signal handler for signal " << signo << endl; \end_layout \begin_layout LyX-Code 26 \end_layout \begin_layout LyX-Code 27 // Do what you want here \end_layout \begin_layout LyX-Code 28 \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The \emph on init_device \emph default method is modified. \end_layout \begin_layout Standard Line 14-15 : The device name is checked and if it is the correct name, the device is registered in the list of device wanted to receive the SIGALARM signal. \end_layout \begin_layout Standard The destructor is also modified \end_layout \begin_layout Standard Line 20 : Unregister the device from the list of devices which should receives the SIGALRM signal. Note that unregister a signal for a device which has not previously registered its interest for this signal does nothing. \end_layout \begin_layout Standard The \emph on signal_handler \emph default method is redefined \end_layout \begin_layout Standard Line 25 : Print signal number \end_layout \begin_layout Standard Line 27 : Do what you have to do when the signal SIGALRM is received. \end_layout \begin_layout Standard If all devices must be warned when the device server process receives the signal SIGALRM, removes line 14 in the \emph on init_device \emph default method. \end_layout \begin_layout Subsubsection Exiting a device server gracefully \end_layout \begin_layout Standard A device server \begin_inset Index idx status collapsed \begin_layout Plain Layout server \end_layout \end_inset has to exit \begin_inset Index idx status collapsed \begin_layout Plain Layout exit \end_layout \end_inset gracefully by unregistering itself from the database. The necessary action to gracefully exit are automatically executed on reception of the following signal \begin_inset Index idx status collapsed \begin_layout Plain Layout signal \end_layout \end_inset : \end_layout \begin_layout Itemize SIGINT, SIGTERM and SIGQUIT for device server running on Linux \end_layout \begin_layout Itemize SIGINT, SIGTERM, SIGABRT and SIGBREAK for device server running on Windows \end_layout \begin_layout Standard This does not prevents device server to also register interest at device or class levels for those signals. The user installed \emph on signal_handler \begin_inset Index idx status collapsed \begin_layout Plain Layout signal-handler \end_layout \end_inset \emph default method will first be called before the graceful exit. \end_layout \begin_layout Subsection Inheriting \begin_inset CommandInset label LatexCommand label name "Inheriting" \end_inset \end_layout \begin_layout Standard This sub-chapter details how it is possible to inherit \begin_inset Index idx status collapsed \begin_layout Plain Layout inherit \end_layout \end_inset from an existing device pattern implementation. As the device pattern includes more than a single class, inheriting from an existing device pattern needs some explanations. \end_layout \begin_layout Standard Let us suppose that the existing device pattern implementation is for devices of class A. This means that classes A and AClass already exists plus classes for all commands offered by device of class A. One new device pattern \begin_inset Index idx status collapsed \begin_layout Plain Layout pattern \end_layout \end_inset implementation for device of class B must be written with all the features offered by class A plus some new one. This is easily done with the inheritance. Writing a device pattern implementation for device of class B which inherits from device of class A means : \end_layout \begin_layout Itemize Write the BClass class \end_layout \begin_layout Itemize Write the B class \end_layout \begin_layout Itemize Write B class specific commands \end_layout \begin_layout Itemize Eventually redefine A class commands \end_layout \begin_layout Standard The miscellaneous code fragments given below detail only what has to be updated to support device pattern inheritance \end_layout \begin_layout Subsubsection Writing the BClass \end_layout \begin_layout Standard As you can guess, BClass has to inherit from AClass. The \emph on command_factory \begin_inset Index idx status collapsed \begin_layout Plain Layout command-factory \end_layout \end_inset \emph default method must also be adapted. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 namespace B \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 class BClass : public A::AClass \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 ..... \end_layout \begin_layout LyX-Code 7 } \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 BClass::command_factory() \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 A::AClass::command_factory(); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 command_list.push_back(....); \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 } /* End of B namespace */ \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Open the B namespace \end_layout \begin_layout Standard Line 4 : BClass inherits from AClass which is defined in the A namespace. \end_layout \begin_layout Standard Line 11 : Only the \emph on command_factory \emph default method of the BClass will be called at start-up. To create the AClass commands, the \emph on command_factory \emph default method of the AClass must also be executed. This is the reason of the line \end_layout \begin_layout Standard Line 13 : Create BClass commands \end_layout \begin_layout Subsubsection Writing the B class \end_layout \begin_layout Standard As you can guess, B has to inherits \begin_inset Index idx status collapsed \begin_layout Plain Layout inherit \end_layout \end_inset from A. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 namespace B \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 class B : public A:A \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 ..... \end_layout \begin_layout LyX-Code 7 }; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 B::B(Tango::DeviceClass *cl,const char *s):A::A(cl,s) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 .... \end_layout \begin_layout LyX-Code 12 init_device(); \end_layout \begin_layout LyX-Code 13 } \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 void B::init_device() \end_layout \begin_layout LyX-Code 16 { \end_layout \begin_layout LyX-Code 17 .... \end_layout \begin_layout LyX-Code 18 } \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 } /* End of B namespace */ \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : Open the B namespace. \end_layout \begin_layout Standard Line 4 : B inherits from A which is defined in the A namespace \end_layout \begin_layout Standard Line 9 : The B constructor calls the right A constructor \end_layout \begin_layout Subsubsection Writing B class specific command \end_layout \begin_layout Standard Noting special here. Write these classes as usual \end_layout \begin_layout Subsubsection Redefining A class command \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset \end_layout \begin_layout Standard It is possible to redefine a command which already exist in class A \series bold only if the command is created \series default \series bold using the inheritance \begin_inset Index idx status collapsed \begin_layout Plain Layout inheritance \end_layout \end_inset model \series default (but keeping its input and output argument types). The method which really execute the class A command is a method implemented in the A class. This method must be defined as \series bold virtual. \series default In class B, you can redefine the method executing the command and implement it following the needs of the B class. \end_layout \begin_layout Standard \end_layout \begin_layout Subsection Using another device pattern implementation within the same server \end_layout \begin_layout Standard It is often necessary that inside the same device server \begin_inset Index idx status collapsed \begin_layout Plain Layout server \end_layout \end_inset , a method executing a command needs a command of another class to be executed. For instance, a device pattern implementation for a device driven by a serial line class can use the command offered by a serial line class embedded within the same device server process. To execute one of the command (or any other CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset operations/attributes) of the serial line class, just call it as a normal client will do by using one instance of the DeviceProxy class \emph on . \emph default The ORB will recognize that all the devices are inside the same process and will execute calls as a local \begin_inset Index idx status collapsed \begin_layout Plain Layout local \end_layout \end_inset calls. To create the DeviceProxy class instance, the only thing you need to know is the name of the device you gave to the serial line device. Retrieving this could be easily done by a Tango device property. The DeviceProxy class is fully described in Tango Application Programming Interface (API) reference WEB pages \end_layout \begin_layout Subsection Device pipe \begin_inset Index idx status open \begin_layout Plain Layout pipe \end_layout \end_inset \end_layout \begin_layout Standard What a Tango device pipe is has been defined in the Chapter 3 about device server model. How you read or write a pipe in a client software is documented in chapter 4 about the Tango API. In this section, we describe how you can read/write into/from a device pipe on the server side (In a Tango class with pipe). \end_layout \begin_layout Subsubsection Client reading a pipe \end_layout \begin_layout Standard When a client reads a pipe, the following methods are executed in the Tango class: \end_layout \begin_layout Enumerate The \emph on always_executed_hook() \emph default method. \end_layout \begin_layout Enumerate A method called \emph on is__allowed() \emph default . The rule of this method is to allow (or disallow) the next method to be executed. It is usefull for device with some pipes which can be read only in some precise conditions. It has one parameter which is the request type (read or write) \end_layout \begin_layout Enumerate A method called \emph on read_() \emph default . The aim of this method is to store the pipe data in the pipe object. It has one parameter which is a reference to the Pipe object to be read. \end_layout \begin_layout Standard The figure \begin_inset CommandInset ref LatexCommand ref reference "r_pipe_timing_fig-1" \end_inset is a drawing of these method calls sequencing for our class StepperMotor with one pipe named DynData. \begin_inset Float figure placement H wide false sideways false status collapsed \begin_layout Plain Layout \align center \begin_inset Graphics filename r_pipe.eps scale 70 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Read pipe sequencing \begin_inset CommandInset label LatexCommand label name "r_pipe_timing_fig-1" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The class DynDataPipe is a simple class which follow the same skeleton from one Tango class to another. Therefore, this class is generated by the Tango code generator Pogo and the Tango class developper does not have to modify it. The method \emph on is_DynData_allowed() \emph default is relatively simple and in most cases the default code generated by Pogo is enough. The method \emph on read_DynData() \emph default is the method on which the Tango class developper has to concentrate on. The following code is one example of these two methods. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 bool StepperMotor::is_DynData_allowed(Tango::PipeReqType req) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 if (get_state() == Tango::ON) \end_layout \begin_layout LyX-Code 4 return true; \end_layout \begin_layout LyX-Code 5 else \end_layout \begin_layout LyX-Code 6 return false; \end_layout \begin_layout LyX-Code 7 } \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 void StepperMotor::read_DynData(Tango::Pipe &pipe) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 nb_call++; \end_layout \begin_layout LyX-Code 12 if (nb_call % 2 == 0) \end_layout \begin_layout LyX-Code 13 { \end_layout \begin_layout LyX-Code 14 pipe.set_root_blob_name( \begin_inset Quotes eld \end_inset BlobCaseEven \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 vector de_names { \begin_inset Quotes erd \end_inset EvenFirstDE \begin_inset Quotes erd \end_inset , \begin_inset Quotes erd \end_inset EvenSecondDE \begin_inset Quotes erd \end_inset }; \end_layout \begin_layout LyX-Code 17 pipe.set_data_elt_names(de_names); \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 dl = 666; \end_layout \begin_layout LyX-Code 20 v_db.clear(); \end_layout \begin_layout LyX-Code 21 v_db.push_back(1.11); \end_layout \begin_layout LyX-Code 22 v_db.push_back(2.22); \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 pipe << dl << v_db; \end_layout \begin_layout LyX-Code 25 } \end_layout \begin_layout LyX-Code 26 else \end_layout \begin_layout LyX-Code 27 { \end_layout \begin_layout LyX-Code 28 pipe.set_root_blob_name( \begin_inset Quotes eld \end_inset BlobCaseOdd \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 29 \end_layout \begin_layout LyX-Code 30 vector de_names { \begin_inset Quotes erd \end_inset OddFirstDE \begin_inset Quotes erd \end_inset }; \end_layout \begin_layout LyX-Code 31 pipe.set_data_elt_names(de_names); \end_layout \begin_layout LyX-Code 32 \end_layout \begin_layout LyX-Code 33 v_str.clear(); \end_layout \begin_layout LyX-Code 34 v_str.push_back( \begin_inset Quotes eld \end_inset Hola \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 35 v_str.push_back( \begin_inset Quotes eld \end_inset Salut \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 36 v_str.push_back( \begin_inset Quotes eld \end_inset Hi \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code 37 \end_layout \begin_layout LyX-Code 38 pipe << v_str; \end_layout \begin_layout LyX-Code 39 } \end_layout \begin_layout LyX-Code 40 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The \emph on is_DynData_allowed \emph default method is defined between lines 1 and 7. It is allowed to read or write the pipe only is the device state is ON. Note that the input parameter req is not used. The parameter allows the user to know the type of request. The data type PipeReqType is one enumeration with two possible values which are READ_REQ and WRITE_REQ. \end_layout \begin_layout Standard The \emph on read_DynData \emph default method is defined between lines 9 and 40. If the number of times this method has been called is even, the pipe contains two data elements. The first one is named EvenFirstDE and its data is a long. The second one is named EvenSecondDE and its data is an array of double. If the number of call is odd, the pipe contains only one data element. Its name is OddFirstDe and its data is an array of strings. Data are inserted into the pipe at lines 24 and 38. The variables nb_call, dl, v_db and v_str are device data member and therefore declare in the .h file. Refer to pipe section in chapter 3 and to the API reference documentation (in Tango WEB pages) to learn more on how you can insert data into a pipe and to know how data are organized within a pipe. \end_layout \begin_layout Subsubsection Client writing a pipe \end_layout \begin_layout Standard When a client writes a pipe, the following methods are executed in the Tango class: \end_layout \begin_layout Enumerate The \emph on always_executed_hook() \emph default method. \end_layout \begin_layout Enumerate A method called \emph on is__allowed() \emph default . The rule of this method is to allow (or disallow) the next method to be executed. It is usefull for device with some pipes which can be read only in some precise conditions. It has one parameter which is the request type (read or write) \end_layout \begin_layout Enumerate A method called \emph on write_() \emph default . It has one parameter which is a reference to the WPipe object to be written. The aim of this method is to get the data to be written from the WPipe oject and to write them into the corresponding Tango class objects. \end_layout \begin_layout Standard The figure \begin_inset CommandInset ref LatexCommand ref reference "w_pipe_timing_fig-1-1" \end_inset is a drawing of these method calls sequencing for our class StepperMotor with one pipe named DynData. \begin_inset Float figure placement H wide false sideways false status collapsed \begin_layout Plain Layout \align center \begin_inset Graphics filename w_pipe.eps scale 70 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Write pipe sequencing \begin_inset CommandInset label LatexCommand label name "w_pipe_timing_fig-1-1" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard The class DynDataPipe is a simple class which follow the same skeleton from one Tango class to another. Therefore, this class is generated by the Tango code generator Pogo and the Tango class developper does not have to modify it. The method \emph on is_DynData_allowed() \emph default is relatively simple and in most cases the default code generated by Pogo is enough. The method \emph on write_DynData() \emph default is the method on which the Tango class developper has to concentrate on. The following code is one example of the \emph on write_DynData() \emph default method. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotor::write_DynData(Tango::WPipe &w_pipe) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 string str; \end_layout \begin_layout LyX-Code 4 vector v_fl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 w_pipe >> str >> v_fl; \end_layout \begin_layout LyX-Code 7 ..... \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard In this example, we know that the pipe will always contain a srting followed by one array of float. On top of that, we are not niterested by the \end_layout \begin_layout Standard data element names. Data are extracted from the pipe at line 6 and are available for further use starting at line 7. If the content of the pipe is not a string followed by one array of float, the data extraction line (6) will throw one exception which will be reported to the client who has tried to write the pipe. Refer to pipe section in chapter 3 and to the API reference documentation (in Tango WEB pages) to learn more on how you can insert data into a pipe and to know how data are organized within a pipe. \end_layout \begin_layout Standard \begin_inset VSpace bigskip \end_inset \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset label LatexCommand label name "BlackPicture" \end_inset \begin_inset Graphics filename ../dance/tango-08-39.jpg lyxscale 60 scale 60 \end_inset \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/ds_writing/line.tex0000644023471100065110000000174013034745264015116 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/ds_writing/r_attribute.fig0000644023471100065110000000652313034745264016464 00000000000000#FIG 3.2 Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 2340 990 2340 1170 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1170 2070 1170 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 2160 1170 2520 1170 2520 4590 2160 4590 2160 1170 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2340 4590 2340 4770 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 1350 9000 1350 9000 1930 8640 1930 8640 1350 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 2160 9000 2160 9000 2740 8640 2740 8640 2160 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 2970 9000 2970 9000 3550 8640 3550 8640 2970 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 3780 9000 3780 9000 4360 8640 4360 8640 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 1080 8820 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 1980 8820 2160 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 2790 8820 2970 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 3600 8820 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 4410 8820 4680 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 1350 8550 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 1890 2610 1890 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 2160 8550 2160 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 2700 2610 2700 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 2880 5760 2880 5760 3590 5400 3590 5400 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 2970 8550 2970 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 3510 5850 3510 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 3690 5760 3690 5760 4400 5400 4400 5400 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 3780 8550 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 4320 5850 4320 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 2790 5580 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 3600 5580 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 4410 5580 4590 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 2250 5580 2610 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 5580 1440 5580 1530 5580 1620 5580 1710 5580 1800 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1080 5580 1260 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1980 5580 2070 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2700 2880 5310 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 3600 2610 3600 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 3690 5310 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 4410 2610 4410 2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 540 360 9810 360 9810 5040 540 5040 540 360 4 0 0 100 0 0 12 0.0000 4 180 1455 1710 810 StepperMotor object\001 4 0 0 100 0 0 12 0.0000 4 165 960 900 1080 read_attribute\001 4 0 0 100 0 0 12 0.0000 4 135 1260 4860 810 PositionAttr class\001 4 0 0 100 0 0 12 0.0000 4 180 1650 2700 1260 always_executed_hook\001 4 0 0 50 0 0 12 0.0000 4 165 1365 2700 2070 read_attr_hardware\001 4 0 0 50 0 0 12 0.0000 4 165 765 2700 3060 is_allowed\001 4 0 0 50 0 0 12 0.0000 4 165 1440 5940 2880 is_Position_allowed\001 4 0 0 50 0 0 12 0.0000 4 135 300 2700 3870 read\001 4 0 0 50 0 0 12 0.0000 4 165 975 5940 3690 read_Position\001 4 0 0 50 0 0 12 0.0000 4 180 1455 7920 810 StepperMotor object\001 tango-9.2.5a/doc/src/ds_writing/command.jpg0000644023471100065110000007260413034745264015574 00000000000000ÿØÿàJFIFPPÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀP"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ô½A¶Ölîïoou–µ;ôýÞ±w…K©Q@T(T :V§ü!º_üýkŸø=½ÿãÔx7þ@w?öÔ¿ô¶jè(Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üzº (Ÿÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿÇ« ¢€9ÿøCt¿ùú×?ð{{ÿÇ«Çþ:I}àïìì k\³ûWÚ<ïø›ÜÉ»o—·ïÈqÍÓÖ¾€¯Ÿÿi¯ù•¿íïÿhаx7þ@w?öÔ¿ô¶jè+Ÿðoü€îì+©élÕÐPEPEPEPEÏøÍãÃ’Y[êðiw×RŤ³\4"YC†îFWù•;ìŒãÐQ^g¡j:ÔwU¬BïK’Muíu+ JäêLƒìFeH§/…U[œî…Jµ?üKñ.¯áÍW]¹Ñìmì²®õ 9Ì«’ð;)“Ì/"ãf_lx9ù”ЬQ^w7ˆ¼mo«Zø~aáÿíIî-OÚ’)Œ Ü<ƒË,ºµ«àîÃ\„çúÄÏêþ*ŸLmMúUì:~«*\]îï–7‘Ô½Wl{·#p$d×(¯/×.¼I«E§ßZ^ìºMnöÞÂÒͤ·ýnÊÇ92í•]í¢ÎBàÙªú‡ŽŸSWŒô³|º%§Ú-šzâÊâiCŽU•Z(‘Xg³uMzÅæzŸˆ¼eh4«í/¹Ô’Öx¯,­dtÜÁˆHC¡1‘ *HVT²²èGâ½zi¦Ô¢:3é0ë¿ÙÙ®ór‹ç 1¤ÎÐûÙ_Ë)÷ù²h¼¢¹=7ÄZ”_ Å: ´¹Ÿû0êK¬M…òDžY,ÎIÎFïqòñÏ/â CÄ70izæpoÇP²¼ÓDËJ—¶ÈÁÓÌ"xˆ¸FS¹s´œ´€T¢¼í¼cªé×ú¢ê¶Ö“ÜhÖZ”²I$Ž;‘ZMÄ„%'çyRÖÁ åøwǾ1Öõ=+Hº¶ÐôËNÐj6÷S¶ó,Z©l³-¼’rˆÇh*@õŠ+—ÑuMRÿÅ·‰-팚göUÔ0Ú¦ð¯+J ,Ù×÷g£ ¦á·õQEQEQEQEQEQEQEyŸžå5KÍFÒîîúÂÊÈG©ÙéšËÚ]iƒç“í!C„rPŸ‘×$¢`‘º€=2Šò}wÆþ1ÒüYs¡iØêWWz„ñXÆÖû<¤ŠÒ)¶Ê¡²f\±a®@mÊ‹©ªxÇÄÈ“j:u¶Œ,,t+}bîÞiW»HZ8æŒìÆÈŸµ;x!²=Šó{ø“JŠëW¿µÒ®tµêvÖð@dŠuû*ÌèÎIJßf‘Hc*FyQ_Ãþ5ñ޳o¦Cui¥i÷”¶ïopñù¡ ’Öi²`YË/ÏPÌÃp?t"€=BŠò}Ä·þ¸ºÑƒ__\j÷w‹¢=ä’]ž+© h·XR5‚BOo8î' Z.«¬Y[hž²Õ ’ê{½U þ´ïq+ÇmrȪ2$!”ýࣀÒ(¯'·ñ¿‹$Ö¢´žçC·’æX4ð’ÆþL‰®ã’EmÁ¤ßö6 ‡nL‘Œ‚¬dèÄ>$y#Ò™ô¨µ1­¾›%з’H^?²5Ò¸‹ÌVV+±HÞÀÇ'Šî(¯?Ó´ë-{L×õ-KÄz¬sG¨_C,Ðjò[¥‚E#"ˆÁljó©ÎíÇ Ñi«^Xh¶öz]ÕŒz•î·« ¹ˆÊóªOtì#@è ePeTg“’ô +Ïô¿øƒWkà „Ís¢&§£Z< Âä´Q’ ǘí•ö2•C†FÎ ­Í3YÔµ_¾©`‘ÝjÆÞ*mZÔ}¡ (‰ãw%uØß>2  ’Šãü?âõ‹ýä}íu§ßI6måµ1Éð!F…¤`K2œ–9S´€ÄnÓǾ*_­åükÜ\[éw15•œ²%¼wsÈ™tówÊB¢áSÏŒ7PªQ^fž!Õm¦‡ÄÄÉ=¦­O i%™x¢šØ&ä³)p›¹è d×ðn@n \Çw òMó„žR Œ‚O–ä€z¥ãþ#Õµ;OëFH¯­´Ñ¨CkºÚÄÉm¦»[BW}ª’¬¡Ûv\báY€$ÖÆñYÔ<_¨Ås§ØÛxjÏP»Ó¤¼–á#hž÷îËI—ÈW%Dcjàîm­@‘Ey~›ã¯j>#Òü6&Ð㺿ÓÓTRx$Í &|¸`2vÝ“¹š3µ\ùc˜ìŒÒèÞ´[]fòðãHöÚ]ùµbʶ]› aŒŸ½Ó¸õJ+ËíõÏhšN¹¿Ò¯¿áŠ6¹ŠñÞK«¤òüöÌ«´.#aÈco1£f!r@Ôoê­&¯k¨Ç7zÅŒ1[¬Cþ5â¤rù«)†NÃh ެ¤p@;Ê+ÍæñN±¤xf [T– Fhu]M…Ø4vñ^\`y€¸0Œ‚˼؟Å>$Ò4ë©ïåÐï÷ø~ãV´žÁ$XÄ„,„o23æÆUÁR@< ƒ@EsþÔ5‹ÄÔíµÃb×ÖknÍc¤g6ðÊp‰82‘ž28+  Š( Š( Š( Š( Š( Š*9ç†ÖÞ[‹‰c†¼’HÁU ’Ià9ÍIExÜ÷‡´½X}ºíï­ô+›½;Y:“ßZjQG屛ȒFò¥ Ñ€FS.ç  ¹áø—Xñ}ŅΛbt‹}BçJ’íbo>ÃnPÒ–}Û\ùa>E ïm­@‘Ey\^5ñ²hZlóÁá÷¼Ö¬ º°(“,p³ÜÁIAbXm¹·)!†`“Yñ÷‹ì5oÙéšmæ½%íÕºÉo*UŠÞ9Єyae™fFÛ±ˆß(Õ(¯/Õ5=cÅzÔý—jº†›mÒîOOöFv &ÉmÌŠ§ Ý…Fþ+Ô¼Qg¦¼fïNŸGÔì¡Ö-Ñ+Þ5Ôp½º°%dˆ)•˜dýè9?0 T¢¼ýüSâK…ºÔ,¥ÐÅ„ZÙÒ ³$’Oeë+°p7yŒ²y[Fc#çæ±ôø²ç—š¯Út;–Ñ´û[«È$Ö{ ð-Ã·ÊØ‡ä}ªv°gG8Qò€X¢°ô«ýJûÄZäRËh4û …µŠ%¼ÒÆeÞÒoÆ?xÃhAÐsëçzÿ‰u½kṿ½m*M']ÓïBEa$©5£­¼³Æ­(lK $‹µ>n0Ã"€=‚ŠáîµÍnÎâ÷LÕ~Ã<Ö÷zTÜÙ‰`Eqt"!“y!”ÆÿÆUPF7)åôŸŠž%¾ðüúÝΓ¥ZXÝÅ»NžæébHßíkn|ÏãA"3I¶ ÿ„æÇLºÕ4©­VÒé®c´¶`ÎèmÊ“—&&uùrÙPXÿ¬Qa@|ÿûMÌ­ÿoûF¾€¯Ÿÿi¯ù•¿íïÿhаx7þ@w?öÔ¿ô¶jè+Ÿðoü€îì+©élÕÐPEgëÞ Ù¥Ö¥qäÇ$©aQ¤ydc…DE¢‚x' 5/ÄO Ã+Fú®<¿,\8·”¥©v(«;…Ûn©ä ê(®~oè0k×]Nú•¾Åg4˜&&˜.åB F!AÉÚ@ñQ¿|7¥i§ù ÝÚ#ÇÚÌv†—ÉÈLF|߇ÁVààÐIEaÉâí+(nšK²%¸û*¶3´â]†MO1NÅ/Ê—¡ÇsãoÚjÖzdš†û«Ø¢ž 2J²ã}è¥B³$G¨ ‚«ßXYêvrYßÚAwk&7Ãðݽ͜>Ò£µºÛöˆRÊ0’í9]Ê‘ž•±EaØxr?YŽîiogko%½•¥¨…bYZ7”¶ KF¤m Œ¶wøUmÞÝ|5£ÕÞ1aÖe)#n ˜Ûqõ­Ê(¿Ø,ÿ´´~ÉÛ¼¯#í>Xó<¼îÙ»®Ü󎙫Q@Q@Q@Q@Q@Q@Q@gÝhZ=ö££y¥XÜ_A·É¹šÝHö˵ˆÈÁ$Œt5¡EeÞxkAÔ^w¾Ñ4Û§ÑæiíQÌŒŠU drUIž€+>é¿ð’É«]Y鳤6öÖút?aPl–ì 1'³ñ´.¨ç®’Šçü5áK=e¹’ µ{‰g–çP†ÌBòù²´¥s–m£ XýÑV-¼'á»=¿eðþ•ÙRqåYF¸‘3±øyw6Q“޵±ES‡IÓmœ¼}¤Nnè²BªLÌ¥ZNß*H-Ô‚EW“ÃZ Ú\:\º&šú|/¾+FµC7<ªcüÍÈÏ­jQ@sxkA¹@“èšl¨-ÖÔ+Ú£ °e‘÷BôR&…£Çgkg•b–¶’‰í¡[t €’VÉ'#žMhQ@sxkA¹Õ©>‰¦Ë¨Woj(eÆÓ¼Œä``çŒ ’óBÑõ 1g{¥XÜÚ‰Zq Öèè$bK>Ò1¸–bOS¸úÖ…—†´^g‹DÓQæ·û,¬¶¨ ô/–Ür›UFÓÆªÄ:N›m¥. >Ò-<£!´HUb*ÙÜ6ŒœŒs“W(  vzN›§$ c§ÚZ¤é Á  ]ƒ8\0Ô€Meë¾³Õtqamº!|¹,ÄÉ-º8¤@T˜Ôœ… £=r¥•º (—ðO‚íü£­’Ïö¹Yž7(BÛ¤Œ Š ÌÌ‘üªH,Ù`I9òîl£'kbŠËO h1Ü]Ü&‰¦¬÷¨éu"Ú iÕÎ\9ÆX1䃜÷­à†™âŠ4yŸ|¬ªvÚ-êvªŒžÀÕ%QEQEQEQEQEQEQEQEU=KIÓu›u·Õ4ûKèìwP¬ªdgŒûš¹EgÿahÿØÿÙÙV?ÙŸóåötò~öﹿ{žy©-´6ÊÞÚÞÓO´‚ W/oPª¬,CP…$;‚G÷©«”P6ÒtÖ{×m>нú¼c æáB•N>p‘ƒž*¼Ðmoâ¿·Ñ4Øo"@‘ÜGj‹"(M€ ùqéÇJÔ¢€0Ç‚ü*¶ïn¾Ñ„êï°‹k2‚‘·€Ìí¸úÕ…ðÖ‚©d‹¢i¡,½š‹TÅ» L||„°#ŒÖ¥Ÿu¡h÷ÚŒæ•cq}ß&ækty#Úw.Ö##’1ÐÑ…£ÛËs,:UŒr]J³Ü:[ 2È­½]ˆ3ù<ƒÏZТ€)äé¶Î^ >Ò'7 tY!U&fR­'ï•$êA"«ÙøkAÓíî­ì´M6Ú ´Ùs6¨‹2àŒ8 0Ä`úŸZÔ¢€#Žayž(£G™÷ÊÊ m¡rÞ§j¨ÉìíRQEQEQEQEQEQEQEeÙøkAÓíî­ì´M6Ú ´Ùs6¨‹2àŒ8 0Ä`úŸZþÞ¶éÚF•k©Ç—owö-bôÚÛBáv†(ÆElQ@\_´Ûo Øè6°é±"½™ÔfþÏ\߬ ®C€Ã–eä¶üns]žÐfÒáÒåÑ4×Óá}ñZ5ª‘¹åSæn@î}kRŠË>ÐM½Å¹Ñ4ß"á"Iãû*m•cFc((=1Æ*ÄÚN›ráçÓí%qp·Ažb&U ²r>øPn *åŸý…£ÿlkÿeXÿiÿÏïÙÓÎû»~þ7}Þ:ôâ«§„ü7¶²Çáý)$´ÇÙl£1q°ãåù‰n;’zÖÅ^ ;{Ë›Èm ŽêëoÚ&HÀyvŒ.æ¶=*šxkAŽâîá4M5g½GK©ÕN®ráÎ2Á$ç½jQ@üþ³X-ltÈ,tÍ1.㼸·µ³Òɤ‘•e!WæCeX•àëWÃZ ww ¢i«=ê:]H¶¨us—q– y ç=ëRŠÏ·Ð´{O±ý›J±‡ì;þÉåÛ¢ýŸßÙòîïŒg½hQEóÿí5ÿ2·ý½ÿíú¾ý¦¿æVÿ·¿ý£@ÁàßùÜÿØWRÿÒÙ« ®Á¿ò¹ÿ°®¥ÿ¥³WA@þ Ñ®5x¬d²Ô>Ã}av·Vó4"T'k#+¡#*É#ŽHÈ ñXrø3W”kIâ8ä³×ŒRX ÁŒ~S˜\y`ÆT8“%‰9í+/RÐ,õ[…žâmIP º•źã$ò±º‚yëŒôô—/…¯ˆS‹S#þÕRX^б´6²!o0g+‚>SÔ0éžþ¼I¯¤µÖ`O´ËÀÙÙ$wòÞ'IW÷¬„pN:VÇü!º_üýkŸø=½ÿãÔÂ¥ÿÏÖ¹ÿƒÛßþ=@õ/ß\Þ]ÜÙë1—W­s=¥ÅŸo:5ª[˜å@ê\|›‡ÌO*ØGkà_³XÚ[hîû=¦•m»ÈÆï±LeÝÜoÎ1ü=~n•¡ÿn—ÿ?Zçþoøõð†éóõ®àö÷ÿP>ágÃRé·)¨lZi6’ØÛYÇd‘ܼ4{A•¦XË Š?›jä+q¸ƒ[%׉¬MµÎ™}¤y7v·*×f <Ï*e”¨JØÿWŒœcp#8"øCt¿ùú×?ð{{ÿǨÿ„7KÿŸ­sÿ·¿üz€)¿áž) ¸¾‘ žßT·GVÛ{:ÊH$ ·¡ÎsÇJ§}ámRõlN¯âk58|¸¬g”$u–‡ß›ûÆ?eS„)¼àñ·cþÝ/þ~µÏüÞÿñêË×þXë[YEuvRGTÔu ë¸G8Ùö”çpR 'éÜXÑ<)©iš••寭ip`{ó"ÇbÑï[©Rbem¥dN¼åN1‘¸õ•ÅøKáͧ„®"šßZÖeŽ4`– xâÊ&c–)IÆK`;>3’K Õs\´ŸŒ´{ îo£µm>öfKKÙ­·:Él“)8Ý}MuÏø7þ@w?öÔ¿ô¶j?á Òÿçë\ÿÁíïÿ¨áð6‹l… —Y‰ ³•MnõAfbÌx—©bI=É&€:J+‹×´mÎÒöÊ÷YY×S°OÞkr©Wº‰y UˆÁ­v”QEQEQEQES:¥¢ë)¤³È/Ý®QLOµ£V Ä>6’ .W9Æ \¢©êº¥¦‹¥ÜjWï"Z[&ù]"y ¯sµ8IÇ$ð \ Š( ŠÇ›ÅM¾ª_Ë4ëo¥JÐÞŸ²JZ&X»w2íumÀÚsœs[QEQEQEQEQEQEV_‰u)´o êú¥ºÆÓÙYMqÈ RÈ…€8 ã#ÔV¥sþ;ÿ’yâ_û]覠‚Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ¿êShÞÕõKu§²²šâ5¥‘ pAÆG¨­Jçüwÿ$óÄ¿ö ºÿÑM]QEQEQEóÿí5ÿ2·ý½ÿíú¾ý¦¿æVÿ·¿ý£@ÁàßùÜÿØWRÿÒÙ« ®Á¿ò¹ÿ°®¥ÿ¥³WA@Q@Q@Q@Q@Q@s÷ŸòPôoû_ÿèÛJè+Ÿ¼ÿ’‡£Ø*ÿÿFÚPAEP?ã/ùÛØWMÿÒØk ®Æ_ò¶ÿ°®›ÿ¥°Ö†§6±•ý“ccuœùŸk¼{}½1±>{õÆ0:ç€ àõÝ;WºÖõUºÓüAsi*'ö}Ö‰¬ c”•£icRáÃ8b!À<.ÚÜûgŒ?è¡ÿàæoþE£íž0ÿ ‡ÿƒ™¿ù€9¿é¾+ºÕ5!§[êM;¼ ¤_Úê {Qò‡[ˆIÀÊîw!u}¹\ WŸDÖ¢Ô öŸ§ø#D±žyõÓ!—möˆØ5ÉV/Ò%pÊ·¬ûgŒ?è¡ÿàæoþE£íž0ÿ ‡ÿƒ™¿ù€99ôMj-@ßiú‰Ò4Ká·Ÿ]2évßhƒ\•bðí WŒ«plxb¯Eþ§¦jV¶Vó‰¡{Á$PJÌŽœ©Ô2GÞ( Ò}³ÆôÐÿðs7ÿ"ÑöÏÐ CÿÁÌßü‹@¾•¢x¦ÇNÒÚÛûV-NãD¹¶¼’ÿS71Á}ˆ¼©YZW]¥–LlVáÀ*9;gÑÙãúhø9›ÿ‘h“Ó´ï§„õ‹+«=dÎÚ¬ð~Y-·AçG›©^  ü’„šFµhu+(aÖn4´ÔãUuBg¸¶6ʦ8¥y„ˆVà!™\€[%NçÛ!ƒÁž5ÓO‡5—ŸV¸¸Ku¨ÛÜIåÉn#Rò4¹Â˜À ’@e¾ ­ÏCâ]bÏLŸM´¾µ„y¿j±ªÎ*#bÑ]D6€$ÈŸ¾¹BFScíž0ÿ ‡ÿƒ™¿ù¶xÃþ€ZþfÿäZæõm_}ÂVÒ^Ïhàê2é·Ëg,‘Î\Üa›ËÜÁ›îÈU—pÏq¥[­®—oGwٻ˻¸iåBy*ÎÌåˆ'xŽ01Ylñ‡ý´?üÍÿÈ´}³ÆôÐÿðs7ÿ"ÐAEsÿlñ‡ý´?üÍÿÈ´}³ÆôÐÿðs7ÿ"ÐAEsÿlñ‡ý´?üÍÿÈ´}³ÆôÐÿðs7ÿ"ÐAEsÿlñ‡ý´?üÍÿÈ´}³ÆôÐÿðs7ÿ"ÐAEsÿlñ‡ý´?üÍÿÈ´}³ÆôÐÿðs7ÿ"ÐAEy¿‰5߈öšŒpèÚ>•-Ä‘öVk‹ˆÛò³y1FŒä<œ…] óö¾×u 3>¹¢A¤H~ä |.\rAÜB-œó‚1@ÏøïþIç‰ìuÿ¢š£:Þ½u«j–š^¦ÍŸp¶í-֤𳱆9r`p%¯cTõÛk~ÔôŸì·ZKmæÿkÌÛ7¡]Øû0Î3œdPaEsÿlñ‡ý´?üÍÿȵ&¬jWZÍö—ªiÖ–“ÚÛÁp­kxÓ«¬­*àî Â{¢€7(¢¸½sÆ¢=/Ä–¶ð]éúµŽ™wwkö”2¬[“ÎU Ä&ð¸.«¸€Àv”Wâoˆºg…%Ôc¿±¾v°Š ‡˜I’X ‘È Up¸^9©.ü}eck%íΙ©G§Ãqq ׬"D ”DÎO™œ$*€dm­„`RäG¼¦Ýüføš÷Rytë¸'¾º¶»º†ïP·Ž8í¡+q2¤eKî ±åˆ…͸€vQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEsþ;ÿ’yâ_û]覮‚¹ÿÿÉ<ñ/ý‚®¿ôSWA@Q@Q@Q@|ÿûMÌ­ÿoûF¾€¯Ÿÿi¯ù•¿íïÿhаx7þ@w?öÔ¿ô¶jè+Ÿðoü€îì+©élÕÐPEPEPEPEPEP\ýçü”=þÁWÿú6Òº çï?ä¡èßö ¿ÿѶ”ÐQEÏøËþ@vßöÓô¶è+Ÿñ—ü€í¿ì+¦ÿél5ÐPEPEPEPEPEPEPEPEPEPEPEPEPEP?áïùx³þ±ÿé­tÏø{þCž,ÿ°¬úEk]ÏÙÿÉCÖìaÿ£në ®~ÏþJ³ÿ`«ýw@qñ|;°Ž ËfÕuY­n-/-¥ü”ºpò•r›Ù·‚ìÿl_xjÃP¼’êkU$|dA«]Bƒ$ :võëUÿá Òÿçë\ÿÁíïÿ Ä^ÒüSyg6©çÉ ´SÂÖªûb% ‘ ÆN #.Ã(=@Æ\ÿ 4§ÒìôûKýJ }2M-…³Ç‰ “i“r²2‡b¹.X“É8Ôÿ„7KÿŸ­sÿ·¿üzøCt¿ùú×?ð{{ÿǨ?ÃúMíÞ±¯ë—ºlúÕö-àFž;‰*àÜ)‘ÔB `ŒÛ©;¸«~“ªxWL·ÒçMYñÖ£owu©,úe›Å®£=²†ynC"uˆ2sÐPÏÿÉ<ñ/ý‚®¿ôSWA\ÜþÑn­å·¸—Yš P¤‘É­Þ²º‘‚2à‚8ÅIÿn—ÿ?ZçþoøõtW'm¦Ç£xëN·´ºÔš 2ñåŽëQžåK$¶ÁH»@wêk¬ Š( Š( ¾ý¦¿æVÿ·¿ý£_@WÏÿ´×üÊßö÷ÿ´hØ<ÿ ;Ÿû ê_ú[5tÏø7þ@w?öÔ¿ô¶jè(¢Š(¢Š(¢Š(¢Š(¢Š(®~óþJÿ`«ÿýi]s÷ŸòPôoû_ÿèÛJè(¢Šçüeÿ ;oû é¿ú[ tÏøËþ@vßöÓô¶è(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ÿð÷ü‡#³ò4Ÿßh{¶‰£“ÃlŠÄíä>01ŽMcøcÀºÞ‘ö¥¹ñôs>À×ÐÉm<×›s†”Ëk¼`•L’mhlŸ@¨ÄŒn# „¤®Ö$œ¨ç9äó Î0ÿáÕ?ès×?ïÍ—ÿ#Ñÿö©ÿCž¹ÿ~l¿ùº (Ÿÿ„{Tÿ¡Ï\ÿ¿6_üGü#Ú§ýzçýù²ÿäzè+?LÕ“SŸR…m§‚M>ìÚÈ&Ûó‰ eÚÇå+"‘œyÐü#Ú§ýzçýù²ÿäz?áÕ?ès×?ïÍ—ÿ#Ö†‹«&·¦ Øí§¶ýì°¼3íÞµ™~ò„Ö…sÿðjŸô9ëŸ÷æËÿ‘èÿ„{Tÿ¡Ï\ÿ¿6_ü]ÏÿÂ=ªÐç®ß›/þG£þíSþ‡=sþüÙò=hiš²jsêP­´ðI§Ý›YÛ~c±$ »Xü¥dR3ƒÏ РþíSþ‡=sþüÙò=ðjŸô9ëŸ÷æËÿ‘ë ¢€9ÿøGµOúõÏûóeÿÈôÂ=ªÐç®ß›/þG®‚ŠçÿáÕ?ès×?ïÍ—ÿ#Ñÿö©ÿCž¹ÿ~l¿ùº (Ÿÿ„{Tÿ¡Ï\ÿ¿6_üGü#Ú§ýzçýù²ÿäzè( þíSþ‡=sþüÙò=ðjŸô9ëŸ÷æËÿ‘ë ¢€9ÿøGµOúõÏûóeÿÈôÂ=ªÐç®ß›/þG®‚ŠçÿáÕ?ès×?ïÍ—ÿ#Ñÿö©ÿCž¹ÿ~l¿ùº (Ÿÿ„{Tÿ¡Ï\ÿ¿6_üGü#Ú§ýzçýù²ÿäzè( þíSþ‡=sþüÙò=ðjŸô9ëŸ÷æËÿ‘ë ¢€9ÿøGµOúõÏûóeÿÈôÂ=ªÐç®ß›/þG£ÇòOºçþ¯øÍcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%P7ákúgF¿¨[hÈn-çŽñ­%PKÈÈû”-´lÃtdbI᳸wnh–¾$³¾×no4ý)~ß/Ú¡Xu b‰Q‰€aO”Ia’3§­XûŒ?è;¡ÿàšoþJ£ì~0ÿ î‡ÿ‚i¿ù*€)é:6¼<1¬i7¯i§Ot÷omwató4Mq$²g# ¡`ƒÎ3ò×.>j³L×ñéþѯ-ííÞÞ=${yï"™eȸ@ƒ Ñ¡œ,ÒeˆÓì~0ÿ î‡ÿ‚i¿ù*±øÃþƒºþ ¦ÿäªçáð£‡â Y5µ_ßË Å}"ªË=¬; C9ØUØþö6vWܬ  ¯¦|?½°Ñe·h,fWÔܺLÓFlî„dž1ÚÆ’-ÆèPðX°ê>Çãúèø&›ÿ’¨ûŒ?è;¡ÿàšoþJ  ÿønÿÃ1kPÝXéVV÷šƒ^[Á¦Ï#¤A•T¦ØÇ  ]…sÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉT}ÆôÐÿðM7ÿ%PAEsÿcñ‡ýt?üMÿÉUËø“Lø…&£iZ®Ë¦ˆ »´±U¶Q“òÉ×l8%Ö|`yZôŠ+Ÿðœ>,‡NdñmÖ•qt»R6Óãq¸˹lÄöUP1ïåæ½u⫽/K¼Óm µ²·¸fº²yÙÚW™p6Ì€!S@xïþIç‰ìuÿ¢šº äõmÅZÎ}¥Ükú2Á{o%¼(`®¥I¹#8>†®}ÆôÐÿðM7ÿ%PAEsvwšõ¯Š­4½RóM»‚êÊâáZÖÉàdhžÁÝ3‚˜öt”QEQEQEQEQEQEQEQEQEQEQEÏøïþIç‰ìuÿ¢šº çüwÿ$óÄ¿ö ºÿÑM]QEQEQEóÿí5ÿ2·ý½ÿíú¾ý¦¿æVÿ·¿ý£@ÁàßùÜÿØWRÿÒÙ« ®Á¿ò¹ÿ°®¥ÿ¥³WA@Q@Q@Q@Q@Q@s÷ŸòPôoû_ÿèÛJè+Ÿ¼ÿ’‡£Ø*ÿÿFÚPAEP?ã/ùÛØWMÿÒØk ®Æ_ò¶ÿ°®›ÿ¥°×A@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ÿ‡¿ä9âÏû Çÿ¤VµÐW?áïùx³þ±ÿé­tW?gÿ%Yÿ°U‡þ»®‚¹û?ù(zÏý‚¬?ômÝtQEQEQEQEQEQEQEQEQEQEQEQEQEQEÏÙÿÉCÖìaÿ£në ®~ÏþJ³ÿ`«ýw@Q@ýçü”=þÁWÿú6Òº çï?ä¡èßö ¿ÿѶ•ÐPEPEPEPEPEPEPEPEPEPEPEP?ã¿ù'ž%ÿ°U×þŠjè+Ÿñßü“ÏÿØ*ëÿE5tQEQEQEWÏÿ´×üÊßö÷ÿ´kè ùÿöšÿ™[þÞÿö{ƒäsÿa]KÿKf®‚¹ÿÿÈçþº—þ–Í]QEQEQEQEQEÏÞÉCÑ¿ìÿ£m+ ®~óþJÿ`«ÿýi@Q@ÿŒ¿ämÿa]7ÿKa®‚¹ÿÈÛþºoþ–Ã]QEQEQEQEQEQEQEQEQEQEQEQEQEsþÿç‹?ì+þ‘Z×A\ÿ‡¿ä9âÏû Çÿ¤VµÐP\ýŸü”=gþÁVú6îº çìÿä¡ë?ö °ÿÑ·tÐQEQEQEQEQEQEQEQEQEQEQEQEQEQEW?gÿ%Yÿ°U‡þ»®‚¹û?ù(zÏý‚¬?ômÝtQEs÷ŸòPôoû_ÿèÛJè+Ÿ¼ÿ’‡£Ø*ÿÿFÚWA@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ÿŽÿäžx—þÁW_ú)« ®ÇòOÙãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€9ÿ¶xÃþ€ZþfÿäZ>Ùãúhø9›ÿ‘k ¢€2ôÙõénuM7M¶ƒa*öºƒÎŲ8*Рç=‡ñŸyg¯ZøªïTÒìôÛ¸.¬­íÙn¯^F‰æl°¸ ‰‡qÐ×IErz¶½â­F¾Õ.4  ²·’âEX”±TRÄ ÛœQW>Ùãúhø9›ÿ‘hñßü“ÏÿØ*ëÿE5tÍÙÙë×^*´Õ5K=6Ò [+‹u[[×¥x['t(ÜõÒQEQEQEQEQEQEQEQEQEQEQEQEsþ;ÿ’yâ_û]覮‚¹ÿÿÉ<ñ/ý‚®¿ôSWA@Q@Q@Q@|ÿûMÌ­ÿoûF¾€¯Ÿÿi¯ù•¿íïÿhаx7þ@w?öÔ¿ô¶jè+Ÿðoü€îì+©élÕÐPEPEPEPEPEP\ýçü”=þÁWÿú6Òº çï?ä¡èßö ¿ÿѶ”ÐQEÏøËþ@vßöÓô¶è+Ÿñ—ü€í¿ì+¦ÿél5ÐPEPEPEPEPEPEPEPEPEPEPEPEPEP?áïùx³þ±ÿé­tÏø{þCž,ÿ°¬úEk]ÏÙÿÉCÖìaÿ£në ®~ÏþJ³ÿ`«ýw@Q@æ~Ñ|_oªO6µ.¥2 )£ºH¥`—’6Þ`cz|§Ü FDfN6ØÐ4OY[ß­Þ¡©M¨M£…Óîo.£h,¥!± ˆ¿ëeVØLåx|¸Ãz%åúvã[}3Z’&¾ó$Š•ÝÃ!—l…¤Lo. Lñ—B~\ “Z‚ÃSƒN¼›KÓ£gªØÜXÁ»Î¹†á8ö͹ÀÀ œô~%ÐfÒæÕ"Öô×Óá}’Ý­Ò‘¸áŸ8æ^ î=hRŠÃð׈áñ ÕÜÚI鵎{K¡ƒðæ"ò/µ^hXÛÚ=¼½ËRŽv‰”ªŒ¨‰T¤ÚjišE߇-ïo%’ï]¼d†Þ-soÂ#4’wåvrT±vàª:J(cU½sn¾Ô´÷t`—WfÚH¢m§–9˰ίQÔcØøæ/…î5+O³Û¤d–ÊÍíY'r%%‹:©b…-‚ v”PcàÛí?CÕ-­õŸ+RÔ%G’ð}¥ÁUÚ+%ðbŠPº:°q‚€Õ}3ÀÚžš’Éý¹·cP…´’ZÍ"¤Ÿg6ì$ó.äSàoR­Ü¯Ë]ÅÅèÚf±à÷ÔÞKy5ãªÞ½óÿfYÁh rª¤$à0!Wdä1bKf³õ ÝVøƒ¢ -?RОÞÊèI>¡§-ݼÂC—†Rþè¶K©Ê¨çv¢Q@]®ô[ 4}j8/4ĸIkh.wH<¤)°yŠ¥B°ÚoÌ+,ü/¼¶Ó ³Óuè-$ŽÐÂo#°0ήÒK#´o±mŒ´¹¶ä‚sŸH¢€9ý{FÖ5=OLº°Õ,m#°”Ü$sØ<å¤1ÉË “åÛ)ãÈÎqÅI¬hú•Ö³cªiz¥¤ö¶óÛ²ÝY´êë+DÙdB0Žç©­Ê(Ÿ»Ñµ‰ü[k¬EªXÇkmÛ­³Ø;9ŽF‰¤Ìžp³ÁÛžCV^¿àk½iõ›dÖ£‡IÖž½µ–Å&udTF0ÈHY#A–WÚWrà×iErðøZò±mÔà?cÖî58óhyŽo;tG÷Ÿxyï‡éÂü§œõQ@V^¥â=#F¸XuKèìC ežè <‘´JÀ&þ Ù»v8Ç4©EGðÝ[Åqo,sA*ŽHØ2º‘AG9®né5-OÆWÖk·Úu­®Ÿk2¥¤VçsÉ%ÀbL±9éôÇz±ã¿ù'ž%ÿ°U×þŠjè+—¿ð…Þ§§\Ø^x»\’Öê'†dòìÆä`C ‹|Œ‚zUøGµOúõÏûóeÿÈôÐQ\½ªjZgŒ¬l'×oµ[­>êfK¸­Æ×ŽKp¤¢CÒVëžÕÔPEPEP_?þÓ_ó+Ûßþѯ +çÿÚkþeoû{ÿÚ4ì ÿÏý…u/ý-šº çüÿ ;Ÿû ê_ú[5tQEQEQEQEQEW?yÿ%Fÿ°Uÿþ´®‚¹ûÏù(z7ý‚¯ÿôm¥tQEsþ2ÿ·ý…tßý-†º çüeÿ ;oû é¿ú[ tQEQEQEQEQEQEQEQEQEQEQEQEQEÏø{þCž,ÿ°¬úEk]sþÿç‹?ì+þ‘Z×A@söòPõŸûXèÛºè+Ÿ³ÿ’‡¬ÿØ*ÃÿFÝÐAEPEPEPEPEPEPEPEPEPEPEPEPEPEP\ýŸü”=gþÁVú6îº çìÿä¡ë?ö °ÿÑ·tÐQEÏÞÉCÑ¿ìÿ£m*æ¥á­Y¸[SDÓo§T²]Z¤¬$àã$œ{š§yÿ%Fÿ°Uÿþ´®‚€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøšËÔ¾øKS¸S&•i ¦À¯ikg+!ÆEŒJ§§ÝuhH=¥áï è^³6º™”m÷Ê^LFç9fÆãŒ“ŒàqUìÿä¡ë?ö °ÿÑ·uÐW?gÿ%Yÿ°U‡þ» ‚Š( ~óþJÿ`«ÿýi]s÷ŸòPôoû_ÿèÛJè(¢Š(¢Š(¯Ÿÿi¯ù•¿íïÿh×Ðóÿí5ÿ2·ý½ÿíöÿÈçþº—þ–Í]sþ ÿÏý…u/ý-šº (¢Š(¢Š(¢Š(¢Š(¢Š+Ÿ¼ÿ’‡£Ø*ÿÿFÚWA\ýçü”=þÁWÿú6Ò€: (¢€9ÿÈÛþºoþ–Ã]sþ2ÿ·ý…tßý-†º (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šçü=ÿ!ÏØV?ý"µ®‚¹ÿÈsÅŸöÿH­k  ¹û?ù(zÏý‚¬?ômÝtÏÙÿÉCÖìaÿ£nè ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®~ÏþJ³ÿ`«ýw]söòPõŸûXèÛºè(¢Šçï?ä¡èßö ¿ÿѶ•ÐW?yÿ%Fÿ°Uÿþ´­ O]ÑôO+û[U±°ó³åý®á"ߌgˆÎ2:zŠÐ¢³ôÍf×Wó~Íô~V7}®Â{lç8Çš‹»§lãŒõ¡@Q@Q@Q@Q@Q@Q@Q@Q@Q@söòPõŸûXèÛºè+Ÿ³ÿ’‡¬ÿØ*ÃÿFÝÐAEP?yÿ%Fÿ°Uÿþ´®‚¹ûÏù(z7ý‚¯ÿôm¥tQEQEWÏÿ´×üÊßö÷ÿ´kè ùÿöšÿ™[þÞÿö{ƒäsÿa]KÿKf®‚¹ÿÿÈçþº—þ–Í]QEQEQEQEQEÏÞÉCÑ¿ìÿ£m+ ®~óþJÿ`«ÿýi@Q@ÿŒ¿ämÿa]7ÿKa®‚¹ÿÈÛþºoþ–Ã]QEQEQEQEQEQEQEQEQEQEQEQEQEsþÿç‹?ì+þ‘Z×A\ÿ‡¿ä9âÏû Çÿ¤VµÐP\ýŸü”=gþÁVú6îº çìÿä¡ë?ö °ÿÑ·t_Æ>;Ó¼gö›û Væ1´»YÙ³¤jÄ€ZCˆÇ nÝó/9¬ÿ|I´×,ÍùÓï–Æ^mdµ°¼¹.2A¶Ü"° Üg#ÙçšØ¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ çüwÿ$óÄ¿ö ºÿÑM]eø—M›Y𮯥۴k=í”Öñ´„… èT€N2} jQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWÏÿ´×üÊßö÷ÿ´kè ùÿöšÿ™[þÞÿö{ƒäsÿa]KÿKf®‚¸½ĺ‡gwa«kznŸxšûµ½ÝÒE"«ÝJèJ± ¬¬pÀŽ jÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPAEsÿðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅPA_?þÓ_ó+Ûßþѯ`ÿ„ïÁÿô5èø1‡ÿНý¡õÝ[ÿ„sû'U±¿ò~Óæ}’á%ÙŸ+ÚN3ƒ×ÐÐÿÙtango-9.2.5a/doc/src/ds_writing/w_attribute.fig0000644023471100065110000000663713034745264016477 00000000000000#FIG 3.2 Produced by xfig version 3.2.5b Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 2340 990 2340 1170 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1170 2070 1170 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 1350 9000 1350 9000 1930 8640 1930 8640 1350 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 2970 9000 2970 9000 3550 8640 3550 8640 2970 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 3780 9000 3780 9000 4360 8640 4360 8640 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 1080 8820 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 3600 8820 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 1350 8550 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 1890 2610 1890 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 2880 5760 2880 5760 3590 5400 3590 5400 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 2970 8550 2970 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 3510 5850 3510 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 3690 5760 3690 5760 4400 5400 4400 5400 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 4320 5850 4320 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 2790 5580 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 3600 5580 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1080 5580 1260 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2700 2880 5310 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 3600 2610 3600 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 3690 5310 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 4410 2610 4410 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 3780 8550 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1980 5580 2880 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1395 5580 1800 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 2025 8820 2970 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 5135 9000 5135 9000 5715 8640 5715 8640 5135 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 4455 8820 5130 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 5805 8820 6030 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2205 1170 2475 1170 2475 5670 2205 5670 2205 1170 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2340 5670 2340 5850 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 5625 2610 5625 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 5175 8550 5175 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 4410 5580 5040 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 5265 5580 5535 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 5760 5580 5940 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 450 495 9855 495 9855 6210 450 6210 450 495 4 0 0 100 0 0 12 0.0000 4 165 1710 1710 810 StepperMotor object\001 4 0 0 100 0 0 12 0.0000 4 135 1620 4860 810 PositionAttr class\001 4 0 0 100 0 0 12 0.0000 4 165 1800 2700 1260 always_executed_hook\001 4 0 0 50 0 0 12 0.0000 4 150 900 2700 3060 is_allowed\001 4 0 0 50 0 0 12 0.0000 4 150 1710 5940 2880 is_Position_allowed\001 4 0 0 50 0 0 12 0.0000 4 165 1710 7920 810 StepperMotor object\001 4 0 0 50 0 0 12 0.0000 4 120 450 2700 3870 write\001 4 0 0 50 0 0 12 0.0000 4 150 1260 5940 3735 write_Position\001 4 0 0 50 0 0 12 0.0000 4 150 1350 765 1080 write_attribute\001 4 0 0 50 -1 0 12 0.0000 4 150 1710 2745 5085 write_attr_hardware\001 tango-9.2.5a/doc/src/ds_writing/command.eps0000644023471100065110000001530213034745264015573 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: command.eps %%Creator: fig2dev Version 3.2 Patchlevel 1 %%CreationDate: Tue Dec 7 11:30:22 1999 %%For: taurel@amber1 (E.Taurel,,,) %%Orientation: Portrait %%BoundingBox: 0 0 819 303 %%Pages: 0 %%BeginSetup %%EndSetup %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save -38.0 324.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def %%EndProlog $F2psBegin 10 setmiterlimit n -1000 6142 m -1000 -1000 l 14602 -1000 l 14602 6142 l cp clip 0.06299 0.06299 sc % Polyline 7.500 slw gs clippath 5460 1410 m 5580 1440 l 5460 1470 l 5595 1470 l 5595 1410 l cp clip n 2610 1440 m 5580 1440 l gs col0 s gr gr % arrowhead n 5460 1410 m 5580 1440 l 5460 1470 l col0 s % Polyline n 2340 990 m 2340 1170 l gs col0 s gr % Polyline n 5850 1080 m 5850 1440 l gs col0 s gr % Polyline gs clippath 1950 1140 m 2070 1170 l 1950 1200 l 2085 1200 l 2085 1140 l cp clip n 990 1170 m 2070 1170 l gs col0 s gr gr % arrowhead n 1950 1140 m 2070 1170 l 1950 1200 l col0 s % Polyline n 5670 1440 m 6030 1440 l 6030 4590 l 5670 4590 l cp gs col0 s gr % Polyline gs clippath 6240 4350 m 6120 4320 l 6240 4290 l 6105 4290 l 6105 4350 l cp clip n 9360 4320 m 6120 4320 l gs col0 s gr gr % arrowhead n 6240 4350 m 6120 4320 l 6240 4290 l col0 s % Polyline gs clippath 2730 4620 m 2610 4590 l 2730 4560 l 2595 4560 l 2595 4620 l cp clip n 5580 4590 m 2610 4590 l gs col0 s gr gr % arrowhead n 2730 4620 m 2610 4590 l 2730 4560 l col0 s % Polyline gs clippath 9240 3570 m 9360 3600 l 9240 3630 l 9375 3630 l 9375 3570 l cp clip n 6120 3600 m 9360 3600 l gs col0 s gr gr % arrowhead n 9240 3570 m 9360 3600 l 9240 3630 l col0 s % Polyline gs clippath 6240 3180 m 6120 3150 l 6240 3120 l 6105 3120 l 6105 3180 l cp clip n 9360 3150 m 6120 3150 l gs col0 s gr gr % arrowhead n 6240 3180 m 6120 3150 l 6240 3120 l col0 s % Polyline gs clippath 9240 2310 m 9360 2340 l 9240 2370 l 9375 2370 l 9375 2310 l cp clip n 6120 2340 m 9360 2340 l gs col0 s gr gr % arrowhead n 9240 2310 m 9360 2340 l 9240 2370 l col0 s % Polyline n 9450 2340 m 9810 2340 l 9810 3150 l 9450 3150 l cp gs col0 s gr % Polyline n 9450 3600 m 9810 3600 l 9810 4320 l 9450 4320 l cp gs col0 s gr % Polyline n 9630 3150 m 9630 3600 l gs col0 s gr % Polyline n 9630 4320 m 9630 4590 l gs col0 s gr % Polyline n 12420 3690 m 12780 3690 l 12780 4230 l 12420 4230 l cp gs col0 s gr % Polyline n 12600 4230 m 12600 4500 l gs col0 s gr % Polyline gs clippath 12210 1590 m 12330 1620 l 12210 1650 l 12345 1650 l 12345 1590 l cp clip n 6120 1620 m 12330 1620 l gs col0 s gr gr % arrowhead n 12210 1590 m 12330 1620 l 12210 1650 l col0 s % Polyline gs clippath 6240 2010 m 6120 1980 l 6240 1950 l 6105 1950 l 6105 2010 l cp clip n 12330 1980 m 6120 1980 l gs col0 s gr gr % arrowhead n 6240 2010 m 6120 1980 l 6240 1950 l col0 s % Polyline n 12420 1620 m 12780 1620 l 12780 1980 l 12420 1980 l cp gs col0 s gr % Polyline n 12600 1080 m 12600 1620 l gs col0 s gr % Polyline n 12600 1980 m 12600 3690 l gs col0 s gr % Polyline gs clippath 10020 4260 m 9900 4230 l 10020 4200 l 9885 4200 l 9885 4260 l cp clip n 12330 4230 m 9900 4230 l gs col0 s gr gr % arrowhead n 10020 4260 m 9900 4230 l 10020 4200 l col0 s % Polyline gs clippath 12210 3750 m 12330 3780 l 12210 3810 l 12345 3810 l 12345 3750 l cp clip n 9900 3780 m 12330 3780 l gs col0 s gr gr % arrowhead n 12210 3750 m 12330 3780 l 12210 3810 l col0 s % Polyline n 2160 1170 m 2520 1170 l 2520 4590 l 2160 4590 l cp gs col0 s gr % Polyline n 2340 4590 m 2340 4770 l gs col0 s gr % Polyline n 9630 2070 m 9630 2340 l gs col0 s gr % Polyline n 5850 4590 m 5850 4860 l gs col0 s gr % Polyline n 630 360 m 13590 360 l 13590 5130 l 630 5130 l cp gs col0 s gr /Courier ff 180.00 scf sf 2790 1350 m gs 1 -1 sc (command_handler) col0 sh gr /Times-Roman ff 180.00 scf sf 1710 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 180.00 scf sf 4860 810 m gs 1 -1 sc (StepperMotorClass singleton) col0 sh gr /Times-Roman ff 180.00 scf sf 9000 810 m gs 1 -1 sc (DevReadPosition) col0 sh gr /Times-Roman ff 180.00 scf sf 11790 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 180.00 scf sf 900 1080 m gs 1 -1 sc (command_inout) col0 sh gr /Courier ff 180.00 scf sf 6300 3510 m gs 1 -1 sc (execute) col0 sh gr /Courier ff 180.00 scf sf 6210 2250 m gs 1 -1 sc (is_allowed) col0 sh gr /Times-Roman ff 180.00 scf sf 6210 1530 m gs 1 -1 sc (always_executed_hook) col0 sh gr /Courier ff 180.00 scf sf 10080 3600 m gs 1 -1 sc (dev_read_position) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/ds_writing/w_pipe.eps0000644023471100065110000001622113034745264015441 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Title: w_pipe.fig %%Creator: fig2dev Version 3.2 Patchlevel 5e %%CreationDate: Tue May 5 10:08:12 2015 %%BoundingBox: 0 0 586 297 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 297 moveto 0 0 lineto 586 0 lineto 586 297 lineto closepath clip newpath -33.3 318.2 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 100 % Polyline 0 slj 0 slc 7.500 slw n 2340 990 m 2340 1170 l gs col0 s gr % Polyline gs clippath 1933 1200 m 2085 1200 l 2085 1140 l 1933 1140 l 1933 1140 l 2053 1170 l 1933 1200 l cp eoclip n 990 1170 m 2070 1170 l gs col0 s gr gr % arrowhead n 1933 1200 m 2053 1170 l 1933 1140 l col0 s % Polyline n 2340 4590 m 2340 4770 l gs col0 s gr % Polyline n 8640 1350 m 9000 1350 l 9000 1930 l 8640 1930 l cp gs col0 s gr % Polyline n 8640 3780 m 9000 3780 l 9000 4360 l 8640 4360 l cp gs col0 s gr % Polyline n 2160 1170 m 2520 1170 l 2520 4590 l 2160 4590 l cp gs col0 s gr % Polyline n 5400 2475 m 5760 2475 l 5760 3185 l 5400 3185 l cp gs col0 s gr % Polyline n 8640 2475 m 9000 2475 l 9000 3055 l 8640 3055 l cp gs col0 s gr % Polyline n 5400 3690 m 5760 3690 l 5760 4400 l 5400 4400 l cp gs col0 s gr /Times-Roman ff 190.50 scf sf 2700 1260 m gs 1 -1 sc (always_executed_hook) col0 sh gr % here ends figure; % % here starts figure with depth 50 % Polyline 0 slj 0 slc 7.500 slw n 8820 1080 m 8820 1350 l gs col0 s gr % Polyline n 8820 4410 m 8820 4680 l gs col0 s gr % Polyline gs clippath 5987 4290 m 5835 4290 l 5835 4350 l 5987 4350 l 5987 4350 l 5867 4320 l 5987 4290 l cp eoclip n 8550 4320 m 5850 4320 l gs col0 s gr gr % arrowhead n 5987 4290 m 5867 4320 l 5987 4350 l col0 s % Polyline n 5580 4410 m 5580 4590 l gs col0 s gr % Polyline n 5580 1080 m 5580 1260 l gs col0 s gr % Polyline gs clippath 5173 3720 m 5325 3720 l 5325 3660 l 5173 3660 l 5173 3660 l 5293 3690 l 5173 3720 l cp eoclip n 2610 3690 m 5310 3690 l gs col0 s gr gr % arrowhead n 5173 3720 m 5293 3690 l 5173 3660 l col0 s % Polyline gs clippath 2747 4380 m 2595 4380 l 2595 4440 l 2747 4440 l 2747 4440 l 2627 4410 l 2747 4380 l cp eoclip n 5310 4410 m 2610 4410 l gs col0 s gr gr % arrowhead n 2747 4380 m 2627 4410 l 2747 4440 l col0 s % Polyline n 540 360 m 9810 360 l 9810 5040 l 540 5040 l cp gs col0 s gr % Polyline gs clippath 2747 1860 m 2595 1860 l 2595 1920 l 2747 1920 l 2747 1920 l 2627 1890 l 2747 1860 l cp eoclip n 8550 1890 m 2610 1890 l gs col0 s gr gr % arrowhead n 2747 1860 m 2627 1890 l 2747 1920 l col0 s % Polyline gs clippath 8413 1380 m 8565 1380 l 8565 1320 l 8413 1320 l 8413 1320 l 8533 1350 l 8413 1380 l cp eoclip n 2610 1350 m 8550 1350 l gs col0 s gr gr % arrowhead n 8413 1380 m 8533 1350 l 8413 1320 l col0 s % Polyline gs clippath 5987 3030 m 5835 3030 l 5835 3090 l 5987 3090 l 5987 3090 l 5867 3060 l 5987 3030 l cp eoclip n 8550 3060 m 5850 3060 l gs col0 s gr gr % arrowhead n 5987 3030 m 5867 3060 l 5987 3090 l col0 s % Polyline gs clippath 5128 2550 m 5280 2550 l 5280 2490 l 5128 2490 l 5128 2490 l 5248 2520 l 5128 2550 l cp eoclip n 2655 2520 m 5265 2520 l gs col0 s gr gr % arrowhead n 5128 2550 m 5248 2520 l 5128 2490 l col0 s % Polyline gs clippath 2747 3120 m 2595 3120 l 2595 3180 l 2747 3180 l 2747 3180 l 2627 3150 l 2747 3120 l cp eoclip n 5310 3150 m 2610 3150 l gs col0 s gr gr % arrowhead n 2747 3120 m 2627 3150 l 2747 3180 l col0 s % Polyline n 5580 1440 m 5580 1755 l gs col0 s gr % Polyline n 5580 2025 m 5580 2475 l gs col0 s gr % Polyline n 8820 2070 m 8820 2475 l gs col0 s gr % Polyline n 8820 3240 m 8820 3780 l gs col0 s gr % Polyline gs clippath 8413 2595 m 8565 2595 l 8565 2535 l 8413 2535 l 8413 2535 l 8533 2565 l 8413 2595 l cp eoclip n 5850 2565 m 8550 2565 l gs col0 s gr gr % arrowhead n 8413 2595 m 8533 2565 l 8413 2535 l col0 s % Polyline n 5580 3375 m 5580 3690 l gs col0 s gr % Polyline gs clippath 8458 3855 m 8610 3855 l 8610 3795 l 8458 3795 l 8458 3795 l 8578 3825 l 8458 3855 l cp eoclip n 5895 3825 m 8595 3825 l gs col0 s gr gr % arrowhead n 8458 3855 m 8578 3825 l 8458 3795 l col0 s /Times-Roman ff 190.50 scf sf 7920 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 190.50 scf sf 2745 2385 m gs 1 -1 sc (is_allowed) col0 sh gr /Times-Roman ff 190.50 scf sf 1845 855 m gs 1 -1 sc (Device_5Impl) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 900 m gs 1 -1 sc (DynDataPipe class) col0 sh gr /Times-Roman ff 222.25 scf sf 5940 2385 m gs 1 -1 sc (is_DynData_allowed) col0 sh gr /Times-Roman ff 190.50 scf sf 855 1035 m gs 1 -1 sc (write_pipe) col0 sh gr /Times-Roman ff 222.25 scf sf 2745 3555 m gs 1 -1 sc (write) col0 sh gr /Times-Roman ff 222.25 scf sf 6030 3645 m gs 1 -1 sc (write_DynData) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/ds_writing/device_et.eps0000644023471100065110000006152513034745264016114 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: device_et.eps %%Creator: fig2dev Version 3.2 Patchlevel 3d %%CreationDate: Fri Oct 1 15:31:45 2004 %%For: taurel@wow (E.Taurel,,,) %%BoundingBox: 0 0 839 982 %%Magnification: 0.9000 %%EndComments /MyAppDict 100 dict dup begin def /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 982 moveto 0 0 lineto 839 0 lineto 839 982 lineto closepath clip newpath -35.0 1087.5 translate 1 -1 scale % This junk string is used by the show operators /PATsstr 1 string def /PATawidthshow { % cx cy cchar rx ry string % Loop over each character in the string { % cx cy cchar rx ry char % Show the character dup % cx cy cchar rx ry char char PATsstr dup 0 4 -1 roll put % cx cy cchar rx ry char (char) false charpath % cx cy cchar rx ry char /clip load PATdraw % Move past the character (charpath modified the % current point) currentpoint % cx cy cchar rx ry char x y newpath moveto % cx cy cchar rx ry char % Reposition by cx,cy if the character in the string is cchar 3 index eq { % cx cy cchar rx ry 4 index 4 index rmoveto } if % Reposition all characters by rx ry 2 copy rmoveto % cx cy cchar rx ry } forall pop pop pop pop pop % - currentpoint newpath moveto } bind def /PATcg { 7 dict dup begin /lw currentlinewidth def /lc currentlinecap def /lj currentlinejoin def /ml currentmiterlimit def /ds [ currentdash ] def /cc [ currentrgbcolor ] def /cm matrix currentmatrix def end } bind def % PATdraw - calculates the boundaries of the object and % fills it with the current pattern /PATdraw { % proc save exch PATpcalc % proc nw nh px py 5 -1 roll exec % nw nh px py newpath PATfill % - restore } bind def % PATfill - performs the tiling for the shape /PATfill { % nw nh px py PATfill - PATDict /CurrentPattern get dup begin setfont % Set the coordinate system to Pattern Space PatternGState PATsg % Set the color for uncolored pattezns PaintType 2 eq { PATDict /PColor get PATsc } if % Create the string for showing 3 index string % nw nh px py str % Loop for each of the pattern sources 0 1 Multi 1 sub { % nw nh px py str source % Move to the starting location 3 index 3 index % nw nh px py str source px py moveto % nw nh px py str source % For multiple sources, set the appropriate color Multi 1 ne { dup PC exch get PATsc } if % Set the appropriate string for the source 0 1 7 index 1 sub { 2 index exch 2 index put } for pop % Loop over the number of vertical cells 3 index % nw nh px py str nh { % nw nh px py str currentpoint % nw nh px py str cx cy 2 index oldshow % nw nh px py str cx cy YStep add moveto % nw nh px py str } repeat % nw nh px py str } for 5 { pop } repeat end } bind def % PATkshow - kshow with the current pattezn /PATkshow { % proc string exch bind % string proc 1 index 0 get % string proc char % Loop over all but the last character in the string 0 1 4 index length 2 sub { % string proc char idx % Find the n+1th character in the string 3 index exch 1 add get % string proe char char+1 exch 2 copy % strinq proc char+1 char char+1 char % Now show the nth character PATsstr dup 0 4 -1 roll put % string proc chr+1 chr chr+1 (chr) false charpath % string proc char+1 char char+1 /clip load PATdraw % Move past the character (charpath modified the current point) currentpoint newpath moveto % Execute the user proc (should consume char and char+1) mark 3 1 roll % string proc char+1 mark char char+1 4 index exec % string proc char+1 mark... cleartomark % string proc char+1 } for % Now display the last character PATsstr dup 0 4 -1 roll put % string proc (char+1) false charpath % string proc /clip load PATdraw neewath pop pop % - } bind def % PATmp - the makepattern equivalent /PATmp { % patdict patmtx PATmp patinstance exch dup length 7 add % We will add 6 new entries plus 1 FID dict copy % Create a new dictionary begin % Matrix to install when painting the pattern TilingType PATtcalc /PatternGState PATcg def PatternGState /cm 3 -1 roll put % Check for multi pattern sources (Level 1 fast color patterns) currentdict /Multi known not { /Multi 1 def } if % Font dictionary definitions /FontType 3 def % Create a dummy encoding vector /Encoding 256 array def 3 string 0 1 255 { Encoding exch dup 3 index cvs cvn put } for pop /FontMatrix matrix def /FontBBox BBox def /BuildChar { mark 3 1 roll % mark dict char exch begin Multi 1 ne {PaintData exch get}{pop} ifelse % mark [paintdata] PaintType 2 eq Multi 1 ne or { XStep 0 FontBBox aload pop setcachedevice } { XStep 0 setcharwidth } ifelse currentdict % mark [paintdata] dict /PaintProc load % mark [paintdata] dict paintproc end gsave false PATredef exec true PATredef grestore cleartomark % - } bind def currentdict end % newdict /foo exch % /foo newlict definefont % newfont } bind def % PATpcalc - calculates the starting point and width/height % of the tile fill for the shape /PATpcalc { % - PATpcalc nw nh px py PATDict /CurrentPattern get begin gsave % Set up the coordinate system to Pattern Space % and lock down pattern PatternGState /cm get setmatrix BBox aload pop pop pop translate % Determine the bounding box of the shape pathbbox % llx lly urx ury grestore % Determine (nw, nh) the # of cells to paint width and height PatHeight div ceiling % llx lly urx qh 4 1 roll % qh llx lly urx PatWidth div ceiling % qh llx lly qw 4 1 roll % qw qh llx lly PatHeight div floor % qw qh llx ph 4 1 roll % ph qw qh llx PatWidth div floor % ph qw qh pw 4 1 roll % pw ph qw qh 2 index sub cvi abs % pw ph qs qh-ph exch 3 index sub cvi abs exch % pw ph nw=qw-pw nh=qh-ph % Determine the starting point of the pattern fill %(px, py) 4 2 roll % nw nh pw ph PatHeight mul % nw nh pw py exch % nw nh py pw PatWidth mul exch % nw nh px py end } bind def % Save the original routines so that we can use them later on /oldfill /fill load def /oldeofill /eofill load def /oldstroke /stroke load def /oldshow /show load def /oldashow /ashow load def /oldwidthshow /widthshow load def /oldawidthshow /awidthshow load def /oldkshow /kshow load def % These defs are necessary so that subsequent procs don't bind in % the originals /fill { oldfill } bind def /eofill { oldeofill } bind def /stroke { oldstroke } bind def /show { oldshow } bind def /ashow { oldashow } bind def /widthshow { oldwidthshow } bind def /awidthshow { oldawidthshow } bind def /kshow { oldkshow } bind def /PATredef { MyAppDict begin { /fill { /clip load PATdraw newpath } bind def /eofill { /eoclip load PATdraw newpath } bind def /stroke { PATstroke } bind def /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def /ashow { 0 0 null 6 3 roll PATawidthshow } bind def /widthshow { 0 0 3 -1 roll PATawidthshow } bind def /awidthshow { PATawidthshow } bind def /kshow { PATkshow } bind def } { /fill { oldfill } bind def /eofill { oldeofill } bind def /stroke { oldstroke } bind def /show { oldshow } bind def /ashow { oldashow } bind def /widthshow { oldwidthshow } bind def /awidthshow { oldawidthshow } bind def /kshow { oldkshow } bind def } ifelse end } bind def false PATredef % Conditionally define setcmykcolor if not available /setcmykcolor where { pop } { /setcmykcolor { 1 sub 4 1 roll 3 { 3 index add neg dup 0 lt { pop 0 } if 3 1 roll } repeat setrgbcolor - pop } bind def } ifelse /PATsc { % colorarray aload length % c1 ... cn length dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor } ifelse } ifelse } bind def /PATsg { % dict begin lw setlinewidth lc setlinecap lj setlinejoin ml setmiterlimit ds aload pop setdash cc aload pop setrgbcolor cm setmatrix end } bind def /PATDict 3 dict def /PATsp { true PATredef PATDict begin /CurrentPattern exch def % If it's an uncolored pattern, save the color CurrentPattern /PaintType get 2 eq { /PColor exch def } if /CColor [ currentrgbcolor ] def end } bind def % PATstroke - stroke with the current pattern /PATstroke { countdictstack save mark { currentpoint strokepath moveto PATpcalc % proc nw nh px py clip newpath PATfill } stopped { (*** PATstroke Warning: Path is too complex, stroking with gray) = cleartomark restore countdictstack exch sub dup 0 gt { { end } repeat } { pop } ifelse gsave 0.5 setgray oldstroke grestore } { pop restore pop } ifelse newpath } bind def /PATtcalc { % modmtx tilingtype PATtcalc tilematrix % Note: tiling types 2 and 3 are not supported gsave exch concat % tilingtype matrix currentmatrix exch % cmtx tilingtype % Tiling type 1 and 3: constant spacing 2 ne { % Distort the pattern so that it occupies % an integral number of device pixels dup 4 get exch dup 5 get exch % tx ty cmtx XStep 0 dtransform round exch round exch % tx ty cmtx dx.x dx.y XStep div exch XStep div exch % tx ty cmtx a b 0 YStep dtransform round exch round exch % tx ty cmtx a b dy.x dy.y YStep div exch YStep div exch % tx ty cmtx a b c d 7 -3 roll astore % { a b c d tx ty } } if grestore } bind def /PATusp { false PATredef PATDict begin CColor PATsc end } bind def % this is the pattern fill program from the Second edition Reference Manual % with changes to call the above pattern fill % left30 11 dict begin /PaintType 1 def /PatternType 1 def /TilingType 1 def /BBox [0 0 1 1] def /XStep 1 def /YStep 1 def /PatWidth 1 def /PatHeight 1 def /Multi 2 def /PaintData [ { clippath } bind { 32 16 true [ 32 0 0 -16 0 16 ] {} imagemask } bind ] def /PaintProc { pop exec fill } def currentdict end /P1 exch def /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0.05669 0.05669 sc % % Fig objects follow % % Polyline 7.500 slw n 9090 9720 m 11250 9720 l 11250 11160 l 9090 11160 l cp gs col0 s gr % Polyline n 9090 10080 m 11250 10080 l gs col0 s gr /Courier ff 180.00 scf sf 9585 10380 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier ff 180.00 scf sf 9765 10695 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier ff 180.00 scf sf 9465 9960 m gs 1 -1 sc (DevReadPosition) col0 sh gr % Polyline n 11565 9720 m 13725 9720 l 13725 11160 l 11565 11160 l cp gs col0 s gr % Polyline n 11565 10080 m 13725 10080 l gs col0 s gr /Courier ff 180.00 scf sf 12060 10380 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier ff 180.00 scf sf 12240 10695 m gs 1 -1 sc (execute\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 11970 9945 m gs 1 -1 sc (TemplCommand) col0 sh gr % Polyline n 12510 11970 m 12780 11700 l 13050 11970 l gs col0 s gr % Polyline n 6390 4770 m 6750 4770 l 6570 4500 l 6390 4770 l cp gs col0 s gr % Polyline n 6390 16920 m 6750 16920 l 6570 16650 l 6390 16920 l cp gs col0 s gr % Polyline gs clippath 6600 2190 m 6540 2190 l 6540 2341 l 6570 2221 l 6600 2341 l cp eoclip n 6570 2610 m 6570 2205 l gs col0 s gr gr % arrowhead n 6600 2341 m 6570 2221 l 6540 2341 l 6600 2341 l cp gs 0.00 setgray ef gr col0 s % Polyline n 2610 9720 m 2610 9360 l 10260 9360 l 10260 9720 l gs col0 s gr % Polyline n 5130 9360 m 5130 9720 l gs col0 s gr % Polyline n 7650 9360 m 7650 9720 l gs col0 s gr % Polyline n 6570 8730 m 6570 9090 l gs col0 s gr % Polyline n 6390 9360 m 6570 9090 l gs col0 s gr % Polyline n 7331 9090 m 7339 9090 l gs col0 s gr % Polyline n 6750 9360 m 6570 9090 l gs col0 s gr % Polyline n 2610 7290 m 2610 7020 l gs col0 s gr % Polyline n 2430 7020 m 2790 7020 l 2610 6750 l 2430 7020 l cp gs col0 s gr % Polyline n 2610 6750 m 2610 6480 l gs col0 s gr % Polyline n 6570 5040 m 6570 4770 l gs col0 s gr % Polyline n 6570 4500 m 6570 4230 l gs col0 s gr % Polyline n 3690 6300 m 3870 6120 l gs col0 s gr % Polyline n 3870 6120 m 4050 6300 l 3870 6480 l 3690 6300 l gs col0 s gr % Polyline n 4590 3330 m 5310 3330 l gs /PC [[0.00 0.00 0.00] [0.00 0.00 0.00]] def 15.00 15.00 sc P1 [16 0 0 -8 306.00 222.00] PATmp PATsp ef gr PATusp gs col0 s gr % Polyline n 4050 6300 m 4590 6300 l 4590 8190 l 5400 8190 l gs col0 s gr % Polyline n 1530 7290 m 3690 7290 l 3690 8730 l 1530 8730 l cp gs col0 s gr % Polyline n 5490 5040 m 7650 5040 l 7650 6480 l 5490 6480 l cp gs col0 s gr % Polyline n 1530 5040 m 3690 5040 l 3690 6480 l 1530 6480 l cp gs col0 s gr % Polyline n 1530 9720 m 3690 9720 l 3690 11160 l 1530 11160 l cp gs col0 s gr % Polyline n 6570 9720 m 8730 9720 l 8730 11160 l 6570 11160 l cp gs col0 s gr % Polyline n 4050 9720 m 6210 9720 l 6210 11160 l 4050 11160 l cp gs col0 s gr % Polyline n 1530 10080 m 3690 10080 l gs col0 s gr % Polyline n 4050 10080 m 6210 10080 l gs col0 s gr % Polyline n 6570 10080 m 8730 10080 l gs col0 s gr % Polyline n 5490 7650 m 7650 7650 l gs col0 s gr % Polyline n 1530 7650 m 3690 7650 l gs col0 s gr % Polyline n 1530 5400 m 3690 5400 l gs col0 s gr % Polyline n 5490 5400 m 7650 5400 l gs col0 s gr % Polyline n 5490 2610 m 7650 2610 l 7650 4230 l 5490 4230 l cp gs col0 s gr % Polyline n 5490 2970 m 7650 2970 l gs col0 s gr % Polyline n 5490 3870 m 7650 3870 l gs col0 s gr % Polyline n 10260 9360 m 12690 9360 l 12690 9675 l gs col0 s gr % Polyline n 4005 12330 m 6165 12330 l 6165 13770 l 4005 13770 l cp gs col0 s gr % Polyline n 4005 12690 m 6165 12690 l gs col0 s gr % Polyline n 6570 12330 m 8730 12330 l 8730 13770 l 6570 13770 l cp gs col0 s gr % Polyline n 6570 12690 m 8730 12690 l gs col0 s gr % Polyline n 9180 12330 m 11340 12330 l 11340 13770 l 9180 13770 l cp gs col0 s gr % Polyline n 9180 12690 m 11340 12690 l gs col0 s gr % Polyline n 7740 11970 m 7740 12330 l gs col0 s gr % Polyline n 10350 11970 m 10350 12330 l gs col0 s gr % Polyline n 5040 12330 m 5040 11970 l 13050 11970 l gs col0 s gr % Polyline n 12780 11700 m 12780 11160 l gs col0 s gr % Polyline n 630 1890 m 15390 1890 l 15390 19170 l 630 19170 l cp gs col0 s gr % Polyline [15 45] 45 sd n 5220 4860 m 7920 4860 l 7920 6660 l 5220 6660 l cp gs col0 s gr [] 0 sd % Polyline [15 45] 45 sd n 1350 7200 m 3870 7200 l 3870 8910 l 1350 8910 l cp gs col0 s gr [] 0 sd % Polyline [15 45] 45 sd n 9000 9630 m 11340 9630 l 11340 11340 l 9000 11340 l cp gs col0 s gr [] 0 sd % Polyline [15 45] 45 sd n 5310 3330 m 5490 3330 l gs col0 s gr [] 0 sd % Polyline [15 45] 45 sd n 5400 8190 m 5490 8190 l gs col0 s gr [] 0 sd % Polyline n 6570 16650 m 6570 16380 l gs col0 s gr % Polyline n 6570 17370 m 6570 16920 l gs col0 s gr % Polyline n 5490 15300 m 7650 15300 l gs col0 s gr % Polyline n 9180 15300 m 11340 15300 l gs col0 s gr % Polyline n 5490 17730 m 7650 17730 l gs col0 s gr % Polyline n 5490 17370 m 7650 17370 l 7650 18810 l 5490 18810 l cp gs col0 s gr % Polyline n 9180 14940 m 11340 14940 l 11340 16380 l 9180 16380 l cp gs col0 s gr % Polyline n 5490 14940 m 7650 14940 l 7650 16380 l 5490 16380 l cp gs col0 s gr % Polyline n 9180 15750 m 9000 15570 l 8820 15750 l 9000 15930 l 9180 15750 l cp gs col0 s gr % Polyline n 7650 15750 m 8820 15750 l gs col0 s gr % Polyline n 7672 3262 m 7852 3082 l 8032 3262 l 7852 3442 l 7672 3262 l cp gs col0 s gr % Polyline n 7830 3600 m 8010 3780 l 7830 3960 l 7650 3780 l gs col0 s gr % Polyline n 1530 2610 m 3690 2610 l 3690 4050 l 1530 4050 l cp gs col0 s gr % Polyline n 1530 2970 m 3690 2970 l gs col0 s gr % Polyline n 1350 5670 m 1530 5850 l 1350 6030 l 1170 5850 l gs col0 s gr % Polyline n 1170 5850 m 900 5850 l 900 3330 l 1530 3330 l gs col0 s gr % Polyline n 5490 7278 m 7650 7278 l 7650 8718 l 5490 8718 l cp gs col0 s gr % Polyline n 1170 5850 m 1350 5670 l gs col0 s gr % Polyline n 7650 3780 m 7830 3600 l gs col0 s gr % Polyline n 8010 3240 m 14220 3240 l 14220 15750 l 11340 15750 l gs col0 s gr % Polyline n 3870 5265 m 4050 5445 l 3870 5625 l 3690 5445 l gs col0 s gr % Polyline n 3870 5670 m 4050 5850 l 3870 6030 l 3690 5850 l gs col0 s gr % Polyline n 9855 3465 m 12015 3465 l 12015 4905 l 9855 4905 l cp gs col0 s gr % Polyline n 9855 3870 m 12015 3870 l gs col0 s gr % Polyline n 9900 5310 m 12060 5310 l 12060 6750 l 9900 6750 l cp gs col0 s gr % Polyline n 8415 7335 m 10575 7335 l 10575 8775 l 8415 8775 l cp gs col0 s gr % Polyline n 11475 7335 m 13635 7335 l 13635 8775 l 11475 8775 l cp gs col0 s gr % Polyline n 9900 5715 m 12060 5715 l gs col0 s gr % Polyline n 8415 7740 m 10575 7740 l gs col0 s gr % Polyline n 11475 7740 m 13635 7740 l gs col0 s gr /Courier-Oblique ff 180.00 scf sf 6585 2850 m gs 1 -1 sc (DeviceImpl) dup sw pop 2 div neg 0 rm col0 sh gr /Courier-Oblique ff 180.00 scf sf 2625 5280 m gs 1 -1 sc (DeviceClass) dup sw pop 2 div neg 0 rm col0 sh gr /Courier-Oblique ff 180.00 scf sf 6600 3180 m gs 1 -1 sc (init_device\(\)=0) dup sw pop 2 div neg 0 rm col0 sh gr /Courier-Oblique ff 180.00 scf sf 5595 3405 m gs 1 -1 sc (attribute_factory\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 5700 3660 m gs 1 -1 sc (command_factory\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 6240 7515 m gs 1 -1 sc (Command) col0 sh gr /Courier-Oblique ff 180.00 scf sf 5850 7965 m gs 1 -1 sc (is_allowed\(\)=0) col0 sh gr /Courier-Oblique ff 180.00 scf sf 5985 8250 m gs 1 -1 sc (execute\(\)=0) col0 sh gr /Courier-Oblique ff 180.00 scf sf 2190 9975 m gs 1 -1 sc (DevState) col0 sh gr /Courier-Oblique ff 180.00 scf sf 4725 9960 m gs 1 -1 sc (DevStatus) col0 sh gr /Courier-Oblique ff 180.00 scf sf 7200 9960 m gs 1 -1 sc (DevRestart) col0 sh gr /Courier-Oblique ff 180.00 scf sf 2010 10410 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 2160 10755 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 4530 10380 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 7050 10365 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 4650 10710 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 7200 10695 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier ff 180.00 scf sf 1755 7530 m gs 1 -1 sc (StepperMotorClass) col0 sh gr /Courier ff 180.00 scf sf 1860 7935 m gs 1 -1 sc (device_factory\(\)) col0 sh gr /Courier ff 180.00 scf sf 1800 8235 m gs 1 -1 sc (command_factory\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 6090 4095 m gs 1 -1 sc (dev_state) col0 sh gr /Courier ff 180.00 scf sf 6030 5280 m gs 1 -1 sc (StpperMotor) col0 sh gr /Courier ff 180.00 scf sf 5940 5670 m gs 1 -1 sc (init_device\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 5970 2145 m gs 1 -1 sc (CORBA classes) col0 sh gr /Courier ff 180.00 scf sf 5535 6030 m gs 1 -1 sc (dev_read_position\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 1680 5730 m gs 1 -1 sc (device_factory\(\)=0) col0 sh gr /Courier-Oblique ff 180.00 scf sf 1620 6030 m gs 1 -1 sc (command_factory\(\)=0) col0 sh gr /Courier ff 180.00 scf sf 4500 12990 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier ff 180.00 scf sf 4680 13305 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier ff 180.00 scf sf 7065 12990 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier ff 180.00 scf sf 7245 13305 m gs 1 -1 sc (execute\(\)) col0 sh gr /Courier ff 180.00 scf sf 9675 12990 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier ff 180.00 scf sf 9855 13305 m gs 1 -1 sc (execute\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 4230 12600 m gs 1 -1 sc (TemplCommandIn) col0 sh gr /Times-Roman ff 210.00 scf sf 6750 12600 m gs 1 -1 sc (TemplCommandOut) col0 sh gr /Times-Roman ff 210.00 scf sf 9270 12600 m gs 1 -1 sc (TemplCommandInOut) col0 sh gr /Times-Roman ff 210.00 scf sf 5040 3240 m gs 1 -1 sc (1,..n) col0 sh gr /Times-Roman ff 210.00 scf sf 5040 8100 m gs 1 -1 sc (1,..n) col0 sh gr /Times-Roman ff 210.00 scf sf 9675 15210 m gs 1 -1 sc (MultiAttribute) col0 sh gr /Times-Roman ff 210.00 scf sf 6165 15210 m gs 1 -1 sc (Attribute) col0 sh gr /Times-Roman ff 210.00 scf sf 6120 17640 m gs 1 -1 sc (WAttribute) col0 sh gr /Times-Roman ff 210.00 scf sf 11475 15660 m gs 1 -1 sc (1) col0 sh gr /Times-Roman ff 210.00 scf sf 7740 15660 m gs 1 -1 sc (1,..n) col0 sh gr /Times-Roman ff 210.00 scf sf 6120 15660 m gs 1 -1 sc (set_value\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 6120 15930 m gs 1 -1 sc (get_name\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 5850 18180 m gs 1 -1 sc (get_write_value\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 9765 16155 m gs 1 -1 sc (read_alarm\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 9675 15885 m gs 1 -1 sc (check_alarm\(\)) col0 sh gr /Times-Roman ff 210.00 scf sf 9855 15615 m gs 1 -1 sc (get_attr....\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 2280 2850 m gs 1 -1 sc (DbClass) col0 sh gr /Times-Roman ff 180.00 scf sf 2040 3330 m gs 1 -1 sc (get_property\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 2070 3600 m gs 1 -1 sc (put_prperty\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 1350 3240 m gs 1 -1 sc (1) col0 sh gr /Times-Roman ff 180.00 scf sf 10575 3735 m gs 1 -1 sc (DbDevice) col0 sh gr /Times-Roman ff 180.00 scf sf 10395 4230 m gs 1 -1 sc (get_property\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 10395 4500 m gs 1 -1 sc (put_property\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 10710 6300 m gs 1 -1 sc (read\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 9180 8325 m gs 1 -1 sc (read\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 12330 8370 m gs 1 -1 sc (read\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 10215 6030 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 8730 8055 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr /Courier-Oblique ff 180.00 scf sf 11745 8055 m gs 1 -1 sc (is_allowed\(\)) col0 sh gr % Polyline n 4590 3330 m 4590 5445 l 4050 5445 l gs col0 s gr % Polyline n 9450 7155 m 12645 7155 l 12645 7335 l gs col0 s gr % Polyline n 9450 7155 m 9450 7335 l gs col0 s gr % Polyline n 10800 7155 m 10980 6975 l 11160 7155 l gs col0 s gr % Polyline n 10980 6975 m 10980 6750 l gs col0 s gr % Polyline n 8010 3780 m 9450 3780 l 9450 3645 l 9855 3645 l gs col0 s gr % Polyline n 4050 5850 m 4860 5850 l 4860 6930 l 9450 6930 l 9450 5490 l 9900 5490 l gs col0 s gr % Polyline n 3690 5850 m 3870 5670 l gs col0 s gr % Polyline n 3690 5445 m 3870 5265 l gs col0 s gr /Times-Roman ff 180.00 scf sf 9675 3555 m gs 1 -1 sc (1) col0 sh gr /Times-Roman ff 180.00 scf sf 9495 5400 m gs 1 -1 sc (1,..n) col0 sh gr /Times-Roman ff 180.00 scf sf 10755 5580 m gs 1 -1 sc (Attr) col0 sh gr /Times-Roman ff 180.00 scf sf 9045 7605 m gs 1 -1 sc (PositionAttr) col0 sh gr /Times-Roman ff 180.00 scf sf 12060 7605 m gs 1 -1 sc (SetPositionAttr) col0 sh gr $F2psEnd rs end tango-9.2.5a/doc/src/ds_writing/command.fig0000644023471100065110000000557413034745264015563 00000000000000#FIG 3.2 Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 1440 5580 1440 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 2340 990 2340 1170 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 5850 1080 5850 1440 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1170 2070 1170 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 5670 1440 6030 1440 6030 4590 5670 4590 5670 1440 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9360 4320 6120 4320 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5580 4590 2610 4590 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 6120 3600 9360 3600 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9360 3150 6120 3150 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 6120 2340 9360 2340 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 9450 2340 9810 2340 9810 3150 9450 3150 9450 2340 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9450 3600 9810 3600 9810 4320 9450 4320 9450 3600 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 9630 3150 9630 3600 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 9630 4320 9630 4590 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 12420 3690 12780 3690 12780 4230 12420 4230 12420 3690 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 12600 4230 12600 4500 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 6120 1620 12330 1620 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 12330 1980 6120 1980 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 12420 1620 12780 1620 12780 1980 12420 1980 12420 1620 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 12600 1080 12600 1620 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 12600 1980 12600 3690 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 12330 4230 9900 4230 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9900 3780 12330 3780 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 2160 1170 2520 1170 2520 4590 2160 4590 2160 1170 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2340 4590 2340 4770 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 9630 2070 9630 2340 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 5850 4590 5850 4860 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 630 360 13590 360 13590 5130 630 5130 630 360 4 0 0 100 0 12 12 0.0000 4 180 1575 2790 1350 command_handler\001 4 0 0 100 0 0 12 0.0000 4 180 1545 1710 810 StepperMotor object\001 4 0 0 100 0 0 12 0.0000 4 180 2220 4860 810 StepperMotorClass singleton\001 4 0 0 100 0 0 12 0.0000 4 135 1320 9000 810 DevReadPosition\001 4 0 0 100 0 0 12 0.0000 4 180 1545 11790 810 StepperMotor object\001 4 0 0 100 0 0 12 0.0000 4 180 1170 900 1080 command_inout\001 4 0 0 100 0 12 12 0.0000 4 120 735 6300 3510 execute\001 4 0 0 100 0 12 12 0.0000 4 180 1050 6210 2250 is_allowed\001 4 0 0 100 0 0 12 0.0000 4 180 1755 6210 1530 always_executed_hook\001 4 0 0 100 0 12 12 0.0000 4 180 1785 10080 3600 dev_read_position\001 tango-9.2.5a/doc/src/ds_writing/complete_server.eps0000644023471100065110000001325513034745264017360 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: complete_server.eps %%Creator: fig2dev Version 3.2 Patchlevel 1 %%CreationDate: Tue Feb 20 16:47:08 2001 %%For: taurel@amber13.esrf.fr (E.Taurel,,,) %%Orientation: Portrait %%BoundingBox: 0 0 745 416 %%Pages: 0 %%BeginSetup %%EndSetup %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save -50.0 460.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def %%EndProlog $F2psBegin 10 setmiterlimit n -1000 8302 m -1000 -1000 l 13612 -1000 l 13612 8302 l cp clip 0.06299 0.06299 sc 7.500 slw [60] 0 sd % Ellipse n 7425 5580 45 45 0 360 DrawEllipse gs col7 0.00 shd ef gr gs col0 s gr [] 0 sd % Polyline n 7470 4860 m 9540 4860 l 9540 6030 l 7470 6030 l cp gs col0 s gr % Polyline n 7470 5220 m 9540 5220 l gs col0 s gr /Times-Roman ff 180.00 scf sf 8250 5115 m gs 1 -1 sc (AClass) col0 sh gr % Polyline n 3780 3150 m 5850 3150 l 5850 4320 l 3780 4320 l cp gs col0 s gr % Polyline n 3780 3510 m 5850 3510 l gs col0 s gr % Polyline n 4590 4680 m 4950 4680 l 4770 4500 l 4590 4680 l cp gs col0 s gr % Polyline n 4770 4500 m 4770 4320 l gs col0 s gr /Times-Roman ff 180.00 scf sf 4410 3420 m gs 1 -1 sc (DeviceImpl) col0 sh gr % Polyline n 4770 4860 m 4770 4680 l gs col0 s gr % Polyline n 6030 5580 m 7380 5580 l gs col0 s gr % Polyline n 8460 4860 m 8460 4680 l gs col0 s gr % Polyline n 7470 3150 m 9540 3150 l 9540 4320 l 7470 4320 l cp gs col0 s gr % Polyline n 7470 3510 m 9540 3510 l gs col0 s gr % Polyline n 8280 4680 m 8640 4680 l 8460 4500 l 8280 4680 l cp gs col0 s gr % Polyline n 8460 4500 m 8460 4320 l gs col0 s gr % Polyline [60] 0 sd n 1440 2790 m 6300 2790 l 6300 6840 l 1440 6840 l cp gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 7110 2790 m 11970 2790 l 11970 6840 l 7110 6840 l cp gs col0 s gr [] 0 sd % Polyline n 810 720 m 12600 720 l 12600 7290 l 810 7290 l cp gs col0 s gr % Polyline n 4005 945 m 6075 945 l 6075 2115 l 4005 2115 l cp gs col0 s gr % Polyline n 4005 1305 m 6075 1305 l gs col0 s gr % Polyline n 7335 945 m 9405 945 l 9405 2115 l 7335 2115 l cp gs col0 s gr % Polyline n 7335 1305 m 9405 1305 l gs col0 s gr % Polyline n 3780 4860 m 5850 4860 l 5850 6030 l 3780 6030 l cp gs col0 s gr % Polyline n 3780 5220 m 5850 5220 l gs col0 s gr % Polyline n 5850 5580 m 5940 5490 l 6030 5580 l 5940 5670 l 5850 5580 l cp gs col0 s gr % Polyline n 6075 1620 m 6165 1530 l 6255 1620 l 6165 1710 l 6075 1620 l cp gs col0 s gr % Polyline n 6255 1620 m 7335 1620 l gs col0 s gr /Times-Roman ff 180.00 scf sf 8100 3420 m gs 1 -1 sc (DeviceClass) col0 sh gr /Times-Roman ff 180.00 scf sf 1890 6660 m gs 1 -1 sc (Device server pattern implementing the DServer class) col0 sh gr /Times-Roman ff 180.00 scf sf 7470 6660 m gs 1 -1 sc (Device server pattern\(s\) implementing device class\(es\)) col0 sh gr /Times-Roman ff 180.00 scf sf 4635 1185 m gs 1 -1 sc (Tango::Util) col0 sh gr /Times-Roman ff 180.00 scf sf 4485 5115 m gs 1 -1 sc (DServer) col0 sh gr /Times-Roman ff 180.00 scf sf 8010 1170 m gs 1 -1 sc (Database) col0 sh gr /Times-Roman ff 180.00 scf sf 4545 1575 m gs 1 -1 sc (server_init\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 4545 1845 m gs 1 -1 sc (server_run\(\)) col0 sh gr /Times-Roman ff 180.00 scf sf 7155 1530 m gs 1 -1 sc (1) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/ds_writing/w_pipe.fig0000644023471100065110000000552513034745264015424 00000000000000#FIG 3.2 Produced by xfig version 3.2.5c Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 2340 990 2340 1170 2 1 0 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1170 2070 1170 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2340 4590 2340 4770 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 1350 9000 1350 9000 1930 8640 1930 8640 1350 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 3780 9000 3780 9000 4360 8640 4360 8640 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 1080 8820 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 8820 4410 8820 4680 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 4320 5850 4320 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 4410 5580 4590 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5580 1080 5580 1260 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 3690 5310 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 4410 2610 4410 2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 540 360 9810 360 9810 5040 540 5040 540 360 2 2 0 1 0 0 100 0 -1 4.000 0 0 -1 0 0 5 2160 1170 2520 1170 2520 4590 2160 4590 2160 1170 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 1890 2610 1890 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 2475 5760 2475 5760 3185 5400 3185 5400 2475 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2610 1350 8550 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8550 3060 5850 3060 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2655 2520 5265 2520 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5310 3150 2610 3150 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 1440 5580 1755 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 2025 5580 2475 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8640 2475 9000 2475 9000 3055 8640 3055 8640 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 2070 8820 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 8820 3240 8820 3780 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5850 2565 8550 2565 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 5400 3690 5760 3690 5760 4400 5400 4400 5400 3690 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5580 3375 5580 3690 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5895 3825 8595 3825 4 0 0 100 0 0 12 0.0000 4 165 1800 2700 1260 always_executed_hook\001 4 0 0 50 0 0 12 0.0000 4 165 1710 7920 810 StepperMotor object\001 4 0 0 50 0 0 12 0.0000 4 150 900 2745 2385 is_allowed\001 4 0 0 50 -1 0 12 0.0000 4 165 1080 1845 855 Device_5Impl\001 4 0 0 50 -1 0 14 0.0000 4 165 1530 4905 900 DynDataPipe class\001 4 0 0 50 -1 0 14 0.0000 4 165 1620 5940 2385 is_DynData_allowed\001 4 0 0 50 -1 0 12 0.0000 4 150 900 855 1035 write_pipe\001 4 0 0 50 -1 0 14 0.0000 4 120 450 2745 3555 write\001 4 0 0 50 -1 0 14 0.0000 4 165 1170 6030 3645 write_DynData\001 tango-9.2.5a/doc/src/ds_writing/startup.eps0000644023471100065110000002446113034745264015665 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Title: startup.fig %%Creator: fig2dev Version 3.2 Patchlevel 5e %%CreationDate: Wed Jul 8 09:18:13 2015 %%BoundingBox: 0 0 1000 319 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 319 moveto 0 0 lineto 1000 0 lineto 1000 319 lineto closepath clip newpath -44.6 363.6 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 100 % Polyline 0 slj 0 slc 7.500 slw [60] 0 sd gs clippath 2743 1560 m 2895 1560 l 2895 1500 l 2743 1500 l 2743 1500 l 2863 1530 l 2743 1560 l cp eoclip n 990 1530 m 2880 1530 l gs col0 s gr gr [] 0 sd % arrowhead n 2743 1560 m 2863 1530 l 2743 1500 l col0 s % Polyline [60] 0 sd gs clippath 2743 2640 m 2895 2640 l 2895 2580 l 2743 2580 l 2743 2580 l 2863 2610 l 2743 2640 l cp eoclip n 990 2610 m 2880 2610 l gs col0 s gr gr [] 0 sd % arrowhead n 2743 2640 m 2863 2610 l 2743 2580 l col0 s % Polyline [60] 0 sd gs clippath 2743 3360 m 2895 3360 l 2895 3300 l 2743 3300 l 2743 3300 l 2863 3330 l 2743 3360 l cp eoclip n 990 3330 m 2880 3330 l gs col0 s gr gr [] 0 sd % arrowhead n 2743 3360 m 2863 3330 l 2743 3300 l col0 s % Polyline [60] 0 sd n 3150 1080 m 3150 1530 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 4950 1080 m 4950 1530 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 6300 1080 m 6300 1710 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 7380 1080 m 7380 1890 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 8550 1080 m 8550 2070 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 4543 1560 m 4695 1560 l 4695 1500 l 4543 1500 l 4543 1500 l 4663 1530 l 4543 1560 l cp eoclip n 3420 1530 m 4680 1530 l gs col0 s gr gr [] 0 sd % arrowhead n 4543 1560 m 4663 1530 l 4543 1500 l col0 s % Polyline [60] 0 sd gs clippath 5893 1740 m 6045 1740 l 6045 1680 l 5893 1680 l 5893 1680 l 6013 1710 l 5893 1740 l cp eoclip n 5220 1710 m 6030 1710 l gs col0 s gr gr [] 0 sd % arrowhead n 5893 1740 m 6013 1710 l 5893 1680 l col0 s % Polyline [60] 0 sd gs clippath 7063 1920 m 7215 1920 l 7215 1860 l 7063 1860 l 7063 1860 l 7183 1890 l 7063 1920 l cp eoclip n 6570 1890 m 7020 1890 l 7200 1890 l gs col0 s gr gr [] 0 sd % arrowhead n 7063 1920 m 7183 1890 l 7063 1860 l col0 s % Polyline [60] 0 sd gs clippath 8233 2100 m 8385 2100 l 8385 2040 l 8233 2040 l 8233 2040 l 8353 2070 l 8233 2100 l cp eoclip n 7650 2070 m 8370 2070 l gs col0 s gr gr [] 0 sd % arrowhead n 8233 2100 m 8353 2070 l 8233 2040 l col0 s % Polyline [60] 0 sd n 5220 1890 m 6030 1890 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 5220 2070 m 6030 2070 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 6570 2070 m 7110 2070 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 7650 2790 m 8280 2790 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 6570 2790 m 7110 2790 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 5220 2790 m 6030 2790 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 3420 2790 m 4680 2790 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 6570 3510 m 7110 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 5220 3510 m 6120 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 3420 3510 m 4680 3510 l gs col0 s gr [] 0 sd % Polyline n 2970 1530 m 3330 1530 l 3330 5580 l 2970 5580 l cp gs col0 s gr % Polyline n 4770 1530 m 5130 1530 l 5130 5580 l 4770 5580 l cp gs col0 s gr % Polyline n 6120 1710 m 6480 1710 l 6480 5580 l 6120 5580 l cp gs col0 s gr % Polyline n 7200 1890 m 7560 1890 l 7560 5580 l 7200 5580 l cp gs col0 s gr % Polyline n 8370 2070 m 8730 2070 l 8730 5580 l 8370 5580 l cp gs col0 s gr % Polyline n 9450 2790 m 9810 2790 l 9810 5580 l 9450 5580 l cp gs col0 s gr % Polyline [60] 0 sd n 9630 1080 m 9630 2790 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 7605 3510 m 8325 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 13050 1080 m 13050 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 14490 1080 m 14490 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 14083 3540 m 14235 3540 l 14235 3480 l 14083 3480 l 14083 3480 l 14203 3510 l 14083 3540 l cp eoclip n 13320 3510 m 14220 3510 l gs col0 s gr gr [] 0 sd % arrowhead n 14083 3540 m 14203 3510 l 14083 3480 l col0 s % Polyline n 12870 3510 m 13230 3510 l 13230 5580 l 12870 5580 l cp gs col0 s gr % Polyline n 14310 3510 m 14670 3510 l 14670 5580 l 14310 5580 l cp gs col0 s gr % Polyline n 15660 3780 m 16020 3780 l 16020 5580 l 15660 5580 l cp gs col0 s gr % Polyline [60] 0 sd n 15840 1080 m 15840 3780 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 15433 3810 m 15585 3810 l 15585 3750 l 15433 3750 l 15433 3750 l 15553 3780 l 15433 3810 l cp eoclip n 14760 3780 m 15570 3780 l gs col0 s gr gr [] 0 sd % arrowhead n 15433 3810 m 15553 3780 l 15433 3750 l col0 s % Polyline n 11520 3150 m 11880 3150 l 11880 5580 l 11520 5580 l cp gs col0 s gr % Polyline [60] 0 sd n 11700 1260 m 11700 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 11293 3180 m 11445 3180 l 11445 3120 l 11293 3120 l 11293 3120 l 11413 3150 l 11293 3180 l cp eoclip n 9900 3150 m 11430 3150 l gs col0 s gr gr [] 0 sd % arrowhead n 11293 3180 m 11413 3150 l 11293 3120 l col0 s % Polyline [60] 0 sd n 8820 3150 m 9360 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 7650 3150 m 8280 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 6570 3150 m 7110 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 5220 3150 m 6030 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 3420 3150 m 4680 3150 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 2743 3000 m 2895 3000 l 2895 2940 l 2743 2940 l 2743 2940 l 2863 2970 l 2743 3000 l cp eoclip n 990 2970 m 2880 2970 l gs col0 s gr gr [] 0 sd % arrowhead n 2743 3000 m 2863 2970 l 2743 2940 l col0 s % Polyline [60] 0 sd n 8820 3510 m 9360 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 9900 3510 m 11430 3510 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd gs clippath 12643 3540 m 12795 3540 l 12795 3480 l 12643 3480 l 12643 3480 l 12763 3510 l 12643 3540 l cp eoclip n 11970 3510 m 12780 3510 l gs col0 s gr gr [] 0 sd % arrowhead n 12643 3540 m 12763 3510 l 12643 3480 l col0 s % Polyline [60] 0 sd gs clippath 9223 2820 m 9375 2820 l 9375 2760 l 9223 2760 l 9223 2760 l 9343 2790 l 9223 2820 l cp eoclip n 8820 2790 m 9360 2790 l gs col0 s gr gr [] 0 sd % arrowhead n 9223 2820 m 9343 2790 l 9223 2760 l col0 s % Polyline n 720 720 m 16560 720 l 16560 5760 l 720 5760 l cp gs col0 s gr /Courier ff 180.00 scf sf 1080 1440 m gs 1 -1 sc (init) col0 sh gr /Courier ff 180.00 scf sf 990 2520 m gs 1 -1 sc (command_factory) col0 sh gr /Courier ff 180.00 scf sf 990 3240 m gs 1 -1 sc (device_factory) col0 sh gr /Courier ff 180.00 scf sf 2340 990 m gs 1 -1 sc (StepperMotorClass) col0 sh gr /Courier ff 180.00 scf sf 4410 990 m gs 1 -1 sc (DeviceClass) col0 sh gr /Courier ff 180.00 scf sf 5310 1620 m gs 1 -1 sc (new) col0 sh gr /Courier ff 180.00 scf sf 6660 1800 m gs 1 -1 sc (new) col0 sh gr /Courier ff 180.00 scf sf 7830 1980 m gs 1 -1 sc (new) col0 sh gr /Courier ff 180.00 scf sf 9270 990 m gs 1 -1 sc (DevReadPosition) col0 sh gr /Times-Roman ff 210.00 scf sf 15390 990 m gs 1 -1 sc (Attribute\(s\)) col0 sh gr /Courier ff 180.00 scf sf 12510 990 m gs 1 -1 sc (StepperMotor) col0 sh gr /Courier ff 180.00 scf sf 14040 990 m gs 1 -1 sc (DeviceImpl) col0 sh gr /Courier ff 180.00 scf sf 9000 2700 m gs 1 -1 sc (new) col0 sh gr /Courier ff 180.00 scf sf 10890 3060 m gs 1 -1 sc (new) col0 sh gr /Times-Roman ff 210.00 scf sf 12240 3420 m gs 1 -1 sc (new) col0 sh gr /Times-Roman ff 210.00 scf sf 15030 3690 m gs 1 -1 sc (new) col0 sh gr /Times-Roman ff 210.00 scf sf 990 2880 m gs 1 -1 sc (attribute_factory) col0 sh gr /Times-Roman ff 210.00 scf sf 10980 990 m gs 1 -1 sc (Attribute list) col0 sh gr /Times-Roman ff 240.00 scf sf 5985 990 m gs 1 -1 sc (Status) col0 sh gr /Times-Roman ff 240.00 scf sf 7110 990 m gs 1 -1 sc (State) col0 sh gr /Times-Roman ff 240.00 scf sf 8370 990 m gs 1 -1 sc (Init) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/ds_writing/device_et.fig0000644023471100065110000002741613034745264016073 00000000000000#FIG 3.2 Portrait Center Metric A4 90.00 Single -2 1200 2 6 9090 9720 11250 11160 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9090 9720 11250 9720 11250 11160 9090 11160 9090 9720 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 9090 10080 11250 10080 4 0 0 100 0 12 12 0.0000 4 180 1260 9585 10380 is_allowed()\001 4 0 0 100 0 12 12 0.0000 4 165 945 9765 10695 execute()\001 4 0 0 100 0 12 12 0.0000 4 135 1575 9465 9960 DevReadPosition\001 -6 6 11565 9720 13725 11160 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 11565 9720 13725 9720 13725 11160 11565 11160 11565 9720 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 11565 10080 13725 10080 4 0 0 100 0 12 12 0.0000 4 180 1260 12060 10380 is_allowed()\001 4 0 0 100 0 12 12 0.0000 4 165 945 12240 10695 execute()\001 4 0 0 100 0 0 14 0.0000 4 195 1455 11970 9945 TemplCommand\001 -6 6 12510 11700 13050 11970 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 3 12510 11970 12780 11700 13050 11970 -6 6 6390 4500 6750 4770 6 6390 4500 6750 4770 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 6390 4770 6750 4770 6570 4500 6390 4770 -6 -6 6 6390 16650 6750 16920 6 6390 16650 6750 16920 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 6390 16920 6750 16920 6570 16650 6390 16920 -6 -6 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 6570 2610 6570 2205 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 2610 9720 2610 9360 10260 9360 10260 9720 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 5130 9360 5130 9720 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7650 9360 7650 9720 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6570 8730 6570 9090 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6390 9360 6570 9090 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 1 7335 9090 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6750 9360 6570 9090 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2610 7290 2610 7020 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 2430 7020 2790 7020 2610 6750 2430 7020 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 2610 6750 2610 6480 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6570 5040 6570 4770 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6570 4500 6570 4230 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 3690 6300 3870 6120 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 3870 6120 4050 6300 3870 6480 3690 6300 2 1 0 1 0 0 100 0 41 0.000 0 0 -1 0 0 2 4590 3330 5310 3330 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 4 4050 6300 4590 6300 4590 8190 5400 8190 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 1530 7290 3690 7290 3690 8730 1530 8730 1530 7290 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5490 5040 7650 5040 7650 6480 5490 6480 5490 5040 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 1530 5040 3690 5040 3690 6480 1530 6480 1530 5040 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 1530 9720 3690 9720 3690 11160 1530 11160 1530 9720 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 6570 9720 8730 9720 8730 11160 6570 11160 6570 9720 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 4050 9720 6210 9720 6210 11160 4050 11160 4050 9720 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 1530 10080 3690 10080 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 4050 10080 6210 10080 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 6570 10080 8730 10080 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 5490 7650 7650 7650 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 1530 7650 3690 7650 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 1530 5400 3690 5400 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 5490 5400 7650 5400 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5490 2610 7650 2610 7650 4230 5490 4230 5490 2610 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 5490 2970 7650 2970 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 5490 3870 7650 3870 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 3 10260 9360 12690 9360 12690 9675 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 4005 12330 6165 12330 6165 13770 4005 13770 4005 12330 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 4005 12690 6165 12690 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 6570 12330 8730 12330 8730 13770 6570 13770 6570 12330 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 6570 12690 8730 12690 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9180 12330 11340 12330 11340 13770 9180 13770 9180 12330 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 9180 12690 11340 12690 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7740 11970 7740 12330 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 10350 11970 10350 12330 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 3 5040 12330 5040 11970 13050 11970 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 12780 11700 12780 11160 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 630 1890 15390 1890 15390 19170 630 19170 630 1890 2 2 2 1 0 7 100 0 -1 3.000 0 0 -1 0 0 5 5220 4860 7920 4860 7920 6660 5220 6660 5220 4860 2 2 2 1 0 7 100 0 -1 3.000 0 0 -1 0 0 5 1350 7200 3870 7200 3870 8910 1350 8910 1350 7200 2 2 2 1 0 7 100 0 -1 3.000 0 0 -1 0 0 5 9000 9630 11340 9630 11340 11340 9000 11340 9000 9630 2 1 2 1 0 7 100 0 -1 3.000 0 0 -1 0 0 2 5310 3330 5490 3330 2 1 2 1 0 7 100 0 -1 3.000 0 0 -1 0 0 2 5400 8190 5490 8190 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6570 16650 6570 16380 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6570 17370 6570 16920 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 5490 15300 7650 15300 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 9180 15300 11340 15300 2 1 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 2 5490 17730 7650 17730 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5490 17370 7650 17370 7650 18810 5490 18810 5490 17370 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9180 14940 11340 14940 11340 16380 9180 16380 9180 14940 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5490 14940 7650 14940 7650 16380 5490 16380 5490 14940 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9180 15750 9000 15570 8820 15750 9000 15930 9180 15750 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7650 15750 8820 15750 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 7672 3262 7852 3082 8032 3262 7852 3442 7672 3262 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 7830 3600 8010 3780 7830 3960 7650 3780 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 1530 2610 3690 2610 3690 4050 1530 4050 1530 2610 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 1530 2970 3690 2970 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 1350 5670 1530 5850 1350 6030 1170 5850 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 1170 5850 900 5850 900 3330 1530 3330 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5490 7278 7650 7278 7650 8718 5490 8718 5490 7278 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 1170 5850 1350 5670 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7650 3780 7830 3600 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 8010 3240 14220 3240 14220 15750 11340 15750 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 3870 5265 4050 5445 3870 5625 3690 5445 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 4 3870 5670 4050 5850 3870 6030 3690 5850 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3 4590 3330 4590 5445 4050 5445 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9855 3465 12015 3465 12015 4905 9855 4905 9855 3465 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 9855 3870 12015 3870 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 9900 5310 12060 5310 12060 6750 9900 6750 9900 5310 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 8415 7335 10575 7335 10575 8775 8415 8775 8415 7335 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 11475 7335 13635 7335 13635 8775 11475 8775 11475 7335 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 9900 5715 12060 5715 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 8415 7740 10575 7740 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 11475 7740 13635 7740 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3 9450 7155 12645 7155 12645 7335 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 9450 7155 9450 7335 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 3 10800 7155 10980 6975 11160 7155 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 10980 6975 10980 6750 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 4 8010 3780 9450 3780 9450 3645 9855 3645 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 6 4050 5850 4860 5850 4860 6930 9450 6930 9450 5490 9900 5490 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 3690 5850 3870 5670 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 3690 5445 3870 5265 4 1 0 100 0 13 12 0.0000 4 180 1050 6585 2850 DeviceImpl\001 4 1 0 100 0 13 12 0.0000 4 135 1155 2625 5280 DeviceClass\001 4 1 0 100 0 13 12 0.0000 4 180 1575 6600 3180 init_device()=0\001 4 0 0 100 0 13 12 0.0000 4 180 1995 5595 3405 attribute_factory()\001 4 0 0 100 0 13 12 0.0000 4 180 1785 5700 3660 command_factory()\001 4 0 0 100 0 13 12 0.0000 4 135 735 6240 7515 Command\001 4 0 0 100 0 13 12 0.0000 4 180 1470 5850 7965 is_allowed()=0\001 4 0 0 100 0 13 12 0.0000 4 165 1155 5985 8250 execute()=0\001 4 0 0 100 0 13 12 0.0000 4 120 840 2190 9975 DevState\001 4 0 0 100 0 13 12 0.0000 4 120 945 4725 9960 DevStatus\001 4 0 0 100 0 13 12 0.0000 4 120 1050 7200 9960 DevRestart\001 4 0 0 100 0 13 12 0.0000 4 180 1260 2010 10410 is_allowed()\001 4 0 0 100 0 13 12 0.0000 4 165 945 2160 10755 execute()\001 4 0 0 100 0 13 12 0.0000 4 180 1260 4530 10380 is_allowed()\001 4 0 0 100 0 13 12 0.0000 4 180 1260 7050 10365 is_allowed()\001 4 0 0 100 0 13 12 0.0000 4 165 945 4650 10710 execute()\001 4 0 0 100 0 13 12 0.0000 4 165 945 7200 10695 execute()\001 4 0 0 100 0 12 12 0.0000 4 180 1785 1755 7530 StepperMotorClass\001 4 0 0 100 0 12 12 0.0000 4 180 1680 1860 7935 device_factory()\001 4 0 0 100 0 12 12 0.0000 4 180 1785 1800 8235 command_factory()\001 4 0 0 100 0 13 12 0.0000 4 180 945 6090 4095 dev_state\001 4 0 0 100 0 12 12 0.0000 4 165 1155 6030 5280 StpperMotor\001 4 0 0 100 0 12 12 0.0000 4 180 1365 5940 5670 init_device()\001 4 0 0 100 0 13 12 0.0000 4 135 1365 5970 2145 CORBA classes\001 4 0 0 100 0 12 12 0.0000 4 180 1995 5535 6030 dev_read_position()\001 4 0 0 100 0 13 12 0.0000 4 180 1890 1680 5730 device_factory()=0\001 4 0 0 100 0 13 12 0.0000 4 180 1995 1620 6030 command_factory()=0\001 4 0 0 100 0 12 12 0.0000 4 180 1260 4500 12990 is_allowed()\001 4 0 0 100 0 12 12 0.0000 4 165 945 4680 13305 execute()\001 4 0 0 100 0 12 12 0.0000 4 180 1260 7065 12990 is_allowed()\001 4 0 0 100 0 12 12 0.0000 4 165 945 7245 13305 execute()\001 4 0 0 100 0 12 12 0.0000 4 180 1260 9675 12990 is_allowed()\001 4 0 0 100 0 12 12 0.0000 4 165 945 9855 13305 execute()\001 4 0 0 100 0 0 14 0.0000 4 195 1635 4230 12600 TemplCommandIn\001 4 0 0 100 0 0 14 0.0000 4 195 1770 6750 12600 TemplCommandOut\001 4 0 0 100 0 0 14 0.0000 4 195 1950 9270 12600 TemplCommandInOut\001 4 0 0 100 0 0 14 0.0000 4 180 345 5040 3240 1,..n\001 4 0 0 100 0 0 14 0.0000 4 180 345 5040 8100 1,..n\001 4 0 0 100 0 0 14 0.0000 4 150 1230 9675 15210 MultiAttribute\001 4 0 0 100 0 0 14 0.0000 4 150 780 6165 15210 Attribute\001 4 0 0 100 0 0 14 0.0000 4 150 975 6120 17640 WAttribute\001 4 0 0 100 0 0 14 0.0000 4 150 105 11475 15660 1\001 4 0 0 100 0 0 14 0.0000 4 180 345 7740 15660 1,..n\001 4 0 0 100 0 0 14 0.0000 4 210 975 6120 15660 set_value()\001 4 0 0 100 0 0 14 0.0000 4 210 1005 6120 15930 get_name()\001 4 0 0 100 0 0 14 0.0000 4 210 1545 5850 18180 get_write_value()\001 4 0 0 100 0 0 14 0.0000 4 210 1140 9765 16155 read_alarm()\001 4 0 0 100 0 0 14 0.0000 4 210 1275 9675 15885 check_alarm()\001 4 0 0 100 0 0 14 0.0000 4 210 1005 9855 15615 get_attr....()\001 4 0 0 100 0 -1 12 0.0000 4 135 660 2280 2850 DbClass\001 4 0 0 100 0 -1 12 0.0000 4 180 1110 2040 3330 get_property()\001 4 0 0 100 0 -1 12 0.0000 4 180 1020 2070 3600 put_prperty()\001 4 0 0 100 0 -1 12 0.0000 4 135 90 1350 3240 1\001 4 0 0 100 0 0 12 0.0000 4 135 750 10575 3735 DbDevice\001 4 0 0 100 0 -1 12 0.0000 4 180 1110 10395 4230 get_property()\001 4 0 0 100 0 -1 12 0.0000 4 180 1110 10395 4500 put_property()\001 4 0 0 50 0 0 12 0.0000 4 135 90 9675 3555 1\001 4 0 0 50 0 0 12 0.0000 4 165 315 9495 5400 1,..n\001 4 0 0 50 0 0 12 0.0000 4 135 315 10755 5580 Attr\001 4 0 0 50 0 0 12 0.0000 4 135 930 9045 7605 PositionAttr\001 4 0 0 100 0 13 12 0.0000 4 165 630 10710 6300 read()\001 4 0 0 100 0 13 12 0.0000 4 165 630 9180 8325 read()\001 4 0 0 100 0 13 12 0.0000 4 165 630 12330 8370 read()\001 4 0 0 100 0 13 12 0.0000 4 180 1260 10215 6030 is_allowed()\001 4 0 0 100 0 13 12 0.0000 4 180 1260 8730 8055 is_allowed()\001 4 0 0 100 0 13 12 0.0000 4 180 1260 11745 8055 is_allowed()\001 4 0 0 50 0 0 12 0.0000 4 135 1185 12060 7605 SetPositionAttr\001 tango-9.2.5a/doc/src/ds_writing/complete_server.fig0000644023471100065110000000540713034745264017336 00000000000000#FIG 3.2 Portrait Center Metric A4 100.00 Single -2 1200 2 6 7380 4860 9540 6030 1 4 1 1 0 7 100 0 0 4.000 1 0.0000 7425 5580 45 45 7380 5580 7470 5580 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 7470 4860 9540 4860 9540 6030 7470 6030 7470 4860 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7470 5220 9540 5220 4 0 0 100 0 0 12 0.0000 4 135 570 8250 5115 AClass\001 -6 6 3780 3150 5850 4680 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 3780 3150 5850 3150 5850 4320 3780 4320 3780 3150 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 3780 3510 5850 3510 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 4 4590 4680 4950 4680 4770 4500 4590 4680 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 4770 4500 4770 4320 4 0 0 100 0 0 12 0.0000 4 180 855 4410 3420 DeviceImpl\001 -6 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 4770 4860 4770 4680 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 6030 5580 7380 5580 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 8460 4860 8460 4680 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 7470 3150 9540 3150 9540 4320 7470 4320 7470 3150 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7470 3510 9540 3510 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 4 8280 4680 8640 4680 8460 4500 8280 4680 2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 8460 4500 8460 4320 2 2 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 1440 2790 6300 2790 6300 6840 1440 6840 1440 2790 2 2 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 7110 2790 11970 2790 11970 6840 7110 6840 7110 2790 2 2 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 810 720 12600 720 12600 7290 810 7290 810 720 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 4005 945 6075 945 6075 2115 4005 2115 4005 945 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 4005 1305 6075 1305 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 7335 945 9405 945 9405 2115 7335 2115 7335 945 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 7335 1305 9405 1305 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 3780 4860 5850 4860 5850 6030 3780 6030 3780 4860 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 3780 5220 5850 5220 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 5850 5580 5940 5490 6030 5580 5940 5670 5850 5580 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 6075 1620 6165 1530 6255 1620 6165 1710 6075 1620 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 2 6255 1620 7335 1620 4 0 0 100 0 0 12 0.0000 4 135 960 8100 3420 DeviceClass\001 4 0 0 100 0 0 12 0.0000 4 180 4080 1890 6660 Device server pattern implementing the DServer class\001 4 0 0 100 0 0 12 0.0000 4 180 4215 7470 6660 Device server pattern(s) implementing device class(es)\001 4 0 0 100 0 0 12 0.0000 4 180 825 4635 1185 Tango::Util\001 4 0 0 100 0 0 12 0.0000 4 135 630 4485 5115 DServer\001 4 0 0 100 0 0 12 0.0000 4 135 735 8010 1170 Database\001 4 0 0 100 0 0 12 0.0000 4 180 960 4545 1575 server_init()\001 4 0 0 100 0 0 12 0.0000 4 180 960 4545 1845 server_run()\001 4 0 0 100 0 0 12 0.0000 4 135 90 7155 1530 1\001 tango-9.2.5a/doc/src/ds_writing/r_pipe.eps0000644023471100065110000001621613034745264015440 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Title: r_pipe.fig %%Creator: fig2dev Version 3.2 Patchlevel 5e %%CreationDate: Tue May 5 10:02:04 2015 %%BoundingBox: 0 0 586 297 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 297 moveto 0 0 lineto 586 0 lineto 586 297 lineto closepath clip newpath -33.3 318.2 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 100 % Polyline 0 slj 0 slc 7.500 slw n 2340 990 m 2340 1170 l gs col0 s gr % Polyline gs clippath 1933 1200 m 2085 1200 l 2085 1140 l 1933 1140 l 1933 1140 l 2053 1170 l 1933 1200 l cp eoclip n 990 1170 m 2070 1170 l gs col0 s gr gr % arrowhead n 1933 1200 m 2053 1170 l 1933 1140 l col0 s % Polyline n 2340 4590 m 2340 4770 l gs col0 s gr % Polyline n 8640 1350 m 9000 1350 l 9000 1930 l 8640 1930 l cp gs col0 s gr % Polyline n 8640 3780 m 9000 3780 l 9000 4360 l 8640 4360 l cp gs col0 s gr % Polyline n 2160 1170 m 2520 1170 l 2520 4590 l 2160 4590 l cp gs col0 s gr % Polyline n 5400 2475 m 5760 2475 l 5760 3185 l 5400 3185 l cp gs col0 s gr % Polyline n 8640 2475 m 9000 2475 l 9000 3055 l 8640 3055 l cp gs col0 s gr % Polyline n 5400 3690 m 5760 3690 l 5760 4400 l 5400 4400 l cp gs col0 s gr /Times-Roman ff 190.50 scf sf 2700 1260 m gs 1 -1 sc (always_executed_hook) col0 sh gr % here ends figure; % % here starts figure with depth 50 % Polyline 0 slj 0 slc 7.500 slw n 8820 1080 m 8820 1350 l gs col0 s gr % Polyline n 8820 4410 m 8820 4680 l gs col0 s gr % Polyline gs clippath 5987 4290 m 5835 4290 l 5835 4350 l 5987 4350 l 5987 4350 l 5867 4320 l 5987 4290 l cp eoclip n 8550 4320 m 5850 4320 l gs col0 s gr gr % arrowhead n 5987 4290 m 5867 4320 l 5987 4350 l col0 s % Polyline n 5580 4410 m 5580 4590 l gs col0 s gr % Polyline n 5580 1080 m 5580 1260 l gs col0 s gr % Polyline gs clippath 5173 3720 m 5325 3720 l 5325 3660 l 5173 3660 l 5173 3660 l 5293 3690 l 5173 3720 l cp eoclip n 2610 3690 m 5310 3690 l gs col0 s gr gr % arrowhead n 5173 3720 m 5293 3690 l 5173 3660 l col0 s % Polyline gs clippath 2747 4380 m 2595 4380 l 2595 4440 l 2747 4440 l 2747 4440 l 2627 4410 l 2747 4380 l cp eoclip n 5310 4410 m 2610 4410 l gs col0 s gr gr % arrowhead n 2747 4380 m 2627 4410 l 2747 4440 l col0 s % Polyline n 540 360 m 9810 360 l 9810 5040 l 540 5040 l cp gs col0 s gr % Polyline gs clippath 2747 1860 m 2595 1860 l 2595 1920 l 2747 1920 l 2747 1920 l 2627 1890 l 2747 1860 l cp eoclip n 8550 1890 m 2610 1890 l gs col0 s gr gr % arrowhead n 2747 1860 m 2627 1890 l 2747 1920 l col0 s % Polyline gs clippath 8413 1380 m 8565 1380 l 8565 1320 l 8413 1320 l 8413 1320 l 8533 1350 l 8413 1380 l cp eoclip n 2610 1350 m 8550 1350 l gs col0 s gr gr % arrowhead n 8413 1380 m 8533 1350 l 8413 1320 l col0 s % Polyline gs clippath 5987 3030 m 5835 3030 l 5835 3090 l 5987 3090 l 5987 3090 l 5867 3060 l 5987 3030 l cp eoclip n 8550 3060 m 5850 3060 l gs col0 s gr gr % arrowhead n 5987 3030 m 5867 3060 l 5987 3090 l col0 s % Polyline gs clippath 5128 2550 m 5280 2550 l 5280 2490 l 5128 2490 l 5128 2490 l 5248 2520 l 5128 2550 l cp eoclip n 2655 2520 m 5265 2520 l gs col0 s gr gr % arrowhead n 5128 2550 m 5248 2520 l 5128 2490 l col0 s % Polyline gs clippath 2747 3120 m 2595 3120 l 2595 3180 l 2747 3180 l 2747 3180 l 2627 3150 l 2747 3120 l cp eoclip n 5310 3150 m 2610 3150 l gs col0 s gr gr % arrowhead n 2747 3120 m 2627 3150 l 2747 3180 l col0 s % Polyline n 5580 1440 m 5580 1755 l gs col0 s gr % Polyline n 5580 2025 m 5580 2475 l gs col0 s gr % Polyline n 8820 2070 m 8820 2475 l gs col0 s gr % Polyline n 8820 3240 m 8820 3780 l gs col0 s gr % Polyline gs clippath 8458 3855 m 8610 3855 l 8610 3795 l 8458 3795 l 8458 3795 l 8578 3825 l 8458 3855 l cp eoclip n 5895 3825 m 8595 3825 l gs col0 s gr gr % arrowhead n 8458 3855 m 8578 3825 l 8458 3795 l col0 s % Polyline gs clippath 8413 2595 m 8565 2595 l 8565 2535 l 8413 2535 l 8413 2535 l 8533 2565 l 8413 2595 l cp eoclip n 5850 2565 m 8550 2565 l gs col0 s gr gr % arrowhead n 8413 2595 m 8533 2565 l 8413 2535 l col0 s % Polyline n 5580 3375 m 5580 3690 l gs col0 s gr /Times-Roman ff 190.50 scf sf 2700 3870 m gs 1 -1 sc (read) col0 sh gr /Times-Roman ff 190.50 scf sf 7920 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 190.50 scf sf 2745 2385 m gs 1 -1 sc (is_allowed) col0 sh gr /Times-Roman ff 190.50 scf sf 1845 855 m gs 1 -1 sc (Device_5Impl) col0 sh gr /Times-Roman ff 222.25 scf sf 810 1035 m gs 1 -1 sc (read_pipe) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 900 m gs 1 -1 sc (DynDataPipe class) col0 sh gr /Times-Roman ff 222.25 scf sf 5940 2385 m gs 1 -1 sc (is_DynData_allowed) col0 sh gr /Times-Roman ff 222.25 scf sf 5985 3555 m gs 1 -1 sc (read_DynData) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/ds_writing/startup.fig0000644023471100065110000001206613034745264015641 00000000000000#FIG 3.2 Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 1530 2880 1530 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 2610 2880 2610 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 3330 2880 3330 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 3150 1080 3150 1530 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 4950 1080 4950 1530 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 6300 1080 6300 1710 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 7380 1080 7380 1890 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 8550 1080 8550 2070 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 3420 1530 4680 1530 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 5220 1710 6030 1710 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 3 0 0 1.00 60.00 120.00 6570 1890 7020 1890 7200 1890 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7650 2070 8370 2070 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 5220 1890 6030 1890 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 5220 2070 6030 2070 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 6570 2070 7110 2070 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 7650 2790 8280 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 6570 2790 7110 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 5220 2790 6030 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 3420 2790 4680 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 6570 3510 7110 3510 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 5220 3510 6120 3510 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 3420 3510 4680 3510 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 2970 1530 3330 1530 3330 5580 2970 5580 2970 1530 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 4770 1530 5130 1530 5130 5580 4770 5580 4770 1530 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 6120 1710 6480 1710 6480 5580 6120 5580 6120 1710 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 7200 1890 7560 1890 7560 5580 7200 5580 7200 1890 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 8370 2070 8730 2070 8730 5580 8370 5580 8370 2070 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 9450 2790 9810 2790 9810 5580 9450 5580 9450 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 9630 1080 9630 2790 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 7605 3510 8325 3510 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 13050 1080 13050 3510 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 0 0 2 14490 1080 14490 3510 2 1 1 1 0 0 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 13320 3510 14220 3510 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 12870 3510 13230 3510 13230 5580 12870 5580 12870 3510 2 2 0 1 0 0 100 0 -1 0.000 0 0 -1 0 0 5 14310 3510 14670 3510 14670 5580 14310 5580 14310 3510 2 2 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 15660 3780 16020 3780 16020 5580 15660 5580 15660 3780 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 15840 1080 15840 3780 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 14760 3780 15570 3780 2 2 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 11520 3150 11880 3150 11880 5580 11520 5580 11520 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 11700 1260 11700 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 9900 3150 11430 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 8820 3150 9360 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 7650 3150 8280 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 6570 3150 7110 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 5220 3150 6030 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 3420 3150 4680 3150 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 990 2970 2880 2970 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 8820 3510 9360 3510 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 0 0 2 9900 3510 11430 3510 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 11970 3510 12780 3510 2 1 1 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8820 2790 9360 2790 2 2 0 1 0 7 100 0 -1 4.000 0 0 -1 0 0 5 720 720 16560 720 16560 5760 720 5760 720 720 4 0 0 100 0 12 12 0.0000 4 135 420 1080 1440 init\001 4 0 0 100 0 12 12 0.0000 4 180 1575 990 2520 command_factory\001 4 0 0 100 0 12 12 0.0000 4 180 1470 990 3240 device_factory\001 4 0 0 100 0 12 12 0.0000 4 180 1785 2340 990 StepperMotorClass\001 4 0 0 100 0 12 12 0.0000 4 135 1155 4410 990 DeviceClass\001 4 0 0 100 0 12 12 0.0000 4 90 315 5310 1620 new\001 4 0 0 100 0 12 12 0.0000 4 90 315 6660 1800 new\001 4 0 0 100 0 12 12 0.0000 4 90 315 7830 1980 new\001 4 0 0 100 0 12 12 0.0000 4 135 1575 9270 990 DevReadPosition\001 4 0 0 100 0 0 14 0.0000 4 195 1020 15390 990 Attribute(s)\001 4 0 0 100 0 12 12 0.0000 4 165 1260 12510 990 StepperMotor\001 4 0 0 100 0 12 12 0.0000 4 180 1050 14040 990 DeviceImpl\001 4 0 0 100 0 12 12 0.0000 4 90 315 9000 2700 new\001 4 0 0 100 0 12 12 0.0000 4 90 315 10890 3060 new\001 4 0 0 100 0 0 14 0.0000 4 105 375 12240 3420 new\001 4 0 0 100 0 0 14 0.0000 4 105 375 15030 3690 new\001 4 0 0 100 0 0 14 0.0000 4 210 1440 990 2880 attribute_factory\001 4 0 0 100 0 0 14 0.0000 4 150 1065 10980 990 Attribute list\001 4 0 0 100 0 0 16 0.0000 4 165 630 5985 990 Status\001 4 0 0 100 0 0 16 0.0000 4 165 525 7110 990 State\001 4 0 0 100 0 0 16 0.0000 4 165 330 8370 990 Init\001 tango-9.2.5a/doc/src/ds_writing/r_attribute.eps0000644023471100065110000001660513034745265016511 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: r_attribute.eps %%Creator: fig2dev Version 3.2 Patchlevel 3d %%CreationDate: Wed Sep 29 13:58:10 2004 %%For: taurel@wow (E.Taurel,,,) %%BoundingBox: 0 0 586 297 %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 297 moveto 0 0 lineto 586 0 lineto 586 297 lineto closepath clip newpath -33.3 318.2 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0.06299 0.06299 sc % % Fig objects follow % % Polyline 7.500 slw n 2340 990 m 2340 1170 l gs col0 s gr % Polyline gs clippath 2085 1200 m 2085 1140 l 1933 1140 l 2053 1170 l 1933 1200 l cp eoclip n 990 1170 m 2070 1170 l gs col0 s gr gr % arrowhead n 1933 1200 m 2053 1170 l 1933 1140 l col0 s % Polyline n 2160 1170 m 2520 1170 l 2520 4590 l 2160 4590 l cp gs col0 s gr % Polyline n 2340 4590 m 2340 4770 l gs col0 s gr % Polyline n 8640 1350 m 9000 1350 l 9000 1930 l 8640 1930 l cp gs col0 s gr % Polyline n 8640 2160 m 9000 2160 l 9000 2740 l 8640 2740 l cp gs col0 s gr % Polyline n 8640 2970 m 9000 2970 l 9000 3550 l 8640 3550 l cp gs col0 s gr % Polyline n 8640 3780 m 9000 3780 l 9000 4360 l 8640 4360 l cp gs col0 s gr % Polyline n 5400 2880 m 5760 2880 l 5760 3590 l 5400 3590 l cp gs col0 s gr % Polyline n 5400 3690 m 5760 3690 l 5760 4400 l 5400 4400 l cp gs col0 s gr /Times-Roman ff 180.00 scf sf 1710 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr /Times-Roman ff 180.00 scf sf 900 1080 m gs 1 -1 sc (read_attribute) col0 sh gr /Times-Roman ff 180.00 scf sf 4860 810 m gs 1 -1 sc (PositionAttr class) col0 sh gr /Times-Roman ff 180.00 scf sf 2700 1260 m gs 1 -1 sc (always_executed_hook) col0 sh gr % Polyline n 8820 1080 m 8820 1350 l gs col0 s gr % Polyline n 8820 1980 m 8820 2160 l gs col0 s gr % Polyline n 8820 2790 m 8820 2970 l gs col0 s gr % Polyline n 8820 3600 m 8820 3780 l gs col0 s gr % Polyline n 8820 4410 m 8820 4680 l gs col0 s gr % Polyline gs clippath 8565 1380 m 8565 1320 l 8413 1320 l 8533 1350 l 8413 1380 l cp eoclip n 2610 1350 m 8550 1350 l gs col0 s gr gr % arrowhead n 8413 1380 m 8533 1350 l 8413 1320 l col0 s % Polyline gs clippath 2595 1860 m 2595 1920 l 2747 1920 l 2627 1890 l 2747 1860 l cp eoclip n 8550 1890 m 2610 1890 l gs col0 s gr gr % arrowhead n 2747 1860 m 2627 1890 l 2747 1920 l col0 s % Polyline gs clippath 8565 2190 m 8565 2130 l 8413 2130 l 8533 2160 l 8413 2190 l cp eoclip n 2610 2160 m 8550 2160 l gs col0 s gr gr % arrowhead n 8413 2190 m 8533 2160 l 8413 2130 l col0 s % Polyline gs clippath 2595 2670 m 2595 2730 l 2747 2730 l 2627 2700 l 2747 2670 l cp eoclip n 8550 2700 m 2610 2700 l gs col0 s gr gr % arrowhead n 2747 2670 m 2627 2700 l 2747 2730 l col0 s % Polyline gs clippath 8565 3000 m 8565 2940 l 8413 2940 l 8533 2970 l 8413 3000 l cp eoclip n 5850 2970 m 8550 2970 l gs col0 s gr gr % arrowhead n 8413 3000 m 8533 2970 l 8413 2940 l col0 s % Polyline gs clippath 5835 3480 m 5835 3540 l 5987 3540 l 5867 3510 l 5987 3480 l cp eoclip n 8550 3510 m 5850 3510 l gs col0 s gr gr % arrowhead n 5987 3480 m 5867 3510 l 5987 3540 l col0 s % Polyline gs clippath 8565 3810 m 8565 3750 l 8413 3750 l 8533 3780 l 8413 3810 l cp eoclip n 5850 3780 m 8550 3780 l gs col0 s gr gr % arrowhead n 8413 3810 m 8533 3780 l 8413 3750 l col0 s % Polyline gs clippath 5835 4290 m 5835 4350 l 5987 4350 l 5867 4320 l 5987 4290 l cp eoclip n 8550 4320 m 5850 4320 l gs col0 s gr gr % arrowhead n 5987 4290 m 5867 4320 l 5987 4350 l col0 s % Polyline n 5580 2790 m 5580 2880 l gs col0 s gr % Polyline n 5580 3600 m 5580 3690 l gs col0 s gr % Polyline n 5580 4410 m 5580 4590 l gs col0 s gr % Polyline n 5580 2250 m 5580 2610 l gs col0 s gr % Polyline n 5580 1440 m 5580 1530 l 5580 1620 l 5580 1710 l 5580 1800 l gs col0 s gr % Polyline n 5580 1080 m 5580 1260 l gs col0 s gr % Polyline n 5580 1980 m 5580 2070 l gs col0 s gr % Polyline gs clippath 5325 2910 m 5325 2850 l 5173 2850 l 5293 2880 l 5173 2910 l cp eoclip n 2700 2880 m 5310 2880 l gs col0 s gr gr % arrowhead n 5173 2910 m 5293 2880 l 5173 2850 l col0 s % Polyline gs clippath 2595 3570 m 2595 3630 l 2747 3630 l 2627 3600 l 2747 3570 l cp eoclip n 5310 3600 m 2610 3600 l gs col0 s gr gr % arrowhead n 2747 3570 m 2627 3600 l 2747 3630 l col0 s % Polyline gs clippath 5325 3720 m 5325 3660 l 5173 3660 l 5293 3690 l 5173 3720 l cp eoclip n 2610 3690 m 5310 3690 l gs col0 s gr gr % arrowhead n 5173 3720 m 5293 3690 l 5173 3660 l col0 s % Polyline gs clippath 2595 4380 m 2595 4440 l 2747 4440 l 2627 4410 l 2747 4380 l cp eoclip n 5310 4410 m 2610 4410 l gs col0 s gr gr % arrowhead n 2747 4380 m 2627 4410 l 2747 4440 l col0 s % Polyline n 540 360 m 9810 360 l 9810 5040 l 540 5040 l cp gs col0 s gr /Times-Roman ff 180.00 scf sf 2700 2070 m gs 1 -1 sc (read_attr_hardware) col0 sh gr /Times-Roman ff 180.00 scf sf 2700 3060 m gs 1 -1 sc (is_allowed) col0 sh gr /Times-Roman ff 180.00 scf sf 5940 2880 m gs 1 -1 sc (is_Position_allowed) col0 sh gr /Times-Roman ff 180.00 scf sf 2700 3870 m gs 1 -1 sc (read) col0 sh gr /Times-Roman ff 180.00 scf sf 5940 3690 m gs 1 -1 sc (read_Position) col0 sh gr /Times-Roman ff 180.00 scf sf 7920 810 m gs 1 -1 sc (StepperMotor object) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/ds_model/0000755023471100065110000000000013034745265013141 500000000000000tango-9.2.5a/doc/src/ds_model/Makefile.am0000644023471100065110000000031213034745263015107 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ event_schematic_zmq img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/ds_model/Makefile.in0000644023471100065110000003276113034745263015135 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/ds_model DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ event_schematic_zmq all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/ds_model/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/ds_model/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/ds_model/event_schematic_zmq.fig0000644023471100065110000000322213034745263017575 00000000000000#FIG 3.2 Produced by xfig version 3.2.5b Landscape Center Metric A4 100.00 Single -2 1200 2 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 8505 2970 738 738 8505 2970 9090 3420 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 8490 5227 738 738 8490 5227 9075 5677 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 3555 2655 3555 1575 1845 1575 1845 2655 3555 2655 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 3555 2655 3555 1575 1845 1575 1845 2655 3555 2655 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 3555 4590 3555 3510 1845 3510 1845 4590 3555 4590 2 4 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5 3555 6525 3555 5445 1845 5445 1845 6525 3555 6525 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7785 2925 3555 2025 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7785 2925 3555 4050 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7740 5220 3555 4095 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 7740 5220 3555 5985 4 0 0 50 -1 0 14 0.0000 4 165 690 8190 5130 Device\001 4 0 0 50 -1 0 14 0.0000 4 165 900 8100 5400 server #2\001 4 0 0 50 -1 0 14 0.0000 4 165 900 8145 3150 server #1\001 4 0 0 50 -1 0 14 0.0000 4 165 690 8235 2880 Device\001 4 0 0 50 -1 0 14 0.0000 4 165 915 2295 2160 Client #1\001 4 0 0 50 -1 0 14 0.0000 4 165 915 2250 4050 Client #2\001 4 0 0 50 -1 0 14 0.0000 4 165 915 2250 6030 Client #3\001 4 0 0 50 -1 0 14 0.0000 4 210 810 5040 2160 Event(s)\001 4 0 0 50 -1 0 14 0.0000 4 210 810 4995 3330 Event(s)\001 4 0 0 50 -1 0 14 0.0000 4 210 810 5130 4455 Event(s)\001 4 0 0 50 -1 0 14 0.0000 4 210 810 5130 5985 Event(s)\001 4 0 0 50 -1 0 18 0.0000 4 255 6765 1935 990 Schematic of event system for TANGO release 8 and more\001 tango-9.2.5a/doc/src/ds_model/ds_model.lyx0000644023471100065110000012312713034745263015411 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter The TANGO device server model \end_layout \begin_layout Standard This chapter will present the TANGO device server object model hereafter referred as TDSOM \begin_inset Index idx status collapsed \begin_layout Plain Layout TDSOM \end_layout \end_inset . First, it will introduce CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset . Then, it will describe each of the basic features of the TDSOM and their function. The TDSOM can be divided into the following basic elements - the \emph on device \emph default , the \emph on server \emph default , the \emph on database \emph default and the \emph on application programmers interface \emph default . This chapter will treat each of the above elements separately. \end_layout \begin_layout Section Introduction to CORBA \begin_inset CommandInset label LatexCommand label name "sec:corba" \end_inset \end_layout \begin_layout Standard CORBA is a definition of how to write object request brokers (ORB \begin_inset Index idx status collapsed \begin_layout Plain Layout ORB \end_layout \end_inset ). The definition is managed by the Object Management Group (OMG \begin_inset Index idx status collapsed \begin_layout Plain Layout OMG \end_layout \end_inset \begin_inset CommandInset citation LatexCommand cite key "OMG-page" \end_inset ). Various commercial and non-commercial implementations exist for CORBA for all the mainstream operating systems. CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset uses a programming language independent definition language (called IDL) to defined network object interfaces. Language mappings are defined from IDL \begin_inset Index idx status collapsed \begin_layout Plain Layout IDL \end_layout \end_inset to the main programming languages e.g. C++, Java, C, COBOL, Smalltalk and ADA. Within an interface, CORBA defines two kinds of actions available to the outside world. These actions are called \series bold attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \series default and \series bold operations \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout operation \end_layout \end_inset . \end_layout \begin_layout Standard Operations are all the actions offered by an interface. For instance, within an interface for a Thermostat class, operations could be the action to read the temperature or to set the nominal temperature. An attribute defines a pair of operations a client can call to send or receive a value. For instance, the position of a motor can be defined as an attribute because it is a data that you only set or get. A read only attribute defines a single operation the client can call to receives a value. In case of error, an operation is able to throw an exception to the client, attributes cannot raises exception except system exception (du to network fault for instance). \end_layout \begin_layout Standard Intuitively, IDL interface correspond to C++ classes and IDL operations correspond to C++ member functions and attributes as a way to read/write public member variable. Nevertheless, IDL defines only the interface to an object and say nothing about the object implementation. IDL is only a descriptive language. Once the interface is fully described in the IDL language, a compiler (from IDL to C++, from IDL to Java...) generates code to implement this interface. Obviously, you still have to write how operations are implemented. \end_layout \begin_layout Standard The act of invoking an operation on an interface causes the ORB to send a message to the corresponding object implementation. If the target object is in another address space, the ORB run time sends a remote procedure call to the implementation. If the target object is in the same address space as the caller, the invocation is accomplished as an ordinary function call to avoid the overhead of using a networking protocol. \end_layout \begin_layout Standard For an excellent reference on CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset with C++ refer to \begin_inset CommandInset citation LatexCommand cite key "Henning" \end_inset . The complete TANGO IDL \begin_inset Index idx status collapsed \begin_layout Plain Layout IDL \end_layout \end_inset file can be found in the TANGO web page \begin_inset CommandInset citation LatexCommand cite key "Tango web" \end_inset or at the end of this document in the appendix 2 chapter. \end_layout \begin_layout Section The model \end_layout \begin_layout Standard The basic idea of the TDSOM \begin_inset Index idx status collapsed \begin_layout Plain Layout TDSOM \end_layout \end_inset is to treat each device as an \series bold object \series default . Each device is a separate entity which has its own data and behavior. Each device has a unique name which identifies it in network name space. Devices are organized according to \series bold classes \series default , each device belonging to a class. All classes are derived from one root class thus allowing some common behavior for all devices. Four kind of requests can be sent to a device (locally i.e. in the same process, or remotely i.e. across the network) : \end_layout \begin_layout Itemize Execute actions via \series bold commands \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset \end_layout \begin_layout Itemize Read/Set data specific to each device belonging to a class via TANGO \series bold attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \end_layout \begin_layout Itemize Read/Set data specific to each device belonging to a class via TANGO \series bold pipes \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout pipe \end_layout \end_inset \end_layout \begin_layout Itemize Read some basic device data available for all devices via CORBA attributes. \end_layout \begin_layout Itemize Execute a predefined set of actions available for every devices via CORBA operations \begin_inset Index idx status collapsed \begin_layout Plain Layout operation \end_layout \end_inset \end_layout \begin_layout Standard Each device is stored in a process called a \series bold device server \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout server \end_layout \end_inset . Devices are configured at runtime via \series bold properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset \series default which are stored in a \series bold database \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout database \end_layout \end_inset . \end_layout \begin_layout Section The device \begin_inset CommandInset label LatexCommand label name "sec:dev" \end_inset \end_layout \begin_layout Standard The device is the heart of the TDSOM. A device is an abstract concept defined by the TDSOM. In reality, it can be a piece of hardware (an interlock bit) a collection of hardware (a screen attached to a stepper motor) a logical device (a taper) or a combination of all these (an accelerator). Each device has a unique name in the control system and eventually one alias \begin_inset Index idx status collapsed \begin_layout Plain Layout alias \end_layout \end_inset . Within Tango, a four field name \begin_inset Index idx status collapsed \begin_layout Plain Layout name \end_layout \end_inset space has been adopted consisting of \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset [//FACILITY/]DOMAIN/CLASS/MEMBER \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset Facility refers to the control system instance, domain refers to the sub-system , class the class and member the instance of the device. Device name alias(es) must also be unique within a control system. There is no predefined syntax for device name alias. \end_layout \begin_layout Standard Each device belongs to a class. The device class contains a complete description and implementation of the behavior of all members of that class. New device classes can be constructed out of existing device classes. This way a new hierarchy of classes can be built up in a short time. Device classes can use existing devices as sub-classes or as sub-objects. The practice of reusing existing classes is classical for Object Oriented Programming and is one of its main advantages. \end_layout \begin_layout Standard All device classes are derived from the same class (the device root class) and implement \series bold the same CORBA interface \series default . All devices implementing the same CORBA interface ensures all control object support the same set of CORBA operations and attributes. The device root class contains part of the common device code. By inheriting from this class, all devices shared a common behavior. This also makes maintenance and improvements to the TDSOM easy to carry out. \end_layout \begin_layout Standard All devices also support a \series bold black box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset \series default where client requests for attributes or operations are recorded. This feature allows easier debugging session for device already installed in a running control system. \end_layout \begin_layout Subsection The commands \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset \end_layout \begin_layout Standard Each device class implements a list of commands. Commands are very important because they are the client's major dials and knobs for controlling a device. Commands have a fixed calling syntax - consisting of one input argument and one output argument. Arguments type must be chosen in a fixed set of data types: All simple types (boolean, short, long (32 bits), long (64 bits), float, double, unsigned short, unsigned long (32 bits), unsigned long (64 bits) and string) and arrays of simple types plus array of strings and longs and array of strings and doubles). Commands can execute any sequence of actions. Commands can be executed synchronously (the requester is blocked until the command ended) or asynchronously (the requester send the request and is called back when the command ended). \end_layout \begin_layout Standard Commands are executed using two CORBA operations named \series bold command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset \series default for synchronous commands and \series bold command_inout_async \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-async \end_layout \end_inset \series default for asynchronous commands. These two operations called a special method implemented in the device root class - the \emph on command_handler \begin_inset Index idx status collapsed \begin_layout Plain Layout command-handler \end_layout \end_inset \emph default method. The \emph on command_handler \emph default calls an \emph on is_allowed \begin_inset Index idx status collapsed \begin_layout Plain Layout is-allowed \end_layout \end_inset \emph default method implemented in the device class before calling the command itself. The \emph on is_allowed \emph default method is specific to each command \begin_inset Foot status open \begin_layout Plain Layout In contrary to the state_handler method of the TACO device server model which is not specific to each command. \end_layout \end_inset . It checks to see whether the command to be executed is compatible with the present device state. The command function is executed only if the \emph on is_allowed \emph default method allows it. Otherwise, an exception is sent to the client. \end_layout \begin_layout Subsection The TANGO attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \end_layout \begin_layout Standard In addition to commands, TANGO devices also support normalized data types called attributes \begin_inset Foot status open \begin_layout Plain Layout TANGO attributes were known as signals in the TACO device server model \end_layout \end_inset . Commands are device specific and the data they transport are not normalized i.e. they can be any one of the TANGO data types with no restriction on what each byte means. This means that it is difficult to interpret the output of a command \begin_inset Index idx status collapsed \begin_layout Plain Layout command \end_layout \end_inset in terms of what kind of value(s) it represents. Generic display programs need to know what the data returned represents, in what units it is, plus additional information like minimum, maximum, quality etc. Tango attributes solve this problem. \end_layout \begin_layout Standard TANGO attributes are zero, one or two dimensional data which have a fix set of properties e.g. quality, minimum and maximum, alarm low and high. They are transferred in a specialized TANGO type and can be read, write or read-write. A device can support a list of attributes. Clients can read one or more attributes from one or more devices. To read TANGO attributes, the client uses the \series bold read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset \series default operation. To write TANGO attributes, a client uses the \series bold write_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset \series default operation. To write then read TANGO attributes within the same network request, the client uses the \series bold write_read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout write-read-attribute \end_layout \end_inset \series default operation. To query a device for all the attributes it supports, a client uses the \series bold get_attribute_config \begin_inset Index idx status collapsed \begin_layout Plain Layout get-attribute-config \end_layout \end_inset \series default operation. A client is also able to modify some of parameters defining an attribute with the \series bold set_attribute_config \begin_inset Index idx status collapsed \begin_layout Plain Layout set-attribute-config \end_layout \end_inset \series default operation. These five operations are defined in the device CORBA interface. \end_layout \begin_layout Standard TANGO support thirteen data types for attributes (and arrays of for one or two dimensional data) which are: boolean, short, long (32 bits), long (64 bits), float, double, unsigned char, unsigned short, unsigned long (32 bits), unsigned long (64 bits), string, a specific data type for Tango device state and finally another specific data type to transfer data as an array of unsigned char with a string describing the coding of these data. \end_layout \begin_layout Subsection The TANGO pipes \begin_inset Index idx status open \begin_layout Plain Layout pipe \end_layout \end_inset \end_layout \begin_layout Standard Since release 9, in addition to commands and attributes, TANGO devices also support pipes. \end_layout \begin_layout Standard In some cases, it is required to exchange data between client and device of varrying data type. This is for instance the case of data gathered during a scan on one experiment. Because the number of actuators and sensors involved in the scan may change from one scan to another, it is not possible to use a well defined data type. TANGO pipes have been designed for such cases. A TANGO pipe is basically a pipe dedicated to transfer data between client and device. A pipe has a set of two properties which are the pipe label and its description. A pipe can be read or read-write. A device can support a list of pipes. Clients can read one or more pipes from one or more devices. To read a TANGO pipe, the client uses the \series bold read_pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout read-pipe \end_layout \end_inset \series default operation. To write a TANGO pipe, a client uses the \series bold write_pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout write-pipe \end_layout \end_inset \series default operation. To write then read a TANGO pipe within the same network request, the client uses the \series bold write_read_pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout write-read-pipe \end_layout \end_inset \series default operation. To query a device for all the pipes it supports, a client uses the \series bold get_pipe_config \begin_inset Index idx status collapsed \begin_layout Plain Layout get-pipe-config \end_layout \end_inset \series default operation. A client is also able to modify some of parameters defining a pipe with the \series bold set_pipe_config \begin_inset Index idx status collapsed \begin_layout Plain Layout set-pipe-config \end_layout \end_inset \series default operation. These five operations are defined in the device CORBA interface. \end_layout \begin_layout Standard In contrary of commands or attributes, a TANGO pipe does not have a pre-defined data type. Data transferred through pipes may be of any basic Tango data type (or array of) and this may change every time a pipe is read or written. \end_layout \begin_layout Subsection Command, attributes or pipes ? \end_layout \begin_layout Standard There are no strict rules concerning what should be returned as command result and what should be implemented as an attribute or as a pipe. Nevertheless, attributes are more adapted to return physical value which have a kind of time consistency. Attribute also have more properties which help the client to precisely know what it represents. For instance, the state and the status of a power supply are not physical values and are returned as command result. The current generated by the power supply is a physical value and is implemente d as an attribute. The attribute properties allow a client to know its unit, its label and some other informations which are related to a physical value. Command are well adapted to send order to a device like switching from one mode of operation to another mode of operation. For a power supply, the switch from a STANDBY mode to a ON mode is typically done via a command. Finally pipe is well adapted when the kind and number of data exchanged between the client and the device change with time. \end_layout \begin_layout Subsection The CORBA attributes \end_layout \begin_layout Standard Some key data implemented for each device can be read without the need to call a command or read an attribute. These data are : \end_layout \begin_layout Itemize The device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset \end_layout \begin_layout Itemize The device status \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset \end_layout \begin_layout Itemize The device name \begin_inset Index idx status collapsed \begin_layout Plain Layout name \end_layout \end_inset \end_layout \begin_layout Itemize The administration device name called adm_name \begin_inset Index idx status collapsed \begin_layout Plain Layout administration \end_layout \end_inset \end_layout \begin_layout Itemize The device description \begin_inset Index idx status collapsed \begin_layout Plain Layout description \end_layout \end_inset \end_layout \begin_layout Standard The device state is a number representing its state. A set of predefined states are defined in the TDSOM. The device status is a string describing in plain text the device state and any additional useful information of the device as a formatted ascii string. The device name is its name as defined in \begin_inset CommandInset ref LatexCommand ref reference "sec:dev" \end_inset . For each set of devices grouped within the same server, an administration device is automatically added. This adm_name is the name of the administration device. The device description is also an ascii string describing the device rule. \end_layout \begin_layout Standard These five CORBA attributes are implemented in the device root class and therefore do not need any coding from the device class programmer. As explained in \begin_inset CommandInset ref LatexCommand ref reference "sec:corba" \end_inset , the CORBA attributes are not allowed to raise exceptions whereas command (which are implemented using CORBA operations) can. \end_layout \begin_layout Subsection The remaining CORBA operations \end_layout \begin_layout Standard The TDSOM also supports a list of actions defined as CORBA operations in the device interface and implemented in the device root class. Therefore, these actions are implemented automatically for every TANGO device. These operations are : \end_layout \begin_layout Labeling \labelwidthstring MMMMMMMMMMM ping \begin_inset Index idx status collapsed \begin_layout Plain Layout ping \end_layout \end_inset to ping a device to check if the device is alive. Obviously, it checks only the connection from a client to the device and not all the device functionalities \end_layout \begin_layout Labeling \labelwidthstring MMMMMMMMMMM command_list_query \begin_inset Index idx status collapsed \begin_layout Plain Layout command-list-query \end_layout \end_inset request a list of all the commands supported by a device with their input and output types and description \end_layout \begin_layout Labeling \labelwidthstring MMMMMMMMMMM command_query \begin_inset Index idx status collapsed \begin_layout Plain Layout command-query \end_layout \end_inset request information about a specific command which are its input and output type and description \end_layout \begin_layout Labeling \labelwidthstring MMMMMMMMMMM info \begin_inset Index idx status collapsed \begin_layout Plain Layout info \end_layout \end_inset request general information on the device like its name, the host where the device server hosting the device is running... \end_layout \begin_layout Labeling \labelwidthstring MMMMMMMMMMM black_box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset read the device black-box as an array of strings \end_layout \begin_layout Subsection The special case of the device state and status \end_layout \begin_layout Standard Device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset and status \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset are the most important key device informations. Nearly all client software dealing with Tango device needs device(s) state and/or status. In order to simplify client software developper work, it is possible to get these two piece of information in three different manners : \end_layout \begin_layout Enumerate Using the appropriate CORBA attribute (state or status) \end_layout \begin_layout Enumerate Using command on the device. The command are called State or Status \end_layout \begin_layout Enumerate Using attribute. Even if the state and status are not real attribute, it is possible to get their value using the read_attributes operation. Nevertheless, it is not possible to set the attribute configuration for state and status. An error is reported by the server if a client try to do so. \end_layout \begin_layout Subsection The device polling \begin_inset Index idx status collapsed \begin_layout Plain Layout polling \end_layout \end_inset \end_layout \begin_layout Standard Within the Tango framework, it is also possible to force executing command(s) or reading attribute(s) at a fixed frequency. It is called \emph on device polling \emph default . This is automatically handled by Tango core software with a polling threads pool. The command result or attribute value are stored in circular buffers. When a client want to read attribute value (or command result) for a polled attribute (or a polled command), he has the choice to get the attribute value (or command result) with a real access to the device of from the last value stored in the device ring buffer. This is a great advantage for \begin_inset Quotes eld \end_inset slow \begin_inset Quotes erd \end_inset devices. Getting data from the buffer is much faster than accessing the device itself. The technical disadvantage is the time shift between the data returned from the polling buffer and the time of the request. Polling a command is only possible for command without input arguments. It is not possible to poll a device pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout pipe \end_layout \end_inset . \end_layout \begin_layout Standard Two other CORBA operations called \emph on command_inout_history_X \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-history-X \end_layout \end_inset \emph default and \emph on read_attribute _history_X \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-X \end_layout \end_inset \emph default allow a client to retrieve the history of polled command or attribute stored in the polling buffers. Obviously, this history is limited to the depth of the polling buffer. \end_layout \begin_layout Standard The whole polling system is available only since Tango release 2.x and above in CPP and since TangORB release 3.7.x and above in Java. \end_layout \begin_layout Section The server \end_layout \begin_layout Standard Another integral part of the TDSOM is the server concept. The server (also referred as device server \begin_inset Index idx status collapsed \begin_layout Plain Layout server \end_layout \end_inset ) is a process whose main task is to offer one or more services to one or more clients. To do this, the server has to spend most of its time in a wait loop waiting for clients to connect to it. The devices are hosted in the server process. A server is able to host several classes of devices. In the TDSOM, a device of the \series bold DServer \series default class is automatically hosted by each device server. This class of device supports commands which enable remote device server process administration. \end_layout \begin_layout Standard TANGO supports device server process on two families of operating system : Linux and Windows. \end_layout \begin_layout Section The Tango Logging \begin_inset Index idx status collapsed \begin_layout Plain Layout logging \end_layout \end_inset Service \begin_inset CommandInset label LatexCommand label name "sec:The-Tango-Logging" \end_inset \end_layout \begin_layout Standard During software life, it is always convenient to print miscellaneous information s which help to: \end_layout \begin_layout Itemize Debug the software \end_layout \begin_layout Itemize Report on error \end_layout \begin_layout Itemize Give regular information to user \end_layout \begin_layout Standard This is classically done using cout (or C printf) in C++ or println method in Java language. In a highly distributed control system, it is difficult to get all these informations coming from a high number of different processes running on a large number of computers. Since its release 3, Tango has incorporated a Logging Service called the Tango Logging Service (TLS) which allows print messages to be: \end_layout \begin_layout Itemize Displayed on a console (the classical way) \end_layout \begin_layout Itemize Sent to a file \end_layout \begin_layout Itemize Sent to specific Tango device called log consumer \begin_inset Index idx status collapsed \begin_layout Plain Layout consumer \end_layout \end_inset . Tango package has an implementation of log consumer where every consumer device is associated to a graphical interface. This graphical interface display messages but could also be used to sort messages, to filter messages... Using this feature, it is possible to centralise display of these messages coming from different devices embedded within different processes. These log consumers can be: \end_layout \begin_deeper \begin_layout Itemize Statically configured meaning that it memorizes the list of Tango devices for which it will get and display messages. \end_layout \begin_layout Itemize Dynamically configured. The user, with the help of the graphical interface, chooses devices from which he want to see messages. \end_layout \end_deeper \begin_layout Section The database \begin_inset Index idx status collapsed \begin_layout Plain Layout database \end_layout \end_inset \end_layout \begin_layout Standard To achieve complete device independence, it is necessary however to supplement device classes with a possibility for configuring device dependencies at runtime. The utility which does this in the TDSOM is the \series bold property database \series default . Properties \begin_inset Foot status open \begin_layout Plain Layout Properties were known as resources in the TACO device server model \end_layout \end_inset are identified by an ascii string and the device name. TANGO attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset are also configured using properties \begin_inset Index idx status collapsed \begin_layout Plain Layout properties \end_layout \end_inset . This database is also used to store device network addresses (CORBA IOR \begin_inset Index idx status collapsed \begin_layout Plain Layout IOR \end_layout \end_inset 's), list of classes hosted by a device server process and list of devices for each class in a device server process. The database ensure the uniqueness of device name and of alias. It also links device name and it list of aliases. \end_layout \begin_layout Standard TANGO uses MySQL \begin_inset Index idx status collapsed \begin_layout Plain Layout MySQL \end_layout \end_inset \begin_inset CommandInset citation LatexCommand cite key "mysql" \end_inset as its database. MySQL is a relational database which implements the SQL language. However, this is largely enough to implement all the functionalities needed by the TDSOM. The database is accessed via a classical TANGO device hosted in a device server. Therefore, client access the database via TANGO commands requested on the database device. For a good reference on MySQL refer to \begin_inset CommandInset citation LatexCommand cite key "MySQL book" \end_inset \end_layout \begin_layout Section The controlled access \end_layout \begin_layout Standard Tango also provides a controlled access \begin_inset Index idx status collapsed \begin_layout Plain Layout controlled-access \end_layout \end_inset system. It's a simple controlled access system. It does not provide encrypted communication or sophisticated authentification. It simply defines which user (based on computer loggin authentification) is allowed to do which command (or write attribute) on which device and from which host. The information used to configure this controlled access feature are stored in the Tango database and accessed by a specific Tango device server which is not the classsical Tango database device server described in the previous section. Two access levels are defined: \end_layout \begin_layout Itemize Everything is allowed for this user from this host \end_layout \begin_layout Itemize The write-like calls on the device are forbidden and according to configuration, a command subset is also forbidden for this user from this host \end_layout \begin_layout Standard This feature is precisely described in the chapter "Advanced features" \end_layout \begin_layout Section The Application Programmers Interfaces \end_layout \begin_layout Subsection Rules of the API \end_layout \begin_layout Standard While it is true TANGO clients can be programmed using only the CORBA API, CORBA knows nothing about TANGO. This means client have to know all the details of retrieving IORs from the TANGO database, additional information to send on the wire, TANGO version control etc. These details can and should be wrapped in TANGO Application Programmer Interface (API). The API is implemented as a library in C++ and as a package in Java. The API is what makes TANGO clients easy to write. The API's consists the following basic classes : \end_layout \begin_layout Itemize DeviceProxy which is a \emph on proxy \emph default to the real device \end_layout \begin_layout Itemize DeviceData to encapsulate data send/receive from/to device via commands \end_layout \begin_layout Itemize DeviceAttribute to encapsulate data send/receive from/to device via attributes \end_layout \begin_layout Itemize Group which is a \emph on proxy \emph default to a group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset of devices \end_layout \begin_layout Standard In addition to these main classes, many other classes allows a full interface to TANGO features. The following figure is a drawing of a typical client/server application using TANGO. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename archi.eps width 12cm height 7cm \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The database is used during server and client startup phase to establish connection between client and server. \end_layout \begin_layout Subsection Communication between client and server using the API \end_layout \begin_layout Standard With the API, it is possible to request command to be executed on a device or to read/write device attribute(s) using one of the two communication models implemented. These two models are: \end_layout \begin_layout Enumerate The synchronous model where client waits (and is blocked) for the server to send the answer or until the timeout is reached \end_layout \begin_layout Enumerate The asynchronous model. In this model, the clients send the request and immediately returns. It is not blocked. It is free to do whatever it has to do like updating a graphical user interface. The client has the choice to retrieve the server answer by checking if the reply is arrived by calling an API specific call or by requesting that a call-back method is executed when the client receives the server answer. \end_layout \begin_layout Standard The asynchronous model is available with Tango release 3 and above. \end_layout \begin_layout Subsection Tango events \end_layout \begin_layout Standard On top of the two communication model previously described, TANGO offers an "event system" \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset . The standard TANGO communication paradigm is a synchronou/asynchronous two-way call. In this paradigm the call is initiated by the client who contacts the server. The server handles the client's request and sends the answer to the client or throws an exception which the client catches. This paradigm involves two calls to receive a single answer and requires the client to be active in initiating the request. If the client has a permanent interest in a value he is obliged to poll the server for an update in a value every time. This is not efficient in terms of network bandwidth nor in terms of client programming. \end_layout \begin_layout Standard For clients who are permanently interested in values the event-driven communicat ion paradigm is a more efficient and natural way of programming. In this paradigm the client registers his interest once in an event (value). After that the server informs the client every time the event has occurred. This paradigm avoids the client polling, frees it for doing other things, is fast and makes efficient use of the network. \end_layout \begin_layout Standard Before TANGO release 8, TANGO used the CORBA OMG COS Notification Service \begin_inset Index idx status collapsed \begin_layout Plain Layout Notification Service \end_layout \end_inset to generates events. TANGO uses the omniNotify \begin_inset Index idx status collapsed \begin_layout Plain Layout omniNotify \end_layout \end_inset implementation of the Notification service. omniNotify was developed in conjunction with the omniORB CORBA implementation also used by TANGO. The heart of the Notification Service is the notification daemon. The omniNotify daemons are the processes which receive events from device servers and distribute them to all clients which are subscribed. In order to distribute the load of the events there is one notification daemon per host. Servers send their events to the daemon on the local host. Clients and servers get the IOR for the host from the TANGO database. \end_layout \begin_layout Standard The following figure is a schematic of the Tango event system for Tango releases before Tango 8. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename event_schematic.eps scale 80 BoundingBox 0bp 0bp 523bp 485bp clip \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Starting with Tango 8, a new design of the event system has been implemented. This new design is based on the ZMQ \begin_inset Index idx status open \begin_layout Plain Layout ZMQ \end_layout \end_inset library. ZMQ is a library allowing users to create communicating system. It implements several well known communication pattern including the Publish/Su bscribe \begin_inset Index idx status open \begin_layout Plain Layout Publish/Subscribe \end_layout \end_inset pattern which is the basic of the new Tango event system. Using this library, a separate notification service is not needed anymore and event communiction is available with only client and server processes which simplifies the overall design. Starting with Tango 8.1, the event propagation between devices and clients could be done using a multicasting \begin_inset Index idx status open \begin_layout Plain Layout multicasting \end_layout \end_inset protocol. The aim of this is to reduce both the network bandwidth use and the CPU consumption on the device server side. See chapter on Advanced Features to get all the details on this feature. \end_layout \begin_layout Standard The following figure is a schematic of the Tango event system for Tango releases starting with Tango release 8. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename event_schematic_zmq.eps scale 80 BoundingBox 0bp 0bp 523bp 485bp clip \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 5cm \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset label LatexCommand label name "OneRicardo" \end_inset \begin_inset Graphics filename ../dance/Eltaita-reduc.jpg lyxscale 80 scale 150 \end_inset \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/ds_model/line.tex0000644023471100065110000000174013034745263014532 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/ds_model/event_schematic.eps0000644023471100065110000001745113034745263016741 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: event_schematic.eps %%Creator: fig2dev Version 3.2 Patchlevel 3c %%CreationDate: Mon Mar 17 13:06:27 2003 %%For: goetz@splash (Andy Goetz) %%BoundingBox: 0 0 523 485 %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 485 moveto 0 0 lineto 523 0 lineto 523 485 lineto closepath clip newpath -126.0 500.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin %%Page: 1 1 10 setmiterlimit 0.06299 0.06299 sc % % Fig objects follow % % Arc 7.500 slw gs clippath 9537 1923 m 9568 1872 l 9439 1792 l 9526 1881 l 9407 1844 l cp eoclip n 6404.4 6896.1 5907.0 -128.8 -57.9 arc gs col0 s gr gr % arrowhead n 9407 1844 m 9526 1881 l 9439 1792 l col0 s % Arc gs clippath 6381 3407 m 6421 3362 l 6308 3261 l 6378 3364 l 6268 3306 l cp eoclip n 3462.7 6563.6 4328.5 -99.5 -47.4 arc gs col0 s gr gr % arrowhead n 6268 3306 m 6378 3364 l 6308 3261 l col0 s % Ellipse n 6345 3915 855 540 0 360 DrawEllipse gs col0 s gr % Ellipse n 9540 2610 704 704 0 360 DrawEllipse gs col0 s gr % Ellipse n 9585 4680 704 704 0 360 DrawEllipse gs col0 s gr % Ellipse n 6399 6595 704 704 0 360 DrawEllipse gs col0 s gr % Polyline n 2130 2340 m 2025 2340 2025 3045 105 arcto 4 {pop} repeat 2025 3150 3450 3150 105 arcto 4 {pop} repeat 3555 3150 3555 2445 105 arcto 4 {pop} repeat 3555 2340 2130 2340 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 2130 4770 m 2025 4770 2025 5475 105 arcto 4 {pop} repeat 2025 5580 3450 5580 105 arcto 4 {pop} repeat 3555 5580 3555 4875 105 arcto 4 {pop} repeat 3555 4770 2130 4770 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 2130 3555 m 2025 3555 2025 4260 105 arcto 4 {pop} repeat 2025 4365 3450 4365 105 arcto 4 {pop} repeat 3555 4365 3555 3660 105 arcto 4 {pop} repeat 3555 3555 2130 3555 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 7830 6390 m 9450 6390 l 9450 7920 l 7830 7920 l cp gs col0 s gr % Polyline 15.000 slw gs clippath 7125 3718 m 7158 3768 l 7285 3685 l 7169 3726 l 7252 3634 l cp eoclip n 8865 2610 m 7155 3735 l gs col7 1.00 shd ef gr gs col0 s gr gr % arrowhead 7.500 slw n 7252 3634 m 7169 3726 l 7285 3685 l col0 s % Polyline 15.000 slw gs clippath 7152 3971 m 7130 4027 l 7270 4082 l 7170 4011 l 7292 4027 l cp eoclip n 8865 4680 m 7155 4005 l gs col0 s gr gr % arrowhead 7.500 slw n 7292 4027 m 7170 4011 l 7270 4082 l col0 s % Polyline gs clippath 6315 5910 m 6375 5910 l 6375 5758 l 6345 5878 l 6315 5758 l cp eoclip n 6345 4455 m 6345 5895 l gs col0 s gr gr % arrowhead n 6315 5758 m 6345 5878 l 6375 5758 l col0 s % Polyline gs clippath 6359 5835 m 6396 5882 l 6515 5789 l 6403 5840 l 6478 5742 l cp eoclip n 9585 3330 m 6390 5850 l gs col0 s gr gr % arrowhead n 6478 5742 m 6403 5840 l 6515 5789 l col0 s % Polyline gs clippath 6460 5822 m 6469 5881 l 6619 5860 l 6496 5848 l 6610 5801 l cp eoclip n 9585 5400 m 6480 5850 l gs col0 s gr gr % arrowhead n 6610 5801 m 6496 5848 l 6619 5860 l col0 s % Polyline gs clippath 3557 2711 m 3526 2763 l 3657 2839 l 3569 2753 l 3687 2787 l cp eoclip n 5490 3870 m 3555 2745 l gs col0 s gr gr % arrowhead n 3687 2787 m 3569 2753 l 3657 2839 l col0 s % Polyline gs clippath 3540 3885 m 3540 3945 l 3692 3945 l 3572 3915 l 3692 3885 l cp eoclip n 5490 3915 m 3555 3915 l gs col0 s gr gr % arrowhead n 3692 3885 m 3572 3915 l 3692 3945 l col0 s % Polyline gs clippath 3526 5157 m 3557 5208 l 3687 5129 l 3569 5166 l 3656 5078 l cp eoclip n 5490 4005 m 3555 5175 l gs col0 s gr gr % arrowhead n 3656 5078 m 3569 5166 l 3687 5129 l col0 s % Polyline gs clippath 7845 6645 m 7845 6585 l 7693 6585 l 7813 6615 l 7693 6645 l cp eoclip n 7155 6615 m 7830 6615 l gs col0 s gr gr % arrowhead n 7693 6645 m 7813 6615 l 7693 6585 l col0 s /Times-Roman ff 180.00 scf sf 5895 3915 m gs 1 -1 sc (notify daemon) col0 sh gr /Times-Roman ff 180.00 scf sf 8910 4725 m gs 1 -1 sc (device server #2) col0 sh gr /Times-Roman ff 180.00 scf sf 2295 2790 m gs 1 -1 sc (client #1) col0 sh gr /Times-Roman ff 180.00 scf sf 2295 4050 m gs 1 -1 sc (client #2) col0 sh gr /Times-Roman ff 180.00 scf sf 2250 5265 m gs 1 -1 sc (client #3) col0 sh gr /Times-Roman ff 180.00 scf sf 5805 6660 m gs 1 -1 sc (database server) col0 sh gr /Times-Roman ff 180.00 scf sf 7920 6660 m gs 1 -1 sc (events table:) col0 sh gr /Times-Roman ff 180.00 scf sf 7920 7110 m gs 1 -1 sc (notifd/host: IOR) col0 sh gr /Times-Roman ff 180.00 scf sf 7920 7335 m gs 1 -1 sc (server/name: IOR) col0 sh gr /Times-Roman ff 180.00 scf sf 5805 945 m gs 1 -1 sc (event subscription ) col0 sh gr /Times-Roman ff 180.00 scf sf 4725 2385 m gs 1 -1 sc (event filter) col0 sh gr /Times-Roman ff 180.00 scf sf 4410 3240 m gs 1 -1 sc (event\(s\)) col0 sh gr /Times-Roman ff 180.00 scf sf 4185 3870 m gs 1 -1 sc (event\(s\)) col0 sh gr /Times-Roman ff 180.00 scf sf 4410 4770 m gs 1 -1 sc (event\(s\)) col0 sh gr /Times-Roman ff 180.00 scf sf 5985 5130 m gs 1 -1 sc (IOR) col0 sh gr /Times-Roman ff 180.00 scf sf 7290 4905 m gs 1 -1 sc (IOR) col0 sh gr /Times-Roman ff 180.00 scf sf 7875 5580 m gs 1 -1 sc (IOR) col0 sh gr /Times-Roman ff 180.00 scf sf 7560 4140 m gs 1 -1 sc (event channel) col0 sh gr /Times-Roman ff 180.00 scf sf 7560 3600 m gs 1 -1 sc (event channel) col0 sh gr /Times-Bold ff 270.00 scf sf 4365 450 m gs 1 -1 sc (Schematic of TANGO Events system) col0 sh gr /Times-Roman ff 180.00 scf sf 8910 2655 m gs 1 -1 sc (device server #1) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/ds_model/archi.eps0000644023471100065110000001431113034745263014656 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: archi.eps %%Creator: fig2dev Version 3.2 Patchlevel 1 %%CreationDate: Wed Jan 9 16:50:19 2002 %%For: taurel@spica1.esrf.fr (E.Taurel,,,) %%Orientation: Portrait %%BoundingBox: 0 0 780 456 %%Pages: 0 %%BeginSetup %%EndSetup %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save -21.0 506.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def %%EndProlog $F2psBegin 10 setmiterlimit n -1000 9022 m -1000 -1000 l 13702 -1000 l 13702 9022 l cp clip 0.06299 0.06299 sc % Arc 7.500 slw gs n 10768.8 6300.0 931.2 -104.9 104.9 arc gs col0 s gr gr % Arc gs n 11061.8 6291.8 908.2 -100.9 89.5 arc gs col0 s gr gr % Arc gs n 4039.0 6150.7 709.7 -111.4 103.8 arcn gs col0 s gr gr % Arc gs n 2676.2 4632.4 608.0 175.5 22.0 arcn gs col0 s gr gr % Ellipse n 10620 6210 1554 1554 0 360 DrawEllipse gs col0 s gr % Ellipse n 2430 6210 1554 1554 0 360 DrawEllipse gs col0 s gr % Ellipse n 6480 2610 1554 1554 0 360 DrawEllipse gs col0 s gr % Ellipse n 10530 6300 900 900 0 360 DrawEllipse gs col0 s gr % Polyline gs clippath 5250 3450 m 5130 3420 l 5250 3390 l 5115 3390 l 5115 3450 l cp 2731 4655 m 2610 4680 l 2705 4601 l 2583 4660 l 2610 4714 l cp clip n 2610 4680 m 5220 3420 l 5130 3420 l gs col0 s gr gr % arrowhead n 2731 4655 m 2610 4680 l 2705 4601 l 2718 4628 l 2731 4655 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 5250 3450 m 5130 3420 l 5250 3390 l 5250 3420 l 5250 3450 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 8970 6180 m 9090 6210 l 8970 6240 l 9105 6240 l 9105 6180 l cp 4080 6240 m 3960 6210 l 4080 6180 l 3945 6180 l 3945 6240 l cp clip n 3960 6210 m 9090 6210 l gs col0 s gr gr % arrowhead n 4080 6240 m 3960 6210 l 4080 6180 l 4080 6210 l 4080 6240 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 8970 6180 m 9090 6210 l 8970 6240 l 8970 6210 l 8970 6180 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 10167 4598 m 10260 4680 l 10140 4651 l 10260 4714 l 10287 4660 l cp 7923 3502 m 7830 3420 l 7950 3449 l 7830 3386 l 7803 3440 l cp clip n 7830 3420 m 10260 4680 l gs col0 s gr gr % arrowhead n 7923 3502 m 7830 3420 l 7950 3449 l 7937 3475 l 7923 3502 l cp gs 0.00 setgray ef gr col0 s % arrowhead n 10167 4598 m 10260 4680 l 10140 4651 l 10153 4625 l 10167 4598 l cp gs 0.00 setgray ef gr col0 s % Polyline n 360 810 m 12690 810 l 12690 8010 l 360 8010 l cp gs col0 s gr % Polyline n 9630 6300 m 11430 6300 l gs col0 s gr % Polyline n 10530 5400 m 10530 7200 l gs col0 s gr /Times-Roman ff 270.00 scf sf 1980 6300 m gs 1 -1 sc (Client) col0 sh gr /Times-Roman ff 270.00 scf sf 5940 2790 m gs 1 -1 sc (Database) col0 sh gr /Times-Roman ff 270.00 scf sf 5940 2430 m gs 1 -1 sc (TANGO) col0 sh gr /Times-Roman ff 270.00 scf sf 1890 5940 m gs 1 -1 sc (TANGO) col0 sh gr /Times-Roman ff 270.00 scf sf 10800 5220 m gs 1 -1 sc (Server) col0 sh gr /Times-Roman ff 270.00 scf sf 9720 5220 m gs 1 -1 sc (TANGO) col0 sh gr /Times-Roman ff 210.00 scf sf 9990 6030 m gs 1 -1 sc (Cmd) col0 sh gr /Times-Roman ff 210.00 scf sf 10620 6030 m gs 1 -1 sc (Attrib) col0 sh gr /Times-Roman ff 210.00 scf sf 9720 6570 m gs 1 -1 sc (CORBA) col0 sh gr /Times-Roman ff 210.00 scf sf 9900 6840 m gs 1 -1 sc (attrib) col0 sh gr /Times-Roman ff 210.00 scf sf 10620 6570 m gs 1 -1 sc (CORBA) col0 sh gr /Times-Roman ff 210.00 scf sf 10620 6840 m gs 1 -1 sc (opera) col0 sh gr /Times-Roman ff 210.00 scf sf 2430 4950 m gs 1 -1 sc (API) col0 sh gr /Times-Roman ff 210.00 scf sf 3510 6300 m gs 1 -1 sc (API) col0 sh gr /Times-Roman ff 210.00 scf sf 10260 7470 m gs 1 -1 sc (Devices) col0 sh gr /Times-Roman ff 210.00 scf sf 6210 6120 m gs 1 -1 sc (CORBA) col0 sh gr /Times-Roman ff 210.00 scf sf 9450 4140 m gs 1 -1 sc (CORBA) col0 sh gr /Times-Roman ff 210.00 scf sf 2700 4140 m gs 1 -1 sc (CORBA) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/ds_model/event_schematic_zmq.eps0000644023471100065110000001371413034745263017626 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: zmq_event.fig %%Creator: fig2dev Version 3.2 Patchlevel 5c %%CreationDate: Wed Feb 22 13:33:58 2012 %%BoundingBox: 0 0 468 364 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 364 moveto 0 0 lineto 468 0 lineto 468 364 lineto closepath clip newpath -115.5 411.8 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 50 % Ellipse 7.500 slw n 8505 2970 738 738 0 360 DrawEllipse gs col0 s gr % Ellipse n 8490 5227 738 738 0 360 DrawEllipse gs col0 s gr % Polyline 0 slj 0 slc n 1950 1575 m 1845 1575 1845 2550 105 arcto 4 {pop} repeat 1845 2655 3450 2655 105 arcto 4 {pop} repeat 3555 2655 3555 1680 105 arcto 4 {pop} repeat 3555 1575 1950 1575 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 1950 1575 m 1845 1575 1845 2550 105 arcto 4 {pop} repeat 1845 2655 3450 2655 105 arcto 4 {pop} repeat 3555 2655 3555 1680 105 arcto 4 {pop} repeat 3555 1575 1950 1575 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 1950 3510 m 1845 3510 1845 4485 105 arcto 4 {pop} repeat 1845 4590 3450 4590 105 arcto 4 {pop} repeat 3555 4590 3555 3615 105 arcto 4 {pop} repeat 3555 3510 1950 3510 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline n 1950 5445 m 1845 5445 1845 6420 105 arcto 4 {pop} repeat 1845 6525 3450 6525 105 arcto 4 {pop} repeat 3555 6525 3555 5550 105 arcto 4 {pop} repeat 3555 5445 1950 5445 105 arcto 4 {pop} repeat cp gs col0 s gr % Polyline gs clippath 3694 2023 m 3546 1992 l 3534 2051 l 3682 2082 l 3682 2082 l 3571 2028 l 3694 2023 l cp eoclip n 7785 2925 m 3555 2025 l gs col0 s gr gr % arrowhead n 3694 2023 m 3571 2028 l 3682 2082 l col0 s % Polyline gs clippath 3679 3986 m 3532 4024 l 3548 4082 l 3694 4044 l 3694 4044 l 3571 4046 l 3679 3986 l cp eoclip n 7785 2925 m 3555 4050 l gs col0 s gr gr % arrowhead n 3679 3986 m 3571 4046 l 3694 4044 l col0 s % Polyline gs clippath 3694 4101 m 3548 4062 l 3532 4120 l 3679 4159 l 3679 4159 l 3571 4099 l 3694 4101 l cp eoclip n 7740 5220 m 3555 4095 l gs col0 s gr gr % arrowhead n 3694 4101 m 3571 4099 l 3679 4159 l col0 s % Polyline gs clippath 3683 5930 m 3534 5958 l 3545 6017 l 3694 5989 l 3694 5989 l 3571 5982 l 3683 5930 l cp eoclip n 7740 5220 m 3555 5985 l gs col0 s gr gr % arrowhead n 3683 5930 m 3571 5982 l 3694 5989 l col0 s /Times-Roman ff 222.25 scf sf 8190 5130 m gs 1 -1 sc (Device) col0 sh gr /Times-Roman ff 222.25 scf sf 8100 5400 m gs 1 -1 sc (server #2) col0 sh gr /Times-Roman ff 222.25 scf sf 8145 3150 m gs 1 -1 sc (server #1) col0 sh gr /Times-Roman ff 222.25 scf sf 8235 2880 m gs 1 -1 sc (Device) col0 sh gr /Times-Roman ff 222.25 scf sf 2295 2160 m gs 1 -1 sc (Client #1) col0 sh gr /Times-Roman ff 222.25 scf sf 2250 4050 m gs 1 -1 sc (Client #2) col0 sh gr /Times-Roman ff 222.25 scf sf 2250 6030 m gs 1 -1 sc (Client #3) col0 sh gr /Times-Roman ff 222.25 scf sf 5040 2160 m gs 1 -1 sc (Event\(s\)) col0 sh gr /Times-Roman ff 222.25 scf sf 4995 3330 m gs 1 -1 sc (Event\(s\)) col0 sh gr /Times-Roman ff 222.25 scf sf 5130 4455 m gs 1 -1 sc (Event\(s\)) col0 sh gr /Times-Roman ff 222.25 scf sf 5130 5985 m gs 1 -1 sc (Event\(s\)) col0 sh gr /Times-Roman ff 285.75 scf sf 1935 990 m gs 1 -1 sc (Schematic of event system for TANGO release 8 and more) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/dance/0000755023471100065110000000000013034745265012425 500000000000000tango-9.2.5a/doc/src/dance/Makefile.am0000644023471100065110000000027413034745265014404 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ Ready img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/dance/Makefile.in0000644023471100065110000003273213034745265014421 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/dance DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ Ready all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/dance/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/dance/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/dance/cover_tango_book1.jpg0000644023471100065110000010700413034745265016452 00000000000000ÿØÿàJFIF,,ÿá²ExifMM*bj(1r2‡i¤Ð,,Adobe Photoshop CS Macintosh2006:08:16 16:56:11 ÿÿ Ö @&(.{HHÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ q"ÿÝÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?óÝqq›~.*>¥Ÿ¾ï¼¤îJŠJgêÛûîÿ8¤.¼„ùÇûÔRIVdä-³üçz¶eŽ/³ü÷z€¬–΀€~k@t.¤0hê¢1²· \ÜàÒ¿gÒcg³Ôzº@&ëZÔ´Ænol‹ÏwþI8ê㌛‡ýqßù%ºß©yÇêýýaͶ£ŽÁhªÆDÕ§¨ïÍú·oÿÀÿ=sp ýA}[´úã.ÿûuÿù$ã«uQÆf@ÿ®¿ÿ$ª¥¢(¶àë]`qŸ’?ëÖäÓþÜëCþô2¿íë?òj«X×;nè&.ÐOò榶»*±ÕØÒËK\ÓÈ!%7]ëŸùc—ÿoÙÿ“Oÿ8:ð˜êYcOôöÿäÕIOѾ­ßé_þ{¿½%‘SÿÐò÷rS'w%2J^<9V³0F6ÂÛ·±,üö—¿Ó°3v×{Õm¤ëÀì¹[êLæç[•M,ÃkÜKj«€ Ÿ¥ùþï~í¿Î oE(Þýàc4¾ÌkìeVÚZÚÛa&wn²Ï ÍŸ×^‰ƒƒ‰SªèÆeMƭ̶Ãí5¾Ç\ÜM¿££}{þÔßø/ðKÊÉ.t»Ry*÷Hê7ôìÆdSa¨·Iäi¿º›(u] œØ»Ð×gÖ¾¸; dzƹØ×V]¶·­.­ó·w©Cn©ŒÜ¼c´­ÿ­?Zrºëqix5SŽÉ}aÒÇÜK¿XÛüš§^ÿ¡úOô‹4F1"íYgÃö÷c ®è}¦u\aÖ#=¶`-!ÛwUê=îú;=ÞÏræp®f>UW¾¦^ڞךlúÚwl²?1˹é=AØØ9ýPkëµö hçû½¥ßÕg¹G˜òÕ~ ?—‚o©¸yµâºyìlÚâ?³¸ Œn……_Nê4ûlÈkñ²Yü¼}ž•³ûÎÇ{+üRìþªÑc:V%¶?‘ ÿ/Þßûn†ÓXãQî+¥°í;ò2\ãÞCiÿɨñ“îo}Î cº¢u|ß²cßàSΑà˜÷øi®ý’xI%?ÿÑórQIöú€µ¯Ô!ôßÉVs2òÇ0ÉØñæí?¬ˆA¾Œm-$»†´µ£ï€ª”z{Èv¾×Dýè'“ ‚—e$¥l9€;¶„j0r/Ìl0ròa¢jýÎÁ¾eiW‡ÔËÜÛE¬¬`d}7ãý=Ÿðõz´¤NŠŒMê,x:U…¸îȲÝà4ÃG´LhíÞÿ¢ªcfu@Ö`7%ÌÂþhAi[?DnK+©W‡F=­s1mÜ꟨†{]Nÿø;6úÌÿ=nt¾•]™˜²˜ëXÍu–J¹wüc½g*Ù2pš–·³©ÉòC,HÜxz[×ô¬ÏÔqïÛO†é !ŸÈ«cgøÈéùêÿ¯S=Jq²j¶×ô´ŒGÿcסŸöýK,õS)ÿgs†%nô1›2>“žëë›güZí°6u®‹VMm{l`c˜ïtµ®s]¹ŸEÍÿÕ3S=i9¹Y "gA-?Æ|5D÷ø.»üetn™Ò:å5têÛEwã‹,¥³áÖW½üÆØÖýÉÿtæð’ ôl‘v$ŠÿÒóòTS»’˜”–€àíÐ`‚ÙàIóà ž—i¯šéúž}Ý;êöC©Ís^Ñ—˜ÁXÛs}ZÚû œ÷[V;ë§èUé®`-í¨@ºé¢é@Ä!D/ñ¶Xˆ1!Þcý©$×Cƒ£ƒ)ßÒÞñ÷¢µa<ð{+X™ù8·Wu6í¤ÍnGùßœªê@ê­^þÀÏ­:ƒv@ÃÌÅuŽÇ´‰©î°WêúÖ·ÞÏæYúOðè¬YUõ±ÑÅYxæÌmÇìùµÿ4òÂæ´×{Ccw³þ 똦û¨vúžXížGsd~w¹uëîNè2Ú,¡óê6Ó?Ks>‡ºTSÆ+QÄ:U³‡šÉŒÜ&q’*_¥ÿz+S¥u:iûm@˜<Ÿi¯Ú?9Î^­õG§Y…Ó›‘“"ëÀ¦LŠÁþn–ÿÅÿçÍë¢ýFúÀj̧”^×5àÒ}6’Ó»m”·ôÖý?øÁúÑ_FèîéøÏoÍi®°9egÙmçoÑöþŽŸøOø¥`ì]ží¬¼æL˜cŽ|"ëÓ|ËëgYwZëùyÛ·T^kÇðW,ª?¯üïýqcžÿéuh æ“džïÒ©'‚’(ÿÓóJˆè5'@>*o‰)èsY}oq†µÀ“Æ€ÊI¿¯2‹u‡6*ªºŸ\¶Cƒ?K-oé7ooó—ÛkȤÓsê:í<ùrÖH¦›©c=FSÓo´¸5ÕzSüõ¶îÞ÷ªn±–äUq­¶úzšœ iÖvY75C(“¡£ùº<ÙÅ–õDN&¿Ðý+WIèy}L—¶(Ägó¹VhÆôƒ'o«oüëžš¿›GD©‡§ÑëÎe®%Çú­Yÿ¦ÉÌÌÏÙö—5•WªX6ÖÁÙ¬©¾ÔÎm ÕÖ_íJFgÃÀ-Äy\b¬NGyÊ<_âÑj fPeL¤ "]XycA{x¿ô\„û«°@ùÿ’B"cuóÉ‚Q¨~”Ös è›ljíº1/ʱµPÝÖ<ín£“ü¥QÁÁÄ:d3Ο(7§fŽHT¨Ô¾^Íœ£—ÓïeøvÞØ$AþK›û©º—QÌêy–fæYê]g'€Ñµ±¿™[?5WL ºbâ5W§eBDh~ Ò<‚(~•I<$’_ÿÔóòTS¸êS$¦îVMW¾‡Ì9´ÖË Gº±éÿkØÖ&9Aº4ʳõq³2ÚÜÖ¿uGh{C†íÌÚv»úÊ}CöCqÚÆ~Ó«™[cc×Ó¹Îú_ð~—ø$Ã/W ÏTœ^ïˆÔQë4dñåFö›œòçwðÕ5¯¿)t裖ӰÛ”8½@l¿îâ8¥/›MÚ€¥Þ}èØÏ t;PPw{cÎSOtò,S^1#£±Kö½®o- ’]ÇmyÆúÄU–Ñ{GƒœH¹ŸÙ¹¯A¦é^Í?iéu~Ãÿƒ·ôv›siP‹ŒÇ¥ÒÉY¹iWÍÖGüŸþcŒ’I‰S¹L“Á$%?MlII/ÿÕò÷rTTÉQI-œ ë02FE`9À{‚´oê?3Õ=‡Ç8;tüÖ×3ó¶—1ÛêýÅŠR ¦›ëÝ›5“ Jýÿç6[“]z¸´Àwä¡Ù{íq8B„á ¬–iÊ<7éìI(Jc]-+W§X.s±ÜDd±Ôëĸ~ŒÿfßMdÇ‚-6j x&N6<[¶onZ뤇‚2$hAñL‹•g«‘e±çs€ñ"]ÿIþÃ]ÿ¤ÒS˜'²Óÿ›Y¿ò£8è5¿úMGþl}eÿÊœïý†·ÿI¢§18Z?ógë'þTæÿì5¿úM/ùµõÿ*³ößý&‚œå !_ÿ›ŸX‡ýåæÿì=¿úM/ù¿õ€ÞfgþÃÛÿE£¤&!_ý×ÿò·/ÿaíÿÈ&ýƒ×¿ò·/þØ·ÿ ’š0™Ü¡û ®åv_ý±gþAEÝ ­Áÿ'eÛäSô¼¤‡'ÀýÉ —ÿÙÿí2’Photoshop 3.08BIM%8BIMê¦ com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName A4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMéxHH/ÿîÿî8Ag{àHHØ(dÿh 8BIMí,,8BIM&?€8BIM 8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM@@8BIM8BIMW@Öphoto pub 2007 okÖ@nullboundsObjcRct1Top longLeftlongBtomlong@RghtlongÖslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong@RghtlongÖurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?ð8BIM8BIM —q TÔ€{ÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ q"ÿÝÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?óÝqq›~.*>¥Ÿ¾ï¼¤îJŠJgêÛûîÿ8¤.¼„ùÇûÔRIVdä-³üçz¶eŽ/³ü÷z€¬–΀€~k@t.¤0hê¢1²· \ÜàÒ¿gÒcg³Ôzº@&ëZÔ´Ænol‹ÏwþI8ê㌛‡ýqßù%ºß©yÇêýýaͶ£ŽÁhªÆDÕ§¨ïÍú·oÿÀÿ=sp ýA}[´úã.ÿûuÿù$ã«uQÆf@ÿ®¿ÿ$ª¥¢(¶àë]`qŸ’?ëÖäÓþÜëCþô2¿íë?òj«X×;nè&.ÐOò榶»*±ÕØÒËK\ÓÈ!%7]ëŸùc—ÿoÙÿ“Oÿ8:ð˜êYcOôöÿäÕIOѾ­ßé_þ{¿½%‘SÿÐò÷rS'w%2J^<9V³0F6ÂÛ·±,üö—¿Ó°3v×{Õm¤ëÀì¹[êLæç[•M,ÃkÜKj«€ Ÿ¥ùþï~í¿Î oE(Þýàc4¾ÌkìeVÚZÚÛa&wn²Ï ÍŸ×^‰ƒƒ‰SªèÆeMƭ̶Ãí5¾Ç\ÜM¿££}{þÔßø/ðKÊÉ.t»Ry*÷Hê7ôìÆdSa¨·Iäi¿º›(u] œØ»Ð×gÖ¾¸; dzƹØ×V]¶·­.­ó·w©Cn©ŒÜ¼c´­ÿ­?Zrºëqix5SŽÉ}aÒÇÜK¿XÛüš§^ÿ¡úOô‹4F1"íYgÃö÷c ®è}¦u\aÖ#=¶`-!ÛwUê=îú;=ÞÏræp®f>UW¾¦^ڞךlúÚwl²?1˹é=AØØ9ýPkëµö hçû½¥ßÕg¹G˜òÕ~ ?—‚o©¸yµâºyìlÚâ?³¸ Œn……_Nê4ûlÈkñ²Yü¼}ž•³ûÎÇ{+üRìþªÑc:V%¶?‘ ÿ/Þßûn†ÓXãQî+¥°í;ò2\ãÞCiÿɨñ“îo}Î cº¢u|ß²cßàSΑà˜÷øi®ý’xI%?ÿÑórQIöú€µ¯Ô!ôßÉVs2òÇ0ÉØñæí?¬ˆA¾Œm-$»†´µ£ï€ª”z{Èv¾×Dýè'“ ‚—e$¥l9€;¶„j0r/Ìl0ròa¢jýÎÁ¾eiW‡ÔËÜÛE¬¬`d}7ãý=Ÿðõz´¤NŠŒMê,x:U…¸îȲÝà4ÃG´LhíÞÿ¢ªcfu@Ö`7%ÌÂþhAi[?DnK+©W‡F=­s1mÜ꟨†{]Nÿø;6úÌÿ=nt¾•]™˜²˜ëXÍu–J¹wüc½g*Ù2pš–·³©ÉòC,HÜxz[×ô¬ÏÔqïÛO†é !ŸÈ«cgøÈéùêÿ¯S=Jq²j¶×ô´ŒGÿcסŸöýK,õS)ÿgs†%nô1›2>“žëë›güZí°6u®‹VMm{l`c˜ïtµ®s]¹ŸEÍÿÕ3S=i9¹Y "gA-?Æ|5D÷ø.»üetn™Ò:å5têÛEwã‹,¥³áÖW½üÆØÖýÉÿtæð’ ôl‘v$ŠÿÒóòTS»’˜”–€àíÐ`‚ÙàIóà ž—i¯šéúž}Ý;êöC©Ís^Ñ—˜ÁXÛs}ZÚû œ÷[V;ë§èUé®`-í¨@ºé¢é@Ä!D/ñ¶Xˆ1!Þcý©$×Cƒ£ƒ)ßÒÞñ÷¢µa<ð{+X™ù8·Wu6í¤ÍnGùßœªê@ê­^þÀÏ­:ƒv@ÃÌÅuŽÇ´‰©î°WêúÖ·ÞÏæYúOðè¬YUõ±ÑÅYxæÌmÇìùµÿ4òÂæ´×{Ccw³þ 똦û¨vúžXížGsd~w¹uëîNè2Ú,¡óê6Ó?Ks>‡ºTSÆ+QÄ:U³‡šÉŒÜ&q’*_¥ÿz+S¥u:iûm@˜<Ÿi¯Ú?9Î^­õG§Y…Ó›‘“"ëÀ¦LŠÁþn–ÿÅÿçÍë¢ýFúÀj̧”^×5àÒ}6’Ó»m”·ôÖý?øÁúÑ_FèîéøÏoÍi®°9egÙmçoÑöþŽŸøOø¥`ì]ží¬¼æL˜cŽ|"ëÓ|ËëgYwZëùyÛ·T^kÇðW,ª?¯üïýqcžÿéuh æ“džïÒ©'‚’(ÿÓóJˆè5'@>*o‰)èsY}oq†µÀ“Æ€ÊI¿¯2‹u‡6*ªºŸ\¶Cƒ?K-oé7ooó—ÛkȤÓsê:í<ùrÖH¦›©c=FSÓo´¸5ÕzSüõ¶îÞ÷ªn±–äUq­¶úzšœ iÖvY75C(“¡£ùº<ÙÅ–õDN&¿Ðý+WIèy}L—¶(Ägó¹VhÆôƒ'o«oüëžš¿›GD©‡§ÑëÎe®%Çú­Yÿ¦ÉÌÌÏÙö—5•WªX6ÖÁÙ¬©¾ÔÎm ÕÖ_íJFgÃÀ-Äy\b¬NGyÊ<_âÑj fPeL¤ "]XycA{x¿ô\„û«°@ùÿ’B"cuóÉ‚Q¨~”Ös è›ljíº1/ʱµPÝÖ<ín£“ü¥QÁÁÄ:d3Ο(7§fŽHT¨Ô¾^Íœ£—ÓïeøvÞØ$AþK›û©º—QÌêy–fæYê]g'€Ñµ±¿™[?5WL ºbâ5W§eBDh~ Ò<‚(~•I<$’_ÿÔóòTS¸êS$¦îVMW¾‡Ì9´ÖË Gº±éÿkØÖ&9Aº4ʳõq³2ÚÜÖ¿uGh{C†íÌÚv»úÊ}CöCqÚÆ~Ó«™[cc×Ó¹Îú_ð~—ø$Ã/W ÏTœ^ïˆÔQë4dñåFö›œòçwðÕ5¯¿)t裖ӰÛ”8½@l¿îâ8¥/›MÚ€¥Þ}èØÏ t;PPw{cÎSOtò,S^1#£±Kö½®o- ’]ÇmyÆúÄU–Ñ{GƒœH¹ŸÙ¹¯A¦é^Í?iéu~Ãÿƒ·ôv›siP‹ŒÇ¥ÒÉY¹iWÍÖGüŸþcŒ’I‰S¹L“Á$%?MlII/ÿÕò÷rTTÉQI-œ ë02FE`9À{‚´oê?3Õ=‡Ç8;tüÖ×3ó¶—1ÛêýÅŠR ¦›ëÝ›5“ Jýÿç6[“]z¸´Àwä¡Ù{íq8B„á ¬–iÊ<7éìI(Jc]-+W§X.s±ÜDd±Ôëĸ~ŒÿfßMdÇ‚-6j x&N6<[¶onZ뤇‚2$hAñL‹•g«‘e±çs€ñ"]ÿIþÃ]ÿ¤ÒS˜'²Óÿ›Y¿ò£8è5¿úMGþl}eÿÊœïý†·ÿI¢§18Z?ógë'þTæÿì5¿úM/ùµõÿ*³ößý&‚œå !_ÿ›ŸX‡ýåæÿì=¿úM/ù¿õ€ÞfgþÃÛÿE£¤&!_ý×ÿò·/ÿaíÿÈ&ýƒ×¿ò·/þØ·ÿ ’š0™Ü¡û ®åv_ý±gþAEÝ ­Áÿ'eÛäSô¼¤‡'ÀýÉ —ÿÙ8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMÿá http://ns.adobe.com/xap/1.0/ 4294967295 1494 2112 1 300/1 300/1 2 2006-08-16T16:56:11+02:00 2006-08-16T16:56:11+02:00 2006-08-16T16:56:11+02:00 Adobe Photoshop CS Macintosh adobe:docid:photoshop:13f3a912-2d9d-11db-8d22-860a69fa5459 image/jpeg ÿâ@ICC_PROFILE0ADBEmntrRGB XYZ ÏacspAPPLnoneöÖÓ-ADBE cprtü2desc0kwtptœbkpt°rTRCÄgTRCÔbTRCärXYZôgXYZbXYZtextCopyright 1999 Adobe Systems IncorporateddescAdobe RGB (1998)XYZ óQÌXYZ curv3curv3curv3XYZ œO¥üXYZ 4 ,•XYZ &1/¾œÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ£)"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ñ™uÆcºêcÿ5¼¹#ý|¿÷ѦIÖ£þC$û]Æ×Éÿ}_µÜ`~úOûèÔ½…Kö»ùï'ýõNûmÎ?×Éÿ}Uz^ÔŸí·_óñ/ýõH/®¿çæ_ûèÔ&“µY÷yé2ÿßf¨^ÿSßf«Ž¢“µZ•öOúdÿ÷Ù¥þÓ¿Ïü~Ïÿ Té{ÐÁ«j#¥õÇýü4á¬jC8¿¹ÿ¿†¨ƒKÐsùPïí­S?òºÿ¿¦”ëš®?ä%uÿMgçšBxühGûwWÿ ßýý4ïíý\tÕ.ÿïé¬ÊS@\Ò!Ö‡MVóþÿpñ&¸:j÷£þÛ7øÖ]ÍQâ|tÖo‡ý·jQâ¿Æ·ÿÚ²iJæÏü%¾"Çü‡/ÿïûQÿ ˆøÿ‰î¡ÿÚ±CIé@înø”t×µûþÔáãOùê?÷ý«–€¹¾Õ:õÙׂAï_R}¶ãþzʾ1²ÿ¸¿ß_ç_cÓñ¤j?á©$ëLÇ) a¥ì(4vRö õ¤ïZA@ê(íJ:Òv ÿ^ôô¸ë@ F ÍSЀ>”Îô„gÿ¯Så0˜_›Äž´÷„¼fcÜýÐ;Ð+a€Î8¥ëWcÓ®d•`’Ìx½I¨è×zb©•8<^@üi]W3ðE%/<ðx¤¦ 4ÑÒŠhé@cô¤i{Qé@é¢J%/­*®XÔšPŒÌUA&€zRqE4Ðw£ÖŽô¾´(¥îh¨îhOJo¥;Ö›é@ì¿ãò÷×ùרÕñÍ—ü}Åþúÿ:û„Æ’u¨ÿ†¤~µðÐRö”½…”£¥ ¢€H)ǽ7µu¤íJ:ŠNÔõ=²ù’”ù‡z€w©"`’«H3ŒŠ}Ôk€Jµ¢hókz´:|,¥<±è£¹©o,Œ³'—·qx! ¾¹õíŠÚøu ƒÅJ’|¦Hš5'׎?JMÙ3H$ä“4õ¿‡0éPÃäÝI,³å9$c·N:×)s§Ëöx¤Ù…ÎЙÎM{Åĺ‹ã†Xäû$(ÒÛ»°ÇOsXv¾¿¬¡7´iw œ•ô¬)Ôoszô’k•žðõíäPÊÐÉÃr\æ»ío¯yáûå¶¶„'’^RÇ,vŒµÒÛÀ¶v¹0qÚ²“ŶV÷2A2¼°²²9‡æÙ~÷µwcŒš¥Á*:–b¦WÛÓqÇÒ£­Î1)½©äS{S;QéK”óøR@âÜñZºV…q©n+ò€3õ¦Ï¤Km ÆåÉL~<ñ½‹äv¹B9$2ãäç¥(‘ÔäcÒ´bÒ¥e¼P¹1"±üEVk D¬›N6u¹Ð¹Xûxcº“É—“ÒE>¢ªÝÚËgu%¼Ë‡¶‘Zzv3Ê„Ø߯ùúWg®xYu? ¾£ /öÛXÃ1ƃ¨>à~‚£Ú$ìRƒhóÖ”u4¬0i;ÖÄô¤îiÊ:Ðà ԇ¥'¥)àS})nËþ?!ÿ}}_ÙÇÜ_ï¯ó¯±© >4“­3øiòu¦ %(è);Òö QH)Ã¥曊uIoÚ.cˆaw¸\КGCi-`žÍšc${ö㓎pJÊÉå6€àŸzë£Õíô{4Z/˜Öþa”·Ìn1ôÀÎNò˾h*Œ3…è®+5'#iA%æP©­“̺0Næ½[°X<Ó Ú>îE2IV ¡4 府«/>¢´0¾¶7.ôÉã·†Óî˳-‘óyÆkªðç‚_PÑÄ?“r®9@û¸®Bñ Ó/<ÉâûB1Ë~oν_ÃÞ.Ñ®`1Çy.ßòÎS·öëXTr:)rßRÍ¿Šã¾‘´ß³šµæåb;­oéÙVc9¯*Ñ®„:Íʰëךõ)ÃÚ `“P»›)9;3¬ÓÄ3¹ºù☱©ŒDá7|ÓBlôÁ¦išÌªÑ!ÀHn¢C‚çh>`üsšó×#ˆrñƒ…,1‘î)÷——×Mqu3Í3}çs’j§jˆÆÛšJ|Å£¨ÌÃiGN•°fÈ~5.9ª"Š‘OZ`¸Æq@l®ž ´ub9õ¯QðïŒ(–+–Øz+v5ähÌ®:Vå½Ò¼œuÅ7A¸;£Ýnõ”‡Ã—ºƒ¡–#Þ|¹ Ÿnžø¯×uûýzì\_Îò²®ÄÜsµsœUûßjcF—Km6·rÎ+šcšˆÂÛšN¯:²F)®ÆCH¦Å<ý)£¥=ÊkÑü%—cáÖº–Oô»‚S~2±Øã¥yÊž+ON¼h&]£cóFƒYÔãcJRåšgA`È·÷8 C¶xö¯SÓ'û>‘`$l̬Aïÿë¯7Ò’9»Àé ùã è?:ë./ÖÄFÇSœôÎ2Z㞈펬ÀÕuw–êéŒÌŠ¤ç£’?QùW i0:iâM˜’iL‡ØmͱøW“é*úÆ­…†ö9¯n°„•Ù÷R5ç¯]ÇôÀ¢Z+ÂîW-Ä‚ÙÒ<…‡æOô¦ÀÁîgä¼àíM´v¾–[’GB2àOò§ÙÆ>ÕlÀY7·>œÔGsg±äßåŠ_ÂbHmÑß9"¼œõ5éŸTNIÎcB9í´W™ž¦½lpOqêËŽri‡©¤w5déMô§†“°¦«/øü‡ýõþuö5|ueÿÿ¾¿Î¾Æü)ñ¬j>Õ#õ¨ûPRŽ‚ŠQÐS –ZfÚ:w>”2‰ ÀúûÖ†Ô‚!Ž$úšd¶U» â8ÿ„QžƒûË’Ý…=— sŠ@T?z™Úœµ7µïGzz^ô-?Öš)}hyÍ!b1´‘Ïj^ôÖ>´¼OfÍÕ—­T"ŽˆUI=ªÏ•æ&d 7¨ÉØ©N¥ «pqE!ˆGÐ8©1RAk,äSõ4 jB£ƒR©#pkZ Lbßð©ukYh‰Q”#<ÿJŽx”éÊ×:_Gö„ˆË*ùhw°fûǰþµ¹¬Íoö6·IU¤òsÐzW’<æ2V|žãŠe²JgŽFf9n¤Ö£}nuRªö±ê> ³ò$¼¹(6ù¿z@¹fÓ¤’#ÌÄç˜ÿë ó=áí´i£f˜€¹õ<Ÿé^¦îÙom@p÷'üë\Òwv7JÆÍ”‰¼!p¢!‘þÑ?ýj«srÖö r2 Èõçôâ›-Îd3ÈHÊ1ýjMbÌÜx$I bhß;½sÏõ¢:‰«Yñ¶ÒAâõ»Ú<¹!A¸nõåÎ¥Xƒßšö‹¬· ¦»KÛ©Ç~ƒü y¤—9úWu7tqUVÁGs@¥îkC1zo¥8ô4…1–¬y¼‡ýõþuö5|seÍä?ï¯ó¯±¨ãWëQÿ I'Zøi¨¥ÛhêjòY›¿„KÒ£Ó„fëtÛ€=I­[ß—OؽpFWBÖÆU£aŒ¤dô©BNsøTH<´Á#5“së@[RXð®Ò>(õ5ÎÄœÑ4¾`@1×ëSÍÚ0y¤!ÔRv§‡Å4t ¡=i{Òzýi{Ð1Aæ—9š)}hþ3Mnƒë@<Э%¥g$õ¨b¤.2i’H~déô5jßLi€o1vŸîÕUaŠžÚñì¤Ü¿2ž¢“¿AŤõ5“L‚ÑÈ2}Mhé©’.Ð+/QÔã›LÚÜySUô=LG2¬‡“À¬lÞçJ’MXô»kh„ íÅs¾&X#·,è¤v©«Rë)klYœ5ÊêÓjQ™Ü¸ì}½k ;´áÏ¢2žIãõéV`Œ Rg!Ûè:ÖÝžä°èeΛÑÙ/+²_Öÿät6RˆÒ7r°_\p+Ñ´¥k[U¹¸#ÌnëÐWš<¶ÄlÍ|î'§¥^Õõj€i\\ÇÐ*}­N§^¿ƒF³.ÄGÊ=N+€¶fžé¦”îšC–>•¥ãÛÖ›_·´#÷qBRýUŸ§…Xç˜õP@úâ¶›²<|I¶Í´‚\&wÄ„îØx;Qsqn¾aÖÛ_nô?–+ÏôÝßcº™Ï/À®»Â$:ݱ”â8íË9öÅf´•Žú°R£)[£=!Äíl˜ïÎ7¤zÕ½6É2HäÕ-6áµó˜aXåG í] Q„·Î;WLUõ>q½O/øÁj’x;q½½Ê:àƒý+çöûÍ^çñR  EhÍq8ü—Ÿð¯ 'æ5½-ŽJöæÓOAJzRÕ©‰wLÔ­‡ý5Oæ+ìŒWÇ_ü„íë²1_dbšãûÕAO~´ÃÒ 'š\ð)=h(¥)¢œ)ëWß›Xó×U …³…8ö«[ Y«ž â2‰ûôÑÒ¥lmQžNsíQ@ÄëšPHlúU·´Š4ÜÌØëÅW‘Pclƒ×=E4hõ¤¾´gšiéøÓˆïM=(:ž)ÅMSÈ B¤Ì«·9†¬­ÆÈ0§ªžET#4ªqÁ¤ÐÍý#Y—LìÎJ×¥éž!¶ºHžGÜ;{WŽFFF·´©ä†HÙO ¬åšBm3®ø¡ê:õü®Ÿjf·ŽØ$›XIéס¯>Žym)Æ8*½I×£X"WùdëUvù˜ã©5…87«:±ø˜Ó³†ìí´ª+€V–¥r¶Öls€Ib8…qõ¦øJþ@Ä;Gå&vãük¯ecçºÜðÏø¡¼I¬–L‹h H†~÷?{ñ®LžM8žiÍtE$¬ŽIÉÝŠzo¥-!íT"ö—ÿ!K_úìŸÌWÙ5ñ¶—ÿ![_úìŸÌWÙT >-~µðÔÖ£ê)ÚP`óK»L V¬á:‚3ìj &·¼%¥K«ø†ÖÖ$Þ7op[hÚ¼œžÃÞšÕƒ=_Føy¥Ãà‰u r³#:FìW˧OZòSOK'hámаFsž=?:ôøŽéãyÄp·5´³L€ÁÍysÞ»H¬î̬1ÉÎ*9¹¤ÚØÒQäŠMjRlïæ™ü5,£ j xª3,Êå­SæÏ"«w¡NÒisóP£MíŠtÑl\‘Ži±6Ùæ¬0qx  éj^ôqZv)ÆšOoJ  C¨Èîi›½)(‡š|[°x¤d9ìj*A÷h§´ñ]Ó†l`šè,.ã×íç[¹HUl",»B€3¸ú÷¯8íSÁrðÈ®9#Ö¡Án‹çv³=ÇÂ7ëi§%°`Ñ`s‘šÕ¾ðg†õÅfk4†VçÌ€ì9þUã:w‰f…†Xñ]Æ‘ãA½œÖ2‹NæÑšµŠzç­FÍ‹éR}²?ø× ©izŽ˜ån¬®-ŸÕЀúKñ 1ƒ»5¾‘Ú_ŲXÒEaÑ— ЪIyÙEê´>gðžŸ&§âhÈgT;›¾+éÍØAmãJhö·fêÒÆ$?xÄ6çðVäQˆPJNM½!U¹4òl“^ ñ—[3^ÚéHàª4˜=ÏÃ?zŒ¼Umáí=®n ª«Õ›Ò¾gÖ59õ}RæþàæIœ±ö…8.i_±5¥ËueNæGs]'R‚—Ö“Ò€/i_ò´ÿ®ÉüÅ}•_é_ò´ÿ®ÉüÅ}—@Hy¨ûT²u5û´Ây4½…´vª2k¼ø|Ëhšµóµ-Ä~ÿ1íùW•èß-"¹²¾ûGú€êÏž€xþUøYÕƒŠ•hÜçõ‚fgxíÕôz}+pLeHÃ)ïé]ïˆîaºº+k)ùœp£é\å¶PÈ£çž:ŠÆ”í£= vÊò‹ÔÉ.NíL)Ünâ+¤ñDõ£½(š\ Jr9MØ=F rÃJ½Ôä1Ú@Òç SFÃŒ\¢®Ê]éÊ»³‚={×T|s {纈6>êóŠÆºÓͼ›wAê+?i¢:þ¥V*óFiV<â‚×qcÁ‡5)„Ôs„p·FnÃAR*ñ‹úSZ,Óæ%áÚ)H:U–Ú¡ÛÅUÌ\z¥”¤phô¦@ •9šµóÄÀƒƒU1F)4˜Ž•â™-ˆÌ„+Ó´E2§ï×>™¯PÕÍ_µ½–ÕÃ*k)S] #6ª´ýj)ËøÔš†¯´,û†É$ðxo…¼_L"¹˜¨=2x¨¼qãµÔ!}/Msäô–e<7¨›Œž‡DjE+³+ÇÞ-jÛ"cö8 ïí\yn´1擹®ˆÅEYr›“»R÷4 \rj‰ô¤ô§cŠOJc/i_ò´ÿ®ÉüÅ}•_i?ò´ÿ®ÉüÅ}“H‹\sQÿ Jýi©€Ê1À¥#­'a@ µéš;OêÓ\г(TþóW›­vVZÓìm-¬íüû¥]ì\|¡¹9Ç·©¬ê|6;p:Tæ} [Á-ä„ýž8`_™sȰ7g“ššãY¿”Hn®<É$qü*3ØtÍTŠvtù¸ ×/+G±í#&bßÀ!¸t|š¦:Vî¡ln”8uì{ÖÒ¤ƒÁÕNWG‡‹¤éÔzhÄõ¥&¯iz=î¯r!´„±ÏÌç…_rk¹°ðŽ•¤ª\jr}¢t*§äéÞœ¦£¸PÂT­¬VÌ? øTjVï¨^‡‘œ=p}+¶»žÓJÒÔYƉŽ}?Ʊ¯<\ѧÙí#U òƒí\íÅåÍÜŒòÈ~nH 攥?CØ£xxÚ¾å›ÝjiË"·¥e2–;›$Óöò=©Ûxh¶ÜÞ¤F1Š6ã­LE5‡¦•ÊåH‰ÐãóªçÿýUcxÎV¢‘Iù”çý¥­#æsÔ³Õ²öªì0=ê}Äc>ÕËÅhŽ)ÚKB¼¥4ŽEM·å4›Gw9ÜHÂÓ‚É¥%UOsLÉ4ÈvCÕoº0;R1ÜÌOzm8÷¢Ä97¸© /jJbõ¥õ¤¥îhw4 QÔÐ0íIéN= 7Òô¡ÿkOúìŸÌWÙ5ñ¾“ÿ!kOúìŸÌWÙ øºNµðÔÔÔyùh(ì)3Fxª2@®™î>ɱÆó~øë´~5Ì«`ƒé]v˜–·šeËì”Cý֚΢½ŽÌ5E'ègÇi<°ý¢E(Â1œzS£@¨ ½óO¸Õ`ÔØ EÌs  Ž¹ÛŒÕmRX|æKi[ ùê+'ÝŽØU‚2w$’â1üYõÇ5”Ѭ—›;IÅMÊF¡ ‘ÈÆhMŒ~PÇè1UòìaZ¬jÛ™£­²ñU¶Ÿ§‹kKM€uìOãÍc_ê“êãÐUâbß1Ú=Z²°( íÏbI¥ìõ¸åŽºåèB­YHÙ—!ýJŒ#`1ÛÒ§…ž´8‘õ·Ñ<™ ÿTÿ÷É¥1J:Dÿ÷ÍY7 wãÖ –ùPrí.AýrK±^Fÿ¬;>£4n~YWóª—·¯påª Éã­R¤/¯Éô6JËèTE ÊÓ"³*NÖ#õ –oùèß>F†ñQ{¢iFæÉëê*0 ç‚}E.é›ïHOÖÎM=ˆo™Ý!¤’?/Z‚Q‡ã#о³OëW®t‰¡Ñ%¾1¤ªäõ=hçIŽXyJ ®š˜Š;ÑZžx´¾´”¾´v¤Í.x¤ =hîhïKë@¥M ¥îh}i=){RzP†“ÿ!kOúìŸÌWØõñÆ“ÿ!k?úìŸÌWÙ hø²Nµûµ$j?á Òö”v¢º ¶è53óßZÏ3õæ˜n ~´Ïá©$AZ‹øhž´vQØP@éE¥´ŸãKH(GZAÒœ:ŠJ4´ìs@ïõ¥ï@(ìiE/­3½!§ƒM=()M%)4'›íHX3GZ`¥Á N©"ùzŸSPh @4š.2±vâ}ˆP}í¢–ÝÜž¦« ÈNÞ¸êjЕPa’k6¬¬vBjSæoA.ØÈª+Ö¦žS&:àÔKÒ®*Èæ¯>ih-/94”½ÍQ€v¤Å/j1Þ€ÞŽæŠ_Z­/sH){šJOJu7Ò€5ü63âm,ÓÔ_ú¯³ñ_ø`ÅQ¥×Ü_ú¯³¨ðÔ„’ri‡îÓß­Gü4 LÑØRRöRŽ”‚”t @hqH(è¤(E¥½éz^ôQKëH.:Ó#Љº~55Dý!´¦ƒA¤0ïOVâ™J´ãMŠSH:Pz›€öïQö4zP5&¶+~N~”€ñB®Oµ;$)JìJ_Z6žÔ»O4Ä'j)p@¢ =i}h4ž´¢—¹¤½ÍƓҜzo¥mx_ŸéCþžâÿÐ…}_ø`ãÅQÿ§¸¿ô!_fæÏ†Ÿ­3øiïÖ™ü4 m( (ì(P:Q@é@%-%(ë@éJ:ҔĴ¸=}h­/zQA=héM'­¹¦·OÆ—½!é@Æž )4CH¢’”q¦Ž”¹¦Ž”§§áNUÉ ƒRŒSBaŠZ^(4Ĥõ¦æ—Öx¤Å¨¤1 ´´¾´”¦”RÉ = 7°§ž†˜GJlxlãÄšaÿ§¨¿ô!_fæ¾0ð÷"ÓOý=Eÿ¡ û34¿ZgðÔŽ9¦ GaE`sLÒÆŽÔ€zAÓñ¥õ¤ ¢ÒœŠNqLBަži˜ë@Ðç4ž´¸¤ÇZC½#tüiؤaÀúÐM”Ðh(¥£R”¸¡G€ž? ]Ý);QéLC·QºšEíÜRîäÓ)Þ´¹£4¨ Bçš;šNô½Í(¥îi¢ÎM˜{SÏCMô  =ã_ÓÏý<Çÿ¡ û35ñž…ÿ!Ý?þ¾#ÿÐ…}•Hh­ÿ_†üÀ4ßü_ð¤ÿ„+Âÿô/é¿ø ¿áE ?á ð·ý Úoþ/øRÂáSÿ2ö™ÿ€ËþQ@ ÿ7…?è]Ó?ð?ÂøA¼)ÿBî™ÿ€ËþQ@ü Þÿ¡wLÿÀeÿ OøA|)ÿBî™ÿ€ËþQ@ƒþ_ л¦à2ÿ…ð‚øSþ…Ý3ÿ—ü(¢‡ü ¾ÿ¡wLÿÀeÿ ?áð§ý ºgþ/øQE4ø‡þeÝ7ÿ×ü*3à? ÿл§ß…¢Š¤!§À^ÿ¡{Nÿ¿øÂGþeí?þüŠ(¤mðÿÂ?ô/Xß¡QŸ‡¾ÿ¡zÇþýÑE4Ä!øyáúìïÝ4ü<ð‡ý ö_÷ÅS¸ ?¼!ÿBý—ýðÆ›ÿ ëÁÿô/Ùÿß'üh¢‹ŒOøW>ÿ¡~Ïþù?ãM?<ùYþGüh¢¤Ÿ†þÿ §äƘ~x;?òµÿǿƊ)€‡á¯ƒ¿èkÿ4ü4ðoý-¿6ÿ( ? <ÿ@ oÍ¿Æü4ðoým¿ï¦ÿ( COÃ?Ÿù€ÛÿßOþ4ÓðËÁ¿ôƒþûþ*Š( >x7?òƒþþ?ÿGü+?ÿÐ ûøÿüUS¸XCðËÁ¿ô‡þþ?ÿMÿ…càßúCÿ$ÿ⨢•ÇbÖðçÂVº¼ðè°¬‘¸e%ÜàŽœŠô?-?¸?*(¤ÁÿÙtango-9.2.5a/doc/src/dance/Eltaita-reduc.jpg0000644023471100065110000032123113034745265015534 00000000000000ÿØÿàJFIFÈÈÿÛC     ÿÛC   ÿÀH7"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?øµ®LŠß>é €€`粩ãó:„HUJ®ì£<y9íYëpb••¸e)=Çlþ´ãt-Ô¹äz1Ú2HArN:ßMÏRÖ.™ÛqUf$a°Glc×§â* 6âà¸` Ç·çß•=f99p7’Hç±ãçð¨ä+µÉNTg÷àúŒËÚ‹õ I6È6VSÈËÉÇ8úñQ+ÌÒ¾èˆ@AB[§<`}=)A&8iùNÓ–=±ž1éïŠtŠ+2+÷ZBpOÓý:Õ^û……>d˜Çܱœþ÷ëïQH~lF§Œ ¤Œç:óÎ=±I·å9eTç#ÏÓ?Ë?Ê!Y‹Là.r~öìcò?•'p°¥Ê£Á`Á9í‘Ǧ\uãêà`¸dã&3»rórpyϱÇñÍD¨Ò`8Ú˜èzú}~™ú†@£÷³'‚N7cŽ?:`KµbpÃ"%l…%›ol’O9ãüâ“äpªcS°dØu뎟ãLó °pBŒåx9oåMK‡g ÁùAU$G'8;ŸÂ’‡–ÝÔŒòž£óÁþtà‡cÊðI>™ÏÓ½Dí€3"Œdã` z{AüÅ42핎äE9 ó1^9ç<óüéꀸ®íò¸ÇÊ>z*‘#+Æ»Šmܹƒý=j´wF&-Š Gœ{çCS:Èóv¹ÉTßùàççôW‰X´l¬r³1Üñ·|üØè3õõ³ŠGo=’0C#ãæÈ!Æ>œg=x¨bo”vª&6` Øz~4±ä¨RøÂyÆz~L©8,‘³`F”N¸ëÏSJdûBÏòýà\ägœ¯ÿª¥Ì«‚ÓŒ‚ rAÐóž;{ÕiÚ"Ã/óKýÖÇqÁ\)[ª<7$o)¹N8äóÇN~•%˺F Rvqž‚9ÉÏùãµ\…À;·oʇž£#޼àò*O1#¸ÙeÃ$` ޼qôéøT¾j4Xl»3¡ÆF=OOþµì RÞQó y`÷÷õzd ‘brÉ3;6;gyõäús]¤„+Ù˜0dÀê¼ü¡±Æs×Üã i;â',Tÿ .Tyíî?,Ð3@ÊNýí£q'»AҪʉlòÈwqóg§|ä Ü>¦v©W`’ìåð¸òOS×ðúR]Ì]¤oNG_Æ­=EbäŽarÊTŽø³œå×8>•!X•8e$úäögò?>*ª\« é·Ë*Ç%¶ƒÔ厾”§™wïrTNIÇL~“FÃ’ªžŠ Ÿ—Ž98éØ sœŠjùb=êTdåB²ä÷*;tÀôéO‘|©TQƒF¶7*w0*F:€ýwȨYÈ‹~ò1Î}=FGÓÿ¯KÔcÒpU€I9|u$tŽÜr?ýk‚‚=ÌJ€QX‚Ç·B8>½j®÷•ö¶íß!íãñ鎵#ÉÇòÆ@ #'# 3Œr~œýpG¨ì]F(˸(d œŒñ׎?Ï5K²Sƒå©Æ]Èãœý?ç½0\™P–fùA*]²FGПOóÑÒå¡À!°àö9ð={zÑ°Š²\4db&ó1ì:˜ƒ×¥RšÛÍ@à ÏÊëÛ×å÷>¾õzx\¶<°T ­Áà󞾇ôüjË"¼ÁÑÊŸËùqè>oÏñúQ~ãDbY&¿½Q²ü½ÿZŽ;ƒ+œä³‘·wþ`zgó=šò!þ\Œm9žÝ{ý)—y/ÎàvòïÛŽÞëÖ§aÜFA! ‚QRÍ’1Óœõ¦É"Œî8BH8õ<\úÓä¬8/挟›$íç±8íßõªï;¬ˆCˆÓqÇ£gß×½vv ùAù@À¹¨vî ¨öç¯R>Ôàÿ1' ƒ»*Ã#ðþ´„îˆÄääg¿¿çë±%,#LdAôÏãíÚŠ˜¡'︡Q×ÜqE' ¬ugvTŸâcÈÇN[_Ò«Åtúy|GöŠHr鸀èÊHÏ;†âAÎAŒV§‚6håhöºÉ?ÃǯLàUI”*nU]À¯ÈË×®AüÎik±¢`«"n!—ï/ËÔþ}ªQ’J£Ï7 ŽAÿõ{Š©Ÿ$©u;ˆÀd`2;¹ôÏåø[ 6xeÀf$œþ8ê}iß°X™‡Y ¢>ÕLEþÏÏ\äçêEEöµ€vq¹±Ó8Ç4ðIde˹l)S÷IÏaÁþ”›ãU Ä(ä);ûÜ V†Ï?žŠTnQ…`œÙÁõÇ8úštR ³*XŸ]¾Ÿ×ô¸X‹0@‘Àã'<}:úñùг«"x Ü@È'$ñâªý„Nµ£©m äŒ•çÓüñHì#ªF¯þ°dð:óÚ¢óD›\®Am¿9oÏê:ûQæ0•ÚE*Ÿ¼¹ÉôÀã'þù¡=N·ÑÆ@*\:øšq˜£—Q€A8öÿªòÈÙ´ž¬Ã'òÝi¥œÊ 8à€A8ð8ÏãBabÉ•d1’7ß+c9<Ÿ_ÿ]G";(b äŒ’G^;|ßäTBrW;@à½ÉàþKö_åb3Á㜞˜^ý?,Pì1²sÜf0ÉèG¶?¼{v¢9ã†]Ï cÐ) øsÐýsQ»y;B»Î6çn:('·CõÏ­J»èÀaÑYsÈ$äwûP´*³>âb°`üçŽÝxïÅL'8?˜«»9-Ÿ¯z¤^Ù䉈זèrOcúõ§‡BåfdÏÈ9õÀÀõà÷íÍÈ D…X‰`pËžÆà}?Jx(*Žc,Ä’1ëÏ^˜üÍR™ÔF^< ¸“9œzuöö©ƒ†@ãvÀ2Y\‘Œ‚}Ïÿ @µÉ‰t2»žâØÇ׎1Šdâ9%f “arpÃñüjšr[æš6æFÊžØ;Hç#×ðö’k}£!n;™w’zž‡·SÉã 9¡¥Ðb´ÏÍW c ƒƒ›“ÛŽƒÖ£-ç:1PKƒ»ø‰ã=ŽzJˆ:Z($ ÄNß™ºŸ®jÔç(êÀôüþt¯}ÂÅèU¼¼mÜx,TåpÎOÔþÊPí,Ûîa€bIÂóõ#ñ¨ëc8#{:ïÀÉÀÈäñõò(¹b¾P‡+æû£¯èA”ÖÅ(–.cXVó ÌIRçæFÒG½L·r0N:³NrxÎÎ*’Lá‘£‘ Irs‘Ôöãž>•©er¤âhw 8?›æÇóíÛ84¯arˆ¨ÌÁÛ µÞÏó äuüúÑ,‹u(ÚrHêOlû犑§…ã†5H€;bÈÜàv°3îqõ¨šù;¾ûsþÏ=:žÕu¸X†â‰¾Ó{‘J©ô'“ìIéH.w"7S$o'žH>àõ⥷¹g·”D6ÆÑœñ“ØŸéVèc”òŠÏ¸МäxbzŒ1À§q2o9ƒìum„œ2œ¨àÔ“ÍSå© 0qŒä}>‡·¥VÜg,¢2ê ev‘‚;{gùÓc™c‡Jùd´pNáMw5´‰ØLõR Œ€#®GOÖš—çÈýæX–( „ç;N:g¸èsQ³ìXÙœGÏ9#''§NžÕrÙ‰`Aç(H9㯯ÿ_Þ‡f…rÔêZ ÎSÕzŒ üîù«-Wïm8=ú߯áJ·d££¡e‘G-’F:ÅBÒrάAeÛß6{ñŽ{}sOAŠ„$f0«´mà1ù O=zÜÊ>T'úg߯åíPH>ðWn™Èã9ç>µ 9ûÄm8601Ï8ô©Z¢Ô¿$l&BôsÐϯlþT“Hª3Îí»°€@ÿçÖ«Gpÿ6Ç8$†hùnÙïìx¨ÔíåH8nñÏùΘ¦'ÁøI#d8G— ê:c­\Šg?!g.ó%,Ý8úöéÐVx“Ëge*CdÓOÈŸo•26•eaÛiàcÿÕëI$4úæÌhÁ™a°ªØ98éþzÕiþq•Ã(bN:óÚšn#p»¶žNxž½HëÁ=sÒ‘\cɼÔsêzzw4=Çq«½Xª¹È^£×žžä“úP]¥•Ã1É=sßÜûÓº©Ë“ü\à^ÊÄ·˜GQÆÓ€qÞB.,Ĥ€Û½ Éàÿ*‰$„o-P·ÊF:g­uÜüdÆHÈÎ{ÿD>\üÛ:ã/ü¿Î)ÜDë!Y n€‚Së×úþ•)“amÙr0yƒÎ}8©°’¤ÿä÷ú}3NIAaŽI8ô>¿_óœ —üä‘Ù‘ZEf,Ê£ï`Û¿ŽÔ[]¨>f]c ¼b«ÃxÀª,¸éŒŒJd ßòÜö&’ šÐß¡ Ç{1ƒž;qÜž}±V$ºMêY•¤yU`¸ÈÏÓ?½sÆà‰„?ìà{ôühŠä¢Š2y?ÄNßð¦;$R!caœ îgž3Ïz•°hŠÛ¹$°à==ñÿÖã†÷Ëí-‚yÇ#úñW†¬Î™Q݉<ç“ÇÓëþïaÝ3FTFòB«!ˆƒÜ0IÏ$ÓC¤ ºüœõÀìFG\VqÕEeÉ|ýì¯__Ö«Év8ÚÇ<’à ÎqÔÒ¸îiHä¦Ó!U˜ÛÃQÓ=sïÖ­ÅpŠw*2ä‚­ž:õëןÔ×>n£ænHÁ'ŒõëþsRC{"‚p;p8ãøþ´yÍÒî‡.ɼޏ%ÂŽOáÏ×ó­<%)`žp£¯#ÛÒ¡‹P"™#ˆc§ÝÇRGN?Ÿ|ÓÖéc$²•ä0ÏÞçŸÿWaéEûŽÃ. X¼ÆPy$©ïè}:Ϋ¼Ñ(˯ÉëÜäûóŸÒœò¤»‹Ç哯ó“œ~‚ª¼ƒ{JX°9,vþ\~h-‰$r îS†q”dävrzd h`»s|§p*r¦¤ÈcC÷ä w€ëÏ^0~‡¥0•:…ܦNÄÿ“î2¶ŒPN\ÏÝTÝFz‘ëJÙW*5,  `g?Ê¢c˜[;Lç¿ùþ”ÝûŽà 3ÿ×Ïõ¡\’T¿û€ÆS¸öëÇøQPÉfÈÞp8èh .u~xQ¸‚ÙwÄz“ëŽâ¦ß«òchaò†<`ó‘íøtïUDxü½Ãs‘µ‡Ë’=sÎ?úÔÉ(ŽÝ\n)å?„àÿJ†tص(ó!‚ðÆG9÷?Ó=ª|ðF?(çò>¸õâ¤yädÁå ôãŽ?.£ñlòtP |OCž@íùŽŸ¥®¢¶‚D[ÎÞr¹o›Ðõ\ô†C!O/vÍœ>F þèçøÔ‘’1œ’áþnÃãÐÌàPXù»œïË»n8õ#Ÿñ¡j+•ÙY œ4kÆÓóÓ¿8úc§¯²”‚Àmù¹É>ƒ=ÈúUƒv ͕ݼmÏ¡È9ϽA4‹ÎÙLî:¡â«N Ç½Ææ%W#< ØÏ®=ÿ‰&+œ0;zà‘œ {ÿQÛÔ;ÈTV $`wnSÁƒ<ô§Ü@Þ£(È{‰ô£VHá ˜»p9·?ž>oÄPåhb»”¶@äñì3øgëQ€±û°è¼€ü/9Çc޾¿ýgýÔ C6ãœnÊÿõóþzfšVPÁøè0G§aÀç ¤2à€wœu žzrxê*œS²"(Á˜`‚ ñ¨Áö<ô§,‰æïÚ¿0À¹ ÜŽ}qü© TÈèÜc'¹Ç|çüóQ´ò*c!”t1àsŒtõëÖ¡/òŒ1ŽpøÎ}sùÓÞœd/¨g 0·?™ÿõÑpŽâ,Ê<ÑŽdÉ##¨õϧ+¹¤O5c@>û‘’yÿJ¯¬ßÛÜÜÉml¬ã¦ Ù¸Ž„¶x¸öù¤&Ke4L Ä­ædd²àB ÿŸzÒ)F ÏÚFhgÔçÛŸ°®e8¥2óznpŒÜwÿ= k¢°Íº(ÆXŒç9'ê{{c½]Éi–¡´Žê,G2†#r¶I¡ǯ?†+*úÆ[Ev’=©¸aTtן¯¶=ërÂþÏìΦÜ<Áø`Ù ç=I=úZÔ‰-õ8 »Ý•f9;NpHì_SÒ­JÆmxná*Ê-´•‡¡õäþUBƒ.ÌFr99Çâ9½½y­-gM{+—\˜2±\äcàñü½ë ³ »OPyûûÓ!èY’¬wF½ŒãŸSGÚ€®bÊþyª«.Ò£rå±×ÿ<~´ñ&Ñò–ìFóÌöªdÒ0•R5Ü[§$œõã'¡¨¥]„©P;ä¶côùÀÃñÀ`þU‚A ‡—è)…Ø™V é gøcòõ¥'“€O\sŸÒ¤XÁ8PçýÓÈ÷éÏ?ç½F-ó‚Ý7 ޽ñøãü(ØVlC(R¼3!'‘Àõíþy¡áâ;•>Ǩôëšv˜¹ìzzçüõq²`Ä çïð .‚ÌoÚ7&Fî9 cðïÐPfé‚T‚xÛŸÿWOçOûÞ –%A%_‚28Ç^Ã=?„úSÒ͸*C8衈íÁÏCÿÖ¢ú‚‹+ä¸=:a?1ÿõç¥' ýÜg“Ï×·­[û3Èø*Å—#éÉÉéÛµ!·;רÈb¨9àtÏùÈ¥ÌW# HÜàîܸÁÍ1"v-´ƒ´08õ ‘n‘Œ’Fw“¸?åǽNºo€¯Œó–ÈãñÏëÇ~”¹®>Fb˜ËgæÝ‘“‚;}p=((B’@!F%Gùâ¶RË~7©òÎ>£¿·ëÞ¡’ÄÊ—gl}Ü€8üúÿ’s!—·$«áSv3èGó㸧Bä¿.GP¯½h h–U<‘¦Ò¬Ê›˜z`dqœ~g­Rš*T€FW8'éÓ×ÜÓ¹.-çÍRìª7g#=‡|ÇùÔd lޏuãü:Š™ãa´”UÏ?/¯ëMH‰Ý’0=®9ïÿת¹ Œü¡X¼¹4ó n;Šûp? ™ ,Ì_Q÷±_o§¥ lB3bBçf2@>ßçô¥q¨²°l±U*Žx§Qž™âž[jÇO$¨?‘ÿ8©Ä? `‹€pXd€~¤uÿëñH—à†/…ÚÀóÖ•Ñ\¥ucŽpÀcå\Œõý¿‘=:1œüêä0{AÒ¬Ç*ÀÞW,sÀúcÜR5»î!rr0C‘éÇ?þ¾Ý‚¸r²¬W0Û>ë =†?ýtô¼|’¿tÿrÓ¡©D|.ð­×qôúz{ûõ¦µ±† ʸ'p?JwšîËdn ¨Ã ÙÇùõ¨C¿~¯ úÿ*±ä4Û–0›PnÄ`ŸÿWnþ¿Š›}¥ˆþÏ#ù~^ôîM™YdÁaó¤®1Ó¿\ÿZPYÔ‘ó0=ÇçÿÖ©þÌvÅ‘Éüýiℇ.YˆÉ^=@ƒÔöéÅ++—¹*‹Ç ýúâ£h˜|óÓiã®j÷Ù ùo– žØ =ûtúÔ¿eËgj’HëótÆr{ý?3Sqò”â¶wp€¶á× ¸ zŒþ”UøâF Œá‘‘øqǯÿ¨¡Ý–•‹ v3˜‚Ãnlà㎆žÛbnI$`±Lcv8=‡ùéTå´^2@TåTüÃò§J<èƒ(d çGµBÔм¬£l‘ýã醞‡=°ÝýO^ÌâW “¸Ê€îN¼u÷ç¶`Y7°ó$b„®@9Çœzp8•/Ú3,¸¶@e{úŽ;ƒŸj[ yFÂÌxÀÈ'ƒüù¨L…q°´„vÉêϤkµN gŒ’]Âã<Æ}/qP k«*¸ÜAê1LS¸Y1þjÉ,aÎ[ C÷ŽÞ‡ó©‹gÌ`ÄgŒ£ž9èxïÓÒ©•$nòØ€ÛrÜôç¿o^Þôé%ÇÊFð£q8ÁÈöúŸéT@¬Là á·l'žÚ•Á·XY˜¯Ë½Föÿ&†ì†µe½EºÕ GjÄ㠿ݧ¯^HüûVÖš;²Hº3uÃîþYþ•¡5Ïü!ñD ˆùˆYWŽ8Éî:¨ãÿ­\¤ú“Ý]K$ìd ÅÀõc1éÉÿ V7rØÙ$‰®.SÊ(ýç“Û¡?§v'½dÍÏÞ屃ëÛ£;¬,÷Ì—oÛîŸÀsÈ5–fig%Ã+’ ¼ }:uâ´rdúÚÚ›¢ 2ÇÜAÆ1Çõêõ½« @ ‚¹$Nœúã¦zþMÑíçP‰$qÝÕ˜z)9üÆ+{S·2’`‰0ƒn^úu¬g+HÖ XØÐæ¶´Óns)9c³‚Þ3Œg¯·áŠâ¼IªµÖ¥2FÛ‘IRËòñ“ýsúUÛÙgH˜d"$ƒÎr;gž0âQË<1¥GyåÈè!\‡àŽüõç£îÞLsWÑðluŽÐŠäAÎ;ãõÁçèk¥×ì 2\“†d È<œäç=:ô5>“me¦ê?j{8°2À²Ž8猎þõŸâýz×[¼µ‚ÚÕmíQÌsÜÇמ8Ÿ½+‰i¢ ðFª4©µUéÎȈNø%¿zã¹÷Ä~*±ŽÆ`›Z&” J^žçÿ¯Y°Cii©©e_²!8gBÀîdþµkjWð_›¦ÿ‡ù±‚ÈùOò>õ7÷®]¬Š6f´3ír0 äIÆâ½xÈüjëøXiº9v‰>ÐΖoº QÆ9éß=+¦ð¼vÓE-œ™'Œ€ ÏN‡×¶Et7> òÈdEŽ(þe‰9È9©<óëô©æ“mݬxƧc$p›‰eV‘‰à7ƒŽ¸þ•f;ÊåˆçºôçÚ¯xŸW¸Õõk¹˜m…°5P€yÚ:k.5v Vaœ¤dcœ­vÅY+œr•Ý‘³¡jKá\e$È!<ã×·Óò=xhFé­Dð ÎÎ8êO~õç–Çç¼·AŽOÿ_ó­½—à; È`ÙÜqœsøŒûç"”‘¤ÎÿP³¦ž’É Å6ßõR Áúõî ñÆ+ƒ¼€Ã,‹å )<©ÈëŒ~uÐ GPtˆErñ}Ø$)ä/#§?Zdz ¼œý¢?1´Š¾àG½IÉ©zlknç2nƒ’Ò2OóïNXÙÑåSò)ãŽÄ~˜üñôìµ ¬&?/ „VÀaÜ çœôÿ Ç›K’Ý ¬{/ÌIõùHî8nÞ´Ô‰QF$¶Æ(Ë0U >lò:ñõÒ¥ûØžž™µîmŽ^ 7*’@ƒó•r›¤Ã@˜(ƘRÜÑö²…uòôêÏ~žÕfnüð£~vätïžÿ0éÏ8¨ÙÞ2‹±I AbÀöôôà¿ÅíRÍÄH P70#¨ùþ½…;ÛPØ®–ávDÄÈv¿‹''‘ëœñßÒ§‚H¶Sî>3ÆF9=9î(ŠEóÜJíÂ)èC~?äÒq•‘Ðð@í×> uõëKqØ~ö0ÞWÊÜíêsÜóøÓ&“~ÔP¬Ã޹¸=F?ȲFZ`£ ÷äŽ Ó¯'§gbÊB¬Kò˜¼8Çóý=¨nú€íP±† úyïëŠb¹Q ÃWnéŒð­ìI#ŠFx[vÓ±’z~?Ïެϣ$å¯ÊdoT’ÀrÊ=üÇÖÚ‹$BY6‘–èÀòÙã'ß¡ªW빤fG|úGZë›Â2ȼ^b3ùYø²I ƒ×Û'Þ¦¥á{‹ ÞBˆeÂ’å9On9ôê;O:zu­¹Ì=Š Ã0`¸럥fÑJHBPw;rúÜv?ÔVÅÜ hTO„x2Ë‚?w‚G¨Ÿí{ÕÚÓ ¨ÉÛÁ,FxQǦ;úûU¢+ýœÆª~]¯ÑÉ÷8÷ý %mÀc…Æ~m§ž3ü³ùS¥v%Ûµ‹c=ˆR3“ôÜzu§Zà[Ãæ›ƒ»X þ‡`A²& FÖCŽ>oÀÿ“žiÍ qÈm¡êGׯ·åNÞêÀ†û;» åó“ÇCþqHñ¢Üf6Ü]Nô?‡^)lX‘Á¾5SÎæÛÁÁwÜ–=û} Et>_¸Ï\“÷ž wôr÷1±qgÀ<{uûÇ>ÇÚž‘4be‘€ÎrHÁÇ÷üý©_PhŠÚ/;{?*2€cžƒÓ9Ö‘pð #H9 x>1ÓÝ?5 ±‚sÄ’À¿ÃÏ×üh!¸ÿR¹ nÜG§?ãO¢!HTn 8=1×ëíF6£ª¦Ütß‚½}Ç=éõ§«  ¨,O8?×µFª’4¯·i9<ç=sùΚµÁ‚`+`‡vaÎ8Àú±î$cÆ<B‚9~ðÿ#¥6&’wÈsò2€rùzuôî>¡euD?ïlp70:qÀð -qÎ<µ#yó n##°äd~Ñ¢+¶[vì1À=ÿzÿZ† 32˜<¬ ùŒûçŸNßZ± ¤H’db§ £§Qùv¡°HŠPÌ7. ‘”Uϯ=ò:ÑK2$rÅ”c'Ÿ¢ö…וòT· .HþŸçß´²\IeÁn ÉôÀçùÖyœ°$íçŽ~ñÏzS0$CdIÇ?çò¢ÁÎ_39¸çp=>¹ü»})ZQ.⑳m\ü¤•ú“ž¨¬÷”…êYza°sךiË ³&~ðÊ’G×8¢Ãç.¬ÛFÒ±8ïÛüi’`DARÃvF}¯µVóU¯÷HäÇôþtá"ìÚà–\îô>çüö¡"yï¹+Ì<­ÐÄóéïþy÷¤2Cm`Ùrr{ŸçPÖ8w?LgüOãÚ“©eq$®a5”ËlŒ"ó#™XGpä¬p>¼þUÛ[i3Ç`$dF™ùœœIÎ; Ž€vëžpjÛhqéñ¶ÎVhŽIîÚ ‰ì1ß×ðÒµÓd¹Ó|ÛùZuù¶.1•Áà’9韩®ohå¥Í’<÷Y`òÀÞ¥ÎÐ8<óרžx§hVIu+ƒ‰° pAØñ“ô5PõÇ0Fñ«‘ª±÷ýN¿J’ÎÖîÞФA„ÎÁr¥‰<Œûñ×~µízÜ«} ú”W,cxí­Û Á~ñÇÍÛ#·¨ü*”:bé6ßlþêmÑbHr@''ƒŠô}wO‹KðÜzh„ ™âóÁÁUc‘“ÁÉöõ5Ã]½Ó@ºvó, '±`HÈ‚Gþ½B|×HWº/^èáì¬ïaLB0¤ò½1Çaž™÷¬½-c³ÖVÞGŒ-ÁÀ2œ(#¨$’sÛò«ë Õ›B°£$‚0pyç_Ö–çJc§5ÙËì¾n@ Œ‘’zg'œŒÛ4EèÆÎÊ/Jöb8X«Ã4r¤¹ùY‡8üNOP3Œ×K¬A}¦CÜÊÍç(O0•^„’xp:`œ©ª~Ö/˜–·Ä0òCG½½uóôbI9y˜ö~ŸUÔ#·†"|Ç ÷@î~œþB‹½7þ&óX!. êÁNÑŽ¹9ëíÚ½'Eðëèú¼Í£´‹ó°^zò9Á?¡î2ñ7C]L»»`ZyæØ>Hp1Ær?ïž5÷/DÏ0Ó59 ¿p²™v3²ƒXg·Óòöç©‚äÁI Ь™Ã6ÝÀϧsþ}yÈÒÖ+GŽ;?Þ3l2³“»¯ }sŸóÉÐðŸˆSEÖ<»Ë/:7&0ePáI㑟óß­k~ÂÛs^ÏÆïÒ[]BdFfÜŠy´ƒ“žùöí]$÷úN¯f‘Eå¬À±HÎT“Ô‘Øç¯ñcã­`xâæÄ\)²XVLrÄ ‡à‘ŒéøÇŸ³×™<¸äÝ€n ¥I‘êz ïÏ­JM\7'»³hYÑdYlb'ܽ2OoJ®-˜F¬<Ää—ë’ÝÎ#è9éï]â~Å/™ü¥ ìTe8år ïïé\ûD«rbÚB¨V Äsœã¯éÏ<>kè4:9|³Ëì”À…<ò0AÇÐÿúÅBÅC¡,ÝTnóœϰç¾iJ!V`wòðsÇLõ>¤÷ïÔSÙKE÷ÛvK¸ðIì:ÇoÄrij´†„òÔ°FÝÇzôäzsíß41˜³02g.g>»ãrଌªNÒÙlvúsß¿>• ¸¹ž%^pÛò ÷ïß·>”^ÊÃØ²L@‰’K)ÏÐ ãŸþ·JŽW@$¸ÜÃï.@<óoדÀí=͸™ZuÙ³P!Oàr?Z¡,¢@€•.vƒ“ø~g#×Þ•ú ’)Õ]– rr rq@ÏÓõõQ‘X"EÌpù À¶;ñúÔ°û¥Yxݹ /QÏ<××ùVLó³JÌßêÏ IëNµI\‰;ŸÚ¦áâG mqц@Ï~µ æ¬×H¨GÊAìÀãpò?§ãY¾`B¡zpLš|>`b[€?O×9ªåF<펚[‰ã1ÊU8 • } ã˵_OÉ ñ¼‰¶h°VH”g\ý(`”x°Ï?þª~Fq d®0p/ñ© y1øöÏn½êÎTŠž^{ëNEù~P;§=úõa•öîdòÉŒ[ÜcéŽh` 9lŸ^¤ò3ßëþ{b‰·¨,êF1޽ÿ_ÿU65,åƒßñç¯áSí vº”ÆA9î,tô© ‹31*¡·†“ë“Óð ,W(BާqÜúgéGK0 Gl ý¿¯øÌ¹.ŒncþçÖ²žpÌÄqƒ–íÏõë@ìWòÔ®;ŽI ã©?_ZxŒä†\Ë`ôÿ­Û°õ«*©þ&'>ÿ•+/”ÊÌ…rÆ0}Góâ–Áa©Wh,»FAqëÁÏ5džÚO–zg·¯ùúÓü‘Èw’˼rOó¥Ê¶#Æ'p$sÒŽŽ4 D|ôÊÇ·ùft'fâÊG;y9Áì:þžù¨#Y;˜ «g°=G·®*ý—™‰©‘Ñ”l!¾‡9ýjššÅ\I [Û41Û™9'hääŸûë·ó¨¬õ¼æ’I#§8ONÞüÓîíæ1Û0…ä’pÍ€¥˜àñŸóßÖº¯h’Y­½ÜÑbs±á¿9ôã•ì®iÔ‚ë@:}õ­”RÅ<ØÌ»åSŽŸ{žÙúŽ+¨MõE‚ß”D”3 !¹Î9ü1ÏZØÐl¢²’ëRÔU¥¿¶À‹6óüL28 Ž+CÃ~º¿½…•ÄM)1œmN¥¶€üùõ¬sú Ï–$z†œ5««;—dxDdd` n9=G{ÔõËñ­·‡¤eªw9gv9%Ny\sÇ@G¶Õ®ì´+ °´Jìç÷Pcyn26Tå²xçÔÖw†ü&ú¦­&¯}Õ1ñdçªúþ>¾æ‰ûÎÖ3ƒåWeMÁbY>×|X ,T0ó»;NÑ€óUµÝ[‹Å³Ùötd(3µF 2óÏ'ÎwW×V: ³G"½Ëܰ¤ »63È㟘à`ãù×}FÂK¹š5ŹÏï_œ÷#©íÏoZ¨ÓV»%ÔwØÂÓ>Cq±°™F åò»X‘ÊúØúŒŽ ohþ>ÕÑ:……FÒkî¤ôÁÏá€.µñÞ¦[\ÃlâkÌõhƒœ`çº9œžk¸ñ–­4ï§ÙA Õ.‘çVi#µQ€x ¸ç§\‹åŠ÷ȼޅ‰òÚè:|ìÒ/Ûç=¨A ¿@qÐãŽëÏN<‡K”j:ªP|À©È dç½løÚÆöïY‚ä2¼lTÌC–¸½³Ô¸—@Ò¦K°$Ée]¤ÈŒÆ#޽ÏjI(£ª*ËS§Ô´9m´ vÄ2o>fæ2&3‡ûǃÈã9­3KÝmmnÃ÷÷YfF\äÑžùÎr/i6â»h¶yUòI!Ôlñ×§QÇ‚»¦ðl–š[Μ|îÍa2sósÔäž1ÎOµd¢Û²ØÊS²ZêKáŸEqႦ?5–/nÀv°Êƒ“Ï<Ðg§'Æï|ý¥¨y¶²ü†R’ùluÏq×püýz{†—4Ö¾Ž„Ø‘¶I|!‡_U¨ü qzeܺ%ãÞ42Oi!Ü0»J :öàqŒzs¿"…•ìc KV=ñ—uáPÅ=™s#+‚ÛpNÒOÍןL梱º·ñ0V¯ö‚ FWÔçà¦Ú½ñJ?´_ÇuIÄm÷ÒL’@^WÔƒÓ½yœZ½Î—âÔ-¥t‘Y «¼pOÌÁ ¹ctm¤ ŒãdŒ~]…DcИ«Ýžƒ§ø ÒÚÂâêå„1®v’› …‚zõì@ï×Ã5ùQuÛ†¶p«¬ŠÙ) Ïôã·5é^/ø†ú–†¾B¬iqçrs“°3ž¼v=«ÉÑK¢J†%ú''>½¯Öµ¦¬)srêjiöÆÿ;ÙžUù˜9õöééÇJ³y¤ÊÖÐ?–ñùyÊrÊåÎ Ç'qéÓ[ÚfŠ-ÒÛgß $@ò™’‡_Oq½a¦‰¦!QÖŠË©dIôêO=qIÊÎæ©+Xʱ†a ü©3Á>\ d“Á=ÏZ;xÂ,b"›’r <“Èç>üv®§[³m`‡|ü óO.qÏÒ¹;Ûsk6K•ÈC=OõïJ:«r¢¯˜Ä»µ°Á°Ã·<:ž¿ˆ’\€Xp ?Ä09Ç<~µ`¨òó7Ë"ÅwcŸ–* Á¸û!]Ãh-ÈÈðäàúf§™=‹±L>âÌÊ_”dgœûúôúQ‹©X¬*èB óÏÒ¤˜,y•Ãï ²¦Ð¤qœtÏ@=E;KÓÚbÒ܆aó¹Wœ àþE>—°Y¿ÉW’bܶÀ}xö®BÐãMçU¾·$E’0ÎH,Tç¿'uÏûC44ÙaŽ{µŒË òYWÉÆçÛ üG®k¸ñ%²­ðu½ºÅþ”’Ë;^L–9]¼®Ù=f$–ã–­Fšr’±å÷aå–RÌCH¥ö°ù¹=§ÿZ²áµ$6y8åƒt'éþ{vÖ¥ï.6ì*dc‘^ÜóU´ïÞù€W Î2G~¹çÿ­ŠìŒ¬ˆ”/o™›¦Éuq€ œ+1ö#ž~µÔê‡Kðúji1žãpC«d€;ƒœ÷çÅfÊ$ŠÎY#“å.Tä ·ùëžµÙÛ[Ãiðõ–öhæ¸Ô(XÙ¡Ú3ó‚r £-Ç46Û"Ê; „…§[˜Ô¤|ªû窞££t#¯ ®²ÆØ^C²Vß €33Æxxïsצsé\Ï… …¯¢ŠWužhûƒâ™ùBœ`Ïøúæ‡m.¼â)ŒñMq¤¢ßA)GÁR) À{c95çÆºÚ[­Š­KÚ+Å_Ä…Wú~“1¶·”y²)‰‘S;IŽ;ž àäz\5ŸÄëGMŸGñäwWâÔ,u[{sö¨7gËŠu÷‹‚‡p°ƒ‰Í}Ï¥i–þ+¶·½šîÚâØ”Es +ÇŠ0[øGÌ2¤}>gøÙð°i^#7ØÀènVÉ[lŒW;ÑŽ7n,G ÷ˆÎ4AÅhÎ(Ô»å–çÌ>"ðÚA©¼ºd‹qñ¼N¬$ž2NzxúžkwÂ~+°±º[{ý&Ýîd\¥w·pIã,1Ç'ƒ‚sÓ5>©¤Íá¿>Ÿ¨ÉçÙÌVå@+†Q´¡é€Xdãhäõ5õOMsa!VŠK‹S½Š‰¶8àguànÆA=Í­3}±×Or·ìilð˜w*3 7)à•;¹Ç±œòy®bûB±a[«‹F~Ö{FeÏå`Ä qÉüz«áÛÝc×kgÇ›¨%Ko5š>q‚·Ô]›Ù¯‹me¹··ŠÚx†Û˜!VP_=z“Î<}ßjväÒä[‘œ©à=SN40ÅsÈ&·”s½G9’ÇbHæ&FŠ@’ÄÞbýäÚwèGåÏøW¥ýªûÃ^M…ßä¸2DÆ<gk@ç9?’uó8ç ÆqÓÞ•ÿzG'aù—'èÓ#×õª¹6 hÙÁ- ;Àfà±Æ8î=zäsÇi¼ž³'q 7ŽøüG_Zcp,Äd#nI d§©ïÏ4ô3$®>R~]ÅO?/$çßž9ïU£"ÖbJO(©ÏúÉ09à _×¥D­ÝàpTärr:öìãÏJ}Ä€DcF( ‚¼—§Õ—+>æW^8w ß^€dŒ¨ªÊ®WŸ”! õëÇ#8ÿëú”ÈåUœócæØùsÜ´TÙå¸aœw a‚0ã™ÈéÎ?¯­);ñ½rG<6GZk 8?(çGltlr¢|ˆ0Ï=?¯åMyÚø 7 ™0sÛú ]À˜'ǵ?º:³ëÿëý(â…Vb1ŒôÏ\þ´É&£WS¡F8õÁý:М‚ÝõéKó~í†Pót'ŽÞ´ºçr0 ³¹Îxü?:l{UÏUaò©^9ôÿ=ªY¼j퀫´íä_ΣeU‘¸ŒFq×Ó¯Ö˜1á¼Ç@¨aòì: ~´Éee`¹ê~eùy=;äçCÎÈU‚ÈažG'òýiÊø‘$CþéÈ=½súZ¡qc–T<Œ óêô˜WI þFà;ñþ{R†ÚØR†Üqùþ4@]ÛkŒ¤  }ÓßRÊÜÒ¶Ó¤h%‘Ø;F„`7ï·üö¨¬.ÞËOš_Þ<Îà&ðOËœ/×Öh6\i3 u2ã!KàŸ»ÓŽN[¦GQÏßP–ÆÚÅÀÄ‚{½¹ïíŽhjš‹ßJ¨ÒM²1•PøéÆsÛ·8ôQ¤mmÑ·go¦[Ù©‡Ï»MB誻ÌÅ]à ôãëšO|V] E§éÈ’–Úv7nõß´õèGÿ¬D†ÂÁ¼Ëö¶M¸ eìAöÇ=* Ã7:¹šK7 ŒHäg`uõÇ>ß…TUÛ*êiCã[‹I¦k‹§»¸b<ƕ˕ààžœ÷ééT_Äú†¦&²¶Ê«Œ’Ù ýzÿõ«S\𵞖OÚg<Xç<Œzþ••—%òÉå¢[FTî‘7oä`rç“r+K(±«4kÐØÜ$vçÌ`Ø.FíìŽHÆzþ#ƒ·à[XÂ÷Ww3C±| G“•Q‘´“¸ƒ’¿QÓœWC¢Çm$W1ÆrÄ1㎜Ï8÷'­iÁã#s{ ¾åŽõH¡•N ð=ò:sž:ÒZ QæZ(ðÕÍÞ­§‰åV$<²&pO å‚>¹ã“§¥h]x}ôˆí¯dm­¦‰W“Îâ8ÉôàŠµ¡Å²úÊKÆß-Ør¿4kÂý23×õ«+ÕΧ|¡”X؉DÆð¥¾`èAëÖ“ZsóKšÈÜÐ5_ ØZj%¶Ç/˜®Š«ÀŒvíHÏaW¼Cñ9n­¦2©Ë³aIGBî¹Ü1ùc /Ÿjú¬—¾ \´vñÊ»Þ5fØŒA‡œ«qœõ¯<ÄóÌÒ2C…;‰bTõëëÇ~N)Jn1²4…7vwš¿´G¹Ž&ÏúÐ@ÉÜ=Aç?†+´Òôí?‡vîÐ7Ú£*ª$fdrzcŸcÚ¼V¸Õ%¶2¥œ}ö,¡nzCqê{ ×½x>Þ]CG6è¼-™%•¶FFy8ü} qÕ«ËnceG¢<+UÍÝÏÙ–Tó£`»O¯¶zú×/âo Þ[Äfû/”%\¨TppsÀãþ"½ÇÂ? îþ#üKžÚÎÞRˆÉ  r¢÷Û׌ׯü[ýš›CÒVó¦ÚTGò©gr Á8þY=«‹„g#®4tw>Lð·ŠLZ+YÞtÙË,«»îç#qÇýÐWâ6Sqå#‰1€Ÿˆ9Åjê éwbÊ£cBçw8È#Ô(ÁϦ r—·ŒîX««6H-@ö:¸êCÞÕRJ¸ñw$–élÄù,8Cœ õô8éõ©o´á§Ý¬…³¨¯AÔpqì1Ÿö«>Y„§(¬Ã«2/Äþu³¼jZd6ÿ3M®:/TôiŽ>òhÝðΰ–÷ w?“>KGŽŒÀÆ}9üN:×$‹ raˆ°`ÀíÀH8jò† ¦$ Ws/ñž2'gž{ 'ÄeÒîÚ5V±Ï# tü2Ï1-u‰µÍQµ ¿j @|”UÈ ˜ÇCžr=)¶¾ºÖL—BÙÆ´’Ýà{c$cçÒ™àm&÷Åzôv¢”®o¯eÀKxƒ©bIíN2OÖ½’KKQ¶ðÕµš¥œ!dšv#sFŒ~ñBäsØgœ×4æá¡-¤ôSØqßÒµ›÷XìSÓ×Ìžù@ M ]Aùy‘ïòŸÊ½3XsàyP>Ë+p|¡UWŒ8Ç^8ϩϦY²x’X%ŽSÒ…Îܨ*rNqÓ=Ϩ®ëH‚}WÂî +tDÀIJe\ß‘ótñלWŸ^¥š5Q<ªÎ)fyÄxaóùdŒœîã?†GàjŽC0W.Ìç¿P{Œ‚+©ðÞœ÷ RK¼€œ2rÇ߻ֱ"Œ[jr5B#¡¸#¯“ïùvæ»c+¶KŽÅËX#¼ðíÂ>幎Y2©…àŽ=ÉäÕ¡%½·…%‚@“Ï#,‘3`¼x¡í‘Øâ®hÇm6± î’?”ò(à‚Ň`@*Ccžqè'®+U+œÒÑêsÒö§ï ʆaO£p{d{qšúçC»ñVl²yvšÅŒ‘‹hn”Æ]#R<–,ܱFÐ×…øcN“IÕá·0 ˜ÝÕðà“œ¬}û{ŸÀWÓú]—öŭލ’[³Hq¸#ÌÒFG~q•ï‘‹²šiõ9jÉŦŒíÆ×Qð×ËEy l’)Wç Ü9ïŒgœëÏLÚ›:£¥i:Œ&yqgpKÑ\! rrrCÛÖ¸ªáãz£HVÓÈô¯1®“m¬é7R¡3@ ™–]ÑÃ(fá3À,X7Ê9ÃrzWcã?¯Ž´Ç²¼Ž8u !o ˆUYg^våÚ àc$18Ç>Ko¯Aám_û H|ÿ=‚A.ГDÁ‹eH'Ÿ›p׊õÝ3\¹ñf•>³k(P²»y%†PX «¸¸'Àñ»¨ªr±ÇU¶ùÏ„<_¤Ü^MªègM'QÒ ÷VÛ'hÁAÏÍ„ã<98ÅIàɬõRkx|³Z‘$@±VR0Ý>ïC^×ûFx%´ßAã]&eCu$ójV%0Yf8~p0ªL{Iã‰Ço™òOøÇÌ·F† ¤FMŒUHÜaŽrA8篭wFÎ×[EóÇBiSXk¬ÿ¥ÛÞ•iÖ=ªa ÀüØê:u…®›Aºû&£(#–+Ä"fUË,IÎ6Ž:Ž ®’çÃñkúRj­, ÀÛÍ´ªÞSºÑW>`f'=ð:f¼ëNÖŸIÕ#†'Ê%Ä…·°^sŽ„“ƒÓ¸ëɢܺ4hýôhx³EYZóK7m3²[JÒä ߤãŽOaÐ}k™—VÚ_M1ý—jý¤eJí$a—<N1Ó¾y­IõH®ü/§k 5»ÆdIc,¢«²Ç»nNŸÔg›ñ> º…Ük’ï Rý2@=G¡Áç98´FÖ* ìÌMüñÜCû¼³€¸mütž8{äÖ$p<'eŒ¨$ùj½©5rfÝ0 V(Çp¯©ãŸ­A=ËMµ¸wÆÕè:ð„ìv(éb”À)>[XgŽ#$NçÛ4–²cS± €’/ÍÐO=08ÿëÓæ‘%A€ÐçoîÀQ€ ÿ—ä8î‘“µ‰mŒã tõÆx÷ÁéZÜ–F°µà‡cùFF d|¨è:°ç׿¯½1äFŠ&÷2ùM¸Ççžž½Ç~µ+±HEE@.î#ëêN×ÔWnãj3PW=2¼œž½ˆ…]ûÉäd7“Ê((Qž§üõ©1pç8 H9çç=?Ù¨˜¬Aã+·!ˆè¸éÓ­9äªxÚ¾ óø}*ŒÈD†IT’Àþ *d$ížr22?¡¢Ÿ,¥ª'b¶™þ÷)éú~Š«îQ„Oã¶qß§¯JP¢l?ESœ‚Üúœÿ*7&àŽs’28öÏ_éT`(ue\ 1ãon?ÄŸOÒ†8%øHÚAÇn¿Cøç¥! ³mlg³ƒéŒçŽ>½(Œ´líÜ|Û”å@=HÎÞAö8°¤!Êœ€Xäò0@ÇëB,r ÷àdž¿ýzFEÝË18ÀÜqôúô (;pxî럥9Ý™‰$’Ä·Í×'ùÿŸJ€Jw‚Ÿä=¸{Ž¥?8åGAŒcÇzRCÙ.z°G8ÿNXãŸzÑÐÞC~‰(w ÏŒž½¸?…hýÔgÊGm­œl²*ÓF»¤1`ñƶ-|!u=¯qvŠÃ~\ä®\gùn®yá? Ûj71³ê7¨$Z6-àò$œzW™ø’_j æÜ¼ƒÆ8ô8¿úõÇÏ퇢¨òFû²ö£¦ÅªÌa¶¹3ÈÍŒ+rO¸5¯áE Á:ÌùoÜzñÛÛšã<;§\Þºùn‚éNí®ÄgsëV|O¨Ü‰±;"ÌŸÆ‹÷±îzÏ±íÆ©t9¥ÍûÏé·×øÁn[@  ð=½s“šµ«êÚbZÂð4“–Æ¢eŒƒÕ}Aëž y‚^¢Ü¬ûL’ƒÆt:>©azòÉxÍØ—oÊÃÓ+Î_oqTãdf­su|íVºB˜Á# OðŽà & ;Hµ‚‹#ÌP›É%²XÉçŸ_ÈP—$w;)ÕjþþòÞÜKyâ @®  »K)#hrGR3ÆHúšú ~ËúV—dÖ$òèöL I:‘óÎz¶Onü{ó^µ§m"ˆÃ r‡Çó#ŠÆñoŒ!Ð-mÝçoœd+rÏÁ9ü0^+È•IÕw{ÿH9ª)Z:#À¼'ðÆÞht¸3qpAšâGr\©m¿+1Æ7ø ðßÛ^ÏÄ^ðTÚÖ¨[ØØ"¦óÙJ|ä ¹Á#;JŒpKGC\ŸÆ?ÚÖ_êÂ;L¬HqQåcnI^;œW™kŸ¶uï‹í[E׬"‚ÎPOœrÅ|ÜeKÎçœb¶ŽªjoësHÏ•êî†üC®K¯^µÛ—“© Ë‚Ù9ù°I'Ðsš§ykØ®ËÆš‡X·ŽH‹¤JH~u]Í´g'OB8^=+‹ñÉmkv‘KºßÌ?¼Àþ 1¸ž}¹öö®ˆ½QÛxÜóûÇC<’¬.K`Ø`ûgÒ­ÚÄ­woÂJ1¶?ZϹØIpUîFp=3ÿê©!½Ä©/”Ó(?2ÂrÝ89ÿëïjëC4ÎýYl.m/|Ä’îV1™ä¡ÈÁ8cŠï„ã®§Â>/Oø©eÊý›T`]¹eeÎrx-‘““Ôdõù…y&§© ï›ÄX·À6K·!I`p Æ@{Ð㡪뎚Àµ¸Xî,îžÍ\üè9é’Hä8 pN^ö»NÑÐú⦚æt—vÓÅshÁí’Sµ¼¹ã€;«覾-ø™d4Ûí±æá¸UÚ:»0{u ÉãÞ½ßOñBßipÉËH²D2ò6ÆGŒq¼ôÍx¯Ä Ú´Z‘fÆP6ù/ËŽ?ºgžy'*¼íE…:|­š¾ñœGD’Â;u–u²yö;)W~\‡ŽÃùsÞµÕ›ÚÛ[2Â$H Dj«ÐqÆÍôéÎ*Æáa{¥éWq@Z5nfAåù„Éç0‡§\ú޾ê¾ðÍ­þ‘mö[i-¡¹iöíeW*\`ò1Î;ö'iÑËNU¹^ì%êp?d‘<|¸2Çms”œªÆYŠç?6ÜŒñÆ éç—5ÍÌrܸe<´ pp= î9jôßµ¤ñ­«Yý²T³ó”cÌÃ)‘²ê2=¾àÎÑ^U#ŠRL[pÀº¯÷O<àØÎ=ºUSkâ±™g’g·“ç—’êAÜ:qɨ¨™Ùؤ‘($å†ÔP¤t>¿–j §¾Ú¤‚Çß“Û8Î=é«v Œ»×‚fRAüÿZÕ+ åÄ61U‚›F|Ÿ~§§¨ö¨Ly|€¸äóœg¦?Ï/ñˆÊ³ #!àuàc¹ãÿ×PIrÅwmQÇ'žØìz‘UÄÚ¬ñ«$a”¶B–l<Ï^޽ǩgp¹1°s’€ÇÛ¿OéP­ì±³2»WøAGáúzT3Ý9pÇ$çþ=‡½kf`ä…ž7ˆ+1 ùÜç¿^p?ÝÍDY› ³u=ºòp*&”ȘQÔð¥²ü 7Í&\“¹³Aã=x÷æ´HårDÓP8$¥†zçëÛ4U1þö@ã‘õ¢¬O:%pÊTKƒÈ'ùõé®­æÜã°SúQhÈ^UF Å7ÈÃU ¡ÜÊHÆq™˜÷·=YT9ažzòiQ–Gã, ÈÏëJ®ÄxÎ@Ï\uþ´Íªí…lç8È¿—õ cŽ@VÉÏ~pOãÿ×Í"3Îsœ€zóOWÚÇ#¼~yý Fƒpà$äœãêA@’4YX„Æ$uÿÎ…™y8 3è;zc rs2ÊèùÞŒÝëß§Ïêk·ðƒÇ§Â“1"㓵†Að;@þµÌjÖp¶©x°2ùP¾ÒAè03ùg‡½c®Î‰'c&Þ=×<¾ÜÜŸNß…vÿ ´Ö½ñž…dÊ$Yµ£hÈ ²ÃåÁõãùW*›y>VÎuÀéü«µøU¬­‡<=pä“ünÜx!‡l}iVºƒh¼?/:OsïoŠ^SਮµÄP¤.ЀúÕã·? uëÿ K7ö|O$ª»2íQž öô¯®µIãñ?†ü; @<—ÆOx•Sߜևƹcðç„þɸ‰¼’7ƒœ‚§Œ~uäss´ÖÈ÷­d—V~hê¾>šYoTùѸˆ† û~]½+Š×d·»¶g ‰[àd1öÏùë_EMðÎç^óï®ʳMµÀÀؽI<óÓ§Ö¼ÏÅ&±ÕÚÑöæW]áFIÈõôþ^ÕÔªFæ9çM¶ùOšÑ¬ÙYÓï îb3þyÍX±°{µb>nåÔdnÆ1שé^‡{ðÖâÅÞ+›)#žIÀbOÐ|~¼Õ ? I Ä{£2+#•äsòœänÏùk¥W‹Z3ÏTZw!Ñôû¯9a‘"ø18ÁaòœñÛ¯~¿Jô φz”ú]¨[t˜8Cå3Žýþ¿ýjô/†ß ïa–Îâ{É5Æ7nÚ@Îyçù¯¤~þÅr´¶÷:å¼n˜Ò«°8NpA#=+ìí¶ZbÛˆ­‘6çi¿CŒŸA[ÆßÉ /–@û¥Gÿž+Ç«Œ«5îè‹•HAÚ'ŸxoÂ:_4•²µ²·pQ@ƒË` ­¯ÞM§ÌÓËrR ¤²+ONÙõíùúúäp­»¬‘‰ƒ|„t-Ûòçõô®Äú®¸óJÌihÔOEϧ?ã^t[nÇE)ójÏŸ>(|o¾Ó®.dðó\ÂÛK2L¼Œgp6ù@LׂøƒãG¼dÒÁ©Ar‹ XÙ”àHÃæÏß¹Ï^1Ç5õö«ñïág„î ‹R²1Þ)ù7[ÈÙ‘$„)ÜsÛ =øä|Kû`ü#¼¼ÙÚ<·ó²d’Ù훜0ê¹Á ŸÏ#"½Ú3oÝ3’¢»»>ñw‡üO}usy,2ÜDlnÃòŽPr1ž8= yŽ¥5àyã‘C)`¸q×Ðã>™÷¯¼¼cûZxwÄVÂů­|3lùÛ’×H`Ùûr¹ÇPÚ¾Xñ{h÷þ!’ö×U…‹ªÈ×>K!)´díḾ¸Èí^¼e8%Ζ«úþ´›´Yä²\ÝOu[©F@c’8àþqüëØ¾ßÉ{â¨ì¯Ù¤ªgåcßw9+ wQ+j‚òÝCç$‚Ƕ;çðþYѧ){Æî:3ÅîÌÑ\é$²Y„LÜ+ 3ØncÔ¼õÔOlm|8¶NÈaqû;a•€Æy‘Áìz`ñÆ ë±Üx#E|h·R]ÀK’®HÛϳ“ZúüÑKáÝ:ÚÖUß Â¨w|¦>>œã?îúù9·«ìzp:±O\²“[ÓÅóÄŠ€ ÁëÓÔ6sÏä×øª9eÒ&•“Õ01qÐŒôçØ×ÒZw†d¼ðäð¾é0¢N3ÿêæ¼CÅšeƳŰ›A_›éÓÖµÃÕNg\©¸ÆÇŒ–šæB„FdÆ 78ãŽúóëÄ0Þýœ)?êIÀÉcžzåZ· çU'ƒ´ôéÿ׬€‚á%ØeXm“iã¿#ükßM5©Àî¶Üè¼=v#–Ymx|±@ÌÀÈÙÎúc¹ÏL÷ðM-Ý;¡h»uX\3+op{7¯­x½£IeòÔÖ”ÔÕ¥£>…ƒK_xBv©[Äóbá¹úrü}+Šø•áioÚÅî•|÷0ꎘ A'ØW£| xF®<7­Ê"´ÔÉk)™så>2åäçÔ‘]oćZ^;5¸•­&ÇP>CŽzþ•ãS|¯š"såŸ$˜xF6êÚÖ Hç› ç@©½;œñŸêi,®"[È,.¤Xã’8­žo,ìAôÇ8ë½FΧ¢\jÉ-†ô¸†à9# #ÔT¬Éâ85 i#6‚&[{Öê«!eýæ=I=Aø×¡Ì”£ÿ Dý×fkG}"ÃHðHÇ£™Œà7¨vƒŒçƒ°5(o4{7P½k¨.á1 ÃçTelž™Êî,½¹àc"¹ß oÔ-ÊöFKûxœˆoIá.܇UoF®:kšF¯¦³Ý[í»Òâ5QB«Z`Ž­Îñ_^㧪§Ì”–Ÿ×äy® šÂëšWö}ܶwÀ\¼ †â& r2v²©Î:W™ÙxŽóÁ^%’âÊG™‘wÉñ+L6ðC—-À$G8€®ïH¿Óüqqi jw0éz–ù$²žmÎpdQÜ(=ñ“ݰañV‘>’ðÙøâ9ôÍWÍ­ìl$ŽáXaFcà„Žã¨ççv×õýl\W&ŒÇñ êhÚÒêö°#[]å&µŠ?ÝJÊG …è§$õ'ƒ’sI_NûdrY˜n`ÜAµhX²à6TŒ nQÔr}«’#¿Ñݼ› ”VK|`ÆÈÇs†ýâ:ŸR:ŠâI޳#:³ÉQ×wß ðsõ{lÏzÊp±×OkF„×–¡ HˆÑßF%³¸–BWz¬ªÇžrîk’Öæ‘õ`y÷ÍF»•ƒ€üDrs×½Y“P¼–ÆÜ›Ó-ÞŸ1f”CóȼÙè:¯ËÏLzÕÇšÌ×öw?èwq­Ä`.9ùÏýõÆÜuqY$”Ó4‚z¦w~Ñç‡ÁwR%šÁÚäAùYB/=AèHö²}ÇÅz­¾¥ð²×Jº³GÔ಴bu#&3üpAUç¿ä<ÃàÊ rÖÎÚêu…g‡Êga÷Žìã8?ÅÛŠèñ·•+X žÞæ¾l°œÈgÝ»Ëà©R¤žHüqëüëì/<'ÁÿßlòüÖ‚C‘¹‚Žz— ϹôøÖÖfãdÂ6ÿᜑŽÝ+jvmõ5ƒænDRÝ£yãäÈP=±é×ú{ÕI.†}®§=1þ}ê ™ÄyaÊç÷ëüª& ʬØxë×ë^„cc:•[ؘϗ‚@ íëßô¡å‘s¸ã#pÀéÇZª²© óÈŸÿP¥B¥†Ð7asÏLÕò£ŸÚ1í&H_º8õäzŸÇùÒ®YŒ·Ÿ‡>ü}j‹ËeqóÛ¥)Ã6`2 uªµˆæb³ä²±û½p¹ÿ?ZP>\·ø²r;ÿZ<£¨PíÆÝؤX~l>DŸwnz­ÜS£}àqùþ‘L??ÊWqo¦(ª¸‰Ü’¾`'ÐwüÿÈ¥y|»~ñrG×Ò˜ªÁá'<ŸÃRF>lvÁ³ >•1é#IàtÏëÓñ¨Øo$0XŒÿ“þzSAA€zdÀ?Aÿëý)Çæ·Ÿ›9>¿çÞžûǼJyÀÀéëéþE5J—m½óéëMjàáœqœã>øüÿ?­ &OÎàòiqè[~yÏ9 t ¿–ã´õÇðëMP œ¡#‚q‘íïJ3œîÛ>¼öÿö>„ãüŠ]»²O¹Ç_©þU0y?Ž9ôïþzR³d;(#§N™ÇåŸJ7ÅÀnbFsò3ǯáštá<áGJnÐSç®õÁÍI3K“Ôu'’i jÎ’çRÛij!góèσœþ#ô¬÷¸kx™LˆÒ?úÒ#üõ§[Ù³Z4¬—¸÷ÎqÎïúSb¸ŠWòäSµP…ôõãüþ5‰×ÐÍ›÷á™›È+þ{Ri·Ù^Áwl>xdRà©?LÓï'ÞDQˆHùN¿ç¥wVŸaqá”…d.ä6{|£¾=•T¥eª3Œo+®‡é7ìñâx¼uð¯Â:ÔŽ%—“m; ‚±FX|¶kÒ>8xJoˆWö6‘ÇÿùNÙÉS–R1€G¿zøËþ ûñÇAÕõŸ‡¼ÊñjS}²É¸óv…`8ôE= ýÓ¯çÓa6ú„“G ³`8aÛ'Šù×zSq“=þ~hÆktr%øKa x2=;Mµh@BäòÇq^ÄŽqÇõÁ„>¼Òf{¨š}HLó §<`géГڽÓC¼·Õô†@‹,X(T°ñÈüy®r? 꺢"[ÙÊ2*¹QŸ›=Ny=¿„ûVµ%AIêyÞÖj.ìÏø«ðCC²ÐYi»-Á+¾ÚfÌ`ãæÿ>þ•ãZ‡ÀM"úMAFŠHšNY}3ŒrFF}«êOÞ˜"º]÷ ¤e"FÁû ‘´d€=Î{×§>¥§Æd”Nñ ùþ_–3ó`Ý~¼ôíÐù’ªéÉÙïý_ðÇU¾Us…ð„¶z%šióAó( ‚p/$údàôíÁÝðóÅQe—Ì`¯&T…ã !O¨á²p9#§.F2ܪ•hrGÍ·<ç¾OA’zÖï…^K⑦@À/¶NžÝk‡>hݳӅ8I4Ï£,¯Òð-…Î/·±ö©bV]ªrA88ÀúW ¥xŠ4t„’ƒ'$ó¸cŒ þœ×[§)æW?yp»xô?ŸµsF§3<ªÔ=›f”Š.†2 öëþƨÞxzÎõÁ¹·YŽsóç¯áZ6Òå2>fïëþy©d^HÅtò©+œJRƒ²2ŽŸ¦ØBªm!¡ùq×'à?*ñO‹¾ЗY]\X&ôUW¸‹9Æ\©àã«ùzW²j¸xÄjÊ„·¾éëÖ¼×ÇZ¥¾Ÿk2]X}²AÝ[#·^qŸÒ¶¡ˆ9¤¶=4TÓæÖçç7íðÎëp}ž(­tHS 6$„ïƒÂôǽjoƒ¿³“üG´:…¸xâ…Ë.7rC)Ž>¤g ¯iñ­Ž›âYåKãrFaTÀ=;/Ÿç_I~Ï?®|7áØ%¼A,ÅÚh§ ¶7œr2:ßÔ“îVÆÊošú²}Œpðv<ëá¿ìž“$3jQ7‘æ Ê]²Ê>ƒ¹=:óÀÏÅãÙƒÁzφÚÚkÝ£]Ñ“;®Aãc·B2M{vâ x'ºÓäˆÉlÁ° â¸%:³WoS…ÖwVØü(ø§àÍG@ñ®©¢_oK{+™(Œv”fûßtœqÛ‚{×­øu#ŒJ²3*I¿¯Júçþ Gà9¼?â?ÄjÑ‹©|‰š.™ Ì׃ü»WÅ˪Ým1Í3Hƒ““šú4ý­Î%Ujp‘™$¥IQ€AÜ9éŽô¡øÈ98Æ:uÎ{c ¬„õïÖš¸ ÜwúþuèXòîîz–‘âÑqccoo9¢Ž'‘P–a÷‡ÍÛ§o~œW¥x^K_Ƕ–Ð-¬ºzÍps¸0Èã£ÔŠùã@¸’ÛU·òK¡GRNò]Ã#ƒôçžÜWÛß²Æg¯Å-ËBÏ<†D2J í_€?ÓóÅ|þ>*’mu=¬Si³×4ë/*Îñnp>l÷®Ç¿`Ö!•’Ý„sŽsº½Õ|:ö’Ê&UHñ‘מ8$~[‹eVPr~éótª4ìÙìɧ©ùÕãï†÷>™Þ ÑÆ:’qÏ­yuγ,N·>Æ#qh”·áÓÚ¿K>0ü$µÔ<8çìù¯ ³ØûWç·Žü04[é3°;wv¿ú|-U5fy•£}bŽ>ÿY.LYä@Á=H¾å^ðWNÑ5‰ïµ?It4].R;xw<2PpÁK¹QçZW†æÕîâ("¹%W–l ‚N3‘œÿúù¯¶¾~΃ZðVS!2^3=ê…tÌIó—,8ç‘ÈÏ+]X™F0åF8e.~y½ ‡¿ð¯> \A£è·÷Vš›ŒÃa¬ ‹Í#æýÛpsíÏ#é^Ýy­]ÞjVñ*·öÌŠcŽW]¦t2G W˾ø)¨·Ž.l!óÑ-®fŠÞédÿU$NTmoªç±=Å}aã[éî¼+áÿ^Û+ë%ÄrÌî˜b7®îO8 z×좛•3¿IV³¶§–øãÀW»¹aÅv,cœ©Ï?¥yÉðÍÄM«hŸ·|ÑH’† ç¨*?„‚yê9¯°¾#ØYxÇÁZWŠô-¤#ûd1ô!fÈôäWjºMÞnšþ˜™·”fH—¡'®?4Q¼%fx®§4u<ÛQƒUKv¶‡ì’[2üÚáT‚Äá†O=OB)Ïâqs·ÏÌìÞ¿18µæŽoÄöú\–-5Ä—Zpp艜¨9O'“ÇLâ¹Íbße²\FÊ]0ò×¢yê@ãóöÆ(×%ðΨÃcÏ`1‰Ô)0ÛÇÍ×Lôæ» GNH¦m64IQì#º6%¢ÝÃFãøH ë߃Rç-™Ón[3™‡Pv¯¢5–ÞrɪîR3ÏÔxìj «»k»{Èã¶_2 šHLlÌyêI9.0}¹õKûQ§ÚM,åd­’  ’sòûúvõæ ÒâWšë ¸¬ ‰€HÀwÔ»æÆ½]NJ±²÷N_ã^±<ÿu(-äŨN£˜¨f "c’2:ƒìƒòïÌÖgrƒ ‘›äŒÏ>¿tý ô¯¨>-HªÚ~”bŽYcûDÎSBHld´ÀàõÚqЊùuåeFP¡‚“¸àñƒÇ¦òíÓ®–ízOà2îO#³4d` ¤’O'Ž3ž™ÿõŠ«‚$ÈɦNÖ¯Ëj…NÞ7 “Û¯Lò:ztô‚P¥Ù¥M¯Î ð:q×¥z èqMYê@@U=ü) ªW=#¯#§ëR›@¸`VL`\ñõ=(XòÄP Ïÿ_¯ÐU™XŒ“ ‚IÚA¼fž¨›yØOfôíþ}éè«ÈU%qÀAïþ}©Y2À2€1À,0qŽçüóHcŒ+ #©Ž9ý)|¼åYp1“Ÿo_Ö¥Œ…Rl‘‚Ì1ǧç¥d’Iè1œñÏÜz÷ô dn•6ŽT’p}x÷ëÀ¢œ®„’X O·¡þ¿…[ˆLˆ°ÅBƒŸ•Gõ¦’¯¼«ÇžœR „žÄO›¼¬€e™z(ê9ö4„?„\œú¨ã¯ãùqJ«.2 ŽsL“¸9Ç~?úý±õ£pÜ@_Ÿ9Úzöê?:L.)rܮёŒƒŒþ¹¤‘˜¨Ø9¨þE!”Áž[íùŽx8\b˜ ´ï9ÁÇ<úŸÆ“s|¿tí 䎘ô¦´c‚9=1ì}ÿ \( “N=)=‚öœ(ÛÔúçÿÕJ­Â /9¯Ë­0“¸ìb¸'wçüipŒœúsšh.)Œ.ö~ÿ0ùªÕŒOy*¢®ÖbrN}OÒ«!¶ ÎI}qSZÈöà¼[Ð`á‡Sê*J‹Ô×Ôo<›t±ùŠ¡Þùa°Aú㞄ծ~~w( »vìãž vÍDÒù“ !Ùœ’IÎ õÏÿ_­/”í½Š«óž=úýª±ÐÛ{Ûù Ç;ÕN7t?—µ1µ‰Õ•º¬q×Ó4šF›.§}ªd‘¶ ÁÉ'==sÒµµß\hö«,„,™ÊeÁé×QÖ§KÙ9Zñ3luûÍV¶Õ4ÙÚÚöÝÄÉ"·ÌñÍ~³~Æß¶¾“ñGÃöúŠfK=~|Ñ>220€t¯É­#@¸ÔgÚ‘–ló…?z·‡¼ y§˜®m™ã¼_™d‹;íŽ9ë\8¨BVktwa ê&¥³?oäð´7íçØ\›hdêblç¯9ëü©—>±Gk­bäÜÅÜÉTP9韯>ƒÚ¿6¾~Ù9ø]fºn§Ömcä| 8àãÛÖºþÔþ2øÓ§>¦ÂtËYÔ¬Ï$a‹aÏ8Ͻyê×hèxZ©ÙOOÄújoÚëvÑM¢»YÊþaÎÜÁÛíÔøÖnqå¼R|Õ•1¸)'’IÎN?^!ð—SÔ,4(ô;öekS´™9/¹™9ôÜ;ëÛ­c[@ÏÀ€Ë° 63É€ØãÖ¼jÊJO·õó;!Mhf^éïö¢¬dòq¥÷)çœôÏSý9Í-¬cpH,èÇø };‘“úv¨õc2³ÄÒJØÜ@Ëc'yÇ'8¨Cn‘<èAÏðÿþø®&Ö¨ë‚z3¡oKnÙ$ªcvú?®ÓÂ-{‹h’vVc‚nƒ}Ö¼ÂX®. }¨êéœ)+øUÿ‰ÄŠdHÎF=;Vê\â¥3Ýá×"Ü*¶=zT—zÚCúw¯9µ»’_¼ “ÀúT§ˆÅŠÉÜÛ@ùpBžõ¢”žˆâú¬/r߉|Wæ4›_÷…pç·<þ5亇Œ/õ æ³BÙ?(Ðý1Û©®ŽÿW¶º2‚…C ƒ‘×Ûhø{F°±ƒíÄò99RÇ}2qÿê­T”5hí²Š²DÞð…ŽœÏ¨êQ™&ÎNΣžs‘ë^ý¦[TŒ ù@ÇzóŸéË-äw.Å×q(HáqǧzôXfEM£-·¸üë|<ï>vxØýmæAär)¦L·°ª~›F~n8nMIlë$uâ½¶¢ƒ•/™ÙZtcS±à…Kcœ})Z0ªHÉÆFìàïõÍN ÿ:ŸJ”\ä)éÏ\õô•b(˜[ÜÇ$\ËŒž‡9=;{W¹~Î_åðwŒb²¹¹"Êî6c€,¹RN1žBœœö¯Œ#B67yýJÞðmâø[·Ô® ’x và sž§¯ç\ØŠq«M¦®uaæá%cõgÃ~7²ñ™ ¨þpÀ²Èïœzöüë¾ÓT­È/‡‡nw*ãšùCöPûgŠô{‹¥à´ó ÌiÈÎàyÎp+ëÝÙ­â‰N~ðÎw~ðU"áQÅô>•YÅ4ikZJj'—°1n²òíùWÆ?¿gÉ/5é#ŽÚGv#ª {šû§J™ï/£¡"8ÈÚ"´üI¡X2®ø“yêIéÓ¥waª=ûr©ìš½Ï€>þÌò.§>¥ulÐb²W9#ûØüó×ÛèÁá;¯‡Ok%‚†´ŒFó–ã~÷$¶0:ŽG_ÃÝâðݬM„ڈɵN:óï]^‹¡[Ç,a£Ý²<ýÓÓŒWjæ«.DÎIâT3GÈz‚5ø£Lñ¾’ßlðæµx/&Œíýܳ¾eèÇ;>xžÝ¥~ÐÚ!¶Ñ5ó/—sdòQŒ^¿˜¯%ñwíuyáŸÚľ ðÖ‹ö¯¼’YÊ“Œº^FÇÍ’ 7|œço°Æ:Uø‡¬ÿÂW£k-æîhtéPíÆ#>YÇ³Ž•tä­g×ñó=P¨çIioÎÎÏÍ8|øÑ‡õ‹ .ô¬ºF¨F•9fáÊ®ãÇaZ^ ÖáßÄ-[׎'Óïd{‹B>ï–ÌÛqø_4éÚuÙ°ñjŸíSȳü¦îBK¹ÈUÜàã'½Ï+«kæî'2@V"’"aŽîÚ1óeOÝõŸNWw;¥±2\êȵñN t{©µ+¥•%¸·ó·qÂñƒ×uÈã>¸ù–iV±•!™ƒy„îFÎèzž€f½óÇwrø‹Q½½š'h"|£XžÝéÎÞsžaž>”­ÛvÆovëùóùÓ¶¶ã·æ ŽHÆyã­#!ªI ªGNþçÿÖ11nÉÈ•} ŸÒ€ žø=?ɧp `@ÉSÀÛÖ†n@Ën?w¸Ç?ãJ¯³Þ@\Áü½©v‚Á¾÷8åôÎɤ2% ¯»a'qÁ>”üñ¤ŽxÁô§ˆ™‰V{Žâ¤’ Èö?Ö€Ü,jr§¡ÏóŠM›HS‚GôíOÀl³ý욦JñÜcž¾™ ü²·ÞAýßZ¿c ™s¨@qïÁ=úÔÑ•Ve%@þò~£šµ Y_ªÀBGñþOéS&k©kìaGL²d’T–è0?k;-nŒ@N¬0J®X`uÿ9µôÃÚx†–8<Ã,c£¯åõïé_Ân£µ†ÙƒrI•G1Ðt¯»>é­£i:zÈÛˆˆ䎜{þpqÖ¼œSµ¬z¸hY³RoÙ¦]rdxQ>vÚH×'äOñŒká¿ß[YF†'èÎ6¬Ÿ»’= ÝEzN•¬GscåyqÉ"®ï0–i$_˜àç¸È\û×ñѾÁã‘-»,!×÷›ãc׺À0úšµá=DÍדË+´…}ÌO$dr3Ÿonr×|êÿ×õþFª7‚;‹ýÒ[<ÅNãó§pN=¹Å%®ž÷(I Ñ‹+M¸|g¯n0äõ©tÒ—a$º…$®Þ=}úâº;OŽÝ ¤o¡b~^™üŽ+ͪ’W'm™¢þÒ±¹Üp N cŒòà)üóZZV‡3¯Ú1åDG*Ù¯¨ã‘Zid— ²íPWkgÁàgðíÒ®k·†ÏNH“ÝÀÇãüs\ñ¸Nl§övȊי ÚSÜ…`럵+é£y$v8ýÙ$gŽÕÔhWj«eÀngaƒÓºp:àƒü…zFŸo”‡fv#¥tSM»&aR»¤¯kžA ü¹Ëv¦ä|†ÎïLtÀýk·>µÓm•WUûÂPëÁéøWO}«ElÞD#ι#"5<Ó'Ò±uEšY/%Æ~U·ROåƒÈöÇjÖi/3–êÔjúÖöòË8ŠVÙ:ù9~¾œÿ:×¼×-ô|[¤u »Hÿ½Æ^}ñO´£ÌžQr3ÂXž{œ æüuðÆ"¼z½Æ—6UH©*3ÃmÏ'ñœûb¨ÇKufòœ%$ªl‰®~-x3GŠ7Ô5Í6äóo!^Ù–ú~b´ôÏ‹þ ÖBŧëúuÃd.Èn£b3ì8¯¼MûøZòÑN¡â kZš"Ï—÷¤ªî6¨ŽŒã#' “>/x[à 5ÈÃß5"æ"¦Që‚xë„ùG¦ÆO¥{Th^:Jÿ# ÆŒö¿Þ~›êž:ÑmiXÈ#jWq8éÖ¿8ÿà¡:ö›¬Áa"<k[Œ(n)¹þ§ÿ¯\7ˆ?k™4*-6ÃQ¼Õd‹8¸“ ;´äŒúcÓ½|ëãoˆ:÷Ä eõ fîi€ÈŠ‘c$ÁÆFk· pš›{Õ¯ tÝ8­YÎn(Iç°<~4:•K?ÄXôrMeRÇœ1ë?­2êxàsõöé^ñâ;åö¨9óßÇzé|áû¯ø§Lðõ¼Ò /d* cÆIïØqë\Û>½Œãç#¡νŸöE±[¯622#}–ÚYoáà&@ÿþµyrS”—cz穾çéÂé¾ Ñmôû4H­bE@HPÍ×€zI®^6 =«‰Ó™Õ"H‰. Åu6²Ä±™2ýKšøÌ÷>¦I-ntÚ]÷‘0vm zœÓ|Câ öùfaû¤úëJÒ«À¤‚8{ÖeÔ2°SIŽOJÒ>î‡+‚“»; 3ÅHLYbe…“¡ç ®ÒÛÅÑØÜ\Hå¥d·ßäÇÉÀÉÎ3ߥx¦—cp·#{0Çû5?Œ|wª|0Õ¬õ¨ôñ©ÙIkäÏk!àòNìàóÅvR›Rn;œµ¨Fm"O þ̺¯âo|Mš)S_ÖækK2‘*Aænœˉ9!@2p1Áxâ ¾øCÄ1jI-Ô–ìŒK’`ã;±ƒÔŠôŸ„Ÿ[]Ò.îïí’É|ç‘-Æ@Df8^ý+äÚŸãçü%>3ŸÃºtåä½”}£Én2¼g±aœWl$œR[Øô0të{Ióü?Õ|2ðí¶©áÙg– u“ó.T³*ŸOzäµ ¼ÕšÖ‡;v?:u­]"ú[\µ¬ÅD‰+1L‚8äÃÚ´W^×ï 3[]]ÞÝ ZI–í·‰sÊã’Ëœ0Ç÷z‘_Aü`øAs¥Ã%Ì:}ÈP7KpqÝ ã¿´ÔR[Kÿ1ãtM˜Œ­–ÁÚ@Àꧦ9¯|&[iÛPÓ5»-.à=BQk1xÊ„é×0+“Um|oáûÆg¹Ñ§µ»l*ÝÀqžß62€K ‚N[Ç"{ïiÚœ ý«©ÛÍ¡Šâ6hÎÊç#=sÉÈÓª2æƒkÈÁÔ—ÚW9ˆ,µi.#YÑ5aÚ$ŽðÛ9xØg »p£–R;s­áTÖnõ«X´{MOP½óDcÒà’âk€ØP¦8Á-’ÉÆ=1S^jš6©,òÚëZú> Ô$DÏ_ÊFAíÈëšúÃþ û«x7^ÑÊÜ·9Ï~Ìþ3øÉ£Feð®¹àûÛrI§¥oC¬$ìÓ4Oš:Nèoò 2ÎO<{uçá^¢)0‰ÈI £“Çóãžñ\3A3³.mP-rzàç¯aøúW‡5–ºµ'Uh ’ÍŒò~µ5i5vs«óXìÍì?”®œrN3“ÇNãüœ­^ÈCpÓu¶7ª3gIuëÔÕÝ&þhc*É&qóÏ9ëè8÷ªšÔÓ yAK•Lçƒïþy®»+ìWÒõä¿·}Å’zõÀÒº{ŸÝ_]&¦dÎø;äyc©nœñüëÏ,o ¦UG¹:ðqþ}ú×YỘ´=îõ×3;w#G¸üÿ:«>k#9EZö5¼Yã-'án•$²þþú`X/ñHØãž}+Ï´_ê%Ô›TÔ•"‹°8ã¿×Ò¾zøñZÊ_O¨jºŽç ÞM¬„Tcô­Ï|QTœËs«YÚ¨ýÜqË V“ߎƒô¯cê©A]ðÑÝ}çÕöúÔQ¤…ŠáH_3qž­6-]o`Y|¡cð9¹üÍxÛøÛOŠÝcì.¤qûÞúÖ·‡¼S§, Ö-IçxÎH¯ëôô¦©#Gw­Š<}s¦è7Iè²>R(ÀÉ~·n£°¯?iï„ÇÃ^·ñ ²Ëuy4›®‹üß1Sœ¶s€C`ãÝë쟉z!ñݤ–w‘N¹¤™P¹Ÿ_¨ì+çŸÛ‡PM;Â6ZAX÷4}U²À#9Î;z}kÞÃ( .§ E.}U„·‡ Ê’vîo›o¦=1ÇåBîi7È £‘Ã~xãòëP«í\¯|mëÏNœ–bNCzòG^¸þ^â½›Mû“®v1áoð†Æ:þT¤‚lÆxÚùÉÿ#¿Z`89=ð¹Î:ä~T€£mÀÆ1‘ƒ×Žô˜ïqà+‚NÜ’~µîÿ±Ä27ÄË©ì%“¨ló÷ããüûŠðgeEù›hQÈÈ~õßìÇà9ü [ë÷£Ê:Ÿï '†hÙQ—ð8?•qc&£I®ç¡‚ƒ•dûgi7’ÿf(•¾ï*sÍuz\-”¹z“^u£jbä+HáP *Žƒük«Ñµƒlo™O_¥|tãgsèZèwZ\ÂxÇ# óÅ]é¼ÈÓmóŽ+2+äHÑ¢mÀŽƒµhÛºŠ9 ùAÆk'³0}Ê÷–Þ]ôr««E6J« ¬“I+nd ’ #'a|*øTöÞ=Óµ¸ö­£‚ŒçŒôÍzüñŒ=»B1[H|9ðïØôû;RƒåE?@6ý+Õ4Ï›‰¼ÙNäÙå¬qœ~gñý+AŽ'•âaCõÏNs^£«G_3#=«ç£Ró¹–&¤¡ #…ñGÂë-f …’Üî#/Ð~>žœdšø_ã‡ìϪ[\]½¼f8%0—Î3µ¾ñÃåp1׿$ ¿¨ 8àqYZÿ…ì¼Gh-ï-ãšä#é‘íœ â½š5gEYj â9ž¨üñ_‚õ ÝÍæD,XJ…w7Í•8ìÝzôëž9Ó¦Ã9‘¡/‚þfö Éçñûñ³öDÒ ü*×~^¹…æÓHÌŠ®ØØ1¼‘שúžÿEZjVÑÎo4këu@.qjkc…ʰ=T’¸aòž˜ëZ´Ô<.’eµ-8²Ç .Wæ@ÉÀçéïÐã,5z´$âµcðHÜøQ* c?ÄAÈõÇò¤l*¯Ý`IVÏãþ}+¹ø£ðñü­)·¹7úUÈ[]™QÉù†Wº°nq\Áù®œœ9íÔwú×Ô))«£È”yI¤o+G*²ËÑÁ“œzúÈ×w™±ONBdãçÓןþµBŸ,h3ŒcjöÛÅ"œŒœ’ãWa\´§£/ñÁê B ¹ÁËÀ¹¦–;·ÁŠýåÀn¹ä£,À4…†rO'§ÿ­É™ÇrI'$Ï¿ÿ®ŠbeÆT<Œß<ô¢\qpYxÆ?¯8¤WFQ“#ïz^ØâŒ–L±Ëg¦sNÞÇld|ȸ*GOÿ]Nâ,cx%º“‘“ùj‰Z'aÆìŒ°p¤‚ޏÍ4¯BçB²F‚$b}ò1ëߥF$<9Ϧà¥8!Gçä'–Ç?Zb€ªÒHŒôã®§µíÀP=ô4I(8Ï žx=È4ª@ Ž9àñÿ×#ÙU¸Éßí½Ó ~´„;|Ü<çž=)Ìî_ŸN s_zŠS–,ŒOÝdä}i]Hc#1ÜÜŒã)”_Òõ)ô‰ƒÁ)p¬3ÏNß×Ú®]k_Å‚ Rœ/\Î#¿5‘²o$ç(6qùç5ewEÁ ~L™5›ŠzêÉ{¦ÞƒMuÄ›˜° x3Îqøq_ZþÏ Ž¡jw6ÂXO*Î@ ‚‡#¯pxéô¯6øðe¼U­X,¨ßcgNvo•È;²1†éƒßÓ? žøim¢éqC ,j#Lv ‘“ß<÷¯Í1mµJŸSé(ÓTãv`éþlv@™•1dܑێž½8måÞˆà0PÌ3Ÿ”{ çžz~5ÞjV‘hïPÆÌwÞlg'=:}+O³óîwFÇp*8 œ~}Ǩ¯žV¿+gdÞÇiáxÈ?3Å•e Žp2qÓøÀÿéÅêÁ:&ÝÌ¿7ÍÉ#§õÿ9¬ ÚjŸ9,¼—¿úõ»<*vm^qpr;ãÐþ=릚\ªÆ½™CÆðÉ«YÅjßq¹}ŠK6 œb1É<ã¸ÇJüùø‰ß¼IåË S´jŒŒX© âÜ2dLc¯p1ŠûöG[›w2üåNuç¦~îxí#à;]zÂçìñ}¡£BÐ> ÂpXwƒßžÕÑN¢U/5¹TÒK•žWàO*íVÚJ¦XÇÊç'¹ëÊž}ÿ öÏøí&1“œŸ•KHöçÿÖ+áÛGRð^·=€RÎ÷ H žy9=28çµzßÃï‰j‘y¼©“ ÁÈÉ8$’G¾ü;ê++ËáÓRen}»mâawl¦)í I'ê3þMXÞ£BehÆ<ñÔîzòø…¯æ„4¦4çæa× ÀÇ¿ó¯fЮL%w’P6x =+Èœy^‚z"…ŽŸæ\Ò11òÅÏ'ò8ô§x²ý—ÓZÂÃ÷Ü3/gœžÕ&­²+ç•@ŒLrIÈÉÿUcoTGåüøË8=ó×AWMYó3·²8‡Ÿ³…n5ÇÖõkíI\ä¬ ãkÐõÏÙëá¶·ŠçñŒ£ Æ:c?•lé𵿗†Ø¥F8Î;ãó­t‹q¾!Än¿1ïì+o­UNñeÂ)XðëØwÀwW†Hnõ[|ŒyItB¯úÒ¸OþÅzÖ’ÒMáoo‡. ©Y[w×ëüëè]o^›BA-²y™ûÛ° žýó^ñö†½Òt¶Èc¸cµAÁç=W°íÞ½Œ=zõ©^†·P~ôœ~'x“Ç¿bxµ y$°>ÔÓ¬Ñ÷Œärxý{×Ìß¾/ë_T^ðÎp?—€s×®:?úä×Ò>?øñ©x§AÔì5í0²Ï¦ZEùA *Sþ=«âûéâí¼ŸõD¸ÉëÏS^í©;ž~:µ¢”^ä?’Ù9Ï?\çõ¥åÇ gž þ”ÈNÞ_hl~œ •_Ÿ¢à’§Ž?Ïå]çÎÜrÊ|¶$pq×üýh3,e°Ãrr{t 1U;XñœgŒþ½GópŸ~øÿ"Üè| §/‰å|õe)$eç¦N ’x'Ð×ß"5¹EÃnHm Œö#šóo‹~moìª-ÌÆ&$ÆíÇŽ9ÏBN=\qu!(ÊNèÞšS|½OÄ|?ºÿ„¶ßG¶ˆy×·BÔ+ÙÝ&Æàps“ÀëÈâ½§âuüpø‰ XƒBˆ¯ ®KnR¼žpA c­z¯Å߆Káï‰ë3[ùpÂÊ †.\?–„n=6Èî0x¯ŸüQz×·r\7Ë%Ä¥“å ]†X¨Æ3œãðȯb­e]ÆÝ?SZT­&ìs¾(ÔÍͲJÉ.ô¹2!Èc#‚ÝëÇÞ‹½jçRÓU’G[ˆAš39)¹Gl‚=ôíø£N’†¶-qeäêºó˜ä;¤‰c%NÀRI;²<k.¥ŠÐÍ$l¯dlàå\*ç®1¹qÉÏõQqäÓ£5nìäΪf´¨[Éòà· Îqô§¦k«ð“[ë0\XLE½ÌA¼—SÅrÇMÝyÏ8äœW°¤:i†2FÉ"^s!êÀô“Þ¯;£kú”–Ó)|ÄàpÀ`gÔ&N{±Ym|Isq¤p0‹ »@ܪ `mè¾½ûä…8Ô•—b$î¹™Ýø¾{ ë6¿eÓ®È`-™-§ÈC9R6âONa…ÆzõîâÆÝÕ”a‡€?¯øJ*Þ1Êåy#!~œþ'üâŠH ï˜6÷²)ªÙ~lô*x¦;‘ƒ»¡# ô§*•«Iÿ?ÌRµ…ùσ&pqÉ>ÿçß­•Žã’‡ÐƒÆ:þ”F HpÁGÉÈ=ð?Ƶnâ·±°XÑ–iØ’Y”e~‡üô¦–— Œ²À†ŸJC)vê; ð?]ÃòÅM-«ÃoÄádÎ? ‰deÎQƒžx©ØCXî$18'8÷üéÉ&/Ê@ô=¸ÏÒ›úÐå°$県ô?áÿÖ `­½m¾œñþM0ÀUÈaß¿Z³{˜ýô8çbd~§Ò«± ¸åÜvS‚?š ØA‘‚OþºE-GV$×Ïz×§|øm/Ž|a°aelß;,¡6±Rò>£œŽzzyå¬"âD@É 3Î1þxz~óý“~ÿaxVÊa ­ÕÌK+_,äåŽîçwCÓó5æcñ …'æz˜*<õ9šÑëðÛÀ±h6èD~_€òA$õã¨íø“Å{v‰*-²ä¥ Éq·ß$žØôô®/L‰`U ´Pb@~øž€ôÅtvìØÆH É\t#ü1ô¯†¨ù›µ_‘ô2ÔæüC"Üj cYYúãã¿ãÛŠ£§Ø£»§–xmÈs–É,qßž„úàc´¬Ýo/¤u¸bTnÎîüƒÑ¸ü:óZV6̲³»K&Õã®IœžõÉ{se¢/X:X«)Ë,g,äd.sß¡çŽK¨Ü¼q7 ‚6 9'ŸëSˆ‹ `©!ÀÈÇ<ò?/ó“Y÷ξ[3° W€1ß¾=þœúîŠåÒþ†?¹ ÅÂZ[äGi ùY3Ï9ãœgšçhø™á8Õ'“ÈÚX—;{·$`œó‚}:jô0xŽWì¤LõEÿƒ¿–{«K+¹QHx×{qþ óÈäqƒ_WxWÆð£»-tÌFù6§ núöô5ù§¨X\é>b“ $œ08zŸSŽ„=ë×¾~Ð^žA£û9*»@É ’à Ó7g5шÁòþò’ºíþG4¤î~ˆ A|KeFâ`чB§‚½GóýkOI@ŸºÚÑIŒàã×ÐW…ø?âB_Áç[:Ç›d]ÊÅ#R8ç' ôu¯[ð§ˆ#¿xæXÆ1ÀaŒÃÜ}}냗ÝRG:•Ù×ÝÂ[bŸÞ1#*½G׎žþÕ™©-ÄRÈ «•Ò5ͽí¾P¨$¼Og¯Î^HIÎÔ$d÷<\Žõ›LÞ2KSÉüM©2ÌꂌùŠìŒtÀÀéŠùkâf±/…nnd¸‰·"îóT)Œ Óõî~ƒï{Ë´KYmÈØÙcÐŒIõ8ÏZù7âæ—¿þž¡K2¦ÙU¯‚yÃöêsœ‚A©Ç±ƒ›Z2¤´Ôø'â§ÄËÝp=šlXd-¸2 `ó€Ïé^\ŒÊp ŒV碞0Õ-”†c'¨ÎÆ;¥`ãÍÓ©=ëë)$¢š>o7:ËAÅ|Æ`FŒž¹ïþýTÝøRîƒúv<õ¥M£v Oçøž´¼ ’§Àädÿ…hr‰»aÚ •Àœqõ§ç…‚[þy¨™•2à Î2ÀŸÎœä#Nzq×ÿ¬hó»HCH¡sŽ3Ÿ^¼T%¥RX«…ÊØãðíR0$I;Žwã>Ÿ^ÿ/@g'¾)\¥d¿…ï>Å3·ØïŒ78`3Ç×=«ì‹{ø#Ô¼õ!¢¸¼Uäƒé_˜~ñUæ‡}j!¦ÉDˆîHüqú×Þñh×t{­àU$ƒÎp¾cAª¼Ýô¸Z‘tÕt±½·C»xP8UcÍo®¥ \†Ü§®ÓÍy”$K0bÌpAγq¯P |0#=kÉöo©èFͅ׈E³%³9;ÆAö4Â\mÓÌg‰p3€yA^A«xÁaFRì×®ü\û aX¤žäôöëWWèuÙÉâ߈ñ4Dº8É5çfG]sI˜FFdûïÀÆEq>×eñΫº]êªäãR;b½SÄ:rZA¥¾ðq"Œ÷‡CM®FDšJÈúáÍê´à·ÌUq޽nÒB8`p©ü+Ã~Ý­¼p‰k(è8¯mÓ®ãGà1f¼y|lË›ŠgAhX¶ëÝ…WÕ¯–Ù`2rG,9üÒÙÞ)”&@' Ü*¶¥$ u ¼ ++>WåÚAúdãÐã#dýË#ÃQý樷¥Û©KàDhÐg®OSÔÕ¹!7/°(ò”ç3PZÍöÉ·FÌæqŒçüâ´Ò,`t=ñ]âæ­Ð¤¹eq‰ŒØpbx«QµÒ4›«û¥o³ÚÄÎäc-€~P $à`:r;kj𕦋c=õõÄv¶.é&•‚ªŒã©÷8úâ¾ý®?iØõû1§é3Ëmbù+gL¹ê#ÉQ‚T•(Ú_qÖpzAjÊ¡ T•×Þxÿí9ñ‘|YâMN[XeµÑb9Ð# ’å\AcŽpÇ9#¯ƒx'ÂïãßèÏ ´Ö¯k£éÌ%(âyåHUŽA‚:GÇj~á½WâçÄk-æYláýåÌÑ•'È…{n|Àk° רü&ðÝ‹ü{ûP° xLºÕd´…0‘KÙ:¯ÌU2OÊG(yzö(QTTW^çezª1qCö‘ÐôÏ OáýÒS—à½. )Î^hC,)Pìñ±$z†ÏƒÅ®Û[YÉu}¸ÚÝJÓ?—£ØDkŒœòÙ<}Ñ“ÅtßüS/ňmg§] ]:ÒµÜtC;™d,9$Û²sÙÎH¯>»±ºñ‡‰c²…LÑy®ª•bB Ðvä`1=«jtÕïóþ½L¡xÂÌÕø_¦Zø—DZ]j 'ö ÜÝìÂ2C¹fÈ‘¡R ÉÝ´k—ѯÙïn®%š2ΧÌFcV C ôý>†½ºó‰ῇWv®–©¨ëÓÄÂWˆa™zá•xBCpÄ'œ"Ô-£´ð¾£z')$·bŒp¤q¸žAÛ­Â")X)ß­'ÍÇ9`[8ÉútçÃüMhÓß\Û»,'`'x  ð@çþz×¾øS{|>†IBIöÃØàÉPûºbpO''œ÷ñÏé³Ûø‹S³YPtbÛþeùAÁÀøü;浤ґÎÓLó5À1+»œ+þzÕYË?3cáøñZVímtQŽ=Fyè2¿ŸpÈTqØa³üÏ¿é^¤YÅQY +æ¹Läýп_ëš$A€¸#žž=ºýiÒmMÛr<:z²¦ß•IÉϨçŠÐæ¹q+JY±¹F~ø4¥q$z`g¿5(hÓ Nr~P}¸›C• oqÐ’Ðg­ ¹*º…|€zñü‡åE,Na˜ã GÇ?ýj(¨ øvþt£$€ n9 s“ÓŽ§4ÖÝ&y_a’qëïÿ매uÜ[Ž7yü©_¸aÀœç$ Žý?Ïø É'¨5ÚT€tÍ ãâšNEm©sà'Á S]×ì¯õ¶Ù«‰4 ûØd#¯œx9ǧèW‚4ì»"UØ.åÆ:óþq\Ãÿ $ÐÁy¥ÀÃ6å“sTà`àõúzö-"ÑÕ" #ç?¼sžß—ëÞ¾1ĺµ]´Húì-%J’¾ìÔ´‹Ì±i9 “Óñ®„ÄɦŽùÆôÆH\Ÿ_ÿUT´„¸]¥?9½9­ëm8¬%… usØûÿŸ§ˆï=.k)Y£'CÒ£¼ŠcÌl\«Är3Çùö¤hM´Ø/»œq׸ÇQÏë]>›§‹+pÛw»œ©i;lT¹¹ }˜ÇBI*AÉàóŽ;þ‡5WQ•œoXÂòGnx?ç¹w+¼¬%rÈ¿*(Ú6#Î|öã¹Í¾Ô·Þ…÷6Ðsø?þ½i6µ6Š3®&i<ݧjÆÛ9ÏÒ²ái#Œ©RÒn·.ðÁ=ùÍMw>ÕvQ¼>ç^Ý1ž*8Ú8‚H7 $”=ó“žAü}}*£érÞÆ&±j—HÌû¤bÅI<’súv÷À&¼{Æž¸¿’@Q;arO¯—CÇòõýVé%`±™á‚Ì8îÆ;qÁíY·6cÉ2‚®„pÄñƒõëÅ;J›VfRÚèøûâWÛOû\¤Ý v(óžyÁêÇã^#åÒ5Þ» ãt`‡$ÿ>ýzgë_ŒzŒzmÅ´w'Ì[Ù\®J°_SŒ‚?ÜÉ9Å|ÌÖ=ÃΤ‘I|(9=yGãÏZúŒå*|ÓGÓ½_‡Ÿ5/ÎÚtîd²œÊÇ0yRz€öü«êüh¶{pñÜ–V]”dp »ã#ÜqÈ¯ŽµØ,ç]Ò[%³*F DŲGŽãÉ%A8Àç ®A|Q6“t²YåZ¹.@oqžºûû êxhÔ“pZþYF 93õŸÃß•-ü¸cK¸ÜíÞ&9Qï‘ÐpxêIÇ­w6¿!—MU¼ge<±s‚3Áàóôâ¿(Ïp¤õäm ´p88=Iàäž/_øÁ¨ -ôëFù‹ƒ"?8È'ŽHéÄ kOË¢[ÿ_#Z•´»èqŸ§ƒQøƒâKÛy ¶ÒÞ»!=0@äg<Èúö®p¿LúšEP\6nçåIïíÏ? À&H'©$¿\z÷"¹b‘óó—4œ»Š€°Ànùàg'üóþM5@ž@Ƕ9Èíª{9*OOóï@PŽáƒÆoêJ¢Cæ8çÇ@GÓž*?•X€.98ëþÏ´…H8s…è Å4°aŽ€óÇâ?Î=¨ã…qž½0ÀƒúÐÎ=8õ£w–FxÁÎ{7=;Sc$¸ 29'ð e«•¶¿¶‘Ô” ×é_Z|;Õ›ì[#$Z¹«çpõ¾@+±Ç\uüÿOjúËökH.>Ú<ê0,|¨€ØÇn™éè¾|¼|W"—ÈôðSÞ3ß<5¯µÆšYœR6äñÓ¿éUµ½~ ²#mr=xÀj>(DØY—Œ`esì®Ä¿„°¹*J®Ò#©¯4å#Ý„•Ž—Äþ#i Gç.üôNüWe¦7‰5DG—* ŽÜןêÞ1¹½ÞÙUº€t?¼RšeúM3¾íàÄOø×J¢á¤iíQõ‡Ã?A¤[F!D™Æ3Œž¿çë]ă¶ -JâEuÇ"¹xâÎú(ÝiáYC}¡®—ÆšŠß[Z¤*ºà{äW–ÓrÔº£Ö¾"Ïchå¶HFÏe¯b´½[3)Î{œWü,Ô(bŽP(ÉûµéºÅãi¶ðÊÏCŽ:õÅx•.¦ÍÚç²gK£]­Ãå! Hçœׯ^ÿCã'‘ñä¡ûJF•¹'9R÷ÏçŒ×-áMKí—Q…we$ÃôõÿëúW[r®lî¢S:1ƒ’p®Iàûôö¡KK3§ÉUI.‹2Í¥[2@a&5ÊÊð8<Ÿò+D²GwuD’îp¹ªVÊ-âR¤mêT ð‹ÚÞ«ñÏÇ_ <-©]ieO‰u´³Kˆ!ùh"Œ‚xYXÅ(GÍѽ(UöqæjïOÏþäxꟵ›³²Ý¾Èä~%üU¼øË6³˜÷…ü?j×7—%CÏ“Š±ä(w(B»3*…?ÞüKs¥.³©jÚÍ­’À‘G-Ë0L-“8,æ#s¨É¯°ÿjÅì|9ð‡Á76ö>›׈uØ^öI&´‰6‰¥-¹Ê³Ï!˜#/)ñïůXø7Â#ÂZ5ª¯Û-Vâáž JÆÝÉݎ̕휜îùzð”›m·vÿ¯/ëc»ÚrÁF’ßúÿƒúšß³½† øâ?‹o{x ŠÒ–BÎé»ÍœíÜrYâ·ms“šó¿†Þ)–ÇágÄÏl š¶«ž!B€ìŽ&•™GQ¼.9É' ã5ÕØøº/þÍ'KR]î#¹Ô); ûŒd€yXU=ÂôÉÉó:fÓ?gK(£ÛO©O|UÎ@“|(2G;°¨~}Z½Ä’¿Ýùž{‹r×¹ÉêºìËdb3-Ó Dmùa (þ§;@ äòÝ z¯ìñ Ã«ø‘bòã–æl,$!ý×1TQ“ƒ ØW€Üê2\Êd›r&6ªÐtéÜu¯¨¿gïÇá­/n˜’é÷mio„윰a’pNæ(Æ:ÞpŒ!¶ãG$Ò;—–KwpÖ‰i‘û¢lrЪmûW|7Θ$‚v:a«Áþ.xrO xoÃÚ;FlïX­ÄÖ¬ŽÒ>Xž ä9o”g¨ïœz‡Š®´ÛýNÃL†$0EZA!å,ÆxÜßJó¿^)¼ø…ñŸRÓ®„³KѠȤ1ŠÛÛ‰23ƒ€Nì8+\Ti¸Ë›Îå)Ú*' ésǦx+°+®tý-'/¸’râ2äÈxÇ®kÊ<_§Í£x¢Õn®Æëø³ÎÐŒTr>RA#‚qÈÏ8íô^½¦5·‡’ÖÝbiÞmyÉ…0wdç;ŸžÛ“ÅyŸÆmK£ÜHì±&Ÿ"‰p€ç<\ƒ×Tœ*%ÜÊ›VlùÛZ‰àº¸W8d`;’8àéÿÖÆ¹,n\óÉÎvöÎ=óõö®»ÇcÊ×g;ä1º,›¦ëœ»8ï†úä' ¨§œu÷äþzÔõW±nÃpzŽyä{gð‘òq¸þã?µ vcœg³qŸ¯ùíAj`)\dü«ÀßýzØä+¸|àòC`ÀîOåõ§€ªöëÍ ÈÈ€œqŸòhÉ €Ìy>¿á@‡Ä¥åU@[wÝ¿ñE5£>Q*ÅxÆìŒþ´QpîF&23õëÇù4Ôb6 IàŒqšU\¼@è3ùõ¨Üdç=0yüêX òÇ–¥sžädãð§6íÀó•üsš0¤(Ïsœžƒ6r Î#=¿áL}éN\)º~TÇA¸¾A<ÄœþT a‰+’@'§¡þTŠ­·hQŸoO„‹¥ÏN08È÷¤M±È7|Øà—üÿZï~|ñ7Æ-Y-t›s¦Nûùò¼`I!‡9“ÏjúRÇþ ᜰÜêž*¸ºˆ§ïaŽ4R9åyú}G|㎦.)rÊZtðµj+¥§™ñcÛ€[‘žƒëùUí#C¾×.#‚ÆÚk†,yhp£¹'‘ÿ}Zú ã7ìסøZÿJ¾•¡œ¬wcs>ñÞÇozŽxv“á$ð„A¬l3©cp+8Ü îÎp8PO^}x®œ<ãˆu$àò8_À•ö´V¡#\ó•W;BðOáõüëÈÆæ’öX›:hÐvæ™ÕxCá7…¼áØt½3M„C aVI"Œ¿AÏ x¯œ¼mñ[ÂÞ ø•yáÍFìYºJËÒHŠ„ç€ 9ëÀã¯ëú÷Ä# ÚÎ’_8†(˾㸪 ƒÏP?Jü¶øÕñ_‰5OÌd²·“ȵ˜6C¸ù=KúŽz“Í ó r8Ù+Ýù›AÏ KݳôãAþÏÔÆöÖt“¢‰A+ëÓ=ˆ®ØD&Pãf°Î[Ö¿(¼?ñ[Åž š ½+Äš„r­å<ÆD8(*[8 צOô‡ÂÛŽçQ¿³ÒüqmBB±Ç© ’mÊ÷l lgqÏóúV„Å‘ÇÌ»úm·ùÇZÁÔÝ£"NFþ8öúÿ]jôZ_ÕÍL«Êý¨,Ëö ‘ÀÉ#Œû½=sÅ}&…F’ØóªU4܈ü_­Æó kwI7)ÈêÇå\‘;É#è;VpɃƒß$dŸz ¸Á^àvús^ìb ž«UՕ؃P Gßã4.åÛµÝXc>)7 ‡h$õäð8éJ§{žy-Œð3ÏSUc‡[ÜãqÜ»pOZA)fF$±QÑŽ<ý?ZŒ²ÆÉŒƒÈ>ügšr(!ŽrzçüÿJ[ ɽءC#¹<~'ÿ­LÉ>kdŒu#¡ëÏéúÒíÀù¾b:c>¿JTF.>ñ9çÇoåL‘®ü©ÎòsÀÿ>Ôªà Ãa$í=§nûǠǶGÖ”ì 9ñÏøóø QÔO¸A#§9”XЯoóý #q!6ïlô?çüi %”…cÓ§Cí@ÅGÈØ Èû»ZÈ )9Álg>ùüé¼ËìI­ÌŽ¢õüiù€ÖP²Œüáå_E|ñ<>{I¥XÚ+™J&î9ò~dú×Ï0Çæ8ç§<þ~ÕÓxbòóL‚cIäðd £ÐóõâÅAT‡+gnòNìö/k)p›’çlÙ$4mŒóÞ¼Ùî¦,fY 8?19$g#õ5æ§<Çæv1F}=ò{ñÅf½Òo ®À'wà}üý+–ì_VÒ$åqÎO'ǧ㊲—ËŸ-QƒÇ^G<ðk(_FBùg tNÿ9éGöœGÌLÇ¡,@$ãÓ§©ü+^^‚æG£ø#â%ö‡©E$2ƒ<ÂNsÆ:f¾—‹Å‡YЭ§ »s/CžsZøžÓ^ÓÒeÚÖU8Þ­‘š÷_‡¾.ûD6ö>p'Ì\)lƒÍpb(òê‘Tê)=öÏÃ)~Óoj[ ˜à“ò׬x—íxbV<²!Ú§°W•ü%ŒÍajø"©Î;ákدK]inÁ#G1˜ øÿ:ùª”âås®Ue’9?ƒº›jk+° ?œôüäkÛ†›¡d`eUÓiÀ(Æ:}ûWËuG†þâÀ»f Š3³P`•-Ü€ èy\WÓž¾ŠæÔºJX0á %‰Ç¯|gÄÙ¤ª´ÑËÙMλñOè³Ç¨éÒ‰­cU†è§î'ä(›oÌNâAëÇ?6OìÛá/øGü!w©_[Éý¿«\Iq}}:•šãMå9=àõf=Xסë]¦¾±ØjAwi$¡ÌW ¿0ùyãœú`ñÅT×üMeá³;@ ewp¤t]¸à)ÇžqY¥+ݽõþGœeOÙÂ:½þGÀ>(4~,øçâ}6+{DÖn´­(ê¶éÅ´v¨×¦GÜvŠb8*í±~`ñŽŸu­xPkó3Ïuq$—TâHÊÄäœ|Š!C `VßÅËÛû}{s,·âûÌŸÌýØÃ(qÔ’9AŒîã.ú)oü=cn׃–€Å¾MñQµÏË‚7$‘°rßIB.1R¾­¯ÁLíöJœœWc]¾—Qø{e¥Û‰#’+cO$ü„‡fà„äžRzf³¬.ìnÿgûËûJßZx†Y¤Rê!Kym`Ù…ëñ0ÏBX>RD“=¶—4Èù´2X‘´‚HQ“ÐõãôÆYH­Mý§’ èøfvQæ&á³ó`“øÉõ╾g á{–Ÿ¾KÁÀ²´I¸îËU#,Hèrzsšõ øÉôŸ ÝL»I$VHüÎv¨$+ ñ–`8=ϵp1øjîÛF½ÔíÕ„p,–ò˜Fé •É8=ˆ'<ŸNj½½ØµÓ`Xœˆe“r°`A'ÉÏ úzb·«j©$cJm3ÕôÏZßëvþ|°´zd`#Â~i™™Œ®rN3Hg…'­d|7µ¯ŒnµmZsq,³=IJɂîÛ–Fcœ‚wúkŽð…Ò$÷òÊÑÆP}YÜíëÕ<œŽý+¬ð|Ël'S‘;£`àmc°¼qÐþžÆ³qå¹£Ö*ÇÓ:¦›â)¬gæD¶³Ž1rÌ»0„Hõg?R¤òrOñ9 Ô%×4Ö$S2°2£= |£?ZØøal¦Ÿ§ÈÊÑy%™dRÆb##Î;‘Ï¥p5ô›Äz²LLe&@ñÄ9õ*rr®zãÐ ó¤Û¨œLéÁ$Ï6ø•£E7†týLÛÌ9òϳ`“ Ä.qלsøf¼¦\yh¬£hbHP0Î*ú âŬ|']²Éñê‘Èñ–Â(òä¹,å\}å=Í|øä1#äí€+Ü¡+ÂçmЬHá¹ÏcÏ~id$1ˆCÜóíúÒPs€pÃ_ò)Sk›çú~Ôr„L‰a"’v±?çüiÏ—r‘‘€1ÆOùÁ!²àãÛùÓ–5<žØÂã“ôôõühÓ“³©?çùQNù£S‚Qsuÿ?ãE/Pc.˹¹=HnGãMìÜ­–=x'ñíRŒrX˜Àèæ ÿ3DÍŸ™ßÌcÕƒdóÅ6€fï©`)Õ‚ÎN}=¹¤;ÀÏ 1È©ëSÙÙ›ÉÖ5À9ê;{ý?úþÔ€tËráUKB€£9?…}ëû/þýðŧ‰> Ú5ä×J. ²fÄhŒˆÀ2Œ‚s¸s^EðOöqºÎ•ªßÌ.ms½`õ88Î=+ô2Êw†ÆÚÛjˆâP <+æóLd¢Õ*NÝÏk A(ûIoÐ];á¿…<#¤Çeáí62ÍB.Ú rqß\wÄ‹û½/N˜ZÁ5Ú‘ŸÝ)-Æ;cÒ½ÎÚ[üF€ä(ã?…jÙèHÅ€ ÙþðɯœS³»Ôíæhø@ð¾#ø¦eMî2„Ži—j¢dÀãÜž}=+í/ƒ_±O…¼?¶©âp¿zîáhmî’ÜÄ>ð*¸ü=Çé]Ôh!„ ãiÎ¥{QÅÕ«û±]ºú³Í¬£ÍÍ»g;«xB=>ÍdÓ#`aèŠÜ3ï^;ñcâ®—à­Ü^\,emÎåq‘Ôs^«ãoÚé:TæY _˜1Ü;vù-û[|^Ÿâg‹m<5¤_ƒk™.–9z°Fx.zq޾·GÕb´fn0s¨ö:_Š?´uÿÄB}/AšERLS]äå䃎¹8çž¹\\‹hRZèvÒÇnÑîPKg$–'$rGnœ÷â¸-;áýï†,b–ÊìÌÀ‚Ì™ œü#=@àú޹®ë¾)–êÝìo”‡…²àméœs¤ã9õíšû.8xr-.yxšÒ­.n‹¡‰)’ý^GMÀä3ŒqŒàgrz}3ÆhDv@Qä‰Ê’¿6YÈÈÀÇáŽùÏ+Ú»Rhî_ì jä~íÛ'Í^ã¦= ëÎk™×t™´ÈÏšw£‚U†vúc¯ôëô®·ÇBžÞ˜è>•ïàhiÎúœµªYZ¶¦Ñry“ËßÓ#ùì=G¥b¬»_ŒŽzjS–˜–èÜôäûR*e°2X„cõë_GË¢>f­WVWcF$Îà[ÜŸº?/óŠ#Ær•éÀÏôöü©ØÜJí\äôÏZUåîÀQÁ§Ö¨ÀES#rù##¿×üúÐ#ã  ¹4Ü›ÞrNÂÙÏøwëÿÖ¥·¯AÛ¦q×çü@ÿw/mÜdžß^´…, ‚sÔv÷¥ U7m'çm!aüY\zÐ1’*ˆø$íî;þêqN1†Ý^ÌIëÿêÿ i ·åùTdd?wÈAÇCÓw=¨;Ÿzgn8úc¯Ê…}¡€ÜzöÇ?þ¡F6åÒFIÏôÅ9‘Tî'ã8ù÷ CpÉbA$à?ÿVhÆícƒì)ÅGÈAÔàäsþ:>ð‚@ÎsÉô S€HÎW€)‰–`$r AéŸÂœ V!ŽsÎIûö4èä9·8ÁÆ)·Ò»8ýM0†Œ$ŒsÅ:dò˜rCLf,I'$Ôƒ¿Rݕ̢dŒ3`ð'½D÷S¬ë‰™N %FOOÒ`™—Í9ÙÌH¨ä”ɼŸ™O=9÷÷ëŸÊ’ø¤¡¸™¶`È~qÏ`}9¦i1¹ÝŠôRr>´²•@>`¤sÄŸÀÔf@C(ç=ªÒFnR{°# Æïjë>øŽMÅ:j<…mÚâ5'Óšå7†ÈàLúsS駘\ç&>»…L⥙¥9JM°Ÿµ¸.t;•¾gEùûUkÙõ -_E˜½ˆbGÌ=xí_,þͺ£]h:xù|Ø£Ž>rR¾©K/;ÃÒL’™$çàc×ĸZLú9¤šgÍ^½–ÃÆúœjïFW,Û€x{Žä ò2ké½Y–M*H–FÆÀ˜ UP`¨%²vŒ°äà.sÆF~ø«ñËÃ_üutÚ…­Ö·«È¦Xôk)L¬Ú$‘ò 0 ’NàÖo¿Œwñ]Á£_XøOO–³½¶›aîñåÉóà˹ˆm¬Ucû ª¦H=0ËëbW4U—vg‹­N+•jÏ×á$p[Úæ{©Ç”­°¯Àl£É…9êO íÖ±µ­;L¹³)u¥ßÏ$¬ _4‘n…A]ŰJƒ×AW·äσࢿ< 2ãÄ–)Ž4+öi1yG€2ç|¦M¼t#8úágü7J¸ccñ;A[{å‘£‹Zð¾Ÿ,Ús‚NÃ9ûB.Ý€`9,Ç*€ +eµéÆñŠví¯çú%åååÂq¾²kð<#ö²°°±ñÆ­–Ÿ¬XZ,ñÉk±qÞFR(Ä…öaT34Œ¸<£d`p(x7Ãßð“øP]Ûƒ$jÆÒI<¼…Ÿní„‘‚ÁNìÓ°kêÏÚ?á§…¾?xf_xWѼA-»$R^h·Ï9 ÆËbŠì€~ö2|ðoX¼øuñ6x†ÌIføGõÉfR_*lF–ê‚…ÊžQCpéÎ5)r­>‰EÚ3†º?Šl[L¸¸e‰£š?ÝOæ.NâÀnÆ0 àútñV¬|:Ú­¼ñ8e¹„(dÿT~nH'§çœ0í럼 &¿ypÐÛÚhwÖöÒ\O²2Xˆ@?êÚBí !þ]¥Ü·ÊKsçž¾›Lñ-¼Z„Ø´¯å¸¿Ô:¶'p$’0A'@àõé…W(]nsÔ‚[­¢Þè××öw‹¸.­ÞÖQ$;‰#"xFç°ÚzpšÅ»ÙyíÄ)3¤Îw!#iç$ôïøŒ×Ö¾:ðV•ªY&­§\Ü\*òíDШ$˜Šìæ<íç¯ uâ¼+Çþ ¹´FÕ _èLO$XfRHÆTô›¿œçÊ®mÚ fùJ!n¬lpNO#Œý{ש…Ò-yœ8ˆö+”`>eOÊ}ûÓK¬H€±|ÐãŸÄtëǽ=”¢…Áä`äuÿ8ÿj‚Ѿ…뎜~½kÐ8,Á³ò}·øÓ”–Ás§’i‘‚»ŽpØÈcÆ…`H% gwQþúÔ ÃXóœÞƒŸÖŠkª4K–ùGBÇúÑHDÁŸzŽrAÛô§ðÇc8cßÿ?ëQº4Rl‘ñØ…nŸNÔÏ™]HáG `sBؤ^³²–úá`‹ ±û äs^ýð[àÚM~—i$ÄŽCÇòŒúzž•æ_þjÿIçλ¿èw—ò£»î^6ªöéŠø©IÊW=ƹV§U èRM$rHÇoLc=«Ðô¿¢ŒarÞ¸;h/t·ýÛaü u®ßAñRG7?¸“§$úwôíZS…Þ§[™+£¡H–Î-˫׵rž"ñ¤P,§ÌDDÉ$œ{zS|Eã;H^Xb›÷…{ƒƒÇ ñÇZù“ã§ÅH<)¥Ï4÷ˆ‰ä³¶[àäñÏoóÖ½H§&£™E½Yæÿ¶WíáËt)â{»ÅaŽäÅLg8zôÏõ¯ˆü#àk¹ ß^;‹â|Ò¬ÊÅÎ[h,ì:öÏ~µÕB×~;×®½8ëôâ ÓÄ‘~턌ãQWåuÁÜÙ'‚2¸À%½WQ+=N'®¨¿s!‚É­Üeв€è§ÛûlÖ=î§—q<‹uúÇóåÆ%F0NAïÓ¿{éÚÌXº_*y2ÆSŒmì8=°yÖ±õ¬SÌ-ãŽU;S c`ARAßi8Çlçó®[ðì¶{ü耗p;gë‚qÏãøÕCú…•ô·Úb’&ùãxl‚F@lîÇš¹¢øêßU¿û6´DRÖ&šL“÷° t<·^çÓ5=%¡¥ÚÛc“)$ wî¶JŒ?B:{×mà?Š:¿…¦mͶRd0'§óÏó©u ‰DÆ9 ãÐ) >üõ'¶{×%œ–&%rÅߌ*°Ý»úšÊ¥8ÉrÉ]ÆvÕ;3î†ôoB‘]&Cû‘ÔŽ«èµ×øŠØÈÁ÷’¤!,0n¿Onµð †¥6“t“Àþ\±g8eÈ9ý ï~øú|EºV³2Á$+û»˜ø,H=@‘×ÓÜgå1yS¦Ü¨êŸN§µ‡Æ§hÔûÏøï¬Iuã;‹a3L€ýÛ—=AçƒËr:?&ÖÄH²‡èO${úµéž-ѧָÿ=©à€T„'žØ§OsoäHN[û¬O?òªŽUHU9^ÁO~+Ñõ>zÃæ@\àî9É9ê=ºÓ\ž1€ùyéÿÖãõ ´¸w$öéÿקˤÐusýÏ@@¸Ën;…Hçüâ—i*2|Æ €íHÊûF8ÇO~ÝéÊ%¹ÁÁ\àý?ùÐ*°vP2ããŒÒ™†â ŒòÌ1Ÿ¯åB ÚÁ nÛw*+€àò?Èÿ?ʀ܇ᔕÁóÿë 8Vû¡ƒ/˓ȤXÈ Ú˜Çéô¥VÁÀIašvAÞãsˆÇf ’iÒÚ¥N¯¨þƒÚ¢Ú#ÆK'¨ÿ…mäöéŠA`$•còýîqŽ î$d/¯§ÿ^¤Ý¼Œ°!GROøñÛòéQ7a¶àò3ŽŸ¯­1“'É´.A'Çü©­‚ØR>VûÙ#ŽG#¿åMP8m©ŸïÎÞ9Í=ð€Œî$äŠ}È¢Â”í €ÉèFHü{õ§£ÄÄ“ ãøKÿ< ¶<Ð1Ø þtÒùp‚1€)r®¥\±=üaÈã˜ãïØþ­WFŠ‘¼ÝG§ZV xÜ3ŽqÿëüiñA-Ô.\ù'û{š¶ÁvÈÙ™Xn«—ÐðGÆ? ü!‡@“\ÖŒ-i Àµ‚6™¶â}Ò9Å\øßÿÕE¤ZÂDŠ+c ½Ç‰uVyÖLŸÝA Š0L¼ØÉøˆÛ"¾ÐЧ’zSü©!$àއ£{× <¾”%Í'ÈœÕ¬I-ÄšÕÍÝÍÅÆ¡ªNÞl×7R4Ó\9þ'vÉcß$ö¡#ÚÂW˜ª rN0@Ç·Nã=©€†Bœ‚àrOqýO#§/•G'Ž0{téÇÞ:M+#“q ¼¨›ªº“•a·‚@äp{ò?…­ YQLJsÄ@@W?­LÊÛZF ÝW9Æx?\óéëQ5³*;¡f Æç¸n¸=±ëE¯¡%­]ñõu/ ëWú¤ñ‘%Þ“tö²H©Ã€ppÄŽ•éÞ"ý¥®<} -¯Ä i¾%Ömì– mwGÛ£êû†I4¡)B mAd¢’s»w”³ñáT"ô0 wÉçsíÃPC„ÞrN6œ8c§ž¿Oj穇¥Q§8꺚ӫR“½7cé_‡Ÿ´o…h7F¿Tz+2¬£Ë(§êŸèÑô…~!jÖW7 ovšÊÄÅù«2)²1'¨`g†=sVu vb+·±´´²Šì¹Ó¥Œ<2ÈË Ž¼·Ëœ6Õô¯œpÖÄL`häO=z“ØœŽ‡òÍZOjz}âÜ­Ü™cÁ•†AÄ3†=Ç÷®j™kR¼qÆAüJÇAâO \xwZ—bî…‰à6ß%\¦G\ß7°=1ZþÔNŸ,Bå []È äp@$ß,ù5ÊÛø¬\ÃåÍ6îpø GB1øtô‘Åt÷³Z[\ÈìÑÌ6Âd?xŽŸ6yéÈïëÅTã.UˆÞ2Ö ô»sõž§§Ü C$LdwBÆ;ä€gJÎ¹Ž ÝFñ¡UŽòd „Mì<»žÇ¯?Ã]R-^;xËÇè¿d‘îY†2Ãk£ ¤à¼ž&®_ðÝûʱCpÒ8ÂÜ/ÝÁ<ƒGËùúµy¼Ü­®¨UîÎÄðç̓:ÃgS ”eÄ»álÎ2GøçÎd„Ÿ•Þ©a€[¨ïïôãéÒk 5–«}y+¼’˶Ei²¤îè0yè¸ÁôÆqÓœ»¸g–v+ååˆ9ÚOÏžyõ×±F.)$`ÚÙ™òGµCm @#È8>ÈÒÀ³Ü)ffQÙïÀúWw¤Ê.¦‰Td·9ëXz¬kk¥?Î#t;V‚ò²ÄíÈ|Ç·+áë6îßSë)ÚöG¶ø[IG‚5•Áû›¾oʽoJHô»eòÈQ¡G$œW躑†U•Yyçµw¶þ'Y[ +0ã?Zó$ìTâäw/7 bá[¦rEr~1šâÛN’h÷G,`p½GL‘íÏzÕÓnšê âvëÊü£Ü~tÍf)/­$Y‚6·R?Úœ›ÖÇ3“tߌ÷w·š–£¨\GlblÞf#nPÎ6ñžzŽÜ×Éßþ#ê_ËÓž|ïâ'„ ´ÿHxUÔºhAU°ûÞàuìHÉ®â+«KDû]¼j€þò`ŒlI#ŒŒ}áQêÖñÏéU¥aJ€ “À<¶xϹ«•š°E´îy%†­âÜ%Ì;§´P~Y™Ê•ÁÃcŸºAŸA]v‡ãm Æ;-'Ûcq’¾K°Œº¼œdnÁp¹#&µf²‡Qí8ÞUZD•3‚¹Ï€:óÖ¸¯ü7Ó–ìOa$ö²†|À\®p»¶€76GsŸ¥`¢ãð³Gizš¾"ðœÖbg‰7Ä­µÝˆ*F”\;åwÜiެÈQ£äªbzµkHø©ibׯm@%¥˜–aÌ0ÎF‡Œ÷Jêu ;HÔ¬ïI“Ì™ã,c®¡‰<ðëÓš\ÊZ¥©iµ¹7…|kb.à]f1¹ ,áGȹã9?\õ=;WmñKÁºbøn fÕRh™Cï‰÷€ $އœç±Íx^©öAÌ‘ùNGréÁÁüë©Ñ¼ms{à÷ðåÌòyLHbc„±Ôž1»#ûÕåUÂóW…Hnž¾×âwB»7±æZ–šÏJAWPK*ðpÓ¯ÓÚ¹¹£IЧa^Ÿ&—½Ï—$EÈÎöî#è}þµÂøƒN’Îõå8X$%¤ûŒòk®¤,r½L1€p2võ9è}1ù~´›¶° œqŽ;ÿ‘R:ÿ¬1“’sÀäÔ…rÌ6·q*1€zιÈcbQµ„­Àä•?6=³ÆsDd»…+9^GOzcØÙèÀóô#?¡4åcaÀ‘“ó{P l˜÷Ôds“íøÒÉ€Á~î8ãüiê¸(å[W9¨Õd#~3ž#Œç×ñþt sª¼€…m 1Èõ?—åH„d„®0Gpýtýê#ýábáHP¸Á=N}ºûô¨ðåG;OpOOóþ4æ 2H ‘‘žGL?QQǹ¹'qÐàõâ!Hv|g€xõüóOi:F#%€Éö4Ð PNÕ< åˆëÓŠhRƒsŒõ8ïøý­;‚…C€;òM4)\ƒÈn¹¢à;¼ Ç#=1C8e<þþ”,fR±ÆI˜€¨9Üzs^õðCö5ñ¿ÅÙc¼ºµèŸÅ-ìrE,ƒ AŒ ‚‚} aZµ:æ¨ìiÓ•Gh#Áíb{«´³1áK1éÐI¯MðìùñÆ·ñÛi^ÖÒ99šŒ°À:s»õí_¤ÿbÏ|3|15›þ¿oÕbŠy”ó÷[ËOjú+Fð¶™j#XÑG@¡G¥|½|ù'j1ù³Ö§‚„Uê=|Ëtÿ‚xüo6ŸiŠëÁ«¾È.nD¿L1ŸÇäþ-ø+ñ;Â72o|:ñ,Vèûl\ÏàdÀú×íÌV;vîŒ Õ‡ÑaÔ x®£Iá~ N¡”ýAÏK;ÄßÞ³*t(¥§æ~ÚK‘ü…ÎT•8ÏëRT§w;ž¤Œ}s_©Ÿ´ßüËß4ù5ÿÛYxgÅ«¹³·mìn¾PtŽ2weFþóz׿?Œ<¯ü?ׯ4Oi—>§o##Cu Æè©Ç¾+ë°¸Êx•¦±çΟ.±wFT±‚Ñï#© Ó<~T(,Â5˜)Ü«’Ù$c=@ã ëØSÕŒªT,ƒœrpjÌL˜P*Ëœ«óqíÅwõ0mÛz©_ݱÜLã 嚉î#v;¼ÈËt^èÏ¿>ÕbâäÇm”œ—ÂäªõéÓò¡"YÓ’@uwáyÎ}:f«NbžåÆ5<Û¾N}º{Rà;v?ÀüyÏ÷ÈõÎr;™#,FÐŒX‚%^«Æ{s’WõõbR!@_-P»6ÑÁΟ4%­…bQ W’8Ú2Šäù»p0¾äýG<ŒÒ4Ù*øù|ÄË~?äãØ IPÄ’‰7Æ€‚Á9àñøþ^ÔÒé¶P¤Dàñó=ÿ)«¡+”4ÇcŒ¼õüi×$y*Á”|ÿ2í…<äç§oñ©Z5“ÎÎÜ’§rýÁÀÚ·<ý G$BXÙU+nRƒž8>üôúTìµÌ]§•Øän+ó×Ó®H˜£ •ÁÎX£ãÜOþ·Ðµæ,Qv‚[<í'8<úçùS%IJ"ef•ö¶0O¯LŸaM5m@‘ʱu’7 phÉçóÓðÍg•*À4DÁW»d}1ô>•jX©e˲aØ€=:Õ˜ç‘-< ÿ¹‘’Y‘óêû€ìç÷¨µÞ¡¹ŒÑIg‰<®Üôãð®“BÔ~Sl0Ö¸óÂ0åW¼sÈ'ÔšË >rOæý2~§µVðÝÌvúõƒœÌ€2>ín¼tã?L\˜ŠjQÐé¡W‘Û¹é6¸<7«4ê×1»’¬amŽxÞOrdc¸éÅ{¤:RxãKÄZ“jСpe” “pÀ*ä”vç¯$d×ÍzõÜ:eÍ›—ó<Ç,ë+Ș`ŽÇrõö5£á¿‰÷Þñ\LÓ<(W ~a«·?;oûÀœ)Œ‘Þ¾~¾¥H©ÓÜõ%R³z”üm§Üi$F)Àv ¨¹9ÈÀ÷äy®DÈ’ ]p@*3ƒÇ¿1áÖ¾ñ†•§üMÑßÄ:T çÂŦ²ˆ(1°M€$|„Ø;›wCÏÎÚ¾˜Ú5ìÖÒ[=”‘³Äö÷)å¼o»AÆÒ2>•ßÄF´yZÔâ¯y=}mÈcâA\ Äò8ÿ?çèà‘ÏÜ;°H Iì1øÿ…YdP’yR0àsœ÷ägÛÚˆedŽFܾo 3Üzõ¯JMÇSšœc=ŸäJ0HaÎrsžâœSc‚…ÍÁÆ6‘žÿÖ´M»³®×V~\rqÁÏãÀÏO­ :=qÆAúž~•æßWó3M¾õUÆÒr7Œt¢·í-É|ǘËÇÌ R?½¿*+7Y.†‘Â.æ '’Ú¾ƒø)ã$оÝY",rùÀ–ÝÔ—oÏñ¯ ‚ÆI‘q"•' rÞœŽÇ>«µÑµÒô»DIU£Só¢sózvïS‹Š©NÌÇ ¤Ûò>Žoµí¥¡q”1ù»úWk¡^ÄŠ²Eò@ͤ“Šð ßÐí»oEÚÊF?•ëÿ®£ñW‚ÅÅ»~ø0¹ìE|¥jMFì÷)´Ùë°ëN…<¹Á^¸ÇJëü?¬«ÖŸ4wGÎZZ[ƒ)’]·b“ÏpyéîEkÃ{Ž¢"g˜rŠÇž>SÈÏ^˜õê+™°[ ¬äB¶Aàõþu« ȆX°R(‘‹yN¡J¶3ÈVÀõàž¿—ÞÇkž‘½—É‘<…YafweXääíŒp9'<œòj͸ž1²MÒË&æÏÍŽ˜_”8ç¯ÿª©y™4XK–IÑž,¶TÄnf+ó ÝÏ¿Ný«ZÐ!×´¹7J$\©œz`§QÛ={þYÊÓ^¦Š] ŸxšÃÄ‘Gî¾gße8?0Ç òŒñ‘Ç>çWÚØj‚hÏ› À3ß¿QÇã\†¥á{½ïͶmÁã$}‚nøÇPO¯SáŸØ>Åx¨.d³Û¿\œg9Ç8æ°½ß,mm„×¥Y¿|¥šD䀃€<÷8äž§¿<ÑÔs­Xƃåp»™GCÇð3ÏzU½O΂iY–9{>#ÜHRß{ 1ïßðý¼w73F‘³ÓœsÐsÍVì­7Ôìf°¸!•¢Á  ~µNP€ØÚIÏãŽkÓüIáu0’í‚Ncb g õý+ήlÚÎá†ñŒÿwÿ?Ò¹gV'®¨¦ÁÆ2N@À-ÏÿœÜp§p8Éëíô¥àÙò¡cÇ$þ'ÿŸZn2pJޏàŸò+"G.»³c cœT`n~nàgüóÐþg¹b1Üý)SÏ’ z~´ÀQó¨àuíÅ?p8ÃU8<ñõÅE±N221ØN´¸dŽÅ! §?*ƒµºŽ™íÓó¤EÉ\sÁïI8çÒ‚BžIÀþTÆC3Ú·¼à-wâ.µ•áý>MBîB p«îXð+Ò¾þËž#øÝ~²ª6™¡FÀKy2œc8O_οNþ üÐ>é)c¢Z0£Ì”ƒºCêI?_μ,vi *p†²üŽú8W?zz#Å¿g/Ø‹Cøy-®«­¯ö׈ÙåLGùg >õö…áä· Ç„QŽ1[ .Æ$ã'ò®Š+/)W9¯ˆ«V®&§=GsÔu#MrÅYìtèãpê¿.0¥ª©ÉAVc²P¡†}jÌP‚2F­tCúž}J×(}‘Xð3íR¥©Eà¦jòD‘ §žh…èÝë¾8d–§;ªÞˆ†ÙoÍ×Ò¼cö¦ý—´/ÚGÁRÚ\F¶ž!µF“NÔW;£p­€F@+–èkÚD€ ˜š‚kÅŒmÜ:rIÎ+®Hѵ˜.nkÄþ}þ ø#Wøkã=[ÃZå»[êºdÆ)‡ÁáDZÖ/ž®;àsü äú³ù×ê¯üög°øµàÇñ‡‡à_øLt…ó” ¸xÜœwdWäÒLWA×­×ßükêp˜•ˆ…úõ °å³èÍO9v´ápT.úôëÛÿÔ‰w ÊKó#‚AëÔqÓƒïÒ laŠgiÜzîïõÈ1¹Juù†ÞÔý»îÌK’´¤äF±±uÿZ Žž¼^ŸZ’_1z2¹X£ ’¦3×ùr SyƒU<—çi=þcž¾½?:‰AW09ù_ÀϯòúPÂåÍÄì £8 Np@ç¡ÆG\t¥3¶Qw‚\‚áxûÿ^*»ÈŒˆv¦p ŽyÉ}{ûuíMŽHà—ÍZEÃH'ŒñÇ?XÑ™¼ÅQ¾MÄ Žü=nŒùÊ#¡.À’! ò=;¾þÙW»”¦A…þÓõçúz jÜaLŠÅ›vAb0ÇŽzsÔþ”´I‘F »\³|¸qÇ®}qÐv={Gç°$žù# çgéßë²O¤Ã¹‹).{kÝ|+ûäTÆ6†cœç¦kâ±]98ŸGÝ]µàõF—$„Ÿ˜ðs^©¤ê&ÔÇ ;Ààf¼_A,ˆªÅ»`úâ½?F(ñD²³y„g¯Jòe£Vã}YÝE$··ºäž渿éñÉbÑ\J‚2¹”``ƒÇ>À×s iìËå¡g‰!@Îp3ü«ÎõKñŸX»¹Õ®gÂ6ĤVÈP]ÛY‰R­ÈÁë[C_{cŽ3Jv[#à/ˆu¦âË›M>â« 0ÈbpÃîv•<“Óÿ­\ü–óBÛJ…ÚvïUÇp=:WÛ¿¾xQìZ]ÞÐG’F¥HÎ=ó_#x¯AÔ¼%|l.Æô^RQ›€O®85úW™CF__üÈÆa%Nõað¿À´AlŸ4"G c“ƒŒ p1÷LõjåõèÚ 8RÈ®…d) ð x9^£¦àbÝË5²ÀNAv0ÁÚéŠÐ²»ŽIRA“–õÝœÿ/òM} ìy-u$ß#£#J¢7A Æ<ç<ñ»×¯T/6ÙÀ¸¼Hw©\Ÿ”•=øÉ9ÆxôàzÝž8…—ËŒ3²˜BÝœ†ì{úƒïŠÉe†'ÜHE% 9#'œ“ÛŸçÞ…«@¬mÙM,¤I1vòFÕv<0n22:ð{gßÒå•ìV,è_ÉVQç4A8ã€Ý3œ÷Æx;sãɧ¯•n$JC2äq×r@Í ÒÃ+¬ÙP Bvä òœý ôõÍ5Ø›\Ó¸º–;¸ü” `AÛµ,v3ÇQ¼t'¨Z6ðk¶VßhG†éÑvJ2ªq×$sÉ\þœô®z8Æå$ÛåÆdXJ† Èàœg¡ÆCÒ§‚ï컃~ö=ä­µ€õõþñàúúU_[1X´—J•Ìg#î‚p¸zO\zôô‚m5dÔ\ÙÅ!I]AhÔfBp3Àäg#à “V¸—Éê‘%ÛM¹¡˜œm(@|¨78ëéšÅV»Ón¼Žb€«ÉPW׿"¦6kÝØz‹q¤%À1M“‘Œ©?!À#žzœW%¬ü>2JÓÙE³ òùm´“޽>¾½O¦k½ÓC¶aËŠ¥X×ñÝŸ\xàÔ«tg" S½ƒ0áN9öã×Ö†”ŠRhá´ÏÜ4'íq— ²7 ý?>­½7Kƒíq†’xð0ªzÙIéÁãŽÃ¯ZéoI‰n@:¿);yéÙX·ãÇ9ªv›·¢yÑ—ÍÆOnç>„~˜©µ´5Èu >9c0 9.ª:ôn§$sÓõ®GÄ~†XŠ»aÂnËdŽ $ƒŒõüzžk¼{Uv†èÁ, ÎIÁ,r{tÇAœŠÇº6ÉyO€Óœª‰Aù}&i[P‹<6òÖK;–ŠLo^ a’ €º²ç*ÃøˆüëÔ¼Cá´Õ¢y¤‘ÎÎxÀ8$töÍy•Õ³ÙLð¶‡Þtú}x®9Õ–ÑB*Œr@8¤iùN0xÏ1S´îNÄŽi,sœì+1!X¯¸=»iRǃØÒ2Aúæ·|àsâ±— Ù=åãðT0P©,@ìje%å'd8ÅÉÙ-LT‰§‘R4gv8 £$“_YþËß±…玮­uÿ[Ëk¤)W†Õ 0°È#¦ {—ìÕûi^ êÞ,·‡XÖVHfL¤ <äÀçö~…áØl¡…c‰!Š<,q¢€ª00+äqÙÂ’t°ïNÿäzô0ªŸ½Ssðg€,<9gocaa¥”*¤hcí^‰§iÑ"íØ@Í]µ²X²dHÀëZPZªvSØó_0©ÊRÔéT2Þ”làçf´"·tQ½2Ät©a·røb 6ãéV‚IòÊàsÎyõ¯N·<Ú•ØtJêJ±g®jCeãŒÕmì€ß½Î7zñéU¥Ôc(ß+àöú⻕HAj`¡);¢ä· l‘€:úb³.u/$037¯8¬ëÝe7œ¾ð£æ;qÎ=1\ÜúÀyU•ËÂA!ÁS®Œô(ᯫ:;ÝaÑ‚D>oq€+6mY¼·&Eio˜þ•ÌË®HÒ€dÜÀ×5^{ÖÛûÀ`t®_jå¯CÑ^‡Eý¥ Ð4Mó«©R ‚~½«ñ×ö½ø6~ |dÕ-m 1è:™kÝ1Ï÷p¾bÐívü˜WëwbØØÂœq‘ú×ËßðPßÃâƒqøžXÚ}GÃ2,–ì ±O<1H£'¡ÈnWךö2¬K¥Z1{=>óE$àÒ?4a ¨v™ã={sð§áUF\¾Àc>㿱ÇåLóüÄ‚3†ýü5,òÆÛŠ9 ;g8öþU÷g‚0“+’í³ƒÀ` lséןòRVR2»|óêOÏ¥™Äl|̪|¬ ±9ÆAèó2ÊÁ'œŸ§b„?~ØÀåI#Œ`ÈÎ1õü©¾~è㘙A8,þ‡ò¨µù•7:ïÆwmÈ#ŸÓŸÒD¤+JLE€Úù²qúdšw}Uf•X‘…pÉ${€I?þ¿¦|€áŽéß$ÿ‘ôÍ@DI6Bª»˜‚¬ìc¯ãSÇ"0;¬Ø¹^N9¢ì`Jeð #þ|ßPO©’Kó ¡vƒ°ägð>Ý;céQ¢J¶å ÿ* “ÀïÔuSþxšGYd`Frx~ƒ®3¯óì(ÈŠI*©´˜ @êÝ?ÎzÓL^HR6« çhÇ9äœúžiѨ6=¸FfÞ§p8ô:tçôâ£?–îGͤnÀ'ŠOk±z‰€Þ$•éÐv=sŸOjA(ŽET.FxÀgÐvþTŠò Œƒæ^I''?ç©öä ðI¿i8ÈÆìñþu7 Áܤ–Úƒƒ×õ©!òÕòWaSÁÛ¸þü¿Ç¥=¡1²|Ä’=ùðæ›y–ãÍe·Vs’?/~*­Ü:íeØsœ6€Æ:g'š…¡Ä¬¡w>2FAõÎ=ºþµi—È]²êAŽø‡ùÅBï»æÉËcÁöÏ~Ÿç4•‚˜â*O9$zg<Ž:ƒŠc¸Ã€éÜŽ£ñü?_zrdÄoçŒËúþtÄ•‰X÷„žXŽþýÏãýj[[ÿ,´”owdžëÔàãŸðªÓÂriÉãàuúcŽJ˜d*ìlŽçgÿ­Ö™)R ÉÎ>¹lçùRzî"³0g\±Á”ÐÑDçÊC’¬Ž}ÿýtT2=OéŒ WÍß·ïÅ;ÀŸ³OŒ´†Ôm!×¼K§É¤ØéòÌ«=ÌS2Ctñ)·— ÌÄ㔩e5ôƒ0¨¯ÆÛ/ö…öø·uy§Þüáé%Ó´D{PŒ`—“½‰ó^2AùA!Ê+'*Qæ–»F<Ìù¦ûOT¶­Êœùc·=O@=Ç\;ÅÞÒ£±Ç¶8þŸ•tú”$nÍÈÜ@0;ûcóÓ™¹$Œ€ò0tœûqÛß½u3­êzGÀÝhG4Ö Ÿ:HdB_B8c±Ï~õô‡‡u/³F îÇ9·ñç€oÿ²|Ug ÊFí´ã§==3Í}]¥9ñ\îRW€y {WÉæT­Rén{øJœÔ’ocÜ´ ¤’Î&VÚ ŒŒtàW¤øU'Ôom­là{Ë©ÎÔ†3ËOò“ÐIé^càÍZÏP±„¡•@`N; äWS§üb´¼·ð¤1_øëW)o§]ËS[é±ýü’.õpÅ3·†B–æyåÊÝ—s¾r’¢®ßõ÷Cê±Ã¥[]xSNnõ{À©­ÜÆ X-ÏPÑñÆ+ï8Ü™¼¶æh­aˆGmX¡…p6 ^À~Àü:³ohpXý²ãQ”¹’[«©šêâæBwovbY#æ'<­w1Ýù ;"ÞT³3 ú~~Õ.jOÝVKoë¿VûýÇžéû=7}ÿ¯ÀÊñ•Ñ‘L˜ŒäœšùóâçÂÛ/XL[$\²°ÎTãƒÔWÓļ…™¸ 8-\¾¯¢[ܯË2ž>•Ÿ´9ªvhê¥$×,µGæWŽ>êþ¹Íg,–ÁˆIÂŒϽrºcƳ!”‚ÿVÃíŒöïé_¢>1ðEµâ´2Ù¤ªãdwö¯—¾)~Ï×Q–ÿB‰2K=»ú`}kîrüî5š§ˆÑ÷èÏ3—¸®z:®Ç”<ȱŠGåt_Ÿ'ø‡B}±Ò˜9#òÊÆ « ã9Æ;œsY—‘β½Ü¬˜ ¸> p}=øÕvÅYÊV(>|à1 ‘Ç$œw$ãë_\¥}Qá5bAo-º¡\ÎFèÈäñÆ3œ{týišÎÔxÔ¬“• ìe#nO×ùwéVÖ ¯´äÄ»‹Ž;[Øp8úÖeíœÈeo1†Ca sµ¹#Ž $gg­6ôÔKRÜ3 äŽ@‘™g¥Œ›@ rH>äŸÇ«,š}ìqÈ$Š<¬¸ÜáˆhêFp3Ó‘Ï5—mÜm»ÎT‚zqÈúþMlC$æXÐD²M‚Ä.Êß{${§SЃK})èÈ®uOí; 4»±²»J±,Gnpnjº^¬³›-Ež'Ê̤mÛŒ¹ì;ÿZdv($óÉp¹pÚå™Çý©ƒq§¼3 gX£ÉÈ|Œà¹Ç˜JW¾èh¿»Ûݨv(bceådÞ§¯êkVß4ÂçrwŽÿÇ@®oOÕ7ªÁrÎdŠO–^OÊGϧò­‹—™Ì{ *rT ¬sôü‡ô§ ’}u,vŒË.ÅU;†àwœp}€'8ö¬¸›å’Hx^¾øééÇ?cÄ“}–ÁŠÑ}Ü»8È=¿N½¹˜Û£f ÃÙrsþ~¹£íXká¹b;¶Xã‡Êëß0’‘œôèxÏãNóF „)s¼’1ž¹É¦Êä,™Un0qÀÏ·Ò£Òì﵉ZYnåqŽËçéIÉFãI½ŠHŽ¿œ(ëïŸé\Ÿü$÷qËxH‘8+žO<ž¾õô/„ÿfox«Ëš[xtKl†ÿN,e=û⽿Áÿ±îha›[¹ºÖîvàÂp°gÝÆqìMx8œßAZR»ìµ=x*õ5å²ó?3´½'Rñ÷Ø´» ­BëþxYÀó?ýò žÕì~ ýŒ~)øµ£kŸK Y1 Üj/7_ùæ\7ò¯Ó ü/Ñ|(²G¢è:~š_{;d‰»ÿîk³°ðÃÝO¶C»Ž‡“_-_?žÔb—®§£ ºœ~7sῇßðNí#O’9|Q¨K¯3`˜"… AÓŒ¬‡=ëëÿ†t_éÉm£é±éöÀ°źõ%‰¯GÓü(¹ùŽâºý;EHJü¼Žp{ׇS‰ÆK÷’mÉÒ£SV1ô¯ÇnNð#õüëvÛN0Õ銽HÊÇhR£$`dSÕx?7>¼äÖ¡óGŸ*­‘Çh<Ð3·h¦$M¨2\nï\ÌÚÛÊ$ŒÈRzJÏÛ©v,3ØîÀ³©‰–ÈÚ8S ¾×_æÚ„p§ëŠÀÕu„ˆíVä‘ÇqÅ`O­7šä°=úóšÂ»×èÈ ™ÛÏšã•G'©éSèô:+ýy0À”ã“ÜÖ,š¿5`ŠÙëýkŸ¿Ô¼˜Â’ƒÆ[‚=ê¬S–W‘˜»Ê©â¡]»³²4ÔQ§.¦b J#ŒôlŒÇó¦Å¬Æ£Ÿ1yã¿Ö²­÷²Êzôâ­Ä¨d”‘Ø‚€ ÜÇŠ®Rݶ.Årò.AüDg?…Tø±áظ_!`É-òƒ´õíþò¡Ú‹æŽNÇ|qëÜâ-²7 vrG<{çn2ihÕ†P½÷ˆTÆG§ÓÞŠ•# ‘´í Š\ªZÑû%ûH~Ó:߇~ëöñ´šg‰¯Ql ¼Ó&h¥Œ;…‘ã åa`®¬ ³~T™B"¤c1  (\qìž8<`WÓŸ¶>´öÚž¦C3Ëmk½ÝÙ¶|̓‚s‘ó{8ùjævƒ.²!* }É€¼gž>§ÓÞ·”ch«A5¾¥+éd;©sµw3ß¡Î~¾Â±öo`ÊJ’p¸8ÏF{þ½êõäk"“&Ò3ü$áxé\ÒlGS„˱8“ÏŽ9úVoW¡Òf²Ë ‚dsÞŒƾ¨øâµï ZJH¤J®ÝNЋ“Œñæ¾Y¼Pãs ±Œ`‘ßšõ?€Ú⬷zT»8bÏ JCŒsÈãæ4¹éó.‡n|³åî{ä7ïlè–wF5š?³´ÆIËñ¯DøM§Å ¹Õ^#²¨ŠGÝEÊ;ŽO?Aøx®›­ ï¶Yù¡nDƉ';r!¶ôûߟã^Óá«”ÓRÚ¿è‘‚¤)À<`z÷éõ¯Œ¯Ud{ÔßV{ç†õ9-—düHŽd ’Äà|Ã~½‡Ðv¶k:† QÀ”äc@Ÿç^+£êí,ˆbêÄp Û¿ó¯Mðî¡*üÆÊ·`#Œ~½s^RVzФ^ç¡]ÊÆâ"Cy§%Ðôý?1¬çß¶4êYºcÚ—Je–6ß…V÷¥ºýOnxükiL3D ŸecÖµkš×8”ùt9]KEB•Iϧ5Çê¾¶pw[®OÞÈë^¬Öæá‰'å_“É5®i&ßݱ'Ó¥a%ɪ:éÕèÏ’þ.üÓ½+cáï†õ?ÜC¤xsM›Q½ŒþýUBEä±;sËuÀÎk)N4Ó”’4Qs²Š»#ÖçK#g!”ãœ/÷gôžáèb·THÊ¢Žpª=|†7ˆ¡ 8aUßw·Ý×ð=z9v‰ÖvòGÌÞý4»Öã_¿›TœæQ9 e{–Ç<ñô¯oðÇÃMC´XôÍ*×O ÐCR]í¦”#&ÒOf-[°é®’’±³Šù øìF)Þ¬›þ»l{…* ÷jÇ/o 1îE;º¶Ü×A†Ù"P˜É¸®ŠßKŠÚ9$-ò¨ùˆä/fÆÖ«_2º'îÇ,=EsªRv¹”ñŒh|>d‰#8ˆôÞƒ¶,|:°Çò$Îz~•·e¦ª…¾_Ö´bR•Fòãì¡üÀÌìrçC\î¡w,j )*ĶÓÖ¹¾ç|)¤ô5õ z6•È;q¸ïX—Ú7{µ“sy´Ñ*'ïAäztúZ ¿¹ÎI'gÐôaù×aæy}ÓØðxñŒþ"• ¡¨V`%eMر–ïÓ¿AÉÈ” Ø`1qžüóíô¦°Ø&ÞTüÀŽ8ädÜÓWÜŒB'ï’Ù둌ç9çÖ˜±˜Ð©ÁPNpNNÆn”ÇÝ(!@ÀÂŒ“»ž=xî8õ¤<¶T‚BÁqO§ÿZ€$Ýù¼Ç ¬FyàÂ3=Tà9;‡?¯ù5£0`¹-·ªLr8&Ÿ†Q–¶Aä ž¼ÿúé\ó!Ší ‘À9Çâ)ŒB.rn?Ç䯨 ûð@É8ÀÁÆGn}ª°Ê¶1$Œ?‡=zd}p?ô6ú ˆÍ “?w$åy2=ÁãÓ § Á¨~?‹>¹Èô#ò¨åsÈE9ÆÌ°n1Æq×ß§JR»8ËHÉ$ž}Ç<´kpQ*‘À'€y˜çòúT1>" Ÿ™øl€?:óÓÿ¬ü2£`—àóÏ»ûИ1¹m±ŒŒq–Žøô£"‚9 !ÁTä í9ÿ{‘ÐázàTAÔ;ðU·sžþ£#§åž”à.”d÷3ùÐñ3IeÑøÿ‘ùSdÈØcåb=½qì{…D¦0›‚ma† r;c×¶ivlîJ–ÜGCƒè;ôü}3Nìd,Ø‘È+t¢œá¶í ¡zªï­„{¿í¨iüV×' ±$FÐÝÄQ†3ïÓŽÕæ÷RH,De£v æLƒžN ôéZ(ÖWWñ ÕÐF†I\íœ6ãŽØü`ÉpT%„Gî¡Îsž}»VÒÕß¹QVIL†=¨Pž§epGù&™nUš\|¿yÑ÷rÃ<Oþ¶)Ç|[wd‘„ã±Çðâ«ÌÐH cBsÇ$gñíÒ³ÛÆ[— Ù*8zsþM3EÖŸB¾7hK¡Ê»ÈRA$}1ÅO4‰0B0¼pBñõÝùÖMÌA À] å r}éíYÔ2åcRq|Èú'ÖÏèzŒž|$¬w%]3Áã‘×ÿ×îÖ#½¶ËpÀýöã’M|©ð×Çë-Ý®™v#Š(mü”`0¥FÏ=qßé^½á |éz·’`a'+–úûûׯã0ò[î}-Ši8ŸIøfé ìÌ#V¨<צhú»Ýd6ÀÁaÀƼCÃúÒIaN0x»½Q¹Œ˜ÉÉäã?ç5ó“‡c±.mÏxеKX–'%¼ÅL¹—·åº{m#­uºn®×v° "A ÎxÏþB¼oAÕ±Š_™3÷È˽ÉãÒ»ýî;hЉ䕻Û$ÇÍ4ô9jÒJììåž 3ùó”þµKQŠf|)Àëò“M·¸Š`±•8aó1ߨ÷­ Ê®ÿ!=6î[;ɉYÜæ¯ífq‘¹¶ñÓƒXZŽÒ†ßÃØõë¿kA#’PžJtÅej¶Q—%P2Ž2ã>µÍ(½N¸T³<ËZÑĬQãi”ar¤s××­|õñ“ös·Ô,$Ô<=[j 6¨»Qºð®A¯©õHŠo½ºÃ æ°¥ OÎ7Øòk§ Œ«ƒŸ=&tÔ¥ ðåš?5oleÒå–Öî¶ž5Úñ0*Tú€yúT6+2(v ŒÍ‚£cÐçú×Úÿg½âßÚ­ÑìµÀ’H‚ª3×å'Ò°¬?bmìê÷:Ωò3±Œÿä:ýž…•4æÚ}šžª“QØøÊå¹IœÊçî7tçúSô¯^x›ËµÒ4;½MËÍendEÉÈ,@ÀZû÷òǂt“¦QÔäERb:ú¯ùâ½?Cø{¤hp…²ÓlìUº¥½ºGü”WŸˆâ:jêŒ/êuSËš·´—Ü|eð³ö<Ôî[í*»òôü«E¦Û;Œ‡Ü¸=«ëŸøMðÖŸo¦é–úu¬ µ"·ˆ 'N'Þ» -)!Þ01œâµRÆ4@Ñãw¾3_ŒÇâ1²ýëÓ·CÖ§Nh"¾›¤¤#c `ð@­jC§ª¶äù€ë¸ “þû"{¹lœ•ëZöq!›NQŽrÆŸ5®L¥b¬zhu û¹#®ßoj·aj¯.ÓòŸâµaµRv(ˆjÍ­€€‚3y‡&»éáïk#‚uôh†ÞÙÞEÂíS‘»Ï'çØÖ­Ÿ”¿3{œUˆâT@@ÛÇnƒŽ”õ(†1ÎM{ðñ‹¹åΫ–Âå:zúd“ìB9&¡{ÀÄò³ÖªËv;Î1ÎAàÖÒ©­ 6÷-И•éŽOZ̹A,/çmVÆrid‘ÚN08=j9e[î d–í^tå)=NèÇ—c6â(ž07íÚ2Çò¬¹lÆÛÔ‘÷•€­y-¦iÀq×S¤LF¡p@<‚9ü«žJûiÛc“¹Ó™W$ŸpG²Æ‚òI“’§!±]µìAÈ,…AõBed(Ú¤c§5•¬o»5XÖ >%_ÇŽµŸqáàÿ'—™±‘‘ÿÖ¯BáNväc®;ÕY­ApÁA|g8è=)Yjjª³Î$ð´ƒ6ç'üŠ®º•ÖÜŸ¼?‘â»Û¢Ñ1;P…<…JðÄáö*ŒNý öœt:["ºl%‰P¸ãÞ®CmæyÉ0å äG'ƒZ(̈âL ¶ãÔ“Ð}*í x<™~Ï6̰uØ0ÇŒmü4Ú¾£sl¨–—O¹¾müƒ;O½kXéÊÅNAÇ‘É5Z+Ö’mÀ®ÂrÛÆÓŽø­›KraV©?0ã‚*­}yÔ}Mm Ѱ1'®+¤±¶l–hÇÌpƒm`Ùþá##o#±ä»¬x€h:¡©Lû ²µ’åäÎ,jXçŸA]4âô8j6ÏÇ?ÛU¿íãŽAº”ö½yù$a^0¬¨ÌI>ý3íúþUÒ|KññwÄßkÏ!tÕu‹»Å|ó±åfÏcêk˜Ãq‚C8ô¯ÐiG’œW‘ãÍÞL’?•Ý™N>e<÷üÿúôñ‚UÊ–ä÷ÈÏåMˆ®8#k½yÏøSÌ®˜P8 äõ:ÔÌN0¤)~27`玿7r2 ¡Ù’Ná…)päìu$ý`)LŸuZ&‡ï÷½xÏÒŸKŒUr’ñJ[€ÿ6}3ÛÒƒ&å-ï“·¡ïßÖ¡Eb –P»F6ƒœçŸçN,‚ 0 ¼ò{S^`HJ|¡€H"ByÏ#üö¡Y™~ð<àŸ—ÿ­þ&£‘TçspÒoóÇÔÓ‹ ‚F8 žzñž?¯¥o@ü¸PÝJœtûŸÒžÌ„"RĆ8'ãƒPã̹ØFY“®sÞœÃj«S“Ô·#Oó©@5Ø`ÌìÈáºr_ΞÒç¦ãÐ~§ò¨Ãï% ØÆTõèÃüâ—ÊÜûÁ$äð½ õúS+m'+ŒÃq#üyþtâÊdä±nq‚3šb)Šr“Àã§_ë@+$h~`ÊIÊýïlš”1“8 ¤ðŸoÏ¿ãHw¬l»*£¦Nx¯§ÿZš\ Ú±È'ƒŒŠs¹íásüK× Æ PØ‘¶¸Î ·$ž0GéMÊyÙÞxsÐçüô¤$ Ú„åN{dœg?_þµ(±] ’2 ägúçÞªècÜïrV5Tu= þÊšW1ä°}ÖÏäwÿ=é$Š@ëpTa\œó€zJ@>m¬@Nv>ö1úÒ$›waB´€µsϽqÍ« ±m®Gñµh¦’}t×ì.n••÷™*8Áªâ×Ì`P 9Sßã>ÜTWm+'˜¹û¥™°Cq××­7Ì7 »Ñ¼´bòJñøZ¾¦„÷J‚ ‘?—xb~Q‚ÇÉúwíYÒǵÂùHhWà=?V§qUR­ùJœô#^¿ŸµAwn?y‰£Ê^ç×ñ?JÐEhYŠrÝ ‘õÿ>”“AÙÊ—bØóÜ ÓŒ[¨ár@Éõ5ŸÅÆæ+ùµfú2ÑFî×!¾n½øÏý?:ÏÌ/s$HÐNt;·Pzqÿë¯dð‰†±¦ÄD˜•O͌׎?ÙWfâx?äUíVm"ü0ÈÀÜ®E/i7:pÕ½”¬ögØÞ ñ’ÒÞ>SŒ“×Ú½—ÃzŽëdóŽžÇÜséSÆû·;᱌ƒÁÏ®Oáù×Ö6•>¦Äˆc(p¤ç8R0OùÍ@÷2±oÝ‚s€»‡Lt&³Þý]¾Yw|Ù,=0i#›FÉ9ôö¨m]Øj=ËÍvÑ3ùƒrÄqø~µX1wiìwÒ³"º““æ.$ãð©¡¿e%Üïnƒ•+Þ4嶆˜•¤Q’¨§b¶åƒ†jÊ›V)+1¸Ry©Ë¬!gÉùHÁ9éMï©\Œº—«u'ŒMS»¼$ í'¡ö¬kÍUQp®HµÏê~"òÔÞZãûÃ¥G-ËäÔØ{¶ fÈìJÈÕµhÕKŽª?•rº§À9ãŒú}kÏ5ï‰p¤‡tƒ`+»¯ãZB“Õ¨>§¢\ø ±$pSŸ^ÕFO¤W çÜä3 Žÿ=ëçý{ãuĉËÂ2¸ÜOOZóûÏÚƒ6ð¤u+ŽœœóÛ޺ᅔ¶[â±cñLVÒÊÎp3SÞº'Ä)zØi©ϵ|9áŒ÷zΰ‘…/!#6UkékDF•²€ÑR“Žç<¢­cÞlï„(ª¸' ŠóÛâ$^ý›¼i31Ž÷S´:]²“Ëȉˆú+øWS¥]4ÁÛqèí_ÁC~6Âgã›Ø\l<;—¹ ²\H¨Øãû£×¹®Œ V®—Dy•ÚŠ>FUÂŒåˆèsÎi‘À*8àŒóD…X`sLpi‘Œñ´»“Ç×Üù;$Úd!òrÀdŒsùõïI¹·³vïôϧÿ¯­ -•ïÆzõöü:RJAw°[§·lSh°®† §‚9ü)ÑûÜœ†^?!Hœ²³‚IÀ/\ôÀÅ5Î@b«´ g‡ÛôüzÒÂ>s&ÝÙ “¿q<ñÔÿœJiÉó’ÌrÀÃùÿ*IQ—mÊpT…ÁôéèiWkmã=8Q×ÿ¯EÀ•ö9ùpI#Ž¿—JL!Nâ§û§=»Ÿóژ˵¸$ðÇ'°ÿ͸sÔ“Ççùû~tu2#<¿™Ø¤_óí@;CrÀàã=ùâœ~v,ÎsÉþ¤Ó27.FF?‡aßÿ¬(²ç9ÆÂzõÿZRåYòîÍ5¿x ’§=_ ð{ÒdàáW%x qƒÏ·Óó¤2I ï€?…XaI÷§I&s:ça@çÒºo…? õ;Ó†’6@ç͇Ìf)*G—Ó‘ƒÉÿëñQ0ÂðÀuÁü:~Ÿ­  # mê8ÆrMÐKs¸€½J nh¥{Ü$a̤¾pÎGOËŽF{zTV¬¨~d†Bß(ì3Ïѥȷ0 ù­U€úÓ¢#íe[ ¥Tõ· ÷Çã[vf„òU›~âFzçß×§O^Ùå¹Þ7ÀÎCîÝøŸóéN¹óÑ%òÁŒàUÉÎáú`Ôq“q)(Š)ù}ÿ^yçÞÂÅG„í*ŽóÎAçŽ>¼ýqP Œö›p¹FÛÁÉÚ:÷íǽY•GžIfdEÉp0HÏáéT› Ò`€¬rn1þ@ïY»"JÒ!Pr@# oóþcF0FI<õª{–V0UsÉÁ>§€ëÃÇ8ýJÍîIÑøKÄÒi·j…ÈR{{×Ö?<^·ª†@\ƒ»·ñOÌ áGB:× ü4ñåÆªCNÊIðÏÒ¼ŒvÚÁ¸î{¦x˜ªÊŸÀAäuïøÓî.aŠBw,dž0§Œr‡éQ]j¶PF²w¨<ÛÇøÖŠŒVŒ®i6^³Ò4dîàr¸úŒ•8íÛÐÕ°è¸%Õ˜œnAÿþµs—^&Ú¥ÖG û¼àFñ“šÃÔ<]öyw‰nYº¯NÕ¯½ñ^júü¥ÚBÊž”ô×Ô#1RyÇ^>¸¨wfžÉ#¹—_2:Ä&â3!î=ª6Õ›#Ë]ülÛ´?ýn~µÆÚê ’1¸©ã=¿J¶5–O0Íòžê0ú Z¦_*Gi¨Dl±ÊÙþ/Æ­Ûê ±íæÍžÕÅj,.Û%$ŒqŠu| Äp~µ\­lc(_c±‹RFFv¶z5"jr@ÌÒ8 Ø×)5Ø´‘d$·Þ§ad;Ì›qÕqÔP¢Èå:ƒv®ÙówÈâ©>ªáÙAÜ9À1LÄ7’¡¶Æ»wcžÝóœÖѤô¹¼c¡ê7þ.H̾d© |¸$öçüñ^â/ˆ1ÃÄLy?¼f8ôü«Ãüañ–7³~ù£ÀB·™Üd¯àæ¼sÄÿµ A%I.(QðW’FyÎ9íÐW\0³˜¥Ë[=»Æ?–кA1e^UÁ9ÏRÏ ?Ö¼7Ç'$ù·"(ú¬hI.¤d^ý±^Y­øÊúæì¤24j n ç ò8ëïÔzW8 gc!g“Œ—9fêO­{Ôp޲/øºm[Q™üœ´vVEÃ-´||£dôÉÆMqÃ;&WàœÍ{˜,*ÃC_‰îxUêûIi°#ï 2É»’TüÃ8éJP£Al†ç='aéL•¶m!ˆænx g ïN’»ž9Æxÿ=ý«»s”wf‘²£?y†NFN? ŠIy Œ/?(8Ü|®H8$ƒÔw_ò)ç•c’å}Gù÷ÿëÓÙÜ[w9ú©¨ 8òÑ[vNü? s¦ø¾D;1?wÔã=ñEÃ1rr@0x÷õ¡÷`"í‘›cÓ'ã=?À{RÿK`žõϧ\Ó<¼€@(À}æ;þlõééÅ<>Òœ.1ìÇþ¿åÚ˜ Ó †p Æ}9úQ¨\‚8àŽ;ÿž´Ñy¦2‚)¶à¿1Z]ÆexÎ d;Љ6å¦[òÇ‘"]ÅWr†!ÎsΡ¦+yRabÃn7d}h}‰Æ¡ûŠ?OÃŒcßÚ¤¸*êFà>rxçùÿJÒ0\²®$‘€1ž¿‡ùôfì‚g=<ÿ“_A~Åß!øïñ·Nµ¿Û?‡ô%VÔbdÊÝ*Ê¢;có–C¸’3ò£ |Ù¨©QS‹œ¶EÂ.nÈûwþ Íû7CðËá•¯Žµ»8_ÄÞ(ŒO¡A–ÛNtW†U,ß¼që´¹_qÇ0HÎQŠâ§žçF²EÒ­|ùîû$EcPÇð§µd\|^ôÙêÁí®u•#”º!Sýð¸ü éÍ|‹Å§'9îþ#ÚxYÍF0WHÈý£üH,~ø©-‘dŸûõ¥(Œ@ù'Ÿ¯N@ô¯Â@[tÈQ…ÎyÇO§Zýrý²¾3Xø{ö|ñ½–Ø®µ;í%¸ wxÝP㳑¨ÜM~F¢²¢ @ c§°â½Ì¹óAϹˌ³QƒérRUÑÕb(€m'F=1ÓöÎB‰;NÓÀ/*=Î>µ©.˜n$ñ»ž{þTAó°5 À6I_Ã߃^½Ï0 ÛAÝ0Fi…T`¯¿$Ê¡YvÉé¿<÷ëøÆ9U·JèW;0 ääq’}a×Óš*€RsÎI'ùQJý€ßu–Þá“ÈÈ£0ä··ëBܘ§t‘ð¸ÁsÓ=1šë~0h1xOâ>£c1‚!H2/ uÁ9ÆO=«“¾e¼,Œ¬ÛIÆr=AéÏçÅÅÝs#Y.VÑ$8È,±»a¿zÈÁÝÇãרQæ£3@N 6p0N3ëTwŸ“$m8 óØ{ûÑ4„wr‡9SÀÇáü½+E.¤Ü°ááe$†üAé×>ù¨/QLÛ]ÊF7Ž>•?Ú‹®íÆMÇ–bNÿ© ŸóØõ„BZOŸå#qNN?hÑ¡3=âQó0ä­ÁéŽôÐ|´B`üÄ8ÆF?Ô·‘¬R“¸c‚ àƒž¿çó¨X']§ nïô¬‰"#%™Îð¸àø¤SåK•àŽA=Kp›IÏלŽqϧùÈ_'+͜㟠üêZºÛB|øÍ¼ó•8+Ÿ½÷½«êß x¥|…É ÇÊI÷9í_šÚ^¡u¤Ý¥Ìy”ó×Óÿ¯_\üø‹mâ-•Çê~9–à!ç¡Åj©»ÜçTîýä{tßmevIg@>PÀãóÅS½ñª_Z4 po`yÁéï^!>¯uzäòÓôë¹ão½’ÃŒž•jªqG©‹àRyÕÙ†Çä §w¬4‚'K¡òçt[A$zzþ5ÃGº\¹ÝíM‚áb¼yS!ÜÙ44l­Ðë/µÛ™Dq([ï/~8¦.¢Å¾øö¬|váG+ÆM$—/"† ªã‡ÓµR‚/¥Ž‘îž8ü·aƒœ:Õ2“ž}êœÚ”RÙ² 6FF9uTI8“ ŒñÓÿ×C‹Z"Tš4v$‹av“Øš™¤ÀTzpsT!Ôadbîå3’Ož5÷k…ìHþµìK5ùL$ÁÁàäô5yn<”`dds\äÚš Ï•Œ¶H¬ñâ%sÛÊð=*Õ1Zçi$ꯕcæúc¥$wÆÝXÊA|×sâñª› x¬»¿*ìÇny\ÖŠ”´D´úž™'ˆ¢ˆž§<*É»ñŒK$ ?AÆsÛ¸¯"Õ<|±HY%U=·£ó®+Xøœ Ø’üî?ƒ“øWHJ=žûÆë ,¤óÉ œzâ¸sâUº±J¢4uÎ:ãùׄx‹âÃ0‘`%Æy‰ç¼W›kž<šâMÏp!ÆxÉ9ïŒgõæ»iáäÂSŒug¶ø£ã6ë?“"¸q–PÞ¸ù¶ž3ÜW’ø‹â,×°·™r Á ™lä€õÈ?\ôÅy¥ßŠ&¹`"Iã{uügÈd™ÃI)waœœ dãõŸzTðŠ*ò8jcc´5: GÅ×”‹$LÛ䌫“ŽŒzãoãYÑ[ÍqtKƒ)?ǹA9ÀÎ=3øcŠH­‰H*J†uçwáéÏõ­˜L@„2®‚¸ãœOæÉèmGHž\êN¦³g#âTC¬O`Áv¨ ÐcÛüô¬À¬P–;Ø‘œ cާü÷«—óý³PšBÛl†ÆâW<sŒ{qÆ*¦yaÆyôÏJïŠÑ\ò嬛@ÙƒÈÎiñ‚À¡ãÜÓ~a»·~MH0ÉnÇ5~¢G}àŠgÀÚLñCj.®ßý[ïÛ°äqƒž¢¹¯øÏWñ¾¤.µ[ƒ<ÀmPUT çŒ=zÖ1([îOcÓ¥49gåLÖj”#.dµf²©)+6+·/ÎOfÇôãùЖN¸¥¶;qÏ>¸éþ}é6ùnw~ó<…ùçóç+Tf w‡Wàíƒß4︡ƒ£ u9àçó¥2°ÜeÈéMnÓ¼€€Aô—OçCHB.Ô¤}ãÛŸóùÒQŽ{öÎóÅ*ägæÛÔüÃ$cŽŸA›¸ r3ÎqçéNãì"àœîç§óü©­ º‚¥¹Ã¶_Ε˜£dq“Ž;Ô†M›Xíulñùæ€#1 °!˜I\r:c#ü;b”JGÈA @9=AÏ~ÿŸµ5 0;Ý89ÁÎ}~œÒ’Ì®O¦8=sÖû®Ñ:åqž…Gù÷ühM¹¾PyÚ£$‘Ï_Ãð¦È…£ÉÉÏëú~tç,çæyÉ_NãéÛó¤&KEÀÎÿNhGܪ@Ãpvý?ȧaF‚rª;äñþ¦3ùР<äü§µ'¨!¶°ùÇ#<OÿZ¿U¿àšÿ[Á¿´oYVÿÄ aQÀɶa¶ Çø€§çà €Oåm¦—{®^[ézT6£w*Û@ˆ¤–‘Ûh8Áã‘ôÁöÇïg¼e¢øZÊÊ<$vÈ"„Dû<¨À@@íøWšÕå„i®¿§üÒÁ¥ÌäúuÌ–ÈQbœå›0cèOøúך|Xñ ¾…ws&©)Ì[%µ"R$§ÎYëÓ“Ôf»ˆú®ŸáÿÝ^joê ½ùo Å÷qûÅ ‚O 9Åž-Ñu«Ë^ïR¼Õ¦”–ho'ó$A÷@Î~\`~ ð¡ JV½¿¯ëô=jNõ:=þÝ_­¼G¬hÞµ—ÍHU.å Ÿ”å€+ôè{W˰‘ã/ùÿ<×OñÅö>7ø…ªêúcÈté|¸-Œ«µŠ"*“Á<ósÐ×(¤®rØÎOËÇ'ôö¸xû:i&§´ªØü€® Ý1þM4lÛ0¼w¤Ê…lç$sÔýiKdª’¼óÛÖ·9IS •Ú£#är^µ¹Úù\ª±sŽ;ûuúRd’F9R~üw£b· “·žÝ3Ÿñ ù˜/ÜÃ1þM@ùp:c }{ÑHG¾þ×VIÅDvñÚ¤±£ªK.f"Ÿå^ààíÐyG—çÃ4hå6Ž œà;wúW¿þÛgÙ¼]¥Ê#xÄèÊJIŒ¾Èþòcòž§¾p3óÞ“,R"¨•fË^=N9¥…kÙ£zŸ)1‘$Á=KƒÁ>¹¤(ެGÞè~`?—øUÍOOdS9cÛ–ùOLã¼þ'ðªQäFà’¹ÁÇùÿ„úzÿ‘L‹Æk3mipѾҬãžøŽÕóÛøüçÎ6ó»ä²(| ry9éÐ{ úÔ3|GºŠ8ÕæRå* ‰<’½@ëùûSú»¸ùÑôjxÊ$ŒI(3ÑœûÊ'~Í6¶3žŸ-|¿/Ä n J$fË|‘†(Î08ü}…T¹ñüí®\;ÞÝ=ÿ23ƒÅ}^LŽs鯈H‘,ªy8RIë×õ“yñJX‰›ËežGõéÜuôóeߎ'hž1r»X]¹{Œ{öç­Q»×n.g{bf‘â}®YËàŒŽ dwíëZÃ)m©¯üL÷kß‹ ²±itFsŒmí’?æµo‹ò4OåÈ ûÇ+Ç äþUåî®ÎöfV¶ìóßÓ=¿Z˜X¤Åä¹–Ftaªgc·ô®èe²})ãéGmNƒSø‘qy(1Ü Ç*¸bsùwät¬'Öµe‰˜F$v úŒsS¤Pôq‚Ûq-œ2þ4\6¸*ìǨÎî¹=}þ•èSÀÓ‚÷™çO0›Ò Ç â=ré.¤·Fا£FÇ'=³Ÿþ½sþo˜ÛØÉÓçmÇÞ¶üiòßî*FîI }îÿþ®Ø¬,*z„óýkNHÃDyõ*N£¼Ë11^[jðNzcñ÷«kTƒ”, Žƒ}zñøö¬ÛHrë¼§Œmܯשÿ&º="7¶–ÝâÂ"Ei!NàwŒqê}½s\õecZ{\± aYB¹Æ>\ŒuÎ?Né÷—­iiq %$òÎ?x û’9äþºÓšO(8fiv»6AÇ]¹ùˆïíšËñ%æ”ìÛÊ#°È$ž¾ù®X®i$T•ÎgÌ«¸7‘Ç·ãýO­¶ ·hù³³“Àëê8¡×i$•ô?ç4ÝÊW®¹ `ü¬Oõõÿ=zÒ„Æ0Ê9ù:óëëHIP;Gq»Ÿÿª¡eÂ2£€qó`äcÓÿÕɧ7™4`i1ó/oǦ}ÿýty„ïdôÇɤ2¬6°¤‡ÿª˜@ó†>_AïN`_‚:÷çŽy¨v²`ùk“žsŸN´*Æ«·k:dƒ’1Îi­;x/|äŸ^¿ÐS°EÁr3œrE5p ýqšs1(qÆÜCôüÿ_­)!7p¶Ð¶1Û§ëHíÁËd‚qœzÒ:‚0zzœtÿ?ôä¸ ÞNØ]ûsžãœCïšRÂ0sòãt©ì¤G÷Ï#Œ{â½£öLý˜uoÚoâöW™q¦øOMTŸ[Õ­Ê !F åEcÌ’4l¹ÁnpÎ¥XÒ‹œÞˆµ'dz·üsöxÔ>(üQÿ„öîÝáð×…\”yâÄw÷rG"MÀ«òYˆ «ëõºÏF†¬¡ Ž@ü~•“àhŸ|1§øwÚT6…§Æ"µ±µc‰rIã©%‰bÇ–$’I&ºŸ4cåm§¥|jßY›©-OCµ9R">Ký¸üzº†m¼;ž]Þ©" «6Ç1)làƒ2½2;ý+óçãÆÇÑ´øG´(-í¯JÜ]Û^ùXrÁ ‘ǽ}ûux®MÇ—Úã±– 6Pª²–ÞW޼ÀtÇ|×çMÌój3Ëszí,ó6ù€K^˜®Ì¿ª/i4wb«:4ã½HÆ6¨ ÀéëôíÿU¤I=ºÈÿOñ¤S¸´*uOáEjøbÝ®5@àŒíÔsÓ'¥ÍV¯,¬G†UaÌϬn}Í]÷ fšA.T®v+¨ Ÿ“±ìkäÈn^…i7;;e‹ç'œwb6‘Œä“ú/ù黆 éÐßvá´óÉÏ=º~t°¶ÓÈà|ÀøsúÓå0ÁÜãÆGcQ¹>¤ŸóÖ¡’Jï!—rº®î‡Œ}xîj  Er¾a Îî¹ëVc‰7+…Ü8=OojŽå>~27{ž‡ëGA©)åÉc!†%X6zƒþôgÁß²&o§êS"\[(Nâ¸äœ·=†}Aé_9+ f †Ryú~„sN ñM¾)&á—¨Ÿž8ú×5Z*ª³:pø‡BWè}ÍiñFÞh„‰2¸Þ×`äàçŸÇéŠç|KñONŠf /™ ãnå`0OmÕòŒ~7Ô‘ ‘¤’…²ÎyÏ|Ê “Å—²°Œ–;ÏSÎkÏú¥sÝy+ãª|PŠyÜÇ3œeq»ßëÓŸÒ¹«¿N[BŽ0IÉôï×ükËŽ¹rãåX€ÎAÁ9ëמ{P5Û¢>B¶íÊN8é[G c'˜Áž‡/‰ç;€qŽHΫ·ˆÜ€¾îqšóÙ¯®åmíq*àtFéÅFÒÎùÝpåF ËóØÖ«a,ÅtG¡Ýk‘ÆYÅ¢ñ…•±ŸóþR_ÛGlÙ¼(,\3~Ÿ\× µdP –EÏ<ùþ¥×hã§OãÒ«ØDÁæÈë$ñ­²H»VêB‚ª3Ó¯${þu]¼^²>#ÑKdnã÷äû~F¹´@æù°G_cÏùÿ!»Nó¹ƒà~½ÏéïWì`Œ~»Yõ6fñeñM±GBI+ßãQ¿Š/e^|”Æ9Ï÷¹ïïY±Íò†üsý)7*ºç‚1òçŒþ5jœCˆ­-äÉ俽4yp¬ÄLc¸éúúë¶ÒN—Ä8¥F6îëôê?k‚v;r¨á½1Çõ®NÕC¼ïC°F ‘·<8éÈÖôùS2ç“Ý‹-ÄWz¤ó«2ÇQBòžÇžƒ'Ÿ¨­Ï &Í×.‘Ê y‹¿,sœ†È<~9çÞ¹KTýÆÐpe`¹cõôï’>ƒÒº½Ó• 0À( àcü~µ´uzŒ¹ò¹ax÷l ôù@#žþ•=Á/!!LnNH8Èç·Ðþí“YHñI ±Ü”ádÚ8\ô>Ç>úS¦¸–qÈÊ짆#¹$ŽO“õ­5µ˜‰#‘ÃáôÎpW9ê>½:U‡h›f䃃ÀÀxã$`©á£bOÞ‘íì}ÈëBúVNz¦;Ïj`sþ4LPHx6OÌ}¾œ~µÊ,>f<µÃgÇzZï™Àîzs\µ–Ÿ$lêÊâBC¡•Àäã‘Ï;yׯÁUò½M#erM6Ûc+ÜBõSóg=xô8út­ëxÆ™pc-óré•'°íè{j¾žŒ›¶“Œ’qÓÐßРв´{É’FLŒd+p28Ï\sÿëçÌ©;êtÅtDºt——"8ËÉ• ¸Ë<àÆ3ÛùV/mþǪEkFæ`ŽÙ'kî#Ü¿­{¿…¼&š>¥næ;8Lò: o‘9àdç ~žµólj5T×¼Aªj3IíÌ—Jã ÌHdápG8Ï^”°Òö•["«ÅS§n¬Ï•ÆÆÂÝà öæO0íR è9çÿ×Q—;°HV‡§Ðö¥#Ë%ƒc€>_ƽCÌÜ>é$þ]:þt°2¢Ë¹rÀ\œu=)dHÃq€OáéøÑ9•€ Ž3œçlÕ"„sæT܃Çä?­#ŸvÐsÉ9Ç'‘Lr€w|£;?ŸiÀyç,T¹ÏÊzœÒT`ò7?‘Ε*„–T]Á} 8qÎ{SF6õ98Æâ3úþ¡cu 8çמ¸üéê®÷$ÞYÄŒj˜ñ·ð#¯ëJTPÛ·p=?Nô6É#Ê»4Šwgœ~•™—'‚Ÿ×òë@ ª®CµÈqb9çüHÿõRío(<ÍÇ,sú*f~l+Éê ÿëÔ‘Hc‘ò“©œžçñýhÜDjÌ|ÅŸ˜G'ÓúŠv>GAòîûÄ€ óÆ:j¨P>ñ䌊I“{#Éà¿N¸j2Iq,AÞÃÇSóü©‹0V Œ•ÇQœs˵9IùÝ›¹ïëùT[O˜¯€»Ž>cËzÿ1OÌ™`B· óþ}hUi“ny?7Ìpq×—osA`…€@ä cŽ àû SCžÿ2s;wÿ<ö¥ê¿¡è÷~%×tíM…©©O…œ6i$kß$³Å~ÜþÉ¿¬~|'Ò<= ´0jw¼–ø+=ùDÒÚ¥—# Xgh¯‡ÿàš³TÞ,ñ$Ÿ¼Cie>cæÚé·³N/U ‘/#hTVuGîÎ:f¿P!ÓͼXŒ ÀÁÏòy–'ÚOÙCe¿¯üÓ¡]îÍ;£¨*̼䑊ç|W© XCˆâ\’]±Ûùuü«f Ë.v„ù™\çåÎsïÐ×Ï¿´gÄôðñû ™Cˆ‹”aÁÎàrsŒŽ©í^\¤åh®§f Ôô>(ý¾|C¤·vÐ;F²ÜÆd‚³¨vlœuPGÔÕñB«ìuv8<“5ïŸ5»¿¥õÔjòÊ…eòœdºƒƒ·“ÀôúW€ ÑŸ™Ž:àž¾™üëë²øòÐå8³ k_Ëõcƒ2©^Jœä‘Î=¿ yeEÀbÄwt c§×„gh?yóÓüäRˆ‘wTžryäŽç¡©!ŒFB€(` ã¦sßÔàþµ[frKyê8ÿ>Ôì1îÊ$'ÎsüºÒ!wVùKœc ŽAãù~}ê6›aÉtˆ!ÎsŽ)ö—‰#¸†`áøe‰Çsßñ…äu^´E·’WBþg]«ó‘ÛŽÿ{ÑWt…K$Œ"EŒ{ž”W™9.g©ô´£ìà£Øû—ö±¸{ï„·ÖéÏnë †ÈS"d&7dœãžïÇçµÀ^Shlãi$+íïÞ1†ï¬£'÷±ò#`IÀO¾9ô?‰ïK3dÆW\ Ÿðü½=k¿ü>UÐðgݒ鳫º4Øb9$Žø?‰üëSQ‰Z! Ü|ÑBäääãwlð}?\sÚ}Ã$¥wH%º1=sÇN•Ò%ÇŸn¨&ýæ74c*Ä`òFzžB+¶¡‘Ïέ €¨'<{€r9í×Þ¢‘q¬¬¤ËŒsŒtüêþ¡ Dã € ÉQ¹}°qÆ*ˆÃ#`îPI NNGô¬ÚÖÁb´ÃgÌp§ žÆ§µ˜H@^¤Œä7§~¿Ö£o•NH9ã ãü>•â3!l?)÷Çòÿëæ§¨‹RmEE8à ã‡×ógùœUwäí8$pqÎjͽǚ íÜrI8?n¿õ êXíEm¤eJààœþTÞ¨BÙDËà )´—`Ç\ý Is¡F 5V L$î;ÿÖµnÄl€ÂU‡UÝŒo_Ã' ôàZ¢º-òev‚ÝÁ÷þU`v’½õéþ ›Ëûã’@äƒ×ß×üôNŒå}r8Æ{sÏ^jFä¾ÀÎ>L¨ÎÁ;¿ÇÿÔJ1ç$ñÖ‘K*ƒÔž¸ëŸÃüšVäT3»¯>”„17rqõþ˜p娽Øu8ÇZ^T)#rž£îÿž´ñ¸IÈ ‘Œû`û拌7¶CHç#¯PGþªh(s8Âr@úŸóÍ9ÔÇBªã8Þåôã§Ja€ø8Ç<ð:úúè¾hR̪ÊO]Ø?Lšj‚Aàð ÿëÔ¶öÏ"³…ÚÃ8ÝÁÿRŧK#`! ö#ß§<ÿŸJi1Ø‚F 0x'¨ †bFÜ1ÈÁéœõÇONÄÕäÒn˜ª„b­Œ€9ÿ?â*h´+©”ª©ËGSéŸóýiò¾Ã³2Jy$FG÷xÇëþ4¤CîcÜŒ?Ò Á±åI#±'§@*H¼=4²}ÿ21’UyüÏ­>FfQ,°ÝÏ=©Ñd¾Ö8VÀ8úúsÞ®ÜiSÀä8:|ÍàäÕf•˜0ÍË2üÇ>þ‡ñíQkÇIkÜL#ÚvÆ mÀ€:sïÇ9â·£·û(Y" aIŒ’É?OÖ±ô9DöhV]®0 ¾0¸Éz¯¨âºù" ŒÅò Ÿ\öãž¿O­uE{¥1—+-¸B›ze”mýr9æˆ#{Œ(frÞ2½I˜Î)U£4%Ûa9 ˜Ç¯,1úúR™ŠÄd 9倎¿Ç_j­FL"eC¼|ˆn7(Àô?Ó¡g³í#_4’»rb?\àã=sÏ^{Ôç…U`· ­ÏCÏ¿aŸ§Jtc,¬$PT’T/^½Hä`ÿ^ƒ_k:æ-d‹Ì]¥„låsê3{Žž¿ZÂxZ7 #T9,‹Ô`ß ž?=릘†Œ"¹…Ý»å~Ëþzu«:âÔnY˜ºk ägŒ{Èqëåã_%¤ÎºsÑZ…¯uy¼¿)Å»6€m\|½ó‘÷‡ zôã>Õàÿ‹<Ï(<Ê€2ô ’p'Ž7`ã±õ­? xF nrÊʪ R[”~@õäuèÖÙæ5PÊpJ…† Î~÷¿A_3R´¦ì¶=hACmÏøñqsá_…ÎRÚ'U”i{Š“µYY˜®R@CÔôlö¯•KovbÛ÷¤uõÈë^ÙûUxœ_xÚÏD³Ÿu•¤sÍM&fp\6àŽ:Ó¥x—ÌÌdÔŸ_Z÷0Tù)]õ<|Tùª[°­À‚3ž <óý)UH$}ìœ{qB±l Ú§?ÒƒÎ@^G¶p1ÿê®óP ‚1ƒÕyàþ×ùNH½Žiå 9ÂÜœw棔2ª€Ï(ý)€yŠ ‚~n§ãüóNÞOÊ2OLŸAù~”HÁ“·ËØ ¼zRª ò+…Æã×ðÿëP1s ÿçÿ¯MÚ€ÀóÉ?áÒ•q…,9äóëŠhÆ/+Ó#žÝ( ÆÒÊ€šE܃yŒãß8üéQÿ9è¬M ¿*HÏ*[†hŸpX‘Œà·ùÿ8¡Y¹ÚÄ2sÏsóí@`~]ýñ÷³ÏùçÚ‘899ÈèHÁ®Gä)î´LUrY˜uŒp?ÚL³‘c«õëøÒ©PFFtã~TÇPرíÇ?µ PFø× ¤©tÍ(bÊ $aðI'އü)ƒ˜dõV Œr=?OçNÞÌÜðØ<äãéEÀk¨ IÜ8õàñþ½àÃ¥ø¹ñ³Áž eͶ¯¨"ÞþóË)dŸ¼¸;ÇÝ>J¶1ÎqŠóø²¬à <ôþ•ú_ÿÌøAuáOMã» ßkñ;*[ÄÛ‚Æ&qæ:ã ¨Ny¯?ˆúµ5¾ÈÞ?k5î/x[Nð‡†toécÒ´‹(të8ÖS X"cæ''  sÉîI®ž]ê‹É0ÆÞõZÖô-°Ü nÃn4—)q±îw²žO×ñ*qнõg£(·-´E]cRm;N¸»XËy*Nи8ÏAùšüãñv¹{ñÄWñ;I¦òð+µF ’\žœã—X~מ4¹ð÷Ã;û+/2‹‘´Ëµ ¦ÿ¼0Ãi;°xõ¯øuáý+LðÅ€ 5Üñ‚…dm¾kŒ‚Kd“ÑŽìœú` ºmÝÍô=1ä§~¯ò<ïÁ?îõ-VVa‚`ÁÒ@¹ÛŒ»=㯽yÇØÞóÚšÞ|?‹íÖ“ãvŠ÷=¹FRI\—,ÜœŒWÛº}‚éeE'”ÕÊÀ‘ÆmÇ8=H=À<Ô~&’Â×S à¹^ˆy=#Ž•×KVœïMZ0¨­#àKØsâö£“û#N·@>A&§XõÇŠ»'üÿã:B’#HØÚ´@é_iÁâ³qw*žPV p? ö=3æ”Þ\¦I!‰O—ÁàñÉʽ_í·¶‡žð‘ŠWGçO„àžž3ÕŸ(ñ&—áŠåQBI9 áQÔÏÿ_èßþÀŸ¼.!}}µjòúâKhËo&6ö$Žyë^“{%Ô_½HÖTI#lb œçŽ;søw¬û¿¥•¤_2\K4»âUB ù‰ëÛ‘GÖ«TÖö5ú´È5ß ü+¤>¥áÏèð_[Ÿ‹Mî…A!nùžkÏc²àgž…[Óþµ¤õØ r¹VVàm z†`BAPxÆIþ•37.8ãzŽ:Q|Å@^ ãn3üûŠÇÈD Î…!½và`ýoóíSy¸’ã¸çׯÔwÇOJ‡Ë Üœãã?•5K/ÊËŽà7q“I;%ÄjCa€¦âI˜Í_³ÅÅ¢Ãz6î0N{ÕcûñÇÈ3Ï\ÿúª]"Eˆ\+1\€3ƒÈÏ5QÒ@Fñ³ Ì»vœOOóéÿÖ¨ˆ$®àÅI ‘œqš¾ãÏ `Œä‘ÐŽÇלÕXã ê]B’pÄ/òÿž‚·QW¸ô3àðüåÌ;[€ªqÇ®F=ýúÒ>?9G’<¢rÌpHÏN}Õ¢ÒÀÒØ ‘ð¦(Ô`ô¾zsÆzS­áH Sä, ‡óȬ3““H#=Ãõõ«K±7îS};|*è»ÒFÁuB¶CüøÅ"ØÇnI8Gv\ äà=É=óíWž0fhš?Ÿ©ºðqÓ‘¦}ªx-šK2ï*pîÚÄ 0ϧõ¥e¸7b”v¹•­Ð'™´¸¯,G¯®{´“Û v ó¢€; ç¸äœzc§÷¢ÜI­D¶ü…yõ sÈñü+%îÐóHÛGÍ¿¨ðéWác+£vr‚ØÜ3‘ƒî?N:ÓZ‡©`•~ê?r}=²P94±ÊèDbLqóH¼ àr:; qÇjeo=6€qœàç©íÊ©¶)ѳ™Y0'ªŽxü;R¸Tl Œ6Ì€9 œ“ŒÏð¯`ð=›O¤#lo‘©“’Ä`dc®3œqè9éáßja¹:tíô潟àü†öÝ¢XÔ`d™p$ŒƒÀÖ¼¬Ê*t®ŽÌ4¹g©ìz5²ybK¢d•W¶@U «žœlçóë[šN.§t`‰ÒÞ2ãkK"ÇÉrW¨ÜqÏÔÕ}6Íç…Ò8*¯ÎêÀùGbxÀ#×ï¥uz›¶X¦¸RªŸ)ÉUÉÀôcÓ5óЋOî='$‘ñí{á› â »{;˜¬nl-¤YŒRVù’HÙÃ!Èàž¸¯òˆ /!xË3õ¯¶¿o뛈<á]?ìP®žnšhµ˽¦È XÎ@–'ø°¿Ýñ2*ù€7 Iúé_G†¿³Iž%oâ6HN8` ÇÿX{Ó†ÞJœ—z羟ʖtùnÌÄðø>”‰lä0qµ2 @GcÀüë¤Ä@$dç= dŽyÿ?Z¶àC*–ä—?_άÜ磃çëP.ÿ›i#ÎxÏùÍ1†ö¾Á€ê|ؤ`ªÁˆ }:“ש¨ÖRÇ-ógŽGoÆžÎäFÎ9QÆÉÍ$ ÛP 2±ÎOo§çéJçsc?tç¦?úô² ‰z‚WŒúw¤$”s“´dsþúÔ€_;)É.†ôíïMr$;€èÌþ_ŸO§N*5Ú[j¿~p¼c¾x俥M»ÕQØa‰ÜCÇoóÒ˜ÅR³/*ñqÛëíúR¹ø–ù”Á8ÏZi,圌0=©Êã“ ñÓîŒz~4tˆ4c8ôzúé® ~Dë“![æ9'¨õÿ?ç­$ŒB.>vn¬­ FFÕ8p9 €zctƒßñHÇ–^r:ûÿ_ùß,Ç÷¸`?3žŸËšSž7sÎsëLƒÀ> —âtO Å/ÙŽ§w>pc9vϨPWíÏÂý3NðÖ…¦èÚU¸¶³³†;haDTUÂŒÀ¯ÉÙDþÕøÑcpy,`ybŸ¾P “_¯~³³hŠyêPvâÈþG>õñ¹ÝWí#Mt=œm.ç Äÿº’!¹“!Æ g‡OÃô¨RëÈ—"º«ÝÉ8ÈÇéý*¸Ô,ã„Å–8ˆMƒîöÈê*K9’ÞÎââEßû²ÀãÎ8®ýõ_=Í®çK‹I¶‘?j ^/üQÐ|2Ó])óX•ƒ!ÀFu\6H‰†{Ü2 ÇwáM'Oš)–dx­â,%X•R(Ô) 3ŒtÚ3Æ3ÏœOxWIÔþ+ø‡YÔçï.-í­SP02»Ÿ(´±…R%ÔõÈ Æÿ¾"hÞÒ¤Ó´`Ðß¾äYU¸Ÿ—‘€:{çð§)I(Çú¾§{ÙE#;"|CHK¸­gˆHÓmHmáS¬%Nx'ϽyêjúµüŸh›{¬‡PyÇsþzSL´7×Z–¢P»•²7ƒ>Xw:¾€Wau©xzÖÞ(Œïn¡X«CÚ€œžƒ_ÏÑ\´ ›zú/DŠ~­ý™©-­Ä‹ÁKÅ_Œ€A<óŽpx÷æ½;ÂZµî¢°[‰¤µ´™cIŒ€3é‚sŒ ò.ÞÎk·ºÜ··ÎëÉàs»ƒÁž?J÷¿ãü2ð„þ!ñÚ\Ì´þfÖ a7sœNqß®ˆµ+6Cj:%vrŸ¼e§xE—SÔák0ÁAŽ@ .q·<`€yé_¿í a5÷ˆ§»š?"hí!ŠÝ\–õœŸ¦ûLþкŠNMM‰´ÑUÚ;d<ÌãŒíÛ‘€Oõ5óÁ¸½¾VQq**5cG+‚3ÜsßõÕîPÃó')hrÕ«v‚Wg­CñFòþ;ˆoæ’Ö2ÌѼL˱qµI;€ 2Tc©€+ÍõLê¤å$Sl äñ¹}xÀ;¸<ý;Uì&wI#M#1B¬I+ŸsÖ¤žÔÚ”ó|øÆrN2GPxÁSù“ÜWt!ë NM$Õ‘nÛsÂÁÀ9 IÃ~†{ÿž(¨£òJ„¸ø Ê ïÔ{ŽÔSiu4Zžñà/3 @.‡îãÞJì'w'à\Æ{9“ų^L‡7'ÍV T¼÷†A¿Jöiñ1ÌGjäÇã®Hõÿ8¯>øác pi“åØíeÈ6c*¸n˜ÎN8ÆKsîròÁ«Ÿ5^wÖràüÙ,>˜Ï§âÍB×ÌGq|¢ã~Ù =qô+Ž?„}i]¹”tëË6‰£Þ`'Éœ¸ç<÷ã§~>‡˜Ö,ÛN¿ùckxdÉ*Fps“õçéÖºJçQðûÇ8ÍíŒlIxw8ÛŸãé€{ÿ¼9—â-ZÇXÒKÛ¤q\$‚B"Œ*9ç’AçÛž e+%æYŠ÷¬ÌÑŸ™˜æ>øéŸåÞ§¶œMľÎ8ÀÚ3ïרüÿ,Áqó‚]ùïƒÏ\f§Šá‹FìuÁÁ?*ŒûôÉÿ=ë£7|äR 0S÷³œn à¯^}¹ãš™Ñ–à%ÄLŒpq圑Œ§^¾Üõ¬d¸‘¢}ò3zœõ=9íŸÂ¬ÂÂ(06•+ÀÛŒ;ŽßÐw­S¾¶­%Þ!®dVÃ`ÇþCüŠôŸz´‘kÒDe8c÷ïÇŒ÷#ò¯%¼ 'Þl‚O=3ß ÿëW]ð§P[_Ú2†`ù@q¹eïɸÿ Ž|Dyé4iIòÉ3í?éí~!·q2£$’ нú}Þ0yêk½Ðl'û?Ÿo ,àœ) ¼dóÎ@ã®åÈè.Hƒl‘/œ?â×<Î3ÐãœWo§ßEl…ZXö·‚™äçƒÔú9õ¯œ§Üì©7Ðäÿj¿†¶Ÿ>êZKÏ%¥î‚ï¯Ùù4í,ÐZÌ<¢¹\ 7['n2¯Ë p#R¥3üJW8펼Wë‰üD.­¦·KÆ×Ja•Sk»9n™$œcôù}ãý=4Ÿˆ>%Ó‘<¸mu ˆ#VmÃbÈÛy8'‚?„ç§Jõ°òoÝ}i)†AÚ''Ž?ÃÓð§yÌá„c;€è:p3ý)J† ܃òŒäÿŸz‰¤ÎÑ€AùGÞú×c0$^dÁ—‚O!OLúþTðªøvÆp¹È¨•Jt 2OÓš{È`¬ÍÔóÅ;Ø Ý"dWYJ8Ýœ§å‚Ó¨÷¨\)$ßB½x?•0åȶ:üëI¸2cq'=±Ÿ§Ò“ª+r’˜ß=[éøûPR5ƘÉÚ3œûŽŸ¥D6n9UÜ;î:}?•Ll®HBmeRÇr¶Ã†ÉÇËŸ½Ïgµ+Øvob%?;rCg‚¹ÆOÿ_ô¥dIbLC9ÉÀÇZ»‡5{­™w/÷<»v%¿3þEu¾ø ãÏÄg²ðÖ¢è$³Kˆ#¹.G?—ê*%Røš4)ÉÚ(â8/þ³œ±Lã?Ö ~$ ¯óy\r 澦ðgìâ¿ÁΩâ;J ’aKyg sÆì¨'éÀõ5è'üB݈mkÇÎ-÷Ïi¦ylŒýé[ßœzW ó4trû®l°µzŸ :Ž*ëØsþZtl]ùù“øŽùú-kÿåøwfª÷> ñÌm…°ÆŒÏQA>ƽ[áÇì¯ðÛÀqC:x^ÏP»‹>\ú€ûS)ù >@8lp=+šyµ¯u6m·lüÐð?À/ˆÿ$LJ|ªj(@ýûÆ-áêG2JU:ƒÆsÅ{àšþ-ñ‚Üx¿Äø}ä}Š EÔœ¨õt•QsìZ¿G´×¢Hmì˜E[j°c¹ÇnONõ«¥Í¥],ûÀ¼/šÀ>ze”žØú+Ì«™â*&©ÙCJßMžAð_öpðgÀû$·ðÕ‡•{r‘ý·Qw’InÙz1 Ä/Rp¸5î6Vó#£È_/qQ½}OëN±Ò£¬ªI¨2ŸðÿüVÕœ(º9Húu+æäçV\õÙê·FÑD6Vʸ’d™rXpÙàqXÞ3ñÓtw€ÄŒ—“½äDÚ=FzõëÀãë½OTµ±/æ1ù—þY_§Lp ¯7×mloÄp%†[g9™Ã.NpñŒãiÁ<þ0혩ÃÚ5)lx†™¬Ÿ_2]6—n±»y£çùœžw ¤Äv8"º8<%e¨Î<ØÝ%òÈÒM­v†ÜÄ÷9ÇãïÒJÚ-™dE‘AÛ¹ñüCkƒÎ8Îr^1Îx-OÆQéò¬–‘ìÃrD¥®O®wdvÈÎO?(­S’vJÞgoW¡7‹<=m FŠP‘­ÎÀ‚£“Ð>ù:רjWÖeâ·Yn䈣³9gÄÞ0¿Ö­ÃHÉ$¿,êÁ!zëÔçÓÞ¬ü&ÑmãKÏë¬^ζ(ÉNw)-Û®1ƒëœ×]9¸¯{~¦S|»‘x[Áš~—co©jsˆ·(’gØÁA;‰è6çð¯(ø‘ûHÙëÚÜÚ†´óâK;E1Ãx²´Q çt| v'Ûœr¾(|SŸâ—ˆN•ew$U`Â!–dÿ–‡9ÉQ–öÉ b¸í'ᆽã)ã³Ð4÷[@Æ–Ý•XE¸ìÇ [žìnÍz”é$ïSëæa/3RÒo¾$-þ£$zµª)g–,$s¾pJà6íú‚8®£Ãü3¤éBîkeŠd]³åäÃÈn§ àµ{»àí?À ž+ÛEöHÌ—««´ìÃ%Y+óî.8¯”ümñ9®ï/ Ó¢Í¹“ˆRs¸àƒÔœ`ç·nÞŠŒçî­ ]’¹ê:߉|;e¤jË;£›«g‚(br~f´ŽQFFq‘Ÿ˜oeV¼¸Û$eÈUþê‚vŒ÷íÏã]º´·zLÐ3#ݘšbdlª SžIûÀç’:W!+õ‘K€FÕ#Ø‚aI昉Îç9xÎ=>•î-´>ihÑó¤°Æj•òî¯|ñþsTç„a—ï¶3œò¿ê+Yc‘›Ë—s˸©mùËzdò.ùjÔå"@» ÛÈïÏ÷éÓ>Ümht—0︚æ9ݼ…áñœìœ(>¸b00­ŒŽq¸HÆ$*¸ .1ßœ÷*%WyJ«ÝÀ;úòzÿžÔÔ2DÔbÁÝéõ¤›Z¨ñÅtˆç8Ø­»ê?åÞ²fEI[bäÃüý?>jô ®ª‚xõÇóéÖ¥’10â=ØåXà3øžxç5£\Êàco©e žwïàóÏÿ?JnС@Üy?äþU4±2³¹äŒ/?ýoëP±!qÝqÁÇOÿWzÃa P#ˆÏB`uíMUÄy#iÇ 7ïÅ? H à íéH˵ËÚ8<ãÒ€44û‡–(ÓpÂeBŸLp?^•¦KMoó.Œä‰ÏéëX:s”¸Æ@çnPû×JŒï»Éx“ÁÏ<ŸóÏNµ´ÑI޳V$PŽî›‰ÈÏ'§#¡ÇN:t­?1ª%,c',qŒŸJ§§Qº@².6’¹Ï$ôõüjÁä:¿—$dñ¶EvVàŸá=x÷ëÍh†J×8%Ê&œ†áIÏ ~Gøô2ÚÝ’?'b¾Jìsøqïžž‹o¼a°˜;L’);yŽpsê;Ž8¨mßd-4 ÌŠÿ?RàôÀéÇñÐQä#V;ƒ Xm…2¬¥Øú};öæEº0œÅ”ܹùH$žO|:Ɇæ5Fi˜‡à?#{qßžÝêõ³¥Ä¤ŽÕ;|À¹'ƒÆsÀ÷ÇqéT˜¬^³¼hüËqw(€ù¥ Ù@ù°O¢™"ÜC'úCþìtþ rÀ98àwô5¸i H$xÊ’Bg®yÈÏOÒ¤ºÔ\‘ÐNû¶áSkdð9ÇéžÞÔÞ«P$æGË´Ÿ(ä:ƒ»$tÇÓ#Ž8зo)B!Æã‚ÏŽ½Gät<8<÷ª±[ê-hÓ¨tµýa~P€>Q“×§Ó4ȯáiXÚ/nk"3§ÝnC&r¾{œŒzá­õ&Å‹É7-¤’ÛùVû<ìüap=NyôɤyRÞUŠ ·²A/š®ãtM8Œç·qØwmÆ›}t`’îêÞÌ-í¤ÜpNlÏN3œŽ8«‘iðZ|+ æ(Ý·¾$sŽyǧq:½C@YneˆÍ=Ï”›¶ˆ£b±í>¤œñÛÖ¥°œFþt Ãx~` ;r~÷$Œ}hºd–è•”[£sÞkÃ#q§k ðŸÃýgâ]ÌIá]"KÛ! I5§Y A“iRFÛvíŽN1©Z•æì¼Í¡JU ®d2G:©B&ßwj¶Åä“‚9éÓ¶; ×#â†O®E,Ú$n._•‚3ˆœ–çÐgðÀ9aø[ödðÿƒYd×.O‰/]wGhªa²L«2ò ;›uSŒWq¬QÃgggieiù£·Y°@û ¸üqé^%|âŠV„y¿ѧ–Ô–²•Í};á׊u-Té–~Ô¥»RÊÑ}ŽM¨Bî9q‘Ðý«¹ÓeÿŠš‹ø¥äˆKÉyl›2qÊ™wÅFG##ýµÐÒþE†×)r…Ö(â)ýþyö+ŒcžÆºo ´6h²©óðynB)ôçŸ^½Ï^ÞMLâW¼"µùÿ‘Û ºš^ô›??í?dHޤrà u,OL¶O¸8ÔsZPþÇ>1k‘׺txRÊÂf$c×ä'8ÇnÙâ¾ù´ðü6pEóJgl0F Øäç©ÏíÖ´¯4¨åä’Ýn°0ÉÂ“Ž¸ÏãÅskb/Óî7ú…²gçÓ~È^2„nšMÉÛ†/vQ›÷‰CÛ<~¹âµ¿ì·ãßjö:¾“ ä±HÇä*S$ofϰ==x¯¿ŽˆAHŒž[†«Œc¯ã‘ß§½K&‰³Ì!A#áVW€Jä~9=¹æ“Íë½_p< ‹ñ<7GÕõM#MŠ;!ÅÂíß a›iÛÃdÛ§uã‹ìy2ØÎ]Ì<¶Â#ëœ{kÓ×Áñ]Ë´E#»ÈyÛ€I=ïêsÇQQÇáÕI|„E‰ƒ»§\žs×ÿÔ9Öc4öE¼)ugÏÚÆ¥¬ß’6_%Ð<¼ã= #85óÇÆ†>&ñ.µ±§é—…ã[yb‚ÝT& ¶ìŒxyÎ+﫯 Bò¼‰®NA |¾ønü:Ó×Ãb…£uH”aÕ—±å>‡§lÖÐ̪SwI x*r®~a/À¯JWþ)­IáJ[;+;g#¡üEjØ~Î~:¾‘¼é°~T”ÇcŽÜã‘ëŽGáúC7…&’îâŽ62Ý‘ó``gž@ú~5f?ÝdÅ…1âÉÞ¤<×GöÅG´QÏýŸEnÏÎ;ßÙgâ••ñ²›ÂÁ$Ncv}NÌŒƒ· ‰NáÁår8ö8Ù²ý¼cyh³É.—dªNï2éäläµUH9ã©^ØÏJýƒáÂ44s]D«æ;Æ­…‡áÎz~U«mà_³ZÇ:A „’H‰²$}ÓõüÅc<â»vVû`ðë{³ámö7–Ê.|i`³¾¶zl²w#æ *„ê1×pÏJô}7öðÍÚ,s뚥ʕ{eŠÛ9ç;`?â¾¹³ð~ ‚ä¨çœ÷8ü½k`ø>s)3:o –®0“r3ƒÁôÆ+–y†.O—Ÿò4öXxü1>\ð×ìEðòØ û=ÕÏîÇﮥ$ `J•É8Çüž¸´ý™¾ØÛ¡›A³´‘>e–îÆßv 3+Ïcƒùúý¦‡Íw=­©Mó,ɼz ýнˆÉõèy«óh=›ZßSfîÚÊ‘Mxÿ0Ä cÆHÁö›£Ü"É$DS!S&ü±Žüë6×Å—1Áå\ùqYç!¢_âÇ|œqoJ½wâiFæ)RV óÆaço ÷ç­7z‹•ìΓVµ´òv¤ÒÁ+]¢”|œqØõ±8 ][éñC*ÛÇ4°…2°Ü¬ÜÏRßwœu®-HÈži™2&P>½1Øú}iï®\8’Ñ¥1ÛYƒ,` €xÉ?0ÇniÕ¾f‹T­¥ÎÂù2\£b7h*•)’'iÆz’yïÍ6‰-yg奡ŽÜÊY—'dñƒ“Ïã\4ÚÏžR+¦Œœ1â=»@nryî3ɬ^ÞéBÀ1‡É”«|±òXàòN~½:Q:iݽÓ ++\ßÔÒìcX×XŒyjÞ¡@Àãø@Ç8èk¦ì¬D¥mN×I³³°Ñ¦¹Õ'k;MÆ Ò)t©ÎÐOR‡Œô5à>7\øÞîßÁ¾Y¤…ƒ«_@3€:3“ÈâªøûÇzÆ·c5¶âÒ¼j°í€Nq’…'€zæ¹m?RѾørMA×í©_œ‰>üá@f8d€Aõô5ÛBФõ}êsNèêô­FððÒçºuµŽ9Õa²ó7Ã79 ‘’pàc=FkCUøë….nl´^5ǘ2UÝ‹d¨Î@8ë’FHõò­:ÕžÂ_x®öQp–q;ªËw1SµTã |¤ç“…É!FNvƒ¨êZ†¸d·a¡Û౎_ÞJÌ\ÿbã'œÁ®ïevùíýXË™t3þ+üNñG‰o ‹rÇp·6UH8ÜCxü:ž¸¨<+ð_Å>(sÿ,åC€ç%B$zã§N¸ÛƒÂÚŽ©ã‹‹ûû×»•äy^[† #…_\ýN9<}1ê3ü[²ðÕ“ÚÚÝ$¬ ( lecœ#$$:ûf»=£‚Q‚9§'wÿù‹_°ºð•ÕÖ™uÍÜR4Q‡8$É>žÕ‹ƒlIÉ^ýOÔ~b½ ã·ŠíâYŽì¸<ŽýjÆ…ra1K&ç*Tž§=0ë^Âwvgν®|ã«ZIm¬^#¨]²0(IÃc v£×ô­(*FÁäðËñÍvß´Ïìϼˆ«SF%8àçØè8õ®BDY—±·ùéÓ ü}?Î fÓÑÒµI˜—Q*ºÿ6NþrŒ6ŒÇ^¿§Ò˜ñÛ#? 2yõàUë»pÑ[`p£x8Îz0zb³Ô—‰’®OROŸÊ¹\lõ ŽYŠA- <\ü¸ô­ ¤ó`—Í_˜|ÈPg#¯çžŸ…f4e>é+œr2yëú –ÞëÉe%·Áàdœ‚*“¶€XŠ)WÄ…ƒ:`Ïá·ñ5Fkq!arÙ?V‘”ù!ÉÉù€¢’sƒü…A:@F2OS€>µoÞ@R$6T(좣±'jíû½2=ÿÏ­X6û)M¯È#ø¿.¿¥E2)ufŒ$£¯û^ÜöàV6ƒ´ä8#±ºÝ2x¾ÍÀƒ—/þ¬ð?úãŸS\ŒŽ2<Í݉Á8ã¨ý?ÏMÝÃø¦ˆ<ÈÇãŸÎª]F™ÓoIe2”H=räzþõ©PoVl4@œ÷I÷úsT¯ Š8wÇÂh;€]Ü` nÏ¿=ªâ ‘$r/ÊÌ:7·l}+£KÜ«[‰./”ј› ¿¶sžyñP^N²\`§Ì¸9ÛŒ ““Ç^qøz´¬‘Û£8I<6zÛÓ¯µe\ÞÅ JÿhÌXîVã8Ç$väþ•ì¬"óM–®“ËáB@f%}z‘œþ”Ö\B~Í"ÇHÎà=1Àú®j fÔbIB[60r6¶0IQÎzcñ8­+FA0KxÓ…V•ÉÌqŽXã®XûàÐÕ÷^ßK½Ô”[]'Ù¢¼Çˆ:2¨Rä¿hÚ >Ù«öòKsh­¥ZyŒØ1]\©hï3ÀWBáÇQšÙEù{¹Ò)n%Ü’ÇR ÷Æì®2¾:ÖšK‘Å6åP؈ò|Ä’÷lœzÓŒnõÊ£O33½Ôò<Ä3ùQHYn9_âÆ1ߨ«v6ïhcˆ‘¤{sã9Ç=ÿ1PCžd*òȳh9cœãõÁ5³á›Kß뉤h7zî¦ZÚÄ)XùÁ/# ŸânüsDå iÊnÈq„ª{±W†Q VfeD;GP‡×?/ZÐð¿€|CñPŽM{¸šSl÷þQû5¼£¬Ò€Bc*Jýì•ïÿ ekë}jïÝ[}ž'ŽæÓMҜɼ¯Íå]4‘íd,SvÂRÀ1Ü1ô!¶²Ólå´ÑôÛ OGÞb±°¨Òr |£ 0@ÝŒ¼d-|Ö/;‚n5}úµ ¶MÞ£<á×쟢xym5?\Ûë: GŽM9K¥±Úp|©# !ÉûÍÇ @¯h2¤ò[Ú[Ë¥ ]±Â­²4Bß.BœýÜ g†£»½y­|¶ â4e ƒ·RG|€2ÿõKg¥*\DÒ;º2bvæ0 œlp dÿ^>R¥jµŸ5Y]ŸAN”iFÑFI-̆GVvÏÞ9*}½‰ëøV¥¶”Há.ò¨ÎÆÁf^8ÝèxÁ縭{]‹}’ Âù)ÉÈãžÞ¤qéZÚE‚Û<òM„‘x玛½ýU‹ž£G$‰ô«E·Ùs.Có;ðëò‘ÏN˜8ô­» <]Ëh$hĽ\Aé‚G‡¢HetK“9P.#„ŠØã`Áëï]m¥Õ¹²”¡h&`¢‚©ìsž¾ã=½«%V™ËRVØÆ»ÓÕYP<¡•–'œ!!€Èúðy÷­´×Ny#)$£Æçê;ž†¯Ée WC$$ÙhåMÊN{qÓ‚H¥j\ $ÒÙ$·ŠÞþaŒp©¿ äó¹ÏŸÎµpr9}«V±ÅËáäÄ’¥ÄØ‘s* ÀtÁé×'­h[hJêP%À]«ò‘…ß´ãnC]-¾žÍ!š”Çþ¬+ÉÉB~ñø¸è6{äû~•n‹¾Æ?X¶‡á¥ù«²)ùX–3Ïì@=j 5ÅÌDGÉÌe;HÁ;ºr¥w'OY4²‡¯¾2höm-V¤ª­õ3,|.–%¤ŽâK‹yÉcÌ›‚ç ÇÝrë@Ó2Udû§çð„ž†kcqjè—líò¬`¾P®~R8ûÄc5)¶–æ,†‹‘½]`ÇLqí[(%º2»ÞäØZº[K™–É'n `qÏz±-©’Rb@wgjtÇÔS|µµ³ò& çqfN`¨¿lõªr\ˆáŠSvP0#$±/ÇHN?‘¤´CI½†êvqLÂK•PŠxá;NxÇZÆ×îìWLžÑP$Š€åîÆFsŠƒÄ½ÔšFþ±¡1‘îzœúמxŸÅë$ç ãi,’ Ì ¨Àlò¹ ³Z—$¬uS§)4ÌéÕ‹wã)ÒýÅÇÚ#3ùÔc®œ€óúâ­ÍÄúÄ¥ãÄq…mÊîórr Æâ@玵Ql'švÒL6¶ñ.pTˆüyíSnTœOI(¦îw^¾‚ØÈ·w;#âó7‰Ã0#9'=x!Õ‹ÝN±žá$H£Vù™~Y# “»áy7o¼þYäÕg•Ús(¡ˆr€°Î{žêNµº›M$vBYX¶Ð|×ÛŸ˜ ÐuÁϨúV±¶3仸ïøŒj p«;9e­&Õ ;ù c©Œö®R=SZM]"˜%»î&9,<Èãa·ŒóxíÜÓõYb’ÖîÖfŒÏ.ÎÅ@+œg‚aÎk*=D¬lÌÁÔŒ»áÝÆ7„gù#¥kË]›[MšÃZ–鷛讠DX¼Æm‡‚sž{rASßø™­¢¬6Ûï¹&8–E±µA)Ïük„MZÒ ½–ó¾ÈŸìÙØŒ×Û©àúQÐÜ(™/£–Lþ~[±$qÎÐI@:‘UËe¢Óa[¹·/‹¦ºIc‚Þ´¦Ð3³Ówuù—òGXñ%ö¡tmÒ{pBn- €Š “ÇsŒu+Ä~ ]1SÊ„G$ØÄÖðŽL/òFyã’«–o‰eŽ'½eŠ%1²ÈÇäÝÆ1зSÈÚN;Ö‘Š’µ‚ïtw:W%Ñn.MÃ,iÁhÛûüÜЧ¬|Y…¯!(Í6Ö¨Ã! ÝNO}ÙôÀ'#\ë,rGn#Ü ©ÚX “Ï Hÿë×%6®ò’í3IpNU³œž>cžsÏZÅ1*ÈQÎâO¿@8ã9çŽÜåÑÂ΀3|à {çk¾4£*X¹·¦„ë+É4’Ë—vs×®Oô欂ʤo ¸ÁÁ<‚—Oʪ«¨R à ç<Ô±:*ÆçØTìoâøíÉzU4(2÷‘#Hü€Å23ÇäzqE@Ó1‰•8ãåÞi9êO^”TØßœúÛÆŽ–×·ãnÄx%RñÇÌp3¸œ{rOJçt—ò¥Üò²3`$ÇÓŒwã­oø¥™åy%Vy¤À Êûº` ÙOLþ<™rÿn J”$XŸaÏéÈúf½y>YØñ ¯ßÅûu¢Cr±­˜‚±`ÃŒž¾¿Ê¼}$Úã$™pà ŸLþ¼÷_E©á[¸ 3‰# ‡ù”à##·N+Áñ$Rœ2žI,Î=ÿN•3ßSH|$³ªbGGHl"†ç#O×Ò°Y$Ü#-2Ø^ãÁþuÐlêŒ`óÛ§SéϿֲµ;m¹#lG¶HsÇʱ’ÐÒÄ K´Æ=M@IVr *’{~˜§D02Î8ÁlcúN*GˆLJçvG@sú Ë}„$w;ô<\vÇnõecämÅ@ÎzŒvþµHJÉ” lCð®ì¨l|Äd˜ð2}…>)q&C=I9ÏÓè‰ãVr†!9E¨Ö¡¹…Õ¸çÔYØDÄÇ'o–ÌÅŽ=O¿'Ú¾šª7…_~‡­CçïT8þĺak—:ìgiM60°Ø F”6ù0CÙÆp9¯yÓ4 /ÂZ\:N…dš6•l…E”q€£8#œ’ÉÏ|ñNŠâHÝ%@U—æ;xfçŽI$çÛ õüª.bÈùcÚBÉ•ÚHÁÁ8䌞:öéñõëÖ®ïRMüÿ¯ëCÚ§F4ôKB’)0%]Ã`çŽ8ú}9λ-mp™u $ù6Uz ÀÿçþU& É%²º r_(@fô' ã¦#Ô`Õ-2Òæí’­wµD¬¡ZC÷@b?àqËMNµ¦•’^FRÏ$‹“‹åeRNI\ó“ØtV gs3*<ý—±nrwt9ç‘Î1JÏI’ŒvÐùI„ºˆöºúnÈù˜í##àóÅKi¦Ï§¢[H‡c³¦Ù  dî)úü§¡öÒnïþÊM>¥°±ác ­rdòö!nÀœäu¯Njkw[6ó%vŠã,C8àüƒüúóYsk’\»³IówC.ÀI2„ÉÞ¾Ìzàç"’ïűF]"Oáw†çpF1ÉõÈ5²Ú¹ìu ’Úl™dŽ2˜¨*Tó–¯|sÞ:øZIzÿuNp:ñœþ½ÿ:äíüi’¥”É'ÞÃà¨ç·^õç‹á‰bòÈnI~2:Áì=¨P|·W!Å¥fzïÚm¤³EÚãc 0SÆ=zÕ½6{8„)0£¿Ü#Ÿ]Àc·ON+Æãñµ¿“<¸Õ·,å0ÏóãžyÅOoã÷Ü™BDÙ#ׯùⵌd’8Ý)w=ªÛYŠ)£1Ä«±]ˆ`X1Á¼ÔqÖ­›øPoµHÞHÎé*Ç?1@—jðïøYi$®ðI·ÏÌSçVÅÁ8ÈäSOñ ÒЇŒfŒ0xʯ'€ ç§~3NóW3t_CÜ>ÜfAˆ†H,²#‚Ttç¹Îp?“WÅ%tù’éM•Ä@,±¤¥°Kcq“ÛœpkÃí¾*\ÝI Är Ë…ùzñÛÆ\Œâ¡¸ñôÐa ‰†é¬±þö%ŽTüÀ®:ç<çœ žŽws?ªË©ï“kÖñí“È åÇÈÍ’=)-õد.žÀXÆ[iÎwv8=»të^)g♥·y-p$Ï’é"‡o,Œž‡óÇ Žk*ÿÄ2\J&¶uˆ#òåääö=O½h£§(ÚV³;ÝSÄE6Ë笷d p~zÞØÆsõÅrrëïc#Û¢ùNàFBËŒãƒÀÈ=· ç¡íÏÏ8Inée‰Ünò3òddO–#ƒœŽqÒ²udŸ2#"0››/±za¸'N£@ï´audK²Øëo|C3BXÇÂÙýÌŸ3Hù˜c’6œnåøwZÕ´É Ü/3Iƒ·$Èí‚ùúð¥sSêHìÒGŸ3hËy)ó´u=lJ«cumžEñæ¸@±¶#`ŽÕª§ÕÛ6nuÃuЕrÁ¡‘üÞ7unCc§¦G#5†ÚÛiwp³(¥dæÜ3œCž3õ­X¾†+ÛQá‘’ûØÉ$õËARŸ„QëÆ²Op¤ªìX@Ú;c ‚HÎ:vÆ:çh¤KeWøÏ¡ßY=´ö7 #£«O…7ucŸ¨íÒ³£Ôô-rkac äÒ¤<6è&“´sŽG~9Í:_†ÖúUøû;6§ ,Ò9`@`¬>ñÀÇÝÚr}½MXÖ|g©x^8¬£x\9Ú¬±£í;@ÎæË g®z¸Åj¡¬ ¿)©i¦éÆÑBÛÜiðy™c"œG;ˆúž8õÏzçüZ|3áKXÞKØöH¤ü°n¼ŒçüçžGcQkþ9¶´ÓRÞæàÉy2n|·%I8ëÁ^£žù¯ñ&·fׂW)Éà—% ã'’x•mN„¥-t0œÒÕ³CT×í'¹‘­Ð´%sžYx*xŒóüóéX·zñŸIíd#æ•-ê©þ†²EøìÁÝ× údÕ˜µPgï_vKyh:ã¦Iÿ8­¹ΫBú³§…n¤ˆ4Óºn]ÅŽ§ãì}€ëÛ";qq?™)ùYΡãÈôã¾?•Q†õï˜B°ÊòbI=009äŸÖ­ÉæÚ_y‘$ þ­ŽÓœòìG§5<­3oiì\¹ðóG0£ŠMêNäå1ôõëÜþëMì"êÖU‰@+$%{ãæ=>¿ÊœZäÐHfsœ3É#Ó?N¾Ãµ§ë³Åm:Fí5ÅÊ•’U`Ä))ÎG§¯ô¤¹‘…hÓ”1}¤ÛÍ 1ç–+!%»p¹ã×ç§äѸð¼Ñ1hØíê¶ÜúÏ^Õ­ee,äŽ6ä*çð§OJ¸/(4„—h88ú}?µMêx*rŽÌâ.#–Év<`ÔžƒÛÛãõ%lj—"fX‘Ð2 sÓýj)§s¡U• µ ˜uHB¨]¬OÊž¼tÏéœæ¹‰mL9ó˜qò²*€]¼’?^´Q^¬¬LU¶4–ø­™”\ƒiCR‡•Ã6sÀ#nî¸Îwãöëgw< ‘îRBªàóÁŒç4QYÉÝ&\P‹pA°Ê¸"ð>ý9ÇéPÜÛ7ϵÇ,Í…ätZ(¤ûÐÇ1­¼À”#žäôõ«Jå¢PÛHÏÝWÆ:àŸÇ¿n”QX-ÆWº¶,@Ø.ää0ïþúõX…”Ø8<{cúÑE&¬"å¤ÒFUÖBÀwo˜/^„tüªYnVu;¹~ÅG9ÿ´QEì –Cžr0IÉÇô¨î…b¡¹äñúŸÂŠ)éü3>ëeÝ ‘£8ˆ?9ÉÁúšÙKgšõn§Y Amȭ׿ÅVðÖÅô4l\Êe,r¬¡¢P6‘“Ï\;c¯ c·P)K,×)i‘æ;m]ÙëסôŽh¢¶jÊäœv¡ã7·—fœß×¼¸ ¼8Á>üsPèÙ×õøZî5¥}Òï!BñÈ8 ûw¢ŠókI¸3£ ïQ&}‘à®›1G p¶~UÚŠ1ž~R??½?JñO›x¹%ŽÅSÆÓø““…ÎlæŠ+ã+A)HúúZ£ÐìæÉûÝzœÓ¿\gåæ’¹œ®<±»ƒ×äc§ÒŠ+ºRÈ茛̹¾&¼*1Ú¬Ilgt˜äìS×N'ü'wS¾Dd@ l…ƒ¸BŽ2x'3‘ŒÑEhà•Š¶ƒ?á3Õ§B¢ Ô6p. R§$tàåýz+=JöK0ÒÈc ¼¢©Ã’FÞ¤c¹éžƒ¾h¢“ŠV1Nè²./e8#HÀ©ÙžHü>œþZöÖw¼fhfwCHñ6BŒúdzóš(©qZ±s;—â¹2º+nù¶§Û®WMçØ­¤H@tˆ)ùTŸÃòé‘ÐçùQEFÎȽ®Km ‘„R;ÈÏ—%1•ÈÎÏãÍ@Þ#û3KÂêH8•“‚0HëÔ (­%MEhJÕØ,üG+Z¼©#gr±tÀ#Ügš­'ŠÚhÞ7V ´ïPK~’IŠ*9×±OK”á6“Oów‡ å² J1î3ÉÍU¹ñä¶Øäíù¹àœÑEi-üÊZW~=eH" ‡FÁbã N~ŸZçµ_™™œ"°ˆ—iæ$öÇ_ëE¹^ƒ½Œ¹IEf'wrÎ=[ß?þª[]UŒR„dIµ™ßYKc8 õË&Š*ä”]—BoxÜ¥© Žê¨X±Àô àç¨éŽßJϹñM‚Éq$h“Íf0?,§–;³ƒž¼ýO#š(­éÁ2$ÝŽkUø‰e%"0§îä»8Î úzÖ&£ñ5®e`±ô<NsÛ<õíEèF”ØÍÉÇc ëâž¡1Bªs¸JìåâÁéÇÒ®Ù|}×´ˆ¦de>z´ry®Åd‰ù° túã= +©Qƒèrά’lÁ?õØí%‚+‰|²v9r§® =3éÆyÅdÝ|SÕo.<ùÉ:íe>fߘcƒÓñúQEu*Ö©L±•›µÌ;¿ßjM+~ê7™‹;F§~Xœòxž¸â²æ ©Ø¹nÛÆN:äç·ø{QEmÊ¢¬ŽIԜ߼î3ÉgEgRQÀÚqÁǜʛf ÈÏ€çßùÑESìd!;sÊŒÿàþqúóD‘äí+–éE=H“ˆ÷Ë’=8êyü¾”Ò¦Id‘Wi‘‹3Œýìç'ë×4QG˜ù¬#ÈòÈ ÈÍ'A»$zé]·‡-ÒÓO‹pRÌÙpîFþzlvQYËc*›!÷’}œ3&5ÚxNÏÃ?¦xã&¹ë½M¢y~n{œõïÁéü¸ëE)&LRfd×NΌͽH$¶N}ÈÏáÔÑE¥Í’?ÿÙtango-9.2.5a/doc/src/dance/tango-08-27.jpg0000644023471100065110000022167613034745265014650 00000000000000ÿØÿá+ExifII* †Œ¤¬1 ´(2Ài‡ÔòCanonCanon EOS 400D DIGITAL``Picasa 3.02008:09:28 11:06:33š‚6‚>"ˆ'ˆ@0221FZ‘’ n’v’ ~’ ’ ’†|’ ކ’š 0100 ÿÿ „ X Ô¢¢¢ª¢¤¤¤¤ ¤!²}- 2008:09:28 11:06:332008:09:28 11:06:33>÷Wþÿÿÿ5.dl"t ¸ Ø  ø } ·  P 6€ h  ƒ“p •@’ –Ò —â ˜â  ê ª´Ðà@2@j @p@ v@ü–\ÿÿÿÿƒF€@ÿÿÿÿÿÿÿÿÿÿÿÿÿ5‹]dD 4Œàìÿ™ìÿg1ˆà^üÿÿCanon EOS 400D DIGITALFirmware 1.0.4unknown( 0 ° NNÕý;]ü³Õý;øúþúþþ/ÿÿ Ÿp":ýPÿÿÿÿtH0012004€P† àÄ"l> 4c6 Xt3t æc¼NN³†feÿÿ”Œ‘€|(Í++ˆµ·h³²?½³ò43õ´²’ÿþ¹o––º { ƒçç¬ ¥æç–` XÞPÙ ÜX Ppo––º € 6--¢¹XÞFJ 3Vÿ33œÿ33œÿ33œM¦xþcð”*‹þmÕ'¾þ„‘l õþ KX6ÿÂpVÿÖâà|ÿëºP³ÿ…\ôÿ<Mh6oØsŸê¬ ¹Ú¶€ ë •¸ &Dqð ©â.` ô%ÿÿ3d.Z6a#€çÎ ²8__ÿÔÿÜ© +1·$^–ÿY&!§ÿKð ÿcÛ ßÿTRÔÈk¸kÈkŸÿe±ÿÄ6løTýÌk\œ‡‰2ÿÿαঃaII*r€S;m'F2bc3ea24510068c64be8724119dff051R980100@H(PÀHHÿØÿàJFIFÿÛC  !"$"$ÿÛCÿÀ p"ÿÄÿÄA!1A"Qaq‘2¡#Bb±Á3‚Ñ4Rcrñ$%Cs²áðÿÄÿÄ1!ÿÚ ?Ê´{R©]‡ yãž‹mÅU–$*¹ÆÐ¥:~øèÛ„PiÿÜ?ÓY¢,ðížUð‘¶à’AÎ>š‘%¸ÉH1… ò³‘BÔTlÏoNZˆñ´ÚyZž%ðÈf‘\—`sÛê>ÚÕóAAÅøÔ(®/¸à~š…wf«%sõ×¹vû郱s>ºþ¢Ê .·#Em :£¨’ÓvZ˜ÕÞ† •cb ä@îѾœöÖ¨pžf§žÝ-㣫DûX`B:üÇc©B™d…7 üu"îG¸UÐu눭æÕ~4q™<4”2—êc#(~9j=h3A4 ‘¼c8Õ™Jçž§X–æ2¤yOôÔ>  4t¨=òRÅo:¡þ";úêæ*EÓTÑß)*f‰3/†®»óË`Ü9‘œý4ï$qþð0äA=}{¹-B—Ž&ŒÈ6¦O2½ÏöÔ›0ëÔq{ë.#*EÇæ8þçT~[­sÔ¸Ê?1• 'Óä4dáZ8£Š¢ãO¾B ,ê’†3B”ðÅþ)ñÌ–õûòfÔþòÓ?ÅÊ„Žì1ŸÔêZ<ðgY+¯3‹½‹LQLlc/¨æX9“ÈsÔ6à~’ÿSS¾¶ª9ªI‰d`¾'¾?7^ú>¸4v¾‚Žž`%¨—tÄF@'üÃ:§¹ûµ¦ÛG,•qûÍDœâ–ÃÐ’y‚>ºšjxgê}µU[— 70etƹZø?‹`­š®¢Ï_%²R®³¥;4dz‚¦‰¥âJu 5<Íß÷ŒNˆxŠÞ©)éêØIÚ²{Ñð×àÊq‘žÙÓh¸OE`¬²¹lÕPžX'^­_Å‘»Ÿ>y|ù )ls;Å$˜6«1ï¼MÔÞª`¶ZžÝP›bñ° HF97öôë©A„æií³Å¬uIT0@p{]Àê,œ#MáP×"G!*áA'Ÿ.üûêÆjºSxž‘©Uˆ‘br %AÃdv%‡ÛV“’zhá Ÿ†²¯\„g´²§ü©:}Q¥ýÒ •¾½©®ËÙù÷yA'—˜tÓ÷ÀÝŽ_=(= Ô)§¸ÔɈ*ôÁ;F¬¢žÉìºK„®¶ã²Îâ"ß?ƒõѼ<5ìÚßj¨°Ü,mUY:í÷áTþñMŸâöçáŽ}ô©°q=êÁºÝoŸN„ q¸Â{•Õov£¨zÊJ©ewbÎ’y·Ôêà9¿{)ºÓYª®vZè/VÚd,æ"EBGަ3éßéS5+"ŸÍåê ãgp§´[ZˆéU$ ÑËç!NF#몾.â*‹­¾ã$ÖûzTÖ"{ÅDP”y6Ç,àtÆ3&…ügV?îN5<Žª}u6šN\ûëBëŠVI®Õ@…FbÝrIõùhy²ÇâtIwoŽH¡l±òžçùê‚8ÛÅ”€9sõ ±ÔÇMnhf%K¶rO—á¢þºP¬B’ª¢›k:„ñdSŸÍϧ,èÆèÑ@fldªÊ‰IpªFÕ?}=ÒÕ_n¹S²[+©êà„«ÌÐÈ àtÉÕ…¾ù©aæ‘ð¿!ÔýÈÒÏðßi¨k½}T DñÂW%Ù9’>[€ôÓožJÁÒ’%]°Æ 9 =OO‰ùë{–-°»íÆŸÓJŽ"¡ŽN¼< n¤¯ÌGêš—JY×(f–w(@ 6dýô®ö€Íiàû…S*Ó;bž5' —88"yöÒñ‡ÿKycXÊŽ]õui·ûüè«$!;ï|gûêµ*R8ycL÷sƒ¯È.6ø&Yd«Wu9c/ÿÖ¶-8ª‡Ü.?àÅJªê±œ¨ì^]QÖm’ŽÕ#újÿˆ/VûÔ4´öÚZÉjÕˆÜc qÐNNuEUo¹ÙÝX…‡,ÄuòóÛR‡æ§^)mÒ+2¬ŠØ8<´QEHëªÞ¦–Iê‘¥ÍI ´d·ÓT\x:#’Ižž3†!¤~øøèãEQEph¥’:˜ÆÖi!mÈÙ3ëÛŸvšºí8š¶±ª_ùùùj ,þú”¹äç 9í¨'ûœTt†ª²xýÞO)xT–¾3ýô#÷ªÐ7*x’~fäOS¢N>šH’’‡nÌ)g§þß×P8"†:Ë©2®ä‰ mÆrsª5±JZÁß­f3Šp¥d çeÜ2:à0)¬âUVFer3““ŸôÒcÙå|ôvúªJX·=3ЍÑ<½~À~ºup•Ð×P£dÚ@ÛèÃuÎŽu6šÝé æKnè=zi#ø¨·KIÃÙ\.MhRÈÙÏ”žmhÉ|C7†œØŒ»z|4üWÄÓp„oÌ«ááÎáõÓŸF]a±Ê‘Ï×^ý5꥖Z–e<µùÜk¨•G<ÐÊ’G#,ˆÁŽÄtÖ–ha»ð¸xh¾÷nñ¹rÁ)“®³,]´oWG'²JAS²Þñ0=r»—¦³Ð¥áúxx~k„’«Ê(št| íÈù÷úê¯Ù•,Vú’Lûı†—˜f9'> rúêmDõÐðu¼MRv¢FoŽ:ô×N§Rªm%”`ý5¼š¾MÇã·–¥X+V·¿Õ•(r~Ú1“‡©¤MÒCž_”ãï¯Tœ'lM<0ºJ«¿vì©újè]ñ Úæšuu Ça ÑéŒêÇ…m“RÕšz™Ypʹò=7IQ°Ilsl 9»ŽÛ ¶‰b¥¥†0Üü±àäütÑYÃüE]e›Èp‚âH²Xzi÷ÁôT­h¡’ËxL–;@bH ¿^ýô±·ÿ³–p¸\©Zz–摇̮}y*ütåàù¿hÙèj…7»™éÑü s°Èg¾±Eœ ±+ÌÛŠF99,Þ¿MgïÅ…tkÃ6ërÈÕ3šÇ\ó …þ£ZêC"QÇüg™ô_ÿgYÏñsOOû>×\«¶ygxWãÓîtçÑž¢P^ˆæ9ëõFëîÃ]G¤?—Gv>$ºPû7ž†ŠÞjâJÆYß¼(Üè:dƒÏ¶æM1}‡Õl¼ÜhNÓïÁ€=Ê·?ÐêQiÔ]¸gÆ·HñÔ¿¾fUÎÎÿÓ¾¢Þ¸º†–Õ²ŽâÏ&Á¶8HbN?ˆã—ß\8ÒĶkŒUÖõ0«9`@äéñ­e.þ''jà}† '–é:±ñG!ü¸Î§[ï‹ 1Êvíç´ b~±Îe_Lç] TEêßAñÐÓÜªŠªRœå‚–A¿=ZßxŠDDÕzgò|HþÚ_CPÐÊ%¤eWã#Ÿ]WNõ³Hd$“–Ü3“óÓu$Æãt‚97Ìf™ðrÌ €5®­¶ól§>cUƒÀ°Ë–³_á†Å5ûŽÞªÔVUYÉ“ÎN#_êßåÖ°H0š`6¯åP9¦±Ð ¬‰¢GfÿÀQð-þƒY¯ñ‘WßlXÏû½<• =7«ÿÄëD^.ªn1A?†1i Bp]W©¾23óÖiüEYkŸÚ›^+¶T[ê)Q0zÆ€`c¿\žZsèIôCò×èEùjÖùcª¶ ›z7J…^_";j®/ð×宣à3öѳªÏrã;l…°¯!‰» 0#úãCÑÓRmÓ5=Æ–¡zÅ2?؃ xq54uÖùiò¥5ï†õÒžñV”3=;î§ ´ò]{Aâø…SÛmó¡ú³§›¯`t>m¼#VŠßí-D.P—SçÍè5˜,R*‚Fò®yóo–º‡Â¡0B¹ÏÏSgEùö—ÏU^Ÿé®bö‘Û›© h JiØîxÌg±^`ý¹L¬±‘ ‘Ȥ)8?mI¨¤\´ŠÙÇmCzZЇޖ•ƒÍ;¬Q(Ë1Àþº Qø^²þÍöoKXðˆå¹ÌõrrÇ,ìOÑsõÓn±öÂÇ éœê¯„mQÙønÙn…AŽŽ™)ÆßTPê¢qísÃc®Äx‘ÓHãç´ã?\kûFLãOh· lRñ/‰;RÐÔ5=49òŠu;JÓ-ÌüÈÓKÚ”TÚ ‘HTcŸ<ëRè« yäã_8ÀÈ9Õ½¾ßîÞõTЩRU¶g'Pg‚hØpÏ#Žº¡°”ø_#3rçæ×h£-ÝdÍuñÑT3~_@qË_°ÍNùfñó#iÔë;ÓíónˆÆqÓ禟° ·×U?]hÍA¥›Â¡]£h”ZLrÉ\Œ|I=´°;p ‘ˆôП‡?‹Å•DSÔÍ1 m°9üµ/olj$”ÄÛ‹bTÃúhÛPÚ(¤µ£«4¨Þ'Nùéx¨¥ŽÜõ!OO-$Ò"F±(wåÖ0âž*§½qtŸ´æ¸Å Ï4ÓGƒ$@œ?íëßYæh¸C ï*àXàçF‡ª*h5ÊÉ„×Òø4ÎäÎ6˜>`hx˜ää°¦H݃Ÿ§M}n—ömòßz†5y¨ª#@ÈÞÉN~£:è:ñœÃümWE€<7’"`WŸ~GNÃgµÞág—â ±·×Ér–¡”ßz{tút¦c4ƒ€q׫Ç^Ô ½)T¦€.D…dTž\’–)ã¥YŽ@i^4‘xÛÆ1RF´†\Õ AÆ '§ò  ì¥{~5$jUs´äÓØ³ÇJT”•Á\@ÏB)Àð)8ZRÌ9Û@fœ"ïgŠ›yv9Tˆ…GJ­ä8$î4ß.Pw<ÕæN¼ŒÇÁ>Ô\Û3§Öž¶Ì£99éŒÓÄŒ8Ú:Sƒ¸?tt äõ8ö§FsNW|´S‹°å  ë”>p9ç½<”†ýâ{u¦ÌþdÙim­ZY7ÉëÀ44 î£ Ö¬$ Ç«QGÿÖ¥QÁõ UsŽiûp)ì¡FE0Ÿ^Q@H×4¹òO5 ¾£Þ[œþoÏÇÒ¬„ç< §æcüñJ$ÝÎ(è—Þž³zsTCsÔô§ 1í@ ?^sN7=0k8KŒúR}úЪ]tç½$×[†3Y‹>8íHò1Ò€$–R Üyôª’KÏZ|€¾0{ûÕ½+ÃÚŽ·r!³ˆ¹îÇ…_©  ¢û¨Ë{óÖ½nËàìB×}Þ¢ær2DjΜßô໎©0ã°•ÐH²dŸÆ”r=kcÅ,z¬ÖPLÓF!œsX Îi2ãÌïŒT’ŸÞàÕ;MšúÖîåÛjŠÌ|œqUî9”ãÒ€,Ù92~•¨­·§ÿª±,¤Û>Þõ®Ž3Ï_z{ÉÏJª•‡æ¤vûÄãÒ›!€‹íŽNÞ‡<Ö¥¬€ìÉè3×­eÏÎõ÷¤µ˜´á­0:ˆg]üŸ×­ZK×5…ýáç`Ÿ½Í 4$œÿ­gÜÈ¥N:ÒœóΫ ÎzzÐpWuéV—{õ¨K/÷‡ç@¤PWTXPÜõ÷«W?xqïPÉåõÜ´Ài+ŽœR^xý)æ5 sL1Œž´ÒT æ© ‚Àw«“(ñÔ÷¨Ò ªq@ »¯OjPÃiBg<IåJBÜ})*ãÕ# ÏTDšG— J…v°ÎÜÒ•©™eû¸  6sQ±ü½}i¥å7ð£,íóg4"IŽÕ ›·jˆ/µ=žÜPóÈéFîÜÓ•l@ôâ€#-åEHWŒQ@mÐñÞšH'Šsgšiî)€ :ö¡p):Šrñí@à£ã5r(ÁíÍQ†áaL‘ïS õÃÅ /ªb•PrëTVøÀâ¯@w}E&ÁíJŠ8÷©qóR¨ºPvyÇçK€rp(dçõ¥ØU±É  jD”©\œÓšõTãh¨ÙÚåÎjÅ ž}°NÁןl´sRPç#Ò,q‘¹"€D„ð3S†6ІÐffÊãήìÈ€+ ?Ù¥gÈaŽÕ0@I)ÅWãµcÉŸ ‰Ž”Ø`Úwž¦­¢@ DG þ”ð¸RXñ@]¹õ¨ä“p?Ý »äöRYpH㔳K€GåU³Á$ЖÏ'õ¨üÒxTnù=M(ñ ƒœ“RÎGZ‹ŽAÒäóé@‘Öø¨·29ÏZ9'Ûh$Ö¢Þ9¥\’MJ„u?•<°'ž•“À®ŸAÐ ÛngQŽª§§ÔСxaõ2&»s ¿oï5z^ˆ?³­ÖÞÖ×j¯b¯ÜÕ8í #ÌmÇÓÿ­]5µÌ…cŒF‡ø›µHV¶k.îøsü*qZ ý™l6C¸“·«K§Eû˙̬;gŠ»o⫈ŽFOM¢ñN!Œ¦*¥ (%Xt®$×qñKTþÓñkË·nÄ ï\0äÕ /Z_Ïf“G•Y€z®Ï¹Ï<úÓ"˜/©’©ŽR:‘ÔÐMàÏ \x«Y’ÂÖâ8$HZPÏБڡº‚{;ÉmnP¤ð±G_B+Oá…İøÂ&„Æ6Q]§Žöù^õ$(Žž´b å‰ÝšCŽsQ@ß&EL­ÈÇò¤†óT®™„wqWrqÅRºÁ¹Á¹  ¤çq/MT,ŒÊx÷«R“Ç›RéL ÷ã«ÓJŽ9&­MÈæ¢x°ýóš°À„PjBœ TŒ¹+éJÜdÐyAò×>¼Ó±K'ú±ÏzR&€E,‹,p3Ú¬/ݪWÃ*;Ð=Òâý)†åuª ‘œÒgŽGJ¸g— 3|¼}ê5ÇP8 c:P¼÷(WŠQ!b âš@ê;Ò'|fQÆ)Âà ñU íúÒ þsí@•42ù¤ŒcµœsW,—.qÖ€/Æ}h§ŽÔP8ÔÒãNojg¯·j`*Ž=iݺS@ gFiÃæóž´&Úã£t§+qÒ ÁêkrÓˆW§JÄOjݳæ=r(\~4 ~4â;bœ<šjŽ˜ žž£’1FúËl‹³Æ5‹œ¶3Žâ:1°Øö©mÉErßÊ€ÏÙ]ÀÔ æ ùsZ1¶áÊñš‚é~ö€ l‰˜t«„`U+!‰›-ž*ù+Ž¢€£×Šs‘¾”€¨x}M+:í8uéÇ4€…îÅ= ëMNb§ÆØSŸÎ˜ )ÆwëUep±ŸOz‘Ÿ<žµBy dg¥1Ÿq$úÔ,û¥#·¢^§šq4ð{S{Ò©ä@÷ö§–À4À gmcòÀcÔP.6•ã¸Ô× —ëUxç 1þ•&zQ¯éW¬-IJîa•ó  OREÄã÷Tô®¶݃‘ιñsI€AaÚ {×—ŒœR«Mrsˆ€-êy¡üCu8ÆòµÊÂáXž¹«*äàŒâ€:‹k‰&_žBMnéåcÁbKW/a.Äκ->_0ŽsH2ñÃñ-Ï9äW4 5¿ã6ω®øþ.Esãš &ˆàã4HŤbzÒیȸõéLsûæ Ãá¬f_ÛÆ¤Œ£tâ½Î{Pceœ³Œc–¯øX ñåšõÈqúW¼jÊ0襃cµKÜñ–…¬ÿm·L+H?­r€Óרëq¥Í¬°Éœí9â¼ÈÅåJÑòv Ó@4 ¤qR&Kc"£þ>:TW’4pîSÎ{Sý¿ÝÚN5ay¬˜ì¯$Eq/^qR‹+ÕçÌÅ 4±Y×d‹¬ŠŽxo!‰œñÖªC;Í!Þr}éyIqŸá§‚ãˆAÁÀ.2sœÒ›˜Ò –o˜Óмãb¨Ü.0O]ÃÀ¶Ü•úu¥lóÓ¥)*íJ{š¯/£Þ•ÇqK(á{sëJÙæ€£åöªW¿ÂM_ÛÛ­P¿09  é8¦1;1íÒ¥aùTax絯LÒÇšp=é@Æ3É Á i Çî¹#­!ô ɤŸ|ÒŽ3Å zxäÕË1ɪŠ? ½f'ÛŠºÝz)Ø3EríÐqïLÏ×­HÞþ´Þ¹>”ÀD<{T£{TIß=*QӜЋ¸þt sÍ(?(ÏZ29&>µ¹eͺý+5¹§ódŽqÏ4à9â†=éËØÒ^I₤>iÊ0Ǥeí@f=÷ÍíÎ*ÒFY¹Å@ìc½-Û~' 2=;Sòˆ5^d'#njéa“Ïz¯#…RÇŒRë1Ê¡Y‡5z.iQ[Îl{Õ+Ï™ÑñÁnµÓZ‘öÏ~)”tiAÿ^Fjõ¤–Erçšê¹a»¯¿JÈñÌqŸJŠÙƒCÖ¥è1žµ Šâ½jcøqÚ€!•¶‚zb¨y5z肼U78ŒžœPFl±š84g9ã­!hÄóK’•3©#˜  ‡YNNÞj­þ¢o.9²–PôØ(’ÎòœÏ´lÄFj~ 5Dmˆ®iã®hkŽæªNtiòN¸êj³H$R3@Žx&”ýhÛß9¤4«ó*ÚŒ {UX‡ÍžÕhcûÐ×½K»1ó×½Ažµ 9€*¾y˜£-Ž˜ïRH0ÿ¥"à{PäoÀÉ×h ü(Γ@'ny5"SQ†ÈÍ<8Œô  ±žiËŒš„¾zž´ªüué@‡AŒŠQ‘‘“ŒUe|ŒçRÎGlPeÉ>{e‡Z„´óÞŸ9Ì­îj p:ô  ‘ÁØnõl9­4ühÉ~$Ë4¬…}ïY»¹c@í˜ •½5²Å ʨ¬(O9‚jÿ›ž Nχ w¤W9ÎÓU]ÉcŽ1MIäø  %¸Ç *^‘Ž:Öh–MÙÍ[Ó]àÏJ´tˆ6Ž^ÔŸÙ0gŒÖ“Úš9ç½ 3¿²¡ü½FmÖ+ƒÀ¥j÷¬é‰ûq˜Œ2Àèh0éëò1$1ϧCg4ÔQáG9ªR¾û =®ïTS–ÕP²×ó@ >qè ÷M+}ñJ{ŽÔ€‚@”;fƒšYzÅõ óš0vŠÌ¿'+ëZƒç­fjºâ˜ìîi¤`c"žëŽÿ3œúPŽyÍÀ¥¨ G­7”m#éKž¼REåíQç ãš“9Sšw?v€NFzÕÓþéÏ­f¯'>•©§ð§Ô¼ý4R·4P(OSßÞ“¶1õ¥#$äñšTç4Ð284äû¸Æi S“J”éCd­(ëȧ½¨#ã­niYû:ÿb¦+oHæÝy  ǨïJó¡úôçÖ”=é«÷ø?…8ýìúÒ&C“ŠéŠÎ¹éXÇZy€à.xïM¸e[ϘÕÄåwv¦>Sg¤hp žTÕÀyàSeQ´ŸÂ¶ê#¼`:c§ÐûÖz _dzt­ä¥‘C6TóF0)Ž3žÜPÆ ¬r)žJž„T’G™[§Z`‡ùÓ)ãuÕb»A9ïVgN@ÏY·*O€q£ÛÒšç”°éœP‘~Z°¤zÕ5“o¡Ïj±oJ•q¸ÔŠpÜ „O"ž¼ÐS›¯éIÐ;Q#€D¯¸óÅ,re˜qOÈ䚦\¬ÌGéR¹d]ÃÓ¥Y,ÎiªsȬ朰ä÷¦ïlphSÏr ¤ûLa±‘PEdÅ|ɘªÿw¹­R]Æè"E$-´©  Áx<þ"›öð1ŽõM+[´™ÏLç( mx[ZOßé¶áˆûÑü‡ô¥p<1ÛsdÓ:g5ë:¿Â(åC.…{óùcpx?FÖ¼ÛVÑ5so¨ÚKnùà²ðßCÐÓ¸‚+¥‡eqlÄ„8à‘Ö³8 ÍtözÄ_ðŒ6™" Ë’§ês\·r?•L„cÆzæ 7O¿ƒùÔãî6*›FÙäq@ý©÷ç<ÕÛIÃŒ0ÝŠÊÛ†Î1Ÿj½§`JÝE04‹Œ‚5cOéyÛŽ*8 ­ØsuŒpE 4Ï"›ž:ô¡øâ€:RAÏ~jƒº­ùÉxÖ³.ãèç¥h. öê`Y#çü)Z†ûã>”7Ò)~ôc®hnàPü¼t­Îh^±¬»óóŽqÅj®6ÖF£ÌàJ`ScMùãÖ—qäiNhs‚=ûSGZ~H†…†Hí@ ¿J^sž)Ùǯ¥DO\ç4ªùîh¹ 6ò¥ò£Ü~l ‚\ù¤ƒL†ÁoÊ€ Û3ÍJ$ÎUª)?ÖiXüÄ÷í@2áÀëÀ­K[/³ –QûΠá©´»5`·RŽOÝõ5-Ëò}(‰27}VF îÈü(2néëÅ"Oã@6×»(8'­v¾¿`@víë^u Žk¨Ñîš"3ŒHaÑe30Á·uOÙêšq³ÔmÒâÙùÇÔƸ/ê&0¹nüW©iIyf°Ç,ñŸÂëÝ%¾ÑL—–8ËÄFeˆ~x~µåã$“ùæ¾ÒšÓd•ä¾<ø]mqyý«§lY¿ÒP—ýà=}E4ÀðøÑˆ>ƒ¹§ý†áØ……ÛýÑ»ùW¨ZxkHµ_3qœàî¥^ƒ^†ÊCo§ÚB±¡ä쟯zwÌ-¼-­^°é—LOOÝуÀÞ"ˆdé7 }Ó“]ýÇŠ¯D¯ºìœÿ ñPÇ­Ýܰg¸b¹è­Š.žÜé—¶N{y#aÙ”ƒM°Êݸ¯bµÔ­î!6÷Ö‘Owuþu^ûÀ7¸¼Ò!#˜\d~‹ç,r}© äŠÐÔôË:项€ SŒâ¨•ÚØühÏ—pܲçƒZyɬ›µo´¶=é*GÎ{TÁ‚ÂÁ@#Ò«ZÂÌ…™‰ç5(içƒÏ4T`®2; …¤¼p9¤–#${Õˆ5Vqs$ž{ÐÓ¿§îœô ŒÉŒÒ°ùO4€ŽLï§½#ýôâ”ã&€8㨓çLVÇðÖ=ÿúáϦ.¤äb—Z=+RtUq’2knHd¸k™¦Nk–—/!ÉÍGÁ¼ÔÑ.[Ž´F•,`(ãš°°ºØâµtâTŒŒ”ËUTr?Z’gû%ÖÑ÷O$ûP_¤Ï…ËǯJÙ_ˆ1é„AjÛˆûÏØ}+Êï|C;#[Z}÷ë:1pÄï}¹=úÒ°ÿ'Å)tY|Ĺ{ì~íqÇ×=«ÌuOxƒ]ŸeÅãEn#Œã9õ=ë™W’8÷4«Ï§­B— '_¼:§ºÖfKí˜ýÞx5—ý¡#9?¦h¸+ua¤â_ºqíTÞDbÇ•ö¦ŠÊ’Ž­ê¼æ´¬fù†ÉÆ;ëb™X4lÌ3ZÝ2æÆ÷ñÖ€:Û+™"Äœudæ»-PY20¾Þ+‚ÓnÑ‚°ÁÇR:Šë´´¶»uhØÇ(èëÇàj@êõo [xŽÈüÁ.ù[šñýo@»ÒîÞ ×?Që^ߦ´ÖØI±ì㡪~+Ò£ÕlÐ(º„nŽH¤˜Œ{VDìë’+¨¿µ‘'“z#¨¹§ˆ½óÓÚ­"“{W=jp<“ØÔÏ‚­gp®SÊnô  £ÝåÌ<Ô;·^D; •¦#e'=ê9%äCf€4ˆýå9†¦ççïJÇå"?úäúS‰È4×ÿZzPÝðzPÇÝãò¬]@ÿ¤~´8ZÄ¿æç0)U·cŽ”€ã©4öéõ¦œ úÐÇZAÀ4ÄcíŠ7õ 0j5å;#Óß8àûP³Îi?Ö’‘IúP—®sZ¶\Ä?OjÉQƒü«^È~íGµ\aÒŠW( _oÍøÒ±àãšN½=hlþTQÖœ£ñ¥+õ¤N8  þ´óÀÏaM^´¥°ã¸ .;V¦—÷=³YJÜ ÔÒðzÔaÆHé@?/"‚x¦ž‡Í  Þ;Ò¹éš~þiÏÉëÞ€*Ì3t™éŠŠéãÎÒ@ç¥IpÁnQ»wª÷AKgnIéL ”°ÏLRA* 6r{SRg>ÕmóF‚4nUÿI‰‡¥^f³º¾ÑZð>”ïZiÆÓ“F@<Òg9×-¶cÚ£F9©.Ffüj%N˜ ¸l€j¦Ø+ëVn98ª§;yç¦q@ ÇJQžzñÚš#ÔRçÇJ:0¥L¾‡š€õ8©Tô ³`7j„œ?^}êSüF«±Á4#ýjŒö§ëøTyæ˜'&ºÿþ£$‹’±(\ûšãA÷ú×qརÇXsÙP þ4˜Iy#¼Öñp§9¬6]®AàÖÒ)k™5™sÙÙ{Ž(0¤óÛùÔÈ0:qšj¡Á©Óõì(ð±F8>¢™ª]—U~ñà°©£M쌊£pªeþT=œQiöfiyº‘~E?¾¸õ5Ÿæ¹¶H9æ“íS]ßJ뻎¥^†Áq’Ç>€+ˆÚR ž=qVì"Q*yƒ÷lv“Ž@â€:K­!"x§O•_†p½gKC)Io?.Gºu½´ó" $ÈËü'ÿ×U¢¸s’¿~3ÇNãÞö¶¬íæ@Lr/]ÁJé4Z;K·É%º“…ŸëŠÎS[9ØH‡; ûÃÛ×é]&•-® ¿g¸Ž4˜¾8ö @Ó®ÖKXþd•|®½ü .£0Ø®œH¿¨®FeÐ5¶ñoÞ¿ˆÿ ¿ý¬—ªXé•íøTÇx¾Ôyßhî?85çÃ_LǪðzî­¦B„ÈH.¯´õö¯`aÔ®Æ$¤[ÈÏ;–Ç Å8ùhó)„r “ÔãûQ9séL .üÐP㉟uÍ¿9üéÅÃKž6⢑·^ÅÏl Òç9ô§1¨”üÆœüýiÆ?¾Sߤòy¦³9qéFy=9¦ üœ“X×¹3’{úÖ¸8LÖ5ë¤míߊ®äøÓw +cÎë@ SÎ9$šp\õ?¥(íH§Žœž((X’3ùÓãQ‘H5Vk³(¼P$òßé@Bòpq'ßš„ßA)%íÆ§I aƒHsëOs9¨ÉH @ÇÝ[­iÙ F¸®kyG ¼`úWA¦\‰~u|öͯӢ€9“ÆiHÏn´Âr9çšw'‘ŸÆ€Ó?JqÓõ¤cƒÓ§J@Æ€'O®iÓŽ(N=(*hBqëŸz×ÒNP×5’ªAåMji`ª¶}h\ŸçLcÇÿ^—9äŽiðNáÞ•>µ'péÒœÇ#>ôNû–^ >‚y¨+ÓÚ ¼b$ÎOˆf¸‘*ð{“L Øè “ïM1ˆÁ8%ª ×GøG×’éT–PGZdM›ÐœwÍkƒÆ9ëXVò—œ3psZ“Ü-¬IéÀõ4oË%7eP«ÄÄ‚às\”Ú¬ÒHÎ\ŒúT *îùÏ­²’ÊÚUÊJ<ÁïÖ³ÚÞD~„jÀ‹R™0<ûšž-jë'snÏj·uÇQÏ¥Ss…íZl´¾P÷rލŸu-ÇÙብýУ9  Yã‘ÒŽçÖ¶äðˆ¢'~wÿ|V]͕Ռ¾]Õ¼°¿¤ˆTÐ9É4å”$ùd‘ŽœÖ^²áeòñŒq~õ|°R éßéXz„¦iËÔ“‘@ô¨8,q–µ›¤N«Nv0$Õ–e•ÚB~ñí@ mž2Gzšé¾Í$ ¨e˜`ƒúˆ&F}1Š»¨ÇæZÅ.rcèE 2Þ=ºq$sßš¢w˜°z•¥r­ýž9$ V`,yÎ{j`tžÔ<¨Õ&æ Å\g§¯åZZ¤er“¸16>÷¿ã\]­Ù†i:ž„zW h’C¬iMg'ÎÀ|„õã›å õQÆô5zM‘ wð@sÒ}å>þ•”Ñ\i7oÆJœ ¸ûÃüjüRC:ŽñçŒv ïMÕmîm>ÏpË*ñ‡<Ö}í‡Ù®æÒO½÷— oþ¿½söö^`ó,¦ˆN¼c${õ«WLÖæfkmB ß?)4€½c}$Ϊ·~0A®ÄúU«$÷–qyr³«(,A(s‘·¾=kµ¸0YÃ5ú¹Xx߯p{÷“ûZísXˆ$峟jv°H‚G>ô¾B…Æ>¹­ÚyÜÑ[‘ +#È›?ë>•@FÐ> ‚sÚ©@]õ‡ËW.cš(Ko$ŠÎ²b÷€ž§Ú€7W–öÅ9úæ}ïþ½Ò€#'2¯=©Äõâ˜rfô¥9Éâ€$È Û8¬kÂ<ò}«cLqYJLÄŸLPRÜgÓµ4‚{T¥nþ´…¯JnN9­: wÓ<ô !ë·õ¦Ëû»˜Ž¤æ€2¥›œóO„<ž* ¸äæ§ØL 5´”‘9 †µOµ1nB ç©ëTít¦vÉÉ_ZØOhPy<ñÐÒ úÖ8ÆåàúS4–ÛxTq‘Úµ/mXÊ ;±ÏÖ²ôøÚ;õRo9âŠFàsÇP<â%$1lƒFø†GÌj<Æçœõ¨q†úúPßÝœ}ìÆD€6Òrjp T°ósÎÚrqÒ¶¡³£ƒXŠ~oå] ÞPÁãß°GÇ'¥>a p vçêM2IŒJ]ŽXcÁ¦±ùjœ7É+€Ï€{Õ:´‘ÏJÀ>•Zöú;D›-ØRÞ\­´FFÆqÀ®Næw¸•SÜÐÕ¾±k=Ê‹Ô>Npvžk£´‡OšÕžÊãvÓÄoÖ¼óEIòÛ¶è¤#§CE€ï'Ýnû$”ý*»È&Rª¬IàqK£x†×S·~§ˆåÿ–w†«ê×˦Æmáei‰Ôç4$V0Äê÷3,X꣓Y~#ž#p‹o!x‚ƒô=ë"[™f|³“ŸzlÙdSÏJ«Ð:S¿ˆƒÒóøŠ~;dô¦Ž9ö¤朼79#S¸'ŽÔÌ•`}ëªðçˆL‚Cå‡eË æ]p£ŸÂ®é€y…Yr¬0Gjë¯>(ê—Š˜]¼z»¢øÒÓZc¦x‚Ò;ˆ%áKuSìzŠóy+œ3MŒ´o½[ 9R°‹<04[=›™,%ÿVXüȺkšóýk±ÐµV×ôk½&õp»¢nùÇÍC+ÆßyN(­Æy?J‰#=)çžýª&<úûÐI9ü)„`Ô„€Ýx¦qž š`¯­t~ˆ¶³$ÙÂÅ 6}ÈÀþuÎ/$õÍvþ¶0hòÜ‘ƒpáA?Ý_þ½&¹È·Ó¤?ÄçŠÇŒ`UíJPÒ,jrª¢îPö¤·OÒŸ·µ(RµW™r+ž¹ÎóÏ#ŠéŸ;qÆ=kPˆ¤¥»zКFé¦1ö"¯ÝÂöÃ&Vô¥ðÕ“k–{¦}*î­µ!geÝè(–RI³;·zÚ‰¾Ñ¥MRuÏë\Åò¸À­ë  _iÏÜPªl:ౌf9zc­oÆSJ„aKvª²Ú«+1ïÓ©—=™‰·/ÌŽ3ùÕk³h×â@›Ó8t'¨ÿtr ˜CÆî†ªIfï!xâ9Jކ˜± æ‘⨕0Iˆæ)ù÷¨ ðÖ¡o;oÙ$YùeF€÷¯8°³Ôuò╘ýÖN ÿZê´½sS±›ì—MªpŽGàzR°|~$ïû#HÃþZF9"Ÿ'…dxòVR}YNj}3Zšu ;;íOÐ×GòO"iÕIãñ¤{Þ™osÌ6w/œ„†çk/ñ¼q%Ó‰‚‡è+¡ñ}Ýó²[–_Ý—ùÛ‡sä+„Ñ5O³ê»du‘3þ¬ð¿•0#׿MN{†‰ˆvÊöãµc›ƒœÏõÝx†ÈÇgöèd”C'Ýwm¯?`e•ÆYy㊠½œµ¹R˜½QµAö´Å_`/*N=óLŠ( máòݳL Ÿyϵg;g=*Glð ÏúÞŸÃÖ”“ƒÍ6B|áLÑ‚A"€%å$›SÓ­ìäE_)Ë’?ˆÓ°ºÛ ÁõíEFø“k€0àíEbÜ ÈNyÍFFàjVÃ7šC´-Çá@yL±n`yõ¥¶'{  I+’23·)-ÆX‘Ó€7Ì~µ¯q •&±z1ëj!¶Ø78  þÐùÁQYÚŒí„Lÿõªf2•ZáY‘d>¼Š¬‡ Á«i!hFN9ªLçN%£Ø“Ò€#ÔïZæP£î¯žHÏJ ä÷¤9ÉÇZ`.y<ŒS[<ƒNäáIÓ8ë@ÈäqÍJ%g?9É÷¨Éçñ§F3Þ€$ÁÇN£­K(Ù óÉéѨ.ªK¨ËÛéÚ€3Èäà`R•Üu«CòŽ¢¦O™›îy  ñ#È$Èô¥K>­nÁ¦2ÇÙÁRǤŸ0¸Àš@V´°I,dšQß ÛVå+œò:VÛDÉ¢ƒ’k!€\§\P0 ŒŠEð+E ,ÁrÍÀ½jÛø6îéÆn­â :¸léœPVƒw%¦­nc?yÀ>ù­Úµ®³ !@o˜b­\ø]Єz“ÅÅ”n7Mnû‚óÁ#¨WÄ×òjZ${[Ž´ˆÄsšŽ)ävÅFÇž´ÀnN}*H­Œ¿6p¹æšlqÞµmÃMÃg#ï0^”=®ˆ’%i(ï]…îËXR ¬(êEsvér™ÙŸRÇîþ]ê µ£tX0t®áH ÝüÙ‹sÖž™En¡I64ŠÜÕÈæFư'ë@äÓAž)Ù$gÖ€!ŠÏxÍÈŒ;ÕÙä §8ªzŒV÷gÌ ü^†€:+m°B#^1L¿Q,`1QÇ:N7… ‡«!éøRÊA ÝžžÔ€­oe8UÅiEj§zu¼XuT š¦üÌjWÆÑµ@#¾y¨]ÿ}´ò«[2™súP<öÅ¥;FUºVmá¸ÓÜL\€F8èÕ}c Äž´—1ItЏPäõ  mW³ºÀ|¦b>uäî+°Õôè¯l-®Ê$÷1‹2òYzŒÿõëÏì­]B¨ýãÐV­§‹Îî8 “m²e žCjÞÒ/¦ŠNmc :ùˆ0+·ÓõG¸· l‰zÛÔú× m<· ¾G‡'’Œ0~™éVd×í.5³[7—ciòïÉc#÷Ï©4€Çø‡lÖò-úÎd™Ü{p­qöÖöw¾"IC£€îêx{Õßj“Ýê X³[j¼ÿ“MðµÍ……ÈmFØÜ‰A ŸSÖ˜¡k†¥aökx\[´j©œœz漯ĚúV¥*…Ì[¾FõêºF§™,jѪm؃€?Z‹^²‡UÓ.ÆŠÜ2A) <>OœÉÂ’1<õ§Þ·º‘e2EU c—^}ª€ºøÇ¥†ážÕQNH`zñÅ9˜Á&€,¡óžÝ) ŠsÀ5ž³•˜ª ×&¦7 Žæ€-ùàÙ¨ñTàñÏ¥UØOÍ»¿z’GFão4;É ‘ž3W|U«Kmck£ÚÈLI.zMg9[q™¤ ƒ÷W©ÿ §qªù³HÕXŒnnMQŠÂypYB)è\â¯,ÁƸ2Ð*ô>ÕQ§y%ÉÏ^icäu&˜y<Ÿ­*§Íþy©xëÜÒ¯SëHÎqÀ§(Ã…J½Á#­Jów§2lÖ˜½Çz“<Ðr´°€À)Í6{uÏj(¼¬»ÎFyÁ¨æ˜qúSÛ{šŽdd‘@ðò ⟠ÝŸJE!ã qÅ)\ôÐ ~c‚:õ­ëLv#8®}'úVͽÂ-ºn8ãs;=+>k¡"¼{sÖ›s¨6¯›ùûÐè†SŠŽõ•ÊCœu5riΉ7o•b³É?^h£>¢ŽýzP847Þâ˜Æã×ê(è=hxç¥. àuö !cÓŽ£Š‘F3Zzeµ¬’Ÿ¶1X‡aÞ¦Õôû[Fk&蛕Ï\P|gçã®1ZCæªÉŒÁü«>Ð?9íÞ¶àAe žO4€®¶3Hÿ"`}kZ)q´•éÜÓá(r3íV•”W?•$V2ëôÍ;ìïË.|t©£”/®{U…vA#€Æ™VÖÌ©9UËb¹Ëx^i6ެzú{×C¬»#qÓ¥QÐÆýCË*Q‹ sÀÏóÅ0;_ Ág£ØIw41W\³QšÖ“Äð^èWvb$f—”ƒÔRé7Qj y´ø Ž:ŸP hi–úF³¨Þiëem 2bQÊø¤g„õFͲ½C%¤ªc•¡¸®#Ç>»ðýÚÜî|툧OÑ[Ð⽯Lð­¥Þ,*\Är¯´ßEsfæ 4kÍ+TƒÎ‚e+°žQ‡p{`ò)\8ìzô­½'Ã×÷G ˆF­Ñ¦{õÙZhúV’7C ¼£¤’üÇÿ­Rê’ºßE"g5Çâ)Ü ßðè¨DNÍ$eÏ$v)óh¶öÐþêfcÐ ¸ûéE´©ÐAôÀ«¶³4öqçšæ[H±rWþU_CBNËŒàÿ×K:aˆ©²žüñ@ûxp¹æHÏü˜<,ê3êØ‚Et!OáJ'Šæ¾£bH¹A,_óÑ9Ûõ©–L `rqÞ·Ìy³®l>VhÔ+“ކ˜—ŒH$Õ„à–9äÖìÁ—r°Ã Õ³.åñÚ€6t§Xà0ÆÑW±¼çÐñXÖ–Êç Ë׵ᵘ`ù¸ ÆhVÝ 'kaÆOAPZ1T¸= K#›Ý§ ÜúÒ¤qù×%ÀùAÀ«xG·J•aXãØ«ŒÔn6ñН ysHn$`¨Xƒè*¼på˜ñŠË{æ–'P˜ùø~Ç=¨¥î¡<ŒÐ«àîÖROå–y9禵ï­!°µiä”Ë<„(`/zÁh›Ì¬g ø4Àííu˜íì7­ÈåTúSôßZXß¼â$dÙ„Œ.=zpqÏ2ž…bGÓÚ¯X$³\lXûgš,w®Z›ý=X:#É)- ŽcŒŸZÇÐ-Dw±Ü^[I,q¶ã³¥XµÔìâÊgÙ‘òŽÞõbß%¤bLž¸ïŠ@t÷Z”3OÛDÐ$  €}ßAÅj¼Ík¡Þ\IÂù,?QXÉs=õ¼K=ª[à|§3úU»+¸õmïIº\Åă‘Î? <·QXÏ—Œ[3øÕbŒ1Àú ·}iöyçÆ«¬¸\“‚:Õ´hÁÚÙQíI!E8,*GºSòùƒ'Þ¡•!ûB…}훞3@%gaÎhEtS$ƒ…c¬Í´”r*µýÈ{m«€s‚(o]¥$s“ŠšãS¦Èˆ/݇o¥PÖ Ñɪˆy-œâ€&’Ff$±$÷¦ðÿëR’0[ï·AQ;¤wÎI¦˜Ô66óž•aUTã©¿Ënõ*3ך@H@¤N qëA82iÉÍ<^~´üh^×ð¥<œž{P€ç®qÞé‚izNÈãùÐüØÆìûâŠv;¸¢€*«FÜ2jRЕÁ_ÖªsO3É  •¡‹î¯^zÐÓÆT•NzU|ZoQ@ bpN)¦RWÐÇ‚"˜ÀxbÝûu«VÆE’VÀEç9ëíUâMò*ôÏÕ«Öшò=ñ@®%óòvŽFTó“Ö›œç4 `õ¨ ñÜÔˆ¾cíÇÍH'š»hÆÖîˆÔƒ Ý Td ƒŠ¿ö&„Ã8iºô5fþ¼‰îâEBI,£µFg-l°.KcŠ@V™É˜óß"¤ònnÑ#\£«+BÛNF"K‚}€¤‰áTt  V:"ÆÊóÈ€>QÒ¶’Þ5û¨£ßØã} …8÷r]˜¯L Ú€Á«fqŸ»þX»î*a!‡ÿ:@ ß›ð¥V9íœúÓb-1ppèA©cT[ƒëë@£dg¯­J© V“Ï(“îQæ‚œŠ•È4…|¨È 4G’Û¥e¶¡Y.OB{öcP»H±F1p¸  È$24úp\µ\ÄóŠÍÓ[*·•^ÚIrÄ["ŽkKxd‘¶öW<þ'šè´ûEµµ@ªUè‡«ßævE< è¯å¶ sŽ0+Ϧ˜ÉpÌNri .Ë/—j[ø›ŠÊ9ëV.$.ˆ”sUߎsL/Ìn*Þ”¦kÆûñ:ÿ_éUâS…ÀÎx«R4ú Ë4°æVä)=½Go IzÊXÂ>A ìï×qMÒ5»xµ3-ÚlVR2£ dÔŠ‘›û+ÆpTƒÔs@‰KÂdcÎìT+~jXõaÛy«qÆNzP"1Š<¯J¼°qNôAb]Ù+;S eàqÖ´ r@â(r(4Ëû2é.mŸk¯äG¡®±¼EªÈ%ˆ#ºFÝ«‘8íJAU*uÅ :Ý?Ån×¹@Œ-u6!†YHgyDdÄÀã€zf­E¨Or07œ’:¥Ø Õ¶¡–ñG:ž0Ê~µÏê4[Òò[Á%”®&Ü ™>ª¥3I˜iÚD7 Ûqº0çî ¨¿á=Ñ ”¤Úíœl Ê <·Ä Õ<-t^dÙ’vÜF§oчðšÄKeIÇ|×°^üSð±‚â+›ènaAˆFXMì8Åy¿¯øViM+Ûflù°H»‘Ý9Î=ª¯蘒õ5ËÝê‘F<”¾vGÔÚ– ÷‰åÄ­å÷!¾÷øVcGZPsLÉ©=ËaÕOû)z3}Nhb6ý‰Š\v·cÔP8%oÓü*¬öLA’,\ž8ÏáC ›‚x5adY˜ ã§½høoÄÍi(·¾Hz ÝWé^“k«yâ;l‡·—2WŒI"™ÊMHã= tú³&›$rÄ7ªönqî=è°§¯Ã%LJ¡’9 ÉlNêàa¼¹F` 'q=89?á]Ú^Ũøjk˜Yš-™ÈõkÎ'?¾p®vç*3I,Ê&Üë’P£ÛÓðª¬ÜçƒÒœŽcmÊÅNzŠK‹‡•òàŽÃÀ‰€e ô¬mÇÚY#?.s[2yp3gVTªÉoÜ‚äþT±´py‡'šíÉ«W¸'ÜU?^´À1…ϯJ|‡.9ãŒÁþqM,IöãŠV9Ⳟ@ÍFzsœ}iÈq×?…KŸ×šT9ÝÜñH¹^9  +ÆsøTŠ}ÍA»ŒãTŠqŸjœu4N=ûÔ`òsÞÔž½i"“œxlJ„fŸ’Íç@¨ªì|’ ÎÃÖŠ¨'ñô§àßò¨†C;Ô¹ã4Àùy¦†ŸÚ£l•Ï^h6ôïëHœðOãN=øç¥ áOô  F›$ >pÙSÇJË{Ôªß(öíK$òO”Á‡æÇ>Ôñ»>áÇÒ­í®…XEvN$\})‚­ŒÖŽ™mçÎ]¾ârsÜöª·HÞnäŽrmÛF-l‘Ë·Ìß0'‘˳`àõP® aü]êV%FÀr[®).1{…€bIì¹…,k’ éŸJ…sÞ§c„UñÖ€7ô—HÊ: É­ˆÜeþ&ýeø~Ÿ4ç«ô«/(ŠÚ)=þt€Õ…·nnÊ¡}•Õ­_C µjHµLõ~MQÔþ&VIžI4—Ùõèäþ Öí¼`«ëYñÙul8Ê‘ŸÎº— YÒ­^MRÉ XSŽ+sI³W½[¼ç9 ìTÒpê0#^¾øÿëÖæ’‚ÞÖÛïmÜ~”€ÏñEÎØ–  ã€9íë[^!¸óo ç85Ž8'ŠhàúRIÛšƒži#‚[‡Ùon”jŶÍnV9·`.{öüºÕíRÎ{©0ä¹=Í^Ðôñe½¥móŒÂý+BvŠ%v?A@ºjZÊìIêBÕÛ9ôˆ\†åX d85KTº2]ÈAŒT0DeÛ’ÇÖ€: iô°0’ÏŒ“ó «FûM‹¤’·ÑqX«lW#Û­P'os@_Ûzrœ¥oR[xŠÀŽÌtÎâæ²d·UQ×°ÍV‘È  ñâ5Ãk; f•|.9“šÃ’é·üÇ·4[êiØÞ9àZ`ußh_½×þµ ºòÙ¹÷¬A¨'Ò›ö­ç“H v¼lã<µYæ$rxª"]ÀsÖænX2ž”‚CœÅCš\“ß§¥XWôè;ÔŠùã#5MHš˜=hò2±À=k¦Ñ'ŽÞA¼€¦¸Ÿ0©È'г¡*¨ëŠö®Äj`Añω˜o<€c̉Oã]‰eHÄn7c€kñÍð½Õ’A€<¼u¡ 9iÎcSèE6à“±)²>Q“ÓÓ\îò—98ªÜø0žFHbi%~]zôQC sÀ  p’ØÔ¼99ÍT„ãË÷©Uù<äR­Â˜dÞ½Jµ €zûÒH¢HñœŸz¥ ´SŽÃ<ó@ ¸O.y{äU‹I !‹#ÔS¯ãÈI€ûÜ« äSïL ˜°¨;â‘ÂHÌ :P˜u ÊO#½Vr|Ænù¤Ã4 ó çP] hüȉäŒÕ…”:l“¯jŠx]cb‡*GZÍ$þ4€ç4íùÒF9öÀ'¹Â·õ¦ÇÁéJ㜠f?/¥ ëƒÍ)¦fæ²·íôçÖ<Ü&á,Œr#(  WÒM,)6±¶ nKPpBžy¾•ƒ«ª–ÇìñvTâ³u Vâþrò1w?¤FD È…¦ÇßsÓè)«c©Ão¢³Ä¸¸™Ê±î@¬é%󳜟zƒÌ;Åðޤֶ•$ñy—9E=uüMg¥¬×åÖ1µûä*[K ‘ùdH 'ƒšéí­–=ˆ«…ƒ *ܪ Ñ ulÒˆkw·”¬ˆU½ O\òvWVܦ$Œ0õî+ëE’ Z¹Gðšw;ȉ€Á+Hm˜–@~´ѱVØŠp“å ŠJ ÷ß5äR´œc5 “ ÿ:<ðsHgÁàõ¨ üÆš_iíŒPÿiÓMØ0ϵU‚Mò1#9;¹«ŠAB¦€!mv+f*ÄävkQ¿}Bí¥# €ëZw6±°!Ó$wô¬Ó¦»6#pWÞ€)0y$æž§¸ÿ­,–²¡+·8=©¦û†˜'y|ô¥$ª ËœP!·Ý©a´žVÄhÎDzŒÐ²~ñè´å—%«bÇÁú•É è°©ï!äþÕhž´iGÛ%F¬H_Ë©¥p8ß#-Kg°+èúŠFnÆçË—òÉë_Dè~ðþ–Šñî½Ìcè+´³ž-¿u1€¥ÌÇ2͘¼²AïÚ«ðšú/â?Ãm/^ß«iÒÇc¨ãç@Ÿ$ÿP:7½|û.›s¯±•t8!¸"šwö·!H-Ȭ´‘\d¦25R;%S‰qØTöð$s?%TŽÔÂ0ÜséOI˜pÄh;Yèi«yvîÆ{â€(L¡Y±ÐôÐ¥‰Ç^ã55Ü{\€r=qUòAÏz`/ñw3ùRî-ÉÆqÖšGšLþ”ƒ?(Ƀ®hÇ8ö¤ÇCJy^9¤íœ΀½qíJ:ÿ4pÔ¿OJz÷?=}ÍB¼æ¥_ÿUJ™Ï·½H§·5 “»×*ôÏÍMÎÑϵVo–@pMYOcš†UÊñÚ“º0G§­ ¼œìîh `7Òž‰ŽçÚ•WûÝéêï¥G0ÇQUr=ªÜÜ©úUF‘ô¦{jf:ò©3îIúTDóùÐÖûÑÁ ´õÍiA¨àþôî+>%\ôÎ)ìÞ˜ ž{¤K$p2Ì>SíU-æ âêj›ÈZPÿ LÉŒdZ@\i·|½‡5‘’Nõ¦+o·zd͵¿•Zµ¶³º ’Ü›y¿„¸Ê¯qU.ôë‹Äs;¹ ­¸0õªîIÎ}*hK4_1'4vß'V”ó…ÀP«Yñ HFî sO„.ÂóÉ  û2‚:âµtQ°)5šê ºóji+ˆ‡=»ÒÜëûñÏù_ËÓ¤~à’EÝè1O[F½òíPæ0  ýÏìúd—l>{‡Ø¿îŽIüÿ•]U&k‚Ý„þ¤ ÐÔÄq]¥¬Cl‚5ΩÂ?wzùçäOÌ“ý(«D·šjn0QƒèE\ðƒíz¥£cxùñíÒ«Y‚¢x‰û­‘ô5_C›ì~<€…¸C{ä~¢€:-Aö5¸é™š¹iô«wœÈÊrz€q“]n«…Ó­—þš=`¿ÞÉæ€2®-]BÅk *“ózÖ…¿…•­¤šYÞ<:u©­“̺}òksSo"Î(†o™¨/ Íh¯#®ØðÌ'%ªÒÀ@‘À8_­t:ÛùvQ[ޤ(?•c²¬c¨ùôqìU<äŒÿ…Bß5êØU§Áf#§Aôªü÷ŽÞ˜|t=©®œäSÔcµ(¥ 2îôØn‡Ì¸aÜW?w¥Ü[çhózu®Ïh< âÏQš`p,Äg®Gj‰›Ö»­&Þäd  ê85‡u Í&6 èx¦)4ÉÛlLÞ‹SIo,'!QT®²y&€ÊL1ÓÖ´Î:ŠÅ…ü¹TœuÅl+î‹+ƒõ ‘C®}* Ì`ã­]D,~\jÄzUÅÉÂFG»p( EëÇ9¤—lIúW]„ÉÁžàcÑEn[iv»Dp.Gñ“EÀâì|3wpDŒŠŠ¼yü«²Ó´ØtøBD‹žíŽM^ Jp )\O¥=F 9¥^¼S—¬o&›ÐVÏü$K D±éÀ½r³ÜGk˜çŽÀu&±¤¼’âBìqè3Ò€;Ø5×Ë»dúUwÂú_‰b2 »Ç§¯­s^´l2~•¹eªôËb€<Ï]𾩢JVx‰Lü²§*EeÚF&b®9kßcº·¾¡¸E‘`†sà=>IÌÖ¤ÆUŠwÅîcG4¶Éæ¸SÎO­zn§ðä\)hŸæÇÍp×Ú=æ‹1Y©“éNàf^Ä#¸+Ž•FKvv“W®¥ó¥ÜO8¨%ɦe·vèG‘aê3Šœ±hïMÚ{ŒqÖ€#dQ{T=êÎuÏ_Çó ž8¤ê)ǧҚÅ8qøÒŒžM ?LzzRŽŸá@n½³RÇÊûÔC¡ïÅIŽ(ëÝy©S§ëPž¥H™ëë@§CÒšü8â•H ž 5‚‘ÊœŠ@DÙIö¢ž@a·¯SF{I ™£‘He>• ŸÖ½U¶ÒuM>âh ÔnÉï^}(ÁÛß4€‰ÿÕ¦ ÕÖRc#ž•Wk~´À‡×šbŒ¸ç5)AƒÁ£aO›w  ìU"„Ë{Rçår(Œõüèh¥*øzT¾le,:Õv Ž‚£9Û“ÜzRÞðÇ÷dëCÂr9cÏsPÚ°'æ'éWÈR7øÐa¿hïZ¶"®WI¬¹•£™™GÒº[YØ#>QŸ­T¸ 7·j–Áw]‚}*9Àäàžjm=±&8 >yc?(­m-8<ÖE™?k“œŠÞ²\08íH ƒ±ØkkJ‰aŽk§á£ùWÙ±ÏéY',TkI®‘¼?©V;ñýâI?Ò€2YüÛ‡vÎXç4ô\XLÝ\Ÿ¢ÿõê3’=jÆ1¤ þôìÇò]3w Ç åx»L“Òdøö+[;e+ŽŸÊ±o—¬ÙKžVT?øð ×ZÇ— ~Œõ†Ãþõµ¬·ï‘qÝëXŽrH  ßϽÉè1ÍKxÿkÕ0¼©‘Q~™ÅXÒZhóݼà õ5[M_3X³SÚMçðÉ  -[÷š›Ÿà€~g°¬Ôã{ž¨:Ÿïòjþ¢pqüR±‘¾¿­Raˆwb\ÿ!HŸ8ôªö|ÈÇMKpØJmšáiuFG¤u¥_Z?iÐ8¤ÇnôáïHz£¢h²N1V;Rc“@d±IW €æ¹ [N…ï$»Bü¼Wq4žL&>èÈú×*ã.Y±“Öš›“JeRU²*?ô‹Q–\¨®d‚Z¡z¬ñ”€œ»ž”»pz4ÿ§J@sPÝÜÃcšf ;ÔŸAPj𵦑hgºlvDyµyõÖ¿.¥vÓÌØ è£Òš@tïu0‘Ûá^„—8íX±Ý‚ÏJ·û‡'éL d“žjÄsm9ŽÕ”²*t”äñH‚×Qdaót®‚ÇWù†Nk‡ŽOÒ¬Å;!È8Åz­¤°Ý¯ V?ˆtmNÄCžŽ+ÓµvV_Ÿ ;æ»K]J-BßÊ—ñÃv4€ùïÄZú.¦Ñ8ÝåX¬)„„v¯rñ&•Ô‘™£±±ÏqX—¾‚âÉf€/9f©0<¥=qÞ¦xÙmÚCÑÅM¨[¥µü±B6ª1ÎqQ2O$aUñÅ0!³¸BF@äþUðäÆkµ·Ð.tÿÏssà®CŽz×)Ë“êh™ljLpZñü©2qÐq@ ^h ÿ•ñé@†ëK»óFHŽ´Ô8?á@¸çð§GžHüÅ#ž3Ž´ˆ@ÿëP• ¯¿½#œSíoj{Ž?• ÄäfŠFÇù)ÝYÅ:fþòšå®2&#Ð×l‰åéì1Ñ ®"fÌî{äŠ@FrPàvª§wÓ¨Ìàüªv¯°íü˜õ+Œò±¬kõ$ÒnØÝ^¾ÃÃ6Äú* <ÎÃ…û«ìJz~í$“<ªíïþµEÀV帩í—ÕYNé@Í^p£Š`N¼ÐiTR€3HÓH5&(íÒ€#ǵ#. Hx&˜G€2µYŠÀ"SËŸ ¬&_|œsZŒ‚K×\ðŸ(ª-éœ{Óä`'=2j„F­ƒ’y,{ÕŒeþñ>™§""+Ÿ”ž~”Ëk$·Ä¡CÔõ¬†‰—9ð­iæûEÔÒð9#>ªPT‚;S ?Q›MŸ|g*O̾µè^©ä!ãaî+Î&ˆ§ÒŸe¨Ë§Þ¬±—ø—ÔP¯C(q늃TÖ`Ò­÷03ÝÄSýsßð“Û[X‹C3Œ*翽ròêw7³´Ëìy•º íJÀM«5ÅÓµæ£t­þ®.øô°¬vbzã=+B[u•÷31|ýòy5]­$_ºCb¨Ay$Xç+Z¶š’3cv¥b˜Ù>òQñ»‚qší¡œ89Í_‰ÁnÕÂ[ÞM Ès·ÐÖ¾¹‚€Š@vIÎsô LÖ-¦¤’†ûÖ’\(ù³ßÖ²èzÖþ‰©ícsÖ¹±r„uâŸúà `h·×Ü"+“Ãw­K ¸¯lD1²yÌ6€Ç?á\‰µíúE®ÖÉÏ_Jå­¼Q¨Z\ b‚½9¢Àhø“ÂÏTo9Ò&`Xì0'>µ´V𱳌(Æîµu>!ܰÿH¶Y›Õ€5`|DO,!Ó¢ÛŸ›ä¥®Þ@Þž ãyE ïÍxì©´ŒŽrr+·ÖµåÖ™‚À±' 1€+ˆ™·JÍž $S@Fy___jiöïN8šLðzô¦›ǽ'çÓŠJv>SÅ2=³AéÇ4ƒ­Yê¤cµ11ƒÇzãÂ…ÇL~"€&ÆGqÖœF 1O=Z:6Oç@ ÃÔQNu@P¤?ú‰@è#"¸y€3¸í“Ö»lÿ¢\7û8®CûçëÖ lᾞ•T¶F9?Ö§sÉúT?ßZ`86 éJ[píLç¸>´ôÛ‚084UŽ`cÚ˜9vÍHøÝÇJ`éÍ46á‚9õ§)!O­0ñëN^Wúâ€$©â~r{zÕT$xü*xÎÊ€5r$·eõ\ņ6k´Dá·ŒV»``š4»rÚ˶8@M 4çB“œT9##ß5vù”Çïž+<z€n[Ÿ5p9ÛŠÚµ|ÚõçÊÛÝ*9ãŠè¬n* õ€\²ym’åBñ¬¥º×a©êQAáÿ±ªæieÞíþÈù×'NsMöÅ×ý¡Ò›a©]éÏû—;sÊ7 þx¨*9æ«Él‘ÃÚÅQ2âkgSþÃgùÕË$ƒY¼ˆ²J°Ë‚0H®fÞÍŒ€”$‚œšï´5í-Ì“‚%nÞ‚ê±Æ·_»]‘„P«è­ E®›uzx*›Wêj–®?ÒPü#ùUû¼Zø~ÖÛø¦;Û”€Å|€Xžy5=™)¦ÿžÒ—?Eà~¹ª× É=+@BÑ[vUáËçLM”Ž8ûŸ¾§§éPIÂÔ²?›3ÉÓqªòž + Ý/5¥ÂûU pL„òkMáLN @Òã'°¤qIO?JhLŠLdäÓ_ „úsSmõª×Çe„ÏþÉ UŽçf?yŽj$öà àŒÓd^)˳Õûƒ•ÄÀýÁ´¼xhçî©Á?¥ex•Äzuµºÿ…Èöƒf03ùÔÀñU"ÏLU”‡Ö˜€FȬÙÓlÌ9"µ g¶k6S™ÉÇ9â€2NçšÒP b¨[d](­!‘Û¥yíJÍ&êA»?TŒU›dU%#·µ_ÚOÑ䎜`Ð •I«2YÊ®ØB@<P:8 þ4À³g)a8#kR+ÉÑxbG½`) äpEiÚ8Š Øõâ€/ý¾EQÉÍ:Þêâêq¶ÐzŸJ©$nÁÇàjxÿÑ¡*?Ö0äúRÝÌþnqd^OZ¯µrx¦ÿÎ=x¤ƒ€rOjR*&=1Þž«ÎXñïIÈ ÆØÛJÖ+c zVêŒä~‡*mr3ÜÓ6{})¸È¥nƒjïJ¼5 í‘@ ÎOzUÉ¥õëÚ‘G^(ëЌӇ\œ“ô¦¯9ãšpè}:s@/'¯éJ{sMZ\äç<@Ï&Šo!zÑ@ŒXÿe\Pk‰À3Û5ÙÊÛt¹€ÇJáebd8ë“ILÛ5 ädñJääçšvy÷¦…=1Î2*1œsKž€"`KÿQLùéJ>øçêi«Üb€°3Å(ásÖ‘‡4‡Ú€3Ú¥V ƒqP©êGãRŽ´v;½i鉳í lô¬ˆ×5ÑÙÇäŵ‡$géH& þÕ[Ë*§8ö«—läýª‘9Ïç@BwaùVµ‹¸# À« 0\íiYÜÁ­k]A-õžÐ0ë÷}ë ¡eo•Á¨­Ëkܰ‘I}§G¨5FÉñ¨ëõ  Åp})PQYŽ©G˜pn#üméZ\çÍfi% è>‚€/ivÚ…b¼km¿5R6çš°Ž9Ô€ëØ¼ÝB?p´ýfP÷â!÷aP‚¬”R‰Û?@3XòHd–IV%¨¶A%ü`Œ¤¼o çù⬫*yÏÞ”}O_ÓùÔ6£Ëµ¸˜õˆ”ûu?Ò¦¸ZEu]Íþñÿëb€+8J‚S…<àTÄuæ ÛæÝGèO4À±>\IŸ¼Üš¸ƒ kŒÌqÐTˆ8€ÓñÈ¥“ë@ '4õixP(ÐÎÕ¤Ûd˾@Åiœâ±uÃ…‰}I4† QLØÎ«*¡†ÓÔt¨Ú1Î2;Óªäõ5‹âˆÁÎÆR˜ìs]" WEÆK6Wñ=¨—Ãs2õ+¯ò?Κ„Tb0N}j8°Ê O÷ vœñXÒcÍ' dšÚ#å>µˆã3ã±4=ÍÖ:ñ‘Z[gØ€nIÇEü«O=?*f9äñ@üéøù‰=¨Q…4 #ùŠM¿0Á5.3ƒèi§œb€޼Ô3[¬ÙìjÀ\žiʃœŒPFQ™[¨=*Ý„GsÊÃÀ÷­ ôçÇ<‘â9Ûž‡‘€^ƒA@ ùÑ'©4nàzÓ[<1â€IRªa‰¤PqÏëNçv(ÇëL=8äS¾‚šFTñ@Œå³Þ±îò.ÜqÖµ¢ÀÉÅdÜspÄã¯Z€~”ÞÔæÎ=}©;gʘ 1žÔƒØf÷ºRÿ/å@8<ÒŽ)HÅ'^èGz‘¦üŠr{úЊ2;ÒsœRöÆhÚA@ ü]qÇz*B¢€;«‡ÿ‰|Àw®<ÂVBÍÛšéæ'ìóÞ°å#È‘Ž3Š@cÊrÇŠ`n¥œž>•é€)"·<ä{Җ‘šgçG·LP@ süè^)sÓœfš½èž>´céC{õ Ÿ—?• Æ ½ªU=ª!é×5(úЛl³^I<Þº9ÙvžVNŽ».òTƒÖ¶3ך@@Ð<Œyê{ÓZ5…Hà“Þ¬´áÞ)ô4lç銰œc®q@å¸D èsNÁ-À?•8ñõÅm¤°¨Þð¯ûÒbQï*Áœà÷Î*”:¬|ÈǯïE1õk%)¾„n c~y¤»×ð'…P£ò¤°ŒÇaqsšcå'Ó©þ”Ñš– –±e~O î*Úž(#¿ŠÞ1‹k4Ï×âh…èò¼«QȉrßïµNCÆ*I$ófi åŽj&å°hn# Vôj,´ÈÃÈp?­dÚ[µÝÜP¨Éb:V®­ k¥?Õ»G×¹  #=*TNiª9©ÀÍ;zQï@Zp Š1O ÎivŒtÍG× u®kV\_·¨QŠê íæ¹ýQM@‚GÜÀÉç cRü¸Ï¯SSˆã'‚}i™[   Q©ÆGu«—-¼Äÿpÿ*‚؆‰Tã+ÁÊŸ¨ÈM¸nþ[cò4ä õb3•ü* Q¾ß¾EKnpÅi€Ù~ëÊ« "ܶ2:Ðt,2 BÙVÁíÞ€Ö´cÜúÕsÎET-–â•'ØÜçk4 `\9ù­K pö®y4Œ±SSÇk;¨rLõ­°²š±Ü'&§²IôùS(–Ùº÷Æ;Šchö²F²,­ƒ€P®H©$ðª)-ÖÂ9R?•\i"†<¿pëVž¥æcòžˆ?3H Û{mI¡0<‰yov’r=Á=ëV³’Îèîù‘þd>¾ßZìÿ³£šžèÇŽ¬^ÖÝ´ÉÊ3;DTï'‚sŽ(—2 c9¨Øå½*M  ö¨ŸƒƒŽôÀpý)ÝÈœSxÎhùàTmÈ¥^ýøõ ùòmÎóÍ5®%9Fàw4ÑÔœ †â@X¨é@îuÎÉ™F9ÃS Ò¹ù™ÔÔŸ›䊗•;sãoέØDïsk©çê*Á8çµ$NèÙFÁö  |8ª’^Þ°ÇDú±ÿëTNb¶rÖ\>Oû£§ëš‡ÂWŸmðÂ:ýùCBåÍG}?Ÿvì>âð£ØT\qJÎI¡T±õ½iiºk_]"tLå^ÑíÅœº„£æ#l`ÿ:Ì dwvêI5©®]/Ëk¼=+%O  “ïõêu^*¼g皸«ë@ ÏJ\í94»±œu¦ô;˜Ð‡<Òðj¤šŒ¡·AÍWk‹É¿Õ@Ê=[н#dc8®^÷2^ÊÙèp>‚­Þ ÈÀÝ*eºJÌ6`åÛ'ÑÍ0_½’)æX•Nj®¶HOF?V&¦[Q’ƒñ [­§rg#Ò§¼”Ü*BÞ=ꔲÅnV0»¤n(É5nÖ6ó ¯÷‡'ØöÀ^Ù?Sš÷ï_¡ªÎå©üA¨-Ljf1œÇ©õÇ_Ö›‡\õã‘LŠPÃæàz‘•[¨úTm9+Œçšr±C‡Î;o¤Œæ¢û('†ãÞ¬ãæÈ9£Ö€*}îÈ?—õ‚Qÿ-1V qÍ@fˆV,}ühUH Nsڬǩ=¬{ Çèyª¼<EäÒÇ ÀÛêÇ“@v¾ x‡ÅÏ÷º¿±¨]0dÓ·c¦Z³,Þ(e °2œb2~µÐÄï@‘XÙq@Z…ø\ɤ;û­{©ÙßDl®[6fæ\sÛð«ãT‚–dvýjmÕËj6®©¦›¥ì$"y¤#,F7ê¼px>⫸àzûÕ™ADòÌsDñ’­¼•ï׸ªÌyéŒÓ zP[šAŒýi¬y>”£©>´zúR : üÙªWßëWñW_z©|>t9  X”‹hr™ëOÏaÖ¢·f6‘öÅJ£€JQô¤}h€}ºTR—9ϵJ9Ï4ÉÈh2òo-6çænõƒçx<ÍW¹—Í¿»Ú¥°ûÍúSUTb‚?*H¹JÒ6ÑNPÎê¨ 'E@,ÇMǃëGÙÈ<3UÝM5›š‰b` 5#  óO(a ˜ŒG¥e»îfÈÉúÔc¾spM4c'ÀT8ëô¤É$“Òž½¸•EÜö }â}*e''ñ¨—îôÍLœ¡ÏZzøzÓ×paƒL\cǽH£÷œt  Ø[©Í0ƒŒÔ¸‘úÓpiBÜwÍ5”&@<ÔÌàd g=j±$žôÀ21Œthƒž)¬ØROa@ ‘ö óUÏCž´¿{$ÐqÏ4 ÏJ±nNxªã $M´ã®häàŸëRÄGSúšªH"yfHcRÎ쪠w$â€=[À—rÁàë Ã ÷%b>Øù¿ZÖXr7°<ô§iºZ[ZÛiéÌV¨ˆþ&êÇñ9­ ¢ß*Æ¢¤ ‰ "ƒ’xÒª.‹¦ßëä7ªJ’ÂÒÞÂ3ys·îÜ×=¬kæVvl&{Ò Í!žM1Ýc1êk?ͽ»ÿtF够Ðu©aÑ"î»’K“þÑÂþB€/b•ˆ€™zù|â•/õ GyÝGõ­[{X-âG Fƒ¢…%´ß~Ú&÷Ú((A1),~ôŒrÇêk+]ÔEœñ@ß:¡gqü"®¥ß› D³i1–Â?Ʊµè ³Ð®ò:¡'%‰â€8‰müÌH§æ<ýiÖòùcséL³Úf_’ 2Iõ5c·nò3‘À­0&IUòH©1–ÏQÚ«ƒ+ýÈÕ?ÞëOò¥=fü†(|œt¨݉ ´{žhä1ýûóïQ´j§æ™ÿ ËfûìOÔà~TªàGû#š¨ eŸÝ¸7”N|Æëü+@ F3€}5 l#ãý£@P˜¡sëJ«Ï_ÈP„¯‚{p+[O”KlVH¼Ò¯5–rr:ÐӬ¤Ä7p»kÛ£ä["nµq.“$~µ¶‘¨Nxµ=]ë^“uåý¼¾9þx¤%â;xänãà•Æ>†¹¢¤sšîõ²¹·ˆ¸ÆW#éVÊž úÐc–áÈ£g<W¨â€?G\ÆÀqëJ¼“éOÇ\õ Q†Œô<ÔÖ™ûJ(õ§^GåÝÈ1ךŠÝÂ\+Ƙè¨) O&HŽ´â0zRð·•:8ìEè#2ÈAéš( ü¾Õq­)Žþ¾µQä`zšœàg¥S¹bbm½iùëÉéÍFÀ>”œG<Š¤àæ®øE4(9 2})Xp?Z}¸©$XäÚm —w8=½è˜À$TÑü«Œ÷¨ä‰£8aŠ•Õç¥.0úÔõ^xçëL'<Ô‘ô'Þ€½M6fÇ>µ.DHs÷»Úª_“ÞR~´˜:TžQÆOsÅN`ò¡ËrÄgÀ¬Ý8ª´’=‡J–fÀã¯z¯Ï=:PFF{{Òž:úv zóJzžÔà9ÀqÞ–,3ªúšj}Ò}ªk%ßr:ôÍI"€çn1šé< cö{íL¹ŽÍ<ßøEŸ?…sÒFá˜öÍzÇíÿbÛî\=Ûyò±íáGó?'°-„w2ÇòÇ„õõ«†k]-Œ·,$›,@óøúRê7²™ µÈŠ6—QÉúVlZkË!w?Þæ¤]꺴™#lc ì*$°Rù#Íw=iýž(y¸™Pˆ§Ÿþµ3í6Ä`J¸ÁÍ@¶ê7ooEè*ÂD®>”¢RF!µcîíQJ·çm£›I4>TulÒ†'§Ê=MWŠ2>k›ÇÑ~QRy–yÁxÛÛ"€ÏoùæLÿ½J·°±ÂïsþÊTxO °ºµ.ü .I4žOD¿ˆ¢’ió¶;V'倫!V?… n çuÔ&~Lh«Ø Ʋe‰ÉÛ3H}›ù êÌc%™†O5C"ò3õ¦0ª£”AZš`ÿZ1Û󿤗Oˆr¤ƒQ(6Ì6ç=Í]k+\ïx#-ë¶¼÷âÜ)µ•°ÀÞYÈ»Ë¶’UXâbªÃ,ýÀôõå>3¸…õaÛí$äæ„zÂö±š=ÌøbARÆ0 HBûÕN&wPZB: ·h~f÷"˜¬£nY¾œTŸ½-ü =ù4ªHwë“I%Ü14€E BY²Ò1ƒ€)VNAõêj”š—Î|µÈõ5ÔgÇyöæ€6;÷#?J|pI&v—=Oó5†o® páG°¨žydÏ™#¿?Äs@!`ÜêÝaÛóéL:ænOÙôùnòm®g¯=‡µ ð:÷¢ÀtMãõR¶°ÚÚ¯ý3ˆgó5~+Ö„…ô™÷ʰ†FsùS×8éøô§`6'ñ>¯rJ¾£1è‡hý+8Ë,ìÍ4ŽçÔ±?ΘÎ=AÏÖ€F´¤¾óЊ\sÉ«Úm´7Sy1WnPç‚})@³wÂÍ“‘]9ðÉÎw¶)?á8r>´͇aØt ¿Zè_Âò¨ÊIŸcTßB»Rß&F:ÐZÉìj½Ën [K¢]’p”£C>?´±/'M>?õižÊ1N$ŒñÒ§‘Pq&¡ù‚œ) ž´à=Î(Ëgîu¤ËcOÔPªã?…<Ï=0„Ò‡Åaê˜ûHÇ\sPYAç\ ýÕ9¥¾Éy!çƒÅ\Òã»cœL @z äúæ¬Ãasp…ãäþñ8¤-˜¥Â•<ÑZv•q=àÜ„*ò[µŽãF9ªŒ¿1ÏQÒ¯-6š‹ì®Ý3ЩӷjcE_ rjAf$b€2 ³Á U›XÕscqéWþÌgóš¡w°p:ƒ@ Ô•@  Ú™l«~5®ùvã½#6Xô  2Ê»\Bð§ËäÕö\ŒäQçSLÙÎ̧Z´ª"L°ùªXÙÖ=ÌàšŒ v'ž´€ƒW=ÍJ‘,#s|Ƥܰ‚|Ôø!ÞCHÝ{PÁ˜Þc¥„$õaƒWL[3ÏgšÇº›s› :P.즶HåtýÜ‹•nƨœ ñÚµ´„º{AqóËö¬¬÷ö¦×éH’E(ôeØ:,ü¨£ÜäÐã8]Ãò ]ÿ[‘Ÿq‘ùŠd\©ÈìEB|å•E‚ijæ®Ø'#pr9æ€+ÓÌÓÌ(T` Rñ§_Ò¢’iHÄi÷¨4^µs"É&gô_ñíWÖÌÉó\HÄtp(\ráB€F€8Ë«­JâQ ÅlbàpÛ™‡~{W—ß{Û†C•ó[LšôÏ].YaàÄã$z?­yiéïT€.¤L.J_¶ÌÙÃôVo”“Ò˜8ü:ÓFšGÎçfühÀ ïŠo'¾˜£Îìz‡ïŽ£§l$´ñ ?©j W'$b¸jm§jðÊS÷nv8ÏbɯWÛƒð©'ÉÍ4Ûœž2+U£ÆÑÅ7i9À˜-ÂŽ€ÀוëìÓcÜŒWo&Ä ®Ö#š+ Kh„qª£ŒQUç~¸=( q“j}Þ*0¡…^H¥ ó.E0ÛÉŸ¸.”À¨`Îyüj3Áùøö­¶gÀþ”ŸÙÎ$;y®h2e- í »W9$Œ?wÉhTaÀé\ËéB}uíÉÄxãÒ€0Õ ç§ÐJœõõ­=WJ}2àc&&èk-1¸ƒLc#¨üéÀ|„SpG8$j²gq!G\PÔˆ--Ó¡ “T^RF`ô¥H¥¹|F¬Øè=*s§ÜóFW¿4€¦§ K}êÊ] Œõ¦Nfb `R®Ž­Õœf€-G•WZ`(=œHÜyíM緽ɠtÆ*ýê[Ç岟­RZGTPIbúÖÜz² 28Ú€6¼7oswä\T™ÐmSàŸ­{øgN”ì–ÕÈC·ùW‹iú-ý«¼Ì¾\¨Àb+ßb!c/è™üêXÇ„ô”¹a ¿ àn$ŒÕè|;doíí@ÛÄw:ã®øÔñ¹2'–’®é€‹ËÃýZ€ÔçúRÅÁ ¦4Q‘° qJË!a¶KUîƒü*õÄ»Œã’j´AÁáÇЊ<ˆ?‚yú5­d#),2Ùãõ«Êd#¤mõ¦Q(‰à‹Ì#!sÉ  /‡´$¦™âŒì—1ÐH0?>•¬¶Ñ¸ù­Ù}ÃRIclP«FÎU<Š¢ÆTäCQy1ï%FÒzàâ¥: ,ÅìÞkCêòþ*x¨ßOÕ#Imî€ëæ)CùŒŠW.¨sÏê¶áÆMX{ká Ý {qÎÙ3ÌVd—j‡k¬ªG¬gü(Æõ^qIö‚Íò©5 ö£ò$­ÿlÏøUÃoå© …¿Ü4’I~^wæ•ÕUGN9§¬S•¶”dªóG~ÃlV1c™€Ç¿Zæ”vÇ·¹ëI.å› §d[ í@îŽmAn‡Ÿ2™°54K±?ô´å£uëL±!â 2d`}k]Cý‹t>íiþñG +;]ûäœ}ÞÔÀâôlh¢õØ»!ozá-gky’xøhÈ<×}n`Õ¬EÌWÇÌž†€!ÁccÚ› ݽLxž6Î0¦ÿv;@¯%a¦NTàì5ãÚ³*®sÎkÖn$M¸õØkËä†Òæá’áÝýÖZz4B&68ËüÕ;»qÖ¥òÄ1$j~UP>0Ž@ÀÜN)§g©‰ H^"¥G_Z™¤ 8¬í’ù…ƒ;b¬ÀIÈaøŠ@Yç SE&í œãŽ”PÃ|ò#lP©¬«ýemY$ËvPkŸ¿Öå`c„á3ÔV3L]‹3îi£}«ËwÀù²Ï$ÿ:p`F3HOQÞ€#à:o=jm»·{Ôl˜ÈãŽâ€pEqêÇŠϵ(<{ÓÕÀ·}Æ 2âFšRïÉ'5 ýïÖž¤¶i41ëZöÑ+BÈÛ‰ëYÑE–ÝŒ¯bi£œÇJ”Y€IóNÚŽöcm¦É“÷¸­BF9lŠÆñ ÈÞ/ðòßZÈ–rö$â¨Ï5,¯¹ºÔC¿­0ñǵ=)==1@Î(Ã§ËØRž„Ò.6’IfUäö  öÖÀ"dd‘Ziï ÎHfÆÖ0¡˜¥h«GÆÓøR¬-ã÷®ûÀó0³½³sÈ"Eüx?Ò¸ÏݱÈ-[~½[}rv;%#Ÿ~Ÿ®)ÓLJLGbiúLâ?M ­_r¦¥½‹2•îzV å×Ù5« Ž…éÓúÒ¬vääš±vɪSÈ­ŒzÔö͸f€4£µiŒÕ(ØtÉ©·ã¥ ,qÓšˆ̓J õ54J.z mAêy5®Ú:S™È 穨sžvÐç*9¥Ÿ¡ï@@ÏJUûÆÃsÈ¥ÅàjAØÑÓ¿Œò}h?­;ë×µ5r¼Gjr}ìgZQËcŠEë@ê}hÜc½)'wáJ8â“©E)è Ç5»àÓÙò è&°`&¶|$vøªÀ7I·ó€=}Û`ûüÒ"´‰n”â‚"p´Ñ(邨d?Ÿ­t‹„/“°Ö–èñ×"³õGG±™ê„t :@@çô­mS}:ë Ÿ-¾ð¬Í¤džGj =¬W¶âXˆË ñPV\qÚ±4+©ãI!ÎF2¸íW[Z¼·8{bãÖ¼Áu!vkËùkôôÜ+·Öµé§´{s”®MpÁ¿ÓTÿ´?4S!çÛ¥If¡®3Œm¨ Ï ôéV­†U‰=3@çjhÆ:t¨€9éR–¤Üõ¢…¢€8­×-‰ÀRjâìþ?^jU¹X¸HÀ>¸Í0(dEùÐŽ;Ô}GjÑ’VœÌ3ùUs  ê==)]IZ™aüpi|¦  žž”œzþU4‘6sЇ $c4ÀzŸOz‘cܧÓÚ£PÛsùšÐ°„JŒa½z@KlÒ[¸Êµ¡É[<àUo²È>öïJtíÎ}(F4Pàtâ¹ ù<Ûɤ8åt×laµy7`ãë\••\’rÇÖ„rÜž;ÓGÇJ2yëÖ›œdwúÓÇ·µ§8¤$øP:tíÞ€>ï8æµôk6I$=WŽ•’¿túâº-µw ’ÍÞ€4⌅Úzý*aÇ}©C±Á#4#>HÁ4€aGã'Ÿ­> ѺȻ•Ô†=éç“ɥܸ8ôëšô;«•º²¶½N’ cì{þµƒ¯"ËmËŒ†Á©|3x.´Û‹9’/Þ >Å&¥ -»¯ðH jki7e¶ùoÏ!…lÚ¸[hØYA®^՛ѷÞPyúz颽D·„¡;LjAn tqM‚rjô8a“\µ¥Ó\Ê“·Ö·ä(¼Ÿj@i†ËZ•Ø*mì9>æªÂJ!$üÇô¦26Ð*@L3#tâ¤Tæ–${ÔƒœÐR8 sÅT–CÛš’y'*º¦_p4øXŒ’9«ÖŠ dúj(Œm•‘÷…’ÝVN¯4NìÉ{>Ôܱ©àŽõVæØGáGRÕtÝFƒl`Ömôí(äÝiJuQh3Õ&¾~º¹˜zHÜ~&¾…»EòHô\WÏ×ë²úå{¬¬?ST€mˆÌäöPM[f×­AdI{ ~àI{P2aÃt¨2r ëÈ©¤!AÏÚZ`ä QÐR—ëƒOËÖ€yÇQJ½OûR}ãÅŠhëøRçÖdƒùPÎF?KŒ1þtÑÔûu§zu \m?­ïcûÒ'Ðæ”}ìóϽ?އÿÕGÀëH{òE/§§å@ qÜûU½"qm­ÙJOú¹çñªg¦9¥V) `OÊs@òÝsž‚™» þï4–· 5¤ŽwÆ­ùŠY%<…ãéPyX*zUK¶hm%}¹ „äÕÑnXîfãÒ²|@ßgÒ¤Á9cŒf˜ÞŸnš„Røu9Å:m.UB{uªz|Ígpdä ØK䙲‡õ˜Ð÷ ÝTqÅi¼â&dlqÒªYK»œ÷¨µéHŒ§—¤9­ÝošWÏ`XÆf¾Aïšv£pZV=ûÕ<Ü»cî­079)Š¿jÊmðG 樎8«qþìáÔãÖ€-Žp@ãÖŽ1ŒdЀF1œŒdS‘›$cÚQµ{ÑM·AEq Œg¿=èb3Ödr:QÐâ˜Ïò§©=@çµ"¹ÓŠMç'õ  C~ZPϨ”ôæ—æÉÁü¨ä ^F}±U›iÜÄTÁ çq¨&.#ù»Ðçp š·£©Îý¤zU“ýkBÊá|åYËléšÕ¶´@HÙ÷"­ˆ[ŒïJ³[F@z [™DJÄ}ãÐzÐNªÆyœ*uÏs\Ýòùr”' ë]0HWsÉ»8Ír·Ry“³æ„|û~4ß_ð¥>¼Rv"˜ O¯½&~ZVÈQÛJAëŽq@Ú1×k«Ò¥òôè‚§oJå9Û“é]®’ˆºd#x?/QHy’B~U,M+uR½XP¹ùsÒœ#ÝÜP%›8À¤ÊŒžõ7‘ƒŒãñ¥À‘Ó>´€»¡L`Ôâ¸!ù‡ªž£ò®ÒâÕg‰Ð ËÕ}pzW;¦ÙE;r}k¦µr‘¦á¿)úv :îÑ­_Œ•³¤ÛC¥.d• # É“¿à)|ElçË–4%G±¬u)ô¹÷FIˆóûÃühªµ³Î!€ÅmÜVµ½º[r͹½ªë:¸ué‡/Œ|½y§Å0™ŽæÅ -ny› Ò®[¯&›”Š>aNk´R6óëH `aj~ Ëòàj68„“@]³V!„â£rÕt‰2ÜÖ€!TœÓ$‰JTg¨ t¨Ñå¼ÜêvB¼ݪyÎÕÆ}¨›`pÊ>µ‘3$—d*Ž+ViUbmÃ¥eZí$€uTœÿ ¯Ÿu©<ÍfðîÏïˆüâš–ä%¨Ï˜Ô.Ä1ޤ߲×§ËUǾ:U‡$’|Ð9p)}y§–ühTÙíœS˜cÒŽ§ñ¤Î ã¿nÔ¼î{RŒãŠLdäp}é@à€h½ýi0søñïNÿ¯M8&€=¹>´“ëøP8Í'9>ôªG9ü©Àw¦®r{úÓùhIÈëùP äw„qÓµ ß>ÔãÈÖä¶3Kô![$VSi÷Qó°ñèkCM¸—&)æ   ßxu/mšTgQÁQÖ°ô“ëÇ¥M0‰ç€:Ñ@u¿¯¢Nqž B[“KŸ­0'YF9Òù£ž™ÍW=±HN3ë@„£ð¦ý sÍT/ÁÆj<ñô  ¿iî BîÎ9ç5$ô©b‘í§VÇÍé@ ãß=ëBX®m‹"•{þµ_øRÅ5­¸Â™úl 8Œ· “Z§î¬–EêNø¨í™ÂX¼²ßß<þUµ!F„üÄäñ@2ܼªÈIµ,Mç§­i9àS H#"€3{:Lu«Íj¬I^j·–êÇåéLÛ°ö£€>‚œèÊ;àŠh㯥9H(x­*í’ˆ àgµc§¯\н§[Ìó—ªw'½t]ÌON?*»Ò–úuª«&2jU,7 j@_7\~µvÒRÓÝçéY*ŗ׿J³m£í>â€;[;¸ã÷‘0ü*úß[ÆH`ðk†MFDm¥‡Öžu˜ñ6)ÞM¾{ ¡S‰69®WOÒÖþñ¡žqojZG#$è=kgC¼k«A½³*|¬}}åüªNhVô=²âu8r:7µij¾&†Hã²¶ ÑÆð2ÏŽ9¨í侘e-™è\] Ñ죉<»4I Œ•染0RÜ*ÿ´i‰wbA¼½À­hÑPnnžô’˸;Ùr=Z¦ežñ±¹êhør]޽F÷&vÙ$Qo¥†Á•Ë7¡5¥ ´pº3@ ¶‡bnaɪ·2™Åºçoñ±yr#B©Ö™cU.~óu4}PGhT®:U¢Fð=5VSÞ”€Ê¿p!n¨ì¡Ûj¤÷¦_1ªâ8­žTz `aêò4û™3÷PŸÒ¾w”ùŒîÇ,ÌI?Z÷o\´¾db"úñ^Jž‚©n@Ç@0dRõä÷ô¡xÈÏ8¦O9ÅJ )£æbH=iãïçð þ/j\=hþ´Õ>´ÇJ^§µç¥rrqÎ(N¹èiÎqH™çš¾OÿZ€¾èúSWïëJÇfš99ý(cô¦÷?J_âéÞäý3@ŠC ÑÈ0J0`~‡5麦¦Ói&Dã }FkÌ:öç5Üâ]CÀ¶ïn…¦ Ÿ^)08¥‘ÝÙœ’OÖ–Þá ›ÌëïQº¸f.0Àò1MÎ=iÒÚ^Åp0žã½tvsˆ)lýkÎÁ+Êœ=kRÇR¾)YÀ1º•€ôHBõíÒ³579Èô5€šö®€ƒl¸k£ˆ5Å„R2arG¥ 9;„hä9LöéZ:\«ñ¼¿I}fç8Z¬€|¸¦J/ SœúÔ wp§å„56^js2¨'4€‰f˜’ÆOçMšv*G'±ÅT»Ô¢‹ýlȹ÷®v÷^,JZäÕÏô¦7W¦-Nv…†ÀÜ}h¬²wzžIõ¢˜¢6ony©¶sS‹f‘ÕâÉÁü9¤ mŒž´ï³…Ôß=Âôçi­9aŒñž” ]¿wi4„9w«—$“ÇåY ûØ geê@ªlầ5$䃴úÕläŽ0&¶G¹¶äçƒZVú­Är*’!8‡5®Ð̹àUÛ(EÅà\ïÅ '™žâs$ªô¨2¤DüÀ~5©-¬nNôSŽ‚«5•±'÷#s@>ÛÎ\çØTRÞ[”!S,G šU´€­V—E”—ë@~{wPy I>_Ê®¾’Ñç÷«ŒÔ §Î¤àéƒLÛÜý·íÊ‘ÈÍ\œ"< úníT……Ó€«tëV­´y‚°,þ€Råœvò~òBÛ¹è*êÀ§8Ú¬ÚhÆ5Ë.Hì*÷ØO÷\}h5`r-Dv²nÜEk­¬h¹9ÅBÓÅ `~x¤7°ó'iªífS†`í]–tlÀÕc"³3ŸJ`Vò'k"¡ýjôQ,…æ´­t/ÞÀ€0–9° {×oà+{ˆµ‰]²ÛœúF(¶Ñmm£2Êÿ(ç$×EáÒ\Ï*EåÁ·j9nzÒ¸R®é(IÇ#(p¢%îz'Ýør©M \Œ~µ Ïÿ^€Ü9¤DËfŒœTð¦:оêâœHši9p)·D œgŠ©!!##­eÝÄ*ñÚ´glíYÑ!’äzf˜Ö8†Ùô¨¬-~õ!Vr~U“í[¯ÄGé\&¿Ú´W–ð¶Ï”€ØëíøÐ€ò»û—¾¿ží³™pè;UkýËl¯ƒµð*yT#²`†Sƒ‘ÐÕ Ö?,y8⨠|ŽÂ–pÍíëHÆý}©€w`ãJyÎFy㨦q–©1‚hwF=èèzw¥9 ÏjCœýh J:h:QÔñŠNp¹£·ò£’9æŒsÏ&€¹ÁÇÍ8Ži>ÜRt84å=Fi;øâ•88¡²1Ïj ãäÓGœpWùS{P‡î.GëGB{ãÞ— ÜÓIäãéŠQƒžõèžœK£\ÛÌrçð#ÿ­^wߊéüx`¸»…9ibG¸?ýzL SÂqê’Mqlê»tc\Uî…sc1ŠT98¯Z¶‰¡²D5VæÕn’@÷¥p<…­XúU:êãL¸Á·Óž†¶õ½1¬®T“åMc˜¹ÀüiÑYø¥œí¹…Ñ–ºk¨®¡Ý¨Üt¼ìGÏ4«#ÆÙG*Gph¿ž(äS•ÄÞß\Úê3¢…Ú­ÆáÚ´´bO4Cpû”ôcÖ®êzJê æ©róõ‚5ëÀ ‹Æ3Š©6©}8!ælËÀ§½®É0WÓ½T ³n#uDGÍ÷N3Z1È8¦°ÚÙÎiOgªœ÷¢­0çœÑ@:•a–Tb? “ìÐÈ–øî=0 V;AǸ¥8\úR7· XI>â£û%±ê~lãƒWa‘Ü(dAÇ#úÔÆÚ“æóýÑÔPPÓ­O.¬=³J4ØÊå‚ö$Ö‹4jÃË8ä°É JÆX²õP9ѳ‰ŸéÇçUB—’²gž€WTªÄ“¸ª‘÷zS„hPˆ¢àrk¤Ý ÆñÇlUë(ÝË7ÌüóŠÞ1ž~Aõ¡’5_š1»\ ¢Äœ˜ýù ’Ç!]h¢f$¤zÔ‚%Uù#8ïé@¢“*TpGj¯9măúV¦Åq‘åA…1ä°8ô  \çùç°©m• G>„UÑa°ñw«hˆ‰•^O¯jdvûTíã­^³Œ 2]ÞÕ†oºäzÔëŒnP:àÒâȘê Ç¥6IS²œUo‘2|ÌûSGtæ€$‘°à88ªRD[OåV ®«ÊóI;J{бžI\kZÓCf9t&®Û«‚SšÙ´f ó6Ð=¨½®‰(>Hü©×&Ö6[[XÄ·-ÁTwÜÕö¹’ç6¶ÀdýéaZVVV¶1ìH÷H~ü‡’Ô€¡gá¸| ×“\ó·'h­ËH¢|¸™ˆ ŒÒ¡!W.ÿ*¹8—«Y_j“YZ0Ãfuèyé@gÂŽøqOA·ƒÈ=­5²ÓºñŒSâÀ]§•ííH âžqHàiã('µN0©žôØ“žh˜ö 1ónªó€Ò‚O=qV—ä‹5AÛ-#žÜ «tü:RXÆN9¨d%ßñ­+dØ”ÀŠíÂ@Ç8À¬¡‹ Èí½…lß6â‘ã;˜ U)\r¬0;ñ¿Û$ýÞÓò»ïvÏ&¹{ÌØsŠôŸéÁ%Šö>¾Gô>†¼Îfß#¶AÉüê‰ÉÏ9`p€q*Ÿ¥LxVéÅ0z6OáRF£Š”‚â€üYíÚŽ=)Çï~4ܾôƒïu¥\ž£¯j@HqÐ U9Î}hG@)¿ÅÖØR¿ýj9äRñÒwõ õ QÉÀéÖ‘¾ñæœ0OãLnâ€OAŽ”œƒÒ—§cý 'R =}hý­‚™ r”:ô úŠÙð¼âÛÄ–lÇ Í°þ"±F2?Ok/“u £$Šß‘ cv8sŸÎ¢-ž˜aOp$@Á°g ,grãÚ  ÍKLµ½V‘ÕÁøZ¸û‹XÖCå‡7Wze0:úŠÌ¿ÑþÕ—B¿¹àÓ02Fj›¨í[3ÚÉnåH"³&Nzþ”À©œ×I¿–H˜0dw®p¯'4KŽ{P…äÖóɾ$e'­R(3ý ɽ޸úwêU¶ÈÛå䀞ã=8äTuL“Ó=sÒ§h•WnÒyÚ3š…àR¸Þ£=ˆ  qâdVR=Æy*Û÷üj­ªä’Ã>¢µ'H‰SŸÆ€3®?w#¬î1L‰¼Õ&6#×"Ÿ _32ù„{ô§¢FÜ!Àöë@§Ë´çÜŠRyPì½3H` ÞÈ=hÛ4'þ>2§ "€o™ fC‘ØŠ¶ª¬°Øö¤T,ªAçÖšñ¸Sò’}3@À séV móqÆ1ÍW·‡ÌpÇrãÐÕ¹j€óÞ€+I²/LT2¢¨ä}*ÆçÙ’†«K)$¸í‚;Pw#8RIõëš– Hë×ýÚXÊ)åÀ©cFÀÆÚ·o)‘ºñ׊ÑVyÆÄ%WûÕ8"(8÷5­k€0â€-YÂñÆ«}M7TÖí´ˆ³q!3cåzÕ]KÄN€ÃÓ9àcœWpïq3ÏpåänäÐÍSÄ—Ú³2´=‘O󭯇·[»ù³›bHú0®@&?*ì¾B~Õ¨NWaT‹õ¨½,wwÍMœŒÎzT1ü¢¤S†š'C•æ¦EȨÑz0üjÄc4õV ¼˜ú –g‡éL·]¨\÷ ¹GÅf9ýÇ=X“RÞHÒ˱O½WŸæÂƒÀâ€oçÉ­ºœŠÝ0§JÛTó@Ó1{ÅÇð ÇùRΊWœsÚ’.d—Õ°? s¯™¦)ÀøýÒßI]ã’øCšò'8þuéÿ¤ mg <—,=ø¯/“î`u&©Ø”–Î*VÎÒqÚ›Àö´¤zô☎(þ!þM8b2EݽèN7qIÆz÷¥?ñíLäsÏ^”4ìIÍ70~TážGoZ2@Å!äóéÒ”û“IùP^qÅͦHúÒ“ÇL Uü5øîk2Ö@À†‰{{U-Üåˆü«7Á² Ÿª—ÃBå?£ùÖËÅ‘ô©™W‰€GÐÒöÎ{–« ›—#óÍ@ÈËü\{ÂÖ•÷¡ØõÍs“F `°Åv—¶«<'¦à;šäî`ÚÅO`Q0ƒÑ”LÓ‘ ‘Ó4ü-О٧G‚9性jiý:TŒ¸Á=)˜ëë@ 銅Ç=:Õ£ÔÇ\¼Ðv(§²å†?#EvFÀ8Úr:RH60Q0À¦º@8 ØÏÞ­68m·äÊ ¹¤ÌÛen=iæè²nMÀ‘éPºÆ¼$€LRy¢4Ê‘Žœõ ¥ÜÞaWÖše‘Y¤ED?\æ ówgäßÏjÊO@Fyf€-ÛM#’ƒëÖŸ&$8EǰÖ©´þS/ ž¦’;Ò䑞ýèbÚÌù`ž2zt«B#ü¤ã×­CÀ0Žxõ#$×[ $môÉ4BGO9†IoLP$€0%þcØÔ2´,w4¼·¾i¡T‘åøç  R«±%%Ú=1N†'+–¸b=…$kógc öíR9p¸QŒzš˜ÄHб¦{sH“¬ióséÍ3í’Coà Z·Œ¡ù±øTç$}ÕúÔ0º•Ü™aNg9é@ ààñÍW’2_8ù5&ッڛ»³®-ã?òÌgÖž‰)´u'ëV7^ž”Ù¤‚Õ ÉŒžÝèÄ¡w1 Rj•ö¶»Lv§êÕ‘y¨É3^ÐU%É^~”X œ»ÈY›’zçšcä í$}j"wœe¿HÙÉçw¯4Àº‘‘ŠôÛ´y'=n%ã?ÝQæMyý¬]]Emùå`‹õ'ëE”Ikú¸#¾øïøÒ`]2ŒÕC0 H<Õ«W ƒ¸"£v«1€y¨Ñvš|®"ˆ“Òå>mÀAÐri÷2aÅɵ Ԝթ<Ù¶ç@G¸üíÓ­4î*gåp8è)ÑGÈ42 /ªw’íŽx«ì6¦k"é¼ÛˆáY€?Ö˜ÛÆÑÚª‘Î2sêhÛÔzÕ·\Ž•ŒHøŸ#ZÞ$„Œ°üOÿZ¼ý¹!O­v'2x®TÏ¢¨Çâ­q€î$ç‘Çh #ã¦1IÕ±ïÛ½*£)8ó1éïL“ÚŽŒi àô£€ÙíšwVÏ\S1ÎGJŸåLã$€>”ÐyR/R;Ô`åêPy$PjAÉ=(ÏB1F9éŠNþ¢—Œ‘þM>céFprqÓŠPIÀ(¡–aµIÁô¬¥É9õ•©¦EËJäxæ€5Yø ½>ZŠòl RWj_Ü‚v;ÔŒÖuÕÓ»mEÜš@H>ϹS#¿­=.P6Ð:v¬Á6Ö_ÄTÈrsøäÓâÊû™‹Ÿlö©RgÚrÀ­QóWžçéNóCœúwÅ 'yçLãw_­Gö™bF`݉¨$B@\çך„#M,`–Áô4ÓYHV àwe²Ã%qÅAgiˆ×jŒ¹,ËoJ -IFÜÛž)†Q»å+ׂ(Ë1áמjèü!d[k’ƒm¼eÏsÀþµÞ"¤{×9ðöÐI& ™ŠFA=ÍvSiåþ5, »2¹“W¬AØ=inZÙ]~òõ÷«6+½r:÷  ¼þVBn'Ø>êò~µ-Ä…*Ÿ˜ð(‰{úúÒ—Rˆ¡**¤[ÜÈß­$Ìf—ã5m#T·9<ô€+9Üù©¡Jb¦Xšœ ©šŠáö¡¬Ëóõ'ôSVîßFitˆ‚Ù™OYX·áÐSvÕi>é>Õv@+:âA¼²ˆ¤š@|ýã“?е'!eØ ö¬ùS8<šŸQ¸7w÷ž²ÊÏùšˆ ©ïZ àúRd?JTåi1øãµ?§QÍÄ~´ÔÒ´ì|Ä~i„ŒöëOÇï 0޽hª{øñR.xÍDŸëó©TÐéùRwéGôëAFh=sš\sÛ¥WŸÊ{€¸9Å#r3Í(ëœþ9;q@äwÅ!á³J§Ü:PFâ 'E?1õ÷¦ôÆ)@ÉÆ€NÇ“J3“üéûP‹ šÚö ׬r+f½]Ïû¥TšòÐç?Zõm2â;&Ö\Œ¼kŸ¨â“Ç2;Tac9Ê€}éAàÔmc§åHH·ŸZ£,›p>µ&Ì)8?Zˆ'©ÇjÁÕ-ðÅ—·zÊ\`‚Etwðyˆy5Ï”Øåq“ïLŽ2üsHFiî˜<Ç4ÁÀçÍ;ëùÓr9ÁÅ6GUIªí8q@¸ÇqEW3ä`š(zC±@Öª y"­Éa€ÿ…@Ð2ä’?ˆ(ÿX½; h''i>”eWïœtÇJPªAÚàhKäœð1õ¨÷6<ÓYp~b@¤TÜ[xþõOÜpäOõ³jÉ ¤™5í‘Kr*Ë381t€4fÔQŸ`:uª«!bO\ûÕpˆ99£ 3³ƒ@@Éûœ}zTÀ"œÓ¹ªH]G#>Õ!¼*0WžÔeˆ$žF=Bó”[?Î’)RâB¬àzÅ[m8‘¹?@¢Y[8 õ«ú`Ì|ÕmËéM{ º•àzеe í?Äþ´¨d™HòeÚ wÇëKðIœõ T2:2ãŽi—‚Ûŵ@ i5íçÙ¢?¼ Øèk—º¹šI‹±õÅ>{±#±|­BYdþ®i€‰+¹8ô§+:à°ô¨Ê”û¿…*ÈÁ~b}¨g“nx<öéMBíÐ}iBy<‘C\a°x®hÈŒ £ÜŠSµ{Ï¥=eO/ï trE‚:@—Ãkýµwþ(ë†ã^ ãp<k;éÆMNçP V%O(}âpOäë^” Œç,mð$e= >(¼‡p¼îû zÔ®Š°èjpž@ÜÊGû£üi”#?7.~ñôöRî\‚¬M O<šÏ»–=OjX!,ÃÞ¯\*Ǩ÷¢ÖN@¤¹'Ì ö㊆1œñK+…\R¨Ø*¼Í¸Ð ×,Žý+ZÚ?*Þ8€ûªe2o¹‰=\ô²´Àk´×'ã ¿°xcQ”7–T}OÖ°àט|V¿òôeµ™¥çè´ <`ó ï¶žsM©&žÜа2Gzd¿Ö•G¢„è}sùМ ݨ¶{çúñH¼â€ãÍ4ÖéÇåO<Ì~”Òx8ë@Æ™Áç5(cQG÷Ï®jnç?΀ äwæ“¿4¹Æ ô Ÿæi¼{Ó€çéÞ“IÏçÞ€{ÐßpõéB”ÐÜÆM 8§ƒŸÆ‘>èçµ/¥!Ÿ½8}á‚1ïAê3Ÿ ¤ã'¨zbŽƒAÆzñIŒ‚hSÏøW xQÄÚ àÆÌ¸Ï5çéô®ÇÁsªÅs1`ãZL®EmœzSP²ÆA¥H÷cn7c×5\Íò‘×ð¤î íŸaQîBp~t¬é˜E@aŒäò¹í@ ˜±ùBƒõ5‘ue.òÛG×5ªc@2’)XÕ~l±h›ed$7ª²8PNy&µu!d$k›ž|³i€³M“Æ Sw$œŽÜSù<ž´Â9éLÉ#ž´S7…çóÅÖ«yƒ#ýjC;'ÊWœzñY!Ü.#ŸZQ;gM 4J‚}I¨š+Ð)ÏAš®·DޤR­Ã²ü¸É É“8 võÍ1•ñŽ‡Ò¦ºäÍ0³9ù“Zhˆ¶IÉÅL‘cÇñ¦F€¾1îjWŒ€ˆ{¯#°þ!ŠE,y Š_”g*~´àAÀy®8Žù£,,8£ rPdúæšT€Nh’VlŽ˜éSÙÞ]Çû¸_ð<Ó#µ•Î󀃜š$|‘)àœrhQµª‡BÙç¯[¨e/¸†=k´\Ì3¸à÷µ%ÚAo…àý(÷·_eNî#šç¦½’F%ëIy;NÄï$©÷Ö€,ÇûÀr}iÅHÆÓ‘P­ÆÕ W´á2îï@‚r æÐñ‘ž¼ÓPnäœñI»¶GZ{ÏÊôd•麓®1ëM'·ž†€'ÙOJ]Ùl!'€Zb2¯%¿[þ Ó£Ôü_§BÌ1'˜Ã—Ÿé@É¡hË¢ø~ÂÑFt§]†OøUÀ6­h02+ dšh‰-‡™. ö•G~Z %ê>âæj)$#,ßxÒÉ!b]R–C+`P%ÊýjxaÀɰ[ã’9õ«¨½¨…]T¶>QUùŽO|æ¯ÈJÀTOjªÀFž†€+ÈHU7<³+ç¥V—„4UX­Ñ „\~u© ‚EÈüAíYö€ylX¬$Ÿ¥ZTòÛzŽHÁæ€'‘‚ÆOµxOÅ-CÏÖRØ7¦ÔòkÚîîQm™É–öÅ|Ùâ‹Ö¾×nenræ©•+µycÚžÙ ?J†òåWJ颵†òA>£¨ªžCÆ3Ç…,dí?^µfçL¹€³*ƒ¿µVˆƒ=h[¡ô¡8ü)¤ô§ÂÇ­&|xíÍ#sœRÿËféÒŽ¤PQçqç58îy¨‰yíÖ§^ÿ¥íÖ…<ã?…€1Ò€>n£4œ“ïF9ãƒJT©4{zÐqõÉÀ§œìlt¦Fy9Ôƒ•n3@|(Éæ”uSS cž=)ßÅÒ€ú;ž”6ÐÐ:ã/9 ½r)8Æ3Ú“Í!ïýk£ðƒƒ©ItxCކ¹ÜcšÙð¼æn¾ ~tÞ½º¸3ãÙª Ÿ2Aõ«Lä#èj<Ä?„¯z+´~“~S>e<ʧ·Ý«@&N=ê´ÒFƒ%‡×Š‚YÝÉB1éX×w¬3Èü)×÷Ê Ã™®~{–™Ž>”À.o\ŒôªœžNAÍ)÷ïژʹ }i€ãÆyϵE#󎔀’ßZkõÁ?!¼Ô8d~£Ö€¬ç ôõ4ô”(ùÁÇó¦`’A¯jhBs´æ€.!ÀòË©¡²A3œ~TiˆÉRH9¥*A^ëUŒ§¸ÈõÏ"¦‚H‰ä¹ôç4`v 3íRGnø-!!ëVÄŠb˯Ӟµ]Ù¤ûÌ:ÅG,ÌÍ´ Š: TݳùUƒß…¨ä瞘  6÷1‡k~ó±5ZîwœüÍ=*&…ÀÈéž•Ö99úÐÊpzÆW´:IŒÆ•PHlÿJ¬£g={u¡œàíj½°5/p½W,£çµ=]Irsí@ ‘p¹ž9¦*0y㸫/!ù ü)¸RrÊ=³@¼Á’sKçÀŸÂ¦òŽƒü錌…ü(¼›Xޏ¦(Ïó•\==*-à·ÿZ€ªöǽ7iÆÞ1N.¤ó×=ûÔB×$1^F £Ô“@©ð{@”%Ö½(À``ƒ#“È,§ç^)•ÎA_zEÓ#Ñ´;=>„·Œ)÷nçóÍM,ßbԀȇâ¥çŠ@½€©•0iª¹ëN ŠP1š\ñŠCÏjaÇçJyã&šc 3ž(*ò@$ç¯J¤Ë¼dôô«N¦âå˜ýÅàTñZ<ñ@¢% ÈúUS$3Èû%ÂÛX.¡©¼Irš>‹u¼b%ùT÷n€~uæ^ÖßûfîÚåÛÐdË®9ýF*hOËÆrØ©!¤Ä‚qõéTâž%$yxìpù«|Ãòü«@LåÈØpS\Ší=è–WŒŒôô5SÈ?Ã×i˜“÷ÁãÒ£Ê8#?Z«$N:¯JëþiªxÎÙ™†ÐÜžØû¿®+œ8#S^±ð“MÚeþ¦Éƒ<‚$÷Uäþ¦†£Í0U8åj¯ç}iû×8o”{TñÀ;¿éP•#µ?¯ZjÇ×4üb€4ÖÏjv £hOsŠd§ ÁNHâÙ8Á5$’´mï@ †‹Ž§®inn#´µy¤`ˆ‹’Ç€*1&×ò‘·æ¼Ó⯈ÙbD·r7 ó{vÖ˜¯¼búõßÙ­Û19#þšZæ¬ï¤³»‚ê,…èú«ŽzQƒÖ¨y³¸·Ô-a¹…¾YP:ãÐÖŒªà9ÿj¼÷Àˆ¹Ó¤°gĶ͹}Œ¡þuÛÄî¹~w©]X¼g?•ejöæëL¸‰GðäV„$ºŒtõ¤’0 ã¯ZòIS’½1Ú©N›Tÿ…tõ‘³Ô¤^B¹Üµê9¦=yv8ô©l©#†®^AºÕñÛ¨Z’ 0:+vÝǽ]ÇË€8¬øm«Éj@K1Xzö‰Üfh€/Q[ÈØôÅ2à~´åOŽm¬0ÀàŠšÎGBJ·­ÄcÔÜ€yÁ¬å8~ýj€±ØRŒqL‘švFh}p(çuŸ|ö ué@ îÅ2#ÁÈ'éR óƒQÄ熀&ï¶:ÑÉõ&›ü‡½8uöõ ½(ÀÅòy¦äàçô 'Ž8Zhc€i„ã<Ògß4çs·éQrÏ#½+SH8Ïç@ œžhbt8¤3Ö€ŽÞ´ÕÅ)õÅ"’:\ã·3H;â”uÆ=é àŠQì:t¤c†éƒKý !Ƕ4¼ð1‘éE!éŠ(¤À#‚8õíNPsƒïMxŽ3ÃSpÀä- Ÿ—·áQ–cœ€§©b~`zzUˆíC4¤„>ñ G*X“³×ü*O60 vúPZW9'l}†8¨CõäƒÐŒu |­ëµiUF$AVÛò°Ç°¦Æú1>£¥7“ŠR:Ž}3šwÊÙ-Œþy§¥pN(0òBvàÓ¯Z—í2‡ ÇÓ4Ò8,xçÒšW##¦{š°“î~Ñê*B€”g¡úûÖ~Õ;¥>6d$ç¶Oj¹4u=~j®-]Õˆà^)Lä6Y¹=0iÂbA 3@5³F72ü§ÐÔ[ç tÍhÞ«‘òÔr[FÜ~€3Ì »Î)‹;0<~"®Ie¹r¾úT)þâ’(?1ˆä‚1ëPúš™°ÊíU[$Žzt  +#)ùIÝé_EøzÀi>°³Ç+gÿy¹?©¯ðŽš5_éöer0wì¯'ùWÑRœýÐíIa•²9\þUq1Œõª±©ZLúT0§þ5Œ÷¥#À\…ùâ<ý+ƒ ׫]@&‚hŸ'r‘^[r†)¤ŒõVÅ49@pWÛŒ¿,€wVÖÞy¬{…ßH1ØúÓZÙþQÏ àç­eÚŒµ¢‡$RÎì”âr¦ ¶3ÜÔƒ¡­sšî‘ö€%AóŽžõƼO²°ÁjôùSp<äW3­i©"™a‡¥40§ ™¥7Ö§–Ñ!²‚tI»!Ó1{ûcš®=zÓAÏáÒ—#žqLÞ—Ë·Aö !±É¨—ýs ‘RyÏÔS1‰¹ëŒñ@v÷§¯={Ó;ùÓùã˜ý) Ãô¤Œ ÔLø'šLóŒÓIç¥4·4tŠ3×@è9¤Î)Tàcµ¡éLžrz>”Ð8ÈýhqŸéH: r€HÏéNp@üè1òôÅ5sÎHÜýqBŒw •çÞ›ƒŸ¥JyçƒIÇ^ÞôÀ8¦±çŠ‘‡<þÃϽ!ê(¥î1éEuN£’¤õ§.vŽI㨒d»³Øw«¨RÕþe 0ì9ÛHƒM1¡–á€Uê ¨n%ŽPؔۙd²ó1á{ ®@!ϰ )¸ LØE'Ë’'¯Zz´{OcØÒÀá‰úƒÍ7dê@+žÜqLÚáÎüJw {-(Oî³gÛ½BXäðI÷§†ùs€µ.gÚrwö¨ |±¾(èÎJ“ê 8† Áù}±N.¤å…÷SHm²rÊAÆx Ð°Ç Ó‘“QòNA%»ÔþBí;eAßæ85 Ž`[n“ÎÒ 5—~Ò;JGÒ•£™$-³Ž=…FÎìs»ñô  D‡h]üc TñÎÉÉ€ü3Uß{ŸZv=³Ž´ugŒTÜÒyÊÃg'©ªœ$dúŠd`ç+ƒ@¥EtÈÚüë9à`Ùê*×Ú›¸5¦GêOjíþiþoˆ®¯X-`!O» k×å dnSíÒ¸„öžN…yzËÅÄø^;(Çó&»²rI qRÀXÕ×ø÷z°¤œf¡‰8ÇJœdö¤‚—­ §`Ðvnõ©R5NM0¹¨ÙÉ€"¹¹}Å"cÆ}*¢Ûm%ämÍÝ[?'¬ÍFè¬F8þóf€<ßâ•ÂÍ œ*~S#zàcúט´@ƒÔàzWiññ[_K0r-¡ Þ<šãÑúã¥Z³DWžx¨Ç^t…b #=:ÓJ/ Ž(¹Á8«zf¡.™}ÔG;+œn^â¢x@åIÇ|Ô&6úÿ*÷]êÚúÊ;øpu#Öº$ƒœú׌ø]kÿìë–ŽÉÂ’xWíù×­YÊQöæ¥j_ö¯5× òµyÇL¶kÒfÉtf pÞ0‡f¨® ” 9sÔVVª›."pqùþ½lã?JÏÕ¢Ýb”`i€¶lNßzÖEèzŠÂÓÜã‚8­¸O‚:SÒ‘ùSääTjÙâœ:Ò’yÅf^®cjÓcÁ¬ëÃò@še”×Vó*XÉ$K'.‘–䎇—ªhÒY±xÕ¶÷F0üëÙþ)6±6Ç}— µà·ËÛ=ëOâ?xÊûTIŸ§Æ!\¨;¤ÎqŽÝ2~”\›zëŒTÊÁÔqÞ½ûÇ¿ ìõ•–ÿIˆZß¹£ „—òèkÁ^&ž6rÏB 4î`䑚c¦ìààõœ\($š€Èïƒ×À‘K©Ã.{d”cj´9l“V‘œŠIzTf#š´£ c½H#ìh7Êo~zš gúVƒGÏô¦”À$þ”Ÿ°óýhØqŒ~µ{Éš @‚(‹´Õò*̉Æj¼P.F¥¾¾ôåN0?ýTݤŠéBœt攎3úS@äã·z]ß7^Ô3Áýi6܃HãŠyÎîûS{JG~sŸZ ¡¢”äž”P¢6-Šhd‹o9÷â«öòd÷©Ë>ÿ™›=³JÑ0ûι=³@ I5#-œõÍ8Ìv䜞˜ Köv8'¨=)¦"¡‹ºŒP²"=±JððÇcHÀƒ¼0Ï\•òÙ}¨sq™O¨lÓ VÉ!ýySŒñ‘ïÍ;kmÝÉÍ)1ã†ÁÇqTÈ“¸~éÒ“»ð«Z-‹j:ÝšŒ™¦D?‰çô ¡¼-§+ºu°eYÿÞnO󭘔¦° ’3°sRJ?ãSôÁ‚I­Hp¤ƒNçÒ…Œ “…4Ìži“0DüMHÍ׫9ä“@\-H ’{ÖJ‘%Ó;’!’}êÕüÂ4c’OaX~!¹:O„ïn ÄΛWêx¦ˆë·Í¨x‚ú猪f#éœÒ³ cÜúSœç&£n=j€“y p)V^qž½ª<玾٤ž8>”kÌP2 íB²ääôª¬Ç·ãïJ84eH È`rí^ËáÍcû[E·ºb<ÕýÜ¿ïÿ_ƼV7g¥v>ÕE¶¨ÖRÜÝ—ÙÇOÌf†®92ÛŽœñ‘\‡ŠÕž8À¹V®¦Ô팮r;W?âøOözν°ÜT 8ÎõÜ^mŒñãªT«‚§ ‘ÇLb˜öœùn•Ð@rs\ÄÃtñÿuˆ®ŠÚLÏëL ñç¾=i²qÍ"yÍ7ptÅ äsžk*ñÆ­h;vkùʆäP¤øìï…ÝÙ™#’{–Ž_kÚž§ð¯EðO†ÓIð…”LvÜL¾|ÏÎYÛžsíŠò†[õéô½"WÙee,—R/@äûçŸNžµô3))…m¾„ –EÔ ¼ŒŽ\g¾3º•些h—$±úšû/[Ó$¿Ò¯íã¹0<ñ4BD'+‘Œþµò·ˆ¼­x^r/m ÏË<20úöüiÄPD«–rI ô#°íV õéŠˆŽ§Õ^wpjÈ?7aíUÐþôæ¬(ä:™r>•(rIM5µN#Ïz@@ÍŽ*›ã÷«R/|U ”œƒš•.gßšš¤g5Ÿü>”¡›?J`X•ñÓëQÍ7“ÉéH£犔ÈRÐÓoþ½ ®Gšy#æÆi½+ÁÊ·±éLVÇLƒï@ï×­&üO&“ ãšÐ±Æ8¦¶ 8"”}i¤ö=>”»xéE)låEuÒÂi·#<þF‘ì#œžÃšµ2¤#.w6zg5&Br<¿Çš@DB¦x9<£5"Ú€õûTÇlhJ°ÉªítHP3í@ ò¦0˜‚j31iFÐ1Àõ§G"Ê3±²U©bdFÁÿhÐ"Œ.ÈÁ¤Ší€1þõ8!ˆqµw¹¤,ÿÄÅ€éÍ@ö®ƒ'g­E³fÿ—§£U·óe\1$Ý)¨_lPÆ]~ž”»ƒ7%n*̈˜9Æ}‡5·ß÷1ßÖ€#>H FIö5awà±Ú{fŸ%¹O½ŸÊœ »ºíDXáÔž‹JþKŒ.sâõ©¦Œ;nŒ…\wïQ"(‚IàP{vã¿ZPªÇ<гåFTœÈ¦b-½9Ò€*ÉÀ*ÜÞšêázýjÚ¤a¶³óÁ¨çUAù÷ŠÏl–#Ò»O…–lñ”s-biO±è?qáÎOë^½ðLû>}©2àÜ8 ½SCÑIËŽç5nX‡—»Õß¼üEj˜sP5LTÊØÅî(ë@«dÐßZ2žíêh§¹'~uZyQÝ*VŒ¨ÜíÉì*ѧր)7×™?êãäý{W7ãé÷YGh2}æ~UØ'—&4<žIõ®#ÅP5Ë4žfq×°¦€ñ˘Ls1ôéU{’V¶5‚LÈH žO­gIRxÈïíT×4›WÔæŸÀ>Ô™^ò Æ;Œšã­#múóGQL ñÇæ*h%x&Icb®„#±ÉýzQÁäŸÂãá}]5&;… ?Ý‘}u­ bs£ÜDã9Jò©²ÖþÈì|«¡€ þ1Ò½ne߯¨©ËUvaOÒœxRMMqŽâHù$1Õ{‚#ŒŒóLbìˆõY@ÇukÛI;÷¬mM±:IÓœUûFš`n£ñQ3d“ü©ªÅ^3Nj@5œœóYW‡(ßÖ´˜óšÊ¼ †<Ó°øwã{_ØÎ³ØK=Ääl}À(AÐsÓ’NkÒ¬¾'ßÝ,7 ¡c3ìY㔞ãПƯxGÀ^—ÂZD×tW25²HZRO,2x®²ÓÃÚ=„M¶›m|ü¡8æ¡´4ÝrÇYY¡·f[ˆ¸x&\{ã¸÷¨µ%’&Y­b‘m`G øVœvv–ÅZ+xbØ ©Th=@ôª—·'c~ì°RɼKðŸIԷϦ•°œŒí@J“ôíøWŒë¾Ô¼?rÑÞÀBŸ»*òô5ôýÄ…ñœç·Jæõxo#ò.9ão¼Ž¼©0>dmÁÕ¥ ž½k¿ñ_õˆK¡‡uNdµn ²¥yà!\0sÈô"¬ Q´sùÔ¹Á<檣äqRáŽy¤r8äÕ ÍVf!j‘#š`ë“Í*©4ÐÃÒž¬:p1@Û•¤ØvóŠ”tå@G4 G™&µ--ÑÈÈÎjŠ® hY\F¬qH #aGœʲ¯4õ\+y'‰£ù\V}ìªç­sL…Ž~¾”À>¹ÇjA—$ˆ¡ÚrqÏÀˆOZBN1‘OÚO¦0Áã¥ã¯oQE :`ö¢€;“‹ê¸ôꉧeoïzgš{Äi„„ÿ© &(Õ„X-ÔŸéH ¡™×ò« ¡;”àzŽ*Æ[¸ Š{gƒÇ=ÍBwþÎ)Âáv0Ý鎔æ¶'»­*@«’Oáé@X…,Ê0xâ£É,IÉý*b÷ŒzH±Œ“¸sÀÀ FË»&cïÞ ç¦9ªá lñéR£ ¹u}h Û†2)0<óúTÂ9$òqAœ àçž›hpÙV`}03P˜ÿ„09ô5'šKœà qž”ÆØX*öy4O˜Œƒô¨$æAÆhÆ 6Aõ=©¯Xÿ«\zŠÌ$d žœÒ²gס«²ÅæH«WíM6¬pY ûž”T;ƒÀǧZ¯9ÉÀ'õmâmÜG°¨'Q»h_ÌÐQbª£,ØzžÕôvbºO‡¬¬Tb‰C{±äþ¦¼WÀúDš§ŠlWËf‚)’68yý+Þe|¿4˜îýçå[páíÿ Â#2u­«&Ì#éR xjMj˯z† &6ŠvN{ÓœŒrj»;ò.@êh;»';¹n€ É)=Ãç8°«ÞY¸œñÏñ¸–ê¸ã¥g‹V†Ýœœ» (÷®KÄ‹"ņ‘€ƒúWY©Ý8•V,e9ë\ˆ%’t¿*h2Õ0Ó’ÃôɬVGþ yö5ÐjKÉôÍe¶Bàžõ@g´@Ž3š‡oGçZ[>nJŸZŽh7Ÿ•pÄv  è=h8=©Ì¸8#½"Ó½*Ó³ÏLÓqÆsøÓú0è([I%†î`8•#×5ôM—ïôôÆѸzâ¼CÁv+}â›E”f(ÛÍaì?úø¯p[o³«,3"B )êsÅ&â-¬®6€®s\UÜÙ$g>µéþ*ÿJÑ' d§ÍÅy;üÄsõ¡Ÿ¨.ëWaŒ©Í3N— #ñ«í ’OPGJȱm²•üéÔÀç$ö4÷aÖª@øÁç©Ù¾AȤdbNf]}Ö"®»qÎõvÙ ž¼Óë?¨Oh tû_ú­K—‘"&%Ë/ñ¬Ï |!£`ÿË”\ÀEj±Tä’GZÌ £<Ïj$$ œd¦â+2âqåòʃÉ#žkbîëŒ*çý¡YRÆ0Ò»F<Œu¦;4¶ï!RY›ý¢~•S c‚½ÅiÌ` û¨¢ GßqÍeO‚Yge^Äq@%3•ž\ p¾ ð=±Òd’Ò&(ÆMÇ’Äœâ»ÖŒ¯!ËÿµT. ì`7aŽ´Àð0Æ&!¸ àƒV„ çžqMÖíå³Õîc™Hrå¹A5EK3eAéV—dàÇZ©“žµ1R§-Ž*99Á õcŒv¦u˜4 pYŒåy­F»–©¡M\‰†=q@ åŒç• ‘Š”þTiÌ>ÒA#éLç8©ø ÿ:Pí@DyÎE!ˆàúU°¸ííFμb€(˜‡n1QŽî™ã¥ilò)¦1žŸgˆ8öçUæ‹‚h¦ØL“Ÿ^´ï*@~ÿO~•4VÈp]XûÕnåPqßÖÕ$Éã*ùà•çš™’B?…AôëAÈô™œHR­ÀÚw‚01ó”¬j¼úrjµ²ò  Õ£` ~ž•*$+“žÍVŽ5àœqVá’†1†ö8¤SC½s¸z1QãË-òûb¦ F8}ÙàcŠhØú¶?…0æ:T÷É㑜gæÀðsNfŸ›pÇåQàùe·ž0hVXv‘½FF1š©½#?(qšX$RXöÅ;ËC÷Âu€Ì y›ÎOB soåòŽd Ëç·µHÍhfœgœÔå’ÛsÓ?{  Eâ/ÝVîOjl’‰Šàm$ò9¡u‘ˆ+ ÁÎ¥8DÝ\ªšl²*ÆbÉÇ\jøfãÄúÒÚ[‚±šYHáüiÐÙIys ´¼®B Çz÷? xzßÚBÛD™þi¤îÍþ›ö-†…a„+"å›»R}i$-ëš½6G=r1U g޵ W ûß¶,ÏîEeùÌ0kFÕ¼›œô  ÙȨde\äÕ9/›¢)"«4“LqŒP³Ï–Ú¼žÔ®%ŽM:Þ%‹ænZ§œÉ)EÁ° íâFIêi'—b“œ`Tæ?-NMdjS›7mÝßÚ€#I£3±›žzÿœW-¯Ý¤‘}^šê=Ù’E_A’3Xz¼Ê¸ ÇaLQ;°F}«1‡^àõæ¶/c]ÎGZÊvN'óª ¹\H¾”²@Ê€¹ÅJ8éŠRà ã#Þ€3¥„?8Á•Vé‘Þµd#Èê*«Âœ|€*€8ç&Œäã©Å)]­†R(aÓƒí@ÏÃQs©êXÿX¶Ù_ûèW Á4‹&ÇbGð“\Âivø¢x²ûfãèA¯M¿ÓYYš1Á9úR`GqŸc4dgr^?$-îÁSƒ^Çe.u:á—×½yÇ‹m’Ï^ŸËÆÙ0Ãñ¡‚Åcʹóû«÷\7ØbKsŠÉ¿_.ø6>ð˜0I•¿µX/òÖe¤ÃŠ¸ÏÆúÐöšÎ¸“vzûÔóIÏó¬é±nÔö‡#¹ÿ„GCXdDÿD‹Ì, 8Ø:{ýjüö³yžbÎùèFxü»V„®¼¤mä­”YÏû¢®É©œÅVP99å~¢³ÕÌøLnv=ªŒ—1¹`çåçþF¯N\¡I•Y‡SŽ+1 ´‰Š¬„{nÈšÊÁ(ŒŒäô¬«ˆÓka´+FâHñ’[Ço²çH]AL£w&˜ž@NN*”͹ˆ¨=”ž¾õné%Qµ]j…Òˆ‘¤˜ ¨¹Ï^(ȼ_1¸ñ$ÿ0ù0œwõ¬¹à {U‹–ûUýÌýžBGÓ4à„ÌÕŸ*8ãqÖ«ã“×ëWgºÕ6=y¦{tüéÊ~_Ò›ôíÏ)*™3žÕzT`U‰ÈçŸzÑ}ÏÖ€% ×µ}yô©U})¸ö¤p(Ÿê*E_—§4¡`h1Æy¥ÎEri¸ã¯zpÎiØ¥¯éNÁÍE³ÖŠ”®r(  é$ÚÙÇ>ž”®YÐv^ÀPÐ3*ñþÝ8¼ ‚ax;[¥ *˜ß”tàÓ¼ §Osº­M4ríØ†5·z#·¥ŒŸî‘ü©á€U_vô£`î˜ëN’Ù‘( ¡Í@¶$’ÅÁ'žOZ™š0g'§Ò– ›ñ•'ÔTBW£$ž›XSÅ¡\mÝž§=¨}ÉÙ°£Ò£Y7·îØàu9¤ò‚š7ÏéJŽ›Kº=ÏZ@.Gñtâˆã‰¦Ë±Pz`Sò®ÃåâœÅrv†€XáÏñ»ïÓô¦É)È^£‘ëR BávsŽx¨¥Ëg A¨§fOÈ'Ö˜ÊX£ánlu `™PªŸ•ÕF+Ðñ]þñ²öDZ¦„`y°6ÂG¸<~U6×g Œ yî‚ý³žPe,`ý—ä×ßlîn’3–±1ÃÈWqØ n·ñDµ‰¾Â$Ô&`ylƪ{z,m&Õ.á×,úV4ñ´¥ŒoÐãïW—Û|HÕ ™å™Wv|²~\zg­zEž§«§ÇwjO’ãžAÚ}¡¢À«mWÞO©®ÇwòéºcÀ.šàí :mï]«xš|RNó£œgŸ ¯!×µ9umA¥¶ÚŠNp) #µ qãHÍQ‚UŒOn]O>pvDئuÆÀªMÔõÍjËhȦIHV\‡©@}=iWØóŸJhïÖ—<?Zš1óg¨÷­+qÀ¬ØóÖ±ÀòhèüèÆ(F㎔»‡Ò ::ÒñÉãð¦>”ÍÜp(Xá¹ýj"A╘œQÎML¯Ç_Ƥݞ3U7`úÓ„™9ü¨Ë7;QUËäcó¢€:&pÄI튕Q”.1Rg‘´qÏ$Ô‹ÈÁÁ?Z@BGNN9# ÈÎHÎ{gʤ`£¡#=qÚ“rƒ€Üz‘@‚@øäç¾j0Ÿ3d±ý*C>у“ØSâ–F?;0ç®1@G±ŽKíÇ9sÒžÓ*°ƒUÎ Gæï¸U&1Áu©Z5Cû1—9€•ÇCƒÎ)øR Üpj®Ù¶–i•>@ÄŒOÍ#¤¡²¿潺g'Ô-ŠÉ€¡8ÒKóJ:íƒ@ ÃŽ@fèJnÕo\1è|þ€“I6Åõ'ŽœPÌ2ùdIaÍ&U² {ä k€Cìc4ëI'Ô-¡„I2©ìy<ÓJËÐ7Ê¥?FšfñˆU\&:óL¡Åºµ YFÝ¡›Ò‚ãr ”ˆå9ÈÍ@éÈÇJ³ b¤6€ž:Óã¶8Á d†9— Ö]Æšcù“$zzW@°¨êiBÚ€9ui­V"´m/R@ëZ’XÃ2£šÌ›NòÜ2pAê(éo’p+*îçs´ë»´U(§²$¸P 1}h bS—rû¹“ŸÂ¼î=EZ gÕøU¶]&x|áæJ<µ“ϵyÉ…K•ãûÀФû‹€I!³T%›,¥'Ù&“˜å‰ûuÅ*XÎr²-ÛçÀ¥$ƒ¨wÇŒ~µ Ö3’HŸåP)€%¢n=¸  ÉÈ<)’sœ~58µxÎ6žh1™ÆO¿“ÁÅ H88úfŸå“Æ0)ʃòŸ¥1™ÈçÖ²î"1ÈF~„Vª¹V ãõ^hÖEÀN;Ðrž9¡¢ÜMm«ÚI‚e”öÏ"¨24y ©ì$ lÞ’¡ýhéKÖ–Õ€/·š§}ŸÑ7GR1N±]ªr=)od*@@YØpHwŽîTc÷Ö³õ y g£zV¾± ¦¯v®6‘)ÏçX׬¾P\òNqTKp ˜èjãpµŸnÄJzUÆcÀã4c-UÊ‘+ þuqžƒVbcž„PT(%‹*½1Ö¢ŽR¹ ÐÑë‰ä^qëI2.I^ç8=¨O8ÀQ‘ß¾)Ì0<Œu5]Q‡Ìp*ÈrSP¸ÆME™”g“^Ÿðýn,ô;›‡Ü±O d¸®wÁþ ºñ ‰Ã`§—n²}+«ñŽ¥‡tô±…•eeÚ\m^”€æC·ç¨<Õ…v[vg””¯ò  B'Û…l‘èÔ¿:²¨l±è=)#–G9*¨äµ2N›@ò×̃é@ Ý2ªá?5ïP geÉޏ5b8¤¸a¾b ä›úV••¼6¨ÞfÙHîhŸ1M#+¾sõ©cG€“ƒïZú„‘0"Päf²_qÀc­1É-” ?•1€UÉbOqVW.pNæ”G“òmÈãÓ4±Ò~4CÄK3ê JcU$œÓpi\F‘|à¨õÆEU¸–(Ó1ïÉê3Søze‡^±–E`žhcøñõ SQ±Ôæ¶f‚â Ê;·?^æ¼Æò÷RYæ·»¸‘dG*Éœ`Š÷YcFNzZòÿè;„š´d.ÒAê3€~´Ð˜‘Âù…•™zdäš‚Yå³!P£œŠ­¯ÚDeÛÞQÏåV£e´™·‚ñò³'&¨±P1ø˜¡³~÷1C°ñœâ;–ß&Ü çnsí@ îÌø ·º§¥9$t U›óªÌÏ»Œ·®œCo^¹:ÝLÃ;Û'µæà7,½?»šIÌ n ÀÁ<ŒÕu.:«zuÅLfnKˆÏ¶Þ´žr8dq~Æì φ¢UdéÒ€,Ÿ%ÎL*}0H¦·RwFãØ51£ãt„’?ºiŸ þ#ìh&†ÍÆœ¸Ê1ÁäŽ9®‚xå8'ƒÓ5•}hÐ>ò>V=hÝ´ Ã}¥Ùʤ6%'¸æ¶žÝQC®Kt$לü>Õ´d·2Ÿ2&+·=jïÌìa;ÜmõÍHAãHŒ^&ºÄ7õÉß…ã-žáÒº^Û¿ˆed•NÐ>õÈ\²Ì!÷úÕ Œ‘0=³V–E yüªž[~Ö©¢NCž½ie®D`Œej¨ÂiÎæ.jìaK—ê}MH‚õÁ¤nŠŠÒ«K/úCœ ÅYcåÄXžÜVn>n§“šÙ±Ñµ Så²¶’Eã-”~5Ù蟺˪I¹ÿV½ãT¼/â[}2+[缉ЕÅ‚ gŒŽµßiéöëa%¦¬ÒÄOÞ‚Gך@hZa “0¨À@ÇÒ¼ÃÇÆ;y¥iw–^=1]ýÍ­Ò¿m1Í?θèS3%ÏÚbf=àšòÃþ‚¤ãƒŸ¥M)Tž+…ÿVÀRYéWóÛùb }[_ߪ¬S@Æ3Ée àSkx Í*‘øšª4´vfm_ï7ô®ŽÛNŠÙ~h$“«sQß4b2©§ 8ýR4Hö¨À¹öÈÎ oê¤37Ïž;b©ÓÐæƒô¥ç=isÞ€%“ÏJÓ¶ÆÑЊΈöó5¡nxç¥^ãžiÈ4¡³ùR¬2*,cÒ¬GãM _o­4©5h¨?Z®àúPgóMã#Ö”žy¦“ÏNhܧ½™¢€;RÉ´º¹ø¥D##Ÿ¨5èÛ?uNxÇzpp¬WpéÖš bÜ IíT^&V%çÒ¤d gÍ ‘Ǫ…Ë.Gq@¦Fà®qÜÅ"ï®î=)¯+F¥£çÐóU„Î$ääv­0._3“&ßîæ—oÎÁ8¨a•CÛõ©#Ë7ËÆ{´f.ݶKv9éCK(BRF*OSÚ¡q ¯9ÁÍ<ìa‡ÉÏ ÌÌF×%Sš•deÈyô¨$U‰pNŽ¡¿JEÁ Oc¥N›IÚÁ³ü4הхÆÞUÔNIÆ3ƒúÔçMž8ÌŠ7'|r(ªJÜ)âPGù¨[“È;³ÖŸ!zž}(Ñe*sÔU}˼öëNÀ äŽô˜hòÀƒ»“š²¿dp¢BËŽ Š¯uÊ!f#ëÅ4Ú “ŸáÅ( Iyþtˆ´œôÒŸiÌgOõÇÖ¥ :sÀq§'<ó@'‚çM¸"9J¸ƒÄئ7ˆµ—CêwE1÷L†®N†XÆ}ÜŠËž 2çÊS´rAÅfÈÏ4¤–gbz“œÖŽÍªª:Uì¡É2À8¨±g“Ò€ Š=Ï’8÷¤ò S´àÒ®¤Xc·œ –8=Ídù3!ã‘íW-…¬6þeךÎÌ@TÀù}sëš¿ä ôÆ8ëQ=š¾IÈ9  šŠÄ"‰ 2yN27®zVY9bzU›Û–žP¸UQ¢ôYÙö…Ïz`jià}œç®kNÇS¹Ó'ÙLоz¯¨ïY0Êc.ÞÕaƒ«p$õî)èzGŒ—S" @ˆn2p>F?ÐÖ?ŒËɨD s+”UòzÕ©¯'ºˆDäÈcû­Ž@ô¢À\Óµ{Û]fô®’ ~ÖóäuÙ!ê ®'súqNÆ:õX@ÚïÊ;Ö}ê>ÒsŠÁ³Ön-@VréèMkË©Çw(yÇ úÒÖ‰glôþuÎw9é]®Å‰®{©5H'‚sG¦?*9¢Šq88¨o\Ç mãµP7“ŸÆ¯Ú·—B®[©"Š).We}W(‰ ³™…Ì„?°,6ÙƒŠ!4OJ\± ñlµ$¥¦¢±ª˜nSu$*Ã\þÊ"b4V–ÏšÈmkeeöRš3p“¦áCžÂ–«–|cnµøõgË}ÖŒ³Bõúd#륫kNh`ùùz}1´ð«ý‹GȽäÓ0×± 3rçXñvó=·tdÌž‡Té=O¡ÄërJfµ¾£öV°°–÷´p×@e|—‚XLË\G¢2œ5EDR¡¦b@#q©xEÙ$(Õ²sf˜Ë`KÜr’¹D°4¸#õ%œ´¡L¼Ìñ¬w"±s)fŒRŽ™0DŒ6‹IŠ´kÇÂ~ºÁ"B*\å­-µêZŸ¢¶«t¯ÀŸþÌãùÚ±£âȬÐvµ¾v F/¦¤9>ÚŸö]p¿ò¡/5b²+¬Y _ù°líZ‚µªÍ•p Ž„) ¯È¦©p”¥–‹×v¬**’:„ºägZ49fW$ŽÂ GlVÓú ZP+è|¬BÑh ½#ãR4)­‡_kE€Š"¶$g-`UXQñà_ßÇBAœ-4/JI%P„Bص0µå·'Ž:O]2{&+U:ÖÅ\Ÿ;X_óÏoÎáŠ|,H¤ûÚ qò½ íPQÅ\•Ïù×¾²Þß++À…-ö'ßF¾ éXµtÄ@ÏÆìR üe½¥»¶a¦©z5÷Ö³`OçŸüñBû1-ZŒ«²ûŽF£þØ´ÑPý–Âk•¢‡;âígQeié8}]”ŸaRª%äÿ$r—m{Ыף¼þ–qêÿze .^ÿr*ÂɽdD‘döˆòÁïëp_pº»¯=YaåB³K…¥v±‘²'kUFQOȰBØ‹é¹l<»Šöµ[«pÒF°Å{\ƒOê“Ä8/¢£5dŽAf 2I Æx€mWžæì+ÚÝ3šEùžÇ±KŠ@Vm1$ŠVÍÕw/Ψa ŠÌ^-h±io„ý•¼A#Ø^æ¥mô}î0ˆ¿T|¤C§½&}æsÄ150+ðøP„%½«6 ˜ÏÇí\D“ÌÚ!AÒþÿWÙó‘† H/.ð~êjýCñÁþæ¸çÀùñ¹u<1atŒ2I°Zl’hxçÇãàüôï¾'?i k¢Y÷åŠX›ÚñÅD!¯rÚ,åW=ÃTÕî .A›ãñÉDyÜTVÄrÞ.Y1…=íBÕaÞŽ jÌ™j0Å.äR“sЄpl¥ÆÉ­õª1ܵ Ä(ë&?Ɔ¬†±z“¥}«KœÕVäúËjXšÇ‡ü® òtñ¯tž1)sUÖ9ÂeÕY â- (pPBQh“U¯ÿh3Iö<þhŽ3¨ÊÔ„ #Tbi£BÇí ÊOõÿí]_ixÚ¦¨¹iœÚ¢b*¾S`iº† ¸êÜ#M$&¢W*B—ØÖ¤ôŠÞ.“?AY~CP_}Ò\À¤Ì @FzÐ-Å®E&Š–©@­ ’†×`|D:ÉYdÄ^HÍ(ÌV‰Ú×´‰:’ã'ÚB^jv‰:”ûè1RÖ¬ÜYQŸÏñAZR`mOqL|= ³$½áŠ–ÕhU-)deGQ_@tû-´ÐB–f§7Èò0GÊlYµFBZÁ/´V({Åkð½½­ï%q7Pl‰Ü2ƒ¸8i qÈ<f¾/äVŽ$T±ézXr9 j¢·hîàAà‹š³}?ª×J¹‹a,Ñj(l÷Tv%e’†li…­zVß0’†9\íøš\$qòÈF[@ëm-*”kX·øU‰* }­[JÇ¥-a­{WåfJVÖĵ«ïïAÚ’CQ‚¶ýu©+öSÚ-QÀÄ:D´ëOøÏÎcÌÁ¾¿ªÖˆ­ãþtˆ _êŠ Ÿ2–ŠÍ‡ð’[þ2[ZßM-/ù¨ið†ÿ–T]PsuÏ'ÏŸÀóÍž¶äÈÂÒ—#O‚Á$_”7ãȯšç§×ú‹›Ÿ®ÓΧQÀX©^ÔŠ‡ñÔ?¦Ÿ:–*3¹pÜËX¢fÿ;À«k^}GAƒöšßé«ZHC"ï´ÕÉ%4^(Y‹ûÚ)BÇ=¨r–&du¬Ä–¬^moŒ}t±"Ñ[ŽÓ5ooo²?ô 1hŸx˜šýŸ;P6÷!GñôI›ZÔ½Y¹=¢Ô›bò: Ì×’^Ñeà?X…ùÈ{&.:Ú66ŠnÖB¤Y-‘5’@á‚]ñüaæ¿,žJœ´"eø{Ã}ç˜7ÿ+”£[Šq—I#= ¶‘S~C:«RÄ éñ'Ä“aA½à±í7´Á`“zÒ¤Ÿzšf‘{Íäß1dzjÚUú;Ò>–ºÖ&VŠÏ¦ŸY9b‚sŽ ·é7Ìøj5NJ³v¶¢Ã2äŠ9V©"‹_§cC‰‘,P¨@ûÔ™©ˆÿGÅ€@ ñ㎥âw޼fŠš‹8Þ°Ã,ÛE b±+¸|tôâdk¢>UúÇ@¦¥ ô0"-Yµbn2ˆÕ\¡kçh\#ÎhdÏ1tÛopÛ½HÊšvËØÊŲ¢qv¬¶³V%,E~‹zä{B×±Zi˜£Õ»Í¡c˜ùè¤VbÞ'ç>õ°góßí‹ý³ Ðo‡Ø&=þíjZÒ+DÁð÷ƒßò—§2oóãÛÝìñ<ÁàNSäq3Õk¤¿cäò·I20Q•Z`¤È öfC:" À2œMc¨âé0®FDP$i4É<­_«j«µUc[›Â‹ Õ–ÜÝéªfý†¡¨O‘“Ûâãc{ä’y®(à…äbò¢€¨Qòê>ÿö†ñ¬_¾Ê$¡¸W˜‹^/íq–(3à;v+¨î݉%,ªQŒ¿ÆòYòŒÅi‘UJa‘pHËJÄÖ—V‘®@ÅiUâµUí§ÃÚÊzoâÔ/-Âӵ׺ 1™.…=îGg–\ò-îØÝ&bû „N.:°î‘BTtAkUÊ4ƒ,*Ý/R&ÑÄÌ~ä^a«ýÒ—Š"ö'±-íò°âókEmQ ê]¥Ü†s¢Í‡˜1%"ݺ&›Ô€À5X&¿GP»Oë_Ót§ïuÕ4¬mn¥Ó&TÓ5|ƒŒcYâ3é™™‘C‘ŽòF³A+Ç,lÀ2X‡Y»®–èašG'êØU\*AÛØU¥Ãƒ\—=™'üFJØßó·½Äõ¿Iy¿ÏNmHú-(ÃqÚƒ­ u5,9¡&µ)_éi –¥´Eh2${ÍÂí‡a@‡÷Ëx`c’@ävÄò2™aý?þ“jMþu˜l­­ð¥n%íQÒ %û foxŠÿÈv¬Z~ojÚ±[åx™¬É`aÄcÂf˜Aà€|žEøøÿn•Ów>¸ò,¬jž% yL…˜ÄfÏÇí}-­èØ¥¬MÞ$u÷\Cùˆb²qQŒ šýr­¬™¨â@B×똯9-ÙïUº{'‹}—·Þ°GO²~Úšã°©>ö˜øÞ'ç›Z>w‹ý7jEïó­ §×$’^j[ZKXRžvkYÖ¡¥-V>6²Ñþb½nH½m%«µ=¾Eµé#¤O·ÇåÿbmOÿfm_kÄÅ}¦rbãÐZÚ$‘Á/ÁããúõQ&»­±v:Žco°÷—‘eNë²y»Sd±\ñÓ§ýSº5áXÐ=-£ô©í ©fu @Gæ |)kf«JV׬†«Æ¢ð?•’ÛÖÓ1>Wx¿1–Æ$·ùÐ÷b—?ÒBAo[ÄûT±B¯0H’M¯þôÿäf’Пò’RƒŸaSýìKM`8­+K[æÄRkøDÌÄÖ•½¦Ùª 10/iûb¯Õ3ò=ïr´­l:|Íf}ÌJ)$‹È­{Mííþm\xûbEàThÑÏtxúˆú–|ûV|̇;­Uòç#Ú.Á#ÇÏho›MH)«3bIKõÖ‘\ÚZÖ ©+zÖ~Syböb”¸îX%òØ^IBAÆRÐÃ4ˆ%ª:õ­=Å6© JPT æöŸ¬·µ¾M£P+¿`ÉC®hùRÔ¤"¾ÿab¬RÖ€H¤Z‚‰ ©3ù|bÖ%\+)3µ/j|D /îh‹ÑX¼ÐTý7±)"T«´Rˆa‘‚ìZ¦écDU P$ßš³Bëúž?<ÙêL 4„0y’ ÒH}Áˆ÷IÍ „óíüU޼¯JŠÉÒ'þum{Ú£ý2K;1oeopRmñ Çõ7KX¢ `Ĥ1·ÛX ¡ký$œ4Gæ^ô§ÓVë¸ÀÅëzZWv㥌zÖç~ðÝm?åãßÇ_„=W=]?=y¯Åž/ånë¸ËWÈ=-9 RW:þÎÚëa"Ãf¸Í&~†Ë÷.Ô`dT"+ŸÆÏ§ïNí=>ù‡Å^Iç•ÓÍGQßw¼÷\¦þNÝÌê/®.³v¨¶V ¶jœz"]T©e*Ê£+êžÝ0öÃcê :ç.–3š¸GPhÆ@ÆvY]ƒê›a@Åm‡$t~'ðùܳöb÷BëZLz“vÜÝÛ‹¬¶§‘Û‘LÑ>jjá­ £—$âGª®YÆŠY=·ksü0ÒÃ`äRcô ªß”jTðC„—‘ÒB5œ=€jÖ“!ú¾ÃÖI8ðM’.ˆèÄcí·éSÔ+ ÀÛ¾O'äOnlgáè·ŸŠîÊþUÆAn‹PkÝy'™°†¥dN½«TQZ ]ñ–O Ô¤ûˆ‚%í6bĈµ¨ê *¹æ¤½"¿WÙïñö­}ëk^•ñÑsø®þ[7¥Â|}oãêùj‹öOámÿPÝzmP³R‹¢\e*aúµbL¢É±vÕ©ÅïZÏûV£ Çñ7Î"ÁÈØ3RVb´-¾t&kxù@ý½ªJD èk_þGTXìO4 +=½b´ è¢æ¤’´­ojŸòŸ{DŽýë7­¦Ÿðšÿ“„(jÀGïí??ЋñÔD†k·{Oö¶¾ÏŽoϧÑùæàP—µ {HÆÁëzIJ*A®Õ‚KA\¼¦ I† ü=Û­ÇF8tôÒqVí\YË~ µa÷¤=(ꬡ;¬*"l ŸÊa·x§å,HÃtu.1Øäöù±4>Z„± Š +! ³ëz~{㽇rä´V¢"S°™ÐËÑýzY?5"ìÀŨBJWï@"Ò ¸i@HX\…:ìö Rªd¯¥ÈBðö¼ °xø'ò8ýú†À2‰X¬g†UfM¬kkP[‡¢Á£}+)\i¾—86R­@;Â$¬Ù×½>¶žt)®ÎÍZÌceÿ¨oØ2±ä­^oG.9ÑõU‡O”xY¬è꛳Ã]Œ+y«&?HÏ-‡î*ë­]l0Ü'•…Å‚(òAñàø¿Rik03Ík7ìh¥Ê%¤¿*Z÷¤WØ0/pÐwAÙzTƒ¬°&|ûDÈW ÀJÞõ4oi9"Gð¼I1ɽëð¡ªIšR§%&"ñ11|1Äfñ »º{uµ¦+\Ë93 §¤6N:ÔA]¬Ém¤u×jæ ©sdJw>~~ÍHk¢ÀÀôßäï!öÜ¿ãLu;ÞBÓi>3 BmIL‡¢s_HY8è|×ÜŽèhæ"½ä%+ ÔÁò:2ÊáA)d¨fñ¹VÏ'à€@>z°ËÑó4øS'#aŒÂ&uIׂ"ʪ2±Úä‚Cb‘°÷ š¾×ãòŸ¡ß.g¹5õ1 î éõ}õÎ$FtP×°æŠË5½ÎËT¡¤ßª&Gn‡w|­âùÅ´ôµyåùÆAV]ÛKB5Â4{ÓlÿÞÛ¶?áLÈ/ê]\¦sÕ½“çû—ôç䎦ûˆ¥˜ŠÏ;¿Õëæëmægº¾o;˜æ–®ja×\¸sXª ¨ ‘ÓÜjŒl17øØÅñWzg›Oc}„ÔÌu¤’lUfo¹Ð)Ïgd ¬ÝVuõÛÞÒG!LÌEŸÖi–)+TUÚ,¸ï/§°÷–~›”ú¦náZqǨ²ØES!ÿáa‡4o޵þ¿‹½OøvíÎíÑ´îÊл¦çÉÇÊ9ù™9X¹ÙáÉ Sˆa‘2±‘f‘ãŠb»å(ÃÔ4Öê’mm[àíeæ‰Ý”Âá†Ç*‘µÒ%ƒFæÖ`4¡þaT‡lÛY†¿ÕiR^kZV,@TWˆ! í"ùÖ©õ‚šV—VÖ¥¢+1fž_ÄžŸ´zoúÂðGšs<¹…Ýn3Ñb™¤¸Ûó /™š5¹ý®Oc'ýGMêu9ð^€Gð4‘F6¹ä¾ ½0q6å:l¯O|ŸEŠÿD®‹~Zê2úuù‹8£øyklc,]®…šì±•©²‚ïó9ëèçlmpsoßTËÀo´]3"a\xr^hâ,¨2Rê ýº¾]ÌOÍÉû¹³¡Â›TšLµÁÆÆÅs½ãJeŽ` ±H¤y窸­Kl+Ål1ü­x‰ö½æÅ‚Vö¤M¦ö~0;}–‘Ûí˜øÞkòàùR¶§·µÄKØ·¸‡[mhùÛë´Þ×¥`Q÷^mZ+Yˆ™­…ùŸ•ñ¯—|…ϹãnGÅëö™9˜˜,ôzýò´`ùÙpçS¹©—õŽÅ»‹…‡pŒ.Q {b4ò¹›§ÓY¢ÿˆú,~Íž'¨P<†žwDþ©ú"³qåj¢Ä êÚ á‹Sbj7>$·õÙú^“C8"‡æè/b˜Ðäcœy £2oY@.r8?>kŽ©çÆÙ X$YÖFeŠÈŽS´‹2Em°UžšýÁ !Å$7¼E&´¼XsBͦ>6,E`õ›V‘4½‰h-9½þ5¯¿¿ƒMNKûDÖµ™š·´Z²B rZT€Å©¥o#ö‘V±ŠûHKz{îaN;FЊIy -—y¦Ÿ@œ¾tÎP`+œ°Fb¾þ;ÕQ+¶7/JÇý«¾¢hZÞò.¸š:Üîª u7n¸/½¸°vƨˆË-cÝŒq®ðKvüâ^íhÝ…¡8ž%V$ìpP홂š«ý^/ŽO?›5ÔEÙ!UGYÙhÈfà,iRîgV5 ÛkÈ«†þ³ZOib+ï_™ Jœµ¼Ø¢­¬V-KV”©H2ɦkK’)ï3„ÿ‡¿N쬟}´7 êÏ…}D)ì̈#©Úð“A ZÍ>LMAVádXc ØÕ C±‰­‡±¹¨‰s5óÞ1€Ü‹ì†®˜È+Eí·ÐĶAÚƒZ‚-ÉY &ƒ!xj(.ÓRL@&:xã̃ÿ›w£ú|CÛ®UH0^ä3O°×ªóŸû5œ›ÿÈä-n/ñN çó⬎|ÞüHŠåDLMêF¼6Åb”0äû=¥G“ž„_Tßá_‡Â¶$-¹biÿ DSÞ ¯µoZ’o0 ´‚žöÁèß¾ÜñG£SÞIÁ:ƒÓæ¼÷écå$‰®õ|Ÿ—úA"`} hW5Uüõ€/lâ4µêÈIjUú¼öþÙ:™:íJµÓqpÉRÁó÷°Œ$˜‰,Þñûovbã-Ø·_á—Ǿ6ó¿©*øÌø]gáÞÍ«¦ày6ŽŽîïÌôúœÖ«ÚBØç·?ÊSWQ…ÑéÐiãY#ùDP° QÜk>“š2Ö9ñq™'̈û½\\vFšd÷oX?‹'£/§g^Ãï.ÞÉвÁõµÍÇÍÒ59¢uô%‰‘¢!xËd aü¿P•uA"í²þ]’ÿèŽOÃ=7™¼®‡é›ÎÛðçAà_“Ãæ£2zN7P~M$tÏèõFk¹6Þp™@Ø«e.¡PŽtïá–¼·¿ç/!õ]Ç%Ì·Ê/ƒä®¸xùºŠT^Iòÿ||¹så±Éƒš¥/äŒÍu%ö3i;~–.™¿®ÿ:Dðÿ _I^tñŸAãK~4óöW«?ßÊ}C.ïêq[ü_¹W;QxΜÎ&#Mm¯›Öeá÷1Õ¸ó5ç§ žgCvw\O6¨³è[Ðdž5=9úÀsÖη ã+áz]ð?;éÚü¿’O’NéBy'/È‚ÿ]c:–­îcy{‚ðžB—ЦÿGý®xñôtØÍ©ì>ÏímmgD×jËŽ2™ä“&dU‚ QmÀFó0)†Ô Aé‹õÏêw{k’ÍÙ½×6„÷;ƒRÖ¦ƒEÐtþÝÇÈÖõYâƒRÔ$M?/ñ%àbê2`eD»1êšöŸòž—ü+ê?£ë<Š>oÍ>`õÀ£“Äìs—óy â¾c¢éü~^k -€ªpÿ@ö»/ãû-/z„óZÓ˜oÁ^$ôyä6r:-œ—¼ƒ>¦¼—Ësrâƒ1ÊësX[/ÚúºQ2…¸9s9är×¾S<Ç‚}Gw=¿E-òOŸÙè¹îÿ VEÓ²íȶ.÷¾AKÑ/ÄSÒÄbv™¤Ñuª°—3Ëî®Ò}½ú|Óôµé ÿ騯Œ'«õêĽ‡«þ¼ð/…ˆþ¼¡µê9O2b;ßåò¼‘°ƒÚ©Ï!–~Ë·[moö|‡E<¤¬Ã.uÿÄoOê Ó_”:ï'º¾‡ª~ÅoÇLàöNF‹ºeõOÔ~CMSÆê„²¯™Ì¸õåµrTåóZ ¥«¾,l9#žXá˜&2*¬äÌÏ Š8•,Ú©…±MìôÉ4cUx2`2BL”«+zD€îTïåJ”`Î@€»Ø×$ôÍåØá´¼­›Ï«·ã\þýÿ+Ùæéä~]~»'Ù´s¹Ý6Ðí**r:¸û’Á9µê55QF÷‰ÇTþ_ÃGÑÏÌÙëz®wÇYËô-æ3×§Ö}Zës‰8íjµ9þeSÎîÎu9œÛØÑYÛ¸o¦lŒºr{I4ñ[>§¼ˆqœïúYÞOýb^ã¬^WB&;ŽÇwú >Néß©¾ÿa×ã?r¤¿èÆåÚç¬ãHW[=€ËLÜfß—|qãÏK½ê{¾ñ/iêÉ%>×ù/®{´¥#[ŸÌå㌎»~ÜžOÍsZ›h-†(£c°§+@t}"°–%´v ,Å]†à"]¤:Æ´ÎÅ7«Í-Õz'U…ñ¥Îí²WÂIyQ] I¸FÀST`2€KIý=Q/ü)=£9ëàw¼«µ7ãWëÊêë|bÏ“³|f.G^5ùÜÕKÐÉöpzJ;„]®4x»yéµÒYm¬¬[SþK¿ŒïúõgÕúmð¿¨"y@çRºšïôÒUe÷cȧ²`Tn™~8•¢w´ôóßú*Á«èWÖeƒPÈÿ»¹"8%:vR,*räÕŽ<Œ10•ÃÄo‹^¼ÒGAêÞ©˜ñ®4ú¤Òôž®«^3êºô~\Šò_Ÿ ö_1¯ä|ÆvÓ¯Œž‘|Q³Î¥v²m¶Pÿz°­ß%nú‰ØÚà<‰ç >eloõ]¿:»8†&¿ùÚ>[‚;„ÈÅ‚¤ú‰|}í©˜+¾€4E–ëÝU»ìVtñ'i—ÇÓ’òO|Ÿâl¾Ÿ·G¿cu Žg°Í×Êæ“/³¶²ñ)©Ù#Ÿ–cc޳Z-‡ aiìh®gI¥CŸ«bLJ,œwtw+ŠD¾Ð$ÉÇ#ß ÷ò9@iù‹›õS±´­Qúƒ¯iŸOu|üý+ ·—#VÃÆÌQH¢Æv2¦¨“(‡9¿à»Ê±7«é¼¾ô‰ü,äú¼ô×éÓÎZйþ“ŒóMü—¿ÌôŒt=§iÜçyÉYþ9i<}Š›‘屨7+ á]éÉ3¯Ò¬/E^|x÷øóçKàîÇÄžoð?Œpºÿ4øË»®×MÑ1×e ¯ÇùK“lÀÿëž_wu½mM>·-\|5âqœDlëUÌñ¨}cοE¿Éï>§}Pújõ-Åñ“ügÌx9îZ¼Õ¬ÇWºß åmsñIé5 ÐÀÌCCR®#‰‰_¿ArtjT¨éúÐ4ëI#XLü&Ö«UgéïjXT~'ýE··ÙK1ð¨-qÖ¶¬ülàíˆ5¸âÕYT¹³bž0¦7)¿‚Ê9ÚÑ þ¦ýºCè¬Qõ•ÇL[b™€°˜ˆ‡ä†`<ôñ©iÿ•`…ÈS5‹TCí,Þö'¿ÖjEGzVóR@È ‚-Qµõ«aÍ)ôØt¬}‘íúà6öûË4û&±H=¾©Aþ±|©§×8™^Þý‡Ñ;„Š æf§'ÕöTt,ZJÌY­ y‹ùéíìkZµ©o÷_ïq½ ÊôïòøÚõ¬1jÒ佫íìǵ¢~Ș%ýâþþóïþlg•¯7Ïì+ÏÍñÏöüÞ{F |æìPò+‚~OÇÍÑŸG‰ë1‡âjæ‹a/î±Í«™ýZŽcçêhç¦`¿Hè:isúƒà+ñx`Òb979#3lêê»TÑ`´Ïšm¾ÖRƉY† ÕÌ6“ Î9s0¾2&r¢ù¬‹…½CgY”O7¹«G£ ‰ŠCAÍÏe›;QÁ-ú3ʧOÌÚ¤¥Zi»ÀE ünš‘|¬Àî¨BC‡ãV Fj)ý-T÷¼ 7j šÇ! U°bI0ª9Ã0²ÎÄ–›oàsVG?¯_} t¼qHè]) ÁOµÓ“~È5î ȶéó¥ãž–Ùh%š½¿ë ²ŽÚ f0Q°e FGÔбEM¨KC‘lïy ý€¼•ã!õÞ2ìrŸÓq#‘õ"MüÖÕ¨›ÄÈÛM…K`éé-|ž‡ êMnÄ’¯~[Ö&±™…KD¬(G§àoA´ì ÜuÖ¸™“ T¼„Ž|±óäô+êÔ•1DQA7¶òÿ“zÞãªòQØ—w³íôt]&ŽV\?¬œ!ÎÅÚ§o§óáçˆÐYOîTîË7¿ö:LL4ËÉIÕ^tlp]½‡q›`ZàŸCîl‹¦‘ÔÉ1tÙò1¥Li ˆ#}Ú}ïÜï}í±ñŠ)"ÚŽ¬dbpÀ=tÚåSÉ]€ÎÝ-l7vÀ®Â˜.壼$cBåÓaëÞËÑ®hާõÃeBøfÆYi8’oøC·§›ßÆÞÎðEê/¬ð^Fƒ½¹Öåõ™øÙýÁp7x,®•~º6á·y-Žºœ_ú7\»cÊOS-¥•ËI]„f­„·?,•7 Ådk#Q(±W)- !V¢¢rØ_”Ä"•±u;$WcomœB0«-Òç^f9 ö«Tb„2¦€+:³3¢E²0S !P’Ÿ69"(ìì’O¤Aö‹Ûº¼ž×Àù“=E‘J%J­éúê°aM·pòkÜEù¿ÏR‹G†O¤_Í[7wk·ñߎ»#df÷0ÛŠ“oÇ©³¢Ÿ'°TöóÒM}ÞyN3aô퇣”*7ÖçÛIqÜÏé;Çý?hÒíädþ¬î{¢¨Æ¿3›LcJÝ>ÿöÎg¹¢Í,¦šÄ’˜ ÈÕIuÙúzvàÖ–¼‰Ïat\§?侟¸ü™ý®OQ¹•…Ôf‚šš{yi,¬¦±íôºáœ Z#`Ödqþ#£ä^»–&‚|}ÙsJÞ¼‡²ßɳSxfæ&.¶@md®š¿¥h=Ðxsìu—o'"&…V?Z2ÄS21$,+ìŠ-óàðz´Š8\ç}Ôxù ›><²”Yâ")]ɲÐ8 ·dóWiXž<Ö·aäß0 OœVýKŽÜÁ×MÅ×Åñdª ð w6cOKj馀%~†Žðõ)®/ÂGɘžž|¨ÑÌ' õf­¿Ó/ö4ž'öçU¼ÅÚ‡ð×­Ï ŸZê©î|!ë4I`w¯?õfØâáê÷kúSmVh¦Þ *â£ôÑVh6„mA4´fÑF~e½©0öCÚn+O.>è3t„ÛÄ/EÐÆ{ˆÌý/ͦ‹%®‘ŸÅÏÑÏ[Ní&³Š!$¸ßRJ¼¸Ì¾ƒæV‚x2Q÷3ð( C‹%˜x×ÇÀÐä1¬ø˜…#H•ò$U3cã²JÒFƒbúŽâM„h,XMïJÞ¡¼…‘ã¿P>˜ñs‡«ßî<Œûÿ×xßiÜ¥¸öspvDÖ^®7µ‘3‡¤ùÕÍ•¦‚rMAü)Q’ìM3 c1QüCŸ´¸¬j «P„\ƒ©Sü|s|ßUÐX…åxý6V÷:„xÉœ)žç]°Ù[4Un€žeZ91qä…QÕf¥Rbî-k>»<8•}´¡Ýè›B„,GùGÇãÈù¤Ó4M;#*‹1ãŽ(æ}¿pìÇ2¯”O¯®Áÿ˜þQŸzzôGÀúõÀw•8xan—ÅY¾eðnŸAO1éuþWò ûÅ'o7¨rú++ó[K ¯ä{Do$ë©ãÕW{Ûðžœüéó¼æ8¾ÇƸ“¾§ŠËÕùïÂ^jò7‚: $bu}®ÿ¡éûÌ;fÌ[½QE¼|ê¾Jç÷¹ÝΚ÷ä!.¦ßʨ­õmÁè²v¯¶ì iJê4‹&Yp9"XÎ&a4îqÆ+7öÐÑAªA7\LCkiiêf¿ tx®ækŸ=Ñ;™ÿXÈÓMS׹ňµ,<¶j¦þ×èÕ²²ñH`âuÚ'·¢Î÷@ÕŽH`TH 8£Pp»oCÐrqpr²4ÿ»ÅÎÈÍ øs.Dz‹#Ï7ó‰[cY Š5Ô“ñ§©-zpê<ÿâù!ykî¼Uå[ œþÞiãí|ýn}žmmŽv4Œ0DËÜå4²™yXGPo·‡ 5f—¤ùKËžTŽ3Æ^'éüŸÓîxã̸9|÷)Ëïo·]>“Žï?Ï/aóê–ù¢>ÓµU}rgä&K†uÎ̶‹NNŸCÇ–ÿšúŽwÍ8¨q¼çsn_kÁ¾+ëï¥Ïu>ª³‡¤kùü²¦÷Êñ¿ Š‹ý—•|¥½£™‹Çqâ#¿»gA –ä÷›gÔžNó„= 'Ös¾8âÜäºfý|uãNÃÅ<†—ÖËó—|^¯!¥æ¾WÊWy ¿"zÒ×I¸žÃÈNèi©é4 b}r93ÓK|I~12J²ÔJm<¥T‹÷)'ñvºÎš˜ý¹'vãê|Ø+Ÿ¨Âά¬ðf¤K2Ç$1¬¤&YA‹†]D_t³¯«C#Æ ò7¡^ž|?—«æ/H½¶"“}wµËùK£ÎÒoö·±<¦—ˆ{®÷k‰ÉW5Fw°åùi®‘É€1?äyþ5=y;øàóßCê Äü§Öw p=?‚‡“y¾×¨â(¿dç>M¶)“ÆuŽÝôHž), ÿt²E0+fäÔù7¡hÞ€¼Í¿âò¿uê“Ì^™xfKã]¯-ø’Ù>z(ôÓ¹½‰äº“¯Ëåz!k󼾯C™‘Ò±Ö]œ~9‰ÆÌü+±r¿ÏƧ¡¿6ß¯ó ž£üSéã—áé“©çOp¼-åVÇ»¯¥ÈxÛ7¦Á[Ç=¡ÑØkœÛÈKN;¥ÂþºïòZ¬:®xâwdZlé…†ø²êˆÓ·ÿ/&|*f É*0v Á…yè¿·{·\Ð_?½²txôýI:ž—.—›¨äçv¬n¸˜ùí$Oè< øí>Ÿ#I©a¬Ñ¾LJ§ê |ûë–ÞyÀ켞]N'Æ–¿— ÿ3é¿ÅüO—9n;ˆäIÃs8wÆË#ÛÌC3­è|Úüi|ŒøKÖléé5Ädrt\ˆÌ¯úÓþ<´=z€ä=SîyÝ¿9ù—Â\O'¢L.SGûe7ü5‘Ît<&?Š÷…È»ÁñÏwßÁçy ©ë§R›œ¨÷†þšZZÆØ-8úìð~Ç¡¯UžVôϱÔ¿è|X×+ï2+<ò}Oä¯qÞHÇA ض¥nÏÀRÙË2¼P¯A` …‰ö±±2˜â£qRPÚʱQ_\PÞ¡›Úú¡³;‹7>(–ÇMÞDŠ-Œ‘I’ÌÍ:•Š•K"ÍñÒZ^²¿½ã×ðÏa™Ôô^|àïßpž:AèfjøÓ’Ö3º¹]®·JŸ7ÈçõOto™w:j—¨ØèˆLõQH ;%ðG?3!œ»^Ÿ<àây;•ÍâpTΗú!á‚ º·AÌL «è!º.u¿$;ÒgþD§[©Â3È¢‡¶ÆOEG”òµùÖ?Þöý36ˆ.Áç Õ¡D‡óÿ²Óhec:¥Çjè)¦~Ù‹«f?™ bžõ‘äb+…¨¸…O¼×/-/RQŠ+ä¸:«ÏëÊÔÂ}’ÎÂEŒÇ¸}¬CH‘Íób^Å…G™žæ)NBǰ˜”ŸÐÕ… e¶¨ |ç®Ë|}üéúxòÿª/ùOÎ|w‘=?ñÞ9à'#¨òOƒ¹>a¾ëW­åø^·'‡Tù[1Ú(ùlra`¬mlÉ54t5r²Ø34¹æ¿ä»Ë~iê8ž«`-ôEñ¯’—ò/,ö³R»é»sw=.‹*º}kèÔΠZÂÏZ¹k7ñ^(=[¸hÇU’,ÑKT˜HíÆ‘jÉà"'ÕôžÁ%§òÖBD}³rV´©B+Zk޽¾¤†§•&Õƒ¡€ Ëåö@ÇUÕ jÍì0´cXÖ=Ü t &ICØÖ‡[Åцf14#£ÈHffVfphM–° þöz‚˜ŸOñòBÁ4’ڤ BÛ·ÁS_ó[À$ñÉ»®ç¿™/VüN×n ³;ºÄmô¶”ÕHñ/>g—çØQ¦XÇžsP˜¼v¿J·ôßh1Ť^K®Á_3ñ<2ñÇòMç?ñ|w9ãŸi·Õø§“ñ[Ý·^γ–æñ•ÇS7®ñîº>CÆGy¡‰Š¾']·¦–Î&§1`dG2œ2ÖÎ…MºÜj-F Hr,R‚iy}MB¨âkƒr þZ;7£KC¡’‚³rÚÉ"èw.QØ Oñ'½èzäcàÁþñZÄ¥‡bA¦¥l2Vÿír°O¬Ðï «ºÂÎñÇ"1t‘E˜è4aCT‘€¯ò’¶C%E©v–!ˆ|؉ ñÁü†‘D‘ÉLTá^5,9€Mõn½gòIê÷É= {»{|²="Þ–¼yé–nNvî?…øO(ãùU\…6ØpÐoÉyËõ èÁ‰ŠKÀrsyܬ%QÃÿý¨o1v¸º¼‹y¼6g=»lî°§Q'®Ý¶ϦÙÜnÝ© g?ªa½@ÅAU]Ö詆D5ÝÀZ¼ÇÑíÊö‘ºÄXŸuÜ ·r\¿%.¹ÏôÕ¿â— ,RX¿­…hU¯”c_¢è½M]W•µËK®íojVµ, 2:„U!,°‹?öŽIq/ Cõ–—¾œ¬MfDH†l±°™GÆòUï,ŠI¯  U†›ÜŸ§I9M+S 2´2´3c©š¤l”< Ìfq«¿ƒqž9õÙç¯zMòÏ£åüo飤ñ·›÷°:^ŸÈ¦/q©ånh¸ŠsY\¨øíÌï,æsYø$å+Ó×"ü–¡­¤N¡}iÔÉqœ‹µ|3êÓ¹ðÿ‹ûÞ“:Iï¼­ÎùSWÉ^@ç{íŸ0ó[œOGÈtcs]–“ñÎäŸ=QÒÂcœÝ)è·_¯xAÑÉ©¨è·íoÔ=g~t-ÉK|+$1„É Q‚&§¾°ÿhþkc¬Ðwûï+¹Ò—D¿z¢±i£ö „›Ì}Ó1Jü’ýƒ ÅŠ!Ðv–)HÝ·š$“ ¾"4¬²ND¥ŒGxyW’ÙSD8 =ùÚ¹I&µ›ñdA“®NÑE4iJñ @c)1ÄR&PÑ*ÄÖ„¯]ôÞ]Óõ´T^­|ÝãßæyÁ~ ôòÇ$‡Œ³|£Ïršç/Ÿ|GáôÜÛÍÕî:6'm ^Ã[gö›}<òm©‰GÓØÁs4F½Wˆ¸ž³Šõã&ûà—Ÿé}TyW¥ÓÍÉ*èk9¿é¿Ó¯“w¹Ý•˜7:âÈbè¯×¸u ½6j8W.ÞŽðKÒ/ˆü‰Ôx'Έ¨:u)æ ø7Àj¦]&³SwJz¢ù…[½;-åçÜûò\á¹³iËͺ¡A[Zv%ÿiè¯Ó¿'ä¼O:çÔ—Ïs§ÏgœozKîzkPÇÉíæ-ÕôV‡#\ÙZZ-X¥³PqÒ°¯9ºµÌÔ´í7_º{bk9pÿ‰Ã‚ˆÒ>Jâ6 Yl¢œf•a@¡o ’Ý1±µm;UР—'³“QÑ4Ç:NLàä阑ï–Eš8”Ë<-•1•æÈSé´‰›Vªø¿$›Ç>ó¿€¹†¿è_Qóã,¯(«)äÃ{Jx“·_Èxè™Â¹ª¯Ó¥}£%€N3—«,X²!Êñ÷[ܧéB¬ûIhkV¤¬EEkˆ§GžÔÊ·ÏäÀDÜÂÄÓzXËÉúvužOSiþ­ê¿6.æž–úŒ™˜jol/‚ªæ HÌåõØTX澜‹OD¥AP²ò,*Â@Rfà$¨Â$Ý 1¤M´-Vꦯoú¯ÿAÖ0A¨ÚKfU™—ÞT1­»W’Äï&º]yLîNÜùÞxã¯Vî¦of\yÏít2‚ó+„ ¿X-kº×LùŠ7M;´…ʺ¬[=BŠ<ÒyC¬ñ^C çsüÏ”:§3¬j™{ñ™êêuoéágè±°´demeè›BÙŒ/£p¤ûuM•Š š}ZÕa¿¸–`V÷"Öê}u¸3WÞ쀈x€®"°VisŠ–µæZzaæõ9Ûö¾d»­WÄ<×_¼¥Õ#ƒ ½–÷&^{1ÕsưŠ›MŒÏÕúÆ3áÌUbë £¢5Ü:ÙhÙó`J˜ÙÒC$Xr•˜³²ÁƒAC«<™,ˆ&Àj³D=µ¥ýoN‡2)Ÿ2#RIKDÜËB¡¶xÚœqR-‘DSÈâät»8!%þæB. ó¡ÑS/cEÜ=hSÂùL]1IŒ]™TGZ&TØM!¯ ÎÕU“Ý_Õ+I¯,͈‰tÎclV£$ Rήѭù®ÍšuÅó¼´t]&ËÎ_§ç2ž}ÇæÑ#“ž¾óúëþ–Â]×ðÍŒ¾È%pÙâÑÔ·Q½ çd.«.uÙÚÂ{Ÿ%ðS›ÅÎ/=wŠO@zª1­ùÍO”kä?Ðäà9Mµœw[3ýOtʃ̄5×ÔϼƒJȆvåL³4Qœ‹‰JK0EI†åCJ¬J@ÍõLüIžrØ $[‡ÛI½’Hagv)}¬ñ U$Ý’> ¸¨n7d`Ï\ÙšL¹©m’ƒÊpãNùï4ë2’왢R¶Ê+Q ÊÏÆ` Õkq£–…TUPÃúV!C¥aY ©Ø˜ ¥`ÒÖ(>¥ K™¶ õ‰1Ü?ÖÛ©uÎþ~^OŸÙ{1@}ͤL³Yšt lçô`nÊhKLÑIHÆv¢ k^bÖy?‡·áCwýaR7FÏåyVs¯ž"µ›˜ùº"¾›DG×;e¢34-Ý“¦e˜ŠíC#3LûgʃÓ+6¦‹«ëJ»Óz° HˆX°ã‹ ×Spp0udÊ *xò0°¥Ï– ’&Y¶J–K’5¨nu®ôÐæÌ†ºI¨ÈvˆÎN^…+”ö'GHŠk>JŸú}'Ö––=Ì4TÖÌ-¬U2®¼Óü1ù#ÓÛ^<Û?EÝøá«ß–ñ§N«œEƒÑ沿iÆäõîå¼¶®™zÎûqÞ@í l.Õrõ„ ,zcjøsQûœÊÔT»ZË_%4À)šÞÞK†}ñ¹j² Óô©ð£PÕ†¿ßl'HØ3ú=.‚½ûmzcf¨Þ è‚©ÅôžT³óçùC7õ®2Ëià8úC#9Q°CDh‰ó5 ùqášjå5èöÅ÷—èóÚ×¢ò«…àô9°lóysâÄoœÉÙj¼ó¬:eÒÝ:‹\´;3âÈÎÛÓ-½CtÜ\Ç’9ÎSÈ^^I͉Ëé:\ð£þ’ÁÌw™›æLƒr¾b@®`uÌô.ty´ý #fTÁC™‘™pȹ&DâI¤LèHRWŽ8[8eÿ‘ú¦Ÿºs ¡‘p1XSG†íެÀ€ŠûO¯1®7É9ÆÎ¢'¨O t~Îk‚ìó-MþiÎY‹|4GG¹®«)}Ài):«™ÉΉҺÏ5jµ˜]ÌÈ4ºã$º5z,éüUäOäKÄ·õ]Ô/åïkõÏ¡Ùw\n—wÍ1ÓôœGoÈø—½èø7Jís>PÔæ;í,Ý)¦S©ä]®·4ØMkâÉÚ^]ìå6›wRsø÷qw+`+¾Ô›Ö'™±÷¤Ï¿¢<„× G(µÚGí5“\ó<¡ŸiÏüsrS°¼CŸÔet)GÝäÝ,®£!ºé"ÇgÊøÊ»\ï šPƒu.¯EÜ!Êe|ÐÐþ÷>›Rà]‘¯ 3QŠ ¼¥ÍšÏh#@!;„’ Ž™Œh6»Q"„È8!º¹]3]ÀÓ5}O-t¼]'?<í¹—æpñ¹\ôÿ㞬ÛÓgˆñF‹qùþ;Éž)åQ?%Å«^W›ÉÏê0°oµž¹È}+âíú»Ð꺡ùcºñ…;müŽ+ÃþŠxî× çs<½þ­k'ˆéKÛ;†¯¼}Øåh ª¬ù;£é°ŸCk5íuYR%¼ÜíBÏ•}7ùƒ¢ê<ã¯vèu¼× /5ð^pÌþ·K7šé:ÎÑ7Kãêtjæ7[ÙgX*0ý}6xcç=óÒ×ËϹwÂqËù;ÇÛBXÁLw¨šWi¶nŸ>¯¨j ¢Ï y„¸Ð žyä‚EÜâ™’N7Ç,*¦·íëoáÛé&¯Ümôý5œMs²»3¶¦ú™¡âaA¥äWSÎË*ÓjxA¨jxË»2‘QšL&ÆõcN·<•á/øÃ†òÇâL O ù³™[•W©ßã_S^ó Ýww+œG™í˜ßñZ½"w–èsü––.¯iÏc×S?ªQB:ƒÐ±òöO¨óÇ(ê¾›ý;ítî=~ cIž‘ù Ä<¢\çIÏq½*‹/¡£Äù?¢ÃíZÒí³®‘TÜÎúôRÇ[Ikõ¡ê¯ÌçñüUÏø›—ïqty‡™NЩðë-ž·iÓóû=-75×S£pQ¢ í$Iægh:]zm¼6_០ÿþIcÇ^¢–åüųêóÆ&&Hk?È'âîÇÄ:뼫ÐõmšÜÔÌ{o¸çy.o?''e»_ĽΣ¦P™etñûAu\®ßÔ²²CêcJŸM'"ty2qæ ‹6D-#å´’"Æ’TÚ‚ «[Ø?®½³Ú8Çôç*VNØÔ¾£i=Á¿ƒ‰o…¬cljšrdéøÓcK‹…“<²Küü™2!I®l·†ÌpKù•ëñ}Du^–=WrÞ/Tšžbôá‰åîó‘Yósý‡—|?Ûù'Ç5«P4—X{á|iYÀ¹ùütŽ&‹—5¹)÷È<¯è¿ÒúÀò?nÄVßSÉg3î¿“|]Åù[ƒÕra•G¹Àoîô1éà÷^Žt\üP€Êy·ýëÔŸ…úJþðŠþ97†5üuæ*N÷‘Êò'=¥ä]o*ú™à5{üMõøÞë²6ñ÷-ƒÅåcóÌÛ“]ü[o·†‡BçgÓ1¼5ä¾Ã¾þ5?‘-`!é‡8\eégCa]þIì¯<êó¾Uòw’qvØñ üâ%æY®^Ö8¿gnÙI=Çé® ¿Íj»‰ƒÑ;°3u<ÈñeM06Xa™2æe†H¹ À=æXYŠºmµ2³ð‰c‡²;oIí,ð}O¹'¸´}[+BËÒñ1W/(sN6d:¢’²Ç9FÍå×t[·75}ÿÕ/›€{¾ܺðúkQyÆÒа©°ýŸþÊ·"”ú-œq$Jhr,íÔ åzT£ZW訩+5S³‹Í³‚ýVš|&µ)=`1`’ÔÕ7±¨[Ö¡èÅÜ„7ü{÷¾ƒyN/'ŠÅÒçÙ##éK½ÔsÞaòÒ[jèÖߕ˜É"¹O´î„êg(Ísó8üË熿?‰G/™žv¥èûO[AU–dd_AæGp‰MÀ&TðAKµ£žû–!A´_¨™”šäyšqGÒ5‰ôÈÌn0À‰$eƒ!¤‰ã`|[yµ#®ˆî_áëJªݿݘ™rkZ$:†¢“aY“MÑ[iþ&ÃR•(Àn¾ UGx’Öl;Z r_íûà‘ù{›åy¤_ÚIz±kEjD}…!3ŒE¤EmOœí½ØŽcóȇï?W¼.;[툟i¼Ž´˜øÌÒËz¢Lš;DZ¡ª“«£T*±Äo¨QrÌ~ZÖJÁ¨°)UàE«3i©íj'.•B2ݺ^,ÑGJBÁ mX¼ÞÑY¤Ô±jŽa˜ŠS½[†W‰‰nDCC íÚÒFŒíÜŸè+óûX듵û<¹ G2˜¥’3!+znSr¨$BØæ«úßI¤‰,’•›ü&á,×óÐu I{†-[× ë6fô$}c£òÖ¿\š"sV Bä¸QÄ/ö@ÉZ†òAÀÈX›Ö›Å'è¸×+_Äk|áL@"nr-Q.È";š’Z$XIV©6bë+õýe%¯÷ ¨9.ØôbªóK$‹}#¡˜¨äRJV/úNÂÞö ªÅí0qÛáKÚ±I íPSv ÙwÿØ~×ûu^3¶ç Àr»»ƒóbüÿøéíÊ ^•²Æ£µ~~ÁÐwnY° Kœ·ks ÿ!ÕTØvª‘U–†Å-áøïÒ“•ùB¿õŸƒçpë–ð† ØÖjà€F¥¡Œ²œëƒH°©×Ðç‰Óóß–·¼CÑîoeâ¿Àt=y2 3;9»8$² ÑÁ‰se¹¼:Vñx«6->sLµ®_ø¢àPK/GOÈ=Õ#è\ý¯\{ìUÚ4µ’Y#¶0þ²¡Üj´`8T<ó¬ÊÉ}Ïõ HíÝKü3SÊž,…‚<€°âÉ(1Èû+¯®ì_¼øé§Û}¾ºÆž¹‘ňÈÌÑ·«3#‡]–H h{…lò<ßTŸãŒû,}§…[·%Ü}F ­üœŠffa“µX‚ýͰz/÷.»*°+9L¢|·,¶4˜•©¼™ Q0%æŽå^ßQE[ôÓÙŠCK™r«28Wé¢×ež‡ƒüTxdˆ>7»îÎZU¢-lžEÌ^„*ë8ƽÇKA‘¸ ŠSO,[õh꫎—Óÿ¾ŸÖÁ>ö§’û´¹¼õ5lCæ±&Y°+šÜ©'‡ÚœÖ®ˆ_YPû=]!0Ž‰Ø¡J!d7ÕÎÛfEûÍE÷p¨¸r Ì•S´r¤rS ‘Ñ<]¢ñ¹ ª ¸fÚ ¨ÜÉ5C‚ÀŽWІO1³‘à¯zÄó7†=,ysÊÝš1<•; sº|[ÈøßÉXÞ{μœŒü­Î«5•:ÔYŒŽ’ ;EÞÒýâŸWÎø;Æ}'O®Ÿ¨õ{Är¾ª4p‹ã펷gc£ì>S~1 <ì*âf“O UÎ’r•?QW‘UúËž”% Í™ËÅÒv;¯üW>Ÿ#ǨqÛòzc¼nÆíZ1¯uB*¢Wиo­­T,¯xf4~Ù%ÌiJ?µu ¾ëðúÖ¯™¨`â¿m ? ?9²†¡þ7M ÎÅÌ—N–-2p™C,qoh÷Å}4'×ûefËÒt90;OOлkZÃ}vhõ„Ö»ŸKÀHs0ÑbÃhò±Ÿ3L0ó™±¢‡ y+O¨?-s\g‘¼q…ׇ7ÆÞt?"ç–ØO©6¯7ãNí^÷Šåè÷ÆßmÍó¸=^r¸n#¤æµw@W•×®Æm?!~¯×t`ºj¤Û4ëEÛ—/nVø´©–úÕ:÷ýt\âÔ×tkÒRÙH—†rê¥f¡Ÿ@eõÍ%Ñ5Û·Çf+®½@\“ ]ľzI¢4¦°+ZltÊó·³WQA—(꺯DLk'`õþ%9lý%2±=@q•³CmÈóöÉeËŸ–Pç1—®0½P3€GLp£¨µ‘Å£!œ.µO¨½•£ê9zTÙAr±dh¤hñ&Fñ*€duB’5Qr¥•šìþUºv‰«ec6\ÏöÏ‘!›$+…õKäÇ?ÊŒI¸¤jŽ2©à¹ÔéœïzM¤ùôM×mêî›ú$°óØÒÞíÏÉllpçÆýú.û)ÎgªÎ‹î+Q‘#»ZÞã}>3ªÅcóks›ùîí5Àß“¥ò#DÍ»-ðÖ6Pp˜»ß“e¸òÝ,õÑ<:þfžåfX£Ž_VFv`NÚE,¶IþƒñÖæÆ§:ªif¦Åõ…Hš“j˜îeVX¹jóëÈà*q/›sÐiß6Í…Ilóç+x”þ8ÎÕÞcÊy†ž9>ãŜҮBbÔ‹H×`q´i(Á•™UÕÇÇM¾7x&,!Iîé/+}G‚ZË0|¢+BŽ^ÁbD–¥¥£æJ7b¨vW«¹zíjPk«,ZÔµk[”·$b@ âÙô_훑[‡R¥]8‚KSHf–Ò« ˜™Ë˜§­¡*%«–_¦P²ËÉŸ¹“%K—ëú¥Êçã/Ü.1EÚ6Wôäl´oyJÖÌ Â;1G%$ÍNq?V”¯obÔ÷XuW>Á…±IhJÇw‚jYÉ1áK¥zŸŸhðCy"ªúŸŠ™Ø±d Ä’9'±9NŒ¬/àþ¡"úègɾ.oøüæ<°LÎ8Ü“>yÃ{NVg<-þg©/3~¡þs#ꓤ@ˆñÃ÷7ôZ<Ý3îºãÓ*¤JÛÄí¼t?J½ç%áw»¾ãËXâÚäqs˜Ë]ossÎn2ÐÝs £]–´’X(šÚm+"wÄÉ 4Œ8:.mç­Æ@Íâ€j‰BÃߨ™ÑR¨:Ðñ'›µ@©eâY4Ô-ÀÃF^ÅnÉžÍ)!F›Oëi-|Óœw±ÁIù²³`¡¾êünÇÔÀîgW`ä¡%‰1Ip=°t]"œ|=C'%æîx»¡Ÿ&d-ëcL†-= “!ÄYÀ™TÇWÓw.¿’LÜi'LÉÒ=8ã‰J®b«Ë «qÚ¬Ì[[ IèëÎuìqŸÑÎvŽ~žVV¨uÙá;…]ÆHæ[—E&ÂÕHïݹa_ÂÓ$ ÓûÙ}ðuµ<…’¨yµ™m6â]IŸÇŸ¢ ¸¸×çß—ñ”¨9íZ7œ*Õð$½R~ÌëgÖ>QêðA ·\­uX¨“,ô+R‡Uo¡ ü wjÝi¿ÌD¡é‚•°A¼U y–Ø+,t|hóǤÅîsñF¾-¿»"b—ÌŠè¯c®"L"V ýÒùÍLÅoB´WUËE+6$²€ÌèØò‰ ;6ã¹XØK$€œ“@Xè-ð°f aÏ9?ò'Ç’1\_óãyaü\d ¿Ü'ô]KÓ¼¶çY±­¯­¨°èΖBóš*&šÜÒ³ ËƒÚyèeY@F¤¸áQ¬™Fõ²æQ¢Îäyï ø÷7H°>+¸éY¦‹— ;zîl—úe"­ `”ÿp¿þk°¥sH°É *àñ¯QÇ%³ˆËO?×°Ç'å¦B7âŒð+ý³IaWòQü¥ øÚÓøbEñ_Ð#xey‡¤ÇòW’w:nnÕOuC›”S‚Ê–A’AcHìw,½ùßñ‘´åر4YMõœÔÎÔ´´UœãaG“Ÿ’ÒÄÑÃAŽCå²ðçzü–ÑåtÞ.|ã(nÀYn$¶ÓV“À‚z±*Sð€_Õ=ZP3ABÐt¶ÇÓ¾Æ=*98lSŠ…L1Kî f@ÅVM§s9*/ú™ø3aebkC‰÷‘ãecåæJ]Ff-‡•ZÑïËÄ’d*™Ä £Ü’ŽoLÛyåù½¶ØÖ¶ñìž^‰öq×Ô®’ñƒ/‡f²]]¥>ˆÂýÖ^ØIƒ=Yl>;0çî—ÏGûŒ–ª=’êwyy‹¶<îl-RÄÍaF¬è¡“¯©åñijêÙg²‘oyÓ§ÖL˜yy\þjÙ‰ä¥ý:r²§¥ªIdmÊœ¶j×`ŠEmúFKXÐ^ÿŠƒC\³£ÌÞû‚LÐÄ¥˜­L_éJ’JÅIdÍíièÒcVÙ§ÈšI›•Ý…‘ýÇxÜËéÄî8pKà–YÇÓ´lwÇF·”UJÒLlTz«1IäL¤ò7z¼)»êqu¬9ã)ÑcóXj#Ÿ­l†j1ôÏèÇE\Ìüf ÕjTpô+šÖ«¶Î.›hŸ-úƒ øÁ>WÊ}7;„†–N¾øz /"á÷œêV{8\ž~Ï<â,×\Øl‘W‰¹s)”Y§ÍY¬ðþvßvP›kÁtÆå|}Ô3ÐÙý÷9ÐoƒÛ7C<€w]¯ÉÎ{Ä¡^L,M'DHa´”N…TîKDÑŽÇt‚2µ¤¤´ªelÊq6øV‹9¡E‰Z¼P/eÝ “œ6EèÀf:E^.«¡Ï9Óçɇ*dóC´Ëd2´§rØ3´F‡takkúÎ\ŒHðc,ÐâÆ¸øñz²*ÌŠRrÞÄí¿Ø/ž»?ñ‡ò?é7Íþšß¦Ï #±ëhÊxߥáüOÂøIÍsIù¯y‡šòBÈA-Þ\^CÉíøØãIÑÊzyŽ•ZÒ¿:Θì|kâF=FÑäzΡnv€Ù·¨Ç>OÛѬvîN@Ϲˆç+Õ‘ÆôŠa[vôÝ¡xÄJ! } ÷·m}8}#[Òåï^Óú™¤œ½\íÙiN,‘#zW¡AsòO3¿©_R|¿†·<òŽåqù¾œ¹pZšihsÃæº¾¡%²´5#£ÓgG[{«ì:m<Ú7ßÕcŸËvo?‚ƒ»ÒªÏMÆw–Éæ¾3ÔoŽ}F÷Íò½·!ýŽü/äžò|fÖYœÑz®wÍÜç…¸}—{#ñËmóÛ½n,côº©²:n(„’kÿ$šØKÕó$øÇkOÚn.ö×S amõùÙ¯s>SÚ̓çy{¢æÕÁåùÍtÛ¶ÃÐó&šm;£hkŒ‘DpÕðå®CÏ É,®»•Ë¢#(¤Æþ¥wŽ«õ/³°5=_RÌ×> ëº¾dº¦½•!ÊдyâldÅÃÒž l6‚K•.6NFfA‘«ìš1$ÚßÈ?™y_.zÜëºÏL£ê¼Uá_ò¼Ï‡|2–ñ£/g–ç|UãrÝ€)~]VQ»Ô¼Ó§Ci:Ý/ÛÙ^‚üº¦af¿r£©¶~¦VkŒ¢¡Ã‡ý®ϰšº”Ë Ÿöë ª¨Ý³h¹4*6FKÐæ#bîÓu~hO¼è——?5ŠÌÐpW‡pâ÷¹ÈR9#­ˆË,ÔÍLT¿¦ªŽÀQ9/öÝ31L,øÚh9öÔ[3w-»‰Eéc5þ“.¬ôíÝ‹²¨©™,Cë¤û CéC¯f›Ë”1#XŒë{XF¤@Ò29àSI´'õ´òk¡Lx}g‘½gõþDAÆ.ÇÄ»{<ªû¼Å›°#Üë:és‰ës`¬üžÃZ» =C©œÞ¦QGuêæú‰¢àkã¶µøy+0™ëÓHG´“íñvi@±cÕLÿOµ<ýw&—<9سåçÃè†(ÈNJ®ôÎfŒ€¢@›XÙ25±r“í*ŰËXÍ“H(#†kK‰r °Èé I®¸ýæö­)a†J(±`âÒ=`´,Ød½þ>ÁæiR”òqÌÊñð¥ÉºÂúˆÁêÖ²ËÞ:Qð÷ÿß(hñ#î|çä<ÿ»§Ïãnƒ‡B€?D•ôóÚiî°lÊèS7G8Âi¯“ý¨DÇÆ¦°IcA¯ä+Òèóˆà¸®tóÓîôšÏ3¥Ñ:,Òh­ÂŽPQýZ™®Ö£½r³©vìàê£Z¾Ð-xßS»gPÖñ»OÉ|ÝFiš0°Á,q(Ž7‘™ž_×ú@2PßÇQÛéž¿‹¢e÷jAƒ‰nÊÙI34“E(D6-¤óû`ž£?ñ÷äÛxƒÔæq§•«µÎ+‰ il¼æô ‡Ì5|¤4·ÜpnÀ³’zsìÙ¾X h‚´‡üfìŒÄÀ–‘”…õSèDs¢É²k˜sTkÏVs¿QaêT²KÕ¤FØÐ1ŸÆ×9Úz7ïüü÷ÜÎËžæüªŸ2l0g_£s¾ât¿µÌìñç”bRc×ÂKw ‰m)ôû§¶\æqtqØ¿KÝG¦¼/)öôµåàv¾(^o–=7m3ršúþ ò*µê²‡Îæ42™ðo”Çä¯daÛ7­ãqø¼FöG›¹›«³þ-~³vôZž}Ý£K÷-¦K‘…¬lþ|pÇŒá¡Sá•ϤçÉ.8°z$ì<Üí' hz¦ã Üxs´æ}hòQdf%±fqÓüüþÝ;‚•þzeµÒX¤2ƒn!£ „gf¶d%^cuRc¶SZ†*ÙaA†Ã¢j²(óëxÖ¸ú+|Äz s£Fú—0—…—¾­‘`´hŽF„Ü Ë©H¥fˆ‘ô†´¡*3pobµ–jŒvy ´ŠIIX£§)R¶–šùÕHå]7U£èa-lKèiÞe†çi²LÀZÚÖYm f¨«hÓ/ÙÊ@èe:Ý¡êêÞ«AÉmÔ®Htß±ƒûy¦=Bhý9¤&cq,LŠw‰‡‹`$ÛïjžIÛ¦ÔQ(pJ[r7KDU—ÁÜ-H_[pNnd›tûËÎÁ°úH§_úü\p7rE/Ú |ª€ÊÈ@7A£^¾/õwåÏO}ÞNº¼ï]¯!ÔðŽr}7>Úa‡u4\Ö£y™›«¯ÕcôR}E6Ñ ˜ËéSSAñè6ªŸç`ö”š¾©ÛÓÏf‘ªæf`BòzSœy#ÉxDa3J+•Ȩ¢‚±vÉéa® /JÖ1÷A™†¿pgu ÏÌ&-2¦Õ%T8Ú¤Ptàþ7È™å[''=î?)&–uXhƒ-¢`+k%…Ì3‘Âç¢ÎVxÕB@ÃÁY]7Ÿbǹ®C6¥ l»ª ±Žg¡{ƒñn])Ÿ¢píÿã…˜þ…uÄ›U‰y€¾á±H*&3x¿ÎWªlò4Å|wàV.c%jÕŽw¸›4E•lüÔ —"#³¹äa«"EXöÓÓQ†)šRfÖPø#ù±ó§“ü¥Ëñ='1éó-½Îw7<‰ó¾RKÖ:Ææn4ކwY¬©:mcißC3OuÌ,P0Ë—S ­fi C«}-ïïG/8âiѬQdO <8È@.ŠÍÀÝF¯ÅÙã÷Æ…4è€Ë¾GTMøè;²¨-î>‹;›÷ñÓ×%4õ}|zo>ˆ¾ª)¿ÍÆf}”Œå/›Ü­ª„Û÷×+öeß=°:=ÇåÞŽ(ÀfãNŒúE[.ÛöJA¦”û–o¬tˆ –ÀS‡ëPU¢µ¨‰jŽC#›šô±ËÒò+Êåâz·ôÐÈtÓ®«ú¾VÔ5KÕ´–].}´ôM%AD‡Ô޲™ Å ¶=Ã+kÖ@,rd1?AÖÆ·ê ˜tÛt¢e,š©/1›ùÐß\Œ2­ SY‰?þ‰5jÍúS©ª`éòM±BöÞwoñmUޞ螎ހ|‚—ï<øñ»×W¯Ñéc„<Õ:«ÍÞÛþŸ·RSÓ¥mo>ƒ¨mme[˜°3®,NG°Ódº`ÚE¡²Ê­ Bâ#lLÞrîij¤ŠŒ“óI} /#¹µß¢ isMW4|fLœøipèD0ƒ%¬¯/›$²U²‚?« 1ð@Õ7Ížï» 0£„£¶W<ƒÇ®>º$œÏìõ«‹ËëëètÌ‘5%¤VÈÕÔMªä·²$¨&?ªÌbY€ÝsG]ìæÖU©gŸ¸~€µÈ[‡ÏO«Í;xÎÛº'Ž9{ª¢8éÝ- jPº®Âîó$@ ™¤M„ð‹=3}¸~)ºîrN«‘¿Åóçè±W®ùAv$Æ×E{C.H¶¸[y„Ôu'D˜×ºÉí] pfH´åŽc˜¥k`­Åní¼°äÐýüô1Ô.å8푨ǹp·« º«_¨ÊC Pä“ùñɶG€qôÿO4—Ê–NΗžkàüÿ8³hv+rìð¥ì+å­}ê„áÖa†xcžÉ¬Y0’—ÝŸNy}G¡Ïó]W?ËÔ·Õô;~µ¼£éjÍãóûú~.Èå¸|yl2åyjm\£wS¿ØD|Ú™k_^@Úš{ ­Ê>Jç¸/Nœÿ¡¾ŒÊ+¬ŸªúÀWanãOË—ùhzzk«^LÞ w¡ÇJ»ÿëÑKÓÞ¹ÅW|»Æ®·ôÁzê×Þ§’y¥¼Y‘™™ÛÎÙ~nìûÞ£Ì w/o‰ßäø”yÌÞ.ŦZ}GaŸÖô õ ©töèsyçäyÙ©À•0i°lS-ñ++‘< Êmb´¥T·$ ïn<ŽâÉÊÈVÄÌÉlh²F)Æ‚¢c´)§'z­HWnÀJèôqã-ðþ‹êGÄy=n¿©3x'§ìôy½k‹áã°òœg]©Ú;œº¯ñÞNºägùæ¶~**‘-Þå©ý“3Ñ–Ï]ãŽ8>LñõûɾPñ}w.ƒ¸x⩌]ÍU îw¬«áwšÑÃÑn‹gŒŽiÆhØÉVBÝ8;L)Äòq;Úèõ½fÞî¡·q:ôuz¿î\s?¡/LÃIj1®¾æ–“z/É·d[L8&´ÄñIô 4á^ƒÅ:¾ð“œ?æn?Ì8ÝGô¼³æ6;¦iËù¤Ü‡áò¾ ¯ÎiøöNmüÙFg£ÐÞ>©CúAϰ¢ú†DPˆ«é,m;5î­Â¤ÚA›“^<ÔIgS ¼ò4ÁÛÜbŽT}à Ã5*Üqf¨Ñ×ÃßÄïuæ¿ÿ“‘òþAÎA¿WõUæ W‚ßO_ÓÇ™PÒçØ]ÃÏm~¡Úág'?8xôÙÚQ§q}Éé·Ðž/•—{7 óR1ÃèÛË~®_G‹ÞÒw[CÇÚý†^YÑÉf57°ùñl!Ù&Ù3sŠgr§<Æ îÑç¿Öñ¾8ôýèëCÇHó¼ëán+Ô6wqå¾SÕ}GSžò¿I©¯‹Ãøâ»Ç5¼-ÌžÝì¹ÿ*¡Í_šGÈ»½wEÓîWa IãG›6¼ÆßÂøÞ ×îø€^š[ç|é·ßô9û^v{¸ò=z62›É,-Êuaøkês·¯=ŸúćB…´óú²³ŸîNDa¬{CÉ`³Šôç.m}‹@‚A?¨ç©:tã ÐÌ‹P,fHßoh¨È±ž4èc}Çr¦à+!zïH\O1áŒÿ!›ËÍo?£èëõ—4<$®e¼±Óz«Úôù_Ùêèô ìfS›Ç§T‚Ênïj»‘tÔÏÇ{#u_GøÑñwyËzšïxÿSOÿËߤú–_~è[§ò'–29†;ß?Ò[±ú¸|iÑtñÌÈ›Ây>£jº ƒ%R©Gß;‡Àx«ð9þo¢À|ž äy/(Íêïdù'ÌÊyñÔÝë÷òÎËDKŽc†cÇYØþ6 ¹áãô<º%¦ämí6EIßâ¹ì¾zž*ÃògÏvÞ+är| ŽÏ7_Ê}&nÖá{ ìŒü´ñÕÙñvÖž.oúc/t:vÊÛ‘™¥ +´¤"bÄ›8paOUBI <Ç%¤ÉYä,8OE‰ˆ•¶ÉÔß\ÃØÙÙ²"Med‹" d`\ÇŠ]‚Ÿ‚ÖAn ©à}xO{õ!åE|û:þ+ôÞoEOKˆC?c¯KÔ§{Íx÷ËmQ5ü€æG?“á²oeç—¥Õ´ö+ÛžHìäçbíý8xS%/Víø‹Ì¹½Ÿ=á_/?‘áJ‡?5ݯ:x[o©g—Ïê5;úBó*`e§žÊïgcõdÑÐØÇ2Íàf,Å®Ýé=<ù Íþ=Æãpé«Â»¹~ÈïózŽ×©îÒÐ×åù> ?±êöa&— “½Þ³9Gl¹Auw[ÙùÕc)•äîC…[Ê¢s|kÝñûœ/z>'wžw[+H[üpÁ…Ìål¹}þ’yÉÚ>1lØ÷˜¢¼±:;ÒSP×wc¤™*ð¶"$Œ’oyÞ©"¬,‹êJÁÖýU½¾` Ž¶ÃªbèúÛ™•“6>L?nñDY!9(ÓœRWl‡’3=Ö¥1œ^iôÙÍO§Cys„òwùïÄÜÇÒd8Pg[ÈžPÞßΧD—^ò˜º9,æ“g+%õ«±˜ÊZͱ˜=‚I^ž¬¼g謎yëªôáå+e5‡êŸ‘à|Iá%7Rïrð¡ü4ž—gå€y¸[¦EÖÞò†¦.? ž0œÉIJᾞ¢aœÜØÅåúVÌ[ÄY™~Gá“o[ÇÔ/S×bS­ÞPémõz³¯­‡ö’io± òò,ï£.ªv tuaÝîú·ÿèí?Vá0¼.§¥.©éyÙÈàSÈ9Äð^J|6W857x‡2sûa=Ö9‘_% ÌìwZ¿WÌû&¿:Väôüsq A¬»"†wY"|Œ}}„©†äzËHï,¹§Y¦ÌÔV¤—+"5˜Ã÷xÂ`«‰"EŠ2SFÂË0fÙ5Ý üÕÂð ïS;Žèy§¹âr^ Û&¯÷X›‡Ïßê¼iÎï÷yMêc»£,ÄûMÀYWkS<”qu˜Ü²tü™éÅ=2ú.ÔgæLàbêt»Øø_éÓ»‘ÊËØå¹W4¹Ž×·ödhm¡ ÓϾM¹÷i…²¶{%ªï©üMÜëùØþž2]èù–ücã ÚèØ/PšíõËrÐ7º¡ÈNÙ$ÞjûZ?ÓTnÓQôñlã#]D\°?xÃÓƒ¼Yè#Θ8cœØÑÍŸ6y÷‡w5.׋ÚÚçø®£ðç ½È;Ybeù=/ЙNmܼ®gËyFên2²ÚMÀƒ>TÅ@ ‡ÔÉûh ôqÕ—b´„ ~DåHÀ°IuŒœYæÒrr0ò%lÜ,œé¦v˜ŸT£ÏîÕF?£Y5±•Kib±3=9ø“£ðÿt;ålN¯gÌæáGáý]Yw©N ­…:àf“¤ðèý44ój5z~U“ –5ª+ó~ß‹ç¼+Ìøë“ÈÅÔäüll®ÿ±Í[iuý;~Vò×F¦¦ð^A"jë“é9¬°i*m¦?£ÃÄç˜Ó±2‹Ÿ›ÑGù¯EËÐrkøÇœô‹ë }ܳËù[€ñ—gÓx§o‡ÇäM‹ž§káÕszX¤Òç1cµåyÎ3pwÃ/iÕÑÑ»ä]½j¼…ÕÛ{ý5Ï^q™WÇiywk3,ómg_²í{êèl²²H_{Pš»YcèYV .iŒ2¾Nf‹ªÉ‘¨¡i¡|g…Nc2Âå–ƒ› "E%H¾|ލ5¹pàÒð!ƒ(õ¾®nSä¼Òr˜ï ”¨!Dr´Š?æ*±àb<òØ…½i!¤É 33[Å„(©JK,8tÔ¡)KßœBŸ•æ/ñÙí.=?¹ªÊ].Vf¸³:ü씺Ž!õhÍ{!m`ØÚ_Óq}.‹k˜mõéxûT–ÖÚ¨@”Ð!Ÿ‹¿P$é•OMûgPŽÐ,éÁ¤Š¡½Kv)BR–!¿CD­¬SV+*Œ‡(Å¡xOÀ}¦ ô ÆøãS¦(2Ö¿Dÿ+Íìt¹ãÁŸ‘ò·:Ч&°;<‹PÂ_Nÿ¹Ûk.¢ Æ:Þf>4}ˤqµÚO`Ã5± ¶*)r¬d'sÚAe­<¨ë 'íí+âé‘I¦ÅŒfU"DVÉ1«5JÔ¬ÊC)o˜õê£ùñ_=¤ç ËøGªéúÔÖØÝ{Á|}ÌÌÆƒ±Ûy†œ’½hªeÑHéðtêvS}mçBï€e¢ÿZ~í½aó¼×sßø—3ÂÊ÷‹N¥.÷¡ÖKÛãä—W¿Õqö 'Ì6ƒ4Q:47_â_ŠETóÑö.oŠ;>P}“Õç:œ ~—É>Bä·Ï¬‡3­Ã±ËfìøûLÌW³ãKÑrýOQ¡©Íꩯ«ÖßëqØÆŽºÍÖyfÖ ø/¥ïw˜ëó_5:þÐN¢Èx¶»NÚ­³œÝœÜ{yÕôžÓÐg>™ŸÞíIZpGŠ®ÇöehíF‡¹Ÿ™çÍ»³ƒ±Íäó‘Yzš<æ ²†à µÜkQ´«Î´"é~Œüb­fÎr…5+¨kgU*u·nö®™…£eé98ñfÇ©båâk2 È™Y2CŽÅ ZG)•Ø))æèuËú÷råêÚŒYq伆LaÀ)B. jÖÖ¢¬ðo®ãx-¾w¸çùþ¯Xú\çc€¶…XË`¹ ª›y5Ì‚±vòÌëNR]gM6´7éEÝ¥*5œÝjbÔŸÑah“- ó¢q®íåå­tR…  ôP±)ÍB ßJVb¯$”#þ.üaåOzEåíå@1ýŸO¯»ÛqÞ?&rŠ¿Ât-•¼<ï¡Aa}Ä‚÷e’©^ðEs’¦ê yo2ÙD`²?íR\ÊZÓ¥©˜º‘A§ ”0a"çÅØ2î?>*lÞyéýi‡AGÛó“¼1qô~âÔ4¬,ÄÍÇQ|h3£G “͉ð ÷ÔNl(Bß×®Ó3&ÊÓ Èš²@²LŒE™˜%Dßçw+cý…ZÙTHÁèþ¥]Õç!n5Ì¢0³'NÇeWßÑ€’lÙLŠ•§L¡³Aô xgõ••¬¯¬OR¢éy}CHž{òö£<¾ž]²ÞåSØïº <|V±‹  “ˆç[6äÑb•hz?œÔ¸»å!hºÊtzÖšg+‘•:íþˆxz?Õh^Y–JɆö„ôcPBÉP¸J2NÄ/É·ÿ"NO+‰þ_}]"ùb[§Ñáû‚7‘zXMö/9ž­ƒGÚVÂfÞ{~„i€Þ‚jÍÄ*½‹þt÷ðã)—Nî…`eHõLR¬öô@àí½¶WüãÜA+~zK}JÉWÖ´˜¶€òi¹¿pöúàïÚ,‡ 1à_ߪ×Èôämï½ä¬<·ÍÌ£dGœÛZ š;¡sçIìÛtÆ’I½†ƒ"ËçÓô©ˆSz˜ð [L¶_š|zM‡uÙè—e‡ŠÔ½[Ì‹0¡À¹‹tL4ub²—'Ôy÷é3Ö?ã¿M^Xñ–°ù­&zþwY2dmeç“núŒ¹Cç?ŒûÊjMl¶i_«Ð@V?FxÀ(íà+S¹õUá€ò8ù‘æ/o#—ç7uÌöïñš.ƒ_Óçé=Üa±£¤« {¢Š-¬½G¬á3™wkSÏ‹ÝSê˜Ðéxx¸òC¨äOX¹íˆÞ2É"¤m²°IJ¹ 6óЛ’°êë<û‘rãWiD¨}eðî®op$6(ž®_ù³~¾|~¹ƒ W/Ç=~ȬÕЋ°âøý3ulPÈ’cþ"ÓRἸv^b·G^šªD<M¾w”ÜkÁÆ›s3v§Ä[èû6ÒYí š”ä ŽÄ¬©qBB§åY{ÞúýgøÎÝ¿¬T{^Ä^BéøÚxŸ­F_;ã΋{[.áõÂQfø9 n0Ãh˜,^ÕQ<ÃÑ g[¬.³ ?ú`õ ¿Œ|w™·éãËJocóECpMxÓ¥†çJýî…îÕ†rÔ'Ðúô.·ÆËP1ŽÕØ5üðÔþ´h¥ h­¦w'oeMö:F3G·‡ë"Öµ.CŽæp×&«2¹óŸ”Ò¹J#XØ-Ù5@U {åÝt :Y$·ùχñÇ u|©Ùf軩GñÀtkK&šÉ Û¦e‘µdXù‘Ñ»…wÕbéa:e:ŸŽâº~§%ÞcHi…~L=iMÄîµó§¶ë:7Yü·˜†.jfõY®wõƒ;µ=ÊÒÙ‚küõÛ²2Ëhºdt®‹&TÊÁB– :‚ŽEíüÍð:õ;NQÜ9*•Áƒ ]Ä¢'¬|5Em e@ð‡O·OO¾pÑ‹ŒÖHÜå±ÞO6§s;S_˜q=ï¥wé$–ÃWWílá[3cT¹@eCýO£š²¾$ξ^sܶž‹¦ÚËÁÏ;Œ¾}(dàÏôêZJcBŠY¥Eý€Z!¥x¼3'Ã¥:ëiô¥Žg;[]kCjE3WEæÙî%ÑØ¢FX™â×TÓªê ¶t—]WÒ‚O³ÜíÌd¹ˆ,dƒNP¢—½ôw:´ÑM•Q] aÌó‡én–5É@0@gÐF®FY›å3cH! :d,ŽЖFh`m} PgȪédºZ8¥,LÈ~òÊÆ ®ß#_\×ùCÂÝ¿‘¼_åOS<¼q™Þ0GÉ rÊóGÓané=%•¨íùòÌ6Ù“wÙqº¨£fšŠ“8c6wÔm.öKÉ»a ±ÿDÈë+„âƒMÎAÛñ 2Y°¿DI?®ŠŸò² Ðá‰-ð®Ïñ±çÏ4ÊÞ"‡9?;pÜ•6 ‰¨õ~ òŽÏ…ò†Ùðcñjœ’K¥‰lÝÀãkw—º.âpÙ”éÝ'CÓ¾½7úýwörñƒ›Ïâè3‹™‹š‚ú’¿‚4?Ž@}·ü™†÷Xò¿¨l¯!xdÝ1½Ê'Ï9Æf`<ÆSxÆLÒåƒ;nœC¢ûø÷5– Ä!Î}]xëÉÞKðo‹ÐÔà©—™Åöy¯5™ÏŠ:]dGÔ%®&Çlxè6Al¹ÅΚ™_ ÑÆ? ûê3»Ý4¼ý;WÁ}55lœ¨ýL¼ˆåí‹1Š1ê@®ŸñaT ¬ÔÛ@°Ïí¥çÞý»ªê}¬Ë©·njx±gÃ"I™¥æA›,R"»Æ±´-ˆÐÜNVñ$!¨Ž©gÊÞßñ)ÈÕe­ Å•¥ sDDz‚^¬$"ŸîÎÝXˆuñÃa2* ´üù¦•ìÙ•Ëö]¦<}O+ãž/šôÝs]ïŽ|’Ž—€öÕø“$€78Íô<ßçG·WOšÉPÙƒ)œòwõgù=¥k—‘Ï­Ï5§ {x»Èàë¶Ê§MŒæªY}1!³=_B½“ƹêºÃQ[9MWéž+][Öÿ–$,²}¼™Xz¶õÝeÐ$Cšõ}"dnH¡JI ô§E‘Šù“dA’Ð<سOM KˆñÅJî‰}E*xO<ž‰^KðNwæÞ#ÅÕ‘­¿ã¯K½³¯§]*„¾yôûáÏ3Ü1 ÀùtýgúýÔC%ºŠ(A•Bl4°3ô4v÷½=7ÏyÏ^?G·Á•|IŠvuwóÖd›É³Ùñ‰·—|<žÁ:û]nnžs×ÒÌh¼°ÉšëÇdü²‰©lx÷KÌ^èöçk™ñÛKø—’ßê7Re±fŽÊä9Ž£¥ÍÍʦƒ»©rÔÛ£ÍYÝÕUùÎPj“kÖ–¯¤ÍÏQž¹oá_P<{â>{þ,kÀËœooËÛÌWúÒÛ=O7Êâhdáèùñ;äôœk¦S'1®ÞÙ>¹‹L:ßn6fI|RtéÃ<™/&JDé"ÌŠ!Ï*b2I¸r6Èç«wDÅÇÊÏ’.êÓ$ž—ž{ΧÑë¼ÕåýÞÓÊÛ×;ÊwÚ݆–‡_Ñ_þ•ñ?A¬^„®ëOEÂèMÊæ ]#”¶k¶úÙ×U‘]ÿñwåõ½gyO+øÿŠê¹𛻜.æSkuìíÿ"ô@±:÷&YBdãm¿Ø‰”²#-¶ÝM7RÏÛxml³#”¿Nž#ôÿüœú2ðõ:½+lù×Ëž'ò榲éì5‡ÉtEgÄ9*`¸…ƾUâ]óùÙ½Ëkki6áɘºé+}¬`Á…¡ägãe¦N½§Á;ê¿•º{àÊ#2ãElä®bdÂ`—îà… ô§V¤ÚARI‘Ý:W|éV,óöÖ¯¦æei}Ñ…98Z£¶P%bây¾k?¡ìKÎhöUæ,NRroA‡Ÿ‡”ËšXzˆUÀ¢¿èû¹ÏåùwÃHð?câ^ýÿOgYñbüù̬ž Òàê7§ÐµÒ=ý2¾©)¶ÖŽCi,ìÞ» ýüÂÿ’´ø.Õ:¼3”Ù]á|QÊxw¦W¯iz¬[ó~[Á#C…cÊlbOQšð 4> «³×oŠùÛúŠÐÏÄ屸Ç+Úmó…Î糆˜º¶â«d!–±šRY’T_Ù²{ÓõKC?ïÒ£-²¤uè÷‰Ðñç£oåáf‹2ùœj5kë£HÎ¥ÞuËȾ&†Ëý£ ˆ“s±aÈè!†(jĪøG# ²ÊògvûÄÓC ÙÙçiÆz ;¤B¯IZ¡&¢Ÿ¹+ )C¶‹“R†•¹+g¼ÏJ-®5È{ŸçU\½k!©â&å%hK²1V~êE¯Yù ö‚­"ö“ RÉÑþÆY¤ÿ‡FhÄŒ_ÜYJ€µ@Ýþܺ7VÆÇVLŒh⼇„Nñ¨ÛRݼ’OGÈ7×2Éo æU|,·ªíݬ¶»OyážkE4¶š6k>íM“Ϊ}<ËäT+uTÒ®a­ž5³c›ë·jMJêçg«2“À>£øîÓ/Çíëïjåâïò–ʮކ¶ÿ!¥eX=soÍK d™•-DÞp›´ØDI»'#v&%ÊuéaÇ|oávCòÔö¨uš]ŽWEÒ“in{Ÿ½ÚÆÁè1"«îV½Mˆ=‚ Õã%}åEd¿1Y¦ÏAÈÏ‘ý8¦|B®ßŒ±x'õ]t=“Wòf¦0ëH°úêí5㌎Ã_?ŸÐß­DÅqø"æœì´Xk1b¨ý+´umcCÓõx0£i1%žhú™X*$ñ¡±Ó!n@”9¬‚ó;ëDíîåÍÐóå’heƈÏ@.4Ìaûv d–ÉGˆ l‹'q®‘¼×꺽@úC×=ã=´z.§¦Œxï´Tý/X#Ê•·¹4²Ø†fÕèM*/§Ší‹§vÔœÝýZ rs—y} ÄÍ—'P휕ÄËt2¶›’}\s0!ÃÅ+7¨®Çƒ¼:‹?¦‡L¾&Ç ÕqÉ„û"XîðJ틞oŸ'´Ÿ2¬%ü7äH,«] r›·Xz'-Ãgj”#7}”Ü®¯ÚCËIì¢X…Ø‹ù§’½F¸õÛ«ç®ÛÍ ùkÔкO%v˜\Ø4w§Kòj+Èfó™ì¸dΩLÔ”ÝØ¡_¿ábº/–Ö)[í_Ò'”ø\>ã:ß S¡à9?(`»ÏùZØ ¦öŽ –Ðßñï~A&i°}p[Eb?ˆm€13‘©ÍÝœ‰zÛÐÙþeþŠ/&x/¥çù/›åý9úcߺnnKäjþ´Ù3>F"c°‡# Ĉ}f™äˆíŽoqj÷¸{3¸rq|8ŒûæãáQ™Yh‡©¢¶@#Í]úaxÓ6ê§Å L±ÎñÙÚ®pÚb%)­¥<¦d«Šå]h…Ĭɠê+6`œõ\”´ÖG`Eý‰‘ÄǺE‰ˆø|=ë{DM&“íjÚ#ó:òGòÏæ%ðyÞ?×ð·¦ntxåѾ/ü{ÄùÌXòu+L6¹Þþ|§wq›â'3:ü*Øé$¶;YëêG="-x^Ÿ—<ÈHfé÷¾YÐSõ˜k´>oJ¤¢ñE­­Æl–¡Jßõ2VbñoÓ<‘`ù™Úßö.÷ß{¾nTŸURI$´¼Ø“ZgÄšv?sðêÈábwŠã‘TFÏÒö_ª‰´¦ÁŇ!±±"GR“³yǦZCìi±<° ‰èŸ²^žQÞqL»}îc[Ë;‚Vñ#xȶžAô¹ œ rÀѹžYæ…(–æQr; ^N`¹&9åõùÅJ¤Sš¡k5Ð;WKIånÜÁë& $u³î*(q4ågòh¦Ò‚]V©Ñ_&ö7™ü|çO©ÍW+µÆë6¯N ËäÍįA‹¥MQU“0¦Œ^ˆ+²±Þ\íÈu++©Ð*kèÓ?/W±©þçS *Ûô"y|)ú7¾QÃÇF{[2Û(äCi¥]ç~¯èŸ°§GÐ#XàrW"T)PI§š¨þú¿=Bú¡ëޤŽêY°±Œˆ¼IëdÇl¤Ø! r/gíÏ[¯.؆ƂT],ì"(Dä´sõèº7†X8TÉ&–PÝÅNìþ,Ó£L´Nž\ÅßX>9ón—2ùŸšñúÌg¼—\K“ÊKE’¬èËóÒK'{ð¼ÁôÑ"ÈOFÖ\™o3ö&vÌQ§ª"ùë›íúÕ0;¾Ó™ÿPø«’Ðâ8Žnù(å—¥ÖÆ\€Ìèóµ±¹¯Í´b&â[ve=-NrÙ‚È#Ô‚[~ž<•ly­ävwú6¥’õµ7êšÙñ’Ý©˜ÛÇÄ›Ã]÷Z`}q1ìž]ÓÐ4>¹ÔFzÎo¹`™&‹cr’•Ui  '‹ yê—CÒeU\¥ËÇFfG†)cÄõ´º: vÞÖ5Dq}UnïÖF«¸,:©ÊdÃaÙaýÇÞ³—­ýxÂUô(Z•ÑüÆY¸`Áµ™ [",â‚(ÅS£Jެšç¢ñVòA¢²O˜C긳3Z0Š"&ÉEQh•"Ff…µ¨ó>å³ýõÞNßñ?“ãÌü÷©Þm NçAâdxÅ¿ çñŽÏ}ãÙþïC{'ÌTí´ñöÆfy¬2¤E±%ê™+ŸûW™T*ü².Í#íÍUU)•}h»5gÿ@ÿ³ÿ•úÃ&­u`z \”ËŽY9Äêƒ)àÆ ´3^†#Á>]:sèù©šÇÊzà+4󠆀;T‘Bü)¢~zrrÞv:uþ^Êé¹ë`ñ= Å;D;aÓ&·r§r\£&ù[€~Š¢#8íœ=¶BLÚ1Q;õµ6ù®†~I5ÌTCû5—Ì:Å­«9¹ÛÅÊ´MbÌè=( –8e„+»þ©J‚Òý"r>ì|ê=0xÃÔ/OÇxç+ÓßmÒoø3±ñÀ39« ¾Ý§{Üô˜}wYÄ3^žþ1|¼wŒ9³«ÝP=3ú«dç±:0ýc.ËÆ^sÄþªü³áù›_›ñ׫ô÷GäÒrlÏ'à}lßP iðžmÂçÚÒÇ×ëô4r…FC+øù~7 l5u3µwó{^³Al›7αœ4¬8“Éhfø¿ÑWoßG½4vï¼ÉÏ GÉŸ¸þ‡¯ñ§·ã?R+µ¯¶eq¹`:ÿ?·Î$~}Œ¼«ŽÚ¾)ËÆo3޹Ï7üNyǼÔ.öo™œõ›áÜÉð*#Ì6{<Ï9ÀvTçü„·™ªZP,Óc©Ì)™»P`¿ÆæN‡3TzŒ åjûŸµ#î8â-›“C—)e˜ãL¹`õE#€&¦+ðÆBvû¸%}“õ;[úm—bé9z~vFªO^(fçÍ,˜î¦s_hÄËLÊ!Þ ×CŸH=ǘ}^óžà7‘ÑÒí‰ãÒkkââs؈mùG\:Ú¹€<¦ƒ]†ã‰QqÅžŸeC±³¬¢e±nÛø©[Ç õÜñ>³¸ÿ!?éŸÂ}&_Mã•2z—„¹wòêôpüR§h2uÓ×é#©QŒíxÑ®²¯¸M™ª°à‡‘ž“„õCãÏVG‡¿ÌzN%¸ÿ]ãž$œ÷ŒRãµÅ°†g<ÞBznéó})N¯)U¹í@OpiRaÔt, ܉´Ì\}%sdÅŸH\bØÚ†8ΗT:’œÿI°CŽº{ú‹‘$þ£©Dè_ºû§IÕõíSWÐ4/ðÜ]gPÍË“ Ä'1 çõ}v[–ÓæÚY³³¶·©Ÿ¬žï‘4g*¹z¡Ì¾V^kZ¡Ò̉!w¦¯15ÛßÃÞ‰¼‚¶gKé÷µõ{áß+lò›¸¿Óõ®un¯áÓ´^ï™sýBøPàº=¤ñym¿ë©·¥]DEM•]ò/«Ÿ ðþ/ô‘âmŒxçs`þµýZr€òO˜/¥×ñXþôJnW–y…Õ±ò¼sµ¥Ö礖þŠztî÷¼’:/ªô› ië½ïÜ]ÃÚÚOofI§>&ÄŽ¸ñq¢Ì‘Q6æÈ5+£D IØxÑ´³Òû[AÓ{Î^êhsò5‹•….VL˜Øs$¿s“0¤m,’¾ëpT’Ó»æ·Ö×ý/u¿Æç‰¼ãhtž–î;4ÝZþhG‘òo§Ì¯Rþ]éûºZòùíñÜ—]Õ«˜ã«²íñq– ²‡Ù©UÍÍó¼³îb§÷P”M_`1DÏÖZ R²1_óžÍÐô]©´[B–‘Ë è$)ëS„ð—ªöó½=yCÏÚ5wÂâ[î|ãÙñÇ“w¸~óÒç8nÿ#_ƒOš{SsžÞÚäçK£^ÍhÏ/Öj‹uopÑ'I‰•¬9jfºMþuT+›úôI—ÿAÝ×ÕÅP(`XŽêèhƒ9X/ú‰â*"Ñ-&<.—‚ØJ›b2É«G<‹CîRU¶VÆ6h­<eiš~­¨ëÉ $ùÆáe@®ÍÊð ãäÜ .'pÁÛt—'rb˜‘4²•côì j¹Ü*=¿ˆ_â·7É<Ï+æ/%²Ñsµ6ö[§3Žê5½ÔH©B°á‡M5÷Þõ-ÓÞ`l T+¨½×ëÿƾñ÷‹)Ìäò|Èò–W3ú;’ÁVŠb ŸÑ LÙq¢UX0HS©yŠk,Ôf¥ßI~uãý*ø›šëzžoßC¥ì: ®7u%&ç(žÜÓ_52Üh]9’·&¢ò˜ÿDÝÙï¦/ä+ÒÏŸ»pœO¨OöŽà¬Â¼–'’ù­}ð×:Œ¸S©¾­ÚÑ\©Mœ†Z’ªëެÐß”òYåÌܽC¸õ<¬¼µÍÈŠLÁéå}¤çJÛ=8ÕÇ´µíRÁ‰ã§ŒÐAÛéxŸi‰,)êb¦D"|¹ö©y]Q·äipGA¿5v„À¦†`¬<ós#y0V3HEšafé_#)úýDMïÐÅÞ•iLÈ!³N†*±Éy'ŒÝç³³ÇÖä}°…‹Ÿ9šÂ1D…*/"8j­øÌ+\¿é,ýd/Ââûèÿ’Ÿ‘{ŽÿrØ»û9Ü—ä£m£ÎêmãWg“{M|¾©L<ñlf¡s‰¼ŒíuŒ§ÔÓné¬c™†¹@çû£–}1eõý&zÿ˜cU\ž£{ ‹–UÆk¬í`¿÷ Wˆ·Ó'ê¥ ú]‹2©'k}0ÍÖ´ÄÔŽ¬˜£*WŠ+”¼{ÏhóÉ“8_×ób·÷"/¶-¢e»YÒ“í „\`B´™ØýUîš$‘¸`”çm˜„ÉfJœBã«#\G:•!FV—\ÿaP1@X„íÑݬÙB[8V«·Z6ÿñå,}Vø3KIjÑ@Ëù‘p25CU xH‹QQ[#u¾0ZÞ¥µ€žõ-Ù©PɘPØ®Ë7ùR—™ Áuólm“OKèøé:^&¸¬Q±I!T3KrÕmdóÍØ¾‘zÎdšö³—«dndÌó5¶÷]êSRvÆ­¶€P(´ÉCLüÏ\šÁ! Ñ"Ay‚.°îk͉ô\Ä |–š5U¥n: hz¬Î²G¥o šl†5ØBÊ÷·Ò6CtíqZÐ3J„PLö‘gŽ”s8®¡³Vfú ¬'®‹>+0J¶è¿%Àªªš¶H¢5³&PëÍ30²krÀ[@ìi 5ŸÔÐìc2ÈÎÁ>Ù¥új¾zŒ€…¥[ ùn{}£7èQ2Ö±*Ù 1#pÚ~,s¶ÇkÍÝV¾#>Ô¢::íçrîPI&Íø$|ƒ}#hXTè¸ì5âð¸ÿE-H°† |ÙµTŠQa48\©‘vmb(Ý‹ò(ïô—Œõ¡ºÍ ô9VXÄ0ÿ-ØØ}ëVµZQ?ëêÚÖ$`>6¾Æ,ÓžÕ@ ŽV :*Xê¡Ù– eŠ:Љ²ßâjÄ&Qus@ÌZ¶cN©)„@m•”Á34=æ(D¤½*Ô…¶%»{Ú½ÏIaUÔ¯7-è@Ä[D’)6TU/€|~G?¹ÿөã%b±$­@WÍ-UóâëýZË¥"Fµt†zŠk[Ðð#Ø pK¯’ÿ#ž´šCý ¦Z ç(Úü[.%•Y›ùÆÇcÄÃ+7Z¶ .›%¿êý%ŠØdš- œËЬAáM>Çñ~¡ñgz‡†w{q3{÷ò™ÍÁÔÞ‚i ñç¨ÙM?Lˆçƒ¡ Û²L#jY”Þ­BNâZè% ³He ,ÛïLÕˆFF½Ia±—¥†½OFkC ºpØŠ9mÓ‹‘‹”§Ð•$D‘ROI„”C€ÈJ“Oí`¹,#޶åi™xkèÏŠñÉ.=¤r«Bì\)†@ j;…y8avñüDúéé=<ët¾&è¹üxçú/-y¹Ñæ:_k×K"Ø™¸ÝGQëúܬR¡.4Ä=´æÀ ’™&Tµ/äÿÖoU©ÑßÄÞœ|[ÚssT¼þÛÚ}~€t±ë®Žn&œˆ©^Š|{} {l%žc™¹LÈÝ|w(sÑ.Ç]ç6|I“|§Xò>Ò@]`cæ²Ï&8ò¬7¦Ö“ËÊq§b¡\;ÍZqèTf“_׈=+ú‹ðæP¿Ñ[~&¾öK]DÖuZ)wÈÂ7ê4'Îå Z¯ƒvÙu³Pfôpt›ei˜~³di:­‘›‡£èºŽ½™‹ëÙÈÿ7_zÞ°?•=9èsÇZ 6ˆ1˜;¥9Ç¡!D¶!òYòiô»umý¡Y:ÛêW)e`ïV žü-꣼êó÷ü³èGŒÂÆÔ¾~îÆ’}­ˆ9|ìëhBÀt}vIJîhýTˆs º÷ÓdÅmö›û.·ÿWœÊl‹|1—¼D𙻆mèÑä1êÎüp۲ήbî¬dæ‚ʧ(æ¨ïL$MÌVjoGk«âýŒ°Á“Ék/MÚ[à¥UmªüøU•&µ"ŸN6s/Ñ›§«eOoòsÆ›õ;¿ôÝo×Ãì¦Z~ˆRlìmS\¤’Ɇ‹&ØãÏ,M±F=ŠDaÉŽÅ“–í6–Ö³$2z ˆN¢\Mé6›b§’8<×=^?ô[åžÔޝ1Äô¹¾Nñ_õÅã½—¶‰·7uvyÑs¸ìÙm¨é&’¤ ›iÁYgto,êEÜN;ÛÀ¸þ5oGˆòÓ}ß!ä>{A¤zŽS;œÅèCÏ?KDÎuöBì(ùª):W:ö«÷e¦>ö Ðÿ)é›Ô7&Ö|yÖxãw£ì²75\G£èÝÙ&ž6¯L÷#ÆY#&†[ˆ½«—XbœiÕÁšæfŒ$òïñÅê‹ÉÞEéü¹åÎC©éz·§ÔõZús§ÑôP¢êii<År™Q¶èEkžÑó‹)Õ„J´D°»·Jý8úÛ©èyÝÛ'zLìŒ3¦®$ú„òã`¦ƒ~!™’fX¤ÕbÈ•"1ÁÌ ØjnæìœC# Q†icdÿ…–L¡Dy 1À¥D  `Ämu¡FÅ/r>AÓá:µÏo+]E؈€¬+÷g•"´6·ê­h°³Ü)ªÃKJ«ØK¤lÒJ–,‹CÕÇ©4°ÚM//로<×B¯lÁ9TYÎ*ÄÑ^WEëL–•¦˜—•ÆÁí¢jO;$ûö|‰ŸŸÝð8”ÉŽo¼·©±CsyO4=;[X˜çÍèô—·GŒ¸c©µ·•äöƵÜk7]}¨+$×ç¦È™Ð6Ì¢6êÏÁr¿ÖÛDÿ¾÷û M®‘â°3;ƒþÀS¢£H/УRÉ‚,XqgËÆŠCë4i¹;Uî£Cñòíã¥óhØùSêr実Ÿ&Í,ÊŽf† ÆÀ•Ý1ŽlUjicÔß“:¾±}þ׳êú-lû‡@M‹¢I%˜kœÉ«YñT…oÂhaôÛ}7&'QÅÅ,Ša1{õ§^=lþ¡tæè•÷¡Å:±öfÆ^b?ˆDÐ+nØšëTš±úÖéæY´‚Õ„(!œC«çÉ`ËÙƒ]2ÌWQ²TEQ †O >qôÈz¥+•;Õ:eÐJæÐ²/®B&t>]‹WóŽ×ͰÝv†ËBqÄêsŸ^ºBNl¡ª4صX³S7Ï–Y$åOîh–bÊLr>IÁ¯l«ÿÁ1ÔÄÑ`ÄؘÂF´H‡¦ˆ¦¼ó~hQ;GF>ôíÝúƒþ4}fz¿òw©ÃÝRœó¯u‰ø×™Ðì„Uw3\ä:2úC!f_ÁÒ‚܆ò#ÅYã©B:IrÖÕÖs¯_§ޏY\Ý_ÎÑ­àÕ¹‡¾ŒÊv›z ÞÒÈ>zT»"8@†œºE–¶ÞªJ³Jí·Ò‡®­@F¦Ì„Ž úWÀq…ðöX^‡Xúvhšm爥¦¥Pq¨û¬ÄŸ«BŒˆç0Ì³î.!@)TíúY4†—K*%‡‚²¿×î:À c†ôR-Æ3¶”]¸¢Æ·Ï7àxÊÜÉLÄçîžTŠ( ¢V`Á ¬Œò•âÜ ,}Äzê‹ø*ôƒÐzôÃü€ò9^ICÅ ö<—¤_Õóäqj»;¾n¦ŽGeЇk@CXœ²›o3‘ý\î_tmûæuYçåÿágÇþôÅü•qžVõ)ÆykÔרoI¾QÁêƒ½Äø'›]>¦ªXï<\ŸïËr tëùoÌ`A.³EUuׯÄër”ikŸ&&œœð€<ëÿ'eùCÌyÙ^#SÓî‡7ä Ìžy j÷ä§^§Y“½šŠFèNBûwÔÆDëŠýOŠ¡xÕßwJO¬ã›¦qÖÒ×kK¢mªë#lVwxZz[‚+„­ª   êT%*=%¦.IðÛ/(çÅ81¥LugŽ/QİÍBJ$Ù¼H­ !;€›¶«‹vî±›¨¾©§öF)‘¾Ù”#²E +ÀÒ$»WWvR«lÄ|š¼ü&ùIŸãÛ›íüqçïL~BÕí<¯ÇÛoýAäî3Ç£â0Þæ¼‰ŸµÈëuݯ{ŸÆìŸC i¢ ]£t7O M\ÌWïM2 @ô+é'·ÿã[êÕ~«–ÊÙkÖ<»,W%m2²øã†ñÐ5q6•uʺÇ™Û"Ú™Z‡Ïü¬íªS+OPLr•˜ZZk¸äçÔáÑXé ^!l>‚‰ T˜w&j3õªl MW’SGU‚ôPþVâ^ÿãßÝ­Ÿõ­‚~KÕ$꟰AeâfìgB¬À–m˶xïI”™°=æâý×™?nëÙ8ª0eXfÔ!;¤Žò1ciý¤¸ÑeAå¤ôÔrM\j‰®–Ðu kRÊbjZ~™…Ax°r%,Ø¢(¿æ¤;@ŒÈ,Iäš<¨ø;ø£"^Ÿ<+Ý÷=ǹŸ0‡Ô>ß!•ÉoöÞ+ÄÊËåÊJ^Io½_ÈÏù\|Ý9¿&kŽ~Ù;éž{NÊTY g†óýÿ¾;ð—«OæÆNŒó]Þô)»Òfu€L åƒKÌüm»(4™î‡1 V“èè‰vyýÇdÓX™Ë*™écp¥ôç§´:RúV+cúéô3TÛ©çí3´%e@^…¶}oZ†°¾f¢«#”Õýÿøùóž7ã¿_7uè?Ž—a¡àÿQï÷ÚèPÑkŸÉÀë;µ³júmë3‘€ˆ‹"?ônýPë:îRÔ0ê{ûWÇÌÄÒ1–ß'Z9zjçÎõQåîûf'H׆¼öJn»k…ÕíÔx2Ô.zålÁSËÀ~zPöE(}8i°ÊÙ¶º®§.F‡¡£*´‚-6B6Ud1å}»:JŠHMˆ¾ V›pecËÍ»Vldî-\JÅ¥jrcF¡!6LÁ$B®XºFf4ÌaðÛDÞ‘½ xoˆþ{7|b¯oÂx'Åêê¿Ða`ô4Å–—Øåp|Þ'ÆâÆŸG’¯;ÓvÍjj—ŸÓ{f^“aðÛGIÛü­úô+ÅøƒÓÇ–ùΟ˜þ@<Àž' ‰dûn–ø=‡‰¼'ùº n¿mîÓŠäTçð{öúV˜ ð¯ÕmqõÈG ÊÛÈfÿ;.ú|îýfz—踃íWÊõõÉ)Òtù{—žIïezCðQ9ôSL…[lcù(]ášeD Ý 4!w¿ìJKøÚñLîz£ñÿCÒç“sÄø›”òCïõ)çásLöËŸŒç£LzdaËt]AÏ/‘Ÿ›£¤QkX²?Aª?p“ôÿBûPäâhø9Õ–S“ñâÁ¼»‚^f—9-lþfë$Ó» RÎ×òõÒãáÏ :|‹$¦$Ê’»”u1O"˜Ô(ÙLZØÕ›ÿò½ñ6O7ë³ÃÛ9YåPè¼le‰³›—½ÇÆqž3ÄͲY™º¥¸ÅBÂPKeîÖf–OF¡BämÄñš>ýëéhø—oGÁþdoK´72ÿ`}·|=æ:risäÞËkõèCJÕl»`›FÎêi%œ‚Èì}Ò›ßüÅ0yêy{ÑÞq^‡c–óºzàCbÉ»u2OáF3`aA‚è/fj«mZ·šÔH =¬?ÿÞ™ýzŒò™xVÞTÊó<ïa=ÙyS#‚Ë麆·Š‰bÝÛIˆÆHBšUM6FîfdÿS©ÎÐõ"bE•“XîŽÆ¹tC•ȼ|œ‡ý¢ÿÚÓFÅè¶ZÎÅEmvtÖº!~ͰäsüÞ“+–µ ó ûPŸ·²“ÑņLLíI1ä_B|qŠÊ¸±K³#JØì²®Õ´afÉ—6X;r?ºt©22¤|GOÓ'Ô x31²äÔdy2¾ÖPAŽ8œÇfÝ[i@|·ê#Êžu×·Eä~´º´IÉ_ŸÎÍçT Ì´fäæ*ŠT¾aZrѤ²ÇÖ»%LvFÑiaß1ßv<7G‰Øñv÷-Ösšêó6BæFöÊ£kë`ôVU¥^£ û(u˜]»°;Æ… •#0Cò;0bŒ’&jË´¨™fÇŠLÊ“¹lCÍ׊{~‘ÖäùAb+rV}Ëâh ‰ažÄ…ƒb $V+4гJÒ÷,‹àiÚbH(-¥pRßã'bcâÅ*ín›bÇt†âXÐ0ZØ óÒŸ#SÎÊÊ9ÙsM•»x–Fw5‚ ÌdµùP†Å­€l]W•½_õÉW„üÄù@bÒóg¦Ý-­·­w[šOGÊ|?dÆs=²x¨çb¥¼Ò<Õ6ºuW¿èÕ2Ú”’RhzšÑÇe.ƒms°³Wi„ %BÅ“!Ä¡GK–¶¼uȱ«³t÷o[ª¹ tœg/TZYþÀmVÔ“\6¹!'ÜÍ@I ÆI“,`Xp£(ÑÄÊ‘S½)þ=¿³wYläŒáž ª²Zº¹ìèhm³ ]q¨ÙÃó3Ê/:$sE<øY4´TÍËA3Ôbh‡EyF EÓžIe‹aQŽó¶ù€a{ÁrXy }.ºucŽùj§S‘_ ÿþˆ£Sur´Ww$W;ÌÐÚ? ÚSM°Œu7Ö1p•Îþ·Úfñjˆ"¯é/¸i˜ÅnÅŸ [±å= ÚFÀ–ú Š cñJö,Xar‚3l.° .þ”–„ð0ž-‰+X(Hcís‚Ź+ŸF,ØÃ@*ô>‰RÞGñüëPgª¡§ê8)•wäTñmh½sݵHòê±M˜£Aˆƒ‹Q‚ÿà^ŠWÑm˜(„[Y4Ø á@æëŸêüßÿµÔÖ{ucQ±•ãÇ·ÝcÊ$ì:Z­fjüš§õîJàl‡ƒ„i¿µPØ—²§¡áÛY¯¬ÇÍ*¥Vа 1;ÿèr øWûØø‘Y ¦òW ïÙ¡#Ì™ˆ†‹SÉ JE¡6J“­œW™È°×jç³ éÓ=ú.œÅ‡ú ¹æ¶Q-ù f,¥FT¦ÇQ%™zù¿™éв ®˜°’\ÿ/Ïsf„a¡ªcPj V™b°KØölKÜ5úÍ.¤û¨)jܸ– írº®h|bÈëxÞ“bÉÁIY@a~ fÇ?¸bÏ=òsÞÖׯÃÉö¿Bb¢†vJ˜—+7Õ{A”TÏJPV®iö&‰¢€d·5Ÿ£Z¦¥\‹šðÏð-ë³É|¹:Ö0ù¥´õ,÷'Úuù®o-lÖ€—Ì“„^¬ |ä&½D-"6b¶d7tsIŒÆÏ™×¼[ßøÏÔ[Í©ÌñžvôÑÕîóˆïpx=å”âo·— 3·©aïøƒÈçîƒ IÌß¹´‡aš®{Œ½Í¬ñÜÑPw§wjÚV¡p(â6f›ï'YmņHÝý5¡¼>Õдzqö§o躖Ÿ÷ó‰r\ú’ñRâc v¦d‘Ôc{DÿEñ—‘6%.«GŸÖ㺠[®êy<™ãgþ¥ÛÄÕw*¨?zkã†ÊëåŠv1^ªªYB~{~µ¸ïx³Ô‡–xN:ïëøÓßK1ZëèNîŠ=W?®CÛý„¿«ì‘ÛC/Wçae¤¬ÓrAi?§:¬…2ô¹s’o:))=7"-Ò›ö°*(ã{5¢u}AÁ&<]N aŠ8ŠcäCf1£M Âìdg 0:¢…t ÐoÓjçŽ=Hx·°Ï™£˜>AÅ#ã ÙËèµçyrե̙.Ö>ŽºÅ+i6¢ÿkNЫÈÔ=»lä4Ö×#·ŒM Ö@á›TY›Ð´™wmk³%×q}íìq¶\‚Ã.Pc¿Hj3ÏôtÙCa|: I6`vP†8CbHÇFU»§”•µ˜ŠV5ˆdÙÿ:òñ¯ò1é® ™wW½è.åg·¡„¿‹{MhçZ¶"»4±õ'¬ó×Â}%×ÎYÇ‘÷ j}97U°z6nbhyXXre–‹7Slî~ÖHVWì BÔKUŒ~‘âçj‹©àiø™¹ ,y>†,O+,o½Bö‚åA,E“Õšæ¶ÀÅ펰X³zJšä2àÒ¢¬]»Ž¥­jÛOÕ]ZŒ‚»Ô!ªzk§Vl½¯ôàRG_„³èR¯Ÿ] «ÜÂ^ã:©%÷µ¯+ÓDÔLs`çè¸C†¶½˜m+)£ ³}qúT¶qÜÿíR–Å“4ž3Ȳ%Y“FŒÄýœ®9HêíØ'VH©Ú"-ËEè’Dw?_NÄŸO°èFãÍ3DWÅJ°’iF™%ŠYO5Æ ¡›ú½†Ÿöjßç°½âúquåá¢êM4¢+$Gl èÈC3ž »áhrH£ÈéóÿpûÅDo'mk›#£®IŒ#nYPžvƒàóÀ=W—òü¢½â~É¿ú]Œ}ÿV¸ýÏ^îA6³04ó3ÇŒ;/K8úy6Ÿj–¢´r†ÎÓSGD®{UÃßÉç®ö¹ÝêyÛ0zŒ·´ø‹ˆ0¯mK­`s¬/P^“øEX5$ O&µÌ~¶|}à¿+yg¯ó¿…;Jêù º]'sÊ»È÷yp]Öšlûš¸¯ÿ¦$ÇÞú#z¢93ÎßX>pÃÉÑäuyz1žÒÍØ©¬~mgõ±bQX²µ8à‰V`lÀG´V±)bh+ü‚>³ì½/²BÓ ÇÑðdɇ3œÚÞ!}GîYciÕ[!âf¢¨ª+{H €êÝÝÚ|­•Ü÷äH˃€ò=Fq,”¼|_ÏD¡øïÑiÊõd*éëG?—6¹s•ÐZI”JÉÙb¬VÕ`í\Œ6ak*_†$zKÇ“—!j"6á†ÝV ’vÆ3pšÇh+I·a&Y½H´Rÿ¼ðÑ"™2Ü^|{…î§u¡(°ZTÙªØAE¸þu¦‚ 3ÒWö×5“imàÏ…k å¿Æ6í”ÛH¹æü÷Š·ÔfÀÛˆë¸ÈCªgnõÞüêºÒ¡RôB™ô3›*O[6@.Ñ ÚŠ ŽV¸AŸgèBV«##i’ö‚¦±¤&¬ÀÏ=­Âq­ ŠÂç3ÊJ³¬ë&öI;¸§ð^ñlµ]Î lÓ–³ß¢ÕXuÒ7çСQ-þ¡onx$õËq{}"ÝOAǰè‡Äô(DÎ}Þj–/:YÊÕ`&wñAEQeŒà€  cs4k+reÃïÔmBD—5i_6nÂbاên”'nSéMõ¾C­çÓcóo$³¹ùî up¡Þn‰¢k™ƒ9%*{Å쬻FÈ_îlU%+¤Õ^DBxöO<’"È ÈÒ)d*cp®Y mnRGÅ]`͉‘ ؽ­¡4ò š8²Á/†Óš¨ûƒ¦Ù-†ž— ÎrÌŠ:‚ÈUý"!¥/A|ëk¤»L&bV wSúsÚNöq¨ýYôM‰*¯Èðï'sY4ײË*ª¬M1>É‚‰³8ºLüúj¼É]2Zx¶ëŽ i¦¶jmFy¬âpJî°ÊÞµÿò{Y¢â „uÙЉQGž«#4 _l4UýuQº©þfþŸa„~æº ÉJye÷d…S†«Ó`/¨n¶\ 0)PéQa•5Ⱥ+@éxæp»óeo䯻Z5&%P#UcA¶ÕŠoq»¸!Á*îÝ¡Ûj,– Œ¦F¡±[n—$*w¸ äžcáù…>…þ|í>‘ké º«_¸×oðÒ·µ!à >h.R”ã2…ûƒVƒPˆ—Îä"qjåjg P¢Í­±‘¯!ÖüÆ×¾ª‡^(Af¡LãQ~ ­œº»J¾Cl8à1 Žxšg§§_ö:Oújër/ÇR®:Ü÷7ßPóùY¹ÃgÞ‘² *Àë‹e9‚k½3; ]ñÉnM]˜«¬°^¯Z íkJ†«3y8Ì#Ì4ª,xïí½eÔ2*C¨ŽÃYÞ <+3øð~: Ó7@¸ý—Û‘;ÈÆ| w"¢Æ žÿypI[nk£.g1Ëj´[Ø˜Ì …€ôFs¦‹ƒDN([UP©-²>†r4Y²}¬°¡ìIUÜÞ7Š'epb•Ei®š² ©÷0«ùÑ“R©cÂïÞCX—”!ÂQ´‹ó©Œ êV^¦Íf¬çÄíjçƒK©Œ U¤—úÉSñ¿z.áÜ\ùDM•$¹N}ÔO fkf´ä•PP:»Ie2iªöŠzˆîMþ¶÷]Y)X¥ '¤ÃÒÔUΑ(MÚœ¾•ô•hp6Ä(ã€Ítcˆš‹"ì]'wixÍ‘¥s{ˆM2Ÿ›4­vhGR#L¯cFwúÞ³S¦Üº±ŽÕ\ÐØ¾ÂiQB¡˜H& A©–!¯lõ¨Ýs–ËA•VOJùʸ–p~9„ÂXua¨ámZ‹8$ü˜„‘ÒV)z,ž{U…åʪ«—?ŠÕ0 ¬&š€šr¼úù¯“ÐçTU¹rék~’ÑcŠdÊ1…‰Z,(Ã9¬U‹Ù˜ª…ižü¶RëDYúâ¢Ò«¹»d>ú±aÝ’”ì_éÉš®Ýÿ³VÖ`ò…À 'ª‰4V¯ûXáôÒc%c ¦£LX‘yÜb!$¡lÌÍ@ÅœÙç« š I%Ÿ²49eT $“däªÿ!Ü}L@R‘@’ªç®?ŽOOêøƒÒW›ý[f3]’w·l×%™Æhó¡ÙsÇäéP:+µ[#¨‹õþ „F´EIU†¨Ðëø*¯ü—‰¼»æ2¥ãïöÞDnn›MÏ+Êoô¶L^Æ£Ž6†s ûgÁö¯xøü =ïi;“Öño:^Dç¸ÿ¢éy> ¸>IÐqØ…OPýö–„r)_L ¢ûh¹³µ£¬v'hí³B.ý\”ÎKŒ7ˆñžh|séßã8ÜŒWÅÒ¡®Q£ŸWíHê²²ùÜæ®!u5s%i!ç‰æ½®ÄY}¿Þ¹=ªu“ÝO•“QäK”®ªHd‹{ÙõZÇ‹>OÏ}PìÈûß¹’}GQ\É[ ÓŒ#8+rH6©/¼Q7d¿7/ê<ºÏ¨N»Ìž¶ùÅò4ÙåSâð+=oA­Pꊜϊ¸”Óªp9Ï¿®¯}Ûi°"'̘ÛëY®xäðÖ P0E DR„¥ìA’–¢Ó6‰6©=î_š.?ÿ‡¿Ûÿ¦-(ôomë°ëØ •qÃ:™8á‰hd@ctJÎ t()ò÷wiåv®¯.Ÿ6ù oæbäíÚ³DGù>M×ÇYvb>‰÷¨ šÃ¥êÁŸ®`DT×8¯”bGš,ª÷¨NSÿ±I¦¤'ìÑé`Vƒ^„c°ŒÙ©(f¤PãüÁ†)qûšÄdv¬ÞôFe®jÜÅ=ŒJÔ¶™­~ðcY‚ŽÁ,Àd‡‹Ö…Z’8±‹3K’w“¼š…fÆb$sþⵤÑ"­ä¥5ˆ6jT²§ÚÁDqɬjA~‘œ˜‘" í&Ï<7àøýùóИ܌Ã)öŸöðöøù;9}k³LÒakþ¡œ„¿ëŠSë¨Öš×'ê¹Ç-µ€2šÖ*ÿEGR¹·úm®­þÜÇ ŸWˆÅbô»¡¹ ¨Kè‘it÷N•¹AV§¶{6OAš. ª[ª×Þj‡ê¸kh/Ê+6ªÕ«7üDC j_Ùëu×§Üú5f@,ÛÒª÷}w*uþ·¡ÔoÌ`QÑ/òtj$›™¶„ÿlŠðÜÞ,‘z[HÎ WùxçÇ#šè‡$d¯¦üΊ 3,ERŸÊ“@Á¯“ÓKމHÿbÿ™Ð˜éëý@\j9£˜ý6ª¿+¶ÁJêN0´k@Š~U\*ëžò–û›™Ì_¡b äCù0ãJ’°³d£³F›(ò Ô ¾ôƒ9©×AskghѰ()àí$RÍKúÚûa„Ž`„¢›Zòcqª»”ÿœ£%¡™éÏÒ—¨SÚVÏñ‹:òeÙLÖºRd7烤{Œ¿¸gB+½fôì¥ö Žf4½Oúi3ó0tØ$ÈËË‹5§/+¢ LY‰ @U¯Ÿ‚:.Ò¢ŸU›yr"‘B„‰ýrÓdŒ-þ©J§ÆàH¹oüNçöZþ©úyG¡¢ÈÂÌ'¨‰ffiôóVÀ—RÔ±Š²Kã#%(újH ª»IÏàÑ¡þÿѳð4}:hǯ+?ÞäA&Iœ‚QYåY¨¼Üq˜ bµë5RÒŽ·þcðµ¨A«7䇸BT’¹W5.5í[„—óè³£ñNç§¾$»ª­’ø±-Ì·¢»i[t·Æ+*X©¡e1YU­¬Ò‡äþW¬òYzT´CȪB­¤9H%i)WB®Ë¤¼š—Ù}+EOR(K@”-)i´Š-ÃÑ Át4ÎÏÝɳ–ÞÖ\|zEX¿{Ñ¡Yœý>Ÿ·0ë¼zWFÁA’‰…!ÑœZ>¸éÐäö¤->Nn ÄÔáË„á$D—$8 º—bpU—ŽA5Ó×øËÔ¡ú±©â鸘™ë¨ö¾YŸ+q1œmCN1´[U¶°õ\Ñ®<›YçÝðn.Xîë«Ð ‚Æ›Õà4ó¯RçfU½,t¢ÖKò4oëém›Ô¶-Åh‹¸cl¼ù»øOž£‚¦Ï²º×¶žm¨éÝIFaz³›$µ¾:&“ŠS=¶ÝY‡sà+°&G¹ßñ#}G«Íd>¸×Ò{@o…ûÔ+‡ÑÔÐ×°:þ¦ÿmWvö™e¡ *k4]ËŒH¬(7üqÉgS;-µÓèq¯Û»A‚£rŸI¥Ž\²ÑýÂ$Ô¬†•@;΂õ¶«· fèø®dXuÞà“×C¹¢?RÀ<Ÿ¼PŒÖc[|П`Ÿ¸ ÿðìhØm$$“û.¿FØéJ‹ÚhŽУ·ý%®Ц!¤až°m¦1–Ùëƒí øó(ºj¬ÈÌŠ÷-€cž¤sBs@ÿZð¼ƒé$ Q¿Ê_­ô‘qq=¥ÎÕµ–*`¨ÈµÇb…ºŽ‘w¨±™Ÿ»F)ç@¯Aru¼ú pkx+ÇÍÓ*­êÉab)ý–ÀHêz€›Z‚B­{[XÆÍ +VE‚ãÛ]Ç•Áì -< ĶcZõ¹o…•rVo¨a,¯ÐP ƒ ó.|ëiwÙ¹5k >Ö’2d9ýØBªF¾Žµ¥ 5r˜…$I&ü³ÐÆ^>«•l]ŽÛ¶~D[·#scÑ6l(®9Ç\¸jêé§F!ŽžÌ°2,î¶ÁþçZó. “~Y«ðŸã:âÆ0lê „O4³#i=Ñí²ZªMíQ”5vÔü̸0œ…)š9ꢓDV Â¦hÍuT 3z7!ëÃð¯¯g¶‚஫½ 8@¶»ï“Gæe—Nê1Uu±ÿHz,›ª¯eT«,B§)ò ,<&x…©O]„6µnºîŠã•lK‘Q”ô¸]e¸µqS1b¯~õ½6Äô=2Z8î¼0 9 Wþ•|uá–¨5rTcäæö-…Þ G Ú(Hɾ éO7cBZ ·Ð5Ó-×,ÛGIÊŽãpŠ7¡f×ûË3QIIžÒõc:"=Ú¹)¥ »€'Ÿ¡Fò<Åö™è[;Õ[X+0@¹-çrÁ{a·nVj*,V"„a\Ç÷-@bË F ƒ ÄÀvlьѾ,ÉaÕe(¢£-Œ —)e7­âµAB›©×;qsºÊæ-•aËiH ¥ÛVì&Ò趈Kz7Bè.몞’ Öæâ‰‰dTÓ”*ðÆÅ|Çôè—BÖ-þ ”¢K$îIØJ¯¤ ’ú…e$×GÓ:ê+‹~“ë·`æZæUØ”-Ô 3vë‹K“ ÇÍK2Û+¡q2S‘lÓ¤²g1,ö aýίvPÄNIq²ÚƒΚë~P”ÁWMu¦Ê¤t±PÄŠþëØYÅ‹_5vÇ*ô¿ì(ÌÕâ´^Ãa‰ ÜmЈI¿—A²]P3cVÙ‹0vÌýúÀ,õm_·^VJ?Í0P…Û˜&/ ÒÆ<®•=á mftgôHé-Ø``@Ìi/uà늤‚†8È”­ozÙ„Y~¢iìq'‘_a ðà}èCÕˆ îQ,Û]µ`²2â ‡d+ èZì¯!É$8k Ö<_<_æ¿¿Íu|LW˜Ê¦KD$ª»›h’à~“^åº-äñ¨!Ì2µBÓ…•\úy“3¸Ò!|Öná±§HíÅM?y™4ŽÌæ±ô²ä µ¯eVNÅÖpX¹Õ±®Îi&£¹BèJZDýÖ±¨8ùXt-þ­5”R.Û”âöFºÆÑ%÷C]«\bPi—$’çáy %$´a±¿`TÁ[àQD½2*€¾äuÓ–Ì:Öe-zY¶z­e¿„bJì\K#÷•…jýªŠ¡4æ1Ow´Ÿh5@ü|| þÿ°KÐq¢˜¹wd„Ê„;JE)ãÛgq$€ ŽA²GÝx!U Á‚{¾þ›ª­]ueh¬!÷Z¯TÑœ£tlC¶ˆÐ:ÃF²ïçŠ)ØÖÌvÖGBßÕR‚f´¤CŠˆ„¬Û>”LG½Ù»&'õ&u„שq¬•H¸‡—2jÂÔÿÌ07MrÖ_©¾ûp•˜Ç#=Œb– ÓUÖΰ~v»V;%ßJ’åÄÒD¹åÔúÿØÍUl@†+›DÁ!å+ƒZ=ÂÒ葪ÃÊWMØ!â†Q4Y/"Ê»ÜB€ü]yäÍYç‡N&&~ŸNr²,BÅšË(  È«!yŽK‰ÂÕ`t.Šõ¬HŽì’ñó’°}…. 6«ešžtj±½òVdß/ËbûÓDøØVÎ1VòÅÍ®»Fm½Ü8ך‡ó– ›š8‚Zʤ™g¥Eu¨µáΞšcºÇŽ‘Y ”F[U6¤WÎû¬;²h&§ÜuåJ¹{˜ö£“—©¦ŽUá0ª˜œ)`µkŸýˆô I,-Vd$®’&X9ë2p‘@Žá–VOiuoùWG•æÿk?ÛÇ]aôŸGÇÓ°ñãÕñ°órtù’I`†V‰™wÇꬨÍ*Ø Vw´Yk½}ù=ªvü‹*Vró­³ìZ˜ Y&ˆ•QÇ™â…?è‘´>ÂÀ“[‹TÈÊN9ø« YÃ0eu{*á[ÜEÛ 9äêwxé˜]®ÍÚ‰¦Ï¬¦‰¨;&dÞrãÅycÄYZiB#ˆÂ‡¶–48¸Ïlr¸ÿŠ{7s&¹—s!ý Ñì½$òò‹ŸÑ Årf$ßÓ Ìz¡¡ ŸEì[q~ß{»ò§8Œc¨d}2\nN®ÎïYÉ­Òã‰ÉéoôŽºHT±ŽÍT‡Jfhr,·Íüøÿׯ¼WâÖ6ûþG°ã6vW¿I–-ì‰çô ³©`ýM¤îŒé Î@ùêô56Ã;Éh‰’ܹ?þG]?7Î#ÈôÞPÁCâ™:^?±ÏH:…ùÌUò`“C?,¬Å½˜ËKNg8¶³Cxæ†;Ú¦ÚÆ;åÈr õ¤ôŸr$òDXúo¾F Lµ´ uâ~£õ'·s¢²scÃÌœKH˜42Jב ш˙bkY·,¤tþí?šr¯}à_D^…u:¯É¬lÛG¸¯1|túO4yzzmqüßß_Ýi0ŽVxûÏ…¨Ý¼Š5¹Iîpú>­ÞÀêù.¤IægO’ÕÄÔæçZf‚d¨— uuu2ñÞ%l‰Å%L€B;'A4ÏDžmÿä$æ79¾™½=áø‹­4Ò¬÷»Zxzf]Ö)Jèi–Ççíë0aºmuˆ® â‘ì¥Ïv€ü±å¯"ùÓµê|Ç厩îÏÈÝ>‚®u&žv2-é–«çä¨K©ŽºY‰®®f`“¢k$ üú¥¬fÖuöV•¦,Â])0#¤&i2[//$.Ý­4„Z"–¹«¾~úƒ­éÚ´‘ɬI¨ÎÓ¼Íc6.2²í¸Ñ‹»ÌÞôö›ñиf·×#-«{ü j¶­]G¨H­‰{Gývšü!_ª€j³Y¸lÈJoª¿)šÅ‹2’‚¡ëk`~ÐÄÜtiã±÷üB5áãM‰¨©n5â°R ü&,yŸ¦jK\7ÄUƒÄVe(ŸuÙ þÓEF3k pƒ4ÈÏöY‘^±{±ì±¾Ã:^Œ@Ç[1V>Êb%— ÅoY©«!|wT+ú·•ÿ§ã¥qä“ù'­„[ØÑyZ(:³öš6V°»-A‡ÿMgþ6µm ŒKÅÀCkÔ]ózIþ }Lú›ñ·Žü¸çƼWŠ<‘n7MÂlu ±4,6Ázcç#Ÿ”vÕ\¹ï®çk ‘ŠþUÎ’Ùc£ ´Ê¡)XµeoQ5û ¤ FAÖN¯eÚ†®Ð/PäMޱ33Z^Öý+¿€mÄzâçÀ ±e˜o’Ôò¦Pvfa!Ç•û å{ÚÕˆ¾fðË+žù´–¥¯¸¨ßÒ긚BË¥eǃ3dÇrÉ@1ˆŠ24‘ú~â $0°:=ì(4Ùµ “¨a6rÅ ˜Õr%€+=nÞ±£z¡~UЇm×=Wï£Oþ<^*ñNÂ'šÍŸê Ïqpéy2x¬[üZšw˜>Öæ@èCÿ`§u™Ë0‹kà]š@ø»ÓOâžc/žÁG##[3–ÉOžÂ̆»7U ÔéLìÕ-%¹)"Xǧê±$`!böÏç/SÞôÕÅïv¾]ò6ÍsÙûz™ö(5Hw¡,ÑRïé’¢´ÜH¤³ÍžÌZÿSt•«N;ÿ’þK—“UÑðÿñâN·ÇÙ!è<ù­‘•}M|jCúY;ùõt³•„‘‡—Ò¢›Âí¼îâÌûC#;V›r|Û\4(*°Æ ~˜¾6³J~Pi·Ü±éâ8cƒOÇhÆ…väÌ»ok¦ôÍ{Rn ×]ÿ!ŸÌG¥ã{¹›š©ùWËŽÄôõã.Ÿœ·bµÍÞÒK¦îYy‚Šå¿N ³œÕs/c~ôÖ ùþs  ™ªüzÿþM}Cz÷óÖgœ÷‰¹âT8ì´ñ|UãþWM´øÅŠ=5Ÿ¾àñòg¡êw抺›dæ}ùJ—T¦bä¼×é÷z]Ý^Û±éö»žç§xÛ}OS×îiït»ÚŒ@ú›;å>–®Ë§¥ŠM :õnö,²¼ý3 tÌ`Ùôíò¡¡kÜ·Xƒ‰`k/z{ŒÔÁS1Z1R” ¬î•Úx8IË y3¤l¨%R!€°ZXã<ìB€5¸ÜGKK¸õ ¦’H%’(Éö¬‡"ÿHk žG“ä׃×@ž›?—%|]ãNŒmí÷qeMw¹ît˜çêuL¶õ69 ìô].˜t‘C°Â ÏP*{ÔˆŠÉš¨=Ez×óQbOš·/Œ›Oj2#:»šº;—ÒzçÚyÑä#©?ØíÞPOKèJOUŸ]«Ë¦‰)ì².:XÄ W³ù¦š’&([ÊᘽÏot,ÔZפÝx‹ÏÖBZ¾Í¨Ã˜û)ÐŒýj’ì² æ ÈÅÚ¶aÊKg옛حYu P±YX]¥£a澩>ܧçp"•£CÍX_?µõ»?¿µKMnDÃÓÚ«7ò#Iò*21…C)SdŠ<ôªÎ¬ `Oµ é³py } BÌÉ-p,Á;.os^¶ë!FC1¡›½ß@}Xùÿ%‘7 ÏM¨½)(U&B 2©voÆG>ÚPcÚ¨¸•›Z&ëÄV” ¹j—»6›–Æf~p:XUA†/­kè5¢Šü¾¶ˆJš‚ÍÃx 'ºäü!Ëw—ÈÄÏñ¶ÖÎÆv€:¾Hú:6ù9˜Z[?¤{ÈXxÚ¶¤j§lÃBd¦yµNÈÕúË‚šlA‡+%Ôà*ïÙ G›,¢¾~8®Çÿ³Ã_Áíï­º†¥©Ú);?UÀŽ'4ÒK‘—¦Î»9#wü!“ñ䎭I)-žÌÖÿž€ úZèUˆQ ˆ­oú›t§ ÌÔìÍ ò¶1™†¨} èg¿æ@- %a¤ÇÝBÐ" ]h‘áTM‘`è5B¤U“è †%†¤¯,¶yép4únÏ«æøü1Ÿ_ªÕ;‘”¯ây«hj1eWÏ®äÙC ĉý‘ó–þÑAN¡kdÏDûC§áºÝîSoç‘»Êêiäo(=žgI`tV‹ÛA†žNš\΢ð¸¦#9 mUÐ<Å4Ñ Îs>7gb Dã´³Ìê·Á «=ß* »óT/¯i³þ¬h˜ó48ðÀ³&õ¤ ‰ÙV9J1 #6.JØ(ŒÙPÈO+³-t”g9·ð2Œ—ì´p"±Hd \-Ô̵F5Í#·É’)+/C}"ø–@„Cë^ALa2¶¸— °,QÁ¡{·R6ÁTf0ô,z6WêMVFWCel­‰Z.ÄÖ„³mÕ±Å%¬W¯k1aPe-ï#t-ªé1e¡/d -6ÂÁtÔÑtõ=QÑÔª3‰§;þÁPwmVîäè4v‡hñÛ¸€)¹<~ôøóñûõ+Q„b4’À»Í”FMÈ@+sJ¥x+u|žA¿+[=#‚{ŽÀY™wRäûFÊq‚£M/R”‘KÜW³7Š´"X )ˆÑž‚qßÚµjá/­’êß#uÐŒ²©Z¹W¸á •Z WØ1³é<¦?œ½ ½•n?±™ ª•Súì‚j'ghBÜgRCQ& Õ'É €‹!EÄøDòúj¸Ö¥)IcôÙa°jb]I¯Ö™Y77ÓšJšäkçõ'2qÎ e)°Îà]WW&Íú| êfˆ32COƒfqqBÁöÃužXŸéñÃÏP[ÓFU°FjµkÝfÍ 9I7[$Œ’Z§s5¨å;ÝßóJ6("ŽFcPU€T¥lÅ"!D/žCa:P å[†¥r,³¬¦W7ÉpÚ²Ån gúù™em–X… ýŸôµQñTe¥,÷ƶi›:ºñkÞ†J`¦t´n[°æsÅ}ëh#'‡kFaµìØËõ~»93·ìË&DØÕöMf˜ °[ip+TÊ…B;¨cL³¾Ù"e¦ð þÿƒùýüôGÓnàÒLÓ±ß$ÌIä“!”4Ê û‘]€ð›ˆbnQêC2%ki8Â/w¢âƒ]Oƒb¤a:Ô!XPu¨ÌíbÌÔ4ŠLe|ûdU–EF]­d…`7H*Òµ¯ý¬3˜8làÖìßÖÑÐ8ásMJ¢idç!Í×Ï­„å$b¢ KbÇ訣0d¤šTd ´.R… ¨½Ï¡W%¸[<…¼Þ¡&':Å~g‰¼öÒP$5Ý\ Δ*»k}ì¦Gsnu“ŠŽúºË0´ÔÍ­õd˜ÊÉ ‘Ž0, AK)alEž,è|vOiË…<ódC /¨c„Vz&y@L›x}«jÑPH× æê·/fåÁè.ƒ‚]¸Ì\߬poÎJ‹dØo(”þ¦îÕζ{`‹ß\a-³ÙUÆ_AªÆ….3í`Mh9¢FdЖ%ö?´¡35õ’¹ ¨3œliغbç—Ø Ý‹ fìÍkT&“\±³˜TZâ÷¿ÐX¿Y½Õbç`Õ(ÎþQn) ûcÊCì2/EJ9–×:ád‹X2C/j±H´Ò£_Lç,ôÙÑ“MⵆFFlô„FH§(Ùœ2dî}ÁÇš°C/Ø$ÞãŠ(FfŸü‘§²\ñÂÃhFâT³·Ù´kÀ<ü•±yûËÀa3lj*,ÅWJM2£õãÒ¬,Ê *Âbp+O"ÁîgteÒ°òlèqiê½y¢g!Þ»F”aoî„¥¹ëKÏÒQÒOu«·íÌŸ•¤—/øPw©¬T-çÍ0üÐ0þB‘O¢ãa9iÌÂÂç©EùOs× +¸aßœ{XÙìn’TëRný"=žÏ2µÃXR?26`O¹õU€ŸèÃ2­|¯¡O{ %—Hôø2bÏŠ\¦Iñˆ]ÁÕ$mÞ¤l¤bU€Š X îû“HÔ;GQÃÑ&·Kþ#MWÑÊ»"È$ ”*²‰6W¶¾ã˜Ìذr™9€PDðdlÔ{ZÞÕúÄH€Ïå§Æ—]šÉšƒŒÌÀ)h¸ Šü>q@5b ZÛØr`Ô2{^•›Œ¬É½þøùUÁ×aJÚFxjãóú«dæ¥:ëÌ ¿kEIb£Tö­lÀmb5x½fÒËÿyyØ0ØpX5Îó`–G´Ïüïó›Šá´VgÚ+h­«1þ?ôÙ¢ha0PE†ôšÁÜÝ’IrÚ‡^5wV|ZŽjæ1'”H‹‰ =;Fέ¼_áÏ$ð:\ƒT“z–ªýµ½¦…fþð¥io•mi‘Y‹Sìù(/¼B÷%ˆiµTÕf!û›! üY¿È–üòÂã²÷úšƒ6†¤ËU–IV$¬ËWa‹È´ULV/$t_6/ú¡C­U†ÕLµ=—ã“$kÒ)1O°ƒÿÍ Z³…ÌefocÞüäˆÌ–«Š¢¥ðÿÕX³A%ª*4ÅEb¶<Ñ›ähÑ™Z_}MèyÎå îA: Ï´ª–»²¨Ž?ÌT–K?•[ñóÓvÁL‚žã´‚ç\ÜL—gêÖö2×¥¢· •)ej\´¥O—3ˆû‘zâ´Ú¡ÿªÀ1l9ˆVÖ0Ûª´ ©õä(T•úC1Hx¿ç˜Fòªa°H5,,5F»ûL2\åì[«zŽÕƒöT…-–e†Eî9Žfã¾*íéÔËTÇeUr‹«RÒk<­@)¹o{”犂 úíBI@={ŸZ=£ÕÐó¼|_Á âˆëráe?è‚VâéQ‰®>+÷ý¿ó¬!{î%h»¤Z£­ïZI¤!`)Ž D’)eFKQ”,OÖ"í¥hâ nËÒ·ó{åïF>Žõ=6øW™Ãk¶w·ßé“î÷nbâòY]*\ùXe|h±ôú <ŽÍ(»N¤†CWA¢kâʼn›$áJ?öš²(ÀšR´8€EKîQIª_úþa‹\‚‘ÄÅR†uòÔÊéŽ"Mõ2,X§Ü«÷ºÄ©o?OÊ""$ƒºÅ˜(×ÂÑhZ¤8º®,qd$sÆ®;kFÚC2ÒØ°< ¢x¿Í–‘“——,Xò6<ÓB†FV@ECW$ñ¶øøçÉëÔ§ªÏRž°zEü…êÊ]‘ÎûØÌÆÓ––幊é’Ì<×)̦Oéqí¥uÄMWH‚ºÚŽPUÖmÅ!Q*™ieTO„ý &+ó˜1 fÖ¬0zÈíIÉŸóRºte’Pl©Zîß§%î›7/倩 £LÁ,Å o²—<Ü­ƒ¨jÔœKX [Iæ–B(‚dÇ‹åhRkJi-xŒÍ R”¤DÐKØ%Ÿ²K#î1[Þ£-èäSTøð@±À†P)”(_’>¾ ó}YHÙqêd;ÌO .C™I$©¤6 /ŠAÀ¡Ï_X>9ÊzÕgE&)JËC+íU0C@¢§$0J…Â{1ð¡¿K7š€3F¢Ä-áx*@#ÉÖŒ ŠŒT³j¾¥or}£‘X)MrDLufµˆøÁ'áZ iâ¼ð\¸KP²_°Þµø*]!MHVJŠÂdjÝßïZÂ2Õ­?Ñ8dÁ2¿ÍZÐÀÇG Ì Ô1í[,9j‡ A†Ë€0íÇB@Öa˜ˆ¥¦<šæ¿é]~ ‚PÅÕJÓDê6²›_žAwàÿNº5ÊÈlc³4#8ÄF¥kX½cäš´÷)½mù¤å‹V¶$û—ç,«²Í>@ûGxú¯y ^Ä‹DMjÚb~-J/®ÓȾÿ”ûM]ÛÚƒmûvj´­„+Ì^Ç›ÍÂÔ6°ÉF>û܉<ŸáPB¡f -&¹ÈôjNÝBPM.&5H­þC,/aŠ n@ŒÃlL¦ö3C,±ñŸÑXÿ5ääÇORDŒÈhj(ð<ëùëZé™úŒ“¾›‰‘œ°m9bÄò¬a™TÚ ²Ä|QºæúNXÿ2Ð:ZµhóYˆµoH`÷¬XÅ´@BE"ÿUËrDHèY¬ÍÄ«—:`°ÈÁÙü¶3ë¡cTR¸%R(gJŽ aØùë£-”3g-bª™ÝZbqšºÇˆ´e-=ŒYéðûi[û‹è1gØ–ý`úí2RÚkòUšÖ~p|úܦBáÈd}x‰;kÃŒÊdhE‰\h RTBF??Ò¥S3P@”ïÌY0~ܔȑͅ+½AR¼’%EÝ.ÒhàXÿ Ý¥Ü ßãÙ“`éÚl Ï‘¦6/GaD4]8`ÂÀº£wÑgKY‘ŽÄñ6CYxbù–0ª¸V-õ ±™ŠB7F°1؆×Êr’:ß9 'V¦0"–j ÓEPq±±k±gõ-÷ºÕލ‡gX¡JWØÎ©¾, ÄJ!ÁÜv¢Þí¥iÿ٨宸ˆÏ‹:(¹ÔzŠ@Zr\¤°åeÓ¿àü‘-äüM-b;0{þÄŒ ŸÊë ¦ÒÇã?RÇ™¶\¬¤&³`m1» êu½Å”̓§æe1OZ˰Mj3-Ž×kJÏ71XÈdG°¬!\v(]±¨¼ÖÎÌC;ÇæÜi3>p¡l£9*”·Ò¿¯J²’48ìÛÌ—4P!m{Š# ªò¶ÓüížF˜Å.cÂ9ÿCm‚g®2g×2‹ç[þË.(½R ˆp,íBª {¤g?Ưsö~+÷µøÔȧܥ%cºžcéæUˆj¿”rC2Öp¥ÑhNuq‰¤2uÈgÉ|Œì¿ñ‰ê&BèYC1lU_âïäøá_£yØz~uÏ› ™cЙ£IÓj®Dxåñ#ÈyI»¥g£íq<·1G¿ÑåU5Oû3¦×ªÊSG@þª¦ÈWhÒsܶ˜`äÕZÊÙ*ÉÖºµÎìuüë(‡SÅÎ2_ê©"ÊUˆ% ¼6+µöé}€Øp3%hÝ•[*"-Òü‰¦7·Fªµ(ÓOã lU ê@þ¡õ^¦šn-T‡©+.*ÀXÖ½föúk`µ’^½ï µS±CÚ x¤ƒãbA­bÚ”hÒÙª²Ã \z>ƒâcLóJÌT)RûUhi¿’MŸëÏžýõõRÏÕõl80° ‡ï¤Q ˆ³n´c´¡ (k+ǃc§ËýZæ(>p¬1Ѭð®MZˆ¥ .f _š×¬Œßmé+ªŒ‡+ž‚ “Wî_^ v€‹d,(Q™jVþ!:¿¸Ì˜Ä?uW) @¾t7µ }ñáøi*ålKŸ¼W½’/ŒÈîêÎUbåDv °0²&ˆU€`æ,Õûz~ôÉÊu~žK×íó^yÌlž³Q1Å|ÖÏfV³)SY”¹-"=2%_g."ùz¹ aè”yU~¥l4DȆtŠ-àS¶éÈd*nØÐ>?b=/ŸºuM=àËlÄGGUŒ¬L•¢;Kn"âêì¨q¯!M–µG˜X³*T$kâ"EÖ°n+ÌE¯!]R~," U½˜‹¶GŽu¼¦·üÓ.sW’!"‚"pµÇ3®Rh˜ön~ðÈÅ%\¤:͘ÒW+«ÜLˆf$Eõ]@™xèÝ—^”£lµ\Ïèi%ñŒM¦CHòoþ4,G×O¼…½‡7‚´8ÿ²ÑQA*ÀbëZ)ò¥oŒý–û†½­þîàØ ˆv›*|Xßàÿ_éû^7Ôé…ždÏYCznUñ > µí,Oƒð>|’$ÿÙƒ Õ.=•ÌÒ\*èÛ(±›@ª„&_L2Ó 'ƒEÆ¢ #4X-ÎÎÄ$UEQ;¿m’ªÎ$Ë$«Ut+ø—¬ÉgP£ø ­fß­uêˆhË`¯á´|ñ+ƒ¿]€3’`:}(]ZUm™ Âõ!aÍeŠØ¢¸¨zT…¡iIÎÁriÅF1¬º‹h¶±ÆÙÇA­ÇTIgÊÀºÿ{ ü™ª­KŒnS8쬠ךæ$x¬pÄÆÑñfÍçÇÀ'€:éï§:Ìý×ôûQÍÍ0¶¥¢ØêÈÐÂdÇh gvD?­^c³óé±ø=2yU$V8ÿ0.O×7­Ú8?<ŸAG ³0y1ôWhšÍ¨ˆ°ì£ö5!y!« ´EÕ,„+ÞšPÆçYëÞ÷"Oh(ˆi ‚¤¤‰pÌ.²2eîQ™†…Æ­Y¡C®ÔÒmVÅê(ÉÕª€ QY øþl4Þä$ RC`1J—Zô`#4Õq,îÀ¡BV|•!¾ ÕÄ´½Wµ)&¯ßM˜àHô¦ä#kQ VÒ@5\׃ù¡ÏG]¯§æK§ãÇŽàMC"T¯¦¥P)fÕ=ÆÉ¡Áùè‹Ê”kU]Îi¸SvËY[öå„ÔpªEeÀ¨OUÈl“òˆµJr9˸òG ›»šg(Q•9±êµ`]*®K‘W õ\³KŒIYåÀuÅus™csè ‘j]&s®;3 Ä*öL3Hkübß 6 ûŠn³U C^¥oŸ^w ëÔ¤öu+]?¢ªFvœ”“ Þ´³!;3Ðñ4¼ë‰›Q ;±O‡¥cêšÆ6ÎR,“é¸E;ÍÅ·jŽ~kÁ=?{³¾5_§ßKµ>æÅÆ#WÑpÒh"ÉõæY"ƒù±‰ý7‡õ#ÜK(_ú~êzŠàî+È DÕ!ÓÊJô È_müº\ihEa†"ðGÄÅ%x;¬AOïçE5¦’1E¬SÁ©úœg퓌ΖÊŪÉãëè³"<ƒÃLmVN!C¡V,ÄÏü…c†(·Ôä×½BQüZVõdqìAå_®ÿö¶’E\üà†B ‡Zí­X‹±EÔuü׊ rý¥(غÁb3E­ôB« Ku›h£hÃØú>2R<Ê’=VU‚,› n­¯àÿn¸+Rþ)¾¨÷Ì™éñE"¼O.Ãì q24„ °Íî`9j=±ü¯›˜(}ÒÌj•’¼K§¸ÝþÀTƒ ×YH¸ vYaˆƒ]›~Ó_þÒZº&ÒxC”_°wÖ9ï @½dŸU ÚAÿÛYTHpˆÈeíbYÿ…½+yc´ðß}×x§‹Ëɧ ƒ}nþ‡!«¨ö"+ÂýùúÖÎc, 髱Lò@Êçmæœ\פ¯Rß8NseÔ,p´Ÿš,QAI¥b8€å1-ª³’†£Ì‡q!†ío‡·ô÷ßi*®Ð—` `x$Q¾ ý“Ðt¿V{Î8=uÊâNîͱE;§¸°˜í,´À«0Þ0½,æ¸'ï$±ÈÕ©NGFÓ»Ú³%Þø%7­î])vo6JÆ8ÈØèt.Ñd` pÔ^¢N«V¿õŒl‚ÔŠ’ÛýêK ±!¬p—îZÿ20×`¶bÇz³cͦשæHzÔŸ}Gð)Ã÷Óñ°ëõtJÁš]›Ž[úYâwCбÜîcQ\/KÎË H%è0_Fµ¦¦™$Üp;¯ñ±}ÇõI1;sLÊɆC «}¼RH^UªÇÜAà( ä| û;¸¾±wÇoöö«yزeÄšŽn&–éÚ{MÌžðø”Dx˜¼±»þÀl7SgÅŒ¼CK-µÔêÈ?ÚóžÕwqÀµØ¥-"?ôä´@ÎÅê›'ý Þ€j„–`Õ¿M^[ôIâ>W›Î·ñ«é/¦XØëtýÜ>u×2š¦µ4œeçê «M&–u^Y™\Š·´¯Ð6AGü«.#z‘:•]¹Î(ÕJšIú4þÄñ[²Z´8-tœV-Pke™½®ª+@~Ôü"䣨®#LXã$ ´1ŠÅ¡sšß¥¢1mž5ÇÏ9}ÓÜm”Ù ªdJI¯MÊÓmÊŠ<Ç]Vàþ¾‹dh8zIìm'1Ð/ܳÁ•3… d|˜U2§`m€Êb¡ªÑ‡´vIé÷×G¢n«—ÊÌñ2¼wƒµz/ž‡‰ëÈr~7Ù£e|YùFÉá)nQÂË1ù Ò¬h|ÈY›DN·mæ„}˰̲Éß´ … v‚–hX˃±Ç[Ø•è9½>2>$KÙ—)?{£dªþàº!‚ŠKd‹ÙQ¢Q\ËjZ%K*GµÊ`Ù³1XZÊ•tzÆØÖ#=*ýI J=´ÛÍÐуÒÖ[Ø%«!*ÿùVƒäéÉp‹ä)¯ >n³ªjqå P­:3-‚E³°7\ÑéK©Ý©‡œÙzqMˆÖßiŽ32 L«e«ö²]Õ™¡ü¦¹ã+»Ìày·ªò1â¶¼ˆEÞ£‡äð<•Øs8ø\¦ÇD븜—QØp¶Ã'M"[hµßÊ:YÑ Õkäjš(ø÷’þ4ýäyƒÈÞ+óýhõº¼‡ŒyßyóÓ×Åfàê¹Ûpš yœo¬ÐòàTÐÁO0Ö‡–ÅÏr¨k:ˆjǰt"7“{g4ÿ8Þ†“*s:/l -¶C psÕôQAmgä­[SRÍoÙ“œLÑj0*Ñð6×.­2¿"g‘¾etèéLV i”öúhÍó­1'u·gÓˆ‘Mb ¤Rý7ô›ÇjÄr ;}Üü¬ž¡ØÈ°Ä–MWãÇ^mÝ«dýF:6gÞÆš^<Ëö‘‰–\ñ¤gk»•Xû±¬¬~E>eÑãµXd™<'/…¹Ñôš»/S 73 ᔄÖfURRDËHMDê¶nRÀý/ZV¥VëöâªØ«*Ë'@fQ&-T´ÑÞ‡Vl°2ƒ÷°þd$ÚL i³,¾ü¯æç•- —%š« €GÞE´À`'žc´øOùØ® —´ÿmyGWúÓµDW#M®¿3 OI_ì“TºÚ –f¥NÏÊUÜûN[¥« ³‚\lè«e´éï{¸Üý„–ºX|2ßk¯ÏÈÿôÒ%µ0Ȱ´APÛ÷†³À†5~|ürz õÙ9IxwÅLÚŽ—_gÉýºµ¹m½<c“ä²²¨”+þ›¿7ÍíqÝK ë„´ÜuîŸw+U'ËsÄu–ïâ‘â»»v ?"óTèý#›YSògwãf«òFÒ•/ Å­E¿B¶hÇ¥¯î/CÏGŸÑÿ§Óvä ùÌ£s™vHÙù©£š}”eeÀ*/K=ÒºBY×ø¢<Üöâ£ÚAÅåÒ>:JS¥Î(Î~S6Fn.bMl8’«Ñ*"».·¢rì6ÖŠ…fhÌújÛÀÿ ˆE]ÊQŽël+sDßÇÀ/çëf¤€7é*¡hsÈ~|óÍx蘋FÜJ‚j³ ×Þ†¤|HPC9¦,Á>7£5`•´DýW“T¡’ÌÎ^yBÓouî2¦&ÄvÃ=,À¨°Û%LÑ )s°G,&-ý¨:M˜¢JG¾(í©Tt¡‹­U, ÙX¥üN#Aý+·{˜sJT´×<ŽÄ­DK`ˆ©*¥j¤ŒLQêÖ¿ûƒu&ò ,0½SgIµåÊ@Òªa+ïfTÝë–[90Ñ©¢%²Ð>A9ù¿šüzü%vQm UÁ9ÊÈ  ò*¸"”·›ö6;Ë.Ò¦Þhä‘Z‚ EíFøàu¹‹žFÊ]ªë~‹C ¹©YFÉ!« ¾I$ m3M'FÏ÷1õÒIih©¼¨IB^cid$U¬áw:÷³¢m•A¦¼6ƒi;âë,6Àd{B¢¢ê®:ˆw;3m:¬  Ù©¨vP¡ò[lŠ9¢*Y2&ÍH#4Üш©–mÔƒTÖN3WÐjœí4^ÒÑy›©f.û“‹–=ÌÀâÉÑ .žŠæµ×t˜5U +þÖbÊVEÈÔ§VŠ;AÀR7¥—ý-\Áºæéß•¦h0<˜®™Y[-Á ÊJÄZÆ÷¼ù®¥@»T_<` 7lÂ*Ôçų4ÄòÁ4ªsYˆÕftM'¥[b% A)kðHµpíûãç¸êã%ƒhÕºçÍÉ`ê”ü¥X–,“á Ýy(;Èÿ5BOˆ®K„cZu…2©´* ¿äR—Ѓ­å™oa•£.Ű¾{°(=)),o¼JŒí—£ÕˆJÙJFC^ô6u+6ÿqZb°½ÿãiÜv›Mî䟶×ÿ(†›èÌP•pC Œ€P/*Žx@à]ñÓ»ŸüF8d’úQ)ÉfØ¡Éà’l(cð@ªºê,àê*ÓÙWX¿Pªwí#`Žºk¨–^•M{‚Bµh >t,ÉJwåöœ~av ™¹Ž(=IAÒ¢¸‚ ?²Gpz&õÃRÚŽ¬°îª S<$‚¤0‡=´±ÁT3Æ ýÄ¢V„Îzϳ:†jB"é¨5 1ßY3‘3®ÄR7 hÚ¶nv0{¬“nç‘´L¹GïK*þHÿô bl}uÊA‹Kh_˜]Á™‹É:¹ÊcDàT«XÒ·5ó_ŸdötåâéÙC/t˜ñ¶\ÙŸNDdžådVV%À!Ad&Ààž˜½—ŒóöVýjÁ‘ÖhLºÆrV—±£âЀ´´'U>À%*Τ `ûdP‘éîPgªÿM[µU,Mè3® 7'û°bTA ˆ+Ž`e´Âä4@Vª°],Ym…’~-GéV Œ*ÐßnUW;¥›3ÿªð8ºC¾„6º ´K7a6ÿú}0é¨[:EÛ5Ù•ãóÍ3ޏZ­†›Vd²j]\æóPS…kVô­,P”èú®V.)GË,SqU‘9  Å5€xþ¶‘ïÞÕÑû‡ZL¼,eÊl`ÓcºÅÅãA4¡QS{ú©€rxÝ)k´°w²fµ|f Ö%}ÊB0¥¬u¬õ¬;ÖÖŠI}€zÐc4©Ö²¨ºÜ ˜‡Íäy+kÆ^Gé2¼ƒT9> üë[¼õú‡26mÔô”ËFùI,ò £]W^œÐŵ& Vž9D&ßžVÎçúꚊÆ&¾3µ5(—§ë¨¬ØnµXÐ*¥Z¥Ÿo뤌EÁL–bn‰cÇ‹5iOúÍ8rlÖÆW ýEbN¨Ømg)QË£^ì+š³Ç¡/Z¶H£¯CÔ_:MþvÞ£>§ˆe½9æŽÀÚx Ð_€kÏç®ú¥Û‰Ù¼Zv úñdÃ¥e‘½ró'ô¤ ¼/¦ñ°bÒ<1 Ž£ö~Yú詊zBBþ±ªÑî0ZZ·öÃpßeËIù4¼H2±,&1Å¡ç_^ºê0ôm4לּ͢‰ªVU3 ’o`PBbI6j‡Ã6øò7yd(MÂPƒ´A„?E>4ÕnÎEÓ¼‘¤¨[Ñ‘3Q0JÚð:”ÑE¤ ͨ„¬jØ)ŽVZT±G¹RËl*ˆWIsÐÍ!wEr^Ä;ܦV.qH¦+P¥l†±FÇ WŸébúaý8í=_ÒÛ/RÃY2“,–RLn±2$‘ìÜ£sjyäŽ:FÌâ²±ÚØÙæúªîÅœÒÏxL¤  kT V‚;uº£÷^©Ð’’§,”l$ }ê²ì}CG<àjÙF¾u…#ÓsÂZ·yªã2lKk°Ì3cP ‘¼s6 5ƒ Ò’Í,ã5Q_µAóýôC¡h*NéÂÂ)$¥Zú3,S^P5MYCB÷£ŒÒ€Y´¿þ)Uä¶gŠ X ZãÛ2a‚\s1|Ör˃NÒO7­4ÆY%$퇸 Uü7×Dé鉉&›¤áljˆìŽÉ)înRjv>NÆc¸Ý–2 Ûˆúd(†$¡”jÅ*¼‚ŒŠ}Öh!2+!bYqYiX¿þ?òÅþc{íãÎì/zÖjO€Bþ«Ñc¶Ø YPæBX(«ˆ²"Í Ø6«[œÏÖz¿Õ¬„ «8»Ì7S2yaaÈØRô¬0Ãlæl²ì™sVƒY3«î¢ì”ÆV¿ZZodăT}Q[^‚h&Ì-Ø0!¦ÖXYî[ç5yr¡’$sa½oiƒGóuàÏ…Øìm'RÓõ|¡]IÚ²€IŽEz.qµQ]29>±M3Z™™öÕ8¡€Üš¢4L£Í¿\*4®fû>Ú,¹$+, Ïh†,*ïy Û7?H K¢v­Ž©Ðbaf ¥5ï_Ú:Q³wÉeh&~T"W Nýçæª+ùÌë²\¡¡‡’Eâ1ES+ú¡ 4Â`H"!סגeÔ©ª1±£LF¨S,¹©Ú¨Î[€d2wi3ë_3¤‘aÕ‹‹‚ÐVò»"¸Ô¥ûâ“ã+BakR­lEl›kÅp~:tGÚÒæv†F…ÝYðëÑj8íl/….ÚFŽÅŒ³™Ð*ƒ”óf÷m_t~º«ø[äx뎖e6¬ÚLFA &Õ¿Ø`‘@Õ "X ®\ê6 á^äOæ…R,ÃmꨑŽ- Vé²Á ‚}“ñš¹î+´) ŠH¨@ ³8õý¹Ê‹O’ÌükÇ£¢”Lö2|B:u›=µZßà;«¹U¾øUµX³WCGV‚›’hTžµ)&¥Þ(†ÏÛ+¦ü´X«˜²),Ó(­;ËYÇ€m’9\o)ê oqߟuÂïƒó×7ë_Ã'ÓŒÉrò0`Ôt´ô x¢ÆÏáDdŒ´ù€oNè[<õ(|üz¢óÖu_¯‘<_„’ÓÖöµ·uA¦ÓˆÎÔÌÃ#M› £Çfî¢íh%ýBIô뜳=O‡°Ë;jâÑ|䪞‘- XüŽØs¨Ã@±kk ŸØÊµXW jéœÀkž‡ôŠ·©:ZV=)ãépÒ -EÊoŸéÏ–Ioö=abT_EÁ|Çn5›’sûü£tÂÐg˜F–öÓž—]ÝU—Hö¹Ð¤d b±>fé¤UAú®ÓP€FQ„awLkì¯ÿQû‡¿âíÝB}>L!>£d°á,,9CrIHÎÖI&•d'xtÛ´ÜwGð·ô¿IÁïY—T#CÓ´)t¼“©å6Jäjv3'˜œ\Ç)ªÄCµäE6ó~›22•o jí5“¯RfÅIó ’LíæNÃŔ⢱ !r¦‰%+eeK(tìï»-PMUƒ)pÖ2²ºk¬¨ 1©rõÍ }ç*í´Ñí|V±Ž«aªD“é‰2 ”k†÷Y`ŒIX°½¼Ð1UmøÎ°ïS)7b%~pÖ«±,Ñm+ÜE¬V¬ýÿôƒ ÁV>ŠMÕX´Ò¿ÌaÐOö4kwn­©fÊñfe<© Œ#Ï·’û~:èo¡=Ù]­¤É©vΣÿ‹®/Ýí <¯ö¥„&\‰Yäpë#<«£;°Û´.ÕuõÞo3raOÎÙÛh1S\u‰T±ìy…85ÿýdðe){„šD"¬É—º—…¯¤Á zÒÃ*ÑŠ­AÁàƒ nEÀ“–+5*V§øåH,Ø­GZŒd×û)õ}Týcd^ô£ba²“F¤QómöV«¬«r)õšÇŸÊ -z5h2Y k`þ«ÚF´² 1Eæ^Ÿæ°€HÉ’V!æ›Å §÷7þã÷뢦"^Ñ\ŽGšøù±ù>zGˆˆ0€R:‘PŽ÷)¢KÏü]½ÆQÕ–Ê ¥ˆ3Ú–%$tYqüš¸Ÿ´¹ÿ3DÏ*â-Í÷4x”íúCc]³Zqž«ÔÐHZ‚‹p½LI—ÛÂãtwRéÍQ‚&–Þ v-o¬¿@h“LË^ŸRö^òZQ-PÕ‘ÐQ£„U–[5þ«ÈÅd¡) ?ŒEµÎ)¤Ú”¸´ G8›j¤.rÔ"À-Å.ÐÖR-|ÝóñãûP7uÉëiYXÉêúÒE(ŒDY\0CÊ2Ùž>n¿¨Š™oôEìVÍØÐ|ëW5*©¤R—°”—è»j'¨K¨sOõ! Im&Ó'Âä¨-WÅ´rùs27˜u0ÝdQRÏÖJ칦± 2z4ºåeqÚ¶æ„e9ޝdéÓK-†Ä»Å7;Ý!}EÌó(‹R,‰HUˆK´µ…U€Ä$í‘{íÑ¢ "Å0ë(]©}¢ ™Ç!”ò¿­½Y0¥ÓÐLÕ9ÒÊSj4uÿ¡’'š¬6- é­ ÎC¶]ñ,~¶ì&¾ÞCŒ–“qXÔÿ¤4(½~ýx=õÍ2Ô-b·Ê“""¼¹YÕX—ÜÄ€yòôí2 n zgníó„Éк,Ö‰UÙ]'ô,Ä›AA%Õ#[,éZåÇr×qºè®ÑÝU“ª–’› XFõ¬QÀ zTì3{JùΉ{¢bhv¡Ö›qRçBÓNyLy^•z«Îæ€A×I å.+&“Ùú]5Û„À€ºå†¹u‹05vÖ"ÂZ.p¬¼F«a*„ÊÆêÀºp‘®pì×ß×ûPñÒ_`Z%nè{jÿ½ùÿ¯?ïÓO @4`1¦H˜ùõ3K¥EUêÒõ? ¤Qi΀`¨ÔÛFš3Z6št¾…—Xf!6+ªºÏ/V ²G2´ŒUo¬³à–_;Í«Y‡Õ26í] ,ß‘FÆs@‰hu½FÒÒ&ºú+þŸ²”HJè—ñ¯#µÂvï›}0°¹%¸ÃŒR’Ϫ]˜W=šRÙp>Š#P6—jâ =¥®þ^ºìˆ1Oz0ú¯ä>…êâšÁ ÚŸî, Û¬ù±*d¬ü*j‰¢Ì šñT87Ç_˜GçãúÕþÞ/­¼ 3´U¸ ù,è)b u½«ýÊ' ÉAQ`ÝCAáQ׿ÌÊá{œg‘1v$  Çȉ±aR¡´M¥‰f(i‘žüèÖQ³Iˆ DœÝ–/ÐîrEc¾ÞÎv¹ðÌt-Ѳ‡èl´»µËÞ¦³ÌgŽm÷!Uâ.Öqì…Þ,2 ¨¤PÖ›·H%¬(ü× h±Mc¬;\,ÉËkèvøÜ 2Å#ûò-ºæXT{TR¤ÅÐÏÅŸéãñ׬ßÂ^liôÏNŽIÐÆs³ÖÆQrGAŠ’ÂˆúñãÉ?êE9ì¯?Æ&å`-ñ¤PSÝ`ž¬‚ô’P’ãŽ.ÊÄ5I.†£ˆb.bÖKh› œqQZƒaßµ)3íT¡!·47s3*ž ©4ÜjíͬFмÉlëØ~0¢ïT³X.»°uí6n6ë>±Ö Ú òÞš´_#ž@ñ_&F¯6°pÄoö‘ÅË0ˆ\ÙôõWf5÷6í´Éà*b2FìÍ`ƒj)r6(T–‘üë" ¢í¡v¿pDEË_«ÜìgÑ`9ì×àŸËf KŽoó¯á&ĽâO±)s^–­ìA[éµmO®´ˆøW_0Ɇ-9ч¼Ë‹/[Ú ÓøÂô°3O·q‚üMà%ٯƷdüÐAÐ1QÓ.(¢ÕY;{1Š·õ.²CÿSU2ÄÉŒ3•däb 0= ‹"rvư6ßhØü“FÀ7C¦ŽšÙxÚ|)º9fV7àR’’EùÏ=Al^v±™oIÁ­B2fæßÞ£‹²º5‡h³4”™¡gD·Ñφ Ôº²/ñ×®- ‡šßÎì-glBĸ¢á«$N¥´þšˆµTtÏeËÕaœ-«V@pèåX× Y}®5Ù_/<Æf¿›RÆ.‡µsZÒ6, <&y »R+ J•} éݱ~rÜM‚ï_4+ O`бv„Åþ–ûApSdê`©k¤óV!œ ˜räzÙ2™–®3¸ ¸ “ý|ñUUדzSaix¸¸ %x³Qau q´¬@’÷†à-Pçiä:ö,æD¡I¦(c”ú© k±—¤¡o\øûÈÅi¢{ºÉmš›L$“éÑ¢ËÆú^pbfMtÌ\rHëP=Û'ÑF‰+èTïžw¤g¥V¤(`š^·U°ËsЏî5hä¢BÅ._•*Q ¢½k§X-ZúË´¤[6´Q¶NºRœ/v„v¬Ê/š»ÖÊf´¿ÅX¡ þ2½jX”¾Ì°µbGBPÇ!ªÛ!„mó®L™2â@œ»í hßÍßõ£@ÑûwHÄÁÕ_Ӕ͋¶2X¦’ŒIé±+ºF!V¨ éä67wyÍ'ÙQŠf×aw¡ÃÖoVaÑVòÜ1vØ»§!=•{ë³u™®±Z9„"q¶pü’“Qà#úÅò_î2”ÞPGMƒVM €RÊS¡¢%lZ†™ô¥x,=)¼“ã„ñ÷ ¸– FâVÎ#U&~›¢a×0§@pWYJ% Þê´öAS6PÌÏù¼i çxÿÊ¢isþ^q`ÂÔ‚N‡5·=„Ë™¡1)8¿Š¯æ­¨#É”SñP5Û O{'6-G $F8ÙR#ä²°šòMx5_ÙsßñÚ™ý­®h£=ŒÙ:¦¥jóJ2=MB6q¦¬‘@R!MÂDDŠ„‡œ- m±Dü¤­KY,­KYYüã7ÑaQ/”ð.TÛf$Á]{ßáLÄkezœä:Ž|Íx_ïdÏH½Aa¬Áu-AMþ…• « ½¾² ¬_ +î=ûÿ-2±ýV¸.KRÿ÷LV‹”Æ<j)FHÕ¡h“NòY­c6[Câ@Éœ(’Bÿ`j¸S¨-{ÁpÆ\ºBЪМa“ÕâŠPwF\PkSFè ´J–~¦Ü4ö |2þ’v¾£®vBM§2Ç‘¨Ï6æ4O1°òÞ %T]nøëb£c"ÈTÙ׆)ì²0±ªeN½5 2EÓT½žSò™³CD5O æÄuЈo¥cftp±Y¸îtÚt72ï´28€.),â½ä?ZÕb‰,xXŸeU+,Ýò!ƒY̵ãëZÑ ùÔ«Wáó#|îS"Ç ²cF‡¸UX€ì€ $7¾ñ³ƒË—Õ^ÌR “:Fq3C0fQ‹°b6©ÃEl(0ªŒ©f*©°+¢g*$G e¹÷¹µp@¿ŸþzudéÓêØão/KŸ"XÚË,pª¬è¬ Û¼–)ä) :ÔâVù½ D4o{IœµS’¬â"ÄŃ󴑿û©Zü±ú­Ú5¨ìF«(õq9Ô±3YÉÕýnQFG£GŒ©eå¡ÊJ¿eX0ªÇ-,eËQ3õ®z^mG  ”[æE+hQ´E3o >4Gÿjò[Us… @þL(,‘¦{„ 2C†pC²léªÊèÒÖ#¥IJ0çR>u,ÌŒàÎÈ[«”jh°¸èuŒs4°äFÄ2Y(¤ƒ%Š÷ך»¸zè¤y1iÚ&n;ãÇ1Ÿ'Ó|–ƨ1äSºè{™ƒlpG=.œ #ý[ £¡blÆ•êøuÖÕ–áô.–{*.|䃜Lˆœ]:ii浬òr¹\ûw[F§ëHåZç¨2]³§$%b“c®Õ¥rýuµA¦[±úìG\ÃСä Ô2z!dðÓuÏu[TpV?Ô):¢(-hm¥X¨6%V¸Ì:Uåã« Úi€e¸—8AŸSÒë,BAb*+„!Glë-v—ÑVªÌRÑÍF¨Ä½õUÆëºÙ$ («»ñWÏ|Yä‘gÉé˜eò"I‹è¼~¢»J€@!yª æÏšçòÝasK÷è·½Wú‚ÅϤµmw*6þ²°b(¡r ¤°·ÂekzÚÓtÊaS ©/é$º¿÷:=ŽaYÉ©iK€ÆÐ0Ø?M 3FÚ1ªšs˜–»"™brîP! ýô¹.Êäû¬I X]šA›r”dð ^-õŽ—‘,é, ºõœ‡5*4É¢êgc‹×ÙqÀ!™<²B´dBj÷(~ÑÍtaà™35žS9ô‚+mfRhS($_ñÏŽ «ùêŸMÄÂô5‹Ä%åšcº6az†=ä‡ZlØA瞺UôkºExlWÉîÀø–-uÒ‘=Ï+3Ïé4‘R°ÙÏ¥Ê T+ʬÒ­¢¶s=UŒËTy빞ƒÈþYÔBÌ3¸}3U }™yýC’[ÚÑbAE•»wfÕ UL/JùéÐm)aª¥ÊúLìRÇôÿ‘Ó´\?âßì¿u¬½ôĈxãég…ŠÖ“J³+±¥D2'ºsö­3L}ö„uÝÖË 3.lîi»#åp 1« sUq]²ˆˆ¨K<Å×Åuovî^bú_¥M‡ß=Û­<¢ãåO‰§–slb«Ñk­Äñͧ¡ÁÜ:V~6PhÆv‘²Ío*q´¡›qø+Èq{ŒË0Â]¿¦X¥¬­U"Ç*JØ£Z·%شˬ«½ïóëƒYk 㤮Ë; /÷ŒÓî7Ö6ÝÙ‰(«DÇhUhÌTÊ:ÀmöƒéPpoÒÚ¦³;Úß8QŸ—è¿Ø9½¾D¯ér«R*SIj[ÏÀV]ußHËbd¨ˆ$Õ*°Cý¤Á5™¯ÀUÁ[^÷úèÕÅC‡þ2(„a¢Øe…X‹•ש挫f­Ûì·Åš?~G7Õ‡fè@À̱©˜"¨(è8ºçöÒÜz£°Ej9I¬Œ /û}Ž\$›šhÙ ÷/Ù ãù… XµÈz3µT«nÖå©«òÖ5^øDÑ`XæùŒ7¢ç,}¥jß3DTP7\mÕ]U» Iþû¬ Bu(îI«ÆùHhÈŠ2«#©ŠÉØçkè}´°í›fÒDÑ—~¹-Ïù¸Õ-éœgme”qÏDîØm†4ÛRÌ]™GЫ{>ø+*ŽKö‘Ú=cRÔ¨¯[“î5/‹’ f¡ÁYµnç¼à¨AÎ2RÑw[œ3ÙS,• ý„ÄV`iÕm7(°Ñ‘ŸAÉY]¨*¥BTA¥q9]ýô³»“ ÿÁófô¡Êíeqí ÁU’ïðx>G<Ÿyuü]ýÊÎÏÈïžÚÂõ31ÙÆ¹žXO§•Ñ¹Ë 3ª‚T óá'#I3h>Vº sî1Æë÷†3]¦Q+Í‚¢¢ãÙ‹ª.ªKßJºK7¨sG¬WMÁ2}]9˜V)÷¾Òøj™$¸4‚¨/÷ ¦ëYVÌûÈL_܇H”AG¬ 6YçÌf©²ÃOW]Ìá\2êfìf”¬TB£ºšzfÉX’ÿæ˜q+¯öÜÅþêç%Ôý'  i:,ùÄüm3s)–E¿°q*¬ F¤ÑyQ~¾€]»w+CÊß.þ=Á«ôÑ䨎¼ßšUŽøäF;GœˆèBºì6ÝVâqkødÛRãxм¹¾ÅLÈ©£4ºkµ}(zúL~ñ5GN&³Z+R 'KaãÐÏ<ÛÇÌ\ i¦v¨ÉÈžu)mmEª+×Fp‰ ÑÞªöMŠŒ I\ ª{È(ʨcÉ<è¹Wÿ´ËÊc?2úòžÓÚ °f@Ê´~lÊòJ¬ñÍyKP¾P"ã!šÉSS3S=Mýk%Æ[ >YRò ²˜“itŒ›ñe b™ h ‹jƱ„›„£"ýiþÕ\ÿ)c $ßdí4Šþ¿ŸÅÁHÏéífßíüÀñgäWJÙ© E>¦aÏÆª÷- Žé«– ¡hU› õ]+¢:©IT¢ ¥˜µ×¨µ™º¬² Õjhܤº¢Ÿ¦ºn}†í'+7 7Øml늨ÅBÍ[´R«³@,5omþ’-€ÍJ»N²•&ê½jFŠÒ¤¸òF“B­ ;ˆ; Øð§Ž<ò<8®9éõŸ«Ï¢M 3u2y_äÀZ¡¦ê~Bª©r©r• X@ÑMiΔûêY“”´Qf¬)Ð éA%%Uq€“pk‘Ÿ…*ËuÃX —¶œ jÐMµãµMÌy£@PÙøãäñ\pÕì-b ^"5û§HâŠ7ÌŽ@@píä³Éü]6Oô³Lÿšæ%D&¯UÃV5 ª‡+PreØ™IµÌžpïr°¸Ù¬Ë# « …`Ô ÐÖ’««¬hL…—$ÝzZÕµ =*Òm‚–fö˜›IQ¬·q8“ ˆò¥ª÷¤‘–(íJµ }7‹‹~sÜ*gþ—´*)–4ô³Llû…Jõ\²èéìZÔC²†F’LéqP²—P2¨ê:ÌÐ^áÄUâÎf„*J­”ºíy$ØŸÇÏžŽótµÂH¦’ " ÜL¥¨… 0_“FïÀüŽ h4«zДq…bˆBi[7û±5­òÖиƒ@Gm” Ä TÍ^¸B®a´RVº@~äÈ#æ~]emŸ¬ËlE–¨\Alâ‘d˨æÙäJŽšÆ]£èÆÓ9>tçò]…gíU0¶Ã­aØ3ªÐ¿QÀŸæq\à±qÒˆ„E<”³”æÖÊŠ4D¸eâI§Ù 6nPÐ`˜ä&· äĊԫõV­Hà¬OœHY—ÔxèÑLÙcƹ4ºêîì#¯¥Î2pÕÈ”E —Ó£´ÈÔ¥-xw|ãã©m€è¦P®oŸv‘ ×e¥ªvWTÎ]gâèˆm° àNÓGUïªí¾J.‘¾ZÀ:ÖKHd~éÕs*¨‘ •T啨™ƒÝrhçHÜZL­ Œ•Xš ƒ0ìÛˆ½¼U_<…ÜrS…cC9¥ýÖWð0wX'áZ×w•„>{Ù˜hˆ‘Å!Sn®¿:úZ:S!àêF”°áÍבA¡×þ6°Ú£GÚ˜kC.6X`lLé0uŽv`7£°TpKPä²Iæë‚>,W=vF“ÙX]íØ²ýþ£‡‰4â ´òˆ$l"ƒ$ˆ“ÄÒXm BH­B‚Âìs¾k -ó5Ö[[¤Hºº)»ž²ú )|g51, D‚feRÌ¡cö]›œ+]… §XÆžW¿WhÒÕçë)Âõ /FÙÉqcAGI¬…”ÒhÚ+/G,|É=Fޱ_òVõþ@`Ünž-Ÿl8çËÑ02ËNµ/¤\ÒœÖ5†kC…\fIç,ŸÜ*hÁÛ­á_ŽçuiÆ„¡÷áëA~¶ W-+žÑhÿSð±Ck#vGó ˆ{ ‰VU“¨ÿ锬zÈbõó]I7… œ¸Ñ¥ø¯Ž¹køÄÍÆÌ~ÂÂÅÍûÆÑ;v "yStBlŒˆ·ÊdU‘Q¤ÜK8{›Žœ*mDvÕiÒTâ sªµ¦µÕ–&ò,V-)EªP‘ýC»ctϱI0_›-0 †Ñmyk¤¿¼™7ìªð©Êóg 53ÈY^ÝL8+’(M㊅ê‰EÍhÓŸÌ©a¦T¢•#"4Wª÷Dô#5Ó¨¯é-„Ô¦*OÝF±‘Žãš1Ke1VqË¥&ŸŠêÖ[3/™"ˆÏÝRh²!¸ªåZì°ZÕ ü§ü¡ï™a‡_Fy4Ñld$î H£DŸÕP®/¦—ðLJ©j]‡ªÇ‰ 4pI$ˆþžÒ%l‡ §ùKa¶6&«ñq×~önî’ÖÃoAA/jÍ‹6“ޤâù_™fV £QjžNg Ê«úSbÖƒ.¸6êÅÚ½À~xÅn–E<ÃІD&½åuWn塊ãK°â•üq¥Nº\úYÚ«—3$lxL¹ßd':•0ˆ¤±Ôòÿqå†IôË Q‡¤ g—2ÁMƒ3Š­’K†ôTÊ´ÄP4iù!˜‹K‡--t·‘/@„m¨Äˆ´-é½’$Æ«îæ‡%–Ç?î9Y®®ˆÔ4ì½Qç-ëä™a\—ŒªÆÄÐV—j½Ìh’K0RzXËXŠî}f}¡XÊ˜ÊØ–%¡`º±7X¤‘RÖVšXy'Â*Q]4¦™ì¥Ûç’Í”?¹0ê´Þ|g‘ŠØÍ&šK*,¶HÍ ÕmÐ(W„WƒHê® 3b½iÞÍH€ía3¯PÚùÈ—­ÐКhTc'êN°ÂóJ,¨_ŸÓž©ääŠÎ(òû*öcR—Du(nÁÓ  ÇÝ2Àì¼…è]“®³K;XЙļ=J9cÕ$Z€7I¥³Â“ñôé¡ôÏ:,¼<œe•Ró±ä˜ræMÑzRÀý5;;‰e9ŸªG‹§g¤2@†,‚·ý]`ç™T³¦ÅtøÜ'aÆä“œR‚ļޤ¬Ë%¥ î®ÍÁ{šÂ_P ÿ¨ÔÔ½"…¿ÉI°â¼.õ˜#Už¡ˆ3! ¹ì°Ûgp#Ïþ¿<º«eXCŒÊÚz‘˜F*!X#2Ï’Ã3,–ïäþä9µXýšW()†Î}býhêé û9’åÚRˆÆgAp| 1Æ€ÿBé8KË)}w$\¬ÖwZ5TékÜv¨ Í1ºê˜lW=å’,JöaÜ'„œ06¾œò-óÏäý?ö FÙ§È*hnuZ%!0È~µáØq×ò‘Úá²öW8 ú60ŒmÙÜÍs裟 ¸[A×YÅÆp< ®,X¸„ý•Èêµô”P³bl¤j¡X ¢ô¹¹Ø™ññÞXšTŽPgPÆ÷RûO“UäñÑæ“¤iÚ–›¹¸p䈲›M‘T¨ŒÂDQØ­Vç¹jÜp·KÕº’ÑòlnÔ_[g%%¡1í©©ZžÍ¶©nKÿØÅ¤Á8è°æku€qí\ X•ˆ¢yÊrš÷hÍ­ÿ*É„ 5ùíUn[Øa¾44Òö ‹ÞLjb*åüí­Lç¢A>‰¢ ý·‹Lcj Qýˆ¯ŸýnU@˜ëE‹ø Ä¥[žË³q•9jW+nÍ »ì]Ø>³#X$±î3&2©ô P.´êÜ’¸sÚ±.K5eiøþk ej€1÷Ò¡—MÒ’Ø tpF(,SR†f>›U‚¨“7%×%•G7²Õ vë'‚ß.é€ÊQÓâ~inçÉ\w:J^‡ê:,ôÿ(‹QéÓû&þƒ3 U[HŠœ—ífdŒ†$ÈGçÿ>B’<Õ«¡‰Z@<äüqCûu ]ÏÇÒð3µ¢ßm‡‘™6ã4Fy@îE"èÑ?ž‡z1Ú:«”aJqU5æ…#µT6!ÃS¢$T@'1JÒÐ;,qãçÜhÂ5—üå$S!‘of@ZVHüµÈà©'¨ *É[hT¤2/¦ä}Iqy'—;^c1 fc lá&1G'úÌÒ.ÇÌK¯m:Qý ¥1ß3Gn!Ù#Õqýö©®(‹¤˜¢’IJ†~²À=ÄÜ,7†P2¹HŒEh¡â¶55£I±8Ro“¶Çö< ñ|Qt-V=EÓu˜chcÕpquñÜ©h+ Ä@‚lG¢†e%lßL^©nƒº… €Uʽ µ” (zA«P_ܨՖ OŠñRX)ÒÕ£¶nÀõœ‚2BÒ3€ Ä´,Aè7gª7IH›æ-OZ»÷”g½€`Ïíµ.ŒCÁ*(¦e€1‘˜b*Q}%‰­Õ;$H­Ì}&^Í]¤Ùq‹«ZVêaýàüÌ´ÖÏ Ds©jÜuˆ¬ Áex Ë4(Tu­f`Ëžò2-cZÖ€¨¼Z.q "¨$©Œ‚¬ ARHÑ® qÐÖ»¤ãge麨)ÔðU#_¨ücä]P›GŽËtb{ ‚Ë)y#t¬Áe¢±fò¥D\ŒÆ*B ŸŠ ÝÈÌš‚Rº(ýª çn†ªWpÙ”=,Ò YõDQQúef‚|ÆÐ-#ŽUTó-RáÏ ÊËÛî$ Ë˶a¦ws[5?…œuvµ™RP•Z‰ ÁX ”­nV»NO²Å —ù+V„8Æs§2ÌÜ-¬è™)ÌRC5µJCT¡Ç`·ûOêØF;Y-“†8)ä@3 ‚¦âlïÜ$p‡×/á7¹#—¸{|.áfwÔ4â Uö¹Ytòãƒ)ˆRвͰpÞÊΞrþ¨ÌºçÆÿܰ•X…X0Î{æ}ÃÏÐýŽ•›f…_A$4œzÆŠºWö¿Ûóèé#ñ6+Z…q6õZÄÍô {^ã­z·´Ä– rÅœE‹Ùù‘·ÊÚ™ÏÍ«=»Ë¼DF~ÅKñ»»0T¤®Æ«±]fr•Ì[=e×((.K??‘ÊYQ£+ª™ Œö[’/'.¾ƒ!ló{ªÛ~{[ W(ÓË=9OW3±«ÎRRPŒ¥µÌnsÛ´…Ùb~¯Õ…¿£lú  b³‘ £-:¨Nnî­72ì˜r $‰¾¬¢Èe, …Úv·À±À¿<‚=þ»ÃMÏì-%´M5òåÇÒš$Â"ÖDr¬n$‘VOH©·Ý° ¥OMç««©óRމ›U7ÉU%…ìÃ5½f¿Œn‘ÀÀ¾ ,UV¿°Îã«/"¨IÈ(\˘kBÞ[³ EI_°B¹9÷"lËb±Àº‡9Ê«@Émžë¬œý4ÖyK¸˳½Z=왃–¿píKº¹ÚŠØ«OP”˜¶„2Ü8ôºùa Ð]¥"YĺÈÌ[U›8™)E³ÅE­Í“²‚ÔÕCµa¹ª—$cm€7yv4é½»¬üóCñwðÎÔ{z=F8³Î9å§«>Üq@¥2ÌÆ#_Û6åK±pT@‰¢'0«=C¶SZ°±h»?Vn°fB¸ášÏ̲h.[R£V$Y¶ÐBÂ6¢ú¥Tâ²S•fÃð£ ]ž*ý-Õ%¨ÃÍeÀ‚«h4Y¥=(QuÀ*ÁÑQpØŠjrˆ£­óÖb„4n¶{L[;X§õ"gÅTw¬Mx í5.‡‘¹”œ^Kk®}AŒ<Þ|_¢ý˜Ëᯔ‘tsyPf*eÒLŸ!¡|‹ uØqÛ¦î¼Ñ‹£œ•H^ORQ½¤* <1Fau¹•ƒ0iýTH»¿¥ZdÙ]ÿ“£ú’C„Úly‘$žVa”bÈ’-ê²@`_·&U+í6›nšùüÎÐ3X2ê´&/ÙºèÂz{1‘:L¶Ì.ÛMFV$ºuêùµ™2ýè5,ë Mxl²Y VÄfÀz~Å—­Gš•N¥ »üÍçY&©_œ}1¼X«¤²ŽÇƒßǃõº ¸…Ǥðs¤eônêÓR¨é€ëÒ­È*umÆUŒÇ5»pËÕ¾u{ù ¬n•ŒÄ]¦@Uk)8ÙÑ?ØY!îÉ+H±LW~Øq¢3ìp¸vQÿ˜“HµÐ5¶ÔšVÆhbȲrzЍ•B¬åKÈ Ý*lâËX[ê>áÑ%ÄEw‚Yñ`x1±„“Ç+K»L³ªG_n«$E9Zi$fÞ¥T4ËBÀÂs’•\Æ¡Qb¿™kY’¯\gHÐ6>·¥:ƒ Üúf´‡þ‚ÌêšÿT9x%:ödÿ1ÑT¿2/ò­GúDT.Qýê•+¶‡”QöTLÞã˜(Ÿ×X¨ÔB¸œ© –U®Òù÷;3MÀ×Xl5væ£ržÛçá)@õ!`‰*KVJ0\ŸNWó'áSœ¿,Æ%Ý=Øq¦fì‰æ ?ÎÖ õñ{'·}"KÄ 3/Û¶Ím“ã“_ŸŽ¿–&îY]Jê9a…s“Ï·íä?£qMW2'HR³£*êúgÓÌL¿·~߇6hÉY$\r¢7Le–Jã͵“æ€ã¢Ìïïœ ux»¯TÀ…íB¦~YRV¢8>|€í@p Ä¿Q´åë÷iÖr²«·æ³GOD5:뙦ÇGkb\eA‰–(3.{VšºdAÆÌˆzz£l‹ g—ìor³új¼¾ßÖ ;©`ËD®™­[X7µÈǵ#Väyãµ^Ãu5Lj пú£ÖnÙïþ¼åJ®$jÚËF„VUèÍóÛ"F`a×¢‚žô]æ.âùk¶ÎŽ–Ëñ·7Ðí½Æu½eø.¯«¢¨kÓúßóåÌ®ó\ö‚e¢¦2Í1ªÙK–A¤þ"ýßI£:>Ÿ—޲›hoV½läƒæÉÛ^I«­Ôu|íRÄõy5)U_Ó—:oQ£É´–äI!Íÿ¨ðz‰ÜÆÛ(5Fs‰U{Ô¢DÝÕrßS¨Ü1+ûL+µ[Ö=$èX¶-TüÀy~pìÿfJ«]sÓ,ÙÉfŠÙwrÉ¿goX×QÇòËúT­Î%çã ®s5SѶ« ?ðç¨.5M€ Á}ÜÞU"QŽ‹ÀÕî·›.‡FUäÛêxⱀы¢Ò&>2ìí²Ö.Cˆ·ÃGwŸësw­—‹Ÿâ®!ëæ_ óz>*K=×keôµ¢êdClÐïÓ9¤™ ­ º Ýo=ŒSµ²`¬vä:–Rî¬âóémö­cn!•­òY wÏ|vøh{c»õ#ý#ö¸3…¤BÒ)t÷.ÐÌ n¹<žšîy{¤Ðh.Û?w¯-•QІ@¤×Î0~ăE´VŒPUk$›¥¡ùmÊY²n·[ðߤ¦uѪæC ‘…Î*ÜÌT¥³m„Ã3Ÿ³áûŸýá¼%¥œ[sÕs`8ÔѵÀü ËGÏ*°¬ ORŸYX4*Ýÿ®^Ùíe¨šä°×Fë‹Ï­[i½š2™ÔbÂI“¬+Fj„VX42…R*ì©´&AKÜF§Ù=Ý3 X;Xã¾4+,ÓŒ‰†—­)”:ø(|ù c¬ýMú‘ŽN_wåäI“’Dg‡jÜû6¶ÒõÏ'ŸÉó³^Bts2« òz}Ö3„Œ°xú–X.ËfRGX^éœà^çâ ¸_Šyci6äeO,"µ‹LâX%ת5F‘+I|å§ôÀX“2©›?2âQ¢3þ —´Cr#Õµ±«RT·1**ÔìµbE X›ßõ,˜ÔmMBAIìô¶uÎ!¨ŠW¹H'bÕúË=÷ŠbÔF÷VVŠP.Zݸ{öЮZ ulÃÉúد³ÔÓ‘”Ø3± kó´gŸ‘_ƒÕF›õ¯ê.”ò7¹r±Y²:GŽ}FZ SÂÈ6ðyVùðhƒŸ—7õ—wEeqlKYA.\ýf “%¨5¤Zþ{‚Ã"’³ŸLf*ñX€éTì%WÊzJXŽ1œžÊË’ÍW5¢4 þdËt¯!²Î8i@·ç#!›KU™¬²/ˆnÈÎX¹ºP½èÐD+p/gVh6#)Ûô§g áq4h÷Y:-+$ÏÚÅ2ŸìœêQr*ÿõȨZÞ¥½Øjµ~õ”ÌþÁÑcÁ.+„È” Ÿ,g+èÏÒ½+//Q‚\\`ŒÒ &¦/ @ªe·ÝE|›è‰>¿}]Ô³1\wNNFJ8ôýHp•.…3*c"±ŸxaC‘WÔ£êü©³ãÍý>F´äzŸ4ÊZ˜›®¹™Bëâ`ôÑ 6Z.×ξ³õ׸fdΆUÇšÜÔzáóŽŽ„’«ã"ÅœÓÇ\m¾ÅÀ³ž-K‹"jEB0¼¸–kbùcýÅH¶¤ž»É³™Ø“Í~•tÙÖÈÎ+<Î?Ÿ8•;Nz™JG8‚;<Ñ—eÞ]áN]ma–ŸKÅÓ\× [1ŒÓÆg¤-pyšš¹~8ôϬ!sÚ—mÍ/3­á°êˆŸ (ˆ2x?”Ä„ ¥k¨ÕØÖ¢Ó7µþŠÉÇCÖäxãÇ;LqàƒùrH­p Àì%A:Óÿˆ®øòŽê#þl`¡Ó°œGîQµ}N?¨ÑÄߨ ”³‚¡Ñ$VaDަߛ<¤·™<‰±ä±àÓŽ„ª»lM.xÉ5q”\ÙÒ§ã¯Ö„Bl×$f)âÕàˆ¨§õýÅ^ßm‘ÕVSÔU (º$$%Vؘ´¾ÍëeQ6¢w›é©ì6}X’â´ •T?H‹Aßí 9 Ð$\!ªé}KÑäa‹Š ±¬¸p޶£T«3¦:…kÌÕwZ›Ù`}Ó72á2Š\K}Õ9 vØ®±<’×a"Á‘=BÒ(;ïP)³ú^ßÍó^ŽŠôŒ ]KÓ´ÌE?k¦aÁ§BnÇ¥‰Ä‹¿üàF«LjÁª I$L°d¾É­Ã{ûRfN:ØÒÌIÅ(’Àú,µôŠÔ›çIxpÉ%ÛZ)‹û+8¥þv‚_ô,^}Ù¹v#¯±âÕlû•{Wó´:1{–˰ó©°Y¥Á#ú™ˆº÷fµ)Dc€MsÛT3B:}J]ØP± b–…hÍ0œÏ¹X“fVdn±Oýr‚÷XbYêŠFg Vb…ʶ\0įixòmÈ@ÛÉ›5F€ÉÓ¨ù¢A#¢E¸Ê »ä1f AO$E|ô€4¨Àìh>ÏwZ ô±Z¯RÞ,T÷ûbžÅ¿%À”Šç5­þh£dÎwM½T‹Å¤Ûd¶•„Õf-wW1a¢Z¦ û*+mJ|e?޽0yÛÊ+æîxßÅßJž©Ô&nÆo¿£ÌÑMgV^-«Ñçcéb.<ñhˆÍö…tP£-Ms–·+éçø¯_ÅR>ÓÊÚJu½‹ØÇYŽ#3(mrþöÁ:54_®æ²ä·NYÍÖϺŽ_žæšçw)VkI{¦½›òAª0ýfÖ‘tÛX+7…H$“Ò§½¾¤ö7ià åj˜ù:ˆ'ÑÀÓò"ÊÈû¬±<Â¥¹›rº¥4k•­ÞÍ2m’§|e¨HL‘² XE¼ÿÛ–‡U&a]þk–!D±™h¬„¿ÙÁûË{I •p¬,&àóœÙut íô\Ã]rh½)ÿI”ΰ™ì“8™ÓIüŠú_Õôÿæ=އ1tü}Õ„À²ÇɃ;©ØseÝ ¥V@ži@ØÒ6¥ëQ0ÔØÆD6*7üã†LÒ%¼}gýh]ã¹\6ªGDG\rI‚³r>‘6ªŒýV‰²]Jˆ­u·Ó©1ò»cOh2%ÎE÷zbLr †‚@Gò‘m»’Muâ¯×M[+Yú‰®ê™:dL™ó¶YÙ,ÒǘdfuËLYä’tÚ$+KkJ€]îöÜã…>^Êe¥¶r–¶Ù MèªÒ#æ×¦h]ìuóÚgý£Ýñ€óO‘ؽŸ› Êè±ÕãŠ)8ÜÑœÛ )*Ö bnÅWO}«ÇU½s°÷óv„“dŸ;?UuSHò§ÐãÚ9µ=Ý…œŸ°3FÛz®ºQÜN}7ùãŒñ÷nûïu+a§ºfÕúd…Xj…¢ÇEo˜ÊRª¡É‘&ÅN»r?¬çšLA…Í¡¬¬AœÐ–߹ܣ¦^˱WÝp¤#º& =‚Óì$ˆ÷e›Pt°OF}¬«Û"~Œ}Z‰õá!è"°¬—AµÎC ÅÔ›’­N›*+u \Ë¿¥›qH“:$ý(LÎÿ³ÃUÑ?Ãæú…–!Ëxá’ItUl,dI‚–Y ¶åà¯ó5é_ö›÷N‡Ü1k‘ý7í£“‹ E—¨cÆñF=‘32Ë#{Xª–“Ók·MÔÝ\Ú~¦|Xؾƒy7j†â)!t(èJþ•ê½î²éQ¢9k¤"L"/­Š]±j,íï&xa굩Ð:ãTX †òr*ìŸ;‚÷&€ˆù/Q£Z)dêQc¬R"Uoj²8ŠÒªT³ æ·u.3ü•94ZÍa§ª­Ä“Œ)ž±i–×ãÊjÄúlqžBê:Å‹ã Ù9ž5Ór‹¯Ñ5äéœý#´Ò†`÷k(È@JF’¨5‹ ·‰€<¿û-£ÑfÇx¾¦æ¬ÇI"ÑñÕ‰´À²œµúUú¯ŸÇ‡ öÌjÙIèä}íùHwõ5¬†Å ÀzÁ‚«ý$ü×-Ö(×k`/eèõu{\Î%àwcóž–"uP–°5Xĉú\b­g)"̜˄(ÁáËÒŠ Ýi)?}×^º$bÕnÔB„Mj´I`ëVdÌÈLÚ;©‰4ßû!5õÖ 5¡Ñ`­SÀÍ ¬;X).Ó—ýä^r¾È”v·ˆÎáÚ4AŸ³d4݆ ¸m(VX³t‹V°]Jÿaf–” ݵ§ñi±ÊN˜óq–¥™ef”¤k$@¨Ä„…<€IyüøëͶ Hb6ðGÈþo‚zJ{<”e6Ö”Ò¯£:%0ìó·(ªç½æŒ”4xµ H©4­Àº¡hß=Ø÷¼ð>'D¶oÍ# ëþ|ëÄ„,6K/`Ý;]BB[H)÷ñ•…^È—bŒ# nÌÇ´~i¹è»²£“àd¬¿Zê|UæÁ¹ˆ Vi[ÐmÚíÏæŒdW‹"Þö–k» 5.&PºGCƒõ˜SµÜ1„UOau[ŠÍW·4|™[5=Hç–PÁáf$“E¬°Iæ¶’+›»êÒ C"%†Ü€isÈâä8­¼©çòGR‡Ç~ºý`xÓIV|{æ;`°+Š€/Œ¶¨«Ñ@汩µÂi¥¬TW0k+šÖ´V³!-àÓûÇÏó ¼Vy‚úöîq2×ÄìöhþGŠ|}C¥¹ýN¤I‹V|m‰¤Sâœ|Ö+äõ%<ÓüzýóéŸ2úÂówr)ÆâMuçÁ‰ZnüÃÊΪ¦FÁsYOéõ¤¹“ Ñ[¯ߣۺ*¹£µ©­k1_µ§ÛjH»¤±my$Þá2öf&§Z_íÒ.±½Ñ„”R ˆÖ\Þ¡¹+Z– RfÂö›%cí`D ácI™ Ò ¢Ñ`0zãµW(Y–#+O©ÓM.#]DÊ$ƒqÜ0ß:¤¨†PB =,Oë,SÛ¿ƒŸ¦G“™,ÒÄ &"0¨»ˆÛ¸#«AÀ"«¬å˜ãH©Ž±À¦8šâDK&!fÕE‹æ®þgf`1Ñ`Iš^̶ÕíuUBµÔö ¯·ÍgL°Ûú•ËUf[Wíchm˜ìÿÅÚÇéZã’-]*P›<5ŒJ44‚cýai!¤;/ ½*¹†óBOVöíaÖßQBáK$JìR„¹,ÈÇP‚s.¼Ýº£nñ¢íqµ[‹é¥5·Ž½’e®*5u‹6b(J(m…dˆ&å¶PŠ5w?÷'³Ò…AR¸ÕÒL:v."`caá4…Y!‚ Þ6)Ø¢R@ã–£WÏž©gË#4ŽÎCn²Xàƒø8øüt™JÒH´7zŠ­LKôû£ä/jR‹€ª^-ªØ2p‰¿¾ãY‘†É.íK´Éš%P¿lÔ¤§Æ—†t²ÈÁcŠõ\á/±„J¬¥BfÕjÃ3±fኜŒ3býŸ´C´5ZX"’„¹¬ìßR×]:¹,b F; «¿uw5DÝM¤²©*Uey#±8íU+IÀBQ±J†† ÚUJ (a«RŒê™3’ —'z÷Q ýhãâ) f‡ÇÇÀÿaÖEê9ÉÞÖËkgÜ÷0Ç …S£="¨šM¯‰ªtæm¡4e*ÜH}†Ê·ÝÏ’Z†û"¥½Cý|žÈP¢‘O»÷ªÅ*É÷‰â(³ ‘ý6Z«ØR¯õ¤s¯Q“7d­ƒn¢ÇüÌ7­Q\—¦r੣DZ(U-7]N)?#HšWD j‚É…¢rEŠ2ÕÙµ5`‹–@µYf²y¡Nq¼JÅkeSjL9©àaê±M‡›râ̈’¨È0»UH¾Ñ¹l5q]JÄñÛÕŠJ*mw)凈ü ùóÏ'¤öÃÖóï*6.Â+¿0gæ=OÌBRLÊÁH¶¿ÿÃY¢ ŸŒUbŸþâËžåÏu^FÔÙäxE±¸&Þs3 š!ñÚe a€o‡{t­&*Ÿe Äè}€ê 6ÕtV`i¬J3¬Ã´øÞÕ[6àªÂ¬€·AU³Ä¸)z("@ v½ @Dg YV\÷•ž¹7ºo;ówÏD[!—·´æ“ô²›7EI˜‰cœë>EHBÖ”=@K|f²‹$þ¡ö¶Û=«­ë/.'ÃÃ/‰ ù†u’y\ˆQ?áOêý!CÕr¬<ôsÙù¹º¶»¥á¸&ND~©Úä¢E"ª¿IÛgž/’ÇT¾”¼Y†§¯)½šlkädeAZ½šÊõ©Á¦žÊf RéØ5û(%JÅYgô}Å"wÇÿŽ»t³”5šéYíáeŸ[#85Rɘ±/IZY"ö%¢åŠ+ Z*¯Ä’ÒnÈ%"°*Î]!g$-v~^•YÙ­Z-oú+TwŠØJŽåÿ¨žÖ›ßšß9Ö|×G¨Í,¬jFšbò]¹,åÁ,9%@>xã›"úîݺõÎÖ1>©OŠbãgwÙUWßdJ6X«^,ÝùæCÔ¯¦ÞËÓÞžVwc‘MJÝÄ¿I†»æô(êÏœÓM†‚\á¡U2u—yWZD j¾µHÜ4ëz̼͡gªæÌÙ­QQ†10Òós‘C\CJKŒì)ð±f¨ª[A1^‚=~ú™â|UÂtlo‘j¤ÑËuC+žÐØQÄ~N âÔ‘Õ¡ÜLÒWJ ûaHªÌÓÿøœ×õäm-ý 0j.µ,åÈ´³šµ˜ÌÏýD2©Uë¬K„ð‚ÍÔ±˜ˆ Xö`…Œ;k³sµ¸§’&G‚R'šGA<_éB¥c4Rlyé­'ñakA‡¯A”3§Øó'%N2êÊÑäJ‹D¬vkáˆäØ7—<¸qOh£'7O½÷äbŽ[­Š;µsº.}ɈKÕðÀ ŽM@•_úWt¡VxgË‹øï¤ÛévÕ{WSmVW>¦{õ°ˆÙ¯¢óvd„™“·±fÖƒ—È)ņw’ü™­å´6¶-Ÿš¦F2 ~©D%¶Ý”ô ®Ã§ÐmÇoò«õ±eÅþæÝÄÀo^ëPJØ E›7Úè ÿ–÷Ûx-$¦øýKDÆ‹kŽD»,áÚŸO ƒEËÆÏ_çe”›T1¿¦Uƒ¦Üxåçù;¶^O¹˜~¯ÿçsýJÒ{¯¶2†•Ù’È{E2±cž9$hR ÍW+ d`¹ÙŒ«˜ Šˆ–§xg͹~JÖó™ÊþœÆmUF°åÁiB£¤.šå6<«uO– RŸ‚.ÉÖb|“ç¾wÅyˆ8EiÔë  ¥œlË¿úœ`¯Ñ€Á­7¢´±«uýÍoëëH‰© ׳7ùôW§ vÑ6Š£OQuÚ˜¼Å•hV%Z®±F~7»U]ªHß¿ÕkÅ)ÿ›œÏ TÜ6¿JDti¡-Õ–º ˜Ñrü¡öõ,&áñÊP©–)àí/a(É'òƒÿâh&Ö —Ù§,ˆfÚWm‘ë6ÆKò6†±Í‚:6ÿûÙݰvz48qIÞ-LYÏ4˜¦(HËqøšZàúN1L1¹" VI(–B'?…üõÌys¨[œo¨ÇñY‘tÞꊹUbYäãÚNŽuÊ=–)HßÖÑÇ0dºŽyî.Šý5x#Ò’Àqž3Êz¢÷sýEÕt¬iÎó(‹2ï'ŸÓ»Ã©’õýfL9P­°—Ô±ô—&¤rW§—ÌhŒ™íäŒô´›U†ü‘&zYsÚFÈ´Ûlò€Ó#µiDJÊ´“‹Ý¬²7†|ýäoL]V¯´ÎÇ‹Às_Šn3Úi<¶PCÒ‘1e BÊ Ç !.wRÿòŸ^:÷ÒÀúÚ9`ñ+¶b/»oªÂÙ¸ý^y? Š^öî)}ïÕó¦FqÉÀ°ãH÷s.9H\U³©@°üþ‹Þ:ÚÍ:jàç)˜¦}A ÔUVÊÌX@ ×ÍX KÔyô¬*«T‚jÞãPljH:i‘zÔ„d‹ŽŒ“ïöÌ[ÜCaƒ@¾V1â+Z ŸÊ#â±f¥ èwøïõ£“êÇÜÆÐŠz‘„UÈsFÎ6×8Ȼ׸›R”ªri¨HCÝw=×Ö—ÝÁè›AeÙ¹… P*¬z~oªDW/îr¯÷üÕ¼ÐFÖ± t¨È)½-I°&žNæÓ²$ïŠhÚ0d (rJ•+·w44AâŦ²å£]KOV)&L•`VoT,œ¸÷—øk?ÜõT?È·£Noξ0ÞøÖ¢€¶Ž~ÐåÓŒ‘m ¬úæ=UéRK €Þ­‰‚/n;Ž«ã{nOqfÒÎy‘’nT_±‡e¬D»™.ß1ë1Õ׳¹®:ªÿØÔXÿ¦Og7]góŠ .[2EÔ}RbD{ò@žàšõbñH°`µr´­6¥­NLÿ—/OÜ¿3Cù6C¥Ï.b&Âssúoèѯ©FëlÈ]ñ;GÊÅYbR¬ÂŒå?O5c wi‰ê6™«:ã]Ä&cWšW5½î¸ÀqÐg~i¹;LêRl‹TÑdE!‰°Ô)–-e¤þMp›…ùsï?’§ Õþ·^>†š ¦X¬6–|Œëh4Äê†Ïm].|÷Ø-|ôÚLHEçÓÙ]³:ÖN…FÇÑF¦ß˜Á£û›Õq´n«¬ã±õH½TÈn‰‚‹Z)]RØ0wÛ[l#®Š¥ ĉŒqˆ7€,³åWB¢&mE ›ë"âpc‚þÌòW_D7Æh­)‰]4•‰s4Ÿ"gŒüÕ³ QÒ¢­” W/þf#>[´²W:“#+ h³1™S+ Xò!ØU[Õ‰•—h¸Á¾|žzåg"FÈM8e“Á°Â©ÏíóãÅr5– ¬IÕ‰ÐWPT²Ô/Ά…ÚJµá‡©[}¬33Q±ª˜¨´,+ÀèªÈŠž*²ËyC™R®¬:fj¬ z +ê¬E²¿B÷h:T]þ©ì _UeœÅÊܬè´Ët¯Û!Ps£fqÄ×ÐÞn‰j²º¿s,36!¯4EBd×TlbQºÜ·IC$P)u„#f¹1’-<ýÈS)”mV¿þV#ñý(]rk¨ñ3nWk[eVÝŽi¬xù⮼p¤fb³ž¿±\«°8Vôj° ™j«˜°­"ª—dP2:ŽËšj!eÛ´ØG[´¸,¡áâD‚ª2*fÈVMbXãŸÁ”&ëD¤¹Øa` ¿kŒÕ5b®S‹,ÖÁŠ^…!ê ÓÜDú3 ­kÛÞˆçö®Á(I¤Š’K¶_…¥?þ †[Ù¸hD‚ûͨy’©÷0bÜ#ÿk’†÷”ƼÍS¥EÌ\ß(bÖ%\vˆá BͶ?¸sÃûA ¨ý&‰¯núë1Œ…Ô‡aH«f‰öIäÕPãûN”Øià 2õÝ¿¶:ɘÆróe&–V=µIGo\Ô‚¶Nhâ~*ƒ2‰(¡Â­¯\b++ŽôXVԊįA~8x…“E*@U8 ‰ƒÜëR±ƒ1`¢ØÌà“Qi!±¢ f$NœÕ%UÇjÙ‰‰tÏ3OнÆÍ‚´O»Ð“NXiÿ¥[V´óúô1w./ìBþI‹$ÁS±¨qPÏн‹JØÕŸ‰Æ雹,œp¾›Ž=V#…ó^+ãñÖC ™É5ÿ†¼xòy6k‚b:Ý H¬ôL„Z÷¹mUÀb6“QZ–’é^£ý_°ØLÁMZÞ˜­‹¾?àzE4òºf)Qïgê°!5·l÷~§³˜ûtÒ"⃺P©¡ ±\fD «o1ÒV52ëØ†-æ¢ ‰{V±+Eou¿M×-¾võr´!*RöÏ (AÒçQ¾‹A¬’fýíJ† ®‚ò`YÅÆ’[QxŒMÈ“â-fÄ«+Õ‚·0—ŸÛhXâ•b·9‰*VšÀKvëôƒP’â÷ê´dNšš#ª´R$°9UZØ ¡LA$yçÑxz”_sƒ—‹•b¥âºƒ´y(¦¼óócÇÇJ«h_²ÂY!}Ê&¤*¢®3Y•͈­˜zHV%µÖ±óŽÃ·~«”ß•­éþj]Öþ-„çýP!IX²ó-®²ÖN`Ì1_  y#KŒ6a{ÀézÒm6ЛqXlÑù©aí¦^BqØ_S¢ò ­ˆî|éok†óYþÃôHßø·îB®±@®.6œjë6 ˜â]]e… 5aú^êR¢ƒÕw×n†*ª¦RO ˆPú•£è©6n¡›¨Á›ÕhT;,¯!¹ ²¤X¯Ÿ é½·¨js..7«!*ÅQ¬;Fæ  Žiˆ4ÐdD̓ t„¸h¶pÆÐÞ#5HéþQÚ„¹X¹ìßF±Ë ¥ï+‘·Ñ L xÏÆŠèôù'W§Ü~7[µÎ:ê,ª&¸¨Ä^÷` ª:•ÓLï°b]dªÔE³ÛzxôÌæjfïêˆí4¥ ´†£<ÖdƒXTã³Ãfð°eÞGfÄßÜeàe*±xü–]“Ua*„‘Øpr¯1Q(œ‹ëÃýŠVL²ÐÑ•Iz¿i¢BmQqÖO¬yô°éxÍ›¿© ovIº¥M¬c•®@=t—Ó¿§­ÛRÏ©gˆß>E j7EŽ ]•N÷ðä9>â:[àÉýKWgT4S4FáeE‚DÈšN:};Íl6ET¤·›üùå¸ã̦æyãþ[ˆ7C4Ç¿Q¦@ÑÑÞÇj´3Ÿ––1d›gÄÉeÔW}¡æßHºéÙÝ[F‘4¥ïêô‘3H "©Õ`ÉíBRµ¨ïpˆ5 ÿ,Þ§ñü[Ë Ç¼ rÉÑ÷Št ˜ã ‹½”p.ÛµT0w« Nš—gë‹û‹üQöæ›™©åãàãDç`ŒÈll n‘˜)U$¾ê½Ä|ò}¬fcé˜Sê9Î1—Ôê’A^š%íVܘË<øê§¿‘¿T{žgò#܈ž]Ì<]|ý‡ïU›¡)¡l—ªlY³]z/ŸWZ\ßZŠ…†Eq ´)ÕŸˆ×ûn+j•øÏÙ_·ý¢³Q}Umiû}‰3xµ¢b•ÎRËe†Øµë6`ç9íY™¥ÉZÞÄØ•™=íQØÔ­ ?\T²_øß仕’Æ‹Š,Ëp²™Š ƒøÞloJˆµ)õ–ÑC [–·ú Ö]¹¢âéøxøHV @$æß@¹ð-|‚A®ž¹c\Ö2u\ÜŒü©-§rQTÿ*5¿d`š (àñÁ¾~NNg ÝÇi™–3I½§ÿE(oe —ú~_1ˆÔ¢ef½Ë MðŠT¬X˜€Äük­7l+HˆbÖpmfÙ­@@kúN†­µaaTÙf“¦‡ë©µù¥”ÁQÌü«TÆ¡Ž= Vvou¤—©7ˆ"Ñ­&¦MŠä}© jëá# ‡— ÌX¬­`šjñ ¤˜ã £ôˆ-ô®¥Ž¬š„"Õ´EdBÐË5rV/µФ»Š Å“CƒÈþÀ|òrÞV4ÞÑúGÈä~?¯4yÿq×ц" í Š2†’\ŠØw)—dRà µHJ°µ.ÏÀa ÐKÜj‘ÊšˆÑg'?:¶i¨¸S+#ˆйÚ÷jÃþ¼m‚RÐa¶Ê¦LKGi¹°ýÂVBwX6‹U–¨Ã+²Q˜´†VÊRªã5v)Õ3V­–\öTµn”@1M…éÔ«.Hÿ,¿[ÕvWÏ\c)½à£Óô»PDįeF¥o£êUÏ}먎É;}6b÷Jÿ)æøóñã⺀eÙe˜OäŽò+þ¼|uí–é_‰è¡3ÕNC¥žJAV–,9°5ôHÛr 4M#„y™¢° TèÝõtt÷é€-.,ð &†#‹Ý/bHOø'þ’ݨúS%¤"Dëã’$&»mƒ¹y…tÎ"HäC9C°³A5 ,´4* ¿K³W °ÀÛ +ú†¸ÒA@MÐwÝv8ˆVú'“ÄÊÍXÖ´´´Ü3U þCZì7£Pˆm}®õ*K0"œÍ‘5 ˜!îTöÓH$*“Ë1"¶(åõa§ádåäE´1GwE*QjW›³tÈññjŸÅ'©ÂyûS Ò¤k¶}6dm Dp§LîÕîeÚZÚ2åbka. F×î)ŠïxþòØõ9ß¹fU¸jÞ fî6hY«?#•¡Ï®°ê¹>ë—ì‹s]èÐ&o=âoo.XÚ:¸§V¶€3Ý"]§õ¯G½oúA‚ÒËÈa†T€Á€¾¸jà¥óñ\Tøû Éüš¯`A±– aJѶÌoŠà )rï$ö½Z€Ú±SÚcçɽí¦OrO•ŽÑã\¨Ìª£{Fv3Xbw•²,H:ìÖÓ µáÓµ„ó”GDrI•–*4ÛÀ<ŠøàütYè¼¼'·vÛÆPæ 漂HC†)è–+–moi-o c쵫̷ó'ê[?_µä<5’E«¾Î6UÔ«œ1™ÌÔ»Ê`°Ozß6¯koJYé.Ðg,Geƒ,¡¥­WÕç¨?z|ñÏEÛôú«åJˆÌ!b+a‡Ž¹VP Y°PÁÛ÷IU)G£M†¢¢eø§—º¯-ôû>RòP—ÊÝ톉DY3“!t®ÆÄÌÐiÝR+38ômϲê[WïÚÑÎvšõ†J¾”蹦¶uY·6#ïYöýÉ#ÓŒ#y?óɯU»‡HÐN‘‰_w¨(ŽHÐ)’jµ1“©f>ª ­ø‡ ÿÅ?“êÑ“dL°KH¯xaFN¦S_¹ACg*hÑg÷ äjå/ÁàÿøÞ½îžØxn¹¸b&ÈÃÉ• ï,@)Û)$ò£òiK9ôì’ΞŒÊÑ’y@Õòn¹#Á²8&Ê€ÁqŒ0E/Y¥ddW©,:ØÑa3 `°ZZT°'>—ʰ)=äëHVSÙ3BK™¢Ú. 8ÅjjŠ!ùÑ@ߨèG7)rÙöPóq¬¨ì‡Üe7ÜãH¨4ÇÝ%¹,³7¸4•)Ì¥Kú÷ʳGhã>ói ˚ŢäÑ1ËE–„ièž Q|–ZL ˆ4(IzU‚ŠL ®ÐÌ€~¡ÒAJ3¨Wð_Wuê8ÒbáÉÅs7÷0‚GÛN,Ó?›@ø¿ÇZpq&3Èv•;9ö²ùàx»çÍò ‰ðí×$¹[‘ «$ù®'ý`îü¶ ›:ša·Æ¦°Zµ©[¨Î»§¡rЖL”=vUH ×ì`gúÎR^-Z°k‹ýÚ‚µ¼M¦–±öü¶8?U&ÞO1È6 ­hT±'òE ¯ÏÁùຣb¯<Ðøøçñÿ·^Gjؤ¹•¡©KÀYˆ±ãçú¡a4B|RR¿þr~1UaE‡CšÀ‘®E#*ÙŒè\+(ý—·ÆöüÐB\µ[ëŠÏÞ Ë1P)[£ñJòBI@½Ù0û!kH{ß lRˆ1"ðøRK@Ö)õ…&/bäXÑv†6ÛqA?¼mªºZ CɬõÉŸa/FY_ŸSgy˺D4ZV%Ì`Æ.rç¹Â½šau% ¤E&Lè¥ÄG“ê=…jQÀ[5çóÖJê¼í'ÿ¤ 7ÇÅyýê¼ò:Àð³y0·’ óÅ ëI(®Y è% 7“˜LA¤Š0—êl£fè°f_‹;SFGQ×ï»tH׃Uò• _+A4³'©Y°Ë ·y­èf+h­EÞÅÀ¹ºØò°ͤ¼@ï”ÚÛ== e¾ž¹ï´™á}e\±í(*î¡e\a$ͯzË9¹‹¬ÚĸïKÒ–æà®& 9éP¶´¬ºÖ cCn„â@\®ÆÉ *ØUQÉn:Ù¸= ò*èówàÿùéß‹Öns† øÍÑ&óNµ~ ú7Qo9Áz2 Kp¹iùÉmu›¸N9Dúq«2¸¿ä¯×‡óÁãýGôü¶fI,¶P±xÿ‚™ñrO`7~F¨EâÍM¨A^t>·ªÊ† E ¶%þ^”¥ï÷S^n‚7¼Wîû®½i`Ú솀úivgóÔT ïRV-h<ì GZÅe‹/*!Úã‘£´ø1í<É#äüu3OÓ3@9¸xÙFæ‰d7Áãxe³Uãäüž¬7cùWþI¶ƒÑõ§ç•dd†|>Øœ°`ÓIdYUæUÊU:1˜À€‹€Òª±?ç@Ž×ò‘ü‹7ƒ>¼}X²¿°~ú/ç/&œlXEb3à)S§¢à¥ÛvX°íRÈ‹QÕfÀ-I€chžÕý MZù’…¤wý1aK µÑ¹-oÿ‚¥9`£€Sð¶!®µ˜m2]Úñd‹h<Í5V ë)Q´ ÞÿhH¾Œ#¦DäOÞÖÇas±²]CRb¦LÌ™XŽg#wjϸWäs㨋¡h ÊhúrÙ Î!$¢‰1V+ûññÔ¬ò÷®oW>pçYå|¯ê{Ô•ùYË=ù ù¶ïyæ/˜ÐËžW3º}7³îLöè2e´Þj®®äPË‘6jHÿ" ílðVÿþò´¤ÏÓ»rcÚ•¼Ék7-†Z•{TCƒ£­}†»$v¹dŒüéö½…Af>¹…k] ŠÏ×#ù-ÿrÖ‹1J²Á,*95ÈDfÝ\JÖ²ãŽAZ|&oó#V¯ò,€aûæ>‘ýƒcäI‹ŸÚÓY‰6nAÔq!Ž$É&ö!RyüþÕž.¡ #W¥Û T@-WÉ<Ÿ<¢8xŽH¿×.»&å¿ÅZ×öUk* à Ë•IP“åS­õÔ‹žä?Ö&¶‡«?ñeG™ŸD„rÝÝdÁ[¬‘ Ï­J]}ro7rì3°Ç{Á˜(k#׬Ìç }C½Ö´fCŽÊk°fHfÈÓÙP† ‹m]“ƒó­b¡ñ-ÑSœÿ y[·ò;×s§ßÐÒÈ¢k€Ä ×¢«í]aÐt¥F!°:šµ æ$³o”û“zŽÝú.¯Š¹™79 #ëÊÖ1ÆTû}óÇS{‹¿1ô9†62&fQSp‰?‘Ðd*ãå -ÆÛ&º½ÿPÿËSœþަ ò ÆÕSèëDl¬ˆ”¶Kvk9=01ðdóa¬ƒh^¶H™—eªV¦Š|¯å>ËÌþBè{î×`Úö•ÎÉêÃ&Y%þDª™©-$4¤šrc Ô縢"Ññ-¬É×<"—­ko™ ï|þßœ@­Z-b’_®µ­F:V²9 ±;9kè—A$‘“¸ˆu‹MmaÚ–šûÄ1zÖ²3Ïè¾°Ò*H5K[\Znéši"ֳȩFR@%‰»>}¥y¾§uÞêÕ5öÿ“_|xQ B¢•¶.H;yj ž,ßKÇúÒ k9Vo´º·ÎW*õ©O2àËRZ¬ãLV´Vfh/ŸÎñIŸrw)Í[¥WdeúŠUmmçP‚¨…õ8Íåë]i,Í(ÂÇ{HD·ÈR¬© /J $¡=¯&7Çôò\~¤À ®kÀ¿Áâìž—™ùË!tˆìU6ÄþÀ€çýÏŽk¬\C¨ÃSÀ˜ûRRõÌ9„H´hWò)2Š£° ¥'Æz ³Yeê2¥.ø¢æ‚=6<È$Žåº5b¬ÿè®{ ¬u 6—øÎúû¤oEŽfJ±³ÖÙx¢^1×a•³ìi}ÌúëIÓûJ½—Fé‘qO¾»ºEÎ䤵a*ØÀj´›í€“‰*¨²®uò ¨H–Ò$Ä­DB}*K Œ°­«i·hùt` #Š6kžâ üõF$Ý´­›4TÕ›µ_<ž8ýN=> yu° Ñjö«•}±®0|ì|¶0YìŸÕ+ FJé©7h„©ž$¡Ž˜cÑtg ¤oLÖ´–ªAÂ(Já55üÔýT¼÷­‚±aýöØ5‰(nÔn¯RÊ…‚¡[îR§ rļ]°ÍÉq^XøÖéÀ˜Xc[åðHEuÒ´À(ëöøVm7­IjüïH­bjZÌýc$͈IµâþÊßý¾3KÞ£#PrÍrê¾Åü¡B‚î~lüz¸ÅÀ22<ÑÙøqF“b¼ÿNzT³–#ö^ `MíbÜb›Ž ‰¬þiûb 7¥&pOÆgàZVùíWø›ôþ+z„K¦ÔWVr8dÿ^;ÌÒo?S¢Ó]”lƒ‡¨‚“BqÏ.©,\aË_é­ÍIЍT˜<ÒII½æ¢5~%Vô™÷³C‹}mcá4¨æÃ¬”àš×îëãø.ðʘ¾$Ïë5ô:½½]Ð%Éù¨rkaf>Ác,ÔåIžà’>ÑhGøÞz›cè Ü³å·ÚăL62 ä᮸¾™—¥Ç>±Á‡ NLŠ.·)ska–ùàÿKë¤/Ož.ÍKšÂªÔëL„Üjt¢±&ý­ÐzÖ¥©oîE®#áTë#­cåmO0háó±­euDMÏè±F¨ b†-c.Q‹¨Q-1¨àa¸…–(ÇÎõ>æí)Åð«ë,¸Þ}èdžñþà„ÁöV±{Z¡! #^F·²´0``¥kPªü´êÅéM+„L,ð Õ(íQPÐ5¡€§"µ´C"‚€„¢Ëˆ7Ð;ÞÅ„f²âàC†Š‡#+kz‰Ã¬Œ…BƒÏ’ydãÏN­MŸ¨IìðãÆÔD¬H …Nð »Gû~\Æÿ0ž£õ{!“ĈhмÂ.aî0l¶+ï,¾ú³r³¨¡j>WAdN&äzƒ5ˆEÊ*޵ÅáîÐn&FíGu3‰úó¥šÇš]5Z°J´†ÎdÊ!Ci²¢R²Æ¸AqêëzÅò¾Oõßog1&Çϲ¼î|[é‹° þF c¡{Ô³]kkÀ[¥L:«õ­6‘JßäoÆÚÒÂÓSg<Õ]°ÖÒ3Þ(È(+}ƒ5HGÀ±`ÛâJWì0•¼È¾³PWBv&‡¤i˜ÒñæÌQiš«ÅÓ- ¤ØƒÒ¾²·­êrFÅŒRÍ3‚Oò¢ pi—l—îÜÑzžùŽ)uJ #•KXíSXï š‹Õ6ƒÀ»m û‡G>969¨ÃTÁp0iouI-¦€ Gò4ödW¢c¤’ÃbCK}g=,¼ÉERÑŒ”[àZ;™‹09ŸùÞIUà<àªë3õØwümôZÿm&ØGQ°QÍ. Øe=‰O$ˆµ®:^õ?ØF&Æ e0 Kвj6b’²þë'=,½&±¨/±yýefGX›Þ#í‚Ù É #ü}ŒoÏc\Ì\ÿÞ "Q#®0‰ËÎ1â² ©Ø¿ËÙGÁ!wsÁùƒ }bÑ£ðkŽ?oÔ_…ŒÚ.3Ð+냳rÏê~º§p²{(SÝý£ÄRP JËSpŽŒþIÏÑ+9åšÙ ’ †dOEæÅ!$PF –ÿ•¯cüE4~ïaÿ¤z ºb£¸è9‘/Oj  µ†È [ ’JüÏX ¾«5q8zXC×i }zö¤L‘QÄX‘ZUkZµ¬þÑò­cå?ÿÔÛäH¿Ê¤´Þ-íškús²ÿ!ÎÕ;DXÉ[lJ?ë>xSv>œLlJ ²ª“â¾G?ûrµ í1ù@Mc}`Í\¬âÅS(Ç{DV‰øÐJ}W:ÖmV-ôÎ:|¦-?Aù¾¨¬‘pÍ1eGI±-ñƒMnR}s7+P%`à(&‘xMTC¼{$¸2KuµÆ½#äjC! 6.HJÄd~ö¨kbTv¶8¬Q¨‰­®H¤£ú®Ô¿ôÁ?؃,jͯ½+ ÆAŽÄ¥à²s]‡Û«¶Úè]þ|Ÿ¿â®#T|ññGš??ïã‘Örš•­ÍKÔs Ú¢^¤ùÔ”4ÌáF+i Q6j¥k[YŸÓvI›5"¯‹‘rÅân!’cãAÜŸPäµ5¬©þºÛíÒ>»›ôE¾—^ä›}.Ï6½çÙ€’À¯ÒJͤÕdµºòKŽÅoX }°;Š“Iyoà°5«î!P@¨ pÄž-unÇÞ*˜„ HÑ(Xµ`‹’i6t€ÌÞ¸¶7’¬sà_ÅxÏÏŽµˆ|yþäïý~zP-ÈK°r= –´»Ya–伄 MþÖ=è«§0ÂëQp•d»Ö”ôp³ ý–•DJK4øØùn ®!HµL¤Ô_»µ YókQ&ýö©J@É– jØV‰¡&l:ж–o'Ï깊Žmð’ØW½½¿ÏKô¨ëÿûû¨¦+5¬ÚÖ¥ìv‹òöúíZÍk?ó<Ävê/£8ƒî ,Øâø6|~ÿ‘篞Ÿ5fÉðMþ?óüëøéHËŒµ=>Và¡#ë­•¸‹kÄÁ^E†ÌRI[Tš¯%§ßCA/h¾Ìß”E~ÓIKíhˆzž—¨í!4„fb.)¹o*1H€Àþvó'h*Á++ŽŽ×‘Õ¡.í./©o¬²UlÅmCW¨à׊Ò÷‚WïO•†>+ü`­É2÷%Ô-jÏÞaÖ+ðý1zÀ‚J‰‚‹éªß<+T­i,ïÈýCâ¿>OYÆê'šžGÇоûqÖño17‰]`T(m@®2Þôµ~§*F¦)sµ%=⦥NV ¸ëRMãTwÁkX•¸ˆÍha}ÏÙ`šµˆ€kz€º3ªRV[+%XÖ-¡[Ö×b´­É·½kKÚß¶–Ü‘H§Ëì¼Ò¶$@¦ñãd?ñ%"â-¿Pপ䵯6EªX `U,‚Ô :ÿÄgøÔv_!©£ ŠdQÇŠ?ž? ñÖÏD±‚§l~߆±WÍô¨:1q±fOZE½ÖUa— AA«J[邎¿c.°H 1ý¤7ÎNþãƒÐôy´Ûò-µ#«†·´´[±úïV¾‹d×^Ït,Wô¬Ä r}  ãí?[÷R÷´ÐD7Ð^ôújY’œä’”ér^K_fdoÒs¬%X0Ån|:Ö~M7ÜU•_7är´€ K-@Ù¶ÑSCî pÑ$t"¡z­|Gf‘»Í*1NòîTÓô©–!éË:˜Ðo³v»…Oé¾~|ßF]¡c\U4`Å^mÛö©¯fâÚKÏ‘t&À'ì(àô1Ýç)Þ(䇾„„}Pÿ ÊñÐçùªÛG¨“,• 9åXßI™t~ ¶r¬J,‹²Šev€VhrÈã—«¿STåˆoðå^ óR÷×uä[¤šôQÛ<¢Ò{+k<ëg·QÞ…d7RZ`F§æô¤Ëš³vŒRüšj—ÿ²÷0ì!¤lu÷Š>UÍJaÄÌ‚³+^ØíeÏ1j:­ífõcˆ äÂÍÑÁ yãóÁçvwøsK¥é;„± ÓD ¢¤<Žhmù±ÒÇW×ô]¾Û/U¨æö›Å4¶ö›Dt“ÿ˜?ÖX" ôú­í*Ö-ïˆA¨ëkŒqzÉ~ËW·¸ÅXˆéi¥ëþסšübæ‚IA@Å>6µrI’±I°½çØ¥½bö‹Dýð"…±kI¬Ó『¿þÚÄ›E«öÆŒ zŠßþïâRÅêQÍâQÐõ˜¨þÂÇÈ3qÜ‚º³i/ÆÞßã†ðá†0Á‘Q•R0ªTm¶5Å|ÏI|™BÓJÅÙ›tdîrm‰Ýî$“ò?úñ¡ Jû =­jâ­¦Ôƒ)4½ê;²:Tö± f s3ˆ·þv‰¶P`~ã%¾L¬½ŠæsyÐa–•p,Êí «‰¿%?ÖÏÍÐ#±oY³w–_;GAÀiuo(¯÷’1Zh䆶e•>L%vkY:åûY·Óq” )‚©ä(ä茦\§—šÛþò3X­:êHŒbYŠ‚ô¦ºµ¡Øh¢!Ù|V™$¢Õ8 [V®¨@£ñóÏãóÕflŠLA„j×É ¼ª¾> €Iä__Ԭɚë7-á„î½¥5ízÙ|ëŠÍZ¡°é ¶EJ‘1Íì¥ÎdÃtMÑÑašš° ´ûÚSò®#ßöÔŒ¶C¢(©J\6Ñ c¶²Ÿj"!##¨½!{RÕYJÐå ß‹ïi¤¨˜)XY:Žá¦ãA>ÖBTKºÂ:¶WP MŠZýB« Ô×\4ø|€KDÜV¼Ž…Z÷¥¬1¬jHF*¾ÒÇ“d]ž?ލ^FrTƒ·ÜsVx¿ÏÈãóÖÙØ¢@(jhÑQIj×5Ki‡è0­ð™ÕÛø_çUC5B‰;±PgM×UŸ7 äÆ(ã ”§™°"G[e‘qsË©]»X–V N)ITìºuÌ·ôÊ}°ã …Í"Ë24H!P¹—©¿LÈ¢²Ù‰bUI ¨Ž|Z~áxK™@ü¾-T°¤×—¥¢ó+ÀWú‚RWç² ?ž¤÷(Î;…›ºF…XÀ–y Ý\PEMÊ9EŽ êïLÓÆÔÉ™wWü”à•¾ o@ÿO÷ëÕoÓ{-&‰½þpo‰‹ò î8šÖ•´ÀoKÌŽäæŸÌÍ«ôД*ô±~¶$ PŸ!Z¤< å$ j„MoJÐÔAaÅAhŸ§?Á[nS–¬OØ™f—öûijÖš†"Ð k{R•‹Ô1ù– ä“OrE"¥¯¹«33húîŠ×Z‚›Mþ&b"Ñb& y^-Y‰§Æ4Qâªmß=fÞ<×§Çü[£ooÀ[ñÜVµ¯÷©ð‹ÖÂøÁ\š ã3 +QZkx‚@íbLMI3í^ò?‰ž8üφ¸<ƪí韇“UâO¨Ä >y$œÁ“Þ.D«4»-¯¨¨˜ƒ™Ã¯‰x¶¼—äo‹Îµë}]1K4%U­h¨"ï2ÙÔ)) …D†ÑïE—pæµY§Á±ÐŸ¢¥e'œç‘Lô³ÒXi@*z®EîApÞ&IiVâ-åUb jÊ^·üÿR2ñ÷hx0÷dI$Œ¶¥l»ˆyüýŸO±æXõlÖ»ô ‰çqK¨7|Ôhƒ^>:•ÞWß;Íèh7ùâËç¶Å›`Ö‘ £E -XŠÒ)°—º1Pe) j‡ú‰Ê·ò5êD|Îa¾®“åÝ€µ“‹DÎÏÿòz”œÊVnŽl­M:’‰Œ0)„2Ô.P·oë“ÎÅÀ:ɹo»ól2AAtWlãq…‚» ­-êÑ—„~»U€1mJüíFúþ¢tÝ›&™rs‡M†ß bƶñJóàüu¿5lÅÜy¸l“÷^ã‚•¦ÄÞìC½&øٿØQ¿qÉ÷ßU# µÚ™b¶> fæ/$Ëõ—놎˵íj|ص~V­kñ-ÇX­íkyš-Z’ -ZÄûL/Êk’„ ¨_û&¥¯ÛSP?˜e¤ÅiCÀ¦ž÷¯ÊŸ¤]iŠ&cë¸)i©&¢›Zôû.2„‰‹Ú£½´K;ŒqÓ°cb!…Ä hÜZ\jñùûuÎI™¶¶ç,ÌÄÙbÄk-tOÁñÅøè…âþ ØÌf÷_#Q‘Â÷åþÄpÐÕ±¿T0¸¨Ü’Ù­–(ì©)iY‘€ƒ´¡Hl°ÃÈê©ÓRh4ˆHjÐÀÝ€8«„‹Ä’L©}E ^ˆh°h*“¤Úèž Vµ´[âaý•´Ö¦ûƽ/1j@I`›ãZfÖ¥#ìù×ÚII÷=L>9êï%ÊÈfD6s€ÊùÖè0´¥Ïú˜Pä±€{…ŠÞ(j?¬ª¸É’©åáä.3lj#¤‘[Ð!‹! ÐO¼=5žâú¤Ô°™‰ÈE#p¹*†Ð*›óýº‘ލ‚««ýž{á…\xÃhšP#…scUåÚx¡ö1ø×ÔjŠ—eØŠÕXºŸG›]<Q:«U€ÚjèŒCÑš‘ZÈ!“oMMf –t”wà öV «@Ü á †%!@R¤M„¶Çc¶Ï¤)JÿjYj\š)ƃÃføËœöÀÆîæ•AAcVͽ]Kž~…VSœûWð«Ëò‘è¿€5ª‘\Î(¬®v´…ÑYGG ”¶î!oQ$a¹»…Ú<Eòk€GT„Ê2”;¬ŽNÒ´+ÿÚ=BÇ2É›v¿U¦„ ¤¡,•šajX2˜¡¼ÃU½Í{Ð]qB54–/1Dq| Xý’eÁZjRÔ!R¢½¾05­"ðFj†GuæK *HòFѰÃK¡ðù‹Ûò¦Àþ¬ø™¬Ù Ôk†&h2Ø5¢‚h´­@Ä[î ÇÔ]ŸËV*+/Of«fư¬*ÄÕ´@ÆqÖ)õé<Âì{p Å¿Þcãab´D¹*Ê̬wÞõ r ·$øÿ°ú(ƒ"i#B¾6‹R?Oéàšÿsdz½eÖµ$ãûfÕ EY®KI`rZM‡PŠö¼ °ÂÄŒÃR„ ï[QªÖÙ(7 ZØTËš|X³ 0RÚ´(;ÞäÌ/½Š*жŠZ)[^ÕŠbÔ¯‘ »PÕú/jB÷5Æ8öÓo´¡¹/i€ûMÏøâo[ÿÖ䊟óbùi¿XmœfµÂ;À‚u–ŠÞÕ‰¼ÙìbCkÿ±+[E-a\d‘çõÖYÓp“|™ ¸²sÊx¶€9³Ž:ÜfÈãŸ4x_Š(ž~/ž¤˜:ON´ÜØÍñ/µ·˜¾hë™ÓìlN .mA"[2¼}¹ƒè°d4¬i³ÌR=‹¤ eÁxÞRÍijÜY«?¤ë­0¼•­Ëýµép??þ‹²¹½ Xh¢ÈÑI¨kz)T‡UCcÈ/U¯V,ïæ“5kPU‚™£ö?ü[¬{Noýæ°ëzû£ù–@*´®z^•%„Bê8Ù$†Y¨âmi(ÏqØkÒ–€D/£™î•Ws·¤ k#ÇàƒF¨þ.XJܸ¼(âèÐÿ¨çàþ1Úô÷­Ir†•¤Tu”R(V‚¸—ö÷M…xÍk ûU«Åˆú¥ijDÅ«Z–­OÈß ÿ8.` l9[v*H)kXéÍì:Z×dtÿzZG5‚|B¬~qMkdlB^lÕÁX-bâö¹)H²äÿ¨ ^ص¤ò ¹Ï¢b@V+A°S• m1ûÇ{Sj-P•³Ä ¢ ªzÚv C°Ãx*¨’?÷üN°Ú@‚<‚+Çìj?±ç¯Ÿ(_þ»{Ú¤Tƒ¸ˆqVð)OZ³¡b Ö²‰R–¤¬7"#üÉñ,¿Âó@V~‰p”©&Gynô±AQûQ¨d“Qü$@@#°¾èI`^þ=<׿eÒÙêпˆ¸Ú™ðg¡æ?K¢OüÌg”¡ S%i4 g´40sAœ:1ëÔ.ŸÓߤøEŒ÷1poØõ™š¦pÞäâèõ ¸U3óô¬æfª\Âdæ¥òɤøš=õô~ý/—ÙKmŒCn@ÚG6.ÇïCÿNµÈèƒÉ,WÚá˜_šžy5Ï#‹£?úóWt¹¦»^sgÆÞ?Ó6Q´º­£¦nÊÆc/úm÷“ÑÚyñ6Ÿõ¨Ð¡Äíi„‚+ŽóŠNb•û+çg‚WB)¼fYjW`ê^½%Œ¥Ôlv^ʶ˜øÍ€*oÞ—P€œ¶É]¦º¥µÕ ,ã4¨Ä«EMcd×lÄU„Èw[YÜ*èÅóR‚Š,uwñhun¼Ì€àfåúI5MS(•/j[Ü`¬›0Á6}4†EÍ£!Ïq„¾Äôâ6CmÈxØí !OP›óìjZù¡àòYcÌ’P1¨ø%©¹à×Åx$MWŠ'gø¡9F4q|Ì´B³Íuù’^Œ¬ßI7.–“m*䑆l{ÕY­"í¬M2þoª=z„ô Ñújæ×éºÏ*qî IÅ’YD1:׌γyºZ¹Y²ž>‚‹4äæë„lõæg?DX¾Óû5Ôélë9¡hÏå®g3cêDCËzça€ÉÔ­ f©– •¾YfºC zcû‰_É'-¨Ï„2úËxWÉÜHôóáÙýÑ(Ôœœâ¶G”_ÓýÀQ‘{ 2Ê0²Õo˜`’0òJÁkÔi¡Ú@%ϵx_Áçžz±Ž#:ÉPF¬Ä,tw€®çÏ÷çªFð‡=Îèwçõ²2Ì·ýl´r²ˆ9,‰»Ä)7nÕ¹'7Ìx_ ¬¤VT­¹­ÑcøûÅîQ¾iõ3EVAT×±±à5 5€&jòp?-¨´º¸À@+1Zš>òßÇüù>ŒóžDgÇ(i{]_èÉÒ` ¥írf>×K…öL0~µÈÕJPÚ­ÁEó€ÓCÖ<ïà_™ç‡å¼?+ðñžUƒÓ8¸&vê̛¢þ¾µ›:A©Š£@iÆC9Äýaa °×z¬ºqê©©8“Òl9ĪÊËLÎŒ¢mÊ´²|Ñ&‡M=]g´ô|¤—BÊ™?R=O E ubG’IY˜‡aµ‚P<ž —–'¡ò?g¿¾½ilª2P v7B‰LÊSþL„¶«Åû ‰@¤“TfäÆV£áöXçÛ ­Æåo{L°U—¨ê’34_ØŸD‚.¸ìF">¦©`”ëÚ°CE ƒ±"­ý·V­Í‡‚ÆŠ«4‰mTÎÙÃúì¼0K2" ¥Ö\6 Çujà6e•#úgça¢›Ì?Ý*gÊíÜr‹ƒ*ݳÌÈîûÆTk‚ló-qcLh•a ‹ãm(PYh²/æ¨Yê;]³ÌÍyÙwvæ “Ý¶E'ÚG <ò@æÁìfjÍ"Ŭb.BÞ´µ{Rµ©¤Ä¬\ðZÔV†/%¥u†Ë$¬RŸÀ\-Pk´±Dz–ÔŠ^Äþ‚|¾?:ÖßmRÕšµ½~7¤PBù_ÚN+ã¦u’;í¾â…I¼3Z”4¥€™yа¥À00ÛSVô\žðïËJT)ëYÎb:PaÌ"êþAü¸KKÉ."4ÑÉUŘ*­@– ·•—”u7wU`¬¼*hë Ž°Ïî"7ecHDò`±Àó@Çÿj=ôÖ²Óh¬Øw%êiV"’bZ±[ ÷©k­íiû-´ÓâCE½ãù}ͤ D[C@T"¶Dr—á ý픉/ö1QUx´Ú–`Vb¤ Ù~ÇïA—]”¢Tƒy:E›©ƒu˜§» &5þ£jœ`][ÍsÈW®Cüýéò1Y­•b½td7:„¥X´ýV7Î׺µ˜¸èSEðƒ°Q³[Þ#ZÁG?ä˜'* ¤Ž¯~ž@³Wàr>ò:Õô´ÉZàž\u"¤tÞ”|Q,*þ~|~@èÇ„/ ±â¾Ç·+co‡s£Àñ®¶‹a£+Ói‡wÈxP“¦Ê"y/o;_¶š9ÛXf\!o$ºR0íw5αѮ›UX¥¡H*–ßgÚ­X ¡¬Šð(‚ –ùÒ {dV§ÕQ×ü™ö>™ŽúNSÆø¼þ/«Ž[3c¨'öVó'iÓ7â¿/릆måðâÓÆ<Ç&êêî)\4£¥ß囂éhJ…‹$÷€Ž "ǼÒõ© ö-(C^ƒ§±G$‹Á&Ô°jJÀ«©#ü´¤’HÐÏ-K1>¥U€J×>¢x°ÖÓÿI'áXŠšÃö¼ßÏócåZèyÞ 6 I×ÖÚÓvYÑýf‚í‰Vþ¿ÌØ­Q&ðªLKlmÓêÿU†‘iûl), 0IôÔjÄÒó6“Ó뽋A„’*Ôl¯P”ÀšÉQ§_M4IG“P¥O¼Èb²?´”^ß‚ä°7ÔÝWÔÖ`ÀY¤h0± 2DHÚÙ€Òp?KF-ê°Ç…ª:—­¢ƒÿöI­EkRãKhŠHæb>1I½Ä¼Õ­ ÀíAš£bà-¼Þ)y™š¾ò9øTr0Míh¨;^Ô™ l9¾ëÍ≱…%²‚׊®Å„#AžZkÔ@¥¥N­Íy1 2­†j•dcLc±Œ¼©Úþ|ˆú­"᤮ÐEL)à"1ìJ¶_cŠ&•ûBP¦”´Ù‚Ô•5ôœŽ9„{GêbÇâþ+öãþ¡`'¹9#Å×÷ùãñ}$Z·¬h9©mrÌ 4™·Çá{ûHä¾ÓK^Öµ¿ã_{Ìü,âÂxÙ[xÚá=‡U4•häVä÷…ÙfÐàI Š’Du/uY «[ÙS];±XæªVb’jis\”®IZ‹ÒÓì)¼\¶ WžßÜŸ[¨ì scòWÓ\²[ b‰Šý-PâJ]2ÿu.Aæ®àfâ lÑÙ°Q‰æ `ü\œmÒÈ D†XÆç“Ó¹ •b ïb€âüù=IŽ/º-q¼Œb.ÁU˜( I5ÏÏ>Hu#2wOªÿÐ%j&ÿn¨ŠÕŒ4 \är¥X%@z6ʈ~‡ÄC1´þ~†{zÄÊ]ý Z„ÏU$ÕTCáKæÍô“Zþƒ5G^£Bmz$ø—SMh>‘¨ck=pÿ‚[ÊØÙÕÍþ˜ŠÓ0>‚úš,“M¡»vt4¥²·› °Ù­Q Ú*c&yÓªó\çu5|‘š{Ò³ÐîJ÷‰>sË)–ì WíIã£é£°ÙÊϸ±þ£*é(Ž//&P¥Ú0ícÔ_xÜp&‡Çç ç†ÙÖ0HYWp*FÒ°|_Å“kùˆ•PúaÑf,ÛòÉ?á–ô¨Ñ³o®à3Ô_áMIÖ’=#OaÒÖ23cÿÀ…‘΄µ"µøWýÌ0Åoó‚\t÷ëbX6û>¥®;ÄÀ©aÚaÐÞ¼v}¶Û|c,œAºˆ6Ù‘˜+D›üHZ9qX°Uþ²H IÕ{°¥ $=‘ñThªã¤"ße„+#CÚ †Ãëþåf®»K«¤èL«9iU} sÅ3µX¡žWib%™6{UH¢8óð|ó]0»S¶5mc¾Ã ³)]#’Ë–$3©ÈkÁèKSsÄØÌGÂÿ!––j2V~á×Üö‚R´­bi¬Ûå°FA^Ÿ”oEzTKÍ JV±7© _ùEb&³0õ&ÓXˆ¬ÚÕ¬ÌDGƱX7ÓÂMêµ6Hx¹Íòÿñ–^VX!ÓjHÀèÿÊÍh… ‹ß*ʺ»1§ð‹‡üGÕñyWxÂ>îq¯óýÏT0ÄdÓ{«:Á„ì;’ëUZ€P€(¸FY%cTþ<¯µ³d>Ëä*Z °|‹ãö³øè´ý9îµ£þ 87V³cñÿýkþ‚ºëQ FmmNo‹ÞÑI_¶u«ÖÍ@®‰×eŒwÄr;mŒªgÓ kÚj }F̆†š.Ç…| žczoáœî{=j«±¥¢Ÿ'Ëc«vª“ÚÛÝ a¦vps‚¥ôÛÒÓ³‰¤¸Â7ü, AÏ8ÿ-^6ÃÌS/À\Ù{þ‹UcÃ]Omfù¬.wï Â#ÉHek°_UjêÙ‡ßÁI ³B´‘@¢zYóתO6z’ÒÌʬîg`~Ùçyäs2¹î[ ®Õ |¹ú ®±¶Œà ½í±¸àݬä -j¼\&ˆ¢º¥6.Û€»“ºô&^B¤§µA<ØüÙ&ë«0ó¿ªA~8[¥â|_éç’òÿ^ z ĺËÁWǯ0ĦGҪƓ}†B„¥uñ Êÿ]T ¦†_›JÐôªµ¼õä<.Ôï ‹á}Š ÜÄâ¸Å 9„ÍtH˜Ö¼“ZŸyï/lèž4›‹ Îr g+žŠDߺÐëZ\c7›}Œýö¹h=¬5Z$ Þo ÐWŠz¥n»rñBŒKŸþlŠ£µ ß;Gz”¿*Ø8ä…¹¢ƒ¥boo{’(m ID,Ö|qFÁøãšã­E\“¼–$Ùão<üñýë©ëçÖ.dX yï¯ÑP•`›xœ§PvÖM•¤Þz{T¥l¨¯ù¥›ÍŽ¢ÑobÄÚWòÿ’oZ¹„]ô|Ü:rUÛ¸OxU³Ñ°€c#*¼ïß=/õÞ REú,¡½ê h¤ÂP‚G{Š/-ÖÆVÒ@Œ†%äEŠE,QI+&I¥×5$†¨îD¢u¬[E ðj”Ÿa~UøŒÄ’ÈÕ É ­uXø³X( ¨æ€¥âõ܆HuR¤’A±vAý¯ð8£àQê9ŒY!M)#æfø"¼_üu>Íü˜úâ^j?þæP6üŒÒÔ7†|?x$ÌØ‚ «â¿hT€5¥Až§Ù'²ö¥GZ¶ò}êÿõÑ®¯‰ëEI¦ç9%Öv`?šŸb\Žo,:7j«)„¡ä¥í0޶q£W‘/õÕ½þÏ”´9¥ ÿ¼’­)æ°¤_þóÖ »”l[õûû¼òøýs‘5(ê p?¼ ²¥£ŸJ0Ù ò?›«‰A ƒ5vÅXΪd¥†ØÓ“&2ò* ´P¤–P¼Ð@^lu' l™},X™Ë%C2­7à5ÉðqÕŽ¥ü»ú𹕠¸_Oî’5Uø>ÒÅ•îRIûÉ ]6Ä"Âé{’£a4¤e‚ÉãU>zõU¢#ó^+_ —X¹n[-ëî©ûYÿÔ]¦ù.Dùç6œ ÇÒ#º#¯Ì²Âm<:Í?™˜ŽiAzYâ8•  Q¦Y‘~P[=ã¿\êDÁKûdÕ”Af ùz”µYÎrñ^}ÚñGPÂkæ×C.„¯aU³)¥E‹Kq'Užj ø°×µ©Ÿ­ô±2°ÕZTTOX–]K . :%û›° @Õ…¢<óýè~?Òt\ÝÉÁÔ»ŽW‹å2ÿ$³¤RwDó¯$€ÔUTÐðAøéÂÉå¢tTƒ°dn–‘^d¿¤41G“b˜Ôe±ËÞªÙQÖ‚è^ãu[ÞUj"µ‡üíãªñß<„LgÇCÕ¨ÏO@—¡ÂŒdœ™hŽÊnz]‚1¢þŠä®› Ud¤c»e[ùô›‡eõYò.fÁþGx âÕÿU칇ôÜH­STF¬ý•^“['{Yƺǥjú‡ó7Ž<±äl }F9ñÿ`ãº/eô,GÁk—äM³è{1Vžèö² PW€Ò%òB··´-^ ar3ps!‹Ö‘šXÜ@\Ä@$(ÇqJš4E}2u>áг± ÂÓõ<,‰òåÇR•¦1úÑ@¶Ý´ð¶lüŒ’Ž~§wù»/Ö)q ß²™Ì´ZBÌ×EŒÐὬ‰ª :ÍkvYxY³ ˆ:ÆÓË`ç;bÑ:êVµ4&©•ÞM†õÖù¿{0¼E—©£c#mQt³mÌÍ ¢³øô’y‚XÔf¶¯Ì6/ÜiM²µËú°áБa5IAG¡é¯SЭZã Œ¨-qâ¢kÑ…mï¡“›Õñ]HàωµÇ_fïf"öiIÒÔ¬KAç¤ÃsHë>ªäð+Šý¯ñÅðÀ•b‚lZŒÊ»m€–ÇšçÉÝGÍôˆÎ~5A¦ÙB¤šç¯³)‡À)fæ]ý®+pª«V!Š&.êØV‡aqº’5”¢K¦cE’­4FKÑ<ð¸œ4ÁEFL2¶Ü«t¥•²u8©$Á‡Fé—kCìÚT[ß+ôii$6™µÙ©Mf“…`9Î3CŠ![?ÙßIãç‘Çã¤>µÜÙz¼¬ù,©` ¬j€ Þ§ÜÒ×’ ^¡ïØ2M"A¡ÁV½í>Á$¿kY"¶šÜAŸküD9!7$*fîBΤÖBº†M/4µDq/Ÿ¸âšÖ¿ö‘YÞ}éïïkü¦•Š„ÇqSüà !BJþŠV~ô©IZÖ°‰1²:Sﳋ-=®DïRÄÍ~ŠçŒE×[Mzüdz WìŽX ­eU*Í™lÑ2éc²gª¿Ùf@]ÒÍ7ÆÅ¶C{Ñü9ÔhM› >GÀ¿Ïy窩⡠²*‰üíó}iääh?gû BVÔ#ƒêf*ø©¤jþ€¾u/`ÔaL ç*ãA#蔲2˜ÔX#î’Ì¥£ô÷´§±ž×¹ì¯ÚÑZ*Âu}@®©.ogbäV×5ÖW(K}h ‰ˆ˜S@%©”×/´…MC©/h'ÝI1ýÎèe1æ^ç›NL¾m½™ÍW(o>ó-j¦€ô ,@6Œàû ˆiŠ×zêüi ´¼3±P},“ÇŒÀF¤ ÄS7ÈAø5ûÑŽo 2I,êêR®èƒÍ4 äQþü_^/̹þëÕI½½ FIz¦&Ò­œìĬj„%­\%îÉ^tšCKŸw8ãÒo÷ž•Îv ¹Ô°ó¿öô¹ðŠÆÁI¼Ò-¦„¾LêzAu»8÷²û:Ïó¼­“6½z-‘¨Í4™•®5²í…E3¶G·fötcD›Q2ð*ŽeŒ¬”#Umíå;U†6]¹,û¿²EK¼qP®·j,O¾Å‹BÌV¶)«3 ,3Ò>¤÷% F{Ø Š¢Ù6GÍ_™˜!‹ ²Ö€‘Ö5ÝU•…94†‡ŒOŸŽ»%ñw-ëÃÓß™Êîx Ã~päù®}œnƒÓÇ•ɵiÁ•øyŸ$ó*½¥i˜£ ][ ³ß[–’.¢ô;úŸä;¿ÍðÒÙÞ‡=v­Ó² dzý>볆óÀîQìË–o)%äìŒâ¶½J°™¥$e•Ë0ï€õ1äC½¿è+ÃþVðŸªÉ7)Ïéêpp¸/÷½õYèu¼pÏ“yý>Ö0&×Räu¼ý$w´™M<À%Œ)¤y§ÍÞ4ë¼qêóÍú™ªõ¹ë×oÇ> ÅÌæ#Î0ÌTÜÏêÓ::£V-¨«âý‹ªÆt>*]åYæ­[·—HÕ2×Z2ïR ‰ÎL˺ìcÆØË´uUîñÓûHî,ÍsOˆho4âL*eãÇéÂ@QFg+€y,‹^HSóÉï¬2Íuè:ŸèºÞQŒÈwŽw¸K;¯ÇÕ.®•žK[ ù2_hÖy ‡VŒ;q¨g>ûÅ+EךÝy˜$Rb*8‚Ú“Y8¹DE†bò”²)¹jÕ)d¿Emò­©!ž‘8_OÅËÖñ6¦&¦›H²sénkjî­psVÍ×ÝiÆ×G-ëÌË*a箜½¦;€Õhª*Äîð$—¦Þ h¯}³Ý‹²KÒß(|{È!JAU‚Þß1rÒiÝ·øzÌØèÍ hAÜŒ÷$§Ô'Á¿ŸÊ»¼1u|=s%u—WÍÈ ò¢ÿ.E”) ZFÓðGÏHV¬Àüô´@nZI¦Å‘ÌŦ"j`“ìͼEÖ­&•©mH ¾EAÐM¢$Ãú‡Y@+5uïj{Ò ymiø}'4,Ä0ßU*fZ®öõî;þâ³uVü#ýb µ-W¬Ö´0©¬aÖ•¢’F`“î¥*)«#·økáîÆài«Ø/Ïló,Á’U­ãþs¡ØuDË6R›s¬3Ÿš›OÏ÷;±´©VjúFkI^oÙáDóä̸ñ¤kLà2ÛlvoŠ<ùªøê“OÁËÔ³!ÂÃ…å–f¡¶½¾94, OÏãäÉò†Õ²ÝŠîi#F¯E*Þôskgã6Q Ðv³@RÖ¿Êí Ð ¬P†–sóÄ´óÜÑËZñ]S+ô $õX¶>ZÒ°@\ŸFk@Prâ:Ëz¸Äáý­Ly}Wess[‡i%ƒjf,ÿ#ãçY˨›"ë„ š¶áFo*¹Ün»J†”Gû•‘4æ>¡_Ú"‹^ ¹¼õß\ÿÝ,ZZާøÚYŸëô›è¤°Þ"jÒÇQÚ¦uÞä—R˜Ç2áFI„°#s7ù¼r·`ph+¨»?éæ>•‰dÆÙÓEY{ýË’´¯,k€¿’,q:Óm`°Æœ”ɿ١ž˜HRgnãfë®ó"‡¯CŠ(BQ‚ü/Yªök2ÉÙÔ,Šc6 ¬Ž´5ŠC28Zrþ¹¥ Hµ¬ Z¿Q €‹ˆ&f[H0e„¡‚9L‹® šÔ]Ý |h7° ii8V€å ³@­‰VJ.ÇîyO‰×@¨èJÐw½­?}¿öëùA)ì*I¦„$ü¾äÿ—×7¤G½¢?Ë=7(äcBåÉÚ(n`H/¶¬Ðæ¿`(~ÜÿßZÐû‹PÄU H%„íÛÄží§Ž6øCã—S¢Õu5Üײ¨ ¢ØHô:Ös'){TÇ“þ4¨ Õœ"I‰$½‚Udò8’Þ.x»-žµe³l±v—I%LÌ—2´pŒU±Wí‘´ûád¶Ë<{Pr[ÄŽÝ“š`f5¯O{Éiú"µf‚€Íbæ5…v" ~_"^Ó#^óþÔ‰Wéßs2 ½’ã†P¢ÌsPg”»L&;æç] ©¾Æ‹I¸—H­Ë_‚Ik³HúÄ&IÜÐUc[n¼‘ÀçŸ?·D¿G3S»ðpæœAvøýË^¬Ê¤KB®F¤Rà‹<Ÿ=•îE„%lçÀ‰ëSÖZá tBÈ„îôhÕªVÕ™q`ÚAa°ªóÛ•ÑÒØ¨ÇKÕõßúHcM?WàMô`VPUV,€¢¬V–­«þ¨¡f“Ÿ1Ÿ_aí#ûXUS Ú ”ÕOA¢|h¡)?IYmjkA³:v:&E<óÑp¢œâ\\Ã]\¦`ZGxÂî“^Òd­ÐŠBÊĪŒ«Œ¾V|©YNLj.ÝÑrõÉ£’8(Ø<’ @È=5My$“UÏÏ]!õ+ê•ØIƒ˜Ñåj¥e\R(^,`¬ ÌíŠ.#UR ¶ë^ŽºÑ7‹pÓ"ºÜ*4`ô±¥.y:´ezjH뚟7*R+KNúߥüºwÑ­³Ówü â.¼ëç5ãHUÅøõynBô\ÇÒ#‘Í"­¡ ä8J“z¯ŒšRl¯ÎÆc§¼ÌÊ­l¸[T–ú‹QŒ—vèQw¡”âÕ¬ÿ`cµ, PH>ºU\5­–\vpßãšÜ€*"7W"ta–_"fe—Ón°Å%Ÿì®²+ Í‘©5 !º,Ôµ¢Õr¢ùzq žS¾$%w,‡”*M‰“’ÓGãyë‡Ó2tR¾§¸2€Ad¨Éð8¿Á>:®ý¯DÞ˜û³ ¦ôÛã=›Ý µRežŸY¿ëåb›E…Û®]4ikÕzè®4).q¶´5a àŸþ,= l¤ZÓ'¡ª”Ð÷ÅÚí‘ú×e•Ô»B.FÆK¨æ™)PeawX!Õr¡kUÉ´êç ¦\áŠ2µ‹uã(a_⤳&H–Bö²*1D"Sš+«ïOÎàhÕØmH©ê/Õ×§ŸLI.w™ÙýR5³Ìp<öý?x3h+ûóàÜéu£™ð¹Ë«¸Lœ:ãYÝ IÁŸãq‘ã’(á·,$q@QmþÀþkž¿c SPÉᲦs´E4Ž9 t€íOË rICƇÿ@ú¬MÐð™î«Â©«ù{ÿ&Zà‚<²ÂžÉÃè•ìÊȡѢ"Ö‰ëÁÍ«c®¿R¾™ÿˆO ilóþÝGKåв¼_ão õ 3n‚Ë}èãëõvCS ù(õÜŒ­Œ„ ×!™çqN<õü«z—óŒcøñAx'Ƕ%¨în3ع“TÀC K»¤(ãêê‘6×+νQ¨¤í¶è~¾ƒü«ª¶§V`- y¶î³O-QçÛ<(8"ÖëL|$µ!FÛ«¾WJ¾¡Å†¯Õ[N:jK HÊìÄ…õ·*’WªA`*—nÒxð:nhL5l‘úæL˜¨J‹diÛ+ÐØ­·ä®R÷pø6ú·ßâø„pyµ\\.‡c«/?Í\ê¯q±ÒŸm%ØÓø=4ÖÔ¦W'•Ÿ¬uïœHkŒgײöÏÅÊeQiKù• ‘&Ôm™ ´Ïà ©Í(æ•ZfÍXÏ'à b.dÚTv$Ž´5A¡ÿRΜ+^ß¹ybÏÍDf¡oMÑÀôZ+bß9]5³ƒ:c°Ï#1G¦eÕªzjœyú )%Ì‘Ú(Q°Áö) ØK0kæ?PTäæJ÷,͹PÚ¨ýBÀÀð?~~O=7´žÚÅÀÛ&:B¡Uí¹NæsDóuçÈ¿ÇM²¯@\pšaP„LÞXpç)t”M…,r6Û9г€-WG)2£ÕuETüÀw—£¨lÕ–Çu !‚Æp¦#8ß9ê©XZTdËOÈ+ŒÄs³Ù§Þ9€ ”óYS<Š){úaÉ¡²&†‰ãX,$ê~2Q§ur WB^cT–Æo¡_Ú¸‰5omcЖ¨^fä±T•&¬ÑÒhæè&Y–ªˆÏŒ<ó¸4âj9·ZÁj"€‹Å‘ç‘篽ÓÙ£[ÒåÄ2ˆeµ’"#µ2"€¶y4*¬ÏùGÄ"K§Ýh5h:Œ ZñKXa€ÄDȤ—™¸ªQRòHû~¹­? -ø§!Û¯¬A-7©™QJš×5Ú³Ã1L;ZËŒ­ EKÿuƒ[ŒV}—\T—Õ3áøü©²ÆŠ3«ž¾Žr74åë6‚úi1Q,Ý—E:U¶rÇEõ-ù±¦)¯ãFtŽ4¥—êþO$Ñ·Œ»bQ¬ì—³e½z™ûB[N™¹ë<†Thþ¹/éH»f"­,“…šÞË<ú¬CIÅŸ#%ŠïXÕ–A ÛØ0U¦Í›ùéc vRvn¢½ÁÝz¶&™ˆ’$ e@ï1•cHÝ —ÞÀ ]«g¦õqF:á.èʲîVîW$E)®\Û_EšŠö¦‹Igg±uéû’a†BÈÒ‹aІ'<~3»XsD·U13鞎Âp:‰$š’¤>«·ÒÚÖzX»‡©í Í]`ÿšçÐ{pÉ- ÿW“‘„øäA ­è$ÒYZåúO1”‡ÙkY´nU©ýZi`mvbKùz ¶³.E 8ÛG!®ÉWÏf\‰Ö`-0**›ÐtZ1x­…˜Û)“Ù­§™©¦ü€Wn2*ˆãñÃ) 9¾w_=÷‡ÖgÌi°{_v. –ˆê2•9“+ s Š5oÉ æÅ®nçò/5} uûN¶,“{ˆÏ ~{æ~Ê•K§ÓÓF=-ŠBµ@ðǪ(=ØÒ°Þ.d]C©´¦Lž£5®|}UÿUŒ»‹ËEN…÷¹‚°ÊI:7*¹—n ÍXøePÙ|ò2WØ*¬‰›Iե̲€¦kì]®±k Ð×Ì)ºÉÛºD 72ÃB¥ôs0’ ‹ ÖüuqïºLÖ%ºx/µþv‹<‹A?K°#º:‚18SìhR5$ã$2…- =B»Â*X Q <zçüœùžFÊÊ–W°òO'¬ìXû˜—ãq&ɪt’þ.ÒÄÿüÂPwu·T@·e¾þr] Mk2wDYýK.2‘¸’ÚÏf 9ÊçÒGÞÄv Ì].“ õϵZªìèsh²K-weöËTFCÄÕ£5Zä'– ‘¤AçÉ^]{EP²¸‰RѬ4¯øŒ½1SDÇpˆ\M“üoš°á¥œÕ[Z—ê|¿ž\ï¼7 `¹Ë˪íËF§BöŠÉB¹Ù$Íf¦„ØÛ®õ¾. ’5cÖ UÍmf@øxùÕ<º‹ÅGÖcBÉ¥oéT>hžHòG<ôÓG%,öÄ«¹*‹õ*­Ë:áÐ¥3~«Q76]Å ŸB£‹ +],ÚÛ81¨¤ pJaä7Í!m·Ãœ ÌáÿØü5ÊU_H+–µcUÆÜY«"€%4 ùóÌò«&Âíq|sDEàbª£a©<»s& ªƒ,*U1èIþŨî|Ê%("jÂö¢÷Óéç…˜ÚEÅœšŸèú¸œ¾ÒÕ‚f]í hÏ×&2¥unÅe+´ë;.*œu`ÉØ6 *+*H0&À­¤¢(ü_’8$E‡2l™„8ŸñJxˆFÉ5@±uÛÍ_jŽEò:GC‰g,aÓèôó³yeÞ¢¶èÕÜÉÝOûP¯_ŽRõÁÑÐÌ`+Tô”t:¨Ô-é.,‹ý•bïôÌþGy®AvTæ]¢³³ó—[r&3µ H&vkM(ÉU9ÒØüÛ{ZC6½‘úÃg®qr½IJEF®VoÅ<¥W¡‹4G=pˆ±§æX.‰O£ªcTÖýì²z³H(hÇ›GÆdÇjhKR+i’’Ÿu…2ÕjÙmH ÆÅªsÞ°+›ô\gI‘}+„#,¨Q¨²¢”€9óÁ¡Çžy4ÂÆh‡©–þ¬ç€¢½ȯ ÀbÀ£ãàœÔÅÐ,RÔÎ~Å,ð $’} µ-CEIµfð1 áà˜ "Öm]\fJR*Uþ“™RZÈ«K‰‰3 Ú öVÓÿAácIzX6*²½*-’8Ì?ÊY˜ujå­ObS=I v¨_sßà¾òµ¾ù æÕ½ò2¼´[Øk¿òÔtбõ/j •=‰@Ôž÷=#‚üXtª1„E½cjºRdàSC6;¼Ñï íqâö–"Á Päž­Rv[,Q…m"¶ñÇッÿ¨ë<õ_z7æXÆH0®=Áe,#ý•ZÒë5vH ®¯H—ÓDW­ =úXþV:.ÏÈ\²2Õu'œÊ3ô£o.\ö“ kôÖâ?Ä Q‚¡fðsF˜èZ{>ywËËÓ]³]tYi¬ƒ94éΩå{^U[ÿrs¥ù eÆ?ŽˆÞÃñL˜»OSO>,3®phŒŽhÿÖÈÖl6) â×÷Ms4j÷˜›&:&‰ DzßÓéuý52_#0¤åž9`r§o[…$xà’:(í¾êÌí̘åÂeûwtiñ˜Yr— ¥ŠîÚÊH#:ì ÖŸqüÓég´é°L>­‡‹³x-§ú%›þ½Md_­gõU; ¬âà39©ˬfXÎ+-ǯQ•¡Ík9¥C_5‹ ¥K û™UÍ[@äA'ÕaØÆXó6«µ:ŒªÁâÑpž"þY»œ?3áŽ×Ä™}Ð+ϧWa^‘üí]$›¿ÔèS8ÙÝâÙþÙU]Ù›7 G,«Z*"¢±*¿´SÉHêzŽÃS dºW{L"AÌüô‹o`f.:Yæ}Q ‹žìØ@V¦)‰{’ÙÅÙyÑçbˆtùf–T¦t`¤Ä€™¿¬±6ð@V§ ïêfƒÝqhÓè/‘Ÿ«G§$8ðä³ O$J A„‘NË SXsÇJ^8ásö¾[3sýŸ Yع¯s¶Üë7êDL ŸÊÆÐtqðÙXŽC±*:¡–ÓÁMf®‡õ§Q]÷ZÂæVtè,LPÈL\ìÕB'?—IDaH±ó”|~uÙ)¯ó;FYÓiM܆üÎlg¼ÞO6è¶~N…Tö•ÂÓˆ¦.¡ÇX 2iz5ýéåô^e,±/'Íz ´²ŽcÚoZDÜ3“œÁ MÿØ“SØRË7ipŒ¬4±FKѦYTåJÙò;ϸ[Ux#9«é?ðñ>ÖI…w*§ÕR@µb6Wãžš?F»+&,\¼Œí'OË,‹VlD4ñ=ZF¯MClöéƒýx×Qù°u/`Ÿ:‚•€~}EDm …D;habðƒÓž…z5Ę“‘Š/†4Îibåa’‰ˆÑR¦;6,=WêuïºéÐa(ÝþÕ‹Sæa"Ë€hcËd“}¥è¿Úÿ;ÆÄ¬Q°Æ^¢:#/Xg:ÛK2ÐÚKA:%"íÐP ž®¥••,²å˜wçqÀP åBMn¬ƒÀ®ã¬hWª5\×u çÃõ®µ®¾‰sßø =~rÕ60`,7w€.ˆª“ç uÓ=½ †P eôÕZÙWé îBÍ`›ñÉoÈŽ{8™zT5®•ÝÍZ j£ùQõ,R],éúZ[<ípå­ ZØD¤ É 6:ú/, ’gcl±û/&«¤©Q@i†ŠÆjÊßHD¹Ij bR˜²‚±¨2ÎZ œ¾2 1X – M«ô5¡Mš!¬Ën¸a>Mr&IÏ£¤øÄX_næ€SŸªÏ5oÛ£F€Æ‘–CI,šÑ,û°"¸W°¶dgšŸJŽf®ØL²ç³ëB²†dìmW'°:…V—®ÂñþPy~Üü/;ƒéÎÜr·øÖ?ìz ÒYHðoªâ ÆêTµRy”F§o–fHpT=EÉ0,¢lž×ÖMœ¿Õ¢Že>7]‰bsˆärÊäu!Â}=§ý9ŽïuÏÆªœòi<–·t¶Ã\RÃÎnÚ9Jbë šPÙ35̾’ui=;ŒKQî…Ñq¡ÕÊ?QR•"`ªÓHÊw…·d£|‹*íW°;é~ ½÷¨æg ÑdYð±22b-™©Y“OÇSŽ­4™ 0W#Ò2 $Ý[O$ô䓼é wIª‘èš-PZ ±ÌªK(յYt&ª…˰Ù6N~¡´Æ É¡$õ3„eëz5{dÉûÈÈ’-´ ±x|Mkf³óÈ(äÙä½ËÑl ›?œ–Õ3uBî¬~™-¯×M©{[3cy,ŽEj5¦îÏIµl` ΃BêõŽd[D -‘a’ll^±òžÌ#‡ÎR—µßn·!lp¤Ãd”»Ÿ± KŽ…¶éLáŽK>´nßÇÒ0ñ´üpQc‰YcfHä˜íx†i $’¥Pæžï_©¹½ÙÜ9Úî°%y2æs-$J¸ðn%‘Ê¢Aí mÙ‹x'6ÿ!ÿT']–õý2ðñ=Ad©bß ‘[ÔHËgÍm|äA3et>™b¿¸µeKNðÏ×WЉoì=-bRì1&s¡ÉòÖFÇÈQ]]&'TžýfðY:9j±^™Ñ EÁ.¼Å?w<ž7ñç8î='GG5 bb¡žeñEåœU5ÜÑ8ÔwCjÊÉnÚÕ3Š’í jhŸE]öóƒË|rÄ5:3 ŸÀ®U p‘¯õŠpÇ›`Iñ,ÏÆ÷ oR¬²+7ϲRÔ`ÁÝXªÒ“¹XŠ­ÛC×f…žy¿“×Jv§ÓEîãÌqáÁ²m ÆV¢¼H!€G“wê+ù¨òW’¹«sÞ¹µ¼[‡³ŽLíî¹™CÔP±TU[bõÁG4®(ÖŽ_Awù—ç5À%Ž\²¯–ñ)g¤_SKs[¡×.Ю®ÆžÛï% NÀð6 "¸`JÚR­ýUºöÏI¯Ö˜i\jcÂHŒ#3e=ÔE/zš´¢§¾Ê§ƒÉÄ„ Ù!)¢÷иËO§õ}ð½bÛ9Ȭî^qUrÅRƳ]ltòµÉ0+5îþIjÅW‚10+o´¥l‰¥Üò’ÕEÛr¨%lŠ¢¾9øþý?4.ÌÑ´XbLÆÕµi‘@›ŽZJ²,p¾Ô£Ê“ÏI@Aóh³§@ J#¬÷“+ãWé/Kç -S£W  V˜?ì’Ð)Ãì«êíƒ78vDàueªä’ªïSEBÂãlT¦Ú­þCoý´ ¥0HïJ£™¹¥Å”u»N±¤S\¤Wîm1³EØü°ÒšÆ…̓W¬˜ÎäjõŒÏÒ¤ÿûú|`еíšÐ Âf™«5³ÆûXcT'X“jÜ23‹iŠÅey¥dA)†ÉâŶ,ìdr RÛ†7|sþþ>çö®¯_½(ä%ÚÀ»«/]ù—»aŠ2ÉØça!j‚£p¶*k<'´’ÓÓ gÖ‘ôIzGöm³ÚmWµSºìݺ-b€KÔbú­rKé=Oqê\VÃ’¸ñÿÅtqçJ€‰.±RÃY‘ˆÒØÑ­ØcòÃY[R†”ˆ@WGTðKè67–×eÉ¢ylð|qÇý(õa A‹'§è¤ÖTí³a€$ññ_·}[3W²k_:Ç.„ Ïο#Ð&ÒU©º§²æ…qmZU4qU€ã,°”ë߆ÚNå+`@Hç2ê¦)z¾k1D¨Ñ „a¥uB’I®‹”c(oB:³Ô®uõµÐM·ºÚÆC©Ò}¶›%†ß@Ú¢*S k#F¼úƒlÁNlÇÔû„VŸqÅfÖ¡ãÖTÿkÑôéì¿u1è ðùenÅ0‚\Š…*¥!Šè|éýËÀ¶¦«û×-êîÛf31giv¦Gs¾D±Í.#,S JÆ@  Ð¯‚A›éWõ[ê¦Ó÷‡KÆÓPÖ²q›'>Žp “Ô–Y­žGR«P…BÜÔ‹|j³Œ²x.òë‹[TÂ3césÔ.~F~~:åÕ\ 8©²3Ö{jéÒšàb5V}‰Ì¥C£j@û¸ä]e’Û?m"CE @»ÍÞµ³ï7¦Gȧ<ò–o©ÖL¾’àO;-Ù4Èÿf ç\~5^Í­kÜdxn¤¸˜2â¡, 9œO‹¿ÖÆe_µË VŒÒÉ‘ÝE´ÚTôqö^4¸™ÈÇM³FH`ت7I–GjP^¦ÐnQz"}B¸Eæ »¶ÔË=ó!é¥hZ~…`ãCBNá Ï4›”†iwpª}À,Š6^÷_ÔNèïM]3µ½fiሃaEÅÅV"ÓmH¶©³"9êÜŸç÷Çz'\âÒÃT+€6l¦yxتÐYå‹…-œmŒˆµ‰”;¯°vS.¹wrüÕ»•£¡oZÂ)£sšSçúi_7Có般Dv~ð0gw>ÀWAWŠTV·;þ`*áš'䎞vUJ/z•ÝWfjÜÚÄ«=ïv[Ö^¥§ó,òèØª—2줵T%µ,û(mBÕ¨D§6³CUfŽ]£n´*9&£CÎ #ý±ÊOcD‡‚+©Œ…Xã*Y·0i ‚SEhºV®, ²H$ëPf‰X>å Áª3O=GW?›UÖ©y­ÖaFM•³öê¶b ºÉèèØe•P²pç‚— ’¡›­a£±œ5S-r³„ÊnŸÓF´ )ÓK:–†á•2®”h>’_;lª©ª6¶V sRjÌ\k4Æ‘KPÄæ™¶Ž#Ûy§Òú›pim4ª¥°”I-Ú~uê*Lô™ŽÎ[Ìív™ôü¤Ê^À‡N‡‘üŽŠ¬|ûþ½ƒ•„äÛqØ]°,,«©BRå+u"h¥ýr…‡æOjÜYõGTUWlhÖ}ÅÖS mÖMl*ÒM†êž}b›nèÃZÊ ~‚B¸‘È ù¯À­T„ãEÃ+äV‹cf–Á¸@¿ÝZèJF‚C_âÑÕ{LçôX-åÏ­;¹bøÌçëvè<µÅH»Z&lU{¯J"XÒ—“49UÍSJAv6©u3P@öÒe(»*›ÿÕÝŠŒ»™n§Rãyœj+a~jFd•Ü¡T+C@xÄÏ–6lÙ”3,]ECœÞZàÀòW¨^ÏŸØêxNI.{<ÒèûWƒ‹¾÷ymYή‚úÔÜÍs= {JÈQ\Œ¤–VÍP:'Ô%ôñR:À‹ 4‚×p"”.÷P`H®(_#­#?WÎle’$E@Ó?¨ì#Œ:Û0Ä\› µ[‚n¶Ž'r¿}žw'?{¬ÑŒæ?¾D êòÜùK˜?<è--—scoõõ¦PPRRÒP ¢Š|q<¤„Rp2}…2§´¶k»…‚5,ï€3“H¶³1Däžœu®ƒJ¶¼ð‡‰t­OU±Aé#/rä}qÚ‹¢”[× ·žÔ´Ý5¯®!dTá³Áøô÷¬-¦¿¸ò PN r@’I¯¨ïæ¾ñK&Ð`‹L~Dò:ËŒ‚TtÏ¡õ¯ñn™¢è¼²ÚBìvJªp«ž¤ ËÚ;Øéú²ÑßN§O¶Ò˜¦B®8>‡¥G[šøkù[T…ìŒDh_ï` ~µ‡ZEÝõ#Ë&–Šôÿ„3\]Üj:J²¤MŸÌnBÈïԨ潳ប4oÜêÒ'úN¤LQg´`ãõ9ü…)Û—QÑ¿:±Æø·Z¹Òµ Ý!e{“’<ù›qÚÀq€?ÎkˆÏÊ+OÄ·ïÄš„ ä™AöåYdŽÔAY991 Yƒý_ãUjÜêÿ£2¼ß|ýi”ù~ùúÓ(((¢ŽÔÀ+Õ~ø&ÏRðãj²l2H̪zQÇëšòªõÝTx>Ηký˜¦Üõ%eZ\°5¡išº…¶§ß…CØœ¢ð8bn¿0Äß­¯tËH!‚[{Q1i\\öϯ¼Í.ç¹Õ1<¤,¬$ð3Æ+Ú´›‘LÒÙÀ· V_•†98ïߊÇmÎêk™G†~!ê=üº³*ȃÉ.ü*`ãq {b²|{n“µ’…ó rN; å|J®ž »ß´6üü¥xü¸”ÌÎÛ‰'¹9­T­#šu¥hDw×v­å«=¼o¸ªôRA?Èʨ·,që^‰.‹iáÿ†òê0Þ­ÕΡ²/ü±’@õ;wƸ{M:êöa­¼³Êz$hXŸÀV‘Öæ­Ü»á­ë–ºeºüÓ8 Øû«Üþ½ÃÅW¶Ú‚ñZ€°iÖÞT+êØÀýqU¾ø]|áùõ]N1©r¤n±'aõ=Oá\ÄxÎñéq·:o©è?¯åYÉóK•Æ>ÎÏvyó1f,I$òi))ÀØæ­ÛŸÝ~5WnÜ~ëñ  Òýóõ¦Såûæ™HaEœÐk°ÐÙåÒ-䬲‘ÿr)H  œ×màëÈ­4«¸&eYeœqŒþY¬«ÛÛŸ>†%Ý´¢{ÎÖq× ÍvW:¯'†mîc¹½O͹ÏÌ=ô¬ñsi§§Ê„€dŒN{»þ¢¾ª‚>ÍQX A+.^t¬vÓš¢ß:nþv>_Ò~ x§Xc<ÉŒ réŽò=vŽËÈÔõk‹»o0J`P#BÀžç¡=1[/­èž³6úUœ0 t‰F[êzŸÆ¼çWø‚%B«6ûªrMpúˆîïK,lbŒõÁùãBS˜9Ó¥¢GkâK5ÙæßÏ'o©í^uy&¡}5ÔÇç•‹éíUóIZ '-JŽ{¥”µ¡ˆ†­Ûªüj¥[¶ÿUøÐY>ù¦qO“ïe"Åϵ%”z¶ÐGf5¿áÛ´·IÐ Òº ôW;RÛÌmçYxÈ8ô#¦QæV.å•Ë©3)ºÏÏîOpÀ×Ö¾ ׎±àí>õˆ2< ?ûÀ`þµñ쬬À®zs^çðƒÄÑCá[›iÝÚKyØÑ 1\g€)5eszsçjúêMñ^ëVrÝœ¯sŠòyB\‚’/Qüë­ñv¿s­ê“Ä–ÓĽÉB¯Zåãˆ'¯ò®6ì{XZ7WkFsW0›{‡ˆœí<QPÕí\¨>}òª=ë¶ñLðqP«(­“aEU޹¤ëJ)’!«–ßê¿§W­GîT|Æ™Š’Cógƒ¥ih ÑKEW´|%Ñln¼;4òI¾iDe"£aFA㞬kÆv?u;ë`¬âÛii#= íCQQ¥ÙÑ„‹hÆ*íÆ£á­:+›¹fmH“‘¾öê1ÓÓø¿Jão¡ŽÖE[vÜ„rÀ‘ù…t àYÚK×ýëî)2kTH`ˆNò;‘ž½³è+Ô„–¬újx\E5yirzÑS|00v Ön3[VúN¥âæ6VŽàœnÆG¹®ûCøkkfV}YÅăŸ,pƒükº-B)3æëÞµiN;6y®wzÛm­ä”ÿ°¹­ûOj×tÆ+uÿm²Jõ‹«‹ 2߈8¢E*Œ\…÷ŠâwhÑÀçéK½‰öQÄÎWЮ´YÄsít?vDèk6»MQéR«le|mö9®4 Ò.èÂi' ÜsWíî¢zÖÌQ&|ŸxÓ)ò˜Ó) ZJ)(OJ)J(kµðÅ¿Øí¼çi9?NÕÈYÆ&¼†28gþuÚÃ0U98Á5Ç‹“ååGÐdcíitѳ\«zfg+›ÄWX€;OLÿ‘\èºRÁ‡\ñE¯‰–Ò;…f ™N}?úù®ZÛ•Ïc5ĨP²{üºµŽ—•"0rZ¿¶±ÿ\–£®5ÔŒU5ƒ4™rÌrÕèFÏ©W¢6µ\^ä´Œ©ØVJ©¹c,„P±cÍ)ù{AâµJÛí·¹=ÅÁp±+t¨A¦RФ!MjX ÛÿÀ«*·´t dN?Œÿ!@2}ãM§¿Þ4ÊE IKIš %)¤ E›Âþ‹¹·Œ]£9 $N8ô5 [.Ìä|±Ž>µ±¨Ol‰‰Y±ÎGJã­$ê%cèòêN89MÊ×z¬›bˆƒÇ_ç\ÕÑ-u+s÷‰ýkuYLíSÐ~©] H¥=Iêh¢ùdN>.µ5®‹üŒ­íëM<šSI]‡Ï ))hí@(¤¥É J+§ðüeôö#þzä+˜®ÃÂË-ÿë©þB€9ûÆ™O¼i” ZJZJ;P-€2M´,`çíWj¯(sS)YQ¤êJÝ:¾ÆÝœbÃN°?ZçïîLÒœ6EO=Ì÷Ä€vÄ9'§œä;zV4©Ù¹=ÏG‹R¦©SVŠüM˜œˆmÁíÿÄšQ;m¹9Üp)Ň—ô`?ñÚ¡y#3ì=‰?(Fò¹¦"¯%—àV¤¥4•Òx¢Òö¤éGj)E6”P×sàø·èòúlô®»ÿ è’×vÿÐV€8'êi”÷êi Å ³“Ì77Êž¾´‘,qüÎA=…K-ë„?ýj‰7²:iBš\ÕȺ[ÛÆ(§Õ€5Nií÷—fiß·eNIùg&£©>­šTÆ&¹a—õò,Mtó.ÜOî­@H½èFfO÷…id–‡+”ªKÞe÷lm' –«_׎G|Ò¥”þéO_Ÿüj ¯øø?Aü«8-N¬D¯ z~L‚Š)kS„(íE¨)›J(kÑü´Oý<7þ‚µçé¿—>›þ¾[ÿAZóF<šni_©¦Ð1ùwüM&Ò}?:m‡qÛT ³~‘ü#ÞÒPéÍ6¬yb;Mçï7è(“*œ[wí¨Œù…G¡Ûƒ™Ïáü©Œ~ZF9bi$9NêÞ‚RPhª2’Š(§ m( ¯TøoLOüý7þ‚•åUë¿ w†g?ôößúP’¸äÓ)òu4ÊRÒPi)M%(8©%|¨^£Í!敆¥ed.{QIE1´”QHzRŠCÒ€ p¦ÒŠ+Ù~¨>¸ÿ¯Æÿмn½Ÿá8ÿŠRãþ¿ÿ@Jò9àPÇ“P˜”ôQLbycÞ“`÷¢Š@!AMÚ(¢€ ¢“Q@ƒ¸¢Š1AQ@ Š(¢€ RE¸æ½£áGüŠ—õøßúQEÿÙÿá.http://ns.adobe.com/xap/1.0/ 4294967295 1488 2082 1 300/1 300/1 2 2006-08-16T17:21:22+02:00 2006-08-16T17:21:22+02:00 2006-08-16T17:21:22+02:00 Adobe Photoshop CS Macintosh image/jpeg ÿÛCÿÛCÿÀ¤,ÿÄ  ÿÄR !1AQ"a2q #B‘3R¡± $bÁÑCr‚áðñ4SDc’%(ƒ'5Hd¢²³ÂÒÿÄ ÿÄF !1AQa"q‘¡2±ÁÑð#BáRñ$3brC‚’&4 %DS¢²ÿÚ ?ᓞ ¶#„ýåû Ä>°/2H•Oi˜¿!5]ÈRÛ`%˜]ž·× ôPNŸí3ÿ7 TL€"qo$­3º•¦“™ãI1x˜#[Úáıg›Îå¿(­F5%´¼`‡i¾Ù ’LŒ±ºÓî Á˜´¯bò6i´?´Zî{1Q3ˇgõ‰m˜XIb-&6¹&Æ`éc1[’¾Òñ°!¿Hs.î$¸@-gŸ4– \÷ÄÁ ì@¹yÉ3©ìLið¦Á‡3 ùAiØ”‘åbw'`†hÜÏ pÏÌ{A6$©/6ƒ;üäŽ#“ÝksÞè,04Zàáɸ‚]ŒqßpúSì”ßYý؈kvž’\ÜðÒwá¹ùöïÊÎDÐå@€4±w¹8`"}Š•­õ$ßh& Ì[†õƒ¹á¬ÀZÍÝ„K@ Z"Ia‰.°gw|0f:L0/´HÞ øÛÝ‹K™nß"ÀZ1,£å-s·”@ìw%Á%À؇ȽÈnHý ‘{Ì N½ø@ý ,³^þ“‚À˜tßS™“‰A1Ýð“Ü‘È@`ir`ID³–pï¹³IÜsßöjÈ´„ˆ‚]ÄnO-¼N°d3¢öï"&Úöž |ܵ¥åÁ‹e™äv;ÌÀÅ’}É<± †§`LÞu7ô¦wØXï"òG I!¶½6ofõæØrÀnOÈH ; ÎîH¾…¨3¯kLöÖ8ŽZð!¿—ý!°ªñ»›{»³C1&Ï‚ÚÁ±©µÔt˜Rdk°gP™ý¡¹f/…SÜ;ÆC¿É¦ØòØI0«ˆ"&I?#¾ÄèDñ±vC¿1,Ðí/{úb\‘cyf÷÷k<`ào¼€mx‰=ûLÞ  À3qú¢ÅçYæÿ„\ƒfù±ÃfúÛMv3màm1dƒ}oci‘þ±¥øã± ÞwŸRC£î×þ €Í~/‰„8®ä›O¨‹æQ@·asy¿ ¦c—,K»Á‰>Î{Ûé°-oX.(¨›‰u$¤A•æ ßÛ[ðI-i/ô÷›8Œ okooÈ`EÅe>£9”~"#ფ ,`“¿~SÄC¨äp~q±Â³íèÖÞæÜf]Xq¥G&æà6»Xí¶ÀŸy¬€ó¥¢ä7ÚÇk˜Äøc¼1ùìcÔAå¹7·”Ÿta#ÔcÏ\HR´i‘­¦àÜÉ:ÍàPjH!ïø‚Yå›Wí…(I?„–`-fÔ_|Q|ìgÄ€¿QA}fÆI¸7#r8@NµlL6b¦ÝŒ›0gÛ,‚ˆ¹–À‚B[ÍÃ…3j'¸·ÏücO‰f׋£¼ÞGέ Z%â IŒ6Þí3Â,1 á­ê7bK5ØZÅŽÔH$ˆ›DyˆÜ\ÈÞÆâb8b;éµÄþÄr ܆"_¼Ë’ì¦áÀbÍ%Ü D† )¼À3'i0N„ÚÂ47Ž ™/èÎÀK0ôb'.?üeˆ,Åɾ渙6ÐcBN·1{F†÷°Ö'`ß’C˜7^ÜûÜáìXŸ)êIv$¹äÏ8y Á&A(Ÿ”k¦úÎÀ=øyô-cÄs¾Ø„ÃO•à@©,éÿ’ˆqvQßRL5ß"{Úžß9ÓH3¿Ü]¸g1ßöÂÔ°`”ÝË6Âà“©‡¨1…Hø·…$m)Ü|¯Nó©'oG’L–ùqmç — ¥üÀq:¶.ÞC¹w U§m½Ó®„lEæb4IÜì{8ý}ïn€"þd• aÜ—»5Žà<8{³ ±”ˆú új{Á·›pZcëÿPÞ…¢™´²ƒ€À°’ížÊ99¤e ^GþË¿¸güä@oO~`(<´‚pv< Ìcc†I’/l#dÌöþ“kð=çÒ†±‡ör}aQ€D@cÜ`.îÀ°,øq“Ä7ÖHÞÀG°¸ž ƒ"=,wÜÍïe$0•wrFÀ961S‚&DMÿS:ˆÒÓÄÁþHk_»±Â›¹ ÀÁ{ÚìÚào ÌFçAÜÁ옑¯Êæ1f-ËKµÃ–þ;Ck‚¦»Ãöìà»–ÃSk¤ÁÂ}ôZ.$γÀôo™»™Ÿ ‹p$32I±€¹¸ I)O\ÞÓ2dɱ Íïp4ƒ»ÃïÃà\ÃáZc©Ë’‘¿˜99‡vÜOm²ÊI }S^¥&Ã1 ÄLhoK<´qÅ®.äÙñÌ´“wܱfÙŸ}ðÅ6SæË#[œªH€Eβ5‘Þ䋆 ù>ñÀa„ ÈÜÀr^Hih™lDF„ܘæo¬ކîü½ì`‚Ñ~×÷Ìf Ìi?—¯qQˆ°• }†ÇR$éi˜¨WØ&àǨißo\‰;¶ÁÄ;‡íþ^~%DQ0&c3vµûÚwDñ6$ö,Ï Î‹[ݰܳ\ıvÝÏ$÷6q†HÎwôÀ"d’ /ï¨þ¾ÐÀaï>„q{ö8äRo"o¶ÁÁà*~-¸ÛbNÀIýN#XKÉü½ì-{7…‹žHòx=¡Ü{wmŒ÷¸?"{Ø[¿i‘Ä ÃÇÈúû“·}€Â‡..; Ë?2e§¾#tÉœ× l¹„HŽòl.c`I#ÑÜ€6›{7}ð³%ç’ï.¾wùáé*2Td™¾Ê'¾¤É¼“¹’xŠ!€ÜmÃɾá˜Ûó†îd—{ @ÿ.·/ƒ‘kÚé;È• 4oÚ`›_„._žý¿fc»óˆãoO‘žOÄ‹aÌ4㮚BÝqkKhCh*ZÖ£•(B¥)D€”¤I€“Ã’@Éo+>½ ·¾ À§0æÀ4¹0M‰l2©§X*§y‡)ÞaKiöžBÛu6ãiu·[KDÔÙJH(!@9˜’•IZT• AIP)P  HP0\§h]%®D.Jj(]:‰R*!@²’´(%@¸RT#JH"ëP±‘®ƒ], ì/0 8rZÎ_g \þn‹â¢  ÞwîóñùÁœªÿ¬µüæDDZv;.½¼ßÀýŒœ7 îÍîó¾ýŒÆ ƒëö¸ÔÈ•N£Ü-÷áD÷ƒÌÜ9† ~#q>ç¹çø|7‰7în¾öŸ®~|pybv$»Ã‘`Æ;8àŸ¯§mù;ß qíø‰Û_VÖÞOÈÀ‰v bÃØË Çæï‰g·éܹ‹¹-ê0RùŠZdÎÂ&Eˆ´vŽYÉž@p{ˆys6'=„ÏÍþBØ2*A¼ù"Ö°òÕݵ¼Î“ÝIgòÈ$µ¤@¼XàDžeæm܈ØúÛ¯”Ð ‡ã®ÒEü¦faLÏôÛ8* ³îrÀÜ­0Ì-³¾ÀywÒx*–ÚTåšYÚb1Hs¨µ±k>ö¦mç/[Ô Ú‡Ä0Þ¬Xž ÀãlŠAøHu%LÒlÂI wbFâ{>-ýF\à[âQÖIõ§XÜ[]FÜZ“±æìÏÛoBldCœWPê,ÒŎ%Ƀ‡›K³K±r7 Ì4V-y;ûÉž†v¿0üÙä€bÌÕ—Kíwvý CØ´(A3k ‰"6Øëï±Òç]ÀæÜ1.ÀˆwØ N-h»Yæù|­.cƒ‡Aî …Œwíi@p‰fÅÎä€h±õa9H>ß›† Hr\lw/ ÿ”a ‡ìYÃÄ‚×ç‘|B`%Ý ‘xÐ….@ Ü|&MÄÁƒ‚›Ëwq}£æâ Ø‘;=ÜÞ¹Lߴɹ{ê DØðD^ñ‘7åɶ,/m¦ïòapûí2D¤Ó ˜šú­ŽQ1p}ÈLE…ôㆾ&ççòÂ`“´A×*ä\ÀÚmÀ$5‰›¹boC 3mvÄÿ#höàóò´LÈ×t ·T1$X| Øp±ì#õð û<‰/k˜ ù¼†ä0ØÈÏ œ¥ÎÜãâ+¢ØNð'¹“*ºÉNòî Í;U ­Ä(ù‚‚¹qÍ8¦J)Ôí[¯ÃTÈy×ò´…‘“é˜ê9z•R•eè•ÕÎ|BÔÑ”§IJÍ)eŽ”§.*©ÙÙ,—QŒ¥<ÍlÖVŽQyº™œºrÈªæ¢ (.Ö$ I.ý©^z2ÏY1ÞqVÊøo2cŽÖóMÈøKJæ|{™1FTyeÌ’†¹|×RÛôÈmªµaφ[«uÇò¶´ðN‰žê75Ôz_NÍÔÍRÉÖ©O'–§¯àŠ5sUóalàdiÑ9ÑF¥sRšM,½"¥>¸ñŸCðÿWËôÞ±ŸéÔ“Ô+¡5˜§N—Þ3yš9js¬Šj9õ)9dü:u)V)+, ‹#È¿gn5Ö~sEO[9§ýçìº.Tj—¹‡Ÿj™B|ê\S¡¤¤ gÄ[òZ´×\Ý1«mÜ>ja'aê=HtõR©Óú•n¡˜ªUóyzuj}Í ¥*•Rs*ZŠ‘R˜¬ŒÇÃøÈR*ª¢*%~C¢Që=?9–ë%ÑÔ¼­\µ ÈËejõ¡h(£Y4SMjk4Í4ÔR*%Hp”y_ž^¿t[è'Tù§¥øåu&-W˪Ã×O‹Q!MÒb¸f+‡áø®ˆ2ÚÔµ²_£¬gÎaKtÓÔ!æ<ÇÎéÑú>¯‘Nm4”+WËW¢£¨Ò¯–¬º5?¥5¨¯H5(T¦¶IVœp¿tJªæ:jêŒÂP)U¡\ Ò5¨WBjÓZ©_¢u*•ZaJ¯N¢R¥$>Û~¿„LvZŒì?¤€tã+ ±.  ~X÷ÆNï_ÝÆÎH„^ í,c6ºˆ÷™íĉ}Võ¹pö½Úyw±ž6 ñê÷µ¬AgÜárÉ0¡9Ób4“rm©o®†Ú¸¿Û°`Äzí0CáT¦#½Øo¶–v烀 ‚gÔ»iAí=ÄvÒ冿ƒ†?B9üa]ȇØÄ rýÞÞ¥ÁP=i¸Ÿ$“xl‘±íØ_{O–.ÒæÜ¹hÛ{1‡¼ mšÞ„îo÷’ÁÈfÅðå¥X@3Þ©'ýÓ±ï°TêQû`П©ÇKDÓ-U=p8%*‚\‰ÝÚqDó™ Å+ì?zé‹h_7630ÏÈ€MET‘!¼À’ äµùm³¨©¡ÇáH}I¼ž&@%ˆ@‚¨8>•ËëH‚2¤H¶–ƒ¦x´YÁá¿îûwõ¶l˜2å6‰H“vr.‹6/xbHÛ] íÁàŸ™ÙÙœ™à›‚+HG à‚Ð\O˜3]Ø’— é ójI'ëkDZÇ_”žÜ@o¹ç€>f>X`ÄbAËEå˜s6/6R IÛq}ÅÄngK÷à~žør/³-‰,ͳ3“Ì3‘¨(DE¤n'Ë6A‰NÂüOÓÓû¿ ÂÃHR€ »;sø‰yq$\àSé@˜ô¢÷1)°$#K´je½¾þŒñ"Ca ¶mƒÙ£pA–y»¸gTþkL+qܦ`‚fþÄØ˜›¹ 8'°†g{7æøHìà–‹; ’_“Èà ÄXÆYÍà"?-àßcCÚÂÎÂYÞ ¶Æò“‚åÃ06&œO`Ì’nûâLÄB Ú !°di¯´œ(kn~wïØ’DÎ@r$$lÏžÁ€$†$0w Š"!jˆ‹ë"m¨öì$–spH$ûòÜ -#Ó ¤‚EÈr”‚7vbÀØl,ä³á¢Iÿ Äonú í¸Ä’îg½š™!»F!p ;ÐÜ>¦k]ï$8xŸT±ÐÁ#q`$wÚÂÓÎîóé;‡/í³¾ÌH,I€Ûz»6É…Öx)“$Çk@¶ayì5‹Äo; ì>‚þ’\ìdŒ#d³´´UU¨}T¬—3m)Ô6¤©åªiµ4Á>kÒã¡Heµä-p‚HŒ]0U­I¦”©D¨¡KH! i«ÌHN¶H%JBTe–`iNµ #X@mM©Š’4§RŠ–•”Î=‚cµK£ªÃ*iª™¦5NÓÔ0óŠt7Ì[NÝ€…¡JP°˜C„ÅIRT”¬S%* ó•hÒT’BÁà.Ô->U ê)+ PR]!NÄ$±Ixž‘ÓQÕ:ª¯!‡ii]r±%¤)MS—§qÀÛ©Y*y´¥c.­. ¤€ åIÒJÉÐJS€IÖ0@t0 M%ºVR „+YHHÔ½a@i„©&Yl:‚¼É €D³­†Ýq)2œä ’ (R›-¨œ¤ &-nYÎÎÖt¸W,»4ÊÒ$K’]$‚%%g/‰e|d{mñ ?ÏKöák¿>û¿³ŽÜ9|V¡¥Ç”à8ôgiåÄaÞ „ºÑ®š«NÛ}~œÄ1‰w‰< zÛfüþ€-/8RBM”‡’±–}E'2B’l¬² "” ñ˜s¼¾Ã°Ÿx?9`xcùÜ9Ä}6'] õЃ¦¼ -êÄ·ì…ØÁ`ä|ç›ó}°P›‘@'X‘bÚ_æ4½¸„3Æàö6›ØÏÇ¿éÎüO³Üâ Í„ GüÃ]$Ï×n‚}þ’w°kñ8ŸãËmæ压¾ÀMå\#Ÿ:×â"«ö>-Ô>˜`\¹Ê(åZš†-U̽E{ ªÅ0Úr©n¦’‰œY€a¬r´4—]Œ˜ïfs™ORËôÕ£ïþ"êôº1t­_ +NÂÍ])òeêf*QÌW!B¢“’B>ëÔ~ɲ};3â ög¨¨%+¦œÍVýJê©N¢©…~*Â’B‘o†™.u„ÔZzKÍÜ¿>®HåÞKw›±ì™î u›«¼ÅQâMÒ¡êü/£e·ñŠÆi**¡ÀhÞÂ0*Dy)ª¬E[ÎÔ?ÇstF]}O#”«÷>ššÕ+#2¢ªÙ¬ýb :•Ö”” õSPÔÌf*!]trtI˧édTûÞW-šBjRGÀ$€—¤Yzµ…|:d2B)!Jª¦«U@¬Õ8…àö–?Û.ªà˜n7ŒõÏ«økxðçpÅ)¼ÎQå>^¡­¬¥ si^}Î<ÚéþåA÷ºÜn¥µºB)èëžM™%¢§†×œËå L½5æ³UÔº™ŒÆdÓKåE%:ÜÓ^hРƒO,šJ«Sâ¯-LàHê‹Ë ‚®i5¤ÓÒ”S¦GÎS¨­’OÃEJŠ&¥E(¡%"¡Oš 8¨j–ÒÏßéü»â• .5R¥ÌÂ’3[üP|â¯þô¯íç¼N×ó–"çÚFÑiÛ€ŸÆMä€ ÀÜÇr{Z٠Š€HQ#MÈ.  A;¸ƒ-å4#êõIŒë“ þtêu'°úÇ í³ÿHü°«-¹‚S,Xj}äü»À™Ã"ÏÂ41ùÒb¤Æó¤ƒ©à« »ßÑ»l ab rkÝÙ‰LAs$ìçO¨ÀÜnH µ´EˆÜÌâ$Ú-6’Ça{m>œ `mÂC8wwrdÞl\D…\|¢çx'µÉÐÀv.쵯 ¸cw·¬`fH ×ËyK—#}Ákc…Ru¿æ&"ÄùjѧúOn ·fnŎx±¸ç˜#T…vÕårXk—pñ,#-ˆ:i &úÄ{k¥®HcØrà»NÓhkâ²Òú :@³\¹îIáØB&`ˆ¶q{¨v½8÷à’÷lÀÆÖ¹2ÕúìÆü÷¹`d›È° ‘êÒfàA™3h™“,`¹®@!à3y[³¾Ø’-ikɼ’õ–›µÞà9[& &/ í¬^uØ™ÖC3÷›ƒüÚb’T ¼ ;H` ±K¼€^c‰Vº-P.3kx#Sí¨ÒwÝö´ööýq.K¨K{8˜ ™6b!Ù¢DÚÀX\M†¦{Ä|½¸%Àí:] z[}Áí€B’A%Ýœ9òÙÉíÆ›È{ ×ùNä€w3¨§{n×rA$ƒ!DZ„Q}ËßÚbÐu8v/‡å¸ˆ3:ÞÆâN¤ØÞOÏN ¶ÜúÂv.bÌdØÀjxØ‹ú37½Îý´‰ƒi’ ‰{ÚdCǤ9¼nFÁÀž à›ù¥€c°Üɘîܱ;NóöMû^/ïüb!û·;Ûg*bÞ×<Ë,²ÝM]CËr©×ž©d4!n-–ü¤ŠŠ0TS¶ÓVÛ¤´<Ô :«’„”¤L€\š‹UD8|:KO‘AŠõ)ÈcAPh+RÊÊ‚—ªP‚WøÏaGX:aJÕ¤ymºàSŠ )·[Prù°”y$Ü–È#*Ò’‚@I2å$³Ü)*"AJTö¸.’Æ!JÁg I f))f.òRHIüAz H ‚ådIìD™Ö"ÃA§×ýâAõõÐà*ÊkÝí¼zpi|8ÆWc¹½ÅÁ™žóÔ¸Clüñk¼™µÆ+"K»ï·n»‡v{oG´ÞMÌM¬5‚L ÏnÜw%¤–fï$f.K>ÏëüùïP ˆ¼_ÚàDDÚÛï:c;°3Çycæ|—zÒœž¯¨œÝU;‡cœÛÌ8»Ë¬–°ì@!רUXSW[нJ—+((_Ã(é .:ÕU?Î×ÉT+êUi?LéÙŒ·JÉåP”õÅ4%YŠ™’ jT£–¦ºkÌŠk¤syüÕJ‹«HQ¨…ýsF–` dê-tÎu5sKø:BòÔ|É¢)jJ™uJVšeZ¾ :’²´©:é·ÚIк~¤TxLðß¿ÈØ"y[›¥«Áp—æ?Œá”jªs ¥|(Tâx›ôɯÅñ Z®««Ä¢qaúìIÿ»9«‘ëG£õ.¥šA9|¶V™¥•NŠO•øÔª‰£L&ž['•¦ )åéSHM:šÂBjÈç ñGHÉu|¯FéËJ*®²ÑW0J¡5†¢šj®­kÌæk(º•V°T ©UJiœiëÞ%ʽMèg>Qu4Ò`ô#–ñ$Vc¸•jK‚‰’æU\ãå'ö½s•t‹P/†šBT\xZ´:9|îQ%šJ¡W-J‘ÔU›Ki¢”ÊÅMKËU¦âÓ©Q % Y4æ3ÔsÔ³¹N¤S÷:ôó4s‹¨É¢¢^²É`…!A©­SNª)®‘Ë=8*~¥(ÊQ$%jH+)A¨”—(%W¼A¿^™R˜RHK¥Â˜˜ÒûÉ"fª%)'BµépK¥áD\$ƒ³`UÍ©ª¥ ¥IVFÖFpJn4‘ ~.P ¨Ú,ÀØ’v ’ ZÌ?â~Û êoÿ,J-9‘šJ”…§)¤•D(I Àõ n#ŠØgÝìàÁ oéyÃkCĸ,; )€€Ä¢•k£ÿé&û\N›ý80O¨¢ñ¿×` 0 ô1wØKÉ •²|ěǒ“ò(ØnÑr¿NÀÿ‰%ãw;ñ v{8‚ Ì80âåÏa‹áÊ?²ç»ê"ÓþånóÞÑyâòüÿ½÷¼Ë€² ¡&^Yì;˶ؠy¾N'\o>s„NãÏTIà=@±â¤þ54Dmß{˜H ë'1¥éÓr`æLw/ÀØKƒB¾xƒñ¬ÇüÈÔíÅ£Ü/ìwŸØò/ŠjJÀƒv¼Ab!ƒïwd°Æ†£C”ƒ3y‰¸HúE„qv2_hÃÝã’Ĺº¥ÂH,#K’aÕv$Áö ,À„2L$ZfAN¶?1 ð?{†,Ûp^`½¶Ã ÖM¦D4ŸR/É ^$Mˆ¾±®kïq:iÒð`ÿŸÐO¬X¹ŒO•I ¹&â.÷%ËÜ¥& å*P ½Ô2¸0/c"Dì ›p7~=_qÀÄ<†h %Eƒò­‹Dƒ€2·c¥ÌÜÀMgÚ'ß~ Žû3€°&mžX±À 2v‘̓:À>Ì Q1s:9;Í”'[7;Úð8À3ÁôbÄ©ÛôÀ@’6S€GpæGšï9 <leP±“`Áõ$›E…† @“Á¿Ë,z¶j/Ó¤€Y& `Æêwg‘‡;0‰:¥ç>^öö›ØKqp@¹nÃ{ð¢  $™x`KCY˵™Ù2&Óù—7˜í'ÜÄwÁàpÒÿÆÿ/ˆTX@X‡!Ü39{ɘfMÄÀ¸ÔØlD“¦ƒõŽ'¯«v;ý?Lsq©ƒ؈s¹}?IrCÍÄ…^&Ö36¸:|®4·؆1y€çbäú]•S¤êp \†`Ìfâ¬í{aJ„‰™›[ü„_Rn>–áƒ3ö‘,BœpÞ˜]D6ÄÛ—p[“/ÞØ‚G«·m¿ÈÅ»k¸~E®á›‚Û 2`` Ia®öC¼ùŒ &cÚÚ΀im;ƒiø“ ߟȋ¿æ“.ÂÂ×.!ø~ouú{Ëìc¸^0ÃX]=rݦûóØ»nµMA°û»TÍcaÕ6|©š¶Ûeo¸ÛLÓ2Óê¬Z©J‹& Š_?@€UUtëÒËeÔ•>°ºë£V’@ÿ×¢jÕR(åÔWu MUõt(%*KRº”ØêÔšHª…$%5€ºÉ É>Gð㉽I[æ<þ!]Ža,S`ܽKŠ/¤ÆŸýF0Õáɬ^!Œà.}â½[mT9ˆ7Aä7D‡š­¡f³œË¥(ʇ]Jµ©šõ@QdåéÑê‡6i”·À9ziÊgA Í¡Tkªžf|{rý*½e&ªP¯:BrÔÖN¬ÇÇ«S&œ½%S œÇÅzùd©÷zš©½*”±uºõákœz:Û5ÜéÈõX?%âØfŠàõ+ëð¤òÏûË´ÄLݹ6ƒÏ¾ý¢kAæ\w’ù«æÞY®s æZÆðÌwÄZCkU+…U³]CV–ÜKŒ¹äTÓ²àCÍ8Òòåq AP!WF¢jS -ÞAJJ·”¥J” !Ü¢…" V•!i©MW!H: I )à1ôoðGÒœ_íðСõ^©X+s¯,cxïV°ÎZr«ź‘ÌØ1c<³TÐ~˜40 O/·YˆÖÐÔ9ˆ/ _ì¬1XrÿûÁ½¯øc§äúúˆ¦ÒúnC§çºKZ×VŠº‡UéÙ^«Z¶t¨%U2ùlÎv¥jyd¿ÞêÔ¥÷ŠÇ(š™ZßRx{ÅyÞ¹àüžk5ý>­ŸûÎW9ž@M%}Û)œÍdr”å(©^•¥5 j jSIÌ)iè›ízÃy?Á?4t?©ýé/Opgä¾uÄpî[Í‚"§ g{–1¼>¦ƒe C˜Šê>ñIˆaÎÔ¼ëÔõxqx-aÚ„=GLÍf³ýW5’©›¨Ôz'P¥šRR„é ^IͶ„TË“Th×U2–RtóïPÊtž™C¨ÐË UÈõŒ¯À++QÒQR‘UAZÕN©ÙÔTH*áZ¹¬ëO‰>ªuÒ¯Ìç>axá¥mÕž\ÃX£Â¹y¼JÖ3…á´ô´åK#ðÍBU8+K+JT¬ÛgMè™>˜ÁJª-%B•ZÕV­4-µ%%d„9e 'PÒ“åBRžsÕzÿPꤊÕ~%2ªÑ¢‘N‚שD-HHP Z¡^•É$ÙJzÇ™Cí!Õ%º‚‚øJBŠƒnflFR2 ´ª3šJˆ±.H³ìI— \íß’ø_Äe‹¸f ÅÙ»ÅãUÕI©ªK¡kZ¾íJ‚¢”$•¶ÂZT„%)*0V¬þ"½K$Þ£©@¹.ðĆÞ9>®1Z’RÐËO?Cg6&P‘t„SÈ>aÍ™ €ÊsfQ)*R’ ‚ †&ýä±¹ôÚÖC1ym¥™ÿ(v–"7ø— í=­7:oÄ7ng—#nÌÏßkH ×gg Ös1{dæ@¼yý|³·m½æ`pæ;´È¬³>ûâ!¥œ[a~þòჽ±|9= áá?Þ/–tÇëó¿ëa@'wàp }9ÝÈ.ðSuI"÷ ·ì[7Ïí*Ó.ºM¦Þr­Eá^ÿ=x¥'Îwó(\İ}žãäüã4Ÿ„‘¾– ö³™x{8 ˆ8¡j>1u“yw-üûñèr@~Á½w™†7Û|P°—vk¨³¼(a0Ðáð&ì4 ±bâm:62c[ a ù.,OÒ.÷’ø@é ¶û12 ¥Àx<÷d:¨Ï´AˆÊž×Ð`xÏàùvðá%Ã÷Ò I9&×Èß’:XÉØXÉžñ;_‚ÛÀìàþl=‰~^qYü.ö$¢Ä€6,wvY°ùÒ÷’ ´O”of4¸ö&`q/ìÁ»,ìpbd Ü`†Ô’åÁw»y]îÅ¢$á‹m•»œ° éxt4ëv .@!íq¸x2?'°ÇK$KKS¹0,Ì,§|0*3ZáÁØØ'Þ×Пò—ßøH0¤0e ‡%€—.Ò|ÅÚ²J$è?)î:AbÓ7‹Ã_Б ìg·ä¹ÇÖ%‰w±ÔzV¤ô<þY¶g'Õ:¥d2Ùœš4ÔÕ™¦sîëBº—O5L ”’G›ì×!”ÍøçÃêêy1›éY õÿU¡UÓEy| VaI®Iá뤟‰J D¥Tôµ lûÃÖÇTú·â/ëý7=sÏV¹W“9ÿœ11úÁ…à8ß/`ª4üßË|ñ…WÑ5‰¢»§Ä2àTU4ÈNŒ¢’™ÍÕ¥’Ž5XdzGE>A<ª³þéy…Ð_Þ34—×z·OèylÏKª…¯ãuŽÔsT³Ôëš•˜9u•©WÛ}?"zÏ‹êUëa9úµ(uEeEEÓOºåòyœ×ÀÏe†„+!›ËÐêÐ]5Ò … KãDÜù„PàíÍØ&jƒó;†Ð}í!_r¡Åj)iSRËP–m/‰ô¼“ÛŽÏÑ39ŒçHéy¼Ò©+3™éù:ù…Ð$Ð]jÙjk¬º&^’ꪑý2‚òøø'Å™§Mñ^Èd‘VžO'Õz ­:¿ú´rÔ³uF•B\š”©SY$’¤©É'¤@pZÒÄÜ›ÄoÚ¥øÊ0ÙAþ^·ÿ=ZáØû[ë=÷ôg!¢IÖIÍ´‘qó6#ëòâq±Üûnܱ2å£7ßÓÞ?HùaÓ{inÂ}¤ú€·ÒÂxŒw{¸nçÞK½¶ŒG·Õƒü¹ß†aìDjA @Ô˜°J‡c¦±{È7…æ Ís¹}ßò/`CðÓÈ-Áí˱3$§þdÏÎ@ì"Ò@€76$—b no=ÙüÁÞ\¸8V“7=Ãs‡h°ZqXrV‰ó9†`˜= N#‹bø…†áô-êšÚúꆩ¨é)™@*qꚇi¶Ð%KPLJt—˜­N‚UU&˜v N¥­dJ?•`—&zŠNTvJX©j0”¤?âS:eJ %Ôǧü‘‹xEû::ÓJz†ðÎiä–rf ­…–бFpÛ­¥¤ ·Y޽‰>¿Nu%Å,æ ž4?uç:Æb®R§ôs9êô©_'Nšr¹ j’Bidòùu+`´i§ú'NWJðÎK)Y TÉtº T§2^¾i{9©˜«U‰!¤¹8ãOíÛê}n.ÏCù"²­/Wãó?c*Y*}iIgÁ$ÓK¸š‹gR”»åž åÒ®½š¨)Èt¼½!¾7P¬ºÕ‰2J<•„%ÄêsËÀ› ³B›øò­)Z€Yl¤)è1|ªPJ”I€7Ë<)Sì.á¤~)ìK;paðÁî  bAMßI.\kb[ràH8ô˜À1Ǩ,Ɖ¹†%~[˜ˆ£}Th^TzªK^J*Hõ¨ 1:R«ÑBÓEu©¦ª¥Ô¤…¬í’w,y|{©tî¡W.¬Ý<ŽiyT(üLÂ(T4P@ª )Ø“XIÎo³/ÄÇ/ø:ñÅáã¯\ñ‡;QÊ\Ï ¯š†Ë•ü¹aø‡-ã¥#c1yü.‹§Cgñ¥Ki9ŒqïÉ*•o¾ejUE*yþ›È|eM•é%YuÔWöÒÑC㜺ªpþ®›ÔÑzŸMê5(U¨2¼¾j­ª‹Ë¢¨Bt®¡¥ñ~Ÿë̤ãè§â—í¿é†nQä.aé×)ó/]pN£òÍ'6òž3Èî!ÞQw¯Ck¢¯ªÄš=T*Ò´df—Ö‚•5S亂ßÕ>#êy.¯›ðòrUhfúp@ª3iªš ©TUÒŠfštÔ”¦©ªT)J§U ¨…£º‡Ié½C£d|IÓ裫åz’Tº9Ê ¦’š!‹¨Tª u)&¦j¢ªj¡iBР0 ûEüIxÅë ôÊŸ¦Ý:Áê?,ÔsNËœ¥Í ç`Âù}ªÚ9¹¥Ê"ã<»VöµU¡ŒWîÎ:©a (5Æ/=ÒºWê=Tf³ºE*jÎ/-@ÓÉR×Z–\У˜R”ŒÍL­J´EZt–ºˆ 5Tt‚¼e|3Ö²ù\¾['N¶]4j*$Ö5óÀ¦µ ™ÁYtÕBBê'PÒQœ–ê'‡~V¤äîi¢ënGWOSBY¨ uĨ„*•i[ª"RËíºT¦”…fl¥* Ó]ÍÓÊå2µÁNa5j²’¢•SPBÌVe„¸<œnÈ¡÷öªR©Eꤩ¥v() È$ÜŒrâ ƒ ^ùÚy¯¡Ü¨ÿíÌ3UB± êÅ׳÷ªj¿¿SÔ’[hSÔ4 m B€òòsq°ä:¿TÎe²TéVM ´jeê 1¡RŠÒi­**ó+Ê H!ÖÀJ`ó#Óº7…ú®w9C§üBSWï.jtˆR– W©(DY-± %“ér÷ŒOøoFz¥â/çŒ5ÏÝKê+üщôþŸ Å1\_™*ðÆ’ï-à˜•Kôxg.àœ„×5}ßyˆ¶ç0ÖsC´vú¨”Ãì Xð¯Q§•èèT«§+Huz•óiHF_§Wë+ÍejõŠõ×T­}K¡tŒæ{/ᬞ[-LeúÆmZ¦n­:ÑG¥ôϵå²½c¯õ,ÕÌäòt)d’ufsc'J‚GKÊ RÑO-Ôëåh#¨æëUÒœ‚jå5U­ýmõ‘¹ã¨cšy£­]78gǘÇÚ–Å{ø«Š¯}Ç@(EK<âÖÓ…*'6[¥QÖz>o§ HéY2Š'¦S§“FMôü,¾Y)£I(TÓMÀ"É)vpOÈÞ.é=nŽf·Zêt—Ujµ~¢¼êøkÌçj/3XT†§QU*,”¨¸!&[=.LN`/}Σ^ÞÝÏÀì Ôî@ÿ=Î4un66ñ$ ïÉ#¾b-¬ ˜±:éï$ˆá˜1ó7—p˜w=ÞÉ¿§§{_êÛáñ0bñ®Ó&nu1ìdX„s`6}LûÈ·xØ€‰/ö»þo~™“m¦N²D ‰ö¹Iž$Ç”7¤z’À[yp?êðü^ìIF ®€5‰Ì=ïc$À¼è ¢}9à·Ì%îßž åËlM‰Þ}KòÐ# ÿg[Áøñã_ ê71á ¬é=ž bŽ?L]¢«çÜr‘p‡âVךŒA5œÆ¤¨-Ž]u•„ùÉXóu Øé½#9œ}5ój/$DUé­yìÊHÓ—ÉQ,uSÌgrÕòãqðK_ÄÙ}h×”éTÕÕ3nFºe(ÈPQ‚êæÆJIRWK)],ä?c>;:¦œYtü…>!Ö©Þm¥‚RŒ„©2RP]ˆ€MÀÕCej}÷©,¤j£Ie(—zììIdi&[W±ú ­WM †I ¬¤ƒ!…0ä‘v@w‘ÁßÛ+ÍCñƒ‰rãOyŒr!òG+–Âå-ÕÔaÎs%\ !+#g5„„&{ ×ÂC⎷mIÍu¼ÅU¹¥Ó²¹Nœ¤ñ¦žw/K 5 hÇϾ9ª‘Ô²Yd—û¯L ¥¦NšÙªÕóO°eåªe‹Kgu$²2®ÓøMÌÿÉ’c¹ìLGIö÷h“ǘÒÝŸrL±f/ìE ðñ8ö)¤aóJx”‰Ì”¨%Ò…ŒÁD’µ'(NP$“ŸC`!€ÒKX±"Îû, ZwQ/¸%áɿš¾ãBÔä‹‚”͈ JD“ŒÆäƒáÍÁ0nÁ¢d^×¶€ 31a%ÍÙ¡›a.ñ³;m"ÂÎ"b ±é÷ŽâÜ™qaypÄ9¹ Žæ1€uA€þ—‹3[Ñ’rÁøs«]Œ£ß~òÖ ƒBG£–»–oB@jXj§rÆûÂ_‰–/:Üùˆ„ƒø"ftòÕïk^D¡½ø$“p÷ÙØ‰‘³vÜTX¿˜l¹’lc܆8¾¼ž€p阨^ Ÿ÷LÔ;ínÝ…@™°y ‚X°á oBތجÉþÒÑ(Öáœî_ß›ˆ8…l«G";m¡$ém§„H:Žþb$z˜as$\ fu ÈJA2C´uÌ ‚ÁÁg¢j Ìåk:[âF¢ÛÎÃP#‹[ßhnü;͹ÍYQ,&\‡³@2K°pA1‚Y°äˆ=&ÉøÑ¦„DÛy3³’à¦òC–àA‰°&°TBšÌI .T’x*Qa$©3$cùŸÔkÜFð­!·ŽׂZÏ‹áÜÇá.HÄ“/»90àÁ670&?–šÄi";lL\{¸ØÉ¹±fÙÁËÉW–bîðTÄÞXƒ4Á¹£´Ø4¯ç&bO`cˆ)w¾Ò\8 ÀZbŽBŽÖpÁV@KýÊ‚aŒà*Ñ0ÛD¦ÆF›cß¹›³»¿á±gac ÑÛ ¢p C%µA &ÞH.íw„‚siÂlÉ)™1¥@M½á° èY‰íõÙìö LH&/.îCIìKÝð€\6Œ£h*N§¸µ£¶–†NÐA{€8'ÿùk¿a‰/X¶À¼†’ì 9/‡8'Ø#p$ú#è$ÿ3iŽ^K‹[›íìá°^ ³rnìî@wqË| AT& QÜN³aï–æðAìÛ9ïm° f¾à†¼–’êr\Á™‡8­:qÈxÿSyÛ—¹–XKØ¿2b ÐSþïJÑõÖb«l,³A†Q¡üB¹ìªò©)ÝP PJI+¡F•|ÖnºrÙ<–^¶s9™T§/•Ë¡U*Ô) j-€E*@…U¬ºTAaž•*¹Šô2ôjæ3iåèÒIÔ«YiBîæZ‹¥Jª(„¥ñ™x‡Fiñ/”:]Ê•NrM~¾~rÌæ¥ã´ ¡oÄz¥KcÀX¨©¥V ƒQ)¦Ù¥|?[]]VV”k)êËÎTMzí”Ude«dºOÄNœ–VºóIÊWÏ.›¯3Ô³J¡\æ*8¥DÒû¶N‚P>5m­¢ª9,¹­—¤ºôªu†õº†b‚iÂi¨"ŽN©LRF¤ª Q©Yk)U:W£û8yáúz¿¿àµŒÖÓ§ ÃÞ) ¢‚§z‡uÅ6ßšóüÉ…;D䤺º…¤%EÁXñ^²TrõSSE_1DüOˆ¯èÓ§ &ªC>ŠˆHSüj$”i VI~ ÌåК™”¦‘4 %jbЉ¦~)YGÞrºV@ Ó¨Züž¿E|s?ó-&b~'Jœ{®|©Ó*°î¶iè×Q]Ì8zã!*¡Tü¹µ[MNØn‘šÊJš—Rã¬%eºÍ<Ýn„¡Q!=G'Ôs4ꯅK¦äº²Ô(8ÖC1Ó+µ$©*Ñ@’ªí“é¾*V{-˜¢M:=S)J²S¡!I§š¯‘)ÿUE#8†@ –­B›ôçŒø%èž˪é'KúIËœÓì.›’q<~¯n£çLyª`Î1W\ë‰u@ÕÔ)ꊤ¸µ¸ò¼°Ûm6‘˜ÌæzýZÝUkU ¶o3Q7)Ma:rÔQN§ÄFZR”*©"¢‰ª¢ô[%“èT2Ý3/— QBƒæB©MF±+©MTÔ‚š¥JQI%,¢€JR_•Þ*¼5óf%ÍœÅCý:¨ÄÜf« }ä¹]ɸ‹®ú°Ô‡Ô*«°e,“ET”¼å#d3Vµ%¨sgðω*fŠ:oQ©¯2u§%œ#IÎÓ£¨W:iæ©¥j!®@ &¡RûEû?Ëôä+Ä2¯Ÿ;ÓUP)}2ªÖß,~%L…e)%)¢òÒ 4@Z{û¼AôGÿÕßÐG¯v掽Ô;§ÅÚMh¤Äqþ cØõ5++CÏ"™¼2¾ÆÐÓ~HqÇJ£eñ¦j‚z¿NÏ"‚+ øo£ä Šfºòy2Œé­¦ñë¥tP¥–E*4ÂH8ܾÈè|OÔÈšµSÏfB S@WÌ-tÍ £å^`Ua2j-J.TTwËÈ<³Ð<%÷ú½ÓžKäÌš*0Çhê9ƒ ¨ˆ­—<æ\¬E;UiS…¤&¡+qJp¥iR€œÎÑÉåªær‡àŠÔÒV€¥¨„…¢–mz´¹@Y‡Q/·ÿ´¯ã+'V3AuUñ+¢’2õ€Eh¨´¸.§.I³3cKhˆ _¦ç —’á¨[/5Q[™im •!NŠHZ‚@)RÖR”¦H]foù`=.,±ÇÈ+ZM@†üZˆÚ ÆÄº@›D>$ŒÉܪ"A±:w0u¾±Á~R@°kHôo×”±»ö0Öoþ\ :@"ò'I"ñmäX$ØE¯g~_hgnl'¹sû£Kˆ-ÞGópÌfZiÅR§4{ ¦I$iýÇ^'ï.à›nâµ(&uÄêo@MÌú·h6÷ |©¸D©n2=– !DMÉ1h3 èG-,@`åõH áÀ ÙÇæÏ¶*!îþRC¢XyòƒÀC?Ñìðä|+ýœØwRy—N Î]q®­êegÞ[ W§–ª¨Û ä”=˜%·ðJqR¡d¤3Œ¡p…­Àu?æ“ATzpPn—”øY€Uøz–h«3𤩠º øJÉ!*Ezi— IÇvû-éëÊôÝFª4Õë9Õf)¨Â•˧îùEHJг¿±tª¢ r¥âsÖ*y·˜ë¹»«JpöqLG}ç¦((<ÌëRÔ}-ä+Y9€ „%1Æ£ÓèSéÝ8ç+?“-W5V$¸*HAÒL%ÜrÝ_<¼þpQ¥a˜M’¡ C$—ÓbIw`áà;ð]âÛª£¬¾"zÃÔ”¼]¥æž¡sn¥¥ŒŠÕP`mú¥CÊÁé([d„„ óÃ%dzM¡WÿÞ@æ³McÏÕ©žÎÀyNk3Y Ü7ÄYÃÔzçSÍ¥?ÓVeTr䳜®T'+”*ƒŠ)‚,H&äãB ¹T~,LEØ:’,mÛ±€0ˆœV\‘ø‹{–-±~Ûˆ—S­ã)1yºÑ¿´@Þÿ#ÃCgnn4›·§6ƒ€d‹–}ÜOg-{³b§Q7˜&"#]‰íZÜmÞð`8>»ˆ»<È"ÌÉ€U»z¸k³ä\hL_å=Æš‘¨¶ü@ćaß»ð#±‰œ¸™ ¾äv!Œ—,XbL=WMɰ÷j>ñI¶÷:SvÝ„ûHˆk¹ŸBø7þçÃ)ÀVàói$0ü(Ê AJI½"AØüÁÖÄØÀI!®!Ü1ƒê`myß ¦-æ{6$[å°’!ÆÈ˜"Faæn›ü¢û:Ìä ³ƒvplþGw;¸›n]»9"Û°ÃIõ ìúªä_éÐLß‚.Ķŷ“Þ\ÜKv %˜(ÅÕg¶Ûd°,@“‡¹ð$ÎÈï&ƒ¬žçh¶¤X—NÎ^ ÎÀ83!Ù¯$`•ÃÁf»rIËk¸| €&ëW}ÿÎuë˜Ap'{4?­ù‚]ÝÙßk—q`Ö~6‚1ÐgØyàn·Än3ÕÞ~uÑ' åõr_,ãŽ#%.UŽYæ*Æ\P ]r0úº<1„ ‚Óx¥Kám:Û ‰²ê>Áº†r•\Å ˜é¹ ßxNUÜ¥˜Êfi©LÊ=?î䮞bµ#¶x.Š+uª•òäé|:u@‡œÍ£GÄL†^Z•ZdÈ)ûÝ5†R¡Ñ×M~Ì<§uܯ\Œ.˜aÔüÙʘ:<ä©tÁœGr¢¸Ó$¡n½‘ªWª¥­úz6ø>žA“Íg3AkÕ?1K5œ  MDåú&låP òü0i§?I4Ίb²Å"D¨÷O¸är™M(H4TŒ­DºIA©œ¤¬ÊÒCJ^ª”’Ti%+m%o®/o§ívOJÛ”<ÿ⥘=S¹ÙJèÛ Æy¡¤aÀ-×ÐQse쀴šU—RâGáô#%Ô:L¬TËê½g8Ššµ)zv[Ä<†/*WVé:Ë®:¤i)¨¬y:ê“›ÊçkÓ¨+§ÒªŸ HVj§NøE, ¥²y¥@`¢ŸÄé Ç.˜aìOL|má4†]`艾jê>â©Ûn§ÂÛÇÜG+×Q´ § F=JòJACµ ¥0juxeõ?öïýšõ°•+3ÐKèÝm.ÏœÊôê«S¨ @3 4*¥I Uj=+Hƒ³¦euõodÖœÎõ öI™-–Ìæ×Ô²`ª‹„y‚R•×S)æïR}¥ž)B©R±UZzB|Ø¿/Öò9ÜÞaY𩸠Óµ’¥V’iÓÌSRY“M Ju´&˜Ò²§zx¬éG8ø…ð£Wã#é¿Pú§ÈÜéÉ\ÕÊœ¥ˆr^Æ?GÊXóÜ3ÇqºU7VëT϶îŒyTï#¡yO%NgFN¶B¯C¡I´+#˜ëªéyܧQÌO.:uâ3 ÉÔ®€¤äëæª¡C2TÊÌ/.ŠZÁ*M\?Qøb¢—Ó)«ªQéù|ö_1’ÊV£W0UÊÔ¡G=K*µ¤×¥B’¿£ ©4þ%Ep¤s‹Ó_þ(<bõ¸7"s>5ÓüF¶µÔÓ*𖩇Pà(MM=>%OULÛæÍ-Ô5æ'.Y #xGûwˆrÊU:ƶ\-Tê! )ZRu%”” ¼¤jK’xý^§âϳš´ú}J_u©Q ¯JªŠÔ+Prªa`Ó)—§SU5) @¥Cª³Oí‡ðåÈþèy/ªñÔΧx‹çîwıNbåÑ„c÷4×ãØÂ(ðÚ|+‘ð._¡z˜aE;S°Ó©~¢­êÚ·|µ<–ZÇõ¾ƒIIèýÃ]+2¬¦['Qxª&®bµLÖj¿Q¯˜ª”¦Š*­m%lµ*cZ”jUWAð×Ú2ó¹zùž³ž¥™êyªè(šJøÕSI":YL¶V‚Þ¡BRu¨µ­)Jtåˆz¬:ž†§æ 'å¯ö…šJôa|ÁFª¦’œ-»ëyœÆjµ I«VµJTU¦š*.¢©ÒxWÃJŽ”j`¤[KÃbo¬[8v8ÒR•aJËiq¼Â%R´ØØ9IƒÇ©‡Â!àTCÐTÌh¸~!ßJŽ+RPîÔ鼸.\‚§h‹¾Ø¦ä¬" Hïocø´âÀ0ÅÈî%ý-ì ]x-s}¦`qÜ7ÄÅ2P§•'01Ìõ@–uþf†H/&ï³€×·>‘½±]S r7pÑc11©©Ò€àM„$@hmfO¦;ÚÇX³)’Ý”^æÅËÇx2@ØÇ$/Rޤ„’\áÒgd‘.K‹¨ý”Þñ_þ-y¦ïáÏ¿Ó좛ž:©_&’ƒ‘ðÊg+hÜ}¨ÇëG€Q6—ãŽâ%h(m—lTÌRéÙLÏW¬”®žDSN] P­Ôj•ýÃ/¤ƒ¯RÑV½TGݲم *Ïxw¢+Ä]g#Ñé•U*­žª5ãôú*AÍÕ'S ©Ñ—¤åÍzô‚JIqôñ?͘o tÖ“yz™š &°ÊL Ãéšv))˜§E-3 % µNÂi–›@BBR”„‘úŠÕÔ3hËÕªªµ+×ø™ŠŠu­kª¯‰UkQ.¥)K*S’_S—'êLÁ¥É‘—B(e²Ô~^šŠtéSèÒBa! O•) ÃHK$ h;íêã^üuC˜šy4ØÆ-Ënr.$-(yxç6NÏ’˜ X§O×8”SOHë¤B8Ìçœå^Ñéê?îÚ9e$?ðòÉVk6¢¦d¶O-\%Ã|SJ™cQ:ÌÖVC#žÏ©‰ËåêÕ¦\ÍWŽY)Љ¯Z‘R]Òkm4ËpÃR²ê󨓙Õ$É$œÄÌ“y½ŒÁ>ýI †Î³6Á¦6b¶8¢×î’IsÉÚK¢Òª„ƒ¨9›y$f411üøv YÉnà)ä“&ñË»áI7r=¬?êo‚!j ±*ˆ±9„“Ø›‰'ç;߀ y„ìx^;»îø±!"éØäáÿ’²³JG¨L+1$=ÉÞ"táÇkqÞÜìÂÝÃCá½`cLLK^/;1nŠ?½F¢Âöêg¹Ü Z3ú»ú_òÇ#’ÂòÝŽá ry‰fì)`nµ{NXù÷½ö¿ CÝÈO`îoé»88¼ݯf݉%¹ÁÙ:IŸ/Ô{~ ¹‘ oMJÈöò ’×{A/ímØÿ×ððÃ!¹!aX"N]*'Ó&bçÒnO¹&ÜcË$‚æÚ×Xü±å¬¸f`ÁÒl<ÈQîîÓÅ­æ }Q7»†fÓæ$ho~û '2’d³q¸ó9~,³ã1§Ê G”"F¦%P_P¢7bNä≩0 ~e±²Ñ¼-úñè9†iíúÏv˜†*^›]‰¦ræ€KÜ-€$í—¹÷‰° Ü÷ŸÖÍÓrðO¦ðÃØÜÌá ;í.ì/Ãndï:[ ¨½ÉÐZdØh w"äIb8® Žð#åpEçg´Þ×d‡I°¹°i`'SÈ{‚H2Ñ¥½’`Úú“ 1`E i·83~¦äÜnÛÂ`´3ƒÈ.L0™}!Ò 8:Ф$æc0e@IQÊ£RL\p0-a³0r_³L8xÀw.Ĺ’òKÌÖ$‹Ð6½) @þgYÛ` 7™€³ðÖà3–‚aÞÒí8I Û¹¾ÿA /Ã.BgÕ[Á>¤ëy¿Îû^üF€òX³]ˆò»ü,wÄ?¢œ±gb\óë0ÁØa€ 4¼ƒºo¯hþûÙXM¸‡ögïßbÐø…ÜAåÝÎÌ m7áV,‹‹~¿†I¹þ€b÷³0Ö¼ò#™i`ª,˜bLöÚ\C0/óéR\} JœREÿ19Sï “úí$ ä$›$˳X¹fÀ°À’.í`æC»Ih³¶;êûy3èG„Þ’×â4®2¾xÄÚ,B¨éÔýC´¯bKõ!nNóõÔìW™i¤¦FT¥iŸjý_ý»¦uŠ5ª¯Kð^­B"Ê­™Ët<ÏÝt€MO¾#2ªZú¹¤¬T¼t³’s'/˜Y OPë94ª© ÉVq4Õ¨Ú~ )%JpE:aÀlgª>(åø{Æ}¬)§iºOÌØã¼Ö¢§Á°Ç+*^}KSŒd¬óÐãÎ!Ev †jÇ>ÎæÑ’ñ-ž•%y^—C¨ôÚH¤±_)ÓE²çGÄËåë! I:”µ«]¦§MWÄ­ÒQ›R€­›«C0¥)õ%?{Ìš¥)Ôa–…)dþY)Ò/‹_´M uƒ©t˜ctõx&Ì‘Õ µ:ÚØoä£B|šgKgÊó•€c:ØGœj\Q9Zp O‡ëÖÎ#¥góÐŒ·‰óËA2³Ó³ùud« ‡×–ëb‘^ŸèÐR‚ˆN'V«÷jýK.†5Ò2ë¤É|ÖQU3A,ÉÓS§)´ƒæP `£Œ5ç'øŸëf=ƒÕ£é—ˆÞœ;„c+ÈÓwwÁðÊÌ¢u >„â‰zžš´4¤-²—j™S‰XBÛ¿¤tºù¯ u¿ ušy„õÌîa*$‘K?–ëyŒísI$x¯Ë¨)êTËUBI*Õ—_X£—ê¹>¯I+^Z·MË*—U ý=Z"¡j¯.Š+H )MZJ/¤E¬ê¿†ŸÅáq8?$ô~‹ éÞ<ÎÍœÑ͘ÃÔ\¾ë‹EsXÅ ðfüæ×Ž=Ì]#ê©t:óT­8ß’’Vi·çrý;1Óéu¼Êh¯¢æéÑÈå>.bµs’ÌdM%SK„PËšõkTª€MJŠEMhO–® ·†Ôó=37O7“¨hæ),šuR )2éRIB’_ÊT¯ÓkK9×ÁÍO1õck™<@œ<á\¦ãn©ë©R¦­i*yhJ*Uýåun†ÐÒI€y‡‰|.¡žËRèT–¥fÖŠ¹ŒÚÁl¢ WL’ &’@ò£Rê–HçFt¯´l•nŠs]S1M9Š 1–ÖUë%‰R'úTHr¢gW6=Kêæ=Ô {Æk*ÖªÜO8¬«I-Å2”BpÜ= .ÓjP‹W*/ÚËgué]†B’i¬%_Tº­5«ª„€tRÒ RT<[¯ø¿9Õs 4ª*ž¤ªZ©QKRr>í—‡AˆÖ¨©YD•iAÐmõs)–ªm@¯÷¹Žl¥ÆµMÓÈéaÆJ­%“© Pƒåx>÷Ù†û¾ØÇtþ£E³T´ª ½”épRú@Ýèm‹xXè#õ»¤½{ÕDíoQ¹&“”z‰Ê¬Ñ$9QŠòÛÚp>lÙ"“OûG ªVr”¶Êê*? 3­uÌög)K¡ç)„SëÃ¥u]GJFK«eœžf¡Q M<¶{*Rµ0„¤ù‹uŸ ø¤õl·\éªE*Ù¬ÏMÿvéŠ?ÆéË*å鳨´*-’’u­ÀÒÇÿ½å_ýGc§¼·Œ/ÄÏ,à¸÷5´—Û~›ıæŽ%KËÍ­Öýí#ÕË*RPýJiÀJsÝÐ:n¦:†£¯-’ÏÕéùlÁN“œ©” Fn¸p?¤œÉ©–¦T¥+/R¡òÔ@G9ñÇBÈt>¡•ÊeB“˜©’§œÎQ+te•š%T($/ài®²êKW¦†J¢¼HJ R’‘&ä;X÷ïþW!@ ‰Ø6ö!ãrüìt—UƒÙ›ØKÃñÀç­ !* ^U%: ±2O¸Ë®f5áÈÐMzbÍ&}¸#ÏT…†°,I$H™Sí¹k°%œŒUxFºÊ¶Ym+Z— ¥´§1R‹jJa)’fc( Ô žе–Šhk©Q¦€åKZÈ) êQ, ¨°ïå:S©J •‚é €Ï<ÕÜ1†/ôû¼ #ÁƒæyóŸ°q„õ‡®4øo<󋬖±,—ÓJâù3•*C.ÓTQPV=ŠâTjʦ1,Z¦™ä¥úU%::•!RŸI ´¯-Òuе­tëu*©Bsk¦´5Q–ée)Ôr…ŠU*ÒtU WÑf~_Ié*ê¹Ê+F{¬ ut):jQÈ'â+)L¤h5Bך¨ƒç&µ4U Z4"®|þï>õT¡ÌôxeBêÉM¹•’£t€T¢¡¡ˆ"dϺBTºÙŒÝB£¨S,õ•ws¥¤–;È|mž"XP¡•A$©”°x;Ä‚ 2Y0ïʯ۷â8ç2ôã xMxrŸ—wžy¥–œÌÚU¨ ÀY|@[4‡¨P¸¬mq$ìþ¥÷êrª]>‡ûfX³˜ÌªŽo8A¥&•,JEE‡ó9wŽóC)‘Ét´)"®f¡ÏæÁþ º`D2JÕ˜X‚ªtÈe ?A_ÞëUSÊÝ.èõUbÛ*¡êJÞ\ ¨p6]bR¼òT§ÜmÇ\ªó·BøÖzŽlæ¼}š©OR(ÖñPËSQ)§ç§Ó:vk(º€Èêë tèË”ÊÆâŽžº^JQR½“J²Ù*¨4ÑÏ×Fi)%AΜ¹,ª„±aŽkz»Ôlkç@å. ýE>7†¹L¿4-*t:Í]z yŠb©ÜK­l¦aUÉ`yŽ•Ðºm·N©N­ƒ•®…é‡A§Q9r•oüqC/@F\,J óž­™Ífz®Ut«§5F¥™¯MI ï˜MJÕ‚€!53)‚Xsº8Þ=ÔNIÄð•ÔšìG“pÖ( +šÖ(˜R˜À1v|¡ç9IDãÈê_FaL•0‡€aàâ<ýwGNÍ«©"™øÌÍʪ¥¥„ ”êjd f“IE ¬´UUVÛü•«›ËÒÉÔ:ªeSS%V‰wû°¨NZº(“•¨¤j)ŠaÂUL­Túúè爾Zë†î›tÛ¹cOP9'‘¹w“ëéІé‘PàØ{T˜’ Ož¶–Zm-â””Åi]bTòTºj†\sÅ×*PëW3Ôò”é&¦k5ñ3‡T=PXTU*«UJÔé,§îõÁ[V¤¢{JVg¥tÚ?2U¢4–'R¡O¥!h JuÉ]–BŠq²î™õ›§žzKËø—5a?·ù§™«èp.WåÌ3 ý³ŽVTùDa˜@Û.¿UˆW¾„7GON‚át¶·2% R}™Ž«_+W+ÒºNQ}G¬ç(æó"•6Jª*†]KP©\²hQ¦‚U˜Ì­h£— jÔ¨´!*#ðrù¤×Ì×Ìœ¦Jš¨Ó«P¬¥Öªšr”’¥j•T¯QH¥MJ Çmo<õ‹ž¹ëÄz°ŽGä…⸃ضÒþY¨Ãñ/CF´.¦®ÄÍC®£¬v ùLâ¼G-—êh¦s(êÝNŠª'?Ô2Z‡J¡R© ÌRÈ,è5é ÍE+E$åôÓl¸Q×^¦;í‚’êøY@ÖFC&ºH©‘é•…u ïÂIøUz‰V¥Q¨i•Wø(:KU%*M4s¼U%vÒØÇ©7"M䈂=âmÚÀbÜ3Ÿr,,w1‹•¼ÝìÉ>þ€›íh™æðldL 2 ˆ-bc€dØ Ø12Á¸b¸ ûÀxÙç·'gÂe,OÈDëÖ DŽ!2Ìî!„Ç" 0û톒_g´‰ ðçnaˆ`Ǧ].çΰs¾ÓÞ›rÎ-ÍÜçÍ‹Xf €àô®UWVÕ<óIP”„¶Ói>cïºPÅ;I[®­)IPj4—Z¡JAR×QAé%!ÍJ«$&šIQ¼$ìËå³¥Ó¥A «V¢ô¡ •©Óæ’í¹†Ópã°?³£ì°Ç|Óó§;x§¯nš¯ä`s™0^_ªRhyc“°jù¯b»QH©z½ì.–“´ÈaºvêZ¥v­n¡Ôóoø§¤Sè=j¢hUÎSéYjf¸Oô•žÍtzˆ©ÊåSIb±øµYYekEz¹Ÿº”§-ðž§ð?ƒº·Hê]0g3éTΩYD¦Š”¤å(çé-êV«U)O”%ºMþ#ª«‘K‘î¾õÞ²u›ªK4ßtkù×ǰü<œ;«Ä_V‡$¸¥¬¦ƒ M%.u(­JiN,©jQ;G…ú]~“ÐzWNÌ®Lî_'HçêÑJQE}BªS[¨T¢„%(§AYÊ•¾$ŠTE:i B1Æ<[Õ)õŽ¿Ö:¥¤åsyêËÊ!eF¢rHY£’ME)EKXÊÒ£ñ¢Tº…j$¨’m“e BJH•()wD™XÄŸ˜×SÆÒ„¤åÚ€"ö;må<“bV“V·™Aä$.Ü‹ØÆÿòA,}Zzrµ !$æ7®9®dÜH¸“¡$¨òBAµ.Xé`ÌA—€b¥dÄ2‰.ää¤bTCÁ$[)ÿgÓìÎOŠ~»]OÁ’çC: ‹PbAŒAŒÔœïÔ„%¬CåÆÛu>UVƒ$5óŠ–ÐKx^âUûUKgÇÔzˆè½?ïiPOQΚ™n’‡ÔºHH)ÍõC>DÐåòjtª¦n¡ª‚¡’ªœnžðʼSÖÅ\Í0zF4óEd½<Öh²ò½0é¨GÇÍ’–F…„œÍ"®Ù¼Qõ—–9Fªš‘Ôµ,”%!!  eM´O¤¤ Ü‘Åú­r”¢’7d“và.LÌ÷3'éáQ:êTYdÓ:€uj`}6bÏ©™‹èsž:©ôó’y׫ÕRš<; ¤Ä1šº—V†Ö((Zyå¡°²R’€†Ñ'ÌyĤJæ ºvFŽ^‚W3˜ ¦ˆüUs@E*v)uV”îøÒ—šNg9™ÏWX§—ËêQ¨©JhÓuT[CŠtÐ¥€ê‚à‡Ç ~ z»ŽõÓ«\ñÕ>auÅâßÖb-Ó•)Máøj]>†1*%,a¸c4”hë  ÜQ=3 ôÄtŽ—–ÉVšUW3[H|Æo0£[7]WÒ*f½v¥KáÑCS¦8G]ê•z×VÎuƒ@®½9z`Å ¥ š9Z),ÇáÑBÔMJ¿²†¥©¬²É%*ß:¢ †‡æ5ÌrZÌàZÿË4Œb D=÷%¡›6ã)&bg*ÖÆZ9¿±?N ‚䪷äö&9cµÙ›o­ÚM¿~Òpd&r›în žÚØÍÉÏáÛk%Þ!ÈílÝ…ˆýÛÖß.ø:û¸ø„1ôµ¦nfÓÃÌ»ûì$Ë1‘°\»†kw¶ÆpøNb`ÅIìDrÖí:[^ø<À1]®ÁÁîC‚ °iÿ“Âç–“™ßÄl@YìQrm'{΀û˜×ïûÚ¶sòpoô¶â)™aµ)I "dż²/§y´ÚÚpе\‰·`9<¶ø%a,îÄ3œ¸kŸûÈnHe#•©sC3ø,0bfG´G´¨™Q—ÞGð¾´AÜ“_m8ºMàd‹pþ¼v³b¯øÍÉ\Úó¸ ;Z¾·±ÿüˆ“Úd[¾ƒˆ\8¹!ÎåÞ \ÜA ± áA{ØÞI{m lnlûDL¥û:l"Ó¹‰±"$1.Ř3Áy,ä°ÜÉ÷t’’,B Ùà¾ÜYÜ1v|:J†¤À›€4×yßS1±á`2lloX=§%FæÅá†Æf@q/'‚1A§Äd 6­5;ÿƒ¥™Ë’wkaÚfrnqRƒC ÌÀ‚9À¿l0¤B=’ÊôímÅ»pûƒ»p÷³Ä¸>ç fÞÐÈw8¿° ‘)]Ä—ô˜"ÛëbaRm qì>S6±pÃ816ü€†±ihw™8b~ 6€"ḑô è í~v$) ¸v7Ý‘ˆÆÀðî\‚>xà0e˜ 3¨oiÿÛu°£~ “¹ ÅííÉøb 1h 00ÏÅ®CáiÔ>ðÖb‚ì(Á9AX“ q› ‡ë@%A*P "€HvrË»K¾’¢€ ’\;{'³ÀúuOáË®ô|½Ð~ŽÓ‡îò ê>çNïšú&?HšsL¼ËuÆ©éÖ¥fuJ(²SóÚbUœñ/ŠTª½'î)N¢SIC+áú«^¦dÑI¡™ª¤PË‚bqõÙ‚iÑð§A]"•(ç~+Šzå3yô%'Ì|Çã¥/!UVÃ`hþ©õj“«½#Æh0õ³Ý åzU•¶öGèùošqü)§Ck”ºó|Àé(C^bJ2¨! iXĦ¥<â³¹ ªkÌx·ÃÔ*ŠIÓS=àà3–aJ~™”R•z‰AN˘¨•%TrÊø¡Ä5複F_­ÒUmsR²*Ört‚é’AÑ2Ð?[˸v7@¦Eo(×TÑšfÖ¥æÃX®ì<Êp—›Ãªg©PJRi¡t€·OqÉTJ3•hVÔª]F…QKHIMuÑZÞ É÷ªh­Q )E5©×)n5žBªtì¶w(i¦§KÍV]ÓQ^ªkR§äÖ|ßq©R%¨¶¬²è©@Dßß |ëƒôß®:çÌB‰ìN1ˆRRs&Ú–ãN`5ªg æŒ2J¿ÒS<ëì¶¢¥(&칊G R Í ×Jê +¡PVËVª¤¥:h×*9LÚ˜•S©¢¢ˆ`•S¨¦rw®ƒUt³¹.¥’Bi*¿ÂÌÓ§Mzš½1Lf2à³* d*MD,:„Ǻ1˸F3Ë\ÛÓ¬^‡ äü=4Õ'Å4bxmb•S€ãxE3/U%…á‹f—UAFgHMC+.§˜å3Jé¹ÊŸX ªU~æªEAUnˆ—QIG•lêN²I(RÊ i¥4•Ž÷S-O©drßÔ«Qµ0ŠkQXÔh)DMj UD’J”T 3â“«¸=c/USʘAåŽY«Ã0®`Åm"‚«£wıjp©ºªÊ¦[Ìykû³¯Ó‡ƒO<•{3N•qÔª+1O(3ÙdäVRR*žª”³5ò©bæ•jùj5®¥*EI! 8Ö“Ò+Ò©“J)ÔÌ}Úºó%*Ò3) EÅ,Fªh¨´BŠBÖRA$c–ßµ:¿Â Zy[æ}ëUv(ª§y€ãjW.`økõ»W‡aØ[( <åCªFwT·‹h–øR|³ðeLÞc7”Êt,¹£ÒrÉ*êYÚÔ]YåŠ#àÒ¦µ(MR¤!‰A@Öê#SûMOHÈt|æ{ĵzµ`¤ôŒ ªMZjYI«Q4‰Rj 2Ê)t•h`?j)*\'QiãÜ;’1~;˜¹ÝŸ`Ç{Ä1\Y¾7QrO$7L[*Äi62bDD^va ;½åÜûi³^äK¤ùLI6`ÒÃÐ,=, ùƒù†Æ$ˆ¶ò$ èm¹RÅϸÕ¾€9ùà…ëÜ݃¸ÙËI‚Ûlûì²ñ‘É |B¢ó¦ºÚjü)Ü‹§¤nº§—ª^¨eb 4¤-äÓTÂZ¨z•:ÈJV¦\l/*W£_3ÍdòÕ~c0ªD)^TÔJ*¢W!–j$­T4­I…chð×_Éô>£÷Ìæ\Ö¢ªe­6Rè+V³TSVTÉaT •¤ IMB4žÁümø°åN}û,ð`ñà™ +_ižq:Ý*l ª"ÀiƒsH71ÞI³¥¿«zp.Áž[kµÊ¦»—'sèdccË(§m*’°ntψ‰ˆbfH¿®@ I\“ 1h»µ°Me—Ó`ÆvÏ7™e¡ ¥03,iÿÉ:‚4î/~ ’‘,ʼn-v'2Yã «Vî ï`vòÝãf´†Á#:ý:lù [ßpb>s5¬†Tz~ûúì˜íˆ !œÉ1wbfFñ|d?#¤`ªpÏÍšslÌOsóˆâ¤9˜Zç`8,1JË(ÈKËϰ6@yÜâÍs*Þê@±•€,/æ™’>-fà˜M€UMï&áˇ$›0;=ËMËsª?Ó*P€’ $@– b,gsŠ: úÁ€NeÌíêA‘âû^#[Ž.J` å¶f  ÿŒR²äð“6,YîáX1=Ë’&¨“Oµ˜˜°7´ÉOùɰÈ A·y n9ƒÎÂû82;Hi ÷tR"}Wì#b’ Ô ›#ÌÀÃ~úµðéctÉáÌË1bÆÄ‡Âƒ ØZ†½É#yÔ}c~@‚$ö=Ü–}÷.%ãSÜ0J‡áÚv`ã¹.‚l0EA¸’3“'÷jÔ€7öhÛ‡qƶ@¹ipòÁÙÆbK9Ä»°°{€ÒÛ[lhÙ?ÀÎÂòu`LûßXKAH1€'¹õ–yÂAf%Ùìä –ÜEœ³‡$N‹¿ûËéÜv:ûØð`9f6Ñ&x<N ÞîâûY—· 2û0ˆ…,5“{õ;žó· 剽¿ !Ãrü æóˆYÝÁpû Ç®âߌÃéMâ$Zÿ»×¹gXè<Ãl?í·á¶¶˜³ îËCµ“/{>øp—DÈ ZŒ:î;^ç]æx wc-¸Ñö}ƒ´ï€Ì@à¾Ýçß³;–ðãÎÏWxc¦­..©þLªÆpúæ›m%ö0¼9ê,L´•¤ÂÞ:–T˜¹cÂ>Ñúnäj’K¬ä(Ó]U…Ê^˜P7˜#â„ȨhÔ RN;÷Ù—TÂYìº|ùŽ«Y4 WÝÃê:Iq©4YJ—RX¸'O¥MÑ~Çæf¤ÿ²\džzV~èöyѱ¦Í9\e¦+Ûm’”"MMD• /.¹Ô¨fU‘ROã­Ÿè ¨Œå ¿‰ºr*T c]Z'P$µ<½7JHen™\Þ\g¨Ô¦Ãáäú£årÕÿÙ³æ2™H „¥F¥EªgÚæfÏ%ušyj•ì)Œd8Ît—¾ãK‹ÒÓS9T@ Îà ÐÕTÓ Ä©‘-¼¼u~žÙî•ÏÒqšP­A@šuªe3•j¢’ŠˆJ~*uÑMg&¢Ô•j<¯7Tt®«ÔzMd¡Y1^žbŸ—â*…,æZžZµD„þ$ÒW­R™r¥"›‡@ŴDZjŽ_û½$&Š8¦ †˜¦Zœs Ä0§5C%ÜéE9CéZÒâMJÛTT)#1C&œå$Wâ®®NAR¢JS^ŽaÊIAMeIZêR M   zõn‹YYEƒF—P¨È¤B••Ìe¼•ãZIU Љ:t¦©¦Â±n~è|Lu øw8tó¨æüÅG,«—X©©8qJq”Óê+Ó÷g êx2ª:FZRòÔƒÆ|[ÑhPê™TæS›¦œø«¢ª*¥  J j èPBP€”+âR$`xŃ;ÑŽg.Œžr­!jCª™¨GĨø©ø…Jièb#üAó?‰^Eqx/P?ÚþXJ’ Õ#︊R˜#+O2ë”Ê ¿ ,:’Hã×áÞ‘Ð3U^–nµ5¤VRÉ ,i¬§R‚aïñ—Š:¾W+R¾R‚²”iU 4‚õu(ÔIZu=œ¥l\¥°×O?aøÚ›Àù§©¨«o˜Ù®M3õ.¸ëªVXšwó-ÂIõ¸!"#B;oIF[,…d¨R§KáQ¥\R¦€”謪ÔÓ@4 '“ üGãÕõîrWÏf+fNmU¨Š•Ô¥¨¹¦¦Ö²H5’@1´[Â…%*9bÂñ`3$È~w‚vž3p¯üä ƒò<ðTFÁÁöÕ·}á£akå.iægC·Ëxÿ0¾,[Á0|KróŒ>š¡sÚum@Ê5©’‰eŸ*XD’@-·Óg¾•:µŽš(©UCûi!KSŽÉ†H¶.†/ز˜wA:ÍZÙMÓ>uy NÄ-8!MÁA2" ç9Íå)“«3—‰.ªÔÁôno z‘Œ‚zGW¨/¨¬~"S“Ì~â”;÷¹;â¾äï>*qümŠ*_½j[¡à¢•tËœ›¸q¸œÁÛÔ‚2æ73Ç£/œéáf¥LæP!õ+3IŠƒéj'g`æíŠ3¯*™§K£uEÕ©åHNG4K‘Lù]”Oyݯ…ϳ#íJê/CºÏá· èv1ɽ&뛜Ÿ‰×ã½\Çä”9‡–9ŠƒO2Òᵨ¨Æ±fq,)‡püRƒ åú÷ê\FT[ó0ôŽ0#Ît. Ž…V¿PË…ø{®+«åÕE?z®ªUº~{'šÈ¦•7SV^j–g/Qj§N…ZU“­ ÍUYÛüá?&‡YÈ´UËdºßN§“©[¨Tû¥*5)æòÙª•”"…J5QI UDUAÒ£I)•ðŸýš/ý)g æÝ@ÅúÑÌ-"™Ú¾TåãQÉœ„ÓÍ]t«©mç9Ÿ¥J³!OŠÜ u-ÂþçJT¦Æ;ã5¨¨tì ¤‡ò×ΔԮçK,eЯ…OHe*¦e ¥‰ZK“Ñ~ƺVXÒ©×óËêU‡™Y|±9l›Ë¤¨ê­Y*…/ú%B4¤³oÿ§<™Ð|©MÉÝ'äNJéÇ-P¢Â9[¡ÂXq`ªšÇYBj1*ç@üCz®µóë~¥Å Ç\Ìuzù…&¶s3S0°i¦¢€B§:I!4é!Ç•‘M’@Æ:fW§tÞ—Låº^G/“¢)!Èò…-`•ÔPŠ¢Öµ¨$€ÆÎõ{Å·.r…k‡¦GÝÚyYŠÀ -¥V¨¤I‰ ØÌñ€ÎõéWÃ*¹#þENÅ¿/kA,º£V’¤¤€„–&,K°%ÝNZy.9ãñ/ö“s63ͳùe5˜wßK.¾Ò” æU+8BB‚Ba  ôÞ`@\žC1œªš™…”¡ª- À>R$¾¢Ä’c8§Õ¨åÀ¥@ •P•!2ê³:´¥à¸7 ÚN°aïc£Ÿ¹û¢Á)˜©{Īkê %ªd¹R •¼¤€Ý:T¶Ø*Z“”$8¼¼lÙ,µ>ŸD©(]eS¢µ%I]JÊ¢”5HE4EÀ Œ^c5÷„¥uêÓËR:’~2…*t„Ÿ5UPZÈÝÔÛžt|Pu²¯¯ÝoçÞ¥ºoÆ1eRòå„Í,á‰ûŽ N¤ÉòÞ]I¬ªBDÖÕÔä”Ãý9}7§R§˜Ó÷ÌÂ×Ï©'P¬É ]$)U<ª<¥²JéPBÔ”¬puJ}Sªæsr~éI²Ù R£• é§QH"³ +Ì©~«ª:P–ÇR Ê1Órs3 "o±ã:Ëp9²I±çn!±®(éÁÞ û\þþ¯>·–ÛyD²#rs ýcÞÖ ëÇ¥ 0$Aw€.4ìณDžjW$»´ºœ©û†H&Ü *H€ ü6ÿ4™>A½õô1Cñg‚ÇH{€îåïbåÃÅjQâL’ž8gK’>— óO§9äî›Í£„L±hsg-mpï³I*µÈ Ù#±g!˜ÁPH €)2gU,$ií´AžÕ¤0bDp ÃîeìØp]Ü+%¼¤K1´€H=Žî V¦2ò.-ùŒƒóKÇm¸°%04TРMÄ‚“bl=ì`̨: C1{lÃlIªr0Jר ï`t'¾™n8E‡–2`UÀ™$ ØIqrç¿€LLc$àaøÓ¯þœi­}Á“úN*Pn`»Ûüs³¾Ç –‘fˆ´acÝÞFFr('´ˆ«v`‚ òiô¸ùi¶úð(ÂL'ñ‚ö¼DN)XÔ\…À8$~Nþ± YŽe)ûåIÍüQ¼Ë‡KZD“>JdÈ–Ô`\Þí.o¸Æp  A¸–p.@–:I ¥èꄤÎÅ{˜¤DÀ7¹:'BdA#bì ±›s¶*R@P €W0Á,d—%¢Ó"A¶±ñ.'ú¿Êü0RBnæï0o;Nà77Â1PhÏ.ÒÆÇÌÂ’%Bl Ș3¹{Æ»ÜZºƒIpÃi!Ë_}â âÁ¤å‘`áÝÁ¤=ÜÁb?¸³Úɉ:im"î}÷7à`>ÿ" Ù…– 2ؤ K“ÿZHP†.&g¶b5Ÿ÷J@™:ÜI¸î$…—6úòaöÝÆ³ê ,]Vu._v,*Ù 6JgÈoÔv"oÀ»÷íywÝÉ`6`HáÈHfat‡x¾ Ìãð»|œË^TÝEȈI"-ÞdöÞc†YÍ¡£~ —1¸w$¬`¹à³èÐoh£ë bHj¡5¸u/†0õ:ªQæSÐâ âläFbSJ[UD´¦ÊO'ãío¥ÕÎx;/Ô2ÃVk¤ç3ª K Š9…tŠ( #JSZ²Â<ÃJê•Q"¦¢žöSÔ©ä÷yµÞi†°—)òUqô÷HêuêRÿuÿnÎR¯˜Ée¨ †gM:” ¹ºÄæ«!U’£˜G£H.©JOÆû¹ Jÿ.>Ò|ѺX­á|犺7XGIÏfj÷‡jÔÌåk®ºi!T骽:)MD JMýDR["𫲔ž|5g£ìÚðåOAV߇ì«ÓF.so[£¨u.<ØB”뽉°žM¢Pq9Ú]7-¦©¯H5JË#ÕW;׳‰Q5“‘AwNH*@ò̬¯2’A!_­4¨¹( ãQÈd<#ÒÊ~ëÒ2ùÚ‰.*u-â¥uQ¨>èY~aý¤¾£ÙvÑ“r +Xw,r&òÕ#inš‹åÌ £edbš†Š–P„œ¹B"ƶM‰©˜«R²Ëê]jµ+-Qu*¢”T^]Ë–"XŽÓº®bªO+JŽ^„ÓËeéÑBŠHJ@hc b‘æJþYÁ›p j£1ÈÛl¤€°Ë §¸&&F"½:)Wá)1gb³͵¤Ûm¦ŽatÒ U•.R.¢ÎI1q`AfùZ$s¾šµ)´0'1 ÊI–$XMÈ"R8¨*™”% µÜAŽÅB-y#Yª¤"YãÊU±$œÎŽu£Âhœ[ki T } È ’A“Çž¾i’>F©} ݘoýÁžÀ8NeI t]ÒM„¹ñc}—ÆuÅ5%|"½¨… º*miI±’A#Œbó+N§%Ë0H€Å?ÿ´Ïøˆ².µ6°ä«bйÌ@¹ß\ýgñ¤ÆŠ´·ŒjJ\ÊÓuŒè ¡!iõ+P ÈÒ!Dù\ÍE0 Ë:eO¸g!˜’àÜ’Lµ¨ø2ª$¹vø€p8$MËëO]yߟ—]S_‹»‡`ã¯-ÚËa€IR–µ¬%-%E@ ¿´qÊå U™D·ºSÀ"BÆ$‚q‚ê)YB¦€ú«d´* $›¼10 êשÞ09 ‘]¨ÃyE–¹ï™K­‡[t§—hÊ¡ž§J”å{ÉRFzj$­³êKµl­%{ÉtÞpkZ~éD”ºˆó©…ƒCËå7Ô¿†4”Š’%êž*éý&²©åôõ,Ê\iBÇÁ¤½$ºà¨:Iü4u* TiÁ:èêwY9ÿ«8¢±NqǬm³’ƒ¥þé‚a,bƒi^Z·›Péz® ¤ЇN]Ó%Ór¹‘EQMñ+TóV¨ò‚¢(Hü(@J%A%JR2êýs¨õšß;]E $QËÒz!J$„Sº­ª¢µÔQ A!)¥™V˜@'}}ÿìl#yh;Y¬[b{ÿÈÆ!3 Zïî4ù\´žL17Z4fù•¬XüÉ$X ,ȽÒìnðÀ´ü¬ðïfÅ5 If,m書·æøöL”&bË6TF¤÷Ò Åõö½áLñpà;€ážÃcpÛxt‡" †à³¥¤“µ¡Çl4ÈÄ!»H“vI„¦ƒCÁ*3`8`Ì}†Ä<¸¸`Ò €óÅõ îCî„ ÃÐ¥)dl†ÐDBˆ˜îýäIŽ\–ï/ë °4€£HI"îI–’§‘.,áMü]X* ª@ „‚fgUÛo¯ÎúZĨ‚EpD3ï·9N %zK9¡ì’Ó‰Pv<‡|A€©Þr,~gkÌA‘nûðÚÊ•°p™pH‡%‰%œ¿¥ðÜê,åîÛ–ÂÀG«ó‰ŸIÿ`@´J$h îMÇ} \›:I³H%¡à‡¹,ømŒ‹Aq¸Y¬/Àc¾É!Æç/îüÀ]µ[C vÏ¿(–;ÇîĹfûfhÏ _Öæûc#ù ËýíͯýŠkèuí<* k<›Ó,$@xìØ¬’ 4íV2áÞ_[™›}ÕT\*H@óHIU)Œ·&AD>:o»¹%åäX‡ó1±¹ÍŸÒJ@. Ù…÷Hâ*I¢êc4™¥Ì%HÛÜ›\Á‘¯ƒèÍ.ÁÃA. AÜ™|R¤† $º¤’CYçx}, `(‰*ÚÖ‘ñ£ç:ÿ¬pÎ8ÄÇ;~ Ú–‚æÌ¼Ð³ ž;@$›-ØèLÅÇy¦¤›“>îÌ Ài—°ž1`§I$X bçñj2äË’é‡Â©x‰€Dk&Â`ê`Ü+´ï¹»ÏóÞ_†d°ó) \E˜<†Ù‡a…P¸¸±& ÚQìD¯ò§è>R{÷m°ª’eÀ’7`–ã†ÌöØgåD$$^ÀúS}î?ú¤ƒÛ‚îÁ‡vHùÝý÷ÅlCå"Öfà³±%¯‡µ”\‚4Ûdé Ä€'YZw ™`’ˆ–³D½æpÃÚà0´ÜKϦe%HJ$D•vDs:°ÐŽdÏ”G̸yÚ~˜q$gm™„³‹Lzá'*D 6‰†Æ€ïï$ëˆ<³ž}Aˆô ‹h.–€ãM½w;»âñ$úÕ®çH$XßçÛ‡Q›Z\ïù‹vº0‚K¾¨bá‹i'pÆ›a¸ý<âÇ(x†ÇêkØmÜ-îGÅ]æ¡N´Ú-áÐG:ш­N)±æZPM‰j>9Ìéð®w íþçœé¹/¯3›BC°dÔê1 ˆ¤£|nžÊ*¿‹2UÒŸˆ2yLöm@jòšu).ó‚ºjÉJ” ‘éxÀðûÓ†9c¨ôܩаŽ`¡Æi9Íì2‰B¡Õ,`TÕØõ,¢¡ Ó+ 2¥!ÆÖ¦žRV•¶¯žúUÉÒWNø¬žC¨õŒ’’¢BÛêõ„"š[”dsy´d’íG1R¸r”(ýšéµêœÁ¨Js9¾™Ó3$€J†zž@¥`€àÔÌФ3“©u)|' ¨cZ½bè­_>ௌòÞ9Ó§mÐ.¿-5S…s'Ô01œe‡”kèhžEJܤ_šíÕ(sïb—¡ÑêJËfëfk€)Öøù.²ÊRU—ê9%œ®n­FVªÃR%! ÊÕ©ð÷eç´ÊÝ-9ÚI¥D).žk¦’„ªl¦dô(W ?úÔV—JõjNfˆ‚«#/íø*Æ(y»ÅN:]Ñ"¹Þs’°êb4lâôKÄy; k•aØ‹8‚©ë^Ã0J¯¦CU¬9HP‡XEMSkÚ2ÈÌg•S1KI­G¨fº²™']SÔòèê9º¡H (úLöhPBÅ*¿B°Z“B¦_ÇÓ’¬ž%—¬ð39Zy*h:ü‡!›VV?‡P’M ¢r™SV¢MT i4ÊkS©ôØè'Ñòß#a”C ¡¡+£g5=;®½JZApÒR©JûŠVé[Ša9 kuI „ñŸéôSK$Å I«©e&¢«EBW¡ +qN™*M6X:,ÈN‘W:jÝI4©×¨S”J(€Šh ÃJR ª§â!!%”)NTªµ] ä{˜hù—å]¬Å(óhqzÌúúsž@¥«vœ½L™CËXZ”§T>¿†²3£=[)—M`\ÕøH”TÃâ¸A QB| Kc~Ò|KÓ:mn™ÓúßS£—¬ƒJ¶R†w2Š J’ÅZh¨WWáV @”„À¿w ÂèœmÆXn–¬­4†P„„$ä"$¨ŸQQ12¯¸”i!Aa(BC% %‚4ÂR!‡íåÊ¥Ïæ´T«R½Z„Ô¨º‹Q*R‰Õ»$(H¶òKbïQz©…àȨ‚Ë@X’@)h¥î¨:N‘Õzý Ah¤–H) ]œÀ`vq.AÇkðǃ«TE:ùªŠÒÀ’]•èîJžÀ»mõƒÅ¦‚Š”·ZÞ`V ºŒÉ7ì¯HôÇŬë 9× Eþ"åˉüE€&ì#Ðc¦SÈÐÉSé¦êb­1ø§`Êñ'Úç)Å+\¤§ÄÚQqJJ‡„Ý#6`ñ>˜¹$Zñà­š«Q :”t€*—WöŽgx-©é¥P+2Ši¦U­O%ìÂir]„¹Å7G×’†—QQˆ†ÎRI[ÆâӪϫÔDƒêõΩg¦R ”¢­)X)ã`m7újRXĪRvÜ6äÍ-`¬cgX¼ca8-3í+BÝRV¡ZXÈ +7"&@ŒÄŽ. šù¥hH"àƒ6’Mƒi¿ΡQ4ëPH*p7a"À9i¿xÕçP¼Nó77ÕTµ„T8Ã.€òZ•$&$„Îbc4ñ¡Ò4¤* É“¥J)*¦ðMÉ$¬¥˜’äjuz¨5‚hR¤u$ATŸ.£¤³ÈÔ`ÁÕÿüÓ<¼{<×Íë+U?-au)¨}· e^%P ØÂ©äz‹Ùê] ýÞ™ã™C-“èٌڴP M.]l) !Mª¢™ÊQLr*øðg|aÓºM2¼Î`×ÍB2ysç5€VŠhÓ%µ*¤»èMEyqªî±ø™êWYj\cÄ׃rÐqJ¤å\×)ðä¢IJñBƒø­Hê©>J ªž•’VW¸ôî’éêMB¼fDšõR)’ÀüM!¡ýB|¥e:R9o_ñ§WëÚ©Ç%‘v,¹X J³Iø•ÔÚ|„ŠAµ|0¢¥œyW›5ôÈ”ÎßMõÀ¾nÑA“Xƒ6àcOQu\ƒ. ±Òwf òÖˆÁJ¬@Sk÷ê£m´%{ˆô—wöm£ßMˆhÚ݈/xne°ÄoyÒN“ôÿ^ÜB~Œ9vç´üÀ 1~y<‚ i›ñ B’Iæ1¨T¡í¾û›ðC i~{¡®ïÇ,õ-ÙO¸•ˆ%Éö?L{‘~ñf÷›¿iö0uTML 3†3hØ‚$ÜÄ›cǤùRÄ1Q Žo¤@,„‚$¶ !fgð[&tfý ü>ñ6+HÜÍ„6«‘–7° ãIp îT^ÎY…ƒD òîðÏï ü„¬•*DÄλ^òÄQ1ܰkì afÜx‡qˆÌIr@/0>X>…ìG–Ä‚tˆ"uÊ7:J¤;62m3`6{ƒ¼ÞD\=À†.ýÚî}5r h2ÅÒ$^À‰õM¿|ƒ±Ÿ_¼À1;2bnÄñsoã‹zû_$‹1»‰qRvR†êgÚ~ëI'ó.F¶Ì؃}i¾“Å¢#†.?Ï:ÖAÒåÙÏgtÉväÍ€‚Ü¢F›œè:}d ­¸$~£¨pGÓç… fa¤?k‡`,@r=ÉÂMÉàé o°íof´Ÿ˜xûEʰ%%ˆÒ&X¸»±`dB™ðB©úY6±ÐžÆvì2žÛíÿ{°"vø±w`ÎÿÜZ!à1öüŽ@ÿ1΀¡@ƾþ×0bÜN~[ïÿqóÅd\Oâ;• K°. ±k.ÉP°ä¥:wa#ýx2³8‹åýã¸ð«–L°ISÊ.KÉ{“¥@yöšR’Ðv¥¦Ô· !9Ö™Gd¤QÙ ’8 ÈáÄõåáæbüa@3wpŸ5¶a?W†˜“=ŒµOOˆ¿ML[S4ÊSIq° •­%Å¥(ÙJR'Ô„$Á¼1.Öà|Ü›ïú`(1a YWÜ8¹æìY®à™î^ÁF=ŠRa«¨M*T¾¤­HK )J   ¥˜BR•fPÈ–¹-é'³0y“»{ŒX)ë À鉈¨ò—i€÷pqWb£ËME;UœÅSNk|Ó)TAÖÃl-HS-‡å¥n6[AÊ¢‡•~”:´@t€lü‡=Á^݉¢Å>Äå6c}Ã% 1$1$œfÏ€R¾Sêg2VÒÕÑVPª‰ª#ZÛ¨}£†5RÍ{ï!h*hùÁªD:ÀZ”Û…)q)ûRΪ—KÉÒ¦¥¦¥<å ðPýZ )Ë¥IbE©F• ÌíÙ~Ç:Rju\þ~¦“Mj™”<µ€©UhWáIøi@ ((ˆ>TNËqN´â˜Ï1õ‡š+jŸ[ؾU…á3™ÐÚ±Q†9X¤y« ºÕ+ nS;TáHBÏ éý8Ððí ¯”UÌçrÕ*…0•*¯R«M+7Á–]J²R…å(‚­k ÇÌ*šºÉªË4ie”„0ÈËÓ¨›*¨”SÐKûÊÌ%)ňx”§å¿o6K.s^„ò×.c¸³hOžÊišÅpö‰l;QLpÜe†ŠYZM3´l)µ6…%loþ7Rë¹|µ*jFO¨g©f‚JÖUQT:(Éfi)ÉOõ«ô¼­ZkPó-‘Q•Q)©¡—Ëôî˜ÌV¨ÙŒ†Vª½ ¡4ëõ4f(Õ øtóÕ D†Ò•!Hd ©6cÁgQ1‹xôðÒy­ŠzÊZ®¯`.Ð×W)òþß4btx{Ÿv}Å©.aõ´Lãe!ÐjiÞakt¿Ó¼œ¡Ö(U­”VŠÔr•ò `*.• èB+$y~"LhXe +A!8ïµ õ³OôŽ“Õi¡Tº†e=O+P¥D"–aY5Ó©–Y,rõ)ÕR J¡ñ5SQó}ezoˆ7Ša¸uUJÖå-:Ü¥!¨ej@RÛ m!JNcb¥)9r„ ²£´ôåÒ¬”­ELK„¨;êÆLÈ`8ÿ‹²µ2y¬Ò)$ª‹(¨5I* ’¶Ëœ\,U:“þÎáNT=奦”T¢£r’IÔΠ ïÆ§×:º¨!II@ ãðáÀq.yvé^ðÞ^­Qš¨¡*päË~ƒ‡·:¾2<|a¼QˆÒ¯C9CÈKhyg!P2  D.EÒN£“f³•óµ”j*rgÊͦ.͆¢‚²ùt!J€$böî¥n\mŽ{:µãùþd­­mœEe•)amÅ)Óuƒ$“bMŒGåñŒz)¨§?™I!42ø¨”Nª Š Ÿ)þ¡W÷ÁÆõÅQ¹Åš¼7¨Ÿ‚9-)¬)k8½S$SQŠœ®4˜ÎÝtÄ‚P·]låãrÊôZYY…ÊÁ!IÓEödRÛ`µi7(*b9?Sñfs:èÊ¡9Di @R«àñ `êr) S,9Æ.>óϺëϺã¯8µ-Ç^RœuÅ(ÉZÖ¢JÔI’¢N²¯lÒR”éN”„° @›0ŽÃŽÚšŠŠ”TúÉrT¢¢I¹$™.Ó.c¾=1xs&Û gKm ÖäleÚ~÷q·æÁ±®,Yœ´Ùšñ`ÓÉrGÅ©ìü&~wˆ¶ÚÞJÍ̸€ß’òæØ¥‰ õ ÓYAAI´ ‚5öÓÜ àM½›ôÁf$´Cû™/¶ÛaˆlÝSÜ?C½ì'òà´³@0]È1¼¿·È´ËZC´|Ü^G 12›üJžß#iìGõ%’ÃÙ‰g–gäŽ×œV»˜¿}VŘßÁX @€Nu½ÁTöÖó´E¸„‰ld¸$‚ Nææì|Ò p„z3|…Ä‚@È»¹kæDÓƒf ͵ÜA+’óß³±ìw6 ÷$[W؈fraˆ†.ÓmÛߥÃ1vÕ ¼g:X ßI•[Ø;»Èh™àÁΙpÎÍ.XÛŽØq‚œ×J’¬ºAo˜ƒpRA ™$‹—-/ÄŽü àðI s'óÛ†W ?‡÷¨öÜëÔÚò{ðáØ˜"d‚7¦ÍÀ,Í{òˆpL܆•X$@¥™Óÿl63T‚ ˜†ìId‚v-ÈþV€$æ òÆd½ÄAžáŒàŸÄlƒ?‚˜¸¼6£ü§ØŸxáBœ^ÎÂr]ùµœM±bCCírߣM¯µ˜Ù)È ÀgOïŽÀAb˜ëÂSS%¦ k Fés늄¨¾…(Ø—x/¾ç×/˜2Š·à ’"óžæ?XùëÅÈ µœ’bÓ{lGfvb1œ €/¨.é,˜‡‡´H-,)Wã8"÷Y.d ¬"ýô#¿‘c؃·¯Ý±Qp¦&n%ƒïé¼’pÖ®`1kÛÌGê/ ­s$p¦Xµ¯ÜË{úÞýð© ¸%™žOü’òÓø‹±:us‡yK“a$ÀÜ‚-}#±Ð’ Àᘃë´ú ÃkÃò 5˳\„¹9‚6I±8˜,'@¬À„ß,z @’s“¦ä$Ø/¬|½,ýã—\8f6bíx z°N’O»6@*.'Õa”kå.Ê$N‚&=ÈáA’,âÅ‹Ëýd“2ï†)",¨w`%¯êÀÄ€ø”q´¶P>(&MÊb75¼ ïôãwõ‚-³â¥$8Ô[`¡f%Ë€䋆R=zq˜”h-Ÿ©´ƒÅ€þÚcû^6‘ü‰ÅzI*7oR\HÒÐ + ±]ÌÀ÷ È¥ÁQ7…‡,6?"=FÏìÐNŽaˆîM€úã`Ñ|T8mFŒá54¤‡YH,@+Cëe—°r©l©m¥À š$:‚”ž16‡9w†ß—%Ý‹)ñx$ê}I —‚ €H¸ïlzœ÷PíG2Õ­ C%¦›KN¡Æ™¤ºç’âR´¸úÜP2¥”(ˆ‰å-8˜‰‚a‹ù/ÆÔBÉÈ b`Ãÿq,Ì¢K³_? Õ˜5á MER(\®ò×G‡”ª¥Úd„¹ŠWÔŒá QÑÒ ¶ªš€ó·›ôi¾,Èåsyz¨¯L,šÕ¨¿À„)ÑG/Lé ÖÌÕRP”!ê+PÊè뼎fš)ÕZhœÊE<¥ JõAB«fkÈPËå)yê-mOP )NèúµËt9ésûH¥§©{  Æ+XwË©~—ö‡š0|¥(K*]bè**«_BóPª„4ë(†3qžQ=_«Õé´ê!HÉæS‘MT7«û°WQª–Y ¥“U<®]Ç”UUu „תŠHf3ˆèý-=[1IAU¨+2i)i^bŒ¢ ¿¶¦gâTP2QLFˆRô7Í=EæªÊŒb޲£û®.õS¯6à§y¥¬†”ÓAc(eĩ֔¢âÒêÖ>“Žõ’ðçOÊ ª©£ULªiü:ŠcP”9%jS•ªé’¥(«;u_´±žûí¡|鬊”ÂH¦šUštPáHøKGÄB”¥+[&)¤'W×~xªZ|2u_[T¸Ã\£‚b¦ŽPâyƒ–*ðÇ‹ä6B¼ôU0••':æ2N•öiM=ľ2È jOOñO9I+r•RÌ%Y‚•VB‚€ Ä„°cëoõmÖUâï¦ß‘ýn»ö{['œ©Lÿqèõr4+±MÔš€u²‚“õð'×¼®žzEÕl"¡ªŠ>}éï)ó*Ck M5V'ƒS9ˆQ©IŸÄ ÄEU‚L;N¡§ ’QÓúPéåZ†[9U4VDÕËTÓ[+UËÍLµJuQIqó߈¨Ž¯ÒúgV¢Àg2”—X%âºEd¹2D¨b —ÎjÊÆÖÂR’ @Ôè`ÄÈ5"6$2~’¥EÞCû‘>½Î4 ¾^¢k˜QØóØü¹àã\.ñÆh¹guUS!š…)^b¬”¡G[F†UÚgŽcâSI%j$3L‡mV6 ¥È`ý¥±Úz:´òyjiNš…ÔÍs ±`Ü@Ô4F8Añ½ÏëêOVq^Så%ª¹TÕ.1[^…-Æ™Yr i)\)ÈX¤‰’DßWèT×ø¹Å4¥è `ªÄ(\8Hò€gS0Œ·QÌ*™¡”ñ–VÁ_ÒAQ)«Ìd¥Èã¾5÷Ï|¶Ç$c˜g,ÖÒyØæ!VsJÖꦒ‚•~M3• ”œË¬©´ÒJŒŒº¿VP“éê=IYtW]‚(ÖËPXo)«š+"’lB©QHª¹Q'ËTtϳ_å¼OÔÓ’Í®ºPzwPê5IŠÅŠÅÕ ó)ФCȬ  AÅ“ç_®ÆjßÉÔR`|Í‚eÂkèÊY©Á1ÚT¦¨¥ç ª¦’¹„¨©·L„!æ(>Sœyrsá¤f*S¥S9Ó³š³9zégz}U*›%*ürõTTK®•RçIé¾&ûé•ó:NK1˜ËôøxRè½f‘#?á¯dQO?ªµZe?xÉõ<ºj-tªM*YœºJºó~ Ìœ·‹Õ`üĺ¯½4¢¦–ëî?OTœ@nª•Å’aØÌ‚˜R~,í'=Óú–Ržo!ðþ€ JR”Ô¥P5*À C±ØÜ“?œ;ð‰|׳} Å4³HÍÒ:èU]j•rÙü¡«¦–{%Z¤VËV %*`´(*T¢ªTF®3}D¥V’7¼L~“? Ê€å½'Ž}¿‘'HÃa{ˆ$õ/ lRä8ˆ& “y3Üì‘iÞÒ狱çwúû1€Ê2äb§€wîwÏ©a(z”j¡/ßAi·ÌvpÐÆb ;¯-ú›ˆÂI-p¦eK€'PdÝ¢Œ.¦w¸:73nÚloúÍÄú7Ho¯¯)$ÜïgØl›‚×7 0ÂlLe3eA÷1'y7±‹Ì=Þí´Xvq0Ø„]¥˜€æî`—·©ùXŠ=ó&-:‘¬OËY´‹›§6¸ã³>Ûó‡!È7}ÉØ›Åˆò¹b!´‚Mâé“{Lk‹6µÌááÁo«|ÿØPXKí! Âöà¹Ý®ÃH…I"M¤± ÄL‘"÷n nÄpYá›ç¸Ÿ¨Â­Ùƒ@»È6hiù˳¶=+"g:‡}Hïr$È ‰pHO™ˆ:€· ؾÖðä0‘åHGð›4X8,lS‘@“!¤@Þœ{ÄüÀp $`g—$ƒ!‡7—…ÀþîCÆi‡kÎR­Â²o{g$ˆ˜ÖIÁ.‘wbAõ îÞØvÄ%È$ˆ°ÙÚò ³z›N(5œ$Üæ$¬Ê‰6P("HI‚A&ÆÀ!¯æ1Ø’n,\LE°L“"@6“%ýœÁ¶i7j÷Ø J²ëè"H®ÛƒÀhå6wsi“‡–Àm-sy0}!ù¾%–13Fýå=ÉЄØmÀ Aí›=åÝï-yÃýìíî@ˆÿ{dçE>Hb &1m‚‘­ˆº¨ ¿f%Ý„ú“$í´° ˜v>–v '5ÓÐ`Zèøcÿ‡¥¼#å¶„ái¥E.¤pïÄÂHžÌ;njZذA®͘[ ¾,'0êŸBLî¹}.nA Ox¢‘2írÀv!Í÷ÛÓçšX!2 ÚAwpIb%Éw‘¸“ŠeÖÖTˆd‘;¸Ø™±Hbö™Òð@»s´pûÍäܶ)ZJ‹¤X{¸!÷‰g±$‰ØVNcµìD~#vÐÉ2>ÜpwÁ–iu¼ÁƒAbp€ L¥ Éy ‰°~ÇS˜{±fU?yªÊ \& ÜßÒ&6ây™å®[~fïmŽñ‹5ɸt‹EÉHŸí#`äÀbžqs*"nrˆ“$γ#H bgpàÄÃÀf!⃀J‰wƒÎ,ítìðKR‰$‘rN¨w¾—‹GÐð½à37¹;;Çvæ.áÉæÞ[7rÍpÇNÌFI„I¼#çS90ÚN’x?忞—ä>+ ’»YÄ7ÈMàâ©.\•ÌëSq¬Ì—Ý¿X‡$ß—¡Ý@«‚TàaZ´ð‡¿Á0´ì?06Ë¥µ›ƒßØ‘ÄpAa \Á Üí$½°ŒæþË‚·Ì#ÑßyAYNVì ¬¤„\’fJ®HÜÚÐý9ÿÀc–¶ørHÝ,™J‰ åA8y„T¡Ô”T…<ñR’‡V³)NXNeçÍÆ`¤‘ñ8`f0~åÆò@`B¦$ÈøË’¥@åÈ‚\GDÀ8Èn†s†ÉØËH[Tï»_]KNª—Ö[J¢uŠÇ ªQ!,>©M2ºµªT:• )Wñ&N®{(¯†j#àÑ«]! Q¨QR™]u2©¢Z’*.¢¨¬mžê4úwQB–šUU˜¯F€5T) SMJU«•­deÐ k(^¥$ÒRVIÛÕžoÇú›ÑêZÔV¸š 7Ä ‡_qðŒ6‰œ[Ī–=*®¨qì–VšÍ>Ä£Dð×I¡Ñz…:ÕiƒšÏåê”è§IÎS)F‰ó(Šõó=O3Z¨PŠ´TY’]{Ži}w"¬®^·þ6FºF´ÇZç+Ô[~—FO'B'×I9€TN¶Èæ¦ ”hªq¾Š¤²¥¹é`Š’”Ôa § p„•(œÊˆ§® € ‚ÜFÎüÈhñÁkjó f%÷,ß…Q»4’@¹»|Þó•þ:Kˆ-ô¸0¾dæ| ('2ÚJœ¨«)IKFÊ•sBJa\sŽ•Le¾Ñ|OGáéû÷Ié™íaˆ_Ã(˺‰¹r´’.‘ë×=[ý%ýŠõ˜ø§ øÛÅÞ4É%tS\fº€BnE=) ¯1I*QƒqÞ÷öc|EÕó‡…:.’ã•êz»¦58~áR×€bÁ¼o J’”Sšºê`JBØXO§U)9šà4Ô«—¥—®^~6E,ªIU\µ\¥WQ}+`Á€æRó>ÿo*~ÃÌåÞI¡]:ŠCå¥Uè) šEŽ:ŠÆqÇQLRÝAÈ LzHäA ÚAiÆ*¾héQÞá/v;ùÜI.CãßÓú]5VÕR™0!ÜûðLHÆ©ük'˜¹–±L6Š©êF§u<‰*RL”‹Éõ*@/Ç=ëÉ^h¨ÔQE2 Ì m'€X ؆Œo™@¢šI %)–Hd‚ⱕaÅñɶ%ÒL–z½Ž²^¨®wïJ©ª~¡)ÌjYp„¤( WÂL2<ý38¸.Ó ¥RA2¢H—SË;¢Óœ§V¡uUÒ¥ÉÐ$8‡bÄ&IÍmSu¯šÑõϬÀ^K”XEM/%áBGàÐòõ:i+ÂL©!+ÅN æTƒ &%\kõkdºz‚ªC;êuçú‚µSC vÿéù|švgSM¾¨û&PéT—Ž$·iõæ×‡ØsÉÂ2‚Ë3»Á´Ã’ìàïÃA¹¹ÖnF»EÌ\Ä[ä Íf³[a/µ½–`YKê&Yá\°6½ ÀG)uI$ì`;n/¦ =¯qÁ ˆÇo#g¸ûa]Èó[³¹±©w‹`Ä@&EÔ“¬~pŽã¸ßÞ$úô¿?™1‡b%Û~K;ÿPÛá¨fÞãs®Úék‹vŽ ÷%¸¹r õs…Ë5Ú_wúˆ&×lFÞïiÌn;/©R#Ë·ü]¦Í=#Ùðªbf“-ê{»öLzvòÚ˜•8©“]Dì†ómxv`¹¾Ü;˳rÃG –pw·¸Üû݈l(*Óf×S×}#i·%ø`"H︀w0ö8_31%‰$`Kõxàpà¹YÒé6ÞJ‰˜&u'娨ðÁ <»‡߸١Á?«9$=Ú ØaPn~D\I‰VdɘÜÌÉ›3‰´KK7®ß³ñ‚ðÙÁo2üvHz‹8Ú &ÖTÜ~³6ãgŸVÜô=ñ‘`I2X6ãï‰U˜EäŸ1PDض#óI, ˜IkÀ~Ýž;ÄX±|Yh !öívçé‚7ÄÀ?¹˜'D*;k˜'cc©0ÓU˜î=€¼@'l}¯»û˵ö´Xã'ºr„ž^$ƒ?}wbøz^àŸÔé E:KQ oÌXdz¹¾j$À6Ù@X‘!DظÍ͆DŽԿ0"oÜæöbÇX ãÍH3´ V‚Zr7öôÆml€+“; ˆ.b™Ò²!+*I’`€´TXÁHP™¤ qh°’âIaË7£pZîKÝø"Ý-³s#Èô‚ÈãÓb k¤ ÿ«˜±-cÞà³l6&FÖŠ€8à³l^ ‡2 `ê>éÐL;¬ö¾°bÒohÿ??LXÎ$$Ì ¸ˆ6 Ó¸ÃA>®ñ{kc`´ú¶#±àKsÝ |€âø—.à‚>›q ¸¸/pBM€Ôf>Æ[$Û±Úžü/±´vþ?†$»îÄ Ù»3m{ûà•?*E„éípIÝÄ›q-õÜY÷Ûò;aHæúH$XßÒcÂøD“ê-11y“¸ û‹pß…¤Z>=Á–‰"MNH#ÌÁ@œî\™bgp|4/Ô6:DZÛ{o¥¸,Ñúîã‹ûb%ƒ0í€îNöbýj0™‰Ê‰ÔzR”Lf5„à óx䟫½æKâT6rCmò‹Ž_f¥D(¿˜¢Ð¶Ó¨÷Ú#@ÉQ ,àƒc$ µåþx¬ƒ-f0Çw'V â16ÅuE3íT0ç–ëN©æÌ)IX%*A fA/” 6,Å,§ÿy"I“rpu(­+…üPX¸^¤©ä°.A6œ±ÔÆ\ðÅUBVâñŒŸW‡b l©# Ç•‡c ¨'2³!öðeÐ,«(ô2’”(j]o§¨uÞƒ˜¢[/™é¹Œº†Ç9Ò+fjÒ¢XZ ëh®à(µ:¤³¤+~ð÷THðÏ]£T›Ëgh®WŒ·XN]Š‚Xšìæ˜ J…dÊ‚TسÌV§­¤zœ!´c%·Qqøx.©Ilؤ6‘N‡sæ8RTã?•ZB2èÔMj6ePR)’\‘çQY’Ê®u$­U3uE= ûÒ~MÊ3)©Y!&ÀÓBP$±ÖÁŠTÔÏíì]Ì ¾[UcËÁ)±q†¨#3-WºÀ¤r¡*l„¡Iœ’$úßî9A=HQHÏ+*œ’³u«.š¦²i˜T%@€òÅØ5ßþ©ëªðÕTêÕáÚ=f§ˆ)tÏ/Â¥ÕªäÆF¦m* ¨)y`)”¾’Åa!D«OgĹ7ªTœ š´§öú+¹O§.åSuÔ4ÕœÙÊ5jNh WP£œðG7U[x5:en qäë P¡P€ÏDgèÇ”ÕÈÔ¥êycúµº~o¦gè ?ô:WRª[á’wßu4©ZNy|ÁéõÃ:†[>*fúv`Ø|*ú9ÌuHºžA‰ Œœ_j±Ð<µ0…‚\ô„©9‚¤X‹$¥çxãY:ŠF£ $»ºˆH¯³É >:©RBµSP”K„Ã9Õ-¹¸pÏøãœðì•qI­n›û«ÆÙL!FI"@6$“– ÏOˆ³:iÔJ*3%D'mW²ž@wrÚqœét“R° ´ÁUÜ\YÏ©v¹çƒõ‹«t<žz¡ÔªêÖªÃĤ€ªêâ¥1‡PÓ6#ͨ««[,2Ò Š–°c¸;‚bq‘ðÊ?ÝúŠhdSñ2ÔP¼Ø4ë-!Eb›€ôÒRÁÃ)ãl]f™Kl>ÚÆ`¤¸ èTÜÄ 2è èDñ­* %Ãä]΢Æûî÷Ç_ËåÍ*F‘IR~B²@Ò¤)  °’áˆ"ìqª\m µŒâ4mõí¶`ŠÇB@ F–1hõ.EJ^O(µÊÎ[.µ'R© ¨¸;’~­&|KJ•õúøzÏU¡D6”¦’3õЄ€ $$f‡o*}™6=§UÆúé;@Þ}€q.H‚Û\>ìò^÷w#^+aê–cûëõðÐeJ&u'ùÁ¶1° Û°¸°3ö»c-ŸQ…Kiݘ‚C3$ƒv°‡` ƒa E­¶ú{mÄ嘙C]ìÞà€=6ìþè`+pC›±/"ÁÞ›Lfne&÷yíü-"vƒÛµ÷&ÞáêqɹrC ‚&`ùŒDÁÿ‰2DßÕÛX:̬P†nþÿ”{Ûg|Yª4€H ìKðAØ0%Ìá[¾cÀÍÈ“k_x´ðÅØ îÁà3ϳ6¥Ë´läcõ‘`Ø—X°í°°Ô’džðm&àkÁ÷`ÒA½ 9ìMÎ’XÌHc,LË]ÙÁ΀ØõŸKaMù§îΫ̦USimÇ[M©r‚¦Ôòh© )–Ê~4¨v'ÌC­Àpå.t’H#VÎí :Ó¥@€éPÔ•8Ô†!+v’ÂâHÂù°Ë„¤æi¢V  “Ÿ(I›l¸½´áp#Óòf³Ç ]Áv€ôí°‹"‘u“¬…êb?CL®'³|®À·Èíß¶'ibGæÝùmçœ#C Ð ‘2/cúEÁ;ðû?ýÃÆí$ßÀ÷ Ü8Ûw›òØa‰iæ&Ú[1Ô"ÖqôžØYå·›^ìäA-ذ™î×`÷ôá°AZ“&#òFÄ[õýg‰Úmµ¾lü‡¦# ö‘6»ìÁûúàìÄH2!¤È6£¼i&LHÑ›öo]É¿`òÎIvŽýÞìó/íwÊn›3›—I‘÷ç@3ô dêAÜÞ~@Ѥ’ <Ä[€.í;Y£²Çûƒù@‚Á½q¸é©ýø²@äǤéެВB°ò¡:XÝÝ LGqleÊœ‘  $³°7q-±‡4»äg“oRÁ œÈµæâ/oˆÆüZÐÍwÙÍ„=ö.×1„Rc¤åÃ\4 06³¶„ÅÁ‘”¹·˜‹ßß¹÷Ž%·¾þÆ=9‚Xo½@80à$(÷ ƒ¨G C!2OÌ^&@@í¬X‘ì àâî &Ïryü÷¶ ’É aôÄ’Ñ#˜8‚$1'·´G¹#ØE÷RÀ€'§Ò ¼³ÁpA%·âC¸32ì0Ùß   3˜ïb<•[è-0/¹ˆ#™ãܽËÜÇl@Ëé%ÃéÌ ³ä<J ¥"àÉô§H=À:ÔƒÁÝŸÀ÷`û·¶ä"¬\ùXˆ€ð­É.ï„lYB`çŸÆÚê3D‹ðÇaFÂKm¶PbK†.%¢oßk8dz¿†Ói±”u¸½ï©¾œCrÈiX ¯wÖ›¾÷aÈwÜà’Ìdžc8=)‚L¥‚" 7¤LEà˜ŠB?7™~y‡/¸ÅÆÄ%‰)\†Gšæþmš° o‚µI&àH™±’Eâ8`À‡Ø½¸&Åâ},ج— %.’X9KÚmÚo|BLG˽ÄLÚÖ¶ÿKðâï{DÃÝ·ob@Q @i™±ôì\Û¼×|§Î•<»†s.å;uxG3RÓµXÊÀÏK]@êÞñeH u6¡‡¼èz’¥ô•†œoÏËŒÕ Qeåó#3Abè+H§Zž©?1M(ø€8ø”2õ¿·#ž^IY†NªYŠ ¡Z›ÁþêU@f*¢½E$¶ªu+R Jj¨â£Çq¼;ÀéêiÜ£[«M3x(%ŠºJÆP¦”ømÉóÚ¨ASžm:¢Uå:R”«C+Z–mh_Ä(ø•jШôÖš¤,ÓVŸÀ¤(„€¶Ô°IV3™ž£—¯Ó©UGÂ…<½,ÍÑYhNjaGMjk¤W©TÃ¥U4,%!$Û&Ÿ]3ŠSe T’€¤8…2…‚:‚™ ã8RJ ‹xbA Úgfvõ¨, Dù‰}ŽÌ\KÌ‚ÎøØgÙwÖfz;ã3¢øž'Š«åžaç^_À1÷ƒ¾[TÿzÅ(œÁ«–W }ÇE"”¢AU3•,)Y\ú(e~þŒÆDjT¡˜«“ C8œ¦b‘JLs¹:Ù¾š»‡R‡#'Òú¨èùì¶n¢´P¨Ò΂Ã-R½•­:‹œ¦b• í7 ¹T—b_éñ‰õ§’ù ’˸¿4á´ QáÁõ}⥀oËÎJ–VT@@7“ȳF•**¥Ð4Fé ¹úÀw³ßëPÔšf+5 P .Yaà wwg$ØåŸí&ûMú}Öb|“ȜԜiÅ—ZÅ1ŠJæÑƒá´ép¶÷™UOøn=„¶ÛêQQÊ¥ž5 ÎO7Ök:iÔM¤”¨…k¬]‚hÓDŸT\¼>3ù'§¦¢êÔ£L¥ ZÖ”Ó¢‚JëT*"˜ € ’\Æ9ÑêXÖÜOål5ÜI®DÀñÌ?Å+)³¹]Œb ¾”¶Û,¤‘Q_U漊Ju©Lá´Ê^#XæcäŒÊTèÔóYÜÊ(§8®Ÿ™ËôÜŠô¦.’¾&g2²¦„” TªV·J Y+¨½óÂù^âüï‡úFAYªý/-â>Ÿñ/\È&­JõC:ƒ–è&ŠÎs¨ç¾"¿¤Jrù:hÿqÏ-èÓ¤=Œk•šZÊ!‚aa {Ž„V>–š· §a¤$$”UV¬‘ŠqÝ3+ŸÒ¯ŠŠ£7+/X T©(Q¦’4Õ¬¢ÀI§–þ⺞J_õ¯ƒDe3Yx{ÃâR:b«šyÜàRPiŒÕP¡S/‘¥IÕ éÍuJ•i&žL •¥0Ær§îø+TÔLåhÕº¬ÁaE P Jp͸™ªŠ^ª¹ºŠ]UêP@SÔ Äj6H ÞcáèÙ@Œ¯‡²4²¹ ¹¥IyêéJ(¨ªHD(’„’êóTUñRTRiž)Wž°—ëÄ]J AÈ€H HBÐ@#Œ`ªT¶) I,ÎÞrd»v|nõ²wɯá¯ïUE%Õ©\²‚ÊiUPJ@)H¤3<:Xy±©Q^f!XáµÔU)y”+UJÔ²T#ÒB• ™‚>³Ê€œ¾\$8)€/˜LX ‘¹yÇà·\Zêõ~©QpºC?Qn!jÎTR¬ ‚H‘É>lœ®;sCÛ¶ƒ[}MÉvpa„‡.óó'´ãI'ñ]RX˜b;ˆ.Â;lɃµÉÐF„L’Ô5@†g¤ îäØ{¾Ýg70ü·fx<…Úû›éq0IÐ÷ÖñƒǸÞ»D»mF)˹f&\ˆÜw’íót“;X’Ig·ë¨ÜÀ ͸¼A»òМ¢à“3&–ï`ò*ŽiŸðk'ó ‹í¤è5: Þý›ƒ¸ía‚à¼8¸kÂØwÚórB’Mã,Û];k¾ºnv‚Ân íÃKLKŒAbY‰,`Á.Îû7¦þÁUÀŽä¯æ6î!R&vx< žÁö&†}öÀpEœ‚A2ìä@xv#ô>ƒN¨°Ók[ŠKN¸R’¥).U‘$”£6Yp¤$¨£Õ˜Áá¥SbÃI, ‰Òì v™óÔ*9:Ap pƒfk´7l9rB¬t€`¸ƒ¹í1úpRû™¹0 0Û!™ùæ§w#ƒ`v†<=Ϭâa·äPÒÿ×½­Eø~9.µÃ€L¨Xò0Égsah·$øvö2˜ËùM…૟`“°¢8ŒnÛ±6g¿xý·l9—â÷wõô1í†*æ×u7“6P'_œëc¯~ê 1?³÷û8‚b"d.ZyĽ²ª^Ÿ$ Fàv&ÀÞ'v°;ÄÀ䌿kû3±$›¥$Í  €Ë¾í¤¸¢ObàÈmö‘¹u¨ÍïÍÅžãac):Å…æd¡¿x½£KÉàéy IæG%ŒÞâÐyfRt¨å›M$1øé;àËE¤BDû”·6˜ï§x6ެGýx‰.ãæÏéV‚ŸRÅÞ@bwôÀ@ ‰Õ"uÐë2-­¾S¹ †åØ3lÀ_æöùà8râîHÝ®\»€_y§‹@d™ X‘±=½ý¸ƒWšÍôÃna®Ds€â €½Žæ/óÞÎò`‘$À#k‚L1^A¤ïÃ6 †{?ž.Å£¨ ˆÂC3mnK‹‡e¾ÖœÖöQ‰±Öö1"ü=ˆ$° Häa?BØB¡pÎðåÀ‰s<òLaùfH"O¶Óó Mý —0D9m­!Ûf}¸µð<ßÕî6s¼3IßÇ$Ðbôø¾ᥠ¿ƒbt8¥2œÌj0瘬akI<ÆÄ•) ú†‚ÞŒ¥Eå3Y|È(V¥Q@I¦´¬EÂJÒ ¤pµ~z5©H«N­ ÉÕÿ¨ƒMô±ÔS¨ÞÍÇv®uÃ?KºÒ¾¹õû§ñÖÞcêçL0>sçOœXÆ9·’y‡œpš\cö"p*"ÿ/áôü³C‰Sá)Ä*hUPjŠÏ¼2ãÄ#õ|®S¢õî«ál®IUÎK9W'›êù„Wê9œµUÓ­^…e¿Ýªf«Ò_Ý©åÕLÒÓðŠ” ¥/ì¿ õ„uo ô?g•÷cšéT³Ôºm-B–ZLºjSJÓL$×§O.iׯS1­* R™)4Ð6xÃëWØëÍ^±Ú.ŒôJ¶»¯˜Ê±J¬"¿—ñît°ì®·R𥮓Åê0Jj•ÕJyµ_©æ+iPþ­5éX{5ˆVâ|Á‰>íRÝ}O-ºÍ;nÕ¡+qjR‹•$¥²’¥ÙYT¹´[C+C'A ¤€¤…+M# KS’ KÎÄ kýO­õuEÔÎ*½rºÈ¨¬¶UóÈ ¨ µ™”è¦Qç.B•ù”I aXÑàëòe(RÐÈJ–„ä!!*J’…%)Ë™3h RS«ãkÔ Z†´y%^bòYZŒäMÞâ1¾tìˆM,%@!hBi$£ËP84…=TÂVyR•±d“AT`°ûe ùƒ)) N3*RB”¡¡Ô^-ljD… ê'’æòÌI~ä\pøÎèIË*™J©º H!!~dŸÄ—%âä‹°ãQ|õ@p¾ræl?Ëò…63‰¡(‚˜OßR-e#(† `ýYЫœ×GéuÉÔjd²ä–rH¤”ªEΠ\̸ÇáÚwKíÆ-4$düKÖQM”#ïÕ—MÁ),ÎÉÓpqH˜Û\©‚}à}'érs:Ip-µ¥ÙÌ ã†Ç=*JT³cpvm$g‚ïÏ"Ë{o&ó1µ´‰´©Ë¼!íÞ° wfÅEI}Ø`Ö-ìàWŒ8 \LÄä#¶‘}`iÄÒ‰úzß^yr M;\¿bI=ønøxMÌfll`{iíkê§ŽíË5š’gë…~\´Ì¿µäåVÆ%I´L‰Ûü‡ A$¸&ÒƒèòÛ[³À½£€ÎnìòoìøD*@ßµîGë·âi,ãq,8`7bFÖ7ôÁ í³ ËóéÈì£ékkè¡ßë¡´ë§%¶{‡ áϧ.ã`Lq=‹’wˆÚÍ-w‰„ÚIô ȃ߼F¤í{pÀ2¥¹\—ƒoI8­‡rÆ>l{lÍkÈ8ŸR!+?vÐ*‚´ú‹ƒÒHŸWp8!$Xo n@aÎ$öÅA¡ÉVÞ›w·±õ  d°3®b (pmï 8CÙ ;7bvÜi’0àÈ.G=ÛoF‡,%ÉÃИôĘÎ`4$÷h·@9Èg"`öcapܱÜ­îfÿVØîNØ1Ö ­‹ŸñDvï"dÛ…( @,Ab.XzÜ3îö0øm@°pà‡“»ñí€O̱óø Þ4°ƒa:áH$8»çäÎG³Ç« ò6=ïÛhó·©Y@. L2&úþŒØ—{óU&8É?ôîçh÷Â}øgâòÍ#ÚãsÒÄ'ý˜9šJ‰Äº”âHþíG`°"gë<>\L»1ÜÌûz1¶Åk ™&ÀX@A¾1¿m"¡Ó“@©€w^¦-Þ&D´5¡ ‚'ñ’m°Þì {<ÉH!œ]ÿQf dÅ-T„”ú³. lTÜ˜Ê I6´Í͸r8$;Äï. yƒ…Ê.̈ôg%œÙ›ÙåPÒ¢ ]&ñ$’´6DŒLpV"ïÿFY)w·˜K“&A˜,Ì CØRe@é25±±'q#æEÌ͸³]Ûw0öxž|¢ðyx ÍûòÁãÔ3r3D(Á£ZæÛÄÚûÀ ñ^ÐÐóvv3{ì=0ÁD$L7ž  °3ÞöœQp«+`f"Ê“fT& àXL…bÏròʼnxhÃíîC€æ2KÙûÛØ O++~„‘@Ô‹ú§¹'ßr"T Ø8‘w0ZĽﻓƒ¨C1‰rXG¤s;»;Hµ«=Í܈´RlÞÛ‡$Úg;>¾¢X^YÆ›»1av`ä‡mÙžÂIÀJN`Hø´‚"s$6° ÿ¥Äî{€G¦óo@æø¬íî,- oОpõü(°DÜ’ 5&?Й¿ÑX›¹–Ü‚ÆÐxk\É ‹z̸‡oû$]†sl%KÔÿŠ=€¤kh„XËÍ€õh`ÐÄÚ-…*À¸x’f,?/ž¨b „“”_nÇ{ñÇ#ž æ_·øƒww‚Žä¶ñaƒ¥9‚†T‚` ¥àÍ·Ö&x`™ܹ¹äý}þŸv÷2{]ŸÕ°d (ÉL€dA¾÷:[Cm`‹kÄ Â í´’ÖþwÀÔݸô}ýØß’Ãc¡©Ì"3¸XÓh›ZÃ… Ø+‚Í nI÷Âê.m.H=…û^Üö#öxtV‡ÄŠß=Äp¶ñl+Ÿ:‹ËԜˆ<¥6ÍW+኷1}ámïÝ…QT"©#*ÔÂÔ´•HôѨrõjæEú~O5ÔAXÔ„WËeõå“i9ÁCJ -^E‚ f:OOX깚S¨g³ÙlšÙJB ÕBk¡!¨üDºe/ñ]†>xO9?‘ð÷E_)r•Ær¦™MÒ²hÊ[û’il²Š¡9SHë‹i¸ BT€åëSEÊÍ%/ÍPÔXªªÅJ+*Zª%Ö¢£ •ÙØ2±ö†K¥ü:´©Ò¦Šh¦J™¦>¢„%(BP„J@Ó¤1¤¯û©ù­çSú)Ó‡9ó£ý¥‹Vò"qŽT­§+1¬Çéù1ì2‰o9 uU•n-ä§Í[®g^u4ó•zwMÌæ“I ×®¶V•e¨ÑH¬•¦šÆ°M:ZD„Ê9<ï„z*ÑþíÔz~I9”-I¥›“G3™¦„*š™Z”×QCNºáDé})[Ê­ýœlax¿/ø]è~-ÏÎ×!t¸O'Óõkš˜&¦,ÔRÖã¸(Ä^nœ!eµ „ÓhD…}K¤æº’SW9ÓkÔ¦!yšKËÒ]:U‘UÀY§Id.˜ZJåiBéøšÕà¿´zþ¡S'á¾¹÷:5–¿Žzj©fó:ªÒ©@¢¥T¦½T¥HPJ©ëJŠRM2¤á?WºWáúš­Úªÿþ ú{_IPYN$æÿöc /¸âMCMâL×a¸ZZ+ósÕ–ÜL¬!`ùÓé.š)RUꚤª‡Æ¨R•*¬I]Dƒå4е$º‚. ËSûBë4óÕ3½G5Õ3‹Ë¥g(ŠÕ3tò´Qcúô²´WK/F¡$¯ã|$TTcZýav§“yâ›À«ùƒå|G Äiq,b’²Š¤UTf¬¨bµÞSo3VÁoÌaôyŒ¡iPãËSÃÙJIÍÕÒiT¡˜U*AbšMz&•:ˆªBè%uITÔ¥$šZÂÀPmË£ý¯x«¨f2¹ ù•f2ù¼±«ñ(f3ÇBÅe ÐZœ_Äd"tÔ@¦éª¡ðÉI*ŠÒ¢å)—œÎäÉÌy¡&à^ Íòå“7:¦g+SPó%м êo)᥶Øç£ø“)÷R¥ÒÌ•Q¤•TÔ’|ÁRJ”%D–ÔTé jßÝë‹ìTõGš^§ È_§äÈT´QÓ)iË+9Q^©ý àŠU)øg¦¥‹EbQ,•WªR˜K6‘·`?&¿Ô~-ûcñžg+¤S^c&þ]J};'N¢– U-+øŠ`T°TJ‰Å¢Reˆ$ØA¹ ûˆ°ƒãYad¬è0¦IÁbN*åôNP£å7i2nÄÛ]u’E¤Tñ— pó i†‡s$qÉ ¾°u%EÈ™#Ì&ÂK]œ4–‡‚’¢BG®Ó£6Åòí¤‘ˆ—$N¢ÿí’N­‰‚9lXŸÄÿ…%™¿0ñ 7oRpÔv‹3¤ZÚ"w‹ÅÁõ“2ˆ!E¡‰.Áˆ/.ã‚lrÿ¶Ýý,!Ë8–¦ FkÄHÿx>Ó7$Á¯¢¨$L4€×Wp塞âãS†%È“½†íry`cå*RbÖ9”-7ýÜM¸s¥Râ]»wb"#çÛQa'µþ¿^æÃm]Ô( '3(²U÷jŸQ‚`É“scq´‰q 8äXr ˜vhc‚ÎÁŸpѰ~^üßxÆ`t¡¬ü®¢ ŒJ &ÇîÔf"ñon/Ë ü1æ!ͽ…Øûâ•ÕHQÔ O@8çñ&þ˜Æ¼u#ï ¤wåg{@&HÏaÇœpæÌÎÛ|{Ô`’Ä›—7g,åœåŒ RÕ(!`Ɍˀ£"ëhFºŸ £ÉÜú_‰$Øí´°Â™À0a$¼™ç~ÂÞâe˜ “”l‡âµ¨/`Ûh8` “åZvåÆÛàŽ\9ؼݘoÄK€¸Èõ¤É9T‘aö3O¦÷ØO Ä'·þÒÓÌ8ý¢É`ð¦€Û]£×¶•^£Y ]W¿ÊúØïñ7k—ö0³>â-.0 —*rû íè[nAÁB–R…ȱ&i@̘;‰‹ E£ˆCv·¼~OÄpHÂÿŸ^Ý»|Ϩԅ…j”™$eHʲ@:jfÜ‹{µ®æþ¸/1Ø–‚6fx~_m°¬à¨’Haª $Ü}ÁÖý¸ZOÅÙÀAyÛ»½ñ Ý=½‰ù:½FíR’#6Àɺv>ÀìmGñr>¤Gé€/=®ßÇl5ÀJS쨸ô¶4°[Á=¯@¤Å¿9c߈v“µçqÚ8ai$[ J}@å¶s¥¦ýõÚà p9î ÷ökCzOu=Ïf Ä[}öøhI'é{Ât2 Eû~‘Äš{o`É÷囌G,ßÂûñ´l\ ‘b?Qhò"`pÛƒôr솘ÏÀ)› ‡ °äĶö3‰ œÁ$$$*ãÕZH@ ¬¦6Ý7ö‘Ã5c¼á wå1gÆø'ÂM´`&ld0"àÌ|Èá4ÀSA&_‹‚ñŒØhÛ˜ ‹ï´÷Îß³»ÄM/†ß]êÎ#RŠL/—ñÊÜ#¬yn¡8vÌø5W.ÔâÙJ–Ø£kûÆd¤„¥²HO3MYœŸRËS*3Ù ™jj|Ju(æè$3„•ÖËS¤^ VuAŒï…:>׺^0Ê¡•ÏS©Tù¢@ªVĻӧUKK(1Hâ>†ñË[¡§¦Æªi¹ÙºÖ[ª8MME ^4¶\Huºœ+ J)ܪ§ ¬9ç4BœkÔ•º¢90A ?xËü_‚¢‰UP´ùHP$$ÊK 1|}—K7Bºh®–j¦ŠÀ)!5T¤))R T *)Q!±ž/zûàãúËEÉu^QÌýO­j‘uNTòH¤Æû…º&jJª)˜Æ\}À†•Eˆ·WL”+"Ûòʧ “ÍÕ«Ì£¥ôäѧ—¨~/ÆE9¦ME))¬£LJµ¯0 –R/RÆÙÕ2/Òèf:†z­ZÙ„Ò V¥‚TÓæPÒŠ)+*rÈc4ŸTüGxˆÂzzú0~zðßáÃg `.åÅ'˜9¿ ¥w3lÓâ¸? 1OÊœ²…¥a?tc˜*«iÞ"𣥯ÛóõÁÌÔR3\õ Õ”škºÔBNSS?šU3Z¢tÔhÖ ¤º©Ö(HQ«£åkŒ¸9†rylºZ—ßBhÔÒ—RJ2YdSBÔB‰©Q¢é…Ó·4ó—W1ê‡ð¼cªÔµô8ûêk¬¦^(”ª°´µµXëâ(a ôÓ%䶦Ö®ÄBzu*i¦¬æ‘E+«@5"J’M5(ùêRƒ‚—!, Ç›3Sªçs ©S#5iÔR…D¥§ÉL¤„&À‚ê $©Qƒ=[çLoÆ0Κb¸öŽ5‡±‚ãÕ5¸CN}áX¥%=u4õe÷KU”¬:ê\b™Ô´ónµ‘ çF±U,ÆršêUËS©[+D­ SR34r†µze‚ÔªtÐJ‚´ª‰.à„íþÈeku\¦Fº>Q £›)¢¢*F®e4©éQ 3U(5ª‰¨”¥!ªÓ?t¤¨eTêJ˜s2–Š–ÁeÒò\h¥ÆImÆÝo,;LæLòµCÙÝÏ¥k¨…ü@Ë ËN“t©'RV… S7•¾™F[#™¢Š ø”*•|Df©©t*ü`š(Ô@¦¼½z~qS*²‘TüE+ï ]Pu_Îõ|æþc¨ .y¸¾ <ÂK¹*ÖŒùPJYAP ô‰„ÂDqôßC§ðºGNF‚2ys ;'U$«O˜:\‚òòdãñ·í;÷ÿø¯2*š¿¯u1ñIWáfêÒøŒŸ"BÊ5„£Ê@HŠ\IK¶‘6-*'Q´ù"ÜeÀ‘€@&ïeáö‡=ô•w™"aì{Û‹5ðTŒæiOªlv6¾–;Ž-Ò‡@@nD»‡¹hnÑŠ ”—bêP»¼‹^9?ˆÃÃÎ/Lz'Õ±âÈÁzkÈø÷6×-Ô4±„áî»KL§'/ß+”¡¤IMóTT¶AQ„Ï¢èЧñ+UEaÙUT :‰*„¥J´9F[-ÏÖø9,¥\Õ]A%4’º…%d‡Y¥ ´¯@ä coû:·Ì¢êï3Pr›O6‡žåÎ[lcXË-©»Ä1'BpÊ'¥¥.¥¤V¥9’ÅÅ%RP´¥M„¨©Ka qß%çHRßCµÒ) ¾Î&C(¨§4Å T¦.¤Ä¥ €? LŠbªUS/¦¥*ÔÆvêô–•$‡Ü“ñ¨¤;ê5@R—¨/XNak§Y”ǤâX7Ppªž]Çðª7ðú–þäèm†\^uÅ04ï8Š †V§Yb•§25@šÚFØ ¿O‹àÃ%K/!HR‚‰Z“æÝ¾%@KjÔ)¡jUGY¬ŠA(Uj5²µhà³y„ªš‘VšJi*˜ P)p„iK¦–JJiÒ!)¦j,¨eªÑ¯N§9Þ/ü/½Ñ,eÎ`ÀV‡ù;¯];m'Ïó0lAE"“ñ(èÒijCŠcÊK­¶¶VÂ_p%1¶ô¼á¬Ùj³TSÕMN¨€ÉV£©JpmIBÔ’¤%ÁW$ñJC÷ܱI¡R±MT‚ÈQLhJ~ˆPt*¢ R•)ã ™tå¦à –IöÓYö´qœBD8%Ì\$1mž^Îà€I7m_V™ ßûœ8a±q0gaaƒ!B@ʾª"Æ.Mµˆ&†$øípÅÈÿä4œ2\É"@$¥ØrLƒa¥²$_ÎL_üF6úÍÒNФ«ûTf É!œ;‡vo4 Ÿ $3»¤™mÔX6§Þí¥Ë±äJ.?:„ˆÐä›í¡qYån!¤JŒËlÐL6K"]‰·!·OîM±ki3û„‘#ðÌmÚ î}\V¤îÂÄܹÒn`n_‡ ð?·ûšDÄ 1 °}Ü–ŒfGI[IåeÊW?´ßúÿt¡; ¶ÃF\†PrO”Ä€y>“8ñTZuI°’ØC0k0xåñŒ8ál>ôe˜„’i±hþ+ÚúžÔú½SÓ:_M¥Ò!G-W«æéÓøQI/TtüµJ™|ºVSªº—QUÊ\Ò¨„  U^9OåµÖãý=ê¶;Œ¥•-.#®”4‹ûÊ+JŨð¬5†ªXõJ/R6•ºû uiApÓ™ûHéˆ|M V”訬•Jôè…Q¥­’²ªƒMMhBª•zXÖKý#ý WEÔzçVÌü ³˜¥—ëÙ|¥\ÐEU°#-S'”¢š…'I_ÃÖKà‡¡ªæ¶9K Ä©pîMåL +Ä(i«“‰s>4ëTRR²º¶C”ô4!Ošª±÷ºªš—Ò—KJI«xô*dÒ¦ŠÙ“KáQ¨šbŽZ¨(®¥M!!UjÓE:I)M:iRÐ’§qÕ|þ”syn­–Íuìí¯F¡XÖÍtÚ5Õœê]KúU‘—¡[6’rù\¨©Sï~ «T­R4k¦B•‹?Î](å.H]oìl6ž¡¥¾¥ýåôùµ• ¾ðBÔH¾UÉ8ŒŸ‰z§TU4æs5<§HJ¦™g#U8 õ¹²‰.z_û&ðw‚rÙ…ô~‡“X¬±]yª¨ø™º U<ÂÊê ¸[+HÈK8Ã~°uåL>µ†jƒøÈQû½-2u·q¥%u!K@HF`T£9 ° õ ô ÷VÍS¨º%9/7Ä©P…%N•%€]Òñb’nÅ?njžð?IÍP£E~ºBFS%–)5‘] Šu35V€€•ä•”!AÊmÔººšº‡Ô™çx„Y).¼\RQhJD˜NøãèšHéÓ¦„ <©’IÜ–w»÷ÇäÖs0¼Þk3™ZR•f3³ BJ«TUE%d¤¨„¥ÎrÏ‹ƒÓn‘õ«˜ê9_§Ÿó~7Tòš<ʯ(-yCµoåÔT÷»õO2Ð+Åë]:(5*©i ]U„SK~)QuP š@ÛåòÙœÝTÐÊåêæ+(€št)ª¢É,„‚C’ÃW”\œo{§طZó¸w2xŒÄK%ª¶zwËU‹CYTâr#æ ¬…²TËÉÂÜmƒP‘Kû@)ÖÖ­w=✽º]=)¬Rç+¥_$ j(¤Ê]O†5ªM*ª(ÕM5#¿Kû=Ì×Z*õºÇ-M…O¸å”•fV_ý\ÂI¦@)4uTI¤3)¨¤ã¢^‡t;¦ý$©pnZä®_Â0l*“‡QaxÝi˜§ :_«c dÓ‡œŠS]Œ—ZkT*åiH^©™Íæ3•W1R¥\ÅJ‹¦¤Õ¨]5¤R˨‚SE+_Þ>z?uRt­mÓú^K#Ói"†R… j!"=TÔŸêfT‚B« )J–ºà«034ÂŽ¢¢nî9‰¢‘—RªJFœm÷û«J`QÓ¾ÆVÅ;m!œ1×ÒJšÃêFí¥5ÏÔc­8¡àEJnµÓZMCQHe|:X)H(]4%yªN…#0Œµ:TÕLù²•jTJ])"¡RS¥$(¤ èZ]‚´T^škÒ¤ÕøÕkUX«I:1s:MDj^£© VSu,š’V…¥õ‡ÃÌÔ!ÅšWžÂëÅM ¯QTòÍ.,ÅÈKÕÓsL ;)É% HX(Qj!#0„æNb°¥š¥Q^b…a5Âj ”ê™ÔÖ(j)U"M%Š:ò‡.šˆNbž0¯:÷NÝCåªö–ØR•‘o‚V|¬¨ Sõ;U (2â•Põ@Ã@®ÂF"Õ#.¥)Ö t¹HI@+óêM$€Pð—™E%ÑEÊúnaT+<ËAIIb<îTE6J’ªª:†’£¨«â|•PÕ§÷ÚtqCœ:áE‰:…Q¾åk®8|ò…:¥þ^.bRd@pXFÎÊ 3—³6$ÔO`V½ äÉ2b7ØÈÜX,n@w2bòåÜØ¾÷nÁËŒ‡ÿä\=ˆ8š§?ŠÜÀÌÂ/&d6­.`¨‚t‹LÒµ\Hˆù±¶Ûv,€3KÝìâòò ƒ¾mtu´+”–H˜Å*”tùGæ˜Ö§E¢ååW‰±½Í§lxëiJÈ`Û8"&”À./ÛfÆ!ãÒ*Ð:ÉŸ½ûƃÛ~< ‚óås >äö7’^ÖÆZL‹»3´žA¸8¦j ¬ æ^ƒOSwˆA‹ÉÒ8¶ $9¼>ç´Ëc`×ÄrM»7½·>§ÙØÊ*„2é*€|ÖÈ2`MÉ&ÀÉ×…#{;s³46ÌX±‡|à_¸ˆî{ÞLZäsuýn`Àˆ€, ?õŽ'” w$°ÏPäจ÷p$;´\± ì_˜˜½À3=çòêPF  %ïf<IÛòawÄ‘ 4–7‡ nîÀÏ2vÕþnú‚ÒÆ“{08îçrܹ< 9Ù¤ï8[c¯ó³‹a…d! l•!0¢µg°H? €"ÈPЃ– x/h£{9‹ØÅâmõd>g7°¼4 BUñˆÿxÀܤ’m{΃X3Áå Ø€k1ê.ÄÚL%¤¹ÞXr[Ÿnp%@jî5ôÚvƒ`'m&Ü@ €d´sÇbî7ö' ²ÅÃóèÎ mÉ~ø1Bœ !*PΔƒf̤)@©D\‚H˜ð Ř|á­Ëìû‹ß L?gv#‚ñÙÏo/lÄc2¦u‰ÔrtùÞÝ¡– <0˜‰<¿aó8’D°$˜i^Î=Î"d4i rë EÍþ"O¼¹ãÒ¬Às¾4°,I–rwwÝÀ6~C=$ú£¼Üû’&n éÞ/#‚&"Yìí/qvÜ}IÀ±bÛØŸ”¾Ä;Ï.l¡)BŠ„­K E‰Ê™JõD„¤úŽU•2f…¤´‡yy’û³Èâ]Âì=çØ~ïùáÁc)61¬›[€=…„pl ´é7bð`AìÁ¡'aÐ4DþKàŒ-HJs6MÔO¥"H’I1t‹éÂT)Òð×$ÝŽæ=m01袅*¢PJ”@äÊX0rMØvŽ‹<àòLyO©UC5.0¼S¦h¯ÍUv$µVÔ4ç—ê ÒJr©!j§K Aâo´.²ž«â®¥¦Jè"§Ý²êvwÊ£à¡zœêéUD‚­,¶m&?¤ô©à¾ûðw‡óHM. ¾žz¿R¦¤£Z:—X¬sÙŠ1©?øi­O(¥1sD— ;V1URØò|ÖýÊÙÖ^[¥+-¥]ò¸àþ,Äñ ®µEÝEcMœ$rÃð] \Žþ𠤣¨ Éó\>[¤ªäÜ<0ŒQ¼ÁŸÍš¾-µÒ¸’—*œI[Š[iHòÛuªyTeòáD“ê2E:Œ¸$¨Ü;Ÿh’6Ù,›i J…PK'Ê•’K%Ù.åˤ@f˜kˆÆ–†³>0Úe°êT èMRÕ/6”ÊHØi…¬H5 x6 È#à…Z©G˜ «þD-Z´ÙÒ„\¾/. 3µŠ­O,šÚA%I×QZÊ@)„ѦQ$0©UIH`@ÅN»sµF ƒÕýÊÊŒV­+f™–R”ÑRTP „ÈKbT„”€³)6Æñá.K?Ÿ¤šµi£+OÏUu Ãó0%D)$ LIÇÍßoþ=Ìø_Ãy¥ôü’ó]_=ªŽK+—¤­TuSZU™P¦‚ßyƒ†Zƒ\±Öß.t­=tæW°žòO0sn'SVâjêiéË8e2¨oÕ_‹U®Ÿ ¢Bs¿TÙ#"B–¤¡_WôÚ¹–V•EÔ¡—Ë! ʈ”M4¤Õ,’ÿ Q)[¹Âÿåú÷[ë9´"Žk?Ÿ­˜©S6Udš«'úµ*Nž’B’•Ô •¥ ÁÜO†?°Ò¯]0ø„æÂ¶Bš/ò_'­TìgZÛW‘ˆó-Jñe%Ö[©]%-i©Æq&–®¡&wÅÔ’ :n]UÖÊ)«˜t¥LGâJYV•Ši+ÔV„¡TµU¦…øºOÙªÊEnµ›H ¶MNA%š¦f¢@TÂÊi„ˆ’*¦¢©ôÑ }(è‡,7ƒr_"`<µƒÑ4•;EABÝ3¯†œ¡[Xú“YŠ>ð¤¯j¹Uµ9Ýu”®µï¾Ô·†+YÌg3½EeYŒÍJ…a"’‰(ËèI£IJ×Êæ)¥LêE'B Lt ŽO¥tœ¸¥“ÉQËÒ|D$Q`„)«WY×UFŸÇEOе$.˜ª¥-(ÅÛĪ0žZEBÐê[z‰N¾_–š‚ý3xŠëeÏ$yÁx*™\0ÅBÚeÌwöud¢šu•H 3 øjIQyU²5²Bz–fš‚©Q*'1E$Òòf3? ÔZ”~-‰[’¥TBTJÒVÀS" ´¦ŠçúýKiŽu[Á¨n™õ7MGWPœ‰.²…S•UºòOžZ}”–0Zp§”ºgœBE76=NUOH¢B–”‚¯êÖ¥MÖDü}4•… IRN£YA šnËÊ…­+ZhûÂ)¥N¥ZJH%:éÄXéX"žD‹ €=<ÉB P¬Yê_\¢£}‡+Û(§mtµ HFš†ÒæDS¸€eœeçðñO÷“’¿ ±‡iœÄ)M ÕD¤Ôjô’æeSªªd•$‡R§OHV¿‰HëJêei¯ÏNk¨)€YP.ÕQ!iYÒ±ç?zXN’Š©¡ä§™©OBuq×/E„âTôÕAn¸ã¥M!ÿ=!õ8¦]S$Õ<§~ò·jYx"¾­šÊ*ÚÞ«®ó0¼W Íå:hX¦C Рè"›%a54¡$BI¢•ÒÌe*TE4,V§šÓ:·ˆ“”5À:Ž’ÔÁ4Ô$¥a” °­UiñVš”*åµ­z¨ÔËêߟú÷Ìꊿ­i«{;¥Õ­âúÛQ>qR’Ô­ß1Aõù,9Rªº–«©Q]WZšlÕŸIÂ4éøaƒ °N’T!#È]4ÓB—¨)Q¤•éy¯çu" PP:Š™iªÄˆ¢B Ô¥'QÐ…©jªŒÊ Zµª aOâAº7¨ž«]EFE©O…ó« q×R§[dù¯¢š²¡¥…KëxB–¼ôÅ(TJtBÂX©œü0d–JªÔiäRÐî ’,šjZjê:”È+?ˆÎ¢“5E:Õá]P¥%E+ZW–}-ëk|ÿƒ¹Õ4t”ÈûÞÁ‡ÐÈ—›Ä ©ÒåÆa,­ [-­âVç‡9‘9u­JRTk(Ö).¥u§C¬wbT HA HëŸzÒŸ†i¦Š)åÔ²ihX”…Š©(ÒRtÈ4Ó§â“S |OsãXæ1„òÕ‰r—müF¡-än²µtèm-4Ë ©4ì(4Í;‹.½¶*’°ÞG¢eŠ «­2½P³¸ µI*•% •Xšd ¤«âÞ¤ŒÊèåAE=uTäüEŸ† J %_Ø•¿:~"T1‹éýìåP”ŸâÔ..}æùf'¹lIHÕ{ܹ2KÀ2XG2Ö™bïæ%Ó`<³¸–h€Ïƒ70~ ¿¬LÁ°‰1´ ØRH ˆ:HÞ\ Hßbö âÔÔS»5i,Ì’–~4ÌBA±,TUI/ ûI^†6ƒ¬ZLhÞc2â,Xxsnd\˜ÅájQt¤»`DX±gr†’Ä 5‚½Öâc÷sí6& ½L\…wQé`]Û¼™±ÚKއ÷Z™Å¥2³âm3 ä&5Ùµh˜ÚäYT—!Þ7ƒ¸ì/cð@-%Ï<5¡šóaôÆsôRŸÌäçV?kÔ\"u¢Ãå´ÞûðÔ—ä’\ 5Ä.dú`Çi‹èÔ—%åßPô€ƒ»ã ñèûÃÑqI ŸˆÆ‘¨‘¨î P‚áŒELFØÑ‹°¾2 Fæ·x.÷ož)z ±üêŸþ¶ïò‰ìÚâÔ°È&d £Ö°}·ÄÈf A$›»|¬n/²e$I…$¼@‚L˜s Æ—ˆ$‡˜w ðHÅØbeÇÊIì;NçyìÅRâL@7DHÖÑ&o©¿Ä‚MÉß–oRÌ=³l=¸€[½ùÃ’MÆÄ{ßç{w´q—,]Ùæ ¬X’7@¼<¹ÏÔ|âÁˆÌ{W}ô'µÀ G Ï6ãsx6žáñ?‡ßg Ý·l ÒÜÚÈ0A×"Léa0Eãùq™°Û–僾ÞÂo€nG#µË A·Ôûb.`$€èÙB`¦ÄØÚ±w5žx Iv›ÝÌÃIc釿í/ø0Ö„_øN»Åæ'H¿C±‰ÜQû'«‰˜1 #åÉãÛt@I'@‚'¼7 øqÄ‚Yáývyí3mÆX¼zKCCFý%°(a“:Ä‚@ø¶ jA0{Åø<´‡÷€H;ZmÝá° 0vchpçy6iö$rÁüC@dk´LÌhÐ%ݤÃÅ÷rcÞà46–‚>v‹€9±Á^g(â'[î'ÞIØÛ†Š pÀrû´1a7‰Ï6±.m$ÃnÍ‚@˜¸¿¹3müçü™œÀQ"ÈØï‚G´÷ž’ÄÁ³€Ó}°à à¦nAØÛßÛC¨î)!„‚C@,Xï=ÞÛÆ“7òg€ÂY†Ó;y±zúÉ çŽ£`tN°§pì5äâØ¢ŠO––ika•È#ûÅHi°“þì: o/Ç]m=ùÊéXFg2ºå,¢ºÀ¥KH¿’–µ—Ò.¡¢Ó7ÙÕO´oµn­—øÝ+£×¥ÖúÂÔ—¢š¦¦Z…B|Š9¼è£HSüJ¤+,šK~ƒºTÂé(š\£9 …AIRDH)X˜UÁTH$ññ?PZª­jeîCÃH»@%‹Yƒƒ#Ò'†2Ÿuèô¨$¤Q ’ÄyH  ŸÄdÆDÓs5Hi.Ôe JÀJIYNwW˜z “2o‘ Æ9B€É$•`rHoÄÝ@ Ç£1MEj$‚ë*#À ƒî´,1Ls_18–ß­ ºò©˜Pi†Ð¥Ô.¡Jò›|© m”²Z?Ä¢”¦é}Õ¥AQÖ²½?ÊHHJKIÁ( ) H œ'Ä9\½E„T^GM$’¥•ùCþh!)%D¤´XsU/Ó7†a”m×âU޶+jëìaô÷ ›¦)d½\èZÜ©|3U•EJ*E2s§"¤%KB—WáÑAÒ’…URÂtºi‘L%´£â0E0§R†1t³õèeêQÊPNc8²WQV†K+Du[6PÕTšŠµ.½UyGÃÈNx]ÀúÌXý/í]åÇèØ¯K‰5ÜÉ=M÷õ5\ò<Çðþ_¢cÊ}Ì6•mª¹.4š‘QFÓ‰­ê¾é´“=ZºEZ«¯^–J…D=­¾šusJB€§˜ÌÔ¨³K.’Šku«M_„ª?Ÿ?ê«í/¬tŽ­CÀýºò(ÌtÊ=K¯õJJ?Î+=Rº²ù 5ÁøùŸJŽ]5³š©Õ®…S¤ÊšÿzÚOLz9ʼ‡¢›Â(ðªVAnŽ…mæe9––Øi(hÔ¶ RZl´Ãel²âÊ*ž¯k¤®²‚«.õTJ@RÀój  §Y R´ÔU4N…_39¢‚µ¨©EJ]Aø•¥%JV°¢Qñ£PCƒFEEÖUâ™9Cª¨u¤°ÚGÞ¼´+ÊA(uÖ˜ )å%–Ó¤¥T¾X¥¤¤[ô+j '¸%¢šHPQ4Šc0ÔÔ„¨ê!Z×÷ê¨Â¢«5d©î˜uæŠ:À *ÏôÔô¬T¢€ªÀ .Q—¦T• 5ìG õªUAZõ ¥,SñT…93b¬ÓúBR³åEzx-Ô®?Tºzœ@´Ûí<—Ts2†\x¶B ¤R„,#q9 éÜ¥­A}×°T¾Ûø†C/–¨¥$ª C+JÒRÉódiÁOME UPøtµü÷Qu¬+Pø´”‘¨2QQz‹©e’­lB‰¦’j¯ ¹ÇÅ2Ó•˜an¡àýBXô»T­d:iT”¹‰µVÚƒMÒU¸ÛÊoÄ]¦Åê2ÉéªIBI£D‚ìGƦ„ù5Ь¡¦£æZ)” ×Bje†¹˜ñ TBÍtÒ*NŠš‹XEE-AlÊj¹¤Ö’…)5*¦Š,È×·UüSâ˜áª £Ä_p„­ÃŽ‘æ4 ¸¼…ªÃž¤<¼}åMÔÔ6×1"ž¿Êez`*ÀN½`¨T –?ÓÓ€b˜J4ÒÿÅ5(QÖº¯‰W^š¨S¨J˜êüaÖ•iRéK­U¡¨(•…¯ÿ)sp×çLbº¥Çª*–âÛy¼´­‚Ix-_ó+—œA`¡S¿PRØ¥qÔPç©Ó¦„²H%.áO CÊET€„©*r”ø‰JªiÕªÔZ”ª«+XVÔƒu(i}*IV¥SТ¨iÒXYNjæ—1ÊÅ·LV¶’¸™RÜ$ rÅÒB ëõ,fSŠyÕ.¡ÏUEDé¸%6I2HÈ p­#JR ”²IU@ ßIñyU¨„¹$é.ÞSu(U.Iy_’ŸÄXUukܨS4à#Ï_˜°­H*m$’§¢–!JRµM J@:ˆóX–pZÀ€×bRIPUê*} ”…,@Qpw ‹«I`Á$”Ýzkéî‹V=ˆ6Õ-:é°Zfƒ)sª%´’µ¥ÌíÊ[©A}4º¤šwRT<•)ŒÊ€… ŠSTRÈ-M/yPÒRXN“T¢*!i*Èå+ÕÊ…­5ˆJRFªŠQü%@­NJÓçÐ<¦‘\k~©úÇÞªªuOTT¸ó®¥­j,JЦMŒA°²lÊÓH@ JX4&`NϹrMÉI/Œee)EED9?ò'QüD=®ÄÈ`Œ+õ$‚@3A^¢$ë  °âÔ»·$Ù6,E‡áwží ˆó Äö{L8‚^êÕ-¾ÉT™¸Ê"` Wï}޲DLqa$º]»g’9~"Û¤j-¼ÅظL@ìå°Š’­üfîFá@è4ôɰ@àa*Ø–-i%æ Ûyg!Sˆ A€À•ü¤ê <–•Pê§ `DÝD½ãa©Þµ$ƒ» —†#ŽàþX¹*`ˆ$9›»(nm¸Tª‡™’ònuB¯ 0 Eû\ŒÕ,ð@Ü3Ü Ü4H}°îѸ/ؾÆîX»oŒûè:¾IxÊ¿ýõT!*X(0Á’&÷’ƒqÃRüü¤ “Ý÷}¶k0`êw'T±ÒÐ 3w¹bC8|`ö7ûç¬t@æ=õ×èuƒÌ'ÑÁÀw;zËÿn ŸCÏm± ›,€L, ‰ãHµ¤‚#kîE‹qÁöfˆ!Àl ~“ò7rìÏ`ØiQÌ5EöÔH´ÈÚÓ,#ÅÈ1°sû¸¸ùbÍ\„·f“èaß á€‘áA›ÊÙ˜ÚÖÉØ "wf]½÷yßòÁ– € „¹7¶ãŸU­+]ϼ_ÿHt;À³Ìì'ݶs¾‰–bX—Ø\ ö"K቉P¹´Øéihýc‰}­ó?+üŸ×œ–sv‚zY¡‡Ê_¡$úˆ‹ÀÐ\ïÚÂx‚[NÒG®ß¼`o0åÁ{wIÍÏŸPƒЀ‰ÖÃH=¤ÿ1$^!˜ó¸Ÿ™ÚàG³Í›ˆ{Ý™Ïv8€ !RFâÄeØü»LðÄìï.î\’Ðd‹ýwœD%ýƒ oÓyˆ³ck^zl¾LÁ0ÏÚThcÅ騯qR°ûM×!µáô.‘Yb—Ëu挖ßuä@Vn>XûIñ'û×Q«N…]y•Eå2ºIеҌÅt‡b*UÔ”.5SJ €öçý }/ÀéËê¹e¼Iâ ¦[¯õ¯ˆ÷¼½,ñ5zOM¬Y霶I4ªÖ˨“G3^²5êlé§ÄÞa¦©éÈ JÓ™i!+R„zDÝ3¬'Ò¢8å]++Y,ðHrʼnbîåÙB&ÛÐü¾iYd£/—Òª‰¦”™rê):\†n¥¢ zn Џ”)Å8\ym¥Eõ$Þ…–›$äJ.¤¸»¯)t¥Â¤¹Ç‘t 1)PTªÄ4$‚]?…‰H[ßHª¡_: Ôjf—vGÿE&I:t…)ÊŽ¥+â9ñ¹‹Ÿ­f¡¬-)Åê+ê©0ªÁR¨ëquÕS¶¦ÔêHn¨Rƒå¾šdýÕ•³ /<ß»+ÓꪪFf¡¡¢šë(°*§E)pµ$°@\”•‚MÂJHJµ^³â<Ž_§¬t¤'ªV­OK˨-_uÌgª•¡t(Õ¦®(+GÇ4Ti!k4×U MAJìR-žPÁ0fWRÍN+‹bôKu( 0‡1lIÇSVó-¦L†šCôôMû½3MgÎáuÇ|É'7š¨2áH§B’ê²A4(€ê¨@e‹)5X’]A,4€µþÑÓrÔú…T¯;ŸÌeò‹¨iŠÙìꚺ[M:4)¥f$’é¢ ‰Z–³Ÿž«i°¾›ÖóEriÛO8s?5óq* =@ÍìLª¥5*ÊšjÌ;—¨ª ;+¦EFFÃÁºz,cöëÿEt š²=¥eVé^_#Aj`i¯š9U.I­IyÚªME$è¯^’U¨e•–GâçÛ¿‹âOµOuUòÊëuú~WÌV¸ôT#¤PU‡ô* ‡Å4È ÐsÌ*éó‡XNCRû̇–•Íc«kÈ.>…%Lº}Ê ™©`-A˜«tŠD§ŒÐ)²I"Sõ… BÐ*Ó ¤¢ThW¤ŸŽ’üS3Ua%aÁ¨ªÚ4¬T?Ú¥SŠÊ@(¨t6s§ˆ÷™qÊ4Õ²ë•+CTŠ5ÎR ¢ªZ»%·ûÞ'OVšvp·E%@«mºL]KlTSà WµeT©`% *Y Bôµ€€*”UQy„üG U_)¤„/4Vi¤,² P(w 4Ü’ªˆ¨(¨%Ah?xq«îê-Ôß•.І‘ˆ¼ãIi!§Pøuú–Ü5.aµ¾eCîÔ8åf-\Úi@[®R¦©†ÓPŒC )C  ¯ˆP5%NPRM$h©¤,„h?-D…:JвAETâó=R’Y!Ó‚õ)@’hÕò­gUjŽkø(ZBV•Ó^¿ú›â=~m[(¬âRókiÐë y©zBWHRÛ©(4޲¶’—XZpgišxó™LІ€%‰(„ü2 Jæèª•k%MSÿ$-‘˜wWêéu SJÒ¤ˆ>d€–4”•¤$j¤¯»TA5r¸Ã®bê‡0sCàb>Sî¥a%a¬áy 2–’”’êšd6ÚCEÂÅ ¢eÁ†ŠPJB’“¥* üJ…rI,€VJá _Å#ãcCÎU©š^¥éY@r51 HH…-i  JM ÑŠ]¼P£3޾”#+¥’„zÚRJ!!ÖÂAIm+im8Ò–PÃVH‹¸y7 } ó‰²Bƒ+ËM JÒŸ) BšH’’ 1ó& ¸ I+aMc8ûØ÷v”ãT¹“œ©d¸ñR‚”TL+Ë*•åZÝp“™×]!9] bC¸ ÍØa%!" &AõçK³±,ç‚ðåØqß×ä,!œKJêJ;+mjÍéA’!J o(Rò¢sYN6’¤©Ä­+V°¦ˆ2@³ ’)ô±Y B×! E#]iA:Pà(7â–bRR ’ìáI.  $¤ÝŽófƒÓ¤SµLŠjfÔ€!¿5oJR @Nu•¸êBZeİÕ–’P’¢A$¹eJDŸ1W›R‚wø•´šŠA®ºòª„&)Hü!ƽEÀ¤$°I&X€¤–B…4ÑÇ>iæzÎc«Kέh¤eåýщ²fžr$yΔæT–Ä4ˆBB= Séu!üÎå’$:C¸‚L¨º”IQ¬êS»„°W$Ë 6€ìا0»ƒøm™üí¾·“· )€óYؙܒð_ÚÃß-$©$¹%N#`H%ƒ‹ÁÝ®òçmD® ¶Siƒñ-2c{‚OnS}&KoaxÙäG aæô´”± òIü:O|L´¨ÞH™ˆ*>òE®6€@ÞîAÜ%ÅØ$™†$Á¹C>Ó*g,CÆï`CÂ䔨´yIwuŠ•˜ÀóbåJ%p{X“$mL¥mbD@2 }ØXp@$Ø%Øéæ€ÙšÚ yL‚ J)@6’¢IxÃ%"ÿÅé‚‚b-ð-¬²¯ë"⛜ÀŽlìæ.'ç8`øˆa¦°w÷ÿ1ÄÏéX 7`2wmÉg‘ØòEÒèç.#œz›ÊX5P/ÓÕã-UW¥ã)všˆ««C³%IuëK¤Ì…™ã]ñ_Q=/ÃýW7MZjSÊUM% е@£IN𤮠RnIŽ;ØG„ixçíoÀžÌSElžo¯e3êKN¦G§ÔsTê!TêÑÊÔ¦´˜(R¯¼áX’˜ÅêRÊ‘÷Ç^i„‘ nœÎÞm*HA$÷WÂgä<ÕT£IJá )j€ä©DRåd€–—TýñèýEY~­Ÿ£EI^v½z9jI)d¡4’‘R¢@:…!@$)J·™JÒ@ºX{è $¡ÒêRàóª‰ޏ…¦œ ­•Õ¤)&2f*%|kõ©¬(²R’X%Æ”‡#^æ•>S$³F:æNµ4§JVªÁaªæõ•¨¦ƒ”£XJDÊAQ+RjªÓTÒqè¡[)0ÒŠ>õø‚[©ZHZ˜Zq º º•¤šTƒ¬%ê%,•© ”’I% ÀW™µ— €–$fytó­—Ì(«'ñJªe²˜þŸàÌ©.£@jB ©®Ø–MZŰçÒRË3ø’<¤6i4á´0Ã(*†ËõJl+"Iûµ5Sj#Í!^ŠIR¨æ/0¤Ð!N¥©JÔJÔXê@%ÔRé‘f¾ i+©t¦H¥–é4ëçš•:b…dhF^˜|:™ŒÍD!Е—Ëç)©IEc‰žqç†p¼æºêúzjNVÀ9—™XE]]=8w¨ÁQƒàÎ4—\kÌq bJ’ãÄ¡hÒ=Ý+!W1ž«Ó©RZªç³]?§«àÒRŠ2ß}ûÆd+JK9£E:‰))ÉIq§ý¢xƒ)Òú&OÅ™ìæW)ðïBñŠ?ó3T²é­ÔÓÒéz~=T!Lœþzª)¹!zJ¤‚2ã£=jc è×M°ï¿%4éä>Yûiqj¨VAS °|ÔRP6öQW†>ÕN%Œ>ínå•ó,Ф3SJµtÓòŠUT„–RB*h+C’e¬T§F~5RË/Ke‚ªþ£?S©×Fv¹Z—ŸRóy…,)K53Uz”É%Ф)ACâU?.~>ŠVÿª]qmÑT–±^eºâžyªŠ”¾ËÊ*r¡.Ô»÷…ÑšdU d6Ûxúé¦B#kÎ42„é)HPN•0*X+V„­ÏÝÂ’²¤Ysu¾|¥e *J–JTIu]'ñj)"3j-ýTƒ­ž£u-jÄÞi—‚!¥´ãˆ[fœ¬ŠšeU­ÐŠÇ‹,0ûPÕñ&?¼¶U‚?O²å(vL BT‘©!Ò½$!:BJ)é¥) æ’yïVͪšÊItIAýJeJ-QaEABµ×Oœ—R0ë¨\÷]‰*¹¤Ô¼µ¾VVá-æz¤¡y‹éi~JjZSuF¢%ÜÏ×5†×zw5—ËA˜$— .ê W“H'I ¦jÒ:F•œÏª¥e¤)ZŽ ¯1j>a懜˜Rj ªë8ñˆ¦£ªqoVµ:¼d)Yœt…æK„¸¢XPÎóè{ÖšÁqï@øqå‡H€ T%#L,„É(<"¢‰%Jww6+S •)GIrê.­IY´ƒ‹¦¡`8ã’ %´§ÔU˜Dƒ™C(HI(.}á•¥h[ÈGáðà-E˜,K’Òo q¼$%H!’L†)¢”1 ¬¶”%->`ð£pN¤- JI¥ê«_«T©PØœ­ úA ¨IHŸhù’Mä3óîà]PC“ãË 9•rÂ^ön{â]Dd“tÎÚUûií Äq'Ö[iÿ­íbGÃÍû^}žA‡ýªœÔÏŒêe¹m/:‚A…Dë6Ch ‘#Šj$•%CJ”´¤—a?ˆ˜r…8A»„H J’ê Éwsm. Ô\€'ÄÅñg1‘*ínI.(—½ÖDhB@ ž-¦ ™`'`ag`I-ÏÕ4¤)D3™Är»<«Þqå^ÅfçYip~s" ÜȰ’H}ÈÒÌ\³‹¼î_ç€|¡Ä»‰r\xfÝ›ÖIp•\O–ÙöŸÀƒ¾“}æg¿’ãf/sè;\–Ç@’8D¾ÁîKìÁ‘ñÿÊtã1$ ÚMàEûÿˆKO˜I¸2Ó$¹òŒ3 :q©â‚ —Ô,@ ¼0b_ À>ähc_Pßab{_‹!œ@Ü=bKÄ î'g61›ü¦û4 C?' c0•Þ¦àÚIÞÚÞ`k"Ü)Q,ÄnX¼»% ‡yulÅæAƒèûñ€8e#@¥…ɉ0$Ʋ«Æÿ.…;¶æð ÄÑ»î0w'‡6q¼_}É|LSÙÖ¢ÿ€žä哈7°ùRLû~Ž ŸNÍ'âLûn},ƒ3c¹ÿ88·H1š…ù@·Ï¸£9a&˼ªåƒ®!@K¦ e™‹È)a(¿§÷*°´©¥_êÓýF€H,„L"Çwñ§|mRóÖ$N«×ô¿úÛŠÒC Üï1,îÕù/îZCÄÈþë8ƒå67ülœ¨2°¦êêI+o¹6ÐÓØqc˜æÛÑ»°äX—lX›åæZGÍØÑLG§Ab%Äï{é¥ÅÉámÜìþñ‘ß Ïb6ˆïf¹çwhwÄjL 6"5 ‹ÖAbI2ü‘3ò~óâÀ<¬ 4-&þsaÎA2ltö‰¼_¼Î›¨æYÉ/ë°Û¶Ãƒ‚Cê,Ûmɸ‰†âì¡4²,gåq{mbY­ó¿ýÞeÞó„ IìÞÐÛ‹ É3a 6EãÐf4¸?2&4ï¤ßg#ѸíòÂ7¨ÿ¡îÄÏø€‚BTde.j5™Il$èu‚.Aâ>âÖ‡i}ûËûí€ÒÍkÜØ=Úíh¶0lfò±È6$k?Y÷›ÏõoMͯˆoÿ[ÞßȰÁÞZ––³BPÚS#ÒØL¬ÆmI&O ±€L'fì#ræ# C;Hö&Ü8–æ&À•*×y1m~qaî"8ŸçÑßn7 Î@q‰’.ÅâÇ}ÀSfN[ÓM{GóÔÇgq½§þÿƒ¾±‘/'ë-¸Á;‰“ÆÛ¦;Ω3íĸ`âOfö±° íìÝíÜÙû‡-f$ɹ™›ÜΧ؂&7í¨à?³’LÚ]¸+‘ÝýÝ¡¿?|dÿ„zVõ~ˆ/ãcÆ_`”©Y]S Ò)R˜‚©t&G¨œ ‘<çíB©§ázìXTÍåi,¸”ê]a}õÓCðÜ }þ‡:e>¡öéÓJм¯@ë¹¼·”©I¬º42d‚–_5_Iv$°:‹c?yÊmÅèq–ß§òY©I Õ-¡ mµtT:‚æa9Ûm&Hvxùú­/#AtÝZ”µ!ÈÿäCt%L‰hÒýWÈg>ïâÞ­—ÍÒ4ÖŠyzY—7Ðè]4“jyŠèUEÅT覙òÕ'ª¹•¶©Ð<û)PI $A€Gh9t’!G÷¨“¥È’As$’[K‹™ ¿«¯Å4)iÓ@`@ €ì,ax¤çkñJ:‘ò<ð•(…ºXeèqò]J’ÓKPÈÚÏ¥H¹•Ìí¶ŸMN˜š9uר’ÉKn”ëRIM6K:‚|Ê )I U­å¼j®§×2;)Y“š®J¡u—  š¹…(¡i¥J¢Ñ¦‚Nºh]]5u¡ õžÇF'ÌLÖœRé‡ämJü¤r¥H+ÊgÕXÑ)Ì@X* 2•¥åò¦ž_&¯†¤QUiÔJÖ”Á¬)¬)!1©DcÕœë#5ÕüEI9̽eŒ¢zxE2ÿµ |åJz€’v†´üE­+&!QÆ2x¦ÅséöXïàbÏáØ-UHu´<Õ:k(׈w*T†X KA’òÜCfWæ¬1ާö_—+êÝS4v Ì€$,­)Ò b]Š– }LG˜8ø{ýru…düྒµ¥Jê¿uèʪJDRÊ/+šê ¢W) ]9u¯È? % [û¸—ˆü#•p¼+Â1X¡À0úJ 1°ûÎT³GLÈKL¶êîê_UU¦»î”ÏT KÆ ™UvÊ:ÂrUsÖ´¥©jPBu;1RI(%z>$:ˆ©ÍÌÇX¥Óþ 5tŠ(BiùÔ¥hÒ–Ë%LºÊ©ðÆ¿^¨`ª)ŗ渦/ç7G\â›K€¶}-^KìC^K)¶ÜJ¢PuOa­°ÙASø`ZŽ˜B”±`RH ÞJ˜J“¦¥%Âj‚15ºç ËN%×&J„æ$%9ˆKtëK퀅¡KUKL±U…‘OO¥A4Ò. c`çrL’AI$…6‚J*’¥à3••X…Kr’«ÏåJ|Àn~"•Ñ!§ø}/©k¹Wš2Ìf‰aM¬y¾Kd!Ÿ!YPª•ªh’‚Ž=ÉQH•;,H,AvPS1$<¥ÎJ .p«¦ë$$GP&ÌÅ”— ÉeI:J4âŽÆ1¶i\}¦ò:²T2¥I ÁÍ+YJrùg2¿ (iÀ< ãËq²¥\šdé*$ﵟÐ3ë”ÀqçHVà܆.A12Ké2áÌb‡©¨r¡å8ãËt©J…®3Äœ²œË ‘¨A7ˆ¿3Ѱü°I$’ä’åÔîIåÜÇÙìÂJŒ ™˜Û*†a;ÉçhÞ{ìÞâÎðþÅöÀÜEƒ¥›æ-¹äARˆ©Q¸˜}Iƒq “{wsIyl(RáÚÀz¸ó.4ááå)ZNVÁI UB®³yRBˆ™  “{\6×3µÜ>HÝÏ.Zv}ϪPÊ&.T=®µ˜'y#A`užéÞ KþsüRðñ!ãêZÎÌÃç8|˜@0@p‡È3þ›© ³—>­ËÞü;?C…R@Ä]½.À]­µ÷| ZnÿZy¤Æ“ÞÓÁ ’~’ïæô çÈ| Ax2]ãݤþï/vÁZ\¬‰o1¢.-}hN¢ $Ù„1ò‹°îåvJ@2}æ_vwìÀnø›U¯–”éBT€H¨H“s¥sZ®àH™Íœ±üBãQ‡¹†Ã3°;Úã‘3>Œ_×ÌJŒJ‰u³ƒlÛ$^Ñ ¹‘y'ˆ«Ø„Á! iómŒH˜Ù›NÆ,"fìNăúØ€©^‘´8«¨oÂbDÈÞöp…F'±pïÈv™{`è™%ȳ›–‡Iïí3TËWœÝÓ„€Hu˜¶ÓÚ&Àp‹0M¡ÉîÚYß–Äg ®Î9â ÞÞ€ƒ¾ùþΊG*:®[z—Œ¢ ¨Û•y-Z¡À?6‡Ô40DΔI&‰KÇ®äžqe @_÷yîßÚ˜‚_×Lh§ Ô:¨¾[cu ƒ=ÉÛ~+¦YÀ´°%DzšÀ6÷œz”’–ƒ$ˆ7ϼY§ãñœ YJ¦ŠAÖ’/ß^-“»;|¹ôµï„UÀ1}GÊeä¹µ™°Æˆ‚u9G¦ogvs…­Á,“Û×ò¹6¤$Ø <’ ï÷¸y† as’Ak.›ˆ´ ÔzdDÇ\³îß1{ú‰ =0é A ÂŒ¶ÂYÉL¹K8*V‚ R"ò2•÷Y†ºJNð«Ù¹0çwîÿ@Ó‚J\†s KÞÅÈ<‰$·T+IL,™±å*MònmbEà˜36`v»¹¼ŸÜ¼l0¤I:t±ÁqìA»<ðòòê>”s”L€OÂ5¹ØˆÐƒq߈¿dzòLâÖ½Á³H`oq߈.Dœ1s^ ^LÝ& E¢3oxá{1w‡gþ™ç$¹àÃ-fm½%Ÿ i·°F_•ŽºM¬cþ_ùcí8R›® @ã—?…à±l=à IµÂ lG—&¼oÚ÷@ÅÞÁÈbÞSØ}_åË”˜:nÓèÑš\’w$*&ajÚòM„È·µ†‡‚; µÃ˜öíÆêb%¤À‰1c±ùD‹5$I'°Ô ´ Íì#am 07kAþzìO|)`\Ï~8a=®!°D’ÐZdß{Ükõ:™#ˆòÞŸ2ðÞƒßOÀ‚[xçaÌ¿¡SbÅî~sßR'é3À-gˆÞoÚÖ¿¦ 8's¢9¶ðÃoPFRxK¯gêže­-¸ö^Õ:³\>ÝfPO– ¢ßí>‚ªøt’¤£?Au¬hæ XUærgl}£þ†z†[#öÔ“]BLφz±`ÿŸPé9#Iy¡B³ˆzaj–ÆÅúÉF^§¢êBžbšš‡™Ø§–éІX Å]dAFGU÷J—Ðó)UéN|¼#¢ÖZú]PJ•W*¥rñh³+P)R;ê‡1ú©öÅÓêä©ÐñçKBˆ©d<@”1@ *+î]@Ó ¤hZ•–®°4€º 'QN.â¼ü¶©m/õ•I£kËRRé[¦%¥(¥9ÂR!WKk)qaI ãmÊôª‹RÐÉ¥L×^­E!(ÊÒ%äˆ*H) N>oëŸi‡/BŠFaZú†b—OË&ŠÒšª«]Z hëPJ”¨!rŠ*U:«¡Šç§FµÂ×í Ž=Q†<òÒÉü*FPšzjfÜ ­`yŠI‚·<çO¥)b:êrêÈ—tÒ§U£™šë*©Vª? ”èL©Û{û+ÿpGŠGû ELÎg'›¯Q¡•é™9TäòY4UWõj 5”5%•V·Ç®¢„!:êÚU)ÅêÜKþB+jy®¡”§(H¤££åºV Gñ%ÜV`@|£/Oî”Õ£R¨Óé´êj?Õ©W?U`— @$¼ $]¶W2ž·›«ñÎ]K;ã|Õ–Ò2YᜦXÒ@Òà-¾H.…j’øãâÚ½ú¼;’Û%*n‘ua• …[A‘ù“å’Nù‰e\t²Ê"–cª«ûªS  Q,×O˜û¸WãßõÙ©›è¾D yLÆ}(X* Æ^‰ƒ°Z~2dv zª¡Õ-N¼ë¥KRÔ¥¨«2”Fe™$¨¾°”Á„ˆí) ¥)`f‘! ‚ÎNæIÝñù§T¨­EKRÉ*$TWQÚÀ;€ÄÓ8‹Œ¥BA¿k…4b&ߪIŽt¬…¥‚£¨\Dw"íéÃ!œbSY¦ð%܃?Y³8݈SL aß1G1˜Òéq*Œ¹’³ È•©NŠÖ¥)~ ÝýŽæâÿÝ`ì¿Ç.åÝÜ™‚ ýA´0*%E¢£ªu§›B -C:¶'1Ë2¨Q¹‹JBŽX̼Ö&’@Á˜‚vwh ßg00•*® c $¾áî »4—.IQóá-JR”T$«1Q&g@ w½„ñnüM§Ð;â¦f*’K|÷q{=œ¾ øŽ‡S}®I¹&/ÀÜIkÄöùKßè0=›µ£·¶•\ÈÒ¤©› ¹:`Éܹ&Æf~°ñ,ÖèÖ-·£í† É?òìmòÿK‹˜ïÄóëþcåËø Öúï–½¾~˜a>‘Úð@îOòÒÛXÞ,fNÌܱ&ö¼™¶ë¤#½ÝÀØ¿¯xŽ0I„§±Z€Æ=·öiâw%„výäÜö˜8¸ì€žøyŒ¤j<¶ïn‘c±Å ÆÂ-{ŽÂó·ïˆîg»¿ÊÌ7‰›³ 0🧬ØkŽú&ÀÏ?,NI™kÚÓlHT 0&{Únï|*ö”õŸÖ{ÞÂã^ —f¸L³Xú=àDXÖÇk=ãÔlÖ<;2æ“{ê Ì‹ª6©¶Öˆž ôòX»of_ëèoû—xq/ô—pîø•'Ò 1Z "<¹:€L ˆL`h¥Ü½ý7âð˜Û¬ZgÔnmÿW/‰šuKͤe„ņfÕ­À&AÞ?ŸE7À@÷KÏšF}„‡ŽÜÞ÷wi¶:û1põUø~æGBz«Ž6l“qÉüˆ¢.mñh,4âÚZtZ\ËYÍ‹ü°„O”—búˆØ {cŸ\a:ìpH!1l÷™í“}ïÇš›AHÞâOÎñ³Ald’”Í †dË »-°}é×Áϵ–­2‰º5Hím{_‹f½›sõháÍÇbqR„ÝÀá“$œ´pI.DNˆ‰dǽ֓k“¨´ïp8hàÿù¿òí„. w–r,vv`wîƒ&æêÒ,L^Û+åÀÁ†%øý€‚Cðûᙈ$–‡€Ü–$¸ MÅÉ.¢ÖûmLØéˆV—wø·ÏÛcë$>g,ÎA‚ñ¥îÆ*p, <ú€€uQ6° iDîbf:*WžKCýcø?6|!—–žf;Å€q÷x’r¶o$‹r¦GÖc¶¾üÂ6€çòbLú¹À;o$\\¼;»ÜA|1œ×ÑÁ§Ìv#Þþý¸,Àq»ýÓ`^Òy˜–bT¸n Ëoy±,€é‚FÚX\m¶š›hÚž/½ˆ ésèA,]Ü’]Ëz÷$8Im¤ÊìäD›Btƒ nMçuèŸn ÞdxÄüÛ‡æ(©L&mÜ0‰,Åù°a «A—¬dì>ÇYµ‹Òç}ï¿·§l$™`nísb ö±>óy„“éwþQðo§œ!@sÆäòö?OߘN€h LÎºï´ ™!Ün>~£ÜMÿR^Äþ…÷h}Ĺæ y ™¼|â ö¼p ·¸åûZûc–83"YØ7$‹wgÚ#ËÃæãÝNÁ)ùy*ûÍ35µÕ§àfšGéxR”ºµ¶Âf œqn-§øç5’Ëxw–昣ž¢¤/3L¦¡@R @u¢ªJT”—Ö‚›©%_žŸhÞÎxÇæ’3g©øO¨ÒÌeº6yj©ñ²tó+£ZÿO-šÈÕEjUs(7–Ì ‘M ÈnŒbmâ”îÔ©ï¼T0Ë´ªtÅM²ðm¥7—âeIkj)%EeÍ žyâü©ÉæL RBÅ:©M´)`ª P;*Hm,ÇV§Î·G®dsYåVûÞc,sY%f­f­²þ%Ò(Ô¡V’Mzk3Sâ*ª|ªÃñ]gåæ^'3¼³ÎÕ ô©ƒˆ2Ý2ŠB‚…=+‰ÔcN-M Éç”C¥¥‰ ¾ÍF)‚Ukb ò„ܾ*ëëPêÞËÕ$®·„~ÐsIt­ õ:TòŠRVËøƒ-• Hr£¨Âƒcˆzõâ8NU”%‡Ú@)½3“:œÙR$I¾ñÇFð]4sYÝŠé&@ I-%œ“³ 1# ÿ««S©øÃzÈ#/ŸM0A:Kä«$%‹Sr ‚Ìá±=-8é!´)À„©kR['"rµA%)î³d΢õMH I ÔBR €r@`9Q ÀIÎ>MÕŠÅ:U*„%U*h¦¥|:h$®¥FJ.µ0"d|GüF#plŸ×¹½ô5½à9&í? {|ñS†;9$–qp7ä4q<`*$,ˆI>¡ïì/ô"8FÄöÜv‰çé{œ!,f×bÜÜÍ‹>áÃ3 8+Òèä, ¨ûZó¡Þx;qú=£ŒbÆ`Ég<ØØì娑,é«îH=í&E­q¦ÜF´Èú¾íٹ߶ w˜†» ü…ÅÚAJ€¼ÚÑ$À¾²'ë@Z;oôÚl_»ž Ø<±÷>†ç ’LÏnÞÊú¹@:[ˆE¤sxÊÂÀó8RmÜv†3õ˜³lC[G©=Ä_M5"#å¯`EýíÀ`ñî76/ƒ;ò$ØzüÅðÔ ª-qcb?îmì3Zþ¼zp"'ß ïë°íüüå¨ ;ë1ª´1 ÁÓ]/ƒÜ›í=ßyöà–Ç׉õ=áû`äB}tÞñ=ˆh÷±˜±<òòý€‹»±lTK±ßrÍèükáfÆ7m³rLþæñ¬ƒï 6á;ˆgsÝýæ7{nA »›íic´lÅŽ ™ 'b’ “1˜÷í¶¹Á‚D#¿¿ëx˜™f{ÃK|¤zàã2=*QA*"ld,‚aQ  DƲ €Æâ¹Á0YÌ4_©îâDz˜6ÞÆ{_ ˜Q‚cÌH×_P¸60Ì7Ž~LÈq.XÀ¼†c·x$‚Ò»Ÿ©wg±–QEÿ:®l¯Ëîcq¬Ò,!Ü;~ywØmfÁ÷f{?©MÁa¶ç”Ê!Ä'𤓩ÌÙ›ß@$XÅäÁZ„c°‹­‡Z6Á¹oI`݇ë&øê ìå´ã^y¾¬¥Jòú×Ìtà¤.!‡Óg-•+ïw ûD)šhMÌfHß÷ß’æÖµ†êbyv—åñÌÆ0‘ç:u"öëíÞfAÖçN+¦À®ÆÌÞÄïóÜcßUÎ¥„€›ÀºH‚\“ky`ˆÅ;Qb—a|Mè¶—} ñhÙ%íw2Í¿=ÙÞNت P$%ÜDov.‰ v—ÀLØ÷aÔh@Ú5½¤XpÂÇéô¼{ßkb¤–$ìà–&Û–hk 5‰„’.7/æMâ×$LƒßÜX A<³A bEÚéKܲ‰Óåbn¸†rŽÉxQ€¸î"-Lh$iiêIaÆÞ‚ƆêRœ8rïY›`]‰¯\‡pMáDLÃjÿÄèbNàщw7o©³Ž'`@rC.nćµÃ´." ãí© $5–Aʳ„‚d‹ ÈÚMôàÿƒõù‚Ù¸œ^TçÌf@Òm TTVDæi “nûìluâ>—güö-ôÀæ Á'‚靖$Ì^^#¸¸ÓNàM€‹Ä;ïÏrKÁbíw2ÉìŸÊ‡ÞÞ·†;)IʈÐĆÀÞtµíß[Mƒ97oËk ½âÑ!Yå%ƒ äÈÎñ™’u P$،ۘ ´7âC³ñúÿží|VÒÀîd"[önÄÆ™Ü3ÀOœÀÛSÀw·ü÷°¼Æ!åß¹á¢Ý·x [^&ck›;¢ð4oÄmÜä’[ôžt“¾ äÇv½CÈ‚o,D‚nÖö2H˜öƒ¬ÅÀâ’À‘›o2ÿ‘¶,Hs¦=_gh#bøØƒN\¡æjqœªÅœFHúÛ@)¥¡Ì§ËN“æ„9Pì>Pe¥®éŽö¯Ô‘S1‘é‰^´åÒ¼ÍT¥D'â×`€¤1IRP—CH Pªÿÿ/Ïæ:oMñ7kPЮ¹™£ÑòUêS¦TœŸM%uÎ* u3UÛ2„'B†^Š‹²TŒÁÆ9'—¹®²ž§a4˜« ©¶ñjEkÈl¯,.©‚¥%¥ÐŒÇËÊTÇ.Êu\×NB©eê™Z‹ 9z€.™X´¥µSYR@òTÌuÐ}žø_ÆUéç:¶Lå:æZ–Š=c$£—Φ‹ÔU„šYÊ!*:Qš§X%É¥¡Üã×;t§éœv—ši”ã…MâUOС ¦2M&,Òœ$¢~ìÒ|Ðrq·ô¯šD|\€ H~ ÔQ•€Q[,@>r¡v¾>iûDÿMC=F­lŸŒS÷%“ñQÔóÕ²é]€¼[ µk Ô·ÊS¦ú·4ñDôÇ–ñ®RæbÂqZ†ŸÂiðƱª¨ÞûÒjXBêKeO!ŠU)rÒ´¶ËMä *Q€ƒïñ?PÈul—LÍeFmy…åêSª“L¡GႪ¾_3:–U«SLžqö3á/xÄþ/è]w3O1в6‡SÊgrY‘œ¼ºžkÓËdÕñ“ð©T]*yz4ƒ©¯cu)æHm+;ÈxñH±PKÍSÕz€QPé0¹P&êTOåôÞ²Hš}_& ¸pj#ËåStù`–ŒÏ^Ì$x³ìâŠui¯öoâb”ZŽ[8u'R” ûÑQ$•R ›Kδô‰¡ûÕm X‘§r™TTï ÉC…¾ãjYNu%.æÈHÌž6Þ‹V¢«¦ž^¿Ý…D/âÔA ò „ê, Ky”AQlpÏ´œ¾A级K¥ÖU”Ìe—ÓòuÓñ)¢ºÑ™AÌÔ¦¡ðŠP‚¢°  †gRI¤¹{•°êL¨Åé’ã¸Ó ‚e ¡ßÜÓ´PIÏ 6R  ªN¡Ôósyjy:ºS’ZM0OÄQ)mk[¸m.T£`JwÁþé=?Ãc5∭™ñ6Z­<Ù øéS¬ÿwËPÍ5¯H¥JžKHRˆLŒgÄ©‘MWVÓk Cuu,¡$úÂ}(IPƒe æ2A”Ž:Mš´i-`….šZΤ‚ÁˆßiÓ¹0ÿõ\µ,¦=–¢²ªTs™¬½2á˜4T,A ÁmE¬1å­D¬$¨”($(ŸJ|Å(¤ ¢UT¥(‰$›»½ÿÇÓùlcÌ’ÜÞ°=N\,NY:ëMïÞ{ÞMÏ[ë~X{·a>–*T@b&7>­;Ž ÝƒªARÈôˆÍ \I"æ’rrœ3zööý>¸K3½‰‰}Ø·=ÎÍ †LÄí 'ê6‘&m}øƒ‚d7Êf/µ†Äú1 .L`¿v‹³ÀÄ&äí¼Èþj¯éØï{Ž>Ì›|Ì6pC³?;ÇÉ®mƒ( ¨DfH™Þfw¶3¨¹†Íóqò±ý¬[À;‘ÞcÛndMʦ"R 0ݵ°™ì}0o^ü¾æ·œôí}˶í.^#( é$;J•7ÔÅÇx´£¥™sè'õüâµ½›×bá½ãgÁUð£OŒ÷v¶ÛÉùNÈf¹—}ݬL ´ï2&¿]¶åä?ä÷Æøi'*´»iH°fMôùI1q6P7õk;G»ÿÞœÁ 9by;çÕþSëá5”Ôuèz²VÒ©·}œÁ·2:´î”¬3RÒˆq—J¤€¤-*)RÉì}üÇ1l:’5$;€X— — L†f8Ë%ç?™ä ×œ¤©Ò‰VPéBœêNTÆcIáƒðDD‚`À¼–¼Ï6&6–\ØŸ¬àDÉÚ È“ÜÜZçsðÍ«`,Y¬=G.ìYî ê@ß‹{ÚYÛêØ ËÌ¢.bFCØíÜØép ÆX;`lD±ý#~£äYâ'¾Ö øš¥ýâÇá&úĶD›[æ;k·©›osr?sÉËY±,CŸ£KƒèñõÇ[b-+oxMç…© Wÿ·Îg 93ÂGN:SA1lo¼ à  rÅ‹†?òW|:<Þaø¿»Sþð•¯Ë bä‡Ý¼Ÿ.àm*:̉ÚÑcyéÍ,}Ýš }_¼;rÙ$ùœ‘åbww%˜—‚ %äø˜3+"Æ~&¯y'™Û‹Á³nû†å¯6Ùí:‚\‘v0;¥Ëú¸‡nál˜1"ÿ¼N½·ÒH;pK€üñ.ÐZ×›ófŒW6/r]õ Gv´Ú$5Gi7¾€jÿ¢“µÀ~ììæ\q 6-Hf:†Á‹€=Ë Eìâ1 Á‰€'ho¨¾»ð—ÖìÀ÷,;løb’AµÜ€@çÌ%¡ì^ìX!oêTÜDyK·´i¥ì",ÝÇäÓ¼ÛpEÜ1ïQIww)õ¶å„‚Dàf2¶ Jn`Ÿ€þ^æcPLÍßžÌ}÷7‹0w°Â±vf†³ Ì]æåáØ¸¼$Æk~q{N£I¶‚ µ½÷?Îóÿ_°‰ÚÌaÙ¢}ç âu ¼›Þ 1m°ÒÛ\ñ O%¯Åƒ žØ'g~ 1w®Ý¶aÈ„=(›HѸ±v¹Ór>wþâ_ôpØ@–€ñÛ=kËr=íüj&×2`ÛéfÆ¿oçýG¾¤¹nwyw “¾Š{o¼Çµ¶ÓQ¯°/íï_Ü{‘ú»8'´‡ Ö> B…µŸn×Þöà¹Ü^Ð×Ûÿ“}mˆ3¸€!¸[`6>¸õ0¼:§¯¢Ã¨™.ÖWÕ1INØ—}Ï) :BJ” ?• “`xóf«ÒËP«^²’ŠT)ª­Eå)BJΞà$Ç÷¶2Ý¥g:ßTéÝ'!EUóÝK9–ÉeiI©˜ÌTM*i!‰Ó©@“²B•`øÜßN9ižLäÜ—‘‘g ÃÛiÇ2$-UJAr¡ó1ÏRëŠê „Ý6ãä_WêÙÌú„fj©A‹&›„!˜ %Ø`öþ‚¾È¼#—ð€ü3áJ@-=#§e¨Ö¬”®¦imW5˜6™©Yn|ÔФ ;6+JŽ`¦Ã¨*—V†ÂVÒ[EQ„©„£Êq£™2T”#2[t`1Ë.ªé¢›©ZIr§%; AH4í ô¼çˆhtÞ›­œÐš ”§4£ SB¢°·),”²)pt¤€1ŠœåÕÞ‡CtÍ-I¤D)H+ZsˆÌ}beIL$ÂûÏLð᪠Ræ©Ò!Nì’ÇmÀw¸k|•ãÿ¶*´ªfëÒÌ"žJ’UO&€½+ª„‰©U%Lê>pvIÉÕŠ§<ä¾ao¨µÅ@"‹jœ:•œ¥Oª©2„å#×`HXRVH••fã3⌞œ¯P\ÕE””ù†ƒF夂\‚#þ%-ŽOöIö‡WÆûZê§GMè¹|½:¨Z…2¼ÂsÀü$±üI#S,+â&õ+ÅSŽ=åó—"6â’y;`€˜³t8h ú¢œÐNY ¼ñŒÉz7\X&z®E@H…WÌ€[IrKXŽÇ—Šªü/´O³J#Àž$ʸCü.—Ò”­L©ëô?¸<øXžKˆÓýæ­a¶iêZ¨©€aM7ç”·eDÉL%P@^ã!–ÍÔÊ©4¨'ZêR4éÞU¬§R‹‡Ò2ÅÉ“«už‹•ê´_?Q4²ÙLÕ,æ`?•T¨"¹¦.á.Pâà$³¶(œQnbQ8–Í6OPãÈJŠ“æ·NÓ‹uõ¦Ã XÈìb#9–òè®±W3Z˜Bˆ¡uT”¢šArä“C°¸~yÖ—™êÙž›U4—“èù<Ý\Ò°RkQÉЫZ¶j¢XÓH‚TE”ξáu×]&KŽ­r.©qÔ,‚m7'úî@ìhHJCù@I€D¼G£Il~sfj®µZµVUjµjª²¢‘2Ä’C³É“r|ÂÂmŸˆ_}gonÜúÑfù{óÇ™D¸Ø{Z{Ĉ›;b'ÐæŸðH¹±¹·Ììq?œþ˜Kþ‘;[ôò`7'þ)‹É˜"öþW?Ÿ3ú~Ø€³±k3D‹pÆùF ¤(´°´-IX%'Ö…AH)*Iõ3A‹§ pŽïÄkEþP[›˜£ì&ùMµ,m¤^vâK „ÇøŸfô v“b`™þ=¾x1Ø vå@îDû^ i~4ü¡Ûhn@¼K ’É÷Ü ö>›Y¨‹Ì€N±}’ ûnv¸V6~šZÃpv´`[¸!ˆ~=É~ç¼aŸJF‚TÃâ]É0´l ÈÓ`ÙÛm¯yôgô¶)$9ÔþÍh qò8…•&/™_[‹ý`÷Ï ¢ 6ü$¹&ÎE¿A‰1&î$[ss2ý¥ÞpÅJˆ‘ŽÇðEç{M´÷ŽÖ<1ì7³Ûû๠– Ü;¿óòÃÒ%s°cÔAôÜþœ,ö½þ³ OÿÂE™°Ã‹@æÂþ¤ËÆÁæ­Â € nF’IH¿ó,Óyqv >À5ÇÔÆ,m ~åÞÀ0wöáƒÞ¤7ÐûD[HÒOÚ\ÁØYö.-g0í!ðA‚7$1{¿¤´‘¾g,ƒªÕ¿`Úˆ˜nósÄ,H¹“0–b6æÿÚ1.çøÓä>&é¤8ÝÌù",wA À q;™ž+Pp_òPM¾£ßxÁ$0Ôí%؆ ÆáÀ»1×÷ØcJÕG„^yZÚHR|@óCg)×/MzJeR¥J‰&Ja:@ïe “M$‚åÍ&#Œ²— YH{8’ÂdOk r5ŒÙç`œ°LÞ3àLp™hâšF,w¹KµƒóÏ8÷-%E*p 3]Œ@$© ìÛ?„ôçm{Çæ@#·aÈ‹'p>"©îeêSlß‘’ 1ôgô=‚ѱÐúF§³ˆN“Úàñ hKÛ¿³mƒðØDÜ‚À#Í2ЮMˆ2ô­AK#0Õ&–R¡•@‘hRIJø„ˆ)'ƒî£.%¼ÅåÀ»8~ر&ûijJ\r[ˆ…Ií‡åNY*¹™H7€L,4‚.-$ëØ}¡€–\ò$Ú0×TAVÀ–i`Р=€ìÌ\M‰>¢oݪ`lgëúÀƒß‰åÿ†ö V¤²˜1ÒfÌÚNÎÝ·Ý<ŒCÒ‹¸7„îAßÎ/Ärä[‡¼‡ë¸°…ÌlúðK¿mÆò‰U1ñÌ F¤ˆ¸ßA’-“bIúCú΀ÚÛÑßy‰;3½Œá¢ÄMæ7÷NŸ+[ë¡à»Z7·¦þÐ6À}„ƒïÞ!­¿¨ÜàΔé9 ò•Y(@1€rèMÓe³\ËKÃní#Þ~xb< 6x·$‘¹lšÀÄ\f ƒ3®ú&6ÔBHsvàqVØMìA ÐYË;Y„™ŸspÃSoµÆÁ"Âm¶¾ñ‚ ›±~Ä?¥¡øÀ‰}žÏC‚ä3Æå‡ ÉÞ'µû;ÌÎ×·ý~G¾ß8ô킨%žK €fö–3œµð¯ÈŸ¶ù©Þk­gÌ åð[¢JÀ)¨ÅŸA UÁ”ÒS©N“¾q˜"Ç2ûIëtéôú]%(WÏU™Ýd+û·jµ< IJUßpÿ¢Ï³â?×ñÎ~‚jtÏ ÿG§%l¡™ëy”RwNG*µT* ýzô4’P v>õ@a… H%d’>ªJbàf XĘ “ÁŠA$¥à– ìX‘ôÜ€î ›~µT­÷d£Kæb Ry,à ,î$Œ_êŸ9}ù&•§k¤^xi‚û¨@%Åi-– ’âHÞ<7Ó´TMR”®²ÁK):‚¡ ßÌAó Ì~RûeñÈÎR¯–§V½>•”©¨|¦š³5©š…u–Êþ¥þÒ­@èÆóŸ8»X“MNáRU¹QXZü@¥Ì¹ˆ ªVd%DŽ;Gé(¢>"ÐJˆ (ÝØ€Cooø‚¤¾?8¾ÒþÐsMg)“Ì)tT…R%EI]:`ÊÓQT‰)ÔRIÖŠuk£ÐGþÌsòL©O±†´D÷…A küÑ~5oÿ¹t#!(øêκIØ‚ÄIåÜXí?éegÿÑÿj¾ªã¤R‚d|â™R§¸‚X¾/5U‘Ô^GO˜2§ æ&¤ú›SiÃéÖHP%*Ê %6 xÓºu?ÿgzèÑ?yéµ£š¨#qø‹K]Ž>ñÎu#ígìÈkJSþÉâܲ™ŠM!Ò2Ä‹§M†î83ÕXm#~^&°Í[´,-D-/»R¤²§–:¦™RÉ€—oNi¦š3UVNQ%u袽D¤$9¦ŠcZR’eiHZÒ–$é‡-ns;ѲT޳PQÉg«ôìšÖT¡Bžg3šÑ–UuÙ9zµ•F‚”X'ã¢£Šžê§åÞjÄO–Ý.S‡Ó–å*¬StKX" IIµ÷AM5õ“–QJ•W2ŒÅ]I *RªÀ;cLAH߀O/ûQÌæ2ñÇV¤>r]3Ó2F’‚SI}J¥.ŸV¢ñ3,` %Él02 œÀ…—ÄØ˜§ØÄqÚ؆-h"{ÄZÀ ¾?7åÝÁ ƒ )ÙínÄ¿q€. ý&c¹X6¾óx½ã†ýâ?ûoFÅEœ}´’$O­¯Ìt¤%Òc1‹I¥˜5ÔÄþ{7Òa›¥bÇS–‚Ö`XLÇ’Ò1.Uê$DIÕ lock{_ˆOíß·6ù@{`-`ä_¿r;qΓ& ´v'I MŽÖâÜÞÍ¿£Á»~Oˆü“íóv&î'‰c8tÛp¤“ü6°'ç?X?^?I÷Û¼9knÂoùÌO!:‰7Rd™ï7üï{jxwií?õw†ùbäÍË»}ZìúâfžB]‹g)Ôa*”€¨æ ( šH2ÜÙ»öžÞ­Á2Ø­jØÅÞÃaofopX…bP'IQ“ÿýí׎ãK˜†Ó˜’XÄnwüιÝçÎ@`þ›=± H`uw›/y!05}øŽf#‚ÐþfÙ‰†ŽÁ¿Xcp7os!Ç8b’•[VÐM‰ÿÙžûE͵¹´:I,XâäO6w"o¤™?™Ï-Ë퇡 9±9Nº|D~ðAíkꢗãˆ3ïÁŸÖï‡ à?´ ‹ì@h0ؘFºß]dÿ /2& $±l.ݤK³‡ LÞNç~gÜ‘ôĤªOï[˜‹ßS3Úâ4‰؇·°ß~ý°K±ùÉßoóþq-ªM„æYˆ$Ê$íy¸=ï’IXM†ß´É M±ËÕÿŸ6fÄõ7ï›#_%$ÜÈ«…Xé}'díÅk ‚ì zÁ¸0‰âpÀwgKÜßr%ÅÎþ˜ìËì ÃYàߨ¤€ˆÞmEÔEÇKú<©€Åÿ%`!,E·$nlÊ‘ß|B•ZCĈ€Zû[pâé>c¾™0GÊ'´E…ÅÀ ‚­ÁÍBîÆÄúcÒJ‚T§´pÇH†Ž€]žàcÁxz€¸“`Û3ýÁ™24ÌߨˆãÛôÂCÍŒ™~Î[¹c#k6è ¾}›‘“õµâï7<Èô·Òa ï ˜p$·kK,ö AÁpƒó Àµˆ´G»¹µÏ·3½Ü†/€KîØ\É0]œ¶ãðú[H’D›×rOñLv“¶œH­üöùžÀfwæÍaÞݤ͋<õ;kuÖÐÚ ÊZÛKm%+Wš¥)!-åA %ÅBPBŒ€•…*J–¢*Q&$D²B@rKooNZJõ©Ñ¥MU*ÖZ)R¥I*UJ•j”!H*Rª,¥!)¢tßbè§$žGäÌ# ªm±ˆºƒ[ˆ”¦ÝmXóÊÖ'ÊIm•‘ “ÇÌž.êÿï=g3šB”¼ºÁËêý*Z’•Äù净T^IÇî7úvû:GÙÇÙçCéÊéuŠÔ¿Üz²Ò”¥hêÒšÕ))DºÍf–Xþø@”§z«¨Xà¡Ã\¥eY]Z ZVTÙHZ²Âä”Ó)'ÔHÄt¬¿Æ®RTÊdPuK8'I– Ú5 oi½|ôÞšrtšõY5êüP¢i—ZÐ. ¦¡!ÊT™ócºÌ.5™"¥>X R²œÃËJ` ÉDÀ9Ó嬯¹xìžéé:iºµ%×Áƒ*#pu?üA·çÛ?ŠëeÑ^šsˆÒ·ËÿMei>FJN€§STA¥PÿȤF/>úŸR& –H)bÁDªŸ¬÷ã¥Ó@@ àn ƒÅáœÇÄùœÂó5—YD:ÔN¢Râ¢U±I.yÆAôuÅ5˜⿽&›1ÂX’nºâ%^…©@@JreFdè~/JWÔz?ôM](ÍT.¢’ êHsÿ#i,~°ÿNõUGÂ?hUœFP.¿EË'Z¤­uÍzn¢iU^–[ h@Ô¥¨H"íóê<÷Ê‹f)ù… ¦ÖE•†¤(©E(U´›.·C¦ + uvJÒëéË!I½‰ CÞKÇwñvb¡ûQû:$Ña—ñu ¤(Øô" ÒN„,°`‹ VhiŒIú<6µ„TÑ×àUIy§Ð•!b𮙣¬ÁJT•%@Ú‚\WU®®V|Þ]k§V‡P¢Pºe” JUTÀÁ!ÜÙIAcÐÓ—Êu|ÎO¢õµ,ÞGªxw=÷ª„!Tê#/ÉPu$Ƥ…SX”))ZPKZ.«6¬‘«ð—êTûîb4ÔkRóðòêq w&JÙn˜Ò­Z-h.R‰ãnð¢ÿÜ:í â(¦4å«W®aO3 åê!, ¨ª¢  .”¨$@žöéN§…~Ì:§BÍgNj¾c«d:ONªªŽ¬×J„õLµJ²ë©—£’ûJŠ'⮑ªú–[”d®ædÞf=mÿœÈ?=øë–ý.~wùãàu%É ±±\z–;|°Šô¨ƒu•±¸Iý €ÞgFˆ‰¹Ú8žÒþÀsX:‰&YîÌ[n.w‘Û %.åÔ¨À0bç}µ$îmkä†÷oñß“9ȇ»'ë!ý%°ÂŸ‹ØØ7½µ±ì}ôá€sD‡igg´7ÓH±-kð>‚ì@ILƒ¼\‰ˆÚu'æ±fÛåoFý¬äb7iw/Ïf£iŒ=&êKë$ü*ìŸsÆÐ8ÏûíÛ݃C8ãÚ`L³l@Á?âLÚbNûü¯~æ8-úE„v òµ±;Z߯ù‰† ²‘12°-a ^Ñ¡´Úñrå) ˜.Dz ÅɼN)P“ëwõxg‰›m8̤ Ðfu̽¤úèoiˆ÷Qv$1»± À6…;ú‹Hœ@ ÏÍÜûž—rÉnT«M÷'¼Éµô’lÙ˜ú±)‡7³Koˆ/;¸¿³n÷¾I‚$þí Íü‰¼Ìj6¾ÊU$Ü>ÑìbãÀÛ›<Ha/øtúÉ»éê$ˆ×&×&fxW››¹;ìÝÉk0±ÿ‹7-«H`ó¾ ˆÍ3q¨¸3ê>ò=„‹€&x„ˆ`MÉ" @gb BoÏÎÑ}Ç{<¶I*ˆq1ðƒó͹1ØpR -  Û˜!‹±öÛ[‡û ímÄMÁA˜Z¬,I9LƒÜÁß¼ñ9üö;´,Xz1À·Ëøßõ>Øž¤Ílþä@ÏîÌÆ°GýL˜âµŸ)´4°‰‹1h¹—¾,Ix*iàDé€ ±6†8îGû9øÄüõ%òÙQG‰þrfALzzKÑþe ýäÈ‘{¥—%$¸Ò.¥\‡ rç)Õ¨ÞZä4™ý±Ä&,’p|°".3‹ptI¼Â²»9mï½¢v-°™Qs'€û41»9u¼i8§Þ)óFw{#´ÌXÎÇQ¿“È- Ì“f%™±¸ŠN›»ÿtpቴ@‹Ã‘¾Úmhºd˜q3hÓ± ˆ8;/rìî LpI`øT“ e÷cÍÀnDÜY‘Zô÷G½Œo·a8?#gõk=Ç–Ÿ.à´Áä‚ Ûvh`|;{ÜÀ›A“Âo#Òm¦½øûÏ7÷ö&û> ³ð%‹1Ý€w2fâZ0ó € 3aoÂUˆ;kìf8 í'ÖÿçœB\›Àl4°`â¹Ü›àj„ðŽÓð§S´DI]OâãçðX%Ý€žAmˆ0çógÜ¢@•þ`ß±Oå~ðx/}™ú|Ìì²IbáÁ 1øpC³ –€Ø„˜ßAÜ›úcb$k 鮤ÿIŸ¯©í¼ îC5ßÓ´v‚ór0®ä ú"ä'ðλ@ÜGÒ#‚[goðk;°‹ÂG¼& ±;ˆ£Àĸ‰î •¯¹™í×ÒçH¿¼óò½°»Ýœ»wï6–„ Ì‚DÜ‘{Fšú ø‡™~~$·¦IQ0{m¿7˜q3Œ¦ðáÓ´cx×û_ŠÓáØ;Àam¸Üµ[Š#Õæ [¢JHª•" ² y×:éÉåÚ²Ë"¾mæT•T²¦4€,ªÅà ÁpêN>ÌÿI_dãÄ~!OŽúÞP¯¥t àtZUi륟ëTB±ØÒéÀ$Ó'ËS8ªi ‚Ò¬ëÄy’“m0¼B§3Œ°µ†™¼ÊÊĤçE+" ?Ž)¶[…¬(qjYæPB… cJÖ¨•E*`¾º‹.Ât¤)Jò¤ãô³©xÃ%Ðé&‚ªQ©Õs)+Ëåj,åé$[?œ)óSÉåÒ§!Uêšt):ª%C :³Ö6¨«ÂðGÖûÍ!M¹XàJ‡˜A.,ePJ\ZÔå´†råHuO øEIM<Öu Z‚“E+/¡Ã%ˆó+jÔI”H2>ûsÿPt•›ÏtO ×^k7A*¥W¨©4êSÔjÔ BÂYkYZP„ª¥4JX$ cÄž¯} rº¥u5)¸V²¥  §4ëYΩšH­Õ³KÍç3‰šŠ]OˆºaA H[øªCy`SI Ò -JÁ)¹™V§¸‰˜½ÎlmaBjgg¨tåÓU@šuò¹ºyjȦªªIaV±Ê,¥ŸÊ\¸Å”ë‡0œUü‰tõ.R0µÔSTüyÔíB[T„¤,Hs* …… ’xÝ<Ó““Fr¨©N²*¬ uP·J¡*d™¦ÄA š?ÔŸŠ×Öëøo¦¯)›éÕr4+f3Y<Û…Ô«^•2 @JÒ*º )‰8°¦3E¤Î÷ÎÙˆÓý “¨'~‚ÀØ ™¼oX/wÇÊê bcv‘”‚ò< €©Rê‰Ó*€$Ìú¤‰±ôìüýÁŽüþÞØ–h·¬»Æß71…I‹{L^ðfñyÐÁ®Ö$Oã¿Ë¿6ím˸÷—æ<Ä;L[XªH“2F ƒóùi¯½âvïx´váî.Fí…bIžîXîî=ÈÌZ6µàë=¿‘Òúƒ<Î?__òÒ6·ýoù³>ܘwÀ›˜´öÊ£´{Ƈcñ'ä#¼ÿ>½°noÜý}E±2¤@‰¾dHÄ&Æt$ÆÛØqÓùlyŽl[x݇¦!›gd¨DF§Y0}â-§%¿¹py#°»[ÔA‚Iˆ{p@bà¢íwÌp‚A¦E¢Ê=€Ôi¸˜‘~T^LÀw0D¿¶ÁƒaH†ÚÑéÑö¸Ä-R”Æ™Õv1ÚI÷¼Ç–3fa÷œïËa‚@ Ìà ÎöÞío¤0¨ÁöB$Nß…–FàÚ½û—›ËÇbn=¶ím @ÂI;¾Þ͵ٰDü`öIÜ@!F'[H¸±úê6½Ÿmœ–aòß5ÃO¤ÿlÞñDÁ#UÖx‰=Á'‚ã“`§ooWhrg÷³w´÷ü°²B…äSi:Á˜ùoÛ‡‚Ï&1¼8$8fì\–ƒ‚b9aò0Ïiw6“ °OŪշb‚5kÜ;“7,dµÃ%öîv߃„wchr›Ù®yùXß”²^nm-ùn †HîO`oµ*ݬÖa°2O³¿nN"^ÏÁÙ®ÍpCÙŸlwýšvžúš¡ÿ\î ©)Ó¤ ˆ‚DEûÈÛ† :À±K»_Ì®Ñõõ' Ššu’§!ô±a Å›·7Ç 8º€uЀˆŸUåÍbs wßM8¥Ø— 1 fNê-ÉmñêQ ±`C‚@¹ ˆ¸g þå¼Éóu/M©É1ïü2âÀ ÑìÐØ³\qýÍŠÕ ~bâÐbnm0ðclü_—ÓÜßñ[í`u7úw-!¶#ƒÏÀá‹oŠ´–8ˆg%˜¹èÿÚÚœÄXª&æ,>×´ˆÔÌq1€àzÁ, °oG3¶øváƒìw¸³Ùƒµˆ‹¤kÛÉÜhM·Ûõâ¿åÛ†ã¶' 62‚æv`€Íë‚Îdùkˆ26?ROË€LþB}Ëòbg—3Ì% Ä0ú퀓ð¦>©4ö?¬wà?¡þ ÈýæØRC7hËê´ñ&·DG¨˜0àì;\ÚæÓ>\?ÏQ{úäU†¦vc·w»NÌâZã ˆÌÊ/'Dò¾ºÁà‹úûü·ï<Ü,À1ú—f${ÄŒ+€eLï–dh!L[ý5·o•¿?£w’@%‰!À/¸†á¢^#“||^ùÔbÖ¹÷ ÿ#3Ä6öþZOç‰pǼws™$ñŸÞ¤åZ¬æ¬z‡£Bæ©Ôyî¥%ÄÓÓ'*ê]¢ÐVPD)e)&ücº¦~LÈ×ÎV!© ši±]O„'¹WÖÆÝàog¼oân™áì‚*¬™¯M ª2¹4ùó9•†ÒȤ•iJ´…ÔÒ‡HSãb®ÂúsÊô”tʦ E;tØ~Ó +ï*1˜6‚ûÎ(ùÏ,Ÿ-JóuA|p¯…œëÝJµj‰]sTª¾ei |*`9ì„6p”¤’ØýT§Ô:ÙWƒúfG&¼§K¡•§•é]•gPÍfê)‰“¥y¬ÅE5zõXRÕñjÕZP"s×T+kÕ[†áU¯­º—1LYnÔâŽ%J”S®Af Íä!!  ©À‘æê}ÃThŠYŒÝat’[*2É!ž¨þüÁ΢I’Iñð—ÚoÛWPê‹Ïô~Ôs+¥›¨¤už¼ºË^s«ÕJΤe|ô:jT2ôД¥h*¨”#[ —ùOÇ*R~êêÒèR›JÔ¤çQÑn©@ä`T¢n¬± xÌõ¥–ÉS-Q Ó‚ a} *,ÍdÄÆ9„¼×BŸOË.•4i©Z¥m. |FVC 0= ï—¾ÐüWšñgZËæóU“]Y>•éß R>*2¡iÖ´¨•‹R–TI±Oé92£oˆŸ‘ o]äZDÄûÛŒ³·Êwÿ?&ÿ÷¾ÿ«zaq3+( ¢HÌ‘&úÅŒkx¸ž <8Ÿ£Æ÷ßn6ÁâIžñßk³¹Þ8ÁØyÖÐVÒ<Å„9h)P\q@”&s(„˜…H_yw73Ý'‹;O|R.`<<À´·¾Ø+¬šwTÛ™µ í8Ó‰Fdçeè)[g,¡`t G‚n"ݠ؆aõŒ,HŽ$H!âû·|+Š *9r‚¤¨$hM€’U@•"Tn ¼ˆ_ÉØw½°¾ìý»ƒóÿ8FµVщüÂ}Á¸3a°›>’v¾ÿQÐà³ðZZ9g›5ý¶£é¼Á*ˆÙJ ›ìEþBb#ˆmâ7{– ÛàH‡ùIoPÅïþ0† FÃ2¶÷ï#Oê`ÞüÏòþ®ã¬^ä;Ž„Ÿc 7 :ÂýÕÌÀö˜Ž×à¿òް{{ýFדnpd$g[Òþïÿç¿ÖÜßõ‰6öÁgØ’Ä 9bÀ“ßÐðy˜@¾ƒH0`ê¹Ôím½ËM£³5¹'oBmvÚr AG»ínM¬H0èõýêI¸´‘´:wé~$†,ðü¼ï·i/ËF!¿ù÷†úúq€*·uv;'H“õ×mg†Ë܇9~Ï´ðÿžöhÞfØž¤¼Ý yC~Í‘q Çq¬÷V¶earÌâd™Èy.NßÎî Y£ÐÞ'¾ìÎ0à/©ÅµŸÿJÞwS¿ÿc½'Bm&ÆÒ ÀâÀ@E7ôؤ<Ê‹‹v ùb’YJ£æå€`ÖÞnïŽ ±R ‹0O¦,dü{¹&Ä™TZ.AÈ ÀlæÅÄsŒ‘”½À¶ Ì ˜¹8ð^²€}KŸZ"4:A›ÎÐn±ž>ìáÈKb²\s; @:L~0Å·w0p6ïÿÓ¡Ð~"H¾Ó'}Ì ðÜ5ÞÿËX±†ï²ó»°vÜ0––˜‘¹bDÉ€ lDØî'{Ìí#ùÇËüdzîÇ"wm¶ 3ÿ“Ë¿°ƒH7¼A±™™ýEÉ·é–Ì8Ñs9‡àç/‚K¾Yj@F|Ä7½ÿœwß × v2L|ÝøvôÀ½„@X¦o'Q"Ï?êÿÉ#æÖ"Ì#½˜w-¾* +–9ƒ˜ [Á°ŒC) æ4ÔåM!_…!Nœ¬¤A + " ãÜê?§‡Îç(e!…U€¢fÉ¢&HL4œm]Áž*ñRÍ/ô§ÕÔ– VS,¥Q¦¦•æ£/MDHJªK€CbérßA¹Ç®§ýµLÞ @Rê–õKÖ%„ŸXi†”âRê€È’âÒ”(…( N­Ô|sÒ2ôjýΪó•€þšP…¦Ž²#]J,Ëvd±sŽßáôÃöƒÖ:ŽPx‡%CÃý(Ô3Õ+g2Õ³Ã.<ÊheªV¦š‹H)Iª´¦™%D’œ^üW›¹¤´' Á0úGñ0ÈA§£BTµ© e]ujœp•]rTJ‰#'%ÒúïŠk Öw3Vž[Y&¥bti/¨P )ÒÀÄrØú[¯øçìÇì'¥ÿ³t•Ó³a4¹ôÔ¥Uj-)d¯©u“^¡vUB ²²|’ÇÙŠãüåÔ¬hÔ¬T>¦Ð¶Øa¤­º,6•c*€0P‚´œ‹Y%צ%S”tŒ¦K¤x{'ð‘L%U³®¾f¨1r¢Ѐ%±ñ·]ñ7ÚÛ‰lSÍfUIie²¹d®Lèù*£á¨¤Rø©%5*¨üZÅE!Ü Vœ›Òš¼Gò”¸iЧ±Mú¡+R™h­! ¨!$f ~.N+«ø¢ž^†´¨PéËå“«; jJK„lÀðH.އö}öê}LP«MNU¿UëHÿléÈ@*V_,ª¨©™`¢¬¯* DÎó¿:àœ­GUË|ž´Ub…Sb8ÐÊ¡N„¥Mªž‰@Fl ¤®} f1!>nÑóÝNµ>¡ÕÞžUÔËä¼ÃY:T*WÕ'–· |ŸÚ?Ú?‡|‘ÎxCÀ)çzµzjÊuÓ)Zr¨H4—–éëI#₟ˆ–øIT²4ãy*q@¨•)d’¥IQ*H’fòI™;“\\›ZÄí`Mÿó;‰ôçò™†-Ç!Ë$[ˆmø'·ÈÇSŠ^T©jRZIJTT”$æ$!&BS™EDFebIà~G؆ÙÅÏ£@Þ0TD`^Ï»ï>÷»áÊ™Ð>’ i°‰Ûæt—õÚÞ„‹Ù÷à‰q…þ~oõýpZe!%ÌéÎ’œ°IL™J¢ ±*NdØ›I"þ–ý·ô}ç¼r]ƒ~Aû9ï‰EÎQ±$þ™Õ¦Ö?â) ƒ\‘IþFø0]»ßÉÃ{¹í„P²D‹(qpdLØÇÞÚÛ‚-kÎÍóÝçôÀÄAÊ Oû¦ÇÐùVD`êLØñíwxùÞ$z>ýFýÿŽlÜ™¹Í”’=$ê;ÚæLè{ñͶoQ܇ lEð@b ¨žÛMÇðKvÄÚ}ÍÀj'Q1#¾’Ó‡yw 7n8™" “±yÃ4“vÆáÝááƒA!Ä23cø‰#H’«Xú͘ƒÀ’6»à{n׉æÏòƒÃ»ï,G<`B “j˜‰ÐN“7óÛh™*‹ß€=Þbs…#Ž^gøâ 6'i óš ’¢ÒL,r´ˆÓsqÂ.RA€/³ ïvïéÈ$wãô±h;ÚÏóúf+ûÇ€N¨¨¥D§ÅŸ= À"èçATD@‚3A4#sbHЉþØt…8Ô©vnÞØ¬‰,——wMØ=Á?ãæxÅ#ÍpHŒ  žàÅõ´‚4'IùéµÁÁžÇå03rNþå@e0!ƒî" Ø8öí$ãÅx«:I‰Ì³°¹Z$Ä 3ò·kYÍ®Úl߯mã ¥‡bð$;ÆþkîäîMØÙ$ ½;yu7齎“qÁ$ðÝ¿7õ¶ØT‚XI$,ó$3àÈ‘„Ô¨iŸ¥Åަw"@:À»ѵìl&lXXÝðD¸ °›´pK9÷º™ö§IîF¤Þ5´ ˆIòl ¸¿råËÜ[”–"4°›—’ 4‰`dCáêØsE¤|-*ú XÀ"ËÈÒ¤d Pµ·ÓŽ~ɨ:ý[Š•ª¾¤ëRHíƒCløúí²gì‹ ¸^[§ä‰H’šŠËe”TÃð‚­FåÍÛ'ª/Ø"Á+"¢­h:4¹A6@y0f}>G“8¤|*)T‚OÄvpH¹»ðZ1„ûpÌ“[Ã5ýE'9ž«L³ ?tøi èÒ\êä¹½üóXÊúQŒá‹-¡Ú< óšh)MµVªÊ:÷ÐT¥ËK®äYÙr”Lq£tu⼞`yŒösB–C®Á¯—¦@(ÔüCîHú?í?9B§ØoˆzMC—§_!áΆsY|¸*Eò³¹©™¤VKª¢kfM:ª/¥`¤IN0}JIˆÔr úÅÆ’/ÛÄngøÃ· †/üÒ*ÅÇ2 MžæìL@qªêMÔfÙ´‘6[{Þ×ïc6·Ÿ‘/öv´Þ÷Àÿ C˜Ú¢ûüçTgT ŽæUr}Ȉ˜™ï¤{Ð÷älcçù`fáÀ‡$ß³°ßäöv¡Ø#â$L •kçùoÄùðÀNöƒ}£ólCu/ÈcÈåì%ð†%r2fo0Dv#R/ÚfÅÞwwpcä?ƒŸKm±¶!Kˆ$eˆ¼ŒÒ, „É ‰âí~IÙƒ4îcƒhÁ˜³ŸA-ùsm¶83̪•Õ²µ6â’|ÆViAm «ˆTAÔ½ˆŸ_åÚ.Ü~¸ XÉÜŽáïòØiÓMÓ~×ïÀqͯí“â~¿Sü(¶ܨ3%=´9~¶¸=Ì(‰‚w·Õnáö ¶'óÓöâ}/‰wf€‚@ÜÈRŒXÀ“~ð$éG×Óøq ~ G£5æòöë$ˆ€±`=$E¢ê7¾Ä}A·i…ž^ Mà±·©€g 7Äa/kzÍrDãJž$?Šoý{’BtLòKðÒoÃíØËwhf `DÍɳû„Í£bn4q"{IÚL^A› ;ðI»¹‘ß°.ÓõÀœ^á­g·æHÅãVR."«À‹äÔÈ$Üw±FñÃn ùÎÍl)¿hõÛiÙÍǶÓÔa"¡™0i˜‚¡èQ'´Á7µø­€± Øm.ǾÓ"ͳÏ1Ø39oMߘÇÑgû+X¯û;ú°þT,<ü‚¥6…GDü=«Uͱ‰“à…”Oöîþ%_ʯÓÐaHJq$ ò§ˆl|íñP<Çf~ “¤)gQ&äŽãA¿ L€˜™`Ì<=Ømî)‹’ûA-'ò zcÄ*]A,ªGÃ)̉DÀ‰ž÷N.ï1³ßØ1ý¶¼Ò\îÏxÝŸgó༞Ar ¤é$_Aæ ÇËùýu’ìîÃÒ1¶óÆ?›e]†î_Ÿhüâ’nõЀì?­·08ìïèða€ý¦vf‡g‹Å® ŸCÌÄiÌI‚ª&|‡÷ûzì Fû¹¶´aÈi <€ X{n  ª5>£¬MšP’ ØØ|É“iàÍÞ\°˜ðpRÊ$Aier€ÆÆß9cŠï“ùæw)Þ^z<,©u*Oâ<‘”-©P!DAItþH$””q‚êýo/ÓCü\Ã4`’Å•P‚A H(/Ž©öyö[ÖztÒµ¸‚@ åÈ›|_TûXéý ûÆk¤Ð®°U÷|Îxš”‚JÒëR‚ªšÔ Ò)Ô³åE‘æ>³óÝqŒ+¢abÆj6«@õ¸‘#¸" ®M“¸ôïtÄ¥+Ìåë-m)ª´‡7.‚- Dð>tñúŒñ}J‹Ëô§Ó2´(29UÔ!ÂR*WBu“>E~'Ô]…–Äqì_qnbXUQTœ¯:²‰0TØ!&ÃiÚ Ã/ÊeN[/J€JR™˜y™áÞL6ÓúÏŠ¼AâË­Öz¶w<µ+QFc1PÓIQ%DQÔš`;° öÞ`&$é1:ÚàØhlu ŽÆO¬Hí{K¼’×ÜÜl` ‰./r]ŒIï»ÁÔÇLm3ôk©“hÜG­eí»ÉùinLØâ4:Eãp—»Ü›Cö•TªA箲E´¶·Û†¿¡ÔKÄðçÛr–ÄpJ¢D»±`o"帽°€`É;#áHÒçßQlLpm,MÇÈ9þzçbK'³°ïv>¬ñ ´§”Ë#âuä6LϘ°ÁD“ØÏ΢´¡J.¥<Â’IìXI!¶ãehœÍ|¾]!Õ˜­JˆCÕ¨šch$«Çq#7ŒÓ%®fåªxYnšˆ¤"?:t€’©Z‰&¦dqÎ2u5ôΡT¨‹P)ÞÁu&;÷‚äí³ûSV[7Õ¼—5[/þá^•sTŠTÎg$¨(›‚Ä‚$⤤Æ‹t럼ðSR…¸§¤(ù•ö†R Œ©ãS Œ¯ˆz©©éè DÔ51'S¹1¾6̧‰jõï²?µ?½Ó(Î'1]uBʵžFjÒI)Ji¤@RP4¹äu‰0And‘;ØGõùqИÏPOrýØ7å ´– ˰;Ò{8[J»*u6ÎÞ’uýnÄAijîÄþÐFÎ.}7õ7r'ò( ™ø¦ÂAˆ&Ãq©€xž½¿Ÿ?]½0$„–ÇüIîÎ6q‡2¸ˆ Ìé*2@7ú{é08ŸÏçðaˆlæä‰bfÀï7½¡„ ©Yˆ’M•x“ïxÚ÷ø@àÄoØÞÐö2áåíð‡±`íµæ@ßcóÃLˆ;›\f-q§{oÁÛ¿òoôÀžv÷ùZvàÁ# ¼¸#Ó•PvÖ"@#±; ´=ìÜ\Œ/ÞGÓÊXñqw"´W`R5âß-ޱ{qÀÜ»&Ø„\¢$û^woÏй=âÚEÒ{þóÞoÁ!÷oO—êþذˆnüwž?‡sà¾[}þ%®ÿ;Øj·?¥û͈g“3-ï·¼þXED&Ö*7¾ƒxŸ–»¯ÿ6þ3ÿ.ÒŇÏû?^ø€D*ò7: | Lµýö13Äv.ûÆß2Kͳ¹!Úcw†·ìCjL2M€ÇÖK¸3áò´ñS±:kÅ ï¤éÄkŽßFùÈþ )6,&íNÝ»9?8 õ¸ Y?áÖÇølFäÌ͉$ۼðmÞàw—¹‡ô?¿›âvûf5hFºä"}µÒm¡ÐñZßA‘mÎþ¦üÛi»bãòÜ[{z_~>‘ŸÙ1ÃoÙ½Õ§r›xËê!2އøvVÀÿyØöá€Páü¥œKjW ~C —V¢4†S`x‹³c犌®»i´ÔÏsõ‹™®œ‡&Cˆ‡¨üËÛÕQ,¢– 5Èžåµq྘X™ Tˆ1u£Y͇ÎH<\-¿ÿwgÚÚþ€â¥%!€nâœmq¸Ü¹rÌXmëé5 Ü8‰÷-y¿ÝÃ;3‚†–;mð¡ä¸&Ìà€C=€îì!÷‚I*¶ºém-"Óüµá@f¿ä~^ð qfÁ%Á}Qw 8³}{Ì&RFÙqÕ†›B–âˆJRJЉ"ãRI÷Û€HHÔ¢üD€ÂK¿·¬1ãR¡V½DR¢…Uª²ŠhT¢ß† q%ÜÜ»6.·-rs F!Œ¹å¬)4êl –T@x¬˜@ôLQÓ[ê]Ud| £‡ VÄ.,NÀ¹%ÎÌ£Á^ÊÓ ê}fŠéªžUdºJ€a\)-V¤†¦ P¶ÅÙgí!éKm!¦Ò„¥)BL! X ºå6R$jµ²ŸJ–êY.¢¢¥(jnLÙÉ7æÇè —ˆN‰4¥)¥(BP”RA© $§IâBtŒx5¼Ðš6^©¬Sˆmª‡Ê@‡YR m”ç ZlÌ¥iöåza¬tRÊ”V °ÈR‹€ÂHqO­øñ>’ëõæSG/Vª(é)ø‹]B ©PIP5 º–!+Rà›U‹sö5Zµ&‘F™’ÞR”º² ÊefS0!(@™²€ ;6S¡å(§U@*Ô…)@”$Æ Áä–Ò1ÃúçÚ§ˆú•JˆÈ­Y ©ÖIZ+VR ê)I(IP%ÓM)@$¹Y•AÔ¾óÞ·RÊÒ‚²¢MÀ@ÜÀÐ4Òüf’”$€” f‡’ß)o|s:ùŠÕÔª•ªÔªµ‡R–­J*ò³’`p,Ëòƒã™·2o?= ÄéÁ&Þœ}×0¦(G³ÌÍ·‡Ó†¤ÁT§¾À‘´iÜ÷´Ž öß߃µýñ8s`Áœ<˜»´nYî ”猦ÅBV”ÌH ”‚@Ð ÿ ›q§blw{ãñ^O$_~߯ØP$Í Èï 7·Î.5µøØ;¹0pìÄ1–83/ÄàÈŽ ‹‚FƱŸc:®’Åáÿ+[ú^1 pžf œ“ÏgŒ #°ÒóÀF¿÷íÀoCú œîaØ3K¹>ûµöŸÌ{Žþ–N*ñŒ*˜œ©w¤A$Y¼$ê¦æÄIÜàs!÷à`Ê Ì…&àbDésîd›p;7¨Ü^ã As»]œúŸÞ6œ#PJ„€$LΧÞo¼ˆð\{Üý^6ýp'«êO¡kp‰I¼™Ð{-C_i@´L˜àOÍÇí,g·­Û³ “ü¿`.‡DMŽu|767½¯hßpxŸ__çíÎ!´vþma†™…J/ ƒå~ ïó½øƒåx÷þ}dÁÁô,>\ö;_шÄÂG®-tÉïñÈßQC`µ¸€ˆ6Ÿ_›?­ýð»Œ0·y¼ÃnpvæbâÂv°*×ý®öuÁ Æáà^Æ{¼.^òY¶;Y‡x°³3ˆõNÞbm&ò©ÿ#mµà]æ7“`åý€`àò@ŒFrl\Äÿ—ÞÚpdÞIÌ­4G{›AüF— ivgdn7Ýö âDö<›óüãôcñš‰ýÊIoB¦Ðb$ë1Â(¹ ò#ÜÃ<=Àg~àÇiw‹v6—ãéUý‘ö”~Í^­«ÆwQޱþÄ<:‹J:LÈ×MËɦ‹4±!”¡1ËŸ| u\¦VóyRü}ñóhÅJ|Ç Í¶“ë&dZÄMíÅTÓ³^ýøfi}ÍñïXJC¨4éž!ɳI$´ó ôúÒ2¥¨wüÈÜ®Ð$öÒ, î‰í'ky`.1K:™É*"âîwd·ÐÂÐÃBT›”™ …ÿ¸‰wDh7:³rAyD7Û³œ J‹‚%…È,ÎóvÚDß(¤uÀPòÚ+ .¬=I×(Ì ˆ™'åÅjª”’—+!ÈH7 ÷:FûöôöÐÈÖª„U Ò¤¥¥&ªÿ R@%A)j`Ad‚ ™Å]Dšzy”Š¥”¤©Ñ *ƒ!$¦K`ŸË°ÔÈž1UTºÅBªÍ å‘!¶vp½øf¹Æë§”é´ÓS%Gïõ RjV,(°%1«á¤©˜  –#Ñ«æ¬R³N¦`%ÅA)ΙòŠ€"à”„¢ä͈E(é™e¯âë]BN¦ºK5œ;3gÆC7ãnµ”¢¬±ËR˨²ŠEJd’…]üÃJnĈ”Ùˆ–5F’ „þ"¥Üͦ|†Ê€@ç)9Pdæ Et̰_‘Uj-Ø¥K"št–¢…Ç—ð‚K;!ix묜9¥“ýd峕u6¯ºÒ*Е(5ª„2BË$ÒõX»Õï)n”äC„6…ʲ¥E$’IÌ\sU8Ne(‰08ÉQʦ‚<®Té*fÚZúBxÎÂØÒzŸ\ÌõZéUe$R¤é …•Tøh2ú‰IUJ…Šê+YN£bCïŠ%) ‹†Qê‰$À™›ßÓßÐyQ3w"ÐÛiË|íŒgÞU%>PÅ’”“!õ*Q"ê%¸àO¾µ!Ò˜øR$@lL‘;AìFƒ‚ÎK—‡$Ï `#ó6|WR²–’–eB@ .\‡/rÌã œÆf3ªMµ6˜Ÿé¬ŽÆ}„ðöÜßÙ±DµüÆÇ{x!í-O¤“‚Ÿ˜’òŸŸ„Dþ¶ü›øØ€„ēٌý>WŽø0LfÖÑ=§_m‡èÙÝ‹¸6oiµïˆKî÷³½Œú±‡`Óˆ¹&ÚI6ÒÝäï©7"OÌñr>ݹnÖÚ0…ÙËðÅãsïØ_x¼ ÌÉ"çxÓô0bI—Ø›4’|À·üF‚%¬àð’³Y€Ÿy8IA߶Д‘?Aë¯}I>åÝíËñØ6ö€ósc#˜¶Þø¨ù0̘9‰ Õ—@’D°Ó®‚g@ A™Ø~1`·M͹…SÚÖ”û°-óx¶íöp^7ðò©g\zåèU®6,ÊBM¶}œ]º:¥½Îµ• Q)g,¤‰9J‹ Ÿð`H€&¾b˜OF €XÔ¬ $Ã$Ô€&<­±$@î½78¬ÇÚgVÍ©Z“—éÕ2á‰`j}ш ’…©D1‹8¦zŽ ¦0scêÄHÿv”d ÌÛr öÉxp¬à.íAÃ˲ǣÁ ìÛIÆ›öÉU5rþT¯¬€to‰”wR›r m‹’ C‡>ûÜùЦð2ÚJ™9LÌ G¤j¼ñᬎ»”(¥fÊ”uJ|ì­šãTnøÛzFk5_ì›ÄßIU4©§á„=ÁB´€t‚ä,J£0´Ñ1ïDçQÁqåË^-nqòáb±c¿, ây$[ ¡uDQóªÑíýHÓ^÷}àü Ï³à”»°i¼Ì‹‰oÎöÀÕ9ÍÌe¹¾¡Cá'YÐw"G¹yL؈ä8÷¹$³· jÍù—=åŽó—=™ð²2¸“:w¹c±‹iíCpʰbçó’ÖÀä~Äÿ©{½š ¹ö*­É±Úñ>þÒ`‚À–œ§ývÀ½ä?é¿¿é…˜fçèF×gHùL<X@s?PDÝÚ8|I wñ¸äM€¾ñˆ "dHèv$¨" Žýî`7ùnyþ;À018¸ùÿ¶& öÁLF‚Q=Œ(iX2Xh›} =»‹Ë>Øn– ?;Ìö¼áÍD™° IÐZö;êIíµ·à‚GiÞà‡õÄ×p;ØÃ–î_°r@”@\ ™@’m28þo¾ÿâÐØlàú¹ƒ${?͈q T(…”œ¤EŒJT3%&dâ5þüãÓé?‡òçè?|0¦o0Û{vòŽ“{Zþç~%ö_ø?Žl»÷þ]ø†|•ŧ,D«P/¡2d÷˜ž m#‘³ ‹ƒ#vÄ>°ãç©ù3<Ë@È´Â`‚®Ñú±ƒµw–œ8arHsóxœ_þ÷y/ð؃bF[S"Ä“kGh‘´žõI—!»Lˇ¾³g&ÓÙ˜“ÿ[“€þS`Ræ& þw{Âî OÎÍ-~Y¿éÄ»ü»°½å®MÉÄåï› 4‚&$þ ì-–~w“x­V>—õÚâgçƒó±¸ÄY÷¹Û¿Òçû#èìÒꢲ_Œ¾£+A·E<<£è=öáÕøi“r‡~]J.FÇŸžø­#ñ3¨°f €NÎ#¹ÇÍ[9œrÂé´iñ@&Sr{Áúz)Ÿ Ù¡É^Çm¸fÆB¡AÙE€$R^á¢ÎÆñB¡)JÛRsçQ)ŸL)H›$“”í*“LP$¥‰0Ñ$írñwî¥Q(EJjF­r‚¢Å*d1,Á€%ÜÂrú²¤ 'ñ› \$ Üü$\€Á$Diy{Á¿è7;‚Š«­)& ¨’H$Í„›œjË‘G$) … XØM§¼I‘I¥$„…\¨¹b )ˆ—À“ì§:SL¬¡˜ „ùA!ˆZEÃK€w!;àÒÔ¿+d¶ˆ2‡Â$Ìw%D\nÕ¤˜X&…SprÆ\vÞÖRÉç3|²©¤¬éÔœØ¦æ „¬ÿp;;o6î´¥"¦½-ŒæA*q%A¥”¨-I]£±tˆ©Ì ÿéQ$´¶”É»†t‚]¹‰œzktª´Ò>÷Ô‘L)ZªVN­ŠU¨¥aáÆ’.ÌF$]feR«‹‡Ñ*C*Yø0JÅŤÀŽÜZ*T“@lä$7Ôü@‘L¶MÊ×Ô¾*™•¢E©ØÊR®a°œJÈÎ*YóÎæQù…Ò„™Ðãúñ`Ö\©“6KL0$÷1ÁÇŠ§ÝÇ–ˆZ¬>%O)%Á%)J¡Áw%˜­-D™¶ û‹ë$ؘ6¼;/>üæÞ¸óÀ -¹— fò÷ÃÖ=?ð§X6 ö:h}ö&ÒïòŸ}¤[ˆÃ0`;±A-±€vN= ¯!LÓ8RÖ<÷a¦îJÜ€@‘›&cÞ:ùì¶]ÅJ‰Ö?±>u‘J\‡1,Îaéžë=Q!y\QD’“š¬>ï–Nïñ«¥I† e€)¾'*0ì; AMEY®¬ˆò)AK ›[ÇÔ I7 I€HHƒ4ÓÍfs*/ƒGþuK­Bl‘ aÝMÎÃßèý¢ £5ÔSê ßvÈ‚œµ#ÅZêÔµOüRƒ¦t»·‡˜fP€ÈHÍæ ÀÐÞÒ&cŒ€p’c€ö{fv÷ŒjŠ#Q!’ ò‡$3° K†nä¸Â™3©ÚÀÜ dkhˆ™± aÛµíàÅ-.ìåí#p41¹nφ˜Áê ŸÐ‘½ ztž û9üƒ·Óùp’9bÿ¼¼‡œ1?—þÿ*~z\FÚO’ñé=Ý÷7/É/‹4Ù¡ÛØ±6í´¾*ŽLKc]C‹)´¯-%)R”¥¸[h ¤¥Å›òÄõ’~è)€ÿª$¥:–I*,?rLc}û8M$ø‚¦nµB‘éùŠôÙ¥ÕªªYd€šaK'áæ*— $0pµ[„Ö”ãx½B[c,@.© °•BŽúEøÆæè¾K%I@¤ËµßH%ˆ%ìÂd\n^êj§âg(ÔÁ)ÓL…9uUH55<xó‰r¨n¢ƒZ°¬õÂ`ÝTÊ ÊDùrÚ&I‘èèôÍ:¹Ä–µJ@ÒÃXû¾­¹aÆ}£giçzw†êÓMD²ú¡Rk¥:¾èH$¥!‚¡%.÷$¹8©ðÇžžãNNe%¦†ªÍp2fI&bq‹®zþLGÿ¼©F'ÊUîIù]ñ»tŠ´ÓöCâešŠRÕÐòô*Qø•“@1oÄJt‹D9²Ä Ö3{Ò7×]ˆ ›q¹¾Ýÿ…½XÛ6îîîïgïrì\¼Û  ™Tj äçEûïêuÔßùíüˆÁ Kí»‰` ¹»¿s¨³˜ß)Ò` à{ˆ™ßA$é9«w.e€Þ` ´±}Ä(Œ®@üÓëschƒh½¤÷±wLÙ™Éß{lØC¹cÛoä–L” ››“7Ôûnah»A;¹Îì÷`ÇÕÌ_³ñíc… ÉØÏox7ÖöÞT=ÿöúß°m¸y¶ü‘;¿êIvˆ››ë3¤§S¬û€H¤OHba®;wÚç‰êþ›p~`_\nNƒ0ˆ¼~h?è-v‡õ{ìüßÔ6'ÕÅË_«ßóÃPc4¸&vµÅ½·f8‘Û˜¿b-ùb9‘"ïa»D“oG— €(¨}Ï´Ê•a‰ß¶²E¸ƒó3»zñfì`>'ò}_fÚ%ðCp’IøÎ÷‰¼ä=¾\ybüÁ>¢ýÎ ö¹Í<mý;FtUÿÝ Åõü#Zmô×·–ƒÁÆÿ›O> ¸ˆÆíoæâí2-ƒ2œÖàHŸe×íím ˜)rÃs?¤DŸmƒârû~[Ïþ;q6)¾·™ý;뮦äpàÁØÁ.,@Ú绑‰pvpâìàEíybm…¶a1gQ¼Gªt=ïÚx,K»I}!Áˆ¸&"HwÄb%ÚC½ŸfæI‚¥@$‘¯hÓ¥»ž þ@¾Ïó¼Û»†ÆÅ˜]çx$Ï©ãÔ‘ç·`e«»dI3¨¼I4"ÕTüh˜¿¼ˆÝýÈذ‰<í¶Øúdÿd–œ'ìÈêžZÅÿSÌBeYzMІd˜rïd2 2”š`’]½ÿ¹Cv;aRÇT6.ö`~qó?ÄÏ⹬€L5×úÄ\\ͤÑH%ãrKŽì ‚ÏËcÞ¶SéHyv ì y0CcÉx„‘rFe^EÆd^w:Øþ¼[ærð^@1qqC–Â,$H* ›°`6bÖbviS)öžÿ"I-­ø‹òÎí{pC÷ f±8ˆÒÅ;‘È uE¶¼1/´A&NÇIÖlg¸&vµ‰ÜKìw0àn$€oò±N‡b i¹-\\X°rÏJŠ'*•1 "pEI X‹ëÂÂØ(9!œ‰ÀØ}Yܘ=7R"Á‹Ã0—I~lºÔ¤:ÐPÌA-¨¶D¶­®‰:Y üÃ) ÓÙ@À™÷üJ!ZkP* •LšJü"YÊ ¸”nÌ%¼1Ä¢j*iÔR-¤¼‘éMÁBfne0}xE+4–jtêrÊ)Þ`‚ö7wäúéÐèÕCÞo*¢ ´S]Àº©©& ¿”˜¶ Š<æµPG™ya`ĤÌ)d ÛBI“nï€çþñpCÙ/Ï£]ßÓ:K†ëhP*?ÿl´“Ïâ¨Á•ê]Ͱÿºá ©%Êõ;7Xhe„Œ·2¨ß@I}3~>mN@$ØæaÍÀ`ü5¦ø°ôþƒD¤Ôêu*¼©4RR‚N£¨È ÄãÓý±ƒP!?pÃYuÔÊ©HZóeh¹kd \™:<ªÉç+–¯˜Z]ÑDèü›€óHiÆr_ð÷IJ¿Úú5,Åt(|,Öy¡SKÔ ¡4Ò'œy•¼Ç‰ÖŠ|²ÐS¡-²€ņh¾‚%FuÓÓ—éùz.t¸%K.¢Ï*3Þ\îy|OSñgXêziÔÌ®•TF’¾4¨’RBdp¨ÎÀSé%D’L”Ø•x“y½â7ÓÝb.}™­¿y¡¬ØÕµ$½‰%D“wrD–]¹w³ä ¼üÍþWùÅ͵ï{–f%çå;Ÿ¬ò½ŸåµÙ˾ì@.Kó…Ô͇oç›åh´í¥‘s!Íàw,w¨Â° f´As¶ÐÒ}Âc¡€M‡nâIÔu˜.I0o~vræå¿-±Oÿ)›Þ ¶ÆI#‹Ú%% Høf H2eW“ñ Ø0ɾÌ>fѹúŒ3$n ick@"ÎæÎ Tüµå³IYP 3—r©9¡G˜¡'ó("𙸌OR*Rè ÁÕRåZAÁ0âØóÁ©£G)Ôsu~)? *RÑ¢4Ô)PÒ²¥¤IÒ¦b`aØ[á+®q$BÒ“˜ZÙÔF°F¾Ä÷Ï™I"‚LéÙœˆH/-a óôZÁ5zd–JÔ’‚ Îj(3±H"Ä;F<ùvƒ lº](UZŽƒ(R©ÓÖ˜ “¬¿ 5³D!)@îF·>ï.'ÔbÏf~7Jè´•YUÍ:½AD(ƒ¡*9X #r–/r—v.jJ*¨éö.€¸•Ñ´')¯AÒnBI¼‹ÅñÕP?ßò§Hfª§bÏðT&ìlyp?áÓ³z~ÈüEKâ—5²4IgIê´W§p )•C&X½²TîA7˜:n#]§å1l±ŸO—¤voìKïÆ>¨·ïc6¶ú'æ8ŽÃ¾ìòá¶ ÍØ´â)!ØrÈ‚\‘ `OË`22ˆek=ÄB6¨Ä€O°à—öùçköÂívÀ$üâÛH’@à4í!%æ®ÈíšÜìM¶±sÅ+0wáßfÃNó>ÓƒrZä=¹ÁmEäg݆>Ù+Aeç6( ñcÕ%Z·Oz8Dé’/ßRਥ ãÊÆõ)ÙÈ-Çl#12î_hÙ¾ŽÅˆv#2lW)}â2üpFoX$‘b4$ÞäÀöª‘9}Øú¹äËH{Ì'ÝT2˜åpÄÂRSË\;È×T¥âY l3¢àv&-aØiÅã¹ÞçxCƒ.ü âµ%A@”¨»3ªòL,gÜ—À۔؈0fdA. pfmp57໘{EÀ‹áåϦ  r\þ¥­‡zNkÍ€`l ˜ßÜkÞü!ÛmܱÛL—íj‹0fºtÃÞÓr¸$e1—°¿k–¦¸#i íû‰fnKݱg”»iy°‚ı‘ÂCaHƒ@‘å*ò Ÿ”éq§ ’îðÒóa0â`oŠÊK—¾«D³ƒÁ Eâð‘} =ÅŒ{Ã=ßÓ°ìãs/ë‚ À~ä´ïò#kÝþ‘7™ž±êo¬î5a’€m€™0˜*%D‘¬äsõ:®aU–”%iE4(XªêQ$*rb1Ü|Yá,:6[§PRªæ+å+æ³™šš‚«æ¢Ziˆ¥OË¢’%€Ôµ)DœP˜iJhêWé*)¨üɘ÷YuÒu9êîj lÐɤú»í½…祧%›¨À’¹ZH'`Ñ©LA#ŸÃ (ç÷zXTz^J’¦e5eă)±jTÇåAMJʼn –,C‰³ÿ›8óuµ…ezyŸ¼·Ó¨Ñ,YöÔ\fš¥ åªöIYY¨¤ËY©d\ÄfBf¸µäqJé“Ôrêa¤S¬îÁEE-êÒeÞ=1ïÊfПõl±UQQyÌ‚P¯†*ª¢)} 2„(Z)ÂS!YL™ÄÞll~i©3ÆOØxµ©"Kú4´$°>Ö~CöK¶ „’á ø³˜°€s7Q¡)ßM,[h¿sË7¼½÷Áì%‡े°Ýï¶ÂXg¾S'°Ÿ‡PI’%Qc@A´·È~Þý»ŒæCbEƒn ÉxÒä? ‚Rﺀ)´|J;v'Þx&/ÜlûCÌvi$ÞAfgoþç–$“"æÓdü£þ»™à_‰ü«ÞÀ6°´I,XO¸.îãýgR/'QÛÚ.#‰êöÚ¾ÿ#êyRìw%§ØµûØðäˆ6 æÂÆÛ{ ý8„ ¶–íð³ œâoìm¸—âó}¢Y°e¥ÉLÚ`Çc ŸkØpÁf.?hq°$¶åöœ]Ãý»<û¾ïØœ53h0/hÛç= \6â4Ýùm±ý ŽZö’9¼îÌ 2+1:ÈË•%Y¤FlÓpd&$A1 ûÃ÷Þ}mê=VÌ^^>·úÁûáÓ ^u›‰˜‰£]fä…`9’íÞ.x~p[ì ]ùž .çH)&#зî·ÜÇ鮢ÒK€Á¬DLXL;ƒêÜáœ;ß™<‰þ®lØ2 ,@;››ÌÁþ¦ïÀHv{¸&ÂÄü¥äý, ‚H±´\‹ÛNürfÀŸl¢603‹‹HÀ‘´pÌmç»Û‡>Î=qìA·™™€¸ìY˜ÏÌ'0™»‰¸ñ#B¾ãX„ðAxr/g°;ZEÎÀîö“rv$ï fâeˆHŒS’¹–4IÉ3$k‚d˜Üžö°îÒßåíˆåšL—€Àv#ÖKqw™ºHó›HòA´Øùj‚@ÿƃ¼V³. üÀ›K7ü°Â^aÿÆû˜ ±bE™úyÿd±!?e¿1‘¢¼VuTþœ‹Ò4ÿþ·÷÷žY`ÇiX‚C;L3÷q„7;Î>cXŠen’A„Þf *Œ¹½ˆ’ ¦’BS) ;0k9f~ä‚ÄðìĹj†¢¢ ¡-ÞCLN“L–a%ó 3e¨Ì¨(()dLØÀ¶[ß‹ÀNûµ¶,â@/-Ì;áH!õ2L?”»¸Ä‘0[€Àoùå‹oæ'q¬~¦n"üÇmþ£x³[×Α>`"åǰ!¬ìæÇgÄN£á&û“¾ñ±a°á~¡Š¢Á»Ë³IæF,ˆpàNä0 ˜ba³€“”e‹Ü‘u A½ÄŽ÷ !$‡ Ü i$íӼ݌a€`@J‰ºK-ýÞŽA»î"f$U”I"þQ2G}ºÛ 6Þ„ú Aƒ@P]Im¦ƒ¤í!ß2ßü)Ü“  Ü‹ý&d×ö‰gÞd>ÝÆÀr@Ó§ûHg$$±¸3&‚Øzõù¡Sp¨&r‘=ĈÖ-Ã'ð›ŽOgÛÐ9‰ról+A™Ê€Kòw#UÌÄp0ËfL¦m¤Þå7Aë¯h"X;nnijïëc.öl*pìîÆí7;úðĎ؇n”›hfÂHoY‚$D{ëh$Žòʼn¿¬Ùâ"1Km˜˜³%ÁÄ0 .ò.@ )P.¸¶›Ÿ¤\|€Žì@&Dú–•ŸößX;rC/s»@w=ƒ° ¾€Ü‘$#BL‹’460oÀ ^ì\p;ì Ÿv/8yf¿,@ ý ß»ŒÀªóy•¼Á´ˆù ØÍø!‹·>œKÃÙû‚ÌKa›s{±"aÚåΠ渔ùEJ ©aÂØQòÔâR´¥e3—:RâÒ•¤-`Q@/Á–/ïicÇ®ö³¸/ÏÀÜ8q%Pm kšòH¾ú71®Öcï \›¹Á$pÌA‹¼›s. s‹ÃÒ¬)´)Üaô¤º¼Ô´abJ”6^ZS3+VTf+H7X‰ë•„eH@j•[uä ;¥ 17!ìèÿ°Î‡I Íøƒ2”šê%Óõª4÷Š´ƒ¸Zצޡ! ¨—jÕ+ÔšÜî%P i¦ÒL„«2YÊA‚›Üt¢‚¸/QJ 0”‰ áÞ¸}´õ1W8Œ¸+2”)¤¬¨¤ë]U‚ä!3r €Þ-« Še"Ùˆ&ÃU‰ƒ:ÇÊÀIŽ6U'ΕI !‰¹K‹Û;/WNN¢IbH’¥1 C’ÄÀ û6¶-1©I.)^ Fb¦îžàimrÞu-DŸ‹P3´³›ƒÌÏä¹à>å“ój!y…)Ô’¤f³ı ‚X—I¡u²g3Ì® ƒ2ᓤÁ‹m¦\ë¡[„¬Dî~ k“þ(EsþÛ˜¢O•YŒº™Ûj·íårCZîq%ìAÐÆÑ©Ÿ}íÿbó¼í¾ÐÓË3» cœ8pãh.ç€ä5˜>å…܉TÁˆ&à–Ù=æFÃ_ë A``0p ž\û@Ö³˜±0™Û“¹m¡˜8Öed™¸TvøçÞ7ì6à’s…rI¾ì €ÅÃúnö‡Œ@œ®op`DÝJÜý´÷1À†ì{zqòÿ¬Øî †Wpo}ÚÀ ÂAàÜ“${ÿX×iÜ“p@&ÍË ¿q$\™s±Ááý‰{’X]Ã]Ë´´â;‚$ Ä€M¾!¬ƒ'µÄ+ƒ=Àyüý½8°†ÏÉ‹<[~Ø/ˆLæ$ ˆþJ€’fàü¯­ä¿fâI›Ol(3gmø´–åûˆ˜Pbþ¤Å¶ÔÏÊ5· w;€g;ÁbÞ‘IÅŒ€g¼1cqµî ¹j,¼m¨Œo¯·¶åÂäì6–†;Û $³I–ôî?ëÄ@÷¼I$™Gúk+É’K›¹éöß{ðB’ä0aëüyä°Û|8‚3Ö#MMÌ$ŸU´àÅŸÓëm£ö|M†ãÐýKßs»bå X”&à ÿuï:v [KϽK9Áû>؀ݽ›»DÈâ"\àè>³q9ocŽÀE†Çëyn÷`îï,æoüΜ–3`&ÎÏ` ÝÜððT܉1aßÞL  · æßÏæý¸:¶!ö2YŽÀC:K8bp^î’bâ%$^up7¯´ñ>—ä߯7c…rKˆ"ÓòìÜ\µ‚g$s+P£º`,#iä“?kúÜYÅ„ð§øùù¿yú!øÍ‹™hZóû³ù­ó™ÐØqUGb\8s0ÁîÌ_o—|0$9ŽK›{;ûìvP옰¤ý–8ºÂAx£êÓé3£ÒæNª¨ˆÚE ”yDáÉp›ÄýKá]ܸ2_×»oÎ>a؂à ãã LvÌ~]àSP€X‘õkñ$̼ûÖ`†IS ¶–S9`âKÙÚç=@…ê\LX…6?Kú®Ò4™Ûb¼Ã’.Ð K9вáÔ$Zˆ,@g€-é-s€6$ `‹û~ ô÷ßC1Äü@÷él($íÙÛ·sôöòüFC&æÄÁ´™ÛCnyK>å½ܸ˜µ)äÃÔ’oKCp¤ ØnN¢Lïì/ó¾ .ïÜ÷ÎE‹ŸÌ$‚4°Tµ&ïr¦$9Í„U¢vWéVêÒDEæòp_T†3ÚÜI< 0/Y8%ÀP¼´]ù–&H&$é`Œ©?áHïùSj Hƒ©#qÄ à‹‡Àï$øùCf‘ð’›w"Ä8Ä"}FmæÄÇð“0 êb`ÅÁ<agܰ`ÆÜârØ9{\:lÂ%ÈS†ÜÏ 81uk’.›"A3pÃÕØ.y?^î6l)pX¼û«mƒÈ,Ä3á\$„/ "o¨@´î/§{e®Ïü"Ö¿ƒ‡Ä.‰ ƒØ;3s¹.Ð\)¹=ÂդΤÚ6Bn;pÍ6°çg³î mÕÄ’ûÇk’H µ®€Á„a \À¹'þX€5ÔhË…{< y,Mî"Æþ‡Œ,ˆ—%€6U€ho0ù÷‘1ÿÓܹ±Ò .ÍkÈ»_coB0Ä’|À@e@gÐvgpÀ€]`ɹ6ˆ€t›‹r‡š ïq,. Oxl)gbìØ!žÀìDïˆ Q$D“î$昀Oñ_Iïq ò™†ÕÜ6ñõ÷—Ád„‡r¤°É$ž^åÁ!ÜØ»¸YÃé(™%IòP‰ & ”Úá7ø”J­©q©g¨üzµVÀê0H°„C üøú½LôŒŽC/¨ PBT ‡ +[*£˜ÊŠ‹Xº‚_77â·w*Ô¤ ¶%Sim!I¼ÚfLþºœ¿IËDyR *,vÔHQ8 L8Øã}¡u÷N½]I¨ºˆ¤(¥ÔìšÂÐúTH »»‹œSér‘¡-§·þæ`>q Óߌ’’äAàïa§ä< —Æ˜Š„Sh¤.^H¼˜±cåboƒ>´¹LÀ aÁ`v-‚T ö:w‹GÓNš•7Ôî@`å¢Fþ÷Fjªje2‰±¥ñ„'ñJ­ÙÎ$%ñ.€|µ·‚P©›ÊIîdÄ‹\Ï1 IßÌ ³’û·âcAÿ£QAR»¦C˜Svrm8Nñ2?¬LôŸéŦÆ?6vØö‰‰ïŠ@iZa’ÂÆv‘‡ªåV'RMó7¤¶óî â1ÿ,ãÝÆÃÑÏÈ%™É#s´@fÙᜀªÎøMÌÇÇ®ƒoûÛ‰wù{6ýçäØC—›ˆ™;û m‡Ñr$c%Z íÞfóþ[Òáæo¸8€7"Í Ià±í÷³á Ü‹þcrbt;Òãæx‹¸<3ìðX™ƒÛ÷]ÇnLÜ–Ü4Âÿ æl Wcnðv·ëÄ$Oä8Ø0 g$»`é¦Â žÄÌ}6{áÃYh“ Ì’dí1mg^!hº’;_ƒåØH-ûBƒa%¸¥Ý@yÙâLƒm $l#½öÛÞM¸–g¹Y‹ÀgÞøfyqà5¯-èA’ Œ#c[ (~P6I‘À}S;‚óèE»?'ÁÀh$ÀÛÑ®Kƒalp4¼‰Üý`AΚ˜à Eök™€>Á¾›p~Gsë´ï°h…TB{çP‹#½Ïa§ ¸/$¹bI—´ò0;0wì ¥çò¥[z:܉jã¹› ˜“ÁÞö¼víèoþ#@GÏþËÖ&%j6²cµä‹“°ÜòàKYàŸ–V ?2ÉLˆàOw N„êFÛ˜VæÖ´n òak3H{hÛÜ´C‡! nă™oX³…0wŸ5ö½Œ[}{Z8?+ ¤„ùfM‚aYÈNRUéQXL¤¨ZÝ›ô·¥ö÷~äÃK4€ ,¾S‰Ú4~;@ E%µ‰$EÍà‘ˆÄ€è:÷؇ Amƒ™c;IiêÄ€MÆ-Dx s©„ï3,Nà€ 3ˆ ȱŸ‘`¨nIbx‚àD;ð/w!ì_å‚Zn§Q Ah±<\¶í2 ïê6›~é^ò}Œß´ ‹Y®/°y± Äî1Wácq7!ŸO{Í;Ž$ÃwŸH@¿¥3}joBÇbKÅß±'Û¶%Ó¸g.ÿ&CÉ`\0Ä!Dfç/ ˆ\îvЃ4]Ëòà±úÎÿ>pÁlJ™Ë’ä‘2$ÆH †‡/' Nb¨'aó‰ÎÑÆö‚xm) ‰z»ž]‰yöyÂ…\“°xrî$‚Ä ɇ+ „§° ›èF·’àîL›À!šÖíadpI‰VEœ±á®X"p®¿™[`ëk[Q±÷0!¡Åáš#~Þ‡€Ã g Ãä]Ò†qg ánIJ{’t½¿”€’mœPE÷`Å™¶"LËÚïÝ_Êwü!À. ÙïÁyÎR ô‚LÁÓ[¤jI¼k÷ì"áØ¾í ´CI–ÙÛ±÷ÃYá ±pþº`À›a¦“>b ìb`ƒîdd“q aë`ìä½à áÞ<±BL»ùˆr@Æx‹|K‘é¶¡J‰‘Ò7¹™6-8-´žÌK]âÀ°vq>„à8‹îãg–1Ù î;†ôh“øí Á¯ð7‰ú‚²x­i=€ø½¸ìшS!˜‡sîöxßa©öOÈGÙEJ MüFõ|Û0úI"ØŽI„X54Ü9Ü»™—Â\’]ƒ³.Ãy·©ù{bR—1(™×4¨&$ *¾` Ý@HipC»ÅÍ‹ »€6l‚’K€ð”ì÷$É,\’X<Î< ·K‹M·T©‚ƒÁÒ.D‰±áãs,%€—±ùÀ¼ÆíZÊgJYÀg,Äi$‹¿h©hQÞÐHïe$‹ê'adí~ lö‹XñCöÅ^€³<± ?%¶¸xHj´&n÷0 dp7ïüö¿¶øµ%Ý.  'Qð•ÀÁ~\;<˜Q›ÌÒàAt04 ŽÜN`Äñ›c±va#“ô¸m˜3YÁ1Ýñ (HQ¹$™òŒÚcéhLØñ˜½¬_ÜnžE‰;>D¹eìC»K‹5î%X>”¤€d Ì&G¥1sqš¨]B#ˆös¶ñbL8—7fõÀ!ˆÌ8³»Ú÷s%™°Ôë±Ìº’7›Çô&ü ‹¿£D»ÃÈÙÉ›¤†o0ûµÜ·˜ÇÕ°„¡p`I‚’AÔk&FY&ð/©pDfìÜÿ›â<˜;°¼™$ÈvÒÒeËP62‹È!-h0"Ú µä y"Ûö¹x!ï‚K H;÷·X;‰7?®#^ßÐm‰‹ËNÍï´ïØ]÷ÀÞæÆÌÏÁØžÿ7bnLÌDü…» L&Þò8ËŽÓííè\aC½šA ÇH}˜<–³¿J„*~V1¹ö5s& àp Ü@!ß`y&\ŸPŒ3¸{©Ò8K±‚‘»àÈNóú¢ÎÒÅVÞüI>SÏkndb™mÀ–o,Ü÷‘èS¼–[ •ÝFdÀû@$–n"â#5T••A!ÈÌìåí»YÆøÊe+¢‚´¯S’Ä–a¡Ì\ØH0*ŠÄºL¨L¤ 6‘*fÂÆâß@iR(.Â{;1†g´€Ò >&w<3K‚7d§ñ'Sc,H=Æ‘ä* 4¶rt›‰*#I‚NšñéÆ$Ìì]·$¼ †Ìůl(åHü¹AËóWy/¥ã^ƒ’lÓvÜ96Ü>Ø:”ÉyA&L‡ŽäÈx6Ú4À‰Òr¤3°¼Àå¢÷ßßêg ¢ &ïrÁ›g™6.>•F„‰€tê/ó÷3 ¸.äÙ»s¹qϤÀ‰¼€Ü¾ïì!-‚)Bn{Ü‹Ûyúi}F»OÌ7¬ôßž ÷¼É0÷.‚$’w‚n69Ûß¼z­ µ´â~{žÞ˜Çy¿æd—þÛ1Qæ*IЃr< ¹¼ ôàsæ7· ~$>!`T}aÉ`òKö/í8Cƒ&`7õ‹È$Ú–ðž£L5nîäÞ7¬ûa†s*tõ{ o7ú‹÷·IÛüÉþQë€GšÀ¹$íó’ІÄD”‚DL|ï¼|¤Çi’OÌ8ù »ür0¡‹NïØCs!‰2Ø_L™¿×þUD@Óå>Ö°Ÿ¯óöùŽF!fÁ'Ó¼~w‹ƒ"Ÿ}Å1s;ÜDÆ »þwgaù`™àoêæîo}íÛ‰$Þ@„¤i*kLì'{“ÀÛ¹¼ÏA} A€0ûúÃ4Zwرĩ˜€¦“&H±>wöŽÑ"mµ¤ò=7žø ìäK;úý{ñ‡Ú|R/=®uÒ |¿XçÑ3&,þ…§yÀÞßõ$qØ]lj(‹zQ©òI呤À‘xÁÜ|;W~ ·l4Yà–>‘Ȇçvv è'1¶‚¤ŸaîFa'k ï»cxäöm¢ø‚ ù½y—žÅ˜‡åŽ&2nFƒôõZgÜÌÄnÐå™™å¤3mýÍn ݰ\I‹ÇŽÒxsÁäâ-˜Fî$È1¡‰ûÆ÷Û‚ñ}Ø8kȿЅ,Ö»ÉsíÁùoÛ”.µÀ±Ð¢5/¬M´à˜Ú9ݘm¹k°wi—ÀýYŒ‘þ„ˆ¸ç•¡£š?tѹˆ$èÌð«—ú;{AhÏë‚.Ó"üÁì8¹¸ãR¿ì ‚>Éü:ƒâ#¬gÿå¹8l‘Ú/&?@İ@$–@Û9k8Âi&S¦êy)FXþ,ä?.¼Ujó]@ åBÈ›•‹e 4 EÌž+baÉf®ükÙñT‚ X€'°wÚY›ëÿõj¥’}ó¶}Á´o¨áÃ1†¹¿ À‡r^mbø® ¶©hr–)iÚ?€ è Ðäâu“Øß}¸'‰ù?§îÁŸöÅnê6³÷kÁˆ?òáçl£q¨¸‰0$L'I˜ÜÆÜ@Ã{½çqÍ€ün\ò€,Aâ_mÀq<’’“‚í{ÁH÷‹_‰oIØÎüoúâîð »‚6ÝÌõas¹3 u&Ð/ål{‘¯Ì‹Á#üýÿŒY‹á˜µœéÄîZè` ?*ÉÌÀ÷ö1b"°¸ <Ž9gŸhÚnã ¿âmˆ¹úž6Ø¡¡s}`LÕ6µ„À˜Ø^\—Ø¿˜³€ÂæÌœïä®KX q"D<Â$@Ð`A¤›ï`EíÜŽ ´–äÌØ¸<1âfÀ±$ö 3ŸãA»ß é²DZ3±$7y‹wí7mÄÃÄíbÛ}Ãü›q‚ä˜v˜!¥ÚHÙÁ €Q22¯`Q:ÚtÛ¹Xoëw·Öå|V.üFê›±›za©0H F¾Éƒ¿ë¨ÚæxœÌ3‡‘ìÒ^?~D=†ÌÌÍÜïôS¾’=FÄ”È2DÖ¿y@< Ký{–»Iý†Ø`ÍÁ'Ô™,Þ‚Û¸8uäÚ/câo-y ÒÜ×ûŽ0ðÌD€!¡ý 6Ñ Ae$zÀùŸx™i¾¼(hú\mfì,îdÎ %È»¸ °çØ@ÙÉŒ17Êm>Ò­›Æ„fúD“nÙ÷üÃàÀxÇÐ’X bûȱØ‘} ·¿´€d‚@¿èt©" £ó‹KOq‰ø™€–a ^Û¼ÙÌO§HòÓ¯º»ìm{ûpm¹3°xá„\ŽCF ;L0ߘ`òEø‡ÄIR ‘wõ'ëm i}w ȵ¢[Þ{ï°s¸€6 Ä;í>¤»Û&Ñx m'y7™€nM¯6'oäÃlð{€/…v9õm¸¹qȳ¸}ðâdÞ.~›Eþ—ˆ>ý¦,nl,Âä7;í‚U‚@ùçF¤NÝÅ­2uŸÏÏëú›*Í·"w—#p$‚;¹8b½N3é#Mó0/ÚÃo¯‹\úÿ?c€áDpÍõ®aƒ@~øp!ÛL*b ÑDÁ1"Æm;ÌìÒóþ.'øðØ—Ôa÷‰>‚óÄHl( Pï Àü…Œo1¤DÙÙ÷ذ‘ÝŒµÇå –¸iƒ°v»m·«áÀí'ç $‘¬{Ç}Á‰¸¸ƒ¸üïnþ˜“Ã]É!,Hgû[Ü6’. ̧øUbÒDo~ܽþ¿Îþ˜R'ÔE›³o°þœ²BàdIÜ’¡¾×Îâ Ø\ûÈn×pÅï†r³´—d¼ÌŹÚ\͵•Z”§Ò`’cE@ˆ'ÔI& Éž. {;~Å·œG$‰fLÁ£± \¸½£Ì`A #ýâbÃø‡þl'Ú8Ài ³–ƒfÄH-`lÐÏv±õ01ð‰™v˜ zE·¾‘®Ýæ?x ÀÏ –“õNþO ݦärϹǣC!öí²$Lød†„[poã…P|™ûïÞñÎØ ÆìvìXÚ ‰Ýá¶ÇÔÃû(²w 1ÿñÖ$à>š@Á[ù<§ÿM6!<ì É›aFþ§çy7¹ro—ž<ËhÎ|µ!n ­2•¤D…dJW òˆZ—ARU õXÄ-3À<=¡ÙØØnØö©"M¶`B¬ j}¥Ë;0hcáYÁõNuͿƉöˆ‹GcÄÛ‚ŸÃì×ÅJbAƒC\Bƒ‘¼Ý˜¸ß i 3”¤Žð3¤wˆ›&,5Ò3=Ä·-7.ÝîÇ®ÓÜ)ËÙÈ6÷{â ’LÎXXH°í©ÊL›Û€Þ¤I,ä‰>›rí‚î @ L9˜Þp@-` ÌwƒõŒÑ3o¡1‡pvÓÛÜg,.}¤12ìI±emmä¤H°“˜¦ÀDùk‘`{[CbœI‰öw-Ã9ÞçÓþX„0 ƒ©ÆðNÄåÄ>p‘éLÁô¢ñ$Î[Z`ÚÂ:ΜÛùüÙç $4› v0±{žÐàr%p 6:‹¦o]ûÇ’ÞíèôŸÛäâCvµŸŽXs¶r¯ä@ ‘"ãHIA¸Ð ÀgÜ~¦ZÎ0ËKgÈöà’&,Øs‰!(G¥^$z´h=ô2Ûƒ´_Ò;’ÍÏ»à«ÚÉ`gdŸ˜0æÄÈ0©ßÖ³À¹ë&{DÀ#X7 &{Dr4½õ{þ›3nᕦìD>Ì!÷³¶Ä6´ï$‰'ß¹¶‚ ûsôß Þw†áÃ\óäEÇk\‘g|\€&I;l­Ìí6ôûñ&A¿ÕÞ`ð[œôÜ—"YËd;2ű@]­xX 2F½ö¼Fljþg³ÿ$Am°ÝÄZM®biö p!6Оúè„\“m öÔñ8a òÏ<6#°†{wÚîl¸í0)„E‚•iØÏȃ±×Ø~#Iþsx}ÏÌÚÐþkæ {íÞ¬ÂA§áè 7\´û“ î#>þþÁïï¿wÛKùgþL}D³Km–d)P;lo˜$F÷=dÞß™÷'üi,-€Kƒ´±,6»‡ ö—–Û>ƒcÿ¦–ÿÄüçùü8SG¬ y™¤m; ô~X"@;H÷?Ì\MµTØNÃÛ{ÿ û6âòYˆ¹à ø»Î@“h9Žân¦µ‘#õÖvàÛ½ßç¿ô÷陞v‘¹ßy¿½Û¯4¨‰ ÐÙi’#ó LkH$`Mɼ‚Înì ØãZÔ²úÖ¥-n,­n,•)KZÔVµ©D•)J9–¥TeD’¢x–öõççíËÙɹ—b<Ä÷“<œI$“•,&ãÛA;™&FÇ€ÌíÉ;ÿÏé¾/u{öÑ&ó´a›&D‚LH©“ ¹™œ¤ÄüÛnÍÏ/Ï®,üX· À9Ü–Ä&AÐÌÛ)@[c¬ÌÁÖyw}q´ aeÿ –$9—6°xg-/7-‡ªwH¤7 Ð|§‰ÚÜ-ÌN#‡$¬ƒP;³‹>!ú€[½ïxÔÚ?¨OÖ Øï.§gßl@à<ì!ìw'oфˑ)´qs¾u gO~%½¯ôw–oÓØw¶q0æ÷ö–‘ Hõ½À÷6"tØÚ8œ/ÿ]ÿÏl!‰1¸'Ÿ¯ËÕ1§äDïåjxŸÏK¾Ã–ç·<Çó¾ Ø9÷œ¢&c_q Þ.N–Ž b}KØú?æ×Álá¬ÎYç{Ãì$âi°™ü³ ÚFh#x(û‰Ó‡,çˆk˜»ð-yals%˜ZàCËD€—8‚%COÞ &ù´Ò"AÌZq.ÌÆû`v—Ÿ–®\=ÜÜÄÝÃKŰ3𙉠P´Íò u¼Osp!œ=½Ã´ÿiÄ2p`È™‹Ùy%Û®‚ª–@Ê™hJŒl¦ms3x’Hwá \rÌ|°Ö#s1sÛ;D7 Z Ç>ïSì¤äkì¢Ã›iÏ= ñ ÕïÄ)S@“KÉê!(9ˆJI€Iëxu4´ È“y¾þþ¸KnyòCbl{ |Þ9ƒ¦XÃÅUX·¥ FQSJR— ’ E* D ãß÷jû£gÿ_óÅ‚ª‰„¶Yˆшkí6{ [|K§ N‡ñ0?™~˜Ì-‘ú=.l#hŽ ËS ‚ êàÝM¸2ÄÎV]IaÞ]õ$òÇÜq¸m7"`Á²|ì@úU«Ôÿ•ä¥(Û_üp§.€ ®éŠÎ¦ˆàúYßYqÇžGy}Ýþs‰*ŽMÂÛóJ^®¸ÝÖ-é™݅犾?÷z¸ý›¿¯¦/ÔB\5”[`BˆK¸k»Þq&9K ßVŒÀOâ1Û_ý7ýþ¼(¤’\Ý{‰>ÎfN¸>Š;Î@ú_¦ÎUÃ’,õgÅ»ŒîÊ7û¼ÜÄÞàG )¤Á'½¥È°qêõ…’K.^x=Û½±"÷.P6ÃKK•DÂ5q².˜ ˆ7Ú?¯HHH!Ý”vÛÛóã×J $€ûÞ9=öµ­‰4`td-Eo“æñ·pÜOá{“ÞO  ;L¹Ú„G|*”AA êrn$DI \1³€B'£+3â@2ÜþH‚Z1Dqh¦™øV^qÛ £¤0Ù V÷HHåûÀßÁ©<´œÏNTÌ‹Àgÿ—çÚR¤€oÛ¿— p ¤»Àwk9€bÖbçXÃ)ä wâWæNÃþä8@6#¶áøþzÎå£#é>°'M«¸};©;@‡N¤r›±;ò;~øSuñ'ôÚà6ýðQ‡Sæ#×­Sr"}:[ùž4ÒL¾Ûÿî¡l!ö€ …Ë~ö·´a!À%fÄÝBgÖ;{^@“6QÚà¸ßþ› MË™/ÿøÉý `07iJfTs3—²U²Fçù|ä­$3ÉbæòCú–Âÿî%ÌòTw~[F™¿EÕuDˆ²g¶¶=ø]!Ò?ä—?3û– .l$ØmøGýà”’Dü]ÁÕ$AÿÇi›Ó÷ÿ¦Ä0Û‡>àô÷îªè½ÆËO·½æf ÚAšG–ò ÏgÝÿ–Á jHÙÿÅó‹ŒS¶BGñ iM!”f ÛÛ‰Hs/y¶óëìØoŒÉÔÊ€7Ÿ•´¶šðÅ Kn>¤ãû¾"€Žþ[¹ô›z–†ˆÂ)¤r'xïÜvçùº‡®Û6*Ýû¿§§*˜@[€@t}=mßMFÜE$!¸ÿä߯ūR†ÌMÍÁ¾Û).8 Q”/q?˜ÆžÜ¤ÿ§‡vQÜvþÄHr§6v0ð¤öïnlØO!\øŒß]%ÈÐ4Ìï&"‚7g1èHõ·|"I*cc'¹Ÿ¤[u”$˜‘ "'ÜûÓƒ¤rlÛ[å¿óf_óõ Ç×S(Ì[QÝC`6ÛÛŠˆfîÅ€'újùInó†ùiƒ­’®ßÂ}¿ëÛ€~^û6À Û¿ÏÖø3$f‚«)&wA¼‹ëü‡~§ó8PäŽä¾ãœ ”$…2 š…ã½õýx8Žp6›ëe(ZÇoaÀm¶þ?<2€þ?’Ê ¾Z@J™Î­ýãúÁÄ"}ÑÚþƒõÀÊE‹m“ú²?ïþ§€lü9#„ÁÙm*pƒ"¸0n°/ô?Ó‚™Òû³Vü¶ã× €ê£ê@ýc¾&›i2u°L¼J­=­ÿp8²Äˆ2 —$»_Õñ÷výÏä › å ‘2eäïþ/ožý€áH`o )™†üûþÃaëù6ÖÜþ†ÒEÏâ$Þ!±íó÷"ö· ÁÿÚL±³5Á‰ÛPR?ä /%Ìÿ=}ÝÃÙA¨cY &1Ù6ŽòÊ/Åk1±q¸ñÓx÷œOçä?OßQßì¥@û(°Àþ!z¿ ‰þïÊO¿Õ SÀ›ûÿ=p©$»ì¢£¿ëÿÙtango-9.2.5a/doc/src/dance/tango-08-39.jpg0000644023471100065110000023331213034745265014641 00000000000000ÿØÿá.dExifII* †Œ¤¬1 ´(2Ài‡ÔòCanonCanon EOS 400D DIGITAL``Picasa 3.02008:09:28 11:15:03š‚6‚>"ˆ'ˆ@0221FZ‘’ n’v’ ~’ ’ ’†|’ ކ’š 0100 ÿÿ X „ Ô¢¢¢ª¢¤¤¤¤ ¤!²2( 2008:09:28 11:15:032008:09:28 11:15:03Ô¤.dl"t ¸ Ø  ø } ·  P 6€ h  ƒ“p •@’ –Ò —â ˜â  ê ª´Ðà@2@j @p@ v@ü–\ÿÿÿÿƒFt0ÿÿÿÿÿÿÿÿÿÿÿÿÿ‹]dD ìÿ€´™ìÿ¦Ð€´TüÿÿCanon EOS 400D DIGITALFirmware 1.0.4unknown( 0 ° NNÕý;]ü³Õý;øúþúþþBÿÿ Ÿp"=ýPÿÿÿÿ•H0012004€P† E"l> 4c6 Xt3t æc¼NN³†feÿÿ”Œ‘€|(Í++ˆµ·h³²?½³ò43õ´²’ÿþ¹o––º { ƒçç¬ ææ.` XÞPÙ ÜX Ppo––º € 6--¢¹XÞFJ 3Vÿ33œÿ33œÿ33œM¦xþcð”*‹þmÕ'¾þ„‘l õþ KX6ÿÂpVÿÖâà|ÿëºP³ÿ…\ôÿ<Mh6oØsŸê¬ ¹Ú¶€ ë •¸ &Dqð ©â.` ô%ç)¶n!CCðÞlÅ‘!D> 䀨·2PM^Q·U7   €çÎ ²8__ÿÔÿÜ© +1·$^–ÿY&!§ÿKð ÿcÛ ßÿT êÈk¸kÈkŸÿe±ÿÄ6løTýÌk`³PMÿÿαঃaII*r€S;m'F3610312e60dae3117c22a2e665f6bcdbR980100@H(P HHÿØÿàJFIFÿÛC  !"$"$ÿÛCÿÀp "ÿÄÿÄ>!1A"Qaq#2‘B¡±RbÁ$rÑð%34‚²ñÿÄÿÄA!1ÿÚ ?ùµÙ’’ä­Ô‹ ò7¢ì™Ì¨Ü™£9Rª zÛ(J!HKKK–¸$n?ýß–=3EENL…6¢ƒ·Ó 2 äæ‘¤(8Ùñr$uÆ@õx(SÉT$ºˆÎ8¢Ò\V¥¥ì@ u¶;@¢È²m½?3‡MÿÛëb+Û}Ôk[Ò™e¤·‰7¸CÏS«)Ë+\®S$ÚPæÊ)^÷êåb0F‚ÓS©Òeƨ0Ô¦”µqÂ+P;­![¸çÌo‰¹ïAAf;,¡Ô´n› ÍÍ΢pŒ™lÕòC0.¸££WËó …L·(e™ÕHn%R[uˆÌ Ru…9·E½ÎÔªÊU7.ÆLx²°¾;iR–²ob@°ØÚØðã.…N¨Cy¸Í:ó-¶–ÛYPUÊ´ƒµ®FöÀ^K£½QìÆ>hfR*©nJPïM+’À¾Ö;|D2%ÛyO©-­c†·ˆóé~xi–ó‘{=.Qø,O•#[®©EElé7@ ØokïíÌã¦{Ëu×U:W“Ž;P$¶‹µ±½¢f:¥´¦ÂÝ*ÔéEÃ`°ò8“ Õݘ‡»ü•8æë.9rm늺MXg*,šbK·KdßJ×möó=<°¯²W"ÄÌžî]n²ìÏò¢3ŠÓ¤ßÅ{úílPï3 ÌÀ¢ÒãÈà °—\Ш§WØ [ßݦŨƒT—8]êK)IqN† |Z÷ÞĤXßs†)§åfZtÚók€…°PÙcSœ="ÁôÜs¶&;XÌïÑê0èu8­"ž ”¥K䵸n—«ÙI )<¬Aß‘)Oÿ†oHqM©æ$¡ÀO…ÆÕõGMü±#±*õ£Tg\Riò% *ßÛ®¶ý%§¥15˜ôô‚”ÁCú‹ŽmI6Øóål,9šÅ qãÊ”*š‡¹n¥m¾ŸÂP¢< b<= ªÕ2,ê|j-©eÊ[𔥭”“èQˆìÚ»¹QÿZ¿\Mð'DzC5(¥ fÒ’§RR½Gå±ê6æ/ƒ¤TªSeKRŽì•æ³WgUSÖ)«nDx+R®¶ø­#^á%:Ž›¨6;Ø|ÔŸJ½l¶*;2Ì*ÊùÅšÚe*2á:JMµù§Á¢¯*ÊÉ™ÞBœŠ¨±ª‘;'‘RE¼µ=ÇL‰›Eý¢Y[ï%¨Êmù â$€ÚÔÙ ·É·S³µ¶ æì›—ó/€Yym£P²Ó·²ml|í”ëÔ»[›Drä¥D\N4æ¤6´ZÔ|¬’/ÐÛ—`ѳ•W¾gioÈeHe °’Ò›mqÒæøÎ4tv•›nš ó8¨Œñ$Æ>'cëAin°9Œ*»ìn#šä¨K׿WnsÏÓ sÎdVH^Z¨Ce)uÙ/©×³„$£IÌN|úl:[™*æ,à 9H‡Äg_ n)Ô¶>äkŽWÆ™VÌ=ƒÔ¤¿Q®eš¡¨ÈZxÒ¥­–Ô³¹: Sså¶#ÿŽ!F”†rÝ-ÈÔˆëpG%ÝJ·R†ê#Uýl:czѧTirMjlxõX¬èëOî…%@>ûŽFÇäÈŒU*±Ø˜üx°ÁZ[©R’Bˆ$r@ÔŒJvSÌÛX±·ÐE¬—Þ|¯€24Øñ_yR¡÷Ä©!!v_{Ž·å€Ô»$‡¶*Ó›Yº¥&;6äP²G¶Ø­{4eÚtžãÆÞ¨ pR¡{ÿQä?\gTÉt䩨h†b¶â–Z säp@'Êö#Öøâ¤í_ñ}æ¦ÛŒ–XP)Kê¸*;|Ê·1Ì[Á|îj““5Uè’êÁ,.$E­½#k}ðÒ&a¡Wó3f™RfA•Æød¬@ؤ‹‰?LAÿ\5–ªÔ7¢¾9¦2’~ŠÔ¶?P{Yz£[%1[yE+}çQàͰÄÀË=Uéù^$4JkS/¸PªÛ\›¦˜èsãJ¥SÛù,‡’«ôl¤ùþX¶öŲ̈Ð(©UAHqj{‚›€«®C®:Õh=ß,@§ÕYa©1VÛ¹©Ãsºvè/¹ó¶(Æéóß®öÃêeYµ®{/ ¸Ûì/JTunGüöÃ.ÏrLìÉK–úHak ñ“¨ïp|·Äæl¢TrµmÚlÒíYHZy-l¡î1 ¦Ž^h†:ô½ÆF…^ÖUö8)Mº…‡’JIIñ#ë…I<7.9¤íƒ¤%´¾HH-¤íÔØ_Ñ B‚JNÀFþG×"Ÿ* ëLÄiN¼´””!Jüºa{N*Åž2ƒjæFÇé‹þϳU)5!£ÍY‡XP*sì,J4cgz7`Sè2j1ÝS©jC ³¨º„'˜*6± ¿/¾3ÿÙÆª¢¸–¬_nˆë­ƒÔ‡Z$oÖ×ß×Gö¦¢ŽìJ>XuÒëAu $¥*ÚêI#{t¶1,½˜«9N½.­Hy¦–Ó‘ÝHjè(Y¹E!p-cÓ’Õ rEkˆ´¤$#]¹âWöˆ‚–²åî+N,¾¥Y'vî›}ô¤®#)ݨÖ#HvC¡¼óŠÔ¢J€'ÎÀà\É›ëY½¦¶x,-.0ËMéJU{S±êqd¢)âJÍÿ<{Ä^•u>Xë= n[É"Å+)#×>ÃÑVÒœâ 8ƒÐ¤õýF4,(o*K®&ö\–ÔØöIMÿúç$ÃŽý¨øN© ¾Î‚6ð’AÀq¤¢NZz;W㔸-Îêlþ€ãŒ°©ÔÕ:E‹.ÆGS¾ßž ³î%Ùl6>nôÎÞ†÷ü·ú`>ÕQº m%Ÿ‰J[K‰Øjp¨ÛÎÁ?|0ÉòZ&¡ZžWÀˆR®ÖF… ½I$za'j }Š:<à†çT%.¢ë)7á%CJôJF'DBâõü¶ê"ÔyÁáÝ'Òýp•¥Iç¾ ˆåŽŸ–#é‹ ä9‰ÆO*K‹:Ê›¶àùn°»°Z„I¹>Kr&FŽód·ãp ¶U‰ßÏçÉʧRXä>¶•wä¶-©“p¥u\œsèmÙ+›Ùý":VØRÙãªä~5u÷ÆûPAâ?H­ŽYmQœ€¢Ô•[Ër/í€bö‰* 4˜Í­†RÐuË€µí‰ZÝV§˜¤-É‘š’òÓ§R‚É¥·°¶,žˆ‡x‚Â÷0D•jq è@?a‚XmQä¶ó±8ÉmZŠ}*·BF:T\KòœxGD]jÔGÊ›ôØñ)q%µ©$!d„¨¶6Çyîjq ½ÂF ´¹9x·¡%˜nëA±½Ôl@ü°¦MÊêo€!”ÆÑüÊn²^ìéé¡´ü*«M-v›$zÛÂ~Ø–lÝhNà„ï†ì%×h3[CŽ”¶¦¤ðSò®ÊR >ÁCîq9û*ËËu40ò~퇘Uï©'˜÷í€2ëš'G‘d¯C‰!\Šo“·“RÉ4¹ m¶õ%—ðx‘vþPz{ci¿ŽS¸;á>³dtÆÌ3ZFž) $Üw¶<ª\gQ?‡€Óc’A&à{O×ÙŠáÔ¸¥¡Ku *)êFÆþ¸5ˆÒ8Ðd8¥HK)m) ¦Ç@$ÛóÀtÉŠaRfF«-<Å—\XÓ© Êaá[JY#À­±(9IÌ¥cùÃÂ)W§,YPŠäMP RP¥m±ØaC¼»L©D}hŽ ¬º¢,”¤øŽýloŒÿ;TZ¯?-½}Ù»5W0ÚJ~ö¿×ÔÓ2d×à¸â–ƒÒB÷Ø&ø”¯¤¸”ð›ä9ȹÄU ÆŒ€U|-G…å}þŸòø6#ž2ŸAþØÐºìÜU\59…4]†ÚYSaEÝíµü‡L~ÎÕÉÕºóÒZKkÔQHÓ¨Ån—òÃÎÆéO¢—Z®6ë%HJCKIºÉ ü,Eö‘˜¦U&Íeæ£!°æ›°’¬yúï×è°E*”ã7d­7ä÷ÁmÑÙe¯…!à¢, H6ÀB,†Æ”–Ô¿Cr=ðÊ32’R#~ªðÚ¥\QPùugÛÙÖœõ2{jq»¶ó|Å­qÓß–57dJÑ¥jB¹X¤Û3ÔêY]×§"ò>k}?LYB¬© µvk˜$pÉ[Hâ,´‹’> ßËÿöÐzâ·,T—W„•€Ü¨.¶¤©F×¶ #‰Wšs¹¥î¸aZ í°U¯kûbŽ¡Z–øŠwÃüºó-VBHSjaMXŽD§c÷¶'c«Ål4§+þ¢ÉQ qsä/Š.34©df`Èp¨±&ÀÈi6ž3öÿó\þ› [g8qc½õ«r@¿‡–ÿ\F2?Ϻ“s{H=*(SÔ´tÜðÔ‹y\ZøÖ²ãzh¡ô-M ¦ÆâÊq7ü“ŒÒcAJSv¹¿å„ø_ ·Mñè„–ß¿á·?ÓÉÜ·PÇfÓÅe¨ lhoý÷$äé,ÃZ“-Ø.´¤„8„›*ý ÿcŒÖ£AGÕ¤%jŒRѤI¤Ç“¼&diLvW² ÷{ròÂ*µyAJ\wOÑ m¹ûc·}¢TÒJtn9\ãð«LsS’5:žgâ‘L$ýì™ ÒÝöÖý1èÉs‡ó§Ô龨¡³Fž^—à›ZÀrúáœhmHÛ¾_‰áI"þÝq:Ó/ZÓ‚ûê½Æ³…-ö 4Ð Rç3{l£Ôâ þ½K4Z㑎·c¸ ikAIÒ¢EñçM©U(q§G†Ûe™m–ã7©!&àC¾Ç¥TY¨~ì“RC±´».BãÜ‹%(NÉJm±¹$“‡™x·ü0¨²”Ã.:âGıQO=ÁÞ÷Æ´DæJSÚeÉeQ©+tƒgwÕkr·Ÿ¾<èt¾1"C¸ë:®“u^‡ßõZcβbÄ’”4à „YŒqF¤wz,¨ °¥)<•騎þØh}:ý3ô%$F <·ÛŽ_ŽÔ’óm  ”¨pÔ«>·6Ç†ŽŠJ¯Ï– Œ^iÀ¤êH#–®LA]QÌe·4Ђ岄$³Þ…('M…Ô*=7šº¢ÊGà 9o„„í†4É’%ÑŒ¦Xsº¯Š¢â,²“adž|úz㘪ˆ°Rì~ÎÛrÄ•ì´.”¾Q̽½Æ€ôp£¥ô$ïó'B¨qÝp)½Mê;í€*Y$¤-æ¤%§¼Ñoõ±tçF§ö}™–øÔäçŽÂÐ’P@ ÖIä,Û­ñP}˜ÒRêœIG5_æ·ÉÁoÁÍTzR¨ð‹/ArA{m*!vµý6ÄÚâËbZž®SåÉl(xˆ)Óõ²T ¸›é.=ðN\g½Of1 P[–!<í†UÅP¢¼Òiê/$n5¢úG¢é‚aæê>ô?t†Ô†ËRa”¥×RzZãånGÌŒQM[œÝ& Pu¤8,¥¡7Ò‘þø–¤²&æ"Ãëâ·!µ´ ­p¤íý°[.Èv‚%ÈRÖóëR–³òÛ–ã©6él-£[2™uFãá­<ÆÛ[óƒÿÙÿí,Photoshop 3.08BIMP Picasa 2.7ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀX„"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ótUQÐqN.:úUCqŽõ›¥ 4|ÁL.¦Rx¬ÿ9å©Dœƒ@îd…׎•†«€@­/´ðAâ³öÊvúа€8éDc2 ŽGJ|\¶qúP®ž8e«À¯Vö⣱`‰Ó$×O¥h7™\eØö4Á½›)` |8i¯FÖ<©ÛÚù²Z¸ :í5ÄÝYÁ 0êh5 .*&çó¦‡hÛlz”Žf€ä@͓֟1ÇJ®OΣ4+ÿ«5RymÏJ’BB94,@­:VóS­,Q¨cÏJz¢‘Àbcb“ÌŒ)oJÐ6'+ô¤lŒ…Q ü(T¸Œ€r*¶±'šÙx‰NöªòÀFx  'Ž´ÆuPr Y *qU,NO€%û@è)†ç‘x¨'H3Ðô¦Õ˜Ö‘ß#ª™ÚvçƒÒœ\Œ´Ö‰Z@Þõ8“ŽJ­E+4jJò@é@^ác\±©Íqç!ÝÂöª2”†fäö©T3+ØPÚËŒ¡ê ]Çï‡ÐÖNX7ojÕˆ—U"€-älõn´´Ý¦ŒÈð–-Ô Ñð‡`ñ‰ãµ½œÅRÿ/ Øì3^ÿ¦øgHÒ£ mf¿ïIóÖ¥»óN££´R3Š(\½ÄàWÑÿ´ÛDÐãºH£ŽPÅ~UÆáŠùâö\; fš`P|ìÆ IaòO¸úw¨ÚlpGÒ£ó‰l(äÓh씃Á#¥H§¥Uµ’/›©§M&Þï°ÓP4üç íP«7Fê:Õi®'²Š»ö­Ý 8O޵.FzU¸góiæ€/¬ÀŽ´Ö;LÕ2ϼíàSE.á´õ  Kôô¨ä¹X—¯>‚žÄ@AЬ¸ç4yÍ+nníI#ãÿÕH¡‰Î)% ÌÑ@BùN£56F2j­·=êç– cÚ€ ’á6áy4Ì<™/Àªd¶Tidc­:ÊÐÎÀ*ç&»}3Áº…ʼnh¬·C^‰ðÇJð|>´¹i,gÔä]Ó‡RÈsÐ)é^¥ÅŒy{DxãoLT¶ÉÚ¾…=ƒ²Í!˜b¹›˜¶õ•}câ/xZÂÒa©ÏipBŸÜm3LWËẔÜ\I$H#FrUáA< iÜ åPаÔÕp¬Í´²¥–Ù”ÍUåXóL |µ#57ÅÜÇ­?i$ ÐÁÍ8n œqOòŽ@«+ÛÖ€+Ž)7…ã­=ÀßøSUFM »Žj9GÍW#\SUåq WÔÐ´Æ P¡h8<ö  î™É隊BÀëëV$ùK}jA´¶y4ÅBG8¨ ŽF*æ02qK°H˜8  ñJÒ–D1¾)¢˜ ǵ9~õ'JQÖ€&:TiO’𣱠 Ei0Ðý+>.¢´‡6¤uâ(ÁoZsb¤UÚ•]ÁÎh[m/jAÅ8£ ‘œÑäóOAò徘¤ØwÚ€%DTmÇš¶Ñ ˆxŠŠBíÉâ´cH¡Œ¨?•c}æ#4æ²P_Æ®;&óÇzqu1ð;Px@èh©‹ó÷J(½²hy/9¥2b«Üƒ’=h¾z“Èâ¬)ùr§"²Á<ƒÁô­ \ˆFOÒ€d.›—Z©¸äŒsZPáÇj§p»d u ‹óR,‡Ó = Ímés¸¤]È£<×ÔÚˆ¼1ymÒç´„²€" —Ø×Êö¡^Ø•eôï[f§%±Ê9w¤ÕÀúÆY"Ž&y09.x¯:ñî£à›­ò æ³kãòó ~ÜüÍytþ.¿–ÜHTv-\î¡z× X“ž´’„o$2(1áTsVbF Ž¢,xSÓŠ 2$r{ ®±–mÆ®J˜‰›M2ÕAVÜ8;óµy¡crù|Š»nƒc0«*H¤f€$8æ«Íû×À °ÊÁŒri‘ÀÊ>aÉë@ ‰B°#Œu¡[t¸Çz¹¶üäUÁb |«ÍRŒç éWaP[¢;VU¸­›9Æ=(H:àŽë¥ÒÊ6kÒÝ‹ò+¥Ó­Óž)ØèVÈÅHà× ZB±Â¼ × ¢Œ¯zïmœ< ECB Œ‘X:Æœ†6aÐ×ATu-¿f âžG®Ù*±ïÍq×ÊmÜ££.FFF+èßìû;› Fñ2ò ŠðÿXÏe­Ëk(ù"‰½Pò*“Çåœ WMá]B}.ᤇi.»N{Ö½›\\ÅctŒ~5½m`öm2~ò7Úpx¦ hþЈÌWjg’EK®øKìÖæTÃ(î+¶ÑâŽ-Ñ"'”§R2jkè–kãaPÿ*›â¿Ù›˜ôàãÓé~{ˆƒªvêj•º/Û šõ (Ö;8•FÐhl4Õü%$™ GŽ„t®S²(åqŒWÑÄ“Dñ¸Ê°Áã>%·X®%±4&ž\G·>•SÊÊ}kNð˜Œb¨¾DY¨ íFW`°+š…Ž=)®Pžâ—QJ dcMߴЮT…??`Ûš‰›r®=jÒ ŽÙ  ‹¨ü©³ØôÅ*¦F>¦¯_[ëÍW‹€O#½U1‘¼zô«š~~d=©#9éSX¨óIõ  {išWVe#¸85ÙhÞ<Ô4¡pν1#n­qAx•Ëìgð¤[âÝëÊ~Ñ&P•GW˜Þ82¶ßZÙ2³g==+牛ëMQ³ŽjkSv7}© }jÞ–£í Ç8  ò|£Ž½ª«!\Ôóš±r péG–¦ æ€*àívëÅcO'Çzèü°ceµssF|ÖC×4 læ®Yɺ\U(ñ“V,¢ÿHSûç“ÍH‘ôrpjs÷éDª­·aäRêPEEubÜ"¬ÛÆví#š‘áÌl8äPDy~•ÐŽ€’:Ô‘Gó0Î0j-Z2äÐ8T Eh¬|EV[sVÈÁ=+J5Êžh±L¥)ÌÄzV£®=«(ó+¿et`pÊpEuIã]I,M²ÝÊ"Æ6ï8®%N3éOÞpE]¾Ô$¸v.ÙÍcÝÇÍL[9Zàü¸ '(F*»©-Ò­[wæ‘Ôn4YTçëV#ˆ·áMæέÀ2h¼¤ÆãŠ<Þ1ƒV'QæT>Päö 2wdõ py©Ö0¨IŠfÒùÁÀ  ¢äUiÆÕ…Ê`TrÇ4õ­!Íg¨Á­†úÐyŽ&uÇz‡y^*ÍÂ~ù¸ëPð Ë7*xF™ñžõ"}h—î]ÀsTOªèqН5¸9a@éW–¤#Šrýê`,‡¥5M:N¼ÓW¤¨G: wÌ}¾”ä†4ži>@Ý8¥Tç’*C¨ÞiÇÊ5º™çQ$l@Æ÷«–ÙŒóÉ g·†)ÉnDÓ§‘‹p´n(àP{(Üh§Ù< (c#Ÿz£x1&;Žjð  dÔBgçwcŠÉprjhY”cʤ¼j*vŒúñRéu¦= -Ô%nDr ñÎJ­&<ä{ö«B7eû¦”¯ð˜úŒP,ÿ•Z•CFÇÚ¡Š #lÅYÈÆÚ@c^&Èzšt1ì³b@ç¥XÔ¢b±àqÒš*I”À‰ó¶Õ\“PÛX±ùØI­”·fûË€82ÂPh!6‘S›T'q•™W¡éL7‹Ïz@H±,| TÞb…Á VLº$àãÞª5Ó¹ÈcLŠÞXÞb ëJ/'™kމäÎA5z)œcæ&DsF’•{ر˜`×36rs[vs2cšïôÙÂà×_§j‚5œŠó =D®9­¸5P­M€ôVÕ¡Ϲ¬SWÞ„©é\ój¤©ù«>[âùù¸¢Àt:“Oµ-èGQ\O޼Emâ Q%·–(ã –êÜ“Uµ9–͜޹‰¦ÜsM Ôn­´«‘Ûšìež'¸Y‘÷»®Ys\;?ÌG­kØHUT³|§LZð׌mí¬’Òø¶„uãÐÕ½kÆÖŸc’ Í+©Rì0y˜ª04×bHù+³þÉU÷qü«Òü?¯[\éŠ&™â|Ǩ¯-±IÉÅhÚ_yJ0æ‹ì:†¹kolÆ)C¹c ¯(×®>Ñ+Ži_S/˚ʚa*å³B@b\ƪåHÍf²åYSÒ·fH›¯J͘B 00¤vˆÊMEæ4‡ ¤g½hº¤ŽsQ¼jª&˜í Ã×½8ª6(>µb7‹®MXUˆrñ¤YQ°®09j•8©ž4<äÑhHM»9ÉStLÎEfÄ¡£mÄ©^­Ìÿ±M[u‘Ël×ŠÈØ¡z“ž´è—Ë}ÀV×ÙÔ‚ 1•rƒ@¤³ÞªÜ!‘”qžµ}DŸÜ‡z¸(EØŒ çïn_=s]z¦3Ò¹MPbúO­0*“û¬UÝ'þ?1íT˜/ñ«šA?n\q@ÒŽACÏJ®a“øPÖ„ˆï*çZ”¥eˆåñÏz̾´$y a»Šèg.åÇÖ³Ý y wÊrrIü«VÂЪ‡,}jߘ m(síNRÛ¸4ö†f\úÒ%œ‹’@«‘y…rMI‚GS@-ƒI+|¸Å\òXö¦Å I²ºÕ¯/=\Ò"K)øÇ'5"ÚIœð=ªß™ÈÁß§µJ³Ãµ°IÅP{yž*x e^Ôö¼· ©&¤cxÃ)b§¥@öåÁä Õ6ÓvŸ¾ k„^¸5NtÂ; ƒ@ìHË×­7µ8Œg¹¦ãŠ`4ŽqëUn¸^ \ª—|Še¯SŠ{ýêe¯Þ©˜|ôÐ1üªÕ¿ªÌ#ž8 ¹p¦ˆ2¹ÝRÍ’aÉRˆÀÍ@m—¦ÿÖƒ¯ñTþW¹¦ùgMEå®:ôª“`9xBrrjÆC0 Fô­ 3ó VxÏãW¬ÏÌ(÷˜’Æ£0¡ïVgPd&¢Û@€ `v 5/—FÀE*åJæ§q…5šÙ,I4zÒ¦7Rv§ ç­0/^¼S“N—ƒMNhÜ$n­%ÿPØô¬¸zŽkN1˜O\䟥=#$ŒÓU/îjÜ’9zTÖð30T]ÌÇkÔ¼áx‚^_üòõ Ùhl ß|3—V‘&ÔხÕ3…zµ¿Ã A¨Ó"b£Ÿ$šÖ³»´´PEÇj²š­¬µ±ö °3SÁ>Q¥Û¢Sσ´þ΄gÑq[hû×8À§ÒËËà-O¹ Æ}Q«.óáÊM– È{ W#óÝsíUî.šß’›‡±¢ày=ÿ…¼C¦n-ln"ïÀw~k7o”20ê¬0E{SxŽÖ2DÈéîk×ãÑ5Õ ù~og0üiÜG—^L%¶ƒÎ+•iþ¼W[«Ùɦ™¡o™;_ÔW!ùRS i9ï[V²[¼XÉ^k'çë]‚XÛ (Ü—J¦åù½ê!~ï6Ž”ý@-7ÁëPE$àŒ‘ÔÐɨ0R Œš·Û¡REPxFòXôïV­±å.9l˹1OÎï¥@Í´r·8¤3É1ûÖmÃÀÃ!žLƒµc18äÓYÞ5'æééUüÄÎ4ŒFÀ})v9aÃéVRîpÉâ°›®sÅI>z÷ Å•R"m‘ˆô©ÂþéOµ~sô¤_0ê+Ëp]”;}ã[åx¬´]òÈ tcŠ£¸òT‰qëIh&ûR«³c§5¤Ñ7”#¾j¼nVõàÞ€-ùG=Z†ò&KVec‘WwÄ2|Ôüê½ä±V "–ôÍeà ¯–,G¥`jQì¼pOJë­Ù\(n8®[Y]—ò `Q-˜êÖ•Ÿíùã5O9J·¥ø˜ÂsŽh­dGvÞE£HqV™9'­C~¿èô¤jÎÜmëPÉzÏÀP*"£‘HƘn& ŽœÔ‰w"@Í0.{➦€'Œ£§½l<ËufêEs8溫þ†½:v lå*UˆuÅ<§)õ©Q84€çå·fžV$ÍK³yEG9ïW<‚ï*:ñRE”¸ÝÏzÍ“OdBAïZVh¹Ò¾1ŒçŠžÍGÙ†9 ½…R¼Œ i1Z¡HéT¯‡ú,´Ëâš×¥vãq5Ч…aòUžgË žiΔÀëT¯@ ]iðÕ¨ÿ–ŽÄ×ôج Dœžô“k÷ªv7¡Ãv©ÛïšàšzSð9â¤ï@Ù¥*£ŒŠz¯5zì%á¨èÙê)ßjË6ÑɤÞÄu  ;•aY7|ÿ:¹óQK@¯<ÕëAó ¢½]´Èqõ  ³2†Á"›Œö¨.¢•®ϯz;i¼¡ˆÛò  å£dÆy«L»G¡\ã&€"eãšÎ” ç¢JžQ™“ƒÖ€!Å=0§‰lg'·½hÙè÷3Ì…W¾h.QÏ4ÄàWZ|"×;€¤Ž÷¬É¼?yj®ÒFp‡œs@ð¥iÂsúVtjCàõ­(ÕœzP(Æ&sžô®ÍœäTlø—Þ¬àÐСäÓ®Ôˆ©ð  )/?ÕÐjZwojA×­>€Ò¦¶b%ëPгl3*Ðé)¹‡çV¡P-‰ª˜zVcùmN8â€3_ïœÑHä¬ÆÙÏzÎÂŽõ±¯&.½EcmÀÈÍ(Æ1šPÒ*î=)Ûq@ Ž94õQ×<ÓqÏ#ñ§(ù½¨¼”Á÷©òõ5œ?"€7ü8ÓJú­mjHV(ÈäƒXZÔ£ô•+øBŽ“ÉR»˜Ž[°4‚ìrxÍszÙ?»(p rEzχßSÓÓP±ŒùLpÙ=ë†Ö-$gÆ¿8==è@nÛhvfÖ9d²ç9¬éñY=«[ðóW-õ-Z(²!Ú1ɪZ Ôõ4H‰Ï41—· ¸9Íë@›ç-ÁâºËŒÁó\ψÀ]Eñé@¤|¦¬i¹ÑÛª²ò OdvÞD}S¼#¯=…E|¹±¥X?p}ExПŽÔ€äëŠP3׊yšAÁïLã1šqÀ46 D@Ϻ­8¡'Ò¹n7tÍuZVMŠgÒ€-Â}jP84ÖÆû÷©W•=阎Ë}*ŽV¬ìg øš­çˆu)SnKkE.P€Æ:Ð9¬l ò;Õ‹lÀ÷¨¯.‚Äì tÅ?K9±Z¸*•òÿ¢ËÓ¥_^ S¾èòé@"x¿ßè±gf~Q^w c‚Ÿx6E\:Æ«€¾p¦fOͼW+ã˜bÂã©¶«ªdþú³5+›©£y cµ+R×ïsS¸ùóš§'Z¹!äSçøjTûâ¡MÞ¢¤†Qê+>ùq95© ‚ô¬ÝGýuR~t¸¥ÝŠg,Vs^H# ø-½³Nrß*õ¯%úY[-ÆÎ9ÇSõ EáØ ‡}ÔÀIÙ7sù º†œ‚Uò·cåÉ>þÕÏÍzÇsn9õª&èÊ@êÙÇ=¨«Movöp›ÝdÖÆ•u Ó„xÐåG&¸HÝYð õ5ØølÅm*]< °íéH OÁí©ZI{§ãrõN›¿úõÀÉk$r´R)WS‚¤`ƒ^‡©xƒì³ƒe9,ÝUGÿæušþâIÙ˜q»oSøÐ€çMºó¶ÑúÓ“ì+'Ýó¿5ZùÙX«!>µ^)Ö5=GéLŠÁ¬åA¶PONy­KíR 56ÚFŒçƒžÕÍé û«›±’P`LиvÜbzÐÖfœ’ÿ+J·¥jn×$¥™XciäVP²ÈUXûŸJsÊ" }¥ò{-túVŸud÷1.àuÇCøVK´8ãŠét-:mU~·n­G«øWRÑK<ê¯äH‡¥ 8·éGëWX€š­*í¼ úö«„(Sð mðWjHq³šŽû;1Ú€3"¤Š`âž(ÀqV¬Wt⪎•wLæzÕ¹cÀëHŸñêÄúSîW+À¨ÆE³R6Aóš)_%ºÑL ¾"ˆ„f°”ví]F½aSŽõÍ…ÇjhP  ­>‚=¨r:šP0xÍS‰ÁPY>ñÏÔD`ÔҜƚFFq@Kl¾…¿Ú®ÏQ\ÚœŽâ¸{¶d>Œ+»ºùìXÿ³š@W¶Ý d6ä#RJÍg>ÔÍ@n^9楱QƒÜÕ)÷‡|Õû¸¾´ÀŠxó)úÓÑp6âŸ*þôQ´¡9=(ÔKÆjìXõªv‘}¢EU ÆIàU»ÝšYa*Š÷Nµ -#øU¨äî ¬‰5‹hœFlÆx'÷‡¡«q_DöÌSÙ¹§ö¶Hÿw#)õ ž/ÖìdÛo¨Ü Çð¹ªÚ„ÂäÛ2[Ãô®z[ÿ1ŽW‘ë@2ø¯X¾WŠæþêHØä«ÊH'éN’í]sŽq\ˆ¾(ÙPVÕ¥ Ž”Xî?J¯$Ç©¬/í9j3¨ÈM05d“ƒÅgÈÀHzÔ+¨ ÔóNs—<õ ‘ŽÂy­m53Àd-Ô0íXìÙŒ]r\¹Ó&ž-vlCŒn«y1Û;*( Œ`TF1Êç<՛߸ó“×iänãE`N¦éÀ¤îÃU‡ò.>•œB'Œr€.¸ùOÒ£^‹N‘Õ³°Ms·*´ƒ+e㎆€-ëC„¬CÅ!KíªWiÏ"šHÈ$ƒLü)£Œà}iü1ïHV€"“tÍ61—)ä}iï(¯µæÍ>•bhn¢‘FJ·ž¦[X•z*åÄ_b²7L7á¶…O­Hõ«kNdœ°0#†“{µs:µüš¼_eŒ4x] ÷5U×YÒH!F‰@ùØƲšÞÐ ·Ä² ýÚž€ûÓ@{‡¼I Í„1L‚ÆB‡ÌBpãŒzʵšìJ.–I3£Œæ¼Ê]r}QLœ$¨ÙŒqé^à-BZÇÈ–`gC€¹ù¿ VmKAžÃs˜Û`ý+íqm&A-z¢ÚÜÃq™Àm½G½r^$ÑÚ=<ÜÛ‚ÐAÿdP€àmC¥¿\ƒÓÚ¹Ílæè“ž•»k#yÂÏB+;UÓÞ[Ì&HnoJ`sèSO·;gF÷­5Óí¡̹ÉÇ!icÒÖáÔÙ¾ç”náL¹èÿ²)·K›7Ï¥:) +‚¬GJY×ý þ”€ä6àœÒc4æûÙS1íM méÍ;Ô¬>´Úê´ €úV :|÷)Œç]k5µ˜Ig¯4e‡È¼w©W•ª7—YA¾yŒ÷êk=FN8§¼Rm£ôª6ºŒW3}£iPÜ] l¥(b€0çR¶çƒ‘Ï"®id!ÔsKª xIàTZHÙcë@ Æ«^ŸÜIô©¨nÿÔÉߊäÇqJE4½E)'™¦𥍀!w U=C˜3@Öøój^ UX?Ö ·/'Š”±jXÀT'€£5,dÖ·ÆÎ:Vf¢35h[¾G­QÔ‡ï±í@ (ÉôvÎŧ̎Œwõ©´=*]Rí‘ØÑKHÇ ·ö@möÄ@ì;(%ónÃä!@ÈúVUå´Åâ·õ9Û¬mr£Ö¹÷Žf# ôõ Fžb3ã#ßÖ˜–m½ŠòGzV•ß:ÐK²¢Ž˜>ÔUÕãÜ3À5gNÖd´GRÙR1ІýÇ—œu¬´r’Ít×÷p@,ÍÂÉ­©®.íì·¼f>8ÈÅgiK%ª ¢›K )ÅiÜÇqJà”'Šå®æ’áË3ƒU–6ÎljZ;YÛ$ûþb~aŽcîÁóõ  ;Ù ­ÀáÎ[=êÅÃÅ,j‰“!è³c$TdŸÖ¶mã6ñùÓ‘¿ER¿•¬!Kpxü»J­b~Ðì×^”—A.n|Ìn÷=)#­'U@M–¥ua²XØnSȯ[Ñn`ñ‡‡¼«´ ï±õö¯Iã™W rýMušMé©fæu‡©Hx-õ4˜¾%ðôvzì±Ú2¼ ýàÙ¬ÙìÚ8ÉÜ z¨šMöˆ`±„Ãp§–a’O¡5ÀÞnFhÝJ²ñÍ!^sQ^ÝñV" ¥A|>LS8¼RøÑŠrõ<Ð¥_Óqçôª>•{M¾úÐ¥ã¸ü»µ-䊫ó0Ï BT8-éH ®ï_ŠF?1æŠ`oë‹þ‰ŸC\Æx#Öjë›År}M!éžh+JFFrjH­älð@÷Ž4ºUø´öœHŸBjì倜®G¨äPsòæ”ñ4â?zsLnx  -Ÿ =AÞïߦƒÿL뀋†"º+`Úéqì ¶ÜhkO•ZÜdŒŠ¾dM§5çVþ%’ßpXWž¢´ ñˆ-‰ À=ÁéJÀt‘²Xm ü¸­]µÍiw±]ß,±­t›±ô  z„Y³|úW<‘ÆEt×_5³ŒõÍ¡§j˼UVmµ%™qÉ'©n”H= 9HXÆ;SIKI P@ª·‚EzñÅó+dŽ1Ålø]`¸Õ¢Kˆ¼å쾦€e¥K&š¬Å©ÜO ¬Ý[Y’Þp%0…Çp:î|g=ΧùH¢4™qÂäèkÈ'vg<œzh@]7Fâ`3ËcŸ¥uVr›ÍJÖÞ"D›™ŸÞ¸ˆ Ypx®ŠÆ³qö§VÂQŸâ=¨ÐÑb[:E!8N9Åsž Ó¢xþÛo £ç(ãñ®›A®.#S»yŽN稭=wBûFæ…6ǤÿZ<ƒx?.Þi˸ã“NÔ,äÓõ-¥Áe=GCL‰ÙTœÕÉ­Y9€÷Q\ƒÁ­Ye‘“æ6{UC°æ€));ÇÖ¯HN ¨ñ”qéžµi²Oµ#1ò˜ ¿i¬Þ]Mek3æ(zVyµ!²‚K´?½y0ÔÕÝói'Ò±­š&ãšÚ˜fͪVE®p¸Ï€šFËoÁÈô¬Ër=;Í$ï•J–úøÁlïžJœW 4$ÅËu¦€Õ¾ñÝù ¾Ôé´V^w7\ Ô ÄJz€X{dÓîäM¸c q‘Þµ¬n8f7JÅÎ_hèM[œ9ºG­tJIù… xäÔ’€€Çš•ˆ Ò˜$й߀:ÒùqÞ¦´Ã]ÆŸÊ€;-2&Á$¼¬¯Ë»½VÖu¨ +o¹s8 z“[wVæëF nTAË­y¥ú0h÷e|ç³I¨ì\í<±Éæ³ÄˆcÚ3ÆqŠ|‘LÓÌ@$8«v¶Ñ‰\ nô÷¦VH'),Í Êþ÷ÿ^»] G´[®-šæÏP‚B«å}¸¬ÝÏO[‚—DªÁ“à tú×H–M¤\Gso;Oi8ûç°4€í¼?â õ±u¹C3!ǘSÞ­iúÌ7ÆêÊõUC3`„¢±´¹ ¶¹SÀ+ Ýåü^Õ¯ªip^"O ùS³¸p ©ʵ³hw· î +²Ä¹äŒñ\¯öÔóÞ3JøLA[_´©4Ÿy2È$Þ»•óÖ¹`¨óîh•’fmçó­[)O =«*m1„^t´}?M•ÒáUÉ ž¾”è6rÞGS.âÿžî'Š Æ Cµ¸‹eÂ*Íñ/q]N³¦Çq£‹«qž>oU¤“¿ sŽ´‚¤™vÈÀ‘Á=j!õ¦#ˆá’RxQŸÆ±£¹g“|„ž}kbñ7é2ž3¸\÷ ïŠêìo B‰¼dœ[úy¸ó€Á8ïÛÂé÷"2€pGS]…¥ãiäÈ2h”Õä—PÖ§I  ššÖÄH<‘“š¢’BrY‰­ho˜Y µkÙY%”>EÊ0ü²ÇÒº+elþVÎÚÓÓRßľ0*¢ÝÜ>µÅY^=¦±q¦ÊH*Ûp{Rö­"Ëmžx§é{ƒÞ¢Ô-BÂùbvÍ.Šÿè\žô¦SUnŽ#“>•h·z¥uÊIô _¹$ñš:ÒcôëGoj`)I<úSkxKÈíÃd¿_aë[¶ööÃ`]ÅWïf¨x|+êÈÙÎÎ*¾§s,·Ó&]}ºPeÔÆYHåí6Íï¯á‚0K;Q4xlWGà‹Y'ñ+ç’}07õëi¨ qTÌ“ÃkJ¹RÁ‡~k´Ö­–97:ä•ô®~£1LÄpŸuqR‰§ólaFlÈß1=+†•pF:ç­tš§Ú%v–El# ®nD+.{šh M8¼*ŽXö6§~“âsƒÅP‰ØÄJ9Ü{Th\ÊÒ¸Éoe™€jŒV•©·h¼Ï(Ìëü=ãM†¶’Ly,x«¡K°Î2_øOAþ4ñ4ˆDìŠxU^+OL×K¢ìBªŒª/Y¤Vª±pTäâ«x~Ö w™]üÎÊ£­vú>«¶wöîÁÆGZoÙìµý=¡u]§Üp?Ï“ƒØ“9_3¾‚žÚŒvÒ„…ÛüT€¨4Kˆ¼Èä]:ŠÎ»±”¾Ì`ÿ*ÑŸÄÌò¶ã‘Ó'½aßk4ØF$ ¦­¦ƒ°6éA`:ŠÄ¸¶h%)µˆéÈ­}:I.!£„Y»šÓ¸°ŠHs¿s×9 5æŽ/¾ÜÓ†¤±DL(wzšv¥£Ì®dP[ڨLj™6ýs@§¾šv%ÜþtØ®aŽ>´Ù!ÚÄö#vi½ÎèÁ¢²ãœ"c4RÑõšÁûŒWIÁæ»®lÜ{W@2xç­tÐÛQ¹In Gj§ï‘Á>•½­Ãi2-¸@bç9ëXÑkic¡>;œ3ôè=«*òäE¸2ni˜ï+Ì_v2sŠžgŠeu›+Ÿ™"³V_Þ0œv­( 23¹§µ06­ì´ÿÌëk"Á8^„ðkïM¹´vŽHÛä8,Ed½Ð¶º2Ú»!®ÓÃ^.·hžßTÚCa@¼G-éU¯îK®Õ"xrM?TüÐH:ú\Z ‘Ö½¯ÄÛ5/[¯•¸ºy…€ç'Ö¼ntòå“b¹Æ1Òš¨%¤9©>µ“æ¶W5£g§I|Ƥã®)A€eÁõ§ÿIV¤údŸ5ÅÈP?„ šŠâòËOPñE²c ¿#ò  ÖÀÁR? Ú.$ðí¨QóÇ/8¬•ñìŽÅa¶en1³¥iéú´ŒÂÞòÄLx*¸ÅtÁ·éù?óÏúVj²„†µ†èg‘Wwò}«r8+Ùm‹HÆ1ÁþTÀ¯,q»H²9WŒ‚9Á¯GðTo{¦g!O  ®GjáeÒÒU.ù.Çšô˜"Ž×B·‚h„q‰Æ=©0,.œóÌ%†pê?ÏÒ_Ä-ôÛXÇÞfÈê@Í;Ão Ô-òƒ;(ÜGs\Ö¿®Ïw{¼j#K'.Î{އ5 y‹¦»Ö ZKið¾R¯cVï´=æªí 9Çf¬˜¤òFz8á¿Æ»=2ö-NÁT`ΣçSÜúþ4À—E¼’Æ4›ïDNÇ_Ozô « í:H’M®F@#Šàm£K+’(6שþèk£¶…lc•â™â™T+pAèj@ó¯[-RXÈùXå dî=9Æ+¸ÖläÕt¹]ŸuÄ\Ž1¸WO"0²õâ©ZíÉ·d¬ê@=ë¨k9vQX—Z|¶ó2:Ÿ­U€íæ¶`¾uµ’0ï0 gÇfçpEåŽN01@•ÙhvQ¥Œ—²c2p‹èq¤_!$ŽG`x‘Ys‡V,k²»UŠ¢ ÙêGJÌ—o˜\ã4i!°¾ phÔ˜Kte\QR^2¼™#T²h$â»ï…Öãí——8ûªWFx®óáÒÇuslz¿"†gâ@¤W,HòÙGBy­¯_ªm<Ö>gæŸïi 2µ¡çD#Æ8îkž“Æ=ë¼»·i†v«Çáø®GÎ1üéÃÛ*Dù~V­M,/*‚:cÚ7…íØlUJåµ-¬¯YHÄm(Þœ‘=µ¼'–sšÚ¶´T £ Ç[Ãömsknvüèä+¡´ÓåŽíä##w<ÒŸÔP´—¸IãÚºOxvÎh ÔW Òʉ¼?wu3¬Q‡,ÇMkÁf¾Ñæy³î½ 7Æ:ŸÙõy¸lÏJã›Qi_s’}i5[Ǿ¿–iÞcŠÍbz irâ÷Ì#hÆ;ÔHwï<ŒÕu$÷©ãp©ŒSzÇS©k{Nºó§ Ì1ÓÖ¸‹VMçÌ'§ktbŸzœûzR¹ýÓ–]£ß5‰y§Bî̫׃Šm¶ KopN}êÔ—!ÓåïØRm ÍÎ×ÇÖ¹Û«w¶™£nHïë]}ÄÂNâGµeFmn§ýòäúš`sÞæŠì?²tÒÙÚŠ.G6Zt®[ìå¤fn?zº‡ÉR=»VBi’Íãi'°  ûÈRO‘$¢õõ¬I¤8ØÇ<ö55ôX]‘“œtªŸ¼›$Ær:‘@ ®@Á ÒùŒÔóQygªÓ—P@¦÷JáóVÞ•g‰L±‰¿IlX¼X}+¦ÓáH-y ‘Ã{Ò•½¶O9¼µÚ éT¥ˆÆqœÖÝÌy•¾p͞¨Ìb¸äÐ(â‘óµIÒ¬ [¥@ÞSàú ½jþE» \çœÖµ¹ómCdàt  o¶,ê"WW'½I†ú Qöö&Sйû–=RË¿æÞêAL‘`•äÒ`g±ãð®yĆåÂ!<çŠÖ»×4í>m²(§¡®oUñR4û´èÌ#Ö„_ˆ#?jYv–˜¬lg]4^/y k}BÊ ´= /#ñ¤ŽÃHÖW2}–ó9È~Vöµ0+·—i¦¥ºgÌ“æ$Õïê¿Øºäs;ª‚vOPx©§Ò옇idIcLI?u…c- 3¬HÎGÖ€=Þé®4Ë«3f ÍÐW- ÎtÝfö唡ˆ™3ÐñÍtúEÆ¡§G$§`TÁ\cšæï­†Ÿ%ÌWĨCsÔö¤)w}-ÕIJ7ÝŸó4Ar`š6Vàš™ìBX\F§Ó4Øt¶“9‘Fæ˜-¤W{K‹6*ñá%@pq×"½&çÏ‹@¶µ•@–I5yì^×´ èfÓÕî#p¤Ïb+Ú­t‰µ]ÆK…Kk¸¶Ë"0ïŽE&~£åÚEoH¡QBþ•æþ(ÒÚ;ùe¶ÚðÉÉÚx­ø§Å¿mž[KdVh\«sŒàö5Å]kw1]€²|½]s‘ô¡ /YiŽìe™JFI5fâú=8ìŽÖ ]6—¥ËªèMuŸ5yέºZLFB‚8÷>¡qµLŒ´˜ö¬›…|!V,¾•jîìÞìÆ—ž1Ú«df*)ú `E º6U¶žÕÐ麋\m,*}â¹ã.\60x±¦4- RZ9ÜcÓ4×i­r— àp2¤ÿ#W®lÒlÆ[ž*¶™LÛÚEócáˆûß\w­]RVX ¸§¯þ4€¯g£Û»4——¦dûÌO'ØW9vtëm^ú}ż˜`XäÞ¶58^k0§-/QÓ5KAÒ™©Çpò£‰¦Ìsƒ@¦±b–Ó1Ǹ¬9Ž8ö®«Ä ¹‘1ˆßgÎ ?1ãµ4Tb§8« T¾à8ÇAR¬JA‘RŽ SúlrÜʱ[FÛ†$þµÛZhI©ÙÏc*jüÑ’q毥Q𖛦ßË<×÷â×ìêW¡zô- i·i§¼›>äÎ6þµ7É.´û›Ÿ*êŽE8!Æ?ýuÙøI7I’°àö¯C}.ÏQ·x.íâp;0ÏëT ðtìd´‘“Ðu\ MzæMBçì¢Ø7–ŒKÿu}kÎõghÃFˆWcœ“ë^¡yk%¼’s‰‚í'Ö¹‹í×$8ÎãóÍ*É|éàåºû{×Y‰¦†UæEEI×)[ÃâÖá‚.xÍliökLØÉcé@\Y¹ô}µ{u—Ë%ÏsYú­Í¬Û±$lsØŠã]äžbyfcÚ´“ÃZ¬ÚKj1Û³Dµ}ñï·®)Ø«CÒ!Ôz\ÇFFMCu¢2ê’Û–ù"9ÿz¹ I$¶˜‚]u tš°„´²ï”ãד@…£YjÅq…'#rÚéâÆÕEª^â$1„=@ªžyòÃ|PÍBåäF,Ùf÷âªéQ³ÏÔsT$™¥rONÕ¡¤¹K€Àã Ó…â;&>CÕÐI¡XλZÆ{ªà×âý*ëIµIl.&[`~tÞH¡·áäm;ObÁY#5´oáiZÆv®Þ YaH'`_ß½k\Þ¥_› Þ”ÝØË¦Cv$ƒP¿pý3]=êi:¶–mïn­®CŽAÇ?Jñû½‹"KŸ•×9­ Üi@Ì÷èK„$ž+Çx£Àšv ïa¸³bJíä§±®&k)c•‘Ñ‘‡Pþ‚}Q4ésg0š#ü:U¬h:¢yz¶‘çÅÿëÓ¸74E:ŠF;W¥{ö©ð·ÃZü 6‰vÖs¿yàyå¾ øsâM»Kb×ëÏŸoó®=ÇQM09Hȯ#‡'ùU ù”¯Ôb¥Žb¦˜ñ]ºà ‘ÛŠÓµ¾pËŸë\ìR–bwzÕÈ.Œ|síH kôi"'`PGÍaâv&·âœ8ÃÄÕ=FÃr {Pp]·•ÔQU£RsEtš~¦gڌ߼5×höޱËq +µ~@F3YéyáͶ·Y%QÎrj¥ÇŠ.5 ï-NÛse"Ò¯ Ü—^IØÇ9 X±Hñõ\ŠÙ¼Õî_MKR+Üõ5…¼–;³š`tDšlíåÝÆ0ÜnE>ûJµ·¹ÛÌ}E`ÂÁIrH´­çfPeo ô  $,Hd?Â8¬©/$’2 67p­¥I ('¦j†ÕB2«»= @À\"ÈHŒÔº•²[°a"°'Œ¯w1‰Ã3ÛÚ³Þw•Ë1æ€4¡¼‰b`A'zWsá_ ÛjÖÉ5î©{†V(Ø }kÍ“©«–³¼2®ÁO¡ L»ÒáÑï„GæPC Ý+BÞ(®.L7r?æ?úõ“snÖWRGæn p  ýêh/‘Úb8ÆAèkg_ÖÒîѾψ‚ý¦®.>`ŽÚ´š“ ÿ,—¢·Bh°–™,6ð#lš7]ë“È­ ?Ó¦gÌOáÇZã4˧*w6ƒ·=¾•ØXÝ(E¡T﹤'¬ÛJÓ›ÌW“–k‚¯Jñš—rKœŸ™³ëõ®ö"$ ì ‘ü4З§=EJ¡ °ûÞ¼™zc§q@ÞÔ4ý7XYuuš6å‡Ü>µßj/Ñì¥Hí®vÀ‘ =«ÉsÎ{‰”ù© vVŒ‚1ê(°ù¯ö;%»Õü»-Ã÷q“øÕaâÈe·i¬™dElHGa^]o³â›Ð ¼û@Üü¨+¬M´é-´«6®s%ÌÍ×jö°Í+Ñj‹ò%ŽHÉtËÃT!Œ@ªK¹Ë61Åj :&„Æ‹Ž9"±5 ¤›ÞàçøPrOµ -Úiͪ^ˆÞP‘çîƒ]ͯ†¢äJ`ןiZ˜·¸ß=²måÜçÿ×^“ xŠÓTµ>TÊ}än¤ÀÁñ5ŠYøb$EÁK@à×1¦Ü ¿·çx®ÓÅQ]jpÚdŒ–uÝ‚OlW·ËÃE<[%C†W"šþ;×yÛê¼d£à6+Ë´ö©xå‘áÏñœ“ë^£{ý‰¨Z2_"ñ’[ŒWŽê‚Ú×Už; Œ¶êß#ôÐΑt!¿[¨å_+iW\uÏ­Y×®òHï‘!l¯È¸Ë ålnüÍ6fHJ Âäžþµ¡癥IksŸ62<±ž‚€,G{4]T”ݪµý¾w^ª›•J«œcœš£—¹r‘ò?½L ú”¦`QNTVlbE'kß{±m“ÔÖ•ž‘ .ó ®àrs@ºÞD“3ìÏÌO@*߈¯,î(ªw>ÓÏÒ­ë7Ö°A$vƒË`F¿ã\Lò–s‚y9  ¸î¬ ¤³bÜ»pyÅv×›äÞ2Ip = ynæõ5zÒíиñïE€öé<9£ëpÜGun¢V\G)ê§±¼föÒãLÔ§±¸e…ʰþµÐé^)Ô- Æ“–Sü-Ít•ž“âÒ·2Èmu"¡wŽé‘K`<ðÈüøâšöÂTýÛ UcE½Ñî^…  ñ"©ªLSŠ`V‘«©"”Ä ƒÈ«Ä%Âmnýë:â# ¥2O¥0&,÷²N}kjÎ0Àg¿­bÚ[;¶ò+vÒ=˜!›ŽÆ'”ÀÌ€ÀÔ]I™W9ïKzÂK‰ñÏMIê(y&Y$á©ÙÇRrk*Æ:ÖŒRn’ï{£ƒ¨^…ÿúÕÑXé¸wÞ„@F3îEií,BŠ«”q ŠÕtUØm0FE\‚ÛqÅYH•O4€,ÔŽek:hí¯Éṳ±®‘6Ðñ²ž„t wG¹]SOŽqÃtqèk@DGJç¼=ÿïj:[pŽÞdcë]qL}(¸VUÉÍR×-ÖûD¹…ùÊV“g éT®2b‘OB¦€<‡JÑ﯄—œXžwQéò\ƒ8^r{Òü8h…Ϋg2†C)È?ZÛñ‡=‚ ›g·Ï rP…;ÏË'b#™ Ê QJ ¬lZ·4ŒŒA¾9ªRÀñÌÒ@Iã$æ€4-ç˜c3«¿i%yý+Ò{}æ ¦1ÊOÞÎ*Ýͼ֋æG*M÷”ò(bËSžÍ÷Dä­ušw&b±\¢ºž+Í£¾ÀÕ—=2*xîÆàÊÔXS—@ÐõÙ —V#’Wâ?ƒV:ƒô;…µp9†Uô£JñLö£ÊfÊ{×Ik­¡pé.3ïKT‰j`>nŽ@dvOÓna¾-¹8ö®ƒÅ>ÿ„rõÞ)L±1ýÚ‘È•ÍÌU†Æ ÜSƒ¸F*¢ª²’Ç9&ŠÝÓü?w¬HÐÆÌ·½Dn>ðö­Ï è—ÖÚڥ݌™€âMËòõ®›áûÅ«ù"ä#Ëf+„8`} z–¹¤}.K„a´ÒçŠMá¾?²Dß[F¨ŒÅNÚàr]²ÝkÕ5‹[ÒåÓ£„ùŒß»Ýë\N«áMCGˆI3@ã©Øý) 1ùsÛÚ¦IÂDäúÔQŒ † —*~fÙìåA<êÑ!?{½@ó3Æ«ž¨3¹ÂvÍ0# ‚OniV0ýéÍ×R´ù$7q@[‚¨ž7ˆå2VŸßÔS‹íN~íiéóÅyoöyþVuñÒµ4˜æ²k«b3æÆDmÛ5ÌÃ"£|­]•¯g‘ç –ýÓÛéHzxî-¥h¤FLœ•"§µ˜ÚÜ$›~ ÷{[ÔRþỗ÷gîñTìm¦Ôn㶆=ò9ã½þ”ÐG43ìX€ö5©å˜­ ·‘é‘÷ «Yiþ³ý뇛w?È{V­â!4¸T%c(ìj@KåB±’4W<’Fv ­q­An¡boAXwÅÂ2³}y8Ö˜šœ÷ŠŽsSTsŠnãH\ãÚ€=GZ±·¹ÅTÜ{SÖVèúÈB±Ÿ£sjr’0ª"v+Œÿõé ››œPC§Êú×›tÞb á[‘ZÒÛéqÛ»Åbb06 dû×-av`ܰÆkRÍ $·S6yžÞ.½½Œ™LÆHãÃZø—Ê” b.›¹ óŠõm2Î×Äú^í.çjpÿc•òŽG¡íš@q2À%‹ô¬ÿì©73($°çµwߨúœR¾š†+¸Ø‰ldêêžþƲà·»+)VS‚¤`ƒEÀãSMó.]‘JžF+^·kf ßÅÏ=ëÔ%†1Ê£$ä+‘ñ&–—¶ÌàéÈÇz~ß0àòjH àáxïQ²4e•‡>”ødh†*€Ø±Þ×(·å'«²´¹U†;x¢då{úë‘ÑÛ|‘Ä»)ÎÇ5×Mo*Z,ùX<ô(?tj@lI2Íd ùgûÅUãÒ¸­O,Eݼd P²Ãé]vžì/:9o”žžü~µ»g˜_3m¼€3ykúÒËòž‡‘RÆü öëL½Xâ¹ažb+•VÇQMï°ìyÀ¶zqSZÛ½Ýä6è>i˜(ú“UÐä)=ÅtÞ³ûo‹ì±sí@“i¥G¢ÙÇi#tŒ-šçõë»Í/Äq_ÆH @ÈõÜסÄ—Êx ¥EgÞX1€ÚÚ.<Ì $ì­Hÿµìɲ—¹•AØ?‡>¾••w·,Î\d·§°®Ž=:ÛK²aáŠòÇ©ük‡Ö¯ ò´`ðNN(*æíäbyÇEZžÒ[ˆcù$e'ï8&ªÁ›!á ÑӠмAsg*‰¤/v×z>‘ãm8¤Ã˹Ûû»˜øt?Ô{òåùMu¾Õ…­âÆï…cǵ&™kþ ñªÏa©Ü¬vñœ¬Ù$J½ˆXèú†œ·2ZÏx‡pügéÚ½óâ>‡/ˆ<5ÞžÔ-Ëw¨ûËùt÷¯•Æ¡v'ï[rëžÔSZgVÔ­îgÍš¼qãGµ-¶¥(8ÝëY$e‰â¥Pâÿe_éQm ·h0Ü}îzÕeµò°Ê~_a\zÉ"•Èú“í·8ÇžøôÍ+Ý[¬Lè IšÓÔ5‹? êwk0†æv· ‚6ÈV#©¯/3JÜ™þ4ÂÌÇ%‰'¹4X Ú†¥-üÅßžè*†sž(üh=ñL…8•˜Œ àu­/ùf3@ÿJµmŸs#ø˜ ¨IÜkOK+«+uwT_Ç­zY«,6û@EˆõÅZ“e¤?fŒä³nbGñSíÙDrÜ7EP«U >lû›Ÿ­H¶Q„1êkϼiª4º¸¶òB¼ýMwÓÝGmfò;U9¯<·ðÍÖ±}5ýû˜a•Ë*ßAMÎZÚ]ê·>M¤Lç¹{šíô_ Zi¬·D\\ŽFGʇØw5§kkŒE¬Kc°O½Y ì1Íd}Ǭ[CŒL‚Æ®Ç 'Oº:Pý*ŒdRž”‘¿cWb!±Y›¶¿Zµ ˜#¾hñ6í+ÆšuòŒ$¿#~uÝ• aÜf¸ÿˆ–ÆM" Äë€çÚº­9¼ÝÖRrZ1ü¨&lUIÔcWËÕ[ƒ…jã<(Æj‘l×£Û]æ&Š@HÆ y¾•ˆ¼yv¹ûè vêO¯Jl;P³{mVèDØ‹ï*•½áHU]7dœê5»MÁgxc\ÚÙÉç¯)±O\ÐE.^F•2ìøÏ¥MscqdŠð¹hòÒzUÈ-JBcilî­gU # ¯zäõ}j[­ˆÊŸ*à0ÅgE«4]T“ë]Möep>½Á¬)ü1p¤ùN¬=úЖڠ“«óéZöúƒ as#B¾²±óìjÌPjVËûËv`;ƒ@펽$@9ºk-j;™âù¾aŠòˆ5»iÜ¡©g¨ìpÑ¿ëE€î|_^@.æ+ʵu6ò$f0¬Ùú×¥iº¼dEsžxæ¸Ïi®ºÄR[í18À>†„ 8Û)h«³ØJ²‘×ÞŠ`;Âz”ZN­ ËÞI)Ë(èÕëóüaÒ–Ú%HŒ­‘”~TýkçÞüS‚›áCW×5vÖòê[û;u¶Êòñ“ÜzWžjº„Ó£I$¬w6'µ.%ÅÌV6"”…-ýÑV¼c§ÛØ\C¡-^÷4ͤ¸ ñRŽH9ªùÁïK»æÍ0&P¦R‡‘G–¡·)ã=é°ýâM8Ž=‰  › 4uã¸8Í4ȹÀüèá2v¨ùX†Íd‘€$°ŽÕU[®?CVmdx¥Ü§àƒH ÓÙI?.zTAœ¡ÁÈìk£Ê\®sŠ>Áöë_%Pׄnæ€9ÿ.e‰K!Øzî¼)lšn“öÇQçÜwþâóšÁÓ,佚;YWk+íeé€:ÕÍKTòô§ŽÓ0Aè‹òŠ©©ê©ë ŠÇÈÞQïUuLG?–:òÌ}M3DÍÕ“#!4j²y—òàp(‰¤¥¤ïÓñ¦øPõ†ëÒ€—ŠJQÈ÷ piHN1N;Ò`” ÊÊô®–ÕÒ]wA÷ïBQ\£åe Ž léÒ˜´û·—iª¾…¯h©w ¼pœÉ÷^ÿ…Wðïˆo4 C͆B±gçJ<;âmG@¹ÞVh{¦îŸJôO+Â^9^t6z‰á®`Âßí¯CõýiÕh÷pøºÍ5BSŽ0ÈéÇœð·©ô4ïÚùše–®ˆ’a¸8ÁÝÕIýEr¾Ñ5ÿë‚ÏÓßç†òPóÓØûõ)-bñ&‹y%WíIóùç(ä7Ó5 yw«$ÞVáך´ÚzÊw7 Wö‹›=bâ9ÁIBŒ=85Øé—âXÁ'Š 8?i o7Ÿ á[¯Ö¹<Øö¯\ñ6›ý¡dÆ?¾9µåW6ÒÚ\”•0AéM«¥´{ö©ØÌ@Æ:×]f¥Q¹JíÚzþuÇé‘´“.Þd2)ïëúW]¯5ÌL„=C@vø·±’láÀÝžjî×H%Þ?{»[‚G¦+-®~Îì¥ï*Pgžâµ¡k‡s;»Æƒ ÃiƒÞ[âM=l¯œÆ#“çT\ü¼ô¬Äož3ê+½×í¢Ôà”}šF»è…=}1\ÖŒ*º•*Ø#)e{5zGÂ+Q.·}tGú˜BøÿëW™–Æð|×­ümõy}Z5ý '°‹"•$g>íHü¾E8€Ôƒ¯Ýl„¢Ÿ›ç7ùäÏÞÎ+{Å7î—ì‘·"¹y$gqÉ,2MRFÎ0‘¨ÇAWD|T0p\QÇÍÒ€+2ñO‚S€ƒÈ=idÇåPg žÔëÞÖÖîÑa•`0sÞ¼âׄ?áñ|¯x°¿ÌðÑIûËøÐ×w êmazœ)<×oã_EãÏÉoS}ó­[ý°:}â’ÑòwåHy©¦†Kyä†hÙ$F*èÃHê EVqIÚ—½…QIKøPÖQŸjZO¥!¥ü)¤ó@Œ0néN‰È˜7½D=iU¶œÐÌÃí6eGQÊýj®¡$ ÊúU«I2¸æ³ï!0ÎÜpÜŠ@oÛ_Ç/FCYZ•×xH#Ž+=XŽ™Í&˜–eXÇu®·ÀR ¯¬²[ļ_A\Êå|±ÐúWE¥\5„cË%[©"“Õ|_à‹]rɯl‚­Äkœâ•ã/ 0³®ÖÒ èkÔ´/Ë*ËwVà†¯4Ö¥ˆë·¦JÄÐæ’’1ÛÞ® ,`g‚jˆá¸äUßwŽ0¸ySÛŠÑѭ⹺n„m¬Y^1+™­¿ ¨k©X ah–ö+ý¡,{5 ‹·+ÓWIu/32Ö& ›.œÆh<ý`)´ß—;åÝ^@¬ó÷ë·Ñ4a{â-&SåGžÿÏó ¯PˆÚ[ÃmÔãsãÔÕKH‹?LÔÕýU¼Û©¤=3YâBÐù)ïŸéRL«yyçI–‚#ˆôcýïð«'26§ÅlJÐzUèaHÇ#šª–ØÓ¶ŒÕòj…ã'¿jš°‹ž•®Õçã(E<Ðã’(ã5Êë~3´Ó¤0Eûûî/EúšÉÓµëÍFç|̺:S°ÁäÔ¨8ª–nd@sÅ_UR+ÅÇw…/æ´¼9r&ðõ¡ÿ¦b³¼Wï ^ýʛ£´aÐ¥Õ$dœU9ˆ;ªÓ÷ªÌ¹é@E¿îþ )ÇÞŠ»‘Ã\EÑòRâ6“êi[V·NÔ¯o!˜ÿS^w.mí‡eˆ~d“]ÄóGK¿—9̘_¦+ϧlÅû£ô¡¹á¸öEsrÝÀ5•3ï™ßÔÖ¶žå|/pË×q±¨):KëAS†¤iXP@¦õ¥à8àÒƒÅ7S‡9âÎ>LÕˆ. é³/÷˜PÈ2†ŸgMkp gfò4ÒYxe¯,’K[ëw”Œ˜Ø‘ŠÂÞ#µŸÎ·„£¡‰ÁÏø×6³É»ãwCœeN+jÓÅ:Å® \™ìã4êÞ×õè,E¶¯dJ±ÚÑÈ:ýGjô¯Ãn ^Y™"âkwço¸¯ð×îµLNwQá‡ÍÃW®hzñ¿\¸Xî‡'†¨`yŸÆ ÿex™u{eÅ®¤ 0Q÷¿1ƒù×;¢Ü2Ä<×Ð>#Ñ-¼_áyô÷Kð7÷$ôúò ;ÁóŽ$¹Eš3‡P„àþbš`>Ø–RÎk‰ñVœ‰q UmÇœW£ë)–Í ¸ ÷¢ÚUÓ?ãQ¾“½bò"í»‹*ñó_¨¦“ÙĤ£F72¢ºDU7«¼cåíØÖMõ›hºža»çjõ…åÅÄ’Mœ1sŽÔÀ×{r/Y !÷gŸÆ·a#í[[# ‘ÜW5læ6PFç“![wnÕ¯oæÆRb™œ £Œbk0 ™e9<Ž ×â "ûTÈîß4ŠëÐûõ×j×÷²£LìèW ʵÃë:Ì÷,韗éùP€Çãs{ŠöƒŒ­¥jƒø„¨JñÅûÃŽ«^ÃðpÇo¢j—3•Tódž¸({é›B©cÐV^¡~"°qÅC©xŽÊ8Û}ÂÂ9&¹;½fKë…X¢a ©#­$€ÁÖ&iõçiE;pÞ³S r)nÎèÚç :æ¶ Ù*c æ¹ã?8Áõ§+K1¹üè{Ù_Nº !&ûý 2È3Ö¨j«u}bÑ–É0úÖ.›©º7‘1Ä€÷ï@ŒrF+Ò|®à y[‘Ò¼¦ €à`æµì/^Úd‘‚)04>4|=YQüY¤Ež3}¿ôÐçù׃‘__xgÄjvÆÖãkn]¬È ׄ|Uøu'„uF¿°›Fº|ÆG>Kà>Þ”âúæÇ­(Æ 5@%¸¤í@ÒŽÔ J 6—½&9 €­ŠÝÿ„Zý¼.šØØmüÕ‹f~l±À?Jë øR÷~ºº·šs¨[Fd(TyoŽJŽÿ+ÁY¿~5jî=¾qó§#é]@Œ.õvK•ÿžÉÈ>žõŒôÍM0ǧ.éÜ™a‘ã€}óEÀóU·Ç'­”À®Ðb6dSÀÏÒ£ŽiIǘØôÍvú^ÞŽå¦1¼ƒ$mÎ}«‰™ÉP *±yeÛ÷Øþ5'½JÇ+žõcwµ0$ˆdóV¯Z8n•=Es /´÷ÍvžðÞ±«¬òØé×FxÂçêx®nx£{à ¯YðÄXô?ÛØ;*˜ò)02o´[Í2O"úŠtä‚søW¬.ˬŽãÖº?xÙõ=^êxÀ‘NÔRk›ÖLŸiL…ÁPO<Ò@dg÷•ì>ˆ.¡˜Z¬@ýMxñQæ¯iðÂø@ —i8<Ÿ¥ nŽíùõªðm9ÇJŠæG“!;÷§Ã *ikÏ @ñ&{ÕP¡sž´Öœ("€4|ÜŽ´¦@{ÖÖµoii$ rküZon<»|¤=Üõ?J`u÷z¬ÊFrÝ”W1q¬ÝÞNcxš8³€婉*É y$欺*·SÛ4—¨h°Þt'ó×ëTôæ—& ~VSÈ­ôBpÜ{S/4{m@’FŠAüIÖ€: 2â6B‘Zé*tÜ3^_pº®ˆû­'71̧"£·ñ¦¡³Mb{r1E€ô˜Ç†î̤ù{~`½Hö©<3 [®®>EÎp;kʵ_ꚥ»[3,P7TA×êi4¯jÚXTI|È—øf‹í,™¨Yx#¥qšwÄ{Y@[Ø&þòò+£·ñ—z¹†î"} Á¤+®ŠôÙIÆXŠí±Æ}«‹ñD»±œí×Ou©AmgILòM0.Ʀt‘cå”VDp´ò9ÉÜ?ét«²é-råZB3Œt¬RÂGfÇ~A¤,0ܧå=ª\e{U¢˜;ãëÜTRaÈÁ  Ná-biŒÞ°ôíYZàÊ_‚jÝî™-ç¹År©½Þeú¤€ô϶DÓ ƒVø:ýì{^y¥ê+ž\ìJg©5Ò5í½¼ašEÛÛiÍ~+ÎMRº¿kÉM¥»áúÇʹ›Ýyä_.U÷5>™©Á„/×½ :ë?ôDQ Æ(Õ´ë}z %Ç2ýÖª„jãåjº’æ€9™|+¬Ã!HŠH˜63Euëq"®{Ñ@A’OZµùví!Î[Uᤔ*Œšžâ@Ïå¯Ý^*€„*\N”ÔlU’»†(ž3Î)>½)ï…l 3“ÀÅ&3N“ˆO½(½¢Ún²šy,ÌÑ´6:晋»·­]Ãz†¹2¥´XRp]º ]VÌ­Äq,{Jì4¿7„a[!§‰gÀ;·qH áÍ·–×ZŠymÔÆœŠ«âO†SèúrßYܸÞÂa–¶æñ®»«Å¶8`€uäÕÏ kÚžªF¨ÒMjã »r¾)j40z†E=ÎðˆÎÄôs_L]hþ×"óe³·lr i®#[´ð·‡ÜÏ ÛÆÃ²Œš.9¦Á=¯‡ \DQÝó´÷®î6X!b¸:þ!¿úõßÞëßèÂæ5ÂnÓ5Çê6Æ-:AŽ!»aŸfÊšΜ3á-AA*b±û{Võ’mð%Ûž7Ý(€¬x «|çÒžzT ~|úÕ€2´À`àâÚš4ðh¾ÔŠy"Ï4ÕûÆ€J´†­Ž(Ì8©t™|›¦VYCøÓ#ŠŽ"c›wLiùSýrc•52¼~5ví6ß»»*‡šŸ»™”úÐ…´¯ ÂXܤªr¤W¦xkÅÆxÕ\”¹N¿_Q^^£"§ŽV‚U—s §9SƒŠúŸÂÞ#Qu›løä7õé|E¤4r˪Y/'þ>#ÿÚÖ¼«Áú×ÚàŠhÛlñœƒžr+Û4ýI5 D¸\nÆ$O~õ@1ô;„™2+Ç ‡um?]‚ u(ŠãiùsêG©ʶÞËû+T?øöŸæý“ÜUÿi)¯xBêבW͈ú:ò?Ãñ *ø‘¤'ögö¤ /•(Ú}U…pZæHBœó(üñ^³ªF5…mqqÕaNr8¯µóa@lE»€þuH—ìq¡Ú¯Í×äÖ¦˜ímnb˜Ãg5’Ûïä‹oÉ;)éÂàSìžt™àg¡òß¹”¹¨À'³Œ0ŒÈIëÜ óEzØÙ ¹# z|r Ÿ1Æ@@zW™ø²êIõ£º5RhÆ}è@`)û‡ð¯Fðå¼–¿®ncq¶i›x¡è?­yÊŸ•}z宓ªOð÷M·²†3±™$NŒNN4Ø øqö)a¾7¢9¥GZPX¨ö®’ïXÑbvÁÜÌȳíä±ðöö0H–Ó*0€ 3cž~µ“¦ëWšÃ\[+Ddˆó ÛsÎigQÔ­¦·v_\W= Änšéµ0é»Ô+àG¯AùW-Åpó: GŒŒZµÆ3šU'°ý*(dLïŽ qV’3ç‚yV~TXÓs\þ¹¦2¿Úá?Å´~µÑÈ6: êIcOd¤}h™Ó/ãÉÉÚ㎕ÐÛË¿¡§éz`‚Ç]#\°&=˜(Õ´{¯]ªÉ–·—˜¤õþô«¦êX\¤‘“ÁÍz½Æâï˧_ƲÃ:l‘üõ¯¶]G5ÒøT“Nº\ã4šÈüsàû¯xŽm:l¼ óÛLGúÄíøŽ†¹ŽõõgŒ<;gñÃ&Ô²¥ü#}¬Çø[Ðûõòþ¥§]é:„ö7Ð47¶×FþµRw—NÔfŠM´Àm'­;÷£ÌsZ:šú¦§IŒ|Ò·¢Š¡ßêÒ/5Ôãi»›ƒþÂÿõé~îswce¢ØÀVÖÞu¸¸”®í*Z¼Þ0Ô„3é°ÜÅRä1Ç#Ôf©ÝêP¥D -T•Ê/SX–>aR€aɤi£ëš~޶»-Ì›ÏÎíÉaÜŠÁø­'…nÖÞûF ¦ò¤*dn\u#×8«^×4Ùõ‹k{«(¤¾O1ÿ‡ÓÂkZWصËÈLÞ`Y™VPx<ñB#Ì2¹·0è}jÅœêѾ׊I­öî ¡eQž:0ÿŽ6$Ž4Àô S¹¢“Ëuoî/5ÀøŽßìÚõҺ͸­tú,WñÎ’Çiòt,MfxÞÖHµD¹hZ1*c ê(@s!¸Å"õ§©¦à HNH¨c#8â¥ÝÈ"€7tæ³6ò%ʱb8Å.—¨üò ýTsŠ£k8…K‘žÕ·tc»°?e„ù›SH 0ÙCh×Ip¯$Óa!2Üöª— u©+ùÄ€€ö«pè“=ºHð°$ÙŠ­&—4&wEÂF¹$@4; uMf kXIJ1Îë^—{ªK§øm,Ã,aY„Š˜ÆA5çº{}Í¥ïô8­å‡íZÚš<ºœõõ¤¥Ž£ÆAüjÿÚ•‡¹)tkÝ6ÓíN³Á€Ø6(ƒP¸–Ñ'FR¥‚¶Jç½t³]$ åõÍzkx_È>q“Ú´ü7}»P¹´Ô#_=¹‰ˆíY>'Òæ{å¶ 4Ž1Š|³Ü]¹–yòzž•4.b ©äVޱ`4ã ¸_¸Ÿ3z±¬øÁn07´ÝN[lÍ€¥ºcÚ·-!¸™Æ6É¿§9®$[Í#áT³0+Ѽ=i$VP;¸i£m¢ºÞ¤ÿ«Om)„sýâ95°p¸â¡–Ù™3´àÒ(X¼Š$d¨%Ñmç't¸ô*+t:ª€ÃTa×ÊF q÷¾±œ°ϪœV¾ ”“öi²Gð°¯TQm¬TÛÆ¤°àæÀò9|'©ÄßêÕ‡±¦ÇáPœÇµŠõ³Äç9枑ĩ4\)ºÐüE'—æG,¡Ê7ä è<;£jÒ^‹½R9X¯£Ú»Ñ`nQS#¶}\ a=™ˆ«*öȬ¹!19õ­^–m£plèiˆevl’i"‘ó¯n¢«ÍÊ–­ò@É8µS ì|ûb€<§ÅÁ×T rqXæ^X×gã¦ÄЧ–<ä×MÛr~•H\Ú¯ÛÛ‡*¼ŸÆ¡Ê@,}EiAvºõÏj`lIá’ö«$@çÅs·Vm1B ‘^£¥Ö1ñÚªkZ$w°3*0 MÀóÛ+ë›y±Êú×Ogªι‹Ûy-e1ºÊ:–)¤Œ©Í0;e¼mÂÉ©Míù¨ ´híl]¶îš_•GR*)ldµˆIqò;òõ­Èc³ÐÓιtžó"BÖåä·×-4Ç9è=(4ç½8‡ãšj8¥Š2iÂW XÔpG´ŒÈJ±Aó!éš©">ò̦ñé^‹áPÁ÷Go;ò=ÍyØšët}[QÓ¬6Ì¢3Ô0Í Z¥“ÜÚÇ©HŠ¡8 ðEaïk‹=‰'8­;ÛËëô1Ï *yÂŒ Ö}¢ƒÜx GÍ·Ý'é:L±0Z–Ï5æV—ÖÑ–t\v&¶¢ñæ™k >kIü"µqÉ6Ž•æ?ü.d·iàA’sPKñzP­µ£¹ W5«|LÔµHÞ#k äŠI03îã{ +Lä”çµ3Ú‹ÿÏ0ë$ÿð$â¨ÛÝ>­e(pL‰ÐŠÕð¼Šú|–ruùÔ¨ÍPòþC÷î2k•?t×g©Eöo[DOIÈýk#ƒŠ†AÿëÕ´\UAÖ¬ÀÜS\S—§H¸jÖ€øSŒÓÏJbãq­JŽý1R/N)¬21H²)yȨã;N=ên 0%šmðÂHù“ŒûU;¥Úêã½NP†´¬’&ÇN® L¾{i—æ;Ojî¬îÒâ1"»Z€8­fÆ=7ÀÒiѨPK ÷‰¯¹‚HF¡qÈÇC^õâ¨^[è­ŠŸ&Oœ{ú×k:pÅsr…Ü@“T€á¬o¦0”;£n=³[ n,Kœž*m#BŠòãΔ€»¾qÈçµG­»YY4ñH +6A÷¦î Qêv÷B-²°ßèqÒ¼ï_›Î×f”I½XäWfñ,ødc·Nz×;,ÆYw±É&šSAÒdÖõ‹}:3†šP3è;×¹jš~«ek§éz<ˆ"‚1Žç^%ámUt_Úß?Ýþo¡à×¹ßΚ¾žM÷–ÅÃnì«ýi08í_KÓí.Šê×2Þ;®æòÛbçÓב£ëVv#,íQ-ß÷,¨2H=ÉîkGW³ÑZúS{{z쀀=j—…eÒ“Å6±-¸Û#m¶~ŸÊ€:;0×6ÚÅ«ŒK œûý+˜¸ŒÚêÈ8IPþuÙßÓ¼e$¯òÛ]*CÛ‘Årú¼ ílÙʱR5Û¥HÝߊ֌‰3Ø ¥2€–ÖàwÖŒ˜ŠnÀPUùî¤a÷Tb¬ÓÞ™e"ÉêÜš×Ò€/épl5(ýaAÿŠ_Š:§Ù4•XðZ) LzåYô©´fÛï¡Døõs_\F¢<ÿ¬º ÿ|Äõ¤·+LÔ£ž%’&Êô žA÷®ŽÖèò+É,¯e±˜Iú¯c]¶•«Eqt?QÜS°«¢k¾@Ûèk[VÒ¼;â¥IuM:ÞæUD¤a€ôÈæ¼Î+ÂW5±e«¼a~sJVbƒ^¿]ÖësjßôÊlÈæ³¥ø ¥6DZ¥âzeTÿJÛ³ñ8ˆ€îqë[x®Í†Z`½`yÓþÏì[÷zÛcÞþ½@ß¾Ìñ­Æ¨ì¬Ø2,x ?Zõxü[`<õçÞ«ê9ÓmcÃ:ÈÇøE`yf½ðbÏÃú3j3ê8,ŒFzƲšòu±ŠÉNØ!Mˆˆ1Åuž-ñ­Ž³f–qGÌm¸|Ç ^}u¬ÛÀ¬»”­5p.¥5œH±:É`€­Á¬‰¯ÚáþaƒT§½óÙä-ì Wѧ8}Ýò)ìþ¾Ð´ß›Ë½' !ŽK¢A“yqÔ-y|ÒyÆT|熲¢Xœ¥ÔG늺o"ÎÒ1žþô©Á%ÅלJñ™áe¿²ÜÇ(úÖô–æk†¤É´ý}kFÌGg4p¯uæ€9fÓáÒ-dÉÜëÔæºßÝBöh ‚q\wŒn 5èïú æí5Û«DLT,·I©CnF÷©#Õ!œ`°ã±øžêC—”7Ö¯ÛëîØŽê,©Kq‹µXz¥t® d_¦y5ÈÚ_Ë&Õ·g&åÞÒF¾¥š¯!?42ìißÚ œÁ'Ƨ:•Œ_ë.àϱÍAqâ­Ñ ’ä9€¦þG'¶GLŠê £ÈïXÒüFÑ¡,#ŽY ß,̘M³õ¢Àtñk1"vÛèM\KûiÆ#”7ãŠó»ÿÛÌ“a¸ž¥Î1T­¼E%ÌëåZª“èæ‹éS߯§c>>”¶¬ÓË”“wÏzçíÚR´j3ÎIÍtºvÁ[©ü¨éU ÀãÔÕK—[hv^g§5x(|Õ[åY!eÏËŽiâºîªú¾®óH6¢ª¾‚©!Ãü«“ëSê .¯t"(sŒŠ0€•X¬ Ò(ÝÉëŽÕ¤ìèsך XRùv«öòÆÑ(7xóHBÑ=ŒdñZe¹}7Sk=<2Den€‡ˆn^ØGE+ñœt¤C,—¨«n¢Ë9B u'åÆ;WMkjnl16ç`9$w¬‰ôç¶V”·îóŽÔÌj³}±°£âŠÚ–Á§}ë’¢˜¡lä’Xžôä“o`~µô y¦é ڬà÷ªpÄÄ‚¡¼Œ8ü©ìäàSð1ŒT¢Âb2$_Ê¢šÚíSiJXcO0ü¢´#aŒ+ Kv’ü½Ä÷QZöÈËnƒæ  *q2g 5•©ÛÞ¥Ù‚9Ê¿jÒXÈäf¯j„'@šÏìåçW߃µféš«¯™tÍ3zWu1£C¤Ín 1É·(®kŒ—Q»liX˜URwI$ûÑ`[4ÚNèÀ¦ï‡u³¸) Ìrps[²Øë1¼g1»ƒúÿõë‹S´ç¥mØÝ­Â,nø}Óš@vž*‡Ëð¨è³^{^‘â/ô #ÿ°¬kÎ03B«㱩baœzÔr¯ÌiàñL Ò Ê Š¥„‡B‡¿"˜F(´ƒÒ—½èëJÃ"š½iøÈ¤b6½L=sQʸæ•V˜ 5¨Y¤Oáa‘ON:SfùU_û§éH c÷Scž¸­:"î9cÍdÜX8ïV!o”0¦{y2Gj÷FÆNO¥Qðž¥óÙ²súÖÞ¥$šoÙ×#ÔÕMïì·ËèM+ô›sçB ž@®“LÔÙ•Á%AÁç:.¡º4lðEvš|Ûþ`2§‚*@íõ dÖ4­ñާ΄z÷xÿ‹u%³·û0nlW­h’´?!?!é\/Œ´h,u¹F ¼ì{þ¿Î’ŽÐ5!’yГ ®Ò:dSõm6+kucF†Aò r¹¢uò—‘òôúTø6æÚwÃÁóÂÙäS̵Ý2[i䔘ÊîÁÙ X½º÷«7Wó]cÌ+Çp1Ÿ­UùvŽjÀ”7~•ÖøKÅÒØ\&Ÿ~%¸°›÷e–^x#ü+ŽÏ5Øø NO¶kÜG˜må™ÁcùúÒ`z©§hv’É$z%åÃIàäˆÈèNjµ®Ÿ“®è+%¤ÎÌ|ÕŒp .F}úWA¨ÞÅ5ÓÝ£–†IcW<qšÈñ>ûmNÞñ³ˆïË´ @&»pÒÌÐܘÎÂþÝU¿¥UÔ”O,·ÞhÀo¨«þ(l¯qÜ»@qê§k],–¨…²ññõ¨"v¤ÇøPb¬]~ñÖМšŠÇ²Hz“V LÊÎÚ™FÔÀ)Hšv8â¸úRGMLY^0îc_üz¹Œ­³Z²‹=c2cðúWedBh÷„›ÌòÉ®ã$›üUh¿Ý²Cù’i­ÀóšžÒæKyCÆåNj¹§&7}j€îtÍaGšáXuÖ‹kö1><Ô'ãšóæ“#€qLÞGE¥`= OX¨Ï˜OÐVdÞ-·çnóí\c–=zTgX²Ocý\lk>ÝË (5…ÊŽ:Ó°d¾¹”Ò0°ªä’rI¤ J·l¤.U»Ó¤q'žzÔp‚AúT¡YÈëÚ€«7 U•XÔýÐÒªCÄœö«Æzb€'2…JÌÞõžzÒÆYNTtï@‡EÇÚ* LòOZôËtÆ›>Š6àjà4À½»â»Ë6cg"g,PŒþ xL£¸ÇñEàS®Û‰êçó¦•@L#8?•MQ‘ÅWW`¥AÀ=©èÄ0ñ@"£ìÀw©aV¥Çµ  aÔÕñj‚5Ï5#嫤|‚€(”JTô5nÎ!äÜ*˜.Z®É™»Õ«!™ B9 í®<«—äŒàŠëeo·i~a9;0kƒ¸r¥Xrz5tú5à’Ä¡<ÐÒ'K½{Kǵ¾Lü¦·nŠ­³‘÷±Årº•´ªvزÈ­+kÖ¹³A÷—nµ0,è~#_0Û^¬§÷räk¨2,—ip@n2;׺ ÷7xC…<äö­[ûæðÌvöœÜ)}çŸÃÒ|bÂKعìk–d +£º½Óµ¡AÚsÀñ«iàöÜÄŽ¹ )Řöò¥ýâôÉ®ÊmÆÊ#%Áȵw¨ÙÀXYÂôËtã@E® v õ¨ÖêèŒ X­+Ï%Ëþñ¹ìAQìÚy¦¡çaÌÏô“Ê ~bOÖ˜Þ”;šw’¿Ý¥0)“žy¥ËôÍG6åŒ @jÞÍtÆKµ¶Ž5ÜÎÃ?€Üõ­-4G?ÛlZà· Uöí ŸÂw?Ú3ye^]‡¯¨þ•ß&E –YP:d âôÏÚiVÞU†¨êw䟩êkN?¼‘î"(›ÐäÔ¸÷“Æ9°öH5Ÿs¨‰°BÕ_ŠË›ÅR6GÚö#ÿÇÄúíÓy·ÒyC¥‹ÈkrùÚÔÎShÎ1ëP6Ã#-Ú·î¼1¾ì¨ºÈÎK2Ö¶™á‹;g 3 Ûß§åNàrÚf¨dAG÷»m'Â1@¡îä?÷GA] ´ˆ(P:9R½C~T®mÞ’“[ù(vÛj…¦˜-n6HÍ,ŸÂXp+pÈÊ~`Hª:½ÜPiï HËŸZl›í7ÄOßG­`Úêg–Î|œôû-i¯RhðëÞ ¾—Q†æÓ×Þ­H ã¡ëYÊyÏqW —rí8ÿ aëMíRȸ&¢Ïjp©öÅF"“ùÒAÕu;ƒVÈÏZÔÓš`IÏz”®ä`Fr:T§©˜“íëŠ@eº²»+<‚:UˆOî«@\ LL·†a+&0sY±&1L äê*‰&92 æ¬nhÛŽ•üÌr9 ûðx3|Ã¥z6…¨0ÙÅx.›vö³¹Á=«Ñ|?¬‡¹DfÚÝÁ©h~Ð¥Žá6çžÕÎüG‘CØBI ÄãÓŠ‹CÔ 2²°ÏR*¿µ+K½Zydˆ' ïSÔ7Ö5o²•GÁu?pšöº÷Ëä¡Â÷Å'Õ$¼Ö®‚2ùaʾ‚¹ò ÍZ@'<ÑÚ”Ð0z׺XxsìðüJ’Vóe÷.§üExrŒ1Þ¾ñ;Ëká5"e1ìBŒ~¢¥É äkK›lsŽdþGõ§®2êZÌ9 Fæ³´éâ¾»I€Â][¼_Fpý2]ë}¥I÷Œg`>ÜÐލá´ë;ƒþ®X„RØö5ÇI ÃpÃÓµuFêt•¶›ˆÝB“ýÓڹɒX® †êåìh@KápEhÁÈâ³ã}¹Y¢!‡ñ'øUÛIc'hphØcŒÓ±‘Æ(Û•" ŽÉ¹sò·Që\×ÅØD·Z6¦€ížÓË?U?ýzßÝ†â©øñPð2éóo'ý–àÿJh þ e° =NF)¿vNj€•_äÛÜP_ÒšO'#èi§Ÿs@6i†—îþ‡'<Ðt£µð¢€”GJ>´ôp§…ë@&î¬ùö©ƒ’éÆj®æ=p¥JŸ/4±%`zŠtï÷qÚ›'úâ;Hßêþ†€y©¢Ø ÷ïP!ãšž/¼1@ŽŠjŒä»K2v‘žvœ×£,Tž{ñ]=¬åcšAÈT$ŸN*@ñëÎ/gÇüôoæj0§#Ští¾yûÌOëN`LHj€*hÉ }j,sÔV–“ù±ß"€-¨ÀŸŽ•±©éFD>P ±¬¦ @O ¶ßtUh‡**ÑP\¤~=š·ö„xû½ÅFF'J±mòÜÇŸï ǽO.òDíÎ*æ˜í”o¸ÈªºúùWă֮iêÒhë´ÊÙ#ÔP¬ÃyÖ²d+ ­bèðËm«Ii*19Ö¶`_*?7:ŒÕ»AÅÒÞ¢å¶ìJ@héváYÇËÔ}+εëÇ¿Ö.&,vï*£Ð•鲆5@Féxâ¸{_5ÕÔïpÅ18ž´ 9 8öÅ]·Öõ;h„PÞÌ©è£Õ"Ž Jx¢"6MTè*€½quqtA¸žIO«±5884 ü¢Œdc&>e4ôa"àõ¡pÚzÒ(Ù(ààÓÀÅ3ÞÀé@Ó‡ÔÐ9íOó ¯Mli‘nˆžqY@üVÆÑ”tŒ‡ íH $ƒ#©§=¨Û÷$nñ’¬ SÞœgU?xïHãˆ1Ÿr8«Vói7&IôíTÚé3÷©bœÈøQ¸ç°¦øµ”kƒö”òϸàÖÌÁ6Hö¬+ë%¸„³Ž¢°ËPµ•Z5×wðäÒÔ­åPÍ]Yׂ pÚ~§zî±=“ô`y®žÖ6‘w23þÑ  U=GÏëš;_IÂBçœVâ,©üAǽ%ÐÀcÚUˆê)Œ4kk(ó³rcï Õh­òÞH×”å1QXÍ-Žªö·Í$Šçåvn1WåQe|¯…ãsØô¦xZÔG¶kq¼pr¼ÑRÞZ#ÜGÚg4P’ô$?knüiýÅP¯Z‘¥@<OÃÒ€.Ç(=N*Ì/†Á<ÎIØq´­J—Š)~fÚ¤8úÖkœ·Z•çܽpj·Rhí…ב6Ö?+q]5±æÎc\f0+¡°œÉd 6Jõ  Ú´ØÓ\g¯ÄJ†9 þ5Ôj—´ü æ®y ž¢„RöëIL¢“ñ¥íÖ€5´[st—‘3£g»gåBHÚ& ö8>Õz%0øjI”e¹ ‘è£?ÌÒ<ëxžCþµ}ý«ƒ¡©dŒJ™EG%¿ñ!â„‘”á¸4X‚¬{zŠz6ӟάIÌ21¸UB lCP‚0tÇÕ^Bc|Á¨ã©ëÅX!.#Á8ô4ˆÀŠ‘MT!íÏÍÈõf'W\†€%ÎAÉ5 æ‚)öâ­AÏ£USíSÄH9¥AwC'˜™Úx8íP*\¯>¢¶[lªs­ÔViˆ$¥KÇJ`W;ºS h¼[ùB þt¢ËÌÀ#Žæ€(ÛÜIi7›Ã/CZº<ó½ÉfclîY×ÓŠ»£øJ]Rä'Ú"Š,àÈüãð®ö…Ù¤w yæÛžCGògó¥p(èÚÅýÅê[ÛÌóÊ:ù ò¯¹'¥tšÅ´¯¥O$Ž Ñ§-ëZ–:~¤Y [Hã¶”õËn2sëYºø6ö[äIÁçô©Áîf㫈֖¹kž£"BÙCÈô¬Þ½êÀ1ÛÒŒRQžù  ©æ]Áþ)~µô׋ms¢¡Qþ¦ÿ÷Î?¦kæ­Öl²åâ?ýWÖZœ 4iòŒ¬ô Š–Œiñ}•îáFæ ÖxÿÜn Y¸”C¨ÛjQqµ¶È?C{Út0^‘›­æª*Î¥o‹ï­þx$P%±õ Õ6FîS›y¾u>„Öz\¤°yC*>랢•®•ìDE Óګdž>Ôz4h€Î%‹øXugÈ‚a Ÿ^†¨ÁæZ¶èþhÿŠ3Zp§|g ÐR b‰É_îµ\´ pÛ ˆŸÑº~tÅ⥎ çž™ê)£i5‹…6îû¬9ñ¦Y¬ZŽ‘ªÙÜclÖlÔWg‹­¤5¬wŸŒIÕZ¸ á›M¹–Ö@QѰÃÞ€µuìgŠÑ'eù½D½iC¶qL*—y 6)œRƒÏõ ]Óî¢^Tr9F§s@×Ü VG|Ö c³Åtï*Ýi¥ò3ŽG¥ròq#zLœÒfŽÔP -6—ñ âÃK[¿µ¿YrÊOsÒ¹I­f²˜ŒGb®Ã©LšZ4•’ C²ýF3ôþÇŠêÏYô /jÑ1ù±È \ÜrËLãÓµi²äRE‘œö¨#½Fá†ÓR™£U$|ßJ¶„¥VºŒ¹Êr¦±°Ôµ ZÝh8Ít'…Ziž{Õr‰È(Üf€9«h&‘Ö1 rz`+¢²ÑuŸ"1Þ[8î1éPx®àÙi j[÷ËP7áäkßBßíî&º}uN¦Øå³Yàóu×~¡#&µ|XÛt[Ò|~´ÀóM'9úÒÿ û˜;íLåXŒpjFÈþ´Ó‚:ÐsNŠm(£ â”ç°æÉ¥ö !Ïœ ¯©ƒŽ•*œŒqH/ŸÔi zÓ×ð  í'òd¾é­¨¥óÇO¥sÝëgL•LeY€#õ  °†'µt#íA˜t‘l#fàŒ×K¤Å´ç€ÝÄdgh¦Œ“”\Õ„*)E ¯dJR£¾Ñô+ÐÔ;g9`Xz—§LU[»Æ¶BÑÍÛ<ÔwÏ4HJDî1Ø×;m«@o¾ÏwçÂ7ueëL´$—6ñ™T<œU/Ë,:;ˆSscŠÕY¡+yŠ´“ŠÎ×äΘÛ0Ùô¤5c§ÛÉj¯)P瓚*²=À\$q‘ïš)çdŽp)½iqëJ\UØ y.5RXžÙª¡³X@Æ+’†F†E• § ×Eö¨îb£u0ô4€ÃÔ,~É!)óFyÒ©Šèä "<æ°î­ZÝò£ä4À„RÓ.pzІ(È¥%!ç•P Ð÷§c¶i@¸qÈÍy§c­ÜS€ù ð9€Pò1ÒçœP9Î)@ë@ 1¡ê)@ 0,p¼§3îx­K]%昖#œt™  2™Þ ̱¸ÜÏ +·Ò ÂñƒÊÿ2íÆÓƒ\Í„–ö·m`°ž}ëÒaKKpìÞh,f;jX÷ FË×$.xT‘ÞŦÉ­½­º6G¨õ«‡IÒîÌ“[ê-7÷•úŠŽÃGŽâÅâ¼Wu9òä^ Òv-)5B%·‘fÚ7•y ŽÆ²„Z™Ô’Å~Õ! Vü{è´ˆE½¼Eq<'HÇ;q[mªØè¢B8,1ÈíŸZç¬|E¨Æ>Íy£Ü‡æ esê+¤Óìã’0\Èe~J±=Ó#_ÜC<ÍÛ (¬K¯j‚- Šë÷Ó¾Õom Mpꊼ–c\ÿˆ¼oes Ë¥éŠd–Cµæ#€;ãÖ¼¾÷T¾ÔµÕÌ’ŸF<Â¥Ó\+ŽqÅ;ZúÊ[eó|…°ªÂ›¤Á­]\Jm£c÷U±J¡ üÊá'ÐÓg Ó JQóã>Õ}ÔŽƒš¡'S@ £©(Å(£”´RbŠ^ÔcëG4PãÿãW b8ü g ± Ô {PÙ9æ¶tx% æÉ\õˆ¬q]&„¼¥›ƒÈ¤}¿LŽ Ô¹tÁ$/¸¬aö€/Ñ€Å^Ô×Êð‚N†?:ãØzSw¡O Rý) ç 4ÀMµzÏ…ç¥SÕ"É" .1@¯†¯Í½ÁŒŸ”Œ `û×LGW5ËÛjÃ(r£#Ò·-/RâïÉ€½Ë5³q&?„S\„AÍIn³Œs@ï™a\d/ãSxcmÆ«•9òбÅs:´ÍqxÛX•u®ŸÀÐyVw×l;méÍ%š ¿ÝÝ0ÊÄN>½+©V)fø5sÚL{mnfþü„×Ak^G|‘è).…d»Ú]¸Œ –5Äø¶ÿíš›€~PxúW­ÝÅ¡èf Jã¯#¸”Ï;¹îh@w!)õ×ÑA¨|`äh‡!Ÿ?­løvÛû7ÂHYpÒåÍs¾-7‡à9Æçüèê:XÇïTZmĮ ݹÅ4Ó_–¥€3ŠP*NÆ”P…(âš8PÒž§ÎôáŸZyïNíÖ¡SÍJ§=zÒݻԖïåʼÔ]9¤t ×N´dl„`ŒŒWO¥Ø5ÈA"Výá;k¬ÐËÆpM :HTàsR´y@¹¬~• súÕêiÖŽîJñØf¹ ˆÔÚxÚòFå‰P¨+¤×È›ȪxÏzÎÓîcµ.²®Õª¨Œ‘QK£X݆óa Þ³&×ía„òÇÐqZ~¥%ÊœZº¦>ùéH?Æ!,Á$Š7—u>ïQŠmÖäoÀÉÍRñ¬‚MI?usÍfiÑÚ2eÌ€p ëL ¨ZD‰V(èy»š)°ÜËTíEy¶0qÔÑì)N1Ç&‘AÁëT†•%ðßÒ<úu®Š "Œ*Ä}ë[Ãv¦1f‰"¶Ì,W8 øTÜXh¬ËòÂÙõ©ÿái£)$ Ü×Q¿†=…]krS÷’b‹ãzÖ…q£L7©h[î°¬ÌÖ½¦ÿJ‚þÑíçѽºW“k[i”–Í’ åIE4ÀÎÆ)J—Œ{ÔMÁ4À`ëÍ1@éïN(4çÆêh –Š1@=qZZ`>\Ç·³kOKæ9ÁÏ4à;—Ò«Í[½U<õªT âQ«sNí@ü(êi3ïFîø jäPt \žÕ4j3–ö¨â;X‚x5( tæ€-¥Á‹(=©‹³Z™š|±p¾XÎqëUUFÜE=b•<÷BÊű·‚kÐ,u›H§˨Û¸ˆn2I¶={WäýiÍû±»?)h°2nrO~ç½1ã§líç©©bùË¡ê*Ž!pòF[TzšªÐmb¤E]“1¾õá– É’BÄòiY—g©Ñ® MsQ½j¸ýhI–'½DEJ͆ôaÖšÊ;u ÇZ‘:‹+qš›9£4ÌàÓ‰ùhÔ¥5>aÖ@j[Y<¹ÁZzòxë@÷+çÙËäã#ð¬{\‚GUö­xÊ3ÐÖZ"íÔœ â·Ü”LÛ“ÐUûRÙHÛ†õ5$iž¢šÑrx¤ß=fLù€cÒ kÙB¼q‘´Œf«ù@Rª`z¥åeŽz×}áèV/ÎøÁ%ŽkØ2y®ÓF•ážëýh`.i‹b—95Ó­t+îT>?*赀 û(+•ñ>¡<÷ X‹ÂŒÒ?ÄÔšã1'oEªÚ™&­«Cl£!˜>ƒ½Aca6£t"‰I$òÞ•êžÑ-ô˜K ®>fïL^"ÛOFUP WŸøªCý™d„ÿ8®ÓÄ÷ H[5ç>!¼ûLñÄ+ãñ¤€Ä©mÇï ö¨ÇJ–¯Ïj y¥Í&yæ—­9O$zÓ…1@éOühíJ˜£à})ÙàÓGJQÇ4áŸÆ¤SÍF½8PÙȦšQÒ÷¤ËÊ\F?‡uz††3šò»6Û*ä÷ï^Ÿá×Ý àäb“°·_”U°œT£+WBÔ‘y¦[Ý$Ö%ÆŽ]‰UÝk©™yÍP–úÝ_Ê,ý­02#ÒôûwRè­ é»š°ú¥¼y‰ˆL3T¯'ó® *8aȬk¸¦ #ÈQHéšæ|Er.µ9eS‘Ыk@Ž= H–u9y7l'jÏÙü¦ Ä(  *K©¼М-“w.û—`ÛrzQ@ݪ摧ɩj1ÛÆ8',OaTÁÇjî>„k«ÂñùF3Ú˜…­§“ tÀ­(¬›fù§D;0Š•q·k€*¾b%ÀïQ¬.O'9­ v\NX€És€+¥¶8n}+Ͼ$ỉmp¨Td†c^œ°¾ðË'·­s¾5±ûnƒp¸%£ÇáBÃò@"˜zÓÏ GNj3Þ¬Å(þT” c cM©|µá@SE;‘Í'5¥¦qçØ Î<ŠÐÓXçNøÝ@ ps9ïU1œõ«W_-ºd`“U =;µ&9¤çñ ôáÖ˜: \О9âôãŠ3M ¡ÉÅ?w5 ’™ø&€,§Ý"‘œ‚#òÔÅ %–lðjÈ~£q&-Èõ¬Þqõ4Àpãò¥§4Ôæ—ø½¨èp⟻*žüTJq ãµ;s@æ7=І¤œ„Œü¤äTÑœJ}Ê¢ºâQÐ@@œÊ£¶jűÍÙ÷ª©#šžÓ›}0&|Fz­C äŽ2jg;ïô¡áû»ÔÌÆØù9=iBêÕäP)+Û<ÖYÁ«»¾ÒáŽ7šPT‚+‰¸ÏœÄ÷æ„(Ü…{õ 4å%Où7cÍ0!#4Ú”®Fi…Hâ€Òœ>éÚ>3É.*áªaÓ4ûÓѰ{ÒM7¥kFIO¥U¹·w¼,¨ÅHêz[IJŒërÊ .mäòd êxÍ ¬Ä¯¡ØH –A±°y®QÇ$÷®‚òÚþ8L¨PrH¬†Ö„*yéCu4˜Á¡©€” »~Z±i)Ž@@Éô®Ö8—Äz)±t"â!º7=qVèÂ1 Á®ŸG¾ki‹×½ 9bx%x¤R®‡k)ìE3µ^Ö.Ö«s8 ýê0 xU#® 2— 1SZH"¹Flã<Õ`O­(È9  WmÌO½iÜ©xàSƒ¶1Yq3f;â´î‰Hþè|94†1ƒ€RŒ[$ý)Jµ3’1NAŠBŽ)ñ#näŒÐËt]¤‘š®ø,HéW¢Ê#Ú¨0;¦hŸ¤ÆiàÞ—9âº7L¸‰Êæöšè|0¬VèvOë@Ó|­·¦ŠãjÍåÄ9ØñüËüC¡ªQ¤S¡fázLZ6œ`r’þñ#¿Ò°õ{%dhìäÕ›‹4‚Aäâ>îXãô®WR»Y./Ìëœæ˜¤‘¼Æ<{Š)<—Ÿç^ŸZ)€ï½áÌB ;™ä…˜ØVÒ¼éyµë¾´û.‡oL®M&@'œ¡ÀéÍFÓ•o–,ýM1d(1œþíÄŒç5 =gœbçNpAQøf éœŒŠr©$óÅ_Žø¨û ·©²Ì÷0ÉƤ:xªKN­øSŒÀ dšðbÌØê×VÌ0QÎ>•Ÿžy®Ï⟕ªEx‹…”`ãÔW{Õ éGçHx£½8á†3P‘‚EMÖ¡?xýh)ÝE6Å:®é§÷ÒÅ R­iØûPªEMÁ}ªëWoÏúH‚©7_jrúf—Þ˜8§ @íIA$R ó@ œIšCÅ%)©‰ÈJƒµLƒ1} MùE?wÈñÓ¥?¤W-«ÓU¸"¤vÜä‘Pž\Sçý`Ï¥/Î=) @å‰í@ ÿ-? S÷:ÓF ‡ŽÔ§îý(AOîãolTW òJ®Dg§J­#îj3Þ§´8‘ßÚª3pjdù >¦€,[¶û—oA[ž‘—P¸ ezV¯¾•¿àöQœäd¦E :;óþƒ9dÀ*qÅy½Ó3Jô½N0tÙ˳d!ÀŠóy•¨útƒOŽ|¤gŽÕ”ÍŠïm¡S§Å´Æp m%M!«Ú•“ZÜ2`õÊŸQT¸"˜0æ›z‘‡9¨È J•jzœb€,š‡54;[ƒI,%O¨ìhm¤ øn†º·2FOÊËs\’ÆXñZÚEÎË´Šl€N¤isme:¸(y?Jó©×œzWtöÞbYBñ޹®*ö# ± 3ÏÞ<ÐiÎ>lÓ1Lž)ž´«É ƒAŽ:þ.e¬èîÞ¢ƒ»¦j 9]'Â9]ÜqVÿ³åËH²!H=h4’ÎÄõÏ4„u¥îi}ºÐ:ÑëJFÖ’€(ÑNí@¶#Í’w[·Vò+±ÎkL™a¹ŠFU<Šê¥vlRTó‘H }‡¸ÇáLdÀÆx­´ÉWüj¬öÑž¯ƒ@„py¢`Ù$ÕÑa»%vái*‘Æá@FG”G|U&êsšÓÎ"'n+<ÅÉÉh5\ûR…ôÀ§ˆˆî)6އ4;ù®‹Ã B]úüµÏàgƒ[~”%ÔѱÀužh¡¾}±Ê@ϵq××× öÑ&ÕVÜãð®Âî0F®_O‹Î’ãŽ<óÚ’χ4Yÿ›&2kGƺˆ†!0ÂŒb¶4ØÄ d8Fy¯:ñ=ø»Ô¥ÚÛ”7ZÃvÜēɨ˜e€4ÿzgñŠ ádqMŒp§aòš:žh)Êx¦šU4 <óRtæ¢ *P({ÒŒzÒ /ÐÑF-ëOÐ8§¨âZvpiÅûf€%¡9?JX'òÉùI#¦*œB•9#µ$²¶àp(VÓıå#*¼ÿv¯C¯_E2¿˜¤g$m¨4ë%†áfxŒ±÷â¦Ö>Îó¶„F½ÅtWž2VÓDvÁÖ|s•§è>*ŠX 7Í+KØ‘\e½´—S,Q ´Û›k­øû›¯µº¾1ÜÈeˆíŒ ã“q6$cj¯,{ý+uë©P nã"¯Fe”› 6E ©îKU‘𣠓‘\ŒÑaŠƒÓ¯½ojs¸ò‚†+Û?•s× Å# lšhüÁUOйbEÀ×Ò¢ûF¥mèÎ3^Ñ¢Dª1€1Šò? (“Ä6ÀÝM{ 8vô©`!;T3B»mmHסùÝúз–¬0³/\`R>r23J¡ñ‚ÄÓšåòF=éŸjR0»OÒ€’F8ÝÇÒœ¶¬Ãš#grO }*mÅT³±ÅsÞ.Ñ?´tBæÅó¯á^,À‚AŽ+Úµ­ìÑ*Ô“>£šlÖÍ‚Aýh‡vѸr :è­šL.ÓŽžµ¯X5µÀf ¬ƒ9µÐÛ‡0G 9ÈëŸ×o~×yäÁúÐ8ü1SÚ›š|¼¿¿znÒE0N^´Ó×Þœ§±1YÔû×K$l¶îäñ·5Ì(&@­u·ªÉ¥9 ’€91ß‘Nšõé@ÊH⣫–ë¾uSß­Aq‚v»(!N^N:ÓiAæ€-Eòô­øî.!>nÊæã˜«Ž•ÐÛ\-Ô ÿõ€°56<8Á©Òp6ÿSxÁê 3j®0H  xî28@ «H|ÅÎÞ¾µ‚—RDx9úÕ¸¯a¸`ûPU*$œ(ééYa˦Kmª+.Òxõ«{ÕÆE 2äÓÇ%WÕUí€+e—q;OëUÌ`Xþt’¶Ì{`ý)ñew §$‚:UçEÎP\[™!Îì²ò3Þ˜T®&·Þƒ‚;Õ "ÃÉóY¹ËUË*[¥1´N÷UKhJÀÇ||´€M_R–’³I´…QÔ×›Í!–VsÔš½ª_Kw12È\þƒÚ³{âšü©n|T« ‘’6ŠvÅt÷¦N*!ÃT­ÆEG~´êÔ¹>´„í”Z H§‘Rç­WSÏãSgæ€$Ï4£šh?(ô¡O$P³ÏjpéMniPäg4ñøT‹QŽ™©ðâí@å°)Iüiƒ;¨˜™6Ó­çÄê¬~QQÊH”ãÒŸcKp7¶ÜSÕ|!¥Ü- Žâ³|K¡šH×0·qÚ­xfhlöãpÏÅtW’ ƒ†U–&àŽµ y0vµ—†#Ðæ£žWË3–>¤×c©h|rI!I1Ô Ç¹¹™•Tõ#ÀŠÑ »PtM+‹#(Ý9÷5•o°Ü)1°ç¿zÔYCÎý¶ŸÒ€1/pf™—çÏþµ1Ãs×é]RD[µp6²Qô5ÉLŦ>¨@ L¼͹ç4Sõëw_R+Óc‰ÉÏ¡5Àø7^VÛˆOJõ­Ÿ»ù –X¶ƒ¡ˆ°õ<ÔÅn1CǤ@åE'îÆ@ ùR´Ñ´Ä2a}wµòÞ¦mοu4ÅÈ\}+>òù¯,йÑ ˾ãøÑý‹aýÓùÓŠ#’;Špé]³£ÂˆƒæRz×> Í0•—¶(ü茡¹i±àT§¦i!‚If‹’}(u¸$ö’ÚÏe4M$eW5Öi:*Û*É( ç¥O­i¦úËäÍŒîQëíJàq, »Œw5CýjyA[‰9éLe¦3HHsšFäzWÃùSÕ²¾Ô™ƒ@é@Ç„X&‘&zy§ù ÄñmœIz·Vê6È?y·³zþ5sDb4›€‰ÆjKÈ[i‘ŒgëH7µ<ž)¤ÑšNô4' iê2Õ]*dêO§4¶ç$šoSíIÎzS×é@ËA8§Â¹lÐÊzÚžØûæ¢s’}ÍH٠ǽ{-׉VÇáý½äl ïEVŠñ's$Œç«Mn_êrÍáë _0âl­`Ÿ˜“ÓéIåï^çàìÿÂ+b²‚§ËÆíšðÔê=} ¡Æí X¼ òT¿JšÝä~•“¨ÙÁ¨ÚIo,yVäV´¥Ð7#°*Žæ~GJ¢’ ôC/#½m_A¡§‰™†ä]Êõ 9fÁz~¨w'ÔÔÍÂÓ³rÆ…#'41ù©䊱e›} ŽîvzÌt™¼¿¼¸«{†·¹ISªœŠèæÖ£º°“pefB0:R˜êUu¦céJ7/j`]°M×ú ÐÔ,MÔK\Ðf$qPü¥½ênÜš€rr:æ˜ ˜a³Í!,«•5œ©†€qS€úŠ„Tؾ”èc<ò 'I:šm»bB§½>àa€&ÆS­Gê)ñÉŠN×"€'ŒSÐçŠ9Í=8€“=)RhìiS@­#z⢂92ØóÚœ  {T©+G )ÆM0;_ ,o’:k­ºk„µýÔXÇVÍs~îU^9#R:‚+~êiaSIã 8©mCÜ2ù‰¼ §©iQ12ùF6ìvÖ–žÏ(+"ë¸U‰æe|—M2üŠ@q“XίæO(*¼ŒÕR….™gÃ/@ë]¥¨Ûˆü¼¬ŽßÝ®bäÀ'Žt.6¿?CL —²¢Ù’§dªã¾MrS6[Ž+¨¾e(Å€áp1ßšå¤'ŽôП­œwS´ðÒØ¼ò“‚À]Zk&Cþ¸Ƽò² 3Ö¥0àHCmbÆ^áOÔÖmߊí“!$ÉÝÆ–fÈ,MFPVjçÄfRxŠ¢uÇç~f¨´\dfÞ˜N¹qÎØÐTM¬Þ9á€ö«íôb€Ú…ãu™ª#spzÊÿ†š½KÔÀqWÚ«§ ʰ§+š®ãl™ ©b?.*1ÓŠtg @ 'dù«3І¨.Œ5Mß öÍ%»qŠlœLi°²ïN›ïŠ™½=OÌjÏNj\àõ¤¼RÏZAÞ•h½>µ,Q;6séRy`°8Íu^Ó-.åÌé¼ç¡é@<3u 1•’VØ/Zܺ»œëgq$}Ûetv:u¥² ¼iE&§'—dçÚ¤"oÛÝ‹iU×׊ϓÄ1Ȭœäã5 –_]€`·4º¶“…Ÿ˜Ïóâ˜ü÷ò%Æø\©§5Yõ‰IÝ!õª#3‘Û­ û¤Õ=ÅÄ’(.ÜÕ2UrÈ=*V;±ÏJ¬íœu4ÜçÚŠM¹æŠØö¥Õ­†ïOÀx *@S¯n#¥[û"÷¿JSb¿óÑF(™cM##Å^ûäù«ùÑö'çæ€3ÏÝÇ= i>AÛ9§ 'úPj‡nˆiè’7aÅi‹⦊Ìçæ^´ž–ÅÇÍú Ô7–‘¢¨¹þðÅt‘B6€#¬=[t—eqÂŒb€2…©#åzŒÛ8'<ÕÁ Tʬ b€2¼£ž”lö­*6è@oqMd##ËV÷¦^ßjB£+@Û’cãò¤¼)´H®bO© FGz»sHÐŒc=ª!‡ó  É&Óȧ³+ÇÇQRµØëVÅ´å”'17'sˆŸ¼i1Ú„=»I”v œ»QL?pŽõ«ª¿C@ÏëB®ãÅ%Ml?x é@µÈ§È~_Ÿ2l—ëL—îÐ"¥^j.Õ,gŠ‘y1À4¢š~”%¸ËŠ–èâ@=©-—‘ïKuþ·ð  z ÏÙ5«9úyr©ü3Zž<ÓL~&¹»”ÅpCŒv8æ¹È[dÊÀóœŠíu›Û_JWT"tAŸ]Þ¿J@pÂSƒ’}wÿ`(g˜¯R½qÂÝ«¥ð½òé÷%ÎÙ08¡éS¡dÜŸ‘¬¹’VV ãÞ­%êJ£sÖ¡“ÈlŸLTÅøˆ±©$óé\µÜƒnÑëÍu¾+UˆÅ‚9Šãed±HåH:œÐiFsŠ`Wš›ÃT“ %G7P‘Šz˜S¦iéÖ€.« `Uȯ‚"¡A€1žµœ­ÁàÔ–‡ÌfŒs‘š@&¨ë*#àg8$V[7ÊGõ­]FKbIµcÚ˜ ×ÿ­Ev  9ómƒØÕ‚ãv ŸÎ©éx‘]3‚9Öµ¸=ÉúÒ¾ì·Ý5^æÝ™÷$Š íŒV‚1ÔpTÝÊÐ2ZÏ’v†ükBÆ#ÃúUÕUÁÇäiñç<Œ~åùErº”f+¹TŒe²=ë®8ǹíy?ƒ‘ŒÈ<.Þýéǘî)­×8ëO^V˜ÂØÁÏJ×vçJĈà]¯Ïlžƒ C<“RŒ0àÔ†0s¸u¦˜”)jÍ𤑸WD÷ ôë\ÌInûÄyö5ÑÛ],ÖäS¸Ÿá< £q$€sYò)$b´&1±8$­’‚ŠÏbyÀ¨÷j²èŒ~\ƒèj6]§P§…ÿÁìþ•Ñj1ü®ø¬OŒë¹àm‰tššâÊBGÍ 8[œy¿…WÍK#cŸ\TF˜±ÈÁ¨eáOҧQòÏ+¹ð|T—V¯g±]”ù‹»ŽÕ³¡Ç°Ü¤ŠáÁÇ"²5&ì©'03L T3jxÿŠ^´ž)ààƒQƒƒþ4ñÁ  ØoˆÓ-[©§Äx"¡æ)ó@ ~Iˆ§LsƒKp>`ØëMqº }(Ñž•=TŒóVr@€%Ï)¦“Ç)äRâ¡*º¯ 6& ñXñ$zÖç‡XG¨àŠôÈ>àçµfø‚ãe™_QZpÜ‚jÂÖÁ–Uޤ ½2 ªXð+–ñMÙ»ºò#o‘?Zëo%]?Nw$Ž+Ï¥6GrI,sM˜c;¹ü©6dóVä‰=ˆ¨ ²ò{SR©!篶|³úUFˆç u¦ `œÑI‚ âŠéD, ¤¶~é…tì‘‘ó/Ó"£1E†GåHyTŽÇ?Jq xÅny‘…^}ª3g¼cÓµbí'Ò“OZÖ’Á€çhúÔ_ٲʀG¨4I&•ÈZ™Z_SRýŠLàFIö§-¤ùæ91ô G#È×5a'ÈÉQšgÙÊõ$cÔS–,ÿéH eX‹làƹéäIefç$Ö­À–AåDÜwâªfÜnqL ÀÍ7stܼúÖ‡Ø$Á,H TbÑï+5TØqÉ¥IO À«+ 'Êç°#4²K<@á€ö…x˜ˆ=Ï­@Èã#>”Öžv=ñô¦åÈËœŸJ‚þ5û#~aíXÑ·ÿ^·f_2'R:¯ƒ¶æ9íL Gµ!R+qŒÓ‰úÐKÃ0âƒØ>Ô‡‰G^iÇÒ€l \FQŽíÃzvŽ@bsŸZãôK¸¹í%Pçë]ݾý»KcޤÀeÌ ý‰y .é^~~XþéW1ªÁ; ÈK;•çz´FÐÏ<,„qB9-OÇÈþñ椦޵^A‡5?8¨¥ûÙÍ1zóNG(hûÔ¦€.ÜáÖ9£ Õy>è¥F& ¤žŠVû§4 éè9 ýÀiWÖ€ž3@ûÔ„áI¥æüE]ˆLÕ{¦Ì¼t51ùP‚{UYOq@ }k¯Ñ4c©ésOÂ9mßÜäsÈë]Ÿƒn‘æl,±dzdR`PûÜI’gRGO”š‚&{IþQ‡CW|E—|“GÒAÔzÖhy$Æàr¼f€;=/S{ÈT9ºdzÖ´r’Û% g£×¤Îñ3®Oc‚+¡[Ÿ5Aç§aH Ï íÀÆH$œç5ÆÈ½OÔxšc#[ƒ»åSÖ¹yyæšÆ”AëJ2>‚˜®$JdC-M,X’O&ŸS@E9zóL^Eâ·Ôf‘¦Ý{àP¼F2A\jrŒéô¡$Àšr³dqÒ€c^ÉúVf©gçÚ:…;—•âµCw;³@ùÅp=ˆ=©S¡sT‰aÔæ ÷IȪ@àç4Àrpƺ /2Z}<×<­†æ·´-®eŒ‘Ç#4«ä|¹$qÓ&›EÉåF¯Z°Ñ©Q‘NDRsŠ@I³cæ Gûœ°ºHLJ@<0ƒV­áVúU“‰NÆâ"h‰&&Öª%;X] î?y‰•BâÔ©89”ÀÌóýäÏãMmår¤éS< £$ƒ§¨ ƒÁqƒ¬JOQ ®›__+Nn9#ƒàP_VŸ<â/ë[þ*?èXÁ¤œ¿ýj&54Ÿxz‰ºSaMÏÏš|Y.=ÈÛÜéb×Aµ½ˆíùÀª]ÐþÐŒªãžµÙEåÜè1iîÛK —µsw>½ÒnÒf ðg‰·Ö¤F±}ö£žÕ™sûÂOJ¹¤>û1ÏjlÑþñ 8ßÌ [|ñÔ×,Ö«œ†'ú×IâD_·( 7cšÀ–2:ÍR™‡nï^µ ÈÀ"®ÄÄûQä1õ4”É™08¨š,kNkWxǧz¥!ù ç¥Uû9<‚(§–!ˆ(_ЃEzÀ³“ßu"DAù¤žy5PÜ©ãŽø5<7‘¨ÎÁÏ­ ,ªºŒëJQq7Ö£{( ôΈf8ö HÉ"€C`vÔ(8B¡4Uqß4Ô Ç8â€.$ΉŒÊ,£Ž ûT[€R¾Y'Ôž) xÚ=F(ݶ þ½$žB©c'SDЦHÆIí^3Æhæ(r#ÚsÉZ†[t 6Èø=‰©Ñd`*ƒQ°1œ·Íì(¢ *¸9éÖ«í¸ …P´Í¼ ¤v¥Ø6rÀë@£K…^6yÎzSdó ¢†Ç?-i%ªya…Âsü!Oó¨eÝùH'Þ€3ž%8Søæ£ ÏË+D~ñ¿y·'ÖÚA»›¿Ý¦aòË =¹®RâFK™Šô lÑOáqÚÕÙ/Û)'̿քP”òjd”ÏZˆªšBŠ\SIºI´±õY¹Îjò8kE~n„ÐGái[÷Ð`a€®¤#æçºeóØ^¤ª~^Œ=Gzõ;$ßË·*qsRÀÍ“Hß6ìp¹íŠàüO(mJUQÀ5éßbŽ7߃¼Œ+ÉuöÝ«ÜõÿXÃõ¦€ÎO¿Rô¨W‡50 TSv©EE/J<ÐM%)  #?#qžA©ü§Š†>¤{SÜü¼Ð>BŠXÉ+M¸ibé@oºiÖýV˜çŠ–Ü|€,OǽU—•©ç ÉAU¤û¸ÍHœ¨®ƒÃR*ê«ãkeN}뎯ZJaU –ùþY-e#tO…'Ò³–$cÆEOq!º‘æQÝi¨ ž=)¶¡á¹R+Ð×Me £ýFkš\£eXçÖ·-ÜKnŽ>úúÐ_ŠB8ÆÓü뛓î~5½âFßs~OëX3€Fh@AŒæ–AˆO½ 2hŸ„¦y© êMASÛôc@)©F½iÀs@ìj$—¢5B:ÐΜ°²ž¢³u(Z; Äpx«zw2íõ÷©µ;bð•,94€Â4wŒŽ¢•‡Žj5m§Š`=x=þ•ÕÛIæ[&W'hï\®õ'‘W­ï±²0H=Ío`–ÂŒgךG%20w÷"«$òp ¨ìy©YA©>›©ad.™‘S«œ ª‘ê @‘„Só}A§ª2~t1nÀSKäöõ¥ @àŒýhlí9aùÐ=¯E¶Xå‚0qX¼×U«Û¬ºs2¹áŠåi€£ŠÔÑäÅà÷b²…\Ó¤X¯c.p¹ë@fóŽ5,!Éäâ œcoçS¢ØÇ=°i§jÄpG5jGààU[hŸšÐ…9j@U—v 5e!6ºîCÖ»œ3qíP¹CÐ=M$Ö§¡>bžÕŸ=„ƒ?#-jAtЕ@SÔzÔһ΅ãpTuQÚ€.xÙÆ¥pXç÷`~µ¯ãò¡Ç¥?áý¨’âæP{Mñü¨“‰äöõ£¨o/úÆíÍ@Ýjgž½j&˜ ߥ8SE8PÓY¤ûzºà}k(!ÎOëZ7 ¹Ûš¢@¦€gü´4íKütÞ€!lóM‹†"žÕpàšs®EZ…·GƒÍV—ïR@ØjGeȧ8ä0§Ì€®i‹óFG¥AŒJ}êx†I5TÔÊ6ÇÆ€ÛÞ¦¶®´*¸õ©íÁóg,9Åz~”¡™ðJ¨ã5ÑO G Ê‘Žkˆðàò!óæÝ–îMhÏâ8b›Ê‰Zwé´RM¦§ÙÜÇ“·µ7S‚õ˜›IcAßræ²ìµÆ ³ÄÀ\ñùÖ˜Ôcž}˜e>„by¬%Ü:‰{žC†ª¬ŒNWWâ¨Kƒé\Áž* G÷Jý 03žjXmY¾cÓÞ•ÂxõU•þ¢³æ¶É!“9î+XƤeX•ô¨Ì*NF}sšÅûöÜGÒŠÙ0çþZcÛ4PˆÙðK`TëµXcn{æ«™ò»B`gŠ‘¤þZK°œ‘q»Ìú¤nä;TƒËÛ–Z@[ŠxÂáÈb=)àŒþè1ôâ¨+r tÍYYÈÚAúв±³ýòÃÛ5/”œí|~µT\•è »ót†³™þx=×µy­¾¡$lŠõÕx{QH¯RvH6··¥&xv¡ ‚IîOJñ ]vðÓVþuëí(#”ýkÉüTë÷`t/ŸÎ’ FTÕB*j õ½*ZùS@ÓJm.r1@ ß§Ê~QÍ1O̽+œšSÊ{ÒÅÒƒœ£o€äÕˆWÎMX‰¶ƒì(”åɨ\dâ¤Îi@ ƒŠ™N D1NšÚ²¸’ UðJÆr+j{}Ñ‹ˆÇÈݱX¶ŽLJñë[ºn¦æ)Š”>ƒ¥ (“É«¶2¨“a݃ڧ¼¶ŠVóm†8èxªq¶ÓƒÁ”W^éHq¶°®:šèuBàç#ÏNAã â„h=i“÷ô©⣔ü¦˜1É«ÿpÕ|š³o÷ J4´sš\äãµ)ÿVjÖ¬°ýÝ@¼·rØíprG5¨ñ¤‘žX·­eÃZq¿îÁ,zcRœ• K"±$ƒùÔ,¸­MB܉ZUS°õ8ïY»ZGÚ€Ÿ¥0ϵI_0`ž¼S1Ž1ÍOiù 銾ç=¾´ôqž•¦ÁàRN;­¸ü*Â\FÀåpk#9 â§óÎN(][Ðu¥ùûÕ®J‚˜]|Ô;gi F1ÈÍrÚÒ\ÊBFªªpMtÇd±°¨®BT1ÊèÝA"€#ìàäH)E05­ufXÖ9# G‡S] €œƒž@Írúdi%⮾&é´ zRVУ4ùÎ3ŸÊ–ÕÆÁòô¦Nä“€)P‚W+Lhû½Jäœc¥FH îa@¼d(9ÈúÓ¡Äû‡QÖŒ€O9ö¥Œuë@›ðõ":eÔÊ›s&?ýUÈøúo7VbÀÚx>3„Sc±®ÆN¦Äp»}i-ÀãØ Þ tæ­¶j9ª±S—©°t §ŠdÜ!=xÅgíÏAZLÁ£9ª™ÏA@ÈýáëI×4ù8œý)£©¦/QŒg w©¤èjë@H2´ÈΩ›îý*ÁÅ]2f ÆÙ>µ$-ò‘š$h…åÍ!<õ©ʃéPg“žÔ!|t5¥¤Â./Q\VPï[zƒ¨ÆI /'±®ÜÿgY¤ òÈÿtg õ«>Ò÷Cö‰‹ ެKÙ?¶|LWv"RŸA]’jº}”il'LŒ äš. †6nÏ^µÐ¼j-#’@2£9Å`Ú¥¸FÇ¿5¹¨öLË#FÀpV~¹¬iú‹m¤f‘ÍÆ¬µ‰Hé“LšäÏrí4&S‚ê»wzµep›ö² z‘L2˜` xÍUipzU›ÉCI…#éUŒ`®I Êq¸f“nGÍ‘ïOrpÃñ¥<ƒÓµA°ún÷Í6Ä<ï_ÄQ@×+óçÜf¦,U1½·ÿ³PHUÛ ÀúÓÕp½zz `=J e˜‘SùðÈ·|ÕS0'fœ!‘q¸½q@’XHùHØSVP‹€F}ªGÌN?JE0h zРà§ÞÇ|b§YQ>lþUWÊsÈ­XHÝ#ÁÇãH-ÆæÊ†#¾EYYA@2׎µTÈüEðàç©  âhŠí FEFeDbÛ[wcU°TT¿¼)“+Üìñù¨øÔPðÄþtGy+çËO—Ö³D¡Sj¿ìÕ¥¹ÛÔ+ô  þÓ)]‚<äô•cË÷ õäRè˜xIï[&Þ+óuõ¤r\º RÌqëNirzã=M[‚CÇëA°À$0òh2ú]Ѭ`ä¯9Åc6IÎjôÄÉ4½ÀàU'\1ÐyëL|§šxÈâšàì4ÀÏ=NjÅ¿ ŒÔÚ–ßïí@y§(Î0iµ4c9 qІ5äÔ²zRF(eï]ƒgÒË=Ô»m Á(ùˆôö®|TŠK#&â7 @ix—X³¾[iöPÚ[Â1¹X³Kþök$†ÞÕ™ÕÚW\p½DÈR@_AüêY®–U1Û¡:94@œwÍZ³RÎßJj[®ì¶I«q¢"áHÀHàä÷¤Xó’>µ"·Q×Þ”¶G#š@ L÷÷§…ºæš¿˜§ìhG\â—'éIÎ~SF[ÓŠzNêN+3SLÍç>~£Þ¯™pqÍT½),!åy  ÜÓ”dõ¦Í=FzqL M:#ÑOæ!°W¸®ÅP þ5ÆXʈÛ$f?…zèloU[É3ïA±üé0: (@4K“ïPÛÈ à­Xyßz@Sè*»dò« NârjNp˃×4f'‘ÇÒž§Ôãð£k¡ê1õ¥Q–^§Šö 6ƒÂö(F—ŸÎ¼ïÅ¥SP™dbIå=«Óù:U²±á`ʼw^•çÕ¦f9çƒíIÃŽ*ïš°r@ÙªÁÁ4Öži 4Y׆ǥ1"Ç$ÔädqMÇZ̹ÿ–úTG¯_Ò¥ºÿ“Š‹&˜ ~¨©«.2:ÕTÎò(Çðã5 úÕÈ?J„ä5>†ëÖ¬‘•ÅSSµªÚ·  ÁÁïP¸*ÄU‡ã‘Ò¢œd«zГé],vóÉ#°Œã=ë%ËVµ…³ÜLv‚qéHŽ1æ´Ž¸f$“V-&ŽÞìHð T»Þ¤¸…ál?Þ¨cŸÈ”HW uÕG5ŒÁeK›ˆGuqÒ¶óm.ã¾¶#”?xV޳§¼A—a#ª0­hõM2HÙ ýĽ×7O ³—ÉŒ“Ê‘ÐÒ ·O˜KúQ*\ŅCTÊ8QŠ`Z;·æŒÇÜúU’BŠTÒœy  „~tãîªqU_,eä=ÍQ—UË”I¶©þ*Ô’Tó¼j}(®qžbZBO©4PT±[(*Ì >ZwÙòùUlv5mÚcPÈ»{ïQIF„ûR/%€û¹¨%ýÞIÃ7O¥\’Vhƒqз5¢Ê2ÑóޤÐ5¥ÆJã¾zÕ,n|íì*X Vbx8ìŸöi·Ú¾üf€"VÀ;WƒÈâ£ff`I<J¼c@ry tÏJ’3n#ï“ØÐ_(”,A>Ù¢8ÿƒ`Ç^MM1Oº {ƒÍFÀCqÁçšµmýàÆ=j)V n;ã‘‘I‚…YN}M1¤>8ÛÛ4,–Ñ¢mLdúÕaf#$’§ñ§¸'$©úç­.ØŠlx SÌûÝð*´ðZ¡ÿXw{ œJ",ÝÀ¦ù²Hså"ãûçšd@˸Éò¯·4Œ–ˆpMÀõSš™¢i"ÎÝÀz jZ«JˆÔvÏZ$¸w;NÕÏñc5n%E%¼½ÎzäšËTpAתÞÔeÀN£ï1é@ 1Nø©÷bqšá¼I`lõáƒ$¿6GL÷®å#(¸ß…Ïnk3^²[Ý9‚dæ_—Šh;Ó×¥0Œ;ŠpãŠ`LµÁÏCÍh…\nÈ ô¬œþ5z ÒCÇQÇZÝÐfòuhI8V;OãYþ$²†Þ'‡ õÈeh6¹#p#Òø¶f}N)ø ñ)8¤[å ”dŠY# c‘‘šhG^GåL*´µpMAÎO9®ƒÃŸmÔ&C2[ÈÊ¿Þ8Çõ¬#xœ¬ˆÈÀà† ”ÊsM Š)V€ýjAÓ¨¨ñÍ=zP‹õ©?>ÔðzÐÝqšãG~”„ŒPŸ¨¥ž´Õù¿:(sÃ¥LÒÆÍ‚W"º •ÁÇŠäôwß©$ƒÓšèõÚ¬O®V pIÛ“íUn¥òábÌF9¨Í̤çíUï'-lr„S@?–­Ï&ªrzóO™‰ni€æ€zkœŽ´î4‘Š`Q”aÍ:Ü€ç?Ý¢qÍ6¼~”mrO&¦Î¨—¥H>”c9Í9WŽ´ž´áÓ8â Ðu§ÄØpsNŽÎyŽ&ú‘в4«„Á} zÐ]Þ^N9•$chëùW@mÒDÈ86™·%9Ô¿ï9@éøÓžÑ•$}iÛ'“ùPÀcŠS)<ÔÂÖ09æÂIÆ€#‘Ò‘§b8ÀÇ¥XXÔ.vƒJ#@s劦%9ëOÄcòàã àV´k ‡œãÔ±5Èi’„ ÎøÖ·­§GFe”dvŠ‘Ç•òsÏRM5¶ãˆ£üFj—ÛZÉ`ÄsÍLu+I°œ7ÐRRûO àµ4"V¹„6»ÀµΛCÉ‹qV4Pº–»iÒl½8 OÔ¤ÛnnÀØéÅy&·mö{éÜ|ÜW¤ßÊí/ÌxŠâ|X›.œeòGÒ’—9Áæ lóV[¥W~æ¨sŠ:ÐÔ€ñ@ aÁæ£ØG|ÔøÎ?J‚hèbèý*×­Z¿nϪ¡#4Às}Ì÷QOïM\੪c‰zP±íPÈnµ(9#ŠdÞ¼PHàÔñŸ’ R v©bo”ŠœŽMFã1‘éJ½M)äHWšíü ie` Šãaq]¨%µ£Gæb}3Hª÷L‚ñ÷Ÿ”÷#½f_è–q[¼†ô¤›*ä9osÀªÒ\½Ënrqô¤:Xy/¹NG¸­›GÖ¦£wæž!¿4ÀÊö?­Gómääj™—h9 : %¸g<ŒUY¯ aŠã×TRÊÎ:íJξ¸% c”—33»nç¡ô«’‹k£¾ 6çZÂrL'7Y]ìn]pPâ Ž¸ü(«1Z]ÄuÀàT‹±Ÿ3Œvz„Üí$ Ô*LB’ˆGÔ kÉæa]F=úÔ+;nŒƒŸÊ‰e(ÀƒŒ÷4(‰ù zw©ËA…cϨªrA;ߎ0¢•CIv¾?Úz²Y£Ê}½jQr1°œ{U&¶ÀzµBbÙ.X³þÑ  y`aO”†ïyÚ¯^8br~ðüM:d·UÚ¦`G÷XŒÐ'¬Ù›kÆp»RO˜Vq<ñ]>¹kæéªSy1 …nN;×$¯Ï9ª@J>_sR,’'GÆ}©ò8¤ç9äâ€-Å<ÆUX})Ú´†òO4‘€튒Ë '…î}j+Ëuƒ3µúgÖÙ,7sš“i*M5—i8zƒ´c“L zF¡&™©Ãr‡œwésÉý­n"¹ÑšhßÍ´uïœ×•„ÔŠït¯,M²yaäEÚç=1íI€ëÏÙÙi÷:ôWvð¬[¢Mà’[€G­pÙ,_83ÿí ­{M×ö¦¿áÛU{Ø¢Óxr€îÈ }½+ÊüE;IpîÈ]Ø/LNh@`oJ âæ1á‰4/'Š` BóÅ:@vtÍ$cŒÐŒÃJ‡ ÒTŠj«ÍHéMsíB‚Çž• ”ŠpéH9íNkO}—ˆszÝw!-X{…Êíü3[b¿xú)a ,ÄñÚ¢ºmÛ9ÇÒ¢9ª1'®!á”±ÇzÇ`wŸZpíM¸¥ÎÝù¢y¤F#“í@0i•nÖÚKÔ- näu ¹©Žt0È?à€1®ŒÔÚM£Þ]´H%^‚­I`ÀícÀR9«vŸ5Ñ•ÃlÚGËÖ˜^'‚àÛ¿,:š·bÚzÝbýäòÁÆr]J$È'®EM§éðÝÅ/š@nÄö¤£xsIð•ê+An²¿ý4l×U&…¦}˜Â¶P¢0è¨+Âlå¿ÑõÖå·!þAéZ7Ä[CME9TsÆsI 5dž,¾ÐÂDpÀ Ú±u½û7 ‡| qÈäz·sñÕÜ‹H]½…P¼×Íêþõ‰QÎÕœ– ý þ¯¦0áFOÒ¬ õrƪ1ÕªÒ̆òxâ€9ùôIn+ÛÖ³æÐnâO0Wõ®Ù@Qó&Héžõ ²B#mêª Á‹À›G\ïp§=é« dö®®ê8’¨‡>Õ“%¨Aþ« ÷˜¢ÝW–ÈúPÉ(ÎHö«RBqµTÅ!è2 E”f;@À©X£}ÕǸ¨š9ä:J°à~”ŽÜpsøTd?Ö¦1€9pqÚ¡rr9 ª•çpojnÜt"”rF8)HÎGŠˆ 9Èã¿zrÚÄÙ!jEÀl“Œãc@ #$ÇÓ¥]ŽŽ3å±õªÈpx« +M4¬€X~tÍåz¡Ïb)ì݆x¦Ô¿l¸UÛ½±é]—Ã×:ä²2ªˆœýkŠ`JŒ“šôo†l³¿¸9$²¢æ“¬“Í%ûá|^Ù½‡‚&@?ZîÖÜÍxAè9®/Ç6¤˜+€€½© 9x5 Ž*F$7µDÍ“T,zÔjy©œÓT|ß6(SÀÆ3OQòÓWNié–`(R»Ç*“ÐÖLfüV\úÖs})€õ9R*™â_Æ­¥T”bC@ˆÁ¦¿+OS˜”‘L9 õ ãn Ô±ðH5\>*uÎELçN Ú›ÎiÞhýë[LPñ;ÖZ!vA$Öå…±Š>¸=ù¤…ŒŒàf¥Hàå}iÊÀðzSÃF4€•cÚ9ÃÞœcùzS¢'ÝãÖ¡»¾[X°Ä“Ð(îhµÌçÕžÊÒ±fä{S..òÝX‚zúTmpÝIŒué^êBÎsÀô¬é>lòjI™ŽæÉúÕs’ô¦†ŒGÛZ—Äö‚+ß5GÊãõªºwË2žAÎ+¤Öm¾Ó§©ÆHZ@q+!Q€ÄQC&Ö ©ÏµÀô%,tÏü ˜ÎŒq“Ö™æåw>‹UZ@ÌIoZ,±\Š£=ê68`3»ô¦Ç;€rE/Ú•¹Úy¦¾oË·`ùÓ|òŒ©>™¨Ë/DaùñU™›;Wúš²óÍ òíÍ(¹ ‚aUv6à“ô'š8RÇj¶/X ãó©ïsŒÃ¸"²÷î`YªhË å}Ú€7£¿·H¿ÕíoöES–ù³Œ÷¬É¦“fЊzõ5[´¢+FÕÏp3M*êre,=j†•Oú zU­ècùÜgµ ªîGÁèIÅ9V7p/ š"`ÄÈÄp*b²`#œ´€E…O™´ü˜9Â㚇ìî…€fàñÏn4VMÁvƒÆìÿJtvø««PxŒäXý5"•BHBG½kÆbÏÌñPË·"ŒÜÐB¾`Úb÷â¢e™Q¼¸˜úV¬QÆÌ `j¾¶–æÒ\ÇcîÍr(“¼lIŸk˜Öt¦ÓîÊõFäØúW§%¬%LÎ ×­ej±é÷ò[ùC’î܃Này¦ÜSÐ9çvîÙ­d10èx>¢ªãŸ½L V÷ |‡‘Ú§žX.b1ÚÊr­Yœ+‚=êüb-™nsÞ€+I¶°àóšhP$U‹®!Œ ñUPüÇ¿¸ÜÛG :š‘¯š8ŒAzƒž”‹œ{TK檩l銛ûVøÃäý²a÷?*¬‘Éq(HÕ¤‘rM"F\áq“ëV`v)q²:ƒŠî|3à[&UŸX“ÌcÈ·C€>§½v¾‡¥IáÉìⱆ8–MŠVƒšÁеÛmNyŽáGÏíî=«[QºéÒ³«°ó×µH6Ë”+žED§êMà³sÁ’NãnÅÊžAéUÖ‹!ןOz†Aöè— N#*ͪAl¥Y7yÍ< X° Eà)\šÛÒ“Nº¸ò™’8ÏÖ~¡¦G=Ù)#©ÁSÞ¦Ë µÀšmຟέjé*]¬±ÝÈ3:š@f ³År}ºS¤8ç¡ö©ó"§Í»Z¯4™\`b€& ò’û÷ Èù”ŒzT0±YU jb]Øoqé@Vî`¸“é“RÇt0RU »¿Z¨Èw ri ŽÎ9ì(OË¢Ú\w¤Y#Ž2¹%‡r+$JK¹°;Pó0\«hãDÊ8óéÍS¸³)’Œt¹Ÿ9,ÜÓÅä˜9 L …B° IíLdrÃ`«^ãvÕè:Ž+>y$L‚2ç@6 ò1ÅDö‡=‡4‘^¦Hg*{}h3n$–É ½¿”ÙSœËò¨š< ƒÏ°©–ä‚€ZŒº’p1ô ðÝH§‘Ò¥ny<ûÔŸ(äP0ÿõÔˆçûÕ0ËÛ4ñ·AÏn(³7|Šnïz­ö¨þÌí0È1Áê ÔÉ¢Þô›Ê¼©âÛÆ+Ö¾åtk£É"~~˜¤Àë K[K«—ؽëɵ{ƒwzÒg¨¯Iñ¾¡–ŽmÑ€yyW$äœÒ@WhÆ*»ÇWX~• Áª“&*´ÒùL8ÈïVäaÜóYÏt¬åYr3Š–Õ*~µ~ß *àÕ É=êì&ÞÖéRg$‘Æ;ÈÖ7i¶ãÎQo»Wµ‡Y56)ÈÀªL>SL¡Á¨nSt#Àï@ƒ˜¸õ¡¦Û‘´Š|ƒå4õÈëRÆw(5-:#ϱ  |½ië÷iƒŒÓ—ó÷  :TòIö­Uˆ°µRÒ= Ãí`{šÑU”/ÞSïHXp~nIüiåm¸üi_Èü*`@ÏâiÉdò!Î~cÀa¾g¸.Ç%sùÓ¯u.ð p)¾dKó>ni*Ù›¢ª½zÖŠb–P3ÔŽ+zäGùN8ê*®ª‰4JÐFyšÉ* +’Õät©1²†ÖM¬Tôê=ébÌ"ŸC]‚þ÷NŒ‘À8 W%h0NzêôþÊHóÁéìiË_Y…ºaŒÃWC%°‘˸úÑEÀo¤œ¨½#YÇÃãÚ”•8.Ù=Hƒ(lg8íí@ HI`NGLŠ´,دU?tÕy70o#qÖ˜ŠÈNàr{æ€ ÒHÝ“cƒÅDŒïŸzºvqœã“ëU¥Üàô#Í*ÜØ œñҚʭò€7ÎiÉ€œ&XsÁÁÝèY‰,{Ðöðûèp{æœèªwlvÚjºÍרqÛ4ñ1 >BßZIXO¥Wy’;㊚GY@]‡=ê0„aB•ôâ°>”Ýà±ÆåÁQO”2ãŒTkÁ!¶Ž8$Pâ›c‚wj¾—Ð8û§qïéT ‘ˆÁ$3ç­Fò+cªãÒ€6Ḋ6Ìr’݆:Tži*]ÈÎqÅeD±•Q`3‚:Tᤋ¾^ø=èüw ägpÐUå•YU209çŠÈŽòOº¡XNjÊÈ» ÿtÒq:¡;XõÈÇ­ <»äsžäT$gæ°=;U‹)Qî#îÁät  šƒùzX Ä3ôZç„2Èß6p=kwQºŠiÖ2€íïéRÁj¤«JoûÝEqzý®ÈAƒØâ¹ÝŒSpÕèþ$²X9X6¢ŒŒßZáR4OºÂš{Tö¤‡(zSçŠnV½58 ñL ’Â.v¸ÀàƒU$€ÛÜ2­_|ÝÍ:{e˜ï,FÑÈ“H í™W#8š¨Ñ=0+qmwÀæÙTcænrkzÛGS¥(šÍ°œ‘EÀàð3Þ´-o0¢)XŸçVõMÛÜ ~íÔ2OZÏ63g•Å0:ybŽdkwÚýˆÖ´/5©ïlÒO,©êÀrEs6i-¹ùŽSÐÖÔ>DêxÁî)œú|Cycçše¹bÙZèɱÜs’iÆ0G˜3ès@ÐÒòOïp=ÅShÂ9PÛ±]}ÌQÛióJÁ@UÀÉäžÕÆdŽh@_°Eß–溻«xfÐm¤A‰Ê·Óµq–÷68ï[0êR½¸„t$ PSîjUr¨0~¼ÕûÛ†0<°0;ÖZ—ü¨ßÚ)ëê3Köç |qUÔdŒã¬0våô  +-N{'Ä\,‹µ†îzU¾g'åA“À«(ï+ׯjv_ŽôµÚ…Û¸}Òc%sAY §®zS$)Ê““ëÍnª‰3·k'¡<šé‘lÜê«ÆFO&°#šd8'ŸaV’äÿrsßhE¡.À¤¬¬Nõ’†‘‹ö< †+£¸|¹ÉíS5±%à‚)É‹G{î9¦´˜LFzÕ¨‘@FÎ}{ÒOsŽAÖ€*ÏT'> ô®‚o´½²I—‹øš±£´*9$ÐÕý)Ú+ÿ)ˆ) ÁÏJ¡#±vRÿˆ=j\Ž_´ïô‹¨.\¢©FÉ{¥f2»HT©R:©¦¢dA ¼XYUÛš¨±7ñ+ ú xÜ€Œ6Ú±#à…98È¥’9B¨7árF@äf¥IC“Ÿ©¤ c„*O­DîåïÍ[+)f¡rÈ úf˜%vÁÀã¾BÚIÎ}sZl»˜,•=MVx0äv÷ £ç½3Üþu!G#€˜ü ¹$Ð[‹å‚k=í¥ˆ‘É÷¬¹c†ÎÓíR ~;úÐ g\Æš."¶eÓ’q~n¹qc$$’ é@}¨þñ8õ5Wž)CPÕ›Þ­Gváý+1\ŸJxÏbhWí¤·=èûb’r™¬’X¦›æ°ï@và^Ý$# »«7Aõ®ÊÓWÃvmg¦Ü™‹Ï)]£>ÕÄxrf:ýš±áœÅ{3XÙ\Û0¹µAåŽX( ŠL7¿Ôî¯$3\HÎ{¬ç¼#8×G­I¥[HÑÛYŽìÄʹ©å–sòZB£¶ #ûcvÓ–ä7U4±ÄàfDŒ})“ÈT•0‘$í;š£Ĥ•äÕ+‹Ëȳ…T¿zÊ–æâc—v?ZÛ¸½X!>BnoQÐVM$’™¾b}iÐ^ËlÇ€Aê¡§††br… ô昼†Iw7&—øM1†$ÁíßñÐó@ –™'Ý©vñŽÕŸwÒ€ýjFïL¯iÍÒ€"¡8?JLõæœ=J²:R¯µ>^f lîz*Œšì´†ºÞ°UçŒYÛžwK÷¿Jàeh $Y‚GJÛ*Jížâ´5 Gá‹„¶¶•™]rYÇ$ÖhRI$œÒU~S•‡½C$Œ±·ñ1àTk«Z¥ËÛ>QÐãst55Ày#D98ϵs7vû¤CÆr+>I]>SšÞ·€—d~ù «y¦6Ðê2ëL tÃf¶lïÉ…áu ¸ Û’`(Ý*Ô)ŽGZŽ÷þ>´Õ`9+÷Oô«W1†‰\(ëÍR‰ö9í@ n3לú×Q¡Ž©×#¥rãUá~Þ†º= Ü\ŒzÇŠ»'î¥u ŒE7WœG~UX¨Ú8R¿b‹jîb8å}(Û ä°~í5¤Æ9PMUžIcïÁêq@^dP@Üqùb£IFÖc¿Â1ÍWITŒgœwëC\¢®9'éLÉ3°ÀÇCš…¼À>y õ¤óã,2¨ÇZŠGMØÉ Ú€$R›²ÜQRº}á‹1Ȫ«À$‘OI$%_Çj¹±ÕT•>µ `»€ÐÕ?µ=¹ãµDfÛ’0sÓ4`ɇÉÜïG˜äT‘Ú YOQŸjÊÍÓõ 36òÊЊ;õy=²iႌ±ÜßZ‘n]¤ŒP#´b~a´w©`N¼€ñBÞ*±Ü¤Š½o{rNÒqÇ\ŠªðËoò¬-‚z÷5ŠI#gØÙÞç5}®U~mŠÍœõ«pyw0àö p("ÚÞo,äìç 3S+,¬ßŽ8©ï¬e‹%æ%p1Y_20@õ  ¢U±çÐ ÔÚ}Â¥ÓÙU\¶êή6AàƒVaM›T.]úë@™ã’é[ [#µÉáo!Àƒx²ØÞgµxä0`F*øŠ[•†x¥{‰FQAǧÐRE®ÌÐ4O#2°Û€:žÂ¼çP·’Êúhe£eb ž«í_CøÀ¢oí+æ¥ ƒ1û±Žû}ýëÊþ,Xé1x¢ItVYÌ@sózƒïBzÁŒž„fœ3Þ«‚AèjQ'¨ªü| f¶4äûDÁv8èk'K†)îTK÷;ŒÕ¨î>ˬƒm\í9‡Ìhà "©ÎàVØ•Pr1Ú³l‹Íp ±aŒóÞ­È»TäG§j@gj–k/'a9ÐÖ`°2“µ×ýÓÖB9¹#8QÏçP«5¼cd »¹.s@ &ž"%_o¥6qƨvŸâ4߷ܳ°”e[³ýj"# XLŠÞ™¦ÒH°ò¡Ž:‚8ÅE.©j°ÊÁ½JŠf?gå‹!èÁj“D’m IP9§|·6ñƃ¡Ï\ÖI­° r£犬leWû¥ôâ˜($åGºMÈÍ-± íÝ“ôªVÖ£f6‘šÑšÕÑ”åPä Ò¬Ô­Òæàò;W-4RC3,kŒqÁ®˜Ì“Ú¬‘üÁÇùÍs÷E‘ØãæÏ<Ѐ¥‡ÞÞü d‘ÉZwœ2w©9ïÒ•UX1S÷… ,zzt£qtŸÃ®)Z%p§'ø§*\îúñ@X`ç¯Ö”FÊOR=éÛŠ’`SÁÂnžœÐw#}jN¤àãÖlzž*dW'.zPl] z\ȸèÜzS™ŽÅD `‚¼ÿ*µþ`Ï9‚¦RìûÕŽ>µR#òàÈõÅLwŒðhñšELÔ‘Nþr¸L`‚*šÍ$}cëS-Öìï\zÅz«Ã¨ØÅ8Û¸Ž}qUo4¨.S0®Oñ¬Ï]G%¬¶Á™Y2G8$ªú¥Ô2¤ï…cò¹ÝŠ@Auk%µÃFåFðš€ÄzϾÚWžK™ZIO¥Y‹hŒïÏÌ1žâ€*›d ã=@ëQÉl‹ÕïPjØH•°Ï½+G ¨¢€"…'Ê{Ó$…vår¤œ`а…b#!@«%„‘|ª ë×¥f¥³¬ešBz¯,9-Ïj×~Tp™úÒ€Œ:7^‹@m w œzTE_t'=0+bx“ b!è*! 0àŒúzPX\€±¥Ëàœþu}ídt$€0}y¨~ÎT€ry¦dónɧgÌaÛ“š¢S÷?Êj n!¾™  Ë6'¯ÊÞÕ•-œ°žFáê+­dz;ÇN˜¨<…fÀï@˜ãÚœ»s££îd;Xút¬¹´ëˆ +ê:P_§4Â:óÅK°÷Ϧ…¹9;˜šÎVàsOW9ÀÍ^WBIÝßJd.>öyíUb•|Çœç8æ¤ûF3°’=hb¿9;ñŽ©¬½2ÊIéLY**Uuû¾^쎹 ¼³žN•aE%dSêzÐãkp6ƒß,L~lœwÍ5vB škF7áü:T‡aœõ§(Á=0CÆ~éúS•$ ׌t¥fUä–'Ôrƒç¡è FÐ0<.Ù4²ÛXsëS€€O×™^~î}è¹A»å*qÚ…T¾@Áõ«é r\.îøÍU1¼lÇ*TqÓštn‘/É€Þã9©ÛP—nLب^ $6òH¿*r~ëÀ«±éð”`[,>öÞhŒRµÄ<…ºdÒ\[4r„o”ã9Î:¶!®Ñ¹3ü\tú Œ"mÞ[-ïH´ÓÌÓ¨C¿ýÞÕáà¿f-³iÊñßµné%¼—’~P*•ͦùY®eUW<н‹íõ?Üøš×Îh‡îæ@‡ÐÜVݶµámîÞêvóžXx÷n1úþ=½«€¹²aò«y蜩û¬±®~†Üz¬ˆA¢Àz'>1\êÀØèÑ+×hPp[ëŠòéï'¹•¤–BÌy&˜ÑNHǵDÄ/©4Ò°i ž{zRO;OåHŒÍ£ò©6KŽø¦›U“ÌP äŸZ·5¼¶²¬²²†ÎBŽMS¶R’+4ˆ æº4‚ Whó•v ’x€ÚÒ&2F» Ãæ­ÝIÆÀÍóuÛéT¬m"¶u]àtØAçޮ݋ˆ•'x‚†î§“H £óKåF é×j FˆaòqÔ H“ùq>V';ÏZŽ9É‹—ŒŸz­mdw2nUÇzÔ&ÎÑSýV\t.qVâ»ü¾[:‘ÓÞªM Ì:‚¹õë@/`.àù‡ <ÿ*§ä”~p~•¶ Æ¿2’ݲsÇÒ q²ä¦}»ÓÎÃ*kq€äN¶>À¬£j€½ËsQKbâ4N PxÂÊÓŸLÔøÜŒP±ès‚>”Ù-”ž2¿Z‰ v oÝøÐæ…><Ûi2vüÊ¿Îcq1äšÏÒ#š;ôc¸5¥xD9hë‘H )bCÓÇ¥DÈq…99⦖5É=8¨U°Ù“ëLc®1ØSÒcÑ•pzHÇ#­3–rq‘ëé@0˧ü¨°;€ÔšÆG¦™e=…L’"¦2w}:Ô{Ê¿Vö9éLo39+;ÔáœnîhžBÜœœc¥H޽YAžXcÔâ‘ £c‚ǃí@1ïùN8ÅJ²nG¶j!h 'Ó© Ø0‰ƒ×é@ ¨I.9ëRË ÙtëP“Ø|gµ"ë‚O×¥¥LlïRC½‰ùB¯½[ÖmÄwhÛ íëX¡ä €ûXwÍušO—¥Ç ÆÙJuçéš@s~qÜ6®1ÍJ×Ò:aŽÙºKØ4ë(|qÆ:çÚ¹™A`X /ažhÇœÉÆi#,8 Ïš­pÃ*6ý3Š]»HaÇ=Ei¤Î«ó( ‚¥ûZ·@N1YðÜm:†©ê9• wÀâ€47£¶àSŸlSJüÙP úƒUã’gžõd9]…zƒ@ UbÇ~i¦5brN}©&-Œ¬Ÿ7¡¦ÄÒ ,¬¸>ƒ¥ýfÖR£¦zÓö!%ºó¸Št—#iÉBÀ ñMäÏPF `B­¸äŸQBÚ‚¬»ªâ@6d& ïœÒ3˜ºçÀ  ‹b|²‡=3LM9ä9AÈàäô­åURØÝž«Þ¤…°Äªœž¾ôœ,fᣠƒPÉlê¸U#wÞšÝv|²0aÜqT牥)´àzw zm&6]Û°ýÆ:ÖMÄRC‘°õõ®¹­dWÁúŒÓ>̬­„¾{c4ÃI0Çz…±­È]¼Þñôn+çñgäB£ `rò(E$h°Ê6à;VÃh×H ÀÇz‹û6aóü@  Kʘ5E%¹L©5~KyðὪœË*ðÛ¿@G÷ÿ:± lC3U¶ÈGÜ$R#îö¦’êsG!pHÏ\÷­[-Qg Áúô®`O9úTÐí ËøR¶{œ›ö¤LISϦ1T4ëÛcn©2æUïž«3ê¶v¹,ÃrŒìS“H ¤Óc•?z#¿5Ëêz}´¿‘)fA–?5ÞÞ)‰C~êõüMd’Ã=irÞêÚ® ýpjÜÍ’­‡n¹ Ã/¾{ŠÆ‘&Ù"óê*H§’;“û¦˜¤2I|èAáÓªŸzb,öã|&‹ºÿõªH¦Gmñ1I;ã¯ÿ^•±»s~éÿ碔ýE Å­ÖvŸ"OBr¦£-sfv·({A©åXÜbæ0­ÚTgúE²ðDПƘÇCåIèzLÜÙœd…?ˆ4yP\sòßû§¥ –âÛäe="€,Ú.îPÙ 9ùzë-¡,TR:ÀÑ£·–w¸U)´m ôϵlÞI#„H±€1Ÿz@6÷P!À‰UqßÞ±ç–Ie9êÝ…[û+àn%KÿZGX•þ\äúö  ñÚÀ±œw«ënZ ~˜¬ó.7¯ڿ˜6î ×oMRtØÄT&cÏz»s©`GÌ*º1eaøP|M²\™­ —ûM–Ârë†SY’|­‘ëSA.æ€%ŽïrQT$VY.qœñE04ùÆ:ý)v‘Ÿ~”QHÜ;ñjvò_Š(U—l¹ôéS‰IàzÑE8318R–)NNLQE<¶ìáB­IbpÍÓŠ(n,ç· É b{b 2O3ÕŽ(¢€A.F ç¿•;xßó $t\J(  ã•–=»A9ÎÜâ `Ø;ŽìžPÊÉ–$Ù©s„ÀvSE‰û¦ùØàóšœ| 4QH ©³k£F‘ ®z‘Ú°'bpÌåñÜžôQB5öóœ{õ©>Ê׫ƒlŒ­ÑžŠ)žQ“ÊA‚k&ëJç! ÑEUþÅuRß8¬[x|\"FÊŒxPË]-CÚØ*ƒ’àdÕƒggk¿Ï-!èª8ÇÖŠ(ÄZ’ZD#µ„'÷‹sšõ›Ò64¬Wû¦Š(1¨ËÜ*ÐÔe¸nUUxjqøÑE<]S†\ãnÇ,r¶Ö`ÛOû4QH4|—$ãÓÒ£òË8 rGàh¢€'ŽIÌBŽ8ïMóYœ[½Pd‘Y@ÿ yòÑ)óÝ¢Š’8d@—!Ù_pÚ¥kÇ›’»XÔQEeê6%ùv㯑öURCœðÀð? (  %°‘ÁÈǦ*¢¤‹# :ôQL v!¹íéAEÚp6zQE9UJ…ùùô©g6[ÓQ@um»xäúÓHQÁïߥP‚n’Ùäç5.ÐßÆÛ»ÑE*§øwzs¨€ 6õ<œ ( ï6YpqךÝðô¢ ¶Æß0|¹õQH ZÔ{ŠŸ83»;VC"åG–ý94Q@ 0•&óžÞ´Gk"‚ÃvÞùíE‚ÙÉÊnz‡ÿ²ÈŠC÷äQE7Èé–AžÄœÔѬQ€Z|àQEZ­wHû•ºdr*Â5äÉÎ:š( ™,ƒ’ª_ŒTKsl²`aô4Q@EìQ.UIøM#ê°í#쀒:ƒEöŠ¿"$RLº«${cÛÓ¡Q@ £pÄâ5¥–ægÀÞ­P ÝÖ†`@Ä*§ŸpTŸ1óžÝ¨¢€³HϲYdïš'R_?Z(  3A!pUÛúSÐËÚÀ9ÇqÖŠ(ë$RŸžÝr:œU{‹ i" ¸ëÅPEŠÏ5#ÜUYôËvõl>œŠ(  Z:¸T¤÷k*]:âÞUVe 䃞íS-î¢)åJ ›óÁÿ ŠâÎXAqó¡ç=MSž;ÊŠÃ)lô(¢€&‘ÓÉ#1ä±éQ%ðÇ\ŸJ( ±õ«ݲq Ü=h¢€'Ff&àõR2 &0ß»&'þéû¦Š)ÇŽ9¡‰ÏF ¦€"ùÑzÑE06t˜Ñ£Äcj6XœdŠ×U#* m#Œö¢Š@6hžLä㹬‰£3‘×=½(¢€)HØ$\Ó­î6Ê£¶sE±¼OÜpFOÖ³Yv1úÑEg\ƒ¼ñšd}=袘 ë¹³ÅQ@ÿÙtango-9.2.5a/doc/src/dance/tg_argentine.jpg0000644023471100065110000010173213034745265015521 00000000000000ÿØÿàJFIFÿþ>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ,"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?O[$zü122“ÃéZ¾>™—Âד*FÑÈ ®@`ãÕeY·s³h'!G±­ŸÁš”jp@ãFúW›}&{^ãhãõXÿÂmq›öùLYù†G$ý p:æ´u„°_%c¶Ë s¸Ž¤ñÔÖk gŠˆ) H9È5ݨè:¤ÜÝÙÒEr4°¯n…Õ å°çð'5鑸–Íüª ™CZÜY2¢ž~||£ë“^ck¨Ç>ƒ=œ‘D&\°v\ç§CØõ¬wy˜·°;¶ƒÇ×`¤ÓTå‹Vܱ§ãíyoõ×éÃ÷cýÁüëÒÏúa‘·­vxÂ÷oOcŠ»/Ïfš„-m$ËümcŽ[9ž98ÏxŽ[Ïø–Ydµòg-å( /˜ƒi Ó‚:ël¬m5 ͽû*Û•,Iõ#¸ïŠÒ±ŠËÌZ]‰kb£uÉm‘œäõïÇ~ljt¥Ê•ØQ~éÎZè:¾…¥ÏwHn~Uû=ÇîÊ€IüÇJ«²YjÖÑ]î’Â%g!º•=›÷ÿ×[޲¶wPXSfؾl‡äg8?Ò°…èÔ¯^)î"¶H”É‚€–lr2qÉ>þž•Ï Öš\å¶hx‚ÚÖþ(õ;}§¹|ÇvÊüÇ vük[QÚ$±Cqö…,T€ìG8ƒßšË²I’(Õ ÎáQW©'Þ¶¥H±­ûk¨´æ‰—{Ï;@À#§=Ç´îmµ&Óí̶ʩrLÌ©Ÿ»Ûq= ûÕ_"[ŸOÉ#ÈÏO|t÷¾—zÄ7dª0|†ÜF±íèq´uàþ´¤õºÊ’êzž›,’ºHíV8“hv`€ªp3ž½yÏZÌK{(E«›»y•T³Œ ­Ž‡?{œåWõMmõ§Šâ7,äŸ,d,Ö±àÓEü’*H›!8>ñã©À ïZÇ™«1¦Í¼·±ìÖSƒk1CrAwe±‘‘´Cõ¦Üëw·Q][»[ÍʤÅJ…QÎýA5‘Ø#6Dä´"€9r:÷ÀôëŸjGHG—æŽTÆÜ¤“ÀõÂÏ¥R§r‰âÕ#‚Îx’i¢óˆqær3íßê*’y—a ¶G“«2޵P)bR@x< rO¹®›ÂVÓÜêMµŒ÷í8XÚ=°1Ðõªk•h·zV´4?²&’ðÁ}¢FeÁåG_n¸úÖÈbºC{ÌI³ÊÛ·§cžþõÙéþ%ñ%Þ¯6‡ex×RÞ\"‡¸ŽxQŒgýÁ]/ˆ~Ç?‡ ¼ÚqBf¸ÜìÌÎH\äœþ=k›Úû-*u*ר±àKíu,­ï5 ÜÙM±´˜/CÜåzžxÍPñ°ðî§åÛéÐÕÔ¸6¤í؈OVÉåý? å4ýZîÍc°7×0Ç4 d?r»ríŒcŒž¼·¿%¨Üܾ«4×24³U™ÉËqŽ{ô¤°×›šv.…ùîšâž$‚f4q|Å{dŸÄñšè¯|qss£ÿeØI2Aù;¤“æ’.pǹïé\;ÈŸgEV¸f%OÝ1~¹ü*Ö—¹šQ˜Êmß(v J¯${ý:×TéEÙöÇIs®ÉqᨴÇEŽê6Úò:þñ×s2Œþ#¯ ï øB?Fþf¥w{Š$,2ÛT[®pµsz¦¨ú…Ôï˜-^MërÀ€œõ>ÿZžÃ\g‘5„O ê‡Y¦/•ua´¸ãŒõ'&³ö.0jžëóõÔÒÔ-WÃZœ‘Zîc*Žê‚{ñ^ù®›D–ï_×í.µ-![2Ȧ8ÈP;ßžã9ëŽ+ÄÜR]}¹-Grã^6n>P3‘Û¥w¾ñü—e­Ýí¤éÖÿ¹Éå§ÁbUÎÀöâ°n£§~[÷—:½.ÏH¶¹¿´ŠKyB™\¸ÛIcñùºçÅx¿IÒî5Ï2Ú}‘˜cùmmŒˆ8þðêkJÛÄe¯x¬ÑM2m@¹uv-¸ cr:wŠèSÆt6Öï%¬‡ÎˆH…·# Ž}+Ϧ¦¥xÿ_™¯5·9]Q>·´AÁ¨ô÷®Æê;(ôéüëpr¥B€Ùìq\Ö‘›u1$q»d‚Gp>µ½­Ápšl¬n¡n€…NïÌס¼Ò=é ž1uáæžO$FË»ýÚ‚_ j+·Ë´/òØ‘zסG!Ž0²Fû»¶:š7B2õÜäyü‡›Åá}B[†D¶tÈÁükúÚKK—‚U*èH`}kÙã›j±o^+3Æ?e¸ðô~)°/&ðZê#ÉQœn_n(^öÄIrîy¦OÚNzb» ?ˆÇû‹\†˜›.[ØWadqgº-mOc¹¹§EØ3ùâ v…w0äãÓ×Ú—TñE„WKe¥Ì­c!Ÿlk†çîÔp:‚I-è(Óô©µ›èì`º{c#|Ó!Ã*ÿ>£#ñªx_R»º¼CdÓO÷Ùî¦Ü “…ùý{îâ¹q4åÌÕÅF-Äâ.nd/$‘’‹9'Ëí?™®BÑÌÖÖîÖì×rªŒ `’$xúz×Eÿgöž;óo<÷1ªÚ pœ4`‘×.9Ç ˜§Íá[ÄJÒ]Iµ¬°Ï ʰŒ¸g Œž8nyì*eE»DÛ–Æ>³ 6:ªÛÛDÑJÞ­ ƒ¹ì@ÁýjkKk‹4²hØ%ÍÓ  ámxí‚}9Å]t³»¿¸ŠmBѯ57Œ°»3 ééŸcU|+©¤_l&xYJy%ù(3ü_2ôP¤þ>õÍV.])^¯›–ö[‚%‰s$ÌŒÂóÕ±Ðf¸i¯¢½»´,ëäÍË`|©×èN\úšÛƒ_ÒµUK;Ë8¾ÐŠÞ\¬æ%• ’OÞÆ Ž:ö®NÇWÓÛZ™¯ìö,›#U]Û0s¸ “Œg޹ö¬)QqVjã{‰®L‹clžDnÙÒp¥|ÀFÀÁó¬‹{kÈçŒ#òÌ€pj[ûå¼7>LQˆÙüȆh×$ž˜ñüª¶Ÿ|ÉrT¨A³¯¨Çõ®ÄšŽ‚³-^OsfݤkwRP9ã$~\MºIõ›k›–yîBÒ†cóvÀÇ9ÿëTWÄ$6ö ­Äy,wåY[æ\Çñâ©Ä$’PåáPÔçµR‚°ùZF¶³8»Ô ¶µKvrï²>v§¡¦4XY¥Ü q5ÓA’%;Œ{ŒñÇãYkn0 u~žõ×躦—¤Ã4÷vËs"aÊð!‡çƒS9rGÝ&ænœú}µãÉiws©«fØâÏ-ÔÀχ¬ÜÍs¨ÜI)Fó–7geÚ[ N{8ö®ÏÃ×±kWR¬AhðÄe8-æJA$…<Œr8$Z£â›$­#[¼2\‘^DÜÒÿ´Xò£’6޽OAN—¼Rnö8¶p]~`å¹8'òæ´ôOê¾’i4©<—• ;’x#9ìpNlÖ3G¶]¹ç×=*þ•2Å+¼Ö&î(ãl.í¡ðñÈw®Oa®]iz…­ý§—Õ³ ·;‰9;³×Ž>•è:Žõ‡ÒS¹½ÝqU”ÿ¯?.pàzv>õÆxfÛO¿ñ,ÖÍ4l†ØfsÐ㿽†{ô:¶þ#³±¸[ilmî­#}Â0/@Á9ÇcŽÇ•É])¾[••Γûiü@n¦ƒIIÕñXÜJ¨#<äŒçÿ­å—öò5ìø‰Ã£ë×n¯¥wsA¬Kᙢ·†æÖ$CtR8Ïú@| Íßh^1Ó¿zãÒþþݯS~>Ô›' ’:÷èjèEGáz ¯¼dpGS’zSÁ"FrzV”¶^]Ж޵|ÆpÇy Œ gñàwëRhÐZ üË䙕yŽ5Lù„v>ßã]Ë ®c†>^À[äŒñšx†F}оüñ]GŠ4û/U·Ô×Kû+çA Ä@žÛsЙëŠç!K‰åRÎ~^w9éÞô¸\GŒùËq•b¹$àsïÒº9tH¬u“co¬Å9µ]ÂD£i8È^߉ô¬sd"-Æò\8s•Û‘Š½c{gm"E³JÅö…+ó“·Ÿv'ŠÎr|¾ê©´Ú”ú]åέ‹Ä†-Ö±E³ÊW€YG‘“Ü÷¨íüX¾YóZU;ŽÕXQÀ¹cWµ/éØ\é­b³\m) 3ǹnH÷?θ—&hüÁòœe#ð#ƒõ¬i¯iyÏjÑmc:âPË·%qן­u:•«K§¸Um©ó€üz{W9áÑ:k0¬Íä++P ôëÏjï^0a(ÓïÞ¥wm jÉÝ>cÖ“Vå9í>_ìÛdŽvFf‘öãïŽ{ñΰˆ*Ø8ë>†)´-X2Ѹ=½kÊ|[ku¥ÚêB<ï·‡y?Ý?øð®ÉjŽìÚ)$¦æRª„F­ŒŸâÿëW³øWlž·´˜ÎPó¹NNkç x„G‹;Ùßùg#g?BkÜtýfÖ XV¹¤x£Ð {óŠPvbŸ¼´<¿Ç~>×ÞâÙ Ó.rÑîr§éüª¬a£ç²¨¯Bø¥®-ç…¬‘#‘Y®2wžú޵ç–Ûa»]Pî?¾¦µ¦ª4øGæ:!TLýæ<ù‘X_uòD·´¶y\lŸï2@Ä™ ÏRIü1éOñ0fÐç C)ãýá\¶§cy¥qÔrI kž"‚;{‹“ªº(ŽÕcêGjç9&Üá~UÆrzz Ú¶ÒžM'P·{E’âÒTw•\f8ÎA9èW%{÷—35z›>ñ¦xZþÆq*ß\y^4S¸0P¡˜òmÏäz¨·ñÚisi ‚h„Ë"H¬pØÆðFzgJ¥|¬©f7ZM+F‘ˆþr:ñ[–Þ ¿ŸÂ‡U†âÑfA }â?Ùþ÷}*}ÙÙ3H'«HçãµóncGo2(ú)BB®{‘Î2zÒýŽ6ûJî.ÈN@àg?NqþMOag,ßé8‘f“ˆíã÷ƒ°éÏ'½]»Ð¯-gKfé ÍŒ1‚yp£’[µL¢å&‘„¯©ÍO–sË¿»‘rŒµœò4R‘Оx«ú…Äw·Ó܈Ì^d…‚ÀÒÇd­Y£"r»Ã;öì1ëN.Êò'aö¶ÂP—S°He8$ÇáPÍL’ñ#Ë“Æ2s€*ÇÙžHâŽÞgRUðzœúv®›ÃþºÖn£„Òá·L<³)c+q€}¿=ë9TŒ4ŠæR8ÛFG™„Ç<ßJÖÓá½½š1$lÅþp±|Øä° ŒŒqZ:Ÿ¯­”•HJ+”†¬M>Qáe$·fyŒaš4ùÝ$‚2õë^›¤êº-ÕµÍÍŵ¤"Ù”3ÞD¡›°;?‡·#Þ¸­/ÃúÍãC«;Ãe3€`ÜT<9u8cÔpå‡5"¾+{ËØ£XâF‹G¼ÐFeöÂ×-H£ßa+¢—,tWž[Ø@Ži¤c‡ À,Àã§<…`ÝØ­¦žm-epÓ!gB¸U$á³ëÚ¯x¶}ë’Åd$š8ˆŒÉ÷C‘ÃíÇwö盼¼G¼!AH“å‰9®{dœW\²@PŠêh%Ü”ä©Ágκïië­êHDp·q4¨îSz(ÎÑR1øŠäî¡Û.GÝ5¿áÝLÛÚÝB"òâ2G €z c$’5u¾ ÄÑÑs®A¦iöÞNlçˆù±#¨îÂsÐ/8ŸÊ¼—VÓƒÉ}z.’åÖQµ`\)ˆ7GÀŽù¨o|`×:+iÂÜ! ž[ƒÂ(R§Žäç¿LÔz¡,«wn×KcnC6H\îÕ×xSCÔ[HÓ¡H'‚âHe$Uò±ðž2ûÏ©è0= ××üAáÝ>m¼»–‘i#ÝöC»iUÇ(/^k9b9}Èn5Ôf±¦hzn'Ølá·½²¬ÐÝ’Ø^8Ï$œœsž:W—Éx,nÝmB·— 1ÊFH õþU¹«ßÝÝÌÏ©K3«J|›‡®:tàƒzÆÕôû{I¢û$Æh¤E ¶7TŒg¼nÒê+ºN‘¼—šåõ½ñ<ðXã©ÀÆ]K;í3u½´Vw¤[+¸$2AÇÒ¦ðŽ—b¶3^jòÄb,KlÛÁbqÈ#Ÿ›¦N9Èé^‹e/†í„ÐGa-ЊR†XÛåÈ0FqÓ>ÕËV¼©É¥¯äh•ÑsÃŽ/¯þѳ2€F[ 6ã¹ïÒ·î5m;J¶óu/Êf p±×ð®Dy(Ï O"‰Фœâ™©XÙhö‹w{¹1¨“É•ò OLriÆ7w=µFU%dz7‚ïíïé­Xµ»6øÉp~µÁüSÔ,íeÖlEÁŽîêÝÄ!ÇN8äzŠë¼%âîÒdÚ,ƒˆÓ‚¿^ÕÊ|Tð”·€ø‚Ý„À(Y6tÀï]‹àÐà• F«RG‡¬3ÓjnaØrkºð䚦ž!mOHÔ&ÓÈÞ’¤mÊúgzãŠ*·B>†»í]†ßÃPéíqte0Óisþð<çµCnú©¨Ý½ /ë°êvViúvË[r]àl°ÝÌ•söé$.é Õâ¶{×k3=äp™Rwo•GFVèrëX·ºÍÅôw uåH÷‰Œ„`®Glc¶+,´Ðââ6 ¼•Xg¶xôæ½8PЋЉvúe{Ã.äù‰fTèOJ¡>$rãsЕ6æ,z“’À¦‚yçð­ã‹¿h„¤ˆ#ÂŒ„'“íøÕqØŒã­>Ò%–O¦FHãõ§”ýÙÁÆp»³ƒþM&1¨ÐÆòRz„éÏй£ß¦©™YϔѲ¶ØÃîã `‘ÜŸJ¡BWÃ:§ûMÒ˜Èw½:ŠOFaâ__ø†îyÞa.AŽÀQùü£š«àÝ3P¾ÕÕ¥š\ !¾A pzŸð«> Ñ-¤7Ž­-íµ´hRíd |ÃŒ‚y?tž;çë]W‰¼#§hpËw¤_\,i"·™4ßñõÆw)yÏ8Åg' 4·a{.—ã™®‹µëÇð˜îmê ü¬ $ã’ŸjåõÛ?ëú ÔYâ{hViãF_3ç$ç§Zㆱsö°—[Ë*äCµ@%¸ä÷ÆxïéŠî×ǧTð­ÝˆîÁ¡KxãòÙ@jƒ‚þ}‰ãö2¥­=nÆ¥}Ï0mRêåí㸔º@¡# N1ùÊŸvYÕb“ÌÉ8Q’ ?Ϊ¾Ÿqæ7Ëž ï]f‰ðòïWòql·ÂÒ¤EŽxãölöÆ=ë¶RŒul®rrÝÜN‰ÊÅ.xã¿Ö´WYº†­ÄÅ|ËÇÍ’X±9ϽTÔ´{í&ííîàxÝ #Ϋ£&Á»÷¦ã!Ý£Õnõè ñÙô½<:£„ŒŸ™ÉúãÖ¡ñ]õíæ°ºmÀ1IÑ•½@àW¨ø#Á?gžçYÔ!kšG1 ˜ù<óÞ±<à›AxºË^Él¡†éJ þ­ßÔ~U‹‹Z¤z‹Õé¦qÖÑfº0G,Ûƒ­mi¿¥±ÓQîžÞL¤¨Ê6ã8ïíX:î¯ökil,Z+¹e]²O@§®8¨ü#áãâum ±F(ÄI·*¡©2Ô¹WÑ«Ýy™(ƒN†Y/ì6Ò°Ù3°žqžãƒZ:–lm‰ÙpêÇi#Бé“W<9ð·P½ñú-ó4Ú°{–-ò€~îÑÜœW¼èþÒ4 `±³BЮI>g'ë]±ŒmsΩQ·vx»éVð¤O"¥šO™ˆ}¿(žøçõ©4›yo®Ò.{€YY’<³c©ÇáVü:ͨÅ`Ë”9üF)¾ÖdÐu%¿Š$™ÓkûŒvïNƒ|§-§WÈî‰e&¤t»{{ëh<—¸o´¹ŽÜ c=y®Â׳xgÇ1Ü$Q}šáši>by öÁÀ=8ÅwþפñˆâûyùþÊð±Àä“ü°+™ºðtšwˆ.L¼Æ 1`dŒ÷ü«Eù®ŽÌ#N67>/j—VÖz\ðƦñþiÙrvŽv} #?•y'ˆtÛÙÔÜÉlš.Š áG$ä}3ø×Ð^,ÑSUÑ4ÙL4–̬ˆ½I#á^eñžÖÏKÓôkD ·Ì¥¦ 0 ŸÇ?•gÊÛº.2Š™ä6vfîò;a€Ò šŽH 7 :¡±õÁ溯h¶º¾¶¦õŒ6°ï&8úgü?J÷Gðç…o-<¨tÛ6¶xÏΑ(Èǯ\Ôꄬ ÑóTRClÞsF^FÄXð9ä‘ߥS‘µq:™²ÙeÀ=ª×‰ôÔÓ5éí!ÜmÕ‰ˆŸîÖd$$ªÄgœV‰){ƽa$‘¥›Ì$ž:{Vå—‰¢¶ðûiÑy.w»¤ä ©Ð1çšç™Lž¾”¡ •Ë:n)­EË¥ŽûH&»xÒYõýÛÅ+s·Ë@>HÁã§­oÞxzÆ+8ÿ³®æ’IçHžM8?.9Ͻs>°mR?·ÌÓ²Ú8‹ÌòÆ£èG'ž·_\±žâh®/†ÒÜ´ ¤FdsÎ ‘ËPqøâ«9Ú&m‘¸Y®àXï¹h¤Ã$®yxÎ}Å]¿K½Ò%ÓïM²-ÒüŽX¢F~ùà@Îxé^W¢ø¥¬u{–y¼ÛKȇþì gã ç¥iø¢úîïAIÅÜ/äºý¡$sºE ãw e» sÍaó qøš‚oEâ {+»¨£¸[„òXØ‘ûİàÔñßړþ!³ðÞ£%•Ùö€´YQæ&3ÉîNyô=ºÖ­UŒ/»3I6c^Ú´:c\M>ëÉ¥*-ÌxÂaHp}ÎF:ðj+ÄWº…ìžIŒ^\¬Ë–U±ìx«Þ.×lµF›('1/Ú Œ,’s–·P+–dÚܰÏ^ tÃeuaf«é×WÉ&¬òþá<ÖÞÌßi`yŒm 8ÉÏCëZÚ.«s×: †?±ÛÉå@V|„9ƒ‚+‚²<ê²KånùwœáG©À&­Ç’¥$ xp íš™Â-XkCÐu-JË\ÒH³ƒ÷@—w³16Ï€H'žVœŠó,HÎyô®²/J|9w¦\Û¡Š"–%ØÉŒýãß9ôç×µsQɅ佪(EÅ;šI«#í]‹éP36âAÉÆ;ššîÊÚö# ÌK$gª°È=¹¤°€ÚÙ¤ ÛŠ3ŒgœÿZ”’b1é]IY Nòló}SáFŸw©@Öh-­•‰‘:‚8Àúâ¶tßAá«Ä»µÃD‡æy­t¢ôµÃD«÷N=ÍYƒ×)½w´•¬|õ®^\ø³]—Q±vc¸ˆ<°>ï^§ÝxO^Õ,µ k)Òyì[lr¹³.3Û8aßé:†õ›È4û4”OpΛøO#¸úWI þ£hÖa?³þÄð,óÆŠK‰Ùãq\ÎN2ò:½”\Ž'â…‹YøFpvÞRF?.•Ï[Œ>Œµè5}3R[2]¤b@«Écæ(+žÜn¨5;E“ÀÖz®™hÖ完3e˜dýî¿Ý몛MhyXˆ;»Žøysx£l‹œÂä{t¯AÔô)®æi–E}«ò©àý+˼%zÖ"†`À¬9ÿÏÚ¼ææ8’ä¤RïN>r1õ¤ãZä8ž&‹jÈG™µO 8U:+/áKùšÚß?¼•WqüQuPvá½ñAErOÝã SjêÂlïN·á»[{›{ ›mæÖëË>dܵˆ;†zãö5Ëj—7F x.¥ÉÈS’?™ý+‰Í!%›''ëQ ˆ7rÜÉv ²àƒýÞÆœòMwsómó°•#¢Z[²«#$c#éTÚO0 ¨] ;𥮍E™®n‰† ܼv„„^Ã'$dU»½JÂêÁ" É`]ÄíQé뜎¹ÆßzÊ0B õ94(Ëõ§ËÔ.L¹Ë„8\c¯QLä.zÕ«Iüˆ¤HàŽi$B •ÜWéÇ_ñª39r{P¯q Ê7³•Î)¤,…\HO§\ô®Ñ|¨ÇkgæÛ‹f¹·)›†rO ©Œãù©IE]Œçlô;风Hí$š7`3î gÈçÖº;»)N½ÒímÙ…²ù¬ÏÚ8?áï]ÌwÒøJ·F„ÅlÈ»š8Ô1›_$“ž€ñÔ‚:VyqâÿÏ©YZ5½«íYÌd“ýïs–Úztï\­)·+{«©i$ŽêîIЯ“K½Ž@ÇáUÕYÔ`Ž:W­øŸÀVwÐÞêѪØ-¼E„k´!ÆsŒuç œ“ÐW•´mÚÇ^k¢…xUâ&š>©Ävš¼ŸÚysI>ÊòçŽqœc§LV¿‡õÿ툮nDp¬Å"'Œ€ë^ñ \Ôõ«{KI ”OgpþdŠ Éúb Äz…œGq+Êéƒsÿë®Ù>¦‘‚jÏsèB¡fó#\‰P(MÂä3ªªG=óŠó?x×Vñº- ßÙÄŒ*¢ä äõñŸOé^¯·+ƒÍ(Êâœ\78o\Cz`ZhцñÀÉè3\þ‹¦j¢Ooi Þk’ÒDûB‘‘Àõ$µ×ëºÚåq4Lü«/cOðŽ•¨Ø¬²ßÌ#b R1ÏSšÆQ~ÓÈéRŠ££î4¶½“Ê`Ýåî$3´pNNJåüiá{= Âv‚Ò9ÊŸ2IÀÜOvýô®˜¤2²m6ŽwÂWú~›â4ŸPÛäyl¤²ä)8æ½?VÖ-áÒc6¢æ3LÉ‘ÂýGãÚH±}EöÓn"vÚÍ´?ZÐIU§†ÎÎU2¥ÈX#ùGž}GjÆ¥ÝEm‡Œ~®æúÏ`®Êe‘óÙGLäû“W;UM>ÜÚÙCn͹‘@fõ=êÌ’,hÌÝKV¯s:jÑaÇ-žvséëïT¬þ x{SMš¾žRnÒ[p=Ç¥yF·s5ö­wu!%¥™‰õ'5œR»–¶Œœ ãëYɤô:£kõ†‹®[ùšDÌ#“‚})Þ%ð³ ]WQ’dOÞ•îžœÈ{לø*meõ¸!² ž=>¦½C_½Ž uŒ¥ÌŠP(ïƒòñï†ý+UkCXÒ¹æº'†~ÃâíKN¼ †…ºàœŸCŒæ½Åztž¸Xb Å:žG¯ÜÁwweª=³ÛIujˆÊÝXÆXf¨Ïw5Ì>[HÛTcõ®y͹§Ðé§I8i¹ÈDgzÆ)£dýéàvÎ+RîxàU°HCªàg>£8Æp?dê7&Þíí䈱“€àd±Ï­[›;ß \‰Ä£V·ÌÛÁÊ8%Hê8Ïå]^Ö*×9~¯7{-„ÕÓÖ;€ÙÃc ÜœŸZó+¨^™VN6·þ•«iz|ÕG'ïgÚªj¬%º€*ð:þ5¡ÎÑZ±o4à°)€>\Œ“Çè UùÜŽI­í>.t©!,ŸgfbCãrm²¼÷éíøÖ\©.ñ0ÚOÊ rJzƒŽ‰•Šmêi¤{U€œ³0™ç4äùXîõ ìiÜ‚«ìiѹmÒrOrsšd¨Â=æ"ŠIã‚h¸0jT8aœd÷55ˆµhn^âR’GaP3½²>˜$þ–$aå’IœŒzÿJÃâ”Á/š‡ :TM™™ŽI<Ó¶íV<œt>•¯áß ê~$½{]2:UMänQ;‘Üç@XϱŽ4¸Š[€|ø'×Ïù÷®ÛQø¬ÞYG ª¤ ígt…žãžõÊjº5Α¨]X\im_d­nPzcó⫤[#i8u\:ŒVu)Å´åÐh¹­jšÜPA}tÓ7”.}NO5ÓxúU»OŽtŠ+™7J ¨PrÀãØþ•Å4ç a@-»v9üý)ÑÈÑò„¬€›85¥[h4ÝÏkñõΟ­YJo-à°š#˜á$yÁ\ •äuÇ^;W—ê–qèJ"Cå%71ÎÜñÚª¶±wyKÛ™¥@0±îùWœñéÏ[ “Àäžç½K¬ý°ËfИÌ0IæH³|ÑñŒeO§¥z ibïgs¥ð>³¥èàk+ÏqóˆâUÀ猖üûW¹ØÏ-ÍœSM…ÝCl»÷À¯–ì-£¸Ýv‘€ÒåpSž@¥}áZ]èÖÖÒN¢æ(²±ç¥G7+×aÍsFës¦7¦UC0éÎ)é£+´úT²HÀ‰J–í·½YÍZwÔÅé¡ã¿®]5»DGeÛ·¾æ®8kº¤ú{ÙM<–í &7rÀþuÓ|^`|I ±öuäô?1é\4gŒïÖ‘8±  ÔY¾Æî”V]Üdc#­v obÕ3sʤ¼8ÏjƒL–%½.c pÇ5‚gT‘ÇIákÙõp»£¶héT2ñ知••Çb¤¶koim,­ºIY÷E´Š:dž9ç¥z÷à LxÁÚ”Öºl×SƒçJÌ#V ¹-œ‰¹¯=»ð®© ­¥ò,fÚiÄhYò‰Ï·Ì9÷®³RÕü=¡x^I4+ûRòUdy~Y@^øã늈ϞÍÅhîq^"ƒÌº]R{‹t:’écŒ1 6üA•5½å…¼fhå„Ý tÞ0#õ~•¡}®\k6è·1$ipmÚ$² 1– €};õ¨µ[{Ø.!mkÍyZ(äY ‘Ðãsü#¦xý+W«Ô‹v2¼•P|“G¥#gyÝ lŒæ¥2¥›~v“Èê{~6õPq…àRDØr6%#øqœÖΛ¢jz…©žÓMyã.Füã‘׸¬Ý:ÊâúàÅ aŽÒÇqÀÀëOŠkÄMÉ.ÅãüRz»—S·Ñâ6vÉåm‡–^Aæ®êf[idžDGÈ„à’{ƒê=ýëÒuk˜Ö-?N· 'MÍ’XŸ@*æµs¨y_Ùú¡‚äbE;Jî^ jÚEò¶vI»ñ4öú©C@%…]‚۾nzßZ“Çz•œ It^/-pÛÞ^_l'Štòfusò)ÝÓ'ükЦ‚rp#‚Rñìi%p÷©¼ZjE¨ÉkSþ5ñ L’æi"èCá†ã]\ž:Õ˜þäƒ1H„·|VÏÃÍ Â $­rÈîÀ—PpÆ9­-{B† ºµŒiÅ ó6ªà0^qŠ…M5tÊö±R´¢™â~3Õ¯um\K}·ÍTD®ю½?Ɉ £Þ©uû©/uVÉ,v~ î×â"º)|'•Œw›%Õ¯^M¬H‚%2+ÄY~½ ôö¨¼%¯Üø3UÔ4›×Ciz›\ƒ• ü. [†eóà¢ÆÃ¿AžõÖÙÛÛKáxí$Ò-fSo°NbŒ»qÃgïg¿­gV§$ŽŒ%/iI¦Î‡EÕ¢ñŽªïu!¹ÓôଔliH<´ü?7ñˆ/¦ñ/Û£uŠ)ƒ$EOD ŸNV»½Ѽ?àHtûxÛûBð3~ìs¹ÿ¡vŠ«¢ü½žÉ¶µ5$}ímaÊg=Ó#ëURWŠŠ5£ 6öèyþ™k­xÅvå"y¥dmìÀNüúsŠô {$·­GN•z=…ôMN0Øiéj…de;¯|·SëøR¿†´Åu0[•/‘¹\ñÁç­rÔ¢Ù×O½Ž_²þÌÖ¼»u,· ú“Çó¨õ 6 -NÕuh¢¸òØH# Ãc’3þsZž1[› KH—b»Ç•_rÇêk˜–ÞÿTñtGUŽkx- 2\"6Ì}ê!ÊÛÜÕUÒ[u='Ãþ/·Ö·Ç·”c}›3Û“ÓÜWK,QÏ G*+ÆÃæV¼ÂÞ M+{Ý>üO<ò;­”^Ûïõö®ÿDÕ£Õ,ƒä,«Ã¦ytæÛå‘Ï^’Kž?âM=­õ=D‹mnL…³µQ ùsŸÊ¹ÄÓGó ŒÃ{WqñºÅí«ê:aimv¯Ú`AÈÛœw“_>Í-À‰ i*ʹè}höÜèúÝ£¢¾Ÿ‰ìsݽܾkýÕUz` ¥ç4øel.~Sýk˜ðþ».¥ö}ÎMÀ\ q÷—¾}ñÞº!,HÉÎF0¿®+ª6JÈóäÛwgO¤ÊŽR×äòO±®sÆ>{¶»Ôü溕£RrT€+ëÀÆ+A.›ÈòbP3Ôã&šc•ã'û@ŒË)‚þ˜9ÚOq)5±åú.µu£k){kˆçˆaKF:ö#OW¾—TÕæ½¹æâá÷JB…žàt~#Óâ‚ê;û|îw(ü`ÆAüEd;ۻŢ5ÃmÚpI÷ü¿‡‡vÌ&3|cL°óÛŽÙ©,à“£?…ºpzþ8ü«YqýªaŠüàø.€ÙútÍK§J’ÌÞPD1‰fˆ•Ûƒ“Ó¯^1Jâå#ѧ½Ó§Çh·*U³°‡Yx Azxæ©jó¥ÕíÔ±[Xžä´P±ÿT§?/áôÅwÚ,’IªÚ5œšœqÇnè6Y~ð.@`ŠîöüqÖ²|HždêÍm+I$Ì¿é0”bLÈG¾N:žØÀJÖ.Q¶ƒü+{5´H²I,ˆÛÖb† ÁI Í&§ke¨Z$&Ñmö1f’’N~bI'Ž:þ}jæaåÄñÂ\c Ø}*ð†òo*hÅŰl•r@Î:äcšžT¶)=,fiv¶Úuµ¥¼Ö‘\Y5ÚÏ<­"@\gœð­`ø¶éµO]ÝÍ@²H¸ S€¹ì0=ñï]q|CÎ B|µnTg®+/S¿ýzô½#A¼K+K&…±jŒ@# ç®+Ïü<³lBam¥YYŽ„Ÿå^¦ž-k8ÏÛ­®6ùj‘|¨=ùÎ=À5ÏRÕö;°•0ï—r¥ÄËc¬[4øŽ3æx%@Î:vÁ¯@‰ƒÆ¬Aã:Ôÿh×ì."º3Àìçx#ÚxÇQŽ:תxzo;E·mÛˆ\ªrýõ¼ŠäýÊ‘¦EfÿiÙ¦¤ºd“®F4cÃÐzŸj³|ŽbY#‘”ÄÁÈ_⨯'ÖµøI¼hÐXÛ\ÜÛ¬b<À9È?x‹Éêhr÷¬:TÔž¬ôÝwH‹V²ÚÊ ±‚ÑädgÐ×/á½e4kI쯼ƀeâÝóõN{wˆô®£D]BÛJHõYçNç,ËÛwmßJóÝ´ÚÝãÈvÇ•°³DÑ­*nMÁì„Ôn$ÖoWʉR0ÄCoà.O`;š‚EÕ<=v‹wÖèü¤…º¨®{Cø‰™¯G:FÍf¬…P tÁ=3ßÚµ¾#üU´Ô|&m4eô¦òäyW^àd¡ÎýíΗ[Ùh£tzW‡µé.­/˜1'h“×ë\‡Ž~ØkB]CB k|rÍHä>ßÝ?¥q? ügæ?öMón€ŒßÄ£úåô¯oÓ¯Œl wÜ1”=˜UB£ƒå™…H'ïÓ>z´Ð¯|7¦_G{nÑ\¡bU±ƒÓ5o@¶ƒV¸3yáî"‹’úÕÙxƒS†ëÄú”r 0´†"dqòæ°¯ü;iÂË`d¶'æ+ c'×½u£•“¼ 1Í ‰uÉäûŠ#ðê+,ö³‡‰VÅY°Ôexe†ôÇ*&AÜ@`GPG¯¸ýi·vöZ}ÄðMòã[Aª$Äñ[K#Úϵ£i#ǯN>œšç¥Óm¬®Iž\í Pq‘Ó'Û­jù‹y{i¡V–Cõ<ϯY%Ý„n…|Ønr㪕'¯üÖU4F”÷hËe‚)%”’W“É‚—‘»‹îzNªÜG¨i)o¤Ý ‹{Veˆ ÌÙ?1ëÀäóëŠæµ«¨õ=`HÑÉ °—‘‘Àãs1 þõtÚ.´Úv©mw¨¬¬"²6ß"üÙß»‘éŒuô¬mRÊúöx®­íÜ Xñ^»@ÉüóøR¦ü‚kÌ· Ù1¼™IPR?˜·ü룛Áú¥Æ“Ö‘ ’@\aÀeö9â·­ôË4&6þkL›æ!°F8ôé]-­Õ±‚;H ac ¥ ô¼Ws.ÇxsÃZ¥ÅÌ×Em#µ îÉïŒgù×9 :­¶·%ÕŽ”· ˜Â*ªe>£<´cÓ>µé—Šmô[¦Òl4ð÷.ß!ßòïc€HçÖ±4Ä"ö4`Ç@Ì÷¾iÛ·Ò³©%dkM9;³“³ŧx”[éðˆä•þ×/˜7DÛ2Áp9?­exªÏ\mL´»±†8á€DNGV*ì žzcù®öÕQPÍuu… Æ<¥&³6§¦Ä¢6Äq¨Gs´œ9÷?saÎÓ7Qº±âwš4údV)~¥DЉcä ÆÄžN:õ뚯m£Ïun²ÛÚJñ’@a{žõØxºÊKýWÃvªA,ºt¨,pŒÌG>‚³tÏÞXiÑX™ Sn]2T’ß9bI*yÉ?¥mÌùS2P\Ö=÷PÐR×Ëh$""0U”d m’+`ÅGNj øÙüKö§Ômc¶•ƒæÎsßð­×¿Ò‹•`‡þq\õäù^†ðrŠJJæHÎ Œ„ô+ÆÖÈž½ä. tþ!]Çö†˜¼ªGƒéW¾½Ñï­ä·º%‰þò´@ƒQ´ïrÜïöO(øA©I¿qj×Ooo(î`íÉÁc÷sý+¿Öµ«{ZX"3åg ²Ou9éXzî Øé7ZOÚ­eD/ˆœ„<‚sëÓôª>ÔN«¦ÍçãÌbrr99Çë^…¦¬p׋Nç#âG‰n0|ÁÆÙ¡ûƒXõúÓõè¡‹Ä—1¡#Y0è>QNÓ<µ’#)Kçµo{#Ìœy¦•ì^Ó.Úý%“!C$vÎ@ü2Ev:Å­å¹´žA)PªÙÎG¡Íyíì­Ÿq"`ð žÞõ™i>§ jmöø`® ª^¾ÙéëS&¯c|2|—;M™â)#aåK!UîF?¨¯Aðn®ÑÝý…Îc~WØ×†__sÅ6±¡qohCî±äž{“Šèdñõ–“¬À-ƒÍ¶AæÈ8 =½MpÔ‹çN'­ J›ŒÏ£À–‹c¤C'Ù-¡]‹6Ås¤ú×7mã»IíUäI 2å|¼a؃\ψ0»Ò#»ŠÚwHî¡0Ì7)î3ÜV´¨u–åÔœcîÀ‚o&y¡•Š 7t`8ÿ ¡=Ü×VI Uû«Ø}*Þ¨Â[ƹVÈ“$œç'¿JËÍtÛ[œµ$Þ†–‘?“ ‚àÛ•`D¸ÎÒ:Wµè¾.[Í9%†áw¡ù¢ Ìl:ãØ×„ÛKå8`ªØìÃ"´ô­E,晦‰]d€8VÇÜÖ5))—F³‡¡Ùë~"hïne.»üæfô%Ž@ýiö%›Y%NcŽÛæ&Avî}…yÜ$Ònw$±ä±ïë]-‚¾š‹³&'åe†¬tV2ž­³¥‡P6ÚݽĭºÐa•Oi|§ñ~ªø—X‚+8cŒ3ï0ñÓüûTÆ.c [kA œ“ÀH9ü³\°¿Š][í—'÷QáñÐ~uw3:Ûií¼?£­Åó¹˜nuxž>_Ë•<—:‡™}q¸‹Ç,°+„D}§ç©ÿ&¹”iüI¨ù·-åÚFr@ì=©5ÔØÉÚ”»GPæ( òAãÄ:‘YÕ~épÑ–´ýbXõ ûo-íàwD1"¨ “¸I?Rk6}%ílt¸âšH¤š¹ ~àŠß·‹O˜_<*f0Ub§Frœç=3ÅkG"\C¢}¦Ú×vè1!8” 8Ó¥qÆHìOB]rê-2 VÑ.!¹µ¶@­ýýù“ÓŸ­rÒ|E¼žU qä€òö£éŽÜW¢&¯£jâk­.Ý..áýäÅx ‚>\Ÿ§5æWºV‘=ìºhÛ$å\C®xÈüJ¸µ{Hé{Ÿ¢ø—í^ ƒR·ki&I ÂÜ6{gðõ¬¯\ÜYØ[Ï8?i–LÇ$2f0®}GnµÉ[XG¡EÅ7ªÜžGÍÒ´S—»~Ã…[;³¶´¶´³‹[íIlHß^1QHÊkGÐÿ}‡ò"º„Ð#Û´œuû˜þµºv• 3M{~vQüê­#§ž™Ë¢£p#€±ùfäÄcVÊIçšè¢µÑ%b"½…˜ñ„‘N?*šæÏOÓtù®®$>D1—bXrKR{ÚAnyŸŒï¡±ðôãËŒK/ȇhü}úWxcÄÒi3¼M<¢%ŠFxcïZ~*Ö&×låšëdkL9=àzût®.ÎÊ[©T¨f$€ª£–=€®êppŽ»œ5f§=6:û›ÄÔ5ºŒ²9`Ò¬Û–0sÎzVuµ³Ûá"3Ús‚+FJ¦:]Øò±ÒxNËíÚÜQù>nßÞFp@$ÀâºïhÂóBœßÙ4Ém*g †POµrþ ÕÓD×Ô€Û³“޵êÓøÃJ[rn%TŒ¡,1¸ãè9®:ñN¥Û±éàe%GÝÑó+Û›ÉîLX¥·i]£?u3ïÅrúí¸µÖ&b1!9T' #ŠúK¸Ó4O êRßY-¾—.ù’dp]”¿Ê„„ +À¼Qqgw¬«'‘á”nÃýå9?)úqÒŠz³ªNÊôßj:E³EW?#8-³éȬÍCV¼¿›ÏšYY©à}j´#˜¸R¤ú*ŠKhœ³ñÍn “ºÜÅÊmZú-#±Ëšnâr2:ÕŽ"9òÃöªéH¥‡8¹ã•ÉOJ¤®fÑͳm] õëM%Ô^MËÇýÓŠzÒ!îOn¬|Â;W'?—õ§§ÌàŒÔ¶‘Âmî ŽÉ.ÜÅŽ‡Ô¡C†ÐЬCcÖ®CumHn]õLä~UE¾ñRe‰µ ä|Îù<ñЦIc“NÛ“Åméúlq\‹=^ƒí¤<=¿MÄÓf†Ú=´ÈÜ×n{×G¥Ã,‰¤º¬nÒ+s†9éÆGé\Õ¼št²Fà§½zG‡îo¯üo.-¯ ´ÝqȧtNJàc8`~\wç¿lk»$![35¶¥yö©a°´x¶™›+ól ò=ÏVDsÚÞ_Ër–%ÐÍ’³=sÇùë]]ä7Úz@ ³[9U­]áB†'}¸Æ@ܹ\óŸ®kBbŽ8"m«¨î1ÏÖ³ ¹õ*/©fÇW¸Öµ+ˆn¤p-¬aœ¶§áо¾¼ñ.©jðšœOpÇhÇÔãµsñhZŵôwrº¤Ë‰`bX60rr?:õÏ éÞ(žÀBýl-#`"·ŽÝ™Açæ=¯9ëV©ZW7u¯^§?®|(»¶³¼}vš‹G8eè ëúW8¿'¶¹ò¤DµR¸~0F{ú5.Ú7Þ[œ?q¼k«[®»gCxªñÎÀÞ+)œu ãó­F7fj·³xfêýç¶’êB±EBUyÆáŒמµÉÙj…¥Í¼ˆê$Bå´a=*Ô:%Ü?f±Uxîíï;óõ¬}OÂú±X"´-pЧ2”n9÷?äV:lh¤tÑk…®štÝJcŒ§ÎÚÑu%· qÏÍj˼×å‚k—ìðÑIœ["œ2íì;æ­Ýøfó\ð¶˜t¦¸º¸‰ñ=¹ŒGz…~yã5ÊÁáÛ„†x®®ííär,ŽAÈnF1׊˜ZWl•#ZMyäñsjÒ}”ð¼D¦?¹»ÐõüèÔüCwsÂÖ×˾[—Ÿq$Å"mÇn£5M¥©¬`å²=Š}_UrJ£*úÉ*¯Àg5Í–•p奂'–S‡`üàžsƒÈöªìB;ž÷©-  6J9ï ®kœºîO ž™¦Å$Zw—e‡næüe¨Þ`6n£H ²’Iy#ÕÑ_›éU"¶ÓîeV`„gf³5¯ ê:Æ-œPÍ 6s¦cëUªmÉ+5Ìx½ÝÄ’Ø\JÛ™†óŽ2N{p:~µ^Êw€)‰ÊH¿u”ò+G\е-5ãÓdŽ·oŠEpÇÜŽŸeYÚÝK¨%¤0»ÜoÛå(ç#­w^êèáZ;3 ²â+|ä“““Þµ-×+•2=þ- ¤¬W ˜×xü× Ö¾—|cˆ}Žäg#˜›ü+Xlyø…vÊ·7YéóÍ0,‹Œ…ïÏJ˳ñ•p>Ô¢NCGòî ÏCÏNøÁ­ÍCAÕ5=&æÞÞÎc)ÚFñ°7«`f¹}KÂ÷þžµ&ƒ7oxÑÕ䀹þöGlõ¬ê%'fu`å*qº'ñ‹ï5€ÐyÍölå»[Õ¹íØv®vD$Û¦[æ98êðÀ×7A1·s`8ÇÔÕ™äŽóÄ*°D^aJ‚ ç¦N3S¨èu):’»$UaÁ9ǾiŽq[ÆÂî%t`¿íLÎÿúÅd\‹ÉN MŸîÃQùÕó\ÞT¬R,OåVíd@UY”rrjaxÇ-¨îJŸÔš]öëû†;òHÎÓ5IœÒ‹Z³"`÷7ÎX±Çašµ¥éÂmDE8 Âq“œ`žÃüŠõ« ûGGuÒ¬Lˆ|µ¹-±U†9aüKž¤æ¸}*(nüO©^,¢P³¿”ÛqIù±ô­%M+js)ÜwŽmᲸ³¶ án0T`/Ìxvúæ¹-„e»µÚøê..âòmüݰ.\•;«ŒIÝbxû0Áüë9nTv!=ih4T”\Ó>Ì5;svH€8,@ÏÓõÅz6££Ã¬X}ÎÙf ³œB}+Ò ¹YVòÉXÜqÓ×ù×_­ÞÙ϶ÊÎyá—dàý1üè@ÌØm­Zëì>$³š9À·HO#¶{~?wz5Œ:6‘-¦—µÖâXH9,Xî>™é\ͯŒ-g"ÞþÖHsÇÌ2ãÛò®×Ö¶—چˋ¹àŒ'™ðžQÁ=ÀäúTÔ‡Ý+šð6—mâĆæ}ˆ„³¨?4„v…høÿH¼Ð´9#’_µ+ºÌ·’ò¶A<çÛ¡ü;×'à…K««æÈ&FW†(æX‹çÑÛ€}ºšÃ S™qµh¶°šLÚL–èY$R0¸Æ©ÀÖž½r£Nh£•#©¸ã'¶?W/sã/é–ñÛGá‰ð‹ƒ5Üåóï9ÿyÛ£ÈÃs( Ù0^xæ´ôýºš£J’$/‰1$£¸íŽ˜Ç½yu$ã%òLæâðþ±¦ 4ý6íf‘ 1½£²²©'p?ÝÎC-®ë9N¬£ÎÝû¡  õç§­uv‰¥iæÛ\m+P„ùm$€·†Æî=êÈ’=Vyé"”Æå_y¸éòœôýkiS¨•Ú±tÓžˆò©ü&°éà@Zh¥˜¸B@^ÕE$´BñÞy21RÄn'õíCÃÖÓÎ#‚à!o˜Ç€AøÏëN¹øk¡]Mæ¼L›ò}zÖ´¡Rz³^w©¦·zr6ÄþâÒÿkZ+cÍý+—WHÀ™‡q3ùT’ÍlHgrGý44¹Ù¿²]™ÐÿnهٽáT/®t½V=—VÞb€FYŠþ¢²ZxvñjƒÜ“šˆÞ6>Xc?ðÒs}Æ©+ìbx“Âúe¾’5>Ý¡w–CHX3‘šó¹íVßX]E 9ãïqŠ÷­[O[ϲÊÁ$T3Ž1êz}+Æ/¢HÔ8u`W5èFqT’oSÓœª9EhjÉ«KqcГö„m“A,¬ª8Ⴢ:ñγ¬… !·¹äuú×1ô s'Ú"’4àá” ã¹àäÖ´¾ŠªÉr§ùnþUJIœ•)´ö:6Ô%ûb17˜É½®! >‹ÏÌ8<ñô¬ gM±Óá¹ÖÚye¿hòa„ŽzsÞ©[k) %¨xæÄ–àc8÷ã$ô¬ßkqj6†+gî”#å9ôýj\•ÍéR–¬än¢ò­Ñ·åŸæ#Ú¢Ó¾¡˜¼Ð\e mÝížÕÄ­#ÆÕà ±¤Ú­¸æèKúsùRgU5ï#¨’Å”oÓu'·?óÅ®pËõÉÁü*£ÛxTÿ¦)SÜN¹þu©}¡¥Ñ îÑ’?çªÊ¿Èaøæ²eðœ€MB?ÚoëPzRèŸÞgÜ[Þgý>ïÌ_FŸ#ù×Aák]6æé’ébk}‡þU$uþc“\ìºEµ«î¹Ô`p?‚±>ÞÕ¹áíRÖãžâÃMžeˆ„–ÈrWpàkX4·8+§fié›Xê0=ÄK,3».@úÔ:}¥–Ÿ{*[«î嘷ñ0=G>„V]Æ¥I#jW)dË f¶ë('žoÃWhÒJÄJÛG›×ÎO¿=iÅZM·¹Ï't•¶,x¾iôÍVÊú?šMÇ÷NOㆮ;U’ÆiÒk$d3"álö¯AñUî‘y£Kjú„Uùâœ0ôÇâ+Ì žH©ÅÜQCM(Á§vRB朱|ò*.;3¢‡VK¤0¨ó}IëU4ÿ]Øa[d±Žv·} a?-÷³ô¥H‹4ÂçjÇ4 € þêCêØÿ²y©íõÍÑÙ$~dÊbÃ=C""ú¾™c<ÖÖÖ“ÜMwi"“ÚþhÑÃ/ŽHþ•¯?€-nmäÙªêöí"•ek¯1pF1†Ïó®ãŽÍÓ*«m ½¸ÂŽÂ¹MkưAtÖÐYFIïžÃüÿúå++—ÌÛÐϴдÅ,6ÿÚ9A™IÙqýâª@Ǿ kiZ¼ŸÚP[³Iuo?ú‹…E`=U™Nâúõ®+ÅúÅöƒ§ê,þ]Ô7ÞWFe;¸ B+Ð<¡éÖzäÊ.&ˆ;H~fÉúôü+9jk²Ô³i¦;kÚ”—Vªm¤*Ñ–‚v€xü+]làŒaz1VHȦÁÿëVNšìO;gâ­~×HÔšÙ-`‘ÆÝÁáŒç‚ pº¦¨uKß:³Ù XÑY÷8Ï5¥ãød>,¹eË©Ðg(®\Å"6^7CÔnR+ ’’|½R„ ¢¥}OCð}ÛY_$\ï•mžyvüÊSvîõëÅwrꢸ‰¥VPÊÈF0kÏüm Ü¥âši²C"+èÅÁÖxfòÞm5—|LSæ=ºç[Sn1G"Îm”Ã×̼˜“Ÿï…Nž”Þ\!Ï\M¸ñUµ¸ýãÀƒÑ¥ÔPø²+€&€®3…}Ä}qÒ¹ýç÷¥Ñá¸÷ qØ-=|=bœ³JÇ=ˆÿ ¡ÿ J ÀÁ²?…I¬÷ñ5äŽË’•;IŽ.úô¢ñìO-Fþ#~ûI¹½³6©©41ìòò±dãäæ¼òûáŽWñ$¸O›oÙÀsýêé[RÕg Gg*¡f™SŸÌš¥©]ê"Î`¢¶6g-/AŽÜsúUªš‹’IZçŒËl÷wí`3ã9'«±øvIcóD\pàuÚ¯iñm’W’NkZ% krO_2»ãcÉ©V\Ú¶ž6W 3²ÌåÐ’7 r?,Öˆmmá|ˆU¸Húäó^…³M;Ä.Bƒžäb¸¯Ù>(­$F #™ ÿwùÖsV¨‘Ù„nTäÙĦ´ôÃê@˜R`ªNÇÎoëY§ƒZš#È—.ñ禿*lÞ’\È·ªX@[r@öNz“Ó)š')&à} ®ÎâÞm›£’0X`¤‘.Öüpó®zóOØÄÜ$°€~ò è?‚)¥t]x´ô2—““^ÕðÒÿW¶ðªCg¥Ï4&Wa$nqÁÍyÚZn¯ÁOEŒæ¾€øg¥IwáRöø†%™•VO½÷W®+*ÉòI¤õÐÁñ/‡uMTû]ÍŠZâ Ÿ¼X“ΪÞð嵜3Ç«ÛZÎn[t@·)´‘íׂ=±^ªžbG™sœB§ÿ^°µMl°›šàÄ›Qƒ,n§êNÍr^N&®PæÞç?âïhw¹Ôà³ =¤ U#%WýìÉéýkÉ´¯Ühže¬H“Ù9ý弃*O¨äs^ãßk:†?²¦¶–Öîì˜Ìç|@|ØÇsÔ׌…L×E·xç«;KÝ4Û§’HDŒr9ǵ:ÒÂïP˜Åk“0ˆAœZnî+ÑüjÚvŽ×[GrûÀoî.1üÍtZÆ Ü¡á¯€]êªT°ù!#¦r2Þüt®¾ÃNÓôëDH Ž££–Úz“Ô’)zìŒ^&VRįÐäV=ÓA ó_1w¸Ç• Dðô?ÏðØYL’Q—#$¸Á¡%{mF ¤¸™Z ª‚ê@þ¹¤µá´2O!y›©ÿ€ÿõé’#G;8çúš{F½¤y—‡U—©Ç·½ZûLvñ3 Úª mÝxÍÛëRiÑèþ{)ŠæÕ@Ê|Á€B:}+”ø‡ã[KM9–ÎpâS´…8ÜÀ}ÑߌšÓdf¢äÇø‹Æ—7“:ÚHcˆ,„óøz:æ­K)“9'©5Â=þ­¨t‘³Æ£‘‰þXÓµ=Zââ+{sù"¯9$œ 眛:éÅ-P}*]r ?J€¨ó¯PÈä}ÕUbJö¬í"¶…vÇQì+€ð׃uk·¾—Z….BüÐÇtê2[Ÿ­wÀ²€@MLf‘55dô•›â”L1“Ò«ž&|¬ñˆ×c×õ †Fe]ƒýÐ+‰´ñl*†[ˆØíÏâ u?.umBE'1€sëÖ¼¢Ü0ž•‹‚m³ÐGÅëð}Õî­rìÎÅPl’rXÿJdò=åÕ©r¾\̸ϽIð>3ý™ªÌyÌÈ€ý?Ö´¼]áû¹µù.-S1̊瞇¡þU¤cxØçœÓ¨ØÈá·BvVˆ{l…A"4h¡çÑ@ʺ±¢i¨rc‘¾¬jEÒ´åå-Pö²rû9õgK¯NúDå£Ý€ ëúTé ’ ú`d×U¼1ýÈa_¢ ›,;-Æû²^&Û#—máX\gÔb©jš=ÔZMì®ýË“óJí@'ž?,ÖOŠ_ËðÆ ÃêHüøþµQ¢‘ÄÉèxM ”M ¸0bâjcwäÅ*;ª3?ñ05–¶íoëD6¶ò9‘¡Œ±!‹2O§_¥z“ŒSG›%'sOCº†óU†/9[|È­°ƒŽkGãFƒk‡­u+xñ$syr?vqŸËõ¬¿:XJF€"' †Æyô®‹ãF¯·ƒàÓø3ÞH¬¢¯$þdιùœæ™ÓJÑVGÎoÔÕÝ:â87™"©2çƒM*?É­Yª›Nçie«YgónÔm äóôJÏÄPÈ¢;•Û&ìËŠævŠFAŒN.̹â%%cµ†YÕ.íã‰7ô>XàýkÝ>)_ 1f,ZåÎOÑkç¯j ÛÉføÊüÊñõô_Ãü¿[ã|’0únÇôª«g Û÷NÇ ÜQµA@ö4ÀMsÙž#û@Øf=ÿÌd% sØäóÚ¼G•è59oü{w˜¼6ª±F™á~PXÄšóÈÛC×µj•É—nB–=ëУӭ µŽh57X™FÝïÀR¿ýjãt="÷Qºv³ò•¡]ÅæóŽ0y®¦ÏÁÛäߪÝKrÁ¹E}«Ó=zÿ*ÙÏŠE»IÅËIŽ˜ÅK¦]__]Eus` ÈÃ%Hg©íǽtVÚ}žžlvÐ[¬mŒ¤ysòÿxóUn<Æž;‹Æc0Žð‹Œdúžiˆ½Ææñˆ œ JK³óêH8úæ‹ Ÿ ¸n'Ó«R« ‹bàƒýlj—°ÿgYF”â 'öˆÎP:+ÎõØtW‰Ö 3QŠåGÈ~Ô“F2rG {×Ðö:ˆ,á'K´.QK1…I'äâ´#Ól"]±YÛ"ú,*?¥fæÞæÊÑVHùžÛV½>N³S€ÄãSœûÖß„¾x–îT¿[*$ÉC;l,qÆçñ¯ ­ím­AðEc–òÐ.O¾*|ÀþQóÛcË —Š4· lïóÈùƒôªëâýgO•EÓÈu–<Ö½sŸLR1ÿ{µx¾£mui~ñJ¨^2U‚°#?^†®7WЧ(É-OPø=ªé:G†g·¿Ô­­î¦ºgÙ$Nݪ_¡¨üo¬É'‰dû-ðh4b“+Œg·¹5åÚ^^¹ò­ä;A%€ÈdMo<ó92ES´¬²¬l>¡ˆ5¬oØÆQŒ]ïsêÁâ]ná}Ӛзº¶»ˆK ˆê{©¼Tžy®ƒÂv²^jaL“ƪ2LDÌÔ5b½š=C>‹šMä»Ik wbI??“éHÄir{çük.ß Ï<Êʘüsý+¢ u8ú×â©P)om†Tm«ÏÞsÇè?TSlM¤®yå°V·.¿1‹ cüúÓí|NBr¸<}+ª‹™˜’BƒÒ ³Ñ%+p»q´øí­]’0ÕÜÑl„9ÛŸ^5çÞ3×/üE¯+ÝBÈÛ8¢'î éùõükÒõÔ}—”8¸”ù@ wþƒñ®+_¶íi,k¾ê/ݨþñÆåÍ*Tùbävуtù™Î#ϵ‘Æ<åmˆñc¯ë‘øV$¶å Œuæ»­>ÌZ«÷›37ZÁÖSf­0)„m¤0:V|ÆÎ Ç4W—«·6ÅOL½j“¹„£bÆ”„ê °À=ý«êï‡óZÏà0ZÈ®#kŽêýXÄ×É)#C*J‡æS‘^ÃðÓÅÙ·hÀ´ŸQžßð?¦h{ Gš6[ž÷Hv¢–c…$Ò‘Áâ±Z{à ¢©,óf%¥“9ô'ÿ|Šh}Ò4’.Xœ†n®úÕ¡b¦`'ØBʦî¬xçõ CµID‚q½øú«2E„}æÀß?ýzÆÔfêE7|±d~9$ÿ*ê¼Ú5û8È~£æ41£Öc‚HÑFì€1Ò—{/]Ü{Vƒ n bš!QÛŠÆÆœë©M%r2TÓ„éœÁ=‰« jŒÛ)þ”X|Ɉ·11ÀpÇÒ½zmýi¢Ö?îS¼œÔj/t\žÜ}EcÆáNrE'–Î( ¡5nÎk›Ôü  jD´¶~T‡øáùåÓô®˜`zÐ͵I'€3šI£Ã.šÇÁþ7½ÓUžk&€O%þμ÷RÔ—R¿–êeFw=Á<}k[Y·»Öµ»ë˜ci™¼É›' ’OåOÐ<1o¨i‚æà]ÎÌá<ÖÊåK•3Øu?È„É`Þ`òÍøoÀÖ]¾¹¬hY¶;”/ü³s§zôµpàd0éPÞiÖš„^]Ô)"ö$r>†°Cs}N{Cñ…¬ñlÔçòç$ó³ ÌþµÕE$SG¾'WSÈd9¸=WÁP–ÁüèºùxÃñ¬+)¯´ÝE"I嶸 €>¢¨VRØíüi¬>§E0dØÌUж v®ßŶO.ótñ° *ïQô#õ®‡S¸Ò¼Aqåj2F%Œmò§;Xb1ÇÓ­d¯ÃÍäÄ žI†p@ˆ?δŒzÜÍÊÊͺWˆ!’2a»Ó¤õÙ3õ/|\šE„³ hn$‘¸)(a¼Ž21œqí\lþÓ`“6W—eGÞga·ðÀæ§ÿ„L,i¶à³¿ª>côV×PŒck³•Ô¼Z몉5H¤žBLŠS,O¦ú dWqÜÞ ÝUI8@xnÝG­wV !¹ÿMÖe‘_ŽØ ƒý£ëôé\¯ˆ¼;§ézñ·€yQÂÏ’Ççõý)Í7ÔÞž_r×Eä°Ÿj•µbíþÎ+×_ÌÕ'ŒùdyZï,µRÖsþdѨHÎ>ó…ýkŠñ%ºZkOj»Ê›Õ¶‚OâIÿ#Žg&’RÔĉ<½Èƒ 'ëYz†Ÿ5Ï–ÄFàTñŒ‘ý kc#=Ç ÿŸ×°ëÍæ9PÅ0ýîÒªOqéþ}iFNãœS‰Î‘íZºùµºò‹•ç¿¥P¹…¢|UÉ ‚­ÑÊŸ,®}oà`ë>·vmÒÛþåò}:~„VÆËÓkà#ì›”ÐßÐW-ð#]7zŽ›#|Æ%” ÷Sƒùîý)ßoüIìC|¸’fÈÔÅY“;s] õkIuôG=˜ª[þµD…'•p^UOl0­ ÑÔÁù7³|ÇiçêM=òÅYˆo•HüóIl ç_ûçÿ¯PI8å<.¸€XÜÈÊHÈõàŸë[yÆF0T/NÜÿõª¾iˆži:°b¾ÀKy*ˆ%eÆÒǧ¦ þ´Æ<Ò»õÏá^ƒðÎ#/ˆK㈠-ô'‘¯< ¡Ç'±÷äþ•ê¿ àܺÛz"\’?•)lR=+‘ßó¤ÿz‘ïøQ•ÇT âcÖ—Ñ’zRàÐcÖ‚¢†tA–e\úšMÉ·p`sÓXÜ­5Ëž¨>§š¯5ÄÉ Hí·ç©fÇåþEO&Y[ËÔüþTб.çP|иè¸ïˆ&‹CÑÄ19óîxÊŸº½ÿ>ŸuŸjBÛKîFWóW%ã?]x–Qucª5¬Â0†2»£‘‘ŸCBܨùž7·7r@$W’6FaÔŒøzVî›0±Ó ¶#õïWᦡc}­NdVÁ–…ÐuRʱ㞟J˾±Ô-®Þ7·e=F>`G±ÑMs7g¡êÞÕí›XI!À2™%úßá]xˆ‘‚ÿ•xŽ‘«É§ê±ÝDF仟¼;ƽ¦Êî+û8®¡lÇ"îŒâ“¸îìLarO¶M`øžÖ¤Ï,éä_Ý»›>€×@ ïTõ=:ÛV²{[•%‘ƒ‚§ÔZ†&Ó<)î® —K€N0@aù±ý§;FUc·Þë‚ëÃÿŽà~•ÖÞü3»Y÷YÞG$}@ßOJ­7Ãý^(Ç–a•‡UVÁúóZEÆú„¥.†7R}žV,€òªÄ~µ©m«‹8<ËkiRB0[í-žžµþÕíãt’ÆRØÆr?JQ¥ß‹|9ØÍ;Ǹ¯&O6¯4ñª:»2dÛÿf®#Z»c¨¶Åˆ88#Ó®}k´þÈ¿eR¶·í”À®X[›[«û©bT_1£ËÉ`{ñÚŸ4z0„e{´\ðíËË®yþòTLÝñ þu¯„þÜÔ œ¨”®âz‘ÆOåüø5­´¾ Ñ^êö']Bð”ðÜò+ !$¿<‡tŒK9õcÿ×ÀüOZ£WÐí¦¬UÆ1þ÷¯¿òçÛŠÏœ¢ê1y¶1ó1=p>¼“Ú·ã¶UË‘•Qœt cóc°éY)b/'yÛqÇo_ÇüšÎ-'r欂ö$º‡|y< Þ°¤ˆ£#Õ%£)"PËœc#ŒÔ3é±^\·R €$gàïúñÞ¶SV¹œ©6k|º{/ˆvdœG2¼.Þ/þ<i|l¿~:û2œ‹[tñ?1ÿЪLJ4H´Û+=Z¹–úVª‡Ÿlçô÷¬¿‹ö†ˆWì3ûÕIâƒü*£+»˜Ô‡.‡ŸI]ö‹eú5¡lmURA8ädÿ2+€ç¯Þéd°ItdgüúU³ÝíÊ1@q ;öÊ6Áîçó\b-ßÔ šßM8yX$?+c»sW%Ô¡·‹Éµ\¶€>´³sq°(ÜÄ•U=[•xÌÐW›§°À55´®nnt¹VUÎqóU{û˜Õ€l•9éèN•ŒÉØ—å²Í÷½³Ô~Uí¿ íöxLÜtóçf@ʼ5Õ¥”гÈvªŽI'·×¥}'á'û ÖZvrñ'ïþù9oÔš™2ºçÎ3H8P)zv©$LZOZ^´ :Ð5 êª1ÆÅ¢EÉêÿëÔûp:Óö¤Æ™­#(Û©§þF¢ÝppßdL÷,ÃçW2)@$Ð;Ø¢°LëóŽzíbqôéü¨ŠêÛ<Ì€¹ÉàñWJqÍW¹€IÕê#ŠÓLrÊñ¸g¦àGóªói7&²·w=X É«8-².xäÒÄKD§#‘ë@:܃ yªx9®óÀ~"’è,å›ýã*ªO ý±éžGÔŠó¤¹PÆ ºÊF}½j]åƒË ¶Ùa`PŽÄr nÕÑúK#ÔRwýjŽ“~š¦“kz¤4aˆëƒÜ~y«€c¦GéXaÞ”ï˜wCL8îýin¿¡ ,Jô R‚¿Ý¡ù³ïùÓ‡ýji“aìˆÜ•Sï^C'‡[\ø…kbãvfÏwpF;ÈýHü³^·»œu¯>Ôµ­ïÅÚ›°EۂÜíúòäþŸsZwÕ?Åv=kÄ«§Û…6Úhe,?ŠOâüO®k–…B‚IÆ:_çß·SQBŒ¤–ùœœ±cß=IúãÐõ«?qsœОÞÿËÓ¿&°›;)Ç•5ÌpùKò™o¹ç:séÁ«FžR ¸çú~5u7›ªGŒãý? ݳåP¤rUä–=©5 YÅݶN7;óÀ²O¶zô‘­‹ jV:a’M>àÜ·ú¸2@ÏBqÔôöâ»Ïxì5=V,ÝpÑ@yûŸVþ_ZôÜ:ãéW[VsÕÄYÚ'‰ÛYêz~kfm$‘_blØß+g©8õÅRøåesN½Ûƒ=¶ÖÁÎIÿ^îÊÚ¼ëã&Š/< ·È3%”¡û­ÁývÖ±vf2©ÏkŸ7Ë…X|Ùá³Æ+¬ðò›ÈÁ]Fõë\Ä«ê+²bõpvœ 5µÌš6ËP€ Þ¬¸^çÒ¦´‚Q·o—¸ªòI÷­+{¶”$obF@â¬Ajƒh<|¨2]b™#vb‡ §¯½fÝmÅf•.Ÿoèkfq²99ùþuçÚàš=VG‘YVL=˜Ru=ᦒºç‹ÖíÀ{]˜øvdoY3g¥ÛŸO1«ªÇ¸›¡Z-‡‡´ëHÆP"þ8çõ«Çœr+kê[Z’qŽi9ÇQùSóÜý)zz~&˜¬#œþ¹ ÛŸ Å b9AHFy8>ù¤; ÎÁaŸöp_¯cƒÃ–öÜ .'Žê “ú‘]àç ý+Äþ&jmñ[[«*Æ13‘¼òOò…'±¥5yŠ*ù€íÆÁޤc=»};u=j;¹„3žp3õ?ý|ÿãÝéÈ̱‚Ns–àø}qÇåXÚß™)AóF‡æ×Ûó5ŠWg[vC,”´Í3œ³“^åðÉ ’k÷©ºâQþŒ„«OïcÔúú}kÈ|;¦ÿmk:u¹È¹”)#¨^¬,×ÔðĶöñÃŽ5 £ t¤UÝÙ…YòÇ•É#œZi“±úÓ·Æ R€;þµ|§ €“ÈQŠÎñ–5¿ßé¤ ÜBʹ=·ëŠÑ$7;Ž}©1ïŸÒ•šñÖ£e=•ÜÖ×´sDår©ü9r¶ú¤lêYTœ¨ëÐ×´|[ðGÛí[_ÓáÿH…ÒQGßQü_QßÛé^hÆßQˆŽ2ÁOãZ'rÞ§§Zj¶B¥[*dŠ®Ú¶fT†=Ë„ç딎âGvUUGzޏ5§j®Àn$6x#ÙªŒÚ7æ—tDc øSQM¢ í±ÊV[ràœpÊ:ä~¢±#$Àæ´a•mÈß:/€{ð¦#Ü` ·Š(D(PÀP8©U$wúb¸¯ 럽‹Oò’.abz{WgŒ?JÅÝ2ôh“¯~|ÒycÿÕM‚äŒ~(2&~ø4]u >ƒŠ‘ÓoãM;ºsjPÁ‡ò ç¿?SŠgÌoçN½.à=áAùºP=ÀžqHÞ˜ÈôÍ!ÇLÒmÀôô…Üb€ÿ_Æ“Œc9ö„¨ä¯çÅaïé@L `cé@zþBŒ1ägó ‹Rºa xÜǽz?‚¼7wöÑÞM+î{øöÅpz8Ý©Eõ5í^#º7 ÕFÕöÏZÏ&ŽŒ{˃ˆàŒ»`+çuûF¹©Ë;æ\Ì]ϦN/ðè{vž-ñ¸ñEˆÒ4«yI ³–#ø@³Žj•ŽŽúÔ…f…d…YC) ÷¯øð¾K$Ö´8÷ÛæKl£&.äUþUî[³ü$ýj®¥y†™uy( …å*;…ãô¦\ù£O{kÈvÊ JŠÝzõ¤è60¡?rW×6¥qv¡PÍ#90I8Õ¹gtnCîÊñÿ|Õ ’5 çU+ ù¿»þs[°Ek¹P+œdëÿ×…§H>ÐÀœo8ýøVÚÉŒðÝ¿ÿ^¨†Mníæ‰‘´pGQ^¥áÝlk:`~VhÎÉýñ¯–ök{Æ‹ËÙ p®;{W ø>ÖîÖÔ꥕,€Ä¦C÷‡¨úL•Öƒ‰Ý}Ÿsd¸üèXâ¶~˜§€ŒÝ})Ü€¤zÀÓ™‚ª¯+Šç9úÓN?…OÓ4 yÀúšbóqíô ííÉ÷¥bsÉú ˆÊ˜ùx>â‹‚W%Á9ÇÐf“ä/æj-ò7‰ÔõYOÞÆ?Ú£˜v°ìŽ„ôlSü$ýiÑG3èi2¤dߎ*®!Jíþíz1ü(Ëê>´žg©'èh§ÇºÝ©¡ô×­øfïË&@ï^UáÈÏžÒ‘ÀEwÚTÂ9ÐçŠç®ï#¯­Ú4É÷¢œñZå€ã9®WC¸ ÞºˆÎôþTRfU£gq ¥x}+ŒñšA#êm‘°±(Æ*ìe’8Fé]T{šäüQy¥ê:y†)§S˜È^÷Ít­ÌÑçÂâ@¥clóÉlgó¬mvõì­I@žSµJž}ÍkH¥ ób!ÆzÖ'ˆ-÷Ù¬ªwl8àò+[‰®ÆÕ–‹ýeca2hÁuÀd`p}¿¾8«šî­« &w¼ÓçBÑ…W‡kF¤ðX‘Ïqù×-¥ksÂ#ˆíf: ƒ¸týFø×eG¦MuspË¿pœñ둎NyýI®KÙêt[K£Ì¼Um%±‚XÔ=» ]Û~éúŠÌðìã]€iߟ¥wk½Õ€Šáw£¨Áªú^ƒm¤Ü<ðDdfÈÊjê±ÏÔÖ<’•™»yB# s‰zŠô¯j1jÖ-ÌP½Ägh WÔÿ*­â_Dñý§KƒsŒ—‹q9úgùRæÖÌmz÷›˜ín¿ ÈüýTðZFÞJÈ Ï üºS™$Þ6)—‚Œ¼©üj ‹ó3,ŒÝÈã?ʨDÉ7•(!ŒL§ bº«/j°Y„QÔ®Ò\‚T;=¾×ô¦ cù‰.êS¥KC=JÏÇÚláVé%·“änQøõý*ω/m®ü¬Mkqˆl¥åXà5åJϰ·Èð<¥©\?öEòC$‘³BÀ¨8c§½.]E¡ç±>ì¡ê:V–™t`¸U9#5†$(ùèA«ÐL7,Šy4Ú°“¹Ú$Âða]·-´däŠèTãŽý³ÈýsXúLŒö¨öå[fÁ±râÚìrz w=E3'¹¦_hßð“Ý>¸×eŒ–TÞGðž{Õ­gǺ¦·ºÒ ZØ• ˆ`ô>µÄo¢Ò"Ô F{·($µ·BØÈå‰ëœã8¬ý#ៈ¯vïlácó4σ æ¥M£^D{…¤’_ érI¸±·L·¯² å ýj .ÑtÝ*ÖÉáoÇ»Î3VK z{TY ²=òwò¡CŸáǹ§€X9üi…AÉ)Ϫõ©qÅÆ~ôƒð©B®1€ß^j¾>Y?ôeþ÷>€RZD¥Oc¢h·OÐÓüÁÐ ýiCw'ð£FJº!6þøôá/÷›ô§ç=¦Ž´¬Š»`ÄmÀAüÍCæ0ãÊ’W8ùXãÐÕW•wr~´6\b|ɧı"ªŒ]«`éX¾KÁ)V­;féšÆ[‘Ðõ_Nsžvv³d W”øvõ,`þ5è¶7 F3Þ¦.Ìš°º.O¥ÛK;Hè\¹É Ç¡ª×z5“@á-#m; fýA­â@yÅ.ò£AúWR•ÑÉfxî¥a<7OïÓï+ddýk›Ö1§\)ˆFÁ{õÎkß§¶¶¸š(Üú2üë›Ô< ¢ß³–‚XËäŸ-þ\ýEiÏÜvg„ŧ,6V÷°Éþ”£ÌuîAç‘®Ö -n­Z+dx Èdç$‘Ãg¦IàT´›L¥&“H‚ÕäKUAÛC.>`z™ ´¸cÈ?CZ×Ïáé%†âÚëì‰"ò‚–)ŽÇžõ¥ ø>/XI#Ý@XãèqŒŽkK««õ0ìõ[ý=ƒ[É³ÔÆp*í4ˆ–ÑØˆïÄÓÜî ã|ž¿…g\ü7½‰´»Žv[ ëÍR¾ðVµi*9Ôuòâ?ƒùRÑ”t>.Úúi¾›E(Ò¶q2–¶åEyá”ùnb~î?§ZÕ>×&³¼u!YIúSúӭ¤Î?ÚòÏÖ‚32û2Ðäúçüš±\ùËôªî££êRÄ—qÉq• s»ñ¨dÚð…÷þ½iŠÁòl$ÆÄ“É"—÷)xÊŽ}>¢’©‘0#Ñõ©-­ZöTŠi$™Û d“@=5¹„å21*´e “}Åz-ï…b´žkyá•.¤\°•'=Ó5ÊßÛk ñù‘ò¶0HÍ Ík±sAÕæ²o”Ÿ(þ•Þø ?·üY¹;¢´C:¡èÄ`/êÀþæ ÖéX· ld?8>ÜWsðë]MPšíá2¯”cÁ;zöZ†ú#U§ÐŠÜc¯Ö“)ãŠä-<}¦ÎØ–+ˆ‡«.Gé]–¥m{›m&øÉÀ`+6í¸r²âœýÖ§û³LóšBÞ´¹…bB@š~îCŸJp à SDÌÿtÒm‚²ã½?cÈüé¦5Ü=}ù©w2õPG¨¥nàß`XØuäzR°NV0·¢ýi¥rMQ:†âGÿ^¡Ÿ¥9œöÀ¨d‘±‚sI²â™ ®zf¨¾àß|Ô·.þïãYÏ8Ü~sRj ¾r²Žè܃íRÚ¾@®‹ÆŸIe(… ÉòÛÛÐû×7lŒ¸¨’±µ7ttZ]з¸RsŠîôíMYWœ ó«ub£ŠÕ¶¼–; ÉšÚçªé³‰™³Ï¤z€?*æ|&fšÑî_*ò¦S]9ö®š§%Eïh=†G"›·jðÀúdÒ4˜8r@íƒ@ecòƒŸZÐÌq+Œ·Ó4…¸"†VR ä{ Br­ŠCЭ –U–KhY×£:GК³EùAãØTyþ÷é@gÏÊ€ýy v$ÆN;ŠvÒ9Ü*1¼‘¹ÿZUC´‚Æ‚lÉ=ϸâ—{tÆ©¨ÖCžxÏ¥?<óEÅnå]OM³Õ­ü‹ÈĪF O¨5ÃjŸg“LºóWþyKòŸÁ¿ýUèY 8WR[¹´Ë”³*.Z&n8±ÇëMI¢¬xÁ°òumx­nRM²7Rž§Žµìþд½:Æ;‹%iEÿ_(ùˆþ•äÚx—NžO;ÃÒ\IŸ˜ãxü1Zv¾&ñƒâ ò8ûD-دë[)£9FLö ´Û)çy§·ŠFtÛÔ8漿âÃ8¯ìåÔt%†) RÍs‡¨ö¬›»Ïë¬Wì7±«q‚|¥ýH¤·øwã;‹yÖMe,–a‡ŒLÍ¿ëŠHì%I­nyôñ–è*Q›l\`‚Cò”gÚœHó¤ =9÷ª$UfîÓÁfÀÞšY‡Ý }(ó2y昬#0Ï94†CÛ¤ [ üê&Ú3œçéIÜjÂiUXõ¦™æÐLy êßMÑJ,‘”(ÉçéUd”×+`íúT)sóâ‹ßcEnT»•qž>¦²dž=ýý_»ˆç;xöæ³^=ÌNÿÌP¢jŸcÿÙtango-9.2.5a/doc/src/dance/0046-reduc.jpg0000644023471100065110000015315113034745265014546 00000000000000ÿØÿàJFIF  ÿÛC     ÿÛC   ÿÀ¦œ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?üÀf`Œ:9ªñ±ÈPp}1S˜ã9¾5Y˜sŒó^»8âºW ÇMØÀõÁÿ ½&ô’ÏùïYšAÝ0Û†!9ç¶+£Dä´Q¾GV€Hê3ßÞ¼ Wñv‚ýÔYÉH0ÄzôÕéíÞ¦¼\\J:üǾj •±ÚØýÙïš@Ü`zSsŒZ^œÑ`æ/iןfrî·C[*Äç¾+›Ý‘šÔÓ/÷2Ã3|œ' ö¨k©œàž¨v¥`dE‘9lüÀV9ô?•u†,‘F@sYZ®–#ýúr:²çBkaEÙXÉ'éô¥w§Ò“8™wÆz¨ÏaíZ©hL•õ>iU2¦ {õª²|²{~5Ñ.ÔHœIˆÇ>n;÷¨N†²d\ç“°ÿñUúT§||]™GCî¿xÀ ‚Iã½v) É;pã²tÝ%-'IÆpFzúýÎ+l\rJmÉ<JòëÒ”çÍObŽ&”i¨ËFŽ/RO.þuãïg~j©ã¥lkö›Ã*+Je=¬Ñkp<©wÁMs¸¸é-ÎèÎ5#xìWéôÏùëJ3¾ŒÒÖ2G žô§¦3ÏZ‘Æ2Äv¥Æ–úVÖ'™ +ƒÎ8 dã4à¥ñ…föÆÏjj’ë‘Ï"‚¾Àsô¯ÐØ\qŠ‚>lškä¯9àçšjM ÜÊì›ÌsŽ8書žœ{Rο­.:*Í»plL'ÿ×J0£x¤[Ðnâ“¿ó§7@3ÅPzf #'Ê‚yõ§„qIŽÔÈóŸ\R­.:žô›q鑯»‰ÔäóM'9æžHÇð¦žJ¢X™Ï„c4RœS3bté[¾ ‘—ÄöOV öþXc¯·à•2x§OóŸûäÖu~ z37±ìðã Ôó’x¡;{uÇáþ"Å€NÆ;ô¥G!ß·å¿=kæfM•ñÔ€I¨¥Œ¯®sÇëéO(ÃsŽÔöùO¡â­X ’-Ô7ÝpFj¼’äg¶*ìÑ&8Ž W™6—%ŽñŒy£Aîlx37ˆñn†Bp9Ww ¾ðl.èϦ>RGù÷®KátQ§ˆf/˜>É( éò‘ùW£ÚéÌ];£ÎFyØ©®*Ò´ÎúKÜ2ÇiE ¸„\ç }ãÓüúT·û 3 3·ëÓÚ´Ä7Œ”‘Q0ÎGÌy«3dbñ†#{¯\ŸZØÝhŠn˜³ÀþZ„Í}Ì@$0=rxþ´º\Ígîø›j„`ØÇÌ3Ÿ^õ§%½œŠï# npcŽ8ã^~”E¥:ÍQpÛT/’ ÷á€is2yS܃œ[j©gssr˜.L!e)<äÓÞ¹±f^C¸†\s׌àWK%¿“q'Ð`]¼pjeLcûÝù¥EÊŽ;Ô©Æv‘מÕvÐDR«¸vëïõ©QB†#·lÑ:ˆ;)äŒ`㌒›Ù…y˜vvg·„Ö’0µÍ#j¼ñ:°#‘žxâ¹ù!x=¸ë^’!!Tì?7 ‘€ErÚÖˆº|žp¹sÈÀãÿ­þ{×VÝÈÇ·ï sO ç8àŸ\gŠT/üjËÂã#ôü*´ÈXî'Ÿ~‚»Õ‘æ§} C ÇËïÍMþ\¢Hòy Š«î'1êAþôþ7mP0¯Ìì5tîŽÓH¿P€«efU·ó{ŠºÑ++FÊrWm+ÄÉ*|®…HíŸóýk´Ò¯ãÕ`²Œ†LŒ}{W‰Š é{ñÛò>‹_Û.Iî¿•Ö4©4냅2@Ãåqž;`Öjä0ônÖ½{4¸‰à‘7D縜Wªèòi—A‹9ó÷‡¡÷®Ì.!MrKFpc0¾ÍûHmùT‰s€HîþtD§Óž¹#‘þ¥(ùPÔŸJw—Œ|½209éimO*í ª—9 ’ Î:R»ò‚ çŸþµ,@³’p®Üÿõ¿Î)Û6«0=GRsFì'~äyÉnâG }sN Ë»€ ÿõS²7 éÇâ?²öÛÉ Wu¡S‡T‹öµ#ª“!0©l‘É4¦Ü"£ Çò:”.ÞÍÆsÚœè\ ¶èzV¾ÆŸT¾â=½[üoïeo'å;•Fni<à§sÚ¬.Whä€pîjBªí‚qÎr:TÊ5öWÜRÄVZs?¼¦ð` (aÇR?l l¿ýz°S$gG·†%æ-órÊ£ØÁ?…}Å*õZøßÞVh‚ç*1À'ŸÒÂ7´ãÑzÔÅJ’GÞ1HCàðzã½=ùP,En²y–»Žáô¤1aN9Ç< ”ÌFqÇVˆ¼à“‚;Ôû(*·«¿3ûÈ cqOša‡§lŒÕ·Œ—vãΡo•˜)ÎzTºTïdŠöõ_Údi˜ÍŽ@éÜV¯‚þ_iùbyîŸJÍ$±^}ù5¯àæĶ I Iëõé\ØŠqTg§BáZnI6{31 ´`ŒtÏ9¬ë™YX€H'ÔÖ¨*ñ”Ü“Y·Ÿ9ÀÈÇ?Ö¾I&{VhrNFáïVÊrXÆO#ùU{X‚0Iã pjß–xÎO¹ãóëNé½A¦S›$`98ç9#ôªî§9c÷ŽI<þ9æ¯2‘!ÚÎ:Ô~_˃œsŸn”öØ6:Ÿ…17öýϔŜÜg`ëÒ½RÞØ#ŒŒaÓi#Ÿ¸qÇÓùWœ|'…[Y¾ÀçìRäuÉééúW¬¬{'}Õ‘A$°O?‡ò¯/ÿxzT>a\ -òˆd `î=*i"+&8FàI5*©Ü¼6 Çž*g‹Éçnqß“þÿÉçlÞÄPéitÌ(‰ú‡|ÆÞçòÿëÖ¥¾™q ÝÚ]#ÛßDe…™á-»£ žuj¼Q"™Wd ƒŒóéZz^“}=Úý‘%yX.ƇàuÎøVѵ´WdIk¾†?‰5'Ôu««§Ë#gË]ªnÃ==³T–Ô© Žƒ³ÓÝø¹î´ñg±ÍŸ3I¹òÙƒ:† ¹ÏÝ8'ß­E‡õ(R9¥³O"îÙî‘ØžZî€ìAVÀ<ç·J©Á§ewßCh ®öõ<âêÌý™å1…O–1ƒèÀŠH홀s#t]Ýý릚Ð\h–òÈÜÀ{1ÁMÙRyÏRÃjè´O[ø‚ËíSÞï# HÉïÐRë×ñé¶1M&|¶˜'ÉÛ œóô§D»gÖ¼œbj§È÷° J¼Ëvò—VÀ䃽YŽ$¹dƒr7Tl*­»cqQƒêzbµ-œ:ªŽÝ‡® Ùž²‰Àkši2ä®ûwkc€yãô¬&\`‘ŸNŸ­zìú|:„Aqš6ê§ŒzòkÍõÝ]"ðÁ  &6õïô¯Jž6IrµsÍ–_îŒc€ÇkqƒRÆs–#Šc®鎼SGc“Z}iö3þÏrìJ[j–Ï8«¶’i޲¡è~ecŒŒô5˜¸ÇÓ¥M–Â…##¸¨x§%Êâh° -IHô=>ö=V×Ï€lá‘{}õ„W¶ÍÜgs¸{áô›÷Ò®ÖxÁh×;ÿçµwö—PßÀ—¨Çø±¸|W“5É.hžÔ-QrËS‚Ô,M•ÛÅ)_” 7@Ýò3Ö©˜%A'’nkÐõ]&-^Ód¼HPã¡ç¯øWug%„¯  †°qÿׯNù5f®Yïì"ª‚ 2düfžv2”R3Ž2{Ô £æ;÷+C•.NâF=8­þ»&¾¨C~añ£}ã¸ç“œÿœSÊ6åÈçµ2E-³89îœÓ"3ßàÓYƒÙ6ŽR¦®çø6+0ã#Žƒµ“œŽ{÷ª½€Æ{â”9{ ?´eü¥bG¤ÿÏ”ØÀa¸tÇò)$û„*’21ŒsU±“Ž2=)˜#žÿJo1wøb¥öÿÌ€²| ƒ’@‡sN¿•&“ɽW`H$úr ¶~÷lrx£ëÿÝüIþÆ]'ø0òºãïe²G5 È&ç$tÔ׸|2g_Ù r6—ÆûmÅtRZ¬©µ€}ür?Ÿùõ¯>YÅ¥ËÉøÿÀ8åPms5³÷µ±ÐgÿÖ¨£1ÈÀ¾‰}"0CF GUíü¿:H¶*30Ï$ $ýsMg }ÇþŸÔÿ¼|ðX ¼ £®yüj0Û`Žkè¡ÙHŸ5¤$®q˜Áþ•]´m=–,mŽ û±(þŸç𥛯[ÃñÔÿ¼x#ê3×¥lxYóâ-8y„·š$ׯI£X lm˜‚>Rþ¼:ŠM&Ê$Ü–6ÈË’®–êéÈÀëÀ¬ªæŠpqPßÌ#…åjWؼ3 Ê©ÈNRD˜a¹}H­x¡Þ‘Œ/N´Ù,¦PH œ’{uÿ?þªù5${”cRŠzœ`ž‚¥+æáBƒÏg>ÞÕ!ˆ)ùA “€;Óž6N¼ßIô‹)ÉŽ~_cÆ*&`¤c‘î­Mp¥yÈëÀªìÃÌ#9úÿ:»“n§ð‚0ÚÆ©!-“8Ú=HÅzÅ´?éê3Œ2Ý×—üRºž²ÛI"É—¯<°ëkG}Á\îÁï·Šò«¿Þ3Ò¢—"1ãˆa8 ƒ>œõêwAóÀ9ä|ÝZP«ÀÈ\($ñÛ§Ó­I"†¼|È «õƒ:Ò »e¶€Þ™Æ9­Ÿ iø‡[ŠÊÝÊù‡ãRûLä€{V5ÜE’L8ù˜t5¯áO^xzøßé÷g—x]áAꀃŸ×Џ¾ær¿MÇxœvG¼f‘¬ç¸Ž9˱. íÏ¡\véÖ¨6£5–%¤RÞ<¦3<“n“fs†ÀgµAâ]VK½F¹w3Ì<ã.Ìî䳞§úÕGk»x„¢*O0UšbOÌ;tùëÉ­›rNç4¡Ójæõ—ˆ,î|âæxÚi#’9.™b»`¯€‘ *NÐ{cœÖ}ωuåÇmCI±P.HÁ=NOá\}§…àKý.vº™m LL.Ÿ|y.ÛXÐ èw޽«£mYI€0NK{œŽ¿çÞ¯šßáK–çÈ‘Ä÷ÿœU¡-÷h °@ ÜúÕ€J0.xãúŸNõúÔiŸØGìžžõ"@je\0 »O<*`UŠŒò8#ŸçZÙ%dIÊ|B·ß ) r²«vô#ú×3á_ f—-¶&?$Ÿ”újíüg›Ã—8v€àu={~¿­ydP2äìžkÊÅÅ7iÆ›xw=]Q³Œm#¡jÝ@'’:çŽ+“ðƼ3öK«€ÄàFÇÿ²úõÕÆqÉ#¾ìׇ=7>•#ZØ™pÚž¸ýÐÕmKK‹W³1ÏóóÇÝ=x4°6ݤ£×jý¾Ùá¹ëÍgèkcÌ5-%¬§{iÓ §ƒŒïíY_gXåÃ(=9¯WÕ´xõh d„qó#c?…p7ú\°Jb’0Œ§¿·çW;‚’Ѧ .Þq€jìI ”BÀó»9­Da1—V#¤S£VIŒÌV»õ1Ò/bÈ·ÜC^Ý#ù~u{J¼:Eך»|³0c9äþ•jC+d£®?Ï)Nƒ¦M+_FËtŽÒÞx® ÄÛã#!·ù?•SÕ´X58Ü”_9WÄãÙëXúf¦úseia#sÂ{ŽÙÿêâÄ„2È¥À~£ô®V¹Έµ$y´–BÞW“§IÆ)ó„ã8×üæ»]cFŠ…¸@NWÿd‘\»Ú:aXm#Ï·Ù ‰«œuh»Ý [(¦RYXàuèHö¡´Øxãå –õörÖ-ñ®ÓƒÐùþµbHþO›9ë\²‘ëÑ‚PZK§C´· r3œÑý|ÌŒ¡=«FH݈rÀ7\…§‹—8ÈèsØÿéPåe¹²‚ìe:œŽ¡Å,šl!ä$ûV„†$ÎG=é<¢€ ¼œ“ïSÍ'aò¤f¦› ¿wpn£ š‰ì!ÏG'‚rkQÕÂË`nÉ?çÛŠ‚HвîÆ3œóÏsV›}Hi'kÅð¾ÜEá+EQœÆNOÞnHíÔÖŠî§Ðô‡¹·EyC¨Pvœ|ÕƒÚ{]|É7’ª2z ‘[-? Nû0XÉcøÇø×˜¤u×Så«Çß—©ç_ðœëïÝceÉêã×ûÕü@Õ¿èd2rÖü¾þi’ÛdØ=óÚªKoØgÜué[ûU}Ãxx÷dòxçV ÍöKP¸Æœuÿ~«?õ9‘kç’ ãÕ„mãë’*»DFÜ“Ó5¯µW¿*!á×vt>ñ 浨¼3[ÇØÎ6dä u­Ë¤S®3ÝÅs~ w‰å 4p£ ü«°¿ˆÇ0ÁàòßJλWZt9ù,Ùv5ÏŽG989?ÏëN01Ðô4û›d€vëR*Àá²{׋Ìîu%¡LÛdŽ wëÓùÔ2A…b“ÔsZ†Fîª?ˆŒcñ¨¦¶`)ìóý*Ô¬+QÀåH<|§>•H[äí¼zÖôö JØÃgµT0d†6;}kTï¸Îëà|j/u 2Çì ÿã÷ùþ•êì¥nË•9ÎÏä¯4ø)˽oøOÙÔsß.+ÔòVl¹= ùp?Ÿé^eoâ6z¾c`œƒ‚ÑÃÿÕO2…ÝÎÑ OûDÿZ’Úœƒ÷0{z~Té´j¸À)ÿ‘úÖw5)´p’æ@Yv¸!=zóùÕ¸m‘•Þ¨”1†(çõÿ<ÔifxÚ$Iƒ¸çðã¿5£ghÄQÄ»™”îÏÉéJÓ¡0nbº½,Â6Ìi±7.K Ç=:õäÓm,eÔ-¢·Šâ9/ò/Ù¾}Ù a‡__ÃOXf²³’y $b=ê¨ã®Í‚02zöÏÓ<¥¥Þ¯mtRÐ-Ä×0´¥§ºò?˜`ïÁûÃ#¨àVÐ]1½îtÙÞǧ¯•=£ØÛóÈ&Oœœû²rØ'ÐŽ„YÓEŠãs=ÈÁÁVÏ|n{ó\ÔöÒËq=®èáŒ[ÂÅ•<À8ÇcÓðªÓM¬êR¼öÚ‹ÚBÄ……$ .8é[×RZ“GÎQFÛŒôÈ=ùèjR£p@³Î°©UˆÁÉ÷ç)C†çÚ¿dhø ‘Ä($q×§?çü*u‰XîÙ¹³Ï=M ‹nvîQÓñ©ßhØÁˆRHzš›v ™¾(€É Þ"¯>K§çÞ¼y–½¾úžÆè.109Àí^$p+ÇÆ®WÛËýèÉäÌLx`r=+¿ðo‰N¬¥Æ^ê5Ýæ ã>Ýù®Ó#¦j¹ S†¥y²Š¨¬÷=)PŸ2ØöøGãç Õ¸kq’?sñ:k–`K…½L†P8aýá] ¹2¹P?μÉ'cÜ„”×2êh©Â¹g’*޵¥&§ I…Ps€G§_¯8«‘8Gbãã=ML™8aGrsYô¹´tw<æçNá·&ÙW#ƒÇV[[á¶1ÆÞƽ#XÒÖ}Ó @>eõý+•»Ó<ýÅT,£ŽÜ¯ÿ^´G}Nfª+£ <™Kcp$–ª‘¬ŠtaëT¶õ*@=OjšÊ_²Ê§ï ӛݺ2T•õ.%¾ìtíÒ´t˶°cÀ·bK¼‚{æ‘dPèÀ«tÀëïOh†: uȬ¹´:ãI$nଠã ×éYz®”.Ï_;« ýà8úf“O¹Áa‰‰Ãá?áZžYRNìwPj.Ó3q¶Œæ-#nù€0íÒ¬”68ÎŒÖժ亽7üê²E°›³Ÿ§5-Ýô’ä)I ƒ†ÁÎi‚"Ž9ýy«’E„\ŽóÛÞ«¼@´âšZƒ|» 1—P¡í‚¢†ïÉô©QÉ÷©V0Ã<9Ï2÷têRÔ¦Ñ ãŽœgžMW0|Ù_npMh2e ßžÕFÛÀÁ ž„chÔ%cÛþØy¾‘È,¥W=Î[?çüж>_ƒ®ùÆÙ"çýµ©gØ7øFà ²2kcâí¯—à}Hª`;DèGïSüyj_íIyŸ%ˆV©#À^ß ÇN3ÔäU+„ÀÎ>cÓ<ýk³´ðŽ«©@$·Óæ˜ÝÀÎG·éXº¶w¦–[«Vˆ¨ ëTæµåf²œŠJç>ëó¶AÀûÜqPKߣg¿ùô«æ ì½é¬œäœñÏ·ùâ¡èÅbÏ‚ã â…701Âôí]®£h|‡ç'iîk–ð:øK¾fÈû;žŸOë]ýí°1:€ sÿ뢼¬ãèq4¹™CN‹|‚Ý5 mÈ-»=9'¯Oð«¶úhHBó´éN6Í‘µrÝŒŸjñ¹îok™æ Áíœ_óҘɜà•8äŒçÖ´¶ÒqÜñíI$;ÔHM5+ £î̳ž6àô'Ú¨¼'¾GSþ}ëzKcÎÞÃÿž•XZñ´äž¼Ö×ÓQZÇaðn?-µÃ‘¸ÃÐgÿ[üñ^–ì©)+Æ $uà/ù⸅…¢}PpDYÀéóO¯ê+¾ž69çt¸ã¶ê⩬›gu/…Ãjœ9†P28ÎÎqN#Ì ’2DkœuçµLP*±e·ƒ…阧ÓtÆ›3…ݱ·ó2²1’8çŸ_¯=3½ÊœãN<òvDZ}à°¸¹¹Hİ$4ŠäÑîãò£‘èkjg{yhJEhKJ’Ÿ8 ·^ž•RåÄ aQA¦ã·;ús“õÅtšo„®÷Œ÷lóLƒÂ§PšÎä[´S™ÁBq@¤à޼c×µt'Ê×::”ãn×0õÍiíüO›o)6Ì¥ü¼U@ÎyèN;ƒš Ö–rHïs©­«9°Ê²U œ)9Ï^õ?‰5»-3ÄpÙéN²j…^Y.>b`\mýØa€ØŽyÆ~\F±#ÏûD¹ò—&FÜÍ×’IÏ>õ«Ý 4† î#»Ž¹ÏZ˜Ê1òƒÏÍŽqš‘BðBàœgŠs&¨~LWìGÀ yu8ëúÔó·‚yàã¹§*'Á篘B¡#ŒŽß_Ò¯±"0$ƒ dçµxc1=@ô¯yò×ktÀ¯zðwM§äq^^9|/Ôö²ëûöò_ÛšŠQ¸t©cÜRmtü+ËZ¬“z3_EžŒ³„|ç;¶‘ø×¤ø{Z·Ö’M’/ÝÉÎIÏË–.6^G»Í&öPBƒ€ƒ¯çÞŸqòžp?OÖ±´ ~ß_±K˜N IÀ(ßá×…lÃ+´JóÚkF¬{1”d®º–vù°üóÅcêúsª5Õ¼~`ãzíÝ«Z á`p(kòNjzšÆN.èóÝQ|À%î3–üzVbݶÒ6ÿ\Šî5]$@|èp±Ÿ¾7t95ÌjZWüµ…pÃ,ã¹ïÓó¦§m:TEtVµÖå°ëò6žÕ°·îÅ~PÞýZç0ãådž: µ§] r±Ë÷;s¢›ÛA$öfáºrʤtô«š~¤UDW€ÏË)?§ùúU½Œq†Ô½yéšÍ´ú›{;ìter@SïT/ƒ/2(ÉÀÎ@¦iZ‰i<©É‘ܰRÇNkSÊÜ6È8Áät¬ÝÌâÝ7sžþÑ ç'cKý €a ÜO)ÉýBÀ@Þb*ù'¦?‡ÿ­ÅSa’rn0H¨ç“êz‘ä’ºE£}]¾Jg¦7` ¯ã`3Ð{oÍF±-‚‚ 9â£6ûò P;éR¦í¹ÓÉ«ˆ¯©m\mtäÿõª·ö‘*AA鎘æ–HÏ O¹ÇùéLòÈÆ@lùÇÒ¶S{³’p]ô÷ìÔÍ7….Ø•_ßdçž»‡áÿ׫¿> Xé÷6"Ò;¶P¤¬²`Ü8ÆN¼ÿ>+öoº[OëDr.Uyþñÿ?ZñÛíQüK¬Os,Ø·,JÇ·.Iãë]9e*r­:ÓÕ­½OÎóYJ\¶¥»ÿˆ:ÅÔÒùR hŸ ³ƒŒíöçÚ±u­^[iK™yß½—¿¹®†°‡Êã$ãœú«År­½‹Ü€pT®XwÈäŒzô¯¡u'-Ï $ŒÅeçÙ/] ¤—nG¿÷ÿ"ºi"VbUxëí^,÷á5dbÛ”6ô¯j²Ûu§Ú̼ï‰sŽçã_=£58õ=ì YN.èhøÝÏŠÔÉ6òuëŠôi`*²S÷pÌF厵Æü<·'Ævé´måÎN#üq^“.œ«nì0;ôà}+ÇÄJÊ>†Ò¼ÉáÓÔÛG£  nÀüÿýuVM9—‚À’O^zÿ“þzmX'›g2 ~*Wµ€ g×·?þªð®Î´9Ç´)ɦzþ}©l+ŒsÀãœZÝšÈãÛž*«Úî$í ŽÇ©ªæ \Ä–»h¯qUþÈ<¼ƒÇnµ·%°-÷W'¿r=)†Ãå=#'“Z© «?­‚KhO’Fw×eä»BûÎÂD‡Ôœêkžð-±D¾*rÅ ößÛüÿ*ë^EK25߉0üçý`ãÿ8¬¦õg]-‘]ãÚH'h qÿ|Ócµ[Œ,…Ê3"¾ÇØßwÔr8â­ÝMFùRsâOºÁã¯'½>ÖÒ[‹ˆü¤.å†_àÅe×CIEJ-Kb‰˜[ÙŒ/0¢G±™ =Ïnžù&´®¼@úg‚¾Ùgl<7ò ¶— ’/˜Ä‚¤ ÝÇâ84­žÐÀè"· ÒPŽrw¼c¿¥RÕm®Ž‚–ZAµµ¾žè$~q$ÖIA ¬{`ã®Ê5%N^æç›:pIÅ¥nÇ#qåÞjVú´‘n¶¤Q0q•›xíÁ,GO­6ørC}¦j:ήºœry¦Ùš|Agç<©+œu srÞX´Ë«k}@Ë{çݼQÈà8›äVÜ~_›'<7A‘šžûF²×– ¬Ù²HnYåH F,FÁÜI'ǽm~Y%-_õ©…xÆÊÏ•ùoèpél¶×©8‚bÍó‚¾ß0ç íÛ?ˆ|)¨4K-Õ½•‹Ì«¥ª[YÈPýÖXå•aÃcµmØø¶ó¾ŽÎÚÕäÕ¥vž-BöÝ%KDÙRvcócïc®qÕ¯¦šæ÷{3—šbÁÌ®z¹=ÉïWH«îvGšI-Rá~L€üà¾ø©A89ç?×éJÌ8¸ëþ¥LpOȸã8í_´;£à1e‰8éŽ@¢HÈ ¸ŒÇéV’¹ðqÈ~›(·Kÿ¯éU  †&Ù–ÊIÕýuâ7ö¤Êä˜1Èî–Ü(R¸*2N}úWêP˜/§CÔHÃÇZðó;ÅEŸK’B3u"û#®3šikBæØõ#Lã¿ë^œñøW+©éméáR±c‘ؘI¯uó÷¢¤‰t»ñ Êp„áO\f¶¶aGÈcrj¤ä§8þéæµôÍLŸÜÌãåèÌݽiÎ:Ý ”®¬Í+xƒ3ŒñžqZöwoîœáÆÿkÜûÿgXÆIžAl*Ù‰x=¾?s¹4í±Ö°ê­?2æiY0xÇ=ÅcÜØ›wÈŒséŸcZÖÓyêUñæ(ÉÏCô§yaÆÙ#ŽN??Z7Øãƒ• òÈÃ`îu$òMNÍŒt ØëÖ®OhbfR RÒßËÒ«ì À'==+ ´õ=´î“E)!ÃTã=sÇzCo·ûÃsZB¸d˜uìÎ)†ŒôéÖ©K£¤·=Çö|µ{Ÿ k¶ñ wÂarAÝ‘ø~•ó¬ê:^¡uдrC+Fà¶>pØaמE}-û5æ;lDå$Âcg“^âÿjZ'®¡XZò)fy Db.ÀއÓò"½<¶iJqïcó<æƒu§5Ñ™Öúƒ‚Y™‘ÁÎ ŸÊ¦Ôµ´i„I"©=[ã5lør{—;yĽâŠ&8úŽkûI¼¸¼‘Ç:ÝÈ0Äÿú¥{׉ó<’}BßÁZ—ˆu2ºF›y¨¯,íglÒlr=¹¯eÒtï±höpàä 8#$sÅ{ßÂÏ iþøE­\³¬"x'h󄘌 qœã8®"ßá_Šõ )ní<1ªÍiÉ’;) í’w¯˜Æb%^\Z#ë0ØHá ¥'«1¾ÚÅyiœgÈ— ¯ËÐר]Zâ%8ÇZã| áíCJø‹§Ç{eqe)·Ÿä¹£nQ†p/óϦ^ØŸ*@¹^§±ü~µåbn¹íú³:–çvdv!má ;@'ðâ§’Ì qòŒ““Ï·ùö«övþ]¬YÜ@ÏœŠ­Õ³ÀéÀõíùW€™lÀžËrpWž:c?ùÆ*”öÌŽQŸc],¶…CayÏ\U¬Ã¨xéŒÕ¦4a%±RG zš†X¸ùFW8ÉÇøVÛ[|í»æÉÎ1“Óš¥4`¸ÈÍhšæÇl–EÔs*ÆËå0N’nžµ´ìË ed÷?ë¬ßZ±‚õˆÚâ%€Î>b>øÇ¿JѸ@öR•8“cr4}=)»K¡ÓOk ½¶ ÎûÛ«œè=jþ©Í¦,‚M¾Dþ²Oà?ŸLñQÞ&mÝW v¹Ïn½êÌA$¶(ÑÈÄ6îC|½Gè1Q^ì¹¥(Ù•4{ùLŠ>&ÀÚø`Ù$çëŸQ\ïŽ4½;þ;K¸žæDXö»FŸ+FrJO8`?!Ú©ézÒÜßÍc¦<š…í»0Ç „n%ñ ŽŸXÔ´óu¥çš±Z¬ À†˜îbH ÷€ç=³]®^÷CŠ2‹ÐÏ›P»i¶ÚY-Ä[¼ôŽãlk€˜SÀàÊH5_Ä^"Õï¼;z×–¥-`U"ÜH|¨AuUK¹l ŽI<“Z }ý“Q‰.¡X%‰š0>\&0qŒnx9¬{Ë5Ì:qž;;Òlœ¾› ÖÔ^IØêBœŽTãAÆDùšv9*Uåši"Mjåu /ËHãY°Ì_³Ï<Ž9ëz—UŸO³{h‰xÜ@…”@$Á9êw®OáþfëLŠÓd@,PZ£H|ïŸÑþ.ƒ’}~•KL´Ò®­Úk>òîgbÍ,šƒ¦âyá@À€æˆ[íhzÚÇ‚,~kc†lã“ì*O+ ²}Ð{÷ý29 ÐF@ ñSH €2FÏø×î=OÏâ [žþÞ´Ù 3èÏ_j±¶Ãœ‚ëùÒ²wl°ç$i^Þ0Ͱ’Àžxý+É5Èvj·Šp1+ ç?ÅÖ½…cÁß¡ü;×–øÂÙ£×nÁ üÄóÓ’Mx¹²^Ê-w>Ÿ w­%ä`lÇpÜuªwV›~u^8àV RT `š|üØZù…>Sí§ET™ƒ´mô¦GSZ7–&™GËõäUB¹Òº£4ÕÑãÔ¢àìÈX æ¡xÁ3VqÎ9  5¢v9eMOCcÁ¾,›A»K{‰éîÿ:c;Mÿ¦kØ!š­Væ³Dã(êÝx¯–,çåÍwuû«yO¹±*Í0û¬HïéÔ⹫SR\ës|-IS—²žÇ¤yÍ´Ç“œLSÈ&6\ås“Ôç¯ëÍ5ƒ,  úŽ´G0$+r½²3Šóì{0[„Û(Ü{ɬ;›#´s*°nxèkp0Îg‚8ÏZl¶é:”~I5g%ævP«ìÞ»3ϵM,XHù OS÷yÿëþ•FH÷òŠ9›Oÿ?Jé´mP]¡ÈYTÀûÞ•ÏR.üÈìÃI8ò²ä±– Œ«Ï­M¦Pß(YT €—·Z(Æ #¿ÊqÍ5¡ ‡BVEÎ:ãñ©ŒÚeâ0ʬtÜ\yŠRNüqÛéúV|–Ûd*½œûWwðßᇉþ-ë©£x[G}[T 1‚'HÂu»²¨ïÔö>•õ÷Âø&ˆ5»´Ÿâ^«…¦˜­Ž“r³^‡ÏÊŠ4J¸Éá›·NkÐŽu—2V]ÙóëO'Òµºuû‚Ä|Ý)ÆÕ‰SëÀÍ~¼øOþ ©ðWÃÒo½´Ö¼MÝF«©ð·X³øæ½ËÀÿ¾|5òÛà Ñtiã «{$ûAÇs)Øû’Mmûrû—ü18 û¸9?’_¯ä~^þÉüoâ½tðÖ©o§Ü¢¯®lfŽÝÀ'8®ŸL×Þzìmð®Á!Ÿ^ðÓjúÐ=Ð{ ¼ö2ª_DæŠì¥B•ò­ÿ®ÇÆbñ“ÄÕuW»~ˆñ]7öFøE§ÝM{¤øRÚÒõÎZa<²Ý‘Ø/Ð_?üqý‘áÖ®üW¦èº}Ý™ÀcnŒóG÷™Hè1ØžÕ÷K(aþVYB¸…ŽüŽTõÇ×¥EL=:šíèaORgåmÞ¿m¦ø’ÖÊv†G¹ž8¼r6à•ˆ#6Ž Á#ꟊ<ãÓ5Õkùt-ZxÓl2:äÿ¬HB/Ý õú×±|føa¤xãN¥$Vò#\Ù}¼3.áe™X!¸9ûßJ›àׯ/‡zŸŠä°²Õ#¼“Éòî-Ú 7Œ† T¯p$œ€HÍa)TÁ¯gM^Û³Ñä†.Ó›ßeØùöÛÆ×3¢Ki–bË3Ãç0SÃ{îoNý½8«Ë®GpÆ ‚ùÒ1 Ñ) 8ã9ç“À¬/ÛgH¾øñ"/øf)-|5­2kÀ“ˆÇ ‚$­yOƒ~7Ûë·‰¨°[³·F„mÀ8Ï'Ò¢ªXºw–·ü'Fn/¡ô¬VÌ`‹PIn;úéÓkÇô«ú5ÌZ–‹kuÝ‘#+c¨ þ4ðXðkóùEÂN/sÓ‹æZ¯òðÃñ<þ5JkL©à`:Ûu;G¡È&«I‘žCþzÒÐg9so½ò\z÷ªr[¯x8çõý+zh¾ñÚÅT’Û%Kdãž âµR²©sÂ2O´+ÎY^%ØÍ€Fãéç[S47 ÛC †}Ÿ~3œìË’}Nç—¡ÃæI28l±DŒ!$–ù°8õÿ•yµ+‹ì­‡XØOÊ»•¾a€ÝBÜŽ‡ÐU»Ù$Å(N×€º“Fñ?ÙÃ(ØÝþ÷jls¼†ÒC9;€ùz:U›ÈZÚ -™à2†eÎè}k3SYJ“‰AY\)á»cŒgßò«äåzI¾S6öÎÓÃQ Ý>×e¬“ý¢á`Cæ°1}Õ=”½óÁ5ZKx’ÚöæÚÚTû`’mÎ$…ÛÉùp¾sZ· Úu½å•¼Â)æE·…˜œ¤Œªwp?S޵OÄ> ŽÓM‘d¹Û<ð„ »a €”}Ð:ÑKš->‡•¥h»³¶Õ,Yíã3ì™#T‘TeÞBUJž9Á?0ç8¬9ü]ŸáýR]9#’Òrgz&Hl@õŒæ©$2j‘OóÄ·7r£NÎJGžI$arô8äqCèZr¤ÖpNÉ·ÏYƒ!e$’çqòÎážyäžgr¡{(·w¹j×Ú³Ã%Ô­v»JÜ€zs€¡í]©zš5ÙµrFÔ\ÿÎ}9Ícx7P[˜åº±·dµ.ËœäìÇ<€ ã$ÿuÚ«K©_Ë:®àI+ïÜÍ’x¬ª4„ç*nÛ¯SçÈ‚`ílzšŸ”ýÓÐdž¿•B…Dè9ÜÀã ¹a×q÷pZýÕÄøK‘£¡#ƒÐuÍFŃS„ž*ÄjªøØGa×ÿÕI8RFÔ'¹>¿OJV¶¡± ‡Ê±ÆÖ<6áÉãµyçŽ-ü­iÇ–@1©pzú×¢ª\vŒŒúWñ&ÄN:5ºÿ^H¯6·°ùŸI;bš}™Æº«Îâ8¤a‘ªr2Nyþu` ±#½ Ã~´Òµ-bò1`³ÆÌqìÙŒg¡9®«À¾“â/"Ó-íai—þYÚ(Œ(¨qÉ8$çŸA[{~ghmÕ‘[-އ·Å»Ié­Ûï仞A‚¼Ax³4&¡(‡>fËg;qøUH5ÙôÏÜËn! ƒò°>ùükõ[À±w…í| -Þ©q©Á¬}›å’ÏP.9Šç„?»1‚Á^@ǸøOö™øgeàßêKj©«[J²Ix€Æ—q2îFÕ#pc>Y8ç'e:•ºŸ39W¤îôó_­Îž=µžâ+ KF²)Ä“à8û¿N0=ý+¶eŒŽàzW€ÉeÈaÞ½À~3{¶MÔ¤ÌÿvOñ²qÎ}=k:˜uÍ|>*N^ζçvЧœà ŽßäT±®é°˜‚rzS€¤`GS@a ·½H?p?3Õßa÷vQÝÛ³8Øá?tÃ7®O¦x®zX÷Å:gÕX~µÑË'™…ÞXʨã€z­ub· ³³Z‰$Ù݆­É M=ì]–’&9,CLZÝÕÐí#ÈÏ5Ö5´W(ðÊ™sÈ ÖÕŒ–3l‘F”>£üz~u›–§¯Ù&t:]üz•¶Çf\es×Þ½‡àÀgã·ŠbÓì’K]-ý/PYbŸ¦NGçùù—Áï„Þ%ø½ã[}Âöu¨H&ü,îP]< ÃüôýŠø?ðoÃßü#‡ +Í9ùïoå$¼ïŽqè=õ¯W/Àýb^ÒkÝüÿà>sGGÙÁþñíåçþF·ÂƒÞøC¤ÚÚø{D±³½[xà¸ÔãµE¹º*0ZG'$“Œñ“ë^›Ú°]¬J3»–5ÆÍ|LðÛÂÌr~b1Àü{×Ao ˜3Ò!Â’pIÿ9¯ª«EE+Ÿ‘ºÓ«79»·ÔêmdWLƒ“Þ§ÝYúl!p9î*øcŠñ¦­&vÁÞ ¯žþõçšRØš’Ó;ùq±ÞöféšÉ¸Õ. „ÊÖ†ö q¾Ø†qï·¯äI­ÿIf. Æ=Ï­cj‹¡i·>mÍØÓ¥”¥´+œv]ÁIïÒ¦qÒÆ´äŸC'Vðöã=>KmVÒ µš2Š×pl¸P7Õä¾ý¼ ૛떲°¿¹{ƼK¯²E êÄœ.åèq€Fyâ½ÏS‡NÖmã»MRÙÉqo|™—=•Ð(À÷\õæºËG´Ô¼«ˆ'©³^Dç(¾[Üõ#'uù$þÖ¿,~3x_é†o¬îR{xåyŒì#ò¹ƾPøÙûxsàßìÅâKsqâÍ*â?7QºÇ$¥®!Œ…@ûä† ‚KsúCñWáÖ¥sau¨x^æÓO×[iÞ#v9uLeha£+]þÏ›Z<ýj8-åûToåWÜN#¸­ÿi ¢ëwV…B„s´˜íŠÆ‘X©daЊô¡Qµ§S‡„ösqšÖ.ǯø{[Q¶Š)¤V»Úzƒ–ÁÕγm‰3íZ¶÷ ° £wóUbÞ§¥NIêµÔ„â5ᚤ‚q<`äÜšÏk“%úó€£<~U„bîüe%ecH2ФãŒgÖ¨O¶fC±Ž˜ïéÏZeìí++RÔM“Ìr̹(ÿ>ÕÑJ3ó1NÆÍͤ–²yasÐbqî¤b¾oøÝ¬ø·Â±½×ƒ´ý<4,Æ{ Ds(`G”Û×Ê; `ò2>ïìSø¦)m$x%1ÆN7“÷<¯±ïø×œxÏSÿ„ƒN½²žh¥–( –5Ã69Áç¯P>¾õÚ°‘œ\k+£o(>h;|ø£wñ'A6S³ /­ÑÕèþûŸ+ü;ðm¿‚|§éVÉ·bùÓ î•ùsùñô­2—¡`–éþzU³°D°:á£PŒ¤rçü÷ªòÁœnǨñ¨ç7)nÎ¥] ÄCõ÷ïííTY3œ‘ÎzýkNH÷NA=ûUvŒtžù®]Œÿ$w /cëÓÞ£òÜŽ?_ò*êÂÍ#gŽojo”¹SürI÷©Í½Ì:Iç¼³˜•§*°lœ–-Œ“É'žýO—o­Íj†9Œ²È.ˆ@oË5Ç&Û±«‹’MRHd(ࣂ2¹Èíþ4ô zñQÇ7Ÿ'˜YAnNÞœÔñFsë_½Ãd~}-Ù!ãܓӥ@ÎË€¤èùþµp¢ |¹àŽÕRd¨<õ<œu¦ÁËç÷ÌÞàV~¤ªêÏóêkÐþÛ]¯ÆO„ÓCiÔw'‚çœ.|È·|ÙR ‘‚9¯C箦k(eè\*áˆóy_k‡«Nß ©á½3mõ¿äe:)FS›‚:ñÜW7©iki eùbl¨ž¿çúWV|„üÃqŒç4=²MòK‚‡‚?ɯ†‹åÜý†¥73¶‹y*8dL®[q2>=sž9õë_cø?Ã7ÿ &·@mRÅ@Ûå‡OºçrO9ë»<ù"âA倨`N6æ¾éý—4»ÏŠ_ u„Ý˧1Óå`Àdɸq‚c+Èà{ä ÆPT©®]7 ™VÌ+ÊUÚæòV<ßãÆßiZf£{pažö[g‚ÕÖÜ C´þ÷îeã Âç¨=+æ¯ ]ÞêwGU½»2ÞJáÞv]¤·8Àöí_¨SþÍ–^"·]yÑÇu ŠHãtm®Ü÷#·õùêèÓøg]Ö|,ð5ÍΑs-›2˜ßa<`rAïXa¨¬]9SNÏÐô©f«%ÆG:|êÍZö³ûŸÜr?m­N¯Å“;A,*Ì®åŠ>NàSÎ9ÆqšãÈô¯D¶zó uc$rDÞ[¬R|á¡ÁÏcÒ¸íoGm*é‚“%»b”ŒnPxã·Ò»ý„èÅ_QO3Ãæ8‰N’åo[3Tô4¶sÜè÷°ßZ¹†x¹I Ž8ÇB1R•'5‘ Ü‚1N2èÎ,F›ß†èöo x¢ßÄÚh’< ˆñçÇŽŒGQÔ`àãñÍl9Á Èî:žµã¾š-2î9­eDŸ#äã=xÿõW®é—‘jP, yg?©6³;Á`ŒüÄ*û<º á£Ëó>7”Þ.IôØ—ZÖ¤i6Â7¾}+—ø“âKhKm4©Ôä »²IÏù5ÑÇ%®‹i&§xÞ\+•˜2¥|¿ñ‹Åºgˆ¼+«øÉµEŠÒÖäXZ)Œ©º¸]­/ ‚òN0xäŠöSQWè EÎJ+vF¸ðçŽôdpD²ùª‡ç ÔŠúÿÃ1Ý[ÀÁ°^0JŸ^â¿5?gÝróâÄ÷I6µ¼O¾Û±A-ÎO9 ú~úð×Óè¾[É?™C´’zâ¥_ë1•E·O‘êc0SÀÊ4j|V»ùž²ìYUy9­+”eìEa#y–ãë[Zcg9#Ò¼ÚªÑ9âõ"%­¥m¹úTVû’GvÏÌqV¯Tg=p{Ôf< þu Ý •ûç' ÈÕ’Þ{r'b˜èÜõæ¯jT…ç©s§.©oöw‘‘ó”eõéýk¦šJÒ¹›¾ÇøŸS[ù.-µŸJ›ÝD¤ng¨œgiÈ÷¯;ñþ¡q¢YÊVeI"êͺ3øý+Ó~(é1èž¼¾ñ Ò¥®œoN¼W=O5ógмQ?ˆ| 5™ ïHšt€óáǃÈíŒã­z|Ñ•¬õ2P•›H¡ˆgX´ýDÉ»ìÓÈ£ª’Tö÷¯°<âñW†^9¿×d¡=ëàß™ßI–)Wj‡e*ØÊœ×Ñ_¼M-œQe ²0+Îz¯šÏpüôÔú£ÜÊêòÉÄîl> Øø§Ä—âçX¼Ó²aH sÛ†HéÀ#õ¯8ñ—‚¯<«ËcpR`~äè?¡ö¯rÕµ¦^Zj°coÅ¡ÍyÏÅŸAâf8áèelgƒÓÇÖ¿4ÄBŸ±ÚÒ]{úŸYWšoícË×(Ç êzöª6UxÏ\VÑiàžýê$·WryQè:WŒ´9¶1ž&$àmÀõªR[³erÇoÒ¶îà˜€9Ó?­cêº{]›x¶þäL’:ñÈR~ gÛ>µ[ƒ½´2¥¨yZf#\m!³V +“É#§'Úº«M2H¾ÖÓO& –Œn#·ž@Sæ%ãÆ:Õ-oÆúuÝŽŸ¥ù˜¸™ X.l•M¿*© gqç#©Å})Âñvn§“íKYÑu ý8i¶è òá"Qp¾^Þ¹88Pݺc­t“è–Zõ•Ì"Imã‹Íqo Üž„àôÀíëRï9¥áå S”êoÖÿ¥útÛÝ[ÆzÞ­&µ}.«yåZ †Š;xl‹œÚ#ïgå$òÕ‘àõ¶iôö‰ôË„¼È^VUPòC-Ó·QœÖÉi%Ä‘iRMc4êë$*²¶WNq€H à†ìrsTô]r÷Á -íÒ5Ì‹1†Þ;ôçØòyÂn$ð׬¤½®­½÷<øÏØ):n˶Ä_|=§KuÆ—ys4Í"å0ÇjáÓ!·¼ƒyøfáñ Ec |é—šæES*n˜¨ÀÇ¿+;T¾»³øŒÚ¨ðèŸI.o.tûÜÆ8ÎWn>S¹ˆ+×#WM¤êj—×iºWöœø’U7*¿²¶s€ÁŽ3“\µïͦÈè£í*¸ÎîK}Q¯srtkAu}3@‘©¤%qœcå#ñëÒ¹;¯YMq$‹m$;˜·–e9\žÇà’kgP·ŠÞ1Ë$Â5EŒ°ÚO=À'§<ñÓµfZG ÂVštFó 1íÜ{æ¹£´u_sÈaýâ©TÛ‘ÂŽ úqSÂÎynƒßô¨Z+»{˘¯7¨eØûº“´?M FOœêyéë_ºÓ|Ñ‹GçSV“L´«€~|dG?äU)òÌÌ ³ž¨?áZRÂP°@Á޽?¥iŸxŠk;{˜ô ùíçBÑ<¯ eÏS´Lã ‚2 jÜSÕ’“{#˜KûO&ñ&Ð5ýZæÞ9#´¸Ò.LCNºu Ð ou1>#fPÀ2•Èϸ˜\›…ûDWæ;—OµÀí"Î2@°Ø À0ÜÈ­ 5M÷_[;½C@ÕVCÆÚy-¤xòUöx!ºLÖ>›¥µ…æÀξj°$ä§züö¶.Ug^—W{ü¶=ü‚¢†eJïgù¢ŒÛŒð=Æ•›lGn‘Û&º ;áÇ‹õ[W¸±ð¦»} Ãy¶ºdò¡¦ ¡5RïÀ^(°˜Guá­fÎS€#¸Ó¦F$Œ†\ž3øf¼UFisr¿¸ý¹×¥{)/½E¬ß>¡¶åÄ&£÷r@ŽpCïšn™&ÕF1*2“ž3ý*úš?ÙúãÇŸô´ÔôCDºPéýÆ,b!¼žŒp;Àëü@Ž£?0kº,þñF£áÍUÚ=JÂá a‡W œ09åHÁDZ⾓ˆU´jÍt?Çá%‡ªß72oó/˧¬é¼IóôW õ¯¤?`¿‰×>øÍoáûÙ£Ãþ'­&k‰ü¸áÞ ý¦oÝcŒù£û WÏúzBlËݹBËÈÏ={óUÖíàt’ ™]::2°9èqϵuV¦ªAÅõ8põŠqè~ÛÝ\iºT7·Òȶöºu¬—wwWS€°ª)fgvÀUK$šü€ø„Ö×Þ4ÖuëÄš½Ü«un&vV ?‡%qõ¯IñÏí›®kÿôï Çqscu5·öv¨ëpê( $¤¨`0 ÜÈÅ·›<&ÓÅqEbñL„ÄApy®\Ø&å»;qøµ‰iAhŽzë\š9Ý”FKòg_¯OÆ»(< ªø·Á×—ú~ªØéуuwci$±[±]Ù‘Ôœøã5ÐþË:W†¼}ûIø;IÖô¸µ[;ÉgYlï"Y-¦ o3€á¸8*CÈû)ªøF³ð hz^•c§i+nÑÅceà )\`"ÕxŒG#äµî…ƒÃs¥WšÍ3ùõ½¶[[†XåŽxø+$LN}Á5Q׎Aϵz?ƇðãâF¿á¹ËcpUþØQø+(ü+€ž†B¯ÉÇ­p)¦Ï¶Qn ·Ð¦ÑöúVŽ‘âGAÔa4—QcaŽF'+ÆéÅW1€‘QÃ0BŽÀñŠÖêJÒG›^„é~ö›Ôú“àçÅ1à½~ÛÄzt‰{oQâY1¼‚§ƒ‚3žGö_ƒÿl êk^‡Óå2¤ÎpíÜd ñõ¯Ê_ øšëÃz©ìålIóž 0ô5í²¤öñKf9u#¡SÅVÀû°Ö&SÂÑÌ×4c|ný«¢ñ0¦œ°=¬OåÅiox¬ý ÜÄ~„|«¯x£Sñ4B;뇒Ø}Û|b4‹`Ž9ýzäÖY$àÿ½ê3JC0`ŽIÿ?çéXâ3 Ø…ÊÝ“èva2ÚGÍy.§Ñß°¯†ZçÄÞ(»òË‹k ÈÛ9åd\ç·ÞþU÷o€®¦û ¤À2ŸLçú×ÍðOM1áÿ^¼k DŒ ꤸü¸õ‰$2Lâ!±Ó±ξ·/ŠŽ1þµ>G:­*øÙÊ^KîGgnø@q[ZCî~¸ö¬[R„0{æ´,Ã8rk*ªé£Ê‹ÔÕÔ¢å¡|ž@ÉC×pÇ‚+JÝøŠ‚ýrükÎŒö‰Òã¥Ñ‰­Z%Ο"³O̼^m©Lú%À‰ïæ{PÛÈ(O|þuêב«[2¿B0M`Ýéúc$ú“Ç,i–Øç¸¯OUB6i³–q»>yø¿§YøCÃui* +òïó?@Èòj8¬ëW•¹¯eúýçÞ²ÝÛÆÂh 8òªp7{~»‡~![ È‘¶òdeú¯—~üM3У´*ê6­ºhx 0ö €O®}«Õ´ýd£¥ÄD¨Æ~^sÇ­zا]˪gǪ3ÁWäšÕ3íÍ&sªè¬€9ÏW’êÈŸm‘ î‘ÒIÏ8ØÍsþ øó¥éÖ-c¨Ï4;v()Ôôþ¢»O xEüq§j7º|¬úˆ_= ²Æ3œz6O¿µ~a_-Ä×EJ·õ¡ôõ14¡óËs“yçǸϭIj ÀøV¸|ô$Žzžµ ãpÈ Œý}«ãQ³DÎØòzÕyà sŒô8©‘²ÇqêÉ¡òU€;‡ ­&ÍN·wqi¨Üˆæ‘#xž7E'Âûàô#ñ®kÃÞÒm3·Ä×=+Ó‹I«[·õ¡â9UtÚ’ìôÚÄþ/²Òt}>8´+ßíMOí[#Ûm·9NYH u9ëëX×gK¾r—Ÿl‚ùQ¾Î6ÄqÎC³ŽIË ÙcŠÌÖµüjÉ«Y¢ý E›’r«qÇÍ9‚¹ ƒžzœŽR]R]J[ÙšÞ[­!QâS%ÒáXœ«Œ‘ó/¸ûºoÞÖÖ89¥VÑÛü-èz­ß‹müYm§hío´QÙ,"IfÉS…€OÓ?ΞÇì6°Û]ˆÅ)Ã)>£Ûž+Î4¥Ýemiil‘O6È#b]¶í Ű:ñÀÉ<ÖÐ…óøŠkoZqfedT€Ãzãò®*·œœ®}*VièÖÞgY©jY-ʸpVÙÀQ'''§g·j–×Ãõg¸ŠÌO”ð©)ß{UK[;I5(/á´h˜(?<€íÎr@<óõü륷wåB±'Žüý8®G+l{)\ù»C×®üLú†©'™yutÓJUp¹ qŒðàuàu­X¸‡içƒ\ÇÃÁ¾Òö0 •ˆ#=ôÙCVTAà=û×í™t½¦}ÏñP¯(ÄÙðß·Òæ·Š%¶Õ.f³‘‚åœºÚÆrÌîÿ1rqŽ•èŸ²7†¤ø5oªCãËÜ&ÒÆƒº²Í·lÒù—?:3…ˆ¼~íN9ùê5¡O:ŽK•í±†'Ç{Y9R|¿#gàÃ}+Äsi:‡‰Ú=:ÂæÒÓ#gX´ÆÕ "Ý0`)Êg;Ç<Šw‡¾ü9ÐüSñF»Ö-$ðö ‰¦¥åíäW’$¾fP»‘£ÇLóɯTñGÄ9|@Éy¥ÝXiwvå|«£'Ú•“z¹Fh¶ê3Aª§Å‹I-¾Ï,–ÛÍ(û^g2©*8åNÞƒ©=Ç¡¯Yæ8t®æz‘Êqº¨Ózÿ3áÝ?J6º‡†¡´Œˆ –I¦—gú±äJq ¹ŽzàóÅ|ÁûUèCHø.¶C‘¨n._B㜠ýãúWë7ˆþ6éOm3Üiú}ËMý _XÇ0»‘H¤ ) /lx"¸½cĿ翶¾>ÒVð~ò9âÑmgÁ“wÎß°t`zñ^{Æa!QN3õ±é¬§ˆ¦ã:v»ÝŸŒÐêÅI^ êPr*zÝ Ë*³ÆÃ ±ÿ:û·öåð†>$h¿nð×…íôÿØ\™ÞîÊÎ8Zîó"e‰’»nAÁ o-_ØZ-¡Y “+tf9ÅzX|U,T\©½›ÇeõðP¬·&º»½˜‚ÖfETŒ¨é× þ5^o:æ<FÚÊ£‚N1Ó=Lñt¢ìõg‡,E8é»9Ù:Ê ã—†5ë©¡ŽËM™Ìï=Ôq2‡‰¢ ªÄÁpNÐp'€Hý¼ÓuxÆ“M"Îî9c5ù$>ø2ËI¹7z]­œ,Å÷%äþd+Œ®Ï’sŒZúûö}ý¤añσôkø­õ;K«k¨›¶XšØùÒö]û1œéâ­?o%8¦’ÝžîUŠ…e*qZ­K¿þxv/Šm®O¦Xße™%ݺHæDD@ +ýÔ\wàךþÓú…ìÉâ§±Óôí4¤–¤ÛÚÄ‘åÅÌv9ÚÝO©è zÿí³ð[þ†ú¾³i#6‰áå}R÷O’]²b·Wc •pÏûÃÃ1’Ê|i¬hþÑ?cŸZøY.§µ“Z°žwÕ#î!›Í†?‘âye%n¼–ñôisΓih¼Í+FÚ2si¶´·ësã©—É‘ÁëÔÔl/>ªì–â@TœÇ?çÚ³¤ ÇÐWsí&ÜwB™ˆ—, ¡çhí]¯‚|M:D$ŒÅpꮲ¾Nq>žÝ«‹Û»÷íUZÜßÞFzJ¹SEg¡çÕ«SûÄ®¤r¬ŠëÈ=Ôç4ÅÝŒ‚8öô¯&øwãÿì“™¨œÙ¶»b{Ÿîó×·Ò½E¹Y¹$ μڔÝ)r³Ð¡ˆ…xsDûëþ Ë7†¥)nŽB6ŽûGùüê'Ö.<(Ò_BcT+~áe` ç*tê9£5ô4+Ú×ÚÚžU|*•;7­îy?‡ô´ð”}¯•¨Iw+K<è7ˆ~QÀ*qü9î8õªÚ‡‡¶ßk×3D u¶{coÇÞ`3ƒ‘´íëÏ óÅuµÍ¬–SÛǧÜÜj÷%dŽâ(P± å£Î º[Ïå?ï×M¶Iå‹Q½‚â4—KŒ¬7 ‡c(+0$€rKp8ÓexîÎ(K–jœ•’Ù÷Ðå5- «bÅËw‡–i å¨Á ÂZ¥â *ÓÒ߽ɷ‘¶ Ù¥ ¡@«&qÏ9¨®û[¼Òôÿjéú€R$&ß$dãg˜@cŠób'ÖÒâöá‹‹b¿éÞñ†Â†#Œ©Èzöâ„’Ñ»¿È䫊J«•Y'¯½hÆæM:Hí„FD†4 qåd†9àí9?ýj»¤[)ÂI>_÷›æG, ýâ{óÒµ¼¤é:…ä"Išá#FX eVœýâÛŽ@õàÜV=î…,·Ç,ÏjIHŠl,¿_qÀâ‰EîÙïQ­‰òìŽÆ ˜#…D¦YÀ#$ŸÐž/ôîCÎÈàÀ?üë(m¡פù‰…Vˆã¶ÇOη¬¯VKy ²&á¿×—.ç]9ƪ惺>gø^àÔÕ€ÎcêG£ÿ…{Ã} ûkÅÖèJˆá_´2¹à€G™âß Ì‹&¥ ÊþY;|¶9ükêƒzG¥\jN^&™ˆŒ¨Á§sÆOò¯Òkbþ©’¹­ÝÒõmþ‡——`þ¹Æ2ZFÒ$¿[‹w5¶¤lá|¥Â‚cÆ6yý3^‹¬ê .›AÕT$îðÆÆN;œv®—U·O>è™ÉUhÆÿ—î€?Ï5ù3v?nQMÕï‰î" Ф–Ñ®ÀÊO^H݃ïßü+Óôëù¯Ä! b pFqÔçœûf¼zíOÝœ*޹8§ãëØ÷ë^©áû2t˜÷ EH£bë‚§ u¿—8¤ÖÔn¼æ'Q¦1¬¶®07’§ŸCŽ:òMy´^-¼Ka:\Ý‚†r»¸Î~>•éúݳ:"•Þf`¶·׌õ¯±‰£¼¸´bÑ*HÇæà ÀþuqØÍêwMªµõ‘ËÉ+–U.[¡+•Î>‡ëZZmà»—²¼aÃg*[ 7¸¯Jætw70(D{±·và?—áëŠÚðÎ÷½Öâ2‰!–.6ü¿6@=)'iZÑg1ãu—Nø“. ËÛ»eÊ•ªˆ3èHÇjùrçáàð7Å­E‘¬ãÿJ°V`r²† ?à'Ì\ÿ° }wñ]Öú}Û¸Î'qièô¯øó ÿÅ,5øn 3XºÂÅOð<Š£=w0Ǧã^Ö¬©Õä_kCâø—õ¬œ½~]ÒúKÇK+g?jvýîÞyý:gÐz÷5è~±’9.!¼Õ¶±t'8˰×9çòãȵ/ÞD¶öq¶Ž@ÍüÎ;–#“ž{þuÌj›­æ/™bO'¯<ç¥}·íVvò?ŽïÞ5ÙõúWÑß<%âø[RÕuMâÞþ` §›i”‹ xÛ° !pÀrNÜG5ëÉÁC–G±‡§%4áÐÚý¢?iÿŠV×Wþ ÕâÓ­4û­6h Kgg¼‚æH§”—óJ±VŒÆ¥F6n'æ_›ô]l’ØÉÿÛ¾%Uȩ̀zƒôeR>•ôÏÄÏÇ«ø^Í|G«­ßŠˆeŽòc™9Àp#Á ªè0Ë)ã-“òÌún¤" ¢H»ŒjN3ÏøÖ¦*‹ŠÛó4­:Š¢›z­¼HŸàOŒ/4È5­7FûF—tžjMå¹Ú·™¸z`ŠËÿ…â« ´èàlíîÿ"jÿ…ü]«Ùhßb¶Öµ+kS¹Úk¹cŒg‚ «sÒ²¯üQâ]1·Ã¯j‚À^É‘ìyõ&¾b´jQªé¦´Øý„«âðñ¯x«ù?B¥÷Â={N†9&Kvv—ËòVl?Ý,OÍÐzÿõ²Ã]ze,mV,r7J¤ŸÈšµ«x«\Õ<‘.·¨HêX(–éÎ;dñY+â}j',5kådd\8>ýéÁÖj÷W1©J¯Á)+Zç†/té„wI±±òºU¿úõí¿³—ÛüiâÍÁ÷k$Ïq>Øf “° ̬}SƒøzWŠê7·šˆæîk¼2BØúdûÖÇ>!ê?¼Ie¬XË*Kjû€ŽS÷9ÕßÏ•OTš<¾O©¶öºß§Ìþ‰¼!áø¼-¢è–PÆ#ö‰êsúæ¯xÆÀÞé‘Ï̱8qŽ?¦kóÂðQo)ôÑgâ=KU¹{eiôÍH–Q(2¬ìÉ9<⺭3þ ¥é·SØkßui–&Ûæé×ÑN¿FTíúñ^Ú”}¢”ey.‡ÈN•E)GÝ}|Ï¿O—œõª2ÉŽôëá9ା ’Úø+ÅŒT`Ç,0¯?Q!¬ëŸø+….¥Ï€|SnIÿ]„Ÿûä¸þußAo#©tGÞvúôUòßÉ矀k·Ò|_¢ë ±Új¶sÎF|¨çRãðÎkò_âüº×^³’Û@ð߈® ´ßˆâcý–~õò_ˆ~8üKÕüGý­§k𝇮G X_<.:ÿíü½«DhÔ믑µ)Nô1{aq§ÝµåŒk\鲿‹]¸ ä`Û.3õíï\Κ”ŸÏo¿¹·;ÚGé”Þ'`U7Gœ ñšøþ …û0Øø¯ÃŸð·|9`–ú±¨m¶ÈQ)þô‘d|ÝLyˆÍÿÿà¦>;ñ&qƒ¢ \2ª­ÈÕ ÓGÎI å '·ø×‚jŸ´OÅ?Auk­üDñ&£guG5£ês y† ˜ƒ*A Œt®lS¡FZÜ÷²L6+‰Jm+?é|Ï2»ŒC)ÈàÔPYÜÝH4§øš·åÑå”ܬ} æ¬Y@É*¢¡–\ýÐ0Ö¾wÛ¥5gê_ÙR_ÞÞ1>ãø áÝKþÛE“RÔúA0–Û*‘J¬PŸbƒØ×®hò4–Qã÷a~»xþ•ñ¯Áßš‡ÃíRð–³*Þèú¢´Váßi°‘ƒ Õ$¡##r9â¾ÅðÅâ_è¶W1¨ r=Hô>µñÊR4¥Õßï>c„žã%£ÛÐÐ0ƒ÷°ÙîGçO‘A„䜕0 Np÷<š†NU±ÔÒ¼{œ62äqœÝïþ­KïøäÓàIé×µ#`rTYM3¤’ëÒÄî“r`በõÿ£wØî™O0$ Tœ‚*íü0˨NÒ0Mñ¿NHàõÌxŽàélb6“b ÛŽOÊNG|{k•’º¨¤Þ‰‡H– -–S#j72™-‘%»(#•q’A9ÁsYš§Ãß_M§êÚ:-ÝëÜl¹·–tÚIᕎàÍÁî;â¡Õtˆ5¯ê3I-Ç› ÃâÒíÞ9b2P ±àÆ1É5KáŠ5- YŽÂëR{›g‰ÑŒ§ ±<6zä€sœ‘é^¥ ¬×CåjÔ¯í~±mOžÞ¦_د±sg81Çû¡Š®wg¨ë»ôÇkx“ÃÇSÓÖhÞe0J·îEB“‘œ0rCÛ¨©.ÚÂÞãí·/=©–EHî¯ *’§ŽyÆ ÇBO©ªÔzx—Gû@ÙzÁ„꿺XN×ÚwÙ§jø]k,÷:„‘î1‰#vîÚ~vþ•õ÷…ln<;àø­Ã²H‘–5ÇÞ%¸9Éÿžß5þÏ }]¯u²ßÜCeyeËkå¬J’ÊP´ŒçŒrxœkëmNá…˜>òà‰ÎØÀäwôôü+ßÍñÁÑÃ/6ÿOÌúN ž"¾%ï¤WæÊ>F«æ\DeH”ü¬ÇŸoºa²\ÕqÕ˜?wræ‹vÑȱ€#‹?2›iÁÇ¥kønçÉñÜk•·!R ã9÷ÿ=kOðý̰Å7˜°Kœ• “Ô`g¨æ´#ÔWNñܘ­íñ!3ÎÊŠ²’Äž€ddœu4I5±¬%¥™«ã«,øvráĖͽàäÈqœWªhðxÇÃÚ¦—rì÷RE<ààmaîê+¤¹ñ·‡¼Gsuce­é÷3ÈAxm&GPN1ÈnyþU‹áÛ¨¬Œ¶÷x˜i0$}3]±¼e³8¥ËQJ;£áÓ¼c¥ÈUßN¬äx×äŠ3qŒ‘œVN®Ñ­ÓJ§~@\Éd×¢~Ò׆õŒz”¾”\[¢Ç ì‘‚®ãù$+•(Ï NNrx[Å aŽî¹9¯Õ(Õ•j1œôm#ð|e(ÑÄNœÒoc¾ýü?câ_о¶¼‰^)¥2ppÁ#gßæNkõ&m/N½Ò#´’6 T!;¹Ï½~M|#ñrè_|-y*•X£L£/úŠýLðn²5KK&°’=8þ•æã““V=, ^ÍúŸ:~Ñ[ÁðÙë†oí 'Ìo:àI(»BIoŸ{2íqÕr¸É¯…5‰žæO´¹àØvþb¿D?nOã|9Õí|ܨþÌ‘‘ÌëÓ5ùÌÏöíï"«íðžÎÿŸ~§{i%¥ÒFØtfl7‡õª7ö¡†õ\7$ûûW[sOr3,OÎpqúÖÔi)Iplì ç uük—ŸTÑêªIsG¡ÎÀõ¨%Lüï½kßÚ1&DSžý8ük5¿*넯ª8kRÞ2!¶CÌ7*Û_*Tà‚:ì­Þ»?˜†VË;1äú×"–ï$ Æ;ó[§[Üe…L‡«õ¨ë#àq±öu;Ý#¯‹ÃÅß÷’`Ž¥-߇$+ˆåV8ç#­aXévÖùÊÈ’uVGÆ=øë[°Ý$¯Ÿ^I?C]hó,Ì©tß ²™ºuãštP"}I¨j rN~`)ÚtèS8¨ºè )n žA±œqÛß­W–=û™P•ê ý%ÕáPåH^§?Jçïõ'÷„°'ñéLUqhÝÕ²¸Ú ã<÷?çŠÊÒ®|»ÃùFxæ«_Ý"–XÁÚ8ÈõïE…àŽxÉó|ùücõ®LDTé³ÚÊqÃâàã³gonÏ*.Ìzb´ô±ä©Á+–íÈ÷ÏéXVZÅ´v«óáÇ^zÕ›mmÒAåÆ\~Uò3„õÐþ„¡Š¡ËÏvþf¿–¦åœ¢¸ÎyÇ#Ú¾çý|Ugâ¿¥µ´²=Ý”qE2Jpr7G¨*ª2}>•ð¼7J£÷mcæÏzö¯ÙsÆÐøCâE”RK}M œ®XŸ¼rq†  ò±ps¤ârgx8c0®¤~(ê¿SíK›fx<óT'‰Àa€9Éçõ®„Ä!Œe~SY7•¤\÷8ä ù+Ÿ–FW1Xmlg Ç'‘’F«íD:€玔Ãnc ‘Î1ÁéT™w9¹,Rêö6e·‚8œ³cžw'°üÈ×âÂÆÖ=ð%Êy™]ÙQÏ®on˜ìõKôÉ[?y=ª†©eÓælí?÷Í{tä¹RHç•.}dÎkûËû›«hôÍ52«@ÉÊ6ã'8ÔŸjó xÛÅs[]$fËí›c‘cù²å÷É>¹ÎMz妕oý·wª¸³² /œzŒžp?Þ5äþ D¼›Y—-.«>Ó"’~cõž1éÚ½/h¥QâÃΓ½µ½Ÿ¯êkx™mÅM¦ë(n¬!ÀáÎX¨# ž8äuÅqëªG'‰nd‚v{8Lˆ©!ù”Hûàþ5ÝkÚ%ņ£}ª$0ijY‘?Þ0Œ@í à4]ÄVK ›Ù¬·Z€7²M">ø[#—•sÔö®ˆÇsIF4$êÍîu×wW’^i¸v0$YÐÙ‰†Â1ô©¡èƒI¿‹Q³ yBoe%Îÿ]]ø}¥j£MÔ›Pi!±µŒÃpc‰'Tqåm‘»žG¿AY¾"ñM·†ôøš ÛŸ2 ¤³'åã¦3Øt®iÅ­žåaý”ê¹Å+%m6ü·ù¯$×;G,*’X˜mç"©bâX¡a2¢˜ÆÐy8íŸzHHE#~÷ ¹°F åùþZ/F®Ô»l<~†¹dí¹ë¥¥‘çßáŽO€^6‰Ç*2\ 0>}®­Œ÷àcŸ_Ïȯ|c­ønò FÇWÔ-,ß÷3Ákrñ©?7ÊØÿõZ÷ƒ^ÔÀoë±Ín-%µœm.áÔÄ a€ œ‚1žkĦHn¬žÚtE ÁÏ#ž?¿X˨ª¸g-Qñ˜Ê²¥ˆæ„šô=›Ã´ìžðí¾›7‡SPýç–תæ|å‹(Ìà A;‡Uö­ ¿ÚKÕ. [ ØÂËåáAðÎ? ù’Å/t½NòÏQòÍíœf²¾>bIÜ2P2;{¶—Æ’R@ëÁ<~µÆ²¾½êÊ¿fÿÌö!ÄÙȪ'néà~<Û+\Äš-ÆâIÞné·ú÷®ŸOý¨t}"ÈDÚMî ªJF¨^®+æ¨5%º”»pÝ?ýTÉîWaX‚7\ Õðæ[kò?½‡úÕš­æ¿ð{5ïí÷ýŸ=Ì0ødUsªóÁã ãé^uñ›öˆ“ã&Ÿ¦YG¡Á£Ák)ˆ¸óäÆjíÆQÓã~$Ñå³Ôx¦‰ ¸&Pˆ2W$äÏJÔøo¦GªøšÚ;é’X•¦šG%B¢rݸéúŠòá•á(Ôç§ 5æÅˆÏ³ U?eR¦É/Å"uñ¾½lI‡[Ôc`IUÛ©õ<ƒPñ>­¨Á#j…Ö¢ˆÛö]NÒÇ¿ÌO=y¬cUµ½Öõ›X–ÚÚk™e†äFŒäª  ~ÛÃiÓ¡Æöô÷®Ú”ãk¨¯¸ñ"µ­ÎþöewPŠèOõÄ©Ê4r²•ôƪÝߊõýjÛìWÚÞ¥{jGOw$ˆqÈùIÅdªýÜôõ«p‚³À !Æyö­£JÛð6•z‰[™ýæ…œgÀ›ˆÇLžõµq?™l‰·$½ÓÞ°âŽE‘w®¬`@N´..¼¥ÁùЦTzZèÑ+w3§¾6Zµ¤±·ÍR0qŒ_¨üpšÃ¥Õ]ФvŠÛ™° lÉ·å_–6I¨ëF~w•úžæ¿Dí,u-à™oͽ…½Š ¬¢¤’ä²å¥2’0yÆÍ¸÷ïY8)§sÑ¡7ÏŸ?j¿‰ü@ñiV’—†Ù–I1.A;}1þ×½x޲¬† Ü$ÍÐÇÜ,rÝxÃS»1‰cYpCçqëôÅq:¬¶ÑüľÜã¸ÏÿZ¢<°|ˆæŸ4ï7Ôµ§ÜIЕÏÊFÈúW¦ÚÝ=&À$‚s‘œ÷¯+ˆÉËE¹g’ õè íÒi)Óçœ+¾#ì>f¸ñôÝJk•j™ô|;ŠŽ¼•IZ-~#o\‹ˆY€bX/< šîÒ;«r¬ 6ß•º•'½+ØÏ;ÄæÑÑ™Ù@ãœpMYxeEÎÜ…ã‚x³…D•‘ö”±¸g)ÞjÇ%4>DŸ+¨êz7Ò²ïm¶1uÔv®âk®ã"\¡ä+ÇðükM.rXÑÆüëJjkte_…KãLæ­à–âñ<§(%öžOùæ¶°ÉÅVŸJ¸·›z«F8ÁãèiAl|Ç'Ú½ú.ñ±ùÖ=E×r‹ºfÄ7`É'©ü踽eR GH‹ÁàV~¡y@=3[ÜòÙ¥©'–8<ŸóøU»=I„C ÇcÅs’òNqÏaš’Öù–0¬Iô÷¡;‰-.t“ê†wg#9Ýþ}ë&æè‡$Ï?_zˆÜo@ Ç5‚W×8§º ÈÓsÉŸ¼£’ ^†ê¤eV$^;žæªÂ¤e”Û>µñÁ<ó\õµ_.—%nt®ÑÐÛê}›‚ÛqZÚˆ>× Ö ±ƒËÊÁyúc&¹ÝAû{ÈÍ\yk¹‚);Fq“r+¹Ñ¬b´lB¶sóf¾wì©ù³ö™ã1)Jêì’oñ¹f=@Åï³[‡?t¨ /±$c¿je¦±ªYêÐ^ZJ–²ÂûÑQwàþU§©_™Ö4“€ãŽÞŸ¥b‡ :œgp;ט­ØûJ´¯NM¯¸ýDÑ3×l’=]>ÆåL·’È¡"'9¾ÒÝ÷àõ­#FQ‹¹•gUÇ™ì`izíýΩ›Dòê¶K”\ŒrFr{ž´Í{B»Ö´{¨_):Ù$°cŸÏ5Ñø£G„>&¼ðíä©~öMlæx&$´“ÈÚ:÷‡<Õ8üA§<¢òÑÑÝcÀÈ9À'Ôûófå^ÇM0ŒW+éb÷„šx,¼»Á¾hæ*w˜þízñœVÅÔŽ°ˆ¸1ƒòŒ×ßüæ¬èû5ÂYÿ|rÎ0s县­Z¸P©nª¨ˆpÀûôÅrIÝž„}ÕcŽðŸÄ?è?|Cá›-nãÄS\¥×Ù¯-cЬ²E´£,\ )çiùˆr|Á1‹øvÑáûDoøÙw‡Q"’ ’Ï#"¿Qµ¯Ø‡áÆ£ð³[ ZxlµÆtö7úf“C1‰‚H¯ç #=+ò÷KÕ#±ŽóXµSÖZT·±LÜ2;E¶c£ $A‘Þ¿_Á8Æ…HÅê¿áƒÄóʤ\%Óîç°ò/§/'”›&@K§Ó®pO¯_­m^æX™1’IçZk,ÒOñlŽaÕ‡Ê?Î*–“+Ãö›g]ÞN 3cçC  ü±]ð‚¤ýŸGùœó+ö%œeHÇõÿ8©g¾jU¸u¸ãš˜YGu›8Àíþ­gÝÂ<¶;‰`{Œgéþ*ÞQiY{²MgLÅ•¸-½^”}ÒÊ2£?A\ö•{ý›¥ê†Ks)¹‰mƒ1ÚÈÂD“xõÊÆËö½¹èÞõ¯mšÛ$›Kp2ÃŽIÆ?\ÍêÉa¡Y—ŠYn'¹‘ˆpKÇ €{pk柺Ú}ÎýÆtºl¨Ú#¶0€Ï¿&–ÎÆÔ–K™ž6do,[ªÈKí;C|öÐO88=*´Z.¯ªÜ­¢žèBüÜtÎ95½aðßÄÚ[C{¥ÝYÙä4±°\0Ç\c‘YÕœRi°öo—˜çÅ·” •RÑœGÕØI• *1`㎠®ƒXðV¡bÞˇOž@‘\7X‚WÀúô¬H-Ú §S’(N:ãÿ×WF¢šM3.Yo"8Ü7™œ¡<ôäÓB[]Ü13‚XáO§z’ÝvGvBäï ½ª½Ÿ‡æÖ\‹y-ã“k>Ù¦X‰ÁÆb'°ú×DšZ•ó;ß´ÿé³À^;˜''°AõÏo­}aîu¯ C¢]j6в@–ÖöÑÚ³.ŸÌŽNÖ“ŽÕóá™´›6ók[½›Ä±§Ý;²ëøq]mâØß^½ÁÓež8RæXö•gÜP†Ç íÀ<ò@ï\ò¯Ê­uF”öW=îÒÿTi5MböïTÕ¦§¸½•¥“åbIÚ¨ª98àWÌšíéÔ|BÌv¦Ïþµõ–·vúºÜ–rî3ž§Ðw&¾IÖ´¹t­zkYÕ’HÜ«nëœW>sIÉ8v‰n5c&y/×êOô¯¡þèÓYøVÝ®ÃÎLÅ6€p×€+Å|¦.·ªèÖ{9º»†ÝXŒçs…Çë_YOikd‰n-™ p¡£ÐÇùTc*4£< 5”Ù̘ÕçŠ<©Ê‰SÌÇ@xÆ=*GÓàº*ïioå²á„p1Üð8=yë[w~ …Q:î|Ò1Ï?ç½\_Ê,—˼ˆ”ä©——ÛŸnžõçÙô=+zèIå­wnW!³êG52xI ù©Î~U+bßÂó¥çˆ8Q¼t=3ZgÁÓ™år¡xç¯OÃòö«M¤e?xãµO‡Z8´º2pÆ7`J€¹ðçšùÊp!¸@vÎ3Þ¾¾ºð´‘&î%@>ã#=×'­|·ãþÿjz~K‘òㆺ~5Û‡“m£Î¯Y™.ÀDO·QÐ×?zÛ™È$ž;u­ù0äŒ{Öâ€Ç$d畯E>‡1®@ÜzîïL‰ÊñÈ÷»á¿Ýx¯ÄVZm¤Fi®eUØ ’G®ïöŽðfàßÛÚipEmk-”Nc‰JÀ²–Çû[sõÍfä”Ô{ -Û¡ævÌXŒœU€B¾7`gÆ£´N¼ÜñÍX‚?5ÎÑ3Ö©ö9Þ¬¿§ØÉ¬1ïšR=+Ѿ~ÏÞ+ø£ñbÏÀ–6/£,Ëö™ÝAKX7ó·#*£œ’FÑÏÐþÎ? .¼Aâý;^–ßÌÒ¬ÞL¹]Ëæ„;"Ê ý.ý™ü ¢xCÄWÚ³Y@uÝP$fôÄ‘Ä +ž %ˆNÜýÑ^}Y«ë²üÏ ËŸ²m¥«:¿Ù×öIÐ~xxèÖÁ5V“wÚ/®b@÷;ŽNåäccÐ}kãOÛOö_‡àŸŠ­n´n›ÃšŒí¥˜«ˆ¦ wÀXrp HŒ’¬kõJÆ5‚"çõ¯ýµ--üGðÅ6þTR]ÚÛ¥å¼wŒÇ*;l'¡dV^;JùêÐRNOsì2ŒÆ®ö^’ôïêÇiÝã•‘þîJ²ã§?çò¨a¶^[…aó8æÇ?Z·¨ ÷r¶7{uúÖlÌ`#i*Àç ôô®Xë±úÍ}bÓ>ÚÒ¼>mì­£1°`Š`Üñ½gâ߇¯. þ™>§}h¿úf¥Ü¼hù[~À \âº?ÚNË\ð·ˆ´¹4ÇÆ•« e¸Òõ!æÁ¨W”%[‡n ñ×Ñüwãµ·kvð&›slñù8„!20W ƒå#‚:~ÛS†¢ù'+38Okx³É4­v?|Ak½F×ÄW&LÝ^X%œ’\‰¤ŒvŒ€q»žŸtŽ wð¾| ¢\ÝZ_Üêz ĉ`—TÓf‰d`>Fî ŽýEuwZŸŠ&ÕWáÃiÈóo³»F ð  ã ®CÆrø÷Ä %Åï€ôé$tÒjrE(Æs‚7Éèyí\¯0ÃGy~(êx-ßæ|íñƒKÖ<âïxÇ@³}WÂ¥­á«)AÀ”ÎåPÄò@ëÍrþÒ¤’&¸C ¦'—¸‘×üô¯Kñ¿ˆ×ï¨[K1›f§·ÈX*ü¡n~U €:“Ú«^ø[Äš³2 ÙB;ü»7ç÷̼ôâ»'™Ô¨íîÛɯó9ã…ŒW[ú;áŸ^ÝÃл°’ÖT 7<ÿã ž¼zT^%ðÄP§ú3[»m¶Üç¿o—Ä×~Ÿ 5m"þòÄZý‚…Y Eb•P‚9ù,PŸŸ!HÎ0r2*•÷‚®î%, °6ˆî›¶D1}t¬Æ¤ÖëîFN„SÙþ'+¦joö{=>óR¾k{hÝbHœ…#æP28<þè¬Cz¶\ZAmu (# {gÊ{1`H3ü»úMŒ1xIÖ'N’é¹>eŒ€9è2.>>SÀsÐöÏ:þ(¸–óLÒ4ˆûJŽ&AŸUT•Wëþ÷zà“RM½™¬~=79_ø«Tðg‹Z+øm¬õMÏ#* T”)' ¼qÇ#Ž+§ñõSL’ÚòX®í$8Ô`ãÒ°õ†^"RGÔ-,â‚3¹b¶’¸ÉRìÞýqÍ7RðõͦŸ$ž[©N ¾ôÈõç8Î+–TiKÞåW7sŸ³qlÍÕüMq¬øe4y![B¡$ÊÀ’ ÛˆüO­yúê žÞíÁAÇ5êV›S¶¶a½gtÝ RTg¾3ÛükÍuK?ì½FkyFÇ(Œ»¾÷ÌŠëœtá…tP¦¡tæÜc~Æ4—€%Òªà–ÝÇÓÖ»Ÿ…Z^‘¨ÜBuˆžt*å¢LÄ0ÆpAèk›ÒÊy—k*†Lub ‡ùé]GƒµÍ3JÔ5{äÙ[uš^z|¬è½p3»Œ×TàåUÔª2Œ&œ–‡·øcÃÒ¯¡—OÒ'…‰fK‰D’Iœ ¹fèqÏ­tÞ7ðäÚ§…u@ÖFi¼†’uc²@7£“Ô|ÁN{àûçÅo~$ø{K™Mµž§1¨• €ÿã³>=½kJÛö€ƒÈµÓä!‡–kødÝž1‚sß æ¼ß©5+Éíæ{RÆSäåäuÞ¾‹ÄÞ ÚÌdybb¬OSõ÷¯øµáo·üL×ímJûÌo*Ñãv$ŽƒhÎqùs^Ñð—ÃWv¾µ¿]/TÔ¬¼Ö´+mæäžd…óp'ƒYö Ÿ@ñ®¡&­¥K¦O¨Z›qd÷QNB0u-¹ Î1éì1¼"Ô®qÔµD’ÔàÿgŸ…zÇÓFŽæ52³¡d2n‘Î3øWË?µ/ƒ…ãhõ¤e–ÛQŒ#”Û"*ðxÇ öÏÝ5öæ£áû˜×Ë ¡Oð#ù~5óçí}¡\Ÿ…ö·b"#²Ô¢šà°ÀØÑÈ€ûüε¥8¸ÊèÆ¯½ä 1å¶N@õæ±g —ÀÈäŠÚ‘pÃ<:À¸˜ïsž9è+Ðù[:߀÷/ŽË‹N  uèqúWµ~Û>Üh> mªHk'LÌ9u tãž¾µÀþÇžÿ„‹ãÞ”’G¾8žòM§€þd~uíðPYbŒx:ÇåÍ{™ÝW¦`ÿÀÏ_lw®i+V‰Ü´ ÏŽàB–Ĩ9n™ôÅ:Ö?)þ|ÄñD®«íÎ:-w¼:|[ñ Æ'³k»KqçÊ£€pGñ5´ß*¹ÇM9JÈû—à§‚<'á__Û•Ôn-EܰÆU.K‚ù#’úì_jˆeÔn$.[´@1€=+ê èh¶ #a$uãóukºŽÝ°¡GÙFïs§ñ>¶šm± Û[Ò¾Uøûñü%¯Å,žbIa*0Ú0AR1øæºï‹¿â¶’Hâ™Y¸`žÙ¯ÏÚ³ãºÁ§\è,Ú…Ü+沩"%ßëœd…<{Ö*.´¹Q³’¡ö<–á<ð$^C ç¨ ÖuÍ©š&Ûó2vúTÞ»7¾±|’Z¬ëŽ?¥O`ùÇÍМó\tÛcöúrUè¢ÚI?ÀôŸÙ€@ž;Yep²lt@[”#ú×Ù:tâ7òg¶'ŒãëÍ|á=J_k¢ò)Á*çé_n|'ñ³xËÃÑ<ìX‘TmÈ+Ô»(Î2÷OÎ8£.œd±qÕlüŽªëJF]Ç>dàƒééM…-àbXãôB¤ƒß¨­e` ’&C.p0G>¼Ô6I°Ë6$aÄ¿ŽŸäW\cѳóÇ+•£²ÑÌÅÅ´² OÝih<•Ü÷À¯Nøªéžñ.§>£}m¤Û][á>Ñ(ŒnÜzqÈæ¸9l⺌l8àŸN•‘ªÏ{okåA“-ˆãÜr):4䛲¿~£s•­Ð÷ï‹z®™®¶‡qmk~wˆ¬3«Œ2“µ»ñéésAЭʹ/¸‘´sšó߉ž3ðað«ÃcyZ¤l-¬°áƒ)ኣ#šµà¿ÝϦ۴[®U‘Hªf#Œó³?•~uRŸµŒú4{Ø ~íDZë¦Ä©Æ1êk…ñ‹Åmo(vËÖ­Í®j&Õ1a©0c€~Á9¯Û^Iñ+^¸³Ò.gŸÁen…=6¹ kÀ6ÚG£{-Ï•¾9ëÐ\üPKDdñ:Dß!õöï\íå“jvWd‰mãy °ÀÁ“ ^p+¢Ô|CáwYc¨èæKÉf*'(ï›†ÝØÁ$uéï[v¿ 4OyÒØ[ÝÙI°+}žI#.8ãdŒã‘í_©á²ä°ðŠ–¶>v¦)ªŽñ&[¨%´Že]ˆ&bÇ®0«»žžŸZ£¨Z® –s™Ù­“%›iϧn? »ªx*m8í"¾ºš;ÅW YBçyRØàwížø©×ÁwÂÒݦDj«‰8Àô®yeՓѯ¼ÑbàmìÖm×ý‡ò³Fì~ŸçÖ¹GÒïàñÞ²²]5ôñˆ6 bˆ ¹Øª™Rp2I=§ü4ä2hö 9á‰'×=½h>nKÍ ¢ž@,F?ké!†Šêy©sçÛÛmnh¶Ì&Š"9W {Žj“hz»æd¸Ù“´¿Úã\×Àõ¯š;%™E²:ãò)?™ü꾡5†ŸbEçÙâ‰Æœª3Ç$ÔÖ®œc¡š“z³çËÝ>ð¢ƒvA¼åcŸO½žzÖÇ„<7s%Ôr__¶žeΖÓùxÏ͇ Fp0:óœMz>©q¢.œn­tô¸Š ÌVð3žŒO¡ô®OÆ^&_è×m¼,_u´Æb29èì£æÚ9eÇB$V°§fµ1©;-7/ɧ[꓉æ¶Òµ)O“qumM€Ä#2ްì[y$ ;m3JÓîí&ÕVa§=ÏÖú]¬6Ê¥‘™]NÜFßx·%qÔWÎZ·ÅÝjñOiq4šEºyFÚ]6]™Æ°b©ûùÝÀ8®çÄŸ5xnÃOðç„n´íR8b÷WR €íó2#ÎËd9Ç=*Ç5¥¿SÐ|_ocx´x|ë§A¶5 VLƒ’ çÝê2z㎟KÖlT´z ê±9û–²ìÈöÜ„~¾µðØøßNñ¨]è3Ik½ì"wØIÆ7g >€×ÕRx_LŽÒeŽâS¹¿vd ¶çi‚C69î§*HÒ Qøµ>^[Dzü"ÆHÛ¥Ùbƒ§ðÂ1یׅx«C²{ëÉñu-ÄMùØäO)ÃeNFpG`×Ú~<Ò®,µË»V¹‹UÒ§D{ycŒ(ƒ ™VmêÌKçctê'ήþèÚÜ‹sh¯B»‡±$ûåúÒ„¹Y¿²çIØùbÃLùD©%YA ûËë[Ú-½ÄŒÍáXõVÈ)æ5Çz#¨?ˆ¯©4ÿ>kW™"µµfPçϺuÉǦqúÒ«_ü:²ÑÞÂÚ172Ç!•NFväüê'‹oáZÒ¡¿{SÀ4Ý/KÓÙ>Óà8-A¼úWã]zÞÇHÔ/¦—l0Gæ3±FOAŒã5)Ü­l~P\’Œ}+•¸ É Î}Mu7²árrÄ ü½­rRÚ]J:£$ãšîJÛžnïSé_Ø"öÂ?ŠÚ¬âÔ®ôÆŽÍ¥ "XÙ‘}X¨'î×Cÿ¹’_øbɾô[J= ’²ä¬5òÇ‚ü_©x Åv»¦NÖÚ…”Ë,r(ä¡ã¥}/ûyÜ=÷Äï ݰqç†,î£20%–Ig`O'žyê+O}Lèsµ.Sæ8ó2I‚Àõë_t~Ãß ­o¬ Õä³Ye™_$ÇÇxgÓWÄòXP€H5ú©ûév¶_´kÉÝR“>ÐØÀóNèqf9)zÙ]%R³o¡ô§‡ô(4(EÄ¥a)œ1O¶+™ø•ñz/LžËO”YYC+”c8¦x£Æmª,ÐA!‰q€9¯.ŸE ÖZ. ¤D¯1Ž$$åS×’1_;I:’QGÓVš¦®ÌÝ ÁÄÙ'½¿½{K6>â^sÜ/ óëÀöøÇöÁý¯ü ¬ŸÙDòéÒD¦àKFÙÛ»¿ ~ú-¦Gqb )€±¨Uü±þpk;€¼¢ÝiºµªÞC4f-§¡\ޏÿö¡OÙlx?Xr•ÞÇåÃéKèRÂr 2 =ÿªºƒ$™©ŸNqÇøWCñàýßÁoÝXì}C{Y¶ìÚ~ã×€äóšÂˆ‰{9¯œk?3÷\ެkåÔ¹]ì­÷¢.wž‡-“ï^Ûð—ârøEâFExÎÄ`1Êôÿ8¯»‘ífW•<àôÏ¥tÕ!ž\M–Ú˘Ž+šÎŸ¼bt)b èVWLû‚Ç⮉ªF¥‘›—…üxWkn¢d(—#pp2ã_A2¢ˆF˜Àçœ}kµÒ>'øƒHX£‹P•‘…¾aéÐ×T1¿Î‹ÇðL$¯‚Ÿim÷£êÛkHg„¦ÅG9#nïCœgê¼Þ{çÚ²+£Ë`r>¸¯2ðWÆË]Ke¦¦†’VdÆ÷Èéù~Uì:ߘÆX¿‰3’2JôiÔ„×4Yù¦a—brêžË?Áú3È¿h‹Mø{w éÃUŒí"SîÞ:J£)øä8‘ó÷ƒ?l/ÂK­þ—«Û uX‰Y’FÊðyb™¯¸õ»qdмI4'î>œâ¼+Ä¿<+â)®$]MÜÎK™îÎzädÁÖ¹±xL>*)UW# ‹ÊÒhåßöûðzÙŒIâ9ÀDý­^Sñö»Ð|_°Ùi:•ʲ€Ë1A¸ç§ÊäãÒ½7Pý™üì‡I±FP1±=1Ø Õ(¾xbÅ„qé6j2X:Â9ü3úb¼¨åx:rRIÝyž›Ì½Úkïg˜|<ñ ×6\ [wŒ-fW™°9¸QíØÍ{¶®Þµ’0•-åÚAbäqÏLž®*–àûK(‚ÚmEUû± c¶;p*y´³cš…Cö.ÍÏ>Ýq^Ý9òi¡âV›­.iJê1ëЪê+h­áT´@‘ž¼®{tãõ¦+Gl6DaEô[Ž+•7ÒÊ™[}îI.ìK>}j$k¦]Ç×€öªöÖ2ä=Šè[¡ (@rÅóƒÏ·ùæ¨Ï­ÃH$hÎ@l*œ€=‡ùâ²×ÃÚÃÈìÞRŽ¿0ãÞ«ÿÂ'sy2ªH|Â1¹xñÈ®Å9Éü&.(Ñ—Äš\Q3¼zzW?¬Kw«[w Bʧ¯¸Oרçšé!øuqy ˆÏ;'vXϯ_z½}à›å´hã–t]¾XžWÛ$c—-Ô¾ˆiFÚœ>Ÿ¨=Žž'¹`’ïI帔ϒxS6àÇœcž1Æ^ÔtÛMNÕnÉJ<ÐnÝØÆ3ŒóŒóÖ´,¾j >ðì;»cãcúþu­að÷Wµ˜¼Ð@‰Ž ÌX}¶ÿ3QQUzy§tì|ØÄŠX*ùÌ>P1ÓíQê6‰uk¾P€Û°äuã?Žqí^wà;Û¢$v™6p1àIîïjŽ×áÆ×‘®rGtÓ¯¬cJ¥µ4r‹gaá[XQ]n „;ˆEÎÒAžÉ«°ÙÃepΑÜUdçŸÀWE>r¬Û,æŽ2yh×ýxþ´/‡%ŽYíî¸ù†N}ÏÒ ífˆÑjsú­ôqx‘—n ›[æÇ NçÃåÃYŒ .Üñ×±=+±‡G¿i‰qé™:{qÏJÔ·ð¤,_k¹Š2ìx#y'Ô9íÞ“¤Þè¬3O Ý%äCÉì$±W^ÞžÿJ«â;76Íg(<¿yƒœƒÐW®¶Ÿ"ŸÍRIÚ«´~Y÷¬ÝsCS¹R»VUP ªn8þéç?­eõ[ì5RÛžM¡ü8-3Çç4¡™Pf`O=Éâºh¾Ãc+ÛIzd]»ˆYTmÏnõ®£IÐͬL\»ª¹Ê„#ñíZìÂIÜäI÷\´ã¨ÿëÿJè§F7´‘r›Üám¼!i£Â%r¤†»Þ\°=8ÉÀÏ·¥-ÌкlX¶€6†ä†Ï§Oò+»ŽÅ’[/$€Œ‹ÏšÌo XJéq`m+Æ?- òd¶pc‡ÝïœTˆÏn  ½À\öõ#§ùÕ{¥ydUoÚ $§ ž¿^Ÿç5jÉ p[HŒ²J|ÐA0î{žÕb+ë¶¶ ¹ñŒ…^«øâ‹;¥KWBBwjýsý;ö¢ÖG• rW V=>œž1ëéM7°4$’]\ÄÂo-£#–Æ=5âßµ¥‡ðsÄtÉ™RÖz³7M¼÷'·å^Ï%ËÁµ$"8^NyýE|íûfø6÷Æ? AÓÕî¡Óµ(ožÞÕX¿—²H²6Žpföö«‚Ô™»EØüóÔõhј#`pçzZŸOñ%–ÕK±Œ•R~½Mÿ½rD2IØocÅiéþ²e9¶‹`ÁË.Iã¶z×m­¡åéÔʺþÊÕË)Ë>rPFGR+ªøŸãwñíφæžq<ºn‡–ìCqå4˜>Î9þª“Ælcx,ty'm¸óv„Œs•ã$ÿõ뚸µº³@÷´s’Ë·4=ÉoK"Ä6«wc’víÈãw¯«ÿd‹bðÌ:Í–ÈH#˜6Ã&yÇ–Çà+äXî¿Ð^49f%xô5Þ~Ïz³¬üOÓí4[»{IJ<—nV!T6py#·¿jãÅÓöÔš;ðX‡Bª}‡éfz|…qö†s[¯áÇó«º]•Λqwsnþ}¼²ƒ4' %O®3Ç9¯:ø}âhï4ø¾ÕÝ£¤†lù‘¸à«Ђ1ŽÝ+¿´ÖQîÛ(ÃsŒ×É·*/CëÚe©Úèú§ÛÕ#È%NJó“‘š×t{e,!ÚÎXnö8®'Â7ñ©U£[°uažA=°u£P»”Œ] œà/‘‘ý+ݧûÈ©£çk/g7Ï>>ø@xÏáÖ«‹!=ͽœ¯FŒŠ» Žì£ò¯Î¨d@Á‹ÎíÙÝéþ…~²~å­Ž%I‹ƒŽ@ç>¹¯Ì_ŒÁ?õý&«o Éx6®Ð"q½vÀV Ç÷Myxè5i¤pn/Z˜g×Uù3ŽÔ~v!W;‡¯çŠÅ¶¼—M¸.ƒ‚{àÖ̳¬Ä’ß0ü¿ÄÕ,ÅC–Á=z×› ]™úeM2=CÀþ/¶¿QÌË’@=kÐ'„D$N¯žXWË~|Ö²o‰Ú6IVµ·ŒµhÁöb3’*¥‡ê…O2Š÷j-Od±Öä›S  ´¡~\õÍ}ÇðGÂúŒÞŠhÙåQÛ°ÇÞç•ùùðÒO6úÚfBX;’xÎ~µúðWâm†ofÒÚ‡ø‡÷¿úôè^º>;Šq­J4;N¯ö¼4R|®>ò·Z¢–ë,8“î± çw¯Ò½6êÎÇÅPŽH✠‰BŽ;×;áKûpG•=Ҝęzäf½>eSÈü¢T¥KÍ{áÛW2(‰œ/!•»}qY7>w´imµòÁÁŒùOÖ½ ­à•¼ƒ"$êÚÃêÎ;ÒZͧîZhÚ–ù„çÿ­úÓT“z™9¾‡™iZö=Üb8æ–W`¼í ¡õ¿¨ødjгÝD±îÀŒ„¯`v©àñÞ·µ?‹ÙÄñLb\’v®íÝóÔU«&[TX.N c,¼õô9¿&–1æÖç“kš9Šà4J¿,²G‡ÉêöéøÖpð¥Â–þ¹œú×¶_i±ùLñÀ&‡ÑOOÇšçMeryã.?3R⺡óX×Ó,㹂@åƒFA%œ÷ëôþu§kmS1‹>hP º)ùOáí×­2Ýá‚ßjº¬H;¼÷ªou ÓÉp¥›¶àíÅz+WsÛ/‹™Rñ ˆä`ã¿zY¼écpÒ*äœõ=¹àRÙê¶w³$1^Ä“Œ|ÃäqíW°Cùe— ˆ7L{gZ]H3ììZ8ŒØ Cg>Øç®\’Õ|ÆereÞÜŒoåøÚšIkITÆÄgŒm?7OoÖªÙÍnÚŒr´Áb’BwLúŠv4¥Ò­tÛ%)ˆKòs»’>¢¹‹½F(P¬s.òrÃ<æ·õ»õ¾VKfŽa‘¸)9RN#ÿú«žÔ,%{t?c>hsÇ™î:tö¤†eÛêÉå‚zØ­{Ý­k.>vQÀçÇ?ÌzÖ Ì¾[X>q÷yÇÐŽ?ÏM"Ý®'Øüîøíðªƒÿn4˜¹Ñn¢ºs»ñÂÌÀDìG,¥HêII9'„e0ÁxüÍ}©ûYü<>(øCs©Åcq5þ‡"Ý[›a¹˜3*Jqœl%ÿ혯‡ôÙK¦ß”Œ `u®úSæ™åÖ‡$‹ªÓ*¨2oCü;z ã<{}$²[Æ1°òHÅ]dÓ1ùcPv““ŸÇÖ¹Bom¤\ƒ&Ðv¯9ÿõ«Wäadr4ŠN2rIW¥~ÏZÌú7Å&ubcbgŒõ¯5š#· ö Ezìë§O¨ücÐbi-0tÜ?ƦKÝÕÓ¿2±÷ÅÛ5ðÏÅ ®,¢u²ÕI¸y0v›‚ÌsÜ€§ZK-jSµîR½}?ÏJõˆÞÿ„ÇÂW¶ÉÝC`šS‘¹Nà '==y¯ðÅ˦ëk…òn"o.Doà`pAúb¾cM'̶>§ Vë•ô={áDüA~ÒÆfFµùx92äŒ}kÐ¥Ž=åâË¥Xmu篽yOÃ]cì^(`W*mÝxëØþ?ýzõ«Kå½]ŸhTnIŒ©ËþÑãŽúÕ׆_ºMX¯âY^¬[áÚo”³ã${ ÿ!ýqò/í¿à6±½Òü_~íñcq†ÝýæNžŸ?>¤WÖw7Ϧº‰„?uóŸ­Sñ߆ôŸ‹¿õmòุ•Ö QÁÇ3ÆrGâòW‡µ¦Ó:ò¼cÀbá]lž¾OÊ)î$$BO®OPk*âa!-· zÕ‰§›MºžÒéLw»C"Ê2¬8úU/µ\$VàË,ŒQG$žÕóðƒOT~ù:Ñ”9¢ô*É0ä7Zêþü5Õ~#ë1[X[9¶Ý‡Ÿ3ï^³ðcöPÔ|s¶÷\Ž{K wsÛ5÷Ï‚¾è¾ÒDZ@e™X1Ï €1ŸÆ½JT9•å¡ùæiŸÂƒtðþô»ö<·áïìë០x~um)/&§ÍæÈ¬¤z9­½OàKÒóÂWâÌXÝÂ1ƒ÷[½zçë^  I½d ÃwP2zp:VŠCPÂAUO#ê+­Ò§(Ù£óÙâëÔ›©96üÎáÇŠïíµô½Y^Âéwafd`òàŽ:Ž+èC:³¼‚T*Ú{b¼¯ZÓàÖ­äŠkwu#ïÚrGê+‡Æº‡…æM9§F¶?¹Y$\•ãXË< ójPpÕjŽêX…SIhÎGöó×­­t++«eº[ûKØ™¦²Sæùep'އžàW˜|øÌþ/¸‹O}B[Û7,î£D1þ?BxŽÞçWЧ¼uYšU(˜ Æ?ƾaøuû;]h¾%Ô.นVIžaP-ŒŽ{u¯K$éò3ƒYûDþGÓK=õ´%-nÆNví 9Ǩ?Ϋ®Ã‡œ’îs¼(ÇáÿêªÞ:­•¢Ûê!£|9ëŽ+Wíñ¬Š³3lnr1ÛŽÕ£Vٜɖ~Ù*DR)Êü-¹Ç=³ÿê¬ùÖÿ~|°Aw`´"½† ç%N}?¥h9gýär9FäÎ CîÐÎmÖdÜdE²÷ïØvÅejí¨4pǺ8GÎdeëÎ:qӚ׌ù¸ä0ÁÂ7Cõ©£°ê$àà“Ž3ÔÿOÊôò(f@™Qòägæë‘úT–ºbڈǚÌàq¸ðy÷­Ò㉤w•Ë.Ñó‘œÓr»¬dÜæ T#væÂ€?»ß?¥6BŽU<·°ÇNù#j´Î»ŸÌ(™]ÎqƒþFqTØù#.øþösß××ñü(Zêÿ†4v¼µœ³‹`Òl{Ž„ÇôúÕ©­míõ ­å>` ž½>çž•{L·véfL)é’{œý}êxlìá–G2IÈr[æ$òF­g}u)£œ¹²[Ë…f–8öüU üxÏ·½TRÎr­åÏÃ!'Ÿ§Np0jI®T†1³gÓöÏò¨ÔÇ,»C¾ä*HUAÆqÓ¹›ièJ6¢Ò,–ŽFÖi§?Ö³çÓáBV‰NcŒQ_Ò´"T³²û~Èž ð 2]JúΨ¤{„/ldõ=¸ú×~ne¶`¬xëÄsÜZÒÓ¼AåºÆ\åÈ'€HíÒ¢xÅóXôçšbåIPu*þ·ÜÕ··¶ klÂÄÄ0©m{Š4ýbî9ñ4rK  xõöª:ž«jÎÍbFYU ®9üé,üE´ÄÈv7,ðs×8==;t­\ö<¾mNÂ÷S¶Ñ4WP¡“'bÊ7*žÄƒè}ª•Ÿˆ¿³ï ‘HØŸ˜¿ÞZåõŒÊ2 (VèGÔž*îm‰ÚæPAŒ…8?ö©ä õ=õx/âD+—Ÿõ„¨9íÛ#ó®3Åzm–«i(yY£u+ˆddd÷¤ÿŸzŠßU[È y±©É …I?Ëÿ×Tu ~+{}ÊŠŒËÒUôê~•Ÿ/DÊO©Íé> ÑtÓ3j¾%¸‚<…ø‚íÐwÁûf»=6 -*ñVÁ¼Ø]Oß–Ýõ9?xÅ_Šš¾Š‚++5—tª §¡çŒ•±ð›]Õu›»i/\¤ŽäœŽ;äÖp¡VíèmR¼&’KSÜ%™üÆßçvO}hK…q´‡ :ô­+q¢4’Ä$äã#©þtëí>xÆqÁ*d^X‰7tär?Q.·5¸Ø“bOªÇ}*»Ój“Œ'óÇoN=*y^ [&qÙ˜rGáNÖ šË¤F t“ˆÆH#}Ïzµg§µÓo1£Ž×žGù5KJk™‚“ R$ù[w™•u«,Zu ŠGf—ïTÉÏ¡Â^ÎI+Üt¬íZiSQ£ºxa2·Ry9÷ü¿.‹Áöw?c•å»Gwo•‡ÞQlüÖ­Z7bHÒkxÒT+œœ) ÇãôÅTÖnŒZI‘OÏ! àžà~GX¿¸‚i2ò Q°=å\ýõýÕòìó\F­’ÏÞÇ^¾•Ÿ/Q¦Y²s"̇æo¼œ|f¡kTI=„ @ˆç?YI …´Yùðyuwì{þ•e ù$à·Í·$GL’9Å;j&d[Z­œ2Kò—<¹Ïn*¨.%‘ÔÃŒ&Óü#<“Ï¿ó®—T†%²ÌhÈ;pH:g9¬ˆbXä\‚@?37®:~‚Çm8‰"s0Á ÈÇÿ?­Q¸º·–7æ;ƒŽžß^¸+åÈØ­cž:sŸ~kÌí,apé…VìOùîkT´ÔÉè>Ö Œ76é…ȇžß­1¥¹tÞ3ñµŠí^˜ã¥=[ДÆ]O#D« èp9ùë^MûIèþ(øA¬,êñ6›š”r¨ÄŒ[Ý7øá^Á=Õ³DçÌŠbp0$ð®sÆÚ}‡ŠüªéM-¼‚îÎ[iʨt*N^¾µqM;´)j¬~ciÖ k1š)|å’§$ÃüþU-ËÝÜËåÛ˜˜“‚—œãó¬È`¼Ó/“ÌŠe;Z& ÷ü+¦ƒT‚ô…-šz©u®¦y¬æ|Söåm>ÝVݦØQ‚}ºõä×ÙŸ²vm£ü9ÞÄ i·3¢u(NN? øó^‡ìIpòœÈ)<ôÐJúÿöJÕ-õï#-ÞËëvtxk6ÐAqÈçê+9ZÆÔ·=ÂÛZY.“2JcÈUe;Èß³oÝÈÀ­ÿø"/xãO°’å"œ™d‘>T;wsÀfÚƒ=Y€šúþkº¸`#º†<ȬÇhéòõéï^V;™Ar£ÙÂr9¾g©ðäŸ ü=ñwQÕañмg¿§ÆS𦭩@Ä 6Ø£ "2í`ÊYpø$6@»û1hÿØ>Ö¬Öz}Ö³5ÅšJ˜gƒÊ…½~ò9ük¿ý¬åÐôë?ªÜÅmâûJßO¶¼µ”Cv!‘‰š6eùŒL…²‡å$©Æ@­[-AÞU-#‰+µð«×»À¥R”\Ö߀±–Œ”ä™g(ϹvSÜU¸n£—î>`F1Z‰Ð"Ç›ÁÄy;€ìO~GJŠÛM>c¬‚Uf eT‡×ÜÃê+ºJîç4ëûØe“ˈªœ¿ÓPfH[˘*:1*GN?Oþµ^3ÎÒŽc$/±•óÔ¾ýG_Z¶º,ÓDûB1»ƒ§ô¨øQ^H‹ûiVY&ã+–ǾAªÂæp Ndo½´¡ÇáÅZm !Ý›¥ÜzmsÏéÍ:Äiáó-ì ó‘óL ü§=k7$Šål«çDQ¥žÝð#nÿwÿ¯Ò´RêÊK`a· ŽJüðqŽ Y‡VÒ 2˜Š6Q¸ã×çëU¥Öô¨$2À¥û)ø¬eVY|±nÖüOhƒû29Z1€Âf1ûÁž=J¥nÜ; S•]¼¨æ´­¡.Îíí ÏôÁÆ?ÏÓk’Û#³‚Yd#.îî\7ëϯò®žòᢂVhÚH‘rŠIû£¢Žj¦‹§-Ŭ÷8)Ú Ó®~¢´í¼>·pþø…Ú¤=ªZÔ«œÅÛ4^g’pW X/‘ϧ9Ͻ\7“ZF‹+…%S?5»¬è:~—j(_pïLãÓÖ°¡Ž,¶7¬ŽÇ Ç8ÏaÁô5£i+9‘’ß12Žzñš·e§Ç•Ê$®Ä1\wÆ(’]‘˜ðãžžŸ–jÌ€ ]’?–¼ŒžßäÖo±IÙØGw3~íPçw_ÿZ’êÒÊ1³¢ŽUçõ÷ëøW+{¥Ë<­3O*+1ù|Ï—?Lp:WEa¦Ì¶N8$÷?\ ¶’Fw¸ßÜ\ÄÁ#hv6ÒÌÙ#=8ÿ?V»Ó Â[r’oÎ9>¿VºžçUÊÉ#þ¹©ZL!rÖàŒ^Ÿÿ=§©VЧ."[Æq“€ôþ@\*ʶÒe’xÔ’ÜNqÙ'éÛšè"ŸÍÝùOM½9ÿõúSÞB»7òžyÇcZó[C;²Å#í_‘vŸ0½O9ôïZ)o  ðHÀîÚ$ÞÏ4é-RVÚ@òò:œŽ¹úãµ@!)s:ùhˆT‚Gô4µbFðŽKvHßÀ*:çØý{W4ʹÕÚg9ã* ýsíž•¶ú‹¡ ‡ê=ûUÈp³ ±^vd+ à{õ•J44AfI#Œ¹o‘ŽHäã®B—:`~f a“$qÔ…]‹Z³ÓíÌ3ÎPNA'ž:J_¶ÛÎí"LÇ#¨=ǵ5tî6´*E¤}™›ÍTE`[‚y^Ý{õúÔêÊÁYI''BbOùúóPë7hò÷r¿yO<§¥Pµ ypÛ7NA!wA= çÛñ毖ú“rÔÞ'³†6WUPN?q€IçÔæ [»KÍB9S6Ñœwì}i¢_a‹ósÇל֕¾Ÿ5 [Êtàg9ïƒ×ò愒ר7s"]'PÔ¹S”'åŽî¼ö¬'ðŽ¥qÙ."}¬SoÌ[ƒ·=‡§½L<ò$ ùd0Hçõÿ8¬éíb¸Aæ]ù.>÷”¤üÄA8öýi£Z$7yLVæÖ|Î˵ÎJ±Ú÷üêS [\)˜)9åF8ÏÔõæºSBh.7 Q¾có>Ag®0xÅp?~!^|3ðèó£ˆbD8!›?7^1Ïs] m™5mχ¾8øXx{⽤ÙMÇã916åÀpŠ}ƒàý+‡Ó<9jI€9î#?‘õ«Z¯Šï5=BïToô‹™X´«3HõÏÓí;V¶»Ueao8ë˜ùóÒµ½Î +37YÓ¥~]«ãb@ö¯yý쯴]rþöKW{K‹&‰bRÃçÞ‡=½éøx²Â.µHÕ˜í ´•ês€1êkìß‚Œh66žMòÁ¸6’Ýpx®zµ# 'Ôè£Kb¶µûDÜxcVÕíìï4ø5.÷1Gq¿ÎV íU“iቦíã^.øåñâB\,Z÷î.îd #[j7VöÊ1†ýÜn#ÁœÇ㟵4Kí÷µô@:¶©ãž3W|c&—weo 0Y˜ܼí^üã¥UlCöI7¢Ø¨P¼›>øgðºo_C©ëvÐÝêK0›ÍYŒ’)¯Ì88ëÖ¾¹ð޽¨ÝÄ~ÐÈ£vÕ-ÁïÇáU$³ƒNòÂB&=÷ «2϶íž8?³Ñ¡ò­Â)!@<ƒÿëý+ÉŒç9ssî**ÍÚt®xãËmÀFÙØôÿ8­iÄ òa"˜nyìkÉo|[ ;ý„‰d wÈ\ûÿUS_Iª#[]0Vò€øƒéD±PZ-Ä©HôÝSÅvq‚^W™ÔWëß'üñX—Þ+’Tͱhn<’NqÒ°ü7¯Aeª,s)T“å-ééýk·¾¸IŒ‘E nQòÁHô®*µå{3hÓHäŠÜjI¾C/ÖV uõ¬[½*{)Ü´ÇË'%PŸóšÞŸP½¸‰à{(Ôï¶:ã/›P±¸]±ÄÉŒ€Tóéž{s\’æhÚÉ>dJ ãk`7â3Zº%œÚƒ æ«›ŽÏ^½+O[Ûë˜Ûj",Q€,NInyö¯GÓ&HbŒ„ÝW Jçóÿ ºt9µ–”í¢)/ƒ|›óɼ…ÆÕϧ­mè÷pX9Ž8ð™qǰ«^h¼Dhw‡N]²çéëúU+ËyŒ ,P’Ã’OðàõãÖ»¡Eh`Ûêm\}VÌ«B_ `éôÍcÛi·–WK*I¶ þ½3ëÇÒ¤Ñu”„¬7Ž"I x!²:ûWC¨ÉmumÌ게ciôªŒen‚“LÔÓ65 ãÇÌ­gjÖvVBêÀž2=¿áYP‰¬äW@Lg¯<ã×­iÍ©Áum²Rß78qõê”lïО†'ž¢l)o/’1×ó© ‹»’ŒmÖ©\B“· ‚œ.ÓÉëÍ,PÎÊOž§ž§5®«bt{šv·¬Ó¤j7p7±Æ?Çô­í³7ÝÂÙÍs¶wA.—3í «ÀÏ©ôþ•ÕZÊ' 6œIcž•ÚíÐÌéteŽ>;Q´/S)ê}±ZJ|¿¿ÇAÆp2OáÞ².oâ´‚Yþ,€íä“íŸóЧÿ \S*Àc| šÉFû™_Äi6£rÌ(ƒîù|ýk1í~Ï<)nŒA8ù>POaô«÷p¬Nêwn<ldõý:ÖuÕÞéü²›‘› …Ê–>¼}?úÔÒè;ºß*£3c ¼–=z{{Ô&I\(ŠE(ü ‡å=úþ_­KöØnì±£@QÎü:ôŸ¥Oc¼×ê’È<žhåKr®Êkuä³"¦r\x©ÚfÄ À(bqŒdtÇÿª¯Þè0ÿgy‹é>Pð2{ñþzVCªmb$màgnsŒ~՚Іº˱'i#wBÏäÖž› rÄ>@ØÕJo.(d·bYVMÊÊ~öïøÿ:Ù¶1ÙÜ3Ã¥zçiãߨV¥ý±¯Êv ϲàîõ3x~mƒ~iuãm9¯!­à”9ڤæ?úïÃEÌ"ÞþÞA瓸G1!ÀíéõünZx7LðýÃÅ …µ³Ž<ÔQ¿=ŽG?Y¿¶ŽÕÔ‡q á…qWÅ{Y/tê£IÓV¹ÞI®­” ë ¤î¹Ø¹Ú3øŸÒ²lC]Êí#—sÏÞ úVEޏé6.Ín‚Ééž?šÚ·Ô´èe݂Ό!'ô?\^ÕIζßqÑh\žÂñ#ŽDVPIÆr $kÛ¸ã¹Q¾6î‰Ézž†’ê}Fkvhˆ{|d²ãôüý+’.Rå7ÊaÝü+Ïã\±•H&-6¡¥Åi;|åãëžÿ_ÿ]bKl„’ØR9SŸn:Ô¶º…Û*F$%”ÎügÚ«ê‘\…9ùKqÓ§øÖWÔ Öw_eubhÂŒ‰^Ý}+Üþê6zî˜<Í«<(‰’[Ž}zõ¯ž4ùEÉÜÅÂôÚß(ú×káŸÜhÐÌc¹)¹T  ŸcM6ôèUŽÿâO…&ûOÛ­.^0üdÎzãÜV=‘ŠáÂKnO‘š»o [9ŒŠODéøÖrWÕ}=ñ-´šEë2©ò]²¤ š“Nñ º‰#qºA÷dþ'ó®_Ò…Ôr)ÃmìÝEqrÙ¦•rAcëÎkhOÝ3”u:Ë-F7à›i,~VÇÝ>˜ôÍAöÓÄE€8û‡Ûšç⸶ï;Ërÿ×®‡I×£‘<™”³¯AÀ>ÕMßPHµ.ãl•û÷OÖ°®­™/ƶî®PíXgØþµU{v$³sèqBv5 o*$gîç=koO‘B¬‡$³p1ù~_ÊŠ+¾]Qš\¾˜˜ VÚ‡çq“Ž3úÕ=Ì\Ý 3„¸ÈÈéEvVnHŠêå·+’ÙÉéœ?Ò¹Hdû[Èämd…lw¢ŠÏ£¥Åb̨¡G˜ªpAǧ­hé’ó»»‚Ç`‘Ž~¿¥TKb’.ë7~Ež_,GÌzþZ¾V(äÚ±í×çùÑETR:Â4dÈh=Ôr}êx¼Os ¤Qu°?ÐÑETÞ ÷4¬5 ïË!eÉÂõ-Ï_n*¾¬"´›ÎWøv÷Ô(¬^†å²Go`²($gc“ÔöDZª±KçÊÅ+(ÃsÀÈãùž¥¤Y&¤–vÁ˜›Ã§#¨=¸#¾ dI§A;÷8eÎ1ÈéùÑEL]›ŒmZÄÉt¬€È3†+ê3ÇáùSo!61ÂòâMËŒd·óúQEtA¶‘˜ØÚX®@}¨‰+8=8ÍlÀ#€ø"=Ùǧ¿áEêhÆŽ™™d"NWrço\*§9F›åŒ“œô`qEÏe©¡gD#eÐÞÅU¶:ƒïX^+×^ÂÉbEáó¹‡`þ}h¢¹æÜUÑI\ó+ËçšåfgÉ÷·dgµ:8ó+åØ¢ÉŽzõ¢ŠâzÙ³]Œ_"âDc”<Œ}8§#Ç6Ÿå•ÜÑ}Ö#ÐcØ®{ö¢Š]F¶8@¶Ž³¸¡u+Î ýk™ƒYy¢À¡ËŸóš(®9-Íã¨ëRq:²…Ú’äðÿ^¬ÛHóFΨ+¸¨Î(¢¡|,hè4rêÇN‚MÁ•²B@ÃbºB Õã22Fá’~sEpÕ´Âzlc^im¥JÒ‰ãÆ#‘ïU$»ŠöK3b.Fßÿ_­W<ÒŒ¬Š‹º)G¥?ÚLf]Ìúqý IurtÀÈùldùÍS¶¶4êÏjѾ§3"8dkdñÚ½%u™\0eS¼ÈâŠ+ÙÃ$©#޶’#}Ad•k(×ÐUøä1ýÂP7§Qß­VÒVѭˬVI2ÀŸ”`JذԾÓvr¼{QE`öÀ7‰I$àãå5ËjQ+Úºä™ü®{®z(¤–—æÖ€‰Ü°Éäj(³‘pT¼~ñúúÑEomŒäwZeœÖÂì¡VÛÓwSþMX’å`m‚=ØXœÑE%¨÷?ÿÙtango-9.2.5a/doc/src/dance/Ready.fig0000644023471100065110000000036313034745265014102 00000000000000#FIG 3.2 Landscape Center Metric A4 100.00 Single -2 1200 2 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 1260 2610 8640 2610 8640 3510 1260 3510 1260 2610 4 0 0 100 0 30 24 0.0000 4 345 6840 1530 3195 Are you ready to dance the TANGO ?\001 tango-9.2.5a/doc/src/dance/0066-reduc.jpg0000644023471100065110000032615113034745265014552 00000000000000ÿØÿàJFIF  ÿÛC     ÿÛC   ÿÀn "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?üÍU2 “ÀbÇÐqþqýiòpÌŘäħ׿—µIæA¼‚ÄaJäñž?—ùd8@‰ãž{צÑv+¾é aòœ}Óßñüê?²%À,ÊÀœ1לõüêÉMªH8*prÜ’_Z`S!*_r‘Œü }{þ†¹¥êÂÝÊYîUà{Œž™9ýȦ6œãs)/òî9ÏëZØX—y`äüÀØü*6 Si#ï`*Ÿ»øV\…cíåEL)žCGùÍ2HØ>xœƒúÖÁ%T÷à®2~£·øÒEûÿ½þ³nAa‘ôïéPÕ…cª©Án~†œ±„VÞ ÇEÎ?¥nYYÅ.ñµ8êz’1Ú®›Km±©0éÆqŽŸÏó¯^†W[MUM$ÌeQEÙœ©fÁN@¾ &ÒÜíã9ÁÍu¿eT‰€‰QòØ €àqÇNÏ¥5v4€…V8Îq9®¥’V{I«Åœ¬cäc÷±Ç#Ïðþt¦2¹Ý”àcÐWXª'þì¶æ`È= Ÿóô¯³Õ£¥Pj)³=¡Än>bUsÓ,<ûæ†&i˜®ÖÑ·;ðjÁJŒ=œÇÛðªî¬­+ã¼äŸ—¯×ŒþçÊüÚ“( *›Kp¡Xu9ni†EuRT€Å¸ÏVëJ…УÁ ç éëÇHÆÎ€rœôéíXI•†í1G”;AèN@ÿ>õÄNr¸!rÊÙò~µcÊß(Ø‚HÜÝþQךM ýÒ©ÂðÝ1““ÅqÉkaZÚ•! 0¤í%ŽF@üzUu-"«cÜôçüOz¸ñ±‡Elõíééɦ¶"€XŒ(ŒöÛ5¬U’$.Ëæ‚w3˜|ýxãðçÛÈÒÆMŒqž}¿—çV¦€‚dnÀ9<ú~_ç­Gœ‡‘ÃÔ û÷þu›ZÈØ„0¢€U 961ÇãÚ«L[ÎpÇ€§ºôïúçéS™ä' ÈPýàIö?Ò"Ÿ<®ÒÊå‡9>¹î8?äRØBƲ€ªm »qòHÏù÷§Í:!”;FÙó8®=süê¸RÒÈ~ê ô㧯\ÓU°ˆî’0½†xý×ô Á´†V\°oº§J»mk,ˆâ¾Å,ÛG=yãÓŒÔP óN~RHèÙ<þ5¥f²\YÞºü¨±³œdñŸÎ¾ƒ)Áýv¢§-ŸoCš½Of®RY\ªùNI ã$ãçëRÛDZcÌQ€w3)é’8ÎsZßt4ÑnlÚ£ pãäåqÛ·-úv®:;‰£ÛÖ,Ž›xäûûWV652\\°Õn=SJ÷Õ}›þ&TÜq0US°²[RD·:´ã;\ÚV#Ž9ëW–]=mˆ‹Ä¿ ˆ ÓßÓÔ·ê+ƒ7s‚A›a`&8ïÀ¥i&¯ïœ2ã#wN¸8ö­¿Ö:‰rªjß⨿)¢^/¯à¿TΪïT¹ ±]]OîaX½x æ»_øRÏ_Ð?¶VkÈnlõ ‘%•]1Á@wdd`cÞ¼z4>uÀV <îÎå×µ} ðŠÚ¾E8|¼þ%µ…7 Àƒ„çÏ^•ö+™TÍqî†"7Š‹{·ªi/‰·×¹çæU <ðÝ»l¼Ï°?g×½Ó>*x~{0ÎÞdŠ0§ƒå8çð$×Ô7¶“?Ä?„±Låwê:Ýûü¼ûl þDË¥|Ùû;ÿ _@„¦Ð¯!`8?êd'_Jœù :c8 Ž}ëKömÔóEø2¼½ì^ Õ°Oñ“ÿ“ýzÖ'ìß®%÷Ãÿ„E]±©ø«T»ueÁ,¶×YÿLj?Jüâò§)[F—þÝ-?éOšÿh °ð‡ŽÕØmÕ>/]òFV;FO< ä{×ç÷ÄøæðÃL¡Ó‚0 ý+ô£ö±Ó|½'Nˆ®M×Å Fà!Àÿž„’>‡ß¨ö¯ÍH‡Ç·*Šyœ°qãvyõÏçU›¤èÒ}¬¿dÿwýyŸ®_ðK)„Ñ®üšb÷Eïù×çí…‹¿Úâ-Ñ“Ìf×ïòê8âwtÇŒç·Ö¿E?àš»mþBɸfyhÈ9(¤Ÿ×?LWç7íFC|dñÄ¿â}¨Øÿ§†Ïù>µífT”§‰ÝóT*ZPO»>}m¡È ¸ç°zc°ÿ=)›w²àÄsÔóïô©¥Œ‰äNÖ*r1×ü=ø¨UŠHœtŒöõý+ósèˆð¥Éûƒ½iJ¬AÏ'‡ùéJyb€<Œb•—oÝ'æàýhîÿ¼ùTÜäq“ÿÖÅ0îB«ÀŸŸÓ¥ƒ‘’¥xÚ:ŒâœÅ¾p¬¡pFÑÐíúþtéäW,*¾˜ÿõÕ¤ƒÊÀ“ ¸ tíÓñª² 8c‡\çœc×·¿•Zy$Ž r œ£9íþ¾´ Ò0™pT‘ŽÏ§§8¨‚ìùÁÁQ”ÀÏÓðïS]ÌÆ pÅ{nÿ>¾”Á¾\s´ïü(ÃLÉ•+‚ª0Ë×®qüª˜h;†íçåÇ=zþ•agBPoæfQÇ~¿…VÚC¦FÀO§1bÀ*í9+ÏËß¹æ YÀÚ[Üš³,ÎÇ(HL|»qš¢i eq ?ÄÛ²JÙâE!Û<ãëI´Ë…$t ½=ùü>´öp[!Ñð>ðÏ®J{eÀÃÜq’1þ5ìN÷fˆ\VCrŽ=þ”öñüž ÉñÓü⣨?3 àžsùý)v—P—%qÏËïþ+–H¢m¥ð¬¹œtëQ* Œ’ ¨Ç¿¿çîjiAÞô8f¼qÏÿ®™å˜âÚ[cç:õǯøV-Ü›ÜkÄŠ³´ÿ=OóÿëT(Ñ®ä+’T.[ŽÒžˆV6Vl¦ÒF:óÇצ)²8}§haÓ'¨Éö¨jÀËör7ÙÜ@vÈý8LsVo‚pAïÎ}øüª®˜‚âfúwÿ>Õ}“bŒ€Yr$ÿ‘_©dÔ9ðPæëþg—]¾wb1»€þzÐqÎ>´áng UAû¼ÿ_Ãó§yй!ŒmÇ-Éìãüi hÂå†Þ…^O¯¯ùü«Ûö)JÈÆ2ÖýîÖ>äqŽ™ïÓô¦oa1ŒÆqòäœT­óE»¤ñ¼úñ¥eØwo^y*9,F? f¹*R‡2л¤2i÷’އ~b?úôÇuÛ–W$©brÈ©Ú7 »ÛvÖÿË4ªãîãw˸Œg?þ¿å^„0ôž¦NWJì&ŒVFef?69#ä{ÔÚt{ïc]À³ºxè3ýZdYl(P< ;x'ƒþMuü)}â?ØYYZ\êÌ]Ú!y€RIÚ¹8ã?JâÅZŽ]üŽÜ%U­%«hëÎi=Ä*ÇÏ·¤]ßt`ðFqë\™lº–­$ rð­ÎFïsôüëÔ|YàÿØk:ÔC@Õa±K î4Ù`]ª§æW@9ϧѸH¯ƒŒÛùV£Â°³–EvX†@ÈÁÀ¬ï/Ë”’ÁË2—ã é“þsNÖ-Ь­0Û†äàÏ·jÜÒm·éÚ›°û°€NF9eÏ_Ëñ¬Ý)Gžç*Ç¡9é“ßëç]>k·ÃšÔŠªQ#sŸYS§úõú·áTàª5ÕþG…˜Mó(/#oö‡ÓÊo‚¸'@”éÇ£WŽ£0”/C’ nü{WØ_µ_ÃôŸáv‹®[ÄòËc},˜ã<#ªò}9UÅ|ŒÖoÊHchÓ$«H%@ê?_3ÆULî²]9WþJ_ „©C FrÕM]|Û"ò„€ª§˜X‚O¸Ï^9ã4 HXK¹CÉãß5ÓÿÂ-ðä—òNy$Ÿ|zöô®fDHdݸ£nÆïl×ÅFjM¥ÐOí+¯A±à0Æ~V ¯¿Aõ¯©¾ [¯ü)mI ÍâØÔxBøôþéãÞ¾^[Ël1aŽA(ö¯«~a~ xP,~Yo*¿ÄD2 ~C¨=±_¦pÿ´æ×ò?ý*'Îf×t]ÿF}kû;B⾉'%q1ÎüðÒ¾…ñÅÊÙÚøVÚžm‡µ«OnŽô_èkçÙØ±ø¯¤®ÖPV|¿lùŸJö¿‰÷©'‡5ûS&Øìþ_JuýädnÿÈ}kê8µ_ð¯ý¼äÉRå—¯ùýšü F ÌžÖe$c†k‹<í×ò®;à3¼Pþζ›w¡mPw ä8„"÷ô™ºþ×~Ïm-†µðžÓphl¼y#‚rw=ͦ ÿ¾[`|0Æ“sð>/0‰-|=¬ÌÈxãlv¦;ú¥|\é9N¢õÿÜŒúG§õèy§í`­}}ðʧø¯T¿ ÀÃbò05ùoâ!çx­ÌŠ#Ý1áF9íŸ~µú}ñ‡þ'£ö~Õ#iαÔõzƒ¾ CÉÏ=Gùùy¬K¿Ä*Ç,K|ÙxõóþEsfÿ¦¿¼ËºövþºŸ©°¯‰?°~ Æñl%ä’^zå¨úžƒõ÷¯€~8^M©øïÄwG fÔï%%N“+ã¯_äkì?Ù#T“þÑÎæ.Fʼûv¯‹¾$0¸ñ±8ÚUî§#$ç;Í}¾mFÂÔª–²KÿI>:„Ÿ´WèÙä×íÉ9?3œäõŸN;zU7‰p3–‘Žùâ®ß;3à” g銢ª3¹=I_^õø³>µl’ÀÀ^sþsLv,ÃŽzÔ…U˜`†<>ñà†(ËPª¹þè'ÚÇ *q¸¡N¤‡“J…8ùK}ׯ‘ëQ€2»H]ÄðG·z”ã{*D»ÏË…Ï\ýùú€E"ˆAå”ð@}*C<²Ä~Uõ0 ˶CŽáXÿJØG´£î ~SÏ®:sQKq$RÇfsúÒQ‚ÊÇf èÓ挜ª1P缆ý¿ ”’”)l³ªñîMeˆÀG&0Çÿ®½»§¡½®F£»€%rHaÛ°ÏùëN;eUÚ9Á ×?¥*Æ‘ƒgð9õ¤%Bà¯ÉЕÆ1ÓµrJä¤G1*rB–ç®N%Šóòæý{Ô±ƒ ¥ÉPdO­!E‘vŒ–'øG#¿¦C]‡kêV'h'jŒ°õ¡ïëHÛÕ™˜*g ÇIÏóÅN͈Âü»y!”}?ZbÎüÆJ“ƒž~½úqY2ìjYGæF¹bŒ$Ûò·'8ïNuòø$ã?.W¡>ÿ‡ò¨-q%£3'˜Á€wNœqéšµ’0€í*~ë/9'ÿ×_³e.SÁRo²_qâÕ’I uFv+ ÷#¦~¿•B@$)‘€ÚŸŽ?Î}j\îmÌ’0ryÿëú¨H¿wµrœã==»úÿZôä¬÷3ú±‹û°¨@3œŽ3œmýE8†x¶«Á+Î9Í+ðTwÆxÿ9íJcyœ±‘œ7|òãX¤›W ; !¦:«¾@àp=ý©9’5;xÇÊAÀ¼ÿžÕ.ÂK7Ê çiê98õëMg` €¹ÁÏÏ9ⵋ¾Ãqz"xU%ºo0n;(pÿ?Ö¾Ìý¾ ê~<ׯu=:álµ RaŠPø(JÜý7~Ÿ‡Æ>c! Z<2F{ÿ‡ò¯Òø'—í=à/‚Ÿ æÑ†¿’¸“.¡†©NYl¬åºM¿š}ÏÕrLÿV•O¯ê¢®›IyYíßð>Sñÿ„b¶Òd‰aS¾Ö5Ú~é r?ñÚùSÆúzÛkšÇÐ^jDsÉÆ~xóÀS˧̨»‹[YªüÃ’×MþñWůÜiz–¦ ld:´§%A!]ÁïÉÿë×Ðð­j±V›=ÆTëÓæ‹<úÍà¾s·'· X‚>Lû×;"v­²1“ƒ‘ówÿëWâ&æÛQ¹>SK˜À㸋#ðìk“¸´Ä*TðñG÷›}ùí_³Ð«­#ó dìd›vû[’@߸Çà*´Öв¢²„ʨ$ ÷òéþ5¥:¢±P·ï²Aïüª‹ó*~ò0UòOÝ"µµÞ›D¢ÊBÞZ0'#pëÓ“‘ÿס„°¬ª7\>NxÏæ=jQ˜Î~}±’@Ç÷ºþzÒÉåÉQŒàƒ‚ Àÿ?çŽy'ÔZ¥b¤ñ6ÕÀÃ~QÀ<þ½ûÔÁ ²8!¥ŸO—×ü?ƤhÄ«‚¥@çñïSÃnŸh(³æ–Ròv÷íß5Ÿ/CJé ‘mm›Y±ÐUk˜v6ÕrGLÆ:{v­ƒn¦5*KŸ,ã€=;ý¥W¿µ!ùÆw®çoB½¿ÏjÊTô¸íÙð¢H]”†`«œŽÙçúÖ••›Ig¨°Ë~í*ÜŽ¾ÞßΪF¥‘†ásµ€=úø­ë;t[ÙYCmQÈãž?ϯåXÒ‡<­ä &£¬·MŒ aN7| Ÿñ¬™ ¬áY‘»0ùr9=¸ê?ƺO[¢ÜÞ!ÂaÕ@ 2>Qï×?Ò°a™Aä~¼ß“Ï¥*«–v"^Eý q$™à7wœúcëŽkÑt-n|®8wµ¬q© ´Ê3\G…íÄ“6GÊŽ1““ÀÆz÷ük×ühaðFª|ÖG—P³„3.íß½8Ï­~ïÁ”—Ô)ÉõæüÚ>K2©ËQßÈú½ß@ñU•Ç‚u–Á¸C:¨‹r($€r=Á÷â¾*ý£< iàiºm‹Åå¸!•›w¨\äzWÒR_É¥~Óú)÷¦ÒÀRGß9ÿÙzû~~ ûaêûã$‘nÈHdèCf8ÇSôþuù5,ö»]-ù\ý8ÔáJmòdp:„N¿ àrÙß0 qƒÆïNد?šEò²¿ÂÀ6G ýx¯Bñy? tx”„srrBœç.Fq×®kÏß ‡åÚK<õã#¥|–¿y¾ìñ³ö§Ä“–vp9Á÷JúÃá+Hÿü(„¡_’SÆ?圠c¿q_(ec£ ³€6ž2GׯJúÛá’ù_¼Ýj³sœ Kúõâ¿Xà÷ú­ÿ/þ܅ͭ좟ÑŸRþÍòyß,%$¨ 8Îl?Ðרü@i•þ"mýà·øL!õÛtzöÏãÒ¼›öcžÕücm#Hÿj .ÕÛrsì?JôË©ÍÆ§ñj0¤›YY–'’ÆÞvÁÉãǧZú®%66ÿÝ_›9rdÔ%ëþF—Â]Iì<iÈÓ~A"œ`æK™3ôÿV?/Ï;ØtMoÂD|·:gµ9ÐÁß§æ•düO•´íCŬ®ŠÖŸ ™PÀfšðt<`ñÏ+æ”=é>ÿäÿÌúMÚþ»4O3Ÿ÷!Û‚ï.@;XÛYí÷<=+òÖù„ºÌ(dûpn8ín:õúeâZ6ðgÃx÷(¸±ød÷ökxÀöê‡ÿ¯_™×ãìÚôJÜz޾þœú«ÀÍ×,(¯7úNI%Ðû·ö]¾{„—~°, lQÏà?JùÅw+>©©:„,e‘·}Xœò3þM})ðKV ¥N~Ï#d»ŸÇÿ×_/ëÒy“ÎGbÎzãúWèYç¹€§æ¿Cäh+V~¿Ö‡|a… ÝqÈíõþµšÍå¹À#%Oæ8ôç¥hÞ³$¥@f|ðGSõ'¾+93…PH¹ÿ8õï_‡KsêÆàóޏÝ)É! »ŒöcÇמ¾´"|®B ÎIç“Å9wE×+ÆW+Žÿ‡½HǰL¡V8ÆTäóëJ 92)Ôî\cò£pÚ ÜÈr ^SÓëùÓÎÚÛ2sžz{p=Oòæ€öEÞ …ätãbK€‘‚¤œàîÎO¶HÿçUd”¢©FÝ´’ý{žõrSå ¸q÷W$wÏ­V˜¨U“pë°çœ~´–÷%#|0ÆH<õϯ:qDð¤L$Ü Âç ÁéÅK*Ç”*’`Œ“ž¾¿•9 ‘­ŸÌÂàÉëßëTb*<°<ð{c=zU·¹V‹œ³Èaü稨P ‡'†ÉúôãÒ€.y›—wÍÜ»N°ýJ…Y'Pí$¹>‡åM¸e’8ÙIFvþ<‰#˜¯Ê«·ý¡“ü¨ £;XŽª¹ÿ?"’AeÞ7qÓ§^ô«Ì¹UÂÊž??ÏÓ¨Œ’’l qÉ8¯rQí±²a'ÌÇÉÎãÈç±èGN´Õ!ŽÖÉÊîR½€ôöëÇz †`~ñ÷8çßðGè;çׯ¹üý« -.‹ÛA˜Žg0¨Ê°ÏŽ9ÆzþTÌ$K’…9럧§zsd29^¸ëþù-„M¸¡Ý÷¾lšÊI%aÛ¹ €!°HCd`~|ú~U¨—z¸”Éî?°P¡ÀÂç‘À·¿ÿª£ßòì¨z¶uÿ8¬\“LÔ±Óݼ„”X«08Ýžçõý*ëi ¢îlù*>ž»ÕŸBM–ãó/®8>½?ÎjÔëX‡É$ Î:ãñý ~Á•'OIEô_‰äΔ̗±*ù¦2XàmÈ?\¥(Ò×;‹q²E=;Uù‘ƒ98$r¼/l~Cô¤dfY®#¯ùë]’©5¹JœB€ÓcÁ+!v-Ÿ÷{Ò‹bJ{°ÜO×Ú®¸>XV%þ^€tõ?¯Oj’HLà’ÙB6’Gn0k•ÖwÜÚ4ãØ£ýœœ–ÊûƒÔ‡4Õ±U—¦äè”°ëøõþµ pÑŒÆÛ‚Þ½Å5 n*I`ŽxÓŠÍάVÿˆ(¤ôÓ̧šX»–ÏÌ1ÛÛ5ÕxOÿ‹µ´Í¸¿•YãMáK`FOÔV ‚IsÈÉϧ5Ý|ñE·ƒ¼ue©Ï)Q³6SŒñßõ5óÙÌeSRË™¨¶—´ìzYrŠÅSçvMëènü0øC¯üDñziº…ž£¦iv³F5¹íÚ%·ˆ0 ó6à ‘ô5öïÀßxáN¯¬xOÃúÌ+7Î÷¹]ò™f'Ôö¯Š¾!~ÐZåÌÚ¦›©O¥þàè<œ‚1¹æ¯!Mnu¹y¼óç¹ ¶@$àuÿëÿJüc7á,ULL£:Š1Ir¤º´›oçu¹÷³¼&Ÿ³„y¯ñ7ÚýýÔï|_D‚6)O.À >rÂIý§¥|ÃñGâ2kz–¡+–·k¸ØóeQÈüü«ç?ã¿o3$—òJV1² €íîj¥çdÕ ”–’Y ‚w{sþMo”ðܰ1^×™­|ïYZŸºwþ(ñe­ýϘТƒreؘ<Jýk˜ó4ëØà]1²3aFH“,"k›¾ÕRæeRæeãӟƪµÉ\.á•u7$ŒdsØqõÅ}OÔœn“ü{ L_<®mj6L“42eWíDg'o#©#×úU1¥´³tbt¸áø¬Èõ.Ý÷0!ƒ°lòyúÔñê¢RÀäL ã‘òc<þU¢„âýÖqT«NZ4W{¸vd& 6ô屟oóíX¶¶2I}芊Žp‡pκ¸­^ËLÖ4é#Ý-½Õ¬lc;”àúdöÿ=|Ü- ÆR”•¬ŸÞ+o®§ã„W÷JÜMÈ=?v;çF䑈A€Hè[uþ7€-Ýë” À8ï„Æ1c\xvFFb\ç|Ã÷ô­qâ¿%æÿ3 êΗÁÀºÜ:É´1ç‘×3^Ùà‹O·xVÑ’ók¶ÊC®G )ú€F¥ycš€+ò•P§Ž¼äæ½çá•‹DУÀÛ'ˆ#  vX&b}ø¯è.‚ŽYEù?ý)Ÿ™ßÚËåùŸ‹íäÿ†§ð˜V“JB—mÁãC×ô¯œ?imEuŽ:àNøŸÊ䜒3×?‡Oç_PøÆÝö¤ðÝÔsÖš¿Zâ£)V„±ÁÆãéúæºÏN%±Ó‘¸žGLŒcù×$fDP³y õéÎ}8ìkçh|/Õžnq+âb»F?’$G%ÛpÀ$cpýGãîzWמUO> Îò=ÍÄœŽ`Ið!ÈÅ|’¬¥ITݑԓÈíü«ê/ Þ~|;·!ˆš É)|³lú’\}+õÎñUŸ÷Wæ|.ogæ}û7±ƒÅ ì»6C9Ààª|>¿Ï5êq8,øë¹]—û:ÆÕv¶Ÿ±chÇ_þËã?³Äù¾Ôd.I[y#9 .#¿&»­_ÄBsâõÖï-nµÝ/N`?À¨@ë×{dþ?eľ-?%ù˜dêП©ƒñÄBÊÏãÛ»ü–¾ÑtÅ ~é–8ÿ7Onõ±û@^Ga?Ä2ÌbTøych¥Ønî®S<ž9nžõÇ|mY[Døþ»÷,×^µÁ^˜Šß?Ëü*ÿí=vÏĵˆâC£h–¼ o²Tõê÷þ†¾Y«\úN—þºÞ*’v¶ cÊ´øKn„³ga1Üg cØ3Ó;}«óÎøùž$*‘·Œwá{â¾ùñ=ñh|^wùmðÞÖ"Џÿ–wGݽú×Àº aâ¹ >üçÊ0?|¾tí*Qè¯ù‚V…ÿ­¦>jB/]Ä2¬"‘I'¨Ú9qøWên­<ÀÌÌpO'ñÿ=kÓ¼ ¬¬~š0d bðsÆÀ+Éï‹6õPÒFç€þ•}–{[ý‚‡šÿ#æiBÕdÚ9«ÆQ6IÛ˜“‘Î: }?OƳ¤š@=Ï¿Lfµn pÄîæ3÷ŽH=ýy¬¹K;žåùÌ‹& eBÄÇäŒ~Tͪ1àë¯n¿­8G‚«’ëŽÈã<:äqæÐµ¨Ç´ªÁUXœÅ;É•Ë Â6ãià‚p8ëßô©ÚUq‘ÇN?ýç5ˆ€B«mWà¸éïY¸2­­öJ¡ÿ»ÁpÀqóëB$ŽáHµ‰9¥ÈeF9 »8è)ˆ ÆåtíŸÏó¨öMêf×c¢Ð[XØç9Ï Àôþ•t”l¯(«—'ü÷ªú)²(ùØn<öíš¿"—LáÁ]ïéÓµ~µƒMa©EöG“'yئc –gáA'`'לž•“!—j(Æ?\w<ŸÈTó «—lå³»üŠV€K]Ûð9»‚yô÷ý*ªEõ5‹MjˆZä(!ùú~•OˆaJ±È;{ð8¸Å*Ä@Àn Øõõ—z–E,©µ°~`©Çá\ROál×­‘TF%bî>ªr¿OÖ¢8ù€ÚIä¨õÇã«ä3a$ä@\œàñ×öIT{c±ü« Å=®_3Ùw±óÇÍå’ÃIÇR>¹ÅAæ¢ïvUSƒœdc§?çÞ”e™ƒn`äöãÓò¥“;ÉŒƒ€NíÜõýéí\¸ªq®•ú;‰9 YÉ´”<ü¬GÉ>ÔØë¸à±SÇðóŸð¦ïÝ#î :ž;ñÎ?_Ξ‘˜äU9vN?ëÞ¸±4ÕWi;2£Ù±ñ3ùX|«m)õÍNó*,˜çk(äõÅVÞØ‚eS[€3ÓçƒM2ª[²(-Ç@Ü€}??_?:r¤Úhë„ô)µî#P¸(2¸:Ÿ×§J…îä–iöçØ#<ÿŸÎ¡2–B† Á†FOòGZa¶epÅW¦Cd½úVØ5R´ý•8s;w·ærNJ:¶9ä!°ìÄä€çÿȧÈÀ¡9þ,ã‚~¾þôÑ`\<‹Ãg•Á¯úSŒI½I˜‚:¨CÇQþô±Êó)¤šŒíïò9½½?2"HQep£w'¯NqÇáSEÀ\yjx МóÏãR4º$.z’£éרSÖÚÙùTÎOÎ0GåZˇ±/øµcFþã?¬Âú&C,±¢€C’w!ÁÎ}ªX¤$Änœà0óW­•Æ—y9FC¨ºÑ¦¤ñ©ÁÆaýÅyÛîS9É^S`Gå]׎ˆµ 5Um^ã @Ã0üxEpG!c?/~Üü«ásÛüÎynv¿мw¡“ Ϧyà×Ñ_ íœé¾I:éåsŒ‹iOOO_¥|ùðô¨†ñBñíä psÇL׿ü8Õ ·ÿ„bYdŠÞ!®1ùäýLÏ=zq_¿ð´U<®£üÙñ“æ¯5ýlt¾.ºCûKèl„ï#ŒïœŽOÔþ•òći>.ø­Øe†§tyë1‡Ò¾·Ô4õ?‰–ž2¾×ôí2H¢ãOŸP¶è€ýçš:î'¯?ÕgÏëÞ/Õ5›ÏŠÞ±–öæ[‡³–úݼ²ÎXŒ¬¤œaÓµ~YœðÖcˆÌë⊄žÊ;Y-¯Àýæû†T÷âÓjÏOÂÇξ*™nZØÅ°:Å“òŸLå\癌mûªå‰Î8Ïjúžo ãý?âÖ”±ɶ™d'¿côõ¤—á_ìù¦Æ¦o]_é/'þ‚½?Zç¥Á¸Ä’u`¾rý x¸¼ç ^§´½ïe·e÷Ÿ0C*3…`Xœu8ãëôþuô¶ráøwi…/I»}ËØk•ïø:¹ªèŸ³íχþÁe{{£±¶ßǧ]ÈU»1_0ƒÛ¥déú¥œ7ú%•¬—7šu†’ðÇw-£Ûùŧ,H Óè é_¡pÎK,ž¥IÔ«s%µ÷OÌùÜv*8…X½;£èÙÒvœk 9©Âc$cÿf¨uíT%牖@Àꬡà°IæçòQøÓÿg˜Câ&Íû¨yGï\á±È¬¿ÉÉjò~ýŸâ¤mFÄYø=xÉÇóÅvçÍJª~_äudêÑ“óý¯ñ»W6šÅ`Ê’ CÅ:%¸iy ­´O‘ƒØ¨íMý 5}7ÅXqµ–ãD¶YñË4×>…¿ùáüY’MsJ×dèÉ'Ží•™WpeŽÊ@FAý8íU~-ÞËöÿˆð ¤º×ô˜‘ßœŽàwÆßó‘_'=·õ£>odTÕuñucñI˜¬bßÃÐY|ÙÃ&ß5|[¨/üUó•ù‚0@ùT×ÒÑÝ üf–@¡št„r2FùúŽžžÕóf¤¾_Šï0¡XGÕ‰À¼‘Ú¾O8IÊ›þ·d»¥c·Ñµi¢>TmòÈRÀñòô<ÿŸåÇÈØ…~`ÊW¦µíætÒ§PX¦mc'óÅbJB’vËó GáÜÿŸjö3šÜØZ ÈñiA{I4djm¾T 0¼'AÆ ¬¹ 2£·Aׯ\ÿ*Ò¹&F~ÃvI+“ôÎ=GùëT~É3HZ8ÇAÆqùzüöZ½V;‘N€ÁÈéÒ„` ýÞ㜎ø«&ÚWeS <ÿyþxú%["òwW<¦î tŸãK•”5XɰÎÖéÏlþ4? Tc†Ú#¯çOžÝLcl"òw<Ž{çÒ•Ö0¾`E*JöÇNœÿŸz@'™ûÅÁ&@Â3“õïO0Ѱw;~ŸÏýj…Ä¢5€Á8<ñÎ3JòÈ Á `3@ÇLÿž´%Ê&å$í›¶xçùÓ•w€²WŒžþßç5O.2dÀÇd1Ûÿ¯H¯$Ãå(7Q’Ï¥ &hàx”#lê2ün>£ÛøTKo°¶ìã?/ðŽý½i@¯¹œãdŽ¿þºÁp¸ÜXƒ‘ÜP“J¹BP£‹ƒ‘Í5d(m¶{» Ó'cæíå8!9Çù⑆òJHö7~¦€:Ál!<ÄK m#'æíß ¨…»ÃHÀŒúIÿ9­#jÑ¡$(8°y$ÿ<ÔS:A¹~]»Jž:ý?Ïý-*ž\ó/w{•üµ. AÀ#î¸ÎLóœu¦M”1#Ÿ»ò‘ÓõúÕôGu Sò©ã9ä~Ÿ¥+3pÚJ˜·¿õÿõ×òœ_zTcç¥VœWºÊqB6.ì«’„sëþ}i§>žÕ!†A.\í@~T'Ï·§½y3áìî¡oFkõÉÇK™iup8R7ð>¼}iíåÇ>%y g'Ó?ç½iÜHÆÌõ2x?ãQÜÆ›³…T?(;÷¤Ûjm~?ä_ך~ò¹µ¡Û•Ӣ°dŒð?úüÿœTާ{•U+Ðã·=ÿ/Ò®èðo±Ÿ{(Æ}©^ß ‡hþé#§¯ã^µ:^Ê”bì’3Jòr2Úò«4e»œÒìËlUe$`2óƒV$Ž868—*ÊŒc©ã(…¬$º:~­`ôÐ范Z"±†$ÈäŽtúT&òÃrJò¬«íüëE†ùT°ÚFÒpÎj7#,HÞ¼ñ»¿@}+–M>ƒQMêf˜¶«´¸‚ÁÔ}2=*7·PûpU í“ÿ­Zb2nŠ cõÓùSE»b""ØÈ>êœqמx¨I7ÌÞ£åIìPxͪ/ï2™ÆöôÇ=;UèˆL8f `sÐþXþ•»å«OËØsžõ«DЈ•ƒù¯– 6sÇãî?°vVZhc"¬ €$uõ… äñÉló×ü©ÒÊ|ÄUˆTÝ¿§7îÔ†R†Bg$1Íe9ÆÍ>ÆJ6ÁÒS¿r‘–Þü>ƒõ¦’IØcppOš–[e± Œ€W3Ÿè*4ÙŠU2 ulc8ôâ¹'+«£dÜ6ýß  “ƒÈäžÔÉUR‘ @ŠG$tîj]Þföbvñ‚Hþ_§ãMÊÈå ©`GßžkÍ”!UZý‡ÔÌŽ Ϊ$ÝŽYØ‚O|géüê $8Q`sÁ5rÅWÌPçnÏ•q“ßç¥Bñù’È¡|Â[$gõÏ­k“ÂQ©ÍoëúùVjÚƒ+veƒ |Ç8Ç?HI 18=ð}éªäd–*z tö«p>s¸ªä“ŸÏñ¯½Šj6{~'œÓ¾¨HÝ6ŽsÛ5!ùB·“—œlñKoI³ËE]Ç'r=*x¾‚Î3ƒŸñÿ<×l”51m'¡~Ö=S™rT"(;F,Ïùõ¬û3ŒóHcœóøúûVÔ¶¡|%ªñå¸0Ž™ÀÞ;ÿõ«ÅÕ#‰ÎážiÏþµñ\GM¬U¯åýYè`Ó²ê}àÛ7¾ø9 FáüÝVÉYIã|MϨéÒ¸nÑ"ñ„Hré?‹î0Sž“0ëøôïÍužñ¦‹aðû@Ñ®gd™u;K™b;›BïÜŽH<ŸÂ¹-c]K¯é «†ñEýÉ8)…3©ÈÏSþ¥kQÅÁ;ë§Sè+EÆ«[QâøMÆ‚nB’]RrÊsËóßüó\!L’Þ¸xäã§Nÿª»]4k;SS$ÒÝû,=OÄbRA[$g9þ¢¿<Ì×ûC±Ï%fw^ê\G"‡(°è3Ÿçï]½î5}"òiôå¸óÓÎÜ®$®r¤d`‘Zò½ÄWZDG¢Ê€rÝ@Ïó«2xßP2墊% íN¸'êÏú~UÄÙ^.¥‡«'Íf¹_¸ù¬F µZÎqZ3¬Ã"¨‘,-ʿˇ-‘Ÿ\“é[6–Ö–Š‘Åg¦)O»ºÂ}~bW-ÐŽMyŒ^/ÔËÂHÆNX…ÏPA‘¦ÉâW37™¨àœç$uÍvGŒ2šjÐOÿ1y~#fÿÖRõL»¢ŽÊ8Ú`³Š3‘Ïð¯%lj5p?Òå rªQ¸ÆŸ­cZiÑÉ lK®U‰÷Óš¼Æ¼¥N„)ËN_Ôá…4¥)49õ ¦%r<àp@'òâªÉ;I(i dü§ä}=úõ¢æ/,íów&3÷±Û¸õÇÒ7"4@îÆãÏ ×®}|ó”žìè^@Û€XmÆÝ§‘ùÜS<ÂXŒ¨À;yÿ?áNR"B³ dw½?ýu `®FA#?.psZ‘’+MÄ6ÞçÝéþ}©_-É*áOüñO’2Î>bÃ78öæšw $‚FNääðsŸQß BÁ× ¹_qÆÐÍéÅXr²¸ Ô.Þ››AO™BÉ@!˜Î21ŽƇ·òeŽ5U‘»hàç?çÐŽ6È€ýÐ3žçÖ‘XÀüÆ£¼ƒLzsýh™]eD‘·d•ùˆúŸñô«LÊ G’,Gœa9z}h„ª<‘¹€Û‘O'ׯ?äÓÖ6 €ÛJ¨8þ÷=½ƇRd@äq×!}Nzú©é"«mpY›9ÁQß¿4Ì;UG;‰ÎJõ?Òœc†±ãréÿ…:äï¢@Þ žzzš’I£…Ê ®;&p?.(­3sÔPŽF?_J|nÄ(Üܱç¯øµQÖU;Xå?ºÀ`{fŸ ¬®ÕÚ¤ê3þs_½lзR>§;Ý2xcµcÃöâëM…ð™P3ÜÏùÅ3QkkFW.çªxÆ=x?áËç%w©ÙNpjïDg›PhÚFb>æy9ÿ?äSV2É”’~B¹ãüâ¯#$¶ìá] Œ„<ãäš©£abÜd$}åê8Ò¸9JêÛ µ8%n¤©nH`Û·g¡à{cñ¤hiTî,{÷éSÍ(¶_>`ûJîS´9'ôý¤vwQÞFŸ»b€í!@ÊôÈ®WwlyÒ’‹{•ZXÉbK¿tç®:cö4Ö`‘®NÐIàƒ\ûöõ©uY–ÑAòÎsÙÉÆ=ê“É+²±f@އŸçŽŸŽ+95º‰è.h¹¨'¨ì¤r«R¸$G$ÿJÉÕægšÚU¹T»yè=?ÏÑnu# NϹÆqÓ¾>Ý>ŸJ¥yqûèv¾)Û“÷ºŽÞÞµÎù¦Šœ—ÂRP7(…R¤Î)p oÌŠ0XvÉ¥+‘» ¹°£oϵ\?Æ¡œ#ÄZO½´1Ó=ÇÒ¸b—5žƒzêSµÞfÀBS«nõõ÷þUÆÌÍÝÄ1'Î?.+B[38ÜŒ!FíïÿëíÚ³º67f;xïœõ¯¢Ê¡kxj­¿Ür×VЏä\±$|çqëNd!ÛÎ0TÏ55²o vçN;}*ÁÝÌ«åƒÓß?ýoé_u qšó<·;ir8@òÜÄäpWùõëSYäÈQIÏlíž:cÜ~u$Q‰>P:dŽp3ÿê‘#hæ]¥|ÀFàǧø¥ìÜ1””•Í»¨L^ Ö$Ë8KˆW ôùút¥sºj.Á½†<ž{ž¼WQ~¸øu©Ïq>¥y$uç+šÒ_ÌJòI»qߟË>õð|J¹ñÔc{{Ÿ«=Lµ§nÿä}]à2+¯Ld‰Aq§Æ²8Ë6fˆÜÓÚ²5í&8¼e¦ÍÛüj®ð†{ÝjßOÈÒ]\Ûdâ‰w7?‰‡¥|†?ZµkÓŽ‡‹zžo¹âRà¹è`_ñâ’B7Øêqòíǯç"½gIø5>¥¦\Ý©,L7ÀǰûO½X¿ø8–P³q:…­¨É fX|ÏÇ×éô®”âž®$¨ßvxâ/Ëò—ÿ‡ùæša*Ķv’1…߇ùô¯Y´øFn`ÓåB]ÄBÄç÷1ïçÓ'#Ÿz~§ð†K >Öy},j¹$c#dòœJWH®CÉŒ{Cx(ëÀÎ}ǧ­>X÷>á<òp2?úëÓ5†¾V¥«Eå€-d´hÝÇšŒgÞº á,Z·‡-îU“ç×&±UÉÈUŸ#éÖ®9N"sqµ‡É¥îx¯Ù%2d#Žr¿)ú]ÏÃ?„úŽtý~ú)RÔh–m¨É±’_a_”vÉ"»ù>Å„ô½Gg˜fÒîîÙTóû²¤~@šô=O³ðnƒñû6/#°V;‹–hãf<ç{'¿> W©ƒÉ}þjÚ¥þFråV=$H¼9ñÄF»N£¦@‘¢˜XíIÔg9ãùת\֭ت—â)|ÁÄnù<õúc§ZélµU–߯ñ;‚__Š$㡎8sÐuk„Ö¯;í6f“y.¾ºýÖÛ.íÏCì+ìïîÜç¾¶7t{÷[ÏbË=þµrÇ9U?hsÓÇõí^u:Çá½)K¢È4k‚yÉù˜ƒ‘ÛãéŠô=U•,<"4……¾«1Ý×&u88=x==¹ÅyV¹sv0@Ì~M!­1ïž:þ•ãã&Ô9—oò7‚±³©3iädí]*Þ´zä ñ¶e—T™Ë‚Y3œ¿ã^«\âÒhÕYž;{xùyéÒ¼¾×"þâIPTçk@ÿ#‘õ¯‹ÅOžq ªÖ4nØ¥¤± b¥8!Ž3þ{÷¬ËG f\.àHÀÏõ«WLÂÉÕ•w`£sÔç·ç5Q˜m”§q, m¸ü:ŸÏŠŠÓråòG"V¹Rá•NCc#﨓ÏCÖ (JÈU¸Æ:ôëÏáSÜnòÃ1<óƒŒØŒcŠŠ 鄯$.ÞàúõÂ÷,II (s€q×ÔÔ*WnÖVì[éþy§±sb F<ŽFHúÔI¹ÀPW ÆOAïÍ ,;™"(ª# ÀÓ¯áîi… —f}ÅN3Žßä ~K³q,pO\ôÏ׃LóÄcé׿ÉÜÜ I 21bÍ…RÄç?Lç¨ÿ˜¨ÜÐ °ä3þ?Oʧº-æn;‹°à¹éÓŠ[}þ[”­Ž:ÿ/C@µ'å ÇNIo_ÿPªy¬äåÇÕ…]|ù‘HÛNW²ãŸÓÔÓcÊ”SÐùkþÓ‡%K˜éøôãØA#àçÚˆ—äUÖÉg·÷æ¦*Ä|û‰è8 uãõ¯ØžRw:¡Š‚Ýä.i$OoÀ |q’üª’OcÐôéSAÈTñŒÃצGùý1S¬gy%°’ géÛµ/ªÔètÃE¯{B?³“†ØÊ eNáBîó I @d{Õ¸£.®¡ŽTr„µ8Ú±fÚYzÔñïÏN´<5D¶;a‰Ã=9¿ø6ž$`ÌxÏ߯қå¼'fTœžqþ­i¢ѣ¢U(µntÑÝxR_+O†Lj6€AŽÝ8¬}RèM¨LÛG’=çƒÇò?‘«×{ìK³'ȧ+ÔŒcÕ;Ãò_ZI$˜ÉùÇäŽ=@ÿú¬D½œã»VùŸœÁ:“•.š²76öÚõ Ü%”d0 N ÷ÿ8«"XO–›Ô/|Ԍ©LLr¸ #óÝxõnTŸäSŽ·cåA†ÏÍ“Ÿ¥U¹; % ³nÒ0Ýjs‰#>Yé’T¯qÒ›rvò£ 1ÿ?¥yRjÍ¥®¡¶ÛX#•p_)UÉãñªP·™+‚²OÊy=z“Z:NÄJxf§ëTl%X‚Äð9Çä÷ô¯©É"ÜSõ8±>ìIìÔ¡WÁ9ǺƒëVbbÜ1R©•*O§áüùÅ26º© ‚qÉ펾þ”õˆ³‡êÍ…l÷ô¯¾…£«G-KJ£Ù‘¾n}:’ #2±ã'c·ò "ö–\‚ü?Çó§[ È¡Tgn3ÇÓù~~õm¦sµÐÐׯÃù\¨$ßB€63’zzkŸðí³;P08úr;zq]'‰Óo€Ô¤Ôbàä<¹}ex~2!‹i`’6Œùºõ÷5ùÞ{OŸ4¦¿¹ú³ßÊ×»¯sìo'‘ám&}bsÒåG=>^µKR³‹QÑç¹Ón•­N¹èœã×=~¸ïU¼7§w‡!†f‚Ñu^ªNL«jäŸçùbÍ ë³ø*;Ÿí !Gðýäû"•Æ@@\Ç]Øý+ž2|«KŸIŠþ,¬XÕ¼7xŒÆ»™F«¤ÛÏ8ͨ$:ç#ôÅwÒ`âv‰½ŠÉ6½â +ëùW–ê^× ürj_´oéІi_‚mFÉç qž¿/µjx3FÖb×|55Æ»rneºÖÙg2;•b;ߨëÆyÉæ´sÊq¥¡é¾Ñí_÷€K„ ²`ÅòNóqÈã©÷÷«zΑa&½r ˆËø¢Â0@ ij$ñßõ®ÃÞÕ¤Ðe”kS†´– 7#f”y|7>žŸ0â¯MáؼP‘\êÒÜâ›x›9çïVÆîp>Zjr×ݸÿ Mi?†¼'w,¨[/\³™:ÁÿqבŠè¾ù®>؉>Ѱ®U2N}ÇSüøúWˆÜœ®ÎzÊÎÅ–—ˆÚyÎŒ}ȨC’ÔaǯùúT³ü¶î»²Ç$`(Î9ü*²²;¨Œô*@éì;uþ¨“z3žÄ€@›*@±ÇNüô¦¹ËÊÄ{ýAÇÖœÌCîÎ :cÒ¢¹!|°Jí'#¿N3ôk!ƒ³"|Îì­O\óþ9éÿÖ¨•¶œï ã¨GOóÞ§iË!‚÷è1“úóÛëUËeðs‘Ç__Ät   F *žß\ã¸ÿlœG´à€q‚qÛÿžþ´“*ùQ¨ yÉÿ9þB6ñÏ;¸ ƒ×‘éùPêŠ&F—(#ÀÇÿZ˜WTSçŒ6}ô¨î¬ƒçáO˸“ž¤RnéÈìþg§ÿª€$¹uSFÛHÎî äqþ:b³;ˆ `OR9 Y˜*¨#PsÆ?Î?*CI™;g€#@½UiþVÂŒ‚Hÿ<Ò,’À 0êØb çÓñ¦È»åL£n:p1Ÿ¯—õ¡÷:«’]9È'®qŸj{G ž~RG<ã<þuPÄÙᇪàжã÷HJœócöúúú®å‰Y1ýÝÄãô ï{JåœrxÇl}?*‘"ù°2Èz*ç¨íü¿*h…cŒ£o¹ž­Øä~5:ª2ä»(í³šýò-Iœ‘ºwlz*—H%¸?ýzº‚Ä``'ŸÂ‹xwüÍåã…r1S$"4tÝ‘žøÏ^ßç´­¢A­Ú$Ž-ê 7˜Ø?6ݤúqþzT° £âFÝ»Ÿ8÷÷¢Ùó2 bHÚÈïŽjí²)FÊä‘–>ß_\âŽRí~¤{%B@\0Q¸)ý•Dñçwñ|߉õ­( BNWo®zCøÖ^¼>ÅbÅI?ÊnNAÿ9ö¥Q%½‚öGO}v·óÇpøX(,Þ98ãu®ÒÞÊ8l-žå Áêkm âÚÂ9ÝXÆŒ ^Fﻀ~†º«MFá–?1F@AÇnýë:Î3ã´t_=Ï&šp—½Ôá®ãŠ]jYä*±£òXãÓž¾õÖøžæ _9ƒ˜åù¼GùïíX:f†ú휒Yò~SÑ}úñÎj»^>¨mt×bJI¹£ð=xþ~ƱŸ,¤þéšÁÊrÞ侎+KØà‘Áža¸§ëéÇøUÆRØGSÓ¯ÿ_Ÿj«­X&ƒukwµ°ê È\cüàúSl­I<’4 À`à6¯ã\5jB­«IÙ–ÇT#:w¥¾¦—†žàžÒ ©l32qüë›ñÁ¼¾(ÊX’î00xÿìÕvDðþ°³Ú¡KÆy¸3ZÒ6Z´Î»e˜y®Iç'œý9ÿã•HÆ*²K™ôóîj©ÎþǧrOÝG©èñí\INÑÀÇׯëÞ¹/Û-ž¬¥@SååŠ.:’2p+bÃí>ñEËCm/u$sÔzžyæ¹MkR:ô“C¹c$€q×Ð÷÷¥QEErï×Ôªr”W$»™a JØÈRNHà?—AVVdˆ @åHPž•’¥€;‰c´cîóǧ5%¼ *©–ÉëÛ¯ô®IE½QºV¸Á™¦6à1´‚¼{{š‡ æî –añü—¹«¢T%@SÐóúQÎBð:á½zûcœ×=HIA±¦´H¦ÅÔ¥Tdãjàž9ɦߎÕ×n…?Ý9ü»ÔóPpIdî=@ëU¯cÌr1ùBcvH>½Î+Í“¼e}ìÿ"ni̤(Œ ï¿ç5nÙYh$ŒÎ~Ÿ¥kéJ²Z^ºà±EE#©=»uÖLv×*0!*í,üñéþ}ë벉:Tù[ôWêrb/+E­ä"dórGNsœûÿ_J“í?:+0€ •äœsúö¨—M¿”¶¥ß@8öϵ:ÛHÔ›#Élç<‚vûç:WÐýyËÝTäþG±›eÕº A@à†ƒÇçKo2ÍrùdsÀ #éPGáÍFiUÁˆp€>Þ½ië ß“¸Ü@bÛ€êyïÏåùVrÆV½Õ_åþcX9nͯ²§ƒàŒ’ÛPüÃŒùoÇ_Ö²|<‹$qm}èÄÅ@`ó^´ÍOIÔÍ£Fó%Ä(C–PFìcw^¼ŸÎ¬øj)êÖ »1M¾¤ç9¯˜Ì'V¾>5¥MÅ(Û_^èõ0T5Ë.çÖ¦ÊéQWHüA32Ú,œtúÕÛRá´H\ SÂÓ¹|ã'ÝNMs> ¹‡û_LYŽÙÿµïX¨<çìø5¹¥À'ð]ç”7<^„PãçWÎqÏðÖtÖšÞ#ø’¹/ˆmcSRÁÿ n›å€Ü|¶€ôÏ$dôõü6Ÿ2èÞ¿BЦ×_º ÷Ï1’3Ç'§õúWE«ÀwE(Œ®<]jÁœò‹P=zçwé\}¬…|¢E¸¤Q蚬§c e–@Á<¤tíõ­»Ó±Ëu¹ÞY^nÒ‚ƒ‰?±<=nÇÄóH½?ŸÆ¶oXÝx®Õ™ø¡]@ìFœçõé\¥Œ˜Ó IFؼ7 *I0—pÛ©Ñé·±ÄìAFñ$ÿ0É$‹½ÿÎ(æi._ëQò]Ý'ƒÙæð¦—"7_k-•C€^WžíÏNÿen~Ñ ÇHh´? Û™0FÚóÈ>½à´·…4;‚™Úž ¸PªbZêp§èIþU¿¡¹ê¹w@±øR›³Œ(Ÿ8b[嵸SÉÏ^˜÷íÔx”ÑÛÄ»~iŸÁwlÅqÑžQ8=1׹氜ôºþ¶&ÎZŠ]à½F(ÀO†lW»  îëÏ^¿Ëšáþ%ÃúôÒuË¿>HÐnÏ·Zݺ»òô_yNX®“¤AµøÆ3ú1þ¼V7.MƳ3“‚Þ!·æl®Vç¶C/\ñΪJë_隨½ö*é—arNß¹÷q“Ž£ò«ªY~gf'·§ÿ<Õ-Ë,žj±îX¯VV?.G|gÞ­˜Ü± å¸ÀGæ~œQ¸qó¸ÛÉ?Ì÷ÿ²"# ¸©;™ëž‡ëZ§d\SZ¡ª‡xÂrA:sY¬ûËæ«7¯ôÿ´øÐ0Ã=H'Ÿ_BJ!ÚbÜ06z_Æ¢jñÔ§w{¯{cþ˜Öó!•[ S nG9Ÿù5›¨øfÒæÔÚŲÚ59cà‘Çg'¿~ÕÐÆÁænçŽÿ©ïUg»-Ѹúóë^KŸ*9cNíÜÊ´Ó °‡m²¡Æ>öwr9<ÿZɰðä:l:¨iXýý¾½ÿ\ªúã×ÿ¯\%tÒêwFÕ•oô¨µ6YQdHØFJœu•“fÉoAO›9ïþ{T†*½[n×'=z‘YI驼tw0Æ hÔÈ2Tºùzu§íVm™ð>œtÿ=kI£ `™ ƒÇ=½:Ô7+²0¹8ᛌŒ{ÞŸZÍè;·©›{hna‘FŒ°ÚYXƒÓø^k¯ÚEcx¶ñ¡P’yÆzW©¸U! ‘¨fÛÁö wëü«ÏSǿ֟lÖ±î$PÊvá¹ô§ÿ®®[^Øéá&xšU.ø^Ü ¿©«äPvlËš1z™#,ƒ†VGL󟧧ùÍA(‘$%T„wÏ^ƒ<þMtº…•´WD2¨‡ÜOžùã·ëX÷ñ£G(T99#i$ã=ùô®J´½ÞKîRÞìĸÚO J¢J9>ÞÇT7cËI6ç$¸rqõíNÈ (Án9÷ÿ=ªX r‡YK GÛq”o›ç~Äã?€Å7ìQÂH⌖<ñéë^[ÅâãjQ÷W«5tú²£ÜLf´ŽýïzöïÇP.ÌÆòÑœ0ÜxëÓòÅh}–ãhÁ'°G@™¡mÃFå~ìcææZJ¾:?iýì9"g%H.¡:m8Ç9üñS¥Ã+’ çÓ9üY&ѸªƒÐc¶)#„åîYX玘éïIcñqošß‰J:Èé)DÝó*‚['ñïÿêü+w·h5û4I“Py>ƒ•d FB¢1´§ƒÁçÿ¯øWyàâ×RÒµ‘å¤K{sónù˜`c¦#5цÆc+Õ6“[õÛð4‚I§Øöß i÷šŸ‹ôiì­e¹ßu¨Ì¯nÎaL€qéø×C¤NÁºJU%O i±˜‹{ÍÏ~ xJ|Dñ&ªé_ÙÚ½ÌÜ[Hû¸<ÌË#t?1¨çéÇ­Í~ßÙ~,H”ù±[hÑ qÇ2ôàä÷þUô´êFo“±ÑQ¹IÎ]YÔ·—qghC«â¨ßÄò°cò=q^urÞOƒ¬ÕÜ"§†ÆÁÛ|“N¤ŸóŽþõßégF€+I—ñ$òn;B‰žøãÿךóíz$ƒÀK#¯Îž²ÆÞ2Æíó׎üëI;lak< ¶‘¡xpòë…61b¿ºWÆxîõø®‡D»[ŸØ+™µ­YгîÆÃ³RsŸ^O¡®FMɬFƒbŸøItoº:âÔê+[Jš(§ DVrA5C’?à?¦3Ågk‘¦_5&œ@Ë›ìžyû¿‘‘áÛéþÝ:Ë/ÊÞ(²êFFÔ”ŽF(úœV•‰Z$GÐôW$5Ãkú„˜/‚[O©<^Wu)´Óí„{f/á #óAÛœÊù99Î=?ÙãÒøgT3GáY8~¥q»“Ë÷:öíéÒ¸Ï^Eob¨ÿ,«áˆS#î®ë¾£“úþ<’wõØÙ«´iê7;âñ vn‡EP§ÝŒ‘ÏAôíY~#¸íʾàuíùu•B1ÏqŠŠ{Ýš†´€É¥E´ð[j® ¡«ºµßñ(þÛ™ÈbIãxüOùï^}Yò¿Ÿê;jdi׌º†›!—c‰.¤ëž Õ+ë§]¤{O{©vàŒãðªör·Ú¬D,±Ÿ*CÇ^sÛ¦i/JÛÆ\ >À8ÏôüÏÓÄGûÝà 5c;R‘¤GKbÆFIè>¿§½Grì%”wyˆ9àž”Û¹6K( Ä(ŒŒþüö¦ÈÌeb¤‚d Ý?Ç5ä9>f‰{XÏÕ7E£pÜ®ÌóòõÇ×ÿ­\Ê){vÛ»ŽràœóÓô•tzšº$»™²ÛùÏük›²L[0R˃ó>ž¿‡=¨…ÝÎ:¯Ur;çbÑî$À¯ãøTjKĬUΞßç½Kt˜‘ 2±á”täŸÇüûUuÚÒÛ[088õúö£sv†%Ìm3—ddóëŸóøS(ATdè~´ˆg\†È'§ôÿ"‘>V\eœg¿à ®DXUàõÁäûúÓY˜Ê©'æ>*Aϵ°H$ã'#¦j8—3ä(þ%ÎzP²ž*’ªOñc}}¹¨×2J‘»^ÜÔ³Å}ÌØ=}pϽ68È(FBzèŽ~rv;b•cÛQ³ß`}üégR¬¬~S×<õÍ4²8^wv [ßüŠ|¬ €%GÌ3Æyãè)²©h×!€£7úñSÜiW ÃwÊW‚Húú»T0 ¶òs¸ìùŽŸ¥;€ò$ ór?ÒšX`0m¬ çúööö§Ü(QÂï#îÏJE*ü÷qŒ7_Cü…PŒß?xõ?×?…B°¬€3Jžª¥ZC!J€z‘Éär{tþµ²aŸ¦ZöûknM×S@äŽv³vr¤ÖŠhž¼Û³YIŒãߪWŸÛ¡y;#8ð¸÷ÿ=ête ½Ùd|¬Ã99þUúRÎkµÓñ=øåÔdÝ۹閾 ÑïÈ[]aIàñÙäu8öüêä_ îY·Aso$ŠÀà0ßéMw’7 €Hçüçô÷â RFI¤%IÉ^zô¬è..%v4¤'ŽLwëéXNVµÏ(Ö”lPkß79éŒ~'ùUvKH„?É\{qî?¡º%cæÆAÉöü:dóùnìT*Œ|Ű­bÕÍ4°…q·Œà{zÓLÞb©Yr!zþ~ÃüñMyÄ„Ìa²Ò1‚)Õ6Wkwœc“Éã¯éIó-L‘â\œ&êFcÇO¥Q’ÛË“±œä:ƒéÇòôüëAy;YT.x¯o_óÍR¹7Ú‡;yÚ¯ÿ_¥Ciõ¬îQ•A%†ÖÉù±ÆqþzW—xŒ§öíÁÀPøc9â½aãS´nxb ‘{‘ýkʵe×.dH2®8<ç·¥%~dEExØ« ‡,­&ÕúsØóÍI¨ÀP7VsÏ~GZ,c#åÞPŒžO¶F09&©“ ¸BFðÄð~n+]“îcd›W6µKr÷͵vìeå€?Üúç“\ö¤B‰TÌ /ÝéÏO×ô®›WP·<¨‰vàñÇ–{Ea5®$ƒrìÜ"ïÆÿúë97/wrÒ½Î{æv.XÉ•$@?_þ½Lšl’Ÿ/` ¤œ`sœþµÛi¾k‹:+Q#-¼ÌJÆXdsúWAa᨜˹CD·kfBùÇž{ÖÁ½Û×B’W±äñÛÏõÚYGsÓ—jՋ܃•U\°ädýk¿¹ÐâDMål&ã ÐnÇõ—m§+Ë2ˆÎrÜ(-ÛŸË—Õ£œµ-ŵ¡Ÿ¢FÖ3˱dUò[ ’ÇÓ±Å]¿ðÂmlØÞíA #ííÞº-ðIÂDmnôÝó tþ>¿lI`>É.Ä ¥u69A†àçëŠì§ÚÉ hyN¡á)m¬þÓ°œEíF ðQž†²/4›‹)Z6gVxÏl•#Øôÿëײ^Ú4–A¶°ò´øåûȈùåøÕ‹O ÅzL—æ??P”/ç!#`ç¹þ«Ž¶W¢×Qîq¾¾¬÷W—îÐý‘"¹ ²æ@:ç=ÿ­zï-#Äå#Q ©@Ã`#n-›²úÿJšP"Ñlã,gKÒc?é#=ÉNôxîø›ÚêË%ÛJK°Á+ \ñÓ}+¦P$ ½• –7m{B]¡ YÛAvêFoOþ·²Û¬²H7ª› A‚|ÕàÓ5å7 WÄþÊ"ÆÛ³99÷ãõéö· ñ¼äñ×úsR-Æ£CµŠØ¨8„‰A9úîªú&¦"Ò´Û!Þš^§2®ü(ÍÊõú'&¹å¾†é]hix‚M‹{ „oÚlo·¶/3ÐtÿëW/i2A©ËÂÆþ)ó*ã 8ÿ?ZÛñØ¾ÔØ£¦Ó¦'Êcþ“œøÿ:æíX-몳(>"ž]ŸÅ€ŸËÖ¹kO–OúêDn—©7ƒ¯d‡Fðó y 6š”„ê>oϨª>-+˜a 4+`ê£Öáp=úŠ«¢4pxjÂPÈž^“¨ŒÄ%±íêxö©5ãæXÊÀ‡Å•´{yýrž1øŽ9ä×ë'®ß¡v)ÝN"ñ-ò’H7ö1ÇÍ´9#ôÿõÔ3ºQÉ?o¸e*ÇŸñÇOÓ½S¼½2ëÌꪙ¾…•”` ¹ÃÿÕQµÌ†h·gcOpÙ88ÞsøÖ¼º•¯{»jiËÕ3&d–Õå!¶ä·8ÜOo˵:YHÂÇ쨼¯µTb ¡ùAźäƒ×ÓóN•ÚåIó »F‰·© tãóZñjw#uæW¹tìAÞ¹Œ3tà&9ü¿J‹ËÝpØ9fâç°à{ö5ÔèÞ“Y‘æšS ñ°*îb@Æpqë^ÛàŸ†6ñí–=/ÊE$ù’@X·‰Õáâ±ô°éónC—UÅ?uY/jÖÒCm+ÉVÏÌ#±ãÓµsP4Ÿfýë “‚ õé§>â¿Amü5kçA¿îËtŸò+•ñ¿ÂÍ/YÓ%Ý-¸ gdì\çFOùü+È¥ŸCšÎ›·{õx~V¿´×µ†ï¿wÈ`rÙ$òqƒPÛ7o*0ådŽüwëø`×[ãÿ Þ;ÛÜ ­úàç{‘Œíü«“ãËÙà óŽ1‘þ}+ééÕh)Ãf|•j3¡7NkT$æ UA<6¯ôüi`‰˜] Üž£ŒãüúÓž"±˜Ô“÷É!Gùþ”ÖSmÎ]äw8ãüûV¦#¤ Ί§88'þ˜ãüŠï†m¼ï<×ãúU™W1GµX˜0°àæ¢K_ºí´nÎÕ'“íõäP‹ù ¬o…”`# õ¿¨ª±²Úp¤²€Ol`/ò*ÅÄ;Á ʪ«ÎH=?™â£UvdÁ åðèp;Ó`-ÛØ Æw£ñ?Elò +·yŒƒ×¿õ§¼%çFçáK/éKö=±«®I9QÆqÓ©ã±(oW eçåÆ=rzûT0Æ]›KË€;ÕÙ,üé„·Œ¶O'8úþ}úÔQÚ$[ƒ’vŒ†#9ǯõ£p#”0a:ç¹ôô¨UƒŒs×é׿â*Û[®å%°G+»§¯~´5²ÆªR0Ï2…Îzýh¼ŽŠ¥;£§9ÇÿZ²'=ãûÇŒþ`¶SçBìØ#y!qž‡ôâ’(²ƒJ¦@¤j7BÀ玧ùÿœU›U.$²Ž«Ç'ú~¿…Ui n¤ÏCA‘þ<@4Ÿ67‘‚Çæ ì }teÿý~gÕÓj= Õ™Z0F9Ï?¯éÁ©Ñ|û”HÉ ãßE ’U·‘×<õàõýjRÁ ÝðÏ8ÇBz íM6»ž•9Ý“Zº@Ã,¡ÕI ŽG~O½NFb'w˜¬½TTݽ;ÕXdáIG+–ÈÏõâ¯ÃÃù'Í>«ê}½³ZÊÛ­ÎŽozìp•P2‰>uWw=AèHúþuNS¥m$‹½ Êá”ñœõúVg™±s°œc ÜœŸ¯áVíXÉqoˆ7 7Ã$ú}•Z|­8# BýÔšì{MÇúP‘Á.„áqØuÀÏ×õ>´Ñnb/ÂÇÑ ÁýÏZ‚Ø΃œ†ç§‘ôÿ8©îÉHˆÁ裞1Î1Çï5}Z??³Z-MJÌT«Á—¾:ÿ*¦T>×B/Êp àûzÿõêe‘B¶Fp>T ~¹?çœSíí$t|ýà3׎ªm«±¦Û•Â(G“€OF qÓçüˆä2!|…Èä[§8ãëWoáû4q˜ÉgrGÎ9ì_©ëUr$PAO9 ž1ŒþU™¤l‘gìæ8ˆ@6îË2¯LúǾ—Ë”±ùC2N2ëÿÖ­I[ a‹ d°d´M9fók`:k+i¹¤ÛJè«3¸8Î[ÔrO^½ý«ÏµuE½›rœ‰ …À9{ãëüëÒc´ ØrTd‚¹éøõëÏõf->q ݎᎫŒÐÖJúœówµÌÈ>[ˆîIpz‚oóÖ¦¿ VÐ`9f|q÷¸ïíM†6Šh„€Ïw?^ ýy«Q({Ü1çåÎi4ìd“¶ºšº’}0`¤’1ÇÄjxÀ÷üÔv±lˆÔå¾Î9œääõö?J»rZ)fbØhžà‚0xýMIo¨CpÐ}ªÓ ¯o¹âm®ÙSÏ9ç¯8ªv›¾ÆÊVWZš¾Õn´­"{‹ÅÄVr;eTä0FAíù{צxN×LÖ'º±hÒînä #SzÇHã¨ôé^_i¡ØÞiíý™¨²Ú˜M½×Èpe¾còœóéÚ·ít{Ý:âK“o2yw³J'y;CnË4{%¶‚Ú9;å¼ÌgóSÓÓ5ÏÇ …ïvª´dÌK9ã©··Ò½]K OCÓµ §eÔ.-¬’h@Ý— ¿6OBw õªZ×Âxt¿†ƒÆ‹­[]¥ÜÓX4# bb]·û¸ù1ŽÍÓÖ5)¶ÛCu$¬¥¹“áËb.%ÀÉûLÉ!Pžãއô­ádWNiåÌ«c8Îeà`ÿú¹¦øCNšÂÆËˆÞùs‚1ž‡¯5Üh‘O¹ÑÜoÛÞ® ƒµ¼âìFy={ÕE]êS½¬ú5¤Q¼Rk‹ÆÕÏ?fÝÁÏ·éWü/ä^i6ñL%T‘5R&ŒôhÈ©äàjõM'Ã6ZøXdÓ$“Q°–˜†Q½VBÃð®OÃÖvÞð]½ÚË嵽܊ñƒˆ¤2.ïÈÇù¨êaÑ›i-ŒMblÏa¾|VÑé6ë!ï¶by烟ÿUrÞ#¹yn,¥‚ Ú ¹#û@ ÷ägÜÕÖµ!«5É*¾mæŒäígàŽ€g­rþ(»3é¶’TìÔ²<™G­qUo¡Òs0âçÅz:ÈBª[ çžïlWo4æ _TŽ@VFÖtõUÝ× ž¸î3Þ¸û#ŶFiW—Ä‚” ãò8ëþ¿‘Iûó;^I#[K¸ûGƒ,%‹³5Yclðs*œãr}¾•¡«Fצ¸ ‚ËK@HܤyÙ‘Èç½`é÷Á<khÙ[CÔŸâ¥è:•Ðê7öºòøÓSvÞ1ô9ÿõWj}QΖ›Ρ(·Õ¬°6(ñô…ç/·|îÿ<Ö&ŸxñèÊ…UÐnAËg%î'ŽyëŸÊÝÔ¬º«íÚ‰«êRò~ñW#àb¹øƒ®•$ù!BÏ&áú ý?*á«;^ìÛ^‡g«ÜOZMî\\é¨YyÀ ¤qÇ©ü«™’cm¨Æ7üÇU¼”¸àð¤w­Nmš¦©fùïl•ØÜ…FØã¯ø×%ªîV%pLwíó£šóqR–úÁ*1V¦ÜgB:i—99ÏÞp:ÓëVµé¼Ý>U«Gn»·`)/vÇéX–gþ%óbÌšcª<ÒõÉÿ>•¡¨>R\†Úe…T“ÀáHÿø¯9ÕN6ܾV’3fo;ZK}´vú1çðÇéô¨ yLB2T¨™ÆáÇÞþ~¿J†c»Ur¬×÷ÿëæ¡Wb¨.‘>WŒƒ¸×VJ/úò¼Œù†m_†ÿRŠ1ÏcÏn+CGµŠãTŒHxxÆÍ¸ã#¸Ç½gHDÑ1+‚Ѫç¦ýz¿¦IöƒLà$NsÁzW R«%+.äÂ.SVW>ð'ƒb¸… @@Ïô&¾”ðƒ£»„,軃¥|ƒðßâ(µ½ŽÞdB˜Dgb:×ÔžñÄQÄ%†t9ä©#¯>ý«ò|âÔñrŒ'x§£î~±—аMhw_þøoFðÛ릮ÖÑÅq°/#g“‘üû×È^>ñu¢ºiWrKVêòç_IüDñ x“ÃrÂò.Є^8Çôô÷¯ˆ¼c©È·ÙÑÊœ6òÙägòçÓùÒÁòÖ|©va Q÷å+ž{ãE/£šŸxõý ²¼•½š<õŒÄÓZMþØ®¶¨$*c,ÅŽ9 Õ„»óUU©9ƒ×·Ò³ bÚ2»y“§õö©Ä@¢9ÎxÎAÀ#ÛðþU›É°.Iû;|ßùšÇ4ÅÃíßä¿ÈѶ»ÜûÊáÈŒvó)àǰ(fQ·Ù÷üóTÂÙˆyk‚Iì?Ÿ×ÿ×R37š3¼dà?ðªy&Ú]|Î¥žb Úvû¿á!"]’*³vq·#ý:Ôú_ü…mrTH¬6·8æ²£VbO!º° ÐÿŸoZÓÐÙT²1® ‘H;ºŒŽ¾Õç×ÉhR§*‘“¹ÑêµUÉ8­OjŽ`ûرWÎÕON¿ç¥U{à»aŽÌc==çŽô©!À`cåêOãéYw ]Ã<‹ÏsƒßÖ¼º’åFI»6ˆÈËó1|` ‚=Ç_ÿY­ÁqŰ(Ü$ŽÝ1ÓÜW5áÉÁvˆ±<ŸÇ¦zã©®Žw ¨ œON¿JçNèÔÆ×GYÛò’>^?~Ÿ­c$r”zçï€?—­ikà¼H7mÁùsØÿ^µFÄ7Ú¢‰~|“߯œ®Ì•Ô4„G–Âèw'>ýë:ê,²®Ü1l ~€~}kÈ[y#s2çnqÎzuö¬MP•&Dàzc×§_­f’~ñ³“E ªJïpKêsÛ­yõøûMìÏÂ(š\½NÑßÓü滦¼‘‘—ç# ÎÆÏ5ÃÜH±Ý3³3 –\nÛ“ÿ×ëíZ+ØÍ¦í}JsFžnää#"© ×»úÔÕ‰!ûK`5$nɳ`Œ}:vÍ"ÛùZ˜15™ð=”`ûòz}k©Ð<¯k^ ²û>›(Æ’î”øSÉù°4V­N—ñ$’îÙ1M«$cÞG$im˹ÁùUÏÖ“H¶2Ü.d ŠIc»…Œõ^¾žõ°þÕͼÈ,®Þm¯1G¼¼zuùMRÒ4ÛõIâr†yc<¸öÿ=ê©V§]Ú ?ëÈm4’jÇoá=Æ“±o¢š) P ‚Ñ·™» '®1ô5ÒøWÇ÷Ð5]2ëEŽý.ÍÛ½Fß„®?Zäü+錓Y^@`HXãp;²F9ëý}ëÔÆ¯k6–`·Ò®¦7I8Úà,P¹# îç¨É‘ô¯N)I{š²æI&¯ø¡b׌ëmo!‡ý Ö5L¬|¯Ê¤}ojåíìuníµ;K¸ãû4„Å2²¨f“ƒ´÷#§= {^• %î¤l´‹¹ÅÔK" ;d8Q¸óÞ²üg­jº “Mµºó¯-—4tÆãß8Î:VQ¤ÝW„§ÊÞ¨§ðïL‚Mjâ9Ç•4w¬Ñ‚6îŲŽsíüë¾Ð´ÆÔ¼_§ßÚ,+ Í·•"§Oõ¸3×pÁ>„µŸ™lgâ ídü×Y¢ ªË'–Šž‡#°Æ1]/†ôéô].]A–št+ Öé!É,ÇÊûç’N3“ZÅ$´éù«s·Ê&‘o}£|IÖ­¤†ãìÒ^b+«yUAðqÕÅø¿Ã¿ðü9¾°jCz«8ÔT€±•âòÈ;_|–är;àÕ~!ê2ø±î­íÏKÇE‚G &Ñö÷þµFÓUñŠþêzþ¦·‰9‚æ(Z4QÄ /ÝüÀ²~ü×+¯{©|ÿC?c/l¥%§s™ñ‡’Þ[9íHšÞkÛFÛ ¦Ø˜1Ó8ç·òó-OPk}Py˜2©àúó×ë^“©ëW"_(¬‘Mi«H›Ž6œFÊGOóšðýwR™ årKÇó3ãï㇧¨® MXÆ=•N÷¾ÆŽ37ˆ÷í"VPÚÀíôô®ŽiÜê ‘bi5Æ,ý2ôÆ ïÛëŽcÂR=ƦXᥠœ*÷à`}k ’V:変·-ª]²äŒ0Ç~£‘ø}EytgÏÍ$uKDœº’Ç:.™o áßþË‚Žv™Oëí]š‘_뤜ŸµX‚Ÿyƒ¦;rIü~µÂ,àŒHØOøG™6`œ3s“ƒÓ?‡>Õݦf¼×E >ß [ÂÆ@ý+½Y^æiY]v¬ÞMÈÄB‹­QÔ9ç? Ÿ_ZŸ-„ å´¤’ ÁêGã]²þl7 càY€nÌqÛŒñÛÛë\½ócGÆ=>eFÇYåÛÖ¼ÚïGoë@Wåm6¥;6«tþ[®ýJ`ƒ ƒÈííøV5Ö•uªêÛZC4óM5àòÔÃ8éŽýkjé~Ñ®‹ÅRF|üþð}ü2$Þ ¾ŠøƒåªØ#ÆÃ¾`#¿é^Q¯h1iòÄ—iXÁUuM£hèH$ã8ý+è ÿ€Þ*ð|7ZŒšuåš6°3Áã¡P:÷Ïzò?ø~âÝ’g+e‡9ãüþ5õ™v)Ê¿'´æOÓü®|Öo‚£ ,gvŸÏüÚ8…ÂaJ© †è9ã­,M‡Þå6äö=ù‘JDÅH$‘ÉÏôéþqJ™‘C—#¡àÎ?\WÖ#á,˜ÐB('æ’r=2=Ï·-4ñp…ºü¼NrxöÍIÀ©€ì~¼ûÕIïÚE$yŒ2¬¸ÁéúwéU`m"ÐŒ8ÏÞ/œu?áLw]ß&T‚I ÆO~?ÏëTžòD‹b¼ðtÆG§¥G%ܬü“„ÉbG!¸ã××õ¤G2F–ÕîÜOBò2sƒ×4’8ò_— ²d’;dõÿõýk?Îq„Ü@£éJ·ª Ü ¸zž;ךbæ.Ûœê¨w/R2=~¼õö¦ùHÈYŒ€Œßôè}©ñ܇‘X*ªñÇLžƒžÈ¥£rJ€0F0r?ýiµCaÝ;ËF€Gÿ^¡›j«9$ƒúþ<Ô¾_ÞïÇøôíO˜„ÏÍ´ŽÄƒžÝ¿Ï¥ey_ÊPARd)8>£ù~´ñ ¯óDdxÏFA~”2PrIÉÎ:ú‘S,S0Ï`lgúPG©¤¶×²Ú€ó—ëùÖ…®¬]Û™­¬n.b'Æ™žz~=}j ‡“ ml6A<õ½Ÿáe¹>±+&†8ÏÝÐ}I'ð¯Ø09í\MG W·Ÿ‘l)YE¿ÀòvÐõ;|ìgó;ïBGl~4ï&æI{gP¥r¡ËŸqÁô¯¤b·Á’ŠÊ«Ô¯_nO¿ò«öj*…xQðr7 Î}yã··§­{ÑÌÚµãøœ¿VK©ópËwvbr¼ôçúSÝü°Pªïãœû~•õ(Ð4ÙSq³¶`¤‘º%>ÞŸ…XÐnÔì›@¼·CÈî8ë[,Þ`OÔÚºRü–· %ò­»ÛÔœUí ßÌÕmCAæ‚v÷9ätõÏOÒ¾š>ðÍÁÃhÖ+ެC¿·~)š·ÃŸZÚÉ<M´RÅ—™ :ö qY×Í)Μ¡ËfѤ0®2NèóﵪÀH'Ìp3×§ùÅQ–áLŸ}ÉÎâ êsèÖ¯O å˜ ç‘žŸÊ©KlÁÝx÷çøïÓùWÍ»É_¹Û -e¡«¦Ü!¸E Fr9àà{çÿ¯ý{1âpŠÀ¶XïÆ×õ®ÙD* N0Iàþ½w­ç¤nۂȽ=úñéþ5èkÆ&¾!.î3Ó?ãÖ©é¸K•ÈÁ-ý}=ê_ߥ„I" ¶÷8àt^{t® Óâ]¥–¿ á–îÖ']Ð($öúVUjÇFUæì—âû/2-ûÅÔõû‹Y¢¶onñZÉ…ó]S'ŒÃŒ~uÄëò*£DçîFyíëÚ¾›Ð5þÐÚ|6k·ðþ¢T*y² V\3Rœdc¿zá~/þÌš—†Õ/t;¹u Iܰç¸9Þs‘ž+óú|i‡Og^›žç»ý—RQæ¦Ó< U^E`|±¸)an^1Ó¯áÆMamw«<óαC%Å䑺ü¤3©9¯@ð…•Ε É¤^"©šXdÑäÄ›øeôÉ\cƒÅqSœê=U—õùs…­Ôâ¼G;<—·aãfµËɹ°¬Â7çØ}kÆuxpð+þîe@[v~½8ã¾µî< ©x+[‹›i–×Q–îæ™cÚ¬¬6ƒØÝÔ~™¯ñ.¨š®¯<Ñ[ˆc!Tz ôï¶¼ÌrqNîÒ4MM'©:ª¯Êèh`:œŒþ<þ•ÑÞÚ˜ï­dsµVæùÂ)©ïœôö¯7•Æ—ÉèܨęÃc<`Õ|C©³¾û©ÈùÜäãv ~}ÿZóðõéÒ¥ï[TšÑ#×/¢ýÜi•W:ºžu åMh¦m¼UkcÇqgå·2DpxÿõV¯Ž,î”æ'ÈÀùy¯†ã^ñ9sm ì¼²£Fr>ðŸ¥O{âý'á„&ï\¾¶å[Î|zñ÷³œ`óêM¿qnkB‹Ž¬àÿn/ éxbM^ ‡–Àó¶x÷ýE|'2]ÄáÕAaÔqÛ?ʾ°øûûWXxç@»Ò4Ý| Q<“@í1îúñŸn~EUßÐüÃaÆÖÈéþE}Þ@ªÒ£(Î6×Cç3¹Ó•hJ?Zþ‡q¬ø>Yôxµl]³J¡ú~•gáÝjqiÏul¼‘öb çñSÇN+–µºž{q¹¢žX‘œÓñ¨bCa*ºÊêÄãn0{fºjÒ«8Ê”êjüŽÈbi)CN––³»_ðçÒšw-t)ü2î[¨€yÙßÜc¶8úcÚ½ Â^1’õÞin$ €—0Î{Ãüæ¾WðƳ#ꜬDn`NüƵufk2-¬ÆfÀá%#ÓŽ=O~+çå—É{©]ÓÌ•F¤þÔ|{¯x³Z»¹¸6ÖÆÕPÈ „[ œîÁ<þµx/‹ïu ½8¼‘´jü„ny÷éŠõÑñA­ü7<1¹–YrY˜‘ƒÆy#ñ®7H´o]ˆb„]—!|¥]Û²NOOƽ<« ãz•c¶Ç•ã£%T§ëÔð³#îpÎ>ÜÿZgž27p ýü“Æç½}«þÈ:ɳkÄžK`䔵{^x dúv¯Ÿ<]áÝOÚ´¶š¥œÐlùCA\œ·#ŸO¦)¨UpNÐÇ¡êOcúsøT„‚5ä”êyù¸Èéí@ \¸#<óqéþ}jHædAÜr2£>ŸBLƒxÁÈ8b2O¹ÆiÖΨ>eÜ›IÏ#§­\FRÀ)<W _ÊsvãŒNqÛ×®=ê¤S´yB‚_cßñõÍX„—z€p› Áç#Ûòæ‘kQvùcQ•á²¾ƒ§øÓÁPÉon þ½éÁ¢¹ÂîùW N·ùÅUÌ)òº¢°à‚iÇ_<ˆÖw‚‚U}º};×´ü(–9ü`›8RÛ€ã#qÚuGž[†aœ¿|ŽüWæ8øaåZv’R[Ÿ}€ha¡)ÁÚ[?×Èú_ö‰øo¤ø´Ú¯„ôç[©Ýn çOû‘ôÀ¯ˆuÝ&ëG²s<.°•XÁ(vœIÎ?WëÇÂïƒéc¦@ú²Kqw™%–âU!NxùW œu8¯Ìx¶ÚÙi×;JÛÆ¤ùi†-ž§×8Å}wÖÄ´èÓÖ›×^›êpfj”â›~ôO+ðìsjVs_;Ǧy©æ•ÂÈ#ÎXc 8Î?~˜þÈþ ð^¡áy4kk±Ã“o¨:ù„ä’Häã$×ÁZ÷ìÛã{?¿Žm¼?q?†.Ie¾‚xå(¸c½1e\)9#ŒF@3~ÎÖÞðï‹£Ô¼O$ó¢'î7} “ü[9à?jù^!ÃÒXš³u9š“·.ÚþVü¤Â{Z”Õ8A+î÷·õÛñ;Úoá_‹|3ñq¨i‘¤Ìžpšo"Ué•`í‚8<Ö‡†üâŠ_ /5¿ÓtÍÃÈæÖyÚ;¹Õ2yC0P òGNý+ôU_Hø“ce-ý¤7¶6Ä4mÎàž1ŠòŸ‹·_ ô…þ6“MÔãIüCe%•¦olÇ̽XÜ+«08Ûæáˆ!?çÌÁbëW”0¸x¦Û²ï÷uþ´8ka(ÂS«ˆº}mµïÕÿ^§ç퇄ˆ.Æ“j¢5ïI&E ØÄäãÓ<ãµ]Юb´Ô­´ÈîmZÆ5 q r ñ¾„ŸÊ»_„‘ÚþkèJ‹eyd˜““òcoÑ¿•sZ…Ο…üTú|abg“bdóö˜ùÉúóŽ¿Ëú« GêøxGªI}ÈüâS朒#Ñaе-xi0½I§¹š|Ò6«€Xòx=À5Üê:f¤×ú…4kÍ>x´ùkí„þòqÃa€€áppr:q\ƒ.´½"Ü]Ý[4ÚÝü¬l|¹8„äù’wÁ”\U?Â:„¼>5huK‹½CìȬáx*ÌÎsÉ?)ÿ ÞœŸÄ–ƒw=jO Mác¨Üéó[ÄöÖ³Ï5ºÌÆf‘Q°à à—¼Úî+ÿKoy<²Ïsd—NÂqœã¸ýN;Õo†ö¤èú†¢ä[Ãkcr©tÇ »2(#œä’!SÛübºÑï.ôí6 IÁŠo 0–S³a裞¸È=ÅaZ¬'N2nÞFM]¤QÖt8ô@Õá zæx,ÎGÊÒeL€cŽ@'ŠÐ·ñ-Ô~ 2I+»4öÈÁ×€ôÏ{zŽÿQ³Õ<8×RÚ:ÜEÂVÄr$äüÃõ®KÄZªKywh! t—2áO'Ê㞟ÄkÍE rìΨµoxí|Iyâ}^´Ô5]:X¬§žâw4†e]­„‰€ t©ÆNÚùÞöSö×'¾>R3Æ:W¢ë6®þ´–f +[ÝÈÅÚÛÏO\þé^]{"ÛiÈ#ïg¶5äfUe4®´&%IË•èúïÚRªYD`ü§'óÇ?Z¨ù…’qCõ©õ'fŒnÈÀçò¨-ŸtÁˆ‚A ç ¼z×…F6•¤´f‰ûÆJïqw®A*3ߟéïQ%•‘cb݉ >µ¥v޳Ú¨[1ƒÁç>ÃñSr©2•ˆªœîà\WÑár¨T‡ïo¼µW ¸¢¢À2Yßæ –£¦,L$Dåþæ@Èèr}«F5‰‘‚DÃwpÜž9Ï¥G4ì¸Hć·9ç'§¿Zu²XÅ{³¿ÞgN¶º,ÇMÕ!ŸnÅÞÀ‘Üÿ]{ЖÞmÖã ƒ–ÜqÎ?Ãú×€¬;xK€qÊgÛ߃þx¯Að¶±<þš mò”ªü `múWÃg™Lþ¯'mW™õY&60­ìå³:­7Tµþ׎Ic œ3uÉëÏ5ô·‡ôh:2k[Ç4¨ ‚@ã#•é_Új’´û™›nNúÿ.+¸ðê뺗tn$ŽÍ~|,œrαù7(¤ïoÔýG‰H¸E\úgGý¢Î—yä“c>2mÔmžû»W¬[ÝxâþŽ«­é‚ìÈ:ˆ—9ÁëÇSùׇør×KñN„±,q»ùxèÉ¿¯ë#MÒuÿêÎþ[Zi }ö`W±èãøWÍé"ìýNÕ rNêÆ×í%û2x3Â_ïï¼3ox·Ëä”’k–‘”yª+ÓcÚ¾ E$—hÆ<`óÐzã÷Ä߈º/Ž<9&ƒá]ê%‘UcÓ하3†€0’?JÂø9û x‡Åšj^>¾ÂzdoÏå¼sÍ*n°Q˜)À<·N8<×ÜdØÉR§?­KO=ÏͰ*¯'°Ž¾KCç |7Õ|A¦Ë~’ÛÙX¢åd»vMþÊ“ý+ ´ ¼öY2;‹uÿ9¯Õo ~Î_³M³›]KÄZŸ‰. ;ÛÙ#XÏS)#ýI¯pðwìíðS·òô_i蜖)&?‹99üëÛ–2ž!¨aêÇ›³kômž$a4ÄPŸ*ëgøÝ$~jòÙ΢7FpT“ß¾*½­ÉƒÈ$`üîGO¯×ù×ïêþÊ¡2HŸ |8Ò7Í™4øßŸQ¸WÅ¿¶¿ì§jÚ]î³ðëÃvª%xm¥dK€±ãË–Gœ£‘ÏRkyW–/¬ÇGÕk÷è´9!N–6N8Win“²¿’Õëý\üÚ½ñ jwÐXC+¤$…fn™Ÿ¥~Ÿ‚© NN.úØù^iù猗âÒ¸@Óêÿ\Vp”Fƒs•céÇ^ŸäúUÏÿ„ªGP8‰pHéÉçšÏi È |“ÓNqÿÖ©Æ7í>Hß “£RÌSµˆÝ‘Élõ'ŸóýkFß °Ç$ñÏéX–ò30\m*£#9üúÖŒ2›”°Nr9®&·;`šGCà|ŸZ31mˆ[pÇ|{þžµé¾.mº+4d9ûǶÓù×–xõ$ñŒ;w`+‚Hàà¯ó¯Mñ«6•#pæÛÓ‚5ëÆê”y»Mv½«gÆrÂ'% |»‰ÀÈÈú:Êü0ÎqŽçŸSŒûÓKÄÇvæ'(Xçž½¹ú}zUvy Æ[q0HrAéôõ¦´Ó±ÍhÉèv¾Ž)ofGvÛ³gÌsƒ‘ÇJÊÓ›û7Z‰ mÀ*ØõÿŸ§ðÑÌ·WD0ÀBC0ÁÏGåÓÒ¨øÐ&Ÿ¯yŸuJ«F}G?çµ+óI¥Ôrމ³ç‹:ΗãmYž«©fŠB Éà÷Ås6ºuÄ÷°ÙÞaÆï”:cŒ{׸|TÕtÿ¾dˆ²^DŸ4»0A8Ï~•wà‡Á)þ*øÿN±†u³~dyÔòF:žž¿˜qJyN&P©-m{uMô~}~g­‚Êkã£í)ü7ßüŽÏöz×¼[ðÂîÞÎÛCG†î}¾uí›~íð¤íê6zó_|xâ6¥àZZêþ´±Rš…¼B0‡mß/«÷÷¯‰lîµ]ÄÖê 0Óïdæ}íÈüzž‰ñ»Vñl–ÚmÄ^rZ°S/ å®FæÎxéÛÒ¿«]Ö®êAY³õà¥õ8Òš¼mo‘ôïíðŽK¿øËâ.Ÿâ½j {M:è¶÷’-¦øã.XûFB€FÚüÐÓõ› œ£Øn ƥ̇¨\“ŸóÖ¾‰øÇûlø—KÓ¼[ð÷GÝxfk&Ò’KèÚt'bÙ;Žó&¸ôÅ|­cp@dMÒ!å€$á9ü±_¿ð†¦*•aËÏÊÖÞ‡©ùfg7í=›ù[^‹ÏMÿ«ž¡ð÷ãœþ ¾€^êž">ò™äÑôÛÇò¤Œ†MÀŒ¯>¤p+Ú~|7øSñÏÂ7·úW…¦Òu+yI8¹pÄvü¶ŽàqÅ|…ýœ÷%RÞDM–èÄ1#w Ç­{ÇÀÿ6? üsga¥Ësª\6&\$r2xíÆ+ó~0ÀNŽ>¥ZjÊVjÚ/Ó©÷ù=e[ NÛìüí·à}ð?\·Ò<8úEÍÇ‘y)1B—LBBñ€pO9ééR~Ó¿³½Áø áÛ½ “þ›dEmnÂg‰–%yÔ®NWË ÙþÄ‘·Ÿ™¿fÝkÅ_~?xrFøLw<© ‘Æ63ã©ùO'5ú‡ãËh­¾xŠ ÔG£Ü£ÿº!`Jó¸b”ðø·‹co^§…Äõ-J.Î[¯Á“¾ñ3A¡ë¶PiwË$vìãíA¼àr Ôö#Ö¼ÿMеΗqm} ¼ÖÌ®0%nƒòå=:÷Å}âO-¾™âKÍÔÞ^ÞX´a ‡ÌÀ^n `•ÇÒ¼]|Ko©ØÉ­K °ÌSì! ©.ä1n‡¦Üú~µý„Çañ”ÔéÔævÛª¿sóCB^òï¿_M52|)á›OxƒOšÞ)­¬¢P |É#çc'?Ó5Ò|EÐ43^?jÕçšÈ^Dö¶0H®¨8$©n2Á›#×¾k#Á~$Ñ<%¥êùžsvb‰bòбµ%˜0*Ø󎧡íׄñ=ì÷×¥½Ó\Û=îy@Þ?u÷vã cŒW[¨”R]õ:¡YU–—û´ûËš÷Äd:]¦Âú–ªíg(XÕäó› JÅ‚…ïÛÒ´4k Ë$0»'\ˆ:«’á8î~µá/…úߊ4õÕobµ³Ñ¢)]ÈAÛÓ’N8ì+wÄÞ%Ó<)hÚ~Ÿ¢Û¬ªnÜê±u•@ä m¤g€’2x滳©WEé©ÛßÀjøŽÓAÒ¼0‰s¬Oe§Éd]âYœËÁ XnãðÇ5Áø\7£éÍz7‰%?ÙöŠ0ìJ—Ž Ó«Ïu&G¹<|Ø8ä(ÿ#çcå̶.Z-JšýÜj~WÊŒg?Ì*¯k•W'çb¤’;ŸòjKýåFHã%†!qß¹ïÖ VKœ¶Í¹áºðyöü+ç-U™Ò^Cõ ¯q ˜ÜQ,Ç9àœñPy ‡8åBÔzûÔÚ¹û\j¹_tèNíUÍ«(†Rç®Â3šýƒÆK¾¯¯ø§ƒˆt¥Z\à â‚à0!”ƒ¿4ï´8rÃ$d ã¿?#ZÈQr>Vʨã·zi]ŠÁˆ`ߟë\î¦dµphÊ*“Õ1ÿiqˆðCáa‘É÷­=Z{K ›£½JÇ ¼†ó9À,9ì1ŸJõo„ß¼SñBLéP@b$,ólN~™5äWÄb9%õ©rÁ-\ž‡¡…¦êVŠ ½ï#Šv väp€ð=+ØtKµ¾ðÖD€íMÝp¯çþ5ë:'ìq¦Ú¬þ'ÔÒK–壳• “ŽYlUmkà•§‚t§†Öifù¾ìÔ{€=?<æÙ†>J/fúh~Ï•a«aâåUêÏ<ð'Ž[M¸&0º€Wç=#µ{χ¼gáßY›}jé!b˜Ì“€ öê}zøÇÅwïáýNþœÆñÈÜ é“ž?3\Wü%ÕíÊ"j—„>Nß=€'§©dRÆ~ö2²{ Ÿa°²Tçååcê»ëáá¯J|+®èú~‹ mY!‰Å©U .ìàg…Æzµy7Š¿hïxÆwm¿‹5ô8B—2ÊÄ2gfò©Ð–#ž¸®Å­ß†ô£cöÉ~ÐøiqeÝ‘’G~2?âì.d‘‘ŽÖ,°Þÿ­}Ž(¡‡J3Z6ûú!˜çuç4©ÉÇ¿’í}ϵ~üeð¹¾Ñ©iº‡Ä-Tòfœˆ­³ØbÀó܃Ü×ègìáñ“Æ? Ýmà;èkÑY›q=rF£¦+òá…íê^+iÚE¦«y´íKÄY#ŒdsµÈ_ÄúñÒ¿RdMKQºÒKë(3ÝÜmbEHÔ`c?^ÕóyŽX,J6ÒoV¾ë+$z¬±¸Fæ¯e¥îÿáÙöm˜Â¦yVG ghÀ«júDZ” ² pF# Ôzv©j!E3dàv<֢Ȯ2E}U?eˆ¥Ë{üî|œèÔæZ~Ì?~ n³—QÓ-d* ÐÁ1~OAœzv¯†¼anÚo‰ÌPÚ}Œï>gÛbŽßË?í3\æ¿_ol£½…£‘‚:ùoö™ý­¼]¡_McomkåHÉ0\x<ã¯OÖ¼LL%‚^òæ¦þõÿúl¿ëÍ8Ë–¯GÑúŸ86š¿‘ö¸ç¸y6ƒ§ÞC(<èÇ|<Óþ|.Ó´¸…ÐO:áÉmî78ëÉú×q¤ÞøgÆ7Z5êˆç´“iec‚ ú`~kÔ§ñ}¿‡th£1<éÏ­z¸j4éÚŽÏ_3‹2Çbquy1nî=4_‘ÚÚB¶1!]£ ãGj¥¨ ¿Ü—+MÙ_0Ó¸Ïùæ¹_ Úx£Å'Q¸¾{=<á–ÇΙãßò®žö8ÒnÎe+ÕÎr}8>ÄWRÿÒ¼$©q½öó† ê~¿ç§>w‰œÕ˜‡¡ŽãМ㞿­ Èb2¤ãoÝÝþx§ uv\npFÂç>Ÿ€¦&Z0¤ ÀãÉíøÿhf5€RÞÀ‡<ãó© )F-ÇúþŸ­F¡¥`pIÃãŽ)Cg»|¹ÃtÇLæ€îÔ¸Pq•l|ªpxãéRG)xÔ¸ÎOóÓÅ'”%.U ) ý܃ßðÿ=iÐ16ÈÁ°7É'oñ  £PKpISÇ©éÀ¥|³a÷þ€ÔO"ùcø—'9éžççùU¨Ú%1Æ›;e gA8W íÌlUqížÏJ÷ÏL†4ÀŠƒl`qßê?^u0—#¸;ñëþ}kÜüs X•FòÌg?Oþ¿jû|‘ûÓ~‡^/Fµ0üO3?ˆîr@!e{OóÞª²¡`îœ tûwÿõÒx‚d}z|’êó×ÿ­þ5 ±mÁB²äƒŒ¤ îŵí.´ØêÂéI/ërÙ$ Ø7wåG<ñëëíOd !%ƒp0xÓ˜•PYvŒƒŽHüI©š8âäí*¼à÷ôãÒ¸c+h·;“iêt?ÇâVÜ6 8ÇÐqÚ½_“ËÒ—`ÊŒð0\qË}+Ï~îo\å–E òp¯ø×wâi|½2@€±'$ž;Œö¯c™û×cʬ¿zîr bCäã+ÑzsÓŽ½ê®ó†@ÚzõÇcþƒåWü¤BçœúUbøXéSÈœ>ÆØA~U»vÞÇ$[R²=£àWÂwÇÚ¨º¶žÚÇKÚG›<Ÿ<ĪÏ\tà×¶|sýukÿ\MlmØ"€¯ ya~a÷ê=k‡ý†¯¥žæh®$f*¹íœgsîOçï_¤Z†›«áÛi£VY"uà ö÷¯Ä¸Ÿ0ÄVÍ*aðÕ%ÓŽ–m]Û[Û¡ú6_‹Yf”eN2Gï^)»zï¡øÿuû,x»á÷Š<5/‰t"ºF£sÅynâH¤RË×o# çœ{Wè—„~[ø{PÓ®m"kxa‡Ë‹ NëZß¼w¤x›YÕ|âKk[çݴV"íVPB¡@lá†Þ?úÕîšÏ‚m5M}>^ÀIF“@x²ܧ±àׯÃW2‡·S¿àïÙ–6yMwƒ«[êžéÅ­?®/-î5ý_V²™'[»ùæIGÝ*ÎN}=ûtÌøÃÇz–™ jz-´pÛZjŒ¢óh%¤ØÛ‚ƒÛ’Ç­{¯íû<[~Ï~(ƒIÓ®öŸy^¤‚//c³2 “õyà÷¯”>1kCB¶€Í¹T0=xçõü+ö,«-Ëg…¥[Ø®h-Þé­îÖï©ó¹ž7IÊ ³tçªÞÍ=¬ž©t9ýVX¬-ÖK똭aoº¹˜žø'üŠÁ¿ø™$,Öú\+dùžløiAÆ0vŽëžõáø§â®­/öU„×í’Ó8;TŒcŒ÷DZ¯±?dOØg]¹ø…ÿŽ|?æ—¹òåÛ,.|·ÆðÀô-Ǹºq\EC ì÷ÿÉŸ¢ÿ3çpÙ~'i%Ëæ{}ÿä|ßðÏPÔ5uÖ®/nhãm‚›Ÿqvãiÿ"xLý—hï ]ë^Ó®¼â­r'–mc6Ö±ÄÐ.Ñݤò±RáÓ¡'о#þÎ_ ô/Ššo¼?¯@¾ñH–ëìv(Řãä‡2€Wär>[Š1pÍ#E«rG®©»7~öÙö>›)’ÀTTÝÛM»ÛG£Ñ|Oýƒÿg±á{«ïßFÈ̦ÛNSÆA¼r=1…ýêõïÚçâ+x;á¿ö=¤Æ-S_f¶B¹ÊÛ® íЃÃ*`{‘÷Mz·ƒ5Ïxƒ@·ºðÅÝ…æŽ2‘¶œÈbR:®…#<Ž¢¾ý­~7éž9øÁ}¥éWÓÉgá˜_KecKÑ4‚r öÀE$Ž|¿@ â£F8<*§ÖçÏâq3Ì1n¬úôò](ð/§ƒâ.« ä.°ÛÅF¾€¨cßœ“Ÿ^½Nê÷Iñ\¶÷7–PË26a™îC׃_6[먓ÝK>iã'’ÇgóÇÒ½gÀóÜÜZ!u•¾AçîxÁõ¬hÔ ©ÁÙ£gg£㟆úÕÔ7+¢jcTÓ¦ÛçØÞ¨WÚ¬€ã$àã ë^eã gBøy¢ÚG¤è0\kktÆí Æù! V8 —Ž ë^õ'tí>7DŸÎøWKt2û|ÛÇãè}+篎—pEãXõp‰5½æš!^K)a¹x8à~<×è9.{ˆ­QÑÄ»Ýhúž}\-8þò?3Ëõnç[7÷ºÔ—WóI<¬0NTàc€Àè1Ž•Íê÷ßÚ Ê¤ùI%Ë«7£0àgžý|·vž!·6eŠÚn*¬Â0ùÀ|Ù·aüê¬þm+#PShB\m;9l7QŸl~—ÓU¥:’¼u]INŽ~ÆÁ­,®‹(vu…ă§?0íþyⶬîgÃHˆC,׌‡w÷\uÏ·­X™,YfžEsm1„E‘ÀÈÇÅS/ö[&Hî,.™Ñ€;@9Æ:úõ®iEGDþò‹VÐÆñ ˆílЩ%làSŒ¤°Æ;gÿ=xÝFwy]ŽG9<}+¯Öˆk8”’Ãɶ\€99ÿë~5È]í•ÝÆps˾•á㶨Ýê‘KQTEŒ.Cd|Ädóýj¬Lr N쾕gQ;|²*äc$ñÓ9÷è*¬L<‰c”8Ü3Ûüþ•å^ÍXQk›bKÉŒ—DÙQT Èç9=úüThÓ¶ÒX Žx펴jN ~bÊ  ¹ù°:Ë3–r«"…Ã/ÊqóúWé˜JÖ µoÑh´ô>vºn¬»Ü ¨%Î9ëÇõ=(,©ÙnžüÓT±,Àü£…Êñ\~%´Fb¤pIàúç?‰¬êb)kwë§üÒ£)ÊÉjΓÁž¸ñ&·ioom$ÌÍ…1®~•÷§ÁŸ†ô=:Ñ´2Õ"ˆ¤hv²€0îp«åƒ6´ðn­nó[Ç92`¾9\Œ¿~œüø…eâ=2ËÊÛþ®0@`z¯?—ø×âœaŽr~Æ›÷:ï¹û¾Qy.ªt£:]¹+þ£ôOkö‘­·‹4F³¸éæÃµ”ŸÁj©ãiÓ2Åæ#Q´‚sž¸‡ê8ýzQ…@Ë€¥ÈñïøÒ,~kþC¸Ÿ™GO~?Ï5±™"¶1lºõFùFz~\tÿEÆæu<<`ô?Ê•ãÚZL‚Ä•‡äúôúÿúé­ }ÛTÏmÇðéù÷ üÔA'# N~±@—+ûÄÜN>`;Œúþ¿äШÊI1`NHÆO½ÌJrA 2~Ÿó ”ó ( ¾q‘Ž;ÒCv-£Û èçühÁ,/†Ë|¹ÏSŸ§¦?ÈLÄ8︎€:§XSqUbüéœW´x.D‡I²B@ÌJ2ëî:ñþGŒL©#¤†SŸ0ò+Øü)0Iµd?tg©ïÓŸóÚ¾×&ÓXìÆi;î«+bïzƒ¹à–ãã×54²+þRF 8Æ*;ùUµKFõ$Fxÿô»£b%·v8ÉëÛßÿ­]x»ª¶;0ŽÔ•Ë1º! ð 3ÏÖ­¤†d€Å:làgÛ æ¨ù§g,csÇ8ǰÿ<Õ¸ö2+FÀå€98*{çæ=+ IJ×:”­_Ãÿûän;ç9ç?È~õÚø ·ØïÚðsÕzóÿê®áŸÉâEË ë¼3Íu~*ºÝb2/<Ýp§¯õ¯MzLÛsÐæD¯º02P‚T“Φ}»×1ãyZ fWÜ¥Ãzw#Üôæ¶Ž2P6òxlö®wÆ×‘Zhݾc…Ç#w\{tk<\Ò¡>m4ô1¤Ÿ2i\ú+ö/×Ο㿠ä‰" 0ÆÜñÏåÏá_­"x¢ÐešB%BY‰è+ò§öÐc×µF¿¹B¦8 ýîs×Ö¿Rõ«o3ÁZœ Õ­¤Qõ*kñŒê“£™Ô—WN/çcëñUpøuæþë£óÊ/IeñËÆ7eÁ kª½Ì …Nßß9ž½;äWÜß¾<é_laÓî¦ò5èЙb“Iƒ÷—Ïãù?£øÑ4OÚcÄú}Äãc^ÜY–bOÌ’°¯=1_Dèó =rÎþ)<‰DŠêpTñÓ:WÁÐÅWËj&¶•®»Üýß5Èð\E€‚nÓ‚²’Õ¦–Ϻzh}9ûuü/|(—UÓ$Ž×\±šK—ÉÌe˜*c¦<ÇCÐð ~#üWñ[xƒVŠ& Ù†I (¹Y8â1ø{×î‡Æ_‹þñ?ÃÓ§hú”ws]ËãÏiš½þɯtÙ är<#b@#$à~òwŠG—F¼*EµºûÌ»]2ëQÔŒP@e!áÆrk*?.-9™dfÖã;Žì’ÞzâºXµ9®du­º"=Ü{œd<€@~RGðLvÉA42Ø¢æP-Žd_”€dÿ/ÿ]D£M$‘ª›l£ªœ¡Ü@-‚2…8út+–ö¨C…*nÏ|úÿ]tÚĪZR°“G‚‹ä?çÿ×\³©F;–?÷¡äqÖ¾s0ìt;´‘WXXå(‹•ÚØc··n>½ª•»·‘1µx%‡ãÇæ*ƨÈ U±·9ôX#$g~àÔýin–F»råTqÆ}HÍWVB¸À @Ú@Î?Ï•~GQŠLñ*ÆS¨äNd(s’T©zžsÇòúÕí&(î##¡;oóÍe™Ò5ØÄ³ž~•zÇý2 •Br¤Ž•Ï[0”éÉstvgµ“S‚ÆÁÉ]-NšÆ{¥U;cÁg#·ùükêŸÙsâ‡ü#ºÝ­…Ëȱ¦À¤ãz>Õò—‡ž)î#ÛË9ÎrqÏzît_2Âê+¨¤Ñ¾WÇ9Èúþ•üë™NS©*uçëЫL½¥=–‡íÃoìØÂèÙ 3õ"ºOx^-wK•îP9ϯµ|û/þÐÒ[Ïi§_H¨UÁßÇÍÇñQ_¡ñ$Ý’2:°oðÏ—U§^Á×ß¡ò9¦¦ ²ÅQØùšóÃßÙZ¥Î›t¡brUq;z÷ò·íYû-Éâ2ãYÒ^!r1æË­Æsßé_¦>7𠯈홂bQ’@È<{{W—ÛøN(¤“LÔ£ T ïðô5ã×Á×Ëk©CäϦ¡›ÑÌ(óOâ·¼¿SùÿÔ¬¤Òo%ŠUd8äŽ9=ýj=(3Ün,q¸›=?Çõ¯´¿ooÙŠÇÀĺþ‚“Lƒj–$#0ÿ#ÿ­Z¾Q·Œ;˜r{ž?ýBŒÓ©/aIž¶ ËiÚÍÛDÛJ•ãŒF¨„ü¨|EÖ>ËkåÂÄgϹ%cíÇÿµO¼¸]´IûͿø€<õïÖ¤·ñ¨ÐC”JÀùIÇלW Ʊø˜±'(ªõŸîï±ØMðzjjë-l f{g ¼d¯¦8ü rÓÃ2ø•þÁwä_õ¹ >èéÏN¸?NÕZ/êt_Î[´WɆbÌŸ–ïzæ5íjiõ#9Š8·ö€1ÀÏÖ»(ª·÷ÿCÃŬ?/îQôƒ5öŽ(ášh¤Ú‡"¿P=뻸±% †ñ ßÉuý:×É7Š—Oˆo»’WÆÂªN{~&»}â;²¤HîèyÝÏÿ¯­t¸ksËM6zäÿõ @×zgˆ¡Ó/Ù–C.÷`Ǩ8^ý£¯Æªv•OÖÃŒäñ^XJ &#*r=ý?AùWØÿmü;¨[<¯o<,@ù¶·œ£?þªùZŠÞ-Vè[xUÙUœÄdòV”dÚ³EO[H¦Û‘†Þ!sœã§n´…0ß¼'’Ƕy$ÿõ©êé4kòîàãï{~u’@ã %¶¦>ö‘ú×A‘"¸P̧kãÎOQþßJªÌ ²·ñqÓéøûÓFݱœ¶B`å‡Í‘üùïJèÉL¦~P­õí×½c‘X•Î=Àö&•‚ p1ž}rzw¦8$eqåó»úÓ“cD§åÜTñžŸLô  |³Â‚þ.?—?çÞörÿ0‘À?óÍŽ*rBäàŒ`zÔÖ¾Psrêyà(=è¼ñ.Žö7öóFæh^EÝ•Æ1ŽùéÞ½+ÃQ7öU¸´•wŒœ`sƒôÅfy"æ6ŠTF ¼€:~=ÏzÚÓíãŠÚ£'`@œtã¦Ó•~±õB¤ªÓÚ[¯3¢½äÓ8™üL®ŽO™TŽ8#OEËä ô?­FäÇu9'K–lííÈëÚœÈK (rOÿ/óšñqRýô’;ðÊÔ’lArÄÉŒv#õÎGZ¸²œd1è·ëU;°#ÆÐI,1úóO‘Dªã@ |}kŠê6r:Õ»ìu?QUÔJ¸8Ñä$…õÇ¿øñ]Wˆî£6*À3düÃ=zóéÒ¼ÆÖîKm;Ä%‹l89*ØÚ}®+OÂÒÉuà¸d”±›ŽæúÿŸjõUkòÒkxßò<š©¹IšH­!g8b>R‡rõç¹ÏÇÚs–Rp2¬ÇžFG…mÍL‚<Jý÷àôÒ±éçŸÒ¹éôýCÄÚ‡Û/¤ód$¨y@çäð=Mr~#ø­¢øEçÓôä{ýJÊY´hý·ÙàŸNƽ<©:U•JTùê-¿•^mzvwÓÄágJ´T)ËGwwßOé–ì¼+„‘Ù[À!´‰æ=°rI=ÎH?§jú7ö\µ·µÖa¸â†È»p-'îÛ§9#$µñ_Œ~%j3hQ[=îë»–# \*xŸiüøíªxT·Š[©’äü¤C´ŒãÒ½¼N毉iÊûy~ ÑXüö9Æ•°ô4MoØþ…ôJÛRÓ!’ÛjÆ Šs³Ðñ_Û7D´ñÂÍ?O½‰&·—Vˆ´r ©ÄS‘ßœ~8® öeý¤4Fð(Õ5íh9»hã†,{Ð$œd@ã¹éSþÕ?<5­øKHÓ´ë³=ã] ¼!CˆÂ:‘Ãg’ã·c^Í,\gC’nÓì|•\$©Vm+ǹñω?g]­Üè3 ˜0Ãû Œñÿë®2?Ù_ñ ¸úäzE°mÉ%¿œò ÎÐãhÇ¿zõ‹ÏCÒ§w@AÁ£ŒçµnxOâBê’Mj ïŒÛÏ>™öïëWõ ¹M\bô¶‡ à?Ù<»´Önå8iÚ,…äú±ÇlõëÔü©AsªÆŠëÃ}Î8úÿúëŒøÁã.XK+Ü\,xgnéZÞHìu˜/$d&V ªñ¸ã“úÿúêªâ'Y/i¯D(Æ1vއ¡øçÀ–Þ"Ñnàò"m…—Ï‚ÑäpÀ×ÂZî‹|ž$¼ÐæÔ¥½kXÚ#* °]»?Q·ù梌&"2…NZZoï›üc,Hâ£(+¾Æe•ÛiÓ‰$Ž6“´úÿ*ì,~$™½H ¿Ïïý>LÐÈCI·œƒ´ý2*F¹b¤‘ÜõÆ5ù†*„+KÞ÷¼õý,~GØÁ·àï®Ö{’=Þ,.ã¼µœ ~ñ¯ÐÙ‡ã¤z•½­¼ó.örgïµp9ùqàËkË‹…“°@SÓœuükÞ¼+&©àë˜ïà˜«& (èAã¦?Ïã_+^:僳[MS+­ŠÃóòÞ-u?h´M^RÎ9Õ² ðsš‹Zðì¢Ú«&s»oZøçà/í5òEi{3¬«±`€ÿû_­}sñ§Ãö–‚K­H¡#•ócÏOâ¯rŽgB½/cŠZ£òŒNOŠÂW½ Qò§í» jºg‡f¸›NþÙ³nQt˜/€02Häœ~X¯ÌÃg \³„oŸ˜É?çŠû»öÍý¥<®Ø]hú6’÷úÛÛ{<’,J gl¹Îãëã-KÉÙÔîÃ6 $Œ÷ÿ=ëZ8Ô©ng§õÿûÚ¸ª¸¬, H¯w}üÀf‘¥>kcv3‚3Ǿ?©ë÷„äyj£ž>oP}3ü멺·6Q$Q€Ò +dþ_§ã^qâæ¹´º1²IÂŒ úž½ÿÉ£ 7‹­«<ªÊ4)éÛ±—¨"’±ásË>;w8ïÞ²ž)¯ ÅÂçiNúcð­ 3Ikù2òT8ÜesœžõÐÛÃò¬¡$ÕnŒ)Ç^åCv¯¥uc†÷"¹¤xÂO2~Ú¤”)­îíeå«w9ÍOÂú…†˜oo-ü˜‚îS"ìÜOAïÉþuÈ—2Nv±dÝœdŽ;`ÿÑx§ÄúŒ†)ã6ÊNLÛÏ¿'õ¬Û(6dÈArw`&ñÔzt¯Gêò^²Iù7™C ü˜)9Eu}_—‘ ?”W;—#-€NFs×ò­K/˜ËAØ–mÄLc˜×ñ³E%†>e€?º}Å7hf.¤¤`nÆN{ð÷®£Ê=_Â?´-‡Ÿ£‹Éø-æ8ŽÛJò?ÏzôûÖ—6±GedšxŒýØ~§¸AŽ+ået,§ ç©ãž¿§ê+¯ðäRÍè#bÊ7|¹<µ.+qkk#Ñ~"xÖ-NÔ¡FÀù™ûçß½x-üÏ6£q½w&ö¼þ]ë´ñTw^CI#–E!¹' ~…pŒËæ’¹*\‚xÃg“ÃùÑ–Åɱ‘¦ð»”nÆA\úý:ÓÙFÄFÊœg-ê{ú»S•»ÁÉäq×Ûêi›÷:ìf`FÌ©ÈÇÓÖ¬á]Q¶g‡CØÈÿô®J§©ÇDãqÿ$Qåy¸'pWÀ ½þ=)¬TF äc$àôÇã@+”Váú†ÁëÿÖ©NÐâQæ1ûÜŽG¹éúT{¼¨¥qãÛ¸ÿ"©Ø6H$äqíÞ€%q’3¹†Üƒ¸¯9õý*ÔVR\ƲÇHÈm€çó[q|HÃ`“Ðv­eÛ ¸ëØzÐ\UÙéžÕžÿlR|ò!ÎâÝÜÇQÏæ+»²e’çq’§ãï^ä¶Ú¼è‰úŽq^Óá˳¨XFìá$+ƒsŒÏNø~­’c~»IÒ­«_‰éK’NÌã[DÔâžeŽÅäG“z±‘FF1ž~êãh:’ì°K™?ÛP}=y¯BXLn¢†%‰ÆxàsK˼–;‡C’G¾=±×ðÙˆÁFÅ5ó¿çcsÒ‡ºô^Ÿäp+á½M¦GRUÉbþ$ôàԑ蚬ˆPé²IR£éŸóü«¿ŠæEˆØ1‘¸ã=?¯åR5×—np$7pGÐÿOñ¯=Ð§Ö O_ó"5ê-Ûü?ÈòÝZÒmLÔà»­Mâùp‰,9é×Ö·<'äÃàûظÝy$ääü«?Å1Íâ}/RœDÓËdUÉêwzöµoC‚K YG:•}åö°ÃOuÿõŠóê¶±)[§õýjdÓ‘3Ë,¸ã8!¸ÏåÖ¹ß;.‡.á±¹¾îW¡ë[,wMˆ·˜_ðõÿ>µŒ<1¨·„$Ô$µu´'ï²1ÉüñŠ×)*åìVòª™Oá7.|#©}¦Íål©YÊàr?"kéx¾=k:²)‘#@UbÇ×éÐן}÷ئW1‚@ç×#õ¯AÓ|k©ëwZið›wo•¥PYúúñNõø.sB®'–]àÕr>Zöçï=:ÿZEÇã{Uœ†Q‚CHKN>nàÖÍ—ƒu/Þ$š›ºFªrÌC~É"±>è·piðO{#O3c¿¨ã'¯¹¯O°¼òð“Ïû×ÁO–2å‰úþ†©SŠi9>Ý ^%Ñí<ðóÄWVK‹ˆl'‘f†rB×Õù”’yÎùà3ò§Ðž¿¯ê+ôûâUœš·Ã}~Â2RK«G~xLŒkóǺ ñ4Ú<3¨¡™P ä¨'ŽÝM~Ã4$éU¬–—Jÿyù_ˆSŽŒU’çÿÛÈç#’W• ¡fÁ¸Æ3Óóüªh7´Œ0Bžý=yÿ™#Ó½ox.ʽ^Û̉JûÁé÷3žzr?ýuõͨ¦ÙøÜS”’Gc¬ø“Sð¿†ü0¶R<hw`[ŒŒä~+ùרü&ñcê1]_êWeØ®T»dÝsŒWˆxîýÍí…“£D¶và…ÉcÎqíӊÃV¼†H®d‰9œr}=¿ZóhÐJ\Ïww™îc±˜—~T¢­æ’Oñ>‹Õ~&¯ÛŒ‘ËÙÂõÃ׿è}« øIñi‡‹¥†á#ˆÁ9ù†Oåßüñ_'MªJÛK;H‹#ÏŸ¦8õ¢b{w‘£vYxÌŠØ#==«¡á–ºžR®Óò>³ø÷ñâÅõDŠ aºÔm1"@ŠÁQŠ >qÏ=*ì>k÷þ/ÐWU½¸yNKIŒ»ÏSî=z×áÅÄÁMï+®Ç,OAמàWØ?³ÿÃKÿ x^ëWÔõ)ö&Ý+?»ÜÈ£sœà‘ÏþsÔVu)FùzšÓ«*“6¾0|Iÿ„‘ÓG·¸éöâP°§ãî‘ßë^cƒÿµ-£_µ›xdD_Þ0>þ£J·¬=¤òM“u<ò]Hϼ>Ì󒃧S×Ò³5MNKIíWûZmÑáhöÿ À;vóƒÖ¿VÂà¨ÑÂ*\·µµµ¾ýO"µYT“ÈÍ•åѵ ­9Õ%–C(G#9úSôMOû:+¼afX¡EIm§ôéíW|g¯Ã¨Å§ßG¦˜%…d ,lpà¶yã‚2߆+•Ô.ÂZ=Ôrm3´jlqƒÔ~Cß&¾^§†J3Ú?§cʃ”a*RV¹ZïPqĺi$w¨89Æ?¾ãÒùeœ6\…ÎìþU³ðÇI“Uñ8,¤1rÉ•üGâ9÷§]é²Á¯,M·K–WŒc©$“ž8à~µ¬\ᇞ:[¿u|¿à™ÇuEÿ ø'ƒ>'‰5=:Kœ‹vón™x c¯lö?­ruÕÕõñ§iȰèÖ»µD<6Uw=AÝ^ã?Aá>Í•¯ï#òÀC†\¦ cžŸ×Šðvyæi9È%†=뺽hàðqÀÒøå¬ß®¶þ»–óâj¿Ozµ\ò¼G_¯¯ò©üÁvð¹á³ŒcÛùv®Õ†ç¤¦ùuõÿ3Ô·B‹·–y'æ<®ÏÏõ®÷Á¶·ZlŒ2eÆA•?•q–Á°B Œ±ÀQ‚W㎜æ·|1ªA¦Ë¶â6pëÃc‘Î3ÓÒºp~×SÚÓå½»9~_ƒ:°Õ©ûXª—KÖߎ¥yíšÚbŽy8Á#¯á‘Í-²+8`H>üU½nÕþÐ$íÆ ú“Tìn¤¶¼Žc˳Ԁ0+óìÂUfç>É8ýÉê~±…|²Šû-®ŽZwÐë|5ªj:l©%ªN¡LçžG§O¯­vIñÇÄVû|Ë-9»aâcÇàÔžøÅ§éVñ¤Þ ƒR °#?O,ö­-Gö…Ó^Ñ’…Ú$œmšâäÇNƟξ-ÓY·*?Šÿ3õ¯¬áðôX‡oð»~¹^Ïâì÷²)6öÖ³uÝo½yç¶Nzqÿê©onuÆÇí×ä œwOµyÞ½ñKPÖ$v]3IÓC|ÁlôèaeéüAvõîiš‹®®îc‰žiH\3'o<Ö¯V”\á/‰­‚ÆÕT¡7)½4‹Wg_m¡L· ²ÇÎ̇#¿ÿ¯ñ®‚=šu‹ÌcÏËÊžBsD~!±ÓìciÄnØ—=9ëß?ýzã<[ã(ïádŠD‡ƒµ7uã‡Ò¸)B¾.v·æx˜Ü:Ë?£ìˉñûºäzŽ™p¶×j§ñ‰t!Œu­ik¿4?ébãÄp@ú° ··1ƒÏPvÈt®ÁŽ‹s«Íý¸gž‘öÎ{äJ£qáôºÖÙ$BHuy·ZúÚY};{)&­Õ~GÆlUÃÔ•z*.úY«Ûñ: hzg‹õï²jWÒXX”>XŠ"Äþ@ãå[W~𖙬O¦C%ÕÅâ¨1Ï;ìÝ•q´zúö¯Kø_ð«Bñ?‡ä™uE]RÕ—ìVû¤C³Œàœá‡LŠñŸ‰ §ø‚êÚû[¾ƒR¶UÚn-Z6|¨!HÜHàû×l!jt›V,þÛaQí¶;³Éê=8®tÀ0-³‘ÛüôçÞ—qFC€¤p;÷Î?  KeÉÆÌþ¿éÍZVظªánãØ-÷²=}¿Ï¥ ²I,á¹8çñ¦´ƒ´Œ`=é]Lx @8<°šb$ ¶œÏPÜ€G¦=÷’àòúOåŠDcíµsòIíœfƒ–Œ2ü¸ù¶c©üG4^OºÙ;@ày^ßçéÍI´¿–… ŽAàgÚ’R©¹°Ä猯#Û¯hÜ<”2z?,qþzМùÛFbw:úãðÍi[Gpð©HZe9ù÷ã<ÕʱV ¼’KsŽ9ݪҼ›G8öS‘HkCUKJÓ£ wüàuˆ¯QÒ^Ke…Ó(@Á >C×ð=s\O†â¶ºñŸÉÄM:䞣æƒ#üú×­ßæò$+áLf¾Ç'rŒ%(ïs¾¼fšqjÎö BÑ%€å 9Éä{{æüW¤µÜ‰wȨ2®CÏ óÅsÚ§w¢w"oÒ¥‘£•›F{69''Þ%Ú]ÚïF e=˜qé_mKÆÑq—»/'¯ªò;cM_–hó¡mq×í2‹órqè1ž)Éi4Ñnn x27áóéKu4ž{ £q Î…½sA»!UW<ôïÓ¥|\± ÜÞýü}•Ñ'Ãõh$¾ä!FVíËÃ5«®ÈVÜ*àœ)$ uÏõþµ›à˘ÍåÑÞÌ \Çc§ëŠé¤ÒàÕ5k[v «4Y— »‘žØÏ5ìIsÂ2ëdy“v“PØåôn=ò “l—J¤·–Ã9$zÖ·ÅŠöÞ!ðlZeµ¤°¼´îPh3»éÛù×K¯ü6êÆÊô—o»ªnzäØ×ˆüH°¹Ðõ¡§Ü¦€pq’qÐþX®LuHÒÃJO}‹Ã)©ùý³ÝOË郎ÎxãÜ~uî?¼&«qç¶Ï.2xÁÁþ†¼»Âš1¾(áL–N0}kèÍ/F½²Ñ!²°´ó%š_Þ»¸]«Æ[œvò¯ÀsœRoÙ&Hp^P°ô*¤}é-=ò-I- hày™×Õr‘Œ`gƒþÓèÖÖDºFÁ$ïbOnçé\·‡ôË}%Úªnß3$ç÷Ç\×o£@d”O#mQ’ŠG8õ?ç½|[´‘ú½orž¦Ž¥¦Kªè×–1eš&Áb}:zöÅ~lü`Éø“­³„:#)‚#Q·ê.Õúw¦·Ùdy[ë×Óù¡ñÉøÃãT,Uµg+pAsÇëÖ¾û†±N0©…èí/»OÔüÄL:–Ž'´¹~ôßèpr‚Äcs1<íäg>Ÿ‰ÅwßtøHüice!ey¸!x;c'××üŠâ#u9ç Ž¹éøæ½Ëöoðì†ÓRÕ#B·ÖSFÑsŽ8=¸ÏåøWÔcj*XyÉöüÏÈrœ4±XêT⺧òZ˜<<úf«jññ!ŸÑHÀ?Ÿÿª¼¨1;² ÛÏ$àñùv?¥}%ûCèBâ9ä[–¸wþ"¥w6F^µó[ÈXìêßÃóc·_nµÉ•TS¨ßXÿ™éq%KêtšOîV²±*&ÉPÃ8'ƒÓˆ¨„Ò·qÊ•ùóÇ\~T²3  ཎ8“õíëSØÙË{´1—’bªnÓŸlôä×°|©×ü)ð«x«Ä¼„ {lM$¬Jç 8üñéü«ê}Åú„ºtÚ5ÕŒ»rªŒËËü<ðt^ðí­¸LÌùi¥À$Äþ€ã¿zëô)tèuhgÕ#óm¼²»CX©=xÉþc>˜ÐK‰…7µ×æv´èÒr[Øñ?6“¦Ëþy$¥LÊþ_\Œ}þyÎkOÅ3¢É)óC©$€w>¼nµÝëööº¤2jH–v±?Ùb‚Ĥ œg¯R}kÏ5evšå E¿jËçøzcŸÏÛÞ¾÷ FjT’‹ÛK¿Âú*~ÏYÊïÏ¡ÐC⫟ìÉlЭż¨Y|±Ì|çùÖ,—A­™qæÄÿ+/BNþ¾Þµ£àß ^_’íòißv[œŒ ÇL“Û5¡â]gÃÚ‹=2Ê-FFÊÍupŽ6r: óøVUðR«GÛÕj ­ú¾ú[3ޤáí9!õÓ§Ìõ¿„\º?‚5]Nçjùë±sÃ0×‘Ó cŸÂ¼òÿP†?ÍvÎvè dòxéžõkáÏ-㺻³Ôçò즵ÙÕ;rÇCׯzäõmf;Eå~À™’G»ÛýßιñuiU†•7eÞýôµÿ?CŧB¤kÔæ_wÆ~׬ìíê±ü…y/ÂO-ž›nÊ ³“ǯÿZ½žÒêæöðzã#¯Ã4rgïxùJœ£ìÞ©/âÿÙwÁ:ìò]Okr“¶ç.nåfb}w1¯ñwÂÁRôØçîÚÍ4…¸Á<œÿœWØ—WbF €AÝϵx_Åí<Û[I¼–mØž þuOV)G™Ûµô7ʨáê×u'º–ÞÊÿ}®|›ã9Õòx°0ÿ0Àõ®;Qó<¸Š•WÎ3ôöïõ®ŸÅR³Ü‘Ç8ãc5Ëêr4P„]˜Œ*ã=À¯Òr˜Ú‚õ?ñª©›5Ù/Í’}’êîÔ<r'!÷c=½§O­ˆÝnÕÎQþW$‚3ê=ªšë­eˆ²ù‡î°ê~žùïüê¼±½ìfia,ÀýøùvÞVH“ “Ëž÷ý r׌—R±Ä ÷Û''Îzõ¸Ås¨¾ndjÚJÈäËy™*¦I güsý(ùv2…QŽb@$õÇ>¿çÑp#-•œÿµÞç%X ݸ çŸ_ËŠè2 #0à´ŠÊ2ÊòúûÒä™Ib 9ÉúcÒ™É\á€É §¯qž£­(f%؆gÉQ‚ ëóšzÄÁ׸Á9^GNõçÖš$‘Bû•øÜsÎGz0ÜÀ0 IëØvOjFyR<ª aøãý¡þ}(6!O”uä㯠4»7ƒ‡ ¤çnqÆ3Éõì PC1+“×¾?Ï­K+2¨TpÍ÷‰Àúûwü¨FcFÊxàåyëéŸÀUÔ·. ™FO÷ŽòªŸ,iòÚÉÉ?Ϩ?Ÿµ\C•bV§ Òe#F D—¶åsþ´oëžç¯OC^«§ê3Cl%ŠS¼F ßÛÿ¯^á¡k.±h·1«Å½IÉ#צÜi6²Bd‹"1ò Æ3Æ1Û__•%É'æt×,¹“+x2Á/ü1-¼ê²Ã+¸`G,r{Uôûø´{‹5æg7,bC÷G@>•wÁRgAŒÄ§kÀ*;ßó®C[qý¹~Œ7#d8Îa_Gˆ©<= uVèöj>]VäËh¥Ã«y@çœäcØt¨ü¦K€¼ØÔc$`ñê*¨¹m¥#Ú£¯ÍÈôäƒþzÔ«p žY är'žÿ•|«q©w5©È¥t7|¸ Æx‚²•9Ûß‘þÖ›S—N»Šâ"HÈ)»žsœóôWÁ7QJó&?taHã«~U·?‡­õbÞÈL`2UÂnÚOùÿžÿD—»m¡ç8óM¥ÜܵøÝª$L÷š}½ÎŽG(@Éã¡O¥xg‰OÏý vÚK„`¡zŒŒzát°–p¤bBÉîÀ'òük¬ÒgóGÈqÌ{JóïtzuÓœ–öé_ȱ3Îã§\¥~xþѺCé–ý¤t'—Ã+«Yõ„%&eîl$“LcŸþµ|†Ÿ»s±ÀÏËÀÇÏ5èZ·ÇokºÆ‘y}ŵÂX­º!Sœ žzWŸ‹* ü€¡ˆÇáß·çS•áka)Ê­¿B³üË™×\:i%×þŒ?'rÿ"8ì{õ¾µìüå±Õî`,Ä%d ‘Ã>ÇŒzä>x5õú–_Eb&¥*õ²};ßô¹òXŒG²‡*cüa¤Ù>ËS¹3‡‚$ULîÈ%rNO©=‡$’{‰œ†IÛ…“ìïÓÿ­ÞªÛùW4÷3É<Ä/Œî8?\ëÒ±ÌsŠ2^ϵ¯þ[˜ÐÃT¥QܹÁŠeÞåFÀÀŽ1žØüZè ±Ž{d…g ·›YccsƧjå,h¯¸¬c ·È玂·G¹¶¶MWN¸ibU&lÍœõÏR1~¾•ä厔ªIÖÓí{¯;uô:1MÕÅÙùìÍŸX˜/äŽYc€ÊAr<µrOEÉëéô¦ë:·öGˆ®b¹‰gµp¸È‘Û?Ë5Ÿ¥j–ƒÍi,÷‚G™ûÓ}G8õ8•rçUÓnnäkËyžQ‡™õ“Ãw¯]J8zo ¤Ö©ëfŸËäÎ:mΧ4ã~ŒæüA¥[Mt‰s ì¬>XÎãò°üºóÍ`<™Á—1€~e#¦;‘]µ»Jc8¸µ› ªÀ“Áç­b5ôWjɵ„ª21ÎñÏlõúWÎU…8×j²qî—é­¬{tÛµÅh“$ÊpßÄqÇãïJälUÙœ(;s×é‘ùÕ/0(!—U':>W?ãêp§™Á­ÜS{15cê!NÞ-ìݹé]ïŸê>× û&ž×öx"[v€ÈAì>¤×—ÞÊ>Öü„°ztç ÷í]N‰­Ou§ùv÷ or­ò´2yoŽç ƒÛùö¯jª”ah+¿3óL/%Z÷›¶ïOËæ{w‰üSà¿^ .4§(UùMŒzåvƒ€}ûWÏúÕ–Û†–ßËH3W¿5¦É ”­q)wv?4ŒXç¯'Üñ×½z'Ãñ¢x«Ãš–š-4Ù&HÙãk§òebs‚„œÕÅR£ÂÃÚ´Ú[ —Öª{%dß}ÏžEkÊIÏÍÉêP=jh .UJ‘ÏË“÷»ýOoÒ®iÖ:¥ïHff*„.àO½ÿÎ*½Ø¹°¸’ÞLÆQº€0Þ„{cýjõ9•ìy-+ô#1G ùrF7Î[Œ~;žÜÕÍÃ:Ž».ÛH”«ËIœϦñ¬¾ €1ŒrO^˜¯Wøm¥J)ÍBäŒÜ{ǽvW%ngX|¾·u{É-g…ˆËA)f¦GãWŸeGûJ·Í#IÎqž0?½Uã[[4Š563òž}¿>¾¿ž,ú$¾ ŽXšxbLn-)àsþ¾?úÕÉí]îÝ‘Ñì×D|ìÌȬ§ä±ã1B²”Ê,ƒ€Cgž¿ç½Kwkö;™-‘¼Ò­Œƒ÷ºsÏáM¬>VóCž¸ŸçÖ»Nv¬ì$k²ã•bBIëÿëþ”©ûÙÜ›°Jò;cØgŠjˆ®ã-Ç ÏôÍ “)m¼uù²?Ïë@‰-˜à’ÙÀ~F;ŸJA.ÒümÉá¹8íøÒ ØUá‡-Áÿëÿž´ØÔHHO1Èùð­›<‘@ q»hÆàÜåHõ=9ö©1± ¥X1Æ0O¨¦’GÏÀaÎâ>ooÒ¥Îé:‡ùI Žpé×·¯Ö€ÌcÏÍ“Ÿ¼9ï×ó«ñ‡dq ô%Wÿ‰5!0!ÆœŒŽFr ÿëÖ€W˜‰1r1šW±q5­­™õ `ñºyn È8=ý¸ߤî,Ì@í.€Cê0G8⺠ï ÚÏy¢"X„JÆTXÞ:çôöâ³îE“ÛÊЕˆAß“é_¢SËå€r…ï±­zn2¹¡à¨Šh6û†9!¸Î?Cú×'©º>©r ïS‚zž8ü«»ð„*<-§ºÅ•½;Öù³tðÔþG«ZvŠ'Úpè®Ny©=ÈÍA-« LùpA^EWWÛ…GÁÿhã=¿®y§E¨JÊ7mãŒ>+äyÒzhÎnhË} ÏJÖétò²Ã þ<ŽÝ*Ýö½s§ßEuo(Š@¸NpG=*·„.Òcs$ˆŠ£ïÇsŸ®kfßÄ:Ì6‹8Œ<`‡Ûœr3Çãý+êšN’¶»sW• sþ4ñþ«¯iöº}ûÅ, œá8ãÓÝJãtàd½‡ø[zœÈõé×üñ]Ä]oxû=§IV4ó Ú bqÇáŸÆ±]AâqRQ„{ÿZ˜¾ ÒÛ6òU2w`Œô*ø{öÇOÅë¶R  vqû¸ñŸÇù×êÄ?†zwà qoâ]2úÕ0fåX猜‚Þ^ã• ädä`_™Ÿ¶å¾š|u¦êV7°Þ›ØäiV7V*E´ñê~‚¾Ÿ(¤èf„–ºþLüˆó Y®E‹ÄЕãh÷_òòê|Ýq‡mˆß"6 <íü¿®*«"Œ€1ØôÿK¸€p¹vlc€G§Nô¯Î‡Í÷UW“_¥ŸÎ#£˜²”ù™I'Óòíþy«ºvž×2¬0.é1–L\_J«8v]¤>Ü|½¿ýUÖxÆ«VF*ž:tÇ#ÿ¯S'eq¥wcr;³àé7±¦øá™‹6w“Çùú×¢X|t¹ÔÞ$Ó|5qy9#æàñÓ¾è‹H±¼(/¬¡”¦ULÑ©ãÛ=tz]…¶”`‚8NÐUa@ víþx®8É.evwEI]EÙzG‰|K~Ë£Øé„ƒòK+Iûç9éžµ·¦ßëZ”í¢¶?Ùÿ2•·W Iê[øVNšòy¡_¡#9É&µt‰ÚãQŠ0ûm×øK}}Oë™»éctµÔù×ÅÖQÙÜÞÁd˜'x6¹ä®ì>¿Ò°$Ö&:*ÚLÈ-ÕÌ‚$äy?Zìþ2Æö~3Ô!€$JϼA$éøþ5æ·«’Q™~^ƒÿ×ë_UƒÄ×§IºmÛ_O™ó³ÃÓ»RÖÌ#Ô¾Íe$[3c~n§ßüûTîÅlâùHÉnsë€r)Ö6)5˜Â/œçj—^˜ïíßó¦Þ¹Šáâëx]Ár[ëïÛÖ¸o)o±Ñ¸—®‚уãy)û°xÆÜòç^•ðƒÅO¤Ý[„Y!“pa ä| ×œÃ`.â啹9ôééW¼3}-¤±•|J³œÀŽ§Þ½ ."®ª­ ¿ÌçÄÓUaÊÍùZwŠînSy¶»wr1žäÿQþsX÷L™*Tž8RNOzÿœÔÞ0¼šKˆK³;œàާî}Hüª”eŒ@:…pÓŽO>¿JÂ¥_iZSîkB6ŠLf®­‹µ»({)[§8öþ^µ¥¦,*òÚ:Íf<ýåÈàóÜVs”ŽGŒ ¾W9Æ3Ð~¿]Šv´“r9xˆùÓ§?¡âjÜ9j–Þ^†®=bTýãI¿ÌÎÖî8>ÙüªIHYP Œ pÈújg åî giLƒÿÖãô©V4(xÑIo¡cúVÿUæÑ4%&Ù{I‹eºü»qÉÉÎÓ—n¥ÎIòN??¯­Â¢Ú×bã`méÒ©ÊæEwÀ@??ν Ú_UÂÓ§¯SíéÒöXXÇ« H{Áç§Lþuè?ä6ßt׈ð3éþIüë…·`>V#$œ.yéùW¤|ÒdÕ<]Dbë·îÝyç_JüÛ2¨–w}¬á|#yÛgÀýð¯ötaX3m8?z¿yq¾RÎB€:×à{ í­#&F8“õúÖÞ«pÑBÀ’IÉê+óÎf¢~¹^„~µ.^§'ñZ?f’4‚«ÎqÓ­|ñ S[­RK8°ò¤§;I$žãÕïuó§é÷r3s±öç¦p8ÅygÇòx«[]Fî2ÑÈìøuÏ»ä‘SFI7VGØÑ§ì((-%øŸoö9 ³bÃ(:ŒÿÖ¯+Ö¯ü›xÔ/úÕ+´œóÓóŠú ö¡ðÄ:‹4öI‚¤±“° œ‚úß•|ׯ9›Q|¸m£åäàLzðE~“‘ÚXE/62xƒQË7á½5fcM‰7ºdG~x©ûƒ+ ä0Ï\ô58,ª1ó¹ëÐ=9§¨ù6¬j'Œv#ü÷¯£?-ˆ‰IŒ`_ñ¨|•R¥²G'“Æ?óüªy¤Äh €>d$óÈãÒ™*É'å†\àöàq‘@ #ºäbzçœuéô¤k†”¨gb·6}3ôÎÿ^‘Èä(;}r8÷þ]ÿ5”ÎÒpAÁþ_•MmÉ*íRpªsÕ«×|ky£è~lóÇ8ã½yLJ¬”Þ)Ê•î8mvGgf,H#ž9¬j»+"à®Íèõ9<°WPpóúþ]©·WQ_é’yD£ nÚÃ×ÔûVAIÞAæÄ › Óïøçó­7ŒLhpP¼GøW#‚Z³dì|û|¢[©‰B ’IÎyÿÖ«mØä NNIã2ϵZ½‘RæP?vIÜH_—èÇÿ×P+!=Û$òNn¿É¯Dæ̪AF “·ïûõ¤8ê0JòsœíþqÞ¢ÜpÀØü­‚iÑ€%#{.Ó…9ÀÏ¿ëÿÖ £‘Œ…Û÷Op{ýhtŽ2ÝÄ`œqø¯QQ‚Ž›sÓêp3õ§lóØ•÷ûßøÐZCL|§»gŒgéïÛÖžù% !€EëÓ±¦ Ë\pW¡çÓñ§¶âFp:=O'ÿ­@ÆÖŒÆ8\d¯PNFjÌ®ÌùÀ<ª=>µYX«üÊBã½O¡çвm„¤±ó9>Ÿýj ºŸGØHˆ,HîôüÿÏé\÷Št¯²Á=Ô/å¦p8ÃqüëRÝ‘QpTmÁ ì ;ñVåArŒŒ‹$%GÜÈãúsÏaÀ¯ÚªAV¦é³è*ÑuÊþò§†'TðåšîÌa>BØÉ<õçŽ;æ¸NxŸU¼ô3IÐŒŽMz µ¬fŸäÂáÄ`íÜÙ$g=‡¿é^U¨È¿Ú3— KHìBŽ1»“ú×ÍgRp¥NÛüŽzÿº„R.H Ë]®FHfèsìj mئ7Œ‚©üǽSRcónäU9½?Ò¤ŽñÄ`#Ç?/·¿ÿ^¾>ú«œ<ÊZXÛÐU ¶˜p&Ý’[ÿëÔ©¨\Ùê)%™hæŒpSÎAôæ¢ð¾§3³«Œ}ß”c?ŸÿZº¯ hš_ŠüPö—… ƒÊÈdÂᲡzôü«é âà’ÛCŽÎRÐóÏê—¾°ÓÝÈÒϰÛT=†;T4‚ÛPƒcCÀŒ÷ï×þ½m|Iðí¯†¼YqclìШ;Kp3Øw•`Ø’%Œîò !r5ùöd›©R,û,±Êž&”žé¯ÐûáMñ¸ðÝ»´»dP}»à~5ÓjúÈÓmÙç‘Q@ÏÌx§§ùÍy‡Á­OÉП-¸Œägœzût®[â—Ä´‹6ñ2± ¶Óžøï_¼4ª×tà®îZËK †öõ]¢—SÖt¯èöúÅ´·Ó(É»Ë ’Àsž>‚½Æ¿¶&§m¡G x›G³O“í.ˆY‡Rp'©<×Äþ¾ŸY¿{Û’@Rvzç¿ùÿ ìáfbª¿Êz·Ôs]•0 .Võ?3Í3ZyÓŒâ¯N;_óÿ#[ZÕîµá,÷÷R_ÜH9iî<çü:ð‰šiW£àfmŠI!G^þƾÑü ®k±™¬´«‹¸ãbÈLŽ:ŒuèGç^añwA¹µÓïbº·–ÒxUÁIÁV÷ú~¿JõrªêxÅlô>;ŠÄagÓ_»SÂ!F%p£¼c¯>ý¨rò  Ã8ÎÒýiªY@fXœdÐúõ©ÎG?w'©ë_¢Ÿ!PãvÞ˜å†0qü±ÿê®Çáê†ÔK`ÛrIääÇ­rV*ŽÛe;€þêõÔxM”;*¾¤·<^*‰«Å¢¢ìî{.¢Ë-²NÆ$s»ôõÿõúU.þGLíå¼xÀûÀqœñÇç5‡£ê1M•# ¤qŒÓµl…‚'àw8ǯ·樫ٞ’]Q×Ú:YIRWŒÿŸ¥mxec]GäBÌÁÊ0:äÿžÕÌiS pä3näcþ·5×øwQkk*vHùyõž¿áY{ÉjV›³Ä>=[K‹&”¦íÑ8Ï<`wçåpiSjд1Ú4¡rÄ'ÌOÐõï_€¿¸·ˆå»º–\ËŽ{W•jz<þu;h¶àÁãÐcéþ{}Þå—©ÅÞ ûÝÕ÷K¿Cå±u¹q2†ÒéØÂÓ T™ePÝ[iRpÙÇ$ý=ý+*ç}Åë2:—ó>ùÆ:öqì=ÇJëõk}ZÐx‚ÙVR.¢\mVé=óëëX·2i®Ö¬"¸A!çÁpúóQW(«ó¥Ó½®Ÿõ±¼q q³NýGé±Ç,.²¦6Œ³g¥U²½x/ÑQTD¹º ¯9üÇù9­wm7ìþ]Œ­çpêN=ºqÓé\÷îÍÄm´ä®pb§ÁYï³¹¬m+Ý?™©â©–W±d>`á¶÷çÿÔ>™ª3»š$eŸÔ“W¯nb¸6Ë$mµ1ŸÅÀäþÖ«Já¥Át)cÈÏOÏ×üŠã•¹®)Ç“CÔ1ÜB²ï<·ð•>ÙœÀ3+zã'Ÿj†\og%|H9'ñŸòj[GÚ@aŽà“‚Oá×ÓùP·4õ-. ,QÎ3¸7#ùv©íb\ªàs´c8ÿ>• !hù~sÇÓüþy«¶H%._çÆ=Oÿ¯5íÒ\ÒW+JUkF ©fiYcn^pGR*Èc¼¶=øëNi÷ æp(ñ1ÓޘȾÀ_8úús_=ÄŸ‘¯×2Šjž š‹Ý_ï?”øÒ´êçuÔ´å|«Ñ-?̨cfÒqÆIQœ÷ÿ ‘%ûª8S‚¸\ç¿JG"b¤¸Q׌Ÿåøt¢ <–ÉõÀì +Gœ²Ã´£ž=úÓcß u|Œrvœ½¾•#æ ÇP3ŒŸ—ê?:¿– Øä m*N>¾Ý(ä).Xm îÉëŸ^ý)#.¦DG dõúöüªi—b6ö›²2¸'®:Š[xáÕb;£<Ÿ˜×üûÐׇ.¢·t36ÀxȽ;÷¯TÒ¯ô[¨U,PÀ9úŸÖ¸- áÝÖ©{ƒì ±+"‚?1ï[°|1‚É’Sq0|d“ qÈá!ïïXÏ–úšE4®‘Ô\øŸD[fƒÍÚÁvŒAã“NƒR·½ÒÌq\u眃׶>„ÿI£é°Xy`$ª£–^O¡oóÞ¯Onï§Ó;1s¹# §x9¤ÊGÐvˆ+Ž3Û<úwÇøUÕR”±ò îútíÆ+ú’êö¥ÈÔP¨Qßõ¾½j ²;<7E7ä8]٠߯j¬× 2 ù‰'Oz…[2}Ï•€ o¯CXT©N•4’üIW•™W]º¹¿¿yçv¸™Æ ;îlgŸ§J­l¸d#’ç®@àÿ*~ ^Iz»#ÓçP¬ÃlnĢ¡ý:~ð¸åÍZzõ>¯>^Iv±èÖ^=è „l|ß89ÏLWkz”·@Êù‘å-’O^È ÌfÚY²»xÏCÛü+*òé§»„$.ÝÇùÿ>Õâ`ð4èÉÎÚ³ê8‡ˆëæ£AiÓ¿™ë>|XÚ„î`6Npr3ëȯ²¿fÙâj¶Ú–²‹%±Ë}šX‰Só`þUñ·ÀÄš¬1LùŽ9A;—?Q× Á¯ÔïÙwT¶x£¶‹jб ùï_#šÅÃÕ÷g¡ƒÄß.Œáºä}9ᇧ$6še¤J:ˆà “Ç¥x¿í·ðGÁþ&ýþ!ê·Ÿ­¥èwº…µè·T’(ZAó;ëøúOL`Ö¼WÏ?·ÏŒ­¼#û-üA’åœ Ý.m=vu-8òTuäý~•ô_V¡FŠq‚éê~{EzµÝæþþ‡àÁä•ÞÅT1€rG§ãÓ5ÇÇ æ6ïáb3N?O4k"ƒ» ѼcŸÿU1™OÍaÎ]±ÉõçäWÔž)*IöVVp@Ã`·Ö»Í,Þ–Þò=„…ÛÂOã\-¥Œ³Á;#ò‘€:Jˆ;"³FJóÃzÛéŸniJ-¤ÆšLö¸ZÖuä(Ê8&LŸSŸñé[‘x£F†ÚºÔmÃ…P¡¦=2zû×ÎÛ·aw6Ý¡¸ôÀ—_Μœ¹92 ƒü»û×; ŸS¡V¶ÈúZßâ‡l‘%űRv„I7gߌú{Ö¾Ÿñ‡Oû*=³›rÌ«;þì6ÕÉ+œzÿ…|¢åNH0Cwÿ?Ö½æÏA[…Pݼj$UYÞw2‚?ñïÈj¨ÒŠœyõ_q2«QÅòhÑãˆCÆ:µ¨KSkö6fyD»™òG=>éüëÄ:߉tØaH̾L‚B·3(gŽ{ãðâ“J»°…nšæ)bUr0Aã’=¿È¬!«Kk«`nŠ0J…Ç#铞ÿJ÷"½„m–„ž±‹Ûï<¹^¬ï%vº¿øÿ…¯ÞÖøFÉæZ¹+%³+ñß<Æ£ñ¤6“•€‡µ¸Ï— @DYìG'¿·JQµ–hïáD‰ÕÈ•Så qÔŒûÒêRUs#<¨láO¨ôêkÒ“T°î“w[ÆK¢v_wF»™r¹ÔS^bË·Ž6~cb<ÁzzwÏ5JáDS"¡Ûr ü§žý{öüjPÕ“ÏÜêwm`9ü?úôÙȘ£¼6žs’G?çµx3—:W=–èh@¨#$`ôúÿž)×”–É'¾~hFÛ+ A‚Ùàžœãúÿõ¨™JB>PaŒ…9ÏƲ’V²4VF+ @¿ ff䃟¦?_ÌRÂí—~ {¿¯üóP—bUXÛò¨lç<~}ªXŽÝÄ®d ñŽzöãê .ÆÛàåy<|¤{œ}{Ö­´@Æå~nxœuíëYJrÁnÁ}³õÿ<ÖœJÞ@(;çæüúë¾Xe Jûž®SâTšØy`ÎÜHw}ßN½iD<ƒ¼õÏþTÂSnÌà“Ñ$øÕ¨,} Ç?ξN­KųïðôJº²K{=±· ž‘Óýzúöx†{(b ¥b"<Ó>¿­|ã¥Z´ú”q€·`s‘ø‘í_Z|µ†ÚÖÝv„8M£$€02Ïÿ¯ãsZË•Dý‡‡pѧÕù@Ãx[Om§™õ¯)ø•r÷cì‘»f]ª6Œdî?çñ¯My„zw¸c§ZòÓæk(ˆ“¹"ú3Ûñ¯›”µI½O¤Ë)¥9Ô¶ˆë¼!¦¦¢&ù†<:çŸñ®»Ãz1@’N>iñúÖ=ž¯m§ÜÛBñ 7c¨é]<7ÍyªØGxÝ*’Îjãd®yxÚ•däíkÝßÐùSöíø'7†l!ñu”L‘Eˆn Bpœ'ž™cù×ÂOp ìÀyYÆ8Áý}k÷ö¢øMkñ#à&³¥\GóO>He+4n{rµøOo.™}um0c%«˜œ/ m8éíï_¢pýGRÃMëW£ÿ‚3ñ Þ2²Ç6Õš±\æ’S$œG Á=ÇL#O3#ºíÃÀÀÏõ¤S»ü;O'ž¿çÚ‡´`”õç>ÝkêÏ‘%V ÆI烎?/ëïQ¬äàªç›æûÄ{õ¦#"“±ˆVÏÊÜ~?Ê¥•ËÚO\c®:þ0,Ãh`GE#‘ŽÞý*îK W "€Ns‘ž¸ˆéYæRw(«Ïݺ~Y³¹1È’:²•*OæàóÏÒ†­ø{Uo"$Ž@TŒåN6ËšÙŒ›¢Wí ™ £<“þzW)áÃk«[ŠdW“8aÏÿ_ú÷®ÊÎÚ 9O(<€ü¹9íŽþõÃQ.mÍà‹¶vPÙÄd,]Ê‚»Î Ÿlþ¶ÑÈâid$»ýÔ*T¯ÐñšŽÎà]I–“ÌåçŽÀvÏj{â^HT¥Fãíþ–²ÐÙY'cç¯!íÂ#¹ðÿ85™¸¤ä¼à‚sÇ\œžÕµãk6µÖåòh OSϯ¥c,gbí,’0FsÜ};×£x¦rKv0²Œ¸$3sœá½?ZA`]dÁÏïŠtaŽ@ŽH^2{zÐ Êçn'†öéTHõBÊÍŒîÛÓÓßךqQµ•>e`vªœñôü?_j"\*w øQýyÿ=cÚ»]C0yäyè=Gë@ŒXî]€rÜõ뎟ÓÒŸ.ÖDf Øè~Uëþ5ÊÇÌÜ€ñ”éŸ\sô¥-¿`8ÉqþOùúX‰‚2Jĺ `öB*x›ÉŒ#Ü.á×!­SYvª-Œg†#Û?ˆ­ÙYp w,Nh5<1¯]hºŒ Ì.üòNW?ýr+Û4ûñ«Ù-Ä™JÀö?ç½y&™ee<‘<ÐBãøgÂ:c©ãÿ­]f†Ï Ý<Ÿoµ¸ó¾¸±ÏóÖ¾÷'•l*Q¨ï®;~'V©ËÙÏc·tiÁòÃ2¨É pqžþ½~”ÒïdÅÌ3¹È;sž8çñ©¡Š;«i&…•ã#!×£~]j­ìm*;p¸ãqëžß_þ½}ƒÚè÷4¶çšê÷(u)Žò­» ç•ðؼRÅIÍ«3ëð” j—D~À|;ñô~#Ò„±¿9 ŒØ|UÿtøžšoÂïøJ7 s¯^HÍî@brsŒpÆ>¾¾ÕÈüý¬î¼fÑj0¬ä¾ã6ΡG§­|µûj~бþÐ4Ó䵌%¶’'Ø`ášABž†Ÿ©¯C,­WR&Ô]ÛôÕ~6>s5ÁSÁFuâÖªÉy½Ü®|àå·dCeFõÿ>õS†R¤õô<ö«”b ” ¤ûcŠb7,@ ÏOoZýø#¶ð—‡.5 ê÷qclp30sÔ'¿_þ¹®4)dÀl’XgÒ½GÂ7–ö6ÏòÉ0l¦H\GZóûV¶¼žÝŽUdeŒ(à€Ç·à¼WÔæ˜*X|¥7«ZëÕêc.ismЮӔbBí<Œ¯^8ôÿõÔ’"³:íP6Ôàóéþ*B ¬pƒÀÎO¡çž3K®ï»†àg§÷úcõ¯–6'³°}Bú“a2È 1Ç<ôÿë׺kÂúçÀz•«'•m *‘„ m ÊÜsíŽ}kÄì.~Ër²°V#7}±þIô¯[ºñI¼ð%ͼ`)Á!²1ÇSÐW=TݬmNÖiž¦­Ã&çwpwHÙíÇ—j¡-ÃG}“(̯¨5­hÿñ,p €Tr:ã'¬)‘m®™™–BOÌ¥³žyôÇZô%M ¾§2i¶‰ídû-É óÉS‚O?Ôþ¶„j¢RKyýÀØe€9ÈäšæÒyYÅ—dŽTçg^OùïZZ}ò²4=ÍÂ猟QÞ»0µ)>juv{y?ò{3)ÅèÖ¤ÆÚH³¡wm%Ac‚9üj¶Af”™À Ž–{øUÇ‚O%” ù ÚîzóßéU£DK r[»dÇéôük’ppi4tFìk?x†@'àvöã5 Ò å{`‡ÈôÇÖ¥g*íœäò­Îà{uþu‘¿’Áœ°?ÂO·jÁß¡fùÊí=01‘\xÚœ´Ô{Ÿc᜛ªÈ¥FP@9 8ÀÀôü*ä Ç'9ÎI5P¤{ÈÉÆõéŽô«è¥FÐ3·º“Œðê»A#ô ¾<Ó”»º‹kyæ¸ù—¦9¯høiñö=f+i ,y ÃôÍx½­¶lt=–ºßÝ2j0ª€rò3ëßó¯šÇAT‹•®ÏÕr‡*QŒÌûbÛRóô@ǯ'×­aøVØÃ;Ë!#.X19ãŠÍÑ.ä—Ãð!bC|¹É=êêŸØ<Î$ÇòIâ¾Ný§…FPÚgS£î´ÌP$ „uô¯eøO¡K_Žf£ òžp+æOÞÝKs Ž«¸2ãÌbrÇ9Šû{à™.¡sËÆ»0 äƒÈÏa]øJ~Ö¢ƒ>7‹ªÿgàœ£µ¬{&·£¥ß†ä¶q•eP1_ß¶ÃßøW_üImEm/îd»„6ß›.sÓ ?Zþ„µÙ²…uøÉÿFÒÒËâ>‹x„Bî'‰˜/8Êüøþºû¸/«f4yv’iþhþj¦þ±€­öZ’üŸà|:_.Œ£/׿Á$Ž£'¯zD¸“ó; –ç¿?…(•&\’N[¿éïIö…ÀP³¨Lñ’Fq_\|Èá.ü‚œóŸþ½,‘ù%œò½r߯ç ¦ QŠˆÑNzå±Cò™ùT'÷WoQëôþT$‘K¸ã gþªAnêë¸ò2 9$Çóõ¥O™Ã0]Ü€ÇôôÍtt+{jé GnzóÇòÿëRzWOðæªê²Ã í~£žxÇøWeg­\iÐl‹`g{±nÂËy¨A*ÅçMÆçb¿Ìgýzì4›Uc¹–+™ÈgÚr:à|þ•\Èk}»KÕƒ Ë –ÎݧÓº ;˜ï¦Hóò©Ý•<çÜÏ­rðŠêWÁ.mÚ8í¤Û°CœöÇAÿÖ®FðÜšU¸žWc Hð3ܯùíÈù_ÂΈ¹&xÿÄ”ðˆÅX¤ÍùW%8UÎJ¡'%ãÖ|DW‹\RG;06ð1ÿÖ®Y£1°Tú àñŒ~u×OáFU5“/½”ò[;öãœ~ìªH¬˜Ž@Nã§~”Ù`@$¸#®;ãüþ4‘/Ì cçA÷Íhf/™—A ÌŸNþ¢š%Û TõsÈL~4¾Vw6¯R ÎO>޿ΑÛ)·%‰#9ç¨õ 0†PwCíÏ5&ÐÈ›”rpª:1Ïzj¾é?‰ï·¯^ãš~å$‚SÁþëú â€$ˆm1ŽY¸Ãtî:ýzU‘¹b’U½Ψœb1Á p$sÓ§NkMcfó|¿öIéÿŽÐ4}>hVÒ!“MŒé‰dÁçýïòI®‡þ¯…®¡ŠY4´WUଌqþ×ùæ«Å¨‹•÷ 1ãi$pzóZ6W${Š€Ã$ñ‘×Þ¿¡!„ÃÇì/¹e&µfŽ›¦èZ5¢Û.šL|2˜ÝØc©À'Û¿¯·gA°X9,\ŸçUP2lØë•8#wÌ1ƒ×§½I¾+”u—7âÏõú×Z„b½Ø¯ÀëU*[âüNcS²Ò¯A Tî óú×/s¢h,Íê©‘´ÿõ¿¥vßÙÛÈCƒŸ”~½ø¤tЀßszÉ6G©÷íüëšt£?‰#™ÊǾ Ò$·e…_w9c“Ç>æ©Üü;oîçu$¸ã žõèòê: ®ÄJòÈ¹ËÆ‡¯PN?ýz̼]f‘¾Ñ*†Wï(+ÿ|ÿŸÒ¹ê`¨Í{ÐAíÑ#«Ú5ž«%¾W(v—§¾xÅmxGKIµKv“çD“;·=Çáô§ë¶_hñ%çwÛ—þ"ÃÝzúWká“*HÈT3ݹ¯ÂóG‰«)l¤í÷Ÿ¥åÔ9Ôg%¥¥þ ¼éQ°Øƒ•##ϲ+Ýßâ±°)ÊNG~ŸáþzWÊš©6‹h‘Û¤dç?ý}«jçÅr¼eXlãǧëô¯Ìóloµªù6>Î'k³©ø­ã'×­Ìrݹ¸ qÏn_¥x¹¨Ûé!•âN9–zV¿Šüe+Þ¹sÇ?‡ç^Wiâ(µ_Û%Ñf‰„“änù@éžüãó¯3.Ë«fãNšøŸâtTÄÑÃGš«²þ¿-Ê|Wqla„:€²ºŽ†I\u=«ÊLŸ2ɽ°NKmûÇ®sþzœu¯Yø¹m¡6˜/t W”e|ƒÔ“‚:ôä×’²>^Þ'9ôÍ~ÍÊa“JX;Ú)·ÝÿHü‡˜Ë3¯*ö´nì»!FT@G8R9éŸðªòíPKœ’vðÀ;þ¿ýj² !€.Ü20G<ÿžÕZëù~O 0Ÿ_^™úלpž¯¢¬sèHþ^Y£EÚ8ÛÉÿ>•Ãx·KÚ¹ò‡îäQ"ù`ôçƒþ5êz•f< 콌®mÕšÓ~$@ʑܞ?:óïF&†ÞD}ÌNrrp1Û¯ùæ¾³9Ãû4%%f⺓JJjVèÎbUv>XR6±àz®jH£Xå À7¯¥D„¡2„ ½J`ôç¯ùôtq®òT°bÛ¸ïÏ®>•òež!°KQávDTÔdœ çê [ÒuY™.,× ™pAŒNJèml¡ñ…íã–aÜ`´rºã'-òž:tü…ciºõ…ô "Fɸ®e'$`t9ïYÓ©®»¢ì÷D1HDW»2¯$l““Ç^œ~¾Õ—>Rí£c“ÃcžßŸÒµ®<Èdòö¼là…ÉèOÇùæ±ï]UC·9ž}EwÕME.†jÅ‹mMmƒ€‹—o˜7Bp:Ó¤š®d‘TF0qŒ¾çŽßÖ£µ‹s0Þ Œ`wéÇÿª†O=Pçàñƒßëùœ×} :Ü»òH®Ë!‘YB„ Ü^Ÿ_Ê‘HL®p8ùW=3þȨ’W+‚…×,HÝúbšÎüÉ @ÆGN¿ýjÝ&Ö Ù !\}Уs`‘*;—ŒG>ÞŒœòOçëNy”m 2[húöút栾ˣýæ*ÙÀ} T>ÂèfùLªû€0 Æ@õü½ª@ûˆÃ|¥GÉÆ3ëÓëÞ¢Ž5ØdÄc’6}{Õ‹"rÂA¹†üú¿…JµÅkèné§*…-Î:ôuÔÛ”ôÀÿ'ò¦ÄC±.3¸`ùRNO ÷Àùr‡5ábgí*ò£õ¼á0Šý†Ûdb>`IÆã¿OóüëN(ñ·<zf¨ÙÄå¹#»ž¿JÓ´ÄŽIÆÜò+Ï®Úvì}.SIJ ÛviáaŠ5eäóÇé[• ¿‡9ɬɿ3Ê\€¹çй¥çíŒópO§qú׉SX;Ÿ¤Ð\µ«<#© ­:ßrv$•9Ç'¯å\>»âñ'¬t€Î R&“=]Çüâµ|ò¦ŽNÓ¸D2G^IÈôÏ…~’ïÅ—WO’"åÉÁÇדÍ|¬b¢Û{ŸWuóŸàŸ¥Ö¡fW\ƒ‘ߊûçàæ‡“¡[(POë_"xIY¨ÐuË®Ú%ų†ÃT9îp³ÁqapË,Oƒ’Žséé]…|PtyöH»áé’:9ïèzW©B‘ëqïMærò?_¯ó®w)SÓsD”½NÁÿïô´Š Ï cv ?–yëúW©éÞ&Mzu\3yœ õè+™ºðÞ¤ŽªªÕ€Ë0è½?ÿ•TV“F}$ø°œv㟩¬çim£-7ö9ÿ‹V")í¦eÀÊãñÏ—â=+Ï%]p½Á!O+Õ~(#\è±LÊØWz’8çüñ^S‡Üe,sÀqøWE?„Îv¾ƒÙ[¨ffÛÚšŒ¤‚NÕm ý=±IbFÊ•ã+þ}?ZÜ_îþ=ÇNõ¡‹†Î>eÎyãÓŸÇç¥b±S€®ç>Ù¤M¦7SÓ ç'>ŸäRº Ç–^TŸò?•FŒŠÄ’FqÀþ6I;°¹È—þ½B„¬lzr>½O5,ƒË;Ž÷d¯ùþZpO1™IeÝÉÚ1ïþ5lÜÆ§ #ïµr?•TŽ qò•É8ÉÎzîç×éÇ­,®$°“útþTö>·,*Áa‡X íïùÖÆ{)T” m çsc{ÿ/ð¬¸ã@ˆUÙAëÐçœu« GqóðÜõ=úÿœWôçÕÛgÏ*¶Ð±ý±"¡S&Þs•ÏåËò§q!œ‰;w ñëÿÖªOnÍ´·'äãҩʹ&5<sÆîØ¡Ði‚¬™¸|QöpVP%@@¶÷9íüªº˜ohã‰+€¹ü«™§Œüª<¾€ã×Ú«Cx~×±X†cœ7ŸÿX®YC—âZ TæWêvvr$h-·hÉÆ1éíV®¬íï­€)¦ Wdçv:ç×ʱ<1Öµª<sóŒ`chçóê?­u²hï¥Ü4nWzuA‘ÏМãžþÕÁ[J…Õõ;¨áªWiµ£8›®«"ƨvß*Œ+ºðþ’`…$`6®3ÇÌ?Æ¡{#6¦ev@ËÎâ2{ôŸQÜÕËíV+x cR¤œŸÄ×òÿc¥,M[3±û^‡%ÅöF“ÝC ,ͽ˜³œÿ_׊æ¤ô¯ŒÃàêbf¹ZU!FÒz âß<“’F}ùÙžJçØ;Ô^Ógk!x\‰fÊ„’Ã>¿QŠÍдWñ—Š´&3ûÛ¹–`¤íËr~˜9>Ù¯iñÏ…´ï ø‚ëIµŠAml±lFsÝ““×$“_²ðn„³AüQ‹—ÜÒýO‚Î)â'‚«˜GøJJ ÖJïîÛæy‹­."Ñf€TÇß' îõí\ÈÎø,Á8 ý>¿Ê½Kƺ]”¯ Ý Ž•98õô'òüüÍL‘(7eŽõÏ?ŸÒ½î*‡&6:ïù³àpÜkÌÕ—nà¡FU°GÓ·áÿצ8#©qƒÏCôÍLñFO\ŽÝ5§áÝ1îu% ¥­×%‡AÐ÷?‡·JùL= âjÆŒ7“±×&¢®ÍmÖZ|YÊ(çÉÁ$žyëÓëUõ]U5WŠF‹qÆÜ€õþUÐßè’ÜA¹­ÏdtÆ9'OÖ±.<1Îß™Pÿ´[Œv5úni“ÕÅS¥N“V‚·¼Úü—æy´1 \ËVs[ƒÌ¨À0ðÏóÅNŽT æd†%›?‡Ò—Q³sy,ØU\˜ãúzŒTHÛˆ’1»óþŸ­~]Vœ¨ÍÓžëCÓ‹æI£¦Óµ·¶P¥£xNÃÀ`IïùqïïZ÷Z$¢huKIÌð¡Rè[œôíÏùÏxnÖ+Éæ±6Æ‰Š•=sׯLþu³áýJóI¼’eAÈ @ÁÏ$ñúñ\²Ñ»nm¥™­©ø–Ò+ƒÓí º€îS%òÏA\¿‰µ+K¨|¨ìcŠp~g@ ƒžÃòúÖ—ˆô›í‹‡8bø|Á$t¬+âK§fÀ¸<ôþŸõµ±ÕªáUDî’½—nç"¦£Q²¬32°G ƒÂÿ§ãþ5zÊ2`ÊËgéóvÿ=Å^µ‡QµŠ5Ší4Â…eútöôõ¦Ë¤& ×1Fª '^zô¯Ÿú¼Ó»GbjÛš§Âæh–e»Û!.Uyéׯáëõª-áS¡hÝ3¸:ž*Ä2´;[ÍÊTÍÐñÁñýjHnFòeRIÉ.I'ò}T^Xé'R“RëfÿÌâ’¨¥î½ ét;„V\Ž 0èzpzšÈ¼µ¹Â`‘‹á÷ü+¡ÆÎs)VÈÊô?ÔþUÔ¸|íÉÜG^•ÁS‚“惒_"—:Üã¼¹ |4QËí8ÇJ·¤DÏ!*’LpÀð?Ϲ$¾\Nr…;³Ð~•I2€)N¤ŽXyéþq^)B”¢ÏS/¢ëâc°å0W$±`ާ>½¿úÔÅæÜTóÎÓÇéùQrÇ€ Ïq犖Ñ~ѬsÇ^ŸýzùÚvêHýN¯ïg <6-F˜U’Q½7}!á}rÒÇŨVa™]‚@àúÿšÔi§ÄZ@ßïWåÍÿÄ쟉6±ù„*K‚œŽGç_Niÿmí45e9Tåƒ)õÇ}*¨T©‡’š[Ÿ‹ñV b«ªWømùc7Žl£VFº‹pì\f¾$ÿ‚ƒêöÿÃF6ÌÉÆ Ãm>[`N•ò‡ÅÿÚ—Å:‡ˆ&.ªðBœåÄAÁ>¨}Åxï‹þ9x»ÅUÅž§ªÛv‰Ð©‚0z(<ä÷¯©¥‡Çf ”S¹ù»X®S\ÍÊÇŠc|‚½³´öçñéA+; [¨ëÏÿ«5$çs>ÀTÞØÈõú ÿ*€Yvcq<}ìÿžs_¢#ó¶I2ª+)>Xa’–Ïc?ZjÌ«4gšÊ~ö}qÇ?J|«ûµÛ”sŸœŒîÈöõõý)¨Â(bÎNàýNyúÐ Š~vn¸ÎqøsÇ_ÇëM ÂN`¤ä~—éL‘wL[‚ÛÈúòjÆò\)Ûß½ƒÇ ÍWßå3d¥užñ”úD‰>|ÿVñßüó\Æ6o €ç¡?#ô¦í-&õ\÷ þ¾ŸÊ“IèÃcß"×.õí,¾™ɹrÌ$ {~?•sþTšlÎ×Oûçq#zãüñ\_‚¼ssá›èˆ}™L‹´e‡ÇæÏ_rÓÛAñÝšß,gíl»›ù}xÿ==+•¯eÓCdùÕ›8O¡¼ð¥Øž?-Ô œç§ùõé^2U@89^\qþ@¯ 5ûHŸL¹µ·½dÂ…·¹ú×ƒÝÆö×SÆëå²±B®ÈsÓNkx;ÜUM&WŒ)ÎÓ·œGN}Öž6£̼‚ß7CéÇçBFcdm¡\ŒƒøgÚ‚Ãb£:¨œéØÖ†BlÝ´í¡Pü¾¹¥Ä-ÀL¥º?JG6pø.>èôü©‚F$åèOooë@ „!]ÌòîNyüϵ ØÑ°Ý´’0§ÿZ•QÕ>`¤cn{ϧ׭)%Fõb2Ù8>™Ïó   “/€BŒ`°çŽ¿…?håñ1¸4´G)%¤°³1TÉ!{gÓ=ùõ¨<=a5ö®ŠÑŒ°!»×W&5Ô¢3£"ýÔãpÏ<çßõ>õö’t;»kèØº‚KevõÉüëæs¬E:y.mmtzX 2•H´´¹ÝøCF_ ø¾Oµ'î®JH…ñÏsÓ¿#ÞºŸG—žz)ýâ;œúú×5©ßoÃÖwp K»!Ä€å#ƒÆ†¤³Õ?´lÒWpC)àò2 ö¯Å)æxŒuE;k³?C¥‡§‡N7F»©%½Ä™QˆoNü?óŠâu`ÏœHÚTnƒúÿœV—Ä˱c¨Æ¡ˆ†ÿhþµæ—:£? K#>ï^:ŸJøLn rÆÔSèϬ£‰„(E®¨v«­I%Â-wzcïøV;³Èí;¾ñÆxçãVB ù|: 'ó?çëQÊ6•Ú¼±ž+Ѥ£M%x5éÕ—4å%Êzÿì·áOíÏ˪IyZdXVc{‚X~*§w¤½ß“_æ~ËaS‚gJ þëŸÍJÿ’±ò¯ ÃW, ™TtëóOÖ¼…OÎJÇåwŽ09ü{‘^ûñ'F‘|%©¹9XpAžy—Zð)”´Q•ù™8féŒgµ~¥ÅíKNKùV6acÉvCûÀGeŽ;œž:×Oà¹Yï 0¾N mœp=Gùë\¿fÜ íyPxç¿åþx­ÿ—Ķé*œí9ãiýkæ2ºÞÃJkºüt:gh´zlk+FT˜Ùˆ$džj3¦ù¥Œ`üÝAëÿêïØWYÿ³ns"4cûÛrp?ɩDž§’lÌ8PS õû{ÄAnÏ.4z'ãý"Ki­¦ UYv—åŒç§^k’mƒ¼Ÿ»œóúzŠúÅþ —TðÄÉ2ÊWr¨MÌÄsèqšð7·hçL ȬT–àƒÏoÃù×äÜG†T±Ž¬6—æz4SŒy_BÖ…r–ú½¬ï¾ ©á°N?‡ó®ÛZÓ¢™÷¾hlŒç?ÌWG—9dÉ*G?Â:qøwâé§$#ï¨uÉÎzwÏÿ®¾>kTθ5f™6± ’ýŸ°r¸ÀK™ÙÄ&&<€NxéøžƒøbHÞ5Ú&Bß/Ê8d×éøWDð¸)¦ÒH¨Â¥ìÏ2xæ“ÌY û¬ryôüé’Å @`Š9 Ý}ÿÎkÓÏ…VyË‘ä¸È$'9Ïמõ“uá"±ŠÏبQ“€8ûWð˜o²ÐÕ:šÜᤋz‡@p}ýzgñ¨¥‰äPwœãŒã·=+³œ'˜€¶2 hH8>Ÿ…Vo—r†'Àsœu<öÏó®OaE+_ðÆhäE¶àd·ññžzÔ‹ ʼn\ `ãÓ'ç]%î€l‘ä]Šé€2=ç\Ü’>ü’s‚¾C=䦣NOµÈ°Î*Uä2^Q¹ÛÀ\è;Œþµ¡§DîûØÀî+9 šRÝ'ížßç½nØÛ·c»¿BÇÞ¾2¼”aÊ}ÖM‡–#ê¾…íÛÏ™w#Èôã5½ ÙuëÃ*áb=rxê9ö?Ð×-ZÊT¥c¶jDÙø±xoš4 ™&PBŒëþqŠï¼2WCðÌ®ÙsÓÛ­q>*µ‡Vñ•­¼Mµ"úgæÀ~†´ü}®C᯼rOåM*€ –Ÿ§Ò¼¦œ”i$zsjr–ÈùçÄ^$’ïÇwÒ‚ yß)BHÎr>¢ºmGÅ·÷b€äàíÉcòãÿÔkË.î$}Eç}àÉ)mÙç“ßÿ¯^‘ [ý¦Åòs¿“ƒŠûüÇ/† Fij•™üãG6xüÇ›ºrvôZ äm$­ó0.9Êä}+6æ"F]ˆÁ¡Ž¿_ë]Æ£¡´,ß.ýÀœ }zûVè“HTùl@‰¦×½m…ÅÓåßcäqøžÑÙ\óýNÉ¡!‡9ä1ß§³ú÷¬ÐÌèÈÀž9%NHãõÆ+«ñZ˜„Œ‹ öÀç“Çø×-V`ìFáØv9õúúWÒRŸ<‘ñµéû*Ž €&Ñ•ÃëŽr9ïïÖ­Á‘ˆ|‚I'<÷\€0ªÃ±cA u‡§ y0!Þ 9èsíÚº ®Îr”¶@ïÛµ—œ!ZzV¿uá»æš#å9;CÃß¿9ý?(´ë„‚à³âFàœàç¡Ïéù×gaö-ZÝcº1¹NAüGáRßq£Ñ|#ñÃÞ1¹Š=Zaa6ìNÒ3ß©ïõçñ—í á­*ÆóOÔ´‚ÓÛά²Ê=6’p:äð®fç‡C½ŽHî^æ6?ÇR9çôýkgL¾·Öô©´»‹”‚DB^JžØÏ^? ÁB0|Ñ5N÷Lòð›ü )^€œ£>õYÌ›w'¨kê:oÙu -Þ=®§½ø'¡ª“[Æv®Pq·¿®*걉]ƒ.1³9Âà‘ýqÅE±v†qÐÁö5qíÑY0C¡Æ'ŽFi‹ùAL±$¸íëÿÖ¢Ì áPÄ­žÁÆ;ÿ)Ü–Œ†;?„¹ cœ}1Ry{UŽÐû±œdú`òqšg–[69ààŸ¡4€sÊ|²»€ç¡ã‡5"̸£,}OÿXT@²¸ ó„È ž¾ßÒ•#  Aô;E}ªšSKaнœ`z ¦Ç¥0É’ †Ï|ûW§¯…—lªQ Ïã¾ùâ¤O MhÌqFP7Œ}=Ïçû£Í"ÞâX+;œ–ƒZ+ˆÀ'œb0­%ÿ†. ŽF†$2nn:gß§ojôxüµ·F»Tð@“޼wÍh[é²Ák,SDd$°í“Éï\³Ílî™k©âVvH/#Šn$õÀÇ¡úqK©øNY­¥¶òƒîèKÇOËé]OŠü?»fŠ6ÈcòãŒñšØðÆŸ=呌6ù²S9öõüëä³Lb«ï=cIS|¶<ÇÂQË–Â`¥Œ òy'õ·eᯱ_¼9Ûo&^îôÈ$R ï$ðK³4ñÅöyAË#7ùÿ"µ¬4¸ÄWJÄ’ã>ŸˆükÄÁÔ§NNQµ™èVRqZê”þ:‰4ïÚ@@ÇÙ”’€ç{gÛÓüšò´ÎŒ`\“Ïjýñ'­ÅZX¶¿²]BÛã;X`¯Üa‚N‡žëçOü$Ñ|'ã ËQ§bßp–yY°§#{Û¿§zùüñBŒ¥Œ½ÓéÔô0œõÔi-ï±óÔLí#!ÞÚ;çžœöÿ Ÿû6êv!‘·pPœä`žõõ—ÀK—^ÔѬ­”,jÀ+óqóšú M¼ IPq‘è;•Í¡GB5ÜùoÒß©X‡:5;^ß/ó>øE£øËCñ­Î•¢ÞÈŽÀHE¹§ÈsŠú³S…õÝ;gG7%•Î8U äôö?wgB¾fîräƒ×úõªí¿†6íò×<ä°Ž8Ͻz40e T1–n¤ZiÞÛzðÏs*xeÐkÙÊëUwgºO¡ó§Ä]Aà=q1çì"•ÜÀ88éÀéÍ|w£YÇ|JÜeFwÏqú×ꎯá}ÚEüJ¡·Û¼O(!ÿ=ëò×NÓK›Ë)%h.YÐr:åkõ oy›”y@àʤ>€ŸjùSöíøsrڇ⬊Ãg#ÛM Æ >6ÉÁÿšò±9ŠÅÇ•Êö1Ä`Ôi¹%±ñoÙþLŒ—S¸¢ç§§­z§ÃX,|C¤›yŸý#ÍhÔœ¯ŸÔ×–ÎÈPFõã?Ë¿ëZmì–n"™¡xØ8`HúqŸÿUys2o“áè|áWƒåî<÷ÏOoΚ~ K1‰'ïÏåô¯£æðrÈXmY =27côÿõ Ê»ðDÈ4D©9¸Î}x9ýk'›É½…}N(ð¿øWpÆX$8Àä9'ž8Æ>£ð¬éþ+YbHÔʹ ð=qOÒ½å|6 ¦3 ´›² Ç'¿>¿aVgÐÌ…ø“¿üÿ:Ÿí‡®£ú¢¾ÇÃ_´Ø´t‘Bím (=ͼ“o˜[#åàäØýk×ÿh{Ó‰ÒÒ/– ðQ½‡Jòq‚g9 þ¼ÿoõ‰ûIŸKF8Ò]Iàˆ ±ÏèG¿jé-`v•ÚO`SYúE¶X9S·cœã¥uþÓî§ j2IƉÿð1ÕãÌÚÙ§ðö[ÉM7ÖǪ|%ð}¥ÌÏw›äØÈ-œþUôï‡mãÓm‚ÛùpàaF@ãVf>ƒjŒÜÍoNª1žÿý¥}]ákK}CD€:R2F1Šø­kÉók™â^æ¶>iñ¿Ãý—Ü­±† a˜ŒtíÒ²-| sák­V›6‚HüÌbàHê8ëëë_[ÿÂ9gd¤ˆ–HÇ;\f¼7ãíꮉuo ÉÜQxä㚉BTÖ¬2üÓëµcN1ùž¢ßBþmFáŽÙNá죂åÞ¸øŠûǺû< !±‚ ‘E·©ö­z†,STÚL 䲑ŽN@þ•ušï†£E„ÙY[Ç\¨R“Ï9õÅ{Ù<`±jRW·ácÆã\ƒž„à`Ó>¼ÖÞ±§›b’dH˜t<ûVVCõRrp99?ýþµq5f Q¼¸ÜÙ£æÏ<û{V¾‹8TPïó§0t’ F¿1Æx`ŽG>¾)ñÎm6•ùsØçtò³¦Üì[µµê‰ ØxÈÇøð*¦«áP·6@‰­ñ"°'’9Æ1íÓ½dø{T¦ ÅDƒå=ÿ<Ÿò+¼ÒõBÿ.ñ `÷Ϩýx®w£V4^÷©æ#¯|«Ò6ÊAWSÀÎ8ã·ÝýkšpïË€A_áëׯÓµì¾+Ñ-µ>{ˆ!+1L°Éè0N+Ê–TA8;[68âºiÉMo©2V³3míˆSÀ%;dýÞ¼ç¿QOxÁ$•#ƒ‘Û¯LqùU•X••VO˜þ¸úúT’+pÃ\r:ãüô­T(Ë–à1b[œ/_Æ£kfNT)ãvÒzó×ùUÅQdbÛW¡'?ôâ—j€…‹1n«Ž\sþ*M&À­äeY[qr0¹có}?Ï>ô’yÈåcò‚ߤd,Ÿ.A6g={ÛéQ˜B|¾vÜvùxýGò¥d3õ·Ë‚ê&f³A‘ƒ¹øÆ8è:}}jK]ÚúßlQ 䯣vHéŽ1é_7h_µô9Žÿ@´¸í'—3(Ç·\~}oXþÖúU“n¼Ðµ uÏ"ÖEp¶H'Ÿç_}_%Íi«¨_ѯó=:y– m';|š=â/ ,+•*WƒÅ9ô>åUW-‘¹¹Ï¿ÏzòÍ+öÁðUê,WsjvŒÙÛö‹_0m㔜uOÒº}#öð>±å}\>j°9í¤R9úZðka³:+š¥)[ÑžØZßÚ2_øSa`‡Œ˜øà3ËŸÒ¸Ë=:çDÔÐÀÍÆÊg<ÿœW¿ØxžÃYa’H¥Þ2Ãצ;q\¿ˆ¼¶CSr8½hÃáÓ‹%ò§!»Ó½¿ÏZo‡Vê6#phÛcž?ÏøWkj‚ItaY8#C\Q­ÉÔê’NÇ5g¦[DêþH•AAÈVõ'¸ï^ûIÚZØø³Gž;%n­[Üo^9ã𯫿°Ñ˜0j8èÀñƒÛëý+åoÚÎþÙüI¢ÛA*™ ‚a(Á~eÀéþÉWŽ«*´'ïÿuám±’)ü ¼·¸ñåý•¤1¢e«l†*àž^¸Ïµ}káÙmò$EÝ»°è=ëä_…÷Þø¯áûëv+ìfØ‚ÃçêJŸOº+îåd+òîã,€œ3À?•q`12§‡ŒcÐÓ*­œdÞ•ÈtÞ ôˆþ#ƒîjö—£yD$’˜¤9ê½³Ü~­vSÇt‚ ¸cÎåÏÔþujOGr­²Uóv“½”ŸlfºåŒ›Z³™SOTshð”Ü®®äpœãó¯ÈïŠÖÇÂ_ü]¡ò¾É­Üˆ„_(ˆãÓدÙi4´²ýåÁóXñ€vñß·= ~CþÔúÚí ã[)#HüÝAîÒP$<öq[á*¹Ôq{Xñ³XZ”eÙ•´ûo üD7F Yä½Ê’cŸîð2z’x=sXzψ>xÂN(&·žÑØ­ÎÂ"—*W!º†õë\ÐŽ×OåÕ RF£Z³’qÈ9÷=A?v¶~?µñš.£æ9”…rdÁ>„}~µè¸¸­5GÏEêšÑ£õ¯áÿˆ"ñ—‚´]b·¿µŠãg\U$qÇ"­êžrÍ(¬ü(Ëéõ“û?øté|R³Ó`pÂ;~Uéfù[;‡á°G¦Ï¥|ÜæÔšGÞGáR{œ•„ð‰HØ|ÁÔ6ãœtéí\oÆ_\xëá—Šôƒd³½Ý„Ë hJì á°AþUêÒYH²må“«Ý@éÎyüjI­´‘…#d‹“ÏQ?­bªÊ©Æ¢³? ^×É“dÉ·†Lî#®AI¥(¸½ŽÞOHvÕÎ:~_¥zïíy฼ ñçÄ:m¥ºXÙ?Ùî †!µ0Ð!sŒñ—ÜO×=ëÊôÍ&;·'íiÁ¾EØÝ¡ÇWÔÒ¨ªSSî|Z~ʤ¡ÙŸK~Æ#Ô|5ñoÍk#ÙêÏL]X"•Y ‘Ç îõô¯½Mc.ß16Ž@=?õówìuà›xüOiuâ;4Žý• ‘‘ù-å¾[{§¾Ï“Ãn§.cž§¯aø×Íãk/i£±õØMQWùh¶R’%¸“Ÿ™Æ<ÿŸÀÔ±Û8fCnzuo_óÅu2è2Ç&d·V;DDÜ ¬–‘™v¸ÝÎ~uì9ÿ×)¶®™éòô3­tø$îÈÛ!Á?×üŠYm›¶h3ŸšM„éƒíé[kcâ¸`89*z×ð&% (<¨¯^µ›«'³/‘lÌH´+ ˆEDÝŒf0)©=*–¯à¸V3öeÜ[$¦:gü3]]­¬S L’~ö0Aõüi çªDŸ¾A?¯ò=*yÛÙê–Gæ—íƒð;[ÒuH¼Gk÷:RF"žDµlGûÇ;‰cæ_Ï5ó0³ã9?1\ƒ§Cþs_·Úÿƒ´éÓX]ÛC<3­Êo‹èCg=¹òÅïø'•µÔ¦÷Á7°h²å‹XÝ4’Û1$ck`ºcŸáaÏa]t±N1äg¡‡•7V.·Câm*ßä Ìḽ3ÀQCg©A϶WbÁXýáƒÐð¯CÐÿb¯éú:ÌV2X¡Á–Öã~þ} ØÇñ‡€dðG.´ýášæ[ò Aà½AïÍx¸ÖÝôÐýc žåøeF\Þ‡_â ’Ái9 5¹ß·¦@Å} ðX]gð<9 Ê—ÉÏçé_,L·þ'ÓÑošÚå q÷9'ò®‹àçˆõ¿†wÒØê—–÷P?1Ù·rA9ʯç^)(Ù·¯n§©‰Ças*^Æœí.—Óå©õ¾µqö[g.Àw9óÇMS67D]œ¬`â'ZõwÇËq™¢† ¹#ðZñßiw>=¾Š+¬‘˼‰;ñøqNOÚÔIl²œ;ÀEÕ¯¡Ëxs@6šE¬g?i™²î¡?^=«Õ“ÂÖ«lµ–N>ø.`pF};Uß ü=m:Þ¨ÅÅAÚàç§ëª:}¹ (FÝÇ8ã^Ö3æ÷>‹ó*X©Â…))%¿©æú·ƒífµ™£ŒPõ`~~uåø-¯«øðSM·Ñ-ek×p$'•ÂñíÞ½ÂëᵓéÒBaJ¾Õ—ð¦þÑíÕF:ö¯OgI¡ãŽ+«-ÁP¯Cšz³ç3,~&–!Æ.É?ðR?ƒIáf°Ö­âÜ­rb‘–¤g%±Ç#éÍ|4k† Ør>ÿÒ¿j¿à¡þ_|.¼Úªe„ˆ ã g5øµt¾MÀU;¶äãÇ^«ÞÈæã ˜wöàÏ78J£¥ˆþu¯ª§Æ..íáÝò¨Ú­¸’H+ÞFäC¨Rz1žç­xׂ,¿´¼g¥Bªrnv¸À#p'ëÍ}Q{£".Õ…6åÏãÀÏ×^õjœˆàÁRöœÍžWs ª‚@e³8ÉöüÿÏ™>Љ‚T <±Pyüv¯J¸ÐÁGÚªB–Æ6çØt5u¤ 2»öá‹.@ÿ<ÔCîµ:jaìîy¶¡¡-ÜLŒÎ2­Œ€ÃçÚ¼Þä5³°rUÁÀÁÿM{½Æ”›ÔöFI;ºW–xçCûªïA ˼ÜúWSš“ºÿ‚yÕir+ØÃ´# J to@~¯¥Z:Z´i5´±‘Œµ»ýG#ð#Ö³¢”@LjÌóŒc#Ÿ× §,ò:¿6C'ÊrGùã׿«9 [HçÓn•¤I¢ÁÈYTß§ç]¾…¬Ç6ÀÛ£”àù¸ÀÎ8çúWgâYâVáĨIRd ÛG·ßó®®Êþ¸"à  ªs€;?³’¹q²gf÷K E*†åñÇòã·å^G©éÂÒ{„!“k{ôééü«Ôt¹e(G2õ}¤ã'=ú÷ü«•ñ}¨·Õ™ïr«®y$œŸþ½:MÞȧvŽD’üûØzqŽÿËô5ÌA$ÆÇ-ƒžþ«"@üIRå˜ôcŸÀÕo) 2GŽOoð5ÔâúY¢¡ÃFL ±'nI޾ø÷þ”Ò‘…R 68+ŽOãùtõúTÏn¹a´@î=ðhHU|À’iÁ8ûgüö: O-¢;vã§½OòôøØìr‹ÙqÒŸ ×aläàîÇoÿ_çHÐK1Þ = \Ñk èïãµ+2 °* ØFyŸùæ¶-®¦áœçÆ=ùïVf·ó€XŠG8,Wôãåµv)q†8` ÷qÿׯè¸ÕÖÌùŸbÛ¹•{§A1°`y!NqUŒ„ð ’§;˜ŽOCý9­ç± ímæ`t¯µQ»Òš-ï† [ d‘Ÿ¡úûRs‹z2½•Ú3Æ[†ÞÃxqØÏNŸ•Oc©\ØÈ ½ÄÐàm9 óÇ\jÕ°1¨,ºgïdrOç¥-żlPÄv¾2@G¸ãñæ±”Õ¤h¥$×/æu'Å¿éb/±ø†úÛgbAÇ< r=½ë¾Ñ?k‰ú,¿>¥e©Ç¥omÖ9ëòAÈþ}ëÄ­á(ÊÁŠí1ÇõêݼíÜŽ†A\ð=úW•<¯QZT¢ýRüìvGŠºª4ýO¡,ÿoÙLÞ¢M™R)7Éú×™üMø…sñŸÄóø®âÑn¡¶ŽÙà²ýâÊAvÞAbIÇЭqĬÊwmq»åùCÓ§µzÁ_…w:ñ"<71)²¸†Qlãýc‘:ô<S_Ä9F_„ÀÔ¯FŠŒ’é}CÝËñ˜¼F"4ç;§é÷ßsÔ< û7|`øµà-"x!ÑôÈ,]o4Ù¦‘âž]¹ÌQ¼(;‰Á8¯¤ö²øworÚv½ªMáýbËg¨Zʯu2©Lsœ÷î,¿²4{(ncò*ȇ*Nz‚}q_ž?ðPŸZø3ö†¸’ ‰m«éö÷è¥p«÷¢`=y‡8ÿj¿"áL- ëð¸Ÿu4Úå²ÕYõOK_î>Ÿ4ÅO/‹”=í·>ÓðçÄxò?/EñŽ¦Ã¢ÛάëžpW’8Áéšè£Š{IÆÇÊ*ã*ÀóŽß/ó¯Ç}#\¿ðžªš†•©µ¥ÄMæ,–òŽÉþ/S‹žP¬­[Ü—Îß‘÷)V¹·teˆ8äŒçé_-~Ýÿ ü%âïC«ë·VZæ‘ÀÒRÞDT¸–EO’Ue$‘yRäŒô,‡þ àíNá ·ðüÊ<’ ÷9ó1ÇéúWšøÛÄzÏíGñ3š›¡jq¤ÒÈ,УIÄÛ?xçÀ ¸àœg¯LüÒɱøjœÕ©¸$®ßeÿc«ŽÂT£%)7§õè|µ¦ü:ñG†4M?Ä:~¥Kkp¬"¼/ŒƒÄ ŒCÒ¨OÕö¬‡Å$vñ\.^÷O;°3rÈNvóŒœú×Ñ?´þ‘ÿ'5¯†ú=ó˜|>-¤T‰ÉŒ3[Ægg LŽÄãÔçà7-Ó^!{Ã!ˆ•ÉÇ©'çò¥ÜÚMÚç‚©*m#ô³ö6·¼‡àö›?i»ÓQÈ´’pøùN:ã§Oñ>ìoaÜ ¸ów(Ï#÷ã¶:WÁß?mý7á€tO Ã໋©,bXžâ;ÕU”˰õëúVÍÏüVÚí¶Çðô‡þüš² Ï¶!?ãV¸o4®ù£CGª»ŠüÚ>šž? N 2ª®’>ây–Gž@q†QÈÏoÔQo¨IX—k`¬ŠA#¾zWÂ'þ ?•‡á´…·ò·cÿ.ÿçæÿ‚’êN—ðáb~ ¬±ëþŽ=êŸ g1zÑÿÉ¡ÿɼç/ëWðä}mñ¯à‡þ4øJãH×lÉY~e½¶!'€!X¦zb¿+ø{ñƒàø¯áäWQø«Â6±ê ³gbC¸pŲ6E.”ç·A]ÿÁˆâ7„íu-Ú•LsÛÈß2H§7s·œò;þ—Ÿþ4x«ÀöƒLð­æ¯cÎÑqk§^I]ãvм:Œ°ÚGBG¯±ÿeoˆú–µñ=tk%4[›‹žâ™‚ç÷`6ϳÎ3^? xs¥±¶]‰öu9Ò_™õÄ×sD„΂Û@RÛ»øÖ}ÕͺÜt“bà¶Tí>ßçҪݵ‹yM$‘är­2“ÛæÅs×~#\\§ØÞU£áxê2E|â|ÛW¶çQÔ7JŸf}ßÝV<}xõ§‰Ò&.`MÀ“‘‘ê?NµÀE¯“kX8ˆ.`C6{åx÷­½/Å×#šN¼+ ¸v¢Èj͆Êû¤E?8gßœTi¼Óú˜çŒ™»þDñYR\Ávª±¾r|ÀB“õÇùíQ}²îÅ·„–õº–=óÇãY¸Ë£ ¥º:xoìïT‰£0?ºàg¯Z¡¨hQü϶Üçz×±éü«<ø—O¹!.PZÈyùÎßþ±çŠdšŒ–ÛZÚú9S÷ŽâÃ¥G+¾ÅhW¼ŸìûWvõ rO>ݺõëâ¿®—_¯¦ŠL·’ˆw6W<ñï_oË©ÛÜ#‹›1Ï ^sŽyü~•ðWÆ–ë⾸w›b†nFqŽÿýojæÆIû4ŽÌ{q<9ù·ìV+аéøúÏÛ| ц½ñFFr$¶³€»9É ƒë\†ž¿c°ir»BœðAùþì?³¾ŠiÚì²*Ë}!ˆdüÁTûoÖ¼¬ 箥mKS’‹K®‡°ÝGkwÙ¢†HÔàùˆO瑚£kŒïäÃC•ÀÏåÇOçIªÊÞcœÄçšü¹½jˆÔmÄ) ]vîFŸç¥}+JZÉ<œÒ´Y¡©]æ™Å.N8=ȬOHžïkEŒ…êâÇëëQßH‘°ºï å˜õ积oOçTÓWžÏàÈxäT©»Þ$¿2…å©W"xÎd‚k†ñ #J¿fPJïÝÙü}}¸¯A¼’+ÂJ^¼NNLr9À?CøtÏøó>(ÓÚH ddžö¬ëBðphÖ¹4Ñï?>&YÝYAlÓ/š8 ; €â¾˜Òï㺶VSTƒ_™?üAsiↂ+¦tUŒ•ÛÅ~…|?ÔÍΑs†1®y>•çå8™RªéKcŸ;ÂEÅVŽçûMèË«øî2Xex#“œWàÞù.6îéÚ¿¡ïŒp¥Ï†%Ý÷pIÏ=«ùõñ­’hþ%Õ,£D7 €N?åÖ¾§*’Xêñ]R×Þ|æ:7ÀQŸf×ßÿ vŸ³î„šŸŽÅÄ‘1KTó V<þýjúWV¸¶x™a¸f$}Ùæ¿*ñßÙŽ×ʶÖo¥ŒrpOä1þ}«ÒÅ^U­cl¾<¸{¾¦GÙw>X#.âw°#žÜ ŽïOK¤ýÜѳ8*Q²áÆiíf®@3àÛrõàÿ“TfŽ{GåFs·¸ôüë8§r³ªKš÷_q‘{¥´*Qãhâà0ãߑָ_ˆzjZ4’Ú«Hаe’NA#צk¿“Rœ+y¶dÀç>üÏñ¬ç’Þçåx‘„cƒÏCŸ®+Ó„šµÎ ÅI8³æËk$Ô3ÝÌ@Ueãwn¿­:÷E¾ÑT«w‰…nN:Õñv>‡â‹ÈRGHÌ¢HÊäu™ôü+¢ðÞ¨šíšÚÜþòH×~äp?κ®ít|ä¢ã'yò³I#ˆÕ†AùTr9öþž•ÔxxªK«n CÛ¹þ†ÍÖ‘§»«[GŒ°b£wáž:ÕíÛFv"=¼à0Æ0?Èü¨½É±ÙiW6ʹùTä•ìEWñTŒ.옣u8ÿÕÞ¨è÷–·,<™Ap8µîšÏìýãrñ¦ž—´`H=Î3ÏJã/¾x†Òi#»Ð¯a(Ø(-É_®@#üþûE<Ó _᪟ͲÂÔŠ\ɯ‘ç;Í.Tp1ô‡g×·­E ›!!²pFzûãÚ»#^/S›Ù8˜k!u¶œžóÔä}ZYÌŽÁ]V>ËŸ»ƒÆ?OnkÖ~øWHñUÚÚjiÂàê{:·üÎú9UJÑö‘üÏŒ›Oq+–…A ãï98?ʺ/ øFÇ]uŠ]~ÓGÏñj1J‚½6:÷ë_XÁû%øLlWÖÚÖˆäúìöïK7ì…áh%Þ5]e²GO(d{žõåKŠ0Oi´ý?Í3¦=XÊî7ùžqû%xÎçN:–‰¬xwĶàrtËýìO.YUAç=k„Ò~"øãöy×çŽÌ ã•>Ûisi¥Ê“À.­·#?2ŸÄ××:gìÉá; ˆ§KÍ^I£mÃ÷‰ÔU޽_þ­ÄV°iú¥…¦¥J"Hõ e™[¹`ÀŒœxï_;âokJT'j°—xòÛ·tþäzt2©BJ¥;ÂKÎÿ¢·â|ÑáOÛ{â‹`Ž;ý6Âs‚¬°£1Ÿ2°{ÖgÆŸ„¾,jöÚ¥þ |i¯ÍBè‘.v¨j.2xÉlõ&½¿Æ¿±Ÿ€†mK.ÄCƒ¥Ô[övß+Œð5ñqtñ2ºþ¿­O†ŸöFø„)á+ˆ‹0™U‚ç°ù±Ò¬Û~Äÿç G‡Ùˆn7]G¶ß¾3šý·™ô›Ö+*̃‚[’ílkÐøÃ÷šRÜÞZ}®&®,%TšF #pG#5õ?ëæ9µÏþ/ÿn8—a–±“¿Èüíø=û.x£â ÝÃ¥êz>ž!G–s¨Î"T ´1-‚$à\të^£à_Ž–?³÷Ú§Šö-cƶÖßd²m-ãžÖØ%&BJ¶F>ê°àò+ÙtØçÁa…Yá†ÜJ½¸}‡d`çŒkËÌ8«‹JQmBVºZ^Û]ïçb(ä¾Í§e7·à|9ið¿â7Å/j~1д95GX¼šêæâæäE»ÈL®ÎØ–$®ê_bzÂâÒ_]éê…®!Žiœì?0eã®__Çì; [xRÎ4èÝ‘i’b$ÿ´ì~ñ?áéU`Öåˆ:\ôsÈVÆ=8'ü+àqüf¼‰%øŸAG.¢­ÎÛòéùcþÉ_å-)ð©} ‡?ÚWaˆôÌç¥gËû2|‰¼¥ðl©åƒ”þѼf$zfOzô)5¨ä í8ff Oðû¿E&±ms3$ÛÆ3ÈçéZCˆsK¨Ô¯?ü ÿ™ÒòÜ%ù•(ýÈÀÓÿe?„·+ö‹ Bè‡h }tqï̘üÿúõ¹mû/ü,T „­•ÕzK<ÏŽŸÞsëBk˦Üù®T+†NÈãù~f­ÂÙÆFâ8àè}³]ë6ÇUV•y¿ûyÿ™SÃÅéJ?r1‰ü'¬Œ9yî£'©lsÓʽÊßÇžtjÌpX:î\}9ëÚ§û|„Xd%xÈ9À?–jþ¿Q²­/FÛOäô&X,õ•%ëm~õ©ð¼Ÿ°ßÅ?‡úÕ¾¡¡djÍþjËayå”ÚF $ÁG9ûªXpGLgê?‚þ ñ‡¼A7Œ<[Qø¦KAdò(…–»ù!Ý ;³¸÷ϧ·ˆ¥²RUózá2HíÎj¥Ö¯o{6NQ°0T^:òq˜¬UxrÉèû!QÀÐ¥>xÅ—ˆôÝAL:„$#–?8ÛëŽß•A¯øCíÁ&ÑîàT dž9<óÁãé^iw3Z)âü¸»ñǽG‰&´tòo$'ÆFSŽÜW‡Ržhz¼©ê™ÑÞØ._³Ý:Á*ó–û§é·5šœ²¤Ä®6•ê½9ý+“Õœõëô«qø¶æÕÐl3ۯ̀7sýîIë^Pú¨!Ê–W/ÆÉ8>€~}8Í,~,hß¶ ‡ î==ý+¢4Ôˆ½¶=~vÒe_Šz¸gýÛ4ny ü¿úõÃt¬zûÛ2Æ©wäèê„3ù£jŒuãéÔWÐ?´Ѽ¥@’ùS¼Ã‚N '랢¾u¾•?µ4e‘%Ä{Aî ŸzúÇÇÞÞ8§…Bª")à“Œpy?‡zäÊhÊqH«ô:3*‰8Âöêu©tÆ #™ƒÀMËÇÐÇ¥S¼8ÝN!“g9§sÓ½fÇ®Aq½´Èç…Á'>ÝqÇ&¢žù”o°Ê}? ׿.úž76„:ŠÈ„Hø˜±áãàdAÛÛùÖ9×nãBf—Ï >냌÷ýjÕ̲²“ž0 †À?_læ¹}jöå˜ùå‘ç1gsOÒºUôhÍÔhÙ—P³¼+†ŽCÆpsÉí'ÙÌhWjŒ©HÆúW-ý¬ÖòC? ®A§5ñ\A|ØÚ% 6?Oê’oB=²ÜÏøE«D|u¬Z>xîäU^‡îôÇáúWèOÃ{ÖP…~ 'n¼Wå—üJúwÇBdÄÒ3‚ 9Êcò5úyð¦ú+­6Ù÷n܈AÇnÕñÕ¨¼.3•èz¸‰ªøG$u¿, ÿ‡e$gÐd×à'ÇÍ ´_Šúý©P7ʬ †#”¯×ð×ô5©[-ÞœÊ9ï_‰¿·¯…ûAGåîH¯lâpă¹ƒºñÇ _Ò¾“½–`ŸóE¯ÉŸ+YûLºQþY'÷è]øcai¢xOkVx$š’PàÎQAÈϿҵõEÖ½D‘0<ƒîÏZΰ°žßCÒá PÇñ =}*½Ã\.Íû$^F;OCÈõɯ§t¹í{…6¡¶v÷°)i@¤ó·»}¢7’ÆÔôGÁÏqÖªµ¡v.®9Á9üøUG‚ê'P˜ A8Ýž>¿ã[ªPŠÖ×üÎDçXh¿vÐ#qœ…àÕd²¹Œ€íîèO|gÿ]%Ì¥J£«|ÃNœš¡-¼r)d`§9†2¡ÿëVî¶9œ´¹Ç|XðëÞY-ý¶$ä™È;p>l{ú×›øwT—NÔ#¸Vó“ÝH ŽÏ_νŸQ‚ilîa™IŠd1“Ôciç=«Äµ}8é:ÔÖ§ #l 8äpsôÅ7nÇ•‰Ž¾Ñu=Wðͯ‹ô¶¼Ó@Žézî-ór:Ü{wõ®ü/z—Ïo4~IRT±?/\dâµ<âì½M#•ÃE#dó’l Ž>¾Õ×øËL’ïNKë5‡÷‡h8éžßçšÆîÏc–×Ôæt‹8tÛ…u;Žs ÎG^¹=zÿ:íVUŸKœÆ$e¸$ò8Zò¨5I£vó2UHÀã×<þ5ÚxgTŽIr#âÈúUJ-‹™­Ùãb xw¯8ÀÏQŒUY#H$méÓž‡ŠÛ˜4NèÇráwƒ‘ô犂D‰#DK±û¡AÇa×9ÕØ¬õfÖ}L[‹f«´°åç ~5 Ž ¯Ö?¤ÝyóÜVóZ$„ìdBTôNµ’ÈÒÙÚ¼äz~¿¥B¾ä¸ßsËC4­žå”œóíê=?¯35©ÜzÛÿJ´ö*0b08ˆÀííUY/C“*¨è5Iõfn+©ú¹a«´SFTcœtëÓ§ë[w…„Ѭs .«ÒFö¯ùé^ynÌîIB²Žßu¸Èý9ÍIÙAÚ2¿Nk‰A=O²æHí¼ëMJÝ­ÙÄ›È%J‚1ê?Ïzƻѭ *¯m ¢œ†Aÿ{uýEsö÷òÙ¸h®m¬ªCeÈýEtÚeòêh¬òä„íÃwϦ?¥\¡8ì FZسiyH¢UùØ9ë_ð©äV¹F¸œåG| ¨Ï=…ʇŽ6…Æ®H=úþuCP…qOÌ¥X©8ëØõï\ÜíKÞEÚËMŽ‘#1Æ+”ýâ åOùõ÷¨ßSqÂÀìÏͱÇ~W9ms(Szœ «ª€p;ÿžõÔRfdo3r’I‰~lŽœžµËV·&’FñŠfìú£Dp]O9ÞH¶}?úÔ ¼:¸Þcsœ‘ƒîNÕ‚n.ŒgÌXrAysï×Ú™ÍÍ‹pÅáæèŸ½a*ÊKcU«=NñƒÙCå¤aÔõ’Gœ}8éÆk8x†[¹7ùlÑœîÂ8ãòý+’¸¹–]­º>n:àg§sÉý}j ;Ç‚@$¸&#ågéþqúW“*Q»Œânç³=-j ¢Ï€;‚¼tÈçÿÕQU-¥-à =;`Îp?q‹ªIˆUÂŒíȶÿ=½h’ÿP¾ÝÞBƒ×½9=>ÕÇ<5›åwCŒÓõ=?Mñ,¬†96Å‘´>ñƒÇþ¿2{åiK¬kœƒ…<¸ÎϽyöŸ ºcº»S&v‘ŸŒtǯ=}é²jÈì‹t\€ œíö'Ú¹u†±•‹i5c­½ñ,'î¦x£'nÜ}ßóÏMµ‡˜8‘Kò0¡0sènžµÉËxæRîáɳÜgÿëæ¢ó|Ó¹ D¨qÊôúÙÒœ’v¿™+—cnyf‚_Ý ”IÁc¿{U{¹–@Q‘c+È;²­Ï§N¸¬Xço+Àç$÷ëþqO‹^‰Ké±×‘ÄÿœÖ.Ýõó3y~ð†kiFÒ hKezžqïYÖúÛ:¶’6«dãŸcSj×KutYŽÏõ®ZÕ?Ò¥‰šXÎvP`wÁ#¡ÿ=jã Á|"çWÕž„··Ê±ÈÓ-Âgil޾½êh¼O5£ªÉ/»(“†ïž=ó^;®ln¼¹WS€¯Œ©^ã'Þµm|qqÊFào qß“QÖvoïØ™3ÕdñÑ“çG_›?)˜Áä9úU(¼[%ÁrbDZaÿÖ¯/½Õm¤`ñ³£daN Ÿaùv¬Iü@"pÉ*íq\…ìF:sëZï­8Ýy [î{cøÖîaÒ¤ô~ýNyéŠÇ—ÇeÂ+¢£1û±ü»ºþý«Ê¦ñÕÂHæêw™ÈÊ9%‡¶Nyª—!þÑ•ä2)ÛÉ'©öJúúg½xñÖðÄâb¨¹Æü~•ZóZ[ÍŒ±r!äséÁ?­z§ÆÏFdê[C×uV^K¦Ô5EŠqk3•ip Âgïœ`f¼i<[7ˆ¼MyªÊ9.fܪ[vÕÀ  ‘ÙGµq?55Õ´½>ÉÁS-Ú¿ï°¬¿Ö™á­zÖúêH˜´1¶ß*\#têNG¿µy™µìycvuåø¤± ;-­æzxÖ#¹ñŒ/Éö„-™0#Œöÿ>•êW··1çȘä¶p¯‚¾œ÷¯žî¥{}VÆTmíæÇŸ,zöõÿë×^¾#NæHân »Œäzƒõ®ž„#‡”Z¾¦ùÅFê¯C²“ÄSXñÉ4nœíf#¿†?•jXüY’Ù6ÝBfLcy”Ž1ôç¹æ¼í¼N× ‰ a²>c‘Ž}Ç5‡¨\FeÝÈz’G§CÓëú×ÖJ…{²‹¹ó®­H»ÄúNñý¾¢ÁmfX¹,²Ç‘Æ>ŸÎ®Ý\ÿhFDŃA*2{ýêùri´Ë¿4‰w–9Ïo¯ã]f“ñzëL¸MÆW„.Ó•\nß­sÔÁ(Gš›ûÊX•xõë­>ú$>\` åz vçôúVÜy»§âä• ¸ç€3Å&‡ñŸDÕ Ò‹b|²²)ÝõÝÿêÍw–“Úê–ÑH­ ÄDgå|õôÁ>†¼öÝ=$Ž¥ij“µ½z-ãÔrDQ!1+°n*Ã‘Ž¼Šý`ýŸ5(µ? ÙL¬º(ηcZühñmÿÚ~4ëðC—_¶Jª­ó}ÐxÏ  à{Wê/ìc¬\]xfÙY%EÂvH¸ÇùÀüëå3ºj5iVïý~¦¸ ¾ÒzŸõùfÀà Wæ×ü3áeηñÁZ¼1°‘%r™Ïñ€N{í¯Ò}1·Æ21‘šñÚËÀð’xúh¢ =º¬ÉµIcµƒ u ]2M*Xˆý—ø=; %)Ï?´ÎÛ+"D»€ÂùA©ã°÷¨µ;{WšÝˆ_™dmœŽ9ÎkRK5O66YqÉíœûž•ç…#¹¢T.Fr#ðS^ú«Éfηk4qRY[6ð¡K}܆ݷ¶ª76)ï*cäŸ^;ãüýkª¸ðí¬+ž²’H–6àCŸqVaÓ@_–BG#hëŽ:V«ã»1t“zhpÊÐÉ &ÛÊ$œíÆ8Áý:Ì’ÀI"•žA<?OóÒ½9t¨nÕñ,[Ôõ ׎Þ{~už ¹ BÄÑ+—rƒŽxÅ_Öt¢yi³žVd—ÆÜƒÇüW ñOA‚ÿO‹QŠÑâ¹…öËcvPôçàãó5îמš8„/°'®p1ùsÿꬫ­Ê»­Ü–}}±Æ´–'»9§†S‹ì|€Îm¤‘|¶Á §¨ãŽò¯Aø}ã6·“û;QqäÊ6£KÆÓÿWåSø»À/g«¾•,‘­ùO2ÎêG!L[ÏÊÇ»uÎqøyÝͼš}ÃÁ*ªÍŒŒFFvœ~\~µ·»Q;8:rqg«x¿Â–QÌ/¨‹«l^œ~±,þË$ ÆèHÈÈ\‘×½Eàÿˆ)iÒõP×6;FÍ„„œñÈÈéZ·ZTøMlêdV…²9îåøRÕhÄõÔØÓ­–í¹Ü9\wÆF2{Q&•"‚Q@¼AÆNzâ©hR­®£ 3Mû6ŒŒà`ôã9È®ÓûBûá0 gq'°ãëOÛrnJ„Jz-QÆÜX™ vŒ|»ïUZ9c NQ23•Çøúæ»9-å·. pTÕØÇ!eF ä§Fç¿ý¯D\ðíõÔãÙU¢Œ0dlÁ—#ùãÓŠŠ8QÐ:©ô(3ú×K}¦ÆaýÔoÇzàóÛס?g®œd–"AõvÖº#UnÕ̽F}è5ón8e<å³ôçÒ¥µÔŒ«æg ‚AápzûöF[,EóI,NN[Øsþ}+%n%G>Reã%zõàñï[S¢Ó»=™Nèêg3N‹ù:ý:ѤjÒØ³‘&Ôãp!¾lwãOÔJv‹ÜF €†VÀROž=qÒ¢¼´o<ÉíŽ>aËsßJë•-#5>Çr×PKd$VóT’¡†N=þµEeh¾C„\m#ðçÒ¹{b[·q1æ,œžzàŽ;~^õ¶÷‚þ%•9@]ý½³ÿׯ>¥.[]htFm— Áˆì}¸$…e~ÜôëŽß•TKs½~u,¸`nÉú÷¨'i¡}…Ë£p cÛ·ùÅBo€“ìü`D›¾aÎ1óþºq’³fû_ÛI/Ù¥hÔ/#+÷zþª)¥H¦‘·vÞÌ8#üŠÌ(g*nñÂÈr}º÷j¤­5¬¨¢²€A3þy®7„ƒÙ›¹»šn̬J̡۵O#?ýn•Ž@crI—«qE´Ë*•·u†#ÓÞ¨i*–IH£cƒ×§­sÏ —º56ÙÚÄŽ#ÆS’Èr¤õŽ=ê”ÓüÁd…Udû¸?xŒÿ×ëV6Ù€Ùp²c¯®Gùü)ð¢´E<­¤pTszã–['÷–ª_¡^9 ,’˜ü³ŽÌqOoj´ÒÜ-¨KGY¶Œ®sŒõõç½A6« >ÂÄòpN1޹ôüª[e´Ë3ƒ!—ÿ>•ãâ°¼Ú¨ýÇD*y”±¨±smR)è[8úÔÖzÊÏ+¨ Ã%O$Àºvt©¢ZëÇ!%@1•##ÓüŸjÀÔ<96–D~Cí ÌʧŽq‚0yçõ¯6ÔÝ£&½M$½äM,‹"‚da€X†$ÇÒ©Ëh’eÒGnx߯F?úÿËÒ¤ŽE2Êb+÷ËaAÇù5d‰a•U·d«‘ßr£hïÓ×üv`ó,%ElM?š8ñzðþâx©øœl†× †8PÎHÀ€;õªUø¡c¨9I#A¿ï2¹ùOýóú{Öï‰?f]OKŽI,n Ò€q¶#œp:Ž;õ¯*×þ뺮·eÀÁ˜DþüôëjúzTrÌV´fÓó<*¸œuŽ:‹½Ú ·@y'xìqÔš’ mû˜ÙGE*Oï~òã¯wyhHóe‰Á¹ØÒ¥·ñõ©i2 ýàå³õª–YR—Ã+¡,Æ-kÈÚÀs³#qä:o^sR5ÜSVã§$:öèç^Gkã+˜Ù<ÕËœ`ãüþb¶¬uï0î.£9}¾aaÆÇüöç–pW”Q¼1´æ­Ìv3<©(1"‘“œöϧ {ù¡GõÚ àŸóŸþ¶+^•]Ë Ëð¤ tÏéÖ‰uä°Ÿ ­Ó¦óšÎ7¢i›¹¦¼8õ$I²ÁÑI$¬oÆ1סüªôicq hnÞB@X¤õéÇLû×/.¦$ŒïÙ(Vþ,nü^Ý}é‹1‡sÄ äžWƒƒšé‹’wæü ]EGâ—Cy1ܾ`%bã ã¿>õ–3’Ñ©'kvßåþeáß4¥.g+o·Ï¸ïøCž#Š{ýÎ{­Ël²Iq"–|Ø\áöÍmA¨%àNK!åˆ8ÎIé__|Ñ,ô Ç,;mäUów€w |ßÔWËß¼/iáO‰úݦŸòiåÖê›q"† Ø9`°®Ÿ3–'**)uVÝÛ¿vucðO MUsr{;ì½;#ÖGþ°2‚C)Éëœ~"¤—V·¸U,ûºFwqžÝ;ŠãÚñˆÚê¹äà18þTw”PBªŽ1ùöÿõ×Û*©|KçÔð9ú#§kˆÀPéásÓŸóÒª8óæ""AÆ6ž¿ZÅ[Ù!@ ’Ç’?)ç±üúTË©dÄ› # ùþ·º£:m];Ïuv>îÝ×EÉ=yéÔ’Ã[¾Ò.ÃÛÜÉo*¾’} :{…“`‘•“Ë|véYw³NÇìÖqîŸ8f<àã¦?úõsön7¶Œi(.dìŽçRøÆ{§”‰Zg‘ÉÉ$ž1ëúWëoì…ñOÃö>°™£ÔÐ5¼-#G§\M 7|Ëzæ¿:µÙ£ÅÑx+TñCiÚŒi§Æ²\ ‹Iq"3+c@`NxÇ^—öqøËâ†ÄÚWdÒ­âš6“N–ô›y°Àc'ýÒ@Ï5ñ™žºvŽñþ¼ÍpX™aæÜöŸ]ÿUÜý©ðÄÏ øŸþAúÔ¸\˜ÈhÜsŽU€#ò®‡ÄÖÖ^ Ѧ·3,ŠêAÚs_6|ñïƒim¤ñ¤ßê‘©ŽiУM‘‘þ±pÝ1ß½z=Ïìߤ[ÎgÓ#|9¼Ñ|_«G^Ùî¥te*_1¶ð¶sÇzå!ÑãVó%µU¯F}úÓüO¥{ßÅ ÉámZ{bMk*ãí6á%T]”á|àsÛšóû…³¹Ÿ2¹-ƒÉ#|öüê)b›‚Œ¿Þ”9½î‡ÚM¼“î„t®x÷îjæ„Ѱ—ïÄ?ˆÓß5è¿ðŒ¤©¼H¥º,z~gšyðª"²¾h\í>kU‰Ž×#Ùëdy+hÏ3|‹—Î98ëÔã§z-ôÝFÅÏÙ1—Æ2{m?‡B+Òo4”¶Ì5È#ðéÇoçYRi©¶Á¹;¶‘íMWÑÙ‡+JÖ9v¿[€‘Þ[å^¤|ëøzvèjìk ôÜGÜà“ž½±õ®¤Ú‘À$à|ì¥K&uÊ%È ‚2:toÊ—¶×³&ÊÚñ³áÚ׆$¾Òíž]GN"H@u 8;ˆí“P|ïnö^3±ŽÃR”Û]Ûåaš0K+z7¨ã§·jý’ÈDìnD;H;S9çÛñ¯‹iŸ†oà?G®iOr¶IJÊÈW Û· 8ùƒd gå>•ëàq|ÏØÉï±âfXkÇÛG¦þ‡ø—Á÷þ™|òÊFÙÜdm“Œž$céÅ7Cñ,úZl lÍ–…Œs‘Ðý+©ðß‹¾Úa±ÕbŠî1º9¾hóÔ{ÿ:»{ð÷FÕÍes%¬ŸÝ3¬Š°ð3Óž•ïsré#æ’obç†ZËÄ:­„ñ0™-¥Þ-û ä|§#×<ûW¬K¢Bò»D†Üžv‡Êž½oç^ÿ ÷[Ñ.cžÎõX¤‡†2Tt8Çæ3ù×­ø ÄºŽ¹xtÍE¢[¨¡.[s3d`c¯B.õËYm$ÏOR1n2ݚ̷VжÕYUpbÇáYwöJÌ òœ¨bèF3ý?jìÿ²O˜À®]p¼Ž·l~^•R}.^|Å^2£aÏáŸÃùW¶Ž‡®é·Ô⤴•-€ù°ÇF9>¾ªˆ²…ÎÐ6ó®Ê}ÌÊë¾7ŠIÉÿëTqé>b}Û]Ñkª5™­Ï©­‰‘ ýâ¨$0ê}}½)·ZU½Â$êáf#æ]ïïUÅ©E`H 9'”öéþy¤„œnÈ逬NN=1Ö¾·ÙÆ/s;½†%•Äxrý°/Lö#¿~kBÞ602ù¤ªŒ£îôÙ¤¶ ’ —…Fìƒß>àvþu0™X¶Å!ƒÀç${qÓ¹ïÍ9Ôè8ű–ºj¼¥eo'€PíÜ3ÎFzc§åW­- )4¢1æ3è}2?Î)lm"¸„Ÿ2òèrNz · ºH~m»¹Æ:¯ùõ¯:¥^‡D`Ñ!Ûöwávð 89߇ëU.´°<©6«)9ÞOÒ¶#G0@€tñþ´ø­¥T˜¼¶|¤àП§Zæç‹Ñ8»Ok2¡éŽ9 8úzÔW]ìË Ÿk`ð¥ ÀGøWCyhc€ ˜·)ÏQŒzÖk*G6aPêOÜ=>œŸBzV~ÑlÖ£Iõ x³*ÆË²B¹$? tƒÉûË&ðv–_óÞµ<±æ¯ˆ‘¸,›ÉÁÏ=¸úûñZ‘[¤ÖȲrœãú‘\µR¾‡8Öì›w GéÏ þ½i$Òf˜!]˜'”cžüvæº?°Æ YY‰ÎW…•{‰ÛÓüŒ -õ-eŒ6R«•9ÚïŒ7`?ÏzغðÿŠì²%Ñ.e%sû”.#Œ'‡_Jçdð–³i"ŸìÛ ¹£l}3Ž{þb¶tmcž—u­¬ñíÀæÜž2IíêçWY8¿u%ë ©8½*9'÷þðLyµ›€Ù{b¥~m¼ŒsÈäuâ“þë­Î¾FS°zôççë^Í¢þÑßô‹an¶Iuî³$þÁíTüQñ“Äž9‚(µ¯Á~cN ŠXØÛ!‡ 5ç{Y©YÒMyI~©.•;^ŸÎ/þ å ☤B²Ç Û–ùOOsÈ¥ð÷ŠgÑVK¨5)£ÝlEr¦Ççý+ZÿF‹RDh< ub„‚¦ g ô8Ëÿýjæ.¼¯™%{mQÚ¼|ÑäŸaÏÿZ´—±­ i~í› õ0ÕUK)ïüßG¡ê:oí]âë 9-šæ9°…"Ag8ãpÀÞýq^}'ÄGÄÞ$º¿×n“Îwçîàöç ~µŽžñ ²îmùÊg…·sß§ÿUIoàM™£ŸCÔTÈU{yçŒg+Ò§C…Ÿµ¤’—} êãqu’ŒÛit:Q¢Úd'oާÐÿõª&ºXÙ¾}­œä¶qÏqŽÕJ×á§‹LAáðö¡,|¹aÀëž™ü>µNóÚ®–„ßé×VYç÷‘•Èô¯gÛQ“i5é¡Ç'5¬£cwÍyœ6äb ù¾÷ùâ ½¾·´gl®LŸÃ¼œW6¶sÊJZFd8ÆÒ1…džß‰¨µ2óHx–W‚pê>@Ä”É#QúJÑʛѫ2GÑrø®Þ!û¡3>8ß÷@ÇA­{7À?è¾,Ò¯‡éÔ¦°õ#{^ÍþGêÆ‡W:ׂ5{<ÄÚÌ–í$J2@ (éÓw_ZüÙÒiUÒ5)´èSéšœ?$ÒYÈž>\ñÁ¾s_hxWþ ¢xDD´ð–¯=ÁŒn3¡MÛG.N+à¯Ú¾ËTøñ+Sñ¢xtéiz±E$0Ý “¹"TîŒp€qéõ£õ •ýŒå¤—{Z_ðOjynoG ëN‹´vv½×ËSé¿ ø‡Kñ²O êPÝ&y*Fyé]\7‘wJ¢P@.9íïÓõý+òÒëGe”,îRöüÏzî<)ñ»Æ¾ µØkX·M¹†x£•p£’2Њõ+d3Jô¦¥ë§ã©áC4‡3X¸µóÿ#ô˜ÙA-¸xÚBñ’xäõ«ÿÁÐÜ8’(Ü;Aã9ÏuÍ|¡þÜ^*Ó›mþ…¤_Æ£ y!ž9$–8ééô¯NðçíùáíA‘uíþÁÉÚÒÚ•˜u럗ù~uãTÊqÔ}ïfÚò×ðÜôaÃTÚkç§æz”úՔ̘\rpTqøúúT?`mÃÌÀ<’ÝN?ŸëUlj?„ –4Ä⠤‘qgè9Ñ.oçÓÙõˆ ic»†çÊxö®~|åX r3èGZòïٷᇇ|[m5®µ¨]érHÅadgŠWËå¸'ŽÆkîp¸Å‰ æ÷®|f/ðÕlŸºöÁæ®6ã g²kÒ¿eÍKQñ¿â î\ ˆEÄò E`¸+8éEzŽiJÈœ5%»“—K;w¥ÜZnÁ¾â£usŒÕ`Êp·hƒ²˜·øâ½ZêÎâC¼`à¸gƒßñ5I´ë69h#'–$ŸïWOÖšØÏ‘=ÏKƒHŽV òŽàQr?´—ÂP¶æ¹'æb#Ï\óŽOµ\K$+¼#8Úƒ'Ÿÿ®­ÚÇ$S(rY:œ`p3_¢U¨Ö¨ó£N2ÑœŸökZ’¾A;NI#`×ñíW´Ë ʲ”ó3¶6eÉÏNýø®§SÓÒéC(ʸ¾ ç=ûV ‹kA0Xü©ÎÕ˃ùŽGZæuù¶‚‹4§²‘ØF€wVsëøþu~+ä¨o÷qÁÇ_Àš¯äO°fI Å[é×=¸©Öá£`ñ|¥ÀÁ\×$ª_Fu¨–n,dˆŽ=§ïsƤ³€2®÷ÜÓ“ÞÄdqK êÄ•BÊ2ùî>¸>õnÚ52/ÝŽFsÉçŸëÿ×®*­ÅÞ,Ú lR¹‰am³B è¹é\~5•5¨Z•JKœCíúŠëdÒª[€ã~â1ôü+2âÈE#,–̈znl¦¡?JÁWÓV?fcØS¸H6HÄᆞßwÿÔkz=6˜ ‡Ë';JléÏÒ³îtÙEšØ\*+|§Ü~¹¨¡3[Éû²À·bý¿Ïó¬¥W™^ ¥Ô–mï,nTRH r>¿¯çQ[¸Ý•`Œe8?JoŸ,ŽKnܧ 'Ÿo^õ=¥òoÄð¶qćúž8þU—´r^ó/•-‘£ef³@PüÌNGÌ£½ºqïM¶¶xÎBì+Èf8àž¸ü*ä $Ÿ2fBvýÜ ¹î=+J 0da…Q¸2’NÜžß­qT’h,ÖÆ,öj ¸O%øa9^<Z¯ý›%¨T1me-†Ï<ú}}k¯ŸIŒÆ^9PÉ–Ê8?ÿZl6Þl{gäù'Ž¿Ê¸e7cE®¦>œ†Bçl`€®z7×ÒºM;T{]è~eÎ6HãúôõíYwZ{[¸e· ‡«n8cØúçð¨ÁufS€¹ÚèÝqq\µ6¨Ö.ÛššŸˆFYô«t9`N{œ‘õÍgZÜÚͱfXâ8 7}:c?ç5rŠX–+ŒJ„ØçÔóL“L‘ÛbȾY8XòH'±ëŸN+5%²˜ÙtËYyl­¸þ?íÓŽ½ê3`Šw;—#%3ÍOmtúfA‹tcåÉ< óÇçëZðÝi²©M¯#œgnF=úÖ„[-3/tr"C.XcålsŒçõ©çÐDø{v13…p:wÿ³qkkm$jÌ€óµOËÓ©õúU‹[ó—j‘œŽ«Á®¦–Oc’›M¸´‘#‘]X|¤íàŒú}>•rÛJ{µxvà|Ä€@ónÜWQqwk¼ ôYlUœ:ªÆvŽIãÐäñY÷V·VûetnÓÎ;}k)ͽ[cP‹ÝÕ§Â/ ´ŸX³/%¾Ë ã‚)Ÿð­<;o!hü5§$xÆß± _ÀÇ\þuÕXê¿q·dOÊœ²žsÀ®‚mµÜbØqÇQúW$å'kIš{(%±çÖß |;xÈÍ i1É×kÙ¦OAÏËô­~øjÝ>ÒZU<°µLŽÜqÅvSiŒ‘•NÞ¨ÈæKeJ®G÷‡óPá)} PŠÙàømáÄ™e5„*G¥ª*ûñƒõÍGðOÀì/ ÷†4{íàXÂÇëµ×Åå¸>T½qS¡ÿõUˆfT*»»¿^(~Ö©*p’øO˜þ&þÀžñ’,ÚÜøGQCòͤ¤k\ca:}ù¯ ñïükÄSiŽú_Œ´ýJñBÏ¥ý˜““Õ„¬@éÛòïú&fŒ *@?6rGÒ£š¯e¾0‰Á…vQÍq´,£=»ÙþzœËðÕ/Í ýáÅþǼ<­{ák»Ë8ÉÛy¦p¬R lcÔtüq‹ðÛS»øQâ–ŸYðºjÂ?’]7TSSÁåX0z޵ûpúLâÝÃÆ»_ø•¸Ç« WÍŸ?e_|YFm&m*ÞQ*¾Ëœ 8pê ï_G‡â_÷8¸.W¥Õ×õò<йDi~÷=WG©ã ÿh„,Ñ›hþÔŠ–‹N†, ¼â5œŽH'ùú6™i¡x¯Ä6ÚÆ…q¥ê1 UÉãnàyät?—zù§Ç±ÅêX‡‡>Ó´ºÚæ7G\àc,8ãÒ°ü1û%|s¶u óÛMa©Ú#.yV“Ô§5­\³;Ô£‰IÿyßþßréckEòÕ¡÷-¯¸ý$¼Ó Õ´U¶x#E €¾¼½ºWÇÿgnÇ]LJü8Úµ±QçÛXŒÇ'æP§óÏÐu¬-;Vý«þdßhš…’¾KZÛ\ç¨1)oÄqÍnGÿñ/‚-0·“n—¡xžÊg`Æ×Q³™c^Ÿ*¾Ðí’}+Óí|+âñh©«øbâ}Ç„û8gž¸ÍeiŸðRÿ0OíOkV H+ö9¡¸À>ìÉþEmÚÿÁE>j’,sYø“JS^êÆ6\ñÐÇ#NqQSŒw—°’üOª¡ÅÕ`í*—¯ü:FV¡û?ßxáZÖo %dãÏ«‰éƒŠ†oø&ýÌö25¿ŒRöq Æ™”ô„¹‡Â¾ˆð'Å}ÇöQÜè7óÞÂÇ ·²GØd¯¦?ÊïaÕ#óT2ºÈ>Ps¸)#··nj(f˜Ìå§6¼ž¿™áæ.µUZ¼cu§º­úŸœž6ý…¾$xnvk6Ó\¶ãY\¤}»‰6ô=³Ö¼³Uø ñJ/öŸkȈy’>YSë¹^¾õúû ëFW“.xÝœdzTajç ‰³€Wœõ¯n—⢭Q)~ÏO%£/‚MŠ–Eâš'·t%^'B¬1ÇN ÿ"k[þ?ñ„£0èž!Õô(ål²iײ[oïÎÖ¿Y'ð&£†ï¯-5¹£òVÒæÉ”2·-÷z`çw~ù5[öjð½Ö«¦=€k›9ec¾¶ºò<²Ê ¡ …[gcø³Å|åuðÛ^ðy•uû/±ÜÃ0Šh¥q˜É€J’@ÎA=«è¯ž7ñ }ŸÃϨ^Ü[mf:y¸XÎ,À†åÏB8÷®ÿ¨ÑÁÒý̯ͭ$yØŒeLL״нWäq´×ÃOÚ¶Ÿ6¡¨ÚÝÌceXí^5l +8 ÁÉÁ85Ñ~Ä¥­‡ˆuëi#Iá’ÔN7d:ä…çŠõŸÚ_Y×¾,xMåñ‡‡~ݬhÑ’5«x¬öªàçEåÆ]A†ù€ˆ#'>3ûÚ”ø‰­ÛC>œä"ž Å“êzõú×2WÁN=‘¶%‰„»Ÿg\ØhÚì?»hREÀ]±ùl¹öïéÆZÁ¿ðµÅžçR$OvñŽã¯zšêÄ¡¤Œgi!8ÿ¾³ùTCq( .¢‚WÎ:ð={ƾ3¾ÌûN[õä>R¼6›ç%AÏ9Î? Í–ÚѤ%b…G¦À?¶絹³“nAáKžØçƒôª%?•áØÃªŸÿQ®Èí£1’TzþšPùȸgç =°*܈¹åÞ8èºù^ ã¥T%Nû÷Çn9ôÅs·éoi3Ê ÁŽÜ#tïÓóüëô¯hÙ㤯©©f«ulªÄäI$íç‘T5ÿË$m´J$îGÈ =F:ž•VÖõ¡Œ²®JŸ›2XwçŸÖ¶íïC(—-·ºïÜW¿Nzþ„›„´5Qº8+{i>ÜQWç –Wt¹úñúý+nÒy&&FU-Ÿ›+‘È®Oë[:¬,÷Ùª´Œ‘¹'¡¬%…dŒ¤m&òÙûÃ*'5mKƘÊL»Dd!ÊŒdãÅlÙ¤/ûè‹Ã1ÆsÎ+.M?Ë¢K÷z³žþ½kBÁ^62îæ#±®iÝ­ ¡$·6m¤Id{²=psÓüóZÍ¥[j1âxÿyêG# wíÿê¬t³2eVQ±å¢ ǹ<~ TÒ[]%Äeg•£ …mÄz×¥yrKšës¯tG.š-ŸÊTÈ,Ê@.1ïõïQI¥+ðÛÇ£î€qÇ$“‚EhG;1žUn¥³ùg¿Ò–=ëÀ*:£¾O'Ò³¾·#mŒxtÛ‰åcfçÊv¯JÙ·ÒŠ ómŠ¡Îù2¬§ŸlŸéÅ:FŸ`PÌrH##è?§¡e#" åd«¨Â“ÜóÇ5›© Ì–´[6ùSd$ýÀÓþ<~l^ËÈ#ÕprWŽüg'ùV•ÔV––þc“‚G9?(ÏCÍf¶±`nCH ûèG<ãð¬y¥$¶¥›yžuW G*¶>~AîsÔÿJt§Í8Q18' ‚Ïò¥IOùˆÄ~èqǧ§z»0–XÑ¡,œcÁNŸ¦+;6µeTk”t¡àïçü÷¨ÚtWud|cl}=ºþëEP-7@O8Ç?Kžçã &v²/íÁé\–IÝ3]^æD1´lUÂl Êç1×9&¬ý™$Q¹Ò#¡ã¯J¾öM>8‚Éœ•¼ôÿõT°éjÑ,Nv;Œœ“¸úûví\òÑù–•ŒÑg.rÙÏ#Øÿžôõ´1h¼ÂBÌÎ ôäb®]X5»’‡^ŠPsî3ùóW-l|ëmí*H3ò¯©ãŸåùV|í|Cq¾¨«nK•Mådm»ÒNAßçµ=à1$1±^@]½¨q)ÒÚWdÀ<ôÁïÇó©áÔN™•¾öð7)ýzçœû»Üv*ÛÛEw!C€ # ;ž¿_ð©%Ó„ ¾Q·krÏ¥kHÙÝÔäàù=f]ÙjQ\’—\à0‰NGÖ{hê*Ú¬²U §§8ü±šHâkY•â_›¾3œtôéM·žl••ƒ•P2ªëŒjð³CEÃJyÜpx犉ǙhRv/Yë6ü $TcÓ·J»qgææèΣh'åcÇùâ¹ ‹iDŸ*oêX¨Î~¿Ê®ØkdÁ2X®? q´àÄã}Væ“é³B ´`ƒÓ횈XKæ;ÉFûÙÇå[6—ÜBÐryW'#ŽG5^[)4L[íLsôÏÆ¡Êú I­$`+Û¼„å–L㎽zþõ~ÊÎÖYKy’é}ª “̶_1þpß33ãó^ݪ‹G$<,]‰Îõ9—aÏéS(ØÛtt†9"Uî~Ü“øsSÂU³¼¡a•³ƒYZ}ü×R^XtlõÏó­/3dÏ?xÖ£•ÅèfÓÙ—âKYÆ„Œe4K¦‡Æ1€ #ùtª‘dbåÏ÷–®Ã±—yʰÆÿŸÒ®3¾ç,”¢ï6M29ù<ƒúUsc=™Þ¸$H䟥t1y7”‘Iê@5«DdŒùƒý‘Râš½†«»Ù˜ñË)`Ó‚¤±·ó­­â¸L†bÇשªÏRÀ›®råN†µw#ä'€À‘ùÖJš½âìi'u¦ŒmÕ¥Ô ûHïæ1 þ]+PÓZè,©4ÑOŸº¤…Áî23é]I¿I#EWY9=óëUZ7“çBsÂ6 üE7 )h(NV÷‘ÍÃ¥^[&q7d\äÄÿúûÒ^Gê=µÕ½älA)t¡‡QÐö=ë¡bB_pÉÏЦ–ay$›°2@¨œ¥{›'­%s¿ø-ðÿP»û@ð'…æ¸$™ëJ…œ±9<•ç½]Ò¼¦x`<:g‡ô­)’ÊÍ"@sÔmºï++"¼eÈ8R:¨íùThæ8JÉ™>àÀn+ìGùþU¤ä¬äÁR§†+î2ÞÈÞ[€ÊÊùq#'ó¨nô4•Ö’‡3Ø‚¥kÝbL´3€ÅG äýzæ«Jï » @zñÏ¡jk¹£…âYŽDPwsŽØ¦ÞZ:@¹O¼v·SRý¦G‘Šá†z—Æ*Ⱥ¡go´ÀÓ=3šÕ»%rmØÇ3**\yc¤‡¸õéÆ})’[AtÉæ†Y°KÏÏùô©1¶½—j:c'5R{qAex$ýì¡çÛŠ.#k5(Bò.zÿUfj¶R±xü¼„mpØÇ§|Ö·˜ÑÊCn+·s6oSŸóÅ1¥„–ûBˆäæ9êÞ¼×ô¹žkè~\|i»ºµø³®Zx…R ^+…[›kpB${ÄFIëÂyîkÙn&ø¥|/²×<)ã_Y|LbݦIo2DÑæ‘mÂõ$ È2çõO¾xâtqÍâo Úk AHÞàñ€<Ø™\Œ6ç ŽyõÏìaðºk}3QŠFQµ ¢§ŸwÏùú×ÝÐÏé<,(TOÝVèÏ•ÅeÕe]Õß¡ñN½ñ^ñMÄŸi’{¥º9/0ËdõÃg¿¿=+é¯Ù7áUÞƒψu>æÕ. 1Á4ÛTI–R@Bw`íãJõýàGÃÿ É»Oð­ŒFw» tÄŽ„Kü==«µxäX!0ŸÞƒ‚˜ÇáÏáÐW™ŒÍV">Ê”yQÕ‡ËåN~Ö£»3 (»²Šñ7^¹ôü«QЀ}³“!Ïqµ»öü)×WšŒwàMò?#§¹íÍ"ËÛZ7óÊgϾ}?JðuLö¾ín¬#V—‡`@Þ~\t gù°7&&c܆l:êîàšKw «.Ìá× ôúôý g mÞ„íúVþóV¹<Ö'Bd±“»i'NÅL‘•Ëe<)äÇéÒ«Ù³ÈO–v6æ ž‡ôÿ=kRÏö“#–S!˜¸ÇNŸÞ¯×ee±ãÊ<´CÏ“Œñžž˜éбg3 ¶Xù°Ç¿N£§ÿ®­-­¤Ä©|†nI8ïQG‹"ìØŒU#·ùÅsºªÍ3KjONϘܪÿtñ‘ÐŽõ`i²D]›j)FÑøgëйäKd…K©*¸$wéþ5* ”ܬOË»gÄ宎æ©6®`ÌŵeŽUpsŒ’N)ULSaÙcÚpu±Õ±.ºçÎ7"®€'þUa4kYfh%Bø>âyM-A"–›©´DÆX¬lIp˜Ëvëþx­Vó¶Æãk¯PÇœŸp?¥d›uŽkˆ‚€Ð63†Ó½ ÝH\á³Ð÷?þ¯Ö¹%ïü&ñ².‰Ùnªrª¥€P}óíÓÿ¯WÌv×ñÄ!¾dÎ}ÀúVRi‹j¥Œ„˜ò­´c8çùVºÚìl{v¶x|õ¾ÕË%%±¢hl^]¼,±oRƒxˆçõÿ<ÔÖºƒ$žR¢>q¸po|ÿŸEn­Ùv”er§­9!ˆÅ½¨Œà€q×Óóï\®e¤˜¶·‘´R–‹tg#Ë O¾O'Ú’ ÕXJŒc…Ø`!9äßãR „Œ®9-Á`9}zÔ‘ÄaT}û’LuQ Æ=ÿžv׺;&ËÖúb۟ݳÆápNs‘Ó ôÍÏ®Ò3îÚ ù>™íŸóÒ«_¶Dh›`û¬ƒü8¨¼òA°© ·©ýy¬äš)AXÓ‘¤™Õ‡˜,3“þy©-‰¼‘"fC È|p8éÿë¨l5q xÕ e`¬[ ôÇõú ŸS€%¤®ØW] „àäÿJNìEÅXæ@dB%ä+…nzqD‘Inw°Ú[¡=OÒ±¬îت0,AÊüíœñ[–z¹) (r±^ßáXÎ-êÊZ=Þ2ò8Œ˜dzp·ØH» r zú~¡ö(ÖÇ,’``žGJ†â³)#aù¿…ï£-[¡IÙw¸pn9öï“Û¿åU¯Þ†Ý”{u$r:zÔËtY<Å9™YX}àëJšŽ}¨¤ ›óíž”¯(úe"²Êð\º¤³êßrŒðO¶´­‹€ûe\6"9üN9ÿ?®eÍÀ{Yg €ÇåÇk-›È¸äu`æ'ÓééP¥}P¶Ðêÿ³I›æ‘GXÏaLuX£ÝUÄ;Nmø:âÚúÝ„¶‰ç.rÀ’Ϲÿ>Õ³ªxzÒå7˜‘ ¨´Jû’®¡>Y#‹¶’9ÙU«•åßpqJú:´„Ç,I'pd$Âqv÷o¨E’8úÇ ªÊ‘ý± óüƒ†àwàõëšÍjÎÍ$ˆL ûJ|£oAÇ'?çµlØj,o_› :÷ª-–èÉ·jÇ#•ùŽåÐúU`ˆcÞAû½úzÔJ*[µÑÅ”w±·î‚ÊÃïŽ=}Åc­„Ï´Í•`8ÇOOÖ‹;§Œ!Vc» fÈþ†¬¼Ëqð]7v8ý)?vÍ‘¸» b ƒ‹«S0?ĽG'Ðà÷í[öÖš}Ì~tP®ÂËd7Ó­`I-»x@Yƒ’r=½þ´øä’DŒ§§'¡Í ÒWHŠrÕ;2åå£[9ž»×àýp*¶Ó( Gêbzó[zf£öñ"ÈYTãŒõé.¬#–VÇÊÀ+)BûF³‹åžæLBâ òß.O‡£kvÌû¤[©aýjŠ©‰ŒlÅ—¦>õöéå—@W Áäu©åpWFÒŠžŒè%†+…œ3 ?ɬym®mÙ›œ¬p9Ç¡¦ZÜ5°VByàó×ð«Ëª¶Ðê ¸àp*\£-YŠŒé;-QI¬Ä‹û¥*Þ õöíUŠP]qæ!íþ©ó]¸lfåI©-¢óX£`®;Œä{Õ%+Ù{G©R ² û¤`’3¸zäý*wŽ)UX)\}ìñ¤»ÓcŽ'x™“q”ò?ʲ‘]7J­³`çút¦åöZ¥?z%ÉÊÆf%¸çýj¡;†Ý±[æræíþ Xï䙊¸RC0[Š£©éö×ež&’"N: tôü+$õètGMÇ<1ÎQÊÄûÊɃ´ƒœS s 2ê$ŒòØÇãŽüuÏó®q¼ËiÉG!”‚Ùô­ QîßÊ!RFûŒ€€;ò3íY8òš'}‹·V…FËv ê;Up`%d,?.܃ïŒã§?‡µY’}—`>íäò·8ÇéÞ¥&;¤Ì¨~éùs»ê=+i-Kåº2ÒdbSæÛ•Pé‚y㊰’88Wó3ø0üŠP±ŽÝ¡ ‘ŸN¸¬™%D'ËFK•ùyÇ_óøé&´Z™´Ö¬Ø’E¹rH>j}ÒÈ3ýxëYžO•ó2)%°iß?ç·Ju–¨×÷y€pÃ;OÔg®iI*]°6ð<à:f¡ûÚ1§mЦ`ŠB°%â>Ÿ§øS$»…‘Rq÷›Œ:qýjH£[åC·hÚÇ€c?Ëÿ×Uõ O³ÀíëžIéëÛØÖN$7õ3µç C"àsÏ_¦k%šx“ÍlYWÁ㯙%Ë39ˆ˜°Ø%N3ÔtÿëÑm«Ï,ÒFüK%áLô­âô¶6ý'_.XV\wQÆ}¿*¡¨éH#1DC’wç¿z¥q©4˜6ýÒ¶<Õspó°HÁÆ{sW"÷"¸K» ²<#øBà¦;`Ç^¢²Íä„äìcë±›?Ž+enL–ŽÆ0>NóÏ{Uw‡.pªFxÜI4]¡ZúŸÿÙtango-9.2.5a/doc/src/dance/Ready.eps0000644023471100065110000000567013034745265014132 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: Ready.eps %%Creator: fig2dev Version 3.2 Patchlevel 1 %%CreationDate: Thu Feb 3 11:33:07 2000 %%For: taurel@amber2 (E.Taurel,,,) %%Orientation: Portrait %%BoundingBox: 0 0 468 59 %%Pages: 0 %%BeginSetup %%EndSetup %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save -78.0 222.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def %%EndProlog $F2psBegin 10 setmiterlimit n -1000 4522 m -1000 -1000 l 9652 -1000 l 9652 4522 l cp clip 0.06299 0.06299 sc % Polyline 7.500 slw n 1260 2610 m 8640 2610 l 8640 3510 l 1260 3510 l cp gs col0 s gr /Palatino-Bold ff 360.00 scf sf 1530 3195 m gs 1 -1 sc (Are you ready to dance the TANGO ?) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/java_api/0000755023471100065110000000000013034745265013125 500000000000000tango-9.2.5a/doc/src/java_api/Makefile.am0000644023471100065110000000002213034745265015073 00000000000000SUBDIRS = picture tango-9.2.5a/doc/src/java_api/Makefile.in0000644023471100065110000005040513034745265015116 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/java_api DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = picture all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/java_api/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/java_api/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/java_api/picture/0000755023471100065110000000000013034745265014600 500000000000000tango-9.2.5a/doc/src/java_api/picture/Makefile.am0000644023471100065110000000032113034745265016550 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ architerture \ NewLine img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/java_api/picture/Makefile.in0000644023471100065110000003302013034745265016563 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/java_api/picture DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ architerture \ NewLine all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/java_api/picture/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/java_api/picture/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/java_api/picture/NewLine.fig0000644023471100065110000000017013034745265016546 00000000000000#FIG 3.1 Portrait Center Inches 1200 2 2 2 0 1 7 7 0 0 -1 0.000 0 0 7 0 0 5 300 300 1575 300 1575 600 300 600 300 300 tango-9.2.5a/doc/src/java_api/picture/architecture.fig0000644023471100065110000002032713034745265017675 00000000000000#FIG 3.2 Portrait Center Inches A4 100.00 Single -2 1200 2 6 1627 75 7413 569 2 1 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 2 1698 498 7342 498 4 0 -1 0 0 18 23 0.0000 4 255 5745 1627 357 TANGO Java API Architecture\001 -6 6 75 3321 2121 4943 6 75 3321 2121 4943 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 3814 2051 3814 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 4238 2051 4238 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 146 3391 2051 3391 2051 4873 146 4873 146 3391 4 0 -1 0 0 18 13 0.0000 4 105 480 851 4097 name\001 -6 6 357 4308 1768 4732 4 0 -1 0 0 18 13 0.0000 4 180 1335 357 4520 get_property()\001 4 0 -1 0 0 18 13 0.0000 4 30 1020 569 4732 .................\001 -6 4 0 -1 0 0 18 13 0.0000 4 135 720 710 3673 DbClass\001 -6 6 75 6848 2121 8471 6 75 6848 2121 8471 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 7342 2051 7342 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 7766 2051 7766 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 146 6919 2051 6919 2051 8401 146 8401 146 6919 4 0 -1 0 0 18 13 0.0000 4 105 480 851 7624 name\001 -6 6 428 7836 1839 8259 4 0 -1 0 0 18 13 0.0000 4 180 1335 428 8048 get_property()\001 4 0 -1 0 0 18 13 0.0000 4 30 1020 639 8259 .................\001 -6 4 0 -1 0 0 18 13 0.0000 4 135 855 639 7201 DbDevice\001 -6 6 75 5084 2121 6707 6 75 5084 2121 6707 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 5578 2051 5578 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 146 6002 2051 6002 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 146 5155 2051 5155 2051 6637 146 6637 146 5155 4 0 -1 0 0 18 13 0.0000 4 105 480 851 5861 name\001 -6 4 0 -1 0 0 18 13 0.0000 4 135 855 710 5437 DbServer\001 4 0 -1 0 0 18 13 0.0000 4 30 1020 569 6566 .................\001 4 0 -1 0 0 18 11 0.0000 4 150 735 639 6425 put_info()\001 4 0 -1 0 0 18 11 0.0000 4 150 735 639 6213 get_info()\001 -6 6 1909 1486 3532 3179 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 1980 1980 3462 1980 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 1980 2333 3462 2333 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 1980 1557 3462 1557 3462 3109 1980 3109 1980 1557 4 0 -1 0 0 18 13 0.0000 4 105 480 2192 2192 name\001 4 0 -1 0 0 18 13 0.0000 4 135 825 2121 1839 DbDatum\001 4 0 -1 0 0 18 11 0.0000 4 150 810 2192 2544 is_empty()\001 4 0 -1 0 0 18 11 0.0000 4 150 555 2192 2756 insert()\001 4 0 -1 0 0 18 11 0.0000 4 150 660 2192 2968 extract()\001 -6 6 3673 3814 5931 5437 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3744 4238 5860 4238 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3744 3885 5860 3885 5860 5367 3744 5367 3744 3885 4 0 -1 0 0 18 13 0.0000 4 135 840 4308 4167 Database\001 4 0 -1 0 0 18 11 0.0000 4 150 1560 3814 4520 get_class_property()\001 4 0 -1 0 0 18 11 0.0000 4 150 1650 3814 4943 get_device_property()\001 4 0 -1 0 0 18 11 0.0000 4 30 855 4097 5226 ...................\001 4 0 -1 0 0 18 11 0.0000 4 150 1305 3814 4732 get_server_info()\001 -6 6 4590 2827 4873 3885 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4590 3462 4873 3462 4732 3179 4590 3462 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 3462 4732 3885 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 3179 4732 2827 -6 6 3885 1204 5790 2897 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3955 1274 5719 1274 5719 2827 3955 2827 3955 1274 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3955 1698 5719 1698 4 0 -1 0 0 18 11 0.0000 4 150 1020 4026 2192 set_timeout()\001 4 0 -1 0 0 18 11 0.0000 4 150 1020 4026 2403 get_timeout()\001 4 0 -1 0 0 18 11 0.0000 4 150 1065 4026 1980 reconnection()\001 4 0 -1 0 0 18 11 0.0000 4 150 1290 4026 2615 command_inout()\001 4 0 -1 0 0 18 13 0.0000 4 135 975 4238 1557 Connection\001 -6 6 287 1486 1909 3179 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 357 1980 1839 1980 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 357 2333 1839 2333 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 357 1557 1839 1557 1839 3109 357 3109 357 1557 4 0 -1 0 0 18 13 0.0000 4 105 480 569 2192 name\001 4 0 -1 0 0 18 11 0.0000 4 150 810 569 2544 is_empty()\001 4 0 -1 0 0 18 11 0.0000 4 150 555 569 2756 insert()\001 4 0 -1 0 0 18 11 0.0000 4 150 660 569 2968 extract()\001 4 0 -1 0 0 18 13 0.0000 4 135 1020 498 1909 DbAttribute\001 -6 6 6002 8401 8048 9529 6 6002 8401 8048 9529 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 6072 8471 7977 8471 7977 9459 6072 9459 6072 8471 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 6072 8824 7977 8824 4 0 -1 0 0 18 13 0.0000 4 180 1650 6143 8753 DeviceDataHstory\001 4 0 -1 0 0 18 11 0.0000 4 150 735 6213 9177 getTime()\001 -6 -6 6 8048 6778 9882 7907 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8118 6848 9811 6848 9811 7836 8118 7836 8118 6848 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 8118 7201 9811 7201 4 0 -1 0 0 18 11 0.0000 4 150 555 8330 7483 insert()\001 4 0 -1 0 0 18 11 0.0000 4 150 660 8330 7695 extract()\001 4 0 -1 0 0 18 13 0.0000 4 135 1395 8189 7131 DeviceAttribute\001 -6 6 6072 6778 7695 7907 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 6143 7201 7624 7201 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 6143 6848 7624 6848 7624 7836 6143 7836 6143 6848 4 0 -1 0 0 18 11 0.0000 4 150 555 6354 7483 insert()\001 4 0 -1 0 0 18 11 0.0000 4 150 660 6354 7695 extract()\001 4 0 -1 0 0 18 13 0.0000 4 135 1035 6284 7131 DeviceData\001 -6 6 3525 6525 5925 9600 6 4590 6566 4873 7624 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4590 7201 4873 7201 4732 6919 4590 7201 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 7201 4732 7624 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 6919 4732 6566 -6 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3814 7624 5860 7624 5860 9529 3814 9529 3814 7624 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3814 8048 5860 8048 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3814 8471 5860 8471 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3673 8824 3532 8965 3673 9106 3814 8965 3673 8824 4 0 -1 0 0 18 13 0.0000 4 105 480 4520 8330 name\001 4 0 -1 0 0 18 13 0.0000 4 180 1140 4097 7907 DeviceProxy\001 4 0 -1 0 0 18 11 0.0000 4 150 435 3885 8683 ping()\001 4 0 -1 0 0 18 11 0.0000 4 150 1665 3885 8894 command_list_query()\001 4 0 -1 0 0 18 11 0.0000 4 150 405 3885 9106 info()\001 4 0 -1 0 0 18 11 0.0000 4 30 1215 3885 9318 ...........................\001 -6 6 3750 9450 5925 12525 6 4590 9491 4873 10549 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4590 10126 4873 10126 4732 9844 4590 10126 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 10126 4732 10549 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 4732 9844 4732 9491 -6 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3814 10549 5860 10549 5860 12454 3814 12454 3814 10549 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3814 10950 5860 10950 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 3814 11325 5860 11325 4 0 0 50 0 18 12 0.0000 4 180 1305 4125 10800 AttributeProxy\001 4 0 -1 0 0 18 11 0.0000 4 30 1215 3900 12300 ...........................\001 4 0 -1 0 0 18 11 0.0000 4 150 405 3900 12150 info()\001 4 0 -1 0 0 18 13 0.0000 4 105 480 4500 11175 name\001 4 0 -1 0 0 18 11 0.0000 4 150 435 3900 11550 ping()\001 4 0 0 50 0 18 10 0.0000 4 150 450 3900 11775 read()\001 4 0 0 50 0 18 10 0.0000 4 150 495 3900 11925 write()\001 -6 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2192 7413 2051 7554 2192 7695 2333 7554 2192 7413 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2192 5649 2051 5790 2192 5931 2333 5790 2192 5649 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2192 3885 2051 4026 2192 4167 2333 4026 2192 3885 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 2333 4026 2897 4026 2897 7554 2333 7554 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 2333 5790 2897 5790 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 2897 4026 3744 4026 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4 0 0 1.00 60.00 120.00 6495 5084 6213 5084 6213 4591 5860 4591 2 2 0 2 -1 7 0 0 -1 0.000 0 0 7 0 0 5 6495 4732 8400 4732 8400 5719 6495 5719 6495 4732 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 6495 5084 8400 5084 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4732 6566 8824 6566 8824 3109 4732 3109 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 3532 8965 1063 8965 1063 8401 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 8118 8894 7977 9036 8118 9177 8259 9036 8118 8894 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 3 8259 9036 8965 9036 8965 7836 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 6707 8259 6989 8259 6848 7977 6707 8259 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 6848 7977 6848 7836 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2 6848 8259 6848 8471 4 0 -1 0 0 18 11 0.0000 4 120 270 6002 4449 i...n\001 4 0 -1 0 0 18 13 0.0000 4 180 1590 6566 5578 Database Objects\001 4 0 -1 0 0 18 13 0.0000 4 135 1425 6707 5367 Static Vector of\001 4 0 -1 0 0 18 13 0.0000 4 180 570 7130 5014 ApiUtil\001 tango-9.2.5a/doc/src/java_api/picture/NewLine.eps0000644023471100065110000000551513034745265016600 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: NewLine.fig %%Creator: fig2dev Version 3.1 Patchlevel 2 %%CreationDate: Mon Mar 5 14:54:29 2001 %%For: verdier@carina () %Magnification: 1.00 %%Orientation: Portrait %%BoundingBox: 0 0 79 20 %%Pages: 0 %%BeginSetup %%IncludeFeature: *PageSize Letter %%EndSetup %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save -17.0 37.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def %%EndProlog $F2psBegin 10 setmiterlimit n 0 792 m 0 0 l 612 0 l 612 792 l cp clip 0.06000 0.06000 sc 7.500 slw % Polyline n 300 300 m 1575 300 l 1575 600 l 300 600 l cp gs col7 s gr $F2psEnd rs tango-9.2.5a/doc/src/java_api/picture/architecture.eps0000644023471100065110000002726613034745265017730 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: architecture.eps %%Creator: fig2dev Version 3.2 Patchlevel 3c %%CreationDate: Thu Dec 11 17:00:25 2003 %%For: verdier@splash (Pascal VERDIER) %%BoundingBox: 0 0 583 743 %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 743 moveto 0 0 lineto 583 0 lineto 583 743 lineto closepath clip newpath -7.0 749.0 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin %%Page: 1 1 10 setmiterlimit 0.06000 0.06000 sc % % Fig objects follow % /Helvetica-Bold ff 180.00 scf sf 4125 10800 m gs 1 -1 sc (AttributeProxy) col0 sh gr /Helvetica-Bold ff 150.00 scf sf 3900 11775 m gs 1 -1 sc (read\(\)) col0 sh gr /Helvetica-Bold ff 150.00 scf sf 3900 11925 m gs 1 -1 sc (write\(\)) col0 sh gr % Polyline 15.000 slw n 1698 498 m 7342 498 l gs col-1 s gr /Helvetica-Bold ff 345.00 scf sf 1627 357 m gs 1 -1 sc (TANGO Java API Architecture) col-1 sh gr % Polyline 7.500 slw n 146 3814 m 2051 3814 l gs col-1 s gr % Polyline n 146 4238 m 2051 4238 l gs col-1 s gr % Polyline 15.000 slw n 146 3391 m 2051 3391 l 2051 4873 l 146 4873 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 851 4097 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 357 4520 m gs 1 -1 sc (get_property\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 569 4732 m gs 1 -1 sc (.................) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 710 3673 m gs 1 -1 sc (DbClass) col-1 sh gr % Polyline 7.500 slw n 146 7342 m 2051 7342 l gs col-1 s gr % Polyline n 146 7766 m 2051 7766 l gs col-1 s gr % Polyline 15.000 slw n 146 6919 m 2051 6919 l 2051 8401 l 146 8401 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 851 7624 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 428 8048 m gs 1 -1 sc (get_property\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 639 8259 m gs 1 -1 sc (.................) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 639 7201 m gs 1 -1 sc (DbDevice) col-1 sh gr % Polyline 7.500 slw n 146 5578 m 2051 5578 l gs col-1 s gr % Polyline n 146 6002 m 2051 6002 l gs col-1 s gr % Polyline 15.000 slw n 146 5155 m 2051 5155 l 2051 6637 l 146 6637 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 851 5861 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 710 5437 m gs 1 -1 sc (DbServer) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 569 6566 m gs 1 -1 sc (.................) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 639 6425 m gs 1 -1 sc (put_info\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 639 6213 m gs 1 -1 sc (get_info\(\)) col-1 sh gr % Polyline 7.500 slw n 1980 1980 m 3462 1980 l gs col-1 s gr % Polyline n 1980 2333 m 3462 2333 l gs col-1 s gr % Polyline 15.000 slw n 1980 1557 m 3462 1557 l 3462 3109 l 1980 3109 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 2192 2192 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 2121 1839 m gs 1 -1 sc (DbDatum) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 2192 2544 m gs 1 -1 sc (is_empty\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 2192 2756 m gs 1 -1 sc (insert\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 2192 2968 m gs 1 -1 sc (extract\(\)) col-1 sh gr % Polyline 7.500 slw n 3744 4238 m 5860 4238 l gs col-1 s gr % Polyline 15.000 slw n 3744 3885 m 5860 3885 l 5860 5367 l 3744 5367 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 4308 4167 m gs 1 -1 sc (Database) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3814 4520 m gs 1 -1 sc (get_class_property\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3814 4943 m gs 1 -1 sc (get_device_property\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 4097 5226 m gs 1 -1 sc (...................) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3814 4732 m gs 1 -1 sc (get_server_info\(\)) col-1 sh gr % Polyline 7.500 slw n 4590 3462 m 4873 3462 l 4732 3179 l 4590 3462 l cp gs col-1 s gr % Polyline n 4732 3462 m 4732 3885 l gs col-1 s gr % Polyline n 4732 3179 m 4732 2827 l gs col-1 s gr % Polyline 15.000 slw n 3955 1274 m 5719 1274 l 5719 2827 l 3955 2827 l cp gs col-1 s gr % Polyline 7.500 slw n 3955 1698 m 5719 1698 l gs col-1 s gr /Helvetica-Bold ff 165.00 scf sf 4026 2192 m gs 1 -1 sc (set_timeout\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 4026 2403 m gs 1 -1 sc (get_timeout\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 4026 1980 m gs 1 -1 sc (reconnection\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 4026 2615 m gs 1 -1 sc (command_inout\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 4238 1557 m gs 1 -1 sc (Connection) col-1 sh gr % Polyline n 357 1980 m 1839 1980 l gs col-1 s gr % Polyline n 357 2333 m 1839 2333 l gs col-1 s gr % Polyline 15.000 slw n 357 1557 m 1839 1557 l 1839 3109 l 357 3109 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 569 2192 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 569 2544 m gs 1 -1 sc (is_empty\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 569 2756 m gs 1 -1 sc (insert\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 569 2968 m gs 1 -1 sc (extract\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 498 1909 m gs 1 -1 sc (DbAttribute) col-1 sh gr % Polyline n 6072 8471 m 7977 8471 l 7977 9459 l 6072 9459 l cp gs col-1 s gr % Polyline 7.500 slw n 6072 8824 m 7977 8824 l gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 6143 8753 m gs 1 -1 sc (DeviceDataHstory) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 6213 9177 m gs 1 -1 sc (getTime\(\)) col-1 sh gr % Polyline 15.000 slw n 8118 6848 m 9811 6848 l 9811 7836 l 8118 7836 l cp gs col-1 s gr % Polyline 7.500 slw n 8118 7201 m 9811 7201 l gs col-1 s gr /Helvetica-Bold ff 165.00 scf sf 8330 7483 m gs 1 -1 sc (insert\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 8330 7695 m gs 1 -1 sc (extract\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 8189 7131 m gs 1 -1 sc (DeviceAttribute) col-1 sh gr % Polyline n 6143 7201 m 7624 7201 l gs col-1 s gr % Polyline 15.000 slw n 6143 6848 m 7624 6848 l 7624 7836 l 6143 7836 l cp gs col-1 s gr /Helvetica-Bold ff 165.00 scf sf 6354 7483 m gs 1 -1 sc (insert\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 6354 7695 m gs 1 -1 sc (extract\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 6284 7131 m gs 1 -1 sc (DeviceData) col-1 sh gr % Polyline 7.500 slw n 4590 7201 m 4873 7201 l 4732 6919 l 4590 7201 l cp gs col-1 s gr % Polyline n 4732 7201 m 4732 7624 l gs col-1 s gr % Polyline n 4732 6919 m 4732 6566 l gs col-1 s gr % Polyline 15.000 slw n 3814 7624 m 5860 7624 l 5860 9529 l 3814 9529 l cp gs col-1 s gr % Polyline 7.500 slw n 3814 8048 m 5860 8048 l gs col-1 s gr % Polyline n 3814 8471 m 5860 8471 l gs col-1 s gr % Polyline n 3673 8824 m 3532 8965 l 3673 9106 l 3814 8965 l 3673 8824 l cp gs col-1 s gr /Helvetica-Bold ff 195.00 scf sf 4520 8330 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 4097 7907 m gs 1 -1 sc (DeviceProxy) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3885 8683 m gs 1 -1 sc (ping\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3885 8894 m gs 1 -1 sc (command_list_query\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3885 9106 m gs 1 -1 sc (info\(\)) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3885 9318 m gs 1 -1 sc (...........................) col-1 sh gr % Polyline n 4590 10126 m 4873 10126 l 4732 9844 l 4590 10126 l cp gs col-1 s gr % Polyline n 4732 10126 m 4732 10549 l gs col-1 s gr % Polyline n 4732 9844 m 4732 9491 l gs col-1 s gr % Polyline 15.000 slw n 3814 10549 m 5860 10549 l 5860 12454 l 3814 12454 l cp gs col-1 s gr % Polyline 7.500 slw n 3814 10950 m 5860 10950 l gs col-1 s gr % Polyline n 3814 11325 m 5860 11325 l gs col-1 s gr /Helvetica-Bold ff 165.00 scf sf 3900 12300 m gs 1 -1 sc (...........................) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3900 12150 m gs 1 -1 sc (info\(\)) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 4500 11175 m gs 1 -1 sc (name) col-1 sh gr /Helvetica-Bold ff 165.00 scf sf 3900 11550 m gs 1 -1 sc (ping\(\)) col-1 sh gr % Polyline n 2192 7413 m 2051 7554 l 2192 7695 l 2333 7554 l 2192 7413 l cp gs col-1 s gr % Polyline n 2192 5649 m 2051 5790 l 2192 5931 l 2333 5790 l 2192 5649 l cp gs col-1 s gr % Polyline n 2192 3885 m 2051 4026 l 2192 4167 l 2333 4026 l 2192 3885 l cp gs col-1 s gr % Polyline n 2333 4026 m 2897 4026 l 2897 7554 l 2333 7554 l gs col-1 s gr % Polyline n 2333 5790 m 2897 5790 l gs col-1 s gr % Polyline n 2897 4026 m 3744 4026 l gs col-1 s gr % Polyline gs clippath 5845 4561 m 5845 4621 l 5997 4621 l 5877 4591 l 5997 4561 l cp eoclip n 6495 5084 m 6213 5084 l 6213 4591 l 5860 4591 l gs col-1 s gr gr % arrowhead n 5997 4561 m 5877 4591 l 5997 4621 l col-1 s % Polyline 15.000 slw n 6495 4732 m 8400 4732 l 8400 5719 l 6495 5719 l cp gs col-1 s gr % Polyline 7.500 slw n 6495 5084 m 8400 5084 l gs col-1 s gr % Polyline n 4732 6566 m 8824 6566 l 8824 3109 l 4732 3109 l gs col-1 s gr % Polyline n 3532 8965 m 1063 8965 l 1063 8401 l gs col-1 s gr % Polyline n 8118 8894 m 7977 9036 l 8118 9177 l 8259 9036 l 8118 8894 l cp gs col-1 s gr % Polyline n 8259 9036 m 8965 9036 l 8965 7836 l gs col-1 s gr % Polyline n 6707 8259 m 6989 8259 l 6848 7977 l 6707 8259 l cp gs col-1 s gr % Polyline n 6848 7977 m 6848 7836 l gs col-1 s gr % Polyline n 6848 8259 m 6848 8471 l gs col-1 s gr /Helvetica-Bold ff 165.00 scf sf 6002 4449 m gs 1 -1 sc (i...n) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 6566 5578 m gs 1 -1 sc (Database Objects) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 6707 5367 m gs 1 -1 sc (Static Vector of) col-1 sh gr /Helvetica-Bold ff 195.00 scf sf 7130 5014 m gs 1 -1 sc (ApiUtil) col-1 sh gr $F2psEnd rs tango-9.2.5a/doc/src/java_api/line.tex0000644023471100065110000000174013034745265014520 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/java_api/TangoApi.lyx0000644023471100065110000002326213034745265015312 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \pdf_bookmarks true \pdf_bookmarksnumbered false \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle true \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 4 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter TANGO Java API \begin_inset CommandInset label LatexCommand label name "cha:TANGO-Java-API" \end_inset \end_layout \begin_layout Standard \emph on \noun on This chapter documents the JAVA API for the TANGO database and device servers. \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename picture/architecture.eps width 80text% \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Section Introduction \end_layout \begin_layout Subsection Description \end_layout \begin_layout Standard This chapter documents the high level interface for Java. \end_layout \begin_layout Subsubsection* Remarks: \end_layout \begin_layout Standard This java api is based on \emph on Jacorb \emph default \noun on ORB \noun default implementation. The \emph on Jacorb \emph default and \emph on Tango \emph default classes are both available in TangORB.jar file. \end_layout \begin_layout Subsection Basic Philosophy \end_layout \begin_layout Standard The basic philosophy is to have high level classes for the database, properties, device, group and database object info. Classes also exist for sending and receiving database or device values. \end_layout \begin_layout Standard All classes and data types are defined in \emph on fr.esrf.TangoApi \emph default package. Group related classes are in a package called \emph on fr.esrf.TangoApi.Group. \emph default Event related classes are in a package called \emph on fr.esrf.TangoApi.events \end_layout \begin_layout Subsection Classes \end_layout \begin_layout Subsubsection Data object classes \end_layout \begin_layout Description DeviceData: Obect used to send and receive data on device. \end_layout \begin_layout Description DbDatum: Object used to put or get properties on database. \end_layout \begin_layout Description DbDevInfo: Object used to read device information on database. \end_layout \begin_layout Description DbDevImportInfo: Object used to read imported device information on database. \end_layout \begin_layout Description DbDevExportInfo: Object used to read exported device information on database. \end_layout \begin_layout Subsubsection Asynchronous callback related classes \end_layout \begin_layout Description CallBack: Object called at asynchronous call reply \end_layout \begin_layout Description CmdDoneEvent: Object to pass asynchronous command reply data to a CallBack object. \end_layout \begin_layout Description ReadAttrEvent: Object to pass asynchronous read_attribute reply data to a CallBack object. \end_layout \begin_layout Description AttrWrittenEvent: Object to pass asynchronous write_attribute reply data to a CallBack object. \end_layout \begin_layout Subsubsection Devices and Database access classes \end_layout \begin_layout Description DeviceProxy: Device access (aggregates DbDevice class). \end_layout \begin_layout Description Group: Multiple device access class \end_layout \begin_layout Description Database: Direct access to TANGO database. \end_layout \begin_layout Description DbClass: Class properties access to TANGO database. \end_layout \begin_layout Description DbServer: Server properties access to TANGO database. \end_layout \begin_layout Description DbDevice Device properties access to TANGO database. \end_layout \begin_layout Subsection Reporting errors \end_layout \begin_layout Standard For the device and database classes, most methods throw a \emph on DevFailed \emph default exception in case of error. See \emph on Writing a TANGO Device Server \emph default chapter \emph on Reporting Errors \emph default ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Reporting-errors" \end_inset ) , except those which specified. \end_layout \begin_layout Standard In opposite, for the data object classes, only the specified method throw \emph on DevFailed \emph default exception in case of error. \end_layout \begin_layout Standard The reason field could be set to: \end_layout \begin_layout Itemize \emph on TangoApi_TANGO_HOST_NOT_SET \emph default : The \emph on TANGO_HOST \emph default environment variable has not been set or has been set with a syntax error. \end_layout \begin_layout Itemize \emph on TangoApi_DATABASE_CONNECTION_FAILED \emph default : The database server cannot be connected (bad \emph on TANGO_HOST \emph default or database server stopped). \end_layout \begin_layout Itemize \emph on TangoApi_CANNOT_IMPORT_DEVICE \emph default : The device is exported but cannot be connected. \end_layout \begin_layout Itemize \emph on TangoApi_DEVICE_NOT_EXPORTED \emph default : The device has not be exported. \end_layout \begin_layout Subsection Compiling a Java client \end_layout \begin_layout Subsubsection Supported java release \end_layout \begin_layout Standard Tango client written using Java language needs release \series bold 1.5.0 \series default (or above) of the Java environment. \end_layout \begin_layout Subsubsection Setting CLASSPATH and other environment variables \end_layout \begin_layout Standard To correctly compile a Java Tango client, the CLASSPATH \begin_inset Index idx status collapsed \begin_layout Plain Layout CLASSPATH \end_layout \end_inset environment variable must be set to : \end_layout \begin_layout Itemize The jar file with all the Tango, TangoDs, TangoApi and Jacorb package \begin_inset Index idx status collapsed \begin_layout Plain Layout package \end_layout \end_inset classes. This file is named TangORB.jar \end_layout \begin_layout Itemize The jar file with all the JDK classes (not always necessary, could be implicit) \end_layout \begin_layout Itemize Your own package directory \end_layout \begin_layout Standard For UNIX like operating system, setting environment variable is done with the \emph on export \emph default or \emph on setenv \emph default command depending on the shell used. For Windows, setting environment variable is possible from the control panel. \end_layout \begin_layout Standard The client/server timeout as been fixed by default to 3000 milliseconds but it can be set to another value a startup using \emph on TANGO_TIMEOUT \emph default environement variable. \end_layout \begin_layout Standard eg : \emph on java -DTANGO_HOST=hal:20000 -DTANGO_TIMEOUT=5000 mypackage.MyClient \end_layout \begin_layout Standard Will start \emph on MyClient \emph default class using the database server running on the host named \emph on hal \emph default on port 20000 with a command timeout of 5 seconds. \end_layout \begin_layout Section Reference manual \end_layout \begin_layout Standard The Tango Java API documentation is now managed using the Java tool javadoc and is available online at \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset href LatexCommand href name "Tango Java API reference documentation" target "http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/tango_java_api/classes/index.html" \end_inset \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/gen_api/0000755023471100065110000000000013034745265012755 500000000000000tango-9.2.5a/doc/src/gen_api/Makefile.am0000644023471100065110000000027313034745263014731 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ pipe img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/gen_api/Makefile.in0000644023471100065110000003273713034745263014754 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/gen_api DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ pipe all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/gen_api/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/gen_api/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/gen_api/pipe.fig0000644023471100065110000000475213034745263014327 00000000000000#FIG 3.2 Produced by xfig version 3.2.5b Portrait Center Metric A4 100.00 Single -2 1200 2 2 2 0 1 0 7 100 0 -1 0.000 0 0 -1 0 0 5 630 360 13590 360 13590 5130 630 5130 630 360 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1350 900 3555 900 3555 4635 1350 4635 1350 900 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 1395 3555 1395 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 6165 1395 8415 1395 8415 4635 6165 4635 6165 1395 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5940 2025 8685 2025 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5940 2610 8685 2610 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5940 3240 8685 3240 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5940 3870 8685 3870 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6165 2340 8370 2340 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6165 2925 8370 2925 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6210 3555 8415 3555 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 6165 4230 8370 4230 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 10440 2025 12060 2025 12060 3510 10440 3510 10440 2025 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 3825 1440 5850 1440 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 3915 4590 5805 4590 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 8685 2340 10215 2070 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 8685 2565 10170 3420 4 0 0 50 -1 0 14 0.0000 4 165 810 2115 1215 Pipe name\001 4 0 0 50 -1 0 14 0.0000 4 165 1260 1845 2565 DevicePipeBlob\001 4 0 0 50 -1 0 14 0.0000 4 165 1260 6660 1215 DevicePipeBlob\001 4 0 0 50 -1 0 14 0.0000 4 90 360 7065 2250 name\001 4 0 0 50 -1 0 14 0.0000 4 135 450 7065 2520 value\001 4 0 0 50 -1 0 14 0.0000 4 135 810 6840 1800 blob name\001 4 0 0 50 -1 0 14 0.0000 4 90 360 7065 2835 name\001 4 0 0 50 -1 0 14 0.0000 4 90 360 7065 3465 name\001 4 0 0 50 -1 0 14 0.0000 4 90 360 7065 4095 name\001 4 0 0 50 -1 0 14 0.0000 4 135 450 7020 3150 value\001 4 0 0 50 -1 0 14 0.0000 4 135 450 7065 3780 value\001 4 0 0 50 -1 0 14 0.0000 4 135 450 7065 4455 value\001 4 0 0 50 -1 0 14 0.0000 4 135 1530 10440 1800 DataElement value\001 4 0 0 50 -1 0 14 0.0000 4 135 360 11025 2610 Data\001 4 0 0 50 -1 0 14 0.0000 4 90 180 11160 2835 or\001 4 0 0 50 -1 0 14 0.0000 4 135 990 4905 2385 DataElement\001 4 0 0 50 -1 0 14 0.0000 4 135 990 4905 3015 DataElement\001 4 0 0 50 -1 0 14 0.0000 4 135 990 4905 3600 DataElement\001 4 0 0 50 -1 0 14 0.0000 4 135 990 4905 4275 DataElement\001 4 0 0 50 -1 0 14 0.0000 4 135 1080 1710 2925 root blob\001 4 0 0 50 -1 0 14 0.0000 4 165 1260 10575 3060 DevicePipeBlob\001 4 0 0 50 -1 0 14 0.0000 4 165 900 2070 765 DevicePipe\001 tango-9.2.5a/doc/src/gen_api/pipe.eps0000644023471100065110000001322513034745263014344 00000000000000%!PS-Adobe-3.0 EPSF-3.0 %%Title: pipe.fig %%Creator: fig2dev Version 3.2 Patchlevel 5d %%CreationDate: Tue Sep 9 09:23:32 2014 %%BoundingBox: 0 0 818 302 %Magnification: 1.0000 %%EndComments %%BeginProlog /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def /pageheader { save newpath 0 302 moveto 0 0 lineto 818 0 lineto 818 302 lineto closepath clip newpath -38.9 323.9 translate 1 -1 scale $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc } bind def /pagefooter { $F2psEnd restore } bind def %%EndProlog pageheader % % Fig objects follow % % % here starts figure with depth 100 % Polyline 0 slj 0 slc 7.500 slw n 630 360 m 13590 360 l 13590 5130 l 630 5130 l cp gs col0 s gr % here ends figure; % % here starts figure with depth 50 % Polyline 0 slj 0 slc 7.500 slw n 1350 900 m 3555 900 l 3555 4635 l 1350 4635 l cp gs col0 s gr % Polyline n 1350 1395 m 3555 1395 l gs col0 s gr % Polyline n 6165 1395 m 8415 1395 l 8415 4635 l 6165 4635 l cp gs col0 s gr % Polyline n 5940 2025 m 8685 2025 l gs col0 s gr % Polyline n 5940 2610 m 8685 2610 l gs col0 s gr % Polyline n 5940 3240 m 8685 3240 l gs col0 s gr % Polyline n 5940 3870 m 8685 3870 l gs col0 s gr % Polyline n 6165 2340 m 8370 2340 l gs col0 s gr % Polyline n 6165 2925 m 8370 2925 l gs col0 s gr % Polyline n 6210 3555 m 8415 3555 l gs col0 s gr % Polyline n 6165 4230 m 8370 4230 l gs col0 s gr % Polyline n 10440 2025 m 12060 2025 l 12060 3510 l 10440 3510 l cp gs col0 s gr % Polyline [60] 0 sd n 3825 1440 m 5850 1440 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 3915 4590 m 5805 4590 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 8685 2340 m 10215 2070 l gs col0 s gr [] 0 sd % Polyline [60] 0 sd n 8685 2565 m 10170 3420 l gs col0 s gr [] 0 sd /Times-Roman ff 222.25 scf sf 2115 1215 m gs 1 -1 sc (Pipe name) col0 sh gr /Times-Roman ff 222.25 scf sf 1845 2565 m gs 1 -1 sc (DevicePipeBlob) col0 sh gr /Times-Roman ff 222.25 scf sf 6660 1215 m gs 1 -1 sc (DevicePipeBlob) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 2250 m gs 1 -1 sc (name) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 2520 m gs 1 -1 sc (value) col0 sh gr /Times-Roman ff 222.25 scf sf 6840 1800 m gs 1 -1 sc (blob name) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 2835 m gs 1 -1 sc (name) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 3465 m gs 1 -1 sc (name) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 4095 m gs 1 -1 sc (name) col0 sh gr /Times-Roman ff 222.25 scf sf 7020 3150 m gs 1 -1 sc (value) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 3780 m gs 1 -1 sc (value) col0 sh gr /Times-Roman ff 222.25 scf sf 7065 4455 m gs 1 -1 sc (value) col0 sh gr /Times-Roman ff 222.25 scf sf 10440 1800 m gs 1 -1 sc (DataElement value) col0 sh gr /Times-Roman ff 222.25 scf sf 11025 2610 m gs 1 -1 sc (Data) col0 sh gr /Times-Roman ff 222.25 scf sf 11160 2835 m gs 1 -1 sc (or) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 2385 m gs 1 -1 sc (DataElement) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 3015 m gs 1 -1 sc (DataElement) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 3600 m gs 1 -1 sc (DataElement) col0 sh gr /Times-Roman ff 222.25 scf sf 4905 4275 m gs 1 -1 sc (DataElement) col0 sh gr /Times-Roman ff 222.25 scf sf 1710 2925 m gs 1 -1 sc ( root blob) col0 sh gr /Times-Roman ff 222.25 scf sf 10575 3060 m gs 1 -1 sc (DevicePipeBlob) col0 sh gr /Times-Roman ff 222.25 scf sf 2070 765 m gs 1 -1 sc (DevicePipe) col0 sh gr % here ends figure; pagefooter showpage %%Trailer %EOF tango-9.2.5a/doc/src/gen_api/line.tex0000644023471100065110000000174013034745263014346 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/gen_api/genapi.lyx0000644023471100065110000047740113034745263014711 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 4 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter Writing a TANGO client using TANGO APIs \end_layout \begin_layout Section Introduction \end_layout \begin_layout Standard \noindent TANGO devices and database are implemented using the TANGO device server model. To access them the user has the CORBA interface e.g. command_inout(), write_attributes() etc. defined by the idl file. These methods are very low-level and assume a good working knowledge of CORBA. In order to simplify this access, high-level api has been implemented which hides all CORBA aspects of TANGO. In addition the api hides details like how to connect to a device via the database, how to reconnect after a device has been restarted, how to correctly pack and unpack attributes and so on by implementing these in a manner transparent to the user. The api provides a unified error handling for all TANGO and CORBA errors. Unlike the CORBA C++ bindings the TANGO api supports native C++ data types e.g. strings and vectors. \end_layout \begin_layout Standard This chapter describes how to use these API's. It is not a reference guide. Reference documentation is available as Web pages in the \begin_inset CommandInset href LatexCommand href name "Tango Web site" target "http://www.tango-controls.org" \end_inset \end_layout \begin_layout Section \noindent Getting Started \end_layout \begin_layout Standard Refer to the chapter "Getting Started" for an example on getting start with the C++ or Java api. \end_layout \begin_layout Section \noindent Basic Philosophy \end_layout \begin_layout Standard \noindent The basic philosophy is to have high level classes to deal with Tango devices. To communicate with Tango device, uses the \series bold DeviceProxy \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceProxy \end_layout \end_inset \series default class. To send/receive data to/from Tango device, uses the \series bold DeviceData \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceData \end_layout \end_inset , DeviceAttribute \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceAttribute \end_layout \end_inset \series default or \series bold DevicePipe \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout DevicePipe \end_layout \end_inset classes. To communicate with a group of devices, use the \series bold Group \begin_inset Index idx status collapsed \begin_layout Plain Layout Group \end_layout \end_inset \series default class. If you are interested only in some attributes provided by a Tango device, uses the \series bold AttributeProxy \begin_inset Index idx status collapsed \begin_layout Plain Layout AttributeProxy \end_layout \end_inset \series default class. Even if the Tango database is implemented as any other devices (and therefore accessible with one instance of a DeviceProxy class), specific high level classes have been developped to query it. Uses the \series bold Database \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout Database \end_layout \end_inset , \series bold DbDevice \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout DbDevice \end_layout \end_inset , \series bold DbClass \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout DbClass \end_layout \end_inset , \series bold DbServer \begin_inset Index idx status collapsed \begin_layout Plain Layout DbServer \end_layout \end_inset \series default or \series bold DbData \begin_inset Index idx status collapsed \begin_layout Plain Layout DbData \end_layout \end_inset \series default classes when interfacing the Tango database. Callback for asynchronous requests or events are implemented via a \series bold CallBack \begin_inset Index idx status collapsed \begin_layout Plain Layout CallBack \end_layout \end_inset \series default class. An utility class called \series bold ApiUtil \begin_inset Index idx status collapsed \begin_layout Plain Layout ApiUtil \end_layout \end_inset \series default is also available. \end_layout \begin_layout Section Data types \end_layout \begin_layout Standard The definition of the basic data type you can transfert using Tango is: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Tango type name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout C++ equivalent type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevBoolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout boolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevEnum \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout enumeration (only for attribute / See chapter on advanced features) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout int (always 32 bits data) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevLong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long long on 32 bits chip or long on 64 bits chip \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout always 64 bits data \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevFloat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout float \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevDouble \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout char * \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevEncoded \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout structure with 2 fields: a string and an array of unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevUChar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned char \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevUShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned short \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned int (always 32 bits data) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevULong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unsigned long long on 32 bits chip or unsigned long on 64 bits chip \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout always 64 bits data \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevState \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango specific data type \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Using commands, you are able to transfert all these data types, array of these basic types and two other Tango specific data types called DevVarLongStri ngArray and DevVarDoubleStringArray. See chapter \begin_inset CommandInset ref LatexCommand ref reference "Data exchange" \end_inset to get details about them. You are also able to create attributes using any of these basic data types to transfer data between clients and servers. \end_layout \begin_layout Section Request model \begin_inset CommandInset label LatexCommand label name "sec:Request-model" \end_inset \end_layout \begin_layout Standard For the most important API remote calls (command_inout, read_attribute(s) and write_attribute(s)), Tango supports two kind of requests which are the synchronous model and the asynchronous model. Synchronous \begin_inset Index idx status collapsed \begin_layout Plain Layout synchronous \end_layout \end_inset model means that the client wait (and is blocked) for the server to send an answer. Asynchronous \begin_inset Index idx status collapsed \begin_layout Plain Layout asynchronous \end_layout \end_inset model means that the client does not wait for the server to send an answer. The client sends the request and immediately returns allowing the CPU to do anything else (like updating a graphical user interface). Device pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout pipe \end_layout \end_inset supports only the synchronous model. Within Tango, there are two ways to retrieve the server answer when using asynchronous model. They are: \end_layout \begin_layout Enumerate The polling \begin_inset Index idx status collapsed \begin_layout Plain Layout polling \end_layout \end_inset mode \end_layout \begin_layout Enumerate The callback \begin_inset Index idx status collapsed \begin_layout Plain Layout callback \end_layout \end_inset mode \end_layout \begin_layout Standard In polling mode, the client executes a specific call to check if the answer is arrived. If this is not the case, an exception is thrown. If the reply is there, it is returned to the caller and if the reply was an exception, it is re-thrown. There are two calls to check if the reply is arrived: \end_layout \begin_layout Itemize Call which does not wait before the server answer is returned to the caller. \end_layout \begin_layout Itemize Call which wait with timeout before returning the server answer to the caller (or throw the exception) if the answer is not arrived. \end_layout \begin_layout Standard In callback model, the caller must supply a callback method which will be executed when the command returns. They are two sub-modes: \end_layout \begin_layout Enumerate The pull \begin_inset Index idx status collapsed \begin_layout Plain Layout pull \end_layout \end_inset callback mode \end_layout \begin_layout Enumerate The push \begin_inset Index idx status collapsed \begin_layout Plain Layout push \end_layout \end_inset callback mode \end_layout \begin_layout Standard In the pull callback \begin_inset Index idx status collapsed \begin_layout Plain Layout callback \end_layout \end_inset mode, the callback is triggered if the server answer is arrived when the client decide it by calling a \emph on synchronization \emph default method (The client pull-out the answer). In push mode, the callback is executed as soon as the reply arrives in a separate thread (The server pushes the answer to the client). \end_layout \begin_layout Subsection Synchronous model \end_layout \begin_layout Standard Synchronous access to Tango device are provided using the \emph on DeviceProxy \emph default or \emph on AttributeProxy \emph default class. For the \emph on DeviceProxy \emph default class, the main synchronous call methods are : \end_layout \begin_layout Itemize \emph on command_inout() \emph default to execute a Tango device command \end_layout \begin_layout Itemize \emph on read_attribute() \emph default or \emph on read_attributes() \emph default to read a Tango device attribute(s) \end_layout \begin_layout Itemize \emph on write_attribute() \emph default or \emph on write_attributes() \emph default to write a Tango device attribute(s) \end_layout \begin_layout Itemize \emph on write_read_attribute() \emph default or \emph on write_read_attributes() \emph default to write then read Tango device attribute(s) \end_layout \begin_layout Itemize \emph on read_pipe() \emph default to read a Tango device pipe \end_layout \begin_layout Itemize \emph on write_pipe() \emph default to write a Tango device pipe \end_layout \begin_layout Itemize \emph on write_read_pipe() \emph default to write then read Tango device pipe \end_layout \begin_layout Standard For commands, data are send/received to/from device using the \emph on DeviceData \emph default class. For attributes, data are send/received to/from device attribute using the \emph on DeviceAttribute \emph default class. For pipes, data are send/receive to/from device pipe using the \emph on DevicePipe \begin_inset Index idx status collapsed \begin_layout Plain Layout \emph off DevicePipe \end_layout \end_inset \emph default and \emph on DevicePipeBlob \begin_inset Index idx status collapsed \begin_layout Plain Layout \emph off DevicePipeBlob \end_layout \end_inset \emph default classes. \end_layout \begin_layout Standard In some cases, only attributes provided by a Tango device are interesting for the application. You can use the \emph on AttributeProxy \emph default class. Its main synchronous methods are : \end_layout \begin_layout Itemize \emph on read() \emph default to read the attribute value \end_layout \begin_layout Itemize \emph on write() \emph default to write the attribute value \end_layout \begin_layout Itemize \emph on write_read() \emph default to write then read the attribute value \end_layout \begin_layout Standard Data are transmitted using the \emph on DeviceAttribute \emph default class. \end_layout \begin_layout Subsection Asynchronous model \end_layout \begin_layout Standard Asynchronous access to Tango device are provided using \emph on DeviceProxy \emph default or \emph on AttributeProxy, CallBack \emph default and \emph on ApiUtil \emph default classes methods. The main asynchronous call methods and used classes are : \end_layout \begin_layout Itemize To execute a command on a device \end_layout \begin_deeper \begin_layout Itemize \emph on DeviceProxy::command_inout_asynch() \emph default and \emph on DeviceProxy::command_inout_reply() \emph default in polling model. \end_layout \begin_layout Itemize \emph on DeviceProxy::command_inout_asynch() \emph default , \emph on DeviceProxy::get_asynch_replies() \emph default and \emph on CallBack \emph default class in callback pull model \end_layout \begin_layout Itemize \emph on DeviceProxy::command_inout_asynch() \emph default , \emph on ApiUtil::set_asynch_cb_sub_model() \emph default and \emph on CallBack \emph default class in callback push model \end_layout \end_deeper \begin_layout Itemize To read a device attribute \end_layout \begin_deeper \begin_layout Itemize \emph on DeviceProxy::read_attribute_asynch() \emph default and \emph on DeviceProxy::read_attribute_reply() \emph default in polling model \end_layout \begin_layout Itemize \emph on DeviceProxy::read_attribute_asynch() \emph default , \emph on DeviceProxy::get_asynch_replies() \emph default and \emph on CallBack \emph default class in callback pull model. \end_layout \begin_layout Itemize \emph on DeviceProxy::read_attribute_asynch() \emph default , \emph on ApiUtil::set_asynch_cb_sub_model() \emph default and \emph on CallBack \emph default class in callback push model \end_layout \end_deeper \begin_layout Itemize To write a device attribute \end_layout \begin_deeper \begin_layout Itemize \emph on DeviceProxy::write_attribute_asynch() \emph default in polling model \end_layout \begin_layout Itemize \emph on DeviceProxy::write_attribute_asynch() \emph default and \emph on CallBack \emph default class in callback pull model \end_layout \begin_layout Itemize \emph on DeviceProxy::write_attribute_asynch() \emph default , \emph on ApiUtil::set_asynch_cb_sub_model() \emph default and \emph on CallBack \emph default class in callback push model \end_layout \end_deeper \begin_layout Standard For commands, data are send/received to/from device using the \emph on DeviceData \emph default class. For attributes, data are send/received to/from device attribute using the \emph on DeviceAttribute \emph default class. It is also possible to generate asynchronous request(s) using the \emph on AttributeProxy \begin_inset Index idx status collapsed \begin_layout Plain Layout AttributeProxy \end_layout \end_inset \emph default class following the same schema than above. Methods to use are : \end_layout \begin_layout Itemize \emph on read_asynch( \emph default ) and \emph on read_reply() \emph default to asynchronously read the attribute value \end_layout \begin_layout Itemize \emph on write_asynch() \emph default and \emph on write_reply() \emph default to asynchronously write the attribute value \end_layout \begin_layout Section Events \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset \end_layout \begin_layout Subsection Introduction \end_layout \begin_layout Standard Events are a critical part of any distributed control system. Their aim is to provide a communication mechanism which is fast and efficient. \end_layout \begin_layout Standard The standard CORBA communication paradigm is a synchronous or asynchronous two-way call. In this paradigm the call is initiated by the client who contacts the server. The server handles the client's request and sends the answer to the client or throws an exception which the client catches. This paradigm involves two calls to receive a single answer and requires the client to be active in initiating the request. If the client has a permanent interest in a value he is obliged to poll the server for an update in a value every time. This is not efficient in terms of network bandwidth nor in terms of client programming. \end_layout \begin_layout Standard For clients who are permanently interested in values the event-driven communicat ion paradigm is a more efficient and natural way of programming. In this paradigm the client registers her interest once in an event (value). After that the server informs the client every time the event has occurred. This paradigm avoids the client polling, frees it for doing other things, is fast and makes efficient use of the network. \end_layout \begin_layout Standard The rest of this chapter explains how the TANGO events are implemented and the application programmer's interface. \end_layout \begin_layout Subsection Event definition \end_layout \begin_layout Standard TANGO events represent an alternative channel for reading TANGO device attribute s \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset . Device attributes values are sent to all subscribed clients when an event occurs. Events can be an attribute value change, a change in the data quality or a periodically send event. The clients continue receiving events as long as they stay subscribed. Most of the time, the device server polling thread detects the event and then pushes the device attribute value to all clients. Nevertheless, in some cases, the delay introduced by the polling thread in the event propagation is detrimental. For such cases, some API calls directly push the event. Until TANGO release 8, the omniNotify \begin_inset Index idx status collapsed \begin_layout Plain Layout omniNotify \end_layout \end_inset implementation of the CORBA Notification service \begin_inset Index idx status collapsed \begin_layout Plain Layout Notification Service \end_layout \end_inset was used to dispatch events. Starting with TANGO 8, this CORBA Notification service has been replaced by the ZMQ \begin_inset Index idx status open \begin_layout Plain Layout ZMQ \end_layout \end_inset library which implements a Publish/Subscribe communication model well adapted to TANGO events communication. \end_layout \begin_layout Subsection Event types \end_layout \begin_layout Standard The following eight event types have been implemented in TANGO : \end_layout \begin_layout Enumerate \series bold change \begin_inset Index idx status collapsed \begin_layout Plain Layout change \end_layout \end_inset \series default - an event is triggered and the attribute value is sent when the attribute value changes significantly. The exact meaning of significant is device attribute dependent. For analog and digital values this is a delta fixed per attribute, for string values this is any non-zero change i.e. if the new attribute value is not equal to the previous attribute value. The delta can either be specified as a relative or absolute change. The delta is the same for all clients unless a filter is specified (see below). To easily write applications using the change event, it is also triggered in the following case : \end_layout \begin_deeper \begin_layout Enumerate When a spectrum or image attribute size changes. \end_layout \begin_layout Enumerate At event subscription time \end_layout \begin_layout Enumerate When the polling thread receives an exception during attribute reading \end_layout \begin_layout Enumerate When the polling thread detects that the attribute quality factor has changed. \end_layout \begin_layout Enumerate The first good reading of the attribute after the polling thread has received exception when trying to read the attribute \end_layout \begin_layout Enumerate The first time the polling thread detects that the attribute quality factor has changed from INVALID to something else \end_layout \begin_layout Enumerate When a change event is pushed manually from the device server code. ( \emph on DeviceImpl::push_change_event() \emph default ). \end_layout \begin_layout Enumerate By the methods Attribute::set_quality() and Attribute::set_value_date_quality() if a client has subscribed to the change event on the attribute. This has been implemented for cases where the delay introduced by the polling thread in the event propagation is not authorized. \end_layout \end_deeper \begin_layout Enumerate \series bold periodic \begin_inset Index idx status collapsed \begin_layout Plain Layout periodic \end_layout \end_inset \series default - an event is sent at a fixed periodic interval. The frequency of this event is determined by the \emph on event_period \emph default property of the attribute and the polling frequency. The polling frequency determines the highest frequency at which the attribute is read. The event_period determines the highest frequency at which the periodic event is sent. Note if the event_period is not an integral number of the polling period there will be a beating of the two frequencies \begin_inset Foot status collapsed \begin_layout Plain Layout note: the polling is not synchronized is currently not synchronized on the hour \end_layout \end_inset . Clients can reduce the frequency at which they receive periodic events by specifying a filter on the periodic event counter. \end_layout \begin_layout Enumerate \series bold archive \begin_inset Index idx status collapsed \begin_layout Plain Layout archive \end_layout \end_inset \series default - an event is sent if one of the archiving conditions is satisfied. Archiving conditions are defined via properties in the database. These can be a mixture of delta_change and periodic. Archive events can be send from the polling thread or can be manually pushed from the device server code ( \emph on DeviceImpl::push_archive_event() \emph default ). \end_layout \begin_layout Enumerate \series bold attribute configuration \series default - an event is sent if the attribute configuration is changed. \end_layout \begin_layout Enumerate \series bold data ready \series default - This event is sent when coded by the device server programmer who uses a specific method of one of the Tango device server class to fire the event ( \emph on DeviceImpl::push_data_ready_event() \emph default ). The rule of this event is to inform a client that it is now possible to read an attribute. This could be useful in case of attribute with many data. \end_layout \begin_layout Enumerate \series bold user \series default - The criteria and configuration of these user events are managed by the device server programmer who uses a specific method of one of the Tango device server class to fire the event ( \emph on DeviceImpl::push_event() \emph default ). \end_layout \begin_layout Enumerate \series bold device interface change \series default - This event is sent when the device interface changes. Using Tango, it is possible to dynamically add/remove attribute/command to a device. This event is the way to inform client(s) that attribute/command has been added/removed from a device. Note that this type of event is attached to a device and not to one attribute (like all other event types). This event is triggered in the following case : \end_layout \begin_deeper \begin_layout Enumerate A dynamic attribute or command is added or removed. The event is sent after a small delay (50 mS) in order to eliminate the risk of events storm in case several attributes/commands are added/removed in a loop \end_layout \begin_layout Enumerate At the end of admin device RestartServer or DevRestart command \end_layout \begin_layout Enumerate After a re-connection due to a device server restart. Because the device interface is not memorized, the event is sent even if it is highly possible that the device interface has not changed. A flag in the data propagated with the event inform listening applications that the device interface change is not guaranteed. \end_layout \begin_layout Enumerate At event re-connection time. This case is similar to the previous one (device interface change not guarantee d) \end_layout \end_deeper \begin_layout Enumerate \series bold pipe \series default - This is the kind of event which has to be used when the user want to push data through a pipe. This kind of event is only sent by the user code by using a specific method ( \emph on DeviceImpl::push_pipe_event() \emph default ). There is no way to ask the Tango kernel to automatically push this kind of event. \end_layout \begin_layout Standard The first three above events are automatically generated by the TANGO library or fired by the user code. Events number 4 and 7 are only automatically sent by the library and events 5, 6 and 8 are fired only by the user code. \end_layout \begin_layout Subsection Event filtering (Removed in Tango release 8 and above) \end_layout \begin_layout Standard Please, note that this feature is available only for Tango releases older than Tango 8. The CORBA Notification Service allows event filtering. This means that a client can ask the Notification Service to send the event only if some filter is evaluated to true. Within the Tango control system, some pre-defined fields can be used as filter. These fields depend on the event type. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Event type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Filterable field name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Filterable field value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_change_rel \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Relative change (in %) since last event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_change_abs \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Absolute change since last event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout quality \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Is set to 1 when the attribute quality factor has \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout changed, otherwise it is 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none forced_event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Is set to 1 when the event was fired on exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or a quality factor set to invalid \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout periodic \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout counter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Incremented each time the event is sent \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_change_rel \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Relative change (in %) since last event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_change_abs \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Absolute change since last event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout quality \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Is set to 1 when the attribute quality factor has \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout changed, otherwise it is 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Incremented each time the event is sent \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout counter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout for periodic reason. Set to -1 if event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout long \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout sent for change reason \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \family roman \series medium \shape up \size normal \emph off \bar no \noun off \color none forced_event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Is set to 1 when the event was fired on exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or a quality factor set to invalid \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Number of milli-seconds since previous event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout double \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Filter are defined as a string following a grammar defined by CORBA. It is defined in \begin_inset CommandInset citation LatexCommand cite key "Notif_doc" \end_inset . The following example shows you the most common use of these filters in the Tango world : \end_layout \begin_layout Itemize To receive periodic event one out of every three, the filter must be \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset "$counter % 3 == 0" \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Itemize To receive change event only if the relative change is greater than 20 % (positive and negative), the filter must be \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset "$delta_change_rel >= 20 or $delta_change_rel <= -20" \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Itemize To receive a change event only on quality change, the filter must be \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset "$quality == 1" \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard For user events, the filter field name(s) and their value are defined by the device server programmer. \end_layout \begin_layout Subsection Application Programmer's Interface \end_layout \begin_layout Standard How to setup and use the TANGO events ? The interfaces described here are intended as user friendly interfaces to the underlying CORBA calls. The interface is modeled after the asynchronous \begin_inset Index idx status collapsed \begin_layout Plain Layout asynchronous \end_layout \end_inset \emph on command_inout() \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout() \end_layout \end_inset \emph default interface so as to maintain coherency. The event system supports \series bold push callback model \series default as well as the \series bold pull callback model. \end_layout \begin_layout Standard The two event reception modes are: \end_layout \begin_layout Itemize \series bold Push callback model \series default : On event reception a callbacks method gets immediately executed. \end_layout \begin_layout Itemize \series bold Pull callback model \series default : The event will be buffered the client until the client is ready to receive the event data. The client triggers the execution of the callback method. \end_layout \begin_layout Standard The event reception buffer in the \series bold pull callback model \series default , is implemented as a round robin buffer. The client can choose the size when subscribing for the event. This way the client can set-up different ways to receive events. \end_layout \begin_layout Itemize Event reception buffer size = 1 : The client is interested only in the value of the last event received. All other events that have been received since the last reading are discarded. \end_layout \begin_layout Itemize Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When more events arrive since the last reading, older events will be discarded. \end_layout \begin_layout Itemize Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size is unlimited and only restricted by the available memory for the client. \end_layout \begin_layout Subsubsection Configuring events \end_layout \begin_layout Standard The attribute configuration set is used to configure under what conditions events \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset are generated. A set of standard attribute properties (part of the standard attribute configuration) are read from the database at device startup time and used to configure the event engine. If there are no properties defined then default values specified in the code are used. \end_layout \begin_layout Paragraph change \end_layout \begin_layout Standard The attribute properties and their default values for the "change" event are : \end_layout \begin_layout Enumerate \series bold rel_change \begin_inset Index idx status collapsed \begin_layout Plain Layout rel-change \end_layout \end_inset \series default - a property of maximum 2 values. It specifies the positive and negative relative change of the attribute value w.r.t. the value of the previous change event which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no property is specified, no events are generated. \end_layout \begin_layout Enumerate \series bold abs_change \begin_inset Index idx status collapsed \begin_layout Plain Layout abs-change \end_layout \end_inset \series default - a property of maximum 2 values.It specifies the positive and negative absolute change of the attribute value w.r.t the value of the previous change event which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then the relative change is used. \end_layout \begin_layout Paragraph periodic \end_layout \begin_layout Standard The attribute properties and their default values for the "periodic" event are : \end_layout \begin_layout Enumerate \series bold event_period \begin_inset Index idx status collapsed \begin_layout Plain Layout event-period \end_layout \end_inset \series default - the minimum time between events (in milliseconds). If no property is specified then a default value of 1 second is used. \end_layout \begin_layout Paragraph archive \end_layout \begin_layout Standard The attribute properties and their default values for the "archive" event are : \end_layout \begin_layout Enumerate \series bold archive_rel_change \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-rel-change \end_layout \end_inset \series default - a property of maximum 2 values which specifies the positive and negative relative change w.r.t. the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then no events are generate. \end_layout \begin_layout Enumerate \series bold archive_abs_change \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-abs-change \end_layout \end_inset \series default - a property of maximum 2 values which specifies the positive and negative absolute change w.r.t the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then the relative change is used. \end_layout \begin_layout Enumerate \series bold archive_period \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-period \end_layout \end_inset \series default - the minimum time between archive events (in milliseconds). If no property is specified, no periodic archiving events are send. \end_layout \begin_layout Subsubsection C++ Clients \end_layout \begin_layout Standard This is the interface for clients who want to receive events \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset . The main action of the client is to subscribe and unsubscribe to events. Once the client has subscribed to one or more events the events are received in a separate thread by the client. \end_layout \begin_layout Standard Two reception modes are possible: \end_layout \begin_layout Itemize On event reception a callbacks method gets immediately executed. \end_layout \begin_layout Itemize The event will be buffered until the client until the client is ready to receive the event data. \end_layout \begin_layout Standard The mode to be used has to be chosen when subscribing for the event. \end_layout \begin_layout Paragraph Subscribing to events \end_layout \begin_layout Standard The client call to subscribe to an event is named \emph on DeviceProxy::subscribe_event() \begin_inset Index idx status collapsed \begin_layout Plain Layout subscribe-event \end_layout \end_inset \emph default . During the event subscription the client has to choose the event reception mode to use. \end_layout \begin_layout Standard \series bold Push model \series default : \end_layout \begin_layout LyX-Code int DeviceProxy::subscribe_event( \end_layout \begin_layout LyX-Code const string &attribute, \end_layout \begin_layout LyX-Code Tango::EventType event, \end_layout \begin_layout LyX-Code Tango::CallBack *callback, \end_layout \begin_layout LyX-Code bool stateless = false); \end_layout \begin_layout Standard The client implements a callback method which is triggered when the event is received. Note that this callback method will be executed by a thread started by the underlying ORB. This thread is not the application main thread. For Tango releases before 8, a similar call with one extra parameter for event filtering is also available. \end_layout \begin_layout Standard \series bold Pull model \series default : \end_layout \begin_layout LyX-Code int DeviceProxy::subscribe_event( \end_layout \begin_layout LyX-Code const string &attribute, \end_layout \begin_layout LyX-Code Tango::EventType event, \end_layout \begin_layout LyX-Code int event_queue_size, \end_layout \begin_layout LyX-Code bool stateless = false); \end_layout \begin_layout Standard The client chooses the size of the round robin event reception buffer. Arriving events will be buffered until the client uses \emph on DeviceProxy::get_events() \begin_inset Index idx status collapsed \begin_layout Plain Layout get-events \end_layout \end_inset \emph default to extract the event data. For Tango releases before 8, a similar call with one extra parameter for event filtering is also available. \end_layout \begin_layout Standard On top of the user filter defined by the \emph on filters \emph default parameter, basic filtering is done based on the reason specified and the event type. For example when reading the state and the reason specified is "change" the event will be fired only when the state changes. Events consist of an attribute name and the event reason. A standard set of reasons are implemented by the system, additional device specific reasons can be implemented by device servers programmers. \end_layout \begin_layout Standard The stateless flag = false indicates that the event subscription will only succeed when the given attribute is known and available in the Tango system. Setting stateless = true will make the subscription succeed, even if an attribute of this name was never known. The real event subscription will happen when the given attribute will be available in the Tango system. \end_layout \begin_layout Standard Note that in this model, the callback method will be executed by the thread doing the \emph on DeviceProxy::get_events() \emph default call. \end_layout \begin_layout Paragraph The CallBack class \end_layout \begin_layout Standard In C++, the client has to implement a class inheriting from the Tango CallBack \begin_inset Index idx status collapsed \begin_layout Plain Layout CallBack \end_layout \end_inset class and pass this to the \emph on DeviceProxy::subscribe_event() \emph default method. The CallBack class is the same class as the one proposed for the TANGO asynchronous call. This is as follows for events : \end_layout \begin_layout LyX-Code class MyCallback : public Tango::CallBack \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code . \end_layout \begin_layout LyX-Code . \end_layout \begin_layout LyX-Code . \end_layout \begin_layout LyX-Code virtual push_event(Tango::EventData *); \end_layout \begin_layout LyX-Code virtual push_event(Tango::AttrConfEventData *); \end_layout \begin_layout LyX-Code virtual push_event(Tango::DataReadyEventData *); \end_layout \begin_layout LyX-Code virtual push_event(Tango::DevIntrChangeEventData *); \end_layout \begin_layout LyX-Code virtual push_event(Tango::PipeEventData *); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard where EventData \begin_inset Index idx status collapsed \begin_layout Plain Layout EventData \end_layout \end_inset is defined as follows : \end_layout \begin_layout LyX-Code class EventData \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceProxy *device; \end_layout \begin_layout LyX-Code string attr_name; \end_layout \begin_layout LyX-Code string event; \end_layout \begin_layout LyX-Code DeviceAttribute *attr_value; \end_layout \begin_layout LyX-Code bool err; \end_layout \begin_layout LyX-Code DevErrorList errors; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard AttrConfEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout AttrConfEventData \end_layout \end_inset is defined as follows : \end_layout \begin_layout LyX-Code class AttrConfEventData \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceProxy *device; \end_layout \begin_layout LyX-Code string attr_name; \end_layout \begin_layout LyX-Code string event; \end_layout \begin_layout LyX-Code AttributeInfoEx *attr_conf; \end_layout \begin_layout LyX-Code bool err; \end_layout \begin_layout LyX-Code DevErrorList errors; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard DataReadyEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout DataReadyEventData \end_layout \end_inset is defined as follows : \end_layout \begin_layout LyX-Code class DataReadyEventData \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceProxy *device; \end_layout \begin_layout LyX-Code string attr_name; \end_layout \begin_layout LyX-Code string event; \end_layout \begin_layout LyX-Code int attr_data_type; \end_layout \begin_layout LyX-Code int ctr; \end_layout \begin_layout LyX-Code bool err; \end_layout \begin_layout LyX-Code DevErrorList errors; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard DevIntrChangeEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout DevIntrChangeEventData \end_layout \end_inset is defined as follows : \end_layout \begin_layout LyX-Code class DevIntrChangeEventData \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceProxy device; \end_layout \begin_layout LyX-Code string event; \end_layout \begin_layout LyX-Code string device_name; \end_layout \begin_layout LyX-Code CommandInfoList cmd_list; \end_layout \begin_layout LyX-Code AttributeInfoListEx att_list; \end_layout \begin_layout LyX-Code bool dev_started; \end_layout \begin_layout LyX-Code bool err; \end_layout \begin_layout LyX-Code DevErrorList errors; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard and PipeEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout PipeEventData \end_layout \end_inset is defined as follows : \end_layout \begin_layout LyX-Code class PipeEventData \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceProxy *device; \end_layout \begin_layout LyX-Code string pipe_name; \end_layout \begin_layout LyX-Code string event; \end_layout \begin_layout LyX-Code DevicePipe *pipe_value; \end_layout \begin_layout LyX-Code bool err; \end_layout \begin_layout LyX-Code DevErrorList errors; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard In push model, there are some cases (same callback used for events coming from different devices hosted in device server process running on different hosts) where the callback method could be executed concurently by different threads started by the ORB. The user has to code his callback method in a \series bold thread \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset \series bold safe \series default manner. \end_layout \begin_layout Paragraph Unsubscribing from an event \end_layout \begin_layout Standard Unsubscribe a client from receiving the event specified by \emph on event_id \emph default is done by calling the \emph on DeviceProxy::unsubscribe_event() \begin_inset Index idx status collapsed \begin_layout Plain Layout unsubscribe-event \end_layout \end_inset \emph default method : \end_layout \begin_layout LyX-Code void DeviceProxy::unsubscribe_event(int event_id); \end_layout \begin_layout LyX-Code \end_layout \begin_layout Paragraph Extract buffered event data \end_layout \begin_layout Standard When the pull model was chosen during the event subscription, the received event data can be extracted with \emph on DeviceProxy::get_events() \begin_inset Index idx status collapsed \begin_layout Plain Layout get-events \end_layout \end_inset . \emph default Two possibilities are available for data extraction. Either a callback method can be executed for every event in the buffer when using \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code CallBack *cb); \end_layout \begin_layout Standard Or all the event data can be directly extracted as EventDataList \begin_inset Index idx status collapsed \begin_layout Plain Layout EventDataList \end_layout \end_inset , AttrConfEventDataList \begin_inset Index idx status collapsed \begin_layout Plain Layout AttrConfEventDataList \end_layout \end_inset , DataReadyEventDataList \begin_inset Index idx status collapsed \begin_layout Plain Layout DataReadyEventDataList \end_layout \end_inset , DevIntrChangeEventDataList \begin_inset Index idx status collapsed \begin_layout Plain Layout DevIntrChangeEventDataList \end_layout \end_inset or PipeEventDataList \begin_inset Index idx status collapsed \begin_layout Plain Layout PipeEventDataList \end_layout \end_inset when using \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code EventDataList &event_list); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code AttrConfEventDataList &event_list); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code DataReadyEventDataList &event_list); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code DevIntrChangeEventDataList &event_list); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int DeviceProxy::get_events( \end_layout \begin_layout LyX-Code int event_id, \end_layout \begin_layout LyX-Code PipeEventDataList &event_list); \end_layout \begin_layout Standard The event data lists are vectors of EventData, AttrConfEventData, DataReadyEvent Data or PipeEventData pointers with special destructor and clean-up methods to ease the memory handling. \end_layout \begin_layout LyX-Code class EventDataList:public vector \end_layout \begin_layout LyX-Code class AttrConfEventDataList:public vector \end_layout \begin_layout LyX-Code class DataReadyEventDataList:public vector \end_layout \begin_layout LyX-Code class DevIntrChangeEventDataList:public vector \end_layout \begin_layout LyX-Code class PipeEventDataList:public vector \end_layout \begin_layout Paragraph Example \end_layout \begin_layout Standard Here is a typical code example of a client to register and receive events. First, you have to define a callback \begin_inset Index idx status collapsed \begin_layout Plain Layout CallBack \end_layout \end_inset method as follows: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code class DoubleEventCallBack : public Tango::CallBack \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code void push_event(Tango::EventData*); \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code void DoubleEventCallBack::push_event(Tango::EventData *myevent) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code Tango::DevVarDoubleArray *double_value; \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "DoubleEventCallBack::push_event(): called attribute " \end_layout \begin_layout LyX-Code << myevent->attr_name \end_layout \begin_layout LyX-Code << " event " \end_layout \begin_layout LyX-Code << myevent->event \end_layout \begin_layout LyX-Code << " (err=" \end_layout \begin_layout LyX-Code << myevent->err \end_layout \begin_layout LyX-Code << ")" << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code if (!myevent->err) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code *(myevent->attr_value) >> double_value; \end_layout \begin_layout LyX-Code cout << "double value " \end_layout \begin_layout LyX-Code << (*double_value)[0] \end_layout \begin_layout LyX-Code << endl; \end_layout \begin_layout LyX-Code delete double_value; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (...) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "DoubleEventCallBack::push_event(): could not extract data ! \backslash n"; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Then the main code must subscribe \begin_inset Index idx status collapsed \begin_layout Plain Layout evebt-subscribe \end_layout \end_inset to the event and choose the push or the pull model for event reception. \end_layout \begin_layout Standard \series bold Push model \series default : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DoubleEventCallBack *double_callback = new DoubleEventCallBack; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code Tango::DeviceProxy *mydevice = new Tango::DeviceProxy("my/device/1"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int event_id; \end_layout \begin_layout LyX-Code const string attr_name("current"); \end_layout \begin_layout LyX-Code event_id = mydevice->subscribe_event(attr_name, \end_layout \begin_layout LyX-Code Tango::CHANGE_EVENT, \end_layout \begin_layout LyX-Code double_callback); \end_layout \begin_layout LyX-Code cout << "event_client() id = " << event_id << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // The callback methods are executed by the Tango event reception thread. \end_layout \begin_layout LyX-Code // The main thread is not concerned of event reception. \end_layout \begin_layout LyX-Code // Whatch out with synchronisation and data access in a multi threaded environme nt! \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code sleep(1000); // wait for events \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code mydevice->unsubscribe_event(event_id); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \series bold Pull model \series default : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DoubleEventCallBack *double_callback = new DoubleEventCallBack; \end_layout \begin_layout LyX-Code int event_queue_size = 100; // keep the last 100 events \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code Tango::DeviceProxy *mydevice = new Tango::DeviceProxy("my/device/1"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code int event_id; \end_layout \begin_layout LyX-Code const string attr_name("current"); \end_layout \begin_layout LyX-Code event_id = mydevice->subscribe_event(attr_name, \end_layout \begin_layout LyX-Code Tango::CHANGE_EVENT, \end_layout \begin_layout LyX-Code event_queue_size); \end_layout \begin_layout LyX-Code cout << "event_client() id = " << event_id << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // Check every 3 seconds whether new events have arrived and trigger the callback method \end_layout \begin_layout LyX-Code // for the new events. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code for (int i=0; i < 100; i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code sleep (3); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // Read the stored event data from the queue and call the callback method for every event. \end_layout \begin_layout LyX-Code mydevice->get_events(event_id, double_callback); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code event_test->unsubscribe_event(event_id); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset \end_layout \begin_layout Standard A Tango Group provides the user with a single point of control for a collection of devices. By analogy, one could see a Tango Group as a proxy for a collection of devices. For instance, the Tango Group API supplies a \emph on command_inout() \emph default method to execute the same command on all the elements of a group. \end_layout \begin_layout Standard A Tango Group is also a hierarchical object. In other words, it is possible to build a group of both groups and individual devices. This feature allows creating logical views of the control system - each view representing a hierarchical family of devices or a sub-system. \end_layout \begin_layout Standard In this chapter, we will use the term \emph on hierarchy \emph default to refer to a group and its sub-groups. The term \emph on Group \emph default designates to the local set of devices attached to a specific Group. \end_layout \begin_layout Subsection Getting started with Tango group \end_layout \begin_layout Standard The quickest way of getting started is to study an example\SpecialChar \ldots{} \end_layout \begin_layout Standard Imagine we are vacuum engineers who need to monitor and control hundreds of gauges distributed over the 16 cells of a large-scale instrument. Each cell contains several penning and pirani gauges. It also contains one "strange" gauge. Our main requirement is to be able to control the whole set of gauges, a family of gauges located into a particular cell (e.g. all the penning gauges of the 6th cell) or a single gauge (e.g. the strange gauge of the 7th cell). Using a Tango Group, such features are quite straightforward to obtain. \end_layout \begin_layout Standard Reading the description of the problem, the device hierarchy becomes obvious. Our "gauges" group will have the following structure: \end_layout \begin_layout LyX-Code -> gauges \end_layout \begin_layout LyX-Code | -> cell-01 \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/strange \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code | | |- ... \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-xx \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-01 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-xx \end_layout \begin_layout LyX-Code | -> cell-02 \end_layout \begin_layout LyX-Code | |-> inst-c02/vac-gauge/strange \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> inst-c02/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | | \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | -> cell-03 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | | -> ... \end_layout \begin_layout Standard In the C++, such a hierarchy can be build as follows (basic version): \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- step0: create the root group \end_layout \begin_layout LyX-Code Tango::Group *gauges = new Tango::Group("gauges"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step1: create a group for the n-th cell \end_layout \begin_layout LyX-Code Tango::Group *cell = new Tango::Group("cell-01"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step2: make the cell a sub-group of the root group \end_layout \begin_layout LyX-Code gauges->add(cell); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step3: create a "penning" group \end_layout \begin_layout LyX-Code Tango::Group *gauge_family = new Tango::Group("penning"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step4: add all penning gauges located into the cell (note the wildcard) \end_layout \begin_layout LyX-Code gauge_family->add("inst-c01/vac-gauge/penning*"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step5: add the penning gauges to the cell \end_layout \begin_layout LyX-Code cell->add(gauge_family); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step6: create a "pirani" group \end_layout \begin_layout LyX-Code gauge_family = new Tango::Group("pirani"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step7: add all pirani gauges located into the cell (note the wildcard) \end_layout \begin_layout LyX-Code gauge_family->add("inst-c01/vac-gauge/pirani*"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step8: add the pirani gauges to the cell \end_layout \begin_layout LyX-Code cell->add(gauge_family); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- step9: add the "strange" gauge to the cell \end_layout \begin_layout LyX-Code cell->add("inst-c01/vac-gauge/strange"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- repeat step 1 to 9 for the remaining cells \end_layout \begin_layout LyX-Code cell = new Tango::Group("cell-02"); \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \series bold Important note \series default : There is no particular order to create the hierarchy. However, the insertion order of the devices is conserved throughout the lifecycle of the Group and cannot be changed. That way, the Group implementation can guarantee the order in which results are returned (see below). \end_layout \begin_layout Standard Keeping a reference to the root group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset is enough to manage the whole hierarchy (i.e. there no need to keep trace of the sub-groups or individual devices). The Group interface provides methods to retrieve a sub-group or an individual device. \end_layout \begin_layout Standard Be aware that a C++ group allways gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a Group (respectively a DeviceProxy) returned by a call to \emph on Tango::Group::get_group() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout get-group \end_layout \end_inset (respectively to \emph on Tango::Group::get_device() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout get-device \end_layout \end_inset ). Use the \emph on Tango::Group::remove() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout remove \end_layout \end_inset method instead (see the Tango Group class API documentation for details). \end_layout \begin_layout Standard We can now perform any action on any element of our "gauges" group. For instance, let's ping the whole hierarchy to be sure that all devices are alive. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- ping the whole hierarchy \end_layout \begin_layout LyX-Code if (gauges->ping() == true) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code std::cout << "all devices alive" << std::endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code std::cout << "at least one dead/busy/locked/... device" << std::endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsection Forward or not forward \begin_inset Index idx status collapsed \begin_layout Plain Layout forward \end_layout \end_inset ? \end_layout \begin_layout Standard Since a Tango Group is a hierarchical object, any action performed on a group can be forwarded to its sub-groups. Most of the methods in the Group interface have a so-called \emph on forward \emph default option controlling this propagation. When set to \emph on false \emph default , the action is only performed on the local set of devices. Otherwise, the action is also forwarded to the sub-groups, in other words, propagated along the hierarchy. In C++ , the forward option defaults to true (thanks to the C++ default argument value). There is no such mechanism in Java and the forward option must be systematicall y specified. \end_layout \begin_layout Subsection Executing a command \end_layout \begin_layout Standard As a proxy for a collection of devices, the Tango Group provides an interface similar to the DeviceProxy's. For the execution of a command, the Group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset interface contains several implementations of the \emph on command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset \emph default method. Both synchronous and asynchronous forms are supported. \end_layout \begin_layout Subsubsection Obtaining command results \begin_inset CommandInset label LatexCommand label name "sub:Obt-cmd-results" \end_inset \end_layout \begin_layout Standard Command results are returned using a Tango::GroupCmdReplyList \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupCmdReplyList \end_layout \end_inset . This is nothing but a vector containing a Tango::GroupCmdReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupCmdReply \end_layout \end_inset for each device in the group. The Tango::GroupCmdReply contains the actual data (i.e. the Tango::DeviceData). By inheritance, it may also contain any error occurred during the execution of the command (in which case the data is invalid). \end_layout \begin_layout Standard We previously indicated that the Tango Group implementation guarantees that the command results are returned in the order in which its elements were attached to the group. For instance, if g1 is a group containing three devices attached in the following order: \end_layout \begin_layout LyX-Code g1->add("my/device/01"); \end_layout \begin_layout LyX-Code g1->add("my/device/03"); \end_layout \begin_layout LyX-Code g1->add("my/device/02"); \end_layout \begin_layout Standard the results of \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl = g1->command_inout("Status"); \end_layout \begin_layout Standard will be organized as follows: \end_layout \begin_layout Standard \emph on crl[0] \emph default contains the status of my/device/01 \begin_inset Newline newline \end_inset \emph on crl[1] \emph default contains the status of my/device/03 \begin_inset Newline newline \end_inset \emph on crl[2] \emph default contains the status of my/device/02 \end_layout \begin_layout Standard Things get more complicated if sub-groups are added "between" devices. \end_layout \begin_layout LyX-Code g2->add("my/device/04"); \end_layout \begin_layout LyX-Code g2->add("my/device/05"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g4->add("my/device/08"); \end_layout \begin_layout LyX-Code g4->add("my/device/09"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g3->add("my/device/06"); \end_layout \begin_layout LyX-Code g3->add(g4); \end_layout \begin_layout LyX-Code g3->add("my/device/07"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g1->add("my/device/01"); \end_layout \begin_layout LyX-Code g1->add(g2); \end_layout \begin_layout LyX-Code g1->add("my/device/03"); \end_layout \begin_layout LyX-Code g1->add(g3); \end_layout \begin_layout LyX-Code g1->add("my/device/02"); \end_layout \begin_layout Standard The result order in the Tango::GroupCmdReplyList depends on the value of the forward \begin_inset Index idx status collapsed \begin_layout Plain Layout forward \end_layout \end_inset option. If set to \emph on true \emph default , the results will be organized as follows: \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl = g1->command_inout("Status", true); \end_layout \begin_layout Standard \emph on crl[0] \emph default contains the status of my/device/01 which belongs to g1 \begin_inset Newline newline \end_inset \emph on crl[1] \emph default contains the status of my/device/04 which belongs to g1.g2 \begin_inset Newline newline \end_inset \emph on crl[2] \emph default contains the status of my/device/05 which belongs to g1.g2 \begin_inset Newline newline \end_inset \emph on crl[3] \emph default contains the status of my/device/03 which belongs to g1 \begin_inset Newline newline \end_inset \emph on crl[4] \emph default contains the status of my/device/06 which belongs to g1.g3 \begin_inset Newline newline \end_inset \emph on crl[5] \emph default contains the status of my/device/08 which belongs to g1.g3.g4 \begin_inset Newline newline \end_inset \emph on crl[6] \emph default contains the status of my/device/09 which belongs to g1.g3.g \begin_inset Newline newline \end_inset \emph on crl[7] \emph default contains the status of my/device/07 which belongs to g1.g3 \begin_inset Newline newline \end_inset \emph on crl[8] \emph default contains the status of my/device/02 which belongs to g1 \end_layout \begin_layout Standard If the forward option is set to \emph on false \emph default , the results are: \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl = g1->command_inout("Status", false); \end_layout \begin_layout Standard \emph on crl[0] \emph default contains the status of my/device/01 which belongs to g \begin_inset Newline newline \end_inset \emph on crl[1] \emph default contains the status of my/device/03 which belongs to g1 \begin_inset Newline newline \end_inset \emph on crl[2] \emph default contains the status of my/device/02 which belongs to g1 \end_layout \begin_layout Standard The Tango::GroupCmdReply contains some public members allowing the identificatio n of both the device (Tango::GroupCmdReply::dev_name \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-name \end_layout \end_inset ) and the command (Tango::GroupCmdReply::obj_name \begin_inset Index idx status collapsed \begin_layout Plain Layout obj-name \end_layout \end_inset ). It means that, depending of your application, you can associate a response with its source using its position in the response list or using the Tango::Gro upCmdReply::dev_name member. \end_layout \begin_layout Subsubsection Case 1: a command, no argument \begin_inset CommandInset label LatexCommand label name "sub:Case-1" \end_inset \end_layout \begin_layout Standard As an example, we execute the Status command on the whole hierarchy synchronousl y. \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl = gauges->command_inout("Status"); \end_layout \begin_layout Standard As a first step in the results processing, it could be interesting to check value returned by the \emph on has_failed \begin_inset Index idx status collapsed \begin_layout Plain Layout has-failed \end_layout \end_inset () \emph default method of the GroupCmdReplyList \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupCmdReplyList \end_layout \end_inset . If it is set to true, it means that at least one error occurred during the execution of the command (i.e. at least one device gave error). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code if (crl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "at least one error occurred" << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "no error " << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Now, we have to process each "individual response" in the list. \end_layout \begin_layout Subsubsection A few words on error handling and data extraction \end_layout \begin_layout Standard Depending of the application and/or the developer's programming habits, each individual error can be handle by the C++ (or Java) exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset mechanism or using the dedicated \emph on has_failed \begin_inset Index idx status collapsed \begin_layout Plain Layout has-failed \end_layout \end_inset () \emph default method. The GroupReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupReply \end_layout \end_inset class - which is the mother class of both GroupCmdReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupCmdReply \end_layout \end_inset and GroupAttrReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupAttrReply \end_layout \end_inset - contains a static method to enable (or disable) exceptions called \emph on enable_exception() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout enable-exception() \end_layout \end_inset . By default, exceptions are disabled. The following example is proposed with both exceptions enable and disable. \end_layout \begin_layout Standard In C++, data can be extracted directly from an individual reply. The GroupCmdReply interface contains a template operator >> allowing the extraction of any supported Tango type (in fact the actual data extraction is delegated to DeviceData::operator >>). One dedicated extract method is also provided in order to extract DevVarLongStr ingArray and DevVarDoubleStringArray types to std::vectors. \end_layout \begin_layout Standard Error and data handling C++ example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code //- synch. group command example with exception enabled \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code //- enable exceptions and save current mode \end_layout \begin_layout LyX-Code bool last_mode = GroupReply::enable_exception(true); \end_layout \begin_layout LyX-Code //- process each response in the list ... \end_layout \begin_layout LyX-Code for (int r = 0; r < crl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- enter a try/catch block \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- try to extract the data from the r-th reply \end_layout \begin_layout LyX-Code //- suppose data contains a double \end_layout \begin_layout LyX-Code double ans; \end_layout \begin_layout LyX-Code crl[r] >> ans; \end_layout \begin_layout LyX-Code cout << crl[r].dev_name() \end_layout \begin_layout LyX-Code << "::" \end_layout \begin_layout LyX-Code << crl[r].obj_name() \end_layout \begin_layout LyX-Code << " returned " \end_layout \begin_layout LyX-Code << ans \end_layout \begin_layout LyX-Code << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- DevFailed caught while trying to extract the data from reply \end_layout \begin_layout LyX-Code for (int err = 0; err < df.errors.length(); err++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "error: " << df.errors[err].desc.in() << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- alternatively, one can use crl[r].get_err_stack() see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (...) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "unknown exception caught"; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- restore last exception mode (if needed) \end_layout \begin_layout LyX-Code GroupReply::enable_exception(last_mode); \end_layout \begin_layout LyX-Code //- Clear the response list (if reused later in the code) \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code //- synch. group command example with exception disabled \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code //- disable exceptions and save current mode bool \end_layout \begin_layout LyX-Code last_mode = GroupReply::enable_exception(false); \end_layout \begin_layout LyX-Code //- process each response in the list ... \end_layout \begin_layout LyX-Code for (int r = 0; r < crl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- did the r-th device give error? \end_layout \begin_layout LyX-Code if (crl[r].has_failed() == true) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- printout error description \end_layout \begin_layout LyX-Code cout << "an error occurred while executing " \end_layout \begin_layout LyX-Code << crl[r].obj_name() \end_layout \begin_layout LyX-Code << " on " \end_layout \begin_layout LyX-Code << crl[r].dev_name() << endl; \end_layout \begin_layout LyX-Code //- dump error stack \end_layout \begin_layout LyX-Code const DevErrorList& el = crl[r].get_err_stack(); \end_layout \begin_layout LyX-Code for (int err = 0; err < el.size(); err++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << el[err].desc.in(); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- no error (suppose data contains a double) \end_layout \begin_layout LyX-Code double ans; \end_layout \begin_layout LyX-Code bool result = crl[r] >> ans; \end_layout \begin_layout LyX-Code if (result == false) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "could not extract double from " \end_layout \begin_layout LyX-Code << crl[r].dev_name() \end_layout \begin_layout LyX-Code << " reply" \end_layout \begin_layout LyX-Code << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << crl[r].dev_name() \end_layout \begin_layout LyX-Code << "::" \end_layout \begin_layout LyX-Code << crl[r].obj_name() \end_layout \begin_layout LyX-Code << " returned " \end_layout \begin_layout LyX-Code << ans \end_layout \begin_layout LyX-Code << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- restore last exception mode (if needed) \end_layout \begin_layout LyX-Code GroupReply::enable_exception(last_mode); \end_layout \begin_layout LyX-Code //- Clear the response list (if reused later in the code) \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Now execute the same command asynchronously. C++ example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code //- asynch. group command example (C++ example) \end_layout \begin_layout LyX-Code //------------------------------------------------------- \end_layout \begin_layout LyX-Code long request_id = gauges->command_inout_asynch("Status"); \end_layout \begin_layout LyX-Code //- do some work \end_layout \begin_layout LyX-Code do_some_work(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- get results \end_layout \begin_layout LyX-Code crl = gauges->command_inout_reply(request_id); \end_layout \begin_layout LyX-Code //- process responses as previously describe in the synch. implementation \end_layout \begin_layout LyX-Code for (int r = 0; r < crl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- data processing and error handling goes here \end_layout \begin_layout LyX-Code //- copy/paste code from previous example \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- clear the response list (if reused later in the code) \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsubsection Case 2: a command, one argument \begin_inset CommandInset label LatexCommand label name "sub:Case-2" \end_inset \end_layout \begin_layout Standard Here, we give an example in which the same input argument is applied to all devices in the group (or its sub-groups). \end_layout \begin_layout Standard In C++: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- the argument value \end_layout \begin_layout LyX-Code double d = 0.1; \end_layout \begin_layout LyX-Code //- insert it into the TANGO generic container for command: DeviceData \end_layout \begin_layout LyX-Code Tango::DeviceData dd; \end_layout \begin_layout LyX-Code dd << d; \end_layout \begin_layout LyX-Code //- execute the command: Dev_Void SetDummyFactor (Dev_Double) \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl = gauges->command_inout("SetDummyFactor", dd); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Since the SetDummyFactor command does not return any value, the individual replies (i.e. the GroupCmdReply) do not contain any data. However, we have to check their \emph on has_failed \begin_inset Index idx status collapsed \begin_layout Plain Layout has-failed \end_layout \end_inset () \emph default method returned value to be sure that the command completed successfully on each device (acknowledgement). Note that in such a case, exceptions are useless since we never try to extract data from the replies. \end_layout \begin_layout Standard In C++ we should have something like: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- no need to process the results if no error occurred (Dev_Void command) \end_layout \begin_layout LyX-Code if (crl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- at least one error occurred \end_layout \begin_layout LyX-Code for (int r = 0; r < crl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- handle errors here (see previous C++ examples) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- clear the response list (if reused later in the code) \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard See case 1 for an example of asynchronous command. \end_layout \begin_layout Subsubsection Case 3: a command, several arguments \begin_inset CommandInset label LatexCommand label name "sub:Case-3" \end_inset \end_layout \begin_layout Standard Here, we give an example in which a \series bold specific \series default input argument is applied to each device in the hierarchy. In order to use this form of command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset , the user must have an "a priori" and "perfect" knowledge of the devices order in the hierarchy. In such a case, command arguments are passed in an "array" (with one entry for each device in the hierarchy). \end_layout \begin_layout Standard The C++ implementation provides a template method which accepts a std::vector of "C++ type for command argument". This allows passing any kind of data using a single method. \end_layout \begin_layout Standard The size of this vector must equal the number of device in the hierarchy (respectively the number of device in the group) if the forward \begin_inset Index idx status collapsed \begin_layout Plain Layout forward \end_layout \end_inset option is set to true (respectively set to false). Otherwise, an exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset is thrown. \end_layout \begin_layout Standard The first item in the vector is applied to the first device in the hierarchy, the second to the second device in the hierarchy, and so on\SpecialChar \ldots{} That's why the user must have a "perfect" knowledge of the devices order in the hierarchy. \end_layout \begin_layout Standard Assuming that gauges are ordered by name, the SetDummyFactor command can be executed on group "cell-01" (and its sub-groups) as follows: \end_layout \begin_layout Standard Remember, "cell-01" has the following internal structure: \end_layout \begin_layout LyX-Code -> gauges \end_layout \begin_layout LyX-Code | -> cell-01 \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/strange \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-xx \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-01 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-xx \end_layout \begin_layout Standard Passing a specific argument to each device in C++: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- get a reference to the target group \end_layout \begin_layout LyX-Code Tango::Group *g = gauges->get_group("cell-01"); \end_layout \begin_layout LyX-Code //- get number of device in the hierarchy (starting at cell-01) \end_layout \begin_layout LyX-Code long n_dev = g->get_size(true); \end_layout \begin_layout LyX-Code //- Build argin list \end_layout \begin_layout LyX-Code std::vector argins(n_dev); \end_layout \begin_layout LyX-Code //- argument for inst-c01/vac-gauge/strange \end_layout \begin_layout LyX-Code argins[0] = 0.0; \end_layout \begin_layout LyX-Code //- argument for inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code argins[1] = 0.1; \end_layout \begin_layout LyX-Code //- argument for inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code argins[2] = 0.2; \end_layout \begin_layout LyX-Code //- argument for remaining devices in cell-01.penning \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- argument for devices in cell-01.pirani \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- the reply list \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl; \end_layout \begin_layout LyX-Code //- enter a try/catch block (see below) \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- execute the command \end_layout \begin_layout LyX-Code crl = g->command_inout("SetDummyFactor", argins, true); \end_layout \begin_layout LyX-Code if (crl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- error handling goes here (see case 1) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard If we want to execute the command locally on "cell-01" (i.e. not on its sub-groups), we should write the following C++ code: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- get a reference to the target group \end_layout \begin_layout LyX-Code Tango::Group *g = gauges->get_group("cell-01"); \end_layout \begin_layout LyX-Code //- get number of device in the group (starting at cell-01) \end_layout \begin_layout LyX-Code long n_dev = g->get_size(false); \end_layout \begin_layout LyX-Code //- Build argin list \end_layout \begin_layout LyX-Code std::vector argins(n_dev); \end_layout \begin_layout LyX-Code //- argins for inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code argins[0] = 0.1; \end_layout \begin_layout LyX-Code //- argins for inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code argins[1] = 0.2; \end_layout \begin_layout LyX-Code //- argins for remaining devices in cell-01.penning \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- the reply list \end_layout \begin_layout LyX-Code Tango::GroupCmdReplyList crl; \end_layout \begin_layout LyX-Code //- enter a try/catch block (see below) \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- execute the command \end_layout \begin_layout LyX-Code crl = g->command_inout("SetDummyFactor", argins, false); \end_layout \begin_layout LyX-Code if (crl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- error handling goes here (see case 1) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code crl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Note: if we want to execute the command locally on "cell-01" (i.e. not on its sub-groups), we should write the following code: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- get a reference to the target group \end_layout \begin_layout LyX-Code Group g = gauges.get_group("cell-01"); \end_layout \begin_layout LyX-Code //- get pre-build arguments list for the group (starting@cell-01) \end_layout \begin_layout LyX-Code DeviceData[] argins = g.get_command_specific_argument_list(false); \end_layout \begin_layout LyX-Code //- argins for inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code argins[0].insert(0.1); \end_layout \begin_layout LyX-Code //- argins for inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code argins[1].insert(0.2); \end_layout \begin_layout LyX-Code //- argins for remaining devices in cell-01.penning \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- the reply list \end_layout \begin_layout LyX-Code GroupCmdReplyList crl; \end_layout \begin_layout LyX-Code //- enter a try/catch block (see below) \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- execute the command \end_layout \begin_layout LyX-Code crl = g.command_inout("SetDummyFactor", argins, false, false); \end_layout \begin_layout LyX-Code if (crl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- error handling goes here (see case 1) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (DevFailed d) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard This form of \emph on command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset \emph default (the one that accepts an array of value as its input argument), may throw an exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset \series bold before \series default executing the command if the number of elements in the input array does not match the number of individual devices in the group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset or in the hierarchy (depending on the forward option). \end_layout \begin_layout Standard An asynchronous version of this method is also available. See case 1 for an example of asynchronous command. \end_layout \begin_layout Subsection Reading attribute(s) \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "sub:Read-attr" \end_inset \end_layout \begin_layout Standard In order to read attribute(s), the Group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset interface contains several implementations of the \emph on read_attribute() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute \end_layout \end_inset and \emph on read_attributes() \emph default methods. Both synchronous and asynchronous forms are supported. Reading several attributes is very similar to reading a single attribute. Simply replace the std::string used for attribute name by a vector of std::stri ng with one element for each attribute name. In case of read_attributes() call, the order of attribute value returned in the GroupAttrReplyList is all attributes for first element in the group followed by all attributes for the second group element and so on. \end_layout \begin_layout Subsubsection Obtaining attribute values \begin_inset CommandInset label LatexCommand label name "sub:O-attr-values" \end_inset \end_layout \begin_layout Standard Attribute values are returned using a GroupAttrReplyList \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupAttrReplyList \end_layout \end_inset . This is nothing but an array containing a GroupAttrReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupAttrReply \end_layout \end_inset for each device in the group. The GroupAttrReply contains the actual data (i.e. the DeviceAttribute). By inheritance, it may also contain any error occurred during the execution of the command (in which case the data is invalid). \end_layout \begin_layout Standard Here again, the Tango Group implementation guarantees that the attribute values are returned in the order in which its elements were attached to the group. See Obtaining command results for details. \end_layout \begin_layout Standard The GroupAttrReply contains some public methods allowing the identification of both the device (GroupAttrReply::dev_name \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-name \end_layout \end_inset ) and the attribute (GroupAttrReply::obj_name \begin_inset Index idx status collapsed \begin_layout Plain Layout obj-name \end_layout \end_inset ). It means that, depending of your application, you can associate a response with its source using its position in the response list or using the Tango::Gro upAttrReply::dev_name member. \end_layout \begin_layout Subsubsection A few words on error handling and data extraction \end_layout \begin_layout Standard Here again, depending of the application and/or the developer's programming habits, each individual error can be handle by the C++ exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset mechanism or using the dedicated \emph on has_failed \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout has-failed \end_layout \end_inset \emph on () \emph default method. The GroupReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupReply \end_layout \end_inset class - which is the mother class of both GroupCmdReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupCmdReply \end_layout \end_inset and GroupAttrReply \begin_inset Index idx status collapsed \begin_layout Plain Layout GroupAttrReply \end_layout \end_inset - contains a static method to enable (or disable) exceptions called \emph on enable_exception() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout enable-exception() \end_layout \end_inset . By default, exceptions are disabled. The following example is proposed with both exceptions enable and disable. \end_layout \begin_layout Standard In C++, data can be extracted directly from an individual reply. The GroupAttrReply interface contains a template operator>> allowing the extraction of any supported Tango type (in fact the actual data extraction is delegated to DeviceAttribute::operator>>). \end_layout \begin_layout Standard Reading an attribute is very similar to executing a command. \end_layout \begin_layout Standard Reading an attribute in C++: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //----------------------------------------------------------------- \end_layout \begin_layout LyX-Code //- synch. read "vacuum" attribute on each device in the hierarchy \end_layout \begin_layout LyX-Code //- with exceptions enabled - C++ example \end_layout \begin_layout LyX-Code //----------------------------------------------------------------- \end_layout \begin_layout LyX-Code //- enable exceptions and save current mode \end_layout \begin_layout LyX-Code bool last_mode = GroupReply::enable_exception(true); \end_layout \begin_layout LyX-Code //- read attribute \end_layout \begin_layout LyX-Code Tango::GroupAttrReplyList arl = gauges->read_attribute("vacuum"); \end_layout \begin_layout LyX-Code //- for each response in the list ... \end_layout \begin_layout LyX-Code for (int r = 0; r < arl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- enter a try/catch block \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- try to extract the data from the r-th reply \end_layout \begin_layout LyX-Code //- suppose data contains a double \end_layout \begin_layout LyX-Code double ans; \end_layout \begin_layout LyX-Code arl[r] >> ans; \end_layout \begin_layout LyX-Code cout << arl[r].dev_name() \end_layout \begin_layout LyX-Code << "::" \end_layout \begin_layout LyX-Code << arl[r].obj_name() \end_layout \begin_layout LyX-Code << " value is " \end_layout \begin_layout LyX-Code << ans << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- DevFailed caught while trying to extract the data from reply \end_layout \begin_layout LyX-Code for (int err = 0; err < df.errors.length(); err++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "error: " << df.errors[err].desc.in() << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- alternatively, one can use arl[r].get_err_stack() see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (...) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "unknown exception caught"; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- restore last exception mode (if needed) \end_layout \begin_layout LyX-Code GroupReply::enable_exception(last_mode); \end_layout \begin_layout LyX-Code //- clear the reply list (if reused later in the code) \end_layout \begin_layout LyX-Code arl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard In C++, an asynchronous version of the previous example could be: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- read the attribute asynchronously \end_layout \begin_layout LyX-Code long request_id = gauges->read_attribute_asynch("vacuum"); \end_layout \begin_layout LyX-Code //- do some work \end_layout \begin_layout LyX-Code do_some_work(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- get results \end_layout \begin_layout LyX-Code Tango::GroupAttrReplyList arl = gauges->read_attribute_reply(request_id); \end_layout \begin_layout LyX-Code //- process replies as previously described in the synch. implementation \end_layout \begin_layout LyX-Code for (int r = 0; r < arl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- data processing and/or error handling goes here \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- clear the reply list (if reused later in the code) \end_layout \begin_layout LyX-Code arl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsection Writing an attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \end_layout \begin_layout Standard The Group interface contains several implementations of the \emph on write_attribute() \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attribute \end_layout \end_inset method. Both synchronous and asynchronous forms are supported. However, writing more than one attribute at a time is not supported. \end_layout \begin_layout Subsubsection Obtaining acknowledgement \begin_inset CommandInset label LatexCommand label name "sub:O-ack" \end_inset \end_layout \begin_layout Standard Acknowledgements are returned using a GroupReplyList. This is nothing but an array containing a GroupReply for each device in the group. The GroupReply may contain any error occurred during the execution of the command. The return value of the \emph on has_failed \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout has-failed \end_layout \end_inset \emph on () \emph default method indicates whether an error occurred or not. If this flag is set to true, the \emph on GroupReply::get_err_stack() \begin_inset Index idx status collapsed \begin_layout Plain Layout get-err-stack \end_layout \end_inset \emph default method gives error details. \end_layout \begin_layout Standard Here again, the Tango Group \begin_inset Index idx status collapsed \begin_layout Plain Layout group \end_layout \end_inset implementation guarantees that the attribute values are returned in the order in which its elements were attached to the group. See Obtaining command results for details. \end_layout \begin_layout Standard The GroupReply contains some public members allowing the identification of both the device (GroupReply::dev_name \begin_inset Index idx status collapsed \begin_layout Plain Layout dev-name \end_layout \end_inset ) and the attribute (GroupReply::obj_name \begin_inset Index idx status collapsed \begin_layout Plain Layout obj-name \end_layout \end_inset ). It means that, depending of your application, you can associate a response with its source using its position in the response list or using the GroupReply ::dev_name member. \end_layout \begin_layout Subsubsection Case 1: one value for all devices \begin_inset CommandInset label LatexCommand label name "sub:Case-1-writing" \end_inset \end_layout \begin_layout Standard Here, we give an example in which the same attribute value is written on all devices in the group (or its sub-groups). Exceptions are supposed to be disabled. \end_layout \begin_layout Standard Writing an attribute in C++: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //----------------------------------------------------------------- \end_layout \begin_layout LyX-Code //- synch. write "dummy" attribute on each device in the hierarchy \end_layout \begin_layout LyX-Code //----------------------------------------------------------------- \end_layout \begin_layout LyX-Code //- assume each device support a "dummy" writable attribute \end_layout \begin_layout LyX-Code //- insert the value to be written into a generic container \end_layout \begin_layout LyX-Code Tango::DeviceAttribute value(std::string("dummy"), 3.14159); \end_layout \begin_layout LyX-Code //- write the attribute \end_layout \begin_layout LyX-Code Tango::GroupReplyList rl = gauges->write_attribute(value); \end_layout \begin_layout LyX-Code //- any error? \end_layout \begin_layout LyX-Code if (rl.has_failed() == false) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "no error" << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "at least one error occurred" << endl; \end_layout \begin_layout LyX-Code //- for each response in the list ... \end_layout \begin_layout LyX-Code for (int r = 0; r < rl.size(); r++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- did the r-th device give error? \end_layout \begin_layout LyX-Code if (rl[r].has_failed() == true) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- printout error description \end_layout \begin_layout LyX-Code cout << "an error occurred while reading " \end_layout \begin_layout LyX-Code << rl[r].obj_name() \end_layout \begin_layout LyX-Code << " on " \end_layout \begin_layout LyX-Code << rl[r].dev_name() \end_layout \begin_layout LyX-Code << endl; \end_layout \begin_layout LyX-Code //- dump error stack \end_layout \begin_layout LyX-Code const DevErrorList& el = rl[r].get_err_stack(); \end_layout \begin_layout LyX-Code for (int err = 0; err < el.size(); err++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << el[err].desc.in(); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code //- clear the reply list (if reused later in the code) \end_layout \begin_layout LyX-Code rl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Here is a C++ asynchronous version: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- insert the value to be written into a generic container \end_layout \begin_layout LyX-Code Tango::DeviceAttribute value(std::string("dummy"), 3.14159); \end_layout \begin_layout LyX-Code //- write the attribute asynchronously \end_layout \begin_layout LyX-Code long request_id = gauges.write_attribute_asynch(value); \end_layout \begin_layout LyX-Code //- do some work \end_layout \begin_layout LyX-Code do_some_work(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code //- get results \end_layout \begin_layout LyX-Code Tango::GroupReplyList rl = gauges->write_attribute_reply(request_id); \end_layout \begin_layout LyX-Code //- process replies as previously describe in the synch. implementation ... \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsubsection Case 2: a specific value per device \begin_inset CommandInset label LatexCommand label name "sub:Case-2-writing" \end_inset \end_layout \begin_layout Standard Here, we give an example in which a \series bold specific \series default attribute value is applied to each device in the hierarchy. In order to use this form of \emph on write_attribute() \emph default , the user must have an "a priori" and "perfect" knowledge of the devices order in the hierarchy. \end_layout \begin_layout Standard The C++ implementation provides a template method which accepts a std::vector of "C++ type for command argument". This allows passing any kind of data using a single method. \end_layout \begin_layout Standard The size of this vector must equal the number of device in the hierarchy (respectively the number of device in the group) if the forward \begin_inset Index idx status collapsed \begin_layout Plain Layout forward \end_layout \end_inset option is set to true (respectively set to false). Otherwise, an exception \begin_inset Index idx status collapsed \begin_layout Plain Layout exception \end_layout \end_inset is thrown. \end_layout \begin_layout Standard The first item in the vector is applied to the first device in the group, the second to the second device in the group, and so on\SpecialChar \ldots{} That's why the user must have a "perfect" knowledge of the devices order in the group. \end_layout \begin_layout Standard Assuming that gauges are ordered by name, the dummy attribute can be written as follows on group "cell-01" (and its sub-groups) as follows: \end_layout \begin_layout Standard Remember, "cell-01" has the following internal structure: \end_layout \begin_layout LyX-Code -> gauges \end_layout \begin_layout LyX-Code | -> cell-01 \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/strange \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | | |-> inst-c01/vac-gauge/penning-xx \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-01 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | |-> inst-c01/vac-gauge/pirani-xx \end_layout \begin_layout Standard C++ version: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- get a reference to the target group \end_layout \begin_layout LyX-Code Tango::Group *g = gauges->get_group("cell-01"); \end_layout \begin_layout LyX-Code //- get number of device in the hierarchy (starting at cell-01) \end_layout \begin_layout LyX-Code long n_dev = g->get_size(true); \end_layout \begin_layout LyX-Code //- Build value list \end_layout \begin_layout LyX-Code std::vector values(n_dev); \end_layout \begin_layout LyX-Code //- value for inst-c01/vac-gauge/strange \end_layout \begin_layout LyX-Code values[0] = 3.14159; \end_layout \begin_layout LyX-Code //- value for inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code values[1] = 2 * 3.14159; \end_layout \begin_layout LyX-Code //- value for inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code values[2] = 3 * 3.14159; \end_layout \begin_layout LyX-Code //- value for remaining devices in cell-01.penning \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- value for devices in cell-01.pirani \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- the reply list \end_layout \begin_layout LyX-Code Tango::GroupReplyList rl; \end_layout \begin_layout LyX-Code //- enter a try/catch block (see below) \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- write the "dummy" attribute \end_layout \begin_layout LyX-Code rl = g->write_attribute("dummy", values, true); \end_layout \begin_layout LyX-Code if (rl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- error handling (see previous cases) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code rl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Note: if we want to execute the command locally on "cell-01" (i.e. not on its sub-groups), we should write the following code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code //- get a reference to the target group \end_layout \begin_layout LyX-Code Tango::Group *g = gauges->get_group("cell-01"); \end_layout \begin_layout LyX-Code //- get number of device in the group \end_layout \begin_layout LyX-Code long n_dev = g->get_size(false); \end_layout \begin_layout LyX-Code //- Build value list \end_layout \begin_layout LyX-Code std::vector values(n_dev); \end_layout \begin_layout LyX-Code //- value for inst-c01/vac-gauge/penning-01 \end_layout \begin_layout LyX-Code values[0] = 2 * 3.14159; \end_layout \begin_layout LyX-Code //- value for inst-c01/vac-gauge/penning-02 \end_layout \begin_layout LyX-Code values[1] = 3 * 3.14159; \end_layout \begin_layout LyX-Code //- value for remaining devices in cell-01.penning \end_layout \begin_layout LyX-Code . . . \end_layout \begin_layout LyX-Code //- the reply list \end_layout \begin_layout LyX-Code Tango::GroupReplyList rl; \end_layout \begin_layout LyX-Code //- enter a try/catch block (see below) \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- write the "dummy" attribute \end_layout \begin_layout LyX-Code rl = g->write_attribute("dummy", values, false); \end_layout \begin_layout LyX-Code if (rl.has_failed()) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- error handling (see previous cases) \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const DevFailed& df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code //- see below \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code rl.reset(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard This form of \emph on write_attribute() \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attribute \end_layout \end_inset \emph default (the one that accepts an array of value as its input argument), may throw an exception before executing the command if the number of elements in the input array does not match the number of individual devices in the group or in the hierarchy (depending on the forward option). \end_layout \begin_layout Standard An asynchronous version of this method is also available. \end_layout \begin_layout Section Reading/Writing device pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium pipe \end_layout \end_inset \end_layout \begin_layout Standard Reading or writing device pipe is made possible using DeviceProxy class methods. To read a pipe, you have to use the method \series bold read_pipe() \series default . To write a pipe, use the \series bold write_pipe() \series default method. A method \series bold write_read_pipe() \series default is also provided in case you need to write then read a pipe in a non-interuptib le way. All these calls generate synchronous request and support only reading or writing a single pipe at a time. Those pipe related DeviceProxy class methods (read_pipe, write_pipe,...) use DevicePipe class instances. A DevicePipe \begin_inset Index idx status collapsed \begin_layout Plain Layout DevicePipe \end_layout \end_inset instance is nothing more than a string for the pipe name and a \emph on DevicePipeBlob \emph default instance called the root blob. In a DevicePipeBlob \begin_inset Index idx status collapsed \begin_layout Plain Layout DevicePipeBlob \end_layout \end_inset instance, you have: \end_layout \begin_layout Itemize The blob name \end_layout \begin_layout Itemize One array of \emph on DataElement. \emph default Each instance of this DataElement class has: \end_layout \begin_deeper \begin_layout Itemize A name \end_layout \begin_layout Itemize A value which can be either \end_layout \begin_deeper \begin_layout Itemize Scalar or array of any basic Tango type \end_layout \begin_layout Itemize Another DevicePipeBlob \end_layout \end_deeper \end_deeper \begin_layout Standard Therefore, this is a recursive data structure and you may have DevicePipeBlob in DevicePipeBlob. There is no limit on the depth of this recursivity even if it is not recommende d to have a too large depth. The following figure summarizes DevicePipe data structure \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename pipe.eps width 14cm height 8cm \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout DevicePipe data structure \begin_inset CommandInset label LatexCommand label name " " \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard Many methods to insert/extract data into/from a DevicePipe are available. In the DevicePipe class, these methods simply forward their action to the DevicePipe root blob. The same methods are available in the DevicePipeBlob in case you need to use the recursivity provided by this data structure. \end_layout \begin_layout Subsection Reading a pipe \end_layout \begin_layout Standard When you read a pipe, you have to extract data received from the pipe. Because data transferred through a pipe can change at any moment, two different s cases are possible: \end_layout \begin_layout Enumerate The client has a prior knowledge of what should be transferred through the pipe \end_layout \begin_layout Enumerate The client does not know at all what has been received through the pipe \end_layout \begin_layout Standard Those two cases are detailed in the following sub-chapters. \end_layout \begin_layout Subsubsection Extracting data with pipe content prior knowledge \end_layout \begin_layout Standard To extract data from a DevicePipe object (or from a DevicePipeBlob object), you have to use its extraction operator ">>". Let's suppose that we already know (prior knowledge) that the pipe contains 3 data elements with a Tango long, an array of double and finally an array of unsigned short. The code you need to extract these data is (Without error case treatment detailed in a next sub-chapter) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp = mydev.read_pipe("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 DevLong dl; \end_layout \begin_layout LyX-Code 4 vector v_db; \end_layout \begin_layout LyX-Code 5 DevVarUShortArray *dvush = new DevVarUShortArray(); \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 dp >> dl >> v_db >> dvush; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 delete dvush; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The pipe is read at line 1. Pipe (or root blob) data extracttion is at line 7. As you can see, it is just a matter of chaining extraction operator (">>") into local data (declared line 3 to 5). In this example, the transported array of double is extracted into a C++ vector while the unsigned short array is extracted in a Tango sequence data type. When you extract data into a vector, there is a unavoidable memory copy between the DevicePipe object and the vector. When you extract data in a Tango sequence data type, there is no memory copy but the extraction method consumes the memory and it is therefore caller responsability to delete the memory. This is the rule of line 9. If there is a DevicePipeBlob inside the DevicePipe, simply extract it into one instance of the DevicePipeBlob class. \end_layout \begin_layout Standard You may notice that the pipe root blob data elements name are lost in the previous example. The Tango API also has a DataElement \begin_inset Index idx status collapsed \begin_layout Plain Layout DataElement \end_layout \end_inset class which allows you to retrieve/set data element name. The following code is how you can extract pipe data and retrieve data element name (same pipe then previously) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp = mydev.read_pipe("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 DataElement de_dl; \end_layout \begin_layout LyX-Code 4 DataElement > de_v_db; \end_layout \begin_layout LyX-Code 5 DataElement de_dvush(new DevVarUShortArray()); \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 dp >> de_dl >> de_v_db >> de_dvush; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 delete de_dvush.value; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The extraction line (number 7) is similar to the previous case but local data are instances of DataElement class. This is template class and instances are created at lines 4 to 6. Each DataElement instance has only two elements which are: \end_layout \begin_layout Enumerate The data element name (a C++ string): \emph on name \end_layout \begin_layout Enumerate The data element value (One instance of the template parameter): \emph on value \end_layout \begin_layout Subsubsection Extracting data in a generic way (without prior knowledge) \end_layout \begin_layout Standard Due to the dynamicity of the data transferred through a pipe, the API alows to extract data from a pipe without any prior knowledge of its content. This is achived with methods \emph on get_data_elt_nb() \emph default , \emph on get_data_elt_type() \emph default , \emph on get_data_elt_name() \emph default and the extraction operator ">>". These methods belong to the DevicePipeBlob class but they also exist on the DevicePipe class for its root blob. Here is one example of how you use them: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp = mydev.read_pipe("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 size_t nb_de = dp.get_data_elt_nb(); \end_layout \begin_layout LyX-Code 4 for (size_t loop = 0;loop < nb;loop++) \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 int data_type = dp.get_data_elt_type(loop); \end_layout \begin_layout LyX-Code 7 string de_name = dp.get_data_elt_name(loop); \end_layout \begin_layout LyX-Code 8 switch(data_type) \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 case DEV_LONG: \end_layout \begin_layout LyX-Code 11 { \end_layout \begin_layout LyX-Code 12 DevLong lg; \end_layout \begin_layout LyX-Code 13 dp >> lg; \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 break; \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 case DEVVAR_DOUBLEARRAY: \end_layout \begin_layout LyX-Code 18 { \end_layout \begin_layout LyX-Code 19 vector v_db; \end_layout \begin_layout LyX-Code 20 dp >> v_db; \end_layout \begin_layout LyX-Code 21 } \end_layout \begin_layout LyX-Code 22 break; \end_layout \begin_layout LyX-Code 23 .... \end_layout \begin_layout LyX-Code 24 } \end_layout \begin_layout LyX-Code 25 ... \end_layout \begin_layout LyX-Code 26 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The number of data element in the pipe root blob is retrieve at line 3. Then a loop for each data element is coded. For each data element, its value data type and its name are retrieved at lines 6 and 7. Then, according to the data element value data type, the data are extracted using the classical extraction operator (lines 13 or 20) \end_layout \begin_layout Subsubsection Error management \end_layout \begin_layout Standard By default, in case of error, the DevicePipe object throws different kind of exceptions according to the error kind. It is possible to disable exception throwing. If you do so, the code has to test the DevicePipe state after extraction. The possible error cases are: \end_layout \begin_layout Itemize DevicePipe object is empty \end_layout \begin_layout Itemize Wrong data type for extraction (For instance extraction into a double data while the DataElement contains a string) \end_layout \begin_layout Itemize Wrong number of DataElement (Extraction code extract 5 data element while the pipe contains only four) \end_layout \begin_layout Itemize Mix of extraction (or insertion) method kind (classical operators << or >>) and [] operator. \end_layout \begin_layout Standard Methods \emph on exceptions() \emph default and \emph on reset_exceptions() \emph default of the DevicePipe and DevicePipeBlob classes allow the user to select which kind of error he is interested in. For error treatment without exceptions, methods \emph on has_failed() \emph default and \emph on state() \emph default has to be used. See reference documentation for details about these methods. \end_layout \begin_layout Subsection Writing a pipe \end_layout \begin_layout Standard Writing data into a DevicePipe or a DevicePipeBlob is similar to reading data from a pipe. The main method is the insertion operator "<<". Let's have a look at a first example if you want to write a pipe with a Tango long, a vector of double and finally an array of unsigned short. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 vector de_names {"FirstDE","SecondDE","ThirdDE"}; \end_layout \begin_layout LyX-Code 4 db.set_data_elt_names(de_names); \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 DevLong dl = 666; \end_layout \begin_layout LyX-Code 7 vector v_db {1.11,2.22}; \end_layout \begin_layout LyX-Code 8 unsigned short *array = new unsigned short [100]; \end_layout \begin_layout LyX-Code 9 DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 try \end_layout \begin_layout LyX-Code 12 { \end_layout \begin_layout LyX-Code 12 dp << dl << v_db << dvush; \end_layout \begin_layout LyX-Code 13 mydev.write_pipe(dp); \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 16 { \end_layout \begin_layout LyX-Code 17 cout << "DevicePipeBlob insertion failed" << endl; \end_layout \begin_layout LyX-Code 18 .... \end_layout \begin_layout LyX-Code 19 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Insertion into the DevicePipe is done at line 12 with the insert operators. The main difference with extracting data from the pipe is at line 3 and 4. When inserting data into a pipe, you need to FIRST define its number od name of data elements. In our example, the device pipe is initialized to carry three data element and the names of these data elements is defined at line 4. This is a mandatory requirement. If you don't define data element number, exception will be thrown during the use of insertion methods. The population of the array used for the third pipe data element is not represented here. \end_layout \begin_layout Standard It's also possible to use DataElement class instances to set the pipe data element. Here is the previous example modified to use DataElement class. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 DataElement de_dl("FirstElt",666); \end_layout \begin_layout LyX-Code 4 vector v_db {1.11,2.22}; \end_layout \begin_layout LyX-Code 5 DataElement > de_v_db("SecondElt,v_db); \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 unsigned short *array = new unsigned short [100]; \end_layout \begin_layout LyX-Code 8 DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); \end_layout \begin_layout LyX-Code 9 DataElement de_dvush("ThirdDE",array); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 try \end_layout \begin_layout LyX-Code 12 { \end_layout \begin_layout LyX-Code 12 dp << de_dl << de_v_db << de_dvush; \end_layout \begin_layout LyX-Code 13 mydev.write_pipe(dp); \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 16 { \end_layout \begin_layout LyX-Code 17 cout << "DevicePipeBlob insertion failed" << endl; \end_layout \begin_layout LyX-Code 18 .... \end_layout \begin_layout LyX-Code 19 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The population of the array used for the third pipe data element is not represented here. Finally, there is a third way to insert data into a device pipe. You have to defined number and names of the data element within the pipe (similar to first insertion method) but you are able to insert data into the data element in any order using the "[]" operator overwritten for the DevicePipe and DevicePipeBlob classes. Look at the following example: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 DevicePipe dp("MyPipe"); \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 vector de_names {"FirstDE","SecondDE","ThirdDE"}; \end_layout \begin_layout LyX-Code 4 db.set_data_elt_names(de_names); \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 DevLong dl = 666; \end_layout \begin_layout LyX-Code 7 vector v_db = {1.11,2.22}; \end_layout \begin_layout LyX-Code 8 unsigned short *array = new unsigned short [100]; \end_layout \begin_layout LyX-Code 9 DevVarUShortArray *dvush = create_DevVarUShortArray(array,100); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 dp["SecondDE"] << v_db; \end_layout \begin_layout LyX-Code 12 dp["FirstDE"] << dl; \end_layout \begin_layout LyX-Code 13 dp["ThirdDE"] << dvush; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Insertion into the device pipe is now done at lines 11 to 13. The population of the array used for the third pipe data element is not represented here. Note that the data element name is case insensitive. \end_layout \begin_layout Subsubsection Error management \end_layout \begin_layout Standard When inserting data into a DevicePipe or a DevicePipeBlob, error management is very similar to reading data from from a DevicePipe or a DevicePipeBlob. The difference is that there is one moer case which could trigger one exception during the insertion. This case is \end_layout \begin_layout Itemize Insertion into the DevicePipe (or DevicePipeBlob) if its data element number have not been set. \end_layout \begin_layout Section Device locking \begin_inset Index idx status collapsed \begin_layout Plain Layout Locking \end_layout \end_inset \end_layout \begin_layout Standard Starting with Tango release 7 (and device inheriting from Device_4Impl), device locking is supported. For instance, this feature could be used by an application doing a scan on a synchrotron beam line. In such a case, you want to move an actuator then read a sensor, move the actuator again, read the sensor...You don't want the actuator to be moved by another client while the application is doing the scan. If the application doing the scan locks the actuator device, it will be sure that this device is "reserved" for the application doing the scan and other client will not be able to move it until the scan application un-locks this actuator. \end_layout \begin_layout Standard A locked device is protected against: \end_layout \begin_layout Itemize \emph on command_inout \emph default call except for device state and status requested via command and for the set of commands defined as allowed following the definition of allowed command in the Tango control access schema. \end_layout \begin_layout Itemize \emph on write_attribute \emph default and \emph on write_pipe \emph default call \end_layout \begin_layout Itemize \emph on write_read_attribute, write_read_attributes \emph default and \emph on write_read_pipe \emph default call \end_layout \begin_layout Itemize \emph on set_attribute_config \emph default and \emph on set_pipe_config \emph default call \end_layout \begin_layout Itemize polling and logging commands related to the locked device \end_layout \begin_layout Standard Other clients trying to do one of these calls on a locked device will get a DevFailed exception. In case of application with locked device crashed, the lock will be automatical ly release after a defined interval. The API provides a set of methods for application code to lock/unlock device. These methods are: \end_layout \begin_layout Itemize \emph on DeviceProxy::lock() \emph default and \emph on DeviceProxy::unlock() \emph default to lock/unlock device \end_layout \begin_layout Itemize \emph on DeviceProxy::locking_status() \emph default , \emph on DeviceProxy::is_locked() \emph default , \emph on DeviceProxy::is_locked_by_me() \emph default and \emph on DeviceProxy::get_locker() \emph default to get locking information \end_layout \begin_layout Standard These methods are precisely described in the API reference chapters. \end_layout \begin_layout Section Reconnection \begin_inset Index idx status collapsed \begin_layout Plain Layout reconnection \end_layout \end_inset and exception \end_layout \begin_layout Standard The Tango API automatically manages re-connection between client and server in case of communication error during a network access between a client and a server. By default, when a communication error occurs, an exception is returned to the caller and the connection is internally marked as bad. On the next try to contact the device, the API will try to re-build the network connection. With the \emph on set_transparency_reconnection \begin_inset Index idx status collapsed \begin_layout Plain Layout set-transparency-reconnection \end_layout \end_inset () \emph default method of the DeviceProxy \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceProxy \end_layout \end_inset class, it is even possible not to have any exception thrown in case of communication error. The API will try to re-build the network connection as soon as it is detected as bad. This is the default mode. See \begin_inset CommandInset ref LatexCommand ref reference "sec:Reconnection-and-exception" \end_inset for more details on this subject. \end_layout \begin_layout Section Thread \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset safety \end_layout \begin_layout Standard Starting with Tango 7.2, some classes of the C++ API has been made thread safe. These classes are: \end_layout \begin_layout Itemize DeviceProxy \end_layout \begin_layout Itemize Database \end_layout \begin_layout Itemize Group \end_layout \begin_layout Itemize ApiUtil \end_layout \begin_layout Itemize AttributeProxy \end_layout \begin_layout Standard This means that it is possible to share between threads a pointer to a DevicePro xy instance. It is safe to execute a call on this DeviceProxy instance while another thread is also doing a call to the same DeviceProxy instance. Obviously, this also means that it is possible to create thread local DevicePro xy instances and to execute method calls on these instances. Nevertheless, data local to a DeviceProxy instance like its timeout are not managed on a per thread basis. For a DeviceProxy instance shared between two threads, if thread 1 changes the instance timeout, thread 2 will also see this change. \end_layout \begin_layout Section Compiling and linking a Tango client \end_layout \begin_layout Standard Compiling and linking a Tango client is similar to compiling and linking a Tango device server. Please, refer to chapter "Compiling, Linking and executing a Tango device server process" ( \begin_inset CommandInset ref LatexCommand ref reference "sec:Compiling,-linking-and" \end_inset ) to get all the details. \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset label LatexCommand label name "ThreeRicardo" \end_inset \begin_inset Graphics filename ../dance/0066-reduc.jpg lyxscale 80 scale 200 \end_inset \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/advanced/0000755023471100065110000000000013034745265013120 500000000000000tango-9.2.5a/doc/src/advanced/Makefile.am0000644023471100065110000000027413034745264015076 00000000000000 if TANGO_DOC_ENABLED pdf-local: img.eps endif img_src = \ alarm img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) tango-9.2.5a/doc/src/advanced/Makefile.in0000644023471100065110000003274313034745264015115 00000000000000# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/src/advanced DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/RSSH_CHECK_OMNIORB.m4 \ $(top_srcdir)/m4/RSSH_CHECK_PTHREADS.m4 \ $(top_srcdir)/m4/RSSH_CHECK_SUNPRO_CC.m4 \ $(top_srcdir)/m4/RSSH_ENABLE_PTHREADS.m4 \ $(top_srcdir)/m4/ac_cxx_have_class_strstream.m4 \ $(top_srcdir)/m4/ac_cxx_have_sstream.m4 \ $(top_srcdir)/m4/ac_cxx_namespaces.m4 \ $(top_srcdir)/m4/ac_path_mariadb.m4 \ $(top_srcdir)/m4/ac_path_mysqlclient.m4 \ $(top_srcdir)/m4/ac_prog_mysql.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/check_zlib.m4 $(top_srcdir)/m4/gcc_release.m4 \ $(top_srcdir)/m4/java_release.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/mariadb_release.m4 \ $(top_srcdir)/m4/mysql_release.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ac_config.h.tmp CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORBA_INCLUDES = @CORBA_INCLUDES@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPP_ELEVEN = @CPP_ELEVEN@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DB_CFLAGS = @DB_CFLAGS@ DB_LDFLAGS = @DB_LDFLAGS@ DB_LDLIBS = @DB_LDLIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FIG2DEV = @FIG2DEV@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_ORB_IDL = @HAVE_ORB_IDL@ IDL = @IDL@ IDLCXX = @IDLCXX@ IDLCXXFLAGS = @IDLCXXFLAGS@ IDLFLAGS = @IDLFLAGS@ IDL_CLN_CPP = @IDL_CLN_CPP@ IDL_CLN_CPP_SUFFIX = @IDL_CLN_CPP_SUFFIX@ IDL_CLN_H = @IDL_CLN_H@ IDL_CLN_H1_SUFFIX = @IDL_CLN_H1_SUFFIX@ IDL_CLN_H_SUFFIX = @IDL_CLN_H_SUFFIX@ IDL_CLN_O = @IDL_CLN_O@ IDL_CLN_OBJ_SUFFIX = @IDL_CLN_OBJ_SUFFIX@ IDL_H1_SUFFIX = @IDL_H1_SUFFIX@ IDL_H_SUFFIX = @IDL_H_SUFFIX@ IDL_SRV_CPP = @IDL_SRV_CPP@ IDL_SRV_CPP_SUFFIX = @IDL_SRV_CPP_SUFFIX@ IDL_SRV_H = @IDL_SRV_H@ IDL_SRV_H1_SUFFIX = @IDL_SRV_H1_SUFFIX@ IDL_SRV_H_SUFFIX = @IDL_SRV_H_SUFFIX@ IDL_SRV_O = @IDL_SRV_O@ IDL_SRV_OBJ_SUFFIX = @IDL_SRV_OBJ_SUFFIX@ IDL_TIE_CPP_SUFFIX = @IDL_TIE_CPP_SUFFIX@ IDL_TIE_H1_SUFFIX = @IDL_TIE_H1_SUFFIX@ IDL_TIE_H_SUFFIX = @IDL_TIE_H_SUFFIX@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JAVA = @JAVA@ JNI_INCL_DIRS = @JNI_INCL_DIRS@ JPEG_LIB_CXXFLAGS = @JPEG_LIB_CXXFLAGS@ JPEG_MMX_LIB_CXXFLAGS = @JPEG_MMX_LIB_CXXFLAGS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBZMQ_CFLAGS = @LIBZMQ_CFLAGS@ LIBZMQ_LIBS = @LIBZMQ_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LYX = @LYX@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MARIADBCLIENT_CFLAGS = @MARIADBCLIENT_CFLAGS@ MARIADBCLIENT_LDFLAGS = @MARIADBCLIENT_LDFLAGS@ MARIADBCLIENT_LIBS = @MARIADBCLIENT_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL = @MYSQL@ MYSQLCLIENT_CFLAGS = @MYSQLCLIENT_CFLAGS@ MYSQLCLIENT_LDFLAGS = @MYSQLCLIENT_LDFLAGS@ MYSQLCLIENT_LIBS = @MYSQLCLIENT_LIBS@ MYSQL_ADMIN = @MYSQL_ADMIN@ MYSQL_ADMIN_PASSWD = @MYSQL_ADMIN_PASSWD@ MYSQL_HOST = @MYSQL_HOST@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ORB = @ORB@ ORB_COSNAMING_LIB = @ORB_COSNAMING_LIB@ ORB_INCLUDE_PREFIX = @ORB_INCLUDE_PREFIX@ ORB_PREFIX = @ORB_PREFIX@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TANGO_DB_NAME = @TANGO_DB_NAME@ TANGO_RC_FILE = @TANGO_RC_FILE@ VERSION = @VERSION@ VERSION_INFO = @VERSION_INFO@ ZLIB_CPPFLAGS = @ZLIB_CPPFLAGS@ ZLIB_LDFLAGS = @ZLIB_LDFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZMQ_PREFIX = @ZMQ_PREFIX@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_aux_dir = @ac_aux_dir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ omniCOS4_CFLAGS = @omniCOS4_CFLAGS@ omniCOS4_LIBS = @omniCOS4_LIBS@ omniORB4_CFLAGS = @omniORB4_CFLAGS@ omniORB4_LIBS = @omniORB4_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ img_src = \ alarm all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/src/advanced/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/src/advanced/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @TANGO_DOC_ENABLED_FALSE@pdf-local: clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: pdf-local ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am pdf-local ps ps-am uninstall \ uninstall-am @TANGO_DOC_ENABLED_TRUE@pdf-local: img.eps img.eps: Makefile (cd $(srcdir); \ for i in $(img_src) ; do \ @FIG2DEV@ -L eps $$i.fig > $$i.eps ; \ done \ ) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tango-9.2.5a/doc/src/advanced/jive_simpl.jpg0000644023471100065110000010134113034745264015702 00000000000000ÿØÿàJFIF``ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀÁ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?éô NGµº»²¶¼»»…'y.b…*ª° `:g9©œxv4gmNòÔn2 % ãÎá1Žõ{Hÿ‘{Hÿ°u·þ‰JàuKôºÒZ;†Ù%½®ØBÉTn鑃ÆAÇ5[- ݪÛè;Õ_E°‹s]!Pdœ–Œ ’@äUñ¡éGþ`ºWþCÿÄ×™x]dŽ D“4…õ+Ê‘Çïôí^Á~ iŽŒUÖ*ÊpAÚy©”ùbäú Fí#;ûKÿ .•ÿ€ÿñ4`éôÒ¿ðþ&³ôÝum·o4ŠëeÍÌ—LÁL±­°ð>}ªqŒîÉéPÜøõĈ¶ZÅæbûI¬Ò…Ö2¾\.70BØrƒ‘óqoGo‘|ÑRF·ö—ÿ@]+ÿ!ÿâhþÂÒÿè ¥à?üM7źݶ•§Û[BßN¹Ô[ËŠ{©1 ã.ÿ1ÆTtØ¨é’ ðĶڷÃ}>kZFO²¯Úoë6à¾é3•<NAò4¯¿‘ilXþÂÒÿè ¥à?üMØZgý´¯ü‡ÿ‰®nëW]'H{'ÕÛOT¸é×Éó`µU]îZS»qlì–×#Õx.å5/h·_iR=œ^l¾fòÒ²½»9Ï9Í4®›ôüÈMXƒûLÿ 6•ÿ€ÿñ4‡CÓ?è ¥ÿà?üMakz¤Z$º¾­y}u½¾µm˜šFU‡ÊŠ„%Žp9Ï5©u¯µ”ë=Þ˜éw% x KÒÊKÌ©0`bYrÃ8äÃ’“¾ŸÖ× +;z~v,bi¿ôÒÿðþ&•t]3<èÚWþCÿÄÖHÔo—]¾MZÑ¢+=„qÃm~æ0]Üo I2¥Fvàä`Ñ¥x†óOÓ¢ŸS²/§½ÝÌ"ïí;å^B3_»„ÀÃÓå ÚJïúÛüĵv6¿°´¯úéøÿKýƒ¥ÐJÿÀøš¤|Wqcn³êº:ÁÖ­sl-î„®ÛvüŽ ¨V;‡BËמnëê‚í¬.´Xûls"[ÞùˆÑí¹‘dÎvãž0sо¶þÁÒ¿è ¥ÿà?üM'ö•ÿ@]+ÿ!ÿâk#Qº¿Ñ¯¼eÍcÿ@+ÿÐñ3 n)hd_f±ÿ N•ÿ‚è?øŠ>Ícÿ@+ÿÐñ%%; »#û=ý´¯üAÿÄR}žËþZWþ  ÿâ*ZJZR&‚ÅF²´¯üAÿÄV>¡yi;4½$Ü6ÿ²V¼àùgÆëÞµv. ìÔ°¿¶ðúf“ÿ‚Ëþ"µn ’C¸izNìÿ\á†q“Þº´œ\Û Ô¯îÜ·x¦ó+K…Ó´ŒØ*ÛÿÕ•1„ËiºGþ íÿøŠŠ8BÉ“V%+·¼ú•%}ÝFÛa/ìÍ#ÿvÿüEHä¤à®ßÿˆ¨1óf¦U-Ò’©.æžÎ=ȯͥiÿ°lüE6aiü:^‘ÿ‚Ëþ"«…ed‘KšWÜ\‘ìO´nº^‘ÿ‚Ëþ"•ÒÓUØžfNš„Ýì4oüZÿñº53œ?GÿÁM·ÿª‹×¥2W ir æfÀÔnN›£ÿàªÛÿÓF§lghÿø*¶ÿãuŠ×_.*9ÝÖ•—aó3©Žòÿ˜nÿ‚«oþ7Vcš~m3GÿÁ]·ÿ\ÕµÉÝÉ«Íy€0h²ì LÛ’K||º^ÿ‚»þ"–t½ÿvßüEfÚÜy‡“ZháEAÌˉ¦9Ò´ü[ÿñãŸýtü[ÿñrn©I§Ê‡vl1ÊQ˜m r{àõ+]u-ôÑ5_ü “ÿÔ8–™kQÒ4Ó®Êèz8a„§Â!IÈ;io4Í )|¸<=¢<:Cµ„*2Îdì8>†¹Y~ÜtéD³JXZÉ»æ'Ÿ,æ¬Ü}® wí ÒÉ7‹)Œ7P²ÀÉÇj9æïö&—ö¿²fxí;ü¿'t;÷çqäg9ãûM'B•ŠMáí $IžUÓáa¹©ÁØ22=eyúwö—Û|s?iûO•º ›·ïÆ3œgÞªF÷sj2´±¤×O(BÝH[èQe»[];;UþÅÑÏî#$¶Ÿ$”$•É«ÛD?óÑ¿ð[ÿ\Y‚ù’Ù–y@6Ðôcÿ<Ö¥ŽÖÿëåÿ¾y’­$}<%&µ·ÜvVZQ®mŠ61A§Û=¼2]HŽIo´ÝK;r1ÃHÌ@ö-“Á§XÛÙZ§—ooÅdª£dòxêÇü#šý¬?ðOþ?Gü#zý¬?ðOþ?EÂÌÃO_íé{{‹¨îã‹Ë*ÑH¨©’Û°ÃäúÒaè¢Õ­Mžè F+ˆX6ÕÉù@ Æ6àc­ÏøFõúØà Ÿü~øFµúØà Ÿü~–Ÿ×ÝùMêÌ+mG³i+yIeŽi$–âIÞ3”ffbIç  ÛmG²»ûL6Ònò*Iq#Æ®ùÜË1Uc¹¹O©­ïøFuúØà Ÿü~“þ{ÿúØà Ÿü~ÐXÀ¶Ñt[D‘Ðɵ¿—<Ï2$Gª"»Šp>Up=Mm£éDè!šBížêYŸ÷m¹çbÁC íÎ:ñÉ­øE¯¿è#aÿ€2ñúQá{õ鍨àŸü~‹ ³2£Ò4Èõ;GmÓÜ\©I¼ËÙyùJ3•Ú7602qŠŽ-E†Æk5¶‘¢›fæ’æWl9@²3P§•§‘ŒÖßü#zý¬?ðOþ=Gü#zýl?ðOþ=EÐY˜’hšD–PÚ&T…ÞDxî¥Iw>w“ `í»'9'=éÓhÚ4ÓÛÊÖaL h‘ÈÉD9EdRž@`qÚ¶áÔ?è#aÿ€2ñê?áÔ?è#aÿ€2ñú.f>›öSj3OsÒ^\ùÿ»ˆÆlT ‚Í“„ñœô4³îïZ?ðŒêô°ÿÀ?øýðŒ_ÿÐFÃÿdÿãô\lÆ-šcr+oþ{ÿúØà Ÿü~øEï¿è!aÿ€2ñê..Vs’-Dk§>½=u ü“ÿS?á»?ó°ÿÀ)?øõ>ar³š¢º_øD.ÿè!cÿ€Rñê?á»ÿ …‡þIÿÇèæVsTWKÿ…ßý,?ð Oþ?Gü"ô°ÿÀ)?øýÁÊÎj–ºOøD.ÿè!aÿ€Rñê?á»ÿ …‡þIÿÇés•œå-t_ðˆÝÿÐBÃÿ¤ÿãÔÂ#wÿA ü“ÿQÌ.Vsµ éÿá»ÿ …‡þIÿÇ©„nÏüÄ,?ð Oþ=G0r³˜¤®Ÿþû¯ùÿ±ÿÀ)?øõð‡ÝÏýþIÿǨæVrô•ÔÿÂuÿ?ö?ø'ÿ£þë¯ùÿ±ÿÀ)?øõ+9V®c\pMz‡ü!×_óÿcÿ€Rñê©sðö[¡óê?ø/ÿ©–¥AYêx¤v¥åâº0a‹½?…þYÈ¿±ÿÀ)øýOÿ åñ·Øÿà¿ü~¹åDu)ÓêyÛ\Ø©#S%wgá‘ÝŸ·Øÿà¿ü~§O‡’ÇÓP±ÿÀ)øýe,<º*ñ8/ úU«x‡q]¿ü SÏýþKÿÇéÃÀ“Žš…þKÿÇê>¯PN¼N8 FÖøÜÜùˆXàŸü~ƒà›“ÿ1 ü—ÿÓú½@Uâq1ÛóR¬_5v#ÁWCþbø/ÿ x*èùXàŸü~«Ô^'/´,uÊë ûÞ+ÕƒnˆÇö…‡þIÿÇê„ÿ ÞvÜú…‡þKÿÇëJTevC«Ž+DÎÑšèW·oà­ÆP°ÿÀ)øýYÿ„>ïþаÿÀ)?øý)М¥r}¤lsL±­a__ã ïeð-Ô¿{R±ÿÀøýT†’9ÉÔl?ð_þH­iÐKâ%ÔvÐòû™]òsUÏ™Œ×¬7Ãaí ü—ÿ’*𣠻ûFÃÿfÿäŠíŒ ŽwÌÎ Ì´ö‹½>ÉÀÔ,?ð _þ?Jßenº…‡þKÿÇéûH‘É&ydÞ*œ§×­†%ºêø/ÿ$TMð¨7]BÇÿ¥ÿäŠ~Ò!ÈÏ™K6jH—j×±„¨åþÇÿ¦ÿäŠAð‘üÄ,ð oþH£ÚD^ÎG„,õvr+ÕGÂuþ?ìð _þH©GÂì5 ü—ÿ’)ûX‡³‘äÓ AYw Í{LŸ |κþMÿÉ]¾Fýu ü›ÿ’){X‡³‘â…ýés^Ò~ ÃÿA ü›ÿ’)?áLÃÿA ü›ÿ’){H‡³‘ã±Ë´Õ‘6{×­š‹þ‚6?ø7ÿ$S‡ÁØÇMFÃÿfÿäŠ=¤CÙÈóYŠ‘[0HÒ]Òü$ ÓQ°ÿÀ¿ù"­ÅðÑâ鍨à ¿ü‘OÚD=œŽ2À©N3]¸ðàq¨Øà ¿ü~š~Üÿ!+ü—ÿÓö±Ir° š¯%À Œ×t|pF?´l?ð_þ?P†ÓÏö–Ÿÿ€2ÿòEK©ò3€¹”ã"¦°bÇšîá¬Î0u-?ÿ%ÿäŠ|_n!ûº–Ÿÿ€ÿòEÒ!ÈÎVW•Uf`Ç0 †V PGp}+¸o‡÷M×SÓÿð_þH¤_‡·þb:wþKÿÉsÄ9Ç$ª*Å*¨ —·*öL d_îÜà}Ïÿ®´x äÌGNÿÀ ù"ÿ%ßý´ïü—ÿ’)s@|²91HŒ’G3# 2µõÉzæÓÚuÎH¸$ÿÓýÏÿ®¯þK¿ú ißø/ÿ$Qÿßý´ïü—ÿ’(æ€rÈåʆü¹ÿ㔢EÏÝŸÿ®øåucÀ·cþbZwþKÿÉ¿ðƒ^ÐKNÿÀ ù"Žh,ŽJ;[UEU†eUUEýȽ©|‹qÿ,î?ð>çÿŽ×T<z?æ%§à¿ü~—þ»ßú ißø/ÿ©ýßbùª÷9_&î\à}Ïÿ£È·=c¸ÿÀûŸþ9]_ü!—¿ôÓ¿ð_þ?Gü!wßôÓ¿ð_þ?Gî»5^ÿ‰Ë­¥©ëÇþ .øíZ@‘¢Çkk¨½y?‰<’y'“[ÃÁ·ãþbzwþKÿÇëæ¶»ºµ•¢y-§òKÄ…ÿw€í,ĬÇSÓ5Q忺‰“›^ó:‡ò&Ãÿ_wŸúU-¿äN‹þ¿/ôªZ**|oÔT?…Drðø bÿ°ÿé0®»ÅÆámRòÒO.â gxßí`88<åa_ø·Ñú¯þ“WQ©ÚE«iwZ|îëÌm” 0cŒƒYÊíhk¦ ×î-¬´—úËÞ\Ù®`H Ÿ)›L*Yr;cýìqYÖ¿ž‰b×¾EÅÒØÇutó\, ûH“n° ÇÊ:sÍt—º=­òéë,“bûâÚÓ°§ ò+ ÆšµÞ—á™®¬§x&Ä¢D@ìH àA8'±­!&ž=Nj޳§C­é¯c<²ÄŒÈûâ 0*Á†2êjO}¼ÊðIaoi¼—ÚÕõц¨ÅöB¸]ÄœD§h®Ó’,ok £Á<„Ëzm/ç+)D1I€*d=õÈ߸Ðþ×?iÕ¯¥¸·˜Mɬ‘@ÄaH œä«ƒ´È-â€Mvé½Å¸ß $¬Ç/“޾‡ùÒ×Ýþc]>_Ÿù…}uw Ø\Þ„ÀŽû ’3žƒ¯\cŽ•nç|öïw2Û»%ˆ)eún~`Önn4í: 1q,ë W—n⣠;@:v«^o½T¬Û±1ºZœ¦•âû- ëU¿Ô.µEì–P[2óy»•@Aõ$ã¯*ûxÒU¸:iÓ“û`]­·ÙþÐ|£”ß¿ÌÙ»r~îsÆ;ÒÿÂ7`tyôÂ󘥸k‘&ð9 ï ¤0zp}óQŸ Ù²™ ÕßÛþÐ.~ݹ<íàmþîÌmùq·íži-•ü¿Oø#ôóýà?á6º›V·1Á(Ž+kϵXƳM Q…ldõ8éœò+_Ã+ÿ„Š9[ʵPˆŽ µêÎ0Ã8a…da‚+ô&©Áá]:ÞXeI®Ä‘Ç2m¬æR ¹` ‘Ôc•kLÑ¢Óo&¼kË«»©£Hšk‚»¶.p>UPzžH'Þ…¶¿Öÿðù[Á:/6¸ë-jòãÅZÕ¼Ú•úÇg6Ø-âµS _(1 '”prOV«¤ó}ë>×L·´¸ÔfŽIKj % FÚåãÐwÍ'}mØjÇ'Ž5±¦Ïwk aýi2­ÉBQ¤‘‘›*€1éÆïŽÇzçâz±²žeϵÇú`óŽJFT@HËpzñÅ1|¥­Œ–‚{½k®íë±¶å#åë“ôö«‘ø~(¯Zæ=KPO5Ò[ˆÒEEžEÜÛTœ … tªÒÿ?×ü‰Öß×oó.è¾ »Ö//×ì1Ciiu-¯šnK;²3³f9þ÷áÞ¶üÚÄÓ4ø4¥ºXF7/rûÈ8g9 `*÷›ïK¢V]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Úà56η«ú}úMv^o½q×Q4º¶ªÃþGþ“ÁWOâ"{Ãßùâÿ¯Ëßý*–Š>ÿÈŸý~^ÿéT´QSã~¤Ðþ}ƒŶ‰¿ê¿úM[–qjwvV÷?m¶O65“oÙ3ŒŒã;«6ÿ‹WÔôž´tßô»+;7âì ‘×þzn?ìü§#¾qÓ Ê4!ûEÑåoƒ¯fM*VSî8#ÜQö‹¿ùüoüÍ[÷Úé÷7۵ıDΩÁ£ëXZ_ˆ%’IžëPÓ.ía·3O%¢˜ÞÔŽ«"3³r3ØT‚(º 2_´]ÿÏãàžj>Ñwÿ?ÿ‚y©çÅ0%œ³Ma} ¨Ñnêžc‰[j0Âr:ä`ä —þ;5µIçŽh ’HäŽ@»¡1©f-‚F^ ž£Ö†ì+ý¢ïþÿóQö‹¿ùüoüÍO>),åšk èeFˆ wTóJÛQ†Œ‘×# VÔ.ÒBŽñÿÍ&?Ýë‘ßéd×/¥ÓtûèU[xT R@$gâ†ì 7¡ö‹¿ùüoüÍGÚ.ÿçñ¿ðO5KÞ©cyg£5ÄnbW··xŒo´°È.ù)ãsÃ"ñ]œƒ{[]Ç ðÊê»fxC"á‰Ú )9àƒŠ¥Æý¢ïþÿóQö‹¿ùüoüÍRËâ;XµY­ävŽhe’i<¯îÄdÁ³À|ciÉÏ#©ñH7K¥j1Nò$pۺǾbÀ‘´‡ÙÐ19`F9Ç/Ô,Cö‹¿ùüoüÍNŽ[¹&Ž!~ªòÌÒä@N ÆXÐʵl/£Ôl’æ%t J²H0ÈÀÊ}Á~¦®óiëž[’7íɺ“8÷ÇOäzS”Ïy ¦3²ýï+My÷Á*N0qî=iŸh»ÿŸÆÿÁ<Õ» )B8× =òOrIîIäžõ„·úåôSÞéÉeöhåtŠÚdo2pŒTŸ3p ’2­Ø“θX>Ñwÿ?ÿ‚y¨ûEßüþ7þ æ©a×. ê*Ö3NÖ÷ko6Ê bG;‰`£$Àqø–# …ìóÍæÿ£F#'”Û_;œ)Ã8'9ã"‹…ˆ¾Ñwÿ?ÿ‚y¨ûEßüþ7þ æ«wìp]$ØÞÜ1‰&“ÊŒfb@,¬C‚F:t­Z.%¿ÛnÒ=B èe“Nt89Áù˜zÊ¢ûEÑåoƒ¯fM*VSî8#ÜU×·ûN·pŽß¹û4;ãÇßù¤À'û½r;ý2‹ºÇ;ª ’OaCiW0~Ñwÿ?ÿ‚y¨ûEßüþ7þ æ¨#ñ-Óé¦v†4œÝÛ¨FSþ¦gP¬F~öÖ#Órž;Uص×{1,V7w®ÓMÛx•6ˆÜ©$»íñdõr{ˆ~Ñwÿ?ÿ‚y¨ûEßüþ7þ 橉mÜÛý–Îòíe‚;†hO•’™K= ñÓ¦v©…ŒK¶Ý;¤z„AÐË&œèpsƒó0ô?•F&¼#)x]OGH••‡¨ àqÅX¹ŒÉ«\†`aû2 ;q€xÀç':wí£7ˆc·Uil/yÓŒ!6ñä€ïót8' “€xªä‰<ì½æßÏÌ¿ø%š6ûþ~eÿÁ,ÕEüElš„¶¿fºd†Xâ–áULhÎNs’à8ð9©]·’ù­„ˆ÷¼IpBùo" ²s‘†êùO4r@9Ùk;ÿŸ™ðK5m÷üüËÿ‚Y«þ¢×2%…ÇØn,äºg`”+(ý0rx=Wß¶÷IrfجRËaˆ8öçPhTâÁÍ …¯fœ@/•$*\ tÉ#ÈÄg¨üêÏØµ?ú[àÿgQ[ÿÈvúö›ÿB޶+:‰EÙur„WÂMÓ^Âñ’©m´ŸÄ±ÇåM¾-§™m:—3$AŠ«(&@‡¦3Œžý«M~ëý?¨¬½A·Á»vÿô˜r·ÉÄãåqät'ŒþŠìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«qKq7Î"„G½—&S» ÅIÆÜvõ®#C¿º‡I×uWP–âÕï)î.ÙíÛc6ÔùœcÝ84¯þc±Ö}‹Sÿ …·þÿöt}‹Sÿ …·þÿöuÌÏâjôØì­w}hoCa<Ê‹µqÄbĒ߀jeϵfq®•,w1YÇs5£ÙÍ,ŽìNcîñ´üÌr8â›Óúþ» ký]ΧìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³ª:ö³}ftXì“Q¹·Ú‘– ÎŒtϵdÛx§Y¾½Ó´èE„7Ü]ÛÜLñ;¦aÆ8àç¡'ëÅl×õ÷'ص?ú[àÿgGص?ú[àÿg\ô^-Ô ·½x­M…Õì–QF¨ÂUeܱÜA¡ÊÀ#“TañÞ©k¥Yj:½œÑÞØMuvÁ£GŽ ,Ù>ƒ9¥}/ýmÈvÖß×c¯û§ÿA oüÿìèû§ÿA oüÿìë–›ÆÕ¶¨Ü=š<°$Ä–3ÛÂåÜ+!W9%sÔr8â£×u=vÃUÔ£žþÞXí´W¹ò¢†HU›yI¸9éœc9¡»~?‚¸%ëúîu¿bÔÿè!mÿ€ýbÔÿè!mÿ€ýs)ãJMA¢µ±y ·šybŽÒi]Ã(,âQ•]»‡ÊÙ$ÈÍ\µñ©ÿ 0°Ô!‚Ò.d†å¶•ZE ¹]&ÉÊü¤7Öß×õ¨º\Úû§ÿA oüÿìèû§ÿA oüÿìë–ñ.¥ya¯ê÷0Oq›-OBV¬…ÙKÎÖÀõ¥i^ØO¤ør÷S±ÕoMÊX;“q3O0]Û±ùO\mÀçqŠ\Ú_úëþCåÖß×Oó5þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ç4ýc[–{7í6…FìÓ´.drN0>~1óóÎ9ÀÏ/¬\ø;ú†ýJîÑm˜ß-Ó%É%~YÈ/·Ÿ—<äpi½/ýwÿ!-mývÿ3³û§ÿA oüÿìèû§ÿA oüÿìë›ÜA=­•”‘]­äv§Ožu!¥Vm²³ôÉžëÒ§‹Äz¿ü$-§ÝÇod²O,é=¬Ùpr:Ê GÏuùOlæ†ÿ¯@7~Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ât¿ë)¢éP´©q{y ÷&se,ü+à&ÈÎrIûÜ01V®üe®º’;kO²éI$p¹1$4yqӃÞíýzÿ“¿¯ëÔë>Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ä5­kR¹Ñuë{™D7vq^ÛÍbòBWxo•°ß61ô>‚»ˆZèÁDE9yXÇ”ÿ:5š_Öåo±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þγaµ"ûTW`î.×sÀ'ìðgŽÕº%¸YáIc„,ŒW)+1)n…G÷j…  ©ë>׈?òZ ¨=E% ¿¿äO‹þ¾ï?ô¦Z(ø}ÿ"|_õ÷yÿ¥RÑEOú‘CøQôG3 Ŀ庰ÌmŸØj6çøö®‹Bÿ–_öµÿÚ•ÌCÿ"$_ö_ý&&›©ÙÚi–ít—O3Gƒ"Ý: ¡Ü*ÿ¬QÆB7NåIÙ£·ºƒíV’ÁæË˜…|È›k¦{ƒØŠÇ}æýØë°Ü³Il¿f¶0²±.Ù< cØñŒ¯øH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê|‘ïý}áÎûí<¶Ö­™c™­äÝg§¬ˆœ? I8ëœÀs›“øj OPºšw0Þ[40° î©UAí·Þ²?á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨp‹ëý}à¤×BݧƒÖÚÕ¢ó,cs5¼›¬ôõ€‡äI'sØsÔWÿ —ýË¿ü?ÿ£þ /û—ø0þ=O•wgØé¢ÿÝ×ý{Cÿ¡KK«Xjh÷–o•ö˜Z-ûwmÈÆq‘šå†»¤‡."ºÞ@¾Þù gýw¹üéßðiÜ»ÿÁƒÿñêN}¯¼ÚèmÃ¥_Kym>©}op¶¤´1ÛÛFò îl»ç1ާ¯ÏÓ|k`·d`’·O&Å#”£w’L’íŒ ¹êA=*ÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉÿ×Þ Mt4"ð’}š(nod›ý{yä µ¥i™YŸ9àåOõö¥½ðíæ©d±jWö—RE"I ½€0‚ ƒ¾2ä±!ñ0çÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉÿ×ÞϱÓi:réZlV‹äü™'ÉaL““„^çÜú’y¢ûþ>ôßúù?ú*Jæá Òÿ¹wÿƒÿãÔÖ×t–*Z+¢TåI¿~1‘ûïB:|±ïý}âæ}ŽÖ°ŸDÔ#ö:°¶²¸‘¤eò7Mc—ɸÉ$Œ«Iö'þ /û—ø0þ=Gü$_÷.ÿð`ÿüz—${ÿ_xùŸcJïÃ/:],w‰‰îÖàÇq –7%d‹¸.uÅUÿ„>EÑáÓ–ãN’’Wò®4Ñ$@»x*W$˜ðzUøH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê9#ßúûÃö/ê>{䵄ÞBðÁD¯sj%ž2:¼räsÉ ÈÒqŸðiÜ»ÿÁƒÿñê?á Òÿ¹wÿƒÿãÔùWëïgØé¢ÿÝ×ý{Cÿ¡KRjŸo°šÐɱfœ©?0üFF{f¹1®é!ˈ®·o·¾HÀÿ]î:wü$_÷.ÿð`ÿüz“„{ÿ_x)>ÆÇ„,…Äo¦¥¾Ÿèšh ·Jc‘]O`ðÃ<ýïjŽãÂo5¬P »ycY§‘¡»µ2Âþl…òSxù—8 Iêxæ©ÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉZÿ×Þϱf_É-……“ÞÚɤ ¼–!¥oñÄûˆ“» uC\gü$_÷.ÿð`ÿüzøH4¿î]ÿàÁÿøõ>UßúûÙö: ¿ä'wÿ\mÿô)ª–©eý¥¥]Øùž_Ú"h÷íÎÜŒgë-Ù*Û›g’RÛY Ë…ˆP{ã¯zéwî/ëþ5 Õõ½”K-ÆÔF‘# ~f`ª8õ$QäJøSE[9íM«¼S„n$v!(73À>¡áí3T¸k‹Ëvy¶r³:Œç*ÁHrO="µwî/ëþ4nÜ_×ühz‚Ócü3¤Ix·Mh|Å(ظFdVdÎÖ#± ž¥,^Ò`Ôìv¥f4ʾk˜ÖB0\G<žMkîÜ_×ühÜ?¸¿¯øÐšÉâi5_´BÖóZ Yídƒvõ »ïr ž)Ðx[G·ÕÜ<ßO$»b<]ÌveÅmnÜ_×ühÜ?¸¿¯øÑäfU§‡ôÛH pëmöPÏ3¹ò·Û–'¹ü:t žÑžÖÖßìÒF–‘˜a1\Iª«¹X1Г[{‡÷õÿ¯ÌÚ•ÌD-!‰•} 2ñÑùQ¸Ã0sK½V†;m.ŽÖÝ!ÁRÀ –,r ½MX‹ÃzL:€½ŽÔ‰D*¯šæ5r0\G<žO­kîÜ_×ühÜ?¸¿¯øÐð†Š¶ÑÛ­´ÉLæ=—R«&JÁ²ÿt{TÍá–eû …šÔYº«²ƒÎxêyÖÆáýÅýÆÃû‹úÿsº×…¡Ôl/ ²’;I¯!Ky¦tisç.ðëüëv$ò¡Hóª>¸©wî/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´UeÕ¬žÒ¥`aÄq­’Äà uþU-Ýí½œ×w;RP¼†8P2N4%àê@!ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´Uk ž{wyHžUvYùVh ¿ãêÏþº·þ‹zⵋ۫MkUó7êEáGѬ?ò"Åÿ`5ÿÒaSxWþC:7û¯ü®*Hÿ„.æ¿úL*o ÿÈgFÿuÿ•Åø%ò*_=6Нt‹#Û«¨e2†u©Ëil¬mâ‚qRQÁx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8slI-áYLmÃäÛ¹FåcÀ`=³VGˆ´Áxö’\ì•7fÄYQ–Q) 9ä`äpk!4 Vêâ ¯ÚÎ1Ùâhà‘˜ß4¿be#8™NvoÁá¾÷?N)n+HÖIîîÕYÖ0~Ó)ù˜…ƒêE2Þx.ˆòn¯œãwŸ62µ†s€sùö«ú´¯º–…DÒ#‡JY®tÆ’)5I¤¿Œ[’h¼É|¼¨A(ØÁãœUI­­’çETÓ®g²Ù|ÐÚý¥)tòÃF8 F>^3Œq½äÓÅßþIÿÅSÊ6™&i.L¨ «›™7(8ÈwÀü…T—êÖ6·0µ=+StÓ–é$g]=#‹ÝÉ áŽJ²ºˆßý_ÎÇi烛šžŽ'‹YšçNk‚u[YmÌ…âAâ«‚Xdg«ZžëP²²iV{ÛàÑ,«4î~v*¸œä‚0)ö—0ßKª.ÜgÎ71~[ñŸÂ…†•÷_Ó¸®^ÐmdMRûÌUò¬Ù­íñÙ\ù§ôh×þYzvÖ·šuòiî—o©Ýùóyd9ˆùÛCÈNÌvÎz·„±ùví<1î-¶;‰dœ“€ÝIæ¥ò?éâïÿ¤ÿâ¨ú¬­¸sns¶ö· =ÛA¥=°ŸL¹IbŽÆd4í*²JßëÛïa€îzæ®êµXu?³é\(™ªFòiþ(¿»D;Y­õ)ô$ƒVÿáOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ³*ÞÆå|BÖÍ ý†ÚY/bm¸Rò ¦AiN;ek•{;©#¿û6“%¹ŸK¹IbŠÂe4í*²JßëÛïa€îzæ»ÿøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ„’Ýîs‘ÜGu}gö;·’}VÒå-Ý“Ë_$1.Ñ‘œñœb“NÓïÆ/<ªË8º™ÞUÓÜ„ƒ±Zà¾Ö\l€H*8àšê?áOú k?øÿÖ£þDÿ Ö³ÿ_ýjjËúôÿ"uµ‹ôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ•îËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ²ýCþDÿ Ö³ÿ_ýj?áOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZ«ßxq-4û›‘­k?º‰¤ÿÝ=03ùŠ,‚ìµ¥ÿǤŸõó?þz»Xz<È—è/®£Ž ù¡SaàòYI',y&´~Å/ýï(øÝ j èI7ü}Yÿ×VÿÑo\ˆßÞ¦?éíôšÞ»kw2 &gw"âd,ädí®xvô®Äc:î§ÿ_kÿ¤ÖõPø‰žÇ_ðóþDè¿ëò÷ÿJ¥¢‡Ÿò'Eÿ_—¿úU-Tøß©4?…Dy²êdxV(³ÿ0%ÿÒ@k¥ð¯ü†to÷_ù\W“ý‡ÿ¨ÿé®û¿òÑ¿ÝåqZ5h?'y#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬M Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèzgƒõKÍWÃ1]jRB÷I=ÄIf5*gŒ6ÒN23Ôš’ÃĶ—ZmÅôÊÐE @ÁvulØ(%ƒ.rqÍaø9«ðîHì®#+uy~d|w.YHÎ~RHü*ÝÇ„ÚÐÌšRG-¼ð$rÃy;ó‚›–dÀ/‚>é @5âšeñ]ŸLŽî&[릶'ìò«BÊ¥Žå)•<Ý©ÓÄúC¥Ó‹¦Tµ¥‘ÞU(§ ÈJáÔ¥r9¢³`ÐuTNyeÞÚý§òd»’_.&£*%eÜän,7×n@ÕI<)ª\i-§Êöh¶ºtÖn²12‡ I•ù0rì’}×à5¿õßü޶Îî+ëT¹ƒÌòŸ;|Èš2yþëNzÔôˆ6¢ƒØb–†JÛP¢Š(QEQEQEQEQEQEQEQEQEQEQEËY]Ëg äÁç1¾váΘüüˆÇôǽFg»¹—Zùi‚KysñŸâ…GæE7:9kÛ}Jk¶övòîY8>c`á¾µ ·Z.ZÝ´”a5ˆÛ‚9®Ëjô9ÛПIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþòÜÖ;(¶k¿ C ÄÒÔrªçåûAÉúc5ÈMa¨Ý­ÃÉk7œú}͸ܽJùj£8þ"¬ÃÔôY¿ä¿õÞ_ýõJº°ð¼/ëþE7©ÈÜ ¯ï¦¸‚ÒìFZÄ%»¡;fbÜ0€yªÖšeÔ|Vr[J!¿EeˆÆ7´ˆS Œr¸Áööã·¢¶ökóüIN߇àr3C§‹ –:ÉHžh–Î_,­ó ˜à0I'oÍ£>‹iÕ¤„Æ÷#“L’hp_åÄ`îCŒm=†EwTPéÞàŽ#Q°”\Épl.!¸’ &2A ™Ól¿¼¶¶æo\“´VŒ’HÖosÚ­õÅœ‹:%Í‘‰ˆ ©û´ÜJ–ãžÕÓQO“p8]CJ¼oæ¡.öû‘–É®;†rÎT†Qd®¸ùzñW§ÒØÞ^^ýšìjvæ)¼³¸Gˆƒ=—ïguÏJë(¡SIÿ]î˜Þ´K->x×ìì·s_+`9rTŽ9vàŽ8ÇjÙ¢Š¤¬¬ESVMÍö™§k3]êã6ÑY£…Î7H&Rƒ¨x§¼Vµ3Jš+oÍ<ò¤QG¦–y‚ª É$ô†#ølkr°ÖôK+VÖîïtË«ë›ÐÑEoxžL3y[i3Ž$»ü‚£e´·þλ>$µ·³•nÚKëfˆÃçÈèŸdr ä×f5­(éÇQ‘±äN¾P9Æ7gx¢}kJ¶±Šö}NÊ+I±åÏ$ê±¾ybpzv¯9–Œ9µ}2ÏÁÖ“ë‘CA ¼²Y!Qò<±· (ܼnÀ9àÌŽîÈÉk®M¨éÒBú˜–õ­fY!µ>CGguÛ–8䎃ØÜêÚm“@·Z…¤ qÄ"Y•L½>îO=GOZ¹O«aÒÇ#§\é–þ¼¤¨–5Üë1­L¬rä© ½;0õ¥ÐåÓ¼M=õ༵&{tƒì¶W`É ±S#FÙ I<ÐÉ=m€æ<(ÖZ‡>Î^+hEåäq&àœ,Ò/ÑA7êMáGÑ:üIcÿ°ÿé®û¿òÑ¿Ýåq\0Qý‹ý€—ÿHÅw>ÿÎþëÿ+ŠÖ_Ü(üG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qXœ‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬77vkY<¥1,¾D²F2Ûwõäš–óÄºŽ— Ãj:U²²YËw¶¼2ã*Å£R¹Ü0@=ÿ¯ Ûn|.½¶²šûlÚ’Ã.ìÆÛ®¦ÁÈÏõ§Kàë‹‹{µƒIÑt‡’Ækaö'$LÎȉ03ѺöÇ>)ª¶Ÿ×oø&ïŠ/ô˜æ:–™j®,溅m¯ZMÞX«nvçpÁÕâp×z¸´;µ@ÅÏ™ÿä!l9åXvè~”^øZÁ|?©Xé:}…•Åå«B^(V0I ÅFq“U`ðÅÜZÜ7¦h PÞ™QFAäã§_2g?Lw§ý_×B~Ïž¿‘ÕQE†QEQEQEQEQEQEQEQEQEQEQEQEsšlQºÞXý¶~HÏü´j½öx?çŒ÷ȪšWܼÿ¯Ùÿôa«õRn䤬bi?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ ÚOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¥¸£°“È5뼿ú1ê•]›þA«ÿ]åÿÑT«³ ü1½ÂŠ(®‚BŠ( Š( Š( Š( Š( ²no´Í;YšïW¶ŠÍ.qºA2”@ûÀu8õ⵩tOùŸþÁçÿF Ãü1­ÊC[Ñ,­[[»½Ó.¯®oCE½ây0Íål¤Î8L’ì;ð: ?¶4MÚÍãÔt«NðÜ4w&áRÖ=îSœãh8fÇnHîRx¤’HÒTi" HªÀ”$ddvãš’¼âÏ=º½ðí…œZ ¶©§ n¬ïîncÿ0A;XÍ…^Rx÷Ð*%¼knŒ ÙÎF89ïMvÍrm…ÄFq’b7 `ž:ñ¹ï¡ëSQp *9'Š'$•åm±«0Î Àõ8þ˜o-V?0ÜÂIån.1¿vݹõÏõâ€'¢£’x¢xÒIQVÛ³\àœS€OàiRh¤y$FxÈ¡*HÈÓ‚ >ŠŒONð,¨fE ц”à‘ØÈÑ$ñDñ¤’¢<­¶5f¹Á8§ŸÀДQA IÀ袙 Ñ\B“C"IŠ2°=#¨§ÐEPEPEPEPEPEPEPEPEPEPT5Ïùj_õë/þ€jýP×?ä©׬¿ú¦·sz<uu®Ã¾S¶¡&-ÇÌð²ŸÈжlçµ™ZMAØ+@7þw~`ÖmŽ5ÅÞ«<Àÿh̤ É èAþs×Ú­¶‹tÿx“õÕgÿâ+£w1å}‹_üyéÿõõsüæ®ůj#þžÇþ“[×{¦§—i§Ç´.Ë‹… 9nA˜u<Ÿ¯ò®ÅŠˆµúûúMoQj6‡- Žçáçü‰Ñ×åïþ•KE/Ãßù¢ÿ¯Ëßý*–ŠŠŸõ ¢<ˆÈ/û¯þ‘Šî<+ÿ!ý×þWÃÿx‡ý@×ÿHÅw>ÿÎþëÿ+ŠÚÜL>#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®sc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oî[U}Í##HÙ9,2áT"†<¶ 8ÍM=–¿v¶·3E¦¥Í”ë,$ò“äd}ϰÈ~C‚:œð_ˆæñF‘Vò5įö„g‰"¶’G!H ò*–Iä‘Îz¡7ŒaÚØÛÀ²[ùvò© ª§Î}¨°={°çŽÌC´ï]ÚßÁw,ònüåBp$šD|/¨Á8'ƒŽx¡oáømm¢i­‹Ea›·»ÿB®)®—þ·³·õ±¹qâ*ÚííZišuf@ÚVVp¥Š+*Ì<OµW³ñ†™>•§^\™mšö—Ë0ÈÞP$ ±Ûò®N¶õŽ‘_¾»• ³5œ„×MrÐL„ dpÒ`v$cÉ·‚õ³²ŠE¶‘—OM>u…ÄH Ãb0¾`!ŽQ±ŽºšQóþ¿¦ë¿ùjurëºt:’éï4‚rÁ2!sr2ÈÀÄc NNGŠÎÓüY£ ¼‘ÙΦ[©àedpʱnË€TÎÕ‚ØÎE2}Ro-Õ¿‘o›´ñ]̬è ¯ r1nòr8ùE;DЯl59&»kv†&¸û?–ä±ó¦ó `T `pOZõý~ÿËõ.èzßößÛØçµ×HYÆ×a±\1^«Ý>¸< jÍÓ4ùl¯ui¤d+yt&Œ)9 å"sÇ\¡ý+JŽÀQEQEQEQEQEQEQEQEQEsúWܼÿ¯Ùÿôa«õCJû—Ÿõû?þŒ5~œ·v14ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏárܘì$ßò _úï/þŒz¥VÞkw´òZêÞ9iIW?xÿãUñüÿYÿßá]4*F0³cheüAÿ?Ö÷øQˆ?çúÏþÿ ßÛSî+1”SñüÿYÿßáF ÿŸë?ûü(öÔû…˜Ê)øƒþ¬ÿïð£ÏõŸýþ{j}ÂÌeüAÿ?Ö÷øQˆ?çúÏþÿ =µ>áf2Š~ ÿŸë?ûü(Äóýgÿ…ÚŸp³E?ÏõŸýþbùþ³ÿ¿ÂmO¸YŒ¬›©g‡Tºx^HÇØPK$d†Ž#: È! öÆkgÏõŸýþiÂÞÓ_kù/­ FÔÃ…˜nݸʱ¯R…“Nç?%ÜP&¨úN¢fÓ›Rgº›P‘GäôûHÜÁw…¹ëŒW¢¾ÔâÓ¬cûcÍý¬gÑM$‚2$;\;*’|¢Ç~ï,œŠì¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñƸQG æQª[êÖìâúæÇP’ÉD„ \2ùCnpìPgIgîŒ;N¿™´M—Z€Z…·ýòêSÜ„r~pÓ” Ãh8'ËÉn3]¿öÖÿ?pÿßÅÿ?¶´ïùû‡þþ/øÐ´Vþ·zÜâxgƒE½’K—‚ËR„©¨IqU‚GÊKò™#`Hù—§wPÑáO h—wQ³^Çwk!˶ԒK„g!s·vY†qœ:WUýµ§ÏÜ?÷ñÆí­;þ~áÿ¿‹þ4_[ú~æ/ø&F·§Û/м?¨lcr×oöv`«äJp œ.p3€3œâ°5 ¤[¯¥Ôc¶[é®n<¹u ,D£!ca2–«„=wg-vßÛZwüýÃÿühþÚÓ¿çîûø¿ãHwÖÿ×_ó8»‹«{mWQ¾¹›Q‚[*ɶµÉŠLerÃî ]ÌÙ¹ˆÁ<Ô°¹Ž÷PÓ^âót6ºß— EªKq m•c´¾_ nõ+Ðà÷ÿÛZwüýÃÿühþÚÓ¿çîûø¿ãU×úî.–þ¶±ÇøGTº7òK¨[¶Ï&¡êLa8å‘%¾>q´6鹫÷7vÇÄ7‰¨j·V׉4kcmì¢XŠ/"!‘ ,\38ò»r:í­;þ~áÿ¿‹þ4mißó÷ýü_ñ©jêþ­œN„í¤izS%Ö¢ÑO Iq*$¦V ‚-¦$lª€ñœÕX5If¶–š“ˆK m«=áç(ÿ¼a•%v‚ ?ôí­;þ~áÿ¿‹þ4mißó÷ýü_ñª¾·þ·¸º¤“›D¼²¹Ô.¡Ò ÕÖ®îMñD`WÌ[pB£;º63ŠÍ¹Ôf].È MŽ˜×W‹ö«­R[]Å_9U˜ü»ˆ†Ú:÷í/o4B&kæUÝ»0^4-ÿ}#lÒÙ^èú}ª[[O D™ ƒIÉ$’I$’I<’itþ¼‡ý~æZÒæMÉï^å C+ª• Ø8 ŸBÒ®Õí­;þ~áÿ¿‹þ4mißó÷ýü_ñ¦ÝÝÉJÈ¿EPþÚÓ¿çîûø¿ãGöÖÿ?pÿßÅÿC/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/Õ sþ@—ýzËÿ ?¶´ïùû‡þþ/øÕ]GR±¼Òîí£¼·4/–•p Ry¡3ôq#C­]S©\gRÊåÁ ‘í‘õÏèš§/ð•86:×xÍöøŽÿþ¾‡þ“[Ö”¾2*|' ü=ÿ‘:/úü½ÿÒ©h£áçü‰Ñ×åïþ•KEMOúЇð£è Qÿ˜¿ì¿úF+ºð¯ü†to÷_ù\W1ý‘ýÿHÅvÞÿÎþëÿ+ŠÞÜL>#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®cc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oîR={u<ÚÕÏÚnã´°[„³Ûç;œ€ß";¸ÒÞÎR­$6¡¡È$c¥uÕ…_ˆÚŸÂQEfhQEQEQEQEQEQEQEQEQEsúWܼÿ¯Ùÿôa«õCJû—Ÿõû?þŒ5~œ·v14ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏárܘìjop0¿:<Çþû~u›sgö³iðÇ2 y˜,Šgt|óõ«?ði¿ô´ÿ¿+þ6E]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYwÙgÌï·çG˜ÿßoΫÂ=¦ÿÐ:Óþü¯øQÿö›ÿ@ëOûò¿áE—p»,ùýöüèóûíùÕoøG´ßúZß•ÿ ?áÓèiÿ~Wü(²îeŸ1ÿ¾ßcÿ}¿:­ÿö›ÿ@ëOûò¿áGü#Úoý­?ïÊÿ…]Âì³æ?÷Ûó£Ìï·çYÚu¼v—ŒƑƷ# ŠŠ3ÐTZvbúe£½•»3B„“’NÑíRÊF·˜ÿßoÎ1ÿ¾ßRþËÓÿçÆÛþü¯øQý—§ÿÏ·ýù_ð  ¾cÿ}¿:<Çþû~uKû/OÿŸoûò¿áGö^Ÿÿ>6ß÷å€.ùýöüèóûíùÕ/ì½?þ|m¿ïÊÿ…ÙzüøÛß•ÿ »æ?÷Ûó£Ìï·çT¿²ôÿùñ¶ÿ¿+þI£Y¼9a¨dsj¬¬2.œ^cÿ}¿:<Çþû~u[þí7þÖŸ÷åÂøG´ßúZß•ÿ «.äÝ–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYw ²Ï˜ÿßoÎ1ÿ¾ßVÿ„{Mÿ u§ýù_ð£þí7þÖŸ÷å‹.ávYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þÂ=¦ÿÐ:Óþü¯øQeÜ.Ë>cÿ}¿:<Çþû~u[þí7þÖŸ÷åÂøG´ßúZß•ÿ ,»…ÙgÌï·çG˜ÿßoΫÂ=¦ÿÐ:Óþü¯øQÿö›ÿ@ëOûò¿áE—p»,ùýöüèóûíùÕoøG´ßúZß•ÿ ­mg޳wÇ xX¬jgtœñô¢Èwf—˜ÿßoÎ1ÿ¾ßeéÚ5•ݼ“Íeo$s>YâRN%aÔŠ·ÿö›ÿ@ëOûò¿áE—q]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYw ²Ï˜ÿßoÎ1ÿ¾ßVÿ„{Mÿ u§ýù_ð£þí7þÖŸ÷å‹.ávYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þSQѬ­-ãž+xä[˜0É‚3*Ž QeÜ.ÍO1ÿ¾ßcÿ}¿:͹³‚ûY´Šxc™¼ÌE 3º>yúÕŸøG´ßúZß•ÿ ,‡vYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þÂ=¦ÿÐ:Óþü¯øQeÜWeŸ1ÿ¾ßcÿ}¿:­ÿö›ÿ@ëOûò¿áGü#Úoý­?ïÊÿ…]Âì³æ?÷Ûó£Ìï·çU¿áÓèiÿ~Wü(ÿ„{Mÿ u§ýù_ð¢Ë¸]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…A¤Æ°Ù4H¡Q.'UU _ŠM!¦hyýöüèóûíùÓh¤1ÅÜŒoμƒÇ'"¿ÿ¯¡ÿ¤Öõëµä;Ïü$Wßõô?ôšÞ´¥ñSá=áçü‰Ñ×åïþ•KE?äN‹þ¿/ôªZ)Tøß©4?…DyüÂâçþ`‹ÿ¤b»Ÿ ÿÈgFÿuÿ•Åyÿ›þƒÿÔôŒW xWþC:7û¯ü®+zŸÜD>/¼ôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+˜Üà¼_u¨Ø\ÝM¦xzÛRw¹q$òÙ5ÑŒ­ª4qùi†ùßåݫߨ¬ÛûK¨½œ¶±÷NŠ9â²w0 cg™¼ÈʆȪ¥”¨ÆFA ‹^5Ð&¿×^îæ F+8¡ºD¸´³bCqlcb?˜ •-÷ ‘ÜV¾%ޝ¤ëÓÛëÐèúlv‹%üÖ©ƶñ´GdóbËn‘Lg ÈS‘ìáçXtª5ÍgÒW½ôÕ>Ë~—ï{Ãæ¾‡¥øKVºÔ|,—º¬Ðˆ¦¹†i£O-C4‘ïÁ'nBdóŽM6é×—¨™má·Žs,ÈŽÛØªªÆÊ³ÆÎIÀ¬¿[íü8¹¶Žp`½¸ÔQfŒî^ê`Ô`çÞ¬M¢ë—ÓÝ\^[éD½¬P$+<¸m’-¼(d<åH©ó^'_ëÏþ§OëËþ ³ÿ ›ýœo¼é|¡/’Sìòy¾fq³ÊÛ¿w|mÎ9éÍE?Š´{x-æ’éÊ\FÒDzÞG;W‰ ¤®Üóœc¿JÊ›ÃZ•Æ SM¾â ß´ÃÔ'®қ>Ó7ø™·c©ÛŒU/ÃrÚ]XË*À#ŽÚæ9ãY¤—/,ˆü4™fû­’HÉ9ÀÎþ¿óëñ5.õÍ:IJÏ;oUFÙO#ä… Äí< ž éL"ÒÙ¬U'wkàZH$bÀ .W€wcñƒ\ÿü!÷ßÙ(’ÏÅì7‹,d\Ih‘ H¦DùÔì$’3óØÕ»/ßX½´ÐhåŠÎé ùÒÈ<é]Ï–a•9c‚O à×áý %Óü]ö·ýžöoN›¢¸/•bd‘UqŽ7,EéÛÓ6,|I Ü€L±[¯úQmòœ…†_,·ÝÛŽç$c#¯$W´ð¿’óÄònöÖѲ1óâ.wôÆrÊAõŸmàýBK1ýÕ¶÷µ¾†Y!ïO(u`¤t‚}¹ëFÚzGø~Z›‰â%í¤œM8Ȧ6´•ebÿwlew¶yÁçÐÔ’ø‹K†Ê ³<ùòÖ+y$íûÙERÃoC0x85B{-~ímnf‹MK›)ÖX Iä)'ÈÈûŸ`+ü‡u9â4-SO{kûQe=ð7&he‘£ŒyÎ$;\!?)P9Q¸dñÒ†#Dx§Gc>˶uU¤t†FA¸)P. 6õ‚IÏÓLjôÃfnD“íù&/²Ëçy˜Ý·ÊÛ¿;~o»ÓžœÕÑõ˜¬µcÕ²ÞÞ\Ç2¼e‘HÆ®¹!ŠnØÀ¸€AëYðxgTŠÎé^ IZkÕ¹XäÔîK ùnvù²½pr ^×ä¥Ï‹´û{›IJÛ^[Ë2K2Hà¡PWËU-Ÿ˜ç mÚsV.¼Ick$,ò)³’Ûí-r !T²ªpÎâß¡ª–:¡ ÖŸ=ÕÊLÐYÜ@å¤glÈèÊ– nã‚p95RÏÂ×°é m4¶í:Ce•fÚ»g–ÝÃ¥×çÿ?¯Ëþ ©‹4y¦XVyÖC(‰–KIPÆí¢MÊ<½ÙÝŒöÍNž ÓP6K;ù¡™FÌ –U“nÆaƒ <CTu êéu ’B>Õymp›‰ác1–Ž¿!ÇáT¥ðþµq¯ÛÞO4RGÌ’,†ö\4lŽª¢ »¨p7d“ŽO4º^C4àñn‰so-ÄwoäŹ.Öò(h‡VRTo¾Üâ´ã½·–ö[4“3ÅJé´ð¬X)ÏNv·å\»øJîm"ÊÅçL:,ºtŒ¤ŸÞ8Œr¿!ô=+SH°ÔãÖ/5E-"3ÛC Ço+I‚†BI,«×xíþ5Nß×Ì]?¯/ø&åQHŠ( Š( Š( Š( Š( vÖмrº]Üúæà•ËÁ>sŒüÊOaS}Š_ú ÞþPÿñº¡}¥>³¡\ZEuc1¹¸hî-edda4˜ÎÜ=AëìpEøoTÑ-¤›ZÖ®µé~]­s$‘D¹þÝIêIù-½D–…í'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`\·&;I'—­Ú·ý;L?ñèªïÚýë'P}šµ¡ÿ¦èQÑçûÓŒn‰”¬Ê>:Ôn-ü+3ÛMSÜ=¸ aŒàç>Þ•j-ÉpάªIvŒ óótïKk¤AnÌîL®dw’Ýíœg¶hþ¿ 3­5K¨í­am¯,ɉŸ$¶N'<⺠º\kwk"•X­¬Q…9õby«ôÄ‘¾ÓÛÑ­þ>•¯X²œxbÈú}—ÿCJàö6þ×ïLšìˆd vžk3Ï÷¡¦ ¥OB0kYSº±šž§¡ø›SŠÛÃQ^ßÝJþl“³X´ð˜œ€ÄŸ› ¬9ôZ×¶ñÞ½w§Ëu ‚:Éd÷P“e:$L¼ùlì@“+Ñ—#¥iÇ¡é1<¥¢ƒ§†§{a‚:óøæ–ËFÒô錶ÖÅX¡CHîIÉT H@OeÀ¡Áêëúõ3›â¡5ÕÌv‘ZšH#Ó™²|ÂÅD…¹ä.îØé[߈5X5û /Mk4ûM¼Ò´—1³í)·—®¯l–ÞÑlþÁäY*}€»[|ì|²ÿ{©çñÎ;S5] cX³½¸™ÄvñI‰‘›~9Þ¬éøæ‡m?­O_ëúØ‹Nñ¶©«]ÚyKioltÁ}8xšG$9VUùÔqÁ9üj¼Þ=Õít¨ïf†É¾Ûa5åª"?îJÁd;¾|‚9y¶môí>Òá'‚Ýc‘-ŪàœÈ\tëøÖuφ4ÇÓ¯mm#û3ÜÀð+–i*ÜŠ[ 3Δ ìíçúÿÀûM__/Óþ ×5]1d†òI®$··šÝàö§šÛpÊ Úyã½Jþ2×>ÍbÚ(îeÔÒÍn.,æŠ9#e'zÆÄ0#ÆON¼ñ5·‡t¨,$µx ¢hÑ%w‘ÉmŸwi$”ò‘ŽÕ4z.—D¢Ý‰Žà]y]œÊ3KqÉ5\šÿ]ÿÈ\ú]¿ÌÌoëÚn¯®Osymskc-¢Ê‚Ý,lvA¼àÄóœã®+¨ðþ¹s«im¸XÑdšO$GŸõAÈRrz3øÖ©¢A} Öζ÷7ñy3ÈûäV\c>^ເèÝ«NÆ8´û {83åAÆ™ë€1IC¿õý~¬n}ßµûÕ(äó5»¦ÿ§hGþ=-VóýèÓß~­vé„?ú”¥ Œ®Ë:UÆË7\ô¹ŸÿF½]û_½aZM¶9†åæýÕ?ŸïUÈ.s6yåÖ|]}§\]ÝÁiiiÄ–×3¹l¹d œmǵC©x›SÓf¼´²x¦M&Ånn$¼RÒ\g?(*T)Ÿ›’8«7úe†¥*Ëq‚P†?2Þ&(z©(A#ØñPO h×H{%UŠ1 ¬nÈ­9ÁH ¹#ó©önßטùÕÿ¯"‹øïV-yVÙöwñ˜™Ît”!ë»ßÝ9öÅhè¾-Ô5li“Gn²[ þÚQX`«…nIÆå9ç5J Ø®±y¨\9žt"Ë"ÆQ@°ø###ŽÕkKÒÆŸ©êZŒ³$·7qlUU\Œ’OrsÏ ¦¡ª¿õ¢ÿ‚'=³í~õKU¸ßf‹ž·0èÔªÞ½Aw6èáÿ—˜?ôjÓäcBI<½nÕ¿éÚaÿEW~×ïY:ƒìÕ­ý0›ÿBŽ?Þ¦1º¥fSñÆ¡<>•­î&‚C< ¾ 0UÁ5‰¨xŠëÂz¾¡im%ÍÕ¼Û¼ s,—L®æ3É%Ø`´ ã­ÝFÖ×U³kKÈÌ1 T;)È ƒ• Ž@ª£DÒÅµÌ nÒ­ÎÓ+Í3É#mû¿;ðx<Š~͇:±—qâ½RK-®–â¤ÈÎKl—qy.Àì~zðA$dfšž8×/´{»ˆáò–]:[¨g[•m™FB–BW£ Ž„V´Z&• ˆ­¹fŠcp®ò»±»™‰%¸8ç4Ø4 ÛÍÚ|²DЕy]•co¼ª !ô\RtÝšþ¶ÿ1ªŠéÿ[ÿ‘–$x†ûþ¾Gþ“[Ö”¾"*|'¤|<ÿ‘:/úü½ÿÒ©h£áçü‰Ñ×åïþ•KE*Ÿõ&‡ð£è~ǯö*ÿé¯LÑl­¥¬³ÛjÞí³ü£/ØÆÀä9ý+Åô½j‹+Fû\6×öð¬G;ª+]€‚ß)Ê‘V>ÕüôðÿþI×O+œt1u! Y»3ÞZòና6¶Jœô1ÁÆ?燹§}¾ëþ{ëø?øÅx/Ú¢ÿž¾ÿÉ:O´Åÿ=|?ÿ’u>Åö¬SþoÈöÙmmçžIæ·Ô¦–B <ºz¹8wƒŽâ£}>ÍÔk©FA =cu äË#§c^/ö˜篇ÿòRsüõðÿþJQì_`úÄ?›ñG½}¾ëþ{ëø?øÅoºÿžúßþþ1^ ö˜?篇ÿòR—í6ÿó×Ãÿù)G±}ƒëÿ›ò=ãí÷_óß[ÿÀ1ÿÆ(û}×ü÷Öÿð ñŠð´ÛÿÏ_ÿä¥9.­GY|?ÿ’”{Ø>±Où¿#ݾßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯ 7–}¥Ð?òR£7vǤ¾ÿÉJ~ÁöÖaüß‘îßoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWƒýªßþzøÿ%)>×Öxÿ%(ö°þ³æüyû}×ü÷Öÿð ñŠ>ßuÿ=õ¿üüb¼ÝÁõžÿÉJ…®Ó´žüìèö/°}fÍùýöû¯ùï­ÿàÿã}¾ëþ{ëø?øÅ|ýö¡ÿ=³æü ~ßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯Ñîtõ”¹ô¾ÂÔÿ*î-µ¤@<úìÏ8¿Â“¤×A¬DÚüQÙý¾ëþ{ëø?øÅoºÿžúßþþ1\—ö׃ü·ÐÿïÜ_áM:¿ƒü·ÐÿïÜ_áSìßòÛÓþoÅÛî¿ç¾·ÿ€cÿŒQöû¯ùï­ÿàÿãÈcÁƒþ[è÷î/ð¥þÚðoü÷ÐÿïÜ_áG³—`öôÿ›ñG[öû¯ùï­ÿàÿã}¾ëþ{ëø?øÅrÛ>ÿžúýû‹ü)Nµàïùï¢߸¿Âg/åoOù¿ußoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWÚ¿„âãCÿ¿q…g^ßx^UýÕΆýs‡úŠ=œ¿”=µ?çüQèoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWšYÝxn935ΆGýsƒú ØþÒð^ßøøÐóÿ\¢ÿ ^Î_ÊÚŸóþ(ìþßuÿ=õ¿üüb·ÝÏ}oÿÇÿ® æÿÂ%—q¡gþ¹CþÎ]\èæBbŸ@Çû–ßÔRä—òÛSþu÷£Ø>ßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯&´½ÑSdúýñmýlÛk>Ly’è?÷ÄáI©/°5VŸó¯½‹Û,‡>ˆ—–lFŽƒ,ʼnÀˆw&™ö%ÿŸŸ~rÿñºÃMsÁ˜¦Ð¿ïÜ_áRsÁ?óßBÿ¿q…/{ù1{JξôuzÿĽÒC‘ˆ4кô1ÉP !OJµ} ²@¸ $†â•ÀQ0=2z ä÷ÇåÇÿmø#þ{è÷î/ð¤:ß‚{O¡ÿ߸¿Â‡·~V5Z’Væ_z;{½.+Ö§ŠRÑ‚£º3÷Hô_ûÓþyÝàL¿üUqÇ[ð_iô?û÷øSµàÏùï¡ÿ߸¿Â¦Õɇ¶¤ú¯½§ö§üóºÿÀ™øª?°-?ç×þËÿÅW5¯ùo¡ÿ߸¿Âí¿ÿÏ}þýÅþ~ó³µ£Ý}èí°-?ç×þËÿÅQýiÿ<î¿ð&_þ*¸±®x3¼Úýû‹ü)ÇZðYëô?û÷øSµNÌ^Úuø—ö§üóºÿÀ™øª?°-?ç×þËÿÅW ú¿ƒIô?û÷øTGSðyÿ—þýÃþ7©ü¬¯kGù—àwߨŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ^s-÷„Ø|·:ÿ¶Pÿ…fÏ?‡‰ýÝÖ…ÿ~íÿ©*£iGù—Þb´Óã²GH"mí¹™‰8©$ô¢]"$EDJª0¸”?ïªñIn4‘÷.tÿ¶ÿ ª×v¤ÚåkUì¤ÄëÓ_i}è÷ì¤õ»ÿÀ™øª?²“Öïÿeÿâ«ÁÖþÉOúÝÿ%iÇS²ÇúÍÿ%jÖD¼U>ëï=Ûû)=nÿð&_þ*ì¤õ»ÿÀ™øªð)5 c÷dÐòR¢7ÐÿÏ]ó´£êÒÖ©÷üO ¿²“Öïÿeÿâ¨þÊO[¿ü —ÿНŸEì=åÐòRœ/-¿ç®ƒÿ’”}ZAõª}ÿèì¤õ»ÿÀ™øªtštRÙ-£BþB…A`FÒäsÆ|ûöËoùë ÿä¥'Ûm¿ç®ƒÿ’”þ¯ úÕ>ÿ‰ï_ØŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ^ õñË ÿä­^X°ùfÐ+Z^ƧpúÅ.ëð=ÇûÓþyÝàL¿üUØŸóÎëÿeÿâ«ÂîÐfÐòR™5Ý©,ºþJQìªÖ)w_ï_ØŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ_=µÔ`ñ'‡ÿòNœ—±¯áÿÎÎe0úÅ.ëð>‚þÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªð}nGßðÿçiQ5ÔDñ'‡ÿòNc>âúÅ.ëð>ƒþÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªùìÝEõžüìé¢ê?ùéáÿÎÎc>ãúÅ.ëð>†þÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªùì]DúÏþvuñ>¦¾|kû^ÏáÿÎÒ•o­;É ä¥Âo¨}f—uøöÚ £;¿•p ±s¶ydœžc©¤þÀ´ÿžw_ø/ÿ^%ݱû²xÿ%*#qi|?ÿ’t{÷Ö)w_ôö§üóºÿÀ™øª?°-?ç×þËÿÅWÏi‹þzøÿ$꼓dü³h/cS¸¾±Kºü£?°-?ç×þËÿÅQýiÿ<î¿ð&_þ*¾pÉÿ=tÎÊž'l­Ð?;:=•Aýb—uøF`ZÏ;¯ü —ÿŠ¥]Ñ]ʸ%8Ý<Œ2G±ÔWÎ&wÏúÝó³§ †ÿžºçgG²˜}b—uøIÝéq^´m…òßûùWøísâ ðzý¤é5½r¢ú×?ëtü”¥ŸX°†×7¶^Ly+ £FI'°Xý}j£EÅÝ“,D$¬™í¿?äN‹þ¿/ôªZ*¿Âˆ¼øw§]:…iå¹”¨è \HqúÑ\ów“hÞ”\a¾ˆìh¢Š“@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ÿÙtango-9.2.5a/doc/src/advanced/advanced.lyx0000644023471100065110000035170113034745264015351 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter Advanced features \end_layout \begin_layout Section Attribute alarms \end_layout \begin_layout Standard Each Tango attribute two several alarms. These alarms are : \end_layout \begin_layout Itemize A four thresholds level alarm \end_layout \begin_layout Itemize The read different than set (RDS \begin_inset Index idx status collapsed \begin_layout Plain Layout RDS \end_layout \end_inset ) alarm \end_layout \begin_layout Subsection The level alarms \end_layout \begin_layout Standard This alarm is defined for all Tango attribute read type and for numerical data type. The action of this alarm depend on the attribute value when it is read : \end_layout \begin_layout Itemize If the attribute value is below or equal the attribute configuration \series bold min_alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout min-alarm \end_layout \end_inset \series default parameter, the attribute quality factor is switched to Tango::ATTR_ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-ALARM \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM. \end_layout \begin_layout Itemize If the attribute value is below or equal the attribute configuration \series bold min_warning \begin_inset Index idx status collapsed \begin_layout Plain Layout min-warning \end_layout \end_inset \series default parameter, the attribute quality factor is switched to Tango::ATTR_WARNING \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-WARNING \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM. \end_layout \begin_layout Itemize If the attribute value is above or equal the attribute configuration \series bold max_warning \begin_inset Index idx status collapsed \begin_layout Plain Layout max-warning \end_layout \end_inset \series default parameter, the attribute quality factor is switched to Tango::ATTR_WARNING \begin_inset Index idx status open \begin_layout Plain Layout ATTR-WARNING \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM. \end_layout \begin_layout Itemize If the attribute value is above or equal the attribute configuration \series bold max_alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout max-alarm \end_layout \end_inset \series default parameter, the attribute quality factor is switched to Tango::ATTR_ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-ALARM \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM. \end_layout \begin_layout Standard If the attribute is a spectrum or an image, then the alarm is set if any one of the attribute value satisfies the above criterium. By default, these four parameters are not defined and no check will be done. \end_layout \begin_layout Standard The following figure is a drawing of attribute quality factor and device state values function of the the attribute value. \end_layout \begin_layout Standard \begin_inset Float figure placement H wide false sideways false status open \begin_layout Plain Layout \align center \begin_inset Graphics filename alarm.eps scale 50 \end_inset \end_layout \begin_layout Plain Layout \begin_inset Caption \begin_layout Plain Layout Level alarm \begin_inset CommandInset label LatexCommand label name "alarm_fig" \end_inset \end_layout \end_inset \end_layout \end_inset \end_layout \begin_layout Standard If the min_warning and max_warning parameters are not set, the attribute quality factor will simply change between Tango::ATTR_ALARM and Tango::ATTR_VAL ID function of the attribute value. \end_layout \begin_layout Subsection The Read Different than Set (RDS) alarm \end_layout \begin_layout Standard This alarm is defined only for attribute of the Tango::READ_WRITE and Tango::REA D_WITH_WRITE read/write type and for numerical data type. When the attribute is read (or when the device state is requested), if the difference between its read value and the last written value is something more than or equal to an authorized delta and if at least a certain amount of milli seconds occurs since the last write operation, the attribute quality factor will be set to Tango::ATTR_ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-ALARM \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset . If the attribute is a spectrum or an image, then the alarm is set if any one of the attribute value's satisfies the above criterium. This alarm configuration is done with two attribute configuration parameters called \series bold delta_val \begin_inset Index idx status collapsed \begin_layout Plain Layout delta-val \end_layout \end_inset \series default and \series bold delta_t \begin_inset Index idx status collapsed \begin_layout Plain Layout delta-t \end_layout \end_inset \series default . By default, these two parameters are not defined and no check will be done. \end_layout \begin_layout Section Enumerated \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium Enumeration \end_layout \end_inset attribute \end_layout \begin_layout Standard Since Tango release 9, enumerated attribute is supported using the new data type DevEnum \begin_inset Index idx status collapsed \begin_layout Plain Layout DevEnum \end_layout \end_inset . This data type is not a real C++ enumeration because: \end_layout \begin_layout Enumerate The enumerated value allways start with 0 \end_layout \begin_layout Enumerate Values are consecutive \end_layout \begin_layout Enumerate It is transferred on the network as DevShort data type \end_layout \begin_layout Standard One enumeration label is associated to each enumeration value. For the Tango kernel, it is this list of enumeration labels which will define the possible enumeration values. For instance if the enumeration has 3 labels, its value must be between 0 and 2. There are two ways to define the enumeration labels: \end_layout \begin_layout Enumerate At attribute creation time. This is the most common case when the list of possible enumeration values and labels are known at compile time. The Tango code generator Pogo generates for you the code needed to pass the enumeration labels to the Tango kernel. \end_layout \begin_layout Enumerate In the user code when the enumeration values and labels are not known at compile time but retrieved during device startup phase. The user gives the possible enumeration values to the Tango kernel using the Attribute class \emph on set_properties() \emph default method. \end_layout \begin_layout Standard A Tango client is able to retrieve the enumeration labels in the attribute configuration returned by instance by a call to the \emph on DeviceProxy::get_attribute_config() \emph default method. Using the \emph on DeviceProxy::set_attribute_config() \emph default call, a user may change the enumeration labels but not their number. \end_layout \begin_layout Subsection Usage in a Tango class \end_layout \begin_layout Standard Within a Tango class, you set the attribute value with a C++ enum or a DevShort variable. In case a DevShort variable is used, its value will be checked according to the enumeration labels list given to Tango kernel. \end_layout \begin_layout Subsubsection Setting the labels with enumeration compile time knowledge \end_layout \begin_layout Standard In such a case, the enumeration labels are given to Tango at the attribute creation time in the \emph on attribute_factory \emph default method of the XXXClass class. Let us take one example \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 enum class Card: short \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 NORTH = 0, \end_layout \begin_layout LyX-Code 4 SOUTH, \end_layout \begin_layout LyX-Code 5 EAST, \end_layout \begin_layout LyX-Code 6 WEST \end_layout \begin_layout LyX-Code 7 }; \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 void XXXClass::attribute_factory(vector &att_list) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 ..... \end_layout \begin_layout LyX-Code 12 TheEnumAttrib *theenum = new TheEnumAttrib(); \end_layout \begin_layout LyX-Code 13 Tango::UserDefaultAttrProp theenum_prop; \end_layout \begin_layout LyX-Code 14 vector labels = {"North","South","East","West"}; \end_layout \begin_layout LyX-Code 15 theenum_prop.set_enum_labels(labels); \end_layout \begin_layout LyX-Code 16 theenum->set_default_properties(theenum_prop); \end_layout \begin_layout LyX-Code 17 att_list.push_back(theenum); \end_layout \begin_layout LyX-Code 18 ..... \end_layout \begin_layout LyX-Code 19 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 1-7 : The definition of the enumeration (C++11 in this example) \end_layout \begin_layout Standard line 14 : A vector of strings with the enumeration labels is created. Because there is no way to get the labels from the enumeration definition, they are re-defined here. \end_layout \begin_layout Standard line 15 : This vector is given to the theenum_prop object which contains the user default properties \end_layout \begin_layout Standard line 16 : The user default properties are associated to the attribute \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard In most cases, all this code will be automatically generated by the Tango code generator Pogo. It is given here for completness. \end_layout \begin_layout Subsubsection Setting the labels without enumeration compile time knowledge \end_layout \begin_layout Standard In such a case, the enumeration labels are retrieved by the user in a way specific to the device and passed to Tango using the Attribute class \emph on set_properties() \emph default method. Let us take one example \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 void MyDev::init_device() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 ... \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 Attribute &att = get_device_attr()->get_attr_by_name("TheEnumAtt"); \end_layout \begin_layout LyX-Code 6 MultiAttrProp multi_prop; \end_layout \begin_layout LyX-Code 7 att.get_properties(multi_prop); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 multi_prop.enum_labels = {....}; \end_layout \begin_layout LyX-Code 10 att.set_properties(multi_prop); \end_layout \begin_layout LyX-Code 11 .... \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 5 : Get a reference to the attribute object \end_layout \begin_layout Standard line 7 : Retrieve the attribute properties \end_layout \begin_layout Standard line 9 : Initialise the attribute labels in the set of attribute properties \end_layout \begin_layout Standard line 10 : Set the attribute properties \end_layout \begin_layout Subsubsection Setting the attribute value \end_layout \begin_layout Standard It is possible to set the attribute value using either a classical DevShort variable or using a variable of the C++ enumeration. The following example is when you have compile time knowledge of the enumeratio n definition. We assume that the enumeration is the same than the one defined above (Card enumeration) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 enum Card points; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 void MyDev::read_TheEnum(Attribute &att) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 ... \end_layout \begin_layout LyX-Code 6 points = SOUTH; \end_layout \begin_layout LyX-Code 7 att.set_value(&points); \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 1 : One instance of the Card enum is created (named points) \end_layout \begin_layout Standard line 6 : The enumeration is initialized \end_layout \begin_layout Standard line 7 : The value of the attribute object is set using the enumeration (by pointer) \begin_inset Newline newline \end_inset To get the same result using a classical DevShort variable, the code looks like \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 DevShort sh; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 void MyDev::read_TheEnum(Attribute &att) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 ... \end_layout \begin_layout LyX-Code 6 sh = 1; \end_layout \begin_layout LyX-Code 7 att.set_value(&sh); \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 1 : A DevShort variable is created (named sh) \end_layout \begin_layout Standard line 6 : The variable is initialized \end_layout \begin_layout Standard line 7 : The value of the attribute object is set using the DevShort variable (by pointer) \end_layout \begin_layout Subsection Usage in a Tango client \end_layout \begin_layout Standard Within a Tango client, you insert/extract enumerated attribute value in/from DeviceAttribute object with a C++ enum or a DevShort variable. The later case is for generic client which do not have compile time knowledge of the enumeration. The code looks like \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 DeviceAttribute da = the_dev.read_attribute("TheEnumAtt"); \end_layout \begin_layout LyX-Code 2 Card ca; \end_layout \begin_layout LyX-Code 3 da >> ca; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 DeviceAttribute db = the_dev.read_attribute("TheEnumAtt"); \end_layout \begin_layout LyX-Code 6 DevShort sh; \end_layout \begin_layout LyX-Code 7 da >> sh; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 2-3 : The attribute value is extracted in a C++ enumeration variable \end_layout \begin_layout Standard line 6-7 : The attribute value is extracted in a DevShort variable \end_layout \begin_layout Section Device polling \end_layout \begin_layout Subsection Introduction \end_layout \begin_layout Standard Each tango device server automatically have a separate polling \begin_inset Index idx status collapsed \begin_layout Plain Layout polling \end_layout \end_inset thread pool. Polling a device means periodically executing command on a device (or reading device attribute) and storing the results (or the thrown exception) in a polling buffer. The aim of this polling is threefold : \end_layout \begin_layout Itemize Speed-up response time for slow device \end_layout \begin_layout Itemize Get a first-level history of device command output or attribute value \end_layout \begin_layout Itemize Be the data source for the Tango event system \end_layout \begin_layout Standard Speeding-up response time is achieved because the command_inout or read_attribut e CORBA operation is able to get its data from the polling buffer or from the a real access to the device. For \begin_inset Quotes eld \end_inset slow \begin_inset Quotes erd \end_inset device, getting the data from the buffer is much faster than accessing the device. Returning a first-level command output history (or attribute value history) to a client is possible due to the polling buffer which is managed as a circular buffer. The history is the contents of this circular buffer. Obviously, the history depth is limited to the depth of the circular buffer. The polling is also the data source for the event system because detecting an event means being able to regularly read the data, memorize it and declaring that it is an event after some comparison with older values. \end_layout \begin_layout Standard Starting with Tango 9, the default polling algorithm has been modifed. However, it is still possible to use the polling as it was in Tango releases prior to release 9. See chaper on polling configuration to get details on this. \end_layout \begin_layout Subsection Configuring the polling system \end_layout \begin_layout Subsubsection Configuring what has to be polled and how \end_layout \begin_layout Standard It is possible to configure the polling in order to poll : \end_layout \begin_layout Itemize Any command which does not need input parameter \end_layout \begin_layout Itemize Any attribute \end_layout \begin_layout Standard Configuring the polling is done by sending command to the device server administration device automatically implemented in every device server process. Seven commands are dedicated to this feature. These commands are \end_layout \begin_layout Description AddObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout AddObjPolling \end_layout \end_inset It add a new object (command or attribute) to the list of object(s) to be polled. It is also with this command that the polling period is specified. \end_layout \begin_layout Description RemObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout RemObjPolling \end_layout \end_inset To remove one object (command or attribute) from the polled object(s) list \end_layout \begin_layout Description UpdObjPollingPeriod \begin_inset Index idx status collapsed \begin_layout Plain Layout UpdObjPollingPeriod \end_layout \end_inset Change one object polling period \end_layout \begin_layout Description StartPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StartPolling \end_layout \end_inset Starts polling for the whole process \end_layout \begin_layout Description StopPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StopPolling \end_layout \end_inset Stops polling for the whole process \end_layout \begin_layout Description PolledDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout PolledDevice \end_layout \end_inset Allow a client to know which device are polled \end_layout \begin_layout Description DevPollStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevPollStatus \end_layout \end_inset Allow a client to precisely knows the polling status for a device \end_layout \begin_layout Standard All the necessary parameters for the polling configuration are stored in the Tango database. Therefore, the polling configuration is not lost after a device server process stop and restart (or after a device server process crash!!). \end_layout \begin_layout Standard It is also possible to automatically poll a command (or an attribute) without sending command to the device server administration device. This request some coding (a method call) in the device server software during the command or attribute creation. In this case, for every devices supporting this command or this attribute, polling configuration will be automatically updated in the database and the polling will start automatically at each device server process startup. It is possible to stop this behavior on a device basis by sending a RemObjPolli ng \begin_inset Index idx status collapsed \begin_layout Plain Layout RemObjPolling \end_layout \end_inset command to the device server administration device. The following piece of code shows how the source code should be written. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 \end_layout \begin_layout LyX-Code 2 void DevTestClass::command_factory() \end_layout \begin_layout LyX-Code 3 { \end_layout \begin_layout LyX-Code 4 ... \end_layout \begin_layout LyX-Code 5 command_list.push_back(new IOStartPoll("IOStartPoll", \end_layout \begin_layout LyX-Code 6 Tango::DEV_VOID, \end_layout \begin_layout LyX-Code 7 Tango::DEV_LONG, \end_layout \begin_layout LyX-Code 8 "Void", \end_layout \begin_layout LyX-Code 9 "Constant number")); \end_layout \begin_layout LyX-Code 10 command_list.back()->set_polling_period(400); \end_layout \begin_layout LyX-Code 11 ... \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 void DevTestClass::attribute_factory(vector &att_list) \end_layout \begin_layout LyX-Code 16 { \end_layout \begin_layout LyX-Code 17 ... \end_layout \begin_layout LyX-Code 18 att_list.push_back(new Tango::Attr("String_attr", \end_layout \begin_layout LyX-Code 19 Tango::DEV_STRING, \end_layout \begin_layout LyX-Code 20 Tango::READ)); \end_layout \begin_layout LyX-Code 21 att_list.back()->set_polling_period(250); \end_layout \begin_layout LyX-Code 22 ... \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard A polling period of 400 mS is set for the command called \begin_inset Quotes eld \end_inset IOStartPoll \begin_inset Quotes erd \end_inset at line 10 with the \emph on set_polling_period \emph default method of the Command class. Therefore, for a device of this class, the polling thread will start polling its IOStartPoll command at process start-up except if a RemObjPolling indicatin g this device and the IOStartPoll command has already been received by the device server administration device. This is exactly the same behavior for attribute. The polling period for attribute called \begin_inset Quotes eld \end_inset String_attr \begin_inset Quotes erd \end_inset is defined at line 20. \end_layout \begin_layout Standard Configuring the polling means defining device attribute/command polling period. The polling period has to be chosen with care. If reading an attribute needs 200 mS, there is no point to poll this attribute with a polling period equal or even below 200 mS. You should also take into account that some "free" time has to be foreseen for external request(s) on the device. On average, for one attribute needing X mS as reading time, define a polling period which is equal to 1.4 X (280 mS for our example of one attribute needing 200 mS as reading time). In case the polling tuning is given to external user, Tango provides a way to define polling period minimun threshold. This is done using device properties. These properties are named \emph on min_poll_period \emph default , \emph on cmd_min_poll_period \emph default and \emph on attr_min_poll_period \emph default . The property min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout min-poll-period \end_layout \end_inset (mS) defined a minimun polling period for the device. The property cmd_min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout cmd-min-poll-period \end_layout \end_inset allows the definition of a minimun polling period for a specific device command. The property attr_min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout attr-min-poll-period \end_layout \end_inset allows the definition of a minimun polling period for one device attribute. In case these properties are defined, it is not possible to poll the device command/attribute with a polling period below those defined by these properties. See Appendix A on device parameter to get a precise syntax description for these properties. \end_layout \begin_layout Standard The Jive \begin_inset CommandInset citation LatexCommand cite key "Jive doc" \end_inset tool also allows a graphical device polling configuration. \end_layout \begin_layout Subsubsection Configuring the polling threads pool \end_layout \begin_layout Standard Starting with Tango release 7, a Tango device server process may have several polling threads managed as a pool. For instance, this could be usefull in case of devices within the same device server process but accessed by different hardware channel when one of the channel is not responding (Thus generating long timeout and de-synchroni sing the polling thread). By default, the polling threads pool size is set to 1 and all the polled object(s) are managed by the same thread (idem polling system in Tango releases older than release 7) . The configuration of the polling thread pool is done using two properties associated to the device server administration device. These properties are named: \end_layout \begin_layout Itemize \emph on polling_threads_pool_size \begin_inset Index idx status collapsed \begin_layout Plain Layout polling-threads-pool-size \end_layout \end_inset \emph default defining the maximun number of threads that you can have in the pool \end_layout \begin_layout Itemize \emph on polling_threads_pool_conf \begin_inset Index idx status collapsed \begin_layout Plain Layout polling-threads-pool-conf \end_layout \end_inset \emph default defining which threads in the pool manages which device \end_layout \begin_layout Standard The granularity of the polling threads pool tuning is the device. You cannot ask the polling threads pool to have thread number 1 in charge of attribute \emph on att1 \emph default of device \emph on dev1 \emph default and thread number 2 to be in charge of \emph on att2 \emph default of the same device \emph on dev1 \emph default . \end_layout \begin_layout Standard When you require a new object (command or attribute) to be polled, two main cases may arrive: \end_layout \begin_layout Enumerate Some polled object(s) belonging to the device are already polled by one of the polling threads in the pool: There is no new thread created. The object is simply added to the list of objects to be polled for the existing thread \end_layout \begin_layout Enumerate There is no thread already created for the device. We have two sub-cases: \end_layout \begin_deeper \begin_layout Enumerate The number of polling threads is less than the polling_threads_pool_size: A new thread is created and started to poll the object (command or attribute) \end_layout \begin_layout Enumerate The number of polling threads is already equal to the polling_threads_pool_size: The software search for the thread with the smallest number of polled objects and add the new polled object to this thread \end_layout \end_deeper \begin_layout Standard Each time the polling threads pool configuration is changed, it is written in the database using the polling_threads_pool_conf property. If the behaviour previously described does not fulfill your needs, it is possible to update the polling_threads_pool_conf property in a graphical way using the Tango Astor \begin_inset CommandInset citation LatexCommand cite key "Astor_doc" \end_inset tool or manually using the Jive tool \begin_inset CommandInset citation LatexCommand cite key "Jive doc" \end_inset . These changes will be taken into account at the next device server process start-up. At start-up, the polling threads pool will allways be configured as required by the polling_threads_pool_conf property. The syntax used for this property is described in the Reference part of the Appendix \begin_inset CommandInset ref LatexCommand ref reference "cha:Reference-part" \end_inset . The following window dump is the Astor tool window which allows polling threads pool management. \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \begin_inset Graphics filename ThreadsManagement.png \end_inset \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard \align block In this example, the polling threads pool size to set to 9 but only 4 polling threads are running. Thread 1 is in charge of all polled objects related to device pv/thread-pool/te st-1 and pv/thread-pool/test-2. Thread 2 is in charge of all polled objects related to device pv/thread-pool/te st-3. Thread 3 is in charge of all polled objects related to device pv/thread-pool/te st-5 anf finally, thread 4 is in charge of all polled objects for devices pv/thread-pool/test-4, pv/thread-pool/test-6 and pv/thread-pool/test-7. \end_layout \begin_layout Standard It's also possible to define the polling threads pool size programmatically in the main function of a device server process using the \emph on Util::set_polling_threads_pool_size() \begin_inset Index idx status collapsed \begin_layout Plain Layout set-polling-threads-pool-size \end_layout \end_inset \emph default method before the call to the \emph on Util::server_init() \emph default method \end_layout \begin_layout Subsubsection Choosing polling algorithm \end_layout \begin_layout Standard Starting with Tango 9, you can choose between two different polling algorithm: \end_layout \begin_layout Itemize The polling as it was in Tango since it has been introduced. This means: \end_layout \begin_deeper \begin_layout Itemize For one device, always poll attribute one at a time even if the polling period is the same (use of read_attribute instead of read_attributes) \end_layout \begin_layout Itemize Do not allow the polling thread to be late: If it is the case (because at the end of polling object 1, the time is greater than the polling date of object 2), discard polling object and inform event user by sending one event with error (Polling thread is late and discard....) \end_layout \end_deeper \begin_layout Itemize New polling algorithm introduced in Tango 9 as the default one. This means: \end_layout \begin_deeper \begin_layout Itemize For one device, poll all attributes with the same polling period using a single device call (read_attributes) \end_layout \begin_layout Itemize Allow the polling thread to be late but only if number of late objects decreases. \end_layout \end_deeper \begin_layout Standard The advantages of new polling algorithm are \end_layout \begin_layout Enumerate In case of several attributes polled on the same device at the same period a lower device occupation time by the polling thread (due to a single read_attr ibutes() call instead of several single read_attribute() calls) \end_layout \begin_layout Enumerate Less \begin_inset Quotes eld \end_inset Polling thread late \begin_inset Quotes erd \end_inset errors in the event system in case of device with non constant response time \end_layout \begin_layout Standard The drawback is \end_layout \begin_layout Enumerate The loss of attribute individual timing data reported in the polling thread status \end_layout \begin_layout Standard It is still possible to return to pre-release 9 polling algorithm. To do so, you can use the device server process administration device \emph on polling_before_9 \emph default \begin_inset Index idx status collapsed \begin_layout Plain Layout polling_before_9 \end_layout \end_inset property by setting it to true. It is also possible to choose this pre-release 9 algorithm in device server process code in the main function of the process using the \emph on Util::set_polling_before_9() \emph default method. \end_layout \begin_layout Subsection Reading data from the polling buffer \end_layout \begin_layout Standard For a polled command or a polled attribute, a client has three possibilities to get command result or attribute value (or the thrown exception) : \end_layout \begin_layout Itemize From the device itself \end_layout \begin_layout Itemize From the polling buffer \end_layout \begin_layout Itemize From the polling buffer first and from the device if data in the polling buffer are invalid or if the polling is badly configured. \end_layout \begin_layout Standard The choice is done during the command_inout CORBA operation by positioning one of the operation parameter. When reading data from the polling buffer, several error cases are possible \end_layout \begin_layout Itemize The data in the buffer are not valid any more. Every time data are requested from the polling buffer, a check is done between the client request date and the date when the data were stored in the buffer. An exception is thrown if the delta is greater than the polling period multiplied by a \begin_inset Quotes eld \end_inset too old \begin_inset Quotes erd \end_inset factor. This factor has a default value and is up-datable via a device property. This is detailed in the reference part of this manual. \end_layout \begin_layout Itemize The polling is correctly configured but there is no data yet in the polling buffer. \end_layout \begin_layout Subsection Retrieving command/attribute result history \end_layout \begin_layout Standard The polling thread stores the command result or attribute value in circular buffers. It is possible to retrieve an history of the command result (or attribute value) from these polling buffers. Obviously the history is limited by the depth of the circular buffer. For commands, a CORBA operation called \emph on command_inout_history_2 \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-history-2 \end_layout \end_inset \emph default allows this retrieval. The client specifies the command name and the record number he want to retrieve. For each record, the call returns the date when the command was executed, the command result or the exception stack in case of the command failed when it was executed by the polling thread. In such a case, the exception stack is sent as a structure member and not as an exception. The same thing is available for attribute. The CORBA operation name is \emph on read_attribute_history_2 \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-2 \end_layout \end_inset . \emph default For these two calls, there is no check done between the call date and the record date in contrary of the call to retrieve the last command result (or attribute value). \end_layout \begin_layout Subsection Externally triggered polling \end_layout \begin_layout Standard Sometimes, rather than polling a command or an attribute regulary with a fixed period, it is more interesting to "manually" decides when the polling must occurs. The Tango polling system also supports this kind of usage. This is called \emph on externally triggered polling \emph default . To define one attribute (or command) as externally triggered, simply set its polling period to 0. This can be done with the device server administration device AddObjPolling or UpdObjPollingPeriod command. Once in this mode, the attribute (or command) polling is triggered with the \emph on trigger_cmd_polling() \emph default method (or \emph on trigger_attr_polling() \emph default method) of the Util class. The following piece of code shows how this method could be used for one externally triggered command. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 ..... \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 string ext_polled_cmd("MyCmd"); \end_layout \begin_layout LyX-Code 4 Tango::DeviceImpl *device = .....; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 Tango::Util *tg = Tango::Util::instance(); \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 tg->trigger_cmd_polling(device,ext_polled_cmd); \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 ..... \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 3 : The externally polled command name \end_layout \begin_layout Standard line 4 : The device object \end_layout \begin_layout Standard line 8 : Trigger polling of command MyCmd \end_layout \begin_layout Subsection Filling polling buffer \end_layout \begin_layout Standard Some hardware to be interfaced already returned an array of pair value, timestamp. In order to be read with the \emph on command_inout_history \emph default or \emph on read_attribute_history \emph default calls, this array has to be transferred in the attribute or command polling buffer. This is possible only for attribute or command configured in the externally triggered polling mode. Once in externally triggered polling mode, the attribute (or command) polling buffer is filled with the \emph on fill_cmd_polling_buffer() \begin_inset Index idx status collapsed \begin_layout Plain Layout fill-cmd-polling-buffer \end_layout \end_inset \emph default method (or \emph on fill_attr_polling_buffer() \begin_inset Index idx status collapsed \begin_layout Plain Layout fill-attr-polling-buffer \end_layout \end_inset \emph default method) of the Util class. For command, the user uses a template class called \emph on TimedCmdData \begin_inset Index idx status collapsed \begin_layout Plain Layout TimedCmdData \end_layout \end_inset \emph default for each element of the command history. Each element is stored in a stack in one instance of a template class called \emph on CmdHistoryStack \begin_inset Index idx status collapsed \begin_layout Plain Layout CmdHistoryStack \end_layout \end_inset . \emph default This object is one of the argument of the fill_cmd_polling_buffer() method. Obviously, the stack depth cannot be larger than the polling buffer depth. See \begin_inset CommandInset ref LatexCommand ref reference "sub:The-device-polling-prop" \end_inset to learn how the polling buffer depth is defined. The same way is used for attribute with the \emph on TimedAttrData \begin_inset Index idx status collapsed \begin_layout Plain Layout TimedAttrData \end_layout \end_inset \emph default and \emph on AttrHistoryStack \begin_inset Index idx status collapsed \begin_layout Plain Layout AttrHistoryStack \end_layout \end_inset \emph default template classes. These classes are documented in \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . The following piece of code fills the polling buffer for a command called MyCmd which is already in externally triggered mode. It returns a DevVarLongArray data type with three elements. This example is not really something you will find in a real hardware interface. It is only to demonstrate the fill_cmd_polling_buffer() method usage. Error management has also been removed. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 .... \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 Tango::DevVarLongArray dvla_array[4]; \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 for(int i = 0;i < 4;i++) \end_layout \begin_layout LyX-Code 6 { \end_layout \begin_layout LyX-Code 7 dvla_array[i].length(3); \end_layout \begin_layout LyX-Code 8 dvla_array[i][0] = 10 + i; \end_layout \begin_layout LyX-Code 9 dvla_array[i][1] = 11 + i; \end_layout \begin_layout LyX-Code 10 dvla_array[i][2] = 12 + i; \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 Tango::CmdHistoryStack chs; \end_layout \begin_layout LyX-Code 14 chs.length(4); \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 for (int k = 0;k < 4;k++) \end_layout \begin_layout LyX-Code 17 { \end_layout \begin_layout LyX-Code 18 time_t when = time(NULL); \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 Tango::TimedCmdData tcd(&dvla_array[k],when); \end_layout \begin_layout LyX-Code 21 chs.push(tcd); \end_layout \begin_layout LyX-Code 22 } \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 Tango::Util *tg = Tango::Util::instance(); \end_layout \begin_layout LyX-Code 25 string cmd_name("MyCmd"); \end_layout \begin_layout LyX-Code 26 DeviceImpl *dev = ....; \end_layout \begin_layout LyX-Code 27 \end_layout \begin_layout LyX-Code 28 tg->fill_cmd_polling_buffer(dev,cmd_name,chs); \end_layout \begin_layout LyX-Code 29 \end_layout \begin_layout LyX-Code 30 ..... \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 3-11 : Simulate data coming from hardware \end_layout \begin_layout Standard Line 13-14 : Create one instance of the CmdHistoryStack class and reserve space for one history of 4 elements \end_layout \begin_layout Standard Line 16-17 : A loop on each history element \end_layout \begin_layout Standard Line 18 : Get date (hardware simulation) \end_layout \begin_layout Standard Line 20 : Create one instance of the TimedCmdData class with data and date \end_layout \begin_layout Standard Line 21 : Store this command history element in the history stack. The element order will be the insertion order whatever the element date is. \end_layout \begin_layout Standard Line 28 : Fill command polling buffer \end_layout \begin_layout Standard After one execution of this code, a command_inout_history() call will return one history with 4 elements. The first array element of the oldest history record will have the value 10. The first array element of the newest history record will have the value 13. A command_inout() call with the data source parameter set to CACHE will return the newest history record (ie an array with values 13,14 and 15). A command_inout() call with the data source parameter set to DEVICE will return what is coded is the command method. If you execute this code a second time, a command_inout_history() call will return an history of 8 elements. \end_layout \begin_layout Standard The next example fills the polling buffer for an attribute called MyAttr which is already in externally triggered mode. It is a scalar attribute of the DevString data type. This example is not really something you will find in a real hardware interface. It is only to demonstrate the fill_attr_polling_buffer() method usage with memory management issue. Error management has also been removed. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 .... \end_layout \begin_layout LyX-Code \align block 2 \end_layout \begin_layout LyX-Code \align block 3 AttrHistoryStack ahs; \end_layout \begin_layout LyX-Code \align block 4 ahs.length(3); \end_layout \begin_layout LyX-Code \align block 5 \end_layout \begin_layout LyX-Code \align block 6 for (int k = 0;k < 3;k++) \end_layout \begin_layout LyX-Code \align block 7 { \end_layout \begin_layout LyX-Code \align block 8 time_t when = time(NULL); \end_layout \begin_layout LyX-Code \align block 9 \end_layout \begin_layout LyX-Code \align block 10 DevString *ptr = new DevString [1]; \end_layout \begin_layout LyX-Code \align block 11 ptr = CORBA::string_dup("Attr history data"); \end_layout \begin_layout LyX-Code \align block 12 \end_layout \begin_layout LyX-Code \align block 13 TimedAttrData tad(ptr,Tango::ATTR_VALID,true,when); \end_layout \begin_layout LyX-Code \align block 14 ahs.push(tad); \end_layout \begin_layout LyX-Code \align block 15 } \end_layout \begin_layout LyX-Code \align block 16 \end_layout \begin_layout LyX-Code \align block 17 Tango::Util *tg = Tango::Util::instance(); \end_layout \begin_layout LyX-Code \align block 18 string attr_name("MyAttr"); \end_layout \begin_layout LyX-Code \align block 19 DeviceImpl *dev = ....; \end_layout \begin_layout LyX-Code \align block 20 \end_layout \begin_layout LyX-Code \align block 21 tg->fill_attr_polling_buffer(dev,attr_name,ahs); \end_layout \begin_layout LyX-Code \align block 22 \end_layout \begin_layout LyX-Code \align block 23 ..... \end_layout \begin_layout LyX-Code \align block \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 3-4 : Create one instance of the AttrHistoryStack class and reserve space for an history with 3 elements \end_layout \begin_layout Standard Line 6-7 : A loop on each history element \end_layout \begin_layout Standard Line 8 : Get date (hardware simulation) \end_layout \begin_layout Standard Line 10-11 : Create a string. Note that the DevString object is created on the heap \end_layout \begin_layout Standard Line 13 : Create one instance of the TimedAttrData class with data and date requesting the memory to be released. \end_layout \begin_layout Standard Line 14 : Store this attribute history element in the history stack. The element order will be the insertion order whatever the element date is. \end_layout \begin_layout Standard Line 21 : Fill command polling buffer \end_layout \begin_layout Standard It is not necessary to return the memory allocated at line 10. The \emph on fill_attr_polling_buffer() \emph default method will do it for you. \end_layout \begin_layout Subsection Setting and tuning the polling in a Tango class \end_layout \begin_layout Standard Even if the polling is normally set and tuned with external tool like Jive, it is possible to set it directly into the code of a Tango class. A set of methods belonging to the \emph on DeviceImpl \emph default class allows the user to deal with polling. These methods are: \end_layout \begin_layout Itemize \emph on is_attribute_polled() \emph default and \emph on is_command_polled() \emph default to check if one command/attribute is polled \end_layout \begin_layout Itemize \emph on get_attribute_poll_period() \emph default and \emph on get_command_poll_period() \emph default to get polled object polling period \end_layout \begin_layout Itemize \emph on poll_attribute() \emph default and \emph on poll_command() \emph default to poll command or attribute \end_layout \begin_layout Itemize \emph on stop_poll_attribute() \emph default and \emph on stop_poll_command() \emph default to stop polling a command or an attribute \end_layout \begin_layout Standard The following code snippet is just an exmaple of how these methods could be used. They are documented in \begin_inset CommandInset citation LatexCommand cite key "Tango-dsclasses-doc" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block \begin_inset CommandInset include LatexCommand lstinputlisting filename "poll_in_ds.cpp.lines" lstparams "language={C++}" \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Threading \begin_inset CommandInset label LatexCommand label name "sec:Threading" \end_inset \end_layout \begin_layout Standard When used with C++, Tango used omniORB as underlying ORB. This CORBA implementation is a threaded implementation and therefore a C++ Tango device server or client are multi-threaded processes. \end_layout \begin_layout Subsection Device server process \end_layout \begin_layout Standard A classical Tango device server without any connected clients has eight threads. These threads \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset are : \end_layout \begin_layout Itemize The main thread waiting in the ORB main loop \end_layout \begin_layout Itemize Two ORB implementation threads (the POA thread) \end_layout \begin_layout Itemize The ORB scavanger thread \end_layout \begin_layout Itemize The signal thread \end_layout \begin_layout Itemize The heartbeat thread (needed by the Tango event system) \end_layout \begin_layout Itemize Two Zmq implementation threads \end_layout \begin_layout Standard On top of these eight threads, you have to add the thread(s) used by the polling threads pool. This number depends on the polling thread pool configuration and could be between 0 (no polling at all) and the maximun number of threads in the pool. \end_layout \begin_layout Standard A new thread is started for each connected client. Device server are mostly used to interface hardware which most of the time does not support multi-threaded access. Therefore, all remote calls executed from a client are serialized within the device server code by using mutual exclusion. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sub:Serialization-model-within" \end_inset on which serialization model are available. In order to limit thread number, the underlying ORB (omniORB) is configured to shutdown threads dedicated to client if the connection is inactive for more than 3 minutes. To also limit thread number, the ORB is configured to create one thread per connection up to 55 threads. When this level is reached, the threading model is automatically switch to a "thread pool" model with up to 100 threads. If the number of threads decrease down to 50, the threading model will return to "thread per connection" model. \end_layout \begin_layout Standard If you are using event, the event system for its internal heartbeat system periodically (every 200 seconds) sends a command to the device server administr ation device. As explained above, a thread is created to execute these command. The omniORB scavanger will terminate this thread before the next event system heartbeat command arrives. For example, if you have a device server with three connected clients using only event, the process thread number will permanently change between 8 and 11 threads. \end_layout \begin_layout Standard In summary, the number of threads in a device server process can be evaluated with the following formula: \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \series bold 8 + k + m \series default \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset k is the number of polling threads used from the polling threads pool and m is the number of threads used for connected clients. \end_layout \begin_layout Subsubsection Serialization model within a device server \begin_inset CommandInset label LatexCommand label name "sub:Serialization-model-within" \end_inset \end_layout \begin_layout Standard Four serialization \begin_inset Index idx status collapsed \begin_layout Plain Layout serialization \end_layout \end_inset models are available within a device server. These models protect all requests coming from the network but also requests coming from the polling thread. These models are: \end_layout \begin_layout Enumerate Serialization by device. All access to the same device are serialized. As an example, let's take a device server implementing one class of device with two instances (dev1 and dev2). Two clients are connected to these devices (client1 and client2). Client2 will not be able to access dev1 if client1 is using it. Nevertheless, client2 is able to access dev2 while client1 access dev1 (There is one mutual exclusion object by device) \end_layout \begin_layout Enumerate Serialization by class. With non multi-threaded legacy software, the preceding scenario could generate problem. In this mode of serialization, client2 is not able to access dev2 while client1 access dev1 because dev2 and dev1 are instances of the same class (There is one mutual exclusion object by class) \end_layout \begin_layout Enumerate Serialization by process. This is one step further than the previous case. In this mode, only one client can access any device embedded within the device server at a time. There is only one mutual exclusion object for the whole process) \end_layout \begin_layout Enumerate No serialization. This is an exotic kind of serialization and \series bold should be used with extreme care \series default only with device which are fully thread safe. In this model, most of the device access are not serialized at all. Due to Tango internal structure, the \emph on get_attribute_config \emph default , \emph on set_attribute_config \emph default , \emph on read_attributes \emph default and \emph on write_attributes \emph default CORBA calls are still protected. Reading the device state and status via commands or via CORBA attribute is also protected. \end_layout \begin_layout Standard By default, every Tango device server is in serialization by device mode. A method of the Tango::Util class allows to change this default behavior. \begin_inset Newpage newpage \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 #include \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 int main(int argc,char *argv[]) \end_layout \begin_layout LyX-Code 4 { \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 try \end_layout \begin_layout LyX-Code 7 { \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 Tango::Util *tg = Tango::Util::init(argc,argv); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 tg->set_serial_model(Tango::BY_CLASS); \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 tg->server_init(); \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 cout << "Ready to accept request" << endl; \end_layout \begin_layout LyX-Code 16 tg->server_run(); \end_layout \begin_layout LyX-Code 17 } \end_layout \begin_layout LyX-Code 18 catch (bad_alloc) \end_layout \begin_layout LyX-Code 19 { \end_layout \begin_layout LyX-Code 20 cout << "Can't allocate memory!!!" << endl; \end_layout \begin_layout LyX-Code 21 cout << "Exiting" << endl; \end_layout \begin_layout LyX-Code 22 } \end_layout \begin_layout LyX-Code 23 catch (CORBA::Exception &e) \end_layout \begin_layout LyX-Code 24 { \end_layout \begin_layout LyX-Code 25 Tango::Except::print_exception(e); \end_layout \begin_layout LyX-Code 26 \end_layout \begin_layout LyX-Code 27 cout << "Received a CORBA::Exception" << endl; \end_layout \begin_layout LyX-Code 28 cout << "Exiting" << endl; \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 return(0); \end_layout \begin_layout LyX-Code 32 } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The serialization model is set at line 11 before the server is initialized and the infinite loop is started. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for all details on the methods to set/get serialization model. \end_layout \begin_layout Subsubsection Attribute Serialization model \end_layout \begin_layout Standard Even with the serialization model described previously, in case of attributes carrying a large number of data and several clients reading this attribute, a device attribute serialization has to be followed. Without this level of serialization, for attribute using a shared buffer, a thread scheduling may happens while the device server process is in the CORBA layer transferring the attribute data on the network. Three serialization \begin_inset Index idx status collapsed \begin_layout Plain Layout serialization \end_layout \end_inset models are available for attribute serialization. The default is well adapted to nearly all cases. Nevertheless, if the user code manages several attributes data buffer or if it manages its own buffer protection by one way or another, it could be interesting to tune this serialization level. The available models are: \end_layout \begin_layout Enumerate Serialization by kernel. This is the default case. The kernel is managing the serialization \end_layout \begin_layout Enumerate Serialization by user. The user code is in charge of the serialization. This serialization is done by the use of a omni_mutex object. An omni_mutex is an object provided by the omniORB package. It is the user responsability to lock this mutex when appropriate and to give this mutex to the Tango kernel before leaving the attribute read method \end_layout \begin_layout Enumerate No serialization. \end_layout \begin_layout Standard By default, every Tango device attribute is in serialization by kernel. Methods of the Tango::Attribute class allow to change the attribute serializati on behavior and to give the user omni_mutex object to the kernel. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void MyClass::init_device() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 ... \end_layout \begin_layout LyX-Code 4 ... \end_layout \begin_layout LyX-Code 5 Tango::Attribute &att = dev_attr->get_attr_by_name("TheAttribute"); \end_layout \begin_layout LyX-Code 6 att.set_attr_serial_model(Tango::ATTR_BY_USER); \end_layout \begin_layout LyX-Code 7 .... \end_layout \begin_layout LyX-Code 8 .... \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 } \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 void MyClass::read_TheAttribute(Tango::Attribute &attr) \end_layout \begin_layout LyX-Code 14 { \end_layout \begin_layout LyX-Code 15 .... \end_layout \begin_layout LyX-Code 16 .... \end_layout \begin_layout LyX-Code 17 the_mutex.lock(); \end_layout \begin_layout LyX-Code 18 .... \end_layout \begin_layout LyX-Code 19 // Fill the attribute buffer \end_layout \begin_layout LyX-Code 20 .... \end_layout \begin_layout LyX-Code 21 attr.set_value(buffer,....); \end_layout \begin_layout LyX-Code 22 attr->set_user_attr_mutex(&the_mutex); \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The serialization model is set at line 6 in the init_device() method. The user omni_mutex is passed to the Tango kernel at line 22. This omni_mutex object is a device data member. See \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset for all details on the methods to set attribute serialization model. \end_layout \begin_layout Subsection Client process \end_layout \begin_layout Standard Clients are also multi threaded processes. The underlying C++ ORB (omniORB) try to keep system resources to a minimum. To decrease process file descriptors usage, each connection to server is automatically closed if it is idle for more than 2 minutes and automatically re-opened when needed. A dedicated thread is spawned by the ORB to manage this automatic closing connection (the ORB scavenger thread). \end_layout \begin_layout Standard Threrefore, a Tango client has two threads which are: \end_layout \begin_layout Enumerate The main thread \end_layout \begin_layout Enumerate The ORB scavanger thread \end_layout \begin_layout Standard If the client is using the event system and as Tango is using the event push-push model, it has to be a server for receiving the events. This increases the number of threads \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset . The client now has 6 threads which are: \end_layout \begin_layout Itemize The main thread \end_layout \begin_layout Itemize The ORB scavenger thread \end_layout \begin_layout Itemize Two Zmq implementation threads \end_layout \begin_layout Itemize Two Tango event system related threads (the KeepAliveThread and the EventConsume r thread) \end_layout \begin_layout Section Generating events in a device server \end_layout \begin_layout Standard The server is at the origin of events \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset . It will fire events as soon as they occur. Standard events ( \emph on change \emph default , \emph on periodic \emph default and \emph on archive \emph default ) are detected automatically in the polling thread and fired as soon as they are detected. The \emph on periodic \emph default events can only be handled by the polling thread. \emph on Change, Data ready \emph default and \emph on archive \emph default events can also be pushed from the device server code. To allow a client to subscribe to events of non polled attributes the server has to declare that events are pushed from the code. Three methods are available for this purpose: \end_layout \begin_layout LyX-Code Attr::set_change_event(bool implemented, bool detect = true); \end_layout \begin_layout LyX-Code Attr::set_archive_event(bool implemented, bool detect = true); \end_layout \begin_layout LyX-Code Attr::set_data_ready_event( bool implemented); \end_layout \begin_layout Standard where \emph on implemented \emph default =true indicates that events are pushed manually from the code and \emph on detect \emph default =true (when used) triggers the verification of the same event properties as for events send by the polling thread. When setting \emph on detect \emph default =false, no value checking is done on the pushed value! The class DeviceImpl also supports the first two methods with an addictional parameter attr_name defining the attribute name. \end_layout \begin_layout Standard To push events manually from the code a set of data type dependent methods can be used: \end_layout \begin_layout LyX-Code DeviceImpl::push_change_event (string attr_name, ....); \end_layout \begin_layout LyX-Code DeviceImpl::push_archive_event(string attr_name, ....); \end_layout \begin_layout Standard For the data ready event, a DeviceImpl class method has to be used to push the event. \end_layout \begin_layout LyX-Code DeviceImpl::push_data_ready_event(string attr_name,Tango::DevLong ctr); \end_layout \begin_layout Standard See the class documentation for all available interfaces. \end_layout \begin_layout Standard For non-standard events a single call exists for pushing the data to the CORBA Notification Service (omniNotify). Clients who are subscribed to this event have to know what data type is in the DeviceAttribute and unpack it accordingly. \end_layout \begin_layout Standard To push non-standard events, use the following api call is available to all device servers : \end_layout \begin_layout LyX-Code DeviceImpl::push_event( string attr_name, \end_layout \begin_layout LyX-Code vector &filterable_names, \end_layout \begin_layout LyX-Code vector &filterable_vals, \end_layout \begin_layout LyX-Code Attribute &att) \end_layout \begin_layout Standard where \emph on attr_name \emph default is the name of the attribute \emph on . Filterable_names \emph default and \emph on filterable_vals \emph default represent any filterable data which can be used by clients to filter on. Here is a typical example of what a server will need to do to send its own events. We are in the read method of the "Sinusoide" attribute. This attribute is readable as any other attribute but an event is sent if its value is positive when it is read. On top of that, this event is sent with one filterable field called "value" which is set to the attribute value. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void MyClass::read_Sinusoide(Tango::Attribute &attr) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 ... \end_layout \begin_layout LyX-Code 4 struct timeval tv; \end_layout \begin_layout LyX-Code 5 gettimeofday(&tv, NULL); \end_layout \begin_layout LyX-Code 6 sinusoide = 100 * sin( 2 * 3.14 * frequency * tv.tv_sec); \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 if (sinusoide >= 0) \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 vector filterable_names; \end_layout \begin_layout LyX-Code 11 vector filterable_value; \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 filterable_names.push_back("value"); \end_layout \begin_layout LyX-Code 14 filterable_value.push_back((double)sinusoide); \end_layout \begin_layout LyX-Code 15 \end_layout \begin_layout LyX-Code 16 push_event( attr.get_name(), \end_layout \begin_layout LyX-Code 17 filterable_names, filterable_value, \end_layout \begin_layout LyX-Code 18 &sinusoide); \end_layout \begin_layout LyX-Code 19 } \end_layout \begin_layout LyX-Code 20 .... \end_layout \begin_layout LyX-Code 21 .... \end_layout \begin_layout LyX-Code 22 \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard line 13-14 : The filter pair name/value is initialised \end_layout \begin_layout Standard line 16-18 : The event is pushed \end_layout \begin_layout Section Using multicast protocol to transfer events \end_layout \begin_layout Standard This feature is available starting with Tango 8.1. Transferring events using a multicast \begin_inset Index idx status open \begin_layout Plain Layout multicasting \end_layout \end_inset protocol means delivering the events to a group of clients simultaneously in a single transmission from the event source. Tango, through ZMQ, uses the OpenPGM multicating protocol. This is one implementation of the PGM protocol defined by the RFC 3208 (Reliable multicasting protocol). Nevertheless, the default event communication mode is unicast and propagating events via multicasting requires some specific configuration. \end_layout \begin_layout Subsection Configuring events to use multicast transport \end_layout \begin_layout Standard Before using multicasting transport for event(s), you have to choose which address and port have to be used. In a IP V4 network, only a limited set of addresses are associated with multicasting. These are the IP V4 addresses between \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset 224.0.1.0 and 238.255.255.255 \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset Once the address is selected, you have to choose a port number. Together with the event name, these are the two minimum configuration informati ons which have to be provided to Tango to get multicast transport. This configuration is done using the \series bold MulticastEvent \begin_inset Index idx status open \begin_layout Plain Layout \series medium MulticastEvent \end_layout \end_inset \series default free property associated to the \series bold CtrlSystem \begin_inset Index idx status open \begin_layout Plain Layout \series medium CtrlSystem \end_layout \end_inset \series default object. \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Graphics filename jive_simpl.jpg scale 70 \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard In the above window dump of the Jive tool, the \emph on change \emph default event on the \emph on state \emph default attribute of the \emph on dev/test/11 \emph default device has to be transferred using multicasting with the address \emph on 226.20.21.22 \emph default and the port number \emph on 2222 \emph default . The exact definition of this CtrlSystem/MulticastEvent property for one event propagated using multicast is \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 CtrlSystem->MulticastEvent: Multicast address, \end_layout \begin_layout LyX-Code 2 port number, \end_layout \begin_layout LyX-Code 3 [rate in Mbit/sec], \end_layout \begin_layout LyX-Code 4 [ivl in seconds], \end_layout \begin_layout LyX-Code 5 event name \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Rate \begin_inset Index idx status open \begin_layout Plain Layout rate \end_layout \end_inset and Ivl \begin_inset Index idx status open \begin_layout Plain Layout ivl \end_layout \end_inset are optional properties. In case several events have to be transferred using multicasting, simply extend the MulicastEvent property with the configuration parameters related to the other events. There is only one MultiCastEvent property per Tango control system. The underlying multicast protocol (PGM) is rate limited. This means that it limits its network bandwidth usage to a user defined value. The optional third configuration parameter is the maximum rate (in Mbit/sec) that the protocol will use to transfert this event. Because PGM is a reliable protocol, data has to be buffered for re-transmission in case a receiver signal some lost data. The optional forth configuration parameter specify the maximum amount of time (in seconds) that a receiver can be absent for a multicast group before unrecoverable data loss will occur. Exercise care when setting large recovery interval as the data needed for recovery will be held in memory. For example, a 60 seconds (1 minute) recovery interval at a data rate of 1 Gbit/sec requires a 7 GBytes in-memory buffer. Whan any of these two optional parameters are not set, the default value (defined in next sub-chapter) are used. Here is another example of events using multicasting configuration \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \begin_inset Graphics filename jive_sophis.jpg scale 70 \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset In this example, there are 5 events which are transmitted using multicasting: \end_layout \begin_layout Enumerate Event \emph on change \emph default for attribute \emph on state \emph default on device \emph on dev/test/11 \emph default which uses multicasting address \emph on 226.20.21.22 \emph default and port number \emph on 2222 \end_layout \begin_layout Enumerate Event \emph on periodic \emph default for attribute \emph on state \emph default on device \emph on dev/test/10 \emph default which uses multicasting address \emph on 226.20.21.22 \emph default and port number \emph on 3333 \end_layout \begin_layout Enumerate Event \emph on change \emph default for attribute \emph on ImaAttr \emph default on device \emph on et/ev/01 \emph default which uses multicasting address \emph on 226.30.31.32 \emph default and port number \emph on 4444 \emph default . Note that this event uses a rate set to \emph on 40 Mbit/sec \emph default and a ivl set to \emph on 20 seconds \emph default . \end_layout \begin_layout Enumerate Event \emph on change \emph default for attribute \emph on event_change_tst \emph default on device \emph on dev/test/12 \emph default which uses multicasting address \emph on 226.20.21.22 \emph default and port number \emph on 2233 \end_layout \begin_layout Enumerate Event \emph on archive \emph default for attribute \emph on event_change_tst \emph default on device \emph on dev/tomasz/3 \emph default which uses multicasting address \emph on 226.20.21.22 \emph default and port number \emph on 2234 \end_layout \begin_layout Subsection Default multicast related properties \end_layout \begin_layout Standard On top of the MulticastEvent property previously described, Tango supports three properties to defined default value for multicast transport tuning. These properties are: \end_layout \begin_layout Itemize \series bold MulticastRate \series default \begin_inset Index idx status open \begin_layout Plain Layout MulticastRate \end_layout \end_inset associated to the CtrlSystem \begin_inset Index idx status open \begin_layout Plain Layout CtrlSystem \end_layout \end_inset object. This defines the maximum rate will will be used by the multicast protocol when transferring event. The unit is Mbit/sec. In case this property is not defined, the Tango library used a value of 80 Mbit/sec. \end_layout \begin_layout Itemize \series bold MulticastIvl \series default \begin_inset Index idx status open \begin_layout Plain Layout MulticastIvl \end_layout \end_inset associated to the CtrlSystem object. It specifies the maximum time (in sec) during which data has to be buffered for re-transmission in case a receiver signals some lost data. The unit is seconds. In case this property is not defined, the Tango library takes a value of 20 seconds. \end_layout \begin_layout Itemize \series bold MulticastHops \series default \begin_inset Index idx status open \begin_layout Plain Layout MulticastHops \end_layout \end_inset associated to the CtrlSystem object. This property defines the maximum number of element (router), the multicast packet is able to cross. Each time one element is crossed, the value is decremented. When it reaches 0, the packet is not transferred any more. In case this property is not defined, the Tango library uses a value of 5. \end_layout \begin_layout Section Memorized attribute \end_layout \begin_layout Standard It is possible to ask Tango to store in its database the last written value for attribute of the SCALAR data format and obviously only for READ_WRITE or READ_WITH_WRITE attribute. This is fully automatic. During device startup phase, for all device memorized \begin_inset Index idx status collapsed \begin_layout Plain Layout memorized \end_layout \end_inset attributes, the value written in the database is fetched and applied. A write_attribute call can be generated to apply the memorized value to the attribute or only the attribute set point can be initialised. The following piece of code shows how the source code should be written to set an attribute as memorized and to initialise only the attribute set point. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 void DevTestClass::attribute_factory(vector &att_list) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 ... \end_layout \begin_layout LyX-Code 4 att_list.push_back(new String_attrAttr()); \end_layout \begin_layout LyX-Code 5 att_list.back()->set_memorized(); \end_layout \begin_layout LyX-Code 6 att_list.back()->set_memorized_init(false); \end_layout \begin_layout LyX-Code 7 ... \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4 : The attribute to be memorized is created and inserted in the attribute vector. \end_layout \begin_layout Standard Line 5 : The \emph on set_memorized() \emph default method of the attribute base class is called to define the attribute as memorized. \end_layout \begin_layout Standard Line 6 : The set_memorized_init() method is called with the parameter false to define that only the set point should be initialsied. \end_layout \begin_layout Section Forwarded attribute \end_layout \begin_layout Subsection Definition \end_layout \begin_layout Standard Let's take an example to explain what is a forwarded attribute. We assume we have to write a Tango class for a ski lift in a ski resort somewhere in the Alps. Obviously, the ski lift has a motor for which we already have a Tango class. This motor Tango class has one attribute \emph on speed \emph default . But for the ski lift, the motor speed is not the only thing which has to be controlled. For instance, you also want to give access to the wind sensor data installed on the top of the ski lift. Therefore, you write a ski-lift Tango class representing the whole ski-lift system. This ski-lift class will have at least two attributes which are: \end_layout \begin_layout Enumerate The wind speed at the top of the ski-lift \end_layout \begin_layout Enumerate The motor speed \end_layout \begin_layout Standard The ski-lift Tango class motor speed attribute is nothing more than the motor Tango class speed attribute. All the ski-lift class has to do for this attribute is to forward the request (read/write) to the speed attribute of the motor Tango class. The speed attribute of the ski-lift Tango class is a \series bold forwarded attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium forwarded-attribute \end_layout \end_inset \series default while the speed attribute of the motor Tango class is its \series bold root attribute \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout root-attribute \end_layout \end_inset . \end_layout \begin_layout Standard A forwarded attribute get its configuration from its root attribute and it forwards to its root attribute \end_layout \begin_layout Itemize Its read / write / write_read requests \end_layout \begin_layout Itemize Its configuration change \end_layout \begin_layout Itemize Its event subscription \end_layout \begin_layout Itemize Its locking behavior \end_layout \begin_layout Standard As stated above, a forwarded attribute has the same configuration than its root attribute except its \emph on name \emph default and \emph on label \emph default which stays local. All other attribute configuration parameters are forwarded to the root attribute. If a root attribute configuration parameter is changed, the forwarded attribute is informed (via event) and its local configuration is also modified. \end_layout \begin_layout Standard The association between the forwarded attribute and its root attribute is done using a property named \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset __root_att \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset belonging to the forwarded attribute. This property value is simply the name of the root attribute. Muti-control system is supported and this __root_att \begin_inset Index idx status collapsed \begin_layout Plain Layout __root_att \end_layout \end_inset attribute property value can be something like \emph on tango://my_tango_host:10000/my/favorite/dev/the_root_attribute \emph default . The name of the root attribute is included in attribute configuration. \end_layout \begin_layout Standard It is forbidden to poll a forwarded attribute and one exception is thrown if such a case happens. Polling has to be done on the root attribute. Nevertheless, if the root attribute is polled, a request to read the forwarded attribute with the DeviceProxy object source parameter set to CACHE_DEVICE or CACHE will get its data from the root attribute polling buffer. \end_layout \begin_layout Standard If you subscribe to event(s) on a forwarded attribute, the subscription is forwarded to the root attribute. When the event is received by the forwarded attribute, the attribute name in the event data is modified to reflect the forwarded attribute name and the event is pushed to the original client(s). \end_layout \begin_layout Standard When a device with forwarded attribute is locked, the device to which the root attribute belongs is also locked. \end_layout \begin_layout Subsection Coding \end_layout \begin_layout Standard As explained in the chapter "Writing a Tango device server", each Tango class attribute is implemented via a C++ class which has to inherit from either \emph on Attr \emph default , \emph on SpectrumAttr \emph default or \emph on ImageAttr \emph default according to the attribute data format. For forwarded attribute, the related class has to inherit from the \series bold FwdAttr \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium FwdAttr \end_layout \end_inset \series default class whatever its data format is. For classical attribute, the programmer can define in the Tango class code default value for the attribute properties using one instance of the \emph on UserDefaultAttrProp \emph default class. For forwarded attribute, the programmer has to create one instance of the \series bold UserDefaultFwdAttrProp \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium UserDefaultFwdAttrProp \end_layout \end_inset \series default class but only the attribute label can be defined. One example of how to program a forwarded attribute is given below \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 class MyFwdAttr: public Tango::FwdAttr \end_layout \begin_layout LyX-Code \align block 2 { \end_layout \begin_layout LyX-Code \align block 3 public: \end_layout \begin_layout LyX-Code \align block 4 MyFwdAttr(const string &_n):FwdAttr(_n) {}; \end_layout \begin_layout LyX-Code \align block 5 ~MyFwdAttr() {}; \end_layout \begin_layout LyX-Code \align block 6 }; \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code \align block 8 void DevTestClass::attribute_factory(vector &att_list) \end_layout \begin_layout LyX-Code 9 { \end_layout \begin_layout LyX-Code 10 ... \end_layout \begin_layout LyX-Code 11 MyFwdAttr *att1 = new MyFwdAttr("fwd_att_name"); \end_layout \begin_layout LyX-Code 12 Tango::UserDefaultFwdAttrProp att1_prop; \end_layout \begin_layout LyX-Code 13 att1_prop.set_label("Gasp a fwd attribute"); \end_layout \begin_layout LyX-Code 14 att1->set_default_properties(att1_prop); \end_layout \begin_layout LyX-Code 15 att_list.push_back(att1); \end_layout \begin_layout LyX-Code 14 ... \end_layout \begin_layout LyX-Code 15 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 : The forwarded attribute class inherits from FwdAttr class. \end_layout \begin_layout Standard Line 4-5 : Only constructor and destructor methods are required \end_layout \begin_layout Standard Line 11 : The attribute object is created \end_layout \begin_layout Standard Line 12-14 : A default value for the forwarded attribute label is defined. \end_layout \begin_layout Standard Line 15: The forwarded attribute is added to the list of attribute \end_layout \begin_layout Standard In case of error in the forwarded attribute configuration (for instance missing __root_att property), the attribute is not created by the Tango kernel and is therefore not visible for the external world. The state of the device to which the forwarded attribute belongs to is set to ALARM (if not already FAULT) and a detailed error report is available in the device status. In case a device with forwarded attribute(s) is started before the device(s) with the root attribute(s), the same principle is used: forwarded attribute(s) are not created, device state is set to ALARM and device status is reporting the error. When the device(s) with the root attribute will start, the forwarded attributes will automatically be created. \end_layout \begin_layout Section Transferring images \end_layout \begin_layout Standard Some optimized methods have been written to optimize image transfer between client and server using the attribute DevEncoded \begin_inset Index idx status collapsed \begin_layout Plain Layout DevEncoded \end_layout \end_inset data type. All these methods have been merged in a class called EncodedAttribute. Within this class, you will find methods to: \end_layout \begin_layout Itemize Encode an image in a compressed way (JPEG \begin_inset Index idx status collapsed \begin_layout Plain Layout JPEG \end_layout \end_inset ) for images coded on 8 (gray scale), 24 or 32 bits \end_layout \begin_layout Itemize Encode a grey scale image coded on 8 or 16 bits \end_layout \begin_layout Itemize Encode a color image coded on 24 bits \end_layout \begin_layout Itemize Decode images coded on 8 or 16 bits (gray scale) and returned a 8 or 16 bits grey scale image \end_layout \begin_layout Itemize Decode color images transmitted using a compressed format (JPEG) and returns a 32 bits RGB image \end_layout \begin_layout Standard The following code snippets are examples of how these methods have to be used in a server and in a client. On the server side, creates an instance of the EncodedAttribute \begin_inset Index idx status collapsed \begin_layout Plain Layout EncodedAttribute \end_layout \end_inset class within your object \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 class MyDevice::Tango::Device_4Impl \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 ... \end_layout \begin_layout LyX-Code 4 Tango::EncodedAttribute jpeg; \end_layout \begin_layout LyX-Code 5 ... \end_layout \begin_layout LyX-Code 6 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard In the code of your device, use an encoding method of the EncodedAttribute class \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 void MyDevice::read_Encoded_attr_image(Tango::Attribute &att) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 .... \end_layout \begin_layout LyX-Code 4 jpeg.encode_jpeg_gray8(imageData,256,256,50.0); \end_layout \begin_layout LyX-Code 5 att.set_value(&jpeg); \end_layout \begin_layout LyX-Code 6 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 4: Image encoding. The size of the image is 256 by 256. Each pixel is coded using 8 bits. The encoding quality is defined to 50 in a scale of 0 - 100. imageData is the pointer to the image data (pointer to unsigned char) \end_layout \begin_layout Standard Line 5: Set the value of the attribute using a \emph on Attribute::set_value() \emph default method. \end_layout \begin_layout Standard On the client side, the code is the following (without exception management) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 .... \end_layout \begin_layout LyX-Code \align block 2 DeviceAttribute da; \end_layout \begin_layout LyX-Code \align block 3 EncodedAttribute att; \end_layout \begin_layout LyX-Code \align block 4 int width,height; \end_layout \begin_layout LyX-Code \align block 5 unsigned char *gray8; \end_layout \begin_layout LyX-Code 6 \end_layout \begin_layout LyX-Code 7 da = device.read_attribute("Encoded_attr_image"); \end_layout \begin_layout LyX-Code 8 att.decode_gray8(&da,&width,&height,&gray8); \end_layout \begin_layout LyX-Code 9 .... \end_layout \begin_layout LyX-Code 10 delete [] gray8; \end_layout \begin_layout LyX-Code 11 ... \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The attribute named Encoded_attr_image is read at line7. The image is decoded at line 8 in a 8 bits gray scale format. The image data are stored in the buffer pointed to by "gray8". The memory allocated by the image decoding at line 8 is returned to the system at line 10. \end_layout \begin_layout Section Device server with user defined event loop \end_layout \begin_layout Standard Sometimes, it could be usefull to write your own process event handling loop \begin_inset Index idx status collapsed \begin_layout Plain Layout event-loop \end_layout \end_inset . For instance, this feature can be used in a device server process where the ORB is only one of several components that must perform event handling. A device server with a graphical user interface must allow the GUI to handle windowing events in addition to allowing the ORB to handle incoming requests. These types of device server therefore perform non-blocking event handling. They turn the main thread of control over each of the vvarious event-handling sub-systems while not allowing any of them to block for significants period of time. The \emph on Tango::Util \emph default class has a method called \emph on server_set_event_loop() \begin_inset Index idx status collapsed \begin_layout Plain Layout server-set-event-loop \end_layout \end_inset \emph default to deal with such a case. This method has only one argument which is a function pointer. This function does not receive any argument and returns a boolean. If this boolean is true, the device server process exits. The device server core will call this function in a loop without any sleeping time between the call. It is the user responsability to implement in this function some kind of sleeping mechanism in order not to make this loop too CPU consuming. The code of this function is executed by the device server main thread \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset . The following piece of code is an example of how you can use this feature. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \align block 1 \end_layout \begin_layout LyX-Code 2 bool my_event_loop() \end_layout \begin_layout LyX-Code 3 { \end_layout \begin_layout LyX-Code 4 bool ret; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 some_sleeping_time(); \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 ret = handle_gui_events(); \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 return ret; \end_layout \begin_layout LyX-Code 11 } \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 int main(int argc,char *argv[]) \end_layout \begin_layout LyX-Code 14 { \end_layout \begin_layout LyX-Code 15 Tango::Util *tg; \end_layout \begin_layout LyX-Code 16 try \end_layout \begin_layout LyX-Code 17 { \end_layout \begin_layout LyX-Code 18 // Initialise the device server \end_layout \begin_layout LyX-Code 19 //---------------------------------------- \end_layout \begin_layout LyX-Code 20 tg = Tango::Util::init(argc,argv); \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 tg->set_polling_threads_pool_size(5); \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 // Create the device server singleton \end_layout \begin_layout LyX-Code 25 // which will create everything \end_layout \begin_layout LyX-Code 26 //---------------------------------------- \end_layout \begin_layout LyX-Code 27 tg->server_init(false); \end_layout \begin_layout LyX-Code 28 \end_layout \begin_layout LyX-Code 29 tg->server_set_event_loop(my_event_loop); \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 // Run the endless loop \end_layout \begin_layout LyX-Code 32 //---------------------------------------- \end_layout \begin_layout LyX-Code 33 cout << "Ready to accept request" << endl; \end_layout \begin_layout LyX-Code 34 tg->server_run(); \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout LyX-Code 36 catch (bad_alloc) \end_layout \begin_layout LyX-Code 37 { \end_layout \begin_layout LyX-Code 38 ... \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The device server main event loop is set at line 29 before the call to the Util::server_run() method. The function used as server loop is defined between lines 2 and 11. \end_layout \begin_layout Section Device server using file \begin_inset Index idx status collapsed \begin_layout Plain Layout file \end_layout \end_inset as database \begin_inset Index idx status collapsed \begin_layout Plain Layout database \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "sec:Device-server-file" \end_inset \end_layout \begin_layout Standard For device servers not able to access the Tango database (most of the time due to network route or security reason), it is possible to start them using file instead of a real database. This is done via the device server \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset -file= \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset command line option. In this case, \end_layout \begin_layout Itemize Getting, setting and deleting class properties \end_layout \begin_layout Itemize Getting, setting and deleting device properties \end_layout \begin_layout Itemize Getting, setting and deleting class attribute properties \end_layout \begin_layout Itemize Getting, setting and deleting device attribute properties \end_layout \begin_layout Standard are handled using the specified file instead of the Tango database. The file is an ASCII file and follows a well-defined syntax with predefined keywords. The simplest way to generate the file for a specific device server is to use the Jive application. See \begin_inset CommandInset citation LatexCommand cite key "Jive doc" \end_inset to get Jive documentation. The Tango database is not only used to store device configuration parameters, it is also used to store device network access parameter (the CORBA IOR). To allow an application to connect to a device hosted by a device server using file instead of database, you need to start it on a pre-defined port \begin_inset Index idx status collapsed \begin_layout Plain Layout port \end_layout \end_inset , and you must use one of the underlying ORB option called \emph on endPoint \emph default like \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset myserver myinstance_name -file=/tmp/MyServerFile -ORBendPoint giop:tcp:: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset to start your device server. The device name passed to the client application must also be modified in order to refect the non-database usage. See \begin_inset CommandInset ref LatexCommand ref reference "DeviceNaming" \end_inset to learn about Tango device name syntax. Nevertheless, using this Tango feature prevents some other features to be used : \end_layout \begin_layout Itemize No check that the same device server is running twice. \end_layout \begin_layout Itemize No device or attribute alias name. \end_layout \begin_layout Itemize In case of several device servers running on the same host, the user must manually manage a list of already used network port. \end_layout \begin_layout Section Device server without database \begin_inset CommandInset label LatexCommand label name "sec:Device-server-without" \end_inset \end_layout \begin_layout Standard In some very specific cases (Running a device server within a lab during hardware development...), it could be very useful to have a device server able to run even if there is no database \begin_inset Index idx status collapsed \begin_layout Plain Layout database \end_layout \end_inset in the control system. Obviously, running a Tango device server without a database means loosing Tango features. The lost features are : \end_layout \begin_layout Itemize No check that the same device server is running twice. \end_layout \begin_layout Itemize No device configuration via properties. \end_layout \begin_layout Itemize No event generated by the server. \end_layout \begin_layout Itemize No memorized attributes \end_layout \begin_layout Itemize No device attribute configuration via the database. \end_layout \begin_layout Itemize No check that the same device name is used twice within the same control system. \end_layout \begin_layout Itemize In case of several device servers running on the same host, the user must manually manage a list of already used network port. \end_layout \begin_layout Standard To run a device server without a database, the \series bold -nodb \begin_inset Index idx status collapsed \begin_layout Plain Layout nodb \end_layout \end_inset \series default command line option must be used. One problem when running a device server without the database is to pass device name(s) to the device server. Within Tango, it is possible to define these device names at two different levels : \end_layout \begin_layout Enumerate At the command line with the \series bold -dlist \begin_inset Index idx status collapsed \begin_layout Plain Layout dlist \end_layout \end_inset \series default option: In case of device server with several device pattern implementation, the device name list given at command line is only for the last device pattern created in the \emph on class_factory() \emph default method. In the device name list, the device name separator is the comma character. \end_layout \begin_layout Enumerate At the device pattern implementation level: In the class inherited from the Tango::DeviceClass class via the re-definition of a well defined method called \emph on device_name_factory() \end_layout \begin_layout Standard If none of these two possibilities is used, the tango core classes defined one default device name for each device pattern implementation. This default device name is \emph on NoName \emph default . Device definition at the command line has the highest priority. \end_layout \begin_layout Subsection Example of device server started without database usage \end_layout \begin_layout Standard Without database, you need to start a Tango device server on a pre-defined port \begin_inset Index idx status collapsed \begin_layout Plain Layout port \end_layout \end_inset , and you must use one of the underlying ORB option called \emph on endPoint \emph default like \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset myserver myinstance_name -ORBendPoint giop:tcp:: -nodb -dlist a/b/c \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard The following is two examples of starting a device server not using the database when the \emph on device_name_factory() \emph default method is not re-defined. \end_layout \begin_layout Itemize StepperMotor et -nodb -dlist id11/motor/1,id11/motor/2 \begin_inset Newline newline \end_inset This command line starts the device server with two devices named \emph on id11/motor/1 \emph default and \emph on id11/motor/2 \end_layout \begin_layout Itemize StepperMotor et -nodb \begin_inset Newline newline \end_inset This command line starts a device server with one device named \emph on NoName \end_layout \begin_layout Standard When the \emph on device_name_factory() \emph default method is re-defined within the StepperMotorClass class. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void StepperMotorClass::device_name_factory(vector &list) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 list.push_back("sr/cav-tuner/1"); \end_layout \begin_layout LyX-Code 4 list.push_back("sr/cav-tuner/2"); \end_layout \begin_layout LyX-Code 5 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Itemize StepperMotor et -nodb \begin_inset Newline newline \end_inset This commands starts a device server with two devices named \emph on sr/cav-tuner/1 \emph default and \emph on sr/cav-tuner/2 \emph default . \end_layout \begin_layout Itemize StepperMotor et -nodb -dlist id12/motor/1 \begin_inset Newline newline \end_inset Starts a device server with only one device named id12/motor/1 \end_layout \begin_layout Subsection Connecting client to device within a device server started without database \end_layout \begin_layout Standard In this case, the host and port on which the device server is running are part of the device name. If the device name is \emph on a/b/c \emph default , the host is \emph on mycomputer \emph default and the port \emph on 1234 \emph default , the device name to be used by client is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset mycomputer:1234/a/b/c#dbase=no \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard See appendix \begin_inset CommandInset ref LatexCommand ref reference "DeviceNaming" \end_inset for all details about Tango object naming. \end_layout \begin_layout Section Multiple database servers within a Tango control system \end_layout \begin_layout Standard Tango uses MySQL as database and allows access to this database via a specific Tango device server. It is possible for the same Tango control system to have several Tango database servers. The host name and port number of the database server is known via the TANGO_HOS T \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-HOST \end_layout \end_inset environment variable. If you want to start several database servers in order to prevent server crash, use the following TANGO_HOST syntax \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \begin_layout Plain Layout \end_layout \begin_layout Plain Layout \end_layout \end_inset TANGO_HOST=:,:,: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard All calls to the database server will automatically switch to a running servers in the given list if the one used dies. \end_layout \begin_layout Section The Tango controlled access system \begin_inset Index idx status collapsed \begin_layout Plain Layout controlled-access \end_layout \end_inset \end_layout \begin_layout Subsection User rights definition \end_layout \begin_layout Standard Within the Tango controlled system, you give rights to a user. User is the name of the user used to log-in the computer where the application trying to access a device is running. Two kind of users are defined: \end_layout \begin_layout Enumerate Users with defined rights \end_layout \begin_layout Enumerate Users without any rights defined in the controlled system. These users will have the rights associated with the pseudo-user called "All Users" \end_layout \begin_layout Standard The controlled system manages two kind of rights: \end_layout \begin_layout Itemize Write access meaning that all type of requests are allowed on the device \end_layout \begin_layout Itemize Read access meaning that only read-like access are allowed (write_attribute, write_read_attribute and set_attribute_config network calls are forbidden). Executing a command is also forbidden except for commands defined as " \series bold Allowed commands \series default ". Getting a device state or status using the command_inout call is always allowed. The definition of the allowed commands is done at the device class level. Therefore, all devices belonging to the same class will have the allowed commands set. \end_layout \begin_layout Standard The rights given to a user is the check result splitted in two levels: \end_layout \begin_layout Enumerate At the host level: You define from which hosts the user may have write access to the control system by specifying the host name. If the request comes from a host which is not defined, the right will be Read access. If nothing is defined at this level for the user, the rights of the "All Users" user will be used. It is also possible to specify the host by its IP address. You can define a host family using wide-card in the IP address (eg. 160.103.11.* meaning any host with IP address starting with 160.103.11). Only IP V4 is supported. \end_layout \begin_layout Enumerate At the device level: You define on which device(s) request are allowed using device name. Device family can be used using widecard in device name like domin/family/* \end_layout \begin_layout Standard Therefore, the controlled system is doing the following checks when a client try to access a device: \end_layout \begin_layout Itemize Get the user name \end_layout \begin_layout Itemize Get the host IP address \end_layout \begin_layout Itemize If rights defined at host level for this specific user and this IP address, gives user temporary write acccess to the control system \end_layout \begin_layout Itemize If nothing is specified for this specific user on this host, gives to the user a temporary access right equal to the host access rights of the "All User" user. \end_layout \begin_layout Itemize If the temporary right given to the user is write access to the control system \end_layout \begin_deeper \begin_layout Itemize If something defined at device level for this specific user \end_layout \begin_deeper \begin_layout Itemize If there is a right defined for the device to be accessed (or for the device family), give user the defined right \end_layout \begin_layout Itemize Else \end_layout \begin_deeper \begin_layout Itemize If rights defined for the "All Users" user for this device, give this right to the user \end_layout \begin_layout Itemize Else, give user the Read Access for this device \end_layout \end_deeper \end_deeper \begin_layout Itemize Else \end_layout \begin_deeper \begin_layout Itemize If there is a right defined for the device to be accessed (or for the device family) for the "All User" user, give user this right \end_layout \begin_layout Itemize Else, give user the Read Access right for this device \end_layout \end_deeper \end_deeper \begin_layout Itemize Else, access right will be Read Access \end_layout \begin_layout Standard Then, when the client tries to access the device, the following algorithm is used: \end_layout \begin_layout Itemize If right is Read Access \end_layout \begin_deeper \begin_layout Itemize If the call is a write type call, refuse the call \end_layout \begin_layout Itemize If the call is a command execution \end_layout \begin_deeper \begin_layout Itemize If the command is one of the command defined in the "Allowed commands" for the device class, send the call \end_layout \begin_layout Itemize Else, refuse the call \end_layout \end_deeper \end_deeper \begin_layout Standard All these checks are done during the DeviceProxy instance constructor except those related to the device class allowed commands which are checked during the command_inout call. \end_layout \begin_layout Standard To simplify the rights management, give the "All Users" user host access right to all hosts ("*.*.*.*") and read access to all devices ("*/*/*"). With such a set-up for this user, each new user without any rights defined in the controlled access will have only Read Access to all devices on the control system but from any hosts. Then, on request, gives Write Access to specific user on specific host (or family) and on specific device (or family). \end_layout \begin_layout Standard The rights managements are done using the Tango Astor \begin_inset CommandInset citation LatexCommand cite key "Astor_doc" \end_inset tool which has some graphical windows allowing to grant/revoke user rights and to define device class allowed commands set. The following window dump shows this Astor window. \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \begin_inset Graphics filename control.PNG \end_inset \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard \align block In this example, the user "taurel" has Write Access to the device "sr/d-ct/1" and to all devices belonging to the domain "fe" but only from the host "pcantares" He has read access to all other devices but always only from the host pcantares. The user "verdier" has write access to the device "sys/dev/01" from any host on the network "160.103.5" and Read Access to all the remaining devices from the same network. All the other users has only Read Access but from any host. \end_layout \begin_layout Subsection Running a Tango control system with the controlled access \end_layout \begin_layout Standard All the users rights are stored in two tables of the Tango database. A dedicated device server called \series bold TangoAccessControl \begin_inset Index idx status collapsed \begin_layout Plain Layout TangoAccessControl \end_layout \end_inset \series default access these tables without using the classical Tango database server. This TangoAccessControl device server must be configured with only one device. The property \series bold Services \begin_inset Index idx status collapsed \begin_layout Plain Layout Services \end_layout \end_inset \series default belonging to the free object \series bold CtrlSystem \begin_inset Index idx status collapsed \begin_layout Plain Layout CtrlSystem \end_layout \end_inset \series default is used to run a Tango control system with its controlled access. This property is an array of string with each string describing the service(s) running in the control system. For controlled access, the service name is "AccessControl". The service instance name has to be defined as "tango". The device name associated with this service must be the name of the TangoAcces sControl server device. For instance, if the TangoAccessControl device server device is named \emph on sys/access_control/1 \emph default , one element of the Services property of the CtrlSystem object has to be set to \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset AccessControl/tango:sys/access_control/1 \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard If the service is defined but without a valid device name corresponding to the TangoAccessControl device server, all users from any host will have write access (simulating a Tango control system without controlled access). Note that this device server connects to the MySQL database and therefore may need the MySQL connection related environment variables MYSQL_USER \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-USER \end_layout \end_inset and MYSQL_PASSWORD \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-PASSWORD \end_layout \end_inset described in \begin_inset CommandInset ref LatexCommand ref reference "sub:Db-Env-Variables" \end_inset \end_layout \begin_layout Standard Even if a controlled access system is running, it is possible to by-pass it if, in the environment of the client application, the environment variable SUPER_TANGO \begin_inset Index idx status collapsed \begin_layout Plain Layout SUPER-TANGO \end_layout \end_inset is defined to "true". If for one reason or another, the controlled access server is defined but not accessible, the device right checked at that time will be Read Access. \begin_inset VSpace 1cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset CommandInset label LatexCommand label name "FourRicardo" \end_inset \begin_inset Graphics filename ../dance/AT97-65-size.jpg scale 400 \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/advanced/alarm.eps0000644023471100065110000001477013034745264014655 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: alarm.eps %%Creator: fig2dev Version 3.2 Patchlevel 3d %%CreationDate: Sun Nov 21 14:13:04 2004 %%For: taurel@wow (E.Taurel,,,) %%BoundingBox: 0 0 728 155 %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 155 moveto 0 0 lineto 728 0 lineto 728 155 lineto closepath clip newpath -27.6 187.8 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0.06299 0.06299 sc % % Fig objects follow % % Polyline 7.500 slw gs clippath 3795 1965 m 3795 1905 l 3643 1905 l 3763 1935 l 3643 1965 l cp eoclip n 2070 1935 m 3780 1935 l gs col0 s gr gr % arrowhead n 3643 1965 m 3763 1935 l 3643 1905 l col0 s % Polyline gs clippath 5775 1965 m 5775 1905 l 5623 1905 l 5743 1935 l 5623 1965 l cp 3900 1905 m 3900 1965 l 4052 1965 l 3932 1935 l 4052 1905 l cp eoclip n 3915 1935 m 5760 1935 l gs col0 s gr gr % arrowhead n 4052 1905 m 3932 1935 l 4052 1965 l col0 s % arrowhead n 5623 1965 m 5743 1935 l 5623 1905 l col0 s % Polyline gs clippath 7845 1965 m 7845 1905 l 7693 1905 l 7813 1935 l 7693 1965 l cp 5835 1905 m 5835 1965 l 5987 1965 l 5867 1935 l 5987 1905 l cp eoclip n 5850 1935 m 7830 1935 l gs col0 s gr gr % arrowhead n 5987 1905 m 5867 1935 l 5987 1965 l col0 s % arrowhead n 7693 1965 m 7813 1935 l 7693 1905 l col0 s % Polyline gs clippath 9690 1965 m 9690 1905 l 9538 1905 l 9658 1935 l 9538 1965 l cp 7905 1905 m 7905 1965 l 8057 1965 l 7937 1935 l 8057 1905 l cp eoclip n 7920 1935 m 9675 1935 l gs col0 s gr gr % arrowhead n 8057 1905 m 7937 1935 l 8057 1965 l col0 s % arrowhead n 9538 1965 m 9658 1935 l 9538 1905 l col0 s % Polyline gs clippath 9750 1905 m 9750 1965 l 9902 1965 l 9782 1935 l 9902 1905 l cp eoclip n 9765 1935 m 11565 1935 l gs col0 s gr gr % arrowhead n 9902 1905 m 9782 1935 l 9902 1965 l col0 s % Polyline 30.000 slw gs clippath 11490 1260 m 11490 1080 l 11049 1080 l 11409 1170 l 11049 1260 l cp eoclip n 1980 1170 m 11475 1170 l gs col0 s gr gr % arrowhead n 11049 1260 m 11409 1170 l 11049 1080 l col0 s % Polyline n 3825 990 m 3825 1350 l gs col0 s gr % Polyline n 5805 990 m 5805 1350 l gs col0 s gr % Polyline n 9720 945 m 9720 1305 l gs col0 s gr % Polyline n 7875 990 m 7875 1350 l gs col0 s gr % Polyline 7.500 slw gs clippath 5730 2550 m 5730 2490 l 5578 2490 l 5698 2520 l 5578 2550 l cp eoclip n 1980 2520 m 5715 2520 l gs col0 s gr gr % arrowhead n 5578 2550 m 5698 2520 l 5578 2490 l col0 s % Polyline gs clippath 7845 2550 m 7845 2490 l 7693 2490 l 7813 2520 l 7693 2550 l cp 5835 2490 m 5835 2550 l 5987 2550 l 5867 2520 l 5987 2490 l cp eoclip n 5850 2520 m 7830 2520 l gs col0 s gr gr % arrowhead n 5987 2490 m 5867 2520 l 5987 2550 l col0 s % arrowhead n 7693 2550 m 7813 2520 l 7693 2490 l col0 s % Polyline gs clippath 7905 2490 m 7905 2550 l 8057 2550 l 7937 2520 l 8057 2490 l cp eoclip n 7920 2520 m 11565 2520 l gs col0 s gr gr % arrowhead n 8057 2490 m 7937 2520 l 8057 2550 l col0 s % Polyline n 450 540 m 11970 540 l 11970 2970 l 450 2970 l cp gs col0 s gr /Times-Roman ff 210.00 scf sf 1035 1035 m gs 1 -1 sc (Attribute) col0 sh gr /Times-Roman ff 210.00 scf sf 1035 1215 m gs 1 -1 sc ( value) col0 sh gr /Times-Roman ff 210.00 scf sf 630 1755 m gs 1 -1 sc (Attribute quality) col0 sh gr /Times-Roman ff 210.00 scf sf 900 1980 m gs 1 -1 sc ( factor) col0 sh gr /Times-Roman ff 210.00 scf sf 855 2565 m gs 1 -1 sc (Device state) col0 sh gr /Times-Roman ff 210.00 scf sf 2205 1755 m gs 1 -1 sc (ATTR_ALARM) col0 sh gr /Times-Roman ff 210.00 scf sf 4005 1755 m gs 1 -1 sc (ATTR_WARNING) col0 sh gr /Times-Roman ff 210.00 scf sf 6165 1755 m gs 1 -1 sc (ATTR_VALID) col0 sh gr /Times-Roman ff 210.00 scf sf 7965 1755 m gs 1 -1 sc (ATTR_WARNING) col0 sh gr /Times-Roman ff 210.00 scf sf 9900 1755 m gs 1 -1 sc (ATTR_ALARM) col0 sh gr /Times-Roman ff 210.00 scf sf 3465 2430 m gs 1 -1 sc (ALARM) col0 sh gr /Times-Roman ff 210.00 scf sf 6660 2430 m gs 1 -1 sc (ON) col0 sh gr /Times-Roman ff 210.00 scf sf 9405 2430 m gs 1 -1 sc (ALARM) col0 sh gr /Times-Roman ff 210.00 scf sf 3330 855 m gs 1 -1 sc (min_alarm) col0 sh gr /Times-Roman ff 210.00 scf sf 5265 855 m gs 1 -1 sc (min_warning) col0 sh gr /Times-Roman ff 210.00 scf sf 7335 855 m gs 1 -1 sc (max_warning) col0 sh gr /Times-Roman ff 210.00 scf sf 9225 855 m gs 1 -1 sc (max_alarm) col0 sh gr $F2psEnd rs tango-9.2.5a/doc/src/advanced/line.tex0000644023471100065110000000174013034745264014512 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/advanced/alarm.fig0000644023471100065110000000426013034745264014624 00000000000000#FIG 3.2 Portrait Center Metric A4 100.00 Single -2 1200 2 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 2070 1935 3780 1935 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 3915 1935 5760 1935 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 5850 1935 7830 1935 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 7920 1935 9675 1935 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 9765 1935 11565 1935 2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 3.00 180.00 360.00 1980 1170 11475 1170 2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2 3825 990 3825 1350 2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2 5805 990 5805 1350 2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2 9720 945 9720 1305 2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 0 0 2 7875 990 7875 1350 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 1980 2520 5715 2520 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2 0 0 1.00 60.00 120.00 0 0 1.00 60.00 120.00 5850 2520 7830 2520 2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 1 2 0 0 1.00 60.00 120.00 7920 2520 11565 2520 2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 450 540 11970 540 11970 2970 450 2970 450 540 4 0 0 50 0 0 14 0.0000 4 150 765 1035 1035 Attribute\001 4 0 0 50 0 0 14 0.0000 4 150 570 1035 1215 value\001 4 0 0 50 0 0 14 0.0000 4 195 1410 630 1755 Attribute quality\001 4 0 0 50 0 0 14 0.0000 4 150 795 900 1980 factor\001 4 0 0 50 0 0 14 0.0000 4 150 1020 855 2565 Device state\001 4 0 0 50 0 0 14 0.0000 4 180 1410 2205 1755 ATTR_ALARM\001 4 0 0 50 0 0 14 0.0000 4 180 1665 4005 1755 ATTR_WARNING\001 4 0 0 50 0 0 14 0.0000 4 180 1320 6165 1755 ATTR_VALID\001 4 0 0 50 0 0 14 0.0000 4 180 1665 7965 1755 ATTR_WARNING\001 4 0 0 50 0 0 14 0.0000 4 180 1410 9900 1755 ATTR_ALARM\001 4 0 0 50 0 0 14 0.0000 4 150 750 3465 2430 ALARM\001 4 0 0 50 0 0 14 0.0000 4 150 300 6660 2430 ON\001 4 0 0 50 0 0 14 0.0000 4 150 750 9405 2430 ALARM\001 4 0 0 50 0 0 14 0.0000 4 180 915 3330 855 min_alarm\001 4 0 0 50 0 0 14 0.0000 4 195 1125 5265 855 min_warning\001 4 0 0 50 0 0 14 0.0000 4 195 1155 7335 855 max_warning\001 4 0 0 50 0 0 14 0.0000 4 180 945 9225 855 max_alarm\001 tango-9.2.5a/doc/src/advanced/jive_sophis.jpg0000644023471100065110000017455013034745264016077 00000000000000ÿØÿàJFIF``ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ£"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?è4 NƒF´¹¹±¶¼¼»'’[˜–P¡ÀuUV Lç5aÓAÛFÓ|µŒƒIB¸Æs¸GŒc½[Òÿ䤨:×ÿD¥q:¥ú]i-Ãl’Þ×l! ä„*7tÈÁã ãšÚO•+#(®fÎÀ[è•_DÓâÜÁA—HD\“€2Ñ’HÔ‘W×DÒÏüÁtŸüÃÿÄ×›xadŽÚU’f¾¥`9R0<ï§jõÛåÙ¤^:1WX«)ÁiäTº‰EÉ­‡ÉªI™¿ØZgýt¯üÃÿÄÒÿaiŸôÒ¿ð_ÿTtÝqm>Íç[Í"ºÙEss%Ó0S,gkl<Ÿjœc;²zTcÎ-´¾DBòŠ’5°´Ïúé_ø/‡ÿ‰¤:™ÿ@m+ÿðÿñ4¾,Ö­´« kso§\ê åÅ=Ô‹…q—˜ã*:ìTtÉxfKm_áÆŸ5Æ­#'ÙWí7‰u‡p_t™Êž' Žyš\Ë_"Ô^„ŸØzoý´¯üÃÿÄÑý‰¦ÿÐJÿÁ|?üMs÷Z²éZCÙ>¬Ú|z¥Ä‡O¸ÔnO›ªªïrÒÛ‹g`$°Þ¹£Á—ê^ ÑnȺw³‹Í—ÌÞK…²½»9ïœÓM4ß§ãþBqk©[ûMÿ 6•ÿ‚øøšOìM7þ€ÚWþ áÿâkZÔâÑ%Õµk»Û¨ííõ›h¤ÄÒ2¬>TlT 8,sÎy­K­y¬§Y®ôÇK¹-Å^–R^UHÑ€Ë–Ç ”¤ž–þ­p”Zvþ·±7ö.ÿ@m+ÿðÿñ4ŸØºwýô¯üÃÿÄÖpÔ/S]¾MZÐÄV{ã†ÚýÌ`»°Þ*’:eJŒíÁÈÁ¤Ò¼Awa§E>§d_O{«˜…ßÚwÊ ¼„f2¿w †'§ÊAÊ)]ÿ[˜¬Û²4N‹§ÿÐJÿÁ|?üM'ö6Ÿÿ@}+ÿðÿñ5øž{ãUÑÖçµk›aЕÛnß‘ÁU ÇpèYzóÀͨuMH]µÖ ßmŽTK{Ï1"á]·2) ½vãž0}2½º…¼ÊÿØöôÒ¿ð_ÿHt{úé_ø/‡ÿˆªÅî{ã £¾¹¹6Ú\WVé6Ò°±óøUP>Uë’qÉ5^îÞ]7X‹DƒR¾k[Ñje’K§ys8b®IeÞÇ%phm&•·ýFâÒnûÀÿ3Wû"ÇþWþ áÿâ)?²lè¥à¾þ"²m!–ûÄ’ønkËñak%Ë$©w"ÊûVªe1 ç¸äœíÎ*ŒwW·Þ¿Õ忺ûV—e °¥1¤¬yfUá÷ã €:`ÑÌ´Óqr¾çIý•§÷Ñô¯üÃÿÄTo§iÃþ`úOþ  ÿâ*}/.ï\ˆË3¤wøA,­&Àa‰ˆ‰ e‰ÇAž*{€5¢K±2ºêf-8ÌIÿÁtüE4ÙéßôÒð]ÿS9æ˜M_*ìgÌû‘M?þOþ  ÿâ)>Ëaÿ@'ÿÐñ!¤§Ê»3îDm¬?è¤ÿàºþ"“ìÖ?ô Òð]ÿRJ|±ì.gÜìÖ?ô Òð]ÿGÙ¬è¤ÿàºþ"¤¢ŽXögÜgÙ¬è¤ÿàºþ"³XÿÐ'IÿÁtüE>Š9cØ9ŸqŸg±ÿ N“ÿ‚è?øŠCoeÛIÒð]ÿRRQËÁÌû•žAÓJÒð[ÿQìµÿ ^“ÿ‚Ø?øŠ¶éš®éŠ9cØ9Ÿq»-è¤ÿà¶þ".×þzOþ `ÿâ(¥£–=ƒ™÷.ÓþzOþ `ÿâ)|»Oúi?ø-ƒÿˆ¤¥£–=ƒ™÷*ÓþZOþ `ÿâ(ò­?è¤ÿà¶þ"–—rǰs>ã|«?úi?ø-ƒÿˆ¥ò¬ÿè¤ÿà¶þ"–Š9cØ9Ÿq<›?úi?ø-ƒÿˆ¥ò¬ÿè¤ÿà¶þ"––ŽXögÜO*ÏþZOþ `ÿâ(òlÿè¤ÿà¶þ"––ŽXögÜO&ÏþZOþ  ÿâ)<›?úi?ø-ƒÿˆ§âŒQËÁÍ.ã|›?úi?ø.ƒÿˆ£È²ÿ V“ÿ‚è?øŠurǰs>ã|›/úi?ø.ƒÿˆ£È²ÿ V“ÿ‚è?øŠ}ù#Ø9Ÿq¾E—ý´ŸüAÿÄQäYÿÐ+IÿÁtüE:Š\±ìϸß"ËþZOþ  ÿâ(ò,¿è¤ÿàºþ"E±ìϸß"ËþZOþ  ÿâ(ò,ÿè¤ÿàºþ"ŸE±ìϸÏ"ÏþZOþ  ÿâ(ò,ÿè¤ÿàºþ"ŸŠJ9#Ø9ŸqžMŸý´ŸüAÿÄRy6ô Òð]ÿRb“rG°s>ã<«?úi?ø.ƒÿˆ¥YwÒ´ŸüAÿÄPxF{Ác52å] 3êi¤þa:Oþ  ÿâ*O²éøÏöF“ÿ‚è?øŠ¡kqæsVÞm±š‰J \¨ÆmØ¡¨5”9Û¥iþá°ý’±ÍݾxÒôüÛÿñíN}Îy¬èþf¯:Sæw=(SIX×·–ÙÈÝ¥èøÿ°e¿ÿ[é§2ŒéIÿ¸lüEaC1[606kÉ÷4åK¡a °Ï>“ÿ‚è?øŠ±¦œß{GÒð]ÿCª¢sP¥ÈSY©Ë¸¹S[ÅŽ•ÿ@m'ÿðÿñ4ïìí,ÿÌIÿÁ|?üMRK°ÏŠÓ„åi¹K¹) ;Itm'ÿðÿñ4¿ÙºKtÑ´ŸüÃÿÄÔWr”éIi+1æ«Þµî+!ï¦ékÿ0m'ÿðÿñ5Ø´¯úéø/‡ÿ‰«S·¨Q ɦ›¶å$†géGþ`ºGþ  ÿâ)ë§içEÒ?ð]ÿH[ ŠPNáNìvD§IÒHãEÒ?ð_ÿP\iI…3£iCý&Øel"^ ñ‚8^„?¿ùjµüÃìR`¶[v'=ž2Oä)Á»‘+XÕþÂðéÿ˜‘ÿ€ÿñ4áxtÌ GÿÀøšç³t—„ºžsçC¥†Ö2ÿÓÔt«ŸiÓè«ÿà{ÿñúÝ/37¡rÿDðúé·Œº’¬°HA[)äµ-þ‘ [)ò|;£I#L¢5”J7;„;Xv5Í0¾]UžY ‚ÑÃ峓åœÕËßµ‹ã ó$X®Ò_,7P²ÀÉÇAIEá§iïìŸÙûNÿ/Éóâß¿8Û·ÈÎsÆ*펑 ÜÅ™|=£G"Ë$.‹g ÈåÁ‘•ô‡¾/µùÞF·³í?iòw[ìÝæy˜ëœn÷©¬…Ñ™œù‘ .d—anT4…€88Î T¬–„«õ*ZÛhëcj¤±ûÆUxdgqÉëÅtWÑ[êvmiv$hï"Lñî‡i¸<õ¡ÿΣÿA-?ÿ$ÿãô¿ðŒê?ôÓÿðOþ?I8!Úf]݆™}o}ͪÉôk :¨À1ž£Ë3N¹š ŠO F!Fµº–°rùl»€ìq“êk_þ­Gþ‚ZþIÿÇèÿ„gQÿ –Ÿÿ€2ñú9¡¸rËa¿o8ëX“h:,ö)dö® HcU.$BrÁá¹Îs[¿ðŒê?ôÓÿðOþ?Gü#:ý´ÿü“ÿÑx§±FÉ ÓížÞ.¤G$Ÿ´ÝË;r1ÃHÌ@öû9!Ó¬mì­WË··b‰7µT` žO½[ÿ„gQÿ –Ÿÿ€2ñúOøF5ÿ1-?ÿdÿãôùâ²0c±_í鮥Ž{{‹¨îã‹Ë*ÑȨ©’Û°ÃäúÒchÂÕ­Mžè F+¨X6ÕÉù@ ŒmÀÆ1[ßð‹jôÓÿðOþ?Iÿ­ÿý¬?ðOþ?Kš×ÝùŒž¬Á¶Ñô‹F‘â·É,±Í$’ÜI#»ÆrŒÌÌI#Üôt›k¤höwi†Ý÷yâG]ó¹–6bªÇsry>¦ºøEoÿè%aÿ€2ñúOøE/¿è%aÿ€2ñú|Ð,ŽzßFÑmRHÒÐÉ›.yžTHTEv!àp  ¢/J‚7A Òohؼ÷RÊÿ»mÈ7; ¹Ç^95ÐÿÂ%}ÿAü“ÿÒÂ#{ÿAü“ÿÐ¥>Yœúiúlz•Æ¡¶åî.¤ÞeäÎŽ¼ü¥Ší›8ÅG“£Ãe5¢ÛÈÑͳsIq#È6¦×f,¡O+‚0y®þ ßúØàŸü~“þûÏúØàŸü~Žh –g9.™¤Ég ©†UHäWŽæT—sçq2Û³ÎIÏz&°Ò&š ZÐ)4HädŒª¢²) ÁO 08í]ü!·ô°ÿÀ)?øý'ü!—ô±ÿÀ)?øý>x,ÎrÅæ³—P–k”™ï.|ÿ’2FÅ@9c“„þ‚%ÙsÖºøB®¿è#cÿ€RñúOøBnè!cÿ€Rñúj¤œ&Îp>ê+¤ º5 ü“ÿÓ¿á»ÿ …‡þIÿÇê½´IöR9ŠJê?á »ÿ …‡þIÿÇé?á »ÿ …‡þIÿÇèöÑe#—¤®§þÛ¿úXàŸü~øCnÿè!aÿ€Rñú~Ú"öR9j\WQÿm×ý,?ð Oþ?Kÿmßý,?ð Oþ?G·ˆý”Ž[bºŸøCnÿè!aÿ€Rñú?á »ÿ …‡þIÿÇèöѲ‘ËbŠêá »ÿ …‡þIÿÇèÿ„6ïþ‚ø'ÿ¥í¢?e#–¨Ý3]gü!·_ô°ÿÀ)?øýð†ÝÐBÃÿ¤ÿãôý´CÙHâÙph®Èø&àõ¿±ÿÀ)?øý'ü óÿÏýþIÿÇèöÑe#Ž¥®ÃþyÿçþÇÿ¤ÿãôÂqÿ?ö?ø'ÿ£ÛÄ=”Ž>–ºÿøB.?è!cÿ€Rñú_øBn?çþÇÿ¤ÿãô{h‡²‘ÈR×]ÿMÇüÿØÿàŸü~øBn?è!cÿ€Rñú^Ú!ì¤r"–ºßøBn?è!cÿ€Rñú?á ¹ÿ …þIÿÇéûh‡²‘ÉQ]oü!W?ô±ÿÀ)?øý/ü!W?ô±ÿÀ)?øý/möR9*Zë?á ¹ÿ …þIÿÇèÿ„.çþìð Oþ?OÛÄ^ÊG'Š1]gü!w?óÿcÿ€Rñú?á ¹ÿ …þIÿÇèöñe#“Å-uð…ÜÿÐBÇÿ¤ÿãôÂsÿA ü“ÿÑíàÊG)Euð…ÜÿÐBÇÿ¤ÿãôÂsÿA ü“ÿÑíàÊG)KŠêÿá ¹ÿ …þIÿÇèÿ„.çþ‚?ø'ÿ£ÛÄ~ÊG)Š1]_ü!w?ô±ÿÀ)?øýð†\ÿÐBÇÿ¤ÿãô{x‡²‘Êb’ºÏøC.çþÇÿ¤ÿãôÂsÿ?ö?ø'ÿ£Û@=”ŽNšÌS]ið]Éÿ˜…þIÿÇêðËõÔ¬ð _þ?R뮃TŸSžtyæ°æÌ²ð{×¢7Ù›®¥cÿ€RÿñúááÏö…þKÿÇëš´ç=Žš1„78Û1å¨É§^]*Ç€kµ?çÆ£b?íÊ_þ?P?Ãi$?6¥bíÊ_þ?\®%¹º•4ô<¶yI;Ôö°‚EzJü2*söûü—ÿÔËðîE_Øà¿ü~©ÂV²)UÆÚª…­(O¥t‹à)צ¡aÿ€Rÿñú|t½5 ü“ÿÖ.„Æë@æeRËTÚ vŸð‡^ÐFÃÿdÿãôÓà˳ÿ1 ü“ÿШM U‰ÇA f¶bm©[+àÛµé¨iÿø'ÿ©?á¾ó°ÿÀ?øý7Fl—R,çeÌnjXb Ò·á¾ÿ ‡þÉÿÇéG…oÇüÄtÿü“ÿÓT¦.x˜3|evVÓøNùúê:þÉÿÇé?á¿RÓÿðOþ?OÙL9âs2°i‚l7ZèÛÁwÌsý§§à¿ü‘M¾?ÚzwþKÿÉj›hŒƒt€IJÖ–àu»ÿÁ…Ïÿ­‘áIæ%§àŸü~ƒáHÿÌKNÿÀ ?øýG$Ú=%¥´ŠÈërÈà ­rA‡÷”ã GœÝ“ÿa Ÿþ9[ŸðŠê9ÿ–ÿ€ñúpð¾ ?æ#§àŸü~«–aÍ `„ž~Õÿ÷?ür¦[{sÔÝÿàÂãÿŽV¹ð¾¢æ%§àŸü~á}HÌKNÿÀ ?øý³h‘èzb¢¢Gv¨ *¨Ôn@pgJyѬE»ÿÁÏÿ­±áÍLÌKNÿÀ ?øý/ü#ºŸý´ÿü“ÿÔ{9Úù˜GH²îÝÿàÆçÿŽUy4Û1Ñ.¿ðasÿÇ+¥>ÔüÄ´ÿü“ÿÔgÉ<êZwþIÿÇèör«ÝœÈÓ- æ;Ÿü\ÿñÊ­"X(£Xã\íEè3ÉüIä“É<šßÿ„_Pÿ Žÿ€ñúÉ•$‚âêÚf‰ä¶ŸÊ/WýÜo¥˜õ˜êzSq”uu- ¯‡c „ÓÝçþ•KE/Ãßùâÿ¯ËÏý*–ŠêŸÄÎ*?¢9‡üPÑØ ôš»_j7w…µKËI<»ˆ-ã|µ€ààðkˆÅ ÿ¨ÿé5v¤Z¶—u§Îî±\ÆÑ¹BF8È4êÝÇB©hõ1¿qme¤¸¿Ôî^òàÆÍs@TùLØÚaRË‘ÛïcŠÎµø”lôK½ò..–Æ;«§šá`gÜzD›pí€N>QÓžk¤½Ñío—OYd˜ ßÖ…9ãО˜¬ø<%gi g¨Zùvëm#C*«Mœ€ÇnA<®ÓÏZž¯×ôÿ2–ËÓõÿ#­Šé'…%²Ž¡”úƒÈ¬/j×z_†fº²à˜K‰° "ƒ€AàžÆ´„˜xõ9ª:禽ŒòË3#À«È#¨©=ôó)ÿÂA%…½¤Vò_jwW×FF£Ù áwq »NIü°m¼i¬&ò-é´¿œ¬¥<Å&`©’@ô s×#~ãCû\Pý§V¾–âÞa4$B²DpA… ‚sj¬Ó ·Š5Û¤V÷ã|€’³¾N:úçIÿ_wùtù~ät:õÕÞƒasz\K;ìl‚HÎz½qŽ:U»óÛ¼QÜËnì8– ¥—é¸ùƒYºu¸Ó´è,Åij¬(^]»ŠŽ€íp8éÚ­y¾õR³nÄÆéjršWˆoì´+­VÿPºÔe²YAlË jÍæìNUÔ“Ž¼t«íãIVàé§NOív¶ßgûAòŽS~ÿ3fvíÉû¹ÏïKÿÝÑçÓ Îb–á®D›Àxä/¼28ÁéÁ÷ÍF|/fÊd7Woû@¹ûväó··û»1·åÆÜc¶y¤¶Wòý?àÓÏõÿ€Tÿ„ÚêmZÜÇ¢8­¯>ÕcÍ4%F±“Ôã¦sÈ­ x¯þ(åo*ÕB"86׫8à ᆑ† ¯Ðš§…tëya•&»GÈdY¶³™H.å€6GQŒzU­3F‹M¼šñ¯.®î¦"i® îØ¹ÀùUAêy ŸzÚÿ[ÿÀåýmÿè¼Ú㬵«ËkVójWëœÛ`·ŠÕL%| Ä4žQÁÉ=Xv®“Í÷¬û]2ÞÒãQš9%-¨H$”1h_—Aß4õ·a«lž8ÖÆ›=ݬ‡öu¤Ê·% F’FFlªÇ§¾;럈pYêÆÊxm”CÿÈŸý~^éT´QðûþDø¿ëòóÿJ¥¢·©ñ3žð£èŽZÿ_ö_ý&®žÎ-NîÊÞçí¶ÉæÆ²mû&q‘œgus0ø·ñØ ôšº]7ý.ÊÎÍø†;($uÿž›Oû?)ÈïœtÈ.[!Çr´]Vø:ödÒ¥e>àƒ‚=Åh»ÿŸÆÿÁ<Õ±q-®Ÿsq »\KLé œ >µ…¥ø‚Y$™îµ 2îÖs4òZ)íHê²#;7#=H"¢è»2_´]ÿÏãàžj>Ñwÿ?ÿ‚y©çÅ0%œ³Ma} ¨Ñnêžc‰[j0Âr:ä`ä —þ;5µIçŽh ’HäŽ@»¡1©f-‚F^ ž£Ö†ì+ý¢ïþÿóQö‹¿ùüoüÍO>),åšk èeFˆ wTóJÛQ†Œ‘×# VÔ.ÒBŽñÿÍ&?Ýë‘ßéd×/¥ÓtûèU[xT R@$gâ†ì 7¡ö‹¿ùüoüÍGÚ.ÿçñ¿ðO5KÞ©cyg£5ÄnbW··xŒo´°È.ù)ãsÃ"ñ]œƒ{[]Ç ðÊê»fxC"á‰Ú )9àƒŠ¥Æý¢ïþÿóQö‹¿ùüoüÍRËâ;XµY­ävŽhe’i<¯îÄdÁ³À|ciÉÏ#©ñH7K¥j1Nò$pۺǾbÀ‘´‡ÙÐ19`F9Ç/Ô,Cö‹¿ùüoüÍNŽ[¹&Ž!~ªòÌÒä@N ÆXÐʵl/£Ôl’æ%t J²H0ÈÀÊ}Á~¦®óiëž[’7íɺ“8÷ÇOäzS”Ïy ¦3²ýï+My÷Á*N0qî=iŸh»ÿŸÆÿÁ<Õ» )B8× =òOrIîIäžõ„·úåôSÞéÉeöhåtŠÚdo2pŒTŸ3p ’2­Ø“θX>Ñwÿ?ÿ‚y¨ûEßüþ7þ æ©a×. ê*Ö3NÖ÷ko6Ê bG;‰`£$Àqø–# …ìóÍæÿ£F#'”Û_;œ)Ã8'9ã"‹…ˆ¾Ñwÿ?ÿ‚y¨ûEßüþ7þ æ«wìp]$ØÞÜ1‰&“ÊŒfb@,¬C‚F:t­Z.%¿ÛnÒ=B èe“Nt89Áù˜zÊ¢ûEÑåoƒ¯fM*VSî8#ÜU×·ûN·pŽß¹û4;ãÇßù¤À'û½r;ý2‹ºÇ;ª ’OaCiW0~Ñwÿ?ÿ‚y¨ûEßüþ7þ æ¨#ñ-Óé¦v†4œÝÛ¨FSþ¦gP¬F~öÖ#Órž;Uص×{1,V7w®ÓMÛx•6ˆÜ©$»íñdõr{ˆ~Ñwÿ?ÿ‚y¨ûEßüþ7þ 橉mÜÛý–Îòíe‚;†hO•’™K= ñÓ¦v©…ŒK¶Ý;¤z„AÐË&œèpsƒó0ô?•F&¼#)x]OGH••‡¨ àqÅX¹ŒÉ«\†`aû2 ;q€xÀç':wí£7ˆc·Uil/yÓŒ!6ñä€ïót8' “€xªä‰<ì½æßÏÌ¿ø%š6ûþ~eÿÁ,ÕEüElš„¶¿fºd†Xâ–áULhÎNs’à8ð9©]·’ù­„ˆ÷¼IpBùo" ²s‘†êùO4r@9Ùk;ÿŸ™ðK5m÷üüËÿ‚Y«þ¢×2%…ÇØn,äºg`”+(ý0rx=Wß¶÷IrfجRËaˆ8öçPhTâÁÍ …¯fœ@/•$*\ tÉ#ÈÄg¨üêÏØµ?ú[àÿgQ[ÿÈvúö›ÿB޶+:‰EÙur„WÂMÓ^Âñ’©m´ŸÄ±ÇåM¾-§™m:—3$AŠ«(&@‡¦3Œžý«M~ëý?¨¬½A·Á»vÿô˜r·ÉÄãåqät'ŒþŠìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«qKq7Î"„G½—&S» ÅIÆÜvõ®#C¿º‡I×uWP–âÕï)î.ÙíÛc6ÔùœcÝ84¯þc±Ö}‹Sÿ …·þÿöt}‹Sÿ …·þÿöuÌÏâjôØì­w}hoCa<Ê‹µqÄbĒ߀jeϵfq®•,w1YÇs5£ÙÍ,ŽìNcîñ´üÌr8â›Óúþ» ký]ΧìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³ª:ö³}ftXì“Q¹·Ú‘– ÎŒtϵdÛx§Y¾½Ó´èE„7Ü]ÛÜLñ;¦aÆ8àç¡'ëÅl×õ÷'ص?ú[àÿgGص?ú[àÿg\ô^-Ô ·½x­M…Õì–QF¨ÂUeܱÜA¡ÊÀ#“TañÞ©k¥Yj:½œÑÞØMuvÁ£GŽ ,Ù>ƒ9¥}/ýmÈvÖß×c¯û§ÿA oüÿìèû§ÿA oüÿìë–›ÆÕ¶¨Ü=š<°$Ä–3ÛÂåÜ+!W9%sÔr8â£×u=vÃUÔ£žþÞXí´W¹ò¢†HU›yI¸9éœc9¡»~?‚¸%ëúîu¿bÔÿè!mÿ€ýbÔÿè!mÿ€ýs)ãJMA¢µ±y ·šybŽÒi]Ã(,âQ•]»‡ÊÙ$ÈÍ\µñ©ÿ 0°Ô!‚Ò.d†å¶•ZE ¹]&ÉÊü¤7Öß×õ¨º\Úû§ÿA oüÿìèû§ÿA oüÿìë–ñ.¥ya¯ê÷0Oq›-OBV¬…ÙKÎÖÀõ¥i^ØO¤ør÷S±ÕoMÊX;“q3O0]Û±ùO\mÀçqŠ\Ú_úëþCåÖß×Oó5þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ç4ýc[–{7í6…FìÓ´.drN0>~1óóÎ9ÀÏ/¬\ø;ú†ýJîÑm˜ß-Ó%É%~YÈ/·Ÿ—<äpi½/ýwÿ!-mývÿ3³û§ÿA oüÿìèû§ÿA oüÿìë›ÜA=­•”‘]­äv§Ožu!¥Vm²³ôÉžëÒ§‹Äz¿ü$-§ÝÇod²O,é=¬Ùpr:Ê GÏuùOlæ†ÿ¯@7~Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ât¿ë)¢éP´©q{y ÷&se,ü+à&ÈÎrIûÜ01V®üe®º’;kO²éI$p¹1$4yqӃÞíýzÿ“¿¯ëÔë>Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ä5­kR¹Ñuë{™D7vq^ÛÍbòBWxo•°ß61ô>‚»ˆZèÁDE9yXÇ”ÿ:5š_Öåo±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þΰf‰£¿ÔÕœ;‹µÜÁv‚~Íxí]H–ág…%޲1\¤¬Ä¥ºÝ®j鱬jÀÿÏÚÿé4MQpÑšß¿äO‹þ¿/?ôªZ(ø}ÿ"|_õùyÿ¥RÑ[Tø™…áGÑÄ#þ-ì_ö_ý&®“Bÿ–_öµÿÚ•ÎÁÏøý@—ÿI©4ÝNÎÓL·k¤ºyš<éÐmáWýbŽ0p­9nµìÎÞêµZK›,>bó"m®™îb+ô ›÷c¬^Ãp>Í%²ýšØÂvÈbÄ»dð1ŒcÆ2¿á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǪ9#ßúûÊç}‹vž[kV‹Ì±ÌÖòn³ÓÖDN $œuÎ`9ÍÉü5Χ¨]M;˜o-šXwÔª öÛïYðiÜ»ÿÁƒÿñê?á Òÿ¹wÿƒÿãÔ8Eõþ¾ðRk¡nÓÁëmjÑy–1¹šÞMÖzzÀ‰Ãò$“޹Àì9ê+Œÿ„ƒKþåßþ ÿQÿ —ýË¿ü?ÿ§Ê»‡3ìtÑÈnëþ½¡ÿÐ¥¥Õ¬?µ4{Ë7ÊûL-ý»¶äc8ÈÍrÃ]ÒC—]o ßo|3þ»ÜþtïøH4¿î]ÿàÁÿøõ'¾¿×Þ mt6áÒ¯¥¼¶ŸT¾·¸[RZííŒ#yw6]ó€HÇS׌gé¾ µ°[ˆˆ²0IÛ§“b‘ÊQ»É&IvÆFÜõ ž•?á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨäëï&ºxI>Í77²Mþ‰=¼òÚҴ̬Ϝðr§ŽzûRÞøvóT²Xµ+ûK©"‘$…^ÀAPAßrXÇø€Žs¿á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨäëïgØé´9t­6+Eò~L“äÀ°¦IÉÂ/sî}I<Ñ}ÿzoý|Ÿý%s?ðiÜ»ÿÁƒÿñêkkºK-Ñ*r¤ß¿Èý÷¡?>X÷þ¾ñs>ÇkXO¢j‹‹{X[Y\HÒ2ù¦Œ±ËˆäÜä’FUˆ$û“ÿ —ýË¿ü?ÿ£þ /û—ø0þ=K’=ÿ¯¼|ϱ¥wá—.–;ÄÄ÷kpc¸„ËDzEÜ —wQÎ:âªÿÂ"èðéËq§I I+ùWh’ ]‹‹¼+’Ìx=*¿ü$_÷.ÿð`ÿüzøH4¿î]ÿàÁÿøõ‘ïý}áÎûõ =òZÂo!x`‰"W¹µÏ^9r 9Àä†äŠé¸ÏøH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê|«¿õ÷‡3ìtÑÈnëþ½¡ÿÐ¥©5 O·ØMhdس Ž@ÎTŸ˜~##=³\˜×tåÄW[È·Ûß$ à®÷?;þ /û—ø0þ=IÂ=ÿ¯¼ŸcFãÂBâ7ÓRßO‹tM4P[€%1È®§‚0xaž~÷µGqá7šÖ(ݼ±¬ÓÈÐÝÚ™a6Bù)¼|Ëœ$õP7GBxÏá“Ve§t[³ÿ_ûk/þŒj¯§Å§\ééo‹[“!š=íó2_œäg'§áV¬qöV$gK×þºµO¸q_ñ©(ɺðö™yom °8[Tòáh¦xÝSJîV AdÎ*; h·B%’È*Å€$Rb”l \#2 +2gkØOÒ–/ é0jö;R³ e_5Ìk!.#ÎÀÇž@Ï&µ÷î/ëþ4nÜ_×ühM äñ4š¯Ú!ky­¬ö²A»z‚džÝ÷¹Oè<-£Û‡ jîo‰§’]± .æ;²â¶·î/ëþ4nÜ_×ühò3*ÓÃúmŒ‹$8u¶û(g™Üù[‹mËÜþ: †O èÏkkoöi#KHÌ0˜®$ÕUܬƒèI­½Ãû‹úÿWŽfmJæ"–Äʾ…Œ™?øèü¨Ü ƒá˜¹¥Þ«C¶— Çknà©`K9^¦¬Eá½&@^ÇjD¢F•WÍs¹.#ÎÀÇž@Ï'Öµ÷î/ëþ4nÜ_×ühxCE[híÖÚdŽ&sË©U“wÞU`Ù º=ªfðÆŒË2ý…BÍj,ÝUÙA„g slI-áYLmÃäÛ¹FåcÀ`=³VGˆ´Áxö’\ì•7fÄYQ–Q) 9ä`äpk!4 Vêâ ¯ÚÎ1Ùâhà‘˜ß4¿be#8™NvoÁá¾÷?N)n+HÖIîîÕYÖ0~Ó)ù˜…ƒêE2Þx.ˆòn¯œãwŸ62µ†s€sùö«ú´¯º–…DÒ#‡JY®tÆ’)5I¤¿Œ[’h¼É|¼¨A(ØÁãœUI­­’çETÓ®g²Ù|ÐÚý¥)tòÃF8 F>^3Œq½äÓÅßþIÿÅSÊ6™&i.L¨ «›™7(8ÈwÀü…T—êÖ6·0µ=+StÓ–é$g]=#‹ÝÉ áŽJ²ºˆßý_ÎÇi烛šžŽ'‹YšçNk‚u[YmÌ…âAâ«‚Xdg«ZžëP²²iV{ÛàÑ,«4î~v*¸œä‚0)ö—0ßKª.ÜgÎ71~[ñŸÂ…†•÷_Ó¸®^ÐmdMRûÌUò¬Ù­íñÙ\ù§ôh×þYzvÖ·šuòiî—o©Ýùóyd9ˆùÛCÈNÌvÎz·„±ùví<1î-¶;‰dœ“€ÝIæ¥ò?éâïÿ¤ÿâ¨ú¬­¸sns¶ö· =ÛA¥=°ŸL¹IbŽÆd4í*²JßëÛïa€îzæ®êµXu?³é\(™ªFòiþ(¿»D;Y­õ)ô$ƒVÿáOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ³*ÞÆå|BÖÍ ý†ÚY/bm¸Rò ¦AiN;ek•{;©#¿û6“%¹ŸK¹IbŠÂe4í*²JßëÛïa€îzæ»ÿøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ„’Ýîs‘ÜGu}gö;·’}VÒå-Ý“Ë_$1.Ñ‘œñœb“NÓïÆ/<ªË8º™ÞUÓÜ„ƒ±Zà¾Ö\l€H*8àšê?áOú k?øÿÖ£þDÿ Ö³ÿ_ýjjËúôÿ"uµ‹ôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ•îËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ²ýCþDÿ Ö³ÿ_ýj?áOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZ«ßxq-4û›‘­k?º‰¤ÿÝ=03ùŠ,‚ìµ¥ÿǤŸõó?þz»Xz<È—è/®£Ž ù¡SaàòYI',y&´~Å/ýï(øÝ j èI7ü}Yÿ×VÿÑoXÁwjš¿ý}¯þ“AZ6îdLÎîEÄÈYÈÉÚ%\ðíéTâÔõúû_ý&‚³¨´./R_‡ßò'Åÿ_wŸúS-|>ÿ‘>/úû¼ÿÒ™h­gñ3 ?¢0à_ø¶1ú€¯þ“U_ ÿÈgFÿuÿ•Å_âÖDê¿úOT<+ÿ!ý×þW§Ø!ý¤z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!‘gâû­FÂæêm3ÃÖÚ“½Ë‰'–É®ŒemQ£ËL7Îÿ.ìí^ýEfßÜx‚]Eìàð…µˆ7ºtQÏ“¹€K<ÍæFT0ŽEU,¥F22 Zñ®5þº÷w0j1YÅ Ò%Å¥˜»‹dƒüÀT©o¸TŽâ°-ôi,u}'^žß^‡GÓc´Y/æµHž5·¢8C'›[tŠc9¶Bœg< Ã¥Q®k>’½ï¦©ö[ô¿{Þ5ô=3Áú¥æ«á˜®µ)!{¤žâ $Š3¿•3Æi' êMIaâ[K­6âúeh"†@ `»:¶ l ’Á— 98æ°ü‡Uøw$vW•º¼¿ 2>FÆ»—,¤g?)$~nãÂmhfM)#–Þx9a¿¼ùÁMŽK2`Át… ñM ²ø®ÈO¦Gw-õÓ[öyU¡eRÇr”Êž Žî€Ôéâ}!ÒéÅÓ*ZÆÒÈï ª”S†d%pêR¹QY°h:ªG§<²Æïm~Óù2]É/—FÑ•²îr7€ë· j¤žÕ.4–Óå{4[]:k 7Y™C…¤Êü˜¹vI>‚ëðßúïþG[gwõª\ÁæyO¾dM<ÿu€?§=jzDQAì1KC%m¨QE (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÁоõ÷ý}ÜèÆ¨ïzµI¡}ëïúû¸ÿÑQÞõjèûlÁü%]'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`g-Í#±‘â‹f»ðÔ0¬M mAw*®~_´Ÿ¦3\„ÖÚÜ<–³yϧÜÛËÔ¯–ª3â*Ì=A¯E›þA«ÿ]åÿÑT«« Âþ¿äSzœÀšþúkˆ-.Äe¬@2[º¶f-Ãxš­i¦]AçÅag%´¢ôVXŒc{H…0ØÇ+Œon;z+of¿?Ä”íø~#4:x°Ùc¡Ì4‰æ‰låòÁ ß1€`ÉŽãrvñLÚ3è¶‘ÝZHLop94É&‡þ\Fä8ÆÓØdWuEî Øâ5 EÌ—Â≠²c$™6ËûÁ»kn`6õÉ;AÁÅhÉ$f÷0Mªß\Yȳ¢\٘ʟ»MÄ©n9í]5ù7…Ô4«Àöþjïo¹lšá£¸g,åHe¶Já›—¯z}-ååïØÙ®Æ§nb›Ë;„xˆ1SÙ~öqÇ\ô®²Š4ŸõÞá¹á«D²Óçm~ÎËw1eò¶—%Hã‘·nãŒv­š(ªJÊÀQE1dÜßišv³5Þ®3mš8\ãt‚e(:÷€êqëÅkS4©¢¶ñ\ÓÏ*Ezig‘Ø*¨ ’OAXb?†Æ·+ oD²µmnî÷Lº¾¹½ V÷‰äÃ7•°“8á2K°ïÀè*6[Kìë³âK[{9Ví¤¾¶hŒ>|ŽŒQK†Aч ’îMvcZÒŽœu©ÙpnDëåœcvq׊'Ö´«k¯gÔ좴›\òN«瑆'§jó™hÛWÓ,üi>¹04ÛË%’…#ËrËÆìƒž¬Èî쌖ºäÚŽ$/©‰oZÖe’Sä4q†qÇ]¹cŽHè1]έ¦Ù4 u¨Z@×B%™TËÓîäóÔtõ«”ú¶,r:uΙoá ÁªJ‰a3]α³ZÔÊÇ JËÓ³Z]];ÄÓß^ ËRg·H>Ëev  24mÄ“À8<“ÖÑHcÂe§øsìåâ¶„^^Gn ÂÍ!ÂýÇaX¶š¯†5H^åï,bÒ,,e†Dœ4ï TîQ…/^ry8ƒEî1á›û-gQºÕa»±i^‰m-§I”±S!R~bXñÐtòOOEQEQEQEQEQEQEQEQEQEQEQEQEU sþ@—ýzËÿ ¿T5Ïùj_õë/þ€i­Á˜º8‘¡Ö„.‰)Ô®3©e òàÈöÈúŠçôOk:?‰%Ö_ÅOt÷, ÜRYág_O¿ò‘ü$—¦1tôk¾Õ5…’{¨ÂêàCpè:úŠ·s¦G ·Wç·’jé«îf§e±bÏîZ×å×þ…5Cn3©kõøŸúM.’1c§ ±ÅÍÈËIæn¤õ¥³ÔµŸúüOý&‚°ª¬Ú4†ªáðÿþDø¿ëîóÿJe¢‡ßò'Åÿ_wŸúS-sø™•áGÑpøµ1Øé=føWþC:7û¯ü®)ßL<¶áåÿa¨Æ?éÚŸá_ù èßî¿ò¸­-h?^òG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qY‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬77vkY<¥1,¾D²F2Ûwõäš–óÄºŽ— Ãj:U²²YËw¶¼2ã*Å£R¹Ü0@=ÿ¯ Ûn|.½¶²šûlÚ’Ã.ìÆÛ®¦ÁÈÏõ§Kàë‹‹{µƒIÑt‡’Ækaö'$LÎȉ03ѺöÇ>)ª¶Ÿ×oø&ïŠ/ô˜æ:–™j®,溅m¯ZMÞX«nvçpÁÕâp×z¸´;µ@ÅÏ™ÿä!l9åXvè~”^øZÁ|?©Xé:}…•Åå«B^(V0I ÅFq“U`ðÅÜZÜ7¦h PÞ™QFAäã§_2g?Lw§ý_×B~Ïž¿‘ÕQE†QEQEQEQEQEQEQEQEQEQEQEQE`è_zûþ¾î?ôcTw½Z¤Ð¾õ÷ý}ÜèÆ¨ïzµt}¶`þ®“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡kèzW„õ{C©}«MŸ·0Í2'–Œ!šH÷à“·!2yÇ&§Oé/J²Üd2¯”læ±`HÛÝì rSèk ÂÐëŸ îm¢¸S íÆ¢©2a×k]M†ˆç>õ£{a¯j6h—všQ1Ȭ‘GyÀW!øêsÁý~ [›ÅD[È׿ڞ$ŠÚI… 7ȪX'FG9èj„Þ1„kkcoÉoåÛÈn¤2ªŸ9ö \FÀõîÞ;1Ó¼=wkܲ@[É»ó• À’ið¼r£dàž9â…¿„oáµ¶‰¦¶-tM†lfÞBïü=<~¸¦º_úÜÎßÖÆåÇŠ4«k·µi¦iÕ™KiYY–(¬«0ð >Õ^ÏÆdúVyre¶kØV_,Ã#y@2Çoʹ8ØSÔV:E~úìT6ÌÖpj]5ËA2HH%!ÃI€UØ‘Ž$FÞ ÔÎÊ)ÚF]=4ùÔj T' ˆÂù€†9FÆ:êiGÏúþ˜=ÿ®ÿå©ÕË®éÐêK§¼Ò ËÈ…ÌaÈÈS Œ)99r+;OñdZŒ6òGg:™n§•‘Ã*Å».P[;T` c9ÉôMI¼@·VþE¼>lnÓÅw2³¢€ ¼1ÈÄ »ÉÈãåíB½°Ôäší­Úšãìþ[’ÇΛÌ%PÁ=ýh_×õøÿ/Ô»¡ëÛn?cžÔ[\y!g]†ÅpÅz®wt<úàð5«7LÓå²½Õ¦‘­åК0¤ä/”‰Ïr‡ô­*;QEQEQEQEQEQEQEQEQEƒ¡}ëïúû¸ÿÑQÞõj“Bû×ßõ÷qÿ££½êÕÑöÙƒøJºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡Â‚Y#$4qÐHÀŽAXç¶3ZÔÍ*h­¼W4óÊ‘EšYäv ªƒ$“ÐVá±­ÌY.â5GÒu6œÚ” =ÔÚ„ˆ¢?'§ÚFæ ¼(ÝÏ\d ½ö§cÛoídk8&Ši$‘!ÚáÙT“å;ð7y`ääWd5­(éÇQ‘±äN¾P9Æ7gx¥—XÓ-ì#¿›R³ŽÎLl¸yÔFÙé†'¼í‹8G2RßV·g×6:„–J$ Já—Ês‡bƒ<‚H?taÚuüÍ êlºÔÔ-¿ï—Ržä#“󆜠1AÁ>^Kqšô)n!‚Ýî%š8àEÞÒ;ª½rO@=êªë:[iͨ®¥flTà܉×ÊãïgxëBÑ[úÜw¾§³Ã<-ì’\¼Z”ì%MBKˆŠ¬>R_”ȹËG̽8«º† xkD»ºšö;»Y]¶¤’\#9 »²Ì3Œà‘Ò»hæŠhx¤G‰Ô:Ȭ ²žAÒ«Øêz~©ɧß[]¢¬Öó,O¡ œ}}-ý|Äbkz}²ø«Ãú†Æ7-vñïgf ¾D§ Âç88Î+PºE±Šú]F;e¾šæãË—P’ÄJ26 9`ЏC×vqòנÊ«ëë{‹¡ÂÉ9´KË+Bê* ]ašáîäßFp Å·d*3»£c8¬ÛFeÒì€ÔØéux¿jºÕ%µÜUñó•Y˸€xm£¯C½±‹PƒÉ™îwnÌBß÷Ò08öÍ:ÊÊßOµKkhöD™ ,I'$’rI$’Iä“K§õä?ëóÿ2!îdѬžñÕîZ2º©PÍ“‚ô }*íSnîä¥dQE!…Q@Q@Q@Q@Q@Q@Q@P×?ä©׬¿ú«õC\ÿ¥ÿ^²ÿèšÜ…áŸù k_ö—ùÕûÿ¾ÕCÃ?òÖ¿ì!/ó«÷ÿ}«wñ|‘Ù*éñç§ÿ×ÕÏóš±nÐ6»ªgþ~×ÿI ­­/þ<ôÿúú¹þsW+«ß}ŸÄššç­Úÿé5½aY^OÔÖžÈê¾ÿÈ¡ý}ÞéL´QðøçÁñ×Ýçþ•KEUO™Ðþ}ÀDqᨇýAWÿIEløWþC:7û¯ü®+?ùáÿ°*ÿé(­¯ ÿÈgFÿuÿ•Åhþò~#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬MN Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèvvÚåÍÏ€SSÕ䉿·¸¸Ši!Œ¢¿“,±î “‚BŒõ|ŽŒQK†Aч ’îMvgYÒÆš5#©Y‹p.¼õòºãïgxëÖ‹gK´´†îçR³†ÚlySI:ªI‘‘µ‰Áãž+Îh³m_L³ðu¤úäPÀÐCo,–HB|,mÈ 7/°x³#»²2Zë“j:t¾¦%½kY–HmOÑÆÇvåŽ9# ÅvW:¦Ÿg<]_ZÁ5ÁÄ1Ë2«Hr“Ôtõ«tï«aÒÇ#§\é–þ¼¤¨–5Üë1­L¬rä© ½;0õ¥ÐåÓ¼M=õ༵&{tƒì¶W`É ±S#FÙ I<ÐÉ=m€æ<(ÖZ‡>Î^+hEåäq&àœ,Ò/ÑAY†TåŽ <€3€_‡ô€—OñtwÚßö{Ù¼Q:nŠà¾U‰’EUÆ8ܱ§oLرñ$7r2Ån¿éE·Êr|²ßwn;œ‘ŒŽ¼‘^ÓÂþKÏÈ»Ø[[FÈÇÌWˆ¹ßÓË)ÔV}·ƒõ ,Ä÷VÛÞÖúd„½<¡Õ‚‘Ðr öç­iê=áùjn'Š4—¶’q4à#"˜ÚÒU•‹ýݱ•ÞÙçœCRKâ-.(.Ìò.ÓíîlWËmyo,É,PÉ#‚…A_-T¶~cœ·iÍXºñ%¬³È¦ÎKo´µÈ$…RÊ©À;‹~†ªXèz„7Z|÷W)3Agq–‘³#£( FX(]»Ž À8äÕK? ^ä-´ÒÛ´é ” U›hXHfíž[v?”_Ÿüþ¿/ø&¤^,Ñæ™aYçY ¢&Y-%C¶6‰7(ò÷dcv3Û5:xƒL}@Ù,ïæ†d `q2‚YVM»†@$ð} QÔ4«¥Ô‚IûUåµÂn'…ŒÆX:ü‡…R—ÃúÕÆ¿oy<ÑI2H²ÙpѲ:ªˆ6ìR¡ÀÝ’N9<Òéýy Ӄź%ͼ·Ý¿“ä»[È¡¢YIQ¼ûsŠÓŽöÞ[ÙlÒLÏi+¦Ó±`§=9Úß•rïá+¹´‹+ž0è²éÒ2’xâ0qÊü‡Ðô­M"ÃSX¼Ôu´ˆÏm +¼­&  $²¯]ã·øÕ;_1tþ¼¿à›”QE (¢€ (¢€ (¢€ (¢€ (¢€0t/½}ÿ_wú1ª;Þ­Rh_zûþ¾î?ôcTw½Zº>Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(ª–óØÛx–Iµ·K%bò¦äF.Ö>€Çc9n—Dÿ‘Éÿìô`¬1Ãc[‘iš…µ¶¡ww¨ií¾ôÉoª˜³kæ´@e~l(??'#vN,ï4û? ¤sj}•Ìp–ú…ÜY†Ti2Å *6¶A » æ5Ú$ñI$‘¤¨ÒD@‘U(HÈÈíÇ5%yÍ]X»õ8 û›ðtk{ étøÑ ºCçÜÆªBǤ¹= T·ÝÉÞDÅáFd(YA*zj`»¶k“l."3Œ“q¸cñ×Ëÿ}Zš›wÔ-`¢£’x¢xÒIQVÛ³\àœS€Oài†òÕcó Ì!žVâã÷mÛŸ\ñ^)=Yõ (ïã°{Ëu¼‘w¥»J¢F^y œ‘Áüªdš)DIž2¨`J’2ôàƒ@¢£ÄÓ¼ *‘C4a†å8$vò4IË~—ï{Ãæ¾‡¥øKVºÔ|,—º¬Ðˆ¦¹†i£O-C4‘ïÁ'nBdóŽMX‹ÄúD¶Þý¥Ò °I.ìm;YAÁÏ<óÁ¬[íü8¹·Žu0^ÜjH³FC¯u0 B0sRÙø^õ,®DÉW25²ƒöû‹œ¬R9izwÂÇ©Ï*45¢ñf4Ë Ï:Èe2Éi*ݱ´I¹G—»#±žÙ¨­¼Q Æ·k¦šá.KÈȦ)6`’€g®yÀ w)-Ô4«¥Ô‚IûUåµÂn'…ŒÆX:ü‡…UµðÅÜW–Ï,‘´ Þ¬ÞUÄ‘:¬Ó T«(#hdu<žâþ¾ï󆞻â;-ÞWœ»Ì°<ËFíÂ÷fU!“¨™´æÔ Yî¦Ô$Eù=>Ò70]áFîzã U诵8´ëþØók#YÁ4SI Œ‰×ʤŸ(±ß»Ë'"»!­iGN:ˆÔìˆ87"uòÎ1»8ëÅ,ºÆ™oaüÚ•œvrceÃ΢6ÏL185çlYÂ9”j–úµ»8¾¹±Ô$²Q!W ¾PÛœ;ä@û£Ó¯æmSeÖ ¡mÿ|º”÷!Ÿœ4åˆ0Ú òò[Œ× Ís½³ÜÍ4q@‹½¥v ª¾¤žªãWÓ›ý¤5O°Ïמ¾W\}üã¯zдVþ·ï©Ã,ðÏ‹{$—/–¥; SP’â"«”—å2.F2À‘ó/N*žÑ.î£f½ŽîÖC—m©$—ÎBçnì³ ã8$t®Ö9â–ž9QáeÞ²+¥qœƒÓõ Ž¥cªBÓi÷¶×q+m/o*È õÆA<ò)õô·õóüÔ¥ŒjZŽž]F©>«iqmGx—Ê˨îª@Hà`æªjH¶1_K¨Çl·Ó\ÜyrêX‰FBÆÂd,WzîÎ>ZôgŠá Ã*HŠ–FdÇpAéPZêš}ô“Çikq%¹Û2Å2¹ŒóÃxèzú•¿®Ÿä‡}NâêÞÛUÔo®fÔ`–ãJ²m­rb“Ù\°û¨Ws6nb0O5,.c½Ô4׸¼Ý ®·åÂÑj’ÜF[e@˜í/—ȽJô8>‡c©éú¤o&Ÿ}mvˆv³[̲>„‚pjÝWQt·õµŽÂ:¥Ñ¿’[ýBÜm¶y5ßP’c Ç,Œ-ñó¡°GLíÍwøñV©ê÷CPŽúÕl¬…ÃddŒÉˆó†$àíëÁ9=ýA½µÅÌñG¶K—+dÌ(>Ü(zR[¯ë¨>¾ge¨?‹çŽKÈ–qsp²ÛùYü€§ËÿGÙ±l$Ü3’3–Å3O¸Ô­ôÍ.K;«Ë›ËâïlÓ¼¾dø‡iÃ:žã“êkШ¡mývæ;ësŽûýQ>©uy¦­Œ·Fåæh‹9•’CðÅGÝêÍA¦\ž$#HÔfº´—SUÞnQ nvï$—PÀu'‘í^‹E _×àyÞ›siq«øa¿µn®5V¹v¿µyÚEŠ_³O»rˆ˜@Q·#<dz%Uº±ŠîâÊyÃYÌgŒ),cxùöćñÅZ Š( Š( Š( Š( Š( Š( Š( Š( ¨kŸòÔ¿ëÖ_ýÕú¡®ÈRÿ¯YôMn ÂðÏü…µ¯ûKüêýÿßjÉÑîÒÆë]¹eP“#z¯V«;÷5$ºÔsªF`£7v篰ŸÊºy[wôüŒ/¥‹_üyéÿõõsüæ®ÅxþßÔsÿ?CÿI­ë¹ÒÿãÏOÿ¯«Ÿç5pž.?ñ?Ôëèé5½DŠþeKøhî¾Èý~^ÿéT´R|<ÿ‘:/úü½ÿÒ©h¬ê|oÔ( >ˆà¢ÿ‘nû/þ’ŠÙð¯ü†to÷_ù\V4_ò-Ãÿ`eÿÒQ[>ÿÎþëÿ+Š¿°þ@¾$z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!‘¡Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8UÈ8vÀ 8«¯âM)5#`ní *ÂØ‚BˆìUg ´‘ŒžsÅs7^×î<=o¤™­ŒQØ @±ßÍ ÆàóÄÌ¡†Ü£` ÎsZáëÙ!½Kp÷•µàÃ6Çäî:þí±õ)èååÿüƒ¡¨‚îa$sÜ]ÉæGˆ‘2ËåälÏßõj¦§àég´¶°¶ŽÙà[!f÷Ï,r¨îÌ‹•˜s­€yçtù~Zþ#Ðên/­­,öy6[¢o-‚xúIöš¡'‰ôˆ¬£º’âDI&û:£[È$ópNÃÝሎr1Ôf-Gé5¤ÆÎYÅÑhäg»•âÝ«¨ØXª‚TTt&±ïô­a.,ï–ÚÚKéõe¸xQÙ¡‰VÝ£“fyÀùŠðX ruÛúì^»ñ¥ŒÄ+K–SÝ Ù%TO(€Uð„©ûÀäeHŒ°©.½§A~–2LÂv*¹;"³}Õgj“Ø ÈõÎ^øOT¹µ}²Yù÷6·±N Œ7•†ß”î¨ uϵlAaªØê·-h,šÒòdžY%vFB*2ªÃd Á,1ž‡"éë_òänÑEQEQEQEQEQEQEQEƒ¡}ëïúû¸ÿÑQÞõj“Bû×ßõ÷qÿ££½êÕÑöÙƒøJºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡GF(¥Ã èÃI÷&»Ø§ŠpÆ)R@¬QŠ08aÁÜzSVîÙ­>Ö·m¥üàãfÑÔîézóY¡‹i¨YGá«6Õ£µµx ‚I­Ú1¶Øœlb¿À¡‡à ½F+Ÿ¶»†)£Ô.o-§°McΛP„m¶bÖåCHUVÚ¤îa»’Aàwr\Áy&!8ÄŒÀ/'ŸrGçRÕ7«béc—Ðç²Ã“¥ï–Ö³Iwq ›ËÛX‚²áàzÔZI¶Ö5gmì7ö·0ĦãO‘£D¾#ÜŒ~pI p3ÖÑHkÂ&ÒÃÃëj<¨cûmÜPÄ03‰¤;TwàaY_èsj2Î×vw4Zd°Ë ¢˜Íœ_!)(RN[‚0yÇyEî×ãs˜ðÍý–³¨Ýj°ÝØ´¯ D¶–Ó¤ JX©©?1,xè:y'§¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÎ@…n5 n'.µ 2c‘‘ºö*Azx#¶—(÷D©ÈÝ{9ˆßÍTðÏü…µ¯ûKüêýÿßjèmó[ÐÇ¡WKÿ=?þ¾®œÕÃx­sâ Gþ¾‡þ“[×s¥ÿÇžŸÿ_W?Îjâ¼N3¯ê?õô?ôšÞ”Šþa/ᣴø{ÿ"|_õù{ÿ¥RÑGÃßùâÿ¯Ëßý*–ŠÊ§ÆýGCøQôGü‹qØô”VÏ…ä3£ºÿÊâ±âÿ‘jû¯þ’ŠØð¯ü†to÷_ù\U/üƒí#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬Í Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèwú7ˆïáŸZÔV+›»3v²yJbY|‰dŒÛwõäšÙ—^Ó¡¿K)fq;•^"vEfûªÎÕcØ ÈõËxbÛûsáuíµ”Ð¿ÛfÔ–weë©°r3Ç=Fkz?U±Õ.M ²kKÉ’id•ØIQ•P.! aŒô8ÁñMÄñø›H•.Ýn˜%¤m,¬Ðº‚ŠHfBWçPAår:zŠH|M¤\ZÏsÑòà _t.¬Cp…TŒ°c•1àf¹øD¯4ÝSŒÂ³tË‹[fKˉä—pã±Ùv®UAÉè@:±éZôֳܗ´µ½kxmâHdlF,Ùb™BÀ•à6Π“Gõùƒþ¿ø&“ø§HŽÑnd¸•§û0F¶”IæíÜË+¼9äc¨¦K⸑èð­íÅÚ»¢É!…P€æBT²H\m'<0HçBÖ´÷µ’+xf–Man–7»šáQE»!ß+®ìeFƒÃŽÕ±‰ªY}BÝ­P 9žvXœJáÊ«…$m `í9çžëðÿ0×â^]6örË«ÚIe,SJF¯8”Ÿºb*»¤=—##Š&ñF‘Vò5įö„g‰"¶’G!H ò*–Iä‘Îz«6­ÜÅäÒYµõ½ßÚ!µ0…cFSÌÙ¸œ1mÅzñŒS4ï]ÚßÁw,ònüåBp$šD|/¨Á8'ƒŽxZÿ^Ÿæoé‘ê70Je[h­ànV$óX… îãç'û¦¯ÂC¦‹ÈmZYRiBÞE_\#ÊÄœr+‡ÂZœ1YÃæZ2Çm§Ç+yŒkyw¶Ñ·A8$Ž@ãœÝ þ}Bê(šÛû>öê ¹¤wo66gÊ«´‚–¼îÉààUiŸõýy5‰’îò8d·XQ–íšF—…J#$ð:ç>ØïÖ¦Oèïa-ïÚdXbdWó-¤GËà&¨b<0k%<#s"Éó±Ko¨@Ì„–h”:sïëÖ£¶ð¥ð¶c*[Åpf´9û}ÅÎRCŸš^ŸÅ…Žä焺_ú×üîíæ^¼ñŒºÕ€²º’+‚€Ê°ÊY #¾ $x88lãå5oþ{)-.§¶·Ô'{vThŒ©&櫎;œ‘’*•懩ý¡oíM¤—‰¨½ÐI¤eB†&‰Fà¤ä§ëžjæ‡iª[YImkg0,ÓÃvÒ´²7Þf5ÇàN8'³°ú¢ÇŒK¼ò­!šþØ\„¼¼EáIM§œ¸cžzbº;yZkh¥hÌlè¡ •$tÈ$Àâ¹È4-COÓôF¶ŠÊæöÂËìr,Ò²!S,¬TmäÒ¶ô‹ì½ÎÀÊeû<+˜F7`c5NÚÿ_×B{(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€0t/½}ÿ_wú1ª;Þ­Rh_zûþ¾î?ôcTw½Zº>Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(¬ÿ6þ-vàé¶òOtÖFP2ƒ(†ò2@'“ŠÐ¥Ñ?ärûŸý+ GðØÖænŽo—×6Z.  :”ñÌh<ÑâXeÁb~RsÜ‘š¦ï}qðÎÎÙ4{ϰ-Œ­1ŽHGÝ` ÈÌüÇ?.1Íz$Ú•½¬·S^ÛGo ’W•B#‚ 'ç­O±Ï M ‹$N¡‘Ðä0=#¨¯5««z~F‰ÙßúÜóßM¨Üh–-.}ö(#¶‘6É ¾bœy™àp1‘–ÉÆ+ÐÑ‹F¬Q VÆG±Çê*›»d¥d‚Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ0¼3ÿ!mkþÂÿ:¿÷Ú¨xgþBÚ×ý„%þu~ÿïµnþ/’1û%]/þ<ôÿúú¹þsWâQwQÿ¯¡ÿ¤ÖõØéñç§ÿ×ÕÏóš¸ÿœkzý}ý&·¢?Å0—ðÑ×ü=ÿ‘>/úü½ÿÒ©h£áïü‰ñ×åïþ•KEeSã~£¡ü(ú#‚‹þE¨¿ì ¿úJ+c¿òÑ¿ÝåqXñȵýWÿIElxWþC:7û¯ü®*—ÀþCûHôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+2Î Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèz¯ÝËày5mRKw¹µk¨å‘Q¢ü™¤qy\„ã=Njµ¬xªËH>Q5ÎèEGؾc¤ UO9OãX>¶þÜø]{me4/öÙµ%†]ÙCºêlŒñÏQšÒÔtRYnà´k?²_\Aq4“;oˆ¦ÀÁT) ‘Á$`“^)£Ø¿/‰¬­ZäÝ 8® ˜£yšR¨Ø*) .H' Ç8§ŸÚ%ÝâHʶ¶Ö‘]}¡[pu¸9ûœc9ÝÀõÆ»ðµëÛióFc–ö9™EôÖªÆfÄIÝÁ`Œîø>g³º¶ŽHQÊÒUd‘FøŸÉeS• XsÜr-‡ý~?äiKâË!>˜Gq*ß]5±?g•ZU,w©L©àpØàîè Y¶ñ—vÒ¬7|¸šmÏ ¢º/VF`¨ÈåIQXö¾¾·6W*–éq neF½ž|¡ˆÅþ²@Y˜EÇZ¤|-¯\\4—W3Ék%¬Ó5ô²yÙ7:ÆP,G ~Uã‘ÉÅ_Ößæ/ëñ¡³Šï4{VÓ.Qõ »#‡1´w7·ËŒñÀ= fjl—WÚDИÖ;+†•Á$¦'@¬? Ó¦íЊ(¤EPEPEPEPEPEPEPEPEPEP#·Zݵ³J®u Á1)'ßÒ9?—ãë"îIó9»+µ‰ÞŽC×6Ê?ñáZºÞ¾ÿ¯»ýÕïV®«®f¬`Ö—*é?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ ÚOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃni„›þA«ÿ]åÿÑTªìßò _úï/þŒz¥]˜oáîQEtQEQEQEQEQEŸæßÅ®Ü6ÞIîšÃbˆÊPe°ÞB’HòqZÍ*h­¼W4óÊ‘EšYäv ªƒ$“ÐVá±­ÌÍh¬,m%¹µ–ÇO³Öç2=Ó¡ •‘T³+0b'Œ‘Éë]_„Ô¸C%Õİ×&•ŠìA{W—YÒÛNmEu+3b§äN¾Pç{8ëÇZ·±Ï M ‹$N¡‘Ðä0=#¨¯;§õÙ‘×çþc袊(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÌ/ ÿÈ[Zÿ°„¿Î¯ßýöªÿ¶µÿa _¿ûí[¿‹äŒ~ÉWKÿ=?þ¾®œÕÇø”g\Ôëèé5½v_üyéÿõõsüæ®?Ä®\ÔGý=ý&·¤¿Šþc:ÿ‡¿ò'Åÿ_—¿úU-|=ÿ‘>/úü¼ÿÒ©h¬ê|oÔ( >ˆà¢ÿ‘j/û¯þ’ŠØð¯ü†to÷_ù\V,,†âõ_ý%µá_ù èßî¿ò¸§ü†þ$z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!œ‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬W7vfídò”IJùÉ8%¶î ëÉ5kûsVžóPK"Úx,¥¹kÒ’¹òÕÎÕòÊç–÷‹á‹oíÏ…×¶ÖSBÿm›RXeÝ”;®¦ÁÈÏõ­hìuûÝSìPé¯ìÂTš[— î‘9ŒFC`¦q¸g¦ExÍ{Ô<]mkiÔùðÍl.̆tDÜpv‚\äž[ƒÒ‹¯jv6Ó}«G‰n–X —LÐIæ¸Aûß,Aê6ž1×4–Þ½Ó­§[+˜¼Ä‚-ÌÃpxã啸ãyfŒà{b³ÛÁó\[ÏÓô« y¥¶/alÅàq¡ÝÈ£s/˼àdúW[yþèlA­Ýé=–­gmlÿf{¤{{£2ìBn܈TüÃy銊×Äï>‡5ô¶¨Ý#¦\–i˜Æí£Þ½¸çÒ©Ká²›Q‡D†ÊÖÃSˆ%ÌA|³ &Õ<-òœ@#©­+ åñµìmÚ(V–,œ³ a1œ“þêÒ_×õùþ¿¯Ì™uÈÛ[ŸMªˆ°—w àÉŒu èsî}*3¯ãÁ¿ðý›þ\¾×äyŸìnÛ»†qøUøE?&þ)œê¢äÜK¾êS ß‘ £äbÛž{ÒXèúÃøe<;¨[XGkö²5Ì#ýÍ¡‚”~¿:ÞcVº¾ÆÎ¡ªý†}:?'Û%hó»1¾zs÷1øÕ=UÖuk[+Ù4Ë,®bYw-û¼Š¬2>_$zFºv±ubÚœv1%ŽçF·™äiœÆÉ’ (A†'nÜñÍ xn}X$žðürÁŽKûyœÄ. cÈžÿ7~´ÖìlŽÂŠ(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Bû×ßõ÷qÿ££½êÕ&…÷¯¿ëîãÿF5G{Õ«£í³ð•tŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɹ¾Ó4ífk½\fÚ+4p¹ÆéÊPuïÔã׊֥Ñ?ärûŸý+ GðÆ·)Gwddµ×&Ôté!}LKzÖ³,ÚŸ!£Œ3Ž:íËrGAŠè|&¤h…À".®%ƒþ¹4¬Pb#؊ؒx¢xÒIQVÛ³\àœS€Oàicš)ƒ¤G ÅIV úƒ^qoúüGÑES][M{¨m“P´k‰ÓÌŠ!2—‘yù”g$py”rŠŒÏΰPLê]c,7è2?1MŠîÚy^(n"’Hþú#‚W’9§*Ãê¥MEPE@÷¶±¥Ã½Ì*¶ßëÉù¿»ÁžÆŸðÌÒ,R£´mµÂ°%Áô8 þ"€$¢ŠŽ9â•äHåGh›dX€p}?ˆ  (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÌ/ ÿÈ[Zÿ°„¿Î¯ßýöªÿ¶µÿa _¿ûí[¿‹äŒ~ÉWKÿ=?þ¾®œÕçþ2œÅâð?çèé5½z—ÿzý}\ÿ9«Î¼j¹ñ&¡ÿ_CÿI­é/â?˜ßÀDøyÿ"t_õù{ÿ¥RÑIðóþDè¿ëò÷ÿJ¥¢³©ñ¿P¡ü(ú#Ï \xv#ÿPUÿÒQ[¾ÿÎþëÿ+ŠÆ‹þE¨ì ¿úJ+g¿òÑ¿ÝåqD~ |Š=õÖßõÐÿè SU{¤YÝ]C)ä0Èû­N[Ke`Ëo 䃊’Ž Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèz7†õ»Ë¯6§©¼sn÷QË"#FäË${°7È@N3Ôàv©‡Šìa7F÷0,WkiEyLÎÑ,€UÎHbÇ8õ8®w@ºŽ_…7²[‰.–æ}Iaû,m7˜^æ}¸Ú#žžõjóFÕm.-g¶‚å“WŽåQ‹mE¾YÞÁNÞTŒà‘×¥x«ë¿ù½¾ÿÈØOXKªÙÚC½á¹¶–ãí7 –Àl®›;ˆÚ@dб‰4«‹)îÒyPíÞÞD›pŒ¡›vp0O5Œþ¾¸Ç-¸ûM½ì7{¿tge`cù~lmÇ;s×Ú’ÓÃ7Ñi×¢[[6¹™!Œ$š…ÔáÕ ?ëîŒä’»Tí<äö:]ÄiKâ»!>™ÜL·×MlOÙåV…•KÊS*x68;º[ÕË[èZ¬k¦É,±;ÚߵǓ-Ü“yq4l…D®»œÅ¾`:íÈêi‡_ë» (¢Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@:Þ¾ÿ¯»ýÕïV©4/½}ÿ_wú1ª;Þ­]m˜?„«¤ÿÇÆÿ`±ü¡«:ƒoƒvíÿé0.åo“‰ÇÊãÈèOü0+i?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ 幤voù¯ýw—ÿF=R«³È5뼿ú1ê•va¿†7¸QEÐHQEQEQEQEQEV6£=Õµåü¶m²A§¨gÞSdfuÛ€%p»Žà ÏjÙ¦iSEmâ¹§žTŠ(ôÒÏ#°UP$$ž‚°Äÿ nŒµD±i:íú=®«!†Xu)¦E_!ŽÓ3ó>q÷ºìÉäRj3j:rX@nâ´v±™o¥·Ýtò|$hÞy¯îÏfàsÇ~5­(éÇQ‘±äN¾P9Æ7gx¥—XÓ-ì#¿›R³ŽÎLl¸yÔFÙé†'¼þ¿×oÔ¿ëñ¹Èê:–¡os{¦‰fó-—Jû›%aLž£Ìw?óÌTSEŒ—:$l£Q:“ÚGÑÞê:•P’z ×y-Ä0[½Ä³G»ÚG`W®Iè½U]gKm9µԬ͊œ‘:ùCœ}ìã¯i-ÿ­¹ƒwog¥xÝ5-¬ôÛ©g‘Ýœ­ÀÉ8QÎàdñÍbEÍœwª&–Þæ[==¥’&ÚÊò\H_êÍ^‰ÑMOˆñ:‡YVSÈ úU{OOÕ#y4ûëk´CµšÞe)ô$ƒBíÛüßùƒüò8û¸%Ó¤Ô%ƒPÔH²Ôm#·I/duUż6[çqûùÇlTkñ[ø¶öEAw4wI>¢Í EI6ÀlDÊ®×áˆÆ~ñ®úâ¸BðÊ’ b¥‘qÜAúTÚ®y<ðZßÚÏ5¹ÄÑÅ2³GÛæät=hþ¿ èyÞ«©m¡êMª[Ç j¶SœÃtìí0Ý*+ «· ¹p g¶X.úÚííf·™d } àÕºúõ é÷œ¶¿}d÷¶+yªµ¦É8{ˆnÌ gR¡PȬ@ó>\òTç¥a¦)ïõK{ëó ÕìâRò¼aÑÒbñü ± s¹xíŠôZ(ŽŽÿÖ÷ÿ€]>mdÂ_[ÞJï&‚xæÔXÈI0>ÌÄMÊ»_†#ûÆ“LŸRµÓì&´»½º¼½Ðeºežw—tÊ#ÚUXÎFïžµèTÙ#Äñ±`®¥IV*yô#}Å.Ÿ×gþc¾·þ·<êMAc´ÕNƒ¬\ÞÀ¶VÌÒK{$‚<ÊÂVÞw;2N9\g¥t¾ž[:åšê‹qpÂÝâ»’èÀÊùΪ_ »žqÓ8}¾"Ô?ëèé5½z6—ÿzý}\ÿ9«Ì||øñ-øÿ§¡ÿ¤ÖÕ?òñüôχŸò'Eÿ_—¿úU-|;ÿ‘:/úý½ÿÒ©h¨©ñ¿P¡ü(ú#‚ˆÅ3ýWÿIEløWþC:7û¯ü®+’]UF‘¾yþÅ_ý$ºß ÿÈgFÿuÿ•Å8«AüŠoÞG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qPQÁx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(¬››í3NÖf»ÕÆm¢³G œnL¥P>ðN=x­jf•4VÞ+šyåH¢M,ò;UA’Iè+ GðØÖåa­è–V­­ÝÞé—W×7¡¢ŠÞñ<˜fò¶Òg&IvøFËioýv|Ikog*Ý´—Ö͇ϑъ)pÈ:0ä@=É®ÌkZQÓŽ¢5;#b È| sŒnÎ:ñI>·¤ÛYÃy>©e¬ßê§’á$ïò±8?…yÍbM«é–~´Ÿ\Šmå’ÉB‘å¹FåãvÁÏÖdwvFK]rmGN’ÔÄ·­k2É ©ò8Ã8ã®Ü±Ç$t®ÊçTÓìç‚ «ëX&¸8†9fUi@‚rzŽžµnõl:Xätë2߃T•Âf»cf µ©•Ž@•!—§f´ººw‰§¾¼–¤Ïn}–Êì!„*dhÛ!‰'€p:y'­¢Ç…ËOðçÙËÅm¼¼Ž$Ü…šC…ú('ŽÂ±m5_ j½ËÞXŤXXË 6‰8iÞ;:©Ü£ ^¼äòp=Š5ÜcÃ7öZΣuªÃwbÒ¼)Ú[N’41)b¦B¤üıã è äžžŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ9õìõ]`­Í›ùNaqÏ» ·s}q3ºMøÏ¨ÿ‹¦èñý­ÿØBOç[•«©g±’…ÖæN–¬¶Zvõ(Æâà•$2f88ã5å_É(¾Çüýý&¶¯Y³û–Ÿõùuÿ¡M^_ãèƒxŽý¿éèé5½(»Í±ËH•ðïþDè¿ëö÷ÿJ¥¢‡ò'Eÿ_·¿úU-5>7ê*¢<Í61ž?±SÿH…zÇ…ä3£ºÿÊâ¼”ãÍþÀ©ÿ¤"½k¿òÑ¿Ýåq[Kàû…ˆôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+œÔà¼_u¨Ø\ÝM¦xzÛRw¹q$òÙ5ÑŒ­ª4qùi†ùßåݫߨ¬ÛûK¨½œ¶±÷NŠ9â²w0 cg™¼ÈʆȪ¥”¨ÆFA ‹^5Ð&¿×^îæ F+8¡ºD¸´³bCqlcb?˜ •-÷ ‘ÜV¾%ޝ¤ëÓÛëÐèúlv‹%üÖ©ƶñ´GdóbËn‘Lg ÈS‘ìáçXtª5ÍgÒW½ôÕ>Ë~—ï{Ãæ¾‡£xŽ÷þ õ­Eb¹»³7k'”¦%—È–HÁÁ-·p@O^I®Žæö +'»¹q(»˜àŸ rI<9'\g†-¿·>^ÛYM ý¶mIa—vP#ÅmòYg›ÉÂNÔùHg‚T9ç‚{/Iu¦±é‚ñX>Ïç>Åö|Í™f ™ÆÀlvÉ¥&¬Û¦§Ãî“coˆgºx ²¯ñ8¾å.qžNp0_Ÿü˜_ÚbŸjvÂ#󟫌äúqX–~'ºRÞ¥”ˆÒ_}Ž8dl1ùöî"šÖÞkÛK¹Ó­·}¢vŸËo•аvä`õ*Î7Ç#5Ë^hϤÛéQ[i·6éU¸¸fYmæÁeÂÍ“¸`¡<ó‘ÓD†8Q˲¨Sï@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Bû×ßõ÷qÿ££½êÕ&…÷¯¿ëîãÿF5G{Õ«£í³ð•tŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɹ¾Ó4ífk½\fÚ+4p¹ÆéÊPuïÔã׊֥Ñ?ärûŸý+ GðÆ·) oD²µmnî÷Lº¾¹½ V÷‰äÃ7•°“8á2K°ïÀè*Ìw:=ž„kš4wWfv[÷E{p]ÃHˆw×.ìœdƒƒ]‚O’IJ$D X„ŒŒŽÜsRWœÕ˹À_ÜØ¯ƒ °3[Ø_K§ÆÒ>æ5R8Øí%Éè@b¥¾îH®ò&/ 3!BÊ SÔ{Sݳ\›aqœd˜ƒÃ'޼n_ûèzÔÔÛ¾¡k“ÅÆ’Jˆò¶ØÕ˜çàzœL7–«˜na$ò·ß»nÜúçŒzñH 誒êš|ñØKkä£1Û¼Ê$qÏ!s“ÐþUa&ŠG‘DgŒ€ê¤Œ€}8 Ð袊(¨åž+t4©– °±8žäI@³Ånæ•#RÁv'sÜ’©(¢Š(¢Š Nï@ÈfŠâšH¤PÈèÁ•èAE$sÅ+ȑʎÑ6ɰ%àú@QQË^ÛYM ý¶mIa—vP#4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɺ–xuK§…äŒ}…²FHhâ3 ‘‚±Ïlfµ©šTÑ[x®iç•"Š=4³ÈìT I' ¬1Ãc[˜²]Åj¤ê&m9µ({©µ D~OO´ÌxQ»ž¸Èz+íN-:Æ?¶<ßÚÈÖpMÒH#"CµÃ²©'Ê,wànòÁÉÈ®ÈkZQÓŽ¢5;#b È| sŒnÎ:ñK.±¦[ØG6¥gœ˜Ùpó¨³Ó N yÛpŽe¥¾­nÎ/®lu ,”H@•Ã/”6çÅy~èôëù›AÔÙu¨¨[ß.¥=ÈG'ç 9@b 6ƒ‚|¼–ã5èRÜC»ÜK4qÀ‹½¤vUz䞀{ÕUÖt¶Ó›Q]JÌØ©Á¹¯”9ÇÞÎ:ñÖ…¢·õ¸ï}Ng†x4[Ù$¹x,µ)ØJš„—X$|¤¿)‘r1–™zqWu ðÖ‰wu5ìwv²»mI$¸Fr;we˜gÁ#¥vÑÍÐ$ñH¨u‘Xe<‚¥W±ÔôýR7“O¾¶»D;Y­æYŸBA84úú[úùˆåu GE½×§Ð¢»²¶‘îâ–öIçQ$’…#‰Xä·Ê£#Ðd“ŒÝNîtµµ¼k˜í¬µ ‹›‰%“P’ÉIXGšŠN|°H\`ãžF¡Ã§)mwªý·OÓ..%yµ‚í¦MêF£Í ¬|`­¡v!X/Ë kù>m“"Çûѵœ# y=úšeîªÓh÷ž­ui3hi=›CrÐ™î ’ç Föå9ûÄãšôŠÏÔ4[-REk¿´:…Úb[©R7ŒŠÁXzî#Š?¯Ïüÿ­ïýt8ë‹ýGþØâ7±E(’Ø[E%ü¨ÒÄTy˜·Te“$È “òã<Íz ``QNä¤QE!…Q@Q@Q@P×?ä©׬¿ú«õC\ÿ¥ÿ^²ÿèšÜƒ Çö·ÿa ?nVÿÚßý„$þu¹N[“ŒÛ?¹iÿ_—_úÕæ~<”&¿~üýý&·¯L³û–Ÿõùuÿ¡M^Wñ Iñö?çäé5½]?ŒšŸ éß?äN‹þ¿oôªZ(øwÿ"t_õû{ÿ¥RÑSSã~¢¡ü(ú#˜|±Ø?ôˆW¨øWþC:7û¯ü®+Í|¬ÁÔ?ôˆW¥xWþC:7û¯ü®+iüq0ø¾óÑçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®sc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oî^ÛYM ý¶mIa—vP#$µ·³•nÚKëfˆÃçÈèŸdr ä×f5­(éÇQ‘±äN¾P9Æ7gx¤Ÿ[Òm¬á¼ŸT²ŠÖoõSÉpŠ’wùXœ¼æ‹1&ÕôË?ZO®E 6òÉd„!GÈòÆÜ€£rñ»`ç€k2;»#%®¹6£§I êb[Öµ™d†Ôù aœq×nXã’: Ws,ðÁ›4©y{°“Éõ$ ’õl:Xätë2߃T•Âf»cf µ©•Ž@•!—§f´ººw‰§¾¼–¤Ïn}–Êì!„*dhÛ!‰'€p:y'­¢Ç…ËOðçÙËÅm¼¼Ž$Ü…šC…ú('ŽÂ±m5_ j½ËÞXŤXXË 6‰8iÞ;:©Ü£ ^¼äòp=Š5ÜcÃ7öZΣuªÃwbÒ¼)Ú[N’41)b¦B¤üıã è äžžŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ0tøþÖÿì!'ó­ÊÃÐ?ãû[ÿ°„ŸÎ·)Ërc±›g÷-?ëòëÿBš¼¿Çìˆï³ÿ?#ÿI­ëÔ,þå§ý~]èSW”|F$xŠ÷óò?ôšÞ®—ÆEO€õ‡Ÿò'Eÿ_—¿úU-|;ÿ‘:/úý½ÿÒ©h©©ñ¿P¡ü(ú#Æ@c‹þÀ©ÿ¤b½ ¿òÑ¿Ýåq^|¨~Çÿ¨*é¯Að¯ü†to÷_ù\Võ>¸ˆ|_yèóÿ®¶ÿ®‡ÿ@jš«Ý"ÈöêêL‡!†GÝjrÚ[+[x „W1¹Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8*+Ã,`}åˆÇ/0[̙Ϧ1Þ¼SW·ÞXÓ¼E¨jQ[]E¤Äl¯}žX0¨™Bb0pA ¶ÓÅK¤ëµþ¡wΛco œ¾LÒG|òÛÁU1.Fu#½TµÐoαmysk¥Ãq î›Qµ$Ox•à@<70FB-ïÉ×cI£C©\FV9D1ÇŸ{åb?hþ¿!uÓ^¹ÔôÙ®të(XäÇ•qpцˆÊùÇ•*qQž* 7Ä—×PhóÝé¶ðGª²ˆ|«¶ª˜žL°1¯?(õëÇ3Xøu4AßOi>Ë=·•*Ü\É+Sû½»Ë`aœ‘Ú¡Möß@С…íÚÿIˆŽB#1²îÆ@!Žn)éùÁø?ð µO&—>¡Ûnû,0HÈY¥v@‘ò¨* nx'Ž9¹¦ß_Ïq=¶¡§­¬±…uxe2Å"œôr‹óF;ƒÞ¨.™¬H÷ú‹5¾¡:EBŒÒŲ2Çk1P~mì 6‚:ãšúu ðä³ÞϧCaʱ -"nSpÉ2‘Œw°É<—˜?#wT¿þÍÓå¹ù² ,qgc± «œd3Ú²åñÔóé°éV6÷ {j÷9¸ºhB*”qäåýºKmâ©máþ+[gó¥ Å›³ãŠ©ÀÉ'9Ö©Aà¨?µ!¶ö—º]°¸Eu™Üy‚wƒ’IÎIÁ§ß_ëú`MŠ/ïn-­,´ËWºqqæ‰oY#C е„lXÜp*Ö—âC¨ßÁfö‹®·>aYwª´2*§hÜ lçŽ)·ž°½Õ´÷›N°—M´µ–¶’eVfB¥TŒ·çEæ•{i«i÷z-‚ÖÖ[³É3[ª†d#nØØ`l<`u¡t¿Ÿê Ò‡Qóu˽7ÊÇÙàŠo3wÞÞ\cã={ÕêÈÓ¬oWZºÔ¯Þ3qk ^T2´›YBy*¹qÛ×ñ× :ÿ]‚Š( Š( Š( Š( Š( Š( Š( Š(   ï_×ÝÇþŒjŽ÷«TšÞ¾ÿ¯»ýÕïV®¶ÌÂUÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'Œþ´ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†rÜÒ; 7üƒWþ»Ëÿ£©UÙ¿ä¿õÞ_ýõJ»0ßÃÜ(¢Šè$(¢Š(¢Š(¢Š(¢Š(¢Š+&æûLÓµ™®õq›h¬ÑÂç¤)AÔ¼S^+Z—Dÿ‘Éÿìô`¬1Ãܤ5½ÊÕµ»»Ý2êúæô4Q[Þ'“ ÞVÀLã„É.ÿ «1Üèöza®hÑÝ]™ÙoÝíÁw "!Ü\|»²q’ v ÿÈý~ÞÿéT´TÔøß¨¨ >ˆñåaýŸýSÿHÅw¾ÿÎþëÿ+ŠóŸ7ý5ÿ¨"é¯Fð¯ü†to÷_ù\Vóø>âañ?úëoúèô©ª½Ò,n®¡”Èrd}Ö§-¥²°e·ˆrAÅs‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGf`ƒbó÷œ/CÓï¡j³ÝèÊ,ÖëíÞ|$ÌQcòL8³,Ø;¹Qžœu¤Ó´=gF†ÓìFÂY¿³à³œÌî6‹8urãç?)+Ðr3Ã@ÿ¯¿üކÿP¶Óm¾Ñtì°E HÌÇ UPY°°`ñdúŠªéZj\LÏq…šà»"`¤’PİùJñÎHÅZ»Ð^/³ÜéÒI%սȸXï/&ts±®X¹A‡'Ô+-¼7ª½š4¶úl×Fêâf u4‡ e‡fB0ÜŒTëý|‡Ûúïÿé¬5;{ý" M ŽÞhDÙ“j‘ž}1U"ñ>‘-„÷¿it‚‚C,FË»NÖPpsÁÆ<ðjªøFÕt?ìÿ´Ýû ³Þ·ðSao+vÌóž•BÏÂ÷©er&H"¹‘­”·Ü\åb9ËKÓ¾=Nx§»DkEâÍi–žuÊ"e’ÒT1»ch“r/vF7c=³QZø¢nÛL34ëpÂXÖFE1I³”=sÎs¹In¡ Ý].¤HGÚ¯-®q<,f2Àñ×ä8ü*-3@¾ÓõK;¢Öè”`BÍ0‘Jü¼‘€8ëÔ㔺_úÓüÁìtÔQEQEQEQEQEQEQEQEQEQE`è_zûþ¾î?ôcTw½ZªØ Md½kI­3y8ݳûÆîS¥²Ö%Î뫟Hÿ‹®9¯s­aºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡Ïÿ@Ù¿ïì?ü]míaÜBQKö{ÿúÍÿaÿâèû=ÿýfÿ¿°ÿñt{Xw(¥û=ÿýfÿ¿°ÿñt}žÿþ³ߨøº=¬;€”Rýžÿþ³ߨøº>Ïÿ@Ù¿ïì?ü]ÖÀJ)~Ïÿ@Ù¿ïì?ü]g¿ÿ lß÷öþ.kà%¿g¿ÿ lß÷öþ.³ßÿÐ6oûûÿGµ‡p²n¥žRéáy#aA,‘’8Œè$`G „,sÛ­³ßÿÐ6oûûÿQÙé[kS]¥”ÈÿeX—p×—É?ëWû½ïÏlå^q”,˜-ÌY.â5GÒu6œÚ” =ÔÚ„ˆ¢?'§ÚFæ ¼(ÝÏ\d ½ö§cÛoídk8&Ši$‘!ÚáÙT“å;ð7y`ääWAöíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòMp¤UÎ^C(Õ-õkv·\ØêY/˜TJÁ“Ês‡mƒ<‚H?tbÂÞ+Ø_&«ÝÜéûlñuö¦•’f—ŒInÒS ÏAšè>Ý®ÿÏÿÀxÿù&·k¿óÁð?þI¡++w1.à—N“P– CQ"ËQ´ŽÝ$½‘ÕVCðÙoœÇïç±Q®²£ÆvÉä¹{Ù`¸ŠmAšP¡$Àû(Q2«µ¾ñÏÞ5¿öíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòMþ¾à¾‡5¦k6Vöúƒßj’Ý[­¦ùî-µYXÜÜ­´ÛHÄðŠÀ}à~í]ÓÖÊD²Þ JÊiïnÎ{ÄËŸ,"’Xºæ®9èr3[n×ç‚ÿà<ü“GÛµßùà¿øÿ$Ñ`¹-ÔZþ¥µí®¡¦ÖÖÂâÏýR¦÷ÝÁ`\G¸“œàŽŒÇ ú•÷‰î쎢\É=ÌOê™ ¤F›cÇîØI¸g8Î[Ñý»]ÿž ÿ€ñÿòMn×ç‚ÿà<ü“E‚ç5w¬jWÚPÔžV¶¶7PÙ܉.ÞÖ4Ø­æ"‚PHMÀr €sSÙ ­Mô›k­Jå k+¹CYÞÊ¢@² Œ™0ŒøVûغò;ßn×ç‚ÿà<ü“GÛµßùà¿øÿ$ÐÕÿ¯+Á ˜þ\kË{sq#^Ýè–ró6$ûûØ&qÁÛÐp[¶ã¯N ‚Ä\\Ék§=È[ÉÒSÄØÅs  .d×êðÕµV)ã[p6çÈlýRè=ºTvjšis]>ügí´øÇ§™vØü)½X^ßוŒ+µ…޹¨Xjš„¢ËIŠ[iþÒê\«ÎT±óc¶C~læ­ëÚȃÄIå^IÄwVÈÉ.¢Ñ|ŒÉ»Ë·¦²ÍÈ9ÁùF:·k¿óÁð?þI£íÚïüð_üÿ’h¶©ƒ×Übé²\¥î›yöÛÉeºÕo-¤In]£ò×ÎÚ¡ Ú0QyÆ}ñÅS´Ôg-éú•ÝΰÚmÔ—V­pÒ,w@.ÆICF8ìz×Möísþx/þÇÿÉ5Ÿggct×Q[Ìó²•ßpÆrªNH]÷gh$ Œàz ž^ƒæÖöþ®/7{o¡ºµ ^¡-áY;³#¢ã#iØ Ú{ ÕŸÇö·†î.%’4ŽüË3 ɉö‚%‚€;äâ Ç|5mFŠxçEVÜ ¹ò?Tºn•„¦š\À—O¿ûD­>1éæ]¶? ¦®Ä‘Î=À¾ðþ½j/å¿c¦I$“[ê2Ì¥×d€6îyýÚœò×O­jzt^´Xuk28¼ÔÔLH?w¹|Û€K"‘´äÄ•êæ×Ûµßùà¿øÿ$Ñöíwþx/þÇÿÉ4­¥‚úßúèsúÝΫw¤Ç-íÃ$qß8H¯]•Ìs sðdHå¾ð<õª“Ki}¢[!Ö/eÕ&šÓíð}¡›È”ÜG»*r!`IFÞü¹_Ûµßùà¿øÿ$Ñöíwþx/þÇÿÉ4ÒÕ]Bû˜Oö¿·" Bö8†­%´nn]TÙ¹%Žädœ`zU{½cR¾Ò†¤òµµ±º†ÎäIvö±¦Åo0™€ÊBn dšé~Ý®ÿÏÿÀxÿù&·k¿óÁð?þI¥oÓð –<-,óxzÙî'IÉ.T‘¤ ›ŽÏ•Kü¸ù±óuç9­ŠçþÝ®ÿÏÿÀxÿù&·k¿óÁð?þI¦Ð&tW?öíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòM+΂ŠçþÝ®ÿÏÿÀxÿù&·k¿óÁð?þI¢Ás ¢¹ÿ·k¿óÁð?þI£íÚïüð_üÿ’h°\è*†¹ÿ Kþ½eÿÐ g}»]ÿž ÿ€ñÿòMCu6µyg=´á&£b°GÁÇúE4‚ã4wháÖ"yYu+‚#B9x dû+Hø§ëzØÒ-4\]†"U’Q _çù@ïßà™ïæ•T<`ªœc9qèzg§¦*Ä`Ãs5ÌZ‰<û|éTÀM£ ¸ïÉÀàg¥'¸-„³û–Ÿõùuÿ¡M^Qñ€ñ÷ý|ý&·¯Y¶ŽH’ÉeŒÆææw(XyÌ3‚GB;׎|N¯‰ïý<ÿíµµ]?ˆŠŸ ëÿäN‹þ¿oôªZ(øwÿ"t_õû{ÿ¥RÑJ§ÆýECøQôGˆ*æÏýAÿH…z_…ä3£ºÿÊâ¼åãÖ?û'þ‘ ôo ÿÈgFÿuÿ•Åm?ƒî&èóÿ®¶ÿ®‡ÿ@jš«Ý"ÈöêêL‡!†GÝjrÚ[+[x „W9±Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8kæºx­á)æ ’6Päm¬¡¶’xlc¯<Ãðu¼:ßË›hçSíÆ¢‹4gp*÷SÀŽ£>ôšÎ‘¬Ï§]^\Ajoä6pG±ySλªqóŒp©¯©¡«?‹ìm=-ãžawrÖ͘%V‚ùÔ¦Wøx pwt§(Ó#²²¸¹ŸoÚ`Yÿs’¢#cæf6/?yÂô=0qžú«=Ü:Œ¢Ín¾ÝçÉLÅ?$Àû2̓»•éÇZM;CÖthm>Äl%›û> 9ÌÎách³‡P.>sò’½#<4úûÿÈè.ï–ÖæÊS7R˜—q ä#7R ù{:óœ/Œ,Ž ¶¶p\]“Ò~îü¼ G•L“Œ©Àüji¼:þ=´Ó‚é§›írÊpb‘>Må¶ò㠬ȴOÚ}…-¿³6é–’ÛÚ¼’92’#8Ûò€ Ï­HË7^)¹Ó-ï¿´ì-mî-¢Še {º&Y`ÜåL09ùHÇBy­mR}VÃíLlK­cyö˜Èíl^sž1øÖEŽ“«C§Î—6\·né3Ë=ÓÏö‰ƒóf%ÙŒ|¸/^*Ä7-£ÍqwªA0¸¾9ŠÂÞ{´@ªï$yÉÆyÓœf˜‹>#×G‡ô™o~ÅqvèŒË(qòŒ’ÏŒ Çsøx­F•4Œ¨Š»™˜à(ÆI&±õ‘-„÷¿it‚‚C,FË»NÖPpsÁÆ<ði‘x³Gše…gd2ˆ™d´• nØÚ$Ü£ËÝ‘ØÏlÖMŸ…ïRÊäLEs#[(?o¸¹ÊÅ s–—§|(zœñPÐn®—R $#íW–× ¸ž3`xëò~Z\žƒ­¼Q Æ·k¦šá.KÈȦ)6`’€g®yÀ w);õÌéšöŸªYÝ·t¯D ;i„ŠWåäŒAÇ^§ôÔº!½Ý‚Š( Š( Š( Š( Š( Š( Š( Š( Jû—Ÿõû?þŒ5~¨i_róþ¿gÿц¯Ó–âŽÆ&“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡ð?Þ4ÿìÛ¿ú ]ÿßñ rO±Áé7þËÿÅQö8=&ÿÀ™øªû6ïþ‚—÷Ä_üEÙ·ô»ÿ¾"ÿâ)ò‹˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*¢°3 /!šw˜Ã0Eg  hßÂêÆ °µ½»Ó­n_Sº ,)! ‘c$ÇÉJùsìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ|¢æ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄU_´ÜI YÌ&+<ÂÜ4Š£?; bî{R°î^û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"Ÿ(¹‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñËQq£qm5Ì“ªÃŠdU\º÷E+äÿcƒÒoü —ÿŠ£ìpzMÿ2ÿñURÖÞòò9&þѸAçJQ#À #(ê„ô?ömßý.ÿøŠ|¢æ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄTV÷–qÇ7öÃ:$*éiOD¡£”|Å¿±Áé7þËÿÅQö8=&ÿÀ™øª‚è\M¨ÛÛCs$ ÐÉ#ÕI$ïýãOþÍ»ÿ ¥ßýñÿI ¹'Øàô›ÿeÿâ¨û“àL¿üUGý›wÿAK¿ûâ/þ"ìÛ¿ú ]ÿßñùEÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£û6ïþ‚—÷Ä_üE¡ÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£û6ïþ‚—÷Ä_üE¡ÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£My^ÐùÒf–=ì$,Œ£8t“Vw$û“àL¿üUcƒÒoü —ÿŠ©è¤2$µ†9@®Ys´´ÎØÈ#¡b:^!ñ97x¢ðÿÓÏþÛ[WºW‰üG]Þ&½ÿ¯‘ÿ¤ÖÕtþ"*|'ª|;ÿ‘:/úý½ÿÒ©h£áçü‰Ñ×íïþ•KE>7êMáGÑ!¿F?êŸúD+Òü+ÿ!ý×þWæ¾^`ŒÿÔ?ôˆW¥xWþC:7û¯ü®+iüq0øGŸýu·ýt?úTÕ^éG·WPÊd9 2>ëS–ÒÙX2ÛÄ9 â¹ÍŽ Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèwú?ˆïáŸZÔV›»?µ¬žR˜–_"Y#m»‚zòM>÷ÅúJJu-2Õ\YÍuÛ^´›¼° º5ÛÃf³<1mý¹ðºöÚÊh_í³jK »²ºêlŒñÏQšÛ½ðµ‚øR±Òtû +‹ËV„¼P¬`’ŠŒã&¼SUk¯ë±v_i°_-œ³8˜²!+ ´hͪÒÚ¬r0 äzŠÇµñª]ÞØÛ¥‹Æ·夒o1V(á¡b|¼q’nÞ2yn¯ kZ†¤®³DöñÜA4%¯eˆF¨È̆]²d©;˜äd` TqøJòV¸†æhÞHoà±|\H®§ù=<ðÁü¿ÌKm|¿à› â¬e¼72$1” $¶‘ç8B¨bœ>†’ohÖòùsÜË.Íåí¥Qð ‡%p„ä`69ã¨"³eÐ5mAÍÝïØ¡¹ßf¢8dgMÍæ3n*NH Œ yâõÞ‰s?öž×ˆ}ªêÞdÉ<,~^sÇ_ãð§ý~@X$ÓÍ®D—Vo ÅöI|ï3¶ù[wçoÍ÷zsÒ¯ÙÞAiÕ´žd2 «`ƒô ò<y¹ëÿÞËq¨MV“‹‹ÈîæXB©•–1¹ ô*Hã5µ£ÚÝYiP[ÞÏçN îmåð $.ãË``n<œdòit^¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(›³[ÈÒsvÎu;fI™>kŒ`#zzÕú—üûÙàSÿñª¡|ÚÂhWhkj÷ÉspËÒ’²:L¨!†¡)Õ­¤¼ñ•­Œ'内ÒV òÌŽÑØ dõàc-½D–…í'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`\·&; ‚=vÔŸùö˜ãÑVÚ‡µbß>Í^ÐÿÓ ¿ô(éþ½М¬Æx³Äè~šþ×ìâT’5u%3…$€G@Iê+&ËÇ>\ÚÛ.,õ [aŠëMˆ…–G$y@`[8þ,sÎ*}vÃûkKk/?É̑ɿnïºá±ŒŽ¸ÅdßøJÉ50·B;ké#¸û;Bu9ߌà†ÀܸçÖŽGý_× s«u¯ÜÅinº^žâõõ±š+”F0±è$‰ †Ç©}|uh"¼‘ìo<»IÚѦeœ0]ˆ7î$’1‘R+ <*‚ UÚÂðê zE­ŠÂ‡h Psß©,ióx^þÂ[ßj¾kÕfˆF,)R~aÆLƒÚ…ý|¿à‡:þ¾ð ©uëÏþ½¤üB‚ãG‚{ûiñ¢¶vŽd36ÕòÁlàsž˜ï]wÚ‡µy¤– gÃȽ¶—nR[’UVb0P [!²yãÞ»O?Þ¯’ÿ{'žÆ¿Ú‡µsñ¾ÒÏ¡´?øüugÏ÷ªyÇ…tóè-?ô4©qµ†¥s£ûPö¦Év'aŒ€H¬¯?ÞšòïF\ã Š% 4=NwFøƒyk¢=Ô°Ëupñݬ Œº²|Üd9Ï!«TüBÓ…´— g|± vº„˜Óý"8gA»¶AÃm89Å`ÁàÈam›æoìøÚ)pCßå#{zõ©4Ûi›£v³’!­×ʱHåen2òrY±ÇAî(pzØ9×õêoMãÝ2ïáò®d{3 ˆ§Í2'<òFsеªø® +P¶±û ÝÕÍÄRJ‰n¨xLnÉf¿ù8®FÇÁ¢Õô§—T’f²‘䘘±ö“S<ñ·×8íVµ«RóÄúmå„©Cm!Œ€ã;Ã3ò޼Q(4¼ÿ_øRWû¿Oø'T¾>Ó„S4ö·–ò¤qÉ2F»æYfŽO$c¾)eñÕ”VêÍc{ö“z,ZÐ*y©)ùöàŒ†#Ÿ®9§ð‹êVŽú¥âÉvÖðEîØ„gp »ˆ|ž½튵…Ò8­@šÒ'†ý/µ²XPí {õ%>MmýoþDóéývÿ3J/2ê÷Ö׺M͵½¼¶ðy„ÆÅ^›ðç$tÏCÏ8­í/]·Õ­¤¸·GXÒi!Ô Å©#ž™Åkz-ËůÍlZçûR$Qnˆªé"®ƒ³Œ‘ŒúVæ‰lt­ÎŘ3ÃÀçsõcø’M ÿ¯ëõŸoëúý›íCÚ³„‚Mvèùö„ãÒÔ>½2Å÷ê÷gþ˜Cÿ¡IJQ²+²æ‘8K^8¹ŸÿF½^ûPö®~Ê]±J?éæýÕgÏ÷§È.r½Þ»¨Ýë×N’lák[tši®¢iAg'jV\p¤““ô¢óÆ1i„Ayk,·Û‹‹ÓfÇl¤ãq,T‘Á [œVuæ›rui5=6ú;[‰ ÍæÀeV’¬eà žäsÒ©Þør{™'tÕZòÕmoZHšUù—B6 „sÓŠ\Žßןü¹Õÿ¯/ø&ÃøÿNKÉáû-ãCo4pËt¨†%2PýíÄŽƒŽõkOñ…Ž£umk 7 4âbUÕuå>Æß‚qÉã®2 Ý˪[Ë(·Òf¹‚E‹hv™#UÀ7ËÊ€rqÆ+G@Òæµñ&µªÍ ÁÌ€Aޤ€]°¤€†zçŽ@¦¡ªþº/ÔNzçÚ‡µQÕçb‹Ç70èÔªÞ½V½—tQúyƒÿF­‚ç/™zí©?óí0ÿÇ¢­µjž}š½¡ÿ¦èQÓüÿzQÐÜ¬Æø§^¹Ñô/,–8–(×ÎRÊ7:©$ ëëYçÆi…톷äM$QE5¼–p”3‡m36pÆwc‘ÓšýƒkzKÙ-À™ÑÄ…7€UƒtÈÏOZʾð±Õ–î]Jö)¯'*:[mŠ5·((Y·IÎ[‘Çr0çV5§ñÀ7VCZý­/bºQ¾#gÈ*Åzs’0ieøkö‹ˆ,.‹-£ÞZ‰B"ÝF½YNâ@èpÀ¬xü'Û¦µÊº7–¶K0(Sh r8lä–5‡ƒ ²µžÛδòÞÖKTx¬9pÀÏ&IfŽ6ƒÜRpv×Oóšºþºÿ‘¸ž>·‹O‚k»¯4Z%Õà…P­²7FoŸy .æÀä êñÔ©Vwçø0LÐË-ÍŒ³-²[HóiË(Ú‡ådÄ#cƒÀõÅuñȱF±¦¨ ÀJ¾MÉçØÙûPö¬Í0î¶”úÜÎò+Ô~½.Žs`O¬óÿèÖ©”lŠŒ®ËôQEfXW‹|Dÿ‘–÷þ¾Gþ“[×´×üBˆ¯Oý<ý&·­)|DTøOLøyÿ"t_õù{ÿ¥RÑGÃÏù¢ÿ¯Ëßý*–ŠU>7êMáGÑ&ú4öOý"éþ´•bÓõ8ÞaÜR3.îe§|võ¯'´¼IôË+õO:ÜÙ¥¬Ê ‘‰=º¸­aâéfÿÀ{?þG®†¹£c%$™í©^;ÄÞEØÛ¿ãæNx#þy{ÔŸÚןóíeÿRñªñ!â©ÏfÿÀ{?þG©SÄÓ7fÿÀ{?þG¨ö^EûO3Ó5 kë—¸žÞÛ@ûLÓ+™/b’à* ´ªz®sžäc½W¿Óµ 8Y[ørÌy‘¼°KæG´dåÔ)9`§#n#© <ôøŽö¿ðÏÿ‘é‡Ä³ïà=Ÿÿ#Õr´­oËüƒÚyž¿§j:Ì|1j-¦]]¨Ä“ÄòB¯ÏaFÇÏ=sÓ µý­yÿ>Ö_ø'ÿ¯'—¸oü³ÿäzx–B?‹ÿìÿù§Ùyµó=—ûZóþ}¬¿ð*Oþ5GöµçüûYàTŸüj¼JoÜ'Ý íÞÏÿ‘ê©ñØþÿÀ{?þF¥ìü‡í<ÏwþÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ¯´ñUÔò`@?ôïgÿÈõ×éÓÃrŠe‚éÚÓÿŒQìü‡ÏæzöµçüûYàTŸüjíkÏùö²ÿÀ©?øÕrÉem ÊÊð×ÿŒÓÿ³`ÿž‡ÿmøÍ.EØ9Ÿs¦þÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ®gû:ÖCÿ€¶¿üf˜l­‡üµ?ø kÿÆhä]ƒ™÷:ŸíkÏùö²ÿÀ©?øÕÚןóíeÿRñªåþÁmõ‡ÿmøÍ1ím¬¿ù+kÿÆhä]ƒ™÷:¿íkÏùö²ÿÀ©?øÕÚןóíeÿRñªãˆ²oþKZÿñšš;[YGË/þJÚÿñš=Ÿs¾çWý­yÿ>Ö_ø'ÿ£ûZóþ}¬¿ð*Oþ5\Ïölß?ø kÿÆi?³¡þùÿÀ[_þ3G"ìϹÓÿk^ϵ—þIÿƨþÖ¼ÿŸk/ü “ÿW.tø¾ð×ÿŒÒ¼ð×ÿŒÑÈ»3îu?ÚןóíeÿRñª?µ¯?çÚËÿ¤ÿãUÊ}Šïä­¯ÿ©cÓ­äÿ–„Û­¯ÿ£‘vgÜ鿵¯?çÚËÿ¤ÿãTk^ϵ—þIÿÆ«žþǃþzüµÿã4cÁÿ=þÚÿñš9aó>çCý­yÿ>Ö_ø'ÿ£ûZóþ}¬¿ð*Oþ5\ÿö<óÔÿà-¯ÿ£ûßþzŸüµÿã4r.ÁÌûöµçüûYàTŸüjíkÏùö²ÿÀ©?øÕsÿØÐÏSÿ€¶¿üfìh?ç«à-¯ÿ¥È»3îtÚןóíeÿRñª?µ¯?çÚËÿ¤ÿãUÍI¥B%oüµÿã5Y¬¢ýsà-§ÿ¬¥Rœ]š-Foc®þÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ®9ì”%?ø iÿÆ*¤ÐH$?ø iÿÆ*}µ!û96ýf0VÞM)P¼‰V9ggê{…ˆ?ç¶ùMþÊ"ÊO.ðÓÿŒU¨¡ ÕþÚñŠ_Y¤?cPéì#òu 8K+´óeÎ S8ÏÒ¦Ôƒy ¾â|û|08\yã ž@êxÎGÐsð¤–Ľ½Ôг ¥¢‚ÙIq‘°§ý¢ñðR½`8e·# äõ^¼Òxˆ6 ›±¿¨iòÝÏÐÜ$Mºñ—1SÙ‡÷j·öU÷üÿ[ÿà3ñuž×—àÈR÷þø·ÿã4‹}|æ){ÿ|[ÿñšk–—¥}Mì«ïùþ·ÿÀfÿâèþʾÿŸëüoþ.³þ×~zj·¿÷Å¿ÿ¨äºÕ@Êj·¿÷Å·ÿªX‹õ%ÓK¡©ý•}ÿ?Öÿø ßü]ÙWßóýoÿ€ÍÿÅ×+y­ëvÇNôÿÀm¿øÅPÿ„£^=5ÏûæÛÿŒVžÑ÷EØî²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºàÛÅ>!_ù½ÿ¾m¿øÅW“Æž ­õïýómÿÆ*““Ù’ÔWCÑ?²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºóSãÝpu¿½ü­¿øÅE'Ä=m?åú÷ò¶ÿã\µ ¼[Ó¬¤²I„³,¯,ža*›@ùUqŒŸîÕt[Ø Ž¿€¬jfØçcûõå/ñ;Z_ù~½ü­¿øÅ0|QÖ¿çö÷ò¶ÿäz\“Cæƒ=sû*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯(O‰šÓŸøý½ü­¿øÅY_ˆzÓøÿ¼ü­¿øÅ;TàzwöU÷üÿ[ÿà3ñte_Ïõ¿þ7ÿ^d~!k#þ_ï?+oþ1PËñZQ‘yù[ñŠ-P/Ôÿ²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºòø¡¯ÇÛ¯?+_þG«|J×$ëx? _þG¥jx¯ý•}ÿ?Öÿø ßü]X“MfÑ¡°Y‚´KÈ% ž™ï·Ö¼³þýd®F¡{ùZÿñЬÿuÅ?ò½ü­ù“ŒÞãR‚=Sû*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯&?µÁÿ1 ßÊ×ÿ‘é?áeëŸô½ü­ùŸïzg­e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuä¿ð²õÏú^þV¿üGü,½sþ‚¿•¯ÿ#Ñjxµý•}ÿ?Öÿø ßü]ÙWßóýoÿ€ÍÿÅו'Ämuÿåþ÷òµÿäz»޵É1»P½ü­¿øÅ>Zzg¤e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuÁ/Œur9Ô¯ï›oþ1CxËWó½ÿ¾m¿øÅ>J¢æ¦w¿ÙWßóýoÿ€ÍÿÅÑý•}ÿ?Öÿø ßü]yÿü&ZÉé©^ÿß6¿übøË[í©^ÿß6¿übŽJ¡ÍLôì«ïùþ·ÿÀfÿâèþʾÿŸëüoþ.¼é¼k®Žš•ïýókÿÆ*&ñξ¿ó½?…¯ÿ£’¨sS=+û*ûþ­ÿð¿øº³§éòÚO<Ó\$­"¢‘”)cÝ÷«Ê¿á>×G[ûÏÊÛÿŒR®gþ?ï?+oþ1IÓ¨Õ˜Ôà¶=7û"íCì!G·$Ì[Þ=hþʾÿŸëüoþ.¼Ðxû[Ç7÷Ÿ•·ÿ øÿ[òÿyù[ñŠ9*53Òÿ²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºó/øX:×üÿÞ~VßübøX:×üÿÞ~VßübŽZzg¦ÿe_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuæ_𰵯ùÿ¼ü­¿øÅ8|@Öü¿Þ~VßübŽZzg¥ÿe_Ïõ¿þ7ÿGöEÛ¼f[ØJ$‰! nA;X63¼úW™ŸˆÈñÿyù[ñŠþ&µ»o½ü­¿øÅµš™ë:†Ÿ-ÜðM ÂDÑ«©ßpC=˜v«e_Ïõ¿þ7ÿ^f> kGþ_ï?+oþ1R¯5’9¿¼ü­¿øÅ ˆ ÷=û*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯:ÿ„ïXÿ …çåmÿÆ)ãí`5 ßÊÛÿŒSå¨.jg¤e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuæãǺÉÿ—ûßÊÛÿŒRÿÂy¬ÿÐBóò¶ÿãrÔjg£ÿe_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuçkã`õÔ/?+oþ1R¯µcÿ1ÏûæÛÿŒQÉT9©ÿöU÷üÿ[ÿà3ñuOµk+5¤0gbÁv‚Y‹tÉõõ¯44Õ¿è#yÿ|ÛñŠ_øLõoúÞß6ßüb“§Qî58-S¢¼š_k8Ô/+oþ1U[â²§þBŸ•·ÿ©ö2+ÚDö:ò_®ï_úyúMoTÿábkÀ¿¼ü­¿øÅS¸Ô%Ö&{›‡}ÅŒ³O3/?*®NÕUTQÀíWNœ”µ"¥Hòž·ð÷þDè¿ëò÷ÿJ¥¢¢øip—~³¹‹>\×r&FæR?CEc7y6‹¢š§û" o… ³Ék¥Ínç«C¨\!?”•oþ߇?ç–£ÿƒk¿þ;E)Éh˜J”$ï(¦ð¯<9ÿì=…/å_p¼ðçüñÔ?ðmuÿÇ)á_xwþxßÿàÖëÿŽQEÒ}Ø{ _ʾáÃÀòÆûÿw?ürø@|=ÿì=…/å_pÂáïùá}ÿƒ;Ÿþ9Gü ÿž7ßø3¹ÿã”QG´Ÿv—ò¯¸?áð÷üñ¾ÿÁÏÿ¤ÿ…áßùãÿƒK¯þ9E{I÷aì)*ûƒþ÷‡çÿþ .¿øåáÿ‡Gü±¿ÿÁ¥×ÿ¢Š=¤û°ö¿•}ÿáð÷üð¾ÿÁÏÿ£þÏ ßü\ÿñÊ(£ÚO»aKùWÜð€ø{þx^ÿàÊçÿŽQÿ‡¿ç…ïþ ®øåQí'݇°¥ü«îø@|=ÿÿž¿ø2¹ÿã”Âáïùá{ÿƒ+Ÿþ9E{I÷aì)*ûƒþÏ ßü\ÿñÊ?áð÷üð½ÿÁ•Ïÿ¢Š=¤û°ö¿•}Áÿ‡¿ç…ïþ ®øåð€ø{þx^ÿàÊçÿŽQEÒ}Ø{ _ʾá?áð÷üð¾ÿÁÏÿ£þÏïüÜÿñÊ(£ÚO¸{ _ʾàÿ„ÃßóÆûÿw?ürø@<=ÿáì)*û„ÿ…{áßùã¨àÖëÿŽQÿ ÷ßóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}»ðçüñÔðmwÿÇhÿ…wáÏùå¨ÿàÚïÿŽÑEÒ}Ø{ _ʾàÿ…yáÏùã¨àÚëÿŽÒÿ¼ðçüñÔ?ðkuÿÇ(¢i>ì=…/å_p¼ðçüñÔ?ðkuÿÇ)?á^xsþxêø6ºÿã”QG´Ÿv—ò¯¸?á]øsþxê?ø6»ÿã´¼ðçüñÔðmwÿÇh¢i>ì=…/å_p¼ðçüñÔ?ðkuÿÇ(ÿ…yáÏùã¨ÿàÚïÿŽÑEÒ}Ø{ _ʾàÿ…wáÏùå¨ÿàÚïÿŽÑÿ ïßóËQÿÁµßÿ¢Š=¤û°ö¿•}Áÿ ïßóËQÿÁµßÿ£þ߇?ç–£ÿƒk¿þ;E{I÷aì)*ûƒþç‡?玣ÿƒk¯þ;Kÿ ÷ßóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}Áÿ ÷ÿóÇPÿÁ­×ÿ£þï‡?玡ÿƒ[¯þ9E{I÷aì)*ûƒþï‡玡ÿƒ[¯þ9Gü+ßÿÏCÿ·_ürŠ(ö“îÃØRþU÷ü+ßÿÏCÿ·_ürøW¾ÿž:‡þ n¿øåQí'݇°¥ü«îøW¾ÿž:‡þ n¿øåð¯|9ÿì=…/å_p¼ðçüñÔ?ðkuÿÇ(ÿ…{áÏùã¨àÖëÿŽQEÒ}Ø{ _ʾàÿ…{áÏùã¨àÖëÿŽR¼ðçüñÔ?ðkuÿÇ(¢i>ì=…/å_p¿ð¯|9ÿì=…/å_p½ðçüñÔ?ðkuÿÇ(ÿ…{áÏùã¨àÖëÿŽQEÒ}Ø{ _ʾàÿ…{áÏùã¨àÖëÿŽQÿ ÷ÿóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}Áÿ ÷ÿóÇPÿÁ­×ÿ£þ÷‡玡ÿƒ[¯þ9E{I÷aì)*ûƒþï‡玡ÿƒ[¯þ9Gü+ÏÏCÿ·_ürŠ(ö“îÃØRþU÷ ÿ óßóÇPÿÁµ×ÿ¨î>øRî?.æÆêtë¶]FåÇäd¢ŠNrz65FšwQ_qÐi:Mއ¦C¦é°yçËs62KX“Ôš(¢¤ÐÿÙtango-9.2.5a/doc/src/advanced/line.lyx0000644023471100065110000000245713034745264014534 00000000000000#LyX 1.2 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 2.15 \textclass book \papersides 1 \language english \secnumdepth 5 \tocdepth 4 \inputencoding latin1 \makeindex \paperpackage widemarginsa4 \layout Standard \align left \latex latex \backslash begin{picture}(0,0) \newline \backslash thicklines \newline \backslash put(0,0){ \backslash line(1,0){400}} \newline \backslash end{picture} \latex default \the_end tango-9.2.5a/doc/src/advanced/control.PNG0000644023471100065110000004455313034745264015100 00000000000000‰PNG  IHDRe%‚W~sRGB®ÎégAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<HéIDATx^í œUÅïyï1'æÍs^üd:óŒQVYº&,Ú€J* ‚¶¢ÆF@[i@¡A¼n±ãˆCÔD·ttÐNÄш¨\¢é¸ÄVqi÷6nͦýþ÷Šª:uê,÷žíw>çs?÷Ö©õ[ÿúÕYîÿxàúöíûÕW_-X° gÏž[6ÿ¡6Ø“Àÿ9ÐõÝvƘ~'Žìóνvþ}ýͳڛ¦¾³ê8ì  @Þ½u2i)Ã+¿Ûíâ‹/&±øðþíw×¾ó›“ßZ9;€€[‹N8ÄçΗè3+JžÜÞ]]Óíƒ>8vØ!íÿuá›·œôú •ØAÜX8±øñ_/þòéUžwJN™°r£œ[·Ÿõ?øÝ{翵zÆ«×ÍïO_;ú¼¥åó— ¼áŽ \9øÄ™}6ÿùþE+¦,¾ôÈ%+޹ú—._qôÐqÿúÐ%C…„ø i#°`B¯Ž'V¾sË žwJN™0nQÎ-«[šç¾Ü8®õÚQüþÇGN™Õ¯þ²«Ž_tùðSg–¾Ú¶áãOÿâ‹'¿üêů>ÿSÇ'ëGÿÓß_\.$ÄÏ`‹æ)l8kòüã{~ôÇ^_y¼ç’S&ÑÏ­[ß^¼yÏœ¯ªö W=ïSÏ[6búœâÚ%gÏ)ßüü}ÓÏã'CÖdÏ9°ätî‘s`‡¾Ý¹ãå•“­£/ß4…B|ê¹¶'œwìAd-­×õ¼SrÊ„UL™Û’ûhv¡\ÇÜî™?”åÆ'd!tH“[V/ÚîšýüŠÂþû‹ULÞÿ¤‡œ4óàºtŸçþÜrì‰û_2gØ5—Nš5÷ˆŸŸÙwÀ轿þp9­a™í–©±Ÿ´&ÏO´#¶~²åÛohÛùæ¯_{¦÷Öå§zÙnzñºÊ¯?xõÛÛ×Þzéãó³~çNŸúô†õÓÆæ¹P«¼å`%¿à„R!vhÇŽ¿½ã×.ÊŽ~´¹™TÎg¡ÞªšTuãÜòß×>wÕQžwJN™°º)s£%L»S,Ê5ÏÍJkå¯Ï-«¯Ýqî¦Ë† ûÚK†{Jïã~Rqìu ¿âê±›^¸wì‰_pñ¸¥™ ÏsÒåWÖ ®ìñ» Kå´†!KO)#óâM~Þk&w>úfû—Ÿ|ôÜšç®>šåÆ¢½ñÀò­Ÿ¾ýí7;;?z㕦YVAhÛgíd‚þÆý ,ò®£—çÑ•¹£;·ýý}ú¾éòáv5|õŽó)áë×>úðZúrAíÏï8ù͖˾z?;P·þᛸÂ)|ØÛë®ßÚñÕjÛß?xgýlºlKòJÓ9_¾ûÒ7Û;É;ø{ÛÓ¯Þ9G.Ôöƒ?ÝEu»ýÆÌðÒžÓÇö™BéÜJfŽí;~hñÕ5¨uvíµc("|ËC×På©?²N9“ÖS µe™?pï=[·vžyü°Ç—þì…_K ríÝ|×Sª-ÿÂK×Û¤Êf¨±ŠËl{‡Õj†K£Chãùc{´ýᪧ.;ÒóNÉ)–­2· 'ô²Ó :$”ë*7JÎg®Ï-«4ðžn"ìä8{JñàÑ?œtJ¯eË+—-}êÌ£îûÝâ_4žyÉŠù‹wâÉúù“æù¥rZW!¼ÑP·×ßxó‚‰G<ìò% èÐ3ëî{lI9…[fwcíÐËëgÑÏöw·¬>ozóÁ«èçkÏ®?¹rȱ#=óÄ#Vž,Cúùä·VÙÿÎÛn¦ïëïúÅ“ËÄö²:úÊã¡¶æäúY§Ñ—?®ÿïó'ô{*ù͵Wgë…?ž9a(•²æîÛ®­É¶Ý.|ËÃÙyÍ‹¯™<²ÿ-+³#aÝê«XVÛ>ÿˆ~^µøœc†ô=÷Ì“_xú±_Ÿ“mˆ]¸À37€»Ž?jè)£[0¹¬iö@BÔrÁàkj\[3@Ó^ C‹sñ,à÷ÝsÇ/fülìÞCKvÌ™é…P[–ó”ñ£Èekºõ?¯ŸVöÞ“MßìØ>iÌpÿ]¯1½Uhz‡ÕŠo¸£=Ÿ7æß_½Åc— õ¼SrÊ„¤Ìmîøƒ¨Vô)ì,P(×17ŠÏ269+ŠÉç–Õ‹ÖÛjŸ¸d°¯©0fòS§vjÍ¡—4ŒYºì¨ÿû“ÜÑtÞUËÇ­^9kÄ‘û4õg#Æx眾rZW!¼Ñ°„uúΩ*¹`rú¬ãÓ©£}ìâA, ’ª‡,;5ûóÛo¿}x¯5óv~úýÏïŽöšSÕÿ—ÓС;wV èµr†Øä¶Go¡£+–-:zP¯¬7eç5·Ý¼réÉý©E|)WœVzïœÒf”^?Í!œïZ©8¼çÎ(ýëš+É9§Còñ›yô—ge~^F5· xv~ö>¥%餙Ț:±šöZXd†<1VœRWUrí¥-ó¬–*HÊÉ­:[‡®š=‘†>xÿ½Û¶V=dÊ‘»&仼O]¯1«PöŽÜpG{ž^±ßŸî\¾úÜ2Ï;%§LXAÊܦU@£O¾e EpÌeÂ’[›¹UŸ[V/ž[5ã¡ K…ý¶sû ù£ÓÏè={îÀ Y¿pØÊ[Ïê=à€ïý°û%ûöR´Ÿ?¥¸iöarZW!¼©mÍ9ê+Î=ø‘ƒúX‡OÙc™ãþ¹»^xBé׿M1'Ž9â‚Jþ«®tÕÇñy²ÑEþÅüI¥-Ûå_ íð’ê=šüð¢ÁÛ¿ìàñ±ïŸ~rÊQ¥kæ–~óbÈ¿ Rî›»;­>|üÈrk—¾WÏÊ=ûøÓ§Nºáº+)ÏÏ>ýøÆ3û1hvá<Ò·6¬¦TW_NÃ~íbÇiÚËcò‡XY|Èó³!†9 ½Ïçó×§¢Ÿ÷4Ý<¼¤çœ‰%þ»^c0z«`½¦ì¹áŽö<#§wœ[Æï4ü4»™’S&¬ »Ü˜^EÈÁ17Š#ˆkµ?+‹Ï-«ÏÿjÆÃ J…ýŽÙ},:jÜc'6 âßþ_ï½?qP¯²ÿôãìQ¶oÿ¡\¸è´O|Û¬Cå´®BøîÙöÅ'ôóì3Nš=©üñš¬C$ |4ÊŸÿùòš+èçö,œ:âцŠþúôõ¿¢Ÿ4sž?eà[ßFßoj¼šü r2ùzþåž‹èÐæ§Ÿà‡÷3O=A—^4ÿ—ÓJ_Y³‚¾?ñØ#‹NùèÒ#(+–Ü6üþ¬ü~Íïž2ì¢S‡Þ|é¬WŸ’¹ú¾ôÈﯜºdê u'Sœ÷Ûß=r@Ï»gÛ† <½dÄ–×_Ù¶m믮Y²vñ°G.*ßtÓ4j5‹¦i¯†áŽÎ/è(Íé¨z,!²«œù ï!RóJ«†B„ɹX0y"¼u½&•Þ*^±ï¹áŽö·¬^¼póŒG– û¯Ï:t¯vÿ‡þÏÞÿ{“O«¨_xþäÓ+|ÈÿùqŸ}þí°^ýÕ¿]}ËéÓÇßy~9­«¾{žûÕYoµýV >ù°ý©;/åñß)áçÝ+/§Q·sÇŽÏ?xã…»–ÐQÊ„9ºël¹kÕ‡¼OÎÿ×ï?¸úúa¥½ªGFçy¾žû%Juñ…çÓÚÕ´¯¾v!¶¾ôç3+ûRGÞvÝů½ò×Û·ýÙ¾géüªCXvá·_¿äo¯¾Lñwt~ùáËZ®™yÚ¨bŠÿ¯g½üÂÓ;·o¥ýíWŸŸyÚÒ¯Å'Ù†ËÿÒã{½ý¤ÿð>·ß~çM7Ü4oþÙ÷Ì)•Óº a§t²!J8wb¿Ñ{ý¬Ïcõš[Õ‡?ħ˜üOškýüèÃhÔ +9xæ‰GS—¿õFeÂò¼ù첓FZ1 çÐþ=Ôë”чÒÜäWg‰5¯Ö›ò<㘾+NÛMcnU_ vH1-y’~i¤ë–]qjé)£;j`/ÊÚ5z`Ï ÃŠ¯Êe®i¯†á´1}(+'Dv•3_a9ë¨ÿ®×ŒÞ*4½£©°Ò¶kGï·ùîå÷œ_Æï3F Ù…È”œ2a™ ·+ª‹YÝä Ó!Mݲzñ—[g>¾¸LØïžÓ§ÿ°¢£Žíµø‚Ê›®›>ñ¤aE‡üsqùþ?îý/?î½ÏòË–­ø‰ë¯»þá%rZ·!ìF Ú)ášye—ZJÎ*ÍAŸXºø¤Ý‡øh“ÿùñ_Ö­ÍœÒpê +ÎÿÊóI/–-š7j`/Ê„bþqqÙ-µeŸTFs Y4¥ôWgg…z^[SF—'©w—MÅößž_vqu¶n—MÍþ¼kvÙò©ÙêQÈ¢KWÏÚM^¶pJ6>•~ù©e¿›“Mrßܲ+Oÿ.ü„ÒåSËh‰D.#}tQÙoÎ)[vr)eN¢¾dNwh¯†!j)UÒê !²ž¤Ùª³á!o]¯I¥·ŠïzSÑ;š +mûœÑû={÷òæóË<2a™G9·ÜõÔ[g>qQ™°ß;¯ßc¼ nôWOºpÞäɧŽ?xÀÔsïþʇÝÔøÁ/<÷âšûÿðð%#å´…yùÎyo½öÒ7;wìÜúåÇ{溋ϡSÄÏéKéð•A‰!P0«˜uTV/èLày§ä” ãåܲzñòoÎzjÉaàÂ3ιôÒSéF ±Q¡T …†H `VqÆûùÜyJ>³¢äyÊ-÷üÈmgmZ:;€è ØÞßéxO"€¤@V/¬Û ð@4º 2˜®>Ò£Dl·»# á i&ÀôAÔ‹ì›b°€ÀžÔzAïA µ^là µ^lÅ µ^|­Úʤb±0ÿ®ÌÁm ‡ =$Ék­ P·õG|ðL@­_ª6fúÊC,Ð1‚&­·óQ¨c%]5ÓUdÇ¢Â% Ö‹ÏU3}á(D°Üenެ,¹PÙÍ1©_s+¾²E&s¬›•‰²nÞÊu¬"€@¾ ¨õâ3ÕÆ¬\8Â*¿+S)ó—s¦!¹œ›&‚¾n¬-ªg –ÜÊ*Oåš@CÈ+µ^t¨6áÄ΢°@Íw>‚2[»²ä<…â#8ÖM™¡c%³uŒà­\ÇŠ!ä€ò~­OTÂ>PþnIŒ2CM  MV¹r„}}X‰vq +éªÉ&õ1,Ñ@ tjÿâ#ÕÆL_8ÂÚ}Wæ¦ JÑg+Ôʤ>>ëiR„Õ:W‘Ý‚B|(0µ^| Ú˜é Gø@»ïÊÜ4B)úl…Z™ÔÇg=MаZç*²[Pˆ& Ö‹÷U3}á(D`?•©”ù³@¹h…ËÙò¥˜ÔASgMŬC®šlWse3MJG‘€Z/ÞÖL;ò1²PëÅ;ÒÆŸÕ­ïr4ÿ!Ê‚X ÿÌýç`W=“œ£Ó “Ú"ÈÔz±€HÔzñ6¨õâ l  PëŧØ@@@" Ö‹MØ@@@"ÿ'SÐ SRˆ àN/j–®æ.täÂ+±›ÀW\è)E4ÿy*Æ·™Æ‰+© P©ízÏ 7Õ &O½þyw^/0ÌM¬ÌY!&#`¤Q Ò/K/0\™5p¹Â…ÈFzq±°ôÖïÖ AÌ-1Äwð/Å‚=CeMR„Ÿ…™¼P% MŸUïu>D>šûЗÂ?Ïæ¹tÆBó\ $L^8ŠÉADô°c"®Bõi3l#Eƒ^˜³BLWò«üÙRðA”^‰¨Lhç­×GìÚφŸ<&­a©<¤q@솷UyÙ‘QbÑ4ƒÜ:Ä'·Ó>Mø®† ";¬_øô/”s+?j™8SeBÍÔ&z¡” Ö°Ï{;¡±ÓG½àó—µO£kv†½€¸%GÿBPA d½Ð8 úu½Ð;òÞq´ §q9Ç„®rÔ •Ô[ôÂíhAü<ê…å)ÐHµ@£Ê„>ý kxËã\)%Ž£]ö&øñlXŠð/ ?RR¢_½à=A ø)€Òq°æ)† ½]œ Á Мùùúk&òàT&$ÃμôiõóÃ"¬¢1IÉ °™èEanÊò¹~ ²Äd½HLW¬!Ћ‚¡Ž\AЋÈuIä+½ˆ|孂Ћ¼¡MlÆÐ‹Äv­càŽˆA  Ö þ%Z¡/O8V š¯üB­@ aèc«Ö«´‡kè¢ùÖ/Ô F@§¡«* )Ћ(¾^0R&‚Ê€€EÀA/L^08 É&@KžL2œõ¢›Óö™v³K­O…£ !@a½èÛH/4k6$Žz±dÏâS* ‹T@@C€œ ×za¹ ”Rø®ùL(U!–ô6 ± àÅ¿ð©<èE,¬•FzK0%Ž^°E ª#ü ÓŽB<ˆ/za·äé¸!G€^DÀP0%½0%…x Р؀€)¼è…|_«æ#¦Ý‚x IñÐ ^€"‰•ŠË¢4õŽZœ( ΋^XÞ„pǧgÿ"1zab‚Q0 ?uˆrí<_¾½Q‹ã§/O ½©.Ã(¥ @D¹QÓ“úÕ/äS8½`häJ;š—•PS@/äç([yÑø8ú£VMôÆa˜‰¡ÿœ'V|¶J žÛ¨ÌÙÆŠx3Ó@p´:¾Ó ™ÛE ª¬@¼ÏL\ë…l|ÿ$ˆ J±°f.”Ð.‚‰^(k¥¨|YÒZÉíh({E3–ôu0ìcÃÊxh¯ž¤rˆÊƒÄs¹²‚^ZŽy4wzÁòž1•9µTÀqXZ=êG/ìNt|5ìÄKN+™Òæd½à‰ë•Q¨‰à¼È?ÍûÒ±-v™ Ý$«ƒR/¼šTVLW9ÛuŸyA/ÌÇ0¦½0ÌZަå0“ǹf¼éÏê†GíÌQ.W~™Ð%Í©Øj“|4CH.Ë[†&E˜äl¨G‚÷aHÌ[%Må/ŽaÓò-`½PºŽ&}c×È‚é…\såIUWöjç­˜4ÓÑL¡I_˜ 0ñ4#Ǥª²a‡ÚUØÉPþƹ+掽n„ õB/Êó³cãíòäêûÃð¨f8úæö}½Pw¥vÀÝæl®Ž}-0ÑÇÁR€ëEöù1z#Žò3‡ÄU“ ½CE0œhjÈ×GòÔ»Kó“­žžI>®XyËÐDMr6w”ž [VÑ×Wc'O‘Ö [±È]þpû-¥KbbŽì„£?+ʧ/;AÑø2Ž#_ÈS_y–›^•\É™[VB|“Qm‡o” ˜x%n;H#Ž&çó¨ÅÉ“¸Ê6`½Ðûè…e|Êa¬lJ?EyR’“{Hk8¤•ŠæY,¡Ñä£i‘ò¯Ú&ê d"ë²>‚ÞqsÕAšÚÊ-u´ÇþâAiºÃm>®Æs¾#¬ú}ÍIÞÐõ6„䎷s4¶“6äyèx~x8žíhè] ½°s‘Üæìù| ÛCdµÀQ =˜A^“¬Áúymyò2wÔˆä5-*0€õ"@ÿ¢À Pô"ñ&©ú9›æΈ3ŠKõ q驸Ö30½°ŒUs§á ?¾4QsH6àõB³„½H¶1¡u‰'¤^ÐbgöïËì?I/Ü^RM|  #Aê…^,Øúô"Fƪ‚€@ H½à= ~à ‡^Àþ@ Ö‚Ô Ç• èE¬m•ôâÁçÞG4€^¤¡—ÑF†ô"ŽÈÒ@z‘†^FA ‘Ö‹îª-˜v#÷BÖ‹›M©V ûf"€@ÂÔ‹ 6›^,ØÑšŽ,@\M/ȱØn³ÙéÉ ¥€^¸ìbDÀ„£L,”î…^,(‰£s¡y¬[ùÆ4;–vOÇ᩹À¬Å@˜za2ï`q˜²zЋ¸!ê¡ëÍ/„}an›¸PL6ÑеNþJ/þEl $¿zqÛƒ›j–®§¾˜7ÍGrÂà L,˜Á¾DM/ä§fxÊ×êò²%·{¯9^Ä<ð¥–X¸•ŒÄè…ò;««ì¤Dp‚è'%Ñg•§îG¶ àŠ€/½`2A«Óƾ–­Õ‹]W@¬i‰5a^†Éd„Å‘§$ÏG4kŸÂ2Š!ˆ‹!@DP¬ô¬ª°+[e®ò|$‚záv­D¹"‹iH(…º"àK/ò3a+»6þž Çë#Ž.}àþ…<ÐLFؼCéøðášë;®º‘A p¾ô‚jão½S^ì´B²×PÙeÃÛ´”b¡ývGõᎢ Ñ Ykïod~øÕ *ÛÕÊ««ææNëÒ)yÂeÃ+#<ÿzaÁPBW.RÈ1õ:¥÷Aüt6Ò‚€O¡é…Ý“f._dÍ]FÝíz8ŽUáDmøÓn`Û]æ°<!‚ì&hÖ>5‘©òÙÓHþ „£Nwvjæ)êûµ¯S(OÚæçy»ÅH”þˆìz瘕ÿÎF à“@z¡ñ,øCª[¹¶ç¼<œê³Ó‘<@/\½ï—¼ÝcìúpKJ »É@À7è…o„ÈRC 4½ åKÙ¡°›ªPLø©±I44ºBÓ ·³K/¢Ë5¤ˆ™^`ñ"é‰öEš@zax}Dޱˆ´)¡r) Ph½HR4Kz‘Ø®EÃ@ p!ë…«{7o<2pE Nzñln«©©éììdloo¯­­¥@WmFdoâ¤ååå =ÚÛª*+Yk««+ÛÛ«ëëë¼5©@\ˆ“^´¶ÖvuÕ·´””—³F’‚´´4P «6#2€€7qÒ‹ÊÊ}:;i:RY\¼K/èKMMQggưñú7zš<®jX&šc)Á¾ÅÇ…‘XÂÔ ówsµµµµ¶¶Ò'¿Ñ²…ξ³OÚì:zÓ?BÓ Wïþ¤EÍææ¦æ]ûBŸÙ/M«V55å¾ä>ër›’{ýŒæ[ÊCš÷VÈñY¹ÂÛq„@G÷A®$Ÿ§¦’ò«…»w…ñáÊ7}8¶È "mŒ„¦®þ‹€„ “ÉПuµµ´×ÖÔTWWÓ̤¡¡žÔ~ÑoŠ@[cc£áJ/”2¡Ñ6¤ù¡n'4ôÂ$+9ŽR>ä@ÞX•u³5Ò#‹GUýˆ^8þ]F%o¢1“ifŸÍMÔrR‡¦Un]dÕ8æþ…ãN¹æƒS£vƒÙ±2B»ìtM£)Žž‘²ÁañcˆH ¡é…«ùˆ…’Ôü‹--äW¿Ñؘ¡‹© õõ¤zܼ›ígøñ'[Á›ÐÌ; ÏÌWR?ÒÏ2,žB­äðX:*Ðô‚jo¾ÞÉ7•$ƒ¦!-ÍM¤íí­7æ–0tþ…p,€^}c¢ù¨$¯vn—ìïÈ®“¡Tœ@ì™D“@˜zAD<ü¥¢ë äSsAbÑÑÖÖHëuušùH€CQ?£‘ #V3ÀL*i7’õ#\3r¬°]Áˈ¦q£Vˆ¥^R‡uëÖ‘Ld—AËvz¡<7òÓ ýªÝéW3`x^ަ½úJ >²IC¬äÊõ 97Ç!°Ò+QàÆŠ C'W½`àhƒ®’ЊÝ!®¹í"tʨ$ƒ@¼õ‚d¢Çw¹Éè´"K d½ðù<;=ŸjÝÖIß#Kdˆ±^øÔšdôZ…$½À»3 iU(+©Ò¢xwFR-í*$´èÞQH«BYI%½ðùî »e³7fRÍíŠäë…Ïwg°ñÏÚõ\¸1#bO¨F² $_/ü¿;Ãü)‰pc&ÛRѺ(H¾^øw†‰sÁú2ܘQ°'Ô!Ùâ­ò+3¬¡Ûü¿;Ãdaz‘ìÑ‚ÖÅX/Üvžçwg¸-ñA ©R¤Ô…Þ‘ÔŽG»@Àtérûî ÍÕ“ [Ô<¦‡žFðO uzAÈÌß¡á›0ÏÓÇ#ð@ zÁ0áÝÌIRN ½zwg¤ÜôÑ|Ò«xw†sA’”H¯^¤¼ãÑ|ð@zá’€@J ÄR/èý7bee%½Õ¢¾¾^ÿÏf)íX4ò@ NzAº@±7eUUUÑ'½ã—Tƒ…Ð!G,Y‚ÀnqÒ‹êêÊööjús¢òò¢ŠŠ ’ ú$ƒ½;‹þö¬ººJÙ·ü‚ø¹ÇÁOZ$€@˜záöÿIZZººZ[k蟊²wj64P üî,¡c„qŽaŸÃEB!š^¸ú¿åÜs ÅÅÅ55EšƒðzÁ¿;‹¢É\d÷‡]qá½²¾°˜JÝá•ï¿à½›Pú…‚@PBÓ öÏ©]¹Íñ_T+*Š‹ŠºÕÖuuÕ56Ö‘(ðzA¿ÜØØ£«+CÿsFÑh’¢÷/„‘o xù‹%²^h4HV z ù€@¸"¤òË,,4¤ÕÕ%L/hÏd²¾yôYTT”ÉìEbÁô¢º:âS/xAáÓ Rn”G¸]ŽÒAÀ3ÐôÂÕ|„ùÅÅY'‚öËŸ}¶¾££±££š.•lÜHY).îæÙ¿°›’¸Õ Y ž­ £F 4½ æëlý¢G¢ææbÚ++³î…µµ‘CÑ­²r¯ææzÚé¯T=¬_(—?ygAXæP®eÈ«|OC2¢f÷¨7aêÕØqå‚o] ¡K¨$û”WtkjêÑÔÔ@_è'-yÒåUŠ ¤ ¿>bw¹D¿J긆ê8'òÖaH!ˆ“^ïPRRBË™t%•¤/h£/ô“éEÐè…æ:…ò£"È©LBBìl > ÄI/¨©---ìØ3™ ­kæ;3ô“éOH  '3½@w‚„H d½±å(@À-ëݯᶵˆ à‡ôÂ=¤tH—^<±àšM£ÎÙ¼÷(Úé ýLWo£µ à@ŠôbÓ´E$;ÿi"Û·tµ¶{9êò÷wÊ1…»?5Y™ÇôסH y$½ Wb·Xô›kéÅuÿÐÇÎË`#œÿúÁ’€c汫‘5ø&½ ÙÇ.Ï"óÒÎÛ?¦ï$ä_^Ðn‡Q·üh‰3bÓw‡"È#´èÅÎE¿¹¼XL꾟F/,Ãι`á&nˆcÌ<ö3² Ä[/äGà­ -X°] èE†„B³kgÓR ÚÏý~oWYÙyÊLôË¥nËE|—@Zô‚5™F°4‚‰í«ÆMsÕæ`ÓUÂ"½ ¾té”d‚W ‹Ì€qnÑ›«€yL·u@|…@Šô‚ø’—aé}qëY`&Š¢ÐèH—^øçnî2˜Çô_+ä…!½pÁÙ\Ìcº(QA lЋ°{åƒ@|@/âÓW¨)„Mzv |ˆèE|ú 5° @/Âî”ñ!¦^Ðëÿ孻ͤ¨)$–@hz±AµÙ‰ Ol' a ¡éÅvÕ&ë© E„^ÄÄœPÍ„G/h"»Jç‚Ä‚b†â\ØýObÂ-Í{~õÂü?“ù:^äÔ~ß­L&ržEÖQêE¾Çs¾ó‡Y‚@ìøÒ K,Øß&ÓOÃö;ê ëSÖ Ã*åǼò;ÿNA  †½‰hé!àK/˜Ltå6Wÿ´î_/¨‡ìƳ£FXi±ò„^¤g ¥†Ö ùyÊzØèÅ®uM6-±œ ú¢ÌÄ¿^XÙZYÙi!MDdð¥AÏGØZÆn±°Ö3 õÂn’Â’k´€O(;ɶ´Ì øÒ *ÆÇz§°ØiýÌ­pî^ï´½íÂn¹Á|>"û<8ÌGÌÍ1SBÀ¯^&W+ +ÍG”÷_° "ìR«ã•TWzay²¯!¸zI‰Y ™  $š^ØÜ ¾‡Ó‘»ób×$E3%‘¯qØ] ÑÌ5ôsX€A/”JÁ ÷e°ÅQô€@è ­Ê;;•Ï’°@¦#ЋР`ü º†jŽzaÎ 1A jð/Ñ å$þEÔÌõI9¨è…Ý”“‘”(š)!è…ãzçžkŸX錔Á 2©&Ph½H5l4bN d½pµösÔ¨>Äž@œôâÙÜVSSÓÙÙÉÀ···×ÖÖR`ìû 8ˆ“^”——74ôhoo¨ª¬dl««+ÛÛ«ëëëâ€u؈“^´¶ÖvuÕ·´””—3ð¤ -- û~@@ ⤕•ûtvÒt¤²¸x—^Зšš¢ÎÎŒ!jù‘Ó¿ðÂñ±W}“·~Ò@4pK L½0¾­­­µµ•>ù–-¬pö}ÒfGzáÖ>x¡é…«wíТfssSó®}¡Ïì—¦U«ššr_rŸu¹MÙÇìáTÍK:•‡ß²c•%?&ËWCùJ¹žÊJZ՞ʷ ç_ÆŠ iùVhJ±kUJ„¦®ÞýIBÉdè>®ºÚZÚkkjª««ifÒÐPOê@¿è7E ­±±Ñοp¥ŽOÄ+¥‡4ym¡^˜d%Ç‘Þwœ|)';¼úh^’“òfFH/ßýI—QÉ›hÌdšÙgsu©CÓªF ·.²jœ sÿÂqˆ 'aóÁ©Yž°Ž•ÚeçCi4ÅÑ QaU8å£(=ÍM/\ÍG¬þ u ÿbcK ùäo46fèbjC}=酾τé€rdº–‚·"OFLrêx%Pêˆ0æ5““äé9élihzA¸Í×;ù¾!É iHKs©Fg{{ëÆ¹% ¡üXòð]¯J!K–äÕÓûPv %m2õÅ%£(=­S/ˆ²‡wR*ºB>9$mm´®QW§™¨Ž£Ñd @鯛TRžñ²e2‘-[_a¹½)LϰImKc©Ô[¤ëÖ­#™ É /ƒ–3ìôÂnp ‚ÈÃÉnuÀ²!~Z!Ú ?}%ùTækJ—A9oÒ×Ü*]ža)µ&µc) «^°¾¡U ºJB+t‡¸æ¶‹4t$Ú o½ ™èñÝFîFx¡H3õÂçóìô|ªu['}OsG¢í P1Ö ŸZS¸(F -zwg$ÌpÑœP¤E/ðîŒPÌ …&Œ@ZôïÎH˜á¢9¡H‹^ø|w†|„þ& “¾´Ë“O«,E™¹p/¹cìn·»ÉBy‡ˆc),BbnÓHLC ;NŽ–|½ðùî å-Ïú4‡–>O»äúl µúÞ¼E‚ry32óŠyËß’$?É]¥-L‹\U©`‘“¯¾;CcšòéÚ± ù$&ÉƒÒ e+‚Í\#4¬ ùD-{Rvœ\p¬¬†Ø¹fÊ Øi¨7muìúøFH¾^øî ~¤ –d2à+ \/”Æmgšr…5É=ŸQ儼Rðc[?„%Ï\ï¬ (K7¬’g ñU Vóxë…üÊ +Dè?ïÎ`'4ÁŸç äŸJ+1Ô W*`îœk,Þƒöª’LÒ°Âú±í\ƒÚ[• O½þ9iGÇGí´w6dpWWûA;=EÊ+ÍÂÏ}S~Òº•jÏïΰ3)ÁÝàëcbO†z!“I«Ý–®q|‡¢¡_ l…ãÉÜÒJoz!'W6‡&Ÿ”0M›ôTìâÄØ¿ðÀÚû3ä òôëᜠ½Ðë…’4y{‹éè :DŒ3IÒ¥Ô%nßa¨ü‰KÖ“s”ÉÉ–?KN(ØÉS¶Eóä~ìX9Œå–:ÖЃ½ðÓqviS§ÂüÝLd·VéèZ‘e÷^© V&0/È[L~Êõñ9QžŠY‰²Š)ë/÷S¾§žB»ì´Iަ“|ŒäÂä™F½`dñîŒÂX˜¬•…)7¥h\³ü‘œÓ«xwFÁL÷&b=Ød·¨` #RPzõïΈˆ ¢1"^½ˆQ'¡ª Ћˆtª1 K½  ô߈•••ôV‹úúzý?›Å PEˆ 8éé=<ÆÞ”UUUEŸôŽ_R B‡ 1±:T3®â¤ÕÕ•ííÕôçDååE$ôI.{wýíYuu•²„Ëøž—è±<W3G½"¦^¸ý?DÒ…––†®®†ÖÖú§¢ìš (¿;K€#Œs û€ŒÙ¤Ž@hzáêÿ–sÏ}4×ÔuvfhÂëÿî,Š&ÿq‘ÝÝ„Vo+ïíã²ïJÝn.0¼s1u††'‚@hzÁþ9•ž‚¥Íñ_T+*Š‹ŠºÕÖuuÕ56Ö‘(ðzA¿ÜØØ£«+CÿsFÑh’¢÷/„‘opù‹%²^h4HVD˜ á½ÿBÖ ùeVÿ TW—0½ =“ÉúäeÐgQQQ&³‰Ó‹êêlˆO½àEx`ÁúéJ/<¯˜ÀBA RBó/\ÍG˜Q\œu"h߸±üÙgë;:;:ªéRÉÆ˜Õ‘âânžý »)‰[½R²{l)Rv€Ê€€ Ðô‚*g¾ÞÉÖ/zô(jn.¦½²2ënPX[9Ý*+÷jn®§þJÕÃú…rù“Ÿ›Ëʵ yuƒ§É0±Eĉ>0õ‚è8®\ðéR]B%±¨¨Ø§¼¢[SS¦¦úB?iÉ“.¯R%qýõ»Ë%úURÇ5TÇ9Qô5@œô‚|‡’’ZΤ+©$ ´xA}¡ŸH‡(‚F/ø»0”ƒÙñ²«ùõa™Wp1ð’A NzAÄ[ZZØÿ°g2Z×Ì-vfè'Ò¡dt Z‘%3½ˆ,GT Ò@ d½Hb´C ÆzQÈÿ"HL£! à‡ôÂ=¤tH—^,ÚÐ0jÓ¤½7H;}¡Ÿéêm´üH‘^LÛ4—db¯±½û–ý»¯Ýº½ÛJ¸%T“¿yLÇJ"€@Zô‚\ &íº3·1½è¾r_½—áöÑþÎ ê?öS™‰yÌØŠiÑ š}X0¥ TƒäƒéÅ÷~¤$Åßß%?rj§#òó&þcšt$â€@¤E/˜s¡‹î“~`8e<Y„ç‚­‰Y#@ `H Þz!?o…íÏz4Éí¼gñýs÷…^Ú ¢@¼õ¼ÿh>’}X{nBJA;I†+ÿÂî9ó•ó˜æ DL(´è-jÒRÛI)H#˜gAû¸U“\é…Ýb‡aoA, A!Z ¤E/=]:åe‚‰Å€ÌP}¯(—$ä$æ*`3‚æ‚*¥œ@Šô‚zš¼ Ë­ /zÏ‚_‰ä­Dž˜K€yÌ”Û%šMéÒ‹<õ¹ ˜ÇÌSU‘-ø!½ðC/›Ö\Ìcú­Òƒ@~@/òù‚@ @/’Ø«hä‡ô"?\‘+$‘@ºôϳ'цѦÂH‘^x~žÝmo8>Wâ6C»øü®úG`ƒ*ù¤œ@ZôÂóóìní#Àq«¿ž"</\©±nq[Ä ´è…‡çÙÙ”žõ,©£4°´ÂHVv†PÿÓÊDH¨ÌY¨®àbðK -zááyv»Á¦Q>‰ãdÁêHMA&3>ô"ØáÜñÖ‹¼>Ïîg˳åù)H/ð/0àƒ%c½pÂÛóìÊUÃá­ñ5„l 3Tú#Ð Wf€È> ¤E/®ºÚZÚkkjª««ifÒÐPOê@¿è7E ­±±Ñοp¥J1Ñ ~¬*…Æqºa oËzìDM.—®G^V«ulQô­5 Š@„ôÂñÝŸt•¼‰ÆL¦™}67R‡¦Un]dÕ8A EùŒm>85zaâȸÕ¾ÉrZ;'Hö#tJ‡%(£D>‘%š^¸šXøHÈ¿ØØÒB~ùº˜ÚP_Oz¡G,øóŽg~Ça)x+B†Âpr<± ³Ã䎕Tf+¸-Ž’! Ó'¬¡£bM/¨öæë|SI2hÒÒÜDªÑÙÞÞºqcn Cç_(‡„ì› ?Þ9NÝ&.½ìàðÃOyVWžØÍ+¯)Qö’}Ñ´H3‹D&Q&¦^ïþ¤Tt„| r.H,:ÚÚi]£®N3 P/äá§_Ô†œÆ7©¤ß¡ñGôzawÔÐ!rÌ<ʦºy K½ v’:¬[·Žd‚$ƒ¼ ZÎ°Ó a*°òDÊûávg~å€Q&T®Ú9÷ÁNžô#\®’¦’B¼¢œvy0;$‰)¸êÃM«t•„V4èqÍm1íT¢F ÞzA2Ñã»Ü¨ÁE}@ aBÖ ŸÏ³Óó©Ömô=a}ƒæ€@ÔÄX/|jMÔzõèH‹^àÝÑ·EÔ0úÒ¢xwFôm5Œ>´èÞ}[D £O -záóÝòMú›,L:Þ.O>­Ý= rþvwmÛÕDy[ŠIµ'Í’¯>ß¡¼#Óî0fIŽCQŸ§]r}¶Ž…ZVÎbòŸih»+É׋ߡ‘ùnnÇnà“˜$J/˜XÈ7q:V@ ùzà»3x½†œÉ€¬-p½0W8ùÞÄ[/äWfX!?ïΦ™Y9öLf†za®ÂŒCcÐ o£©b¬n;Ïó»3d½à‹Î·^˜«€‡˜n"~Ê ¤H/¨§=¼;C^³PN=BŸÈ–rËFóóA ]zAݾ;ÃP/xDÖåôÄNbL®èW+…™ŽÉä(¶…<“G uzA]hþî ¦üfɇrYA9Œå@ežVY‚§`X\I¾ªÉ3\´(iÔ ïÎÅàPh¬ ¤W/ðîŒX.* ôêÞŠÁ¡ÐXH¯^ĺÛPy…ô"ì(bI –zA8è¿+++é­õõõú6‹e· Ò IqÒ ÒzxŒ½)«ªªŠ>鿤,„A8"ic¨TrÄI/ª«+ÛÛ«éωÊË‹***H2è“\ öî,úÛ³êê*eÏ÷;x¾I—TrŒ-aê…ÛÿC$]hiièêjhm­¡*ÊÞ©ÙÐ@ò»³„ÆÊOˆy– ¤™@hzáêÿ–sÏ}4×ÔuvfhÂëÿî,Š&ÿq‘Ý–VÇ ÷PÊúÂb*u‡ÔÜ‹ ß$ÍÃ,1mM/Ø?§vå6ÇQ­¨(.*êV[[ÔÕUרXG¢Àëýýrcc®® ýÏE£IŠÞ¿F¾5’å/–LÈz¡Ñ YAc.hHÊ DH/ä—YX}C*P]]Âô‚öL&ëk—AŸEEE™Ì^$L/ª«³!>õ‚»g·\é¦?)f‰i~hzáj>Âü‹ââ¬AûÆåÏ>[ßÑÑØÑQM—J6n¤À¬Žwóì_ØMIÜê…<%QNRc@hHª„¦DÙ|½“­_ôèQÔÜ\L{eeÖÝ °¶6r(ºUVîÕÜ\O;ý•ª‡õ ýC¥nõB&U¶…Æ&@˜zA4W.xât)„.¡’XTTìS^Ñ­©©GSS}¡Ÿ´äI—W)‚f¸ «›v?5áú… ýŠ&Ö;“7xRØ¢8éù%%%´œIWRIhñ‚6úB?)QýéÝnj |y„ùUË‘óQæœB;C““A NzAÄ[ZZØÿ°g2Z×Ì-vfè'Ò¡dt Z‘%3½ˆ,GT Ò@ d½Hb´C ÆzA÷k$¦ÐˆèE,º •HH—^,ÚÐ0jÓ¤½7H;}¡Ÿ‘èTbB Ez1mÓ\’‰½vÄöî[öï¾v? ,LOÉ·„û¿I\¸Ž+7Ä…ƒRâB -zA®‹ƒvݙۘ^t_¹o¼ å¸õ9˜y±`Ö&ߊ곈¸1êY0iÑ š}X0¥ TƒäƒéÅ÷~d‡[¸ÛJã#èïËRÞT®ÞÂQ;ßA¨’þgÁ¬ %•@Zô‚9J±è>éÊÞut ä3¼c>Ê„RôzaW4ô"©5"튷^ÈÀ[!߬7AÜÎ{ß?wßPô‚Ÿ>ØI ×Ëü‹ˆ ¤”T#Æz᪇h>’}X{nBJA;I†ã|„ ÆÖ|DÈJ3ž_CÎÁN/4®ü WVÈn ¤E/hQ“–*ØNJAÁ< ÚÇ­šäHM¢vK‰†ó;ÿÂD˜ä8Vô±+Á´è1¢K§¼L0±j‚Ï|êó&XÑzéq,Z“]Î&MF ¤H/¨ñäeXn}Ñ{ÖAuò¶›MÈÄ-¥”E9£q Kq4U‚j`äE ]z5ÃágÍU•ò‘§« rÊ @/\?‰Ð'ËÇÀÎGž.¨ ðÙgÐ X€€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SÐ SRˆ ½€ €˜€^˜’B<èl@À”ô”â@/` ¦ ¦¤@z0%½0%…x Р؀€)è…))Ä€^À@L @/LI!€ô6 `JzaJ ñ@ °SîôâÓO?¥ØARK ««ë©×?§t|ÔN{·aCS(ûA{ÍÒõt˜Ä‚±¤œ€©^d`H9èEÊ Í .`!*¤œô"倿ƒ€ Ð °RNz‘r@óAÀè… Xˆ )'½ˆ,ÚÐ0jÓ¤½7H;}¡Ÿª\HUybÁ5›F³yïQ´ÓúREPl–@Òô¢LÚ¼õ3ËÆ[Zo©¦mšK2±×΃ØÞ}ËþÝ×îGv¹ õV¨•JÙ^‹€pTþ)—ÀMÓ‘Lìü§‰lßÒ}ÔÚîå"˜y3Ícúìʼ&O¦^è‡A^zËœ\ &íº3·1½è¾r_;/ƒ·?ÿ¶¸^ð¼U\‰ÝbÑo®¥×ýC;/£LX»<ä ‚7sÊ_ª„ë…еÖOÍ™S6>•PðAøs¾\´¦iöAbÁ”‚6R ’¦ßkø‘2¡Æd­j8ž 5NвiÊÑ"²„Võ&|d½G³]žE楷LßI>È¿ ½ =&JÛ°“;§ÌÄ;Ë߀÷™sºôB0b¥š˜œ@ä|”ê`~JaÎ…R,ºOú«±¡¬›ÒáÒŸ$íôB–¥8Ê™£žîá\ô›Ë‹Å¤îû…ÂÄ\/J²€ò=âs 2yÚõBèHÇq%ŸKõ‡a_f½ š€ävÞ³øþ¹ûêõÂΕ°vÃX–6ozaP¯hV$´`ÁvA,ôz‘?&æz¡?ëð -$"ÑÒ¨‚=);ÏñÜëÙÍVv<ÍG²³kÏMCH)h'ÉПK•~¯É”Dï… ”dhvî·Ò‰SÒJ¤ùÍ>¬MCH)h?÷û½ ÏD)…†º @€^DDþöXˆÒ÷¥ÜýüÕD/4&+œœéТ&-U°”‚4‚y´[5É›ïͧrœ@É£].T£v¢ öOºìôøøõªxÌ º û¥ƒŽSåŸß3Ü*ÇßøÞão<ø„›þÄL9ä7râÍïùò?ªrÒ-ªz²*·.øä­ïÿämï)8åöÃN¹ã°Sï8üSwêòÁÓîúÐéª|eá­ræÄ¢3'Ž»ûˆ³fÊ‘gÝsäÙ÷|øì¯.>ç«‹Ïýš*KT9ïÞœïQç}¦\pßÒe÷}tÙ7>zá7>öé¦.G/ÿæÇ/Rå[Ç\Ü*—|ûØK¾}Üg¾£Ëðø¿ _ú/Ç_zÿ —ÝÂgPåŸ}àÄËÿõÄ+ÑåʇNºê¡“¯úîÉW÷“×ü›.£×~ïU®û¾*§~N•|êó?8í “ºœþO?<ý‹?<ã‹?:óúyÃU»á'g}é'gýó¿Ÿ­ËÿqÎMÿqîMŸ{óÃçÝ<5S¾²ü®G.ºë?/þÊ£3eâÑK&~ù™»UY1~O«|õ±K¿úØe_ûÕe÷þê³÷þz¦|ý×—ß÷›+TùÆoU¹²©ÊãW}óñ«¿µR—k¾½êÚï$¥KPd7¶Ë‘Ǿöæo.>ìøM?÷åSO8õ€}ß»Ñ! 79jx›ÃŸ3çkD‘Ad<;îÿ·KŽßúœå{-ñ½W¾q"ƒÈ 2j¢ë* ‘±Ï;Üqÿ©KNxÝÛö[û²«ÙùíÏéœg¬»ÁZKŽØÿ€Wm±ózD‘AdÔ12DW.‘ñ†ÝÿféIoZøêÅ'lùõû®Ü}ÿ ÷Û{ã/_ràïž»tx×-w~‘AdDÆÓ0xÈÜ-¶_wëù/=íì=ÿÝ= ?²Ýéç¾ãžXuÉ¥§?öÈ­;í?@dDF­#£Ñ’‰l82FÎ>p`Çg-\²ÕE¾÷¿¼íÁ®¾ú²÷<ô£½çÎÓ.¿nô•[=ŸÈ 2ˆŒZGF.#r "ŽŒM¶zÞ™ ½çÐ9ç/?àáŸÝñìõcÇïð…‹Û|ë—\pÞQ¯Ú⯉ "ƒÈ¨{d¤IaŽ8Ä‘±Ëžl¿ís>pø¦gŸ³ï=wŽ\wãQëmÐxÅ·÷Ûn»Ûæs·Y›È 2ˆŒYÖ3”2‘±ëà+÷ØëÅCo2rÆ;_2ðÀÝÖ^ÿY¼zÍ·záë·ñÀ›žCdDÆ,ˆŒÊF/Úð9k¯÷Œµ^ôŒ¹Û­¿ñfÏúоëlô¬]çlºÅ«>Å…;í6‡È 2ˆŒºGF•×2þz½µ^°ás_ôеÎ7‘e. Žœ‘‘ôÁïªLÓÁ¬4›PSÎÈXi0Çievë€ÙÁôñï©L§Í ³ƒ32~cÐÇ¿§26'ÌÎÈøµAÿ®ÊôlŬ4›PSÎÈxÌ`^ËÈÖ['rÓêÎ+ÀàŒŒG æ(C1g0‹9#ã08#ã`pFÆÏÀàŒŒ)0¾0Îȸ Œ2ˆ D"€‘@€È @d 2ˆ û×òOWÞ±´ñ ×Þéüæ"¢O¸.fÙæ"2ìGfàRæt§;V¯ÈÈ.%úxëb–mN"#ÿÝÜ ¬;º+2¬ÓþŸºÖ•zzèoÙÕ¦¿¢îüá‘á©,ì³ç“ñ\!Ÿ†gñykþÿõ³‘Q®ÝÂÜu\ÓþBö9Ïa.^éïC`ûÖn§õ¹ ?Ÿ6?·ðEÚ_Ü3ÿìFd~+?aB¦ ß*ÜçÌw[¶.îZW‰ /ì°g"pí¥;æoÁ?-íÿÓ˜eˆŒâŸZÖ—•ì…®Y{è©ñïÄæzflßÚŽ9¿g¢µ‡t̵”ºpñÂO{Ö#2|ÿ×÷•éð·Bz(Ú‰=ÃJÇÁìïž«)WÒ=-·ÿ¹y63|ºpñÂO{Ö#2Š##»O—Ø ­+ò´ÒCÑN\¸¥»RߵϭôfŠ_j¶"2‚~›‡M›»¾Ùra<5…;±k]ž>”XÄÓÏçãZE‰Ï-¤Á‰úãÿf%"£ø…uŸ(½GZñ÷Á¿vÿJÍ­°6e톿ÞÓgs~Ïskiçs³ö-ðPÈâþMèDFo°âsë9"£7æÙôºS5ÀçÖsDFϰߗÃçÖ[D"€‘@€È @d 28#ã¸3.¦P(”l)ˆŒF‘Ä«ÜRâ¤2!ÍgdL»…DÆÈšÒÊ®l €*©!FPd¤£sÚðë¦3ɲ€8…Ž2ÚŒŒl ‘Ô‘@ {‘‘^È 2€úªàò'£  ˆ •E†ëËZD0›Df;ÙÖª’mÖµFë<Õv£ÓÝ®j!•蟘˜;SU‘Qí>JdHWgÖ·ß>ê¨N‘Qán*=ö*ï@wº]áêr•í7Žšêld¸v/ÏníÙM]•…M6XomÓœ¡’~ºVØmQû¹üõ}óP¨£ ÈðóG†kÅzÁÀ½ß³ç™ûtÈ ®·°ÞÕfx}¹~zZðt»öý[ؽÔKqdèùF¼Òæ÷HÍž}ѳsKgp­ÝÓ+ëœæ ÖÖ¬KùßõlEx· WòÒìsaC>ÔKhd”æÏÏ^n2çqÕ”˜AZ~t0íoíwÛߥð­ö×xÖ…º¨ 2^Ò…´Óþ®ìê^x}Hƒ‹ëÝ•†×{:Ò±\MøÇ’³N»‘áÙ)Ëí!Kî©%fÖ‡4ò™dk¤[^ïé€9[áV‡,¹¥¬D½T3¿7±ÿ+ßE\{¿éÁVúØ5X¸-þFÈõþÎvÀÓ¾ÿsï ¢UÅ(Õ­KÒ/†‡ìX¹ýϳ¯Î¸öÂcè.%ÝŠÊ»]¸Q®Öü=l¬)Au|”щÈHŒ½°p7õ9%ê .Q7JÏPø¡µÓ~᪻çï!꥖£ŒÜœGKÈZÂë]G—´Ÿ¹·ü+’v[ÚÏå7¼ÖwQ#Ñ2P#AŠn”!2úPg¿—aý²f "£µÙhð|¿“]j¶"2úP5‘Q¨kÛ £Ú 5çHëÊ…ë_.g³I»‘áÏ‹®€³K•£Œ,FÀ¬ÔkD0k”ŒŒÛ|´ËƒîE¿Uf®FFfzZ뻢ՃÈhLO{Þ³DF³EO¤ÿš‘a=séÜ)Œ§eΛ€T™È¸êöûœ|*j"|Mþ£.ðpí~dp©ÈGFšÒÔPGÝèèh’V4WKä‘‘­7¯¡Z¯ªz*Íyú™82tRèG¥ééÂudI•zBß47uYëaŸ¸v3;rí»Z°F†Ù>ÐÏ*ˆŒÛ|4Wr‹´’¢‘M õ¯®ÉÎcí_`Γ}i]Г Dêø‰‰Vä"ÃzÄZ/¹t°ÎOdR¿ü©óB%E’9˜›Íf:Ð(w-# e„/Hd!Jþ’5ð*F²æY‰z©³C5²ç&Š :ä&ˆ  PÇ##yê^gB•$3îh¬þ¥IRid$™0—ÍÕ{qõègÝe¤ç ̵ …£ QéÒ(#•f‡©ºÐ)]ýãwÒ¨»Ü/ƒ{mõudLMM/mU/'''K¯@›¢ŽŒeË–ÝrË-ÍfshhhÁ‚×·Œ­X±¢ôÚ´#êÈP#‹‰‰ ‹-R©¡#C5ôïet_Ô‘100 2b¼E_7UÁ188¨^V5ÐH¿”‘}Y¹N4›ûÊI¹µxá*5¬¢Ž u2¢NLtj¨“SSSj”¡*+k®z"V±G† µïª1… ˆ42ÔËÉÉI•jײæw:]ÇXöW¿Öo‚š±bQžÊÄqdZ×Þ~n»r3„4âúwéB?ˆ:2Ô9ȨñÝ/}MTEÆÄÄ„:Oq-k†…?\K¹*­‹¶éïaéöÛoÄÚ=×[èg½‰ OÉΩG*Ò¼ÐÓúTEE†Ê×Zü?­õþ¥üÓáK…ôPTYb+ü+| ý,êQ†ŽŒU«Vé}T§†z©ÆþQ†9]IddYë]MÎP®Ò5®ñtÒß1s¥@*êÈPç *V´¨‰±–ljôv”²®J–jg”a2'‘«¨#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒu¥æpÿÌ¢^U¸if÷\o¡ŸEšbLµ¨I+ÓÔp-•r›õ‰qéÌÖÊfCzRéY¨×gHdÀª‘áâOø÷øø{˜jIÍÇÕñ÷0Õ;2t‘@ êÈà~@l¢Ž î—Ä&êÈà~@l¢Ž î—ئçÛáäê=_Ù@?‹:2¸_F`›ÕF†õûl€{dp¿ Wen»r3„42” 2udp¿ŒÀöÛoÄ…È@÷˰OV&ŽÃ©p©Š*Kl…¿cï¢?õ 2Âq¿ŒJ׸ÆÓIÇÌu©¨#ƒûe„Tú·Â*dNòVQG÷Ë(¬¬pÓr}³ÖQG†Æý2¬•žÕ‰1ûÖX“Ùsô³D†‹?5âß×ãï!`ªqd$5?¿‡€©Þ‘ Ëˆ Ý‹ŒF‘¶·@Çu522ÓÓºXß­DFczÚó.€˜õ 2š-z"ý·ðÛ®o1T¥ð X)P;e"ãªÛï_pò=ª¨‰ð5ù:Ï×+ ¿zT ן:½^ ^Ä‘‘æ…45Ô!7::šd†ÍÕyd˜Ç³¿Æ_i®Èß  o‰#C'Åt‹ž.\Gö˜Lï1=?t]ËZûÄ}´[Gþ˜0£Äß  oUþ{^$O/Ù¤Pÿêšì<ÖþÆAá<Ù—Ö=¡@^©ŽŸ˜èaE.2¬G¬uñÒ‘‘Këü!‘A^Y¿ü©óB%E’9˜›Íf:Ð(w-# e„/X¸€¤ô/Y¯b$kž•¨—:;ôX#{nÒ¡Èð§Cn"×ò0u<2’Ö±§Çª$™qGcõ/M’J##ÉD€¹l®>°âк1ÊHÏA™k:AE£ QéÒ(#e„ Ð?ºôäw=¦P%ÉŒ;«i’TI&ÌesõžF\íý¬£Œô¤‘¹–¡¤p” *]e¤Œg ðc¨“®þñ;éÔ]Ô>›¨#cjjj|||xxxiËèè¨z999YzÕÚudèg)6›Í¡¡¡ \ß266VÕcßHEjd111¡"cÑ¢E*5td¨±F%Ï|PBÔ‘100 ¿ª­Øh=…`ppP½¬j ‘~)#û²rh6÷•“rkñ†kÕ0EêdD?-M?*MïÁSSSj”¡*+k¢z öÈP¡v_ýLÖ42ÔËÉÉI•jײæw:]ÇXöÇ©õ› f¬˜?~=•‰ã´®+¼ýÜvåfiÄ5Ž /àud¨sQã»_úš¨ŠŒ‰‰ Ñ3Yý)àZÊUi]¼°MK·ß~#fÇ\ÝFŸëMdxJvN=ÊÐOQÔô´>UQ‘ÑÛ'¿»Ž7éœå:ÐÎV”è Eýè#«V­Ò'&ú"¨N õR5ü£ sº’Ȱþ6+­ƒš6,/줿cYDr¢Ž u¢¢aE‹škɦFoG!ëªd©vFV%æ´¨#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒu¥žàídV.þÚß4ÿ6ZÔ‘¡©!ÆT‹J´2M ×RÙ!·YŸFà˜Îl­ i6¤‡!•žÕ‰ñÄyS "ÃÅŸñïîñ÷0Õ82ïQÿS½#@—ºúg¿¶·@ÇõàÉï­éi]¬ïˆV"£1=íy@Ìzé³K²ÿš‘a=séÜ)Œ§eΛ€Tǰ˜òu‡k÷#ƒK-@VÇãœjÌ<Äd4É +š«%òÈÈÖ›×P­WU=•æŠÌ¥7˜ÝÄ‘¡“bº%ðHÙc2½ÿ…~lZnë²ÖÃ>qífväÚwµ`öÁŸ&@ª 2ü÷¼Hž_4²I‘>r1;µqP8Oö¥uA"Ññ=¬0ŸÉš¸ÿØ4«tdäÒÁ:¿?2üiô§Ž_þl¬~Î{’9˜›Íf:ШüÉï®ñ‚AkdX£ègÝxò{:ÄP/uvè±FÈ“ßÛŒ :ä&ûô³.=ù])TI2ãŽÆê_š$•FF²æÁZÒˆ«@?ëÆ(#=id®eè)eˆJ—F)ã–á€huõßI î¢~ô€ØDSSSãããÃÃÃK[FGGÕËÉÉÉÒ«Ц¨#C?K±Ùl -X°àú–±±±ªû@*êÈP#‹‰‰ ‹-R©¡#C5*yæ;€¢ŽŒýøUýhÅFë)ƒƒƒêeUôKÙ—•ëD³¹¯œ”[‹.TÃud¨“ý´4ý¨4SSSj”¡*+kž·ˆ ˜b jÇÕÏdM#C½œœœT©¡fp-k~§ÓuŒeõký&¨+æáä©LG¦u]áíç¶+7CH#þßy°Š:2Ô9ȨñÝ/}MTEÆÄĄ虬þp-媴.^ئ¿‡¥Ûo¿³ožwÑÏzž’S2ôS5=­OUTdôöÉï® ÎY®íl…¿c ‘·¨G:2V­Z¥OLôEPê¥køGæt%‘‘e­w5U8C¹J׸ÆÓÉÀŽ0EêDEÊ51Ö’MÞŽ2BÖUÉRíŒ2¬ ‡ÖÄ’È#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒëgµçÈl³Wnšµ‡žwÑŸ¢Ž M 1¦ZT‚¤•ij¸–ʹÍúÄ8„ÀtfkeH³!= ©ô¬NÔHágdÕ 2\ü©ÿîS##ñuññ÷0Õ;2t‘@ êÈà~@l¢Ž î—Ä&êÈà~@l¢Ž î—ئçÛáäêý_Ù@ߊ:2¸_F`›ÕF†õûl€{dp¿ Wen»r3„4âJðˆ:2¸_F`ûí7’똧ÛèsÜ/Ã>QX™x7Ñœå:ÐÎVvÌ¿úYÔ£ î—Ré×x:Y¢c€udp¿ŒJÿVX…=ˆ äDÜ/£°²ÂMóo# E÷˰VzV'jÄgäL5ˆ jÄ¿»ÇßCÀTãÈH¼G]üdü=LõŽ ]Fdˆ:2¸_›¨#ƒûe±‰:2¸_›¨#ƒûe¶éùöGx#Ùʬv:‰Ù'êÈà~mV¢Ðob î—áªÌmWn†F ÇäLQG÷Ël¿ýF¬Ýs½…~Æý2ì…•‰ã *\*¤‡¢Ê[áïXá[èg=ˆŒpÜ/#¤Ò5®ñtÒß1s¥@*êÈà~!•þ­°*œ“¼€KÔ‘Áý2 ++Ü´\߬õ@Ô‘¡q¿ k¥gu¢F<}L5ˆ jÄ¿ÓÇßCÀTãÈHj~Á?þ¦zG€.#2t/2EÚÞ×ÕÈÈLOëb}@´zéiÏ»bÖƒÈh¶è‰ô_32¬g.;…±¶Ì©Ó›“ðw¿zÔ>Odtbu@Mu52FGG“̰¢¹Z"Œl½9° <•抬5ºÙc2½ÿÅôtþÐu-k=ì÷ÑnfG®}W ÖȰ¾ô­ò‘xÏ‹ä©ñE#›ê_]“Ǻ¢À8(œ'ûÒº ”AjZÇGzX‘‹ ëk]¼td˜sþðP 2­ã‘¡óB%E’9˜›Íf:Ð(w-# e„/Hd!ºé!§³C5²ç&Š :ä&r} téò§S¨’dÆÕ¿4I*Œ$æ²¹zO#®v€~ÖQFzÒÈ\ËÐ R8Ê•.2RÆ3ø1ÔIWÿøtêŽûeà~¸_î—@€ûe¬±:W=‰hÜ/Ã×rƒokâ~Îñ 1˜¸_÷˸_÷˸_‘p¿ "à~Ü/à~ÎF\íýŒûeà~¸_î—@€ûeà~¸_î—±Æê ;ô9î—Ô2‘hÜ/£xüB^)î—áüW€~Æý2 þðŒ¼²¸_‘p¿ _d@÷Ëð]Ë 2€î—álÄU ô3î—@€ûeà~¸_î—@€ûeà~¸_Æ«óô¡+j‡ûe8[ÎÖ€Æý2œã"0q¿ çߘ€‰ûeÿ%+y¤¸_†32 èCÜ/ƒÈ¸_×2î—álÄÕÐϸ_î—@÷óßüO}‹52zÞ«n><ˆŒ ¨}î—+ÿ·¾Å=ïU7DFÔ>÷›ßý±¾Å=ïU7DFÔ>—üþ‰úkdô¼W=Ü|xPûÜïÿøçúkdô¼W=Ü|xPûÜŸþü—úkdô¼W=Ü|x8®õ~õeŒ^wª{ˆ "£uÿ™Ì(£'»MM(}æ?oµÒËvèd¾ÄÍ[SUý¬p3¹–Q "£¥¿`¥—íЯ JlQ¶?ö­ …È!2*Pî[ ú¸ÊN”¨ÌÖäfèò÷2\=ñ÷Ù¿½á›\nÃù^F DFÊ}WRïåÙ‰t:Wï¯L—Í5ÕåoºzâÙL릹–ò,ÞζóíO)"£åþ"CïâÙ ×´¿Ò:[÷ÿÆ$·vW÷r= ßvÏâå¶š¿1)‡È¨€Úç~ì¿¥EïëÙ ×´¿Ò:›¨X#£ôæv¾p{ÃwU¶¹ùð 2* ö¹?ú;Q™g“Ögç)¬´Î&*ÖÈ(·EæK³W…Û¾¸¿²ôæÃƒÈ¨€Úç&IDEïßæËt׬Ì.žmPT¬‘ÑÎY§Ã+­3ˆosóáAdT@ísßûù*QÑû·ùÒœ(¬L§³ ŠŠ52Êm‘Ùk?=[Q¸ÉÖö«Ý|xPûÜC?]YIÑ»~H¥h±FFU[!2DˆŒ ¨}¤èƒ?¤2û–ëÝÀbŒª¶(þBdˆPûÜwþý·õ-ÖÈèy¯z¸ùð 2* ö¹oþø×õ-ÖÈèy¯z¸ùð 2* ö¹û~ø«úkdô¼W=Ü|xPûÜ×~ðX}‹52zÞ«n><ˆŒ ¨}îîï­¨o±FFÏ{ÕÃ͇‘QN?˜§ eömQ;›"€‘@€È @d 28#ƒB¡P\…È P(‚òtdŒ@€™È˜ÁþèÇ?æÑÔ"sIEND®B`‚tango-9.2.5a/doc/src/advanced/poll_in_ds.cpp.lines0000644023471100065110000000070213034745264016775 00000000000000 1 void MyClass::read_attr(Tango::Attribute &attr) 2 { 3 ... 4 ... 5 6 string att_name("SomeAttribute"); 7 string another_att_name("AnotherAttribute"); 8 9 if (is_attribute_polled(att_name) == true) 10 stop_poll_attribute(att_name); 11 else 12 poll_attribute(another_att_name,500); 13 14 .... 15 .... 16 17 } tango-9.2.5a/doc/src/atk/0000755023471100065110000000000013034745265012132 500000000000000tango-9.2.5a/doc/src/atk/img/0000755023471100065110000000000013034745265012706 500000000000000tango-9.2.5a/doc/src/atk/img/core-widget.eps0000644023471100065110000005273713034745263015564 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: Untitled-1 %%Creator: Dia v0.88.1 %%CreationDate: Wed Jul 24 12:56:48 2002 %%For: a user %%Magnification: 1.0000 %%Orientation: Portrait %%BoundingBox: 0 0 419 203 %%Pages: 1 %%BeginSetup %%EndSetup %%EndComments %%BeginProlog [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def /Times-Roman-latin1 /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Italic-latin1 /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Bold-latin1 /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-BoldItalic-latin1 /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Book-latin1 /AvantGarde-Book findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-BookOblique-latin1 /AvantGarde-BookOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Demi-latin1 /AvantGarde-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-DemiOblique-latin1 /AvantGarde-DemiOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Light-latin1 /Bookman-Light findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-LightItalic-latin1 /Bookman-LightItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Demi-latin1 /Bookman-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-DemiItalic-latin1 /Bookman-DemiItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-latin1 /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Oblique-latin1 /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Bold-latin1 /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-BoldOblique-latin1 /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-latin1 /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Oblique-latin1 /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Bold-latin1 /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-BoldOblique-latin1 /Helvetica-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-latin1 /Helvetica-Narrow findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Oblique-latin1 /Helvetica-Narrow-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Bold-latin1 /Helvetica-Narrow-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-BoldOblique-latin1 /Helvetica-Narrow-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Roman-latin1 /NewCenturySchoolbook-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Italic-latin1 /NewCenturySchoolbook-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Bold-latin1 /NewCenturySchoolbook-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-BoldItalic-latin1 /NewCenturySchoolbook-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Roman-latin1 /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Italic-latin1 /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Bold-latin1 /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-BoldItalic-latin1 /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Symbol-latin1 /Symbol findfont definefont pop /ZapfChancery-MediumItalic-latin1 /ZapfChancery-MediumItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /ZapfDingbats-latin1 /ZapfDingbats findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /cp {closepath} bind def /c {curveto} bind def /f {fill} bind def /a {arc} bind def /ef {eofill} bind def /ex {exch} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth pop} bind def /tr {translate} bind def /ellipsedict 8 dict def ellipsedict /mtrx matrix put /ellipse { ellipsedict begin /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc savematrix setmatrix end } def /mergeprocs { dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def 28.346000 -28.346000 scale -15.579133 -17.035000 translate %%EndProlog 0.069570 0.512979 1.000000 srgb n 23.764133 11.010000 m 23.764133 16.985000 l 29.789133 16.985000 l 29.789133 11.010000 l f n 23.764133 11.510000 m 23.764133 11.510000 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.789133 11.510000 m 29.789133 11.510000 0.500000 0.500000 270.000000 360.000000 ellipse f n 23.264133 11.510000 m 23.264133 16.485000 l 30.289133 16.485000 l 30.289133 11.510000 l f n 23.764133 16.485000 m 23.764133 16.485000 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.789133 16.485000 m 29.789133 16.485000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 23.764133 11.010000 m 29.789133 11.010000 l s n 23.764133 16.985000 m 29.789133 16.985000 l s n 23.764133 11.510000 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.789133 11.510000 0.500000 0.500000 270.000000 360.000000 ellipse s n 23.264133 11.510000 m 23.264133 16.485000 l s n 30.289133 11.510000 m 30.289133 16.485000 l s n 23.764133 16.485000 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.789133 16.485000 0.500000 0.500000 0.000000 90.000000 ellipse s 0.069570 0.512979 1.000000 srgb n 16.129133 10.950000 m 16.129133 16.925000 l 22.154133 16.925000 l 22.154133 10.950000 l f n 16.129133 11.450000 m 16.129133 11.450000 0.500000 0.500000 180.000000 270.000000 ellipse f n 22.154133 11.450000 m 22.154133 11.450000 0.500000 0.500000 270.000000 360.000000 ellipse f n 15.629133 11.450000 m 15.629133 16.425000 l 22.654133 16.425000 l 22.654133 11.450000 l f n 16.129133 16.425000 m 16.129133 16.425000 0.500000 0.500000 90.000000 180.000000 ellipse f n 22.154133 16.425000 m 22.154133 16.425000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.129133 10.950000 m 22.154133 10.950000 l s n 16.129133 16.925000 m 22.154133 16.925000 l s n 16.129133 11.450000 0.500000 0.500000 180.000000 270.000000 ellipse s n 22.154133 11.450000 0.500000 0.500000 270.000000 360.000000 ellipse s n 15.629133 11.450000 m 15.629133 16.425000 l s n 22.654133 11.450000 m 22.654133 16.425000 l s n 16.129133 16.425000 0.500000 0.500000 90.000000 180.000000 ellipse s n 22.154133 16.425000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.800000 scf sf (Core) dup sw 2 div 19.054133 ex sub 10.475000 m gs 1 -1 sc sh gr /Courier-latin1 ff 0.800000 scf sf (Widget) dup sw 2 div 26.879133 ex sub 10.550000 m gs 1 -1 sc sh gr 0.787651 0.871212 0.798553 srgb n 24.239133 11.250000 m 24.239133 13.775000 l 26.079133 13.775000 l 26.079133 11.250000 l f n 24.239133 11.750000 m 24.239133 11.750000 0.500000 0.500000 180.000000 270.000000 ellipse f n 26.079133 11.750000 m 26.079133 11.750000 0.500000 0.500000 270.000000 360.000000 ellipse f n 23.739133 11.750000 m 23.739133 13.275000 l 26.579133 13.275000 l 26.579133 11.750000 l f n 24.239133 13.275000 m 24.239133 13.275000 0.500000 0.500000 90.000000 180.000000 ellipse f n 26.079133 13.275000 m 26.079133 13.275000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 24.239133 11.250000 m 26.079133 11.250000 l s n 24.239133 13.775000 m 26.079133 13.775000 l s n 24.239133 11.750000 0.500000 0.500000 180.000000 270.000000 ellipse s n 26.079133 11.750000 0.500000 0.500000 270.000000 360.000000 ellipse s n 23.739133 11.750000 m 23.739133 13.275000 l s n 26.579133 11.750000 m 26.579133 13.275000 l s n 24.239133 13.275000 0.500000 0.500000 90.000000 180.000000 ellipse s n 26.079133 13.275000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (State) dup sw 2 div 25.154133 ex sub 12.400000 m gs 1 -1 sc sh gr (viewer) dup sw 2 div 25.154133 ex sub 12.900000 m gs 1 -1 sc sh gr 0.049637 0.742424 0.077347 srgb n 24.289133 14.060000 m 24.289133 16.735000 l 26.139133 16.735000 l 26.139133 14.060000 l f n 24.289133 14.560000 m 24.289133 14.560000 0.500000 0.500000 180.000000 270.000000 ellipse f n 26.139133 14.560000 m 26.139133 14.560000 0.500000 0.500000 270.000000 360.000000 ellipse f n 23.789133 14.560000 m 23.789133 16.235000 l 26.639133 16.235000 l 26.639133 14.560000 l f n 24.289133 16.235000 m 24.289133 16.235000 0.500000 0.500000 90.000000 180.000000 ellipse f n 26.139133 16.235000 m 26.139133 16.235000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 24.289133 14.060000 m 26.139133 14.060000 l s n 24.289133 16.735000 m 26.139133 16.735000 l s n 24.289133 14.560000 0.500000 0.500000 180.000000 270.000000 ellipse s n 26.139133 14.560000 0.500000 0.500000 270.000000 360.000000 ellipse s n 23.789133 14.560000 m 23.789133 16.235000 l s n 26.639133 14.560000 m 26.639133 16.235000 l s n 24.289133 16.235000 0.500000 0.500000 90.000000 180.000000 ellipse s n 26.139133 16.235000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Attribute) dup sw 2 div 25.254133 ex sub 15.425000 m gs 1 -1 sc sh gr (viewer) dup sw 2 div 25.254133 ex sub 15.925000 m gs 1 -1 sc sh gr 1.000000 0.962677 0.066859 srgb n 27.514133 14.060000 m 27.514133 16.735000 l 29.364133 16.735000 l 29.364133 14.060000 l f n 27.514133 14.560000 m 27.514133 14.560000 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.364133 14.560000 m 29.364133 14.560000 0.500000 0.500000 270.000000 360.000000 ellipse f n 27.014133 14.560000 m 27.014133 16.235000 l 29.864133 16.235000 l 29.864133 14.560000 l f n 27.514133 16.235000 m 27.514133 16.235000 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.364133 16.235000 m 29.364133 16.235000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 27.514133 14.060000 m 29.364133 14.060000 l s n 27.514133 16.735000 m 29.364133 16.735000 l s n 27.514133 14.560000 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.364133 14.560000 0.500000 0.500000 270.000000 360.000000 ellipse s n 27.014133 14.560000 m 27.014133 16.235000 l s n 29.864133 14.560000 m 29.864133 16.235000 l s n 27.514133 16.235000 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.364133 16.235000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Command) dup sw 2 div 28.404133 ex sub 15.325000 m gs 1 -1 sc sh gr (Viewer) dup sw 2 div 28.404133 ex sub 15.825000 m gs 1 -1 sc sh gr 0.886364 0.036715 0.191547 srgb n 27.489133 11.160000 m 27.489133 13.835000 l 29.339133 13.835000 l 29.339133 11.160000 l f n 27.489133 11.660000 m 27.489133 11.660000 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.339133 11.660000 m 29.339133 11.660000 0.500000 0.500000 270.000000 360.000000 ellipse f n 26.989133 11.660000 m 26.989133 13.335000 l 29.839133 13.335000 l 29.839133 11.660000 l f n 27.489133 13.335000 m 27.489133 13.335000 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.339133 13.335000 m 29.339133 13.335000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 27.489133 11.160000 m 29.339133 11.160000 l s n 27.489133 13.835000 m 29.339133 13.835000 l s n 27.489133 11.660000 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.339133 11.660000 0.500000 0.500000 270.000000 360.000000 ellipse s n 26.989133 11.660000 m 26.989133 13.335000 l s n 29.839133 11.660000 m 29.839133 13.335000 l s n 27.489133 13.335000 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.339133 13.335000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Error) dup sw 2 div 28.329133 ex sub 12.275000 m gs 1 -1 sc sh gr (viewer) dup sw 2 div 28.329133 ex sub 12.775000 m gs 1 -1 sc sh gr 1.000000 0.962677 0.066859 srgb n 19.839133 13.785000 m 19.839133 16.460000 l 21.689133 16.460000 l 21.689133 13.785000 l f n 19.839133 14.285000 m 19.839133 14.285000 0.500000 0.500000 180.000000 270.000000 ellipse f n 21.689133 14.285000 m 21.689133 14.285000 0.500000 0.500000 270.000000 360.000000 ellipse f n 19.339133 14.285000 m 19.339133 15.960000 l 22.189133 15.960000 l 22.189133 14.285000 l f n 19.839133 15.960000 m 19.839133 15.960000 0.500000 0.500000 90.000000 180.000000 ellipse f n 21.689133 15.960000 m 21.689133 15.960000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 19.839133 13.785000 m 21.689133 13.785000 l s n 19.839133 16.460000 m 21.689133 16.460000 l s n 19.839133 14.285000 0.500000 0.500000 180.000000 270.000000 ellipse s n 21.689133 14.285000 0.500000 0.500000 270.000000 360.000000 ellipse s n 19.339133 14.285000 m 19.339133 15.960000 l s n 22.189133 14.285000 m 22.189133 15.960000 l s n 19.839133 15.960000 0.500000 0.500000 90.000000 180.000000 ellipse s n 21.689133 15.960000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Command) dup sw 2 div 20.729133 ex sub 14.975000 m gs 1 -1 sc sh gr (list) dup sw 2 div 20.729133 ex sub 15.475000 m gs 1 -1 sc sh gr 0.049637 0.742424 0.077347 srgb n 16.579133 13.775000 m 16.579133 16.450000 l 18.429133 16.450000 l 18.429133 13.775000 l f n 16.579133 14.275000 m 16.579133 14.275000 0.500000 0.500000 180.000000 270.000000 ellipse f n 18.429133 14.275000 m 18.429133 14.275000 0.500000 0.500000 270.000000 360.000000 ellipse f n 16.079133 14.275000 m 16.079133 15.950000 l 18.929133 15.950000 l 18.929133 14.275000 l f n 16.579133 15.950000 m 16.579133 15.950000 0.500000 0.500000 90.000000 180.000000 ellipse f n 18.429133 15.950000 m 18.429133 15.950000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.579133 13.775000 m 18.429133 13.775000 l s n 16.579133 16.450000 m 18.429133 16.450000 l s n 16.579133 14.275000 0.500000 0.500000 180.000000 270.000000 ellipse s n 18.429133 14.275000 0.500000 0.500000 270.000000 360.000000 ellipse s n 16.079133 14.275000 m 16.079133 15.950000 l s n 18.929133 14.275000 m 18.929133 15.950000 l s n 16.579133 15.950000 0.500000 0.500000 90.000000 180.000000 ellipse s n 18.429133 15.950000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Attribute) dup sw 2 div 17.504133 ex sub 15.225000 m gs 1 -1 sc sh gr (list) dup sw 2 div 17.504133 ex sub 15.725000 m gs 1 -1 sc sh gr 0.787651 0.871212 0.798553 srgb n 16.529133 11.425000 m 16.529133 13.300000 l 21.679133 13.300000 l 21.679133 11.425000 l f n 16.529133 11.925000 m 16.529133 11.925000 0.500000 0.500000 180.000000 270.000000 ellipse f n 21.679133 11.925000 m 21.679133 11.925000 0.500000 0.500000 270.000000 360.000000 ellipse f n 16.029133 11.925000 m 16.029133 12.800000 l 22.179133 12.800000 l 22.179133 11.925000 l f n 16.529133 12.800000 m 16.529133 12.800000 0.500000 0.500000 90.000000 180.000000 ellipse f n 21.679133 12.800000 m 21.679133 12.800000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.529133 11.425000 m 21.679133 11.425000 l s n 16.529133 13.300000 m 21.679133 13.300000 l s n 16.529133 11.925000 0.500000 0.500000 180.000000 270.000000 ellipse s n 21.679133 11.925000 0.500000 0.500000 270.000000 360.000000 ellipse s n 16.029133 11.925000 m 16.029133 12.800000 l s n 22.179133 11.925000 m 22.179133 12.800000 l s n 16.529133 12.800000 0.500000 0.500000 90.000000 180.000000 ellipse s n 21.679133 12.800000 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Device) dup sw 2 div 19.054133 ex sub 12.450000 m gs 1 -1 sc sh gr showpage tango-9.2.5a/doc/src/atk/img/listpanel.eps0000644023471100065110000004763313034745263015345 00000000000000%!PS-Adobe-2.0 EPSF-2.0 %%Title: Untitled-2 %%Creator: Dia v0.88.1 %%CreationDate: Wed Jul 24 13:14:06 2002 %%For: a user %%Magnification: 1.0000 %%Orientation: Portrait %%BoundingBox: 0 0 424 367 %%Pages: 1 %%BeginSetup %%EndSetup %%EndComments %%BeginProlog [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def /Times-Roman-latin1 /Times-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Italic-latin1 /Times-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-Bold-latin1 /Times-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Times-BoldItalic-latin1 /Times-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Book-latin1 /AvantGarde-Book findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-BookOblique-latin1 /AvantGarde-BookOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-Demi-latin1 /AvantGarde-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /AvantGarde-DemiOblique-latin1 /AvantGarde-DemiOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Light-latin1 /Bookman-Light findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-LightItalic-latin1 /Bookman-LightItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-Demi-latin1 /Bookman-Demi findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Bookman-DemiItalic-latin1 /Bookman-DemiItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-latin1 /Courier findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Oblique-latin1 /Courier-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-Bold-latin1 /Courier-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Courier-BoldOblique-latin1 /Courier-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-latin1 /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Oblique-latin1 /Helvetica-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Bold-latin1 /Helvetica-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-BoldOblique-latin1 /Helvetica-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-latin1 /Helvetica-Narrow findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Oblique-latin1 /Helvetica-Narrow-Oblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-Bold-latin1 /Helvetica-Narrow-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Helvetica-Narrow-BoldOblique-latin1 /Helvetica-Narrow-BoldOblique findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Roman-latin1 /NewCenturySchoolbook-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Italic-latin1 /NewCenturySchoolbook-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-Bold-latin1 /NewCenturySchoolbook-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /NewCenturySchoolbook-BoldItalic-latin1 /NewCenturySchoolbook-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Roman-latin1 /Palatino-Roman findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Italic-latin1 /Palatino-Italic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-Bold-latin1 /Palatino-Bold findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Palatino-BoldItalic-latin1 /Palatino-BoldItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /Symbol-latin1 /Symbol findfont definefont pop /ZapfChancery-MediumItalic-latin1 /ZapfChancery-MediumItalic findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /ZapfDingbats-latin1 /ZapfDingbats findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding isolatin1encoding def currentdict end definefont pop /cp {closepath} bind def /c {curveto} bind def /f {fill} bind def /a {arc} bind def /ef {eofill} bind def /ex {exch} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth pop} bind def /tr {translate} bind def /ellipsedict 8 dict def ellipsedict /mtrx matrix put /ellipse { ellipsedict begin /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc savematrix setmatrix end } def /mergeprocs { dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll putinterval } bind def 28.346000 -28.346000 scale -15.400000 -18.300000 translate %%EndProlog 0.121383 0.803030 0.233482 srgb n 24.800000 7.125000 m 24.800000 18.175000 l 29.800000 18.175000 l 29.800000 7.125000 l f n 24.800000 7.625000 m 24.800000 7.625000 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.800000 7.625000 m 29.800000 7.625000 0.500000 0.500000 270.000000 360.000000 ellipse f n 24.300000 7.625000 m 24.300000 17.675000 l 30.300000 17.675000 l 30.300000 7.625000 l f n 24.800000 17.675000 m 24.800000 17.675000 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.800000 17.675000 m 29.800000 17.675000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 24.800000 7.125000 m 29.800000 7.125000 l s n 24.800000 18.175000 m 29.800000 18.175000 l s n 24.800000 7.625000 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.800000 7.625000 0.500000 0.500000 270.000000 360.000000 ellipse s n 24.300000 7.625000 m 24.300000 17.675000 l s n 30.300000 7.625000 m 30.300000 17.675000 l s n 24.800000 17.675000 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.800000 17.675000 0.500000 0.500000 0.000000 90.000000 ellipse s 1.000000 1.000000 1.000000 srgb n 25.046473 7.380445 m 25.046473 10.155445 l 28.971473 10.155445 l 28.971473 7.380445 l f n 25.046473 7.880445 m 25.046473 7.880445 0.500000 0.500000 180.000000 270.000000 ellipse f n 28.971473 7.880445 m 28.971473 7.880445 0.500000 0.500000 270.000000 360.000000 ellipse f n 24.546473 7.880445 m 24.546473 9.655445 l 29.471473 9.655445 l 29.471473 7.880445 l f n 25.046473 9.655445 m 25.046473 9.655445 0.500000 0.500000 90.000000 180.000000 ellipse f n 28.971473 9.655445 m 28.971473 9.655445 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 25.046473 7.380445 m 28.971473 7.380445 l s n 25.046473 10.155445 m 28.971473 10.155445 l s n 25.046473 7.880445 0.500000 0.500000 180.000000 270.000000 ellipse s n 28.971473 7.880445 0.500000 0.500000 270.000000 360.000000 ellipse s n 24.546473 7.880445 m 24.546473 9.655445 l s n 29.471473 7.880445 m 29.471473 9.655445 l s n 25.046473 9.655445 0.500000 0.500000 90.000000 180.000000 ellipse s n 28.971473 9.655445 0.500000 0.500000 0.000000 90.000000 ellipse s 1.000000 1.000000 1.000000 srgb n 25.296473 7.755445 m 25.296473 10.530445 l 29.221473 10.530445 l 29.221473 7.755445 l f n 25.296473 8.255445 m 25.296473 8.255445 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.221473 8.255445 m 29.221473 8.255445 0.500000 0.500000 270.000000 360.000000 ellipse f n 24.796473 8.255445 m 24.796473 10.030445 l 29.721473 10.030445 l 29.721473 8.255445 l f n 25.296473 10.030445 m 25.296473 10.030445 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.221473 10.030445 m 29.221473 10.030445 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 25.296473 7.755445 m 29.221473 7.755445 l s n 25.296473 10.530445 m 29.221473 10.530445 l s n 25.296473 8.255445 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.221473 8.255445 0.500000 0.500000 270.000000 360.000000 ellipse s n 24.796473 8.255445 m 24.796473 10.030445 l s n 29.721473 8.255445 m 29.721473 10.030445 l s n 25.296473 10.030445 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.221473 10.030445 0.500000 0.500000 0.000000 90.000000 ellipse s 1.000000 1.000000 1.000000 srgb n 25.621473 8.155445 m 25.621473 10.930445 l 29.546473 10.930445 l 29.546473 8.155445 l f n 25.621473 8.655445 m 25.621473 8.655445 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.546473 8.655445 m 29.546473 8.655445 0.500000 0.500000 270.000000 360.000000 ellipse f n 25.121473 8.655445 m 25.121473 10.430445 l 30.046473 10.430445 l 30.046473 8.655445 l f n 25.621473 10.430445 m 25.621473 10.430445 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.546473 10.430445 m 29.546473 10.430445 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 25.621473 8.155445 m 29.546473 8.155445 l s n 25.621473 10.930445 m 29.546473 10.930445 l s n 25.621473 8.655445 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.546473 8.655445 0.500000 0.500000 270.000000 360.000000 ellipse s n 25.121473 8.655445 m 25.121473 10.430445 l s n 30.046473 8.655445 m 30.046473 10.430445 l s n 25.621473 10.430445 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.546473 10.430445 0.500000 0.500000 0.000000 90.000000 ellipse s 0.258946 0.251912 1.000000 srgb n 25.386473 14.805445 m 25.386473 17.580445 l 29.311473 17.580445 l 29.311473 14.805445 l f n 25.386473 15.305445 m 25.386473 15.305445 0.500000 0.500000 180.000000 270.000000 ellipse f n 29.311473 15.305445 m 29.311473 15.305445 0.500000 0.500000 270.000000 360.000000 ellipse f n 24.886473 15.305445 m 24.886473 17.080445 l 29.811473 17.080445 l 29.811473 15.305445 l f n 25.386473 17.080445 m 25.386473 17.080445 0.500000 0.500000 90.000000 180.000000 ellipse f n 29.311473 17.080445 m 29.311473 17.080445 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 25.386473 14.805445 m 29.311473 14.805445 l s n 25.386473 17.580445 m 29.311473 17.580445 l s n 25.386473 15.305445 0.500000 0.500000 180.000000 270.000000 ellipse s n 29.311473 15.305445 0.500000 0.500000 270.000000 360.000000 ellipse s n 24.886473 15.305445 m 24.886473 17.080445 l s n 29.811473 15.305445 m 29.811473 17.080445 l s n 25.386473 17.080445 0.500000 0.500000 90.000000 180.000000 ellipse s n 29.311473 17.080445 0.500000 0.500000 0.000000 90.000000 ellipse s /Courier-latin1 ff 0.500000 scf sf (Refresher) dup sw 2 div 27.286473 ex sub 16.330445 m gs 1 -1 sc sh gr /Courier-latin1 ff 0.500000 scf sf (Attribute) dup sw 2 div 27.236473 ex sub 9.555445 m gs 1 -1 sc sh gr 0.666667 0.666667 0.666667 srgb n 15.950000 7.200000 m 15.950000 18.250000 l 20.950000 18.250000 l 20.950000 7.200000 l f n 15.950000 7.700000 m 15.950000 7.700000 0.500000 0.500000 180.000000 270.000000 ellipse f n 20.950000 7.700000 m 20.950000 7.700000 0.500000 0.500000 270.000000 360.000000 ellipse f n 15.450000 7.700000 m 15.450000 17.750000 l 21.450000 17.750000 l 21.450000 7.700000 l f n 15.950000 17.750000 m 15.950000 17.750000 0.500000 0.500000 90.000000 180.000000 ellipse f n 20.950000 17.750000 m 20.950000 17.750000 0.500000 0.500000 0.000000 90.000000 ellipse f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 15.950000 7.200000 m 20.950000 7.200000 l s n 15.950000 18.250000 m 20.950000 18.250000 l s n 15.950000 7.700000 0.500000 0.500000 180.000000 270.000000 ellipse s n 20.950000 7.700000 0.500000 0.500000 270.000000 360.000000 ellipse s n 15.450000 7.700000 m 15.450000 17.750000 l s n 21.450000 7.700000 m 21.450000 17.750000 l s n 15.950000 17.750000 0.500000 0.500000 90.000000 180.000000 ellipse s n 20.950000 17.750000 0.500000 0.500000 0.000000 90.000000 ellipse s 1.000000 1.000000 1.000000 srgb n 16.146473 13.980445 m 16.146473 17.405445 l 20.846473 17.405445 l 20.846473 13.980445 l f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.146473 13.980445 m 16.146473 17.405445 l 20.846473 17.405445 l 20.846473 13.980445 l cp s /Courier-latin1 ff 0.500000 scf sf (Error...) dup sw 2 div 17.636473 ex sub 14.830445 m gs 1 -1 sc sh gr 1.000000 1.000000 1.000000 srgb n 16.146473 12.380445 m 16.146473 13.180445 l 20.846473 13.180445 l 20.846473 12.380445 l f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.146473 12.380445 m 16.146473 13.180445 l 20.846473 13.180445 l 20.846473 12.380445 l cp s /Courier-latin1 ff 0.500000 scf sf (5.98) dup sw 2 div 19.961473 ex sub 12.955445 m gs 1 -1 sc sh gr 1.000000 1.000000 1.000000 srgb n 16.096473 10.355445 m 16.096473 11.155445 l 20.796473 11.155445 l 20.796473 10.355445 l f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.096473 10.355445 m 16.096473 11.155445 l 20.796473 11.155445 l 20.796473 10.355445 l cp s /Courier-latin1 ff 0.500000 scf sf (modify) dup sw 2 div 19.761473 ex sub 10.880445 m gs 1 -1 sc sh gr 1.000000 1.000000 1.000000 srgb n 16.050000 8.375000 m 16.050000 9.175000 l 20.750000 9.175000 l 20.750000 8.375000 l f 0.100000 slw [] 0 sd [] 0 sd 0 slj 0.000000 0.000000 0.000000 srgb n 16.050000 8.375000 m 16.050000 9.175000 l 20.750000 9.175000 l 20.750000 8.375000 l cp s /Courier-latin1 ff 0.500000 scf sf (3.14159) dup sw 2 div 19.611473 ex sub 8.930445 m gs 1 -1 sc sh gr 0.100000 slw [] 0 sd [] 0 sd 0 slc 0.977273 0.025858 0.096629 srgb n 25.121473 9.542945 m 20.846473 17.405445 l s 0 slj n 20.877201 16.511546 m 20.846473 17.405445 l 21.580029 16.893688 l f 0.100000 slw [] 0 sd [] 0 sd 0 slc n 24.796473 9.142945 m 20.846473 15.692945 l s 0 slj n 20.917072 14.801309 m 20.846473 15.692945 l 21.602142 15.214442 l f 0.100000 slw [] 0 sd [] 0 sd 0 slc 0.000000 0.000000 0.000000 srgb n 25.121473 9.542945 m 20.846473 12.780445 l s 0 slj n 21.242739 11.978589 m 20.846473 12.780445 l 21.725718 12.616344 l f 0.100000 slw [] 0 sd [] 0 sd 0 slc n 24.796473 9.142945 m 20.796473 10.755445 l s 0 slj n 21.388897 10.085345 m 20.796473 10.755445 l 21.688008 10.827324 l f 0.100000 slw [] 0 sd [] 0 sd 0 slc n 24.546473 8.767945 m 20.750000 8.775000 l s 0 slj n 21.549255 8.373514 m 20.750000 8.775000 l 21.550742 9.173513 l f 0.100000 slw [] 0 sd [] 0 sd 0 slc 0.977273 0.025858 0.096629 srgb n 24.546473 8.767945 m 20.846473 13.980445 l s 0 slj n 20.983359 13.096555 m 20.846473 13.980445 l 21.635717 13.559619 l f /Courier-latin1 ff 0.500000 scf sf 0.000000 0.000000 0.000000 srgb (Events) dup sw 2 div 22.886473 ex sub 8.180445 m gs 1 -1 sc sh gr /Courier-latin1 ff 0.800000 scf sf (Panel) dup sw 2 div 17.961473 ex sub 6.205445 m gs 1 -1 sc sh gr /Courier-latin1 ff 0.800000 scf sf (Attribute) dup sw 2 div 27.186473 ex sub 5.955445 m gs 1 -1 sc sh gr (list) dup sw 2 div 27.186473 ex sub 6.755445 m gs 1 -1 sc sh gr showpage tango-9.2.5a/doc/src/atk/img/prog_guide_exple1.jpg0000644023471100065110000010233513034745263016734 00000000000000ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀYD"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?žÚÚãP¼Ô¿âekg¯üÃÍÓÈóúoPÿz¦þÌ?ô1ü'ÿû¶3¯ˆÿîÿ·õoWñ…4½ZöÍ4ývé-çxDð‰$ ÄnR¶ÄqA#ž ®3ó«h¬–Ä:~ŸkÚ\ëòMÕìŽ- F]þÕÁ¸Þ6Ð[nNÓœx¨¿³ý cÿ ÿþí¨lµ{]c]Ñä²°½°µ‹^Ó#O·¾_ô«v.b¸Áû¤çœ ©ô K– E»ýû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š›˜ûO$Ù‡þ†1ÿ„ÿÿvÑý˜ècøOÿ÷mQpöžH?³ý cÿ ÿþí£û0ÿÐÆ?ðŸÿîÚ(¢áí<fúÇþÿýÛGöaÿ¡Œá?ÿÝ´QEÃÚy þÌ?ô1ü'ÿû¶ìÃÿCÿÂÿ»h¢‹‡´òAý˜ècøOÿ÷mÙ‡þ†1ÿ„ÿÿvÑEiäƒû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š.ÓÉöaÿ¡Œá?ÿÝ´fúÇþÿýÛE\=§’ìÃÿCÿÂÿ»hþÌ?ô1ü'ÿû¶Š(¸{O$Ù‡þ†1ÿ„ÿÿvÑý˜ècøOÿ÷mQpöžH?³ý cÿ ÿþí£û0ÿÐÆ?ðŸÿîÚ(¢áí<fúÇþÿýÛGöaÿ¡Œá?ÿÝ´QEÃÚy þÌ?ô1ü'ÿû¶ìÃÿCÿÂÿ»h¢‹‡´òAý˜ècøOÿ÷mÙ‡þ†1ÿ„ÿÿvÑEiäƒû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š.Óɵ(ÓKÓ®¯%ñ4Vñ<ÎÃùbqþ׊ÑÔ|?&™¨]YËâDimåh\¦€J’¤ƒôÞœV‹ÿäSÖÿëÆýÕÛêöð]üA½‚ê_&Ú]QÒY7؆Räð03ɦh¤œoe¹ÏfúÇþÿýÛRÚiðe‡_H5{ƒ4¡‚þËe€ª/8BòXä±àªA«Úë\Iea{akˆÓíÄï—åV.b¸Áû¤çœ ÏÈJÏþƃÿ¤Ú}4\Å-¿TdÿfúÇþÿýÛDZykë[q¯ùÒOæ•C¡ùa¼¸$™¶6ܬLÚØ$qZßð—k¿ôÔð*Oñ®kÃZÞ­®i×7×S^\µæ®¦k‰ ŽBÚߪŒžp=„(¸ÉíøÁ<â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ*–DZKøqôGÑÚv›ª­®¿r|?¯ä}:4FºÞÅEñl'—¸½2q¹FyÙµ?ú|Gÿ‚ßþ5^û:ÿÈÙãúñÓôeåu6íõŠþ#ð“á?j×þ–Æ=WQ·6QÚZ­ÔbXä&[”‘Ô.âÛ#fùsJ Jæ¸|¶–&”j¶Õ×—ù)§é𵿽 "x{_Mº½„¬óh×q¢"]DÌÌÍ ©$“Ú¢û6§ÿBïˆÿðC{ÿÆ«×üûOøGÅþ$‹F 6šíá¹¼S%ýÍåŒÖ0YEvö®^æÞâX÷FcµŠªýæ Dð§|=ã½:Kÿ kÚgˆl#”À÷ZUäwQ,€(Z6 0 §pÃÖ«Ù£§û—*3ü—>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñªúö¼‡þ‡ÁÖÿ <]ãÛøµ=6×÷N¯§\[«Þ[ßE"Åöp#vÙšH‚²ÈS÷ƒs®jöhŸìZ?ÌÿÈ>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñª÷ã¿…n|=}¬k÷ö^ ¶²Õ$ѧ]{Xӆ˴@í<2Ʋ»1³‰Æ%@Á=ü, ÿÐÑ¢ÿÈ/ûsþBÿÈ;þ>÷úúk÷=èöh?±hÿ3ü™>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñªú²ÇÄzN§¬jZMž©ewªéžWÛ¬`¸GžÓÌ]Ñù¨äÞ •Ü@ÈÍhÑìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgøøKÖ/ü=ª[Aá¯É<Ö²Ça^ ÌP€2bÇS]?‹­µâ½h¦ƒ¯ÌŸmŸC¢ÝÈŒ<ÆåYb!ìA ö¯©è§ìÑØô¹yyŸà|…ömOþ…ßÿà†÷ÿUígC²KñáÝtÊ5É®¡´[¶bÚÈdî Yq­Ž†¾¯¢f‚9E(ÞÒzúÂ7¯ÿsÆŸøNÉÿÈ•¡á êvžš‰¢xŽHíÿ´n&žïF¹Œ“%Þyò”^@¡@É,רu‹ãOùõ¿úò›ÿ@4r%©ÊéÒƒš“Ó^Ÿä~lü]²»´ñÕëÝØ^Ø}¡"–$¾µ’ÝÝ6ÜE•†qØÑPüWÿ‘ÿTÿ¶_ú)(¬ÑÉJÜ‘·d}¡û:ÿÈÙãúñÓôeåUðWÁH~Óß¼k­ÛêvZF£.‡6‰qc­ÍmÛ[Ú”˜M/˜ªáFÙЩ°f˾Çvþ,ñoÙg†XéÛ¼èL™ýåæ1‡\wõ¯mò5oùý²ÿÀ7ÿãµ´>{ywû¬?®§ç5‡ìcñjóá›h’øvñðöM$ FÜ«_/‰[P[pQÛæ{p ±ù70 ëÎ>»ýŸ~êþñ·Äoëzwˆ,ïüI.Ÿ¸ñ6£§Oyv¶Ð,"X Qæl’F}›ˆOâõï#VÿŸÛ/üþ;G‘«Ïí—þ¿ÿ«=F¾Dñ÷ìßâýkö€»°Óì÷|$ñ>¿¥x«[+,+eÖ‘N.,å±2qö¹ÖI%ÛÛ ,…2>ªò5oùý²ÿÀ7ÿã´y·üþÙàÿñÚøªÙËân‰ñ:?Û隬6¼S«(Ð.ôÖÔžÇP¶-î![¶6ûKBÊë!‚<®v¥ûx’ÊÃá.›¦xBkúÁtiÚ†»ËiÚoöÔ:žt[bò’fW1+«µ2vÈßsy·üþÙàÿñÚ<[þl¿ð ÿøí|ÿûüñ_«/_øâÒ/Þ˧èÑ­…ÂKiq§é¶QÛZÜG‚]ZAæß´œÝÇÐý#YÞF­ÿ?¶_øÿüv#VÿŸÛ/üþ;@4Vw‘«Ïí—þ¿ÿ£ÈÕ¿çöËÿßÿŽÐäjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£Egy·üþÙàÿñÚÈÕo|I¥”ú#cq¨O> ³ÁQÄð!Ç–%f$μ`t4Ò¾ˆ¢Šã¾ÛãùíáûãUÿä:>ÛãùíáûãUÿä:¿g?åbº;+ŽûoŒç·…ÿïWÿèûoŒç·…ÿïWÿèösþVGcEqßmñüöð¿ýñªÿòmñüöð¿ýñªÿòÎÊÂèìh®;í¾1ÿžÞÿ¾5_þC£í¾1ÿžÞÿ¾5_þC£ÙÏùX]Ëè×~#¿Ô¥µ¹¾ðê²[Is¶Í/^L$!eŠ ?ãâ3œ÷è{kù·üþÙàÿñÚ†švc4h¬ï#VÿŸÛ/üþ;G‘«Ïí—þ¿ÿ¤äjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£Egy·üþÙàÿñÚ<[þl¿ð ÿøíhÑYÞF­ÿ?¶_øÿüv#VÿŸÛ/üþ;@4Vw‘«Ïí—þ¿ÿ£ÈÕ¿çöËÿßÿŽÐäjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£X¾4ÿ‘?[ÿ¯)¿ôV|[þl¿ð ÿøíex²-E|+¬™î­d‹ìSîXí™þíº!ÇåIìaˆþ ýä~oüWÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#íÙ×þFÏ׎›ÿ£/+Ý«Âg_ùÓïîžytÛ;YKcºÏHÁÙ$°ÈÙÃ"žmÔ}Þ„Õφ?ñùãoûgÿÑ0×M©x‹NÒ5='O»ºXouYž (pKLéÊÝ$lI8rÀ9þÖÐ?èñÿ¶_üGö¶ÿ@Ÿˆ¿ø%²ÿä é|KñwþפѮ×Z¼Ô¢‚;‰bÑü?©‘ËÞÖÐH¨NÆÂ±8Á½¯øŸKð¼vO©Ý‹U¼»†ÆÜmf2M+„@PO,Þ€rHšÓÚOù˜¬<þÖÐ?èñÿ¶_üGö¶ÿ@Ÿˆ¿ø%²ÿä ô}sĆíc¸Ôn<„–U‚%ÎòÈßuv8<('ƒéX—ÿü5¦øjmvkÙÚÆ¤±’8,n&º ê‹Ù’37˜K¯É³8 ãÑí'üÌ,ŽOû[@ÿ OÄ_üÙòÚÚý~"ÿà–Ëÿ+­°ø ßèë©“©ØÀ÷_bŠ-OG¼²¹šm»¶ÇÑ$²|¹9U#ån~VÆÆâM;Äö³\i·e†V·™7ŠHd€ÈØ*pÀ0=£ÚOù˜Yuý­ Ð'â/þ l¿ùímþ?ðKeÿÈëQí'üÌ,7Ñ'ÛÇi¤xª—dQCtˆ¹Î æ“ØÃüú?ÈüÆø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^Wªx÷ÆVþðÕÆ«: å °Û[y‚?>w;Q7r\ðª kÊÿg_ùU%P1+`ÇáP€’I'ȵÝkTð7Ĉž0ÒàûtÐx“ûìÙ°²5Ή¥OÇíicÐ\9¯¥è«=æ }øWÂ>1Ñ ËÞg|Fð…±¸“ïJÊ<;¹Ï»1f>ìjÄš„¿ o53iÔ®þ$)/@—É>2 ±_ªŽ3щn¤šú^ŠñÝwGðƉã}KOñ-žaà¸ôa¤Û\F#¶Kƒ=Ù¼/ $*m>ïÍÏËÞ°e"}FÇ\Õ¼Kfeñ]¥Æ™ÓÞGþ‘ÍáÝ(ÏÉåY™Ø7s€ÝúŠó{ûÛ |f¾Õõ©ÖÏKÔtK;+ÉþX"š‹—Cò¡užÜ€HÝågmr~<Ö.l·ðí¾ ¾Ò5 _KñV㋤0éšL–:tpøµ¼1É,»â2FÌÅ\£dL`®wÄž ð-‡‹E¶¿ ø~xsâ#À"Ô¬àv™i7…’VL8òâ‰îÞ'#…2”?{õ­óoÁm7]mgÁZïŠôñ ·‘õ+NðõÄZœò}ı^Ü›©U™•÷¼H£@›C^ƒû3h¶þßÛÚC î¡á½.[»„@fû*¸õ!wa€0ê4PðÇþ? "ÞÏâ9-äœãMWdR}‘ÈÿxÖ¯Ãøüñ·ýŒ3ÿè˜k¸ ø‹se¢ÜxþóH¾Õ¬<|ËšE¬×(µ ‘j‚Ù`‰."2 Ž$ U¼ßº»Mr?õ û½SVø}âÅ¿‰ôK-"æÞëL6«hšÍ›å^ <Ë—9dP?r­´#¹úzŠó¯ŠZ¿†£ƒKÕ5ÙèSøsZG[ùñ-½ÓÚH¾]Þ«[Ý7.Éþ¶2YsÁhÖ:ž¥¯ø‚îöçGÕ|hš…¶³¥¨··‘LŠÙn$%‹End•9ò[qRÎ~‚¢€>yÖÚÿ[ÓìLÅ寇l¼h?²¼Z’ ‰ì,³}ÂÉ2ºÈ¦åçµ(uÙ6yÀ5Ûü ·xm|c#_M®Å>¾òC M]>Ël¾qòÕcù µ¸1ª©ÀÉ'Óè •þ|?ðÞ·kðbÚÿD±¼¶×þK¨jÐͲ_Ïé+ ÌÄžZÜÌvv†qµq«à=*ÏâE§À{oÛÇâ {ï†÷W—qê+ç ‰¿âJwÉ»;Ž]›ŸâÃu¤è œ~ZÅkªüÔâ@š‡‰>\j:ÍÐÿY¨\«i%%™º»/Ú' Nv‰ +ëÿÌsþÁsÿìµÎ×EàßùŽØ.ý–€9Úó+í ÏÆ?|E§k–Qê:]—‡4Ù-a¹]Ѥ“Ü߉™Aà>-àù‡#y¯M®GǾ·Ô­eÖfÒã¼X¡6RI§=ë’ÂD?x®T€¥9€<·R¼Õ5ïÙóá.¿p·rÍá9níˆgžmGMÜîOÌJeòA*¤t>YüIøƒç_ZxK^VŽ¢ÛKñÔ /4ÎZC #ÊWè«.XŸ.A·å9íjZuÞc{áû«&Ó/tøï$ŠK'‘ÈÁÃ.åR¥N{/ËÛ›©ÙÅ×™ "™…­Ì‘áÑÕÀÞ…K.å©á×*À« wã¿ Osã ýWTÑÄþ}+k{Y&O%™¦œ‰`: Âþ(Ô,|§Iö/Ù ùEÅÂî–g€‘åy†Q.X’’ §iϪüGøs¦kàø‚÷H]@AÙÌ"Õî¬ÞåIfKyb‹ pŒKíI7 ³ £wÍcÆž·¿ÒÆ­s¢Û\mÅ”ßfÔ§µ•ƒd‹Ý ócbU'äñżºñåî—7„¼¢ë:dÞÒ¯¢ðæ¹vlm´xç7l#†@dpŒŒÆ[G‡Àô}*ùu?ÙšÎñ5].< ’®¡x»fº d–A“†lî#'’y­¯x.ÖçF]J]ÖH ¶[ RÏRžÎR¤¶ÃÊAæFĪN3‘´df×­RÇán¿m¼6‘ã\F¶öÿêâWòŒ`p8w~#ÿ‘‡Tÿ¯©ô3\펽m¨ÿgyQ^§ÛíMä^}ŒðíAåñ.ôTŸ½_ÝɵÎ ò>×x£â…añ6¯ž&ÑÒD»™YZþ ArÝYŸð±ü'ÿCF‹ÿƒøª­ã[øµ_…šõì+2Cs¢ÜL‹sÁ(Vˆ]•`bº/‹ñãâÿ÷.ÿöjâ<}ãï ^xÄvöþ#Ògž]6æ8âŽú&gc É$ñŠíþ,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQEQEQE4º‡Xo ¹äŒŸÔ~tê(¢€1¼ ÿg…F½ý³¯3ßê¬×¯´°¢ÀDw6Kb<“‚ØÁÆOMÿ _Ãú ]àU·ø×’xÂ:¿ªxÒãSÑtýFu×çe»µŽV "„…8É'溿øVÞÿ¡[EÿÁt?üMvð•ü8ÿ Å×þ[ð•ü8ÿ Å×þ[qÿð­¼#ÿB¶‹ÿ‚èøš?á[xGþ…mÿÐÿñ4ØÂWðãþƒ_ømþ4ÂWðãþƒ_ømþ5Çÿ¶ðý Ú/þ ¡ÿâhÿ…máú´_üCÿÄÐaÿ _Ãú ]àU·øÑÿ _Ãú ]àU·ø×ÿ ÛÂ?ô+h¿ø.‡ÿ‰£þ·„èVÑð]ÿ@‡ü%?è1uÿVßãGü%?è1uÿVßã\ü+oÿЭ¢ÿàºþ&øVÞÿ¡[EÿÁt?üMvð•ü8ÿ Å×þ[[°ñ߬Rö-7SškËËg´%¸/Œp­œç¶ðý Ú/þ ¡ÿâk¨øàO iwڭ퟇´«KÈ4ˆŠâ (’HÉ]¤«Èʳ;;ÐU°¬êªûŠ Sq Äã`€Àઞ %fx\±Ð´©.fÔ­á½ÕÒÉ¥@óD3æ§Ÿ»£åˑο,+:ª¾âƒÜB±#pèØ 08*§¨³ª«î(1MÄ+r7‚s‚ªz€Fn»â7JÑ~Üu[U¸%†ÔN›®!ä»Ôü¼.1¹ˆä…`MwÄ:n•¢ý¸ê¶«p K ¨7\CÉv©ùx\csÉ À€iK Ϊ¯¸ `Å7¬AÈÜ:6 Î ©êVN»â7JÑ~Üu[U¸%†ÔN›®!ä»Ôü¼.1¹ˆä…`táš;ˆ’Xd‰Ô2º†Aî(%…gUWÜP0b›ˆV änçTõ‚XVuU}Å)¸…bFáѰ@`pUOP¡â=rÇBÒ¤¹›R·†ö7WK&•ÍϘvž~îB—.G8VšïˆtÝ+EûqÕmVà–Q:n¸‡’ìSòð¸Ææ#’Ò–U_q@ÁŠn!Xƒ‘¸tlœSÔ$¬wÄ:n•¢ý¸ê¶«p K ¨7\CÉv©ùx\csÉ À·ÄúÛi>Õµ{#ïmc-Ü%¾hܬe—8<ƒÐô §þ=[þ‚—¿øÿãGü$z·ý/ð!ÿưï|?¬Ø^Ü[Iâ›$24lWÃo‚AÁÇúµCý•«ÐÑeÿ„Ûÿò}t_ð‘êßô½ÿÀ‡ÿå¼s#Íá=zIžG³™˜ä’Pä“Uõó©è¥©ÉâKIc²¶’å£_0,K?Óûâ¯üF³þÏÐxoUMQnôÅ™u=JßW» ,Ÿ½º H¤ûܶЩQ…`§p;›6z'ƒøeõox;Æk©¤Ö›â/†úܨºEžçû î C óɰ¨0¥6²‚:™ø~×@‹F‡MH¬"›í1ª;‰bÅŒÂLïó KîÜI<ó@c'м{q…t«äÔü#s«ø¢m*+­A4ù¯e±UÕϘëK¸–&UÛõH̸fVå<9oâ=cö¡·Ó/¼q­\'†­µK8åû5‚½ä!t ¶IñmœÞùlcvÁÂŒdg÷[O‡^±“M’-<ùÚ~¡&«Ï<'Úž -ÚWvbdcÒ'Î[‚?º¸‚ãág†®u›ãŒ4ÿ†ÖÞ(—Ziç×¾j~0ŠÛìÐ,zmÕ¼6oÂBe”ý°îóL™1©A*v~ x£ÆžÌ>/¹¸o xf/CæXÚâyíßèmˆ¸·aì|ÜKþ·åÉôùþøBçÃÖZšFí*Ë@¸ðÄÿi˜lÓfHRX7oÜw-¼#y%ÆÎdçG\ø} x“þí´ÿÂA¥®‹©þúEûEšùûbùXmÇÚ§ù— óõápÑWEàßùŽØ.ý–¹Úè¼ÿ1ÏûÏÿ²Ð;\§©ë!ø“«øgOÖ%ÐàÓ4[M@ÍoR<’ÜÍugÌVTZ6@ýx®ú¸Oèóé~!»ñŸª>sy¦¥…ÌòèòÞBR’HØ2 ÑùòœF$¯L€sñî·ñi´µ³Õ$ðòMàý'Ä.Ö¶ñHÍ5ñŸh>b¸ØŸfn ß÷¸£Àþ=Öþ-6–¶z¤žI¼¤ø…ÚÖÞ)¦¾3íÌWìÍÀÁ;þ÷¢|€íl.<;©O¡Ám¢ù·:4·iö{]æÊìØñ‰¤ÈcÞ ¯J‚¢ð­…LJu)ô8"Ð-´_6çF–í>Ïk¼ÀÙ]›14™ qûÁ•é@¿ü&>/ø¥x;YÓ.üM¡é7ž¶Ö®ÛÃ662<ÓÜ…`›¯b‘QÎÈþÞ.AùkÙ<)}o©ø_G¼´Õ$Öín,ášNP*(.cµTsÂÅq2x]ü¤iQèî¡£i–º,TqÝi“ÝÛG ì•TmX¦Ubž£få!VºÍÃÉá¯èz'‡,¬´Û{KKq{HE¬[¡]ÈC˜”¨c÷X†*À OĹüYyã-4‹ÿé:-–˜n®&ðÝ•Œ’\LòíU/{¡Ø‘9)Î|Õ$¶¤ñ—u='Àž Õ|?©[L¾¾Ñ!›\¸òüë¸noìàF±ªfXç‘™•T.0ª ›ž1´Ô4ýR]VË_½ÒR{!m*ͦÍ{f›ÍŒ)  HÛ‰'#Ëܤ*Öoˆü¤Yü5ðç†m¥½Ò´m]"æÖvÓæœtû›{…ˆP·U99]ኞ„ĹüYyã-4‹ÿé:-–˜n®&ðÝ•Œ’\LòíU/{¡Ø‘9)Î|Õ$¶·µËë}OডyiªI­ÚÜxzI¡ÔåñØ•™‚*(.cµTsÂÅ,‚úÚýµ› zÿHŠêÁ`‘.4¹îíQQ™Ä¨ ªÅ0Äç#ËÞ¤*Òk: …¾ßhº\rE¦i¾’ÎÖ9A±GlQd g ôŸÿÈê×Ô¿ú¬êÑñüŒ:§ý}Kÿ¡šçl|9¤éÙßcÒì­?³­M—‘n‰ö[såæ°>HÏ•ȸ»N>Q€ ïˆÿòOˆûCöuÿ‘³Æõã¦ÿèËÊ÷jðŸÙ×þFÏ׎›ÿ£/+Ý«h|(÷2ï÷X]BŠ(«=¢Š(¢Š(¢Š(¢Š(¢Š(+áo¯U×MûV¹ÿB­ïþ 4¿þK ®|áëËymî4Ë©à• rE&»©²º‘‚¤¬G§üA»{ÿxŽæ@¢I­®$`½*Äãó¨¯u}WN²¸»¹ðÍÜ6ÐFÒË#jš^d“þ—ØOñí¼–žñ®Éb´sœŒâ“ØÃüú?ÈüÎø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^W»W„þοò6xÃþ¼tßýy^í[CáG¹—ºÃúêQEYè…yOÅ/ˆÚ§þ%ø*Þ+„_ÜYÞÜjÐ4!™]iöÑÈ$ÎPF×¥Û¨*­ž€V®3Æ ìümâ;{ýFa%‚èZž…q`cÏŸãÚ36üñ´Z‘Œù™ÈÛÈ;¦üDÕ5Ú ü;Â/†¡Ò¯ÐÁäÒÞ[ɧ3Ê%Îvªßy{@ûÈù$€7¦þк”_ W[‡B£iÞÓ¼c}6¡©¬R4sÃrìŒb¶ÚdÿE'+«no•6ª·ià¿„GÂZ§…µ5ƒ¨^i:^¥ew+[ì7÷7·6·\Ÿœìý峟7úß½òóÏXþΟbøy­ø_þ ÿÚ^°ðGÚþÅ/ìÐÞGö­žg;¾ÙŸ/#^7Üvw6Õ`Õtíè¶Ë®j1ÜÝÛZ¾ DbÒy%q*û®"]Š®2ßxšÄÓ~1^k÷ú¥hË©jVú³Í Íÿ”–Òé÷Ú\!qn_2W€äªñ†%:¯xN]O^ÒõÝ:ò; gN·¸´Š[‹>&‚sHŒýëxXÃ;‚k ¾!еUÕêM>×YŠtxý¢}JúÞòYA ò’0xsòüÀ߯¿Gáψ~Òu‰?ð­4+ý/TºšûÍÓáûEÄ3X,1fEû“Îv¨ã=­ø?âlzv›ã RçÄ­ã/h:\Zœ^(TŒä-Ã\ÄHd1¤1>äP?}´ò3]Æ¡àññEñ9º 4í*ÿL6†,ù¿i–ÎMû³Æß±ã9ó:¼æÇðÂÐøÅ¸ºyü)­A%´zX]¿aŠXÌsE爈9TÛòÀ»U9/ˆŸõïM£i3iñèZ¦§{¥Ko,+tÙµ>Òò' û/Qr7}òUPk¯øKâCÄÞ¾¼Ô®>Ós¿­Ù#ìTÄ6ú¥Ô®òÇ.z¹$’IÀñ?Á«ÿjºF¥¬ø&»Ò^Óì­Ÿåƒzô¾`óçéñ&á´.I zWaà?ÿ¡ÜéßkûoªjZ—™åù{~×{=ÖÌdýÏ?fsÎÜàg'áü~xÛþÆÿôL5ÒxŸÄ–^Ðîµ[ö³À#‰wÉ+± ‘Æ¿ÄîÅUTrY€ï\ßÃøüñ·ýŒ3ÿè˜k[ÆÞÑþ!XYÚk+zc³º[Ûy4ýFæÆXæUd %·‘£·Ç=20>x›^ñçíüBcKÍ/ZŠÕ-¢ÚRÙM²¹0«7ík‡ÎKžrñê¾$>5¹ÔõÏø¯@Ð_VXé˧2 £Ën×DO(8‘X)ó—k/º_| O†²xâãCÖof¼ñ Ò]Û¾·ww©%£%¤P q5Ái~x™Ùƒ#2²G¸,HE«Ï‡z”Éi{¯K{ .®šÈ³¹„Ép%K…¹Š19~!I•YSfBª `£Å_üPÕôûqs¬%¶®;m®–ÿáþ¹¯kðkİê>µÔST¶ÓWM\‰c2’àIµã²·È»¹ÜÃð²_ùÿjÅÿçöçöñ°ûó¼ÿµ}³h—~6ý§÷Ÿswlâ€5<{ãK¿ MáËM?L‹UÔ5ÝEôÛhfº6è®-..3„rÄ@$€Äncïõ­SÃñ_xr->ÃWÔït¹‹Pó5E¹3¦Ï)A‡ý áV]Á‰UýØ ‘Øø£Â?ð’kžÔ~×öoøGõI5//ËÝöÖWV»3‘·jßœ¹Œs‘Îéÿ³áÿ‰·™ý‹âWÄ¿ñí;í¿Ú?¹ûÿ.Ïí¿Îï+î®ï”Å| ñŠMKáNâ ð˜|AŸB†üø/~‘/Ú/švµò-í’á3!1ýü¦rÙÁ¯jøñZãáÝž³q¥Z½Ž›nn€¸Õ#†æö5MòhB±r£*Ša€0A&‘ðûáσt =\Á®x[N´±³×Rßü˜ãGîb”F7ſІ ªÃâGÀ]KÇ2øÎ+?[i6^*³k[©%ÑÅÕí¾m„ ¥! nhü²I’R®…òñŸâ¾¹ øâ]×…tï:çÂú|é>£çÆ$µº6bá^8]JH#I`‘ƒ²‚ 9OÐ~ ÿ˜çý‚çÿÙkÅ<ƒO´ðö›q­Å.m­ùW:ÌÖ±}žçp…NÝáäE&K /–éYþðµði¦ÏJ—Ä^OƒôŸ°µ¸Š2³X}£i>c/Êÿjo˜dŸwš<à=ká ÓMž•/ˆ¼Ÿé>akqef°ûFÒ|Æ_•þÔß0É>ï4kÇÿi³¬hŠ#†Q#ÉóäGÔðíW[¾Õ5øFWE7úņo¨j6c^ž+HÄí,krlff¶˜otL„RÅrÕñZ¥—ˆïo-ü+e¯ÙÞi‰h*;¿1^Bcå`܉rTù‡koâ.ü¬xgÃ^ÑÂw>.Ôì|?m¥Yê©jhÐ)jÒFï`哹ÁŒ¬><ƒâ–—‡t»­bZë¾Mæ¯5š k Â`»÷I ŠL–òÏ–é[ºÎ¹gâ‚7ÚΜÎú~£áÙ.íÚV,Æ9-‹¡$““‚9Éú×;áoêÿ ¯md°Ógñ:'…4½tÅy¶&ãk0‘—å“íD’ #gCšÔ¯à_ÙÙ|7$¢i4o 9¥^Žb´òÉ]´êþ#ÿ‘‡Tÿ¯©ô3YÕ£â?ùuOúú—ÿC5ÎØéw6ŸÙÞn±{{ö[So/ž¶9òÿ.È× Ä{÷¯”8M ßÿäžx£þÁw_ú%«gâÇüxø¿ýË¿ýš¹ßÚËcð³^¶šòmBht[ˆÞòä –v028U1;UW'€Ñ|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆûCöuÿ‘³Æõã¦ÿèËÊ÷jðŸÙ×þFÏ׎›ÿ£/+Ý«h|(÷2ï÷X]BŠ(«=¢Š(¢Š(¢Š(¢Š(¢Š(’øO¤ß_ÜxÞKk+‹ˆÇˆçRÑDÌò`ã {Šï¿áÕ¿è{ÿ€ïþæš?~!^Þkv~þɵÓ4ÍFk5Yîî!fn$fÚŠG>fIîrqZð”ü_ÿŸ ÿWŸüEwðŽjßô ½ÿÀwÿ ?áÕ¿è{ÿ€ïþÃÿÂSñþ~t/ü^ñÂSñþ~t/ü^ñÜÂ9«Ð.÷ÿßü(ÿ„sVÿ ]ïþ¿øWÿ OÅÿùùпðeyÿÄQÿ OÅÿùùпðeyÿÄPqÿæ­ÿ@»ßüð£þÍ[þw¿øÿá\?ü%?ÿççBÿÁ•çÿGü%?ÿççBÿÁ•çÿ@Çü#š·ýïðÿÂøG5oúÞÿà;ÿ…pÿð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEwðŽjßô ½ÿÀwÿ ÛðÆ“}a·%͕żgLCK('Ž2G±¯,ÿ„§âÿüüè_ø2¼ÿâ+cÂ÷Ÿ5ûùâÕoôx4¸m¥¸º6÷—SHÈ«÷UYUIb@äàN6 õ™â=Ç]Ò¤¶›M·šöGTKÖ‰ ÃϘ7~îJŸ›f#N£–eUŸpBÁKí%T“¸ô\’Œ–QÔ€@3ußiº®‹ö¥ZµÁ)7BÝo!Ô£ååq¬3k¾Óu]ì'Jµk‚R(n„ ºÞC¨=GËÊã;Xf#JY–V}Á /´•RNãÑrHPN2YGR%™`UgܰRûIU$àn=$…ã%”u  ÝwÃÚn«¢ý„éV­pJE Ð7[ÃÈu¨ùy\gkÀ Äià vñ$Q"Ç(UD ØRK2ÀªÏ¸!`¥ö’ªIÀÜz.I ÆK(ê@2Pgˆô;wJ’Úm6ÞkÙQ/Z$/ G>`Üyû¹*~l8a˜†k¾Óu]ì'Jµk‚R(n„ ºÞC¨=GËÊã;Xf#JY–V}Á /´•RNãÑrHPN2YGR%™`UgܰRûIU$àn=$…ã%”u  ÝwÃÚn«¢ý„éV­pJE Ð7[ÃÈu¨ùy\gkÀ Ä;^УÖ<1¨èÑ2ÙÅug%¢²&V ÈP¹ ôã¥hK2ÀªÏ¸!`¥ö’ªIÀÜz.I ÆK(ê@)ss ¼·¤D†I%‘‚ª(,Ià9Í7V¶ÔõVöî?ZCó<«xyœ f$ßnÆzà}UþÊÕ¿èh²ÿÂmÿù>³¿ácøOþ†ÿÿñTÂÇðŸý /þ !ÿâ¨MoÂºŽ½£_é—*µH/mä¶‘£ðã êT‘›ò3ƒèjÿÄ«´¿Ñ{™wû¬?®¡EUž‰Å|Oø›oðÂ\]X½Ý®©©ý‚y’UO±Ä-§¸’áƒ}åD·b@ç#8Á\a¶’Ká?‡úî‰ð§à½¼öDk>·²’ÿKIãÝ#®™5œ±«îØYZà¿ÞÚ|¿½È4ÛIñOÃ1Y[]5ü»./ŸLŽ!g9›íIÊИ‚oWÙAo” –PixûÇúŸ‡àðŒ~ÑíuCÄšØ-¢Õ/dÓ¢ˆ}Žæì»°‚Wm±]¾^rÃ8Á®B×À>!ºñΛâôÃmÇŽ_]šÚIâi--G‡¤ÓÕŸk,Ó*¨[P{1'ÅßOñRð/³´ý}ïu ´ýF[ á‡û6ú%e–)Q™f…HFÉr6î ÏñZëCÒ|cÿ ›c¤ëÑW\ºŽ+ùn,L·ž¶âLfÒ`Ø€°­ |7ñÃHÖ¼Oã"êÛPÓÃÿdkË6î;y”Alä‰^%y’àªF³ª¬ˆMAñá\)ðWâá‹+‹ÍgZÐ/l¢kÛù.nn¥ki#…ââFcË`| žœÖ>¯ào\ë~;³‹K™­µOé^)³ÔRxD 5ÒÃZ0/æ,®leÁÙåía—Šéµï6‘‹qMyew¬I£Þ·‘2Oc"ÙÏr3nc2;±Š4…ùêÃ<é¼'ã-+ÆÚt·šLÓ:C1·ž»Ymg‚P–•d¶²¶A*ÊGÉkºˆ|]âê3h ¦[èþ&šîh廊IÓû*ö• ™§EØŒä¬Hù‚êøÃÚ†‹âŸˆ÷—–þM¶¯¯Å{dûÕ¼ØWK°€¶%y«†ÁùsŒH_ ãóÆßö0Ïÿ¢a­ˆ+oø3V×ÐjÚCºC/”'”±Æ_ °3²‚Ø888Åd|1ÿÏØÃ?þ‰†¶¼oay¨ønh¬4ý;UºI ™lõDß ¢9‘زûTìcÂ¾Æ ŠÍøuâ­oÅ–×·:¥§†á·Ö8&ðæ¼úª;sæ+–¶„!_“nÎã¸ü@¾%Ûx>;IL’i÷w¯xࢬÁ_Ÿå½Œ–ü£qÜ;C°Õm|SâÿK¢ÝÀ·z}¥µ¾ˆ²Û››‰-Ë™yAäóÒ1ºAÄ+¸¨ékUðö¡sñ“Âúävû´«-W²žãz“Mq¦¼K·;Žå·˜äÎHÈÈNµã¯h~0Ò4É|+áé´ÝSS6vóÃâ9ÍßÙÆçyÚb‰ óq»–Rdo‹Œ"˜Ò3á¿íïøGMñºÄÿhûoØwvcËûOÉû±ómÅj P¼ø¾ÚÕÌÒtý ml'Þ§|óÎÍr6çpÚ¶Ö¼߀NN¹à}CÄþ,†Î?ÝhðkÐjóëKª$– ÂN;u“pžS+–…pLHÿÄéž)ñ–“àË{9µiå…o'6Öé´·M(ŠIv*F¬ÅŠDødeˆ+Cø·á_ê–:}†£,—7ÁþÏæÙO ;¢–xwº*«3BH‘B±*8Ǿ¿Ö¼SðâîÎßζÒuùoo_z¯• Òïà ‚AoÞÏár~lã‘Æh?uû/øAüí?göo|A­]þú3åÙÜÿlùðÜîû]·Ê2ÃÌä ­€Ð~5ø¾ëáŸÄMcÁš-„¦Ñã×ekKu{ «B&'Ék(Ñ™P’TIØ»Œú»ñ3Þ–þ;ýA£þÏÙöÙ"¶–Xí7Ëç:)XþRæ#‚x9¯ð_ìûwá/…þ• Öu=kKÒ¬`Ö<)©xŽêæÂá„Q,è‘IpÖêñ•o,ÜðWt¹ñÏÃ|WeãÝMѵ-bKKš×D6Ú¥½¦›½®×[¥gÉ1”ɱ¢+å«Íwÿ~3è <ñu¾k&‹6©˜–¶É:l÷—¨J¬ÿºoݪ8b£œœœ ½uyöµaàߌ¾"ÕµÛètí:óÃztV’ܶÕw‚æý§U'‚ظ·ùG'#ƒŠØñgí#Ñ¢Ó[[¶X®íQg²Ó'¼”¢Œ-ÊùL|´RÙV#‚IÜp0x³Æö‘èÑi­­Û,Wv‹¨³Ùi“ÞJQFå|¦>Z)l«Á$î8ó_„²†-£Iã ´ÒØ|=ðýkÖ+ºâÔÝý©=\àù~ñÈàℲ†-£Iã ´ÒØ|=ðýkÖ+ºâÔÝý©=\àù~ñÈàâ€;ßüM°ÒtÝ;G—Sšc«[}º!¢øvûUš@›@¸_²‰<¥S*”,:·Þl wEðÔô›+Åó1qL<ëi-ŸæP~h¤ã<òŽ/CÈ5áÒto øWÂxÇPÖ¼?­Úx#K´k±vÖ°´‘« 'BçWÁhÛ †‹ Çv=kÁºåôü1ã `Ó5»‹Ôì±*ßJ±¡ˆgsLûGV`$PÞ:ÖŸ¡ÇkuªÚiV7×–ö¨òZ<Ó=ÔŽ#ƒaW!Ÿ …ùyf8\®ÄˆÐøfÈ躄ºœQËÝÍs¦xKSÔ‘Ywq5ººFP†`¤î\†9MRøù¦ÚËáPx¯müI Cä|è’kšyuÑŒiŸ÷E]øË!¿Ò4/ ƒ…ñ>±—0þý°Y.nc>Ïom2g4ýsâ-…ÿ…ì¡ZŽ]JÂ-W÷z5Ô·"2¿%ÁŒð*î$oPU³’Jüº^5»PøW¯]Eq äSè³È—ÿêå!—“òœärx=Mqß|A¡xÇZ£x®ÛÃúAjlo-L¦þ(eâKL²†¸ <Ãbù‡çBÈFÜÝÒ4¯ ~Ì–Z-ô"Þ÷MðzYÏ9ÉF\÷ÁR(ÛõýS‡]Ô£R»HÒæEUYØ3T?á#Õ¿è){ÿþ4xþFSþ¾¥ÿÐÍs¶3êÒg}²ÊÊ ö¥ï|‹Ç—ȸýÞ#‹1/›2þñ¶±>C¼ìwÄ/k0øÄÒG«ß$‰¦\²²Ü¸ ˆ›Ôß?ãÇÅÿî]ÿìÕÎøÖK¹~kÏ6×í¢Üˆ-¦3EžCnT¢PrRG;GJè¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQEQEQEQEÃü1ÿÏØÃ?þ‰†»Šä<9ñoCðTúæ§x>ûW›ûJio®×I–ó}Á ‘¼6 p#$“³ÿ oÿDóPÿÂjoñ  j+'þ"ßþ‰æ¡ÿ„ÔßãGü4E¿ýÍCÿ ©¿Æ€5¨¬Ÿøh‹ú'š‡þSðÑÿôO5ü&¦ÿÖ¢²á¢-ÿèžjøMMþ4ÃD[ÿÑ<Ô?ðš›ühZŠÉÿ†ˆ·ÿ¢y¨á57øÑÿ oÿDóPÿÂjoñ  jè¼ÿ1ÏûÏÿ²×ÿ oÿDóPÿÂjoñ­-ãeljnæÓ4ÿê/q‹-Ëh’[$Qm%Ù¤f@¿S€$%fxŽÞc¥I=–«qg¨ïXaµQ$¥²a·Êy`¤™ ŒN“®ÙÜ&‹æZkPjjR¡+ YÙ²7cÏÊ~f ü9!@C“]³¸MÌ´Ö. ÔÔ¤BV³³do ÇŸ”üÌørB€‡:ÔPN»gpš/™i¬]A©©H"„¬%gfÈÞA?)ù˜/ðä…táCH#JÊ ˜úœ2}€ú(3Ävó*Iìµ[‹=Gzà ªˆ™%- …¾SË$ìÉlbY®ÙÜ&‹æZkPjjR¡+ YÙ²7cÏÊ~f ü9!@Cj(']³¸MÌ´Ö. ÔÔ¤BV³³do ÇŸ”üÌørB€‡0øÃK¹Ô¼­éÖÛ®¯.4éíâÞUZGh™FO 'ØsÚ·( ëú†¯q®êRÁ᛹à{™9WSÓu,H °FG¨¨}«\ÿ¡V÷ÿš_ÿ%ÖÌx²ÓÄ:÷…u2ßÂ÷I=í”ÖÑ´š®˜3¡PN.ÉÆO¡­ÏŠr$Úg‹dÕãxîÙYNA65n±|iÿ"~·ÿ^Sè“ØÃüú?ÈüÓø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^W»W„þοò6xÃþ¼tßýy^í[CáG¹—ºÃúêQEYè…cxkÆ7Œ"Ôdѵ¯×N¾ŸL»òò 70¶Ùc`@ÁSøÈ5³_)éƒWÓìõ=9ä ã½o_ðé• kpšõñóSý¡i%Ûçþ#ô_†ü øÃGÓ5]ôêÚf£q5­µå¤I$„ Ù@=ºŠøÆ /k^ 𦗥»Kwâ é>)]9g{Û-9òîp2|øôŒœsótÀ¯¢~Iý­àËŸ°;üO©\ë*Ç«@ï²ÔŸ³En? »ðÇþ?2oêºw„ôRñkÚd÷i;ý«VòÀx®"1 †ÉÛ&r09ǾִÀ²ë¹‚ãRÕ¼L§\Ÿ]sa§é—±ÚˆI»Ev´JŠÌêí$/»} Z?|C§ëWÞ4³³¸ó®t‹Yl¯Sc/•3Aár@ û¹âl®GÍŒä>QðF£­¥å½´ž ƒÇ¡u!m éÿdm)¢7Kv¼’É%q¸Ü{ì™m¥[^üi S¢>§3Ùìº:^›™'îݰ (M»FÜPuYž#¸˜iRAe¥\^j;Öhn”Ä©\¹g ó¨f@'{CþÍ7þÿøF¾Í­hÿÏì;ß±«ó?ãóÉû?ÝãýgÞù~÷Ê_hV~1øËâ-;\²QÒì¼9¦Ék Êî$žæüLÊñoÌ9ëÍvúíåÃè¾]¦u>¦Å'ŠbÐ…—'a&LüÇåb¿Ã‡85ÛˇÑ|»Mê}MŠOÅ¡ .NÂL™ùÊŇ 1qâ¿ -ÏÄæÑ‹í¨ƒáï‡ï6^)e7Fìܸ£þâ›ï^hÔ¯5M{ö|øK¯ßßÜ-ܳxN[»bÙç›QÓw;“ó»¥g|J©Õ®Þ\>‹åÚh÷SêlRx¦-XrvdÏÌ~V+ü9ˆs8\É;FÑ3(&7Æå>‡ŒbEyŸŽü1=ÏŒ/õ]SDOøyôx­­ídš4]>t–fšr$a€èðüé—_³ðkwàÅíî£ð{À·z”ó]j3è6ÜÏp1$’µºfÿh±$ûšßñÄÃJ’ -*âóQÞ³Ct¦%HŠä…Ë8o˜ðÅ@;2;Øk·—¢ùvš=Ôú›ž)‹B\„™3ó•Šÿ@bã“ø…á›_Ýj†ÞßOñ.¹˜‹ƒªÞ‚ÙͶáQP²¼Œ»7’2!ùYJ¶y'Nðþ±ð³Â¾"Õ¤¾ñ“ê>°´Ó¬µ"¾eÜ­ñ"'ð\K½KÉ»" ” ì@=K]¼¸}Ë´Ñî§ÔؤñLZ°2äì$ÉŸ˜ü¬WørçÕÏ VçÄûxí4AìŠ(n‘9À€ÖoâÕ~k×°¬É ΋q2-Ì¡Z {™wû¬?®¡EUžˆQEQEQEQEQEÃü1ÿÏØÃ?þ‰†»ŠÆð7ü!ž÷öμϨj³^¼VÒ‹!!ÜÙ-ˆòN c=7ü%?è1uÿVßã@¨«¿ð•ü8ÿ Å×þ[ð•ü8ÿ Å×þ[R¢®ÿÂWðãþƒ_ømþ4ÂWðãþƒ_ømþ4JŠ»ÿ _Ãú ]àU·øÑÿ _Ãú ]àU·øÐ**ïü%?è1uÿVßãGü%?è1uÿVßã@«¢ðoüÇ?ì?þËY_ð•ü8ÿ Å×þ[[°ñ߬Rö-7SškËËg´%¸/Œp­œç\|#o©ZˬͥÇx±Bl¤’N{;‡W%„8ˆ~ñ\©Kr027uÕ°¬êªûŠ Sq Äã`€Àઞ Æø·Á’èÑêO¢[²ø>Ù&Ñlnô› ìæ[8ïd„Ås©=²Æ?˜ !M£#qM¬¸8n–XVuU}Å)¸…bFáѰ@`pUOP%…gUWÜP0b›ˆV änçTõ€âëÀž!Ô´hï^VÎá-õ›«C8;™mäŽ æ6báRMÀ’ÃhÝóviÉ}aoo:½¸¡—eÃŵ£up¡©)•©ù]r¬ ±SfXVuU}Å)¸…bFáѰ@`pUOP’€9xB×T²—W¸Òa¾Hâû¯£5¥ÄŠä‘ò×÷ˆä±ä27aø÷á.—«­—‰fÓn£ŸL³]61£xŸQÒšc¸AvÌŠÁÊ€RQA ^,+:ª¾âƒÜB±#pèØ 08*§¨³ª«î(1MÄ+r7‚s‚ªz€@âoÛ/‡íïeÒþÛ•’i’Iý¹v—n¤|°´ o¸ÞT€]‹3gp²×üol¶ µût‚+T‹F¸`ƒý\`@À*ð8è+¦–U_q@ÁŠn!Xƒ‘¸tlœSÔ$  (ø…áX|M«Ç'‰´t‘.æVV¿ˆCœ‚7Vgü, ÿÐÑ¢ÿàÂþ*»?øHõoú ^ÿàCÿð‘êßô½ÿÀ‡ÿòïxûÞñ½¿ˆô™ç—M¹Ž8£¾‰™ØÄÀ(²I6…ú}]X°V©Ãzgð#ó§Wü Ðo­>(ü`¾›Äšõ©ñ"F4ÛˆíEº³izlŠà¤+&äV._nŃ>\ïéš–»âÏøš+M]´›Oëödû$rÇy³¶¹”±8pÄ\”R¬˜Á!ù¿¢¼rëÇšñУñZj ãðñÑÌù-oý±ý˜\±_3yÏœ`: ¸¬jšç‹|%c­Ëª›kþ Xi­£=ªÚoClޝĂBð,»‹ÚÌ6t`ô áÿ ¾$xïÇrøCY›Âºõ¦‰­Û «ÙµÒÖÆÖ'·ibkqÃ\“¿Ê&HrÌŒWað+TÖ|Mð³Â~$Öõ‰µKÝoE°¿‘cHžHÛhå·s‘œí >PGÀþеýSÆ—ž‹§ê3®¿,ÕfÐ|+¬êvê=•”×1¬€•,ˆX‚2=EkW;ñþIçŠ?ìuÿ¢Z€5ï|?¬Ø^Ü[Iâ›$24lWÃo‚AÁÇúµCý•«ÐÑeÿ„Ûÿò}t^#ÿ‘‡Tÿ¯©ô3YÔÏëçSÐ4-KS“Ä–’Çem%ËF¾`X"– §÷Å_øgýŸ x–×™ä[ÜÅ¿ݵXg…g|Gÿ’yâûÝè–­Ÿ‹ñãâÿ÷.ÿöjOc Gðgèÿ#ó â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ+l|Í/áÇÑh~οò6xÃþ¼tßýy^í^û:ÿÈÙãúñÓôeå{µm…æ]þëë¨QEg¢ÎÝ|>Ð/´üë ÿÚZ¥¦µuûé™ymö"^¿c·ùFù|ƒ¹³ÑQ@š÷ƒ4Ì&¾·—Ï Ö×2ÛÈñ“4l¥“<í$޼sT?áWx\xwÄz i1Å£ø†#¥iމ2Hí6®ycȆ$6ãnG$“ÕQ@–~ Ò´ÿ_x†Ú)àÔï%×—w0‚bHÐnòŒbD›wíP»±ÅG©xBÕõxµ;»6ê9¢¸ÿ]"ÆòÇÌRA¸1„7–d¼®rÎy¨µ/†~Õõ$¾¹°v.â¿UK©£ˆ\Æèé7–®~è×-Œ‘r ¨¢€9Í?áï‡ô­RßP¶°òî-Œl†ic&w˜¢,R2A ”QÃКÒð燴ÿ x{KÐô›²iZe¬VV–ûÙü¨c@ˆ»˜–8U$’qÉ5£Epÿ ãóÆßö0Ïÿ¢a®â²¾øõSÅ7wwz~š—ºä÷éyrä‹dhhɲ63‚@Î0A=¿ü!¿õÑð/ÿ­@>»ám7Äok%ô2íš ‹yä‚X‹.ÖÛ$l¬žxô¦éþÒ´»{Kk[wŠÒÖÚ[TµÈad‘•Ÿ|e¶ÈÄ ùÜŸo}Ý×ü!¿õÑð/ÿ­Gü!¿õÑð/ÿ­@giðÃÃÖBÿʶ»2^ZÉdóɨÜÉ,P?ÞŠBЯP ©ÀÆw†~ xcÂ:cëñØÍbÚwÙnÐÐ/´üë ÿÚZ¥¦µuûé™ymö"^¿c·ùFù|ƒ¹³èŸð†ÿÔsEÿÀ¿þµð†ÿÔsEÿÀ¿þµsµÑx7þcŸö Ÿÿe£þßúŽh¿øÿÖ­'I‡A·Õå—WÓ'ól&…Þä3 ÁÒ€8Ê(¢€ (¢€ (¢€ (¢€ ç~#ÿÉ<ñGý‚î¿ôKWEUµ->ßWÓ®¬nãómn¢x&q]ÈÀ†# ž”µâ?ùuOúú—ÿC5ÎØøsIÒÿ³¾Ç¥ÙZgZ›/"Ýì¶çËÌ1`|‘Ÿ*/‘p?vœ|£^èzF£{qu=•ÛO<,…uÝMf98Qräôü"úüøÞÿàÿTÿäªÅñ®›i£|,׬,-a±°µÑn ·µ¶ŒG1¬ ªˆ ªÀº/‹ñãâÿ÷.ÿöj¥sàï^[Ëoq¦]O¨c’)5ÝM•ÔŒ Ý`‚8Å?â ÛßøsÄw2Mmq#è V''±†#ø3ô‘ù™ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè´?g_ùc™`e†áQ¿Ç®,ô¹´Ýkæñ­•ç‡WÍ(ºŒwKo;O’aS¾O½ˆÈa¸’ Ô(¯1øeâŸkŸ~%éúÍžšº“­ KàÔIãÆÆTÊû: ¬³4¬ÆBUähÀePçþ{ëïêv‘¢N×J¿ƒNÔ®>رI ’CÅ’6uH牛æS‚B†#¯¢¼öãâÃEz”zRËá³®½ÿÚ±0¸7ŸbÜ!Ù‚‚ç÷yÞ2ÛqXâ¾¹¯xƒáUÆŸ§}‡ÂÞ*Ô$xïVxåk›_ìËˈ’T* EÌpʦ6cˆÙX¯Fö+È<ûMxKÇž$д½3XЯN»æ ,5¨®o¬O7úE²Ð.7$å¶¶°Mv |mñÁº?‰.4˜t›-[OµÔ-/ îVXƒÃË@ÈÁçp §*9Í@¿ñŽ­â©¦ñV½§¥ž±5¤0Xܢƨ621êç¾1ŠÚÿ…cqÿC·Š¿ð.þ5GÃøüñ·ýŒ3ÿè˜k¸ þÇýÞ*ÿÀ¸øÕð¬n?èvñWþÃÿÆ«•=ÖÛDo6©"ÙÂ<ºJÛÅ䘵Ɨ’Å|Íû³.Cã¶Úõ]bKøô÷:d0Íz̈¢áÊ¢à3œ ªY¶ñ»nÜ®r9OøV7ô;x«ÿáÿãT±¸ÿ¡ÛÅ_øÿ¯=²ø½ª¿>jZ¥þ£o‰|<·×÷z.–u Aîͽ´ˆÞ(d>Yó'guˆª•Œ|¡ÅD>,ëZLJ|k6­{¤¶¶ºÔº¾‘¦ «æµ¶¸H` måJyxE17—¶`Uvå@=þÇýÞ*ÿÀ¸øÕð¬n?èvñWþÃÿÆ«gÀ—¨xRÂw×#ñ#0qý§ ž°‘xWml7+|«÷Gxkã‰ÈñewE*²ÎV@ ˜U FãèP'áÿ^xwÆÞ&Õ Ôà“I×§Kéì$´>|wkoolfcËò­—(c's¼–˜<}aâMGQÒ5¡¦Zê·ðê:”dYešHኩ#"¼pD­ò1À%J“‘×Ñ@yu𙦉tÈõe‡Ãƒ]_µˆµÌæà^‹â¢mønFò6‚Wv*3áÆ—{àˆcÖã:ƒæ/¦éßbÄž_ØçµDyDœ”Žp)È%ƒ/¤Ñ@gƒ| ¨ø2×EÒ-5ÑÿÖoö[]=l”Jñ*ì‰%˜±ÈEÆ6*TdžAÑøqáøWÿ“}qãy-¬®.##KE0ɃŒî+¾ÿ„sVÿ ]ïþ¿øP—…’ÿÈ?ûV/øG?·?·‡Ø‡çý«í›D»ñ·í?¼û›»gÛÚÇv“ޙᖔdŠ{r]·¶ñ#nFÖUÛ•,Û_ðŽjßô ½ÿÀwÿ ?áÕ¿è{ÿ€ïþäÞøE7„ü=à+};YOíŸ h#@Šúâ̼70˜íÖBЉRÍi ?Ë‚2A56ðªOÙi“hº¤1x‚ɯØê7öfx¥7×"êï1,‘UVP®6íæÔÿáÕ¿è{ÿ€ïþÂ9«Ð.÷ÿßü(ð7„£ðO‡—LK—¼vºº¾šáÔ)’k‹‰.%`£…d¯Ø`W5ào„ð†¼ÿ‰·Û?áð´¾ÿmŸkßöß}ó³aûŸ7úß½òüÞ«ÿæ­ÿ@»ßüð£þÍ[þw¿øÿá@Uào„ð†¼ÿ‰·Û?áð´¾ÿmŸkßöß}ó³aûŸ7úß½òüǾÿÂÿ óþ&ßlÿ„KÂÒøkþ=¶}¯Ø}÷ÎÌ}‡î|ßë~÷Ëóz¯ü#š·ýïðÿÂøG5oúÞÿà;ÿ…gWEàßùŽØ.ý–³¿áÕ¿è{ÿ€ïþ·á&úÂ=nK›+‹xΙ:†–&POdc@Q@Q@Q@Q@s¿ÿäžx£þÁw_ú%«¢¬ïéðx{TÒüß³ýºÖ[o7ní›Ð®ìdgÎ2(¢ñüŒ:§ý}Kÿ¡šçlt»›Oìï7X½½û-©·—ÏHÛù¿—dk‰Æâ=‰û×Ê&ÛZµ¶§¨ê··qø’Òç™åXÛÃÌå1 ûpÎ3×è*¯öV­ÿCE—þoÿÉô‹ã[Yl~kÖÓ^M¨M‹qÞ\„ÎÂGª f#'jªäðâº/‹ñãâÿ÷.ÿöjÊÖü+¨ëÚ5þ™qâ«T‚öÞKi?0`®¥I¿#8>†¯üJ»KýÅ1†ÍÌŠ¨1üé=Œ1ÁŸ£üÌŠÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQX¾5ñ$^ ðn½â Œ"*ÂâùÍ˺D(ÙÎö$p¸^J£°^øËá? jw¶…õÔsXJ!½’-2êhlÉŽ9CÏ2FcŠ=’¡ó•>÷Í•lvÔWào‹v~5ñ¿Œü5©ZÜøwP6bâ}6ê8'Qom#7œñ,a·Ü¨—EYW(á«wRñæ…¤ki—wÞUÜ“EoÄ24i,¼EÈ¢3ämV œŒg# ÎÏñ@·Õ“N’ø‰ÞèY >ÐG™‚ùaûm-œ1ž+÷ã>†¾.ðŸ‡ô÷…ƽ¨Of²ñ Ž+[™žh™“láZÝc!åóA'  E`éÞ9Ñ5mM,-oç”9…Ú )ö}ï*VP’ÎB1àÐQáhþ:Ó£¿Ñ'šîÊXb¸Žáí&…$Ir•2"†ã‚JC`ŒPã߈W·šÝŸ‡?²mtÍ3QšÍV{»ˆY›‰¶¢‘Ï™’{œœVŸü%?ÿççBÿÁ•çÿYß ãóÆßö0Ïÿ¢a®â€9øJ~/ÿÏÎ…ÿƒ+Ïþ"øJ~/ÿÏÎ…ÿƒ+Ïþ"±GÅYµúé1ÿÂ:ºçö_µàþÔ-7¶`§ÚO—÷÷qœWO⻿ÙéÑ¿†´½3V¿2€ðjº”–1,x9a$vó’ÙÚ6íà ¿á)ø¿ÿ?:þ ¯?øŠ?á)ø¿ÿ?:þ ¯?øŠÁð¯Å+íCÁ×:Ö¿£ÙéÓNM2ÂÛJÔ^ù5"S¼ŸšQ å1µ<ÍÛFV¥ñÂçþokš^—¤½ÏЬ£Ô6k:ËXYÙÀÖÂff¸HN Æ€ycq|ü¸Åvð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEixZÿQÕ4 ;ÍVÛO´¾™K´Z]ó^Ûm$ì)3EpWiÎÁ‚H'’¶øõà«ËT¸·¿¾¸Ž[t»€C£Þ»ÜÄÊ|*!Ý(PFÿ,7–x}¤@ð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEC¬üTðƇi¥ÜϨIs©f÷ö'N³žôÜÛ¯•ºHÄ(å€ÆÜºK}Õb&ðçÄ¿x·Um;JÔ ÍÏÙþ×måŽ;ˆA ÒC#(I•Y”1Œ°RÊŒ€ð”ü_ÿŸ ÿWŸüElx^ó↿0Oa®#òVßûdjl…wy›ÀÌ #€wb Ð<â=0|ÐeÒ$6^ ˜%Þ°nae¸DÒîíÕwïØ3(ÃÌ=ªŠð¿„ÿ¿á›Áv·ºN¹}{áè m«ßø²îâÄH¶ïn%·³yÝ2èì6˜£XöÓÀÐ> xzÿÂ?ü¡ê¶ÿdÕtÍÂÎî êþ\ÑÛ¢H»”•8`FA ö&»J(‡øcÿž6ÿ±†ý wÃü1ÿÏØÃ?þ‰†»ŠñÓà=hhŸð‰ÿeKö3ãøH?µþÑ’!þ×þÔÁ]ÞfíÙ‹nÜwÝŠïü[}®?„¼Wý‡¦Nu»kI×KYd‰Vö³‡ˆ¡ß…_1¼¼É°îF8Ûµ›£¢€<šo„~&Ò¯<(Þñ.‹a§øwHM´±Ö4)¯Är…Ø÷ ÑÞA‡h§!ˆðG˜ÀÕø[áxá§ÂÛm[AÓõODðúé·ñZEw¶åB!‘æ1^\¤82£®Ð6W±Ñ@§Ã ÞxSÁñXßK‰//oLÛ–Ùn.¥ pDk*Æ1ÇÉÇÁü*øy¯øoþßö–ŸöøGüq£j_¾¾ÏxßÙXåc»?fŸæ\¯É׿\û=ã ¾ëþÿ…5ý¥§ýŸþïO¢ê_¾þÏxßÙ[cùXîÿYþeÊü~eÉð§áî¿á¯øSÚ:Ù¿áðÆ‹©þú6ò/û+ü¬wgì³üË•ù:ò¹öz(®‹Á¿óÿ°\ÿû-sµÑx7þcŸö Ÿÿe vŠ( Š( Š( Š( ¹ßˆÿòOZýñÿ_|"ÿ’±à¯û Ùèô®JŸ4»›{|U¿‰ø#ô«þÆ…ÿ>ZýñÿGü/ þ|µûâ?þ.¿5h£š]Åíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº?á|h_óå¨ÿßÿñuù«EÒîßÿ??~•ÂøÐ¿çËQÿ¾#ÿâèÿ…ñ¡Ï–£ÿ|GÿÅ׿­sK¸{|WüüüúUÿ ãBÿŸ-Gþøÿ‹£þÆ…ÿ>Zýñÿ_š´QÍ.áíñ_óóðGé…>>x[Â×±ZxlÜ=íÜ—·Þ[¬¯$¯€O2`ªªasÉ$¿øj­ þ…koüÿŽWåsK¸{|Wüüüú™ÿ U¡Эmÿ€ÿñÊ?᪴/ú­¿ð?þ9_–tQÍ.áíñ_óóðGêgü5V…ÿBµ·þGÿÇ(ÿ†ªÐ¿èV¶ÿÀÿøå~YÑG4»‡·ÅÏÏÁ©ŸðÕZý Ößøÿ£þ«Bÿ¡ZÛÿ#ÿã•ùgEÒîßÿ??~¦ÃUh_ô+[àürøj­ þ…koüÿŽWåsK¸{|Wüüüú™ÿ U¡Эmÿ€ÿñÊö¬Ò>Ïs^K_>&…ÞÞѶ°ÁäI_–tQÍ.áíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº?á|h_óå¨ÿßÿñuù«EÒîßÿ??~•ÂøÐ¿çËQÿ¾#ÿâèÿ…ñ¡Ï–£ÿ|GÿÅ׿­sK¸{|WüüüúUÿ ãBÿŸ-Gþøÿ‹£þÆ…ÿ>Zýñÿ_š´QÍ.áíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº øñ¡Om,ëe¨„Žéí)w¬QHOßé‰ÓñŽ™üÕ®·Sÿ’OáÏû êŸú"ÂŽiw¯ŠÖõ?}ûÿ ãBÿŸ-Gþøÿ‹ª øÑ£jÚ£e¥òKso$(Ή´R~~œ×ç%^]È•\Lââêhü‘ÖüWÿ‘ÿTÿ¶_ú)(®JŠFp,T{ÿÙtango-9.2.5a/doc/src/atk/img/prog_guide_exple2.jpg0000644023471100065110000017567113034745263016752 00000000000000ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀzŠ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?݃Å^+¿»½ŽÛZò`³Ž’kýNæ<´¦mª¢8¤'ˆ’qÔTßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“¦uñýÂÿöþ­êú—ƒ4MZ÷NºñVË«9ÞÞUòatb¬9œ õÈ~yyYY_æÿ̵ÿˆ5[CƒRñ.œögWÓÝã…ôÅÊÝÄÊ¡Ô)%€$H$€3Ký»âïúôïüêü‰XvZ¾“«ëº9Ñï$¿µƒ^Ó"iÞ4@Ïö«v;v»‚`3‘ÎF8Éš‹è¨ãuÕõ~^f·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“E+™{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3Z={ÅÒÛCp¾'ÓŒ3y›û_PçdqöNÏÃ=4nø»þ†};ÿú‡ÿ"VMü‹z?ý¿éÊî¥Õ®4?TƒH†þK­]­RîhHdÀ,$-ŸÞ®2£8cžY¬¤ÓvŽÞoüÍ ÿM«ÝÝOâ]9ïàÒ'K`5 æ*îË{o6  Âò‚IaÆ!·|]ÿC>ÿƒ}Cÿ‘+'NÿÝïý.?ô²ÆºM_W—L¸····±X…³|ö;Ð#1,ÈI$’y=è¸ÝOv-¯Ï»ó2ï뺖­âE}¨]^Å ƒD—´Š…žì1POí\ã®Ñé]c|nð‘ø¨x*N÷Äzt¶Ðß[Øè—×1Z5„Í+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯xø‘qu'ޤ·MCP¶‚=6ÞEŠÒöhsKpˆF’FO ¯0‡âdžåðn§â£ãV L’Xo¦¹Ôïa’ÖXÛkÅ$NÂD“qFWq,¸rçÑ¥–άE$“¾þFO'‚vçwü–ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯Dð÷ˆG‰ìžêÏQñD1$†"ºŒÚ•”™„œ£Èù€Ær3q©¶çþ‚ú×þ î¿øån²jÍ]I~?ä/ìˆ;û¿àžOÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã^±¶çþ‚ú×þ î¿øåzw‡y¼#|òÍqq,ZÄÖâ[›™gr‚ÚÕÀÌŒØÁ•ø×>#-©†‡<䆲h?¶þïø'Ë?ð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥çû?2¿±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'ÆøI³ðÞ…çê–Py©{,~eÂ.ô:•Þdò­Eÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ™rÉ£'~Ãþ ñ†•â=&mOSž=RÊH!Ñ&óe[„+ol@Üs“Ó5S^ñ¼®¢'µñ.ƒkÁ +¸•‡—!%„ÊJ“ÓŒãœdýµEÏÌØêÉsíåýw>ÕµkìŸO?ˆ´«Û«­8ÛÇ«,ue dbI2~‚½Æž)Ñmüc®Å.¯a©:º=ÊR$`Aà××uó_Š#ÿ¡nÏÿ -?ÿŽÖÐøQôywû¬?®§ævƒðcâ’|,–ÏMð‰¬5_øU·6ŸbšÚFc⇞k\°\Èö›ÛÉûÒ#`+ný™û)ø. ø—â^¡7¶§u`mlÂ’økKŽhí¶Í%”Ó¼£p1 ãŒ3§Ê\·Ù¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚ³Ñ8OˆŸòPî?ìkÿ£®kã|4ñÿu¯ZiwRx Æ °ñä©o#Y,*²>¡×;wE4²Á "«`e@d AûbóÁþ#ñ¿‹µkŇGÒ>ŧÙG*^ê¢PÁåºØQ­’POÊùS‚¡áßð©üCÿA/ àeçÿ"WÑЫÂIY¯ÉßOšf.÷º??®<âã no´¦ðÀøâ+˨µãUµ‘e·ˆZ\=Œe^t$LUùT¶sÎ ßüM§Yü9²Kê6ž$Ðך•ËYµµæ“cý©Æù¶<ëky° ˆwthÇèGü*ÿÐKÃ_øyÿÈ”§ñý¼5ÿ—Ÿü‰Ul.¿¼ßþù½ØùSöUðlj­.|iâ/XßézÝôš~“5®¢䔨Ú$-t&?ëDÌÌw Œ©Ã¾s_cü$ÿ‘CTÿ°üÿúEcXð©üCÿA/ àeçÿ"WIá/ x‡ÂÚ=Õ᫯>þKï3ûFñ6ãìG8ò3Ÿö±Ž2qÅΔ¨F•)]§ÏüÇÞìéèªGˆ»á¯ü^ò Gˆ»á¯ü^ò xžÍù}èÒåú*‡‘âîøkÿ—ŸüƒG‘âîøkÿ—ŸüƒG³~_z —èªGˆ»á¯ü^ò Gˆ»á¯ü^ò Íù}è._¢¨y!þðiyÿÈ5‘ˆ5»0ÚèúmüQË$&{}vÞ$.ŽQÀ[*NX|È3ŒŒ© SƒJàtÔW9ý³â?úìÿð¢ÓÿøíÛ>#ÿ¡nÏÿ -?ÿŽÔ èè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠÄ·¾ñÒÆ!Ð-%™ŒÛ¡[µ)còw3¸b‹Ÿ´FîÝÎp ›>+ÿ¡j×ÿÖü]jÑYYñ_ý V¿ø>³ÿâèÏŠÿèZµÿÁõŸÿ@´VV|WÿBÕ¯þ¬ÿøº¯¨j~ Ò,仾Ñ4û+Xñ¾{YF‹’Ë$Æ€7h®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíëåÈ×­×ìßú1«è-Å7ž%Õ ±°‹A¸šGD>O‰ìfØÕÙˆÜÊ8’@’|ûâïùõ¯úý›ÿF5cS¡óYßÃOçú?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}\>z™wû¬?®¥+½oN°Ôl,.¯ím¯¯Ë­¥¬Ó*ËrQw8IËíPXã8šƒVñN‹ ÞØYêz½†w¨IåYÁwr‘Irü|±«\ò8ê+Ä<}ðÎh?kO…^/ÓìuKäœêßÚ—§ÌšÚÉOH ?rfónwsÉÛRÓÚ+>ö-n ]îàÃpì@*98«=ï?Ç÷Š¿ëž•üõ Âý þ.‰øC¯øçû'ûsû+ìÿèiû?›æÜGúÍ·fïºsŒqœÖãûÅ_õÏJþz…r?µ­[ãoÀŸx+C¸²´Õu?²ù3jéùwQJÛŠ+0ùc`0§’:u­*oò_’,jß®>éÐ^üM±Ó<7¡—¥/‡îïu¹o.¥––Qº±ü¸ ¸’88 £ |nð—Šâ-[U²Õ´­ÀW%Úé°Ï-Ó]¾§%ûùP¬e¤VBŠGï¨Äcv»Ûübð…Ý÷¬âÕ÷ÜøÞÖKß§Ù¦m†8wlìÄxÕ±&ÓÎÏÙ×ÈŸ±WÀm[Áž'Ö|Q©ÙÞéš•kwá_èÄö÷·zYÔî.Úêò Y$gt Äghbc£7×tW—è¿êõû ßÿé\µêóâkž8¶¿‰á¿ßiÖú½ìis¨kóÚÌäÎìsYJˆ9Î3Æp4_õ_¨ºž‡Eyí爾&YZOpþð™HQ¤`¾*¹Édãþ%µ7öÏÄïú<%ÿ…U×ÿ+k1åå—>?ø‹kâÍ7ÃÏàÏ Ûû«ø¤_Üùb8$·G ³³¸›¨ñ€FdŒ ëÿlüNÿ¡CÂ_øU]ò¶€;Ê+ÏlüEñ2öÒ „ð„ÂL‹"†ñUÎ@##?ñ-¢|L‚[toøL™ÜƸñUÏk7?ñ-ôS@…EpÛ?¿èPð—þW_ü­¨`ñÄÉå¸Eð„ÁÄmŸ\òv«qÿßFèTWžÞx‹âe•¤÷àÿ ”…F ⫝̸N?â[SlüNÿ¡CÂ_øU]ò¶€;Ê+Ë.|ñ×Åšo‡ŸÁž7·ö7WñH¾)¹òÄpInŽÿggq7QãŒÉ×þÙøÿB‡„¿ðªºÿåmw”WžÙø‹âeí¤ àÿ „™E ⫝̸€FFâ[Dþ"ø™¶èÞð™3¹q⫞Önâ[覀= Šàÿ¶~'Сá/ü*®¿ù[PÚø‹âeÜLéàÿ €ãù¼UsÕX©ÿ˜o¨4èTWžÝx‹âe¤Jïàÿ ]#ù|UsÕ˜(ÿ˜o©7öÏÄïú<%ÿ…U×ÿ+h¼¢¼²ÛÇÿn¼Y©xy<á{ack,⛟,Ç<—Oövwk&rÁ\“Ï|L²´žáüá2£HÁ|Us’ÉÇüKhШ®ûgâwý ÿªëÿ•µ x‹âb]Çn|á=ò#Hü%W8•þa¿íÖ€= Šàÿ¶~'Сá/ü*®¿ù[PÚø‹âeÜLéàÿ €ãù¼UsÕX©ÿ˜o¨4èTWžÝx‹âe¤Jïàÿ ]#ù|UsÕ˜(ÿ˜o©7öÏÄïú<%ÿ…U×ÿ+h¼¢¼²ÛÇÿn¼Y©xy<á{ack,⛟,Ç<—Oövwk&rÁ\“2×|S©x¦Ç\Ñ4í]ú+týRKÕšF¶ŠáÏoÕ qI;øA`ÖŠ( Š( áïú_ýûïå£Um/\Öõ=/O½û>l/- ¼X%Ô¯ãI¢YP6Ë\íuÎ úÕŸ‡¿ê5÷ï¿–W|â[áΔ¶³4.Ún¤®3ƒ¦Âi¥}È“ihcMâ{ø«ÉáÅ#þŸµþWÔð—Ýùoá¿üÔ?ù_Xןád’Yÿá Ѻ¶—)eÚ'Èáqÿ.Òt=×׈®þ4Cj'Ý.¸Lfìiró³íÇÉÿNÒcêž¼_)òìl·Ž'PI¹ðà®ou?òTüI¬ü>’ý.4Û˜ÓZ²µß¦\K<{–{IZHb âemà‚ È s?ñµõÏ5«ûI¯àŽ´[µÀb2ʱ€;IgÚ¹?€· wû. ›;ŸÆdœúý£O¦•¬Ë‹osÕ¨¢Šõ‰ +ŠÔ>7|:Òoîlo¼}á{;ÛiZí®5›häŠE$22—ʰ ‚ Нÿ ûá‡ýÿàö×ÿŽTó.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑUôýB×V°¶¾±¹†òÊæ%š ›y‘ËUÕ‡ ¤AjÅPü'!>?Ó"Âíòà—;Fì[LnëŒ9Êç…$ªGƒø»þF½kþ¿fÿÑ^íá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒjñ1ó¹ÏÁOælü ÿ‘óÇ_ö+ÚÿéÁ+ÓëÌ>Èùã¯ûíôà•éõøQëeßî°þº…QVz';¬ø×WðGˆ´{M1l$OÞÅ¥È×°Hílmíoî–TÛ"¬…O÷Ï=ö÷Š¿çÿGÿÁd¿ü‘^ñ:¹ñgÂØÜ¸Vñ$Ù1¹Cÿ G¸ Šï£Aj€’ 1cø“ÉükOi/é!Xwö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘E{Gå÷ °ox«þôüKÿÉox«þôüKÿÉQG´~_r ö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘E{Gå÷ °ox«þôüKÿÉox«þôüKÿÉQG´~_r ö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘Y7:´Ðø¯NÓPÁseurìAÜ9-Õ@9Æ1+gŽÃ§}j•[™´­§’õ7©FT£ Ëi+¯K¸þi™³øÛÅPxŠÇJûNŽßiµ¸¹ó³åù|§…vãíçÎÎsÆÞùã/Y’÷ún·H÷sêðeŽ-ªEÅúyŠ‹`m•—©=óšÌñF­6ñ[ÀÖñª2_ÛêVÒ—!BC.Wž»¢QÎx'ê4¾#\Ãeᨮ.%H ‹RÓ¤’YX*¢‹Ø bOÎkŠx‰Je‡É/²Ÿê}&/Œ19kp¿¶³¶÷ýôáªÿ·moó:z+˜ø­/‡þx†ù®^ÍÒÊDŠx·Y]vG‚¼ƒ½—žÝxÆk¢¹¹†ÊÚ[‹‰R"C$’ÊÁU –$ðæ·ö‹Ã²Oï¿ùÂTXzx”´œ¥§X¨7ëñ­?Ì š^—ªêºwˆcT¹»†Î[{KÈ¥%|‰Úp0v°c'8?w‚9Ô®sá¿ü“¿ Ø*×ÿD­ttS—<#7Õ Aaq5h'u5÷;QZaEPEP ´+vÏY’ Ú•¥´öpO½†È¦hžEÛœ´‘‘·‚2s~Š(¢Š(¢Š(¢Š(„:¾»y¬ÇÝJîÚ 9çÞÇ|P´¯íÎyN@ÉÝÉ8¿EQEQEQEB Æß]¼Öcƒn¥wmœóïc¾(ZWvç <§ dîäœ r_?äqø§ÿc$?úgÓk¼¯=øaj–Þ/ø¦¤#þ8ï%gÿ˜FœˆŸSúz ô*(¢€ (¢€:?‡¿ê5÷ï¿–Xþ‘‡„´…ÿÈ;FÇ?õ †¶>ÿ¨Õÿß¾þZ5sš%ÒÁá}+yãû;FûCTŒç±Ká-·Ù|3vžGÙó©Þ6ß#ÊÏïßœyþ{OûÇ·k^o§ü8¸Ó,e‚ÇÆWZrÌe‘’ÊÚÚIö‚\(N¹¯îWŸK×>Ô§óöx÷T‹Ìó6íÿ&ï´c'ðùÑãþ¸'ᡃ³g¯[ýাŸg6ù¼Ô`‡Ê'÷¯Î<ˆ=§ýãÚ·ìêÛÿdø[ÏŒ|ÿËÅ…l|EЭü)ð×\Ó­îâ¸IžêíJA%„¶Ò#1Ÿ˜Œž=+#öwŒEû(Ä Œ_úø°£·©¼O]¢Š+Õø­ñûþK¿Äû5/ý*’¸:ï>?Éwøÿc&¥ÿ¥RW^4·f¡ET€QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®¡EUž‰çÿ¤h|YðµÒ'‡‰&Äq ÿ‰F£ê@ýk¾‹Æ¬PÆH£c+ìq‘ùW ñþG…Ÿö2Mÿ¦}J»Ê(¢Š(¢Š(¢Š(ªÑê6òê3Ø,™º‚(ç’=§åG.¨sÓ“þ^â©\êÓCâ½;LUCÍ•Õ˱phä·UçÄ­ž;áÎ)_åøÛó:a†«R~ÎÖvr×My¯óZ®æuíÌ/ñ7G·YPÏ‘{#ÄnUi­±@%Xßiô­jÓhºl7*;½í¥±FÙnc‰rÉøëÒ¼û@Ö?·>=Ksäù4 ›m»·gÊÔž-ÙÀë³8íœsÖ´h_ù#úÿý»ÿéDuåýcýž½xô»_(£îVP¿µò¼®·Ûöq•õ·=Gu£Ö×k}{‡ÿä°|4ÿ¸Ÿþ“­e|_Õ¦Ö¾ø–âuDt½{`# ±jRžIäª}óÓ¥jøßþKÃOû‰ÿé:×ñ?Xò>ëzW“»í7Z•Ï›»îùZÄk·ç>vsž6÷ÏX™òÛÒÒÿÒ —æ}NI†öøŒ‚Pä¥KîúÎ*Rü#‘Ú|~ÿIøi¨éëÄןêØýÑä«\¾~©nà´W É~(êÓC¢ëbª.|;ª\»wbUçÄ­ž;é|dÿLÒÞÏîyV©©ïë»Ëµ0lÇlý¯véž1ódp5‹/ëPÃ&Èï"Ö`vƒ½g ôù£Cǧ¡5xÊÞÊUeß’?Ÿù³Ÿ†ò߯ÒÀRMZX­¯V”ËHE¯5çuëÿ ÿäø[þÁV¿ú%k£®sá¿ü“¿ Ø*×ÿD­]ðέ6µ¦Íq:¢:^ÝÛ mŠæH”òO%Pïž+ס$©Â=Zÿ/ó?8ÍhÊX¼Ue²¨×͹5ÿ¤³ZŠ(®£Ã (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ó߆¼Þ/ø¦^ÞHü$pHTÿÌ#Nãå'ÐÄ{ãЫƒøqÿ#Å?û!ÿÓ>›@åQ@Q@Ãßõ¿û÷ßËF¯ø•Ä»]+A±ð¿µýRÑô¦–{}6à•,"“‚Ý$~ íŸÔjÿïß-«izæ·©éz}ïÙô ayiâÁ.¥xÏMʶX²çk®pOÖš¿A;u>MžÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄ×Ö³xžþ*òxqHÿ§íCÿ•õü%÷cþ[øoÿµþWÕó>ÂÐù*óÃ5k9-¯~xžHäVGN—#ݯgøSàÝ{Àß³Dwˆ´kíPo¤ÂÛP·xd(Óéø` Œ‚3Óƒé^’Þ8A&çÀ¹½ÔxÿÊuSñ&²ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]BŠ(«=Ïþ'FÓx³áj$¯M‰#‘ÿGÔúW}”T¹€vÆ[Üãò®âtëmâÏ…²8r«âI²#BçþA` 5ßFâXÕÀ 0R§ñ‘øÐ¨¢Š(¢Š+ÅÓh·º5ÊZÙÍ{"]¼»BùKiq!˺F§<}ßLÕ-/Å—w^<Õ4I£€ÚÅ¿ÈtR®¾\VŽÛÉ$6ãwÆíòÿ‹wÇÇmZltÝ1•Ì÷6ú¥Ê0hXôë…`NsœÊ¸ã±éßÏÄbhʤ_ÂÒùÝ~gØe95JÙ•%hÝU§)+kîºrwõ›òjë£; ù(šßý‚¬?ôuåßòQ4Oû_ÿèë:,ä¢kö °ÿÑוK^Õ¡Ó¾'øJÞEv{û-FÚ"€`06òå¹é¶&g’> mF•ßóíäœêãù`®ýƒ%†»û’¹Ãø þKe×ý‚µ/ý<Ï]í ÿ$_ÿ·ý(ޏ?ÿk?-EÏŸqåøo›ér~Ñ$ÓExüž¬¿kU<’pãvyñÛ÷þ k7ù­®~Ñæ§÷¼«;‰ãç¨ÄÆÜuÛƒH>EsåÕ|î¾m%ùŸ¢fT~¯Æx{¨:sºëÉÏO7¢v³ÑÛ[7ÿ’ÁðÓþâúNµãž%ñ4Þ0ð´Ö0éïôºmÍÿÙ‘Œ’»Ö xâÚìÀÿ‘H#>Çñ÷6ðâ|·6Ûü§þï›yaœt9Žiž›²0@#ÅþÿÉ|ð·ý‚­ôҵɘ9{wFúT’OÒQ‚¿ÉÄú…'•Ã3q¼°teR:½eJ®"n:iiFªWwi§§døs íµÅż©<øOX’9b`ÊêE© à‚9Íy¯‰'¸ñ_Äk¨­¶Û[øªæÖò3 ! ÙÖo¸nWÜ\$ äd×¥|1¶†öÚÞÞâ$ž |'£Ç$R¨eu"è ðAb¼·àu•߉­­3?›tÚ…Õä³\9%ü»&g$òKש<žõ¦)Ê»‡ý<ÖÞqi~79²O*§ˆ_ô ¹9ŸX׌äݖܪ>z¤ú´{Ï€>_ Öu;…w‚Ê÷V¹‘b±T»¸b$ àzŠÉð‡üoýÌ?úsн¨TåöVß•~.(ü¿„uÞ9ËHûY4üá Ò·åSÑ«Î~þïÂü°ÅöO.1¦ý>ÖGÀí—wsêÎÇ©5wÁ~>mÃÞÔZ7™5½Jîš]¨ÐĦåãÈPA!!Tëß9=ó¾ ÜÃeàûË‹‰R"K)$–V ¨£K³%‰<9¤ëB­Z5 ô³üRä\rìN_€Ìp˜ˆûÊPVßXÔ”¾jKdþóÒ¨¢ŠõO‚ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ó߆<>/ø¦âIÏü$p ÈÌ#NçåÔÀ{çЫÏ~]%Ï‹þ)”Yÿ„ŽûÈ™?æ§âÐþž¢€= Š( Š( áïú_ýûïå£Ußø–çDøs¥-¬Í ¶›¤)+Œàé°š¥ð÷ýF¯þý÷òÑ«ÃÒ0ð– ŸùhØçþ¡pÕ#9«£:óãœ,’K?ü$º#—VÒå,»Dù.?åÚN‡ºúñ߯ˆmDû¥× ƒÌÝ.^v}£8ù?éÚL}S׎oA“ÄÚ/ÃÛ–ðž‹e{ªnpÖ×ÄÚ'’nXHãC’û>§.@CÈ~ÌZωÞÞ×O½ð£_ê/u©kÉu?ñµõÏ5«ûI¯àŽ´[µÀb2ʱ€;IgÚ¹?€· wû. ›;ŸÆdœúý£O¥×­þÇðS_O³›|Þj °Cåû×çD?žÓþñí[öumÿ²|-ŒgÆG¾åâ—cX-Ï^¢Š+Õñ[ã÷ü—ˆÿö2j_úU%puÞ|~ÿ’ïñþÆMKÿJ¤®¼inÍBŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ö£àü‡ö-é¿úKwµÁ|ÿ’ðãþŽ7ÿIc®ö½˜ìŒ‹>ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]O5Ö¿h è? ðEȽ:ƒÜZÙKyJmmînRG·Ø°mò,NFŽ™#5{Æß-|ã°hZ¿ˆõíZÞ{¸m4Ÿ³.(¶îiy¢UwœàûgÍ|]û4êž!øê|]¥dšÞµ£ë÷Hìâé'Ó ž(âE µ‘üÕ%‹»O5GâGÀ_|ZÓô{u|câƒo½æ»¦ Áq¦˜¯¼ô’ľAÌ_+)Û˜å@Z³Ñ=câ?üŽ? ?ìd›ÿLú•w•æŸ4Û_\øeikªÝè—x’]·Ö+ M4D¢häN@ îCÁ8ÁÁ§†tKÍÂK{íQñ­)]jqÛ$ˆ¸`ðÄ»F åIËq€5袊(¢ŠñÿÉD»ÿ°¬?ú;B¬ßzÇöŸŠ­-¼Ÿ/û>×[¶Ý»>ft¸¥ÝŒqþ·çîç¾—ˆÿä¢]ÿØVý¡W9ñ_þG‹ïûé’Ö¾?&¡U.³þ”Ïèþ¥ ˜œ ¤µŽ³^OÙE~Mž£qÇyìLZÏá¸ç’=£ætºuCž¼ óöÎC¨ÜxƒÅ¿ïç“íI§É=ì›BáîlÙà`|ÆÞ»Óo8Êçkþn#þå_ý»®BÇÃ7Þ+´ðÕ•š§’t-!odvÛåÛIm¨C+/û{eÂðF⤌]µ%7.E¯¾ôôq—éø³æ0tpЧõŠAý^ ™¥ÿ/)Õ¤ï³zIY_V£½¬]øoÿ~ÿ°­¯þ£Ë]Çùàÿ·ïý6^Ö¶µ¤Ã§xŸA¸žÿ]k™C‘€ÃLš,/6ħœòOÐdüqÿ‘^û~ÿÓeíjéº8Z}ùñ°Ìsì* ÊTÞšö‰¯“[õ¦x¡7ñýý“åmþ/´êqù›½qöHñŒulç#uðëÂñ\x?ÄÉ'üñÓ¥›þ ‘IQúé’O÷p:×{â]FÞ÷Åúô0ɾK9|;ë´Žuzü²!ã×Ô‹ÂL:v…ðââ6v{û‹{™C‘€ÃG’,/6ħœòOÐsÕ§؈K{;ýÓ·üØÀcjå™5z1¼}¥7­ÒxxÔ'w$û´Ë¿ ?åÇþÅ]ÿn«‹ý–ô°ØÞܼÞÚmb¹‰Yãßt÷Hªr~÷Ùc$Œgjƒ ×ið«å–Aá½& PõŽDk´taÙ••”ƒÈ ƒÈ¬ïZ?öµ·çïÐ4ûÛvãÍžö]¸Éé¿ïŒñÒªŒ9ªa¤Ö‰Oô0Ìq^ÇžQŒ­)Ë óIJúôծͧm®y÷‹¼M}eŠÚÙ’kk-bÃl‹ÂO6­œvb|™à ò¹#© +°Åöú,iªÙOÔ‰kâI­ŠæXÍãMâ½ÖÚbFá`äU/ÚÂðø{ÀÌúU»Í=ýíÊÜá3,Ïö¹d;@$©µ@ç©8pÞÿ’wiÿ`©¿ôN»^TçWŠ•þÊùY§þGÞáð¸ ç!¥˜Æ6J´Õ´\ÊP”uõ|ÏÎï[êzß…ô˜|1†<9 <ƒFñÕ·˜äÊöwWœ€2|¹ÐÌ`œ­ýáŠ-™'ðݾ¢¥zßMX?ínµ‘ÓyÉ hëÇög?wÚ&_C#Ç»nØ_O¶µi3Žv½Ü?/SŸ@HÁ¹Õ¡Ñ~k«º?‚4›`#Ò‹˜”òGœíž½+Ñ”¡M¸l£Ï÷(Ù~GÇÑ¥ˆÅÆ–¹¥]áÝûÎuœåøÏñò=ÖŠ­£o.£=‚É›¨"Žy#Ú~Trê‡=91¿åî*—†uiµ­6k‰ÕÒöîØÁlW2D§’y*€Ÿ|ôé_KÏ%çøˆ¼5XÓud¬“Š×ûɵòi_îîkQEg0QEQEQEQEQEQEQEQEWðãþGŠö2Cÿ¦}6ºÝwM¸Õô©í-u[½âM»o¬Vš,0'hš9;ðN0pGüÑ/4oüRKÍQטx‚Þ?3PŽÙ°Ò¬X¿îaŒn!ÕÄI€»8©ÑEQEÑü=ÿQ«ÿ¿}ü´jç4K¥ƒÂúVóÇövŒö †º?‡¿ê5÷ï¿–^'ñ*‰vºVƒcákú¤-£éM,öúmÀ *XE!&0 ºHüA¢D•ÑÔéÿ.4Ë`±ñ•Öœ³dd²¶¶…’} — ®gCëû•çÒtøskÌV^5¿°ŠgžP–ñ["«Ê×,[;®ç¹…O~<{ÚÈ)ðçÄëë>_þ&¡þÍý¡øÿ‹wâ~ä/ÿZüÈäg®üEЭü)ð×\Ó­îâ¸IžêíJA%„¶Ò#1Ÿ˜Œž=+#öwŒEû(Ä Œ_úø°¯5¼ðßÇZÎKk߆Þ'’9‘ÁÓ¥ÆÇ÷kÙþø7^ð7ìÑâ-ûCÔÅi0¶Ô-Þ 4ú~# ŒôàúRì\U@¢Š+Õ$üVøýÿ%ßâ?ýŒš—þ•I\wŸ¿ä»üGÿ±“RÿÒ©+ƒ¯[³P¢Š*@(¢Š(¢Š(¢Š(¢Š–<~”R«9”ô°QHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Ú€?òB>Ø·¦ÿé,uÞ×ðþHGÃûôßý%Ž»Úöc²2,øKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£½ÛÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕãbþ3çsŸ‚ŸÌÙøÿ#玿ìWµÿÓ‚W§×˜| ÿ‘óÇ_ö+ÚÿéÁ+Óê!ð£ÖË¿Ýaýu (¢¬ôO?øq¯‹>Ë4‰ KâI²ò0P?âQ¨Ž¦»èäYcWFŒ+)È ô × ñþG…Ÿö2Mÿ¦}J»Ê(¢«G¨Û˨Ï`²f꣞HöŸ•º¡ÏNLoù{ŠM¥¹q„¤›ŠºZ¿%{kóiz²ÍbÚj7øÏT°i3kŸiÕ¡Ð|W­êw ï•ê\ȱXªI¡±p=EbüH‰¤ñŸu æqg£ P€.Ô7š[ÀXñ¸–’;d8$ŒdïŠúu¾©¦xš˜üØ×Zšp»ˆÃÇ¡ñèʧßñRkZ*ê¾+ø“í³É¦Þê^µrw*È<ÈDˆc®¹ÁÈÜ=E|¶"©:‰mÍšG¯•Ò?|ÉñT0˜\%I'ÍìT[Óà\$-þ×,ª}ýUÎŒ4ÚÄ]O_‘{h/WF—>r-Äz’cRä©eÇšì2IO…òãÿb®‹ÿ·U‹áÝFãWðeÅýÜžmÕÖµ¡O4›BîvLf8$ž•µð£þ\ìUÑöê½2RÄA­Ÿ3ûî¿D|VeFTr|M:–榩SÓf¢¡/Îrí¥´:?ÿÈsÁÿö“ÿHn¨ñOü‡<ÿaY?ô†êÿÈsÁÿö“ÿHn¨ñOü‡<ÿaY?ô†ê½}¿ñGÿm>.üÃÿך¿û˜ñ‡¿óÿ¹CÿhW¢èò+ü&ÿ¶úl¸¯øÿ ?ÿØWBÿÒá^ãám:â÷ ¦†=ñÙÅo<í¸ ˆtùcž¿4ˆ8õô¼ µº”éÉ-Õÿò¥Ï×xÚ”pX¼UKHÉFû]ýJ1_{Ùwv+|3ÿ‘£Ä¿ð?ý9êt|(ÿ—ût_ýº£áŸü%ÿÿéÏS®IÓ~Áã=Oɵû=‚éVAåǶ!²K¬¢àcå œ€Q^® ÂŒûs~7ÿ#೬DaˆÌðïy*MÛ¼šä߃,ëúuÅî«á¹¡|vzƒÏ;nb[ˆÁç¯Í"=}¯šô¿øöº°>×K²´„p¾uÎxGeß4Ä“ÀÝ#1<“_WWËÞÒfÔu(®#dT°½ð•Ì¡ÉÉSl"Âñ×tªyÇýkO÷”œz¶ÿò_øÒp*øLtjÙ(BœW«­§Îóiy;w7þ,ê7F£â«ûI<««YLðÉ´6×S¢2œƒ‚Zêü_áí?ÎÔ´/³ÿī쾲û>öÿSý¡*mÝßwŒç>õÅükÿ™ÓþÚî½Åÿò4j_÷/éÎZÁ%*õÓþ®ª_ï=G9Rʲ©Óvz;­ã<'/Ýwn×vÝ™ßÑ2éZ.b¯ß¶y[…«ÈçñÇ@k|¹šxüh’Jò$>'¿Ž%v$F»•¶¨ì73ìOzæ?fïÞiFvù¦—Jµó$<³ìº¾2{áz*(èXøi¯ÿeëZÆž™©øÓS‰£só˜ÒÜÈY{2Æ ä Þ¤WF«öxz“7þLôüÑäq/œa0ðKÙ**ÉY~ê I¤¶ºŒŸÌö (¢¾üP(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ï~^AwâÿŠf ã˜ÂGf7 ÇöFœ3Ǹ#ð5èUÁü8ÿ‘ÇâŸýŒÿéŸM òŠ( Š( áïú_ýûïå£Um/\Öõ=/O½û>l/- ¼X%Ô¯ãI¢YP6Ë\íuÎ úÕŸ‡¿ê5÷ï¿–Rø_ÆSxOáUÌ2´^V‘¥;ítC´iq1ùœ…:±ÔM+‘&Òº3¦ñ=ü Uäðâ‘ÿOÚ‡ÿ+ê?øKîÇü·ðßþjü¯«—ž+ÖåiXÛjr• ‚¯oócÌÆ3 ë±qœ®Lã±Ö:åö£nÒŨJË,'æ²È쇕$uSÇQЀA¹QŸ´fcxâu›Ÿ:æ÷Qãÿ)ÕOÄšÈñÃé/ÒãM¹5«+]úeijǹg´å¤†"&PFÞ œ‚_ÅÍcSÑü©ÜÇ)"Þ@ü½ø®à-Ã]þË‚fÎçñ™'>¿hÓê’J̸ÉÈõj(¢½aŠß¿ä»üGÿ±“RÿÒ©+ƒ®óã÷ü—ˆÿö2j_úU%puãKvjQEHQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µä„|8ÿ±oMÿÒXë½® àü‡ö-é¿úKwµìÇddYð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5{·„¿ä¢éõïþôªðŸÈ×­×ìßú1«ÆÅügÎç??™³ð+þGÏدkÿ§¯O¯0øÿ#玿ìWµÿÓ‚W§ÔCáG­—ºÃúêQEYèžñ9¥_|-0¢I/ü$“adr ÿÄ£QîþUßFXÆ¥ÀWÀÜäß?•p¿ÿäqøYÿc$ßúgÔ«¼ ¼×þ7µ><Ö¥2[ÜÍo´)nC,zåªø%žrz¹<qéUòðñ5Œšµï‹agŸIµy—(¸’A¹otYU±ÁŽê03ƒÀ€O˜bP’{]ÿ^—?Gáž9Å,M EûÞÎ7[ݶһMjâ½l}C^ âÍ~ïÃš×ÆK9öj/™IÍ»yŒ›H;’1$™6<^¯ñRþÈðˆ®Åר¤OŸÊœIå•¡ µ²0ÅŠŽrF9¯:ýãäûùþÑÕcò¶ÿÙ´—ó7zgíqãèÙÆc1““§M;;¥~ÜÑœSûÎŽ ¢©SÅã*Gž>ÎO•ý¯aWZQo³Š×²¸xÛ÷žžvù¦—U×|É,û-µÓ'¾¢¢Ž€WE/ïü+uxÿ5ÍÏŠ¢ó_ûÞV©ñÐb8c^:íÉÉ$Ÿ>Э¦½øá;{xžyå}R8â‰K3±´Ô@P$“Æ+½¶¹†÷áôWò¤ðKâq$rÄÁ•ÔëY à‚9Íqáåí¤úÁ?Ÿ*ÿ?Äú\Ö‡Õ%J„]ù1R…ö÷UYÙy'Èš[{«±ÅÁ«M üÕõ;uGžÊãF¹e©d¶ÓX¢»…»ºÍÄÖz›e:ÿrhe¼ŠUÏ|:0Èàã ‘ƒ\:i3k_¼Uo":[Ø\“! m‹O±•‡òUøéÖ»„éwþ2»~$ƒZºÓ”/CO,àŸö·]H 逼dV›ë4ûrþ³¿è^쿱1¶øý®½íɇ·ãÍøŠä9àÿû Éÿ¤7UƒyâeÕ¼i¤³ ŸI×UB"°>TšTî¬ÄðI4qÙFGs½âŸùx?þ²é Õy×…¿äé?Šäo[þÝÿÒbã~ðEÕ‡ˆ|]ka Ícm{áûhd–DÜËj y éÈŒ«tÎOì•Îx[þCž0ÿ°¬úCkF&ŒjÊŸ7FÿÉ %Ìkåôq~ÊÖpƒiíxÖ¥%Ûª·£~§‹ükÿ™ÓþÚî½Åÿò4j_÷/éÎZç~"þëÇþ+‰>HßÀד²/¤/°¹Þ+jO\"Ž€WEâ_ô?ŒßÏöú­¿Ãök{ß3w¦~×1žœ`gÆQµj²ï$½/̯÷Èý2¥~l»E-iÒEýîEB£—»I뮚ÛMt¼£ÿÂ=â)ô¯;íaÐ4»o7nÝûíwc'Æq“^Y¤ÛLÿü9p±9‚7Õ#yBªÍw©•RzB±¾Óé^Éÿ_?¿ý§¥}<¿³Múîûg¶<¾û¸ãìt˜SÀZ·¹Íöªú$·Y#kH×ë;¸à´—2€º+QO’+ì6þ椗ÏO¼ñòÌÉÅâ+TÕâ¡Nš~u)Δ¥oî¾wm.ãe£Lí<­6·¦Þ¼·)s=¶¥{já6æ0—2*#Јü¾¼Aç9­úñø³þo ÚÊ#ónõkKµ.˸4“ÙY¼Ò9È%˜y­»’]9ɯh¯G ]V¦“Ýoý|‹â®Yv2rJÔæß/N‰».ÉÊËÐ(¢Šî>X(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ï~4íâÿŠ~|qÆá#ƒˆä/ÏöFꣶ?3éÏ¡WðãþGŠö2Cÿ¦}6€;Ê(¢€ (¢€:?‡¿ê5÷ï¿–\娞o‡–°Û‰gÑô•cb·öTX˜9ÿm?Þ^££ø{þ£Wÿ~ûùhÕÎè7kká­!œä ?FÀö „ÕDÎ{×W×¼kã½Â^º°Ð¤Ôt›Ýmu½VÌjVòCm=´>\qCu %ÅÚJ$2aU@*K1‹ÏµßŽ7? ®šÇÄ:߉îaÖâÓ¯ôý+â#ÜjV†kå…ÏÙ¦³V&7s£:mXß„ Us|aðƒÅžñ=®³ð—X±ÒšïK¼Ñõ1ªê÷O ´Ïdê,æH¥1?úÂäUoÝ”qÇÆÚü ø‘ck µ¶à{{xPG1x†åQ P,0 ùl¦qGÍ„§í)»ixÆÖßW®¿‡àiMQp´ŸÌô?Š¿üâÏj:n‰ãoëz”ÖòùVzn±o<Ï„,Ä"9f«:c=«?öumÿ²|-ŒgÆG¾åâ°µ¿…Káßê~ ’ÆïľD†¬ä3[ØŒ¬cvT-# ¹E!IE2o~Îñˆ¿e”ñ‘ëÿ_ôxZ•ªÒŒñä“é{ÛçeøiæÈJ*ê.èõÚ(¢½òOÅoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸:ñ¥»5 (¢¤Š( Š( Š( Š( Š( Š( QEÀ(¢Š(¢Š@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQE~Ô|ÿ’ðãþŽ7ÿIc®ö¸/€?òB>Ø·¦ÿé,uÞ׳‘‘gÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕîÞÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯñŸ;œüþfÏÀ¯ù¼ÃàWüž:ÿ±^×ÿN ^ŸQ…¶]þëë¨QEg¢yÿÄëx®¼Yð¶)£I¢oM”‘CÿDô5ßGÅ¢(DPUF ¸‰Ò4>,øZéÎÃÄ“b8ÈÿÄ£Qõ ~µßFÅãV(c$Q±•ö8Èü¨ñ±ý™ñKÁ–ÞO™ý¡k¨ÛnÝ/ wcÿªÆ8ûÙíƒáÚ†qwáKG1ïÓO𠓏 ¸Ñ,®a¿ë-CqýÌ{âÛÛø§Sñ4VÓ½®ä­ÂL¦-΃T·P§r´¯†]ØÝÎ6°>àï K¢À²%五S4Éòi?eÜÊOÈ£€[†õÇËÖƒÆÉ¨»®oÃEóMÅßæÝ²ÜTx^„*ÔŠST¬®íÍQ:•_Ë8F­>_>Y¤ïb/ÚþHþ¿ÿnÿúQs©ûω~¾i¥Õ|EæHygØÏd÷Â" ôTQÐ ±à›ßøI´¯è÷AiÖúG„……¤~U­®¡1î-µòeQ“’pëQü7Ñll¼ºlvÈlm5+Ô‚>p‚;é|¿½“•*¤Î@=k¦†¨RŠÿŸm?[A~‡‹™ç1–#U¦ÒÅÂqZ|*X™4üï?>ºèŽÂ?¿ø âkÄù­®t¦òŸûÞV› qÔbHd^zíÈÈ ž‹àÏüÏ_ö5_ì•gU𽿂þ jú%³oŽÏEºC&óÄìï‚N71fÆxΣø=m4øÑä‰ãI¼O$Lê@‘w*îSÜnVÔŽÕ4iÊ•z0–ê:úëÄ×1ÆÑÇeYŽ"ƒ÷%VоÅ:j7óåI¿;葽ã?ôoì-Gï}‹Uƒ÷}7ùû­zöÛöývcŒäq~Ñ÷|_ºñ#M™µ[]JÚHáSì—ÀŒ‰2?¼ô /Gñ†öïMð ÝÞŸÚ¯í·ƒa2E»„ªí^NH“šÉøypºÕö«YŸM™5×K‘ÄšŒmr8,¡ˆå>†µ¯Ë,R§ÚÒùó(ßîÐóòÅV–CÜOÿIÖº;ù(šßý‚¬?ôuåR×´˜u‰þ¸‘^ÂËQ¹ˆ!,M¼Xn:m•ä¡ójSæ§u¿:ü*\ûŒ&3Ùc}O…aê[Öx>_Ño¿ä¢hŸö ¿ÿÑÖuÇê´:À_jw s"Äb©5» gÔWa}ÿ%Dÿ°Uÿþ޳¬ï èÿðüÒô¯;ìÿnÐ"¶óvîÙ¾Ü.ìdgÎ2(©Nu# Ú•¾è‚­K ‡Á×Ä|'/ER»}O'èy¬:LÚ¡i¦^2H4›‹I§e$Å@š"¼ù `,foœ„gÎ5é_l­5ýCÃzL³ì‘õfò\  Í•ß—*õÚÁ•lpɑȮsÇÚ>íwÇ:‚MåÇ„$V·UâI&ó”œýí¶±©8ÉFp U›Yî5ow‰5¶Í:ÃO ž`>eÌJŒ_‘¶=E× îÏ$ ¼0ФåM­%$¾Wä}^"´±Ô©c#;T¥F¤ßOyž×ßãOKþÝÇ„µiµï hÚ¢O{e Ì‹!CMžÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄ×Ö³xžþ*òxqHÿ§íCÿ•õü%÷cþ[øoÿµþWÕó>ÂÐù*óÃ5k9-¯~xžHäVGN—#ݯgøSàÝ{Àß³Dwˆ´kíPo¤ÂÛP·xd(Óéø` Œ‚3Óƒé^’Þ8A&çÀ¹½ÔxÿÊuSñ&²w9ø)üÍŸ_ò>xëþÅ{_ý8%z}y‡À¯ù¢ =l»ýÖ×SÅüIûKØøwã x%´wšÚ=GNÑîõO´…0Þ_E,¶È±m;Ô¬?3n,84|hý¥ì~ø¦"mõ(àÓ£Ö5;r"6–oy¢º.Öó[Ì—;r¼)9íG‰?f‹|`_6±$6Òj:v±w¦}œ1šòÆ)b¶u—pØfù—iÉQÈæ°|]û(ÞüCeÇŠ¼s&±«6œ4}nøi1Àu+5¿KØÑ,­¦à+“ŒœÕž‰è¿.a²ñGˉR"ñ Ä’K+TQ£êD±'€ç5ZÆÏV}¾.ΫӞsÿ·§ËÍåöWõkyGÁÿ‡ŸØº¤Úì×_i¹ŠÖMÌQ³Íû=Ô‘odÁ û¸-”`ÿ g$î7~[CiÃÄ‚$…†'¬jf±flå‰$÷$šô :ßK¡¶Ê¥–r»‰ËÈí#ž}Y˜ûgŽ*ÍqÒÁF”!éoÅÝ7ùEâZøüF"µ[ÉTzl­ вÓESe¢µ–LÛMi£\$ñ<.u-B@²)RU¯&elÅH ÷ߢŠï„y  º+Š®ñUêWjÎM¿½ÜÉñn“6½áMgL·dIïl¦¶¥$(g”@'>†©x þ@w_öÔ¿ôºzè굆o¥ÀÐÛGåFÒË9]Äåäv‘Ï>¬Ì}³Ç›§ûÕSÊßü9Ö±¿ðŸ,þu5ÿ€´ÿöÛ|ÊÚþý¹c·älº¶¹Ý·v|©Ò]¸Èë³íœóÒ«ø;Âöþ Ð"Ò-6°K3¸?"<¯"§$“´8\“Î3Þ¶¨«öpöžÖÞõ­#Ä,+À©þéËŸ—§2M'ßDÚù°¢Š+CˆÅÐ4ë‹-WÄ“MÈï5žÜô¶ñ“ÇOš7úz[TQQ¨+/?ÅÜè¯^X‰©Ët¢¾QŠŠü¾aEUœåhôëxµïÖ<]OpI&ãó"déÁ‘ÿ?aDšu¼ºŒín ŠH#“qùQÊ3ŒtäÆŸ—¹«4Tò«Zƾڧ773½­{ôµ­ém-ÛM,øÁ«j:^½ ]õ‰¬¯ZÑ142ÚÜ´lî!ÒM£ï€I‡Ãù'~ÿ°U¯þ‰ZÚŸM´º¼¶»šÖ n­wy¼ažà ±ˆÊäpqÖ¤¶¶†ÊÚ+{x’"AqD¡U pb¸á‡”q¬å£éÛEþOð>›Q­”aòØR´©»¹3r›û’”l»ó>§1 nx‹Äö—)[”â±Ô]j =yRêß+“·’I'ç(®§£QT´MZ{E°ÔíÕÒ ÛxîcY@ Ô0Fp}MV¼ñ 6>&Òôy6#ê÷Dï RZ#È«üD¬ŒÜm]H¨©_GoÇc†8ZÒ«* >ôy›]¹Srû’oäkQE¡ÈQEQEQEU-V‡^Ñl5;ut‚öÞ;˜ÖPu ‘œSWi&¤“[T§:S•9«4ìך àþÈãñOþÆHôϦ×A4V><Ð.­äkû{G¸–ÙÚÒò[9ÃC;!+,.® ´g£ ©Áà‘\GÁ ÙøgÅ¢³›Q™Gˆ-âΡ©ÜÞ¶Ñ¥X¸;¦‘ÎìÊÀ¶r@E$ª Q5$šØ*S)ʜ՚vkͧES3 (¢€:?‡¿ê5÷ï¿–W|â[áΔ¶³4.Ún¤®3ƒ¦Âj—Ãßõ¿û÷ßËF¬HÃÂZB‚ä£cŸú…ÃTŒæ®|Kâ]R {‡òã"9ßrêꌟ• RÝ/ ù»ÎÅÓµnéf[›ƒo4,¨Â6fBLhÇ Ñ®à 0ÈÈ;{ʾ#ñKÅ’.àï CªZé:F¡¬Ã¡kWv¢›ka¨Àb%Ä&1BðTG†‘v]ñçÃÿ|ë´‹ox¢÷Ä:-æ—¦. Öl¦” Ýâä³Cy2>æÒÀ„2)¦b¢v_5SHðn§qô¤­¼žœü§Ú¸€· wû. ›;ŸÆdœúý£O®×ã¹ÇíS©ýÄœ¿v¸/ÙÕ·þÉð¶1Ÿùÿ—‹ ®Æ”ö=zŠ(¯Tgâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QREb€ (¥ÚiÚà'jÍ;o©Ò˜›×5j-ô¡sžqJŸQRGo»©§”e;qòÖ±¤ív…r 7CZw•–éùUdqVRݰ>]߆k®g- r(˜6 ääö§y¦;Ö‡ÙÈ$ƒß"œ4öbýßâÈ5Ö°R{"yŒÃm“ÁÀõ¦ˆN0y­ceœ_QR}ƒh‚Ç=Ö­eÒo`ç2~Íòq})¹#œƒ[&ÂEc•íÓßìéðœã•5«Ëeü¬\æ@µƒMû>3´[cM í?)ô4Ãc!-Ž>‚¦Yt—ÙsBAé×µ7Êã;Mm¶žÅ>SϦ*³@b`x¬'€”>% Ôîf#Ž‚”'˜zô­²—Û\ÒKm±Aís¼$–½ æ3J}©µz[lGœâ«‹vôãÞ¹'BQv±IÑR4Xã4Â…z×;ƒ[ŒJ(ïE@Q@Q@Q@Q@Q@Q@9¤w3 '¥6Šwk@ (¢Q@Q@µä„|8ÿ±oMÿÒXë½® àü‡ö-é¿úKwµìÇddYð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5{·„¿ä¢éõïþôªðŸÈ×­×ìßú1«ÆÅügÎç??™³ð+þGÏدkÿ§¯O¯0øÿ#玿ìWµÿÓ‚W§ÔCáG­—ºÃúêQEYèžñ:u¶ñgÂÙ9Uñ$Ù¡sÿ G°šï£q,jà)SøƒÈük…øÿ#ÂÏû&ÿÓ>¥]åQEQEQEQEQEQEQEQEQEQEQEQEsxJe¹ûÜ'ü#Ð\Gwkf€†FB¬‘g´I"y€üJƒjGµüú]9üCñºêík¥j±Op±3mKa‘—ÛŒ*Kcç!™×¦>oh¬›m&h|W¨êlÈ`¹²µ¶Eî — ÄŒc•qÏcÓ¿[ œ‘[)&ýv^JöÓüϲË3ê¸E‰«7ïÊ”¡µ¥9AJzo7kÉë{;Þ*Ô¼ÿ ;¯û ê_ú]=sž.çǶºƒ|óhßÙ¿dS÷Wí·3[\grôh×±`݂ѠÖ4öæk=VëÌa÷OœÿiL}áÿh7Q‚yÏþÿþ]cîÿcý‹÷?óÛìx¿ûßÿÎòú»ws£:Ÿîð]¿4Ÿä×ÞŽì¹Æ&Ki½xT©þS§6ŸxÉ®§£QYº¦±ý™}£Ûy>gö…Ó[nÝ/K.ìcŸõXÇ{=°OköžÓP¿*ÕeŠ'y’,a˜’P\{kÑu"”›{o÷\ø¨ákNT¡ÝÔøRÝݸþi£JЉna{—·YPÏ,a¹U‹b:€J°¾ÓéRÖ›œ­8èÐVMέ4>+Ó´ÅT0\Ù]\»wŽKuPqŒJÙã°éßZ¸ûmZkÇ:=Ä è‰e«[ îŠîÚ&<Ád${c§J´ùRIëuù¤ÿ3ÔËðþÚS”£x¨ÏïösqÿÒn½ŠÅÐ5‹ÝWÄÍ&øìõ‚ÚÄ6¶òÇ_šG<úúRj>&±Ó´Ýnõ™æM®ã‰~`V˜¨Î;O\sŒõÅ{Hòó7e¯áò1x*þÕQ„y¤Ô^ŸßQkÿJKÕØ¥ðßþIß…¿ìkÿ¢V³¦×îì>+=ß~™y§Ûı䒗$ÝÈ à)Ž ¤ˆ»†ÿòNü-ÿ`«_ýµÎx³÷~/½~Y¢þÀòä2oÔ'ð{eÐú«°èMpJN4)It³û¢Ùõt)S¯šcéTWææŠòr«§ònæ×à FßW𿴓͵ºÔ/ç†M¥w#^LÊppFAk'á…Ò\ø¿â™EøHà?¼‰“þapþ =éê*?ÙëþHþÿoúQ%Zøqÿ#Å?û!ÿÓ>›]99á©IõŠü‰(G ãhChÕ¨•÷²›GyEWaó¡EPGð÷ýF¯þý÷òÑ«œÑ.– é[ÏÙÚ0Ø*èþÿ¨Õÿß¾þZ5xŸÄ¨>%ÚéZ …ü ¯ê¶¥4³Ûé·$©al„˜À$~é#ñ ‰WG¢]ü>ðv£6­=ΧLÚ½»Z߬РÜFçs‡OºKIÆI'\.«û9øZÒÆk Þ\i~!Dt·¼Õu+ZFR²ÛO Ô²,–Ó+–.¹å&žÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄÕÙ>¤rµÔë/ük­êž ñW†õ­SÒßH²Œ¥Æ¢^e/'œ¯o Ógí‘Æ"GK‚|“Ɠ–9%—köwŒEû(Ä Œ_úø°¯5¼ðßÇZÎKk߆Þ'’9‘ÁÓ¥ÆÇ÷kÙþø7^ð7ìÑâ-ûCÔÅi0¶Ô-Þ 4ú~# ŒôàúQÙ•@¢Š+Ö$üVøýÿ%ßâ?ýŒš—þ•I\wŸ¿ä»üGÿ±“RÿÒ©+ƒ¯[³P¢Š]¦–à%9UŸÍ*ÄÍÛ$P1lV°§&Ö‚¸ÅŒ€}jUš¬ #¸œw«Yd…ŽÙã5éRÂM»X‡"§Ù0q»5s_ ÉÞW€ñVað£\õJW8_ñÅ}OcðöéK¬O…ãlc$gê+~×ö{}«ºÊYXœ©8÷8v¯Å| ‚vž)IõJßæxÕ8¯n{³ãßøCDk³ËÉöÇëRîQò•‰¾Ù³ÉÁÝÉ TŸÔŠl?³„ŽYŒ ªOôõã/x)óT²ùKŒ°Nú³â'ð‹g§+Ïó¤“Áò/@K8޾ßٹѓ6Îå¸Ü 6Óô*jµ×ìÛ$lÚI*v‰ž}z~´áâ/Tvöûí·ùš./Á·»ûˆÂr‘œð9 Š«?…Ÿw1«“Ðq_k^~Γ@2¶S;sÁÓ¬+Ùúâ ÛÈ…y9ˆ©üëÒ¥ÄÜ _»Å¥~öÿ6uÊðûv>?›Âì\†·=ˆÿëÕi¼8áq±‚Ž…†?­}EðFý$*mÙ;€§pü±ŸÖ¹Wá=ä@žYàü˜üø¯ ¥áìwû®* ¿5ÿ {s¼-_†¢ûÏœ%ðû?» zžC&ŽSåÚÇÜÿžkÛïü{nX}šM¸È>[}ÁÅs÷ž ƒA0Ïsð®zܹ¨µ+ö±ëà í#ÉJ X‘‚?‚ãNo=«Ñï¼8Ñ ˜Øv$ÃŽk.•çcn낯’ÅðµJW!×霺q¿åP½»/y5Ø\hò–Á,GÓúÕ ´— N>µòŒ’tÛå‹:TÎccsÁâŒV¼–/8BGLâ¨Knr0?ùÊØIÒÝ)\¯E<Âí0ðk‰Å­Ê (¢¤Š( Š( Š( Š( Š( Š( Š( Ú€?òB>Ø·¦ÿé,uÞ×ðþHGÃûôßý%Ž»Úöc²2,øKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£½ÛÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕãbþ3çsŸ‚ŸÌÙøÿ#玿ìWµÿÓ‚W§×˜| ÿ‘óÇ_ö+ÚÿéÁ+Óê!ð£ÖË¿Ýaýu (¢¬ôO?øœ²·‹>ˆ]#—þI°Ò!`?âQ¨ö:ï£ #Pä3àn*0 ï“θ‰×Zø³ál³Hľ$›/#þ%ˆêk¾ŽE–5t`èÀ2²œ‚B :Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( .-cþè~"j¾OÚ>Ãt×>Ví»öiöÍ·88Î1œŸÔmõï‡u»<ý3SŠæ{Iö•ólc…ŽÓ‚1$R/ }Üô ›¿ÐõItø¾[oZ­­âŽ6æêÚØÈ„†;¶›?ê¡ì¸6u Ûø3àçˆô‹Fͬ~¢ð®ÈæÈ©É$í$óŒ÷¯|îS‡ÙŠ“ù»Ûåfïçcõ /ÕiÑÂâUý­iÒ‚ìéÁANý¤ªB*=âåtô¶Oˆ5haøõ iŒ®g¹·†å´,pêJÀœç9•qÇcÓ¿YñÚß EoqOº–‘J¡•ÔÞÀ x Ž1\7Œ´ëˆþ8iÚôqîLÓì`ÜXmßszöø#©ýÜ“ŽŒ«ž8=ÏŠîaÕ#Ðì`•$KÍ^(Ìñ°a[3Ü2àu;­Lddm,O;p]6ÜkÓ—Víç}?;¢q°„kå8º/HS‡;þWê?KSq’[½lŽàv¥wªx‡ÄRÞ]Ow Ò´L<ò#u¡väžìÌÇÔ±=I¯[[˜^åíÖT3Æ‹#ÄnUbÁXŽ ¬ï´úWÍ6±ÿÏ…µ½m¡ûD2Zø~æÐÂÜýŒÚ­Â†ãkȈO÷‹J°Ç­4?®´ÅT0\øv—bàÑÜʪÎ1‰[k[´i®e^Dkä·þÒÄUÊ› ¸pÍŸj7iÞ°Y1k?†ÌòG´|΂ÑPç¯Güý…V×ÿäWø³ÿmÿôÙoW))aâ—Eÿ¶7úœØz¥œVœ¶œ“^ŸYŒuùÅü‰~ÛMeðŸE·¸‰àž'¹ŽH¥R¬Œ.eH<‚¤ø`³¯‹þ)ùòG!ÿ„ŽcŒ§?Ùw«Øü¯þÿ×ý…u/ý.ž¹ï…š¦£âߊiu ÒÂIÍ ÇNž§‘þÒ°ú©«·  =8vŠü‘òùýib³|f%«sU›}“r“±è”QEuŸ>QEtÔjÿïß-«izæ·©éz}ïÙô ayiâÁ.¥xÏMʶX²çk®pOÖ¬ü=ÿQ«ÿ¿}ü´j»àÜèŸt¥µ™¡vÓt…%qœ6M+îD›KCoßÀÅ^O)ôý¨ò¾£ÿ„¾ìË ÿàv¡ÿÊú¸þ5¸¾doµjy. ØÌ¸Ýåã9õ«œôÃç[í[-vûQ‡Ì†öíÆEÅ»ByUaè=gŽ òÊgíc5¼q:‚Mχs{¨ñÿ”ê§âMdxáô—éq¦ÜÆšÕ•®ý2âYãܳÚHrÒC(#oNA+âæ³ªi Ôî#¾”•·“ÓŸ”ûWðá®ÿeÁ3gsøÌ“Ÿ_´iõI%f\däzµQ^°Åoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸UPs¸â¼v¯#Q£ç¥I8À¹ïOE+È<ÕÁ;‰“ÂI8aб í<äÓ=ê%Ç\z°’Чôæ½j)hfË‘#H¿*8«¶HP/”tÚ@ªñB2NðzäZضuÀi e˜8ý+ì04c9jÌ$ËV ‘•BG¨­û+%)L}â³mö!Þ zVö™åÈr[ÓoÒ¿OÊpÔ¹”l®qTlÓÓ´èü옸Àä¡Ôiº˜«˜þG r;ýk.ÃÊ}B·sÈãð®Ï@’5UewÇ.9>Ü×ê|±Áa]JqMž6&¬¡£gÃ> L RÝ\žFQ±úõ¯Xðç‚b–0Ãk’tLnϸ¬¯ -¢0iƒ+¾¼qô¯lð³Ø)U_ÞѶ€ßxƹ†ISR²íuùiþgäæm^-¥q|9ðÒÎÚZOÌWewº?ÃÝ= ì²MØÎã?LÖŽ‹ö|·¨äåGëŠî´F·Œªû„Ç¥güWšb%)Ô«'7cnÉ)f•ñUo~æ=ã1ä*î¦Ò¯Ÿi¶‘»–Þœ¶ò2?] ûyV¤Åæ7Ü#»W’øº}mžK›vº˜1Ùˆ™×° ·_Ò¿5£ŒÅc¦Ó©ÊNd>å5ùyâ¿Ïc³ººðÆœ®f»€0ÆJ‚8üªƒø³Âçt…w+°n?5àþ"¿¿¼+ŽâÁݼO)#ðÎkÔ'Õ–R¤ÈcÎçuîOÌH…}6%•UyוýOÚ°>dsŠç‚¿¢>ªøÀj¶gÇ9e?Z’øNä²ùñ*‚ÅÔ öƒŽkãÁªêɲ?5ÁÇÌY¸=;æ­éºæ¢ƒdÏåòX””çéƒÎ»eÃ’Š¼kËï=J¾ä|­ªkîGØqXøvø![Ø[¦æŸÇüi·³ºRaHfpW?:ùÃBñã„U’`@ãÌr€~%²kÔÚlÀ’UpÞõäÞ!ø]k­² òB §ükìOÙ['Ën¹Á¯7ñœ¬$ ‘µAü…Op_Š9ÆqZÒiùŸŒË‹Éñ.Œª]zŸ!êž_1À·cß;F=GW ¬øLYMå:ª0çiUçõÍ}9â]&8î$`5^xÛü³šòïi°±`J3’}:×÷— ñ„³…âR”Z^«çú¤eyÄë[™èx=þŒ‰»åúÿ묽,)X@8¯NÔ¬Ùˆ PŽÁü qÚŒP±#n2x s_m›e49}¤-gýyŸ}J¯2¹Ä]Ù…á@u%xþU‘5š#7O¡®ÃR„¡' -Šçï"]Ä”1¨î?¨Å~=™àc =F¹ÎË#€¹ôÎ*¡·'>Õ­uì€/¨ëT. UR¥~wŠ¡6Ú:âÌùVÁö¦qžÕ,™|dóQGó³VlÙ EV# (¢€ (¢€ (¢€ (¢€ (¢€ (¢€?j>ÿÉøqÿbÞ›ÿ¤±×{\Àù!?ì[Óô–:ïkÙŽÈȳá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒj÷o ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW‹øÏÎ~ 3gàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¨‡Â[.ÿu‡õÔ(¢Š³Ñ8?ˆÿò8ü,ÿ±’oý3êUÞWŸüNiWÅŸ L(’Kÿ $ØY¨?ñ(Ô{€•wÑ–1©pð79÷ÁÀÏå@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(†ø‘¤Í¨ê¾6Œ‘ܶ¯R<„àÛ§úT‰ÐòZÒ23• ÏsQKm òBòD’Œu×Å7¾Òt"—Þ®¾}µ^cñ_þD{ïûéîÖ½ææ/òÜ\JA„Ì’K+TQw’ÄžœÖw‰t™´][@·‘ÝïnnAŒ’6Ë®XJ£9 à|õë\~¯û¯i²§É#øBÖuà´gNÔÜ¡?Ý-lGL¢ž W4Û£Y¶µ÷?òUÿöpЧ™åÑ„eîß®ºª³Ž¿.Oú[_høoÿ$ïÂßö µÿÑ+^IðoV›Vñ¾•­Þ*Du-"æ#å·íê7s„$² ŽO& Éõ¿†ÿòNü-ÿ`«_ýµâÿ?æKÿ¶û›®ºÍûL*éoÖÏeÔàð9õF½å4¯äÖ"ÿ’ûEø3ÿ3×ýWßû%W‹Q·×u]ZÒÚMÑÝø¾ ÛHòÞÖÖ Ü`ã9kFþ¸d þo_Jy’ymg•ÏY$}:ÑÝØ÷fff$òI$òkðçü”KOû Íÿ£µÚ¨Éû*0èÛüíù6gZ„^?3Å}ªpƒ]®¢¦ŸÊPO¶é¦høkXþ̾øGmäùŸÚöÛ·cËÄÒîÆ9ÿUŒq÷³Û{ᆭ6µwãk‰ÕÓÄWÀFbŠ”òO%Pïž+ðçúf¹ð·ÙÚU¯•·ø¾ÓcwænõÇÙ#Æ1Õ³œŒuÿ 4™´ëO\HÈÉâ-Bæ „ä(—ÊÃq×tLxÏ}ÂJsœ{_ò„Wçs ¥‡Ãák&­QÅ/W,Eiéÿn(·éÜÖðü€î¿ì+©étõÁþÏòø»ÿcÍçþ’ÚWyáOÝê¾+~XbÕG—áS}­¼Û.îçÕRkÏÿgf”ê¿<ÄEÿŠÞè®[æû-®GAÀã¿ ¯F–’„{&¾æ‘ñ¹†´ñ5?ž¥9ú)¤Òù^DZÑEÞ|¨QEÑü=ÿQ«ÿ¿}ü´jÇðôŒ<%¤('þAÚ69ÿ¨\5±ð÷ýF¯þý÷òÑ«œÑ.– é[ÏÙÚ0Ø*¤g=_hÒx›NÓ´{KûÍâÞÍ¥E–u¤`¦ß*5_õ«ÎÕåYB‚¬«±eð«P’HÞ/Ïlú‚}²FÃ¥ˆ`¨¸ÈÿYò•ûQÜVGü,m¾)ÁâÉ4û Io4‰¯¾Íoræ(â_>`G–ƒžW‚Aõ3U±_ìŒßØ®Ûv½,{Oî¸8!àüƒŽ÷Ejr¶ÖÇ€üzðÕÞðÂòæëX›TÖ¯"Dúy¶|™![þZ}à2=­yïìêÛÿdø[ÏŒ|ÿËÅ…zÏí9¨ÛOð²ÒnmåXK¸E¨5Ã'ÈPñö„v¯'ýã~Ê1(ã#×þ¾,)v:)ìzíQ^¨ÏÅoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸:ñ¥»5 ŠšLÒ–&‹€ôsÍ[ŠVà &¨Í=d9®šUyÕ͈¤t`Nßbjý¬­·€<ñŒ×:'ut«ÝíÆG^+ÞÃãÕ7ÔÅÂç[ktÊȨFq–ÍkYÞ6åP}qÍpÐ^aÀÚzœV•¶¦c|§9öÆ?Zût¢Õßõ÷ò¦zFŸ«lIÏ8Î1ý+¥³×<¹RU%]zmÆx¯#ƒXvà¸ü­jÚøˆ”6Ð1ÊŽþ¼×ê9oÂ䛺8jaî} xémÙ `0þ&PÌ}ºW¨øoâ+D¨¨§{œ°2 ¿P?ÏZùÓÅN¤[gCšèì<{4A<¹BGËÐ×>m’dGM¦”dûíø)ŽÈ)b–ÇÝ^øª…°n=FGåþ5éZ'ĸ.?P2 Çã_Ö_'ŠuyG$d¹9õë]Nñ–âßÓ™‰ý⿞sï£þ2nX Å?'þm.Åá%Í‚›¦ß‰ú7¤üBL Ë´0£®?*Û%Óõ"c»†)ÐòCrøþ5ùé¦üvòvºÈTc ÏSëŠìtÏÚ UµçVn ôäŽ:ü6ú8ç”sz/ò¹ëá3~)ÊmÊù­òÿ3í ­+úÊ9bq̸;‡âHª7ß ¼3ª– ’Xnç“Ü`ñ_.AûC+(qþƒCÿÖ­?öPdWè°OS__ÁN/«ӧ-<ÿÌúì7‰ÜO…·´¢ôìÿá|“àLJÕÆ êËÁWäcÐäçN°øGáËiž_>"1³‚sê Ïõ¯ ´jÁÛËÏLàíýiÓþÑG‚pIú~$k‹þ!??qÓ›¿¡éËÅþ"’åö2ü `ð‡´ÇE9Tϲ—èr:Öµ¬º“&è"ç¡/ÓðýzùrÚ%9"ÿ ¹låX×´Sì]“«0äª7®1]´<âÜcµZRù»}öû«çm[âôó1!œ·+ÁÇýMsšçÅ­GQ‡É{›‡ˆ*²MŒ(§Ç¿¡øÀ§”Î1ŠîÛw_%Ðâ£Â¸ªÕ}¾"W“ß§àZñ'‹Q_cWœu5å~$ñT—NÀ ÀôÚù'òÈ®Rñ˜“%¥<ðrâ¹ëÿ('37¾?Æ¿£2ÜQÃt×$”äºöûÛ?AÀdÐÂ¥Õ5þ°®IœƒþsÍsW·¹Ü ãÃõæ±nuå|‚ì€2?eÜë wd’žâ¼üÓ‰a[í~GÒ ëµt+·,1œqX³Þ£qíŒ7"«]já‰û¤zYÓj+!ÀÇÚ¿-Ì3xT•Ô‘Ý v,Oq\’ fÍ.IÇLt¦Éw¼€j«¹,M|N'ϱÓv ÐqQ“žÔ”W)9QPEPEPEPEPEPEPíGÀù!?ì[Óô–:ïk‚øÿ$#áÇý‹zoþ’Ç]í{1Ù|%ÿ%Kÿ¯x¿ôï¥W„ø»þF½kþ¿fÿÑ^íá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒjñ±ó¹ÏÁOælü ÿ‘óÇ_ö+ÚÿéÁ+ÓëÌ>Èùã¯ûíôà•èú†Ÿk«X\Øß[CyesC=µÄbHå Œ§†R 5øQëeßî°þºžûB~ÒÚ§Áÿ3OÓ¬®¬ôÝS7JæI “P†ÌE V÷0aòŽs]/í ñ‡TøWÿ¼:PµƒûJêgÔ5 Ý6âþ+ cÝ4æ(\í-9ÀçE~ÌñmÞ›'öqÑm,í…“éÚ:Åmkul.’ëÈ’0‡ ç “äÚI-“É«"økâ}+VÓ¯мa%‡´];A²’S3Ûi–‘ÛÆÒr¨,B¨Ï\é@ôQEQEQEQEQEQEQEQEQEQEQEQEQEQExþ‹§\izW‹¡¹Ê‘¼so8]Àå$º³‘ªÊ}³Ï5Þü7ÿ’wáoûZÿ蕪Þ>Ó­ì¼ãY¡d—š}Ìó¶âw¸¶òÁç§Ë==I«? ÿäø[þÁV¿ú%kÊ¡KØâ;EÿéGè¦7ûG(–*Ör­úªI;jôºvò9Ï~óâÏÈæ†_í23ʾȣ‘2;áÑz2)êyÕ×ú_Ãë{·âH4øôå ÐÆšÄàŸö·]H 逼d}_Æ?Ÿãïê¾vß³]]Ûy[~÷›i#nÎxÇ“Œcݱϖ-´×>Ôôèbv¶1ŸBWE,-mÞÈØÄíê^1ÉËl¶kËÆEª³o¬¿XÁ>ã‡+S– ¿†’OüN¾#ñiÇð][øu¨ÛÅàÏØ4˜ºŸE†xãÚ~dHâW9éÁ‘??c^'ð÷V‡Bñ>’dW6Ëq ÛE@aãL¹ e™±Ô³IçÔ¼ ÿ4ïþÅYöƼsG¶™5Má¢qš¿…cIJ¬ËbK(= ”‘Ûpõ¬ñu$¾®×Ùûj™ÙÃøJ3þ×¥7¥Xê¼ý¼á§ýºŸž¯¡ì¿äWŸþÜôÙe\ä¶]Ø+RÿÓÌõÑ|(ÿ—ût_ýº¬¯‡šLÓ|RÕ55d[Y^[:’w“W»e cÄMž{޽º œ£‡K»üÏR4«fò›²ä‚ù¸4¾öìRðßËãý6!ÄpjH:G>¸ˆŠ;*ªª€88è¾ÿ×ý…u/ý.ž¼ëFÿFñEÆ£÷¾ÅªÇû¾›üýOUµëÛoÚ7ô9ÙŽ3‘è¿¿yà]幚òÕ/goïÍ0óelvË»p¶_£IöoÿI_£<Þ/÷ã9­”©Çæ£RM}Ó‹í¯tìx[þCž0ÿ°¬úCk\ìéûØü{vÖjü:Œ tY.4:w þÈirpI<ÕùçÒu_ë^×´û SJÖïecgl.#šX,ôùJ°+€7·Ì:¢àƒ×ö`Ð4½"ÓÆW:m¥•ÅÅþŸçKoÆÒçFÓå;ˆŸÞM3óüR¹êÄžºŒªÙtçOïOògÏæ˜j´0J¥EeQaå5ìçýñkä{uQ^‘ñaEPGð÷ýF¯þý÷òÑ«Äþ%Añ.×JÐl|/àmT…´})¥žßM¸%K£d$Æ ƒ÷Iˆ {gÃßõ¿û÷ßËF­ÚiØM\øž{ÚÈ)ðçÄëë>_þ&¡þÍý¡øÿ‹wâ~ä/ÿ_oQUÎÂÇ÷žøñ«YÉm{ðÛÄòG"²8:t¸Áþí{?ŸëÞýš Ó¼E£_hzƒx­&Ú…»Ã!FŸOÃÀddžœJ÷ºå~%ÿȪ?ì!§ÿéd4Ó»AkÔQEzægâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QR@8¢Šw° ½±ŒÓ’R¼v¦QT¦ÐÒãåŸÆž.#VÏ$ÕPÄõ®˜âd‰±¯m4G''ñ«BñûÇÐ+%(y¦RyÅz4óN6H— ,ؤ¶ÓþÍZ‡Z*ÅwcÓ¨®T]a9üiæí›½JYÕHZÌÍÓGk¾#ù²Üúš·‰J©É=yƸ(ïNì3ê*Âê~U{t8–´V’3tQèÑx¥bP>bItÕ´ñ@Ý„)ÀÈeæCTd]¸-ž§5 ÔÎÛÏ\žµô¸Æ¼tæþ¾ã‡GªÁãC±[·R ÷ç"øÅà dÜ/Zò•Õ¶€#FúzÔ§XtÁ!‚÷Éé^¬8ç—Çùð«±êÃÇ„öS× ´þ”ããg~hPqùו]Šîëíšõf`qŸa]Žq |DýR=So¼e·†$úb 9$o;:Ž@¯1ä¬Bä ÿxÓ_VqË9”×Õ݆QƒÚ¼ÊÜgZ§Ûv-aÒ;)|Hò|¦RG\?•S“Ä Ä0óÛƒùæ¹)u&cqU¥¾fèpkç«ñEi}¦l¨#¥¸ÖLƒƒÇ¡=j¤º¨a×w°ÚéÝ@Ï1Q<åÔô¯¶uVww5TÒ4î5,•Qï×—$•SÌãÞ˜ŒûׇSR£»fŠ)<Ù'9¨‹r:Rš+‚SrÜ«QYŒ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šý¨øÿ$#áÇý‹zoþ’Ç]íp_ä„|8ÿ±oMÿÒX뽯f;#"Ï„¿ä¢éõïþôªðŸÈ×­×ìßú1«Ý¼%ÿ%Kÿ¯x¿ôï¥W„ø»þF½kþ¿fÿÑ^6/ã>w9ø)üÍŸ_ò>xëþÅ{_ý8%z}y‡À¯ù¢ =l»ýÖ×P¢Š*ÏDóÿ‰Ò4>,øZéÎÃÄ“b8ÈÿÄ£Qõ ~µßFÅãV(c$Q±•ö8Èü«…øÿ#ÂÏû&ÿÓ>¥]åQEQEQEQEQEQEQEQEQEQEQEQEQEQE`xþÚkßø’ÞÞ'žytÛ˜ãŠ%,ÎÆ&@’O­«khl­¢··‰ ‚$ÇJQ@ÀPÆ*Z+5¦çåoÏüιb%,»Újß=Q“àë˜_Æ6ë*ãM~Gˆ0ܪڤaXŽ ¬ï´úWŸCû¯è׳µ[Ogüôû6…û3Ûw•·<ã9ÁÆ÷†.aѾ'ɪ\J‘ÀÉ{a#JÁ%kýJàÊXñ…˜ÇûyÈÛƒgÃöÓY|ñ­½ÄOñi«‘J¥Yhö ©Aãä?ßB>Wü"¿;¡BÙv*­µæö~_j—ÿÀy×áµÎÃÁº?ü#Þ"ŸJó¾ÑöK¶óvíß±î×v2qœg5wÀЦ—{p± žMKPå 72­õÁU'©³;n>µ%ü”MoþÁVú:òÈëþº—þ—O^ݨÊ1[.ý)˜fuªV£Z¬Þ²xvüïJMíç©çZ?úZxŽí8ŽZiÌ©‘5©'$³¶ê0\†ãè¿ ÿäø[þÁV¿ú%kϼ#m5LJ<|ðD÷i㯌1)i%X'‚fDQÕÙc!Gr@Èë^ƒðßþIß…¿ìkÿ¢V¹0?Âÿô£è¸¡¯«WW×ÛGÿL£Î£ÿFøÁâýGï}‹UÑwÓŸo%¯^Û~Ñ¿¡ÎÌqœ‰fÉôïÆþŸ†b0âG¦0O ?ˆï.^èþOˆ¼iªùÛ¾Ó¯èVÞVß»å=£nÎyÏŒc½óÅÙÃþAž*ÿ¯ý?ÿLZ]<\+8¿ï¿¾oôHψêÖR«{,<>QÃEÛå)K^·ÞÖ=~Š(¯lüÀ(¢Šèþÿ¨Õÿß¾þZ5Gà¯Úë>Òo¦Ÿ tÍ>Yç¾×µE’Ye´ŠglGre™¸R|=ÿQ«ÿ¿}ü´j«á½A“ÀZ=º¶?â_£é²¤DïmµM ËMYd{½28#Rï,¾!ÖQFI$›°rk;H‡O×ô»mGO»ÒîlîPc ·þ5ð·†ôpí©ØEcl©Ai‰JŒ…EHãË’~‚©Ù+³%)2¦²Ðèv3ÝNtóHÎBëºÎNNnûÖ7‡|amãkVÖObŸð”Af#{Ë‹£ˆæ°ÉÝ<ŽÀiàNIÎø—â];Å 5MKL•YV9­åJ—‚U2=ëãO¢-I).¦©I6¥¹ëtQEz䟊ß¿ä»üGÿ±“RÿÒ©+ƒ®óã÷ü—ˆÿö2j_úU%puãKvjQEHQ@Q@ÇjZ)ÛÇ—·o>µJÏp’M&N1ÚŠ)\oÂà RÀúæ™AàõÍZ“êý©ë1Œu¨hɪUØV&2‘Æzö§‰qÈëïU³špç’qVªÊú‹h QOñ¸Õ<œã4™ÍZÄMl+"ïÛQKöŽ*‘qÜÑÉãŠXšÜ,‹~yÇÒÎ[ïrT¢§ë ©lƒŒSKî'5J3šjØì8¾­4ÆŠ+&ÆŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ö£àü‡ö-é¿úKwµÁ|ÿ’ðãþŽ7ÿIc®ö½˜ìŒ‹>ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]BŠ(«=Ïþ'FÓx³áj$¯M‰#‘ÿGÔúW}”T¹€vÆ[Üãò®âtëmâÏ…²8r«âI²#BçþA` 5ßFâXÕÀ 0R§ñ‘øÐ¨¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠùÓÄßóÿ¸þçëÜWÂöò§ˆ¡»oµZëR—šÚ†Þ82y“‘½íšñ½{IšËÂZõäì’Íw\hY![=ADd‘ÀyÌqûÂz±¯~¯/¦Ÿ2šíø§ú3õž0ÆN „°óµùÓkû²ƒß£RŠÕv9Ëù(šßý‚¬?ôuå?{àý>ó§ö™©ìÿži‘§Ùžû|ݹã8Îp ù(šßý‚¬?ôuå ÿäø[þÁV¿ú%kÐ¥üEÿoÿéHù û­Oû—ÿÓ29σ?ó=ØÕ}ÿ²W Û[Cem½¼I Ž8¢PªŠ€81\ïÃÛh`ѵŽ$æÕõ)%dP öÉ—sçj¨Éì v®ž« J¿oÏSŸˆ1XÌëÊ:.k[Î+–ÿƒ·©ç?âŒðˆõßøüߪØjgû˜òä´M›¹ëäç8ãwCŽj|ÐÛÃzÄ0ݽز֭-„ŒlѴѸÓëí–×ú\°ùŠþT‘0+4RFÊRgd8$‚ â¸YØŠþ%PÏ) !Òp¡†scÑÊç’OÌXqQRŒj4öý|Ÿ‘TêJšµ¿à>þ¦¯ÄËbøsâËè5kö¿™®%–Ô8¶Ž ª76>XA9=O¥sß³‘'öN„œçþ#×þ¾,*xÊÎãÀšŽœÞ%¼ñÔ~̲ݪíb\eKr¤åÛ»@¹û>.ßÙV1×þ+ÿäÆŸZÆ*)%ÜI·«=jŠ(¯\“ñ[ã÷ü—ˆÿö2j_úU%puÞ|~ÿ’ïñþÆMKÿJ¤®¼inÍBŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ï¢E0 (¢p1ES¢Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®¡EUž‰ÁüGÿ‘ÇágýŒ“éŸR®ò¼ÿârÊÞ,øZ!tŽ_øI&ÃH…€ÿ‰F£Øü뾌0Cϸ¨À'¾N?:uQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ŸÅ Üx³Áš…¥‹lÔÒ)Ѱ\Æñ²r@ùãy#Éû»÷uºÊ(¬Õ8Æn¢ÝÛð¿ùþGmLeZ¸jxI|0rk¿½Ëu~ÞíÒÙ7'Õœ™Ômô¿ë3\ÉåFÚ~—m¤å乺¬Ê=³Ïgá¿ü“¿ Ø*×ÿD­qÿ/æÒµŸÝ­£Ïv÷s<ƒ!U­ÚÞõPœ ‹6Aé’Ø;p{Ÿé×Gƒ4 ¸ü««]>Þ £Ük¬j¬22=+‚ŒÛÄÊŸHßï“LúÌÇd´q’v•g +¯†”eNý÷M»ít¼ÝGþñ–ÛÎó÷Ý\ÜîÛ·lï.Üdôߌ÷ÆxéZTQ^Œb¢”VÈøºµg^¤ªÔw”›oÕêÎsâGü“¿ÿØ*ëÿDµc|8ÿ‘ÇâŸýŒÿéŸM®¿[Òa×´[ý2á ½·’ÚFˆ€Á]J’ gÐ×ðÁg_üSóäŽCÿ ÇN²4ïV=±ù^!EªŽ],¿_ó:§ZÂS¢¾%)¿“PKÿIg¡QE©ÀQEtÔjÿïß-¼çÅ?³¶‰ñOHðÕíÇÄÛ½‡¦(²·Ñ&s´YĤ"f]å6“·{œ“èßÔjÿïß-®x'Ä×:'Ã}-m&hdm3HRW?³a5Q"nÊèùÆçö%ð*¶Ù¾5j ú—§þPÃ|?óZõOü'§ÿâ«Üáñ¿‰µ8`¸‘cA*#×® ˆÉùZA—‚ù8Üv%·‹uãu L!ßH^Z@ädÄ«÷ÀÉ„– ¦¦>ÔðÔý޾@¿ò[µ@«Ù¼9?ÿ^—¡ø'Ãß¾&á¿Â[c‰á‘ïþÆm±#K§±ifÉ®O’ÊšÅ?jV Õ.b½˜2[¸Á#œ©ö®à-Ã]þË‚fÎçñ™'>¿hÓèìi s+ž­EWªâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QREPEPEPEPEPEPEPNÞ<½»yõ¦ÑM6¶¢Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJô}CPµÒl.o¯®a³²¶‰¦žæâAqF –vc¨’O ó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®§Ïß>2ø—O×>]x.ÿG¹ð>½â]7K¸Ö¬î#»{Ã,ò¬ÐG€È¨« àîÜà. µµ_ÅŸ|=¸ðΙá«ñ¥M¨Xëz”ׂÞ9›ýÁ®,H¬¡]ðã8kØüYà]Ç?ØßÛv?mþÇÔ¡Õìzñù7QgË“äa»ÊÙSžA¯'øÛà† ¾x¯ÄºÏ…šþÆ;ùõÛˆ"½ž9n/n¶Á&$”Yw*2“i?)Už‰k_ø‡csᯞ2ñå–ƒk}¨E}u=äë4Ú%ñÚ]Ènp£'©»ø_¿ è£øKÿ–¿ür°üñWCñÃÍ{Ä:–ƒ”Þ½¿´»²ˆ­ÂÙMg¤†Ýö®A‰Ø §k²ô&Ÿð/ã´“W†]èzŽ› …ÛÛ‹¯´+[Þ[-Å»ïØŸ1F!—y=hVÚ áŒè[þ…cÃ2áõ»Px$gýgCŒb(Ÿö‚øcÿ…‡áY2ʸMnÔžHÿYÐg'Øï’5‰HE -…䜓ø’MÊ :‡†Ã òAü€8_ø_¿ è£øKÿ–¿ür£ö‚øc#Ê¿ð°ü*¾[mËkv 7ä~ó‘Î> × SV5Frª¹ÜÄ n8'ð~ÀÜ~Ð_ mà’_øX~“b–Ù·jY°3€<ÎMIÿ ÷áý àò×ÿŽWu$k,lŽ¡ÑVV ŠòGã£'Ç_øVöCK ­½ÕÅÞ§¬ý’VóîŽÞ ™¤XÆünPs‚W­%çí'àH|w£é‘xëÂO¢Üé··77ŸÚð*xåµXcÞ$Ú»ÖiÎÒ2|¼ŒlïÂýøcÿEÂ_ø<µÿã•Åüý¡ôŒþ6ñøytû“¤Ï©hú‹Ê³K=‡ÛZÖ]ß 0––Ù ,IÊàXð×í/câ?Œà•ÑÞY5GG´Õ ÈfšòÆ(¥¹F‹hØ¡fù[qÉSÀ ¢ßö‚øcqrÿÂÃð¬{Ô6É5»PË‘œæph“ö‚øcÄ¿ð°ü*ÞcmÊëv¤/äþóÆ>¤W}kjˆ¡@UU€ 5vBʡܤŒí8##ð$~4ÂÿÂýøcÿEÂ_ø<µÿã•´ÃUÿ…‡áUòÛn[[µ¸#÷œŽqõ½š±ª3•P¥Îæ cqÀ?€ð ãö‚øco’ÿÂÃ𬛶Èõ»RÍœærjOø_¿ è£øKÿ–¿ürºÏê¶z©êzŽ³ì­¥¹¹Û”ùH…Ÿ-À<Ié^!¦þÖ1k¼Õíü)uo¨7Œ—Áz~—¨\ù=Ë*Ó6Æò1¹·.Nxéo?i?Cã½L‹Ç^}çM½¹¹¼þ×€ùSÇ-ªÃñ&ÕÞ³Nv‘“åä`+g{þïÃú(þÿÁå¯ÿ¯¿ý³ü5ö x– 5×¢VþæYÕ'Ó,äÔ"²‘c; ”›…RW(„6r¯JøéñÚ?ƒ+£ÃŒuÍGR†þí-Í×ÙÕmìíšâá÷ì|°EW’9hVßö‚øcqrÿÂÃð¬{Ô6É5»PË‘œæph“ö‚øcÄ¿ð°ü*ÞcmÊëv¤/äþóÆ>¤WWáMvÏÅѵ9Jiú”7vÊWiHÐ`tàŽ+M£Wd,¡ŠÊHÎÓ‚2?Gã@/ü/߆?ôQü%ÿƒË_þ9QÇûA|1‘å_øX~_-¶åµ»P€r?yÈçPkÐ)«£9U \îb7“ø? àn?h/†6ðI/ü,? ɱKl[µ,ØÀg&¤ÿ…ûðÇþŠ?„¿ðykÿÇ+¬ñ«g èž§¨çû>ÊÚ[›±O”ˆYð€ÜÀž•áþ×ÖÃáw‰|`ó-uS¢é×é‘Ru’þ îlb1ì%Ð.òIq°ÊpI­ŸŸ´žð‹Ä©¢Ýh­ªÁ›­ªÌnf³’ò;5dBæ·™/(Jªyí@wü/߆?ôQü%ÿƒË_þ9Q·íðÅgH¿áaøTîVmã[µÚ0@Á>gSž>†½šcS r º‚¡±Èüä(ËüCñ[áŠ!·ƒPø‹áY ‰äcköÊ$²±œl•ºsŽkJÚ áŒè[þ…cÃ2áõ»Px$gýgCŒb+Ð)©Ĥ"„–ÂŒrNIüI&¥F)¹%«7zµ! S“qìº+»»z½ÎÚ áŒþ…dË*á5»Ry gýgAœŸ`jOø_¿ è£øKÿ–¿ürºOj†•áËÛ½+CjP¨{}-'Ž;îd„*ãïdôÇœ ð«¯Û4-2c¡éöڥ׉®¼5*êØ·ÓâkuÌ—+va;¢ùå‚wL0;;?ÚOÀ“xïXÓ%ñׄ“E¶Ól®m¯?µàlòKt³G¼Éµ¶,0 dy™9 ¸ŸàÇ‹ô/x¯â”Úµ§k1[Ì$ÓîãLm¥X¢¾PŸ”¼R¨=3ŽªqÌÞþÑÚv‡ñvß÷>¶³O¤hš®³gv$ò®ï"ž{XS1+O â_œ”Ç›Ÿ1«?ÿh}à‡‹åÓ‡‡–í¤²‹^Öï!•`híÞæ —Ÿ&J ¸H‡ÍÀîQEQEtÔjÿïß-±´ ü":Jäãû7Fã?õ †¶~ÿ¨Õÿß¾þZ5sº â? i*Çïiú2ÿp¨j‘œö<çáÜÚÞ¿ñRµÓ.á:2øCŠÉimÌî÷¥ö¨¤rm0nAÙä’£wÂ^%‹âTÚ–§ \ÄC•ìfi,ÚA4R2˜î;%ÄÀE“·oÎX”Ç•üBøá¿‚~*ñõ¤z݇ƒõ ­I¹ÑaY–ÙžêK»ÈîdŒqÒ† â6Ã.Ùæþ[8• а §pG­~îÑMa—V''ÐüžÚkVA4O tYH¥w) 3ØŽA«Vº¥}"Çm§ÝÜHÉæªÅ1)ÇÌ9ûŠý×¢‰a¢ÓåzôÿƒµÿZs‚’u×[;?“³·ÜÏÁÙà’Úi!š6ŠXØ£ÆêC+‚=¦Wï-?Vï/À—%we¡ø=¼³¤ÏO"B»äeRB.à¹oA–Q“ÜÞ£¯ÞZ)ý[ÌžcðjŠý増ռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ)ý[Ì9Áª+÷–Š_VócðjŠý墫y‡1ø5E~òÑGռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ(ú·˜sƒTWï-}[Ì9Áª+÷–Š>­æÇàÕûËEVócðjŠý墫y‡1ø5E~òÑGռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ(ú·˜sƒTWï-}[Ì9Áª+÷–Š>­æÇàÕûËEVóc‚øÿ$#áÇý‹zoþ’Ç]íWjVV$³á/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒj÷o ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW‹‹øÏÎ~ 3gàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¨‡Â[.ÿu‡õÔ+ø»ðÚËâ÷ÃsÂ÷Z[jq*}¢ ¢uu‘®ãŒãØQVz'ŠèŸ³Î¡¥i7ºSøÅ¤Òµû½bûÅVé‘ Õ¥¾`òÙ™šÙbê–ÝÐšÖøð&/ƒ)«Í&°u½GR†ÂÑî·ÙÕmìí–ÞÝ6oo˜"’ÍžI<•ê”PEPEP^Mã/2øÓâ.—¯ÝxaѬuk=piPé‘$ÍwmÆ„Ý)ÈÁ—rÈü€+(â½fŠùç²ïäÔçð¯ŽdÑõeÓ¿±ôKöÒcœé¶m~÷²#£¹YÝšFMÄ&­ï ~Íø¾þ6]bIí£ÔubÓL6áZË袎åÚ]Çz‡å]£'ŠöŠ(¢Š(¢Š(¯ Ù}±µ¨#ñÝJçÇoãÍ>ñ¬7%Ée+ Çæ~õ@ ™ÝÐcŸuª÷:…­œÖ°Ü\÷r˜mã’@­4Ê ?y¶#¶8F= œ/?b MÃÚ=·ˆ'‚ÊÏHMSj¯í…ú_‡xòXέÎår1‘šé>$~Î:¿Äõ3jþ92ê6÷šªé×HŒ-ž›möy,ö+¯˜È„•™ŽsŒ©Æ+ÚôýB×V°¶¾±¹†òÊæ%š ›y‘ËUÕ‡ ¤AjuÍ:çQ—O‹Pµ–þ"ÂKT™L¨TFÍ•#hIô§÷†@"ðLJí|%á­'C±Ü,´ËHl ÞrÞ\hr}p¢´è¨^öÞ;È­x–îXÞXà.º!P쩺{n_Q@QTb×tÙŹQ´“íÉkÉÔù³G¿Ìyå×Ê“rŽG–Ùû§%ý´·ÓY%ÄOy i,¶êàÉ9`ŒËÔ(à×cc¡  ãzGÀÿi^&‹JñE¼:–«ã Áuu¢Ås¹”mÌnä°ÚyˆÑ¾‚¼çÕïõ­?JÝöÛëk=Ktßh™SÇ·ÌäýÅÞ»› Ü3ÔUÚùžçöÑŸ@ðöˆîRÒÏI]S2Ú‰þØ_­ùw%¼å#?>±ŒŒ×Kñ#öqÕþ'©›WñÉ—Q·¼ÕWN¸:DalôÛûo³Ég±]|ÆD$¬ÌsœeN1^çEfxcÃö¾ðÖ“¡ØîZe¤6Po9o.4¹>¸QZtT0^ÛÝKs3Å4–Ò§HÜ1‰Ê«…`>éÚèØ=˜„PÔQEsü3¨øÏÁ¶‡¤ëMáëëè„+©,&S –ð¡Ðå“rä0#vAȯ%ñG쬞%ð_†thµ3B»Ð Ô,m¦Ò4wŽÛì—¶ío:y/píæmÞaüÜrE{ܲ¤<²ºÇ)fw8 ROaYöþ(Ñ®ôy5h5{´¨Ã¾ŽåÇÞ˃´c¿4âñþÉ5§ŽômjÏXš &Âm"îM-íü×m¼–öŽ&Ü6¨I>eØw"ªx»öQ½ø†4ËxæMcVm8húÝðÒc€êVk~—±¢"8XZ5MÀ>W'9¯z½Ö,4Ù ]ß[Z¸‚K¢³L¨D1íó$Á?qw¦æè7 õf)Rx’HÝdÀet9 Bq@¢Š(¢Š(›øáGÆ~Õ´='Zo__D!]Ia2˜T°ß…‡,›—!²Ey¶³û;ßj? ´ß Xëº&­¥æ›!Ó|8¾L–—1ìuU–w–9:?˜³|Ìun•í´PÃû#é~9Ñu›mnát» t‹¹té ,÷m¼–ö²yۆѲL²ì;ŠŒª¾.ý”o~!2ãÅ^9“XÕ›N>·|4˜à:•šß¥ìhˆŽVSp•ÉÆNkèj(¢Š(¢Š(£ø{þ£Wÿ~ûùhÕâ ø—k¥h6>ð6¿ªBÚ>”ÒÏo¦Ü’¥„Q²cAû¤Ä=³áïú_ýûïå£Ví4ì&®|O=íäøsâuõΟ/ÿPÿfþÐüÅ»ñ??ò—ÿ‰¯·¨ªçacáÛÏ üxլ䶽ømây#‘Y:\`Œv½£á?‚õÿ~ÍVúgˆ4[ýQ$ËklðÈÊÓéø`¬# ŒŽàúW½T–÷3ZL²Á+Ã*ý׊°íÁs*¹ñ~…gq-½Æµ§A²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ã_ðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{Çü#½¢ÿáGwÿÈtÂ7ñgûÚ/þwü‡GÖ_`å<þÐKÿÀØÿøª?á8ðçýô¿ü ÿНxÿ„oâÏ÷´_ü(îÿùøFþ,ÿ{EÿÂŽïÿèúËì§Žø\ÓµŸˆ¶Ùú…­÷—oÿ³L²lί¥ã;IÆp*ñÈ×­×ìßú1«ëíKDø‡g.“6¸tÃ¥.¯§yßgÖî.þ?! ˆÞÙ¾m½Xc¯8ÁùÅßò5ë_õû7þŒjà¯.wÌ|Þu¤iüÿCgàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¢ =\»ýÖ×P¢Š*ÏD(¢Š(¢Š(¢Š(¢Š(¢Šç?áÔÿèpÖ¿ïÍÿ#Qÿ¶§ÿC†µÿ~lùº:+cïïæz¿Úuÿ–ø.Ÿÿ"sŸð‹jô8k_÷æÇÿ‘¨ÿ„[Sÿ¡ÃZÿ¿6?ü]{÷{ÿ0þÓ¯ü°ÿÁtÿùœÿ„[Sÿ¡ÃZÿ¿6?üX¾-–ÿF×þY®«yp.|A472ÈÊsö^¡ IjªÊ·E=Fk½¬ÛÏéú†³§ê·0¯tðÿev‘¶Ä]J³ÎÝÛK.ìn˜j4ÔÕþöÿ6sׯTÄG–j)yB|bŸËcæo‚Zþ ¾ðô6ºµéÕà¸ðÕµ†˜.\ÄÖ/¦éFðˆ³´…ŽIÜñò¬0\ïé>i·Ÿ<â뉮£›^°ñì /fH%]ÚµªyAÄnÆ×'Ia ±Ï’…=ãNÐìt›ÍVêÒ*}Rånîß{6Q p†Á8»†5ÀÀùsŒ’MúÔâ>eѼKâýSÃ÷^×,ü53è1Í«=¦­{{4F{pL¨-Õl Â8ŽBT6åâ"â kz-ô˪jwšv‘£ëñEw'ˆn/¬n<¡a.-åfÄèQ®Xù›Û|N aoO¨(  ±ðT~›àUÍì%µô½k{©]‰ ï¤ê3OµI”’ÄrÛPvŒ&³¨A7ü%ZÍÔºŒvº—‰F™š~ tõòm-Œl³].üøîNåe%Ê&~bºÑ@xëCoøD^ßÞk7Wßð‰øÓO²Ù«]©íïZÀBȾs‘÷+©3,@ȧË~·ÐÅ¢èºxÓîZòÀ[Çö{†¹k“,{F×2³3I‘ƒ¼’[9$ç5z¸Ëÿ„º¥}sw-÷‰’[‰W[jÆ HXÒä*/<*€à(Å<â©tKï­‡Š¯õ-xØëRGž¯Ó¦ê6ÒZ]A½“ÌŠE(ë¹H#*HÈ ú¿@6Gâ‹é.¬#ñ?‰¦Ñ|6×:Øîü=«]]°ºD²û5ºÜ¼×lYï™cÙ"¶ÅOœ¡Zмµÿ„gQø Ú~¡¨ÙßßxëÃÁó¨Îî-®K™œ„V/sTV?/•‰U~ƒ¢€<Zñ<ÞÔÕ5IÌòë~†Ú¼Äoq-°½b¤˜œqŒÖž½á¸døÉ£é‹+¦“«Zϯ^ب\×V/kL~¿i‰½¤?ígÒõ=6×YÓn´ûèêÊê'‚x$Y#`U”B û;Xìm ¶‹yŠXÓÌ‘¤l–bK:’Iï@u}¢YÙ~Ðú üpæïPðÞ¬.%v.Yc¸ÒÕd¨2ÇhÀ˳c,IÑø(ÇþÝœjsgow}mb{}Ž;É£µÇ·±cÛÚ]ÚÇ}i5´»ÄS#Fþ\`Œ2TóÔGjf™¦ÚèÚm®ŸcZÙZÄAc jªè€,ÑEQEQEQEQEQEÑü=ÿQ«ÿ¿}ü´jæö_*f‚X `÷sʸl›8È|ïãoŒ^/ðo…/üu¯öß;Tñ6•‡îí¡þÏ·]6 Uà• "Ü´¸·ï™”ùÓmUÌ~_E¬ÞüBÒ|C®øGH×õ¯Gck¥ê³ê ™¶!¹}B'Š×|QY²YÛ7ï“>[Üá‹ùA}þøBmbóPŸHûgÚüó%…ÝÌÓéá§VYäK'so’,’‡tŒ3ùÓn'Í“u ᎃáÝ;U´³›>§‘u}w¬^\ß4`0T[¹eiÑS|…8Ò;.Öf$„ø)ñŠßKˆµ{#ªÝùvÖVš]´£NvŠ Ó`fžbÙ2ɸ½øà»÷&M*dI%¸–æ(5 ˜b¾ÜKq,wH’¹ˆË<ì!˜<`M*… ì ñ3ã£ø_ñÄ^ðå”zv—k¬[Ùkê ][ÜX™âšymZÝ“Ë[Må…’RçÈ‘«ÈÐèØ|]ñ5׌õŸ Øh6Wþ)ŠéÝ­µ dçÛà †•,ëñÙ™[÷º”aCÄKbV/ÙêµOÞ ÖçÕžûJšæR+˜®,ŸP¹û"„xî$†ßÌò –E–`ÓD©!ó¥%³#–.~øJåýŸS·»yVgÔ­5»è/…¼ä5Ôs,Ì­­¶õ/µÚv ãuqžý¥eñb.¯eá9¡ð€¿Ò,_Sº¾E¹fÔíìdµÙnªÙd}B5˜4ˆª€4m3=¾¹K…ž³Ó®l-´hm,./ìµ7µ¶gŠ%¸´ËjȪ@EŒY[‹„Ä|©Ëg« ¼Lý¡ükà„_¢këx´Ý?ÃRZxOP[T3iº¥¯„,5D 'YUïgV‘ÆlݤóâDö ƒÂÞøw¨|›Á¾,ðf·kâ]3OÙËáíNæ+¹×N´€:¼q0FD¶AŒ©G„0ÃÄ_þÖWÞðö»â™¼ouá8&×ôÝ*tÖo®õ &ÞþYÒ{so²éWŠ’¤Ó70Þâ3Æ¿µv­à+™t]WáýÄ^0¹šÅ´Í"ÚêâýZÞî=BXÓYZO,sªi7¢Híáº[ÉÄÎŒòEsZðgÂ?Üë’j>ñuݾ³ ä7:{é:ÿØPÝÇ$wSAjɶžTšpó‰+}¢r_2È[[ŶŸ ¼mªÞjš¦ƒâïí{˜m-Χc¢ë¶Wp­³\˜LA< íÚ‰•'‘²´Þü-ñµÇÄ_išýÞ…¨xnîçÍI´ÝNÞh%ã•âfTš8¥òœ¡xÚHãvÑš8É(:ºóo xÇ Эt}Gñ5¥…¾âªÞÕ¥wwbòK$yewgw‘Ë;»³331'[þÖ‡ÿ>>&ÿÂWTÿäj»ñþ@¿öÒÿô¾ üõñwüz×ý~Íÿ£¾äñWÄ=+]²Óìm­5ئ—WÓvµç‡ïíb½€ÒK ¢ð8É8’|7âïùõ¯úý›ÿF5cS¡óYßÃOçú~êšG‡¼Kâ«â®n4ëX%ŸûJÑwBf•Âmû¶G=ºuïá+Ò?燈ðiiÿÈ5ä~ÿ‘³Yÿ¯?ýs]u~ ÄÜS›åÙµl.·,#Ëe˼bÞ®-îÏç>$ãLû*Í*àðxŽZqå²äƒµãõqovúwü%zGüðñþ -?ùøJôùáâüZò r4WÌ®ÙÿýäÿäOšÿˆ‹Åôÿ’Sÿä»þ½#þxx‡ÿ–ŸüƒGü%zGüðñþ -?ù¹(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ ußð•éóÃÄ?ø4´ÿä?á+Ò?燈ðiiÿÈ5ÈÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿù®ÿ„¯Hÿž!ÿÁ¥§ÿ Ñÿ ^‘ÿ<2iWVÖWç\÷–Íqò3º5’2Ù0H<ã†ðg‹\‡%Z2÷þ´ñ7³•W^Ê:ë}ÒÓÝ×}-¿Bÿ×>1öR¬ñ6ŒUõ%¥ÒÓÝ×ukoÓcÝô߈Úf‘fðZØëQ¼’M$“Rؼ‚An œÙí}–"0ë’sRÿÂÑ´ÿŸ}sÿVŸü…^©üGŠÇ_½Òmt-_WžÌ ™ìR«#¨dL<ªüî_Ÿo–»¾g\69+ã\—ÿF±s¥]Yê‘xf?]†) )Ùgž¥ÕšÝЦàÄ:Tï)¬8—Š'u_M>Í?µ¶œ·×õ]ѵ>.ã:U#OwìÒ¿½¶œ·×Óªî¦ÿáhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*ðëω66ZÕ̓Ø_˜­u4Ë‹õHÌÏ2BЃóï!ÄkœóapÆM⇈õK;k[ÈÖþÎ]BÒædUŠâÞ%Þ¸bpLÈF@8äã+œq2?¶Ò×øiö¿òöÖÛÛ]ŽgÆÜb¡í!òÚ÷䥵¯ü»Û[omv=·þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯'ñ'ˆmü/¥‹ë¨å–#qoj åæ™!LGñH¹öÎ3Ò³,â¹H¦´»€-Äw2?–VÒæeŒÇ ›\üÇ͈ew.]~nk8qwT4+݆_Ýó_zîeOŽøº¬yቺ×ìSéoîy¯›Kv{Oü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^oñ:ÄOrš–›©è1Ec>§ÚœH‚khJ dUWg]¾bedTo˜qÖ¦ðç‹îõßjúl¶iöÖš}•ÒEtn7Í%ʶì3.ݰÆF9¸<Œ eÅ\KÊr¯d•þ}ÒÓÝ×W¯n¦Òã^0„%Rx›(«ü»¥§»­›³¶Û=Ooÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«ÀŸÅšÅ‡Ä; êçH¸ŠüÊɧY«ý²ÒÝQÊ\ÊåðQ™`F¸g3m&²ußx¯ÂRO¦š=É–Ð] m!•aÓíÂÍ;3æTU™åÜY[y8FÐân$œ£âUä“^ì5»kù:Yùv½Õú!Æ]Rq„qŠòI¯rž·m'K;ôìÝÕþ“ÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«æ[¿ŠzÅ¿Ãx‚Â7ÄSé&ãÈÔì˜Ç§ÝG¸˜Î÷mŠwDUY‰t#* +Ôø»[Ö£×´­@“O·¿¼µº¾iµhü¸(,× ógÁéJ\Mı’Œ±)^ÿfe&î¹n´}UúZâ—ñ|&¡øoÅZn6¥&¯.–>Ë F iu,Jy’DÄ›WŸ¾È[ ¸‹ß£))§_ëóϪ,VöG³¼û;ðócËón°N²ÇKýfâ~^ooÕÇ᧺Ww÷t²î/õÃŒy9þ³öœ~Z8«»ûº$µ»±ïßð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòx-§Å½èÛ1·½‚ ëT»Ón%D ¨FòEò°äƒæ\@¿8LùŠFFH/þ*YÙÍ ¤zN§yª½Ä–ϦÃä,Ñ2$nÛ™åXÏË,L¹f0'ýgâ‹òû_ü–ŸMþÏN½žRq›—/·}~Å.›ýž{=™ï_ð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòy¥ÚßÙ[Ü¢KMÈxÌr(#8e` žyjzá|kÄ Ùâ?òHò'šüC∻úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÑ?áhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*óº(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ z'ü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^wEë¶ÿAù$?ùÿˆ‹Åôÿ’SÿäDÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«Îè£ývÏÿè#ÿ$‡ÿ"ñx£þ‚ÿòJüèŸð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòyÝ®ÙÿýäÿäCþ"/Ð_þIOÿ=þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯;¢õÛ?ÿ ü’üˆÄEâú ÿÉ)ÿò¢ÂÑ´ÿŸ}sÿVŸü…Gü-Où÷×?ðeiÿÈUçtQþ»gÿôÿ’Cÿ‘øˆ¼QÿAù%?þ@ôOøZ6Ÿóï®àÊÓÿ¨ÿ…£iÿ>úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÑ?áhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*óº(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ z'ü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^wEë¶ÿAù$?ùÿˆ‹Åôÿ’SÿäDÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«Îè£ývÏÿè#ÿ$‡ÿ"ñx£þ‚ÿòJüèŸð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòyÝ®ÙÿýäÿäCþ"/Ð_þIOÿ=þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯;¢õÛ?ÿ ü’üˆÄEâú ÿÉ)ÿò¢ÂÑ´ÿŸ}sÿVŸü…Gü-Où÷×?ðeiÿÈUçtQþ»gÿôÿ’Cÿ‘øˆ¼QÿAù%?þ@ôOøZ6Ÿóï®àÊÓÿ¨ÿ…£iÿ>úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÒ-~*XÁ{gq%†³r-®"¹X¥Ôí‚3Fêêm˜8ÊŒàŠñÿXX¿Šõ¦{Íu\ÞÎJÃuh1¸PÖŒ@ôÉ'Ôžµ±Xþ.ÿ‘¯Zÿ¯Ù¿ôcWéÜæÇÖ>½SŸ“’ÚEZü×Ù.Èý#ƒø“5ÏcˆþÑ«í999}Ø+_šûEoe¹KÂ62Mâ}f]Ðó´U{‰Òbà¥ÈÉÇLŒõ×ÿgùûÓ¿ðaÿ\=éf|—渹ã+ÎjRµìãm]bÞ˹¾gÂvm‹ž2¼æ¥+^Î)h’ëö]Îàiļh.ôâò:Ä‹ý¡YÙ‚ªŸ’IäGöqÿŸ½;ÿñuÃÃÿ!ŸÿØoMÿÒÈh¯3þ!îUÿ?*}ñÿä=ø{”¨©{J~Ô|¿¸wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôRÿˆ{•ÏÊŸ|ù?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]q’ü!´¾ðU÷‡5 ý*þÖëSŸS"k›sg¿kÅã2ê•H'æôÎTVô¸.£ogZ¢³Oxî¯gðt»:hðF]‡·²«UY©|PÞ7³ø:]³øDú7†'Òô}CÂÚcMzolì–žP¾[[¬ªXaTîó7åGÍ´m©üð¦OêèkÚ}ç›§Çe4mu€cžy“Êý騋ö™!Ý…XÆï”éŸ`§ S•j––¯à×çÉsª|%ƒ©Nt§Z£SwzÓÕù¿grm{á•þ¹â«=I¼A£Eeoq ÊÆ ·Úã1àùq܉†#|ÊÈä‡p1‹iðí|#¬èGÄšs¥ÿ…àðÄsùÐp­Ò¤¤yß3m¹\”#°º”UGƒ°p‚§ÕVþO²î¿åß¿©pá\-:j”+TQ\¿óï컯ùwß_>·&¿øTo·?âw§'öž½§ëñõòþÍö?Ý­çwØþ÷ó:¼óšÃïèWpI§É§t/Ýiz2jÖ™,í…XGpw€-Ô3™pÜÕ»E:|„9IµæãÛ—ù?—OB©p¦ œ7Rr›‡ò¨ÿ"û*Þžm›þ,ðañF—Ÿöžmå_Ù_oûlŸ³ÝE>Üyƒïy[sÛvpqƒÎêt«ß?ˆóá³}-äÒÜÜ¥•ÅØx‘V)ÉqtqR¤ä>ŠÂ`pñå¥Z¢Zõ‡[_ìy/¸æ¡ÁØ,,\(Öª“¿XuµþÇ^U÷Ö_¢_´E¯Øß[Üiz=ÁûT =ÂOån–I ÇtŸº98/À^wt¾ð%î—â-KYÔ5í/Qº½³µ³>\ðB`yØõÍœùç>àž„Ë¢®¯`«EÆ¥j?8w¿òiª[v4­ÂXLD\*Ö¨ÓÓz}ÓÿŸzj•í½‘¢Þ¿¼ñŽ¡¨ø‹L¼¶Ó¯%¼±…f¶ŽXËÅ$[A.e`U<)bÄdà§ÂŸ_Zê0k>/ðåû\Ë Ò\Ao2¬ÐΓ@›ÇV‰vm1…\†'p%‹]¢ˆð^ Yéoù÷¥Õ¿w¦ºé»Ü!Â8*vå«5k[øzY¶­û½5wvÝï{!føQsà¯h÷¾ ÒŸQñ4wæöÞhc†'’ÙmÃG ˆQIÉ'qÈÏ-ð.§«ê:~§£x‡HÒ5K8gµ\ÉÒ43yeÆÁ:a·Eœ|¼‚ gQSþ¤ày”ý­M/ü–Õ$ô䵬’¶Äÿ©øu?kRêÿóîÚ¥§³µ¬’µ¬º¯¾G'4Ï Yjº}¤zgØM¬Ò^Á& ¤±IåóàL*pNªþøTt vËQþÛÓ§û7öÇî¾Õîû}ôw]|Ó/ËÙÓæÎ~\b¡¢…Á8mRͶõ†íYýŽ©‰p~ AÓöÕ,ÛoXo$âÝýõM¯Çs.ãö´Ô<=á]#PÕô«û]E]$Ç4ÖíÓ,¶R¬Ž†R6î±\Æs¸HFáŽe?¤²ÐLÒµéðKq,óYÿgY}‰·¢ Ûs#UNÈIÜÙÈÚýÑþ¨ál£íêY6íîZíÝ»{>ïú±Õþ¬aì£íêY6ízm]¶Û·³µîÿ«#¥ðï†n´M. õ› B;hㆠ¥¾€Lȱ"“+y¤;–Å€Q†ŽŸöqÿŸ½;ÿñuÃÑ^lü?Êç')T©wçþ@ò'ÀYUI9Ê¥K¿8òqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×EGüCÜ«þ~TûãÿÈÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;…Ó‹»"ÝéÌê†R£Pƒ!*–ûýtõ`;Š?³üýéßø0ƒÿ‹®NÿÝïý.?ô²ÆŠñr¯ùùSïÿ T¼=ÊROÚT×ûÑîÿ¸wÙÇþ~ôïüAÿÅ×7≣¸ñ6¯,N²Ä÷“2:«ä‚qYtWÓäœ=„È}§Õe'Ïkó4ö½­d»ŸI’äL‰TXYIóÚüÍ?†öµ¢»³ÿÙtango-9.2.5a/doc/src/atk/img/prog_guide_exple3.jpg0000644023471100065110000032407313034745263016743 00000000000000ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀWó"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ô‰#Öì.<3o¥ÜÏm=í¥…º[ý­àŒK4ÞP,T0Xdí'¥sÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ•¹ñ̾%ð ²”f“E%OQþšœW1,š•¤Û^ëZÏögÚg–SËŒîòÖ2Ç/"ÏAÓ5È~x›QVWù¾ËÏÌ·ý»âïúôïüêü‰Igâ éKaâ];lŸlšg…ôAåkû¢äbÔ–Á;K0•ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍ Ïx¦ÂÒ{™üS§G(ÒHÿÚÚ‰Ú dœ LônïSñ¥…ÜÖÓø“NIávŽEþØ¿8`pFE¦:Šã¼_ÿ"ž·ÿ^3ÿè¶®ßW°þÕøƒ{eæy_iÕøÎÝÒ‘œwëN报ãtµ¿wþeOíßÐϧàßPÿäJK ÿ[i7“Ûx—N7—:¼Ïu Ô/dZY*.ÿ²îrÈr$¾“«Épt{É/í`qNñ¢}ªÇn×p@ r9ÈÇ;>†;‹Ûh¥E–'ñ3+£Œ«m§‚î(EÂoÞ‹_‹î¼Çÿnø»þ†};ÿú‡ÿ"Pž ña¹†â['yw•ŽVø»åp»­•r7#, ãæøIï?çŽÿ‚Ûoþ7\ï‡õ[g^Ón®Œfcw«Gû¨R% –—È *@éÏSÉ&‚c5'k~æyWÄÏŠ>3°ñ¾¥¯‹µÛhËÛZ”Ê«˜œØêMÌ|Wÿ‘ÿTÿ¶_ú)(«G­Iþî>ˆú³â'ˆtëŸxÄ_ZEfÑD–Bu3FÆî7ÚS9i Ó¡¥p¿ð—è?ôÓ¿ð.?ñ¯Wñ¿ˆ5;À±Zß]ØÃpú8–gdVxŠêÀœ©*sÔpkÔ¾"|Pðß­;M½ñ-ìÖpêWñivkme=Ü·R1Ä‘ÀŽå˜#cŽHÇRy‘že+óZßä•¿á/Ðè7§à\ãRÃâ=&ÏÃzŸªYAæ¥ì±ù—»ÐêWxa“È>µô_ˆ~>ø7Â^¸ñ¹6µ¢è¶ö«y5æ¡áÝF‰ä[(möà‰ Œ¸ŒüåH}»êôJ¯gæw,š)5Ï¿—üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûR¹Ûïˆ:™ã7Á÷—ÿdñ§k-å´ðȉv‘ŸÞ¥+弈fX¸S¸¨^hö~dbGþ~~ðO“á/Ðè7§à\ãGü%úýôïü ükêâÿ…¼Gâûï i7wº¦£au%ÜöZ]ÜÖV÷ ‘á’ñb6é"©¡Ä)¸®ÎgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üáø§E¸ðƯZ½„²½œÊˆ—(Y‰B<šë|iâ߯:ìRêöJ—ó«£Ü e"Fž }wEÏÌ¿ìhòòóþðOŠÿá/Ðè7§à\ãZñ–“¢ZEªI¨ÙÄ3Mk”U›e­![8ê0qœWØ”QìíÔ#“¨ÞÓßËÎýÏ…?á&ÿ©³Ã¿÷ëÿº*ï„u=2ßVÒ ]jÂúTmRêi •B¨k×fÛ¹¶¨ßŒ“_oVG‹¦’ߺı;E*YÊÈèpÊB=ÎÚÜ™eJ”\ùö×d~eüL¼‚ÿÆú”ö³Çsù{e‰Ã+b$qÔ+¬ø™ñGÆv7Ô µñv»my{b‹R™Us€I¢¥R·$mÙJ|Ds/Š>»)FitRTõéÑñVÿl k~1Ó¾[hvú›Ímñ Iº¸¼Ò­„òØ@¢`×DtUŒ²Ò)@q¸pi|H’Gñ'€¤XÀ”É¢°Ø»í©Á8ãòü+ß<ý[þ|¬¿ð1ÿøÕ]=ŽìŸøRõ_’>ý±>xÛTño‹“NÓüMãÿ,ìcÕ¿³²]\Á9‡ýˆÈ±ÛØ›ˆ<±ÑѾx²Úú÷V²Ö¬µÔø¥&±iªÙx^k‹©´qØ’kMqØ|Äm†ù€¢6'Ënùú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕj{ÆxGíOáÍZ×þÿÄ éwº®»à~+‰­´»wº½¸ÒîqôðVI3–ÚUQˆu=}›ÏÕ¿çÊËÿÿQçêßóåeÿÿƨàøRôý'á¥i£êoñ[°ñ®½­jv)-¹¶Õµ;ýÌä"YÊO‘?v«$mŽ…Ž6“û<ë¾)øCâë++ kD¹ÿ…qaæ•eà‰ô›[½JÖá.£ŽA,âKëòa–#øãïŠ~ÔµÏø·GÒ<[âäñÝüšÁ–â-ëNŸQT²12!‰e¶þÎe“nB.ÐáB'èEgyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@5‹ãOùõ¿úò›ÿ@5gÏÕ¿çÊËÿÿVW‹%Ô[ºȞÖÖ8¾Å>æŽå‡îÛ 1ŒþtžÆàÏÑþGæÿÅùõOûeÿ¢’Š>+ÿÈÿªÛ/ý”W:Øùš_â>»øˆæ_|?vRŒÒ褩ê?Ó£â¹ïÛOâoÄß øÿàÏ„>ø’ßÚ—59ô¦–îÖ¡iZ[H g2E!UV‰(3‚x8ºˆŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´ÚÒžÇ~Oü)z¯Éü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~×Ïÿ kiþ4øLñ—ƒ~|@Ö|7©y¿d½ó´8<Ï.W‰þIu5q‡Ç*3ŒŽ5©ï/Ã,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×Ö×ßµo†ü5ñ—à |a øƒÀº×‰ì’çE¿×c¶þοœ„ÝeÄÊ¿iF,¡À,+0–/âø(_ï Éñ~Hô_júoÂÉ­­~ÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯¥ôßÛcA{Ÿ†2kžñÇ…t/ˆó[Ûx{Ä:•­Œö3KqÉm­kw3ÂÒ‡P‹")å‰ÂÇ#'µ|Bñ­Ã_x—ÅúœW麙sªÝEhªÓÚiúÄ~,ðÖ˜š­åäÐÄ,d‰–Ù‚ÆâRå±w0>Wç¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëìÈ?iOÂ_ñ{A½†™ÿ ¶ÊÓPñ£qnßȸ´{°ðˆÙä}‘FÛ@s†¬Ÿ„µŸ„>1üGÔ<¦i¾ ÒuXô[é³k}kI˜¨ŠúÑÕÛ12.$¸/´ xåXÀ>Iÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh Éï~ý´go„úïÄ/|\ð}î‹£ùhƒK³ŠK†ógŽد§"œ4ªNXpSÁó]OÅ¿¶×‡5ßé¾!×-ü<¾'×m<;c{w,"îåŠÆAŽ«ÃÁNž§þ€ÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•ÏèrÒlÒ1M7Øçá–nßú,ÿÿðùW\ÿÄ/ÿ¶ÿÃ_x—ÅúŸÆϦèeΫu¥¬m3ÅM+ªÓT*„HÆHë_¨5å_µüšÇÆOû5Ÿý!š™™ù¯|bý³<3ð¾/ˆº–¯öoËkmzš—Ù´gÌ7-åª>c*q·#w `ãê¯øeŸÛ·þ‹?Ãÿü_þU×ñãþQ{¦Ø­áÏýe_ª”“¹¤â¢ÕÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢™™ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúC_7|Bý¹<#áíVãIðf‘¨üMÕlæhoF„ñGijÈ̲#]LË•X&b [lŠÀc&¸qxì6Ó5æy¸ìË –Sö¸ÊŠó>oÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«®îçö°øã¬ÛKlšW€ü,ì‡n¡¼Õ˜` }œÎíåØ ¸(weihÿ´ÇŸùÓ\ë~ ñ~q¶ÆóDŸMÏPvÏÄ›:äæ'ÎÐÜ–"øß%ŒÔGwåu÷«­}lºØøIxÃÑš§*®ïÊëÊí6µõ²êÒ9øeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺö ~Ý:¶§Ä?†÷¶è¨Ï&«àËí[uËaÛ²Ås»±Ù€e[ òþœðG|7ñ/öÚÿ…5Ý?ÄZ-ÆDwÚmÂÏ#ªîRpáSÈ< }65ÁæQæÂÔRý<½}?&±Ë3¼¿7‡> ª—{=Ÿn×]m~û4~~Ã,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ëáù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«®ÄmO øý˜5Q,Vq|£)‹nNœíÀœcïÚ¿VëæoŠ¿òtöÿö&/þ—=&TUä“>Dÿ…_ûkÿÑ^ðgþEÿÊê?áWþÚÿôW¼ÿ€‘òº¾Ì¢¢ìëöQ>,ðÿßÛSÄž?[|]ðrjI¦TË-œB(J"Û‘§»qÆ;ö®ëþgöíÿ¢Ïðÿÿ×ÿ•uôG¯ù:{ûÿK’¾™«G,•¤Ò?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†Šd›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~Ox¦Ú‹övøûð/þ$xÄ/޼Mm§½¶…g nn­c$f³…“rÜ€ ýîTŸÓÿøWÚüøäi?øªø‹þ ;ÿ'OûÿØæßú]¥WßôÎÿ¾Ð?çÃÿ#IÿÅW†|O·ŽÓHñT.È¢†ésœÍ}+_7|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆúïâ#™|QðýÙJ3K¢’§¨ÿNŠãÿlù:ÙþÇ4ÿÒí6»ˆŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´ÚÒžÇ~Oü)z¯É¨uù«û|øíâ¿Ù;ÀÚ¯ƒh¿øA<7qöï²xþ{ Gì»oîÿÒ%pï¹Õß‘Æý£€+ôª¼«þ;à‡ý¿‡ÿøKØÿñªÔ÷š¿à¨ÚŽ—â À|+¤ÂCñóRÖ »ð‚éw-©¢¢6ù¯’DÇ—ò1Ñ83gý”ùÖÇÄž—þûñ7ÁúF‹qáŸxOS´±ñV•©yK|uÕ­Y®%UTp¬”žj_³4Y'{~¤Úü'ð=–»¢kvþ ðý¾µ¡Ù.›¥j1ip-ÆŸjªÈ¶ðHtQ‘Ô" ; `š«®|øuâ}WXÔõŸø_VÔµ˜c¶Ôï/´ki¦¾‰6HçvBdUh!!X Q‘÷F>Jðßì“®~Õß²gÀï xÿÇ:}¿€lô]#W†ÃÃzÚjŸ.–ÑC^Mw5ý“¾ üvÿ…Yðo^ÿ†‹ÿŠ3ûF¾ÿ„Kþ{øðò!°ý¯™þ«÷^v73^ká ê>*ÿ‚¾üq´Ó2Ø™¬ÿé ÕF'À?åºgýŠÞÿѶUú©_•?åºgýŠÞÿѶUú©Rªî½ ý¸~)k_ÿe?ˆ~/ðì­o­ÙYÅ ¥Â ´<ñ[ù«î‚Rã=ÔW›ü_ý–¼ ð‹öcñ?‰<9jtïˆ>ðýÖ·mã¨%a«ÜßA Nežç;æ:a£²aÈ Œ úo‴_Š^×<%â+O¶èšÍ£ÙÝä£ eOð°à‚9Ú¼+Wý”¼gâÿ‡6_ üQñv}WáÔ µÌÚ ¶Öu8ض¹¾óÙJáUY£‚7p9<œÑ‰â?^µë´ð¯ÇoÙëáfûg~˺%‡ÃOÙhºÇü%?ÚZu¾ƒk½÷•§FðùшÂɱ‰eÜÒr0kªý´|'¡øBýš4O èÚ‡ô[_ŒÞû>¥Ú¥µ¼;šéÛdh®Y™Ž%‰êkÚþ"| ÿ„÷ã·Â?ˆÿÛaÿ„û_þ%Ÿdó>ßöëUƒýnñålÛ»î¶ìãåëGÇßð¼á\Äïûþÿé¾.ÿO´}¯ìžgú?ßM›üÏ¿óctæ€Xsm¸zúÂ>Ó¼áMÚD&ßIÑì Óìá,X¤1F±Æ¹=pªhãoØëÇúï…u_Ú"ÓLøkâÛ¿ÆJ×Ú%Ε1±hŒ‹»Øp Bà 19çÿ^M©Á?ÿlÛ»‹ .⌲ÉavÑ´ÖÌÚ––LncwBÊN GeÈ8b0OèWÀ/ð£¿ácÿÄïûoþê^.ÿO³ý“í~_ú?ß}û<¿¿òç?tb¸Íö4ÑÃ>ñµ.·£üKñV¥âižÞØ[I§›¦‰Ò4%Ü;Dð« 8Êàïügöø˜_ø–éÒÒ¹Oø*?ÂÿÃ'|Mñ·ü!¾ÿ„Ïþ%ŸñQÿeÁý£ÿöÿÇÆÏ3ýWîþ÷Ýùzq^âكƿ<-¢x;âGÅoø*ÆêÞâòÏOðçØou¬‘Gwpn¥R»‘ yQF[«ºý¨þÿÃJ| ñ7Ãí¿øG?¶¾Ëÿ?²}«Éòn¢ŸýVôÝŸ+oÞÝžq‚æÿµ4Zìû*üPñ‡ÂŸh × ¼>~¤ÁfÅä¸HV b:îÈ>¦®ÜþÃ?n>ÿbXDÚwÚÙdOˆð“&º/€ífì°•òãqMáH%@öÑ~)x\ðˆ­~Ù¢k6’YÝÂÖ(ãSÙ‡ÄÚ¼fÙÏâT¿bø}ñªY¼‹»µÐ ~[0ù }ö†;Ã*Û«œç9æ€<ïö–¼Õ<ûZþÈ2&Ÿ©øçV²·ñDOŸöXnïßû2y,0©äÈAu.NÖøã-_Å¿·gì©ý«àOx+ìÿð•ùÛ³éÒý§v–™òþÇwq»Fwíûëß6=ÛÅÿ³Å¯ˆ¾1|ñµŽªºE—ÃXuKx4d´óÜwv‰lª%ó–#Ý}Ý>^µkâ'À¿øO~;|#øý·öø@?µÿâYöO3íÿnµX?ÖïVÍ»¾ënÎ>^´êµðÏÁ¯ xÃÂ?ðR[¥ñ׋á/ñ.£ðõ ©àƒìöv…µˆÐ[ÚÅ’RX—ïÌÅÙ¹l¹«Ê¿áEÿÆSÿÂåþÛÿ™3þìO²Ó÷Ú¾Ñçoÿ€lÙﻵz­Q@Q@Q@Q@Q@)þÝß›Fÿ…kðî;—Š/êW«¨Û¦@¼Óílä’X…ÿVÒÉk½w ê¤þ ý¤|.•Vÿð—Íu£k(«µnÒ; îá™Â‘¾hšÉcßvÈç@ùò<»þÍCYù<9ámNû< Íb6Ò­QÇ%\L¿hû¸Ã$¤°†¯Að_Âw–ÿµÁo\Õ¿µõ„ÕõX¼‹amkm躃H±G–œÃ c$’§Ë°1ZúÞ¥S œáÜçÈÛµº»§£Kn—æ·t›V>ç‚(ÕÁñU*r7+[y;§£Keµù­¦©6¬~•QEýJi…Q@Q@|ÍñWþNžßþÄÅÿÒ篦kæoŠ¿òtöÿö&/þ—='±pø‘£EVg g|*ÿ“§¸ÿ±1¿ô¹+ó‡öø¶Õþ-ÿÁDõÿjº–³«ø~Çìía£Å©lŠÚE¼ó‹Q(h¢y=ÄaUØÌ¹Þ¿£ß ¿äéî?ìLoý.Jüåý­ì´ઞ+ƒû3ûc?d±­Ç‘#mÐámÑIÆÉW£;“©óÇ÷ׇ1©*8õ`ìã 4ûY?5ù¯T|ÎwZX|*´œa6Ÿf¢Ý÷_šõ[œ,²ƒ§ò>É©k—ßh¸’K-³Ãö„+¿Ì´_2!ä^ôæ9x%¿Õþ÷ìÜoÅÏÙßÂ~øu¨kúvµ©É2Ü+iÓ]„ò/c3yojɱ ¸I;ÑòH…ÈPD©Ôòÿ¨ÏöŸýºmù?÷ÇÙ5[+þ™îò埗þ‡æŸ´…ö> øŠí<ÿi}>ØÖû#Ö|»˜—l±ü¿gÔ!òöÈ6éüŸ»ÙiøÞ[æUqÔ)N´šsŠkç¯O[èºé?cüõ”qo_1ÃÑ©ˆ“RœS]Ó•šÛÖú/µ¤lÖôËþ ÃâÍsÇ?±ÃÍoĚΡâ jëûG펩t÷7mÔnQwÈä³aUTdð‚¾•¯•à—òb ¿î'ÿ§Kºúª¿w?¦€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ€ ù»âÇüxø¿ýË¿ý𾑝›¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}wñ̾(ø~쥥ÑISÔ§GÅqÿ¶ü?ì‰ÿcšév›]‡ÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmiOc¿'þ½WäÔ:(¢µ=ࢊ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(å_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZõ_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZ—º6‡Ã#ïúò¯ÚÇþMcã'ý‰šÏþÍ^«^UûXÿɬ|dÿ±3YÿÒªŒO€><Ê/tÏû¼9ÿ£l«õR¿*þ<Ê/tÏû¼9ÿ£l«õR¥UÝzÉeXbyíD˜úT´Íb=Vk•‰Ž"r~ösÎ;t¯6¾i‚ÃbèàjÕJ­[òG«²rnÝIê쯥îÒ!BR‹’Z#BŠ«e©Ûj;þÏ'™³¾R1žGµUÿ„—MÿŸŸüq¿Â¸êqMFrFŠpÒ•Âî&CxÊý¥i_üñßÃoø7á·ü,¯xßûKì–_Û±i^_ØâŠWùåå$sË.<¼ –¾hý›ÿcƒ´W‹¿h_|Að‡ü$íŸÅXÅqý§ym²ÜIªm†dSóÉ!É箫ÓþÍß ?gÏÛ³ödÿ…aáßìíøIÿ´Ó®î|ß+Ký×ü|HûqæÉ÷qÜ眱ØXU§BUb§>e̯'‹•^ï—í[n¤rÊÍÛcéïÙ[ö„Õ?hŸ øºÿ[ðoü š×†|Mwá‹í#ûQu³Û¤-!ó’4S†”®pù2ƒÇµ×ä7…<§x—âÇ›«»^ân½]?Z¼³prRQIäüÄg Î®¿þ>‰ÿ?Þ&ÿ«TÿäŠüó2ãÌ6[Œ©ƒ 7k¦Æ30™F>®¦RtÝ®š³>Œý´ÿä±|+ÿ°ˆô£G¯%®7þV—ÏmªøšÖåyŠøHïæòß³yrÌñ¾×FSÑ”Œƒ¥à-~ãÄþÓ/ï’(µCƒP†DpÞDÆ+˜×$ä$É"‚ nA`A?Žñe óó Qq^ìZ{§go¾Ìü ‹3z|G–kB.1÷bÓÝ;;j·NÏÐè(¬ÍÄú7„ìÒï[Õ¬tkGD³ê)lä3 “céFâ}Å–ow¢jÖ:Í¢Hbiôû”ž5p*Y áǸõ¯–öU9=¯+åïm>óâ½…_gí¹'{;}ûu©ðÏþN+à×ý‡¯ôÇ©Ö]pÞ)´OøÛNðì*ØéöªÞËi+[ÜE+±†Ô$ÊC u»ŒD7r’{&%`qôñrWTýçè—ë²ói÷c]šQÇJ7&äúh—7d»¶—SõFŠüµÿ…O¢Ï÷‰¿ðªÕ?ù"øTú'üÿx›ÿ ­Sÿ’+öø‰8Oú—Þß?â.àèz>Êý¥i_üñßÃoø7á·ü,¯xßûKì–_Û±i^_ØâŠWùåå$sË.<¼ –µeoÚTý¢|+âëýoÁ¿ð‚k^ñ5߆/´íEÔvÏn´‡ÎHÑNR¸]ÃäÈb ü&ð…ÿnÏÙïìsêsyÿðïþÑÕn¯q·K|móä}Nvã{ŸíÛÐ;Ë!M³Êê2СÈùzàœû§ìñÿ'Ùû\ÿÜ£ÿ¦¹+ÛÂâðøê1Äa*F¥9m(µ$ìììÕÓ³Mzžü¢âí%fjüký©¼wào¶¿ ~üÿ…›­Iá”ñ<ÒÂO“äÀn¤¶a‰¢*Øeù>gÝ“^MðÇã§ü4§Œ|!ñûþÏí¯\ijíjò|bâõ»v|­ßtcv9ÆOyg}¡ÿH2@þbƒ[IÁÿmûýkÁÿ`¯Ø+àOÆŸÙ;ÀÞ2ñ—¿¶|I©}»íw¿Ú÷ðyž]ýÄIòE: ÂFƒ…ÆO$šªŠ8ºQ¯‡šœ%ª”Zi¯&´cÖÕj¨¨®wþqû1Ñ2ÿÊþ©ÿÉ4î?f/ú&_ù_Õ?ù&¶å6öÞF¯ù:{ûÿK’¿#>;|KI?o߉%ñ«jÚiþ&Õ,_hò$[y¶¶Â#äKqB#”ïDf‘d¬_ðëÙ‹þ‰—þWõOþI¯œàœ¿ü'ÇßÚ³Ãm£gEð牡Óô»oµMþ]jQªnß¹ð± Ëxë’kJ¥l-JTÒnI­dã¾ÞJM;m£×ïÉÆünøÝáü:ñV‘¤x«íÚ­ßÙCÈ4é£YfŒ¬’)DXnâX€yÙ"}Ķý³ÿ†xø}ÿBÿþNÜñÊ?áž>пÿ“·ür¿:Ãðµ|5XV…8Þ-5zÚhÓÛêûiùZܰåü“ ÁxœzxŠtbÜ’½wkÅÅ«¯ªíîì­m-nJ|Ÿ“Ÿ°—í¿ñ/á7<1áY'ðxøY¦øÏKЯ¯uؤŠóOƒS–æi9RDˆD‚ÖîBón*Ò/ÞA„ú«öçÿ‚—ÂŽÿ„'þÖ»ðÿâö§Û¿µÓ?´¾ÉåýŸÉÿ[”Ù¿Ì—ïç;8Æ ~zþÈ:MŽ¿¥iZf§eo¨é·¿< mugwË ñ:ë ñº0!•”T‚$ú+þ )ðŸÀÿ ÿáPÂàßøKíßÛkþÂÒà²ûFϱló<¤]Ûw¾3œnlu5ú¡ûYôüwþNŸö/ÿ±Í¿ô»J¯¿ëóÛþ !©Ûj?µ?ìeöy<Íž3;¾R1›í+Gµ~„×&‡ÇQŽ# R5)ËiE©'ggf®škÔ©EÅÚJÌ+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf®§±Íˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Vwˆ|G¤øKG¸ÕµÍRËEÒ­öù×Ú…ÂA[˜*îw!FY” žI½hÑ^wÿ Û÷.“§ø›^’^-MðÕûÚÞ“÷ W Ûß³DX`Æ@Ÿ5ð›xÿXÿ?Ã_ìÏ/ýoü%Úõ½žüýß'ìK{»;¼Ï/]»òÛ@=Šó¿øCþ"êß¹Õ¾"ÙiÖËó¬¾ðêZ]èžòkÈÌx$#VÈRÊÇü"ß|?ÿ ŸÙx’Ù?zÖþ+ÒP]Nì+uf`ŽØi™ 30mŒz%ÊxÇø¦}_MÔ´‰¼?â Xá¼°žd•dW@Ésnês%³Ÿ1RFTbÐʬˆÈʽ]QEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡ËR÷FÐød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯A’ijDñ¸ÜŽ °õ«ØévúsHmРWq#ŒóÏÖ­Ñ\UpJØŠxÊ”¢êÓ¿,š\Ѻi¤÷I¦îŒÔ¤“Šz2­–™m§oû<~^ünù‰Î:u>õWþ­7þ}¿ñöÿÔ¢¼êœ=“V£OSJTéß–.œ3¼¹U¬®õvÝîZ«Q6Ôß™VËL¶Ó·ýž?/~7|Äç:Ÿz,´Ëm;Ùãò÷ãwÌNqÓ©÷«TW]§.Ãû/c‡„}—7%¡ÉÍñrÙ{¼ßjÖ¿Q:“w»zîeÿÂ5¦ÿÏ·þ>ßãV¬´Ëm;Ùãò÷ãwÌNqÓ©÷«TW&‡²l hâ0˜*TêGiFœ"ÕÕšI«¦× åV¤•¥&שVËL¶Ó·ýž?/~7|Äç:Ÿz«ÿÖ›ÿ>ßøûjQENÉ«Q§‡©‚¥*tïËN G™Þ\ªÖWz»n÷V¢m©;¿2­–™m§oû<~^ünù‰Î:u>ôYi–Úvÿ³ÇåïÆï˜œã§SïV¨®º9N]‡ö^Çû.nKB+“›âå²÷y¾Õ­~¢u&ïvõÜËÿ„kMÿŸoü}¿Æ­Yi–Úvÿ³ÇåïÆï˜œã§SïV¨®L/dØÑÄa0T©ÔŽÒ8E««;4“WM¯AÊ­I+JM¯R­–™m§oû<~^ünù‰Î:u>õWþ­7þ}¿ñöÿÔ¢Šœ=“V£OSJTéß–.œ3¼¹U¬®õvÝî ­DÛRw~e[-2ÛNßöxü½øÝóœtê}è²Ó-´íÿgËßß19ÇN§Þ­Q]trœ»콎ö\Ü–„W'7ÅËeîó}«ZýDêMÞíë¹—ÿÖ›ÿ>ßøûZ²Ó-´íÿgËßß19ÇN§Þ­Q\˜^ɰ5£ˆÂ`©S©¥p‹WVvi&®›^ƒ•Z’V”›^¥[-2ÛNßöxü½øÝóœtê}ê¯ü#Zoüûãíþ5©E8{&­Fž¦ ”©Ó¿,]85gyr«Y]êí»ÜZ‰¶¤îüʶZe¶¿ìñù{ñ»æ'8éÔûÑe¦[iÛþÏ—¿¾bsŽO½Z¢ºèå9vÙ{<#ì¹¹-®No‹–ËÝæûVµú‰Ô›½Û×s/þ­7þ}¿ñöÿùãÖ™m§~ÝŸ²OÙãò÷ÿÂ]»æ'8ÒãÇSï_ZWÍ_µ7ÁOŠ~9ø±ð⛯íxûc|1’émæûlÀ0¶èY°«)û˃³ï ŠäÂðöM­FJHí(Ó„Zº³³I5tÚôªÔ’´¤Úõ<Ëö9øÕðßᦵûEXx»Ç¾ð®«?ÅïΖšÞ³og3úW +©+¹\n©ªOˆ¾øÿöìý•ÿáñw‡üSöOøJ¾Ùý…«C}änÒ×Ëó<·m›¶¾3Œílt5ÔþÍŸ±5Ž¥xëSøá࿆þ4ñ·‰ü[â&¼´Ò–þ"¹X˜Àw‘Ue™`ƒ¸’j§ÆßØó\Ò>,|,ø…û;ø_áƒ5¯ ÿjýº SO{ {ïµAï[(CI±LäneÚ\c °¯NX,êÓ¯*Qs‡3‹åW‹—ÅÊíuÍö­¿R9¥f¯¹ó7Ã_ù(¿?ì¨ëÿú9kÐkÕfÿÙCðäÞ4ã—„þøÓâO‹|I©x´Ig¥ B8-f6û£Gº€Hˆ³<›P“Ãä;ñíßðÉß?èü?ÿÂ^ÇÿWåÙŸG5ÆÖÆGng·%ìû_~GáY߆Ûl×9=£½½íóçWûŠuÿé~³K­Vö+8äC ¹Ì“ÊA+H2ÒHØ;QfÆ&¹ŸNÿþǨkvÒ¦£åË©_XÛ•’F¾¹•¦’Ú»Lóã]ĶQw19>¹ûXü?øyðCâÃëï øOÃþ ¶¹ÐuÁxt&+VºeºÒ+•÷HUbÒaA-ƒæÚ>y«j0ëºì>MÌY:~–X:éêÀ©v*J½Ã)!œ¨¬cŒd’oÌs¬¢9wƒœùãîÉ»[™ÙÚ)]ÛyÝÛG½”¿â Š5‰–_R|ð\²r·/3³´b®íe'Ìîìšz;FShÄW¬ë/ƹ4f !%¡²„|ˆ2#*¥ä 4Œ ª±Çl_¼øÅuöOÝy: ?Ú{ÿå¾û‰>ų®<¿.ÿwÝÏœŸfψ¼Eýö{[[í fóp³°³~Ün’FÁòâM˾LnUPÎèŒxcÿØ^I5ÇÛu=Bãí—÷a<µšm‰U2v"¤q¢®IÚƒs;vùÕRJ«Sí+E|ûvZÛûÖµÚvùEVQ§:Õ~ÜybºZë§ò«;?ç³Wqml×â}kOðÄ+=sV¿¶Òô}jÃû2âöþeŽ(î`wšÙ6ïI¯I-Á1FR@~þµ>ÿÉÅ|ÿ°õïþ˜õ:ìÈð˧ƒ›´j{¯çþM'ò;¸oÇ3¥€›´jû¯æ´&“^hË¢¾Ãÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿÆ«õ/ø†õÿ”ÿûsöŸøƒßõÿ”¿û¡ð÷‚?äû?g?û˜ÿôÖÕé_²7Å…ÞÖ¿h{xçÂþÕdø½â)â´Öõ¸,¦xKB¡ÂI"’¥•Æìc*Gjë>6þÇšæ‘ñcágÄ/ÙßÂÿ ü­xOûWíÐjš{Ø[ß}ªàzÙBMŠg#s.Òã…[ý›?bkJñÖ§ñÃÁ üiãoø¶ÿÄMyi¥-ü0Er±1î"ªÊ&!2Àq$×èøÂáòªyV21¯ÝûÑM6äåð¾e¥ÏÛ¸o)—唲èÕçäæ÷­Ë~i9mwmí¹Åþ×>øçUýž´ÏxëÂþ&Ô—ã‡.f³Ñ5»{Ù–%iÔÈR9… ê7c`;Šïÿgù>ÏÚçþåý5ÉU?i?ØšÇ_Ò¼ ©üð_ÃøÛÃ-°ñÞ]éKa ñ[,¬ w´„ÈÊÒ˜IL¨! ÜÐ~Ë?>)øâÇÆˆ_®¼6µã¯ì}x:K¦·‡ìPMÊÜ eÊ´Gï6Nÿº0+ÞÂá0ø1Ãá)Æ8í¥®îì•’»múŸG)9;ÉݘVv0iÿðTƒ 塸5¸Œ“Ïö߿Ҹø'í ð³Àß±ÃÍÄŸüáýj×ûGív©¯ZÛ\C»Q¹ußÈr¬¬29 C^ñ¯à§Æÿøj{_‹¿®¾ÿȘž¸µñ¬—ßóý%Ó:-²× ïü½ |óð›ö7Ð>kžð/¼+àïø†ËÂW:…äZtwpÜÊúµÃG&ù¡WvXZ8÷2‚mWCG J40ðP„tQŠI%ä–ˆzÎZ½Yößü5Áú,Ÿÿð¨±ÿã´ÃXüÿ¢Éðÿÿ ‹þ;^ÿ ãð›þ‰ƒ?ðŸ´ÿãtÃ8ü&ÿ¢_àÏü'í?øÝmÌkì_sÝÿá¬~Ñdøÿ…Eÿ¯ƒ¿aßÚ7á‡Ã/ÚKö±ÔüQã­GÓ|Aâß´é7“])†þ!y©1’\‡]²Æw‚Ö½¯á§ìíð¦ÿö’ŸL¹øeàë4xI®Eœº£B%ûb¯™°ÇÛI±œq_™~(ð5¿†?oßøjéU„~*Õ’ËD×,„ ´íiÆTI¡2«¾&Tq…nÿÑZðÏþÿõ¨ÿ†ïýŸè­xgÿÿúÕù«kðÇÁÖ¿cû7„ô8þËplíµôØu3lΙ©a[ÙÈ»‹n™7¶y×Ç¿‡ÞÑ>j÷Zg†¢ÓäÓäŽÚÞê –îÉÚh|Ë+ýªÜ…ÚÑÝó¦‰w]~…âÙâ±è(¥ÌÒ¿/woçôü{kù^Žjc1TðÑŠNrQ¿/wkÿÓñí¯;û êÖ:•¥jzí¾¦Ù|`ð%ÍÕåÜ«0D‹¬3ÈîÄUPIb@kè¯ø,§ÅüPÿ…AÿoŒ¼?âß°ÿl}¯û T‚÷ìûþųÌò¶îØøÎ3µ±Ð×û~Æ~3ø7Gñ¶ð¸ø_/ŽtWS³ñw?iÔ¢ÓLË"Û§’ÐÍ¥õÌLᤈ©*³õ¯íÏÿÑÿ…ãÿOü)­ áÿÃÿì¿·jÿ¡ÿfý¯Ìû?“ÿ¶Ï¿g—/߯7ñœšý8ýŒ«ÿÓ-´ïÚŸö2û<~^ÿß19Åö•Ž§Þ¿Bkàø(ïü?ì_ÿc›év•_×& ‡ÀÑŽ N4éÇhÅ(¥wwd¬•ÛoÔ©IÉÞNì+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf®§±Íˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@W•|zÿL—áæ¨|ÞÖ¼Lºoˆ¢—å·žÕìo ó¿h¦½[Jc*ÀÁÖfÀ=VŠð­i¼+ðƒÃ>5Ò¼ª\xe-fÒì¿°ô-6)­4ËëÉÖ(á°Â[ÁwsçCû¹ȉ淹š³Ê×iáŒ~>ñÒé^ÓüQ¨h—q|M¹ðm櫬Zé7º¡µÃ³ê¤ßb-d.c¸ÜˆÑ±ù1 £¬ñÈöóWÃ߈>;þÝð5î±â¯í› gÆzïÛMm:ìÚrêÞ]ôŽŠ¯¤}) ²íöLʶÈÀI^káÿÚâÅÇÁ}Æ—¬ioªü,Õ|ig>ºt?&×PŠÚÚX“om#\=¢ý¦BßnIBÚ`Îâ@·è¯’¿i?‹þ0ø!á^ú?kÖ±á?{PM3MÒ,´Ó=Ä÷"ÙoÚöQ#ZK,Þ{7J°È$šie…ëëZ(¢Š(¢¹/‰ÿô?„ž“\×$•Õ¤övªêþ僷 œ…c’B¢«»²FŽëœiÅÎnÉjÛÙ"'8Rƒ©Q¥®ÛÑ$·mö1þ5|jÒþhPI$ÚÞ"Ôw¦“¡Ç/–÷n¸Þîøo*÷!’b§nåUW’H£“æ¿øjïŒê?nû¯, ¾göÙ¯ ”FOú¯í9ÁeýoÙr¿êãÝòñ!×õoxËRñ‡ˆEºkz„0Ú k2LV‘4 ´lB™64ó3Jà3¼ŽqyqG^¿ŸóÞ<ÅÏá•ÍF”t½“rîõÕ.Ö³¶·W²þ[âO1óÇ:y4ÔhGKò¦çÝê®—Ek;ktÝ—ÔŸ³Äø½¨|Cñ}ö˜úN±©k Ihó,¢Þ{ {…‰@Gçß]Ê’2¬Œ³¨uB¢8ýÒ¾/ý’?´?á¡5ÿìïùÂ,ŸÛ¿wýwÚÿâW÷¾o»ý±þ¯ùéÿ,«í ý›#Ì'še´q•#Ë)-Wšvmy;]y4ApÞiS:Ê0øú±å”ãªóM¦×“jëÉ ¢Š+Ý>”(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠùWþ ÿ&'ñ7þáŸút´¯*ý©äaýž¿ì®x{ÿC–½Wþ ÿ&'ñ7þáŸút´¯*ý©äaýž¿ì®x{ÿC–¥î¡ðÈûþ¼«ö±ÿ“XøÉÿbf³ÿ¤3Wª×•~Ö?òk?ìLÖô†j£àò‹Ý3þÅoèÛ*ýT¯Ê¿ò‹Ý3þÅoèÛ*ýT©FÕw^EÏÙ|Bð®£ã+ÿZx›Gºñe„"æóA†þ'¾¶ˆ„"I ½‰c;ˆ÷‰ýáš1: (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ †öò>Î{«‡òà‚6–GÁ;UFIÀäð*jò?'×.¼O |=м)¥ø–]LÔ5[†Õ¼Eq£G VSئՒÞÖwfg½C”dœâ±­í=œ½¹ìí}¯ÒöÖ×ÞÃV¾§üRñ•ßü$–ž<°Õì¡×4½H8ÒÚåDÞSÀeVVdÚ2e•ØœIúßJñx/BÞÇ@6FþkËÉÒ8íbU-!™÷mO/ ' U²x¯?áŸ5ÿú"¿ÿðæküª¯ý¦¾xÃÇW_>ø’æÇáOÂ{ƒ{®k¶^×oüCs©Ç ÖŸVñ¤–º¹¸¾‹dc|{¤iYáEÏø[$Í2)VúýxԌۓwwæníê’ÖîúöìwMýjq§F ÉÙ$•Ûè’KwÙñÛö»øyû@þÖvÞK»K½ÂQ½†õ‹iÙí5{Ùš .K“…`’Û@° 23ÄÒ+³<zm_·ðõšM2Kq<Ò-líÀi®¦ ‘` ±$ªªÌÅUY‡—~Û_~xgDø{û=ü*ð+k"»)o.‡t’\‹g%Ìš¬æ5É4afòØ ·]Ì8V]Ó¿d¯‹ÿtë-CÄ*¿å‹NH®5Lßiˆ¨,+k V¸Œ21ó¢-s9Xƒ@J _ŒxgŽ®³,?5Mpë¦Ü½—u¿kßOçox7ÅjáyªÙYÓZ½4\¶èþ×^ª÷ÓÂZÆ—Õö¨ñ\뺄†K¹ã%‚&æ0Û£3JÛ »Žù ‡‘óÐW#sñwÁ2Úßø·FÒï sö:•ìv·6ò†ŽXd*ñH¤ÈêH €Aü.‡ßô=øgÿÿü]~)W©7)Ñ•ÿÂôòÛD¶K¦Çó¥|cV¤§R„ïþiåkh–ÉtZ•j|3ÿ“Šø5ÿaëßý1êu“àÝ#Å?cþxmüObî«ý¿qp,ôTˆ,.ÙXÜRE?eIÊ:mFH¯ª¾þÍ+ð«U)ñ¼þ$ñ¬¶§´Öð ]>Ê)$åŽÚ³áÌåši%mÑe<¥vJý„xk1–>Ž:´:p|Þòi¿Eú»iª¹ú—p†k<Άe^›§JšòM9hì’óÓWemUö=Š(¯èÃúÌ(¢Š(¢Š+æoŠ¿òtöÿö&/þ—=}3_3|Uÿ“§·ÿ±1ô¹é=‹‡Ä(¢³=;áWü=Çý‰ÿ¥É_œ¿µ¿ÍÿTñ\_ñ,´}’ßÈÖ?ãÖçÌÐáO!Ïo7w–ÁØÿq¿F¾ÉÓÜؘßú\•ù‹ûzxÊßÀðR_ë·vQjv–ñÙ¤Ö3Ä$Žå$Ñ`¢`H8r¥Ží¹Ý±ñ±¸³ s­­Nš¼¥ $¼Úv>o:¥Ožê ·1?ö~¤>mÞ^ï2œÁ±æ7}ß3uû^x9>Ùäéºæ£²Ü[Aý§2hZûìo³+yˆ»—pwH¾aܯûß´ò¿h¿ xóÀÚÞ…§Eâ»–;xl¯¯V!$öé8Û^1Ì¢"»¢›ýgÎU2¼ÿŒå¹&cKB¤èµ(¶ü®¿¯¿³?ž2Žͨf8jÕ0òQŒàÛ씓ׯf~·ÿÁ.?äÄþÜOÿN—uõU|«ÿ¸ÿ“øeÿq?ý:]×ÕUûÁý0|ÿÿ“§ý‹ÿìsoý.Ò«ïúøþ ;ÿ'OûÿØæßú]¥WßôWÍß?ãÇÅÿî]ÿìÕô|Ýñcþ<|_þåßþÍIìaˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@TÕ´›J½Ó5;+}GM½…í®¬îâYaž'R¯£YIH ‚A«tP?¦|=ð®‹à×ð†ŸáÃÂo ÖÍ ÛXE‹E)c,fP…\»–\a·6s“\þ¾Ÿ > èúmî¡aáÿ ÚC{Òâ†Æ4–[ÑfmaŠÎ×|·&Ö3op«Hѯ–ŠGËU?h}sYÐ>E&¬\xR½ñƒ¥ JÒ%š®õ{;Y™xäw•4€FqÅx‡þ|=øEãûË;/Ž~8¶ñßœš5æ±}¤iú½ÃI.–©úŒÚD“L»õm%FùYUdŒ ,,#õø~5|5¶û•àÿEö;Ùõ+mŸ µáä]Mæù× ?å–O´O¹ÇÌÞt™'{gçâ§ÀÏi^3Ôçð±¡éºÜ3\ø¢òO…:ͼ7ñm‘¦’ùΞ«¶I‹4¤Œ;“Ô×kÿ oÅßô]¾ à‡¿ùU\W€<'¤Þø¯âV­ñ7Ä5O‡Þ †-;Wñ|¶ém¦Ã•§êèÛÅ6qÏ—W]ˆVeŒí2m ×ÁÞ"øQûRèéâK +Oñ…¦›çiñ\ë¾’)`K»8¤•#[¸UÄSÚÜBIQ²Xä^XWª×ξÖþ"É⿉Z߃þÛÝè^#ñ:­÷5+Ÿ4Ñ.•§Ù•Kcg=ʲÍeq¸Oi…£2«’š¿ >/xª÷ãoŠ~ø¾ÿGÖn,!v³¿Ñ4ItÅómá°ší$IonK/—¬i¾[¤²ÝU Hî´QU5mZÇ@Ò¯u=NößNÓl¡{›«Ë¹V(`‰³ÈîÄUPIb@h‡Œ¼e£|>ðÍÿˆ#xª? ø^8ŸThÖ{»ë”/k¥[1*.'‚Ä•q!ƒLÊÀD–XªXØêž!×lðâ²ápx³þ…ÿ ¿ù¿¨¨åõ}œ}”-ik%oCúî (ªpI%¢KD’Ù/#ר¯!ÿ…ÁâÏút_ü(&ÿä:?ápx³þ…ÿ ¿ù¶þÏÄÿ'â¿Ì¾tzõä?ð¸Uÿ‚£ÿɉüMÿ¸gþ-+Ê¿j_ùg¯û+žÿÐå¯Uÿ‚£ÿɉüMÿ¸gþ-+Ê¿j_ùg¯û+žÿÐå©{£h|2>ÿ¯*ý¬äÖ>2Ø™¬ÿé Õêµå_µüšÇÆOû5Ÿý!š¨ÄøãÇü¢÷Lÿ±[ßú6Ê¿J~*ßjšwÃ͢˨Zj¦ÊHí¯´½=u ‹q°]%«ö'wœa]Ï Œ¢#»*7æ·ÇùEî™ÿb·‡?ôm•~Ÿx³Å:_¼+¬ø“[ºû‹£ÙM¨_\ùm'“Hd‘ö ,ØU' 8àRªî½'ø­ñLé?cÓ| ñÂïnïu+Û©n®Ò ]]"–)Q¬îîVÓå¡[Ô¤IQ»¾XŠñZfã x#I·ð5×ÄèZÇ‹|Júηá½_½³d¿¸ºÑ˜ióΓ¤E?,ñE"Í4QGw½^to¢¼iûL\xÆÞ¸Ö´BÇÁš—†u}VþÆ]cªié×6‹u4ò¬­ ¶Hn&rQH“ìëäKpn Gín>;é0ëSèÉ£këêwºØÆ¶á¥Ô`²ñZ«4Á7\Ùq³‚“<2â3F'ʶ>ñ—Âm?Ç^5šãÇ^*Òü[áÍS]°Ô$»‰|Se>Ÿ¥Gw ¤bõlÙ¼I¶Ek,¿5¼v =¼ËýðSÁº·Ãï„~ðïˆ5[sÄ:~™Z®§s¨\_5ÕîÀn$NLŒ­)r¡±µJ¨U(ù~ëö¦øoñþ?|[øSÿ¿ü#º.âï jÚþ¥¦KºÿSûDvöö­ç®7ý¤G›ËUû;M:Úýž9°|1ý³>|hñ– x×Å#·½….W^‡Ã—pi‘DÂôy’O2 UXIâ0ÒHˆ›ÊMå{­Q@Q@Q@Q@Q@Q@Wšx·â?Їïƒq £ižÔ„zûImskZ„ökk4Å)Žxš6’TÉ Fh•ZQÐ|ø¿gñ·ÂÚõ–™¨i1ÚëZ–`Ôlî-¾Ëw$ Y≾uEfP§Ëvx˜ï‰Àô (¢€ (¢€ ÀðÇŽtÞë6º]ÒÜK¥\-´à2òZ5uuä¡ÜT1Œ“‘ñwÆÐø'Á÷5Ôv·7?¸†G&ÌðÏÀŒÁ—Ö¾Lð¯ÄÍáïÆ ĺ^¯öí7P€ZkQ´.†b Y*»bq³,Æ&ùÞoÅ´òÌæ†[ËxµyÊÏݿîËKÉߥ­¹×Nƒ7?¸û¦¾ý­õŸ ü,Ь¾,ø›âˆ>IáÛ+Í.Õü;„ןÚÚÞF´ŽËi–IY¬b+·fЮÌÁ2Ûýª¿lO~Ê ¼Ô'hUôÏ Û] ¾¾g.±±^LPn÷NÊTl`7¾Ôoˆü1ð[Æ>&è?k;K^Ô5;K½sÂ? ,tWQ‚Ý£hU–îÚÖÚãìvé¾Çt{]ä2'Ÿ¹ÒHäýc•.f’:oÙCâ7í?ñ»Ä–þ#ñïÄ?ü<ø[«^‹=ðÖ>­«É4O=ºÂÿÙ»|”„y’^4+!@Ë´[_´ÆŸü ø›áÏø Åž"ø³ûJêú<ú%–“tº\Ö>Šñ­§žw6ö6¾d¿èq: ð‰™¥UBOtøÙû@ë2|>ÖíþXx–ÏÆÚ¤cÔ|QàO›]=Lah£]2`]B.ض¬{Ù¤mß2IÃþÀ? |ðfòîÖîóÄ øãâk+_]ñ‰|5«iÏsÍÚ#µ–þÚ"ñ,·—lù’»¬Ž‘Êæ½Ù´Ý.D ú¶ÿ%Ñz·{_M@ýŒ¿c-/öaЯµ­jûþß‹"Ý?ˆ¼Upí+ÈîÞcÁ Éóù[þfvÃÌã{ã‘ý+EFEå?hï ~Ïi 7‰m5›Æ×&–ÞÊOkÙ^HÓ{-ﻹ²Sœw™IA9IÙ"e(Â.RvKvz¥òçü8×þ8iº]×ÄëÄG…4–‡^½ðÔóI4:~±ox«:ý¼<²Ë=´ ò1´H¤.=“űˆ¼wáH´}sâ&Žî³k÷5·„A‰ÛQÕm5ˆÁ‚âîhÙb¾³]É u–ÝÚ"¿}Z-ŽüL$¼ýŠáÕmô·ðïÂuÕå†[‰4Ãá«?µÙ¬Mœ]Ãäoµh„›åIÕ$Šwp©Í¿x#à&…ñ«Á_¬>|?ÕäÖ¯n,5+èü/¦•2ió_C8²kv•〓 OÊ’Å Ñ÷ š×ìOâ++RÓôxÂV:¯‡õúÃDø|--u%´Žâ[xá¿B¬#°¶Úfi›y˜–1´QCÕøsömñï‡üMỦø—£ßèZ?‹n¼`ºmÇ…f°]%ý¼S¥ê…¤Ô/eˆH’É’5i&Xð̃Ý<-á=ÀÚ®‰á½Oðþ‹k»ìúv—j–Öðîbí²4W,ÌÇ’Äõ5­EðüwþNŸö/ÿ±Í¿ô»J¯¿ëàø(ïü?ì_ÿc›év•_Ð_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQEQEQEQEQEQEÆ|]ñ>­á/-æ†öQê·¦—¦Ã.¡nóÁÚ¯ííYÚ4’6}«30×$k³¯;øñÿ"F™ÿcO‡?ô÷e@wñ×Jø‡má-MsÅÔt¥ñŸ…|ëm?Ãw“¿üOôý»e{ùUpÛIÊ6@#ŒäxGÅ_ù:}sþÇ=?ÿK¾WªþÑ~±Ôþ&kzóøqõÝWÃÉà-BÞk%õ ûHÄ·2]½ºD7ú˜œ¸ŒUÊxûÁÿ|wñQñšø“ã†y{ m4¿‡:·ŠxŽ˜Êè'Ñ%~_EÓœ†r3 wV·ñ¯áÏÁo|m×Ä:ƱˆfÔôíöH~iº•½ìðÚÇk𕯇p:Ïkþ¶äíó‘~QµGk«x[TñŽ™ûIéÚ=¯öúøÏO¼]¤XÓYK}BžM6Frb»HžÕËå\1euÊž_›ÀÚÿŒµ]hëÿ,tÝWÄg‰¯¼9mðßQû ÷¶"ËÈ%ßFk…SýŸlYVa­Œn5Ð|4ñoŽ5Ï|X—Á¾Ô,¬5ïA}iâoÙϤÙÅ èÚe«²YJ©yq*K‘ŽdTp.£`(Ø<ñ“Â^?ÕeÒtÍBâ×]ŠtÚ&·§\éZ‘· ªn¥ÜqLÐo`žpCl¨mÊ@ð¯|ßÈÂUÑ¿go Ýèúõ¿­´ÿ‰wzþ´¾!Ô?·ô›i,ã½pÚ²Û”aI ˆ¤)mòÈIckÀ?³ß„¾øÊóÄÚAÖ'Ô®a–"ú¾±s¨²´ÂÙn$ónåv‘,l‡vT[8ÄkéL€ss •´·¤D†I%•‚ª(,Ià9Í|ñ÷ã~½ñÏYÒcðÕ”?ð¯l3?Øõ;¶·mVð4m Ëã4P•s’Uœ¬ØÌp°úöÝ×®ô_ÙÛ_ƒN¸„êZ¤¶út[Êb—V 3YDã”i!Y·>HÖVmª¬éñ5ïí¬çÕ¼]$Z½ô1µÄÚµüv ´– ¹A@hÊ¿îÑÝ×yü¯sš˜.Lee4î’»iéÒQin·^Iî¿ñˆ*åÞÏ YTNé+¹'¦ÊQin¯ÌµÑ)o“JÖ%¸¸k-BÙ,u5S'“¦Xå oÊ©` PT‘‘†FmkSÄ:퇇ü?aý­â-GwÙlÌžZ*.ß2yäÃyPG¹wɃ÷‘^I#üâÃQÖuoü:³šÆ÷SñÖ©un,l"RòæA‹Àv¬NÖþhÝÀÒÒ*!˜}oû>ë¿ ¾x#ľ6×¼edu[§Ó ×uwŽâßO··–w‡Nû)–4ó¬ ·lÔ1åNÍ<Ò4Áð9 Ë7ĪÕW-·ÍkÙ´íh·­Ÿ}ÕšÓFÿ0á~–{‹XŠñåÃEµ+7i8»Z êâûî¬Ö•¿bø+ðWKø9¡Osÿkx‹QØú¶¹$^[ݺçb"e¼¨#Üâ8C»™™žI%’OE¯?³ø÷àK¿ èþ$“]þÍÑu[ÛÝ> ZÎ{.{4º’í'YÑßÊ[ ²Æ`€y'œ•ί~'h~ÜšDš„7v[ ņ³¤Ýéw‘£îòå6÷QE/”å$U“nÆh¤PÄÆàFÒ¥N…8Ò¥ÅY%²Gõ °Ô£FŒTad–‰%Ñ{ãßù,Ÿý€´ïý(¾¯ˆ¼[ã]k[ý—µX%ñ—†tÝ;á•©In¶6ÑZjj6×<WËÿhÖ¢ $¿2Ê»b¯½|{à/j~<Ÿ[Ñ Ò.­gÓm¬Ù/ïå·tx¥¸r@H$8î:+„¾ýžu-N×L¶¼ð€.í´»Il,!žé--¤‹É–±ÂFñ"àH#ŠúªU©:‹šNÖNû¢ýö¡ðÞ¢×÷·R^øWZU‚y³´qÜèà$Q€e™Ýœ‚ì_Š$jžsañöº—Wñ ëZŸkáýwK¶‡TÓo-´ûkKYôùõ¥’? y®·LgI f±VÙ#o¨$ø_ãYu5Ð|(÷ðE$]6¯9–8ä(Ò"·Ø²ŒQ’Á1®~èÅm[àïŠuíÿÚ~ðn£æZM`ÿkÔå—u´Û|èNë#˜äòÓrtm‹p+¦XŠj‹{þB³ì|‹oãoˆ~ðuž•§ëVš®—à«?êiö]­«j÷ò_Oyý¬oÝs<Åm|¶Œ<ã+ˆ‚v²êž ð¯þ$ø‚Ã[òtØü¡i£ HÌw_l´Ñ-&y¤`_äŽuh„F-®„ÈfV¾ù®ü ×¼S¨éZ†µàßê÷úL¾~u$òÙI•mð³X“eåH9Eôf_ƒ¾)Ÿí^g…ü'ڮ⿸ߩÊ|똼¿*gÿBù¤O&®y_)0FшU¨­=¯§ÜÂϱ⚮ƒ¡é<®hv\ «kWÖ—ž$°¹7–£t¶š—Oºb¹û4f Ã3?—%¤1Q^?Fø·âË¿|)ñŸ‰´øàšÿEÑou+xîT´O$0<Š)©*2Åj\|ñöÆ­®éþðnâ­NÑ­&ñ%î5…UT™_OmûvFBÈv™R+7ÿ>.hºÅ½íç__¶‹vý;QÔ¬’ r¤ Æ 9 6¸åFr2‹B7JK_À\¬à<Ê/tÏû¼9ÿ£l«ôûÅ:ü$úÖš5-CG’]­¡¥ÏäÜ[ÈŒ$BAVÃ*’’+Æã)":3#~`üxÿ”^éŸö+xsÿFÙWê¥J6«ºô>j›öððð…—†,|}ã E·Ñuítètx’k]RìÝ_©_ìò±ïa(„F±¤(!.[ªOÙŠ$øaâÓñÆwm­[x†[&M/ì÷wñi‰¦<ÒbÇxó­U‘Ö7EFhÄd)_k¢¨ÄùÖÛö'Ðlm¼,-|ã‹;ï išf™¤ê6×V1On4ù.¤§m Y`¾»µduh¤†fó#ywþø"¾ñþ­âÏøMÆ„o26ßk¢€>u—öqñP±ÏâK}~â 3Àv3jú”’­Íôº&±5ííÄ ‰i£˱2 @ùÏwðÏM¸ø5àO·o´MJƒÄzÞ³¨5 [+ÍF{Ô{†–8Ö_´”e×ä îÂôÚ—Å èÿôoßkVöž,Ölç¾Ó´Ù·+]Å o–ÄmfPwlvÕvj1aûwÿÉž|Zÿ° ÿÒ¹kÖTèN´5åMüÕôûÕŽU'óôûÕ™ïWÅÿþ<šû?†¼Kqÿïˆìõ [þEÞÂ9üøú7üºô?èÿñëö…pe9¶9Ã,VÝ=×Tû??Ïu¡æd™Þ?Áǃ•ÓÝu‹êšïø5ªÐ(¢ŠöO|ùÿT±ñ¿Æ/ˆ>°µ»øm¢øKZ‹H²‡Ä~ ŸW¸o3L°¼’C(Ô!UË]Ú±Ž#\’i?áAxÛþ‚ÿð×ÏÿËzù3öÊøÌ5¯ºçÃoÙËDñGо-ê“ñF«áßkÖ:d¬‘¼›[¸­Äñm¶O(òbòÑ$ÞÅÄ~õð3öi¿Òü&žñ_Åxûâ—{ñ>­qãÙÙY‰aY­˜†xR|!C3no5À-Ï%ZyKš¤oºWgE*U*ß“h«·Ñ+¥wÙ]¥æÚKV‘Àü ý–üuû`|LñW‰|¿|Qð¦µdm¬ÖÚêÓB²¶’ÃN–+¨£”ÝçˆKp°Â× ‹ä¯—+4Qütýµ´ßþØþ ðg¿ ß|`ñ¦Ÿa¬èWÚU®¨aŽ»ë«+†Œ\ºËÌa“ÌR(U‚—_)Ñ1¾6|`Ô#ñÞ¯û4þÊÚß5ë×»ñ‡/u«ÍCûCo17·K"Ê‘E o cäíXâV¸`"ú/öDý‡<û éWrèMq¯x³R†8uêJ‚gP«ºF!€È¦M™f'hw“ËM½…9ÅÅFšiu»½ßÜ•·¶—WÝŸ/üuÿ‚„|_ñ=ŸÃÿü%ðχì~&øîÊÇWµ‹DÖ[½Ó-g….#Žâ)ìa·‚Wƒ33ȱIJ;VŽZúWöm?þ(ÿ¤øãk_Áh¿äƒíº~«%Åæ¥>¡ý—qçËoö8b·âÍË"<€4¡W…Éù«öDýŒ¼!ð>ÿöqø©a}¨j¾$ñ¥í´ù¼p©§Á?…5‰àE\Ýp¥·°Ê¢Äƒ•‘åûWöNÿ“Xø7ÿbfÿ¤0Õ˜«EP_þߟò<|ÿ°Î©ÿ¦Ù«ìjøçöüÿ‘ãà?ý†uOý6Í^{ÿ"œ_ý{Ÿþ’Ï›â_ùã¿ëÕOý!ž[EWñÙü 柴§üŸ׃èB½.¼Óö”ÿ’ãOúðoýW¹‘ÈÛ ÿ_!ÿ¥#èøkþG˜úûOÿKGëQ_؇÷ÐQEWÌßäéíÿìL_ý.zúf¾fø«ÿ'OoÿbbÿésÒ{‰5+ø´­:êöe™á¶‰æu¶ç”ª‚HHã îØ*‚Äð'ñå÷Æ /Æ+ðïS×<{á'ÄZOŒïtÖñH6-¼-¢K%á±›Îd’2âŠI*MªÜE$‘·›öe™ÜÕÏ‘>~ÔÑèßü#ãKÆú™ýµáO ]Mmsqm› ÍZ;=NÕ þ]º‰î~ù’9!o1Ú%h«¤Ô¾9ø·àÝØ×¡ø¹¬x×PÓæñæžÚˆn­¥²K‹MzÎ{¨lìþÒËoepúƒÇóvù03¡úáWü=Çý‰ÿ¥É_LÖ‹c†> ø_ñËâ>4x+Á·¿þ­Ü7בÇá«Oí9µ›K;5Àûd†Þ9§š#¨BÓZ[¬(mïvÇæDV×íú(¦@QEðüwþNŸö/ÿ±Í¿ô»J¯¿ëàø(ïü?ì_ÿc›év•_Ð_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQEQEQEQEQEQEç?äHÓ?ìiðçþžì«Ñ+Îþ<È‘¦ØÓáÏý=ÙP¡ÿÉÂø×þÅmÿJõŠôJó½þNÆ¿ö+h?úW¬W¢PEPX>;ñ¾‘ðß§‰uÛŸ³iš|^d…F瑉 ‘F½^Y•Ìîêª `+z¿>~.øûÅI’FfY’ íÊ*µÂMÞÚN“c iVZf™eo§i¶P¥µ­¤K0DŠ#DPª¨(ð|9õñØ™çÚæ“øSÕ[kµÚÚE>šögæ\'˜œËS>â(óÎ_^ªÛs5ü¶Ò îµkfyï¯ÙßÁÿõ[oM‚çSñ=Õ¨±¸×õYD·on$."Pª±Â™+¹bDcBûÙCW üñůÁ_ |=¿ºðø´ð¥ï…àÓg·’v{Ë]'P´žk©˜ K<6À-²«¬n¼ÜH$Ì@Q_­Ó¥ 0TéEF+D’²KɺQ£ON4¨ÅF1VI+$»$´Hù«Äß³×ü,‰ŸUfÔ4›xfãE‡V¸·ÝßêvV¶×Å#`†h¡·Ò´wFVÛæOv†Fe)¥|8𗊇üOãoÙèú>¥«išv•¢j2ê0¤VrÞÌ'7[ÛÎ×î¾_•…†ÞÛʧ¥ÑZZ÷R´ÓV¼º†Õf• ˆÏ @ò1¢äòÄðäÕš•$ÛIê€(¬Ÿj:¦á]fÿDÒ?á Ö­l¦žÇHûJÛ}ºuBÑÁç>V=ìïnvO¾uÔ>.x›]ðéwâyu+OøJ?:ÇÃúŸ…¯…½Ö»i ±Ë§ß3KäH‹" Ć9·\E±|‡/@}AE|¿ðׯ2ñ/ÇÏ­ÛÚøaáñôWZ3%ÜípÖ^#†Ö9 ²]0 áØ<²±(¸Ž5T™¯ÅmâÓâ?„.tOø¼g¬kV¢ÒÌj³ 6ÇI·1É©lca ÄÐ¬Ñ ‰¢•ÖçPµQ$cÉ1{]Q@âžø­â˯Œ³xw]M?E°šöîÎ×G½Ñ/íåhã<Ûêäµô³EÎlãXäŠ9eÜå­$Wð ˆß5„^‹Fñ?ö~´ÞøW}u¬jm{}-Ûê´ÐN$Qwüì‘XóFeŠF!£h@>ꢼö”—ÄV„õ Ä—Œ-ðô7ÖÖQ…šýgÖì ò^brå›z*†˜Áq’9½‚€ (¢€ (¢€ (¢€ (®*çãG‚­t¯êOâ w³ðt3\ëo<†Ö(–C,UI‘U ¸Œ´a‡›o<_ë!‘µ¢²toé~ Ôuë ¯´]èw«§êùl¾Dío ÈL~ææÊä|øÎAZ€ (¢€ +'Ã^)Òüa§M¤]}®ÒÛ½=äòÙ1=µÄ–Ó¦òÍ ‹ž‡nA ‚u¨¢Š(¢Š(¢Š(å_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZõ_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZ—º6‡Ã#ïúò¯ÚÇþMcã'ý‰šÏþÍ^«^UûXÿɬ|dÿ±3YÿÒªŒO€><Ê/tÏû¼9ÿ£l«õR¿*þ<Ê/tÏû¼9ÿ£l«õR¥UÝz>(ñ¯…tKFé”ÔˆãfÁ–L¨8<œz ž€×˜þÏ®~!·ˆt]fæ9uÍ*òCHÌÖ¥ÈS´JUˆPhó’I¨ü]¨7Ä?‹he2øoN8fñòã’9ë·¸À$»Ÿ=ø¯§ðïÅz_Ľ+ö2–úżr¬_j€º€­òÛ³°“¸®" |™Îøß©Sâ¸`éÊøxÞ §£“Ýùê½ßÃâ=àß°r{ŸUQU4V×]Ò¬µ+|û+Èâ v•ߨe8 Gf­×ôDd¤”¢î™äQTEPEPEPEPEPEPÂß¶„:—í=àxfð}ü‰$24RÅ"jO‘Ȥ4r#ªººÊʬ¤ g|hý¡æñGì‹ñKÁ~4¹AâÁáë‘§j¥(µÈÑw7Ê ,whŠÍ$Jº«K %ŠßgöÅÿ“§ð?ý‰š—þ—Yךø—ÃZ_ŒtÝZ²‹PÒï#ò綘pè9‚0 ‚ ~›gõò|âµ4ïJ¢’”}e%̼×ã³è×òîyÄøœƒ>ÄRMºT”ãë)®hÿy|“Z>iתþÌ߯¼ â¿ü4½¨xkZ–[M2éÅm5ɶçïZ­åòÇÞ…‚Æ¡¢t[oðV±yzúî—}7Û.t;ñ§›â¡éM¼¬Œª«íœ+m–BÁP0EÚ²ñÿ‡~|WøaâÏjÖú‡´­búâòú䱯ö&¦Y™Šª¢‚Ì̪ ’ù®ÄbpÕ*4çhͤ×I&®Ÿê¶kïGÈp6+•ñ =)Ú5RKiE«§oškf¶ÓT~ŒêÚµŽ¥^êzí¾¦ÙB÷7W—r¬PÁ)g‘݈ ª ’Ä€$×ç¯ÇOÚ?â_í¡ñQø5û.j¿Ùz&‹‰üIñ&+É-m÷©&8 ¹‰YÖ&tÚ0^r­·$&§ã_ÿÁY|džð´ZÇÃßÙ·Dš5ýNåR;ífè[¬èYIR±‚éË<»˜Áûö{ø5àŸ|Ñ|/ðòÞm?á­Å’Ý-úIya¬j·m"“w,ª!‘7,Jw$YPGj²PÊVÑnmQ ê'RWPM&í{^ö].Ý•ÕìöIµâ_²Oà >xSÇþøEàßø’×FÖ‡üEã-kÅWš.§¬j i“²¤:|ÍPµÓŤÇnÆpK;HþÉâý'ãŠ>^øRÏÃþðÂÜÚ %Öt‰§S‚1€Z9çÐå"B ©”‚ãq`ÁðÃäÚ“ö ¹ðGí/àß‚ÿ5ûWñÏÄ rK6û@ðÐ+g¥´ç[ -¼Ök…Š7?õ’0‹Çü ñ›ã÷íñ²ã·ˆ5¿†^ ñ6‰cwâ;++oËzš†§mf„XÄ®³no1ÑnUÐGoTi ,Òê÷3œïxÂê7ºMßü“vëd}éû|ðïÀŸ xïÂg…môwFñéú¾¢º¹Õ¦ÔØØÚÞBírmmNÔŽøF±ˆUT«°ËHìÖþ5þÔÞ;ð7ÇÛ_…?~ÿÂÍÖ¤ðÊxži?á'ƒIò`7R[0ÄÑl2ÇÈ|Ÿ3îáI¯`øcðÅ~Çâ9$ñ±â­K_ÔÆ«©kbÕfyE­½ª¨[h!TEkÀLç$“šð¯ùÊoýÑŸýÎUUáSöð烾 h?ðÌ?hÿ…köôøOôµþÑò´{­7îàùYûO›Õñ³o9Ü;ÿØóãoŽôx_öwø…ð³þMkÃ?íuuøH`Ô~Ý»Ãb¯åÂ…cÞÂFÁ‘ŠìÆ!«ì ùWþr›ÿtgÿs”õUQ@|‰ûøÄ7ŸüC£ø_]ñE–‹¬Þ›è|=§Iq Ía4q±† _nî c  úîŠæÄáá‹¡<=_†iÅú5frc0´ñØj˜ZßH¸¿I+?ÁŸ—ÿð–xƒþ‰7Å/ü"uþ7Gü%ž ÿ¢MñKÿCÿ×êð_êIü²ÿÀÌâpïòÏÿgåÿü%ž ÿ¢MñKÿCÿ×ñŒø»Ç? üI é¿ ¾'}¾úÑ¢„Mà½AT·|£ŒãúåEtá¸'(ÂW†"”eͤ½î©Ýx?²&ž*ŒeÏNJKÞ{ÅÝ~((¢ŠûÓôࢊ(¯™¾*ÿÉÓÛÿؘ¿ú\õôÍ|ÍñWþNžßþÄÅÿÒç¤ö.4h¢ŠÌô ï…_òt÷ö&7þ—%}3_3|*ÿ“§¸ÿ±1¿ô¹+éšÑlpTø˜QEÌŠ( €?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ€ ù»âÇüxø¿ýË¿ý𾑝›¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}wñ̾(ø~쥥ÑISÔ§GÅqÿ¶ü?ì‰ÿcšév›]‡ÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmiOc¿'þ½WäÔ:(¢µ=ࢊ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šùþé~6ðo…¼OñÄ“=‡Šl"Ô´¿h°Ë‹ˆ^4”ÄðA¾ëRhÒb“þŽñÏl»KP¢j_m.µ­#Â6xÓ[·•í®Op¶63)*Ëuxw#lß y— ®@â¹_Cmmu¤]üSñGr÷Qßé> ðÜS”yí¥ŽdtŠך„1˜„ª¤mMÃgMÓ|iâ-:ÖÂÂÖ„þ¶‰ ·µ¶ŽÚëVXÐTEK;ER€>Ô7ÿ–8êü#ðû@ð7ÚßG°ò¯/6}³QºšK«ÛÍ›¼¿>æVifتùŽÛW ¸Ps¾Ó5ýG≼a¬h¿ðŽÙêz^›¦Ùé·WQÍz¿fšõäyÄE¢MÆìmË&UAb¬J/¢QEå_ðÖ??è²|?ÿ¢ÇÿŽ×Ì_lß|U½¿ð–•ãÿZxÞG¶Ôf}^Ý$×IW„ù@‚õ¹ ø÷ÏÚ¸ø^èð¿þm¿øºú¼¿"XÊ^ÖµeNû-·}Õ¼2¾7ÙK–rþ½·?á¬~Ñdøÿ…Eÿ¯ž|geð[ñ]Ö©¡~ÑÞ Ð,u+Ùou+ uÍ:ï+ù’µ¤†u1;»JäÊ'PλQUv)ÿ…áðçþ‡ÿ ÿàæÛÿ‹£þ‡ÃŸúü/ÿƒ›oþ.¶Åð^_§ì±Uá8ÞöqOU×âþ•ÖÌñqÏ™ÒöÜ*©Ó´µÕuÛ~ž­›>­øIñwöqø)ðóGð_†>/øLI_iñu”²ÈòHÒË#±—ï<’;P[ ª ï:N­c¯éVZž™{o¨é·°¥Í­å¤«,3Äê$GRC+)0$Aù³ÿ%GþÄŸý=ÿ÷þ”×øøôŸþÐþ,ð—ì‹®i>Ð’ëQø{àÝE_UQÇ5µ­Î©¦é—A*4wR/öCMr¢ Ä“ Ó(ylaQOš2º½­ú½<ÿK3ÞÃbþ°ÜZ³GÝWŠjõM7Å'Ðt½+ûk^“ÆqxcGµÕ5´²ýoªÈ^h­žHb Œ—e nXÜK?ÚT×"ðí–‡àßí_^m=þ–uE…"M"ú; Amfhñ<­q* u”[¤‰––Kr6×ÎçµÑ_ÛþÜvþøYðþ÷ÅwžºÖ¤ø¤xÃ^—[סÒo5¹‚BãKµ²Þ\–¶¸&À¤·PøùUø¦ßS»ððÅ©ËHâFž Ü •8ÎƵGJ”ªF.M&ì·vè¼ØÒ»±áõ=gÇkªi~y!:úLrÀÒ¬’\FÊÇnÑŸ0eL ä‘ð#â?ü-†úv«3îÔáÍÿÿH@2Ü*J¾`oÛž y%¯ÁZp‘, ÚA«söï_Äï¤ønÍ”ßjN¤±© i…E ÌB«û-zô°ÔÝZÒQŠêÎJTjWš§J7lÍñÞ“ð§à>kñÄ·_ð‹Yxf]Væ=Aµ °õ;´^£BŽ~ÑæÏµÄLµ• j¥W·ßü)¨|G—ÇnÞ ƒÄ“}”M-Ÿ‰õ;{yRر‚'µŽá`h”¼‡Ë1”c,¥”™wçÇíý¯ã¯øûÆ^4»þÑñ#xQò- šC§éq›YBÃm!rªÎ¦v_5üÉyU-~øø×ûAøsཔðÞë>!ÔVC§è:L>uÕÆÑíÚ·²!šB¨¦EÉòyWásJxŒGÃJ›Jﯟõÿú,Ç!Ä`'FÅ9«Ùt=>ŠòÿÙ«âf¹ñàþâYéú~µ6¡ªYÜ[ilínŸfÔ.mT#?Ìß,*K2I;T£©ø‘ñ#@øOá ßx’÷ìzm¶ÕÉ4ò±Û0Æ>i%v!UI¾³ÛÓöJ»v¯#åkÊ8e'YÙG‘¿ |áOã9a:}ÂM-Ðûf«qý›iq6å–âG—ìÖóÈe”4ÑÆ²9¸›,LÒnóƒú7ÁÚÀÚõŸ„t}M|5¢>•á»[ë»6š $G}¦Ék2L%Æ×Šé8*òg$²ì'Àþ/|D¾ý¤õQ.¹`ö휶—á{ø¹»=åômÁr9ŽˆÎ ¤½§ö¹†ËÃ_..%H ‹Æd’ÊÁUhºY,Ià9Í|~]ÄÔsLÖ¦ðB-¹wiÅ}Ú¿éÙ~w•qŽ9ÎêåØ]iÓ„¤åÝ©E}Ú¿»ÎËè¯x[Kñ† †¯kö»Hom5ÌdÄö×ÜÀùRË41¶:¸ ‚AÖ¯˜4Û5>!|sð…|¤}«ÁšÍýÝ÷ˆµ8d„ܲX]ÜÄlPã|GìÈÆvÊ2È¡Å>Ÿ¯¬Ãb¨ââçFWIÚþhûœ&6†:¦\ÑM«ù­ÂŠ(®³´(®/â×Ä!ðãÁ·ºœ1Çq¨ùRX$?)uBÛ˜ Qœz‘œŸxÃNñ÷…´ýIiÂõ  ™6:ÅYXz«+‚G0kφ? S<&H$Úìžß×K®è·¢¥ÐÛ¢©k:µ¾…¥]jM¶ xÌ‚8è£$ “€rEq?¾.ZüR³Ö#òþͪéW’Asl¨v,fGòYXçvQpOr·Ê\“Çá©âá”Ò«$ä—t¿¯ÁöaÈÜyºo‹5ÿøE<+¬ëÙº†³ý›e5ïöv“Ÿyuå¡*ò7ÊÛvªäeˆæ¾ ñÿìõñÁŸüScâX4ˆw.ð6³¥jv^ðåÌ’¾¼ëWµ¼”Ë4ªÊ/$Ôö<1[¤^Û*÷ûÖ¼ÃBøå¦ë®¼WËY-Ãé×»ÅĈeó²ÀÔVN0B¶[%VŒN? „«Jy¨Ê£´Wwý~-.  ä›]–u¯…ZuŒþ5Oü<·ðï„î÷D *[£éq$^¬z“3tËÛNLÒ"mb}ÀßáñF¹ð›Oñžƒqâ_ ÙxÅ’µ¶©¢Éa¦¢Ï«i²ØZɧ¼Ó,P$ýžÒá‹F¶ÑrÁ¶/­kÌ5ÏŽZn…ñ_Hðœë‹Kíö¿lEó?Ó D#O”ð¿3)8'y\í Ƽ~ìþ³5y(Çͽ$õØ#+Û¡ó&¿eã‹€^%]cž0ñŠügð3FÐaŠ :{»ÉµX-uC|·nßêeO·DäNÊó1t„M(1×UñÃ@ñ%×ÇÝ7SÑ|NßÄÞÛ¯CáËCQ:Iº²[¹áÖ>бX[aîmåÓãŽGeûDî‚+™eO°*–³«[èZUÖ¡tÛ`·ŒÈØ ŽŠ2@É8w$WeJ£ T¨í¦Ûì–ì”®ì‹|ðÏÂ^^&øWq?í?Ä6ŠûBÀ×7Öͨͬ@úMÒØÅlæerMWiGdÂ$RÁUà_ƒ~"Ô.n®üo§ø¢oXüðö5M?QnM_ËÖ"½{K™$û;j ç[†rcûIùÕ'}þåð{âå¯Å+=b?/ìÚ®•y$6ʇbÆd%•Žweðw+| Ï M4vÐÉ4Ò,QF¥ÞG *¨$“Ð æÂc(cpñÅЕá%tü¿Kuì9EÅò½Ïý”´dÑ?á)ŠÃÂÚ~…¢¿ÙZ+ÝÂ7Þ³ºŸ÷ÂXÆ‘w#0–5òK^(uš8¹6œ}^gðÓãeÄø‹Ãæ´½°e¸µŒ¡ýå¡HÁfl‘¼;œŽ8tÆì1¯L©Àã°ù•âp³æƒÙ„¢àùe¸Q^a®|rÓt/ŠúG„ç\Z_oµûb/™þ˜Z!|§…ù™IÁ;ÊçhV'Óéa1øl?Õ¦¥É'äÖñë³è9AÆ× +Ì>(ürÓ~øƒD³¼]ÖS\ÔnQ|ƶ£“fä0Fn Ùœ+ôú0Øü62¥ZT&¥*o–K³þ´õMt AÅ&úŸ*ÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•ÏèrתÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•Ïèr×s݆Gßõå_µüšÇÆOû5Ÿý!š½V¼«ö±ÿ“XøÉÿbf³ÿ¤3UŸ|xÿ”^éŸö+xsÿFÙW鿎fÞÖ.]ƒÃ0ÁjóM¬]Ùăt’¹fPª1-¹p2r1šüÈøñÿ(½Ó?ìVðçþ²¯¿ÿkù5ŒŸö&k?úC5aR”kS•)í$Ó³iÙöjÍz§uÐÞ£³M9}£áº;´_µß„mƒÅ-µ»HS8;RôÐv¦\¿ÃkËymî?kï Ϩc’)8ÍceýŸjߨ{-¼Ó.Î/Áù'''ñ¯ÔšúÜ6–”hQVŒtZ·§«»'/y…ÄøçâΉðÿ\дíVe·]J*K©X¤V¨RMŽÇ†t ØK1sÛTÑÅÐÄN¥:SNPv’]¯gýw[¦7¬ßP¢Š+¬¢Š(¢Š©«i6:þ•{¦jvVúŽ›{ Û]YÝIJÃñ÷‡a–îYKjRµ‰"IïË’&»û¥\«€§n«,|»˜‚€}¿EPÃß¶/ü?ÿìLÔ¿ôºÎ¸Šö/Û3ᾩ¼9ñN1öèº-æ‘«×/b’ÍÉvã¼ äºÈÃý^åvX•âñÚþ`ã|5j£H´¤›O£÷›ßæ¯ÚúŸÆž#a+á³§:°iM6ŸGïIèþjëu}N7ÀŸò4üEÿ°ô_úk°®WNÿ„#ö”“áu—­¯t M¨nkz`”‰’Ö-þõHxÁg†AãЉyr«é¾|&ñ%ߌþ,|C9Ñ4 E¬YhðøoWvC¨Þ.k,­ ¤â)„NžZ*Éç•daT‘aø-o6Ÿà?„þ(ÒšÞÏÅ>Ñí.4­F{a8žÍc• ¢–6du ¤©Ê²:£§N<“…Ì1 •&µi8;Þ=uZõÙ§º~¦ K†±Ø ç4ƒtf¨J2‹×—Ùµ%k>«]Z5}bÿF|#àm.ÓH°±Ò4‹_ ø:ÆH/tM#AŽãIdcºYâü ªÏ)ͳ!BϹŸd(~Õßµw‹þ&|GÙÇöq·|@ºßˆüY¥mü;!fQ2ƒ²UÜ’Œ˜‰Æဋã¯í‡ñ/ã}æð?à‡†uüLñ‘ŸÄÝË²Ûø~ÏyŽI º 7!ÆEÐPÊ®ˆˆ.ŸËƒéŸÙGöQð‡ì•ðá<7á´ûv«u²mg_ž ·œà1;"]Ì#ˆË;;¿ôu ”ëSUiIIKT×SúÞ8ÊxÚp«BW¦Òq³º·uÓ]Û[½OÕ?b‡Ÿÿd•øqoeý·ˆ¼MákOêÓƒ Ʊæk¶1È #nŠ ²:Ç7îø»<”¿ü!û:kzׂ¼§}‡Jµÿ…]$³JC\^Î|]xâwo•¶ŒœUP¨ª¢¤þ5ý¦j}Câ.™àè¾éþð_ÄgÒ­Û\]N+éeÒu {ÈÌM"2±Žä'2ƒVüWðSöÂñ‡‰u nöëà|WwߨbA&°djRê¸ ù¦™–L“”.Ö=}Õ_üwÓ~-|6ý²-þ/x#át_<<~§†. Þ&²Ñ– ÛR{‚KNI8QÆÜ3ïeH¯Fý¾5øããO…|ÿ ×Ãö¾$ðŸŒõ MÿÌs¥œŸeH7:ùÎÎròI‚våBü æ½êöÎBÎ{[„ó ž6ŠDÉ•†Èäpk:œü’öVæ³µö¿Kùwµõ>Bÿ†»øûÿFǦáÖÑÿøš­ð/Š_?m ïŠÞ3økmðÿE·ø~ÞHíüSc­oŸûE.P“nÁ—r™8)Ýýì+gâ±²øYcâ[»f–øát™Ùœnß÷Xœm%F[îà”eÏJ÷?‚Ÿ¿á_x2Ýo£Vñú­Î«r@óS’#$3 ±ƒ°;x$¸×æ\3Ŷw­…ÄácJ4[Rww¿eóëäÎÊÔiÒŠq•îzQ_¨œAEPEPEPEPEP_3|Uÿ“§·ÿ±1ô¹ëéšù›â¯ü=¿ý‰‹ÿ¥ÏIì\>$hÑE™èß ¿äéî?ìLoý.Júf¾F»´ñ¯†þ'øDè/#èÿÙRE­ùä`Ïæ–™¢¾fÿ…«ñ¿þ}þÿßßüUðµ~7ÿÏ¿ÃÿûâûÿЧtO$»LÑ^ ðã޼IñbçÂ.¶ðòFš#j±Ë¢G89¤AI‘Ï«œcÓž¢½æ™ [F|ÿÿ“§ý‹ÿìsoý.Ò«ïúøþ ;ÿ'OûÿØæßú]¥Wßô+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmvËâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµ¥=ŽüŸøRõ_’?P袊Ô÷‚Š( Š( ¹O|RðÇðǮê~Mþ¡¿ìU¼·šþ;oÙ¬àWž,:³ùhÛ,ØPHçþ3ëšÍ­÷ÃÿhºÅLJ_Å~ }*ãW±† .íbM¾½Ýž9" Ïe$n6<˜¶ºôø[á†ÿn“BÓ<›ýCgÛõ[ˉo5ý›¼¯´ÞNÏ<þXvTó¶.p ÊÿÂäñwýŸˆøáïþZÑÿ â7‰ÿÐ4O…º‡„®ßïjþ5Ô4ógn‡å.Ø]\Kq*’BÞB:«ƒqÛ»Õh *ÿ†zÐüWþ•ñ6oøZWíó}—_·FÑíXó‹]7ÚZ@“J&º #F×-TÕ¿fO€Z•{©ê >éÚm”/suywáÍ>(`‰³ÈîÑ€ªª ,HM{|ñûmëáï…<$²IŸãÁáÝBky J¶ímss´ŒŽö±Ç,l’&å.@>vÐ< à_]xÅøàÙôýRñÛL·»ðÅŒJš}³´vé–0‘5ÃG4îÏ œ±žZÛC)ô‡¿¼+ðÄú¶^µøu¢ÝßM¢ø§AÒ4ϲévrȪöZ£ùAã‹k…´i1ž·K+·—fª–¼ý«oá}[ /M6×€M>ûÇííÎß .!o9ÒˆKÏ–>cœŠ¿¦‰5d²ºð†¡â=#Z°›GÕÒx![«Y•ã{mí2:¯'̸Æþ ãÎÉÛòoòÜôpÔIÁM&ßǾڹ]G]®®×ÉŸ\èZþ—â* OFÔ­5m6}ÞUåŒë42mb­µÔpÀƒƒÁv¬?‡ÿ <)ð·N6~Ñ¡ÓQ¢Š ',ó\Í@¬)$ò’ENÄÄ"aW )ð£Sð×Ä?é·4ðŽ¨¿ÅÜÚç‹4ýhnïn,î^ÂK£§)[Bïnáãó•cÐ4l’OañŠt­7Åšœþ>Ó¼9«¼ˆSB¼šÛ:œrH/–ø˜±ÚëDê7Ÿ˜HaÎ5½Öåo¿ôv·¥ÎÊÙoï# *Z¦õÕ—iC›tæQK«¶¶íh®gÄÚ߉tkøäÓ|3¿¤,`Íö]IbÔ „‘¶(%E…”|„³Ü!ÆüT¡§üVÓd¿¶Óõm/\ðÖ£4‹ ‹UÓ%é##Cy{BÎJ 1%Sï•««ìݽtüv8¡€ÄT§í)Ç™ohµ&—wÜ’ói-»£µ®+ão¾üñ÷‹ôÈ­çÔ´ê­¬WjÍ Ë´’¢¸VRT²@ ã8#­vµâ_¶uüö³§ˆíá“d:­Þ—¢^.ólïu+kK¨²~îø'•7 2îÊ•`è§Rj vìy²|©¶|»á_ÛxCÃ>…fòËi¥ÙÃe ÎA‘’4¥ˆ…À=…jT×ÖÚe•ÅååÄV––ñ´Ó\Ná#‰e™˜ð’O ä?°ÿáe¤ø‡OÿŠg­¦…ü}z\]ÄÃñŽ' óv¤ЪiB ^ˆøD¹½é~ñLJ|Ðþ/iß4-Kľ Ð"ÔïF™¤è—éoö­*käö²3ž¸Õ¥O+Ý,âußy¿Ãô][Çšd_-•ˆìñuÙçÚ[]ÍÏSº{™ß’q¿ rý•5H´ÚÅ:tÊí?ˆ¼1iqhÑ€UN»™gd‚ ZÛfÎÉs· »ãø‚—>Uü~‹ù\õ°2¶)ÿyÁ=Ó\ø¤ê×ÚÆ§k¬ë.»}âüMo«Xµ»M§^®›˜L 42DÊÖ±ºš99šF]¬#)Uÿg]=;B†Ë\ñ•§h-Ư§Ý¤7šŒz…ÂÝjQÊâ8üeŸãÃíÅ~5ÑüA k·÷V76–¾[)Í:òåH&~n¼cO5÷{~c…Í(}g >h^׳[y4™ô^kƒÎp뀟=6Ú½šÕo¤’ùWû.Zxâ‡ÀŸ øŸâ?íñÂ^3¾ûWÛôoøZpY}ŸeÔ±Åû™÷H»¢Hßæ';²8"½ö_ÔltÛ—Pð„>9ø£ã/‚[áÌš¬’ë~.]v5©ÅPcÄjËCŒnSÎ ù¯þ Åð¯Â¾-ø/.»¯øÂú®¥‹n4í/\ñ-”Wš}ä²[YĦü<.m–f1ýšíw”1ûÁm}é_±„ô?ÿÁN¾,è>ѵh¶> X­ô}RÕ-î,~m(´“cQ8i<à¢_:s''¤zÇéý~vCq.·ã_k—ò½æ¯sâbÆK¹˜³ýžÓRº¶µ„gîÇQ¨T.ØÜîÍú'_š’øŸJðµÿŠ$Õo¢²[ßëú}°üÓ\K®^$q¨’IíÐc€¤Ê¼GŒç•R4ÛuÓ¯»'o½'ò?Bà‡æ5%7d Þ½=è«þ%/‰RÿÂC¢êž ±µþÓÔõ}>Xg„\ý™-m¥VŒË,Þ\ž^~uŒyn]”áJ¤Œ=ìÚž£®kš‹ëž'ÕYdÔuYSa”®vGdˆ Œ1Ä $³³»sOü–ÿØ¿¤éN¥]­>W­R…ƒƒ´,Ÿ›qO_Ké÷¾–ýš(U¨ñ3^ò¼W’M¯ÆßåÖÿFþÄßòovö0xÿO—Õæÿ¶Çïþ-ü'‚OÞC‘¯Ý$mʬË.—Èg 4ȨY\tcŸHý‰¿äÞì?ì`ñþŸ/«Íÿm?ù,_ ÿìâý(Ñëú:ÿ’f§ý{_’?‹|Aÿ‘6cé/ý(ñëÛÛ}6Î{»¹âµ´·¥šyÜ$q¢Œ³3IéŠæôiµÏhî‰:Ë¥x]Õ¿¶îôÙ˜‹­ZO³[Û$w1”_&Ø-¢IäÍ!p%ØByxßKñÇÁ¿‰òi/,Öú~™}f×›cœ›0’"~üefM¯Ñº®T«R¯ç:u1e)J Âs¼_F•£/Æë}­Üþ.£W“Q”é· •/ºj6„¾÷u¾ÖÓ]V§Ã?ù8¯ƒ_ö½ÿÓ§_ •ù÷ðÏþN+à×ý‡¯ôÇ©×eû?ÿÁA¼OñŸÇ_ 4­Wàçü"~øý«ýâøJ"½ó>Áqþް+Œr™Ý¸n¿àùGüR?¨¼0ÿ’v?ã—æ}¥Eðíÿñ?ÀïüPðw‡¾y¿ðýH‹Æ_Ûq²_êsÜÚÉö7·mû<¹ŽÒÅO‘†+¼ ýýdö_Œ~*×µÈx_ñ&—bZÙ`þÏmåpvݱƒå€ä ¬¡sP~Érø—ÂZ¾±á½WÃæ“¡ß;^YMc*¬2€#Éå(%/ÌÅW1` ¾+Ò¿áMø»þ‹·Äüð÷ÿ*«Šøßá|5ø/ãïéŸ|q>¥ xPÕmb»Óü>м°[I*+…ÒÔ•,€8Îë_„á:xLÖy¼kÉÔ›¼¯³Zém¬“²ÓM;R®ågm—öˆñ³oei£éÖµŸ0}¢c¦ØË,mÔ"4Š IS’>BxŸÃûßx_ãM§‰í~x‡DÒ/lõ+Q§Í*ˆ›hinàªH@™‘¾ož½Gῇ|mñCIÖõëŒ^0Ñ?â¦×ôøtí.ÇDû=¼š½Ý¤(†m:I"2]Ø““žk«ÿ…7âïú.ß?ðÃßüª¥Šá*x¬ÛûgÛÉUV·d•´¶ÖÓ[÷}Â5Ú§ìí¡Ó|Tñ ÷‡<w6›a¨j7óÿ£Ã›k$ò¡`Il'+€ b¹ë_x–ËÆ:•Æ‹{¥|8ñ™¬é_h‡S:|’pÁ“|fªUHŠŒ·vk½ø1©üDø¯ãOxPø»â2ßÃPËw:nŸ¢‰¯Xx‹Ä"IüÍ=×pƒMµ\F±®UŽÜ±¯`ÿ…7âïú.ß?ðÃßüª­3¾¥ãiãjÖ”]5h¥²îý_ŸeØTëºqqKs¨o]?Ãtñ"躄ZƒÚ«ÿd›9¤¸Šv˜Ì{UØ+žHQ•‡¯¼u§ø£ÆDöðÛÄÏ|nEÌz´ÖSy½>eeò› å‰ÃŒ¤ç®çÄšŸÄMãöðÊ‹¾(ŸMÕfÒ%mZm?Eût 5‰¦–8Êéâ-¬úM™ËÄÌ6¸ 7öøS~.ÿ¢íñÿ|=ÿʪ3ΧŸÔ£SZKÙ-Ñ_¬¾zi°R®é&¢·:O„ž%Õ|Uà.ï^Óï4Ír4ò/a¾¶x¥N YaÆåFâ¹Êšâÿhë6öVš>‘áýkYóÚ&:mŒ²ÆÝB#H ¨•9#ä V~­¤øÃá¯ÄŸ…‘ÉñOÅ*Óuÿ\iWún·e¤,/Ò5¥`ÖÖȬ%µˆä>1AÍe|ð‡>%|ð‹õ?Ž>8ƒR×ü?§ê·QZiþXRYí£•ÕilB†r$œc$õ¯o1Êže–¼º­V¹’R’Ý¥¿þ׿g òO#Î>Þø«ÂÿmiTDÛCHƒwRB,Ìó|õôGÇOjZG…RËKÒ5mVâýŠH4«)'e‰q¸œ)lópT8ªð¦ü]ÿEÛâþø{ÿ•Uãÿ³.§ñöƒð]Lj5‹¾(Ю ‡Dˆ[hš~а»OáÝ*úiŸ§ÊÛž{ÉÛ‚€@UWƒáˆàrª¹E*òäšµú¤ôi7}ÖžZ½Í%[šj£ZœdRxÓMñ÷†üW¤ü2ñ›}¥…K”[9\^/!òLVdgBÇv\ch¯²üEâGÒ¼#s¬ÙÙ^^Éä,[Ge+ÌÌø ºƒa€@ 1\?ü)¿Ñvøÿ€>ÿåUxÿ†õ?ˆšÿÇícá”ß|Q›¥M«Êº´:~‹öéÖ ÍrÓÌ[UõkÔ‰Xî@Xí¶IÑȰ•0xZÒå–×ÕÅÚ×W¿–ýªVö²R’8oiþ(ñ†‘=£ü6ñ3ß‘s­5”ÞoO™Y|¦È9bpã$)9Æ+ëO†¾3Õ5†º¾¿¤êvšÕ¥»-õœ¶R%IJF¼²FQw  e¶‚JšÄÿ…7âïú.ß?ðÃßüª¯¿kÍsâ/Á%tÍ7âï‹54Ö4vŸí¶ú\Ù˽ Z‰ ’ÖÊ ‡P¹RrÃŽ+.á*y YG ZMTѧ®½¯u®›j̱x·ì¥RKáMýÈŸâÇŠ9ÁEüuâÿÙUñÿÀ_ì_xúÊÿÈÿá1‚|O470öan%ùL3˜(>_Þ4bcüxÿ”^éŸö+xsÿFÙWßÿµüšÇÆOû5Ÿý!š¾øñÿ(½Ó?ìVðçþ²®[þ _ûJxŸã‡Â½sBÿ…oý‹àÏ|LŸÃÿð–ÿnÅqö»ûH.“Éû'–²&ø¤ówe”cnI5(Ú®ëÐøgÂpgÃö°ýšäùÛî>Ì’|÷´Z7ðO0Sø”Z×ÿ¯ú}ûWúWúîþÝ·þ^íçÒŃYƒ>µ‡ì×'Îßqöd“ç¸Øä}¢Ñ¿‚xñ‚ŸÄ zÖ¿ü}Óïڿҿпwöí¿ò÷kÿ<î“øãþ,è[4þ'ý_×Ëôþ“?ÚuS}§íždú;ý§Ëòüܶ wíþõÇl×ꥨÛiuÕýäËoikÏ4­ÑAfcì&¿ÿàŸž<ø‹áïÚ·ì? dð¾¡âÏÙßi‰wâønVÅ¢_ôÉ$+nC£h1Ávî?O~ü{ñßíð à‰%×áÖ¼uâmCOÕn|-gm‚Þ×X‘%½K•]ÍabC½‚ ñ„®Óåßúþ·=(ìŽ?âÇÄï øðëßl7sjS¸–ÊkdW†R@V;“pØnŒ1l}3û5üMÿ…‘ðÞ×ísùºÖ—‹+ÝïºGÀýܧ,Ìw®2ÍŒºÉNÿ…7âïú.ß?ðÃßüª®VÒ|að×âOÂÈäø§âiºÿˆ.4«ý7[²ÒˆiÒ°kkdVÚÄrÈ æ¿?áþ«‘bªâ^-Ôö—rN6»zÞüÎÚë·WÜë«]UŠ\¶±·ûLþÐÿ³_ÃËO]èw ´“W³Óf´´b™Ry64‰¼mfQ’Š8Ôr;ßøãBø•á=7ÄÞÔ¡Õô=F?6Úî€À¬¬¬#«VF‘••€e ~Bü@ý´~(þÑþð~ãÝ#ÁÖº¶4ïØÚé'-xiÞ\Þtμ´S¶ÕƒÜ>eßð?â7ÄÙŸM¹Ót–Ó|Yáfº–çû Q–X2À’Ö÷ ®mw;$CÈÌ>QÉ$öuñØl-ZtkÔQ”ïÊ›µíkÛÏU¡áâs,µ<>&ª„ê_•7kÚ×·Kê´Ýô?J(¯4¯ÛóàÓXE'‰uûêÚo‰í  û²ÇæA7Xù2¾Ðêk¢ßü7×ìúÜCñGG»”ð–ö‹4óJÝ•#D,ìzPI$ 5ÜzGÐãP|yð—ÄŸº¯Á«}.?Y PŸY¾œ$º{<3Û[M§ì`DçdKüTÆw¸•bùóâ?í‹ã¯ŠV·Z_ý_h3¡üC¬¨mZT!rmíÕ¼»fÃ6×™ÔŽ`R3_,xÆ_> þÐ^5»ø]iá'—ÁŸ/õ‹äñBÝȳY íî.vœ4—-"! ìn»d渣ÃOð‘¨D›qNí%ewÛu¾ý:žtsñO ±uRrqNí$Ò»KmZÞ×é³?^|Gá=Æki¯hÚ~·h¾fØ5T¸AæC$a\óC4Ñ·ªJêxbÁ~ý«¼¢i^$°ðgì«oo¡j’O¥ê‹¢®•mk©¬/,“G„2&Lª‹ÑÛŒ1Éñ[þ 1â¨< ð‚ãᎣðßÄ>,×ü%©x‹Åv3ËtºT¶ZdwÒÀ#·¸ß ·h©.IdPYv³Wš| ÿ‘3Pÿ°þ¯ÿ¥ó×ièŸNü7ý¸4¯ì>ø§áV©¢ÂKͦÍNæÊúÖP-e™á¸\ü RŒÙÊ‚0ÙÛñ¾æÇá¯ÂxûLÐtyüC iš‡‰íe»³V¨A§ILåv¹c   åeÅ~_k?õOƒ´î“ã#Ã_ð—]ø}¯5Ò>Þ¶^lèwm;ù̬—™&6’Þ^Ð2¾‚ý§¿à :OŒ?gí'þ Ñtë¿< ¬\k~›â›v›ÂʺXžq:ˆÉvŽ9.Æò™³(Žö¡ûGüu¼û7“â_ØyS,¯ö Ý9FsoÔ[ {•ÚÜp¾–ýšþ2Ü|køpÚŽ«ko§øŸI¾›GÖììÖAwQí`ñyƒ>\°Éê2ûp…Ù‘|{\Ĉ>;ø¥xâ÷‡^—H“OÔ㸀ÍAéyåïTií¶¹¤YY¥c_„p·c1õ…Í*óFzEÚ*Òé²Z=ºëo3ùŸ‚ü@Çâ³5ƒÎksB¦‘|±,º_•-%·]m²¹õíƒÿðïìéªÿÂá}2ãÇ_õQ4íÂ#46·²-ºÝl`åœ>ô‚0dp,JŽ|Jøñöqø; ëÿõÝí5ØßXÙÅ ±ðãɺHà_,ˆ¦T6á *Û;CÛ£KÐ_²ì]áßÙ§J}_Z—LñïÇ].5{¿ë™® ••me‘XâÝq²Y™$3nq†H“ ý¶¼9•û+üuÔÅö£u.©¢´ÕÛÉol±Ä‘„‚"vħ í–g$’…ýS?Ëðùž¥ñ½“iõ‹I´×ŸèõÐý߈òlo”×§ÒŒ¥ o̶iô¶ºÙ§g®ß'ü)ñGˆ<#㯊é7Ó\iú…ùÒ¯ôK»ÉVÊH¦Òôñö˜ãT¹‡Ú|ÄÝcrIO‚ÿòG| ÿ`ý'JÒð‚4¿®©’’Ão¨]‹Æ·wÝC"8û‘……6§Eè¸Pª3~ ÿÉð'ý€l?ô+ùŸž3 ìÜœ¡OÙÆ7Vvå’kï]ݽãLË5­˜`#FU©ÑöQ…÷K’W]t½ÚWv¾ŽÇa§kWÞñßµ½"åì5AâM'J7u{KÍFÖÞꇎHß•`@dŽA‡Ž6_ѪüØ¿ÿç‚?ìsðßþžlëôž¿jðêr–Q5'tª4¼—,^Ÿ6ß«?¡<'œç‘TŒ›iU’^K–˲»oÕ¶|«ûÿÍÆÿÙfñþÛ×ÕUð®ð÷ö”ý›|Iñ&oê_…|cã]SÅòx•u‰®£k—R±¹·ˆ"‘iòóÎü3Åïø[ÿµý¿gÿüñÿ_s‰ÎrÌGGЧ ®’œSû›¹ûb§9+Æ-—ì ÿ7ÿe›Äûo_UWÍß°·Ãoxá÷Ž5_ê¾Ö5OxÏRñY¸ð¬—b¿hXUÑ<ôGeŠQƒ»oÌNkéõ)Ô…X*”Úqjé­SOfŸTÈjÚ3’ñÃ}7Æ^!ðέyĺ%à»T 8ª·– Ù!W‘Ãî:ÚøÿöK°ñ~¹á¯ƒþ#ƒKø§}§Eµ¾ñ6»ãVÃ[‚]5¸µ¶mB墕îÞÖuccŠU,›ŒRíñ×áe¶½§Ùxûà ´/ˆ¢ê{uyxóA|óXÅ$“31l†Û©žW/É—1åK FŒçRœRsw“îì—ä6Ý“>À¢¼ÿâߌuÏËàíÃo§Úk^*Ö›H·ÔuKW»·²ÙcwzÒ=ºKK¹lš ¢Xðe– ±¾ðÏÇxÂ÷ ñ Ÿö½þ•¢üL×®ìWY¹•7éšüK¤r°Th•Ä’Éo½ ZD~‘`Q_?ë_¼qà)üOá­noë¾$´ÿ„oì:ÆŸ¦OcgöΩ.™›h÷3<Ÿgx ͶtóUÄcÊ+æ7ÿ|uðöYkWV÷!¿ø‡-ïltG]´±‰|1i}æÁ¦@Âá–_"F6ñɈ^îG2Ì"f”ëZ+Šø7ã-[Çßôýg\Ò®4JI®­ž+>ãOiÖ™aŽäZÜ, :F³¬RndYUK>77k@Q@Q@Q@|ÍñWþNžßþÄÅÿÒ篦kæoŠ¿òtöÿö&/þ—='±pø‘£EVg QEQEg|*ÿ“§¸ÿ±1¿ô¹+éšù›áWü=Çý‰ÿ¥É_LÖ‹c‚§ÄÏ€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ™˜WÍß?ãÇÅÿî]ÿìÕô|Ýñcþ<|_þåßþÍIìaˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Uñ“þJ/ÀŸûîõÖkÕkÏþ-ø;\ñ¾Ö¼6š}Þµá]iµ{};Tº{K{Ýö7vMÜ$R´[Võ¥ "“& ˜PûÔð·Æ½]×m|9«Úê ñ}Îï³øwı¤[TÈße•íï6Æ¿Ùe—Ê¢_-ŽÐèWã__iz¬^ð®“oâ_K»6W­giejY”Owp±JaWdt‰V7y][jìŠy!ÉÒ~'ø‹EÕl´ïˆ~·ð¸¿™-í5½VžÓHÁ!¶–gŠÞhg‘ò«¾ 3B‹3K*E@—_4þÕè¾4Ðç›÷P^x/Äš=´¯ò¬÷Ó\èòCj„ðÓIµÃ¬cæe‚RÄ}-^%ûYxnïè^+ºØÖ>ÖSÄ·‹"±Xí–ÚâÚk“µƒ0µŽéï<µËMöO%Fey§…ïu¦ÐÓç];T´y!ª[™ŒhÓ3bDWs¨bµ€W¨9~9š;íNMcûgZ·Òt+o´Ko¡Çk,×r’<¨-„±>û™¤h¡Ž2À<Œˆ'œ&¤¯kü­úþ§«‡• 8:Š ×O›Úk¶¯–ûì¹l´w[^çŸÚCGðWÄoŠZ‰¼YðÓFº“Å–ãT]SÇqÃ<‘¦[Íä£Ûþÿiƒ1âe–#/{z®­û^|8‡]³‹Lø™ð¦ïFmŸj»»ñí´eˆ}¬n¯…Á‘2IhàÝ=~hú^“㯉0i>1¸Yu¦êͽ®›ªOq}qwªI vÏ{§]]ª˜ 6Ò# *ÃÖ|Iñ.™à½VîòyüKk©[Ãquoh/ïn¡Ò Ï2êZ RKq§Îñ¢Ä“B¢²;Gr L¤¢ï-­»WùÙ=úw=9P£:´ù)]IJܱ©ÊÚꜧù~ÓÑG[¦µ1~%üqø#âv ¿í¯1Ùl±}»ÄÞ0±Žâ<3Ÿ-GÙçùrñË7Ê:˜ü'ñ'ÀžÕì5}?PøMá"3æÌ4‰”ˇœÙÇm´Ï°ä4ƒ'j|à*•¹ñ—–ºü·Éàïê÷ºLw—²ÜøÿTg‡£c©”Ôo›Í˜Üir‘!ŠØùb£6²Z¼Ó|W¦xpé‰âÝ/áÌZ3^j/ ¤k3xfÙ’üAwróê^\Úq1H±ÆÐ° Xm 9µÂ¥):­Å~ ói~lõ°˜ÚÀ*u§£MY΢î¾N¥×“§üÎâÆß€¶Ÿ¼ã9~ xfù¥»Ž©é^0Ȳ(0ª:¬oÑ‹‘$Š.mÒ@ò—Žb[Î?l_Ú_Â~'ñÏ„¼?ኖþ)°’ò=NïF°¹Ó¯t“¶)RæE"HïÈ“˜¥rªÆ9ƒ)…U¾¨ñ¥­Ý¶¯Ö¯áäÓỼcuâ ˆ[DY$¿êšƒCªFeÓåkdÄ ´J¬£Ê]ëoá´†˜§ö€ðd©n!ú¸óÚ^Ÿ´êï&§‘<³ùòâÞeûQµˆ„ò‘nóE©€ÀUÄbãJŒ¹\¦Õô¶÷J×Û¾¾Göþ:51tÝUJœ ã+I=}ÞW.n]í~[ÇdšV>iÕ|WªøçWÑ4-nÕ?±îµhÄWÚ,§s”I\&èætYÕ”üÅ¢XÚDÛ"Ç,{z'ŒuŸˆ6úçƒlä»3ØÜ3RñD,‘µ¬m– cmŸnPXDLq´‰) sl¾¥­h¶~!Ó&°¿‡Ï¶—i 3#++GGRX++© ¬¡SXØÛi–VövvñZZ[ưÃoŽ$Q…UQÀ+öŒU‹Ã^5±R¨›Ý¤¿—m»;ÞÍ¥müÿ8ΰES €… ,Ôe6¯f¹­t“Õ6’³qNÚÉJŽ’âÊËL³¶ÐæÓm3 [ #³DE*Ž@&à3¶§·Ôn&û&ý.î;™æ4'ìøé¿l‡;»lÝE{Ñ¥(Ùs½?Ãååäþ÷n–ùÉb)Êÿ¹Š½úËKó{¥Õ¯ü±½ýîo;ðäÚœ_|GZZ[Á6¦]ÞEÓ2¬í-ü~j, ’˜í!bA– +¼ðÄ;/…_~ø›Å:Žá­:ù5/êÚò¥¥´SAöµ>lžXVitè;qó²lbêéÈë¸øÃáäýÜhú­¢Jü+NÒØÈ±йH&p½JÄçS_Þ_iè¾—¨ÛèzŽ™â *å5›¸ÙáÓ¢ûl)s<ÛdŒùÙîß¼@aiU™U˜×ÏæiTÀb)9·ËwÓ]§ÑW~V¦«ÂJŒUüå¥ù—Ytºßùc{ûÜØ¾)ñ§ü'ÿµŽõÛêvº6¾óÃúÏöŸÉöÔLâ%ò¤7 µƒ›£ºƒ}›Îµ¶vï?eË7—ýÝ™ŒoÏ|íǽIñ#ö¸ø®¿cÔ,se¥·•©Ý}¦VÌ·çÌWó$ÄOñ¦á²6DÙß-l×ùéÆ,ûš¿Áÿ¤GúùËþ"â¨ÿ¬Øµõx}o>´ÿÇm9•´ÿ—p½ï>zþñ~—࿌ÿõÏjš_†4«]jðÜ_Þß,v°»i‚FYB*†ßŒœ|ÛT»#êí;ö¼øq'öGÛþ&|)¶ó<ïí/³øöÚo³c>W“˜ÓÎÝÆíÞVÎÛëåê_Øÿ~ßÿjéúÙuNíMYwYÙíÐ5Vó§dy‰1¹‡˜Ÿ(?2õbêú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_迯ð¾M´÷¥ù£÷¯ 1ªpúq£ÞsÙÏK·ÞOk¤¯†7»ææüŒýо7Ýü&ø{©éZÁßøþkZ¹´}KOÒÍÕŸˆ#kit;ËPŽ’a!–Tq#IÍ,‚7ˆÏÇ¥~Å¿ôÿ‚„|Iñ‹õð ׇäÒeƒâ&µ7vF²‹ìïq*¡štke@²þô¢»É#ÈŒdÓÿ‚_ÃöÏ€Zþ›ö=CRþÒñ5Âÿa\Ýùzç‘ki?—§Üy‹ö=^ÛgÚb|Ãæ¨ûÿèÿh°Öøâ?µÁOþ/k¿ð•k}‹Á’Kÿ mì_Ùöº•g`ž~¯içÛîòvùWa1p y6Þ_î?CQÌÿ//êïÊß«:Ðwµ(­ÿ›ÏûÝ.­þ{ûÜß]øãöÐÓ´mD·ð´žñÇ‹5Xf•tßø•¯`7ÉW&d·ÚÖáãa+·–Tˆ%vEoŽ>*hþðÕߊµ9“Rñο¦ß_ßI,Vpy’ëÓÏ䤲-½¤nøf%6Õy¤vS%uŸ®%Õ¾èõì¯w­köVúÆ©}3–îîhQ䕨òI8tUUUU@‹âþ³¨øsÂVZ¶ \jöþ‰ug ‘‰I“UµhÔ¡’0À°DÏMë÷‡óVcĘŒã9¡†¬ùhƤSWÝs$ÛjÝ?ϲ_·árZ~[WF Ô”$ÖýSi+·ÞÛì–îí¶Æ=+Føµâ)cñÆ…âÙ¥ðÞ™6¡s¡_Cq§ØOΣæÚE*à°…í&´»ÊIJ$I{ÅŸü7àØ´Ã¨j–ÿhÕ&ŠßO·I©%Ï”³X©lŒ‘¬ê9®ÆÓm3êñ­ó?Ú%Ä3#Ì¶ëµ QùÑð †.>ºø×<Å`ëdÐ|°Q[^ûiç§©üâgâ¨c§•РÒm¶îÜ“×Ýåµ›R[«¥tÕÓò”‡Á¯ƒÿh3âíRÐërXêϤxNòþÂ'‚æ/ÛmÉ$bŠ7Xää|ºÄÐzLóËömúuÌ>víûÚ#äc¦ü9ÎîÛw{â¼sâ ½ö·àOŽVÚ‹ÍịBßETÛ_aÙq1ÏïJ*'–¤FÜÿ3l1ûwÁ=*Çã|þ1½Öä±Ñ¼/áYÌ7–ZÃÄÁU¬ Ü7ú½³Ë Ǧq´À¯æNÙI|˜¢¸Fá©|GO€ÀÁGÙÇßoK^®÷Mô¶ïmm·“_O‹éeùfY„§N ÎWšåæ§Nò^ýånh¨§ÌÛ„.ù\ïðão€Óý£ìÿ¦}ƒÍ¸Õ>Ù{¨'ö]‚ý«ËÔ.ò[KöGØÃ-ó è›%òÿ3¿h½/Ä^ ƒãÿ‡~ ¾añûâ.¬Ýiú]ÈhfYmu©Þ{ef.`ÅÜnùM¾Ö8¯YE­ÝþïëþÐú •a4Ôi¨úswzjßt»Ú+­Ûý=Ó¿à›³•ïöGð'VÓþÝçyÿhñ%ÁþÏÙ¾vÍE³æ•æc?>Ê4ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì£Nÿ‚mþÎW¿ÙwÀ[Oûwçý£Ä—û?fvùÛ5Ï™ü>W™Œüû+Ö>5þØZ'Å3áìö¿ßZÔ>ÉåOzÁ·_´AªN›˜¸nFº yx±X§ ÆoÕ¿ÿår…üÏðòòþ®ü¬:Ðwµ(­ÿ›ÏûÝ.­þ{ûÜØ:wüoör½þÈó¾êÚÛ¼ï?í$¸?Ùû3·ÎÙ¨¶|Ïáò¼ÌgçÙFÿÛýœ¯²<ï:¶Ÿöï;ÏûG‰.ö~Ìíó¶j-Ÿ3ø|¯3ùöS|Mã_ÛCºׄô˸¾Éqâ]Mô«6…u¢±Ê¶W7…¤% åÚH2;™0IÃßþÚ¼á¯é‘|ƒM×ôËmVÖ+µÖ–dŠx–TW ÌpŒçõ¡Eÿ3ü<¼¿«¿+´íJ+æóþ÷K«…^þ÷3´ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì­ïøÍïú·ÿü®WŸüø×ûa|tðÔúÞƒkð>ÒÒ±nMF=aý§M³Ô#ÀGqÄ7Ыsë0¢ÿ™þ^_Õß•‡Zö¥¿óyÿ{¥Õ¿Â¯{›¢Ó¿à›³•ïöGð'VÓþÝçyÿhñ%ÁþÏÙ¾vÍE³æ•æc?>Ê4ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚă¾DçÍÕ-ÛýÔç!Uª4å&¢›oåååý_ÒÑSJ1”åN)küÚ|_Þéuÿ€«ßÞæÐñ·ì7û-ü9ðHñWˆþkšn—r½à> ¸–K"$I QmÍ3²ªyeÀ, †0 ÿÁD~ ü'ømàÏ‚þ'øWàCÁV~,VšâßT¹¹–y’µ9Y¦”*‘#º”8e‘O—4r.h/â±¹¾ÝòbC#1RW!ÁU'nÒÄ·›þÚ^9ø§ñ¿ÁžÔúÛÌhüè%Ô5HäMÈC.U˜eH#<k«øñçÀ¿~6~Ãð¦¹ý«­x7Ã:¦Ÿ®Û}’x~Ç?ö QìÝ"*ÉóA(Ê/\Ÿ®ÿjï øWöøájö÷ÿü ã”ñ4Ú%ݕϓÅu¨My6ª:“4T“vô âÎcïÝ;þ ·û9^ÿdyßum?íÞwŸö\ìý™ÛçlÔ[>gðù^f3óì¯Êߊ~Óü%àÚCÒt¹´=+Lø©¥YZi—‰d³†8¼B‰ 8wÜȪ¶÷ÉÜÝOÞ-ýµ¿jüƒâÕî•ð~_Mae¨­­½¾ªowMÆ ™‚neÜ7à`àž3ðgÇ mì4ŸŽš?ŠõüEÕ~)Åw{£èÑ]y*mWWK©ãy#Ø 3^¢Æ­!”…bÊÄS]ntUš–ÐQô¿wݾöôK­Ûæ4ƒZ.©¡éײÝ_¬·6ÑÌá$@ ²‚q”éÍ_ÿ… ÿÏÞ£ÿcÿâ+‚ÐÆ«w¤ÛM‰5;[xW7!´UfC20Fn àðjÿØ5èããÅZŠù?¼ºòe’]¶çî\ŇýìGøˆÁ^à×J·cÃ’©wûÃèø'~…oá¯ø(§Ãý6Õä’?´6´Ä9Ò.Xç¤ö¯ªaoØoàÅÿÙᯊ<]ðÆïÄšî¹ý¥ý¡®C¬ÜÛÓ{q^dkwù‘•r¹lgqøÃþ ñã /Á_·u¿ø—OÓ´Ë7Ô’ë[Õ/Ò+a:ê4&if*ªIç*Q__~Åþ5ý¦|+û4|Ó<Ây<'â]ORÒ´Fñêfú9UµÉšäÂÁæÒà)@OÍ#–#k±êR|©s+éçÛ}-¶ëÏ{­ ´ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì­ïøÍïú·ÿü®W?âoþÚÖ¼'¦]ÅðKêo¥Y´+­ŽU²¹¼-!,_.ÒA ÜÈ1‚HÍEÿ3ü<¼¿«¿+uºÐwµ(­ÿ›ÏûÝ.­þ{ûÜß™^ÿ_Á/û-ÿõ9º¯¹ëà?x§Kñ|0°°ºûEÞ‡á›]?PËeò'o=ÈL~êæÊä|øÎAïÊüOÄÏùƒÿ¸ŸûaüËãüÀÜ_ýÆ@Ö6ÎÅšÞ&brIA“IýŸkÿ>Ðÿß±V(¯Ç;••YàOüÏÀVcв¯;‰ÿ˜Š¡*€ªx¾‡ÿ%Ûö—ÿ²­ÿè0W´×€¿‹4? |vý¡¿¶õ?FþÒø/«i¶?ÚIÚ®¤X|»x·‘¾VÚv¢åŽúG‡M¼Þ«óíÿéP?\ð¹gµ›ßÙKÿK¦t_>øWÁß ¿f O@ðΡêZßÁÿ\ê—šm„Vó_Ëÿ’·™;¢ƒ+n’C¹‰9v=Íoü ÿ‘3Pÿ°þ¯ÿ¥óךüSø“âÛχ߳¼<ð5¿Ãßi¿ +ȧÊøˆEÂZîùmy)}×M-ãÆø7þ(x4¿Þü°Û[­®|~íä1&mýÛ„DË/IL‰€$H{;ëSÃÚíÿ‡üAaý“â-;oڬĞb26ï.x$Âù°Iµ¶I÷]RHä Ñ|£|AøÉð§Ãþ °MKH½Öïh™F‹©2::ÑÈŽªé"Èʬ¤2‚?À嵪ãÿ²1 ’RvwÝI'gç¿£ON.å¹F"¶h²,Rörœ¹]Ö±’NÏÏG§F«_ÿÈsÁö9øoÿO6uúO_žŸ~ë?þ!x EÖ¦}KK½ñ·‡WEñ" ¾X´cÁ@Xîјª€²ª´±X ý ¯Þ¸+.ÄåX*ø\Tm%Qú5Ë 4ú§ýjNxw”âò\»‚ÆÃ–q­/F¹!fŸTÿà;4Ñ“âZø«D¹Ó®•H‘IŽF\˜¤ÁÚã‘ÈϨÈÈèM|§«h÷¾>ñ‡¾CfÖ$ÒM­_[(W[d%|Är7¯Ì¥K˜¹äרU‡gàÝ.ÇÆ‰¢ƒþ&×öÑZK+`íHË”ã+»+¸ƒå§/ˆxG žãð˜é¥zoÞþôlì¼ìöÿ}úý,D©BQ]MkKH4ûHmmaŽÚÚX¢†‘ UUSQE~€’JÈä2|'ám/ÀÞѼ7¢Zý‹EÑì¡Óìm¼Æ“É‚$Æ›œ–l*–$œrI®VÛà'-<+¨øn- f‹¨xfÛÁ×6ßlœùšMºO6Û‹îVêqæïå‰ @¢˜ÿ|£|AÒ¢°Ö ¸d‚asosc{=•ݬ¡Y|È.`t–(ò!hÝK$’!Ê»Ïè_~xkN´Ótß éöÚU­–©¦Ã¦m-f¶ºÂ\ß[ù Lf)%»UFÄ „­zçúwÀiÚ¯¥-CQUò~Õ{«ë7º…ùòX½¾ËÉæ{ˆ¼™ K—"ùR3IÇbÆ¥—ìåðûLðõþc¢Üiö÷º˜Ö滳Õ.à¾þÐû:[½ÚÞ$¢tžH£Û$« i|ÉŒ…ÌÒ—ôº('ÂÞÒü¡Zèú=¯Ù,-÷V‘¥wwbòK$ŽKË+»;¼ŽYÝÝ™™™‰:ÔQ@Q@Q@Q@|ÍñWþNžßþÄÅÿÒ篦kåÿŽ«¬èŸ´ ¦½má?øƒMo ¥‰—DÓ^ä,¿k‘ö’0ŒçæsIì\¤›6(®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿЍ³;9ãÜìè®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿŠ¢Ì9ãÜìè®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿŠ¢Ì9ãÜè¾ÉÓÜؘßú\•ôÍ|¿ð)uoö»×®|'âé«áw±ëzkÛ—íq¾ÐNAÊ’qœü§Ž+ê µ±Ç7y6€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ™_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQE“⟠è~9Ю´OhÚˆ4[­¿hÓµKT¹·›k]ñ¸*ØeV¨­jå~%üTð‡ÁÏ Oâ?x‹OðÖáö›ù‚y®¤ò¢_½,¥cr± gm§j“@§ìßû¿j×ÿ½ñmžµ}câKÙ¸ºÔoá”Ä/¦CÌ_i·Kkˆ¡û±[ÍoD‘í~!j~Ñ|â]CÅéo'„í4Ë›a.íÌ-d±3N ¬d_,>SiÜ20sŠð¿„Ÿ®õoÚ P›Rð¦¡à+Oè¶÷6š.»soïk´WWÐÈâ;›ÈfºˆFäL"ðã¸!K}OÚOÇZ_ˆïGÂ-{OÑõë«(¼M®\ë³ØiÞ·™¤ž{µgŠ;‹i¥·[)`#îÝØѲWà§Åßi?ü!¯x›ÂúÆ·á=kLƒV°ÖôY¥Öï¬-nPO ­í°Œ]LЬÐÚ¬ð‹§›Éyçò75jÅûl|(›J¸Ôã¾ñDšm¾™µ5âø\0ŧȲ4wlÿcÀÖJÊNÒ#r Úqæ¿t/ˆv¿<{ð—H´ð~‡àï¶Ú¾¹â{á?] Ÿ6ækÐEöeÞÅdâ0‘ T‘ȸ+íz¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú(Í|Køm¡k*𞵤xïIðÿ‡í¤×4ß'õtƒJÒ%réiw[,‘,2G~„[¥¥¼Iæ—‰Ôu:‡†t?ÝÛéðéÚ†‘à] Î]kW¾ñ—ú´óÙ¬nïô©®a˜éÑOetÎ'Šh­Ì,ÖÿhqíÚ¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢Ì¢¤­%tkJµJU)IÆKªvz0tß xcáößü#šv“àO²}£SŸ{EöVµ6êz¦ËôûF›&È·8ò±Ò?/ý{WÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE#h« «Z¥yº•då'Õ»¿½†¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è´d¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú/ÌŸî`Ô¿hßMgo¨[çi¶Z=Újw&yRño5× ÆGýÓA¨ZM µ##ÛFñGôÞ¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þ‹ò\ÆÒÿâ‡ÅmgO7`Ôü]yå­ýÃÍ2Ék6.Í„7s˜Ô6ՈĠ Z}_ Óö™Œeü©¿Âß©æf2åõÞßæ]¢Š+ö#䂊( 'â?ú.­à=N_–ÊÇÄ ö‰zìóí.m!ã©Ý=Ì À8ß“… F§ÄoÜø¿áï‰ô+7Š+½SKº²…ç$F¯$LŠX€HaœqØÖ_Æ_Ü|<¾Ô[˜4{‹=náGÞh,•S±r8PHˆ’6µÿÿ»‹ÁGSÓô[-BÊïPÖµMYwYØèöÈ­w,ãÍ„´Nd‚Ù¶Mˆ·fUaå1N.½<-:ó«ðÙ7ó¼mó²·›:©BU%ïoÔô­oáÁïÚ;Fâ~­¡M¦\k^‹U[w\¸‚ëD³—ûBê KTú²,–o€±F„=\x#ÃÞ3š[«¯ C¨-½Å­ÔÇq ÒN 3†·ŽA4"9£ˆ†ÌHöðÂÿüÿ‚ŽøQñ—Ä_øL¼I©|2¹ñ ߌîtø´;LÙ"Ú¤×ö±]Ä“[F–¨ †åž7! fdÒºý‡¾_ũˤü‚8¦² §<º¾³p ºhie+v¾t\Ãû¥òØyr~ðï_]ðKá„?õ½_áï…¬|ªiúÓͬÝkº…Ŷ’¨²yòê -êGqo»ìÇÉ! 4LåÇÈÑ|n ² Ç.Ï9;$¡=ÿð/WdމaªÁsIiò<Ãàü‘ÿØ¿§ÿé4t|Yýï‡ô›Tùîn.ø:ãYÕ¢ÑôÍ7þ#¾ŸNÕ.~Ñl%Õ,€¹g“opP}šªPFÑ!‡Ì¼qá;ë¯øGGñ|QéšÎ¬¯ƒoãÍêEÖ‘Û]ßBÇ(²™®|»yå0îß)ŽßÃã,³ŒÍ«b#ì©Â.R¶‹M–×zí=àŽ?ɱXüó‹„£Jœ\¥m–ËdåªÒþoMFü;ÿL½ñv±ï4Í_W[« ‘÷n![+X|ÅõBðɵº2€Ë•ec»ö OŒmý½§Øÿex™u6Y¼¸´<øvý¡©§Û!óì[ËØ±m’&}ß/™oÀ×¥þË/}¢øWÇÚìú¥ž™¥ßjÿð’é7·ùPéö‡F6ÃWÔ#ûd&ãN’K9R$*|åfB“Bü?”«fõj¨ûª½,à’o»KÊövCð¶sÄgµë¨Ú*/{YÓQM÷j>W³i#Þu}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ô^Mø'ð·áŽ»q­øsÀþð&³ ý³SƒQ{Xî© y°êp®³{p÷›¥²+ýš'ÉN#â×µø™ñ[ÿ 4«ÝCÄ~(·ð}½”×76©®j&y¬.$]U’îæ%ÔßZ\[ìÖ1)ÀTC-|~ïãŒþ$ý¦m3Yÿ…-á(¼Ûí6ïWÔ쯼E Óý¤ÜO} ú—‘om äÙKÃ,Z=øÒh-•<§ö¿ýªü]û,ë>#Ðn>*|@›Ä“è¶w^Ó/4ï~öi/5('º¹–-9“ìÊ––²¤jVfó¶Â\Á䳿À/h:WŠ-õÒ>)øÇÄ~$¼[]:à].¤º gºÔgIKCoÍôæÜÑEx¡ÕÒ$ú×àÀo‡ž ý¦üm¯j^þÒÖ´{- Z²Ôõý@ê×p_‹fÙ³;ß^1–ÙaŠÒEivý£N2$h¯ÁÝ_û þ;Ïí/ì<|ð?üLîõ"Æ=ŸÚ“þö/í O3Ëò>×'úÌÚXßÅòùøpÆ¿o?e=+K¸‹¾8Ѿ\xƒQký.Êê—º[\.­z-üéöâYä¾O°ù“³/§j,òª¼E~tøß¾=üRÒÿi=cân¡¡L|MyàÝ3P4û›Ñ/®ÚêqøÁãÏ…> ñfŸqâO]x‚òÖóIÔ5“yöUþÂÕa r«tLêÖ‹n³*+%Þ•©Ì²)¸ÓÇv–>ñÜÐé‘ÛøMÑþ0[›W·u´²Ò¢ƒáúšU[‹aöH’Â%@ðÅ$`6íŒÅè^ñÃ8hox[â'Œ4mkAðañ4·Sðj7ï}â+·†xÂ]ÃÙçó-eŽÔÛ«OÓ„ÕÊþ!kÿ·wŽümáïüLñ³ðËá·†uOÇsâ‹{H¥ÔÞÒ,c·³µ¶Qæ4‘Çœ ÇJù í}™¬kv:LJ?kø­.®.gÓ¾Zi÷iu«®£%¬±Ûë€ZÈÂöì¤ðFc†pdS%ÄSͳ}ïÚ3áW„>è^)Ñ|áÍ?Ã:UÇÂoˆº„¶št"$yæm!È‚¨èˆˆŠT{çì¬uGâ{ÏŠž8¹ñdYËk®4Z:Íl¶Ðj0¤ké⬚µæâñ³d¦mçó/Äügû|ø¿ágÀ]⯈/-ªý“¿äÖ> ÿØ™£é 5Ê|køUጴOÃMƾÓüM¥[øg_Ô"´Ôa¢O¡ ²8ñVу#²ˆ?àŸÿ ~ üCø¯¦|fñÅ]bÇÄ?¼?â ¶¾Ñà´–ìEc¨é¶Å%7vóDªÏ#Š(À „+€Æ5úâ¿ÃH¿cïƒWž'ðÇÅxKÃv7¾µÕ#û&—{Z¡Ó4‰®q&Ÿ$¦Qg¾•ó!0voŸòX¼)ÿuKÿRû*ô¯Ú³I±×þÚi𕾣¦Þø·ÂÖ×Vwq,°ÏøƒOWÑ ¬¤‚¤A Ðå·„õŸþÜ_?áe?Ä/Aá†Þ&ðÍ–ˆºÌvMª'ö†³¼r¬p[Gf’ü²Lìb“\0™WzþšYþÊÇNñ4ž'³ø©ã‹oO5ä·ZâÅ£´×+s ÆÑ¶ža ©¤Ùí)¶CåŽî<«ÆžðïÂÏê¾ðž“o¡ø{J‡ám½°;c_øL/I$’K31fgbY™™˜’I?ePâ·ˆþ5øÏöùñÂÏ€º'Å_^Zx‚ÊÚ÷ÅwúÝ•½—Ûã´ûUÌVðZZA,‘@c˜*Í#,’¬x*#Y›íïƒÿ²^Ÿñ‹öfø]?Š> xÂò;éVÖ6ñ 2$Ò£vÓ/¶ÀVÈ3bM:ÙAœÊv+–bÕWà¯|?øwû'k^ðæŸ¢ê¾(½Óu fîÎ{8ðn¦¡ÜÿßM€^I_ävo ?dïù5ƒö&hßúC 4Ü]ÖäÊ*IÆJ韚?>\ü?øÃ㯠YøÇ^½Ó4-JÎÎÕ¯c±2°–ÆÎà»”¶PYd¹r¸aTÜîöÏØÇögÓþ-¦¥â¯xÏÄóÜøCÆv¿c²ƒìÛÏöh,/âó±i¼þúBÇL¨ƒ’x¯ÚsþNgâçý‡t¿ý4é•ôÇü—þD‰ö9·þštÊûLuZ«.…NysIA?yꟴºzùŸe˜|<±îƒ¥XT®â¹cî´°¶kM»ÔµÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë_÷Gé0ød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•}Uÿ.øÿ ÇöX×âwý‰ÿŸâïøôûGÚþÉcuþ÷Ófÿ3ïüØÇÝ9¯•~<Ê/tÏû¼9ÿ£l«ïÿÚÇþMcã'ý‰šÏþÍRªî½çÇÂsíðý«}¦å>ɾãÌæk ¹h„ËX6Ȉ&µÿã×þœ¾Ëþ•þ…ûϰîÿ—»_ùéjÿÇðä×3áÏØØi:t3j3C,R¹G––ÂBIÆ@ÃÂÃâ'$ä€sWáñf”¿fÛuö³±O²Æçìwž Ž`â…°FNnš±äJ2æz_×õßíø$‡À? üZø«ñO_ñ~áïiºœ61è·ú\W¶m-Ôîââ/3!<µ³t_”’³žFoÔ|ÐuxOHðÅÕÇÃ[ joªé'–0-´¯osŠ!šÞXvº^NHòó¹·d¿ŸßðD9V}Gã´Š! òè̲•‹êp¾€óŠýL¬Al~;~Ò¿´ÇŽ~"kþÏø¯âcÅž ñmÿ„µÉ5[}:ÇM‚ßûZ{;Krö¶ÎÍ$K“:?—µÙ6?˜ÉÙ?±WìÔþøgàx¯üâ jÓÀ>&ñ~ök}8Ï î©§ð-ÍÏÍÓ>Ƹ`Ná@Zw¯i5ÙxsO¶ñž¯ñf>û[Ž.. ‹â!(Œß÷È$rÂ(ƒ"Œ/гOü“­_þÇ?êC¨Ð3Íÿ࡞Ö¼Eð'KM BÕ¼Ewiâ&úK-Æ[Ë&)ÃHÂ(Ô±JùþˆôD¾ á5ªò~¬×¾ý¯>!ø“á?Áë ‹sþ!× ÿÐ'þOSÿ“>&ÿ„ßâý/ˆøMjŸü‡]7ì©ðkþ¯íKªk_þ ß ¼/tо5ð¤ße[‘q`±k»uV“`¸#€dìN~Óøyû@MñOÆZ&Ÿáÿ ÜÂ=¨øKIñ„šÕýìpµµ¾ /6í‡->ëTáXǵ¦&E1Æ“ûz¹oå™Eg_K–MZüÒz]>­­Ò=¬§…2lŠ»ÄåÔ9&×+|Óz6­)5º^gâO‚¼c¥hºf¿à ëšn‰Ù´»=KF¶¸†Â-¨¾\èDK¶8ÆÕavù¿ð'þDÍCþÃú¿þ—Ï_ªµð«ÿ´ÕfÖ5I´ß‹vÖÚmÅýÕݵ­ï…ÞâX#šy&´‹|Ê™ÜAë´gôgÖž9à? è~9ý¹<¢x“FÓüA¢Ý_Ü}£NÕ-RæÞmº%Ó®øÜl2« Ž ƒÔWÜ_µ÷Âê²Ç~ÙàßÝÿÂ/àÍ[ûÏÒàì–-³ì™OÜmò¢Ç—·ZcîŒyÀ¿ø'¦«ðƒã…¢½kþ³âýO ÿáqÿËJ?á‹> ÿÑTðÏþWü´¯æ_õ;þXÿàGñßüC"þXàHòZÓýŸ¾#Cð ãDVSËp|-ñSµ±ž<6:› R+•ÚHVžFµ·eØK†G2D–»dôøbψ?ôU<3ÿ„UÇÿ-+3Ä¿°WŒü[¡^èú—Äÿ Ícw—*ÂqÈëÿAL@àäàŽ+ê8s†óÜG,\’\Û§ú­×ݥϳá.â^ÌáŠq‹¦ôšSZÅõõŽëÒ×W>ŒøÕðWKøÇ¡A“ÿdø‹NÞúN¹^cÚ;cz:e|Ø$Ú‚HK ÛU•’Hâ’?|cªx{ö§øSáÿXdø‹N×®þÕf$ó‘´MWËž 0¾lmm’`}×FT’9#O³¾i·Þðo…<âÛø«Å–zaŒê2#[Üêq[˜ãk–ŠI¥v`$€K&öIù|ÅQ«®øþ&ñ7†|E©é6÷zžãHÔ5›MÁ0V¯Èr¤ª1‘ þ¥ÉpØÜ]sV«IÝ5Õv}×nßz´æ<;ƒÌ1Ø|ÊK–µš’ê¿•÷]º§åtõu=&ÇZ¶K}BÊÞþÝ&†åb¹‰dU–)X¤’DGVꬪF­ÑE}õ•~Љª\hþ´°“P¹´¹Ö¼½CDÐõ…ÒµmbgtâÞÊàÏnVT™!¸p³ÄL6³Œ°Ìoçþñæ¹ i–¾ðÝæ¡a­jþ3o[Ùxô>¯qálh§Shn$K×mCÌXTawû±¨"gÞM{¯|£|AÒ¢°Ö ¸d‚asosc{=•ݬ¡Y|È.`t–(ò!hÝK$’!Ê»Ïÿˆðgü"¿Ø?bÔ<Ÿ¶ÿiilÞÿk}«g•öí;í~o“ûþnï'÷9ò¾JóÿütñǵßKq¢x}´_ü?·ñ–«gÜò\\]:ꬠ˜¢/”ZŸxÃ(FKƒAÏÚ_ÅÚ‚[HVcm Â%°|ñ­÷¼5N+xõ+MOSÑ®žÑY!ž[û‹'™Œk#[™eœ p¥ßnö4?ƒ~ðôz?Ùtû‰n4­NMfÞöûQ¹»»{×µ’ÐÏ=ÄÒ4· öyžç3íA®qíßð×…´¿éÓXi¿d´šöïPxüÆ|Ïsq%Ìï–$üÓM#c Ý€ j(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€>ÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ý|ÿÿ“§ý‹ÿìsoý.Ò«ïú+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmvËâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµ¥=ŽüŸøRõ_’?P袊Ô÷‚Š*¦­«Xè:Uæ§©Þ[éÚm”/suyw*Å "–yØ€ªª ,HM[¬¯ø³Cð>…u­øYÓü?¢ÚíûF£ª]%µ¼;˜"ï‘ÈUË2¨Éä°Mx^­ûLk>1ñ-î“ðûD·°ðÆ ÝêÿüU$ ¤XZ ÐÞÃfna¸½´›Ëž%ºVŠÆÒ#̈ô‡úN‡âi¼S¯k7¿Œ|? ÷–þ ñݼ³xmL•¿ö¥Ì^AmŸq J‚+h`g1+Ï™žØ®»ñËÇ_·¬<%§Â¥ðý•“Ü\øßǰË8Û^ÿdKs ¶öÙ³,—X%ˆÕãË­Ÿ‚ôO뺧ˆžïÊñu…”Ò\ø—Å7©q¥Ã¶üýEÖú5:Dín%ŽÆ†ä â8™XÛRøÁñ¾É™¦Gq7Š¥š{í/EÔo'Ø—žò95ù#»a-”‹ 6ÖD+nŒ*ˆ¼¦k,ÙÓǚγðRKÄ7MKWÓ/u˹µmVáTéu n$Ô5D[«ušÄ¤ @ˆŠ+µcmÅm âe„Œ¯R*ívOkúöí¯cÎŽa†ž2XM:±Š“]“Úý›è·¶»Xí¾)hËâ? ëRøŽãÀך\Í®Zk“\ZÜj•'Ô%½Ä—NŸp°´ ª‘“BÛ#iß'Fð%§¼Mâ?ê¾%¸Õ|e2ÌÞ%ñyÓÖ÷ÃöKäI=鳞ÙF”Ú,±Ú*.&2Lø“{ÛvÚ¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢öžˆjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è¿9|=ý¡µÏø›Æ>/ñ¯ Ãâÿ¦‘â BI^/Lº…õ´+{rÅö­5T–GÿGeV,"U’Ï‹¡ƒö~Þ\¼òåWîÓi|ìþzv30Ãeî—Öf£í$¡íÌÓi_¥ìíçe»>ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ý´ôCWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôPWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôPWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEøÀßü©h ¬ÞxËÚ]Þ¿{{â ´Ùõ‹q%‹ß]KxÖÌKLFsbªX¦v®v¿5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEör¼ÊY]YU„›V×Öÿ¡É‰Ã¬LT[±ñü/‡?ô?ø_ÿ6ßü]ð¼>ÿÐÿáüÛñuöÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è¿Kþ·WÿŸKïgý•ægÄ_ð¼>ÿÐÿáüÛñtÂðøsÿCÿ…ÿðsmÿÅ×Ûº¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìG墟ëuùô¾öÙPþf|ã‰|gà¯xþG…ìÿµtû‹´k[?•æÆÉ¿o˜7cvq‘œuï_²µä>»ø¡­Þéþ×¼O¥Zk±ÚËx­…´Å´Ô~Åu©”½…nìdÝ<ʦ4u’v OÙÖKo}ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÃÌóªÙ”TyW[u¶ßußßäŽÌ6wtý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìG墚¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢üé诫ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è eã_ÅðQñ´n˺·Òî§ŽYáVšh-æuI!•áv\°s¶È®‚_ƒº%߀üu}¬ÞE¡x‘£—\Ô$Õ¦E}1ê)¡ª…½ˆÏa"D @ÿ2Kæ»ef¶í¼umcªèšÖ“©\[éÖVR>¯"kóÅvtM³ßÌ5-@É}ûÍ6sn8c"nOݪ°µÒÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ8Èx3 ‘fجƊV©ð¥öoºùl­ÑØì«ˆ•Zqƒèrüá¾™<7cáËVº{fî7¸±d·¿·]kYd¾Œ]YM´b8°¾_”ƒ@´ùJãźo†u?%ÝÌ_mŸÅþ*’ÚÇÎŽ9n=bñ¥eóUR5ùä•Ùc‰<Žˆ¬ÃíÍ_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýð×€¼=ð–ÿÆš†“2h:¥åýÿˆõífî6“JidÕä[ýG˾eÒX³ù .Æ/#âS4{ùöEK>ÃÒÂÕ—,#5'mÚJJ˶ûžžO›ÔÊ+TÄS4¥~´îûìqŸþ ÚøS>0ñv£iô[k‹Ô’êüÿgxEFÔ'·[ø£¸±’8ÙRGn´ÌÆ&+/bÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ}ì.† Œhaà£ì—õøîÏ#ˆ«Š¨ëW“”žíœÿ‹ÍU(#hÀÈÃõ>¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þ‹Ïø³ÂþŸÆV>,Ô#·°ñ‚áÕnô«ízüÎÞ[Á~'Õ/ÔTK§Î¶È±E…h•J(Üù–9–¦r²š³k{?›å°Íð5p$ãŠÍ­í}mçýjxÇ> XëšUþ¹ñ×L‚Ò+¼·ðï‰b‚KM"Ùà¸huvÎi¢c {gXí‰/&ÙT›/¡õ}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‡ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEð¨?j‰¼yâȾ%¾›àý'S»eñ—‹µ¨þËç-Å฻·ƒûQTÓÞ¾•5¼0G¦\4Öíî'ÑÚ[‰æ˜y0k‘ÛÛ¬>CE:ZÃɇuˆ°RxÖ»oøK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~ÛózG®súež“ x…üKs­[§Œ#†[{ŸøƒU·’úþÐ×2ÅrÑk¨‹3Y3Ëm Çn?°µÔŠ(Òé¼ÿö·øÃâ/…Ÿ#xßãŸðóÁšE”Z|Ú.—à],ÛÜÁ¨ ¡2"Ây9òÜ’œ“)9dýUã_Ø›ã·ÄO´ÂCûSh}£EÔ<=/ü[Û·X^ù?k‡ä™q¿ìðüÃæ]Ÿ)\œøüÇþkgýÁ?öþ¿U(ò¯þí;ÿ Ùÿ ãÿ ÿs/ü!z_ýþßÿÛ?íŸúÏö¿Ù¯Ó?boŽÚ6à*Ïö¦òl<åÿ`Ãÿ öÁ¾Ç²Î[$äÌL˜·žTýáo½¸üÀàóóÿBÅ~ªP¾Ñ>1~Ëß´?ìïð§WøÍÿ ç€uû-[OM#þk=;ì°iºhhÎS$¯ËGÎðwÉmƹOÙ“À_´Oí?ðÏÁåý¥?áÖ®¬µ=>ÚÛþM:çì°5êÇ2n ¾öÓà|”ÊíÀ8-»Úÿhù>ÏÙþæïý5ÇGüãþLOá—ýÄÿôéw@¦…û|vðÖ±iªé¿µ7Ù¯íµ<™¿á^Ø6ßíĽ¾á¦ ù—£ò>\mMªH¯š¿cßþÑ?ðP;ƿǟøFm<+{£j ü!Úuߟ8¸{˜*°•òæ²±óÎÆAýj¯Ê¿ø!üÖÏû‚íý{þ»û|vñ.±wªê_µ7Úoüé¿á^Ø.ïìëǽ±áfyw;ð>lí}ʯÿ…ÁûNÿÃvÃ8ÿÃAÿÜËÿ^—ÿ@¿·ÿǶÏûgþ³ý¯ökõR¿*ÿç:ÿçþ…Š÷ý3ö&øí£hþ Ò¬ÿjo&ÃÁ~_ö ?ð¯lì{,å²NLÄÉ‹yåOÞûÛÌ>þÒšïíû EðkÀº'Çÿí½\ ¢XÇÿfoý›¯ÙaŒeÄ­/Ë8ûÌîù$¶Gê½~hÁ`?ä¥~ÌÿöÔ?ôv›[ЊXF[6¿3—9SÃÔœª-¯’>sñ?†~(xËÄÚ¿ˆuŠÿlÖ5iâ¹½¹ÿ„rÕ<Ù#Š(Q¶© ¸Ž— ;rrI'®ø%ñ#ãÀ‰?´M?âoÛ<9ãiVºÆ™ýfŸhóÚ%o5•Ý3 º&®:Œ“¥XwŸòW~ÿÙJÐô¢¿RÍr¼%,IB/ÝZ{Òi[m·W÷³ùû‡ø‹2ÄæÔiU¨­9;ÚMÞ×ÕE=yc}uå]‘÷oüþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-z¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-~H÷GôŒ>ו~Ö?òk?ìLÖô†jõZò¯ÚÇþMcã'ý‰šÏþÍTb|ñãþQ{¦Ø­áÏýe_£¼-7޾|Aðŵ喟w®ø~ÿJ·ºÔe1[Å-Å»ÃHÀs®Húx¯Îò‹Ý3þÅoèÛ*ýQšîa’£Yb‘JeÂ|mÔ4ÿYXèú „’ø›Tu[e̯Þ£>Y,X¹Ê(Ç?6WùÏâŽm…ÌÞSW•Tík»zß·[­Ö׺;Ö_FPö‰èsßðMÙ7ųÇÄ©¼Qâ/ kÏâìÏ xRååX|tÌS A3ç.6ƒœ6qß±ý­üañ?þ·À‡> ÿºÿ„Óû{íúŸö-®©ÿv°Ïî§õÑ~V_¿“ W¼|&ø{Ã_Zéfi.µ 1q¨\É3Kç\”Ur¥€ù@UU*Œó’|ö‡ÿ“ìý‘¿înÿÓ\uý ƒ–"xxK’¨ÕÚ['Û^Ç™%íŽSþ›ã·ü#ŸØ_ðÔßñ*þÚÿ„‡ìÿð¯l?ãÿûGûKÎÝçnÿ¿ÞíÎßáÆÏ–²¼¢|bý™¿j‚¿µ¿ŒßðŸxCÇ·¾'Ô/´ïøE¬ôÝ“¤2ßHþbﹺ2aYBíÚÓ´}Õ_*þÐÿò}Ÿ²7ýÍßúkŽ» >ª¯Ñ?dŸèv‘ijú‡üJì¼?eì`óOöMżñJXD?{qö+îcÌŽÊÙ@O%öº(Ïü)ðSCð‰týnÊëP–îÇûËIäB‡û_R‹PºÈË4*±àŒ!!·œ0Êö{Óô¯ øIð÷Š1]YxóÆIà_†Vž&ÓV]aÕ&ÕÌÚìßm*Éó@ Û-Y6ÆÐ2EÅöòÿŠõï†z‡ÅO?ˆ¼Q«i¾ðî­5ÝÖ²ÑηWº†¡o{s%áF:}£Gk NÖȉi O-¼q8Íp¼Y¯|G‡Ã¾>&Ö4} þœÚ,o¡ø–úý®4¿øDæ¾hSSºŠ;›˜&™ÞTœÁd­¥ ¼«öýñV»âÏj Õ´­Yñæ«oàÏŠV\6WSËy,Ú~³ke¦0*L“\Å“1i™˜³;±m_ˆ¿ÿábø³Ç à/j ¢øW–Vš×‡îwÛÇ%׉® º–ÎFW·›t{"‘”IšÞ1öòUÌ:·ƒõ_ÝØx»ÅÛøCâ7†ü3¢ØßkWPÁe~Ú!¾™Yžõ¥È vóy Gäy%r~µ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šøþ ;ÿ'OûÿØæßú]¥WßõðüwþNŸö/ÿ±Í¿ô»J¯¿è¯›¾,Ç‹ÿÜ»ÿÙ«éù»âÇüxø¿ýË¿ýš“ØÃüú?ÈüÂø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôG×Ëâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµØ|Ds/Š>»)FitRTõéÑñ\íƒÿ'Oû"ØæŸú]¦Ö”ö;òáKÕ~HýC¢¼/ÇßµV“¥ø‡VðÏ€ôëˆ!Ña7ZýÌzµ½–‹á¨VàE+ꚃ–쪷ä¢K6-¤&5jÀ×|wâ_íÙ¾*øŸOñ/Ù¬žI4VÎÞ×ÃÞ>ÜU¾ÓÆ ~×c7ØàxÒêY¤ŽXÐÛæE¶Ô÷]kö¦·ñ>»}¢ü3¶Óõû :Ê-GYø¨ßÆ´k)Vïb_0=ödz‘Y Ä{•Ñî d}™ZŸÃ«{ÝuüGñÄ?ðø“ùխˆ¤†-/Ârƺ€‹W›N†ý kbcnÒ /#Éó.IBm»ý_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýˆøÁñ¾É™¦Gq7Š¥š{í/EÔo'Ø—žò95ù#»a-”‹ 6ÖD+nŒ*ˆ¼¦k.ßWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEùßã¿ÃÇðoмOã>M*êáµ/i÷·1ϨèÁžH"Ô\¤ŽÍ§Ì¶¤©sºÙcÁ :Y|þ}‰Ça2ú•²øsÔKî]Z]Zíùìþ_‰±yŽ+«_*§ÏU-eÖI}¦·Qëç³óØ¡˜Ü^^^^\jš­üÆêÿR¼`ÓÞL@S$„>ꪪ¨TDDDUDU¶m")aÒüIã ÒK‰®ž—âíRÒÝd–F–VHb¹TMÒ;±  e‰ï[Wò…<ËF¬ëÒ­(Î{µ&›õiêRÍó牣ˆœjOâ’”“—]Zjå°jô;ü@ÿÂëYÿäª>Á©ÿÐïñÿ ­gÿ’ªý×ý»›Ð]Oü_ævÿ¬¹çýUÿÁ“ÿ2‡Ø5?úþ áu¬ÿòU.‹m X›[SpèÓMs$—wRÜÍ,²ÊÒË#Ë+3»4ŽìY˜’XÕú+“™c±Tñ5ç8§{JM«÷³{œX¼ß1Ì)ªXÌLêE;ÚS”•ö½›zêõó;?…_n>YÚxwVÕ>Ãá ]í¢j×O3[øjs ‘F·qG,hÓ˜NÇ`-ˆS•…Qìþ‘ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ~=ÓtÛïj·V•qe`Ö–§PÕu­Q¶éúˆÝºòí·(Û„“d{•¥do™9¥‹êK´ø]àÛ? Xj¯¤XøJÁÚ×/cfÑ£Hõ×TÔÖ;è’]:Qò­‘cX¶ $" -?¢ø'˜ãrûã£xÇHIï%úÛnn¾m6Xxu™fÙŽW|Æ7„t„ßÅ%Öë¯.ÜÝvզͭ_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑD?W _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÆWüýÅCûÏ#û?÷ÿóÓû ^ëößš°xºXì<14~+¢°ê9–¼;¼&®Ž&ÓBK™#¿ñ÷ŒmüQ­Ùjm­A/‰níE—‡®Òêæìm#×vF¶s%È,ÆI„:±oç42[¢vßð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›°ôþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mùªjì|)l—‡Œ-ü3El²øƒÄªëg/˜±EÉoâVŽK4IW“3hšè7À1ðÂÛâoÆ9 öZW‰þx5a…­µo\_&ºì—EìRU– -<ý¦ìyÓ5¬ñßÌ Ôþ Cá›t–_ÜiÏÑZÛÚÝjòj)qæ,P[´kí%Üë-šDðÆ­%Äš.¸ˆ®×à?)âO€k…þ$ðæ©-ÇÂêÐÚŧÇ┾ÕuÛ¨CÚβOnÚ«ÃjÈ––p‘!–g‘ofe·k—CôÿÃOþøaä]Ú C^ñ"Y-„Þ)ñ-üºž±qÚZ6º˜³¬Lè$0Dzå™cRMwôñüß hi¤†oÛKOŠXØ£Æÿô€ÊÀà‚ ¼\¯Ä¿ÙOâ×Ç/jñoí§ëڬХƜžÓai™%Ic¢\"!ùHÎ1È$WÑ|%mkkâO³4ð<‹¡,r0¸Æ1ÀÛÔ ì㓞à‡-~#ø÷ZñkÀ²x_Gºû>‹m'Άà&ã’r®Sƒ?ÊAJü©q.tø…äU–¼÷väèýmÓk¦®ú÷{~ËÚó|5ø{û#|bøà­+Àþý®,ü5 iË#Ùé×Ó¤dY%y\îšvvGsÉ=p8ü*¿¿ôzÚgþ:?ÿ¯£¾+x9|WáÇ–gÔlU¥· OÌ8Þ›@9$/g rkç[2×â—Äí ÂZ\-k¦Alo|BUÛçŒÌ#,ùr18Ÿ‘òUq.q–çT²¬>3_‚W~›µŸn7kèS£NtÜܶ<Ëà¯ü»Çß²õž­wàÚ†Û¶šÿÙþ×<¾ ³¸KŸ(HaÃ\\¸È~\g<ç“ÿ ¯ãïý¶™ÿ„ÿÇkêíOÃv©á×ÐÚÝmôÓÂÛ‰WÀ ŒqŒcŠù;â’ønÑ<1ieŸÞjIafካÃçþB *£vÞ$Vìk^*âLׇëaã‡ÃF¬*û·Öê]S]­ªë¾šj¨Q§U;»Xóhÿàžž:—ã<Ÿ“ö¥³FÛÄkàË37ÙE¦ iòòHO¹Ü½Ízgü*¿¿ôzÚgþ:?ÿ¯¦|ðëKðg‚bðäQ¬Ñ<%o§£ÞJë‰es¸¶ç9þ#€¯¾+/…–>!µ»¶ioŽI™Æíÿu‰ÆÒTe¾î F\ô¥ÄÜG›ðö]aãSžÑ•›÷fÿöÛuò~AF:­«ÚÄ¿fjÿ¼ñÇ?´5·Å/øAþßö=2ß¶z~ß¶Z´f[yŽ3„o™[ý^2MqŸ ?e?‹_|§øÂ_µþŸ èKL–úsøM™¡g•å–vrLŽçæ'Ç_U|øuÿ ûÁ–ë}·ˆïÕnu[’˜òœ‘!˜mŒ€)ÛÁ ư>2øJÚÖþ×ÄŸfiày-B0Xä`qŒc·¨ÙÇ'>®q›æ¹^H³5B2©œáw¢}¼ã¥ï¦îúkéÂu9/§CÇ¡øKû@ÜÍ0þÚZ|²ÈÁ4ø¤f'%äšóƒðOO~ʳkPøö¥³ð„ºâÀ÷ÑÜx2Îfb2Ž.._hl¿wÏ9ÀǺüðå¯Äë^-xO è÷_gÑm¤ùÐܤÜrCnUÃêpgùH)^Ëñ[ÁËâ¿<°£>£b­-¸R~aÆôÚÉ!xã93X`sœã‘K5ú¼U[sFz¥ºÞÞËfÒèî9S§¼—Ó¹óü*¿¿ôzÚgþ:?ÿ¯6¹ÿ‚wxúËãT_.?jh<}.<¿Kà«5Gͧن"7>IÌ/Üÿk¯5é¶:e¯Å/‰Ú„´¸Z×L‚ØÞø„«·Ï+˜FX0 ò.äbq?#ä"¾ªÔü1§jž} ­ÖßM1,) °ˆ•q° ¸ÇÆ8¬¸g>Íx‡.©Ž•Ózò&Þ­wìžš«ïå`­J)¨ÞýÏ”áUü}ÿ£ÖÓ?ðÑÿøíyïÅÏØâí'‡uß~Õ6~ ¸’]6õ|ev’ÈÑɆå‰1CÃç ÇSžÿâ’ønÑ<1ieŸÞjIafካÃçþB *£vÞ$VìkéÏ|:Òüà˜¼9k4O [éÀ(÷’ºâY\î-¹Îˆà`€+—…¸›8â Wu0ñ¤©]]·~u·É5¯UoAâ0ô ”[º‘ð?ü;×Ä¿ôuzgþV_ü•[~ÿ‚oër|Aðgˆïÿh+oZxW_°×Žoáh!ó^ÞQ"¡’;¢SpV\@Îpq^©ñXÙ|,±ñ ­Ý³K|pºLìÎ7oû¬N6’£-÷pJ2ç¥{ŸÁO‡_ð¯¼n·Ñ«xŽýVçU¹ y)É’†ØÁؼÜk·‡8Óˆxƒ_§É MÆw”ßd›³×«ìÏ)äYVƵ RÝ5¦¾i+ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë_ ½Ñ߆Gßõå_µüšÇÆOû5Ÿý!š½V¼«ö±ÿ“XøÉÿbf³ÿ¤3UŸ|xÿ”^éŸö+xsÿFÙWê¥~Uüxÿ”^éŸö+xsÿFÙWê¥J6«ºô9ˆ>_x~T…ÔíÇg0áÖAƒ´ŒnÆ98¼à_ÃíOÄ>9Õ>"x¦6VÒɧhðù¥|±x&vøNC ¤¹¥;P×ÐtWËâ8oˆÎ)çSïalµ×Fü×ÿ#ü£U¤©º}¾výª?g¿|RñgÃÏø_â[|3×<º›Á¨'‡“X.·‘E‡Êw ¤nU¸|ü»s_DÓ&†;˜d†hÖX¤R€U”ŒAê }5Nw {&”¬í}Uú_m;êŒU¯©ñ7ü"ßÿèóÿóXÿj|*øã/||ð_ÄþÑüR›á÷Û|!|o¤´_nµx2E êæVÿWÄÖïÆd“áÂë-Ž™öÛ½]’Ç™"I\û€ªrNäS·æ5ïŸ <ÃiÚ6åšõTÍ}r¤1žåù‘ËmRÃ?*–ÚªJü¿…óÞ Í³ F1¥Nœ(·r©]¾–nm[­ìî—šgmzT©Å86Û:ú(¢¿T8BŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹O‹Z¥—ÂÏ\hšÞŸájöKoVuK=>q˜î'gVQm‡bÊÀ*œ‚8®®ªjÚMŽ¿¥^éš•¾£¦ÞÂö×Vwq,°Ï©WÑ ¬¤‚¤A Ð̾9ÿ…%ÿ f½ý‡ñÃßÙ^ ÖµðΗ iš-LJ4Ý*k¹¬†õK½&kQu;Oq sZˉÊC˜yYŽ, ò£Úå^$ý£¾"ÛiZæ¿oá½ÃÚo†þé5[ŽæMIe™uŸJ1ˆØ­–Ï´:“ !ͼÞf!õ_ ø×Å^*ø«âË H´xü'á­M4;È&YEô’¶m|/#˜1B¹»Ž³Áù^_? Ö½ø/à«ý+]ÓÃöðiºß‡áð­í£½¼-¥Â· ²$l¢%U»¸Æ€p3ò®-­ðÇü'ð˜ÿfÄûïùŸh—Èó¼¯'í?gÝäý§ÉýÇÚvyÞOî·ù-|Õá¿ÚûÆšçÂÏxÖ-íƒáþ£ã[¹ð–«¦Yé3ÃSAa5Ýõ?0NØšØÂ ÚHÁq*ùUx[ûpèV­âOìõÖŸt—i{ͼ;˜•‰ðÒlR¨e*žaRþ\A¼µâ­¿g/‡ÖºV½¦ âm7YÓ.4I¬îuK¹¡µÓç]³ZY#ÊEŒ ¡ŠÔD¸ŠÝG·Ò袊(¯ý |_¬ø;_øC>‹§kãÝx¶[kD¹‚¯âþÄÕ_Ë>|ÐÄʯrí‘ÀÌ Œ°Q^ÁY:Ï…´¿j:ýý¯Ú.ô;ÖÔ4ù<Æ_"v·šØ¾¿ss2á²>|ã ò¯Ä_øŸÆ,ñƧøÃáõ£¼²]2ãXŠÞàGwâk¨.¥†]>îQ!fYB"Á N·Çyõþñ߇¼-¯øl5†^*ñ sjšåæ¡y§ßØ%¢E5µÝį<{…é,»Ê«AF#c)—Ý|gðoÂ^?“W—ZÓî%¸ÕaÓ­î®-5›IŠØ]IwfRHdF‰¢žY$V$€IRÇàGƒ,ü+âIe¨j–%²}7V›YÖou Ë«VGO³›»‰žuˆ f*ŠáQ¥‘”+;æ¿^ûAøÑa£G¤xãÁºmÿ‡õ¹ôx•µÙµa¹°Hçµ·^ˆ¸•dS$&Cw 7–L<ÿÆ[RËĵËûß Miþ,ðŸˆWû3ÁðG§A)mKJð¹a˜ÍxÑ5½Á– àL¸"$÷_|ð×€uYu=8kÚ“Âm–ó_ׯõ‰ ‰™Yã…ï'”®ÉuŒ¨se·yi¶§Š~x3ÆZíÖ«ªYj %îßí +MföÖÃRÚ¡?Ó,â™mî÷F©yñ¾øÑ#mȪ Çô¿|EÒ>'|Aðü^ Ñîî5߈ÑxCžÿK¹š %ðÔZ›î‡í€Ì­+ÄxšI§Éä¯Aá?~8ñŒ|áë;_ÃößøI£×¯çŽù‚ëº{Ëis´o”ˆ¤säùÈÆI¼‚“ú±ð#Ášæ£âBæËPŽÿ]½·Ô®î¬õ›Ûibº†ÜZ¥Å³E2›YM¸ò]íÌm$yI ©"µ|?ð·Ã¼ÑnôÍ3ì÷z=•å…¤íq,åÝÍ ÷M#34²Ío4›¤g ʼnw,࿵α¢ÂYw©A§ø¢ÒËÁšÇŒìÆ“¢êZ]š¥‡ÙÏÙàÔn•¢Õ"”].ÛËxãM±òˆjø³ãÏÄ…ÓøóKñ<^Õ®ô[/ ¶ŸªhZ]ëyï«ê—Vy,’ÊÞI‰µŠWy¼¦Ä¨g  Eû5xEþֽм=§Á­]è·š ë"}JÎ+,›#k$Á~­ emÇ)‘b _w?ðÃöXÓ¼)mâ×ñMõ¿‰µ/Ãcm{ugí³2ÙÉ4¶³´÷—Wmw— ¶äÜî`µX„~B’Õ|ø¯|Aðö³/ˆ,. ¸Óu3c¥7‡ï´Õ"û<}¢;ÜÍ «Ìð|ÎášÝÜbú]sþ ððûJ–ÃE‚áRyÍÅÍõì÷·wR•Uó'¹ÞY˜"F¤v*‘ƃ ŠA@ÁGäéÿbÿûÛÿK´ªûþ¾ÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ýówÅøññû—û5}#_7|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆúïâ#™|QðýÙJ3K¢’§¨ÿNŠòÿø(v3|iýš£Ôî4{=5¼A2Ý\x†ŸMŠ#s§ï{¨ÙÐ<r]K *\äz‡ÄG2ø£áû²”f—E%OQþç_·n¥ýñûö]¿þÕÓô/²ø™çþÔÕ—užÛ­9¼éÇ™bLnaæ'Ê̽F”ö;òáKÕ~HúçNý¡¾hzU†™áߊ>Ð4Û9® ÑläñMœé2…¾Qqr‰©¨¸ÓÙZ ’a!¶-‹ö[rþÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙrÿá-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›SÞ5%ý§>¶Ï°|]ð}ŽooŸöÿZÜý‚èý¿7—˜ÕÚ¬dó!ò­ è¾Xö²’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙrÿá-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöߘR_Úsá[lûÅߨæöðéÿoñu­ÏØ.ÛóyyP}ªÆO2*ÑpÑn‹åhû)/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}—/þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù€< âŒ>øðjÞøƒàÿøDnï^Õ¼;ˆôù®4wóŒqËo3¾ëp®±žØH¹U‡rZCð³Mø!¬ø*êüGÒ,WüýÅCûÏ#û?÷ÿóÓû ^ëöß›Ÿð›á߃þƒÃ¾¾·ð^…§MqqŸy¯™aÒÙ§yä/ü$$2Á%£™‘~V¼ªÞ~f`hcªc¡z‹UdÕï~eÙ¾½÷ï¡Â¹n2­˜Ó¦¯UZQi5{ß™vo¯}÷½ù ½ö[ºûOؾ#h¶kól¬þÙñNæoìù£ûV/®vk«ç[K²Ûd1m˜yƒy]Ïäzì·uöŸ±|FÑl>׿ÙYý³âÌßÙóGö¬_\ì×Wζ—e¶ÈbÛ0óò»ŸÈôÿøK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æö>¡„ÿŸQÿÀWù÷öfþ|Cÿ_äy…Þƒû-Ý}§ì_´[µù¶Vlø§s7ö|Ñý«×;5Õó­¥Ùm²¶Ì<Á¼®çòËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÜÿƒtßü-¶Õ`ðíõ¿„ÒïSºÖoΡ¯™Ú;×É4÷Ì|BLí Xâ|“¹t q vª||ˇ°9œiÓ«£)4’\ÖMYµÓ[¿O™àæü+–ç¥Jµ5ÂjmE%Íe%ÊÚ³I·wém7Z>ø¿ðWá燭t¯ üVðeûTíö¡â}>I΢!»‰µMPèƷ¶ó µÛ"©‹÷ ,B4¿´ç¶Ùö‹¾±ÍíáÓþßâë[Ÿ°]·æòó ûUŒžd>U¢á¢ÝËÑö\¿øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æú8B4â¡d´Il‘õ°„)AS¦’ŠVIh’[$»’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÍeš’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀ’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀ’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀõŸÛá}–«ýŸ¢øÆïW¸I®.lßBµ¾ñ4:]Ä©(»Ô%°º‘'´”ù~MŽå’ b;#M´þÙ_ÛgØ.ükc›Ûçý¿ÁúýÏØ.Ûóyy‡j±“̇ʴ\4[¢ùcÚ>ËâÞ2—ÏøûâÙ¨ ¾Ñàݨjneò®µH|ÿm»Ä°yfœùƒ}ͽ̻{¹¬Wä÷â2ŒÆ®ÉBÚ¶úÅ?Ôü‰üFÅd9µlºž2PåÕ·wxÆ_©ì2þÙ_ÛgØ.ükc›Ûçý¿ÁúýÏØ.Ûóyy‡j±“̇ʴ\4[¢ùcÚ>ÊKûe|?mŸ`»ñ­ŽooŸöÿë÷?`º?oÍåæ}ªÆO2*ÑpÑn‹åhû/Q^üDœ_ýÇïgËÄ]ÇÐ,>ö{ ¿¶WÃöÙö ¿Øæöðéÿoð~¿sö £öüÞ^aÇÚ¬dó!ò­ è¾Xö²Óñí—áOì+é|‰õCss.áÍCJÔ ¸Šé¤¼W¼¼’ââ(¤°‘%Ao+Ä•±6É¥·•W¥Ébñ?ý€tŸý(Ôjÿâ!ãkR«ÉF1qWOWÕ/ÖæŸñsE ÎFQÓ»zóF;?[ü­æu^'ñ?~*ÛKiãMulü54ÒÏ'„4{‰§³›Ì“ÌxîngÌ·o’ "Ž5&¯ Keeo¦ÙÁiiV¶–ñ¬PÁŽ4Q…UQÀ1SÑ_–c³,VeSÚbfäÿ¯øk½mÔü[2ͱ¹µW[QÉÿ_ð×wvêMð{WþÂøÅã›Ïí/ì—‚ÓÄž0½:…õºùf"`$íÙâÚ’< O´4ÆWËŸJ¢Š(¢Š¥¬é6úî•u§Ý.è.#1¶$g£ ‚2=ˆ—ðÿÁ¶¿¼¤øzͼȬ`Òà6BKI& 8ÜìÍŒ3À®†ŠæúµoõžUÏn[õµïoKê;»[ W%ெúoõŸjV\Í­Ý$îíF‘…H€nŒ„Às´ëh¢¦Z°­8§(_•õWVvõ@›I ®Jûá¾›ñ#JñŒœ^ØZÍDÈûTJH#$&ôÃeèTg­¢ŠØj8ž_mùZ’¿F¶kÌk`®KÅÿ ôßx‡Ã:µçè—‚íP.<âªÞX,#d…\rG ;¸ëh£†£Š‡³¯%tìû§uø MÇTKYÒmõÝ*ëOº]Ð\FclHÏFd{*í­Jp­ S¨¯&šîžè³º9ï‡þ µø}àÍ'ÃÖmæEcF—y²ZI0IÆçfldœt4QE*p£N4©«F)$»%°7wvr^ øo¦øYñ6¥eÌÚÝÒNà.ÑiTˆváXÈA8;A®¶Š+,>Ž’£B*1[%¶®ÿ˜6äîÎJûá¾›ñ#JñŒœ^ØZÍDÈûTJH#$&ôÃeèTg­¢Š(á¨áù½ŒRænNÝ[Ýú°m½ÎKÅÿ ôßx‡Ã:µçè—‚íP.<âªÞX,#d…\rG ;¸ëh¢ŠXj4g:”â“›¼Ÿwd¿$¶ì™ò¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-z¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-n÷F°ød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯@¢Š*ŒN+âw¯¼‡,tm&ßYñˆõ3¥i–××­eiæ­­ÅÛ´ó¬R¼j!´›br_ËR1uɲøÈÚ‡¯î|{¡ÜxgW²ÔÆ”,t˜®µuÔ¥kt¹VÓ„vé=∷”€k{¬‚´†ßÆ¿êž;𭮟a¦xÄv‘Þ¤ú‡†|S;Y€$€A,† Ì;&hnUÖ'%­•>På—Ít?€þ*ðÆ‡£ê:6™á}'RѼ['‰tÏXßK‡cé2igÒÚƒ³O5ñe´Ë,ˆWæ3»Äÿ>kž2ðä—‰´ûKLÓ×ÅÖn­æÚ 6Hn6ß¼ÛLBÙ~Îíç– Ž-Áu3D$ÜÓ¾;ø3Qе}TÞêtzW“ö«-_F½ÓïÇœÅ-öYÏ \KçH(¼¸ÛÍ‘Z8÷º•§‹>ëž;ÿ…Ÿo«ëz|?ðš|?±ð‹êV޾UÒj‰î³9ÛüL#dO9›åe-Àfâ‡ì¿­ë~ñŒ7ÖÖú&»«M¢Kkãs[šuÒïÍôq¶©u²kU‘ÙãSoè ¼Á¦fXãʩӔ§¤äîßwdµù$½îÙê·¿´oÃí3ÃÖÍöµq§ÛÞêgD†ÒóK»‚ûûCìïp–fñ Òy"tq4a¥ó!‡3Dµð·Št¿hVºÆuö» ÁY£h¤‘I€ñJŽ®…tteeVRŠøà± Ýx;R– ?L»³ñœþ'Õm¿·õ-nVFÐît´n½Ì·2åàl”1°+÷Ëé|}à _éš„¶ó\Oâ sUV¶fe^j·W‘), îÜ aŒ #ê#µ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯‡¾<|xø½¦þѾ0ðƒüa¥ø{DÑôý6í#½Ð’ùÙî]À7™sÎ~ñè÷ ~yüiÿ“Éø£ÿ`mÿ@»¯•âŒn#.Ê+b°²åœylìžòŠz4ÖÌøž3ÌqYNCˆÆà§ËR<¶vNלSѦ¶o Âéý¡¿è¨øÿäÿäš?átþÐßôT|?ÿ„ròMS¢¿ÿ]³ÿúÿÉ!ÿÈŸËÿñx£þ‚ÿòJüsþOí ÿEGÃÿøG'ÿ$×GðoöˆøÄŸ´/ÃÏ x·ÅZ‰ô/Imÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ý|ÿÿ“§ý‹ÿìsoý.Ò«ïú+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþç_·n¥ýñûö]¿þÕÓô/²ø™çþÔÕ—užÛ­9¼éÇ™bLnaæ'Ê̽G¢üDs/Š>»)FitRTõéÑñ^uûvê_Øÿ¿eÛÿí]?Bû/‰žíMYwYÙíºÓ›Îœy‘æ$Ææb| üËÔiOc¿'þ½Wä¬?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›õ=ãªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oóKçü}ñ ìÔß èðnÔ5?·2ùWZ¤>Nÿ¶ÝâX<¿³N|Á¾æÞæ]¿½ÜÖ+Ì>)þÒ ¼?ñÇS¿¼ñgiwá.WSmqO•-ñ™`»¾ ,1KoÄȾlé4áH˜;åÿÃ_|$ÿ¡°ÿà²óÿŒ×ógå9†';¯V†r‹å³Q“OÜŠÝ+n"qæGšã8_ …©8>K8ÂM;SŠvi[}=Oc¢¼sþûá'ý ‡ÿ—Ÿüføkô6ü^ñšøïì,Ûþ*àÿ#à?Õ¬óþ€jÿà¹ÿ‘ìuÆé_òX¼Oÿ`'ÿJ5ã¿á¯¾ÐØðYyÿÆjŸþ&j?>+kçჵŸ‰÷séu®û(•¬‘Ë}#-ÕÕÀUƒtnJ;)QÍz8>ͪª”–iÊ)+ÅÅ|Q{».Yëåü-žVU¨¬Då—4Uùà÷’Ih›ÕžßX^ÖuŸ‹º©Ó~ørãÇ­fE¶‡dwA¿Î¿`Q™Rá_Ê€M.ü•ôïØ6Îÿìš§Æ]þËõòæÿ„cNG³ðí¼ƒìq’÷l°¹áÌl²Ü-}S¤é6:•g¦i–vúv›e [ZÙÚD±CH¡R4E*ª€€_¥dþÓ…ªæ³æÉÎ[¿•½YúîCáM*v­TæÉÒÿ·¥£~‘µžÒgÆ^ðìïà?ëÇâgƯxÃÄÓôÍ_CÔõû[ ¬³ìŠM)®ddy™ˆ»iÙ%]ÑùG >د*ñü?ÃÏû ÒÕ¢¾?OÙè7ž'ñ7ïj)øeà¿ì-zæøxšã^²mÓjk±Ëu$ÒÉ7‘¦µ½Ø´YÉbµ‘b-!Yp½w'ÄK¼‘‹xàw’†(’UŸÊ‰”íú+䯊о‰ÞмE¬jÖöºg„µk«½sY–6Q{¬^[ê÷/x¨Í§ÀÖv»­‘"´T’Xcˆ‚k+Âwº÷Œ4i)㋈ü3¬|F¸±µ¹ð‡‹/µu“K_ ÞM- Ö.aŽ[Åk¨§c*hY¼¸¥Ž[eò@>¿“V±‡U·Ó$½·MJæn`³iTM,Q´k$Š™Ë*4Ñ`0 ˆ7 Û¯ˆ,îZóâ7„¯î¼g¬hþ'·ðÿįè‹]]j3)Óõ˜mìöØy‡ûFx­‘Ý‘’In ²<†G‰}öRñUž¿ÿ M®›©kØ[}–Au¥øÞãÆ:8‘üàÉ¥uÎ.@ ÖĘãFµ‘iäÈÐQEQEQEQEQEQEQE|«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡ËR÷FÐød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯@¢Š*ŒBŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¿<þ4ÿÉäüQÿ°6ÿ ]×èe|³ñ»ö2ñÄŒ¯<-ñ.É«iövw¶7ž]H3Û™B:?Ú"Ú Ë‚¤A;¹|çeµs|²® ƒJRåµïm$ŸDÞ˱ò\W”×Ïrjùv¥9òÙÊéi8ÉÞɽ—mÏ ¢½þ?âým3ÿeÿäê?áƒþ'ÿÑvÓ?ð†_þN¯Å¿âæßóöŸß/þ@þzÿˆKžÏê_øÿùYçÕÃïù;¯€ÿõÿ¬éžî½þ?âým3ÿeÿäêè>þÄ~+ð_Æ?xçÄlüQ†¦ºš:ßÂÿaiZ{I­ïEܘÎÝ÷vãŒæ¾‡x+0Ê3:XÚóƒŒy¯g+ëºÅ-ßsë8SÃÌ×"Îhf8š”Ü!Íu&õ„¢­x%»ï±õ½Q_´ŸÐÁEPEP_•¿ÿäG—þÃ:Çþœ®kõJ¾#‹þ íãMçQƒÃŸmtÝmBîòÖÎó u4 =Ä“liEÚy„ݵsº:WÅqfKˆÏp0Ãa¥%5/y´¬”—DõÔüóŽ8wÄÙu<QŒ£5/y´¬£%Ñ=u]Šôø`ÿ‰ÿô]´Ïü!—ÿ“¨ÿ†øŸÿEÛLÿÂù:¿(ÿˆs›ÏÚ|¿ùñø„¹çüþ¥ÿOÿ•ž}^ƒûÿÉvøíÿ^ÿÐu ?áƒþ'ÿÑvÓ?ð†_þN¯Vý—ÿeýcà‰f—ðãè®þ"9—ÅÝ”£4º)*zôèø¯9ý»|S¥øãïì»âMnëìZ.âgÔ/®|¶“É‚+­:IjÍ…Rp “Ž5èÞ4PÕücàºi¶·Š]ÍÍõ¤JÀ\Ç!Ú0÷@6d°À‚~¤ðçÂüPûGü&^ ðÿ‹~÷ìŸÛº\¿gßþ_š·vÄÎ1«ž‚µ†Ç¡”&©Jý×äŽþû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ­tò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ Š¿o_Û×àOÆŸÙ;Ç> ðo޶|I©}‡ì–_Ùðyž]ý¼¯óË ÂFç–Æ$ Êý©¿h†qð_Tµñç‡õKMâV‹«ê?ÙZ„w²ÛÙÂfif1B]ʨÇE'$’@¯º¿á“¾Ñøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªV-JÉ®ç•ÃÑÿf/ú)¿ù@Õ?ù¼ÿö…ÿ‚~ÎÞ9øñ/Ãz'Ä?¶ëZdžu=>ÆÛûQΞ[Y#7=¸UË0bÏ$ úWþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ¦Aù«ñ§âÇõ_ø'.Ÿá«/x~óÄká½ÑíõHðI–fD0‡ß¹B6ጧ= }«ÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj’V.Ræ<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ¦Aå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕ|ûU~Ô ?iOÚŸöJÿ…qâoøHÿ±|gÛÿÐ.­|Ÿ:ûNò¿×Ä›³åI÷s¼ã#?ª•æšOìÉð{@Õlµ=3áGôíJÊd¹µ¼´ðåœSA*0d‘cYXAŠôº+æï‹ñãâÿ÷.ÿöjúF¾nø°®Ö/§™!K°©½Sqù°71 >¬@Ȥö0¯ü)ú?ÈüÂø¯ÿ#þ©ÿl¿ôRQ]Ä믋ïî·èÖ~g—û‹¿é©*â5¯Ú8Î3ô"ŠÁ5IZ^Húgâ#™|QðýÙJ3K¢’§¨ÿNŠû?áüÅ¿í—þÏ_|Ds/Š>»)FitRTõéÑñ_VøGÅßðŠý¯ýí^~Ïùi³nÝÞÇ?z®žÇvOü)z¯ÉÍEyßü-Ïú„ÿäÏÿaGü-Ïú„ÿäÏÿaZžñè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè•ówÅøññû—û5zoü-Ïú„ÿäÏÿa^UñóûC@ñ-ÖÏ/Ï·¹—fs·r±ÆOc Gðgèÿ#ó+â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ+l|Í/áÇÑB|gøÅ¡h¾*Ðí].æ¿Óì,.ÈŒÀ‰ãb»ˆÌmÆG8=ÅfÿÃe^ÿÏÞ¥ÿ€vÿãER§h'ÕÒÙ‡ü6Uïüýê_øoþ5)ý°î Ótìêw×n“=Ç—eØMÌÞZœ€2!ò~îG¹9¢Šfܮֿ{"ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆ¥öúK2I©ßIu%ì»b[(wGn!ƒfîó'žF >¸h¢¨µöŸÞȿᲯçïRÿÀ;ñ¨o?këBÒ{[‹JH&FŽDû%¸Ü¤`ŒƒéE ÓoG'÷³À¼m®Aâ_ÞêV©$pM³jÊa„U9Á#¨=袊 ŠQI.‡ÿÙtango-9.2.5a/doc/src/atk/programmersguid.lyx0000644023471100065110000022474213034745263016030 00000000000000#LyX 1.6.2 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \language english \inputencoding latin1 \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 5 \tocdepth 4 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Chapter TangoATK Programmer's Guide \end_layout \begin_layout Standard This chapter is only a brief Tango ATK (Application ToolKit) programmer's guide. You can find a reference guide with a full description of TangoATK classes and methods in the ATK JavaDoc \begin_inset CommandInset citation LatexCommand cite key "ATK-doc" \end_inset . \end_layout \begin_layout Standard A tutorial document \begin_inset CommandInset citation LatexCommand cite key "ATK-Tutorial" \end_inset is also provided and includes the detailed description of the ATK architecture and the ATK components. In the ATK Tutorial \begin_inset CommandInset citation LatexCommand cite key "ATK-Tutorial" \end_inset you can find some code examples and also Flash Demos which explain how to start using Tango ATK. \end_layout \begin_layout Section Introduction \end_layout \begin_layout Standard This document describes how to develop applications using the Tango Application Toolkit, TangoATK for short. It will start with a brief description of the main concepts behind the toolkit, and then continue with more practical, real-life examples to explain key parts. \end_layout \begin_layout Subsection Assumptions \end_layout \begin_layout Standard The author assumes that the reader has a good knowledge of the Java programming language, and a thorough understanding of object-oriented programming. Also, it is expected that the reader is fluent in all aspects regarding Tango devices, attributes, and commands. \end_layout \begin_layout Section The key concepts of TangoATK \end_layout \begin_layout Standard TangoATK was developed with these goals in mind \end_layout \begin_layout Itemize TangoATK should help minimize development time \end_layout \begin_layout Itemize TangoATK should help minimize bugs in applications \end_layout \begin_layout Itemize TangoATK should support applications that contain attributes and commands from several different devices. \end_layout \begin_layout Itemize TangoATK should help avoid code duplication. \end_layout \begin_layout Standard Since most Tango-applications were foreseen to be displayed on some sort of graphic terminal, TangoATK needed to provide support for some sort of graphic building blocks. To enable this, and since the toolkit was to be written in Java, we looked to Swing to figure out how to do this. \end_layout \begin_layout Standard Swing is developed using a variant over a design-pattern the Model-View-Controll er \begin_inset Index status collapsed \begin_layout Plain Layout Model-View-Controller \end_layout \end_inset (MVC \begin_inset Index status collapsed \begin_layout Plain Layout MVC \end_layout \end_inset ) pattern called \emph on model-delegate \emph default , where the view and the controller of the MVC-pattern are merged into one object. \end_layout \begin_layout Standard \align center \begin_inset Graphics filename img/core-widget.eps scale 60 \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard This pattern made the choice of labor division quite easy: all non-graphic parts of TangoATK reside in the packages beneath \family typewriter fr.esrf.tangoatk.core \family default \begin_inset Index status collapsed \begin_layout Plain Layout model \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout core \end_layout \end_inset , and anything remotely graphic are located beneath \family typewriter fr.esrf.tangoatk.widge \family default t \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout widget \end_layout \end_inset . More on the content and organization of this will follow. \end_layout \begin_layout Standard The communication between the non-graphic and graphic objects are done by having the graphic object registering itself as a listener to the non-graphic object, and the non-graphic object emmiting events telling the listeners that its state has changed. \end_layout \begin_layout Subsection Minimize development time \end_layout \begin_layout Standard For TangoATK to help minimize the development time of graphic applications, the toolkit has been developed along two lines of thought \end_layout \begin_layout Itemize Things that are needed in most applications are included, eg \family typewriter Splash \family default , a splash \begin_inset Index status collapsed \begin_layout Plain Layout splash \end_layout \end_inset window which gives a graphical way for the application to show the progress of a long operation. The splash window is moslty used in the startup phase of the application. \end_layout \begin_layout Itemize Building blocks provided by TangoATK should be easy to use and follow certain patterns, eg every graphic widget has a \family typewriter setModel \family default method which is used to connect the widget with its non-graphic model. \end_layout \begin_layout Standard In addition to this, TangoATK provides a framework for error handling, something that is often a time consuming task. \end_layout \begin_layout Subsection Minimize bugs in applications \end_layout \begin_layout Standard Together with the Tango API, TangoATK takes care of most of the hard things related to programming with Tango. Using TangoATK the developer can focus on developing her application, not on understanding Tango. \end_layout \begin_layout Subsection Attributes and commands from different devices \end_layout \begin_layout Standard To be able to create applications with attributes \begin_inset Index status collapsed \begin_layout Plain Layout attributes \end_layout \end_inset and commands \begin_inset Index status collapsed \begin_layout Plain Layout commands \end_layout \end_inset from different devices, it was decided that the central objects of TangoATK were not to be the device \begin_inset Index status collapsed \begin_layout Plain Layout device \end_layout \end_inset , but rather the \emph on attributes and the commands \emph default . This will certainly feel a bit awkward at first, but trust me, the design holds. \end_layout \begin_layout Standard For this design to be feasible, a structure was needed to keep track of the commands and attributes, so the \emph on command-list \begin_inset Index status collapsed \begin_layout Plain Layout command-list \end_layout \end_inset and the attribute-list \begin_inset Index status collapsed \begin_layout Plain Layout attribte-list \end_layout \end_inset \emph default was introduced. These two objects can hold commands and attributes from any number of devices. \end_layout \begin_layout Subsection Avoid code duplication \end_layout \begin_layout Standard When writing applications for a control-system without a framework much code is duplicated. Anything from simple widgets for showing numeric values to error handling has to be implemented each time. TangoATK supplies a number of frequently used widgets along with a framework for connecting these widgets with their non-graphic counterparts. Because of this, the developer only needs to write the \emph on glue \emph default - the code which connects these objects in a manner that suits the specified application. \end_layout \begin_layout Section The real getting started \end_layout \begin_layout Standard Generally there are two kinds of end-user applications: Applications that only know how to treat one device, and applications that treat many devices. \end_layout \begin_layout Subsection Single device applications \end_layout \begin_layout Standard Single device applications are quite easy to write, even with a gui. The following steps are required \end_layout \begin_layout Enumerate Instantiate an AttributeList \begin_inset Index status collapsed \begin_layout Plain Layout AttributeList \end_layout \end_inset and fill it with the attributes you want. \end_layout \begin_layout Enumerate Instantiate a CommandList \begin_inset Index status collapsed \begin_layout Plain Layout CommandList \end_layout \end_inset and fill it with the commands you want. \end_layout \begin_layout Enumerate Connect the whole \emph on AttributeList \emph default with a \emph on list viewer \emph default and / or each \emph on individual attribute \emph default with an \emph on attribute viewer \emph default . \end_layout \begin_layout Enumerate Connect the whole \emph on CommandList \emph default to a \emph on command list viewer \emph default and / or connect each \emph on individual command \emph default in the command list with a \emph on command viewer \emph default . \end_layout \begin_layout Standard \align center \begin_inset Graphics filename img/listpanel.eps scale 60 \end_inset \end_layout \begin_layout Standard The following program (FirstApplication) \begin_inset Index status collapsed \begin_layout Plain Layout ScalarListViewer \end_layout \end_inset shows an implementation of the list mentioned above. It should be rather self-explanatory with the comments. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code package examples; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import javax.swing.JFrame; \end_layout \begin_layout LyX-Code import javax.swing.JMenuItem; \end_layout \begin_layout LyX-Code import javax.swing.JMenuBar; \end_layout \begin_layout LyX-Code import javax.swing.JMenu; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import java.awt.event.ActionListener; \end_layout \begin_layout LyX-Code import java.awt.event.ActionEvent; \end_layout \begin_layout LyX-Code import java.awt.BorderLayout; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.AttributeList; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.ConnectionException; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.CommandList; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ErrorHistory; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ATKGraphicsUtils; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.attribute.ScalarListViewer; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.command.CommandComboViewer; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public class FirstApplication extends JFrame \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code JMenuBar menu; // So that our application looks \end_layout \begin_layout LyX-Code // halfway decent. \end_layout \begin_layout LyX-Code AttributeList attributes; // The list that will contain our \end_layout \begin_layout LyX-Code // attributes \end_layout \begin_layout LyX-Code CommandList commands; // The list that will contain our \end_layout \begin_layout LyX-Code // commands \end_layout \begin_layout LyX-Code ErrorHistory errorHistory; // A window that displays errors \end_layout \begin_layout LyX-Code ScalarListViewer sListViewer; // A viewer which knows how to \end_layout \begin_layout LyX-Code // display a list of scalar attributes. \end_layout \begin_layout LyX-Code // If you want to display other types \end_layout \begin_layout LyX-Code // than scalars, you'll have to wait \end_layout \begin_layout LyX-Code // for the next example. \end_layout \begin_layout LyX-Code CommandComboViewer commandViewer; // A viewer which knows how to display \end_layout \begin_layout LyX-Code // a combobox of commands and execute \end_layout \begin_layout LyX-Code // them. \end_layout \begin_layout LyX-Code String device; // The name of our device. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public FirstApplication() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // The swing stuff to create the menu bar and its pulldown menus \end_layout \begin_layout LyX-Code menu = new JMenuBar(); \end_layout \begin_layout LyX-Code JMenu fileMenu = new JMenu(); \end_layout \begin_layout LyX-Code fileMenu.setText("File"); \end_layout \begin_layout LyX-Code JMenu viewMenu = new JMenu(); \end_layout \begin_layout LyX-Code viewMenu.setText("View"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code JMenuItem quitItem = new JMenuItem(); \end_layout \begin_layout LyX-Code quitItem.setText("Quit"); \end_layout \begin_layout LyX-Code quitItem.addActionListener(new \end_layout \begin_layout LyX-Code java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void \end_layout \begin_layout LyX-Code actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {quitItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code fileMenu.add(quitItem); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code JMenuItem errorHistItem = new JMenuItem(); \end_layout \begin_layout LyX-Code errorHistItem.setText("Error History"); \end_layout \begin_layout LyX-Code errorHistItem.addActionListener(new \end_layout \begin_layout LyX-Code java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void \end_layout \begin_layout LyX-Code actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {errHistItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code viewMenu.add(errorHistItem); \end_layout \begin_layout LyX-Code menu.add(fileMenu); \end_layout \begin_layout LyX-Code menu.add(viewMenu); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Here we create ATK objects to handle attributes, commands and errors. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code attributes = new AttributeList(); \end_layout \begin_layout LyX-Code commands = new CommandList(); \end_layout \begin_layout LyX-Code errorHistory = new ErrorHistory(); \end_layout \begin_layout LyX-Code device = "id14/eh3_mirror/1"; \end_layout \begin_layout LyX-Code sListViewer = new ScalarListViewer(); \end_layout \begin_layout LyX-Code commandViewer = new CommandComboViewer(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // A feature of the command and attribute list is that if you \end_layout \begin_layout LyX-Code // supply an errorlistener to these lists, they'll add that \end_layout \begin_layout LyX-Code // errorlistener to all subsequently created attributes or \end_layout \begin_layout LyX-Code // commands. So it is important to do this _before_ you \end_layout \begin_layout LyX-Code // start adding attributes or commands. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code attributes.addErrorListener(errorHistory); \end_layout \begin_layout LyX-Code commands.addErrorListener(errorHistory); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Sometimes we're out of luck and the device or the attributes \end_layout \begin_layout LyX-Code // are not available. In that case a ConnectionException is thrown. \end_layout \begin_layout LyX-Code // This is why we add the attributes in a try/catch \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Another feature of the attribute and command list is that they \end_layout \begin_layout LyX-Code // can add wildcard names, currently only `*' is supported. \end_layout \begin_layout LyX-Code // When using a wildcard, the lists will add all commands or \end_layout \begin_layout LyX-Code // attributes available on the device. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code attributes.add(device + "/*"); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (ConnectionException ce) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.out.println("Error fetching " + \end_layout \begin_layout LyX-Code "attributes from " + \end_layout \begin_layout LyX-Code device + " " + ce); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // See the comments for attributelist \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code commands.add(device + "/*"); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (ConnectionException ce) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.out.println("Error fetching " + \end_layout \begin_layout LyX-Code "commands from " + \end_layout \begin_layout LyX-Code device + " " + ce); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Here we tell the scalarViewer what it's to show. The \end_layout \begin_layout LyX-Code // ScalarListViewer loops through the attribute-list and picks out \end_layout \begin_layout LyX-Code // the ones which are scalars and show them. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code sListViewer.setModel(attributes); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // This is where the CommandComboViewer is told what it's to \end_layout \begin_layout LyX-Code // show. It knows how to show and execute most commands. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code commandViewer.setModel(commands); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // add the menubar to the frame \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code setJMenuBar(menu); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Make the layout nice. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code getContentPane().setLayout(new BorderLayout()); \end_layout \begin_layout LyX-Code getContentPane().add(commandViewer, BorderLayout.NORTH); \end_layout \begin_layout LyX-Code getContentPane().add(sListViewer, BorderLayout.SOUTH); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // A third feature of the attributelist is that it knows how \end_layout \begin_layout LyX-Code // to refresh its attributes. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code attributes.startRefresher(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // JFrame stuff to make the thing show. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code pack(); \end_layout \begin_layout LyX-Code ATKGraphicsUtils.centerFrameOnScreen(this); //ATK utility to center window \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public static void main(String [] args) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code new FirstApplication(); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public void quitItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.exit(0); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public void errHistItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code errorHistory.setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The program should look something like this (depending on your platform and your device) \end_layout \begin_layout Standard \align center \begin_inset Graphics filename img/prog_guide_exple1.jpg scale 75 \end_inset \end_layout \begin_layout Subsection Multi device applications \end_layout \begin_layout Standard Multi device applications are quite similar to the single device applications, the only difference is that it does not suffice to add the attributes by wildcard, you need to add them explicitly, like this: \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // a StringScalar attribute from the device one \end_layout \begin_layout LyX-Code attributes.add("jlp/test/1/att_cinq"); \end_layout \begin_layout LyX-Code // a NumberSpectrum attribute from the device one \end_layout \begin_layout LyX-Code attributes.add("jlp/test/1/att_spectrum"); \end_layout \begin_layout LyX-Code // a NumberImage attribute from the device two \end_layout \begin_layout LyX-Code attributes.add("sr/d-ipc/id25-1n/Image"); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (ConnectionException ce) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.out.println("Error fetching " + \end_layout \begin_layout LyX-Code "attributes" + ce); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The same goes for commands. \end_layout \begin_layout Subsection More on displaying attributes \end_layout \begin_layout Standard So far, we've only considered scalar \begin_inset Index status collapsed \begin_layout Plain Layout scalar \end_layout \end_inset attributes, and not only that, we've also cheated quite a bit since we just passed the attribute list to the \family typewriter fr.esrf.tangoatk.widget.attribute.ScalarListViewer \family default and let it do all the magic. The attribute list viewers are only available for scalar attributes (NumberScal arListViewer \begin_inset Index status collapsed \begin_layout Plain Layout NumberScalarListViewer \end_layout \end_inset and ScalarListViewer \begin_inset Index status collapsed \begin_layout Plain Layout ScalarListViewer \end_layout \end_inset ). If you have one or several spectrum \begin_inset Index status collapsed \begin_layout Plain Layout spectrum \end_layout \end_inset or image \begin_inset Index status collapsed \begin_layout Plain Layout image \end_layout \end_inset attributes you must connect each spectrum or image attribute to it's correspond ing attribute viewer individually. So let's take a look at how you can connect individual attributes (and not a whole attribute list) to an individual attribute viewer (and not to an attribute list viewer). \end_layout \begin_layout Subsubsection Connecting an attribute \begin_inset Index status collapsed \begin_layout Plain Layout model \end_layout \end_inset to a viewer \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset \end_layout \begin_layout Standard Generally it is done in the following way: \end_layout \begin_layout Enumerate You retrieve the attribute from the attribute list \end_layout \begin_layout Enumerate You instantiate the viewer \end_layout \begin_layout Enumerate Your call the \family typewriter setModel \begin_inset Index status collapsed \begin_layout Plain Layout setModel \end_layout \end_inset \family default method on the viewer with the attribute as argument. \end_layout \begin_layout Enumerate You add your viewer to some panel \end_layout \begin_layout Standard The following example (SecondApplication) \begin_inset Index status collapsed \begin_layout Plain Layout SimpleScalarViewer \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout NumberImageViewer \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout NumberSpectrumViewer \end_layout \end_inset , is a Multi-device application. Since this application uses individual attribute viewers and not an attribute list viewer, it shows an implementation of the list mentioned above. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code package examples; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import javax.swing.JFrame; \end_layout \begin_layout LyX-Code import javax.swing.JMenuItem; \end_layout \begin_layout LyX-Code import javax.swing.JMenuBar; \end_layout \begin_layout LyX-Code import javax.swing.JMenu; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import java.awt.event.ActionListener; \end_layout \begin_layout LyX-Code import java.awt.event.ActionEvent; \end_layout \begin_layout LyX-Code import java.awt.BorderLayout; \end_layout \begin_layout LyX-Code import java.awt.Color; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.AttributeList; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.ConnectionException; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.IStringScalar; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.INumberSpectrum; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.core.INumberImage; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ErrorHistory; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.Gradient; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ATKGraphicsUtils; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.attribute.NumberImageViewer; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.attribute.NumberSpectrumViewer; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.attribute.SimpleScalarViewer; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public class SecondApplication extends JFrame \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code JMenuBar menu; \end_layout \begin_layout LyX-Code AttributeList attributes; // The list that will contain our attributes \end_layout \begin_layout LyX-Code ErrorHistory errorHistory; // A window that displays errors \end_layout \begin_layout LyX-Code IStringScalar ssAtt; \end_layout \begin_layout LyX-Code INumberSpectrum nsAtt; \end_layout \begin_layout LyX-Code INumberImage niAtt; \end_layout \begin_layout LyX-Code public SecondApplication() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // Swing stuff to create the menu bar and its pulldown menus \end_layout \begin_layout LyX-Code menu = new JMenuBar(); \end_layout \begin_layout LyX-Code JMenu fileMenu = new JMenu(); \end_layout \begin_layout LyX-Code fileMenu.setText("File"); \end_layout \begin_layout LyX-Code JMenu viewMenu = new JMenu(); \end_layout \begin_layout LyX-Code viewMenu.setText("View"); \end_layout \begin_layout LyX-Code JMenuItem quitItem = new JMenuItem(); \end_layout \begin_layout LyX-Code quitItem.setText("Quit"); \end_layout \begin_layout LyX-Code quitItem.addActionListener(new java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {quitItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code fileMenu.add(quitItem); \end_layout \begin_layout LyX-Code JMenuItem errorHistItem = new JMenuItem(); \end_layout \begin_layout LyX-Code errorHistItem.setText("Error History"); \end_layout \begin_layout LyX-Code errorHistItem.addActionListener(new java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {errHistItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code viewMenu.add(errorHistItem); \end_layout \begin_layout LyX-Code menu.add(fileMenu); \end_layout \begin_layout LyX-Code menu.add(viewMenu); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Here we create TangoATK objects to view attributes and errors. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code attributes = new AttributeList(); \end_layout \begin_layout LyX-Code errorHistory = new ErrorHistory(); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // We create a SimpleScalarViewer, a NumberSpectrumViewer and \end_layout \begin_layout LyX-Code // a NumberImageViewer, since we already knew that we were \end_layout \begin_layout LyX-Code // playing with a scalar attribute, a number spectrum attribute \end_layout \begin_layout LyX-Code // and a number image attribute this time. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code SimpleScalarViewer ssViewer = new SimpleScalarViewer(); \end_layout \begin_layout LyX-Code NumberSpectrumViewer nSpectViewer = new NumberSpectrumViewer(); \end_layout \begin_layout LyX-Code NumberImageViewer nImageViewer = new NumberImageViewer(); \end_layout \begin_layout LyX-Code attributes.addErrorListener(errorHistory); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // The attribute (and command) list has the feature of returning the last \end_layout \begin_layout LyX-Code // attribute that was added to it. Just remember that it is returned as an \end_layout \begin_layout LyX-Code // IEntity object, so you need to cast it into a more specific object, like \end_layout \begin_layout LyX-Code // IStringScalar, which is the interface which defines a string scalar \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code ssAtt = (IStringScalar) attributes.add("jlp/test/1/att_cinq"); \end_layout \begin_layout LyX-Code nsAtt = (INumberSpectrum) attributes.add("jlp/test/1/att_spectrum"); \end_layout \begin_layout LyX-Code niAtt = (INumberImage) attributes.add("sr/d-ipc/id25-1n/Image"); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (ConnectionException ce) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.out.println("Error fetching one of the attributes "+" " + ce); \end_layout \begin_layout LyX-Code System.out.println("Application Aborted."); \end_layout \begin_layout LyX-Code System.exit(0); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Pay close attention to the following three lines!! This is how it's done! \end_layout \begin_layout LyX-Code // This is how it's always done! The setModel \begin_inset Index status collapsed \begin_layout Plain Layout setModel \end_layout \end_inset method of any viewer takes care \end_layout \begin_layout LyX-Code // of connecting the viewer to the attribute (model) it's in charge of displaying. \end_layout \begin_layout LyX-Code // This is the way to tell each viewer what (which attribute) it has to show. \end_layout \begin_layout LyX-Code // Note that we use a viewer adapted to each type of attribute \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code ssViewer.setModel(ssAtt); \end_layout \begin_layout LyX-Code nSpectViewer.setModel(nsAtt); \end_layout \begin_layout LyX-Code nImageViewer.setModel(niAtt); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code nSpectViewer.setPreferredSize(new java.awt.Dimension(400, 300)); \end_layout \begin_layout LyX-Code nImageViewer.setPreferredSize(new java.awt.Dimension(500, 300)); \end_layout \begin_layout LyX-Code Gradient g = new Gradient(); \end_layout \begin_layout LyX-Code g.buidColorGradient(); \end_layout \begin_layout LyX-Code g.setColorAt(0,Color.black); \end_layout \begin_layout LyX-Code nImageViewer.setGradient(g); \end_layout \begin_layout LyX-Code nImageViewer.setBestFit(true); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Add the viewers into the frame to show them \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code getContentPane().setLayout(new BorderLayout()); \end_layout \begin_layout LyX-Code getContentPane().add(ssViewer, BorderLayout.SOUTH); \end_layout \begin_layout LyX-Code getContentPane().add(nSpectViewer, BorderLayout.CENTER); \end_layout \begin_layout LyX-Code getContentPane().add(nImageViewer, BorderLayout.EAST); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // To have the attributes values refreshed we should start the \end_layout \begin_layout LyX-Code // attribute list's refresher. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code attributes.startRefresher(); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // add the menubar to the frame \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code setJMenuBar(menu); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // JFrame stuff to make the thing show. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code pack(); \end_layout \begin_layout LyX-Code ATKGraphicsUtils.centerFrameOnScreen(this); //ATK utility to center window \end_layout \begin_layout LyX-Code setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public static void main(String [] args) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code new SecondApplication(); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public void quitItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.exit(0); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public void errHistItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code errorHistory.setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard This program (SeondApplication) should look something like this (depending on your platform and your device attributes) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \begin_inset Graphics filename img/prog_guide_exple2.jpg lyxscale 75 scale 50 \end_inset \end_layout \begin_layout LyX-Code \end_layout \begin_layout Subsubsection Synoptic \begin_inset Index status collapsed \begin_layout Plain Layout Synoptic \end_layout \end_inset viewer \end_layout \begin_layout Standard TangoATK provides a generic class to view and to animate the synoptics. The name of this class is fr.esrf.tangoatk.widget.jdraw.SynopticFileViewer \begin_inset Index status collapsed \begin_layout Plain Layout SynopticFileViewer \end_layout \end_inset . This class is based on a \begin_inset Quotes eld \end_inset home-made \begin_inset Quotes erd \end_inset graphical layer called jdraw \begin_inset Index status collapsed \begin_layout Plain Layout jdraw \end_layout \end_inset . The jdraw package is also included inside TangoATK distribution. \end_layout \begin_layout Standard SynopticFileViewer is a sub-class of the class TangoSynopticHandler. All the work for connection to tango devices and run time animation is done inside the TangoSynopticHandler. \end_layout \begin_layout Standard The recipe for using the TangoATK synoptic viewer is the following \end_layout \begin_layout Enumerate You use Jdraw graphical editor to draw your synoptic \end_layout \begin_layout Enumerate During drawing phase don't forget to associate parts of the drawing to tango attributes or commands. Use the \begin_inset Quotes eld \end_inset name \begin_inset Quotes erd \end_inset in the property window to do this \end_layout \begin_layout Enumerate During drawing phase you can also aasociate a class (frequently a \begin_inset Quotes eld \end_inset specific panel \begin_inset Quotes erd \end_inset class) which will be displayed when the user clicks on some part of the drawing. Use the \begin_inset Quotes eld \end_inset extension \begin_inset Quotes erd \end_inset tab in the property window to do this. \end_layout \begin_layout Enumerate Test the run-time behaviour of your synoptic. Use \begin_inset Quotes eld \end_inset Tango Synoptic view \begin_inset Quotes erd \end_inset command in the \begin_inset Quotes eld \end_inset views \begin_inset Quotes erd \end_inset pulldown menu to do this. \end_layout \begin_layout Enumerate Save the drawing file. \end_layout \begin_layout Enumerate There is a simple synoptic application (SynopticAppli) which is provided ready to use. If this generic application is enough for you, you can forget about the step 7. \end_layout \begin_layout Enumerate You can now develop a specific TangoATK based application which instantiates the SynopticFileViewer. To load the synoptic file in the SynopticFileViewer you have the choice : either you load it by giving the absolute path name of the synoptic file or you load the synoptic file using Java input streams. The second solution is used when the synoptic file is included inside the application jarfile. \end_layout \begin_layout Standard The SynopticFilerViewer will browse the objects in the synoptic file at run time. It discovers if some parts of the drawing is associated with an attribute or a command. In this case it will automatically connect to the corresponding attribute or command. Once the connection is successfull SynopticFileViewer will animate the synoptic according to the default behaviour described below : \end_layout \begin_layout Itemize For \emph on tango state attributes \emph default : the colour of the drawing object reflects the value of the state. A mouse click on the drawing object associated with the tango state attribute will instantiate and display the class specified during the drawing phase. If no class is specified the atkpanel generic device panel is displayed. \end_layout \begin_layout Itemize For \emph on tango attributes \begin_inset Index status collapsed \begin_layout Plain Layout attributes \end_layout \end_inset \emph default : the current value of the attribute is displayed through the drawing object \end_layout \begin_layout Itemize For \emph on tango commands \begin_inset Index status collapsed \begin_layout Plain Layout commands \end_layout \end_inset \emph default : the mouse click on the drawing object associated with the command will launch the device command. \end_layout \begin_layout Itemize If the tooltip \begin_inset Index status collapsed \begin_layout Plain Layout tooltip \end_layout \end_inset property is set to \begin_inset Quotes eld \end_inset name \begin_inset Quotes erd \end_inset when the mouse enters \emph on any tango object \emph default ( attribute or command), inside the synoptic drawing the name of the tango object is displayed in a tooltip. \end_layout \begin_layout Standard The following example (ThirdApplication), is a Synoptic \begin_inset Index status collapsed \begin_layout Plain Layout SynopticFileViewer \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout Synoptic \end_layout \end_inset application. We assume that the synoptic has already been drawn using Jdraw graphical editor. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code package examples; \end_layout \begin_layout LyX-Code import java.io.*; \end_layout \begin_layout LyX-Code import java.util.*; \end_layout \begin_layout LyX-Code import javax.swing.JFrame; \end_layout \begin_layout LyX-Code import javax.swing.JMenuItem; \end_layout \begin_layout LyX-Code import javax.swing.JMenuBar; \end_layout \begin_layout LyX-Code import javax.swing.JMenu; \end_layout \begin_layout LyX-Code import java.awt.event.ActionListener; \end_layout \begin_layout LyX-Code import java.awt.event.ActionEvent; \end_layout \begin_layout LyX-Code import java.awt.BorderLayout; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ErrorHistory; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.util.ATKGraphicsUtils; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.jdraw.SynopticFileViewer; \end_layout \begin_layout LyX-Code import fr.esrf.tangoatk.widget.jdraw.TangoSynopticHandler; \end_layout \begin_layout LyX-Code public class ThirdApplication extends JFrame \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code JMenuBar menu; \end_layout \begin_layout LyX-Code ErrorHistory errorHistory; // A window that displays errors \end_layout \begin_layout LyX-Code SynopticFileViewer sfv; // TangoATK generic synoptic viewer \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public ThirdApplication() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // Swing stuff to create the menu bar and its pulldown menus \end_layout \begin_layout LyX-Code menu = new JMenuBar(); \end_layout \begin_layout LyX-Code JMenu fileMenu = new JMenu(); \end_layout \begin_layout LyX-Code fileMenu.setText("File"); \end_layout \begin_layout LyX-Code JMenu viewMenu = new JMenu(); \end_layout \begin_layout LyX-Code viewMenu.setText("View"); \end_layout \begin_layout LyX-Code JMenuItem quitItem = new JMenuItem(); \end_layout \begin_layout LyX-Code quitItem.setText("Quit"); \end_layout \begin_layout LyX-Code quitItem.addActionListener(new java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {quitItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code fileMenu.add(quitItem); \end_layout \begin_layout LyX-Code JMenuItem errorHistItem = new JMenuItem(); \end_layout \begin_layout LyX-Code errorHistItem.setText("Error History"); \end_layout \begin_layout LyX-Code errorHistItem.addActionListener(new java.awt.event.ActionListener() \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public void actionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code {errHistItemActionPerformed(evt);} \end_layout \begin_layout LyX-Code }); \end_layout \begin_layout LyX-Code viewMenu.add(errorHistItem); \end_layout \begin_layout LyX-Code menu.add(fileMenu); \end_layout \begin_layout LyX-Code menu.add(viewMenu); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Here we create TangoATK synoptic viewer and error window. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code errorHistory = new ErrorHistory(); \end_layout \begin_layout LyX-Code sfv = new SynopticFileViewer(); \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code sfv.setErrorWindow(errorHistory); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (Exception setErrwExcept) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.out.println("Cannot set Error History Window"); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Here we define the name of the synoptic file to show and the tooltip mode to use \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code sfv.setJdrawFileName("/users/poncet/ATK_OLD/jdraw_files/id14.jdw"); \end_layout \begin_layout LyX-Code sfv.setToolTipMode (TangoSynopticHandler.TOOL_TIP_NAME); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (FileNotFoundException fnfEx) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.showMessageDialog( \end_layout \begin_layout LyX-Code null, "Cannot find the synoptic file : id14.jdw. \backslash n" \end_layout \begin_layout LyX-Code + "Check the file name you entered;" \end_layout \begin_layout LyX-Code + " Application will abort ... \backslash n" \end_layout \begin_layout LyX-Code + fnfEx, \end_layout \begin_layout LyX-Code "No such file", \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.ERROR_MESSAGE); \end_layout \begin_layout LyX-Code System.exit(-1); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (IllegalArgumentException illEx) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.showMessageDialog( \end_layout \begin_layout LyX-Code null, "Cannot parse the synoptic file : id14.jdw. \backslash n" \end_layout \begin_layout LyX-Code + "Check if the file is a Jdraw file." \end_layout \begin_layout LyX-Code + " Application will abort ... \backslash n" \end_layout \begin_layout LyX-Code + illEx, \end_layout \begin_layout LyX-Code "Cannot parse the file", \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.ERROR_MESSAGE); \end_layout \begin_layout LyX-Code System.exit(-1); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (MissingResourceException mrEx) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.showMessageDialog( \end_layout \begin_layout LyX-Code null, "Cannot parse the synoptic file : id14.jdw. \backslash n" \end_layout \begin_layout LyX-Code + " Application will abort ... \backslash n" \end_layout \begin_layout LyX-Code + mrEx, \end_layout \begin_layout LyX-Code "Cannot parse the file", \end_layout \begin_layout LyX-Code javax.swing.JOptionPane.ERROR_MESSAGE); \end_layout \begin_layout LyX-Code System.exit(-1); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Add the viewers into the frame to show them \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code getContentPane().setLayout(new BorderLayout()); \end_layout \begin_layout LyX-Code getContentPane().add(sfv, BorderLayout.CENTER); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // add the menubar to the frame \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code setJMenuBar(menu); \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // JFrame stuff to make the thing show. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code pack(); \end_layout \begin_layout LyX-Code ATKGraphicsUtils.centerFrameOnScreen(this); //TangoATK utility to center window \end_layout \begin_layout LyX-Code setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public static void main(String [] args) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code new ThirdApplication(); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public void quitItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code System.exit(0); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code public void errHistItemActionPerformed(ActionEvent evt) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code errorHistory.setVisible(true); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The synoptic \begin_inset Index status collapsed \begin_layout Plain Layout synoptic \end_layout \end_inset application (ThirdApplication) should look something like this (depending on your synoptic drawing file) \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \begin_inset Graphics filename img/prog_guide_exple3.jpg lyxscale 75 scale 40 \end_inset \end_layout \begin_layout Subsection A short note on the relationship between models and viewers \end_layout \begin_layout Standard As seen in the examples above, the connection between a model \begin_inset Index status collapsed \begin_layout Plain Layout model \end_layout \end_inset and its viewer \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset is generally done by calling \family typewriter setModel \begin_inset Index status collapsed \begin_layout Plain Layout setModel \end_layout \end_inset (model \begin_inset Index status collapsed \begin_layout Plain Layout model \end_layout \end_inset ) \family default on the viewer \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset , it is never explained what happens behind the scenes when this is done. \end_layout \begin_layout Subsubsection Listeners \end_layout \begin_layout Standard Most of the viewers \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset implement some sort of \emph on listener \begin_inset Index status collapsed \begin_layout Plain Layout listener \end_layout \end_inset \emph default interface, eg INumberScalarListener \begin_inset Index status collapsed \begin_layout Plain Layout INumberScalarListener \end_layout \end_inset . An object implementing such a listener interface has the capability of receiving and treating \emph on events \begin_inset Index status collapsed \begin_layout Plain Layout event \end_layout \end_inset \emph default from a model \begin_inset Index status collapsed \begin_layout Plain Layout model \end_layout \end_inset which emits events. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code // this is the setModel of a SimpleScalarViewer \end_layout \begin_layout LyX-Code public void setModel \begin_inset Index status collapsed \begin_layout Plain Layout setModel \end_layout \end_inset (INumberScalar scalar) { \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code clearModel(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code if (scalar != null) { \end_layout \begin_layout LyX-Code format = scalar.getProperty("format").getPresentation(); \end_layout \begin_layout LyX-Code numberModel = scalar; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // this is where the viewer connects itself to the \end_layout \begin_layout LyX-Code // model. After this the viewer will (hopefully) receive \end_layout \begin_layout LyX-Code // events through its numberScalarChange() method \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code numberModel.addNumberScalarListener(this); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code numberModel.getProperty("format").addPresentationListener(this); \end_layout \begin_layout LyX-Code numberModel.getProperty("unit").addPresentationListener(this); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // Each time the model of this viewer (the numberscalar attribute) decides it is time, it \end_layout \begin_layout LyX-Code // calls the numberScalarChange method of all its registered listeners \end_layout \begin_layout LyX-Code // with a NumberScalarEvent object which contains the \end_layout \begin_layout LyX-Code // the new value of the numberscalar attribute. \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code public void numberScalarChange(NumberScalarEvent evt) { \end_layout \begin_layout LyX-Code String val; \end_layout \begin_layout LyX-Code val = getDisplayString(evt); \end_layout \begin_layout LyX-Code if (unitVisible) { \end_layout \begin_layout LyX-Code setText(val + " " + numberModel.getUnit()); \end_layout \begin_layout LyX-Code } else { \end_layout \begin_layout LyX-Code setText(val); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard All listeners in TangoATK implement the \family typewriter IErrorListener \family default interface which specifies the \family typewriter errorChange(ErrorEvent e) \family default method. This means that all listeners are forced to handle errors in some way or another. \end_layout \begin_layout Section The key objects of TangoATK \end_layout \begin_layout Standard As seen from the examples above, the key objects of TangoATK are the \family typewriter CommandList \begin_inset Index status collapsed \begin_layout Plain Layout CommandList \end_layout \end_inset \family default and the \family typewriter AttributeList \family default \begin_inset Index status collapsed \begin_layout Plain Layout AttributeList \end_layout \end_inset . These two classes inherit from the abstract class \family typewriter AEntityList \family default which implements all of the common functionality between the two lists. These lists use the functionality of the \family typewriter CommandFactory \family default , the \family typewriter AttributeFactory \family default , which both derive from \family typewriter AEntityFactory, \family default and the \family typewriter DeviceFactory \family default . \end_layout \begin_layout Standard In addition to these factories and lists there is one (for the time being) other important functionality lurking around, the refreshers. \end_layout \begin_layout Subsection The Refreshers \end_layout \begin_layout Standard The refreshers \begin_inset Index status collapsed \begin_layout Plain Layout refresher \end_layout \end_inset , represented in TangoATK by the \family typewriter Refresher \family default object, is simply a subclass of \family typewriter java.lang.Thread \family default which will sleep for a given amount of time and then call a method refresh on whatever kind of \family typewriter IRefreshee \family default it has been given as parameter, as shown below \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code // This is an example from DeviceFactory. \end_layout \begin_layout LyX-Code // We create a new Refresher with the name "device" \end_layout \begin_layout LyX-Code // We add ourself to it, and start the thread \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code Refresher refresher = new Refresher("device"); \end_layout \begin_layout LyX-Code refresher.addRefreshee(this).start(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Both the \family typewriter AttributeList \begin_inset Index status collapsed \begin_layout Plain Layout AttributeList \end_layout \end_inset \family default and the \family typewriter DeviceFactory \family default implement the \family typewriter IRefreshee \family default interface which specify only one method, \family typewriter refresh() \family default , and can thus be refreshed by the \family typewriter Refresher \family default \begin_inset Index status collapsed \begin_layout Plain Layout refresher \end_layout \end_inset . Even if the new release of TangoATK is based on the Tango Events \begin_inset Index status collapsed \begin_layout Plain Layout event \end_layout \end_inset \begin_inset Index status collapsed \begin_layout Plain Layout Tango-Event \end_layout \end_inset , the refresher mecanisme will not be removed. As a matter of fact, the method refresh() implemented in \noun on AttributeList \noun default skips all attributes (members of the list) for which the subscribe \begin_inset Index status collapsed \begin_layout Plain Layout subscribe \end_layout \end_inset to the tango event has succeeded and calls the old refresh() method for the others (for which subscribe to tango events has failed). \end_layout \begin_layout Standard In a first stage this will allow the TangoATK applications to mix the use of the old tango device servers (which do not implement tango events) and the new ones in the same code. In other words, TangoATK subscribes for tango events if possible otherwise TangoATK will refresh the attributes through the old refresher mecanisme. \end_layout \begin_layout Standard Another reason for keeping the refresher is that the subscribe event can fail even for the attributes of the new Tango device servers. As soon as the specified attribute is not polled the Tango events cannot be generated for that attribute. Therefore the event subscription will fail. In this case the attribute will be refreshed thanks to the ATK attribute list refresher. \end_layout \begin_layout Standard The \family typewriter AttributePolledList \family default class allows the application programmer to force explicitly the use of the refresher method for all attributes added in an AttributePolledList even if the corresponding device servers implement tango events. Some viewers (fr.esrf.tangoatk.widget.attribute.Trend) need an AttributePolledList in order to force the refresh of the attribute without using tango events. \end_layout \begin_layout Subsubsection What happens on a refresh \end_layout \begin_layout Standard When \family typewriter refresh \begin_inset Index status collapsed \begin_layout Plain Layout refresh \end_layout \end_inset \family default is called on the \family typewriter AttributeList \family default and the \family typewriter DeviceFactory \family default , they loop through their objects, \family typewriter IAttributes \family default and \family typewriter IDevices \family default , respectively, and ask them to refresh themselves if they are not event driven. \end_layout \begin_layout Standard When \noun on AttributeFactory \noun default , creates an \family typewriter IAttribute \family default , TangoATK tries to subscribe for Tango Change event for that attribute. If the subscription succeeds then the attribute is marked as event driven. If the subscription for Tango Change event fails, TangoATK tries to subscribe for Tango Periodic event. If the subscription succeeds then the attribute is marked as event driven. If the subscription fails then the attribute is marked as to be \begin_inset Quotes eld \end_inset without events \begin_inset Quotes erd \end_inset . \end_layout \begin_layout Standard In the \noun on refresh() \noun default method of the \noun on AttributeList \noun default during the loop through the objects if the object is marked event driven then the object is simply skipped. But if the object (attribute) is not marked as event driven, the \noun on refresh() \noun default method of the \noun on AttributeList \noun default , asks the object to refresh itself by calling the \begin_inset Quotes eld \end_inset \noun on refresh() \noun default \begin_inset Quotes erd \end_inset method of that object (attribute or device). The \noun on refresh() \noun default method of an attribute will in turn call the \begin_inset Quotes eld \end_inset readAttribute \begin_inset Quotes erd \end_inset on the Tango device. \end_layout \begin_layout Standard The result of this is that the \family typewriter IAttributes \family default fire off events to their registered listeners \begin_inset Index status collapsed \begin_layout Plain Layout listener \end_layout \end_inset containing snapshots of their state. The events are fired either because the \noun on IAttribute \noun default has received a Tango Change event, respectively a Tango Periodic event (event driven objects), or because the \noun on refresh() \noun default method of the object has issued a readAttribute on the Tango device. \end_layout \begin_layout Subsection The DeviceFactory \end_layout \begin_layout Standard The device factory is responsible for two things \end_layout \begin_layout Enumerate Creating new devices (Tango device proxies) when needed \end_layout \begin_layout Enumerate Refreshing the state and status of these devices \end_layout \begin_layout Standard Regarding the first point, new devices are created when they are asked for and only if they have not already been created. If a programmer asks for the same device twice, she is returned a reference to the same device-object. \end_layout \begin_layout Standard The \family typewriter DeviceFactory \family default contains a Refresher as described above, which makes sure that the all \family sans Devices \family default in the \family sans DeviceFactory \family default updates their state and status and fire events to its listeners. \end_layout \begin_layout Subsection The AttributeFactory and the CommandFactory \end_layout \begin_layout Standard These factories are responsible for taking a name of an attribute or command and returning an object representing the attribute or command. It is also responsible for making sure that the appropriate \family typewriter IDevice \family default is already available. Normally the programmer does not want to use these factory classes directly. They are used by TangoATK classes indirectly when the application programmer calls the AttributeList's (or CommandList's) \noun on add() \noun default method. \end_layout \begin_layout Subsection The AttributeList \begin_inset Index status collapsed \begin_layout Plain Layout AttributeList \end_layout \end_inset and the CommandList \begin_inset Index status collapsed \begin_layout Plain Layout CommandList \end_layout \end_inset \end_layout \begin_layout Standard These lists are containers for attributes and commands. They delegate the construction-work to the factories mentioned above, and generally do not do much more, apart from containing refreshers, and thus being able to make the objects they contain refresh their listeners. \end_layout \begin_layout Subsection The Attributes \end_layout \begin_layout Standard The attributes \begin_inset Index status collapsed \begin_layout Plain Layout attributes \end_layout \end_inset come in several flavors. Tango supports the following types: \end_layout \begin_layout Itemize Short \end_layout \begin_layout Itemize Long \end_layout \begin_layout Itemize Double \end_layout \begin_layout Itemize String \end_layout \begin_layout Itemize Unsigned Char \end_layout \begin_layout Itemize Boolean \end_layout \begin_layout Itemize Unsigned Short \end_layout \begin_layout Itemize Float \end_layout \begin_layout Itemize Unsigned Long \end_layout \begin_layout Standard According to Tango specifications, all these types can be of the following formats: \end_layout \begin_layout Itemize Scalar, a single value \end_layout \begin_layout Itemize Spectrum, a single array \end_layout \begin_layout Itemize Image, a two dimensional array \end_layout \begin_layout Standard For the sake of simplicity, TangoATK has combined all the numeric types into one, presenting all of them as doubles. So the TangoATK classes which handle the numeric attributes are : NumberScalar, NumberSpectrum and NumberImage (Number can be short, long, double, float, ...). \end_layout \begin_layout Subsubsection The hierarchy \end_layout \begin_layout Standard The numeric attribute hierarchy is expressed in the following interfaces: \end_layout \begin_layout Description INumberScalar extends \series bold INumber \end_layout \begin_layout Description INumberSpectrum extends \series bold INumber \end_layout \begin_layout Description INumberImage extends \series bold INumber \end_layout \begin_layout Description \series medium and \series bold INumber \series default in turn extends \series bold IAttribute \series default \begin_inset space ~ \end_inset \end_layout \begin_layout Standard Each of these types emit their proper events and have their proper listeners. Please consult the javadoc for further information. \end_layout \begin_layout Subsection The Commands \end_layout \begin_layout Standard The commands \begin_inset Index status collapsed \begin_layout Plain Layout commands \end_layout \end_inset in Tango are rather ugly beasts. There exists the following kinds of commands \end_layout \begin_layout Itemize Those which take input \end_layout \begin_layout Itemize Those which do not take input \end_layout \begin_layout Itemize Those which do output \end_layout \begin_layout Itemize Those which do not do output \end_layout \begin_layout Standard Now, for both input and output we have the following types: \end_layout \begin_layout Itemize Double \end_layout \begin_layout Itemize Float \end_layout \begin_layout Itemize Unsigned Long \end_layout \begin_layout Itemize Long \end_layout \begin_layout Itemize Unsigned Short \end_layout \begin_layout Itemize Short \end_layout \begin_layout Itemize String \end_layout \begin_layout Standard These types can appear in scalar or array formats. In addition to this, there are also four other types of parameters: \end_layout \begin_layout Enumerate Boolean \end_layout \begin_layout Enumerate Unsigned Char Array \end_layout \begin_layout Enumerate The StringLongArray \end_layout \begin_layout Enumerate The StringDoubleArray \end_layout \begin_layout Standard The last two types mentioned above are two-dimensional arrays containing a string array in the first dimension and a long or double array in the second dimension, respectively. \end_layout \begin_layout Standard As for the attributes, all numeric types have been converted into doubles, but there has been made little or no effort to create an hierarchy of types for the commands. \end_layout \begin_layout Subsubsection Events \begin_inset Index status collapsed \begin_layout Plain Layout event \end_layout \end_inset and listeners \begin_inset Index status collapsed \begin_layout Plain Layout listener \end_layout \end_inset \end_layout \begin_layout Standard The commands publish results to their \family typewriter IResultListener \family default s, by the means of a \family typewriter ResultEvent \family default . The \family typewriter IResultListener \family default extends \family typewriter IErrorListener \family default , any viewer \begin_inset Index status collapsed \begin_layout Plain Layout viewer \end_layout \end_inset of command-results should also know how to handle errors. So a viewer of command-results implements IResultListener interface and registers itself as a resultListener for the command it has to show the results. \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \align center \begin_inset CommandInset label LatexCommand label name "TwoRicardo" \end_inset \begin_inset Graphics filename ../dance/0046-reduc.jpg scale 400 \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/atk/line.tex0000644023471100065110000000174013034745263013523 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/intro/0000755023471100065110000000000013034745265012506 500000000000000tango-9.2.5a/doc/src/intro/intro.lyx0000644023471100065110000002212513034745263014317 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 4 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter Introduction \end_layout \begin_layout Section Introduction to device server \end_layout \begin_layout Standard Device servers were first developed at the European Synchrotron radiation Facility (ESRF \begin_inset Index idx status collapsed \begin_layout Plain Layout ESRF \end_layout \end_inset ) for controlling the 6 Gev synchrotron radiation source. This document is a Programmer's Manual on how to write TANGO device servers. It will not go into the details of the ESRF \begin_inset Index idx status collapsed \begin_layout Plain Layout ESRF \end_layout \end_inset , nor its Control System nor any of the specific device servers in the Control System. The role of this document is to help programmers faced with the task of writing TANGO device servers. \end_layout \begin_layout Standard Device servers have been developed at the ESRF \begin_inset Index idx status collapsed \begin_layout Plain Layout ESRF \end_layout \end_inset in order to solve the main task of Control Systems viz provide read and write access to all devices in a distributed system. The problem of distributed device access is only part of the problem however. The other part of the problem is providing a programming framework for a large number of devices programmed by a large number of programmers each having different levels of experience and style. \end_layout \begin_layout Standard Device servers have been written at the ESRF \begin_inset Index idx status collapsed \begin_layout Plain Layout ESRF \end_layout \end_inset for a large variety of different devices. Devices vary from serial line devices to devices interfaced by field-bus to memory mapped VME cards or PC cards to entire data acquisition systems. The definition of a device depends very much on the user's requirements. In the simple case a device server can be used to hide the serial line protocol required to communicate with a device. For more complicated devices the device server can be used to hide the entire complexity of the device timing, configuration and acquisition cycle behind a set of high level commands. \end_layout \begin_layout Standard In this manual the process of how to write TANGO client (applications) and device servers will be treated. The manual has been organized as follows : \end_layout \begin_layout Itemize A getting started chapter. \end_layout \begin_layout Itemize The TANGO device server model is treated in chapter 3 \end_layout \begin_layout Itemize Generalities on the Tango Application Programmer Interfaces are given in chapter 4 \end_layout \begin_layout Itemize Chapter 5 is an a programmer's guide for the Tango Application ToolKit (TangoATK ). This is a Java toolkit to help Tango Java application developers. \end_layout \begin_layout Itemize How to write a TANGO device server is explained in chapter 6 \end_layout \begin_layout Itemize Chapter 7 describes advanced Tango features \end_layout \begin_layout Standard Throughout this manual examples of source code will be given in order to illustrate what is meant. Most examples have been taken from the StepperMotor class - a simulation of a stepper motor which illustrates how a typical device server for a stepper motor at the ESRF functions. \end_layout \begin_layout Section Device server history \end_layout \begin_layout Standard The concept of using device servers to access devices was first proposed at the ESRF in 1989. It has been successfully used as the heart of the ESRF \begin_inset Index idx status collapsed \begin_layout Plain Layout ESRF \end_layout \end_inset Control System for the institute accelerator complex. This Control System has been named TACO \begin_inset Index idx status collapsed \begin_layout Plain Layout TACO \end_layout \end_inset \begin_inset Foot status collapsed \begin_layout Plain Layout TACO stands for \series bold T \series default elescope and \series bold A \series default ccelerator \series bold C \series default ontrolled with \series bold O \series default bjects \end_layout \end_inset . Then, it has been decided to also used TACO to control devices in the beam-line s. Today, more than 30 instances of TACO are running at the ESRF. The main technologies used within TACO are the leading technologies of the 80's. The Sun Remote Procedure Call (RPC) is used to communicate over the network between device server and applications, OS-9 is used on the front-end computers , C is the reference language to write device servers and clients and the device server framework follows the MIT Widget model. In 1999, a renewal of the control system was started. In June 2002, Soleil \begin_inset Index idx status collapsed \begin_layout Plain Layout Soleil \end_layout \end_inset and ESRF offically decide to collaborate to develop this renewal of the old TACO control system. Soleil is a French synchrotron radiation facility currently under construction in the Paris suburbs. See \begin_inset CommandInset citation LatexCommand cite key "Soleil_home_page" \end_inset to get all information about Soleil. In December 2003, Elettra \begin_inset Index idx status collapsed \begin_layout Plain Layout Elettra \end_layout \end_inset joins the club. Elettra is an Italian synchrotron radiation facility located in Trieste. See \begin_inset CommandInset citation LatexCommand cite key "Elettra_home_page" \end_inset to get all information about Elettra. Then, beginning of 2005, ALBA \begin_inset Index idx status collapsed \begin_layout Plain Layout ALBA \end_layout \end_inset also decided to join. ALBA is a Spanish synchrotron radiation facility located in Barcelona. See \begin_inset CommandInset citation LatexCommand cite key "Alba_WEB" \end_inset to get all information about ALBA. The new version of the Alba/Elettra/ESRF/Soleil control system is named TANGO \begin_inset Foot status collapsed \begin_layout Plain Layout TANGO stands for \series bold TA \series default co \series bold N \series default ext \series bold G \series default eneration \series bold O \series default bject \end_layout \end_inset and is based on the 21 century technologies : \end_layout \begin_layout Itemize CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset \begin_inset Foot status collapsed \begin_layout Plain Layout CORBA stands for \series bold C \series default ommon \series bold O \series default bject \series bold R \series default equest \series bold B \series default roker \series bold A \series default rchitecture \end_layout \end_inset and ZMQ \begin_inset Index idx status collapsed \begin_layout Plain Layout ZMQ \end_layout \end_inset \begin_inset CommandInset citation LatexCommand cite key "ZMQ" \end_inset to communicate between device server and clients \end_layout \begin_layout Itemize C++, Python and Java as reference programming languages \end_layout \begin_layout Itemize Linux and Windows as operating systems \end_layout \begin_layout Itemize Modern object oriented design patterns \end_layout \end_body \end_document tango-9.2.5a/doc/src/intro/line.tex0000644023471100065110000000174013034745263014077 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/started/0000755023471100065110000000000013034745265013021 500000000000000tango-9.2.5a/doc/src/started/started.lyx0000644023471100065110000007513613034745264015160 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter Getting Started \end_layout \begin_layout Section A C++ TANGO client \end_layout \begin_layout Standard \noindent The quickest way of getting started is by studying this example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent /* \end_layout \begin_layout LyX-Code \noindent * example of a client using the TANGO C++ api. \end_layout \begin_layout LyX-Code \noindent */ \end_layout \begin_layout LyX-Code \noindent #include \end_layout \begin_layout LyX-Code \noindent using namespace Tango; \end_layout \begin_layout LyX-Code \noindent int main(unsigned int argc, char **argv) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // create a connection to a TANGO device \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code DeviceProxy *device = new DeviceProxy( \begin_inset Quotes eld \end_inset sys/database/2 \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Ping the device \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code device->ping(); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Execute a command on the device and extract the reply as a string \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code string db_info; \end_layout \begin_layout LyX-Code DeviceData cmd_reply; \end_layout \begin_layout LyX-Code cmd_reply = device->command_inout( \begin_inset Quotes eld \end_inset DbInfo \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code cmd_reply >> db_info; \end_layout \begin_layout LyX-Code cout << \begin_inset Quotes eld \end_inset Command reply \begin_inset Quotes eld \end_inset << db_info << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Read a device attribute (string data type) \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code string spr; \end_layout \begin_layout LyX-Code DeviceAttribute att_reply; \end_layout \begin_layout LyX-Code att_reply = device->read_attribute( \begin_inset Quotes eld \end_inset StoredProcedureRelease \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code att_reply >> spr; \end_layout \begin_layout LyX-Code cout << \begin_inset Quotes eld \end_inset Database device stored procedure release: \begin_inset Quotes eld \end_inset << spr << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \noindent catch (DevFailed &e) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent Except::print_exception(e); \end_layout \begin_layout LyX-Code \noindent exit(-1); \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent Modify this example to fit your device server or client's needs, compile it and link with the library -ltango. Forget about those painful early TANGO days when you had to learn CORBA and manipulate Any's. Life's going to easy and fun from now on ! \end_layout \begin_layout Section A TANGO device server \end_layout \begin_layout Standard The code given in this chapter as example has been generated using POGO. Pogo \begin_inset Index idx status collapsed \begin_layout Plain Layout Pogo \end_layout \end_inset is a code generator for Tango device server. See \begin_inset CommandInset citation LatexCommand cite key "Pogo doc" \end_inset for more information about POGO. The following examples briefly describe how to write device class with commands which receives and return different kind of Tango data types and also how to write device attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset The device class implements 5 commands and 3 attributes. The commands are : \end_layout \begin_layout Itemize The command \series bold DevSimple \series default deals with simple Tango data type \end_layout \begin_layout Itemize The command \series bold DevString \series default deals with Tango strings \end_layout \begin_layout Itemize \series bold DevArray \series default receive and return an array of simple Tango data type \end_layout \begin_layout Itemize \series bold DevStrArray \series default which does not receive any data but which returns an array of strings \end_layout \begin_layout Itemize \series bold DevStruct \series default which also does not receive data but which returns one of the two Tango composed types (DevVarDoubleStringArray) \end_layout \begin_layout Standard For all these commands, the default behavior of the state machine (command always allowed) is acceptable. The attributes are : \end_layout \begin_layout Itemize A spectrum type attribute of the Tango string type called \series bold StrAttr \end_layout \begin_layout Itemize A readable attribute of the Tango::DevLong type called \series bold LongRdAttr \series default . This attribute is linked with the following writable attribute \end_layout \begin_layout Itemize A writable attribute also of the Tango::DevLong type called \series bold LongWrAttr \series default . \end_layout \begin_layout Standard Since release 9, a Tango device also supports pipe. This is an advanced feature reserved for some specific cases. Therefore, there is no device pipe example in this "Getting started" chapter. \end_layout \begin_layout Subsection The commands and attributes code \end_layout \begin_layout Standard For each command called DevXxxx, pogo generates in the device class a method named dev_xxx which will be executed when the command is requested by a client. In this chapter, the name of the device class is \emph on DocDs \end_layout \begin_layout Subsubsection The DevSimple command \end_layout \begin_layout Standard This method receives a Tango::DevFloat \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevFloat \end_layout \end_inset type and also returns a data of the Tango::DevFloat type which is simply the double of the input value. The code for the method executed by this command is the following: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevFloat DocDs::dev_simple(Tango::DevFloat argin) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 Tango::DevFloat argout ; \end_layout \begin_layout LyX-Code 4 DEBUG_STREAM << "DocDs::dev_simple(): entering... !" << endl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 // Add your own code to control device here \end_layout \begin_layout LyX-Code 7 \end_layout \begin_layout LyX-Code 8 argout = argin * 2; \end_layout \begin_layout LyX-Code 9 return argout; \end_layout \begin_layout LyX-Code 10 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard This method is fairly simple. The received data is passed to the method as its argument. It is \end_layout \begin_layout Standard doubled at line 8 and the method simply returns the result. \end_layout \begin_layout Subsubsection The DevArray command \end_layout \begin_layout Standard This method receives a data of the Tango::DevVarLongArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset type and also returns a data of the Tango::DevVarLongArray type. Each element of the array is doubled. The code for the method executed by the command is the following : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarLongArray *DocDs::dev_array(const Tango::DevVarLongArray *argin) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 // POGO has generated a method core with argout allocation. \end_layout \begin_layout LyX-Code 4 // If you would like to use a static reference without copying, \end_layout \begin_layout LyX-Code 5 // See "TANGO Device Server Programmer's Manual" \end_layout \begin_layout LyX-Code 6 // (chapter x.x) \end_layout \begin_layout LyX-Code 7 //------------------------------------------------------------ \end_layout \begin_layout LyX-Code 8 Tango::DevVarLongArray *argout = new Tango::DevVarLongArray(); \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 DEBUG_STREAM << "DocDs::dev_array(): entering... !" << endl; \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 // Add your own code to control device here \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 long argin_length = argin->length(); \end_layout \begin_layout LyX-Code 15 argout->length(argin_length); \end_layout \begin_layout LyX-Code 16 for (int i = 0;i < argin_length;i++) \end_layout \begin_layout LyX-Code 17 (*argout)[i] = (*argin)[i] * 2; \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 return argout; \end_layout \begin_layout LyX-Code 20 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The argout data array is created at line 8. Its length is set at line 15 from the input argument length. The array is populated at line 16,17 and returned. This method allocates memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset for the argout array. This memory is freed by the Tango core classes after the data have been sent to the caller (no delete is needed). It is also possible to return data from a statically allocated array without copying. Look at chapter \begin_inset CommandInset ref LatexCommand ref reference "Data exchange" \end_inset for all the details. \end_layout \begin_layout Subsubsection The DevString command \end_layout \begin_layout Standard This method receives a data of the Tango::DevString \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevString \end_layout \end_inset type and also returns a data of the Tango::DevString type. The command simply displays the content of the input string and returns a hard-coded string. The code for the method executed by the command is the following : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevString DocDs::dev_string(Tango::DevString argin) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 // POGO has generated a method core with argout allocation. \end_layout \begin_layout LyX-Code 4 // If you would like to use a static reference without copying, \end_layout \begin_layout LyX-Code 5 // See "TANGO Device Server Programmer's Manual" \end_layout \begin_layout LyX-Code 6 // (chapter x.x) \end_layout \begin_layout LyX-Code 7 //------------------------------------------------------------ \end_layout \begin_layout LyX-Code 8 Tango::DevString argout; \end_layout \begin_layout LyX-Code 9 DEBUG_STREAM << "DocDs::dev_string(): entering... !" << endl; \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 // Add your own code to control device here \end_layout \begin_layout LyX-Code 12 \end_layout \begin_layout LyX-Code 13 cout << "the received string is " << argin << endl; \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 string str("Am I a good Tango dancer ?"); \end_layout \begin_layout LyX-Code 16 argout = new char[str.size() + 1]; \end_layout \begin_layout LyX-Code 17 strcpy(argout,str.c_str()); \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 return argout; \end_layout \begin_layout LyX-Code 20 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The argout string is created at line 8. Internally, this method is using a standard C++ string. Memory for the returned data is allocated at line 16 and is initialized at line 17. This method allocates memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset for the argout string. This memory is freed by the Tango core classes after the data have been sent to the caller (no delete is needed). It is also possible to return data from a statically allocated string without copying. Look at chapter \begin_inset CommandInset ref LatexCommand ref reference "Data exchange" \end_inset for all the details. \end_layout \begin_layout Subsubsection The DevStrArray command \end_layout \begin_layout Standard This method does not receive input data but returns an array of strings (Tango::DevVarStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset type). The code for the method executed by this command is the following: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarStringArray *DocDs::dev_str_array() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 // POGO has generated a method core with argout allocation. \end_layout \begin_layout LyX-Code 4 // If you would like to use a static reference without copying, \end_layout \begin_layout LyX-Code 5 // See "TANGO Device Server Programmer's Manual" \end_layout \begin_layout LyX-Code 6 // (chapter x.x) \end_layout \begin_layout LyX-Code 7 //------------------------------------------------------------ \end_layout \begin_layout LyX-Code 8 Tango::DevVarStringArray *argout = new Tango::DevVarStri ngArray(); \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 DEBUG_STREAM << "DocDs::dev_str_array(): entering... !" << endl; \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 // Add your own code to control device here \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 argout->length(3); \end_layout \begin_layout LyX-Code 15 (*argout)[0] = CORBA::string_dup("Rumba"); \end_layout \begin_layout LyX-Code 16 (*argout)[1] = CORBA::string_dup("Waltz"); \end_layout \begin_layout LyX-Code 17 string str("Jerck"); \end_layout \begin_layout LyX-Code 18 (*argout)[2] = CORBA::string_dup(str.c_str()); \end_layout \begin_layout LyX-Code 19 return argout; \end_layout \begin_layout LyX-Code 20 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The argout data array is created at line 8. Its length is set at line 14. The array is populated at line 15,16 and 18. The last array element is initialized from a standard C++ string created at line 17. Note the usage of the \emph on string_dup \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset \emph default function of the CORBA namespace. This is necessary for strings array due to the CORBA memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset allocation schema. \end_layout \begin_layout Subsubsection The DevStruct command \end_layout \begin_layout Standard This method does not receive input data but returns a structure of the Tango::De vVarDoubleStringArray \begin_inset Index idx status collapsed \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset type. This type is a composed type with an array of double and an array of strings. The code for the method executed by this command is the following: \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 Tango::DevVarDoubleStringArray *DocDs::dev_struct() \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 // POGO has generated a method core with argout allocation. \end_layout \begin_layout LyX-Code 4 // If you would like to use a static reference without copying, \end_layout \begin_layout LyX-Code 5 // See "TANGO Device Server Programmer's Manual" \end_layout \begin_layout LyX-Code 6 // (chapter x.x) \end_layout \begin_layout LyX-Code 7 //------------------------------------------------------------ \end_layout \begin_layout LyX-Code 8 Tango::DevVarDoubleStringArray *argout = new Tango::DevVarDoub leStringArray(); \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 DEBUG_STREAM << "DocDs::dev_struct(): entering... !" << endl; \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 // Add your own code to control device here \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 argout->dvalue.length(3); \end_layout \begin_layout LyX-Code 15 argout->dvalue[0] = 0.0; \end_layout \begin_layout LyX-Code 16 argout->dvalue[1] = 11.11; \end_layout \begin_layout LyX-Code 17 argout->dvalue[2] = 22.22; \end_layout \begin_layout LyX-Code 18 \end_layout \begin_layout LyX-Code 19 argout->svalue.length(2); \end_layout \begin_layout LyX-Code 20 argout->svalue[0] = CORBA::string_dup("Be Bop"); \end_layout \begin_layout LyX-Code 21 string str("Smurf"); \end_layout \begin_layout LyX-Code 22 argout->svalue[1] = CORBA::string_dup(str.c_str()); \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 return argout; \end_layout \begin_layout LyX-Code 25 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The argout data structure is created at line 8. The length of the double array in the output structure is set at line 14. The array is populated between lines 15 and 17. The length of the string array in the output structure is set at line 19. This string array is populated between lines 20 an 22 from a hard-coded string and from a standard C++ string. This method allocates memory \begin_inset Index idx status collapsed \begin_layout Plain Layout memory \end_layout \end_inset for the argout data. This memory is freed by the Tango core classes after the data have been sent to the caller (no delete is needed). Note the usage of the \emph on string_dup \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset \emph default function of the CORBA namespace. This is necessary for strings array due to the CORBA memory allocation schema. \end_layout \begin_layout Subsubsection The three attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset \end_layout \begin_layout Standard Some data have been added to the definition of the device class in order to store attributes value. These data are (part of the class definition) : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 protected : \end_layout \begin_layout LyX-Code 4 // Add your own data members here \end_layout \begin_layout LyX-Code 5 //----------------------------------------- \end_layout \begin_layout LyX-Code 6 Tango::DevString attr_str_array[5]; \end_layout \begin_layout LyX-Code 7 Tango::DevLong attr_rd; \end_layout \begin_layout LyX-Code 8 Tango::DevLong attr_wr; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard One data has been created for each attribute. As the StrAttr attribute is of type spectrum with a maximum X dimension of 5, an array of length 5 has been reserved. \end_layout \begin_layout Standard Several methods are necessary to implement these attributes. One method to read the hardware which is common to all "readable" attributes plus one "read" method for each readable attribute and one "write" method for each writable attribute. The code for these methods is the following : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code 1 void DocDs::read_attr_hardware(vector &attr_list) \end_layout \begin_layout LyX-Code 2 { \end_layout \begin_layout LyX-Code 3 DEBUG_STREAM << "DocDs::read_attr_hardware(vector &attr_list) entering... "<< endl; \end_layout \begin_layout LyX-Code 4 // Add your own code here \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 string att_name; \end_layout \begin_layout LyX-Code 7 for (long i = 0;i < attr_list.size();i++) \end_layout \begin_layout LyX-Code 8 { \end_layout \begin_layout LyX-Code 9 att_name = dev_attr->get_attr_by_ind(attr_list[i]).get_name(); \end_layout \begin_layout LyX-Code 10 \end_layout \begin_layout LyX-Code 11 if (att_name == "LongRdAttr") \end_layout \begin_layout LyX-Code 12 { \end_layout \begin_layout LyX-Code 13 attr_rd = 5; \end_layout \begin_layout LyX-Code 14 } \end_layout \begin_layout LyX-Code 15 } \end_layout \begin_layout LyX-Code 16 } \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 void DocDs::read_LongRdAttr(Tango::Attribute &attr) \end_layout \begin_layout LyX-Code 19 { \end_layout \begin_layout LyX-Code 20 DEBUG_STREAM << "DocDs::read_LongRdAttr(Tango::Attribute &attr) entering... "<< endl; \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 attr.set_value(&attr_rd); \end_layout \begin_layout LyX-Code 23 } \end_layout \begin_layout LyX-Code 24 \end_layout \begin_layout LyX-Code 25 void DocDs::read_LongWrAttr(Tango::Attribute &attr) \end_layout \begin_layout LyX-Code 26 { \end_layout \begin_layout LyX-Code 27 DEBUG_STREAM << "DocDs::read_LongWrAttr(Tango::Attribute &attr) entering... "<< endl; \end_layout \begin_layout LyX-Code 28 \end_layout \begin_layout LyX-Code 29 attr.set_value(&attr_wr); \end_layout \begin_layout LyX-Code 30 } \end_layout \begin_layout LyX-Code 31 \end_layout \begin_layout LyX-Code 32 void DocDs::write_LongWrAttr(Tango::WAttribute &attr) \end_layout \begin_layout LyX-Code 33 { \end_layout \begin_layout LyX-Code 34 DEBUG_STREAM << "DocDs::write_LongWrAttr(Tango::WAttribute &attr) entering... "<< endl; \end_layout \begin_layout LyX-Code 35 \end_layout \begin_layout LyX-Code 36 attr.get_write_value(attr_wr); \end_layout \begin_layout LyX-Code 37 DEBUG_STREAM << "Value to be written = " << attr_wr << endl; \end_layout \begin_layout LyX-Code 38 } \end_layout \begin_layout LyX-Code 39 \end_layout \begin_layout LyX-Code 40 void DocDs::read_StrAttr(Tango::Attribute &attr) \end_layout \begin_layout LyX-Code 41 { \end_layout \begin_layout LyX-Code 42 DEBUG_STREAM << "DocDs::read_StrAttr(Tango::Attribute &attr) entering... "<< endl; \end_layout \begin_layout LyX-Code 43 \end_layout \begin_layout LyX-Code 44 attr_str_array[0] = const_cast("Rock"); \end_layout \begin_layout LyX-Code 45 attr_str_array[1] = const_cast("Samba"); \end_layout \begin_layout LyX-Code 46 \end_layout \begin_layout LyX-Code 47 attr_set_value(attr_str_array, 2); \end_layout \begin_layout LyX-Code 48 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The \emph on read_attr_hardware \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attr-hardware \end_layout \end_inset () \emph default method is executed once when a client execute the read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset CORBA request whatever the number of attribute to be read is. The rule of this method is to read the hardware and to store the read values somewhere in the device object. In our example, only the LongRdAttr attribute internal value is set by this method at line 13. The method \emph on read_LongRdAttr() \emph default is executed by the read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset CORBA call when the LongRdAttr attribute is read but after the read_attr_hardwa re() method has been executed. Its rule is to set the attribute value in the TANGO core classes object representing the attribute. This is done at line 22. The method \emph on read_LongWrAttr() \emph default will be executed when the LongWrAttr attribute is read (after the \emph on read_attr_hardware() \emph default method). The attribute value is set at line 29. In the same manner, the method called \emph on read_StrAttr() \emph default will be executed when the attribute StrAttr is read. Its value is initialized in this method at line 44 and 45 with the \emph on string_dup \begin_inset Index idx status collapsed \begin_layout Plain Layout string-dup \end_layout \end_inset \emph default Tango function. There are several ways to code spectrum or image attribute of the DevString data type. A HowTo related to this topic is available on the Tango control system Web site. The \emph on write_LongWrAttr() \emph default method is executed when the LongWrAttr attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset value is set by a client. The new attribute value coming from the client is stored in the object data at line 36. \end_layout \begin_layout Standard Pogo also generates a file called "DocDsStateMachine.cpp" (for a Tango device server class called DocDs). This file is used to store methods coding the device state machine. By default a allways allowed state machine is provided. For more information about coding the state machine, refer to the chapter "Writing a device server". \end_layout \begin_layout Standard \begin_inset Newpage newpage \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 5cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset CommandInset label LatexCommand label name "APicture" \end_inset \begin_inset Graphics filename ../dance/tg_argentine.jpg groupId pictures \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/started/line.tex0000644023471100065110000000174013034745264014413 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/appendix/0000755023471100065110000000000013034745265013163 500000000000000tango-9.2.5a/doc/src/appendix/appendix.lyx0000644023471100065110000102273213034745264015457 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 5 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash appendix \end_layout \end_inset \end_layout \begin_layout Chapter Reference part \begin_inset CommandInset label LatexCommand label name "cha:Reference-part" \end_inset \end_layout \begin_layout Standard \series bold This chapter is only part of the TANGO device server reference guide. To get reference documentation about the C++ library classes, see \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . To get reference documentation about the Java classes, also see \begin_inset CommandInset citation LatexCommand cite key "TANGO_ref_man" \end_inset . \end_layout \begin_layout Section Device parameter \end_layout \begin_layout Standard A black box, a device description field, a device state and status are associate d with each TANGO device. \end_layout \begin_layout Subsection The device black box \end_layout \begin_layout Standard The device black box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset is managed as a circular buffer. It is possible to tune the buffer depth via a device property. This property name is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset device name->blackbox_depth \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset A default value is hard-coded to 50 if the property is not defined. This black box depth property is retrieved from the Tango property database during the device creation phase. \end_layout \begin_layout Subsection The device description field \end_layout \begin_layout Standard There are two ways to intialise the device description \begin_inset Index idx status collapsed \begin_layout Plain Layout description \end_layout \end_inset field. \end_layout \begin_layout Itemize At device creation time. Some constructors of the DeviceImpl class supports this field as parameter. If these constructor are not used, the device description field is set to a default value which is \emph on A Tango device \emph default . \end_layout \begin_layout Itemize With a property. A description field defines with this method overrides a device description defined at construction time. The property name is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset device name->description \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Subsection The device state and status \end_layout \begin_layout Standard Some constructors of the DeviceImpl class allows the initialisation of device state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset and/or status \begin_inset Index idx status collapsed \begin_layout Plain Layout status \end_layout \end_inset or device creation time. If these fields are not defined, a default value is applied. The default state is Tango::UNKOWN, the default status is \emph on Not Initialised. \end_layout \begin_layout Subsection The device polling \begin_inset CommandInset label LatexCommand label name "sub:The-device-polling-prop" \end_inset \end_layout \begin_layout Standard Seven device properties allow the polling tunning. These properties are described in the following table \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Property name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout property rule \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout poll_ring_depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Polling buffer depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cmd_poll_ring_depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Cmd polling buffer depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout attr_poll_ring_depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attr polling buffer depth \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout poll_old_factor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Data too old" factor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_poll_period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Minimun polling period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cmd_min_poll_period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Min. polling period for cmd \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout attr_min_poll_period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Min. polling period for attr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The rule of the poll_ring_depth \begin_inset Index idx status collapsed \begin_layout Plain Layout poll-ring-depth \end_layout \end_inset property is obvious. It defines the polling ring depth for all the device polled command(s) and attribute(s). Nevertheless, when filling the polling buffer via the fill_cmd_polling_buffer() \begin_inset Index idx status collapsed \begin_layout Plain Layout fill-cmd-polling-buffer \end_layout \end_inset (or fill_attr_polling_buffer() \begin_inset Index idx status collapsed \begin_layout Plain Layout fill-attr-polling-buffer \end_layout \end_inset ) method, it could be helpfull to define specific polling ring depth for a command (or an attribute). This is the rule of the cmd_poll_ring_depth \begin_inset Index idx status collapsed \begin_layout Plain Layout cmd-poll-ring-depth \end_layout \end_inset and attr_poll_ring_depth \begin_inset Index idx status collapsed \begin_layout Plain Layout attr-poll-ring-depth \end_layout \end_inset properties. For each polled object with specific polling depth (command or attribute), the syntax of this property is the object name followed by the ring depth (ie State,20,Status,15). If one of these properties is defined, for the specific command or attribute, it will overwrite the value set by the poll_ring_depth property. The poll_old_factor \begin_inset Index idx status collapsed \begin_layout Plain Layout poll-old-factor \end_layout \end_inset property allows the user to tune how long the data recorded in the polling buffer are valid. Each time some data are read from the polling buffer, a check is done between the date when the data were recorded in the polling buffer and the date when the user request these data. If the interval is greater than the object polling period multiply by the value of the poll_old_factor factory, an exception is returned to the caller. These two properties are defined at device level and therefore, it is not possible to tune this parameter for each polled object (command or attribute). The last 3 properties are dedicated to define a polling period minimum threshold. The property min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout min-poll-period \end_layout \end_inset defines in (mS) a device minimum polling period. Property cmd_min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout cmd-min-poll-period \end_layout \end_inset defines (in mS) a minimum polling period for a specific command. The syntax of this property is the command name followed by the minimum polling period (ie MyCmd,400). Property attr_min_poll_period \begin_inset Index idx status collapsed \begin_layout Plain Layout attr-min-poll-period \end_layout \end_inset defines (in mS) a minimum polling period for a specific attribute. The syntax of this property is the attribute name followed by the minimum polling period (ie MyAttr,600). These two properties has a higher priority than the min_poll_period property. By default these three properties are not defined mening that there is no minimun polling period. \end_layout \begin_layout Standard Four other properties are used by the Tango core classes to manage the polling thread. These properties are : \end_layout \begin_layout Itemize polled_cmd to memorize the name of the device polled command \end_layout \begin_layout Itemize polled_attr to memorize the name of the device polled attribute \end_layout \begin_layout Itemize non_auto_polled_cmd to memorize the name of the command which shoule not be polled automatically at the first request \end_layout \begin_layout Itemize non_auto_polled_attr to memorize the name of the attribute which should not be polled automatically at the first request \end_layout \begin_layout Standard You don't have to change these properties values by yourself. They are automatically created/modified/deleted by Tango core classes. \end_layout \begin_layout Subsection The device logging \end_layout \begin_layout Standard The Tango Logging Service (TLS) uses device properties to control device logging at startup (static configuration). These properties are described in the following table \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Property name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout property rule \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout logging_level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Initial device logging level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout WARN \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout logging_target \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Initial device logging target \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No default \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout logging_rft \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Logging rolling file threshold \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 20 Mega bytes \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout logging_path \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Logging file path \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout /tmp/tango- or \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout C:/tango- (Windows) \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Itemize The logging_level \begin_inset Index idx status collapsed \begin_layout Plain Layout logging-level \end_layout \end_inset property controls the initial logging level of a device. Its set of possible values is: "OFF", "FATAL", "ERROR", "WARN", "INFO" or "DEBUG". This property is overwritten by the verbose command line option (-v). \end_layout \begin_layout Itemize The logging_target \begin_inset Index idx status collapsed \begin_layout Plain Layout logging-target \end_layout \end_inset property is a multi-valued property containing the initial target list. Each entry must have the following format: target_type::target_name (where target_type is one of the supported target types and target_name, the name of the target). Supported target types are: \emph on console \emph default , \emph on file \emph default and \emph on device \emph default . For a device target, target_name must contain the name of a log consumer device (as defined in \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango-log-consumer" \end_inset ). For a file target, target_name is the name of the file to log to. If omitted the device's name is used to build the file name (domain_family_memb er.log). Finally, target_name is ignored in the case of a console target. The TLS does not report any error occurred while trying to setup the initial targets. \end_layout \begin_deeper \begin_layout Itemize Logging_target property example : \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset logging_target = [ "console", "file", "file::/home/me/mydevice.log", "device::tmp /log/1"] \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset In this case, the device will automatically logs to the standard output, to its default file (which is something like domain_family_member.log), to a file named mydevice.log and located in /home/me. Finally, the device logs are also sent to a log consumer device named tmp/log/1. \end_layout \end_deeper \begin_layout Itemize The logging_rft \begin_inset Index idx status collapsed \begin_layout Plain Layout logging-rft \end_layout \end_inset property specifies the rolling file threshold (rft), of the device's file targets. This threshold is expressed in Kb. When the size of a log file reaches the so-called rolling-file-threshold (rft), it is backuped as " \emph on current_log_file_name \emph default " + " \emph on _1 \emph default " and a new current_log_file_name is opened. Obviously, there is only one backup file at a time (i.e. any existing backup is destroyed before the current log file is backuped). The default threshold is 20 Mb, the minimum is 500 Kb and the maximum is 1000 Mb. \end_layout \begin_layout Itemize The logging_path \begin_inset Index idx status collapsed \begin_layout Plain Layout logging-path \end_layout \end_inset property overwrites the TANGO_LOG_PATH \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-LOG-PATH \end_layout \end_inset environment variable. This property can only be applied to a DServer class device and has no effect on other devices. \end_layout \begin_layout Section Device attribute \end_layout \begin_layout Standard Attribute are configured with two kind of parameters: Parameters hard-coded in source code and modifiable parameters \end_layout \begin_layout Subsection Hard-coded device attribute parameters \end_layout \begin_layout Standard Seven attribute parameters are defined at attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout attribute \end_layout \end_inset creation time in the Tango class source code. Obviously, these parameters are not modifiable except with a new source code compilation. These parameters are \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout data_type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout data_format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute data format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout writable \begin_inset Index idx status collapsed \begin_layout Plain Layout writable \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute read/write type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_dim_x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Maximum X dimension \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_dim_y \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Maximum Y dimension \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout writable_attr_name \begin_inset Index idx status collapsed \begin_layout Plain Layout writable-attr-name \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Associated write attribute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout level \begin_inset Index idx status collapsed \begin_layout Plain Layout level \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute display level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout root_attr_name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Root attribute name \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsubsection The Attribute data type \begin_inset Index idx status collapsed \begin_layout Plain Layout data-type \end_layout \end_inset \end_layout \begin_layout Standard Thirteen data types are supported. These data types are \end_layout \begin_layout Itemize Tango::DevBoolean \end_layout \begin_layout Itemize Tango::DevShort \end_layout \begin_layout Itemize Tango::DevLong \end_layout \begin_layout Itemize Tango::DevLong64 \end_layout \begin_layout Itemize Tango::DevFloat \end_layout \begin_layout Itemize Tango::DevDouble \end_layout \begin_layout Itemize Tango::DevUChar \end_layout \begin_layout Itemize Tango::DevUShort \end_layout \begin_layout Itemize Tango::DevULong \end_layout \begin_layout Itemize Tango::DevULong64 \end_layout \begin_layout Itemize Tango::DevString \end_layout \begin_layout Itemize Tango::DevState \end_layout \begin_layout Itemize Tango::DevEncoded \end_layout \begin_layout Subsubsection The attribute data format \begin_inset Index idx status collapsed \begin_layout Plain Layout data-format \end_layout \end_inset \end_layout \begin_layout Standard Three data format are supported for attribute \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::SCALAR \begin_inset Index idx status collapsed \begin_layout Plain Layout SCALAR \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The attribute value is a single number \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::SPECTRUM \begin_inset Index idx status collapsed \begin_layout Plain Layout SPECTRUM \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The attribute value is a one dimension number \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::IMAGE \begin_inset Index idx status collapsed \begin_layout Plain Layout IMAGE \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The attribute value is a two dimension number \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsubsection The max_dim_x \begin_inset Index idx status collapsed \begin_layout Plain Layout max-dim-x \end_layout \end_inset and max_dim_y \begin_inset Index idx status collapsed \begin_layout Plain Layout max-dim-y \end_layout \end_inset parameters \end_layout \begin_layout Standard These two parameters defined the maximum size for attributes of the SPECTRUM and IMAGE data format. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout data format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_dim_x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_dim_y \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::SCALAR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::SPECTRUM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout User Defined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::IMAGE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout User Defined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout User Defined \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard For attribute of the Tango::IMAGE data format, all the data are also returned in a one dimension array. The first array is value[0],[0], array element X is value[0],[X-1], array element X+1 is value[1][0] and so forth. \end_layout \begin_layout Subsubsection The attribute read/write type \end_layout \begin_layout Standard Tango supports four kind of read/write attribute which are : \end_layout \begin_layout Itemize Tango::READ \begin_inset Index idx status collapsed \begin_layout Plain Layout READ \end_layout \end_inset for read only attribute \end_layout \begin_layout Itemize Tango::WRITE \begin_inset Index idx status collapsed \begin_layout Plain Layout WRITE \end_layout \end_inset for writable attribute \end_layout \begin_layout Itemize Tango::READ_WRITE \begin_inset Index idx status collapsed \begin_layout Plain Layout READ-WRITE \end_layout \end_inset for attribute which can be read and write \end_layout \begin_layout Itemize Tango::READ_WITH_WRITE \begin_inset Index idx status collapsed \begin_layout Plain Layout READ-WITH-WRITE \end_layout \end_inset for a readable attribute associated to a writable attribute (For a power supply device, the current really generated is not the wanted current. To handle this, two attributes are defined which are \emph on generated_current \emph default and \emph on wanted_current \emph default . The \emph on wanted_current \emph default is a Tango::WRITE attribute. When the \emph on generated_current \emph default attribute is read, it is very convenient to also get the \emph on wanted_current \emph default attribute. This is exactly what the Tango::READ_WITH_WRITE attribute is doing) \end_layout \begin_layout Standard When read, attribute values are always returned within an array even for scalar attribute. The length of this array and the meaning of its elements is detailed in the following table for scalar attribute. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array length \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WITH_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Associated attributelast write value \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard When a spectrum or image attribute is read, it is possible to code the device class in order to send only some part of the attribute data (For instance only a Region Of Interest for an image) but never more than what is defined by the attribute configuration parameters max_dim_x and max_dim_y. The number of data sent is also transferred with the data and is named \series bold dim_x \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout dim-x \end_layout \end_inset and \series bold dim_y \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout dim-y \end_layout \end_inset . When a spectrum or image attribute is written, it is also possible to send only some of the attribute data but always less than max_dim_x for spectrum and max_dim_x * max_dim_y for image. The following table describe how data are returned for spectrum attribute. dim_x is the data size sent by the server when the attribute is read and dim_x_w is the data size used during the last attribute write call. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array length \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[0->dim_x-1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[dim_x -> dim_x + dim_x_w -1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_x_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_x + dim_x_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WITH_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_x + dim_x_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Associated attributelast write values \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The following table describe how data are returned for image attribute. dim_r is the data size sent by the server when the attribute is read (dim_x * dim_y) and dim_w is the data size used during the last attribute write call (dim_x_w * dim_y_w). \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array length \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[0->dim_r-1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Array[dim_r-> dim_r + dim_w -1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_r \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_r + dim_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Last write values \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::READ_WITH_WRITE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout dim_r + dim_w \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Read value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Associated attributelast write values \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Until a write operation has been performed, the last write value is initialized to \emph on 0 \emph default for scalar attribute of the numeriacal type, to \emph on "Not Initialised" \emph default for scalar string attribute and to \emph on true \emph default for scalar boolean attribute. For spectrum or image attribute, the last write value is initialized to an array of one element set to \emph on 0 \emph default for numerical type, to an array of one element set to \emph on true \emph default for boolean attribute and to an array of one element set to " \emph on Not initialized \emph default " for string attribute \end_layout \begin_layout Subsubsection The associated write attribute parameter \end_layout \begin_layout Standard This parameter has a meaning only for attribute with a Tango::READ_WITH_WRITE read/write type. This is the name of the associated write attribute. \end_layout \begin_layout Subsubsection The attribute display level \begin_inset Index idx status collapsed \begin_layout Plain Layout level \end_layout \end_inset parameter \begin_inset CommandInset label LatexCommand label name "display level" \end_inset \end_layout \begin_layout Standard This parameter is only an help for graphical application. It is a C++ enumeration starting at 0. The code associated with each attribute display level is defined in the following table (Tango::DispLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout DispLevel \end_layout \end_inset ). \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::OPERATOR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::EXPERT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard This parameter allows a graphical application to support two types of operation : \end_layout \begin_layout Itemize An operator mode for day to day operation \end_layout \begin_layout Itemize An expert mode when tuning is necessary \end_layout \begin_layout Standard According to this parameter, a graphical application knows if the attribute is for the operator mode or for the expert mode. \end_layout \begin_layout Subsubsection The root attribute \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium root-attribute \end_layout \end_inset name parameter \end_layout \begin_layout Standard In case the attribute is a forwarded one, this parameter is the name of the associated root attribute. In case of classical attribute, this string is set to "Not specified". \end_layout \begin_layout Subsection Modifiable attribute parameters \end_layout \begin_layout Standard Each attribute has a configuration set of 20 modifiable parameters. These can be grouped in three different purposes: \end_layout \begin_layout Enumerate General purpose parameters \end_layout \begin_layout Enumerate Alarm related parameters \end_layout \begin_layout Enumerate Event related parameters \end_layout \begin_layout Subsubsection General purpose parameters \end_layout \begin_layout Standard Eight attribute parameters are modifiable at run-time via a device call or via the property database. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout label \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute label \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout standard_unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Conversion factor to MKSA unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout display_unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout The attribute unit in a printable form \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout How to print attribute value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute min value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute max value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout enum_labels \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Enumerated labels \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout memorized \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute memorization \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The \series bold description \begin_inset Index idx status collapsed \begin_layout Plain Layout description \end_layout \end_inset \series default parameter describes the attribute. The \series bold label \begin_inset Index idx status collapsed \begin_layout Plain Layout label \end_layout \end_inset \series default parameter is used by graphical application to display a label when this attribute is used in a graphical application. The \series bold unit \begin_inset Index idx status collapsed \begin_layout Plain Layout unit \end_layout \end_inset \series default parameter is the attribute value unit. The \series bold standard_unit \begin_inset Index idx status collapsed \begin_layout Plain Layout standard-unit \end_layout \end_inset \series default parameter is the conversion factor to get attribute value in MKSA units. Even if this parameter is a number, it is returned as a string by the device \emph on get_attribute_config \emph default call. The \series bold display_unit \begin_inset Index idx status collapsed \begin_layout Plain Layout display-unit \end_layout \end_inset \series default parameter is the string used by graphical application to display attribute unit to application user. The \series bold enum_labels \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium enum_labels \end_layout \end_inset \series default parameter is defined only for attribute of the DEV_ENUM data type. This is a vector of strings with one string for each enumeration label. It is an ordered list. \end_layout \begin_layout Paragraph The format \begin_inset Index idx status collapsed \begin_layout Plain Layout format \end_layout \end_inset attribute parameter \end_layout \begin_layout Standard This parameter specifies how the attribute value should be printed. It is not valid for string attribute. This format is a string of C++ streams manipulators separated by the \series bold ; \series default character. The supported manipulators are : \end_layout \begin_layout Itemize fixed \end_layout \begin_layout Itemize scientific \end_layout \begin_layout Itemize uppercase \end_layout \begin_layout Itemize showpoint \end_layout \begin_layout Itemize showpos \end_layout \begin_layout Itemize setprecision() \end_layout \begin_layout Itemize setw() \end_layout \begin_layout Standard Their definition are the same than for C++ streams. An example of format parameter is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset scientific;uppercase;setprecision(3) \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset . A class called Tango::AttrManip has been written to handle this format string. Once the attribute format string has been retrieved from the device, its value can be printed with \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset cout << Tango::AttrManip(format) << value << endl; \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset . \end_layout \begin_layout Paragraph The min_value \begin_inset Index idx status collapsed \begin_layout Plain Layout min-value \end_layout \end_inset and max_value \begin_inset Index idx status collapsed \begin_layout Plain Layout max-value \end_layout \end_inset parameters \end_layout \begin_layout Standard These two parameters have a meaning only for attribute of the Tango::WRITE read/write type and for numerical data types. Trying to set the value of an attribute to something less than or equal to the min_value parameter is an error. Trying to set the value of the attribute to something more or equal to the max_value parameter is also an error. Even if these parameters are numbers, they are returned as strings by the device \emph on get_attribute_config() \emph default call. \end_layout \begin_layout Standard These two parameters have no meaning for attribute with data type DevString, DevBoolean or DevState. An exception is thrown in case the user try to set them for attribute of these 3 data types. \end_layout \begin_layout Paragraph The memorized \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium memorized \end_layout \end_inset attribute parameter \end_layout \begin_layout Standard This parameter describes the attribute memorization. It is an enumeration with the following values: \end_layout \begin_layout Itemize NOT_KNOWN : The device is too old to return this information. \end_layout \begin_layout Itemize NONE : The attribute is not memorized \end_layout \begin_layout Itemize MEMORIZED : The attribute is memorized \end_layout \begin_layout Itemize MEMORIZED_WRITE_INIT : The attribute is memorized and the memorized value is applied at device initialization time. \end_layout \begin_layout Subsubsection The alarm related configuration parameters \end_layout \begin_layout Standard Six alarm related attribute parameters are modifiable at run-time via a device call or via the property database. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute low level alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute high level alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute low level warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute high level warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta time for RDS alarm (mS) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_val \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta value for RDS alarm (absolute) \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset These parameters have no meaning for attribute with data type DevString, DevBoolean or DevState. An exception is thrown in case the user try to set them for attribute of these 3 data types. \end_layout \begin_layout Paragraph The min_alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout min-alarm \end_layout \end_inset and max_alarm \begin_inset Index idx status collapsed \begin_layout Plain Layout max-alarm \end_layout \end_inset parameters \end_layout \begin_layout Standard These two parameters have a meaning only for attribute of the Tango::READ, Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. When the attribute is read, if its value is something less than or equal to the min_alarm parameter or if it is something more or equal to the max_alarm parameter, the attribute quality factor will be set to Tango::ATTR_ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-ALARM \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset . Even if these parameters are numbers, they are returned as strings by the device \emph on get_attribute_config() \emph default call. \end_layout \begin_layout Paragraph The min_warning \begin_inset Index idx status collapsed \begin_layout Plain Layout min-warning \end_layout \end_inset and max_warning \begin_inset Index idx status collapsed \begin_layout Plain Layout max-warning \end_layout \end_inset parameters \end_layout \begin_layout Standard These two parameters have a meaning only for attribute of the Tango::READ, Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. When the attribute is read, if its value is something less than or equal to the min_warning parameter or if it is something more or equal to the max_warning parameter, the attribute quality factor will be set to Tango::ATTR_ WARNING \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-WARNING \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset . Even if these parameters are numbers, they are returned as strings by the device \emph on get_attribute_config() \emph default call. \end_layout \begin_layout Paragraph The delta_t \begin_inset Index idx status collapsed \begin_layout Plain Layout delta-t \end_layout \end_inset and delta_val \begin_inset Index idx status collapsed \begin_layout Plain Layout delta-val \end_layout \end_inset parameters \end_layout \begin_layout Standard These two parameters have a meaning only for attribute of the Tango::READ_WRITE and Tango::READ_WITH_WRITE read/write type and for numerical data type. They specify if and how the RDS \begin_inset Index idx status collapsed \begin_layout Plain Layout RDS \end_layout \end_inset alarm is used. When the attribute is read, if the difference between its read value and the last written value is something more than or equal to the delta_val parameter and if at least delta_val milli seconds occurs since the last write operation, the attribute quality factor will be set to Tango::ATTR_ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ATTR-ALARM \end_layout \end_inset and if the device state is Tango::ON, it is switched to Tango::ALARM \begin_inset Index idx status collapsed \begin_layout Plain Layout ALARM \end_layout \end_inset . Even if these parameters are numbers, they are returned as strings by the device \emph on get_attribute_config() \emph default call. \end_layout \begin_layout Subsubsection The event related configuration parameters \end_layout \begin_layout Standard Six event \begin_inset Index idx status collapsed \begin_layout Plain Layout event \end_layout \end_inset related attribute parameters are modifiable at run-time via a device call or via the property database. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout rel_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Relative change triggering change event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout abs_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Absolute change triggering change event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Period for periodic event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_rel_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Relative change for archive event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_abs_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Absolute change for archive event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Period for change archive event \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Paragraph The rel_change and abs_change parameters \end_layout \begin_layout Standard Rel_change \begin_inset Index idx status collapsed \begin_layout Plain Layout rel-change \end_layout \end_inset is a property with a maximum of 2 values (comma separated). It specifies the increasing and decreasing relative change of the attribute value (w.r.t. the value of the previous change event) which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value's satisfies the above criterium. It's the absolute value of these values which is taken into account. If only one value is specified then it is used for the increasing and decreasin g change. \end_layout \begin_layout Standard Abs_change \begin_inset Index idx status collapsed \begin_layout Plain Layout abs-change \end_layout \end_inset is a property of maximum 2 values (comma separated). It specifies the increasing and decreasing absolute change of the attribute value (w.r.t the value of the previous change event) which will trigger the event. If the attribute is a spectrum or an image then a change event is generated if any one of the attribute value's satisfies the above criterium. If only one value is specified then it is used for the increasing and decreasin g change. If no values are specified then the relative change is used. \end_layout \begin_layout Paragraph The periodic period \begin_inset Index idx status collapsed \begin_layout Plain Layout period \end_layout \end_inset parameter \end_layout \begin_layout Standard The minimum time between events (in milliseconds). If no property is specified then a default value of 1 second is used. \end_layout \begin_layout Paragraph The archive_rel_change \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-rel-change \end_layout \end_inset , archive_abs_change \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-abs-change \end_layout \end_inset and archive_period \begin_inset Index idx status collapsed \begin_layout Plain Layout archive-period \end_layout \end_inset parameters \end_layout \begin_layout Standard archive_rel_change is an array property of maximum 2 values which specifies the positive and negative relative change w.r.t. the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then a default fo +-10% is used \end_layout \begin_layout Standard archive_abs_change is an array property of maximum 2 values which specifies the positive and negative absolute change w.r.t the previous attribute value which will trigger the event. If the attribute is a spectrum or an image then an archive event is generated if any one of the attribute value's satisfies the above criterium. If only one property is specified then it is used for the positive and negative change. If no properties are specified then the relative change is used. \end_layout \begin_layout Standard archive_period is the minimum time between archive events (in milliseconds). If no property is specified, no periodic archiving events are send. \end_layout \begin_layout Subsection Setting modifiable attribute parameters \end_layout \begin_layout Standard A default value is given to all modifiable attribute parameters by the Tango core classes. Nevertheless, it is possible to modify these values in source code at attribute creation time or via the database. Values retrieved from the database have a higher priority than values given at attribute creation time. The attribute parameters are therefore initialized from: \end_layout \begin_layout Enumerate The Database \end_layout \begin_layout Enumerate If nothing in database, from the Tango class default \end_layout \begin_layout Enumerate If nothing in database nor in Tango class default, from the library default value \end_layout \begin_layout Standard The default value set by the Tango core library are \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Library default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "No description" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout label \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout One empty string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout general \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout standard_unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "No standard unit" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout purpose \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout display_unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "No display unit" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout format \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 6 characters with 2 decimal \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout alarm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout parameters \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_warning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_t \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout delta_val \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout rel_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout abs_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout event \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1000 (mS) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout parameters \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_rel_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_abs_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout archive_period \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard It is possible to set modifiable parameters via the database at two levels : \end_layout \begin_layout Enumerate At class level \end_layout \begin_layout Enumerate At device level. Each device attribute have all its modifiable parameters sets to the value defined at class level. If the setting defined at class level is not correct for one device, it is possible to re-define it. \end_layout \begin_layout Standard If we take the example of a class called \emph on BumperPowerSupply \emph default with three devices called \emph on sr/bump/1 \emph default , \emph on sr/bump/2 \emph default and \emph on sr/bump/3 \emph default and one attribute called \emph on wanted_current \emph default . For the first two bumpers, the max_value is equal to 500. For the third one, the max_value is only 400. If the max_value parameter is defined at class level with the value 500, all devices will have 500 as max_value for the \emph on wanted_current \emph default attribute. It is necessary to re-defined this parameter at device level in order to have the max_value for device sr/bump/3 set to 400. \end_layout \begin_layout Standard For the description, label, unit, standard_unit, display_unit and format parameters, it is possible to return them to their default value by setting them to an empty string. \end_layout \begin_layout Subsection Resetting modifiable attribute parameters \end_layout \begin_layout Standard It is possible to reset attribute parameters to their default value at any moment. This could be done via the network call available through the DeviceProxy::set_ attribute_config() method family. This call takes attribute parameters as strings. The following table describes which string has to be used to reset attribute parameters to their default value. In this table, the user default are the values given within Pogo in the "Properties" tab of the attribute edition window (or in in Tango class code using the Tango::UserDefaultAttrProp class). \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Input string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Action \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "Not specified" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Reset to \series bold library \series default default \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "" (empty string) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Reset to \series bold user \series default default if any. Otherwise, reset to \series bold library \series default default \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "NaN" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Reset to Tango \series bold class \series default default if any \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Otherwise, reset to \series bold user \series default default (if any) or to \series bold library \series default default \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center Let's take one exemple: For one attribute belonging to a device, we have the following attribute parameters: \begin_inset VSpace 0.3cm \end_inset \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Def. class \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Def. user \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Def. lib \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout standard_unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No standard unit \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout min_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Not specified \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout max_value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 50 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Not specified \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout rel_change \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Not specified \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The string "Not specified" sent to each attribute parameter will set attribute parameter value to "No standard unit" for standard_unit, "Not specified" for min_value, "Not specified" for max_value and "Not specified" as well for rel_change. The empty string sent to each attribute parameter will result with "No stanadard unit" for standard_unit, 5 for min_value, "Not specified" for max_value and 10 for rel_change. The string "NaN" will give "No standard unit" for standard_unit, 5 for min_value, 50 for max_value and 5 for rel_change. \end_layout \begin_layout Standard C++ specific: Instead of the string "Not specified" and "NaN", the preprocessor define \series bold AlrmValueNotSpec \series default and \series bold NotANumber \series default can be used. \end_layout \begin_layout Section Device pipe \end_layout \begin_layout Standard Pipe are configured with two kind of parameters: Parameters hard-coded in source code and modifiable parameters \end_layout \begin_layout Subsection Hard-coded device pipe parameters \end_layout \begin_layout Standard Three pipe parameters are defined at pipe \begin_inset Index idx status collapsed \begin_layout Plain Layout pipe \end_layout \end_inset creation time in the Tango class source code. Obviously, these parameters are not modifiable except with a new source code compilation. These parameters are \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pipe name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout writable \begin_inset Index idx status collapsed \begin_layout Plain Layout writable \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pipe read/write type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout disp_level \begin_inset Index idx status collapsed \begin_layout Plain Layout disp_level \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pipe display level \end_layout \end_inset \end_inset \end_layout \begin_layout Subsubsection The pipe read/write type. \end_layout \begin_layout Standard Tango supports two kinds of read/write pipe which are : \end_layout \begin_layout Itemize Tango::PIPE_READ \begin_inset Index idx status collapsed \begin_layout Plain Layout READ \end_layout \end_inset for read only pipe \end_layout \begin_layout Itemize Tango::PIPE_READ_WRITE \begin_inset Index idx status collapsed \begin_layout Plain Layout READ-WRITE \end_layout \end_inset for pipe which can be read and written \end_layout \begin_layout Subsubsection The pipe display level \begin_inset Index idx status collapsed \begin_layout Plain Layout level \end_layout \end_inset parameter \end_layout \begin_layout Standard This parameter is only an help for graphical application. It is a C++ enumeration starting at 0. The code associated with each pipe display level is defined in the following table (Tango::DispLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout DispLevel \end_layout \end_inset ). \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::OPERATOR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::EXPERT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard This parameter allows a graphical application to support two types of operation : \end_layout \begin_layout Itemize An operator mode for day to day operation \end_layout \begin_layout Itemize An expert mode when tuning is necessary \end_layout \begin_layout Standard According to this parameter, a graphical application knows if the pipe is for the operator mode or for the expert mode. \end_layout \begin_layout Subsection Modifiable pipe parameters \end_layout \begin_layout Standard Each pipe has a configuration set of 2 modifiable parameters. These parameters are modifiable at run-time via a device call or via the property database. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pipe description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout label \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Pipe label \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The \series bold description \begin_inset Index idx status collapsed \begin_layout Plain Layout description \end_layout \end_inset \series default parameter describes the pipe. The \series bold label \begin_inset Index idx status collapsed \begin_layout Plain Layout label \end_layout \end_inset \series default parameter is used by graphical application to display a label when this pipe is used in a graphical application. \end_layout \begin_layout Subsection Setting modifiable pipe parameters \end_layout \begin_layout Standard A default value is given to all modifiable pipe parameters by the Tango core classes. Nevertheless, it is possible to modify these values in source code at pipe creation time or via the database. Values retrieved from the database have a higher priority than values given at pipe creation time. The pipe parameters are therefore initialized from: \end_layout \begin_layout Enumerate The Database \end_layout \begin_layout Enumerate If nothing in database, from the Tango class default \end_layout \begin_layout Enumerate If nothing in database nor in Tango class default, from the library default value \end_layout \begin_layout Standard The default value set by the Tango core library are \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Parameter name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Library default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout description \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout "No description" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout label \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout pipe name \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard It is possible to set modifiable parameters via the database at two levels : \end_layout \begin_layout Enumerate At class level \end_layout \begin_layout Enumerate At device level. Each device pipe have all its modifiable parameters sets to the value defined at class level. If the setting defined at class level is not correct for one device, it is possible to re-define it. \end_layout \begin_layout Standard This is the same principle than the one used for attribute configuration modifiable parameters. \end_layout \begin_layout Subsection Resetting modifiable pipe parameters \end_layout \begin_layout Standard It is possible to reset pipe parameters to their default value at any moment. This could be done via the network call available through the DeviceProxy::set_ pipe_config() method family. It uses the same principle than the one used for resetting modifiable attribute pipe parameters. Refer to their documentation if you want to know details about this feature. \end_layout \begin_layout Section Device class parameter \end_layout \begin_layout Standard A device documentation \begin_inset Index idx status collapsed \begin_layout Plain Layout documentation \end_layout \end_inset field is also defined at Tango device class level. It is defined as Tango device class level because each device belonging to a Tango device class should have the same behaviour and therefore the same documentation. This field is store in the DeviceClass class. It is possible to set this field via a class property. This property name is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset class name->doc_url \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset and is retrieved when instance of the DeviceClass object is created. A default value is defined for this field. \end_layout \begin_layout Section The device black box \end_layout \begin_layout Standard This black box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset is a help tool to ease debugging session for a running device server. The TANGO core software records every device request in this black box. A tango client is able to retrieve the black box contents with a specific CORBA \begin_inset Index idx status collapsed \begin_layout Plain Layout CORBA \end_layout \end_inset operation availabble for every device. Each black box entry is returned as a string with the following information : \end_layout \begin_layout Itemize The date where the request has been executed by the device. The date format is dd/mm/yyyy hh24:mi:ss:SS (The last field is the second hundredth number). \end_layout \begin_layout Itemize The type of CORBA requests. In case of attributes, the name of the requested attribute is returned. In case of operation, the operation type is returned. For \begin_inset Quotes eld \end_inset command_inout \begin_inset Quotes erd \end_inset operation, the command name is returned. \end_layout \begin_layout Itemize The client host name \end_layout \begin_layout Section Automatically added commands \end_layout \begin_layout Standard As already mentionned in this documentation, each Tango device supports at least three commands which are State \begin_inset Index idx status collapsed \begin_layout Plain Layout State \end_layout \end_inset , Status \begin_inset Index idx status collapsed \begin_layout Plain Layout Status \end_layout \end_inset and Init \begin_inset Index idx status collapsed \begin_layout Plain Layout Init \end_layout \end_inset . The following array details command input and output data type \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Input data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout State \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevState \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Status \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Init \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsection The State command \end_layout \begin_layout Standard This command gets the device state (stored in its \emph on device_state \emph default data member) and returns it to the caller. The device state is a variable of the Tango_DevState type (packed into a CORBA Any object when it is returned by a command) \end_layout \begin_layout Subsection The Status command \end_layout \begin_layout Standard This command gets the device status (stored in its \emph on device_status \emph default data member) and returns it to the caller. The device status is a variable of the string type. \end_layout \begin_layout Subsection The Init command \end_layout \begin_layout Standard This commands re-initialise a device keeping the same network connection. After an Init command executed on a device, it is not necessary for client to re-connect to the device. This command first calls the device \emph on delete_device() \emph default method and then execute its \emph on init_device() \emph default method. For C++ device server, all the memory allocated in the \emph on init_device() \emph default method must be freed in the \emph on delete_device() \emph default method. The language device desctructor automatically calls the \emph on delete_device() \emph default method. \end_layout \begin_layout Section DServer \begin_inset Index idx status collapsed \begin_layout Plain Layout DServer \end_layout \end_inset class device commands \end_layout \begin_layout Standard As already explained in \begin_inset CommandInset ref LatexCommand ref reference "DServer_class" \end_inset , each device server process has its own Tango device. This device supports the three commands previously described plus 32 commands which are DevRestart \begin_inset Index idx status collapsed \begin_layout Plain Layout DevRestart \end_layout \end_inset , RestartServer \begin_inset Index idx status collapsed \begin_layout Plain Layout RestartServer \end_layout \end_inset , QueryClass \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryClass \end_layout \end_inset , QueryDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryDevice \end_layout \end_inset , Kill \begin_inset Index idx status collapsed \begin_layout Plain Layout Kill \end_layout \end_inset , QueryWizardClassProperty \begin_inset Index idx status collapsed \begin_layout Plain Layout QueyWizardClassProperty \end_layout \end_inset , QueryWizardDevProperty \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryWizardDevProperty \end_layout \end_inset , QuerySubDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout QuerySubDevice \end_layout \end_inset , the polling related commands which are StartPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StartPolling \end_layout \end_inset , StopPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StopPolling \end_layout \end_inset , AddObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout AddObjPolling \end_layout \end_inset , RemObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout RemObjPolling \end_layout \end_inset , UpdObjPollingPeriod \begin_inset Index idx status collapsed \begin_layout Plain Layout UpdObjPollingPeriod \end_layout \end_inset , PolledDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout PolledDevice \end_layout \end_inset and DevPollStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevPollStatus \end_layout \end_inset , the device locking related commands which are LockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout LockDevice \end_layout \end_inset , UnLockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout UnLockDevice \end_layout \end_inset , ReLockDevices \begin_inset Index idx status collapsed \begin_layout Plain Layout ReLockDevices \end_layout \end_inset and DevLockStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevLockStatus \end_layout \end_inset , the event related commands called EventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout EventSubscriptionChange \end_layout \end_inset , ZmqEventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout ZmqEventSubscriptionChange \end_layout \end_inset and EventConfirmSubscription \begin_inset Index idx status collapsed \begin_layout Plain Layout EventConfirmSubscription \end_layout \end_inset and finally the logging related commands which are AddLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout AddLoggingTarget \end_layout \end_inset , RemoveLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout RemoveLoggingTarget \end_layout \end_inset , GetLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingTarget \end_layout \end_inset , GetLoggingLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingLevel \end_layout \end_inset , SetLoggingLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout SetLoggingLevel \end_layout \end_inset , StopLogging \begin_inset Index idx status collapsed \begin_layout Plain Layout StopLogging \end_layout \end_inset and StartLogging \begin_inset Index idx status collapsed \begin_layout Plain Layout StartLogging \end_layout \end_inset . The following table give all commands input and output data types \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Input data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Output data type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout State \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevState \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Status \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Init \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevRestart \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RestartServer \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout QueryClass \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout QueryDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Kill \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout QueryWizardClassProperty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout QueryWizardDevProperty \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout QuerySubDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout StartPolling \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout StopPolling \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AddObjPolling \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RemObjPolling \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout UpdObjPollingPeriod \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout PolledDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevPollStatus \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LockDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout UnLockDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ReLockDevices \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DevLockStatus \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EventSubscribeChange \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ZmqEventSubscriptionChange \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EventConfirmSubscription \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AddLoggingTarget \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout RemoveLoggingTarget \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GetLoggingTarget \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout GetLoggingLevel \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout SetLoggingLevel \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout StopLogging \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout StartLogging \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout void \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The device description field is set to \begin_inset Quotes eld \end_inset A device server device \begin_inset Quotes erd \end_inset . Device server started with the -file command line option also supports a command called QueryEventChannelIOR \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryEventChannelIOR \end_layout \end_inset . This command is used interanally by the Tango kernel classes when the event system is used with device server using database on file. \end_layout \begin_layout Subsection The State command \end_layout \begin_layout Standard This device state is always set to ON \end_layout \begin_layout Subsection The Status command \end_layout \begin_layout Standard This device status is always set to \begin_inset Quotes eld \end_inset The device is ON \begin_inset Quotes erd \end_inset followed by a new line character and a string describing polling thread status. This string is either \begin_inset Quotes eld \end_inset The polling is OFF \begin_inset Quotes erd \end_inset or \begin_inset Quotes eld \end_inset The polling is ON \begin_inset Quotes erd \end_inset according to polling state. \end_layout \begin_layout Subsection The DevRestart command \end_layout \begin_layout Standard The DevRestart command restart a device. The name of the device to be re-started is the command input parameter. The command destroys the device by calling its destructor and re-create it from its constructor. \end_layout \begin_layout Subsection The RestartServer command \end_layout \begin_layout Standard The DevRestartServer command restarts all the device pattern(s) embedded in the device server process. Therefore, all the devices implemented in the server process are destroyed and re-built \begin_inset Foot status open \begin_layout Plain Layout Their black-box is also destroyed and re-built \end_layout \end_inset . The network connection between client(s) and device(s) implemented in the device server process is destroyed and re-built. \end_layout \begin_layout Standard Executing this command allows a complete restart of the device server without stopping the process. \end_layout \begin_layout Subsection The QueryClass \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryClass \end_layout \end_inset command \end_layout \begin_layout Standard This command returns to the client the list of Tango device class(es) embedded in the device server. It returns only class(es) implemented by the device server programmer. The DServer device class name (implemented by the TANGO core software) is not returned by this command. \end_layout \begin_layout Subsection The QueryDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryDevice \end_layout \end_inset command \end_layout \begin_layout Standard This command returns to the client the list of device name for all the device(s) implemented in the device server process. Each device name is returned using the following syntax : \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset :: \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Standard The name of the DServer class device is not returned by this command. \end_layout \begin_layout Subsection The Kill \begin_inset Index idx status collapsed \begin_layout Plain Layout Kill \end_layout \end_inset command \end_layout \begin_layout Standard This command stops the device server process. In order that the client receives a last answer from the server, this command starts a thread which will after a short delay, kills the device server process. \end_layout \begin_layout Subsection The QueryWizardClassProperty \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryWizardClassProperty \end_layout \end_inset command \end_layout \begin_layout Standard This command returns the list of property(ies) defined for a class stored in the device server process property wizard. For each property, its name, a description and a default value is returned. \end_layout \begin_layout Subsection The QueryWizardDevProperty \begin_inset Index idx status collapsed \begin_layout Plain Layout QueryWizardDevProperty \end_layout \end_inset command \end_layout \begin_layout Standard This command returns the list of property(ies) defined for a device stored in the device server process property wizard. For each property, its name, a description and a default value is returned. \end_layout \begin_layout Subsection The QuerySubDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout QuerySubDevice \end_layout \end_inset command \end_layout \begin_layout Standard This command returns the list of sub-device(s) imported by each device within the server. A sub-device is a device used ( to execute command(s) and/or to read/write attribute(s) ) by one of the device server process devices. There is one element in the returned strings array for each sub-device. The syntax of each string is the device name, a space and the sub-device name. In case of device server process starting threads using a sub-device, it is not possible to link this sub-device to any process devices. In such a case, the string contains only the sub-device name \end_layout \begin_layout Subsection The StartPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StartPolling \end_layout \end_inset command \end_layout \begin_layout Standard This command starts the polling thread \end_layout \begin_layout Subsection The StopPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout StopPolling \end_layout \end_inset command \end_layout \begin_layout Standard This command stops the polling thread \end_layout \begin_layout Subsection The AddObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout AddObjPolling \end_layout \end_inset command \end_layout \begin_layout Standard This command adds a new object in the list of object(s) to be polled. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and three strings. The input parameters are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object type ( \begin_inset Quotes eld \end_inset command \begin_inset Quotes eld \end_inset or \begin_inset Quotes eld \end_inset attribute \begin_inset Quotes eld \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout polling period in mS \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command does not start polling if it is stopped. This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The RemObjPolling \begin_inset Index idx status collapsed \begin_layout Plain Layout RemObjPolling \end_layout \end_inset command \end_layout \begin_layout Standard This command removes an object of the list of polled objects. The command input data type is a Tango::DevVarStringArray with three strings. These strings meaning are : \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout String \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout string[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout string[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object type ( \begin_inset Quotes eld \end_inset command \begin_inset Quotes eld \end_inset or \begin_inset Quotes eld \end_inset attribute \begin_inset Quotes eld \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout string[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object name \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The UpdObjPollingPeriod \begin_inset Index idx status collapsed \begin_layout Plain Layout UpdObjPollingPeriod \end_layout \end_inset command \end_layout \begin_layout Standard This command changes the polling period for a specified object. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and three strings. The input parameters are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object type ( \begin_inset Quotes eld \end_inset command \begin_inset Quotes eld \end_inset or \begin_inset Quotes eld \end_inset attribute \begin_inset Quotes eld \end_inset ) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Object name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout new polling period in mS \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The object type string is case independent. The object name string (command name or attribute name) is case dependant. This command does not start polling if it is stopped. This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The PolledDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout PolledDevice \end_layout \end_inset command \end_layout \begin_layout Standard This command returns the name of device which are polled. Each string in the Tango::DevVarStringArray returned by the command is a device name which has at least one command or attribute polled. The list is alphabetically sorted. \end_layout \begin_layout Subsection The DevPollStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevPollStatus \end_layout \end_inset command \end_layout \begin_layout Standard This command returns a polling status for a specific device. The input parameter is a device name. Each string in the Tango::DevVarStringArray returned by the command is the polling status for each polled device objects (command or attribute). For each polled objects, the polling status is : \end_layout \begin_layout Itemize The object name \end_layout \begin_layout Itemize The object polling period (in mS) \end_layout \begin_layout Itemize The object polling ring buffer depth \end_layout \begin_layout Itemize The time needed (in mS) for the last command execution or attribute reading \end_layout \begin_layout Itemize The time since data in the ring buffer has not been updated. This allows a check of the polling thread \end_layout \begin_layout Itemize The delta time between the last records in the ring buffer. This allows checking that the polling period is respected by the polling thread. \end_layout \begin_layout Itemize The exception parameters in case of the last command execution or the last attribute reading failed. \end_layout \begin_layout Standard A new line character is inserted between each piece of information. \end_layout \begin_layout Subsection The LockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout LockDevice \end_layout \end_inset command \end_layout \begin_layout Standard This command locks a device for the calling process. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and one string. The input parameters are: \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Lock validity \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsection The UnLockDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout UnLockDevice \end_layout \end_inset command \end_layout \begin_layout Standard This command unlocks a device. The command input parameters are embedded within a Tango::DevVarLongStringArray data type with one long data and one string. The input parameters are: \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Force flag \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The force flag parameter allows a client to unlock a device already locked by another process (for admin usage only) \end_layout \begin_layout Subsection The ReLockDevices \begin_inset Index idx status collapsed \begin_layout Plain Layout ReLockDevices \end_layout \end_inset command \end_layout \begin_layout Standard This command re-lock devices. The input argument is the list of devices to be re-locked. It's an error to re-lock a device which is not already locked. \end_layout \begin_layout Subsection The DevLockStatus \begin_inset Index idx status collapsed \begin_layout Plain Layout DevLockStatus \end_layout \end_inset command \end_layout \begin_layout Standard This command returns a device locking status to the caller. Its input parameter is the device name. The output parameters are embedded within a Tango::DevVarLongStringArray data type with three strings and six long. These data are \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Locking string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CPP client host IP address or "Not defined" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Java VM main class for Java client or "Not defined" \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Lock flag (1 if locked, 0 othterwise) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CPP client host IP address or 0 for Java locker \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Java locker UUID part 1or 0 for CPP locker \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[3] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Java locker UUID part 2 or 0 for CPP locker \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[4] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Java locker UUID part 3 or 0 for CPP locker \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[5] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Java locker UUID part 4 or 0 for CPP locker \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsection The EventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout EventSubscriptionChange \end_layout \end_inset command (C++ server only) \end_layout \begin_layout Standard This command is used as a piece of the "heartbeat" system between an event client and the device server generating the event. There is no reason to generate events if there is no client which has subscribe d to it. It is used by the \emph on DeviceProxy::subscribe_event() \emph default method and one of the event thread on the client side to inform the server to keep on generating events for the attribute in question. It reloads the subscription timer with the current time. Events are not generated when there are no clients subscribed within the last 10 minutes. The input parameters are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout action ("subscribe" or "unsubsribe") \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[3] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout event name ("change", "periodic", "archive","attr_conf") \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The command output data is the simply the Tango release used by the device server process. This is necessary for compatibility reason. \end_layout \begin_layout Subsection The ZmqEventSubscriptionChange \begin_inset Index idx status collapsed \begin_layout Plain Layout ZmqEventSubscriptionChange \end_layout \end_inset command \end_layout \begin_layout Standard This command is used as a piece of the "heartbeat" system between an event client and the device server generating the event when client and/or device server uses Tango release 8 or above. There is no reason to generate events if there is no client which has subscribe d to it. It is used by the \emph on DeviceProxy::subscribe_event() \emph default method and one of the event thread on the client side to inform the server to keep on generating events for the attribute in question. It reloads the subscription timer with the current time. Events are not generated when there are no clients subscribed within the last 10 minutes. The input parameters are the same than the one used for the EventSubscriptionCh ange command. They are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command in parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout action ("subscribe" or "unsubsribe") \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[3] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout event name ("change", "periodic", "archive","attr_conf") \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The command output parameters aer all the necessary data to build one event connection between a client and the device server process generating the events. This means: \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command out parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Heartbeat ZMQ socket connect end point \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout svalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Event ZMQ socket connect end point \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[0] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango lib release used by device server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device IDL release \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Subscriber HWM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[3] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Rate (Multicasting related) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout lvalue[4] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout IVL (Multicasting related) \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsection The EventConfirmSubscription \begin_inset Index idx status collapsed \begin_layout Plain Layout EventConfirmSubscription \end_layout \end_inset command \end_layout \begin_layout Standard This command is used by client to regularly notify to device server process their interest in receiving events. If this command is not received, after a delay of 600 sec (10 mins), event(s) will not be sent any more. The input parameters for the EventConfirmSubscription command must be a multiple of 3. They are 3 parameters for each event confirmed by this command. Per event, these parameters are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Command in parameter \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Parameter meaning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[x] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[x + 1] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout argin[x + 2] \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Event name \end_layout \end_inset \end_inset \end_layout \begin_layout Subsection The AddLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout AddLoggingTarget \end_layout \end_inset command \end_layout \begin_layout Standard This command adds one (or more) logging target(s) to the specified device(s). The command input parameter is an array of string logically composed of {device_name, target_type::target_name} groups where the elements have the following semantic: \end_layout \begin_layout Itemize device_name is the name of the device which logging behavior is to be controlled. The wildcard "*" is supported to apply the modification to all devices encapsulated within the device server (e.g. to ask all devices to log to the same device target). \end_layout \begin_layout Itemize target_type::target_name: target_type is one of the supported target types and target_name, the name of the target. Supported target types are: \emph on console \emph default , \emph on file \emph default and \emph on device \emph default . For a device target, target_name must contain the name of a log consumer device (as defined in \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango-log-consumer" \end_inset ). For a file target, target_name is the full path to the file to log to. If omitted the device's name is used to build the file name (domain_family_memb er.log). Finally, target_name is ignored in the case of a console target and can be omitted. \end_layout \begin_layout Standard This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The RemoveLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout RemoveLoggingTarget \end_layout \end_inset command \end_layout \begin_layout Standard Remove one (or more) logging target(s) from the specified device(s).The command input parameter is an array of string logically composed of {device_name, target_type::target_name} groups where the elements have the following semantic: \end_layout \begin_layout Itemize device_name: the name of the device which logging behavior is to be controlled. The wildcard "*" is supported to apply the modification to all devices encapsulated within the device server (e.g. to ask all devices to stop logging to a given device target). \end_layout \begin_layout Itemize target_type::target_name: target_type is one of the supported target types and target_name, the name of the target. Supported target types are: \emph on console \emph default , \emph on file \emph default and \emph on device \emph default . For a device target, target_name must contain the name of a log consumer device (as defined in \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango-log-consumer" \end_inset ). For a file target, target_name is the full path to the file to log to. If omitted the device's name is used to build the file name (domain_family_memb er.log). Finally, target_name is ignored in the case of a console target and can be omitted. \end_layout \begin_layout Standard The wildcard "*" is supported for target_name. For instance, RemoveLoggingTarget (["*", "device::*"]) removes all the device targets from all the devices running in the device server. This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The GetLoggingTarget \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingTarget \end_layout \end_inset command \end_layout \begin_layout Standard Returns the current target list of the specified device. The command parameter device_name is the name of the device which logging target list is requested. The list is returned as a DevVarStringArray containing target_type::target_name elements. \end_layout \begin_layout Subsection The GetLoggingLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout GetLoggingLevel \end_layout \end_inset command \end_layout \begin_layout Standard Returns the logging level of the specified devices. The command input parameter device_list contains the names of the devices which logging target list is requested. The wildcard "*" is supported to get the logging level of all the devices running within the server. The string part of the result contains the name of the devices and its long part contains the levels. Obviously, result.lvalue[i] is the current logging level of the device named result.svalue[i]. \end_layout \begin_layout Subsection The SetLoggingLevel \begin_inset Index idx status collapsed \begin_layout Plain Layout SetLoggingLevel \end_layout \end_inset command \end_layout \begin_layout Standard Changes the logging level of the specified devices. The string part of the command input parameter contains the device names while its long part contains the logging levels. The set of possible values for levels is: 0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG. \end_layout \begin_layout Standard The wildcard "*" is supported to assign all devices the same logging level. For instance, SetLoggingLevel (["*"] [3]) set the logging level of all the devices running within the server to WARNING. This command is not allowed in case the device is locked and the command requester is not the lock owner. \end_layout \begin_layout Subsection The StopLogging \begin_inset Index idx status collapsed \begin_layout Plain Layout StopLogging \end_layout \end_inset command \end_layout \begin_layout Standard For all the devices running within the server, StopLogging saves their current logging level and set their logging level to OFF. \end_layout \begin_layout Subsection The StartLogging \begin_inset Index idx status collapsed \begin_layout Plain Layout StartLogging \end_layout \end_inset command \end_layout \begin_layout Standard For each device running within the server, StartLogging restores their logging level to the value stored during a previous StopLogging call. \end_layout \begin_layout Section DServer class device properties \end_layout \begin_layout Standard This device has two properties related to polling threads pool management plus another one for the choice of polling algorithm. These properties are described in the following table \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Property name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout property rule \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout polling_threads_pool_size \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Max number of thread in the polling pool \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout polling_threads_pool_conf \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Polling threads pool configuration \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout polling_before_9 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Choice of the polling algorithm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout false \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The rule of the polling_threads_pool_size \begin_inset Index idx status collapsed \begin_layout Plain Layout polling-threads-pool-size \end_layout \end_inset is to define the maximun number of thread created for the polling threads pool size. The rule of the polling_threads_pool_conf \begin_inset Index idx status collapsed \begin_layout Plain Layout polling-threads-pool-conf \end_layout \end_inset is to define which thread in the pool is in charge of all the polled object(s) of which device. This property is an array of strings with one string per used thread in the pool. The content of the string is simply a device name list with device name splitted by a comma. Example of polling_threads_pool_conf property for 3 threads used: \end_layout \begin_layout LyX-Code dserver///polling_threads_pool_conf-> the/dev/01 \end_layout \begin_layout LyX-Code the/dev/02,the/dev/06 \end_layout \begin_layout LyX-Code the/dev/03 \end_layout \begin_layout Standard Thread number 2 is in charge of 2 devices. Note that there is an entry in this list only for the used threads in the pool. \end_layout \begin_layout Standard The rule of the polling_before_9 \begin_inset Index idx status open \begin_layout Plain Layout polling_before_9 \end_layout \end_inset property is to select the polling algorithm which was used in Tango device server process before Tango release 9. \end_layout \begin_layout Section Tango log consumer \begin_inset Index idx status collapsed \begin_layout Plain Layout consumer \end_layout \end_inset \begin_inset CommandInset label LatexCommand label name "sec:Tango-log-consumer" \end_inset \end_layout \begin_layout Subsection The available Log Consumer \end_layout \begin_layout Standard One implementation of a log consumer associated to a graphical user interface is available within Tango. It is a standalone java application called \series bold LogViewer \series default based on the publicly available chainsaw application from the log4j package. It supports two way of running which are: \end_layout \begin_layout Itemize The static mode: In this mode, LogViewer is started with a parameter which is the name of the log consumer device implemented by the application. All messages sent by devices with a logging target type set to \emph on device \emph default and with a logging target name set to the same device name than the device name passed as application parameter will be displayed (if the logging level allows it). \end_layout \begin_layout Itemize The dynamic mode: In this mode, the name of the log consumer device implemented by the application is build at application startup and is dynamic. The user with the help of the graphical interface chooses device(s) for which he want to see log messages. \end_layout \begin_layout Subsection The Log Consumer interface \end_layout \begin_layout Standard A Tango Log Consumer device is nothing but a tango device supporting the following tango command : \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset void log (Tango::DevVarStringArray details) \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset where details is an array of string carrying the log details. Its structure is: \end_layout \begin_layout Itemize details[0] : the timestamp in millisecond since epoch (01.01.1970) \end_layout \begin_layout Itemize details[1] : the log level \end_layout \begin_layout Itemize details[2] : the log source (i.e. device name) \end_layout \begin_layout Itemize details[3] : the log message \end_layout \begin_layout Itemize details[4] : the log NDC (contextual info) - Not used but reserved \end_layout \begin_layout Itemize details[5] : the thread identifier (i.e. the thread from which the log request comes from) \end_layout \begin_layout Standard These log details can easily be extended. Any tango device supporting this command can act as a device target for other devices. \end_layout \begin_layout Section Control system specific \end_layout \begin_layout Standard It is possible to define a few control system parameters. By control system, we mean for each set of computers having the same database device server (the same TANGO_HOST environment variable) \end_layout \begin_layout Subsection The device class documentation default value \end_layout \begin_layout Standard Each control system may have it's own default device class documentation value. This is defined via a class property. The property name is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset Default->doc_url \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset It's retrieved if the device class itself does not define any doc_url property. If the Default->doc_url property is also not defined, a hard-coded default value is provided. \end_layout \begin_layout Subsection The services definition \end_layout \begin_layout Standard The property used to defined control system services is named \series bold Services \begin_inset Index idx status collapsed \begin_layout Plain Layout Services \end_layout \end_inset \series default and belongs to the free object \series bold CtrlSystem \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout CtrlSystem \end_layout \end_inset . This property is an array of strings. Each string defines a service available within the control system. The syntax of each service definition is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset Service name/Instance name:service device name \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset \end_layout \begin_layout Subsection Tuning the event system buffers (HWM) \begin_inset Index idx status collapsed \begin_layout Plain Layout HWM \end_layout \end_inset \end_layout \begin_layout Standard Starting with Tango release 8, ZMQ \begin_inset Index idx status collapsed \begin_layout Plain Layout ZMQ \end_layout \end_inset is used for the event based communication between clients and device server processes. ZMQ implementation provides asynchronous communication in the sense that the data to be transmitted is first stored in a buffer and then really sent on the network by dedicated threads. The size of this buffers (on client and device server side) is called High Water Mark (HWM) and is tunable. This is tunable at several level. \end_layout \begin_layout Enumerate The library set a default value of \series bold 1000 \series default for both buffers (client and device server side) \end_layout \begin_layout Enumerate Control system properties used to tune these size are named \series bold DSEventBufferHwm \begin_inset Index idx status collapsed \begin_layout Plain Layout DsEventBufferHwm \end_layout \end_inset \series default (device server side) and \series bold EventBufferHwm \begin_inset Index idx status collapsed \begin_layout Plain Layout \series bold EventBufferHwm \end_layout \end_inset \series default (client side). They both belongs to the free object \series bold CtrlSystem \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout CtrlSystem \end_layout \end_inset . Each property is the max number of events storable in these buffer. \end_layout \begin_layout Enumerate At client or device server level using the library calls \emph on Util::set_ds_event_buffer_hwm() \emph default documented in \begin_inset CommandInset citation LatexCommand cite key "Tango-dsclasses-doc" \end_inset or \emph on ApiUtil::set_event_buffer_hwm() \emph default documented in \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango::ApiUtil" \end_inset \end_layout \begin_layout Enumerate Using environment variables TANGO_DS_EVENT_BUFFER_HWM \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-DS-EVENT-BUFFER-HWM \end_layout \end_inset or TANGO_EVENT_BUFFER_HWM \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-EVENT-BUFFER-HWM \end_layout \end_inset \end_layout \begin_layout Subsection Allowing NaN when writing attributes (floating point) \end_layout \begin_layout Standard A property named \series bold WAttrNaNAllowed \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium WAttrNaNAllowed \end_layout \end_inset \series default belonging to the free object \series bold CtrlSystem \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium CtrlSystem \end_layout \end_inset \series default allows a Tango control system administrator to allow or disallow NaN numbers when writing attributes of the DevFloat or DevDouble data type. This is a boolean property and by default, it's value is taken as false (Meaning NaN values are rejected). \end_layout \begin_layout Subsection Tuning multicasting event propagation \end_layout \begin_layout Standard Starting with Tango 8.1, it is possible to transfer event(s) between devices and clients using a multicast protocol. The properties \series bold MulticastEvent \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout MulticastEvent \end_layout \end_inset , \series bold MulticastRate \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout MulticastRate \end_layout \end_inset , \series bold MulticastIvl \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium MulticastIvl \end_layout \end_inset \series default and \series bold MulticastHops \begin_inset Index idx status collapsed \begin_layout Plain Layout \series medium MulticastHops \end_layout \end_inset \series default also belonging to the free object \series bold CtrlSystem \series default allow the user to configure which events has to be sent using multicasting and with which parameters. See chapter "Advanced features/Using multicast protocol to transfer events" to get details about these properties. \end_layout \begin_layout Subsection Summary of CtrlSystem free object properties \end_layout \begin_layout Standard The following table summarizes properties defined at control system level and belonging to the free object CtrlSystem \begin_inset Index idx status collapsed \begin_layout Plain Layout CtrlSystem \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Property name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout property rule \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout default value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Services \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout List of defined services \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No default \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DsEventBufferHwm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DS event buffer high water mark \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1000 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout EventBufferHwm \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Client event buffer high water mark \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1000 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout WAttrNaNAllowed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Allow NaN when writing attr. \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout false \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MulticastEvent \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout List of multicasting events \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No default \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MulticastRate \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Rate for multicast event transport \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 80 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MulticastIvl \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Time to keep data for re-transmission \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout MulticastHops \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Max number of eleemnts to cross \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Section C++ specific \end_layout \begin_layout Subsection The Tango master include file (tango.h \begin_inset Index idx status collapsed \begin_layout Plain Layout tango.h \end_layout \end_inset ) \end_layout \begin_layout Standard Tango has a master include file called \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset tango.h \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset This master include file includes the following files : \end_layout \begin_layout Itemize Tango configuration include file : \series bold tango_config.h \end_layout \begin_layout Itemize CORBA include file : \series bold idl/tango.h \end_layout \begin_layout Itemize Some network include files for WIN32 : \series bold winsock2.h \series default and \series bold mswsock.h \end_layout \begin_layout Itemize C++ streams include file : \end_layout \begin_deeper \begin_layout Itemize \series bold iostream \series default , \series bold sstream \series default and \series bold fstream \series default \end_layout \end_deeper \begin_layout Itemize Some standard C++ library include files : \series bold memory, string \series default and \series bold vector \end_layout \begin_layout Itemize A long list of other Tango include files \end_layout \begin_layout Subsection Tango specific pre-processor define \end_layout \begin_layout Standard The tango.h previously described also defined some pre-processor macros allowing Tango release to be checked at compile time. These macros are: \end_layout \begin_layout Itemize TANGO_VERSION_MAJOR \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-VERSION-MAJOR \end_layout \end_inset \end_layout \begin_layout Itemize TANGO_VERSION_MINOR \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-VERSION-MINOR \end_layout \end_inset \end_layout \begin_layout Itemize TANGO_VERSION_PATCH \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-VERSION-PATCH \end_layout \end_inset \end_layout \begin_layout Standard For instance, with Tango release 8.1.2, TANGO_VERSION_MAJOR will be set to 8 while TANGO_VERSION_MINOR will be 1 and TANGO_VERSION_PATCH will be 2. \end_layout \begin_layout Subsection Tango specific types \end_layout \begin_layout Subsubsection* Operating system free type \end_layout \begin_layout Standard Some data type used in the TANGO core software have been defined. They are described in the following table. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Type name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout C++ name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TangoSys_MemStream \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout stringstream \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TangoSys_OMemStream \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ostringstream \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TangoSys_Pid \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout int \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TangoSys_Cout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ostream \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard These types are defined in the tango_config.h file \end_layout \begin_layout Subsubsection Template command model related type \end_layout \begin_layout Standard As explained in \begin_inset CommandInset ref LatexCommand ref reference "Command fact" \end_inset , command created with the template command model uses static casting. Many type definition have been written for these casting. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Class name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Command allowed method (if any) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Command execute method \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TemplCommand \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommand \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::StateMethodPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::CmdMethPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TemplCommandIn \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandIn \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::StateMethodPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::CmdMethPtr_xxx \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TemplCommandOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandOut \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::StateMethodPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::xxx_CmdMethPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TemplCommandInOut \begin_inset Index idx status collapsed \begin_layout Plain Layout TemplCommandInOut \end_layout \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::StateMethodPtr \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::xxx_CmdMethPtr_yyy \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The \series bold Tango::StateMethPtr \series default is a pointer to a method of the DeviceImpl class which returns a boolean and has one parameter which is a reference to a const CORBA::Any obect. \end_layout \begin_layout Standard The \series bold Tango::CmdMethPtr \series default is a pointer to a method of the DeviceImpl class which returns nothing and needs nothing as parameter. \end_layout \begin_layout Standard The \series bold Tango::CmdMethPtr_xxx \series default is a pointer to a method of the DeviceImpl class which returns nothing and has one parameter. xxx must be set according to the method parameter type as described in the next table \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Tango type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout short cut (xxx) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevBoolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Bo \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Sh \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Lg \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevFloat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Fl \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevDouble \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Db \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevUshort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout US \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout UL \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Str \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarCharArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ChA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ShA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LgA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarFloatArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout FlA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DbA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarUShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout USA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarULongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ULA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout StrA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout LSA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DSA \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevState \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Sta \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard For instance, a pointer to a method which takes a Tango::DevVarStringArray as input parameter must be statically casted to a Tango::CmdMethPtr_StrA, a pointer to a method which takes a Tango::DevLong data as input parameter must be statically casted to a Tango::CmdMethPtr_Lg. \end_layout \begin_layout Standard The \series bold Tango::xxx_CmdMethPtr \series default is a pointer to a method of the DeviceImpl class which returns data of one of the Tango type and has no input parameter. xxx must be set according to the method return data type following the same rules than those described in the previous table. For instance, a pointer to a method which returns a Tango::DevDouble data must be statically casted to a Tango::Db_CmdMethPtr. \end_layout \begin_layout Standard The \series bold Tango::xxx_CmdMethPtr_yyy \series default is a pointer to a method of the DeviceImpl class which returns data of one of the Tango type and has one input parameter of one of the Tango data type. xxx and yyy must be set according to the method return data type and parameter type following the same rules than those described in the previous table. For instance, a pointer to a method which returns a Tango::DevDouble data and which takes a Tango::DevVarLongStringArray must be statically casted to a Tango::Db_CmdMethPtr_LSA. \end_layout \begin_layout Standard All those type are defined in the tango_const.h file. \end_layout \begin_layout Subsection Tango device state code \end_layout \begin_layout Standard The Tango::DevState type is a C++ enumeration starting at 0. The code associated with each state \begin_inset Index idx status collapsed \begin_layout Plain Layout state \end_layout \end_inset is defined in the following table. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout State name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::ON \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::OFF \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::CLOSE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::OPEN \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::INSERT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::EXTRACT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::MOVING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 6 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::STANDBY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 7 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::FAULT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 8 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::INIT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 9 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::RUNNING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::ALARM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 11 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DISABLE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::UNKNOWN \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 13 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard A strings array called \series bold Tango::DevStateName \begin_inset Index idx status collapsed \begin_layout Plain Layout DevStateName \end_layout \end_inset \series default can be used to get the device state as a string. Use the Tango device state code as index into the array to get the correct string. \end_layout \begin_layout Subsection Tango data type \end_layout \begin_layout Standard A \begin_inset Quotes eld \end_inset define \begin_inset Quotes erd \end_inset has been created for each Tango data type. This is summarized in the following table \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Type name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Type code \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Value \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevBoolean \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_BOOLEAN \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_SHORT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_LONG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 3 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevFloat \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_FLOAT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 4 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevDouble \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_DOUBLE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 5 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevUShort \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_USHORT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 6 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_ULONG \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 7 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_STRING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 8 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarCharArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_CHARARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 9 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_SHORTARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 10 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_LONGARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 11 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarFloatArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_FLOATARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 12 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_DOUBLEARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 13 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarUShortArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_USHORTARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 14 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarULongArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_ULONGARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 15 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_STRINGARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 16 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLongStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_LONGSTRINGARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 17 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarDoubleStringArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_DOUBLESTRINGARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 18 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevState \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_STATE \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 19 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::ConstDevString \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::CONST_DEV_STRING \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 20 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarBooleanArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_BOOLEANARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 21 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevUChar \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_UCHAR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 22 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevLong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_LONG64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 23 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevULong64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_ULONG64 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 24 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarLong64Array \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_LONG64ARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 25 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarULong64Array \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_ULONG64ARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 26 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevInt \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_INT \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 27 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevEncoded \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_ENCODED \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 28 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevEnum \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_ENUM \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 29 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevPipeBlob \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEV_PIPE_BLOB \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 30 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DevVarStateArray \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Tango::DEVVAR_STATEARRAY \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 31 \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard For command which do not take input parameter, the type code Tango::DEV_VOID (value = 0) has been defined. \end_layout \begin_layout Standard A strings array called \series bold Tango::CmdArgTypeName \begin_inset Index idx status collapsed \begin_layout Plain Layout CmdArgTypeName \end_layout \end_inset \series default can be used to get the data type as a string. Use the Tango data type code as index into the array to get the correct string. \end_layout \begin_layout Subsection Tango command display level \end_layout \begin_layout Standard Like attribute, Tango command has a display level. The Tango::DispLevel type is a C++ enumeration starting at 0. The code associated with each command display level is already described in page \begin_inset CommandInset ref LatexCommand pageref reference "display level" \end_inset \end_layout \begin_layout Standard As for attribute, this parameter allows a graphical application to support two types of operation : \end_layout \begin_layout Itemize An operator mode for day to day operation \end_layout \begin_layout Itemize An expert mode when tuning is necessary \end_layout \begin_layout Standard According to this parameter, a graphical application knows if the command is for the operator mode or for the expert mode. \end_layout \begin_layout Section Device server process option and environment variables \end_layout \begin_layout Subsection Classical device server \end_layout \begin_layout Standard The synopsis of a device server process is \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset ds_name instance_name [OPTIONS] \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset The supported options are : \end_layout \begin_layout Itemize \series bold -h, -? -help \series default \begin_inset Newline newline \end_inset Print the device server synopsis and a list of instance name defined in the database for this device server. An instance name in not mandatory in the command line to use this option \end_layout \begin_layout Itemize \series bold -v[trace level] \series default \begin_inset Newline newline \end_inset Set the verbose level. If no trace level is given, a default value of 4 is used \end_layout \begin_layout Itemize \series bold -file= \series default \begin_inset Newline newline \end_inset Start a device server using an ASCII file instead of the Tango database. \end_layout \begin_layout Itemize \series bold -nodb \series default \begin_inset Newline newline \end_inset Start a device server without using the database. \end_layout \begin_layout Itemize \series bold -dlist \series default \begin_inset Newline newline \end_inset Give the device name list. This option is supported only with the -nodb option. \end_layout \begin_layout Itemize \series bold ORB options \series default (started with -ORBxxx) \begin_inset Newline newline \end_inset Options directly passed to the underlying ORB. Should be rarely used except the -ORBendPoint option for device server not using the database \end_layout \begin_layout Subsection Device server process as Windows service \end_layout \begin_layout Standard When used as a Windows service \begin_inset Index idx status collapsed \begin_layout Plain Layout service \end_layout \end_inset , a Tango device server supports several new options. These options are : \end_layout \begin_layout Itemize \series bold -i \series default \begin_inset Newline newline \end_inset Install the service \end_layout \begin_layout Itemize \series bold -s \series default \begin_inset Newline newline \end_inset Install the service and choose the automatic startup mode \end_layout \begin_layout Itemize \series bold -u \series default \begin_inset Newline newline \end_inset Un-install the service \end_layout \begin_layout Itemize \series bold -dbg \series default \begin_inset Newline newline \end_inset Run in console mode to debug service. The service must have been installed prior to use it. \end_layout \begin_layout Standard Note that these options must be used after the device server instance name. \end_layout \begin_layout Subsection Environment variables \end_layout \begin_layout Standard A few environment variables can be used to tune a Tango control system. TANGO_HOST \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-HOST \end_layout \end_inset is the most important one but on top it, some Tango features like Tango logging service or controlled access (if used) can be tuned using environment variable. If these environment variables are not defined, the software searches in the file \series bold $HOME/.tangorc \series default for its value. If the file is not defined or if the environment variable is also not defined in this file, the software searches in the file \series bold /etc/tangorc \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout tangorc \end_layout \end_inset for its value. For Windows, the file is \series bold $TANGO_ROOT/tangorc \series default TANGO_ROOT \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-ROOT \end_layout \end_inset being the mandatory environment variable of the Windows binary distribution. \end_layout \begin_layout Subsubsection TANGO_HOST \end_layout \begin_layout Standard This environment variable is the anchor of the system. It specifies where the Tango database server is running. Most of the time, its syntax is \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset TANGO_HOST=: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset host is the name of the computer where the database server is running and port is th eport number on which it is litenning. If you want to have a Tango control system which has several database servers (but only one database) in order to survive a database server crashes, use the following syntax \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset TANGO_HOST=:,:,: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset Obviously, host_1 is the name of the computer where the first database server is running, port_1 is the port number on which this server is listenning. host_2 is the name of the computer where the second database server is running and port_2 is its port number. All access to database will automatically switch from one server to another one in the list if the one which was used has died. \end_layout \begin_layout Subsubsection Tango Logging Service (TANGO_LOG_PATH) \end_layout \begin_layout Standard The TANGO_LOG_PATH \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-LOG-PATH \end_layout \end_inset environment variable can be used to specify the log files location. If not set it defaults to /tmp/tango- under Unix and C:/tango- under Windows. For a given device-server, the files are actually saved into $TANGO_LOG_PATH/{ server_name}/{ server_instance_name}. This means that all the devices running within the same process log into the same directory. \end_layout \begin_layout Subsubsection The database and controlled access server (MYSQL_USER, MYSQL_PASSWORD, MYSQL_HOS T and MYSQL_DATABASE) \begin_inset CommandInset label LatexCommand label name "sub:Db-Env-Variables" \end_inset \end_layout \begin_layout Standard The Tango database server and the controlled access server (if used) need to connect to the MySQL database. They are using four environment variables called MYSQL_USER \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-USER \end_layout \end_inset , MYSQL_PASSWORD \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-PASSWORD \end_layout \end_inset to know which user/password they must use to access the database, MYSQL_HOST \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-HOST \end_layout \end_inset in case the MySQL database is running on another host and MYSQL_DATABASE \begin_inset Index idx status collapsed \begin_layout Plain Layout MYSQL-DATABASE \end_layout \end_inset to specify the name of the database to connect to. The MYSQL_HOST environment variable allows you to specify the host and port number where MySQL is running. Its syntax is \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset host:port \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset The port definition is optional. If it is not specified, the default MySQL port will be used. If these environment variables are not defined, they will connect to the DBMS using the "root" login on localhost with the MySQL default port number (3306). The MYSQL_DATABASE environment variable has to be used in case your are using the same Tango Database device server executable code to connect to several Tango databases each of them having a different name. \end_layout \begin_layout Subsubsection The controlled access \end_layout \begin_layout Standard Even if a controlled access system is running, it is possible to by-pass it if in the environment of the client application the environment variable SUPER_TANGO \begin_inset Index idx status collapsed \begin_layout Plain Layout SUPER-TANGO \end_layout \end_inset is defined to "true". \end_layout \begin_layout Subsubsection The event buffer size \end_layout \begin_layout Standard If required, the event buffer used by the ZMQ \begin_inset Index idx status collapsed \begin_layout Plain Layout ZMQ \end_layout \end_inset software could be tuned using environment variables. These variables are named TANGO_DS_EVENT_BUFFER_HWM \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-DS-EVENT-BUFFER-HWM \end_layout \end_inset for the event buffer on a device server side and TANGO_EVENT_BUFFER_HWM \begin_inset Index idx status collapsed \begin_layout Plain Layout TANGO-EVENT-BUFFER-HWM \end_layout \end_inset for the event buffer on the client size. Both of them are a number which is the maximum number of events which could be stored in these buffers. \end_layout \end_body \end_document tango-9.2.5a/doc/src/appendix/idl.lyx0000644023471100065110000035544113034745264014424 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \usepackage{amstext} \def\reg{\setbox0\hbox{$\mathchar"20D$}% \hbox to 0pt{\hbox to \wd0{\hfill\,\rm R\hfill}\hss}% $\mathchar"20D$} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding utf8x \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter The TANGO IDL file : Module Tango \end_layout \begin_layout Standard The fundamental idea of a device as a network object which has methods and data has been retained for TANGO. In TANGO objects are real C++/Java objects which can be instantiated and accessed via their methods and data by the client as if they were local objects. This interface is defined in CORBA IDL. The fundamental interface is Device. All TANGO control objects will be of this type i.e. they will implement and offer the Device interface. Some wrapper classes group in an API will hide the calls to the Device interface from the client so that the client will only see the wrapper classes. All CORBA details will be hidden from the client as far as possible. \end_layout \begin_layout Section Aliases \end_layout \begin_layout Standard \series bold AttributeConfigList \end_layout \begin_layout Standard typedef sequence AttributeConfigList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfigList_2 \end_layout \begin_layout Standard typedef sequence AttributeConfigList_2; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfigList_3 \end_layout \begin_layout Standard typedef sequence AttributeConfigList_3; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfigList_5 \end_layout \begin_layout Standard typedef sequence AttributeConfigList_5; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeDimList \end_layout \begin_layout Standard typedef sequence AttributeDimList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValueList \end_layout \begin_layout Standard typedef sequence AttributeValueList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValueList_3 \end_layout \begin_layout Standard typedef sequence AttributeValueList_3; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValueList_4 \end_layout \begin_layout Standard typedef sequence AttributeValueList_4; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValueList_5 \end_layout \begin_layout Standard typedef sequence AttributeValueList_5; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttrQualityList \end_layout \begin_layout Standard typedef sequence AttrQualityList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold CppClntIdent \end_layout \begin_layout Standard typedef unsigned long CppClntIdent; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistoryList \end_layout \begin_layout Standard typedef sequence DevAttrHistoryList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistoryList_3 \end_layout \begin_layout Standard typedef sequence DevAttrHistoryList_3; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevBoolean \end_layout \begin_layout Standard typedef boolean DevBoolean; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdHistoryList \end_layout \begin_layout Standard typedef sequence DevCmdHistoryList \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdInfoList \end_layout \begin_layout Standard typedef sequence DevCmdInfoList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdInfoList_2 \end_layout \begin_layout Standard typedef sequence DevCmdInfoList_2; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevDouble \end_layout \begin_layout Standard typedef double DevDouble; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevErrorList \end_layout \begin_layout Standard typedef sequence DevErrorList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevErrorListList \end_layout \begin_layout Standard typedef sequence DevErrorListList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevFloat \end_layout \begin_layout Standard typedef float DevFloat; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevLong \end_layout \begin_layout Standard typedef long DevLong; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevShort \end_layout \begin_layout Standard typedef short DevShort; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevString \end_layout \begin_layout Standard typedef string DevString; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevULong \end_layout \begin_layout Standard typedef unsigned long DevULong; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevUShort \end_layout \begin_layout Standard typedef unsigned short DevUShort; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarCharArray \end_layout \begin_layout Standard typedef sequence DevVarCharArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarDoubleArray \end_layout \begin_layout Standard typedef sequence DevVarDoubleArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarEncodedArray \end_layout \begin_layout Standard typedef sequence DevVarEncodedArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarFloatArray \end_layout \begin_layout Standard typedef sequence DevVarFloatArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarLongArray \end_layout \begin_layout Standard typedef sequence DevVarLongArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarPipeDataEltArray \end_layout \begin_layout Standard typedef sequence DevVarPipeDataEltArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarShortArray \end_layout \begin_layout Standard typedef sequence DevVarShortArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold DevVarStateArray \end_layout \begin_layout Standard typedef sequence DevVarStateArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarStringArray \end_layout \begin_layout Standard typedef sequence DevVarStringArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarULongArray \end_layout \begin_layout Standard typedef sequence DevVarULongArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarUShortArray \end_layout \begin_layout Standard typedef sequence DevVarUShortArray; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold EltInArrayList \end_layout \begin_layout Standard typedef sequence EltInArrayList; \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold JavaUUID \end_layout \begin_layout Standard typedef unsigned long long JavaUUID[2]; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold PipeConfigList \end_layout \begin_layout Standard typedef sequence PipeConfigList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold NamedDevErrorList \end_layout \begin_layout Standard typedef sequence NamedDevErrorList; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold TimeValList \end_layout \begin_layout Standard typedef sequence TimeValList; \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Section Enums \end_layout \begin_layout Standard \series bold AttrDataFormat \end_layout \begin_layout Standard enum AttrDataFormat \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset SCALAR, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset SPECTRUM, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset IMAGE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset FMT_UNKNOWN \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeDataType \end_layout \begin_layout Standard enum AttributeDataType \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_BOOL, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_SHORT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_LONG, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_LONG64, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_FLOAT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_DOUBLE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_UCHAR, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_USHORT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_ULONG, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_ULONG64, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_STRING, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_STATE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DEVICE_STATE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_ENCODED, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATT_NO_DATA \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttrQuality \end_layout \begin_layout Standard enum AttrQuality \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATTR_VALID, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATTR_INVALID, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATTR_ALARM, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATTR_CHANGING, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ATTR_WARNING \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttrWriteType \end_layout \begin_layout Standard enum AttrWriteType \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset READ, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset READ_WITH_WRITE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset WRITE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset READ_WRITE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset WT_UNKNOWN \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DispLevel \end_layout \begin_layout Standard enum DispLevel \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset OPERATOR, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EXPERT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DL_UNKNOWN \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevSource \end_layout \begin_layout Standard enum DevSource \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DEV, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset CACHE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset CACHE_DEV \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevState \end_layout \begin_layout Standard enum DevState \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ON, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset OFF, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset CLOSE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset OPEN, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset INSERT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EXTRACT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset MOVING, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset STANDBY, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset FAULT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset INIT, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset RUNNING, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ALARM, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DISABLE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset UNKNOWN \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold ErrSeverity \end_layout \begin_layout Standard enum ErrSeverity \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset WARN, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ERR, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PANIC \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold LockerLanguage \end_layout \begin_layout Standard enum LockerLanguage \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset CPP, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset JAVA \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold PipeWriteType \end_layout \begin_layout Standard enum PipeWriteType \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PIPE_READ, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PIPE_READ_WRITE, \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PIPE_WT_UNKNOWN \end_layout \begin_layout Standard }; \end_layout \begin_layout Section Structs \end_layout \begin_layout Standard \series bold ArchiveEventProp \end_layout \begin_layout Standard struct ArchiveEventProp \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string rel_change; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string abs_change; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string period; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \series bold \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset AttributeAlarm \end_layout \begin_layout Standard struct AttributeAlarm \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_warning; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_warning; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string delta_t; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string delta_val; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \series bold \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset AttDataReady \end_layout \begin_layout Standard struct AttributeAlarm \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long ctr; \end_layout \begin_layout Standard } \series bold ; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset AttributeConfig \end_layout \begin_layout Standard struct AttributeConfig \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrWriteType writable; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_y; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string description; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string label; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string standard_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string display_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string writable_attr_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfig_2 \end_layout \begin_layout Standard struct AttributeConfig_2 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrWriteType writable; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_y; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string description; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string label; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string standard_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string display_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string writable_attr_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DispLevel level; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfig_3 \end_layout \begin_layout Standard struct AttributeConfig_3 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrWriteType writable; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_y; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string description; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string label; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string standard_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string display_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string writable_attr_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DispLevel level; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeAlarm alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EventProperties event_prop; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray sys_extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeConfig_5 \end_layout \begin_layout Standard struct AttributeConfig_5 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrWriteType writable; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean memorized; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean mem_init; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long max_dim_y; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string description; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string label; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string standard_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string display_unit; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string min_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string max_value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string writable_attr_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DispLevel level; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string root_attr_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray enum_labels; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeAlarm att_alarm; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EventProperties event_prop; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray sys_extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeDim \end_layout \begin_layout Standard struct AttributeDim \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long dim_y; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValue \end_layout \begin_layout Standard struct AttributeValue \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQuality quality; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long dim_x; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long dim_y; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValue_3 \end_layout \begin_layout Standard struct AttributeValue_3 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQuality quality; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim r_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim w_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList err_list; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValue_4 \end_layout \begin_layout Standard struct AttributeValue_4 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrValUnion value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQuality quality; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim r_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim w_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList err_list; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold AttributeValue_5 \end_layout \begin_layout Standard struct AttributeValue_5 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrValUnion value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQuality quality; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim r_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDim w_dim; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList err_list; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold ChangeEventProp \end_layout \begin_layout Standard struct ChangeEventProp \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string rel_change; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string abs_change; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistory \end_layout \begin_layout Standard struct DevAttrHistory \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean attr_failed; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeValue value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList errors; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistory_3 \end_layout \begin_layout Standard struct DevAttrHistory_3 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean attr_failed; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeValue_3 value; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistory_4 \end_layout \begin_layout Standard struct DevAttrHistory_4 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeValList dates; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQualityList quals; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList quals_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDimList r_dims; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList r_dims_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDimList w_dims; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList w_dims_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorListList errors; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList errors_array; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevAttrHistory_5 \end_layout \begin_layout Standard struct DevAttrHistory_5 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrDataFormat data_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long data_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeValList dates; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrQualityList quals; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList quals_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDimList r_dims; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList r_dims_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDimList w_dims; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList w_dims_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorListList errors; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList errors_array; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdHistory \end_layout \begin_layout Standard struct DevCmdHistory \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean cmd_failed; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList errors; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdHistory_4 \end_layout \begin_layout Standard struct DevCmdHistory_4 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeValList dates; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset any value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeDimList dims; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList dims_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorListList errors; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset EltInArrayList errors_array; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long cmd_type; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdInfo \end_layout \begin_layout Standard struct DevCmdInfo \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string cmd_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long cmd_tag; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long in_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long out_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string in_type_desc; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string out_type_desc; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevCmdInfo_2 \end_layout \begin_layout Standard struct DevCmdInfo_2 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string cmd_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DispLevel level; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long cmd_tag; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long in_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long out_type; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string in_type_desc; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string out_type_desc; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevEncoded \end_layout \begin_layout Standard struct DevEncoded \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevString encoded_format; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarCharArray encoded_data; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevError \end_layout \begin_layout Standard struct DevError \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string reason; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ErrSeverity severity; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string desc; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string origin; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevInfo \end_layout \begin_layout Standard struct DevInfo \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string dev_class; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string server_id; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string server_host; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long server_version; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string doc_url; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevInfo_3 \end_layout \begin_layout Standard struct DevInfo_3 \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string dev_class; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string server_id; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string server_host; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long server_version; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string doc_url; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string dev_type; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevIntrChange \end_layout \begin_layout Standard struct DevIntrChange \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean dev_started; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevCmdInfoList_2 cmds; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttributeConfigList_5 atts; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevPipeBlob \end_layout \begin_layout Standard struct DevPipeBlob \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarPipeDataEltArray blob_data; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevPipeData \end_layout \begin_layout Standard struct DevPipeData \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset TimeVal time; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevPipeBlob data_blob; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevPipeDataElt \end_layout \begin_layout Standard struct DevPipeDataElt \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset AttrValUnion value; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarPipeDataEltArray inner_blob; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string inner_blob_name; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarDoubleStringArray \end_layout \begin_layout Standard struct DevVarDoubleStringArray \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarDoubleArray dvalue; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray svalue; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold DevVarLongStringArray \end_layout \begin_layout Standard struct DevVarLongStringArray \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarLongArray lvalue; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray svalue; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold EltInArray \end_layout \begin_layout Standard struct EltInArray \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long start; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long nb_elt; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold EventProperties \end_layout \begin_layout Standard struct EventProperties \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ChangeEventProp ch_event; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PeriodicEventProp per_event; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset ArchiveEventProp arch_event; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold JavaClntIdent \end_layout \begin_layout Standard struct JavaClntIdent \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string MainClass; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset JavaUUID uuid; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold NamedDevError \end_layout \begin_layout Standard struct NamedDevError \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long index_in_call; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList err_list; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold PeriodicEventProp \end_layout \begin_layout Standard struct PeriodicEventProp \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string period; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold PipeConfig \end_layout \begin_layout Standard struct PipeConfig \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string description; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string label; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DispLevel level; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset PipeWriteType writable; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray extensions; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold TimeV \series default a \series bold l \end_layout \begin_layout Standard struct TimeVal \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long tv_sec; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long tv_usec; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long tv_nsec; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold ZmqCallInfo \end_layout \begin_layout Standard struct ZmqCallInfo \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset long version; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset unsigned long ctr; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset string method_name; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarCharArray oid; \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset boolean call_is_except; \end_layout \begin_layout Standard }; \end_layout \begin_layout Section Unions \end_layout \begin_layout Standard \series bold AttrValUnion \end_layout \begin_layout Standard union AttrValUnion switch (AttributeDataType) \end_layout \begin_layout Standard { \end_layout \begin_layout Standard case ATT_BOOL: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarBooleanArray bool_att_value; \end_layout \begin_layout Standard case ATT_SHORT: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarShortArray short_att_value; \end_layout \begin_layout Standard case ATT_LONG: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarLongArray long_att_value; \end_layout \begin_layout Standard case ATT_LONG64: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarLong64Array long64_att_value; \end_layout \begin_layout Standard case ATT_FLOAT: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarFloatArray float_att_value; \end_layout \begin_layout Standard case ATT_DOUBLE: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarDoubleArray double_att_value; \end_layout \begin_layout Standard case ATT_UCHAR \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarCharArray uchar_att_value; \end_layout \begin_layout Standard case ATT_USHORT: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarUShortArray ushort_att_value; \end_layout \begin_layout Standard case ATT_ULONG: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarULongArray ulong_att_value; \end_layout \begin_layout Standard case ATT_ULONG64: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarULong64Array ulong64_att_value; \end_layout \begin_layout Standard case ATT_STRING: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStringArray string_att_value; \end_layout \begin_layout Standard case ATT_STATE: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarStateArray state_att_value; \end_layout \begin_layout Standard case DEVICE_STATE: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevState dev_state_att; \end_layout \begin_layout Standard case ATT_ENCODED: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevVarEncodedArray encoded_att_value; \end_layout \begin_layout Standard case ATT_NO_DATA: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevBoolean union_no_data; \end_layout \begin_layout Standard }; \series bold \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset ClntIdent \end_layout \begin_layout Standard union ClntIdent switch (LockerLanguage) \end_layout \begin_layout Standard { \end_layout \begin_layout Standard case CPP: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset CppClntIdent cpp_clnt; \end_layout \begin_layout Standard case JAVA: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset JavaClntIdent java_clnt; \end_layout \begin_layout Standard }; \end_layout \begin_layout Section Exceptions \end_layout \begin_layout Standard \series bold DevFailed \end_layout \begin_layout Standard exception DevFailed \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset DevErrorList errors; \end_layout \begin_layout Standard }; \series bold \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset MultiDevFailed \end_layout \begin_layout Standard exception MultiDevFailed \end_layout \begin_layout Standard { \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset NamedDevErrorList errors; \end_layout \begin_layout Standard }; \begin_inset Newline newline \end_inset \end_layout \begin_layout Section Interface Tango::Device \end_layout \begin_layout Standard The fundamental interface for all TANGO objects. Each Device is a network object which can be accessed locally or via network. The network protocol on the wire will be IIOP. The Device interface implements all the basic functions needed for doing generic synchronous and asynchronous I/O on a device. A Device object has data and actions. Data are represented in the form of Attributes. Actions are represented in the form of Commands. The CORBA Device interface offers attributes and methods to access the attributes and commands. A client will either use these methods directly from C++ or Java or access them via wrapper classes implemented in a API. The Device interface describes only the remote network interface. Implementation features like threads, command security, priority etc. are dealt with in server side of the device server model. \end_layout \begin_layout Subsection Attributes \end_layout \begin_layout Standard \series bold adm_name \end_layout \begin_layout Standard readonly attribute string adm_name; \end_layout \begin_layout Standard adm_name (readonly) - administrator device unique ascii identifier \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold description \end_layout \begin_layout Standard readonly attribute string description; \end_layout \begin_layout Standard description (readonly) - general description of device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold name \end_layout \begin_layout Standard readonly attribute string name; \end_layout \begin_layout Standard name (readonly) - unique ascii identifier \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold state \end_layout \begin_layout Standard readonly attribute DevState state; \end_layout \begin_layout Standard state (readonly) - device state \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold status \end_layout \begin_layout Standard readonly attribute string status; \end_layout \begin_layout Standard status (readonly) - device state as ascii string \end_layout \begin_layout Subsection Operations \end_layout \begin_layout Standard \series bold black_box \begin_inset Index idx status collapsed \begin_layout Plain Layout black-box \end_layout \end_inset \end_layout \begin_layout Standard DevVarStringArray black_box(in long number) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read list of last N commands executed by clients \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset number -- of commands to return \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of command and clients \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_inout \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout \end_layout \end_inset \end_layout \begin_layout Standard any command_inout(in string command, in any argin) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard execute a command on a device synchronously with no input parameter and one one output parameter \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- ascii string e.g. "On" \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset argin -- command input parameter e.g. float \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command result. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_list_query \begin_inset Index idx status collapsed \begin_layout Plain Layout command-list-query \end_layout \end_inset \end_layout \begin_layout Standard DevCmdInfoList command_list_query() \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard query device to see what commands it supports \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of commands and their types \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_query \begin_inset Index idx status collapsed \begin_layout Plain Layout command-query \end_layout \end_inset \end_layout \begin_layout Standard DevCmdInfo command_query(in string command) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard query device to see command argument \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- name \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command and its types \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold get_attribute_config \begin_inset Index idx status collapsed \begin_layout Plain Layout get-attribute-config \end_layout \end_inset \end_layout \begin_layout Standard AttributeConfigList get_attribute_config(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read the configuration for a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute configurations read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold info \begin_inset Index idx status collapsed \begin_layout Plain Layout info \end_layout \end_inset \end_layout \begin_layout Standard DevInfo info() \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard return general information about object e.g. class, type, ... \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset device info \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold ping \begin_inset Index idx status collapsed \begin_layout Plain Layout ping \end_layout \end_inset \end_layout \begin_layout Standard void ping() \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard ping a device to see if it alive \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold read_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attributes \end_layout \end_inset \end_layout \begin_layout Standard AttributeValueList read_attributes(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold set_attribute_config \begin_inset Index idx status collapsed \begin_layout Plain Layout set-attribute-config \end_layout \end_inset \end_layout \begin_layout Standard void set_attribute_config(in AttributeConfigList new_conf) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard set the configuration for a variable list of attributes from the device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset new_conf -- list of attribute configuration to be set \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold write_attributes \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset \end_layout \begin_layout Standard void write_attributes(in AttributeValueList values) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard write a variable list of attributes to a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset values -- list of attribute values to write \end_layout \begin_layout Section Interface Tango::Device_2 \end_layout \begin_layout Standard interface Device_2 inherits from Tango::Device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The updated Tango device interface. It inherits from Tango::Device and therefore supports all attribute/operation defined in the Tango::Device interface. Two CORBA operations have been modified to support more parameters (command_ino ut_2 and read_attribute_2). Three CORBA operations now retrun a different data type (command_list_query_2, command_query_2 and get_attribute_config) \end_layout \begin_layout Subsection Operations \end_layout \begin_layout Standard \series bold command_inout_2 \end_layout \begin_layout Standard any command_inout_2(in string command, in any argin, in DevSource source) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard execute a command on a device synchronously with no input parameter and one one output parameter \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- ascii string e.g. "On" \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset argin -- command input parameter \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset source -- data source \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command result. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_inout_history_2 \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-history-2 \end_layout \end_inset \end_layout \begin_layout Standard DevCmdHistoryList command_inout_history_2(in string command, in long n) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get command result history from polling buffer. Obviously, the command must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- ascii string e.g. "On" \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of command result (or exception parameters if the command failed). \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_list_query_2 \end_layout \begin_layout Standard DevCmdInfoList_2 command_list_query_2() \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard query device to see what commands it supports \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of commands and their types \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_query_2 \end_layout \begin_layout Standard DevCmdInfo_2 command_query_2(in string command) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard query device to see command argument \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- name \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command and its types \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold get_attribute_config_2 \end_layout \begin_layout Standard AttributeConfigList_2 get_attribute_config_2(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read the configuration for a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute configurations read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold read_attributes_2 \end_layout \begin_layout Standard AttributeValueList read_attributes_2(in DevVarStringArray names, in DevSource source) \end_layout \begin_layout Standard raises(DevFailed) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold read_attribute_history_2 \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-2 \end_layout \end_inset \end_layout \begin_layout Standard DevAttrHistoryList read_attributes_history_2(in string name, in long n) \end_layout \begin_layout Standard raises(DevFailed) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get attribute value history from polling buffer. Obviously, the attribute must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- Attribute name to read history \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- Record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute value (or exception parameters if the attribute failed). \begin_inset Newline newline \end_inset \end_layout \begin_layout Section Interface Tango::Device_3 \end_layout \begin_layout Standard interface Device_3 inherits from Tango::Device_2 \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The updated Tango device interface for Tango release 5. It inherits from Tango::Device_2 and therefore supports all attribute/operation defined in the Tango::Device_2 interface. Six CORBA operations now return a different data type (read_attributes_3, write_attributes_3, read_attribute_history_3, info_3, get_attribute_config_3 and set_attribute_config_3) \end_layout \begin_layout Subsection Operations \end_layout \begin_layout Standard \series bold read_attributes_3 \end_layout \begin_layout Standard AttributeValueList_3 read_attributes_3(in DevVarStringArray names, in DevSource source) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset source -- data source \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold write_attributes_3 \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-history-2 \end_layout \end_inset \end_layout \begin_layout Standard void write_attributes_3(in AttributeValueList values) \end_layout \begin_layout Standard raises(DevFailed, MultiDevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard write a variable list of attributes to a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset values -- list of attribute values to write \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold read_attribute_history_3 \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-2 \end_layout \end_inset \end_layout \begin_layout Standard DevAttrHistoryList_3 read_attributes_history_3(in string name, in long n) \end_layout \begin_layout Standard raises(DevFailed) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get attribute value history from polling buffer. Obviously, the attribute must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- Attribute name to read history \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- Record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute value (or exception parameters if the attribute failed). \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold info_3 \begin_inset Index idx status collapsed \begin_layout Plain Layout info \end_layout \end_inset \end_layout \begin_layout Standard DevInfo_3 info() \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard return general information about object e.g. class, type, ... \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset device info \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold get_attribute_config_3 \end_layout \begin_layout Standard AttributeConfigList_3 get_attribute_config_3(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read the configuration for a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute configurations read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold set_attribute_config_3 \begin_inset Index idx status collapsed \begin_layout Plain Layout set-attribute-config \end_layout \end_inset \end_layout \begin_layout Standard void set_attribute_config_3(in AttributeConfigList_3 new_conf) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard set the configuration for a variable list of attributes from the device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset new_conf -- list of attribute configuration to be set \begin_inset Newline newline \end_inset \end_layout \begin_layout Section Interface Tango::Device_4 \end_layout \begin_layout Standard interface Device_4 inherits from Tango::Device_3 \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The updated Tango device interface for Tango release 7. It inherits from Tango::Device_3 and therefore supports all attribute/operation defined in the Tango::Device_3 interface. \end_layout \begin_layout Subsection Operations \end_layout \begin_layout Standard \series bold read_attributes_4 \end_layout \begin_layout Standard AttributeValueList_4 read_attributes_4(in DevVarStringArray names, in DevSource source,in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset source -- data source \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold write_attributes_4 \end_layout \begin_layout Standard void write_attributes_3(in AttributeValueList_4 values, in ClniIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed, MultiDevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard write a variable list of attributes to a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset values -- list of attribute values to write \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_inout_4 \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-4 \end_layout \end_inset \end_layout \begin_layout Standard any command_inout_4(in string command, in any argin, in DevSource source, In ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Execute a command on a device synchronously with one input parameter and one one output parameter \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command -- ascii string e.g. "On" \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset argin -- command input parameter \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset source -- data source \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset command result \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold read_attribute_history_4 \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-4 \end_layout \end_inset \end_layout \begin_layout Standard DevAttrHistory_4 read_attributes_history_4(in string name, in long n) \end_layout \begin_layout Standard raises(DevFailed) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get attribute value history from polling buffer. Obviously, the attribute must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- Attribute name to read history \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- Record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset Attribute value (or exception parameters if the attribute failed) coded in a structure. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold command_inout_history_4 \begin_inset Index idx status collapsed \begin_layout Plain Layout command-inout-history-4 \end_layout \end_inset \end_layout \begin_layout Standard DevCmdHistory_4 command_inout_history_4(in string command, in long n) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get command value history from polling buffer. Obviously, the command must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Parameters: \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- Command name to read history \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- Record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset Command value (or exception paramteters) coded in a structure \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold write_read_attribute_4 \end_layout \begin_layout Standard AttributeValueList_4 write_read_attribute_4(in AttributeValueList_4 values, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed,MultiDevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Write then read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset values -- list of attribute values to write \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold set_attribute_config_4 \begin_inset Index idx status collapsed \begin_layout Plain Layout set-attribute-config-4 \end_layout \end_inset \end_layout \begin_layout Standard void set_attribute_config_4(in AttributeConfigList_3 new_conf, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard set the configuration for a variable list of attributes from the device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset new_conf -- list of attribute configuration to be set \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \begin_inset Newline newline \end_inset Interface Tango::Device_4 \end_layout \begin_layout Standard interface Device_4 inherits from Tango::Device_3 \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The updated Tango device interface for Tango release 7. It inherits from Tango::Device_3 and therefore supports all attribute/operation defined in the Tango::Device_3 interface. \end_layout \begin_layout Section Interface Tango::Device_5 \end_layout \begin_layout Standard interface Device_5 inherits from Tango::Device_4 \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard The updated Tango device interface for Tango release 9. It inherits from Tango::Device_4 and therefore supports all attribute/operation defined in the Tango::Device_4 interface. \end_layout \begin_layout Subsection operations \end_layout \begin_layout Standard \series bold get_attribute_config_5 \end_layout \begin_layout Standard AttributeConfigList_5 get_attribute_config_5(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read the configuration for a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute configurations read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold set_attribute_config_5 \begin_inset Index idx status collapsed \begin_layout Plain Layout set-attribute-config-5 \end_layout \end_inset \end_layout \begin_layout Standard void set_attribute_config_5(in AttributeConfigList_5 new_conf, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard set the configuration for a variable list of attributes from the device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset new_conf -- list of attribute configuration to be set \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold read_attributes_5 \end_layout \begin_layout Standard AttributeValueList_5 read_attributes_5(in DevVarStringArray names, in DevSource source,in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of attribute names to read \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset source -- data source \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold write_read_attributes_5 \end_layout \begin_layout Standard AttributeValueList_5 write_read_attributes_5(in AttributeValueList_4 values, in DevVarStringArray r_names, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed,MultiDevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Write then read a variable list of attributes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset values -- list of attribute values to write \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset r_names -- list of attribute to read \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of attribute values read \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold read_attribute_history_5 \begin_inset Index idx status collapsed \begin_layout Plain Layout read-attribute-history-5 \end_layout \end_inset \end_layout \begin_layout Standard DevAttrHistory_5 read_attributes_history_5(in string name, in long n) \end_layout \begin_layout Standard raises(DevFailed) \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Get attribute value history from polling buffer. Obviously, the attribute must be polled. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- Attribute name to read history \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset n -- Record number \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset Attribute value (or exception parameters if the attribute failed) coded in a structure. \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold get_pipe_config_5 \end_layout \begin_layout Standard PipeConfigList get_pipe_config_5(in DevVarStringArray names) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read the configuration for a variable list of pipes from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- list of pipe names to read \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset list of pipe configurations \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold set_pipe_config_5 \begin_inset Index idx status collapsed \begin_layout Plain Layout set-pipe-config-5 \end_layout \end_inset \end_layout \begin_layout Standard void set_pipe_config_5(in PipeConfigList new_conf, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard set the configuration for a variable list of pipes from the device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset new_conf -- list of pipe configuration to be set \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \series bold \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold read_pipe_5 \end_layout \begin_layout Standard DevPipeData read_pipe_5(in string name, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard read a pipe from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset name -- pipe name to read \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset Pipe value \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \align left \series bold write_pipe_5 \end_layout \begin_layout Standard void write_pipe_5(in DevPipeData value, in ClniIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard write a pipe to a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset value -- new pipe value to write \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \series bold write_read_pipe_5 \end_layout \begin_layout Standard DevPipeData write_read_pipe_5(in DevPipeData value, in ClntIdent cl_ident) \end_layout \begin_layout Standard raises(DevFailed); \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard Write then read a pipe from a device \begin_inset Newline newline \end_inset \end_layout \begin_layout Standard \emph on Parameters \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset value -- New pipe value to write \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset cl_ident -- client identificator \end_layout \begin_layout Standard \emph on Returns \emph default : \end_layout \begin_layout Standard \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset \begin_inset space ~ \end_inset pipe values read \end_layout \end_body \end_document tango-9.2.5a/doc/src/appendix/naming.lyx0000644023471100065110000002673113034745264015122 00000000000000#LyX 1.3 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 221 \textclass book \language english \inputencoding latin1 \fontscheme default \graphics default \paperfontsize default \spacing single \papersize a4paper \paperpackage widemarginsa4 \use_geometry 0 \use_amsmath 0 \use_natbib 0 \use_numerical_citations 0 \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language english \quotes_times 2 \papercolumns 1 \papersides 2 \paperpagestyle default \layout Chapter Tango object naming (device, attribute and property) \layout Section Device name \begin_inset LatexCommand \label{DeviceNaming} \end_inset \layout Standard A Tango device name is a three fields name. The field separator is the \series bold / \series default character. The first field is named \series bold domain \series default , the second field is named \series bold family \series default and the last field is named \series bold member \series default .A tango device name looks like \begin_inset ERT status Collapsed \layout Standard \backslash begin{center} \end_inset domain/family/member \begin_inset ERT status Collapsed \layout Standard \backslash end{center} \end_inset It is a hierarchical notation. The member specifies which element within a family. The family specifies which kind of equipment within a domain. The domain groups devices related to which part of the accelerator/experiment they belongs to. At ESRF, some of the machine control system domain name are SR for the storage ring, TL1 for the transfer line 1 or SY for the synchrotron booster. For experiment, ID11 is the domain name for all devices belonging to the experiment behind insertion device 11. Here are some examples of Tango device name used at the ESRF : \layout Itemize \series bold sr/d-ct/1 \series default : The current transformer. The domain part is sr for storage ring. The family part is d-ct for diagnostic/current transformer and the member part is 1 \layout Itemize \series bold fe/v-pen/id11-1 \series default : A Penning gauge. The domain part is fe for front-end. The family part is v-pen for vacuum/penning and the member name is id11-1 to specify that this is the first gauge on the front-end part after the insertion device 11 \layout Section Full object name \layout Standard The device name as described above is not enough to cover all Tango usage like device server without database or device access for multi control system. With the naming schema, we must also be able to name attribute and property. Therefore, the full naming schema is \begin_inset ERT status Collapsed \layout Standard \backslash begin{center} \end_inset \emph on [protocol://][host:port/]device_name[/attribute][->property][#dbase=xx \emph default \begin_inset ERT status Collapsed \layout Standard ] \backslash end{center} \end_inset The protocol, host, port, attribute, property and dbase fields are optional. The meaning of these fields are : \layout List \labelwidthstring 00.00.0000 protocol : Specifies which protocol is used (Tango or Taco). Tango is the default \layout List \labelwidthstring 00.00.0000 dbase=xx : The supported value for xx is \emph on yes \emph default and \emph on no \emph default . This field is used to specify that the device is a device served by a device server started with or without database usage. The default value is \emph on dbase=yes \layout List \labelwidthstring 00.00.0000 host:port : This field has different meaning according to the dbase value. If \emph on dbase=yes \emph default (the default), the host is the host where the control system database server is running and port is the database server port. It has a higher priority than the value defined by the TANGO_HOST environment variable. If \emph on dbase=no \emph default , host is the host name where the device server process serving the device is running and port is the device server process port. \layout List \labelwidthstring 00.00.0000 attribute : The attribute name \layout List \labelwidthstring 00.00.0000 property : The property name \layout Standard The host:port and dbase=xx fields are necessary only when creating the DevicePro xy object used to remotely access the device. The -> characters are used to specify a property name. \layout Subsection Some examples \layout Subsubsection Full device name examples \layout Itemize \series bold gizmo:20000/sr/d-ct/1 \series default : Device sr/d-ct/1 running in a specified control system with the database server running on a host called gizmo and using the port number 20000. The TANGO_HOST environment variable will not be used. \layout Itemize \series bold tango://freak:2345/id11/rv/1#dbase=no \series default : Device served by a device server started without database. The server is running on a host called freak and use port number 2345. //freak:2345/id11/rv/1#dbase=no is also possible for the same device. \layout Itemize \series bold Taco://sy/ps-ki/1 \series default : Taco device sy/ps-ki/1 \layout Subsubsection Attribute name examples \layout Itemize \series bold id11/mot/1/Position \series default : Attribute position for device id11/mot/1 \layout Itemize \series bold sr/d-ct/1/Lifetime \series default : Attribute lifetime for Tango device sr/d-ct/1 \layout Subsubsection Attribute property name \layout Itemize \series bold id11/rv/1/temp->label \series default : Property label for attribute temp for device id11/rv/1. \layout Itemize \series bold sr/d-ct/1/Lifetime->unit \series default : The unit property for the Lifetime attribute of the sr/d-ct/1 device \layout Subsubsection Device property name \layout Itemize \series bold sr/d-ct/1->address \series default : the address property for device sr/d-ct/1 \layout Subsubsection Class property name \layout Itemize \series bold Starter->doc_url \series default : The doc_url property for a class called Starter \layout Section Device and attribute name alias \begin_inset LatexCommand \index{alias} \end_inset \layout Standard Within Tango, each device or attribute can have an alias name defined in the database. Every time a device or an attribute name is requested by the API's, it is possible to use the alias. The alias is simply an open string stored in the database. The rule of the alias is to give device or attribute name a name more natural from the physicist point of view. Let's imagine that for experiment, the sample position is described by angles called teta and psi in physics book. It is more natural for physicist when they move the motor related to sample position to use \emph on teta \emph default and \emph on psi \emph default rather device name like \emph on idxx/mot/1 \emph default or \emph on idxx/mot/2 \emph default . An attribute alias is a synonym for the four fields used to name an attribute. For instance, the attribute \emph on Current \emph default of a power-supply device called \emph on sr/ps/dipole \emph default could have an alias \emph on DipoleCurrent \emph default . This alias can be used when creating an instance of a AttributeProxy class instead of the full attribute name which is \emph on sr/ps/dipole/Current \emph default . Device alias name are uniq within a Tango control system. Attribute alias name are also uniq within a Tango control system. \layout Section Reserved words and characters, limitations \layout Standard From the naming schema described above, the reserved characters are \series bold : \series default , \series bold # \series default , \series bold / \series default and the reserved string is : \series bold -> \series default . On top of that, the dbt_update tool (tool to fulfill database from the content of a file) reserved the \series bold device \series default word \layout Standard The device name, its domain, member and family fields and its alias are stored in the Tango database. The default maximum size for these items are : \layout Standard \added_space_top 0.3cm \added_space_bottom 0.3cm \align center \begin_inset Tabular \begin_inset Text \layout Standard Item \end_inset \begin_inset Text \layout Standard max length \end_inset \begin_inset Text \layout Standard device name \end_inset \begin_inset Text \layout Standard 255 \end_inset \begin_inset Text \layout Standard domain field \end_inset \begin_inset Text \layout Standard 85 \end_inset \begin_inset Text \layout Standard family field \end_inset \begin_inset Text \layout Standard 85 \end_inset \begin_inset Text \layout Standard member field \end_inset \begin_inset Text \layout Standard 85 \end_inset \begin_inset Text \layout Standard device alias name \end_inset \begin_inset Text \layout Standard 255 \end_inset \end_inset \layout Standard The device name, the command name, the attribute name, the property name, the device alias name and the device server name are \series bold case insensitive \series default . \the_end tango-9.2.5a/doc/src/appendix/line.tex0000644023471100065110000000174013034745264014555 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/appendix/notifd2db.lyx0000644023471100065110000001137513034745264015522 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 0 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter The notifd2db utility \end_layout \begin_layout Section The notifd2db utility usage (For Tango releases lower than 8) \end_layout \begin_layout Standard The notifd2db utility is used to pass to Tango the necessary information for the Tango servers or clients to build connection with the CORBA notificatio n service. Its usage is: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset notifd2db [notifd2db_IOR_file] [host] [-o Device_server_database_file_name] [-h] \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \begin_layout Plain Layout \end_layout \begin_layout Plain Layout \end_layout \end_inset \end_layout \begin_layout Standard The [notifd2db_IOR_file] parameter is used to specify the file name used by the notification service to store its main IOR. This parameter is not mandatoty. Its default value is /tmp/rdfact.ior. The [host] parameter is ued to specify on which host the notification service should be exported. The default value is the host on which the command is run. The [-o Device_server_database_file_name] is used in case of event and device server started with the file as database (the -file device server command line option). The file name used here must be the file name used by the device server in its -file option. The [-h] option is just to display an help message. Notifd2db utility usage example: \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset notifd2db \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset to register notification service on the current host using the default notifictaion service IOR file name. \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset notifd C: \backslash Temp \backslash nd.ior \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset to register a notification service with IOR file named C: \backslash Temp \backslash nd.ior. \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash begin{center} \end_layout \begin_layout Plain Layout \end_layout \begin_layout Plain Layout \end_layout \end_inset notifd -o /var/my_ds_file.res \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset to register notification service in the /var/my_ds_file.res file used by a device server started with the device server -file command line option. \end_layout \end_body \end_document tango-9.2.5a/doc/src/appendix/prop_file.lyx0000644023471100065110000002336613034745264015631 00000000000000#LyX 1.6.2 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \language english \inputencoding latin1 \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \end_header \begin_body \begin_layout Chapter The property file syntax \end_layout \begin_layout Section Property file usage \end_layout \begin_layout Standard A property file is a file where you store all the property(ies) related to device(s) belonging to a specific device server process. In this file, one can find: \end_layout \begin_layout Itemize Which device(s) has to be created for each Tango class embedded in the device server process \end_layout \begin_layout Itemize Device(s) properties \end_layout \begin_layout Itemize Device(s) attribute properties \end_layout \begin_layout Standard This type of file is not required by a Tango control system. These informations are stored in the Tango database and having them also in a file could generate some data duplication issues. Nevertheless, in some cases, it could very very helpful to generate this type of file. These cases are: \end_layout \begin_layout Enumerate If you want to run a device server process on a host which does not have access to the Tango control system database. In such a case, the user can generate the file from the database content and run the device server process using this file as database (-file option of device server process) \end_layout \begin_layout Enumerate In case of massive property changes where no tool will be more adapted than your favorite text editor. In such a case, the user can generate a file from the database content, change/add/modify file contents using his favorite tool and then reload file content into the database. \end_layout \begin_layout Standard Jive \begin_inset CommandInset citation LatexCommand cite key "Jive doc" \end_inset is the tool provided to generate and load a property file. To generate a device server process properties file, select your device server process in the "Server" tab, right click and select "Save Server Data". A file selection window pops up allowing you to choose your file name and path. To reload a file in the Tango database, click on "File" then "Load Property File". \end_layout \begin_layout Section Property file syntax \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \series bold 1 \series default #--------------------------------------------------------- \end_layout \begin_layout LyX-Code 2 # SERVER TimeoutTest/manu, TimeoutTest device declaration \end_layout \begin_layout LyX-Code 3 #--------------------------------------------------------- \end_layout \begin_layout LyX-Code 4 \end_layout \begin_layout LyX-Code 5 TimeoutTest/manu/DEVICE/TimeoutTest: "et/to/01", \backslash \end_layout \begin_layout LyX-Code 6 "et/to/02", \backslash \end_layout \begin_layout LyX-Code 7 "et/to/03" \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 \end_layout \begin_layout LyX-Code 10 # --- et/to/01 properties \end_layout \begin_layout LyX-Code 11 \end_layout \begin_layout LyX-Code 12 et/to/01->StringProp: Property \end_layout \begin_layout LyX-Code 13 et/to/01->ArrayProp: 1, \backslash \end_layout \begin_layout LyX-Code 14 2, \backslash \end_layout \begin_layout LyX-Code 15 3 \end_layout \begin_layout LyX-Code 16 et/to/01->attr_min_poll_period: TheAttr, \backslash \end_layout \begin_layout LyX-Code 17 1000 \end_layout \begin_layout LyX-Code 18 et/to/01->AnotherStringProp: "A long string" \end_layout \begin_layout LyX-Code 19 et/to/01->ArrayStringProp: "the first prop", \backslash \end_layout \begin_layout LyX-Code 20 "the second prop" \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 # --- et/to/01 attribute properties \end_layout \begin_layout LyX-Code 23 \end_layout \begin_layout LyX-Code 24 et/to/01/TheAttr->display_unit: 1.0 \end_layout \begin_layout LyX-Code 25 et/to/01/TheAttr->event_period: 1000 \end_layout \begin_layout LyX-Code 26 et/to/01/TheAttr->format: %4d \end_layout \begin_layout LyX-Code 27 et/to/01/TheAttr->min_alarm: -2.0 \end_layout \begin_layout LyX-Code 28 et/to/01/TheAttr->min_value: -5.0 \end_layout \begin_layout LyX-Code 29 et/to/01/TheAttr->standard_unit: 1.0 \end_layout \begin_layout LyX-Code 30 et/to/01/TheAttr->__value: 111 \end_layout \begin_layout LyX-Code 31 et/to/01/BooAttr->event_period: 1000doc_url \end_layout \begin_layout LyX-Code 32 et/to/01/TestAttr->display_unit: 1.0 \end_layout \begin_layout LyX-Code 33 et/to/01/TestAttr->event_period: 1000 \end_layout \begin_layout LyX-Code 34 et/to/01/TestAttr->format: %4d \end_layout \begin_layout LyX-Code 35 et/to/01/TestAttr->standard_unit: 1.0 \end_layout \begin_layout LyX-Code 36 et/to/01/DbAttr->abs_change: 1.1 \end_layout \begin_layout LyX-Code 37 et/to/01/DbAttr->event_period: 1000 \end_layout \begin_layout LyX-Code 38 \end_layout \begin_layout LyX-Code 39 CLASS/TimeoutTest->InheritedFrom: Device_4Impl \end_layout \begin_layout LyX-Code 40 CLASS/TimeoutTest->doc_url: "http://www.esrf.fr/some/path" \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 1 - 3: Comments. Comment starts with the '#' character \end_layout \begin_layout Standard Line 4: Blank line \end_layout \begin_layout Standard Line 5 - 7: Devices definition. "DEVICE" is the keyword to declare a device(s) definition sequence. The general syntax is: \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset //DEVICE/: dev1,dev2,dev3 \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset Device(s) name can follow on next line if the last line character is ' \backslash ' (see line 5,6). The '"' characters around device name are generated by the Jive tool and are not mandatory. \end_layout \begin_layout Standard Line 12: Device property definition. The general device property syntax is \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset \series bold -> \series default : \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset In case of array, the array element delimiter is the character ','. Array definition can be splitted on several lines if the last line character is ' \backslash '. Allowed characters after the ':' delimiter are space, tabulation or nothing. \end_layout \begin_layout Standard Line 13 - 15 and 16 - 17: Device property (array) \end_layout \begin_layout Standard Line 18: A device string property with special characters (spaces). The '"' character is used to delimit the string \end_layout \begin_layout Standard Line 24 - 37: Device attribute property definition. The general device attribute property syntax is \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset / \series bold -> \series default : \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset Allowed characters after the ':' delimiter are space, tabulation or nothing. \end_layout \begin_layout Standard Line 39 - 40: Class property definition. The general class property syntax is \begin_inset ERT status open \begin_layout Plain Layout \backslash begin{center} \end_layout \end_inset CLASS/ \series bold -> \series default : \begin_inset ERT status open \begin_layout Plain Layout \backslash end{center} \end_layout \end_inset "CLASS" is the keyword to declare a class property definition. Allowed characters after the ':' delimiter are space, tabulation or nothing. On line 40, the '"' characters around the property value are mandatory due to the '/' character contains in the property value. \end_layout \end_body \end_document tango-9.2.5a/doc/src/appendix/starting_tango.lyx0000644023471100065110000003167413034745264016676 00000000000000#LyX 1.6.7 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 345 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \language english \inputencoding latin1 \font_roman default \font_sans default \font_typewriter default \font_default_family default \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \author "" \author "" \end_header \begin_body \begin_layout Chapter Starting a Tango control system \end_layout \begin_layout Section Without database \end_layout \begin_layout Standard When used without database \begin_inset Index status collapsed \begin_layout Plain Layout database \end_layout \end_inset , there is no additional process to start. Simply starts device server using the -nodb option (and eventually the -dlist option) on specific port. See \begin_inset CommandInset ref LatexCommand ref reference "sec:Device-server-without" \end_inset to find informations on how to start/write Tango device server not using the database. \end_layout \begin_layout Section With database \end_layout \begin_layout Standard Starting the Tango control system simply means starting its database device server on a well defined host using a well defined port. Use the host name and the port number to build the TANGO_HOST environment variable. See \begin_inset CommandInset ref LatexCommand ref reference "Env variable" \end_inset to find how starting a device server on a specific host. Obviously, the underlying database software (MySQL) must be started before the Tango database device server. The Tango database server connects to MySQL using a default logging name set to "root". You can change this behaviour with the MYSQL_USER \begin_inset Index status collapsed \begin_layout Plain Layout MYSQL-USER \end_layout \end_inset and MYSQL_PASSWORD \begin_inset Index status collapsed \begin_layout Plain Layout MYSQL-PASSWORD \end_layout \end_inset environment variables. Define them before starting the database server. \end_layout \begin_layout Standard If you are using the Tango administration graphical tool called \series bold Astor \series default \begin_inset Index status collapsed \begin_layout Plain Layout Astor \end_layout \end_inset , you also need to start a specific Tango device server called \series bold Starter \begin_inset Index status collapsed \begin_layout Plain Layout Starter \end_layout \end_inset \series default on each host where Tango device server(s) are running. See \begin_inset CommandInset citation LatexCommand cite key "Astor_doc" \end_inset for Astor documentation. This starter device server is able to start even before the Tango database device server is started. In this case, it will enter a loop in which it periodically tries to access the Tango database device. The loop exits and the server starts only if the database device access succeed. \end_layout \begin_layout Section With database and event \end_layout \begin_layout Subsection For Tango releases lower than 8 \end_layout \begin_layout Standard On top of what is described in the previous chapter, using event means using CORBA Notification service. Start one Notification Service \begin_inset Index status collapsed \begin_layout Plain Layout Notification Service \end_layout \end_inset daemon on each host where device server(s) used via events are running. The Notification Service daemon event channel factory IOR has to be registered in the Tango database. This is done with the \series bold notifd2db \begin_inset Index status collapsed \begin_layout Plain Layout notifd2db \end_layout \end_inset \series default command. The notification daemon is a process with a high thread number. By default, Unix like operating systems reserve a big amount of memory for each thread stack (8 MByte for Linux/Ubuntu, 10 MByte for Linux/RedHat 4). If your process has several hundreds of threads, this could generate a too high memory requirement on virtual memory and even exceed the maximun allowed memory per process (3 GBytes on Linux for 32 bits computer). The notification service daemon works very well with a value of only 2 Mybtes for thread stack. The Unix command line "ulimit \begin_inset Index status collapsed \begin_layout Plain Layout ulimit \end_layout \end_inset -s 2048" asks the operating system to give 2 Mbytes for each thread stack. Example of starting and registering a Notification Service daemon on a UNIX like operating system \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout LyX-Code 1 ulimit -s 2048 \end_layout \begin_layout LyX-Code 2 notifd -n -DDeadFilterInterval=300 & \end_layout \begin_layout LyX-Code 3 notifd2db \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Standard The Notification Service daemon is started at line 2. Its "-DDeadFilterInterval" \begin_inset Index status collapsed \begin_layout Plain Layout DeadFilterInterval \end_layout \end_inset option is used to specify some internal cleaning of dead objects within the notification service. The "-n" option is used to disable the use of the CORBA Naming Service for registering the default event channel factory. The registration of the Notification Service daemon in the Tango database is done at line 2. \end_layout \begin_layout Standard It differs on a Windows computer \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout LyX-Code 1 notifd -n -DDeadFilterInterval=300 -DFactoryIORFileName=C: \backslash Temp \backslash evfact.ior & \end_layout \begin_layout LyX-Code 2 notifd2db C: \backslash Temp \backslash evfact.ior \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Subsection For release 8 and above \end_layout \begin_layout Standard A new event system has been implemented starting with Tango release 8. With this new event system, the CORBA Notification service is not needed any more. This means that \series bold as soon \series default as all Tango device server processes running on a host and all clients using events from their devices used Tango 8, it is not required to start any process other than the device servers and the clients. You can forget the previous sub-chapter! \end_layout \begin_layout Section With file used as database \end_layout \begin_layout Standard When used with database \begin_inset Index status collapsed \begin_layout Plain Layout database \end_layout \end_inset on file, there is no additional process to start. Simply starts device server using the -file option specifying file name port. See \begin_inset CommandInset ref LatexCommand ref reference "sec:Device-server-file" \end_inset to find informations on how to start Tango device server using database on file. \end_layout \begin_layout Section With file used as database and event \end_layout \begin_layout Subsection For Tango releases lower than 8 \end_layout \begin_layout Standard Using event means using CORBA Notification service. Start one Notification Service \begin_inset Index status collapsed \begin_layout Plain Layout Notification Service \end_layout \end_inset daemon on the host where device server(s) using events are running. The Notification Service daemon event channel factory IOR has to be registered in the file(s) use as database. This is done with the \series bold notifd2db \begin_inset Index status collapsed \begin_layout Plain Layout notifd2db \end_layout \end_inset \series default command. Example of starting and registering a Notification Service daemon on a UNIX like operating system \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout LyX-Code 1 notifd -n -DDeadFilterInterval=300 & \end_layout \begin_layout LyX-Code 2 notifd2db -o /var/myfile.res \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Standard The Notification Service daemon is started at line 1. Its "-n" option is used to disable the use of the CORBA Naming Service for registering the default event channel factory. The registration of the Notification Service daemon in the file used as database is done at line 2 with its \series bold -o \series default command line option. \end_layout \begin_layout Standard It differs on a Windows computer because the name of the file used by the CORBA notification service to store its channel factory IOR must be specified using its -D command line option. This file name has also to be passed to the notifd2db command. \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout LyX-Code 1 notifd -n -DDeadFilterInterval=300 -DFactoryIORFileName=C: \backslash Temp \backslash evfact.ior & \end_layout \begin_layout LyX-Code 2 notifd2db C: \backslash Temp \backslash evfact.ior -o C: \backslash Temp \backslash myfile.res \end_layout \begin_layout Standard \begin_inset ERT status open \begin_layout Plain Layout \backslash input{line.tex} \end_layout \end_inset \end_layout \begin_layout Subsection For release 8 and above \end_layout \begin_layout Standard A new event system has been implemented starting with Tango release 8. With this new event system, the CORBA Notification service is not needed any more. This means that \series bold as soon \series default as all clients using events from devices embedded in the device server use Tango 8, it is not required to start any process other than the device server and its clients. \end_layout \begin_layout Section With the controlled access \end_layout \begin_layout Standard Using the Tango controlled access means starting a specific device server called TangoAccessControl \begin_inset Index status collapsed \begin_layout Plain Layout TangoAccessControl \end_layout \end_inset . By default, this server has to be started with the instance name set to "1" and its device name is "sys/access_control/1". The command line to start this device server is: \end_layout \begin_layout LyX-Code TangoAccessControl 1 \end_layout \begin_layout Standard This server connects to MySQL using a default logging name set to "root". You can change this behaviour with the MYSQL_USER \begin_inset Index status collapsed \begin_layout Plain Layout MYSQL-USER \end_layout \end_inset and MYSQL_PASSWORD \begin_inset Index status collapsed \begin_layout Plain Layout MYSQL-PASSWORD \end_layout \end_inset environment variables. Define them before starting the controlled access device server. This server also uses the MYSQL_HOST \begin_inset Index status collapsed \begin_layout Plain Layout MYSQL-HOST \end_layout \end_inset environment variable if you need to connect it to some MySQL server running on another host. The syntax of this environment varaible is "host:port". Port is optional and if it is not defined, the MySQL default port is used (3306). If it is not defined at all, a connection to the localhost is made. This controlled access system uses the Tango database to retrieve user rights and it is not possible to run it in a Tango control system running without database. \end_layout \end_body \end_document tango-9.2.5a/doc/src/cpp_api/0000755023471100065110000000000013034745265012766 500000000000000tango-9.2.5a/doc/src/cpp_api/line.tex0000644023471100065110000000174013034745265014361 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/src/cpp_api/cppapi.lyx0000644023471100065110000144631513034745265014736 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 4 \paragraph_separation skip \defskip medskip \quotes_language english \papercolumns 1 \papersides 2 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Chapter The TANGO C++ Application Programmer Interface \begin_inset CommandInset label LatexCommand label name "cha:The-TANGO-C++" \end_inset \end_layout \begin_layout Section Tango::DeviceProxy() \end_layout \begin_layout Standard The high level object which provides the client with an easy-to-use interface to TANGO devices. DeviceProxy is a handle to the real Device (hence the name Proxy) and is not the real Device (of course). DeviceProxy provides interfaces to all TANGO Device interfaces. The DeviceProxy manages timeouts, stateless connections (new DeviceProxy() nearly always works), and reconnection if the device server is restarted. \end_layout \begin_layout Subsection Constructors \end_layout \begin_layout Subsubsection DeviceProxy::DeviceProxy(string &name, CORBA::ORB *orb=NULL) \end_layout \begin_layout Standard Create a DeviceProxy to a device of the specified name. The TANGO_HOST environment variable is used to determine which TANGO database to connect to. The client can specify an ORB as argument if she wants to. The constructor will connect to the TANGO database, query for the client's network address and build a connection to the device. If the device is defined in the TANGO database but the device server is not running DeviceProxy will try to build a connection every time the client tries to access the device. If the device is not defined an exception is thrown. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DeviceProxy *my_device = new DeviceProxy( \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard See appendix on device naming for all details about Tango device naming syntax. If an alias \begin_inset Index idx status collapsed \begin_layout Plain Layout alias \end_layout \end_inset name is defined for the device, this alias name can be used to create the DeviceProxy instance. \end_layout \begin_layout Standard \emph on Exception: WrongNameSyntax, ConnectionFailed \end_layout \begin_layout Subsubsection DeviceProxy::DeviceProxy(const char *name, CORBA::ORB *orb = NULL) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsection Miscellaneous methods \end_layout \begin_layout Subsubsection DeviceInfo DeviceProxy::info() \end_layout \begin_layout Standard A method which returns information on the device in a DeviceInfo structure. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code cout << " device info : " << endl \end_layout \begin_layout LyX-Code DeviceInfo dev_info = my_device->info() << endl; \end_layout \begin_layout LyX-Code cout << " dev_class " << dev_info.dev_class; \end_layout \begin_layout LyX-Code cout << " server_id " << dev_info.server_id; \end_layout \begin_layout LyX-Code cout << " server_host " << dev_info.server_host; \end_layout \begin_layout LyX-Code cout << " server_version " << dev_info.server_version; \end_layout \begin_layout LyX-Code cout << " doc_url " << dev_info.doc_url; \end_layout \begin_layout LyX-Code cout << " device_type " << dev_info.dev_type; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard All DeviceInfo fields are strings except for the server_version server_version which is a long integer. \end_layout \begin_layout Standard \emph on Exception: Connection Failed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DevState DeviceProxy::state() \end_layout \begin_layout Standard A method which return the state of the device as a Tango::DevState type. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code dev_state = my_device->state() << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection string DeviceProxy::status() \end_layout \begin_layout Standard A method which return the status of the device as a string. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code cout << "device status " << my_device->status() << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection int DeviceProxy::ping() \end_layout \begin_layout Standard A method which sends a ping to the device and returns the time elapsed as microseconds. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code cout << " device ping took " << my_device->ping() << " microseconds" << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection void DeviceProxy::set_timeout_millis(int timeout) \end_layout \begin_layout Standard Set client side timeout for device in milliseconds. Any method which takes longer than this time to execute will throw an exception. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsubsection int DeviceProxy::get_timeout_millis() \end_layout \begin_layout Standard Get the client side timeout in milliseconds. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsubsection int DeviceProxy::get_idl_version() \end_layout \begin_layout Standard Get the version of the Tango Device IDL interface implemented by the device \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsubsection void DeviceProxy::set_source(DevSource source) \end_layout \begin_layout Standard Set the data source (device, polling buffer, polling buffer than device) for command_inout and read_attribute methods. The DevSource is an enumerated type which can be one of {DEV, CACHE, CACHE_DEV}. The default value is CACHE_DEV. See chapter on Advanced Feature for all details regarding polling. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsubsection DevSource DeviceProxy::get_source() \end_layout \begin_layout Standard Get the device data source used by command_inout or read_attribute methods. The DevSource is an enumerated type which can be one of {DEV, CACHE, CACHE_DEV}. See chapter on Advanced Feature for all details regarding polling. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsubsection vector *DeviceProxy::black_box(int n) \end_layout \begin_layout Standard Get the last n commands executed on the device server and return a pointer to a vector of strings containing the date, time, command, and from which client computer the command was executed. This method allocates memory for the vector of strings returned to the caller. It is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection string DeviceProxy::name() \end_layout \begin_layout Standard Return the device name (from the device itself) \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection string DeviceProxy::adm_name() \end_layout \begin_layout Standard Returns the name of the corresponding administrator device. This is useful if you need to send an administration command to the device server e.g. restart it. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection string DeviceProxy::dev_name() \end_layout \begin_layout Standard Return the device name as it is stored locally \end_layout \begin_layout Subsubsection string DeviceProxy::description() \end_layout \begin_layout Standard Returns the device description as a string. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout LyX-Code \end_layout \begin_layout Subsubsection DbDevImportInfo DeviceProxy::import_info() \end_layout \begin_layout Standard Query the device for import info from the database. This method returns a DbDevImprtInfo type. The DbDevImportInfo type is a struct defined as follows : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code class DbDevImportInfo { \end_layout \begin_layout LyX-Code public : \end_layout \begin_layout LyX-Code string name; \end_layout \begin_layout LyX-Code long exported; \end_layout \begin_layout LyX-Code string ior; \end_layout \begin_layout LyX-Code string version; }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: NonDbDevice \end_layout \begin_layout Subsubsection void DeviceProxy::set_transparency_reconnection(bool flag) \end_layout \begin_layout Standard If flag is true, no exception will be thrown in case of network communication error between client and server. The API will try to re-build the network connection between client and server as soon as an error is detected. See \begin_inset CommandInset ref LatexCommand ref reference "sec:Reconnection-and-exception" \end_inset more more details on reconnection and exception \end_layout \begin_layout Subsubsection bool DeviceProxy::get_transparency_reconnection() \end_layout \begin_layout Standard Returns the transparency reconnection flag. \end_layout \begin_layout Subsubsection string DeviceProxy::alias() \end_layout \begin_layout Standard Returns the device alias name if one is defined otherwise, throws a DevFailed exception with the reason field set to Db_AliasNotDefined. \end_layout \begin_layout Subsubsection AccessControlType DeviceProxy::get_access_right() \end_layout \begin_layout Standard Returns the device access right. AccessControlType is one enumeration with 2 values which are ACCESS_READ and ACCESS_WRITE. In case the Tango Access Control systemis not used, ACCESS_WRITE is returned. \end_layout \begin_layout Subsection Synchronous command oriented methods \end_layout \begin_layout Subsubsection CommandInfo DeviceProxy::command_query(string command) \end_layout \begin_layout Standard Query the device for information about a single command. This command returns a single CommandInfo type. The CommandInfo type is a struct described in command_list_query(). \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection CommandInfoList *DeviceProxy::command_list_query() \end_layout \begin_layout Standard Query the device for info on all commands. This method returns a vector of CommandInfo types. This method allocates memory for the vector of CommandInfo returned to the caller. It is the caller responsibility to delete this memory. The CommandInfo type is a struct defined as follows : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code typedef _CommandInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string cmd_name; /* command name as ascii string */ \end_layout \begin_layout LyX-Code long cmd_tag; /* command as binary value (for TACO) */ \end_layout \begin_layout LyX-Code long in_type; /* in type as binary value */ \end_layout \begin_layout LyX-Code long out_type; /* out type as binary value */ \end_layout \begin_layout LyX-Code string in_type_desc; /* description of in type (optional) */ \end_layout \begin_layout LyX-Code string out_type_desc; /* description of out type (optional) */ \end_layout \begin_layout LyX-Code Tango::DispLevel disp_level; /* Command display level */ \end_layout \begin_layout LyX-Code } CommandInfo; \end_layout \begin_layout LyX-Code typedef CommandInfoList vector; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DeviceData DeviceProxy::command_inout(string) \end_layout \begin_layout Standard Execute a command on a device which takes no input arguments (void). The result is returned in a DeviceData object (cf. below how to insert and extract data from DeviceData). \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection DeviceData DeviceProxy::command_inout(const char *) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection DeviceData Deviceproxy::command_inout(string, DeviceData &) \end_layout \begin_layout Standard Execute a command on a device. Input arguments are passed in a DeviceData object, output is returned as a DeviceData object (see below on how to insert and extract data from DeviceDat a). \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection DeviceData DeviceProxy::command_inout(const char *, DeviceData &) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection vector *command_history(string &, int) \end_layout \begin_layout Standard Retrieve command history from the command polling buffer. The first argument is the command name. The second argument is the wanted history depth. This method returns a vector of DeviceDataHistory types. This method allocates memory for the vector of DeviceDataHistory returned to the caller. It is the caller responsibility to delete this memory. Class DeviceDataHistory is detailed on chapter \begin_inset CommandInset ref LatexCommand ref reference "DataHistory" \end_inset . See chapter on Advanced Feature for all details regarding polling. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy dev = new DeviceProxy("..."); \end_layout \begin_layout LyX-Code vector *hist; \end_layout \begin_layout LyX-Code hist = dev->command_history("Status",5); \end_layout \begin_layout LyX-Code \noindent for (int i = 0;i < 5;i++) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code bool fail = (*hist)[i].failed(); \end_layout \begin_layout LyX-Code if (fail == false) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string str; \end_layout \begin_layout LyX-Code (*hist)[i] >> str; \end_layout \begin_layout LyX-Code cout << "Status = " << str << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Command failed !" << endl; \end_layout \begin_layout LyX-Code cout << "Error level 0 desc = " << ((*hist)[i].errors())[0].desc << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code cout << "Date = " << (*hist)[i].date().tv_sec << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code delete hist; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DeviceDataHistoryList *command_history(const char *, int) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsection Synchronous attribute related methods \end_layout \begin_layout Subsubsection Compatibility between Tango release 4 and release 5 regarding attribute properties \end_layout \begin_layout Standard Between Tango V4 and Tango V5, attribute configuration has been modified to incorporate alarm and event related parameters. This explains why it exists two structure types for attribute configuration parameters. All Tango V4 parameters are defined in a structure called \series bold AttributeInfo \begin_inset Index idx status collapsed \begin_layout Plain Layout AttributeInfo \end_layout \end_inset \series default and a new structure called \series bold AttributeInfoEx \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout AttributeInfoEx \end_layout \end_inset has been defined for all Tango V5 parameters. Nevertheless, AttributeInfoEx inherits from AttributeInfo and it is always possible to call the Tango V5 \emph on DeviceProxy::attribute_query() \emph default method and to store its result in one AttributeInfo structure thus allowing compatibility \begin_inset Index idx status collapsed \begin_layout Plain Layout compatibility \end_layout \end_inset for client written for Tango V4 but linked with Tango V5. It is also possible for a client written and linked with Tango V5 to call Tango V5 \emph on DeviceProxy::attribute_query() \emph default method to all kind of Tango devices. For device using Tango V4, the alarm and event related parameters will be retrieved from the database instead of from the device. \end_layout \begin_layout Subsubsection AttributeInfoEx DeviceProxy::attribute_query(string attribute) \end_layout \begin_layout Standard Query the device for information about a single attribute. This command returns a single AttributeInfoEx type which inherits from the AttributeInfo type. The AttributeInfoEx and AttributeInfo types are structures described in get_attribute_config() and get_attribute_config_ex(). \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection AttributeInfoList * DeviceProxy::attribute_list_query() \end_layout \begin_layout Standard Query the device for info on all attributes. This method returns a vector of AttributeInfo types. The AttributeInfo type is a structure described in get_attribute_config(). This method allocates memory for the vector of AttributeInfo structures returned to the caller. It is the caller responsibility to delete this memory. \end_layout \begin_layout Subsubsection AttributeInfoListEx * DeviceProxy::attribute_list_query_ex() \end_layout \begin_layout Standard Query the device for info on all attributes. This method returns a vector of AttributeInfoEx types. The AttributeInfoEx type is a structure described in get_attribute_config_ex(). This method allocates memory for the vector of AttributeInfoEx structures returned to the caller. It is the caller responsibility to delete this memory. \end_layout \begin_layout Subsubsection vector *DeviceProxy::get_attribute_list() \end_layout \begin_layout Standard Return the names of all attributes implemented for this device as a vector of strings. This method allocates memory for the vector of strings returned to the caller. It is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection AttributeInfoList *DeviceProxy::get_attribute_config(vector&) \end_layout \begin_layout Standard Return the attribute configuration for the list of specified attributes. To get all the attributes pass a vector containing the string AllAttr (defined in tango_const.h). This method allocates memory for the vector of AttributeInfo returned to the caller. It is the caller responsibility to delete this memory. AttributeInfo is a struct defined as follows : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code typedef struct _AttributeInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string name; \end_layout \begin_layout LyX-Code AttrWriteType writable; \end_layout \begin_layout LyX-Code AttrDataFormat data_format; \end_layout \begin_layout LyX-Code int data_type; \end_layout \begin_layout LyX-Code int max_dim_x; \end_layout \begin_layout LyX-Code int max_dim_y; \end_layout \begin_layout LyX-Code string description; \end_layout \begin_layout LyX-Code string label; \end_layout \begin_layout LyX-Code string unit; \end_layout \begin_layout LyX-Code string standard_unit; \end_layout \begin_layout LyX-Code string display_unit; \end_layout \begin_layout LyX-Code string format; \end_layout \begin_layout LyX-Code string min_value; \end_layout \begin_layout LyX-Code string max_value; \end_layout \begin_layout LyX-Code string min_alarm; \end_layout \begin_layout LyX-Code string max_alarm; \end_layout \begin_layout LyX-Code string writable_attr_name; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code Tango::DispLevel disp_level; \end_layout \begin_layout LyX-Code } AttributeInfo; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection AttributeInfoListEx *DeviceProxy::get_attribute_config_ex(vector&) \end_layout \begin_layout Standard Return the extended attribute configuration for the list of specified attributes. To get all the attributes pass a vector containing the string AllAttr (defined in tango_const.h). This method allocates memory for the vector of AttributeInfoEx returned to the caller. It is the caller responsibility to delete this memory. AttributeInfoEx is a structure defined as follows : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code struct AttributeInfoEx: public AttributeInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code AttributeAlarmInfo alarms; \end_layout \begin_layout LyX-Code AttributeEventInfo events; \end_layout \begin_layout LyX-Code vector sys_extensions; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code struct AttributeAlarmInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string min_alarm; \end_layout \begin_layout LyX-Code string max_alarm; \end_layout \begin_layout LyX-Code string min_warning; \end_layout \begin_layout LyX-Code string max_warning; \end_layout \begin_layout LyX-Code string delta_t; \end_layout \begin_layout LyX-Code string delta_val; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code struct AttributeEventInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code ChangeEventInfo ch_event; \end_layout \begin_layout LyX-Code PeriodicEventInfo per_event; \end_layout \begin_layout LyX-Code ArchiveEventInfo arch_event; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code struct ChangeEventInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string rel_change; \end_layout \begin_layout LyX-Code string abs_change; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code struct PeriodicEventInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string period; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code struct ArchiveEventInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string archive_rel_change; \end_layout \begin_layout LyX-Code string archive_abs_change; \end_layout \begin_layout LyX-Code string archive_period; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection AttributeInfoEx DeviceProxy::get_attribute_config(string&) \end_layout \begin_layout Standard Return the attribute configuration for a single attributes. The AttributeInfoEx is a structure defined above. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::set_attribute_config(AttributeInfoList &) \end_layout \begin_layout Standard Change the attribute configuration for the specified attributes. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::set_attribute_config(AttributeInfoListEx &) \end_layout \begin_layout Standard Change the attribute configuration for the specified attributes. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection vector *DeviceProxy::read_attributes(vector&) \end_layout \begin_layout Standard Read the list of specified attributes. To extract the value you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. By default, if the server reports error for one of the attribute in the list, this error will be passed to the user using exception when he (she) will try to extract the data form the corresponding See sub-chapter on DeviceAttribute to learn how to change this default behaviour. DeviceAttribute object. This method allocates memory for the vector of DeviceAttribute objects returned to the caller. This is the caller responsibility to delete this memory. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code vector *devattr; \end_layout \begin_layout LyX-Code vector attr_names; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code attr_names.push_back("attribute_1"); \end_layout \begin_layout LyX-Code attr_names.push_back("attribute_2"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code devattr = device->read_attributes(attr_names); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code short short_attr_1; \end_layout \begin_layout LyX-Code long long_attr_2; \end_layout \begin_layout LyX-Code (*devattr)[0] >> short_attr_1; \end_layout \begin_layout LyX-Code (*devattr)[1] >> long_attr_2; \end_layout \begin_layout LyX-Code cout << "my_attribute value " << short_attr; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code delete devattr; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection DeviceAttribute DeviceProxy::read_attribute(string&) \end_layout \begin_layout Standard Read a single attribute. To extract the value you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double (this will return 0) you have to extract it as a short. See example above. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection DeviceAttribute DeviceProxy::read_attribute(const char *) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::write_attributes(vector&) \end_layout \begin_layout Standard Write the specified attributes. To insert the values to write you have to use the operator of the DeviceAttribu te class which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. Note that this is the only API call which could throw a NamedDevFailedList exception. See \begin_inset CommandInset ref LatexCommand ref reference "sub:The-NamedDevFailedList-exception" \end_inset to get all the details on this exception. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code vector attr_in; \end_layout \begin_layout LyX-Code string att1_name("First_attr"); \end_layout \begin_layout LyX-Code string att2_name("Second_attr"); \end_layout \begin_layout LyX-Code short short_attr; \end_layout \begin_layout LyX-Code double double_attr; attr_in.push_back(DeviceAttribute(att1_name,short_attr)); \end_layout \begin_layout LyX-Code attr_in.push_back(DeviceAttribute(att2_name,double_attr)); \end_layout \begin_layout LyX-Code device->write_attributes(attr_in); \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed or NamedDevFailedList \begin_inset Index idx status collapsed \begin_layout Plain Layout NamedDevFailedList \end_layout \end_inset from device \end_layout \begin_layout Subsubsection void DeviceProxy::write_attribute(DeviceAttribute&) \end_layout \begin_layout Standard Write a single attribute. To insert the value to write you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. See example above. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection DeviceAttribute DeviceProxy::write_read_attribute(DeviceAttribute&) \end_layout \begin_layout Standard Write then read a single attribute in a single network call. By default (serialisation by device), the execution of this call in the server can't be interrupted by other clients. To insert/extract the value to write/read you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection vector *DeviceProxy::attribute_history(string &, int) \end_layout \begin_layout Standard Retrieve attribute history from the attribute polling buffer. The first argument is the attribute name. The second argument is the wanted history depth. This method returns a vector of DeviceAttributeHistory types. This method allocates memory for the vector of DeviceAttributeHistory returned to the caller. It is the caller responsibility to delete this memory. Class DeviceAttributeHistory is detailed on chapter \begin_inset CommandInset ref LatexCommand ref reference "AttributeHistory" \end_inset See also chapter on Advanced Feature for all details regarding polling. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy dev = new DeviceProxy("..."); \end_layout \begin_layout LyX-Code vector *hist; \end_layout \begin_layout LyX-Code hist = dev->attribute_history("Current",5); \end_layout \begin_layout LyX-Code \noindent for (int i = 0;i < 5;i++) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code bool fail = (*hist)[i].has_failed(); \end_layout \begin_layout LyX-Code if (fail == false) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Attribute name = " << (*hist)[i].get_name() << endl; \end_layout \begin_layout LyX-Code cout << "Attribute quality factor = " << (*hist)[i].get_quality() << endl; \end_layout \begin_layout LyX-Code long value; \end_layout \begin_layout LyX-Code (*hist)[i] >> value; \end_layout \begin_layout LyX-Code cout << "Current = " << value << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Attribute failed !" << endl; \end_layout \begin_layout LyX-Code cout << "Error level 0 desc = " << ((*hist)[i].get_err_stack())[0].desc << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code cout << "Date = " << (*hist)[i].get_date().tv_sec << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code delete hist; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection vector *DeviceProxy::attribute_history(const char *, int) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsection Asynchronous command oriented methods \end_layout \begin_layout Subsubsection long DeviceProxy::command_inout_asynch(string &name, bool forget) \end_layout \begin_layout Standard Execute asynchronously (polling model) a command on a device which takes no input argument. The last argument is a \emph on fire and forget \emph default flag. If this flag is set to true, this means that the client does not care at all about the server answer and will even not try to get it. A false default value is provided. Please, note that device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an application using only fire and forget requests is not able to automatically re-connnect to device. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the command result. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection long DeviceProxy::command_inout_asynch(const char *name, bool forget) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection long DeviceProxy::command_inout_asynch(string &name, DeviceData &argin, bool forget) \end_layout \begin_layout Standard Execute asynchronously (polling model) a command on a device. Input arguments are passed in a DeviceData object (see following chapters on how to insert data into DeviceData object). The last argument is a \emph on fire and forget \emph default flag. If this flag is set to true, this means that the client does not care at all about the server answer and will even not try to get it. A false default value is provided. Please, note that device re-connection will not take place (in case it is needed) if the fire and forget mode is used. Therefore, an application using only fire and forget requests is not able to automatically re-connnect to device. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the command result. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection long DeviceProxy::command_inout_asynch(const char *name, Devicedata &argin, bool forget) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection DeviceData DeviceProxy::command_inout_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code Tango::DeviceProxy dev("..."); \end_layout \begin_layout LyX-Code long asyn_id; \end_layout \begin_layout LyX-Code asyn_id = dev.command_inout_asynch("MyCmd"); \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code Tango::DeviceData arg; \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code arg = dev.command_inout_reply(asyn_id); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch(Tango::AsynReplyNotArrived) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cerr << "Command not arrived !" << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (Tango::DevFailed &e) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code Tango::Except::print_exception(e); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DeviceData DeviceProxy::command_inout_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous command_inout is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceData object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. \end_layout \begin_layout Standard \emph on Exception: AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::command_inout_asynch(string &name, CallBack &cb) \end_layout \begin_layout Standard Execute asynchronously (callback model) a command on a device which takes no input argument. The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on cmd_ended() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::command_inout_asynch(const char *name, CallBack &cb) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::command_inout_asynch(string &name, DeviceData &argin, CallBack &cb) \end_layout \begin_layout Standard Execute asynchronously (callback model) a command on a device. Input arguments are passed in a DeviceData object (see following chapters on how to insert data into DeviceData object). The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on cmd_ended() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::command_inout_asynch(const char *name, DeviceData &argin, Callback &cb) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout LyX-Code \end_layout \begin_layout Subsection Asynchronous attribute related methods \end_layout \begin_layout Subsubsection long DeviceProxy::read_attribute_asynch(string &name) \end_layout \begin_layout Standard Read asynchronously (polling model) a single attribute. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the attribute value. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection long DeviceProxy::read_attribute_asynch(const char *name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection long DeviceProxy::read_attributes_asynch(vector &names) \end_layout \begin_layout Standard Read asynchronously (polling model) the list of specified attributes. This call returns an \emph on asynchronous call identifier \emph default which is needed to get attributes value. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection DeviceAttribute *DeviceProxy::read_attribute_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous read_attribute is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DeviceAttribute *DeviceProxy::read_attribute_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous read_attribute is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection vector *DeviceProxy::read_attributes_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous read_attributes is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a vector. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the vector object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection vector *DeviceProxy::read_attributes_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous read_attributes is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a vector. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the vector object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection long DeviceProxy::write_attribute_asynch(DeviceAttribute &argin) \end_layout \begin_layout Standard Write asynchronously (polling model) a single attribute. To insert the value to write you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the server reply. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection long DeviceProxy::write_attributes_asynch(vector &argin) \end_layout \begin_layout Standard Write asynchronously (polling model) the specified attributes. To insert the value to write you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the server reply. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::write_attribute_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous write_attribute is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::write_attribute_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous write_attribute is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::write_attributes_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous write_attributes is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::write_attributes_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous write_attributes is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::read_attribute_asynch(string &name, CallBack &cb) \end_layout \begin_layout Standard Read asynchronously (callback model) a single attribute. The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_read() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::read_attribute_asynch(const char *name, CallBack &cb) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::read_attributes_asynch(vector &names, CallBack &cb) \end_layout \begin_layout Standard Read asynchronously (callback model) an attribute list. The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_read() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::write_attribute_asynch(DeviceAttribute &argin, CallBack &cb) \end_layout \begin_layout Standard Write asynchronously (callback model) a single attribute. The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_written() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void DeviceProxy::write_attributes_asynch(vector &argin, CallBack &cb) \end_layout \begin_layout Standard Write asynchronously (callback model) an attribute list. The last argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_written() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsection Miscellaneous asynchronous related methods \end_layout \begin_layout Subsubsection long DeviceProxy::pending_asynch_call(asyn_req_type req) \end_layout \begin_layout Standard Return number of device asynchronous pending requests. The input parameter is an enumeration with three values which are: \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 POLLING : Returns only device polling model asynchronous request number \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 CALLBACK : Returns only device callback model asynchronous request number \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 ALL_ASYNCH : Returns device asynchronous request number \end_layout \begin_layout Standard \emph on Exception: None \end_layout \begin_layout Subsubsection void DeviceProxy::get_asynch_replies() \end_layout \begin_layout Standard Fire callback methods for device asynchronous requests with already arrived replied. Returns immediately if there is no replies already arrived or if there is no asynchronous request for the device. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code class MyCallBack: Tango::CallBack \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code public: \end_layout \begin_layout LyX-Code MyCallback(double d):data(d) {}; \end_layout \begin_layout LyX-Code virtual void cmd_ended(Tango::CmdDoneEvent *); \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code private: \end_layout \begin_layout LyX-Code double data; \end_layout \begin_layout LyX-Code }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code void MyCallBack::cmd_ended(Tango CmdDoneEvent *cmd) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code if (cmd->err == true) \end_layout \begin_layout LyX-Code Tango::Except::print_error_stack(cmd->errors); \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code short cmd_result; \end_layout \begin_layout LyX-Code cmd->argout >> cmd_result; \end_layout \begin_layout LyX-Code cout << "Command result = " << cmd_result << endl; \end_layout \begin_layout LyX-Code cout << "Callback personal data = " << data << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code int main(int argc, char *argv[]) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code .... \end_layout \begin_layout LyX-Code .... \end_layout \begin_layout LyX-Code Tango::DeviceProxy dev("..."); \end_layout \begin_layout LyX-Code double my_data = ...; \end_layout \begin_layout LyX-Code MyCallBack cb(my_data); \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code dev.command_inout_asynch("MyCmd",cb); \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code dev.get_asynch_replies(); \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code ... \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: None, all errors are reported using the err and errors fields of the parameter passed to the callback method. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:Asynchronous-callback-related" \end_inset for details. \end_layout \begin_layout Subsubsection void DeviceProxy::get_asynch_replies(long timeout) \end_layout \begin_layout Standard Fire callback methods for device asynchronous requests (command and attributes) with already arrived replied. Wait and block the caller for timeout milliseconds if they are some device asynchronous requests which are not yet arrived. Returns immediately if there is no asynchronous request for the device. If timeout is set to 0, the call waits until all the asynchronous requests sent to the device has received a reply. \end_layout \begin_layout Standard \emph on Exception: AsynReplyNotArrived. All other errors are reported using the err and errors fields of the object passed to the callback methods. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:Asynchronous-callback-related" \end_inset for details. \end_layout \begin_layout Subsubsection void DeviceProxy::cancel_asynch_request(long id) \end_layout \begin_layout Standard Cancel a pending asynchronous request. id is the asynchronous call identifier. This is a call local to the client. It simply allows the caller not to get the answer of the asynchronous request. It does not interrupt the call execution on the remote device. \end_layout \begin_layout Standard \emph on Exception: AsynCall \end_layout \begin_layout Subsubsection void DeviceProxy::cancel_all_polling_asynch_request() \end_layout \begin_layout Standard Cancel all pending polling asynchronous requests. This is a call local to the client. It simply allows the caller not to get the answers of the asynchronous requests. It does not interrupt the call execution on the remote devices. \end_layout \begin_layout Subsection Polling related methods \end_layout \begin_layout Subsubsection bool DeviceProxy::is_command_polled(string &cmd_name) \end_layout \begin_layout Standard Returns true if the command "cmd_name" is polled. Otherwise, returns false. \end_layout \begin_layout Subsubsection bool DeviceProxy::is_command_polled(const char *cmd_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection bool DeviceProxy::is_attribute_polled(string &attr_name) \end_layout \begin_layout Standard Returns true if the attribute "attr_name" is polled. Otherwise, returns false. \end_layout \begin_layout Subsubsection bool Deviceproxy::is_attribute_polled(const char *attr_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection int DeviceProxy::get_command_poll_period(string &cmd_name) \end_layout \begin_layout Standard Returns the command "cmd_name" polling period in mS. If the command is not polled, it returns 0. \end_layout \begin_layout Subsubsection int DeviceProxy::get_command_poll_period(const char *cmd_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection int DeviceProxy::get_attribute_poll_period(string &attr_name) \end_layout \begin_layout Standard Returns the attribute "attr_name" polling period in mS. If the attribute is not polled, it returns 0. \end_layout \begin_layout Subsubsection int Deviceproxy::get_attribute_poll_period(const char *attr_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection vector *DeviceProxy::polling_status() \end_layout \begin_layout Standard Returns the device polling status. There is one string for each polled command/attribute. Each string is multi-line string with : \end_layout \begin_layout Itemize The attribute/command name \end_layout \begin_layout Itemize The attribute/command polling period (in mS) \end_layout \begin_layout Itemize The attribute/command polling ring buffer depth \end_layout \begin_layout Itemize The time needed for the last command/attribute execution (in mS) \end_layout \begin_layout Itemize The time since data in the ring buffer has not been updated \end_layout \begin_layout Itemize The delta time between the last records in the ring buffer \end_layout \begin_layout Itemize The exception parameters in case of the last command/attribute execution failed \end_layout \begin_layout Standard This method allocates memory for the vector of string(s) returned to the caller. It is the caller responsibility to delete this memory. \end_layout \begin_layout Subsubsection void DeviceProxy::poll_command(string &cmd_name,int period) \end_layout \begin_layout Standard Add the command "cmd_name" to the list of polled command. The polling period is specified by "period" (in mS). If the command is already polled, this method will update the polling period according to "period". \end_layout \begin_layout Subsubsection void DeviceProxy::poll_command(const char *cmd_name, int period) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::poll_attribute(string &attr_name, int period) \end_layout \begin_layout Standard Add the attribute "attr_name" to the list of polled attributes. The polling period is specified by "period" (in mS). If the attribute is already polled, this method will update the polling period according to "period". \end_layout \begin_layout Subsubsection void DeviceProxy::poll_attribute(const char *attr_name, int period) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::stop_poll_command(string &cmd_name) \end_layout \begin_layout Standard Remove command "cmd_name" from the list of polled command. \end_layout \begin_layout Subsubsection void DeviceProxy::stop_poll_command(const char *cmd_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::stop_poll_attribute(string &attr_name) \end_layout \begin_layout Standard Remove attribute "attr_name" from the list of polled attributes. \end_layout \begin_layout Subsubsection void DeviceProxy::stop_poll_attribute(const char *attr_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsection Event related methods \end_layout \begin_layout Subsubsection int DeviceProxy::subscribe_event(const string &attribute, EventType event, CallBack *cb) \end_layout \begin_layout Standard The client call to subscribe for event reception in the \series bold push model \series default . The client implements a callback method which is triggered when the event is received. Filtering is done based on the event type. For example when reading the state and the reason specified is "change" the event will be fired only when the state changes. Events consist of an attribute name and the event reason. A standard set of reasons are implemented by the system, additional device specific reasons can be implemented by device servers programmers. \end_layout \begin_layout Standard The \emph on attribute \emph default parameter is the device attribute name which will be sent as an event e.g. \begin_inset Quotes eld \end_inset current \begin_inset Quotes erd \end_inset , \emph on event \emph default parameter is the event reason and must be on the enumerated values: \end_layout \begin_layout Itemize Tango::CHANGE_EVENT \end_layout \begin_layout Itemize Tango::PERIODIC_EVENT \end_layout \begin_layout Itemize Tango::ARCHIVE_EVENT \end_layout \begin_layout Itemize Tango::ATTR_CONF_EVENT \end_layout \begin_layout Itemize Tango::DATA_READY_EVENT \end_layout \begin_layout Itemize Tango::USER_EVENT \end_layout \begin_layout Standard \emph on cb \emph default is a pointer to a class inheriting from the Tango CallBack class and implementi ng a \emph on push_event() \emph default method. \end_layout \begin_layout Standard The \emph on subscribe_event() \emph default call returns an event id which has to be specified when unsubscribing from this event. Please, note that the \emph on cb \emph default parameter is a pointer. The lifetime of the pointed to object must at least be equal to the time when events are requested because only the pointer is stored into the event machinery. The same thing is true for the DeviceProxy instance on which the \emph on subscribe_event() \emph default method is called. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a forth argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection int DeviceProxy::subscribe_event(const string &attribute, EventType event, CallBack *cb, bool stateless) \end_layout \begin_layout Standard This subscribe event method has the same functionality as described in the last section. It adds an additional flag called \emph on stateless. \emph default When the \emph on stateless \emph default flag is set to \emph on false \emph default , an exception will be thrown when the event subscription encounters a problem. \end_layout \begin_layout Standard With the \emph on stateless \emph default flag set to \emph on true \emph default , the event subscription will always succeed, even if the corresponding device server is not running. The keep alive thread will try every 10 seconds to subscribe for the specified event. At every subscription retry, a callback is executed which contains the corresponding exception. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a fifth argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering and it was the forth argument in the argument list. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection int DeviceProxy::subscribe_event(const string &attribute, EventType event, int event_queue_size, bool stateless) \end_layout \begin_layout Standard The client call to subscribe for event reception in the \series bold pull model \series default . Instead of a callback method the client has to specify the size of the event reception buffer. \end_layout \begin_layout Standard The event reception buffer is implemented as a round robin buffer. This way the client can set-up different ways to receive events. \end_layout \begin_layout Itemize Event reception buffer size = 1 : The client is interested only in the value of the last event received. All other events that have been received since the last reading are discarded. \end_layout \begin_layout Itemize Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When more events arrive since the last reading, older events will be discarded. \end_layout \begin_layout Itemize Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size is unlimited and only restricted by the available memory for the client. \end_layout \begin_layout Standard All other parameters are similar to the descriptions given in the last two sections. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a fifth argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering and it was the forth argument in the argument list. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection void DeviceProxy::unsubscribe_event(int event_id) \end_layout \begin_layout Standard Unsubscribe a client from receiving the event specified by \emph on event_id \emph default . \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection void DeviceProxy::get_events(int event_id, CallBack *cb) \end_layout \begin_layout Standard The method extracts all waiting events from the event reception buffer and executes the callback method \emph on cb \emph default for every event. During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection void DeviceProxy::get_events(int event_id, EventDataList &event_list) \end_layout \begin_layout Standard The method extracts all waiting events from the event reception buffer. The returned \emph on event_list \emph default is a vector of EventData pointers. The EventData object contains the event information as for the callback methods. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection void DeviceProxy::get_events(int event_id, AttrConfEventDataList &event_list) \end_layout \begin_layout Standard The method extracts all waiting attribute configuration events from the event reception buffer. The returned \emph on event_list \emph default is a vector of AttrConfEventData pointers. The AttrConfEventData object contains the event information as for the callback methods. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection void DeviceProxy::get_events(int event_id, DataReadyEventDataList &event_list) \begin_inset Index idx status collapsed \begin_layout Plain Layout DataReadyEventDataList \end_layout \end_inset \end_layout \begin_layout Standard The method extracts all waiting attribute configuration events from the event reception buffer. The returned \emph on event_list \emph default is a vector of DataReadyEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout DataReadyEventData \end_layout \end_inset pointers. The DataReadyEventData object contains the event information as for the callback methods. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection int DeviceProxy::event_queue_size(int event_id) \end_layout \begin_layout Standard Returns the number of stored events in the event reception buffer. After every call to \emph on DeviceProxy:get_events() \emph default , the event queue size is 0. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection TimeVal DeviceProxy::get_last_event_date(int event_id) \end_layout \begin_layout Standard Returns the arrival time of the last event stored in the event reception buffer. After every call to \emph on DeviceProxy:get_events() \emph default , the event reception buffer is empty. In this case an exception will be returned. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection bool DeviceProxy::is_event_queue_empty(int event_id) \end_layout \begin_layout Standard Returns true when the event reception buffer is empty. \end_layout \begin_layout Standard During event subscription the client must have chosen the \series bold pull model \series default for this event. \emph on event_id \emph default is the event identifier returned by the \emph on DeviceProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsection Property related methods \end_layout \begin_layout Subsubsection void DeviceProxy::get_property (string&, DbData&) \end_layout \begin_layout Standard Get a single property for a device. The property to get is specified as a string. Refer to DbDevice::get_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::get_property (vector&, DbData&) \end_layout \begin_layout Standard Get a list of properties for a device. The properties to get are specified as a vector of strings. Refer to DbDevice::get_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::get_property(DbData&) \end_layout \begin_layout Standard Get property(ies) for a device. Properties to get are specified using the DbData type. Refer to DbDevice::get_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::put_property(DbData&) \end_layout \begin_layout Standard Put property(ies) for a device. Properties to put are specified using the DbData type. Refer to DbDevice::put_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::delete_property (string&) \end_layout \begin_layout Standard Delete a single property for a device. The property to delete is specified as a string. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::delete_property (vector&) \end_layout \begin_layout Standard Delete a list of properties for a device. The properties to delete are specified as a vector of strings. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::delete_property(DbData&) \end_layout \begin_layout Standard Delete property(ies) for a device. Properties to delete are specified using the DbData type. Refer to DbDevice::get_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void DeviceProxy::get_property_list(const string &filter,vector &prop_list) \end_layout \begin_layout Standard Get the list of property names for the device. The parameter \emph on filter \emph default allows the user to filter the returned name list. The wildcard character is '*'. Only one wildcard character is allowed in the filter parameter. The name list is returned in the vector of strings passed as the method second argument. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, WrongNameSyntax, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsection Logging related methods \end_layout \begin_layout Subsubsection void DeviceProxy::add_logging_target(const string &target_type_target_name) \end_layout \begin_layout Standard Adds a new logging target to the device. The target_type_target_name input parameter must follow the format: target_type ::target_name. Supported target types are: \emph on console \emph default , \emph on file \emph default and \emph on device \emph default . For a device target, the target_name part of the target_type_target_name parameter must contain the name of a log consumer device (as defined in \begin_inset CommandInset ref LatexCommand ref reference "sec:Tango-log-consumer" \end_inset ). For a file target, target_name is the full path to the file to log to. If omitted, the device's name is used to build the file name (which is something like domain_family_member.log). Finally, the target_name part of the target_type_target_name input parameter is ignored in case of a console target and can be omitted. \end_layout \begin_layout Standard \emph on Exception: DevFailed from device \end_layout \begin_layout Subsubsection void DeviceProxy::add_logging_target (const char *target_type_target_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection void DeviceProxy::remove_logging_target(const string &target_type_target_name) \end_layout \begin_layout Standard Removes a logging target from the device's target list. The target_type_target_name input parameter must follow the format: target_type ::target_name. Supported target types are: \emph on console \emph default , \emph on file \emph default and \emph on device \emph default . For a device target, the target_name part of the target_type_target_name parameter must contain the name of a log consumer device (as defined in ). For a file target, target_name is the full path to the file to remove. If omitted, the default log file is removed. Finally, the target_name part of the target_type_target_name input parameter is ignored in case of a console target and can be omitted. \end_layout \begin_layout Standard If target_name is set to "*", all targets of the specified target_type are removed. \end_layout \begin_layout Subsubsection void DeviceProxy::remove_logging_target (const char *target_type_target_name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsubsection vector DeviceProxy::get_logging_target () \end_layout \begin_layout Standard Returns a vector of string containing the current device's logging targets. Each vector element has the following format: target_type::target_name. An empty vector is returned is the device has no logging targets. \end_layout \begin_layout Subsubsection int DeviceProxy::get_logging_level () \end_layout \begin_layout Standard Returns the current device's logging level (0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG). \end_layout \begin_layout Subsubsection void DeviceProxy::set_logging_level (int level) \end_layout \begin_layout Standard Changes the device's logging level. (0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG). \end_layout \begin_layout Subsection Locking \begin_inset Index idx status collapsed \begin_layout Plain Layout Locking \end_layout \end_inset related methods \end_layout \begin_layout Subsubsection void DeviceProxy::lock \begin_inset Index idx status collapsed \begin_layout Plain Layout lock \end_layout \end_inset (int lock_validity = 10) \end_layout \begin_layout Standard Lock a device. The lock_validity is the time (in seconds) the lock is kept valid after the previous lock call. A default value of 10 seconds is provided and should be fine in most cases. In case it is necessary to change the lock validity, it's not possible to ask for a validity less than a minimum value set to 2 seconds. The library provided an automatic system to periodically re lock the device until an unlock call. No code is needed to start/stop this automatic re-locking system. The locking system is re-entrant. It is then allowed to call this method on a device already locked by the same process. The locking system has the following features: \end_layout \begin_layout Itemize It is impossible to lock the database device or any device server process admin device \end_layout \begin_layout Itemize Destroying a locked DeviceProxy unlocks the device \end_layout \begin_layout Itemize Restarting a locked device keeps the lock \end_layout \begin_layout Itemize It is impossible to restart a device locked by someone else \end_layout \begin_layout Itemize Restarting a server breaks the lock \end_layout \begin_layout Standard A locked device is protected against the following calls when executed by another client: \end_layout \begin_layout Itemize \emph on command_inout \emph default call except for device state and status requested via command and for the set of commands defined as allowed following the definition of allowed command in the Tango control access schema. \end_layout \begin_layout Itemize \emph on write_attribute \emph default call \end_layout \begin_layout Itemize \emph on write_read_attribute \emph default call \end_layout \begin_layout Itemize \emph on set_attribute_config \emph default call \end_layout \begin_layout Subsubsection void DeviceProxy::unlock \begin_inset Index idx status collapsed \begin_layout Plain Layout unlock \end_layout \end_inset (bool force = false) \end_layout \begin_layout Standard Unlock a device. If used, the method argument provides a back door on the locking system. If this argument is set to true, the device will be unlocked even if the caller is not the locker. This feature is provided for administration purpopse and should be used very carefully. If this feature is used, the locker will receive a \emph on DeviceUnlocked \emph default during the next call which is normally protected by the locking Tango system. \end_layout \begin_layout Subsubsection string DeviceProxy::locking_status \begin_inset Index idx status collapsed \begin_layout Plain Layout locking-status \end_layout \end_inset () \end_layout \begin_layout Standard This method returns a plain string describing the device locking status. This string can be: \end_layout \begin_layout Itemize "Device is not locked" in case the device is not locked \end_layout \begin_layout Itemize "Device is locked by CPP or Python client with PID from host " in case the device is locked by a CPP client \end_layout \begin_layout Itemize "Device is locked by JAVA client class

from host " in case the device is locked by a JAVA client \end_layout \begin_layout Subsubsection bool DeviceProxy::is_locked \begin_inset Index idx status collapsed \begin_layout Plain Layout is-locked \end_layout \end_inset () \end_layout \begin_layout Standard Returns true if the device is locked. Otherwise, returns false. \end_layout \begin_layout Subsubsection bool DeviceProxy::is_locked_by_me \begin_inset Index idx status collapsed \begin_layout Plain Layout is-locked-by-me \end_layout \end_inset () \end_layout \begin_layout Standard Returns true if the device is locked by the caller. Otherwise, returns false (device not locked or locked by someone else) \end_layout \begin_layout Subsubsection bool DeviceProxy::get_locker \begin_inset Index idx status collapsed \begin_layout Plain Layout get-locker \end_layout \end_inset (LockerInfo &li) \end_layout \begin_layout Standard If the device is locked, this method returns true an set some locker process informations in the structure passed as argument. If the device is not locked, the method returns false. The LockerInfo structure definition is \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code typedef union \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code pid_t LockerPid; \end_layout \begin_layout LyX-Code unsigned long UUID[4]; \end_layout \begin_layout LyX-Code }LockerId; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code enum LockerLanguage \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code CPP, \end_layout \begin_layout LyX-Code JAVA \end_layout \begin_layout LyX-Code }; \begin_inset Newline newline \end_inset \begin_inset Newline newline \end_inset \end_layout \begin_layout LyX-Code struct LockerInfo \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code LockerLanguage ll; \end_layout \begin_layout LyX-Code LockerId li; \end_layout \begin_layout LyX-Code string locker_host; \end_layout \begin_layout LyX-Code string locker_class; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The structure \emph on ll \emph default field is set to either CPP or JAVA depending on the locker process language. In case of CPP client, the \emph on li \emph default union is set to the locker process pid ( \emph on LockerPid \emph default field). In case of Java client, it is set to the Java client UUID (Universal Uniq IDentifier) in the \emph on UUID \emph default field. The \emph on locker_host \emph default field is initialised with the host name where the locker process is running (or its IP adress as a string if it is not possiblr to get the name associated with this address). The \emph on locker_class \emph default field is set to the Java virtual machine main class name when the locker client process is written in Java. For CPP client, it is set to the string "Not defined". \end_layout \begin_layout Section \noindent Tango::DeviceData \end_layout \begin_layout Standard \noindent This is the fundamental type for sending and receiving data from device commands. The values can be inserted and extracted using the operators << and >> respectively and insert() for mixed data types. A status flag indicates if there is data in the DbDatum object or not. An additional flag allows the user to activate exceptions. \end_layout \begin_layout Subsection \noindent Constructors, assignement operators and C++11 \end_layout \begin_layout Standard This class has a default constructor ( \emph on DeviceData() \emph default ), a copy constructor ( \emph on DeviceData(const DeviceData &) \emph default ) and one assignement operator ( \emph on DeviceData & operator=(const DeviceData &) \emph default ). Nevertheless, the assignement operator and the copy constructor does not really copy the data included in the instance. For efficiency reasons, they rather move the data from one instance to another. Starting with Tango 8 and if Tango is compiled with gcc release 4.3 or above (or Windows VC 10 and above), some move semantics from C++11 \begin_inset Index idx status collapsed \begin_layout Plain Layout C++11 \end_layout \end_inset has been added. This means that: \end_layout \begin_layout Itemize A move constructor ( \emph on DeviceData(DeviceData &&) \emph default ) has been added. \end_layout \begin_layout Itemize A move assignement operator ( \emph on DeviceData & operator=(DeviceData &&) \emph default ) has been added. \end_layout \begin_layout Itemize The classical copy constructor and assignement operator really copy the data. \end_layout \begin_layout Subsection \noindent Operators \end_layout \begin_layout Standard \noindent The insert and extract operators are specified for the following C++ types : \end_layout \begin_layout Enumerate \noindent bool \end_layout \begin_layout Enumerate \noindent short \end_layout \begin_layout Enumerate \noindent unsigned short \end_layout \begin_layout Enumerate \noindent DevLong \end_layout \begin_layout Enumerate \noindent DevULong \end_layout \begin_layout Enumerate \noindent DevLong64 \end_layout \begin_layout Enumerate DevULong64 \end_layout \begin_layout Enumerate \noindent float \end_layout \begin_layout Enumerate \noindent double \end_layout \begin_layout Enumerate \noindent string \end_layout \begin_layout Enumerate \noindent char* (insert only) \end_layout \begin_layout Enumerate \noindent const char * \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Standard Operators exist for inserting and extracting the native TANGO CORBA sequence types. These can be useful for programmers who want to use the TANGO api internally in their device servers and do not want to convert from CORBA to C++ types. Insert and extract operators exist for the following types : \end_layout \begin_layout Enumerate DevVarUCharArray * (const DevVarUCharArray * for extraction) \end_layout \begin_layout Enumerate DevVarShortArray * (const DevVarShortArray * for extraction) \end_layout \begin_layout Enumerate DevVarUShortArray * (const DevVarUShortArray * for extraction) \end_layout \begin_layout Enumerate DevVarLongArray * (const DevVarLongArray * for extraction) \end_layout \begin_layout Enumerate DevVarULongArray * (const DevVarULongArray * for extraction) \end_layout \begin_layout Enumerate DevVarLong64Array * (const DevVarLong64Array * for extraction) \end_layout \begin_layout Enumerate DevVarULong64Array * (const DevVarULong64Array * for extraction) \end_layout \begin_layout Enumerate DevVarFloatArray * (const DevVarFloatArray * for extraction) \end_layout \begin_layout Enumerate DevVarDoubleArray * (const DevVarDoubleArray * for extraction) \end_layout \begin_layout Enumerate DevVarStringArray * (const DevVarStringArray * for extraction) \end_layout \begin_layout Enumerate DevVarLongStringArray * (const DevVarLongStringArray * for extraction) \end_layout \begin_layout Enumerate DevVarDoubleStringArray * (const DevVarDoubleStringArray * for extraction) \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \series bold Note : \begin_inset Newline newline \end_inset Insertion by pointers takes full ownership of the pointed to memory. The insertion copy the data in the DeviceData object and delete the pointed to memory. Therefore, the memory is not more usable after the insertion. Also note that when using extraction by pointers, the pointed to memory is inside the DeviceData object and its lifetime is the same than the DeviceDat a object lifetime. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Operators also exist for inserting TANGO CORBA sequence type by reference. The insertion copy the data into the DeviceData object. Insert operator exist for the following types : \end_layout \begin_layout Enumerate DevVarUCharArray & \end_layout \begin_layout Enumerate DevVarShortArray & \end_layout \begin_layout Enumerate DevVarUShortArray & \end_layout \begin_layout Enumerate DevVarLongArray & \end_layout \begin_layout Enumerate DevVarULongArray & \end_layout \begin_layout Enumerate DevVarLong64Array & \end_layout \begin_layout Enumerate DevVarULong64Array & \end_layout \begin_layout Enumerate DevVarFloatArray & \end_layout \begin_layout Enumerate DevVarDoubleArray & \end_layout \begin_layout Enumerate DevVarStringArray & \end_layout \begin_layout Enumerate DevVarLongStringArray & \end_layout \begin_layout Enumerate DevVarDoubleStringArray & \end_layout \begin_layout Standard Additional methods exist for inserting a mixture of strings and long (Tango::Dev VarLongStringArray) and string and doubles (Tango::DevVarDoubleStringArray). These are : \end_layout \begin_layout Enumerate insert(vector&, vector&) \end_layout \begin_layout Enumerate insert(vector&, vector&) \end_layout \begin_layout Enumerate extract(vector&, vector&) \end_layout \begin_layout Enumerate extract(vector&, vector&) \end_layout \begin_layout Standard \noindent All the extraction methods returns a boolean set to false if the extraction has failed (empty DeviceData, wrong data type...) \end_layout \begin_layout Standard \noindent Special care has been taken to avoid memory copy between the network layer and the user application. Nevertheless, C++ vector types are not the CORBA native type and one copy is unavoidable when using vectors. Using the native TANGO CORBA sequence types avoid any copy. When using these TANGO CORBA sequence types, insertion into the DeviceData object consumes the memory pointed to by the pointer. After the insertion, it is not necessary to delete the memory. It will be done by the destruction of the DeviceData object. For extraction, the pointer used for the extraction points into memory inside the DeviceData object and you should not delete it \end_layout \begin_layout Standard \noindent Here is an example of creating, inserting and extracting some data type from/into DeviceData object : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceData my_short, my_long, my_string; \end_layout \begin_layout LyX-Code \noindent DeviceData my_float_vector, my_double_vector; \end_layout \begin_layout LyX-Code \noindent string a_string; \end_layout \begin_layout LyX-Code \noindent short a_short; \end_layout \begin_layout LyX-Code \noindent DevLong a_long; \end_layout \begin_layout LyX-Code \noindent vector a_float_vector; \end_layout \begin_layout LyX-Code \noindent vector a_double_vector; \end_layout \begin_layout LyX-Code \noindent my_short << 100; // insert a short \end_layout \begin_layout LyX-Code \noindent my_short >> a_short; // extract a short \end_layout \begin_layout LyX-Code \noindent my_long << 1000; // insert a long \end_layout \begin_layout LyX-Code \noindent my_long >> a_long; // extract a long \end_layout \begin_layout LyX-Code \noindent my_string << string( \begin_inset Quotes eld \end_inset estas lista a bailar el tango ? \begin_inset Quotes erd \end_inset ); // insert a string \end_layout \begin_layout LyX-Code \noindent my_string >> a_string; // extract a string \end_layout \begin_layout LyX-Code \noindent my_float_vector << a_float_vector // insert a vector of floats \end_layout \begin_layout LyX-Code \noindent my_float_vector >> a_float_vector; // extract a vector of floats \end_layout \begin_layout LyX-Code \noindent my_double_vector << a_double_vector; // insert a vector of doubles \end_layout \begin_layout LyX-Code \noindent my_double_vector >> a_double_vector; // extract a vector of doubles \begin_inset Newline newline \end_inset // \end_layout \begin_layout LyX-Code // Example of memory management with TANGO sequence types without memory leaks \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code for (int i = 0;i < 10;i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceData din,dout; \end_layout \begin_layout LyX-Code DevVarLongArray *in = new DevVarLongArray(); \end_layout \begin_layout LyX-Code in->length(2); \end_layout \begin_layout LyX-Code (*in)[0] = 2; \end_layout \begin_layout LyX-Code (*in)[1] = 4; \end_layout \begin_layout LyX-Code din << in; \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code dout = device->command_inout( \begin_inset Quotes eld \end_inset Cmd \begin_inset Quotes erd \end_inset ,din); \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch(DevFailed &e) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code .... \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code const DevVarLongArray *out; \end_layout \begin_layout LyX-Code dout >> out; \end_layout \begin_layout LyX-Code cout << \begin_inset Quotes eld \end_inset Received value = \begin_inset Quotes eld \end_inset << (*out)[0]; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection \noindent bool DeviceData::is_empty() \end_layout \begin_layout Standard \noindent is_empty() is a boolean method which returns true or false depending on whether the DeviceData object contains data or not. It can be used to test whether the DeviceData has been initialized or not e.g. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent string string_read; \end_layout \begin_layout LyX-Code \noindent DeviceData sl_read = my_device->command_inout( \begin_inset Quotes eld \end_inset ReadLine \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \noindent if (! sl_read.is_empty()) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent sl_read >> string_read; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code \noindent else \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent cout << \begin_inset Quotes eld \end_inset no data read from serial line ! \begin_inset Quotes erd \end_inset << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection int DeviceData::get_type() \end_layout \begin_layout Standard \noindent This method returns the Tango data type of the data inside the DeviceData object \end_layout \begin_layout Subsection \noindent void DeviceData::exceptions(bitset ) \end_layout \begin_layout Standard \noindent Is a method which allows the user to switch on/off exception throwing when trying to extract data from an empty DeviceData object or using a wrong data type. The default is to not throw exception. The following flags are supported : \end_layout \begin_layout Enumerate \noindent \series bold isempty_flag \series default - throw a WrongData exception (reason = API_EmptyDeviceData) if user tries to extract data from an empty DeviceData object \end_layout \begin_layout Enumerate \series bold wrongtype_flag \series default - throw a WrongData exception (reason = API_IncompatibleCmdArgumentType) if user tries to extract data with a type different than the type used for insertion \end_layout \begin_layout Subsection bitset exceptions() \end_layout \begin_layout Standard Returns the whole exception flags. \end_layout \begin_layout Subsection void DeviceData::reset_exceptions(DeviceData::except_flags fl) \end_layout \begin_layout Standard Resets one exception flag \end_layout \begin_layout Subsection void DeviceData::set_exceptions(DeviceData::except_flags fl) \end_layout \begin_layout Standard Sets one exception flag \end_layout \begin_layout Standard The following is an example of how to use these exceptions related methods \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent 1 DeviceData da; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 bitset bs = da.exceptions(); \end_layout \begin_layout LyX-Code 4 cout << "bs = " << bs << endl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 da.set_exceptions(DeviceData::wrongtype_flag); \end_layout \begin_layout LyX-Code 7 bs = da.exceptions(); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 cout << "bs = " << bs << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsection ostream &operator<<(ostream &, DeviceData &) \end_layout \begin_layout Standard Is an utility function to easily print the contents of a DeviceData object. This function knows all types which could be inserted in a DeviceData object and print them accordingly. A special string is printed if the DeviceData object is empty \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy *dev = new DeviceProxy( \begin_inset Quotes eld \end_inset ... \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code DeviceData out; \end_layout \begin_layout LyX-Code out = dev->command_inout( \begin_inset Quotes eld \end_inset MyCommand \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code cout << \begin_inset Quotes eld \end_inset Command returned: \begin_inset Quotes erd \end_inset << out << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Tango::DeviceDataHistory \begin_inset CommandInset label LatexCommand label name "DataHistory" \end_inset \end_layout \begin_layout Standard This is the fundamental type for receiving data from device command polling buffers. This class inherits from the Tango::DeviceData class. One instance of this class is created for each command result history. Within this class, you find the command result data or the exception parameters , a flag indicating if the command has failed when it was invoked by the device server polling thread and the date when the command was executed. For history calls, it is not possible to returns command error as exception. See chapter on Advanced Features for all details regarding device polling. On top of the methods inherited from the DeviceData class, it offers the following methods \end_layout \begin_layout Subsection bool DeviceDataHistory::has_failed() \end_layout \begin_layout Standard Returns true if the corresponding command has failed when it was executed by the device server polling thread. Otherwise returns false (amazing!) \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsection TimeVal &DeviceDataHistory::get_date() \end_layout \begin_layout Standard Returns the date when the device server polling thread has executed the command. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsection const DevErrorList &DeviceDataHistory::get_err_stack() \end_layout \begin_layout Standard Return the error stack recorded by the device server polling thread in case of the command failed when it was invoked. \end_layout \begin_layout Standard \emph on Exception: none \end_layout \begin_layout Subsection ostream &operator<<(ostream &, DeviceDataHistory &) \end_layout \begin_layout Standard Is an utility function to easily print the contents of a DeviceDataHistory object. This function knows all types which could be inserted in a DeviceDataHistory object and print them accordingly. It also prints date and error stack in case the command returned an error. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy *dev = new DeviceProxy( \begin_inset Quotes eld \end_inset ... \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code int hist_depth = 4; \end_layout \begin_layout LyX-Code vector *hist; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code hist = dev->command_history( \begin_inset Quotes eld \end_inset MyCommand \begin_inset Quotes erd \end_inset ,hist_depth); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code for (int i = 0;i < hist_depth;i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << (*hist)[i] << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code delete hist; \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section \noindent Tango::DeviceAttribute \end_layout \begin_layout Standard \noindent This is the fundamental type for sending and receiving data to and from device attributes. The values can be inserted and extracted using the operators << and >> respectively and insert() for mixed data types. There are two ways to check if the extraction operator succeed : \end_layout \begin_layout Enumerate By testing the extractor operators return value. All the extractors operator returns a boolean value set to false in case of problem. \end_layout \begin_layout Enumerate By asking the DeviceAttribute object to throw exception in case of problem. By default, DeviceAttribute throws exception : \end_layout \begin_deeper \begin_layout Enumerate when the user try to extract data and the server reported an error when the attribute was read. \end_layout \begin_layout Enumerate When the user try to extract data from an empty DeviceAttribute \end_layout \end_deeper \begin_layout Subsection Constructors, assignement operators \end_layout \begin_layout Standard Many constructors have been written for this class. The following constructors exist : \end_layout \begin_layout Enumerate The C++ basic constructors \end_layout \begin_deeper \begin_layout Enumerate DeviceAttribute(); \end_layout \begin_layout Enumerate DeviceAttribute(const DeviceAttribute&) \series bold ; \end_layout \end_deeper \begin_layout Enumerate Constructors for scalar type with name as C++ string or "const char *" \end_layout \begin_deeper \begin_layout Enumerate DeviceAttribute(string &, bool); \end_layout \begin_layout Enumerate DeviceAttribute(string &, short) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevLong); \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevLong64); \end_layout \begin_layout Enumerate DeviceAttribute(string &, float); \end_layout \begin_layout Enumerate DeviceAttribute(string &, double); \end_layout \begin_layout Enumerate DeviceAttribute(string &, unsigned char); \end_layout \begin_layout Enumerate DeviceAttribute(string &, unsigned short); \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevULong); \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevULong64); \end_layout \begin_layout Enumerate DeviceAttribute(string &, string &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevState); \end_layout \begin_layout Enumerate DeviceAttribute(string &, DevEncoded &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, bool); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, short) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, DevLong); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, DevLong64); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, float) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, double); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, unsigned char) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, unsigned short); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, DevULong); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, DevULong64); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, string &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, DevState); \end_layout \begin_layout Enumerate DeviceAttribute(const char *,DevEncoded &); \end_layout \end_deeper \begin_layout Enumerate Constructors for C++ vector types (for spectrum attribute) with name as C++ string or "const char *" \end_layout \begin_deeper \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector \series bold < \series default short \series bold > \series default &) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector & ); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector & ); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &); \end_layout \end_deeper \begin_layout Enumerate Constructors for C++ vector types (for image attribute) with name as C++ string or "const char *". These constructors have two more parameters allowing the user to define the x and y image dimensions. \end_layout \begin_deeper \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int \series bold ) \series default ; \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int ); \end_layout \begin_layout Enumerate DeviceAttribute(string &, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int) \series bold ; \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector &, int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector & , int, int); \end_layout \begin_layout Enumerate DeviceAttribute(const char *, vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \end_deeper \begin_layout Enumerate Insert methods for the DevEncoded \begin_inset Index idx status collapsed \begin_layout Plain Layout DevEncoded \end_layout \end_inset data type \end_layout \begin_deeper \begin_layout Enumerate insert(char *&, unsigned char *&, unsigned int) \begin_inset Newline newline \end_inset The last argument is the size of the buffer passed to the method as its second argument \end_layout \begin_layout Enumerate insert(string &, vector) \end_layout \end_deeper \begin_layout Enumerate Insert methods for the following C++ vector types for image attributes allowing the specification of the x and y image dimensions : \end_layout \begin_deeper \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate \noindent insert(vector &,int, int) \end_layout \begin_layout Enumerate insert(vector &,int, int) \end_layout \end_deeper \begin_layout Standard Extractor operators are specified for the following C++ basic types \end_layout \begin_layout Enumerate Extract operators for the following scalar C++ types : \end_layout \begin_deeper \begin_layout Enumerate \noindent bool \end_layout \begin_layout Enumerate \noindent short \end_layout \begin_layout Enumerate \noindent DevLong \end_layout \begin_layout Enumerate DevLong64 \end_layout \begin_layout Enumerate \noindent float \end_layout \begin_layout Enumerate \noindent double \end_layout \begin_layout Enumerate \noindent unsigned char \end_layout \begin_layout Enumerate \noindent unsigned short \end_layout \begin_layout Enumerate \noindent DevULong \end_layout \begin_layout Enumerate DevULong64 \end_layout \begin_layout Enumerate \noindent string \end_layout \begin_layout Enumerate Tango::DevState \end_layout \begin_layout Enumerate Tango::DevEncoded \end_layout \end_deeper \begin_layout Enumerate Extract operators for the following C++ vector types for spectrum and image attributes : \end_layout \begin_deeper \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \end_deeper \begin_layout Enumerate Extract methods to extract only the read value of an attribute into a C++ vector. The dimension of the read value can be read by using the methods get_dim_x() and get_dim_y() or get_r_dimension(). The methods use the same return values as the extraction operators with exceptions triggered by the exception flags: \end_layout \begin_deeper \begin_layout Enumerate bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_read (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_read(string &, vector &); \end_layout \end_deeper \begin_layout Enumerate Extract methods to extract only the set value of an attribute into a C++ vector. The dimension of the set value can be read by using the methods get_written_dim _x() and get_written_dim_y() or get_w_dimension(). The methods use the same return values as the extraction operators with exceptions triggered by the exception flags: \end_layout \begin_deeper \begin_layout Enumerate bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate \noindent bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_set (vector&); \end_layout \begin_layout Enumerate bool DeviceAttribute::extract_set(string &, vector &); \end_layout \end_deeper \begin_layout Enumerate Special extract method for the Tango::DevEncoded data type \end_layout \begin_deeper \begin_layout Enumerate bool DeviceAttribute::extract(const char *&, unsigned char *&, unsigned int &); \begin_inset Newline newline \end_inset The last argument is the size of the buffer passed to the method as its second argument \end_layout \begin_layout Enumerate bool DeviceAttribute::extract(string &, vector &); \end_layout \end_deeper \begin_layout Standard \noindent Operators also exist for extracting some native TANGO CORBA sequence types. These can be useful for programmers who want to use the TANGO api internally in their device servers and do not want to convert from CORBA to C++ types. \end_layout \begin_layout Enumerate \noindent Insert operators for spectrum attribute and for the following types by pointer : \end_layout \begin_deeper \begin_layout Enumerate DevVarBooleanArray * \end_layout \begin_layout Enumerate DevVarShortArray * \end_layout \begin_layout Enumerate DevVarLongArray * \end_layout \begin_layout Enumerate DevVarLong64Array * \end_layout \begin_layout Enumerate DevVarFloatArray * \end_layout \begin_layout Enumerate DevVarDoubleArray * \end_layout \begin_layout Enumerate DevVarUCharArray * \end_layout \begin_layout Enumerate DevVarUShortArray * \end_layout \begin_layout Enumerate DevVarULongArray * \end_layout \begin_layout Enumerate DevVarULong64Array * \end_layout \begin_layout Enumerate DevVarStringArray * \end_layout \begin_layout Enumerate DevVarStateArray * \end_layout \end_deeper \begin_layout Enumerate Insert operators for spectrum attribute and for the following types by reference : \end_layout \begin_deeper \begin_layout Enumerate const DevVarBooleanArray & \end_layout \begin_layout Enumerate const DevVarShortArray & \end_layout \begin_layout Enumerate const DevVarLongArray & \end_layout \begin_layout Enumerate const DevVarLong64Array & \end_layout \begin_layout Enumerate const DevVarFloatArray & \end_layout \begin_layout Enumerate const DevVarDoubleArray & \end_layout \begin_layout Enumerate const DevVarUCharArray & \end_layout \begin_layout Enumerate const DevVarUShortArray & \end_layout \begin_layout Enumerate const DevVarULongArray & \end_layout \begin_layout Enumerate const DevVarULong64Array & \end_layout \begin_layout Enumerate const DevVarStringArray & \end_layout \begin_layout Enumerate const DevVarStateArray & \end_layout \end_deeper \begin_layout Enumerate Insert methods for image attribute and pointers. These method allow the programmer to define the x and y image dimensions. The following methods are defined : \end_layout \begin_deeper \begin_layout Enumerate insert(DevVarBooleanArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarShortArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarLongArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarLong64Array *, int, int ) \end_layout \begin_layout Enumerate insert(DevVarFloatArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarDoubleArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarUCharArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarUShortArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarULongArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarULong64Array *, int, int ) \end_layout \begin_layout Enumerate insert(DevVarStringArray *, int , int ) \end_layout \begin_layout Enumerate insert(DevVarStateArray *, int, int) \end_layout \end_deeper \begin_layout Enumerate Insert methods for image attribute and reference. These method allow the programmer to define the x and y image dimensions. The following methods are defined : \end_layout \begin_deeper \begin_layout Enumerate insert(const DevVarBooleanArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarShortArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarLongArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarLong64Array &, int, int ) \end_layout \begin_layout Enumerate insert(const DevVarFloatArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarDoubleArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarUCharArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarUShortArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarULongArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarULong64Array &, int, int ) \end_layout \begin_layout Enumerate insert(const DevVarStringArray &, int , int ) \end_layout \begin_layout Enumerate insert(const DevVarStateArray &, int, int ) \end_layout \end_deeper \begin_layout Enumerate Extract operators for the following types : \end_layout \begin_deeper \begin_layout Enumerate DevVarBooleanArray * \end_layout \begin_layout Enumerate DevVarShortArray * \end_layout \begin_layout Enumerate DevVarLongArray * \end_layout \begin_layout Enumerate DevVarLong64Array * \end_layout \begin_layout Enumerate DevVarFloatArray * \end_layout \begin_layout Enumerate DevVarDoubleArray * \end_layout \begin_layout Enumerate DevVarUCharArray * \end_layout \begin_layout Enumerate DevVarUShortArray * \end_layout \begin_layout Enumerate DevVarULongArray * \end_layout \begin_layout Enumerate DevVarULong64Array * \end_layout \begin_layout Enumerate DevVarStringArray * \end_layout \begin_layout Enumerate DevVarStateArray * \end_layout \begin_layout Enumerate DevVarEncodedArray * \end_layout \end_deeper \begin_layout Standard \noindent Here is an example of creating, inserting and extracting some DeviceAttribute types : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceAttribute my_short, my_long, my_string; \end_layout \begin_layout LyX-Code \noindent DeviceAttribute my_float_vector, my_double_vector; \end_layout \begin_layout LyX-Code \noindent string a_string; \end_layout \begin_layout LyX-Code \noindent short a_short; \end_layout \begin_layout LyX-Code \noindent DevLong a_long; \end_layout \begin_layout LyX-Code \noindent vector a_float_vector; \end_layout \begin_layout LyX-Code \noindent vector a_double_vector; \end_layout \begin_layout LyX-Code \noindent my_short << 100; // insert a short \end_layout \begin_layout LyX-Code \noindent my_short >> a_short; // extract a short \end_layout \begin_layout LyX-Code \noindent my_long << 1000; // insert a long \end_layout \begin_layout LyX-Code \noindent my_long >> a_long; // extract a DevLong \end_layout \begin_layout LyX-Code \noindent my_string << string("estas lista a bailar el tango ?"); // insert a string \end_layout \begin_layout LyX-Code \noindent my_string >> a_string; // extract a string \end_layout \begin_layout LyX-Code \noindent my_float_vector << a_float_vector // insert a vector of floats \end_layout \begin_layout LyX-Code \noindent my_float_vector >> a_float_vector; // extract a vector of floats \end_layout \begin_layout LyX-Code \noindent my_double_vector << a_double_vector; // insert a vector of doubles \end_layout \begin_layout LyX-Code \noindent my_double_vector >> a_double_vector; // extract a vector of doubles \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Extract read and set value of an attribute separately \end_layout \begin_layout LyX-Code // and get their dimensions \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code \noindent vector r_float_vector, w_float_vector; \end_layout \begin_layout LyX-Code my_float_vector.extract_read (r_float_vector) // extract read values \end_layout \begin_layout LyX-Code int dim_x = my_float_vector.get_dim_x(); // get x dimension \end_layout \begin_layout LyX-Code int dim_y = my_float_vector.get_dim_y(); // get y dimension \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code my_float_vector.extract_set (w_float_vector) // extract set values \end_layout \begin_layout LyX-Code int w_dim_x = my_float_vector.get_written_dim_x(); // get x dimension \end_layout \begin_layout LyX-Code int W_dim_y = my_float_vector.get_written_dim_y(); // get y dimension \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code // Example of memory management with TANGO sequence types without memory leaks \end_layout \begin_layout LyX-Code // \end_layout \begin_layout LyX-Code for (int i = 0;i < 10;i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code DeviceAttribute da; \end_layout \begin_layout LyX-Code DevVarLongArray *out; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code da = device->read_attribute("Attr"); \end_layout \begin_layout LyX-Code da >> out; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch(DevFailed &e) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code .... \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code cout << "Received value = " << (*out)[0]; \end_layout \begin_layout LyX-Code delete out; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection \noindent bool DeviceAttribute::is_empty() \end_layout \begin_layout Standard \noindent is_empty() is a boolean method which returns true or false depending on whether the DeviceAttribute object contains data or not. It can be used to test whether the DeviceAttribute has been initialized or not e.g. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent string parity; \end_layout \begin_layout LyX-Code \noindent DeviceAttribute sl_parity = my_device->read_attribute("parity"); \end_layout \begin_layout LyX-Code \noindent if (! sl_read.is_empty()) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent sl_parity >> parity; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code \noindent else \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent cout << " no parity attribute defined for serial line !" << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection \noindent void DeviceAttribute::exceptions(bitset) \end_layout \begin_layout Standard \noindent Is a method which allows the user to switch on/off exception throwing when trying to extract data from an empty DeviceAttribute object or with a wrong data type. The following flags are supported : \end_layout \begin_layout Enumerate \noindent \series bold isempty_flag \series default - throw a WrongData exception (reason= API_EmptyDeviceAttribute) if user tries to extract data from an empty DeviceAttribute object. By default, this flag is set. \end_layout \begin_layout Enumerate \series bold wrongtype_flag \series default - throw a WrongData exception (reason = API_IncompatibleAttrArgumentType) if user tries to extract data with a type different than the type used for insertion. By default, this flag is not set. \end_layout \begin_layout Enumerate \series bold failed_flag \series default - throw an exception when the user try to extract data from the DeviceAttribute object and an error was reported by the server when the user try to read the attribute. The type of the exception thrown is the type of the error reported by the server. By default, this flag is set. \end_layout \begin_layout Enumerate \series bold unknown_format_flag \series default - throw an exception when the user try to get the attribute data format from the DeviceAttribute object when this information is not yet available. This information is available only after the \emph on read_attribute \emph default call has been sucessfully executed. The type of the exception thrown is WrongData exception (reason = API_EmptyDevi ceAttribute). By default, this flag is not set. \end_layout \begin_layout Subsection bitset exceptions() \end_layout \begin_layout Standard Return the whole exception flags. \end_layout \begin_layout Subsection void DeviceAttribute::reset_exceptions(DeviceAttribute::except_flags fl) \end_layout \begin_layout Standard Reset one exception flag \end_layout \begin_layout Subsection void DeviceAttribute::set_exceptions(DeviceAttribute::except_flags fl) \end_layout \begin_layout Standard Set one exception flag \end_layout \begin_layout Standard The following is an example of how to use these exceptions related methods \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent 1 DeviceAttribute da; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 bitset bs = da.exceptions(); \end_layout \begin_layout LyX-Code 4 cout << "bs = " << bs << endl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 da.set_exceptions(DeviceAttribute::wrongtype_flag); \end_layout \begin_layout LyX-Code 7 bs = da.exceptions(); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 cout << "bs = " << bs << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Subsection bool DeviceAttribute::has_failed() \end_layout \begin_layout Standard Returns a boolean set to true if the server report an error when the attribute was read. \end_layout \begin_layout Subsection const DevErrorList &DeviceAttribute::get_err_stack() \end_layout \begin_layout Standard Returns the error stack reported by the server when the attribute was read. \end_layout \begin_layout Standard The following is an example of the three available ways to get data out of a DeviceAttribute object. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent 1 DeviceAttribute da; \end_layout \begin_layout LyX-Code 2 vector attr_data; \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 try \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 da = device->read_attribute("Attr"); \end_layout \begin_layout LyX-Code 7 da >> attr_data; \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout LyX-Code 9 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 .... \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 \end_layout \begin_layout LyX-Code 15 ------------------------------------------------------------------------ \end_layout \begin_layout LyX-Code 16 \end_layout \begin_layout LyX-Code 17 DeviceAttribute da; \end_layout \begin_layout LyX-Code 18 vector attr_data; \end_layout \begin_layout LyX-Code 19 \end_layout \begin_layout LyX-Code 20 da.reset_exceptions(DeviceAttribute::failed_flag); \end_layout \begin_layout LyX-Code 21 \end_layout \begin_layout LyX-Code 22 try \end_layout \begin_layout LyX-Code 23 { \end_layout \begin_layout LyX-Code 24 da = device->read_attribute("Attr"); \end_layout \begin_layout LyX-Code 25 } \end_layout \begin_layout LyX-Code 26 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 27 { \end_layout \begin_layout LyX-Code 28 ..... \end_layout \begin_layout LyX-Code 29 } \end_layout \begin_layout LyX-Code 30 \end_layout \begin_layout LyX-Code 31 if (!(da >> attr_data)) \end_layout \begin_layout LyX-Code 32 { \end_layout \begin_layout LyX-Code 33 DevErrorList &err = da.get_err_stack(); \end_layout \begin_layout LyX-Code 34 ..... \end_layout \begin_layout LyX-Code 35 } \end_layout \begin_layout LyX-Code 36 else \end_layout \begin_layout LyX-Code 37 { \end_layout \begin_layout LyX-Code 38 ..... \end_layout \begin_layout LyX-Code 39 } \end_layout \begin_layout LyX-Code 40 \end_layout \begin_layout LyX-Code 41 ---------------------------------------------------------------------- \end_layout \begin_layout LyX-Code 42 \end_layout \begin_layout LyX-Code 43 DeviceAttribute da; \end_layout \begin_layout LyX-Code 44 vector attr_data; \end_layout \begin_layout LyX-Code 45 \end_layout \begin_layout LyX-Code 46 try \end_layout \begin_layout LyX-Code 47 { \end_layout \begin_layout LyX-Code 48 da = device->read_attribute("Attr"); \end_layout \begin_layout LyX-Code 49 } \end_layout \begin_layout LyX-Code 50 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 51 { \end_layout \begin_layout LyX-Code 52 ...... \end_layout \begin_layout LyX-Code 53 } \end_layout \begin_layout LyX-Code 54 \end_layout \begin_layout LyX-Code 55 if (da.has_failed()) \end_layout \begin_layout LyX-Code 56 { \end_layout \begin_layout LyX-Code 57 DevErrorList &err = da.get_err_stack(); \end_layout \begin_layout LyX-Code 58 .... \end_layout \begin_layout LyX-Code 59 } \end_layout \begin_layout LyX-Code 60 else \end_layout \begin_layout LyX-Code 61 { \end_layout \begin_layout LyX-Code 62 da >> attr_data; \end_layout \begin_layout LyX-Code 63 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The first way is coded between lines 1 and 13. It uses the default behaviour of the DeviceAttribute object which is to throw an exception when the user try to extract data when the server reports an error when the attribute was read. The second way is coded between line 17 and 40. The DeviceAttribute object now does not throw "failed" exception any more and the return value of the extractor operator is checked. The third way is coded between line 43 and 63. In this case, the attribute data validity is checked before trying to extract them. \end_layout \begin_layout Subsection string &DeviceAttribute::get_name() \end_layout \begin_layout Standard Returns the name of the attribute \end_layout \begin_layout Subsection void DeviceAttribute::set_name(string &) \end_layout \begin_layout Standard Sets attribute name \end_layout \begin_layout Subsection void DeviceAttribute::set_name(const char *) \end_layout \begin_layout Standard Sets attribute name \end_layout \begin_layout Subsection AttrQuality &DeviceAttribute::get_quality() \end_layout \begin_layout Standard Returns the quality of the attribute: an enumerate type which can be one of {ATTR_VALID, ATTR_INVALID, ATTR_ALARM, ATTR_CHANGING or ATTR_WARNING}. \end_layout \begin_layout Subsection int DeviceAttribute::get_dim_x() \end_layout \begin_layout Standard Returns the attribute read x dimension \end_layout \begin_layout Subsection int DeviceAttribute::get_dim_y() \end_layout \begin_layout Standard Returns the attribute read y dimension \end_layout \begin_layout Subsection int DeviceAttribute::get_written_dim_x() \end_layout \begin_layout Standard Returns the attribute write x dimension \end_layout \begin_layout Subsection int DeviceAttribute::get_written_dim_y() \end_layout \begin_layout Standard Returns the attribute write y dimension \end_layout \begin_layout Subsection AttributeDimension DeviceAttribute::get_r_dimension() \end_layout \begin_layout Standard Returns the attribute read dimension \end_layout \begin_layout Subsection AttributeDimension DeviceAttribute::get_w_dimension() \end_layout \begin_layout Standard Returns the attribute write dimension \end_layout \begin_layout Subsection long DeviceAttribute::get_nb_read() \end_layout \begin_layout Standard Returns the number of read values \end_layout \begin_layout Subsection long DeviceAttribute::get_nb_written() \end_layout \begin_layout Standard Returns the number of written values. Here is an example of these last methods usage. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent 1 DeviceAttribute da; \end_layout \begin_layout LyX-Code 2 vector attr_data; \end_layout \begin_layout LyX-Code 3 \end_layout \begin_layout LyX-Code 4 try \end_layout \begin_layout LyX-Code 5 { \end_layout \begin_layout LyX-Code 6 da = device->read_attribute("Attr"); \end_layout \begin_layout LyX-Code 7 da >> attr_data; \end_layout \begin_layout LyX-Code 8 } \end_layout \begin_layout LyX-Code 9 catch (DevFailed &e) \end_layout \begin_layout LyX-Code 10 { \end_layout \begin_layout LyX-Code 11 .... \end_layout \begin_layout LyX-Code 12 } \end_layout \begin_layout LyX-Code 13 \end_layout \begin_layout LyX-Code 14 long read = da.get_nb_read(); \end_layout \begin_layout LyX-Code 15 long written = da.get_nb_written(); \end_layout \begin_layout LyX-Code 16 size_t size = attr_data.size(); \end_layout \begin_layout LyX-Code 17 \end_layout \begin_layout LyX-Code 18 for (long i = 0;i < read;i++) \end_layout \begin_layout LyX-Code 19 cout << "Read value " << i+1 << " = " << attr_data[i] << endl; \end_layout \begin_layout LyX-Code 20 \end_layout \begin_layout LyX-Code 21 int ind; \end_layout \begin_layout LyX-Code 22 for (long j = 0; j < written;j++) \end_layout \begin_layout LyX-Code 23 { \end_layout \begin_layout LyX-Code 24 size == 1 ? ind = j : ind = j + read; \end_layout \begin_layout LyX-Code 25 cout << "Last written value " << j+1 << " = " << attr_data[ind] << endl; \end_layout \begin_layout LyX-Code 26 } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Line 24 is needed to cover the case of scalar write attribute where only one value is returned but both get_nb_read() and get_nb_written() methods return 1. \end_layout \begin_layout Subsection TimeVal &DeviceAttribute::get_date() \end_layout \begin_layout Standard Returns a reference to the time when the attribute was read in server \end_layout \begin_layout Subsection int DeviceAttribute::get_type() \end_layout \begin_layout Standard Returns the type of the attribute data. \end_layout \begin_layout Subsection AttrDataFormat DeviceAttribute::get_data_format() \end_layout \begin_layout Standard Returns the attribute data format. Note that this information is valid only after the call to the device has been executed. Otherwise the FMT_UNKNOWN value of the AttrDataFormat enumeration is returned or an exception is thrown according to the object exception flags. \end_layout \begin_layout Subsection ostream &operator<<(ostream &, DeviceAttribute &) \end_layout \begin_layout Standard Is an utility function to easily print the contents of a DeviceAttribute object. This function knows all types which could be inserted in a DeviceAttribute object and print them accordingly if the data are valid. It also prints the date returned within the attribute, the attribute name, the dim_x and dim_y attribute parameter and its quality factor. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy *dev = new DeviceProxy("..."); \end_layout \begin_layout LyX-Code DeviceAttribute attr; \end_layout \begin_layout LyX-Code attr = dev->read_attribute("MyAttribute"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code cout << "Attribute returned: " << attr << endl; \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Tango::DeviceAttributeHistory \begin_inset CommandInset label LatexCommand label name "AttributeHistory" \end_inset \end_layout \begin_layout Standard This is the fundamental type for receiving data from device attribute polling buffers. This class inherits from the Tango::DeviceAttribute class. One instance of this class is created for each attribute result history. Within this class, you find the attribute result data or the exception parameters and a flag indicating if the attribute has failed when it was invoked by the device server polling thread. For history calls, it is not possible to returns attribute error as exception. See chapter on Advanced Features for all details regarding device polling. On top of the methods inherited from the DeviceAttribute class, it offers the following methods \end_layout \begin_layout Subsection ostream &operator<<(ostream &, DeviceAttributeHistory &) \end_layout \begin_layout Standard Is an utility function to easily print the contents of a DeviceAttributeHistory object. This function knows all types which could be inserted in a DeviceAttributeHisto ry object and print them accordingly. It also prints date, attribute name, attribute dim_x and dim_y parameters, attribute quality factor and error stack in case the attribute returned an error. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DeviceProxy *dev = new DeviceProxy( \begin_inset Quotes eld \end_inset ... \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code int hist_depth = 4; \end_layout \begin_layout LyX-Code vector *hist; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code hist = dev->attribute_history( \begin_inset Quotes eld \end_inset MyAttribute \begin_inset Quotes erd \end_inset ,hist_depth); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code for (int i = 0;i < hist_depth;i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << (*hist)[i] << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code delete hist; \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section Tango::AttributeProxy() \end_layout \begin_layout Standard The high level object which provides the client with an easy-to-use interface to TANGO device attributes. AttributeProxy is a handle to the real Attribute (hence the name Proxy) and is not the real Attribute (of course). The AttributeProxy manages timeouts, stateless connections (new AttributeProxy( ) nearly always works), and reconnection if the device server is restarted. \end_layout \begin_layout Subsection Constructors \end_layout \begin_layout Subsubsection AttributeProxy::AttributeProxy(string &name) \end_layout \begin_layout Standard Create an AttributeProxy to an attribute of the specified name. The constructor will connect to the TANGO database, query for the device to which the attribute belongs to network address and build a connection to this device. If the device to which the attribute belongs to is defined in the TANGO database but the device server is not running, AttributeProxy will try to build a connection every time the client tries to access the attribute. If an alias \begin_inset Index idx status collapsed \begin_layout Plain Layout alias \end_layout \end_inset name is defined for the attribute, this alias name can be used to create the AttributeProxy instance. If a device name alias is defined for the device, it can be used instead of the three fields device name. If the device to which the attribute belongs to is not defined in the database, an exception is thrown. Examples : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code AttributeProxy *my_attr = new AttributeProxy("my/own/device/attr"); \end_layout \begin_layout LyX-Code AttributeProxy *my_attr_bis = new AttributeProxy("attr_alias"); \end_layout \begin_layout LyX-Code AttributeProxy *my_attr_ter = new AttributeProxy("dev_alias/attr"); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard See appendix on device/attribute naming for all details about Tango device or attribute naming syntax. \end_layout \begin_layout Standard \emph on Exception: WrongNameSyntax, ConnectionFailed \end_layout \begin_layout Subsubsection AttributeProxy::AttributeProxy(const char *name) \end_layout \begin_layout Standard Idem previous call \end_layout \begin_layout Subsection Miscellaneous methods \end_layout \begin_layout Subsubsection DevState AttributeProxy::state() \end_layout \begin_layout Standard A method which returns the state of the device to which the attribute belongs to. This state is returned as a Tango::DevState type. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code dev_state = my_attr->state() << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection string AttributeProxy::status() \end_layout \begin_layout Standard A method which return the status of the device to which the attribute belongs to. The status is returned as a string. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code cout << "device status" << my_attr->status() << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection int AttributeProxy::ping() \end_layout \begin_layout Standard A method which sends a ping to the device to which the attribute belongs and returns the time elapsed in microseconds. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code cout << "device ping took " << my_device->ping() << \begin_inset Quotes eld \end_inset microseconds \begin_inset Quotes erd \end_inset << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed \end_layout \begin_layout Subsubsection string AttributeProxy::name() \end_layout \begin_layout Standard Returns the attribute name \end_layout \begin_layout Subsubsection DeviceProxy *get_device_proxy() \end_layout \begin_layout Standard Returns the DeviceProxy instance used to communicate with the device to which the attributes belongs. \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout Subsection Synchronous related methods \end_layout \begin_layout Subsubsection AttributeInfo AttributeProxy::get_config() \end_layout \begin_layout Standard Return the attribute configuration. AttributeInfo is a struct defined as follows : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code typedef struct _AttributeInfo { \end_layout \begin_layout LyX-Code string name; \end_layout \begin_layout LyX-Code AttrWriteType writable; \end_layout \begin_layout LyX-Code AttrDataFormat data_format; \end_layout \begin_layout LyX-Code int data_type; \end_layout \begin_layout LyX-Code int max_dim_x; \end_layout \begin_layout LyX-Code int max_dim_y; \end_layout \begin_layout LyX-Code string description; \end_layout \begin_layout LyX-Code string label; \end_layout \begin_layout LyX-Code string unit; \end_layout \begin_layout LyX-Code string standard_unit; \end_layout \begin_layout LyX-Code string display_unit; \end_layout \begin_layout LyX-Code string format; \end_layout \begin_layout LyX-Code string min_value; \end_layout \begin_layout LyX-Code string max_value; \end_layout \begin_layout LyX-Code string min_alarm; \end_layout \begin_layout LyX-Code string max_alarm; \end_layout \begin_layout LyX-Code string writable_attr_name; \end_layout \begin_layout LyX-Code vector extensions; \end_layout \begin_layout LyX-Code Tango::DispLevel disp_level; \end_layout \begin_layout LyX-Code } AttributeInfo; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void AttributeProxy::set_config(AttributeInfo &) \end_layout \begin_layout Standard Change the attribute configuration. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection DeviceAttribute AttributeProxy::read() \end_layout \begin_layout Standard Read the attribute. To extract the value you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double (this will return 0) you have to extract it as a short. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void AttributeProxy::write(DeviceAttribute&) \end_layout \begin_layout Standard Write the attribute. To insert the value to write you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection DeviceAttribute AttributeProxy::write_read(DeviceAttribute&) \end_layout \begin_layout Standard Write then read a single attribute in a single network call. By default (serialisation by device), the execution of this call in the server can't be interrupted by other clients. To insert/extract the value to write/read you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device \end_layout \begin_layout Subsubsection vector *AttributeProxy::history(int) \end_layout \begin_layout Standard Retrieve attribute history from the attribute polling buffer. The argument is the wanted history depth. This method returns a vector of DeviceAttributeHistory types. This method allocates memory for the vector of DeviceAttributeHistory returned to the caller. It is the caller responsibility to delete this memory. Class DeviceAttributeHistory is detailed on chapter \begin_inset CommandInset ref LatexCommand ref reference "AttributeHistory" \end_inset See chapter on Advanced Feature for all details regarding polling. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent AttributeProxy attr = new AttributeProxy("my/own/device/Current"); \end_layout \begin_layout LyX-Code vector *hist; \end_layout \begin_layout LyX-Code hist = attr->history(5); \end_layout \begin_layout LyX-Code \noindent for (int i = 0;i < 5;i++) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code bool fail = (*hist)[i].has_failed(); \end_layout \begin_layout LyX-Code if (fail == false) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Attribute name = " << (*hist)[i].get_name() << endl; \end_layout \begin_layout LyX-Code cout << "Attribute quality factor = " << (*hist)[i].get_quality() << endl; \end_layout \begin_layout LyX-Code long value; \end_layout \begin_layout LyX-Code (*hist)[i] >> value; \end_layout \begin_layout LyX-Code cout << "Current = " << value << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Attribute failed !" << endl; \end_layout \begin_layout LyX-Code cout << "Error level 0 desc = " << ((*hist)[i].get_err_stack())[0].desc << endl; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code cout << "Date = " << (*hist)[i].get_date().tv_sec << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code delete hist; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on NonSupportedFeature, ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout Subsection Asynchronous methods \end_layout \begin_layout Subsubsection long AttributeProxy::read_asynch() \end_layout \begin_layout Standard Read the attribute asynchronously (polling model). This call returns an \emph on asynchronous call identifier \emph default which is needed to get the attribute value. \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed \end_layout \begin_layout Subsubsection DeviceAttribute *AttributeProxy::read_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous read is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection DeviceAttribute *AttributeProxy::read_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous read is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, it is returned to the caller in a DeviceAttribute object. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. To extract attribute value, you have to use the operator of the class DeviceAtt ribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the DeviceAttribute object returned to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection long AttributeProxy::write_asynch(DeviceAttribute &argin) \end_layout \begin_layout Standard Write the attribute asynchronously (polling model). To insert the value to write you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the user type to the attribute native type e.g. if an attribute expects a short you cannot insert it as a double (this will throw an exception) you have to insert it as a short. This call returns an \emph on asynchronous call identifier \emph default which is needed to get the server reply. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void AttributeProxy::write_reply(long id) \end_layout \begin_layout Standard Check if the answer of an asynchronous write is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. An exception is also thrown in case of the reply is not yet arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void AttributeProxy::write_reply(long id, long timeout) \end_layout \begin_layout Standard Check if the answer of an asynchronous write is arrived (polling model). id is the asynchronous call identifier. If the reply is arrived and if it is a valid reply, the call returned. If the reply is an exception, it is re-thrown by this call. If the reply is not yet arrived, the call will wait (blocking the process) for the time specified in timeout. If after timeout milliseconds, the reply is still not there, an exception is thrown. If timeout is set to 0, the call waits until the reply arrived. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on AsynCall, AsynReplyNotArrived, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsubsection void AttributeProxy::read_asynch(CallBack &cb) \end_layout \begin_layout Standard Read the attribute asynchronously using the callback model. The argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_read() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsubsection void AttributeProxy::write_asynch(DeviceAttribute &argin, CallBack &cb) \end_layout \begin_layout Standard Write the attribute asynchronously using the callback model. The argument is a reference to a callback object. This callback object should be an instance of a user class inheriting from the \emph on Tango::CallBack \emph default class with the \emph on attr_written() \emph default method overloaded. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on ConnectionFailed \end_layout \begin_layout Subsection Polling related methods \end_layout \begin_layout Subsubsection bool AttributeProxy::is_polled() \end_layout \begin_layout Standard Returns true if the attribute is polled. Otherwise, returns false. \end_layout \begin_layout Subsubsection int AttributeProxy::get_poll_period() \end_layout \begin_layout Standard Returns the attribute polling period in mS. If the attribute is not polled, it returns 0. \end_layout \begin_layout Subsubsection void AttributeProxy::poll(int period) \end_layout \begin_layout Standard Add the attribute to the list of polled attributes. The polling period is specified by "period" (in mS). If the attribute is already polled, this method will update the polling period according to "period". \end_layout \begin_layout Subsubsection void AttributeProxy::stop_poll() \end_layout \begin_layout Standard Remove attribute from the list of polled attributes. \end_layout \begin_layout Subsection Event related methods \end_layout \begin_layout Subsubsection int AttributeProxy::subscribe_event(EventType event, CallBack *cb) \end_layout \begin_layout Standard The client call to subscribe for event reception in the \series bold push model \series default . The client implements a callback method which is triggered when the event is received either by polling or a dedicated thread. Filtering is done based on the reason specified and the event type. For example when reading the state and the reason specified is "change" the event will be fired only when the state changes. Events consist of an attribute name and the event reason. A standard set of reasons are implemented by the system, additional device specific reasons can be implemented by device servers programmers. \end_layout \begin_layout Standard The \emph on event \emph default parameter is the event reason and must be on the enumerated values: \end_layout \begin_layout Itemize Tango::CHANGE_EVENT \end_layout \begin_layout Itemize Tango::PERIODIC_EVENT \end_layout \begin_layout Itemize Tango::ARCHIVE_EVENT \end_layout \begin_layout Itemize Tango::ATTR_CONF_EVENT \end_layout \begin_layout Standard \emph on cb \emph default is a pointer to a class inheriting from the Tango CallBack class and implementi ng a \emph on push_event() \emph default method, \emph on filters \emph default is a variable list of name,value pairs which define additional filters for events. The \emph on subscribe_event() \emph default call returns an event id which has to be specified when unsubscribing from this event. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a third argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection int AttributeProxy::subscribe_event(EventType event, CallBack *cb, bool stateless) \end_layout \begin_layout Standard This subscribe event method has the same functionality as described in the last section. It adds an additional flag called \emph on stateless \emph default . When the \emph on stateless \emph default flag is set to \emph on false \emph default , an exception will be thrown when the event subscription encounters a problem. \end_layout \begin_layout Standard With the \emph on stateless \emph default flag set to \emph on true \emph default , the event subscription will always succeed, even if the corresponding device server is not running. The keep alive thread will try every 10 seconds to subscribe for the specified event. At every subscription retry, a callback is executed which contains the corresponding exception. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a forth argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering and it was the third argument in the argument list. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection int AttributeProxy::subscribe_event(EventType event, int event_queue_size, bool stateless) \end_layout \begin_layout Standard The client call to subscribe for event reception in the \series bold pull model \series default . Instead of a callback method the client has to specify the size of the event reception buffer. \end_layout \begin_layout Standard The event reception buffer is implemented as a round robin buffer. This way the client can set-up different ways to receive events. \end_layout \begin_layout Standard Event reception buffer size = 1 : The client is interested only in the value of the last event received. All other events that have been received since the last reading are discarded. \end_layout \begin_layout Standard Event reception buffer size > 1 : The client has chosen to keep an event history of a given size. When more events arrive since the last reading, older events will be discarded. \end_layout \begin_layout Standard Event reception buffer size = ALL_EVENTS : The client buffers all received events. The buffer size is unlimited and only restricted by the available memory for the client. \end_layout \begin_layout Standard All other parameters are similar to the descriptions given in the last two sections. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Standard Note: For releases prior to Tango 8, a similar call with a forth argument (const vector &filters) was available. This extra argument gave the user a way to define extra event filtering and it was the third argument in the argument list. For compatibility reason, this call still exist but the extra filtering features is not implemented. \end_layout \begin_layout Subsubsection void AttributeProxy::unsubscribe_event(int event_id) \end_layout \begin_layout Standard Unsubscribe a client from receiving the event specified by \emph on event_id \emph default . \emph on event_id \emph default is the event identifier returned by the \emph on AttributeProxy::subscribe_event() \emph default method. \end_layout \begin_layout Standard \emph on Exception: \emph default \emph on EventSystemFailed \end_layout \begin_layout Subsubsection void AttributeProxy::get_events(int event_id, CallBack *cb) \end_layout \begin_layout Standard The method extracts all waiting events from the event reception buffer and executes the callback method cb for every event. During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsubsection void AttributeProxy::get_events(int event_id, EventDataList &event_list) \end_layout \begin_layout Standard The method extracts all waiting events from the event reception buffer. The returned event_list is a vector of EventData pointers. The EventData object contains the event information as for the callback methods. \end_layout \begin_layout Standard During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsubsection void AttributeProxy::get_events(int event_id, AttrConfEventDataList &event_list) \end_layout \begin_layout Standard The method extracts all waiting attribute configuration events from the event reception buffer. The returned event_list is a vector of AttrConfEventData pointers. The AttrConfEventData object contains the event information as for the callback methods. \end_layout \begin_layout Standard During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsubsection int AttributeProxy::event_queue_size(int event_id) \end_layout \begin_layout Standard Returns the number of stored events in the event reception buffer. After every call to DeviceProxy:get_events(), the event queue size is 0. \end_layout \begin_layout Standard During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsubsection TimeVal AttributeProxy::get_last_event_date(int event_id) \end_layout \begin_layout Standard Returns the arrival time of the last event stored in the event reception buffer. After every call to DeviceProxy:get_events(), the event reception buffer is empty. In this case an exception will be returned. \end_layout \begin_layout Standard During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsubsection bool AttributeProxy::is_event_queue_empty(int event_id) \end_layout \begin_layout Standard Returns true when the event reception buffer is empty. \end_layout \begin_layout Standard During event subscription the client must have chosen the pull model for this event. event_id is the event identifier returned by the AttributeProxy::subscribe_even t() method. \end_layout \begin_layout Standard \emph on Exception: EventSystemFailed \end_layout \begin_layout Subsection Property related methods \end_layout \begin_layout Subsubsection void AttributeProxy::get_property (string&, DbData&) \end_layout \begin_layout Standard Get a single property for the attribute. The property to get is specified as a string. Refer to DbDevice::get_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::get_property (vector&, DbData&) \end_layout \begin_layout Standard Get a list of properties for the attribute. The properties to get are specified as a vector of strings. Refer to DbDevice::get_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::get_property(DbData&) \end_layout \begin_layout Standard Get property(ies) for the attribute. Properties to get are specified using the DbData type. Refer to DbDevice::get_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::put_property(DbData&) \end_layout \begin_layout Standard Put property(ies) for an attribute. Properties to put are specified using the DbData type. Refer to DbDevice::put_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::delete_property (string&, DbData&) \end_layout \begin_layout Standard Delete a single property for an attribute. The property to delete is specified as a string. Refer to DbDevice::delete_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::delete_property (vector&, DbData&) \end_layout \begin_layout Standard Delete a list of properties for an attribute. The properties to delete are specified as a vector of strings. Refer to DbDevice::get_property() and DbData sections below for details on the DbData type. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Subsubsection void AttributeProxy::delete_property(DbData&) \end_layout \begin_layout Standard Delete property(ies) for an attribute. Properties to delete are specified using the DbData type. Refer to DbDevice::get_property() and DbData sections below for details. \end_layout \begin_layout Standard \emph on Exception: NonDbDevice, ConnectionFailed (with database), CommunicationFailed (with database), DevFailed from database device \end_layout \begin_layout Section Tango::ApiUtil \begin_inset CommandInset label LatexCommand label name "sec:Tango::ApiUtil" \end_inset \end_layout \begin_layout Standard This class is a singleton. Therefore, it is not necessary to create it. It will be automatically done. A static method allows a user to retrieve the instance \end_layout \begin_layout Subsection static ApiUtil *ApiUtil::instance() \end_layout \begin_layout Standard Return the ApiUtil singleton instance. \end_layout \begin_layout Subsection static void ApiUtil::cleanup() \end_layout \begin_layout Standard Destroy the ApiUtil singleton instance. \end_layout \begin_layout Subsection long ApiUtil::pending_asynch_call(asyn_req_type req) \end_layout \begin_layout Standard Return number of asynchronous pending requests (any device). The input parameter is an enumeration with three values which are: \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 POLLING : Return only polling model asynchronous request number \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 CALL_BACK : Return only callback model asynchronous request number \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 ALL_ASYNCH : Return all asynchronous request number \end_layout \begin_layout Standard \emph on Exception: None \end_layout \begin_layout Subsection void ApiUtil::get_asynch_replies() \end_layout \begin_layout Standard Fire callback methods for all (any device) asynchronous requests (command and attribute) with already arrived replied. Returns immediately if there is no replies already arrived or if there is no asynchronous requests. \end_layout \begin_layout Standard \emph on Exception: None, all errors are reported using the err and errors fields of the parameter passed to the callback method. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:Asynchronous-callback-related" \end_inset for details. \end_layout \begin_layout Subsection void ApiUtil::get_asynch_replies(long timeout) \end_layout \begin_layout Standard Fire callback methods for all (any device) asynchronous requests (command and attributes) with already arrived replied. Wait and block the caller for timeout milliseconds if they are some device asynchronous requests which are not yet arrived. Returns immediately if there is no asynchronous request. If timeout is set to 0, the call waits until all the asynchronous requests sent has received a reply. \end_layout \begin_layout Standard \emph on Exception: AsynReplyNotArrived. All other errors are reported using the err and errors fields of the object passed to the callback methods. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:Asynchronous-callback-related" \end_inset for details. \end_layout \begin_layout Subsection void ApiUtil::set_asynch_cb_sub_model(cb_sub_model model) \end_layout \begin_layout Standard Set the asynchronous callback sub-model between the pull and push sub-model. See chapter \begin_inset CommandInset ref LatexCommand ref reference "sec:Request-model" \end_inset to read the definition of these sub-model. The cb_sub_model data type is an enumeration with two values which are : \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 PUSH_CALLBACK : The push sub-model \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 PULL_CALLBACK : The pull sub-model \end_layout \begin_layout Standard By default, all Tango client using asynchronous callback model are in pull sub-model. This call must be used to switch to the push sub-model. NOTE that in push sub-model, a separate thread is spawned to deal with server replies. \end_layout \begin_layout Standard \emph on Exception: None \end_layout \begin_layout Subsection cb_sub_model ApiUtil::get_asynch_cb_sub_model() \end_layout \begin_layout Standard Get the asynchronous callback sub-model. \end_layout \begin_layout Standard \emph on Exception: None \end_layout \begin_layout Subsection static int ApiUtil::get_env_var(const char *name,string &value) \end_layout \begin_layout Standard Get environment variable. On Unixes OS, this call tries to get the variable in the caller environment then in a file \emph on .tangorc \begin_inset Index idx status collapsed \begin_layout Plain Layout tangorc \end_layout \end_inset \emph default in the user home directory and finally in a file \emph on /etc/tangorc \emph default . On Windows, this call looks in the user environment then in a file stored in %TANGO_HOME%/tangorc. This method returns 0 of the environment variable is found. Otherwise, it returns -1. \end_layout \begin_layout Standard \emph on Exception: None \end_layout \begin_layout Subsection void set_event_buffer_hwm(DevLong val) \end_layout \begin_layout Standard Set the client event buffer high water mark (HWM \begin_inset Index idx status collapsed \begin_layout Plain Layout HWM \end_layout \end_inset ) \end_layout \begin_layout Section Asynchronous callback related classes \begin_inset CommandInset label LatexCommand label name "sec:Asynchronous-callback-related" \end_inset \end_layout \begin_layout Subsection Tango::CallBack \end_layout \begin_layout Standard When using the event push model (callback automatically executed), there are some cases (same callback used for events coming from different devices hosted in device server process running on different hosts) where the callback method could be executed concurently by different threads started by the ORB. The user has to code his callback method in a \series bold thread \series default \begin_inset Index idx status collapsed \begin_layout Plain Layout thread \end_layout \end_inset \series bold safe \series default manner. \end_layout \begin_layout Subsubsection void CallBack::cmd_ended(CmdDoneEvent *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when the asynchronous callback model is used. This is the method which will be executed when the server reply from a command_inout is received in both push and pull sub-mode. \end_layout \begin_layout Subsubsection void CallBack::attr_read(AttrReadEvent *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when the asynchronous callback model is used. This is the method which will be executed when the server reply from a read_attribute(s) is received in both push and pull sub-mode. \end_layout \begin_layout Subsubsection void CallBack::attr_written(AttrWrittenEvent *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when the asynchronous callback model is used. This is the method which will be executed when the server reply from a write_attribute(s) is received in both push and pull sub-mode. \end_layout \begin_layout Subsubsection void CallBack::push_event(EventData *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when events are used. This is the method which will be executed when the server send event(s) to the client. \end_layout \begin_layout Subsubsection void CallBack::push_event(AttrConfEventData *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when events are used. This is the method which will be executed when the server send attribute configuration change event(s) to the client. \end_layout \begin_layout Subsubsection void CallBack::push_event(DataReadyEventData *event) \end_layout \begin_layout Standard This method is defined as being empty and must be overloaded by the user when events are used. This is the method which will be executed when the server send attribute data ready event(s) to the client. \end_layout \begin_layout Subsection Tango::CmdDoneEvent \end_layout \begin_layout Standard This class is used to pass data to the callback method in asynchronous callback model for command execution. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 cmd_name : The command name (string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 argout : The command argout (DeviceData &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the command failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Subsection Tango::AttrReadEvent \end_layout \begin_layout Standard This class is used to pass data to the callback method in asynchronous callback model for read_attribute(s) execution. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_names : The attribute name list (vector &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 argout : The attribute data (vector *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the request failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Standard To extract attribute value(s), you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the vector of DeviceAttribute objects passed to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Subsection Tango::AttrWrittenEvent \end_layout \begin_layout Standard This class is used to pass data to the callback method in asynchronous callback model for write_attribute(s) execution. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_names : The attribute name list (vector &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the request failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Subsection Tango::EventData \end_layout \begin_layout Standard This class is used to pass data to the callback method when an event is sent to the client. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_name : The attribute name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 event : The event name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_value : The attribute data (DeviceAttribute *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the request failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Standard To extract attribute value(s), you have to use the operator of the class DeviceAttribute which corresponds to the data type of the attribute. NOTE: There is no automatic type conversion from the attribute native type to user type e.g. if an attribute returns a short you cannot extract it as a double, you have to extract it as a short. Memory has been allocated for the vector of DeviceAttribute objects passed to the caller. This is the caller responsibility to delete this memory. \end_layout \begin_layout Subsection Tango::AttrConfEventData \end_layout \begin_layout Standard This class is used to pass data to the callback method when an attribute configuration event is sent to the client. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_name : The attribute name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 event : The event name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_conf : The attribute configuration (AttributeInfoEx *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the request failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Subsection Tango::DataReadyEventData \begin_inset Index idx status collapsed \begin_layout Plain Layout DataReadyEventData \end_layout \end_inset \end_layout \begin_layout Standard This class is used to pass data to the callback method when an attribute data ready event is sent to the client. It contains the following public field \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 device : The DeviceProxy object on which the call was executed (Tango::DevicePro xy *) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_name : The attribute name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 event : The event name (std::string &) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 attr_data_type :The attribute data type (int) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 ctr : The user counter. Set to 0 if not defined when sent by the server (int) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 err : A boolean flag set to true if the request failed. False otherwise (bool) \end_layout \begin_layout Labeling \labelwidthstring 00.00.0000 errors : The error stack (DevErrorList &) \end_layout \begin_layout Section Tango::Group \end_layout \begin_layout Subsection Constructor and Destructor \end_layout \begin_layout Subsubsection Group::Group (const std::string& name) \end_layout \begin_layout Standard Instanciate an empty group. The group name allows retrieving a sub-group in the hierarchy. \end_layout \begin_layout Standard See also: Group::~Group(), Group::get_group(). \end_layout \begin_layout Subsubsection Group::~Group () \end_layout \begin_layout Standard Delete a group and all its elements. \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a Group (respectively a DeviceProxy) returned by a call to \emph on Tango::Group::get_group() \emph default (respectively to \emph on Tango::Group::get_device() \emph default ). Use the \emph on Tango::Group::remove() \emph default method instead. \end_layout \begin_layout Standard See also: Group::Group(), Group::remove(), Group::remove_all(). \end_layout \begin_layout Subsection Group Management Related Methods \end_layout \begin_layout Subsubsection void Group::add (Group* group, int timeout_ms = -1) \end_layout \begin_layout Standard Attaches a (sub)group. \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a Group attached to a Group. Use the \emph on Group::remove() \emph default method instead. \end_layout \begin_layout Standard If \emph on timeout_ms \emph default parameter is different from -1, the client side timeout associated to each device composing the group added is set to \emph on timeout_ms \emph default milliseconds. If \emph on timeout_ms \emph default is -1, timeouts are not changed. \end_layout \begin_layout Standard This method does nothing if the specified group is already attached (i.e. it is silently ignored) and \emph on timeout_ms \emph default = -1. \end_layout \begin_layout Standard If the specified group is already attached and \emph on timeout_ms \emph default is different from -1, the client side timeout of each device composing the group given in parameter is set to \emph on timeout_ms \emph default milliseconds. \end_layout \begin_layout Standard See also: all other forms of Group::add() and Group::set_timeout_millis(). \end_layout \begin_layout Subsubsection void Group::add (const std::string& pattern, int timeout_ms = -1) \end_layout \begin_layout Standard Attaches any device which name matches the specified \emph on pattern \emph default . \end_layout \begin_layout Standard The pattern parameter can be a simple device name or a device name pattern (e.g. domain_*/ family/member_*). \end_layout \begin_layout Standard This method first asks to the Tango database the list of device names matching the pattern. Devices are then attached to the group in the order in which they are returned by the database. \end_layout \begin_layout Standard Any device already present in the hierarchy (i.e. a device belonging to the group or to one of its subgroups) is silently ignored but its client side timeout is set to \emph on timeout_ms \emph default milliseconds if \emph on timeout_ms \emph default is different from -1. \end_layout \begin_layout Standard Set the client side timeout of each device matching the specified \emph on pattern \emph default to \emph on timeout_ms \emph default milliseconds if \emph on timeout_ms \emph default is different from -1. \end_layout \begin_layout Standard See also: all other forms of Group::add() and Group::set_timeout_millis(). \end_layout \begin_layout Subsubsection void Group::add (const std::vector& patterns, int timeout_ms = -1) \end_layout \begin_layout Standard Attaches any device which name matches one of the specified patterns. \end_layout \begin_layout Standard The \emph on patterns \emph default parameter can be an array of device names and/or device name patterns. \end_layout \begin_layout Standard This method first asks to the Tango database the list of device names matching one the patterns. Devices are then attached to the group in the order in which they are returned by the database. \end_layout \begin_layout Standard Any device already present in the hierarchy (i.e. a device belonging to the group or to one of its subgroups), is silently ignored but its client side timeout is set to \emph on timeout_ms \emph default milliseconds if \emph on timeout_ms \emph default is different from -1. \end_layout \begin_layout Standard If \emph on timeout_ms \emph default is different from -1, the client side timeouts of all devices matching the specified \emph on patterns \emph default are set to \emph on timeout_ms \emph default milliseconds. \end_layout \begin_layout Standard See also: all other forms of Group::add() and Group::set_timeout_millis(). \end_layout \begin_layout Subsubsection void Group::remove (const std::string& pattern, bool fwd = true) \end_layout \begin_layout Standard Removes any group or device which name matches the specified pattern. \end_layout \begin_layout Standard The \emph on pattern \emph default parameter can be a group name, a device name or a device name pattern (e.g domain_*/family/member_*). \end_layout \begin_layout Standard Since we can have groups with the same name in the hierarchy, a group name can be fully qualified to specify which group should be removed. Considering the following group: \end_layout \begin_layout LyX-Code -> gauges \end_layout \begin_layout LyX-Code | -> cell-01 \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | -> cell-02 \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | -> cell-03 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | \end_layout \begin_layout LyX-Code | -> ... \end_layout \begin_layout Standard A call to gauges->remove("penning") will remove any group named "penning" in the hierarchy while gauges->remove("gauges.cell-02.penning") will only remove the specified group. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the remove request is also forwarded to subgroups. Otherwise, it is only applied to the local set of elements. For instance, the following code remove any stepper motor in the hierarchy: \end_layout \begin_layout LyX-Code root_group->remove("*/stepper_motor/*"); \end_layout \begin_layout Standard See also: all other forms of Group::remove(). \end_layout \begin_layout Subsubsection void Group::remove (const std::vector& patterns, bool fwd = true) \end_layout \begin_layout Standard Removes any group or device which name matches the specified patterns. \end_layout \begin_layout Standard The \emph on patterns \emph default parameter can be an array of group names and/or device names and/or device name patterns. \end_layout \begin_layout Standard Since we can have groups with the same name in the hierarchy, a group name can be fully qualified to specify which group should be removed. See previous method for details. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the remove request is also forwarded to subgroups. Otherwise, it is only applied to the local set of elements. \end_layout \begin_layout Standard See also: all other forms of Group::remove(). \end_layout \begin_layout Subsubsection void Group::remove_all (void) \end_layout \begin_layout Standard Removes all elements in the group. After such a call, the group is empty. \end_layout \begin_layout Standard See also: all forms of Group::remove(). \end_layout \begin_layout Subsubsection bool Group::contains (const std::string& pattern, bool fwd = true) \end_layout \begin_layout Standard Returns true if the hierarchy contains groups and/or devices which name matches the specified \emph on pattern \emph default . Returns false otherwise. \end_layout \begin_layout Standard The pattern can be a fully qualified or simple group name, a device name or a device name pattern. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of elements. \end_layout \begin_layout Standard See also: Group::get_device(), Group::get_group(). \end_layout \begin_layout Subsubsection DeviceProxy* Group::get_device (const std::string& device_name) \end_layout \begin_layout Standard Returns a reference to the specified device or NULL if there is no device by that name in the group. This method may throw an exception in case the specified device belongs to the group but can't be reached (not registered, down...). See example below. See also the Tango::DeviceProxy class documentation for details. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent try \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code Tango::DeviceProxy *dp = g->get_device("my/device/01"); \end_layout \begin_layout LyX-Code if (dp == 0) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // my/device/01 doe snot belongs to the group \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code catch (const Tango::DevFailed &df) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code // my/device/01 belongs to the group but can't be reached \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The request is systematically forwarded to subgroups (i.e. if no device named device_name could be found in the local set of devices, the request is forwarded to subgroups). \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a DeviceProxy returned by the \emph on Group::get_device() \emph default method. Use the \emph on Tango::Group::remove() \emph default method instead. \end_layout \begin_layout Standard See also: other form of Group::get_device(), Group::get_size(), Group::get_group (), Group::contains(). \end_layout \begin_layout Subsubsection DeviceProxy* Group::get_device (long idx) \end_layout \begin_layout Standard Returns a reference to the "idx-th" device in the hierarchy or NULL if the hierarchy contains less than " \emph on idx \emph default " devices. This method may throw an exception in case the specified device belongs to the group but can't be reached (not registered, down...). See previous example. See also the Tango::DeviceProxy class documentation for details. \end_layout \begin_layout Standard The request is systematically forwarded to subgroups (i.e. if the local set of devices contains less than "idx" devices, the request is forwarded to subgroups). \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a DeviceProxy returned by the \emph on Group::get_device() \emph default method. Use the \emph on Tango::Group::remove() \emph default method instead. \end_layout \begin_layout Standard See also: other form of Group::get_device(), Group::get_size(), Group::get_group , Group::contains(). \end_layout \begin_layout Subsubsection DeviceProxy* Group::operator[] (long i) \end_layout \begin_layout Standard Returns a reference to the "idx-th" device in the hierarchy or NULL if the hierarchy contains less than "idx" devices. See the Tango::DeviceProxy class documentation for details. \end_layout \begin_layout Standard The request is systematically forwarded to subgroups (i.e. if the local set of devices contains less than "idx" devices, the request is forwarded to subgroups). \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a DeviceProxy returned by the \emph on Group::get_device() \emph default method. Use the \emph on Tango::Group::remove() \emph default method instead. \end_layout \begin_layout Standard See also: other form of Group::get_device(), Group::get_size(), Group::get_group (), Group::contains(). \end_layout \begin_layout Subsubsection Group* Group::get_group (const std::string& group_name) \end_layout \begin_layout Standard Returns a reference to the specified group or NULL if there is no group by that name. The group_name can be a fully qualified name. \end_layout \begin_layout Standard Considering the following group: \end_layout \begin_layout LyX-Code -> gauges \end_layout \begin_layout LyX-Code |-> cell-01 \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code |-> cell-02 \end_layout \begin_layout LyX-Code | |-> penning \end_layout \begin_layout LyX-Code | | |-> ... \end_layout \begin_layout LyX-Code | |-> pirani \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | -> cell-03 \end_layout \begin_layout LyX-Code | |-> ... \end_layout \begin_layout LyX-Code | \end_layout \begin_layout LyX-Code | -> ... \end_layout \begin_layout Standard A call to gauges->get_group("penning") returns the first group named "penning" in the hierarchy (i.e. gauges.cell-01.penning) while gauges->get_group("gauges.cell-02.penning \begin_inset Quotes erd \end_inset ) returns the specified group. \end_layout \begin_layout Standard The request is systematically forwarded to subgroups (i.e. if no group named group_name could be found in the local set of elements, the request is forwarded to subgroups). \end_layout \begin_layout Standard Be aware that a group always gets the ownership of its children and deletes them when it is itself deleted. Therefore, never try to delete a Group returned by the \emph on Group::get_group() \emph default method. Use the \emph on Tango::Group::remove() \emph default method instead. \end_layout \begin_layout Standard See also: Group::get_device(), Group::contains(). \end_layout \begin_layout Subsubsection long Group::get_size (bool fwd = true) \end_layout \begin_layout Standard Return the number of devices in the hierarchy (respectively the number of device in the group) if the forward option is set to true (respectively set to false). \end_layout \begin_layout Subsubsection std::vector Group::get_device_list (bool fwd = true) \end_layout \begin_layout Standard Returns the list of devices currently in the hierarchy. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) the request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Considering the following hierarchy: \end_layout \begin_layout LyX-Code g2->add("my/device/04"); g2->add("my/device/05"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g4->add("my/device/08"); g4->add("my/device/09"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g3->add("my/device/06"); \end_layout \begin_layout LyX-Code g3->addg(g4); \end_layout \begin_layout LyX-Code g3->add("my/device/07"); \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code g1->add("my/device/01"); \end_layout \begin_layout LyX-Code g1->add(g2); \end_layout \begin_layout LyX-Code g1->add("my/device/03"); \end_layout \begin_layout LyX-Code g1->add(g3); \end_layout \begin_layout LyX-Code g1->add("my/device/02"); \end_layout \begin_layout Standard The returned vector content depends on the value of the forward option. If set to true, the results will be organized as follows: \end_layout \begin_layout LyX-Code std::vector dl = g1->get_device_list(true); \end_layout \begin_layout Standard \emph on dl[0] \emph default contains "my/device/01" which belongs to g1 \begin_inset Newline newline \end_inset \emph on dl[1] \emph default contains "my/device/04" which belongs to g1.g2 \begin_inset Newline newline \end_inset \emph on dl[2] \emph default contains "my/device/05" which belongs to g1.g2 \begin_inset Newline newline \end_inset \emph on dl[3] \emph default contains "my/device/03" which belongs to g1 \begin_inset Newline newline \end_inset \emph on dl[4] \emph default contains "my/device/06" which belongs to g1.g3 \begin_inset Newline newline \end_inset \emph on dl[5] \emph default contains "my/device/08" which belongs to g1.g3.g4 \begin_inset Newline newline \end_inset \emph on dl[6] \emph default contains "my/device/09" which belongs to g1.g3.g4 \begin_inset Newline newline \end_inset \emph on dl[7] \emph default contains "my/device/07" which belongs to g1.g3 \begin_inset Newline newline \end_inset \emph on dl[8] \emph default contains "my/device/02" which belongs to g1 \end_layout \begin_layout Standard If the forward option is set to false, the results are: \end_layout \begin_layout LyX-Code std::vector dl = g1->get_device_list(false); \end_layout \begin_layout Standard \emph on dl[0] \emph default contains "my/device/01" which belongs to g1 \begin_inset Newline newline \end_inset \emph on dl[1] \emph default contains "my/device/03" which belongs to g1 \begin_inset Newline newline \end_inset \emph on dl[2] \emph default contains "my/device/02" which belongs to g1 \end_layout \begin_layout Subsection "A la" DeviceProxy Methods \end_layout \begin_layout Subsubsection bool Group::ping (bool fwd = true) \end_layout \begin_layout Standard Ping all devices in a group. This method returns true if all devices in the group are alive, false otherwise. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Subsubsection void Group::set_timeout_millis(int timeout_ms) \end_layout \begin_layout Standard Set client side timeout for all devices composing the group in milliseconds. Any method which takes longer than this time to execute will throw an exception. \end_layout \begin_layout Standard \emph on Exception: none (errors are ignored). \end_layout \begin_layout Subsubsection GroupCmdReplyList Group::command_inout (const std::string& c, bool fwd = true) \end_layout \begin_layout Standard Executes a Tango command on a group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Command results are returned in a GroupCmdReplyList. See Obtaining command result for details ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Obt-cmd-results" \end_inset ). See also Case 1 of executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-1" \end_inset ) for an example. \end_layout \begin_layout Subsubsection GroupCmdReplyList Group::command_inout (const std::string& c, const DeviceData& d, bool fwd = true) \end_layout \begin_layout Standard Executes a Tango command on each device in the group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard The second parameter \emph on d \emph default is a Tango generic container for command carrying the command argument. See the Tango::DeviceData documentation. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Command results are returned in a GroupCmdReplyList. See Obtaining command results ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Obt-cmd-results" \end_inset ) for details. See also Case 2 of executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-2" \end_inset ) for an example. \end_layout \begin_layout Subsubsection template GroupCmdReplyList Group::command_inout (const std::string& c, const std::vector& d, bool fwd = true) \end_layout \begin_layout Standard Executes a Tango command on each device in the group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard This implementation of command_inout allows passing a specific input argument to each device in the group. In order to use this form of command_inout, the user must have an "a priori" and "perfect" knowledge of the devices order in the group. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard The std::vector \emph on d \emph default contains a specific argument value for each device in the group. Since this method is a template, d is able to contain any Tango command argument type. Its size must equal Group::get_size(fwd). Otherwise, an exception is thrown. The order of the argument values must follows the order of the devices in the group (d[0] => 1st device, d[1] => 2nd device and so on). \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Command results are returned in a GroupCmdReplyList. See Obtaining command results ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Obt-cmd-results" \end_inset ) for details. See also Case 3 of executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-3" \end_inset ) for an example of this special form of command_inout. \end_layout \begin_layout Subsubsection long Group::command_inout_asynch (const std::string& c, bool fgt = false, bool fwd = true, long rsv = -1) \end_layout \begin_layout Standard Executes a Tango command on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::command_inout_reply() \emph default to obtain the results. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard The parameter \emph on fgt \emph default is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller does not care about it and will not even try to get it). A false default value is provided. \end_layout \begin_layout Standard If the parameter \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Finally, \emph on rsv \emph default is reserved for internal purpose and should not be modify. This parameter may disappear in a near future. \end_layout \begin_layout Standard See Case 1 of Executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-1" \end_inset ) for an example. \end_layout \begin_layout Subsubsection long Group::command_inout_asynch (const std::string& c, const DeviceData& d, bool fgt = false, bool fwd = true, long rsv = -1) \end_layout \begin_layout Standard Executes a Tango command on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::command_inout_reply() \emph default to obtain the results. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard The second parameter \emph on d \emph default is a Tango generic container for command carrying the command argument. See the Tango::DeviceData documentation for details. \end_layout \begin_layout Standard The parameter \emph on fgt \emph default is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller does not care about it and will not even try to get it). A false default value is provided. \end_layout \begin_layout Standard If the parameter \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Finally, \emph on rsv \emph default is reserved for internal purpose and should not be modify. This parameter may disappear in a near future. \end_layout \begin_layout Standard See Case 2 of Executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-2" \end_inset ) for an example. \end_layout \begin_layout Subsubsection long Group::command_inout_asynch (const std::string& c, const std::vector& d, fgt = false, bool fwd = true) \end_layout \begin_layout Standard Executes a Tango command on each device in the group asynchronously. The method send the request to all devices and return immediately. Pass the returned request id to Group::command_inout_reply to obtain the results. \end_layout \begin_layout Standard This implementation of command_inout allows passing a specific input argument to each device in the group. In order to use this form of command_inout_asynch, the user must have an "a priori" and "perfect" knowledge of the devices order in the group. \end_layout \begin_layout Standard The parameter \emph on c \emph default is the name of the command. \end_layout \begin_layout Standard The std::vector \emph on d \emph default contains a specific argument value for each device in the group. d is able to contain any Tango command argument type. Its size must equal Group::get_size(fwd). Otherwise, an exception is thrown. The order of the argument values must follows the order of the devices in the group (d[0] => 1st device, d[1] => 2nd device and so on). \end_layout \begin_layout Standard The parameter \emph on fgt \emph default is a fire and forget flag. If set to true, it means that no reply is expected (i.e. the caller does not care about it and will not even try to get it). A false default value is provided. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default), the request is also forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard See Case 3 of Executing a command ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-3" \end_inset ) for an example of this special form of command_inout. \end_layout \begin_layout Subsubsection GroupCmdReplyList Group::command_inout_reply (long req_id, long timeout_ms = 0) \end_layout \begin_layout Standard Returns the results of an asynchronous command. \end_layout \begin_layout Standard The first parameter \emph on req_id \emph default is a request identifier previously returned by one of the command_inout_asynch methods. \end_layout \begin_layout Standard For each device in the hierarchy, if the command result is not yet available, command_inout_reply wait \emph on timeout_ms \emph default milliseconds before throwing an exception. This exception will be part of the global reply. If \emph on timeout_ms \emph default is set to 0, command_inout_reply waits "indefinitely". \end_layout \begin_layout Standard Command results are returned in a GroupCmdReplyList. See Obtaining command results ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Obt-cmd-results" \end_inset ) for details. \end_layout \begin_layout Subsubsection GroupAttrReplyList Group::read_attribute (const std::string& a, bool fwd = true) \end_layout \begin_layout Standard Reads an attribute on each device in the group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard The parameter \emph on a \emph default is the name of the attribute to read. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Attribute values are returned in a GroupAttrReplyList. See Obtaining attribute values ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-attr-values" \end_inset ) for details. See also Reading an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Read-attr" \end_inset ) for an example. \end_layout \begin_layout Subsubsection long Group::read_attribute_asynch (const std::string& a, bool fwd = true, long rsv = -1) \end_layout \begin_layout Standard Reads an attribute on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::read_attribute_reply() \emph default to obtain the results. \end_layout \begin_layout Standard The parameter \emph on a \emph default is the name of the attribute to read. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard The last parameter (rsv) is reserved for internal purpose and should not be modify. It may disappear in a near future. \end_layout \begin_layout Standard See Reading an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Read-attr" \end_inset ) for an example. \end_layout \begin_layout Subsubsection GroupAttrReplyList Group::read_attribute_reply (long req_id, long timeout_ms = 0) \end_layout \begin_layout Standard Returns the results of an asynchronous attribute reading. \end_layout \begin_layout Standard The first parameter \emph on req_id \emph default is a request identifier previously returned by read_attribute_asynch. \end_layout \begin_layout Standard For each device in the hierarchy, if the attribute value is not yet available, read_attribute_reply wait \emph on timeout_ms \emph default milliseconds before throwing an exception. This exception will be part of the global reply. If \emph on timeout_ms \emph default is set to 0, read_attribute_reply waits "indefinitely". \end_layout \begin_layout Standard Replies are returned in a GroupAttrReplyList. See Obtaining attribute values ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-attr-values" \end_inset ) for details. \end_layout \begin_layout Subsubsection GroupReplyList Group::write_attribute (const DeviceAttribute& d, bool fwd = true) \end_layout \begin_layout Standard Writes an attribute on each device in the group. This method is synchronous and does not return until acknowledgements are obtained or timeouts occurred. \end_layout \begin_layout Standard The first parameter \emph on d \emph default is a Tango generic container for attribute carrying both the attribute name and the value. See the Tango::DeviceAttribute documentation for details. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-ack" \end_inset ) for details. See also Case 1 of Writing an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-1-writing" \end_inset ) for an example. \end_layout \begin_layout Subsubsection GroupReplyList Group::write_attribute (const std::string& a, const std::vector& d, bool fwd = true) \end_layout \begin_layout Standard Writes an attribute on each device in the group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard This implementation of write_attribute allows writing a specific value to each device in the group. In order to use this form of write_attribute, the user must have an "a priori" and "perfect" knowledge of the devices order in the group. \end_layout \begin_layout Standard The parameter \emph on a \emph default is the name of the attribute. \end_layout \begin_layout Standard The std::vector \emph on d \emph default contains a specific value for each device in the group. Since this method is a template, d is able to contain any Tango attribute type. Its size must equal \emph on Group::get_size(fwd) \emph default . Otherwise, an exception is thrown. The order of the attribute values must follows the order of the devices in the group (d[0] => 1st device, d[1] => 2nd device and so on). \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-ack" \end_inset ) for details. See also Case 2 of Writing an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-2-writing" \end_inset ) for an example. \end_layout \begin_layout Subsubsection long Group::write_attribute_asynch (const DeviceAttribute& d, bool fwd = true, long rsv = -1) \end_layout \begin_layout Standard Writes an attribute on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::write_attribute_reply() \emph default to obtain the acknowledgements. \end_layout \begin_layout Standard The first parameter \emph on d \emph default is a Tango generic container for attribute carrying both the attribute name and the value. See the Tango::DeviceAttribute documentation for details. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard The last parameter \emph on rsv \emph default is reserved for internal purpose and should not be modify. It may disappear in a near future. \end_layout \begin_layout Standard See Case 1 of Writing an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-1-writing" \end_inset ) for an example. \end_layout \begin_layout Subsubsection long Group::write_attribute_asynch (const std::string& a, const std::vector& d, bool fwd = true) \end_layout \begin_layout Standard Writes an attribute on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::write_attribute_reply() \emph default to obtain the acknowledgements. \end_layout \begin_layout Standard This implementation of write_attribute_asynch allows writing a specific value to each device in the group. In order to use this form of write_attribute_asynch, the user must have an "a priori" and "perfect" knowledge of the devices order in the group. \end_layout \begin_layout Standard The parameter \emph on a \emph default is the name of the attribute. \end_layout \begin_layout Standard The std::vector \emph on d \emph default contains a specific value for each device in the group. Since this method is a template, d is able to contain any Tango attribute type. Its size must equal \emph on Group::get_size(fwd) \emph default . Otherwise, an exception is thrown. The order of the attribute values must follows the order of the devices in the group (d[0] => 1st device, d[1] => 2nd device and so on). \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard See Case2 of Writing an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Case-2-writing" \end_inset ) for an example. \end_layout \begin_layout Subsubsection GroupReplyList Group::write_attribute_reply (long req_id, long timeout_ms = 0) \end_layout \begin_layout Standard Returns the acknowledgements of an asynchronous attribute writing. \end_layout \begin_layout Standard The first parameter \emph on req_id \emph default is a request identifier previously returned by one of the write_attribute_async h implementation. \end_layout \begin_layout Standard For each device in the hierarchy, if the acknowledgement is not yet available, write_attribute_reply wait \emph on timeout_ms \emph default milliseconds before throwing an exception. This exception will be part of the global reply. If \emph on timeout_ms \emph default is set to 0, write_attribute_reply waits "indefinitely". \end_layout \begin_layout Standard Acknowledgements are returned in a GroupReplyList. See Obtaining acknowledgements \begin_inset CommandInset ref LatexCommand ref reference "sub:O-ack" \end_inset for details. \end_layout \begin_layout Subsubsection GroupAttrReplyList Group::read_attributes (const std::vector& al, bool fwd = true) \end_layout \begin_layout Standard Reads several attributes on each device in the group. This method is synchronous and does not return until replies are obtained or timeouts occurred. \end_layout \begin_layout Standard The parameter \emph on al \emph default is a vector containing the name of the attributes to be read. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard Attribute values are returned in a GroupAttrReplyList. See Obtaining attribute values ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-attr-values" \end_inset ) for details. See also Reading an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Read-attr" \end_inset ) for an example. The order of attribute value returned in the GroupAttrReplyList is all attributes for first element in the group followed by all attributes for the second group element and so on. \end_layout \begin_layout Subsubsection long Group::read_attributes_asynch (const std::vector& al, bool fwd = true, long rsv = -1) \end_layout \begin_layout Standard Reads several attributes on each device in the group asynchronously. The method sends the request to all devices and returns immediately. Pass the returned request id to \emph on Group::read_attributes_reply() \emph default to obtain the results. \end_layout \begin_layout Standard The parameter \emph on al \emph default is a vector containing the name of the attributes to be read. \end_layout \begin_layout Standard If \emph on fwd \emph default is set to true (the default) request is forwarded to subgroups. Otherwise, it is only applied to the local set of devices. \end_layout \begin_layout Standard The last parameter (rsv) is reserved for internal purpose and should not be modify. It may disappear in a near future. \end_layout \begin_layout Standard See Reading an attribute ( \begin_inset CommandInset ref LatexCommand ref reference "sub:Read-attr" \end_inset ) for an example. \end_layout \begin_layout Subsubsection GroupAttrReplyList Group::read_attributes_reply (long req_id, long timeout_ms = 0) \end_layout \begin_layout Standard Returns the results of an asynchronous attribute reading. \end_layout \begin_layout Standard The first parameter \emph on req_id \emph default is a request identifier previously returned by read_attributes_asynch. \end_layout \begin_layout Standard For each device in the hierarchy, if the attribute value is not yet available, read_attributes_reply wait \emph on timeout_ms \emph default milliseconds before throwing an exception. This exception will be part of the global reply. If \emph on timeout_ms \emph default is set to 0, read_attributes_reply waits "indefinitely". \end_layout \begin_layout Standard Replies are returned in a GroupAttrReplyList. See Obtaining attribute values ( \begin_inset CommandInset ref LatexCommand ref reference "sub:O-attr-values" \end_inset ) for details. The order of attribute value returned in the GroupAttrReplyList is all attributes for first element in the group followed by all attributes for the second group element and so on. \end_layout \begin_layout LyX-Code \end_layout \begin_layout Section \noindent Tango::Database \end_layout \begin_layout Standard \noindent A high level object which contains the link to the database. It has methods for all database commands e.g. get_device_property(), device_list(), info(), etc. \end_layout \begin_layout Subsection \noindent Database::Database() \end_layout \begin_layout Standard \noindent Create a TANGO Database object. The constructor uses the environment variable \begin_inset Quotes eld \end_inset TANGO_HOST \begin_inset Quotes erd \end_inset to determine which instance of the TANGO database to connect to. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent using namespace Tango; \end_layout \begin_layout LyX-Code \noindent Database *db = new Database(); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard The Database class also has a copy constructor and one assignement operator defined. \end_layout \begin_layout Subsection \noindent string Database::get_info() \end_layout \begin_layout Standard \noindent Query the database for some general info about the tables in the database. Result is returned as a string. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent cout << db->get_info() << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent will return information like this : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent Running since 2000-11-06 14:10:46 \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code \noindent Devices defined = 115 \end_layout \begin_layout LyX-Code \noindent Devices exported = 41 \end_layout \begin_layout LyX-Code \noindent Device servers defined = 47 \end_layout \begin_layout LyX-Code \noindent Device servers exported = 17 \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code \noindent Class properties defined = 5 \end_layout \begin_layout LyX-Code \noindent Device properties defined = 130 \end_layout \begin_layout LyX-Code \noindent Class attribute properties defined = 20 \end_layout \begin_layout LyX-Code \noindent Device attribute properties defined = 92 \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::add_device(DbDevInfo&) \end_layout \begin_layout Standard \noindent Add a device to the database. The device name, server and class are specified in the DbDevInfo structure. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDevInfo my_device_info; \end_layout \begin_layout LyX-Code \noindent my_device_info.name = \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_info._class = \begin_inset Quotes eld \end_inset MyDevice \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_info.server = \begin_inset Quotes eld \end_inset MyServer/test \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent db->add_device(my_device_info); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent void Database::delete_device(string) \end_layout \begin_layout Standard \noindent Delete the device of the specified name from the database. Example \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent db->delete_device( \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError, DB_DeviceNotDefined) \end_layout \begin_layout Subsection \noindent DbDevImportInfo Database::import_device(string &) \end_layout \begin_layout Standard \noindent Query the database for the export info of the specified device. The command returns the information in a DbDevImportInfo structure. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDevImportInfo my_device_import; \end_layout \begin_layout LyX-Code \noindent my_device_import = db->import_device( \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \noindent cout << \begin_inset Quotes eld \end_inset device \begin_inset Quotes erd \end_inset << my_device_import.name; \end_layout \begin_layout LyX-Code \noindent cout << \begin_inset Quotes eld \end_inset exported \begin_inset Quotes erd \end_inset << my_device_import.exported; \end_layout \begin_layout LyX-Code \noindent cout << \begin_inset Quotes eld \end_inset ior \begin_inset Quotes erd \end_inset << my_device_import.ior; \end_layout \begin_layout LyX-Code \noindent cout << \begin_inset Quotes eld \end_inset version \begin_inset Quotes erd \end_inset << my_device_import.version; \end_layout \begin_layout LyX-Code \noindent cout << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device ( DB_SQLError, DB_DeviceNotDefined) \end_layout \begin_layout Subsection \noindent void Database::export_device(DbDevExportInfo&) \end_layout \begin_layout Standard \noindent Update the export info for this device in the database. Device name, server, class, pid and version are specified in the DbDevExportInf o structure. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDevExportInfo my_device_export; \end_layout \begin_layout LyX-Code \noindent my_device_export.name = \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_export.ior = \begin_inset Quotes eld \end_inset the real ior \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_export.host = \begin_inset Quotes eld \end_inset dumela \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_export.version = \begin_inset Quotes eld \end_inset 1.0 \begin_inset Quotes erd \end_inset ; \end_layout \begin_layout LyX-Code \noindent my_device_export.pid = get_pid(); \end_layout \begin_layout LyX-Code \noindent db->export_device(my_device_export); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError, DB_DeviceNotDefined) \end_layout \begin_layout Subsection \noindent void Database::unexport_device(string) \end_layout \begin_layout Standard \noindent Mark the specified device as un-exported in the database. Example : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent db->unexport_device( \begin_inset Quotes eld \end_inset my/own/device \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::add_server(string &, DbDevInfos&) \end_layout \begin_layout Standard \noindent Add a group of devices to the database. The device names, server names and classes are specified in the vector of DbDevInfo structures. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_server(string &) \end_layout \begin_layout Standard \noindent Delete the device server and its associated devices from the database. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::export_server( DbDevExportInfos &) \end_layout \begin_layout Standard \noindent Export a group of devices to the database. The device names, IOR, class, server name, pid etc. are specified in the vector of DbDevExportInfo structures. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::unexport_server(string &) \end_layout \begin_layout Standard \noindent Mark all devices exported for this server as unexported. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection DbDatum Database::get_services(string &servicename,string &instname) \end_layout \begin_layout Standard Query database for specified services.The instname parameter can be a wildcard character ("*"). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string servicename("HdbManager"); \end_layout \begin_layout LyX-Code string instname("ctrm"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_services(servicename,instname); \end_layout \begin_layout LyX-Code vector service_list; \end_layout \begin_layout LyX-Code db_datum >> service_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection void Database::register_service(string &servicename,string &instname,string &devname) \end_layout \begin_layout Standard Register the specified service wihtin the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string servicename("HdbManager"); \end_layout \begin_layout LyX-Code string instname("ctrm"); \end_layout \begin_layout LyX-Code string devname("sys/hdb/1"); \end_layout \begin_layout LyX-Code db->register_service(servicename,instname,devname); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection void Database::unregister_service(string &servicename,string &instname) \end_layout \begin_layout Standard Unregister the specified service from the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string servicename("HdbManager"); \end_layout \begin_layout LyX-Code string instname("ctrm"); \end_layout \begin_layout LyX-Code db->unregister_service(servicename,instname); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_host_list() \end_layout \begin_layout Standard Returns the list of all host names registered in the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_host_list(); \end_layout \begin_layout LyX-Code vector host_list; \end_layout \begin_layout LyX-Code db_datum >> host_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_host_list(string &wildcard) \end_layout \begin_layout Standard Returns the list of all host names registered in the database which match the specified wildcard (eg: "l-c0*"). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string wildcard("l-c0*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_host_list(wildcard); \end_layout \begin_layout LyX-Code vector host_list; \end_layout \begin_layout LyX-Code db_datum >> host_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_server_class_list(string &server) \end_layout \begin_layout Standard Query the database for a list of classes instancied by the specified server. The DServer class exists in all TANGO servers and for this reason this class is removed from the returned list. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string server("Serial/1"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_server_class_list(server); \end_layout \begin_layout LyX-Code vector class_list; \end_layout \begin_layout LyX-Code db_datum >> class_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_server_name_list() \end_layout \begin_layout Standard Return the list of all server names registered in the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_server_name_list(); \end_layout \begin_layout LyX-Code vector server_list; \end_layout \begin_layout LyX-Code db_datum >> server_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_instance_name_list(string &servername) \end_layout \begin_layout Standard Return the list of all instance names existing in the database for the specifed server. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string servername("Serial"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_instance_name_list(servername); \end_layout \begin_layout LyX-Code vector instance_list; \end_layout \begin_layout LyX-Code db_datum >> instance_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_server_list() \end_layout \begin_layout Standard Return the list of all servers registered in the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_server_list(); \end_layout \begin_layout LyX-Code vector server_list; \end_layout \begin_layout LyX-Code db_datum >> server_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_server_list(string &wildcard) \end_layout \begin_layout Standard Return the list of all servers registered in the database which match the specified wildcard (eg: "Serial/*"). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string wildcard("Serial/*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_server_list(wildcard); \end_layout \begin_layout LyX-Code vector server_list; \end_layout \begin_layout LyX-Code db_datum >> server_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_host_server_list(string &hostname) \end_layout \begin_layout Standard Query the database for a list of servers registred on the specified host. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string host("kidiboo"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_host_server_list(wildcard); \end_layout \begin_layout LyX-Code vector server_list; \end_layout \begin_layout LyX-Code db_datum >> server_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbServerInfo Database::get_server_info(string &server) \end_layout \begin_layout Standard Query the database for server information. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string server("Serial/1"); \end_layout \begin_layout LyX-Code DbServerInfo info = db->get_server_info(server); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection void Database::put_server_info(DbServerInfo &info) \end_layout \begin_layout Standard Add/update server information in the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code DbServerInfo info; \end_layout \begin_layout LyX-Code info.name = "Serial/1"; // Server (name/instance) \end_layout \begin_layout LyX-Code info.host = "kidiboo"; // Register on host kidiboo \end_layout \begin_layout LyX-Code info.mode = 1; // Controlled by Astor flag (0 or 1) \end_layout \begin_layout LyX-Code info.level = 3; // Startup level (Used by Astor) \end_layout \begin_layout LyX-Code db->put_server_info(info); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection void Database::delete_server_info(string &server) \end_layout \begin_layout Standard Delete server information of the specifed server from the database. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string server("Serial/1"); \end_layout \begin_layout LyX-Code db->delete_server_info(server); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent DbDatum Database::get_device_name(string &, string &) \end_layout \begin_layout Standard \noindent Query the database for a list of devices served by the specified server (1st parameter) and of the specified class (2nd parameter). The method returns a DbDatum type. The device names are stored as an array of strings. Here is two code example of how to extract the names from the DbDatum type : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent vector device_names; \end_layout \begin_layout LyX-Code \noindent device_names << db_datum; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent or : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent for (int i=0; i< db_datum.size(); i++) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent device_name[i] = db_datum.value_string[i]; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent DbDatum Database::get_device_exported(string &) \end_layout \begin_layout Standard \noindent Query the database for a list of exported devices whose names satisfy the supplied filter (* is wildcard for any character(s)). This method returns a DbDatum type. See the method get_device_name() for an example of how to extract the list of aliases from the DbDatum type. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent DbDatum Database::get_device_domain(string &) \end_layout \begin_layout Standard \noindent Query the database for a list of device domain names which match the wildcard provided. Wildcard character is * and matches any number of characters. Domain names are case insensitive. This method returns a DbDatum type. See the method get_device_name() for an example of how to extract the list of aliases from the DbDatum type. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent DbDatum Database::get_device_family(string &) \end_layout \begin_layout Standard \noindent Query the database for a list of device family names which match the wildcard provided. Wildcard character is * and matches any number of characters. Family names are case insensitive. This method returns a DbDatum type. See the method get_device_name() for an example of how to extract the list of aliases from the DbDatum type. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent DbDatum Database::get_device_member(string &) \end_layout \begin_layout Standard \noindent Query the database for a list of device member names which match the wildcard provided. Wildcard characters is * and matches any number of characters. Member names are case insensitive. This method returns a DbDatum type. See the method get_device_name() for an example of how to extract the list of aliases from the DbDatum type. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection DbDatum Database::get_device_class_list(string &server) \end_layout \begin_layout Standard Query the database for a list of devices and classes served by the specified server. Return a list with the following structure: {device name,class name,device name,class name,...} \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string server("Serial/1"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_device_class_list(server); \end_layout \begin_layout LyX-Code vector dev_list; \end_layout \begin_layout LyX-Code db_datum >> dev_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection string Database::get_class_for_device(string &devname) \end_layout \begin_layout Standard Return the class of the specified device. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string devname("sr/rf-cavity/1"); \end_layout \begin_layout LyX-Code string classname = db->get_class_for_device(devname); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_class_inheritance_for_device(string &devname) \end_layout \begin_layout Standard Return the class inheritance scheme of the specified device. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string devname("sr/rf-cavity/1"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_class_inheritance_for_device(devname); \end_layout \begin_layout LyX-Code vector class_list; \end_layout \begin_layout LyX-Code db_datum >> class_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_device_exported_for_class(string &classname) \end_layout \begin_layout Standard Query database for list of exported devices for the specified class. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string classname("MyClass"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_device_exported_for_class(classname); \end_layout \begin_layout LyX-Code vector dev_list; \end_layout \begin_layout LyX-Code db_datum >> dev_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_object_list(string &wildcard) \end_layout \begin_layout Standard Query the database for a list of object (free properties) for which properties are defined and which match the specified wildcard. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string wildcard("Optic*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_object_list(wildcard); \end_layout \begin_layout LyX-Code vector obj_list; \end_layout \begin_layout LyX-Code db_datum >> obj_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_object_property_list(string &objectname,string &wildcard) \end_layout \begin_layout Standard Query the database for a list of properties defined for the specified object and which match the specified wildcard. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string objname("OpticID9"); \end_layout \begin_layout LyX-Code string wildcard("Delta*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_object_property_list(objname,wildcard); \end_layout \begin_layout LyX-Code vector prop_list; \end_layout \begin_layout LyX-Code db_datum >> prop_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent void Database::get_property(string, DbData&) \end_layout \begin_layout Standard \noindent Query the database for a list of object (i.e. non-device) properties for the specified object. The property names are specified by the vector of DbDatum structures. The method returns the properties in the same DbDatum structures. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData type to specify and extract properties : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db->get_property( \begin_inset Quotes eld \end_inset mymotor \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout LyX-Code \noindent float velocity, acceleration; \end_layout \begin_layout LyX-Code \noindent db_data[0] >> velocity; \end_layout \begin_layout LyX-Code \noindent db_data[1] >> acceleration; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::put_property(string, DbData&) \end_layout \begin_layout Standard \noindent Insert or update a list of properties for the specified object. The property names and their values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum structures. Here is an example of how to insert properties into the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum velocity( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset ), acceleration( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent velocity << 100000.0; \end_layout \begin_layout LyX-Code \noindent acceleration << 500000.0; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(velocity); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acceleration); \end_layout \begin_layout LyX-Code \noindent db->put_property( \begin_inset Quotes eld \end_inset mymotor \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_property(string, DbData&) \end_layout \begin_layout Standard \noindent Delete a list of properties for the specified object. The property names are specified by the vector of DbDatum structures. Here is an example of how to delete properties from the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db->delete_property( \begin_inset Quotes eld \end_inset mymotor \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection vector Database::get_property_history(string &objname, string &propname) \end_layout \begin_layout Standard Get the list of the last 10 modifications of the specifed object property. Note that propname can contain a wildcard character (eg: "prop*"). \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code vector hist; \end_layout \begin_layout LyX-Code DbDatum result; \end_layout \begin_layout LyX-Code string objname("jlptest"); \end_layout \begin_layout LyX-Code string propname("test_prop"); \end_layout \begin_layout LyX-Code hist = db->get_property_history(objname,propname); \end_layout \begin_layout LyX-Code // Print the modification history of the specified property \end_layout \begin_layout LyX-Code for(int i=0;i> result; \end_layout \begin_layout LyX-Code for (int j=0; j>. Here is an example of how to use the DbData type to specify and extract properties : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db->get_device_property( \begin_inset Quotes eld \end_inset id11/motor/1 \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout LyX-Code \noindent float velocity, acceleration; \end_layout \begin_layout LyX-Code \noindent db_data[0] >> velocity; \end_layout \begin_layout LyX-Code \noindent db_data[1] >> acceleration; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::put_device_property(string, DbData&) \end_layout \begin_layout Standard \noindent Insert or update a list of properties for the specified device. The property names and their values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum structures. Here is an example of how to insert properties into the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum velocity( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset ), acceleration( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset ); \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent velocity << 100000.0; \end_layout \begin_layout LyX-Code \noindent acceleration << 500000.0; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(velocity); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acceleration); \end_layout \begin_layout LyX-Code \noindent db->put_device_property( \begin_inset Quotes eld \end_inset id11/motor/1 \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_device_property(string, DbData&) \end_layout \begin_layout Standard \noindent Delete a list of properties for the specified device. The property names are specified by the vector of DbDatum structures. Here is an example of how to delete properties from the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset velocity \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum( \begin_inset Quotes eld \end_inset acceleration \begin_inset Quotes erd \end_inset )); \end_layout \begin_layout LyX-Code \noindent db->delete_device_property( \begin_inset Quotes eld \end_inset id11/motor/1 \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection vector Database::get_device_property_history(string &devname, string &propname) \end_layout \begin_layout Standard Get the list of the last 10 modifications of the specifed device property. Note that propname can contain a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the documentation of the get_property_history() function. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent void Database::get_device_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Query the database for a list of device attribute properties for the specified object. The attribute names are specified by the vector of DbDatum structures. The method returns all the properties for the specified attributes. The attribute names are returned with the number of properties specified as their value. The first DbDatum element of the returned DbData vector contains the first attribute name and the first attribute property number. The following DbDatum element contains the first attribute property name and property values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData type to specify and extract attribute properties : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("acceleration")); \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code \noindent db->get_device_attribute_property("id11/motor/1", db_data); \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code float vel_max, vel_min, acc_max, acc_min; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code for (int i=0;i < db_data.size();) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code long nb_prop; \end_layout \begin_layout LyX-Code string &att_name = db_data[i].name; \end_layout \begin_layout LyX-Code db_data[i] >> nb_prop; \end_layout \begin_layout LyX-Code i++; \end_layout \begin_layout LyX-Code for (int k=0;k < nb_prop;k++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string &prop_name = db_data[i].name; \end_layout \begin_layout LyX-Code if (att_name == "velocity") \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code if (prop_name == "min") \end_layout \begin_layout LyX-Code db_data[i] >> vel_min; \end_layout \begin_layout LyX-Code else if (att_name == "max") \end_layout \begin_layout LyX-Code db_data[i] >> vel_max; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code if (prop_name == "min") \end_layout \begin_layout LyX-Code db_data[i] >> acc_min; \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code db_data[i] >> acc_max; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code i++; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::put_device_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Insert or update a list of attribute properties for the specified device. The attribute property names and their values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum structures. Here is an example of how to insert/update properties \emph on min \emph default , \emph on max \emph default for attribute \emph on velocity \emph default and properties \emph on min \emph default , \emph on max \emph default for attribute \emph on acceleration \emph default of device \emph on id11/motor/1 \emph default into the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum velocity("velocity"), vel_min("min"), vel_max("max"); \end_layout \begin_layout LyX-Code \noindent DbDatum acceleration("acceleration"), acc_min("min"), acc_max("max"); \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent velocity << 2; \end_layout \begin_layout LyX-Code \noindent vel_min << 0.0; \end_layout \begin_layout LyX-Code \noindent vel_max << 1000000.0; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(velocity); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(vel_min); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(vel_max); \end_layout \begin_layout LyX-Code \noindent acceleration << 2; \end_layout \begin_layout LyX-Code \noindent acc_min << 0.0; \end_layout \begin_layout LyX-Code \noindent acc_max << 8000000; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acceleration); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acc_min); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acc_max); \end_layout \begin_layout LyX-Code \noindent db->put_device_attribute_property( \begin_inset Quotes eld \end_inset id11/motor/1 \begin_inset Quotes erd \end_inset , db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_device_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Delete a list of attribute properties for the specified device. The attribute names are specified by the vector of DbDatum structures. Here is an example of how to delete the \emph on unit \emph default property of the \emph on velocity \emph default attribute of the \emph on id11/motor/1 \emph default device using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("unit")); \end_layout \begin_layout LyX-Code \noindent db->delete_device_attribute_property("id11/motor/1", db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection vector Database::get_device_attribute_property_history(string &devname, string &attname, string &propname) \end_layout \begin_layout Standard Get the list of the last 10 modifications of the specifed device attribute property. Note that propname and attname can contain a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the documentation of the get_property_history() function. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_class_list(string &wildcard) \end_layout \begin_layout Standard Query the database for a list of classes which match the specified wildcard. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string wildcard("Motor*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_class_list(wildcard); \end_layout \begin_layout LyX-Code vector class_list; \end_layout \begin_layout LyX-Code db_datum >> class_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_class_property_list(string &classname) \end_layout \begin_layout Standard Query the database for a list of properties defined for the specified class. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string classname("MyClass"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_class_property_list(classname); \end_layout \begin_layout LyX-Code vector prop_list; \end_layout \begin_layout LyX-Code db_datum >> prop_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent void Database::get_class_property(string, DbData&) \end_layout \begin_layout Standard \noindent Query the database for a list of class properties. The property names are specified by the vector of DbDatum structures. The method returns the properties in the same DbDatum structures. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData type to specify and extract properties : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("acceleration")); \end_layout \begin_layout LyX-Code \noindent db->get_class_property("StepperMotor", db_data); \end_layout \begin_layout LyX-Code \noindent float velocity, acceleration; \end_layout \begin_layout LyX-Code \noindent db_data[0] >> velocity; \end_layout \begin_layout LyX-Code \noindent db_data[1] >> acceleration; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::put_class_property(string, DbData&) \end_layout \begin_layout Standard \noindent Insert or update a list of properties for the specified class. The property names and their values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum structures. Here is an example of how to insert properties into the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum velocity("velocity"), acceleration("acceleration"); \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent velocity << 100000.0; \end_layout \begin_layout LyX-Code \noindent acceleration << 500000.0; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(velocity); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acceleration); \end_layout \begin_layout LyX-Code \noindent db->put_class_property("StepperMotor", db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_class_property(string, DbData&) \end_layout \begin_layout Standard \noindent Delete a list of properties for the specified class. The property names are specified by the vector of DbDatum structures. Here is an example of how to delete properties from the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("acceleration")); \end_layout \begin_layout LyX-Code \noindent db->delete_class_property("StepperMotor", db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection vector Database::get_class_property_history(string &classname, string &propname) \end_layout \begin_layout Standard Get the list of the last 10 modifications of the specifed class property. Note that propname can contain a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the documentation of the get_property_history() function. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection DbDatum Database::get_class_attribute_list(string &classname,string &wildcard) \end_layout \begin_layout Standard Query the database for a list of attributes defined for the specified class which match the specified wildcard. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code string classname("MyClass"); \end_layout \begin_layout LyX-Code string wildcard("*"); \end_layout \begin_layout LyX-Code DbDatum db_datum = db->get_class_attribute_list(classname,wildcard); \end_layout \begin_layout LyX-Code vector att_list; \end_layout \begin_layout LyX-Code db_datum >> att_list; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard Exception: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection \noindent void Database::get_class_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Query the database for a list of class attribute properties for the specified object. The attribute names are specified by the vector of DbDatum structures. The method returns all the properties for the specified attributes. The attribute names are returned with the number of properties specified as their value. The first DbDatum element of the returned DbData vector contains the first attribute name and the first attribute property number. The following DbDatum element contains the first attribute property name and property values. To retrieve the properties use the extract operator >>. Here is an example of how to use the DbData type to specify and extract attribute properties : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("acceleration")); \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code db->get_class_attribute_property("StepperMotor", db_data); \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code \noindent float vel_max, vel_min, acc_max, acc_min; \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code for (int i=0; i< db_data.size(); i++) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code long nb_prop; \end_layout \begin_layout LyX-Code string &att_name = db_data[i].name; \end_layout \begin_layout LyX-Code db_data[i] >> nb_prop; \end_layout \begin_layout LyX-Code i++; \end_layout \begin_layout LyX-Code for (int k=0;k < nb_prop;k++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code string &prop_name = db_data[i].name; \end_layout \begin_layout LyX-Code if (att_name == "velocity") \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code if (prop_name == "min") \end_layout \begin_layout LyX-Code db_data[i] >> vel_min; \end_layout \begin_layout LyX-Code else if (att_name == "max") \end_layout \begin_layout LyX-Code db_data[i] >> vel_max; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code if (prop_name == "min") \end_layout \begin_layout LyX-Code db_data[i] >> acc_min; \end_layout \begin_layout LyX-Code else \end_layout \begin_layout LyX-Code db_data[i] >> acc_max; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code i++; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::put_class_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Insert or update a list of attribute properties for the specified class. The attribute property names and their values are specified by the vector of DbDatum structures. Use the insert operator >> to insert the properties into the DbDatum structures. Here is an example of how to insert/update \emph on min \emph default , \emph on max \emph default properties for attribute \emph on velocity \emph default and \emph on min \emph default , \emph on max \emph default properties for attribute \emph on acceleration \emph default properties belonging to class \emph on StepperMotor \emph default into the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum velocity("velocity"), vel_min("min"), vel_max("max"); \end_layout \begin_layout LyX-Code \noindent DbDatum acceleration("acceleration"), acc_min("min"), acc_max("max"); \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent velocity << 2; \end_layout \begin_layout LyX-Code \noindent vel_min << 0.0; \end_layout \begin_layout LyX-Code \noindent vel_max << 1000000.0; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(velocity); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(vel_min); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(vel_max); \end_layout \begin_layout LyX-Code \noindent acceleration << 2; \end_layout \begin_layout LyX-Code \noindent acc_min << 0.0; \end_layout \begin_layout LyX-Code \noindent acc_max << 8000000; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acceleration); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acc_min); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(acc_max); \end_layout \begin_layout LyX-Code \noindent db->put_class_attribute_property("StepperMotor", db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void Database::delete_class_attribute_property(string, DbData&) \end_layout \begin_layout Standard \noindent Delete a list of attribute properties for the specified class. The attribute names are specified by the vector of DbDatum structures. All properties belonging to the listed attributes are deleted. Here is an example of how to delete the \emph on unit \emph default property of the \emph on velocity \emph default attribute of the \emph on StepperMotor \emph default class from the database using this method : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("velocity")); \end_layout \begin_layout LyX-Code \noindent db_data.push_back(DbDatum("unit")); \end_layout \begin_layout LyX-Code \noindent db->delete_class_attribute_property("StepperMotor", db_data); \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection vector Database::get_class_attribute_property_history(string &devname, string &attname, string &propname) \end_layout \begin_layout Standard Get the list of the last 10 modifications of the specifed class attribute property. Note that propname and attname can contain a wildcard character (eg: "prop*"). An example of usage of a similar function can be found in the documentation of the get_property_history() function. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device \end_layout \begin_layout Subsection void Database::get_alias(string dev_name, string &dev_alias) \end_layout \begin_layout Standard Get the device alias name from its name. The device name is specified by \emph on dev_name \emph default and the device alias name is returned in \emph on dev_alias \emph default . If there is no alias defined for the device, a DevFailed exception is thrown. \end_layout \begin_layout Standard \emph on Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device (DB_AliasNotDefined) \end_layout \begin_layout Subsection void Database::get_device_alias(string dev_alias, string &dev_name) \end_layout \begin_layout Standard \noindent Get the device name from an alias. The device alias is specified by \emph on dev_alias \emph default and the device name is returned in \emph on dev_name \emph default . If there is no device with the given alias, a DevFailed exception is thrown. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_DeviceNotDefine d) \end_layout \begin_layout Subsection void Database::get_attribute_alias(string attr_alias, string &attr_name) \end_layout \begin_layout Standard \noindent Get the full attribute name from an alias. The attribute alias is specified by \emph on attr_alias \emph default and the full attribute name is returned in \emph on attr_name \emph default . If there is no attribute with the given alias, a DevFailed exception is thrown. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void Database::put_attribute_alias(string &att_name, string &alias_name) \end_layout \begin_layout Standard Set an alias for an attribute name. The attribute alias is specified by alias_name and the attribute name is specifed by att_name. If the given alias already exists, a DevFailed exception is thrown. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void Database::delete_attribute_alias(string &alias_name) \end_layout \begin_layout Standard Remove the alias associated to an attribute name. \end_layout \begin_layout Standard Exceptions: ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection DbDatum Database::get_device_alias_list(string &filter) \end_layout \begin_layout Standard \noindent Get device alias list. The parameter \emph on alias \emph default is a string to filter the alias list returned. Wildcard (*) is supported. For instance, if the string alias passed as the method parameter is initialised with only the * character, all the defined device alias will be returned. The DbDatum returned by this method is initialised with an array of strings and must be extracted into a vector. If there is no alias with the given filter, the returned array will have a 0 size. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbData db_data; \end_layout \begin_layout LyX-Code string filter("*"); \end_layout \begin_layout LyX-Code \noindent \end_layout \begin_layout LyX-Code \noindent db_data = db->get_device_alias_list(filter); \end_layout \begin_layout LyX-Code vector al_list; \end_layout \begin_layout LyX-Code db_data >> al_list; \end_layout \begin_layout LyX-Code cout << al_list.size() << " device alias defined in db" << endl; \end_layout \begin_layout LyX-Code for (int i=0;i < al_list.size();i++) \end_layout \begin_layout LyX-Code cout << "alias = " << al_list[i] << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection DbDatum Database::get_attribute_alias_list(string &filter) \end_layout \begin_layout Standard \noindent Get attribute alias list. The parameter \emph on alias \emph default is a string to filter the alias list returned. Wildcard (*) is supported. For instance, if the string alias passed as the method parameter is initialised with only the * character, all the defined attribute alias will be returned. The DbDatum returned by this method is initialised with an array of strings and must be extracted into a vector. If there is no alias with the given filter, the returned array will have a 0 size. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void Database::put_device_alias(string &dev_name,string &alias_name) \end_layout \begin_layout Standard \noindent Create a device alias. Alias name has to be uniq within a Tango control system and you will receive an exception if the alias is already defined. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void Database::delete_device_alias(string &alias_name) \end_layout \begin_layout Standard \noindent Delete a device alias. \end_layout \begin_layout Standard \noindent \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Section \noindent Tango::DbDevice \end_layout \begin_layout Standard \noindent A database object for a device which can be used to query or modify properties, import and export information for a device. This class provides an easy to use interface for device objects in the database. It uses the methods of the Database class therefore the reader is referred to these for the exact calling syntax and examples. The following methods are defined for the DbDevice class : \end_layout \begin_layout Subsection \noindent DbDevice::DbDevice(string &) \end_layout \begin_layout Standard \noindent A constructor for a DbDevice object for a device in the TANGO database specified by the TANGO_HOST environment variable. \end_layout \begin_layout Subsection \noindent DbDevice::DbDevice(string &, Database *) \end_layout \begin_layout Standard \noindent A constructor for a DbDevice object for the device in the specified database. This method reuses the Database supplied by the programmer. \end_layout \begin_layout Subsection \noindent DbDevImportInfo DbDevice::import_device() \end_layout \begin_layout Standard \noindent Query the database for the import info of this device. Returns a DbDevImportInfo structure. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::export_device(DbDevExportInfo&) \end_layout \begin_layout Standard \noindent Update the export info for this device in the database. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::add_device(DbDevInfo&) \end_layout \begin_layout Standard \noindent Add/Update this device to the database. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::delete_device() \end_layout \begin_layout Standard \noindent Delete this device from the database. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::get_property(DbData&) \end_layout \begin_layout Standard \noindent Query the database for the list of properties of this device. See Database::get_device_property() for an example of how to specify and retrieve the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::put_property(DbData&) \end_layout \begin_layout Standard \noindent Update the list of properties for this device in the database. See Database::put_device_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::delete_property(DbData&) \end_layout \begin_layout Standard \noindent Delete the list of specified properties for this device in the database. See Database::delete_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::get_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Query the database for the list of attribute properties of this device. See Database::get_device_attribute_property() for an example of how to specify and retrieve the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::put_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Update the list of attribute properties for this device in the database. See Database::put_device_attribute_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbDevice::delete_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Delete all properties for the list of specified attributes for this device in the database. See Database::delete_device_attribute_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Section \noindent Tango::DbClass \end_layout \begin_layout Standard \noindent A database object for a class which can be used to query or modify class properties. \end_layout \begin_layout Subsection \noindent DbClass::DbClass(string) \end_layout \begin_layout Standard \noindent A constructor for a DbClass object for a class in the TANGO database specified by the TANGO_HOST environment variable. \end_layout \begin_layout Subsection \noindent DbClass::DbClass(string, Database *) \end_layout \begin_layout Standard \noindent A constructor for a DbClass object for the class in the specified database. This method reuses the Database supplied by the programmer. \end_layout \begin_layout Subsection \noindent void DbClass::get_property(DbData&) \end_layout \begin_layout Standard \noindent Query the database for the list of properties of this class. See Database::get_class_property() for an example of how to specify and retrieve the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbClass::put_property(DbData&) \end_layout \begin_layout Standard \noindent Update the list of properties for this class in the database. See Database::put_class_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbClass::delete_property(DbData&) \end_layout \begin_layout Standard \noindent Delete the list of specified properties for this class in the database. See Database::delete_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbClass::get_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Query the database for the list of attribute properties of this class. See Database::get_class_attribute_property() for an example of how to specify and retrieve the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbClass::put_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Update the list of attribute properties for this class in the database. See Database::put_class_attribute_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection \noindent void DbClass::delete_attribute_property(DbData&) \end_layout \begin_layout Standard \noindent Delete all properties for the list of specified attributes for this class in the database. See Database::delete_class_attribute_property() for an example of how to specify the properties. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Section Tango::DbServer \end_layout \begin_layout Standard \noindent A database object for a device server which can be used to query or modify server database information. \end_layout \begin_layout Subsection \noindent DbServer::DbServer(string) \end_layout \begin_layout Standard \noindent A constructor for a DbServer object for a server in the TANGO database specified by the TANGO_HOST environment variable. \end_layout \begin_layout Subsection \noindent DbServer::DbServer(string, Database *) \end_layout \begin_layout Standard \noindent A constructor for a DbServer object for the server in the specified database. This method reuses the Database supplied by the programmer. \end_layout \begin_layout Subsection \noindent void DbServer::add_server(DbDevInfos &) \end_layout \begin_layout Standard Add a group of devices to the database. The device names, server names and classes are specified in the vector of DbDevInfo structures. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void DbServer::delete_server() \end_layout \begin_layout Standard Delete the device server and its associated devices from the database. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void DbServer::export_server(DbDevExportInfos &) \end_layout \begin_layout Standard Export a group of device to the database. The device names, IOR, class, server name, pid etc. are specified in the vector of DbDevExportInfo structures. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Subsection void DbServer::unexport_server() \end_layout \begin_layout Standard Mark all the devices exported by the server as un exported. \end_layout \begin_layout Standard \emph on Exceptions \emph default : \emph on ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError) \end_layout \begin_layout Section \noindent Tango::DbDatum \end_layout \begin_layout Standard \noindent A single database value which has a name, type, address and value and methods for inserting and extracting C++ native types. This is the fundamental type for specifying database properties. Every property has a name and has one or more values associated with it. The values can be inserted and extracted using the operators << and >> respectively. A status flag indicates if there is data in the DbDatum object or not. An additional flag allows the user to activate exceptions. \end_layout \begin_layout Subsection \noindent Operators \end_layout \begin_layout Standard \noindent The insert and extract operators are specified for the following C++ types : \end_layout \begin_layout Enumerate \noindent boolean \end_layout \begin_layout Enumerate unsigned char \end_layout \begin_layout Enumerate \noindent short \end_layout \begin_layout Enumerate \noindent unsigned short \end_layout \begin_layout Enumerate \noindent DevLong \end_layout \begin_layout Enumerate \noindent DevULong \end_layout \begin_layout Enumerate DevLong64 \end_layout \begin_layout Enumerate DevULong64 \end_layout \begin_layout Enumerate \noindent float \end_layout \begin_layout Enumerate \noindent double \end_layout \begin_layout Enumerate \noindent string \end_layout \begin_layout Enumerate \noindent char* (insert only) \end_layout \begin_layout Enumerate \noindent const char * \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Enumerate \noindent vector \end_layout \begin_layout Standard \noindent Here is an example of creating, inserting and extracting some DbDatum types : \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent DbDatum my_short("my_short"), my_long( \begin_inset Quotes eld \end_inset my_long \begin_inset Quotes erd \end_inset ), my_string("my_string"); \end_layout \begin_layout LyX-Code \noindent DbDatum my_float_vector("my_float_vector"), my_double_vector("my_double_vector") ; \end_layout \begin_layout LyX-Code \noindent string a_string; \end_layout \begin_layout LyX-Code \noindent short a_short; \end_layout \begin_layout LyX-Code \noindent DevLong a_long; \end_layout \begin_layout LyX-Code \noindent vector a_float_vector; \end_layout \begin_layout LyX-Code \noindent vector a_double_vector; \end_layout \begin_layout LyX-Code \noindent my_short << 100; // insert a short \end_layout \begin_layout LyX-Code \noindent my_short >> a_short; // extract a short \end_layout \begin_layout LyX-Code \noindent my_long << 1000; // insert a DevLong \end_layout \begin_layout LyX-Code \noindent my_long >> a_long; // extract a long \end_layout \begin_layout LyX-Code \noindent my_string << string("estas lista a bailar el tango ?"); // insert a string \end_layout \begin_layout LyX-Code \noindent my_string >> a_string; // extract a string \end_layout \begin_layout LyX-Code \noindent my_float_vector << a_float_vector // insert a vector of floats \end_layout \begin_layout LyX-Code \noindent my_float_vector >> a_float_vector; // extract a vector of floats \end_layout \begin_layout LyX-Code \noindent my_double_vector << a_double_vector; // insert a vector of doubles \end_layout \begin_layout LyX-Code \noindent my_double_vector >> a_double_vector; // extract a vector of doubles \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection \noindent bool DbDatum::is_empty() \end_layout \begin_layout Standard \noindent is_empty() is a boolean method which trues true or false depending on whether the DbDatum object contains data or not. It can be used to test whether a property is defined in the database or not e.g. \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent sl_props.push_back(parity_prop); \end_layout \begin_layout LyX-Code \noindent dbase->get_device_property(device_name, sl_props); \end_layout \begin_layout LyX-Code \noindent if (! parity_prop.is_empty()) \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent parity_prop >> parity; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout LyX-Code \noindent else \end_layout \begin_layout LyX-Code \noindent { \end_layout \begin_layout LyX-Code \noindent cout << device_name << " has no parity defined in database !" << endl; \end_layout \begin_layout LyX-Code \noindent } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard \emph on Exception: WrongData if requested \end_layout \begin_layout Subsection \noindent void DbDatum::exceptions(bitset) \end_layout \begin_layout Standard \noindent Is a method which allows the user to switch on/off exception throwing for trying to extract data from an empty DbDatum object. The default is to not throw exception. The following flags are supported : \end_layout \begin_layout Enumerate \noindent \series bold isempty_flag \series default - throw a WrongData exception (reason = API_EmptyDbDatum) if user tries to extract data from an empty DbDatum object \end_layout \begin_layout Enumerate \series bold wrongtype_flag \series default - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user tries to extract data with a type different than the type used for insertion \end_layout \begin_layout Subsection bitset exceptions() \end_layout \begin_layout Standard Returns the whole exception flags. \end_layout \begin_layout Subsection void DbDatum::reset_exceptions(DbDatum::except_flags fl) \end_layout \begin_layout Standard Resets one exception flag \end_layout \begin_layout Subsection void DbDatum::set_exceptions(DbDatum::except_flags fl) \end_layout \begin_layout Standard Sets one exception flag \end_layout \begin_layout Standard The following is an example of how to use these exceptions related methods \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent 1 DbDatum da; \end_layout \begin_layout LyX-Code 2 \end_layout \begin_layout LyX-Code 3 bitset bs = da.exceptions(); \end_layout \begin_layout LyX-Code 4 cout << "bs = " << bs << endl; \end_layout \begin_layout LyX-Code 5 \end_layout \begin_layout LyX-Code 6 da.set_exceptions(DbDatum::wrongtype_flag); \end_layout \begin_layout LyX-Code 7 bs = da.exceptions(); \end_layout \begin_layout LyX-Code 8 \end_layout \begin_layout LyX-Code 9 cout << "bs = " << bs << endl; \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Section \noindent Tango::DbData \end_layout \begin_layout Standard \noindent A vector of Tango::DbDatum structures. DbData is used to send or return one or more database properties or information. It is the standard input and output type for all methods which query and/or update properties in the database. \end_layout \begin_layout Section Exception \begin_inset CommandInset label LatexCommand label name "sec:Exception" \end_inset \end_layout \begin_layout Standard All the exception thrown by this API are Tango::DevFailed exception. This exception is a variable length array of Tango::DevError type. The Tango::DevError type is a four fields structure. These fields are : \end_layout \begin_layout Enumerate A string describing the error type. This string replaces an error code and allows a more easy management of include files. This field is called \series bold reason \end_layout \begin_layout Enumerate A string describing in plain text the reason of the error. This field is called \series bold desc \end_layout \begin_layout Enumerate A string giving the name of the method which thrown the exception. This field is named \series bold origin \end_layout \begin_layout Enumerate The error severity. This is an enumeration with three values which are WARN, ERR or PANIC. Its name is \series bold severity \end_layout \begin_layout Standard This is a variable length array in order to transmit to the client what is the primary error reason. The sequence element 0 describes the primary error. An exception class hierarchy has been implemented within the API to ease API programmers task. All the exception classes inherits from the Tango::DevFailed class. Except for the \emph on NamedDevFaildeList \emph default exception class, they don't add any new fields to the exception, they just allow easy "catching". Exception classes thrown only by the API layer are : \end_layout \begin_layout Itemize ConnectionFailed \begin_inset Index idx status collapsed \begin_layout Plain Layout ConnectionFailed \end_layout \end_inset \end_layout \begin_layout Itemize CommunicationFailed \begin_inset Index idx status collapsed \begin_layout Plain Layout CommunicationFailed \end_layout \end_inset \end_layout \begin_layout Itemize WrongNameSyntax \begin_inset Index idx status collapsed \begin_layout Plain Layout WrongNameSyntax \end_layout \end_inset \end_layout \begin_layout Itemize NonDbDevice \begin_inset Index idx status collapsed \begin_layout Plain Layout NonDbDevice \end_layout \end_inset \end_layout \begin_layout Itemize WrongData \begin_inset Index idx status collapsed \begin_layout Plain Layout WrongData \end_layout \end_inset \end_layout \begin_layout Itemize NonSupportedFeature \begin_inset Index idx status collapsed \begin_layout Plain Layout NonSupportedFeature \end_layout \end_inset \end_layout \begin_layout Itemize AsynCall \begin_inset Index idx status collapsed \begin_layout Plain Layout AsynCall \end_layout \end_inset \end_layout \begin_layout Itemize AsynReplyNotArrived \begin_inset Index idx status collapsed \begin_layout Plain Layout AsynReplyNotArrived \end_layout \end_inset \end_layout \begin_layout Itemize EventSystemFailed \begin_inset Index idx status collapsed \begin_layout Plain Layout EventSystemFailed \end_layout \end_inset \end_layout \begin_layout Itemize NamedDevFailedList \begin_inset Index idx status collapsed \begin_layout Plain Layout NamedDevFailedList \end_layout \end_inset \end_layout \begin_layout Itemize DeviceUnlocked \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceUnlocked \end_layout \end_inset \end_layout \begin_layout Standard On top of these classes, exception thrown by the device (Tango::DevFailed exception) are directly passed to the client. \end_layout \begin_layout Subsection The ConnectionFailed exception \end_layout \begin_layout Standard This exception is thrown when a problem occurs during the connection establishme nt between the application and the device. The API is stateless. This means that DeviceProxy constructors filter most of the exception except for cases described in the following table. \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Method name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout device type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout error type \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout reason \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TANGO_HOST not set \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_TangoHostNotSet \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device not defined in db \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DB_DeviceNotDefined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DeviceProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Alias not defined in db \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceNotDefined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout constructor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Database server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout specified in dev name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDatabase \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout without \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server running but device \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not defined in server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceNotExported \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout TANGO_HOST not set \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_TangoHostNotSet \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DB_DeviceNotDefined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Device not defined in db \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AttributeProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceNotDefined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout constructor \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DB_SQLError \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Alias not defined in db \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_AliasNotDefined \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Database server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout specified in dev name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDatabase \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DeviceProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout without \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server not \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_ServerNotRunning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AttributeProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server not running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceNotExported \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout method call \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Dead \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout (except \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cmd_inout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Dead database server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout read_attribute) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout when reconnection needed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDatabase \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout without \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout DeviceProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_ServerNotRunning \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout cmd_inout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceNotExported \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout read_attribute \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout not running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout with \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Dead \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDevice \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout AttributeProxy \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout server \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout read \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout or API_AttributeFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Dead database \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout write \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout server when reconnection \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CantConnectToDatabase \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout needed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommandFailed \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard The desc DevError structure field allows a user to get more precise information. These informations are : \end_layout \begin_layout Description DB_DeviceNotDefined The name of the device not defined in the database \end_layout \begin_layout Description API_CommandFailed The device and command name \end_layout \begin_layout Description API_CantConnectToDevice The device name \end_layout \begin_layout Description API_CorbaException The name of the CORBA exception, its reason, its locality, its completed flag and its minor code \end_layout \begin_layout Description API_CantConnectToDatabase The database server host and its port number \end_layout \begin_layout Description API_DeviceNotExported The device name \end_layout \begin_layout Subsection The CommunicationFailed exception \end_layout \begin_layout Standard This exception is thrown when a communication problem is detected during the communication between the client application and the device server. It is a two levels Tango::DevError structure. In case of time-out, the DevError structures fields are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Reason \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Desc \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Severity \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA exception fields translated into a string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ERR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_DeviceTimedOut \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout String with time-out value and device name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ERR \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard For all other communication errors, the DevError structures fields are: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Level \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Reason \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Desc \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Severity \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 0 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CorbaException \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CORBA exception fields translated into a string \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ERR \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout API_CommunicationFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout String with device, method, command/attribute name \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ERR \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Subsection The WrongNameSyntax exception \end_layout \begin_layout Standard This exception has only one level of Tango::DevError structure. The possible value for the reason field are : \end_layout \begin_layout Description API_UnsupportedProtocol This error occurs when trying to build a DeviceProxy or an AttributeProxy instance for a device with an unsupported protocol. Refer to the appendix on device naming syntax to get the list of supported database modifier \end_layout \begin_layout Description API_UnsupportedDBaseModifier This error occurs when trying to build a DeviceProx y or an AttributeProxy instance for a device/attribute with a database modifier unsupported. Refer to the appendix on device naming syntax to get the list of supported database modifier \end_layout \begin_layout Description API_WrongDeviceNameSyntax This error occurs for all the other error in device name syntax. It is thrown by the DeviceProxy class constructor. \end_layout \begin_layout Description API_WrongAttributeNameSyntax This error occurs for all the other error in attribute name syntax. It is thrown by the AttributeProxy class constructor. \end_layout \begin_layout Description API_WrongWildcardUsage This error occurs if there is a bad usage of the wildcard character \end_layout \begin_layout Subsection The NonDbDevice exception \end_layout \begin_layout Standard This exception has only one level of Tango::DevError structure. The reason field is set to API_NonDatabaseDevice. This exception is thrown by the API when using the DeviceProxy or AttributeProx y class database access for non-database device. \end_layout \begin_layout Subsection The WrongData exception \end_layout \begin_layout Standard This exception has only one level of Tango::DevError structure. The possible value for the reason field are : \end_layout \begin_layout Description API_EmptyDbDatum This error occurs when trying to extract data from an empty DbDatum object \end_layout \begin_layout Description API_IncompatibleArgumentType This error occurs when trying to extract data with a type different than the type used to send the data \end_layout \begin_layout Description API_EmptyDeviceAttribute This error occurs when trying to extract data from an empty DeviceAttribute object \end_layout \begin_layout Description API_IncompatibleAttrArgumentType This error occurs when trying to extract attribute data with a type different than the type used to send the data \end_layout \begin_layout Description API_EmptyDeviceData This error occurs when trying to extract data from an empty DeviceData object \end_layout \begin_layout Description API_IncompatibleCmdArgumentType This error occurs when trying to extract command data with a type different than the type used to send the data \end_layout \begin_layout Subsection The NonSupportedFeature exception \end_layout \begin_layout Standard This exception is thrown by the API layer when a request to a feature implemente d in Tango device interface release n is requested for a device implementing Tango device interface n-x. There is one possible value for the reason field which is API_UnsupportedFeatur e. \end_layout \begin_layout Subsection The AsynCall exception \end_layout \begin_layout Standard This exception is thrown by the API layer when a the asynchronous model id badly used. This exception has only one level of Tango::DevError structure. The possible value for the reason field are : \end_layout \begin_layout Description API_BadAsynPollId This error occurs when using an asynchronous request identifie r which is not valid any more. \end_layout \begin_layout Description API_BadAsyn This error occurs when trying to fire callback when no callback has been previously registered \end_layout \begin_layout Description API_BadAsynReqType This error occurs when trying to get result of an asynchronou s request with an asynchronous request identifier returned by a non-coherent asynchronous request (For instance, using the asynchronous request identifier returned by a \emph on command_inout_asynch() \emph default method with a \emph on read_attribute_reply() \emph default attribute). \end_layout \begin_layout Subsection The AsynReplyNotArrived exception \end_layout \begin_layout Standard This exception is thrown by the API layer when: \end_layout \begin_layout Itemize a request to get asynchronous reply is made and the reply is not yet arrived \end_layout \begin_layout Itemize a blocking wait with timeout for asynchronous reply is made and the timeout expired. \end_layout \begin_layout Standard There is one possible value for the reason field which is API_AsynReplyNotArrive d. \end_layout \begin_layout Subsection The EventSystemFailed exception \end_layout \begin_layout Standard This exception is thrown by the API layer when subscribing or unsubscribing from an event failed. This exception has only one level of Tango::DevError structure. The possible value for the reason field are : \end_layout \begin_layout Description API_NotificationServiceFailed This error occurs when the \emph on subscribe_event() \emph default method failed trying to access the CORBA notification service \end_layout \begin_layout Description API_EventNotFound This error occurs when you are using an incorrect event_id in the \emph on unsubscribe_event() \emph default method \end_layout \begin_layout Description API_InvalidArgs This error occurs when NULL pointers are passed to the subscribe or unsubscribe event methods \end_layout \begin_layout Description API_MethodArgument This error occurs when trying to subscribe to an event which has already been subsribed to \end_layout \begin_layout Description API_DSFailedRegisteringEvent This error means that the device server to which the device belongs to failed when it tries to register the event. Most likely, it means that there is no event property defined \end_layout \begin_layout Description API_EventNotFound Occurs when using a wrong event identifier in the \emph on unsubscribe_event \emph default method \end_layout \begin_layout Subsection The NamedDevFailedList \begin_inset Index idx status collapsed \begin_layout Plain Layout NamedDevFailedList \end_layout \end_inset exception \begin_inset CommandInset label LatexCommand label name "sub:The-NamedDevFailedList-exception" \end_inset \end_layout \begin_layout Standard This exception is only thrown by the \emph on DeviceProxy::write_attributes() \begin_inset Index idx status collapsed \begin_layout Plain Layout write-attributes \end_layout \end_inset \emph default method. In this case, it is necessary to have a new class of exception to transfer the error stack for several attribute(s) which failed during the writing. Therefore, this exception class contains for each attributes which failed : \end_layout \begin_layout Itemize The name of the attribute \end_layout \begin_layout Itemize Its index in the vector passed as argumen tof the write_attributes() method \end_layout \begin_layout Itemize The error stack as described in \begin_inset CommandInset ref LatexCommand ref reference "sec:Exception" \end_inset \end_layout \begin_layout Subsubsection long NamedDevFailedList::get_faulty_attr_nb() \begin_inset Index idx status collapsed \begin_layout Plain Layout get-faulty-attr-nb \end_layout \end_inset \end_layout \begin_layout Standard Returns the number of attributes which failed during the write_attribute call. \end_layout \begin_layout Subsubsection vector NamedDevErrorList::err_list \end_layout \begin_layout Standard Public data member of the NamedDevFailedList. There is one element in this vector for each attribute which failed during its writing. \end_layout \begin_layout Subsubsection string NamedDevFailed::name \begin_inset Index idx status collapsed \begin_layout Plain Layout NamedDevFailed \end_layout \end_inset \end_layout \begin_layout Standard Public data member of the NamedDevFailed class. It contains the name of the attribute which failed. \end_layout \begin_layout Subsubsection long NamedDevFailed::idx_in_call \end_layout \begin_layout Standard Public data member of the NamedDevFailed class. It contains the index in the write_attributes method parameter vector of the attribute which failed. \end_layout \begin_layout Subsubsection DevErrorList NamedDevFailed::err_stack \end_layout \begin_layout Standard Public data member of the NamedDevFailed class. This is the error stack. \end_layout \begin_layout Standard The following piece of code is an example of how to use this class exception \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout LyX-Code \noindent catch (Tango::NamedDevFailed &e) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code long nb_faulty = e.get_faulty_attr_nb(); \end_layout \begin_layout LyX-Code for (long i = 0;i < nb_faulty;i++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Attribute " << e.err_list[i].name << " failed!" << endl; \end_layout \begin_layout LyX-Code for (long j = 0;j < e.err_list[i].err_stack.length();j++) \end_layout \begin_layout LyX-Code { \end_layout \begin_layout LyX-Code cout << "Reason [" << j << "] = " << e.err_list[i].err_stack[j].reason; \end_layout \begin_layout LyX-Code cout << "Desc [" << j << "] = " << e.err_list[i].err_stack[j].desc; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand input filename "line.tex" \end_inset \end_layout \begin_layout Standard This exception inherits from Tango::DevFailed. It is possible to catch it with a "catch DevFailed" catch block. In this case, like any other DevFailed exception, there is only one error stack. This stack is initialised with the name of all the attributes which failed in its "reason" field. \end_layout \begin_layout Subsection The DeviceUnlocked \begin_inset Index idx status collapsed \begin_layout Plain Layout DeviceUnlocked \end_layout \end_inset exception \end_layout \begin_layout Standard This exception is thrown by the API layer when a device locked by the process has been unlocked by an admin client. This exception has two levels of Tango::DevError structure. There is only possible value for the reason field which is \end_layout \begin_layout Description API_DeviceUnlocked The device has been unlocked by another client (administratio n client) \end_layout \begin_layout Standard The first level is the message reported by the Tango kernel from the server side. The second layer is added by the client API layer with informations on which API call generates the exception and device name. \end_layout \begin_layout Section Reconnection and exception \begin_inset CommandInset label LatexCommand label name "sec:Reconnection-and-exception" \end_inset \end_layout \begin_layout Standard The Tango API automatically manages re-connection between client and server in case of communication error during a network access between a client and a server. The transparency reconnection mode allows a user to be (or not be) informed that automatic reconnection took place. If the transparency reconnection mode is not set, when a communication error occurs, an exception is returned to the caller and the connection is internally marked as bad. On the next try to contact the device, the API will try to re-build the network connection. If the transparency reconnection mode is set, the API will try to re-build the network connection has soon as the communication error occurs and the caller is not informed. Several cases are possible. They are summarized in the following table: \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard \align center \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout Case \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server state \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout call nb \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout exception (transparency false) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout exception (transparency true) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server killed before call n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CommunicationFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ConnectionFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server killed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout down \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n+1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ConnectionFailed(2 levels) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and re-started \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout down \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server died before call n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CommunicationFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ConnectionFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server died \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout died \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + 1 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout ConnectionFailed (3 levels) \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and re-started \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout died \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + 2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout idem \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server killed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server killed and re-started before call n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CommunicationFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and re-started \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n+x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server died \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Server died and re-started before call n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout CommunicationFailed \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout and re-started \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout Running \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout n + x \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout No exception \end_layout \end_inset \end_inset \end_layout \begin_layout Standard \begin_inset VSpace 0.3cm \end_inset \end_layout \begin_layout Standard Please note that the timeout case is managed differently because it will not enter the re-connection system. The transparency reconnection mode is set by default to true for Tango version 5.5! \end_layout \end_body \end_document tango-9.2.5a/doc/src/tango.lyx0000644023471100065110000004050513034745265013145 00000000000000#LyX 2.0 created this file. For more info see http://www.lyx.org/ # # Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 # European Synchrotron Radiation Facility # BP 220, Grenoble 38043 # FRANCE # # This file is part of Tango. # # Tango is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Tango is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Tango. If not, see . # \lyxformat 413 \begin_document \begin_header \textclass book \begin_preamble \usepackage{a4wide} \usepackage{array} \usepackage{verbatim} \makeindex \usepackage{graphicx} \usepackage{mathptm,times} \usepackage{hyperref} \hypersetup{colorlinks=true,citecolor=blue} \end_preamble \use_default_options false \maintain_unincluded_children false \language english \language_package default \inputencoding latin1 \fontencoding global \font_roman default \font_sans default \font_typewriter default \font_default_family default \use_non_tex_fonts false \font_sc false \font_osf false \font_sf_scale 100 \font_tt_scale 100 \graphics default \default_output_format default \output_sync 0 \bibtex_command default \index_command default \paperfontsize default \spacing single \use_hyperref false \pdf_bookmarks true \pdf_bookmarksnumbered false \pdf_bookmarksopen false \pdf_bookmarksopenlevel 1 \pdf_breaklinks false \pdf_pdfborder false \pdf_colorlinks true \pdf_backref false \pdf_pdfusetitle true \papersize default \use_geometry false \use_amsmath 1 \use_esint 0 \use_mhchem 1 \use_mathdots 1 \cite_engine basic \use_bibtopic false \use_indices false \paperorientation portrait \suppress_date false \use_refstyle 0 \index Index \shortcut idx \color #008000 \end_index \secnumdepth 5 \tocdepth 4 \paragraph_separation indent \paragraph_indentation default \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle default \tracking_changes false \output_changes false \html_math_output 0 \html_css_as_file 0 \html_be_strict false \end_header \begin_body \begin_layout Title \begin_inset Tabular \begin_inset Text \begin_layout Plain Layout \size huge The TANGO Control System Manual \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \size huge \emph on Version 9.2 \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \begin_inset Graphics filename dance/cover_tango_book1.jpg width 7cm \end_inset \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \begin_inset Text \begin_layout Plain Layout \end_layout \end_inset \end_inset \end_layout \begin_layout Author The TANGO Team \end_layout \begin_layout Standard \begin_inset CommandInset toc LatexCommand tableofcontents \end_inset \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash vspace{3cm} \end_layout \end_inset \end_layout \begin_layout Standard \align center \begin_inset CommandInset label LatexCommand label name "FirstPicture" \end_inset \begin_inset Graphics filename dance/tango-08-27.jpg lyxscale 70 scale 70 \end_inset \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash vspace{0.3cm} \end_layout \end_inset \end_layout \begin_layout Standard \align center \begin_inset Graphics filename dance/Ready.eps \end_inset \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Plain Layout \backslash vspace{0.3cm} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Introduction \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "intro/intro.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Getting started \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "started/started.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout The TANGO device server model \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "ds_model/ds_model.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout The Tango API generalities \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "gen_api/genapi.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout The Tango ATK \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "atk/programmersguid.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Writing a TANGO device server \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "ds_writing/ds_writing.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Advanced features (polling) \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "advanced/advanced.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout The appendix \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/appendix.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout The IDL file \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/idl.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Device naming \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/naming.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout Starting Tango control system \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/starting_tango.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout notifd2db command \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/notifd2db.lyx" \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status open \begin_layout Plain Layout property file \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset include LatexCommand include filename "appendix/prop_file.lyx" \end_inset \end_layout \begin_layout Chapter* List of pictures \end_layout \begin_layout Itemize Cover page: From http://www.juliaetandres.com \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "FirstPicture" \end_inset : By O. Chevre from http://www.forteresses.free.fr \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "APicture" \end_inset : From http://www.photo-evasion.com licence "Creative Commons" \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "OneRicardo" \end_inset : By R. STEINMANN © ECK2000 \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "ThreeRicardo" \end_inset : By R. STEINMANN © ECK2000 \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "TwoRicardo" \end_inset : By R. STEINMANN © ECK2000 \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "BlackPicture" \end_inset : By O. Chevre from http://www.forteresses.free.fr \end_layout \begin_layout Itemize \begin_inset CommandInset ref LatexCommand vpageref reference "FourRicardo" \end_inset : By R. STEINMANN © ECK2000 \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "1" key "OMG-page" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.omg.org}{OMG home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "2" key "Henning" \end_inset "Advanced CORBA programming with C++" by M.Henning and S.Vinosky (Addison-Wesley 1999) \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "3" key "Tango web" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.tango-controls.org}{TANGO home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "4" key "Alba_WEB" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.cells.es}{ALBA home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "5" key "Soleil_home_page" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.synchrotron-soleil.fr}{Soleil home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "6" key "mysql" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.mysql.com}{MySQL home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "7" key "MySQL book" \end_inset "MySQL and mSQL" by Randy Jay Yarger, George Reese and Tim King (O'Reilly 1999) \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "8" key "TANGO_ref_man" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.tango-controls.org/device-servers}{Tango classes on-line documenta tion} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "9" key "Stroustrup" \end_inset "C++ programming language" third edition by Stroustrup (Addison-Wesley) \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "10" key "Patterns" \end_inset "Design Patterns" by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (Addison-Wesley 1995) \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "11" key "OOC page" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://omniorb.sourceforge.net}{omniORB home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "12" key "CORBA_norm" \end_inset The Common Object Request Broker: Architecture and Specification Revision 2.3 available from OMG home page \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "13" key "Java memory leak" \end_inset Java Pro - June 1999 : Plugging memory leak by Tony Leung \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "14" key "CVS" \end_inset CVS WEB page - http://www.cyclic.com \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "15" key "Pogo doc" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/pogo_doc/index.html} {POGO home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "16" key "JacORB" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.jacorb.org}{JacORB home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "17" key "ATK-doc" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/atk_doc/index.html}{Tango ATK reference on-line documentation} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "18" key "Notif_doc" \end_inset The Notification Service specification available from OMG home page - http://www. omg.org \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "19" key "Astor_doc" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/astor_doc/index.html }{ASTOR home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "20" key "Elettra_home_page" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.elettra.trieste.it}{Elettra home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "21" key "Jive doc" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/tools_doc/jive_doc/index.html} {JIVE home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "22" key "ATK-Tutorial" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/atk_tutorial/Tutorials.pdf}{Ta ngo ATK Tutorials} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "23" key "ZMQ" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.zeromq.org}{ZMQ home page} \end_layout \end_inset \end_layout \begin_layout Bibliography \begin_inset CommandInset bibitem LatexCommand bibitem label "24" key "Tango-dsclasses-doc" \end_inset \begin_inset ERT status open \begin_layout Plain Layout \backslash href{http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/cpp_doc/index.html} {Tango class development reference documentation} \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset CommandInset index_print LatexCommand printindex type "idx" \end_inset \end_layout \end_body \end_document tango-9.2.5a/doc/src/line.tex0000644023471100065110000000174013034745265012746 00000000000000% % Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 % European Synchrotron Radiation Facility % BP 220, Grenoble 38043 % FRANCE % % This file is part of Tango. % % Tango is free software: you can redistribute it and/or modify % it under the terms of the GNU Lesser General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Tango is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU Lesser General Public License for more details. % % You should have received a copy of the GNU Lesser General Public License % along with Tango. If not, see . % \begin{flushleft} \begin{picture}(0,0) \thicklines \put(0,0){\line(1,0){400}} \end{picture} \end{flushleft} tango-9.2.5a/doc/tango.pdf0000644023471100065110001077370113034745263012325 00000000000000%PDF-1.4 %ÐÔÅØ 1 0 obj << /S /GoTo /D (chapter.1) >> endobj 4 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n) endobj 5 0 obj << /S /GoTo /D (section.1.1) >> endobj 8 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n\000\040\000t\000o\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 9 0 obj << /S /GoTo /D (section.1.2) >> endobj 12 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000h\000i\000s\000t\000o\000r\000y) endobj 13 0 obj << /S /GoTo /D (chapter.2) >> endobj 16 0 obj (\376\377\000G\000e\000t\000t\000i\000n\000g\000\040\000S\000t\000a\000r\000t\000e\000d) endobj 17 0 obj << /S /GoTo /D (section.2.1) >> endobj 20 0 obj (\376\377\000A\000\040\000C\000+\000+\000\040\000T\000A\000N\000G\000O\000\040\000c\000l\000i\000e\000n\000t) endobj 21 0 obj << /S /GoTo /D (section.2.2) >> endobj 24 0 obj (\376\377\000A\000\040\000T\000A\000N\000G\000O\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 25 0 obj << /S /GoTo /D (subsection.2.2.1) >> endobj 28 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000s\000\040\000a\000n\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s\000\040\000c\000o\000d\000e) endobj 29 0 obj << /S /GoTo /D (subsubsection.2.2.1.1) >> endobj 32 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000S\000i\000m\000p\000l\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 33 0 obj << /S /GoTo /D (subsubsection.2.2.1.2) >> endobj 36 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000A\000r\000r\000a\000y\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 37 0 obj << /S /GoTo /D (subsubsection.2.2.1.3) >> endobj 40 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000S\000t\000r\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 41 0 obj << /S /GoTo /D (subsubsection.2.2.1.4) >> endobj 44 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000S\000t\000r\000A\000r\000r\000a\000y\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 45 0 obj << /S /GoTo /D (subsubsection.2.2.1.5) >> endobj 48 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000S\000t\000r\000u\000c\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 49 0 obj << /S /GoTo /D (subsubsection.2.2.1.6) >> endobj 52 0 obj (\376\377\000T\000h\000e\000\040\000t\000h\000r\000e\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 53 0 obj << /S /GoTo /D (chapter.3) >> endobj 56 0 obj (\376\377\000T\000h\000e\000\040\000T\000A\000N\000G\000O\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000m\000o\000d\000e\000l) endobj 57 0 obj << /S /GoTo /D (section.3.1) >> endobj 60 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n\000\040\000t\000o\000\040\000C\000O\000R\000B\000A) endobj 61 0 obj << /S /GoTo /D (section.3.2) >> endobj 64 0 obj (\376\377\000T\000h\000e\000\040\000m\000o\000d\000e\000l) endobj 65 0 obj << /S /GoTo /D (section.3.3) >> endobj 68 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e) endobj 69 0 obj << /S /GoTo /D (subsection.3.3.1) >> endobj 72 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 73 0 obj << /S /GoTo /D (subsection.3.3.2) >> endobj 76 0 obj (\376\377\000T\000h\000e\000\040\000T\000A\000N\000G\000O\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 77 0 obj << /S /GoTo /D (subsection.3.3.3) >> endobj 80 0 obj (\376\377\000T\000h\000e\000\040\000T\000A\000N\000G\000O\000\040\000p\000i\000p\000e\000s) endobj 81 0 obj << /S /GoTo /D (subsection.3.3.4) >> endobj 84 0 obj (\376\377\000C\000o\000m\000m\000a\000n\000d\000,\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s\000\040\000o\000r\000\040\000p\000i\000p\000e\000s\000\040\000?) endobj 85 0 obj << /S /GoTo /D (subsection.3.3.5) >> endobj 88 0 obj (\376\377\000T\000h\000e\000\040\000C\000O\000R\000B\000A\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 89 0 obj << /S /GoTo /D (subsection.3.3.6) >> endobj 92 0 obj (\376\377\000T\000h\000e\000\040\000r\000e\000m\000a\000i\000n\000i\000n\000g\000\040\000C\000O\000R\000B\000A\000\040\000o\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 93 0 obj << /S /GoTo /D (subsection.3.3.7) >> endobj 96 0 obj (\376\377\000T\000h\000e\000\040\000s\000p\000e\000c\000i\000a\000l\000\040\000c\000a\000s\000e\000\040\000o\000f\000\040\000t\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000t\000a\000t\000e\000\040\000a\000n\000d\000\040\000s\000t\000a\000t\000u\000s) endobj 97 0 obj << /S /GoTo /D (subsection.3.3.8) >> endobj 100 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000o\000l\000l\000i\000n\000g) endobj 101 0 obj << /S /GoTo /D (section.3.4) >> endobj 104 0 obj (\376\377\000T\000h\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 105 0 obj << /S /GoTo /D (section.3.5) >> endobj 108 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000L\000o\000g\000g\000i\000n\000g\000\040\000S\000e\000r\000v\000i\000c\000e) endobj 109 0 obj << /S /GoTo /D (section.3.6) >> endobj 112 0 obj (\376\377\000T\000h\000e\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 113 0 obj << /S /GoTo /D (section.3.7) >> endobj 116 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s) endobj 117 0 obj << /S /GoTo /D (section.3.8) >> endobj 120 0 obj (\376\377\000T\000h\000e\000\040\000A\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000P\000r\000o\000g\000r\000a\000m\000m\000e\000r\000s\000\040\000I\000n\000t\000e\000r\000f\000a\000c\000e\000s) endobj 121 0 obj << /S /GoTo /D (subsection.3.8.1) >> endobj 124 0 obj (\376\377\000R\000u\000l\000e\000s\000\040\000o\000f\000\040\000t\000h\000e\000\040\000A\000P\000I) endobj 125 0 obj << /S /GoTo /D (subsection.3.8.2) >> endobj 128 0 obj (\376\377\000C\000o\000m\000m\000u\000n\000i\000c\000a\000t\000i\000o\000n\000\040\000b\000e\000t\000w\000e\000e\000n\000\040\000c\000l\000i\000e\000n\000t\000\040\000a\000n\000d\000\040\000s\000e\000r\000v\000e\000r\000\040\000u\000s\000i\000n\000g\000\040\000t\000h\000e\000\040\000A\000P\000I) endobj 129 0 obj << /S /GoTo /D (subsection.3.8.3) >> endobj 132 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000e\000v\000e\000n\000t\000s) endobj 133 0 obj << /S /GoTo /D (chapter.4) >> endobj 136 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000\040\000T\000A\000N\000G\000O\000\040\000c\000l\000i\000e\000n\000t\000\040\000u\000s\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000A\000P\000I\000s) endobj 137 0 obj << /S /GoTo /D (section.4.1) >> endobj 140 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n) endobj 141 0 obj << /S /GoTo /D (section.4.2) >> endobj 144 0 obj (\376\377\000G\000e\000t\000t\000i\000n\000g\000\040\000S\000t\000a\000r\000t\000e\000d) endobj 145 0 obj << /S /GoTo /D (section.4.3) >> endobj 148 0 obj (\376\377\000B\000a\000s\000i\000c\000\040\000P\000h\000i\000l\000o\000s\000o\000p\000h\000y) endobj 149 0 obj << /S /GoTo /D (section.4.4) >> endobj 152 0 obj (\376\377\000D\000a\000t\000a\000\040\000t\000y\000p\000e\000s) endobj 153 0 obj << /S /GoTo /D (section.4.5) >> endobj 156 0 obj (\376\377\000R\000e\000q\000u\000e\000s\000t\000\040\000m\000o\000d\000e\000l) endobj 157 0 obj << /S /GoTo /D (subsection.4.5.1) >> endobj 160 0 obj (\376\377\000S\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000\040\000m\000o\000d\000e\000l) endobj 161 0 obj << /S /GoTo /D (subsection.4.5.2) >> endobj 164 0 obj (\376\377\000A\000s\000y\000n\000c\000h\000r\000o\000n\000o\000u\000s\000\040\000m\000o\000d\000e\000l) endobj 165 0 obj << /S /GoTo /D (section.4.6) >> endobj 168 0 obj (\376\377\000E\000v\000e\000n\000t\000s) endobj 169 0 obj << /S /GoTo /D (subsection.4.6.1) >> endobj 172 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n) endobj 173 0 obj << /S /GoTo /D (subsection.4.6.2) >> endobj 176 0 obj (\376\377\000E\000v\000e\000n\000t\000\040\000d\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 177 0 obj << /S /GoTo /D (subsection.4.6.3) >> endobj 180 0 obj (\376\377\000E\000v\000e\000n\000t\000\040\000t\000y\000p\000e\000s) endobj 181 0 obj << /S /GoTo /D (subsection.4.6.4) >> endobj 184 0 obj (\376\377\000E\000v\000e\000n\000t\000\040\000f\000i\000l\000t\000e\000r\000i\000n\000g\000\040\000\050\000R\000e\000m\000o\000v\000e\000d\000\040\000i\000n\000\040\000T\000a\000n\000g\000o\000\040\000r\000e\000l\000e\000a\000s\000e\000\040\0008\000\040\000a\000n\000d\000\040\000a\000b\000o\000v\000e\000\051) endobj 185 0 obj << /S /GoTo /D (subsection.4.6.5) >> endobj 188 0 obj (\376\377\000A\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000P\000r\000o\000g\000r\000a\000m\000m\000e\000r\000'\000s\000\040\000I\000n\000t\000e\000r\000f\000a\000c\000e) endobj 189 0 obj << /S /GoTo /D (subsubsection.4.6.5.1) >> endobj 192 0 obj (\376\377\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g\000\040\000e\000v\000e\000n\000t\000s) endobj 193 0 obj << /S /GoTo /D (paragraph.4.6.5.1.1) >> endobj 196 0 obj (\376\377\000c\000h\000a\000n\000g\000e) endobj 197 0 obj << /S /GoTo /D (paragraph.4.6.5.1.2) >> endobj 200 0 obj (\376\377\000p\000e\000r\000i\000o\000d\000i\000c) endobj 201 0 obj << /S /GoTo /D (paragraph.4.6.5.1.3) >> endobj 204 0 obj (\376\377\000a\000r\000c\000h\000i\000v\000e) endobj 205 0 obj << /S /GoTo /D (subsubsection.4.6.5.2) >> endobj 208 0 obj (\376\377\000C\000+\000+\000\040\000C\000l\000i\000e\000n\000t\000s) endobj 209 0 obj << /S /GoTo /D (paragraph.4.6.5.2.1) >> endobj 212 0 obj (\376\377\000S\000u\000b\000s\000c\000r\000i\000b\000i\000n\000g\000\040\000t\000o\000\040\000e\000v\000e\000n\000t\000s) endobj 213 0 obj << /S /GoTo /D (paragraph.4.6.5.2.2) >> endobj 216 0 obj (\376\377\000T\000h\000e\000\040\000C\000a\000l\000l\000B\000a\000c\000k\000\040\000c\000l\000a\000s\000s) endobj 217 0 obj << /S /GoTo /D (paragraph.4.6.5.2.3) >> endobj 220 0 obj (\376\377\000U\000n\000s\000u\000b\000s\000c\000r\000i\000b\000i\000n\000g\000\040\000f\000r\000o\000m\000\040\000a\000n\000\040\000e\000v\000e\000n\000t\000\040) endobj 221 0 obj << /S /GoTo /D (paragraph.4.6.5.2.4) >> endobj 224 0 obj (\376\377\000E\000x\000t\000r\000a\000c\000t\000\040\000b\000u\000f\000f\000e\000r\000e\000d\000\040\000e\000v\000e\000n\000t\000\040\000d\000a\000t\000a) endobj 225 0 obj << /S /GoTo /D (paragraph.4.6.5.2.5) >> endobj 228 0 obj (\376\377\000E\000x\000a\000m\000p\000l\000e) endobj 229 0 obj << /S /GoTo /D (section.4.7) >> endobj 232 0 obj (\376\377\000G\000r\000o\000u\000p) endobj 233 0 obj << /S /GoTo /D (subsection.4.7.1) >> endobj 236 0 obj (\376\377\000G\000e\000t\000t\000i\000n\000g\000\040\000s\000t\000a\000r\000t\000e\000d\000\040\000w\000i\000t\000h\000\040\000T\000a\000n\000g\000o\000\040\000g\000r\000o\000u\000p) endobj 237 0 obj << /S /GoTo /D (subsection.4.7.2) >> endobj 240 0 obj (\376\377\000F\000o\000r\000w\000a\000r\000d\000\040\000o\000r\000\040\000n\000o\000t\000\040\000f\000o\000r\000w\000a\000r\000d\000?) endobj 241 0 obj << /S /GoTo /D (subsection.4.7.3) >> endobj 244 0 obj (\376\377\000E\000x\000e\000c\000u\000t\000i\000n\000g\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 245 0 obj << /S /GoTo /D (subsubsection.4.7.3.1) >> endobj 248 0 obj (\376\377\000O\000b\000t\000a\000i\000n\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d\000\040\000r\000e\000s\000u\000l\000t\000s) endobj 249 0 obj << /S /GoTo /D (subsubsection.4.7.3.2) >> endobj 252 0 obj (\376\377\000C\000a\000s\000e\000\040\0001\000:\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d\000,\000\040\000n\000o\000\040\000a\000r\000g\000u\000m\000e\000n\000t) endobj 253 0 obj << /S /GoTo /D (subsubsection.4.7.3.3) >> endobj 256 0 obj (\376\377\000A\000\040\000f\000e\000w\000\040\000w\000o\000r\000d\000s\000\040\000o\000n\000\040\000e\000r\000r\000o\000r\000\040\000h\000a\000n\000d\000l\000i\000n\000g\000\040\000a\000n\000d\000\040\000d\000a\000t\000a\000\040\000e\000x\000t\000r\000a\000c\000t\000i\000o\000n) endobj 257 0 obj << /S /GoTo /D (subsubsection.4.7.3.4) >> endobj 260 0 obj (\376\377\000C\000a\000s\000e\000\040\0002\000:\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d\000,\000\040\000o\000n\000e\000\040\000a\000r\000g\000u\000m\000e\000n\000t\000\040) endobj 261 0 obj << /S /GoTo /D (subsubsection.4.7.3.5) >> endobj 264 0 obj (\376\377\000C\000a\000s\000e\000\040\0003\000:\000\040\000a\000\040\000c\000o\000m\000m\000a\000n\000d\000,\000\040\000s\000e\000v\000e\000r\000a\000l\000\040\000a\000r\000g\000u\000m\000e\000n\000t\000s) endobj 265 0 obj << /S /GoTo /D (subsection.4.7.4) >> endobj 268 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\050\000s\000\051\000\040) endobj 269 0 obj << /S /GoTo /D (subsubsection.4.7.4.1) >> endobj 272 0 obj (\376\377\000O\000b\000t\000a\000i\000n\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000v\000a\000l\000u\000e\000s) endobj 273 0 obj << /S /GoTo /D (subsubsection.4.7.4.2) >> endobj 276 0 obj (\376\377\000A\000\040\000f\000e\000w\000\040\000w\000o\000r\000d\000s\000\040\000o\000n\000\040\000e\000r\000r\000o\000r\000\040\000h\000a\000n\000d\000l\000i\000n\000g\000\040\000a\000n\000d\000\040\000d\000a\000t\000a\000\040\000e\000x\000t\000r\000a\000c\000t\000i\000o\000n) endobj 277 0 obj << /S /GoTo /D (subsection.4.7.5) >> endobj 280 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000n\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040) endobj 281 0 obj << /S /GoTo /D (subsubsection.4.7.5.1) >> endobj 284 0 obj (\376\377\000O\000b\000t\000a\000i\000n\000i\000n\000g\000\040\000a\000c\000k\000n\000o\000w\000l\000e\000d\000g\000e\000m\000e\000n\000t) endobj 285 0 obj << /S /GoTo /D (subsubsection.4.7.5.2) >> endobj 288 0 obj (\376\377\000C\000a\000s\000e\000\040\0001\000:\000\040\000o\000n\000e\000\040\000v\000a\000l\000u\000e\000\040\000f\000o\000r\000\040\000a\000l\000l\000\040\000d\000e\000v\000i\000c\000e\000s\000\040) endobj 289 0 obj << /S /GoTo /D (subsubsection.4.7.5.3) >> endobj 292 0 obj (\376\377\000C\000a\000s\000e\000\040\0002\000:\000\040\000a\000\040\000s\000p\000e\000c\000i\000f\000i\000c\000\040\000v\000a\000l\000u\000e\000\040\000p\000e\000r\000\040\000d\000e\000v\000i\000c\000e) endobj 293 0 obj << /S /GoTo /D (section.4.8) >> endobj 296 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000/\000W\000r\000i\000t\000i\000n\000g\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000i\000p\000e) endobj 297 0 obj << /S /GoTo /D (subsection.4.8.1) >> endobj 300 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000\040\000a\000\040\000p\000i\000p\000e) endobj 301 0 obj << /S /GoTo /D (subsubsection.4.8.1.1) >> endobj 304 0 obj (\376\377\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000w\000i\000t\000h\000\040\000p\000i\000p\000e\000\040\000c\000o\000n\000t\000e\000n\000t\000\040\000p\000r\000i\000o\000r\000\040\000k\000n\000o\000w\000l\000e\000d\000g\000e) endobj 305 0 obj << /S /GoTo /D (subsubsection.4.8.1.2) >> endobj 308 0 obj (\376\377\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000i\000n\000\040\000a\000\040\000g\000e\000n\000e\000r\000i\000c\000\040\000w\000a\000y\000\040\000\050\000w\000i\000t\000h\000o\000u\000t\000\040\000p\000r\000i\000o\000r\000\040\000k\000n\000o\000w\000l\000e\000d\000g\000e\000\051) endobj 309 0 obj << /S /GoTo /D (subsubsection.4.8.1.3) >> endobj 312 0 obj (\376\377\000E\000r\000r\000o\000r\000\040\000m\000a\000n\000a\000g\000e\000m\000e\000n\000t) endobj 313 0 obj << /S /GoTo /D (subsection.4.8.2) >> endobj 316 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000\040\000p\000i\000p\000e) endobj 317 0 obj << /S /GoTo /D (subsubsection.4.8.2.1) >> endobj 320 0 obj (\376\377\000E\000r\000r\000o\000r\000\040\000m\000a\000n\000a\000g\000e\000m\000e\000n\000t) endobj 321 0 obj << /S /GoTo /D (section.4.9) >> endobj 324 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000l\000o\000c\000k\000i\000n\000g) endobj 325 0 obj << /S /GoTo /D (section.4.10) >> endobj 328 0 obj (\376\377\000R\000e\000c\000o\000n\000n\000e\000c\000t\000i\000o\000n\000\040\000a\000n\000d\000\040\000e\000x\000c\000e\000p\000t\000i\000o\000n) endobj 329 0 obj << /S /GoTo /D (section.4.11) >> endobj 332 0 obj (\376\377\000T\000h\000r\000e\000a\000d\000\040\000s\000a\000f\000e\000t\000y) endobj 333 0 obj << /S /GoTo /D (section.4.12) >> endobj 336 0 obj (\376\377\000C\000o\000m\000p\000i\000l\000i\000n\000g\000\040\000a\000n\000d\000\040\000l\000i\000n\000k\000i\000n\000g\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000l\000i\000e\000n\000t) endobj 337 0 obj << /S /GoTo /D (chapter.5) >> endobj 340 0 obj (\376\377\000T\000a\000n\000g\000o\000A\000T\000K\000\040\000P\000r\000o\000g\000r\000a\000m\000m\000e\000r\000'\000s\000\040\000G\000u\000i\000d\000e) endobj 341 0 obj << /S /GoTo /D (section.5.1) >> endobj 344 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n) endobj 345 0 obj << /S /GoTo /D (subsection.5.1.1) >> endobj 348 0 obj (\376\377\000A\000s\000s\000u\000m\000p\000t\000i\000o\000n\000s) endobj 349 0 obj << /S /GoTo /D (section.5.2) >> endobj 352 0 obj (\376\377\000T\000h\000e\000\040\000k\000e\000y\000\040\000c\000o\000n\000c\000e\000p\000t\000s\000\040\000o\000f\000\040\000T\000a\000n\000g\000o\000A\000T\000K) endobj 353 0 obj << /S /GoTo /D (subsection.5.2.1) >> endobj 356 0 obj (\376\377\000M\000i\000n\000i\000m\000i\000z\000e\000\040\000d\000e\000v\000e\000l\000o\000p\000m\000e\000n\000t\000\040\000t\000i\000m\000e) endobj 357 0 obj << /S /GoTo /D (subsection.5.2.2) >> endobj 360 0 obj (\376\377\000M\000i\000n\000i\000m\000i\000z\000e\000\040\000b\000u\000g\000s\000\040\000i\000n\000\040\000a\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000s) endobj 361 0 obj << /S /GoTo /D (subsection.5.2.3) >> endobj 364 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000s\000\040\000a\000n\000d\000\040\000c\000o\000m\000m\000a\000n\000d\000s\000\040\000f\000r\000o\000m\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000\040\000d\000e\000v\000i\000c\000e\000s) endobj 365 0 obj << /S /GoTo /D (subsection.5.2.4) >> endobj 368 0 obj (\376\377\000A\000v\000o\000i\000d\000\040\000c\000o\000d\000e\000\040\000d\000u\000p\000l\000i\000c\000a\000t\000i\000o\000n) endobj 369 0 obj << /S /GoTo /D (section.5.3) >> endobj 372 0 obj (\376\377\000T\000h\000e\000\040\000r\000e\000a\000l\000\040\000g\000e\000t\000t\000i\000n\000g\000\040\000s\000t\000a\000r\000t\000e\000d) endobj 373 0 obj << /S /GoTo /D (subsection.5.3.1) >> endobj 376 0 obj (\376\377\000S\000i\000n\000g\000l\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000a\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000s) endobj 377 0 obj << /S /GoTo /D (subsection.5.3.2) >> endobj 380 0 obj (\376\377\000M\000u\000l\000t\000i\000\040\000d\000e\000v\000i\000c\000e\000\040\000a\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000s) endobj 381 0 obj << /S /GoTo /D (subsection.5.3.3) >> endobj 384 0 obj (\376\377\000M\000o\000r\000e\000\040\000o\000n\000\040\000d\000i\000s\000p\000l\000a\000y\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 385 0 obj << /S /GoTo /D (subsubsection.5.3.3.1) >> endobj 388 0 obj (\376\377\000C\000o\000n\000n\000e\000c\000t\000i\000n\000g\000\040\000a\000n\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000t\000o\000\040\000a\000\040\000v\000i\000e\000w\000e\000r) endobj 389 0 obj << /S /GoTo /D (subsubsection.5.3.3.2) >> endobj 392 0 obj (\376\377\000S\000y\000n\000o\000p\000t\000i\000c\000\040\000v\000i\000e\000w\000e\000r) endobj 393 0 obj << /S /GoTo /D (subsection.5.3.4) >> endobj 396 0 obj (\376\377\000A\000\040\000s\000h\000o\000r\000t\000\040\000n\000o\000t\000e\000\040\000o\000n\000\040\000t\000h\000e\000\040\000r\000e\000l\000a\000t\000i\000o\000n\000s\000h\000i\000p\000\040\000b\000e\000t\000w\000e\000e\000n\000\040\000m\000o\000d\000e\000l\000s\000\040\000a\000n\000d\000\040\000v\000i\000e\000w\000e\000r\000s) endobj 397 0 obj << /S /GoTo /D (subsubsection.5.3.4.1) >> endobj 400 0 obj (\376\377\000L\000i\000s\000t\000e\000n\000e\000r\000s) endobj 401 0 obj << /S /GoTo /D (section.5.4) >> endobj 404 0 obj (\376\377\000T\000h\000e\000\040\000k\000e\000y\000\040\000o\000b\000j\000e\000c\000t\000s\000\040\000o\000f\000\040\000T\000a\000n\000g\000o\000A\000T\000K) endobj 405 0 obj << /S /GoTo /D (subsection.5.4.1) >> endobj 408 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000f\000r\000e\000s\000h\000e\000r\000s) endobj 409 0 obj << /S /GoTo /D (subsubsection.5.4.1.1) >> endobj 412 0 obj (\376\377\000W\000h\000a\000t\000\040\000h\000a\000p\000p\000e\000n\000s\000\040\000o\000n\000\040\000a\000\040\000r\000e\000f\000r\000e\000s\000h) endobj 413 0 obj << /S /GoTo /D (subsection.5.4.2) >> endobj 416 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000i\000c\000e\000F\000a\000c\000t\000o\000r\000y) endobj 417 0 obj << /S /GoTo /D (subsection.5.4.3) >> endobj 420 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000F\000a\000c\000t\000o\000r\000y\000\040\000a\000n\000d\000\040\000t\000h\000e\000\040\000C\000o\000m\000m\000a\000n\000d\000F\000a\000c\000t\000o\000r\000y) endobj 421 0 obj << /S /GoTo /D (subsection.5.4.4) >> endobj 424 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000L\000i\000s\000t\000\040\000a\000n\000d\000\040\000t\000h\000e\000\040\000C\000o\000m\000m\000a\000n\000d\000L\000i\000s\000t) endobj 425 0 obj << /S /GoTo /D (subsection.5.4.5) >> endobj 428 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 429 0 obj << /S /GoTo /D (subsubsection.5.4.5.1) >> endobj 432 0 obj (\376\377\000T\000h\000e\000\040\000h\000i\000e\000r\000a\000r\000c\000h\000y) endobj 433 0 obj << /S /GoTo /D (subsection.5.4.6) >> endobj 436 0 obj (\376\377\000T\000h\000e\000\040\000C\000o\000m\000m\000a\000n\000d\000s) endobj 437 0 obj << /S /GoTo /D (subsubsection.5.4.6.1) >> endobj 440 0 obj (\376\377\000E\000v\000e\000n\000t\000s\000\040\000a\000n\000d\000\040\000l\000i\000s\000t\000e\000n\000e\000r\000s) endobj 441 0 obj << /S /GoTo /D (chapter.6) >> endobj 444 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000\040\000T\000A\000N\000G\000O\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 445 0 obj << /S /GoTo /D (section.6.1) >> endobj 448 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000f\000r\000a\000m\000e\000w\000o\000r\000k) endobj 449 0 obj << /S /GoTo /D (subsection.6.1.1) >> endobj 452 0 obj (\376\377\000N\000a\000m\000i\000n\000g\000\040\000c\000o\000n\000v\000e\000n\000t\000i\000o\000n\000\040\000a\000n\000d\000\040\000p\000r\000o\000g\000r\000a\000m\000m\000i\000n\000g\000\040\000l\000a\000n\000g\000u\000a\000g\000e) endobj 453 0 obj << /S /GoTo /D (subsection.6.1.2) >> endobj 456 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000a\000t\000t\000e\000r\000n) endobj 457 0 obj << /S /GoTo /D (subsubsection.6.1.2.1) >> endobj 460 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000b\000a\000s\000e\000\040\000c\000l\000a\000s\000s\000\040\000\050\000D\000e\000v\000i\000c\000e\000I\000m\000p\000l\000\040\000c\000l\000a\000s\000s\000\051) endobj 461 0 obj << /S /GoTo /D (paragraph.6.1.2.1.1) >> endobj 464 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 465 0 obj << /S /GoTo /D (paragraph.6.1.2.1.2) >> endobj 468 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 469 0 obj << /S /GoTo /D (subsubsection.6.1.2.2) >> endobj 472 0 obj (\376\377\000T\000h\000e\000\040\000D\000b\000D\000e\000v\000i\000c\000e\000\040\000c\000l\000a\000s\000s) endobj 473 0 obj << /S /GoTo /D (subsubsection.6.1.2.3) >> endobj 476 0 obj (\376\377\000T\000h\000e\000\040\000C\000o\000m\000m\000a\000n\000d\000\040\000c\000l\000a\000s\000s) endobj 477 0 obj << /S /GoTo /D (paragraph.6.1.2.3.1) >> endobj 480 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n\000\040\000o\000f\000\040\000t\000h\000e\000\040\000i\000n\000h\000e\000r\000i\000t\000a\000n\000c\000e\000\040\000m\000o\000d\000e\000l) endobj 481 0 obj << /S /GoTo /D (paragraph.6.1.2.3.2) >> endobj 484 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n\000\040\000o\000f\000\040\000t\000h\000e\000\040\000t\000e\000m\000p\000l\000a\000t\000e\000\040\000m\000o\000d\000e\000l) endobj 485 0 obj << /S /GoTo /D (paragraph.6.1.2.3.3) >> endobj 488 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 489 0 obj << /S /GoTo /D (subsubsection.6.1.2.4) >> endobj 492 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000i\000c\000e\000C\000l\000a\000s\000s\000\040\000c\000l\000a\000s\000s) endobj 493 0 obj << /S /GoTo /D (paragraph.6.1.2.4.1) >> endobj 496 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 497 0 obj << /S /GoTo /D (paragraph.6.1.2.4.2) >> endobj 500 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 501 0 obj << /S /GoTo /D (subsubsection.6.1.2.5) >> endobj 504 0 obj (\376\377\000T\000h\000e\000\040\000D\000b\000C\000l\000a\000s\000s\000\040\000c\000l\000a\000s\000s) endobj 505 0 obj << /S /GoTo /D (subsubsection.6.1.2.6) >> endobj 508 0 obj (\376\377\000T\000h\000e\000\040\000M\000u\000l\000t\000i\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000c\000l\000a\000s\000s) endobj 509 0 obj << /S /GoTo /D (paragraph.6.1.2.6.1) >> endobj 512 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 513 0 obj << /S /GoTo /D (paragraph.6.1.2.6.2) >> endobj 516 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 517 0 obj << /S /GoTo /D (subsubsection.6.1.2.7) >> endobj 520 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000c\000l\000a\000s\000s) endobj 521 0 obj << /S /GoTo /D (paragraph.6.1.2.7.1) >> endobj 524 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 525 0 obj << /S /GoTo /D (paragraph.6.1.2.7.2) >> endobj 528 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 529 0 obj << /S /GoTo /D (subsubsection.6.1.2.8) >> endobj 532 0 obj (\376\377\000T\000h\000e\000\040\000W\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000c\000l\000a\000s\000s) endobj 533 0 obj << /S /GoTo /D (paragraph.6.1.2.8.1) >> endobj 536 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 537 0 obj << /S /GoTo /D (paragraph.6.1.2.8.2) >> endobj 540 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 541 0 obj << /S /GoTo /D (subsubsection.6.1.2.9) >> endobj 544 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000\040\000c\000l\000a\000s\000s) endobj 545 0 obj << /S /GoTo /D (subsubsection.6.1.2.10) >> endobj 548 0 obj (\376\377\000T\000h\000e\000\040\000S\000p\000e\000c\000t\000r\000u\000m\000A\000t\000t\000r\000\040\000c\000l\000a\000s\000s) endobj 549 0 obj << /S /GoTo /D (subsubsection.6.1.2.11) >> endobj 552 0 obj (\376\377\000T\000h\000e\000\040\000I\000m\000a\000g\000e\000A\000t\000t\000r\000\040\000c\000l\000a\000s\000s) endobj 553 0 obj << /S /GoTo /D (subsubsection.6.1.2.12) >> endobj 556 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000e\000p\000p\000e\000r\000M\000o\000t\000o\000r\000\040\000c\000l\000a\000s\000s) endobj 557 0 obj << /S /GoTo /D (paragraph.6.1.2.12.1) >> endobj 560 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 561 0 obj << /S /GoTo /D (paragraph.6.1.2.12.2) >> endobj 564 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 565 0 obj << /S /GoTo /D (subsubsection.6.1.2.13) >> endobj 568 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000e\000p\000p\000e\000r\000M\000o\000t\000o\000r\000C\000l\000a\000s\000s\000\040\000c\000l\000a\000s\000s) endobj 569 0 obj << /S /GoTo /D (paragraph.6.1.2.13.1) >> endobj 572 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 573 0 obj << /S /GoTo /D (paragraph.6.1.2.13.2) >> endobj 576 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n\000\040) endobj 577 0 obj << /S /GoTo /D (subsubsection.6.1.2.14) >> endobj 580 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000R\000e\000a\000d\000P\000o\000s\000i\000t\000i\000o\000n\000\040\000c\000l\000a\000s\000s) endobj 581 0 obj << /S /GoTo /D (paragraph.6.1.2.14.1) >> endobj 584 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 585 0 obj << /S /GoTo /D (paragraph.6.1.2.14.2) >> endobj 588 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 589 0 obj << /S /GoTo /D (subsubsection.6.1.2.15) >> endobj 592 0 obj (\376\377\000T\000h\000e\000\040\000P\000o\000s\000i\000t\000i\000o\000n\000A\000t\000t\000r\000\040\000c\000l\000a\000s\000s) endobj 593 0 obj << /S /GoTo /D (paragraph.6.1.2.15.1) >> endobj 596 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 597 0 obj << /S /GoTo /D (paragraph.6.1.2.15.2) >> endobj 600 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 601 0 obj << /S /GoTo /D (subsection.6.1.3) >> endobj 604 0 obj (\376\377\000S\000t\000a\000r\000t\000u\000p\000\040\000o\000f\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000a\000t\000t\000e\000r\000n) endobj 605 0 obj << /S /GoTo /D (subsection.6.1.4) >> endobj 608 0 obj (\376\377\000C\000o\000m\000m\000a\000n\000d\000\040\000e\000x\000e\000c\000u\000t\000i\000o\000n\000\040\000s\000e\000q\000u\000e\000n\000c\000e) endobj 609 0 obj << /S /GoTo /D (subsection.6.1.5) >> endobj 612 0 obj (\376\377\000T\000h\000e\000\040\000a\000u\000t\000o\000m\000a\000t\000i\000c\000a\000l\000l\000y\000\040\000a\000d\000d\000e\000d\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 613 0 obj << /S /GoTo /D (subsection.6.1.6) >> endobj 616 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000/\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 617 0 obj << /S /GoTo /D (subsubsection.6.1.6.1) >> endobj 620 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 621 0 obj << /S /GoTo /D (subsubsection.6.1.6.2) >> endobj 624 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 625 0 obj << /S /GoTo /D (subsection.6.1.7) >> endobj 628 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000f\000r\000a\000m\000e\000w\000o\000r\000k) endobj 629 0 obj << /S /GoTo /D (subsubsection.6.1.7.1) >> endobj 632 0 obj (\376\377\000V\000o\000c\000a\000b\000u\000l\000a\000r\000y) endobj 633 0 obj << /S /GoTo /D (subsubsection.6.1.7.2) >> endobj 636 0 obj (\376\377\000T\000h\000e\000\040\000D\000S\000e\000r\000v\000e\000r\000\040\000c\000l\000a\000s\000s) endobj 637 0 obj << /S /GoTo /D (subsubsection.6.1.7.3) >> endobj 640 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000U\000t\000i\000l\000\040\000c\000l\000a\000s\000s) endobj 641 0 obj << /S /GoTo /D (paragraph.6.1.7.3.1) >> endobj 644 0 obj (\376\377\000D\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n) endobj 645 0 obj << /S /GoTo /D (paragraph.6.1.7.3.2) >> endobj 648 0 obj (\376\377\000C\000o\000n\000t\000e\000n\000t\000s) endobj 649 0 obj << /S /GoTo /D (subsubsection.6.1.7.4) >> endobj 652 0 obj (\376\377\000A\000\040\000c\000o\000m\000p\000l\000e\000t\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 653 0 obj << /S /GoTo /D (subsubsection.6.1.7.5) >> endobj 656 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000s\000t\000a\000r\000t\000u\000p\000\040\000s\000e\000q\000u\000e\000n\000c\000e) endobj 657 0 obj << /S /GoTo /D (section.6.2) >> endobj 660 0 obj (\376\377\000E\000x\000c\000h\000a\000n\000g\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000b\000e\000t\000w\000e\000e\000n\000\040\000c\000l\000i\000e\000n\000t\000\040\000a\000n\000d\000\040\000s\000e\000r\000v\000e\000r) endobj 661 0 obj << /S /GoTo /D (subsection.6.2.1) >> endobj 664 0 obj (\376\377\000C\000o\000m\000m\000a\000n\000d\000\040\000/\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000d\000a\000t\000a\000\040\000t\000y\000p\000e\000s) endobj 665 0 obj << /S /GoTo /D (subsubsection.6.2.1.1) >> endobj 668 0 obj (\376\377\000U\000s\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000t\000y\000p\000e\000s\000\040\000w\000i\000t\000h\000\040\000C\000+\000+) endobj 669 0 obj << /S /GoTo /D (paragraph.6.2.1.1.1) >> endobj 672 0 obj (\376\377\000B\000a\000s\000i\000c\000\040\000t\000y\000p\000e\000s) endobj 673 0 obj << /S /GoTo /D (paragraph.6.2.1.1.2) >> endobj 676 0 obj (\376\377\000S\000t\000r\000i\000n\000g\000s) endobj 677 0 obj << /S /GoTo /D (paragraph.6.2.1.1.3) >> endobj 680 0 obj (\376\377\000S\000e\000q\000u\000e\000n\000c\000e\000s) endobj 681 0 obj << /S /GoTo /D (paragraph.6.2.1.1.4) >> endobj 684 0 obj (\376\377\000S\000t\000r\000u\000c\000t\000u\000r\000e\000s) endobj 685 0 obj << /S /GoTo /D (paragraph.6.2.1.1.5) >> endobj 688 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000S\000t\000a\000t\000e\000\040\000d\000a\000t\000a\000\040\000t\000y\000p\000e) endobj 689 0 obj << /S /GoTo /D (subsection.6.2.2) >> endobj 692 0 obj (\376\377\000P\000a\000s\000s\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000b\000e\000t\000w\000e\000e\000n\000\040\000c\000l\000i\000e\000n\000t\000\040\000a\000n\000d\000\040\000s\000e\000r\000v\000e\000r) endobj 693 0 obj << /S /GoTo /D (subsubsection.6.2.2.1) >> endobj 696 0 obj (\376\377\000C\000+\000+\000\040\000m\000a\000p\000p\000i\000n\000g\000\040\000f\000o\000r\000\040\000I\000D\000L\000\040\000a\000n\000y\000\040\000t\000y\000p\000e) endobj 697 0 obj << /S /GoTo /D (paragraph.6.2.2.1.1) >> endobj 700 0 obj (\376\377\000I\000n\000s\000e\000r\000t\000i\000n\000g\000/\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000b\000a\000s\000i\000c\000\040\000t\000y\000p\000e\000s) endobj 701 0 obj << /S /GoTo /D (paragraph.6.2.2.1.2) >> endobj 704 0 obj (\376\377\000I\000n\000s\000e\000r\000t\000i\000n\000g\000/\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000s\000t\000r\000i\000n\000g\000s) endobj 705 0 obj << /S /GoTo /D (paragraph.6.2.2.1.3) >> endobj 708 0 obj (\376\377\000I\000n\000s\000e\000r\000t\000i\000n\000g\000/\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000s\000e\000q\000u\000e\000n\000c\000e\000s) endobj 709 0 obj << /S /GoTo /D (paragraph.6.2.2.1.4) >> endobj 712 0 obj (\376\377\000I\000n\000s\000e\000r\000t\000i\000n\000g\000/\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000s\000t\000r\000u\000c\000t\000u\000r\000e\000s) endobj 713 0 obj << /S /GoTo /D (paragraph.6.2.2.1.5) >> endobj 716 0 obj (\376\377\000I\000n\000s\000e\000r\000t\000i\000n\000g\000/\000E\000x\000t\000r\000a\000c\000t\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000e\000n\000u\000m\000e\000r\000a\000t\000i\000o\000n) endobj 717 0 obj << /S /GoTo /D (subsubsection.6.2.2.2) >> endobj 720 0 obj (\376\377\000T\000h\000e\000\040\000i\000n\000s\000e\000r\000t\000\040\000a\000n\000d\000\040\000e\000x\000t\000r\000a\000c\000t\000\040\000m\000e\000t\000h\000o\000d\000s\000\040\000o\000f\000\040\000t\000h\000e\000\040\000C\000o\000m\000m\000a\000n\000d\000\040\000c\000l\000a\000s\000s) endobj 721 0 obj << /S /GoTo /D (subsection.6.2.3) >> endobj 724 0 obj (\376\377\000C\000+\000+\000\040\000m\000e\000m\000o\000r\000y\000\040\000m\000a\000n\000a\000g\000e\000m\000e\000n\000t) endobj 725 0 obj << /S /GoTo /D (subsubsection.6.2.3.1) >> endobj 728 0 obj (\376\377\000F\000o\000r\000\040\000s\000t\000r\000i\000n\000g) endobj 729 0 obj << /S /GoTo /D (subsubsection.6.2.3.2) >> endobj 732 0 obj (\376\377\000F\000o\000r\000\040\000a\000r\000r\000a\000y\000/\000s\000e\000q\000u\000e\000n\000c\000e) endobj 733 0 obj << /S /GoTo /D (subsubsection.6.2.3.3) >> endobj 736 0 obj (\376\377\000F\000o\000r\000\040\000s\000t\000r\000i\000n\000g\000\040\000a\000r\000r\000a\000y\000/\000s\000e\000q\000u\000e\000n\000c\000e) endobj 737 0 obj << /S /GoTo /D (subsubsection.6.2.3.4) >> endobj 740 0 obj (\376\377\000F\000o\000r\000\040\000T\000a\000n\000g\000o\000\040\000c\000o\000m\000p\000o\000s\000e\000d\000\040\000t\000y\000p\000e\000s) endobj 741 0 obj << /S /GoTo /D (subsection.6.2.4) >> endobj 744 0 obj (\376\377\000R\000e\000p\000o\000r\000t\000i\000n\000g\000\040\000e\000r\000r\000o\000r\000s) endobj 745 0 obj << /S /GoTo /D (subsubsection.6.2.4.1) >> endobj 748 0 obj (\376\377\000E\000x\000a\000m\000p\000l\000e\000\040\000o\000f\000\040\000t\000h\000r\000o\000w\000i\000n\000g\000\040\000e\000x\000c\000e\000p\000t\000i\000o\000n) endobj 749 0 obj << /S /GoTo /D (section.6.3) >> endobj 752 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000L\000o\000g\000g\000i\000n\000g\000\040\000S\000e\000r\000v\000i\000c\000e\000\040) endobj 753 0 obj << /S /GoTo /D (subsection.6.3.1) >> endobj 756 0 obj (\376\377\000L\000o\000g\000g\000i\000n\000g\000\040\000T\000a\000r\000g\000e\000t\000s) endobj 757 0 obj << /S /GoTo /D (subsection.6.3.2) >> endobj 760 0 obj (\376\377\000L\000o\000g\000g\000i\000n\000g\000\040\000L\000e\000v\000e\000l\000s) endobj 761 0 obj << /S /GoTo /D (subsection.6.3.3) >> endobj 764 0 obj (\376\377\000S\000e\000n\000d\000i\000n\000g\000\040\000T\000A\000N\000G\000O\000\040\000L\000o\000g\000g\000i\000n\000g\000\040\000M\000e\000s\000s\000a\000g\000e\000s) endobj 765 0 obj << /S /GoTo /D (subsubsection.6.3.3.1) >> endobj 768 0 obj (\376\377\000L\000o\000g\000g\000i\000n\000g\000\040\000m\000a\000c\000r\000o\000s\000\040\000i\000n\000\040\000C\000+\000+) endobj 769 0 obj << /S /GoTo /D (subsubsection.6.3.3.2) >> endobj 772 0 obj (\376\377\000C\000+\000+\000\040\000l\000o\000g\000g\000i\000n\000g\000\040\000i\000n\000\040\000t\000h\000e\000\040\000n\000a\000m\000e\000\040\000o\000f\000\040\000a\000\040\000d\000e\000v\000i\000c\000e) endobj 773 0 obj << /S /GoTo /D (section.6.4) >> endobj 776 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000p\000r\000o\000c\000e\000s\000s) endobj 777 0 obj << /S /GoTo /D (subsection.6.4.1) >> endobj 780 0 obj (\376\377\000U\000n\000d\000e\000r\000s\000t\000a\000n\000d\000i\000n\000g\000\040\000t\000h\000e\000\040\000d\000e\000v\000i\000c\000e) endobj 781 0 obj << /S /GoTo /D (subsection.6.4.2) >> endobj 784 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000n\000g\000\040\000d\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 785 0 obj << /S /GoTo /D (subsubsection.6.4.2.1) >> endobj 788 0 obj (\376\377\000S\000t\000a\000n\000d\000a\000r\000d\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 789 0 obj << /S /GoTo /D (subsection.6.4.3) >> endobj 792 0 obj (\376\377\000C\000h\000o\000o\000s\000i\000n\000g\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000t\000a\000t\000e) endobj 793 0 obj << /S /GoTo /D (subsection.6.4.4) >> endobj 796 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000u\000t\000i\000l\000i\000t\000i\000e\000s\000\040\000t\000o\000\040\000e\000a\000s\000e\000\040\000c\000o\000d\000i\000n\000g\000/\000d\000e\000b\000u\000g\000g\000i\000n\000g) endobj 797 0 obj << /S /GoTo /D (subsubsection.6.4.4.1) >> endobj 800 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000v\000e\000r\000b\000o\000s\000e\000\040\000o\000p\000t\000i\000o\000n) endobj 801 0 obj << /S /GoTo /D (subsubsection.6.4.4.2) >> endobj 804 0 obj (\376\377\000C\000+\000+\000\040\000u\000t\000i\000l\000i\000t\000i\000e\000s\000\040\000t\000o\000\040\000e\000a\000s\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000c\000o\000d\000i\000n\000g) endobj 805 0 obj << /S /GoTo /D (subsection.6.4.5) >> endobj 808 0 obj (\376\377\000A\000v\000o\000i\000d\000i\000n\000g\000\040\000n\000a\000m\000e\000\040\000c\000o\000n\000f\000l\000i\000c\000t\000s) endobj 809 0 obj << /S /GoTo /D (subsection.6.4.6) >> endobj 812 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000m\000a\000i\000n\000\040\000f\000u\000n\000c\000t\000i\000o\000n) endobj 813 0 obj << /S /GoTo /D (subsection.6.4.7) >> endobj 816 0 obj (\376\377\000T\000h\000e\000\040\000D\000S\000e\000r\000v\000e\000r\000:\000:\000c\000l\000a\000s\000s\000\137\000f\000a\000c\000t\000o\000r\000y\000\040\000m\000e\000t\000h\000o\000d) endobj 817 0 obj << /S /GoTo /D (subsection.6.4.8) >> endobj 820 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000S\000t\000e\000p\000p\000e\000r\000M\000o\000t\000o\000r\000C\000l\000a\000s\000s\000\040\000c\000l\000a\000s\000s) endobj 821 0 obj << /S /GoTo /D (subsubsection.6.4.8.1) >> endobj 824 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000c\000l\000a\000r\000a\000t\000i\000o\000n\000\040\000f\000i\000l\000e) endobj 825 0 obj << /S /GoTo /D (subsubsection.6.4.8.2) >> endobj 828 0 obj (\376\377\000T\000h\000e\000\040\000s\000i\000n\000g\000l\000e\000t\000o\000n\000\040\000r\000e\000l\000a\000t\000e\000d\000\040\000m\000e\000t\000h\000o\000d\000s) endobj 829 0 obj << /S /GoTo /D (subsubsection.6.4.8.3) >> endobj 832 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000\137\000f\000a\000c\000t\000o\000r\000y\000\040\000m\000e\000t\000h\000o\000d) endobj 833 0 obj << /S /GoTo /D (subsubsection.6.4.8.4) >> endobj 836 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\137\000f\000a\000c\000t\000o\000r\000y\000\040\000m\000e\000t\000h\000o\000d) endobj 837 0 obj << /S /GoTo /D (subsubsection.6.4.8.5) >> endobj 840 0 obj (\376\377\000T\000h\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\137\000f\000a\000c\000t\000o\000r\000y\000\040\000m\000e\000t\000h\000o\000d) endobj 841 0 obj << /S /GoTo /D (subsection.6.4.9) >> endobj 844 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000R\000e\000a\000d\000P\000o\000s\000i\000t\000i\000o\000n\000C\000m\000d\000\040\000c\000l\000a\000s\000s) endobj 845 0 obj << /S /GoTo /D (subsubsection.6.4.9.1) >> endobj 848 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000c\000l\000a\000r\000a\000t\000i\000o\000n\000\040\000f\000i\000l\000e) endobj 849 0 obj << /S /GoTo /D (subsubsection.6.4.9.2) >> endobj 852 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000c\000o\000n\000s\000t\000r\000u\000c\000t\000o\000r) endobj 853 0 obj << /S /GoTo /D (subsubsection.6.4.9.3) >> endobj 856 0 obj (\376\377\000T\000h\000e\000\040\000i\000s\000\137\000a\000l\000l\000o\000w\000e\000d\000\040\000m\000e\000t\000h\000o\000d) endobj 857 0 obj << /S /GoTo /D (subsubsection.6.4.9.4) >> endobj 860 0 obj (\376\377\000T\000h\000e\000\040\000e\000x\000e\000c\000u\000t\000e\000\040\000m\000e\000t\000h\000o\000d) endobj 861 0 obj << /S /GoTo /D (subsection.6.4.10) >> endobj 864 0 obj (\376\377\000T\000h\000e\000\040\000P\000o\000s\000i\000t\000i\000o\000n\000A\000t\000t\000r\000\040\000c\000l\000a\000s\000s) endobj 865 0 obj << /S /GoTo /D (subsubsection.6.4.10.1) >> endobj 868 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000c\000l\000a\000r\000a\000t\000i\000o\000n\000\040\000f\000i\000l\000e) endobj 869 0 obj << /S /GoTo /D (subsubsection.6.4.10.2) >> endobj 872 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000c\000o\000n\000s\000t\000r\000u\000c\000t\000o\000r) endobj 873 0 obj << /S /GoTo /D (subsubsection.6.4.10.3) >> endobj 876 0 obj (\376\377\000T\000h\000e\000\040\000i\000s\000\137\000a\000l\000l\000o\000w\000e\000d\000\040\000m\000e\000t\000h\000o\000d) endobj 877 0 obj << /S /GoTo /D (subsubsection.6.4.10.4) >> endobj 880 0 obj (\376\377\000T\000h\000e\000\040\000r\000e\000a\000d\000\040\000m\000e\000t\000h\000o\000d) endobj 881 0 obj << /S /GoTo /D (subsection.6.4.11) >> endobj 884 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000e\000p\000p\000e\000r\000M\000o\000t\000o\000r\000\040\000c\000l\000a\000s\000s) endobj 885 0 obj << /S /GoTo /D (subsubsection.6.4.11.1) >> endobj 888 0 obj (\376\377\000T\000h\000e\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000c\000l\000a\000r\000a\000t\000i\000o\000n\000\040\000f\000i\000l\000e) endobj 889 0 obj << /S /GoTo /D (subsubsection.6.4.11.2) >> endobj 892 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000n\000s\000t\000r\000u\000c\000t\000o\000r\000s) endobj 893 0 obj << /S /GoTo /D (subsubsection.6.4.11.3) >> endobj 896 0 obj (\376\377\000T\000h\000e\000\040\000m\000e\000t\000h\000o\000d\000s\000\040\000u\000s\000e\000d\000\040\000f\000o\000r\000\040\000t\000h\000e\000\040\000D\000e\000v\000R\000e\000a\000d\000D\000i\000r\000e\000c\000t\000i\000o\000n\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 897 0 obj << /S /GoTo /D (subsubsection.6.4.11.4) >> endobj 900 0 obj (\376\377\000T\000h\000e\000\040\000m\000e\000t\000h\000o\000d\000s\000\040\000u\000s\000e\000d\000\040\000f\000o\000r\000\040\000t\000h\000e\000\040\000P\000o\000s\000i\000t\000i\000o\000n\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 901 0 obj << /S /GoTo /D (subsubsection.6.4.11.5) >> endobj 904 0 obj (\376\377\000T\000h\000e\000\040\000m\000e\000t\000h\000o\000d\000s\000\040\000u\000s\000e\000d\000\040\000f\000o\000r\000\040\000t\000h\000e\000\040\000S\000e\000t\000P\000o\000s\000i\000t\000i\000o\000n\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 905 0 obj << /S /GoTo /D (subsubsection.6.4.11.6) >> endobj 908 0 obj (\376\377\000R\000e\000t\000r\000i\000e\000v\000i\000n\000g\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000r\000o\000p\000e\000r\000t\000i\000e\000s) endobj 909 0 obj << /S /GoTo /D (subsubsection.6.4.11.7) >> endobj 912 0 obj (\376\377\000T\000h\000e\000\040\000r\000e\000m\000a\000i\000n\000i\000n\000g\000\040\000m\000e\000t\000h\000o\000d\000s) endobj 913 0 obj << /S /GoTo /D (section.6.5) >> endobj 916 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000u\000n\000d\000e\000r\000\040\000W\000i\000n\000d\000o\000w\000s) endobj 917 0 obj << /S /GoTo /D (subsection.6.5.1) >> endobj 920 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000g\000r\000a\000p\000h\000i\000c\000a\000l\000\040\000i\000n\000t\000e\000r\000f\000a\000c\000e) endobj 921 0 obj << /S /GoTo /D (subsubsection.6.5.1.1) >> endobj 924 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000m\000a\000i\000n\000\040\000w\000i\000n\000d\000o\000w) endobj 925 0 obj << /S /GoTo /D (subsubsection.6.5.1.2) >> endobj 928 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000n\000s\000o\000l\000e\000\040\000w\000i\000n\000d\000o\000w) endobj 929 0 obj << /S /GoTo /D (subsubsection.6.5.1.3) >> endobj 932 0 obj (\376\377\000T\000h\000e\000\040\000h\000e\000l\000p\000\040\000w\000i\000n\000d\000o\000w) endobj 933 0 obj << /S /GoTo /D (subsection.6.5.2) >> endobj 936 0 obj (\376\377\000M\000F\000C\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 937 0 obj << /S /GoTo /D (subsubsection.6.5.2.1) >> endobj 940 0 obj (\376\377\000T\000h\000e\000\040\000I\000n\000i\000t\000I\000n\000s\000t\000a\000n\000c\000e\000\040\000m\000e\000t\000h\000o\000d) endobj 941 0 obj << /S /GoTo /D (subsubsection.6.5.2.2) >> endobj 944 0 obj (\376\377\000T\000h\000e\000\040\000E\000x\000i\000t\000I\000n\000s\000t\000a\000n\000c\000e\000\040\000m\000e\000t\000h\000o\000d) endobj 945 0 obj << /S /GoTo /D (subsubsection.6.5.2.3) >> endobj 948 0 obj (\376\377\000E\000x\000a\000m\000p\000l\000e\000\040\000o\000f\000\040\000h\000o\000w\000\040\000t\000o\000\040\000b\000u\000i\000l\000d\000\040\000a\000\040\000W\000i\000n\000d\000o\000w\000s\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000M\000F\000C\000\040\000b\000a\000s\000e\000d) endobj 949 0 obj << /S /GoTo /D (subsection.6.5.3) >> endobj 952 0 obj (\376\377\000W\000i\000n\0003\0002\000\040\000a\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n) endobj 953 0 obj << /S /GoTo /D (subsection.6.5.4) >> endobj 956 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000a\000s\000\040\000s\000e\000r\000v\000i\000c\000e) endobj 957 0 obj << /S /GoTo /D (subsubsection.6.5.4.1) >> endobj 960 0 obj (\376\377\000T\000h\000e\000\040\000s\000e\000r\000v\000i\000c\000e\000\040\000c\000l\000a\000s\000s) endobj 961 0 obj << /S /GoTo /D (subsubsection.6.5.4.2) >> endobj 964 0 obj (\376\377\000T\000h\000e\000\040\000m\000a\000i\000n\000\040\000f\000u\000n\000c\000t\000i\000o\000n) endobj 965 0 obj << /S /GoTo /D (subsubsection.6.5.4.3) >> endobj 968 0 obj (\376\377\000S\000e\000r\000v\000i\000c\000e\000\040\000o\000p\000t\000i\000o\000n\000s\000\040\000a\000n\000d\000\040\000m\000e\000s\000s\000a\000g\000e\000s) endobj 969 0 obj << /S /GoTo /D (subsubsection.6.5.4.4) >> endobj 972 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000u\000s\000i\000n\000g\000\040\000M\000F\000C\000\040\000a\000s\000\040\000W\000i\000n\000d\000o\000w\000s\000\040\000s\000e\000r\000v\000i\000c\000e) endobj 973 0 obj << /S /GoTo /D (section.6.6) >> endobj 976 0 obj (\376\377\000C\000o\000m\000p\000i\000l\000i\000n\000g\000,\000\040\000l\000i\000n\000k\000i\000n\000g\000\040\000a\000n\000d\000\040\000e\000x\000e\000c\000u\000t\000i\000n\000g\000\040\000a\000\040\000T\000A\000N\000G\000O\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000p\000r\000o\000c\000e\000s\000s) endobj 977 0 obj << /S /GoTo /D (subsection.6.6.1) >> endobj 980 0 obj (\376\377\000C\000o\000m\000p\000i\000l\000i\000n\000g\000\040\000a\000n\000d\000\040\000l\000i\000n\000k\000i\000n\000g\000\040\000a\000\040\000C\000+\000+\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 981 0 obj << /S /GoTo /D (subsubsection.6.6.1.1) >> endobj 984 0 obj (\376\377\000O\000n\000\040\000U\000N\000I\000X\000\040\000l\000i\000k\000e\000\040\000o\000p\000e\000r\000a\000t\000i\000n\000g\000\040\000s\000y\000s\000t\000e\000m\000\040) endobj 985 0 obj << /S /GoTo /D (paragraph.6.6.1.1.1) >> endobj 988 0 obj (\376\377\000S\000u\000p\000p\000o\000r\000t\000e\000d\000\040\000d\000e\000v\000e\000l\000o\000p\000m\000e\000n\000t\000\040\000t\000o\000o\000l\000s) endobj 989 0 obj << /S /GoTo /D (paragraph.6.6.1.1.2) >> endobj 992 0 obj (\376\377\000C\000o\000m\000p\000i\000l\000i\000n\000g) endobj 993 0 obj << /S /GoTo /D (paragraph.6.6.1.1.3) >> endobj 996 0 obj (\376\377\000L\000i\000n\000k\000i\000n\000g\000\040) endobj 997 0 obj << /S /GoTo /D (subsubsection.6.6.1.2) >> endobj 1000 0 obj (\376\377\000O\000n\000\040\000W\000i\000n\000d\000o\000w\000s\000\040\000u\000s\000i\000n\000g\000\040\000V\000i\000s\000u\000a\000l\000\040\000S\000t\000u\000d\000i\000o) endobj 1001 0 obj << /S /GoTo /D (subsection.6.6.2) >> endobj 1004 0 obj (\376\377\000R\000u\000n\000n\000i\000n\000g\000\040\000a\000\040\000C\000+\000+\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 1005 0 obj << /S /GoTo /D (section.6.7) >> endobj 1008 0 obj (\376\377\000A\000d\000v\000a\000n\000c\000e\000d\000\040\000p\000r\000o\000g\000r\000a\000m\000m\000i\000n\000g\000\040\000t\000e\000c\000h\000n\000i\000q\000u\000e\000s) endobj 1009 0 obj << /S /GoTo /D (subsection.6.7.1) >> endobj 1012 0 obj (\376\377\000R\000e\000c\000e\000i\000v\000i\000n\000g\000\040\000s\000i\000g\000n\000a\000l) endobj 1013 0 obj << /S /GoTo /D (subsubsection.6.7.1.1) >> endobj 1016 0 obj (\376\377\000U\000s\000i\000n\000g\000\040\000s\000i\000g\000n\000a\000l) endobj 1017 0 obj << /S /GoTo /D (subsubsection.6.7.1.2) >> endobj 1020 0 obj (\376\377\000E\000x\000i\000t\000i\000n\000g\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000g\000r\000a\000c\000e\000f\000u\000l\000l\000y) endobj 1021 0 obj << /S /GoTo /D (subsection.6.7.2) >> endobj 1024 0 obj (\376\377\000I\000n\000h\000e\000r\000i\000t\000i\000n\000g) endobj 1025 0 obj << /S /GoTo /D (subsubsection.6.7.2.1) >> endobj 1028 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000B\000C\000l\000a\000s\000s) endobj 1029 0 obj << /S /GoTo /D (subsubsection.6.7.2.2) >> endobj 1032 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000B\000\040\000c\000l\000a\000s\000s) endobj 1033 0 obj << /S /GoTo /D (subsubsection.6.7.2.3) >> endobj 1036 0 obj (\376\377\000W\000r\000i\000t\000i\000n\000g\000\040\000B\000\040\000c\000l\000a\000s\000s\000\040\000s\000p\000e\000c\000i\000f\000i\000c\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1037 0 obj << /S /GoTo /D (subsubsection.6.7.2.4) >> endobj 1040 0 obj (\376\377\000R\000e\000d\000e\000f\000i\000n\000i\000n\000g\000\040\000A\000\040\000c\000l\000a\000s\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1041 0 obj << /S /GoTo /D (subsection.6.7.3) >> endobj 1044 0 obj (\376\377\000U\000s\000i\000n\000g\000\040\000a\000n\000o\000t\000h\000e\000r\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000a\000t\000t\000e\000r\000n\000\040\000i\000m\000p\000l\000e\000m\000e\000n\000t\000a\000t\000i\000o\000n\000\040\000w\000i\000t\000h\000i\000n\000\040\000t\000h\000e\000\040\000s\000a\000m\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 1045 0 obj << /S /GoTo /D (subsection.6.7.4) >> endobj 1048 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000p\000i\000p\000e) endobj 1049 0 obj << /S /GoTo /D (subsubsection.6.7.4.1) >> endobj 1052 0 obj (\376\377\000C\000l\000i\000e\000n\000t\000\040\000r\000e\000a\000d\000i\000n\000g\000\040\000a\000\040\000p\000i\000p\000e) endobj 1053 0 obj << /S /GoTo /D (subsubsection.6.7.4.2) >> endobj 1056 0 obj (\376\377\000C\000l\000i\000e\000n\000t\000\040\000w\000r\000i\000t\000i\000n\000g\000\040\000a\000\040\000p\000i\000p\000e) endobj 1057 0 obj << /S /GoTo /D (chapter.7) >> endobj 1060 0 obj (\376\377\000A\000d\000v\000a\000n\000c\000e\000d\000\040\000f\000e\000a\000t\000u\000r\000e\000s) endobj 1061 0 obj << /S /GoTo /D (section.7.1) >> endobj 1064 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000a\000l\000a\000r\000m\000s) endobj 1065 0 obj << /S /GoTo /D (subsection.7.1.1) >> endobj 1068 0 obj (\376\377\000T\000h\000e\000\040\000l\000e\000v\000e\000l\000\040\000a\000l\000a\000r\000m\000s) endobj 1069 0 obj << /S /GoTo /D (subsection.7.1.2) >> endobj 1072 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000a\000d\000\040\000D\000i\000f\000f\000e\000r\000e\000n\000t\000\040\000t\000h\000a\000n\000\040\000S\000e\000t\000\040\000\050\000R\000D\000S\000\051\000\040\000a\000l\000a\000r\000m) endobj 1073 0 obj << /S /GoTo /D (section.7.2) >> endobj 1076 0 obj (\376\377\000E\000n\000u\000m\000e\000r\000a\000t\000e\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 1077 0 obj << /S /GoTo /D (subsection.7.2.1) >> endobj 1080 0 obj (\376\377\000U\000s\000a\000g\000e\000\040\000i\000n\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000l\000a\000s\000s) endobj 1081 0 obj << /S /GoTo /D (subsubsection.7.2.1.1) >> endobj 1084 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000l\000a\000b\000e\000l\000s\000\040\000w\000i\000t\000h\000\040\000e\000n\000u\000m\000e\000r\000a\000t\000i\000o\000n\000\040\000c\000o\000m\000p\000i\000l\000e\000\040\000t\000i\000m\000e\000\040\000k\000n\000o\000w\000l\000e\000d\000g\000e) endobj 1085 0 obj << /S /GoTo /D (subsubsection.7.2.1.2) >> endobj 1088 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000l\000a\000b\000e\000l\000s\000\040\000w\000i\000t\000h\000o\000u\000t\000\040\000e\000n\000u\000m\000e\000r\000a\000t\000i\000o\000n\000\040\000c\000o\000m\000p\000i\000l\000e\000\040\000t\000i\000m\000e\000\040\000k\000n\000o\000w\000l\000e\000d\000g\000e) endobj 1089 0 obj << /S /GoTo /D (subsubsection.7.2.1.3) >> endobj 1092 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000t\000h\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000v\000a\000l\000u\000e) endobj 1093 0 obj << /S /GoTo /D (subsection.7.2.2) >> endobj 1096 0 obj (\376\377\000U\000s\000a\000g\000e\000\040\000i\000n\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000l\000i\000e\000n\000t) endobj 1097 0 obj << /S /GoTo /D (section.7.3) >> endobj 1100 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000p\000o\000l\000l\000i\000n\000g) endobj 1101 0 obj << /S /GoTo /D (subsection.7.3.1) >> endobj 1104 0 obj (\376\377\000I\000n\000t\000r\000o\000d\000u\000c\000t\000i\000o\000n) endobj 1105 0 obj << /S /GoTo /D (subsection.7.3.2) >> endobj 1108 0 obj (\376\377\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g\000\040\000t\000h\000e\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000s\000y\000s\000t\000e\000m) endobj 1109 0 obj << /S /GoTo /D (subsubsection.7.3.2.1) >> endobj 1112 0 obj (\376\377\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g\000\040\000w\000h\000a\000t\000\040\000h\000a\000s\000\040\000t\000o\000\040\000b\000e\000\040\000p\000o\000l\000l\000e\000d\000\040\000a\000n\000d\000\040\000h\000o\000w) endobj 1113 0 obj << /S /GoTo /D (subsubsection.7.3.2.2) >> endobj 1116 0 obj (\376\377\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g\000\040\000t\000h\000e\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000t\000h\000r\000e\000a\000d\000s\000\040\000p\000o\000o\000l) endobj 1117 0 obj << /S /GoTo /D (subsubsection.7.3.2.3) >> endobj 1120 0 obj (\376\377\000C\000h\000o\000o\000s\000i\000n\000g\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000a\000l\000g\000o\000r\000i\000t\000h\000m) endobj 1121 0 obj << /S /GoTo /D (subsection.7.3.3) >> endobj 1124 0 obj (\376\377\000R\000e\000a\000d\000i\000n\000g\000\040\000d\000a\000t\000a\000\040\000f\000r\000o\000m\000\040\000t\000h\000e\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000b\000u\000f\000f\000e\000r) endobj 1125 0 obj << /S /GoTo /D (subsection.7.3.4) >> endobj 1128 0 obj (\376\377\000R\000e\000t\000r\000i\000e\000v\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d\000/\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000r\000e\000s\000u\000l\000t\000\040\000h\000i\000s\000t\000o\000r\000y) endobj 1129 0 obj << /S /GoTo /D (subsection.7.3.5) >> endobj 1132 0 obj (\376\377\000E\000x\000t\000e\000r\000n\000a\000l\000l\000y\000\040\000t\000r\000i\000g\000g\000e\000r\000e\000d\000\040\000p\000o\000l\000l\000i\000n\000g) endobj 1133 0 obj << /S /GoTo /D (subsection.7.3.6) >> endobj 1136 0 obj (\376\377\000F\000i\000l\000l\000i\000n\000g\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000b\000u\000f\000f\000e\000r) endobj 1137 0 obj << /S /GoTo /D (subsection.7.3.7) >> endobj 1140 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000a\000n\000d\000\040\000t\000u\000n\000i\000n\000g\000\040\000t\000h\000e\000\040\000p\000o\000l\000l\000i\000n\000g\000\040\000i\000n\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000l\000a\000s\000s) endobj 1141 0 obj << /S /GoTo /D (section.7.4) >> endobj 1144 0 obj (\376\377\000T\000h\000r\000e\000a\000d\000i\000n\000g) endobj 1145 0 obj << /S /GoTo /D (subsection.7.4.1) >> endobj 1148 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000p\000r\000o\000c\000e\000s\000s) endobj 1149 0 obj << /S /GoTo /D (subsubsection.7.4.1.1) >> endobj 1152 0 obj (\376\377\000S\000e\000r\000i\000a\000l\000i\000z\000a\000t\000i\000o\000n\000\040\000m\000o\000d\000e\000l\000\040\000w\000i\000t\000h\000i\000n\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 1153 0 obj << /S /GoTo /D (subsubsection.7.4.1.2) >> endobj 1156 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000S\000e\000r\000i\000a\000l\000i\000z\000a\000t\000i\000o\000n\000\040\000m\000o\000d\000e\000l) endobj 1157 0 obj << /S /GoTo /D (subsection.7.4.2) >> endobj 1160 0 obj (\376\377\000C\000l\000i\000e\000n\000t\000\040\000p\000r\000o\000c\000e\000s\000s) endobj 1161 0 obj << /S /GoTo /D (section.7.5) >> endobj 1164 0 obj (\376\377\000G\000e\000n\000e\000r\000a\000t\000i\000n\000g\000\040\000e\000v\000e\000n\000t\000s\000\040\000i\000n\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 1165 0 obj << /S /GoTo /D (section.7.6) >> endobj 1168 0 obj (\376\377\000U\000s\000i\000n\000g\000\040\000m\000u\000l\000t\000i\000c\000a\000s\000t\000\040\000p\000r\000o\000t\000o\000c\000o\000l\000\040\000t\000o\000\040\000t\000r\000a\000n\000s\000f\000e\000r\000\040\000e\000v\000e\000n\000t\000s) endobj 1169 0 obj << /S /GoTo /D (subsection.7.6.1) >> endobj 1172 0 obj (\376\377\000C\000o\000n\000f\000i\000g\000u\000r\000i\000n\000g\000\040\000e\000v\000e\000n\000t\000s\000\040\000t\000o\000\040\000u\000s\000e\000\040\000m\000u\000l\000t\000i\000c\000a\000s\000t\000\040\000t\000r\000a\000n\000s\000p\000o\000r\000t) endobj 1173 0 obj << /S /GoTo /D (subsection.7.6.2) >> endobj 1176 0 obj (\376\377\000D\000e\000f\000a\000u\000l\000t\000\040\000m\000u\000l\000t\000i\000c\000a\000s\000t\000\040\000r\000e\000l\000a\000t\000e\000d\000\040\000p\000r\000o\000p\000e\000r\000t\000i\000e\000s) endobj 1177 0 obj << /S /GoTo /D (section.7.7) >> endobj 1180 0 obj (\376\377\000M\000e\000m\000o\000r\000i\000z\000e\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 1181 0 obj << /S /GoTo /D (section.7.8) >> endobj 1184 0 obj (\376\377\000F\000o\000r\000w\000a\000r\000d\000e\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 1185 0 obj << /S /GoTo /D (subsection.7.8.1) >> endobj 1188 0 obj (\376\377\000D\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 1189 0 obj << /S /GoTo /D (subsection.7.8.2) >> endobj 1192 0 obj (\376\377\000C\000o\000d\000i\000n\000g) endobj 1193 0 obj << /S /GoTo /D (section.7.9) >> endobj 1196 0 obj (\376\377\000T\000r\000a\000n\000s\000f\000e\000r\000r\000i\000n\000g\000\040\000i\000m\000a\000g\000e\000s) endobj 1197 0 obj << /S /GoTo /D (section.7.10) >> endobj 1200 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000w\000i\000t\000h\000\040\000u\000s\000e\000r\000\040\000d\000e\000f\000i\000n\000e\000d\000\040\000e\000v\000e\000n\000t\000\040\000l\000o\000o\000p) endobj 1201 0 obj << /S /GoTo /D (section.7.11) >> endobj 1204 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000u\000s\000i\000n\000g\000\040\000f\000i\000l\000e\000\040\000a\000s\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1205 0 obj << /S /GoTo /D (section.7.12) >> endobj 1208 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000w\000i\000t\000h\000o\000u\000t\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1209 0 obj << /S /GoTo /D (subsection.7.12.1) >> endobj 1212 0 obj (\376\377\000E\000x\000a\000m\000p\000l\000e\000\040\000o\000f\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000s\000t\000a\000r\000t\000e\000d\000\040\000w\000i\000t\000h\000o\000u\000t\000\040\000d\000a\000t\000a\000b\000a\000s\000e\000\040\000u\000s\000a\000g\000e) endobj 1213 0 obj << /S /GoTo /D (subsection.7.12.2) >> endobj 1216 0 obj (\376\377\000C\000o\000n\000n\000e\000c\000t\000i\000n\000g\000\040\000c\000l\000i\000e\000n\000t\000\040\000t\000o\000\040\000d\000e\000v\000i\000c\000e\000\040\000w\000i\000t\000h\000i\000n\000\040\000a\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000s\000t\000a\000r\000t\000e\000d\000\040\000w\000i\000t\000h\000o\000u\000t\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1217 0 obj << /S /GoTo /D (section.7.13) >> endobj 1220 0 obj (\376\377\000M\000u\000l\000t\000i\000p\000l\000e\000\040\000d\000a\000t\000a\000b\000a\000s\000e\000\040\000s\000e\000r\000v\000e\000r\000s\000\040\000w\000i\000t\000h\000i\000n\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000o\000n\000t\000r\000o\000l\000\040\000s\000y\000s\000t\000e\000m) endobj 1221 0 obj << /S /GoTo /D (section.7.14) >> endobj 1224 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s\000\040\000s\000y\000s\000t\000e\000m) endobj 1225 0 obj << /S /GoTo /D (subsection.7.14.1) >> endobj 1228 0 obj (\376\377\000U\000s\000e\000r\000\040\000r\000i\000g\000h\000t\000s\000\040\000d\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 1229 0 obj << /S /GoTo /D (subsection.7.14.2) >> endobj 1232 0 obj (\376\377\000R\000u\000n\000n\000i\000n\000g\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000o\000n\000t\000r\000o\000l\000\040\000s\000y\000s\000t\000e\000m\000\040\000w\000i\000t\000h\000\040\000t\000h\000e\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s) endobj 1233 0 obj << /S /GoTo /D (appendix.A) >> endobj 1236 0 obj (\376\377\000R\000e\000f\000e\000r\000e\000n\000c\000e\000\040\000p\000a\000r\000t) endobj 1237 0 obj << /S /GoTo /D (section.A.1) >> endobj 1240 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1241 0 obj << /S /GoTo /D (subsection.A.1.1) >> endobj 1244 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000b\000l\000a\000c\000k\000\040\000b\000o\000x) endobj 1245 0 obj << /S /GoTo /D (subsection.A.1.2) >> endobj 1248 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000d\000e\000s\000c\000r\000i\000p\000t\000i\000o\000n\000\040\000f\000i\000e\000l\000d) endobj 1249 0 obj << /S /GoTo /D (subsection.A.1.3) >> endobj 1252 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000t\000a\000t\000e\000\040\000a\000n\000d\000\040\000s\000t\000a\000t\000u\000s) endobj 1253 0 obj << /S /GoTo /D (subsection.A.1.4) >> endobj 1256 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000o\000l\000l\000i\000n\000g) endobj 1257 0 obj << /S /GoTo /D (subsection.A.1.5) >> endobj 1260 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000l\000o\000g\000g\000i\000n\000g) endobj 1261 0 obj << /S /GoTo /D (section.A.2) >> endobj 1264 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e) endobj 1265 0 obj << /S /GoTo /D (subsection.A.2.1) >> endobj 1268 0 obj (\376\377\000H\000a\000r\000d\000-\000c\000o\000d\000e\000d\000\040\000d\000e\000v\000i\000c\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1269 0 obj << /S /GoTo /D (subsubsection.A.2.1.1) >> endobj 1272 0 obj (\376\377\000T\000h\000e\000\040\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000d\000a\000t\000a\000\040\000t\000y\000p\000e) endobj 1273 0 obj << /S /GoTo /D (subsubsection.A.2.1.2) >> endobj 1276 0 obj (\376\377\000T\000h\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000d\000a\000t\000a\000\040\000f\000o\000r\000m\000a\000t) endobj 1277 0 obj << /S /GoTo /D (subsubsection.A.2.1.3) >> endobj 1280 0 obj (\376\377\000T\000h\000e\000\040\000m\000a\000x\000\137\000d\000i\000m\000\137\000x\000\040\000a\000n\000d\000\040\000m\000a\000x\000\137\000d\000i\000m\000\137\000y\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1281 0 obj << /S /GoTo /D (subsubsection.A.2.1.4) >> endobj 1284 0 obj (\376\377\000T\000h\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000r\000e\000a\000d\000/\000w\000r\000i\000t\000e\000\040\000t\000y\000p\000e) endobj 1285 0 obj << /S /GoTo /D (subsubsection.A.2.1.5) >> endobj 1288 0 obj (\376\377\000T\000h\000e\000\040\000a\000s\000s\000o\000c\000i\000a\000t\000e\000d\000\040\000w\000r\000i\000t\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1289 0 obj << /S /GoTo /D (subsubsection.A.2.1.6) >> endobj 1292 0 obj (\376\377\000T\000h\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000d\000i\000s\000p\000l\000a\000y\000\040\000l\000e\000v\000e\000l\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1293 0 obj << /S /GoTo /D (subsubsection.A.2.1.7) >> endobj 1296 0 obj (\376\377\000T\000h\000e\000\040\000r\000o\000o\000t\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000n\000a\000m\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1297 0 obj << /S /GoTo /D (subsection.A.2.2) >> endobj 1300 0 obj (\376\377\000M\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1301 0 obj << /S /GoTo /D (subsubsection.A.2.2.1) >> endobj 1304 0 obj (\376\377\000G\000e\000n\000e\000r\000a\000l\000\040\000p\000u\000r\000p\000o\000s\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1305 0 obj << /S /GoTo /D (paragraph.A.2.2.1.1) >> endobj 1308 0 obj (\376\377\000T\000h\000e\000\040\000f\000o\000r\000m\000a\000t\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1309 0 obj << /S /GoTo /D (paragraph.A.2.2.1.2) >> endobj 1312 0 obj (\376\377\000T\000h\000e\000\040\000m\000i\000n\000\137\000v\000a\000l\000u\000e\000\040\000a\000n\000d\000\040\000m\000a\000x\000\137\000v\000a\000l\000u\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1313 0 obj << /S /GoTo /D (paragraph.A.2.2.1.3) >> endobj 1316 0 obj (\376\377\000T\000h\000e\000\040\000m\000e\000m\000o\000r\000i\000z\000e\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1317 0 obj << /S /GoTo /D (subsubsection.A.2.2.2) >> endobj 1320 0 obj (\376\377\000T\000h\000e\000\040\000a\000l\000a\000r\000m\000\040\000r\000e\000l\000a\000t\000e\000d\000\040\000c\000o\000n\000f\000i\000g\000u\000r\000a\000t\000i\000o\000n\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1321 0 obj << /S /GoTo /D (paragraph.A.2.2.2.1) >> endobj 1324 0 obj (\376\377\000T\000h\000e\000\040\000m\000i\000n\000\137\000a\000l\000a\000r\000m\000\040\000a\000n\000d\000\040\000m\000a\000x\000\137\000a\000l\000a\000r\000m\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1325 0 obj << /S /GoTo /D (paragraph.A.2.2.2.2) >> endobj 1328 0 obj (\376\377\000T\000h\000e\000\040\000m\000i\000n\000\137\000w\000a\000r\000n\000i\000n\000g\000\040\000a\000n\000d\000\040\000m\000a\000x\000\137\000w\000a\000r\000n\000i\000n\000g\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1329 0 obj << /S /GoTo /D (paragraph.A.2.2.2.3) >> endobj 1332 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000l\000t\000a\000\137\000t\000\040\000a\000n\000d\000\040\000d\000e\000l\000t\000a\000\137\000v\000a\000l\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1333 0 obj << /S /GoTo /D (subsubsection.A.2.2.3) >> endobj 1336 0 obj (\376\377\000T\000h\000e\000\040\000e\000v\000e\000n\000t\000\040\000r\000e\000l\000a\000t\000e\000d\000\040\000c\000o\000n\000f\000i\000g\000u\000r\000a\000t\000i\000o\000n\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1337 0 obj << /S /GoTo /D (paragraph.A.2.2.3.1) >> endobj 1340 0 obj (\376\377\000T\000h\000e\000\040\000r\000e\000l\000\137\000c\000h\000a\000n\000g\000e\000\040\000a\000n\000d\000\040\000a\000b\000s\000\137\000c\000h\000a\000n\000g\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1341 0 obj << /S /GoTo /D (paragraph.A.2.2.3.2) >> endobj 1344 0 obj (\376\377\000T\000h\000e\000\040\000p\000e\000r\000i\000o\000d\000i\000c\000\040\000p\000e\000r\000i\000o\000d\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1345 0 obj << /S /GoTo /D (paragraph.A.2.2.3.3) >> endobj 1348 0 obj (\376\377\000T\000h\000e\000\040\000a\000r\000c\000h\000i\000v\000e\000\137\000r\000e\000l\000\137\000c\000h\000a\000n\000g\000e\000,\000\040\000a\000r\000c\000h\000i\000v\000e\000\137\000a\000b\000s\000\137\000c\000h\000a\000n\000g\000e\000\040\000a\000n\000d\000\040\000a\000r\000c\000h\000i\000v\000e\000\137\000p\000e\000r\000i\000o\000d\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1349 0 obj << /S /GoTo /D (subsection.A.2.3) >> endobj 1352 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000m\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1353 0 obj << /S /GoTo /D (subsection.A.2.4) >> endobj 1356 0 obj (\376\377\000R\000e\000s\000e\000t\000t\000i\000n\000g\000\040\000m\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1357 0 obj << /S /GoTo /D (section.A.3) >> endobj 1360 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000p\000i\000p\000e) endobj 1361 0 obj << /S /GoTo /D (subsection.A.3.1) >> endobj 1364 0 obj (\376\377\000H\000a\000r\000d\000-\000c\000o\000d\000e\000d\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000i\000p\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1365 0 obj << /S /GoTo /D (subsubsection.A.3.1.1) >> endobj 1368 0 obj (\376\377\000T\000h\000e\000\040\000p\000i\000p\000e\000\040\000r\000e\000a\000d\000/\000w\000r\000i\000t\000e\000\040\000t\000y\000p\000e\000.\000\040) endobj 1369 0 obj << /S /GoTo /D (subsubsection.A.3.1.2) >> endobj 1372 0 obj (\376\377\000T\000h\000e\000\040\000p\000i\000p\000e\000\040\000d\000i\000s\000p\000l\000a\000y\000\040\000l\000e\000v\000e\000l\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1373 0 obj << /S /GoTo /D (subsection.A.3.2) >> endobj 1376 0 obj (\376\377\000M\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000p\000i\000p\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1377 0 obj << /S /GoTo /D (subsection.A.3.3) >> endobj 1380 0 obj (\376\377\000S\000e\000t\000t\000i\000n\000g\000\040\000m\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000p\000i\000p\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1381 0 obj << /S /GoTo /D (subsection.A.3.4) >> endobj 1384 0 obj (\376\377\000R\000e\000s\000e\000t\000t\000i\000n\000g\000\040\000m\000o\000d\000i\000f\000i\000a\000b\000l\000e\000\040\000p\000i\000p\000e\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r\000s) endobj 1385 0 obj << /S /GoTo /D (section.A.4) >> endobj 1388 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000c\000l\000a\000s\000s\000\040\000p\000a\000r\000a\000m\000e\000t\000e\000r) endobj 1389 0 obj << /S /GoTo /D (section.A.5) >> endobj 1392 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000b\000l\000a\000c\000k\000\040\000b\000o\000x) endobj 1393 0 obj << /S /GoTo /D (section.A.6) >> endobj 1396 0 obj (\376\377\000A\000u\000t\000o\000m\000a\000t\000i\000c\000a\000l\000l\000y\000\040\000a\000d\000d\000e\000d\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 1397 0 obj << /S /GoTo /D (subsection.A.6.1) >> endobj 1400 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000t\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1401 0 obj << /S /GoTo /D (subsection.A.6.2) >> endobj 1404 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000t\000u\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1405 0 obj << /S /GoTo /D (subsection.A.6.3) >> endobj 1408 0 obj (\376\377\000T\000h\000e\000\040\000I\000n\000i\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1409 0 obj << /S /GoTo /D (section.A.7) >> endobj 1412 0 obj (\376\377\000D\000S\000e\000r\000v\000e\000r\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000s) endobj 1413 0 obj << /S /GoTo /D (subsection.A.7.1) >> endobj 1416 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000t\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1417 0 obj << /S /GoTo /D (subsection.A.7.2) >> endobj 1420 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000t\000u\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1421 0 obj << /S /GoTo /D (subsection.A.7.3) >> endobj 1424 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000R\000e\000s\000t\000a\000r\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1425 0 obj << /S /GoTo /D (subsection.A.7.4) >> endobj 1428 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000s\000t\000a\000r\000t\000S\000e\000r\000v\000e\000r\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1429 0 obj << /S /GoTo /D (subsection.A.7.5) >> endobj 1432 0 obj (\376\377\000T\000h\000e\000\040\000Q\000u\000e\000r\000y\000C\000l\000a\000s\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1433 0 obj << /S /GoTo /D (subsection.A.7.6) >> endobj 1436 0 obj (\376\377\000T\000h\000e\000\040\000Q\000u\000e\000r\000y\000D\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1437 0 obj << /S /GoTo /D (subsection.A.7.7) >> endobj 1440 0 obj (\376\377\000T\000h\000e\000\040\000K\000i\000l\000l\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1441 0 obj << /S /GoTo /D (subsection.A.7.8) >> endobj 1444 0 obj (\376\377\000T\000h\000e\000\040\000Q\000u\000e\000r\000y\000W\000i\000z\000a\000r\000d\000C\000l\000a\000s\000s\000P\000r\000o\000p\000e\000r\000t\000y\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1445 0 obj << /S /GoTo /D (subsection.A.7.9) >> endobj 1448 0 obj (\376\377\000T\000h\000e\000\040\000Q\000u\000e\000r\000y\000W\000i\000z\000a\000r\000d\000D\000e\000v\000P\000r\000o\000p\000e\000r\000t\000y\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1449 0 obj << /S /GoTo /D (subsection.A.7.10) >> endobj 1452 0 obj (\376\377\000T\000h\000e\000\040\000Q\000u\000e\000r\000y\000S\000u\000b\000D\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1453 0 obj << /S /GoTo /D (subsection.A.7.11) >> endobj 1456 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000r\000t\000P\000o\000l\000l\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1457 0 obj << /S /GoTo /D (subsection.A.7.12) >> endobj 1460 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000o\000p\000P\000o\000l\000l\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1461 0 obj << /S /GoTo /D (subsection.A.7.13) >> endobj 1464 0 obj (\376\377\000T\000h\000e\000\040\000A\000d\000d\000O\000b\000j\000P\000o\000l\000l\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1465 0 obj << /S /GoTo /D (subsection.A.7.14) >> endobj 1468 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000m\000O\000b\000j\000P\000o\000l\000l\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1469 0 obj << /S /GoTo /D (subsection.A.7.15) >> endobj 1472 0 obj (\376\377\000T\000h\000e\000\040\000U\000p\000d\000O\000b\000j\000P\000o\000l\000l\000i\000n\000g\000P\000e\000r\000i\000o\000d\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1473 0 obj << /S /GoTo /D (subsection.A.7.16) >> endobj 1476 0 obj (\376\377\000T\000h\000e\000\040\000P\000o\000l\000l\000e\000d\000D\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1477 0 obj << /S /GoTo /D (subsection.A.7.17) >> endobj 1480 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000P\000o\000l\000l\000S\000t\000a\000t\000u\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1481 0 obj << /S /GoTo /D (subsection.A.7.18) >> endobj 1484 0 obj (\376\377\000T\000h\000e\000\040\000L\000o\000c\000k\000D\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1485 0 obj << /S /GoTo /D (subsection.A.7.19) >> endobj 1488 0 obj (\376\377\000T\000h\000e\000\040\000U\000n\000L\000o\000c\000k\000D\000e\000v\000i\000c\000e\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1489 0 obj << /S /GoTo /D (subsection.A.7.20) >> endobj 1492 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000L\000o\000c\000k\000D\000e\000v\000i\000c\000e\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1493 0 obj << /S /GoTo /D (subsection.A.7.21) >> endobj 1496 0 obj (\376\377\000T\000h\000e\000\040\000D\000e\000v\000L\000o\000c\000k\000S\000t\000a\000t\000u\000s\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1497 0 obj << /S /GoTo /D (subsection.A.7.22) >> endobj 1500 0 obj (\376\377\000T\000h\000e\000\040\000E\000v\000e\000n\000t\000S\000u\000b\000s\000c\000r\000i\000p\000t\000i\000o\000n\000C\000h\000a\000n\000g\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000\040\000\050\000C\000+\000+\000\040\000s\000e\000r\000v\000e\000r\000\040\000o\000n\000l\000y\000\051) endobj 1501 0 obj << /S /GoTo /D (subsection.A.7.23) >> endobj 1504 0 obj (\376\377\000T\000h\000e\000\040\000Z\000m\000q\000E\000v\000e\000n\000t\000S\000u\000b\000s\000c\000r\000i\000p\000t\000i\000o\000n\000C\000h\000a\000n\000g\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000\040) endobj 1505 0 obj << /S /GoTo /D (subsection.A.7.24) >> endobj 1508 0 obj (\376\377\000T\000h\000e\000\040\000E\000v\000e\000n\000t\000C\000o\000n\000f\000i\000r\000m\000S\000u\000b\000s\000c\000r\000i\000p\000t\000i\000o\000n\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1509 0 obj << /S /GoTo /D (subsection.A.7.25) >> endobj 1512 0 obj (\376\377\000T\000h\000e\000\040\000A\000d\000d\000L\000o\000g\000g\000i\000n\000g\000T\000a\000r\000g\000e\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1513 0 obj << /S /GoTo /D (subsection.A.7.26) >> endobj 1516 0 obj (\376\377\000T\000h\000e\000\040\000R\000e\000m\000o\000v\000e\000L\000o\000g\000g\000i\000n\000g\000T\000a\000r\000g\000e\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1517 0 obj << /S /GoTo /D (subsection.A.7.27) >> endobj 1520 0 obj (\376\377\000T\000h\000e\000\040\000G\000e\000t\000L\000o\000g\000g\000i\000n\000g\000T\000a\000r\000g\000e\000t\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1521 0 obj << /S /GoTo /D (subsection.A.7.28) >> endobj 1524 0 obj (\376\377\000T\000h\000e\000\040\000G\000e\000t\000L\000o\000g\000g\000i\000n\000g\000L\000e\000v\000e\000l\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1525 0 obj << /S /GoTo /D (subsection.A.7.29) >> endobj 1528 0 obj (\376\377\000T\000h\000e\000\040\000S\000e\000t\000L\000o\000g\000g\000i\000n\000g\000L\000e\000v\000e\000l\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1529 0 obj << /S /GoTo /D (subsection.A.7.30) >> endobj 1532 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000o\000p\000L\000o\000g\000g\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1533 0 obj << /S /GoTo /D (subsection.A.7.31) >> endobj 1536 0 obj (\376\377\000T\000h\000e\000\040\000S\000t\000a\000r\000t\000L\000o\000g\000g\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d) endobj 1537 0 obj << /S /GoTo /D (section.A.8) >> endobj 1540 0 obj (\376\377\000D\000S\000e\000r\000v\000e\000r\000\040\000c\000l\000a\000s\000s\000\040\000d\000e\000v\000i\000c\000e\000\040\000p\000r\000o\000p\000e\000r\000t\000i\000e\000s) endobj 1541 0 obj << /S /GoTo /D (section.A.9) >> endobj 1544 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000l\000o\000g\000\040\000c\000o\000n\000s\000u\000m\000e\000r\000\040) endobj 1545 0 obj << /S /GoTo /D (subsection.A.9.1) >> endobj 1548 0 obj (\376\377\000T\000h\000e\000\040\000a\000v\000a\000i\000l\000a\000b\000l\000e\000\040\000L\000o\000g\000\040\000C\000o\000n\000s\000u\000m\000e\000r) endobj 1549 0 obj << /S /GoTo /D (subsection.A.9.2) >> endobj 1552 0 obj (\376\377\000T\000h\000e\000\040\000L\000o\000g\000\040\000C\000o\000n\000s\000u\000m\000e\000r\000\040\000i\000n\000t\000e\000r\000f\000a\000c\000e) endobj 1553 0 obj << /S /GoTo /D (section.A.10) >> endobj 1556 0 obj (\376\377\000C\000o\000n\000t\000r\000o\000l\000\040\000s\000y\000s\000t\000e\000m\000\040\000s\000p\000e\000c\000i\000f\000i\000c) endobj 1557 0 obj << /S /GoTo /D (subsection.A.10.1) >> endobj 1560 0 obj (\376\377\000T\000h\000e\000\040\000d\000e\000v\000i\000c\000e\000\040\000c\000l\000a\000s\000s\000\040\000d\000o\000c\000u\000m\000e\000n\000t\000a\000t\000i\000o\000n\000\040\000d\000e\000f\000a\000u\000l\000t\000\040\000v\000a\000l\000u\000e) endobj 1561 0 obj << /S /GoTo /D (subsection.A.10.2) >> endobj 1564 0 obj (\376\377\000T\000h\000e\000\040\000s\000e\000r\000v\000i\000c\000e\000s\000\040\000d\000e\000f\000i\000n\000i\000t\000i\000o\000n) endobj 1565 0 obj << /S /GoTo /D (subsection.A.10.3) >> endobj 1568 0 obj (\376\377\000T\000u\000n\000i\000n\000g\000\040\000t\000h\000e\000\040\000e\000v\000e\000n\000t\000\040\000s\000y\000s\000t\000e\000m\000\040\000b\000u\000f\000f\000e\000r\000s\000\040\000\050\000H\000W\000M\000\051) endobj 1569 0 obj << /S /GoTo /D (subsection.A.10.4) >> endobj 1572 0 obj (\376\377\000A\000l\000l\000o\000w\000i\000n\000g\000\040\000N\000a\000N\000\040\000w\000h\000e\000n\000\040\000w\000r\000i\000t\000i\000n\000g\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000s\000\040\000\050\000f\000l\000o\000a\000t\000i\000n\000g\000\040\000p\000o\000i\000n\000t\000\051) endobj 1573 0 obj << /S /GoTo /D (subsection.A.10.5) >> endobj 1576 0 obj (\376\377\000T\000u\000n\000i\000n\000g\000\040\000m\000u\000l\000t\000i\000c\000a\000s\000t\000i\000n\000g\000\040\000e\000v\000e\000n\000t\000\040\000p\000r\000o\000p\000a\000g\000a\000t\000i\000o\000n) endobj 1577 0 obj << /S /GoTo /D (subsection.A.10.6) >> endobj 1580 0 obj (\376\377\000S\000u\000m\000m\000a\000r\000y\000\040\000o\000f\000\040\000C\000t\000r\000l\000S\000y\000s\000t\000e\000m\000\040\000f\000r\000e\000e\000\040\000o\000b\000j\000e\000c\000t\000\040\000p\000r\000o\000p\000e\000r\000t\000i\000e\000s) endobj 1581 0 obj << /S /GoTo /D (section.A.11) >> endobj 1584 0 obj (\376\377\000C\000+\000+\000\040\000s\000p\000e\000c\000i\000f\000i\000c) endobj 1585 0 obj << /S /GoTo /D (subsection.A.11.1) >> endobj 1588 0 obj (\376\377\000T\000h\000e\000\040\000T\000a\000n\000g\000o\000\040\000m\000a\000s\000t\000e\000r\000\040\000i\000n\000c\000l\000u\000d\000e\000\040\000f\000i\000l\000e\000\040\000\050\000t\000a\000n\000g\000o\000.\000h\000\051) endobj 1589 0 obj << /S /GoTo /D (subsection.A.11.2) >> endobj 1592 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000s\000p\000e\000c\000i\000f\000i\000c\000\040\000p\000r\000e\000-\000p\000r\000o\000c\000e\000s\000s\000o\000r\000\040\000d\000e\000f\000i\000n\000e) endobj 1593 0 obj << /S /GoTo /D (subsection.A.11.3) >> endobj 1596 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000s\000p\000e\000c\000i\000f\000i\000c\000\040\000t\000y\000p\000e\000s) endobj 1597 0 obj << /S /GoTo /D (subsubsection.A.11.3.1) >> endobj 1600 0 obj (\376\377\000T\000e\000m\000p\000l\000a\000t\000e\000\040\000c\000o\000m\000m\000a\000n\000d\000\040\000m\000o\000d\000e\000l\000\040\000r\000e\000l\000a\000t\000e\000d\000\040\000t\000y\000p\000e) endobj 1601 0 obj << /S /GoTo /D (subsection.A.11.4) >> endobj 1604 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000t\000a\000t\000e\000\040\000c\000o\000d\000e) endobj 1605 0 obj << /S /GoTo /D (subsection.A.11.5) >> endobj 1608 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000d\000a\000t\000a\000\040\000t\000y\000p\000e\000\040) endobj 1609 0 obj << /S /GoTo /D (subsection.A.11.6) >> endobj 1612 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000c\000o\000m\000m\000a\000n\000d\000\040\000d\000i\000s\000p\000l\000a\000y\000\040\000l\000e\000v\000e\000l) endobj 1613 0 obj << /S /GoTo /D (section.A.12) >> endobj 1616 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000p\000r\000o\000c\000e\000s\000s\000\040\000o\000p\000t\000i\000o\000n\000\040\000a\000n\000d\000\040\000e\000n\000v\000i\000r\000o\000n\000m\000e\000n\000t\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s) endobj 1617 0 obj << /S /GoTo /D (subsection.A.12.1) >> endobj 1620 0 obj (\376\377\000C\000l\000a\000s\000s\000i\000c\000a\000l\000\040\000d\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r) endobj 1621 0 obj << /S /GoTo /D (subsection.A.12.2) >> endobj 1624 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000s\000e\000r\000v\000e\000r\000\040\000p\000r\000o\000c\000e\000s\000s\000\040\000a\000s\000\040\000W\000i\000n\000d\000o\000w\000s\000\040\000s\000e\000r\000v\000i\000c\000e) endobj 1625 0 obj << /S /GoTo /D (subsection.A.12.3) >> endobj 1628 0 obj (\376\377\000E\000n\000v\000i\000r\000o\000n\000m\000e\000n\000t\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s) endobj 1629 0 obj << /S /GoTo /D (subsubsection.A.12.3.1) >> endobj 1632 0 obj (\376\377\000T\000A\000N\000G\000O\000\137\000H\000O\000S\000T) endobj 1633 0 obj << /S /GoTo /D (subsubsection.A.12.3.2) >> endobj 1636 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000L\000o\000g\000g\000i\000n\000g\000\040\000S\000e\000r\000v\000i\000c\000e\000\040\000\050\000T\000A\000N\000G\000O\000\137\000L\000O\000G\000\137\000P\000A\000T\000H\000\051) endobj 1637 0 obj << /S /GoTo /D (subsubsection.A.12.3.3) >> endobj 1640 0 obj (\376\377\000T\000h\000e\000\040\000d\000a\000t\000a\000b\000a\000s\000e\000\040\000a\000n\000d\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s\000\040\000s\000e\000r\000v\000e\000r\000\040\000\050\000M\000Y\000S\000Q\000L\000\137\000U\000S\000E\000R\000,\000\040\000M\000Y\000S\000Q\000L\000\137\000P\000A\000S\000S\000W\000O\000R\000D\000,\000\040\000M\000Y\000S\000Q\000L\000\137\000H\000O\000S\000T\000\040\000a\000n\000d\000\040\000M\000Y\000S\000Q\000L\000\137\000D\000A\000T\000A\000B\000A\000S\000E\000\051) endobj 1641 0 obj << /S /GoTo /D (subsubsection.A.12.3.4) >> endobj 1644 0 obj (\376\377\000T\000h\000e\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s) endobj 1645 0 obj << /S /GoTo /D (subsubsection.A.12.3.5) >> endobj 1648 0 obj (\376\377\000T\000h\000e\000\040\000e\000v\000e\000n\000t\000\040\000b\000u\000f\000f\000e\000r\000\040\000s\000i\000z\000e) endobj 1649 0 obj << /S /GoTo /D (appendix.B) >> endobj 1652 0 obj (\376\377\000T\000h\000e\000\040\000T\000A\000N\000G\000O\000\040\000I\000D\000L\000\040\000f\000i\000l\000e\000\040\000:\000\040\000M\000o\000d\000u\000l\000e\000\040\000T\000a\000n\000g\000o) endobj 1653 0 obj << /S /GoTo /D (section.B.1) >> endobj 1656 0 obj (\376\377\000A\000l\000i\000a\000s\000e\000s) endobj 1657 0 obj << /S /GoTo /D (section.B.2) >> endobj 1660 0 obj (\376\377\000E\000n\000u\000m\000s) endobj 1661 0 obj << /S /GoTo /D (section.B.3) >> endobj 1664 0 obj (\376\377\000S\000t\000r\000u\000c\000t\000s) endobj 1665 0 obj << /S /GoTo /D (section.B.4) >> endobj 1668 0 obj (\376\377\000U\000n\000i\000o\000n\000s) endobj 1669 0 obj << /S /GoTo /D (section.B.5) >> endobj 1672 0 obj (\376\377\000E\000x\000c\000e\000p\000t\000i\000o\000n\000s) endobj 1673 0 obj << /S /GoTo /D (section.B.6) >> endobj 1676 0 obj (\376\377\000I\000n\000t\000e\000r\000f\000a\000c\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000D\000e\000v\000i\000c\000e) endobj 1677 0 obj << /S /GoTo /D (subsection.B.6.1) >> endobj 1680 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000s) endobj 1681 0 obj << /S /GoTo /D (subsection.B.6.2) >> endobj 1684 0 obj (\376\377\000O\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 1685 0 obj << /S /GoTo /D (section.B.7) >> endobj 1688 0 obj (\376\377\000I\000n\000t\000e\000r\000f\000a\000c\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000D\000e\000v\000i\000c\000e\000\137\0002) endobj 1689 0 obj << /S /GoTo /D (subsection.B.7.1) >> endobj 1692 0 obj (\376\377\000O\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 1693 0 obj << /S /GoTo /D (section.B.8) >> endobj 1696 0 obj (\376\377\000I\000n\000t\000e\000r\000f\000a\000c\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000D\000e\000v\000i\000c\000e\000\137\0003) endobj 1697 0 obj << /S /GoTo /D (subsection.B.8.1) >> endobj 1700 0 obj (\376\377\000O\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 1701 0 obj << /S /GoTo /D (section.B.9) >> endobj 1704 0 obj (\376\377\000I\000n\000t\000e\000r\000f\000a\000c\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000D\000e\000v\000i\000c\000e\000\137\0004) endobj 1705 0 obj << /S /GoTo /D (subsection.B.9.1) >> endobj 1708 0 obj (\376\377\000O\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 1709 0 obj << /S /GoTo /D (section.B.10) >> endobj 1712 0 obj (\376\377\000I\000n\000t\000e\000r\000f\000a\000c\000e\000\040\000T\000a\000n\000g\000o\000:\000:\000D\000e\000v\000i\000c\000e\000\137\0005) endobj 1713 0 obj << /S /GoTo /D (subsection.B.10.1) >> endobj 1716 0 obj (\376\377\000o\000p\000e\000r\000a\000t\000i\000o\000n\000s) endobj 1717 0 obj << /S /GoTo /D (appendix.C) >> endobj 1720 0 obj (\376\377\000T\000a\000n\000g\000o\000\040\000o\000b\000j\000e\000c\000t\000\040\000n\000a\000m\000i\000n\000g\000\040\000\050\000d\000e\000v\000i\000c\000e\000,\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000a\000n\000d\000\040\000p\000r\000o\000p\000e\000r\000t\000y\000\051) endobj 1721 0 obj << /S /GoTo /D (section.C.1) >> endobj 1724 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000n\000a\000m\000e) endobj 1725 0 obj << /S /GoTo /D (section.C.2) >> endobj 1728 0 obj (\376\377\000F\000u\000l\000l\000\040\000o\000b\000j\000e\000c\000t\000\040\000n\000a\000m\000e) endobj 1729 0 obj << /S /GoTo /D (subsection.C.2.1) >> endobj 1732 0 obj (\376\377\000S\000o\000m\000e\000\040\000e\000x\000a\000m\000p\000l\000e\000s) endobj 1733 0 obj << /S /GoTo /D (subsubsection.C.2.1.1) >> endobj 1736 0 obj (\376\377\000F\000u\000l\000l\000\040\000d\000e\000v\000i\000c\000e\000\040\000n\000a\000m\000e\000\040\000e\000x\000a\000m\000p\000l\000e\000s) endobj 1737 0 obj << /S /GoTo /D (subsubsection.C.2.1.2) >> endobj 1740 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000n\000a\000m\000e\000\040\000e\000x\000a\000m\000p\000l\000e\000s) endobj 1741 0 obj << /S /GoTo /D (subsubsection.C.2.1.3) >> endobj 1744 0 obj (\376\377\000A\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000p\000r\000o\000p\000e\000r\000t\000y\000\040\000n\000a\000m\000e) endobj 1745 0 obj << /S /GoTo /D (subsubsection.C.2.1.4) >> endobj 1748 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000p\000r\000o\000p\000e\000r\000t\000y\000\040\000n\000a\000m\000e) endobj 1749 0 obj << /S /GoTo /D (subsubsection.C.2.1.5) >> endobj 1752 0 obj (\376\377\000C\000l\000a\000s\000s\000\040\000p\000r\000o\000p\000e\000r\000t\000y\000\040\000n\000a\000m\000e) endobj 1753 0 obj << /S /GoTo /D (section.C.3) >> endobj 1756 0 obj (\376\377\000D\000e\000v\000i\000c\000e\000\040\000a\000n\000d\000\040\000a\000t\000t\000r\000i\000b\000u\000t\000e\000\040\000n\000a\000m\000e\000\040\000a\000l\000i\000a\000s) endobj 1757 0 obj << /S /GoTo /D (section.C.4) >> endobj 1760 0 obj (\376\377\000R\000e\000s\000e\000r\000v\000e\000d\000\040\000w\000o\000r\000d\000s\000\040\000a\000n\000d\000\040\000c\000h\000a\000r\000a\000c\000t\000e\000r\000s\000,\000\040\000l\000i\000m\000i\000t\000a\000t\000i\000o\000n\000s) endobj 1761 0 obj << /S /GoTo /D (appendix.D) >> endobj 1764 0 obj (\376\377\000S\000t\000a\000r\000t\000i\000n\000g\000\040\000a\000\040\000T\000a\000n\000g\000o\000\040\000c\000o\000n\000t\000r\000o\000l\000\040\000s\000y\000s\000t\000e\000m) endobj 1765 0 obj << /S /GoTo /D (section.D.1) >> endobj 1768 0 obj (\376\377\000W\000i\000t\000h\000o\000u\000t\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1769 0 obj << /S /GoTo /D (section.D.2) >> endobj 1772 0 obj (\376\377\000W\000i\000t\000h\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1773 0 obj << /S /GoTo /D (section.D.3) >> endobj 1776 0 obj (\376\377\000W\000i\000t\000h\000\040\000d\000a\000t\000a\000b\000a\000s\000e\000\040\000a\000n\000d\000\040\000e\000v\000e\000n\000t) endobj 1777 0 obj << /S /GoTo /D (subsection.D.3.1) >> endobj 1780 0 obj (\376\377\000F\000o\000r\000\040\000T\000a\000n\000g\000o\000\040\000r\000e\000l\000e\000a\000s\000e\000s\000\040\000l\000o\000w\000e\000r\000\040\000t\000h\000a\000n\000\040\0008) endobj 1781 0 obj << /S /GoTo /D (subsection.D.3.2) >> endobj 1784 0 obj (\376\377\000F\000o\000r\000\040\000r\000e\000l\000e\000a\000s\000e\000\040\0008\000\040\000a\000n\000d\000\040\000a\000b\000o\000v\000e) endobj 1785 0 obj << /S /GoTo /D (section.D.4) >> endobj 1788 0 obj (\376\377\000W\000i\000t\000h\000\040\000f\000i\000l\000e\000\040\000u\000s\000e\000d\000\040\000a\000s\000\040\000d\000a\000t\000a\000b\000a\000s\000e) endobj 1789 0 obj << /S /GoTo /D (section.D.5) >> endobj 1792 0 obj (\376\377\000W\000i\000t\000h\000\040\000f\000i\000l\000e\000\040\000u\000s\000e\000d\000\040\000a\000s\000\040\000d\000a\000t\000a\000b\000a\000s\000e\000\040\000a\000n\000d\000\040\000e\000v\000e\000n\000t) endobj 1793 0 obj << /S /GoTo /D (subsection.D.5.1) >> endobj 1796 0 obj (\376\377\000F\000o\000r\000\040\000T\000a\000n\000g\000o\000\040\000r\000e\000l\000e\000a\000s\000e\000s\000\040\000l\000o\000w\000e\000r\000\040\000t\000h\000a\000n\000\040\0008) endobj 1797 0 obj << /S /GoTo /D (subsection.D.5.2) >> endobj 1800 0 obj (\376\377\000F\000o\000r\000\040\000r\000e\000l\000e\000a\000s\000e\000\040\0008\000\040\000a\000n\000d\000\040\000a\000b\000o\000v\000e) endobj 1801 0 obj << /S /GoTo /D (section.D.6) >> endobj 1804 0 obj (\376\377\000W\000i\000t\000h\000\040\000t\000h\000e\000\040\000c\000o\000n\000t\000r\000o\000l\000l\000e\000d\000\040\000a\000c\000c\000e\000s\000s) endobj 1805 0 obj << /S /GoTo /D (appendix.E) >> endobj 1808 0 obj (\376\377\000T\000h\000e\000\040\000n\000o\000t\000i\000f\000d\0002\000d\000b\000\040\000u\000t\000i\000l\000i\000t\000y) endobj 1809 0 obj << /S /GoTo /D (section.E.1) >> endobj 1812 0 obj (\376\377\000T\000h\000e\000\040\000n\000o\000t\000i\000f\000d\0002\000d\000b\000\040\000u\000t\000i\000l\000i\000t\000y\000\040\000u\000s\000a\000g\000e\000\040\000\050\000F\000o\000r\000\040\000T\000a\000n\000g\000o\000\040\000r\000e\000l\000e\000a\000s\000e\000s\000\040\000l\000o\000w\000e\000r\000\040\000t\000h\000a\000n\000\040\0008\000\051) endobj 1813 0 obj << /S /GoTo /D (appendix.F) >> endobj 1816 0 obj (\376\377\000T\000h\000e\000\040\000p\000r\000o\000p\000e\000r\000t\000y\000\040\000f\000i\000l\000e\000\040\000s\000y\000n\000t\000a\000x) endobj 1817 0 obj << /S /GoTo /D (section.F.1) >> endobj 1820 0 obj (\376\377\000P\000r\000o\000p\000e\000r\000t\000y\000\040\000f\000i\000l\000e\000\040\000u\000s\000a\000g\000e) endobj 1821 0 obj << /S /GoTo /D (section.F.2) >> endobj 1824 0 obj (\376\377\000P\000r\000o\000p\000e\000r\000t\000y\000\040\000f\000i\000l\000e\000\040\000s\000y\000n\000t\000a\000x) endobj 1825 0 obj << /S /GoTo /D [1826 0 R /Fit] >> endobj 1829 0 obj << /Length 265 /Filter /FlateDecode >> stream xÚ}‘KKÄ@ Çïó)rlÁf“tžGŸ‹ *âàE<­ضØ]ûív\XeIHòKò‚W X*úÞDµ¸0Bh­ˆ/ÀÚbmoP‡ñŠøÖ–•*bêâøzy“ÃӡߎÃ:w»Í¶í²ÕôŸÍº|Œ«Ä¯ðÉ£3*a ì3ÿ¾dæ¢K¦bó>ôP&‚:ŠÓºœ@‚âˆ1ÈFÃS§>” óµ3sÉ¡?'§†ÜM„iðwfqÙ1œ ê6½=½Úã«þ^#NûšdÓ SÖZ \kòÿkKGEÛtÓ) Ñ׉îÑÉm«I©q—kYeGˆí|ûïKZ|¡fë endstream endobj 1826 0 obj << /Type /Page /Contents 1829 0 R /Resources 1828 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R >> endobj 1827 0 obj << /Type /XObject /Subtype /Image /Width 297 /Height 419 /BitsPerComponent 8 /Length 36356 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF,,ÿá²ExifMM*bj(1r2‡i¤Ð,,Adobe Photoshop CS Macintosh2006:08:16 16:56:11 ÿÿ Ö @&(.{HHÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ q"ÿÝÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?óÝqq›~.*>¥Ÿ¾ï¼¤îJŠJgêÛûîÿ8¤.¼„ùÇûÔRIVdä-³üçz¶eŽ/³ü÷z€¬–΀€~k@t.¤0hê¢1²· \ÜàÒ¿gÒcg³Ôzº@&ëZÔ´Ænol‹ÏwþI8ê㌛‡ýqßù%ºß©yÇêýýaͶ£ŽÁhªÆDÕ§¨ïÍú·oÿÀÿ=sp ýA}[´úã.ÿûuÿù$ã«uQÆf@ÿ®¿ÿ$ª¥¢(¶àë]`qŸ’?ëÖäÓþÜëCþô2¿íë?òj«X×;nè&.ÐOò榶»*±ÕØÒËK\ÓÈ!%7]ëŸùc—ÿoÙÿ“Oÿ8:ð˜êYcOôöÿäÕIOѾ­ßé_þ{¿½%‘SÿÐò÷rS'w%2J^<9V³0F6ÂÛ·±,üö—¿Ó°3v×{Õm¤ëÀì¹[êLæç[•M,ÃkÜKj«€ Ÿ¥ùþï~í¿Î oE(Þýàc4¾ÌkìeVÚZÚÛa&wn²Ï ÍŸ×^‰ƒƒ‰SªèÆeMƭ̶Ãí5¾Ç\ÜM¿££}{þÔßø/ðKÊÉ.t»Ry*÷Hê7ôìÆdSa¨·Iäi¿º›(u] œØ»Ð×gÖ¾¸; dzƹØ×V]¶·­.­ó·w©Cn©ŒÜ¼c´­ÿ­?Zrºëqix5SŽÉ}aÒÇÜK¿XÛüš§^ÿ¡úOô‹4F1"íYgÃö÷c ®è}¦u\aÖ#=¶`-!ÛwUê=îú;=ÞÏræp®f>UW¾¦^ڞךlúÚwl²?1˹é=AØØ9ýPkëµö hçû½¥ßÕg¹G˜òÕ~ ?—‚o©¸yµâºyìlÚâ?³¸ Œn……_Nê4ûlÈkñ²Yü¼}ž•³ûÎÇ{+üRìþªÑc:V%¶?‘ ÿ/Þßûn†ÓXãQî+¥°í;ò2\ãÞCiÿɨñ“îo}Î cº¢u|ß²cßàSΑà˜÷øi®ý’xI%?ÿÑórQIöú€µ¯Ô!ôßÉVs2òÇ0ÉØñæí?¬ˆA¾Œm-$»†´µ£ï€ª”z{Èv¾×Dýè'“ ‚—e$¥l9€;¶„j0r/Ìl0ròa¢jýÎÁ¾eiW‡ÔËÜÛE¬¬`d}7ãý=Ÿðõz´¤NŠŒMê,x:U…¸îȲÝà4ÃG´LhíÞÿ¢ªcfu@Ö`7%ÌÂþhAi[?DnK+©W‡F=­s1mÜ꟨†{]Nÿø;6úÌÿ=nt¾•]™˜²˜ëXÍu–J¹wüc½g*Ù2pš–·³©ÉòC,HÜxz[×ô¬ÏÔqïÛO†é !ŸÈ«cgøÈéùêÿ¯S=Jq²j¶×ô´ŒGÿcסŸöýK,õS)ÿgs†%nô1›2>“žëë›güZí°6u®‹VMm{l`c˜ïtµ®s]¹ŸEÍÿÕ3S=i9¹Y "gA-?Æ|5D÷ø.»üetn™Ò:å5têÛEwã‹,¥³áÖW½üÆØÖýÉÿtæð’ ôl‘v$ŠÿÒóòTS»’˜”–€àíÐ`‚ÙàIóà ž—i¯šéúž}Ý;êöC©Ís^Ñ—˜ÁXÛs}ZÚû œ÷[V;ë§èUé®`-í¨@ºé¢é@Ä!D/ñ¶Xˆ1!Þcý©$×Cƒ£ƒ)ßÒÞñ÷¢µa<ð{+X™ù8·Wu6í¤ÍnGùßœªê@ê­^þÀÏ­:ƒv@ÃÌÅuŽÇ´‰©î°WêúÖ·ÞÏæYúOðè¬YUõ±ÑÅYxæÌmÇìùµÿ4òÂæ´×{Ccw³þ 똦û¨vúžXížGsd~w¹uëîNè2Ú,¡óê6Ó?Ks>‡ºTSÆ+QÄ:U³‡šÉŒÜ&q’*_¥ÿz+S¥u:iûm@˜<Ÿi¯Ú?9Î^­õG§Y…Ó›‘“"ëÀ¦LŠÁþn–ÿÅÿçÍë¢ýFúÀj̧”^×5àÒ}6’Ó»m”·ôÖý?øÁúÑ_FèîéøÏoÍi®°9egÙmçoÑöþŽŸøOø¥`ì]ží¬¼æL˜cŽ|"ëÓ|ËëgYwZëùyÛ·T^kÇðW,ª?¯üïýqcžÿéuh æ“džïÒ©'‚’(ÿÓóJˆè5'@>*o‰)èsY}oq†µÀ“Æ€ÊI¿¯2‹u‡6*ªºŸ\¶Cƒ?K-oé7ooó—ÛkȤÓsê:í<ùrÖH¦›©c=FSÓo´¸5ÕzSüõ¶îÞ÷ªn±–äUq­¶úzšœ iÖvY75C(“¡£ùº<ÙÅ–õDN&¿Ðý+WIèy}L—¶(Ägó¹VhÆôƒ'o«oüëžš¿›GD©‡§ÑëÎe®%Çú­Yÿ¦ÉÌÌÏÙö—5•WªX6ÖÁÙ¬©¾ÔÎm ÕÖ_íJFgÃÀ-Äy\b¬NGyÊ<_âÑj fPeL¤ "]XycA{x¿ô\„û«°@ùÿ’B"cuóÉ‚Q¨~”Ös è›ljíº1/ʱµPÝÖ<ín£“ü¥QÁÁÄ:d3Ο(7§fŽHT¨Ô¾^Íœ£—ÓïeøvÞØ$AþK›û©º—QÌêy–fæYê]g'€Ñµ±¿™[?5WL ºbâ5W§eBDh~ Ò<‚(~•I<$’_ÿÔóòTS¸êS$¦îVMW¾‡Ì9´ÖË Gº±éÿkØÖ&9Aº4ʳõq³2ÚÜÖ¿uGh{C†íÌÚv»úÊ}CöCqÚÆ~Ó«™[cc×Ó¹Îú_ð~—ø$Ã/W ÏTœ^ïˆÔQë4dñåFö›œòçwðÕ5¯¿)t裖ӰÛ”8½@l¿îâ8¥/›MÚ€¥Þ}èØÏ t;PPw{cÎSOtò,S^1#£±Kö½®o- ’]ÇmyÆúÄU–Ñ{GƒœH¹ŸÙ¹¯A¦é^Í?iéu~Ãÿƒ·ôv›siP‹ŒÇ¥ÒÉY¹iWÍÖGüŸþcŒ’I‰S¹L“Á$%?MlII/ÿÕò÷rTTÉQI-œ ë02FE`9À{‚´oê?3Õ=‡Ç8;tüÖ×3ó¶—1ÛêýÅŠR ¦›ëÝ›5“ Jýÿç6[“]z¸´Àwä¡Ù{íq8B„á ¬–iÊ<7éìI(Jc]-+W§X.s±ÜDd±Ôëĸ~ŒÿfßMdÇ‚-6j x&N6<[¶onZ뤇‚2$hAñL‹•g«‘e±çs€ñ"]ÿIþÃ]ÿ¤ÒS˜'²Óÿ›Y¿ò£8è5¿úMGþl}eÿÊœïý†·ÿI¢§18Z?ógë'þTæÿì5¿úM/ùµõÿ*³ößý&‚œå !_ÿ›ŸX‡ýåæÿì=¿úM/ù¿õ€ÞfgþÃÛÿE£¤&!_ý×ÿò·/ÿaíÿÈ&ýƒ×¿ò·/þØ·ÿ ’š0™Ü¡û ®åv_ý±gþAEÝ ­Áÿ'eÛäSô¼¤‡'ÀýÉ —ÿÙÿí2’Photoshop 3.08BIM%8BIMê¦ com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2006-08-16T14:54:28Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName A4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2003-07-01T17:49:36Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMéxHH/ÿîÿî8Ag{àHHØ(dÿh 8BIMí,,8BIM&?€8BIM 8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM@@8BIM8BIMW@Öphoto pub 2007 okÖ@nullboundsObjcRct1Top longLeftlongBtomlong@RghtlongÖslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong@RghtlongÖurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?ð8BIM8BIM —q TÔ€{ÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀ q"ÿÝÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?óÝqq›~.*>¥Ÿ¾ï¼¤îJŠJgêÛûîÿ8¤.¼„ùÇûÔRIVdä-³üçz¶eŽ/³ü÷z€¬–΀€~k@t.¤0hê¢1²· \ÜàÒ¿gÒcg³Ôzº@&ëZÔ´Ænol‹ÏwþI8ê㌛‡ýqßù%ºß©yÇêýýaͶ£ŽÁhªÆDÕ§¨ïÍú·oÿÀÿ=sp ýA}[´úã.ÿûuÿù$ã«uQÆf@ÿ®¿ÿ$ª¥¢(¶àë]`qŸ’?ëÖäÓþÜëCþô2¿íë?òj«X×;nè&.ÐOò榶»*±ÕØÒËK\ÓÈ!%7]ëŸùc—ÿoÙÿ“Oÿ8:ð˜êYcOôöÿäÕIOѾ­ßé_þ{¿½%‘SÿÐò÷rS'w%2J^<9V³0F6ÂÛ·±,üö—¿Ó°3v×{Õm¤ëÀì¹[êLæç[•M,ÃkÜKj«€ Ÿ¥ùþï~í¿Î oE(Þýàc4¾ÌkìeVÚZÚÛa&wn²Ï ÍŸ×^‰ƒƒ‰SªèÆeMƭ̶Ãí5¾Ç\ÜM¿££}{þÔßø/ðKÊÉ.t»Ry*÷Hê7ôìÆdSa¨·Iäi¿º›(u] œØ»Ð×gÖ¾¸; dzƹØ×V]¶·­.­ó·w©Cn©ŒÜ¼c´­ÿ­?Zrºëqix5SŽÉ}aÒÇÜK¿XÛüš§^ÿ¡úOô‹4F1"íYgÃö÷c ®è}¦u\aÖ#=¶`-!ÛwUê=îú;=ÞÏræp®f>UW¾¦^ڞךlúÚwl²?1˹é=AØØ9ýPkëµö hçû½¥ßÕg¹G˜òÕ~ ?—‚o©¸yµâºyìlÚâ?³¸ Œn……_Nê4ûlÈkñ²Yü¼}ž•³ûÎÇ{+üRìþªÑc:V%¶?‘ ÿ/Þßûn†ÓXãQî+¥°í;ò2\ãÞCiÿɨñ“îo}Î cº¢u|ß²cßàSΑà˜÷øi®ý’xI%?ÿÑórQIöú€µ¯Ô!ôßÉVs2òÇ0ÉØñæí?¬ˆA¾Œm-$»†´µ£ï€ª”z{Èv¾×Dýè'“ ‚—e$¥l9€;¶„j0r/Ìl0ròa¢jýÎÁ¾eiW‡ÔËÜÛE¬¬`d}7ãý=Ÿðõz´¤NŠŒMê,x:U…¸îȲÝà4ÃG´LhíÞÿ¢ªcfu@Ö`7%ÌÂþhAi[?DnK+©W‡F=­s1mÜ꟨†{]Nÿø;6úÌÿ=nt¾•]™˜²˜ëXÍu–J¹wüc½g*Ù2pš–·³©ÉòC,HÜxz[×ô¬ÏÔqïÛO†é !ŸÈ«cgøÈéùêÿ¯S=Jq²j¶×ô´ŒGÿcסŸöýK,õS)ÿgs†%nô1›2>“žëë›güZí°6u®‹VMm{l`c˜ïtµ®s]¹ŸEÍÿÕ3S=i9¹Y "gA-?Æ|5D÷ø.»üetn™Ò:å5têÛEwã‹,¥³áÖW½üÆØÖýÉÿtæð’ ôl‘v$ŠÿÒóòTS»’˜”–€àíÐ`‚ÙàIóà ž—i¯šéúž}Ý;êöC©Ís^Ñ—˜ÁXÛs}ZÚû œ÷[V;ë§èUé®`-í¨@ºé¢é@Ä!D/ñ¶Xˆ1!Þcý©$×Cƒ£ƒ)ßÒÞñ÷¢µa<ð{+X™ù8·Wu6í¤ÍnGùßœªê@ê­^þÀÏ­:ƒv@ÃÌÅuŽÇ´‰©î°WêúÖ·ÞÏæYúOðè¬YUõ±ÑÅYxæÌmÇìùµÿ4òÂæ´×{Ccw³þ 똦û¨vúžXížGsd~w¹uëîNè2Ú,¡óê6Ó?Ks>‡ºTSÆ+QÄ:U³‡šÉŒÜ&q’*_¥ÿz+S¥u:iûm@˜<Ÿi¯Ú?9Î^­õG§Y…Ó›‘“"ëÀ¦LŠÁþn–ÿÅÿçÍë¢ýFúÀj̧”^×5àÒ}6’Ó»m”·ôÖý?øÁúÑ_FèîéøÏoÍi®°9egÙmçoÑöþŽŸøOø¥`ì]ží¬¼æL˜cŽ|"ëÓ|ËëgYwZëùyÛ·T^kÇðW,ª?¯üïýqcžÿéuh æ“džïÒ©'‚’(ÿÓóJˆè5'@>*o‰)èsY}oq†µÀ“Æ€ÊI¿¯2‹u‡6*ªºŸ\¶Cƒ?K-oé7ooó—ÛkȤÓsê:í<ùrÖH¦›©c=FSÓo´¸5ÕzSüõ¶îÞ÷ªn±–äUq­¶úzšœ iÖvY75C(“¡£ùº<ÙÅ–õDN&¿Ðý+WIèy}L—¶(Ägó¹VhÆôƒ'o«oüëžš¿›GD©‡§ÑëÎe®%Çú­Yÿ¦ÉÌÌÏÙö—5•WªX6ÖÁÙ¬©¾ÔÎm ÕÖ_íJFgÃÀ-Äy\b¬NGyÊ<_âÑj fPeL¤ "]XycA{x¿ô\„û«°@ùÿ’B"cuóÉ‚Q¨~”Ös è›ljíº1/ʱµPÝÖ<ín£“ü¥QÁÁÄ:d3Ο(7§fŽHT¨Ô¾^Íœ£—ÓïeøvÞØ$AþK›û©º—QÌêy–fæYê]g'€Ñµ±¿™[?5WL ºbâ5W§eBDh~ Ò<‚(~•I<$’_ÿÔóòTS¸êS$¦îVMW¾‡Ì9´ÖË Gº±éÿkØÖ&9Aº4ʳõq³2ÚÜÖ¿uGh{C†íÌÚv»úÊ}CöCqÚÆ~Ó«™[cc×Ó¹Îú_ð~—ø$Ã/W ÏTœ^ïˆÔQë4dñåFö›œòçwðÕ5¯¿)t裖ӰÛ”8½@l¿îâ8¥/›MÚ€¥Þ}èØÏ t;PPw{cÎSOtò,S^1#£±Kö½®o- ’]ÇmyÆúÄU–Ñ{GƒœH¹ŸÙ¹¯A¦é^Í?iéu~Ãÿƒ·ôv›siP‹ŒÇ¥ÒÉY¹iWÍÖGüŸþcŒ’I‰S¹L“Á$%?MlII/ÿÕò÷rTTÉQI-œ ë02FE`9À{‚´oê?3Õ=‡Ç8;tüÖ×3ó¶—1ÛêýÅŠR ¦›ëÝ›5“ Jýÿç6[“]z¸´Àwä¡Ù{íq8B„á ¬–iÊ<7éìI(Jc]-+W§X.s±ÜDd±Ôëĸ~ŒÿfßMdÇ‚-6j x&N6<[¶onZ뤇‚2$hAñL‹•g«‘e±çs€ñ"]ÿIþÃ]ÿ¤ÒS˜'²Óÿ›Y¿ò£8è5¿úMGþl}eÿÊœïý†·ÿI¢§18Z?ógë'þTæÿì5¿úM/ùµõÿ*³ößý&‚œå !_ÿ›ŸX‡ýåæÿì=¿úM/ù¿õ€ÞfgþÃÛÿE£¤&!_ý×ÿò·/ÿaíÿÈ&ýƒ×¿ò·/þØ·ÿ ’š0™Ü¡û ®åv_ý±gþAEÝ ­Áÿ'eÛäSô¼¤‡'ÀýÉ —ÿÙ8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMÿá http://ns.adobe.com/xap/1.0/ 4294967295 1494 2112 1 300/1 300/1 2 2006-08-16T16:56:11+02:00 2006-08-16T16:56:11+02:00 2006-08-16T16:56:11+02:00 Adobe Photoshop CS Macintosh adobe:docid:photoshop:13f3a912-2d9d-11db-8d22-860a69fa5459 image/jpeg ÿâ@ICC_PROFILE0ADBEmntrRGB XYZ ÏacspAPPLnoneöÖÓ-ADBE cprtü2desc0kwtptœbkpt°rTRCÄgTRCÔbTRCärXYZôgXYZbXYZtextCopyright 1999 Adobe Systems IncorporateddescAdobe RGB (1998)XYZ óQÌXYZ curv3curv3curv3XYZ œO¥üXYZ 4 ,•XYZ &1/¾œÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ£)"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ñ™uÆcºêcÿ5¼¹#ý|¿÷ѦIÖ£þC$û]Æ×Éÿ}_µÜ`~úOûèÔ½…Kö»ùï'ýõNûmÎ?×Éÿ}Uz^ÔŸí·_óñ/ýõH/®¿çæ_ûèÔ&“µY÷yé2ÿßf¨^ÿSßf«Ž¢“µZ•öOúdÿ÷Ù¥þÓ¿Ïü~Ïÿ Té{ÐÁ«j#¥õÇýü4á¬jC8¿¹ÿ¿†¨ƒKÐsùPïí­S?òºÿ¿¦”ëš®?ä%uÿMgçšBxühGûwWÿ ßýý4ïíý\tÕ.ÿïé¬ÊS@\Ò!Ö‡MVóþÿpñ&¸:j÷£þÛ7øÖ]ÍQâ|tÖo‡ý·jQâ¿Æ·ÿÚ²iJæÏü%¾"Çü‡/ÿïûQÿ ˆøÿ‰î¡ÿÚ±CIé@înø”t×µûþÔáãOùê?÷ý«–€¹¾Õ:õÙׂAï_R}¶ãþzʾ1²ÿ¸¿ß_ç_cÓñ¤j?á©$ëLÇ) a¥ì(4vRö õ¤ïZA@ê(íJ:Òv ÿ^ôô¸ë@ F ÍSЀ>”Îô„gÿ¯Så0˜_›Äž´÷„¼fcÜýÐ;Ð+a€Î8¥ëWcÓ®d•`’Ìx½I¨è×zb©•8<^@üi]W3ðE%/<ðx¤¦ 4ÑÒŠhé@cô¤i{Qé@é¢J%/­*®XÔšPŒÌUA&€zRqE4Ðw£ÖŽô¾´(¥îh¨îhOJo¥;Ö›é@ì¿ãò÷×ùרÕñÍ—ü}Åþúÿ:û„Æ’u¨ÿ†¤~µðÐRö”½…”£¥ ¢€H)ǽ7µu¤íJ:ŠNÔõ=²ù’”ù‡z€w©"`’«H3ŒŠ}Ôk€Jµ¢hókz´:|,¥<±è£¹©o,Œ³'—·qx! ¾¹õíŠÚøu ƒÅJ’|¦Hš5'׎?JMÙ3H$ä“4õ¿‡0éPÃäÝI,³å9$c·N:×)s§Ëöx¤Ù…ÎЙÎM{Åĺ‹ã†Xäû$(ÒÛ»°ÇOsXv¾¿¬¡7´iw œ•ô¬)Ôoszô’k•žðõíäPÊÐÉÃr\æ»ío¯yáûå¶¶„'’^RÇ,vŒµÒÛÀ¶v¹0qÚ²“ŶV÷2A2¼°²²9‡æÙ~÷µwcŒš¥Á*:–b¦WÛÓqÇÒ£­Î1)½©äS{S;QéK”óøR@âÜñZºV…q©n+ò€3õ¦Ï¤Km ÆåÉL~<ñ½‹äv¹B9$2ãäç¥(‘ÔäcÒ´bÒ¥e¼P¹1"±üEVk D¬›N6u¹Ð¹Xûxcº“É—“ÒE>¢ªÝÚËgu%¼Ë‡¶‘Zzv3Ê„Ø߯ùúWg®xYu? ¾£ /öÛXÃ1ƃ¨>à~‚£Ú$ìRƒhóÖ”u4¬0i;ÖÄô¤îiÊ:Ðà ԇ¥'¥)àS})nËþ?!ÿ}}_ÙÇÜ_ï¯ó¯±© >4“­3øiòu¦ %(è);Òö QH)Ã¥曊uIoÚ.cˆaw¸\КGCi-`žÍšc${ö㓎pJÊÉå6€àŸzë£Õíô{4Z/˜Öþa”·Ìn1ôÀÎNò˾h*Œ3…è®+5'#iA%æP©­“̺0Næ½[°X<Ó Ú>îE2IV ¡4 府«/>¢´0¾¶7.ôÉã·†Óî˳-‘óyÆkªðç‚_PÑÄ?“r®9@û¸®Bñ Ó/<ÉâûB1Ë~oν_ÃÞ.Ñ®`1Çy.ßòÎS·öëXTr:)rßRÍ¿Šã¾‘´ß³šµæåb;­oéÙVc9¯*Ñ®„:Íʰëךõ)ÃÚ `“P»›)9;3¬ÓÄ3¹ºù☱©ŒDá7|ÓBlôÁ¦išÌªÑ!ÀHn¢C‚çh>`üsšó×#ˆrñƒ…,1‘î)÷——×Mqu3Í3}çs’j§jˆÆÛšJ|Å£¨ÌÃiGN•°fÈ~5.9ª"Š‘OZ`¸Æq@l®ž ´ub9õ¯QðïŒ(–+–Øz+v5ähÌ®:Vå½Ò¼œuÅ7A¸;£Ýnõ”‡Ã—ºƒ¡–#Þ|¹ Ÿnžø¯×uûýzì\_Îò²®ÄÜsµsœUûßjcF—Km6·rÎ+šcšˆÂÛšN¯:²F)®ÆCH¦Å<ý)£¥=ÊkÑü%—cáÖº–Oô»‚S~2±Øã¥yÊž+ON¼h&]£cóFƒYÔãcJRåšgA`È·÷8 C¶xö¯SÓ'û>‘`$l̬Aïÿë¯7Ò’9»Àé ùã è?:ë./ÖÄFÇSœôÎ2Z㞈펬ÀÕuw–êéŒÌŠ¤ç£’?QùW i0:iâM˜’iL‡ØmͱøW“é*úÆ­…†ö9¯n°„•Ù÷R5ç¯]ÇôÀ¢Z+ÂîW-Ä‚ÙÒ<…‡æOô¦ÀÁîgä¼àíM´v¾–[’GB2àOò§ÙÆ>ÕlÀY7·>œÔGsg±äßåŠ_ÂbHmÑß9"¼œõ5éŸTNIÎcB9í´W™ž¦½lpOqêËŽri‡©¤w5déMô§†“°¦«/øü‡ýõþuö5|ueÿÿ¾¿Î¾Æü)ñ¬j>Õ#õ¨ûPRŽ‚ŠQÐS –ZfÚ:w>”2‰ ÀúûÖ†Ô‚!Ž$úšd¶U» â8ÿ„QžƒûË’Ý…=— sŠ@T?z™Úœµ7µïGzz^ô-?Öš)}hyÍ!b1´‘Ïj^ôÖ>´¼OfÍÕ—­T"ŽˆUI=ªÏ•æ&d 7¨ÉØ©N¥ «pqE!ˆGÐ8©1RAk,äSõ4 jB£ƒR©#pkZ Lbßð©ukYh‰Q”#<ÿJŽx”éÊ×:_Gö„ˆË*ùhw°fûǰþµ¹¬Íoö6·IU¤òsÐzW’<æ2V|žãŠe²JgŽFf9n¤Ö£}nuRªö±ê> ³ò$¼¹(6ù¿z@¹fÓ¤’#ÌÄç˜ÿë ó=áí´i£f˜€¹õ<Ÿé^¦îÙom@p÷'üë\Òwv7JÆÍ”‰¼!p¢!‘þÑ?ýj«srÖö r2 Èõçôâ›-Îd3ÈHÊ1ýjMbÌÜx$I bhß;½sÏõ¢:‰«Yñ¶ÒAâõ»Ú<¹!A¸nõåÎ¥Xƒßšö‹¬· ¦»KÛ©Ç~ƒü y¤—9úWu7tqUVÁGs@¥îkC1zo¥8ô4…1–¬y¼‡ýõþuö5|seÍä?ï¯ó¯±¨ãWëQÿ I'Zøi¨¥ÛhêjòY›¿„KÒ£Ó„fëtÛ€=I­[ß—OؽpFWBÖÆU£aŒ¤dô©BNsøTH<´Á#5“së@[RXð®Ò>(õ5ÎÄœÑ4¾`@1×ëSÍÚ0y¤!ÔRv§‡Å4t ¡=i{Òzýi{Ð1Aæ—9š)}hþ3Mnƒë@<Э%¥g$õ¨b¤.2i’H~déô5jßLi€o1vŸîÕUaŠžÚñì¤Ü¿2ž¢“¿AŤõ5“L‚ÑÈ2}Mhé©’.Ð+/QÔã›LÚÜySUô=LG2¬‡“À¬lÞçJ’MXô»kh„ íÅs¾&X#·,è¤v©«Rë)klYœ5ÊêÓjQ™Ü¸ì}½k ;´áÏ¢2žIãõéV`Œ Rg!Ûè:ÖÝžä°èeΛÑÙ/+²_Öÿät6RˆÒ7r°_\p+Ñ´¥k[U¹¸#ÌnëÐWš<¶ÄlÍ|î'§¥^Õõj€i\\ÇÐ*}­N§^¿ƒF³.ÄGÊ=N+€¶fžé¦”îšC–>•¥ãÛÖ›_·´#÷qBRýUŸ§…Xç˜õP@úâ¶›²<|I¶Í´‚\&wÄ„îØx;Qsqn¾aÖÛ_nô?–+ÏôÝßcº™Ï/À®»Â$:ݱ”â8íË9öÅf´•Žú°R£)[£=!Äíl˜ïÎ7¤zÕ½6É2HäÕ-6áµó˜aXåG í] Q„·Î;WLUõ>q½O/øÁj’x;q½½Ê:àƒý+çöûÍ^çñR  EhÍq8ü—Ÿð¯ 'æ5½-ŽJöæÓOAJzRÕ©‰wLÔ­‡ý5Oæ+ìŒWÇ_ü„íë²1_dbšãûÕAO~´ÃÒ 'š\ð)=h(¥)¢œ)ëWß›Xó×U …³…8ö«[ Y«ž â2‰ûôÑÒ¥lmQžNsíQ@ÄëšPHlúU·´Š4ÜÌØëÅW‘Pclƒ×=E4hõ¤¾´gšiéøÓˆïM=(:ž)ÅMSÈ B¤Ì«·9†¬­ÆÈ0§ªžET#4ªqÁ¤ÐÍý#Y—LìÎJ×¥éž!¶ºHžGÜ;{WŽFFF·´©ä†HÙO ¬åšBm3®ø¡ê:õü®Ÿjf·ŽØ$›XIéס¯>Žym)Æ8*½I×£X"WùdëUvù˜ã©5…87«:±ø˜Ó³†ìí´ª+€V–¥r¶Öls€Ib8…qõ¦øJþ@Ä;Gå&vãük¯ecçºÜðÏø¡¼I¬–L‹h H†~÷?{ñ®LžM8žiÍtE$¬ŽIÉÝŠzo¥-!íT"ö—ÿ!K_úìŸÌWÙ5ñ¶—ÿ![_úìŸÌWÙT >-~µðÔÖ£ê)ÚP`óK»L V¬á:‚3ìj &·¼%¥K«ø†ÖÖ$Þ7op[hÚ¼œžÃÞšÕƒ=_Føy¥Ãà‰u r³#:FìW˧OZòSOK'hámаFsž=?:ôøŽéãyÄp·5´³L€ÁÍysÞ»H¬î̬1ÉÎ*9¹¤ÚØÒQäŠMjRlïæ™ü5,£ j xª3,Êå­SæÏ"«w¡NÒisóP£MíŠtÑl\‘Ži±6Ùæ¬0qx  éj^ôqZv)ÆšOoJ  C¨Èîi›½)(‡š|[°x¤d9ìj*A÷h§´ñ]Ó†l`šè,.ã×íç[¹HUl",»B€3¸ú÷¯8íSÁrðÈ®9#Ö¡Án‹çv³=ÇÂ7ëi§%°`Ñ`s‘šÕ¾ðg†õÅfk4†VçÌ€ì9þUã:w‰f…†Xñ]Æ‘ãA½œÖ2‹NæÑšµŠzç­FÍ‹éR}²?ø× ©izŽ˜ån¬®-ŸÕЀúKñ 1ƒ»5¾‘Ú_ŲXÒEaÑ— ЪIyÙEê´>gðžŸ&§âhÈgT;›¾+éÍØAmãJhö·fêÒÆ$?xÄ6çðVäQˆPJNM½!U¹4òl“^ ñ—[3^ÚéHàª4˜=ÏÃ?zŒ¼Umáí=®n ª«Õ›Ò¾gÖ59õ}RæþàæIœ±ö…8.i_±5¥ËueNæGs]'R‚—Ö“Ò€/i_ò´ÿ®ÉüÅ}•_é_ò´ÿ®ÉüÅ}—@Hy¨ûT²u5û´Ây4½…´vª2k¼ø|Ëhšµóµ-Ä~ÿ1íùW•èß-"¹²¾ûGú€êÏž€xþUøYÕƒŠ•hÜçõ‚fgxíÕôz}+pLeHÃ)ïé]ïˆîaºº+k)ùœp£é\å¶PÈ£çž:ŠÆ”í£= vÊò‹ÔÉ.NíL)Ünâ+¤ñDõ£½(š\ Jr9MØ=F rÃJ½Ôä1Ú@Òç SFÃŒ\¢®Ê]éÊ»³‚={×T|s {纈6>êóŠÆºÓͼ›wAê+?i¢:þ¥V*óFiV<â‚×qcÁ‡5)„Ôs„p·FnÃAR*ñ‹úSZ,Óæ%áÚ)H:U–Ú¡ÛÅUÌ\z¥”¤phô¦@ •9šµóÄÀƒƒU1F)4˜Ž•â™-ˆÌ„+Ó´E2§ï×>™¯PÕÍ_µ½–ÕÃ*k)S] #6ª´ýj)ËøÔš†¯´,û†É$ðxo…¼_L"¹˜¨=2x¨¼qãµÔ!}/Msäô–e<7¨›Œž‡DjE+³+ÇÞ-jÛ"cö8 ïí\yn´1擹®ˆÅEYr›“»R÷4 \rj‰ô¤ô§cŠOJc/i_ò´ÿ®ÉüÅ}•_i?ò´ÿ®ÉüÅ}“H‹\sQÿ Jýi©€Ê1À¥#­'a@ µéš;OêÓ\г(TþóW›­vVZÓìm-¬íüû¥]ì\|¡¹9Ç·©¬ê|6;p:Tæ} [Á-ä„ýž8`_™sȰ7g“ššãY¿”Hn®<É$qü*3ØtÍTŠvtù¸ ×/+G±í#&bßÀ!¸t|š¦:Vî¡ln”8uì{ÖÒ¤ƒÁÕNWG‡‹¤éÔzhÄõ¥&¯iz=î¯r!´„±ÏÌç…_rk¹°ðŽ•¤ª\jr}¢t*§äéÞœ¦£¸PÂT­¬VÌ? øTjVï¨^‡‘œ=p}+¶»žÓJÒÔYƉŽ}?Ʊ¯<\ѧÙí#U òƒí\íÅåÍÜŒòÈ~nH 攥?CØ£xxÚ¾å›ÝjiË"·¥e2–;›$Óöò=©Ûxh¶ÜÞ¤F1Š6ã­LE5‡¦•ÊåH‰ÐãóªçÿýUcxÎV¢‘Iù”çý¥­#æsÔ³Õ²öªì0=ê}Äc>ÕËÅhŽ)ÚKB¼¥4ŽEM·å4›Gw9ÜHÂÓ‚É¥%UOsLÉ4ÈvCÕoº0;R1ÜÌOzm8÷¢Ä97¸© /jJbõ¥õ¤¥îhw4 QÔÐ0íIéN= 7Òô¡ÿkOúìŸÌWÙ5ñ¾“ÿ!kOúìŸÌWÙ øºNµðÔÔÔyùh(ì)3Fxª2@®™î>ɱÆó~øë´~5Ì«`ƒé]v˜–·šeËì”Cý֚΢½ŽÌ5E'ègÇi<°ý¢E(Â1œzS£@¨ ½óO¸Õ`ÔØ EÌs  Ž¹ÛŒÕmRX|æKi[ ùê+'ÝŽØU‚2w$’â1üYõÇ5”Ѭ—›;IÅMÊF¡ ‘ÈÆhMŒ~PÇè1UòìaZ¬jÛ™£­²ñU¶Ÿ§‹kKM€uìOãÍc_ê“êãÐUâbß1Ú=Z²°( íÏbI¥ìõ¸åŽºåèB­YHÙ—!ýJŒ#`1ÛÒ§…ž´8‘õ·Ñ<™ ÿTÿ÷É¥1J:Dÿ÷ÍY7 wãÖ –ùPrí.AýrK±^Fÿ¬;>£4n~YWóª—·¯påª Éã­R¤/¯Éô6JËèTE ÊÓ"³*NÖ#õ –oùèß>F†ñQ{¢iFæÉëê*0 ç‚}E.é›ïHOÖÎM=ˆo™Ý!¤’?/Z‚Q‡ã#о³OëW®t‰¡Ñ%¾1¤ªäõ=hçIŽXyJ ®š˜Š;ÑZžx´¾´”¾´v¤Í.x¤ =hîhïKë@¥M ¥îh}i=){RzP†“ÿ!kOúìŸÌWØõñÆ“ÿ!k?úìŸÌWÙ hø²Nµûµ$j?á Òö”v¢º ¶è53óßZÏ3õæ˜n ~´Ïá©$AZ‹øhž´vQØP@éE¥´ŸãKH(GZAÒœ:ŠJ4´ìs@ïõ¥ï@(ìiE/­3½!§ƒM=()M%)4'›íHX3GZ`¥Á N©"ùzŸSPh @4š.2±vâ}ˆP}í¢–ÝÜž¦« ÈNÞ¸êjЕPa’k6¬¬vBjSæoA.ØÈª+Ö¦žS&:àÔKÒ®*Èæ¯>ih-/94”½ÍQ€v¤Å/j1Þ€ÞŽæŠ_Z­/sH){šJOJu7Ò€5ü63âm,ÓÔ_ú¯³ñ_ø`ÅQ¥×Ü_ú¯³¨ðÔ„’ri‡îÓß­Gü4 LÑØRRöRŽ”‚”t @hqH(è¤(E¥½éz^ôQKëH.:Ó#Љº~55Dý!´¦ƒA¤0ïOVâ™J´ãMŠSH:Pz›€öïQö4zP5&¶+~N~”€ñB®Oµ;$)JìJ_Z6žÔ»O4Ä'j)p@¢ =i}h4ž´¢—¹¤½ÍƓҜzo¥mx_ŸéCþžâÿÐ…}_ø`ãÅQÿ§¸¿ô!_fæÏ†Ÿ­3øiïÖ™ü4 m( (ì(P:Q@é@%-%(ë@éJ:ҔĴ¸=}h­/zQA=héM'­¹¦·OÆ—½!é@Æž )4CH¢’”q¦Ž”¹¦Ž”§§áNUÉ ƒRŒSBaŠZ^(4Ĥõ¦æ—Öx¤Å¨¤1 ´´¾´”¦”RÉ = 7°§ž†˜GJlxlãÄšaÿ§¨¿ô!_fæ¾0ð÷"ÓOý=Eÿ¡ û34¿ZgðÔŽ9¦ GaE`sLÒÆŽÔ€zAÓñ¥õ¤ ¢ÒœŠNqLBަži˜ë@Ðç4ž´¸¤ÇZC½#tüiؤaÀúÐM”Ðh(¥£R”¸¡G€ž? ]Ý);QéLC·QºšEíÜRîäÓ)Þ´¹£4¨ Bçš;šNô½Í(¥îi¢ÎM˜{SÏCMô  =ã_ÓÏý<Çÿ¡ û35ñž…ÿ!Ý?þ¾#ÿÐ…}•Hh­ÿ_†üÀ4ßü_ð¤ÿ„+Âÿô/é¿ø ¿áE ?á ð·ý Úoþ/øRÂáSÿ2ö™ÿ€ËþQ@ ÿ7…?è]Ó?ð?ÂøA¼)ÿBî™ÿ€ËþQ@ü Þÿ¡wLÿÀeÿ OøA|)ÿBî™ÿ€ËþQ@ƒþ_ л¦à2ÿ…ð‚øSþ…Ý3ÿ—ü(¢‡ü ¾ÿ¡wLÿÀeÿ ?áð§ý ºgþ/øQE4ø‡þeÝ7ÿ×ü*3à? ÿл§ß…¢Š¤!§À^ÿ¡{Nÿ¿øÂGþeí?þüŠ(¤mðÿÂ?ô/Xß¡QŸ‡¾ÿ¡zÇþýÑE4Ä!øyáúìïÝ4ü<ð‡ý ö_÷ÅS¸ ?¼!ÿBý—ýðÆ›ÿ ëÁÿô/Ùÿß'üh¢‹ŒOøW>ÿ¡~Ïþù?ãM?<ùYþGüh¢¤Ÿ†þÿ §äƘ~x;?òµÿǿƊ)€‡á¯ƒ¿èkÿ4ü4ðoý-¿6ÿ( ? <ÿ@ oÍ¿Æü4ðoým¿ï¦ÿ( COÃ?Ÿù€ÛÿßOþ4ÓðËÁ¿ôƒþûþ*Š( >x7?òƒþþ?ÿGü+?ÿÐ ûøÿüUS¸XCðËÁ¿ô‡þþ?ÿMÿ…càßúCÿ$ÿ⨢•ÇbÖðçÂVº¼ðè°¬‘¸e%ÜàŽœŠô?-?¸?*(¤ÁÿÙ endstream endobj 1830 0 obj << /D [1826 0 R /XYZ 89 721 null] >> endobj 1831 0 obj << /D [1826 0 R /XYZ 90 690.045 null] >> endobj 1828 0 obj << /Font << /F52 1832 0 R /F53 1833 0 R >> /XObject << /Im1 1827 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 1877 0 obj << /Length 1233 /Filter /FlateDecode >> stream xÚí[Ën£HÝç+X‚zÌÔ»ŠU+I÷D¦[iK½hÍ‚àŠ„Á8£üýæa(ðÜQÇ1›¤Ì9÷VsoswW ø¼™^ýþ"6Ó'ÃÀÆBÍŒæm¦2LëŸéŸWP=ŒxnäwùãŽí0IJ§1aÐæLäCkæ}˜Æf4[{©…›?V~ ƒ@lÌÕIþÚ9Eµ±&Ø6p°1Ðv(-ž¶7ƒÒ|ÐjÀ RWÒ(ÿœI QóÙ÷d~žÈøÙ‚Ô”qó‹ý˜puÕ¶&T½ÃÙ~Ç9p‹öÒAP²P^n³‘q½ž•À£øO»áÝœ/ü$â}X&øÙc=€}<àäí‡ùÁÔr°yý÷Ý—üÔ |5Çèï}ŸqZb’c“–, & øÇφ8cNfÐC ¤’´xØäRwº(Àö¢åÒ gI~¦ŽŠƒ4ýG sʤ¼U1¥§çð0H1´…è@tƒ)¦5L‹õ盿\M˜õ¡ bg¦¸±þ³/Õ]˜]DZû²2çÍFÜ+C†w…™ÊÔrIÝ™xë*ò0f¼§Ì1#»1;iÂ÷W#Äèn¸”Ùbž{ˆ‰A˜1³tKÙ¹Šê9äÜ…K'ŽNOÃÀ›cQ†Â¸ãÂ0T¨*ÍššjšÑRc?g?J›·Tz%п"¢iñK/S§aðo¿<ÜX˜*Á«ë%(F/±„z殼D4cç}[·Ÿb-öƒ{ƒubj¾®•`dçUÙiø?VQ´ÇÿéÅ0ˆÆ*Øiù°™ª¶ˆÕ ûå=Ëräi(“(ã(¯üU\ÆÅ…ô¨Iõm>iü¶»VÅuð7‡[N^Ñt®wBJ@JõèÝJÇ£æ|q’qÊLG9–K׫º‰z´’±›©ú¤­\È¥kM=pÆd%=ß )á&Ååè©´ÂrG‰?uS©•œ³këv„ô–Í.b¢Qè0ê𬢠ÈbSosvá‹ÖA´']|ájx“Ý=&ÂøèMÀkrÔʪ³3µD61Ì‹jÊ_Ñ|¾í+æ:,%hÌž¸³–cwS÷1›Åu¥Fј ýØà½Ùà:^”Õƒ@–=YÏ“I{Älܤpþ•¼:þ׫Uà{û5Žæ±»\ʸ°4÷a*㧬æìzmqŽé;ó7|È®lUuzX•AÔ%âõ×ûöv6N&Ã&QŸ2¯¾qü(Óÿ¤ [Ÿ4-®í˜['Õú»0†œ_ ÁÅtª¢QSiä:|óæå–Óºþf£àëÀ¿o¿s[P­ßGŠ~ß÷Øßnt;[õ€­Å¥v—ŠÎ0›ïý‘îÞ_˳²Q. %Ü·ÊNªvàá¥j=¹(kwÒ’3€‰²ÿwã&¾W¦…DI´ZXÔlm·æ4ü4XICYêø¤¼\±b¿t4@…[æøE R–9ä¿k™¤{v/8\Œ<ÉC³Uý:ÄŒ*µíò¿`ãÖÏÓ«ÿÒ™iK endstream endobj 1876 0 obj << /Type /Page /Contents 1877 0 R /Resources 1875 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R /Annots [ 1835 0 R 1836 0 R 1837 0 R 1838 0 R 1839 0 R 1840 0 R 1841 0 R 1842 0 R 1843 0 R 1844 0 R 1845 0 R 1846 0 R 1847 0 R 1848 0 R 1849 0 R 1850 0 R 1851 0 R 1852 0 R 1853 0 R 1854 0 R 1855 0 R 1856 0 R 1857 0 R 1858 0 R 1859 0 R 1860 0 R 1861 0 R 1862 0 R 1863 0 R 1864 0 R 1865 0 R 1866 0 R 1867 0 R 1868 0 R 1869 0 R 1870 0 R 1871 0 R 1872 0 R 1873 0 R ] >> endobj 1835 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 537.497 160.007 546.473] /A << /S /GoTo /D (chapter.1) >> >> endobj 1836 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 525.562 243.274 534.408] /A << /S /GoTo /D (section.1.1) >> >> endobj 1837 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 511.549 213.665 522.453] /A << /S /GoTo /D (section.1.2) >> >> endobj 1838 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 489.766 172.071 500.645] /A << /S /GoTo /D (chapter.2) >> >> endobj 1839 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 479.734 217.471 488.58] /A << /S /GoTo /D (section.2.1) >> >> endobj 1840 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 467.778 227.394 476.625] /A << /S /GoTo /D (section.2.2) >> >> endobj 1841 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 455.823 299.433 464.67] /A << /S /GoTo /D (subsection.2.2.1) >> >> endobj 1842 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 441.811 305.929 452.715] /A << /S /GoTo /D (subsubsection.2.2.1.1) >> >> endobj 1843 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 429.856 300.928 440.76] /A << /S /GoTo /D (subsubsection.2.2.1.2) >> >> endobj 1844 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 417.9 302.054 428.804] /A << /S /GoTo /D (subsubsection.2.2.1.3) >> >> endobj 1845 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 405.945 312.555 416.849] /A << /S /GoTo /D (subsubsection.2.2.1.4) >> >> endobj 1846 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 396.047 301.496 404.894] /A << /S /GoTo /D (subsubsection.2.2.1.5) >> >> endobj 1847 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 383.973 278.851 392.939] /A << /S /GoTo /D (subsubsection.2.2.1.6) >> >> endobj 1848 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 362.154 246.92 371.131] /A << /S /GoTo /D (chapter.3) >> >> endobj 1849 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 350.219 224.814 359.066] /A << /S /GoTo /D (section.3.1) >> >> endobj 1850 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 338.264 171.743 347.111] /A << /S /GoTo /D (section.3.2) >> >> endobj 1851 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 326.309 172.59 335.156] /A << /S /GoTo /D (section.3.3) >> >> endobj 1852 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 314.354 221.885 323.2] /A << /S /GoTo /D (subsection.3.3.1) >> >> endobj 1853 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 302.399 252.022 311.245] /A << /S /GoTo /D (subsection.3.3.2) >> >> endobj 1854 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 288.386 236.171 299.29] /A << /S /GoTo /D (subsection.3.3.3) >> >> endobj 1855 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 276.431 285.336 287.335] /A << /S /GoTo /D (subsection.3.3.4) >> >> endobj 1856 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 266.533 252.061 275.38] /A << /S /GoTo /D (subsection.3.3.5) >> >> endobj 1857 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 252.521 299.573 263.425] /A << /S /GoTo /D (subsection.3.3.6) >> >> endobj 1858 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 240.565 342.531 251.469] /A << /S /GoTo /D (subsection.3.3.7) >> >> endobj 1859 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 228.61 235.195 239.514] /A << /S /GoTo /D (subsection.3.3.8) >> >> endobj 1860 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 218.712 171.026 227.559] /A << /S /GoTo /D (section.3.4) >> >> endobj 1861 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 204.7 240.116 215.604] /A << /S /GoTo /D (section.3.5) >> >> endobj 1862 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 194.802 181.138 203.649] /A << /S /GoTo /D (section.3.6) >> >> endobj 1863 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 182.847 215.17 191.694] /A << /S /GoTo /D (section.3.7) >> >> endobj 1864 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 168.834 291.712 179.738] /A << /S /GoTo /D (section.3.8) >> >> endobj 1865 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 158.937 227.424 167.783] /A << /S /GoTo /D (subsection.3.8.1) >> >> endobj 1866 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 144.924 386.097 155.828] /A << /S /GoTo /D (subsection.3.8.2) >> >> endobj 1867 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 132.969 212.939 143.873] /A << /S /GoTo /D (subsection.3.8.3) >> >> endobj 1868 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 111.186 297.879 122.065] /A << /S /GoTo /D (chapter.4) >> >> endobj 1869 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 101.153 178.109 110] /A << /S /GoTo /D (section.4.1) >> >> endobj 1870 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 87.141 189.456 98.045] /A << /S /GoTo /D (section.4.2) >> >> endobj 1871 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 75.186 198.273 86.09] /A << /S /GoTo /D (section.4.3) >> >> endobj 1872 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 63.23 171.185 74.134] /A << /S /GoTo /D (section.4.4) >> >> endobj 1873 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 51.275 188.351 62.179] /A << /S /GoTo /D (section.4.5) >> >> endobj 1878 0 obj << /D [1876 0 R /XYZ 90 690.045 null] >> endobj 1875 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1935 0 obj << /Length 1756 /Filter /FlateDecode >> stream xÚí›[s£6Çßó)x«™­I @}éxÓ$ÓvºÛÙu§Û>,;L¸xl6ýô .F²±™ì®o/qì`ÿttÎÿ\´¥´û«·³«ë;ÛÔÈ„XÈÒf ÍΘX›ÍµO£›÷ïf·ïfõg¿]ßaÔºÔ„ü:HøŠ+Q~Éw†ü'ÐØR+ùp¥ L µ1²ùMŒòmæO >†€ÑÇ—È{dqg‰>FŒÂxNƒµûjŸø»ÑDcþ†£}0 ÙíÊÎw‡‚‘ûPm á„`Ü0F‚ñ4Ù ²iº› ¡ f—±Å Îóö³ñˆFi"A%ÆÑ[î7^¡m eõ-Ô†uªýͯQÊâyæ¥~u?ÂÖýpô@¦^y z”îgNÿE¾rLç‚}v«Án¨±§/+*9(lËѿªÑ›jú¹É)e~´¬^Àà ãüªòÒyù?*gºFn´ŒË§ŒÔMhùÄ)ÜH¼Ç}h݇ßv¿±ð×E¬äç à‡+Ù²Z¾çN¢øŽ²xÉÜ0¤ìã‘Ð2Ü£S¶Ðù§¹•¬Û"Gd—J„¤¡'Ž£ÀXÄ<ƒº‰£Üø–Yc{TG•±(D‹à‰løaDáDÕH ¨ù½½G¾3%{ã ÒiùÈa1)g‡»÷‚ñÜ÷ºw·‘qÂØL0Ärl†Àæ2ïÑo6®¬œìÓ·½~ˆãÍ»UñÍ›Ò Þ¾ÊÿÙ§£‰vuŠý\·`­âÇì!ñ˜ÿPÇ™4Þ%ÞX69ž€"¸Ã*v¶Y‡ÓSýh6í媉ù7ó[Ò7RX÷ƒ¡Îu+Ûƒzv«×ÙÝÊÞ×q¹at¾¤ª¸ër|[vˆÆ[p­PjGW'ÁdT³;E„ö=Ù:‡0ëöŠì¬6;£Oò%+êùyŸÝS’\QÖ(ñ³¬Cá§×›Fp16±‰TÇrD©Qèšë5ŸØÂQròWT.·À3¨'ª˜[`XéЩK‡ëbr3cÃs­à*ÁÃA¡È"¹§-›ÆÒkmÓm‹•yP”Ö}›ó+Ç»¿äñ¦WŸ @v€T P/ˆjÒM<]Òˆ2ßkiH÷¥™•Ë©ÅY!Urdï9”£D€!¨¢Æm£|y¶ëª•ˆiœò„e쥥­#RjéÍ®ŒØÆeˆuð\j\ÙÅ|-D}$†½á~ÃBŠòxQ¯.®KeáÁ£+UÝÁqÌsU¢ûÂCXž=2.BE–ä.hú"Ehã2Zðõ—•Ëq‡+_Q{ã/=uÃkg¨À+æ%¥Ó™³á_ßÙ uFv ¹Ï7y@œ>tJúy9ä³:AÏ©Nðhö{u°!op4‡ »:ÜpŸùs*ó&ÈYe:®úÖÎìVÿNÛÊzÀÛÏÃáS=÷Õ7§³WÖnÕ‹RgíÓ$ÉÂ"%‡Õ'<^äÊ#¼eMàÖTîSžw"à¥ÎÌs5Põ2Ï8Õ!„ùV–²|>ÕgH™ªšÏ þ?òCÿ?ºV,ÚÀA¼ ›#Œ~(W®€}Êágß …jÔ\¦Zvœ–I§öÒ³“ó xa*˜V#mÓvó.éh(1Ít§Öç~=­Ý‚ÞØH!ßÊ¢wN~‡«Æ¦ºmæÝî;ýÓ¼ÚéYsȳ[OÀÖÙU×9wogWÿ«Lý endstream endobj 1934 0 obj << /Type /Page /Contents 1935 0 R /Resources 1933 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R /Annots [ 1874 0 R 1880 0 R 1881 0 R 1882 0 R 1883 0 R 1884 0 R 1885 0 R 1886 0 R 1887 0 R 1888 0 R 1889 0 R 1890 0 R 1891 0 R 1892 0 R 1893 0 R 1894 0 R 1895 0 R 1896 0 R 1897 0 R 1898 0 R 1899 0 R 1900 0 R 1901 0 R 1902 0 R 1903 0 R 1904 0 R 1905 0 R 1906 0 R 1907 0 R 1908 0 R 1909 0 R 1910 0 R 1911 0 R 1912 0 R 1913 0 R 1914 0 R 1915 0 R 1916 0 R 1917 0 R 1918 0 R 1919 0 R 1920 0 R 1921 0 R 1922 0 R 1923 0 R 1924 0 R 1925 0 R 1926 0 R 1927 0 R 1928 0 R 1929 0 R 1930 0 R 1931 0 R ] >> endobj 1874 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 676.929 240.156 687.833] /A << /S /GoTo /D (subsection.4.5.1) >> >> endobj 1880 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 664.974 245.686 675.878] /A << /S /GoTo /D (subsection.4.5.2) >> >> endobj 1881 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 655.076 155.823 663.923] /A << /S /GoTo /D (section.4.6) >> >> endobj 1882 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 643.121 209.99 651.968] /A << /S /GoTo /D (subsection.4.6.1) >> >> endobj 1883 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 631.166 224.515 640.012] /A << /S /GoTo /D (subsection.4.6.2) >> >> endobj 1884 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 617.153 207.35 628.057] /A << /S /GoTo /D (subsection.4.6.3) >> >> endobj 1885 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 605.198 382.751 616.102] /A << /S /GoTo /D (subsection.4.6.4) >> >> endobj 1886 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 593.243 304.504 604.147] /A << /S /GoTo /D (subsection.4.6.5) >> >> endobj 1887 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 581.288 277.287 592.192] /A << /S /GoTo /D (subsubsection.4.6.5.1) >> >> endobj 1888 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 569.333 268.65 580.237] /A << /S /GoTo /D (paragraph.4.6.5.1.1) >> >> endobj 1889 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 557.377 273.083 568.281] /A << /S /GoTo /D (paragraph.4.6.5.1.2) >> >> endobj 1890 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 547.48 269.357 556.326] /A << /S /GoTo /D (paragraph.4.6.5.1.3) >> >> endobj 1891 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 535.524 250.188 544.371] /A << /S /GoTo /D (subsubsection.4.6.5.2) >> >> endobj 1892 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 521.512 325.825 532.416] /A << /S /GoTo /D (paragraph.4.6.5.2.1) >> >> endobj 1893 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 511.614 317.356 520.461] /A << /S /GoTo /D (paragraph.4.6.5.2.2) >> >> endobj 1894 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 497.602 358.462 508.506] /A << /S /GoTo /D (paragraph.4.6.5.2.3) >> >> endobj 1895 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 487.704 347.752 496.55] /A << /S /GoTo /D (paragraph.4.6.5.2.4) >> >> endobj 1896 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 473.691 275.853 484.595] /A << /S /GoTo /D (paragraph.4.6.5.2.5) >> >> endobj 1897 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 461.736 154.309 472.64] /A << /S /GoTo /D (section.4.7) >> >> endobj 1898 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 449.781 292.758 460.685] /A << /S /GoTo /D (subsection.4.7.1) >> >> endobj 1899 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 439.883 258.597 448.73] /A << /S /GoTo /D (subsection.4.7.2) >> >> endobj 1900 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 425.871 249.681 436.775] /A << /S /GoTo /D (subsection.4.7.3) >> >> endobj 1901 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 413.915 311.717 424.819] /A << /S /GoTo /D (subsubsection.4.7.3.1) >> >> endobj 1902 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 401.96 335.369 412.864] /A << /S /GoTo /D (subsubsection.4.7.3.2) >> >> endobj 1903 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 390.005 402.497 400.909] /A << /S /GoTo /D (subsubsection.4.7.3.3) >> >> endobj 1904 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 378.05 342.283 388.954] /A << /S /GoTo /D (subsubsection.4.7.3.4) >> >> endobj 1905 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 366.095 357.097 376.999] /A << /S /GoTo /D (subsubsection.4.7.3.5) >> >> endobj 1906 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 354.14 242.437 365.044] /A << /S /GoTo /D (subsection.4.7.4) >> >> endobj 1907 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 342.184 304.624 353.088] /A << /S /GoTo /D (subsubsection.4.7.4.1) >> >> endobj 1908 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 330.229 402.497 341.133] /A << /S /GoTo /D (subsubsection.4.7.4.2) >> >> endobj 1909 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 318.274 241.61 329.178] /A << /S /GoTo /D (subsection.4.7.5) >> >> endobj 1910 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 306.319 316.161 317.223] /A << /S /GoTo /D (subsubsection.4.7.5.1) >> >> endobj 1911 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 296.421 333.655 305.268] /A << /S /GoTo /D (subsubsection.4.7.5.2) >> >> endobj 1912 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 282.409 338.905 293.312] /A << /S /GoTo /D (subsubsection.4.7.5.3) >> >> endobj 1913 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 270.453 243.712 281.357] /A << /S /GoTo /D (section.4.8) >> >> endobj 1914 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 258.498 220.5 269.402] /A << /S /GoTo /D (subsection.4.8.1) >> >> endobj 1915 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 246.543 401.659 257.447] /A << /S /GoTo /D (subsubsection.4.8.1.1) >> >> endobj 1916 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 234.588 437.515 245.492] /A << /S /GoTo /D (subsubsection.4.8.1.2) >> >> endobj 1917 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 222.633 276.002 233.537] /A << /S /GoTo /D (subsubsection.4.8.1.3) >> >> endobj 1918 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 210.678 218.288 221.581] /A << /S /GoTo /D (subsection.4.8.2) >> >> endobj 1919 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 198.722 276.002 209.626] /A << /S /GoTo /D (subsubsection.4.8.2.1) >> >> endobj 1920 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 186.767 189.197 197.671] /A << /S /GoTo /D (section.4.9) >> >> endobj 1921 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 174.812 241.591 185.716] /A << /S /GoTo /D (section.4.10) >> >> endobj 1922 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 162.857 183.349 173.761] /A << /S /GoTo /D (section.4.11) >> >> endobj 1923 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 150.902 277.774 161.806] /A << /S /GoTo /D (section.4.12) >> >> endobj 1924 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 129.118 245.765 139.997] /A << /S /GoTo /D (chapter.5) >> >> endobj 1925 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 119.086 178.109 127.933] /A << /S /GoTo /D (section.5.1) >> >> endobj 1926 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 105.074 212.769 115.977] /A << /S /GoTo /D (subsection.5.1.1) >> >> endobj 1927 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 93.118 255.628 104.022] /A << /S /GoTo /D (section.5.2) >> >> endobj 1928 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 81.163 273.241 92.067] /A << /S /GoTo /D (subsection.5.2.1) >> >> endobj 1929 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 69.208 281.47 80.112] /A << /S /GoTo /D (subsection.5.2.2) >> >> endobj 1930 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 59.191 353.44 68.157] /A << /S /GoTo /D (subsection.5.2.3) >> >> endobj 1931 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 45.298 253.327 56.202] /A << /S /GoTo /D (subsection.5.2.4) >> >> endobj 1936 0 obj << /D [1934 0 R /XYZ 89 721 null] >> endobj 1933 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 1993 0 obj << /Length 1397 /Filter /FlateDecode >> stream xÚíš]s¢H†ïó+¸” IÓ}™ÍWÍîNf+±*3{A´£ì(PØÉTþý6"6(S»¼T|ú¼ç¼§`M-`Ýžý6:;¿q‰%Á³FÏ–– ¸µFëûàòÛÝèúnô`ÿ=úýü†¢Ò¡êã Ð'JÄÉ!g ?3Ô¯ÀЧV¶s{f Àp©5D®> Î~Fl! `0šI{ˆôN,½y¶7•JùÁ4{³T^¬ädã2Ö÷¡ ÐÀ±‡€Žmˆ ‡$ ‚`à‚¦q@ÈXCAi1 Ôã€ôy4ñy>i#:xõÇù{/ŠæþØS~,+á²Þ3ýZ!‹r²__æÊß,¦¢?áKZðÅ+¾aœã ƒ³¿ŒæÞ[‘C<¥bÿÉF`ð¢d´`´“LiS Îk¸¦9kn—aÈñ:{A Ïì#æ_e›W?ô_26ïAòYˆ¶£¶ŠDV&†rboA)ÜHðn•¨Z–¼Ñl A’Kû"÷³0VÙn*Cìjm æY&ùQöÉ“T¿¤Ì[„9_®ybŽP5ÿ2ôѬê qÔR¦¤éŸþRÉ æ/Núc’ÚÁR⸢⋈éNÚútÒ†tð–‡ßÓ?:5æñ>gÛ‘Í“àš†6„p0úü+.`'‹ú®1Àí¬))¬i1÷ò9–ËYM¤3&úÓ|órRa%äERyœyyÊi—*ƒåfÖõV97‘Š¥âî1ЭEGÚ-Røý"\¯ ·“$o¬ÂøÍ¼(¼?!Û8¨²Æ&닲%-ãÞ¬÷…Y¸  ýéŽ!þïô>ŒÙÉ+1  ÒCLB@]WÔŠÝIïøÊÿ¸‘VWc/ŠQ~æËØ‹Ç3;ña¦·B¤?Æ–îU¥Jž™±œ ¼Úÿð“¥Ú‹ø–(fE_¿&ÕFÊìBçÛ8ÆX'£—5°<¿qAiÍaÈ„ãbÍi¶gl“@ú±_š¡ZõaB'é»ÛoÅ´+,O».eœ´s¯iOW™›A wÀ³É‹º{ÛXÄÄh^²!ßèÍ™_} Y4ÄÙûçØ[dSÉM…ñÏŠOÄ}]Ûà¼MÉò^&ÉuwÞ¢ˆ±î`H:ö©ý¢¡Y‰1ŠÃ©Œõ/溡ñ¦²’ Å'5ˆ|O‹“ ª4/fÀFžR2*Eãž·/¼E]H‰WÝM1}”O_zËü‹ñÜ[æEã‡N+ëÆòË"š—Ñ_Âjƒ‰?Éܺh^¤U=«”Vr‰+¹Ç~”*·Œ¤S™O€=#V¬PÎê2 Tê7*½-épÁhÆ6ÜhÈåÕÓ•‘ 35šV ¡.Z5Û“t~fƒbÞeìxd‹p{,âÚ¤·±âPÌÓøÁLj'ì«(M×»*Å€³ã‰¡"5ÿ{%u!ôÔ®¿Î1=:¥:êq"Gû%ò*H*‰¼Hã—k;UŸŠÛ­„Úç ÒKã…Zé•ôÝx¡Œ­¯&Rˆ:<Ç+p« d&ÇôùËê#[µH1vûBo{é`½Ìy-íï9ó\S«ï–)½Î|;ž´ûníºÇ¯ÝƒænÒ.7µûhCô~ Îú¬ÙzËOš}·fùI³í5+êê푺¢›ËZµ`I«x„Àò2Ò‡HŽUü²hB ºÒh´ä n_ÞT6@£žBo™¡§dÉøk¨Âë ·í5fëÏàèŠîaÕ£m¤¥U7ƒõøu´˜ ,¹ä€’ ñ‘6Mð1W_= <å€{)JÚN”¸×¢¤‡ˆ’¢Ìׯî¥7ù+\úë•Ö-²dGëÖ6=5·×£³¯e endstream endobj 1992 0 obj << /Type /Page /Contents 1993 0 R /Resources 1991 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R /Annots [ 1932 0 R 1938 0 R 1939 0 R 1940 0 R 1941 0 R 1942 0 R 1943 0 R 1944 0 R 1945 0 R 1946 0 R 1947 0 R 1948 0 R 1949 0 R 1950 0 R 1951 0 R 1952 0 R 1953 0 R 1954 0 R 1955 0 R 1956 0 R 1957 0 R 1958 0 R 1959 0 R 1960 0 R 1961 0 R 1962 0 R 1963 0 R 1964 0 R 1965 0 R 1966 0 R 1967 0 R 1968 0 R 1969 0 R 1970 0 R 1971 0 R 1972 0 R 1973 0 R 1974 0 R 1975 0 R 1976 0 R 1977 0 R 1978 0 R 1979 0 R 1980 0 R 1981 0 R 1982 0 R 1983 0 R 1984 0 R 1985 0 R 1986 0 R 1987 0 R 1988 0 R 1989 0 R ] >> endobj 1932 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 676.929 220.988 687.833] /A << /S /GoTo /D (section.5.3) >> >> endobj 1938 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 664.974 265.082 675.878] /A << /S /GoTo /D (subsection.5.3.1) >> >> endobj 1939 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 653.019 261.764 663.923] /A << /S /GoTo /D (subsection.5.3.2) >> >> endobj 1940 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 641.064 278.143 651.968] /A << /S /GoTo /D (subsection.5.3.3) >> >> endobj 1941 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 629.108 341.416 640.012] /A << /S /GoTo /D (subsubsection.5.3.3.1) >> >> endobj 1942 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 617.153 266.358 628.057] /A << /S /GoTo /D (subsubsection.5.3.3.2) >> >> endobj 1943 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 605.198 403.701 616.102] /A << /S /GoTo /D (subsection.5.3.4) >> >> endobj 1944 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 595.3 238.104 604.147] /A << /S /GoTo /D (subsubsection.5.3.4.1) >> >> endobj 1945 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 581.288 248.993 592.192] /A << /S /GoTo /D (section.5.4) >> >> endobj 1946 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 571.39 221.317 580.237] /A << /S /GoTo /D (subsection.5.4.1) >> >> endobj 1947 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 557.377 307.812 568.281] /A << /S /GoTo /D (subsubsection.5.4.1.1) >> >> endobj 1948 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 545.422 236.968 556.326] /A << /S /GoTo /D (subsection.5.4.2) >> >> endobj 1949 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 533.467 350.611 544.371] /A << /S /GoTo /D (subsection.5.4.3) >> >> endobj 1950 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 523.569 321.042 532.416] /A << /S /GoTo /D (subsection.5.4.4) >> >> endobj 1951 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 511.614 218.368 520.461] /A << /S /GoTo /D (subsection.5.4.5) >> >> endobj 1952 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 497.602 257.133 508.506] /A << /S /GoTo /D (subsubsection.5.4.5.1) >> >> endobj 1953 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 487.704 224.107 496.55] /A << /S /GoTo /D (subsection.5.4.6) >> >> endobj 1954 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 475.749 281.122 484.595] /A << /S /GoTo /D (subsubsection.5.4.6.1) >> >> endobj 1955 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 451.908 243.045 462.787] /A << /S /GoTo /D (chapter.6) >> >> endobj 1956 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 441.876 245.117 450.722] /A << /S /GoTo /D (section.6.1) >> >> endobj 1957 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 427.863 351.11 438.767] /A << /S /GoTo /D (subsection.6.1.1) >> >> endobj 1958 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 415.908 234.627 426.812] /A << /S /GoTo /D (subsection.6.1.2) >> >> endobj 1959 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 403.953 364.041 414.857] /A << /S /GoTo /D (subsubsection.6.1.2.1) >> >> endobj 1960 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 391.998 286.921 402.902] /A << /S /GoTo /D (paragraph.6.1.2.1.1) >> >> endobj 1961 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 381.98 275.863 390.946] /A << /S /GoTo /D (paragraph.6.1.2.1.2) >> >> endobj 1962 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 370.025 281.561 378.991] /A << /S /GoTo /D (subsubsection.6.1.2.2) >> >> endobj 1963 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 358.07 282.936 367.036] /A << /S /GoTo /D (subsubsection.6.1.2.3) >> >> endobj 1964 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 344.177 386.526 355.081] /A << /S /GoTo /D (paragraph.6.1.2.3.1) >> >> endobj 1965 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 332.222 376.574 343.126] /A << /S /GoTo /D (paragraph.6.1.2.3.2) >> >> endobj 1966 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 322.204 275.863 331.171] /A << /S /GoTo /D (paragraph.6.1.2.3.3) >> >> endobj 1967 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 310.249 290.975 319.215] /A << /S /GoTo /D (subsubsection.6.1.2.4) >> >> endobj 1968 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 296.356 286.921 307.26] /A << /S /GoTo /D (paragraph.6.1.2.4.1) >> >> endobj 1969 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 286.339 275.863 295.305] /A << /S /GoTo /D (paragraph.6.1.2.4.2) >> >> endobj 1970 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 274.384 275.185 283.35] /A << /S /GoTo /D (subsubsection.6.1.2.5) >> >> endobj 1971 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 262.428 299.344 271.395] /A << /S /GoTo /D (subsubsection.6.1.2.6) >> >> endobj 1972 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 248.536 286.921 259.44] /A << /S /GoTo /D (paragraph.6.1.2.6.1) >> >> endobj 1973 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 238.518 275.863 247.484] /A << /S /GoTo /D (paragraph.6.1.2.6.2) >> >> endobj 1974 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 226.563 277.197 235.529] /A << /S /GoTo /D (subsubsection.6.1.2.7) >> >> endobj 1975 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 212.67 286.921 223.574] /A << /S /GoTo /D (paragraph.6.1.2.7.1) >> >> endobj 1976 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 202.653 275.863 211.619] /A << /S /GoTo /D (paragraph.6.1.2.7.2) >> >> endobj 1977 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 190.697 285.406 199.664] /A << /S /GoTo /D (subsubsection.6.1.2.8) >> >> endobj 1978 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 176.805 286.921 187.709] /A << /S /GoTo /D (paragraph.6.1.2.8.1) >> >> endobj 1979 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 166.787 275.863 175.753] /A << /S /GoTo /D (paragraph.6.1.2.8.2) >> >> endobj 1980 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 154.832 257.471 163.798] /A << /S /GoTo /D (subsubsection.6.1.2.9) >> >> endobj 1981 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 140.939 295.658 151.843] /A << /S /GoTo /D (subsubsection.6.1.2.10) >> >> endobj 1982 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 128.984 282.368 139.888] /A << /S /GoTo /D (subsubsection.6.1.2.11) >> >> endobj 1983 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 117.029 296.764 127.933] /A << /S /GoTo /D (subsubsection.6.1.2.12) >> >> endobj 1984 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 105.074 286.921 115.977] /A << /S /GoTo /D (paragraph.6.1.2.12.1) >> >> endobj 1985 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 95.056 280.844 104.022] /A << /S /GoTo /D (paragraph.6.1.2.12.2) >> >> endobj 1986 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 81.163 318.352 92.067] /A << /S /GoTo /D (subsubsection.6.1.2.13) >> >> endobj 1987 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 69.208 286.921 80.112] /A << /S /GoTo /D (paragraph.6.1.2.13.1) >> >> endobj 1988 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 59.191 283.334 68.157] /A << /S /GoTo /D (paragraph.6.1.2.13.2) >> >> endobj 1989 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 47.235 310.91 56.202] /A << /S /GoTo /D (subsubsection.6.1.2.14) >> >> endobj 1994 0 obj << /D [1992 0 R /XYZ 89 721 null] >> endobj 1991 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2051 0 obj << /Length 1603 /Filter /FlateDecode >> stream xÚí›Is›H†ïþE¥$Óй9¶“ÊT&IÅÊÌ!3‚Ú25hšVbÿû4[‹UB»J`_Œ¢`,}Ëû-XÆÒ°Œwgoægçolе¡mÌo jŽåÎ,LŒùÂø6¹üôq~ýq~cþ;ÿãü-¥S1ç*/”ž‰“SάüÊ@þ´ ¾4²_ÞS$QdL¡#/‚²_³g`gÏ€9–eM®Xìó`#‚(¬\Ñø6užÌÌ)‘gæSÚõµ[XjbfSf”,¨`ýcY0 ÚhÙôÄi=´)¤3×u[Ñsêk2¿cæÊŸ£8…w!ÏÞñW^×ÿ2`,ÛêAÜÇðÅWûû*‡¯î¡µšsÐWm0sìÂÎì:$©Ayááq±Ýd¾ÝfG/;,˜ ÉäGàçμñ„`¼×p°Îûˆ¨[ìç/£õÚ Ef2¹O~0›kúvÌþß²P¢®‡Fû…gÁ“äHm„tÙß3P»Ìæ0M9ãäèHŒRØô(ûZÒ©ÇÊz6ÿ‘f¡\˜ßrožòÓ”9âÿÕ?B#õþŒ4Ðô~Gyÿ_&€tù^f¬+?4ºx€Öú›¿'_«m”_ÝÔì¶½ $çÞQA%ª³œ›® ¯á2zýú«V{xº‹ Ô-Ð%ÆÔáÉPësÍð5z æ¬.£P°P4, c<欂´»iNZ>&þz¡Ê™ÍЉÃé¼þA0º·"­xGr~W”O\îtÕáŽã¢ÿØ×ìž9×±¥Í4IáúÞ¿“‰Aið…'ò¦Ðw&~2¹">Ëô¢ÁÑm‰‘ˆ™ƒÓg4ñ¦©£Ñ:ÏåB§Î]R âmbB/þFP î3&¨’‘rÞ [sïἫí :âA"@ZÑíÁÔ!`èܰFžDj Sᦆ°»)O+l­ºÖuÉ`ÁÝtƒÕöÚ&â;YÁ8xK›ÒsHì'‰fÂ*]ß{ÉØ±®\x”® í¾‡Tñø¬uN•‰¶ÏÎP>;k®Wdÿü-wµd‹%h†F`!ø\mÕÖ›©!5S«ÎàsSF‚%k®PÛz‰½¨[Mà° ø‡¬ÁšvWÍ^ŒKžV}ìö»zfƒ…‹®ººò•üÉâX–a/ºtè–£•ØP©ÀªZ{>⢢ïœ2áïh¸ý®€R5ÿª ±§úa²Q|àɢƚ 8Éñúa`ªçª ºÒÞo%{Ã#Ÿ5›AÈEcŽž­ø]=q€•8ø.…W ¢e5¾ŽÚ"£LM­Œïsc%Ч/Õ±fÚ]Ïb!ô ÚÐÒ(âÒ@ñ&±\z² À1¶© f“ïšÔwQwgœ.Œ¢»úÄvÚ°Šû“ÙV+™‹=<‘WÅÌ‹UˆHK\°l2õpÐI6¤aõ‰Œúñz~ö ÷² endstream endobj 2050 0 obj << /Type /Page /Contents 2051 0 R /Resources 2049 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R /Annots [ 1990 0 R 1995 0 R 1996 0 R 1997 0 R 1998 0 R 1999 0 R 2000 0 R 2001 0 R 2002 0 R 2003 0 R 2004 0 R 2005 0 R 2006 0 R 2007 0 R 2008 0 R 2009 0 R 2010 0 R 2011 0 R 2012 0 R 2013 0 R 2014 0 R 2015 0 R 2016 0 R 2017 0 R 2018 0 R 2019 0 R 2020 0 R 2021 0 R 2022 0 R 2023 0 R 2024 0 R 2025 0 R 2026 0 R 2027 0 R 2028 0 R 2029 0 R 2030 0 R 2031 0 R 2032 0 R 2033 0 R 2034 0 R 2035 0 R 2036 0 R 2037 0 R 2038 0 R 2039 0 R 2040 0 R 2041 0 R 2042 0 R 2043 0 R 2044 0 R 2045 0 R 2046 0 R 2047 0 R ] >> endobj 1990 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 676.929 286.921 687.833] /A << /S /GoTo /D (paragraph.6.1.2.14.1) >> >> endobj 1995 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 666.912 280.844 675.878] /A << /S /GoTo /D (paragraph.6.1.2.14.2) >> >> endobj 1996 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 654.956 290.138 663.923] /A << /S /GoTo /D (subsubsection.6.1.2.15) >> >> endobj 1997 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 641.064 286.921 651.968] /A << /S /GoTo /D (paragraph.6.1.2.15.1) >> >> endobj 1998 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 631.046 280.844 640.012] /A << /S /GoTo /D (paragraph.6.1.2.15.2) >> >> endobj 1999 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 617.153 265.62 628.057] /A << /S /GoTo /D (subsection.6.1.3) >> >> endobj 2000 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 605.198 282.178 616.102] /A << /S /GoTo /D (subsection.6.1.4) >> >> endobj 2001 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 593.243 304.893 604.147] /A << /S /GoTo /D (subsection.6.1.5) >> >> endobj 2002 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 581.288 267.074 592.192] /A << /S /GoTo /D (subsection.6.1.6) >> >> endobj 2003 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 569.333 274.158 580.237] /A << /S /GoTo /D (subsubsection.6.1.6.1) >> >> endobj 2004 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 557.377 271.947 568.281] /A << /S /GoTo /D (subsubsection.6.1.6.2) >> >> endobj 2005 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 547.48 276.998 556.326] /A << /S /GoTo /D (subsection.6.1.7) >> >> endobj 2006 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 533.467 246.573 544.371] /A << /S /GoTo /D (subsubsection.6.1.7.1) >> >> endobj 2007 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 523.569 274.468 532.416] /A << /S /GoTo /D (subsubsection.6.1.7.2) >> >> endobj 2008 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 509.557 287.12 520.461] /A << /S /GoTo /D (subsubsection.6.1.7.3) >> >> endobj 2009 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 497.602 286.921 508.506] /A << /S /GoTo /D (paragraph.6.1.7.3.1) >> >> endobj 2010 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 487.704 275.863 496.55] /A << /S /GoTo /D (paragraph.6.1.7.3.2) >> >> endobj 2011 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 473.691 302.711 484.595] /A << /S /GoTo /D (subsubsection.6.1.7.4) >> >> endobj 2012 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 461.736 324.838 472.64] /A << /S /GoTo /D (subsubsection.6.1.7.5) >> >> endobj 2013 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 449.781 299.403 460.685] /A << /S /GoTo /D (section.6.2) >> >> endobj 2014 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 437.826 288.385 448.73] /A << /S /GoTo /D (subsection.6.2.1) >> >> endobj 2015 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 425.871 308.569 436.775] /A << /S /GoTo /D (subsubsection.6.2.1.1) >> >> endobj 2016 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 413.915 286.094 424.819] /A << /S /GoTo /D (paragraph.6.2.1.1.1) >> >> endobj 2017 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 401.96 268.67 412.864] /A << /S /GoTo /D (paragraph.6.2.1.1.2) >> >> endobj 2018 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 390.005 282.488 400.909] /A << /S /GoTo /D (paragraph.6.2.1.1.3) >> >> endobj 2019 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 380.107 280.834 388.954] /A << /S /GoTo /D (paragraph.6.2.1.1.4) >> >> endobj 2020 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 366.095 333.426 376.999] /A << /S /GoTo /D (paragraph.6.2.1.1.5) >> >> endobj 2021 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 354.14 313.988 365.044] /A << /S /GoTo /D (subsection.6.2.2) >> >> endobj 2022 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 342.184 326.393 353.088] /A << /S /GoTo /D (subsubsection.6.2.2.1) >> >> endobj 2023 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 330.229 403.034 341.133] /A << /S /GoTo /D (paragraph.6.2.2.1.1) >> >> endobj 2024 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 318.274 385.61 329.178] /A << /S /GoTo /D (paragraph.6.2.2.1.2) >> >> endobj 2025 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 306.319 399.428 317.223] /A << /S /GoTo /D (paragraph.6.2.2.1.3) >> >> endobj 2026 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 294.364 397.774 305.268] /A << /S /GoTo /D (paragraph.6.2.2.1.4) >> >> endobj 2027 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 282.409 408.843 293.312] /A << /S /GoTo /D (paragraph.6.2.2.1.5) >> >> endobj 2028 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 272.511 415.597 281.357] /A << /S /GoTo /D (subsubsection.6.2.2.2) >> >> endobj 2029 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 258.498 267.712 269.402] /A << /S /GoTo /D (subsection.6.2.3) >> >> endobj 2030 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 246.543 240.455 257.447] /A << /S /GoTo /D (subsubsection.6.2.3.1) >> >> endobj 2031 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 234.588 277.506 245.492] /A << /S /GoTo /D (subsubsection.6.2.3.2) >> >> endobj 2032 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 222.633 302.691 233.537] /A << /S /GoTo /D (subsubsection.6.2.3.3) >> >> endobj 2033 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 210.678 308.829 221.581] /A << /S /GoTo /D (subsubsection.6.2.3.4) >> >> endobj 2034 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 198.722 226.308 209.626] /A << /S /GoTo /D (subsection.6.2.4) >> >> endobj 2035 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 186.767 327.08 197.671] /A << /S /GoTo /D (subsubsection.6.2.4.1) >> >> endobj 2036 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 174.812 242.607 185.716] /A << /S /GoTo /D (section.6.3) >> >> endobj 2037 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 162.857 225.89 173.761] /A << /S /GoTo /D (subsection.6.3.1) >> >> endobj 2038 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 150.902 223.15 161.806] /A << /S /GoTo /D (subsection.6.3.2) >> >> endobj 2039 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 138.947 307.294 149.85] /A << /S /GoTo /D (subsection.6.3.3) >> >> endobj 2040 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 126.991 297.222 137.895] /A << /S /GoTo /D (subsubsection.6.3.3.1) >> >> endobj 2041 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 115.036 347.324 125.94] /A << /S /GoTo /D (subsubsection.6.3.3.2) >> >> endobj 2042 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 103.081 254.053 113.985] /A << /S /GoTo /D (section.6.4) >> >> endobj 2043 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 91.126 262.303 102.03] /A << /S /GoTo /D (subsection.6.4.1) >> >> endobj 2044 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 79.171 269.506 90.075] /A << /S /GoTo /D (subsection.6.4.2) >> >> endobj 2045 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 69.273 282.657 78.119] /A << /S /GoTo /D (subsubsection.6.4.2.1) >> >> endobj 2046 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 55.26 247.927 66.164] /A << /S /GoTo /D (subsection.6.4.3) >> >> endobj 2047 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 43.305 351.886 54.209] /A << /S /GoTo /D (subsection.6.4.4) >> >> endobj 2052 0 obj << /D [2050 0 R /XYZ 89 721 null] >> endobj 2049 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2109 0 obj << /Length 1622 /Filter /FlateDecode >> stream xÚí›]s›F†ïý+¸”&•²ŸÀæÎuœL:Ó±Ô¦3i'ƒa-3A@9É¿ï ’XdÐVuÎd&cöÉÙóžóŒ×g?/Ïž¿²ˆÁæÌD¦±¼50,`Ï¡ÆÒ3>L.Þ]-/¯–‹éßË_ž¿¢hçRÅu‰WÒü’3 ï ÅßÀHVFypýú̘abÏ‘ ²ÄMpùc月?p:ƒ˜‚ÉòŽOgHx|ŠèäÞwåyÊ“û)¤ž”çòä&JåQœùQ¸÷ Ƈ™iÃÉ|:£|ÃÂØö¬ñ€ˆ`;`Ì œ3Jw¡! íâÙ³’Á&ó?óyZžfQùÉ´'U7òüpÕ|Fl} lMP€õ5ÃpnÛ*-*X!qßó©EDð 0~1ÖbÜ¡³æð/°ïf©òæwKšQw è""‘FDš’qïI¼vü°<ºÝ„nÛü¥}ñâ=W«Éõå¢ùâ…8iúñv*nï¸Y”|•lyvy͇°9 ­q_‚æ– - ¾ODz¬&}Vá\d<Žyò6ô.rš2‡g@ éx …ÚªJ»[Z'‰SLââ ‘FQÀ›ÀðÒ¦?ÐÆ5Ù¥"žU¸8÷v'¯|ÚÃÃEµpa%Ô¢õÚ ½Þ‰±12µ‘ÃEs_L¦mvZ:BP‚{М,Kü›¼"Üd½¹åO0>`‡Šg¦ e ]sÇû-Jý<é_¬½d“Úp\uœ­)¢ì‡ˆöãÚØ¡؉Î-Í’M>u^ ¶sk¥Ç´è)šê§ ˆò¹üy¿ôP~­m ¯Û=!:EjyÞ~})z0WèÆCì¨5xß $GÉÉŽC0Y»rRiȹâDÄ–s ¦ò û©ëL7?ÐÊf7é=Å¡=Ü ÷uFi KD‰ý0l‘æÄ“Ã<Ô¹@Øš]¯ï©aÄ|:ƒŽÑ˜]‡?4¦¿¶©UÙ ‹„ZO`šc=M¹©ÜÓrM4­ç¶šñY‹ñÒO¸»Ué6*è2`ÛV41Õ3ÑsUk·˜_ж0ü˜Òšx¨.žÏŽ dŠþïñ™XzLÌ’É5’FqµÖ\¨“Hˆd±“ &lž¶5 cqn)%Y¾n]³;°VcR8’¬Ü‰mFÉÜb¤t¹Ó¶Yöà.€MèU‡ï§Dt ¡W¶ jU†À¸T°ýN¿ ¡9ƒ*üÂgÞ3í—S[¤³põÛœ±JœøÎw@öpaƹ:¢äAÂì¬|=3E <~ÚvkËç:ž•\jÓádOr¼“’ƒS{QåFïdCðK\Ö œ¢âÜßñ îBÈÐXzX=’³³ÉÄøöÕEç\nŠ:¢Ã Sxi¦P¤¦Ð7¡Ÿ½-¯º|ÐWïÉ4R(RSèå—~àìïÖÄêM k«ÒåågWZÝÊÔ)³åÞé²ÁóÙ:íåh/å¯ÓÊ“÷™Íÿ“Nƒ»Í% D7Ùájçc9Œäã8µ]Û–[{ÈŽòIrÑÐh"9w5;NºýÞW é¼Ñ|*­ 15µ¤åu‘ çaGC6~•˜ù’¨ Ócc>Dcæhiq¬tg±å‹IrÚçž²Tì4uVª¿Fl:8cØZ´ê=5Çù›´¶Þj©­²j«`Hµ„þ¿6-aš¾™)}³‹hûìOå8Äá§zèu íoDÚþ{åù0<9¿zý®Û8‰\®æNÓÂNÇY^µ›µåU“k°Ú'X~Ô/ÏÑ28„™iÉ«¹ãv½“"ðûÕ›?+‚Ÿr °Nm<_à­ˆ¦_ÓŒ¯›!&CHbÝQÇ®v^±üÞ‹MGIý‡Œ©"Œ‚(^ó0«úŽ(P7I›öÐB´ã@Çv"6“¯GYÒêÃد2C5ÛŒGÜÐçjäªÖ`§føcjæÒ6ÕºÆ"Ûx~¤¾¯0„2•B½-¸fí^oÂðŠˆÁ¨ãuÇgë"œ%+¹sï>'™ûu^]h­g½Þ¾ŒÊÝ»Ðÿg£vŒŽÙ Xo}Óª‹½kîr;Cê¯B1¿•$ olÂßj o~^.Ïþ iáJ endstream endobj 2108 0 obj << /Type /Page /Contents 2109 0 R /Resources 2107 0 R /MediaBox [0 0 612 792] /Parent 1834 0 R /Annots [ 2048 0 R 2053 0 R 2054 0 R 2055 0 R 2056 0 R 2057 0 R 2058 0 R 2059 0 R 2060 0 R 2061 0 R 2062 0 R 2063 0 R 2064 0 R 2065 0 R 2066 0 R 2067 0 R 2068 0 R 2069 0 R 2070 0 R 2071 0 R 2072 0 R 2073 0 R 2074 0 R 2075 0 R 2076 0 R 2077 0 R 2078 0 R 2079 0 R 2080 0 R 2081 0 R 2082 0 R 2083 0 R 2084 0 R 2085 0 R 2086 0 R 2087 0 R 2088 0 R 2089 0 R 2090 0 R 2091 0 R 2092 0 R 2093 0 R 2094 0 R 2095 0 R 2096 0 R 2097 0 R 2098 0 R 2099 0 R 2100 0 R 2101 0 R 2102 0 R 2103 0 R 2104 0 R 2105 0 R ] >> endobj 2048 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 676.929 333.277 687.833] /A << /S /GoTo /D (subsubsection.6.4.4.1) >> >> endobj 2053 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 664.974 366.262 675.878] /A << /S /GoTo /D (subsubsection.6.4.4.2) >> >> endobj 2054 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 653.019 257.76 663.923] /A << /S /GoTo /D (subsection.6.4.5) >> >> endobj 2055 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 643.121 289.262 651.968] /A << /S /GoTo /D (subsection.6.4.6) >> >> endobj 2056 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 629.108 302.143 640.012] /A << /S /GoTo /D (subsection.6.4.7) >> >> endobj 2057 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 617.153 307.672 628.057] /A << /S /GoTo /D (subsection.6.4.8) >> >> endobj 2058 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 607.255 300.908 616.102] /A << /S /GoTo /D (subsubsection.6.4.8.1) >> >> endobj 2059 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 593.243 321.949 604.147] /A << /S /GoTo /D (subsubsection.6.4.8.2) >> >> endobj 2060 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 581.288 324.33 592.192] /A << /S /GoTo /D (subsubsection.6.4.8.3) >> >> endobj 2061 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 569.333 310.791 580.237] /A << /S /GoTo /D (subsubsection.6.4.8.4) >> >> endobj 2062 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 557.377 318.044 568.281] /A << /S /GoTo /D (subsubsection.6.4.8.5) >> >> endobj 2063 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 547.36 289.441 556.326] /A << /S /GoTo /D (subsection.6.4.9) >> >> endobj 2064 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 535.405 300.908 544.371] /A << /S /GoTo /D (subsubsection.6.4.9.1) >> >> endobj 2065 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 523.45 286.243 532.416] /A << /S /GoTo /D (subsubsection.6.4.9.2) >> >> endobj 2066 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 510.533 294.861 520.461] /A << /S /GoTo /D (subsubsection.6.4.9.3) >> >> endobj 2067 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 499.539 282.069 508.506] /A << /S /GoTo /D (subsubsection.6.4.9.4) >> >> endobj 2068 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 487.704 249.291 496.55] /A << /S /GoTo /D (subsection.6.4.10) >> >> endobj 2069 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 475.749 300.908 484.595] /A << /S /GoTo /D (subsubsection.6.4.10.1) >> >> endobj 2070 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 463.793 286.243 472.64] /A << /S /GoTo /D (subsubsection.6.4.10.2) >> >> endobj 2071 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 450.757 294.861 460.685] /A << /S /GoTo /D (subsubsection.6.4.10.3) >> >> endobj 2072 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 439.883 269.088 448.73] /A << /S /GoTo /D (subsubsection.6.4.10.4) >> >> endobj 2073 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 425.871 255.917 436.775] /A << /S /GoTo /D (subsection.6.4.11) >> >> endobj 2074 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 415.973 300.908 424.819] /A << /S /GoTo /D (subsubsection.6.4.11.1) >> >> endobj 2075 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 404.018 268.261 412.864] /A << /S /GoTo /D (subsubsection.6.4.11.2) >> >> endobj 2076 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 392.062 421.575 400.909] /A << /S /GoTo /D (subsubsection.6.4.11.3) >> >> endobj 2077 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 380.107 373.505 388.954] /A << /S /GoTo /D (subsubsection.6.4.11.4) >> >> endobj 2078 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 368.152 386.237 376.999] /A << /S /GoTo /D (subsubsection.6.4.11.5) >> >> endobj 2079 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 354.14 313.969 365.044] /A << /S /GoTo /D (subsubsection.6.4.11.6) >> >> endobj 2080 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 342.184 296.216 353.088] /A << /S /GoTo /D (subsubsection.6.4.11.7) >> >> endobj 2081 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 332.167 248.704 341.133] /A << /S /GoTo /D (section.6.5) >> >> endobj 2082 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 318.274 335.099 329.178] /A << /S /GoTo /D (subsection.6.5.1) >> >> endobj 2083 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 308.376 328.754 317.223] /A << /S /GoTo /D (subsubsection.6.5.1.1) >> >> endobj 2084 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 296.421 284.341 305.268] /A << /S /GoTo /D (subsubsection.6.5.1.2) >> >> endobj 2085 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 282.409 271.061 293.312] /A << /S /GoTo /D (subsubsection.6.5.1.3) >> >> endobj 2086 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 272.511 236.699 281.357] /A << /S /GoTo /D (subsection.6.5.2) >> >> endobj 2087 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 260.556 298.975 269.402] /A << /S /GoTo /D (subsubsection.6.5.2.1) >> >> endobj 2088 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 248.6 301.745 257.447] /A << /S /GoTo /D (subsubsection.6.5.2.2) >> >> endobj 2089 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 234.588 450.775 245.492] /A << /S /GoTo /D (subsubsection.6.5.2.3) >> >> endobj 2090 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 222.633 234.218 233.537] /A << /S /GoTo /D (subsection.6.5.3) >> >> endobj 2091 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 212.735 256.873 221.581] /A << /S /GoTo /D (subsection.6.5.4) >> >> endobj 2092 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 200.78 269.635 209.626] /A << /S /GoTo /D (subsubsection.6.5.4.1) >> >> endobj 2093 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 188.825 275.185 197.671] /A << /S /GoTo /D (subsubsection.6.5.4.2) >> >> endobj 2094 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 174.812 320.285 185.716] /A << /S /GoTo /D (subsubsection.6.5.4.3) >> >> endobj 2095 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 162.857 410.297 173.761] /A << /S /GoTo /D (subsubsection.6.5.4.4) >> >> endobj 2096 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 150.902 393.131 161.806] /A << /S /GoTo /D (section.6.6) >> >> endobj 2097 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 138.947 333.176 149.85] /A << /S /GoTo /D (subsection.6.6.1) >> >> endobj 2098 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 126.991 331.254 137.895] /A << /S /GoTo /D (subsubsection.6.6.1.1) >> >> endobj 2099 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 115.036 356.818 125.94] /A << /S /GoTo /D (paragraph.6.6.1.1.1) >> >> endobj 2100 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 103.081 283.065 113.985] /A << /S /GoTo /D (paragraph.6.6.1.1.2) >> >> endobj 2101 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 91.126 274.478 102.03] /A << /S /GoTo /D (paragraph.6.6.1.1.3) >> >> endobj 2102 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 79.171 334.283 90.075] /A << /S /GoTo /D (subsubsection.6.6.1.2) >> >> endobj 2103 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 67.216 277.267 78.119] /A << /S /GoTo /D (subsection.6.6.2) >> >> endobj 2104 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 55.26 270.821 66.164] /A << /S /GoTo /D (section.6.7) >> >> endobj 2105 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 43.305 227.175 54.209] /A << /S /GoTo /D (subsection.6.7.1) >> >> endobj 2110 0 obj << /D [2108 0 R /XYZ 89 721 null] >> endobj 2107 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2166 0 obj << /Length 1780 /Filter /FlateDecode >> stream xÚíœ[sÚ8Çßó)üPIÖÅ~ls›îL»3)}h÷Až56#›¦í§__dc,F›mƒÃKL€ü;Gçò×q€³p€sõnrõæŽaÇûQg2w|à0à&Îdæ|\ÿùqrûqòiø÷ä7w5ÞŠaö>èg'*ÞIó·\uf˜ýŽ\8僇û+gäboŒ<èŒËNâª?³1ÃẠ>'A´ŽPö0 wNê|Q„ãáˆpöìûÚ“­«e q‘αOH)RHo¿i •—‡™"2øL…b-ä·!$!Ëß’OÅ|†?Úßcü‘‘ãÎÇž§sË©¡ìô%¸ÖBûâÝòÐÁŽÿ>üu$øK6Ü6]*G}wò$i¦ï¹çÚŽ"0D‡ –‡©‘ãYºöqŽ´+GÚäèš8îà+cçZLƒ¯ ©z)^­x4ÓØ"ÿEGLjåkX1z3‘3ˆjPo5P{ÀP{èQûò‹«òK£ÐáQœ­NiÎÌkž¦BFå/ÁjŠ•ˆRž±zî)H—AÔZä _陽É)|6ça΃‰›ök¡}W/ÉXÓß㋸N¶×ayUÉ_ >k׋&› ô2Y0‹dë¤Û$ù$õÊÛèÝ Ÿ$ý#$³Ö4úÉõÇÌÍüet!+鲌+È>âí, cy¬œŠYIr.xº‘Cè „Vȸ@:€/˜>y§“…xìc¼kVV,g²4•ÁãÁ&U1Ї\®½7r{ÝX†.“o(ËXeeN€wƒV¥äicR庰ÌE’ ™Çcä¾{ cGmìYš(ÝóÜs!ëÈ—.¹*I> õÔ×l)=Ü|ʰa$­„èeb5‚DG«@³#Yn£ÍJHžV!ïDš¶ûr $6Øc‚:|NøBùtUG«\=zyÆYÄZf {MÞ¹¡Þ,ˆ×õf ÒDÈE˜lÛšò‘P‹¤îx²>r„êoÒ êtþ‰â< =…b¶ÐO×¢}ÁÀïrÁ ]; †ÛíbãMúŒ×ë-EŒêžœò u^(×˧oùçáFûÚŸ{ÑK±2PÉv'Æ£¢Õh[ÞE¯. aË<ìª<¬Iq”ø—úþ4Ë»ììÖÙù}”Êx¶™áP³½ ·GtêU ºŽ£\Í]l¤Ï«ÅQÊ‹?’T¬Î.YÆ™“vµhëVhÓÁ>-¹ÊüK®êTEøÇòºGˆÔƒe™þ5Ñßž­\o+¡uu¾t™k•IõJ¬ x¿g³ú8 f¨ª³®—q¼Ý>ØAÂÃE,³jR[’ÄwÏuþzv%•[o¶<4%íOU=5—ñê•Ek%nhAޏçÏ| 7Ä5Ó¬¬WuSLíð½1”üR$›°ŠsA’ÆR-!Ð;ÑÇQÐn¿ç›y<Ÿ«)ýN‹…UlßSwz~ŸNî®Ý1U@ï‚Æz=añÒW+˜uÇÝð_¦pïtøu%’n¢#™ÚBXó©ÿ"×?³}±j6'Ëj‡UKÑൗÏßñ0×®ÙÄu³ysd,r-ã©Ð]QúZƒ‰k%ã)X< ~6ÏU<«vòšÓ-ÇgWÛyó×¶¡&E•á““nHdž­ç½¼ÚOðÙ‰§ŒØUúx+\4Æ/ö¬Öþ©FÏ<©eZ#*­Ý‹¨Øµ¨R~cW>JcÐ}%3Âzb#ûÓ媨7ÆWYLy²õþ4žÆá®¢”J%ó*Ÿµl¤ âžðõì ZIÊäßåM"Œ6)è¯c©mÚx¿¸õ}v€ºƒÖ!ùF̋ɭºýoA‘"ÜN@d^»2 „azŸ¹zà´[WL-öbËàg§iÄØ¥a°·„æÏž²Á]¾âcùT¸´œu²ñ.ÍÛ°…98{®­¼óÀ´Eø’nW{©¥ŸÍjh욤ŒÞΪYb?DZÞ~¥' ]2Peݶ< V|¡'Q .Ëa¿%Ðés± ;!9.m§Ù²Ò°¾Ó§[UÙ©'ÕˆX¯õí]·E¹çž¬Œ@ØöfÛ别ѹjw=ß|䉖¦}÷¸ÉôðéÞº{w=¾¸.î·HjDn9ý‹yVìòü–¿’l<ïvó~’rY7TfÛ¨eÂõÁQú?(-Gu?Zøf^‚°²7Ät+> endobj 2106 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 676.929 251.673 687.833] /A << /S /GoTo /D (subsubsection.6.7.1.1) >> >> endobj 2111 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 664.974 335.638 675.878] /A << /S /GoTo /D (subsubsection.6.7.1.2) >> >> endobj 2112 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 653.019 200.027 663.923] /A << /S /GoTo /D (subsection.6.7.2) >> >> endobj 2113 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 641.064 277.964 651.968] /A << /S /GoTo /D (subsubsection.6.7.2.1) >> >> endobj 2114 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 629.108 278.233 640.012] /A << /S /GoTo /D (subsubsection.6.7.2.2) >> >> endobj 2115 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 617.153 338.277 628.057] /A << /S /GoTo /D (subsubsection.6.7.2.3) >> >> endobj 2116 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 605.198 318.632 616.102] /A << /S /GoTo /D (subsubsection.6.7.2.4) >> >> endobj 2117 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 593.243 432.602 604.147] /A << /S /GoTo /D (subsection.6.7.3) >> >> endobj 2118 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 581.288 208.346 592.192] /A << /S /GoTo /D (subsection.6.7.4) >> >> endobj 2119 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 569.333 284.868 580.237] /A << /S /GoTo /D (subsubsection.6.7.4.1) >> >> endobj 2120 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 557.377 283.772 568.281] /A << /S /GoTo /D (subsubsection.6.7.4.2) >> >> endobj 2121 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 537.497 185.073 546.473] /A << /S /GoTo /D (chapter.7) >> >> endobj 2122 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 525.562 193.68 534.408] /A << /S /GoTo /D (section.7.1) >> >> endobj 2123 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 513.607 226.736 522.453] /A << /S /GoTo /D (subsection.7.1.1) >> >> endobj 2124 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 499.968 326.491 510.498] /A << /S /GoTo /D (subsection.7.1.2) >> >> endobj 2125 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 489.696 212.49 498.543] /A << /S /GoTo /D (section.7.2) >> >> endobj 2126 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 475.684 251.792 486.588] /A << /S /GoTo /D (subsection.7.2.1) >> >> endobj 2127 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 463.729 443.462 474.633] /A << /S /GoTo /D (subsubsection.7.2.1.1) >> >> endobj 2128 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 451.773 456.194 462.677] /A << /S /GoTo /D (subsubsection.7.2.1.2) >> >> endobj 2129 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 439.818 303.797 450.722] /A << /S /GoTo /D (subsubsection.7.2.1.3) >> >> endobj 2130 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 427.863 254.562 438.767] /A << /S /GoTo /D (subsection.7.2.2) >> >> endobj 2131 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 415.908 187.544 426.812] /A << /S /GoTo /D (section.7.3) >> >> endobj 2132 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 406.01 209.99 414.857] /A << /S /GoTo /D (subsection.7.3.1) >> >> endobj 2133 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 391.998 284.45 402.902] /A << /S /GoTo /D (subsection.7.3.2) >> >> endobj 2134 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 380.042 373.177 390.946] /A << /S /GoTo /D (subsubsection.7.3.2.1) >> >> endobj 2135 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 368.087 346.597 378.991] /A << /S /GoTo /D (subsubsection.7.3.2.2) >> >> endobj 2136 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 356.132 311.737 367.036] /A << /S /GoTo /D (subsubsection.7.3.2.3) >> >> endobj 2137 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 344.177 306.656 355.081] /A << /S /GoTo /D (subsection.7.3.3) >> >> endobj 2138 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 332.222 334.899 343.126] /A << /S /GoTo /D (subsection.7.3.4) >> >> endobj 2139 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 320.267 271.418 331.171] /A << /S /GoTo /D (subsection.7.3.5) >> >> endobj 2140 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 308.311 244.42 319.215] /A << /S /GoTo /D (subsection.7.3.6) >> >> endobj 2141 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 296.356 345.351 307.26] /A << /S /GoTo /D (subsection.7.3.7) >> >> endobj 2142 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 284.401 169.8 295.305] /A << /S /GoTo /D (section.7.4) >> >> endobj 2143 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 272.446 247.748 283.35] /A << /S /GoTo /D (subsection.7.4.1) >> >> endobj 2144 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 262.548 369.131 271.395] /A << /S /GoTo /D (subsubsection.7.4.1.1) >> >> endobj 2145 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 250.593 317.605 259.44] /A << /S /GoTo /D (subsubsection.7.4.1.2) >> >> endobj 2146 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 236.58 217.461 247.484] /A << /S /GoTo /D (subsection.7.4.2) >> >> endobj 2147 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 224.625 272.743 235.529] /A << /S /GoTo /D (section.7.5) >> >> endobj 2148 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 212.67 298.078 223.574] /A << /S /GoTo /D (section.7.6) >> >> endobj 2149 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 200.715 339.383 211.619] /A << /S /GoTo /D (subsection.7.6.1) >> >> endobj 2150 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 188.76 301.465 199.664] /A << /S /GoTo /D (subsection.7.6.2) >> >> endobj 2151 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 178.862 210.278 187.709] /A << /S /GoTo /D (section.7.7) >> >> endobj 2152 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 166.907 207.26 175.753] /A << /S /GoTo /D (section.7.8) >> >> endobj 2153 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 154.952 201.143 163.798] /A << /S /GoTo /D (subsection.7.8.1) >> >> endobj 2154 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 140.939 190.075 151.843] /A << /S /GoTo /D (subsection.7.8.2) >> >> endobj 2155 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 128.984 209.013 139.888] /A << /S /GoTo /D (section.7.9) >> >> endobj 2156 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 117.029 298.487 127.933] /A << /S /GoTo /D (section.7.10) >> >> endobj 2157 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 105.074 270.382 115.977] /A << /S /GoTo /D (section.7.11) >> >> endobj 2158 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 95.176 253.227 104.022] /A << /S /GoTo /D (section.7.12) >> >> endobj 2159 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 81.163 385.818 92.067] /A << /S /GoTo /D (subsection.7.12.1) >> >> endobj 2160 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 69.208 458.355 80.112] /A << /S /GoTo /D (subsection.7.12.2) >> >> endobj 2161 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 57.253 353.42 68.157] /A << /S /GoTo /D (section.7.13) >> >> endobj 2162 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 45.298 272.484 56.202] /A << /S /GoTo /D (section.7.14) >> >> endobj 2167 0 obj << /D [2165 0 R /XYZ 89 721 null] >> endobj 2164 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2223 0 obj << /Length 1483 /Filter /FlateDecode >> stream xÚí›[s£6†ïó+¸´gjG‰Ët»›¶3ÝN÷jÛñ( 8L9x@Þ$ûë+ Ž9Ø»6±obNôè;¼ú$€¶Ð€v{õóìêú14kj™ÈÔfš4èX›9ڗч??Ï>~žÝÿý~ý £Ü¥”×AKÞh}%I.¹Ù¡ü ´h¡¥w·WÚD§` M¨M‘7ѳ›Bc ÇÀèï˜Gã Â`¹‹'§Ûÿ¸Â ƒÂ3´/,ÿk:èaYí®,5š@0‚´‘7Ð&N-Œs Q únn°Hù²ôg6¦r;X„é®" ½t'~÷ÓígW<¥[≮õ¸“ÝѶy—_Û€æw‚VÅÇ |¤áƒœ5Ot2¥˜Jã”Ì M™ÝH\„Žîø£4LHG<°³&/Y$ŠÏ5·ÁæÆ ×ç«\p£‰néSQ±·nŸ ˆŽ~ác„G_Ý܃™Ï…|ŸR«M×~Ód}²Ãi’½o(}‘ô†%-a¶1y§Ô-³ÿË6ÃÅô ãB¼]˜J`£ØíÈ]®Âú@’ ¸ç”߀RúN ­Þ€6Ld›,p¶ÇVJ8Ç¿/+Þ±¹el40^ÊT™dßò‰y‰Î 7ÀöÂÅ¢6ÆÆ™ÃFz½:¢j]„ˆÜ‡1£• eÚœƒ69H¿èý$ ÚH”_YäLìÐÙˆqggG5¥äÉ ‰ÊÖÊ¿‘ §”VLJ%ž‹&7*,‡‰lÄ$^—Š¥SÓžVR4:g>”J·"A¶‹àcùL”ŸoáóW0?½ Ïg/sÇõç/%E¶9þÚ俦?„E%Ü ‚Ñ‚"ΜëçÈÝìWy"Âæ¬è€ä°B.ŽCÛ•‚>3›±]Y@iÖø”ÁK‚1{1Û%7^z,s(/Í™cˆGÜk C xt[: +Rf…¡¨¥H& |&Cp¹åëœjÈ弬XñGè¸I‚=x}„–á`Em?ž5" ½‰°[ðˆmÜo-ø£¡£Áj†FbȒĪ‘­¡¡ü88“Vƒ=ôTt<éÀ6´ÀÂwƒù×$¢3oÅ+¤Té\½yíY5h¶ڳɺÒdûímF¦ƒèÏ hsU¢Ö Ô±‡Ç"£½­²Ã Õ‹UĶ5äú^× 9z2§‚ƒYÀ¢‡Ä!rp Î;^QtŠŽ€ª}ÿy,ïɢܔg¾ÁÊÙ]þÖB«g Ww¸'Ø\”Z–Í"[c»<‚¯[{øº2TÎ)ö@ìïóÑ£KR«¿ ÐUŸ—4æö å Èâ‰z(¢c™¨n¥âîK¹R‰Ûù½Æá-> ŃèQsK0b´’pf?¹[˜o;ÿ'I 傼¬oXGÕ2¤ò=5Cš_¹½#‹šú‰•ß÷ÎÌíúLòSL‘jÁÙdì=â-ùø{Ž#u:´±b³Ï±Ë&Yïx|@zä¨ë4ºbƒ=gðôš•E®ZD5 <£‰»ž¤²sP§i¼·x®·Æ[÷VS¾ÖÍa—‘Z`¬,#éUsy[bUÓÊó©A†= Õ¨‡êÁõ.’ÓS¨ËؤÆÜj‹ÀmÜaôîWR! ÷0Æv©cb1Ƕb©]RÁƒÍ&z7Åô–•jÅd{,Ž›êéž«Jªì‚î+#p ¿çÒkÓ0.«ÌÑ fÚ 7+úL¸6ó¼L0ÇÙVÙ|ŸŽ:°Âäbâ +øLå#ƒûíbì ¬*àÅ»²ò}Á}ºÀ}hŒÍ áö„ËŸü¸b'_j¢3/àžÚ„dÚäžGéX,RÄI9cÖFéAV{zFiÜ/J“K”î»ûZ4r‰Òßp9Jgã9LÉç­»HB.P+¡–¿þÊh*á¹Æ‚‰þžƒn å/¼þZñèõÃ6»Õ‘¤øì,´üûqvõ?C«Œ endstream endobj 2222 0 obj << /Type /Page /Contents 2223 0 R /Resources 2221 0 R /MediaBox [0 0 612 792] /Parent 2168 0 R /Annots [ 2163 0 R 2169 0 R 2170 0 R 2171 0 R 2172 0 R 2173 0 R 2174 0 R 2175 0 R 2176 0 R 2177 0 R 2178 0 R 2179 0 R 2180 0 R 2181 0 R 2182 0 R 2183 0 R 2184 0 R 2185 0 R 2186 0 R 2187 0 R 2188 0 R 2189 0 R 2190 0 R 2191 0 R 2192 0 R 2193 0 R 2194 0 R 2195 0 R 2196 0 R 2197 0 R 2198 0 R 2225 0 R 2199 0 R 2200 0 R 2201 0 R 2202 0 R 2203 0 R 2204 0 R 2205 0 R 2206 0 R 2207 0 R 2208 0 R 2209 0 R 2210 0 R 2211 0 R 2212 0 R 2213 0 R 2214 0 R 2215 0 R 2216 0 R 2217 0 R 2218 0 R 2219 0 R ] >> endobj 2163 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 676.929 245.416 687.833] /A << /S /GoTo /D (subsection.7.14.1) >> >> endobj 2169 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 664.974 395.691 675.878] /A << /S /GoTo /D (subsection.7.14.2) >> >> endobj 2170 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 643.191 169.103 654.07] /A << /S /GoTo /D (appendix.A) >> >> endobj 2171 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 631.101 199.14 642.005] /A << /S /GoTo /D (section.A.1) >> >> endobj 2172 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 621.083 245.974 630.05] /A << /S /GoTo /D (subsection.A.1.1) >> >> endobj 2173 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 607.191 271.438 618.095] /A << /S /GoTo /D (subsection.A.1.2) >> >> endobj 2174 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 597.173 267.284 606.139] /A << /S /GoTo /D (subsection.A.1.3) >> >> endobj 2175 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 583.28 235.195 594.184] /A << /S /GoTo /D (subsection.A.1.4) >> >> endobj 2176 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 571.325 237.407 582.229] /A << /S /GoTo /D (subsection.A.1.5) >> >> endobj 2177 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 561.308 192.315 570.274] /A << /S /GoTo /D (section.A.2) >> >> endobj 2178 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 547.415 317.694 558.319] /A << /S /GoTo /D (subsection.A.2.1) >> >> endobj 2179 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 535.46 294.074 546.364] /A << /S /GoTo /D (subsubsection.A.2.1.1) >> >> endobj 2180 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 525.442 300.709 534.408] /A << /S /GoTo /D (subsubsection.A.2.1.2) >> >> endobj 2181 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 511.549 380.33 522.453] /A << /S /GoTo /D (subsubsection.A.2.1.3) >> >> endobj 2182 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 499.594 315.095 510.498] /A << /S /GoTo /D (subsubsection.A.2.1.4) >> >> endobj 2183 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 487.639 361.291 498.543] /A << /S /GoTo /D (subsubsection.A.2.1.5) >> >> endobj 2184 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 475.684 347.622 486.588] /A << /S /GoTo /D (subsubsection.A.2.1.6) >> >> endobj 2185 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 463.729 337.5 474.633] /A << /S /GoTo /D (subsubsection.A.2.1.7) >> >> endobj 2186 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 451.773 286.153 462.677] /A << /S /GoTo /D (subsection.A.2.2) >> >> endobj 2187 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 439.818 313.341 450.722] /A << /S /GoTo /D (subsubsection.A.2.2.1) >> >> endobj 2188 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 427.863 362.795 438.767] /A << /S /GoTo /D (paragraph.A.2.2.1.1) >> >> endobj 2189 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 415.908 409.261 426.812] /A << /S /GoTo /D (paragraph.A.2.2.1.2) >> >> endobj 2190 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 403.953 381.057 414.857] /A << /S /GoTo /D (paragraph.A.2.2.1.3) >> >> endobj 2191 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 391.998 373.664 402.902] /A << /S /GoTo /D (subsubsection.A.2.2.2) >> >> endobj 2192 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 380.042 411.971 390.946] /A << /S /GoTo /D (paragraph.A.2.2.2.1) >> >> endobj 2193 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 368.087 431.697 378.991] /A << /S /GoTo /D (paragraph.A.2.2.2.2) >> >> endobj 2194 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 356.132 387.373 367.036] /A << /S /GoTo /D (paragraph.A.2.2.2.3) >> >> endobj 2195 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 344.177 372.16 355.081] /A << /S /GoTo /D (subsubsection.A.2.2.3) >> >> endobj 2196 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 332.222 414.163 343.126] /A << /S /GoTo /D (paragraph.A.2.2.3.1) >> >> endobj 2197 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 320.267 361.331 331.171] /A << /S /GoTo /D (paragraph.A.2.2.3.2) >> >> endobj 2198 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.63 308.311 513.996 319.215] /A << /S /GoTo /D (paragraph.A.2.2.3.3) >> >> endobj 2225 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 296.356 284.141 307.26] /A << /S /GoTo /D (paragraph.A.2.2.3.3) >> >> endobj 2199 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 284.401 315.771 295.305] /A << /S /GoTo /D (subsection.A.2.3) >> >> endobj 2200 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 272.446 325.176 283.35] /A << /S /GoTo /D (subsection.A.2.4) >> >> endobj 2201 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 260.491 176.465 271.395] /A << /S /GoTo /D (section.A.3) >> >> endobj 2202 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 248.536 301.844 259.44] /A << /S /GoTo /D (subsection.A.3.1) >> >> endobj 2203 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 236.58 304.823 247.484] /A << /S /GoTo /D (subsubsection.A.3.1.1) >> >> endobj 2204 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 224.625 331.772 235.529] /A << /S /GoTo /D (subsubsection.A.3.1.2) >> >> endobj 2205 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 212.67 270.303 223.574] /A << /S /GoTo /D (subsection.A.3.2) >> >> endobj 2206 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 200.715 299.921 211.619] /A << /S /GoTo /D (subsection.A.3.3) >> >> endobj 2207 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 188.76 309.326 199.664] /A << /S /GoTo /D (subsection.A.3.4) >> >> endobj 2208 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 176.805 220.997 187.709] /A << /S /GoTo /D (section.A.4) >> >> endobj 2209 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 166.907 214.094 175.753] /A << /S /GoTo /D (section.A.5) >> >> endobj 2210 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 152.894 257.799 163.798] /A << /S /GoTo /D (section.A.6) >> >> endobj 2211 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 142.996 240.425 151.843] /A << /S /GoTo /D (subsection.A.6.1) >> >> endobj 2212 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 131.041 244.858 139.888] /A << /S /GoTo /D (subsection.A.6.2) >> >> endobj 2213 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 119.086 234.338 127.933] /A << /S /GoTo /D (subsection.A.6.3) >> >> endobj 2214 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 107.131 257.66 115.977] /A << /S /GoTo /D (section.A.7) >> >> endobj 2215 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 95.176 240.425 104.022] /A << /S /GoTo /D (subsection.A.7.1) >> >> endobj 2216 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 83.221 244.858 92.067] /A << /S /GoTo /D (subsection.A.7.2) >> >> endobj 2217 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 71.265 265.072 80.112] /A << /S /GoTo /D (subsection.A.7.3) >> >> endobj 2218 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 59.31 274.577 68.157] /A << /S /GoTo /D (subsection.A.7.4) >> >> endobj 2219 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 45.298 266.985 56.202] /A << /S /GoTo /D (subsection.A.7.5) >> >> endobj 2224 0 obj << /D [2222 0 R /XYZ 89 721 null] >> endobj 2221 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2281 0 obj << /Length 1687 /Filter /FlateDecode >> stream xÚí›]s›8†ïó+¸„iMõ@ºL“4™Ý4Icw:»íN†âÐÅàÜNöׯ°dv0É66ÎM Æö£Wç¼çHÚHÚéÁûÁÁ»Ž¥1“ÙÈÖwš¨ ,¢ <í«~ty18¹ô¿¿½û@PáR òë ã7š]IóK€¼3ä–Œ4qp}z õ0&´¡ÖC¿ /;4Ó6zÌ¡úàÞ7zˆýÓÔOŽ}ýG0”Oãñؼһh_{6#ºiôÛý`1öÈ%Ês а£ ´„&#d‰ÓQpþ„a'>ï:ÌN Ì´Nµ_ èÁ¿nâ…nš^%ñÄO²‡µø¥[FìÙ±õŒäoDɱ­í”׳Á‚€¿O…VzÛ4bÖ­à×¢]€ˆýÌM²«8 ƒh´Ÿå n¼ç&ª0'Mä¼&z¤XAzèy—·ß›@ÝÞiþÊ´Œ×þ¸!Æ­Ÿî-1Ò6‰‚ñó¤ Æ+? bo-LäнáVL6¶Â-'æ{ó5ír¦i%DG:wˆœ+OäÙ4]KüJT!J¢çñðï†Å”íAúfm¨25`Fpµm§“úlCJ/“Lw[¢¿%¬ž9ÏÁÓ†`¿Q;R+ž“$ºe¼O‡I0É‚8:ºw£‘2Õg'ßGoÞˆ“ÔOÄ‹qGá¿VÚ@€<7:´‘–Z®ü9þ§1åS@HñV6mÚ‘±V)å(޾€’q‘ÏúrÙ»3¯ lC‹TËÞóx4âUÆÀ @wR}ägë#¢ÝðíÚÕš7Î5'„·9Nb9»Ü!jP-2Nýlsj ØÝHÍ$]Éð\¸Ž™ׯ;YvÊj´S£ZJô[$Ìy%‰AM›Z¢\¿´äиíXÖ.£4‚‰ð^Ãì!d2h©Hy¼¤Ü¶÷•j`˜/‹COéLIJhÀK`µê%¤Ë+õµàñÆ*f¹ÈéÑ(TÃx¡ß(Žù8¨õ lç·C´”ü“ $ü…W`&T6¸<«q­»AèÞ†‹Æ¤˜£cú*ð’ÀM¤ ­2œQæ'w—+%{uEÀÎwc`>8É,‰¥ýJÒÌËã‰? ò Xqc6ìXyÚXEŽÂ˜ª QSd1{ÆC.ø(s—mÏšŸ†²”A'œúÕ³¶…g;‚ žÚÃÌ‘ˆºççÚ‚.µÁbíÝÀæˆíây[Ô°ˆ>Ö8›#/pQV !·y&œÞåÝùIºlŸ}ùX×"FÛ°gaÓ®j+íÊ®êaÆ9Ÿ ´î…8øyïËiþ3á"žÿßͲ$\3¿@”‹ÇîòºIÌ“bcЬ—›ç¤ +R/Â1{ÁÐM—ß¹FyᎠëâ†xf÷ó¡”­Õþ”—¶‰ÜßIK•%a¿0yï_Îòøö»?Ì+Ú[cH[£¥QZ,x­4F˜€n£ÿ=;‘– V,”Ry€X– Ãpêùó  Pè/h–¿Æ¼¯ ™6³vÏ”’Íó=\Xª2Âàe ð{<p«•ÆIÉmUŒ'ÅÖ®»ûÍ¢ÂÏp#ÙäGé.·gžE¡Iiî< سf˜Ã}ÀxºYÝÆ…qìÍW?¿Æ[D¥f"öËl‡§·ŠU+GµÚL³5¯„Ùl¤è´™õ¤³›¹«e!v^°9rÚ¹]‹¼4é½ åñ@ºÝ°´æ¨~J;Ù b›Yߥ#@Âúªû>Õ-_Ò Èj¡°h1¼–µ¿CGãEq&ÚUI÷È«k@¶ýâ„ÛÁ\aUÑܪÎ~9É+×pE^Â­ì ²÷®·ºùFQZÚØdëÊGñëÍÈ}™´ÔZ¬hãíû|(¥‘=Ùxþ:ï›E EEÿʰ~xqzysvÙTQƒ»ÚQ¬Õi>éíêrxiKG_NãEÑ¿Ä}~yzse0¤B}pV×pú…™¦9»KyG2á?oÝTžÍRr~0 ¡/ÏÝ¡†ùq1Ræç9«ô?ß|îŸ\¿OŠ'´~ÿK¾uy}ü6ÿКLj9åq×Ït]6âÇy„‘ôgÃòÞÀ„ßù¤n$,B_,'=>.½º¯/GÇ*ŒŽÜ¦±†1 •hjïì\¯eXQõñdpð{!@¤ endstream endobj 2280 0 obj << /Type /Page /Contents 2281 0 R /Resources 2279 0 R /MediaBox [0 0 612 792] /Parent 2168 0 R /Annots [ 2220 0 R 2226 0 R 2227 0 R 2228 0 R 2229 0 R 2230 0 R 2231 0 R 2232 0 R 2233 0 R 2234 0 R 2235 0 R 2236 0 R 2237 0 R 2238 0 R 2239 0 R 2240 0 R 2241 0 R 2242 0 R 2243 0 R 2244 0 R 2245 0 R 2246 0 R 2247 0 R 2248 0 R 2249 0 R 2250 0 R 2251 0 R 2252 0 R 2253 0 R 2254 0 R 2255 0 R 2256 0 R 2257 0 R 2258 0 R 2259 0 R 2260 0 R 2261 0 R 2262 0 R 2263 0 R 2264 0 R 2265 0 R 2266 0 R 2267 0 R 2268 0 R 2269 0 R 2270 0 R 2271 0 R 2272 0 R 2273 0 R 2274 0 R 2275 0 R 2276 0 R 2283 0 R 2277 0 R ] >> endobj 2220 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 676.929 273.362 687.833] /A << /S /GoTo /D (subsection.A.7.6) >> >> endobj 2226 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 667.031 236.002 675.878] /A << /S /GoTo /D (subsection.A.7.7) >> >> endobj 2227 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 653.019 330.218 663.923] /A << /S /GoTo /D (subsection.A.7.8) >> >> endobj 2228 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 641.064 324.978 651.968] /A << /S /GoTo /D (subsection.A.7.9) >> >> endobj 2229 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 629.108 288.863 640.012] /A << /S /GoTo /D (subsection.A.7.10) >> >> endobj 2230 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 617.153 268.111 628.057] /A << /S /GoTo /D (subsection.A.7.11) >> >> endobj 2231 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 605.198 267.563 616.102] /A << /S /GoTo /D (subsection.A.7.12) >> >> endobj 2232 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 593.243 281.391 604.147] /A << /S /GoTo /D (subsection.A.7.13) >> >> endobj 2233 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 581.288 283.055 592.192] /A << /S /GoTo /D (subsection.A.7.14) >> >> endobj 2234 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 569.333 307.403 580.237] /A << /S /GoTo /D (subsection.A.7.15) >> >> endobj 2235 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 559.435 273.929 568.281] /A << /S /GoTo /D (subsection.A.7.16) >> >> endobj 2236 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 547.48 277.267 556.326] /A << /S /GoTo /D (subsection.A.7.17) >> >> endobj 2237 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 535.405 268.938 544.371] /A << /S /GoTo /D (subsection.A.7.18) >> >> endobj 2238 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 523.45 281.112 532.416] /A << /S /GoTo /D (subsection.A.7.19) >> >> endobj 2239 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 511.494 283.882 520.461] /A << /S /GoTo /D (subsection.A.7.20) >> >> endobj 2240 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 499.539 281.68 508.506] /A << /S /GoTo /D (subsection.A.7.21) >> >> endobj 2241 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 485.646 398.292 496.55] /A << /S /GoTo /D (subsection.A.7.22) >> >> endobj 2242 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 473.691 345.71 484.595] /A << /S /GoTo /D (subsection.A.7.23) >> >> endobj 2243 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 461.736 327.179 472.64] /A << /S /GoTo /D (subsection.A.7.24) >> >> endobj 2244 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 449.781 296.445 460.685] /A << /S /GoTo /D (subsection.A.7.25) >> >> endobj 2245 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 437.826 312.196 448.73] /A << /S /GoTo /D (subsection.A.7.26) >> >> endobj 2246 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 425.871 293.675 436.775] /A << /S /GoTo /D (subsection.A.7.27) >> >> endobj 2247 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 413.915 290.936 424.819] /A << /S /GoTo /D (subsection.A.7.28) >> >> endobj 2248 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 401.96 289.282 412.864] /A << /S /GoTo /D (subsection.A.7.29) >> >> endobj 2249 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 390.005 272.535 400.909] /A << /S /GoTo /D (subsection.A.7.30) >> >> endobj 2250 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 378.05 273.083 388.954] /A << /S /GoTo /D (subsection.A.7.31) >> >> endobj 2251 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 366.095 254.332 376.999] /A << /S /GoTo /D (section.A.8) >> >> endobj 2252 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 354.14 212.45 365.044] /A << /S /GoTo /D (section.A.9) >> >> endobj 2253 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 342.184 276.221 353.088] /A << /S /GoTo /D (subsection.A.9.1) >> >> endobj 2254 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 330.229 275.454 341.133] /A << /S /GoTo /D (subsection.A.9.2) >> >> endobj 2255 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 318.274 222.392 329.178] /A << /S /GoTo /D (section.A.10) >> >> endobj 2256 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 308.376 341.913 317.223] /A << /S /GoTo /D (subsection.A.10.1) >> >> endobj 2257 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 296.421 251.493 305.268] /A << /S /GoTo /D (subsection.A.10.2) >> >> endobj 2258 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 282.409 322.407 293.312] /A << /S /GoTo /D (subsection.A.10.3) >> >> endobj 2259 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 270.453 376.683 281.357] /A << /S /GoTo /D (subsection.A.10.4) >> >> endobj 2260 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 258.498 314.527 269.402] /A << /S /GoTo /D (subsection.A.10.5) >> >> endobj 2261 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 246.543 344.742 257.447] /A << /S /GoTo /D (subsection.A.10.6) >> >> endobj 2262 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 234.588 179.663 245.492] /A << /S /GoTo /D (section.A.11) >> >> endobj 2263 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 222.633 318.203 233.537] /A << /S /GoTo /D (subsection.A.11.1) >> >> endobj 2264 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 210.678 301.864 221.581] /A << /S /GoTo /D (subsection.A.11.2) >> >> endobj 2265 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 198.722 241.84 209.626] /A << /S /GoTo /D (subsection.A.11.3) >> >> endobj 2266 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 186.767 356.937 197.671] /A << /S /GoTo /D (subsubsection.A.11.3.1) >> >> endobj 2267 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 174.812 255.688 185.716] /A << /S /GoTo /D (subsection.A.11.4) >> >> endobj 2268 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 162.857 226.617 173.761] /A << /S /GoTo /D (subsection.A.11.5) >> >> endobj 2269 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 150.902 279.907 161.806] /A << /S /GoTo /D (subsection.A.11.6) >> >> endobj 2270 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 138.947 351.358 149.85] /A << /S /GoTo /D (section.A.12) >> >> endobj 2271 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 128.929 251.633 137.895] /A << /S /GoTo /D (subsection.A.12.1) >> >> endobj 2272 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 115.036 329.271 125.94] /A << /S /GoTo /D (subsection.A.12.2) >> >> endobj 2273 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 105.138 250.567 113.985] /A << /S /GoTo /D (subsection.A.12.3) >> >> endobj 2274 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 92.102 266.508 102.03] /A << /S /GoTo /D (subsubsection.A.12.3.1) >> >> endobj 2275 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 79.171 392.345 90.075] /A << /S /GoTo /D (subsubsection.A.12.3.2) >> >> endobj 2276 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 67.589 513.996 78.119] /A << /S /GoTo /D (subsubsection.A.12.3.3) >> >> endobj 2283 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 55.634 380.33 66.164] /A << /S /GoTo /D (subsubsection.A.12.3.3) >> >> endobj 2277 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 45.362 287.897 54.209] /A << /S /GoTo /D (subsubsection.A.12.3.4) >> >> endobj 2282 0 obj << /D [2280 0 R /XYZ 89 721 null] >> endobj 2279 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2330 0 obj << /Length 1325 /Filter /FlateDecode >> stream xÚí[[s£6}ϯàf «+’ò–Äqf;í¦³q§ÛN‡Ø$¡C r7鯯@ØÁ_ÀN;Nx±1ÆX>çèè»ÈÀº·€uur>9ù4fÄžð‘oMî,,¸µ&3ë›}qýerùerãü1ùñÓ˜¢Ú¥ªë P7*¯Å%' º3TÀÊî-}ðõêÄr1áâÐrS7ÁúcgDö¨ãúˆÛ“‡Ðqvè jÿí@j‡‰Ô§nìù]ñÆ]˜ésyôO¸ò½Ö7ù¾í9.à(žˆÆÉÆ/bØÁ-+&A×Ã\¡ =¹FûÜq9Ư0Oì³/W×úåçÑOúàwP\]sê¸X àçt6_?†ì ¹O ì1¦L•o´qEBx‚Ë…jˆ´RܹÕ 9¶Ïâ(ÈÃÜø zTôþÇÊÙôÔª*´mÚ‚&=HÓs™Ì rB9‡#ÇïLÖäÜÈl>•=oKïLÑôüšDib°ƒ!Ø9;˜uf‡VÎö< ŸdCyí9';ÏÁ‰¯9ùœÈ0»sÔM‚é2á  BNOG:\Œ¦¡9§ÄG¥£©hÑÉü"(ƒ@…ŽgRf‘Å¥œQ4Ì…ÃM‚ü¨‚ÿú)Ì‚Voâ>0_‹ùöì´]ø¬›ýü‰ ZÞõ³ûY[ZΠù^šßüªæ—K.ï¨yh~OÍãž>/:jž šoBOúi^ šßSó´§æ!p\ÜEôt}{¿Ÿè!(TO•èÓµ¢Ç˜ ¹Ô6üYǦf§¦È…ã2ÆkMr ¤·…Óªõ”Qr¿hP0 ‹ÎT1'~Ð'ƒzV\Jfúà)s /y–/êðùC ÏÕïSWöï™\,z&µBÈbàFID06T¯:©¬¢f÷²ÕÅ¢I2žÇq«œZXá{óÐæ¶ŠŒeˆq“>.Ìj?O±YÅ"þ{ö­‰$†ç-¨—¸Ã•y0ks¨­Œ0FÙ~è6äP…Ü™¹²ìçðˆ4y@äðzäž2½ ¯·a èñMè‚G*ðšÄÈaq´Ž¸€~@Zxy¾+v‰c_TúAèRâ1a,ظ=š]†ÔÁ&S Š}CF2ÅÙ{^ÄäÕö„¯afzó]ø÷¢:f³¼AÄô!È‚© ³¼J„âè1’íù,âä}ìÄ£¨cÒ¹HÙêIçH'72Èä2· šÛë4Èi"uYÅPùK.ÃGss‚X÷Ï#Ge‰¸ý›C€ɇt^¥,³@·An8óŶlÓ î8GeúX£a3” ý›3‚72²êŠ«›—ß}ù¥_é”öê‘)" *ª%ãà4k¬õË,ŒÃró°^”Ò‚ï‹Mãò!Hô7í }0Al/jÁ·t[#»MËzh©xcYüÃI›ôêÈŒÊøË0™ú^üy¾ˆÈ‚|ó¢€)lf'. «§{°Ða!`¿çìƒô³w:ØûÛŠ{°÷½Q§½6Vʽ̆±ÈűÊ4/㥷L§andÑ|ð–ûVô7fßLsqÙø\’Êèn†f·•ÁË(Žä‹±¦ês5¿†}YÚ[¿ºZh‚ûðµí|Klë@Lÿ÷R¡€šÊ¸(_Õ ­wÞÍU<IdðlúBL‡õçx\0£[ŽŒØ¿dë ÙmÎo ‡¼}­JXÇtFS¶RÑ®²‹¹h>_NNþœap endstream endobj 2329 0 obj << /Type /Page /Contents 2330 0 R /Resources 2328 0 R /MediaBox [0 0 612 792] /Parent 2168 0 R /Annots [ 2278 0 R 2284 0 R 2285 0 R 2286 0 R 2287 0 R 2288 0 R 2289 0 R 2290 0 R 2291 0 R 2292 0 R 2293 0 R 2294 0 R 2295 0 R 2296 0 R 2297 0 R 2298 0 R 2299 0 R 2300 0 R 2301 0 R 2302 0 R 2303 0 R 2304 0 R 2305 0 R 2306 0 R 2307 0 R 2308 0 R 2309 0 R 2310 0 R 2311 0 R 2312 0 R 2313 0 R 2314 0 R 2315 0 R 2316 0 R 2317 0 R 2318 0 R 2319 0 R 2320 0 R 2321 0 R 2322 0 R 2323 0 R 2324 0 R 2325 0 R 2326 0 R 2327 0 R ] >> endobj 2278 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 678.986 285.108 687.833] /A << /S /GoTo /D (subsubsection.A.12.3.5) >> >> endobj 2284 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 655.146 266.357 666.025] /A << /S /GoTo /D (appendix.B) >> >> endobj 2285 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 645.113 158.184 653.96] /A << /S /GoTo /D (section.B.1) >> >> endobj 2286 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 633.158 156.53 642.005] /A << /S /GoTo /D (section.B.2) >> >> endobj 2287 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 621.203 156.53 630.05] /A << /S /GoTo /D (section.B.3) >> >> endobj 2288 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 609.248 157.636 618.095] /A << /S /GoTo /D (section.B.4) >> >> endobj 2289 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 595.235 173.128 606.139] /A << /S /GoTo /D (section.B.5) >> >> endobj 2290 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 583.28 224.803 594.184] /A << /S /GoTo /D (section.B.6) >> >> endobj 2291 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 573.382 200.385 582.229] /A << /S /GoTo /D (subsection.B.6.1) >> >> endobj 2292 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 559.37 204.45 570.274] /A << /S /GoTo /D (subsection.B.6.2) >> >> endobj 2293 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 547.415 234.766 558.319] /A << /S /GoTo /D (section.B.7) >> >> endobj 2294 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 535.46 204.45 546.364] /A << /S /GoTo /D (subsection.B.7.1) >> >> endobj 2295 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 523.504 234.766 534.408] /A << /S /GoTo /D (section.B.8) >> >> endobj 2296 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 511.549 204.45 522.453] /A << /S /GoTo /D (subsection.B.8.1) >> >> endobj 2297 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 499.594 234.766 510.498] /A << /S /GoTo /D (section.B.9) >> >> endobj 2298 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 487.639 204.45 498.543] /A << /S /GoTo /D (subsection.B.9.1) >> >> endobj 2299 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 475.684 234.766 486.588] /A << /S /GoTo /D (section.B.10) >> >> endobj 2300 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 463.729 202.239 474.633] /A << /S /GoTo /D (subsection.B.10.1) >> >> endobj 2301 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 441.945 331.682 452.824] /A << /S /GoTo /D (appendix.C) >> >> endobj 2302 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 431.913 180.889 440.76] /A << /S /GoTo /D (section.C.1) >> >> endobj 2303 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 417.9 195.822 428.804] /A << /S /GoTo /D (section.C.2) >> >> endobj 2304 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 405.945 223.399 416.849] /A << /S /GoTo /D (subsection.C.2.1) >> >> endobj 2305 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 393.99 309.924 404.894] /A << /S /GoTo /D (subsubsection.C.2.1.1) >> >> endobj 2306 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 382.035 301.396 392.939] /A << /S /GoTo /D (subsubsection.C.2.1.2) >> >> endobj 2307 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 370.08 297.67 380.984] /A << /S /GoTo /D (subsubsection.C.2.1.3) >> >> endobj 2308 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 358.125 289.86 369.029] /A << /S /GoTo /D (subsubsection.C.2.1.4) >> >> endobj 2309 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 346.169 283.484 357.073] /A << /S /GoTo /D (subsubsection.C.2.1.5) >> >> endobj 2310 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 336.272 254.013 345.118] /A << /S /GoTo /D (section.C.3) >> >> endobj 2311 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 322.976 299.871 333.163] /A << /S /GoTo /D (section.C.4) >> >> endobj 2312 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 300.476 240.993 311.355] /A << /S /GoTo /D (appendix.D) >> >> endobj 2313 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 290.443 197.905 299.29] /A << /S /GoTo /D (section.D.1) >> >> endobj 2314 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 278.488 185.172 287.335] /A << /S /GoTo /D (section.D.2) >> >> endobj 2315 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 266.533 225.72 275.38] /A << /S /GoTo /D (section.D.3) >> >> endobj 2316 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 252.521 287.638 263.425] /A << /S /GoTo /D (subsection.D.3.1) >> >> endobj 2317 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 242.623 254.901 251.469] /A << /S /GoTo /D (subsection.D.3.2) >> >> endobj 2318 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 230.668 231.937 239.514] /A << /S /GoTo /D (section.D.4) >> >> endobj 2319 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 218.712 272.484 227.559] /A << /S /GoTo /D (section.D.5) >> >> endobj 2320 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 204.7 287.638 215.604] /A << /S /GoTo /D (subsection.D.5.1) >> >> endobj 2321 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.862 194.802 254.901 203.649] /A << /S /GoTo /D (subsection.D.5.2) >> >> endobj 2322 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 182.847 233.869 191.694] /A << /S /GoTo /D (section.D.6) >> >> endobj 2323 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 159.006 194.517 169.885] /A << /S /GoTo /D (appendix.E) >> >> endobj 2324 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 146.917 373.086 157.821] /A << /S /GoTo /D (section.E.1) >> >> endobj 2325 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 125.133 207.877 136.012] /A << /S /GoTo /D (appendix.F) >> >> endobj 2326 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 113.044 203.563 123.948] /A << /S /GoTo /D (section.F.1) >> >> endobj 2327 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [103.948 101.089 206.891 111.992] /A << /S /GoTo /D (section.F.2) >> >> endobj 2331 0 obj << /D [2329 0 R /XYZ 89 721 null] >> endobj 2328 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2336 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ]½Â0 „w?ۤ—6?dZCÂb*‚©B¼ÿBˆ2 ÊÃÙçÓwÄ ÄA¶*Í’I¡ Ð'¹1túÀmµ;Úz]ßõÔ ¾ý‹:Ûv1ƒJÒò—VôR{›Â"Yãi˜k¦Y>bbùU)V Ë‘ªf³9Î-öo¹äYò¿m@+> endstream endobj 2335 0 obj << /Type /Page /Contents 2336 0 R /Resources 2334 0 R /MediaBox [0 0 612 792] /Parent 2168 0 R >> endobj 2332 0 obj << /Type /XObject /Subtype /Image /Width 600 /Height 900 /BitsPerComponent 8 /Length 74686 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿá+ExifII* †Œ¤¬1 ´(2Ài‡ÔòCanonCanon EOS 400D DIGITAL``Picasa 3.02008:09:28 11:06:33š‚6‚>"ˆ'ˆ@0221FZ‘’ n’v’ ~’ ’ ’†|’ ކ’š 0100 ÿÿ „ X Ô¢¢¢ª¢¤¤¤¤ ¤!²}- 2008:09:28 11:06:332008:09:28 11:06:33>÷Wþÿÿÿ5.dl"t ¸ Ø  ø } ·  P 6€ h  ƒ“p •@’ –Ò —â ˜â  ê ª´Ðà@2@j @p@ v@ü–\ÿÿÿÿƒF€@ÿÿÿÿÿÿÿÿÿÿÿÿÿ5‹]dD 4Œàìÿ™ìÿg1ˆà^üÿÿCanon EOS 400D DIGITALFirmware 1.0.4unknown( 0 ° NNÕý;]ü³Õý;øúþúþþ/ÿÿ Ÿp":ýPÿÿÿÿtH0012004€P† àÄ"l> 4c6 Xt3t æc¼NN³†feÿÿ”Œ‘€|(Í++ˆµ·h³²?½³ò43õ´²’ÿþ¹o––º { ƒçç¬ ¥æç–` XÞPÙ ÜX Ppo––º € 6--¢¹XÞFJ 3Vÿ33œÿ33œÿ33œM¦xþcð”*‹þmÕ'¾þ„‘l õþ KX6ÿÂpVÿÖâà|ÿëºP³ÿ…\ôÿ<Mh6oØsŸê¬ ¹Ú¶€ ë •¸ &Dqð ©â.` ô%ÿÿ3d.Z6a#€çÎ ²8__ÿÔÿÜ© +1·$^–ÿY&!§ÿKð ÿcÛ ßÿTRÔÈk¸kÈkŸÿe±ÿÄ6løTýÌk\œ‡‰2ÿÿαঃaII*r€S;m'F2bc3ea24510068c64be8724119dff051R980100@H(PÀHHÿØÿàJFIFÿÛC  !"$"$ÿÛCÿÀ p"ÿÄÿÄA!1A"Qaq‘2¡#Bb±Á3‚Ñ4Rcrñ$%Cs²áðÿÄÿÄ1!ÿÚ ?Ê´{R©]‡ yãž‹mÅU–$*¹ÆÐ¥:~øèÛ„PiÿÜ?ÓY¢,ðížUð‘¶à’AÎ>š‘%¸ÉH1… ò³‘BÔTlÏoNZˆñ´ÚyZž%ðÈf‘\—`sÛê>ÚÕóAAÅøÔ(®/¸à~š…wf«%sõ×¹vû郱s>ºþ¢Ê .·#Em :£¨’ÓvZ˜ÕÞ† •cb ä@îѾœöÖ¨pžf§žÝ-㣫DûX`B:üÇc©B™d…7 üu"îG¸UÐu눭æÕ~4q™<4”2—êc#(~9j=h3A4 ‘¼c8Õ™Jçž§X–æ2¤yOôÔ>  4t¨=òRÅo:¡þ";úêæ*EÓTÑß)*f‰3/†®»óË`Ü9‘œý4ï$qþð0äA=}{¹-B—Ž&ŒÈ6¦O2½ÏöÔ›0ëÔq{ë.#*EÇæ8þçT~[­sÔ¸Ê?1• 'Óä4dáZ8£Š¢ãO¾B ,ê’†3B”ðÅþ)ñÌ–õûòfÔþòÓ?ÅÊ„Žì1ŸÔêZ<ðgY+¯3‹½‹LQLlc/¨æX9“ÈsÔ6à~’ÿSS¾¶ª9ªI‰d`¾'¾?7^ú>¸4v¾‚Žž`%¨—tÄF@'üÃ:§¹ûµ¦ÛG,•qûÍDœâ–ÃÐ’y‚>ºšjxgê}µU[— 70etƹZø?‹`­š®¢Ï_%²R®³¥;4dz‚¦‰¥âJu 5<Íß÷ŒNˆxŠÞ©)éêØIÚ²{Ñð×àÊq‘žÙÓh¸OE`¬²¹lÕPžX'^­_Å‘»Ÿ>y|ù )ls;Å$˜6«1ï¼MÔÞª`¶ZžÝP›bñ° HF97öôë©A„æií³Å¬uIT0@p{]Àê,œ#MáP×"G!*áA'Ÿ.üûêÆjºSxž‘©Uˆ‘br %AÃdv%‡ÛV“’zhá Ÿ†²¯\„g´²§ü©:}Q¥ýÒ •¾½©®ËÙù÷yA'—˜tÓ÷ÀÝŽ_=(= Ô)§¸ÔɈ*ôÁ;F¬¢žÉìºK„®¶ã²Îâ"ß?ƒõѼ<5ìÚßj¨°Ü,mUY:í÷áTþñMŸâöçáŽ}ô©°q=êÁºÝoŸN„ q¸Â{•Õov£¨zÊJ©ewbÎ’y·Ôêà9¿{)ºÓYª®vZè/VÚd,æ"EBGަ3éßéS5+"ŸÍåê ãgp§´[ZˆéU$ ÑËç!NF#몾.â*‹­¾ã$ÖûzTÖ"{ÅDP”y6Ç,àtÆ3&…ügV?îN5<Žª}u6šN\ûëBëŠVI®Õ@…FbÝrIõùhy²ÇâtIwoŽH¡l±òžçùê‚8ÛÅ”€9sõ ±ÔÇMnhf%K¶rO—á¢þºP¬B’ª¢›k:„ñdSŸÍϧ,èÆèÑ@fldªÊ‰IpªFÕ?}=ÒÕ_n¹S²[+©êà„«ÌÐÈ àtÉÕ…¾ù©aæ‘ð¿!ÔýÈÒÏðßi¨k½}T DñÂW%Ù9’>[€ôÓožJÁÒ’%]°Æ 9 =OO‰ùë{–-°»íÆŸÓJŽ"¡ŽN¼< n¤¯ÌGêš—JY×(f–w(@ 6dýô®ö€Íiàû…S*Ó;bž5' —88"yöÒñ‡ÿKycXÊŽ]õui·ûüè«$!;ï|gûêµ*R8ycL÷sƒ¯È.6ø&Yd«Wu9c/ÿÖ¶-8ª‡Ü.?àÅJªê±œ¨ì^]QÖm’ŽÕ#újÿˆ/VûÔ4´öÚZÉjÕˆÜc qÐNNuEUo¹ÙÝX…‡,ÄuòóÛR‡æ§^)mÒ+2¬ŠØ8<´QEHëªÞ¦–Iê‘¥ÍI ´d·ÓT\x:#’Ižž3†!¤~øøèãEQEph¥’:˜ÆÖi!mÈÙ3ëÛŸvšºí8š¶±ª_ùùùj ,þú”¹äç 9í¨'ûœTt†ª²xýÞO)xT–¾3ýô#÷ªÐ7*x’~fäOS¢N>šH’’‡nÌ)g§þß×P8"†:Ë©2®ä‰ mÆrsª5±JZÁß­f3Šp¥d çeÜ2:à0)¬âUVFer3““ŸôÒcÙå|ôvúªJX·=3ЍÑ<½~À~ºup•Ð×P£dÚ@ÛèÃuÎŽu6šÝé æKnè=zi#ø¨·KIÃÙ\.MhRÈÙÏ”žmhÉ|C7†œØŒ»z|4üWÄÓp„oÌ«ááÎáõÓŸF]a±Ê‘Ï×^ý5꥖Z–e<µùÜk¨•G<ÐÊ’G#,ˆÁŽÄtÖ–ha»ð¸xh¾÷nñ¹rÁ)“®³,]´oWG'²JAS²Þñ0=r»—¦³Ð¥áúxx~k„’«Ê(št| íÈù÷úê¯Ù•,Vú’Lûı†—˜f9'> rúêmDõÐðu¼MRv¢FoŽ:ô×N§Rªm%”`ý5¼š¾MÇã·–¥X+V·¿Õ•(r~Ú1“‡©¤MÒCž_”ãï¯Tœ'lM<0ºJ«¿vì©újè]ñ Úæšuu Ça ÑéŒêÇ…m“RÕšz™Ypʹò=7IQ°Ilsl 9»ŽÛ ¶‰b¥¥†0Üü±àäütÑYÃüE]e›Èp‚âH²Xzi÷ÁôT­h¡’ËxL–;@bH ¿^ýô±·ÿ³–p¸\©Zz–摇̮}y*ütåàù¿hÙèj…7»™éÑü s°Èg¾±Eœ ±+ÌÛŠF99,Þ¿MgïÅ…tkÃ6ërÈÕ3šÇ\ó …þ£ZêC"QÇüg™ô_ÿgYÏñsOOû>×\«¶ygxWãÓîtçÑž¢P^ˆæ9ëõFëîÃ]G¤?—Gv>$ºPû7ž†ŠÞjâJÆYß¼(Üè:dƒÏ¶æM1}‡Õl¼ÜhNÓïÁ€=Ê·?ÐêQiÔ]¸gÆ·HñÔ¿¾fUÎÎÿÓ¾¢Þ¸º†–Õ²ŽâÏ&Á¶8HbN?ˆã—ß\8ÒĶkŒUÖõ0«9`@äéñ­e.þ''jà}† '–é:±ñG!ü¸Î§[ï‹ 1Êvíç´ b~±Îe_Lç] TEêßAñÐÓÜªŠªRœå‚–A¿=ZßxŠDDÕzgò|HþÚ_CPÐÊ%¤eWã#Ÿ]WNõ³Hd$“–Ü3“óÓu$Æãt‚97Ìf™ðrÌ €5®­¶ól§>cUƒÀ°Ë–³_á†Å5ûŽÞªÔVUYÉ“ÎN#_êßåÖ°H0š`6¯åP9¦±Ð ¬‰¢GfÿÀQð-þƒY¯ñ‘WßlXÏû½<• =7«ÿÄëD^.ªn1A?†1i Bp]W©¾23óÖiüEYkŸÚ›^+¶T[ê)Q0zÆ€`c¿\žZsèIôCò×èEùjÖùcª¶ ›z7J…^_";j®/ð×宣à3öѳªÏrã;l…°¯!‰» 0#úãCÑÓRmÓ5=Æ–¡zÅ2?؃ xq54uÖùiò¥5ï†õÒžñV”3=;î§ ´ò]{Aâø…SÛmó¡ú³§›¯`t>m¼#VŠßí-D.P—SçÍè5˜,R*‚Fò®yóo–º‡Â¡0B¹ÏÏSgEùö—ÏU^Ÿé®bö‘Û›© h JiØîxÌg±^`ý¹L¬±‘ ‘Ȥ)8?mI¨¤\´ŠÙÇmCzZЇޖ•ƒÍ;¬Q(Ë1Àþº Qø^²þÍöoKXðˆå¹ÌõrrÇ,ìOÑsõÓn±öÂÇ éœê¯„mQÙønÙn…AŽŽ™)ÆßTPê¢qísÃc®Äx‘ÓHãç´ã?\kûFLãOh· lRñ/‰;RÐÔ5=49òŠu;JÓ-ÌüÈÓKÚ”TÚ ‘HTcŸ<ëRè« yäã_8ÀÈ9Õ½¾ßîÞõTЩRU¶g'Pg‚hØpÏ#Žº¡°”ø_#3rçæ×h£-ÝdÍuñÑT3~_@qË_°ÍNùfñó#iÔë;ÓíónˆÆqÓ禟° ·×U?]hÍA¥›Â¡]£h”ZLrÉ\Œ|I=´°;p ‘ˆôП‡?‹Å•DSÔÍ1 m°9üµ/olj$”ÄÛ‹bTÃúhÛPÚ(¤µ£«4¨Þ'Nùéx¨¥ŽÜõ!OO-$Ò"F±(wåÖ0âž*§½qtŸ´æ¸Å Ï4ÓGƒ$@œ?íëßYæh¸C ï*àXàçF‡ª*h5ÊÉ„×Òø4ÎäÎ6˜>`hx˜ää°¦H݃Ÿ§M}n—ömòßz†5y¨ª#@ÈÞÉN~£:è:ñœÃümWE€<7’"`WŸ~GNÃgµÞág—â ±·×Ér–¡”ßz{tút¦c4ƒ€q׫Ç^Ô ½)T¦€.D…dTž\’–)ã¥YŽ@i^4‘xÛÆ1RF´†\Õ AÆ '§ò  ì¥{~5$jUs´äÓØ³ÇJT”•Á\@ÏB)Àð)8ZRÌ9Û@fœ"ïgŠ›yv9Tˆ…GJ­ä8$î4ß.Pw<ÕæN¼ŒÇÁ>Ô\Û3§Öž¶Ì£99éŒÓÄŒ8Ú:Sƒ¸?tt äõ8ö§FsNW|´S‹°å  ë”>p9ç½<”†ýâ{u¦ÌþdÙim­ZY7ÉëÀ44 î£ Ö¬$ Ç«QGÿÖ¥QÁõ UsŽiûp)ì¡FE0Ÿ^Q@H×4¹òO5 ¾£Þ[œþoÏÇÒ¬„ç< §æcüñJ$ÝÎ(è—Þž³zsTCsÔô§ 1í@ ?^sN7=0k8KŒúR}úЪ]tç½$×[†3Y‹>8íHò1Ò€$–R Üyôª’KÏZ|€¾0{ûÕ½+ÃÚŽ·r!³ˆ¹îÇ…_©  ¢û¨Ë{óÖ½nËàìB×}Þ¢ær2DjΜßô໎©0ã°•ÐH²dŸÆ”r=kcÅ,z¬ÖPLÓF!œsX Îi2ãÌïŒT’ŸÞàÕ;MšúÖîåÛjŠÌ|œqUî9”ãÒ€,Ù92~•¨­·§ÿª±,¤Û>Þõ®Ž3Ï_z{ÉÏJª•‡æ¤vûÄãÒ›!€‹íŽNÞ‡<Ö¥¬€ìÉè3×­eÏÎõ÷¤µ˜´á­0:ˆg]üŸ×­ZK×5…ýáç`Ÿ½Í 4$œÿ­gÜÈ¥N:ÒœóΫ ÎzzÐpWuéV—{õ¨K/÷‡ç@¤PWTXPÜõ÷«W?xqïPÉåõÜ´Ài+ŽœR^xý)æ5 sL1Œž´ÒT æ© ‚Àw«“(ñÔ÷¨Ò ªq@ »¯OjPÃiBg<IåJBÜ})*ãÕ# ÏTDšG— J…v°ÎÜÒ•©™eû¸  6sQ±ü½}i¥å7ð£,íóg4"IŽÕ ›·jˆ/µ=žÜPóÈéFîÜÓ•l@ôâ€#-åEHWŒQ@mÐñÞšH'Šsgšiî)€ :ö¡p):Šrñí@à£ã5r(ÁíÍQ†áaL‘ïS õÃÅ /ªb•PrëTVøÀâ¯@w}E&ÁíJŠ8÷©qóR¨ºPvyÇçK€rp(dçõ¥ØU±É  jD”©\œÓšõTãh¨ÙÚåÎjÅ ž}°NÁןl´sRPç#Ò,q‘¹"€D„ð3S†6ІÐffÊãήìÈ€+ ?Ù¥gÈaŽÕ0@I)ÅWãµcÉŸ ‰Ž”Ø`Úwž¦­¢@ DG þ”ð¸RXñ@]¹õ¨ä“p?Ý »äöRYpH㔳K€GåU³Á$ЖÏ'õ¨üÒxTnù=M(ñ ƒœ“RÎGZ‹ŽAÒäóé@‘Öø¨·29ÏZ9'Ûh$Ö¢Þ9¥\’MJ„u?•<°'ž•“À®ŸAÐ ÛngQŽª§§ÔСxaõ2&»s ¿oï5z^ˆ?³­ÖÞÖ×j¯b¯ÜÕ8í #ÌmÇÓÿ­]5µÌ…cŒF‡ø›µHV¶k.îøsü*qZ ý™l6C¸“·«K§Eû˙̬;gŠ»o⫈ŽFOM¢ñN!Œ¦*¥ (%Xt®$×qñKTþÓñkË·nÄ ï\0äÕ /Z_Ïf“G•Y€z®Ï¹Ï<úÓ"˜/©’©ŽR:‘ÔÐMàÏ \x«Y’ÂÖâ8$HZPÏБڡº‚{;ÉmnP¤ð±G_B+Oá…İøÂ&„Æ6Q]§Žöù^õ$(Žž´b å‰ÝšCŽsQ@ß&EL­ÈÇò¤†óT®™„wqWrqÅRºÁ¹Á¹  ¤çq/MT,ŒÊx÷«R“Ç›RéL ÷ã«ÓJŽ9&­MÈæ¢x°ýóš°À„PjBœ TŒ¹+éJÜdÐyAò×>¼Ó±K'ú±ÏzR&€E,‹,p3Ú¬/ݪWÃ*;Ð=Òâý)†åuª ‘œÒgŽGJ¸g— 3|¼}ê5ÇP8 c:P¼÷(WŠQ!b âš@ê;Ò'|fQÆ)Âà ñU íúÒ þsí@•42ù¤ŒcµœsW,—.qÖ€/Æ}h§ŽÔP8ÔÒãNojg¯·j`*Ž=iݺS@ gFiÃæóž´&Úã£t§+qÒ ÁêkrÓˆW§JÄOjݳæ=r(\~4 ~4â;bœ<šjŽ˜ žž£’1FúËl‹³Æ5‹œ¶3Žâ:1°Øö©mÉErßÊ€ÏÙ]ÀÔ æ ùsZ1¶áÊñš‚é~ö€ l‰˜t«„`U+!‰›-ž*ù+Ž¢€£×Šs‘¾”€¨x}M+:í8uéÇ4€…îÅ= ëMNb§ÆØSŸÎ˜ )ÆwëUep±ŸOz‘Ÿ<žµBy dg¥1Ÿq$úÔ,û¥#·¢^§šq4ð{S{Ò©ä@÷ö§–À4À gmcòÀcÔP.6•ã¸Ô× —ëUxç 1þ•&zQ¯éW¬-IJîa•ó  OREÄã÷Tô®¶݃‘ιñsI€AaÚ {×—ŒœR«Mrsˆ€-êy¡üCu8ÆòµÊÂáXž¹«*äàŒâ€:‹k‰&_žBMnéåcÁbKW/a.Äκ->_0ŽsH2ñÃñ-Ï9äW4 5¿ã6ω®øþ.Esãš &ˆàã4HŤbzÒیȸõéLsûæ Ãá¬f_ÛÆ¤Œ£tâ½Î{Pceœ³Œc–¯øX ñåšõÈqúW¼jÊ0襃cµKÜñ–…¬ÿm·L+H?­r€Óרëq¥Í¬°Éœí9â¼ÈÅåJÑòv Ó@4 ¤qR&Kc"£þ>:TW’4pîSÎ{Sý¿ÝÚN5ay¬˜ì¯$Eq/^qR‹+ÕçÌÅ 4±Y×d‹¬ŠŽxo!‰œñÖªC;Í!Þr}éyIqŸá§‚ãˆAÁÀ.2sœÒ›˜Ò –o˜Óмãb¨Ü.0O]ÃÀ¶Ü•úu¥lóÓ¥)*íJ{š¯/£Þ•ÇqK(á{sëJÙæ€£åöªW¿ÂM_ÛÛ­P¿09  é8¦1;1íÒ¥aùTax絯LÒÇšp=é@Æ3É Á i Çî¹#­!ô ɤŸ|ÒŽ3Å zxäÕË1ɪŠ? ½f'ÛŠºÝz)Ø3EríÐqïLÏ×­HÞþ´Þ¹>”ÀD<{T£{TIß=*QӜЋ¸þt sÍ(?(ÏZ29&>µ¹eͺý+5¹§ódŽqÏ4à9â†=éËØÒ^I₤>iÊ0Ǥeí@f=÷ÍíÎ*ÒFY¹Å@ìc½-Û~' 2=;Sòˆ5^d'#njéa“Ïz¯#…RÇŒRë1Ê¡Y‡5z.iQ[Îl{Õ+Ï™ÑñÁnµÓZ‘öÏ~)”tiAÿ^Fjõ¤–Erçšê¹a»¯¿JÈñÌqŸJŠÙƒCÖ¥è1žµ Šâ½jcøqÚ€!•¶‚zb¨y5z肼U78ŒžœPFl±š84g9ã­!hÄóK’•3©#˜  ‡YNNÞj­þ¢o.9²–PôØ(’ÎòœÏ´lÄFj~ 5Dmˆ®iã®hkŽæªNtiòN¸êj³H$R3@Žx&”ýhÛß9¤4«ó*ÚŒ {UX‡ÍžÕhcûÐ×½K»1ó×½Ažµ 9€*¾y˜£-Ž˜ïRH0ÿ¥"à{PäoÀÉ×h ü(Γ@'ny5"SQ†ÈÍ<8Œô  ±žiËŒš„¾zž´ªüué@‡AŒŠQ‘‘“ŒUe|ŒçRÎGlPeÉ>{e‡Z„´óÞŸ9Ì­îj p:ô  ‘ÁØnõl9­4ühÉ~$Ë4¬…}ïY»¹c@í˜ •½5²Å ʨ¬(O9‚jÿ›ž Nχ w¤W9ÎÓU]ÉcŽ1MIäø  %¸Ç *^‘Ž:Öh–MÙÍ[Ó]àÏJ´tˆ6Ž^ÔŸÙ0gŒÖ“Úš9ç½ 3¿²¡ü½FmÖ+ƒÀ¥j÷¬é‰ûq˜Œ2Àèh0éëò1$1ϧCg4ÔQáG9ªR¾û =®ïTS–ÕP²×ó@ >qè ÷M+}ñJ{ŽÔ€‚@”;fƒšYzÅõ óš0vŠÌ¿'+ëZƒç­fjºâ˜ìîi¤`c"žëŽÿ3œúPŽyÍÀ¥¨ G­7”m#éKž¼REåíQç ãš“9Sšw?v€NFzÕÓþéÏ­f¯'>•©§ð§Ô¼ý4R·4P(OSßÞ“¶1õ¥#$äñšTç4Ð284äû¸Æi S“J”éCd­(ëȧ½¨#ã­niYû:ÿb¦+oHæÝy  ǨïJó¡úôçÖ”=é«÷ø?…8ýìúÒ&C“ŠéŠÎ¹éXÇZy€à.xïM¸e[ϘÕÄåwv¦>Sg¤hp žTÕÀyàSeQ´ŸÂ¶ê#¼`:c§ÐûÖz _dzt­ä¥‘C6TóF0)Ž3žÜPÆ ¬r)žJž„T’G™[§Z`‡ùÓ)ãuÕb»A9ïVgN@ÏY·*O€q£ÛÒšç”°éœP‘~Z°¤zÕ5“o¡Ïj±oJ•q¸ÔŠpÜ „O"ž¼ÐS›¯éIÐ;Q#€D¯¸óÅ,re˜qOÈ䚦\¬ÌGéR¹d]ÃÓ¥Y,ÎiªsȬ朰ä÷¦ïlphSÏr ¤ûLa±‘PEdÅ|ɘªÿw¹­R]Æè"E$-´©  Áx<þ"›öð1ŽõM+[´™ÏLç( mx[ZOßé¶áˆûÑü‡ô¥p<1ÛsdÓ:g5ë:¿Â(åC.…{óùcpx?FÖ¼ÛVÑ5so¨ÚKnùà²ðßCÐÓ¸‚+¥‡eqlÄ„8à‘Ö³8 ÍtözÄ_ðŒ6™" Ë’§ês\·r?•L„cÆzæ 7O¿ƒùÔãî6*›FÙäq@ý©÷ç<ÕÛIÃŒ0ÝŠÊÛ†Î1Ÿj½§`JÝE04‹Œ‚5cOéyÛŽ*8 ­ØsuŒpE 4Ï"›ž:ô¡øâ€:RAÏ~jƒº­ùÉxÖ³.ãèç¥h. öê`Y#çü)Z†ûã>”7Ò)~ôc®hnàPü¼t­Îh^±¬»óóŽqÅj®6ÖF£ÌàJ`ScMùãÖ—qäiNhs‚=ûSGZ~H†…†Hí@ ¿J^sž)Ùǯ¥DO\ç4ªùîh¹ 6ò¥ò£Ü~l ‚\ù¤ƒL†ÁoÊ€ Û3ÍJ$ÎUª)?ÖiXüÄ÷í@2áÀëÀ­K[/³ –QûΠá©´»5`·RŽOÝõ5-Ëò}(‰27}VF îÈü(2néëÅ"Oã@6×»(8'­v¾¿`@víë^u Žk¨Ñîš"3ŒHaÑe30Á·uOÙêšq³ÔmÒâÙùÇÔƸ/ê&0¹nüW©iIyf°Ç,ñŸÂëÝ%¾ÑL—–8ËÄFeˆ~x~µåã$“ùæ¾ÒšÓd•ä¾<ø]mqyý«§lY¿ÒP—ýà=}E4ÀðøÑˆ>ƒ¹§ý†áØ……ÛýÑ»ùW¨ZxkHµ_3qœàî¥^ƒ^†ÊCo§ÚB±¡ä쟯zwÌ-¼-­^°é—LOOÝуÀÞ"ˆdé7 }Ó“]ýÇŠ¯D¯ºìœÿ ñPÇ­Ýܰg¸b¹è­Š.žÜé—¶N{y#aÙ”ƒM°Êݸ¯bµÔ­î!6÷Ö‘Owuþu^ûÀ7¸¼Ò!#˜\d~‹ç,r}© äŠÐÔôË:项€ SŒâ¨•ÚØühÏ—pܲçƒZyɬ›µo´¶=é*GÎ{TÁ‚ÂÁ@#Ò«ZÂÌ…™‰ç5(içƒÏ4T`®2; …¤¼p9¤–#${Õˆ5Vqs$ž{ÐÓ¿§îœô ŒÉŒÒ°ùO4€ŽLï§½#ýôâ”ã&€8㨓çLVÇðÖ=ÿúáϦ.¤äb—Z=+RtUq’2knHd¸k™¦Nk–—/!ÉÍGÁ¼ÔÑ.[Ž´F•,`(ãš°°ºØâµtâTŒŒ”ËUTr?Z’gû%ÖÑ÷O$ûP_¤Ï…ËǯJÙ_ˆ1é„AjÛˆûÏØ}+Êï|C;#[Z}÷ë:1pÄï}¹=úÒ°ÿ'Å)tY|Ĺ{ì~íqÇ×=«ÌuOxƒ]ŸeÅãEn#Œã9õ=ë™W’8÷4«Ï§­B— '_¼:§ºÖfKí˜ýÞx5—ý¡#9?¦h¸+ua¤â_ºqíTÞDbÇ•ö¦ŠÊ’Ž­ê¼æ´¬fù†ÉÆ;ëb™X4lÌ3ZÝ2æÆ÷ñÖ€:Û+™"Äœudæ»-PY20¾Þ+‚ÓnÑ‚°ÁÇR:Šë´´¶»uhØÇ(èëÇàj@êõo [xŽÈüÁ.ù[šñýo@»ÒîÞ ×?Që^ߦ´ÖØI±ì㡪~+Ò£ÕlÐ(º„nŽH¤˜Œ{VDìë’+¨¿µ‘'“z#¨¹§ˆ½óÓÚ­"“{W=jp<“ØÔÏ‚­gp®SÊnô  £ÝåÌ<Ô;·^D; •¦#e'=ê9%äCf€4ˆýå9†¦ççïJÇå"?úäúS‰È4×ÿZzPÝðzPÇÝãò¬]@ÿ¤~´8ZÄ¿æç0)U·cŽ”€ã©4öéõ¦œ úÐÇZAÀ4ÄcíŠ7õ 0j5å;#Óß8àûP³Îi?Ö’‘IúP—®sZ¶\Ä?OjÉQƒü«^È~íGµ\aÒŠW( _oÍøÒ±àãšN½=hlþTQÖœ£ñ¥+õ¤N8  þ´óÀÏaM^´¥°ã¸ .;V¦—÷=³YJÜ ÔÒðzÔaÆHé@?/"‚x¦ž‡Í  Þ;Ò¹éš~þiÏÉëÞ€*Ì3t™éŠŠéãÎÒ@ç¥IpÁnQ»wª÷AKgnIéL ”°ÏLRA* 6r{SRg>ÕmóF‚4nUÿI‰‡¥^f³º¾ÑZð>”ïZiÆÓ“F@<Òg9×-¶cÚ£F9©.Ffüj%N˜ ¸l€j¦Ø+ëVn98ª§;yç¦q@ ÇJQžzñÚš#ÔRçÇJ:0¥L¾‡š€õ8©Tô ³`7j„œ?^}êSüF«±Á4#ýjŒö§ëøTyæ˜'&ºÿþ£$‹’±(\ûšãA÷ú×qརÇXsÙP þ4˜Iy#¼Öñp§9¬6]®AàÖÒ)k™5™sÙÙ{Ž(0¤óÛùÔÈ0:qšj¡Á©Óõì(ð±F8>¢™ª]—U~ñà°©£M쌊£pªeþT=œQiöfiyº‘~E?¾¸õ5Ÿæ¹¶H9æ“íS]ßJ뻎¥^†Áq’Ç>€+ˆÚR ž=qVì"Q*yƒ÷lv“Ž@â€:K­!"x§O•_†p½gKC)Io?.Gºu½´ó" $ÈËü'ÿ×U¢¸s’¿~3ÇNãÞö¶¬íæ@Lr/]ÁJé4Z;K·É%º“…ŸëŠÎS[9ØH‡; ûÃÛ×é]&•-® ¿g¸Ž4˜¾8ö @Ó®ÖKXþd•|®½ü .£0Ø®œH¿¨®FeÐ5¶ñoÞ¿ˆÿ ¿ý¬—ªXé•íøTÇx¾Ôyßhî?85çÃ_LǪðzî­¦B„ÈH.¯´õö¯`aÔ®Æ$¤[ÈÏ;–Ç Å8ùhó)„r “ÔãûQ9séL .üÐP㉟uÍ¿9üéÅÃKž6⢑·^ÅÏl Òç9ô§1¨”üÆœüýiÆ?¾Sߤòy¦³9qéFy=9¦ üœ“X×¹3’{úÖ¸8LÖ5ë¤míߊ®äøÓw +cÎë@ SÎ9$šp\õ?¥(íH§Žœž((X’3ùÓãQ‘H5Vk³(¼P$òßé@Bòpq'ßš„ßA)%íÆ§I aƒHsëOs9¨ÉH @ÇÝ[­iÙ F¸®kyG ¼`úWA¦\‰~u|öͯӢ€9“ÆiHÏn´Âr9çšw'‘ŸÆ€Ó?JqÓõ¤cƒÓ§J@Æ€'O®iÓŽ(N=(*hBqëŸz×ÒNP×5’ªAåMji`ª¶}h\ŸçLcÇÿ^—9äŽiðNáÞ•>µ'péÒœÇ#>ôNû–^ >‚y¨+ÓÚ ¼b$ÎOˆf¸‘*ð{“L Øè “ïM1ˆÁ8%ª ×GøG×’éT–PGZdM›ÐœwÍkƒÆ9ëXVò—œ3psZ“Ü-¬IéÀõ4oË%7eP«ÄÄ‚às\”Ú¬ÒHÎ\ŒúT *îùÏ­²’ÊÚUÊJ<ÁïÖ³ÚÞD~„jÀ‹R™0<ûšž-jë'snÏj·uÇQÏ¥Ss…íZl´¾P÷rލŸu-ÇÙብýУ9  Yã‘ÒŽçÖ¶äðˆ¢'~wÿ|V]͕Ռ¾]Õ¼°¿¤ˆTÐ9É4å”$ùd‘ŽœÖ^²áeòñŒq~õ|°R éßéXz„¦iËÔ“‘@ô¨8,q–µ›¤N«Nv0$Õ–e•ÚB~ñí@ mž2Gzšé¾Í$ ¨e˜`ƒúˆ&F}1Š»¨ÇæZÅ.rcèE 2Þ=ºq$sßš¢w˜°z•¥r­ýž9$ V`,yÎ{j`tžÔ<¨Õ&æ Å\g§¯åZZ¤er“¸16>÷¿ã\]­Ù†i:ž„zW h’C¬iMg'ÎÀ|„õã›å õQÆô5zM‘ wð@sÒ}å>þ•”Ñ\i7oÆJœ ¸ûÃüjüRC:ŽñçŒv ïMÕmîm>ÏpË*ñ‡<Ö}í‡Ù®æÒO½÷— oþ¿½söö^`ó,¦ˆN¼c${õ«WLÖæfkmB ß?)4€½c}$Ϊ·~0A®ÄúU«$÷–qyr³«(,A(s‘·¾=kµ¸0YÃ5ú¹Xx߯p{÷“ûZísXˆ$峟jv°H‚G>ô¾B…Æ>¹­ÚyÜÑ[‘ +#È›?ë>•@FÐ> ‚sÚ©@]õ‡ËW.cš(Ko$ŠÎ²b÷€ž§Ú€7W–öÅ9úæ}ïþ½Ò€#'2¯=©Äõâ˜rfô¥9Éâ€$È Û8¬kÂ<ò}«cLqYJLÄŸLPRÜgÓµ4‚{T¥nþ´…¯JnN9­: wÓ<ô !ë·õ¦Ëû»˜Ž¤æ€2¥›œóO„<ž* ¸äæ§ØL 5´”‘9 †µOµ1nB ç©ëTít¦vÉÉ_ZØOhPy<ñÐÒ úÖ8ÆåàúS4–ÛxTq‘Úµ/mXÊ ;±ÏÖ²ôøÚ;õRo9âŠFàsÇP<â%$1lƒFø†GÌj<Æçœõ¨q†úúPßÝœ}ìÆD€6Òrjp T°ósÎÚrqÒ¶¡³£ƒXŠ~oå] ÞPÁãß°GÇ'¥>a p vçêM2IŒJ]ŽXcÁ¦±ùjœ7É+€Ï€{Õ:´‘ÏJÀ>•Zöú;D›-ØRÞ\­´FFÆqÀ®Næw¸•SÜÐÕ¾±k=Ê‹Ô>Npvžk£´‡OšÕžÊãvÓÄoÖ¼óEIòÛ¶è¤#§CE€ï'Ýnû$”ý*»È&Rª¬IàqK£x†×S·~§ˆåÿ–w†«ê×˦Æmáei‰Ôç4$V0Äê÷3,X꣓Y~#ž#p‹o!x‚ƒô=ë"[™f|³“ŸzlÙdSÏJ«Ð:S¿ˆƒÒóøŠ~;dô¦Ž9ö¤朼79#S¸'ŽÔÌ•`}ëªðçˆL‚Cå‡eË æ]p£ŸÂ®é€y…Yr¬0Gjë¯>(ê—Š˜]¼z»¢øÒÓZc¦x‚Ò;ˆ%áKuSìzŠóy+œ3MŒ´o½[ 9R°‹<04[=›™,%ÿVXüȺkšóýk±ÐµV×ôk½&õp»¢nùÇÍC+ÆßyN(­Æy?J‰#=)çžýª&<úûÐI9ü)„`Ô„€Ýx¦qž š`¯­t~ˆ¶³$ÙÂÅ 6}ÈÀþuÎ/$õÍvþ¶0hòÜ‘ƒpáA?Ý_þ½&¹È·Ó¤?ÄçŠÇŒ`UíJPÒ,jrª¢îPö¤·OÒŸ·µ(RµW™r+ž¹ÎóÏ#ŠéŸ;qÆ=kPˆ¤¥»zКFé¦1ö"¯ÝÂöÃ&Vô¥ðÕ“k–{¦}*î­µ!geÝè(–RI³;·zÚ‰¾Ñ¥MRuÏë\Åò¸À­ë  _iÏÜPªl:ౌf9zc­oÆSJ„aKvª²Ú«+1ïÓ©—=™‰·/ÌŽ3ùÕk³h×â@›Ó8t'¨ÿtr ˜CÆî†ªIfï!xâ9Jކ˜± æ‘⨕0Iˆæ)ù÷¨ ðÖ¡o;oÙ$YùeF€÷¯8°³Ôuò╘ýÖN ÿZê´½sS±›ì—MªpŽGàzR°|~$ïû#HÃþZF9"Ÿ'…dxòVR}YNj}3Zšu ;;íOÐ×GòO"iÕIãñ¤{Þ™osÌ6w/œ„†çk/ñ¼q%Ó‰‚‡è+¡ñ}Ýó²[–_Ý—ùÛ‡sä+„Ñ5O³ê»du‘3þ¬ð¿•0#׿MN{†‰ˆvÊöãµc›ƒœÏõÝx†ÈÇgöèd”C'Ýwm¯?`e•ÆYy㊠½œµ¹R˜½QµAö´Å_`/*N=óLŠ( máòݳL Ÿyϵg;g=*Glð ÏúÞŸÃÖ”“ƒÍ6B|áLÑ‚A"€%å$›SÓ­ìäE_)Ë’?ˆÓ°ºÛ ÁõíEFø“k€0àíEbÜ ÈNyÍFFàjVÃ7šC´-Çá@yL±n`yõ¥¶'{  I+’23·)-ÆX‘Ó€7Ì~µ¯q •&±z1ëj!¶Ø78  þÐùÁQYÚŒí„Lÿõªf2•ZáY‘d>¼Š¬‡ Á«i!hFN9ªLçN%£Ø“Ò€#ÔïZæP£î¯žHÏJ ä÷¤9ÉÇZ`.y<ŒS[<ƒNäáIÓ8ë@ÈäqÍJ%g?9É÷¨Éçñ§F3Þ€$ÁÇN£­K(Ù óÉéѨ.ªK¨ËÛéÚ€3Èäà`R•Üu«CòŽ¢¦O™›îy  ñ#È$Èô¥K>­nÁ¦2ÇÙÁRǤŸ0¸Àš@V´°I,dšQß ÛVå+œò:VÛDÉ¢ƒ’k!€\§\P0 ŒŠEð+E ,ÁrÍÀ½jÛø6îéÆn­â :¸léœPVƒw%¦­nc?yÀ>ù­Úµ®³ !@o˜b­\ø]Єz“ÅÅ”n7Mnû‚óÁ#¨WÄ×òjZ${[Ž´ˆÄsšŽ)ävÅFÇž´ÀnN}*H­Œ¿6p¹æšlqÞµmÃMÃg#ï0^”=®ˆ’%i(ï]…îËXR ¬(êEsvér™ÙŸRÇîþ]ê µ£tX0t®áH ÝüÙ‹sÖž™En¡I64ŠÜÕÈæFư'ë@äÓAž)Ù$gÖ€!ŠÏxÍÈŒ;ÕÙä §8ªzŒV÷gÌ ü^†€:+m°B#^1L¿Q,`1QÇ:N7… ‡«!éøRÊA ÝžžÔ€­oe8UÅiEj§zu¼XuT š¦üÌjWÆÑµ@#¾y¨]ÿ}´ò«[2™súP<öÅ¥;FUºVmá¸ÓÜL\€F8èÕ}c Äž´—1ItЏPäõ  mW³ºÀ|¦b>uäî+°Õôè¯l-®Ê$÷1‹2òYzŒÿõëÏì­]B¨ýãÐV­§‹Îî8 “m²e žCjÞÒ/¦ŠNmc :ùˆ0+·ÓõG¸· l‰zÛÔú× m<· ¾G‡'’Œ0~™éVd×í.5³[7—ciòïÉc#÷Ï©4€Çø‡lÖò-úÎd™Ü{p­qöÖöw¾"IC£€îêx{Õßj“Ýê X³[j¼ÿ“MðµÍ……ÈmFØÜ‰A ŸSÖ˜¡k†¥aökx\[´j©œœz漯ĚúV¥*…Ì[¾FõêºF§™,jѪm؃€?Z‹^²‡UÓ.ÆŠÜ2A) <>OœÉÂ’1<õ§Þ·º‘e2EU c—^}ª€ºøÇ¥†ážÕQNH`zñÅ9˜Á&€,¡óžÝ) ŠsÀ5ž³•˜ª ×&¦7 Žæ€-ùàÙ¨ñTàñÏ¥UØOÍ»¿z’GFão4;É ‘ž3W|U«Kmck£ÚÈLI.zMg9[q™¤ ƒ÷W©ÿ §qªù³HÕXŒnnMQŠÂypYB)è\â¯,ÁƸ2Ð*ô>ÕQ§y%ÉÏ^icäu&˜y<Ÿ­*§Íþy©xëÜÒ¯SëHÎqÀ§(Ã…J½Á#­Jów§2lÖ˜½Çz“<Ðr´°€À)Í6{uÏj(¼¬»ÎFyÁ¨æ˜qúSÛ{šŽdd‘@ðò ⟠ÝŸJE!ã qÅ)\ôÐ ~c‚:õ­ëLv#8®}'úVͽÂ-ºn8ãs;=+>k¡"¼{sÖ›s¨6¯›ùûÐè†SŠŽõ•ÊCœu5riΉ7o•b³É?^h£>¢ŽýzP847Þâ˜Æã×ê(è=hxç¥. àuö !cÓŽ£Š‘F3Zzeµ¬’Ÿ¶1X‡aÞ¦Õôû[Fk&蛕Ï\P|gçã®1ZCæªÉŒÁü«>Ð?9íÞ¶àAe žO4€®¶3Hÿ"`}kZ)q´•éÜÓá(r3íV•”W?•$V2ëôÍ;ìïË.|t©£”/®{U…vA#€Æ™VÖÌ©9UËb¹Ëx^i6ެzú{×C¬»#qÓ¥QÐÆýCË*Q‹ sÀÏóÅ0;_ Ág£ØIw41W\³QšÖ“Äð^èWvb$f—”ƒÔRé7Qj y´ø Ž:ŸP hi–úF³¨Þiëem 2bQÊø¤g„õFͲ½C%¤ªc•¡¸®#Ç>»ðýÚÜî|툧OÑ[Ð⽯Lð­¥Þ,*\Är¯´ßEsfæ 4kÍ+TƒÎ‚e+°žQ‡p{`ò)\8ìzô­½'Ã×÷G ˆF­Ñ¦{õÙZhúV’7C ¼£¤’üÇÿ­Rê’ºßE"g5Çâ)Ü ßðè¨DNÍ$eÏ$v)óh¶öÐþêfcÐ ¸ûéE´©ÐAôÀ«¶³4öqçšæ[H±rWþU_CBNËŒàÿ×K:aˆ©²žüñ@ûxp¹æHÏü˜<,ê3êØ‚Et!OáJ'Šæ¾£bH¹A,_óÑ9Ûõ©–L `rqÞ·Ìy³®l>VhÔ+“ކ˜—ŒH$Õ„à–9äÖìÁ—r°Ã Õ³.åñÚ€6t§Xà0ÆÑW±¼çÐñXÖ–Êç Ë׵ᵘ`ù¸ ÆhVÝ 'kaÆOAPZ1T¸= K#›Ý§ ÜúÒ¤qù×%ÀùAÀ«xG·J•aXãØ«ŒÔn6ñН ysHn$`¨Xƒè*¼på˜ñŠË{æ–'P˜ùø~Ç=¨¥î¡<ŒÐ«àîÖROå–y9禵ï­!°µiä”Ë<„(`/zÁh›Ì¬g ø4Àííu˜íì7­ÈåTúSôßZXß¼â$dÙ„Œ.=zpqÏ2ž…bGÓÚ¯X$³\lXûgš,w®Z›ý=X:#É)- ŽcŒŸZÇÐ-Dw±Ü^[I,q¶ã³¥XµÔìâÊgÙ‘òŽÞõbß%¤bLž¸ïŠ@t÷Z”3OÛDÐ$  €}ßAÅj¼Ík¡Þ\IÂù,?QXÉs=õ¼K=ª[à|§3úU»+¸õmïIº\Åă‘Î? <·QXÏ—Œ[3øÕbŒ1Àú ·}iöyçÆ«¬¸\“‚:Õ´hÁÚÙQíI!E8,*GºSòùƒ'Þ¡•!ûB…}훞3@%gaÎhEtS$ƒ…c¬Í´”r*µýÈ{m«€s‚(o]¥$s“ŠšãS¦Èˆ/݇o¥PÖ Ñɪˆy-œâ€&’Ff$±$÷¦ðÿëR’0[ï·AQ;¤wÎI¦˜Ô66óž•aUTã©¿Ënõ*3ך@H@¤N qëA82iÉÍ<^~´üh^×ð¥<œž{P€ç®qÞé‚izNÈãùÐüØÆìûâŠv;¸¢€*«FÜ2jRЕÁ_ÖªsO3É  •¡‹î¯^zÐÓÆT•NzU|ZoQ@ bpN)¦RWÐÇ‚"˜ÀxbÝûu«VÆE’VÀEç9ëíUâMò*ôÏÕ«Öшò=ñ@®%óòvŽFTó“Ö›œç4 `õ¨ ñÜÔˆ¾cíÇÍH'š»hÆÖîˆÔƒ Ý Td ƒŠ¿ö&„Ã8iºô5fþ¼‰îâEBI,£µFg-l°.KcŠ@V™É˜óß"¤ònnÑ#\£«+BÛNF"K‚}€¤‰áTt  V:"ÆÊóÈ€>QÒ¶’Þ5û¨£ßØã} …8÷r]˜¯L Ú€Á«fqŸ»þX»î*a!‡ÿ:@ ß›ð¥V9íœúÓb-1ppèA©cT[ƒëë@£dg¯­J© V“Ï(“îQæ‚œŠ•È4…|¨È 4G’Û¥e¶¡Y.OB{öcP»H±F1p¸  È$24úp\µ\ÄóŠÍÓ[*·•^ÚIrÄ["ŽkKxd‘¶öW<þ'šè´ûEµµ@ªUè‡«ßævE< è¯å¶ sŽ0+Ϧ˜ÉpÌNri .Ë/—j[ø›ŠÊ9ëV.$.ˆ”sUߎsL/Ìn*Þ”¦kÆûñ:ÿ_éUâS…ÀÎx«R4ú Ë4°æVä)=½Go IzÊXÂ>A ìï×qMÒ5»xµ3-ÚlVR2£ dÔŠ‘›û+ÆpTƒÔs@‰KÂdcÎìT+~jXõaÛy«qÆNzP"1Š<¯J¼°qNôAb]Ù+;S eàqÖ´ r@â(r(4Ëû2é.mŸk¯äG¡®±¼EªÈ%ˆ#ºFÝ«‘8íJAU*uÅ :Ý?Ån×¹@Œ-u6!†YHgyDdÄÀã€zf­E¨Or07œ’:¥Ø Õ¶¡–ñG:ž0Ê~µÏê4[Òò[Á%”®&Ü ™>ª¥3I˜iÚD7 Ûqº0çî ¨¿á=Ñ ”¤Úíœl Ê <·Ä Õ<-t^dÙ’vÜF§oчðšÄKeIÇ|×°^üSð±‚â+›ènaAˆFXMì8Åy¿¯øViM+Ûflù°H»‘Ý9Î=ª¯蘒õ5ËÝê‘F<”¾vGÔÚ– ÷‰åÄ­å÷!¾÷øVcGZPsLÉ©=ËaÕOû)z3}Nhb6ý‰Š\v·cÔP8%oÓü*¬öLA’,\ž8ÏáC ›‚x5adY˜ ã§½høoÄÍi(·¾Hz ÝWé^“k«yâ;l‡·—2WŒI"™ÊMHã= tú³&›$rÄ7ªönqî=è°§¯Ã%LJ¡’9 ÉlNêàa¼¹F` 'q=89?á]Ú^Ũøjk˜Yš-™ÈõkÎ'?¾p®vç*3I,Ê&Üë’P£ÛÓðª¬ÜçƒÒœŽcmÊÅNzŠK‹‡•òàŽÃÀ‰€e ô¬mÇÚY#?.s[2yp3gVTªÉoÜ‚äþT±´py‡'šíÉ«W¸'ÜU?^´À1…ϯJ|‡.9ãŒÁþqM,IöãŠV9Ⳟ@ÍFzsœ}iÈq×?…KŸ×šT9ÝÜñH¹^9  +ÆsøTŠ}ÍA»ŒãTŠqŸjœu4N=ûÔ`òsÞÔž½i"“œxlJ„fŸ’Íç@¨ªì|’ ÎÃÖŠ¨'ñô§àßò¨†C;Ô¹ã4Àùy¦†ŸÚ£l•Ï^h6ôïëHœðOãN=øç¥ áOô  F›$ >pÙSÇJË{Ôªß(öíK$òO”Á‡æÇ>Ôñ»>áÇÒ­í®…XEvN$\})‚­ŒÖŽ™mçÎ]¾ârsÜöª·HÞnäŽrmÛF-l‘Ë·Ìß0'‘˳`àõP® aü]êV%FÀr[®).1{…€bIì¹…,k’ éŸJ…sÞ§c„UñÖ€7ô—HÊ: É­ˆÜeþ&ýeø~Ÿ4ç«ô«/(ŠÚ)=þt€Õ…·nnÊ¡}•Õ­_C µjHµLõ~MQÔþ&VIžI4—Ùõèäþ Öí¼`«ëYñÙul8Ê‘ŸÎº— YÒ­^MRÉ XSŽ+sI³W½[¼ç9 ìTÒpê0#^¾øÿëÖæ’‚ÞÖÛïmÜ~”€ÏñEÎØ–  ã€9íë[^!¸óo ç85Ž8'ŠhàúRIÛšƒži#‚[‡Ùon”jŶÍnV9·`.{öüºÕíRÎ{©0ä¹=Í^Ðôñe½¥móŒÂý+BvŠ%v?A@ºjZÊìIêBÕÛ9ôˆ\†åX d85KTº2]ÈAŒT0DeÛ’ÇÖ€: iô°0’ÏŒ“ó «FûM‹¤’·ÑqX«lW#Û­P'os@_Ûzrœ¥oR[xŠÀŽÌtÎâæ²d·UQ×°ÍV‘È  ñâ5Ãk; f•|.9“šÃ’é·üÇ·4[êiØÞ9àZ`ußh_½×þµ ºòÙ¹÷¬A¨'Ò›ö­ç“H v¼lã<µYæ$rxª"]ÀsÖænX2ž”‚CœÅCš\“ß§¥XWôè;ÔŠùã#5MHš˜=hò2±À=k¦Ñ'ŽÞA¼€¦¸Ÿ0©È'г¡*¨ëŠö®Äj`Añω˜o<€c̉Oã]‰eHÄn7c€kñÍð½Õ’A€<¼u¡ 9iÎcSèE6à“±)²>Q“ÓÓ\îò—98ªÜø0žFHbi%~]zôQC sÀ  p’ØÔ¼99ÍT„ãË÷©Uù<äR­Â˜dÞ½Jµ €zûÒH¢HñœŸz¥ ´SŽÃ<ó@ ¸O.y{äU‹I !‹#ÔS¯ãÈI€ûÜ« äSïL ˜°¨;â‘ÂHÌ :P˜u ÊO#½Vr|Ænù¤Ã4 ó çP] hüȉäŒÕ…”:l“¯jŠx]cb‡*GZÍ$þ4€ç4íùÒF9öÀ'¹Â·õ¦ÇÁéJ㜠f?/¥ ëƒÍ)¦fæ²·íôçÖ<Ü&á,Œr#(  WÒM,)6±¶ nKPpBžy¾•ƒ«ª–ÇìñvTâ³u Vâþrò1w?¤FD È…¦ÇßsÓè)«c©Ão¢³Ä¸¸™Ê±î@¬é%󳜟zƒÌ;Åðޤֶ•$ñy—9E=uüMg¥¬×åÖ1µûä*[K ‘ùdH 'ƒšéí­–=ˆ«…ƒ *ܪ Ñ ulÒˆkw·”¬ˆU½ O\òvWVܦ$Œ0õî+ëE’ Z¹Gðšw;ȉ€Á+Hm˜–@~´ѱVØŠp“å ŠJ ÷ß5äR´œc5 “ ÿ:<ðsHgÁàõ¨ üÆš_iíŒPÿiÓMØ0ϵU‚Mò1#9;¹«ŠAB¦€!mv+f*ÄävkQ¿}Bí¥# €ëZw6±°!Ó$wô¬Ó¦»6#pWÞ€)0y$æž§¸ÿ­,–²¡+·8=©¦û†˜'y|ô¥$ª ËœP!·Ý©a´žVÄhÎDzŒÐ²~ñè´å—%«bÇÁú•É è°©ï!äþÕhž´iGÛ%F¬H_Ë©¥p8ß#-Kg°+èúŠFnÆçË—òÉë_Dè~ðþ–Šñî½Ìcè+´³ž-¿u1€¥ÌÇ2͘¼²AïÚ«ðšú/â?Ãm/^ß«iÒÇc¨ãç@Ÿ$ÿP:7½|û.›s¯±•t8!¸"šwö·!H-Ȭ´‘\d¦25R;%S‰qØTöð$s?%TŽÔÂ0ÜséOI˜pÄh;Yèi«yvîÆ{â€(L¡Y±ÐôÐ¥‰Ç^ã55Ü{\€r=qUòAÏz`/ñw3ùRî-ÉÆqÖšGšLþ”ƒ?(Ƀ®hÇ8ö¤ÇCJy^9¤íœ΀½qíJ:ÿ4pÔ¿OJz÷?=}ÍB¼æ¥_ÿUJ™Ï·½H§·5 “»×*ôÏÍMÎÑϵVo–@pMYOcš†UÊñÚ“º0G§­ ¼œìîh `7Òž‰ŽçÚ•WûÝéêï¥G0ÇQUr=ªÜÜ©úUF‘ô¦{jf:ò©3îIúTDóùÐÖûÑÁ ´õÍiA¨àþôî+>%\ôÎ)ìÞ˜ ž{¤K$p2Ì>SíU-æ âêj›ÈZPÿ LÉŒdZ@\i·|½‡5‘’Nõ¦+o·zd͵¿•Zµ¶³º ’Ü›y¿„¸Ê¯qU.ôë‹Äs;¹ ­¸0õªîIÎ}*hK4_1'4vß'V”ó…ÀP«Yñ HFî sO„.ÂóÉ  û2‚:âµtQ°)5šê ºóji+ˆ‡=»ÒÜëûñÏù_ËÓ¤~à’EÝè1O[F½òíPæ0  ýÏìúd—l>{‡Ø¿îŽIüÿ•]U&k‚Ý„þ¤ ÐÔÄq]¥¬Cl‚5ΩÂ?wzùçäOÌ“ý(«D·šjn0QƒèE\ðƒíz¥£cxùñíÒ«Y‚¢x‰û­‘ô5_C›ì~<€…¸C{ä~¢€:-Aö5¸é™š¹iô«wœÈÊrz€q“]n«…Ó­—þš=`¿ÞÉæ€2®-]BÅk *“ózÖ…¿…•­¤šYÞ<:u©­“̺}òksSo"Î(†o™¨/ Íh¯#®ØðÌ'%ªÒÀ@‘À8_­t:ÛùvQ[ޤ(?•c²¬c¨ùôqìU<äŒÿ…Bß5êØU§Áf#§Aôªü÷ŽÞ˜|t=©®œäSÔcµ(¥ 2îôØn‡Ì¸aÜW?w¥Ü[çhózu®Ïh< âÏQš`p,Äg®Gj‰›Ö»­&Þäd  ê85‡u Í&6 èx¦)4ÉÛlLÞ‹SIo,'!QT®²y&€ÊL1ÓÖ´Î:ŠÅ…ü¹TœuÅl+î‹+ƒõ ‘C®}* Ì`ã­]D,~\jÄzUÅÉÂFG»p( EëÇ9¤—lIúW]„ÉÁžàcÑEn[iv»Dp.Gñ“EÀâì|3wpDŒŠŠ¼yü«²Ó´ØtøBD‹žíŽM^ Jp )\O¥=F 9¥^¼S—¬o&›ÐVÏü$K D±éÀ½r³ÜGk˜çŽÀu&±¤¼’âBìqè3Ò€;Ø5×Ë»dúUwÂú_‰b2 »Ç§¯­s^´l2~•¹eªôËb€<Ï]𾩢JVx‰Lü²§*EeÚF&b®9kßcº·¾¡¸E‘`†sà=>IÌÖ¤ÆUŠwÅîcG4¶Éæ¸SÎO­zn§ðä\)hŸæÇÍp×Ú=æ‹1Y©“éNàf^Ä#¸+Ž•FKvv“W®¥ó¥ÜO8¨%ɦe·vèG‘aê3Šœ±hïMÚ{ŒqÖ€#dQ{T=êÎuÏ_Çó ž8¤ê)ǧҚÅ8qøÒŒžM ?LzzRŽŸá@n½³RÇÊûÔC¡ïÅIŽ(ëÝy©S§ëPž¥H™ëë@§CÒšü8â•H ž 5‚‘ÊœŠ@DÙIö¢ž@a·¯SF{I ™£‘He>• ŸÖ½U¶ÒuM>âh ÔnÉï^}(ÁÛß4€‰ÿÕ¦ ÕÖRc#ž•Wk~´À‡×šbŒ¸ç5)AƒÁ£aO›w  ìU"„Ë{Rçår(Œõüèh¥*øzT¾le,:Õv Ž‚£9Û“ÜzRÞðÇ÷dëCÂr9cÏsPÚ°'æ'éWÈR7øÐa¿hïZ¶"®WI¬¹•£™™GÒº[YØ#>QŸ­T¸ 7·j–Áw]‚}*9Àäàžjm=±&8 >yc?(­m-8<ÖE™?k“œŠÞ²\08íH ƒ±ØkkJ‰aŽk§á£ùWÙ±ÏéY',TkI®‘¼?©V;ñýâI?Ò€2YüÛ‡vÎXç4ô\XLÝ\Ÿ¢ÿõê3’=jÆ1¤ þôìÇò]3w Ç åx»L“Òdøö+[;e+ŽŸÊ±o—¬ÙKžVT?øð ×ZÇ— ~Œõ†Ãþõµ¬·ï‘qÝëXŽrH  ßϽÉè1ÍKxÿkÕ0¼©‘Q~™ÅXÒZhóݼà õ5[M_3X³SÚMçðÉ  -[÷š›Ÿà€~g°¬Ôã{ž¨:Ÿïòjþ¢pqüR±‘¾¿­Raˆwb\ÿ!HŸ8ôªö|ÈÇMKpØJmšáiuFG¤u¥_Z?iÐ8¤ÇnôáïHz£¢h²N1V;Rc“@d±IW €æ¹ [N…ï$»Bü¼Wq4žL&>èÈú×*ã.Y±“Öš›“JeRU²*?ô‹Q–\¨®d‚Z¡z¬ñ”€œ»ž”»pz4ÿ§J@sPÝÜÃcšf ;ÔŸAPj𵦑hgºlvDyµyõÖ¿.¥vÓÌØ è£Òš@tïu0‘Ûá^„—8íX±Ý‚ÏJ·û‡'éL d“žjÄsm9ŽÕ”²*t”äñH‚×Qdaót®‚ÇWù†Nk‡ŽOÒ¬Å;!È8Åz­¤°Ý¯ V?ˆtmNÄCžŽ+ÓµvV_Ÿ ;æ»K]J-BßÊ—ñÃv4€ùïÄZú.¦Ñ8ÝåX¬)„„v¯rñ&•Ô‘™£±±ÏqX—¾‚âÉf€/9f©0<¥=qÞ¦xÙmÚCÑÅM¨[¥µü±B6ª1ÎqQ2O$aUñÅ0!³¸BF@äþUðäÆkµ·Ð.tÿÏssà®CŽz×)Ë“êh™ljLpZñü©2qÐq@ ^h ÿ•ñé@†ëK»óFHŽ´Ô8?á@¸çð§GžHüÅ#ž3Ž´ˆ@ÿëP• ¯¿½#œSíoj{Ž?• ÄäfŠFÇù)ÝYÅ:fþòšå®2&#Ð×l‰åéì1Ñ ®"fÌî{äŠ@FrPàvª§wÓ¨Ìàüªv¯°íü˜õ+Œò±¬kõ$ÒnØÝ^¾ÃÃ6Äú* <ÎÃ…û«ìJz~í$“<ªíïþµEÀV帩í—ÕYNé@Í^p£Š`N¼ÐiTR€3HÓH5&(íÒ€#ǵ#. Hx&˜G€2µYŠÀ"SËŸ ¬&_|œsZŒ‚K×\ðŸ(ª-éœ{Óä`'=2j„F­ƒ’y,{ÕŒeþñ>™§""+Ÿ”ž~”Ëk$·Ä¡CÔõ¬†‰—9ð­iæûEÔÒð9#>ªPT‚;S ?Q›MŸ|g*O̾µè^©ä!ãaî+Î&ˆ§ÒŸe¨Ë§Þ¬±—ø—ÔP¯C(q늃TÖ`Ò­÷03ÝÄSýsßð“Û[X‹C3Œ*翽ròêw7³´Ëìy•º íJÀM«5ÅÓµæ£t­þ®.øô°¬vbzã=+B[u•÷31|ýòy5]­$_ºCb¨Ay$Xç+Z¶š’3cv¥b˜Ù>òQñ»‚qší¡œ89Í_‰ÁnÕÂ[ÞM Ès·ÐÖ¾¹‚€Š@vIÎsô LÖ-¦¤’†ûÖ’\(ù³ßÖ²èzÖþ‰©ícsÖ¹±r„uâŸúà `h·×Ü"+“Ãw­K ¸¯lD1²yÌ6€Ç?á\‰µíúE®ÖÉÏ_Jå­¼Q¨Z\ b‚½9¢Àhø“ÂÏTo9Ò&`Xì0'>µ´V𱳌(Æîµu>!ܰÿH¶Y›Õ€5`|DO,!Ó¢ÛŸ›ä¥®Þ@Þž ãyE ïÍxì©´ŒŽrr+·ÖµåÖ™‚À±' 1€+ˆ™·JÍž $S@Fy___jiöïN8šLðzô¦›ǽ'çÓŠJv>SÅ2=³AéÇ4ƒ­Yê¤cµ11ƒÇzãÂ…ÇL~"€&ÆGqÖœF 1O=Z:6Oç@ ÃÔQNu@P¤?ú‰@è#"¸y€3¸í“Ö»lÿ¢\7û8®CûçëÖ lᾞ•T¶F9?Ö§sÉúT?ßZ`86 éJ[píLç¸>´ôÛ‚084UŽ`cÚ˜9vÍHøÝÇJ`éÍ46á‚9õ§)!O­0ñëN^Wúâ€$©â~r{zÕT$xü*xÎÊ€5r$·eõ\ņ6k´Dá·ŒV»``š4»rÚ˶8@M 4çB“œT9##ß5vù”Çïž+<z€n[Ÿ5p9ÛŠÚµ|ÚõçÊÛÝ*9ãŠè¬n* õ€\²ym’åBñ¬¥º×a©êQAáÿ±ªæieÞíþÈù×'NsMöÅ×ý¡Ò›a©]éÏû—;sÊ7 þx¨*9æ«Él‘ÃÚÅQ2âkgSþÃgùÕË$ƒY¼ˆ²J°Ë‚0H®fÞÍŒ€”$‚œšï´5í-Ì“‚%nÞ‚ê±Æ·_»]‘„P«è­ E®›uzx*›Wêj–®?ÒPü#ùUû¼Zø~ÖÛø¦;Û”€Å|€Xžy5=™)¦ÿžÒ—?Eà~¹ª× É=+@BÑ[vUáËçLM”Ž8ûŸ¾§§éPIÂÔ²?›3ÉÓqªòž + Ý/5¥ÂûU pL„òkMáLN @Òã'°¤qIO?JhLŠLdäÓ_ „úsSmõª×Çe„ÏþÉ UŽçf?yŽj$öà àŒÓd^)˳Õûƒ•ÄÀýÁ´¼xhçî©Á?¥ex•Äzuµºÿ…Èöƒf03ùÔÀñU"ÏLU”‡Ö˜€FȬÙÓlÌ9"µ g¶k6S™ÉÇ9â€2NçšÒP b¨[d](­!‘Û¥yíJÍ&êA»?TŒU›dU%#·µ_ÚOÑ䎜`Ð •I«2YÊ®ØB@<P:8 þ4À³g)a8#kR+ÉÑxbG½`) äpEiÚ8Š Øõâ€/ý¾EQÉÍ:Þêâêq¶ÐzŸJ©$nÁÇàjxÿÑ¡*?Ö0äúRÝÌþnqd^OZ¯µrx¦ÿÎ=x¤ƒ€rOjR*&=1Þž«ÎXñïIÈ ÆØÛJÖ+c zVêŒä~‡*mr3ÜÓ6{})¸È¥nƒjïJ¼5 í‘@ ÎOzUÉ¥õëÚ‘G^(ëЌӇ\œ“ô¦¯9ãšpè}:s@/'¯éJ{sMZ\äç<@Ï&Šo!zÑ@ŒXÿe\Pk‰À3Û5ÙÊÛt¹€ÇJáebd8ë“ILÛ5 ädñJääçšvy÷¦…=1Î2*1œsKž€"`KÿQLùéJ>øçêi«Üb€°3Å(ásÖ‘‡4‡Ú€3Ú¥V ƒqP©êGãRŽ´v;½i鉳í lô¬ˆ×5ÑÙÇäŵ‡$géH& þÕ[Ë*§8ö«—läýª‘9Ïç@BwaùVµ‹¸# À« 0\íiYÜÁ­k]A-õžÐ0ë÷}ë ¡eo•Á¨­Ëkܰ‘I}§G¨5FÉñ¨ëõ  Åp})PQYŽ©G˜pn#üméZ\çÍfi% è>‚€/ivÚ…b¼km¿5R6çš°Ž9Ô€ëØ¼ÝB?p´ýfP÷â!÷aP‚¬”R‰Û?@3XòHd–IV%¨¶A%ü`Œ¤¼o çù⬫*yÏÞ”}O_ÓùÔ6£Ëµ¸˜õˆ”ûu?Ò¦¸ZEu]Íþñÿëb€+8J‚S…<àTÄuæ ÛæÝGèO4À±>\IŸ¼Üš¸ƒ kŒÌqÐTˆ8€ÓñÈ¥“ë@ '4õixP(ÐÎÕ¤Ûd˾@Åiœâ±uÃ…‰}I4† QLØÎ«*¡†ÓÔt¨Ú1Î2;Óªäõ5‹âˆÁÎÆR˜ìs]" WEÆK6Wñ=¨—Ãs2õ+¯ò?Κ„Tb0N}j8°Ê O÷ vœñXÒcÍ' dšÚ#å>µˆã3ã±4=ÍÖ:ñ‘Z[gØ€nIÇEü«O=?*f9äñ@üéøù‰=¨Q…4 #ùŠM¿0Á5.3ƒèi§œb€޼Ô3[¬ÙìjÀ\žiʃœŒPFQ™[¨=*Ý„GsÊÃÀ÷­ ôçÇ<‘â9Ûž‡‘€^ƒA@ ùÑ'©4nàzÓ[<1â€IRªa‰¤PqÏëNçv(ÇëL=8äS¾‚šFTñ@Œå³Þ±îò.ÜqÖµ¢ÀÉÅdÜspÄã¯Z€~”ÞÔæÎ=}©;gʘ 1žÔƒØf÷ºRÿ/å@8<ÒŽ)HÅ'^èGz‘¦üŠr{úЊ2;ÒsœRöÆhÚA@ ü]qÇz*B¢€;«‡ÿ‰|Àw®<ÂVBÍÛšéæ'ìóÞ°å#È‘Ž3Š@cÊrÇŠ`n¥œž>•é€)"·<ä{Җ‘šgçG·LP@ süè^)sÓœfš½èž>´céC{õ Ÿ—?• Æ ½ªU=ª!é×5(úЛl³^I<Þº9ÙvžVNŽ».òTƒÖ¶3ך@@Ð<Œyê{ÓZ5…Hà“Þ¬´áÞ)ô4lç銰œc®q@å¸D èsNÁ-À?•8ñõÅm¤°¨Þð¯ûÒbQï*Áœà÷Î*”:¬|ÈǯïE1õk%)¾„n c~y¤»×ð'…P£ò¤°ŒÇaqsšcå'Ó©þ”Ñš– –±e~O î*Úž(#¿ŠÞ1‹k4Ï×âh…èò¼«QȉrßïµNCÆ*I$ófi åŽj&å°hn# Vôj,´ÈÃÈp?­dÚ[µÝÜP¨Éb:V®­ k¥?Õ»G×¹  #=*TNiª9©ÀÍ;zQï@Zp Š1O ÎivŒtÍG× u®kV\_·¨QŠê íæ¹ýQM@‚GÜÀÉç cRü¸Ï¯SSˆã'‚}i™[   Q©ÆGu«—-¼Äÿpÿ*‚؆‰Tã+ÁÊŸ¨ÈM¸nþ[cò4ä õb3•ü* Q¾ß¾EKnpÅi€Ù~ëÊ« "ܶ2:Ðt,2 BÙVÁíÞ€Ö´cÜúÕsÎET-–â•'ØÜçk4 `\9ù­K pö®y4Œ±SSÇk;¨rLõ­°²š±Ü'&§²IôùS(–Ùº÷Æ;Šchö²F²,­ƒ€P®H©$ðª)-ÖÂ9R?•\i"†<¿pëVž¥æcòžˆ?3H Û{mI¡0<‰yov’r=Á=ëV³’Îèîù‘þd>¾ßZìÿ³£šžèÇŽ¬^ÖÝ´ÉÊ3;DTï'‚sŽ(—2 c9¨Øå½*M  ö¨ŸƒƒŽôÀpý)ÝÈœSxÎhùàTmÈ¥^ýøõ ùòmÎóÍ5®%9Fàw4ÑÔœ †â@X¨é@îuÎÉ™F9ÃS Ò¹ù™ÔÔŸ›䊗•;sãoέØDïsk©çê*Á8çµ$NèÙFÁö  |8ª’^Þ°ÇDú±ÿëTNb¶rÖ\>Oû£§ëš‡ÂWŸmðÂ:ýùCBåÍG}?Ÿvì>âð£ØT\qJÎI¡T±õ½iiºk_]"tLå^ÑíÅœº„£æ#l`ÿ:Ì dwvêI5©®]/Ëk¼=+%O  “ïõêu^*¼g皸«ë@ ÏJ\í94»±œu¦ô;˜Ð‡<Òðj¤šŒ¡·AÍWk‹É¿Õ@Ê=[н#dc8®^÷2^ÊÙèp>‚­Þ ÈÀÝ*eºJÌ6`åÛ'ÑÍ0_½’)æX•Nj®¶HOF?V&¦[Q’ƒñ [­§rg#Ò§¼”Ü*BÞ=ꔲÅnV0»¤n(É5nÖ6ó ¯÷‡'ØöÀ^Ù?Sš÷ï_¡ªÎå©üA¨-Ljf1œÇ©õÇ_Ö›‡\õã‘LŠPÃæàz‘•[¨úTm9+Œçšr±C‡Î;o¤Œæ¢û('†ãÞ¬ãæÈ9£Ö€*}îÈ?—õ‚Qÿ-1V qÍ@fˆV,}ühUH Nsڬǩ=¬{ Çèyª¼<EäÒÇ ÀÛêÇ“@v¾ x‡ÅÏ÷º¿±¨]0dÓ·c¦Z³,Þ(e °2œb2~µÐÄï@‘XÙq@Z…ø\ɤ;û­{©ÙßDl®[6fæ\sÛð«ãT‚–dvýjmÕËj6®©¦›¥ì$"y¤#,F7ê¼px>⫸àzûÕ™ADòÌsDñ’­¼•ï׸ªÌyéŒÓ zP[šAŒýi¬y>”£©>´zúR : üÙªWßëWñW_z©|>t9  X”‹hr™ëOÏaÖ¢·f6‘öÅJ£€JQô¤}h€}ºTR—9ϵJ9Ï4ÉÈh2òo-6çænõƒçx<ÍW¹—Í¿»Ú¥°ûÍúSUTb‚?*H¹JÒ6ÑNPÎê¨ 'E@,ÇMǃëGÙÈ<3UÝM5›š‰b` 5#  óO(a ˜ŒG¥e»îfÈÉúÔc¾spM4c'ÀT8ëô¤É$“Òž½¸•EÜö }â}*e''ñ¨—îôÍLœ¡ÏZzøzÓ×paƒL\cǽH£÷œt  Ø[©Í0ƒŒÔ¸‘úÓpiBÜwÍ5”&@<ÔÌàd g=j±$žôÀ21Œthƒž)¬ØROa@ ‘ö óUÏCž´¿{$ÐqÏ4 ÏJ±nNxªã $M´ã®häàŸëRÄGSúšªH"yfHcRÎ쪠w$â€=[À—rÁàë Ã ÷%b>Øù¿ZÖXr7°<ô§iºZ[ZÛiéÌV¨ˆþ&êÇñ9­ ¢ß*Æ¢¤ ‰ "ƒ’xÒª.‹¦ßëä7ªJ’ÂÒÞÂ3ys·îÜ×=¬kæVvl&{Ò Í!žM1Ýc1êk?ͽ»ÿtF够Ðu©aÑ"î»’K“þÑÂþB€/b•ˆ€™zù|â•/õ GyÝGõ­[{X-âG Fƒ¢…%´ß~Ú&÷Ú((A1),~ôŒrÇêk+]ÔEœñ@ß:¡gqü"®¥ß› D³i1–Â?Ʊµè ³Ð®ò:¡'%‰â€8‰müÌH§æ<ýiÖòùcséL³Úf_’ 2Iõ5c·nò3‘À­0&IUòH©1–ÏQÚ«ƒ+ýÈÕ?ÞëOò¥=fü†(|œt¨݉ ´{žhä1ýûóïQ´j§æ™ÿ ËfûìOÔà~TªàGû#š¨ eŸÝ¸7”N|Æëü+@ F3€}5 l#ãý£@P˜¡sëJ«Ï_ÈP„¯‚{p+[O”KlVH¼Ò¯5–rr:ÐӬ¤Ä7p»kÛ£ä["nµq.“$~µ¶‘¨Nxµ=]ë^“uåý¼¾9þx¤%â;xänãà•Æ>†¹¢¤sšîõ²¹·ˆ¸ÆW#éVÊž úÐc–áÈ£g<W¨â€?G\ÆÀqëJ¼“éOÇ\õ Q†Œô<ÔÖ™ûJ(õ§^GåÝÈ1ךŠÝÂ\+Ƙè¨) O&HŽ´â0zRð·•:8ìEè#2ÈAéš( ü¾Õq­)Žþ¾µQä`zšœàg¥S¹bbm½iùëÉéÍFÀ>”œG<Š¤àæ®øE4(9 2})Xp?Z}¸©$XäÚm —w8=½è˜À$TÑü«Œ÷¨ä‰£8aŠ•Õç¥.0úÔõ^xçëL'<Ô‘ô'Þ€½M6fÇ>µ.DHs÷»Úª_“ÞR~´˜:TžQÆOsÅN`ò¡ËrÄgÀ¬Ý8ª´’=‡J–fÀã¯z¯Ï=:PFF{{Òž:úv zóJzžÔà9ÀqÞ–,3ªúšj}Ò}ªk%ßr:ôÍI"€çn1šé< cö{íL¹ŽÍ<ßøEŸ?…sÒFá˜öÍzÇíÿbÛî\=Ûyò±íáGó?'°-„w2ÇòÇ„õõ«†k]-Œ·,$›,@óøúRê7²™ µÈŠ6—QÉúVlZkË!w?Þæ¤]꺴™#lc ì*$°Rù#Íw=iýž(y¸™Pˆ§Ÿþµ3í6Ä`J¸ÁÍ@¶ê7ooEè*ÂD®>”¢RF!µcîíQJ·çm£›I4>TulÒ†'§Ê=MWŠ2>k›ÇÑ~QRy–yÁxÛÛ"€ÏoùæLÿ½J·°±ÂïsþÊTxO °ºµ.ü .I4žOD¿ˆ¢’ió¶;V'倫!V?… n çuÔ&~Lh«Ø Ʋe‰ÉÛ3H}›ù êÌc%™†O5C"ò3õ¦0ª£”AZš`ÿZ1Û󿤗Oˆr¤ƒQ(6Ì6ç=Í]k+\ïx#-ë¶¼÷âÜ)µ•°ÀÞYÈ»Ë¶’UXâbªÃ,ýÀôõå>3¸…õaÛí$äæ„zÂö±š=ÌøbARÆ0 HBûÕN&wPZB: ·h~f÷"˜¬£nY¾œTŸ½-ü =ù4ªHwë“I%Ü14€E BY²Ò1ƒ€)VNAõêj”š—Î|µÈõ5ÔgÇyöæ€6;÷#?J|pI&v—=Oó5†o® páG°¨žydÏ™#¿?Äs@!`ÜêÝaÛóéL:ænOÙôùnòm®g¯=‡µ ð:÷¢ÀtMãõR¶°ÚÚ¯ý3ˆgó5~+Ö„…ô™÷ʰ†FsùS×8éøô§`6'ñ>¯rJ¾£1è‡hý+8Ë,ìÍ4ŽçÔ±?ΘÎ=AÏÖ€F´¤¾óЊ\sÉ«Úm´7Sy1WnPç‚})@³wÂÍ“‘]9ðÉÎw¶)?á8r>´͇aØt ¿Zè_Âò¨ÊIŸcTßB»Rß&F:ÐZÉìj½Ën [K¢]’p”£C>?´±/'M>?õižÊ1N$ŒñÒ§‘Pq&¡ù‚œ) ž´à=Î(Ëgîu¤ËcOÔPªã?…<Ï=0„Ò‡Åaê˜ûHÇ\sPYAç\ ýÕ9¥¾Éy!çƒÅ\Òã»cœL @z äúæ¬Ãasp…ãäþñ8¤-˜¥Â•<ÑZv•q=àÜ„*ò[µŽãF9ªŒ¿1ÏQÒ¯-6š‹ì®Ý3ЩӷjcE_ rjAf$b€2 ³Á U›XÕscqéWþÌgóš¡w°p:ƒ@ Ô•@  Ú™l«~5®ùvã½#6Xô  2Ê»\Bð§ËäÕö\ŒäQçSLÙÎ̧Z´ª"L°ùªXÙÖ=ÌàšŒ v'ž´€ƒW=ÍJ‘,#s|Ƥܰ‚|Ôø!ÞCHÝ{PÁ˜Þc¥„$õaƒWL[3ÏgšÇº›s› :P.즶HåtýÜ‹•nƨœ ñÚµ´„º{AqóËö¬¬÷ö¦×éH’E(ôeØ:,ü¨£ÜäÐã8]Ãò ]ÿ[‘Ÿq‘ùŠd\©ÈìEB|å•E‚ijæ®Ø'#pr9æ€+ÓÌÓÌ(T` Rñ§_Ò¢’iHÄi÷¨4^µs"É&gô_ñíWÖÌÉó\HÄtp(\ráB€F€8Ë«­JâQ ÅlbàpÛ™‡~{W—ß{Û†C•ó[LšôÏ].YaàÄã$z?­yiéïT€.¤L.J_¶ÌÙÃôVo”“Ò˜8ü:ÓFšGÎçfühÀ ïŠo'¾˜£Îìz‡ïŽ£§l$´ñ ?©j W'$b¸jm§jðÊS÷nv8ÏbɯWÛƒð©'ÉÍ4Ûœž2+U£ÆÑÅ7i9À˜-ÂŽ€ÀוëìÓcÜŒWo&Ä ®Ö#š+ Kh„qª£ŒQUç~¸=( q“j}Þ*0¡…^H¥ ó.E0ÛÉŸ¸.”À¨`Îyüj3Áùøö­¶gÀþ”ŸÙÎ$;y®h2e- í »W9$Œ?wÉhTaÀé\ËéB}uíÉÄxãÒ€0Õ ç§ÐJœõõ­=WJ}2àc&&èk-1¸ƒLc#¨üéÀ|„SpG8$j²gq!G\PÔˆ--Ó¡ “T^RF`ô¥H¥¹|F¬Øè=*s§ÜóFW¿4€¦§ K}êÊ] Œõ¦Nfb `R®Ž­Õœf€-G•WZ`(=œHÜyíM緽ɠtÆ*ýê[Ç岟­RZGTPIbúÖÜz² 28Ú€6¼7oswä\T™ÐmSàŸ­{øgN”ì–ÕÈC·ùW‹iú-ý«¼Ì¾\¨Àb+ßb!c/è™üêXÇ„ô”¹a ¿ àn$ŒÕè|;doíí@ÛÄw:ã®øÔñ¹2'–’®é€‹ËÃýZ€ÔçúRÅÁ ¦4Q‘° qJË!a¶KUîƒü*õÄ»Œã’j´AÁáÇЊ<ˆ?‚yú5­d#),2Ùãõ«Êd#¤mõ¦Q(‰à‹Ì#!sÉ  /‡´$¦™âŒì—1ÐH0?>•¬¶Ñ¸ù­Ù}ÃRIclP«FÎU<Š¢ÆTäCQy1ï%FÒzàâ¥: ,ÅìÞkCêòþ*x¨ßOÕ#Imî€ëæ)CùŒŠW.¨sÏê¶áÆMX{ká Ý {qÎÙ3ÌVd—j‡k¬ªG¬gü(Æõ^qIö‚Íò©5 ö£ò$­ÿlÏøUÃoå© …¿Ü4’I~^wæ•ÕUGN9§¬S•¶”dªóG~ÃlV1c™€Ç¿Zæ”vÇ·¹ëI.å› §d[ í@îŽmAn‡Ÿ2™°54K±?ô´å£uëL±!â 2d`}k]Cý‹t>íiþñG +;]ûäœ}ÞÔÀâôlh¢õØ»!ozá-gky’xøhÈ<×}n`Õ¬EÌWÇÌž†€!ÁccÚ› ݽLxž6Î0¦ÿv;@¯%a¦NTàì5ãÚ³*®sÎkÖn$M¸õØkËä†Òæá’áÝýÖZz4B&68ËüÕ;»qÖ¥òÄ1$j~UP>0Ž@ÀÜN)§g©‰ H^"¥G_Z™¤ 8¬í’ù…ƒ;b¬ÀIÈaøŠ@Yç SE&í œãŽ”PÃ|ò#lP©¬«ýemY$ËvPkŸ¿Öå`c„á3ÔV3L]‹3îi£}«ËwÀù²Ï$ÿ:p`F3HOQÞ€#à:o=jm»·{Ôl˜ÈãŽâ€pEqêÇŠϵ(<{ÓÕÀ·}Æ 2âFšRïÉ'5 ýïÖž¤¶i41ëZöÑ+BÈÛ‰ëYÑE–ÝŒ¯bi£œÇJ”Y€IóNÚŽöcm¦É“÷¸­BF9lŠÆñ ÈÞ/ðòßZÈ–rö$â¨Ï5,¯¹ºÔC¿­0ñǵ=)==1@Î(Ã§ËØRž„Ò.6’IfUäö  öÖÀ"dd‘Ziï ÎHfÆÖ0¡˜¥h«GÆÓøR¬-ã÷®ûÀó0³½³sÈ"Eüx?Ò¸ÏݱÈ-[~½[}rv;%#Ÿ~Ÿ®)ÓLJLGbiúLâ?M ­_r¦¥½‹2•îzV å×Ù5« Ž…éÓúÒ¬vääš±vɪSÈ­ŒzÔö͸f€4£µiŒÕ(ØtÉ©·ã¥ ,qÓšˆ̓J õ54J.z mAêy5®Ú:S™È 穨sžvÐç*9¥Ÿ¡ï@@ÏJUûÆÃsÈ¥ÅàjAØÑÓ¿Œò}h?­;ë×µ5r¼Gjr}ìgZQËcŠEë@ê}hÜc½)'wáJ8â“©E)è Ç5»àÓÙò è&°`&¶|$vøªÀ7I·ó€=}Û`ûüÒ"´‰n”â‚"p´Ñ(邨d?Ÿ­t‹„/“°Ö–èñ×"³õGG±™ê„t :@@çô­mS}:ë Ÿ-¾ð¬Í¤džGj =¬W¶âXˆË ñPV\qÚ±4+©ãI!ÎF2¸íW[Z¼·8{bãÖ¼Áu!vkËùkôôÜ+·Öµé§´{s”®MpÁ¿ÓTÿ´?4S!çÛ¥If¡®3Œm¨ Ï ôéV­†U‰=3@çjhÆ:t¨€9éR–¤Üõ¢…¢€8­×-‰ÀRjâìþ?^jU¹X¸HÀ>¸Í0(dEùÐŽ;Ô}GjÑ’VœÌ3ùUs  ê==)]IZ™aüpi|¦  žž”œzþU4‘6sЇ $c4ÀzŸOz‘cܧÓÚ£PÛsùšÐ°„JŒa½z@KlÒ[¸Êµ¡É[<àUo²È>öïJtíÎ}(F4Pàtâ¹ ù<Ûɤ8åt×laµy7`ãë\••\’rÇÖ„rÜž;ÓGÇJ2yëÖ›œdwúÓÇ·µ§8¤$øP:tíÞ€>ï8æµôk6I$=WŽ•’¿túâº-µw ’ÍÞ€4⌅Úzý*aÇ}©C±Á#4#>HÁ4€aGã'Ÿ­> ѺȻ•Ô†=éç“ɥܸ8ôëšô;«•º²¶½N’ cì{þµƒ¯"ËmËŒ†Á©|3x.´Û‹9’/Þ >Å&¥ -»¯ðH jki7e¶ùoÏ!…lÚ¸[hØYA®^՛ѷÞPyúz颽D·„¡;LjAn tqM‚rjô8a“\µ¥Ó\Ê“·Ö·ä(¼Ÿj@i†ËZ•Ø*mì9>æªÂJ!$üÇô¦26Ð*@L3#tâ¤Tæ–${ÔƒœÐR8 sÅT–CÛš’y'*º¦_p4øXŒ’9«ÖŠ dúj(Œm•‘÷…’ÝVN¯4NìÉ{>Ôܱ©àŽõVæØGáGRÕtÝFƒl`Ömôí(äÝiJuQh3Õ&¾~º¹˜zHÜ~&¾…»EòHô\WÏ×ë²úå{¬¬?ST€mˆÌäöPM[f×­AdI{ ~àI{P2aÃt¨2r ëÈ©¤!AÏÚZ`ä QÐR—ëƒOËÖ€yÇQJ½OûR}ãÅŠhëøRçÖdƒùPÎF?KŒ1þtÑÔûu§zu \m?­ïcûÒ'Ðæ”}ìóϽ?އÿÕGÀëH{òE/§§å@ qÜûU½"qm­ÙJOú¹çñªg¦9¥V) `OÊs@òÝsž‚™» þï4–· 5¤ŽwÆ­ùŠY%<…ãéPyX*zUK¶hm%}¹ „äÕÑnXîfãÒ²|@ßgÒ¤Á9cŒf˜ÞŸnš„Røu9Å:m.UB{uªz|Ígpdä ØK䙲‡õ˜Ð÷ ÝTqÅi¼â&dlqÒªYK»œ÷¨µéHŒ§—¤9­ÝošWÏ`XÆf¾Aïšv£pZV=ûÕ<Ü»cî­079)Š¿jÊmðG 樎8«qþìáÔãÖ€-Žp@ãÖŽ1ŒdЀF1œŒdS‘›$cÚQµ{ÑM·AEq Œg¿=èb3Ödr:QÐâ˜Ïò§©=@çµ"¹ÓŠMç'õ  C~ZPϨ”ôæ—æÉÁü¨ä ^F}±U›iÜÄTÁ çq¨&.#ù»Ðçp š·£©Îý¤zU“ýkBÊá|åYËléšÕ¶´@HÙ÷"­ˆ[ŒïJ³[F@z [™DJÄ}ãÐzÐNªÆyœ*uÏs\Ýòùr”' ë]0HWsÉ»8Ír·Ry“³æ„|û~4ß_ð¥>¼Rv"˜ O¯½&~ZVÈQÛJAëŽq@Ú1×k«Ò¥òôè‚§oJå9Û“é]®’ˆºd#x?/QHy’B~U,M+uR½XP¹ùsÒœ#ÝÜP%›8À¤ÊŒžõ7‘ƒŒãñ¥À‘Ó>´€»¡L`Ôâ¸!ù‡ªž£ò®ÒâÕg‰Ð ËÕ}pzW;¦ÙE;r}k¦µr‘¦á¿)úv :îÑ­_Œ•³¤ÛC¥.d• # É“¿à)|ElçË–4%G±¬u)ô¹÷FIˆóûÃühªµ³Î!€ÅmÜVµ½º[r͹½ªë:¸ué‡/Œ|½y§Å0™ŽæÅ -ny› Ò®[¯&›”Š>aNk´R6óëH `aj~ Ëòàj68„“@]³V!„â£rÕt‰2ÜÖ€!TœÓ$‰JTg¨ t¨Ñå¼ÜêvB¼ݪyÎÕÆ}¨›`pÊ>µ‘3$—d*Ž+ViUbmÃ¥eZí$€uTœÿ ¯Ÿu©<ÍfðîÏïˆüâš–ä%¨Ï˜Ô.Ä1ޤ߲×§ËUǾ:U‡$’|Ð9p)}y§–ühTÙíœS˜cÒŽ§ñ¤Î ã¿nÔ¼î{RŒãŠLdäp}é@à€h½ýi0søñïNÿ¯M8&€=¹>´“ëøP8Í'9>ôªG9ü©Àw¦®r{úÓùhIÈëùP äw„qÓµ ß>ÔãÈÖä¶3Kô![$VSi÷Qó°ñèkCM¸—&)æ   ßxu/mšTgQÁQÖ°ô“ëÇ¥M0‰ç€:Ñ@u¿¯¢Nqž B[“KŸ­0'YF9Òù£ž™ÍW=±HN3ë@„£ð¦ý sÍT/ÁÆj<ñô  ¿iî BîÎ9ç5$ô©b‘í§VÇÍé@ ãß=ëBX®m‹"•{þµ_øRÅ5­¸Â™úl 8Œ· “Z§î¬–EêNø¨í™ÂX¼²ßß<þUµ!F„üÄäñ@2ܼªÈIµ,Mç§­i9àS H#"€3{:Lu«Íj¬I^j·–êÇåéLÛ°ö£€>‚œèÊ;àŠh㯥9H(x­*í’ˆ àgµc§¯\н§[Ìó—ªw'½t]ÌON?*»Ò–úuª«&2jU,7 j@_7\~µvÒRÓÝçéY*ŗ׿J³m£í>â€;[;¸ã÷‘0ü*úß[ÆH`ðk†MFDm¥‡Öžu˜ñ6)ÞM¾{ ¡S‰69®WOÒÖþñ¡žqojZG#$è=kgC¼k«A½³*|¬}}åüªNhVô=²âu8r:7µij¾&†Hã²¶ ÑÆð2ÏŽ9¨í侘e-™è\] Ñ죉<»4I Œ•染0RÜ*ÿ´i‰wbA¼½À­hÑPnnžô’˸;Ùr=Z¦ežñ±¹êhør]޽F÷&vÙ$Qo¥†Á•Ë7¡5¥ ´pº3@ ¶‡bnaɪ·2™Åºçoñ±yr#B©Ö™cU.~óu4}PGhT®:U¢Fð=5VSÞ”€Ê¿p!n¨ì¡Ûj¤÷¦_1ªâ8­žTz `aêò4û™3÷PŸÒ¾w”ùŒîÇ,ÌI?Z÷o\´¾db"úñ^Jž‚©n@Ç@0dRõä÷ô¡xÈÏ8¦O9ÅJ )£æbH=iãïçð þ/j\=hþ´Õ>´ÇJ^§µç¥rrqÎ(N¹èiÎqH™çš¾OÿZ€¾èúSWïëJÇfš99ý(cô¦÷?J_âéÞäý3@ŠC ÑÈ0J0`~‡5麦¦Ói&Dã }FkÌ:öç5Üâ]CÀ¶ïn…¦ Ÿ^)08¥‘ÝÙœ’OÖ–Þá ›ÌëïQº¸f.0Àò1MÎ=iÒÚ^Åp0žã½tvsˆ)lýkÎÁ+Êœ=kRÇR¾)YÀ1º•€ôHBõíÒ³579Èô5€šö®€ƒl¸k£ˆ5Å„R2arG¥ 9;„hä9LöéZ:\«ñ¼¿I}fç8Z¬€|¸¦J/ SœúÔ wp§å„56^js2¨'4€‰f˜’ÆOçMšv*G'±ÅT»Ô¢‹ýlȹ÷®v÷^,JZäÕÏô¦7W¦-Nv…†ÀÜ}h¬²wzžIõ¢˜¢6ony©¶sS‹f‘ÕâÉÁü9¤ mŒž´ï³…Ôß=Âôçi­9aŒñž” ]¿wi4„9w«—$“ÇåY ûØ geê@ªlầ5$䃴úÕläŽ0&¶G¹¶äçƒZVú­Är*’!8‡5®Ð̹àUÛ(EÅà\ïÅ '™žâs$ªô¨2¤DüÀ~5©-¬nNôSŽ‚«5•±'÷#s@>ÛÎ\çØTRÞ[”!S,G šU´€­V—E”—ë@~{wPy I>_Ê®¾’Ñç÷«ŒÔ §Î¤àéƒLÛÜý·íÊ‘ÈÍ\œ"< úníT……Ó€«tëV­´y‚°,þ€Råœvò~òBÛ¹è*êÀ§8Ú¬ÚhÆ5Ë.Hì*÷ØO÷\}h5`r-Dv²nÜEk­¬h¹9ÅBÓÅ `~x¤7°ó'iªífS†`í]–tlÀÕc"³3ŸJ`Vò'k"¡ýjôQ,…æ´­t/ÞÀ€0–9° {×oà+{ˆµ‰]²ÛœúF(¶Ñmm£2Êÿ(ç$×EáÒ\Ï*EåÁ·j9nzÒ¸R®é(IÇ#(p¢%îz'Ýør©M \Œ~µ Ïÿ^€Ü9¤DËfŒœTð¦:оêâœHši9p)·D œgŠ©!!##­eÝÄ*ñÚ´glíYÑ!’äzf˜Ö8†Ùô¨¬-~õ!Vr~U“í[¯ÄGé\&¿Ú´W–ð¶Ï”€ØëíøÐ€ò»û—¾¿ží³™pè;UkýËl¯ƒµð*yT#²`†Sƒ‘ÐÕ Ö?,y8⨠|ŽÂ–pÍíëHÆý}©€w`ãJyÎFy㨦q–©1‚hwF=èèzw¥9 ÏjCœýh J:h:QÔñŠNp¹£·ò£’9æŒsÏ&€¹ÁÇÍ8Ži>ÜRt84å=Fi;øâ•88¡²1Ïj ãäÓGœpWùS{P‡î.GëGB{ãÞ— ÜÓIäãéŠQƒžõèžœK£\ÛÌrçð#ÿ­^wߊéüx`¸»…9ibG¸?ýzL SÂqê’Mqlê»tc\Uî…sc1ŠT98¯Z¶‰¡²D5VæÕn’@÷¥p<…­XúU:êãL¸Á·Óž†¶õ½1¬®T“åMc˜¹ÀüiÑYø¥œí¹…Ñ–ºk¨®¡Ý¨Üt¼ìGÏ4«#ÆÙG*Gph¿ž(äS•ÄÞß\Úê3¢…Ú­ÆáÚ´´bO4Cpû”ôcÖ®êzJê æ©róõ‚5ëÀ ‹Æ3Š©6©}8!ælËÀ§½®É0WÓ½T ³n#uDGÍ÷N3Z1È8¦°ÚÙÎiOgªœ÷¢­0çœÑ@:•a–Tb? “ìÐÈ–øî=0 V;AǸ¥8\úR7· XI>â£û%±ê~lãƒWa‘Ü(dAÇ#úÔÆÚ“æóýÑÔPPÓ­O.¬=³J4ØÊå‚ö$Ö‹4jÃË8ä°É JÆX²õP9ѳ‰ŸéÇçUB—’²gž€WTªÄ“¸ª‘÷zS„hPˆ¢àrk¤Ý ÆñÇlUë(ÝË7ÌüóŠÞ1ž~Aõ¡’5_š1»\ ¢Äœ˜ýù ’Ç!]h¢f$¤zÔ‚%Uù#8ïé@¢“*TpGj¯9măúV¦Åq‘åA…1ä°8ô  \çùç°©m• G>„UÑa°ñw«hˆ‰•^O¯jdvûTíã­^³Œ 2]ÞÕ†oºäzÔëŒnP:àÒâȘê Ç¥6IS²œUo‘2|ÌûSGtæ€$‘°à88ªRD[OåV ®«ÊóI;J{бžI\kZÓCf9t&®Û«‚SšÙ´f ó6Ð=¨½®‰(>Hü©×&Ö6[[XÄ·-ÁTwÜÕö¹’ç6¶ÀdýéaZVVV¶1ìH÷H~ü‡’Ô€¡gá¸| ×“\ó·'h­ËH¢|¸™ˆ ŒÒ¡!W.ÿ*¹8—«Y_j“YZ0Ãfuèyé@gÂŽøqOA·ƒÈ=­5²ÓºñŒSâÀ]§•ííH âžqHàiã('µN0©žôØ“žh˜ö 1ónªó€Ò‚O=qV—ä‹5AÛ-#žÜ «tü:RXÆN9¨d%ßñ­+dØ”ÀŠíÂ@Ç8À¬¡‹ Èí½…lß6â‘ã;˜ U)\r¬0;ñ¿Û$ýÞÓò»ïvÏ&¹{ÌØsŠôŸéÁ%Šö>¾Gô>†¼Îfß#¶AÉüê‰ÉÏ9`p€q*Ÿ¥LxVéÅ0z6OáRF£Š”‚â€üYíÚŽ=)Çï~4ܾôƒïu¥\ž£¯j@HqÐ U9Î}hG@)¿ÅÖØR¿ýj9äRñÒwõ õ QÉÀéÖ‘¾ñæœ0OãLnâ€OAŽ”œƒÒ—§cý 'R =}hý­‚™ r”:ô úŠÙð¼âÛÄ–lÇ Í°þ"±F2?Ok/“u £$Šß‘ cv8sŸÎ¢-ž˜aOp$@Á°g ,grãÚ  ÍKLµ½V‘ÕÁøZ¸û‹XÖCå‡7Wze0:úŠÌ¿ÑþÕ—B¿¹àÓ02Fj›¨í[3ÚÉnåH"³&Nzþ”À©œ×I¿–H˜0dw®p¯'4KŽ{P…äÖóɾ$e'­R(3ý ɽ޸úwêU¶ÈÛå䀞ã=8äTuL“Ó=sÒ§h•WnÒyÚ3š…àR¸Þ£=ˆ  qâdVR=Æy*Û÷üj­ªä’Ã>¢µ'H‰SŸÆ€3®?w#¬î1L‰¼Õ&6#×"Ÿ _32ù„{ô§¢FÜ!Àöë@§Ë´çÜŠRyPì½3H` ÞÈ=hÛ4'þ>2§ "€o™ fC‘ØŠ¶ª¬°Øö¤T,ªAçÖšñ¸Sò’}3@À séV móqÆ1ÍW·‡ÌpÇrãÐÕ¹j€óÞ€+I²/LT2¢¨ä}*ÆçÙ’†«K)$¸í‚;Pw#8RIõëš– Hë×ýÚXÊ)åÀ©cFÀÆÚ·o)‘ºñ׊ÑVyÆÄ%WûÕ8"(8÷5­k€0â€-YÂñÆ«}M7TÖí´ˆ³q!3cåzÕ]KÄN€ÃÓ9àcœWpïq3ÏpåänäÐÍSÄ—Ú³2´=‘O󭯇·[»ù³›bHú0®@&?*ì¾B~Õ¨NWaT‹õ¨½,wwÍMœŒÎzT1ü¢¤S†š'C•æ¦EȨÑz0üjÄc4õV ¼˜ú –g‡éL·]¨\÷ ¹GÅf9ýÇ=X“RÞHÒ˱O½WŸæÂƒÀâ€oçÉ­ºœŠÝ0§JÛTó@Ó1{ÅÇð ÇùRΊWœsÚ’.d—Õ°? s¯™¦)ÀøýÒßI]ã’øCšò'8þuéÿ¤ mg <—,=ø¯/“î`u&©Ø”–Î*VÎÒqÚ›Àö´¤zô☎(þ!þM8b2EݽèN7qIÆz÷¥?ñíLäsÏ^”4ìIÍ70~TážGoZ2@Å!äóéÒ”û“IùP^qÅͦHúÒ“ÇL Uü5øîk2Ö@À†‰{{U-Üåˆü«7Á² Ÿª—ÃBå?£ùÖËÅ‘ô©™W‰€GÐÒöÎ{–« ›—#óÍ@ÈËü\{ÂÖ•÷¡ØõÍs“F `°Åv—¶«<'¦à;šäî`ÚÅO`Q0ƒÑ”LÓ‘ ‘Ó4ü-О٧G‚9性jiý:TŒ¸Á=)˜ëë@ 銅Ç=:Õ£ÔÇ\¼Ðv(§²å†?#EvFÀ8Úr:RH60Q0À¦º@8 ØÏÞ­68m·äÊ ¹¤ÌÛen=iæè²nMÀ‘éPºÆ¼$€LRy¢4Ê‘Žœõ ¥ÜÞaWÖše‘Y¤ED?\æ ówgäßÏjÊO@Fyf€-ÛM#’ƒëÖŸ&$8EǰÖ©´þS/ ž¦’;Ò䑞ýèbÚÌù`ž2zt«B#ü¤ã×­CÀ0Žxõ#$×[ $môÉ4BGO9†IoLP$€0%þcØÔ2´,w4¼·¾i¡T‘åøç  R«±%%Ú=1N†'+–¸b=…$kógc öíR9p¸QŒzš˜ÄHб¦{sH“¬ióséÍ3í’Coà Z·Œ¡ù±øTç$}ÕúÔ0º•Ü™aNg9é@ ààñÍW’2_8ù5&ッڛ»³®-ã?òÌgÖž‰)´u'ëV7^ž”Ù¤‚Õ ÉŒžÝèÄ¡w1 Rj•ö¶»Lv§êÕ‘y¨É3^ÐU%É^~”X œ»ÈY›’zçšcä í$}j"wœe¿HÙÉçw¯4Àº‘‘ŠôÛ´y'=n%ã?ÝQæMyý¬]]Emùå`‹õ'ëE”Ikú¸#¾øïøÒ`]2ŒÕC0 H<Õ«W ƒ¸"£v«1€y¨Ñvš|®"ˆ“Òå>mÀAÐri÷2aÅɵ Ԝթ<Ù¶ç@G¸üíÓ­4î*gåp8è)ÑGÈ42 /ªw’íŽx«ì6¦k"é¼ÛˆáY€?Ö˜ÛÆÑÚª‘Î2sêhÛÔzÕ·\Ž•ŒHøŸ#ZÞ$„Œ°üOÿZ¼ý¹!O­v'2x®TÏ¢¨Çâ­q€î$ç‘Çh #ã¦1IÕ±ïÛ½*£)8ó1éïL“ÚŽŒi àô£€ÙíšwVÏ\S1ÎGJŸåLã$€>”ÐyR/R;Ô`åêPy$PjAÉ=(ÏB1F9éŠNþ¢—Œ‘þM>céFprqÓŠPIÀ(¡–aµIÁô¬¥É9õ•©¦EËJäxæ€5Yø ½>ZŠòl RWj_Ü‚v;ÔŒÖuÕÓ»mEÜš@H>ϹS#¿­=.P6Ð:v¬Á6Ö_ÄTÈrsøäÓâÊû™‹Ÿlö©RgÚrÀ­QóWžçéNóCœúwÅ 'yçLãw_­Gö™bF`݉¨$B@\çך„#M,`–Áô4ÓYHV àwe²Ã%qÅAgiˆ×jŒ¹,ËoJ -IFÜÛž)†Q»å+ׂ(Ë1áמjèü!d[k’ƒm¼eÏsÀþµÞ"¤{×9ðöÐI& ™ŠFA=ÍvSiåþ5, »2¹“W¬AØ=inZÙ]~òõ÷«6+½r:÷  ¼þVBn'Ø>êò~µ-Ä…*Ÿ˜ð(‰{úúÒ—Rˆ¡**¤[ÜÈß­$Ìf—ã5m#T·9<ô€+9Üù©¡Jb¦Xšœ ©šŠáö¡¬Ëóõ'ôSVîßFitˆ‚Ù™OYX·áÐSvÕi>é>Õv@+:âA¼²ˆ¤š@|ýã“?е'!eØ ö¬ùS8<šŸQ¸7w÷ž²ÊÏùšˆ ©ïZ àúRd?JTåi1øãµ?§QÍÄ~´ÔÒ´ì|Ä~i„ŒöëOÇï 0޽hª{øñR.xÍDŸëó©TÐéùRwéGôëAFh=sš\sÛ¥WŸÊ{€¸9Å#r3Í(ëœþ9;q@äwÅ!á³J§Ü:PFâ 'E?1õ÷¦ôÆ)@ÉÆ€NÇ“J3“üéûP‹ šÚö ׬r+f½]Ïû¥TšòÐç?Zõm2â;&Ö\Œ¼kŸ¨â“Ç2;Tac9Ê€}éAàÔmc§åHH·ŸZ£,›p>µ&Ì)8?Zˆ'©ÇjÁÕ-ðÅ—·zÊ\`‚Etwðyˆy5Ï”Øåq“ïLŽ2üsHFiî˜<Ç4ÁÀçÍ;ëùÓr9ÁÅ6GUIªí8q@¸ÇqEW3ä`š(zC±@Öª y"­Éa€ÿ…@Ð2ä’?ˆ(ÿX½; h''i>”eWïœtÇJPªAÚàhKäœð1õ¨÷6<ÓYp~b@¤TÜ[xþõOÜpäOõ³jÉ ¤™5í‘Kr*Ë381t€4fÔQŸ`:uª«!bO\ûÕpˆ99£ 3³ƒ@@Éûœ}zTÀ"œÓ¹ªH]G#>Õ!¼*0WžÔeˆ$žF=Bó”[?Î’)RâB¬àzÅ[m8‘¹?@¢Y[8 õ«ú`Ì|ÕmËéM{ º•àzеe í?Äþ´¨d™HòeÚ wÇëKðIœõ T2:2ãŽi—‚Ûŵ@ i5íçÙ¢?¼ Øèk—º¹šI‹±õÅ>{±#±|­BYdþ®i€‰+¹8ô§+:à°ô¨Ê”û¿…*ÈÁ~b}¨g“nx<öéMBíÐ}iBy<‘C\a°x®hÈŒ £ÜŠSµ{Ï¥=eO/ï trE‚:@—Ãkýµwþ(ë†ã^ ãp<k;éÆMNçP V%O(}âpOäë^” Œç,mð$e= >(¼‡p¼îû zÔ®Š°èjpž@ÜÊGû£üi”#?7.~ñôöRî\‚¬M O<šÏ»–=OjX!,ÃÞ¯\*Ǩ÷¢ÖN@¤¹'Ì ö㊆1œñK+…\R¨Ø*¼Í¸Ð ×,Žý+ZÚ?*Þ8€ûªe2o¹‰=\ô²´Àk´×'ã ¿°xcQ”7–T}OÖ°àט|V¿òôeµ™¥çè´ <`ó ï¶žsM©&žÜа2Gzd¿Ö•G¢„è}sùМ ݨ¶{çúñH¼â€ãÍ4ÖéÇåO<Ì~”Òx8ë@Æ™Áç5(cQG÷Ï®jnç?΀ äwæ“¿4¹Æ ô Ÿæi¼{Ó€çéÞ“IÏçÞ€{ÐßpõéB”ÐÜÆM 8§ƒŸÆ‘>èçµ/¥!Ÿ½8}á‚1ïAê3Ÿ ¤ã'¨zbŽƒAÆzñIŒ‚hSÏøW xQÄÚ àÆÌ¸Ï5çéô®ÇÁsªÅs1`ãZL®EmœzSP²ÆA¥H÷cn7c×5\Íò‘×ð¤î íŸaQîBp~t¬é˜E@aŒäò¹í@ ˜±ùBƒõ5‘ue.òÛG×5ªc@2’)XÕ~l±h›ed$7ª²8PNy&µu!d$k›ž|³i€³M“Æ Sw$œŽÜSù<ž´Â9éLÉ#ž´S7…çóÅÖ«yƒ#ýjC;'ÊWœzñY!Ü.#ŸZQ;gM 4J‚}I¨š+Ð)ÏAš®·DޤR­Ã²ü¸É É“8 võÍ1•ñŽ‡Ò¦ºäÍ0³9ù“Zhˆ¶IÉÅL‘cÇñ¦F€¾1îjWŒ€ˆ{¯#°þ!ŠE,y Š_”g*~´àAÀy®8Žù£,,8£ rPdúæšT€Nh’VlŽ˜éSÙÞ]Çû¸_ð<Ó#µ•Î󀃜š$|‘)àœrhQµª‡BÙç¯[¨e/¸†=k´\Ì3¸à÷µ%ÚAo…àý(÷·_eNî#šç¦½’F%ëIy;NÄï$©÷Ö€,ÇûÀr}iÅHÆÓ‘P­ÆÕ W´á2îï@‚r æÐñ‘ž¼ÓPnäœñI»¶GZ{ÏÊôd•麓®1ëM'·ž†€'ÙOJ]Ùl!'€Zb2¯%¿[þ Ó£Ôü_§BÌ1'˜Ã—Ÿé@É¡hË¢ø~ÂÑFt§]†OøUÀ6­h02+ dšh‰-‡™. ö•G~Z %ê>âæj)$#,ßxÒÉ!b]R–C+`P%ÊýjxaÀɰ[ã’9õ«¨½¨…]T¶>QUùŽO|æ¯ÈJÀTOjªÀFž†€+ÈHU7<³+ç¥V—„4UX­Ñ „\~u© ‚EÈüAíYö€ylX¬$Ÿ¥ZTòÛzŽHÁæ€'‘‚ÆOµxOÅ-CÏÖRØ7¦ÔòkÚîîQm™É–öÅ|Ùâ‹Ö¾×nenræ©•+µycÚžÙ ?J†òåWJ颵†òA>£¨ªžCÆ3Ç…,dí?^µfçL¹€³*ƒ¿µVˆƒ=h[¡ô¡8ü)¤ô§ÂÇ­&|xíÍ#sœRÿËféÒŽ¤PQçqç58îy¨‰yíÖ§^ÿ¥íÖ…<ã?…€1Ò€>n£4œ“ïF9ãƒJT©4{zÐqõÉÀ§œìlt¦Fy9Ôƒ•n3@|(Éæ”uSS cž=)ßÅÒ€ú;ž”6ÐÐ:ã/9 ½r)8Æ3Ú“Í!ïýk£ðƒƒ©ItxCކ¹ÜcšÙð¼æn¾ ~tÞ½º¸3ãÙª Ÿ2Aõ«Lä#èj<Ä?„¯z+´~“~S>e<ʧ·Ý«@&N=ê´ÒFƒ%‡×Š‚YÝÉB1éX×w¬3Èü)×÷Ê Ã™®~{–™Ž>”À.o\ŒôªœžNAÍ)÷ïژʹ }i€ãÆyϵE#󎔀’ßZkõÁ?!¼Ô8d~£Ö€¬ç ôõ4ô”(ùÁÇó¦`’A¯jhBs´æ€.!ÀòË©¡²A3œ~TiˆÉRH9¥*A^ëUŒ§¸ÈõÏ"¦‚H‰ä¹ôç4`v 3íRGnø-!!ëVÄŠb˯Ӟµ]Ù¤ûÌ:ÅG,ÌÍ´ Š: TݳùUƒß…¨ä瞘  6÷1‡k~ó±5ZîwœüÍ=*&…ÀÈéž•Ö99úÐÊpzÆW´:IŒÆ•PHlÿJ¬£g={u¡œàíj½°5/p½W,£çµ=]Irsí@ ‘p¹ž9¦*0y㸫/!ù ü)¸RrÊ=³@¼Á’sKçÀŸÂ¦òŽƒü錌…ü(¼›Xޏ¦(Ïó•\==*-à·ÿZ€ªöǽ7iÆÞ1N.¤ó×=ûÔB×$1^F £Ô“@©ð{@”%Ö½(À``ƒ#“È,§ç^)•ÎA_zEÓ#Ñ´;=>„·Œ)÷nçóÍM,ßbԀȇâ¥çŠ@½€©•0iª¹ëN ŠP1š\ñŠCÏjaÇçJyã&šc 3ž(*ò@$ç¯J¤Ë¼dôô«N¦âå˜ýÅàTñZ<ñ@¢% ÈúUS$3Èû%ÂÛX.¡©¼Irš>‹u¼b%ùT÷n€~uæ^ÖßûfîÚåÛÐdË®9ýF*hOËÆrØ©!¤Ä‚qõéTâž%$yxìpù«|Ãòü«@LåÈØpS\Ší=è–WŒŒôô5SÈ?Ã×i˜“÷ÁãÒ£Ê8#?Z«$N:¯JëþiªxÎÙ™†ÐÜžØû¿®+œ8#S^±ð“MÚeþ¦Éƒ<‚$÷Uäþ¦†£Í0U8åj¯ç}iû×8o”{TñÀ;¿éP•#µ?¯ZjÇ×4üb€4ÖÏjv £hOsŠd§ ÁNHâÙ8Á5$’´mï@ †‹Ž§®inn#´µy¤`ˆ‹’Ç€*1&×ò‘·æ¼Ó⯈ÙbD·r7 ó{vÖ˜¯¼búõßÙ­Û19#þšZæ¬ï¤³»‚ê,…èú«ŽzQƒÖ¨y³¸·Ô-a¹…¾YP:ãÐÖŒªà9ÿj¼÷Àˆ¹Ó¤°gĶ͹}Œ¡þuÛÄî¹~w©]X¼g?•ejöæëL¸‰GðäV„$ºŒtõ¤’0 ã¯ZòIS’½1Ú©N›Tÿ…tõ‘³Ô¤^B¹Üµê9¦=yv8ô©l©#†®^AºÕñÛ¨Z’ 0:+vÝǽ]ÇË€8¬øm«Éj@K1Xzö‰Üfh€/Q[ÈØôÅ2à~´åOŽm¬0ÀàŠšÎGBJ·­ÄcÔÜ€yÁ¬å8~ýj€±ØRŒqL‘švFh}p(çuŸ|ö ué@ îÅ2#ÁÈ'éR óƒQÄ熀&ï¶:ÑÉõ&›ü‡½8uöõ ½(ÀÅòy¦äàçô 'Ž8Zhc€i„ã<Ògß4çs·éQrÏ#½+SH8Ïç@ œžhbt8¤3Ö€ŽÞ´ÕÅ)õÅ"’:\ã·3H;â”uÆ=é àŠQì:t¤c†éƒKý !Ƕ4¼ð1‘éE!éŠ(¤À#‚8õíNPsƒïMxŽ3ÃSpÀä- Ÿ—·áQ–cœ€§©b~`zzUˆíC4¤„>ñ G*X“³×ü*O60 vúPZW9'l}†8¨CõäƒÐŒu |­ëµiUF$AVÛò°Ç°¦Æú1>£¥7“ŠR:Ž}3šwÊÙ-Œþy§¥pN(0òBvàÓ¯Z—í2‡ ÇÓ4Ò8,xçÒšW##¦{š°“î~Ñê*B€”g¡úûÖ~Õ;¥>6d$ç¶Oj¹4u=~j®-]Õˆà^)Lä6Y¹=0iÂbA 3@5³F72ü§ÐÔ[ç tÍhÞ«‘òÔr[FÜ~€3Ì »Î)‹;0<~"®Ie¹r¾úT)þâ’(?1ˆä‚1ëPúš™°ÊíU[$Žzt  +#)ùIÝé_EøzÀi>°³Ç+gÿy¹?©¯ðŽš5_éöer0wì¯'ùWÑRœýÐíIa•²9\þUq1Œõª±©ZLúT0§þ5Œ÷¥#À\…ùâ<ý+ƒ ׫]@&‚hŸ'r‘^[r†)¤ŒõVÅ49@pWÛŒ¿,€wVÖÞy¬{…ßH1ØúÓZÙþQÏ àç­eÚŒµ¢‡$RÎì”âr¦ ¶3ÜÔƒ¡­sšî‘ö€%AóŽžõƼO²°ÁjôùSp<äW3­i©"™a‡¥40§ ™¥7Ö§–Ñ!²‚tI»!Ó1{ûcš®=zÓAÏáÒ—#žqLÞ—Ë·Aö !±É¨—ýs ‘RyÏÔS1‰¹ëŒñ@v÷§¯={Ó;ùÓùã˜ý) Ãô¤Œ ÔLø'šLóŒÓIç¥4·4tŠ3×@è9¤Î)Tàcµ¡éLžrz>”Ð8ÈýhqŸéH: r€HÏéNp@üè1òôÅ5sÎHÜýqBŒw •çÞ›ƒŸ¥JyçƒIÇ^ÞôÀ8¦±çŠ‘‡<þÃϽ!ê(¥î1éEuN£’¤õ§.vŽI㨒d»³Øw«¨RÕþe 0ì9ÛHƒM1¡–á€Uê ¨n%ŽPؔۙd²ó1á{ ®@!ϰ )¸ LØE'Ë’'¯Zz´{OcØÒÀá‰úƒÍ7dê@+žÜqLÚáÎüJw {-(Oî³gÛ½BXäðI÷§†ùs€µ.gÚrwö¨ |±¾(èÎJ“ê 8† Áù}±N.¤å…÷SHm²rÊAÆx Ð°Ç Ó‘“QòNA%»ÔþBí;eAßæ85 Ž`[n“ÎÒ 5—~Ò;JGÒ•£™$-³Ž=…FÎìs»ñô  D‡h]üc TñÎÉÉ€ü3Uß{ŸZv=³Ž´ugŒTÜÒyÊÃg'©ªœ$dúŠd`ç+ƒ@¥EtÈÚüë9à`Ùê*×Ú›¸5¦GêOjíþiþoˆ®¯X-`!O» k×å dnSíÒ¸„öžN…yzËÅÄø^;(Çó&»²rI qRÀXÕ×ø÷z°¤œf¡‰8ÇJœdö¤‚—­ §`Ðvnõ©R5NM0¹¨ÙÉ€"¹¹}Å"cÆ}*¢Ûm%ämÍÝ[?'¬ÍFè¬F8þóf€<ßâ•ÂÍ œ*~S#zàcúט´@ƒÔàzWiññ[_K0r-¡ Þ<šãÑúã¥Z³DWžx¨Ç^t…b #=:ÓJ/ Ž(¹Á8«zf¡.™}ÔG;+œn^â¢x@åIÇ|Ô&6úÿ*÷]êÚúÊ;øpu#Öº$ƒœú׌ø]kÿìë–ŽÉÂ’xWíù×­YÊQöæ¥j_ö¯5× òµyÇL¶kÒfÉtf pÞ0‡f¨® ” 9sÔVVª›."pqùþ½lã?JÏÕ¢Ýb”`i€¶lNßzÖEèzŠÂÓÜã‚8­¸O‚:SÒ‘ùSääTjÙâœ:Ò’yÅf^®cjÓcÁ¬ëÃò@še”×Vó*XÉ$K'.‘–䎇—ªhÒY±xÕ¶÷F0üëÙþ)6±6Ç}— µà·ËÛ=ëOâ?xÊûTIŸ§Æ!\¨;¤ÎqŽÝ2~”\›zëŒTÊÁÔqÞ½ûÇ¿ ìõ•–ÿIˆZß¹£ „—òèkÁ^&ž6rÏB 4î`䑚c¦ìààõœ\($š€Èïƒ×À‘K©Ã.{d”cj´9l“V‘œŠIzTf#š´£ c½H#ìh7Êo~zš gúVƒGÏô¦”À$þ”Ÿ°óýhØqŒ~µ{Éš @‚(‹´Õò*̉Æj¼P.F¥¾¾ôåN0?ýTݤŠéBœt攎3úS@äã·z]ß7^Ô3Áýi6܃HãŠyÎîûS{JG~sŸZ ¡¢”äž”P¢6-Šhd‹o9÷â«öòd÷©Ë>ÿ™›=³JÑ0ûι=³@ I5#-œõÍ8Ìv䜞˜ Köv8'¨=)¦"¡‹ºŒP²"=±JððÇcHÀƒ¼0Ï\•òÙ}¨sq™O¨lÓ VÉ!ýySŒñ‘ïÍ;kmÝÉÍ)1ã†ÁÇqTÈ“¸~éÒ“»ð«Z-‹j:ÝšŒ™¦D?‰çô ¡¼-§+ºu°eYÿÞnO󭘔¦° ’3°sRJ?ãSôÁ‚I­Hp¤ƒNçÒ…Œ “…4Ìži“0DüMHÍ׫9ä“@\-H ’{ÖJ‘%Ó;’!’}êÕüÂ4c’OaX~!¹:O„ïn ÄΛWêx¦ˆë·Í¨x‚ú猪f#éœÒ³ cÜúSœç&£n=j€“y p)V^qž½ª<玾٤ž8>”kÌP2 íB²ääôª¬Ç·ãïJ84eH È`rí^ËáÍcû[E·ºb<ÕýÜ¿ïÿ_ƼV7g¥v>ÕE¶¨ÖRÜÝ—ÙÇOÌf†®92ÛŽœñ‘\‡ŠÕž8À¹V®¦Ô팮r;W?âøOözν°ÜT 8ÎõÜ^mŒñãªT«‚§ ‘ÇLb˜öœùn•Ð@rs\ÄÃtñÿuˆ®ŠÚLÏëL ñç¾=i²qÍ"yÍ7ptÅ äsžk*ñÆ­h;vkùʆäP¤øìï…ÝÙ™#’{–Ž_kÚž§ð¯EðO†ÓIð…”LvÜL¾|ÏÎYÛžsíŠò†[õéô½"WÙee,—R/@äûçŸNžµô3))…m¾„ –EÔ ¼ŒŽ\g¾3º•些h—$±úšû/[Ó$¿Ò¯íã¹0<ñ4BD'+‘Œþµò·ˆ¼­x^r/m ÏË<20úöüiÄPD«–rI ô#°íV õéŠˆŽ§Õ^wpjÈ?7aíUÐþôæ¬(ä:™r>•(rIM5µN#Ïz@@ÍŽ*›ã÷«R/|U ”œƒš•.gßšš¤g5Ÿü>”¡›?J`X•ñÓëQÍ7“ÉéH£犔ÈRÐÓoþ½ ®Gšy#æÆi½+ÁÊ·±éLVÇLƒï@ï×­&üO&“ ãšÐ±Æ8¦¶ 8"”}i¤ö=>”»xéE)låEuÒÂi·#<þF‘ì#œžÃšµ2¤#.w6zg5&Br<¿Çš@DB¦x9<£5"Ú€õûTÇlhJ°ÉªítHP3í@ ò¦0˜‚j31iFÐ1Àõ§G"Ê3±²U©bdFÁÿhÐ"Œ.ÈÁ¤Ší€1þõ8!ˆqµw¹¤,ÿÄÅ€éÍ@ö®ƒ'g­E³fÿ—§£U·óe\1$Ý)¨_lPÆ]~ž”»ƒ7%n*̈˜9Æ}‡5·ß÷1ßÖ€#>H FIö5awà±Ú{fŸ%¹O½ŸÊœ »ºíDXáÔž‹JþKŒ.sâõ©¦Œ;nŒ…\wïQ"(‚IàP{vã¿ZPªÇ<гåFTœÈ¦b-½9Ò€*ÉÀ*ÜÞšêázýjÚ¤a¶³óÁ¨çUAù÷ŠÏl–#Ò»O…–lñ”s-biO±è?qáÎOë^½ðLû>}©2àÜ8 ½SCÑIËŽç5nX‡—»Õß¼üEj˜sP5LTÊØÅî(ë@«dÐßZ2žíêh§¹'~uZyQÝ*VŒ¨ÜíÉì*ѧր)7×™?êãäý{W7ãé÷YGh2}æ~UØ'—&4<žIõ®#ÅP5Ë4žfq×°¦€ñ˘Ls1ôéU{’V¶5‚LÈH žO­gIRxÈïíT×4›WÔæŸÀ>Ô™^ò Æ;Œšã­#múóGQL ñÇæ*h%x&Icb®„#±ÉýzQÁäŸÂãá}]5&;… ?Ý‘}u­ bs£ÜDã9Jò©²ÖþÈì|«¡€ þ1Ò½ne߯¨©ËUvaOÒœxRMMqŽâHù$1Õ{‚#ŒŒóLbìˆõY@ÇukÛI;÷¬mM±:IÓœUûFš`n£ñQ3d“ü©ªÅ^3Nj@5œœóYW‡(ßÖ´˜óšÊ¼ †<Ó°øwã{_ØÎ³ØK=Ääl}À(AÐsÓ’NkÒ¬¾'ßÝ,7 ¡c3ìY㔞ãПƯxGÀ^—ÂZD×tW25²HZRO,2x®²ÓÃÚ=„M¶›m|ü¡8æ¡´4ÝrÇYY¡·f[ˆ¸x&\{ã¸÷¨µ%’&Y­b‘m`G øVœvv–ÅZ+xbØ ©Th=@ôª—·'c~ì°RɼKðŸIԷϦ•°œŒí@J“ôíøWŒë¾Ô¼?rÑÞÀBŸ»*òô5ôýÄ…ñœç·Jæõxo#ò.9ão¼Ž¼©0>dmÁÕ¥ ž½k¿ñ_õˆK¡‡uNdµn ²¥yà!\0sÈô"¬ Q´sùÔ¹Á<檣äqRáŽy¤r8äÕ ÍVf!j‘#š`ë“Í*©4ÐÃÒž¬:p1@Û•¤ØvóŠ”tå@G4 G™&µ--ÑÈÈÎjŠ® hY\F¬qH #aGœʲ¯4õ\+y'‰£ù\V}ìªç­sL…Ž~¾”À>¹ÇjA—$ˆ¡ÚrqÏÀˆOZBN1‘OÚO¦0Áã¥ã¯oQE :`ö¢€;“‹ê¸ôꉧeoïzgš{Äi„„ÿ© &(Õ„X-ÔŸéH ¡™×ò« ¡;”àzŽ*Æ[¸ Š{gƒÇ=ÍBwþÎ)Âáv0Ý鎔æ¶'»­*@«’Oáé@X…,Ê0xâ£É,IÉý*b÷ŒzH±Œ“¸sÀÀ FË»&cïÞ ç¦9ªá lñéR£ ¹u}h Û†2)0<óúTÂ9$òqAœ àçž›hpÙV`}03P˜ÿ„09ô5'šKœà qž”ÆØX*öy4O˜Œƒô¨$æAÆhÆ 6Aõ=©¯Xÿ«\zŠÌ$d žœÒ²gס«²ÅæH«WíM6¬pY ûž”T;ƒÀǧZ¯9ÉÀ'õmâmÜG°¨'Q»h_ÌÐQbª£,ØzžÕôvbºO‡¬¬Tb‰C{±äþ¦¼WÀúDš§ŠlWËf‚)’68yý+Þe|¿4˜îýçå[páíÿ Â#2u­«&Ì#éR xjMj˯z† &6ŠvN{ÓœŒrj»;ò.@êh;»';¹n€ É)=Ãç8°«ÞY¸œñÏñ¸–ê¸ã¥g‹V†Ýœœ» (÷®KÄ‹"ņ‘€ƒúWY©Ý8•V,e9ë\ˆ%’t¿*h2Õ0Ó’ÃôɬVGþ yö5ÐjKÉôÍe¶Bàžõ@g´@Ž3š‡oGçZ[>nJŸZŽh7Ÿ•pÄv  è=h8=©Ì¸8#½"Ó½*Ó³ÏLÓqÆsøÓú0è([I%†î`8•#×5ôM—ïôôÆѸzâ¼CÁv+}â›E”f(ÛÍaì?úø¯p[o³«,3"B )êsÅ&â-¬®6€®s\UÜÙ$g>µéþ*ÿJÑ' d§ÍÅy;üÄsõ¡Ÿ¨.ëWaŒ©Í3N— #ñ«í ’OPGJȱm²•üéÔÀç$ö4÷aÖª@øÁç©Ù¾AȤdbNf]}Ö"®»qÎõvÙ ž¼Óë?¨Oh tû_ú­K—‘"&%Ë/ñ¬Ï |!£`ÿË”\ÀEj±Tä’GZÌ £<Ïj$$ œd¦â+2âqåòʃÉ#žkbîëŒ*çý¡YRÆ0Ò»F<Œu¦;4¶ï!RY›ý¢~•S c‚½ÅiÌ` û¨¢ GßqÍeO‚Yge^Äq@%3•ž\ p¾ ð=±Òd’Ò&(ÆMÇ’Äœâ»ÖŒ¯!ËÿµT. ì`7aŽ´Àð0Æ&!¸ àƒV„ çžqMÖíå³Õîc™Hrå¹A5EK3eAéV—dàÇZ©“žµ1R§-Ž*99Á õcŒv¦u˜4 pYŒåy­F»–©¡M\‰†=q@ åŒç• ‘Š”þTiÌ>ÒA#éLç8©ø ÿ:Pí@DyÎE!ˆàúU°¸ííFμb€(˜‡n1QŽî™ã¥ilò)¦1žŸgˆ8öçUæ‹‚h¦ØL“Ÿ^´ï*@~ÿO~•4VÈp]XûÕnåPqßÖÕ$Éã*ùà•çš™’B?…AôëAÈô™œHR­ÀÚw‚01ó”¬j¼úrjµ²ò  Õ£` ~ž•*$+“žÍVŽ5àœqVá’†1†ö8¤SC½s¸z1QãË-òûb¦ F8}ÙàcŠhØú¶?…0æ:T÷É㑜gæÀðsNfŸ›pÇåQàùe·ž0hVXv‘½FF1š©½#?(qšX$RXöÅ;ËC÷Âu€Ì y›ÎOB soåòŽd Ëç·µHÍhfœgœÔå’ÛsÓ?{  Eâ/ÝVîOjl’‰Šàm$ò9¡u‘ˆ+ ÁÎ¥8DÝ\ªšl²*ÆbÉÇ\jøfãÄúÒÚ[‚±šYHáüiÐÙIys ´¼®B Çz÷? xzßÚBÛD™þi¤îÍþ›ö-†…a„+"å›»R}i$-ëš½6G=r1U g޵ W ûß¶,ÏîEeùÌ0kFÕ¼›œô  ÙȨde\äÕ9/›¢)"«4“LqŒP³Ï–Ú¼žÔ®%ŽM:Þ%‹ænZ§œÉ)EÁ° íâFIêi'—b“œ`Tæ?-NMdjS›7mÝßÚ€#I£3±›žzÿœW-¯Ý¤‘}^šê=Ù’E_A’3Xz¼Ê¸ ÇaLQ;°F}«1‡^àõæ¶/c]ÎGZÊvN'óª ¹\H¾”²@Ê€¹ÅJ8éŠRà ã#Þ€3¥„?8Á•Vé‘Þµd#Èê*«Âœ|€*€8ç&Œäã©Å)]­†R(aÓƒí@ÏÃQs©êXÿX¶Ù_ûèW Á4‹&ÇbGð“\Âivø¢x²ûfãèA¯M¿ÓYYš1Á9úR`GqŸc4dgr^?$-îÁSƒ^Çe.u:á—×½yÇ‹m’Ï^ŸËÆÙ0Ãñ¡‚Åcʹóû«÷\7ØbKsŠÉ¿_.ø6>ð˜0I•¿µX/òÖe¤ÃŠ¸ÏÆúÐöšÎ¸“vzûÔóIÏó¬é±nÔö‡#¹ÿ„GCXdDÿD‹Ì, 8Ø:{ýjüö³yžbÎùèFxü»V„®¼¤mä­”YÏû¢®É©œÅVP99å~¢³ÕÌøLnv=ªŒ—1¹`çåçþF¯N\¡I•Y‡SŽ+1 ´‰Š¬„{nÈšÊÁ(ŒŒäô¬«ˆÓka´+FâHñ’[Ço²çH]AL£w&˜ž@NN*”͹ˆ¨=”ž¾õné%Qµ]j…Òˆ‘¤˜ ¨¹Ï^(ȼ_1¸ñ$ÿ0ù0œwõ¬¹à {U‹–ûUýÌýžBGÓ4à„ÌÕŸ*8ãqÖ«ã“×ëWgºÕ6=y¦{tüéÊ~_Ò›ôíÏ)*™3žÕzT`U‰ÈçŸzÑ}ÏÖ€% ×µ}yô©U})¸ö¤p(Ÿê*E_—§4¡`h1Æy¥ÎEri¸ã¯zpÎiØ¥¯éNÁÍE³ÖŠ”®r(  é$ÚÙÇ>ž”®YÐv^ÀPÐ3*ñþÝ8¼ ‚ax;[¥ *˜ß”tàÓ¼ §Osº­M4ríØ†5·z#·¥ŒŸî‘ü©á€U_vô£`î˜ëN’Ù‘( ¡Í@¶$’ÅÁ'žOZ™š0g'§Ò– ›ñ•'ÔTBW£$ž›XSÅ¡\mÝž§=¨}ÉÙ°£Ò£Y7·îØàu9¤ò‚š7ÏéJŽ›Kº=ÏZ@.Gñtâˆã‰¦Ë±Pz`Sò®ÃåâœÅrv†€XáÏñ»ïÓô¦É)È^£‘ëR BávsŽx¨¥Ëg A¨§fOÈ'Ö˜ÊX£ánlu `™PªŸ•ÕF+Ðñ]þñ²öDZ¦„`y°6ÂG¸<~U6×g Œ yî‚ý³žPe,`ý—ä×ßlîn’3–±1ÃÈWqØ n·ñDµ‰¾Â$Ô&`ylƪ{z,m&Õ.á×,úV4ñ´¥ŒoÐãïW—Û|HÕ ™å™Wv|²~\zg­zEž§«§ÇwjO’ãžAÚ}¡¢À«mWÞO©®ÇwòéºcÀ.šàí :mï]«xš|RNó£œgŸ ¯!×µ9umA¥¶ÚŠNp) #µ qãHÍQ‚UŒOn]O>pvDئuÆÀªMÔõÍjËhȦIHV\‡©@}=iWØóŸJhïÖ—<?Zš1óg¨÷­+qÀ¬ØóÖ±ÀòhèüèÆ(F㎔»‡Ò ::ÒñÉãð¦>”ÍÜp(Xá¹ýj"A╘œQÎML¯Ç_Ƥݞ3U7`úÓ„™9ü¨Ë7;QUËäcó¢€:&pÄI튕Q”.1Rg‘´qÏ$Ô‹ÈÁÁ?Z@BGNN9# ÈÎHÎ{gʤ`£¡#=qÚ“rƒ€Üz‘@‚@øäç¾j0Ÿ3d±ý*C>у“ØSâ–F?;0ç®1@G±ŽKíÇ9sÒžÓ*°ƒUÎ Gæï¸U&1Áu©Z5Cû1—9€•ÇCƒÎ)øR Üpj®Ù¶–i•>@ÄŒOÍ#¤¡²¿潺g'Ô-ŠÉ€¡8ÒKóJ:íƒ@ ÃŽ@fèJnÕo\1è|þ€“I6Åõ'ŽœPÌ2ùdIaÍ&U² {ä k€Cìc4ëI'Ô-¡„I2©ìy<ÓJËÐ7Ê¥?FšfñˆU\&:óL¡Åºµ YFÝ¡›Ò‚ãr ”ˆå9ÈÍ@éÈÇJ³ b¤6€ž:Óã¶8Á d†9— Ö]Æšcù“$zzW@°¨êiBÚ€9ui­V"´m/R@ëZ’XÃ2£šÌ›NòÜ2pAê(éo’p+*îçs´ë»´U(§²$¸P 1}h bS—rû¹“ŸÂ¼î=EZ gÕøU¶]&x|áæJ<µ“ϵyÉ…K•ãûÀФû‹€I!³T%›,¥'Ù&“˜å‰ûuÅ*XÎr²-ÛçÀ¥$ƒ¨wÇŒ~µ Ö3’HŸåP)€%¢n=¸  ÉÈ<)’sœ~58µxÎ6žh1™ÆO¿“ÁÅ H88úfŸå“Æ0)ʃòŸ¥1™ÈçÖ²î"1ÈF~„Vª¹V ãõ^hÖEÀN;Ðrž9¡¢ÜMm«ÚI‚e”öÏ"¨24y ©ì$ lÞ’¡ýhéKÖ–Õ€/·š§}ŸÑ7GR1N±]ªr=)od*@@YØpHwŽîTc÷Ö³õ y g£zV¾± ¦¯v®6‘)ÏçX׬¾P\òNqTKp ˜èjãpµŸnÄJzUÆcÀã4c-UÊ‘+ þuqžƒVbcž„PT(%‹*½1Ö¢ŽR¹ ÐÑë‰ä^qëI2.I^ç8=¨O8ÀQ‘ß¾)Ì0<Œu5]Q‡Ìp*ÈrSP¸ÆME™”g“^Ÿðýn,ô;›‡Ü±O d¸®wÁþ ºñ ‰Ã`§—n²}+«ñŽ¥‡tô±…•eeÚ\m^”€æC·ç¨<Õ…v[vg””¯ò  B'Û…l‘èÔ¿:²¨l±è=)#–G9*¨äµ2N›@ò×̃é@ Ý2ªá?5ïP geÉޏ5b8¤¸a¾b ä›úV••¼6¨ÞfÙHîhŸ1M#+¾sõ©cG€“ƒïZú„‘0"Päf²_qÀc­1É-” ?•1€UÉbOqVW.pNæ”G“òmÈãÓ4±Ò~4CÄK3ê JcU$œÓpi\F‘|à¨õÆEU¸–(Ó1ïÉê3Søze‡^±–E`žhcøñõ SQ±Ôæ¶f‚â Ê;·?^æ¼Æò÷RYæ·»¸‘dG*Éœ`Š÷YcFNzZòÿè;„š´d.ÒAê3€~´Ð˜‘Âù…•™zdäš‚Yå³!P£œŠ­¯ÚDeÛÞQÏåV£e´™·‚ñò³'&¨±P1ø˜¡³~÷1C°ñœâ;–ß&Ü çnsí@ îÌø ·º§¥9$t U›óªÌÏ»Œ·®œCo^¹:ÝLÃ;Û'µæà7,½?»šIÌ n ÀÁ<ŒÕu.:«zuÅLfnKˆÏ¶Þ´žr8dq~Æì φ¢UdéÒ€,Ÿ%ÎL*}0H¦·RwFãØ51£ãt„’?ºiŸ þ#ìh&†ÍÆœ¸Ê1ÁäŽ9®‚xå8'ƒÓ5•}hÐ>ò>V=hÝ´ Ã}¥Ùʤ6%'¸æ¶žÝQC®Kt$לü>Õ´d·2Ÿ2&+·=jïÌìa;ÜmõÍHAãHŒ^&ºÄ7õÉß…ã-žáÒº^Û¿ˆed•NÐ>õÈ\²Ì!÷úÕ Œ‘0=³V–E yüªž[~Ö©¢NCž½ie®D`Œej¨ÂiÎæ.jìaK—ê}MH‚õÁ¤nŠŠÒ«K/úCœ ÅYcåÄXžÜVn>n§“šÙ±Ñµ Så²¶’Eã-”~5Ù蟺˪I¹ÿV½ãT¼/â[}2+[缉ЕÅ‚ gŒŽµßiéöëa%¦¬ÒÄOÞ‚Gך@hZa “0¨À@ÇÒ¼ÃÇÆ;y¥iw–^=1]ýÍ­Ò¿m1Í?θèS3%ÏÚbf=àšòÃþ‚¤ãƒŸ¥M)Tž+…ÿVÀRYéWóÛùb }[_ߪ¬S@Æ3Ée àSkx Í*‘øšª4´vfm_ï7ô®ŽÛNŠÙ~h$“«sQß4b2©§ 8ýR4Hö¨À¹öÈÎ oê¤37Ïž;b©ÓÐæƒô¥ç=isÞ€%“ÏJÓ¶ÆÑЊΈöó5¡nxç¥^ãžiÈ4¡³ùR¬2*,cÒ¬GãM _o­4©5h¨?Z®àúPgóMã#Ö”žy¦“ÏNhܧ½™¢€;RÉ´º¹ø¥D##Ÿ¨5èÛ?uNxÇzpp¬WpéÖš bÜ IíT^&V%çÒ¤d gÍ ‘Ǫ…Ë.Gq@¦Fà®qÜÅ"ï®î=)¯+F¥£çÐóU„Î$ääv­0._3“&ßîæ—oÎÁ8¨a•CÛõ©#Ë7ËÆ{´f.ݶKv9éCK(BRF*OSÚ¡q ¯9ÁÍ<ìa‡ÉÏ ÌÌF×%Sš•deÈyô¨$U‰pNŽ¡¿JEÁ Oc¥N›IÚÁ³ü4הхÆÞUÔNIÆ3ƒúÔçMž8ÌŠ7'|r(ªJÜ)âPGù¨[“È;³ÖŸ!zž}(Ñe*sÔU}˼öëNÀ äŽô˜hòÀƒ»“š²¿dp¢BËŽ Š¯uÊ!f#ëÅ4Ú “ŸáÅ( Iyþtˆ´œôÒŸiÌgOõÇÖ¥ :sÀq§'<ó@'‚çM¸"9J¸ƒÄئ7ˆµ—CêwE1÷L†®N†XÆ}ÜŠËž 2çÊS´rAÅfÈÏ4¤–gbz“œÖŽÍªª:Uì¡É2À8¨±g“Ò€ Š=Ï’8÷¤ò S´àÒ®¤Xc·œ –8=Ídù3!ã‘íW-…¬6þeךÎÌ@TÀù}sëš¿ä ôÆ8ëQ=š¾IÈ9  šŠÄ"‰ 2yN27®zVY9bzU›Û–žP¸UQ¢ôYÙö…Ïz`jià}œç®kNÇS¹Ó'ÙLоz¯¨ïY0Êc.ÞÕaƒ«p$õî)èzGŒ—S" @ˆn2p>F?ÐÖ?ŒËɨD s+”UòzÕ©¯'ºˆDäÈcû­Ž@ô¢À\Óµ{Û]fô®’ ~ÖóäuÙ!ê ®'súqNÆ:õX@ÚïÊ;Ö}ê>ÒsŠÁ³Ön-@VréèMkË©Çw(yÇ úÒÖ‰glôþuÎw9é]®Å‰®{©5H'‚sG¦?*9¢Šq88¨o\Ç mãµP7“ŸÆ¯Ú·—B®[©"Š)> endobj 2334 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im2 2332 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2340 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚe»Â0C÷ûé’8&Í m Eˆ»!¦"˜*Äÿ/´ˆÁdÇÇÄÄVÖ*¶ÏÅ”äô†Bd6†±†^q^mƒvƒžª‹îm_û/4º`ò,z“Î-Œð£þÍNå)n®„[^’§a“0NbwS@ûãßèçÂ#+ endstream endobj 2339 0 obj << /Type /Page /Contents 2340 0 R /Resources 2338 0 R /MediaBox [0 0 612 792] /Parent 2168 0 R >> endobj 2333 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./21_home_taurel_tango_manual_dance_Ready.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2342 0 R /BBox [0 0 468 59] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2343 0 R >>/Font << /R8 2344 0 R>> >> /Length 158 /Filter /FlateDecode >> stream xœ-Í ‚@…÷÷)β6·™qþ\…A¸+²yQ3Íß¾)å,¾÷ò‚%Ä/+«Žv…Cû"ÍNieð¡ÿEN2aëŒGÊÂç¡­öl-ŒµœJŒ ]×ç±¥äÒWT!Ê=”Š«n´ŒJHωÓJpDŠÐÑ&Ìý;jËzÆÔ£.ŸUƒéÞ d§üŒý6<èèó}M,¹ endstream endobj 2342 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152422+01'00') /ModDate (D:20160114152422+01'00') /Title (Ready.eps) /Creator (fig2dev Version 3.2 Patchlevel 1) /Author (taurel@amber2 \(E.Taurel,,,\)) >> endobj 2343 0 obj << /Type /ExtGState /OPM 1 >> endobj 2344 0 obj << /BaseFont /YSBIGD+Palatino-Bold /FontDescriptor 2345 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 444 0 778 0 0 0 0 0 833 0 0 0 0 0 0 833 833 0 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 500 0 444 611 500 0 0 611 0 0 0 0 0 611 556 0 0 389 0 333 611 0 0 0 556] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2345 0 obj << /Type /FontDescriptor /FontName /YSBIGD+Palatino-Bold /FontBBox [ 0 -266 798 720] /Flags 32 /Ascent 720 /CapHeight 695 /Descent -266 /ItalicAngle 0 /StemV 119 /MissingWidth 500 /XHeight 471 /CharSet (/A/G/N/O/T/a/c/d/e/h/n/o/question/r/space/t/u/y) /FontFile3 2346 0 R >> endobj 2346 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2228 >> stream xœ• PeÇ7…dW¥±Gf¬¥!Ú;EÅÒZ[¯ê•ÚÚ³öZª-" $%(°å34É“l á«MZ ¥V iŠ¥(•jï¬çôz§­õô¬§ÎÜ8:Þù,ó2w÷ÆêÞÍÜÌÝìÌÎλï>ûžÿï}=‘ÉdÊÍy¦<‹±Ô|Ïj³IYI‘ʤøyÒ¢( ÁÙS³:ù"fÃÁwæCLÄDŽ¿99G„ž[±v%“Y¡+Ý\V½ÛXd°h“¶elO¾ûî”­Ü¿bÅ m~õwo´kôÆ¢Rm"}¨Ò›Ìe%úRËCÚtºÛd2h‹LÕe† mžN§×E>ËÊ3鋵k&cY™¹J›”ž¬]’šzÿ=ô¶ŒFÔRù¦<Ѭݠ$ðÃ%†ab^jÞ½ÎR™W] Û¨ßdت}„aî`61›™L&‰ÙÆd1«™Ìæ1æ>f-“ʬg–12F˨hy˜h¦_¶JÖ¥̈AÿI[@:”Þ™L·ûÉ")Ã{ÉbløâJ÷8Æ$àrú<ž°Sâõšd×Q…W/ðMÁ= öZ²Ÿë9›€e}o…Mþ Sâ ro»ºÀjª{Ê*nwY¡ŠÛĮϕW²=rÒÁ. ë?:Þßðk(<5Ÿ<6†$.RÝ ÐêH…s¤ø÷ø–åªDñ€ÀÂv8N•ÓFñ<¡òŸ,H2¶¡õ±Ê]Ô‹'èE*« îÈÍÏʨžÑ`×·Ûjþݲulâ¹Ì™cG|ÝÝT½æ£Õ!)æÝتeÞ§²â+oñ-ORÁÛ@+þ+Šf=o=Î 7.+=-íÎ3Â!Öù‚súà¨ë×IW'=PmÜÇ›¦óòë-…š¬bùZöùæÃ“bÛ@ÛQÞ‚ŠÄiÕj[ž£ƒ8UçÊÑÜ+‡x|íš?a o-/´–Wlí;uöPèr0a¼CNÉ&Ák2œÃQ8 ­àORÔˆšB±ja±HéÙaG·³£¶[/à’¹$K¦%Ã`4‚PUË‘úýêꔣu½-½ ü^=÷2ÞŒ;¥uÇÑî]â¯:ð^Ï&×f÷7ñ=Î@Ô `sÔ;Z‰W½KÁeo³· MA»Ú¡3àïvqJisÍeüü2ía\§J•nÃI¾õ¢wÐÿbs§Zu©ç™*OÑB=˜›+ön7©—d? K9’vm).ž ûûÏh½ÔØnÜ[ÙR BòÆk¨útèìÅñ‘=1¡m“<Íg+#ÐÄ]ćOÄŽa,–F¨ JÞÙ¾©5½²´ÑhÛb£6OÙ;= ›•ìŸ9PÖº„b(m,«IÏVgèË2`G¿Š7õöDjþÕ‡rêõ£ßóZ•è¾túà sÀÉ©Öþ'ƒªQ^às² ·®É¹„ÌÃ/_>}bOî †žßÚPsXú:‹1¯Kæ×#8Ý7»’¯R4Â.W†›+dÃöñý¢ Ò„¹Òì¶œý…‘Ž>C;G¶É—œ7+sÜ>xQsx¢®;»¼¤±„í°c`÷éÚ[¯ã ‡qŠó0Þ:ÝÅ‘¢çùý ”¹žs»Ôâç}#¯Áyè+p'q?èið®(iõì:tõ¢zêŃC0Íͬþ%‘oÑÕeiì†fSåãœêCL!ãó õyù' c£á££…' ”{B³«B[Bг7ã­·œõÅÄà­¡˜ù óe%Í9 endstream endobj 2341 0 obj << /D [2339 0 R /XYZ 89 721 null] >> endobj 2338 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im3 2333 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2354 0 obj << /Length 1983 /Filter /FlateDecode >> stream xÚM³Ü¶íî_±·jgò¶úXQ«Þ\×vŒÛL¼“KÒŸÄ]q,‰[Šz¯›__€õ±^;/¹ˆH€ ¾(Þœ7ñæý«˜Ç¿_ýõ]oÒx'DšoާMoDœï2‘nŽõæ—èM#/NÙíCšÇQ²ýÏñ{¢ØïŠC‘ E¼yØ—»C’Á‡ÞÙmrˆL=VN›~"Iö»ll=I^&IvÉö!‰ãøKb¬34Öj›äÑ“®ÁÈ•ÄÑ~`êÊÓM¹+E*øœ4Ý¥¢ sþ¡¶éL_ ýrTv ij²¼ôk§Û$²ƒ#¸&R¿»5UZò²k˜îíhaUö}ºöUc³†VÖZ: œæ²”•nµ»†£óøí§ŸÞÁ˜æd,M*ú1m«û3Þï—$»2Ïé~$E|ˆ ïYh +YâIaÝŒ¶R;J=º6ÕØ©Þ°’†­9[ÙuÊþe›çÑ@Œ?Ê~”-í܃¢<àí ã³ÕŽ%>nË,zý¯÷ÿ¾w¯zi·ò°´È»ÏEôÁÑʳnñಌzè³!„îý±€!5ªVNêv ¬9’WÚà»ÀÌN»0oÈ„ýtœên¶‚€ˆWÂóÅÑÃEU¬úÝ gñ£¦xZ ~0™å€äÕdq¦ä-°¬ˆÚK㩽=a¶°2@šOñ ¸Qí…f—ÉàLxÂØ“• xÖ®¹‘ÌÉáó½;z! ˆÑ П=0»Aøô&àgÃ#OÈ)å~¿f¼Œò,kå!¢‘Û4æX&Ì£R=ÍîÄ9¢1Îqô·Â :Í4S[cšô» ŸlÚå)q'‘W‘Ÿhœ ‰rðW}XÝUÐ]Ÿôo ‘£a(7ÖŠVI´‰ÙûšP!Ü&œJ ͽ•çCGˆ…Öy‡÷6ÜAC­gõ#*qtŠ™“Ïå‚}ŽÄzl}hà-ŽüïÑ/L}ÇY‚¼YVxïÄÑôí•fiãN4’ªq)€'¡…‰-¦-:/bÚ3jûÇ8™f3x—F”œV|ä|%uŸ`MQŠ„€2½"?PæÏrâp+ýóxVöc÷¨x‡p+ë!bŠÙš6>^ e±`y˜XðlQNɪ¡‡ÓW.VëÊs‚—Õ§ˆâvcáB6ð/üÿ.ÊjÕ‡¨'Æðw×V½0ð³ò&ðqø€áÀ‡‡ €÷¬ Æ.C¸gÁ"¸‡†¥ú|B$Hﮄ ¿)oõàQ³¥¼ ‹ +vׯg€“5胱OŽŸ]œC… h¶v‡˜Š©,N¾\€RÙE>Gœ÷ñ¥Rmý@A»âGêŒå¼\ñÏßÒ¤’¶èT¯=@ýøæfɳ»ã? -틲D–SP‘‚„ÿõ ¹z%J?¨Ç¬ØsþA …’÷‹ÞÑCذxa<|Q=J„{Ï•(º=Þó`^ôÆÁÒ8,* X° ij _T~¨nnõÁ¿ßC–Fƒî.þyd%ÆJB¬ËdáØ´­’Ìî‘é@žš0„ièa˜L&ÁeòÄB¬;SÆóEVÌ@@Óuc¯+éø<ÿìßKÛ¨òAuhaéë«ÌL”Tûúz ð!EÛý¥õÜkZZ?HE(.V+´°Ò ¬“f`á‘ X37€aÍ,¹Î>ÇÂPV¢ ]pýÄ¿W½aû¢1ëG”ðè’çÑʹÁ™2ÜÚ¯q»/"«–Y=ªFO{CMäÖ)´ÑçæN¢ Çwœöò ]3W¦âg×ó„U4?á'9Ïù¡Èç*ßo54rÙÓEy‡`ÕjJ†0Ç®r‡·;Ü~ îW¼rp²Ô+ÂëüŽ'ùêgêëÓAi®…>˜ð«š ·ô*”CзbCJó[”Gÿ¦‚ xß š2º;#þ†çO}ö&»}v9 7MYÑ¿¦i¾ÞõËCyð5q8+7×ŃƒB$ZqKîK—ƒøe'Lw~q¹Í*2uð#Í÷de2²_ èìO‰ø^õÊJhе Bø0 ÀÈ9óÏ׳óbnN þ°|ߘ©´Ìì¬çPé¿q›ýýÛˆoßfþ‰’‰(§Z/,ÏyÄ¡XtXÓƒ‹ç‘ó·àŸ™‰\¬àZaݘöí±6½Þ&IÀ€Û1÷…Å,$ ßs…E‰°Ãn/Ê›ŸpÒgíÖn¸ƒüÒj+Žd’[;Þ¶dÜûÍ:~R¼À¯þ9ý‡XH£9©þÁÀÑÀÕk ýÝ7cBü©˜XýŠ+‚dC½ÔäÏ5©²¯Âù7ú>A¸ŽV…–r™–؇5ã¹1#šðP†Ÿ‡Ãœ!K7•ø6„ñÏŒô‰(*ã½öP†3‡’^bo#¶{]!+j¥ý醗Úv„®‘*ä×H–Oóù’½ÃßAPj|4ƒ»[L®¥†¶sÝ`wÊ)fjùÙÿ\d Û¾inxû'§ âµ¡j²´Tµ’Zk=,úf5ÞØÇ^ôÃÜVĉpÝÌï¹Ñ¾ð쬅áÞõš¥s³'»ë¢©}™󯹶˜DòÙßMËî&SäYŒ½ÿs{¤i,vyQZä;!þñ›®6½=¾ú? .F endstream endobj 2353 0 obj << /Type /Page /Contents 2354 0 R /Resources 2352 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R >> endobj 2355 0 obj << /D [2353 0 R /XYZ 89 721 null] >> endobj 2 0 obj << /D [2353 0 R /XYZ 90 690.045 null] >> endobj 6 0 obj << /D [2353 0 R /XYZ 90 515.401 null] >> endobj 2352 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2361 0 obj << /Length 2087 /Filter /FlateDecode >> stream xÚX[w›H~÷¯àmÑ™7 Íeßç²Î™Ä[{öœMò€PKb¦dü離«@ Û»/¢º¨®{]B8;G8ï/^¯..ßÅ¡“zi$#gµuRáÄ"ñD¨œÕÆùì^ÿëênõö~±”J¸¾·XªH¸7ŸV÷‹P¸·oþ}½º¹ý´øºúpùNÉ‘žÐ<Ä`Ūñ”¹lŒ ǽ Œ$J/{ñ¥ŒAEÀ›<¹XúB÷^øÊýVäši´YøÂý†?@ZÞ¾hÚÚ<Îø"@­ôd‘ÚÕµDÊÍë*×Ç–õ–ž]ST;"7z!«°«ßÐmb´5=³<×Ms¾‰ßÑÉŒ_„¦a“GSëFoX sÛÞ½·÷ïˆ**zúi’B ¥Ü–Þ÷š×ZW;Fëû^ª¸€MgÛveù[£"D“Há^|Z“HìufZ$c›É;r©ëºjM]Òâá±iõèmmÎ6UÓm×òUj“µ½`^Ž¥-î_X¤R¨NÑLâઠFeFeœp€i3`YUv°Yæj‘î6ëõ­mA Çì"[b/ˆe€Ýâ+hå^äÇ܇g½;mtÏOBg9÷È h³êIè-9î&ƒ«1´K^lÈÙ„ú ˜YÙÔÄ¡ZýÈD:?e&™´fqéGÐúA8m ÛPÒç^“Ê˲¨tƒý'nµH„[o²Çô†!÷PÝïË*Úâ`¡³ŠšØö4ûÌkàd†Mš®ªè¨!·%&;äS· ñW=ÿl¹Õù¾ªËzWèf®ñ9uœÀ¢ÝÛ]@Ÿ9DìPÐ< JmÈ3äŽÍXŽí$¹‰øÇŽ$¥N±¯ ðбÑ{}¨[fÞ™:×›®7z•%Q_„÷w×ððImÁöl 3bý‘à:tU‘gö” 8º ?t©ˆCçd+ÝZ<ªÍÄXÃ6#.Æ€‡ÛN€Gï³jÃÄñX¢Á¢®hŽÊqû°Lé%úOÆtˆõnl ôìRW³q!&bÔ,Cé^cRJÔÒ„Ñ[mteÑÞ—Yµë²¿´‡žßMѲÀÎCqçÀ°á¡d^ºj'ÜÁð“Šh½5€?(2¤z&Êm]–µB;ªo'¹oVÄù¶i±Ùé–Ö‡z£Kl2»7ñü4M1O Pƒ8’“ñ¬$¦íYõFÔ4€Û œ.àpÑòtcaW·p%è5±ÙÈýÐU¬HÂÆ<Ô¥.Ê9ð¦¦ý%‚x$é>Ì3{5!“Ðh[Á¯ˆ²ÌÖµ±í-ÓxxÁe°™/ë#ïÚÛ>êÇðñp̪¢ÙÓbr@1J=.§©GÎz\,ö:30gÖUÆ`âgPé‰2„sUP’ª ®0¨ À™Vßp€ìà‘( ÀïÊrû»hP@˜ÝÏD qU®³K®è%"é%£!º$D?°g³ãQ?#+ÁÐ÷éý d(SyG¯|j@޼(žÈt€a‹Lð\gMï ß_¶@HŸž9À`gùít(Î?§[ªÀ“"?$GüEÊs0[*xÏýù¢ðCé…¡oÃç> ž _QøÑYøÿýøÛSHÌö 6˜‘ñÜgÓØÏr¸˜ )êlHQâäE?ìL󦞿,¿üòŠtÝ=¶û¾‚ƒ^;ßÐŒ_qÑÆ,áÿðF§!0ú‘îÌ9ÁnEO»õkQuùB#UµM^'wê#þ5¬Óú‰ígRòF5ɨ׿ë¼eÚ`²ûfßè¦Ø±Ô1kaæ­¦æÞ®.þäŽôí§åÅiâ䇋Ï_…³6œk/Öw+tpü —âw—Òy¸ø¾ð@C*/cÛ¾^¢R'JNHè_Mb>Ê^˜à/Iù{ÌÙˆ„)‚ÿ|Îþù·Zb1Ò¢”—ýW ÕŒåÐg, KÝäP†SÕ~Ôç/ T¿ãjVe¬Â^`ôÅáG]éû½èõsºa˾|ø¿rÎÁBºQy²m{£dNeZJ¡¼ gAäh^§p\'Äó =å©J©˜Í«­¦†bæõŒ¦ÔS§j~úI>‡âчŸvFÜT‘?xô~>‡b¨Œú†®Þ™ƒª0}¦'UtXgêá‡1Aâ¨Á‹ÎÍé‚ùê‡/oËÃa6rAYÿ¯È§µˆ!¢¡¨÷Ïy£ÿì`æs¢Rƒž×Ïa©ÿàÏ»3.%^¼L¾/`bhñ£Ë]ÏŸ€¶æØß5 endstream endobj 2360 0 obj << /Type /Page /Contents 2361 0 R /Resources 2359 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R /Annots [ 2347 0 R 2348 0 R 2349 0 R 2350 0 R 2351 0 R 2357 0 R 2358 0 R ] >> endobj 2347 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [247.054 630.752 253.231 643.516] /A << /S /GoTo /D (Hfootnote.1) >> >> endobj 2348 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [478.146 549.123 485.12 557.97] /A << /S /GoTo /D (cite.Soleil_home_page) >> >> endobj 2349 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [251.973 525.213 263.928 534.06] /A << /S /GoTo /D (cite.Elettra_home_page) >> >> endobj 2350 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [92.321 501.402 99.295 510.149] /A << /S /GoTo /D (cite.Alba_WEB) >> >> endobj 2351 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.987 487.29 158.164 500.054] /A << /S /GoTo /D (Hfootnote.2) >> >> endobj 2357 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.883 467.739 154.059 480.129] /A << /S /GoTo /D (Hfootnote.3) >> >> endobj 2358 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [196.889 469.422 208.844 478.269] /A << /S /GoTo /D (cite.ZMQ) >> >> endobj 2362 0 obj << /D [2360 0 R /XYZ 89 721 null] >> endobj 10 0 obj << /D [2360 0 R /XYZ 90 690.045 null] >> endobj 2363 0 obj << /D [2360 0 R /XYZ 104.346 75.527 null] >> endobj 2364 0 obj << /D [2360 0 R /XYZ 104.346 65.742 null] >> endobj 2365 0 obj << /D [2360 0 R /XYZ 104.346 55.957 null] >> endobj 2359 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2372 0 obj << /Length 787 /Filter /FlateDecode >> stream xÚUMs›0½ûWh¦»©eI °šÔ3m¾¦9´iÃ-ÉddPl¦; {úç«/8´Íä$±»o÷íÛXÎÈ_¢Áä,D€ „‚è0D¡%àzx¼ä)ŠÑ˜P4$£ÛèÂ"|NC¬Œ}§Ø³€s!eš/,àJòBФaz¾Nm`4TIŒ@<c„Ðð³…ØK4bÊøíü»}ŒW©È¥ÍH `$p $mÂh),à¡Jã_#Œ†¢”Öò¤ŸøÎ>¬ïí¹hó.oó–öœïjg•ìšP¹¬ýb„ép˳ÍÊUþ¨Y6b×çi4x`uUrh¹}êA:% Î×·$Ê~ YžLT<6…ê¾Wƒ/Rš9bÔV+© ïa5[ßj2Ñ„…, ÁÃÐwö÷Æ®Ä2JÛFgi‹ºÅYõôÉíá†cîUi4ÒW¹tá‘£¾šùè&…¦T]}Œ=0Öf¡)O ¯ÝÉ3¢Åû]šÇ«*q$Ïk¸œõµØ¢˜óL”×D5ê°“Öýe<ÍoEU^¦‹\/‹¶6n^,âN•%/¬˜,T Ú•þo2+ü£Jm£1Hð^§¿xá®C»õ ?îL&}­*«å_.EwÐë<±L×¹›ðºãnÍ9©Rµ?½¶ú!TÛïXlj\ë­m#T²x¸gcŸ×™]1Sø“¬x²—VV=¶B¼rWN.ùœ—bB”Å׊ºÝ"RÂ3ü¡._nüÚ·ñl£²¦ÏœÚÁ¯btºqõbvYÆs·¯Í÷[@%¶²à±Ü -Äfµs‘e§D) -Åëºv8Œ%1¿KóûþÐÎñD͵“%w†Iotãí,E-±“B[W²ÞŠ“ùWU»» ÿÎ:›ýŸv¬*¸OÒ‘=u­ãö,Zµ¯írw"OVo]Ÿ‚'¡u&/Õ4æÍæhi:óiÔ—»¨?SÍÿhïÏŒ§ê„59Åѽ©Øï ÔOñ§&— endstream endobj 2371 0 obj << /Type /Page /Contents 2372 0 R /Resources 2370 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R >> endobj 2373 0 obj << /D [2371 0 R /XYZ 89 721 null] >> endobj 14 0 obj << /D [2371 0 R /XYZ 90 690.045 null] >> endobj 18 0 obj << /D [2371 0 R /XYZ 90 510.667 null] >> endobj 2370 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2378 0 obj << /Length 2105 /Filter /FlateDecode >> stream xÚµkoãFî{~…ÚWX+#ži»@Ú<ÚCÛÝKŒ»»‹…"m¡²ä•ä$Æ¡ÿýÈ!G¶%»@¯_,Î ‡orH ke ëúä‡ÅÉéUä[‰“„^h-–V"¬HÄŽðk‘[ïì:»¸¼™Í½@Øž3›¡°¯/‹Ÿ»¦ÍÛÅ,‘öùÍ —³‹ž^ÞMß•ŽpÔ$ÝqNËpzåŠc칌cÇ•ÖÜ‹`OÒÓS¼cù‘{p"Ä¥ƒ¶kŠj5›‡BØí¶ùV£ kîºN°ê¾ÈÔy¨w»NrÚuµ-÷“WúSBþž>¹&4ݨ4ÿ˜zïE Þ{ž¼íêFåo›:Sù®Q7ªTi«àÄ wÈ&œdóúõËŠdõ®#Œï¾£/ò½H»ô8ËÈt´Do\´lHº³™!aa¸¡ª¼$¡ØüÉþœ7í²53®Ò¢4ý çNÝû¯Þ<æÂæº|ÌÔ¶;;Û‚Ï»J¯ŠºBâê©™šz,:Ę»”çUxö¤Wó½\œ|:q–‹ißqcie›“w„•Ã>ÈâDId=h¬%“Ø DpiÝžü‹Òo*@Ç¥AFhÖ¿Öy±„èðüÀîÖEKš¹ý˜n¶¥Â ßîj:x/„׸¯w A¹šyMQÈ­jî‘€âóš¿YY¨ªûf6ó©”ÊÛW|Zo¶ñ ì‚™¤UN@YTôPtkj­Ìá]“6¬Å¼ìÒjU;S®ºB±@7¶W Yi§w:è=áÁ£w·iQ-w%-TÚ`!Hµè·ë7t#O÷-<¬UE†×iN;Úzð…ŒhéÇ77?Ìd`Ÿ*é û›´*¶»2íXŽó EÞ“Ñ :z‰oÿR,[q"åWµ®WX95_øB"î ">,wM½!¨ªÑ´¨ùø+*·Ä ïH?ô0ˆ€£”Ž ÙªžãÍæ®€”;§K`$aŒ`Å@8>` ñ1s…}?>­ç@ߢ!k´Ð~’Y3´*tÈé(«h«à/GqœØÙ:Ýv:a;mé; mØX›“;eH­T¥pANË]Kðí›ë7Q[¯jæÌÒ'RšEXÖ͔ó£©Éx˜M29Î&p90—"´o•"ìw\:°F4+.7×'OŸAØù@—Z ¸¼©&Á^7›‹ᘬ€3£3€ä M¢,)\È4pvdØ–v¦{º“«6ƒMM%æÚĞļž¹vMàCS`&H_ì‚GY™¶-QIЛõ2(7ûë"ãƒFeê(fA§w;LMͨX"âR5P­èø‚¥]/içÈiú<‘,ü~«ÚÉ_“À´lk‚ZK*ø5*Ko¨2ÞÔÁÌƒì´ °§]‚ÀÙØÀ²mx0 LÍö’ò ¢œâ‡½Yh†“­ƒ±¼®3 çúÙ0ÝÐñe 7c'Š8þ¡7Gê<€bBÁCº¯D‡BÆŽ'}Ó÷]P¹ÕêNµ‰€%;WàbÀO –¦‚ ƒ®b‡¼Ä*¦]¬Ë*¸x(0X"tì)ÝÄ‘û7)F­è„b¼ú/+6R†ºÚö‰ÐøŸÓb$jìøa2’ô¼iÒý” ¾“ø®Aåäè…2)I›&¬.=PË¿æ±@:¾û×5Ÿ<§l>ôze¹i¹jÕš'·3ÊNšB¿ýce8!Ùòd°öó›ô}: Üÿû¬›ŽQ_Äckø.—C„Ø.‘]ü)» ™ ƒ)`qDó` XÔßÓð…é]»{À„¹,±…n0g̾ªÏY‘Añ£éCËùï™ë‚RÍE½»+¥¬Ž~‚N"¢a4)µ¤%7ž )5¤‡— »e×c`?WKT"Ý•ÜÏÞ©uŠf¹/ 9­7Q# í¸¿ô¡ßÌÖEÅû¨†©I,ÒÖVêÝÔ¼ü*×*i2…9ÌpdJAóÉþ»¯|ã—ì‹ßŒèåÒÊ h»Uâæ(ûŸ²fE·V/TÊ1¡ ¬ ¦ ·'CGxÒÄ9–à9Ê¢AbÌÍ•/z;PÁ$°ñ´2 cµA«•¬VrÔ°œq¤þRSW½zA/߉“¾šáݛܨ6.|ÿ^aLè|ì—¨+O„åèIxÈá §µ~¾(e¢Ä €É šz—»Q¬‹ÐE±žø}Xø¨Š}±ñ?C›¶¨¤½]c7|axù˜Á±þÓ<ç߉bÿàmH z&ɨøÜ•ž6ÂÐümC‹‹M˜èÁ–Ç™ËÁ kÖ v·ÝÖ v›¸Ú[…cK™(€MóÕï~ó{¤–‚ 9í@YƒÁµÓ(‘dý$d0tC~õ†‘0ñ ü“"›þ¿¨Õm¬tuÖ(  ^õ2õ§è_ç~~õŽçWTˆëÁ0ðôC(@__«®ëÃ*oså×ìfPõ\×ÏÙZ`3g{ÐD„ý˜í¸íTË×à±ÝÓvJú‡ #,ŠìŸ+ÂáXÀcö7ô uQl˜‘r„®KÆA˜Áç µšŒÌp7âEË.–ÇúA=ûF­Î.ÚçþpüÇ÷&( endstream endobj 2377 0 obj << /Type /Page /Contents 2378 0 R /Resources 2376 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R /Annots [ 2375 0 R ] >> endobj 2375 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [193.424 391.109 205.379 399.955] /A << /S /GoTo /D (cite.Pogo\040doc) >> >> endobj 2379 0 obj << /D [2377 0 R /XYZ 89 721 null] >> endobj 22 0 obj << /D [2377 0 R /XYZ 90 442.202 null] >> endobj 26 0 obj << /D [2377 0 R /XYZ 90 100.839 null] >> endobj 2376 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2384 0 obj << /Length 1388 /Filter /FlateDecode >> stream xÚ½WÝsã4Ï_aúBÂU’-ä 39’–2Ü]i̽”NÇ+‰ÇÎ9vÓÃÿÎêÃŽí¸¡¥@^´^í—´«ým°±4°qÑ{ç÷NÏËðgSÛð†‡ »[ÌðCã¦ÿÃã+z=R†û †ÌÆý‹©ï_~¸PÌ™?ðÌþøzþt2¸õ:=g´fÓ"&¦¥Ib ™Ö1@¸&<,¥‡Ô¦©t(¢ˆ 2ŒÁÍŠ+ß> ¬?‹Ö›X³æéz$aGØÙ®²è¯¢­ÒXó|•†@[^?ãs (؆¹–Ô¦?pN–éhŽ…Ðyœ¹’É7\‰ ïJ-Þ¦¥Ù¼È’š5XBÐ$åGºÐVVüE¾v«h¾RL8œYž’ éümÅÕ< a§4îöôø,ï ˜Ò3ðô¦Ó’M‘+ò^8â‚CÞMìé{áyjéEšµô÷×éôezäU΋œ‡JôsL´§’¦ضÂ]¤qœŠPvQ²5Ч\§~ïK‰ "j؆âaÔ3æëÞÍ-6BàÃÕ ÇsŒ”Z¦ç"†m ccÖûåÀ¤|×+ˆ yØ1˜g"›Ùºœ¡(©(Ê2[e¦l`NÒùd;…üþNf‚ÿ†î” ²e”À.‘Y¤r]·™JªýÑ•gSZy" °š~Û¥miíÉôݯw3ÿz:~¯ÄÏÎÔzÒyïH ð$çä!¤_4-ð$Œ;³Sߪ­#:=…Òêã0TvÓ"STºK¡ÊQPyZr’U0$¶ƒL‡6½yÚ›jõÌi-†<§Uë¢øóYϲ-D,ú’g!ŸA£ ¯À² Ë‚®L­'Û©êIr] œ%Êd'‚oUA¢«Z7o5ß°ê“AÓÚ&ØnË]‘ð}ãl¹´B”—­7·¿,ÖP­Úûe~¬}ªNYšÓ¢q”hg®Þ(;~gU f¸ ùþàÛ"†€$f5Ѩ»Rú«ƒ!} ÇY<þ,$Þ>nAb¡àjQY”±ÊÓâº> ¨Ë~N“¥OjH“FíSA¦ò®oêßsÚÑfD¢˜ÝŸIm8jÌE¨‰°ªdèûµmUÀÒU¢ ù¥¤FI JÖ­Tf:P$$JÖUö ʵ½ßvUð9UM<?MÓCÔ´ÿ#ü41Cf9Úâç§vÒ-Öª·XѣƮÁ”L”@)ƒ­îÞGœP‚³½'œ¸u'M¬†‰•"‹™ÍÊzZWèvõñâ£(Ñ´±ä ÏY ÔRÖ¹L£Ú.ÊW‡PÀØ4ò(MÐ1Я‚¸\T«Í¦E¬}ÅÑï-ˆ-¶¼Ù6WsEg|8›ÌkáUQÍÓÍ#Tã·Ý£@+¤×&Nüñ‡òŠ&5<Ÿñìžëyà*K—Y°^óìk}‡ïƒ¤â“.Wõõ€•² 6yiî=T9nµ §R¾âwlä8V¨Þ&aǾPͪPå½ËJÔ“KÂwÇÞB9Öé™!â™íIåØ<ò‚I2¨{|õ IH'—þ_£dù‡Àì £|nq*Zq5CÞÅ\¿W;Í„´­²ÆˆZש[Z¿|¡lý ¢D¿Õ¨~«¿Ïã½ysðZJ'ŽU\m\utÊäÿ³ç5[8™°}Ý6⩬¹ðw̵_Ô¹…-)á!Çaª:£5~9¼Sе†wâv–ÂßÍô­›¢/ç™( ò+@ú/¥’‚y endstream endobj 2383 0 obj << /Type /Page /Contents 2384 0 R /Resources 2382 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R >> endobj 2385 0 obj << /D [2383 0 R /XYZ 89 721 null] >> endobj 30 0 obj << /D [2383 0 R /XYZ 90 690.045 null] >> endobj 34 0 obj << /D [2383 0 R /XYZ 90 413.542 null] >> endobj 2382 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2389 0 obj << /Length 1837 /Filter /FlateDecode >> stream xÚíXKsÛ6¾ûW°¾”j,à›N:§v\wšGc57“¡EXâ„"U’²£vúß»‹]P¤Lg’IŽõEàû^,ö³°–°ÎžÍ?|+q’Ð ­Ù•+±#üÀšeÖ•ýó/'¯ggo&S7¶ëL¦A(ìó³Ùìâå9/g“ijOÞL`cvv:y7ûõñóÀíÉô¥ç/Z¤ŒðÌ`¬©—€Âij¦n<š-ÕdêIa§õDÆö¢Ú´ø-í,mS³S§["æ ‘æµJ[•1m‰Xä¥"J ø‰´/Z>_¨rÑ.‡2Õ>Ä/¢ÜÔÕŠVí’·òr½ioVªdI¤ÆA¿­©ôÄ÷áW:Iô¼u½Øøäz‰¶Iëj½)È+$£UH&«"Ã#ˆ)±—|ª'¤½©K•Ïžˆ@…¸Rí²2Ò 8VTsße¥VU½¥“7UMÄvgß.š_Û¶Ö’tS ì¤!9E¥Ò5o‘Ø›Mbd¹¨ˆ>¯jÅ«"mm+|¤7­ª‰9C®\-Ó‰+ìÛ‰ l–z­TI{ÎVYí ˜§EARCûOˆ’dªP­ê»Ú%x 28%1¯/PGÄÇ£¢ÝTDYWM“_о´ °Yƒ”ý€U›æ'BÓ¦mŽfnéV:ƒŸâ‚»R½a+æÕzå¹ÍËf+Nìߪêó˜3Ët1Å*ÁaÕ ‹oà®^éC¡ã¯ð•–Õ2°Ž:GX@$Û4/‡zE$z½xÝÐ ðy]Çu¤ãM¦RÁ·œ*Lêíe[ƒ/DšW«VÿýöƒæÄN››FÉ»kIü\å7àjá)mšL»º! y„®LÁ&·oì¶Ûµ"º—(’+@r®?­ÉÄ ¶Ô4qÔ‹.âyÂëâ£?š|µÆâñ„ogy³.ÒmC;íî|ÙRÿ‚3hÍ`×t;”Åã¹NAç~¤´¹Lël:¯2•õ{vŽx‚Ç)¿ÔŠúUÔåÖº>êÜÍ7t€J]¥ÇÒ?è÷vo*¸GÚ»®ªŽun~Ïfñíøb¾t\7¶æ«ƒ«wÂÊ€ž8QYwúÔÊÂ7.!¬ ëòà÷{"õK,E¿n%>"²9ž ˆ„«àâU0¥Ð\ÔÓj~Úgêö=Eû×øÑ´^ä%6.v7qâ8ÆÞeUÿŒ%ÆÓR„ýø1$å½~uþŠ$/Ó† UªšÚ’ÖH?&m¸¦¶Ž+lTaºcé55¶¼*GÛ«¿oÄÅ ñm« ‹­6ë*ò¬ »-þn5°ŒÚ*­ku£jUÎ{æuVAÅz40‰V°oÒ¥b‡³“—&D‹Üˆ¾Tõ->7:ˆuµ¨ÓÕJÕßs _¤å&-Ǽ{ªb˜lÓ¿5óGçc—á=æ¨cž~Åߘä˜%ß/;?îÒûdŒ3aÎÓ³gœ¿¿œ½9;yAŽ<}Ê1-pôñ˜@ÇRº«8¾;JPeVòià$Q<ÌžcvI¹ŸÔ“,ë c]Ý•¦:²½:ÃVZW}d½Ô/¡ÄFº£Tsçæ]%vqÑ=Œê²[såšÞ…Ϲ¢ö¢ûÀC1Ú·À¥ššïkƒ5¦æðdE߃›¶¨L˜ÑŒ§#“ÂuãhþtˆI}2vä©û~£ø‘~JuÇ!‡Çæ lpšüoej„¶Ñ|7îb´sf¾Þ"+é9Bió÷슻o¡‘RMy›!/üômp÷ß?ë rƒØqãäKÞ ýæ F%)›¸^èx‘ìc“8Îþðmòký˜ÂoÀ4ƒ>è¨ Àà•¾À{Zê °Ãl&><ÄFJ÷´w’}èÖ²Ô臷† úúùÑ£¾Y¬èáŽa²é(=Ú óD2 “á°-ÈG ³a¢ Tï”Ù3/ó6O ¨HÞ ¡[ôy#œÌÃØŒ©a²‹EOw7Á2¨‚­†onÉ=àÖE© ûèíöE‡Ó€t½àÁd€Ó|ó ãƧ¡rÆi}Nެ/öqª!œ†fNCFVÑ `œ6â´Amžî·ŒÚrÈÓmb‡Ú¦~kœæqôD7¥Ë§yÜÑ‘j®°V@~•ÿ+@mÎë ÆiÉ t¼^¿Ä­nÀðhÀصÿ¶\}ø ؇Æ`[²þz æ? ÔN”~9TÛëY¥«*ð]q#ÚCoÜ7¢hJ¬®±Òˆöö”Ò49²–ƒu …•ê‰ú{;‘ø£šF“ „bþ{`¶Ã%ßæHó8çóމãGî·F8¾"+Žœ ð8o‡aÅ8Ê ˜3•Näó? Ð;8ÔEV<œßëôv= ‘çx~ò?øùbð3V6ÿ¥jÇù endstream endobj 2388 0 obj << /Type /Page /Contents 2389 0 R /Resources 2387 0 R /MediaBox [0 0 612 792] /Parent 2356 0 R /Annots [ 2381 0 R 2386 0 R ] >> endobj 2381 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [485.181 641.064 499.627 651.968] /A << /S /GoTo /D (section.6.2) >> >> endobj 2386 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.019 185.397 168.465 196.301] /A << /S /GoTo /D (section.6.2) >> >> endobj 2390 0 obj << /D [2388 0 R /XYZ 89 721 null] >> endobj 38 0 obj << /D [2388 0 R /XYZ 90 617.592 null] >> endobj 42 0 obj << /D [2388 0 R /XYZ 90 171.823 null] >> endobj 2387 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2393 0 obj << /Length 1494 /Filter /FlateDecode >> stream xÚíÙrÛ6ðÝ_Áú¥dÁ8x*igäØq“™µÙô!Íx:&©ò°ãtúï]K™b(Ç´}iù‚å{ï»ÔZXÔ:;8ŽŽž®‘Èç¾Ï­ˆZ u=+ά·ö“g¯ãÓsgÂ=jsâL<ŸÚg§qüìå™A^ÄN$ìÙ¹ñé‰ó.~~ôÔã=ž.„Š$j–,Tg(êpô”Ñþé‰ðBÂ]nMxHaˆŽ[âÉW|cœCä'Å¢œNÁÔ7IuÑT«b1«ªäFÓp/Wû@I×5„ßéDA`õÐIµ(ÛÆ™0L¿7†òÚû„(W(ÓižîCd™ØU42{J`ˆ;>Fž¢ '§Ç?Ÿ]^Äç§³FàãÇÍ“2=©§ÓL^]ÖMu™ô¥NÍY@$@#BˆA|s¸ËDYþḣl4fŒ“k–e†ÓMÙbÌËëÂi™a†5e‡)šªÌÍOÖKÁ¥¬ä¨@1ŠuQ ™É¹,ÍR/n}N.í CÓ‚€42 Æ3@ô3@±~Kß1ž¼:?žM§µüeÖn÷Ãóvý>9ì…?Äýþߢ»B¿$yóé‹ u%iˆ ?€5‡ç²J?~î]o{UÝaÌ}êKÃïa ü‘ôõRT_2+BÕ*Ù´榑9j §XêìܾÝzüvÀ¤S€D„ùž•®Þ¾£Vx`I‚(°®õ©µ%¢xÔ8·.~2ÉÎÅϨK"ð‡ ·’ _â%T‡”uXh›KHagI“t;ê>Óàª6›i%“Ff¸ß˜5_Òl‡êeòûYSã–®³¹B\-›>½ØÒs¨=dÐÓu¸¥ß”›6j\tœ˜1w7NÞCUÜì¤È À”ºÂ4…É“ºÁCF®e.×p×™¥„^‹U³JòÕ'‰ÌæU¹FRX•Û (©pûɃèÒ_Á[oj2”`¼¡õ P¿—eƒ¨f9z“µu²Fl9W+ëNB*ˆ^*xŒpáu-Àmêµ  Ö·Eڬʢ/„j!Zšª%GxöÌà‹d-ëM’JelÇKí7ØéÖB¦²®“êÆüÎËÊ02*á¡.f-Ú§nûž}Ö$ £ƒªì«½ÑZ®K- à$ÏË4ASà¿N—r ö@ÕÃJ\?ÀÊ%œ0÷<ÓÏ¿¶ÜS½ŽÃ<û ç6m *-×k•dŸûT…-„K¤+AÒœƒ‚Í²Ì œ•±EÙ g­b”,i«bÓâ>–,@ïNmƒx%!3s]`áY‚FÄ 8^™øRí4¡ãYÀ©€{%ØÓ\„ýæb·±„\ìZleAμÁ£‰šü> 1ì_¿êæe‚cÆB²2W­~ŸÍÒUi+ìMòÝ>ão¯ 2Öÿ¹C%žÍ·+²-Ûe嫃ֵ­åŽfðv4«ÔÀ•œCÿZ¤=õ¶Z¥åæñpÌ/ÿj££Úžþ'¶ÏDýÛc[¯ºþc3[v•ä­$wŽnÞ`tÛ¥Îb”ÐñÉÏ'LN@ÂöÈÆ ¦ýß7a£Ûzè¾×%œŽÒÞo<=Æ—›ýgwLƒë¶šîµ9׎}Ýx7ÔPì{ÿ™èÿÆ endstream endobj 2392 0 obj << /Type /Page /Contents 2393 0 R /Resources 2391 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R >> endobj 2394 0 obj << /D [2392 0 R /XYZ 89 721 null] >> endobj 46 0 obj << /D [2392 0 R /XYZ 90 405.041 null] >> endobj 2391 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2398 0 obj << /Length 1748 /Filter /FlateDecode >> stream xÚ­WmoÛ6þž_!äà ¡³BJ¢^’®@ڤ݆­ÝÐbѱYò$9^6ô¿ïŽwTäDY;¬þ"òx|xïwÎ#œ7/çG¯“ÈÉü,bg¾t2á$"õE¤œyá¼w_}úËüü›J¸ïÍT,Ü7çóùoßñrîe¡{záÁÁüüÌû8ÿñèµ F˜‘ }&ð¢”ò–áèµcîYG~8³ ZHw‚È›ÅB·Õý¶­ÍÆÍÛ›fÛŸ  ͤô3ÅbÊ›Éx>í½e¿çóƒ?$,…#Qå8Šý4ŽœÅúàýGá@H?Égg¸ÖN˜¥¾1¬+çòàW2ÝžšRD~EN(?’™¯4˜)AXO¦. Lû"ïsZu}»]€VÌXvô]´:ïuÁ·Í­Ä­ÊšÙRðEˆÃ•®oú­›%}{{X4Ûëj¤Íïø­š`>oc%|,z&IË=swïÄŠä„/Ë +`÷f¡ŠXPäá÷ait…ï¦Ùl+ֶ׺ßi]ßC1›TŒP3£L ¸²àѽàÔX¾½}4*ë›ÇRÔøØ 㸊YÑ‘M2Aòg’õ‚Ѭ?Pd†Ž ‘¸Å½ÀhÅä{c\OºdØ‚_åÓ  ý²mÖ O„UÞ³ES¦´L$›6´q`0€Ðõp8D|õì™%#º!J¬Ž@^ë~Õ0o^UÍŽÖM{GG˦%"Û>ØÏ8À<™@¿‡°´e«A½ •®‘1Èø‰ª”—¢Ín¢/š–UÞuFL çË^·D§›@㤅Õ*÷áÞzR¹|ùšœg®{¾ØljŽxú³ a†Y¯}S–hÐãˆpˆ/å0ÿòÁƒò<›jËP ýÃàk|e?µ39d˜À'+÷ÐwmÙƒDù?<¾¥Ç`ÁÁ /òc[-š]ŽÚ2޼p¬Ë”9_ñô=î:Ëf ™ ë_Üg•ùB|õ>ƒî‰„‰ŸDCŸ1Eý¶)¹œ5‹³îøýqe ž‰(ˆ&l±·ÔMû¼‚šø‚Ø¿1@ÒôÉϵIŠïŒÓ}ΨnÿÊÅÔ`®pä}ª§™ &‘ PÙîä–ôùŽ>â„÷Ïd²Šß•Ó¡yNÊgÏžr[ÊÏMú-ƒ - ¼÷v¡o§f/ntO>»¾»*kü#"AÞ—ÍäAˆA¦)wH1%…”<”Ë{‹<‰e:Ä6~Q`3;|Jc0ܤÊb5 îLJ=•Õ¤ÇdÄ€Ÿ&O±EN­Æ4=q5yªŒüN³ á endstream endobj 2397 0 obj << /Type /Page /Contents 2398 0 R /Resources 2396 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R >> endobj 2399 0 obj << /D [2397 0 R /XYZ 89 721 null] >> endobj 50 0 obj << /D [2397 0 R /XYZ 90 537.26 null] >> endobj 2396 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2402 0 obj << /Length 2037 /Filter /FlateDecode >> stream xÚµ]sܶñ]¿‚£‡ ¯“£AürÜÎȱ¬$Ó|TºÄŽGƒ#)[y!yRÕNþ{w±¤x²å¤‹Åb¿wy̹u˜sqòzuòâm$ÄKB:«'aNÄbÉÀYeÎ{÷ëoÎ~Z_.–<`.÷Ë dîÅùjõ턼Z-áž].à`uþfñaõÝ‹·ð”¾ð˜ˆàEÍ’3¤9aF†o}6¤^Š8ö|á,y8Awüx± sïê"#èM¾i_¾lr•]ÿ½®n/³³®k~e[©ê¶~ù·ÅzßåDÿ…¢c‡‡—¾ï%ÑÒOˆè¿s‡ ïR0|òüõÏ×W«Ëó³ï‰þÕ+ZO?_½Í«.oŠêÖó<ÃÐrΫ¬üjVªYE87²"¯Í»ë;UîsD?yÝdøê˜chî zò÷YÆr|Ì-ïš?à>å–èùnùtižíkÄxVÖä#n¹o»ÅÜì ·ˆY» ~Ä-÷MÑåó–x÷Ç1çc!?Ù1Ÿ%ÏçfŒf±áÐ5·àªwÐGýó qø 2#¸«i]›=¾ÖåmþjèÇ×cäq5ã§â%™ó˜dO¥ñU÷GrXúOä°äÏËágˆò¹Q"Å,V¢äº…?Õ4êá=û0r\ZWmwª¶{•nT£9ñ ‚î?/’’ØýEŸ^EÎý7Tìô²Nÿuz·%¡}bC Ì äÿºRÛµ:.‘ ¢pÖpÑHÎaåKþ% Ìæ™Æu?=Øõ|uòÛ‰ s|bx’xKœt{òþs2ÀG/J"ç^Sm‘Ä@\:W'ÿ ah4¸øLz Ø‚G‘$œäXmr3ãˆ!)Ì,’Û§YˆÈÅ€Õ:¢áaŸÝÓª•·é2y1©¥°l¶y·©!#yºEKk¾ð÷ßø/O!ìÍi]¥9A÷,&)ZÒ²€4˜½LÈnc€ÆJ\¬œ¹@`ÞüúÇË× ¸gä~Ÿs/äÉØýMþÛ>oñƒ ¸óÀ½Óo5„¥‡¨öÛµEÖ7´ŽÞ5ô5­k³GùŠÀÏ< µ3èl_æc†ÝF›  ÞŒ[œåmy¤we÷ B¶1Ueý­™Èl»)ý„æa⋨;´Æ|Kû¶ÞjÓ€£C\T“Û¯H ÛzýÏ<í´Î¾û­¡®÷ äUµÝ•ù—(§„p(ˆ“aÉÝÃTJû‰½I ¨–•*çtìµÀt´q…„F@ºëBÕ²VGXu´–EeÀ'Áb)#IÐ?N-0¼'@Žinçì# AB%‰½ke{œDˆ=è“Rs A0†o“@ŽMtÈ’¥ÂMUYD)‰q`è !äÔH¢e6’2ç´Q7]ÞL¸6Ã’ÓÇpoýRï ß(óÆ: g¼>µøL`v˜EQd³.Š(¯`Õy« Ø ˆßç8`q¥ÙT“[ôqùÃÅ´Mu¦i¨Tm››W)?ŒLù®É[(yÐ÷‰0xß››„VT4„QH„nVcÈ"ƒW b<ãøA,˜-Cpv4ˆ})<.ÃÙ >̾ǺóïïÞXøÚÚÈ1ÓàÔta „‡×¬Jc‡ÞâŽø8Lµ”ÜÕ œB·ÝlS  )rÿÏhŠã¦ˆ¤Úø‘1¾|TÒ5 /Øj§ÂJÑ©¯Ðj| O [,³V5º¤¶ÚªªÍ%s±ÞJiÕcÉÈ“<[­ï?1U…|.@P’‹G¶L¼G¬eL‚#±œ ŽØÖ$„H?¦æƒ»æu:ׯ‹©Ê`ñ†êB…pC;Ã=KZTEW¨²ø}¶¨Œ`^ŠâIt™Ž-üƒÅ¦´ë]ÆõIeHpÆõ¾è6ÍÇ£1#dlm³'Ôˆël¿›ûÑ*ðdÜÇîjC-…/b³¯Ò®¨+úÄŠZ¹–ÉípþQ¥P—䇖4ê ·´Î쥔±f¿5FJB/îç,c¤‹¾LÜb«ns§Í#`zÂ#j ¼!q®´Ê„ÊT§ˆº{Øåú)ÒÍ 0ßÔzDÑj×DÞ䥢V‰|kË_·)äQïŠÔˆÖ¹P$ŠŒ¢TëÒˆRW憕í`Ü™_0]Sc'Á>m—oæî;¼•¯ÍA}‘3æ\¿&ʾˆÌýðp¬úHÑt$ÇGµž1Ÿ›&àÔtýØ7ŠÆ|T~ñ`ì8*»>÷óÇ]i”]æSVªbq¤D(Zhâ×)š˜êØŠ¦NC9ÍõpüvÚ-5P8ºiê-AåÖUôòD4gWM.ô-`Š<¼¢ F'÷ì¯3Ô¦}úýTc: ˜!UÙjH¸·9f¥?\ôaeŒëè”)À¦ß®:¸ð½J7 ƒ—îv§öRÀnt¶ Êb‡c:îÛ¼é?x\Ï(£gM“x¬Œ–Ä65(”f›Vx„-nßj;Dó–´ß <²ƒ´¡„Úbæ iç ±ÜtYuö²±ìë{áFW®}ÙB5ޏ€”5í’ª‡Ñ÷Ñ×’~L€×Íc¸‰L6…цwE¦çÍbø-"´+€n«:ÆÀ?[……˜ŽÔºÖã1ƧÑ[Ø:@§OCÿ–܇Úv£}†ÄõäRºQ;œsfT9}e„Ì õLÑ22.ìAqêûéâUñ½÷ endstream endobj 2401 0 obj << /Type /Page /Contents 2402 0 R /Resources 2400 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R >> endobj 2403 0 obj << /D [2401 0 R /XYZ 89 721 null] >> endobj 2400 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2407 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚe޽Â0 „w?…Çdhêü–Œ…¦¡ Š7Ä‚©B¼ÿB äá“|çóÞ0Ã’¡î‡QÅ`ò#aC EÎ#_ð(VëvÇi”•ñ$Œ’•$rb¶ù½<°ŒV´£,§NžxS÷Þ|e:mÙ¦||E={€>~™`‰pW¨½VM¤Ò*ày‚z˜vwØÿÝ>ª^-[ endstream endobj 2406 0 obj << /Type /Page /Contents 2407 0 R /Resources 2405 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R >> endobj 2404 0 obj << /Type /XObject /Subtype /Image /Width 300 /Height 400 /BitsPerComponent 8 /Length 33754 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIFÿþ>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ,"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?O[$zü122“ÃéZ¾>™—Âד*FÑÈ ®@`ãÕeY·s³h'!G±­ŸÁš”jp@ãFúW›}&{^ãhãõXÿÂmq›öùLYù†G$ý p:æ´u„°_%c¶Ë s¸Ž¤ñÔÖk gŠˆ) H9È5ݨè:¤ÜÝÙÒEr4°¯n…Õ å°çð'5鑸–Íüª ™CZÜY2¢ž~||£ë“^ck¨Ç>ƒ=œ‘D&\°v\ç§CØõ¬wy˜·°;¶ƒÇ×`¤ÓTå‹Vܱ§ãíyoõ×éÃ÷cýÁüëÒÏúa‘·­vxÂ÷oOcŠ»/Ïfš„-m$ËümcŽ[9ž98ÏxŽ[Ïø–Ydµòg-å( /˜ƒi Ó‚:ël¬m5 ͽû*Û•,Iõ#¸ïŠÒ±ŠËÌZ]‰kb£uÉm‘œäõïÇ~ljt¥Ê•ØQ~éÎZè:¾…¥ÏwHn~Uû=ÇîÊ€IüÇJ«²YjÖÑ]î’Â%g!º•=›÷ÿ×[޲¶wPXSfؾl‡äg8?Ò°…èÔ¯^)î"¶H”É‚€–lr2qÉ>þž•Ï Öš\å¶hx‚ÚÖþ(õ;}§¹|ÇvÊüÇ vük[QÚ$±Cqö…,T€ìG8ƒßšË²I’(Õ ÎáQW©'Þ¶¥H±­ûk¨´æ‰—{Ï;@À#§=Ç´îmµ&Óí̶ʩrLÌ©Ÿ»Ûq= ûÕ_"[ŸOÉ#ÈÏO|t÷¾—zÄ7dª0|†ÜF±íèq´uàþ´¤õºÊ’êzž›,’ºHíV8“hv`€ªp3ž½yÏZÌK{(E«›»y•T³Œ ­Ž‡?{œåWõMmõ§Šâ7,äŸ,d,Ö±àÓEü’*H›!8>ñã©À ïZÇ™«1¦Í¼·±ìÖSƒk1CrAwe±‘‘´Cõ¦Üëw·Q][»[ÍʤÅJ…QÎýA5‘Ø#6Dä´"€9r:÷ÀôëŸjGHG—æŽTÆÜ¤“ÀõÂÏ¥R§r‰âÕ#‚Îx’i¢óˆqær3íßê*’y—a ¶G“«2޵P)bR@x< rO¹®›ÂVÓÜêMµŒ÷í8XÚ=°1Ðõªk•h·zV´4?²&’ðÁ}¢FeÁåG_n¸úÖÈbºC{ÌI³ÊÛ·§cžþõÙéþ%ñ%Þ¯6‡ex×RÞ\"‡¸ŽxQŒgýÁ]/ˆ~Ç?‡ ¼ÚqBf¸ÜìÌÎH\äœþ=k›Úû-*u*ר±àKíu,­ï5 ÜÙM±´˜/CÜåzžxÍPñ°ðî§åÛéÐÕÔ¸6¤í؈OVÉåý? å4ýZîÍc°7×0Ç4 d?r»ríŒcŒž¼·¿%¨Üܾ«4×24³U™ÉËqŽ{ô¤°×›šv.…ùîšâž$‚f4q|Å{dŸÄñšè¯|qss£ÿeØI2Aù;¤“æ’.pǹïé\;ÈŸgEV¸f%OÝ1~¹ü*Ö—¹šQ˜Êmß(v J¯${ý:×TéEÙöÇIs®ÉqᨴÇEŽê6Úò:þñ×s2Œþ#¯ ï øB?Fþf¥w{Š$,2ÛT[®pµsz¦¨ú…Ôï˜-^MërÀ€œõ>ÿZžÃ\g‘5„O ê‡Y¦/•ua´¸ãŒõ'&³ö.0jžëóõÔÒÔ-WÃZœ‘Zîc*Žê‚{ñ^ù®›D–ï_×í.µ-![2Ȧ8ÈP;ßžã9ëŽ+ÄÜR]}¹-Grã^6n>P3‘Û¥w¾ñü—e­Ýí¤éÖÿ¹Éå§ÁbUÎÀöâ°n£§~[÷—:½.ÏH¶¹¿´ŠKyB™\¸ÛIcñùºçÅx¿IÒî5Ï2Ú}‘˜cùmmŒˆ8þðêkJÛÄe¯x¬ÑM2m@¹uv-¸ cr:wŠèSÆt6Öï%¬‡ÎˆH…·# Ž}+Ϧ¦¥xÿ_™¯5·9]Q>·´AÁ¨ô÷®Æê;(ôéüëpr¥B€Ùìq\Ö‘›u1$q»d‚Gp>µ½­Ápšl¬n¡n€…NïÌס¼Ò=é ž1uáæžO$FË»ýÚ‚_ j+·Ë´/òØ‘zסG!Ž0²Fû»¶:š7B2õÜäyü‡›Åá}B[†D¶tÈÁükúÚKK—‚U*èH`}kÙã›j±o^+3Æ?e¸ðô~)°/&ðZê#ÉQœn_n(^öÄIrîy¦OÚNzb» ?ˆÇû‹\†˜›.[ØWadqgº-mOc¹¹§EØ3ùâ v…w0äãÓ×Ú—TñE„WKe¥Ì­c!Ÿlk†çîÔp:‚I-è(Óô©µ›èì`º{c#|Ó!Ã*ÿ>£#ñªx_R»º¼CdÓO÷Ùî¦Ü “…ùý{îâ¹q4åÌÕÅF-Äâ.nd/$‘’‹9'Ëí?™®BÑÌÖÖîÖì×rªŒ `’$xúz×Eÿgöž;óo<÷1ªÚ pœ4`‘×.9Ç ˜§Íá[ÄJÒ]Iµ¬°Ï ʰŒ¸g Œž8nyì*eE»DÛ–Æ>³ 6:ªÛÛDÑJÞ­ ƒ¹ì@ÁýjkKk‹4²hØ%ÍÓ  ámxí‚}9Å]t³»¿¸ŠmBѯ57Œ°»3 ééŸcU|+©¤_l&xYJy%ù(3ü_2ôP¤þ>õÍV.])^¯›–ö[‚%‰s$ÌŒÂóÕ±Ðf¸i¯¢½»´,ëäÍË`|©×èN\úšÛƒ_ÒµUK;Ë8¾ÐŠÞ\¬æ%• ’OÞÆ Ž:ö®NÇWÓÛZ™¯ìö,›#U]Û0s¸ “Œg޹ö¬)QqVjã{‰®L‹clžDnÙÒp¥|ÀFÀÁó¬‹{kÈçŒ#òÌ€pj[ûå¼7>LQˆÙüȆh×$ž˜ñüª¶Ÿ|ÉrT¨A³¯¨Çõ®ÄšŽ‚³-^OsfݤkwRP9ã$~\MºIõ›k›–yîBÒ†cóvÀÇ9ÿëTWÄ$6ö ­Äy,wåY[æ\Çñâ©Ä$’PåáPÔçµR‚°ùZF¶³8»Ô ¶µKvrï²>v§¡¦4XY¥Ü q5ÓA’%;Œ{ŒñÇãYkn0 u~žõ×躦—¤Ã4÷vËs"aÊð!‡çƒS9rGÝ&ænœú}µãÉiws©«fØâÏ-ÔÀχ¬ÜÍs¨ÜI)Fó–7geÚ[ N{8ö®ÏÃ×±kWR¬AhðÄe8-æJA$…<Œr8$Z£â›$­#[¼2\‘^DÜÒÿ´Xò£’6޽OAN—¼Rnö8¶p]~`å¹8'òæ´ôOê¾’i4©<—• ;’x#9ìpNlÖ3G¶]¹ç×=*þ•2Å+¼Ö&î(ãl.í¡ðñÈw®Oa®]iz…­ý§—Õ³ ·;‰9;³×Ž>•è:Žõ‡ÒS¹½ÝqU”ÿ¯?.pàzv>õÆxfÛO¿ñ,ÖÍ4l†ØfsÐ㿽†{ô:¶þ#³±¸[ilmî­#}Â0/@Á9ÇcŽÇ•É])¾[••Γûiü@n¦ƒIIÕñXÜJ¨#<äŒçÿ­å—öò5ìø‰Ã£ë×n¯¥wsA¬Kᙢ·†æÖ$CtR8Ïú@| Íßh^1Ó¿zãÒþþݯS~>Ô›' ’:÷èjèEGáz ¯¼dpGS’zSÁ"FrzV”¶^]Ж޵|ÆpÇy Œ gñàwëRhÐZ üË䙕yŽ5Lù„v>ßã]Ë ®c†>^À[äŒñšx†F}оüñ]GŠ4û/U·Ô×Kû+çA Ä@žÛsЙëŠç!K‰åRÎ~^w9éÞô¸\GŒùËq•b¹$àsïÒº9tH¬u“co¬Å9µ]ÂD£i8È^߉ô¬sd"-Æò\8s•Û‘Š½c{gm"E³JÅö…+ó“·Ÿv'ŠÎr|¾ê©´Ú”ú]åέ‹Ä†-Ö±E³ÊW€YG‘“Ü÷¨íüX¾YóZU;ŽÕXQÀ¹cWµ/éØ\é­b³\m) 3ǹnH÷?θ—&hüÁòœe#ð#ƒõ¬i¯iyÏjÑmc:âPË·%qן­u:•«K§¸Um©ó€üz{W9áÑ:k0¬Íä++P ôëÏjï^0a(ÓïÞ¥wm jÉÝ>cÖ“Vå9í>_ìÛdŽvFf‘öãïŽ{ñΰˆ*Ø8ë>†)´-X2Ѹ=½kÊ|[ku¥ÚêB<ï·‡y?Ý?øð®ÉjŽìÚ)$¦æRª„F­ŒŸâÿëW³øWlž·´˜ÎPó¹NNkç x„G‹;Ùßùg#g?BkÜtýfÖ XV¹¤x£Ð {óŠPvbŸ¼´<¿Ç~>×ÞâÙ Ó.rÑîr§éüª¬a£ç²¨¯Bø¥®-ç…¬‘#‘Y®2wžú޵ç–Ûa»]Pî?¾¦µ¦ª4øGæ:!TLýæ<ù‘X_uòD·´¶y\lŸï2@Ä™ ÏRIü1éOñ0fÐç C)ãýá\¶§cy¥qÔrI kž"‚;{‹“ªº(ŽÕcêGjç9&Üá~UÆrzz Ú¶ÒžM'P·{E’âÒTw•\f8ÎA9èW%{÷—35z›>ñ¦xZþÆq*ß\y^4S¸0P¡˜òmÏäz¨·ñÚisi ‚h„Ë"H¬pØÆðFzgJ¥|¬©f7ZM+F‘ˆþr:ñ[–Þ ¿ŸÂ‡U†âÑfA }â?Ùþ÷}*}ÙÙ3H'«HçãµóncGo2(ú)BB®{‘Î2zÒýŽ6ûJî.ÈN@àg?NqþMOag,ßé8‘f“ˆíã÷ƒ°éÏ'½]»Ð¯-gKfé ÍŒ1‚yp£’[µL¢å&‘„¯©ÍO–sË¿»‘rŒµœò4R‘Оx«ú…Äw·Ó܈Ì^d…‚ÀÒÇd­Y£"r»Ã;öì1ëN.Êò'aö¶ÂP—S°He8$ÇáPÍL’ñ#Ë“Æ2s€*ÇÙžHâŽÞgRUðzœúv®›ÃþºÖn£„Òá·L<³)c+q€}¿=ë9TŒ4ŠæR8ÛFG™„Ç<ßJÖÓá½½š1$lÅþp±|Øä° ŒŒqZ:Ÿ¯­”•HJ+”†¬M>Qáe$·fyŒaš4ùÝ$‚2õë^›¤êº-ÕµÍÍŵ¤"Ù”3ÞD¡›°;?‡·#Þ¸­/ÃúÍãC«;Ãe3€`ÜT<9u8cÔpå‡5"¾+{ËØ£XâF‹G¼ÐFeöÂ×-H£ßa+¢—,tWž[Ø@Ži¤c‡ À,Àã§<…`ÝØ­¦žm-epÓ!gB¸U$á³ëÚ¯x¶}ë’Åd$š8ˆŒÉ÷C‘ÃíÇwö盼¼G¼!AH“å‰9®{dœW\²@PŠêh%Ü”ä©Ágκïië­êHDp·q4¨îSz(ÎÑR1øŠäî¡Û.GÝ5¿áÝLÛÚÝB"òâ2G €z c$’5u¾ ÄÑÑs®A¦iöÞNlçˆù±#¨îÂsÐ/8ŸÊ¼—VÓƒÉ}z.’åÖQµ`\)ˆ7GÀŽù¨o|`×:+iÂÜ! ž[ƒÂ(R§Žäç¿LÔz¡,«wn×KcnC6H\îÕ×xSCÔ[HÓ¡H'‚âHe$Uò±ðž2ûÏ©è0= ××üAáÝ>m¼»–‘i#ÝöC»iUÇ(/^k9b9}Èn5Ôf±¦hzn'Ølá·½²¬ÐÝ’Ø^8Ï$œœsž:W—Éx,nÝmB·— 1ÊFH õþU¹«ßÝÝÌÏ©K3«J|›‡®:tàƒzÆÕôû{I¢û$Æh¤E ¶7TŒg¼nÒê+ºN‘¼—šåõ½ñ<ðXã©ÀÆ]K;í3u½´Vw¤[+¸$2AÇÒ¦ðŽ—b¶3^jòÄb,KlÛÁbqÈ#Ÿ›¦N9Èé^‹e/†í„ÐGa-ЊR†XÛåÈ0FqÓ>ÕËV¼©É¥¯äh•ÑsÃŽ/¯þѳ2€F[ 6ã¹ïÒ·î5m;J¶óu/Êf p±×ð®Dy(Ï O"‰Фœâ™©XÙhö‹w{¹1¨“É•ò OLriÆ7w=µFU%dz7‚ïíïé­Xµ»6øÉp~µÁüSÔ,íeÖlEÁŽîêÝÄ!ÇN8äzŠë¼%âîÒdÚ,ƒˆÓ‚¿^ÕÊ|Tð”·€ø‚Ý„À(Y6tÀï]‹àÐà• F«RG‡¬3ÓjnaØrkºð䚦ž!mOHÔ&ÓÈÞ’¤mÊúgzãŠ*·B>†»í]†ßÃPéíqte0Óisþð<çµCnú©¨Ý½ /ë°êvViúvË[r]àl°ÝÌ•söé$.é Õâ¶{×k3=äp™Rwo•GFVèrëX·ºÍÅôw uåH÷‰Œ„`®Glc¶+,´Ðââ6 ¼•Xg¶xôæ½8PЋЉvúe{Ã.äù‰fTèOJ¡>$rãsЕ6æ,z“’À¦‚yçð­ã‹¿h„¤ˆ#ÂŒ„'“íøÕqØŒã­>Ò%–O¦FHãõ§”ýÙÁÆp»³ƒþM&1¨ÐÆòRz„éÏй£ß¦©™YϔѲ¶ØÃîã `‘ÜŸJ¡BWÃ:§ûMÒ˜Èw½:ŠOFaâ__ø†îyÞa.AŽÀQùü£š«àÝ3P¾ÕÕ¥š\ !¾A pzŸð«> Ñ-¤7Ž­-íµ´hRíd |ÃŒ‚y?tž;çë]W‰¼#§hpËw¤_\,i"·™4ßñõÆw)yÏ8Åg' 4·a{.—ã™®‹µëÇð˜îmê ü¬ $ã’ŸjåõÛ?ëú ÔYâ{hViãF_3ç$ç§Zㆱsö°—[Ë*äCµ@%¸ä÷ÆxïéŠî×ǧTð­ÝˆîÁ¡KxãòÙ@jƒ‚þ}‰ãö2¥­=nÆ¥}Ï0mRêåí㸔º@¡# N1ùÊŸvYÕb“ÌÉ8Q’ ?Ϊ¾Ÿqæ7Ëž ï]f‰ðòïWòql·ÂÒ¤EŽxãölöÆ=ë¶RŒul®rrÝÜN‰ÊÅ.xã¿Ö´WYº†­ÄÅ|ËÇÍ’X±9ϽTÔ´{í&ííîàxÝ #Ϋ£&Á»÷¦ã!Ý£Õnõè ñÙô½<:£„ŒŸ™ÉúãÖ¡ñ]õíæ°ºmÀ1IÑ•½@àW¨ø#Á?gžçYÔ!kšG1 ˜ù<óÞ±<à›AxºË^Él¡†éJ þ­ßÔ~U‹‹Z¤z‹Õé¦qÖÑfº0G,Ûƒ­mi¿¥±ÓQîžÞL¤¨Ê6ã8ïíX:î¯ökil,Z+¹e]²O@§®8¨ü#áãâum ±F(ÄI·*¡©2Ô¹WÑ«Ýy™(ƒN†Y/ì6Ò°Ù3°žqžãƒZ:–lm‰ÙpêÇi#Бé“W<9ð·P½ñú-ó4Ú°{–-ò€~îÑÜœW¼èþÒ4 `±³BЮI>g'ë]±ŒmsΩQ·vx»éVð¤O"¥šO™ˆ}¿(žøçõ©4›yo®Ò.{€YY’<³c©ÇáVü:ͨÅ`Ë”9üF)¾ÖdÐu%¿Š$™ÓkûŒvïNƒ|§-§WÈî‰e&¤t»{{ëh<—¸o´¹ŽÜ c=y®Â׳xgÇ1Ü$Q}šáši>by öÁÀ=8ÅwþפñˆâûyùþÊð±Àä“ü°+™ºðtšwˆ.L¼Æ 1`dŒ÷ü«Eù®ŽÌ#N67>/j—VÖz\ðƦñþiÙrvŽv} #?•y'ˆtÛÙÔÜÉlš.Š áG$ä}3ø×Ð^,ÑSUÑ4ÙL4–̬ˆ½I#á^eñžÖÏKÓôkD ·Ì¥¦ 0 ŸÇ?•gÊÛº.2Š™ä6vfîò;a€Ò šŽH 7 :¡±õÁ溯h¶º¾¶¦õŒ6°ï&8úgü?J÷Gðç…o-<¨tÛ6¶xÏΑ(Èǯ\Ôꄬ ÑóTRClÞsF^FÄXð9ä‘ߥS‘µq:™²ÙeÀ=ª×‰ôÔÓ5éí!ÜmÕ‰ˆŸîÖd$$ªÄgœV‰){ƽa$‘¥›Ì$ž:{Vå—‰¢¶ðûiÑy.w»¤ä ©Ð1çšç™Lž¾”¡ •Ë:n)­EË¥ŽûH&»xÒYõýÛÅ+s·Ë@>HÁã§­oÞxzÆ+8ÿ³®æ’IçHžM8?.9Ͻs>°mR?·ÌÓ²Ú8‹ÌòÆ£èG'ž·_\±žâh®/†ÒÜ´ ¤FdsÎ ‘ËPqøâ«9Ú&m‘¸Y®àXï¹h¤Ã$®yxÎ}Å]¿K½Ò%ÓïM²-ÒüŽX¢F~ùà@Îxé^W¢ø¥¬u{–y¼ÛKȇþì gã ç¥iø¢úîïAIÅÜ/äºý¡$sºE ãw e» sÍaó qøš‚oEâ {+»¨£¸[„òXØ‘ûİàÔñßړþ!³ðÞ£%•Ùö€´YQæ&3ÉîNyô=ºÖ­UŒ/»3I6c^Ú´:c\M>ëÉ¥*-ÌxÂaHp}ÎF:ðj+ÄWº…ìžIŒ^\¬Ë–U±ìx«Þ.×lµF›('1/Ú Œ,’s–·P+–dÚܰÏ^ tÃeuaf«é×WÉ&¬òþá<ÖÞÌßi`yŒm 8ÉÏCëZÚ.«s×: †?±ÛÉå@V|„9ƒ‚+‚²<ê²KånùwœáG©À&­Ç’¥$ xp íš™Â-XkCÐu-JË\ÒH³ƒ÷@—w³16Ï€H'žVœŠó,HÎyô®²/J|9w¦\Û¡Š"–%ØÉŒýãß9ôç×µsQɅ佪(EÅ;šI«#í]‹éP36âAÉÆ;ššîÊÚö# ÌK$gª°È=¹¤°€ÚÙ¤ ÛŠ3ŒgœÿZ”’b1é]IY Nòló}SáFŸw©@Öh-­•‰‘:‚8Àúâ¶tßAá«Ä»µÃD‡æy­t¢ôµÃD«÷N=ÍYƒ×)½w´•¬|õ®^\ø³]—Q±vc¸ˆ<°>ï^§ÝxO^Õ,µ k)Òyì[lr¹³.3Û8aßé:†õ›È4û4”OpΛøO#¸úWI þ£hÖa?³þÄð,óÆŠK‰Ùãq\ÎN2ò:½”\Ž'â…‹YøFpvÞRF?.•Ï[Œ>Œµè5}3R[2]¤b@«Écæ(+žÜn¨5;E“ÀÖz®™hÖ完3e˜dýî¿Ý몛MhyXˆ;»Žøysx£l‹œÂä{t¯AÔô)®æi–E}«ò©àý+˼%zÖ"†`À¬9ÿÏÚ¼ææ8’ä¤RïN>r1õ¤ãZä8ž&‹jÈG™µO 8U:+/áKùšÚß?¼•WqüQuPvá½ñAErOÝã SjêÂlïN·á»[{›{ ›mæÖëË>dܵˆ;†zãö5Ëj—7F x.¥ÉÈS’?™ý+‰Í!%›''ëQ ˆ7rÜÉv ²àƒýÞÆœòMwsómó°•#¢Z[²«#$c#éTÚO0 ¨] ;𥮍E™®n‰† ܼv„„^Ã'$dU»½JÂêÁ" É`]ÄíQé뜎¹ÆßzÊ0B õ94(Ëõ§ËÔ.L¹Ë„8\c¯QLä.zÕ«Iüˆ¤HàŽi$B •ÜWéÇ_ñª39r{P¯q Ê7³•Î)¤,…\HO§\ô®Ñ|¨ÇkgæÛ‹f¹·)›†rO ©Œãù©IE]Œçlô;风Hí$š7`3î gÈçÖº;»)N½ÒímÙ…²ù¬ÏÚ8?áï]ÌwÒøJ·F„ÅlÈ»š8Ô1›_$“ž€ñÔ‚:VyqâÿÏ©YZ5½«íYÌd“ýïs–Úztï\­)·+{«©i$ŽêîIЯ“K½Ž@ÇáUÕYÔ`Ž:W­øŸÀVwÐÞêѪØ-¼E„k´!ÆsŒuç œ“ÐW•´mÚÇ^k¢…xUâ&š>©Ävš¼ŸÚysI>ÊòçŽqœc§LV¿‡õÿ툮nDp¬Å"'Œ€ë^ñ \Ôõ«{KI ”OgpþdŠ Éúb Äz…œGq+Êéƒsÿë®Ù>¦‘‚jÏsèB¡fó#\‰P(MÂä3ªªG=óŠó?x×Vñº- ßÙÄŒ*¢ä äõñŸOé^¯·+ƒÍ(Êâœ\78o\Cz`ZhцñÀÉè3\þ‹¦j¢Ooi Þk’ÒDûB‘‘Àõ$µ×ëºÚåq4Lü«/cOðŽ•¨Ø¬²ßÌ#b R1ÏSšÆQ~ÓÈéRŠ££î4¶½“Ê`Ýåî$3´pNNJåüiá{= Âv‚Ò9ÊŸ2IÀÜOvýô®˜¤2²m6ŽwÂWú~›â4ŸPÛäyl¤²ä)8æ½?VÖ-áÒc6¢æ3LÉ‘ÂýGãÚH±}EöÓn"vÚÍ´?ZÐIU§†ÎÎU2¥ÈX#ùGž}GjÆ¥ÝEm‡Œ~®æúÏ`®Êe‘óÙGLäû“W;UM>ÜÚÙCn͹‘@fõ=êÌ’,hÌÝKV¯s:jÑaÇ-žvséëïT¬þ x{SMš¾žRnÒ[p=Ç¥yF·s5ö­wu!%¥™‰õ'5œR»–¶Œœ ãëYɤô:£kõ†‹®[ùšDÌ#“‚})Þ%ð³ ]WQ’dOÞ•îžœÈ{לø*meõ¸!² ž=>¦½C_½Ž uŒ¥ÌŠP(ïƒòñï†ý+UkCXÒ¹æº'†~ÃâíKN¼ †…ºàœŸCŒæ½Åztž¸Xb Å:žG¯ÜÁwweª=³ÛIujˆÊÝXÆXf¨Ïw5Ì>[HÛTcõ®y͹§Ðé§I8i¹ÈDgzÆ)£dýéàvÎ+RîxàU°HCªàg>£8Æp?dê7&Þíí䈱“€àd±Ï­[›;ß \‰Ä£V·ÌÛÁÊ8%Hê8Ïå]^Ö*×9~¯7{-„ÕÓÖ;€ÙÃc ÜœŸZó+¨^™VN6·þ•«iz|ÕG'ïgÚªj¬%º€*ð:þ5¡ÎÑZ±o4à°)€>\Œ“Çè UùÜŽI­í>.t©!,ŸgfbCãrm²¼÷éíøÖ\©.ñ0ÚOÊ rJzƒŽ‰•Šmêi¤{U€œ³0™ç4äùXîõ ìiÜ‚«ìiѹmÒrOrsšd¨Â=æ"ŠIã‚h¸0jT8aœd÷55ˆµhn^âR’GaP3½²>˜$þ–$aå’IœŒzÿJÃâ”Á/š‡ :TM™™ŽI<Ó¶íV<œt>•¯áß ê~$½{]2:UMänQ;‘Üç@XϱŽ4¸Š[€|ø'×Ïù÷®ÛQø¬ÞYG ª¤ ígt…žãžõÊjº5Α¨]X\im_d­nPzcó⫤[#i8u\:ŒVu)Å´åÐh¹­jšÜPA}tÓ7”.}NO5ÓxúU»OŽtŠ+™7J ¨PrÀãØþ•Å4ç a@-»v9üý)ÑÈÑò„¬€›85¥[h4ÝÏkñõΟ­YJo-à°š#˜á$yÁ\ •äuÇ^;W—ê–qèJ"Cå%71ÎÜñÚª¶±wyKÛ™¥@0±îùWœñéÏ[ “Àäžç½K¬ý°ËfИÌ0IæH³|ÑñŒeO§¥z ibïgs¥ð>³¥èàk+ÏqóˆâUÀ猖üûW¹ØÏ-ÍœSM…ÝCl»÷À¯–ì-£¸Ýv‘€ÒåpSž@¥}áZ]èÖÖÒN¢æ(²±ç¥G7+×aÍsFës¦7¦UC0éÎ)é£+´úT²HÀ‰J–í·½YÍZwÔÅé¡ã¿®]5»DGeÛ·¾æ®8kº¤ú{ÙM<–í &7rÀþuÓ|^`|I ±öuäô?1é\4gŒïÖ‘8±  ÔY¾Æî”V]Üdc#­v obÕ3sʤ¼8ÏjƒL–%½.c pÇ5‚gT‘ÇIákÙõp»£¶héT2ñ知••Çb¤¶koim,­ºIY÷E´Š:dž9ç¥z÷à LxÁÚ”Öºl×SƒçJÌ#V ¹-œ‰¹¯=»ð®© ­¥ò,fÚiÄhYò‰Ï·Ì9÷®³RÕü=¡x^I4+ûRòUdy~Y@^øã늈ϞÍÅhîq^"ƒÌº]R{‹t:’écŒ1 6üA•5½å…¼fhå„Ý tÞ0#õ~•¡}®\k6è·1$ipmÚ$² 1– €};õ¨µ[{Ø.!mkÍyZ(äY ‘Ðãsü#¦xý+W«Ô‹v2¼•P|“G¥#gyÝ lŒæ¥2¥›~v“Èê{~6õPq…àRDØr6%#øqœÖΛ¢jz…©žÓMyã.Füã‘׸¬Ý:ÊâúàÅ aŽÒÇqÀÀëOŠkÄMÉ.ÅãüRz»—S·Ñâ6vÉåm‡–^Aæ®êf[idžDGÈ„à’{ƒê=ýëÒuk˜Ö-?N· 'MÍ’XŸ@*æµs¨y_Ùú¡‚äbE;Jî^ jÚEò¶vI»ñ4öú©C@%…]‚۾nzßZ“Çz•œ It^/-pÛÞ^_l'Štòfusò)ÝÓ'ükЦ‚rp#‚Rñìi%p÷©¼ZjE¨ÉkSþ5ñ L’æi"èCá†ã]\ž:Õ˜þäƒ1H„·|VÏÃÍ Â $­rÈîÀ—PpÆ9­-{B† ºµŒiÅ ó6ªà0^qŠ…M5tÊö±R´¢™â~3Õ¯um\K}·ÍTD®ю½?Ɉ £Þ©uû©/uVÉ,v~ î×â"º)|'•Œw›%Õ¯^M¬H‚%2+ÄY~½ ôö¨¼%¯Üø3UÔ4›×Ciz›\ƒ• ü. [†eóà¢ÆÃ¿AžõÖÙÛÛKáxí$Ò-fSo°NbŒ»qÃgïg¿­gV§$ŽŒ%/iI¦Î‡EÕ¢ñŽªïu!¹ÓôଔliH<´ü?7ñˆ/¦ñ/Û£uŠ)ƒ$EOD ŸNV»½Ѽ?àHtûxÛûBð3~ìs¹ÿ¡vŠ«¢ü½žÉ¶µ5$}ímaÊg=Ó#ëURWŠŠ5£ 6öèyþ™k­xÅvå"y¥dmìÀNüúsŠô {$·­GN•z=…ôMN0Øiéj…de;¯|·SëøR¿†´Åu0[•/‘¹\ñÁç­rÔ¢Ù×O½Ž_²þÌÖ¼»u,· ú“Çó¨õ 6 -NÕuh¢¸òØH# Ãc’3þsZž1[› KH—b»Ç•_rÇêk˜–ÞÿTñtGUŽkx- 2\"6Ì}ê!ÊÛÜÕUÒ[u='Ãþ/·Ö·Ç·”c}›3Û“ÓÜWK,QÏ G*+ÆÃæV¼ÂÞ M+{Ý>üO<ò;­”^Ûïõö®ÿDÕ£Õ,ƒä,«Ã¦ytæÛå‘Ï^’Kž?âM=­õ=D‹mnL…³µQ ùsŸÊ¹ÄÓGó ŒÃ{WqñºÅí«ê:aimv¯Ú`AÈÛœw“_>Í-À‰ i*ʹè}höÜèúÝ£¢¾Ÿ‰ìsݽܾkýÕUz` ¥ç4øel.~Sýk˜ðþ».¥ö}ÎMÀ\ q÷—¾}ñÞº!,HÉÎF0¿®+ª6JÈóäÛwgO¤ÊŽR×äòO±®sÆ>{¶»Ôü溕£RrT€+ëÀÆ+A.›ÈòbP3Ôã&šc•ã'û@ŒË)‚þ˜9ÚOq)5±åú.µu£k){kˆçˆaKF:ö#OW¾—TÕæ½¹æâá÷JB…žàt~#Óâ‚ê;û|îw(ü`ÆAüEd;ۻŢ5ÃmÚpI÷ü¿‡‡vÌ&3|cL°óÛŽÙ©,à“£?…ºpzþ8ü«YqýªaŠüàø.€ÙútÍK§J’ÌÞPD1‰fˆ•Ûƒ“Ó¯^1Jâå#ѧ½Ó§Çh·*U³°‡Yx Azxæ©jó¥ÕíÔ±[Xžä´P±ÿT§?/áôÅwÚ,’IªÚ5œšœqÇnè6Y~ð.@`ŠîöüqÖ²|HždêÍm+I$Ì¿é0”bLÈG¾N:žØÀJÖ.Q¶ƒü+{5´H²I,ˆÛÖb† ÁI Í&§ke¨Z$&Ñmö1f’’N~bI'Ž:þ}jæaåÄñÂ\c Ø}*ð†òo*hÅŰl•r@Î:äcšžT¶)=,fiv¶Úuµ¥¼Ö‘\Y5ÚÏ<­"@\gœð­`ø¶éµO]ÝÍ@²H¸ S€¹ì0=ñï]q|CÎ B|µnTg®+/S¿ýzô½#A¼K+K&…±jŒ@# ç®+Ïü<³lBam¥YYŽ„Ÿå^¦ž-k8ÏÛ­®6ùj‘|¨=ùÎ=À5ÏRÕö;°•0ï—r¥ÄËc¬[4øŽ3æx%@Î:vÁ¯@‰ƒÆ¬Aã:Ôÿh×ì."º3Àìçx#ÚxÇQŽ:תxzo;E·mÛˆ\ªrýõ¼ŠäýÊ‘¦EfÿiÙ¦¤ºd“®F4cÃÐzŸj³|ŽbY#‘”ÄÁÈ_⨯'ÖµøI¼hÐXÛ\ÜÛ¬b<À9È?x‹Éêhr÷¬:TÔž¬ôÝwH‹V²ÚÊ ±‚ÑädgÐ×/á½e4kI쯼ƀeâÝóõN{wˆô®£D]BÛJHõYçNç,ËÛwmßJóÝ´ÚÝãÈvÇ•°³DÑ­*nMÁì„Ôn$ÖoWʉR0ÄCoà.O`;š‚EÕ<=v‹wÖèü¤…º¨®{Cø‰™¯G:FÍf¬…P tÁ=3ßÚµ¾#üU´Ô|&m4eô¦òäyW^àd¡ÎýíΗ[Ùh£tzW‡µé.­/˜1'h“×ë\‡Ž~ØkB]CB k|rÍHä>ßÝ?¥q? ügæ?öMón€ŒßÄ£úåô¯oÓ¯Œl wÜ1”=˜UB£ƒå™…H'ïÓ>z´Ð¯|7¦_G{nÑ\¡bU±ƒÓ5o@¶ƒV¸3yáî"‹’úÕÙxƒS†ëÄú”r 0´†"dqòæ°¯ü;iÂË`d¶'æ+ c'×½u£•“¼ 1Í ‰uÉäûŠ#ðê+,ö³‡‰VÅY°Ôexe†ôÇ*&AÜ@`GPG¯¸ýi·vöZ}ÄðMòã[Aª$Äñ[K#Úϵ£i#ǯN>œšç¥Óm¬®Iž\í Pq‘Ó'Û­jù‹y{i¡V–Cõ<ϯY%Ý„n…|Ønr㪕'¯üÖU4F”÷hËe‚)%”’W“É‚—‘»‹îzNªÜG¨i)o¤Ý ‹{Veˆ ÌÙ?1ëÀäóëŠæµ«¨õ=`HÑÉ °—‘‘Àãs1 þõtÚ.´Úv©mw¨¬¬"²6ß"üÙß»‘éŒuô¬mRÊúöx®­íÜ Xñ^»@ÉüóøR¦ü‚kÌ· Ù1¼™IPR?˜·ü룛Áú¥Æ“Ö‘ ’@\aÀeö9â·­ôË4&6þkL›æ!°F8ôé]-­Õ±‚;H ac ¥ ô¼Ws.ÇxsÃZ¥ÅÌ×Em#µ îÉïŒgù×9 :­¶·%ÕŽ”· ˜Â*ªe>£<´cÓ>µé—Šmô[¦Òl4ð÷.ß!ßòïc€HçÖ±4Ä"ö4`Ç@Ì÷¾iÛ·Ò³©%dkM9;³“³ŧx”[éðˆä•þ×/˜7DÛ2Áp9?­exªÏ\mL´»±†8á€DNGV*ì žzcù®öÕQPÍuu… Æ<¥&³6§¦Ä¢6Äq¨Gs´œ9÷?saÎÓ7Qº±âwš4údV)~¥DЉcä ÆÄžN:õ뚯m£Ïun²ÛÚJñ’@a{žõØxºÊKýWÃvªA,ºt¨,pŒÌG>‚³tÏÞXiÑX™ Sn]2T’ß9bI*yÉ?¥mÌùS2P\Ö=÷PÐR×Ëh$""0U”d m’+`ÅGNj øÙüKö§Ômc¶•ƒæÎsßð­×¿Ò‹•`‡þq\õäù^†ðrŠJJæHÎ Œ„ô+ÆÖÈž½ä. tþ!]Çö†˜¼ªGƒéW¾½Ñï­ä·º%‰þò´@ƒQ´ïrÜïöO(øA©I¿qj×Ooo(î`íÉÁc÷sý+¿Öµ«{ZX"3åg ²Ou9éXzî Øé7ZOÚ­eD/ˆœ„<‚sëÓôª>ÔN«¦ÍçãÌbrr99Çë^…¦¬p׋Nç#âG‰n0|ÁÆÙ¡ûƒXõúÓõè¡‹Ä—1¡#Y0è>QNÓ<µ’#)Kçµo{#Ìœy¦•ì^Ó.Úý%“!C$vÎ@ü2Ev:Å­å¹´žA)PªÙÎG¡Íyíì­Ÿq"`ð žÞõ™i>§ jmöø`® ª^¾ÙéëS&¯c|2|—;M™â)#aåK!UîF?¨¯Aðn®ÑÝý…Îc~WØ×†__sÅ6±¡qohCî±äž{“Šèdñõ–“¬À-ƒÍ¶AæÈ8 =½MpÔ‹çN'­ J›ŒÏ£À–‹c¤C'Ù-¡]‹6Ås¤ú×7mã»IíUäI 2å|¼a؃\ψ0»Ò#»ŠÚwHî¡0Ì7)î3ÜV´¨u–åÔœcîÀ‚o&y¡•Š 7t`8ÿ ¡=Ü×VI Uû«Ø}*Þ¨Â[ƹVÈ“$œç'¿JËÍtÛ[œµ$Þ†–‘?“ ‚àÛ•`D¸ÎÒ:Wµè¾.[Í9%†áw¡ù¢ Ìl:ãØ×„ÛKå8`ªØìÃ"´ô­E,晦‰]d€8VÇÜÖ5))—F³‡¡Ùë~"hïne.»üæfô%Ž@ýiö%›Y%NcŽÛæ&Avî}…yÜ$Ònw$±ä±ïë]-‚¾š‹³&'åe†¬tV2ž­³¥‡P6ÚݽĭºÐa•Oi|§ñ~ªø—X‚+8cŒ3ï0ñÓüûTÆ.c [kA œ“ÀH9ü³\°¿Š][í—'÷QáñÐ~uw3:Ûií¼?£­Åó¹˜nuxž>_Ë•<—:‡™}q¸‹Ç,°+„D}§ç©ÿ&¹”iüI¨ù·-åÚFr@ì=©5ÔØÉÚ”»GPæ( òAãÄ:‘YÕ~épÑ–´ýbXõ ûo-íàwD1"¨ “¸I?Rk6}%ílt¸âšH¤š¹ ~àŠß·‹O˜_<*f0Ub§Frœç=3ÅkG"\C¢}¦Ú×vè1!8” 8Ó¥qÆHìOB]rê-2 VÑ.!¹µ¶@­ýýù“ÓŸ­rÒ|E¼žU qä€òö£éŽÜW¢&¯£jâk­.Ý..áýäÅx ‚>\Ÿ§5æWºV‘=ìºhÛ$å\C®xÈüJ¸µ{Hé{Ÿ¢ø—í^ ƒR·ki&I ÂÜ6{gðõ¬¯\ÜYØ[Ï8?i–LÇ$2f0®}GnµÉ[XG¡EÅ7ªÜžGÍÒ´S—»~Ã…[;³¶´¶´³‹[íIlHß^1QHÊkGÐÿ}‡ò"º„Ð#Û´œuû˜þµºv• 3M{~vQüê­#§ž™Ë¢£p#€±ùfäÄcVÊIçšè¢µÑ%b"½…˜ñ„‘N?*šæÏOÓtù®®$>D1—bXrKR{ÚAnyŸŒï¡±ðôãËŒK/ȇhü}úWxcÄÒi3¼M<¢%ŠFxcïZ~*Ö&×låšëdkL9=àzût®.ÎÊ[©T¨f$€ª£–=€®êppŽ»œ5f§=6:û›ÄÔ5ºŒ²9`Ò¬Û–0sÎzVuµ³Ûá"3Ús‚+FJ¦:]Øò±ÒxNËíÚÜQù>nßÞFp@$ÀâºïhÂóBœßÙ4Ém*g †POµrþ ÕÓD×Ô€Û³“޵êÓøÃJ[rn%TŒ¡,1¸ãè9®:ñN¥Û±éàe%GÝÑó+Û›ÉîLX¥·i]£?u3ïÅrúí¸µÖ&b1!9T' #ŠúK¸Ó4O êRßY-¾—.ù’dp]”¿Ê„„ +À¼Qqgw¬«'‘á”nÃýå9?)úqÒŠz³ªNÊôßj:E³EW?#8-³éȬÍCV¼¿›ÏšYY©à}j´#˜¸R¤ú*ŠKhœ³ñÍn “ºÜÅÊmZú-#±Ëšnâr2:ÕŽ"9òÃöªéH¥‡8¹ã•ÉOJ¤®fÑͳm] õëM%Ô^MËÇýÓŠzÒ!îOn¬|Â;W'?—õ§§ÌàŒÔ¶‘Âmî ŽÉ.ÜÅŽ‡Ô¡C†ÐЬCcÖ®CumHn]õLä~UE¾ñRe‰µ ä|Îù<ñЦIc“NÛ“Åméúlq\‹=^ƒí¤<=¿MÄÓf†Ú=´ÈÜ×n{×G¥Ã,‰¤º¬nÒ+s†9éÆGé\Õ¼št²Fà§½zG‡îo¯üo.-¯ ´ÝqȧtNJàc8`~\wç¿lk»$![35¶¥yö©a°´x¶™›+ól ò=ÏVDsÚÞ_Ër–%ÐÍ’³=sÇùë]]ä7Úz@ ³[9U­]áB†'}¸Æ@ܹ\óŸ®kBbŽ8"m«¨î1ÏÖ³ ¹õ*/©fÇW¸Öµ+ˆn¤p-¬aœ¶§áо¾¼ñ.©jðšœOpÇhÇÔãµsñhZŵôwrº¤Ë‰`bX60rr?:õÏ éÞ(žÀBýl-#`"·ŽÝ™Açæ=¯9ëV©ZW7u¯^§?®|(»¶³¼}vš‹G8eè ëúW8¿'¶¹ò¤DµR¸~0F{ú5.Ú7Þ[œ?q¼k«[®»gCxªñÎÀÞ+)œu ãó­F7fj·³xfêýç¶’êB±EBUyÆáŒמµÉÙj…¥Í¼ˆê$Bå´a=*Ô:%Ü?f±Uxîíï;óõ¬}OÂú±X"´-pЧ2”n9÷?äV:lh¤tÑk…®štÝJcŒ§ÎÚÑu%· qÏÍj˼×å‚k—ìðÑIœ["œ2íì;æ­Ýøfó\ð¶˜t¦¸º¸‰ñ=¹ŒGz…~yã5ÊÁáÛ„†x®®ííär,ŽAÈnF1׊˜ZWl•#ZMyäñsjÒ}”ð¼D¦?¹»ÐõüèÔüCwsÂÖ×˾[—Ÿq$Å"mÇn£5M¥©¬`å²=Š}_UrJ£*úÉ*¯Àg5Í–•p奂'–S‡`üàžsƒÈöªìB;ž÷©-  6J9ï ®kœºîO ž™¦Å$Zw—e‡næüe¨Þ`6n£H ²’Iy#ÕÑ_›éU"¶ÓîeV`„gf³5¯ ê:Æ-œPÍ 6s¦cëUªmÉ+5Ìx½ÝÄ’Ø\JÛ™†óŽ2N{p:~µ^Êw€)‰ÊH¿u”ò+G\е-5ãÓdŽ·oŠEpÇÜŽŸeYÚÝK¨%¤0»ÜoÛå(ç#­w^êèáZ;3 ²â+|ä“““Þµ-×+•2=þ- ¤¬W ˜×xü× Ö¾—|cˆ}Žäg#˜›ü+Xlyø…vÊ·7YéóÍ0,‹Œ…ïÏJ˳ñ•p>Ô¢NCGòî ÏCÏNøÁ­ÍCAÕ5=&æÞÞÎc)ÚFñ°7«`f¹}KÂ÷þžµ&ƒ7oxÑÕ䀹þöGlõ¬ê%'fu`å*qº'ñ‹ï5€ÐyÍölå»[Õ¹íØv®vD$Û¦[æ98êðÀ×7A1·s`8ÇÔÕ™äŽóÄ*°D^aJ‚ ç¦N3S¨èu):’»$UaÁ9ǾiŽq[ÆÂî%t`¿íLÎÿúÅd\‹ÉN MŸîÃQùÕó\ÞT¬R,OåVíd@UY”rrjaxÇ-¨îJŸÔš]öëû†;òHÎÓ5IœÒ‹Z³"`÷7ÎX±Çašµ¥éÂmDE8 Âq“œ`žÃüŠõ« ûGGuÒ¬Lˆ|µ¹-±U†9aüKž¤æ¸}*(nüO©^,¢P³¿”ÛqIù±ô­%M+js)ÜwŽmᲸ³¶ án0T`/Ìxvúæ¹-„e»µÚøê..âòmüݰ.\•;«ŒIÝbxû0Áüë9nTv!=ih4T”\Ó>Ì5;svH€8,@ÏÓõÅz6££Ã¬X}ÎÙf ³œB}+Ò ¹YVòÉXÜqÓ×ù×_­ÞÙ϶ÊÎyá—dàý1üè@ÌØm­Zëì>$³š9À·HO#¶{~?wz5Œ:6‘-¦—µÖâXH9,Xî>™é\ͯŒ-g"ÞþÖHsÇÌ2ãÛò®×Ö¶—چˋ¹àŒ'™ðžQÁ=ÀäúTÔ‡Ý+šð6—mâĆæ}ˆ„³¨?4„v…høÿH¼Ð´9#’_µ+ºÌ·’ò¶A<çÛ¡ü;×'à…K««æÈ&FW†(æX‹çÑÛ€}ºšÃ S™qµh¶°šLÚL–èY$R0¸Æ©ÀÖž½r£Nh£•#©¸ã'¶?W/sã/é–ñÛGá‰ð‹ƒ5Üåóï9ÿyÛ£ÈÃs( Ù0^xæ´ôýºš£J’$/‰1$£¸íŽ˜Ç½yu$ã%òLæâðþ±¦ 4ý6íf‘ 1½£²²©'p?ÝÎC-®ë9N¬£ÎÝû¡  õç§­uv‰¥iæÛ\m+P„ùm$€·†Æî=êÈ’=Vyé"”Æå_y¸éòœôýkiS¨•Ú±tÓžˆò©ü&°éà@Zh¥˜¸B@^ÕE$´BñÞy21RÄn'õíCÃÖÓÎ#‚à!o˜Ç€AøÏëN¹øk¡]Mæ¼L›ò}zÖ´¡Rz³^w©¦·zr6ÄþâÒÿkZ+cÍý+—WHÀ™‡q3ùT’ÍlHgrGý44¹Ù¿²]™ÐÿnهٽáT/®t½V=—VÞb€FYŠþ¢²ZxvñjƒÜ“šˆÞ6>Xc?ðÒs}Æ©+ìbx“Âúe¾’5>Ý¡w–CHX3‘šó¹íVßX]E 9ãïqŠ÷­[O[ϲÊÁ$T3Ž1êz}+Æ/¢HÔ8u`W5èFqT’oSÓœª9EhjÉ«KqcГö„m“A,¬ª8Ⴢ:ñγ¬… !·¹äuú×1ô s'Ú"’4àá” ã¹àäÖ´¾ŠªÉr§ùnþUJIœ•)´ö:6Ô%ûb17˜É½®! >‹ÏÌ8<ñô¬ gM±Óá¹ÖÚye¿hòa„ŽzsÞ©[k) %¨xæÄ–àc8÷ã$ô¬ßkqj6†+gî”#å9ôýj\•ÍéR–¬än¢ò­Ñ·åŸæ#Ú¢Ó¾¡˜¼Ð\e mÝížÕÄ­#ÆÕà ±¤Ú­¸æèKúsùRgU5ï#¨’Å”oÓu'·?óÅ®pËõÉÁü*£ÛxTÿ¦)SÜN¹þu©}¡¥Ñ îÑ’?çªÊ¿Èaøæ²eðœ€MB?ÚoëPzRèŸÞgÜ[Þgý>ïÌ_FŸ#ù×Aák]6æé’ébk}‡þU$uþc“\ìºEµ«î¹Ô`p?‚±>ÞÕ¹áíRÖãžâÃMžeˆ„–ÈrWpàkX4·8+§fié›Xê0=ÄK,3».@úÔ:}¥–Ÿ{*[«î嘷ñ0=G>„V]Æ¥I#jW)dË f¶ë('žoÃWhÒJÄJÛG›×ÎO¿=iÅZM·¹Ï't•¶,x¾iôÍVÊú?šMÇ÷NOㆮ;U’ÆiÒk$d3"álö¯AñUî‘y£Kjú„Uùâœ0ôÇâ+Ì žH©ÅÜQCM(Á§vRB朱|ò*.;3¢‡VK¤0¨ó}IëU4ÿ]Øa[d±Žv·} a?-÷³ô¥H‹4ÂçjÇ4 € þêCêØÿ²y©íõÍÑÙ$~dÊbÃ=C""ú¾™c<ÖÖÖ“ÜMwi"“ÚþhÑÃ/ŽHþ•¯?€-nmäÙªêöí"•ek¯1pF1†Ïó®ãŽÍÓ*«m ½¸ÂŽÂ¹MkưAtÖÐYFIïžÃüÿúå++—ÌÛÐϴдÅ,6ÿÚ9A™IÙqýâª@Ǿ kiZ¼ŸÚP[³Iuo?ú‹…E`=U™Nâúõ®+ÅúÅöƒ§ê,þ]Ô7ÞWFe;¸ B+Ð<¡éÖzäÊ.&ˆ;H~fÉúôü+9jk²Ô³i¦;kÚ”—Vªm¤*Ñ–‚v€xü+]làŒaz1VHȦÁÿëVNšìO;gâ­~×HÔšÙ-`‘ÆÝÁáŒç‚ pº¦¨uKß:³Ù XÑY÷8Ï5¥ãød>,¹eË©Ðg(®\Å"6^7CÔnR+ ’’|½R„ ¢¥}OCð}ÛY_$\ï•mžyvüÊSvîõëÅwrꢸ‰¥VPÊÈF0kÏüm Ü¥âši²C"+èÅÁÖxfòÞm5—|LSæ=ºç[Sn1G"Îm”Ã×̼˜“Ÿï…Nž”Þ\!Ï\M¸ñUµ¸ýãÀƒÑ¥ÔPø²+€&€®3…}Ä}qÒ¹ýç÷¥Ñá¸÷ qØ-=|=bœ³JÇ=ˆÿ ¡ÿ J ÀÁ²?…I¬÷ñ5äŽË’•;IŽ.úô¢ñìO-Fþ#~ûI¹½³6©©41ìòò±dãäæ¼òûáŽWñ$¸O›oÙÀsýêé[RÕg Gg*¡f™SŸÌš¥©]ê"Î`¢¶6g-/AŽÜsúUªš‹’IZçŒËl÷wí`3ã9'«±øvIcóD\pàuÚ¯iñm’W’NkZ% krO_2»ãcÉ©V\Ú¶ž6W 3²ÌåÐ’7 r?,Öˆmmá|ˆU¸Húäó^…³M;Ä.Bƒžäb¸¯Ù>(­$F #™ ÿwùÖsV¨‘Ù„nTäÙĦ´ôÃê@˜R`ªNÇÎoëY§ƒZš#È—.ñ禿*lÞ’\È·ªX@[r@öNz“Ó)š')&à} ®ÎâÞm›£’0X`¤‘.Öüpó®zóOØÄÜ$°€~ò è?‚)¥t]x´ô2—““^ÕðÒÿW¶ðªCg¥Ï4&Wa$nqÁÍyÚZn¯ÁOEŒæ¾€øg¥IwáRöø†%™•VO½÷W®+*ÉòI¤õÐÁñ/‡uMTû]ÍŠZâ Ÿ¼X“ΪÞð嵜3Ç«ÛZÎn[t@·)´‘íׂ=±^ªžbG™sœB§ÿ^°µMl°›šàÄ›Qƒ,n§êNÍr^N&®PæÞç?âïhw¹Ôà³ =¤ U#%WýìÉéýkÉ´¯Ühže¬H“Ù9ý弃*O¨äs^ãßk:†?²¦¶–Öîì˜Ìç|@|ØÇsÔ׌…L×E·xç«;KÝ4Û§’HDŒr9ǵ:ÒÂïP˜Åk“0ˆAœZnî+ÑüjÚvŽ×[GrûÀoî.1üÍtZÆ Ü¡á¯€]êªT°ù!#¦r2Þüt®¾ÃNÓôëDH Ž££–Úz“Ô’)zìŒ^&VRįÐäV=ÓA ó_1w¸Ç• Dðô?ÏðØYL’Q—#$¸Á¡%{mF ¤¸™Z ª‚ê@þ¹¤µá´2O!y›©ÿ€ÿõé’#G;8çúš{F½¤y—‡U—©Ç·½ZûLvñ3 Úª mÝxÍÛëRiÑèþ{)ŠæÕ@Ê|Á€B:}+”ø‡ã[KM9–ÎpâS´…8ÜÀ}ÑߌšÓdf¢äÇø‹Æ—7“:ÚHcˆ,„óøz:æ­K)“9'©5Â=þ­¨t‘³Æ£‘‰þXÓµ=Zââ+{sù"¯9$œ 眛:éÅ-P}*]r ?J€¨ó¯PÈä}ÕUbJö¬í"¶…vÇQì+€ð׃uk·¾—Z….BüÐÇtê2[Ÿ­wÀ²€@MLf‘55dô•›â”L1“Ò«ž&|¬ñˆ×c×õ †Fe]ƒýÐ+‰´ñl*†[ˆØíÏâ u?.umBE'1€sëÖ¼¢Ü0ž•‹‚m³ÐGÅëð}Õî­rìÎÅPl’rXÿJdò=åÕ©r¾\̸ϽIð>3ý™ªÌyÌÈ€ý?Ö´¼]áû¹µù.-S1̊瞇¡þU¤cxØçœÓ¨ØÈá·BvVˆ{l…A"4h¡çÑ@ʺ±¢i¨rc‘¾¬jEÒ´åå-Pö²rû9õgK¯NúDå£Ý€ ëúTé ’ ú`d×U¼1ýÈa_¢ ›,;-Æû²^&Û#—máX\gÔb©jš=ÔZMì®ýË“óJí@'ž?,ÖOŠ_ËðÆ ÃêHüøþµQ¢‘ÄÉèxM ”M ¸0bâjcwäÅ*;ª3?ñ05–¶íoëD6¶ò9‘¡Œ±!‹2O§_¥z“ŒSG›%'sOCº†óU†/9[|È­°ƒŽkGãFƒk‡­u+xñ$syr?vqŸËõ¬¿:XJF€"' †Æyô®‹ãF¯·ƒàÓø3ÞH¬¢¯$þdιùœæ™ÓJÑVGÎoÔÕÝ:â87™"©2çƒM*?É­Yª›Nçie«YgónÔm äóôJÏÄPÈ¢;•Û&ìËŠævŠFAŒN.̹â%%cµ†YÕ.íã‰7ô>XàýkÝ>)_ 1f,ZåÎOÑkç¯j ÛÉføÊüÊñõô_Ãü¿[ã|’0únÇôª«g Û÷NÇ ÜQµA@ö4ÀMsÙž#û@Øf=ÿÌd% sØäóÚ¼G•è59oü{w˜¼6ª±F™á~PXÄšóÈÛC×µj•É—nB–=ëУӭ µŽh57X™FÝïÀR¿ýjãt="÷Qºv³ò•¡]ÅæóŽ0y®¦ÏÁÛäߪÝKrÁ¹E}«Ó=zÿ*ÙÏŠE»IÅËIŽ˜ÅK¦]__]Eus` ÈÃ%Hg©íǽtVÚ}žžlvÐ[¬mŒ¤ysòÿxóUn<Æž;‹Æc0Žð‹Œdúžiˆ½Ææñˆ œ JK³óêH8úæ‹ Ÿ ¸n'Ó«R« ‹bàƒýlj—°ÿgYF”â 'öˆÎP:+ÎõØtW‰Ö 3QŠåGÈ~Ô“F2rG {×Ðö:ˆ,á'K´.QK1…I'äâ´#Ól"]±YÛ"ú,*?¥fæÞæÊÑVHùžÛV½>N³S€ÄãSœûÖß„¾x–îT¿[*$ÉC;l,qÆçñ¯ ­ím­AðEc–òÐ.O¾*|ÀþQóÛcË —Š4· lïóÈùƒôªëâýgO•EÓÈu–<Ö½sŸLR1ÿ{µx¾£mui~ñJ¨^2U‚°#?^†®7WЧ(É-OPø=ªé:G†g·¿Ô­­î¦ºgÙ$Nݪ_¡¨üo¬É'‰dû-ðh4b“+Œg·¹5åÚ^^¹ò­ä;A%€ÈdMo<ó92ES´¬²¬l>¡ˆ5¬oØÆQŒ]ïsêÁâ]ná}Ӛзº¶»ˆK ˆê{©¼Tžy®ƒÂv²^jaL“ƪ2LDÌÔ5b½š=C>‹šMä»Ik wbI??“éHÄir{çük.ß Ï<Êʘüsý+¢ u8ú×â©P)om†Tm«ÏÞsÇè?TSlM¤®yå°V·.¿1‹ cüúÓí|NBr¸<}+ª‹™˜’BƒÒ ³Ñ%+p»q´øí­]’0ÕÜÑl„9ÛŸ^5çÞ3×/üE¯+ÝBÈÛ8¢'î éùõükÒõÔ}—”8¸”ù@ wþƒñ®+_¶íi,k¾ê/ݨþñÆåÍ*Tùbävуtù™Î#ϵ‘Æ<åmˆñc¯ë‘øV$¶å Œuæ»­>ÌZ«÷›37ZÁÖSf­0)„m¤0:V|ÆÎ Ç4W—«·6ÅOL½j“¹„£bÆ”„ê °À=ý«êï‡óZÏà0ZÈ®#kŽêýXÄ×É)#C*J‡æS‘^ÃðÓÅÙ·hÀ´ŸQžßð?¦h{ Gš6[ž÷Hv¢–c…$Ò‘Áâ±Z{à ¢©,óf%¥“9ô'ÿ|Šh}Ò4’.Xœ†n®úÕ¡b¦`'ØBʦî¬xçõ CµID‚q½øú«2E„}æÀß?ýzÆÔfêE7|±d~9$ÿ*ê¼Ú5û8È~£æ41£Öc‚HÑFì€1Ò—{/]Ü{Vƒ n bš!QÛŠÆÆœë©M%r2TÓ„éœÁ=‰« jŒÛ)þ”X|Ɉ·11ÀpÇÒ½zmýi¢Ö?îS¼œÔj/t\žÜ}EcÆáNrE'–Î( ¡5nÎk›Ôü  jD´¶~T‡øáùåÓô®˜`zÐ͵I'€3šI£Ã.šÇÁþ7½ÓUžk&€O%þμ÷RÔ—R¿–êeFw=Á<}k[Y·»Öµ»ë˜ci™¼É›' ’OåOÐ<1o¨i‚æà]ÎÌá<ÖÊåK•3Øu?È„É`Þ`òÍøoÀÖ]¾¹¬hY¶;”/ü³s§zôµpàd0éPÞiÖš„^]Ô)"ö$r>†°Cs}N{Cñ…¬ñlÔçòç$ó³ ÌþµÕE$SG¾'WSÈd9¸=WÁP–ÁüèºùxÃñ¬+)¯´ÝE"I嶸 €>¢¨VRØíüi¬>§E0dØÌUж v®ßŶO.ótñ° *ïQô#õ®‡S¸Ò¼Aqåj2F%Œmò§;Xb1ÇÓ­d¯ÃÍäÄ žI†p@ˆ?δŒzÜÍÊÊͺWˆ!’2a»Ó¤õÙ3õ/|\šE„³ hn$‘¸)(a¼Ž21œqí\lþÓ`“6W—eGÞga·ðÀæ§ÿ„L,i¶à³¿ª>côV×PŒck³•Ô¼Z몉5H¤žBLŠS,O¦ú dWqÜÞ ÝUI8@xnÝG­wV !¹ÿMÖe‘_ŽØ ƒý£ëôé\¯ˆ¼;§ézñ·€yQÂÏ’Ççõý)Í7ÔÞž_r×Eä°Ÿj•µbíþÎ+×_ÌÕ'ŒùdyZï,µRÖsþdѨHÎ>ó…ýkŠñ%ºZkOj»Ê›Õ¶‚OâIÿ#Žg&’RÔĉ<½Èƒ 'ëYz†Ÿ5Ï–ÄFàTñŒ‘ý kc#=Ç ÿŸ×°ëÍæ9PÅ0ýîÒªOqéþ}iFNãœS‰Î‘íZºùµºò‹•ç¿¥P¹…¢|UÉ ‚­ÑÊŸ,®}oà`ë>·vmÒÛþåò}:~„VÆËÓkà#ì›”ÐßÐW-ð#]7zŽ›#|Æ%” ÷Sƒùîý)ßoüIìC|¸’fÈÔÅY“;s] õkIuôG=˜ª[þµD…'•p^UOl0­ ÑÔÁù7³|ÇiçêM=òÅYˆo•HüóIl ç_ûçÿ¯PI8å<.¸€XÜÈÊHÈõàŸë[yÆF0T/NÜÿõª¾iˆži:°b¾ÀKy*ˆ%eÆÒǧ¦ þ´Æ<Ò»õÏá^ƒðÎ#/ˆK㈠-ô'‘¯< ¡Ç'±÷äþ•ê¿ àܺÛz"\’?•)lR=+‘ßó¤ÿz‘ïøQ•ÇT âcÖ—Ñ’zRàÐcÖ‚¢†tA–e\úšMÉ·p`sÓXÜ­5Ëž¨>§š¯5ÄÉ Hí·ç©fÇåþEO&Y[ËÔüþTб.çP|иè¸ïˆ&‹CÑÄ19óîxÊŸº½ÿ>ŸuŸjBÛKîFWóW%ã?]x–Qucª5¬Â0†2»£‘‘ŸCBܨùž7·7r@$W’6FaÔŒøzVî›0±Ó ¶#õïWᦡc}­NdVÁ–…ÐuRʱ㞟J˾±Ô-®Þ7·e=F>`G±ÑMs7g¡êÞÕí›XI!À2™%úßá]xˆ‘‚ÿ•xŽ‘«É§ê±ÝDF仟¼;ƽ¦Êî+û8®¡lÇ"îŒâ“¸îìLarO¶M`øžÖ¤Ï,éä_Ý»›>€×@ ïTõ=:ÛV²{[•%‘ƒ‚§ÔZ†&Ó<)î® —K€N0@aù±ý§;FUc·Þë‚ëÃÿŽà~•ÖÞü3»Y÷YÞG$}@ßOJ­7Ãý^(Ç–a•‡UVÁúóZEÆú„¥.†7R}žV,€òªÄ~µ©m«‹8<ËkiRB0[í-žžµþÕíãt’ÆRØÆr?JQ¥ß‹|9ØÍ;Ǹ¯&O6¯4ñª:»2dÛÿf®#Z»c¨¶Åˆ88#Ó®}k´þÈ¿eR¶·í”À®X[›[«û©bT_1£ËÉ`{ñÚŸ4z0„e{´\ðíËË®yþòTLÝñ þu¯„þÜÔ œ¨”®âz‘ÆOåüø5­´¾ Ñ^êö']Bð”ðÜò+ !$¿<‡tŒK9õcÿ×ÀüOZ£WÐí¦¬UÆ1þ÷¯¿òçÛŠÏœ¢ê1y¶1ó1=p>¼“Ú·ã¶UË‘•Qœt cóc°éY)b/'yÛqÇo_ÇüšÎ-'r欂ö$º‡|y< Þ°¤ˆ£#Õ%£)"PËœc#ŒÔ3é±^\·R €$gàïúñÞ¶SV¹œ©6k|º{/ˆvdœG2¼.Þ/þ<i|l¿~:û2œ‹[tñ?1ÿЪLJ4H´Û+=Z¹–úVª‡Ÿlçô÷¬¿‹ö†ˆWì3ûÕIâƒü*£+»˜Ô‡.‡ŸI]ö‹eú5¡lmURA8ädÿ2+€ç¯Þéd°ItdgüúU³ÝíÊ1@q ;öÊ6Áîçó\b-ßÔ šßM8yX$?+c»sW%Ô¡·‹Éµ\¶€>´³sq°(ÜÄ•U=[•xÌÐW›§°À55´®nnt¹VUÎqóU{û˜Õ€l•9éèN•ŒÉØ—å²Í÷½³Ô~Uí¿ íöxLÜtóçf@ʼ5Õ¥”гÈvªŽI'·×¥}'á'û ÖZvrñ'ïþù9oÔš™2ºçÎ3H8P)zv©$LZOZ^´ :Ð5 êª1ÆÅ¢EÉêÿëÔûp:Óö¤Æ™­#(Û©§þF¢ÝppßdL÷,ÃçW2)@$Ð;Ø¢°LëóŽzíbqôéü¨ŠêÛ<Ì€¹ÉàñWJqÍW¹€IÕê#ŠÓLrÊñ¸g¦àGóªói7&²·w=X É«8-².xäÒÄKD§#‘ë@:܃ yªx9®óÀ~"’è,å›ýã*ªO ý±éžGÔŠó¤¹PÆ ºÊF}½j]åƒË ¶Ùa`PŽÄr nÕÑúK#ÔRwýjŽ“~š¦“kz¤4aˆëƒÜ~y«€c¦GéXaÞ”ï˜wCL8îýin¿¡ ,Jô R‚¿Ý¡ù³ïùÓ‡ýji“aìˆÜ•Sï^C'‡[\ø…kbãvfÏwpF;ÈýHü³^·»œu¯>Ôµ­ïÅÚ›°EۂÜíúòäþŸsZwÕ?Åv=kÄ«§Û…6Úhe,?ŠOâüO®k–…B‚IÆ:_çß·SQBŒ¤–ùœœ±cß=IúãÐõ«?qsœОÞÿËÓ¿&°›;)Ç•5ÌpùKò™o¹ç:séÁ«FžR ¸çú~5u7›ªGŒãý? ݳåP¤rUä–=©5 YÅݶN7;óÀ²O¶zô‘­‹ jV:a’M>àÜ·ú¸2@ÏBqÔôöâ»Ïxì5=V,ÝpÑ@yûŸVþ_ZôÜ:ãéW[VsÕÄYÚ'‰ÛYêz~kfm$‘_blØß+g©8õÅRøåesN½Ûƒ=¶ÖÁÎIÿ^îÊÚ¼ëã&Š/< ·È3%”¡û­ÁývÖ±vf2©ÏkŸ7Ë…X|Ùá³Æ+¬ðò›ÈÁ]Fõë\Ä«ê+²bõpvœ 5µÌš6ËP€ Þ¬¸^çÒ¦´‚Q·o—¸ªòI÷­+{¶”$obF@â¬Ajƒh<|¨2]b™#vb‡ §¯½fÝmÅf•.Ÿoèkfq²99ùþuçÚàš=VG‘YVL=˜Ru=ᦒºç‹ÖíÀ{]˜øvdoY3g¥ÛŸO1«ªÇ¸›¡Z-‡‡´ëHÆP"þ8çõ«Çœr+kê[Z’qŽi9ÇQùSóÜý)zz~&˜¬#œþ¹ ÛŸ Å b9AHFy8>ù¤; ÎÁaŸöp_¯cƒÃ–öÜ .'Žê “ú‘]àç ý+Äþ&jmñ[[«*Æ13‘¼òOò…'±¥5yŠ*ù€íÆÁޤc=»};u=j;¹„3žp3õ?ý|ÿãÝéÈ̱‚Ns–àø}qÇåXÚß™)AóF‡æ×Ûó5ŠWg[vC,”´Í3œ³“^åðÉ ’k÷©ºâQþŒ„«OïcÔúú}kÈ|;¦ÿmk:u¹È¹”)#¨^¬,×ÔðĶöñÃŽ5 £ t¤UÝÙ…YòÇ•É#œZi“±úÓ·Æ R€;þµ|§ €“ÈQŠÎñ–5¿ßé¤ ÜBʹ=·ëŠÑ$7;Ž}©1ïŸÒ•šñÖ£e=•ÜÖ×´sDår©ü9r¶ú¤lêYTœ¨ëÐ×´|[ðGÛí[_ÓáÿH…ÒQGßQü_QßÛé^hÆßQˆŽ2ÁOãZ'rÞ§§Zj¶B¥[*dŠ®Ú¶fT†=Ë„ç딎âGvUUGzޏ5§j®Àn$6x#ÙªŒÚ7æ—tDc øSQM¢ í±ÊV[ràœpÊ:ä~¢±#$Àæ´a•mÈß:/€{ð¦#Ü` ·Š(D(PÀP8©U$wúb¸¯ 럽‹Oò’.abz{WgŒ?JÅÝ2ôh“¯~|ÒycÿÕM‚äŒ~(2&~ø4]u >ƒŠ‘ÓoãM;ºsjPÁ‡ò ç¿?SŠgÌoçN½.à=áAùºP=ÀžqHÞ˜ÈôÍ!ÇLÒmÀôô…Üb€ÿ_Æ“Œc9ö„¨ä¯çÅaïé@L `cé@zþBŒ1ägó ‹Rºa xÜǽz?‚¼7wöÑÞM+î{øöÅpz8Ý©Eõ5í^#º7 ÕFÕöÏZÏ&ŽŒ{˃ˆàŒ»`+çuûF¹©Ë;æ\Ì]ϦN/ðè{vž-ñ¸ñEˆÒ4«yI ³–#ø@³Žj•ŽŽúÔ…f…d…YC) ÷¯øð¾K$Ö´8÷ÛæKl£&.äUþUî[³ü$ýj®¥y†™uy( …å*;…ãô¦\ù£O{kÈvÊ JŠÝzõ¤è60¡?rW×6¥qv¡PÍ#90I8Õ¹gtnCîÊñÿ|Õ ’5 çU+ ù¿»þs[°Ek¹P+œdëÿ×…§H>ÐÀœo8ýøVÚÉŒðÝ¿ÿ^¨†Mníæ‰‘´pGQ^¥áÝlk:`~VhÎÉýñ¯–ök{Æ‹ËÙ p®;{W ø>ÖîÖÔ꥕,€Ä¦C÷‡¨úL•Öƒ‰Ý}Ÿsd¸üèXâ¶~˜§€ŒÝ})Ü€¤zÀÓ™‚ª¯+Šç9úÓN?…OÓ4 yÀúšbóqíô ííÉ÷¥bsÉú ˆÊ˜ùx>â‹‚W%Á9ÇÐf“ä/æj-ò7‰ÔõYOÞÆ?Ú£˜v°ìŽ„ôlSü$ýiÑG3èi2¤dߎ*®!Jíþíz1ü(Ëê>´žg©'èh§ÇºÝ©¡ô×­øfïË&@ï^UáÈÏžÒ‘ÀEwÚTÂ9ÐçŠç®ï#¯­Ú4É÷¢œñZå€ã9®WC¸ ÞºˆÎôþTRfU£gq ¥x}+ŒñšA#êm‘°±(Æ*ìe’8Fé]T{šäüQy¥ê:y†)§S˜È^÷Ít­ÌÑçÂâ@¥clóÉlgó¬mvõì­I@žSµJž}ÍkH¥ ób!ÆzÖ'ˆ-÷Ù¬ªwl8àò+[‰®ÆÕ–‹ýeca2hÁuÀd`p}¿¾8«šî­« &w¼ÓçBÑ…W‡kF¤ðX‘Ïqù×-¥ksÂ#ˆíf: ƒ¸týFø×eG¦MuspË¿pœñ둎NyýI®KÙêt[K£Ì¼Um%±‚XÔ=» ]Û~éúŠÌðìã]€iߟ¥wk½Õ€Šáw£¨Áªú^ƒm¤Ü<ðDdfÈÊjê±ÏÔÖ<’•™»yB# s‰zŠô¯j1jÖ-ÌP½Ägh WÔÿ*­â_Dñý§KƒsŒ—‹q9úgùRæÖÌmz÷›˜ín¿ ÈüýTðZFÞJÈ Ï üºS™$Þ6)—‚Œ¼©üj ‹ó3,ŒÝÈã?ʨDÉ7•(!ŒL§ bº«/j°Y„QÔ®Ò\‚T;=¾×ô¦ cù‰.êS¥KC=JÏÇÚláVé%·“änQøõý*ω/m®ü¬Mkqˆl¥åXà5åJϰ·Èð<¥©\?öEòC$‘³BÀ¨8c§½.]E¡ç±>ì¡ê:V–™t`¸U9#5†$(ùèA«ÐL7,Šy4Ú°“¹Ú$Âða]·-´däŠèTãŽý³ÈýsXúLŒö¨öå[fÁ±râÚìrz w=E3'¹¦_hßð“Ý>¸×eŒ–TÞGðž{Õ­gǺ¦·ºÒ ZØ• ˆ`ô>µÄo¢Ò"Ô F{·($µ·BØÈå‰ëœã8¬ý#ៈ¯vïlácó4σ æ¥M£^D{…¤’_ érI¸±·L·¯² å ýj .ÑtÝ*ÖÉáoÇ»Î3VK z{TY ²=òwò¡CŸáǹ§€X9üi…AÉ)Ϫõ©qÅÆ~ôƒð©B®1€ß^j¾>Y?ôeþ÷>€RZD¥Oc¢h·OÐÓüÁÐ ýiCw'ð£FJº!6þøôá/÷›ô§ç=¦Ž´¬Š»`ÄmÀAüÍCæ0ãÊ’W8ùXãÐÕW•wr~´6\b|ɧı"ªŒ]«`éX¾KÁ)V­;féšÆ[‘Ðõ_Nsžvv³d W”øvõ,`þ5è¶7 F3Þ¦.Ìš°º.O¥ÛK;Hè\¹É Ç¡ª×z5“@á-#m; fýA­â@yÅ.ò£AúWR•ÑÉfxî¥a<7OïÓï+ddýk›Ö1§\)ˆFÁ{õÎkß§¶¶¸š(Üú2üë›Ô< ¢ß³–‚XËäŸ-þ\ýEiÏÜvg„ŧ,6V÷°Éþ”£ÌuîAç‘®Ö -n­Z+dx Èdç$‘Ãg¦IàT´›L¥&“H‚ÕäKUAÛC.>`z™ ´¸cÈ?CZ×Ïáé%†âÚëì‰"ò‚–)ŽÇžõ¥ ø>/XI#Ý@XãèqŒŽkK««õ0ìõ[ý=ƒ[É³ÔÆp*í4ˆ–ÑØˆïÄÓÜî ã|ž¿…g\ü7½‰´»Žv[ ëÍR¾ðVµi*9Ôuòâ?ƒùRÑ”t>.Úúi¾›E(Ò¶q2–¶åEyá”ùnb~î?§ZÕ>×&³¼u!YIúSúӭ¤Î?ÚòÏÖ‚32û2Ðäúçüš±\ùËôªî££êRÄ—qÉq• s»ñ¨dÚð…÷þ½iŠÁòl$ÆÄ“É"—÷)xÊŽ}>¢’©‘0#Ñõ©-­ZöTŠi$™Û d“@=5¹„å21*´e “}Åz-ï…b´žkyá•.¤\°•'=Ó5ÊßÛk ñù‘ò¶0HÍ Ík±sAÕæ²o”Ÿ(þ•Þø ?·üY¹;¢´C:¡èÄ`/êÀþæ ÖéX· ld?8>ÜWsðë]MPšíá2¯”cÁ;zöZ†ú#U§ÐŠÜc¯Ö“)ãŠä-<}¦ÎØ–+ˆ‡«.Gé]–¥m{›m&øÉÀ`+6í¸r²âœýÖ§û³LóšBÞ´¹…bB@š~îCŸJp à SDÌÿtÒm‚²ã½?cÈüé¦5Ü=}ù©w2õPG¨¥nàß`XØuäzR°NV0·¢ýi¥rMQ:†âGÿ^¡Ÿ¥9œöÀ¨d‘±‚sI²â™ ®zf¨¾àß|Ô·.þïãYÏ8Ü~sRj ¾r²Žè܃íRÚ¾@®‹ÆŸIe(… ÉòÛÛÐû×7lŒ¸¨’±µ7ttZ]з¸RsŠîôíMYWœ ó«ub£ŠÕ¶¼–; ÉšÚçªé³‰™³Ï¤z€?*æ|&fšÑî_*ò¦S]9ö®š§%Eïh=†G"›·jðÀúdÒ4˜8r@íƒ@ecòƒŸZÐÌq+Œ·Ó4…¸"†VR ä{ Br­ŠCЭ –U–KhY×£:GК³EùAãØTyþ÷é@gÏÊ€ýy v$ÆN;ŠvÒ9Ü*1¼‘¹ÿZUC´‚Æ‚lÉ=ϸâ—{tÆ©¨ÖCžxÏ¥?<óEÅnå]OM³Õ­ü‹ÈĪF O¨5ÃjŸg“LºóWþyKòŸÁ¿ýUèY 8WR[¹´Ë”³*.Z&n8±ÇëMI¢¬xÁ°òumx­nRM²7Rž§Žµìþд½:Æ;‹%iEÿ_(ùˆþ•äÚx—NžO;ÃÒ\IŸ˜ãxü1Zv¾&ñƒâ ò8ûD-دë[)£9FLö ´Û)çy§·ŠFtÛÔ8漿âÃ8¯ìåÔt%†) RÍs‡¨ö¬›»Ïë¬Wì7±«q‚|¥ýH¤·øwã;‹yÖMe,–a‡ŒLÍ¿ëŠHì%I­nyôñ–è*Q›l\`‚Cò”gÚœHó¤ =9÷ª$UfîÓÁfÀÞšY‡Ý }(ó2y昬#0Ï94†CÛ¤ [ üê&Ú3œçéIÜjÂiUXõ¦™æÐLy êßMÑJ,‘”(ÉçéUd”×+`íúT)sóâ‹ßcEnT»•qž>¦²dž=ýý_»ˆç;xöæ³^=ÌNÿÌP¢jŸcÿÙ endstream endobj 2408 0 obj << /D [2406 0 R /XYZ 89 721 null] >> endobj 2405 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im4 2404 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2414 0 obj << /Length 2487 /Filter /FlateDecode >> stream xÚYK“Û6¾ûWèHU< ¾Ä£ë)§ìLU2µ{Hr€HhÄŠÔ¤ù÷éøLJ½@h6ÐÝ_7ZÁîiìîßÒ¾|óó§,Ø©ÀOS•ìO»<Ø¥AâG©Ú=–»?¼g}íM·¿SIàEû¿á±Ÿ²w»»8÷aÄφ?îóÀ{÷ëýK³ï[UÈ´¦aà}ÃÇÿÒ–¦æo$j—ûyªRùDú‡ uŸ¨ìþ. 3¯pÒáà{UרK½kg¬iz&÷(v@ HÂ!¤œ@8¾¡ˆÌ.õÚãM!ô|~ª:Û¿…~{UÄ#…¡Ÿ' ‰eWqæUMßµå@×§Þ‡‡ßÞï£Ä{çó4\oó»äDK¦½¥±EW Œ.μ¢=1…®;Gm«‚»'£{t€+cÂÍb> 1ÒM9NV0š¢¯ÚÆß:YCŒL¢ààºaÚQæÊŠ5QÒ5Š ‚5¡‡’µLë§S[×-nø^5OˆƒËLm. zËwÜà^¶ªhfU*ËüDÅ 2‰:3Ð[ T‰¯òÄ-EU*õÛÀÏ£Ð-E«[Ùàû‡<ý?8–º×pà-)£Ü¢Ì-De¡Jîâàà§a¼ÔÌö§Â`<§¾^ëªÐ¨]vÐk·ÐøìS‡×¥/öcË ÀzMwÒ›w‚xJG&ßÄ™qo1‡1jèõZ(uÅ¢¡GFŠ“mô±%õ‘ËêÑo®ºÓ½©_öiâù#’Á‰£Ñî÷“D ”pŽê§`$gä‡`ŠAxŸÁ5÷áÁC÷œî¤o¹eOÈÛ0¥|• €NZ—·ÜjnJóg¨¦âO O‹í™ížø]l¿wUodƒ,…Àô¿ÁX»ö™V>õg 4!êAÄS7?ïä»èF?‘"˃íht|9âÈž¡÷•ö]‘ï¾k‡+O‘_ï™þ2‚àJÙu¡°óÛý`ÊÇ- ü%¢Ç¹òþ½•îªv°Ì¶hÑ.‹J×Ì™p 'š¶¹[OV—+[ ºp 0ø»²›h}jÑJÌgŠTÐŒtMÆ ¶O˜ºèª±hÊžh¯¬‘ ‡öÅöæbQA²d{ƒ%l‚fµkŸ:p½q{­›§î˜WUMi®~šMéW ΂Ùv¡N 8iÆŸ?~ÁˆAš³ÕecâÖ4¦ÿŽÖvÏLM1s €Ó xÆ}Y|óP§±<ÒYeK ]{áø J¬GéÂÃóñÚ¹·¸3$¸C[Þbü',Õøé'‰Õ¿è½ÂœN Tó–wxxÿðEú¿_à¶z]?KÀÆvðÞ}ÜÇEn$ÿU6ƒ1ðayWè³`a°Ä]Šå¡\<2ït/t‚Hhu!fMƒé@U­µ­´g!´Co!ó@4[—x’$G¨°f‹y'T±± \ºï!]A‘†Žs‹›qägSØ•€¶â¦þ!ƒžøÊ´ÁbîH9a¹Ë?IòzM\¸ÝɰCŽ­ÜM©ù (ºs¸ZÈÑ/€(I«nê%oWÞ'„BZ`{ݰ꣠Ìë<˜trÛ57 ¡îÒ'€;ry¼JŠZ[ûvF|ˆaE;Ô%w)›Œ\¤9°[n×ÊÕ2€3b:tB`lœöXÓ¯¶4-x§®oöÓ=Aê.]XÍŽA3ASSÆ ~DžqsêqaQWª¨O—{Š Ò[lCÉ0òÔïLa8•uYÈÙìsõÀ‡‰gJ'Àž)ÝeÞ(rk+wÙ±ˆ=r¼´}ÛmŸe†·©ÚVã)Ôʲå}IÁÎBV¶Ó;[·O¸Bʽþ¬eÉK;p§mê‘ÔqûdzŒÛÑð b<‹]72E ­’G·€îµ@ÿ¨]~Î!Á©—úZfY½SÉÖÊ´¼Nóä\›Iˆ™¡ãgÝ×O¼‡pp@~ )îƒ é$ÅÂØqdñÓQŽþÜY—­l‹³•Â\ÅZ Ã]Az"çFƒè»B^^ ›¦í¹ßéʺ³Á|"ñ˜Ó—õœ,O)£(‡¹\É2cÀEŒhC-,OÛÆí\…Ó?\°…m©à9“ú8ë'DSº°BR2„^óöÚr ŸÔI,@Ø4vêÓ‰åSnù9óJ?ÈPÌåÈÄm˜vÏkzÇîž áq¼T"’Ý:nèŠõ ÏÑÕÇ19ÜÏòlÀñu8Ö\ˆ8´ž­¼«Ð(}~^ÿj¦;íÀ´jÃ1VÓ ‹¹£âk‘:Žož £J—ñ 4Ä«¢`ì²I¦•L´t. €Õž%Žð!8ôÂ…qTͶG«l_ИeÇY¸S+ßd¹#<àÂÕ•k¿‚øhÌ$7+  ™Vª ³6;$YnOC_Å®+æ”nÓŠ ›tÜçÑºó€ ¨ðʹV5•©`„(ùò|+Y#´’òÂîíE3Ï}ßçB¬rÀ÷]€qS J#üt@ʨ!s n’#äöpäª <íFVyî" ¤=W  {‘D3³O:cÇEMq~‘äüðزP'±)_Ç)|0AÂN.EŠª.¦«´{fCÅe ·³H@›šåôÚ;, É‹0É]äàá:\8¸üÖh&\ÀWù8®šíŸ€êîu0âÇS&µÇ oœ*ÍÀ©N<É‹Må“'C»ÂÙQhdæz985Y/uY‚l–gì•_FqN¬éô¸´„A_] “ð"dïfÒÐH¥èè•X˜’sÖÄ¥8Á÷år3˜ºÅHM?ŸV«æGƉ‰ŽùÄ©YlÊØ.²}<8‘¯b\g&ön ½¸$ÏØ8"ߓЦè {Xxä@]¸QWöÌuÅ%mÅÙ"ŽÛ®„$½{aª‹N<'Y”Ф8¥Æ÷&|®*eÊÉ2+Øugʉÿ‰gËÆFLˆ2Ëpj“@{}[´õëN:¦ÝXfá:ô”àÀRbSTÖ7 ÝABN¹*ÌàÆï.ú38¢»½Ü¥k€¹T¶ÔMe ‘/K\é<%$¯M/¢ÌÿÅ$êbcnívh‘÷h~X´D 8«¦Î>BÅXs”ú/àÇÎÝœEªµRÔuuÜñ;ÆI0Õs]5¸l‹A‚Ä–„úŠ®êo©e9‘ï$Š R? ᕟåþ!—PË»ÿ×ã››6» endstream endobj 2413 0 obj << /Type /Page /Contents 2414 0 R /Resources 2412 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R /Annots [ 2409 0 R 2410 0 R 2411 0 R ] >> endobj 2409 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [235.287 399.036 242.261 407.783] /A << /S /GoTo /D (cite.OMG-page) >> >> endobj 2410 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [339.718 112.112 346.692 120.859] /A << /S /GoTo /D (cite.Henning) >> >> endobj 2411 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [217.282 100.057 224.256 108.904] /A << /S /GoTo /D (cite.Tango\040web) >> >> endobj 2415 0 obj << /D [2413 0 R /XYZ 89 721 null] >> endobj 54 0 obj << /D [2413 0 R /XYZ 90 690.045 null] >> endobj 58 0 obj << /D [2413 0 R /XYZ 90 450.03 null] >> endobj 2412 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2422 0 obj << /Length 2966 /Filter /FlateDecode >> stream xÚÕYKsÜ6¾ûWè¶œªˆ ¾&7Ù–oÅQÊVekËÎÃ4Œ9ä,Á±­üúíø2#g·ö²—!~Æ×=êâáB]üðìùݳ«Wyr± ·Yœ]ÜÝ_lÕE®ŠP%éÅÝþâ}ðâÇë_înÞn.ãT:Ü\¦™ î~¼á»ÍV×?ÿpËÝ—7¿¾~!Sï`Q¡‚_ýÚ7·/o~Úüv÷÷«Wi<˜D:T:uH^¬‘æ™A;u%¡N²©/=ùeœ Í‹to.#¥@¡ƒeqÇvoëq VÆaœe¼’éó<ØW•ܬöÖ`«Ú{é=ÕÝËw·o„Ê1Mß MgMÏMkÊ·öv§Á§ª”õF™†UãFÕb‡Y”ùhw¿Û²_1!ÎB¥´'ƒ#ÑÛ8¸ùS™¬(ÈfÑΞLgz™´M_õÜþ|¨€ȃ-Ê4¨²½¸Œ¢p›Š+Œpªzi´(és#rMoDR³—Mµ³‰(Óv›4ý¶®ƒátnªe®1G;UÔŸXðA©Øʱ•¨ÕØþó&RAÛ}\òq'SÚ,Vbª¸ÅËA/äšéÀt¸&K€Í&*‚‡M VVؽL—eÛí«æ‰À'¾>Þ(7·¬sÀ~å|‹0ŽO÷²| dÍö „ílÝ6"[³?°á.‰Á}O£àº®'ƒlF·no»Š¸o¢4ðÆÝwí‘Ý"Ê£0Iæ^Ñ6tãÒ kÛž[Ä›°‡³ãAS×ì.¬)Œ¸ö(KËöxlnÏ|†xÜsƒXpcÜ2-N‚W¨p{Ây ´è£rüÈõ¢Kif½x·hûPÖÌ-ÄÖÙÖCù RU·%èõÈUhQ!p7r?é}@rìvÐ:u-(î¾ã§@ÃcÛÛ¯™²ky7'Ì&N :D<øý,r^DY˜è ÏŠÅ€qœÎ©Þ_¦6o¾Ð—ç^˜²¯ÚFÄ~ªÌŠ?à¦ùvpg8B¸÷n½gŽ})KX¥ìi•ÞZ³¿zg{VA‚ îãÉ–táKÙ“–¿rAvqJÓ 2Y üge;ÏÚJ”Þ*…·Ûô}WíÐaaïž¶Þ¯üK'òbþ©:ý¯­;[]ü˼bÚ¸-2pÖTµÙÕBpïo—„Ž)‹¥Õ/nß>ßè4¸–³ƒ çÚªÿöZù`÷±±Þ\Ò°ð[ÖÙ1fwÿ¡íÉ Yã§aCî¨<Ø:™Ÿô \h¸¾íÈkøkø#áŽ;+=ÝZP‰²<,¶Ãã⢩8g; {Ÿðš_¿iªm<ÅF*]¼æÚ¿æ¨NÛà1<œå ÃÁ·;®8 ÙzŒRت|¼ „ p;ûjõ]¿Ôù6L²ÅûéÁ sçß ¿›éø¬†à4LŠ!ãm€ËbWD#²ÔŸ-žÕYG±£µìøCµ^"ëÉ™üExÇs¿>ù |ùE‹£à`M×ó]q.fÔrûú)~Q@;ôÍÎõÜ!îÁ1—öÔû¥ã̓îîñO¥EÁkaؾFœœ¥„Çâaæ @``¡#š/2ñ®êå‡9áY¶p•(J0 3ŽþŒ1¹²³Vd@„ƒ{ÍŽñ»0jìz{Wæ “¶#V°²Aœ² êö¡‚ÛÍéñ`_4Àfo€-ƒ] aø•Y€»ª1lÍßã·àNëÖM¹  p[c$cE1Qr \kQ¦1ì3 lS†°rºUú«°¶Mßµ5ºGس£h‹ø)&‘¹éÏ ‘€P3ÛUGÚfÁ?6 Ü÷þP"³î0‡6ÍC n§uêµ½'¨‹ë)õ©÷ÜáÔ (µáA±´Ÿ´~³öí©‡ƒ_ó`x*×pöú°è2ŽÂ4×ówðýÕÕ«MžÀ%C^¼þéõÝ?¯~{yûæúõÏW/~º~÷îêÍÍ›ç7oå¥YcA@Þ”UÍiiº…»wo;Çm/[„''€û‹"jÐYàhÕ¸ÞÀý§D ®{4²ÁßäîλK>VZhiªÂ8Ɖ/4Žö¸ã÷iy[d™Ôâ?ûÚOO\Ègör†}´Oc¡E.„wÁ:Ÿ èàxv=s2µkyl' †¬ÚŸÑßaÄŸÉžjöjØ®£¨½ó8Ѥ]s¤ŒóØôæËº,!]3¤Ir35øõf7/Χ’²QÒÙÉôl/ž,"`\Nb* ê$¢h3ðÆ z\¤£ÈØ…qê„`‡·„~;{vt"H2?#œž «D ÊKÃ÷^‰Û¡¹ i·]îoù/]ûЙãqxA$(*‰ÊWŒÆ\‡ë‰X´5ÚÝsºçÁ>¨¤…>{ß¡?ږ挄˜jQßÂAªoQ‹vhp±—J,ÀA ±ÅRW¿ÉpR)†âø V€¼Î¶Ð‡¼e® ]$ðXfsë9•SŠ£mÌ ñÞ¬ó< c•M£x+Á3Ÿ$V^Y:F!°Á{ƒ­I&9Ч\ …m¤VŽ…– v¤ÌͬϧÞ@²X4žÌáQi_MÃeÎJžPøNó[ó[ê³;bc‘àÃŽ¤ò&¨E•úRÝTzx”ž¾Ð;q3QePw(pÎ9¯â¯=ÆDåÁsŒpî+¼¹•„ÖBê±4Ósà,ä*#HÙúZG¡5 rÐ=…¶ašA3Z)×£wƒ°ìh>R.xq{ÛžYK†p"-à~úo±‘ÀAðÁázÃD¬üÍðsù—¾ !ûÕÊÐÍݳ×] endstream endobj 2421 0 obj << /Type /Page /Contents 2422 0 R /Resources 2420 0 R /MediaBox [0 0 612 792] /Parent 2395 0 R >> endobj 2423 0 obj << /D [2421 0 R /XYZ 89 721 null] >> endobj 62 0 obj << /D [2421 0 R /XYZ 90 690.045 null] >> endobj 66 0 obj << /D [2421 0 R /XYZ 90 462.678 null] >> endobj 70 0 obj << /D [2421 0 R /XYZ 90 150.827 null] >> endobj 2420 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2427 0 obj << /Length 3661 /Filter /FlateDecode >> stream xÚ­]“Û¶ñÝ¿B¼$Hö͹8Ž;mÝ&7yI2JÂ8–H…¤|¹üúîb (Q9»ÓX|í.ö’«Ç•\½{õíý«o¾/²U%*£ÌêþaUÉU!K!³|u¿]ý’Üýðæß÷o¼¹U¹L´¸¹ÍLîxK€û›J'oþõîu¿{ûóû;ú •2ùÙ¯ýç‡ïÞþãæ·û¿ó}®¢³T © @ǧ2œóJ2‚«[?~« X£iÖðÜnv}×v§aÿ û—yò«Ì帳ØÉ’Þþ~²Ãh{k¯÷ÝæÓM*»¥S;6{ãµy²é‡ºÝÔ¶[»…­Sëz×_‰Àû ]@ÓmšŠ*gîÒ|àϧ ‡7|7õ~o¶®×zÚÙ–Za› wèÜ…;:ÍD•eóóïh>£Ó¤îq +oÒ<ùìæ4º“aø44í#5Ç'äbG»?~{£óä -¯Ç¦ky×¶>Ø-]|!£‹WY%@øÞó °t\“"YYùÙî"`óèètØçÖ‘{«u„ê9ÁL­Nãò%V™¦2‹X}t·¾€[*S‘ªt†œ;a†Bx¿õH–ÉýΖFG±³P§ÞÿMš8ÀnM³†£Ý40â¨M³B”iqF­wÞÜds8îíÁ¶t°¼ii€„[{£òäs³±4¡ïº‘F6ûzx;-"Fè˜"qμüìA.Õˆp•1¶ÀU9Ö,+QU_±!d™…ù Eq+“™(tÅÜ24^·K$)!‹€b3|„Mº'/ÐsK–‹2«æÔ1¦<ã=Zúï¡1ã=ô=Ç¡¹¶ P §“Æ‹'­Ç­ÇÁÚäW¸¨U*ʪü"¢nuQ‰R©+‚•gl¤2Ç_¥TìëdìnëÍŽZO4ð(%rÕ?®¨ñã»WîàBèBiÇø ì•ÌWZ˜”/(¹†sî‹®ú6šŽàe<5ƒ}í#{6GÈÆ™ÆÈU2×Ð)vçÎqßÀ FŸNRˆ/¸eUŠ<-é\-´P RJf0Å:2Šuêqì›õ’ °rXàºúRÞò=à©3X¶Ý6„5öGüz¿ðÕVÅaŽN÷?ð&û§ã±ëGê´]¨÷ÍŸÎOàºz¬ùœç£_ëc ·Ï /ë¥.Áƃ`DЦ¾Z/sˆ ï&O]) ñ®yêÞ’ã‹!x@69Î1¶[ö¦;¿‚XÀ šg‚}Ý̹ø„¶cÈŒ—0Ðëœv5ÛÔe'¬­+¢cº–¡ÝŸKªuÆq´IklñÅ)ºÙJ°íè 6îÏ+:ü÷iW´ˆ/ÀÖÏ£¥ÖÁíh>2´SåCyy êIÛøI[0 C]`ùiÏ“FF§ÿÖƒágš(ÒÕR%HO#·è[Ó'˜0ì ‹Ä/ìyæÓ‰<-ÓäSã§û±Ïˆ_½?Y ÇŠÜÝv|doÙ´"2c’w¶µÀDÝ6Ãq_?SçØw}ío­]á;ÿÔ’a›£¨&ÂYã©oíö#Ô~ŒÔZ"nÚãÔ‚WŸÓÑøÙÇý‰‡¼i9ø€BÌÖû†’êš¶9œ¯—ˆ:ÔИ3u¿Ÿ@Æg¶½ãe'EƒX¢I~ì "YãnÿÙùoн™Þ‚O<\ÏLbÈôåæ »”®ÀàŸ¶ïÕ,#…ÃA— ÀØ”©dx½„ Ì"eEËð§)ÜÕxNÀO§9(öd°#Ÿó@ ‚ö±ñÈYñˆl‚ ßs±×>¸¤—o5‰ísÑ=@ð¾îyÆÞ Ûlú®yÜ v!ÁJá±Ê°Ý{°}O‘h"ÑšºœSÝCøÌ2κ¡¸ù\„\|”bf[oÿ´Lžúfd¨»½up÷.‰LåY."ÉÌb#8<ìÔôÙ7.sNSºô\ÝÖ&¹sþ8Û1àÅírŠ»Ó%Gynßúî€÷-ÙæKÚ¿´ ¶"GŽÖ'¯H‡:%L°ûy~ºÓ{ÍaMUqXC3OƒsóRN1Ü<ç® ç6¡ØÒßÀ­À©_ fL)2’õŸ:*=äÌaªTç.ßüœ6µD›¿W)eJ¦L™ºJYj´ÀEF¾LV!E&‹%²`é/O ¸ ¡% ËÎKTc”†PH_FþNKŸÎAc¨Üj-›¯þ¸Lôšt%¬Œ‚63Š7\8?+Ò9£¾\ª\dù¢¨lbX‰fÏöÏÔÄë,gÑIŠ4¢Réœ#T<1ã¢Ë+v æÒÁà s‡&˜§%UHòH5LP Þp/2YIË£çÌø¸éZt L)+‘št‰+FWhÒΑi䑸"‚䉼X2t¦"°gjŠ ¶\ì£!¨áˆ™m-âܺšNuÑ*~cÒDñ%¶®0ÈU˜‚ ¾ŠA°T.2('_åÊ`š"ËeÐûf‰ y&hŽ9Ûƒ òp¹ôûris^"yèÇÕK7˜÷€JWoì—…'*¼’BûÐô£u6B…X^M±<4©~ ù=ÀFÆà•,Îéûú™œƒ‹7 §… L> x.g«”ƒž«1 ðôo Øͬ»nùj—†àg´r{ß9Ñ‚qÖŠÚkˆWñ˜ÅI&ãŒ)žä¢+ÝÕ~ßmwàÎ hx¤€S®È9d¯‹ƒ1nad!ò,/0¶† †¬!tB¤RdL,çõMM— (—ïûgºþBG»¢¼º¨ô5ŒÂU]/™‰ŸŒ*¼Ð!º²Êû…*uDÈ_ùò¶oÔ)G7Xna!Ï(£ÀõáËwÀa¡51VCñ­ÝÔ§aŽ…LÚÓaíT®Jõf<Õc×KòNõWÊn‡Î¹},?·h ?£üø |FÜ—¢*\G,h\áÃUÊé±ÍyMΩõ|… Krà x® èÝ-´=lžK*!i®ˆã—*lÐ8vÃà ãÑVYâX‚š>Ov¿_ÔóÉÍÏ‹+,™)æi”bu†æyŠƒk'¢n+ü ô(…%à ë®L…êÁG¼!ÐÂI¾LÃÛ×C³!›ÕѼEâ¶0›_‹|MÎ,òT$”‘†8h´9GM×ýÞÐBgìj.ñqá‘ †µÁÄq…‘ój‡ICõÄøGdãeÚ²ä‚ëµÅ°D—Œ¨v¯WÔ opä(Rz^.=ʺä^—TjÐ¥OÇ EÏÃå¼¼m2³8¢‡­&é)o—pÛ‡ ‡wœª új-„+ Ûlôôå´X<± ñgâôî…%gõ„´Œ20ZÓ'öeît™¤÷µ0eÊ$MÈ$Í•„l¯ÈÍE-Á_÷ÅC"M_Žâ‘™•šÐ/¦jQáÒ9„ÄøÔã_f~Âä] }q=ÖÂÈrž_Á=+Ešé¥ôå/æ2AäÒ&ÊøL*Šü,ö6$E”6®&ç\$@ЬH€CS‘@§>}–&ªå¡N:ƒ½Ä­…*õ•:ÁFJäÕr™¨0Q±Ëøò"SÓç²<‹²È—ÊøÌâÊü¢â Þ¼ãc ?âÄUMVÿMá‘z^fÎËJe§öXÀsþ*×5¤ï‹Â‚¯Go.qh. qä+†pâOâ’kQœ?•úèÍGO «¡@QÖT pÕd³=…–†V×xQ”¢,‹¸ð"/J!õbÞ¯‹ð÷<‘òþ|ªº#!qŠ}ò,…Š|?ñ#3¢‚¸~ÆÿwÞoâg\ÌIZðÆN‚3Ê{êƒyí zY¾¥z;ŽÍ^zs¯ô0°í,oC€Î‚–Œb$\ÕÛÛ8ʲðô›ûx(‡s¾CàÕlþ4 Ð)ôÝéqGïljs~WqÚ§òééÓ bÄCÍYJR’NEž£ 8 ¥ÛÙ+rŸîæd²\È€LH>²'ˆRÏÃ#ÄÞ‹ñó”#ÍÿHÀF;ç瀜JÀ£mÅìµûíý«ßùÑ«ôâ¹øOWDÿ›r é=òÅóIJ1¨¿û°¬Mƒí™ß¼]·u±û›"ņoH»e³ÿ M˜úÿ …üXò'6Ý2ýèWÑ?^äÒY½ôpùd}=Ñ¿ëú,Þ¿lBŽûJ‘ñeX,Yç_´ÿÓW›$ endstream endobj 2426 0 obj << /Type /Page /Contents 2427 0 R /Resources 2425 0 R /MediaBox [0 0 612 792] /Parent 2431 0 R /Annots [ 2419 0 R 2424 0 R ] >> endobj 2419 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [233.908 605.198 240.085 617.962] /A << /S /GoTo /D (Hfootnote.4) >> >> endobj 2424 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [476.856 534.09 483.033 546.854] /A << /S /GoTo /D (Hfootnote.5) >> >> endobj 2428 0 obj << /D [2426 0 R /XYZ 89 721 null] >> endobj 74 0 obj << /D [2426 0 R /XYZ 90 567.714 null] >> endobj 78 0 obj << /D [2426 0 R /XYZ 90 295.425 null] >> endobj 2429 0 obj << /D [2426 0 R /XYZ 104.346 74.965 null] >> endobj 2430 0 obj << /D [2426 0 R /XYZ 104.346 65.18 null] >> endobj 2425 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2436 0 obj << /Length 2387 /Filter /FlateDecode >> stream xÚ­ÙŽä¶ñ}¾¢ÕÀ¶¬£)©óì1k'ˆw‚݆Àj‰=MŒZRtìxþ>uQ×h& ;O¤ŠÅbÝU¤¼ÍýÆÛüxóîxóÃÇx¿9¸‡(ˆ6Çóæàmb/q½½ÚóͯÎûŸÞþóxûy» ”ç„îv§"Ï9þtË€ãö:o?ýxÇŸnùÛ{Yú›ÏùÅîýùîÃí?¶ÿ>þý‡*˜¸÷C× c`‡Î âÜx pçm|ß=(ØØ;‹¾ b ò¦Ð Ýývç{žç¼¯®×´Ìßð©i×5æ´ <§ït˰ªá±6µýu…1o³ó7JøˆãE7z» ½ƒ“ò$qÊŠ-œ‘u kú‰"8«ÊL7¥)ïyéñ’v²áRõEÎГPmt×7¥h:Ð i„¶nûBH ÀשšëE#aH‹,M]è«.;>-”Ó`ÜúN)Ó©â„z›cÃÁ/öÑÁù¤·r¾m}å覻hPE †ýè™!p§(2t®•¥yZluã±jV_¶ÊyjM– ø†G¦E¯×ä|¼˜ì‚x±sIñpæ !ó;†U;Õ™:sÕ ¶¦ít™á¾§m¤üúíR?@¯h«õ³âAÂÈ©›ªåVB<²9 °š ;a 0`'aK¨×^5jfZ]<œý¾ zyä/ñ˜ TZ ÝbH¾ó™% #VÙv)8/Ú.L„€´“)ûLf‹}ËsÒ$bñP33ZÈ·}]3£¾øËJX›ZxEÊÁÞº 3B¤¨i$Xð†HÂŽ$ÅSÚ‚Ò7 i?îu©›´³dNOL¼³È™ðÓÊ„scYã-3—EøºËF,Ÿ(Ö'*4^§ÑŠ*“…´”qêŠdÎez¶È ™¢‘ŠbtŸmæžsò<§^ŒuÂH_šŽ\å0Šô¤ Ëg¾fȶÂ( w TTãTWž«æšv%>p‘- °Fb€"sLy˜kû0Ñ6F® lX|ÔE!tl š‡PHÕäÀìŠ<„ï‰X99çB“iæaë{ŽæÕöÑtÙ…J.ž›êÊ U)ø×*\ &„ ÕH3 Î+­þhwíe—w¡·'á踘2îÔ—‘9öeHvoV¥Hb‚ç"ABi_¤7øðî_ Ö`Fœ'l1Øp÷i‰@„ˆO5Ú‘â >sVlùfÒ ‰Ø7Zú£)ÇMXžæTÉÔ+r†W˜2uÉ3‰xO uvRöד–v‚cžv)Ï4ªú÷ì’–÷–ìIwúek3ÚÃêÌ“› ›¦»:-—Û˜yËR‰«üdì•”ôJG{Äû»Ïï¶!TµÕ®éõF_(’CS­$+gó4€3U?ttJ±'’âwF)&'4:•Ý(xÕwüÁ5&¥¶Ô;he*KCgÂÊØTÁs1% ‡®yÇ"ˆ>é¯ÕK«Kòœ¿Ì:Ù¹û0¢ Æ@’ýoÁ¢ßÝüºSSÃ,mÏx¶Ã’êOìÛÿ/Í2½þI.ÓüjJh½†Œ÷Ò)`bb°óëËçÿQÅçºÍS3è»™9ÕpIÀ“Ìw÷4NAr,ÄÍ CI’±)ãºH9PzS¤ÒO(ñÀ›sý›çÜû$ÞeÏkÞ&8Xq·³¼?|¹ûÙ] /ŠçâEÉÐúáš‘1åïF$M”ˆOòóÑ0ÖEÊS¨·œ3;^èÖŒ}F¶ÿÃKÉ;ô‘çmEM`õ­>÷…=vè1Ö¤¤Þ(IR‰YIqÿå+Î&‘ÃÄ$­ájf OYvìÈ {?¾D޽WŒæ&j¶dÏœ0I‚dð6Íý†'ŸÉq$û…—;ÂÎØïã%E2°b§Â …•ætä¬:÷MÕ×äJçd6dhM·wZRµº‘«ávï9o«Ñâ³xö «‡âZ û®BûÙÖ€¶çˈ—q’ –f&œ F¡M•l (l{/xÆ,ŽÌᱞ/ÑØ3¶ sL„ÀGûra¤d —á¯!vˆè$v¦¼MN[‘Ÿ#8–ý½{ØïŸ4Õ/hkÑ­ÆË;ø+à„ƒ½òò-e쟓yyçN^:è‹`ÌÔßM…7>œeEÚZz¶ÍÆ–VŸ+K>¯x,í®ô¼…ãž³òŠ”Y•³Úʶ©‡ÈòµhÔaaàFáMé¾I¯WðXÅ7ÿ}켕EÎT”»˜•èÕpÄ-¡ë/ÃñÍäÂ$f:W+:WVç‘U†op–è°×œ!5¶]‘ÖT×ö¦Å-/4Aò1¹.{àʳ÷°i‡37:ú–5=´”ʶ”Ã5¤b¾­Úå÷v¬Ñ²cm¶~âè+(q¢÷üÄïyÜÃË‘Ô>œÆö5'á«}ÕPNæ H  z6]"pš§yÎKfE[GicáågV+ð ªnÎØd§™ ¼p»ž·Û¡Ç´Cû^úsÚ°Àñˆ3ЬÊçwOŠCŸ|UQêieÏ(s(nAG-Ï^$l<»ÿ=q|2|Z«9‹7æyÞ7áS}¾ÖŠ/šÑ]hÑ &Ê“w1̸æ«E Wj@Ì.:{à©9Ëé{eU{…φfTȱsw¯o¦ê[{cü|gÏi™NU’N§4Jõ^àî=µÌ‚e©³±™–L¨<'}~ ¥úkwÐñ\Ù{+½Ÿ¼¶çÜ—÷d†ŸfßLO,#Yè+FÛ×ÿôâ!S;ù „S£aâ1¢Æ ЈûcZ k`dß3£áM°å/‰srÚˆ_üz‡¹ùÌ7o!gžš²î-—scˆOÃÍ•I_OÃoˆA«‹ÛÆ÷ªiUCà#ɨ¡À÷f ð.ÀŸ 'ºJãZÊC[ëÌ` Ëø{,€nKo# iÒM…ˆ³döÂq}÷e/ý£@‘ž…pÍåM·à¹À£íXüÅ­¾'Ox¸Ÿ%Ž©qÄn6Ø[/•=ó‘½DøEMLºeRRJÝ‹1fÄ“š¾ÄÂèºî«Úw<iöðõTý¾Taäû¡¼Œ¼z,Ø!öãÁŸmnÒ§ù+÷¶ó$`ÇÛãÍÞ¥i endstream endobj 2435 0 obj << /Type /Page /Contents 2436 0 R /Resources 2434 0 R /MediaBox [0 0 612 792] /Parent 2431 0 R /Annots [ 2432 0 R 2433 0 R ] >> endobj 2432 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [431.285 348.038 445.731 358.942] /A << /S /GoTo /D (section.3.3) >> >> endobj 2433 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [329.373 288.262 343.819 299.166] /A << /S /GoTo /D (section.3.1) >> >> endobj 2437 0 obj << /D [2435 0 R /XYZ 89 721 null] >> endobj 82 0 obj << /D [2435 0 R /XYZ 90 690.045 null] >> endobj 86 0 obj << /D [2435 0 R /XYZ 90 537.079 null] >> endobj 90 0 obj << /D [2435 0 R /XYZ 90 262.733 null] >> endobj 2434 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2440 0 obj << /Length 2829 /Filter /FlateDecode >> stream xÚ•YY“Û6~÷¯Ð#Uñм}sf&ŽSNìòÌ&[o¹( ’X¡H-AÆ™Ÿ¾@gRû"«Ñèþú ·9n¼Í»Wß?¾zóCmr7O‚dóxØäÞ&õ2׋âÍã~ó»sûãÛO÷Ÿ·7Aì9¡»½‰Ïyüñž ÛîÔ6·Jòq+hòVBƒ­˜Øáhj˜ʹÕ=·ªó¥íú¢‘î[ßsˆÓ'&ìgUÍ¡íÎE_µ†g “ÔùE]ýÄ'uÍóʺRfSÝúo¸13B»uÕñ¦t7’<_î[ÕŸ`R€¯ž¡lŽ-w-N ß(µ×Ë¡/^ìiøñyÀH& !¿i»‰<ûð’ï&¶Ý^Éx/GjN]ž¸7^ Gì+M< èTÝ^.f/šÕv¼^»lÕóÃWšÿ/­ÖÕ®½ 6àÿ¨úQ™Œ~ñé2áR©r¡w³w2³G§ŒJVäù :¾ÎEÓ¨N¸ù—e#?p£8„ €^rßµçü~ƒHÿ­ñqmý/.—®½tÕ¨õ·?¿ cç­Œ÷}Wí¶ ±Á̠ǜ̄^o´zdëlOXKÄÄÿ‰µ²=ŸGÓk›k{B=ñgo­ã÷'Ó¯k%ćk¦FÓ¾f86ðòÃAb‹ˆ´7pîYãžQøŸoÑ¡4 ‘Õ7uš¶gJ§̖ǽZè±ÂÂôjë;š›3Å“[þgeVªŽ›¢D‹z©ƒ6@šÙ¦AW£ÚµxÑ<Ђ‚'mƒ#KŠ&#ì`‡ZiýQ*&ÎÃÈ'SÃÕtalLücùÇ­dþÈÇBA‘T¶ÍÏ ŽC'††D°»5SïE¿ÞŠª®3Jc`¡SÒF»vO UÕª“+Ë2Á€B4Óà®éžllÙË¿n]ö; GDnî¡ÌÜØÏ&?˜-ýàÒ¿]ÚÚ@ü‹Îì·m„ju"|JŒêƒÍá臮8ÓëN€J‡4ßWó¼¢Ö²b¦˜0Þ›}ÚŽ}YÂ~î/’\9ôlf0Sì{îJ`2½IBö±§Z:±XPôò¿¦ ¨6|òž½Ð¡SÿTS²ë…­A+¢8sÞ÷¼g­¨<…ÀýK6äX »–ä(oM‡6üûéÓbòõ)7Á­\ôˆ6'yŒ°ÀU¾™°¢óºÅO³«ÏRz£$´" Ý$ˆL’]•êàI|Ük\ÝzfnvN[¼m r¤(ŒžBêcG‘d—¢ëyŒ”"•\‡ï>þ,ë´5†i³ïÌ6 AY‚Š¡B§â½hæb†;’Þ¤(LP1¶+ä *Óyn(ÑÐŒ¥ÕÌäÒµ%)ª¦–dé\p¸A]¡ÿà–ɹ8·JQ£ Ãn£æ¹Sêœ9€²…ÑÅb}#ÃãLîá}GÆ«¸ø(EBY¾—´ü×VÅ3µe } QWnÏá·U]¢=S+Íå™sL95Ä#çl*8Tp—cúJÖÕm{áaCgÀ€!‰ÈM~`ö.@/Uö<Ã+ró&ÊÁ‘Y´ÆS¸ª x>Fµ\ )÷Ÿ‹],E‰Ñ*3åä/hO:#¶ˆK9±Ôhͬ&C¶ÄÂeMìF)Ë5J–Q'KµÙÈDÙÐ ÃzÍËŠå*îón  2|UBŠÉÊÃ,uÓ<0nòîáŸ`áÆ¬°“¼K ^Ŀʑah|Þ Må‰)v`Ìå+!>t$ćé³#Ù‹@q‡ ÖŠd–ø`YþíTñÁÀBCO¶äuêÜöj=îZš&¬@ìÞŸ«|+T/…gÖÇœ9Ãÿç‰cÍv^ çTâ\=iÛeK°g|µq¯\é¦8õCÕ K—Äõ©fÏ¡”^u=£Û³P¼t@põÀ”´ û¡=GvŒâÕŸ÷LòHwC7ÝÃþAÁÌêµ±wõìÏ70ô¤M=»Á;J!yV+4á8œe>TºTu]4ªôÕ‡¡ŒjæýÕ³ÙòkBâFafWÀ!×jàwŠ«å7ëê/} xnãÏTXµµ‰ë¯/êŸÛí]eGËè£)dàjÑêg#äAK®|³&†Ês%Y%(0@ƒ{ržØ¦t¹¤ ‰¦T‚Ô[&Ñ»8, ­%¹½ýî;&´Ýlb-£gyßÞ^1ÍxTä8@†M 9cCrÁóOÕñ|¯eÐ c‚Çø9–vš¾kkìÄb¶¨Þ^JêD” Δ/ZX]-©ìçKI 'Q… ô‘’Fø{í`©1Ÿz&9b›xœW0oÀ­f8ïp‘fƆ|X[Y1%h»¡i¤¸’±&9×q2§–„Z¾œšãhæA¾µ¶gH¿%#‚pê£sœÂ¡ 1†Þ@ ):Šì{&e;úÈ[¶XFÁ® † 0ˆµòrÑ] ë'ô›N[A¿i5êêã‡S¾³eLjõ58DAå´mX;eù¿|õ7—¸¯ endstream endobj 2439 0 obj << /Type /Page /Contents 2440 0 R /Resources 2438 0 R /MediaBox [0 0 612 792] /Parent 2431 0 R >> endobj 2441 0 obj << /D [2439 0 R /XYZ 89 721 null] >> endobj 94 0 obj << /D [2439 0 R /XYZ 90 690.045 null] >> endobj 2442 0 obj << /D [2439 0 R /XYZ 90 631.35 null] >> endobj 2443 0 obj << /D [2439 0 R /XYZ 90 611.425 null] >> endobj 2444 0 obj << /D [2439 0 R /XYZ 90 591.499 null] >> endobj 98 0 obj << /D [2439 0 R /XYZ 90 537.079 null] >> endobj 102 0 obj << /D [2439 0 R /XYZ 90 333.343 null] >> endobj 106 0 obj << /D [2439 0 R /XYZ 90 205.721 null] >> endobj 2438 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2450 0 obj << /Length 2668 /Filter /FlateDecode >> stream xÚ¥ÉvÛFò®¯ÀËeÀ÷Lû27Å–cÏ‹#Gâd¶Ð"ñ °žæë§¶ÆB!²'¹½TWW×^E×Ú[®õóÅO»‹ß&¡•9YìÇÖîÞÊ\+qSÇ #kWZŸì×ï.?î®n6[?ríÀÙl£Øµwï®xa·Éûòן¯yúæê÷÷¯e륮ý»9ûáúÍÕ/›/»ýø6òg†^à¸AäÐ}~‚0®h¾Ö6Èb'Ê2kë'p6`èϾ-à­OÛÈB*}ªó'UòÝmÃßœ?EÛè¶V<ùìFnIQçZWE^óôqãÁ¡'ñ–·¸ÖÖƒ'øÑËdܪ¦gL}» à³ëú@ÀßÀé…ŒÓ l}RE… ^ß!ßófßò´T?²¿V…â9¼®&ÆÀѺÝË"°d8ªìgé9ŠS^<ä{Åg¹æÕ¼áou<Õêdå}Eœ öž÷ælñ9Vê„1HÑóœ,Šù©t3^ÚÕ)2Ù/²U÷„KÑH%,óJóDØUÞÓ#3á®3’}—Ÿ"c<Õôª»'A ž†¾½;0®—é9®´­FŽ"ÀœÅ+<À¸#‡¡‰LŠÎÉVj…³ÄP/t‚¸‚ c'õCˆ¡ûÂSn¶žëºÌ ’UÞçw¹V+QHõ}Ç>LºÓâ}x졚ùj^Æ ÐËlî©q^5¥:)øi˜QIJšE[š¿BÍÑóãôÐ"†ÇyLà^¨ÐÃI¢Ðú•Ù• 1#ñk‚`OWÕUÿÄáM“*‰ÛJÏ¢Îåe»ªÔ&…o74}u¤šÁ\‡å¡ŸÝd$ˆZƒ@ü5ŒªÆ¬ÈáÝ›Ûë²·ªTiTbæ§BÇ›r®S·ñR»=©Éð²ä%MHÒ!s”òßþØÑéŠû·]«Û[<¸ƒMœ ñJú"'u= tГ xɾcÇ Pß <Ç,)­€Õ=e?è qåNÞ€.›¾º¨*êžåÆÛO¼¤GÏ$‰sp#ŠÞÌó\:Û÷l»JBº˜óÖ `k|æ )ŸÄçýèÜ©ÃÊ Á†§‘•žÜ1­Q*43«^É`ÔËŠî[¾>^ê)ŒÕ“Oi»ÁS–bÁ)æÅ¯¯o~Ú‘}¹¦Yï¯oþ±‰àL1ƒeB‰2ðí'‡VsVÆ$&\Ëù³ æà—G;Gp Úr†¢Ëê}ˆ'±…tdT˜«Ù„a r20CÉ®à–o3gDl̇HCq%¾ØuâÍ¥•¸¶‚|¢“ Ê :MõÇ ~lphö–÷j"ïðËGP u•›«ß÷$%ä3Uó ×pz#Nw¹žÿ ±Œº—"ï”Xƒ®$ Ãå‘yY©çÀ £O·¿ýòILbúÜ`cÇgýÏ›–óU/Ã\t¦nÊxD rþtª¦²„2øÙAÆkÜ-ž3UŒœg!Á1‹y?i Ô—l5²ß­„)Î.ü 3~0öå)ñÂÕã:$2G0Í›{ªa“ªÝX’EÜ_âœ^ƒy‹o G³‚оmKƒœª”B-‘Ý6k.Èäƒ/˜VòÜ´VRE÷‚¾ jt¤‡Îàcžx\*k(ŸuCãÆp‡ aG]üLQµ]Mzê`]Uð ÇÏÉ¢níQ®Ž0u-~¯”â “òbNËsC_0ÚOÄV.}ìª^ê*H¯¦Üjº®mža[dùx0¯˜‡TVI4¯eÑýPo$61\mþähúXɘR%ñØi™%o¦Ä®ô¸5©ìLN(2Ùàäg¥¹›×Æ’}²–oz/á8˜ü3ø òû¸ÊŸE£æssŒƒ¥ÓEðy OÁ2fÉã¶ŒÉJebÀÊâ מ¸¸ËS¥ Ð ãt*iÉŒÍÛS'èÚA›ò¸C¢>’Â9ïÂmqçg³kYc1ÑÍlnå²ùcy±é÷õm¯L+;UÒeªÌEsÂÎVéq† ›6Ç>Á´‹Êü—Úɬú`«dÛºz@ÑšO­bÍÛdÉ]ÏL7˜Y0ÚïªÊ2†cÕD€¢h»’ߎˆZ¹c´'2;J•"ÒX½BêáN«ž7¤Ø]i&KPa&Ž„üžB ƒÌÏM– Ýp“iÏD ÊXTšóºïÐÝâŸzCÌ—åWdn¹@¹¸Cÿð]A;=Ú—ˆîtªÇ`„‹9Œï»ü8u:ßS+—ßD6in^øQ6Þäxr×ÍP+½¬Æ×]~|¿žx©K›ô?‡ŠBu̽ újþöÝ ;‹ä,•ŒO ¸G ƒ;†hÍo+ynŠl¶ &6Lµ.MäW« ›ªÜ ìy­z×b»ßˉnç(î`;W†&E€CŽáÏtÔ<ù¿æ~žQ1€¤‹ÿŠôyU J”îv "ª,7@B¬ßŠ•eÑðG·ýjáB®vH¯ÇÃ?£ÔɲÄ*ŽŸ¾¸V ËÀ'ÈRë‘€Žà03Ç˰ñT[·¿ñÿ ‘“% w¦\×IA¿"ßñ¢pÖ’R–¸ÂN˜‚EúNšÉ³wL•±IÃ2ó/ €9µCWøg6É<Àúíõµ±â™Ï£ø²ŒPǶTõêÿ—3–ýÈ–×9 endstream endobj 2449 0 obj << /Type /Page /Contents 2450 0 R /Resources 2448 0 R /MediaBox [0 0 612 792] /Parent 2431 0 R /Annots [ 2445 0 R 2446 0 R 2447 0 R ] >> endobj 2445 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [225.993 447.689 232.17 460.453] /A << /S /GoTo /D (Hfootnote.6) >> >> endobj 2446 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [196.646 389.97 203.619 398.817] /A << /S /GoTo /D (cite.mysql) >> >> endobj 2447 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [102.563 342.15 109.537 350.727] /A << /S /GoTo /D (cite.MySQL\040book) >> >> endobj 2451 0 obj << /D [2449 0 R /XYZ 89 721 null] >> endobj 110 0 obj << /D [2449 0 R /XYZ 90 512.795 null] >> endobj 114 0 obj << /D [2449 0 R /XYZ 90 325.955 null] >> endobj 118 0 obj << /D [2449 0 R /XYZ 90 138 null] >> endobj 122 0 obj << /D [2449 0 R /XYZ 90 109.001 null] >> endobj 2452 0 obj << /D [2449 0 R /XYZ 104.346 58.726 null] >> endobj 2448 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2458 0 obj << /Length 1648 /Filter /FlateDecode >> stream xÚ½ËrÛ6ðî¯à­Ò$¢ù©Þ\ÛIÜi›´Õ¤‡¤ˆ„LLH‚H+úûîbŠ”ÕN’C‡»‹}a_ ¼G/ð^_ý´½º~•%ÞÆß¬£µ·Ý{›À˂ܒÔÛ–Þ‡Åí››wÛû?–«( ±¿\¥ë`±}sO€ír/n~{ý–Žw÷ïn-êO¸”‹÷îî¯oïîYþ½ýùúUM&aìqêyQŽ4WUÐ[9ü*ÊàNLT¬,E/dËj`*ˆv/UÄ€dÑKBhÞ–´1'ÀA(þr¹Šƒdfìž–aºàJÜ ÙöJZY¼/À IÖW\[f%µ%g-A™®+9Ô%aw-ëVaèoRëçƒb]Ç‘$Á\£™^¾éºZÎJ¼SòQ±¦áŠèÚž«ý2 ¬àDò1Hƒ›w°„>A¶Æ@ `+NÛµéjÞp`R³FK-vŠ©ã\ÇÛ/.ÙcLÃÐðˆÃyà±cÅ'öÈé€<÷3[F¸=J } ^2Z"ÑÒ[F‡ŠõiØ'´•k:N¼…tE-À‹ãLi‡‘aØ(Ñó Â~X¦éÂÞ‚w×B÷V0FÎK÷²®%ª~í#ÅúŽiQж¨™Ö¨!~œÇv¸ö“8n ˜ Èíc¥sª«4€Ôâ(âIýË‘ø*QT´V³)OR, RÆ.Å:µLÒ2yžQâgјŒ&‹€)å l7»rÔç,_Ã8ðãÄ•~­Qw¬gV–•ÉÛ‚uz¨Yoe—# &õµâæºÉVÂì•l®‡‰Šæü$ìýB6 ħž«|«Î7}¯Ä#wp:þʳ©Ôï3áµ’C÷M”mü8ˆ¾?€¬î'Árn§± ˆ?Ygó¬xÀB‘åcÝÇSF© Оê0‚&,©M<¨ðI°x‹ž>N EÆü4ì]&kB2¦˜Ø©Óêà=gý ¸† ³Äö«kÇÇ ˆáæù£·C3NÔÎ.yŽ4ˆÚ•,€×š+ÛÐ,鬋`Ð#»Ñ7n½ß^…° ¼Ð ãÐO¢ØƒÂè§›Ä+š«ÏWPÎÖD»ÔTœ€0îš\?4©w'¯~‡Ï¡VŽåjÂÓ (³ ƒÄß$‰å‘fv ž–Å&Ï úÚ“ñ¬ƒ6-‹å ÈØ gƒ‰c2×­aC޳D=S½ Z8tÕÈÚD60ä@°«…®ìUÙ¶¼°¾…óŽ÷ÎÛç|QÅ;™CaaÃ}¢4#ŸÒ,'™Ð‰Ð HQî§aN7b?÷£å* ½o¡¼ íì‰OjŒqaƒÁØlʒ°~2 U= Œ±`;~žõÖ¹¿¶Êüµ„áHôà’8µnàêKÚ‰Þ®šÖNj-vµ¥3«âŸp/bW³ç;{ƒ£³¾ƒ™^jʬŒ–iE5hu.Ž•×f*¸LÏúÕ¥žTcœµ4NZÏÜ'[>Ï×ÑŸý=.OéìåYòÚÉ|æãHrš@ÏMo1ÅÏçŽÈO ¼ÏzEè_êvV„èØ•’­ÌH¸& „;@1åC Á¦LŠ^ÓCÑtÂwµ,h†+­ß¹—аý(}š©@a’ÏÀÑ”µúÀí}iɇ¶µy;cyrö€ãSˆ†Ë¡Ÿ^ˆŠ¢âåùãøL<ý‡sè-sĸ'Ð(1 a}%¦Ø—øË[óü4ÓâÁZŸOðcʉ-à¡0‹ÔGG½©ÕN¶¥ú¹lAj¥qK6}0 Aüç°r4>Å?sÛü³EiWÜùièQD%–0“Ó¶b–Çüf?$“ CUÞ¦VF/ƒÑ‚u•ë}9V|eõš¶l«3=Jš¹x½ÖF—8ÙØò›¢’¶М‡0p¤|:ÈÍ®LãÏ.8‘ÅîèØò⓱ObÆBñ_-¶!i¸(5™KŽì`†!n¦ºÐísuÇ óþ«Ào=ÞÅ]H™³&%qµqEN_cùÂ0¤d§««üÛѱá}%K¢0±.i„Bñh‰Ž‚x=éOFðlPÖN<§;_ü5îv-:&ôÚ ›§íÖ¥ÿY‚º*z>‡?ª¢f¦e™1Út;š rôû£tå£æÌ•èø¬ç²DåÉ‚¸þ0Až endstream endobj 2457 0 obj << /Type /Page /Contents 2458 0 R /Resources 2456 0 R /MediaBox [0 0 612 792] /Parent 2431 0 R >> endobj 2455 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./26_home_taurel_tango_manual_ds_model_archi.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2462 0 R /BBox [0 0 780 456] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2463 0 R >>/Font << /R8 2464 0 R>> >> /Length 1335 /Filter /FlateDecode >> stream xœµWKo7 ¾Ï¯Ð­vU%JÔãè¸EТh{ŠœÍÆv±“6k#ýûý(4»c_²°aÀ³¤øø(Q$õEm•‘¿é»‡®¢º}¼Žä‰ÕCYWWo‡à‰´÷ÊNÚG5‚­ ¾T`H¸B'm3èè4ÅNo†rÔD-gœ²Þ²æ4Ó&òƒFãÄuHª`ÃÚ„Ð]4.&]bÉŸ PSLˆ1 ¨ë!Ÿk YB ‰5p„ÀÚ["!BÁ’N4Ç‚s¢ÓHŒe%0ÒÑwÒä “ˆW:&¬fH›(|¦¨=‚Œt¢ ÑSHah¬ìq°9g(+ËN"Q6¥¨-0¹€`ìL[„Äiãäˆ-E˜dà[”ŒÑ²"ÍØkF°®n ;½"kIœ‚†¬²Yâ ÊRdà<☠Â÷ o£á48³DŒ5I; ™œ)[™3ö¾:^R È}ÒNÜNŒ`¢ŽÖb»)+›‘µç(gœ5ûNoÎ.éì:‡YbLÝB£› h4NHE³Y „X’yòÑh9òŠ¢qêÉÀ"ˆÍp'ÇH84I¤Zã4d6[/MEn¼àæØb2ÚøYÂy‹ˆÓÝÒLAýZ¦¶Åb`鞚ѦCÐzµ¦¤ö[¹(‹ž=>™äÔ–}z–ÓHÕ§ÖþÉnëïé³Õ›5žf2gkƒ—†Zê“ £)€e2vµ‡³ËÝýöóãùúïð°Ác‡P¤Mfµþ8œýxóxóáæa+Ë+ .+ë‹ßÞ¾öŠ ªÕ¡b_f™ ñ*ò2“aH”Åëíþëv_”ñ2„Ñkøx¬n¿À/‘xµÂc=$‹ðŸg—ãÇó•5HœÏ.÷÷ÎÿZÿ2¬º¸ôEë+¢ËwWo.Ä6¦ çл˜¬ÞTu,7 ‡«³ncþ:œýóïvsþݰ’*•ä]cñha[4.~ÿYä[x+dq!®áɬ-ï AäAÝïí×ûÍöáh_«ª;B˜ÐŒø¤2©­­šesÌÿiŠð~ø{$‘ endstream endobj 2462 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152423+01'00') /ModDate (D:20160114152423+01'00') /Title (archi.eps) /Creator (fig2dev Version 3.2 Patchlevel 1) /Author (taurel@spica1.esrf.fr \(E.Taurel,,,\)) >> endobj 2463 0 obj << /Type /ExtGState /OPM 1 >> endobj 2464 0 obj << /BaseFont /VIQTXR+Times-Roman /FontDescriptor 2465 0 R /Type /Font /FirstChar 65 /LastChar 118 /Widths [ 722 667 667 722 0 0 722 0 333 0 0 0 0 722 722 556 0 667 556 611 0 0 0 0 0 0 0 0 0 0 0 0 444 500 444 500 444 0 0 0 278 0 0 278 778 500 500 500 0 333 389 278 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2465 0 obj << /Type /FontDescriptor /FontName /VIQTXR+Times-Roman /FontBBox [ 0 -217 775 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -217 /ItalicAngle 0 /StemV 116 /MissingWidth 500 /XHeight 460 /CharSet (/A/B/C/D/G/I/N/O/P/R/S/T/a/b/c/d/e/i/l/m/n/o/p/r/s/t/v) /FontFile3 2466 0 R >> endobj 2466 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3250 >> stream xœeV{TSW¾>1$ûT‘NI3ˆ`ÂX«VE©£f|cEм_òŽ€Â3$! ÏB€„—<ä±Xª bë´ÖŽVÛNÁ½vœÞÒ™;û°÷®{â¬{ïw­¬¬œì}öoïïûö÷ûX„Ó*‚Åb9‡¦gˆr½ƒ%‰™Žç”‹ò\Em`±Ü²|ˆ³hc¯g68;µ{®mrÅ_ïbý/6‹%3vûK²ä9é©iy^[Â#ÞÚ¾}Çÿýó¶ŸŸŸW’üF¼ŽŠrÓS3½63?¤"±$+C”™÷[/f¶Xœžì•*–g¥åz%¦¤ˆR¯…'ŠE¼Ž§‹Ó³²$R¯­þoyíöñyÛ›ùÚ˜ž‘”Ÿëõrç^?¯¯`Qj¾81çÿáq$ó]‰ÖÑœÜy'¥‰IÉ)¢÷ƒ‚ÓCBű‘xŸxƒ"6gˆ7‰"”ØJ„Ûˆâ]Ÿ8J#vÇ âmâ×Ä{Äb/qš$< 'BD|É*dÝYu`Õ ÛmvÚåô!çWœXÎun<÷ÄCF’E&ß¼úÊ·«÷¯þãšmkRݨr—ås`ÑãÔ¯l¬åp+?ΠmH{HWS÷Öp锕¢Sôæ¢Â˜ w޶¢˜so“¡¹Ö,œÂ¯p°…;¾½)˘ *wÈQèÂ+I®G+jÜÀÇ÷b’îå¸På`¡Ößd}½€.°[¨ü:CCU#½&e´®B¬QE–‘JœfA‘5Ê&°“x}pµ£iÈé.ñI!-B VD9&¥XPtmQL“X޾Ÿ=rV¬8uBðÒWGËÓ5¡…î.Ë»À*¡GdVWÌYÂ¥K¿ÁÈw¾uyŸg‘¡…Ò& !W‚Q«}ËIÞyþzÚG†ì¶«ðLÊÇÄ}=YMïµÌ˜ÛºÚIž¸»Ã22¾;í¾EøÑÏø/`ªÔ®d^ŸËíIXaÒ”ä¼ ò$ÝI £U¦!wbvÙn4Y“\ž£ù˜ÝÂã½… *Ú^jw/«ï9n~ÎÆ*OÿÒg;- =þ²»b׿þ`·]?Я ÕþÂííôšwâpʹ®1©P2Sø9< ¸v÷€9¯j’úyŒÅÎ^&¨p~1–r¤ÜiaQƒÒ ¬‹n‰ª?ðŸ=vZ´èU°³ï‡ÁwÞûNô#`ü85ÿ )o;rôd†/¸@ˆ-a4tZü0›Ä'ÿ‚_ÁoÎÍH“Ç,ë{$s:£UÑ&ÇÚÊåŽë£œÿÔWj¢6ðMUF09dÔÆ WÒDh4A%$o³—"^\:\¥n„Iü6>ߥ½$^ývÂoâ_{¶-$>',^ø•T‡IÓÔ¡ w¼í0¿Ö>õpúMÒìèÃþ±Áö~CºÿËóß—(.f¹ñªþŽY|ð/R*e“á„IøÇàÝÙ{·GžÁ xžñ$ôæ‰û4ËNo’îäò`c}¹À6RëùÍSUݦÂx!m@¥×Ÿ*b´ª· …æHœ&®÷Ô™Jµ‚Uc‰È.Kkï Ô–ž˜™w4Zø*­ÏOUÉÜ](wmG‘ÚiSw¸~xû}îÆÛ?ßò˰'Gí¨(ÖWV–{ h«5µ$¯µ>?¿&Ûcp¤È@òbŒðÖùá‚Ö\»Ç_D¦‹Í2´»¸S=GÒ>f®±¡¦šÙ//ÀÍ 1­%½=em?¹õùõÜÁ÷íBšøDÒ¢ì†÷±K½Ssýé»;x«Æ¨ޱ0—òzÁ^ŽÂÿäÓõrîDySy“ÎR\— $ýº˜åOïÛ‚¹8ðûÞ›œLNßíù faZv9µ_Ò’ÕHvru8•“Ï-‘ÉURÐB¡AnŒ³œ­cH‰¥ß ·Ð oõž ~zü¯"¼ ž~mxl˜Äñn7™oÕ’.ø’v†rp5ãRúô‚o×3ÚçÝߌInC¥¡D /.)ÖkE¡ 1…e$oQ£/Ñ—®‡òª CÉ»ÿ}ƒ»¯?áöôh×Ì @Ý(ÍQhóÁýœ²çc!¾Œx‹?q<[—¬,Œ–ØŒ£1Ê:¬.ÚWÎØÜu+ò36ÃHб‘?4›jH+}]†ÿe.ÌõPÙ¨ý6•ÍlŠ*¹å-È@[¡-Ón¥›Ö½‰M%ÍåÍ`r‡¶F㰴БJ4ZaÔNmÂÎôغêƒÞ «“×éê ŒfË~?\×÷Y±ßÀÒÎߢÖu¹Î~‹·~ãÆ»Jþž¯P•*ÌÓ7O q‚™Ò>eW¾=Á¤÷‘è€<[AgW»­£¦²¶Ò(¬0UÖƒ‘ìè›îÉ "zçi….A”_ J‡ó$/2`2~~r¼}f^À3GÔ¶IÇ=† ½ix”¢w}Ëqi±´(W%)–™&šÖ0üŒÛñÚIŒ3¬ù˜uü™½—ðK«•YºXµ{¦ŽSˆêªjÀ䘩8Q¸Ò‚Ä‹ç¿Æë–ð*ü~õÐ÷[ϤFÂ._³Ï<¹~€v¡Ù1§ü"â:»ŽÓAqúXÝÙÔFìÃ9–š ¤Ï©¯1úùæƒoìf͹a]~½¤MÞî;¬³Ç®í‹Ž,HMFÅKNÀ~’þåW;1ûêXË%» §ËÚÓûåžg …ZÝËêyŠ Øø…–·ÌpZ¼²ÊLÕ5N ©O˜Û£HÓžR¸¢úª:¨rĤMÒ>H4Õ˜ÌÈí¤9ôFúõG{ðªÙQÛµ!á)FBN ×i5ò‚m&¾¡_ãW1gúá—Mdž ™+¦±;$çŠY“Ô¯'¬R>Õ‰àNÈÕÜÜÐ\3êPZ‘ –7—YŠm*S*œ&éçh…OÉ8ô!wšuc±äÊiÄ‹„M*™o #Ø"+:X£è„ŸHÊñÌTàÊ5ŽÅû8s#;‹Ú}ù1‡2OA0$ôeÎÉGõƒó$žçêîiûr2ìgÛ# bå¢ôؤ¬£àGÒ‚/öbôãۘ¸" ŸàüÆ'C#ó0]óÒavê¿ì¬!Æ0b.ÿç²/Ÿ¡=éMôYïŸg„·ž¥ü™ñÿ(쉽ðÙ3Cïîï³og vš‚)¹ýÂèKÞ@¯ õñ‚ˆâEN^^ZZœ<ÎB\[Ú¥ˆ©ó?1] –z_\¹F^ž˜î¸ ‘wŒáëŽîðïK¸ÐÑÄ8Oò/V´V^„'p£a¢ë΀}~WT£Y}É“{z½âZ¹¼Vz¨kЂ?¹r Á>öžÁpЊö”ŽKÏSR§£±{ÜÝ´-(ŠFªªê<ÁËðAýì(º´„ÕŽ¢—·Xù"CACæ„ëÖ}jîoì¸h½×`B=’Ý'÷½è(ÜÇå]•¡Gº }YØW[tØA^?C^­Ú _0@¡Ùj\LÏsð^./r%†zÊïm¬ïÝJðŽ’&¦Êg³ÓJ¶W8ü‘iRk,Ã6¼vÉõÉÒ;ŒEþû;‚Æ®PŽ’QmSµ¹Êî]/Û–¿Vsܱ´t²V×ਆŠÄR~V^žDÒ‘×Û×ÙÑכיɘTö|E§Û\<ŪŸÜxžTï”[–§Ñ(OWÔ(êIÞ`ó¹sõ< ^q>3M,O„øídv úB4“Ô-2©k¥Kþ.êì»»nb—(A·ŸNãtpyÖª¦f‹G#´–YõÌJÊÑ1ݘFϾúù¡÷èu„o%N òæ•Ñ»W¯ÈR‡—.4g·‘Ý\ 3Düí ï6.ü•rïh4¾¥  Wû®Q™ö]a.tÈ;éUd·ä¬ÌsK胜.nfuZ±ü KÖߨÖe6¿ŽÛXÕTÅ\øo²„©Ô¥ p ¨)j€›$õ=*«ŽPˆ´ÇLµ2Dl˜a=]ÀŽÛÊ„`³¡Þ‚/š c„tc eH%³FŽ…W+á2‰‡T×7Ý­Ã@Nv¤ÒB4š`Oy\¥l…»$®EýƒmS@εeù éT&TëtgôÌ$‰eWgT«Ûà²;NBxuʃg"³Ï„ äsé=a•oùˆÉÏ‘2&?+Ý] lT¸ ‡Ú¸ý«×ô×;;/¶9¯%ˆÿ+KlV endstream endobj 2459 0 obj << /D [2457 0 R /XYZ 89 721 null] >> endobj 126 0 obj << /D [2457 0 R /XYZ 90 255.548 null] >> endobj 2460 0 obj << /D [2457 0 R /XYZ 90 204.922 null] >> endobj 2461 0 obj << /D [2457 0 R /XYZ 90 175.099 null] >> endobj 2456 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /XObject << /Im5 2455 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2471 0 obj << /Length 1585 /Filter /FlateDecode >> stream xÚ}Ë’£6ð>_áÊ%¸jí¶9ÎÎÎ>RÙÔŽk/I2ȶ²€¼Žã¿O·º…3s’Ôê÷SNö“pòñîÝæîí‡U2ÉæÙr±œlv“,œ¬Âõ[¬€ELDñ|=§³( J‹@Ô{Mbå4Jƒ§ìêÆŽÈ'³h=_®‰ÓS=Åi4úH½cÀ4 ’÷gä§éëª:Õ*ÒL\éB–´=9]€JŸly!X!mnÔVoà¼ZwÈb'¥³p\Á/Ä íSèÎ^l#«_ ,Ë( 6  èLr.#›l#êB˜²ì‡,ªGaD¡ö”%DAG{©óƒÑµ>½×½¥KvÌÌ-âÂDY‚‚ñb|f ÍAÙ¬½ô÷bIhçÈp­D‰FÙ^h½•ʹ ÷çƒf ®‘7¶‡›Vò«™‚¨,,Ï©sëÎpg)-‘äýŠ ˜½‘?OÒ² @ã¹Õ…}Å\ ¸=“,`¯ Ö^^ÍJmü¥Ñ˜gëÐêrÿ¿\9¶@r>¨üð Kȃü ­sÔÅ p:9'UO“RqÁ.É7Þ¾4cˆÛ¸©X;aÊ¥ºf5.ëÀªz_z{„ö…'þyR#º³ÁÞÜ{9[IHúqªö«j Ÿ@*Ó˜ˆÃ.IÖ»ÁuWÞAXoC×ê%Y}”¦5¹:†Âªi(?܉V,³x…¾…œ)O’ ^]8`ÕÛRí]êÃÁå¬GíʨßK]8ï4o‹; ¨¡® +Ra9T¡Ó}Ì…«Jb¦„©Ï ö*Öº ½tÝí¯0\äœugN2¬àÊÒû.®µä”2?°…8«¢9ð½³èum‚ÃþhôÞˆª‚8Ï~Q2Ï’¤¯ä4lj06ɨ“ TI6ª®½Ã+†\‚¼õ'³¢ ‚‹^_Ÿ¦“¢L:œ1(¶-H'“yRÞÍÆlª´áŒ½ A®|Y­ƒZ4'#J:´njÏ…P±ëëT„ŠË±£Þµ8WbÁºB÷ > endobj 2472 0 obj << /D [2470 0 R /XYZ 89 721 null] >> endobj 130 0 obj << /D [2470 0 R /XYZ 90 690.045 null] >> endobj 2469 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2477 0 obj << /Length 980 /Filter /FlateDecode >> stream xÚuVKsÛ6¾ëWðHÎD4ø&®-'é4S39$í$a’P0ÿû.° $jÔÑ‹Ýo±ï¥ˆ·÷ˆ÷~ó[½¹{*R¯ «<νúÕ«ˆW2$iæÕ÷Ãøpÿ\ïþ ¶qFü$ ¶YNüúÃuP%þýŸï?ãõq÷íヽ€RIüo‹î§Ï»?‚êßïž²øÂ`%!I pÇÚKˆÁlˆsðúÜÕ›âE^‡‰—|M½vÜü» K+r‡e-`Ǹ{#ïQl¾ÀomíCÛ‹—lVVNF$ +ÆEæqŒ®¾h*5ŸöÁ6‰SÿÈuo¨ ’qÓi/PP¾ƒ3M}Š×‰€9"´cŠï'ˆWäéž!ÃQæ³I#K½)ÍFÄõT!³alBÍ:S©$ñëž+”]ØM/ì‚’2÷¶†¸¢°Ê\õªXõ‹*_LxZ÷ ñýÓ$ÞH*ß‚<óÁjBÈYăÈWHÒ5yà ¬W6‹†3+&‚x¶’Qíl¶b牷TŸ40%ÎðGíì.‰ÀØÈ:*u‘YIPˆdƒ£~NèԄ׳M† Ç=P­™t>µÃÜa+À+ÄóÜ \õw/s£ZÉv­K*ÿØó¶wϨ+}H?o‘„î¸ £ˆÏÕ‹ä²ìª ✴¢ð¿*L&@µmƒ¸(ê;Ã)m¢ØJ,ˆ±+4ÿ›ØTÄvˆyœÉ_¼u€å=.ž²ÎöÐt2^½B2DÑ©»æuyrªŠ3›;K ¡AL ”´²¦Íˆš‹˜†7÷ÎÀÝ›±µn™&켤h™RL!ΕÌ"M§Ù 0gK(a^85Ù€R¼ðVë„dË:!ëu×2ŒÌB‰J×&Àº^Àt@0A†×0}ÄUAÌæ±JP'… ¼!0#–›Bšç¡[Ô¦˜5«“»q4ß®¢Ë1º–*7³en¼Ó¢4` ÓZÛ”•lD€Ù…ætýžn¸KÖͶǀn„­«‘öŽ5A¬ùÓa ¾#ï ìäcÍ­)çÄÃóWä´bRóx° ¼Q/Ûw™›VCœSŠ÷U™;ïXˆÓü¦íéA/€åÅûÛwjí ç Và,m‹‹Ï=ÓH`{­}ÑÐýjý®Ë&P¯øöá­ÅïJRú¯b½£!A¦Û÷³t, ®8TÛ³š®E,²\²[®v\¯'T–oZ—7Õ$Åy4§É12œœµÒÿ~àÜC˜•2¼ùßþsüüo endstream endobj 2476 0 obj << /Type /Page /Contents 2477 0 R /Resources 2475 0 R /MediaBox [0 0 612 792] /Parent 2479 0 R >> endobj 2468 0 obj << /Type /XObject /Subtype /Form /BBox [0 0 522.999 484.999] /FormType 1 /Matrix [1 0 0 1 0 0] /Resources 2480 0 R /Length 29 /Filter /FlateDecode >> stream xÚ+ä2T0B™œË¥ï™k¦à’ÏÈJj‹ endstream endobj 2467 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./27_home_taurel_tango_manual_ds_model_event_schematic.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2481 0 R /BBox [0 0 523 485] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2482 0 R >>/Font << /R8 2483 0 R/R10 2484 0 R>> >> /Length 1963 /Filter /FlateDecode >> stream xœ•XKo#ǾϯhÀ‡HØêª~û–†‘ ˆa‰€q2Eyp¤¬¨làŸ¯ú5äˆ0V؃¶kªëñu=ùYMÊÈ¿öw7O7·Qývœ>OF¹äš'ùp˜<Û“ÿ”O‡éÓ䢋ÚecJ:‚ÛÅtJÊ&6:Y0¹¼”HšY(Ñí„B^S(<ÁkA±I»PDÿü­zžœŽìØ«ÿ3ŒºýarŽuð¬¬÷^g†N"cµwÊ™5gE™ƒ&VÎÆ sP£ÓdÇy7Yq#Š#Ÿt’¿1ëDÊEOÚŠ=&ÉÍÝt7ýtј•áóEçÖÜ}5¾}Ö6+NÞêlÁÎ19í…’XsG²Ú‘âì¼N¹P|Ô^XHQÈÏÃÂBøàOð…Iä’€)ÞA~ ëEP1‘q̬‰Tf\ðaœwƒ«iP˜ƒ(¬µ^[€€ÆDÈ+”kƒæ 6¿sën²à§Ù[ÀápmP¬ ÚÀNcÀΔ­9Ú #õãnbgsáoß)ãý¸>ÎM.tJ„ç¸Ðï'Ä”\è Ú±Õ-h”aa°va‡§¸›Çˆ2âÆ¦Œ:eÁ¨Sº¿”Ñ8b893,p'‘—ty‚bÔRŸd*ùV ˆÛ*#•~=ÑW„B¥`lt±ð {³=¹ÕzçñÒú†Çh@ÒZ»Çç’æ‹ÚÖ}d‚Ä„UD,Ãq™´ÐhP ÅBc)í}¬!ÎQ;_DZ*gð4W#Ö|r7á¯k~®ïÏu¬íøˆŸNŠîw_åć4>dh–2Áɉ‰d1L{* ¡OKTë5ËÞ‚ü'Lô2ÍžLÊmjÈèÕ®N⨄xa²(?&w?Wæ‹JVv|ÀM´h©à„,¨;'ÔðòÀ2½H±‡‰ÉË'9¶1’òe]å±e*@âh}?’å:P²¾1EÔ7—N^‹bèsG›$¿› €d(Kú{G[]%YÊ9GÏÌ•¬ ù@“ 80Hb"¤¤w ¥’BÖ§:ß.”|°W%é¥ò ž&g8Ú;IgDZ\.½e%`þ#%ûöóÚügàPþßþìfõ—íts›d^±×¶Sýí ØYYA¼42§¶ótõüòöôø»z¸ßÏ/Ï×ÛO„%$ã6^‚}wû0]=ì¿<íöê¸ý²Uß°0nœLZ($ks …qwxÚ?¿©oH8ð¶â¶Úþ}ùÀך6ˆ^‹P›ˆ™ÃÂÙU+W™Ë¯)›„–þyõpÿvÿëý±Ûq½ñÜÕþ ®>öß]ÿkû·‰;„ÄÍÅ/ñÅч›O/Ç·ïÔ_¼-¾b¯Šˆ:1°Ê¼y¾Ÿ÷õ;ìì‚dûó¦zXÔ©ã=î^Ÿþóöôò¬ heF"y#K›ñù„ùñéðs…K~»qØå6x‚ä1§®_®Ž¿\WžfÕÆÊxê.° Ì!!ÓŽŒœ0Y Àf±• KóZ~–*ÛIs~ù‚vŸ\fµqò ESݾUÓ›×;ÿvŸîŸŸ÷á2Xд! ?ßÜ"N1fƒ ‘¹a$8ÂQIap-ØîvŸöóýÛÓN½<ªíŸÿñÃêûúÆÇßoû¹ :‹pd°=+¼&Šl/m Éï·ÈºŸ¦ÿ­ÖY endstream endobj 2481 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152423+01'00') /ModDate (D:20160114152423+01'00') /Title (event_schematic.eps) /Creator (fig2dev Version 3.2 Patchlevel 3c) /Author (goetz@splash \(Andy Goetz\)) >> endobj 2482 0 obj << /Type /ExtGState /OPM 1 >> endobj 2483 0 obj << /BaseFont /EZHHVD+Times-Roman /FontDescriptor 2485 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 500 0 0 0 0 333 333 0 0 0 0 0 278 0 500 500 500 0 0 0 0 0 0 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 722 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 444 500 444 500 444 333 0 500 278 0 0 278 778 500 500 500 0 333 389 278 500 500 0 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2484 0 obj << /BaseFont /DTEKDX+Times-Bold /FontDescriptor 2486 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 667 0 778 0 0 0 0 0 0 722 778 0 0 0 556 667 0 0 0 0 0 0 0 0 0 0 0 0 500 0 444 0 444 333 0 556 278 0 0 0 833 556 500 0 0 0 389 333 0 500 0 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2485 0 obj << /Type /FontDescriptor /FontName /EZHHVD+Times-Roman /FontBBox [ -9 -218 775 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 116 /MissingWidth 500 /XHeight 460 /CharSet (/I/O/R/a/b/c/colon/d/e/f/h/i/l/m/n/numbersign/o/one/p/parenleft/parenright/r/s/slash/space/t/three/two/u/v/y) /FontFile3 2487 0 R >> endobj 2486 0 obj << /Type /FontDescriptor /FontName /DTEKDX+Times-Bold /FontBBox [ 0 -205 814 692] /Flags 32 /Ascent 692 /CapHeight 692 /Descent -205 /ItalicAngle 0 /StemV 122 /MissingWidth 500 /XHeight 473 /CharSet (/A/E/G/N/O/S/T/a/c/e/f/h/i/m/n/o/s/space/t/v/y) /FontFile3 2488 0 R >> endobj 2487 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3214 >> stream xœeVyTSW1$÷‰J;ÄŒ5ÓE­Š¢m°¶ê€Xkª‚ìÈ*"ÙXÂ’…°] @€„}‡ ( h©V팥îK§àÔYºÌtìéÌ}œç,/væÌ=çwÞ÷î½ßý¾ß÷ûæ²c0«CE’”,ï™$Qê”·“ëä†äF¦ž’.7/ïcmÄ­Ì5p5®viÛ°¦Ø=ýê~ ½Œ1Œ>»¼é×ÛGE’$E–× Ë½ŽÊü½^!)B…81óç+†R™<3+[q8'1)ÿTrʱԴ‘X²s×î7½^ݳå ;†Ç‚±X(†…c[±ì×Xb± Ì;„ÆÞÄ>À>ÄŽb/cî[‹10l=¶sżV¼r°YF £sÅž­L7æa怋À¥µ…¥eý›Ç~|Á0î‹×ã·VêW6­|êºÇuÖu~Õ›«ÒV ¯ú,u#K¡•ôœe<^D‹Ìfòn©¾ÂñÞ:U4AU¢UG–à*”f‘UªèÀÑ0˜¾ÐÞ0ñ‹âÕ @£ŒrnJ¶‚èêÂxGùàëø+bÅÊ#‡ø@Qet¾HZÀ£oÔõ’»{}@M`"™À¥~é³âSëÿ¼ ¹#÷oÿŽøhÝÎo¨µ„FÆ]¼ºÚH±âíONíÏ!d3ŸÃ[ø7S×oñi]”¤EÙš$ºAÒí÷{‹Hñd§¸ŽÜÈ­«0Ã:ˆ›u'‰çiFhµÇ8g“N\+Ø_¡±À8ÚFNwêÎA¹þ ¹ ×ÑËŸn=ŸO<ÆÊ°œ4M¨’‡¶îçö_qLÞ½¸Â)fôþ€“!Ž~¾zBã÷®q‘i&=¹M¦ºŠˆwÕÄ” À¨¢¢#…4.EVpȤ´Â9)ÀàÄ¥žšºb…߬¶!Þiméʱ‹¥ÙÑÄŸ@qe¸B¨9žGƒÅÓµÚÉvM»ûGבÿçë8ÛÑgè&·m`iÙeeú¢òòÈ3B]¥¶ç´Ô*Uë÷†Dœ<µCÌŸÉmÉ‚b^|º,R$nlÏãçté;4sxåÓÈ6×WUÒöru°©¬ƒ†§ÅØÛSÒºþÁ§óŸ_Ê:æ (ìSY³ª öðÆz'çúE»;h¯t3äêA÷FTL}¸¸Ž³„jÉp.gaÂÙõå&#¿HoÔéRBb JpÎ’¶ÈXTì K+ÊLe8gácê2Û·?áêÅ33C|%'S©S@^ªªçÆgéol'MæCìäžu“û­EDßÒBf]â³cµ–I}Kíœ!%¸^Ú ƒQ8U ¬X­ÖÊâB ēӇÏœôˆÚ¤Ó¥M*‹SÕ`ïtäѱæžþÄËpUe—ìËGM«1÷›è ŽëæBæIN÷+_¢-_¬ã\ þ–«T« ž]Ôtž@Î÷©:ŽÛqˆ{ˆdÛs;:ÛìíUåÕåf¢¬®¼šñžÁöñ‹=Ò0þQ@íøPiHHQäªEð4Ήœ¿vþlÛÌ5>§1¢º5çìúaØÖ0r†^¢v~É…âb}Na–Z¦Ïxšlx‚¨ðêYZsÞ «n0QîWLä½ü.·¸2Q%7œÔð¤V¨©¨‚fˆ×é‰çÍ@¼tú1òx†V WÑKû¾Þ|4XËw›rÌ<¼ô.åF1cŽøGÄut½Èré"yÆWæÄw=o³¾ ¤ÜXZDl¥ú(€jŒM%ÐB£k5OTÒè&©AwI‹¶V‰ØT¹‡É`•ôF5 ¡ŠUÙ¥D¡ÈSC#ÔWêªóÌÊ*%bnnÖéÁÌs7§¯ ×.h¹½qÐRßiâ9Ñ¿M²ú]˜ä+ȇsP˜qŸ#øaöÖŽFmj=Q£¨•µæ·A^w»­ãÊÁ)ßèÈ\a/;÷âÔ/í@Ì ãÍ~O§­§ÿê Ìf`3éÚËèy‚r™è;mža5ƒüò2X q¡f:ù)]b”iº#J^¨­¨µ­Ó%”H”[NAœ;(õ µöÞ[hÅ•3ö©aâMaXTT¨Óæçfê¤÷ }Œ^B¬‹wï|ñd8átkIp0Èíȳ/Az†À„>é\þ™¢¡²k8ºÆ6üF×—9(qĶEÀ(x2?Et2IýqŠûm¾¹waçøÔC´ky8/¶‚à]}Þmy'´‘?ŒæÙÜŸ=CÄXÇy°¼ÙÆM1åÖK‡©$Tãq³±¿a¨g°ÛvNÁ ÍhF_ÊY¿noš}lÎ…X¯¦›x€aj ˜V¥µAUa=œÅɯAIe„2E¤ä¹-ÛhÓ6Î0ž,"óaÚè¦ÑTëhºë bªÆ©Cu¢œÖ‘iá•* ÃÑ€•µõfsWÇDËÄÏ·§Ñq”xB« qZžm!ªxGÕ b¨uâs­r?‚Ò’Á\Do’YAF¥¤RÓ Çx( ×äOÞ ŽÌãçωzÂ`<”©ýø=zŠÌ£g!ÝsÔöe¾ÆéÜxŸMåÿ3ˆõû'†}Üt‹^=a¢óÎÄy߇¥ Õ–ªªÊVsKU=ÄÛêTéÄó(O² ô*½º4ÑéVŸì­(¨‡Ó8ùÝ ²Þ';î2П0IÚÈÕT§†hôqGØh/ |úç±ûð!ïû=^ PœJå§‹TéÊÀ¶bñ¿8 ¾8âûnìßÝD³ IO§V:·ÿø‰;ºý(åö:ÎòF_r¯Â޲NýuÅX Â}C>8 Ï5w¦ò%­J³³¾ªÔ9iŠÏ<ê>;EL힇7áGSÒÜö¼†x=%,Lu^öüâÈ•QñÊt!_"We(ŽYK<ÎÞ¹0t⿹/ª„™™„D"SÊ¢©hr:hG‘³Ès}@wˆtÔÉÝ̶#OÖ³[Ùý(ŽÌ–Pq,ŠÇx!ˆ‚k(ZÁΡ> stream xœ}U}TSç¿—Ƚo ¦–œL˜šÄÎÛª«VÝV­ëR¤buIH$!!á+ò‘„¾|¾$H€\Ä!0øA‹µ²µÇ:γµ§Ã­=vÝN=í9}nöòÇntn;ÛÎÎ=ç=÷ãwßçyŸçùý~4µ(Œ¢i:"UoÔX_Úa2¨C/òËh~y¿B„‰*x%¸;|µïTøb)‘‹ú—?ó§(¸ú<œ|œK(M—´øwšÌ6‹>GW ˆ;%mõš5/þëÍú-[¶(²lO¿(vi¬úœêfŽ?ê.ÈAò¥’ó ãURrÐÊ\­•X…ÈE«ªœéNd…j?«m¶wá1>7hkkE’ûý}þŽþe£ÝæƒrRÃbmE©¾VÛý¬º±²O!hbç]Ùr@iJÖÊļ»|ˆmˆæ ÖCœšx£”Hâ_ ËÉþ¼ –‚ô«o…tk¾%Ry½A:דJ6“—‹ÓÞJ.~baשÙkrqp-æ,C<ŒX¸¨oáÕ¥ÿyp³tá.#é´°·j{Jña´PÂâ´rÇö*$ÑYøOÙ P‡›ÃîbSNžR›Zº £½%Ór¨aÆ“ê‚Ð|‘Ï”FC¨zeìxgë,lšÑ“NÆ1b>¦|„ßÙÑÊ5xë£ÿíÄøüên•pâKѶCÇßÉÏ-À1Î*Ok=n¨o”×7×7ã&tÆêÓkÍùåı«#g:z{e½ý¾‰Ñ/a5¿2º{ª­m¨‰ùäò›|Lˆ+Eü: ¥ZU~yFRÀòoÎ^ŸõvU9ZäÍN!Uý‘ScM øÏ]Û}鲌 ¦õ£™3. åÿþP‰/*4TCÄRÉf¾„7IÁhd]ùUUÇmr4z›ñþ,·E³Œ,ß¼•D½2»"Rä7sÿ¨òçã´˜7ޤo}ënF#3•ÿ5Ê#ø ÓÂyZ½ØƒÛÝ}®÷޹¦1‚ø¯ÿQ÷”÷öž•“¸ßüx¢Ã—b®M|~ªDû وΛçÛƒ»K0ÂGC ¼*–g¤x»Ã±Ñ%Œpc7´8Úðoïgá¹ÚYe7‰@g˜:P†/ü…qeø¦"f/À’&a§»O=öö“6=ñÙÈ~ê³Õíö§…s82ª„¹B…s„ jV‹·§³ I>ñövŸè^v®«àÀãve9*´n\!€›„Î>7‡À}Ý£ñ.kòc¨Êaׄ NÁ’xú©%§h ö¦ÉŒ×uþ}xVš5uoûx•Ò|Ìð³ ˆŽŒEäbŠú;tŠ» endstream endobj 2480 0 obj << /XObject << /Im6 2467 0 R >> /ProcSet [ /PDF ] >> endobj 2478 0 obj << /D [2476 0 R /XYZ 89 721 null] >> endobj 2475 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Fm1 2468 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2492 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚ]N;‚0Þû+nlÊõtD( ñmÃbœ4:ãÿ_¬PCn¸»ïq÷!¼¡%+OÒ&×`¹Ídþ !Ç‚£6àp¥UW½;³D¤Š³ÄdH}ç&À3«h¹oÓZ»~]EêLÒ~öîµÛ²›ß¤‘µPUâŒÿ”øiÆ€Ëî<a@`%W P†¬îù^ŒTl#4‹#6ƒ„úMN¡–§¿ðì9 endstream endobj 2491 0 obj << /Type /Page /Contents 2492 0 R /Resources 2490 0 R /MediaBox [0 0 612 792] /Parent 2479 0 R >> endobj 2474 0 obj << /Type /XObject /Subtype /Form /BBox [0 0 522.999 484.999] /FormType 1 /Matrix [1 0 0 1 0 0] /Resources 2494 0 R /Length 29 /Filter /FlateDecode >> stream xÚ+ä2T0B™œË¥ï™k®à’ÏÈJqŒ endstream endobj 2473 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./28_home_taurel_tango_manual_ds_model_event_schematic_zmq.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2495 0 R /BBox [0 0 468 364] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2496 0 R >>/Font << /R8 2497 0 R>> >> /Length 1044 /Filter /FlateDecode >> stream xœíVMo7 ½Ï¯ÐC쫈õuLÛ —¢EâzÉŘŒ»6²k¸è¿ïÓHÔŒw÷ß Ö|#‘O$¥ïÊhR¦üµßq?¼ýÕ×ãÀ:Z¶^ý3ÌßÕ§‡5Ee-GmÕ¾”³Ñ³ÏÚ°¢˜¬vN±5øíæ8¸Ì^ûÐ]Ô캱[lÀ§3646’Õ&H1ÇA(ô¹98Éa¾ 7ÈÃG¤«’…sª™Uć¤cÄ6æ¬}V.Ø+¦luòÝ.©¹ ‰:â¢:§îAl‰Qr«ˆ¥ÅYˆáR!vI®²è+KñpšGÍ.:í Gåp&dwŠìDŽ3ˆ@£ÀÏ™´Í+òÆÏ‚XO¤£‡ŽpôÚÂWóiq&:X%QÅ2”°©#; žuHAf\â‹Ïn·¨ÅGE„Ùn…TîâSr“¨bÿ¯ÒëU¢l¢6~¥’ ‹J‚HÆ”"z™W6›ê¹#ŸW"!vÐ.v‘ÈZüºHb/" ²ˆ$ˆ$,>{ºh$¼v+¤2ï.[f=h³_j>æµF‚, " Ÿ´Ov±-¦˜÷+"c¼¹•Fž0Å%fб޻Fb/ ²h$H/ŠæSìtÑHx- sq)™IP±«Fßq«8Ї8årÙaà¦Õ?ó§VE*3Ð&v:–®$“è—œ¶5 ¬1蘄ƒ6smC™¹þ“ º²šr.‘FGžõ\\'¡~@ ì µkªgTÏCœÒx}Ywx§¤Z-q 8WXÄA­&Z%Å9•ÛòÐY¢› ¿`Y#­”°¦$’lÖ¹¥(J¸T{]kªçANx¼ª&ñ•à äÖ s;¸à{‹"®Ãc#Õ©Ö¹ò”²ñ2Ò8:<8²KR¸«@? „C­” ÔKâŒéyS"7íùyø I¨þß~ƽúe‹ç*”ÄÓ.c¶lï†úŒ%Ŧ¼ðܰäÔv?\ý6=ßÓõöïaƒkXmƒÛDVÛ/ÃÕq:> endobj 2496 0 obj << /Type /ExtGState /OPM 1 >> endobj 2497 0 obj << /BaseFont /VBAWKL+Times-Roman /FontDescriptor 2498 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 500 0 0 0 0 333 333 0 0 0 0 0 0 0 500 500 500 0 0 0 0 500 0 0 0 0 0 0 0 0 722 0 667 722 611 0 722 0 0 0 0 0 0 722 722 0 0 0 556 611 0 0 0 0 0 0 0 0 0 0 0 0 444 0 444 500 444 333 0 500 278 0 0 278 778 500 500 0 0 333 389 278 0 500 0 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2498 0 obj << /Type /FontDescriptor /FontName /VBAWKL+Times-Roman /FontBBox [ 0 -218 775 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 116 /MissingWidth 500 /XHeight 460 /CharSet (/A/C/D/E/G/N/O/S/T/a/c/d/e/eight/f/h/i/l/m/n/numbersign/o/one/parenleft/parenright/r/s/space/t/three/two/v/y) /FontFile3 2499 0 R >> endobj 2499 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3698 >> stream xœeWyTS×Ö¿1äÞ£"}˜'Mxj«­µƒÐÉZPª"Ê L2j‘@˜IB aÞ L!@"ƒDA”qh}Öj­Cô½ÚÑöùz.ëÒo}7í÷­ïo­»îº'çœ}öùíßÞ¿á´€àp8Ρ²Iæ†`EJ|ªc¼žöàÐËÐ+¸À¤ÎµÌmå­ Ú¸KÀ™ ÎNG—?£uÅßÿÛŸÁE!¸ŽÒÔå«HSeȤIYžk÷‡=¿nÝúÿûåEÏÕÿÎxúI2eÒTÏçØ‰\‘–"IÍzÝÓ—]-—ËyJ媴¤LÏøÃ‡%‡ÛÄË%Éž;drYZš"Çs­ï󞛽¼^ÜÀ¾^ ”¥$dgzþá¹g ÂÇ3À3X"Í–Çgüÿ‚ þ¾-Uáë·=#Ó?+'^uèp dob’,$Tžòâæ—<½W­}ž V{‰}ÄjâYâ9"„%Öû‰0â"’ð#¶›ˆ„áOì$v/¯{ˆ@•àK !$œˆ…Ä"b% *û)!îpVqšðXüέwZåTâô ¯œ\HÆ“¨½Ôz•¢ßF-œ_´sQÉâWëßqŽuNpþfÉþ%–%³t™Ë\"Øpø(ýwgî€UcÔ7$Ýfªèkn¹$sx¾`7ó\A^T¹P‰#­TT®ÙÞdl®1‹'ðB¶£ëšÒLé B†Úp )q5Ÿ˜ÂvŒ;Ï…. í~óÙ,ö›å¶Ð+µÆ†ÊF@özM¤˜©¤ X§ /Eœd¡Â«5M0ˆð êìéö¦~@“òbFBA@¾:Â±è°…Š¬)h‚I„UÔw±ÓÛ¢åêÝþ¢ûTQU¤J¦ Ͳ'êíôf;çø#Üüˆ‹tœ€ù›×:FÄx|ûvÅ®?ü‹ð²Mß3KÅù Áì¥uÌ †ãÿöáÄΑ±b*ïc¸‰¾?sõ¦Èen“vœþu„Ã^†;GÐ…8‡—CçääB!hŒšÚÈ–ˆºƒàÞò=¡Û÷H6³6ö¼ò~ðå]ßH~̃Ÿ&®|ŽTmÛüv¦xƒ0Blqá“òG€¹ïü/ÄÏ^œÊ94"êK¶(¬»#(Våý`Hiuý÷šÄœeüÊcŽ| ò·– ¾\‰‡(ŒàiÿÕék—†¾‚Çð(å^èÿ gYˆé ùË•Ôý¢úBØÆ®Ò/èm¬}x-OvVtoÿè+ÀÀ,JØòÚÁðÔ ‚—*¨ï»ÐØq2ÅõÃìá?=YÆÏ¢¿Ão dCÄe2«¥‘‘_Sd*1–7B+€7R_€%ßì:°&‹,J(Õè´ùj…á ëÈFœAÚkk»E؃d±h×´¾ˆºÈ2¼Š7o'ù•Jêv±Y ÛÑü> ¶k5ï°·óSÒC” ~ÈçMçÎ,×D» šõ•M€ºêóbÅŒ‘‚ˆ¢¢Ý,!Š,”¿Qm‹gS}cïu×Ö—èE-ÚÆb3 NK«½?Ç&‹OÍò‹C•TÈ–æïS²,êÛ lôF[~»ëûW±ÏÇËøëñGøº /çéÈòòÂ¢ŠŠRƒ¾JWƒø­uÙÙÕéo‡û†ôz%ž92Ûš ral²"\&7·+E9]…ùQãe&M ÕU¬¿ü€zh.ï(f Û»KÛ<î~8óñ{™ý{Å ñ¡¢EÓÝ‘^ûÄÅÙæ–p‰Úú·N&iÏÇܹü›€©S‘ceMeMKamÄ!æU*90Í—Ù²“8ð;û×ã“¢ñÉ«ÝÁ4L*OJ{-i]¨ƒ4`)/›,Vª´9 ‡<£Êc‰®‹aÃrYŬaâžï~{zŸøúŽ$x<üב„c)¸Ôdž©A.¸W?E;÷¹šq ³gvÿ®c“€ã9ŒÈ† c±¨¨°¸°H/ ‹Ê+Eüº¢â¢w(«,7–#þsÌyrKOÜ¥ÉáΩ~Q~cN†ZŸ ÂDM÷b|’â?ø…dÓUk£ß°qètÖ2#Ö}e=(A_®/Õ¯ešÜžÅõÅÍeÍP/„¶FÓ€Y˜p 5\nÒO¬ÆÎ̈[U±±Èh¨UÕj¡LfË^Šo»ÿ¨ÖÔcD.ô>ýÅàÚ­ÓuúK¼öóeüÓtà?jmA‰PVQó¸‡Q0Ur\Ó™=gÝhöȀ,[nGçQ[{uEM…I\^_Q&ÔÝ×>2Ùº_H1÷¨ q’ì\­ Ž ~xÀxì•ñÑ£SWD|sXM[묂 8Ú40ÌN1›¾€¼¤0§ S«(Ì”¤81&®fAÄKÆY˘ÔYú ‹Â‹AKa^iEqY‘øæ8CáÚâæR34²XLcU, ZêXi«®NI¦ÂÍh°¤Ø#Z¤ ‚&+@¢MÏVj¡ «ô5J“ºZÍÞ477óH_Æ©ëg§ñêób¼‘^oîklè4 Ý¢yÇ9]w¹ôJì%ˆÚ.Í äµû3Lýzáæçƒf]bƒ¸6»NѦ: ÂcíÖŽéíg¶D†çJı x1»¿sO´ôŠº;­Ý=—÷ÒOA ½ÈÎé~ˆsg¹ø±^€×LñZ(UE9”’'Äô‡lZF©“ô»ÕÂ<ª®²ê ÕëÄŒ%éKk<Äò•ÚÈð˜•ÌÒO_Æ ¦‡mgNˆwS˜ãEEz*7CŸ È;ô3ü æMÞ¾snòà1›K:[¡uÎÉêŠ9ãôKãŽÈÓ:ÝAÁå†!«¹¹¡¹z¸Y™%5\Ö\j)´i륰1¨y­ä1[•ä4F¢ù=?Vk•ÞŬÊX©·ªÕð ¢—S|38†ç@ñNíÃÔ ‡^½Q[ãRwC0ÄO½¨.ê/¿‚ðÒpM<£/e0úhDÀA•Dv0!Í|#ºõ ¦¾ÿô&N‰˜{x½ ñÞ‰¡+p:æ—¢ ¤ÿks‚­ oa’‹Ÿó0!Ìrf5½¡Ïë|x&à«Ãÿ„#ðr쉣J}zYpcËà:j§ ˜P &ŸìÝÌbØ—¿#7¬0C‘••”£:ÑÓ–Ô6qäV—à‰ýñ©3èäØdû@Öâ5}8ÞÎù• ãUKŸaKÀŒµwøh³>µMÔ’Þ¤oÔamëŒ=¶wÏ´ètqz¬AZñ:òIþ‚¹NÂ;º_‡„›-”Qן"|»Pvç9ŸÌâ@Öø‹øÁ©‰žÖ“€Þë’n3‘øëóƒŠÿlö7×Á „£¨§ñç_ÛŸ¹7Z„/R%FYA†!$O˜fàåQÕ•F¨4VgˆÏ'³ÂR\d`÷Ë-TP­¾‰ÝÏV6öÔÅ–^òÄõÞ“WÙâöû:z…M¡< Kæ*se=;ÿ ¾z݇ûz µ³ÆÐ·ÆŸÇ9‚´¬,…¢=Ë~¼£ý¸=«#•ÕÑsÚÁlÍŒÊl®7bí/ËøËé6`9di–N§f«1›”uˆßßœ˜X—ì±ê#©IrU<„Áëã!Øiß-ÉTB—¤>¿&2Ñ»Ñïl¸€]"DYd“Äk'ùÖʦf‹«Á¥Ö"Ö’fxÄ0⩯îÿúEè5Æí¦xåLü8œGN _=}J)õ&7§·ìcõ÷¡§<ÅÁ¦'\lš#óe¼ªÓy—°ô>m¥|ªµføÑuç)LB»ªƒY€:Ébüoþ Y̼Åë$;1§ÃŠàO,9?Îr­s\A-ÙXÙTÉfp_ƒö x>‚ýÚü€8… ¨.h€ ˆþŽ*­ SKô;ÔB—9+ˆSœ‡³8Àñp­lh6Ö9zÄcõyQb¦ÖaCRÁÚȰPª4pá ªêL¦®Ž±Ö@ãíI,WR(Ñé‚qʲPÁ•šV¸Šp Õ3Öß6èb[š·˜‘²=§ÁTÄ.RX¨ôª”ªü68)Ä ^tøò[AáéAûEª‹²îý ­wú”m/Õl{©þI×sÍ7m,{ÈÅãŽ,|׋§¥šj«««ÚL­Õ €ŽÖk’Åó1dåj µeñÿ[¨7*óà,¢ÿÁü;tÇmþú!—Và‚üšÄàüÂ2¿ý¾úöä¸'üùµ»«Bò%Š’ešdµßÑ·‘ûnš½¼åÍè[6‹™L¯€vwXe Å×—]ñ­û’[Ëø7ðü¥àt”w^Í> ;Жà]ÛÒrM‰¢”6µÉ¡ mNÒXöÇwï=#>3zl®ÃûygR{sÛ•M±VVÙoœé:ïþùîéM±êd©(%M“ž½×Rê6úÉéþ]; ÕH32Ä)) &Ë £Ãûœ‹ÝuúÎöÛXq#ôÎ2þ] ë”BÚ³kkøÌ??l?5sF4yW°yF:ÓhæôèÅîVÄKD%e¥erüŹ€Ý/à]¬Ä&ãNÁÒ†ÝyO/¼@öà^™ÂÄð!ÙûÇ@î, Å ÈÆÇ ÐßÈ#Œœ7Cöc9»³óŽA¯cÀ!ä:Ö¹“GY›l©œ[mãœe™q–eƶ¨”ôÄh¿—“Ö³þÐóÿzv4êXöTrS‹Ûë(Ò>ͼ®»?ÃSóÝWíW{oÍ ÿ1‚£r‡™í‚Ûg{Ž MÜüçÀÏ€^šøø¥' gÓÛÃú òÜ> èN²¿ÝùnãVX«ò½Ó)Rß ä’k£Øp¨ìYô`qO³óƒ6ç%ñß®>Y~ endstream endobj 2494 0 obj << /XObject << /Im7 2473 0 R >> /ProcSet [ /PDF ] >> endobj 2493 0 obj << /D [2491 0 R /XYZ 89 721 null] >> endobj 2490 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Fm2 2474 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2502 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚ]N»Â0 Üó“×y6¡ P”GÄ‚˜@0Uˆÿ_(}H¨òp¾;ŸÎ/ X±EbÙ2708å =!ä䑌…ô€+/ÖóCŠ'1S–¸F1³ŽxZÇ^H"h>߯ꞖñRƒunCžøeÌîê2nÅ-m²¥U…Fj$·ït}Zýn N1&&Û…@‚4tÞÁ½a&ÑöȠTW’P™ÑʪÆCùfÇv¦E_.â> endobj 2489 0 obj << /Type /XObject /Subtype /Image /Width 567 /Height 584 /BitsPerComponent 8 /Length 107161 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIFÈÈÿÛC     ÿÛC   ÿÀH7"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?øµ®LŠß>é €€`粩ãó:„HUJ®ì£<y9íYëpb••¸e)=Çlþ´ãt-Ô¹äz1Ú2HArN:ßMÏRÖ.™ÛqUf$a°Glc×§â* 6âà¸` Ç·çß•=f99p7’Hç±ãçð¨ä+µÉNTg÷àúŒËÚ‹õ I6È6VSÈËÉÇ8úñQ+ÌÒ¾èˆ@AB[§<`}=)A&8iùNÓ–=±ž1éïŠtŠ+2+÷ZBpOÓý:Õ^û……>d˜Çܱœþ÷ëïQH~lF§Œ ¤Œç:óÎ=±I·å9eTç#ÏÓ?Ë?Ê!Y‹Là.r~öìcò?•'p°¥Ê£Á`Á9í‘Ǧ\uãêà`¸dã&3»rórpyϱÇñÍD¨Ò`8Ú˜èzú}~™ú†@£÷³'‚N7cŽ?:`KµbpÃ"%l…%›ol’O9ãüâ“äpªcS°dØu뎟ãLó °pBŒåx9oåMK‡g ÁùAU$G'8;ŸÂ’‡–ÝÔŒòž£óÁþtà‡cÊðI>™ÏÓ½Dí€3"Œdã` z{AüÅ42핎äE9 ó1^9ç<óüéꀸ®íò¸ÇÊ>z*‘#+Æ»Šmܹƒý=j´wF&-Š Gœ{çCS:Èóv¹ÉTßùàççôW‰X´l¬r³1Üñ·|üØè3õõ³ŠGo=’0C#ãæÈ!Æ>œg=x¨bo”vª&6` Øz~4±ä¨RøÂyÆz~L©8,‘³`F”N¸ëÏSJdûBÏòýà\ägœ¯ÿª¥Ì«‚ÓŒ‚ rAÐóž;{ÕiÚ"Ã/óKýÖÇqÁ\)[ª<7$o)¹N8äóÇN~•%˺F Rvqž‚9ÉÏùãµ\…À;·oʇž£#޼àò*O1#¸ÙeÃ$` ޼qôéøT¾j4Xl»3¡ÆF=OOþµì RÞQó y`÷÷õzd ‘brÉ3;6;gyõäús]¤„+Ù˜0dÀê¼ü¡±Æs×Üã i;â',Tÿ .Tyíî?,Ð3@ÊNýí£q'»AҪʉlòÈwqóg§|ä Ü>¦v©W`’ìåð¸òOS×ðúR]Ì]¤oNG_Æ­=EbäŽarÊTŽø³œå×8>•!X•8e$úäögò?>*ª\« é·Ë*Ç%¶ƒÔ厾”§™wïrTNIÇL~“FÃ’ªžŠ Ÿ—Ž98éØ sœŠjùb=êTdåB²ä÷*;tÀôéO‘|©TQƒF¶7*w0*F:€ýwȨYÈ‹~ò1Î}=FGÓÿ¯KÔcÒpU€I9|u$tŽÜr?ýk‚‚=ÌJ€QX‚Ç·B8>½j®÷•ö¶íß!íãñ鎵#ÉÇòÆ@ #'# 3Œr~œýpG¨ì]F(˸(d œŒñ׎?Ï5K²Sƒå©Æ]Èãœý?ç½0\™P–fùA*]²FGПOóÑÒå¡À!°àö9ð={zÑ°Š²\4db&ó1ì:˜ƒ×¥RšÛÍ@à ÏÊëÛ×å÷>¾õzx\¶<°T ­Áà󞾇ôüjË"¼ÁÑÊŸËùqè>oÏñúQ~ãDbY&¿½Q²ü½ÿZŽ;ƒ+œä³‘·wþ`zgó=šò!þ\Œm9žÝ{ý)—y/ÎàvòïÛŽÞëÖ§aÜFA! ‚QRÍ’1Óœõ¦É"Œî8BH8õ<\úÓä¬8/挟›$íç±8íßõªï;¬ˆCˆÓqÇ£gß×½vv ùAù@À¹¨vî ¨öç¯R>Ôàÿ1' ƒ»*Ã#ðþ´„îˆÄääg¿¿çë±%,#LdAôÏãíÚŠ˜¡'︡Q×ÜqE' ¬ugvTŸâcÈÇN[_Ò«Åtúy|GöŠHr鸀èÊHÏ;†âAÎAŒV§‚6håhöºÉ?ÃǯLàUI”*nU]À¯ÈË×®AüÎik±¢`«"n!—ï/ËÔþ}ªQ’J£Ï7 ŽAÿõ{Š©Ÿ$©u;ˆÀd`2;¹ôÏåø[ 6xeÀf$œþ8ê}iß°X™‡Y ¢>ÕLEþÏÏ\äçêEEöµ€vq¹±Ó8Ç4ðIde˹l)S÷IÏaÁþ”›ãU Ä(ä);ûÜ V†Ï?žŠTnQ…`œÙÁõÇ8úštR ³*XŸ]¾Ÿ×ô¸X‹0@‘Àã'<}:úñùг«"x Ü@È'$ñâªý„Nµ£©m äŒ•çÓüñHì#ªF¯þ°dð:óÚ¢óD›\®Am¿9oÏê:ûQæ0•ÚE*Ÿ¼¹ÉôÀã'þù¡=N·ÑÆ@*\:øšq˜£—Q€A8öÿªòÈÙ´ž¬Ã'òÝi¥œÊ 8à€A8ð8ÏãBabÉ•d1’7ß+c9<Ÿ_ÿ]G";(b äŒ’G^;|ßäTBrW;@à½ÉàþKö_åb3Á㜞˜^ý?,Pì1²sÜf0ÉèG¶?¼{v¢9ã†]Ï cÐ) øsÐýsQ»y;B»Î6çn:('·CõÏ­J»èÀaÑYsÈ$äwûP´*³>âb°`üçŽÝxïÅL'8?˜«»9-Ÿ¯z¤^Ù䉈זèrOcúõ§‡BåfdÏÈ9õÀÀõà÷íÍÈ D…X‰`pËžÆà}?Jx(*Žc,Ä’1ëÏ^˜üÍR™ÔF^< ¸“9œzuöö©ƒ†@ãvÀ2Y\‘Œ‚}Ïÿ @µÉ‰t2»žâØÇ׎1Šdâ9%f “arpÃñüjšr[æš6æFÊžØ;Hç#×ðö’k}£!n;™w’zž‡·SÉã 9¡¥Ðb´ÏÍW c ƒƒ›“ÛŽƒÖ£-ç:1PKƒ»ø‰ã=ŽzJˆ:Z($ ÄNß™ºŸ®jÔç(êÀôüþt¯}ÂÅèU¼¼mÜx,TåpÎOÔþÊPí,Ûîa€bIÂóõ#ñ¨ëc8#{:ïÀÉÀÈäñõò(¹b¾P‡+æû£¯èA”ÖÅ(–.cXVó ÌIRçæFÒG½L·r0N:³NrxÎÎ*’Lá‘£‘ Irs‘Ôöãž>•©er¤âhw 8?›æÇóíÛ84¯arˆ¨ÌÁÛ µÞÏó äuüúÑ,‹u(ÚrHêOlû犑§…ã†5H€;bÈÜàv°3îqõ¨šù;¾ûsþÏ=:žÕu¸X†â‰¾Ó{‘J©ô'“ìIéH.w"7S$o'žH>àõ⥷¹g·”D6ÆÑœñ“ØŸéVèc”òŠÏ¸МäxbzŒ1À§q2o9ƒìum„œ2œ¨àÔ“ÍSå© 0qŒä}>‡·¥VÜg,¢2ê ev‘‚;{gùÓc™c‡Jùd´pNáMw5´‰ØLõR Œ€#®GOÖš—çÈýæX–( „ç;N:g¸èsQ³ìXÙœGÏ9#''§NžÕrÙ‰`Aç(H9㯯ÿ_Þ‡f…rÔêZ ÎSÕzŒ üîù«-Wïm8=ú߯áJ·d££¡e‘G-’F:ÅBÒrάAeÛß6{ñŽ{}sOAŠ„$f0«´mà1ù O=zÜÊ>T'úg߯åíPH>ðWn™Èã9ç>µ 9ûÄm8601Ï8ô©Z¢Ô¿$l&BôsÐϯlþT“Hª3Îí»°€@ÿçÖ«Gpÿ6Ç8$†hùnÙïìx¨ÔíåH8nñÏùΘ¦'ÁøI#d8G— ê:c­\Šg?!g.ó%,Ý8úöéÐVx“Ëge*CdÓOÈŸo•26•eaÛiàcÿÕëI$4úæÌhÁ™a°ªØ98éþzÕiþq•Ã(bN:óÚšn#p»¶žNxž½HëÁ=sÒ‘\cɼÔsêzzw4=Çq«½Xª¹È^£×žžä“úP]¥•Ã1É=sßÜûÓº©Ë“ü\à^ÊÄ·˜GQÆÓ€qÞB.,Ĥ€Û½ Éàÿ*‰$„o-P·ÊF:g­uÜüdÆHÈÎ{ÿD>\üÛ:ã/ü¿Î)ÜDë!Y n€‚Së×úþ•)“amÙr0yƒÎ}8©°’¤ÿä÷ú}3NIAaŽI8ô>¿_óœ —üä‘Ù‘ZEf,Ê£ï`Û¿ŽÔ[]¨>f]c ¼b«ÃxÀª,¸éŒŒJd ßòÜö&’ šÐß¡ Ç{1ƒž;qÜž}±V$ºMêY•¤yU`¸ÈÏÓ?½sÆà‰„?ìà{ôühŠä¢Š2y?ÄNßð¦;$R!caœ îgž3Ïz•°hŠÛ¹$°à==ñÿÖã†÷Ëí-‚yÇ#úñW†¬Î™Q݉<ç“ÇÓëþïaÝ3FTFòB«!ˆƒÜ0IÏ$ÓC¤ ºüœõÀìFG\VqÕEeÉ|ýì¯__Ö«Év8ÚÇ<’à ÎqÔÒ¸îiHä¦Ó!U˜ÛÃQÓ=sïÖ­ÅpŠw*2ä‚­ž:õëןÔ×>n£ænHÁ'ŒõëþsRC{"‚p;p8ãøþ´yÍÒî‡.ɼޏ%ÂŽOáÏ×ó­<%)`žp£¯#ÛÒ¡‹P"™#ˆc§ÝÇRGN?Ÿ|ÓÖéc$²•ä0ÏÞçŸÿWaéEûŽÃ. X¼ÆPy$©ïè}:Ϋ¼Ñ(˯ÉëÜäûóŸÒœò¤»‹Ç哯ó“œ~‚ª¼ƒ{JX°9,vþ\~h-‰$r îS†q”dävrzd h`»s|§p*r¦¤ÈcC÷ä w€ëÏ^0~‡¥0•:…ܦNÄÿ“î2¶ŒPN\ÏÝTÝFz‘ëJÙW*5,  `g?Ê¢c˜[;Lç¿ùþ”ÝûŽà 3ÿ×Ïõ¡\’T¿û€ÆS¸öëÇøQPÉfÈÞp8èh .u~xQ¸‚ÙwÄz“ëŽâ¦ß«òchaò†<`ó‘íøtïUDxü½Ãs‘µ‡Ë’=sÎ?úÔÉ(ŽÝ\n)å?„àÿJ†tص(ó!‚ðÆG9÷?Ó=ª|ðF?(çò>¸õâ¤yädÁå ôãŽ?.£ñlòtP |OCž@íùŽŸ¥®¢¶‚D[ÎÞr¹o›Ðõ\ô†C!O/vÍœ>F þèçøÔ‘’1œ’áþnÃãÐÌàPXù»œïË»n8õ#Ÿñ¡j+•ÙY œ4kÆÓóÓ¿8úc§¯²”‚Àmù¹É>ƒ=ÈúUƒv ͕ݼmÏ¡È9ϽA4‹ÎÙLî:¡â«N Ç½Ææ%W#< ØÏ®=ÿ‰&+œ0;zà‘œ {ÿQÛÔ;ÈTV $`wnSÁƒ<ô§Ü@Þ£(È{‰ô£VHá ˜»p9·?ž>oÄPåhb»”¶@äñì3øgëQ€±û°è¼€ü/9Çc޾¿ýgýÔ C6ãœnÊÿõóþzfšVPÁøè0G§aÀç ¤2à€wœu žzrxê*œS²"(Á˜`‚ ñ¨Áö<ô§,‰æïÚ¿0À¹ ÜŽ}qü© TÈèÜc'¹Ç|çüóQ´ò*c!”t1àsŒtõëÖ¡/òŒ1ŽpøÎ}sùÓÞœd/¨g 0·?™ÿõÑpŽâ,Ê<ÑŽdÉ##¨õϧ+¹¤O5c@>û‘’yÿJ¯¬ßÛÜÜÉml¬ã¦ Ù¸Ž„¶x¸öù¤&Ke4L Ä­ædd²àB ÿŸzÒ)F ÏÚFhgÔçÛŸ°®e8¥2óznpŒÜwÿ= k¢°Íº(ÆXŒç9'ê{{c½]Éi–¡´Žê,G2†#r¶I¡ǯ?†+*úÆ[Ev’=©¸aTtן¯¶=ërÂþÏìΦÜ<Áø`Ù ç=I=úZÔ‰-õ8 »Ý•f9;NpHì_SÒ­JÆmxná*Ê-´•‡¡õäþUBƒ.ÌFr99Çâ9½½y­-gM{+—\˜2±\äcàñü½ë ³ »OPyûûÓ!èY’¬wF½ŒãŸSGÚ€®bÊþyª«.Ò£rå±×ÿ<~´ñ&Ñò–ìFóÌöªdÒ0•R5Ü[§$œõã'¡¨¥]„©P;ä¶côùÀÃñÀ`þU‚A ‡—è)…Ø™V é gøcòõ¥'“€O\sŸÒ¤XÁ8PçýÓÈ÷éÏ?ç½F-ó‚Ý7 ޽ñøãü(ØVlC(R¼3!'‘Àõíþy¡áâ;•>Ǩôëšv˜¹ìzzçüõq²`Ä çïð .‚ÌoÚ7&Fî9 cðïÐPfé‚T‚xÛŸÿWOçOûÞ –%A%_‚28Ç^Ã=?„úSÒ͸*C8衈íÁÏCÿÖ¢ú‚‹+ä¸=:a?1ÿõç¥' ýÜg“Ï×·­[û3Èø*Å—#éÉÉéÛµ!·;רÈb¨9àtÏùÈ¥ÌW# HÜàîܸÁÍ1"v-´ƒ´08õ ‘n‘Œ’Fw“¸?åǽNºo€¯Œó–ÈãñÏëÇ~”¹®>Fb˜ËgæÝ‘“‚;}p=((B’@!F%Gùâ¶RË~7©òÎ>£¿·ëÞ¡’ÄÊ—gl}Ü€8üúÿ’s!—·$«áSv3èGó㸧Bä¿.GP¯½h h–U<‘¦Ò¬Ê›˜z`dqœ~g­Rš*T€FW8'éÓ×ÜÓ¹.-çÍRìª7g#=‡|ÇùÔd lޏuãü:Š™ãa´”UÏ?/¯ëMH‰Ý’0=®9ïÿת¹ Œü¡X¼¹4ó n;Šûp? ™ ,Ì_Q÷±_o§¥ lB3bBçf2@>ßçô¥q¨²°l±U*Žx§Qž™âž[jÇO$¨?‘ÿ8©Ä? `‹€pXd€~¤uÿëñH—à†/…ÚÀóÖ•Ñ\¥ucŽpÀcå\Œõý¿‘=:1œüêä0{AÒ¬Ç*ÀÞW,sÀúcÜR5»î!rr0C‘éÇ?þ¾Ý‚¸r²¬W0Û>ë =†?ýtô¼|’¿tÿrÓ¡©D|.ð­×qôúz{ûõ¦µ±† ʸ'p?JwšîËdn ¨Ã ÙÇùõ¨C¿~¯ úÿ*±ä4Û–0›PnÄ`ŸÿWnþ¿Š›}¥ˆþÏ#ù~^ôîM™YdÁaó¤®1Ó¿\ÿZPYÔ‘ó0=ÇçÿÖ©þÌvÅ‘Éüýiℇ.YˆÉ^=@ƒÔöéÅ++—¹*‹Ç ýúâ£h˜|óÓiã®j÷Ù ùo– žØ =ûtúÔ¿eËgj’HëótÆr{ý?3Sqò”â¶wp€¶á× ¸ zŒþ”UøâF Œá‘‘øqǯÿ¨¡Ý–•‹ v3˜‚Ãnlà㎆žÛbnI$`±Lcv8=‡ùéTå´^2@TåTüÃò§J<èƒ(d çGµBÔм¬£l‘ýã醞‡=°ÝýO^ÌâW “¸Ê€îN¼u÷ç¶`Y7°ó$b„®@9Çœzp8•/Ú3,¸¶@e{úŽ;ƒŸj[ yFÂÌxÀÈ'ƒüù¨L…q°´„vÉêϤkµN gŒ’]Âã<Æ}/qP k«*¸ÜAê1LS¸Y1þjÉ,aÎ[ C÷ŽÞ‡ó©‹gÌ`ÄgŒ£ž9èxïÓÒ©•$nòØ€ÛrÜôç¿o^Þôé%ÇÊFð£q8ÁÈöúŸéT@¬Là á·l'žÚ•Á·XY˜¯Ë½Föÿ&†ì†µe½EºÕ GjÄ㠿ݧ¯^HüûVÖš;²Hº3uÃîþYþ•¡5Ïü!ñD ˆùˆYWŽ8Éî:¨ãÿ­\¤ú“Ý]K$ìd ÅÀõc1éÉÿ V7rØÙ$‰®.SÊ(ýç“Û¡?§v'½dÍÏÞ屃ëÛ£;¬,÷Ì—oÛîŸÀsÈ5–fig%Ã+’ ¼ }:uâ´rdúÚÚ›¢ 2ÇÜAÆ1Çõêõ½« @ ‚¹$Nœúã¦zþMÑíçP‰$qÝÕ˜z)9üÆ+{S·2’`‰0ƒn^úu¬g+HÖ XØÐæ¶´Óns)9c³‚Þ3Œg¯·áŠâ¼IªµÖ¥2FÛ‘IRËòñ“ýsúUÛÙgH˜d"$ƒÎr;gž0âQË<1¥GyåÈè!\‡àŽüõç£îÞLsWÑðluŽÐŠäAÎ;ãõÁçèk¥×ì 2\“†d È<œäç=:ô5>“me¦ê?j{8°2À²Ž8猎þõŸâýz×[¼µ‚ÚÕmíQÌsÜÇמ8Ÿ½+‰i¢ ðFª4©µUéÎȈNø%¿zã¹÷Ä~*±ŽÆ`›Z&” J^žçÿ¯Y°Cii©©e_²!8gBÀîdþµkjWð_›¦ÿ‡ù±‚ÈùOò>õ7÷®]¬Š6f´3ír0 äIÆâ½xÈüjëøXiº9v‰>ÐΖoº QÆ9éß=+¦ð¼vÓE-œ™'Œ€ ÏN‡×¶Et7> òÈdEŽ(þe‰9È9©<óëô©æ“mݬxƧc$p›‰eV‘‰à7ƒŽ¸þ•f;ÊåˆçºôçÚ¯xŸW¸Õõk¹˜m…°5P€yÚ:k.5v Vaœ¤dcœ­vÅY+œr•Ý‘³¡jKá\e$È!<ã×·Óò=xhFé­Dð ÎÎ8êO~õç–Çç¼·AŽOÿ_ó­½—à; È`ÙÜqœsøŒûç"”‘¤ÎÿP³¦ž’É Å6ßõR Áúõî ñÆ+ƒ¼€Ã,‹å )<©ÈëŒ~uÐ GPtˆErñ}Ø$)ä/#§?Zdz ¼œý¢?1´Š¾àG½IÉ©zlknç2nƒ’Ò2OóïNXÙÑåSò)ãŽÄ~˜üñôìµ ¬&?/ „VÀaÜ çœôÿ Ç›K’Ý ¬{/ÌIõùHî8nÞ´Ô‰QF$¶Æ(Ë0U >lò:ñõÒ¥ûØžž™µîmŽ^ 7*’@ƒó•r›¤Ã@˜(ƘRÜÑö²…uòôêÏ~žÕfnüð£~vätïžÿ0éÏ8¨ÙÞ2‹±I AbÀöôôà¿ÅíRÍÄH P70#¨ùþ½…;ÛPØ®–ávDÄÈv¿‹''‘ëœñßÒ§‚H¶Sî>3ÆF9=9î(ŠEóÜJíÂ)èC~?äÒq•‘Ðð@í×> uõëKqØ~ö0ÞWÊÜíêsÜóøÓ&“~ÔP¬Ã޹¸=F?ȲFZ`£ ÷äŽ Ó¯'§gbÊB¬Kò˜¼8Çóý=¨nú€íP±† úyïëŠb¹Q ÃWnéŒð­ìI#ŠFx[vÓ±’z~?Ïެϣ$å¯ÊdoT’ÀrÊ=üÇÖÚ‹$BY6‘–èÀòÙã'ß¡ªW빤fG|úGZë›Â2ȼ^b3ùYø²I ƒ×Û'Þ¦¥á{‹ ÞBˆeÂ’å9On9ôê;O:zu­¹Ì=Š Ã0`¸럥fÑJHBPw;rúÜv?ÔVÅÜ hTO„x2Ë‚?w‚G¨Ÿí{ÕÚÓ ¨ÉÛÁ,FxQǦ;úûU¢+ýœÆª~]¯ÑÉ÷8÷ý %mÀc…Æ~m§ž3ü³ùS¥v%Ûµ‹c=ˆR3“ôÜzu§Zà[Ãæ›ƒ»X þ‡`A²& FÖCŽ>oÀÿ“žiÍ qÈm¡êGׯ·åNÞêÀ†û;» åó“ÇCþqHñ¢Üf6Ü]Nô?‡^)lX‘Á¾5SÎæÛÁÁwÜ–=û} Et>_¸Ï\“÷ž wôr÷1±qgÀ<{uûÇ>ÇÚž‘4be‘€ÎrHÁÇ÷üý©_PhŠÚ/;{?*2€cžƒÓ9Ö‘pð #H9 x>1ÓÝ?5 ±‚sÄ’À¿ÃÏ×üh!¸ÿR¹ nÜG§?ãO¢!HTn 8=1×ëíF6£ª¦Ütß‚½}Ç=éõ§«  ¨,O8?×µFª’4¯·i9<ç=sùΚµÁ‚`+`‡vaÎ8Àú±î$cÆ<B‚9~ðÿ#¥6&’wÈsò2€rùzuôî>¡euD?ïlp70:qÀð -qÎ<µ#yó n##°äd~Ñ¢+¶[vì1À=ÿzÿZ† 32˜<¬ ùŒûçŸNßZ± ¤H’db§ £§Qùv¡°HŠPÌ7. ‘”Uϯ=ò:ÑK2$rÅ”c'Ÿ¢ö…וòT· .HþŸçß´²\IeÁn ÉôÀçùÖyœ°$íçŽ~ñÏzS0$CdIÇ?çò¢ÁÎ_39¸çp=>¹ü»})ZQ.⑳m\ü¤•ú“ž¨¬÷”…êYza°sךiË ³&~ðÊ’G×8¢Ãç.¬ÛFÒ±8ïÛüi’`DARÃvF}¯µVóU¯÷HäÇôþtá"ìÚà–\îô>çüö¡"yï¹+Ì<­ÐÄóéïþy÷¤2Cm`Ùrr{ŸçPÖ8w?LgüOãÚ“©eq$®a5”ËlŒ"ó#™XGpä¬p>¼þUÛ[i3Ç`$dF™ùœœIÎ; Ž€vëžpjÛhqéñ¶ÎVhŽIîÚ ‰ì1ß×ðÒµÓd¹Ó|ÛùZuù¶.1•Áà’9韩®ohå¥Í’<÷Y`òÀÞ¥ÎÐ8<óרžx§hVIu+ƒ‰° pAØñ“ô5PõÇ0Fñ«‘ª±÷ýN¿J’ÎÖîÞФA„ÎÁr¥‰<Œûñ×~µízÜ«} ú”W,cxí­Û Á~ñÇÍÛ#·¨ü*”:bé6ßlþêmÑbHr@''ƒŠô}wO‹KðÜzh„ ™âóÁÁUc‘“ÁÉöõ5Ã]½Ó@ºvó, '±`HÈ‚Gþ½B|×HWº/^èáì¬ïaLB0¤ò½1Çaž™÷¬½-c³ÖVÞGŒ-ÁÀ2œ(#¨$’sÛò«ë Õ›B°£$‚0pyç_Ö–çJc§5ÙËì¾n@ Œ‘’zg'œŒÛ4EèÆÎÊ/Jöb8X«Ã4r¤¹ùY‡8üNOP3Œ×K¬A}¦CÜÊÍç(O0•^„’xp:`œ©ª~Ö/˜–·Ä0òCG½½uóôbI9y˜ö~ŸUÔ#·†"|Ç ÷@î~œþB‹½7þ&óX!. êÁNÑŽ¹9ëíÚ½'Eðëèú¼Í£´‹ó°^zò9Á?¡î2ñ7C]L»»`ZyæØ>Hp1Ær?ïž5÷/DÏ0Ó59 ¿p²™v3²ƒXg·Óòöç©‚äÁI Ь™Ã6ÝÀϧsþ}yÈÒÖ+GŽ;?Þ3l2³“»¯ }sŸóÉÐðŸˆSEÖ<»Ë/:7&0ePáI㑟óß­k~ÂÛs^ÏÆïÒ[]BdFfÜŠy´ƒ“žùöí]$÷úN¯f‘Eå¬À±HÎT“Ô‘Øç¯ñcã­`xâæÄ\)²XVLrÄ ‡à‘ŒéøÇŸ³×™<¸äÝ€n ¥I‘êz ïÏ­JM\7'»³hYÑdYlb'ܽ2OoJ®-˜F¬<Ää—ë’ÝÎ#è9éï]â~Å/™ü¥ ìTe8år ïïé\ûD«rbÚB¨V Äsœã¯éÏ<>kè4:9|³Ëì”À…<ò0AÇÐÿúÅBÅC¡,ÝTnóœϰç¾iJ!V`wòðsÇLõ>¤÷ïÔSÙKE÷ÛvK¸ðIì:ÇoÄrij´†„òÔ°FÝÇzôäzsíß41˜³02g.g>»ãrଌªNÒÙlvúsß¿>• ¸¹ž%^pÛò ÷ïß·>”^ÊÃØ²L@‰’K)ÏÐ ãŸþ·JŽW@$¸ÜÃï.@<óoדÀí=͸™ZuÙ³P!Oàr?Z¡,¢@€•.vƒ“ø~g#×Þ•ú ’)Õ]– rr rq@ÏÓõõQ‘X"EÌpù À¶;ñúÔ°û¥Yxݹ /QÏ<××ùVLó³JÌßêÏ IëNµI\‰;ŸÚ¦áâG mqц@Ï~µ æ¬×H¨GÊAìÀãpò?§ãY¾`B¡zpLš|>`b[€?O×9ªåF<펚[‰ã1ÊU8 • } ã˵_OÉ ñ¼‰¶h°VH”g\ý(`”x°Ï?þª~Fq d®0p/ñ© y1øöÏn½êÎTŠž^{ëNEù~P;§=úõa•öîdòÉŒ[ÜcéŽh` 9lŸ^¤ò3ßëþ{b‰·¨,êF1޽ÿ_ÿU65,åƒßñç¯áSí vº”ÆA9î,tô© ‹31*¡·†“ë“Óð ,W(BާqÜúgéGK0 Gl ý¿¯øÌ¹.ŒncþçÖ²žpÌÄqƒ–íÏõë@ìWòÔ®;ŽI ã©?_ZxŒä†\Ë`ôÿ­Û°õ«*©þ&'>ÿ•+/”ÊÌ…rÆ0}Góâ–Áa©Wh,»FAqëÁÏ5džÚO–zg·¯ùúÓü‘Èw’˼rOó¥Ê¶#Æ'p$sÒŽŽ4 D|ôÊÇ·ùft'fâÊG;y9Áì:þžù¨#Y;˜ «g°=G·®*ý—™‰©‘Ñ”l!¾‡9ýjššÅ\I [Û41Û™9'hääŸûë·ó¨¬õ¼æ’I#§8ONÞüÓîíæ1Û0…ä’pÍ€¥˜àñŸóßÖº¯h’Y­½ÜÑbs±á¿9ôã•ì®iÔ‚ë@:}õ­”RÅ<ØÌ»åSŽŸ{žÙúŽ+¨MõE‚ß”D”3 !¹Î9ü1ÏZØÐl¢²’ëRÔU¥¿¶À‹6óüL28 Ž+CÃ~º¿½…•ÄM)1œmN¥¶€üùõ¬sú Ï–$z†œ5««;—dxDdd` n9=G{ÔõËñ­·‡¤eªw9gv9%Ny\sÇ@G¶Õ®ì´+ °´Jìç÷Pcyn26Tå²xçÔÖw†ü&ú¦­&¯}Õ1ñdçªúþ>¾æ‰ûÎÖ3ƒåWeMÁbY>×|X ,T0ó»;NÑ€óUµÝ[‹Å³Ùötd(3µF 2óÏ'ÎwW×V: ³G"½Ëܰ¤ »63È㟘à`ãù×}FÂK¹š5ŹÏï_œ÷#©íÏoZ¨ÓV»%ÔwØÂÓ>Cq±°™F åò»X‘ÊúØúŒŽ ohþ>ÕÑ:……FÒkî¤ôÁÏá€.µñÞ¦[\ÃlâkÌõhƒœ`çº9œžk¸ñ–­4ï§ÙA Õ.‘çVi#µQ€x ¸ç§\‹åŠ÷ȼޅ‰òÚè:|ìÒ/Ûç=¨A ¿@qÐãŽëÏN<‡K”j:ªP|À©È dç½løÚÆöïY‚ä2¼lTÌC–¸½³Ô¸—@Ò¦K°$Ée]¤ÈŒÆ#޽ÏjI(£ª*ËS§Ô´9m´ vÄ2o>fæ2&3‡ûǃÈã9­3KÝmmnÃ÷÷YfF\äÑžùÎr/i6â»h¶yUòI!Ôlñ×§QÇ‚»¦ðl–š[Μ|îÍa2sósÔäž1ÎOµd¢Û²ØÊS²ZêKáŸEqႦ?5–/nÀv°Êƒ“Ï<Ðg§'Æï|ý¥¨y¶²ü†R’ùluÏq×püýz{†—4Ö¾Ž„Ø‘¶I|!‡_U¨ü qzeܺ%ãÞ42Oi!Ü0»J :öàqŒzs¿"…•ìc KV=ñ—uáPÅ=™s#+‚ÛpNÒOÍןL梱º·ñ0V¯ö‚ FWÔçà¦Ú½ñJ?´_ÇuIÄm÷ÒL’@^WÔƒÓ½yœZ½Î—âÔ-¥t‘Y «¼pOÌÁ ¹ctm¤ ŒãdŒ~]…DcИ«Ýžƒ§ø ÒÚÂâêå„1®v’› …‚zõì@ï×Ã5ùQuÛ†¶p«¬ŠÙ) Ïôã·5é^/ø†ú–†¾B¬iqçrs“°3ž¼v=«ÉÑK¢J†%ú''>½¯Öµ¦¬)srêjiöÆÿ;ÙžUù˜9õöééÇJ³y¤ÊÖÐ?–ñùyÊrÊåÎ Ç'qéÓ[ÚfŠ-ÒÛgß $@ò™’‡_Oq½a¦‰¦!QÖŠË©dIôêO=qIÊÎæ©+Xʱ†a ü©3Á>\ d“Á=ÏZ;xÂ,b"›’r <“Èç>üv®§[³m`‡|ü óO.qÏÒ¹;Ûsk6K•ÈC=OõïJ:«r¢¯˜Ä»µ°Á°Ã·<:ž¿ˆ’\€Xp ?Ä09Ç<~µ`¨òó7Ë"ÅwcŸ–* Á¸û!]Ãh-ÈÈðäàúf§™=‹±L>âÌÊ_”dgœûúôúQ‹©X¬*èB óÏÒ¤˜,y•Ãï ²¦Ð¤qœtÏ@=E;KÓÚbÒ܆aó¹Wœ àþE>—°Y¿ÉW’bܶÀ}xö®BÐãMçU¾·$E’0ÎH,Tç¿'uÏûC44ÙaŽ{µŒË òYWÉÆçÛ üG®k¸ñ%²­ðu½ºÅþ”’Ë;^L–9]¼®Ù=f$–ã–­Fšr’±å÷aå–RÌCH¥ö°ù¹=§ÿZ²áµ$6y8åƒt'éþ{vÖ¥ï.6ì*dc‘^ÜóU´ïÞù€W Î2G~¹çÿ­ŠìŒ¬ˆ”/o™›¦Éuq€ œ+1ö#ž~µÔê‡Kðúji1žãpC«d€;ƒœ÷çÅfÊ$ŠÎY#“å.Tä ·ùëžµÙÛ[Ãiðõ–öhæ¸Ô(XÙ¡Ú3ó‚r £-Ç46Û"Ê; „…§[˜Ô¤|ªû窞££t#¯ ®²ÆØ^C²Vß €33Æxxïsצsé\Ï… …¯¢ŠWužhûƒâ™ùBœ`Ïøúæ‡m.¼â)ŒñMq¤¢ßA)GÁR) À{c95çÆºÚ[­Š­KÚ+Å_Ä…Wú~“1¶·”y²)‰‘S;IŽ;ž àäz\5ŸÄëGMŸGñäwWâÔ,u[{sö¨7gËŠu÷‹‚‡p°ƒ‰Í}Ï¥i–þ+¶·½šîÚâØ”Es +ÇŠ0[øGÌ2¤}>gøÙð°i^#7ØÀènVÉ[lŒW;ÑŽ7n,G ÷ˆÎ4AÅhÎ(Ô»å–çÌ>"ðÚA©¼ºd‹qñ¼N¬$ž2NzxúžkwÂ~+°±º[{ý&Ýîd\¥w·pIã,1Ç'ƒ‚sÓ5>©¤Íá¿>Ÿ¨ÉçÙÌVå@+†Q´¡é€Xdãhäõ5õOMsa!VŠK‹S½Š‰¶8àguànÆA=Í­3}±×Or·ìilð˜w*3 7)à•;¹Ç±œòy®bûB±a[«‹F~Ö{FeÏå`Ä qÉüz«áÛÝc×kgÇ›¨%Ko5š>q‚·Ô]›Ù¯‹me¹··ŠÚx†Û˜!VP_=z“Î<}ßjväÒä[‘œ©à=SN40ÅsÈ&·”s½G9’ÇbHæ&FŠ@’ÄÞbýäÚwèGåÏøW¥ýªûÃ^M…ßä¸2DÆ<gk@ç9?’uó8ç ÆqÓÞ•ÿzG'aù—'èÓ#×õª¹6 hÙÁ- ;Àfà±Æ8î=zäsÇi¼ž³'q 7ŽøüG_Zcp,Äd#nI d§©ïÏ4ô3$®>R~]ÅO?/$çßž9ïU£"ÖbJO(©ÏúÉ09à _×¥D­ÝàpTärr:öìãÏJ}Ä€DcF( ‚¼—§Õ—+>æW^8w ß^€dŒ¨ªÊ®WŸ”! õëÇ#8ÿëú”ÈåUœócæØùsÜ´TÙå¸aœw a‚0ã™ÈéÎ?¯­);ñ½rG<6GZk 8?(çGltlr¢|ˆ0Ï=?¯åMyÚø 7 ™0sÛú ]À˜'ǵ?º:³ëÿëý(â…Vb1ŒôÏ\þ´É&£WS¡F8õÁý:М‚ÝõéKó~í†Pót'ŽÞ´ºçr0 ³¹Îxü?:l{UÏUaò©^9ôÿ=ªY¼j퀫´íä_ΣeU‘¸ŒFq×Ó¯Ö˜1á¼Ç@¨aòì: ~´Éee`¹ê~eùy=;äçCÎÈU‚ÈažG'òýiÊø‘$CþéÈ=½súZ¡qc–T<Œ óêô˜WI þFà;ñþ{R†ÚØR†Üqùþ4@]ÛkŒ¤  }ÓßRÊÜÒ¶Ó¤h%‘Ø;F„`7ï·üö¨¬.ÞËOš_Þ<Îà&ðOËœ/×Öh6\i3 u2ã!KàŸ»ÓŽN[¦GQÏßP–ÆÚÅÀÄ‚{½¹ïíŽhjš‹ßJ¨ÒM²1•PøéÆsÛ·8ôQ¤mmÑ·go¦[Ù©‡Ï»MB誻ÌÅ]à ôãëšO|V] E§éÈ’–Úv7nõß´õèGÿ¬D†ÂÁ¼Ëö¶M¸ eìAöÇ=* Ã7:¹šK7 ŒHäg`uõÇ>ß…TUÛ*êiCã[‹I¦k‹§»¸b<ƕ˕ààžœ÷ééT_Äú†¦&²¶Ê«Œ’Ù ýzÿõ«S\𵞖OÚg<Xç<Œzþ••—%òÉå¢[FTî‘7oä`rç“r+K(±«4kÐØÜ$vçÌ`Ø.FíìŽHÆzþ#ƒ·à[XÂ÷Ww3C±| G“•Q‘´“¸ƒ’¿QÓœWC¢Çm$W1ÆrÄ1㎜Ï8÷'­iÁã#s{ ¾åŽõH¡•N ð=ò:sž:ÒZ QæZ(ðÕÍÞ­§‰åV$<²&pO å‚>¹ã“§¥h]x}ôˆí¯dm­¦‰W“Îâ8ÉôàŠµ¡Å²úÊKÆß-Ør¿4kÂý23×õ«+ÕΧ|¡”X؉DÆð¥¾`èAëÖ“ZsóKšÈÜÐ5_ ØZj%¶Ç/˜®Š«ÀŒvíHÏaW¼Cñ9n­¦2©Ë³aIGBî¹Ü1ùc /Ÿjú¬—¾ \´vñÊ»Þ5fØŒA‡œ«qœõ¯<ÄóÌÒ2C…;‰bTõëëÇ~N)Jn1²4…7vwš¿´G¹Ž&ÏúÐ@ÉÜ=Aç?†+´Òôí?‡vîÐ7Ú£*ª$fdrzcŸcÚ¼V¸Õ%¶2¥œ}ö,¡nzCqê{ ×½x>Þ]CG6è¼-™%•¶FFy8ü} qÕ«ËnceG¢<+UÍÝÏÙ–Tó£`»O¯¶zú×/âo Þ[Äfû/”%\¨TppsÀãþ"½ÇÂ? îþ#üKžÚÎÞRˆÉ  r¢÷Û׌ׯü[ýš›CÒVó¦ÚTGò©gr Á8þY=«‹„g#®4tw>Lð·ŠLZ+YÞtÙË,«»îç#qÇýÐWâ6Sqå#‰1€Ÿˆ9Åjê éwbÊ£cBçw8È#Ô(ÁϦ r—·ŒîX««6H-@ö:¸êCÞÕRJ¸ñw$–élÄù,8Cœ õô8éõ©o´á§Ý¬…³¨¯AÔpqì1Ÿö«>Y„§(¬Ã«2/Äþu³¼jZd6ÿ3M®:/TôiŽ>òhÝðΰ–÷ w?“>KGŽŒÀÆ}9üN:×$‹ raˆ°`ÀíÀH8jò† ¦$ Ws/ñž2'gž{ 'ÄeÒîÚ5V±Ï# tü2Ï1-u‰µÍQµ ¿j @|”UÈ ˜ÇCžr=)¶¾ºÖL—BÙÆ´’Ýà{c$cçÒ™àm&÷Åzôv¢”®o¯eÀKxƒ©bIíN2OÖ½’KKQ¶ðÕµš¥œ!dšv#sFŒ~ñBäsØgœ×4æá¡-¤ôSØqßÒµ›÷XìSÓ×Ìžù@ M ]Aùy‘ïòŸÊ½3XsàyP>Ë+p|¡UWŒ8Ç^8ϩϦY²x’X%ŽSÒ…Îܨ*rNqÓ=Ϩ®ëH‚}WÂî +tDÀIJe\ß‘ótñלWŸ^¥š5Q<ªÎ)fyÄxaóùdŒœîã?†GàjŽC0W.Ìç¿P{Œ‚+©ðÞœ÷ RK¼€œ2rÇ߻ֱ"Œ[jr5B#¡¸#¯“ïùvæ»c+¶KŽÅËX#¼ðíÂ>幎Y2©…àŽ=ÉäÕ¡%½·…%‚@“Ï#,‘3`¼x¡í‘Øâ®hÇm6± î’?”ò(à‚Ň`@*Ccžqè'®+U+œÒÑêsÒö§ï ʆaO£p{d{qšúçC»ñVl²yvšÅŒ‘‹hn”Æ]#R<–,ܱFÐ×…øcN“IÕá·0 ˜ÝÕðà“œ¬}û{ŸÀWÓú]—öŭލ’[³Hq¸#ÌÒFG~q•ï‘‹²šiõ9jÉŦŒíÆ×Qð×ËEy l’)Wç Ü9ïŒgœëÏLÚ›:£¥i:Œ&yqgpKÑ\! rrrCÛÖ¸ªáãz£HVÓÈô¯1®“m¬é7R¡3@ ™–]ÑÃ(fá3À,X7Ê9ÃrzWcã?¯Ž´Ç²¼Ž8u !o ˆUYg^våÚ àc$18Ç>Ko¯Aám_û H|ÿ=‚A.ГDÁ‹eH'Ÿ›p׊õÝ3\¹ñf•>³k(P²»y%†PX «¸¸'Àñ»¨ªr±ÇU¶ùÏ„<_¤Ü^MªègM'QÒ ÷VÛ'hÁAÏÍ„ã<98ÅIàɬõRkx|³Z‘$@±VR0Ý>ïC^×ûFx%´ßAã]&eCu$ójV%0Yf8~p0ªL{Iã‰Ço™òOøÇÌ·F† ¤FMŒUHÜaŽrA8篭wFÎ×[EóÇBiSXk¬ÿ¥ÛÞ•iÖ=ªa ÀüØê:u…®›Aºû&£(#–+Ä"fUË,IÎ6Ž:Ž ®’çÃñkúRj­, ÀÛÍ´ªÞSºÑW>`f'=ð:f¼ëNÖŸIÕ#†'Ê%Ä…·°^sŽ„“ƒÓ¸ëɢܺ4hýôhx³EYZóK7m3²[JÒä ߤãŽOaÐ}k™—VÚ_M1ý—jý¤eJí$a—<N1Ó¾y­IõH®ü/§k 5»ÆdIc,¢«²Ç»nNŸÔg›ñ> º…Ük’ï Rý2@=G¡Áç98´FÖ* ìÌMüñÜCû¼³€¸mütž8{äÖ$p<'eŒ¨$ùj½©5rfÝ0 V(Çp¯©ãŸ­A=ËMµ¸wÆÕè:ð„ìv(éb”À)>[XgŽ#$NçÛ4–²cS± €’/ÍÐO=08ÿëÓæ‘%A€ÐçoîÀQ€ ÿ—ä8î‘“µ‰mŒã tõÆx÷ÁéZÜ–F°µà‡cùFF d|¨è:°ç׿¯½1äFŠ&÷2ùM¸Ççžž½Ç~µ+±HEE@.î#ëêN×ÔWnãj3PW=2¼œž½ˆ…]ûÉäd7“Ê((Qž§üõ©1pç8 H9çç=?Ù¨˜¬Aã+·!ˆè¸éÓ­9äªxÚ¾ óø}*ŒÈD†IT’Àþ *d$ížr22?¡¢Ÿ,¥ª'b¶™þ÷)éú~Š«îQ„Oã¶qß§¯JP¢l?ESœ‚Üúœÿ*7&àŽs’28öÏ_éT`(ue\ 1ãon?ÄŸOÒ†8%øHÚAÇn¿Cøç¥! ³mlg³ƒéŒçŽ>½(Œ´líÜ|Û”å@=HÎÞAö8°¤!Êœ€Xäò0@ÇëB,r ÷àdž¿ýzFEÝË18ÀÜqôúô (;pxî럥9Ý™‰$’Ä·Í×'ùÿŸJ€Jw‚Ÿä=¸{Ž¥?8åGAŒcÇzRCÙ.z°G8ÿNXãŸzÑÐÞC~‰(w ÏŒž½¸?…hýÔgÊGm­œl²*ÓF»¤1`ñƶ-|!u=¯qvŠÃ~\ä®\gùn®yá? Ûj71³ê7¨$Z6-àò$œzW™ø’_j æÜ¼ƒÆ8ô8¿úõÇÏ퇢¨òFû²ö£¦ÅªÌa¶¹3ÈÍŒ+rO¸5¯áE Á:ÌùoÜzñÛÛšã<;§\Þºùn‚éNí®ÄgsëV|O¨Ü‰±;"ÌŸÆ‹÷±îzÏ±íÆ©t9¥ÍûÏé·×øÁn[@  ð=½s“šµ«êÚbZÂð4“–Æ¢eŒƒÕ}Aëž y‚^¢Ü¬ûL’ƒÆt:>©azòÉxÍØ—oÊÃÓ+Î_oqTãdf­su|íVºB˜Á# OðŽà & ;Hµ‚‹#ÌP›É%²XÉçŸ_ÈP—$w;)ÕjþþòÞÜKyâ @®  »K)#hrGR3ÆHúšú ~ËúV—dÖ$òèöL I:‘óÎz¶Onü{ó^µ§m"ˆÃ r‡Çó#ŠÆñoŒ!Ð-mÝçoœd+rÏÁ9ü0^+È•IÕw{ÿH9ª)Z:#À¼'ðÆÞht¸3qpAšâGr\©m¿+1Æ7ø ðßÛ^ÏÄ^ðTÚÖ¨[ØØ"¦óÙJ|ä ¹Á#;JŒpKGC\ŸÆ?ÚÖ_êÂ;L¬HqQåcnI^;œW™kŸ¶uï‹í[E׬"‚ÎPOœrÅ|ÜeKÎçœb¶ŽªjoësHÏ•êî†üC®K¯^µÛ—“© Ë‚Ù9ù°I'Ðsš§ykØ®ËÆš‡X·ŽH‹¤JH~u]Í´g'OB8^=+‹ñÉmkv‘KºßÌ?¼Àþ 1¸ž}¹öö®ˆ½QÛxÜóûÇC<’¬.K`Ø`ûgÒ­ÚÄ­woÂJ1¶?ZϹØIpUîFp=3ÿê©!½Ä©/”Ó(?2ÂrÝ89ÿëïjëC4ÎýYl.m/|Ä’îV1™ä¡ÈÁ8cŠï„ã®§Â>/Oø©eÊý›T`]¹eeÎrx-‘““Ôdõù…y&§© ï›ÄX·À6K·!I`p Æ@{Ð㡪뎚Àµ¸Xî,îžÍ\üè9é’Hä8 pN^ö»NÑÐú⦚æt—vÓÅshÁí’Sµ¼¹ã€;«覾-ø™d4Ûí±æá¸UÚ:»0{u ÉãÞ½ßOñBßipÉËH²D2ò6ÆGŒq¼ôÍx¯Ä Ú´Z‘fÆP6ù/ËŽ?ºgžy'*¼íE…:|­š¾ñœGD’Â;u–u²yö;)W~\‡ŽÃùsÞµÕ›ÚÛ[2Â$H Dj«ÐqÆÍôéÎ*Æáa{¥éWq@Z5nfAåù„Éç0‡§\ú޾ê¾ðÍ­þ‘mö[i-¡¹iöíeW*\`ò1Î;ö'iÑËNU¹^ì%êp?d‘<|¸2Çms”œªÆYŠç?6ÜŒñÆ éç—5ÍÌrܸe<´ pp= î9jôßµ¤ñ­«Yý²T³ó”cÌÃ)‘²ê2=¾àÎÑ^U#ŠRL[pÀº¯÷O<àØÎ=ºUSkâ±™g’g·“ç—’êAÜ:qɨ¨™Ùؤ‘($å†ÔP¤t>¿–j §¾Ú¤‚Çß“Û8Î=é«v Œ»×‚fRAüÿZÕ+ åÄ61U‚›F|Ÿ~§§¨ö¨Ly|€¸äóœg¦?Ï/ñˆÊ³ #!àuàc¹ãÿ×PIrÅwmQÇ'žØìz‘UÄÚ¬ñ«$a”¶B–l<Ï^޽ǩgp¹1°s’€ÇÛ¿OéP­ì±³2»WøAGáúzT3Ý9pÇ$çþ=‡½kf`ä…ž7ˆ+1 ùÜç¿^p?ÝÍDY› ³u=ºòp*&”ȘQÔð¥²ü 7Í&\“¹³Aã=x÷æ´HårDÓP8$¥†zçëÛ4U1þö@ã‘õ¢¬O:%pÊTKƒÈ'ùõé®­æÜã°SúQhÈ^UF Å7ÈÃU ¡ÜÊHÆq™˜÷·=YT9ažzòiQ–Gã, ÈÏëJ®ÄxÎ@Ï\uþ´Íªí…lç8È¿—õ cŽ@VÉÏ~pOãÿ×Í"3Îsœ€zóOWÚÇ#¼~yý Fƒpà$äœãêA@’4YX„Æ$uÿÎ…™y8 3è;zc rs2ÊèùÞŒÝëß§Ïêk·ðƒÇ§Â“1"㓵†Að;@þµÌjÖp¶©x°2ùP¾ÒAè03ùg‡½c®Î‰'c&Þ=×<¾ÜÜŸNß…vÿ ´Ö½ñž…dÊ$Yµ£hÈ ²ÃåÁõãùW*›y>VÎuÀéü«µøU¬­‡<=pä“ünÜx!‡l}iVºƒh¼?/:OsïoŠ^SਮµÄP¤.ЀúÕã·? uëÿ K7ö|O$ª»2íQž öô¯®µIãñ?†ü; @<—ÆOx•Sߜևƹcðç„þɸ‰¼’7ƒœ‚§Œ~uäss´ÖÈ÷­d—V~hê¾>šYoTùѸˆ† û~]½+Š×d·»¶g ‰[àd1öÏùë_EMðÎç^óï®ʳMµÀÀؽI<óÓ§Ö¼ÏÅ&±ÕÚÑöæW]áFIÈõôþ^ÕÔªFæ9çM¶ùOšÑ¬ÙYÓï îb3þyÍX±°{µb>nåÔdnÆ1שé^‡{ðÖâÅÞ+›)#žIÀbOÐ|~¼Õ ? I Ä{£2+#•äsòœänÏùk¥W‹Z3ÏTZw!Ñôû¯9a‘"ø18ÁaòœñÛ¯~¿Jô φz”ú]¨[t˜8Cå3Žýþ¿ýjô/†ß ïa–Îâ{É5Æ7nÚ@Îyçù¯¤~þÅr´¶÷:å¼n˜Ò«°8NpA#=+ìí¶ZbÛˆ­‘6çi¿CŒŸA[ÆßÉ /–@û¥Gÿž+Ç«Œ«5îè‹•HAÚ'ŸxoÂ:_4•²µ²·pQ@ƒË` ­¯ÞM§ÌÓËrR ¤²+ONÙõíùúúäp­»¬‘‰ƒ|„t-Ûòçõô®Äú®¸óJÌihÔOEϧ?ã^t[nÇE)ójÏŸ>(|o¾Ó®.dðó\ÂÛK2L¼Œgp6ù@LׂøƒãG¼dÒÁ©Ar‹ XÙ”àHÃæÏß¹Ï^1Ç5õö«ñïág„î ‹R²1Þ)ù7[ÈÙ‘$„)ÜsÛ =øä|Kû`ü#¼¼ÙÚ<·ó²d’Ù훜0ê¹Á ŸÏ#"½Ú3oÝ3’¢»»>ñw‡üO}usy,2ÜDlnÃòŽPr1ž8= yŽ¥5àyã‘C)`¸q×Ðã>™÷¯¼¼cûZxwÄVÂů­|3lùÛ’×H`Ùûr¹ÇPÚ¾Xñ{h÷þ!’ö×U…‹ªÈ×>K!)´díḾ¸Èí^¼e8%Ζ«úþ´›´Yä²\ÝOu[©F@c’8àþqüëØ¾ßÉ{â¨ì¯Ù¤ªgåcßw9+ wQ+j‚òÝCç$‚Ƕ;çðþYѧ){Æî:3ÅîÌÑ\é$²Y„LÜ+ 3ØncÔ¼õÔOlm|8¶NÈaqû;a•€Æy‘Áìz`ñÆ ë±Üx#E|h·R]ÀK’®HÛϳ“ZúüÑKáÝ:ÚÖUß Â¨w|¦>>œã?îúù9·«ìzp:±O\²“[ÓÅóÄŠ€ ÁëÓÔ6sÏä×øª9eÒ&•“Õ01qÐŒôçØ×ÒZw†d¼ðäð¾é0¢N3ÿêæ¼CÅšeƳŰ›A_›éÓÖµÃÕNg\©¸ÆÇŒ–šæB„FdÆ 78ãŽúóëÄ0Þýœ)?êIÀÉcžzåZ· çU'ƒ´ôéÿ׬€‚á%ØeXm“iã¿#ükßM5©Àî¶Üè¼=v#–Ymx|±@ÌÀÈÙÎúc¹ÏL÷ðM-Ý;¡h»uX\3+op{7¯­x½£IeòÔÖ”ÔÕ¥£>…ƒK_xBv©[Äóbá¹úrü}+Šø•áioÚÅî•|÷0ꎘ A'ØW£| xF®<7­Ê"´ÔÉk)™så>2åäçÔ‘]oćZ^;5¸•­&ÇP>CŽzþ•ãS|¯š"såŸ$˜xF6êÚÖ Hç› ç@©½;œñŸêi,®"[È,.¤Xã’8­žo,ìAôÇ8ë½FΧ¢\jÉ-†ô¸†à9# #ÔT¬Éâ85 i#6‚&[{Öê«!eýæ=I=Aø×¡Ì”£ÿ Dý×fkG}"ÃHðHÇ£™Œà7¨vƒŒçƒ°5(o4{7P½k¨.á1 ÃçTelž™Êî,½¹àc"¹ß oÔ-ÊöFKûxœˆoIá.܇UoF®:kšF¯¦³Ý[í»Òâ5QB«Z`Ž­Îñ_^㧪§Ì”–Ÿ×äy® šÂëšWö}ܶwÀ\¼ †â& r2v²©Î:W™ÙxŽóÁ^%’âÊG™‘wÉñ+L6ðC—-À$G8€®ïH¿Óüqqi jw0éz–ù$²žmÎpdQÜ(=ñ“ݰañV‘>’ðÙøâ9ôÍWÍ­ìl$ŽáXaFcà„Žã¨ççv×õýl\W&ŒÇñ êhÚÒêö°#[]å&µŠ?ÝJÊG …è§$õ'ƒ’sI_NûdrY˜n`ÜAµhX²à6TŒ nQÔr}«’#¿Ñݼ› ”VK|`ÆÈÇs†ýâ:ŸR:ŠâI޳#:³ÉQ×wß ðsõ{lÏzÊp±×OkF„×–¡ HˆÑßF%³¸–BWz¬ªÇžrîk’Öæ‘õ`y÷ÍF»•ƒ€üDrs×½Y“P¼–ÆÜ›Ó-ÞŸ1f”CóȼÙè:¯ËÏLzÕÇšÌ×öw?èwq­Ä`.9ùÏýõÆÜuqY$”Ó4‚z¦w~Ñç‡ÁwR%šÁÚäAùYB/=AèHö²}ÇÅz­¾¥ð²×Jº³GÔ಴bu#&3üpAUç¿ä<ÃàÊ rÖÎÚêu…g‡Êga÷Žìã8?ÅÛŠèñ·•+X žÞæ¾l°œÈgÝ»Ëà©R¤žHüqëüëì/<'ÁÿßlòüÖ‚C‘¹‚Žz— ϹôøÖÖfãdÂ6ÿᜑŽÝ+jvmõ5ƒænDRÝ£yãäÈP=±é×ú{ÕI.†}®§=1þ}ê ™ÄyaÊç÷ëüª& ʬØxë×ë^„cc:•[ؘϗ‚@ íëßô¡å‘s¸ã#pÀéÇZª²© óÈŸÿP¥B¥†Ð7asÏLÕò£ŸÚ1í&H_º8õäzŸÇùÒ®YŒ·Ÿ‡>ü}j‹ËeqóÛ¥)Ã6`2 uªµˆæb³ä²±û½p¹ÿ?ZP>\·ø²r;ÿZ<£¨PíÆÝؤX~l>DŸwnz­ÜS£}àqùþ‘L??ÊWqo¦(ª¸‰Ü’¾`'ÐwüÿÈ¥y|»~ñrG×Ò˜ªÁá'<ŸÃRF>lvÁ³ >•1é#IàtÏëÓñ¨Øo$0XŒÿ“þzSAA€zdÀ?Aÿëý)Çæ·Ÿ›9>¿çÞžûǼJyÀÀéëéþE5J—m½óéëMjàáœqœã>øüÿ?­ &OÎàòiqè[~yÏ9 t ¿–ã´õÇðëMP œ¡#‚q‘íïJ3œîÛ>¼öÿö>„ãüŠ]»²O¹Ç_©þU0y?Ž9ôïþzR³d;(#§N™ÇåŸJ7ÅÀnbFsò3ǯáštá<áGJnÐSç®õÁÍI3K“Ôu'’i jÎ’çRÛij!góèσœþ#ô¬÷¸kx™LˆÒ?úÒ#üõ§[Ù³Z4¬—¸÷ÎqÎïúSb¸ŠWòäSµP…ôõãüþ5‰×ÐÍ›÷á™›È+þ{Ri·Ù^Áwl>xdRà©?LÓï'ÞDQˆHùN¿ç¥wVŸaqá”…d.ä6{|£¾=•T¥eª3Œo+®‡é7ìñâx¼uð¯Â:ÔŽ%—“m; ‚±FX|¶kÒ>8xJoˆWö6‘ÇÿùNÙÉS–R1€G¿zøËþ ûñÇAÕõŸ‡¼ÊñjS}²É¸óv…`8ôE= ýÓ¯çÓa6ú„“G ³`8aÛ'Šù×zSq“=þ~hÆktr%øKa x2=;Mµh@BäòÇq^ÄŽqÇõÁ„>¼Òf{¨š}HLó §<`géГڽÓC¼·Õô†@‹,X(T°ñÈüy®r? 꺢"[ÙÊ2*¹QŸ›=Ny=¿„ûVµ%AIêyÞÖj.ìÏø«ðCC²ÐYi»-Á+¾ÚfÌ`ãæÿ>þ•ãZ‡ÀM"úMAFŠHšNY}3ŒrFF}«êOÞ˜"º]÷ ¤e"FÁû ‘´d€=Î{×§>¥§Æd”Nñ ùþ_–3ó`Ý~¼ôíÐù’ªéÉÙïý_ðÇU¾Us…ð„¶z%šióAó( ‚p/$údàôíÁÝðóÅQe—Ì`¯&T…ã !O¨á²p9#§.F2ܪ•hrGÍ·<ç¾OA’zÖï…^K⑦@À/¶NžÝk‡>hݳӅ8I4Ï£,¯Òð-…Î/·±ö©bV]ªrA88ÀúW ¥xŠ4t„’ƒ'$ó¸cŒ þœ×[§)æW?yp»xô?ŸµsF§3<ªÔ=›f”Š.†2 öëþƨÞxzÎõÁ¹·YŽsóç¯áZ6Òå2>fïëþy©d^HÅtò©+œJRƒ²2ŽŸ¦ØBªm!¡ùq×'à?*ñO‹¾ЗY]\X&ôUW¸‹9Æ\©àã«ùzW²j¸xÄjÊ„·¾éëÖ¼×ÇZ¥¾Ÿk2]X}²AÝ[#·^qŸÒ¶¡ˆ9¤¶=4TÓæÖçç7íðÎëp}ž(­tHS 6$„ïƒÂôǽjoƒ¿³“üG´:…¸xâ…Ë.7rC)Ž>¤g ¯iñ­Ž›âYåKãrFaTÀ=;/Ÿç_I~Ï?®|7áØ%¼A,ÅÚh§ ¶7œr2:ßÔ“îVÆÊošú²}Œpðv<ëá¿ìž“$3jQ7‘æ Ê]²Ê>ƒ¹=:óÀÏÅãÙƒÁzφÚÚkÝ£]Ñ“;®Aãc·B2M{vâ x'ºÓäˆÉlÁ° â¸%:³WoS…ÖwVØü(ø§àÍG@ñ®©¢_oK{+™(Œv”fûßtœqÛ‚{×­øu#ŒJ²3*I¿¯Júçþ Gà9¼?â?ÄjÑ‹©|‰š.™ Ì׃ü»WÅ˪Ým1Í3Hƒ““šú4ý­Î%Ujp‘™$¥IQ€AÜ9éŽô¡øÈ98Æ:uÎ{c ¬„õïÖš¸ ÜwúþuèXòîîz–‘âÑqccoo9¢Ž'‘P–a÷‡ÍÛ§o~œW¥x^K_Ƕ–Ð-¬ºzÍps¸0Èã£ÔŠùã@¸’ÛU·òK¡GRNò]Ã#ƒôçžÜWÛß²Æg¯Å-ËBÏ<†D2J í_€?ÓóÅ|þ>*’mu=¬Si³×4ë/*Îñnp>l÷®Ç¿`Ö!•’Ý„sŽsº½Õ|:ö’Ê&UHñ‘מ8$~[‹eVPr~éótª4ìÙìɧ©ùÕãï†÷>™Þ ÑÆ:’qÏ­yuγ,N·>Æ#qh”·áÓÚ¿K>0ü$µÔ<8çìù¯ ³ØûWç·Žü04[é3°;wv¿ú|-U5fy•£}bŽ>ÿY.LYä@Á=H¾å^ðWNÑ5‰ïµ?It4].R;xw<2PpÁK¹QçZW†æÕîâ("¹%W–l ‚N3‘œÿúù¯¶¾~΃ZðVS!2^3=ê…tÌIó—,8ç‘ÈÏ+]X™F0åF8e.~y½ ‡¿ð¯> \A£è·÷Vš›ŒÃa¬ ‹Í#æýÛpsíÏ#é^Ýy­]ÞjVñ*·öÌŠcŽW]¦t2G W˾ø)¨·Ž.l!óÑ-®fŠÞédÿU$NTmoªç±=Å}aã[éî¼+áÿ^Û+ë%ÄrÌî˜b7®îO8 z×좛•3¿IV³¶§–øãÀW»¹aÅv,cœ©Ï?¥yÉðÍÄM«hŸ·|ÑH’† ç¨*?„‚yê9¯°¾#ØYxÇÁZWŠô-¤#ûd1ô!fÈôäWjºMÞnšþ˜™·”fH—¡'®?4Q¼%fx®§4u<ÛQƒUKv¶‡ì’[2üÚáT‚Äá†O=OB)Ïâqs·ÏÌìÞ¿18µæŽoÄöú\–-5Ä—Zpp艜¨9O'“ÇLâ¹Íbße²\FÊ]0ò×¢yê@ãóöÆ(×%ðΨÃcÏ`1‰Ô)0ÛÇÍ×Lôæ» GNH¦m64IQì#º6%¢ÝÃFãøH ë߃Rç-™Ón[3™‡Pv¯¢5–ÞrɪîR3ÏÔxìj «»k»{Èã¶_2 šHLlÌyêI9.0}¹õKûQ§ÚM,åd­’  ’sòûúvõæ ÒâWšë ¸¬ ‰€HÀwÔ»æÆ½]NJ±²÷N_ã^±<ÿu(-äŨN£˜¨f "c’2:ƒìƒòïÌÖgrƒ ‘›äŒÏ>¿tý ô¯¨>-HªÚ~”bŽYcûDÎSBHld´ÀàõÚqЊùuåeFP¡‚“¸àñƒÇ¦òíÓ®–ízOà2îO#³4d` ¤’O'Ž3ž™ÿõŠ«‚$ÈɦNÖ¯Ëj…NÞ7 “Û¯Lò:ztô‚P¥Ù¥M¯Î ð:q×¥z èqMYê@@U=ü) ªW=#¯#§ëR›@¸`VL`\ñõ=(XòÄP Ïÿ_¯ÐU™XŒ“ ‚IÚA¼fž¨›yØOfôíþ}éè«ÈU%qÀAïþ}©Y2À2€1À,0qŽçüóHcŒ+ #©Ž9ý)|¼åYp1“Ÿo_Ö¥Œ…Rl‘‚Ì1ǧç¥d’Iè1œñÏÜz÷ô dn•6ŽT’p}x÷ëÀ¢œ®„’X O·¡þ¿…[ˆLˆ°ÅBƒŸ•Gõ¦’¯¼«ÇžœR „žÄO›¼¬€e™z(ê9ö4„?„\œú¨ã¯ãùqJ«.2 ŽsL“¸9Ç~?úý±õ£pÜ@_Ÿ9Úzöê?:L.)rܮёŒƒŒþ¹¤‘˜¨Ø9¨þE!”Áž[íùŽx8\b˜ ´ï9ÁÇ<úŸÆ“s|¿tí 䎘ô¦´c‚9=1ì}ÿ \( “N=)=‚öœ(ÛÔúçÿÕJ­Â /9¯Ë­0“¸ìb¸'wçüipŒœúsšh.)Œ.ö~ÿ0ùªÕŒOy*¢®ÖbrN}OÒ«!¶ ÎI}qSZÈöà¼[Ð`á‡Sê*J‹Ô×Ôo<›t±ùŠ¡Þùa°Aú㞄ծ~~w( »vìãž vÍDÒù“ !Ùœ’IÎ õÏÿ_­/”í½Š«óž=úýª±ÐÛ{Ûù Ç;ÕN7t?—µ1µ‰Õ•º¬q×Ó4šF›.§}ªd‘¶ ÁÉ'==sÒµµß\hö«,„,™ÊeÁé×QÖ§KÙ9Zñ3luûÍV¶Õ4ÙÚÚöÝÄÉ"·ÌñÍ~³~Æß¶¾“ñGÃöúŠfK=~|Ñ>220€t¯É­#@¸ÔgÚ‘–ló…?z·‡¼ y§˜®m™ã¼_™d‹;íŽ9ë\8¨BVktwa ê&¥³?oäð´7íçØ\›hdêblç¯9ëü©—>±Gk­bäÜÅÜÉTP9韯>ƒÚ¿6¾~Ù9ø]fºn§Ömcä| 8àãÛÖºþÔþ2øÓ§>¦ÂtËYÔ¬Ï$a‹aÏ8Ͻyê×hèxZ©ÙOOÄújoÚëvÑM¢»YÊþaÎÜÁÛíÔøÖnqå¼R|Õ•1¸)'’IÎN?^!ð—SÔ,4(ô;öekS´™9/¹™9ôÜ;ëÛ­c[@ÏÀ€Ë° 63É€ØãÖ¼jÊJO·õó;!Mhf^éïö¢¬dòq¥÷)çœôÏSý9Í-¬cpH,èÇø };‘“úv¨õc2³ÄÒJØÜ@Ëc'yÇ'8¨Cn‘<èAÏðÿþø®&Ö¨ë‚z3¡oKnÙ$ªcvú?®ÓÂ-{‹h’vVc‚nƒ}Ö¼ÂX®. }¨êéœ)+øUÿ‰ÄŠdHÎF=;Vê\â¥3Ýá×"Ü*¶=zT—zÚCúw¯9µ»’_¼ “ÀúT§ˆÅŠÉÜÛ@ùpBžõ¢”žˆâú¬/r߉|Wæ4›_÷…pç·<þ5亇Œ/õ æ³BÙ?(Ðý1Û©®ŽÿW¶º2‚…C ƒ‘×Ûhø{F°±ƒíÄò99RÇ}2qÿê­T”5hí²Š²DÞð…ŽœÏ¨êQ™&ÎNΣžs‘ë^ý¦[TŒ ù@ÇzóŸéË-äw.Å×q(HáqǧzôXfEM£-·¸üë|<ï>vxØýmæAär)¦L·°ª~›F~n8nMIlë$uâ½¶¢ƒ•/™ÙZtcS±à…Kcœ})Z0ªHÉÆFìàïõÍN ÿ:ŸJ”\ä)éÏ\õô•b(˜[ÜÇ$\ËŒž‡9=;{W¹~Î_åðwŒb²¹¹"Êî6c€,¹RN1žBœœö¯Œ#B67yýJÞðmâø[·Ô® ’x và sž§¯ç\ØŠq«M¦®uaæá%cõgÃ~7²ñ™ ¨þpÀ²Èïœzöüë¾ÓT­È/‡‡nw*ãšùCöPûgŠô{‹¥à´ó ÌiÈÎàyÎp+ëÝÙ­â‰N~ðÎw~ðU"áQÅô>•YÅ4ikZJj'—°1n²òíùWÆ?¿gÉ/5é#ŽÚGv#ª {šû§J™ï/£¡"8ÈÚ"´üI¡X2®ø“yêIéÓ¥waª=ûr©ìš½Ï€>þÌò.§>¥ulÐb²W9#ûØüó×ÛèÁá;¯‡Ok%‚†´ŒFó–ã~÷$¶0:ŽG_ÃÝâðݬM„ڈɵN:óï]^‹¡[Ç,a£Ý²<ýÓÓŒWjæ«.DÎIâT3GÈz‚5ø£Lñ¾’ßlðæµx/&Œíýܳ¾eèÇ;>xžÝ¥~ÐÚ!¶Ñ5ó/—sdòQŒ^¿˜¯%ñwíuyáŸÚľ ðÖ‹ö¯¼’YÊ“Œº^FÇÍ’ 7|œço°Æ:Uø‡¬ÿÂW£k-æîhtéPíÆ#>YÇ³Ž•tä­g×ñó=P¨çIioÎÎÏÍ8|øÑ‡õ‹ .ô¬ºF¨F•9fáÊ®ãÇaZ^ ÖáßÄ-[׎'Óïd{‹B>ï–ÌÛqø_4éÚuÙ°ñjŸíSȳü¦îBK¹ÈUÜàã'½Ï+«kæî'2@V"’"aŽîÚ1óeOÝõŸNWw;¥±2\êȵñN t{©µ+¥•%¸·ó·qÂñƒ×uÈã>¸ù–iV±•!™ƒy„îFÎèzž€f½óÇwrø‹Q½½š'h"|£XžÝéÎÞsžaž>”­ÛvÆovëùóùÓ¶¶ã·æ ŽHÆyã­#!ªI ªGNþçÿÖ11nÉÈ•} ŸÒ€ žø=?ɧp `@ÉSÀÛÖ†n@Ën?w¸Ç?ãJ¯³Þ@\Áü½©v‚Á¾÷8åôÎɤ2% ¯»a'qÁ>”üñ¤ŽxÁô§ˆ™‰V{Žâ¤’ Èö?Ö€Ü,jr§¡ÏóŠM›HS‚GôíOÀl³ý욦JñÜcž¾™ ü²·ÞAýßZ¿c ™s¨@qïÁ=úÔÑ•Ve%@þò~£šµ Y_ªÀBGñþOéS&k©kìaGL²d’T–è0?k;-nŒ@N¬0J®X`uÿ9µôÃÚx†–8<Ã,c£¯åõïé_Ân£µ†ÙƒrI•G1Ðt¯»>é­£i:zÈÛˆˆ䎜{þpqÖ¼œSµ¬z¸hY³RoÙ¦]rdxQ>vÚH×'äOñŒká¿ß[YF†'èÎ6¬Ÿ»’= ÝEzN•¬GscåyqÉ"®ï0–i$_˜àç¸È\û×ñѾÁã‘-»,!×÷›ãc׺À0úšµá=DÍדË+´…}ÌO$dr3Ÿonr×|êÿ×õþFª7‚;‹ýÒ[<ÅNãó§pN=¹Å%®ž÷(I Ñ‹+M¸|g¯n0äõ©tÒ—a$º…$®Þ=}úâº;OŽÝ ¤o¡b~^™üŽ+ͪ’W'm™¢þÒ±¹Üp N cŒòà)üóZZV‡3¯Ú1åDG*Ù¯¨ã‘Zid— ²íPWkgÁàgðíÒ®k·†ÏNH“ÝÀÇãüs\ñ¸Nl§övȊי ÚSÜ…`럵+é£y$v8ýÙ$gŽÕÔhWj«eÀngaƒÓºp:àƒü…zFŸo”‡fv#¥tSM»&aR»¤¯kžA ü¹Ëv¦ä|†ÎïLtÀýk·>µÓm•WUûÂPëÁéøWO}«ElÞD#ι#"5<Ó'Ò±uEšY/%Æ~U·ROåƒÈöÇjÖi/3–êÔjúÖöòË8ŠVÙ:ù9~¾œÿ:×¼×-ô|[¤u »Hÿ½Æ^}ñO´£ÌžQr3ÂXž{œ æüuðÆ"¼z½Æ—6UH©*3ÃmÏ'ñœûb¨ÇKufòœ%$ªl‰®~-x3GŠ7Ô5Í6äóo!^Ù–ú~b´ôÏ‹þ ÖBŧëúuÃd.Èn£b3ì8¯¼MûøZòÑN¡â kZš"Ï—÷¤ªî6¨ŽŒã#' “>/x[à 5ÈÃß5"æ"¦Që‚xë„ùG¦ÆO¥{Th^:Jÿ# ÆŒö¿Þ~›êž:ÑmiXÈ#jWq8éÖ¿8ÿà¡:ö›¬Áa"<k[Œ(n)¹þ§ÿ¯\7ˆ?k™4*-6ÃQ¼Õd‹8¸“ ;´äŒúcÓ½|ëãoˆ:÷Ä eõ fîi€ÈŠ‘c$ÁÆFk· pš›{Õ¯ tÝ8­YÎn(Iç°<~4:•K?ÄXôrMeRÇœ1ë?­2êxàsõöé^ñâ;åö¨9óßÇzé|áû¯ø§Lðõ¼Ò /d* cÆIïØqë\Û>½Œãç#¡νŸöE±[¯622#}–ÚYoáà&@ÿþµyrS”—cz穾çéÂé¾ Ñmôû4H­bE@HPÍ×€zI®^6 =«‰Ó™Õ"H‰. Åu6²Ä±™2ýKšøÌ÷>¦I-ntÚ]÷‘0vm zœÓ|Câ öùfaû¤úëJÒ«À¤‚8{ÖeÔ2°SIŽOJÒ>î‡+‚“»; 3ÅHLYbe…“¡ç ®ÒÛÅÑØÜ\Hå¥d·ßäÇÉÀÉÎ3ߥx¦—cp·#{0Çû5?Œ|wª|0Õ¬õ¨ôñ©ÙIkäÏk!àòNìàóÅvR›Rn;œµ¨Fm"O þ̺¯âo|Mš)S_ÖækK2‘*Aænœˉ9!@2p1Áxâ ¾øCÄ1jI-Ô–ìŒK’`ã;±ƒÔŠôŸ„Ÿ[]Ò.îïí’É|ç‘-Æ@Df8^ý+äÚŸãçü%>3ŸÃºtåä½”}£Én2¼g±aœWl$œR[Øô0të{Ióü?Õ|2ðí¶©áÙg– u“ó.T³*ŸOzäµ ¼ÕšÖ‡;v?:u­]"ú[\µ¬ÅD‰+1L‚8äÃÚ´W^×ï 3[]]ÞÝ ZI–í·‰sÊã’Ëœ0Ç÷z‘_Aü`øAs¥Ã%Ì:}ÈP7KpqÝ ã¿´ÔR[Kÿ1ãtM˜Œ­–ÁÚ@Àꧦ9¯|&[iÛPÓ5»-.à=BQk1xÊ„é×0+“Um|oáûÆg¹Ñ§µ»l*ÝÀqžß62€K ‚N[Ç"{ïiÚœ ý«©ÛÍ¡Šâ6hÎÊç#=sÉÈÓª2æƒkÈÁÔ—ÚW9ˆ,µi.#YÑ5aÚ$ŽðÛ9xØg »p£–R;s­áTÖnõ«X´{MOP½óDcÒà’âk€ØP¦8Á-’ÉÆ=1S^jš6©,òÚëZú> Ô$DÏ_ÊFAíÈëšúÃþ û«x7^ÑÊÜ·9Ï~Ìþ3øÉ£Feð®¹àûÛrI§¥oC¬$ìÓ4Oš:Nèoò 2ÎO<{uçá^¢)0‰ÈI £“Çóãžñ\3A3³.mP-rzàç¯aøúW‡5–ºµ'Uh ’ÍŒò~µ5i5vs«óXìÍì?”®œrN3“ÇNãüœ­^ÈCpÓu¶7ª3gIuëÔÕÝ&þhc*É&qóÏ9ëè8÷ªšÔÓ yAK•Lçƒïþy®»+ìWÒõä¿·}Å’zõÀÒº{ŸÝ_]&¦dÎø;äyc©nœñüëÏ,o ¦UG¹:ðqþ}ú×YỘ´=îõ×3;w#G¸üÿ:«>k#9EZö5¼Yã-'án•$²þþú`X/ñHØãž}+Ï´_ê%Ô›TÔ•"‹°8ã¿×Ò¾zøñZÊ_O¨jºŽç ÞM¬„Tcô­Ï|QTœËs«YÚ¨ýÜqË V“ߎƒô¯cê©A]ðÑÝ}çÕöúÔQ¤…ŠáH_3qž­6-]o`Y|¡cð9¹üÍxÛøÛOŠÝcì.¤qûÞúÖ·‡¼S§, Ö-IçxÎH¯ëôô¦©#Gw­Š<}s¦è7Iè²>R(ÀÉ~·n£°¯?iï„ÇÃ^·ñ ²Ëuy4›®‹üß1Sœ¶s€C`ãÝë쟉z!ñݤ–w‘N¹¤™P¹Ÿ_¨ì+çŸÛ‡PM;Â6ZAX÷4}U²À#9Î;z}kÞÃ( .§ E.}U„·‡ Ê’vîo›o¦=1ÇåBîi7È £‘Ã~xãòëP«í\¯|mëÏNœ–bNCzòG^¸þ^â½›Mû“®v1áoð†Æ:þT¤‚lÆxÚùÉÿ#¿Z`89=ð¹Î:ä~T€£mÀÆ1‘ƒ×Žô˜ïqà+‚NÜ’~µîÿ±Ä27ÄË©ì%“¨ló÷ããüûŠðgeEù›hQÈÈ~õßìÇà9ü [ë÷£Ê:Ÿï '†hÙQ—ð8?•qc&£I®ç¡‚ƒ•dûgi7’ÿf(•¾ï*sÍuz\-”¹z“^u£jbä+HáP *Žƒük«Ñµƒlo™O_¥|tãgsèZèwZ\ÂxÇ# óÅ]é¼ÈÓmóŽ+2+äHÑ¢mÀŽƒµhÛºŠ9 ùAÆk'³0}Ê÷–Þ]ôr««E6J« ¬“I+nd ’ #'a|*øTöÞ=Óµ¸ö­£‚ŒçŒôÍzüñŒ=»B1[H|9ðïØôû;RƒåE?@6ý+Õ4Ï›‰¼ÙNäÙå¬qœ~gñý+AŽ'•âaCõÏNs^£«G_3#=«ç£Ró¹–&¤¡ #…ñGÂë-f …’Üî#/Ð~>žœdšø_ã‡ìϪ[\]½¼f8%0—Î3µ¾ñÃåp1׿$ ¿¨ 8àqYZÿ…ì¼Gh-ï-ãšä#é‘íœ â½š5gEYj â9ž¨üñ_‚õ ÝÍæD,XJ…w7Í•8ìÝzôëž9Ó¦Ã9‘¡/‚þfö Éçñûñ³öDÒ ü*×~^¹…æÓHÌŠ®ØØ1¼‘שúžÿEZjVÑÎo4këu@.qjkc…ʰ=T’¸aòž˜ëZ´Ô<.’eµ-8²Ç .Wæ@ÉÀçéïÐã,5z´$âµcðHÜøQ* c?ÄAÈõÇò¤l*¯Ý`IVÏãþ}+¹ø£ðñü­)·¹7úUÈ[]™QÉù†Wº°nq\Áù®œœ9íÔwú×Ô))«£È”yI¤o+G*²ËÑÁ“œzúÈ×w™±ONBdãçÓןþµBŸ,h3ŒcjöÛÅ"œŒœ’ãWa\´§£/ñÁê B ¹ÁËÀ¹¦–;·ÁŠýåÀn¹ä£,À4…†rO'§ÿ­É™ÇrI'$Ï¿ÿ®ŠbeÆT<Œß<ô¢\qpYxÆ?¯8¤WFQ“#ïz^ØâŒ–L±Ëg¦sNÞÇld|ȸ*GOÿ]Nâ,cx%º“‘“ùj‰Z'aÆìŒ°p¤‚ޏÍ4¯BçB²F‚$b}ò1ëߥF$<9Ϧà¥8!Gçä'–Ç?Zb€ªÒHŒôã®§µíÀP=ô4I(8Ï žx=È4ª@ Ž9àñÿ×#ÙU¸Éßí½Ó ~´„;|Ü<çž=)Ìî_ŸN s_zŠS–,ŒOÝdä}i]Hc#1ÜÜŒã)”_Òõ)ô‰ƒÁ)p¬3ÏNß×Ú®]k_Å‚ Rœ/\Î#¿5‘²o$ç(6qùç5ewEÁ ~L™5›ŠzêÉ{¦ÞƒMuÄ›˜° x3Îqøq_ZþÏ Ž¡jw6ÂXO*Î@ ‚‡#¯pxéô¯6øðe¼U­X,¨ßcgNvo•È;²1†éƒßÓ? žøim¢éqC ,j#Lv ‘“ß<÷¯Í1mµJŸSé(ÓTãv`éþlv@™•1dܑێž½8måÞˆà0PÌ3Ÿ”{ çžz~5ÞjV‘hïPÆÌwÞlg'=:}+O³óîwFÇp*8 œ~}Ǩ¯žV¿+gdÞÇiáxÈ?3Å•e Žp2qÓøÀÿéÅêÁ:&ÝÌ¿7ÍÉ#§õÿ9¬ ÚjŸ9,¼—¿úõ»<*vm^qpr;ãÐþ=릚\ªÆ½™CÆðÉ«YÅjßq¹}ŠK6 œb1É<ã¸ÇJüùø‰ß¼IåË S´jŒŒX© âÜ2dLc¯p1ŠûöG[›w2üåNuç¦~îxí#à;]zÂçìñ}¡£BÐ> ÂpXwƒßžÕÑN¢U/5¹TÒK•žWàO*íVÚJ¦XÇÊç'¹ëÊž}ÿ öÏøí&1“œŸ•KHöçÿÖ+áÛGRð^·=€RÎ÷ H žy9=28çµzßÃï‰j‘y¼©“ ÁÈÉ8$’G¾ü;ê++ËáÓRen}»mâawl¦)í I'ê3þMXÞ£BehÆ<ñÔîzòø…¯æ„4¦4çæa× ÀÇ¿ó¯fЮL%w’P6x =+Èœy^‚z"…ŽŸæ\Ò11òÅÏ'ò8ô§x²ý—ÓZÂÃ÷Ü3/gœžÕ&­²+ç•@ŒLrIÈÉÿUcoTGåüøË8=ó×AWMYó3·²8‡Ÿ³…n5ÇÖõkíI\ä¬ ãkÐõÏÙëá¶·ŠçñŒ£ Æ:c?•lé𵿗†Ø¥F8Î;ãó­t‹q¾!Än¿1ïì+o­UNñeÂ)XðëØwÀwW†Hnõ[|ŒyItB¯úÒ¸OþÅzÖ’ÒMáoo‡. ©Y[w×ëüëè]o^›BA-²y™ûÛ° žýó^ñö†½Òt¶Èc¸cµAÁç=W°íÞ½Œ=zõ©^†·P~ôœ~'x“Ç¿bxµ y$°>ÔÓ¬Ñ÷Œärxý{×Ìß¾/ë_T^ðÎp?—€s×®:?úä×Ò>?øñ©x§AÔì5í0²Ï¦ZEùA *Sþ=«âûéâí¼ŸõD¸ÉëÏS^í©;ž~:µ¢”^ä?’Ù9Ï?\çõ¥åÇ gž þ”ÈNÞ_hl~œ •_Ÿ¢à’§Ž?Ïå]çÎÜrÊ|¶$pq×üýh3,e°Ãrr{t 1U;XñœgŒþ½GópŸ~øÿ"Üè| §/‰å|õe)$eç¦N ’x'Ð×ß"5¹EÃnHm Œö#šóo‹~moìª-ÌÆ&$ÆíÇŽ9ÏBN=\qu!(ÊNèÞšS|½OÄ|?ºÿ„¶ßG¶ˆy×·BÔ+ÙÝ&Æàps“ÀëÈâ½§âuüpø‰ XƒBˆ¯ ®KnR¼žpA c­z¯Å߆Káï‰ë3[ùpÂÊ †.\?–„n=6Èî0x¯ŸüQz×·r\7Ë%Ä¥“å ]†X¨Æ3œãðȯb­e]ÆÝ?SZT­&ìs¾(ÔÍͲJÉ.ô¹2!Èc#‚ÝëÇÞ‹½jçRÓU’G[ˆAš39)¹Gl‚=ôíø£N’†¶-qeäêºó˜ä;¤‰c%NÀRI;²<k.¥ŠÐÍ$l¯dlàå\*ç®1¹qÉÏõQqäÓ£5nìäΪf´¨[Éòà· Îqô§¦k«ð“[ë0\XLE½ÌA¼—SÅrÇMÝyÏ8äœW°¤:i†2FÉ"^s!êÀô“Þ¯;£kú”–Ó)|ÄàpÀ`gÔ&N{±Ym|Isq¤p0‹ »@ܪ `mè¾½ûä…8Ô•—b$î¹™Ýø¾{ ë6¿eÓ®È`-™-§ÈC9R6âONa…ÆzõîâÆÝÕ”a‡€?¯øJ*Þ1Êåy#!~œþ'üâŠH ï˜6÷²)ªÙ~lô*x¦;‘ƒ»¡# ô§*•«Iÿ?ÌRµ…ùσ&pqÉ>ÿçß­•Žã’‡ÐƒÆ:þ”F HpÁGÉÈ=ð?Ƶnâ·±°XÑ–iØ’Y”e~‡üô¦–— Œ²À†ŸJC)vê; ð?]ÃòÅM-«ÃoÄádÎ? ‰deÎQƒžx©ØCXî$18'8÷üéÉ&/Ê@ô=¸ÏÒ›úÐå°$県ô?áÿÖ `­½m¾œñþM0ÀUÈaß¿Z³{˜ýô8çbd~§Ò«± ¸åÜvS‚?š ØA‘‚OþºE-GV$×Ïz×§|øm/Ž|a°aelß;,¡6±Rò>£œŽzzyå¬"âD@É 3Î1þxz~óý“~ÿaxVÊa ­ÕÌK+_,äåŽîçwCÓó5æcñ …'æz˜*<õ9šÑëðÛÀ±h6èD~_€òA$õã¨íø“Å{v‰*-²ä¥ Éq·ß$žØôô®/L‰`U ´Pb@~øž€ôÅtvìØÆH É\t#ü1ô¯†¨ù›µ_‘ô2ÔæüC"Üj cYYúãã¿ãÛŠ£§Ø£»§–xmÈs–É,qßž„úàc´¬Ýo/¤u¸bTnÎîüƒÑ¸ü:óZV6̲³»K&Õã®IœžõÉ{se¢/X:X«)Ë,g,äd.sß¡çŽK¨Ü¼q7 ‚6 9'ŸëSˆ‹ `©!ÀÈÇ<ò?/ó“Y÷ξ[3° W€1ß¾=þœúîŠåÒþ†?¹ ÅÂZ[äGi ùY3Ï9ãœgšçhø™á8Õ'“ÈÚX—;{·$`œó‚}:jô0xŽWì¤LõEÿƒ¿–{«K+¹QHx×{qþ óÈäqƒ_WxWÆð£»-tÌFù6§ núöô5ù§¨X\é>b“ $œ08zŸSŽ„=ë×¾~Ð^žA£û9*»@É ’à Ó7g5шÁòþò’ºíþG4¤î~ˆ A|KeFâ`чB§‚½GóýkOI@ŸºÚÑIŒàã×ÐW…ø?âB_Áç[:Ç›d]ÊÅ#R8ç' ôu¯[ð§ˆ#¿xæXÆ1ÀaŒÃÜ}}냗ÝRG:•Ù×ÝÂ[bŸÞ1#*½G׎žþÕ™©-ÄRÈ «•Ò5ͽí¾P¨$¼Og¯Î^HIÎÔ$d÷<\Žõ›LÞ2KSÉüM©2ÌꂌùŠìŒtÀÀéŠùkâf±/…nnd¸‰·"îóT)Œ Óõî~ƒï{Ë´KYmÈØÙcÐŒIõ8ÏZù7âæ—¿þž¡K2¦ÙU¯‚yÃöêsœ‚A©Ç±ƒ›Z2¤´Ôø'â§ÄËÝp=šlXd-¸2 `ó€Ïé^\ŒÊp ŒV碞0Õ-”†c'¨ÎÆ;¥`ãÍÓ©=ëë)$¢š>o7:ËAÅ|Æ`FŒž¹ïþýTÝøRîƒúv<õ¥M£v Oçøž´¼ ’§Àädÿ…hr‰»aÚ •Àœqõ§ç…‚[þy¨™•2à Î2ÀŸÎœä#Nzq×ÿ¬hó»HCH¡sŽ3Ÿ^¼T%¥RX«…ÊØãðíR0$I;Žwã>Ÿ^ÿ/@g'¾)\¥d¿…ï>Å3·ØïŒ78`3Ç×=«ì‹{ø#Ô¼õ!¢¸¼Uäƒé_˜~ñUæ‡}j!¦ÉDˆîHüqú×Þñh×t{­àU$ƒÎp¾cAª¼Ýô¸Z‘tÕt±½·C»xP8UcÍo®¥ \†Ü§®ÓÍy”$K0bÌpAγq¯P |0#=kÉöo©èFͅ׈E³%³9;ÆAö4Â\mÓÌg‰p3€yA^A«xÁaFRì×®ü\û aX¤žäôöëWWèuÙÉâ߈ñ4Dº8É5çfG]sI˜FFdûïÀÆEq>×eñΫº]êªäãR;b½SÄ:rZA¥¾ðq"Œ÷‡CM®FDšJÈúáÍê´à·ÌUq޽nÒB8`p©ü+Ã~Ý­¼p‰k(è8¯mÓ®ãGà1f¼y|lË›ŠgAhX¶ëÝ…WÕ¯–Ù`2rG,9üÒÙÞ)”&@' Ü*¶¥$ u ¼ ++>WåÚAúdãÐã#dýË#ÃQý樷¥Û©KàDhÐg®OSÔÕ¹!7/°(ò”ç3PZÍöÉ·FÌæqŒçüâ´Ò,`t=ñ]âæ­Ð¤¹eq‰ŒØpbx«QµÒ4›«û¥o³ÚÄÎäc-€~P $à`:r;kj𕦋c=õõÄv¶.é&•‚ªŒã©÷8úâ¾ý®?iØõû1§é3Ëmbù+gL¹ê#ÉQ‚T•(Ú_qÖpzAjÊ¡ T•×Þxÿí9ñ‘|YâMN[XeµÑb9Ð# ’å\AcŽpÇ9#¯ƒx'ÂïãßèÏ ´Ö¯k£éÌ%(âyåHUŽA‚:GÇj~á½WâçÄk-æYláýåÌÑ•'È…{n|Àk° רü&ðÝ‹ü{ûP° xLºÕd´…0‘KÙ:¯ÌU2OÊG(yzö(QTTW^çezª1qCö‘ÐôÏ OáýÒS—à½. )Î^hC,)Pìñ±$z†ÏƒÅ®Û[YÉu}¸ÚÝJÓ?—£ØDkŒœòÙ<}Ñ“ÅtßüS/ňmg§] ]:ÒµÜtC;™d,9$Û²sÙÎH¯>»±ºñ‡‰c²…LÑy®ª•bB Ðvä`1=«jtÕïóþ½L¡xÂÌÕø_¦Zø—DZ]j 'ö ÜÝìÂ2C¹fÈ‘¡R ÉÝ´k—ѯÙïn®%š2ΧÌFcV C ôý>†½ºó‰ῇWv®–©¨ëÓÄÂWˆa™zá•xBCpÄ'œ"Ô-£´ð¾£z')$·bŒp¤q¸žAÛ­Â")X)ß­'ÍÇ9`[8ÉútçÃüMhÓß\Û»,'`'x  ð@çþz×¾øS{|>†IBIöÃØàÉPûºbpO''œ÷ñÏé³Ûø‹S³YPtbÛþeùAÁÀøü;浤ґÎÓLó5À1+»œ+þzÕYË?3cáøñZVímtQŽ=Fyè2¿ŸpÈTqØa³üÏ¿é^¤YÅQY +æ¹Läýп_ëš$A€¸#žž=ºýiÒmMÛr<:z²¦ß•IÉϨçŠÐæ¹q+JY±¹F~ø4¥q$z`g¿5(hÓ Nr~P}¸›C• oqÐ’Ðg­ ¹*º…|€zñü‡åE,Na˜ã GÇ?ýj(¨ øvþt£$€ n9 s“ÓŽ§4ÖÝ&y_a’qëïÿ매uÜ[Ž7yü©_¸aÀœç$ Žý?Ïø É'¨5ÚT€tÍ ãâšNEm©sà'Á S]×ì¯õ¶Ù«‰4 ûØd#¯œx9ǧèW‚4ì»"UØ.åÆ:óþq\Ãÿ $ÐÁy¥ÀÃ6å“sTà`àõúzö-"ÑÕ" #ç?¼sžß—ëÞ¾1ĺµ]´Húì-%J’¾ìÔ´‹Ì±i9 “Óñ®„ÄɦŽùÆôÆH\Ÿ_ÿUT´„¸]¥?9½9­ëm8¬%… usØûÿŸ§ˆï=.k)Y£'CÒ£¼ŠcÌl\«Är3Çùö¤hM´Ø/»œq׸ÇQÏë]>›§‹+pÛw»œ©i;lT¹¹ }˜ÇBI*AÉàóŽ;þ‡5WQ•œoXÂòGnx?ç¹w+¼¬%rÈ¿*(Ú6#Î|öã¹Í¾Ô·Þ…÷6Ðsø?þ½i6µ6Š3®&i<ݧjÆÛ9ÏÒ²ái#Œ©RÒn·.ðÁ=ùÍMw>ÕvQ¼>ç^Ý1ž*8Ú8‚H7 $”=ó“žAü}}*£érÞÆ&±j—HÌû¤bÅI<’súv÷À&¼{Æž¸¿’@Q;arO¯—CÇòõýVé%`±™á‚Ì8îÆ;qÁíY·6cÉ2‚®„pÄñƒõëÅ;J›VfRÚèøûâWÛOû\¤Ý v(óžyÁêÇã^#åÒ5Þ» ãt`‡$ÿ>ýzgë_ŒzŒzmÅ´w'Ì[Ù\®J°_SŒ‚?ÜÉ9Å|ÌÖ=ÃΤ‘I|(9=yGãÏZúŒå*|ÓGÓ½_‡Ÿ5/ÎÚtîd²œÊÇ0yRz€öü«êüh¶{pñÜ–V]”dp »ã#ÜqÈ¯ŽµØ,ç]Ò[%³*F DŲGŽãÉ%A8Àç ®A|Q6“t²YåZ¹.@oqžºûû êxhÔ“pZþYF 93õŸÃß•-ü¸cK¸ÜíÞ&9Qï‘ÐpxêIÇ­w6¿!—MU¼ge<±s‚3Áàóôâ¿(Ïp¤õäm ´p88=Iàäž/_øÁ¨ -ôëFù‹ƒ"?8È'ŽHéÄ kOË¢[ÿ_#Z•´»èqŸ§ƒQøƒâKÛy ¶ÒÞ»!=0@äg<Èúö®p¿LúšEP\6nçåIïíÏ? À&H'©$¿\z÷"¹b‘óó—4œ»Š€°Ànùàg'üóþM5@ž@Ƕ9Èíª{9*OOóï@PŽáƒÆoêJ¢Cæ8çÇ@GÓž*?•X€.98ëþÏ´…H8s…è Å4°aŽ€óÇâ?Î=¨ã…qž½0ÀƒúÐÎ=8õ£w–FxÁÎ{7=;Sc$¸ 29'ð e«•¶¿¶‘Ô” ×é_Z|;Õ›ì[#$Z¹«çpõ¾@+±Ç\uüÿOjúËökH.>Ú<ê0,|¨€ØÇn™éè¾|¼|W"—ÈôðSÞ3ß<5¯µÆšYœR6äñÓ¿éUµ½~ ²#mr=xÀj>(DØY—Œ`esì®Ä¿„°¹*J®Ò#©¯4å#Ý„•Ž—Äþ#i Gç.üôNüWe¦7‰5DG—* ŽÜןêÞ1¹½ÞÙUº€t?¼RšeúM3¾íàÄOø×J¢á¤iíQõ‡Ã?A¤[F!D™Æ3Œž¿çë]ă¶ -JâEuÇ"¹xâÎú(ÝiáYC}¡®—ÆšŠß[Z¤*ºà{äW–ÓrÔº£Ö¾"Ïchå¶HFÏe¯b´½[3)Î{œWü,Ô(bŽP(ÉûµéºÅãi¶ðÊÏCŽ:õÅx•.¦ÍÚç²gK£]­Ãå! Hçœׯ^ÿCã'‘ñä¡ûJF•¹'9R÷ÏçŒ×-áMKí—Q…we$ÃôõÿëúW[r®lî¢S:1ƒ’p®Iàûôö¡KK3§ÉUI.‹2Í¥[2@a&5ÊÊð8<Ÿò+D²GwuD’îp¹ªVÊ-âR¤mêT ð‹ÚÞ«ñÏÇ_ <-©]ieO‰u´³Kˆ!ùh"Œ‚xYXÅ(GÍѽ(UöqæjïOÏþäxꟵ›³²Ý¾Èä~%üU¼øË6³˜÷…ü?j×7—%CÏ“Š±ä(w(B»3*…?ÞüKs¥.³©jÚÍ­’À‘G-Ë0L-“8,æ#s¨É¯°ÿjÅì|9ð‡Á76ö>›׈uØ^öI&´‰6‰¥-¹Ê³Ï!˜#/)ñïůXø7Â#ÂZ5ª¯Û-Vâáž JÆÝÉݎ̕휜îùzð”›m·vÿ¯/ëc»ÚrÁF’ßúÿƒúšß³½† øâ?‹o{x ŠÒ–BÎé»ÍœíÜrYâ·ms“šó¿†Þ)–ÇágÄÏl š¶«ž!B€ìŽ&•™GQ¼.9É' ã5ÕØøº/þÍ'KR]î#¹Ô); ûŒd€yXU=ÂôÉÉó:fÓ?gK(£ÛO©O|UÎ@“|(2G;°¨~}Z½Ä’¿Ýùž{‹r×¹ÉêºìËdb3-Ó Dmùa (þ§;@ äòÝ z¯ìñ Ã«ø‘bòã–æl,$!ý×1TQ“ƒ ØW€Üê2\Êd›r&6ªÐtéÜu¯¨¿gïÇá­/n˜’é÷mio„윰a’pNæ(Æ:ÞpŒ!¶ãG$Ò;—–KwpÖ‰i‘û¢lrЪmûW|7Θ$‚v:a«Áþ.xrO xoÃÚ;FlïX­ÄÖ¬ŽÒ>Xž ä9o”g¨ïœz‡Š®´ÛýNÃL†$0EZA!å,ÆxÜßJó¿^)¼ø…ñŸRÓ®„³KѠȤ1ŠÛÛ‰23ƒ€Nì8+\Ti¸Ë›Îå)Ú*' ésǦx+°+®tý-'/¸’râ2äÈxÇ®kÊ<_§Í£x¢Õn®Æëø³ÎÐŒTr>RA#‚qÈÏ8íô^½¦5·‡’ÖÝbiÞmyÉ…0wdç;ŸžÛ“ÅyŸÆmK£ÜHì±&Ÿ"‰p€ç<\ƒ×Tœ*%ÜÊ›VlùÛZ‰àº¸W8d`;’8àéÿÖÆ¹,n\óÉÎvöÎ=óõö®»ÇcÊ×g;ä1º,›¦ëœ»8ï†úä' ¨§œu÷äþzÔõW±nÃpzŽyä{gð‘òq¸þã?µ vcœg³qŸ¯ùíAj`)\dü«ÀßýzØä+¸|àòC`ÀîOåõ§€ªöëÍ ÈÈ€œqŸòhÉ €Ìy>¿á@‡Ä¥åU@[wÝ¿ñE5£>Q*ÅxÆìŒþ´QpîF&23õëÇù4Ôb6 IàŒqšU\¼@è3ùõ¨Üdç=0yüêX òÇ–¥sžädãð§6íÀó•üsš0¤(Ïsœžƒ6r Î#=¿áL}éN\)º~TÇA¸¾A<ÄœþT a‰+’@'§¡þTŠ­·hQŸoO„‹¥ÏN08È÷¤M±È7|Øà—üÿZï~|ñ7Æ-Y-t›s¦Nûùò¼`I!‡9“ÏjúRÇþ ᜰÜêž*¸ºˆ§ïaŽ4R9åyú}G|㎦.)rÊZtðµj+¥§™ñcÛ€[‘žƒëùUí#C¾×.#‚ÆÚk†,yhp£¹'‘ÿ}Zú ã7ìסøZÿJ¾•¡œ¬wcs>ñÞÇozŽxv“á$ð„A¬l3©cp+8Ü îÎp8PO^}x®œ<ãˆu$àò8_À•ö´V¡#\ó•W;BðOáõüëÈÆæ’öX›:hÐvæ™ÕxCá7…¼áØt½3M„C aVI"Œ¿AÏ x¯œ¼mñ[ÂÞ ø•yáÍFìYºJËÒHŠ„ç€ 9ëÀã¯ëú÷Ä# ÚÎ’_8†(˾㸪 ƒÏP?Jü¶øÕñ_‰5OÌd²·“ȵ˜6C¸ù=KúŽz“Í ó r8Ù+Ýù›AÏ KݳôãAþÏÔÆöÖt“¢‰A+ëÓ=ˆ®ØD&Pãf°Î[Ö¿(¼?ñ[Åž š ½+Äš„r­å<ÆD8(*[8 צOô‡ÂÛŽçQ¿³ÒüqmBB±Ç© ’mÊ÷l lgqÏóúV„Å‘ÇÌ»úm·ùÇZÁÔÝ£"NFþ8öúÿ]jôZ_ÕÍL«Êý¨,Ëö ‘ÀÉ#Œû½=sÅ}&…F’ØóªU4܈ü_­Æó kwI7)ÈêÇå\‘;É#è;VpɃƒß$dŸz ¸Á^àvús^ìb ž«UՕ؃P Gßã4.åÛµÝXc>)7 ‡h$õäð8éJ§{žy-Œð3ÏSUc‡[ÜãqÜ»pOZA)fF$±QÑŽ<ý?ZŒ²ÆÉŒƒÈ>ügšr(!ŽrzçüÿJ[ ɽءC#¹<~'ÿ­LÉ>kdŒu#¡ëÏéúÒíÀù¾b:c>¿JTF.>ñ9çÇoåL‘®ü©ÎòsÀÿ>Ôªà Ãa$í=§nûǠǶGÖ”ì 9ñÏøóø QÔO¸A#§9”XЯoóý #q!6ïlô?çüi %”…cÓ§Cí@ÅGÈØ Èû»ZÈ )9Álg>ùüé¼ËìI­ÌŽ¢õüiù€ÖP²Œüáå_E|ñ<>{I¥XÚ+™J&î9ò~dú×Ï0Çæ8ç§<þ~ÕÓxbòóL‚cIäðd £ÐóõâÅAT‡+gnòNìö/k)p›’çlÙ$4mŒóÞ¼Ùî¦,fY 8?19$g#õ5æ§<Çæv1F}=ò{ñÅf½Òo ®À'wà}üý+–ì_VÒ$åqÎO'ǧ㊲—ËŸ-QƒÇ^G<ðk(_FBùg tNÿ9éGöœGÌLÇ¡,@$ãÓ§©ü+^^‚æG£ø#â%ö‡©E$2ƒ<ÂNsÆ:f¾—‹Å‡YЭ§ »s/CžsZøžÓ^ÓÒeÚÖU8Þ­‘š÷_‡¾.ûD6ö>p'Ì\)lƒÍpb(òê‘Tê)=öÏÃ)~Óoj[ ˜à“ò׬x—íxbV<²!Ú§°W•ü%ŒÍajø"©Î;ákدK]inÁ#G1˜ øÿ:ùª”âås®Ue’9?ƒº›jk+° ?œôüäkÛ†›¡d`eUÓiÀ(Æ:}ûWËuG†þâÀ»f Š3³P`•-Ü€ èy\WÓž¾ŠæÔºJX0á %‰Ç¯|gÄÙ¤ª´ÑËÙMλñOè³Ç¨éÒ‰­cU†è§î'ä(›oÌNâAëÇ?6OìÛá/øGü!w©_[Éý¿«\Iq}}:•šãMå9=àõf=Xסë]¦¾±ØjAwi$¡ÌW ¿0ùyãœú`ñÅT×üMeá³;@ ewp¤t]¸à)ÇžqY¥+ݽõþGœeOÙÂ:½þGÀ>(4~,øçâ}6+{DÖn´­(ê¶éÅ´v¨×¦GÜvŠb8*í±~`ñŽŸu­xPkó3Ïuq$—TâHÊÄäœ|Š!C `VßÅËÛû}{s,·âûÌŸÌýØÃ(qÔ’9AŒîã.ú)oü=cn׃–€Å¾MñQµÏË‚7$‘°rßIB.1R¾­¯ÁLíöJœœWc]¾—Qø{e¥Û‰#’+cO$ü„‡fà„äžRzf³¬.ìnÿgûËûJßZx†Y¤Rê!Kym`Ù…ëñ0ÏBX>RD“=¶—4Èù´2X‘´‚HQ“ÐõãôÆYH­Mý§’ èøfvQæ&á³ó`“øÉõ╾g á{–Ÿ¾KÁÀ²´I¸îËU#,Hèrzsšõ øÉôŸ ÝL»I$VHüÎv¨$+ ñ–`8=ϵp1øjîÛF½ÔíÕ„p,–ò˜Fé •É8=ˆ'<ŸNj½½ØµÓ`Xœˆe“r°`A'ÉÏ úzb·«j©$cJm3ÕôÏZßëvþ|°´zd`#Â~i™™Œ®rN3Hg…'­d|7µ¯ŒnµmZsq,³=IJɂîÛ–Fcœ‚wúkŽð…Ò$÷òÊÑÆP}YÜíëÕ<œŽý+¬ð|Ël'S‘;£`àmc°¼qÐþžÆ³qå¹£Ö*ÇÓ:¦›â)¬gæD¶³Ž1rÌ»0„Hõg?R¤òrOñ9 Ô%×4Ö$S2°2£= |£?ZØøal¦Ÿ§ÈÊÑy%™dRÆb##Î;‘Ï¥p5ô›Äz²LLe&@ñÄ9õ*rr®zãÐ ó¤Û¨œLéÁ$Ï6ø•£E7†týLÛÌ9òϳ`“ Ä.qלsøf¼¦\yh¬£hbHP0Î*ú âŬ|']²Éñê‘Èñ–Â(òä¹,å\}å=Í|øä1#äí€+Ü¡+ÂçmЬHá¹ÏcÏ~id$1ˆCÜóíúÒPs€pÃ_ò)Sk›çú~Ôr„L‰a"’v±?çüiÏ—r‘‘€1ÆOùÁ!²àãÛùÓ–5<žØÂã“ôôõühÓ“³©?çùQNù£S‚Qsuÿ?ãE/Pc.˹¹=HnGãMìÜ­–=x'ñíRŒrX˜Àèæ ÿ3DÍŸ™ßÌcÕƒdóÅ6€fï©`)Õ‚ÎN}=¹¤;ÀÏ 1È©ëSÙÙ›ÉÖ5À9ê;{ý?úþÔ€tËráUKB€£9?…}ëû/þýðŧ‰> Ú5ä×J. ²fÄhŒˆÀ2Œ‚s¸s^EðOöqºÎ•ªßÌ.ms½`õ88Î=+ô2Êw†ÆÚÛjˆâP <+æóLd¢Õ*NÝÏk A(ûIoÐ];á¿…<#¤Çeáí62ÍB.Ú rqß\wÄ‹û½/N˜ZÁ5Ú‘ŸÝ)-Æ;cÒ½ÎÚ[üF€ä(ã?…jÙèHÅ€ ÙþðɯœS³»Ôíæhø@ð¾#ø¦eMî2„Ži—j¢dÀãÜž}=+í/ƒ_±O…¼?¶©âp¿zîáhmî’ÜÄ>ð*¸ü=Çé]Ôh!„ ãiÎ¥{QÅÕ«û±]ºú³Í¬£ÍÍ»g;«xB=>ÍdÓ#`aèŠÜ3ï^;ñcâ®—à­Ü^\,emÎåq‘Ôs^«ãoÚé:TæY _˜1Ü;vù-û[|^Ÿâg‹m<5¤_ƒk™.–9z°Fx.zq޾·GÕb´fn0s¨ö:_Š?´uÿÄB}/AšERLS]äå䃎¹8çž¹\\‹hRZèvÒÇnÑîPKg$–'$rGnœ÷â¸-;áýï†,b–ÊìÌÀ‚Ì™ œü#=@àú޹®ë¾)–êÝìo”‡…²àméœs¤ã9õíšû.8xr-.yxšÒ­.n‹¡‰)’ý^GMÀä3ŒqŒàgrz}3ÆhDv@Qä‰Ê’¿6YÈÈÀÇáŽùÏ+Ú»Rhî_ì jä~íÛ'Í^ã¦= ëÎk™×t™´ÈÏšw£‚U†vúc¯ôëô®·ÇBžÞ˜è>•ïàhiÎúœµªYZ¶¦Ñry“ËßÓ#ùì=G¥b¬»_ŒŽzjS–˜–èÜôäûR*e°2X„cõë_GË¢>f­WVWcF$Îà[ÜŸº?/óŠ#Ær•éÀÏôöü©ØÜJí\äôÏZUåîÀQÁ§Ö¨ÀES#rù##¿×üúÐ#ã  ¹4Ü›ÞrNÂÙÏøwëÿÖ¥·¯AÛ¦q×çü@ÿw/mÜdžß^´…, ‚sÔv÷¥ U7m'çm!aüY\zÐ1’*ˆø$íî;þêqN1†Ý^ÌIëÿêÿ i ·åùTdd?wÈAÇCÓw=¨;Ÿzgn8úc¯Ê…}¡€ÜzöÇ?þ¡F6åÒFIÏôÅ9‘Tî'ã8ù÷ CpÉbA$à?ÿVhÆícƒì)ÅGÈAÔàäsþ:>ð‚@ÎsÉô S€HÎW€)‰–`$r AéŸÂœ V!ŽsÎIûö4èä9·8ÁÆ)·Ò»8ýM0†Œ$ŒsÅ:dò˜rCLf,I'$Ôƒ¿Rݕ̢dŒ3`ð'½D÷S¬ë‰™N %FOOÒ`™—Í9ÙÌH¨ä”ɼŸ™O=9÷÷ëŸÊ’ø¤¡¸™¶`È~qÏ`}9¦i1¹ÝŠôRr>´²•@>`¤sÄŸÀÔf@C(ç=ªÒFnR{°# Æïjë>øŽMÅ:j<…mÚâ5'Óšå7†ÈàLúsS駘\ç&>»…L⥙¥9JM°Ÿµ¸.t;•¾gEùûUkÙõ -_E˜½ˆbGÌ=xí_,þͺ£]h:xù|Ø£Ž>rR¾©K/;ÃÒL’™$çàc×ĸZLú9¤šgÍ^½–ÃÆúœjïFW,Û€x{Žä ò2ké½Y–M*H–FÆÀ˜ UP`¨%²vŒ°äà.sÆF~ø«ñËÃ_üutÚ…­Ö·«È¦Xôk)L¬Ú$‘ò 0 ’NàÖo¿Œwñ]Á£_XøOO–³½¶›aîñåÉóà˹ˆm¬Ucû ª¦H=0ËëbW4U—vg‹­N+•jÏ×á$p[Úæ{©Ç”­°¯Àl£É…9êO íÖ±µ­;L¹³)u¥ßÏ$¬ _4‘n…A]ŰJƒ×AW·äσࢿ< 2ãÄ–)Ž4+öi1yG€2ç|¦M¼t#8úágü7J¸ccñ;A[{å‘£‹Zð¾Ÿ,Ús‚NÃ9ûB.Ý€`9,Ç*€ +eµéÆñŠví¯çú%åååÂq¾²kð<#ö²°°±ñÆ­–Ÿ¬XZ,ñÉk±qÞFR(Ä…öaT34Œ¸<£d`p(x7Ãßð“øP]Ûƒ$jÆÒI<¼…Ÿní„‘‚ÁNìÓ°kêÏÚ?á§…¾?xf_xWѼA-»$R^h·Ï9 ÆËbŠì€~ö2|ðoX¼øuñ6x†ÌIføGõÉfR_*lF–ê‚…ÊžQCpéÎ5)r­>‰EÚ3†º?Šl[L¸¸e‰£š?ÝOæ.NâÀnÆ0 àútñV¬|:Ú­¼ñ8e¹„(dÿT~nH'§çœ0í럼 &¿ypÐÛÚhwÖöÒ\O²2Xˆ@?êÚBí !þ]¥Ü·ÊKsçž¾›Lñ-¼Z„Ø´¯å¸¿Ô:¶'p$’0A'@àõé…W(]nsÔ‚[­¢Þè××öw‹¸.­ÞÖQ$;‰#"xFç°ÚzpšÅ»ÙyíÄ)3¤Îw!#iç$ôïøŒ×Ö¾:ðV•ªY&­§\Ü\*òíDШ$˜Šìæ<íç¯ uâ¼+Çþ ¹´FÕ _èLO$XfRHÆTô›¿œçÊ®mÚ fùJ!n¬lpNO#Œý{ש…Ò-yœ8ˆö+”`>eOÊ}ûÓK¬H€±|ÐãŸÄtëǽ=”¢…Áä`äuÿ8ÿj‚Ѿ…뎜~½kÐ8,Á³ò}·øÓ”–Ás§’i‘‚»ŽpØÈcÆ…`H% gwQþúÔ ÃXóœÞƒŸÖŠkª4K–ùGBÇúÑHDÁŸzŽrAÛô§ðÇc8cßÿ?ëQº4Rl‘ñØ…nŸNÔÏ™]HáG `sBؤ^³²–úá`‹ ±û äs^ýð[àÚM~—i$ÄŽCÇòŒúzž•æ_þjÿIçλ¿èw—ò£»î^6ªöéŠø©IÊW=ƹV§U èRM$rHÇoLc=«Ðô¿¢ŒarÞ¸;h/t·ýÛaü u®ßAñRG7?¸“§$úwôíZS…Þ§[™+£¡H–Î-˫׵rž"ñ¤P,§ÌDDÉ$œ{zS|Eã;H^Xb›÷…{ƒƒÇ ñÇZù“ã§ÅH<)¥Ï4÷ˆ‰ä³¶[àäñÏoóÖ½H§&£™E½Yæÿ¶WíáËt)â{»ÅaŽäÅLg8zôÏõ¯ˆü#àk¹ ß^;‹â|Ò¬ÊÅÎ[h,ì:öÏ~µÕB×~;×®½8ëôâ ÓÄ‘~턌ãQWåuÁÜÙ'‚2¸À%½WQ+=N'®¨¿s!‚É­Üeв€è§ÛûlÖ=î§—q<‹uúÇóåÆ%F0NAïÓ¿{éÚÌXº_*y2ÆSŒmì8=°yÖ±õ¬SÌ-ãŽU;S c`ARAßi8Çlçó®[ðì¶{ü耗p;gë‚qÏãøÕCú…•ô·Úb’&ùãxl‚F@lîÇš¹¢øêßU¿û6´DRÖ&šL“÷° t<·^çÓ5=%¡¥ÚÛc“)$ wî¶JŒ?B:{×mà?Š:¿…¦mͶRd0'§óÏó©u ‰DÆ9 ãÐ) >üõ'¶{×%œ–&%rÅߌ*°Ý»úšÊ¥8ÉrÉ]ÆvÕ;3î†ôoB‘]&Cû‘ÔŽ«èµ×øŠØÈÁ÷’¤!,0n¿Onµð †¥6“t“Àþ\±g8eÈ9ý ï~øú|EºV³2Á$+û»˜ø,H=@‘×ÓÜgå1yS¦Ü¨êŸN§µ‡Æ§hÔûÏøï¬Iuã;‹a3L€ýÛ—=AçƒËr:?&ÖÄH²‡èO${úµéž-ѧָÿ=©à€T„'žØ§OsoäHN[û¬O?òªŽUHU9^ÁO~+Ñõ>zÃæ@\àî9É9ê=ºÓ\ž1€ùyéÿÖãõ ´¸w$öéÿקˤÐusýÏ@@¸Ën;…Hçüâ—i*2|Æ €íHÊûF8ÇO~ÝéÊ%¹ÁÁ\àý?ùÐ*°vP2ããŒÒ™†â ŒòÌ1Ÿ¯åB ÚÁ nÛw*+€àò?Èÿ?ʀ܇ᔕÁóÿë 8Vû¡ƒ/˓ȤXÈ Ú˜Çéô¥VÁÀIašvAÞãsˆÇf ’iÒÚ¥N¯¨þƒÚ¢Ú#ÆK'¨ÿ…mäöéŠA`$•còýîqŽ î$d/¯§ÿ^¤Ý¼Œ°!GROøñÛòéQ7a¶àò3ŽŸ¯­1“'É´.A'Çü©­‚ØR>VûÙ#ŽG#¿åMP8m©ŸïÎÞ9Í=ð€Œî$äŠ}È¢Â”í €ÉèFHü{õ§£ÄÄ“ ãøKÿ< ¶<Ð1Ø þtÒùp‚1€)r®¥\±=üaÈã˜ãïØþ­WFŠ‘¼ÝG§ZV xÜ3ŽqÿëüiñA-Ô.\ù'û{š¶ÁvÈÙ™Xn«—ÐðGÆ? ü!‡@“\ÖŒ-i Àµ‚6™¶â}Ò9Å\øßÿÕE¤ZÂDŠ+c ½Ç‰uVyÖLŸÝA Š0L¼ØÉøˆÛ"¾ÐЧ’zSü©!$àއ£{× <¾”%Í'ÈœÕ¬I-ÄšÕÍÝÍÅÆ¡ªNÞl×7R4Ó\9þ'vÉcß$ö¡#ÚÂW˜ª rN0@Ç·Nã=©€†Bœ‚àrOqýO#§/•G'Ž0{téÇÞ:M+#“q ¼¨›ªº“•a·‚@äp{ò?…­ YQLJsÄ@@W?­LÊÛZF ÝW9Æx?\óéëQ5³*;¡f Æç¸n¸=±ëE¯¡%­]ñõu/ ëWú¤ñ‘%Þ“tö²H©Ã€ppÄŽ•éÞ"ý¥®<} -¯Ä i¾%Ömì– mwGÛ£êû†I4¡)B mAd¢’s»w”³ñáT"ô0 wÉçsíÃPC„ÞrN6œ8c§ž¿Oj穇¥Q§8꺚ӫR“½7cé_‡Ÿ´o…h7F¿Tz+2¬£Ë(§êŸèÑô…~!jÖW7 ovšÊÄÅù«2)²1'¨`g†=sVu vb+·±´´²Šì¹Ó¥Œ<2ÈË Ž¼·Ëœ6Õô¯œpÖÄL`häO=z“ØœŽ‡òÍZOjz}âÜ­Ü™cÁ•†AÄ3†=Ç÷®j™kR¼qÆAüJÇAâO \xwZ—bî…‰à6ß%\¦G\ß7°=1ZþÔNŸ,Bå []È äp@$ß,ù5ÊÛø¬\ÃåÍ6îpø GB1øtô‘Åt÷³Z[\ÈìÑÌ6Âd?xŽŸ6yéÈïëÅTã.UˆÞ2Ö ô»sõž§§Ü C$LdwBÆ;ä€gJÎ¹Ž ÝFñ¡UŽòd „Mì<»žÇ¯?Ã]R-^;xËÇè¿d‘îY†2Ãk£ ¤à¼ž&®_ðÝûʱCpÒ8ÂÜ/ÝÁ<ƒGËùúµy¼Ü­®¨UîÎÄðç̓:ÃgS ”eÄ»álÎ2GøçÎd„Ÿ•Þ©a€[¨ïïôãéÒk 5–«}y+¼’˶Ei²¤îè0yè¸ÁôÆqÓœ»¸g–v+ååˆ9ÚOÏžyõ×±F.)$`ÚÙ™òGµCm @#È8>ÈÒÀ³Ü)ffQÙïÀúWw¤Ê.¦‰Td·9ëXz¬kk¥?Î#t;V‚ò²ÄíÈ|Ç·+áë6îßSë)ÚöG¶ø[IG‚5•Áû›¾oʽoJHô»eòÈQ¡G$œW躑†U•Yyçµw¶þ'Y[ +0ã?Zó$ìTâäw/7 bá[¦rEr~1šâÛN’h÷G,`p½GL‘íÏzÕÓnšê âvëÊü£Ü~tÍf)/­$Y‚6·R?Úœ›ÖÇ3“tߌ÷w·š–£¨\GlblÞf#nPÎ6ñžzŽÜ×Éßþ#ê_ËÓž|ïâ'„ ´ÿHxUÔºhAU°ûÞàuìHÉ®â+«KDû]¼j€þò`ŒlI#ŒŒ}áQêÖñÏéU¥aJ€ “À<¶xϹ«•š°E´îy%†­âÜ%Ì;§´P~Y™Ê•ÁÃcŸºAŸA]v‡ãm Æ;-'Ûcq’¾K°Œº¼œdnÁp¹#&µf²‡Qí8ÞUZD•3‚¹Ï€:óÖ¸¯ü7Ó–ìOa$ö²†|À\®p»¶€76GsŸ¥`¢ãð³Gizš¾"ðœÖbg‰7Ä­µÝˆ*F”\;åwÜiެÈQ£äªbzµkHø©ibׯm@%¥˜–aÌ0ÎF‡Œ÷Jêu ;HÔ¬ïI“Ì™ã,c®¡‰<ðëÓš\ÊZ¥©iµ¹7…|kb.à]f1¹ ,áGȹã9?\õ=;WmñKÁºbøn fÕRh™Cï‰÷€ $އœç±Íx^©öAÌ‘ùNGréÁÁüë©Ñ¼ms{à÷ðåÌòyLHbc„±Ôž1»#ûÕåUÂóW…Hnž¾×âwB»7±æZ–šÏJAWPK*ðpÓ¯ÓÚ¹¹£IЧa^Ÿ&—½Ï—$EÈÎöî#è}þµÂøƒN’Îõå8X$%¤ûŒòk®¤,r½L1€p2võ9è}1ù~´›¶° œqŽ;ÿ‘R:ÿ¬1“’sÀäÔ…rÌ6·q*1€zιÈcbQµ„­Àä•?6=³ÆsDd»…+9^GOzcØÙèÀóô#?¡4åcaÀ‘“ó{P l˜÷Ôds“íøÒÉ€Á~î8ãüiê¸(å[W9¨Õd#~3ž#Œç×ñþt sª¼€…m 1Èõ?—åH„d„®0Gpýtýê#ýábáHP¸Á=N}ºûô¨ðåG;OpOOóþ4æ 2H ‘‘žGL?QQǹ¹'qÐàõâ!Hv|g€xõüóOi:F#%€Éö4Ð PNÕ< åˆëÓŠhRƒsŒõ8ïøý­;‚…C€;òM4)\ƒÈn¹¢à;¼ Ç#=1C8e<þþ”,fR±ÆI˜€¨9Üzs^õðCö5ñ¿ÅÙc¼ºµèŸÅ-ìrE,ƒ AŒ ‚‚} aZµ:æ¨ìiÓ•Gh#Áíb{«´³1áK1éÐI¯MðìùñÆ·ñÛi^ÖÒ99šŒ°À:s»õí_¤ÿbÏ|3|15›þ¿oÕbŠy”ó÷[ËOjú+Fð¶™j#XÑG@¡G¥|½|ù'j1ù³Ö§‚„Uê=|Ëtÿ‚xüo6ŸiŠëÁ«¾È.nD¿L1ŸÇäþ-ø+ñ;Â72o|:ñ,Vèûl\ÏàdÀú×íÌV;vîŒ Õ‡ÑaÔ x®£Iá~ N¡”ýAÏK;ÄßÞ³*t(¥§æ~ÚK‘ü…ÎT•8ÏëRT§w;ž¤Œ}s_©Ÿ´ßüËß4ù5ÿÛYxgÅ«¹³·mìn¾PtŽ2weFþóz׿?Œ<¯ü?ׯ4Oi—>§o##Cu Æè©Ç¾+ë°¸Êx•¦±çΟ.±wFT±‚Ñï#© Ó<~T(,Â5˜)Ü«’Ù$c=@ã ëØSÕŒªT,ƒœrpjÌL˜P*Ëœ«óqíÅwõ0mÛz©_ݱÜLã 嚉î#v;¼ÈËt^èÏ¿>ÕbâäÇm”œ—ÂäªõéÓò¡"YÓ’@uwáyÎ}:f«NbžåÆ5<Û¾N}º{Rà;v?ÀüyÏ÷ÈõÎr;™#,FÐŒX‚%^«Æ{s’WõõbR!@_-P»6ÑÁΟ4%­…bQ W’8Ú2Šäù»p0¾äýG<ŒÒ4Ù*øù|ÄË~?äãØ IPÄ’‰7Æ€‚Á9àñøþ^ÔÒé¶P¤Dàñó=ÿ)«¡+”4ÇcŒ¼õüi×$y*Á”|ÿ2í…<äç§oñ©Z5“ÎÎÜ’§rýÁÀÚ·<ý G$BXÙU+nRƒž8>üôúTìµÌ]§•Øän+ó×Ó®H˜£ •ÁÎX£ãÜOþ·Ðµæ,Qv‚[<í'8<úçùS%IJ"ef•ö¶0O¯LŸaM5m@‘ʱu’7 phÉçóÓðÍg•*À4DÁW»d}1ô>•jX©e˲aØ€=:Õ˜ç‘-< ÿ¹‘’Y‘óêû€ìç÷¨µÞ¡¹ŒÑIg‰<®Üôãð®“BÔ~Sl0Ö¸óÂ0åW¼sÈ'ÔšË >rOæý2~§µVðÝÌvúõƒœÌ€2>ín¼tã?L\˜ŠjQÐé¡W‘Û¹é6¸<7«4ê×1»’¬amŽxÞOrdc¸éÅ{¤:RxãKÄZ“jСpe” “pÀ*ä”vç¯$d×ÍzõÜ:eÍ›—ó<Ç,ë+Ș`ŽÇrõö5£á¿‰÷Þñ\LÓ<(W ~a«·?;oûÀœ)Œ‘Þ¾~¾¥H©ÓÜõ%R³z”üm§Üi$F)Àv ¨¹9ÈÀ÷äy®DÈ’ ]p@*3ƒÇ¿1áÖ¾ñ†•§üMÑßÄ:T çÂŦ²ˆ(1°M€$|„Ø;›wCÏÎÚ¾˜Ú5ìÖÒ[=”‘³Äö÷)å¼o»AÆÒ2>•ßÄF´yZÔâ¯y=}mÈcâA\ Äò8ÿ?çèà‘ÏÜ;°H Iì1øÿ…YdP’yR0àsœ÷ägÛÚˆedŽFܾo 3Üzõ¯JMÇSšœc=ŸäJ0HaÎrsžâœSc‚…ÍÁÆ6‘žÿÖ´M»³®×V~\rqÁÏãÀÏO­ :=qÆAúž~•æßWó3M¾õUÆÒr7Œt¢·í-É|ǘËÇÌ R?½¿*+7Y.†‘Â.æ '’Ú¾ƒø)ã$оÝY",rùÀ–ÝÔ—oÏñ¯ ‚ÆI‘q"•' rÞœŽÇ>«µÑµÒô»DIU£Só¢sózvïS‹Š©NÌÇ ¤Ûò>Žoµí¥¡q”1ù»úWk¡^ÄŠ²Eò@ͤ“Šð ßÐí»oEÚÊF?•ëÿ®£ñW‚ÅÅ»~ø0¹ìE|¥jMFì÷)´Ùë°ëN…<¹Á^¸ÇJëü?¬«ÖŸ4wGÎZZ[ƒ)’]·b“ÏpyéîEkÃ{Ž¢"g˜rŠÇž>SÈÏ^˜õê+™°[ ¬äB¶Aàõþu« ȆX°R(‘‹yN¡J¶3ÈVÀõàž¿—ÞÇkž‘½—É‘<…YafweXääíŒp9'<œòj͸ž1²MÒË&æÏÍŽ˜_”8ç¯ÿª©y™4XK–IÑž,¶TÄnf+ó ÝÏ¿Ný«ZÐ!×´¹7J$\©œz`§QÛ={þYÊÓ^¦Š] ŸxšÃÄ‘Gî¾gße8?0Ç òŒñ‘Ç>çWÚØj‚hÏ› À3ß¿QÇã\†¥á{½ïͶmÁã$}‚nøÇPO¯SáŸØ>Åx¨.d³Û¿\œg9Ç8æ°½ß,mm„×¥Y¿|¥šD䀃€<÷8äž§¿<ÑÔs­Xƃåp»™GCÇð3ÏzU½O΂iY–9{>#ÜHRß{ 1ïßðý¼w73F‘³ÓœsÐsÍVì­7Ôìf°¸!•¢Á  ~µNP€ØÚIÏãŽkÓüIáu0’í‚Ncb g õý+ήlÚÎá†ñŒÿwÿ?Ò¹gV'®¨¦ÁÆ2N@À-ÏÿœÜp§p8Éëíô¥àÙò¡cÇ$þ'ÿŸZn2pJޏàŸò+"G.»³c cœT`n~nàgüóÐþg¹b1Üý)SÏ’ z~´ÀQó¨àuíÅ?p8ÃU8<ñõÅE±N221ØN´¸dŽÅ! §?*ƒµºŽ™íÓó¤EÉ\sÁïI8çÒ‚BžIÀþTÆC3Ú·¼à-wâ.µ•áý>MBîB p«îXð+Ò¾þËž#øÝ~²ª6™¡FÀKy2œc8O_οNþ üÐ>é)c¢Z0£Ì”ƒºCêI?_μ,vi *p†²üŽú8W?zz#Å¿g/Ø‹Cøy-®«­¯ö׈ÙåLGùg >õö…áä· Ç„QŽ1[ .Æ$ã'ò®Š+/)W9¯ˆ«V®&§=GsÔu#MrÅYìtèãpê¿.0¥ª©ÉAVc²P¡†}jÌP‚2F­tCúž}J×(}‘Xð3íR¥©Eà¦jòD‘ §žh…èÝë¾8d–§;ªÞˆ†ÙoÍ×Ò¼cö¦ý—´/ÚGÁRÚ\F¶ž!µF“NÔW;£p­€F@+–èkÚD€ ˜š‚kÅŒmÜ:rIÎ+®Hѵ˜.nkÄþ}þ ø#Wøkã=[ÃZå»[êºdÆ)‡ÁáDZÖ/ž®;àsü äú³ù×ê¯üög°øµàÇñ‡‡à_øLt…ó” ¸xÜœwdWäÒLWA×­×ßükêp˜•ˆ…úõ °å³èÍO9v´ápT.úôëÛÿÔ‰w ÊKó#‚AëÔqÓƒïÒ laŠgiÜzîïõÈ1¹Juù†ÞÔý»îÌK’´¤äF±±uÿZ Žž¼^ŸZ’_1z2¹X£ ’¦3×ùr SyƒU<—çi=þcž¾½?:‰AW09ù_ÀϯòúPÂåÍÄì £8 Np@ç¡ÆG\t¥3¶Qw‚\‚áxûÿ^*»ÈŒˆv¦p ŽyÉ}{ûuíMŽHà—ÍZEÃH'ŒñÇ?XÑ™¼ÅQ¾MÄ Žü=nŒùÊ#¡.À’! ò=;¾þÙW»”¦A…þÓõçúz jÜaLŠÅ›vAb0ÇŽzsÔþ”´I‘F »\³|¸qÇ®}qÐv={Gç°$žù# çgéßë²O¤Ã¹‹).{kÝ|+ûäTÆ6†cœç¦kâ±]98ŸGÝ]µàõF—$„Ÿ˜ðs^©¤ê&ÔÇ ;Ààf¼_A,ˆªÅ»`úâ½?F(ñD²³y„g¯Jòe£Vã}YÝE$··ºäž渿éñÉbÑ\J‚2¹”``ƒÇ>À×s iìËå¡g‰!@Îp3ü«ÎõKñŸX»¹Õ®gÂ6ĤVÈP]ÛY‰R­ÈÁë[C_{cŽ3Jv[#à/ˆu¦âË›M>â« 0ÈbpÃîv•<“Óÿ­\ü–óBÛJ…ÚvïUÇp=:WÛ¿¾xQìZ]ÞÐG’F¥HÎ=ó_#x¯AÔ¼%|l.Æô^RQ›€O®85úW™CF__üÈÆa%Nõað¿À´AlŸ4"G c“ƒŒ p1÷LõjåõèÚ 8RÈ®…d) ð x9^£¦àbÝË5²ÀNAv0ÁÚéŠÐ²»ŽIRA“–õÝœÿ/òM} ìy-u$ß#£#J¢7A Æ<ç<ñ»×¯T/6ÙÀ¸¼Hw©\Ÿ”•=øÉ9ÆxôàzÝž8…—ËŒ3²˜BÝœ†ì{úƒïŠÉe†'ÜHE% 9#'œ“ÛŸçÞ…«@¬mÙM,¤I1vòFÕv<0n22:ð{gßÒå•ìV,è_ÉVQç4A8ã€Ý3œ÷Æx;sãɧ¯•n$JC2äq×r@Í ÒÃ+¬ÙP Bvä òœý ôõÍ5Ø›\Ó¸º–;¸ü” `AÛµ,v3ÇQ¼t'¨Z6ðk¶VßhG†éÑvJ2ªq×$sÉ\þœô®z8Æå$ÛåÆdXJ† Èàœg¡ÆCÒ§‚ï컃~ö=ä­µ€õõþñàúúU_[1X´—J•Ìg#î‚p¸zO\zôô‚m5dÔ\ÙÅ!I]AhÔfBp3Àäg#à “V¸—Éê‘%ÛM¹¡˜œm(@|¨78ëéšÅV»Ón¼Žb€«ÉPW׿"¦6kÝØz‹q¤%À1M“‘Œ©?!À#žzœW%¬ü>2JÓÙE³ òùm´“޽>¾½O¦k½ÓC¶aËŠ¥X×ñÝŸ\xàÔ«tg" S½ƒ0áN9öã×Ö†”ŠRhá´ÏÜ4'íq— ²7 ý?>­½7Kƒíq†’xð0ªzÙIéÁãŽÃ¯ZéoI‰n@:¿);yéÙX·ãÇ9ªv›·¢yÑ—ÍÆOnç>„~˜©µ´5Èu >9c0 9.ª:ôn§$sÓõ®GÄ~†XŠ»aÂnËdŽ $ƒŒõüzžk¼{Uv†èÁ, ÎIÁ,r{tÇAœŠÇº6ÉyO€Óœª‰Aù}&i[P‹<6òÖK;–ŠLo^ a’ €º²ç*ÃøˆüëÔ¼Cá´Õ¢y¤‘ÎÎxÀ8$töÍy•Õ³ÙLð¶‡Þtú}x®9Õ–ÑB*Œr@8¤iùN0xÏ1S´îNÄŽi,sœì+1!X¯¸=»iRǃØÒ2Aúæ·|àsâ±— Ù=åãðT0P©,@ìje%å'd8ÅÉÙ-LT‰§‘R4gv8 £$“_YþËß±…玮­uÿ[Ëk¤)W†Õ 0°È#¦ {—ìÕûi^ êÞ,·‡XÖVHfL¤ <äÀçö~…áØl¡…c‰!Š<,q¢€ª00+äqÙÂ’t°ïNÿäzô0ªŸ½Ssðg€,<9gocaa¥”*¤hcí^‰§iÑ"íØ@Í]µ²X²dHÀëZPZªvSØó_0©ÊRÔéT2Þ”làçf´"·tQ½2Ät©a·røb 6ãéV‚IòÊàsÎyõ¯N·<Ú•ØtJêJ±g®jCeãŒÕmì€ß½Î7zñéU¥Ôc(ß+àöú⻕HAj`¡);¢ä· l‘€:úb³.u/$037¯8¬ëÝe7œ¾ð£æ;qÎ=1\ÜúÀyU•ËÂA!ÁS®Œô(ᯫ:;ÝaÑ‚D>oq€+6mY¼·&Eio˜þ•ÌË®HÒ€dÜÀ×5^{ÖÛûÀ`t®_jå¯CÑ^‡Eý¥ Ð4Mó«©R ‚~½«ñ×ö½ø6~ |dÕ-m 1è:™kÝ1Ï÷p¾bÐívü˜WëwbØØÂœq‘ú×ËßðPßÃâƒqøžXÚ}GÃ2,–ì ±O<1H£'¡ÈnWךö2¬K¥Z1{=>óE$àÒ?4a ¨v™ã={sð§áUF\¾Àc>㿱ÇåLóüÄ‚3†ýü5,òÆÛŠ9 ;g8öþU÷g‚0“+’í³ƒÀ` lséןòRVR2»|óêOÏ¥™Äl|̪|¬ ±9ÆAèó2ÊÁ'œŸ§b„?~ØÀåI#Œ`ÈÎ1õü©¾~è㘙A8,þ‡ò¨µù•7:ïÆwmÈ#ŸÓŸÒD¤+JLE€Úù²qúdšw}Uf•X‘…pÉ${€I?þ¿¦|€áŽéß$ÿ‘ôÍ@DI6Bª»˜‚¬ìc¯ãSÇ"0;¬Ø¹^N9¢ì`Jeð #þ|ßPO©’Kó ¡vƒ°ägð>Ý;céQ¢J¶å ÿ* “ÀïÔuSþxšGYd`Frx~ƒ®3¯óì(ÈŠI*©´˜ @êÝ?ÎzÓL^HR6« çhÇ9äœúžiѨ6=¸FfÞ§p8ô:tçôâ£?–îGͤnÀ'ŠOk±z‰€Þ$•éÐv=sŸOjA(ŽET.FxÀgÐvþTŠò Œƒæ^I''?ç©öä ðI¿i8ÈÆìñþu7 Áܤ–Úƒƒ×õ©!òÕòWaSÁÛ¸þü¿Ç¥=¡1²|Ä’=ùðæ›y–ãÍe·Vs’?/~*­Ü:íeØsœ6€Æ:g'š…¡Ä¬¡w>2FAõÎ=ºþµi—È]²êAŽø‡ùÅBï»æÉËcÁöÏ~Ÿç4•‚˜â*O9$zg<Ž:ƒŠc¸Ã€éÜŽ£ñü?_zrdÄoçŒËúþtÄ•‰X÷„žXŽþýÏãýj[[ÿ,´”owdžëÔàãŸðªÓÂriÉãàuúcŽJ˜d*ìlŽçgÿ­Ö™)R ÉÎ>¹lçùRzî"³0g\±Á”ÐÑDçÊC’¬Ž}ÿýtT2=OéŒ WÍß·ïÅ;ÀŸ³OŒ´†Ôm!×¼K§É¤ØéòÌ«=ÌS2Ctñ)·— ÌÄ㔩e5ôƒ0¨¯ÆÛ/ö…öø·uy§Þüáé%Ó´D{PŒ`—“½‰ó^2AùA!Ê+'*Qæ–»F<Ìù¦ûOT¶­Êœùc·=O@=Ç\;ÅÞÒ£±Ç¶8þŸ•tú”$nÍÈÜ@0;ûcóÓ™¹$Œ€ò0tœûqÛß½u3­êzGÀÝhG4Ö Ÿ:HdB_B8c±Ï~õô‡‡u/³F îÇ9·ñç€oÿ²|Ug ÊFí´ã§==3Í}]¥9ñ\îRW€y {WÉæT­Rén{øJœÔ’ocÜ´ ¤’Î&VÚ ŒŒtàW¤øU'Ôom­là{Ë©ÎÔ†3ËOò“ÐIé^càÍZÏP±„¡•@`N; äWS§üb´¼·ð¤1_øëW)o§]ËS[é±ýü’.õpÅ3·†B–æyåÊÝ—s¾r’¢®ßõ÷Cê±Ã¥[]xSNnõ{À©­ÜÆ X-ÏPÑñÆ+ï8Ü™¼¶æh­aˆGmX¡…p6 ^À~Àü:³ohpXý²ãQ”¹’[«©šêâæBwovbY#æ'<­w1Ýù ;"ÞT³3 ú~~Õ.jOÝVKoë¿VûýÇžéû=7}ÿ¯ÀÊñ•Ñ‘L˜ŒäœšùóâçÂÛ/XL[$\²°ÎTãƒÔWÓļ…™¸ 8-\¾¯¢[ܯË2ž>•Ÿ´9ªvhê¥$×,µGæWŽ>êþ¹Íg,–ÁˆIÂŒϽrºcƳ!”‚ÿVÃíŒöïé_¢>1ðEµâ´2Ù¤ªãdwö¯—¾)~Ï×Q–ÿB‰2K=»ú`}kîrüî5š§ˆÑ÷èÏ3—¸®z:®Ç”<ȱŠGåt_Ÿ'ø‡B}±Ò˜9#òÊÆ « ã9Æ;œsY—‘β½Ü¬˜ ¸> p}=øÕvÅYÊV(>|à1 ‘Ç$œw$ãë_\¥}Qá5bAo-º¡\ÎFèÈäñÆ3œ{týišÎÔxÔ¬“• ìe#nO×ùwéVÖ ¯´äÄ»‹Ž;[Øp8úÖeíœÈeo1†Ca sµ¹#Ž $gg­6ôÔKRÜ3 äŽ@‘™g¥Œ›@ rH>äŸÇ«,š}ìqÈ$Š<¬¸ÜáˆhêFp3Ó‘Ï5—mÜm»ÎT‚zqÈúþMlC$æXÐD²M‚Ä.Êß{${§SЃK})èÈ®uOí; 4»±²»J±,Gnpnjº^¬³›-Ež'Ê̤mÛŒ¹ì;ÿZdv($óÉp¹pÚå™Çý©ƒq§¼3 gX£ÉÈ|Œà¹Ç˜JW¾èh¿»Ûݨv(bceådÞ§¯êkVß4ÂçrwŽÿÇ@®oOÕ7ªÁrÎdŠO–^OÊGϧò­‹—™Ì{ *rT ¬sôü‡ô§ ’}u,vŒË.ÅU;†àwœp}€'8ö¬¸›å’Hx^¾øééÇ?cÄ“}–ÁŠÑ}Ü»8È=¿N½¹˜Û£f ÃÙrsþ~¹£íXká¹b;¶Xã‡Êëß0’‘œôèxÏãNóF „)s¼’1ž¹É¦Êä,™Un0qÀÏ·Ò£Òì﵉ZYnåqŽËçéIÉFãI½ŠHŽ¿œ(ëïŸé\Ÿü$÷qËxH‘8+žO<ž¾õô/„ÿfox«Ëš[xtKl†ÿN,e=û⽿Áÿ±îha›[¹ºÖîvàÂp°gÝÆqìMx8œßAZR»ìµ=x*õ5å²ó?3´½'Rñ÷Ø´» ­BëþxYÀó?ýò žÕì~ ýŒ~)øµ£kŸK Y1 Üj/7_ùæ\7ò¯Ó ü/Ñ|(²G¢è:~š_{;d‰»ÿîk³°ðÃÝO¶C»Ž‡“_-_?žÔb—®§£ ºœ~7sῇßðNí#O’9|Q¨K¯3`˜"… AÓŒ¬‡=ëëÿ†t_éÉm£é±éöÀ°źõ%‰¯GÓü(¹ùŽâºý;EHJü¼Žp{ׇS‰ÆK÷’mÉÒ£SV1ô¯ÇnNð#õüëvÛN0Õ銽HÊÇhR£$`dSÕx?7>¼äÖ¡óGŸ*­‘Çh<Ð3·h¦$M¨2\nï\ÌÚÛÊ$ŒÈRzJÏÛ©v,3ØîÀ³©‰–ÈÚ8S ¾×_æÚ„p§ëŠÀÕu„ˆíVä‘ÇqÅ`O­7šä°=úóšÂ»×èÈ ™ÛÏšã•G'©éSèô:+ýy0À”ã“ÜÖ,š¿5`ŠÙëýkŸ¿Ô¼˜Â’ƒÆ[‚=ê¬S–W‘˜»Ê©â¡]»³²4ÔQ§.¦b J#ŒôlŒÇó¦Å¬Æ£Ÿ1yã¿Ö²­÷²Êzôâ­Ä¨d”‘Ø‚€ ÜÇŠ®Rݶ.Årò.AüDg?…Tø±áظ_!`É-òƒ´õíþò¡Ú‹æŽNÇ|qëÜâ-²7 vrG<{çn2ihÕ†P½÷ˆTÆG§ÓÞŠ•# ‘´í Š\ªZÑû%ûH~Ó:߇~ëöñ´šg‰¯Ql ¼Ó&h¥Œ;…‘ã åa`®¬ ³~T™B"¤c1  (\qìž8<`WÓŸ¶>´öÚž¦C3Ëmk½ÝÙ¶|̓‚s‘ó{8ùjævƒ.²!* }É€¼gž>§ÓÞ·”ch«A5¾¥+éd;©sµw3ß¡Î~¾Â±öo`ÊJ’p¸8ÏF{þ½êõäk"“&Ò3ü$áxé\ÒlGS„˱8“ÏŽ9úVoW¡Òf²Ë ‚dsÞŒƾ¨øâµï ZJH¤J®ÝNЋ“Œñæ¾Y¼Pãs ±Œ`‘ßšõ?€Ú⬷zT»8bÏ JCŒsÈãæ4¹éó.‡n|³åî{ä7ïlè–wF5š?³´ÆIËñ¯DøM§Å ¹Õ^#²¨ŠGÝEÊ;ŽO?Aøx®›­ ï¶Yù¡nDƉ';r!¶ôûߟã^Óá«”ÓRÚ¿è‘‚¤)À<`z÷éõ¯Œ¯Ud{ÔßV{ç†õ9-—düHŽd ’Äà|Ã~½‡Ðv¶k:† QÀ”äc@Ÿç^+£êí,ˆbêÄp Û¿ó¯Mðî¡*üÆÊ·`#Œ~½s^RVzФ^ç¡]ÊÆâ"Cy§%Ðôý?1¬çß¶4êYºcÚ—Je–6ß…V÷¥ºýOnxükiL3D ŸecÖµkš×8”ùt9]KEB•Iϧ5Çê¾¶pw[®OÞÈë^¬Öæá‰'å_“É5®i&ßݱ'Ó¥a%ɪ:éÕèÏ’þ.üÓ½+cáï†õ?ÜC¤xsM›Q½ŒþýUBEä±;sËuÀÎk)N4Ó”’4Qs²Š»#ÖçK#g!”ãœ/÷gôžáèb·THÊ¢Žpª=|†7ˆ¡ 8aUßw·Ý×ð=z9v‰ÖvòGÌÞý4»Öã_¿›TœæQ9 e{–Ç<ñô¯oðÇÃMC´XôÍ*×O ÐCR]í¦”#&ÒOf-[°é®’’±³Šù øìF)Þ¬›þ»l{…* ÷jÇ/o 1îE;º¶Ü×A†Ù"P˜É¸®ŠßKŠÚ9$-ò¨ùˆä/fÆÖ«_2º'îÇ,=EsªRv¹”ñŒh|>d‰#8ˆôÞƒ¶,|:°Çò$Îz~•·e¦ª…¾_Ö´bR•Fòãì¡üÀÌìrçC\î¡w,j )*ĶÓÖ¹¾ç|)¤ô5õ z6•È;q¸ïX—Ú7{µ“sy´Ñ*'ïAäztúZ ¿¹ÎI'gÐôaù×aæy}ÓØðxñŒþ"• ¡¨V`%eMر–ïÓ¿AÉÈ” Ø`1qžüóíô¦°Ø&ÞTüÀŽ8ädÜÓWÜŒB'ï’Ù둌ç9çÖ˜±˜Ð©ÁPNpNNÆn”ÇÝ(!@ÀÂŒ“»ž=xî8õ¤<¶T‚BÁqO§ÿZ€$Ýù¼Ç ¬FyàÂ3=Tà9;‡?¯ù5£0`¹-·ªLr8&Ÿ†Q–¶Aä ž¼ÿúé\ó!Ší ‘À9Çâ)ŒB.rn?Ç䯨 ûð@É8ÀÁÆGn}ª°Ê¶1$Œ?‡=zd}p?ô6ú ˆÍ “?w$åy2=ÁãÓ § Á¨~?‹>¹Èô#ò¨åsÈE9ÆÌ°n1Æq×ß§JR»8ËHÉ$ž}Ç<´kpQ*‘À'€y˜çòúT1>" Ÿ™øl€?:óÓÿ¬ü2£`—àóÏ»ûИ1¹m±ŒŒq–Žøô£"‚9 !ÁTä í9ÿ{‘ÐázàTAÔ;ðU·sžþ£#§åž”à.”d÷3ùÐñ3IeÑøÿ‘ùSdÈØcåb=½qì{…D¦0›‚ma† r;c×¶ivlîJ–ÜGCƒè;ôü}3Nìd,Ø‘È+t¢œá¶í ¡zªï­„{¿í¨iüV×' ±$FÐÝÄQ†3ïÓŽÕæ÷RH,De£v æLƒžN ôéZ(ÖWWñ ÕÐF†I\íœ6ãŽØü`ÉpT%„Gî¡Îsž}»VÒÕß¹QVIL†=¨Pž§epGù&™nUš\|¿yÑ÷rÃ<Oþ¶)Ç|[wd‘„ã±Çðâ«ÌÐH cBsÇ$gñíÒ³ÛÆ[— Ù*8zsþM3EÖŸB¾7hK¡Ê»ÈRA$}1ÅO4‰0B0¼pBñõÝùÖMÌA À] å r}éíYÔ2åcRq|Èú'ÖÏèzŒž|$¬w%]3Áã‘×ÿ×îÖ#½¶ËpÀýöã’M|©ð×Çë-Ý®™v#Š(mü”`0¥FÏ=qßé^½á |éz·’`a'+–úûûׯã0ò[î}-Ši8ŸIøfé ìÌ#V¨<צhú»Ýd6ÀÁaÀƼCÃúÒIaN0x»½Q¹Œ˜ÉÉäã?ç5ó“‡c±.mÏxеKX–'%¼ÅL¹—·åº{m#­uºn®×v° "A ÎxÏþB¼oAÕ±Š_™3÷È˽ÉãÒ»ýî;hЉ䕻Û$ÇÍ4ô9jÒJììåž 3ùó”þµKQŠf|)Àëò“M·¸Š`±•8aó1ߨ÷­ Ê®ÿ!=6î[;ɉYÜæ¯ífq‘¹¶ñÓƒXZŽÒ†ßÃØõë¿kA#’PžJtÅej¶Q—%P2Ž2ã>µÍ(½N¸T³<ËZÑĬQãi”ar¤s××­|õñ“ös·Ô,$Ô<=[j 6¨»Qºð®A¯©õHŠo½ºÃ æ°¥ OÎ7Øòk§ Œ«ƒŸ=&tÔ¥ ðåš?5oleÒå–Öî¶ž5Úñ0*Tú€yúT6+2(v ŒÍ‚£cÐçú×Úÿg½âßÚ­ÑìµÀ’H‚ª3×å'Ò°¬?bmìê÷:Ωò3±Œÿä:ýž…•4æÚ}šžª“QØøÊå¹IœÊçî7tçúSô¯^x›ËµÒ4;½MËÍendEÉÈ,@ÀZû÷òǂt“¦QÔäERb:ú¯ùâ½?Cø{¤hp…²ÓlìUº¥½ºGü”WŸˆâ:jêŒ/êuSËš·´—Ü|eð³ö<Ôî[í*»òôü«E¦Û;Œ‡Ü¸=«ëŸøMðÖŸo¦é–úu¬ µ"·ˆ 'N'Þ» -)!Þ01œâµRÆ4@Ñãw¾3_ŒÇâ1²ýëÓ·CÖ§Nh"¾›¤¤#c `ð@­jC§ª¶äù€ë¸ “þû"{¹lœ•ëZöq!›NQŽrÆŸ5®L¥b¬zhu û¹#®ßoj·aj¯.ÓòŸâµaµRv(ˆjÍ­€€‚3y‡&»éáïk#‚uôh†ÞÙÞEÂíS‘»Ï'çØÖ­Ÿ”¿3{œUˆâT@@ÛÇnƒŽ”õ(†1ÎM{ðñ‹¹åΫ–Âå:zúd“ìB9&¡{ÀÄò³ÖªËv;Î1ÎAàÖÒ©­ 6÷-И•éŽOZ̹A,/çmVÆrid‘ÚN08=j9e[î d–í^tå)=NèÇ—c6â(ž07íÚ2Çò¬¹lÆÛÔ‘÷•€­y-¦iÀq×S¤LF¡p@<‚9ü«žJûiÛc“¹Ó™W$ŸpG²Æ‚òI“’§!±]µìAÈ,…AõBed(Ú¤c§5•¬o»5XÖ >%_ÇŽµŸqáàÿ'—™±‘‘ÿÖ¯BáNväc®;ÕY­ApÁA|g8è=)Yjjª³Î$ð´ƒ6ç'üŠ®º•ÖÜŸ¼?‘â»Û¢Ñ1;P…<…JðÄáö*ŒNý öœt:["ºl%‰P¸ãÞ®CmæyÉ0å äG'ƒZ(̈âL ¶ãÔ“Ð}*í x<™~Ï6̰uØ0ÇŒmü4Ú¾£sl¨–—O¹¾müƒ;O½kXéÊÅNAÇ‘É5Z+Ö’mÀ®ÂrÛÆÓŽø­›KraV©?0ã‚*­}yÔ}Mm Ѱ1'®+¤±¶l–hÇÌpƒm`Ùþá##o#±ä»¬x€h:¡©Lû ²µ’åäÎ,jXçŸA]4âô8j6ÏÇ?ÛU¿íãŽAº”ö½yù$a^0¬¨ÌI>ý3íúþUÒ|KññwÄßkÏ!tÕu‹»Å|ó±åfÏcêk˜Ãq‚C8ô¯ÐiG’œW‘ãÍÞL’?•Ý™N>e<÷üÿúôñ‚UÊ–ä÷ÈÏåMˆ®8#k½yÏøSÌ®˜P8 äõ:ÔÌN0¤)~27`玿7r2 ¡Ù’Ná…)päìu$ý`)LŸuZ&‡ï÷½xÏÒŸKŒUr’ñJ[€ÿ6}3ÛÒƒ&å-ï“·¡ïßÖ¡Eb –P»F6ƒœçŸçN,‚ 0 ¼ò{S^`HJ|¡€H"ByÏ#üö¡Y™~ð<àŸ—ÿ­þ&£‘TçspÒoóÇÔÓ‹ ‚F8 žzñž?¯¥o@ü¸PÝJœtûŸÒžÌ„"RĆ8'ãƒPã̹ØFY“®sÞœÃj«S“Ô·#Oó©@5Ø`ÌìÈáºr_ΞÒç¦ãÐ~§ò¨Ãï% ØÆTõèÃüâ—ÊÜûÁ$äð½ õúS+m'+ŒÃq#üyþtâÊdä±nq‚3šb)Šr“Àã§_ë@+$h~`ÊIÊýïlš”1“8 ¤ðŸoÏ¿ãHw¬l»*£¦Nx¯§ÿZš\ Ú±È'ƒŒŠs¹íásüK× Æ PØ‘¶¸Î ·$ž0GéMÊyÙÞxsÐçüô¤$ Ú„åN{dœg?_þµ(±] ’2 ägúçÞªècÜïrV5Tu= þÊšW1ä°}ÖÏäwÿ=é$Š@ëpTa\œó€zJ@>m¬@Nv>ö1úÒ$›waB´€µsϽqÍ« ±m®Gñµh¦’}t×ì.n••÷™*8Áªâ×Ì`P 9Sßã>ÜTWm+'˜¹û¥™°Cq××­7Ì7 »Ñ¼´bòJñøZ¾¦„÷J‚ ‘?—xb~Q‚ÇÉúwíYÒǵÂùHhWà=?V§qUR­ùJœô#^¿ŸµAwn?y‰£Ê^ç×ñ?JÐEhYŠrÝ ‘õÿ>”“AÙÊ—bØóÜ ÓŒ[¨ár@Éõ5ŸÅÆæ+ùµfú2ÑFî×!¾n½øÏý?:ÏÌ/s$HÐNt;·Pzqÿë¯dð‰†±¦ÄD˜•O͌׎?ÙWfâx?äUíVm"ü0ÈÀÜ®E/i7:pÕ½”¬ögØÞ ñ’ÒÞ>SŒ“×Ú½—ÃzŽëdóŽžÇÜséSÆû·;᱌ƒÁÏ®Oáù×Ö6•>¦Äˆc(p¤ç8R0OùÍ@÷2±oÝ‚s€»‡Lt&³Þý]¾Yw|Ù,=0i#›FÉ9ôö¨m]Øj=ËÍvÑ3ùƒrÄqø~µX1wiìwÒ³"º““æ.$ãð©¡¿e%Üïnƒ•+Þ4嶆˜•¤Q’¨§b¶åƒ†jÊ›V)+1¸Ry©Ë¬!gÉùHÁ9éMï©\Œº—«u'ŒMS»¼$ í'¡ö¬kÍUQp®HµÏê~"òÔÞZãûÃ¥G-ËäÔØ{¶ fÈìJÈÕµhÕKŽª?•rº§À9ãŒú}kÏ5ï‰p¤‡tƒ`+»¯ãZB“Õ¨>§¢\ø ±$pSŸ^ÕFO¤W çÜä3 Žÿ=ëçý{ãuĉËÂ2¸ÜOOZóûÏÚƒ6ð¤u+ŽœœóÛ޺ᅔ¶[â±cñLVÒÊÎp3SÞº'Ä)zØi©ϵ|9áŒ÷zΰ‘…/!#6UkékDF•²€ÑR“Žç<¢­cÞlï„(ª¸' ŠóÛâ$^ý›¼i31Ž÷S´:]²“Ëȉˆú+øWS¥]4ÁÛqèí_ÁC~6Âgã›Ø\l<;—¹ ²\H¨Øãû£×¹®Œ V®—Dy•ÚŠ>FUÂŒåˆèsÎi‘À*8àŒóD…X`sLpi‘Œñ´»“Ç×Üù;$Úd!òrÀdŒsùõïI¹·³vïôϧÿ¯­ -•ïÆzõöü:RJAw°[§·lSh°®† §‚9ü)ÑûÜœ†^?!Hœ²³‚IÀ/\ôÀÅ5Î@b«´ g‡ÛôüzÒÂ>s&ÝÙ “¿q<ñÔÿœJiÉó’ÌrÀÃùÿ*IQ—mÊpT…ÁôéèiWkmã=8Q×ÿ¯EÀ•ö9ùpI#Ž¿—JL!Nâ§û§=»Ÿóژ˵¸$ðÇ'°ÿ͸sÔ“Ççùû~tu2#<¿™Ø¤_óí@;CrÀàã=ùâœ~v,ÎsÉþ¤Ó27.FF?‡aßÿ¬(²ç9ÆÂzõÿZRåYòîÍ5¿x ’§=_ ð{ÒdàáW%x qƒÏ·Óó¤2I ï€?…XaI÷§I&s:ça@çÒºo…? õ;Ó†’6@ç͇Ìf)*G—Ó‘ƒÉÿëñQ0ÂðÀuÁü:~Ÿ­  # mê8ÆrMÐKs¸€½J nh¥{Ü$a̤¾pÎGOËŽF{zTV¬¨~d†Bß(ì3Ïѥȷ0 ù­U€úÓ¢#íe[ ¥Tõ· ÷Çã[vf„òU›~âFzçß×§O^Ùå¹Þ7ÀÎCîÝøŸóéN¹óÑ%òÁŒàUÉÎáú`Ôq“q)(Š)ù}ÿ^yçÞÂÅG„í*ŽóÎAçŽ>¼ýqP Œö›p¹FÛÁÉÚ:÷íǽY•GžIfdEÉp0HÏáéT› Ò`€¬rn1þ@ïY»"JÒ!Pr@# oóþcF0FI<õª{–V0UsÉÁ>§€ëÃÇ8ýJÍîIÑøKÄÒi·j…ÈR{{×Ö?<^·ª†@\ƒ»·ñOÌ áGB:× ü4ñåÆªCNÊIðÏÒ¼ŒvÚÁ¸î{¦x˜ªÊŸÀAäuïøÓî.aŠBw,dž0§Œr‡éQ]j¶PF²w¨<ÛÇøÖŠŒVŒ®i6^³Ò4dîàr¸úŒ•8íÛÐÕ°è¸%Õ˜œnAÿþµs—^&Ú¥ÖG û¼àFñ“šÃÔ<]öyw‰nYº¯NÕ¯½ñ^júü¥ÚBÊž”ô×Ô#1RyÇ^>¸¨wfžÉ#¹—_2:Ä&â3!î=ª6Õ›#Ë]ülÛ´?ýn~µÆÚê ’1¸©ã=¿J¶5–O0Íòžê0ú Z¦_*Gi¨Dl±ÊÙþ/Æ­Ûê ±íæÍžÕÅj,.Û%$ŒqŠu| Äp~µ\­lc(_c±‹RFFv¶z5"jr@ÌÒ8 Ø×)5Ø´‘d$·Þ§ad;Ì›qÕqÔP¢Èå:ƒv®ÙówÈâ©>ªáÙAÜ9À1LÄ7’¡¶Æ»wcžÝóœÖѤô¹¼c¡ê7þ.H̾d© |¸$öçüñ^â/ˆ1ÃÄLy?¼f8ôü«Ãüañ–7³~ù£ÀB·™Üd¯àæ¼sÄÿµ A%I.(QðW’FyÎ9íÐW\0³˜¥Ë[=»Æ?–кA1e^UÁ9ÏRÏ ?Ö¼7Ç'$ù·"(ú¬hI.¤d^ý±^Y­øÊúæì¤24j n ç ò8ëïÔzW8 gc!g“Œ—9fêO­{Ôp޲/øºm[Q™üœ´vVEÃ-´||£dôÉÆMqÃ;&WàœÍ{˜,*ÃC_‰îxUêûIi°#ï 2É»’TüÃ8éJP£Al†ç='aéL•¶m!ˆænx g ïN’»ž9Æxÿ=ý«»s”wf‘²£?y†NFN? ŠIy Œ/?(8Ü|®H8$ƒÔw_ò)ç•c’å}Gù÷ÿëÓÙÜ[w9ú©¨ 8òÑ[vNü? s¦ø¾D;1?wÔã=ñEÃ1rr@0x÷õ¡÷`"í‘›cÓ'ã=?À{RÿK`žõϧ\Ó<¼€@(À}æ;þlõééÅ<>Òœ.1ìÇþ¿åÚ˜ Ó †p Æ}9úQ¨\‚8àŽ;ÿž´Ñy¦2‚)¶à¿1Z]ÆexÎ d;Љ6å¦[òÇ‘"]ÅWr†!ÎsΡ¦+yRabÃn7d}h}‰Æ¡ûŠ?OÃŒcßÚ¤¸*êFà>rxçùÿJÒ0\²®$‘€1ž¿‡ùôfì‚g=<ÿ“_A~Åß!øïñ·Nµ¿Û?‡ô%VÔbdÊÝ*Ê¢;có–C¸’3ò£ |Ù¨©QS‹œ¶EÂ.nÈûwþ Íû7CðËá•¯Žµ»8_ÄÞ(ŒO¡A–ÛNtW†U,ß¼që´¹_qÇ0HÎQŠâ§žçF²EÒ­|ùîû$EcPÇð§µd\|^ôÙêÁí®u•#”º!Sýð¸ü éÍ|‹Å§'9îþ#ÚxYÍF0WHÈý£üH,~ø©-‘dŸûõ¥(Œ@ù'Ÿ¯N@ô¯Â@[tÈQ…ÎyÇO§Zýrý²¾3Xø{ö|ñ½–Ø®µ;í%¸ wxÝP㳑¨ÜM~F¢²¢ @ c§°â½Ì¹óAϹˌ³QƒérRUÑÕb(€m'F=1ÓöÎB‰;NÓÀ/*=Î>µ©.˜n$ñ»ž{þTAó°5 À6I_Ã߃^½Ï0 ÛAÝ0Fi…T`¯¿$Ê¡YvÉé¿<÷ëøÆ9U·JèW;0 ääq’}a×Óš*€RsÎI'ùQJý€ßu–Þá“ÈÈ£0ä··ëBܘ§t‘ð¸ÁsÓ=1šë~0h1xOâ>£c1‚!H2/ uÁ9ÆO=«“¾e¼,Œ¬ÛIÆr=AéÏçÅÅÝs#Y.VÑ$8È,±»a¿zÈÁÝÇãרQæ£3@N 6p0N3ëTwŸ“$m8 óØ{ûÑ4„wr‡9SÀÇáü½+E.¤Ü°ááe$†üAé×>ù¨/QLÛ]ÊF7Ž>•?Ú‹®íÆMÇ–bNÿ© ŸóØõ„BZOŸå#qNN?hÑ¡3=âQó0ä­ÁéŽôÐ|´B`üÄ8ÆF?Ô·‘¬R“¸c‚ àƒž¿çó¨X']§ nïô¬‰"#%™Îð¸àø¤SåK•àŽA=Kp›IÏלŽqϧùÈ_'+͜㟠üêZºÛB|øÍ¼ó•8+Ÿ½÷½«êß x¥|…É ÇÊI÷9í_šÚ^¡u¤Ý¥Ìy”ó×Óÿ¯_\üø‹mâ-•Çê~9–à!ç¡Åj©»ÜçTîýä{tßmevIg@>PÀãóÅS½ñª_Z4 po`yÁéï^!>¯uzäòÓôë¹ão½’ÃŒž•jªqG©‹àRyÕÙ†Çä §w¬4‚'K¡òçt[A$zzþ5ÃGº\¹ÝíM‚áb¼yS!ÜÙ44l­Ðë/µÛ™Dq([ï/~8¦.¢Å¾øö¬|váG+ÆM$—/"† ªã‡ÓµR‚/¥Ž‘îž8ü·aƒœ:Õ2“ž}êœÚ”RÙ² 6FF9uTI8“ ŒñÓÿ×C‹Z"Tš4v$‹av“Øš™¤ÀTzpsT!Ôadbîå3’Ož5÷k…ìHþµìK5ùL$ÁÁàäô5yn<”`dds\äÚš Ï•Œ¶H¬ñâ%sÛÊð=*Õ1Zçi$ꯕcæúc¥$wÆÝXÊA|×sâñª› x¬»¿*ìÇny\ÖŠ”´D´úž™'ˆ¢ˆž§<*É»ñŒK$ ?AÆsÛ¸¯"Õ<|±HY%U=·£ó®+Xøœ Ø’üî?ƒ“øWHJ=žûÆë ,¤óÉ œzâ¸sâUº±J¢4uÎ:ãùׄx‹âÃ0‘`%Æy‰ç¼W›kž<šâMÏp!ÆxÉ9ïŒgõæ»iáäÂSŒug¶ø£ã6ë?“"¸q–PÞ¸ù¶ž3ÜW’ø‹â,×°·™r Á ™lä€õÈ?\ôÅy¥ßŠ&¹`"Iã{uügÈd™ÃI)waœœ dãõŸzTðŠ*ò8jcc´5: GÅ×”‹$LÛ䌫“ŽŒzãoãYÑ[ÍqtKƒ)?ǹA9ÀÎ=3øcŠH­‰H*J†uçwáéÏõ­˜L@„2®‚¸ãœOæÉèmGHž\êN¦³g#âTC¬O`Áv¨ ÐcÛüô¬À¬P–;Ø‘œ cާü÷«—óý³PšBÛl†ÆâW<sŒ{qÆ*¦yaÆyôÏJïŠÑ\ò嬛@ÙƒÈÎiñ‚À¡ãÜÓ~a»·~MH0ÉnÇ5~¢G}àŠgÀÚLñCj.®ßý[ïÛ°äqƒž¢¹¯øÏWñ¾¤.µ[ƒ<ÀmPUT çŒ=zÖ1([îOcÓ¥49gåLÖj”#.dµf²©)+6+·/ÎOfÇôãùЖN¸¥¶;qÏ>¸éþ}é6ùnw~ó<…ùçóç+Tf w‡Wàíƒß4︡ƒ£ u9àçó¥2°ÜeÈéMnÓ¼€€Aô—OçCHB.Ô¤}ãÛŸóùÒQŽ{öÎóÅ*ägæÛÔüÃ$cŽŸA›¸ r3ÎqçéNãì"àœîç§óü©­ º‚¥¹Ã¶_Ε˜£dq“Ž;Ô†M›Xíulñùæ€#1 °!˜I\r:c#ü;b”JGÈA @9=AÏ~ÿŸµ5 0;Ý89ÁÎ}~œÒ’Ì®O¦8=sÖû®Ñ:åqž…Gù÷ühM¹¾PyÚ£$‘Ï_Ãð¦È…£ÉÉÏëú~tç,çæyÉ_NãéÛó¤&KEÀÎÿNhGܪ@Ãpvý?ȧaF‚rª;äñþ¦3ùР<äü§µ'¨!¶°ùÇ#<OÿZ¿U¿àšÿ[Á¿´oYVÿÄ aQÀɶa¶ Çø€§çà €Oåm¦—{®^[ézT6£w*Û@ˆ¤–‘Ûh8Áã‘ôÁöÇïg¼e¢øZÊÊ<$vÈ"„Dû<¨À@@íøWšÕå„i®¿§üÒÁ¥ÌäúuÌ–ÈQbœå›0cèOøúך|Xñ ¾…ws&©)Ì[%µ"R$§ÎYëÓ“Ôf»ˆú®ŸáÿÝ^joê ½ùo Å÷qûÅ ‚O 9Åž-Ñu«Ë^ïR¼Õ¦”–ho'ó$A÷@Î~\`~ ð¡ JV½¿¯ëô=jNõ:=þÝ_­¼G¬hÞµ—ÍHU.å Ÿ”å€+ôè{W˰‘ã/ùÿ<×OñÅö>7ø…ªêúcÈté|¸-Œ«µŠ"*“Á<ósÐ×(¤®rØÎOËÇ'ôö¸xû:i&§´ªØü€® Ý1þM4lÛ0¼w¤Ê…lç$sÔýiKdª’¼óÛÖ·9IS •Ú£#är^µ¹Úù\ª±sŽ;ûuúRd’F9R~üw£b· “·žÝ3Ÿñ ù˜/ÜÃ1þM@ùp:c }{ÑHG¾þ×VIÅDvñÚ¤±£ªK.f"Ÿå^ààíÐyG—çÃ4hå6Ž œà;wúW¿þÛgÙ¼]¥Ê#xÄèÊJIŒ¾Èþòcòž§¾p3óÞ“,R"¨•fË^=N9¥…kÙ£zŸ)1‘$Á=KƒÁ>¹¤(ެGÞè~`?—øUÍOOdS9cÛ–ùOLã¼þ'ðªQäFà’¹ÁÇùÿ„úzÿ‘L‹Æk3mipѾҬãžøŽÕóÛøüçÎ6ó»ä²(| ry9éÐ{ úÔ3|GºŠ8ÕæRå* ‰<’½@ëùûSú»¸ùÑôjxÊ$ŒI(3ÑœûÊ'~Í6¶3žŸ-|¿/Ä n J$fË|‘†(Î08ü}…T¹ñüí®\;ÞÝ=ÿ23ƒÅ}^LŽs鯈H‘,ªy8RIë×õ“yñJX‰›ËežGõéÜuôóeߎ'hž1r»X]¹{Œ{öç­Q»×n.g{bf‘â}®YËàŒŽ dwíëZÃ)m©¯üL÷kß‹ ²±itFsŒmí’?æµo‹ò4OåÈ ûÇ+Ç äþUåî®ÎöfV¶ìóßÓ=¿Z˜X¤Åä¹–Ftaªgc·ô®èe²})ãéGmNƒSø‘qy(1Ü Ç*¸bsùwät¬'Öµe‰˜F$v úŒsS¤Pôq‚Ûq-œ2þ4\6¸*ìǨÎî¹=}þ•èSÀÓ‚÷™çO0›Ò Ç â=ré.¤·Fا£FÇ'=³Ÿþ½sþo˜ÛØÉÓçmÇÞ¶üiòßî*FîI }îÿþ®Ø¬,*z„óýkNHÃDyõ*N£¼Ë11^[jðNzcñ÷«kTƒ”, Žƒ}zñøö¬ÛHrë¼§Œmܯשÿ&º="7¶–ÝâÂ"Ei!NàwŒqê}½s\õecZ{\± aYB¹Æ>\ŒuÎ?Né÷—­iiq %$òÎ?x û’9äþºÓšO(8fiv»6AÇ]¹ùˆïíšËñ%æ”ìÛÊ#°È$ž¾ù®X®i$T•ÎgÌ«¸7‘Ç·ãýO­¶ ·hù³³“Àëê8¡×i$•ô?ç4ÝÊW®¹ `ü¬Oõõÿ=zÒ„Æ0Ê9ù:óëëHIP;Gq»Ÿÿª¡eÂ2£€qó`äcÓÿÕɧ7™4`i1ó/oǦ}ÿýty„ïdôÇɤ2¬6°¤‡ÿª˜@ó†>_AïN`_‚:÷çŽy¨v²`ùk“žsŸN´*Æ«·k:dƒ’1Îi­;x/|äŸ^¿ÐS°EÁr3œrE5p ýqšs1(qÆÜCôüÿ_­)!7p¶Ð¶1Û§ëHíÁËd‚qœzÒ:‚0zzœtÿ?ôä¸ ÞNØ]ûsžãœCïšRÂ0sòãt©ì¤G÷Ï#Œ{â½£öLý˜uoÚoâöW™q¦øOMTŸ[Õ­Ê !F åEcÌ’4l¹ÁnpÎ¥XÒ‹œÞˆµ'dz·üsöxÔ>(üQÿ„öîÝáð×…\”yâÄw÷rG"MÀ«òYˆ «ëõºÏF†¬¡ Ž@ü~•“àhŸ|1§øwÚT6…§Æ"µ±µc‰rIã©%‰bÇ–$’I&ºŸ4cåm§¥|jßY›©-OCµ9R">Ký¸üzº†m¼;ž]Þ©" «6Ç1)làƒ2½2;ý+óçãÆÇÑ´øG´(-í¯JÜ]Û^ùXrÁ ‘ǽ}ûux®MÇ—Úã±– 6Pª²–ÞW޼ÀtÇ|×çMÌój3Ëszí,ó6ù€K^˜®Ì¿ª/i4wb«:4ã½HÆ6¨ ÀéëôíÿU¤I=ºÈÿOñ¤S¸´*uOáEjøbÝ®5@àŒíÔsÓ'¥ÍV¯,¬G†UaÌϬn}Í]÷ fšA.T®v+¨ Ÿ“±ìkäÈn^…i7;;e‹ç'œwb6‘Œä“ú/ù黆 éÐßvá´óÉÏ=º~t°¶ÓÈà|ÀøsúÓå0ÁÜãÆGcQ¹>¤ŸóÖ¡’Jï!—rº®î‡Œ}xîj  Er¾a Îî¹ëVc‰7+…Ü8=OojŽå>~27{ž‡ëGA©)åÉc!†%X6zƒþôgÁß²&o§êS"\[(Nâ¸äœ·=†}Aé_9+ f †Ryú~„sN ñM¾)&á—¨Ÿž8ú×5Z*ª³:pø‡BWè}ÍiñFÞh„‰2¸Þ×`äàçŸÇéŠç|KñONŠf /™ ãnå`0OmÕòŒ~7Ô‘ ‘¤’…²ÎyÏ|Ê “Å—²°Œ–;ÏSÎkÏú¥sÝy+ãª|PŠyÜÇ3œeq»ßëÓŸÒ¹«¿N[BŽ0IÉôï×ükËŽ¹rãåX€ÎAÁ9ëמ{P5Û¢>B¶íÊN8é[G c'˜Áž‡/‰ç;€qŽHΫ·ˆÜ€¾îqšóÙ¯®åmíq*àtFéÅFÒÎùÝpåF ËóØÖ«a,ÅtG¡Ýk‘ÆYÅ¢ñ…•±ŸóþR_ÛGlÙ¼(,\3~Ÿ\× µdP –EÏ<ùþ¥×hã§OãÒ«ØDÁæÈë$ñ­²H»VêB‚ª3Ó¯${þu]¼^²>#ÑKdnã÷äû~F¹´@æù°G_cÏùÿ!»Nó¹ƒà~½ÏéïWì`Œ~»Yõ6fñeñM±GBI+ßãQ¿Š/e^|”Æ9Ï÷¹ïïY±Íò†üsý)7*ºç‚1òçŒþ5jœCˆ­-äÉ俽4yp¬ÄLc¸éúúë¶ÒN—Ä8¥F6îëôê?k‚v;r¨á½1Çõ®NÕC¼ïC°F ‘·<8éÈÖôùS2ç“Ý‹-ÄWz¤ó«2ÇQBòžÇžƒ'Ÿ¨­Ï &Í×.‘Ê y‹¿,sœ†È<~9çÞ¹KTýÆÐpe`¹cõôï’>ƒÒº½Ó• 0À( àcü~µ´uzŒ¹ò¹ax÷l ôù@#žþ•=Á/!!LnNH8Èç·Ðþí“YHñI ±Ü”ádÚ8\ô>Ç>úS¦¸–qÈÊ짆#¹$ŽO“õ­5µ˜‰#‘ÃáôÎpW9ê>½:U‡h›f䃃ÀÀxã$`©á£bOÞ‘íì}ÈëBúVNz¦;Ïj`sþ4LPHx6OÌ}¾œ~µÊ,>f<µÃgÇzZï™Àîzs\µ–Ÿ$lêÊâBC¡•Àäã‘Ï;yׯÁUò½M#erM6Ûc+ÜBõSóg=xô8út­ëxÆ™pc-óré•'°íè{j¾žŒ›¶“Œ’qÓÐßРв´{É’FLŒd+p28Ï\sÿëçÌ©;êtÅtDºt——"8ËÉ• ¸Ë<àÆ3ÛùV/mþǪEkFæ`ŽÙ'kî#Ü¿­{¿…¼&š>¥næ;8Lò: o‘9àdç ~žµólj5T×¼Aªj3IíÌ—Jã ÌHdápG8Ï^”°Òö•["«ÅS§n¬Ï•ÆÆÂÝà öæO0íR è9çÿ×Q—;°HV‡§Ðö¥#Ë%ƒc€>_ƽCÌÜ>é$þ]:þt°2¢Ë¹rÀ\œu=)dHÃq€OáéøÑ9•€ Ž3œçlÕ"„sæT܃Çä?­#ŸvÐsÉ9Ç'‘Lr€w|£;?ŸiÀyç,T¹ÏÊzœÒT`ò7?‘Ε*„–T]Á} 8qÎ{SF6õ98Æâ3úþ¡cu 8çמ¸üéê®÷$ÞYÄŒj˜ñ·ð#¯ëJTPÛ·p=?Nô6É#Ê»4Šwgœ~•™—'‚Ÿ×òë@ ª®CµÈqb9çüHÿõRío(<ÍÇ,sú*f~l+Éê ÿëÔ‘Hc‘ò“©œžçñýhÜDjÌ|ÅŸ˜G'ÓúŠv>GAòîûÄ€ óÆ:j¨P>ñ䌊I“{#Éà¿N¸j2Iq,AÞÃÇSóü©‹0V Œ•ÇQœs˵9IùÝ›¹ïëùT[O˜¯€»Ž>cËzÿ1OÌ™`B· óþ}hUi“ny?7Ìpq×—osA`…€@ä cŽ àû SCžÿ2s;wÿ<ö¥ê¿¡è÷~%×tíM…©©O…œ6i$kß$³Å~ÜþÉ¿¬~|'Ò<= ´0jw¼–ø+=ùDÒÚ¥—# Xgh¯‡ÿàš³TÞ,ñ$Ÿ¼Cie>cæÚé·³N/U ‘/#hTVuGîÎ:f¿P!ÓͼXŒ ÀÁÏòy–'ÚOÙCe¿¯üÓ¡]îÍ;£¨*̼䑊ç|W© XCˆâ\’]±Ûùuü«f Ë.v„ù™\çåÎsïÐ×Ï¿´gÄôðñû ™Cˆ‹”aÁÎàrsŒŽ©í^\¤åh®§f Ôô>(ý¾|C¤·vÐ;F²ÜÆd‚³¨vlœuPGÔÕñB«ìuv8<“5ïŸ5»¿¥õÔjòÊ…eòœdºƒƒ·“ÀôúW€ ÑŸ™Ž:àž¾™üëë²øòÐå8³ k_Ëõcƒ2©^Jœä‘Î=¿ yeEÀbÄwt c§×„gh?yóÓüäRˆ‘wTžryäŽç¡©!ŒFB€(` ã¦sßÔàþµ[frKyê8ÿ>Ôì1îÊ$'ÎsüºÒ!wVùKœc ŽAãù~}ê6›aÉtˆ!ÎsŽ)ö—‰#¸†`áøe‰Çsßñ…äu^´E·’WBþg]«ó‘ÛŽÿ{ÑWt…K$Œ"EŒ{ž”W™9.g©ô´£ìà£Øû—ö±¸{ï„·ÖéÏnë †ÈS"d&7dœãžïÇçµÀ^Shlãi$+íïÞ1†ï¬£'÷±ò#`IÀO¾9ô?‰ïK3dÆW\ Ÿðü½=k¿ü>UÐðgݒ鳫º4Øb9$Žø?‰üëSQ‰Z! Ü|ÑBäääãwlð}?\sÚ}Ã$¥wH%º1=sÇN•Ò%ÇŸn¨&ýæ74c*Ä`òFzžB+¶¡‘Ïέ €¨'<{€r9í×Þ¢‘q¬¬¤ËŒsŒtüêþ¡ Dã € ÉQ¹}°qÆ*ˆÃ#`îPI NNGô¬ÚÖÁb´ÃgÌp§ žÆ§µ˜H@^¤Œä7§~¿Ö£o•NH9ã ãü>•â3!l?)÷Çòÿëæ§¨‹RmEE8à ã‡×ógùœUwäí8$pqÎjͽǚ íÜrI8?n¿õ êXíEm¤eJààœþTÞ¨BÙDËà )´—`Ç\ý Is¡F 5V L$î;ÿÖµnÄl€ÂU‡UÝŒo_Ã' ôàZ¢º-òev‚ÝÁ÷þU`v’½õéþ ›Ëûã’@äƒ×ß×üôNŒå}r8Æ{sÏ^jFä¾ÀÎ>L¨ÎÁ;¿ÇÿÔJ1ç$ñÖ‘K*ƒÔž¸ëŸÃüšVäT3»¯>”„17rqõþ˜p娽Øu8ÇZ^T)#rž£îÿž´ñ¸IÈ ‘Œû`û拌7¶CHç#¯PGþªh(s8Âr@úŸóÍ9ÔÇBªã8Þåôã§Ja€ø8Ç<ð:úúè¾hR̪ÊO]Ø?Lšj‚Aàð ÿëÔ¶öÏ"³…ÚÃ8ÝÁÿRŧK#`! ö#ß§<ÿŸJi1Ø‚F 0x'¨ †bFÜ1ÈÁéœõÇONÄÕäÒn˜ª„b­Œ€9ÿ?â*h´+©”ª©ËGSéŸóýiò¾Ã³2Jy$FG÷xÇëþ4¤CîcÜŒ?Ò Á±åI#±'§@*H¼=4²}ÿ21’UyüÏ­>FfQ,°ÝÏ=©Ñd¾Ö8VÀ8úúsÞ®ÜiSÀä8:|ÍàäÕf•˜0ÍË2üÇ>þ‡ñíQkÇIkÜL#ÚvÆ mÀ€:sïÇ9â·£·û(Y" aIŒ’É?OÖ±ô9DöhV]®0 ¾0¸Éz¯¨âºù" ŒÅò Ÿ\öãž¿O­uE{¥1—+-¸B›ze”mýr9æˆ#{Œ(frÞ2½I˜Î)U£4%Ûa9 ˜Ç¯,1úúR™ŠÄd 9倎¿Ç_j­FL"eC¼|ˆn7(Àô?Ó¡g³í#_4’»rb?\àã=sÏ^{Ôç…U`· ­ÏCÏ¿aŸ§Jtc,¬$PT’T/^½Hä`ÿ^ƒ_k:æ-d‹Ì]¥„låsê3{Žž¿ZÂxZ7 #T9,‹Ô`ß ž?=릘†Œ"¹…Ý»å~Ëþzu«:âÔnY˜ºk ägŒ{Èqëåã_%¤ÎºsÑZ…¯uy¼¿)Å»6€m\|½ó‘÷‡ zôã>Õàÿ‹<Ï(<Ê€2ô ’p'Ž7`ã±õ­? xF nrÊʪ R[”~@õäuèÖÙæ5PÊpJ…† Î~÷¿A_3R´¦ì¶=hACmÏøñqsá_…ÎRÚ'U”i{Š“µYY˜®R@CÔôlö¯•KovbÛ÷¤uõÈë^ÙûUxœ_xÚÏD³Ÿu•¤sÍM&fp\6àŽ:Ó¥x—ÌÌdÔŸ_Z÷0Tù)]õ<|Tùª[°­À‚3ž <óý)UH$}ìœ{qB±l Ú§?ÒƒÎ@^G¶p1ÿê®óP ‚1ƒÕyàþ×ùNH½Žiå 9ÂÜœw棔2ª€Ï(ý)€yŠ ‚~n§ãüóNÞOÊ2OLŸAù~”HÁ“·ËØ ¼zRª ò+…Æã×ðÿëP1s ÿçÿ¯MÚ€ÀóÉ?áÒ•q…,9äóëŠhÆ/+Ó#žÝ( ÆÒÊ€šE܃yŒãß8üéQÿ9è¬M ¿*HÏ*[†hŸpX‘Œà·ùÿ8¡Y¹ÚÄ2sÏsóí@`~]ýñ÷³ÏùçÚ‘899ÈèHÁ®Gä)î´LUrY˜uŒp?ÚL³‘c«õëøÒ©PFFtã~TÇPرíÇ?µ PFø× ¤©tÍ(bÊ $aðI'އü)ƒ˜dõV Œr=?OçNÞÌÜðØ<äãéEÀk¨ IÜ8õàñþ½àÃ¥ø¹ñ³Áž eͶ¯¨"ÞþóË)dŸ¼¸;ÇÝ>J¶1ÎqŠóø²¬à <ôþ•ú_ÿÌøAuáOMã» ßkñ;*[ÄÛ‚Æ&qæ:ã ¨Ny¯?ˆúµ5¾ÈÞ?k5î/x[Nð‡†toécÒ´‹(të8ÖS X"cæ''  sÉîI®ž]ê‹É0ÆÞõZÖô-°Ü nÃn4—)q±îw²žO×ñ*qнõg£(·-´E]cRm;N¸»XËy*Nи8ÏAùšüãñv¹{ñÄWñ;I¦òð+µF ’\žœã—X~מ4¹ð÷Ã;û+/2‹‘´Ëµ ¦ÿ¼0Ãi;°xõ¯øuáý+LðÅ€ 5Üñ‚…dm¾kŒ‚Kd“ÑŽìœú` ºmÝÍô=1ä§~¯ò<ïÁ?îõ-VVa‚`ÁÒ@¹ÛŒ»=㯽yÇØÞóÚšÞ|?‹íÖ“ãvŠ÷=¹FRI\—,ÜœŒWÛº}‚éeE'”ÕÊÀ‘ÆmÇ8=H=À<Ô~&’Â×S à¹^ˆy=#Ž•×KVœïMZ0¨­#àKØsâö£“û#N·@>A&§XõÇŠ»'üÿã:B’#HØÚ´@é_iÁâ³qw*žPV p? ö=3æ”Þ\¦I!‰O—ÁàñÉʽ_í·¶‡žð‘ŠWGçO„àžž3ÕŸ(ñ&—áŠåQBI9 áQÔÏÿ_èßþÀŸ¼.!}}µjòúâKhËo&6ö$Žyë^“{%Ô_½HÖTI#lb œçŽ;søw¬û¿¥•¤_2\K4»âUB ù‰ëÛ‘GÖ«TÖö5ú´È5ß ü+¤>¥áÏèð_[Ÿ‹Mî…A!nùžkÏc²àgž…[Óþµ¤õØ r¹VVàm z†`BAPxÆIþ•37.8ãzŽ:Q|Å@^ ãn3üûŠÇÈD Î…!½và`ýoóíSy¸’ã¸çׯÔwÇOJ‡Ë Üœãã?•5K/ÊËŽà7q“I;%ÄjCa€¦âI˜Í_³ÅÅ¢Ãz6î0N{ÕcûñÇÈ3Ï\ÿúª]"Eˆ\+1\€3ƒÈÏ5QÒ@Fñ³ Ì»vœOOóéÿÖ¨ˆ$®àÅI ‘œqš¾ãÏ `Œä‘ÐŽÇלÕXã ê]B’pÄ/òÿž‚·QW¸ô3àðüåÌ;[€ªqÇ®F=ýúÒ>?9G’<¢rÌpHÏN}Õ¢ÒÀÒØ ‘ð¦(Ô`ô¾zsÆzS­áH Sä, ‡óȬ3““H#=Ãõõ«K±7îS};|*è»ÒFÁuB¶CüøÅ"ØÇnI8Gv\ äà=É=óíWž0fhš?Ÿ©ºðqÓ‘¦}ªx-šK2ï*pîÚÄ 0ϧõ¥e¸7b”v¹•­Ð'™´¸¯,G¯®{´“Û v ó¢€; ç¸äœzc§÷¢ÜI­D¶ü…yõ sÈñü+%îÐóHÛGÍ¿¨ðéWác+£vr‚ØÜ3‘ƒî?N:ÓZ‡©`•~ê?r}=²P94±ÊèDbLqóH¼ àr:; qÇjeo=6€qœàç©íÊ©¶)ѳ™Y0'ªŽxü;R¸Tl Œ6Ì€9 œ“ŒÏð¯`ð=›O¤#lo‘©“’Ä`dc®3œqè9éáßja¹:tíô潟àü†öÝ¢XÔ`d™p$ŒƒÀÖ¼¬Ê*t®ŽÌ4¹g©ìz5²ybK¢d•W¶@U «žœlçóë[šN.§t`‰ÒÞ2ãkK"ÇÉrW¨ÜqÏÔÕ}6Íç…Ò8*¯ÎêÀùGbxÀ#×ï¥uz›¶X¦¸RªŸ)ÉUÉÀôcÓ5óЋOî='$‘ñí{á› â »{;˜¬nl-¤YŒRVù’HÙÃ!Èàž¸¯òˆ /!xË3õ¯¶¿o뛈<á]?ìP®žnšhµ˽¦È XÎ@–'ø°¿Ýñ2*ù€7 Iúé_G†¿³Iž%oâ6HN8` ÇÿX{Ó†ÞJœ—z羟ʖtùnÌÄðø>”‰lä0qµ2 @GcÀüë¤Ä@$dç= dŽyÿ?Z¶àC*–ä—?_άÜ磃çëP.ÿ›i#ÎxÏùÍ1†ö¾Á€ê|ؤ`ªÁˆ }:“ש¨ÖRÇ-ógŽGoÆžÎäFÎ9QÆÉÍ$ ÛP 2±ÎOo§çéJçsc?tç¦?úô² ‰z‚WŒúw¤$”s“´dsþúÔ€_;)É.†ôíïMr$;€èÌþ_ŸO§N*5Ú[j¿~p¼c¾x俥M»ÕQØa‰ÜCÇoóÒ˜ÅR³/*ñqÛëíúR¹ø–ù”Á8ÏZi,圌0=©Êã“ ñÓîŒz~4tˆ4c8ôzúé® ~Dë“![æ9'¨õÿ?ç­$ŒB.>vn¬­ FFÕ8p9 €zctƒßñHÇ–^r:ûÿ_ùß,Ç÷¸`?3žŸËšSž7sÎsëLƒÀ> —âtO Å/ÙŽ§w>pc9vϨPWíÏÂý3NðÖ…¦èÚU¸¶³³†;haDTUÂŒÀ¯ÉÙDþÕøÑcpy,`ybŸ¾P “_¯~³³hŠyêPvâÈþG>õñ¹ÝWí#Mt=œm.ç Äÿº’!¹“!Æ g‡OÃô¨RëÈ—"º«ÝÉ8ÈÇéý*¸Ô,ã„Å–8ˆMƒîöÈê*K9’ÞÎââEßû²ÀãÎ8®ýõ_=Í®çK‹I¶‘?j ^/üQÐ|2Ó])óX•ƒ!ÀFu\6H‰†{Ü2 ÇwáM'Oš)–dx­â,%X•R(Ô) 3ŒtÚ3Æ3ÏœOxWIÔþ+ø‡YÔçï.-í­SP02»Ÿ(´±…R%ÔõÈ Æÿ¾"hÞÒ¤Ó´`Ðß¾äYU¸Ÿ—‘€:{çð§)I(Çú¾§{ÙE#;"|CHK¸­gˆHÓmHmáS¬%Nx'ϽyêjúµüŸh›{¬‡PyÇsþzSL´7×Z–¢P»•²7ƒ>Xw:¾€Wau©xzÖÞ(Œïn¡X«CÚ€œžƒ_ÏÑ\´ ›zú/DŠ~­ý™©-­Ä‹ÁKÅ_Œ€A<óŽpx÷æ½;ÂZµî¢°[‰¤µ´™cIŒ€3é‚sŒ ò.ÞÎk·ºÜ··ÎëÉàs»ƒÁž?J÷¿ãü2ð„þ!ñÚ\Ì´þfÖ a7sœNqß®ˆµ+6Cj:%vrŸ¼e§xE—SÔák0ÁAŽ@ .q·<`€yé_¿í a5÷ˆ§»š?"hí!ŠÝ\–õœŸ¦ûLþкŠNMM‰´ÑUÚ;d<ÌãŒíÛ‘€Oõ5óÁ¸½¾VQq**5cG+‚3ÜsßõÕîPÃó')hrÕ«v‚Wg­CñFòþ;ˆoæ’Ö2ÌѼL˱qµI;€ 2Tc©€+ÍõLê¤å$Sl äñ¹}xÀ;¸<ý;Uì&wI#M#1B¬I+ŸsÖ¤žÔÚ”ó|øÆrN2GPxÁSù“ÜWt!ë NM$Õ‘nÛsÂÁÀ9 IÃ~†{ÿž(¨£òJ„¸ø Ê ïÔ{ŽÔSiu4Zžñà/3 @.‡îãÞJì'w'à\Æ{9“ų^L‡7'ÍV T¼÷†A¿Jöiñ1ÌGjäÇã®Hõÿ8¯>øác pi“åØíeÈ6c*¸n˜ÎN8ÆKsîròÁ«Ÿ5^wÖràüÙ,>˜Ï§âÍB×ÌGq|¢ã~Ù =qô+Ž?„}i]¹”tëË6‰£Þ`'Éœ¸ç<÷ã§~>‡˜Ö,ÛN¿ùckxdÉ*Fps“õçéÖºJçQðûÇ8ÍíŒlIxw8ÛŸãé€{ÿ¼9—â-ZÇXÒKÛ¤q\$‚B"Œ*9ç’AçÛž e+%æYŠ÷¬ÌÑŸ™˜æ>øéŸåÞ§¶œMľÎ8ÀÚ3ïרüÿ,Áqó‚]ùïƒÏ\f§Šá‹FìuÁÁ?*ŒûôÉÿ=ë£7|äR 0S÷³œn à¯^}¹ãš™Ñ–à%ÄLŒpq圑Œ§^¾Üõ¬d¸‘¢}ò3zœõ=9íŸÂ¬ÂÂ(06•+ÀÛŒ;ŽßÐw­S¾¶­%Þ!®dVÃ`ÇþCüŠôŸz´‘kÒDe8c÷ïÇŒ÷#ò¯%¼ 'Þl‚O=3ß ÿëW]ð§P[_Ú2†`ù@q¹eïɸÿ Ž|Dyé4iIòÉ3í?éí~!·q2£$’ нú}Þ0yêk½Ðl'û?Ÿo ,àœ) ¼dóÎ@ã®åÈè.Hƒl‘/œ?â×<Î3ÐãœWo§ßEl…ZXö·‚™äçƒÔú9õ¯œ§Üì©7Ðäÿj¿†¶Ÿ>êZKÏ%¥î‚ï¯Ùù4í,ÐZÌ<¢¹\ 7['n2¯Ë p#R¥3üJW8펼Wë‰üD.­¦·KÆ×Ja•Sk»9n™$œcôù}ãý=4Ÿˆ>%Ó‘<¸mu ˆ#VmÃbÈÛy8'‚?„ç§Jõ°òoÝ}i)†AÚ''Ž?ÃÓð§yÌá„c;€è:p3ý)J† ܃òŒäÿŸz‰¤ÎÑ€AùGÞú×c0$^dÁ—‚O!OLúþTðªøvÆp¹È¨•Jt 2OÓš{È`¬ÍÔóÅ;Ø Ý"dWYJ8Ýœ§å‚Ó¨÷¨\)$ßB½x?•0åȶ:üëI¸2cq'=±Ÿ§Ò“ª+r’˜ß=[éøûPR5ƘÉÚ3œûŽŸ¥D6n9UÜ;î:}?•Ll®HBmeRÇr¶Ã†ÉÇËŸ½Ïgµ+Øvob%?;rCg‚¹ÆOÿ_ô¥dIbLC9ÉÀÇZ»‡5{­™w/÷<»v%¿3þEu¾ø ãÏÄg²ðÖ¢è$³Kˆ#¹.G?—ê*%Røš4)ÉÚ(â8/þ³œ±Lã?Ö ~$ ¯óy\r 澦ðgìâ¿ÁΩâ;J ’aKyg sÆì¨'éÀõ5è'üB݈mkÇÎ-÷Ïi¦ylŒýé[ßœzW ó4trû®l°µzŸ :Ž*ëØsþZtl]ùù“øŽùú-kÿåøwfª÷> ñÌm…°ÆŒÏQA>ƽ[áÇì¯ðÛÀqC:x^ÏP»‹>\ú€ûS)ù >@8lp=+šyµ¯u6m·lüÐð?À/ˆÿ$LJ|ªj(@ýûÆ-áêG2JU:ƒÆsÅ{àšþ-ñ‚Üx¿Äø}ä}Š EÔœ¨õt•QsìZ¿G´×¢Hmì˜E[j°c¹ÇnONõ«¥Í¥],ûÀ¼/šÀ>ze”žØú+Ì«™â*&©ÙCJßMžAð_öpðgÀû$·ðÕ‡•{r‘ý·Qw’InÙz1 Ä/Rp¸5î6Vó#£È_/qQ½}OëN±Ò£¬ªI¨2ŸðÿüVÕœ(º9Húu+æäçV\õÙê·FÑD6Vʸ’d™rXpÙàqXÞ3ñÓtw€ÄŒ—“½äDÚ=FzõëÀãë½OTµ±/æ1ù—þY_§Lp ¯7×mloÄp%†[g9™Ã.NpñŒãiÁ<þ0혩ÃÚ5)lx†™¬Ÿ_2]6—n±»y£çùœžw ¤Äv8"º8<%e¨Î<ØÝ%òÈÒM­v†ÜÄ÷9ÇãïÒJÚ-™dE‘AÛ¹ñüCkƒÎ8Îr^1Îx-OÆQéò¬–‘ìÃrD¥®O®wdvÈÎO?(­S’vJÞgoW¡7‹<=m FŠP‘­ÎÀ‚£“Ð>ù:רjWÖeâ·Yn䈣³9gÄÞ0¿Ö­ÃHÉ$¿,êÁ!zëÔçÓÞ¬ü&ÑmãKÏë¬^ζ(ÉNw)-Û®1ƒëœ×]9¸¯{~¦S|»‘x[Áš~—co©jsˆ·(’gØÁA;‰è6çð¯(ø‘ûHÙëÚÜÚ†´óâK;E1Ãx²´Q çt| v'Ûœr¾(|SŸâ—ˆN•ew$U`Â!–dÿ–‡9ÉQ–öÉ b¸í'ᆽã)ã³Ð4÷[@Æ–Ý•XE¸ìÇ [žìnÍz”é$ïSëæa/3RÒo¾$-þ£$zµª)g–,$s¾pJà6íú‚8®£Ãü3¤éBîkeŠd]³åäÃÈn§ àµ{»àí?À ž+ÛEöHÌ—««´ìÃ%Y+óî.8¯”ümñ9®ï/ Ó¢Í¹“ˆRs¸àƒÔœ`ç·nÞŠŒçî­ ]’¹ê:߉|;e¤jË;£›«g‚(br~f´ŽQFFq‘Ÿ˜oeV¼¸Û$eÈUþê‚vŒ÷íÏã]º´·zLÐ3#ݘšbdlª SžIûÀç’:W!+õ‘K€FÕ#Ø‚aI昉Îç9xÎ=>•î-´>ihÑó¤°Æj•òî¯|ñþsTç„a—ï¶3œò¿ê+Yc‘›Ë—s˸©mùËzdò.ùjÔå"@» ÛÈïÏ÷éÓ>Ümht—0︚æ9ݼ…áñœìœ(>¸b00­ŒŽq¸HÆ$*¸ .1ßœ÷*%WyJ«ÝÀ;úòzÿžÔÔ2DÔbÁÝéõ¤›Z¨ñÅtˆç8Ø­»ê?åÞ²fEI[bäÃüý?>jô ®ª‚xõÇóéÖ¥’10â=ØåXà3øžxç5£\Êàco©e žwïàóÏÿ?JnС@Üy?äþU4±2³¹äŒ/?ýoëP±!qÝqÁÇOÿWzÃa P#ˆÏB`uíMUÄy#iÇ 7ïÅ? H à íéH˵ËÚ8<ãÒ€44û‡–(ÓpÂeBŸLp?^•¦KMoó.Œä‰ÏéëX:s”¸Æ@çnPû×JŒï»Éx“ÁÏ<ŸóÏNµ´ÑI޳V$PŽî›‰ÈÏ'§#¡ÇN:t­?1ª%,c',qŒŸJ§§Qº@².6’¹Ï$ôõüjÁä:¿—$dñ¶EvVàŸá=x÷ëÍh†J×8%Ê&œ†áIÏ ~Gøô2ÚÝ’?'b¾Jìsøqïžž‹o¼a°˜;L’);yŽpsê;Ž8¨mßd-4 ÌŠÿ?RàôÀéÇñÐQä#V;ƒ Xm…2¬¥Øú};öæEº0œÅ”ܹùH$žO|:Ɇæ5Fi˜‡à?#{qßžÝêõ³¥Ä¤ŽÕ;|À¹'ƒÆsÀ÷ÇqéT˜¬^³¼hüËqw(€ù¥ Ù@ù°O¢™"ÜC'úCþìtþ rÀ98àwô5¸i H$xÊ’Bg®yÈÏOÒ¤ºÔ\‘ÐNû¶áSkdð9ÇéžÞÔÞ«P$æGË´Ÿ(ä:ƒ»$tÇÓ#Ž8зo)B!Æã‚ÏŽ½Gät<8<÷ª±[ê-hÓ¨tµýa~P€>Q“×§Ó4ȯáiXÚ/nk"3§ÝnC&r¾{œŒzá­õ&Å‹É7-¤’ÛùVû<ìüap=NyôɤyRÞUŠ ·²A/š®ãtM8Œç·qØwmÆ›}t`’îêÞÌ-í¤ÜpNlÏN3œŽ8«‘iðZ|+ æ(Ý·¾$sŽyǧq:½C@YneˆÍ=Ï”›¶ˆ£b±í>¤œñÛÖ¥°œFþt Ãx~` ;r~÷$Œ}hºd–è•”[£sÞkÃ#q§k ðŸÃýgâ]ÌIá]"KÛ! I5§Y A“iRFÛvíŽN1©Z•æì¼Í¡JU ®d2G:©B&ßwj¶Åä“‚9éÓ¶; ×#â†O®E,Ú$n._•‚3ˆœ–çÐgðÀ9aø[ödðÿƒYd×.O‰/]wGhªa²L«2ò ;›uSŒWq¬QÃgggieiù£·Y°@û ¸üqé^%|âŠV„y¿ѧ–Ô–²•Í};á׊u-Té–~Ô¥»RÊÑ}ŽM¨Bî9q‘Ðý«¹ÓeÿŠš‹ø¥äˆKÉyl›2qÊ™wÅFG##ýµÐÒþE†×)r…Ö(â)ýþyö+ŒcžÆºo ´6h²©óðynB)ôçŸ^½Ï^ÞMLâW¼"µùÿ‘Û ºš^ô›??í?dHޤrà u,OL¶O¸8ÔsZPþÇ>1k‘׺txRÊÂf$c×ä'8ÇnÙâ¾ù´ðü6pEóJgl0F Øäç©ÏíÖ´¯4¨åä’Ýn°0ÉÂ“Ž¸ÏãÅskb/Óî7ú…²gçÓ~È^2„nšMÉÛ†/vQ›÷‰CÛ<~¹âµ¿ì·ãßjö:¾“ ä±HÇä*S$ofϰ==x¯¿ŽˆAHŒž[†«Œc¯ã‘ß§½K&‰³Ì!A#áVW€Jä~9=¹æ“Íë½_p< ‹ñ<7GÕõM#MŠ;!ÅÂíß a›iÛÃdÛ§uã‹ìy2ØÎ]Ì<¶Â#ëœ{kÓ×Áñ]Ë´E#»ÈyÛ€I=ïêsÇQQÇáÕI|„E‰ƒ»§\žs×ÿÔ9Öc4öE¼)ugÏÚÆ¥¬ß’6_%Ð<¼ã= #85óÇÆ†>&ñ.µ±§é—…ã[yb‚ÝT& ¶ìŒxyÎ+﫯 Bò¼‰®NA |¾ønü:Ó×Ãb…£uH”aÕ—±å>‡§lÖÐ̪SwI x*r®~a/À¯JWþ)­IáJ[;+;g#¡üEjØ~Î~:¾‘¼é°~T”ÇcŽÜã‘ëŽGáúC7…&’îâŽ62Ý‘ó``gž@ú~5f?ÝdÅ…1âÉÞ¤<×GöÅG´QÏýŸEnÏÎ;ßÙgâ••ñ²›ÂÁ$Ncv}NÌŒƒ· ‰NáÁår8ö8Ù²ý¼cyh³É.—dªNï2éäläµUH9ã©^ØÏJýƒáÂ44s]D«æ;Æ­…‡áÎz~U«mà_³ZÇ:A „’H‰²$}ÓõüÅc<â»vVû`ðë{³ámö7–Ê.|i`³¾¶zl²w#æ *„ê1×pÏJô}7öðÍÚ,s뚥ʕ{eŠÛ9ç;`?â¾¹³ð~ ‚ä¨çœ÷8ü½k`ø>s)3:o –®0“r3ƒÁôÆ+–y†.O—Ÿò4öXxü1>\ð×ìEðòØ û=ÕÏîÇﮥ$ `J•É8Çüž¸´ý™¾ØÛ¡›A³´‘>e–îÆßv 3+Ïcƒùúý¦‡Íw=­©Mó,ɼz ýнˆÉõèy«óh=›ZßSfîÚÊ‘Mxÿ0Ä cÆHÁö›£Ü"É$DS!S&ü±Žüë6×Å—1Áå\ùqYç!¢_âÇ|œqoJ½wâiFæ)RV óÆaço ÷ç­7z‹•ìΓVµ´òv¤ÒÁ+]¢”|œqØõ±8 ][éñC*ÛÇ4°…2°Ü¬ÜÏRßwœu®-HÈži™2&P>½1Øú}iï®\8’Ñ¥1ÛYƒ,` €xÉ?0ÇniÕ¾f‹T­¥ÎÂù2\£b7h*•)’'iÆz’yïÍ6‰-yg奡ŽÜÊY—'dñƒ“Ïã\4ÚÏžR+¦Œœ1â=»@nryî3ɬ^ÞéBÀ1‡É”«|±òXàòN~½:Q:iݽÓ ++\ßÔÒìcX×XŒyjÞ¡@Àãø@Ç8èk¦ì¬D¥mN×I³³°Ñ¦¹Õ'k;MÆ Ò)t©ÎÐOR‡Œô5à>7\øÞîßÁ¾Y¤…ƒ«_@3€:3“ÈâªøûÇzÆ·c5¶âÒ¼j°í€Nq’…'€zæ¹m?RѾørMA×í©_œ‰>üá@f8d€Aõô5ÛBФõ}êsNèêô­FððÒçºuµŽ9Õa²ó7Ã79 ‘’pàc=FkCUøë….nl´^5ǘ2UÝ‹d¨Î@8ë’FHõò­:ÕžÂ_x®öQp–q;ªËw1SµTã |¤ç“…É!FNvƒ¨êZ†¸d·a¡Û౎_ÞJÌ\ÿbã'œÁ®ïevùíýXË™t3þ+üNñG‰o ‹rÇp·6UH8ÜCxü:ž¸¨<+ð_Å>(sÿ,åC€ç%B$zã§N¸ÛƒÂÚŽ©ã‹‹ûû×»•äy^[† #…_\ýN9<}1ê3ü[²ðÕ“ÚÚÝ$¬ ( lecœ#$$:ûf»=£‚Q‚9§'wÿù‹_°ºð•ÕÖ™uÍÜR4Q‡8$É>žÕ‹ƒlIÉ^ýOÔ~b½ ã·ŠíâYŽì¸<ŽýjÆ…ra1K&ç*Tž§=0ë^Âwvgν®|ã«ZIm¬^#¨]²0(IÃc v£×ô­(*FÁäðËñÍvß´Ïìϼˆ«SF%8àçØè8õ®BDY—±·ùéÓ ü}?Î fÓÑÒµI˜—Q*ºÿ6NþrŒ6ŒÇ^¿§Ò˜ñÛ#? 2yõàUë»pÑ[`p£x8Îz0zb³Ô—‰’®OROŸÊ¹\lõ ŽYŠA- <\ü¸ô­ ¤ó`—Í_˜|ÈPg#¯çžŸ…f4e>é+œr2yëú –ÞëÉe%·Áàdœ‚*“¶€XŠ)WÄ…ƒ:`Ïá·ñ5Fkq!arÙ?V‘”ù!ÉÉù€¢’sƒü…A:@F2OS€>µoÞ@R$6T(좣±'jíû½2=ÿÏ­X6û)M¯È#ø¿.¿¥E2)ufŒ$£¯û^ÜöàV6ƒ´ä8#±ºÝ2x¾ÍÀƒ—/þ¬ð?úãŸS\ŒŽ2<Í݉Á8ã¨ý?ÏMÝÃø¦ˆ<ÈÇãŸÎª]F™ÓoIe2”H=räzþõ©PoVl4@œ÷I÷úsT¯ Š8wÇÂh;€]Ü` nÏ¿=ªâ ‘$r/ÊÌ:7·l}+£KÜ«[‰./”ј› ¿¶sžyñP^N²\`§Ì¸9ÛŒ ““Ç^qøz´¬‘Û£8I<6zÛÓ¯µe\ÞÅ JÿhÌXîVã8Ç$väþ•ì¬"óM–®“ËáB@f%}z‘œþ”Ö\B~Í"ÇHÎà=1Àú®j fÔbIB[60r6¶0IQÎzcñ8­+FA0KxÓ…V•ÉÌqŽXã®XûàÐÕ÷^ßK½Ô”[]'Ù¢¼Çˆ:2¨Rä¿hÚ >Ù«öòKsh­¥ZyŒØ1]\©hï3ÀWBáÇQšÙEù{¹Ò)n%Ü’ÇR ÷Æì®2¾:ÖšK‘Å6åP؈ò|Ä’÷lœzÓŒnõÊ£O33½Ôò<Ä3ùQHYn9_âÆ1ߨ«v6ïhcˆ‘¤{sã9Ç=ÿ1PCžd*òȳh9cœãõÁ5³á›Kß뉤h7zî¦ZÚÄ)XùÁ/# ŸânüsDå iÊnÈq„ª{±W†Q VfeD;GP‡×?/ZÐð¿€|CñPŽM{¸šSl÷þQû5¼£¬Ò€Bc*Jýì•ïÿ ekë}jïÝ[}ž'ŽæÓMҜɼ¯Íå]4‘íd,SvÂRÀ1Ü1ô!¶²Ólå´ÑôÛ OGÞb±°¨Òr |£ 0@ÝŒ¼d-|Ö/;‚n5}úµ ¶MÞ£<á×쟢xym5?\Ûë: GŽM9K¥±Úp|©# !ÉûÍÇ @¯h2¤ò[Ú[Ë¥ ]±Â­²4Bß.BœýÜ g†£»½y­|¶ â4e ƒ·RG|€2ÿõKg¥*\DÒ;º2bvæ0 œlp dÿ^>R¥jµŸ5Y]ŸAN”iFÑFI-̆GVvÏÞ9*}½‰ëøV¥¶”Há.ò¨ÎÆÁf^8ÝèxÁ縭{]‹}’ Âù)ÉÈãžÞ¤qéZÚE‚Û<òM„‘x玛½ýU‹ž£G$‰ô«E·Ùs.Có;ðëò‘ÏN˜8ô­» <]Ëh$hĽ\Aé‚G‡¢HetK“9P.#„ŠØã`Áëï]m¥Õ¹²”¡h&`¢‚©ìsž¾ã=½«%V™ËRVØÆ»ÓÕYP<¡•–'œ!!€Èúðy÷­´×Ny#)$£Æçê;ž†¯Ée WC$$ÙhåMÊN{qÓ‚H¥j\ $ÒÙ$·ŠÞþaŒp©¿ äó¹ÏŸÎµpr9}«V±ÅËáäÄ’¥ÄØ‘s* ÀtÁé×'­h[hJêP%À]«ò‘…ß´ãnC]-¾žÍ!š”Çþ¬+ÉÉB~ñø¸è6{äû~•n‹¾Æ?X¶‡á¥ù«²)ùX–3Ïì@=j 5ÅÌDGÉÌe;HÁ;ºr¥w'OY4²‡¯¾2höm-V¤ª­õ3,|.–%¤ŽâK‹yÉcÌ›‚ç ÇÝrë@Ó2Udû§çð„ž†kcqjè—líò¬`¾P®~R8ûÄc5)¶–æ,†‹‘½]`ÇLqí[(%º2»ÞäØZº[K™–É'n `qÏz±-©’Rb@wgjtÇÔS|µµ³ò& çqfN`¨¿lõªr\ˆáŠSvP0#$±/ÇHN?‘¤´CI½†êvqLÂK•PŠxá;NxÇZÆ×îìWLžÑP$Š€åîÆFsŠƒÄ½ÔšFþ±¡1‘îzœúמxŸÅë$ç ãi,’ Ì ¨Àlò¹ ³Z—$¬uS§)4ÌéÕ‹wã)ÒýÅÇÚ#3ùÔc®œ€óúâ­ÍÄúÄ¥ãÄq…mÊîórr Æâ@玵Ql'švÒL6¶ñ.pTˆüyíSnTœOI(¦îw^¾‚ØÈ·w;#âó7‰Ã0#9'=x!Õ‹ÝN±žá$H£Vù™~Y# “»áy7o¼þYäÕg•Ús(¡ˆr€°Î{žêNµº›M$vBYX¶Ð|×ÛŸ˜ ÐuÁϨúV±¶3仸ïøŒj p«;9e­&Õ ;ù c©Œö®R=SZM]"˜%»î&9,<Èãa·ŒóxíÜÓõYb’ÖîÖfŒÏ.ÎÅ@+œg‚aÎk*=D¬lÌÁÔŒ»áÝÆ7„gù#¥kË]›[MšÃZ–鷛讠DX¼Æm‡‚sž{rASßø™­¢¬6Ûï¹&8–E±µA)Ïük„MZÒ ½–ó¾ÈŸìÙØŒ×Û©àúQÐÜ(™/£–Lþ~[±$qÎÐI@:‘UËe¢Óa[¹·/‹¦ºIc‚Þ´¦Ð3³Ówuù—òGXñ%ö¡tmÒ{pBn- €Š “ÇsŒu+Ä~ ]1SÊ„G$ØÄÖðŽL/òFyã’«–o‰eŽ'½eŠ%1²ÈÇäÝÆ1зSÈÚN;Ö‘Š’µ‚ïtw:W%Ñn.MÃ,iÁhÛûüÜЧ¬|Y…¯!(Í6Ö¨Ã! ÝNO}ÙôÀ'#\ë,rGn#Ü ©ÚX “Ï Hÿë×%6®ò’í3IpNU³œž>cžsÏZÅ1*ÈQÎâO¿@8ã9çŽÜåÑÂ΀3|à {çk¾4£*X¹·¦„ë+É4’Ë—vs×®Oô欂ʤo ¸ÁÁ<‚—Oʪ«¨R à ç<Ô±:*ÆçØTìoâøíÉzU4(2÷‘#Hü€Å23ÇäzqE@Ó1‰•8ãåÞi9êO^”TØßœúÛÆŽ–×·ãnÄx%RñÇÌp3¸œ{rOJçt—ò¥Üò²3`$ÇÓŒwã­oø¥™åy%Vy¤À Êûº` ÙOLþ<™rÿn J”$XŸaÏéÈúf½y>YØñ ¯ßÅûu¢Cr±­˜‚±`ÃŒž¾¿Ê¼}$Úã$™pà ŸLþ¼÷_E©á[¸ 3‰# ‡ù”à##·N+Áñ$Rœ2žI,Î=ÿN•3ßSH|$³ªbGGHl"†ç#O×Ò°Y$Ü#-2Ø^ãÁþuÐlêŒ`óÛ§SéϿֲµ;m¹#lG¶HsÇʱ’ÐÒÄ K´Æ=M@IVr *’{~˜§D02Î8ÁlcúN*GˆLJçvG@sú Ë}„$w;ô<\vÇnõecämÅ@ÎzŒvþµHJÉ” lCð®ì¨l|Äd˜ð2}…>)q&C=I9ÏÓè‰ãVr†!9E¨Ö¡¹…Õ¸çÔYØDÄÇ'o–ÌÅŽ=O¿'Ú¾šª7…_~‡­CçïT8þĺak—:ìgiM60°Ø F”6ù0CÙÆp9¯yÓ4 /ÂZ\:N…dš6•l…E”q€£8#œ’ÉÏ|ñNŠâHÝ%@U—æ;xfçŽI$çÛ õüª.bÈùcÚBÉ•ÚHÁÁ8䌞:öéñõëÖ®ïRMüÿ¯ëCÚ§F4ôKB’)0%]Ã`çŽ8ú}9λ-mp™u $ù6Uz ÀÿçþU& É%²º r_(@fô' ã¦#Ô`Õ-2Òæí’­wµD¬¡ZC÷@b?àqËMNµ¦•’^FRÏ$‹“‹åeRNI\ó“ØtV gs3*<ý—±nrwt9ç‘Î1JÏI’ŒvÐùI„ºˆöºúnÈù˜í##àóÅKi¦Ï§¢[H‡c³¦Ù  dî)úü§¡öÒnïþÊM>¥°±ác ­rdòö!nÀœäu¯Njkw[6ó%vŠã,C8àüƒüúóYsk’\»³IówC.ÀI2„ÉÞ¾Ìzàç"’ïűF]"Oáw†çpF1ÉõÈ5²Ú¹ìu ’Úl™dŽ2˜¨*Tó–¯|sÞ:øZIzÿuNp:ñœþ½ÿ:äíüi’¥”É'ÞÃà¨ç·^õç‹á‰bòÈnI~2:Áì=¨P|·W!Å¥fzïÚm¤³EÚãc 0SÆ=zÕ½6{8„)0£¿Ü#Ÿ]Àc·ON+Æãñµ¿“<¸Õ·,å0ÏóãžyÅOoã÷Ü™BDÙ#ׯùⵌd’8Ý)w=ªÛYŠ)£1Ä«±]ˆ`X1Á¼ÔqÖ­›øPoµHÞHÎé*Ç?1@—jðïøYi$®ðI·ÏÌSçVÅÁ8ÈäSOñ ÒЇŒfŒ0xʯ'€ ç§~3NóW3t_CÜ>ÜfAˆ†H,²#‚Ttç¹Îp?“WÅ%tù’éM•Ä@,±¤¥°Kcq“ÛœpkÃí¾*\ÝI Är Ë…ùzñÛÆ\Œâ¡¸ñôÐa ‰†é¬±þö%ŽTüÀ®:ç<çœ žŽws?ªË©ï“kÖñí“È åÇÈÍ’=)-õد.žÀXÆ[iÎwv8=»të^)g♥·y-p$Ï’é"‡o,Œž‡óÇ Žk*ÿÄ2\J&¶uˆ#òåääö=O½h£§(ÚV³;ÝSÄE6Ë笷d p~zÞØÆsõÅrrëïc#Û¢ùNàFBËŒãƒÀÈ=· ç¡íÏÏ8Inée‰Ünò3òddO–#ƒœŽqÒ²udŸ2#"0››/±za¸'N£@ï´audK²Øëo|C3BXÇÂÙýÌŸ3Hù˜c’6œnåøwZÕ´É Ü/3Iƒ·$Èí‚ùúð¥sSêHìÒGŸ3hËy)ó´u=lJ«cumžEñæ¸@±¶#`ŽÕª§ÕÛ6nuÃuЕrÁ¡‘üÞ7unCc§¦G#5†ÚÛiwp³(¥dæÜ3œCž3õ­X¾†+ÛQá‘’ûØÉ$õËARŸ„QëÆ²Op¤ªìX@Ú;c ‚HÎ:vÆ:çh¤KeWøÏ¡ßY=´ö7 #£«O…7ucŸ¨íÒ³£Ôô-rkac äÒ¤<6è&“´sŽG~9Í:_†ÖúUøû;6§ ,Ò9`@`¬>ñÀÇÝÚr}½MXÖ|g©x^8¬£x\9Ú¬±£í;@ÎæË g®z¸Åj¡¬ ¿)©i¦éÆÑBÛÜiðy™c"œG;ˆúž8õÏzçüZ|3áKXÞKØöH¤ü°n¼ŒçüçžGcQkþ9¶´ÓRÞæàÉy2n|·%I8ëÁ^£žù¯ñ&·fׂW)Éà—% ã'’x•mN„¥-t0œÒÕ³CT×í'¹‘­Ð´%sžYx*xŒóüóéX·zñŸIíd#æ•-ê©þ†²EøìÁÝ× údÕ˜µPgï_vKyh:ã¦Iÿ8­¹ΫBú³§…n¤ˆ4Óºn]ÅŽ§ãì}€ëÛ";qq?™)ùYΡãÈôã¾?•Q†õï˜B°ÊòbI=009äŸÖ­ÉæÚ_y‘$ þ­ŽÓœòìG§5<­3oiì\¹ðóG0£ŠMêNäå1ôõëÜþëMì"êÖU‰@+$%{ãæ=>¿ÊœZäÐHfsœ3É#Ó?N¾Ãµ§ë³Åm:Fí5ÅÊ•’U`Ä))ÎG§¯ô¤¹‘…hÓ”1}¤ÛÍ 1ç–+!%»p¹ã×ç§äѸð¼Ñ1hØíê¶ÜúÏ^Õ­ee,äŽ6ä*çð§OJ¸/(4„—h88ú}?µMêx*rŽÌâ.#–Év<`ÔžƒÛÛãõ%lj—"fX‘Ð2 sÓýj)§s¡U• µ ˜uHB¨]¬OÊž¼tÏéœæ¹‰mL9ó˜qò²*€]¼’?^´Q^¬¬LU¶4–ø­™”\ƒiCR‡•Ã6sÀ#nî¸Îwãöëgw< ‘îRBªàóÁŒç4QYÉÝ&\P‹pA°Ê¸"ð>ý9ÇéPÜÛ7ϵÇ,Í…ätZ(¤ûÐÇ1­¼À”#žäôõ«Jå¢PÛHÏÝWÆ:àŸÇ¿n”QX-ÆWº¶,@Ø.ää0ïþúõX…”Ø8<{cúÑE&¬"å¤ÒFUÖBÀwo˜/^„tüªYnVu;¹~ÅG9ÿ´QEì –Cžr0IÉÇô¨î…b¡¹äñúŸÂŠ)éü3>ëeÝ ‘£8ˆ?9ÉÁúšÙKgšõn§Y Amȭ׿ÅVðÖÅô4l\Êe,r¬¡¢P6‘“Ï\;c¯ c·P)K,×)i‘æ;m]ÙëסôŽh¢¶jÊäœv¡ã7·—fœß×¼¸ ¼8Á>üsPèÙ×õøZî5¥}Òï!BñÈ8 ûw¢ŠókI¸3£ ïQ&}‘à®›1G p¶~UÚŠ1ž~R??½?JñO›x¹%ŽÅSÆÓø““…ÎlæŠ+ã+A)HúúZ£ÐìæÉûÝzœÓ¿\gåæ’¹œ®<±»ƒ×äc§ÒŠ+ºRÈ茛̹¾&¼*1Ú¬Ilgt˜äìS×N'ü'wS¾Dd@ l…ƒ¸BŽ2x'3‘ŒÑEhà•Š¶ƒ?á3Õ§B¢ Ô6p. R§$tàåýz+=JöK0ÒÈc ¼¢©Ã’FÞ¤c¹éžƒ¾h¢“ŠV1Nè²./e8#HÀ©ÙžHü>œþZöÖw¼fhfwCHñ6BŒúdzóš(©qZ±s;—â¹2º+nù¶§Û®WMçØ­¤H@tˆ)ùTŸÃòé‘ÐçùQEFÎȽ®Km ‘„R;ÈÏ—%1•ÈÎÏãÍ@Þ#û3KÂêH8•“‚0HëÔ (­%MEhJÕØ,üG+Z¼©#gr±tÀ#Ügš­'ŠÚhÞ7V ´ïPK~’IŠ*9×±OK”á6“Oów‡ å² J1î3ÉÍU¹ñä¶Øäíù¹àœÑEi-üÊZW~=eH" ‡FÁbã N~ŸZçµ_™™œ"°ˆ—iæ$öÇ_ëE¹^ƒ½Œ¹IEf'wrÎ=[ß?þª[]UŒR„dIµ™ßYKc8 õË&Š*ä”]—BoxÜ¥© Žê¨X±Àô àç¨éŽßJϹñM‚Éq$h“Íf0?,§–;³ƒž¼ýO#š(­éÁ2$ÝŽkUø‰e%"0§îä»8Î úzÖ&£ñ5®e`±ô<NsÛ<õíEèF”ØÍÉÇc ëâž¡1Bªs¸JìåâÁéÇÒ®Ù|}×´ˆ¦de>z´ry®Åd‰ù° túã= +©Qƒèrά’lÁ?õØí%‚+‰|²v9r§® =3éÆyÅdÝ|SÕo.<ùÉ:íe>fߘcƒÓñúQEu*Ö©L±•›µÌ;¿ßjM+~ê7™‹;F§~Xœòxž¸â²æ ©Ø¹nÛÆN:äç·ø{QEmÊ¢¬ŽIԜ߼î3ÉgEgRQÀÚqÁǜʛf ÈÏ€çßùÑESìd!;sÊŒÿàþqúóD‘äí+–éE=H“ˆ÷Ë’=8êyü¾”Ò¦Id‘Wi‘‹3Œýìç'ë×4QG˜ù¬#ÈòÈ ÈÍ'A»$zé]·‡-ÒÓO‹pRÌÙpîFþzlvQYËc*›!÷’}œ3&5ÚxNÏÃ?¦xã&¹ë½M¢y~n{œõïÁéü¸ëE)&LRfd×NΌͽH$¶N}ÈÏáÔÑE¥Í’?ÿÙ endstream endobj 2503 0 obj << /D [2501 0 R /XYZ 89 721 null] >> endobj 2500 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im8 2489 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2507 0 obj << /Length 2018 /Filter /FlateDecode >> stream xÚ•X[Û¶~ϯ0úrd4«PÔÕ}Û$=Á¶@´úÐ…,Ó6±²¨#É»õ¿?sÓÍÑ&íƒ!rf83Î ?Z­Ž+µúðJÉ÷íöÕ›ÿ¦j¥•Ÿ$:^m«Z%*öÃD¯¶ûÕïÞ»S^w¦YßéXyÑúÏí¼"òÓ, p…ZÝE? B^ð[c;[yAΟíz£¼ûŸ>üÌÓ¢´¦êx|iáQ ¬ Z j³ŒÕÞ|hëAä‡zHÖã|둬凜÷PuÍ:È<·¿u/ŽõjãoÈZ­}¤¼ì‡âeÄÞÞ¬uì=Ù´HH¼¼Ú 'ïò]Þžåa¾=×¥9ÃÎŒÈÉÞ×­ï$r/Úavkš§5Ð1èÈ?»½)ýõ]¬pi¦<'v ðL\ëNæÜG-üMó–:²¢+¤F§¼åð"ïÝÏ¿¼]ážé6ÐÖœ^!«D’Ø+Üù qøËVîÒý¡b¿à5Hʼn÷ 'oþÊ»®±»µ†£íLÛ‹ˆž® =lú¥tE‘Æî:ó œØ—<@±ÒøK›Ûž žŽ F¦;¹}Ë:H¯<+Æùù®äx¯”x²4hÛËYVçü9:'ÌgŒ‰k9a£Ä{¬Xe ‡köGÃTw`ñ!¬>Ï*þºfOõÃÎñ·ÅÔ±‡ëòZÜWÈ¿ÆIêìñôÙVRíåµei:g¤ì ºWñd–£(ö|²Å‰y'»7½©RÔMrƒèmmŠN„h£ 3ä³Ïô±•ï÷¶¯¼ÅÄÔY,þfÉ`=Êèr[¶L/í#Æ]ÄOqfQø2Lʪ·æÄ¼×5V²Ÿ¬0ăd¨f ì&Z¶Ð˜‰ Ð}à–/˜Áè/l{gè  ˆÓvyÇ€f³tb6݈Yh”®Ë]yåi,À ¤K%DÏ+ïF°•®bÆNt ÁY ”NÊ „¬8›ó*¿‚}O÷•Èq6yÕÖPxØÖÃ4¤З Ô€âØƒI@Õ¶§Óùã næñ§±dee± P«€©i×ðð»+¹ÅÂìÀ䈓)ÓF‹ú*Q1mx½Æv±Å|ª&éõI3-n™~û-v¶ÚƒGÔ‰¢Q|â µJz,üK]»¦“ÆUå úF3¦©8q­¬àƪÌkáìÅ±¦¢ö7ç&Šnû(u˜8óŠñ²O!¥ÛòÉoLPàQ‚ñB™‚I ÁMý<é= µ÷Ð1¤^å„ó§1‰Sˆ¦ã2€–†Þ/sÖÞLÕœºJ¯·u·´¯Ká ½†n’ïJ#˜¤åïox—šOêüh„NIS nK¤…Z=®úѯV¿ bÁ⨎nAc —¡¬g°µ€\ÂÐ×› G.ZËÓêWî_@/R‚+ñÜ;`À5qß,éÿ†gTC$ ‚Áú;Ç&Á'ŒãT µ2>ÛîtcS׊ò&'#æjë¿€î(F}ˆB ÑÛ¼µ/ýx²¥k]}BO¯ÿå‘[ˆ9D  zÐ*ˆKÙ ,Š%Á&öY*)p³Ìí5 Ì¢(AÊ5"èÉ…-QÚ4…Âè¤ÂŽÈGZ}A;,òÎðê^O<Ñ³ÐÆF­Õà’»oa’ôYNc–dïA -o¸3æ#Cê¿—â'þ& ú5löP·jÙšjÿ.53ëtè 78”éÜ›CãÎLžy7[‰‡­Ä/l ™¯Uôù^Þƒ½×Ü=‚•êyÐFÉûéź°óTùiö\³à(†Í,ÔÖKáAµÂ4–”QÑ„®?KˆP¥’ÈÊùslÜ¥æ!â5üNr c¨5·qd½Â0õ7P„âÎNPû¹ãaàZß$Å8RÀŠnbü@.…ÞÕ]pÉc (ô ŒD×>Ì]…(E°?#¥ug‘½>(5¢ÞŠa…šRçy¤}^©ð… „ؘƼšåÈ—Ê$X†Ù×#$mý{.ìºpPöÀ_î­:˜µ /S’nå;ý@ +VC—¸ãÑÒFÔLŸ¾HÀgƒ 6w¶kÄ~–X¾_-= 5V½#Üx/ô&zE$º R…¥¡û^ƒ$EI^š¾BÌ—V Ëo[q¿˜6‚’ó6+’o?]ëꚢ•Éÿ]ø- $ÛawN2ïÓ ù…,É_c'íÏg¡r6pÏ •ózA×]¤•«ÍM›ÚÝd©“@oÚ¤_R›@gjûýî†kÉ¿Øô¿Qô+dS@±Vži–\Ã{>ûZÛÌ6¿%ß?SéM»ÄÂ÷-o˜èÙÿüh6¿O=¿f‚¡ð ÿÞ;zh¡ì}…sÈ´¯‚äv¶×ª85®rz€p!uÚNf„‚(ŽÙVõ<þëó’‚¼[Ad©AëìKÐÛ·èíB̵ÿÙ)íÝW¬ýÒÙÒvWž€ AeBoN®×¡ â–jû ”,R4Úîq{ËCð|Á²uýÿ‡7þ‹(q@Ò‘ÀÄ÷üfB0Jo¦¯‚èmYåÿ)Û¿4÷©)¬Ýt?³Ã#ºÒ|÷XšÉÒ—þùœ½#lûÝìå°Ò*ñã ?†½E¥0œ }¿}õ9®³k endstream endobj 2506 0 obj << /Type /Page /Contents 2507 0 R /Resources 2505 0 R /MediaBox [0 0 612 792] /Parent 2479 0 R /Annots [ 2504 0 R ] >> endobj 2504 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [208.385 334.862 271.866 345.766] /Subtype/Link/A<> >> endobj 2508 0 obj << /D [2506 0 R /XYZ 89 721 null] >> endobj 134 0 obj << /D [2506 0 R /XYZ 90 690.045 null] >> endobj 138 0 obj << /D [2506 0 R /XYZ 90 485.513 null] >> endobj 142 0 obj << /D [2506 0 R /XYZ 90 320.5 null] >> endobj 146 0 obj << /D [2506 0 R /XYZ 90 264.944 null] >> endobj 150 0 obj << /D [2506 0 R /XYZ 90 115.803 null] >> endobj 2505 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2512 0 obj << /Length 2710 /Filter /FlateDecode >> stream xÚµ[ÝsÛ6÷_ÁGê3øàgß\7ɹÓIs±r›¤Ó¡$Øâ”"’ªÏÿýíb‰%9 u±@p¹_¿ÝÅd˜÷è1ïÝÕOÓ«×o“ÐË‚,±7}ð2æ%, XyÓ…÷Ù¿ýç͇雓k1? &×QÌüß?ÞMïÞ¿£Éú™N2éß¼÷]Þþz÷æý”ÆŸî·Ä{T7îî'Lyý6=%B.&PQë C¤¹bFé7Ó«¯W†Ìã,½8eH¹7_]}þƒy ¸õ‹Ç™¥Þ“&\y2Ï2—ÞýÕ¿.Ï"öâ8 ¸HN±bdQd8hÿ;¦sI¼$<$L')óóê±&¯uÏkE£*_)íÇ'‚ñ@ŠËè#‘WÄ]}nøä«¯›b""ÿoü“—ªêzô SŽ>[«Tqd"…v‘LF¡É@¦bÚ2xмb˜ËÈ»?+íÒŸêºTyuÞ (|–IWÙ1ÉÀ³å¼x*G8–ø/äÙ8G–:aĺÉY¼ Ý”n¿rM䩎åò¥È`ÕŠ\ùЛšuèG1<[öàD£:Ñ,À‡Xû²±HH(FQˆÇáÞFe^/ ™?â`JûKG¶k6sÜ;’OE·¤‘°Ý(ª\´?N®%®£4ÛRÌÑn¤ZØùmšÜluêúÝTmñXÙÝŠœcs¶¡¸ƒÌFmmG³À$ƒe*1u˜õ°ô¥’;óéö ·ñrñ’Ã6%J]ñg y¶ €žaAr, p%O`ɽúâ‘à°ûM\ _8aº€xÉEÇ{â] O7­Â`g£NöG³O²‹¿ É\i ý”t‘<}rp ñ" ƒ4v¥»@þŽÎW|prÔYÿh±f/ž6þÂ0^ø†gÿ©c„KÈx|À¤#ß €±g Ǹ}ß Ãù6PKy D:ê„á|ÇOÂRОÒ?acer`ãŽòG³·Äi&áè†áJÀ31ßÛåä݉=ê%Ä ˆÕö¨Žø½·¶íZÍ ì‰ç=h_|[z¾v„âï_ù|öe=ëiàBÆ`ƒM^ÈcØ[˜á§–62óçõj„ö\†Â®74Ÿë ð@:tqŽlòª}PMgÊÒÜ_ªÖ¯‡äubηû Ðû¼½{f–·ÅÜp‡ w½yAJĵyžÓ}­wÍɾkƒÎ &éÆD"¬vpÇ ‚É9Ø¡‹*L›þ÷„sÔ× ÚÄß €žÓaMŸ<Žü6gIjÞ¡0óÖÑ‚ yôhðñÝ•÷Y3Žá|‘+5,õUGƒ…êò¢lé"ŸÕ=¯Y"‹ýÿ€–àÅ¡Ñ ã lkûXiæ,ûy£rýö 8á ± ÷·ïÄZšÞ˜xÂç« ügºÐ(#+ƒ2 -ʨ.ÁÀvx÷¤Ú Ó [Ãcs,µÍé™êž”2 ß¼,TeKúvÓÛªæoTI5m@Á$ra C|ø€¼±e`æÈ+ ¢É5gŒùÕ×jM³¶‚ÝyàxZà‹E£Ù[”¤ê0F«qÀÚ L«5´ñye.o>ÜE£Vµö1Lb ¶4ÄÑ$èŸEx¾²äùâOçå$RÒËEý ÉšÄjŠN!ņá.aúî¶oº7kÔuâq/yâÿUhA0­¡æ¨šöš!~Zó%Ý XãÖ-0Ó>WóeSƒ]†šœLÔ–ï–:?L®ã:óï{7˜`9g¡¿RX8„ì_æM’P Ñmê C¢Ûu­\†Ã¬¬ç!™ZçÃMz}¼ã*{1hnÔôÛ*b(éhf@·' ŠtÉ¡fÞ¸f£6÷ÓÂX&ck ¬e8¡Ü¯d²¦ýª6wv6ã•¶ÄáÒ·Dߨí£ÊÖ<„Ø—MOmÖP„¶”9ý<6ù>/érÓj¼ö|ªyЮcþqSÍÒQÌÕ!×…þ \×Ë@Ýèk£ÃÌX…EÎ ¸csŸÀòY ato›ì¯Lck©”ÛÁ.Ë#§}M³àñ¦ tDôUBû1¯ ²Ž‡v>-m·ë’»&ÙlLÂX2ËŒ>ÏT?º+%‡¦.’ &Ó_Àh1_GŒ8i&ëº,·ÒQÖpífvK'N3Ã>Ë¡48Ü€E_/ӌݡñ ' %µpO!B‰-‚ Û•'¸¯=ð_íâ¹YŠ:ÿ…›nËC Ñ Î,•Ö¦Šš2b¸ÅJOêR—èæ­Ø½Ð ÷ï ×eѺôº¤8\çy (\t.‹æjm?ÌɈ[„aÕPFW(X&$8Ú¦@á¸Öiƒ TØp¨c½ƒ™Ë“Jm¤mX÷ꆰ¡±é&2rÕ!±0¤4ií[›B² û¦ºÒºÔåPUkmj]»SÈÛw¹8Yjûœ·Sc¢*b´S„ZîCjÚŒcËдl7³k4·½Àµ±Yux}ùÞÕj½i—ßÄ·÷þµ“]U endstream endobj 2511 0 obj << /Type /Page /Contents 2512 0 R /Resources 2510 0 R /MediaBox [0 0 612 792] /Parent 2479 0 R /Annots [ 2509 0 R ] >> endobj 2509 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.55 401.41 513.996 412.314] /A << /S /GoTo /D (section.6.2) >> >> endobj 2513 0 obj << /D [2511 0 R /XYZ 89 721 null] >> endobj 2514 0 obj << /D [2511 0 R /XYZ 90 690.045 null] >> endobj 154 0 obj << /D [2511 0 R /XYZ 90 364.884 null] >> endobj 2515 0 obj << /D [2511 0 R /XYZ 90 246.984 null] >> endobj 2516 0 obj << /D [2511 0 R /XYZ 90 227.107 null] >> endobj 2517 0 obj << /D [2511 0 R /XYZ 90 80.094 null] >> endobj 2518 0 obj << /D [2511 0 R /XYZ 90 60.218 null] >> endobj 2510 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2521 0 obj << /Length 1911 /Filter /FlateDecode >> stream xÚÝYYoÛF~ϯÐ#Dë½wé7嬋" E‘MÑ6YH*‰ûë;{ð4MQ¶‹OZ.—»3ß|s­ðìj†goŸ½X=;y£ø,D¡¤r¶ºœ…x¦°F˜‹Ùj=û¼üiù~õúÃ|A8š/„ÄÁoÎVgï޺ɥûYÍC,ß½ýÕ=¾üåìõ»•úX/î­Z¾?û8ÿcõóÉA[BpÂf D´20aÖ<Ã^èÙ¢z¿  ¾anÕÙv¾`˜åub$Øí77G›ÍEuó7Ù:yC"šµí4H 7[æéÕU’'k?}é§ÝW4(’üÛ¶Ir÷m‹ïnLü0—ç霊À-\»—߯“¾´ñ&M¶¥›\'qºNŒÒ ð‚ oŽÔ¬$¸¸5¿ØÊn¯Üdä¡d-(%Aœð Éâv9®ó9A¶MÿŒÊ4Û˜@J$¹¬¾»IÊëlíNù‚^Y©Íù•ÔÒá½Èö¥{ã3RYPà+쑜:CÙõŵ[[YD‡A9'Ì’ iô†‘TÊ‚P ¨ìB“Å~X”ã}i6 ‹ ÷[d fgÆ hy²ÛÜúwcù…iõ¡ß)ÙEyT&Õ.yù³jdܲ†æÙh›ô®c'³ÞK‡­ÎHá™S˜ 3޽ú D8ŒqðÌ &&Lœíý¡äÍ€¥ Ã4’Úmã>­>Ó,ˆâ8)üØŠ¿«¹6²_ùG ªÁ,ÿIî»<3|2¯Ý̾°lµ›]'|¥œ"Škâ½JÜqòÞQöÇí€ ‚! øo²|`_ްZ²,Áµ/æÀ”±Á}XýU¼‰ŠHÌq¼1reù˜*ÀX˜f]šNÖˆõ~Þ£ÇMT³èØL8§ñ‹¬ã»ý§§½xÊ$ 19CÄ©§_(í†Ýžv@=Ù˜ÝÜDÛõy 2ÆbÃÚµ¨EëhT1¾ç¹okS ;T3šºƒ{úh‚TȬ>R=DŸ|ÎT~}µ‰2¢„KBÉ81RúÀ ÅØ0 U»&úLìŽBEu\ ?"bJzùüž§e2=9½íÇ S }:»ÉÓc'1âñØMÁ€’âh'b(@Z2‚fi«›.;ŸZÈ ˆaþhkewén K"ðÇúš9¤§‚PHRþhr*ÅÅ£ù> ?›þtä> ˆâH6Yûi¨Vi5[„!Tú´GÝM^WºÊ.6õj¬£2r/\&U ª¼íú$Oâ¤[ã›5evr™g7n]GxYÕAðêž:HH¤6UÃ+#Ä€É1"¡îW* º­–FªëgN/Q륬^†ô€½ÒåeMa^+kÚÊÚ }¨›òúÛOõePÓ6êw*·áDÌéã y Û{ ßr8õ­ ¹oHS •)[+µ€iL}ßì¨2º¯â†ŠÔaBŠ_ÏÙ~˜ÒˆŠÚ=|Ôßx¤Ôð–/6Ùņ`{ÕåRR ¯?ÔŠTS¯¿lZoªM“u“¸Qž^ zÛ^é^”/Ü\¿GÀ¶·µ«ÝO§ÙèÁ««¢V…Ц•Ъ¥o0ppéÊóªd6kw»MÛ–×–ñ8ø}N²}%õÖ÷—…œw¼/’1Û1Œ8“i0šn§v[é¬,ÖùÓª{%ºæ”5G5Ê}Âl:Þn,0SߌA£Í¾ŸkÔPµ=2׌ c=ž]Ž—Zƒó¨'ËcYž>ôÈä8Y%à‚î5ìòæ•Kmº•y´-nÒ²¾r9æ(E¸é–ŽîѦ}ôÞ2p5² Z! ÙóÎ õ7$ËâáW$ËŽ2®ê;36v0¿­°e;9‘+Ÿj`ÐfÆá7P0…4G^p(™Å¡«%E.!“. ^F›Í‹(6+¾H0$È& '%ˆ½€'éEØå.ýT¦C`Š¡^Bê„@4Ww/G¢É·#Ûš¿“;'Ý_ Ä)LÜžÌ>/öÉlµGu¯a²îd‹JݘNÐb ä#ÓiPh ›0$ÇÂÐëô´sÏsÕ×É#QŠH|`Še‹ŠéG»ð¸ÛÜŽ %t}®¥C…_æ.Ì]• ECÑ-fl@cÐ.PÆðRë[Œ4©]÷ù²ô0=÷jŽ“´O¬ÑMG杻q°ü„â¬Zs v@î4eWÛϽ¡$EZ¨®¡*oþ"p÷ìµwWÑüÿ`G¨¯d£] <=-ºv‹/΋ýŹU|Ô1My¨oÐ7øDÃ'…w=ɰóJßVæ a[™êÙ`Ãê[šÑ»¦É!”<?†/Ü&EðgyŒË#ä¨ M';q•„¸Ž«öá°ç1¨½5÷®þ; eP‘°ñXª¸üûbië¦ë^à ͦÆRpH®‡b©¹YÂaïå)±tzRüïX´•U1´“ü©Ó!L‡ ÞÐi&¼?ÄV¿¯WÏþ-¯ï endstream endobj 2520 0 obj << /Type /Page /Contents 2521 0 R /Resources 2519 0 R /MediaBox [0 0 612 792] /Parent 2479 0 R >> endobj 2522 0 obj << /D [2520 0 R /XYZ 89 721 null] >> endobj 158 0 obj << /D [2520 0 R /XYZ 90 639.558 null] >> endobj 162 0 obj << /D [2520 0 R /XYZ 90 297.617 null] >> endobj 2519 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2525 0 obj << /Length 2649 /Filter /FlateDecode >> stream xÚÍËŽÛ8òž¯ðme V$QÔ£oL’íÅ&“M,°“E@Kt[ˆRžÿýV±HY’Õö2‡†©b±Xï;Xݯ‚Õû¯·/^½KãUîçI”¬¶ûU¬Ò 󃘯¶åê7ïÍßo?mß~^o"x±¿Þð$ðþýùn{÷ñ=oég»Î™wûñý¯ôùæŸwo?niýõË€<úýt÷eýßí?^½ãш‰8d~ÀR`ÑðÀÄyX¦ÝïjÃòÄçy¾ÚD)œe„ý-ŠøõÛ†xuxÝû ª^ÒRÐO)×÷þ¨ î{UíÖQàsLŒx?Žb`!ôó0XHfg8+WNº_ä:¤›?©u̽îÏóÍaðû„‰ïBŸÛqßÀ_¸ ºg~’ÇŽxÕ’8Ç®®«öž>š®”õS2m¨ðÜb1¡D[Z¤ñýaâgiâpÞˆº~- ¼æÇE–û<rQ ­I7Naœß‰â‡Uß©®Ÿ«;p??HÙ_Gw‰Ì¹ ¹Øç„Ûcõµ¯ê›-ûÑ ß‹Ýw}Ú}7ò?y]à'ÁÏM¥ùsM•ÙÔT€ÑŸ@ô³ ¡ÇùÔáçöÓ‡™ýV›f¹ïPØN­7,½¢k@¿\oâ ñJÑ ÚJÒB˶|¥d!+“=ð°,i«ï^íU×àŸdÜÈþЕ–8hÈè$ÌS?c¡ÕIBLœ´+ Ê.n¦Å|,6Š1"þHÉžé'óãdHjÍROŠr–þ–‚‚ùÐ˸sÖÈÚbRŠ"?ÉøÕ-´8Öç'’üð’ózÛdŒÝ£>LIZ‘=®: úM'êÓ´ñ¡Ÿ$Éÿ¡<[FžS8*yFÍM§ÄŸ¥°x\ÏŸRبS{¶ÆLEcŸÅPTM;ýÏ Õ3æ'‘­ÉÀÂzо_<ÙöúrÚ„¹9@ôÇ~Äóá˜Úƒwm¯Ö[ºòTôU×.H §Ch^lyyKQ…7mX–ÛäšeØ…âwÒVPºèë(TO«noÑZ<&`Yé‘JK¡žºšÐõY÷²N£ÔÛd¥,™ª!ìÊòa’lÅ~UJË £Ú4§8sR¹F©°‘$J7Öj‡ª°·²Õu,t A³{´Ü· ˆŠ ôââ`»<ާ7l&AsO¯C¯‡óB•xóëç×kÆqaQ<ãÕ`€"EYÝ7„`„Fw¡ÏIG¸©–°!®vú¢Û˜q¶÷A§5†Åà63.ðß̽q>æ&¦Š`H‡V„˜A/Þ È´Þç'jT­‚ˆ¢×3\-ùžZsîasÍva×|ƒ-ËZêÅûþ†ôÄ lî·Õ ›dÖÂIjúM0Š`³©ð.Ü7Ñ?Þtbáf§Ü¦¢z¦Ú7ÁŸ…<’±qËùÞ…d:" äEuÛ–0PAeIfYpoè*c“dÀú5iʸuâ\‚>ЄnA³†‰€‚~°-¨ÈiĬKwø÷S¥†«wf¸'õvŽ$¢ùuÔ'Οì8"h ‡*‰ SÚ/©Àê’tƒŸh ú>J³Ýfpa/•õFl’ ÏKÊ&R–|e)v»ºº—%m’03ÆZˆÃ».~ïÉebë"Ì;KÑÛKªvÄî ò¢8u^ÔAÕ˜Ž,nýf”àÚ®_LiÓ¹ÒØ˜ÔÍAiHÙieðP•ýÁV?¥qq‰“ø½Mv~<^æ‚ØEœžd’Ì'LXΪõÙ%&²«ËLÈÂ}N3G6ÖlÛoJ5rQ{tžµgy2ó\ö§Ø¦3ѵ XRXán+ú“2E —\;¦ÎÂïD…0(šÔnvlGœ {@†Dð”¨Lzº‡:-•=u0)—Ø@Ì®-¤ƒ/¥Vræ`ªH4wŽ}m0(û-ôPÈV·ûžŠiî{:oÃ&˜† GBà¯c]Ü*ŸEáUœX`Ð& pÖ¢8)%KdåCê žL½“.eÞªÔ³NpâöôÄõÒ¶JJ aïâ¨ì†§°®?HåˆT¿|V×Òˆ¦eÔODü0 ¹¸üOú(‘Á\…D( ¬"š®#Y9 l-<Ö¢jíöj¦;% :~ƒf³ixÃi¹9Ö² “‰#§‚(tär<ÖCÜ⎠žÍ*•í"l^HÓ…ôëÁ¡…w¯4؃GóæÝ½ã¢°Ð=£iGþ¹&´öJÁÑøjк×()àJ&å÷°neMÆéˆ¸¸{õ˜]<}2Éfï4æ#ÁGÇßUôRèLÒqä¦ üu‰ÙÜ5í'>œv‘½îä£êÀ°³7;²ªˆòyÄ#’ t¸Ã°¹{2ö0|œ³gwrJkþVÄÆ“1ʽ—/—3ä½Ðbà:²…ÉegXØ7/BçÀÉâĉ ÐÛOwnÛ 2x¦„¤èkˆæ3è-Ýq¹ ÝU„À¤ùBÁ˜!™æ>qQK¡%íeFÇÎÐ5mõ±ë«ý™°‡zä„Gœ=í ‡Æhi8ojóp†·¶¾”Øp1…BÇz—Û$çøêrÄ ’ ÓÆ^1fÞ—^(;eåøÛ[äqá… #lÀ]9„ãˆ0gQÆ:+€î¤´ûP¯jQÓýð±QÝó?þEÞuµSBY§µ4—÷hN?ŸN0œéë/.Ùö¼‡Lúw‹Ù}µ­‰¢Ä®¥´!ÒÑöE9 YïªGá³ÛžÛ5°å®¡?¥þy»à¸ùó:¶€ÕýÁÍóØÑ7˃mhÝx8ãñy·5šøfÿ6¿YüøÛí‹ÿ át÷ endstream endobj 2524 0 obj << /Type /Page /Contents 2525 0 R /Resources 2523 0 R /MediaBox [0 0 612 792] /Parent 2527 0 R >> endobj 2526 0 obj << /D [2524 0 R /XYZ 89 721 null] >> endobj 166 0 obj << /D [2524 0 R /XYZ 90 498.847 null] >> endobj 170 0 obj << /D [2524 0 R /XYZ 90 472.588 null] >> endobj 174 0 obj << /D [2524 0 R /XYZ 90 270.045 null] >> endobj 178 0 obj << /D [2524 0 R /XYZ 90 115.251 null] >> endobj 2523 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2531 0 obj << /Length 3219 /Filter /FlateDecode >> stream xÚ­ÉrÛFö®¯à‘¬Š`4vø¦¬£©”“±•™ƒ“RD“B´Ì|ý¼­4ÊrÍœØèåõÛ·¦»:¬ÜÕO7ß>ܼù1V©“F^´zدRw»‰ãáê!_}\÷»_~x¿¹õBw8›Û0r×ÿyÿpÿî'ž¼ãŸ‡Mê¯ïÞýô ~÷óýïxüÛ‡~ód×ݯ÷6<üóÍ¡7B"P¾ãú1 H8ø1î¹qió»º \× “`uëÅpÖçÝʱv}î´òœ äÝSVô¾çø¡o¶Ý¶A¼Î*üMÖzã…ëO®uÕñRÑòRׇƒntnNä2ÿ¤e¦ƒ-Ûç®ÏæµO.+ÏÚÕöÀŸŸtõ%0± &ÒZ^k‹CUìo‘ÐÕ­Ðv«”“†"æb—U]yÙDádì»Ñú®òc ýœí?YuVÕ?ê=ï!ø¿»®‡`x‰È€¥œ¹Uì4ÏO1‡©\Ÿt•¹tu¸þo¬Ù_ee}0ã\€‡¢ËJží o‰>צ¬{b††kó›áO·–]Æ3ˆùg’gÎ'ÝÈÞ1¶ß03÷µ,¶°FœÂ1ôm®†k+¼áÂU]Ýþ­›š¿D y»£‰ ÀÁ½%K±òy³%ÂGúà+¦ÞWÜÜñ„þëŒĹ®æ)º §F¤VŸåØDl¸©¿½‚ë³Æà‚p‡;´<¯ ÞðäVó\{Ò;Òd;.d­üòz£Ë¬+cãEàþµÙ¶­KÑ(WJ| Œ&»½Ä}%Úé oaÐfGÍK,^˜ÊÊR •(gËËçªÔ­œÎøI(;R™h‹:\øÝ ÝVË}[]Ö$M˜U„(0p“¸ëš7ë¬-ÀÇ”FLésS™à>³Ó©Ë튺jyæÜ²F††´Ð´ Æ–ëú†çŠN~FV¶µ€y3ÜPM ïëR¨èoÝe­,¾µÜð*t’8O ”¨˜)A†dH¿½ó#hÄvz!s9d~vÍùÈ_$$Äé˜Ú¦žÏ[LhíØ°º…øV*tÒ@ Xm¯au×-ðQî:oÛ]SœP§â¨m ãë†Ûv_æAÏò°|$âFg"œFïôÈVŒ,+ƒ/:ña—Ÿ›Ðë2®_ç×@@þÿ ׸5 Y79¸€#z°¢»ˆ2nlÚuF3ž²v,úÜy(ô5JعÅlìM‹>4JׇºÎyÚ°‹¦1,âdgM½'ìÉöä1¬m=opƒá .-89‘²,O¤‹S”3 ÷P¤R©íBºæ2ˆ äý"ÇmEP“úþŒûùç¥ÁÀ?2A²šîÌú 4+hÁÞA?hôc8èÏôÖý€K?à›õŠ~È®¦>òèþçK=¥£hóïòÃõÝÏ÷ßÛLl룆Èox«ËvÆ·È ÓxÆ·ÃˤRrƒøc¼9Ž'^§Ð‰ãïéÜ>!M8>f0¢ }1…8"Öá`œ£áw«†ÚÈuŽÁÔK]BVòe”/{)Ð%&aþž4ÞOåÛ·ˆÍãç{„~ä-€8‚4äOÒpåÇŽ§útc¥ÍÐÀ÷•x3Ž>]ãè·Œ¶žX PduŽæ*pð#-zû¶ÕÝ£hQ&¢T úÄè1Ï:½t^QrGpø‡S £bŠå²ªŒ,W‚Ì–s ÎÜèw£ÖœÊC¼‡ñ4NÁùß7©Ï$µ“üÓWØÆfÛ¶š|9Œ ©>@ƒ…¤L>EÙ¨‘ 𦅔 Ò±ìb2‹®©óóÎdÛËk£Æ,'YˆÌ§¦>e‡ æÌ}ô3É¥ÃäìΠ ä Ó@qëŽ+I]ÆÝûŠ"Љ¢Î‹ÝR™CJÇef,1;žS Ö±kjCŠ,ø«(I’è4T2RÌå|dÖˆz:(Ø1Çè "ÐÕÎT)0Eå(s±Á)˜ã„þ¹9•¹y{‘r“iœezÁ‰€ûId¸Ñû‡G¦a}!ú(fÝ »÷=c°'jŽÓì#o"0ÌÚáÒ8ôbÉ^ÞMëļQ*ïØubß³YkY†¬Ã1x€âð¤[‘ìL.J„î»§ÉY | a¶+ÐpHð¦,‚5KÏ ³iw/Òk.XõÝDt4q{tc®‰¥ŸÉ\å)§VyÀ<þ®îä4•ÈcpWhIÜ|"f†€MàCC Ür>n©šKÈ› Ĉxä—ð£g]Œ;Ùó\P! £­Ì±Fð Éf[‹ÐÝ3ÆÉš? W nrÜ(ÀÈ]5‡Þ£ ÓˆÁSy>äò>O­|'R;ÔÄeÙ-7¢ë°Õ$UëïúâÐØ±oŠAÐ[O0¶EOïE®ã¹á¤V—kôAÜ·(̼–/>hÊÔÍ·vÔ Ê{?¤¸R@ŽÊt, g…ÉuøRGÔgtŸ›Á$«c‡É’“zÂ?ÿ+BDÖl¶ì ù'Ê–¢EgÂQ´ð}Vc6¸D-Xj‡™=ÏÔ•æ ò’¦‚+YƒXP6HŽ Ûu•Òcð¥ÁáSˤ+Znp c !yšV“Àn£%,01“ŒÁqñ€‚’‡+ž½ ? ô=Ó… ge[È=L#œ“æ-¬±žØLdüs,>wçFŽ“íy 7ˆûüÉ3G/îµCn(e ]ð3 …š‚±šc+ ˆfRxø_,…n~`åÂà‚Üé㲩캦/˜¬Î,á2dý„,dýK„])|ÇWñ‹h¹>„Ê€âÓk+€Ä•—*úNâyb}‚dð5Ö7ï,€Ú¢*Î çŒsÄÒÔ ¼hœºYí–™÷0 g;Ìì¿Üá˜âaZnl€¬”“$¶3 ¿‚hL˜¿@¶€^ ´î²ôF“B²¦ÆÎpÙ€£©;òÄy½;‚?làu-çáöÂÛ%'S–žòùAOñ¼ÄîãÑ|??Õ<8S1‚°„ž¾%»c$4ØùUƒ\÷¢_ ßJÛ}åL-[BýÊBºÌZ)Ð;9Bý=»PØ_+¼‘ÏÑîP d{(Ë×™ØTìz3³Ã77‹‰ã–\2Y7ç’F©ä3I_;¤ózF‰`‰ÊXü® ”<ò8ã%S3,Î|SîY÷ÈêÌÓ,žê¶-¶¥ Ä°SÓàBÈÏÌ ß´/|a„û2çÛE?êµ?—v:´¿ëýU£~.:I{ŽÃ£v@AN¯É,¢¯0f@²Y/Բɸîô#)p°Ã†ƒ¯…R$áôÔá$%E•Vóº’&§!ç0 ОQÛ ÏÑGœp`}d'<F/E“bI¦w^˜°;À»eü3rômLÇ,¾„M~ZÑ£)|‹é9bLß; ÉÕ€GŽRÑÔôÍ+¯¬ZŒ±ÜÂkü@Bô})ø¦PÝ»{㯠6½ÃÂz+áÅ>ãÏøú½r='TãdO‹õ&ñ¼’_‘ôëIÿ°žö'1öøpëØÂ©ÅbÊþßäÅ-i>¬¥1;)¾˜Dbp¶D2rV‘4’#ˆy—*;;Éå`!Ëó7>ÖÄ-SEÊv/ovõñÈ)k‹ËŸhFÑÕ&XãÒ”Y‘ä‘IN`U£ÙÅFSüõÂ+%»mzòä¦'¿d“ÿ¢«h¡4ƒÐ4qwÙÁ„|Ù-yíøYL¦›˜nuýð§€îr’U2pX³™±à÷Mà hÈvœ`co¤–YÓ:é5õ¤-Æý‡Ñö0±šEŠ˜ƒ~YüÉ!oâ^ã÷ôÅF¡"²Zó´÷²ŽÕK]ÅñsoŒÂ½Þúø“W<þÞqÚ&VÀÉÛ¬ÇÀœ=Šþ i¦ËJÃë¼û –Q;Ï3í> endobj 2528 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [369.932 366.095 376.108 378.859] /A << /S /GoTo /D (Hfootnote.7) >> >> endobj 2532 0 obj << /D [2530 0 R /XYZ 89 721 null] >> endobj 2533 0 obj << /D [2530 0 R /XYZ 90 690.045 null] >> endobj 2534 0 obj << /D [2530 0 R /XYZ 90 610.179 null] >> endobj 2535 0 obj << /D [2530 0 R /XYZ 90 594.239 null] >> endobj 2536 0 obj << /D [2530 0 R /XYZ 90 578.299 null] >> endobj 2537 0 obj << /D [2530 0 R /XYZ 90 562.359 null] >> endobj 2538 0 obj << /D [2530 0 R /XYZ 90 546.419 null] >> endobj 2539 0 obj << /D [2530 0 R /XYZ 90 518.523 null] >> endobj 2540 0 obj << /D [2530 0 R /XYZ 90 490.628 null] >> endobj 2541 0 obj << /D [2530 0 R /XYZ 90 474.688 null] >> endobj 2542 0 obj << /D [2530 0 R /XYZ 90 430.852 null] >> endobj 2543 0 obj << /D [2530 0 R /XYZ 90 351.151 null] >> endobj 2544 0 obj << /D [2530 0 R /XYZ 90 295.479 null] >> endobj 2545 0 obj << /D [2530 0 R /XYZ 90 275.435 null] >> endobj 2546 0 obj << /D [2530 0 R /XYZ 90 219.644 null] >> endobj 2547 0 obj << /D [2530 0 R /XYZ 90 175.928 null] >> endobj 2548 0 obj << /D [2530 0 R /XYZ 90 104.077 null] >> endobj 2549 0 obj << /D [2530 0 R /XYZ 104.346 59.772 null] >> endobj 2529 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2553 0 obj << /Length 3160 /Filter /FlateDecode >> stream xÚÍ[_“›8ŸOáÚº­bªb-„Dªö!ÙKrsu•ÍMæj’T c͘Z ^À›Ë}úëÖ0¶Ç·{/‹¦ÕÝú©»ÕHþâaá/Þ\½¼»úá5 Ib/îྠ~ÄwëÅï§¿½xw÷êözI™ïEäzÉbßûåöæîæíÝøB_Ð{ñöÍÏúïOÿ¸yõöNßÿë}G<¢zñîæýõ§»¿ÿðšÑžQ?ä ¢’!Hså¡íu± %"X,)‡WCMüÑgþ ~‚Á;‹KæC­î·ÝH}#˵¾©îõ5]oóRß®å5eÞïyfhoeÓ¦uû^Ö¿_Ì“µyÓ\ÿªÉ •n˪í6….¢ø„1±XŒ$Ñ£ÌÙQ™ï[ÝUä¥x ½Z.³ª,eÖæU©Ÿ¬÷Rß´U4ézÍ@øX)ia\Cx/e–îËi#§xD^^‚@÷×˲Íý¨¬Z}³•Ûj‰Ú,‚†2u’0ª:ÿ\?CÊØv"©^”pe«›4[R—†oŸÈÐÜ›ëèMþ°)¾êû]Õ4ùªèK m×÷PEv¨"ðK‡:2/Û¤åƒ\+Û1˜¨­?Tô£ï‡é‡§`WÝ)ܬÓ6Õw»ºÚóÒV®uÓ—¼ÝŒèÇR<ï«z«ï‹¼ie™—¦»t·+ò,Eˆ4–QÚŽEèë­øõõî+k…´ÎÜÚÒ¾5ˆï=ìÓ:h“—–ð̯OÎSq¨² àª6ßJ…ȼ»’ è²Të–Àkòm^¤µ~¬æ‰°¦8ÆÕÞp¨JóH‰Ú·”‚=jÛÐk}{X˜0Ó¡úË0"!G—oB¿)†æí÷œe@IÄ"ë+wùNNxTꓘ&–h‰£Í­±ÂX›Z 0¸÷k®#Ü)Ç$èãÞ—Mžmô­ž@¦ì +ÃÜÉÚR«)ƽÀÃÚ­ÄY‚“¿–¦=]UÊ~Š•~:àݲÚ<K Ïd)kãÁbešµ- ¡Ÿû@{‘¯ê´6D*‰H-žæàÖGu`Ã&™rЯú‡Ô+÷Û•ždÔ‹LdÐS›z\_´N!5€WM#í ©é‚ÎÊ´˜iL{šà«–ûù aЙh…‘ÌJòh†Xýž'¢­1óÍ£|¥¦¡8à *³ž5"1«>Ä´œos ”|¼¨LÏÏ[HkJ“,Ú|Æ—ö°^_“…Ôq„ÁºÅ°‚œåud¢†01¸ï7´!O0ž cÞ%4<´SÚ 4y2m÷µ¡Ñí!8"Š]ÂФ uNà^AšúS—cÒ©:7lªb-ë®÷R7Þˆ0lA†î›¹ÏúùöåuÈÔŠž¿­Zå —Sc©3$fÜ:ðrî"+ÿK£Žãô†E€Yg"oeZš[k6®Â4dEÞñÈRÓ¹öiŠÜH`å>"¢Ð^ ½º0ïN(yòvÑ%¶‘×T[“‚Z½LÞ òfÑboÜO·€·ÞK•¢†Þ/× 0bRç0b3࣎`•m]&ýþ ™åö™ùÓ‰Ór-Q¨ÒvŠd±6’¡ '´^™ù`R7†sî^F™;úÌqu¶{\¼•ãeÝØ°ðì«É®^Ý]ýv€TàB¢ÅaÁãE¶½úðÉ_¬á!NÂD,¾(Ò-0Ä î‹Åû«ÎÏ$"2E-§ôëÒ µŠÆùÀ'2íPÄ$ôÅ(4<dÂ,!4˜Gˆ˜‘Pð¡¯s`ãxÕ$évB$ñi8‹L!¬@â€^ “Y‚E`«(˜ÇX÷ Ùjz„¢D!¾Å€ì4' ^ø$GÔÇœ$œ›6³³˜À,ƒˆdk0ÂlIi-‹6ý¬—wŸ!ž€è "@l'1äèneÑæÑ«™4§·ÇôÄf"ß«lBÝÂÄ֝дi§Üãq\Ï MN€ 12hµÇÉvÚŽ`ˆüDñà\œDe–æá)T²Æ•:¡òbS¨ õð­w 2]5'P9ƒ°è "‰‡"¼X5U±o'Ðè»Äí`7°Ø9Ø9޶‚ƒözv \ìèÉN¬ È“˜…ƒòÝѨ?G¿X¯àɰßßöi‘·_O@t†žiißÝïùƤ‹l‡%ãMUªŸ<¦m[ç+\'uжò«?¦ê×ÚÂ?Ö¾ŽƒyÅ:0÷; æ‹;žÀaHá8¹?8.æ1‘øùXzF^&¢?ô—XEê/¹]näí°òåŸd%»ñr´µr>!V]…tŽÅNƒ~1‹ ?Y¥À.4$<2 ¿¯êL®?Ÿ $nfƒÆ°’ ñ .eb=ª ¨½…o-G«YUÐýw&wªÌp|3hÙy˜¾žg=Œ P,Ø|™›‡q`Ñ!åbSR¤.Ðqa<ŒéâÈž ºh¾>t£é2v%ˆ;|×å¤+šèn#a¬ÀÈ¡ùj¹“u^­óìh 5KÇkǰtôœU{üäxÜÛÍÑ3åT¦Ãžoʬ–[p\ÖAÉ4³Ÿfò­<ïêòÎažJûç«(°RÊ_TåÃq/vy·‡Eq$ÜpïÈÄà^„$J"z9‹ãe*8™\¯ž¬¢Ì!­¢ô%øSŠ(s(cÃóÀœg¢³+0ŸDô4óù$ÅÊO˜8AòbÇk(”òŸ…Ÿ^C™C[Cˆð¿©¡Ì!n‡ºÅÎÁÎq´ì€GxšÇ`Ì介Y/‡Ð8$ ÕÓª!stl«!ýŽÿìbÈzu¨ìéu”.X°xÂâ Nxr`ÑAãbÇk!”K ؼµ%»ñr´µr"À#¢®N«E‡È/FßR>ŸC ]>ñV>ŸCË.'íëy.)uŠ›àD0§ý .,:¤\Ìãxù\&dùÜÅÝh:ŽúäßwÝü¬ÖEâ´‘êrSþ'Tö8è&¢~¹å©îg)(nA â¡oí–øÞ9‚m^ù²‘YUÚ ¦½òËèlÐÓS–9t°ÎehÉsÎŦ <ðS¹SUû˜ŒÏyN€ °žDÑ" ‰úfÞÛʼnû½c}øz½ýɪ½1W}iZ½½)ï+»±Ü4uTuºÝ¦õ$C<‘€×nk;ÑÿoZMž›G¯a¯ÌÁ.´Xý`Lw‹Çà¼@ŒÆyŸ€7¸ÚO¯ºÚ ƒÍÕ#5aºÝÙý­Íæq=üýZíGñv[5½¬6 îm5ÀNšv¸7Íß D;¤¢wUÛ=¶Ï‡ª1DèK¨/?þhÊ.ßœ«<ätÖRœMXŠÇ);?<Œ Möˆˆ9™Àí9>Åîàà g~úøÎ%™j%9ëNŽ0úúú½¦ÂÏ0»ªÉyêÃ3pS*Të3³=*üfóÌœð4ÓD(NŽå^2`àaÿ RE‚1 endstream endobj 2552 0 obj << /Type /Page /Contents 2553 0 R /Resources 2551 0 R /MediaBox [0 0 612 792] /Parent 2527 0 R /Annots [ 2550 0 R ] >> endobj 2550 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [473.297 128.015 485.252 136.862] /A << /S /GoTo /D (cite.Notif_doc) >> >> endobj 2554 0 obj << /D [2552 0 R /XYZ 89 721 null] >> endobj 2555 0 obj << /D [2552 0 R /XYZ 90 690.045 null] >> endobj 2556 0 obj << /D [2552 0 R /XYZ 90 676.306 null] >> endobj 2557 0 obj << /D [2552 0 R /XYZ 90 624.127 null] >> endobj 2558 0 obj << /D [2552 0 R /XYZ 90 592.247 null] >> endobj 182 0 obj << /D [2552 0 R /XYZ 90 496.047 null] >> endobj 2559 0 obj << /D [2552 0 R /XYZ 90 395.075 null] >> endobj 2551 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2563 0 obj << /Length 2447 /Filter /FlateDecode >> stream xÚíY[Û¶~ϯ0*µ*êjM¶Á&Ý"H‚Ämšƒ…lÓ6Q]\IÎÖçןÎPey›ö¹»Éásû8C{³ýÌ›½~öÃêÙ·¯’p–ºiìdzÕn–z³Ä[º^ÍVÛÙoÎËo߯î>Ì~ä9¡;_D±çüúá~uÿö5 ÞR³š§sûöõ;ê¾|s÷vEß?ìˆGT·ïï?Îÿ»úéÛW‘?8D(× 8¢>C"Í3=ng‹ÀóÜ8g ?­ºùj+ó6{زr/j™Óžß¿ Ö÷¨­jj¯Çä ß»±Ž1[¤‘›ì¸© M?ù~dSý¶ˆ<”{ ;§Zn¤šû‘óy."GÒ`F íNß²§)[>k™ŸÍµœ²\µçáêo¨Ó˜Ï'ÏóóV²˜Å©afk9©Ö™Hb7ò}K®›¯¬^°R„VÉl!RÏ+xÉ+<¹Qî©1û[R5OŸ{2ßR§Ì ùÉ‹¼þ VZ¹íÖ+^óùgùÉèµæ­Dn¥äëóhç-Lm¸¦S2ßc]íë¬( EŽK^›x3!Ü4ï·õ@K7KR@è‚ç áy$ÀüxÌÕ&k•±Ýûz.–Žaûõ×\€^7’i¶²ÙÔj-yŸƒ¬™˜T¸ªÜ‚¬éTÓü®V0¯=Ûì1÷!â´o¡¸ZÅ$ïpó¥ ‰±Õ'„;ÁFu~Våž&^¾ûðÃ<ˆ4JAw“åy(z>Kƒ–T<Äü‹ PAŸxg;òÌ~?ÒœËÍ¡®ÊêÔ°±‚±‚ÈwE$ÛTEyP@Þ¢3k_¾´ñ¬³dŸ3òFcŠ ¥B_ëÚ"bø£ÙM…V)7hÜó¢ö««øŒÐ~ì7i:zn_  SܶÆ'o‘¼K7ŒS#î{Vµ7%Ù´ªÓ¨3ÔsôÏyW~©,™½‹UÈöP1¤îeË£ ðl«²VšÛJ"ç?5ûÍ©•[w|“‚d>ë"úGº@‡ D<Ðö®ê3œp ‹0d<ÀU#e`¤<*³Áš‰ÖQ§’î ¸¶4Ú›\ñâ0©¤äO Þ`[Ël{fºŠ¶¾H íê,‰å®ÆÜfmæ’É;g6ûkÇ®Õ~/ëft)Úvë|¡ÚèF¨Â¥úO^bÛ–ŽG'#v;Ô—Þ FlMÓ˜â¹i\AñZÀ ÉçŒÃëÞ«߬Æ%^Ò€;Ç\p\}+À@Æ1­«SÉ3uµVÓ2DÁQØ«‚­A:±›ƒþ±Á/äå/!Ë«*}™Ã7Y>õ?þzj cª­B¾ ÍŒ}i2Ãa/K §@×^@þŽuåà0>†ôÄ-Ö´`Fˆ ÐK¨¬«£¬[…å’`mxÌê–zˆHE©#^MOòÃ;ÉÖ=™ $¡§¯]]#þ˜.®³FþS2Y&ËÏTÓ³tZUèáˆý†È5½ ØÃȹoi¢·C\H'ȼjG¬›w¦rÀwJˆû9°SaÒ’g—k{g ËòM }M™ @édãg2L1‘úQ?Q‚Iä¥}U:¢¥’~þXsÜãƒÕ±üfd¥3ìvP›vU4×›#Þãjv? ¨¼äûºû@¿X`ƒöjk´.ö*†ÿ¬¤¾*²=³"DГ4Ð æ] ÖïÓ] Ìq×í ŸÛhÛ’ù>=#Àøº{ ¾Fƒq}Ñ€³4&¢/²uÅ/y^5¤µ:èÉ@«ÑÚ¾(ÑÇáA|`­bv³ vã2FµCRaP>1˜ÑW2â2>†Ò2vðt=Zº:øAãž_#ÊÊB LƒÌØàpÜãÌxÁ4™¦¯›©ÖM•Ó,-ÐbA.A+4!€ËG1ZE1RXˆ5Z=$ ½ž;à ÀŽp˜l„[á ¼avÞ0mp ·'Ü ½nÝãBq+ù·þÅ­ˆ[JŽ1è"ãd1†ùØDþ0ú9¹«/›1˜™önõìÿb–X© endstream endobj 2562 0 obj << /Type /Page /Contents 2563 0 R /Resources 2561 0 R /MediaBox [0 0 612 792] /Parent 2527 0 R >> endobj 2564 0 obj << /D [2562 0 R /XYZ 89 721 null] >> endobj 186 0 obj << /D [2562 0 R /XYZ 90 591.624 null] >> endobj 190 0 obj << /D [2562 0 R /XYZ 90 305.323 null] >> endobj 194 0 obj << /D [2562 0 R /XYZ 90 224.252 null] >> endobj 2565 0 obj << /D [2562 0 R /XYZ 90 208.312 null] >> endobj 2566 0 obj << /D [2562 0 R /XYZ 90 140.566 null] >> endobj 2561 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2569 0 obj << /Length 2048 /Filter /FlateDecode >> stream xÚåXÝÛ¸Ï_aÜÃU¾‹u¤$JÖ}Èw÷pH‚ÄE.ÅB–é5QYr%9÷¯ï g¨ÕW6ÉŠ¢¸“ ‡Ã™Z,nbñêÑÓÍ£Ÿ^&Ñ"õÓ8ˆ›ý"‹D¬}©Åf·øÕ{ö×'o7/Þ-W^ä/W*Þßß]o®_¿"áj6Ë4ôž¼~õ††Ï~¹~ñzCý¿½ï”GZOÞ^¿_þcóóO/UÐs"’¡/Â\´>Du v<=å•Ó^ CžãǾò¥,WRátmªÉgV[§~ Óx±ÍA“oYÛÖf» „wnYtª+°ÓݰJ¹£N{Ц¦îNï—>‹–—ò²âì&í«º›DïœsßÑXãŒK©<]²‘¬fÝ«A(«$ñ¹XIØNÀ)“þCá’©ÈíVã*ÑaXê†ü˜ ‘JüX*7i…®„ÎÿÐ;šÒÏGD^kŽKéilu{§uIjƒm5$û ”0¥3S¦ÑyUîÃ6V!DÿzOŸËŠZNÂ…F† 5'›BzÇ~`]ØÉbÅί¤ôSÅ1ʾ”,V{j%5äõ §óÜèO!Â2ˆüT *ˆ(ê£2dTfõR®½ü`Ð JÃ@8žü/šÕèc—¾ß‚ÓÐW"úí@‰Ôéâ&?dåíç'=؆€”Œš{áí1ûDPÆA@M?>8¾;˜ü€Ý¨‡:þfCfÍWi{!ãµ1Ø)íÁ»]‚á–,»=l­‹ld/ïÜž“»e¬<¿^*øm‘¨ƒ€ÝÅSMÉ2Õ¹!É=h¡~ÔpûÄ.MêÁ¤Û[]Ó„Îü ¼6ž[;ãÀæ'+J{ˆ¬3vãb¸e n[[^I#ςڬ¤Ö3Üy†tÔGx%á®h¤¡öV—ºÎZË(Þwæ@ûB«T%Û©ø+TDu¡üæƒWi ƒ £¥¿_& Tö¶Ó2%: ½¼6-óùho`IÁÕª,.®Çª=`‡´Clüˆj4«ÒöUCËh$±L€vmÖèpÉ‚õ(»]äxé8^0ÇÏ𘣕Í —ûÞÜé5Ó›ïíè‰Éf@OÁ蠟lÛ<@Mk?NÓ>5…ÂRS(”DM ½§&Ô ¨ ÆîÈ´!5…î°¢ù™ —Cùj"·‡wé¶© >ÒªGIjHI$b6PFRS~PCFR÷Œ¤:FR}Fꙟ0R¨˜‘zJ3+çÌš‘ÔŠ‘âÿ#uõÓôòF©;)³Õä¸)üÜôÙJ?N NëWúaâ¨:]¥o¥æÈâ®ÌÇÁé(“r§]íO†'µœPð3fÛ’4KJìóä¨rZ2é^‚œGç­)o¿âitù­å¾{‚>ûñG~ÆZžF »v•¾="ö\K‰@A ‡êøÜŠ ø–³y;¸;TܱÊH3ÖKkëa²Äˆ;HE”¬éÙSŽ™Mô²¼5÷í-%Ô½‡äÅÈ}^µ9oàíla@o–N}y¯g8Û‰!õM™;µwœ Ø?d u:›v•¨3JdŠšÚcUë¹õF‹L?FŒø8 /oÌ”³ûv;eHüŽBj1±l/#Z¡ýY4.$À/І7˵ ¼Wއr}¢œáðXí&ttÚ˜m¡Gï7éG鈂>*ýºRñÙ×áh}ÞqžÅ6ËÿÉ®u{¨v®\sÐzg .Åř˟¬ù.¹1k v6~ØÙî1=ã-•6ò¬D7êU÷ºv„.[Șæë¾;îÇL»÷6¹7Ú|ÞemF€XÉØÂõ0gÝv1õÃ¥Üé®Å™•üP5ën;w°:þ0*ʦ,*˜?Õ€?}É ú¾¿„LÉ3lcÍ«Œ"_éà?œèò`ûæ»o¶Ç?}1Öt´ê þ(Â\b[fWö#ìû±NüõýŸÏÉq“ë·õ2R^õéruÕ­zC_Á8^•x-Îì kv?Mƒa-ÃUÌósÝ¥ã!Øð’½³9‹Ô " …/ÛŸ!ž¡!@ÝæXíí¹9Ü›)æþ>N}uåÏÉî+&)†a„Ik øƒ¥$_ÀýxÏ5åhœ—{â’ÄOÄzôʭʆm4-åûßS¼õxî*Ø@aX]]½@ó›ËIÓ$»ÚCúÏÀOH­Jªü8BTø Īý`?(?M’EOìø÷1ó†~,Go¼mUnHºihøjöYÑhDèŸç ¡¦¿`ûÁ%. ï+…žhæx*ô‘oRø–‘عHÂ'!Š-†ÝƒÐÒX;† ¹6AÑ¡8y)=^s|iûTÙ¼®ZžÞ²ÖY4< =\Í对öÜÜÝRKªa8¹Ïøë…ô3våô!5ë¬çÊ|2•;]:ý0~óî©OªöyhdTÉíÈRv:&ÏìéÙ•ƒA,ÙF+ ½—¸*¥*D£¤Ï!5¶ô€ÑVï¹Ò’Þú1P4l ¼ ²šDÏØ»3íz\´IŽ^[óD,¡ Üš§î#ãÄÃ7|#ø’µ‘Šé?IlÑÕÜ31[v•‚sP*}=q¹zâ³ÄgŠÿo$.´£þ?‰«óÓªÜüë¬Ïú¦1ÿž·þm$4‰Ü‹Í£ÿ¨‘v endstream endobj 2568 0 obj << /Type /Page /Contents 2569 0 R /Resources 2567 0 R /MediaBox [0 0 612 792] /Parent 2527 0 R >> endobj 2570 0 obj << /D [2568 0 R /XYZ 89 721 null] >> endobj 198 0 obj << /D [2568 0 R /XYZ 90 690.045 null] >> endobj 2571 0 obj << /D [2568 0 R /XYZ 90 673.94 null] >> endobj 202 0 obj << /D [2568 0 R /XYZ 90 633.532 null] >> endobj 2572 0 obj << /D [2568 0 R /XYZ 90 615.534 null] >> endobj 2573 0 obj << /D [2568 0 R /XYZ 90 547.788 null] >> endobj 2574 0 obj << /D [2568 0 R /XYZ 90 480.042 null] >> endobj 206 0 obj << /D [2568 0 R /XYZ 90 437.577 null] >> endobj 210 0 obj << /D [2568 0 R /XYZ 90 296.73 null] >> endobj 2567 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2577 0 obj << /Length 1837 /Filter /FlateDecode >> stream xÚÝWÝoÛ6Ï_aôIÞ•Ô§•¢ištº4h=ìa Y¦c¡²hPrRoØÿ¾;ÞI¶9K†ö`˜º;Þýx_<ŠÑÍHŒÞ½ž½¸ˆƒQâ&‘¦‹Q"F±˜¸"GÓùèWçì‡Óëéù‡ñ± 'pÇÇa$œ_>\N/¯Þñ”þ¦ãÄwN¯Þ¾§Ï³w—çWSZÿü±îI^_~ÿ6ýñÅEèí¤ï ?ˆC QæH0èÑqÃ?öbØã“Ôt©@ià;Y‘«²ÆµçdK­+U£n$ªüwE|½è°<ÇèM9'šÑ³¼¤¥{¡s;–¡Ój6*Së:×,1{ÂÙ,Pn¡Ì8 ð•/&Ω1¹Ý—7´³£Œ¡ÝåEÁŠHW¡bL›²Î ôxâXJ7 9Nt€ÉÞé'ž³Á£“{ý=÷†°”AãÝ7 ¡Ü智6ã tô×íÉÉÍX GÕŸ‰‡8?‰PÀO„KBÂÄ»p՚ؽ_k“f §ÅØw'æi‚Ç;ÈІèÓñD8iyÃ:*TJ…3µÐ†uNžÃ"”XU¾Ê‹ÔXWËhâF¡ìz,K­Ë! ïòzI+]*Z´Øésšt¥jeès¡M#Ö=> á IáB^ÑZTšWÚ[ÜšÆY¡\ Sn]ï!½ü Ÿ®qÙ„µô%. ƆVeœ+ü.1q9ÛîöÝÏù®6lATñö"èI#½óM ‚Kg–VyÖEeýÀÐȘ[g[lÑ9¯ìÏ@¸hÃè‰Àõ¿ë¡j­²XaÉ‚ èR¤(½(!©Þ®ÁëÇ‘?Ù¥‰bÜÓÕºà½wKU’:@2§CàþFwU§µ:d˜Á“`gDyŒgÙò[=ëTu´WÕ~$ï!Ü29c!ÔnH½O[ä#Ⱥ5,Éz…΀®s¾×—,W—U^±E›{@LY]Z×&§>Õh+!H˜½!a ‡‘»lߌìµÑ¤å<5Øþ|p¢ª‰lû6üÓ–Š>RÛ `‘cüV`Eñ>Ì~dPBµÛªV+lœc>ϱ“§1ç„:" 7¡ËîM ”D©¡3u¡@ñ[(ðß1ßPÆäÃýbmô TÖ ‡û]z2¢ˆªªèÐúé ­_ÑßËšoÈËyžÁÞP/St-¨•ýæ†V6³*3ysï…/.q‘T–){^°ÙG&XñM¾§™HÝT¢¦=p\[3"t¾”UÜ•”+”k¸Øï¬cˆìÌÖ±ÀãÒNÊF ì],H§„À(Žª®©Ô‘³ó,î{Åz̆qm•~±×&ÑÙRØs²ØAχJ^u}$N¾ ÿ”¿{e‡$Í"õÒÞ6°¢BÄÕ{CÞSoˆÔú DyŽ²Ý« Õ½ñ'égÚá&q–ézÝ€çðI3b%½ðÔLÿ€aÓìlý¨—(ß¶%ý“5;qî,3Žó¡‚ºÒhR&‚+W¨“(è]\­ô\Ø=O5HÄb–f_XDÕK=§5¡ÇÕŒeéž±.È6¶7Xî¶1ÔbÀ[‡ÖsmS²áß¿Ä}_ºÿ ç:¼‘]?žÜŸ›\’ŽÅž4ƒÐã<\øp=×ÈBpZù~èœÁþ×ÖM¾Á¸šVC3†ôc×ß ©—%oþþ{1ÂfB°hàEöó‰8ƒ"¡m¿DN‰JFI \ÂlÂÕ £WÄi ì2ˆú#ë8eïPp÷5úw× ŽUÕÌ93-ÊèPAáðrÂ¥AGŽ ÝÚžµí¿Oèo½™8ãzŠ9urÒú{ þA} ^¹¾×å¸Câ ruÞæ¦Þ`{'PÕò³jr‡aã÷x•Ùí0¸2ÁÑÛ&Õñå„nbŒ¹÷’œ#ãÞ»ëïMŸBÿ?Óå¢Þ(ÂÖÝ“ ÀÓ/I¼§B@« õnûmCâCbÈ•(y2u{Y‚'ì€ÞÑx}Œ#öEpG2q'“§Â¸Î×}ë>Ô½XY·ñë½Þþºv†J æÃ=¡}£X@‚ß{ô>XÿߤĻNytåBXm‡þM2"vÃ$~Œ7çv+ûSJß ã [×UMíØ€8G}ÆAðåÂŽ¨ ú Á=µ#Y3›w ?\ÃmZl†a³‘™Ö‚“‘sǹ1Ú¼kž£VT›ªÑ;àêGg×®ãü7Rk¸þ_S¬M®Ër¡Ï¿þ£ËÀ[ÿV†Ý‹öùôè/&@ endstream endobj 2576 0 obj << /Type /Page /Contents 2577 0 R /Resources 2575 0 R /MediaBox [0 0 612 792] /Parent 2527 0 R >> endobj 2578 0 obj << /D [2576 0 R /XYZ 89 721 null] >> endobj 214 0 obj << /D [2576 0 R /XYZ 90 509.995 null] >> endobj 2575 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2581 0 obj << /Length 1386 /Filter /FlateDecode >> stream xÚÍWßoÛ6~Ï_áGi¨Yê·Ô>¥‰Ûy(Ú uчuh‰Ž…É¢!JIŒaÿûŽ> endobj 2582 0 obj << /D [2580 0 R /XYZ 89 721 null] >> endobj 218 0 obj << /D [2580 0 R /XYZ 90 186.069 null] >> endobj 222 0 obj << /D [2580 0 R /XYZ 90 126.469 null] >> endobj 2579 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2586 0 obj << /Length 1253 /Filter /FlateDecode >> stream xÚÍV[oÛ6~÷¯Ðú0ÈCÍ¢®n Í­Š4K¼í¡-Fbba²åJ²cØß!åH¶œ86ô‰Ïíã9‡Ÿµî-jõÞz{§kE$òßÝYµêzÖ(±>ÛG/G'WýãQÛ%ýçSû«óÑùÅâ2êGÜ>¼8û„ŸGÏO.F¸ÿíz¥¼¦uxy~Ýÿ:úeïÔs \Æ å@Ô\®tzÔ€¶µ|à`ÃQëS>™k‹,SnWc‰'²ïxö¢Ï<[N+”%¢(ŒÅnv’2®²em fU!âJ&¨(JÔ.ÁÙÇ´¬Þ¹—ªªâ(ŸÞmÈÑLk1[^I‘,WjuK¸á€1y&ÿMß°c¼ËùBŒÅô^v½¼Àõ2mSyË)îæe:½o¥¸^÷NmÆqIDUÞ¡NˆS•SŸ*l‹4–—Eþ¸ïeu#´üB=ªoZ«}½•±Ö½I“·­$ø¨u²h¡Wú?¢A€½ÓfƒgCüøŒÖSÅ¿SœþS3™žû¾ ž›-þ¿ƒõ_ߨN×xn¯‹øÌk?¨‘æ-¾É[Ü«y „Êo‰[QH”¢n\å…‘äw¸¶(@Q »iJË‚r:^Îûf¸ß —®üÌrÈ£Ôí¤ÕwåLÆ©Èð#‘eUÌtüÓ7q&Åt0Ÿá×DVã<1®ªW)JiNƲ֛äÅ÷ÐDI Gþ5ÅÅ™(K¬j«ÐÃÙü6Kc”,tâ÷W :Ž*Æ!!$p]ôö“–x$ B«q|€Mìø!‰"ÖnÄ€N®é²¡¨ýs/$>TFâ뀫qlqß%>wÚ5mê&•.D›š) ð^ƒ(ð‰ÛmeNTÚ:’ËBâò×@s¡}Üuj@ÛàŠ.D-%L£$äîÎmCmò wAƒEª»÷MSAY‰GâÁƒ¦ªµÅd–ÉžŠH¯Ç±RóMàÙi‰«À¥ZÎÒX?høˆóÄhá…¾áÀGVz2‹³ùM¹Èq-´Ñ=$HFY‚Å2}bÆ:Fƒ*KSyèÙ§iƒSèØË|Ž2wih,ú0·­ü5¨%‘_(u¦æTJ‚óVÄ6)É(fºË³,WÊa'뜌zßz ¶ÔbjææÐiÌÜñ¤÷ù+µ8%AXZkbñT¨û̺îýºáRÏòm.c É̉â±`ó¡äÐ|ØjGp§÷úNJ0Ä¥Ù›#xùp¸Òë ú¿ô!ƒ™|E¦ÕyšÔ.Ë1þzÕŸ×8m7;‹qB¾åÕ…ÍW×øù;Ì#,Z+ìßïjœ'@ªk`:î?î€; Âh—ç8YÖ®˜!/'$te1¶&> endobj 2587 0 obj << /D [2585 0 R /XYZ 89 721 null] >> endobj 226 0 obj << /D [2585 0 R /XYZ 90 361.95 null] >> endobj 2584 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2590 0 obj << /Length 1054 /Filter /FlateDecode >> stream xÚíVKsÛ6¾ëW :IH€9íŒãÈ®;×Ùæàx4›œðáð!Gíô¿$‰¤©ÄšÎtzèIëå>¾]ìîg£·Þh~nàB×2,àÝ9 ¼ÜNÎ~<½ö–ï§3ƒ¢ ÓµÐäÃûKïòêB*Oå7uÍÉéÕÅ/òϳŸ/—Wž”»Ù÷¬N¯/o¦wÞOósj´@lBdÚbƒÚf„èù9Fmë™á HM"[(MéôæÍtf!4ùˆ(ªÝaBƒ†6Q&ß5z ]Û-uU똯6~\qáoÑ]c83\è8Ž¡Ki7 Oƒøä°YÀc^riÚŽ¯]¶–Ç_‡ƒÉOH)-©d~ÉÂ}ÉÂ{ÇR¹ÿ)Û1˜eU)Cè²Æï°Ë OË3?ŽßúìÓbñXáŠ×º:Ug!ÍE€8bš©PüK™ûLýø¥/¥W±IÒñÉ·Ê<Ø›Ý<èߥ7ú<ÂBD×sLE¨å–Œnï„^ôÚ® ž«˜®)²„ƒ›Ñ¯r:£ˆ.!€´Tz/䩘_âLÊK!ñ#¥bY uUQJ©¨ÖË£µúPf=o>5èd3ÅTŒ‘rñÓ@Å ³¬à=‡újÉdù³Oq¬ò $J¼×f™rÎøãLöËb;Í.£,…rImÔîÌ€íµÄ%6[&XmRá¥6{ñ¢‡$ŽÃ8æ!û!›‡íž \€l@ˆ# q% qo:ƒ±ÀMÕù ÃçƒtÎîëÚ½™öïÕRð') äQ›€ ©áê¹—ç§ÙbñŽo"ƯóìËV2!µÉPvT² ça4Ïã×{=N¶sé5ÇãzÉ5BÝ‹¡‚¥zÝëšVQp2tzX–Ê®(ó(}²_–ù*õÞ¤eUž‹­”½(:E§]áì‡Ý¶íOÔ.ÁkÙ81…Ät»QUá]],WËß}½ÊÞ{ßvc:a­ƒ7UâgqÔ: òS¯¦q×±[÷sæéÏÕë†êÙ»#™ð2Ì‚B½@Îõµæ¬*¹Ê±ÞÊßR‡hšÔB#Åæ„ÔwB[çÜà‹0Éù÷R}(z$"‡ñ<Õ¸²ûþš÷C¸§ÉÝÃèIÚ ï7o°Alh#r4™v)C‘©!nœíXš3ÂúgPh ?Š3 dBç8ò?‚3°%t.=‚3^ô/ç?æŒö<õ.òçŠW|UDt9@ [oÎ>‰1ìm}ìë«-ÌŽÞÿ\õßá*«}ÿôÉŠþÛd5´ÀÊçÂê endstream endobj 2589 0 obj << /Type /Page /Contents 2590 0 R /Resources 2588 0 R /MediaBox [0 0 612 792] /Parent 2583 0 R >> endobj 2591 0 obj << /D [2589 0 R /XYZ 89 721 null] >> endobj 2588 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2594 0 obj << /Length 1959 /Filter /FlateDecode >> stream xÚ½XÝÛ6 ¿¿"蓃Í>ùÛ^·mÑÞnÚ®M±‡n([q´ù#µìKëþ÷‘¢ìØ™¯×aÃ^"J¢HŠü‰¤ÃVÅŠ­®.žl..ŸÇÁ*uÒÈ‹V›Ý*e«˜% ÂÕ&_½³ž~ÿøÕæÙëµí…Ì œµFÌúùõõæúÅ->¦a³N}ëñ‹«—4}úãõ³¢ß¾™Ï¸¿º~³þuóÃåóЛ¸¾ÃüLÔ6!ò\0côås—M¹m?I×_Ù^ k>¹¼\Û;ö"ûHq#Ú["}”Èš:W49îE·-MjqÕáØóAo[y#r3© ѵ²( ‹ˆŒ—å–FT ¤Éñ>pÛu4 çïšs gÆ8K§ÇS¿°Éº£‰üŽ=4 ßÒà²qý«¯à„»$ò½èùNêÎ7T)Äá¤ÍG šß_éµàùÙT×´ƒõµˆÌyÇÚ¦:;ó¡½8ó9z÷K>wí Zù¢K«Û\ÜÈLØ Ñ½'ßã}5õ^æ_“›~[Š÷ƒÖ“3ì×ý¹ä&Ø ÕÙúZõ[•µr+HåTã({| ÃølsñáÂ’­\|ÃaÀ–¬²êâݯl•Ã2huâ4^5SµòÓÄ Yt¹zsñ“IpðnÖ ­hpš‚<¬wm³vCëFæBѦ$nõ RGÙíi“Ó‚’uQ¶C£ñŽ»ÍŽ–àYwmSÒ¢Ž:®òa³,EÖɦžÊÅÚCC2¡0ÏQOnÒš—Mq»ŽBëë%¤45šÂRÝ—9’`¡0kœ†©`{ð2¨ £vÈÇ[Z!ËO[3Ë™±ƹåAYÏѧt:±d­:^gë{ñ/›…¥S“ //ÝSõ‡C)1N˜¼¹‰¾?ÍÜžÃ<&qgMUÁK}/ë¦×@RÍfb߯SËE]C£Àû|Ä‘õ0›{C(^Êh¤ ºIŠ)bv@”¢¢¼®ùvÃ…ôP (# Ü ðæn@LþÌ}A0ºv¤¢%^ª†V8-ì¥hy›í%d Úh¶¿ADo)³®kbk¨áþqí‚m®0xQlÉŽXH…àWJnõS€YglÙ®=fõRcñ¤½8Y¨‘ƒŒ ÊÜ4pÒ ˜_T@'ù)e\/€ŠQç’à–÷x ÜœÐg±µÙKsp'x×·ÂH)ËYŠ„e-ìÂ[¦]xdäœÜH1åÔAòMv@b|㸫nU'*Ú°i<ÛÓæ i鈮؊C+`Œ8¡`*\Ùa(x%ËÛ9l&—7íL$t›ì#P-y#ïÅ!ÜN» ¨lÏ ì‡Ð{‰kí¥Æ3P ‡c!ÚjáYºAå&^Þ ßo×~leHîo—ú0æ$ºDèSú-‚ŽVìZYâ4€é  dg.„n @!D’ rÑ)TœØÔCÑ Â;ŠŽí§±øÑÜ©PQdQónˆËLÆ4P6cp•èî‰*ï:@”8KLCŒ"“¿0æe4¿sUm•7ÔÇÄñÂ`,ªŽ;”UÑ`)»ímTÿL홤C¹ê³•ØMœ(!E›áÒz ½@ú #]û ÕÅÆÈ3wª®ÏÍa^OÓ5¯¥€`»°2w¾€ŠR×Ñ0ÐP÷C¨Y¸Á`ð¬ï+š‹™E«ˆï¸ohÖr¢t*„­ª©e§+!,jT"qj€eß×94£Š¶tj„±XƒÆ¾FE.ô÷”XÑw&Mjgt©ÂW9›ð„ј‰²TDjwÃÈi(¹h!lÐ4ǰ~·}¥ûT(®õŒR›‘d(¸Nš)B/Y¡1Ag!êšBŠ õâ [^K¢Ç;E×aÆB¶Ðœ”ú¾gÚ €½€Qñ§î(«\Y/û–Ö+8JZ¨luM¦iDê(ëÖHæTêÆoI\Ô­ ð Fý²µy;ÇKbI =êcÎëÂ,Ù„  縌„ÖäµkÕúU`í§áGf=ÆUŸ7ƒÝØ;…C½õ(XÂ5Xðä­ ˜«õ5Á‰9ÒùÁÈ×]YÝNŒñÇ®y*q)¬'Ó‚xèÇYd™¨Òd<¯gÔ‰F'ÞX7ì, ÒÂë­ÒwBn:…iQæÔ*VÎlO«¦‰Pædk´j:AbÐ8Yì;è™)Ÿµ¹1i¹Í{w:ÂOV²tü"ñ°(à§ÙáüÛaüfI±{ˆVx?>-Ÿª º p¢ùÆØ è]‡O fKßDMOŸ"‰y4°õ`„ÂEE÷Îtdºìh8&/Ê g…p× }Ù$å·}†>ÿfñƒóüOT³jôË¡ù®µÑrAÈÕ®&Ëf~‚ÒàÛÀŽˆ±Ùâ_Ÿ0¤ÀòiàÅÔhg̽¼á™­õ\(]xÔ;>¼±Ï©ë’{T1÷ýO$y_&‰9Žó_)þøñËGEcYiܧLŸ¾Û]swßîK]곸óþ î¼ÿwÞ¿ÇqèÒŸH”›Î9 endstream endobj 2593 0 obj << /Type /Page /Contents 2594 0 R /Resources 2592 0 R /MediaBox [0 0 612 792] /Parent 2583 0 R >> endobj 2595 0 obj << /D [2593 0 R /XYZ 89 721 null] >> endobj 230 0 obj << /D [2593 0 R /XYZ 90 524.653 null] >> endobj 234 0 obj << /D [2593 0 R /XYZ 90 384.304 null] >> endobj 2592 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2598 0 obj << /Length 1499 /Filter /FlateDecode >> stream xÚÍWÝÛ6 Ï_aäÉYkG²-ܰ×®½Þ6t]›a]1èl%6æÈ™ì4;`ü(Q¾89»½C1`/CQ?~”Iâlâ\Íž¯fËWIäd~±³Z;q’ú$bΪp>¸/^_¾]½|·ðFÜÈ_x,&îoï®W×o®y‰Ëj‘…î囫Ÿñ®_¾Y!ýëû;á3©Ë·×ïW?,_±``DDCŸ„ ˜hlˆb-3#Öèå+J†Ò^˜Ä>M˜ã 0C<ôÏ !°ÂY8çQêgŒmzÏ^ Ä®R\VŸ]x4ñ}Bž°Ý‹å¢®=>ÈŠs•ñ‹Ð„x ÙJŸÅÎ c?õÍPõÄxw¥°éyòä)Rí>/‘⸔•P\“¹·Èɹ=~cOß,â°[\×M]7‹€¹Ëø0rÃÛ*Ç¿Ÿ”¹BµU#a‡^œdµ__®fÍ(Ä¡,Iü N|;ûð‘8ð!@~’%ÎÁHm0K}Fb kçýì—{* ÊO1Ciäg$qc~¥¥åÒÃȶؑ ›?%x'6áÓ„jš©jö»±ä®¸Ü4WwûàTÁ…£ß˜ ægIê Ø¾ßˆõ‡‹$†juxç(<×ýÖ¨óÒÐÓúñŒŽxƇÞrݨ3§¥×•GL?ÚçhÜgË6*æ1VtyÌçÀú¼åžçòx³ B»¿ñhÖO>&Å{Æ‹B›¬¯8ZK¦SN§f¾RVr3ÿÜ}>Æê?Ö|[Õ·ÌEoÔcrY'!8–è`µYUP79ÄÊW²k&s¨­’ͽ‚=Àc•s¥³A'f]¿KÛ¼’mçå„.?ñÜ3"ËÞD­ž%?ƒ<Ž—t2,éa€‚ÞxÑ&QÀÎtçÆd€Æ#2â¨)žÞÁ¡×÷ñ9fZü9€šoèü!¥ñH¡âUP2 .üÄÿŸ±ulB‚: >¤jO Õ#r2é4¶&âó_@kİlÒ°yÛe1Øö5¦…¾¿âËU Ä ´)zjP6õ UbË«c k»Ú)ƒõ9 NMê²}â;-ʨÇÑc:-œȰ±"ð¸4iH|ÚCôz»kTÇ%„-È×ÔÐýÎ5f~e}Óp3æ®J¡«tW ãƒlðÿŽ«®Ê÷5WÈoT!nu ²úgÊðJKœ4¸1sa¨‰ÂÔ}­«Ð¿¶S]DÄ}ª›ôðxÀ#àÞFÞ»ü?ÌÂÓàqèš Ô_庼š¡W°‘7Z1^\ «+!É›²Ùw(z§¤®Ö"×’·ymYºK9‘ÁÀ\¸ ¼Ô½‹fÞX¹¼ÔÀ/|3‹@¸¹½ì° pÒHO A|®ziÕvW‹­·›=‡ë„8Eú2ýúâz(«~(Q¢Ý×'¸=·Û+)Šã˜Ñözo„At=à8E’'¦þ¨e„Ø™R ÒÌL?i š×8™ ä ¥}Xõ¾iþ4˶ˆšir,!u¾†'Sè8%߈-ܲ©­Â³q 6µ;•/4,1êÊž’V¥Æs¼Ä@nÌÃ?u…~ Â rá}Ó>iRCŰJËhÔí{ÞÖÊ(\+YTØbÏkä Œ1öXèBÅm ¼0õ×T¨µRùN5¸ OØ«¶¢+›ÂþÑQÓ+$XUƒRD.Ý ]G8Y¬ÈS§hÞу€Ø¡û¹¾3ÑwÂýX ʰN nLÓøßÚ¡yºï€C¶ŒZ»/:KaðAÁ*a,.«î™ÁVÕ ç%´€J«Y—³f¢ £1Jl‘}(Q²×YEí4LàQë ÃÐ*Ôoc>½ð ú dÀnø4šºµD3Ô€4Ç¥ÇÙPÐ;‘wÕQW};Üïmr”¹x«š¿Mÿ€{Ǻ×nnO.ÊM«g­™øàý ë±ëi endstream endobj 2597 0 obj << /Type /Page /Contents 2598 0 R /Resources 2596 0 R /MediaBox [0 0 612 792] /Parent 2583 0 R >> endobj 2599 0 obj << /D [2597 0 R /XYZ 89 721 null] >> endobj 2596 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2602 0 obj << /Length 2241 /Filter /FlateDecode >> stream xÚµXmsÛ¸þî_¡ñ—Rs ðUô½t_â:sMÒX7ùËÜÐ$$³G‘:‚´âvúß»‹]P¤L'çÎÜ@`±x°Ø}v1ÛÌÄìêäÅêäìUÌ7‰¼h¶ZÏ1‹ÅÒA8[å³Îåß/Þ­^¾Ÿ/¼P8;_„‘p>¼¿^]¿¹¢Î ú[Íß¹xsõ–>/º~ùfEíŸozá#©‹w×7óO«×g¯Bo"¾+ü  AŒ2'‚Aƒ°?^Xé…C§Os`!ÏI«M}~~Õ̃Щ»Ýùùf.…£Ú_7¶ë øÉ Rz®/—J6JïTÖs/tîç2tTù0_ÈD8m͆È"Ï “Ð*ø2¢\¡¾û"S_ƒ !I8ÖÿY+r§&•Aòe$Íܵ­Ðý—P,|0tàÏRºIÈ~²Uí]Ó©•nUʨH+EˆŽý`) ú¼j5³2Õº÷jäuÖmUÕ¦mQWÔµ®SmZ”šl`g2p“ £û€ËÁÒ¾9YZa#vªÏqO½;Õ€Ê-}€Æ‰¥­Šö$ J…àXbÍÿ]C£§›yè¤ÝFéSÙà^M %Î+TS74€fK«Lý>Ã¥Sªö/ó0t4,ª iä#†NìtW—lã»B5i“ÝÍ Rc~6÷-Kè®é&m©•–¥5¬qsðH>ŽÔ §å ÜQlÚÿ—«“ßO$4ÅL"§D^àFI0˶'?‰Yý¯g“x¶7RÛ™Ÿ,ÝPDÐ.g7'ÿ|¤Òp•ãx ˆx‰Ð•±$ œ-æ‹H¶¶ŒÛaƒ­ƒMkcK1¶b±&!tÞ9¼Å¨® 3úý÷¬¾é”•^SDšþc:=ßMäx ÝæççYݵ¤ã»ïèÿÔØ[¹bÛã˜ü^ŽEUåå·ä‹üwjsªÔjªÿùP¹£T©æf])‹>ÍÏn;ýpVÖÙo*?s]w¸¯gì%ì嫎$ÂàEÏp4J‚0ßlÙã,Dð)Î@nìz@° ¾B߯›}Ú0ÃY&ªj¡õAâoü‰f_ºQ̺o ˆyˆì¨†þ䈟LŽØ,ôHÐúp‘¥%öíÜþ 2Hì X* ›Kb0ød¾S9}ÚnV¼9,It [ Óö˜#`wvvËH‹VOÅ€înF£€öþQ£¿øÂ'º„¡Ø <¢é£¨ŽF­)Dc-lÁm Bï]:÷3MIéO× 0R ˆgGàÛô¸6G‡Ù0Ÿ8=?t…×§ÒzÇÉ–Èêªmê²$¢6° ²жïúq4«]SïR“Pf8±£ÚH.§k )À#ÃÇ:å >®–îRöRè~ÈæÍ}jƒ¶q-‰ž€5 ö ]>­`?Û¸4kLç ƒäÁ{ óš}¡Õe1/rE¼Ûæ€L2‘êšzŽ]PRjC!F'N‡ r¦Ä©É%u“[‘Á‰½fÑڧգązõ2q®ïå7ßÐ\ÖjwzD·ƒMm€·Y_ò|´¹vW¶šFMî†L6ÔƒÉòvõ›æ‘š%M‘ö ´Q¸7Ò¦£ºeïñ¼Ò’™‹ø#g†âµ ^£â5tÛ7­­ÊC¡·$VžØëkK\ƒkˆ*?* Çö@^Ýʽm§Û£ÚåŠÌ-„†5×7X¿á©Ü¥`Ó: òàn³Œ¬î3«¿ü¬²®5¡kàq1Zo·ˆôI_’¦ 0O Ìæ0øÑçê1uê`(‚¾Rìߨ…1ƒƒ˜Ï ‚€lƒCƒŒ€3˜q–¢‹C®,V; ÈŒÕèb[”)jYY¿Èýú‹©3|‡›¢ŠC:‰ÕkÀj°a.2Ÿ £E)³pa„”a"kY“©lhÁhŸëá§Ip€2™¾´:T¡ %@ˆòíŽÊqCªz¸vôÄåèhŸŒìעŠçñÉGT²–Q)]¹ø/€Z¬sVÙ]Sƒ}äîé£!äØã [w»]Ý´C7Ü¿Áy3 ®ìJvæ··h¦Þ™­›ùJbùš[_öÁÆ O‚ˆ‘šÞ¶k*Å2¦E%Å9öž‹wM8ÛËmþ^íʇŸ Ýš»ëhư Ì)X;TRw½¢[¤¬=Zéг֔^ÐdÇÀ9ž‹“–Þ“Ph”.”KßQ©¡6è:$}cÁ¢,hØ«\ b$Ë?²ÌÁ…q­^ä»\x|ž¶2 ñ}áÂ…k‡¶&Jâáz‡þf1“£ð‹’-* ôÂÞ2Ê(LÜpÛ”E8ËBCåî¾–„Õ4&ìA¨Î²®iL¶„¼k¨úI–O¥½ z0d¿>J#§5[gÉ=”»fYªÈ\æBÛ׈y`sOYäð¡&î6'„ª©‰B ÊrH8Tô×f ã¿lø‡— 3wDM4¼éÒ&¢Cò&5¤Pö†Àñæ¹G÷®µM`b%|Lª–éŸ+é«S ÆØ°¦ðn5õñÛí•Õž¶-„‰ÕNÅ×@{p 9d ³ÖáÊÅbÍò’‡y¡t fʉñÎÇߨ'¦ÇÏ=Tö†ã²£,é!¨×fls>yÝ<~ðèb!7ôøéq#?¤9:š8Ý>œÑ}÷LÈSt½o§¶óÄ ÿÙ3¼ÃŒãG»)¤½ÜN¡øÿn}õÓÓ%?køiƒßMp£lk¶sñÑéçmd_ØW+[ÖTáb-_ÿV}ö=>t}>u¹š`ÿQ|šiØK¤-ü>ô2m65¦:snÖYÁ?&€,éz~ø‰ü3‘øSHXùˆl‰÷g"ñ˜è¤¹Ÿ¬°Â go_¶usH»ÒRµ üµ-­ì½ðøU3Ï­ìé­j÷JU§(åÉ×ÎÿÈo¥­ endstream endobj 2601 0 obj << /Type /Page /Contents 2602 0 R /Resources 2600 0 R /MediaBox [0 0 612 792] /Parent 2583 0 R >> endobj 2603 0 obj << /D [2601 0 R /XYZ 89 721 null] >> endobj 238 0 obj << /D [2601 0 R /XYZ 90 475.867 null] >> endobj 242 0 obj << /D [2601 0 R /XYZ 90 367.168 null] >> endobj 246 0 obj << /D [2601 0 R /XYZ 90 296.49 null] >> endobj 2600 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2606 0 obj << /Length 1395 /Filter /FlateDecode >> stream xÚÕXYoã6~÷¯ò$k…ÔE)E ¤A’z±H·‰‹>dƒ€‘hY­$º:ÖM}‡‡lÙV¼6v]´/&=œããpRÈH dÜŽ~œŽÎoˆgDv812 mäùÆ41Í«Ÿ.?N¯ï­±ã#Ó³­± ó·ûÉtrw«ˆ—j˜Z‘k^ÞÝþ¬þ^}˜\ßMÕüׇó×åÇɃõ4}~ã;=vmä€(1x¡à! z{<¿Á¨/=vÃÐÆ®1vÐ\¥#uÆ?Ð$ù„|tV¼ž'ìs³sä'ôƒ®1Æväû{%üM ǵ#¬¼Ap‰a‰hÀDgÔöØXK¤Þ!\}½d<(÷ YK¤Î!\}½îazÝcõ:k½[A8v<;BFl;]Mç "7 ÌŠÕmÞ¨9¯V‰©of¥"5ßÔ ‘IË”_\ÜV¼]\É=[䯲ZK'lÁʤ֪6å}ó³åø&Í[­ŽÏ¶ôÏxµ´0˜¨ͱh2^B¢z1'š½fÚXÃõNÝÞN;OjMÖvýù]J¾Sù«`ÀD¹£V–Yž«Ù‹^æ•…C3µ`+eö7K•jþÏs.ö¹¬/3};ÃC;ôá`\×vp¨æM™q•«É÷jÁó¢ eòœ•¼mdX<4´ië³wŠG¸¡î—bŒ<¢§Ï9í@‘Ю‹yÙЬ¬·f]áKÞÕtÑfÒ¶€ðHZáh#ÚÒe×´?˜…}ó/Z,r¦Õ.YEü°¸mØ–+zY¾Š>é¿mG/ç<×ÓyÆ*ZAÎûæ«.¯e<¯8t‡R6ÐÎúbwêÃW4'Ú¦¬ÞÓ ŽúÆ ½JByN$2E¨d@­nØBÍd ]QaÝšáÏ¢â1«EÔɼ ®ÕBÌÛ> endobj 2607 0 obj << /D [2605 0 R /XYZ 89 721 null] >> endobj 250 0 obj << /D [2605 0 R /XYZ 90 174.592 null] >> endobj 2604 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2611 0 obj << /Length 1708 /Filter /FlateDecode >> stream xÚ­koÛ6ð{~…›ŒÔŒ$J–äv²æ±EÚ%Þö¡+Y¢mm²äQrÒlØßT$[ ÚbRÇã½_´c--Ǻ8øqvp|úVÌâ‰7±f +v¬Ð‰˜ãÖ,³>Úo~:ù0;»½À±}6ÇþíúrvyuAÀZf£˜Û'Wïéóͻ˳«í¹i‘w°N>\ÞŒ>ÍÞŸ^GßåÌá!ˆ¨dðcÄ9p´Ð»ëñ¹ëtoy1—[c/'ùb4ž8Žý»8©,Ø*©oI^ˆ !ðïâ?òšc×eq -ðzœÅnÿ ­¶ }õŠÖÃD ‘Ôz[•‚6BÊJjXšn¥Ùaÿº(³â¥â6`÷ïp¢¨E>ùz¡ËjOÀ¯lÏ+g³ƒ¿\Ø:–‹Q„>‹œ‰•®>~r¬ à 5 ãкWXk‹Ç ű ëæàgŠÎ^`¸ŽÏbß·‚€3ÏÕº^U#/°ïG“À~Aau/h]%#ϱïFn`kHSѺ‘U*êš>D’®hw˜—YŽÔîòl›”¢ÞTe-é3/5©•¦YäuÃ(ŠC§‡. ;ö&ÌŸ„:–YÈ8㣱ë8mî,Ľ|äBtÈL ViVà™‘ÙèR ü‘—Kú‚ÚdI“hüÏLÒ&‡ûûÉ…‘±IDòœŠ x—ˆqภ•”ã®l6Ež&Š–:vÇJG,`-”Ñ”¡‹j#ä÷£ °k:[/e²^k&.È?Ï›}Å}c|Ž†Ý±=oc·iRÒõ¹f fåDV(ÇøöüWn<åÛoŽŽ‚9OÖôí·:H€s¢j€Â¨ËçTl´æ€¸)°Ìë5a˜ûÛZ»¢Ã(MdÚþ¼c/ŒX¦¸í¢Ÿ›„핵hVUµ˜{®=#žÜ¾Õvs-È$p³ ìfS€Ax¦,Œ}Æö˜ ÷«Ý€¼&R7ë ¶’Í͈B×9Ó¡’àÍ:»-'œíÙIÓÈΡæVe“ä¥(!`Ý@Ì¥Cî%íËõT:ã*ÊdŽ^ǽñ-î³¼Ær«Bìº9º«(=åÆP²ÜÖìÄäV`¸Ïø,œ07ðÍeð–Oì´`b©žl‹æú1̳)zzdLáÐ6qß.3SUQPIlkOÖ›Bãäu[7U-t¹Ï]É©WåR0mî~ù!IDSúº^Bq'Â,T:ûºb!L%7n0¹¹k¶ªŒ¡tx”åR¤ @XÈjMpºïÕ<“*Ú 3 ý£€Œ„È»± ¸yÙInI5„¦Î§žBºñ˜¨Å„ß01ä=±&ŠE8{ýZ£ö¼£n­ô…ŽÒªêà¡J3¼Vâ¡V¾Þn6•$˸8U©T[VšÞÃFÄðÌ5!­YC'1@ÈZ®î CSÆŽ\žCe×Lêx9‚ú©$B¨ê³°žRcÈSq ´§ÓG“xÊ$˜;àRã=JJÑO…ÔaNSºR$E­9BDãC ×C_…26 ž úœ ¥ÿuäºÐ 廪\Þ4üv"eò°ÿ;ȧÕ²a}S÷g‘ºÉ¦Sê)˜¦~:ƒÎt7îúý±@÷º^îO¿hRãØ "þ5“Ú.I5¹õ§rrB‹!ób=•¿íohæb4®Öeºb´_bžÓ6­Öke65ÒšjˆT÷ܶ||UÙ šÿGô`GtSY{²ÔôÝÊ^'wE=#J=Я«L ŸWU¡Ÿ%ð*¹UhêóZôàup:5=®Ûß¹Uôå³’·µ] u¸3Ã3}åÚ®ªú(‰róNbŒ Ñ_˜' •2,{ 8/{PýhÁW^ÿ-L‹6HGG{/½Þ£éi×4BsH´òá •Qu^T韔»ððäÞN‘‘O¿.ÇC7ZÎx•6æ¥fŠTÏ–T pG½±w(ÇMëìxÏiªºK½GõqNëØ SeN‘ó]ù¼oR}¬ã· !pÔGù‰p°I>‹»÷|¥Û,w·e²ÝÌ‚8Š¢>…öÙ;qØ¡[ÍÿاûÄ•Ccàf+K‘à@¤™ æs;ïn?d‘÷%¿tRýÖɧ-v*îÎÕCã;íºÅó?yôÞú»5¶%¦­•l—+ÍÞÆå¹ª!}[ð>F*X4 ¾¤2àSy¨6´ðWFy¦Þ–5+D¹lV;UÎêD×> endobj 2612 0 obj << /D [2610 0 R /XYZ 89 721 null] >> endobj 254 0 obj << /D [2610 0 R /XYZ 90 536.548 null] >> endobj 2609 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2615 0 obj << /Length 974 /Filter /FlateDecode >> stream xÚµWmoÛ6þž_!øÃ`£3MY–å·vȲ$MQdEêa²Â`$ÚÖJ“I%K‹ý÷Q"©H6­ MžŽÏÝ=÷œ ½½ë³Ÿ—gƒ«häMÁt<{˵7…^'ŽBo™x÷Ý‹÷矖—w½þ0„ÝèõÃ1ìþ~w³¼¹½Ö›çú±ìMƒîùíõ¯úãÅÇ›ËÛ¥^ÿö¹2Þ³:ÿtó¹÷eùapk F~`)ˆ%†6gЀ\ù°n݆CD‘×Fj3Ð/Å,—½þÂîb¡ŸÌ9ã3ó¡y–¬Ay*îÕã H°ˆAJÿ€!Tÿ~ÓÓ„Ì DêÂ)˜L&^ß÷Á44û[!˜ŒÃæÑ`Ð×.‘˜S$ÓGLžÔ{Œb½ˆÕ‹\ØNîª –+o%$Š¿6± lL0aO%‚a¦¾ lnÆHÆ[ýráPº­[޵å÷rÓWI‚=‡ÉÎéWÊžL$ø¯g2eÔF˜o¶²c’èrh’xj Ub9’q“ ‚„tÞ¿c ~‰8]ë5Å8Áɱà¯9˳;œ‘çÙ Sô@ðªòZx).[Ž óV#®—r‹+ࣶà$µÈë9VŒHllŠAz™Ò=_±Aá¬6'@Ý…¥åOUçÚ"ýw­a‹go^oŠlZ´»¢‰-ÚeÄÄñ”Ê­³~I*Š$®:ý?ØÍ{h„éf‹^ G[‚œsLå>Ý#®{*òh³·úñåÖˆˆè–qca°bd›½É¸½PP)‚ËÿšñEm¬¼œ7v•œ‘~Ã/ÔFoÞcí÷#•¶ÅIö»©o™“àÇ46»›Ô–§ÔúŸŽÉ¤í·Ÿ‘Þ-«5JI©5Ý}k•<Çíà]ZV+‘J`¥¡%: _Ä<ÕÔ/¼Œ|0½.¾v‚Ô<±¸ä¤ÉÔÓ6}a3Žs™ÒŒeVƒm±hL#öð犢]UEW‰*@vÄÕîUášîÍàÈQp,±I¾ËRQÎÏ–tRËü_ðãeñÚGÕ ?7¤Að¶É‘g³– ‰ìL¡¥•>›c–+ ­ò䪽6±ª.œ,5Ü*hN¤ƒzýî]»£ºÌ4\_•¼OÙIeí¨-’Ø4V߈$G±¬gÆÜÊÙOkÕ–îîØÔ©©Ö*µM'ÿ™_z&«-¤6QìÌf§¨šK4«6öy¹<ûíwe endstream endobj 2614 0 obj << /Type /Page /Contents 2615 0 R /Resources 2613 0 R /MediaBox [0 0 612 792] /Parent 2608 0 R >> endobj 2616 0 obj << /D [2614 0 R /XYZ 89 721 null] >> endobj 2613 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2619 0 obj << /Length 1148 /Filter /FlateDecode >> stream xÚÕVKsÛ6¾ëWp|’F¾E9íŒëW”É8©Í¶‡4£¡IX│ô£ü÷\€&UZvú8TX,ß.¾Ý666.F?„£ù¹ï <Ë3Â[#À†;®&ƧñÉÛãáÙÕdf¹xì ÉÌõðø—«U¸º¼á1 á$°ÇÇ—`yò~uvÂü§ëVyGëøãêzò9|7?w­Ç´¶}±ÁàšRg„èù¹‰»Ú3+°³ÄÄB>zóf2ó0ÀP’ª.)I´PÆf¦‰×íQ¾o›Ð$;jf®ü`ÑWû [¦€bÛƒ[–SíxÝçó™ÆÎ+VXd¯‡˜UÊ(,s–(•_±‹Ó[˜SB’‰9tÄEÉêâŠÙãrIht“‘ukUZ‘‡­¥aiàh/È“ŒD%L«-iŒr<ÕÈ»KRs}-YTe#¥;¶b…bD\fHœE*i¸…ÚFgáèËÈSl˜’è®k"˲8}úŒDÈ…iq¥¾qßhå†,‹=1ÏŒëÑ0=®šØAã®%dn€.ÙÄrÇ÷@r21Ýñƒü#q]6~É r5‹YžG4EÄi¼-e5Ï'ž;¹g›"ÎÓi×l”Y¾Î]‘×^à}‹»»&÷ûÙgšÂìÎÂGŽm·¬ø{¿½ƒ˜ Xl$u55Tà +š<­ Xgç9ý;˜UBgŒn4¿¿Ô"שÂ÷‚ÕÂgß+ìëT\tµ%êƒë*ªj~ðrâ% FÎråõ=+ú$ak©´–û½L‘ж‹Þ®í ©ÚL®³Š¹*’ïž•²ÈÈCŸâñ²kEÉbÂy¿˜pM­CîRHáq™ÞgÊH—B©¤CN¨ˆ´¬¢HnYÙ©XT£ç/>êIU—%‰§¿“§8ƒÒtúÿþØËQõ‚’j‚=1¿,5Ü­f­Æ†é m‰h#ûމYñ8/DÕïT]˜Ý–,ïG¼ŸoÌPan‡ƒ÷7¾øÿ×SDeFïsOñqÿfYr=ÕNä#9“™‰e§¸êÖzBÔk ‡°bTi‰ M-™>ðØ’~‹Æ°€£Þ †‚Õ{ù}Œ7©lfwM“’… ìtZl¤ÆûmoA©F'D)-êJYؘà E–ÊK”Š)a–@°RbJc»'wŽSýANå ÊÌhήw¼¾™5_pyÕ@U{OoEÕóv:}]Ó5=qùæÕtM;@ޏÍ~Ú´üŽJY¹º‹²š ÷…úFwÌ~—Âè… ŠL,•ýT´b;@BxòCK¡¤Lc€¢ø¦T'h[n“—°:%ò¢OeÀFtÖˎ8’ "O”ƒú5Ÿì÷<¨7ÛNÝØ·þ™éþ~MªÓ:ÏÏ£¸êv©uÚú/Çë9Ò¼ÉOò¤y–¿oëÛ«Ú,¼zu<^_ÄO°jñO8û'úÚœ– endstream endobj 2618 0 obj << /Type /Page /Contents 2619 0 R /Resources 2617 0 R /MediaBox [0 0 612 792] /Parent 2608 0 R >> endobj 2620 0 obj << /D [2618 0 R /XYZ 89 721 null] >> endobj 258 0 obj << /D [2618 0 R /XYZ 90 236.524 null] >> endobj 2617 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2623 0 obj << /Length 2031 /Filter /FlateDecode >> stream xÚ­k“Û¸íûþ Í~©<©µÔ{½}̤¹<¶ÓÉÝeÝöÃÝM†‘h›Yò‰Òn|MÿûhK¶Ü$3ýD› JxkOx¯¯þ¶¼ºy•'Þ"XdQæ-WÞBx¹¸ D’zËÒûÉñæùË—ïfó(~Ìæi&ü¿»_Þ¿}MÈç´,g‹Øþöõ÷´}ñû—o—ÿóá@|Bõü‡û‡Ù/˿߼J£I"ÎÁDkC!Í•`£½y¼ ±7rà‰‰êA×…šÍÃ…ð» ªû®ßn÷¯faêË¢kZÂÍv+ë’6e£ AuÓЪ®ok‚eÌ{Ú<Î"Tõêà€ˆŽšt]jüö¨Ë^VNÊ®ÒNöÏ":PÁhháë¶éw/¶sôЛ‡I°HXÃ`‘ò ”ï@ÌØCd Á\\#2ESwR×´9X‹$¥ì$(LâØÓ uOÊÚˆ$ª%Â7bpð–{#g‘àï$¢kXÉF Ûu˧N-ÊÃ@ä wjiÞ¯¤®T‰®[ûÏO:–4t,[Õmš’´Ð¨’Ì8ÄMh(^qa<Ž×¤Éßô-CÝFvb$À,ô)x¿«T§JÇ[ʘU_U{Â45­J‚JŠ¥.X$z)‹5Ü^«­ª;tÎ NCÿmÓY¤ëƒF–+­kbìT!M9¸3 OçS¡vnjC8i] 7ªÃicèF øÄk=J‹êÚ=ÍPA×Â}!¦A«âFÄ–ÈIX«§ò÷¾æŠðìÙØ³iúª$ø$ñðkƒÙ ë5m+ýq‚mw£RàÖ—Ë«_¯0„b ËBÄ`H±½úéá•€‡ù"÷ž,ÕÖÃ’Š àÊ{¸úñL¤-¡&kˆî‰ÜKó,HòÜ»¹™Ïæ™ÀâÁ«Â,B¨cÌ®m {(‰C U¦¯:ÆêÕXˆj[¬U6EÑ·­“‰Yöz|ÿ¯F3†k™»`§™ã$#cÑVÁùµ<ã̈ó?SâîbãZ)iljuÙz”ÅÁ"Ë[9B[k–ĸ¿Ð"þ4Âþ™ýgŒþM97ѳg—BAÍ'¬8xµHVC/ø|6ªUG;RîdÕ£nz&²n9?I,'æ`È„Êÿž“ ¿\Š{oÏSiµ€w•vbcºr4P8e*Ù)–õg$«hJu)€rÐ¥ºcÌ¿æ6&q~Ëm´·oÔ)BAµÅη®ç+®X ¹R5\Þd=¬jö\Ѭ˜ÀìëbÓ6µ=G+ŒnT@ý*+:Ê‚4â°$AÄA ]`L‰ï îCÑ’#±\Æ5èѵ'ªã¸_÷Ø8ÌD»Äó¸ ²[Òû’ÒJ˸¦¦þZë;aÈÿôÔÿ”:¬Om[OÊ­çÄã0oסÍNúg!¢bº‚ÇŽT×»¾cÀ­[v‹•þ²ÃîQ’zj@©ë±zìÀfî>©¿Ñ¼ÈqæÉR;-p@Ï¡yê6²Ó¡iKÛû²4ÂÚÛ#CÄÆZ$Ж ›(YèÎfLé0îYì +en{ÓtÒÔ²ÖkIë®ÕM«¯ÝÇ’¿îT»REÇøÑH16 ÕOÜÓcØÐ™(;¸åB@‘倘 !Œ„¶mÃgsÍ&°‘Ä릑8:NÒˆž³a;™À·4¶þ ¬Y¶d[®eÛÊý5!±¶<énÖ×l&ˆ„AeÂÙÃMwi#NÒFpÚ †–¡Ï4 M/\Œ—ÈC¨mqG@ãB%`„Ûã~3 œÿ1èqf¯=~ë0ȎŸa¾yÊ:Ãâ7]ywGÙC/—˜O×ëƒ=Ý~Dz1Ÿǃâ:ãê: *µ¤ÔǯUEÇ{<ºÃ v|`Àæ£v]5=Ίý€ç0®]õ¥8\ž)î!2ýf!v=|GötõVýj_aDÎ’ê~ûAµcYÃLÁ=fÊ€)ßû ó.èÛjÂxÔfƒsùy7zFðý„•+Kî¯ñ…ÈÏ¿,³óÜè;œúv Ù–„hv”˜Vš¡o±ê˜³áµíYÄe—,ï˜1óWV]e”{Û@î}ö´OšêBî*]>~­LΧÆÝÍ–’®þBR`UÀÔÚ2 nذ®¸öˆa‚XCǶƒ•°9áHÏÆç¥§õó¼Ù¿ô‘ªlúã@Óy¶d®©Ž²ñ¤öìÖõ’žQîý ½Ü/KxˆþaÔÙ'úH‡ëmÉ¡·%g½-±—ˆGÍ+9o^ 7¯üq»B סíûx"i& 95¯K¹óܘ~K)Y¸8@k`•ýZ^Ò€·6Ø͇=­µÜÚ·Ø„©LHp,¸¸±÷%±xº”ž=ýwÀ*ÊTöÎ_®×…ªª¹¯‰Ëþyp…Xwîõߘ[9†‹‡uÝt|(ñw#öºœ­aôŸùNo¤9i¬GÁ‡â:ÕÖnÂ5PuŠ®o/<äOŸÜ ûoY!O½ó¿ÒCeM§f­ÏƒE­ÿLTŽš ŸJ¦Ïs ùìhumºy!›GYÌ­š0[Ök5õL>cß©ºFïÿ—*¸}·_PÉb¾dô·HоIRÿ/ÍŸ>}]ä4DY_Pš|Q™å¾¯ä+½ûZEäÔÔë÷w+Y¥ endstream endobj 2622 0 obj << /Type /Page /Contents 2623 0 R /Resources 2621 0 R /MediaBox [0 0 612 792] /Parent 2608 0 R >> endobj 2624 0 obj << /D [2622 0 R /XYZ 89 721 null] >> endobj 262 0 obj << /D [2622 0 R /XYZ 90 396.356 null] >> endobj 2621 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2627 0 obj << /Length 1070 /Filter /FlateDecode >> stream xÚÍV]oÛ6}÷¯ òPÈkE“ú–³HÓ$sQdY¢aiÈ- “¥”’âfEÿ{ù%Ere']½a/º$ÅËsÏåÕÕA œÞ£É©kúŽá€`|\äAdÙ ˆÁµvüëÑEpr9Ö i붃´?/gÁìüL.IŒ}S;:?ûMNßÏNÎ9þãªÝ¼±ëèbv5¾ ÞMNm£„…MˆL—…(b°M¾g„TÐ@oÞë†Ë|L¹ëbŒm-,Ë4Oäá¡4å‰Ò‘Z¦cìiI½"y%WªBZFK9ŠÉذµû4"ržæŠÕË—Ó^,= FG˜ À<‡ŽíAìX Z®oˆÙú;€ ë»`-v­€é{ÐFgàjôû7GŠ»Á¨›Œ-è#8¦ Ë•¼'}¬;i ©ä ”†’¡$çø”³vÙ,„´uIhQßqf ZÇú¶#OÂ<)¦Ó³ö½ëBV lt-•ùŸÄ ú®:ˉ<ú…Ö )õ× òV }@6:ˆH–é° >Çèž ÏQQØÛ8æõjN¨ ic"oŒùõØ.SBC-䔣—,•(‘5u² ‰GÔKˆ %+‡ü–ö9Jzeú7áçW´&ÄÐJoê4‹U4iâÎÒ²r+«x:½'QUП㢞gäuÇ·ä°"®§q™ƒúølQÐ&qe¥GOîÃH—6)+ʪ€ •‡D½F7½< ˆö…}Gòœ]»¡<Þ„Ç{‡7vÀ›ðÆáP®ž‚§d¦y[²šË~9«â„*®¡  ÜÙšˆÝÐ)«†ôG‘Ûï’’»ìawÍw{Ðñ*¾äïù^Ív§›ñk:…êŒ}˜DaÅ»=ŸÎ³"ú«Óˆ mN²b½­°3†–?ïdM>‘¨®ÈF ¢bµ óXx&ôqß›Üì2Êã6Í‹ºôŠToëÕêá4ä­áàU·)¼jXïhGéâ1 .Ãòv¦‰ù wû&N—±>ø#mJ›ÒZ²°³¶Æ“¢©²%ûU \A–jôˆ?€ôek _†Èvî^ð-ò¦˜Þ’ûSÁú…úÛîÿóΚë×Ðÿp`,󔔤j’~ø,µa˜ì·ËtÐw¨ ¡.z¢ #&., ȇž¥ÍXY¾«­‰²c̪J'6‰YÂ¥×'þPåmøž,oþ¶)o1aŸZ˜ñžOŠ\ÚVÈ)'ŸBÂúˆec-/ªînOK«R.”õ\R‚ÿö0«rùm¤å²¨3º¦i%_:–${·&#µy̲‚+¿u+"™â“ƒ¨ˆÉó´v¹2ÿ%í‡m ¢íºh/ÚÏ~†ö³†µŸµ?íçìMûI†ÿ™î[„Yùÿ~ÌaOÒ =!½œ7¾G÷[ûåWÓ´Ï5 endstream endobj 2626 0 obj << /Type /Page /Contents 2627 0 R /Resources 2625 0 R /MediaBox [0 0 612 792] /Parent 2608 0 R >> endobj 2628 0 obj << /D [2626 0 R /XYZ 89 721 null] >> endobj 2625 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2631 0 obj << /Length 943 /Filter /FlateDecode >> stream xÚÕV[oÛ6~÷¯ ò0H@E“ºZ)64Mâ,E‘v‰Š>d¡È”,T=‰ŠýïåM¶åÈn¶¡ÃúbÑçð|ç p1zÆÓÀ! }ÛQ B4Èõ@4·Æéï'ï£ókÓ²=d¸Ð´<¯/£Ë« µy¢–È ãäêâú<}{y~)ùÃÍZyGëäýåy½O={ „‹ˆœ€C”ï š|RâŸÈC ÑÐîIAW|÷Ž÷ÕñüŒ!¯_CùL’–‘$´,ãj.-m†¸oÍTz¿ª%³~Ó³¼¢-˜n;kËòq'ŒÖG/¶«­?Ò¸hˆg0]yºÉ÷q3Kã¼ s±#ÌöeB…l ßÄ]×]¯-8îbÝjíúlAj2Pƒ$n´´ñ?àéë^ _‡‚Ý*¾Œ—V]7‘‡©Œú}Ò'aVÚ߉¸ßDCöÃÀxækÒÖ%ýeï®wëy4úk„¹ˆåºä‘”£Û;æ|›Ÿ ƒ0+©T'œ@ù\.ÀÍèEu=–ÁÈ…¡ëׯpâa…çŠ2rlrJqdƒØßX½š˜7XÅÔ£b bbÏø,~t§Ë?Zè:]ªò[âî‹h¥Ö#Í3GêS¤!‡„SŠ‹C£¢L™vÚ9k”д÷V&ø¡Iã o‡¤Í‚¶…º^VAöжªs‰ÔÓwR)- jÚž±’½*¶:ç¹xN9;ÿwê±{¤¬OŸØ±ÀŽàø>/P°Ópa=Ž«IÊoT•tdCwH‡qnèLdæ†ÚQR®ÖésPÜf¤ü„™4–Ô•î)ÇøûÀ.kbÝ·9¯NÇWmÉùºÙzúOÕ¶& ƒÇÃx©^iûní™|ÛÎbßÞ=}»èd`É6K’äižÌ:t3K8=̨‡ß\¾Ã¬áñCœX2cý´rôCÇ©SnÑä ©%ñpopûîíï×úgœ8þ'£†7> endobj 2632 0 obj << /D [2630 0 R /XYZ 89 721 null] >> endobj 2629 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2636 0 obj << /Length 2624 /Filter /FlateDecode >> stream xÚ½YYãÆ~Ÿ_!ø%Öâð¦8N˜]¯×kgWAlc@‘­ +ùó©«y‰#}X«««««ª¿ªî±VO+kõñæÝîæö»Ð[Ef8ÁjwXEÖ*´¶¦åù«]ºúÙxÿýýO»Ÿ×Ç· Ï\oüÀ2þñùa÷ðé#3ïùg·Ž\ãþÓÇùóý>í˜þû—^x&uÿÓ×õ¯»¿Þ~ç;##<Û5-7ÉßG™KŒ^mÜ,ŒÜÕÆ aŽËR»cÖ Vß8TuÁTuíîH»Ê­^yRE\¦YYuí‚-A`†ž£¥±|«=*Ñ^ Ñã©Àˆ“DZ±#.å·®ãsoý>¯àç’i2#ÓS³òÔµzöÚÞO]¡Ê–·¿FvhZe{¬+Ôö‚Ư6¶ë™úƶÍÈ—(’%‘g¨µí¿¡‰YUòfCkêš­éÍîÕWd€Zð™Õ‹³rüO%]›•O¼&» ñ4d‡ÙhÙ{U3]É Ê)ålŠvR4¸¸i¥dBYµLq›Ù=[×ôüíÔ;Pk°hŽ”‹¤zá9K»8g^ª˜“ÐJ$Ä¿½¦§ºêN¢¨~E昩:®Á0ß83³+U'K’÷pö|$÷ËÚ¶`Ç©HP013Lڢ홑çMwxZBòì\&/ë sž)^u“U"Bû†ß–P…j.º†æÅyS µv,Iç,÷¹ŒpÃÀø¢ $q#”Í?òN-Y)'N\œr5µab.g÷Âæ$¯Ì>ŸyÐÁ µ#¶¦lYÔ3CÓ[ol˲ŒÏ*Ü·míq+]«0 :t!åA¡½5µ¾JÉbœrîFF[ño ê™ZÖ ÇØµÌ‘ñQ2ȬlU}  '2šTegeÃ_ 燎’g¡ÿð¸Ä˜"É')¢e.‘Ðõ#ðM€ëµ`öã…ů8c£p< 6éÂZ6àèv{}©æÊZV?Ÿs²Á\³Bã]ÕaŸžmLó 8H\ a™ÐR5úÙsŒ¦;ªºU©h’•ÏÜ΀Ü3¸l &»ŸÏÒÓÏÌm²NMÍC”:.§Ž, ) Ë':Þ,YÉP8nþ3×ê”s渑$p›6½»k`&i†‘®Q)ñ‰tg©Êce\PêPæö¸‡Å\Ï?üز­¤EMÈÆÄÃßɪ(ø’a¬HË'ó<~ÐTœˆàÌ*”B«°q:ƒÈbœ¯]_I0™’çx=Kù.å`»6%69·†FÕ?kÕvu‰ÎEyÄ}äR  “~Z>CœÎ?dMË|ÌZ Ï™1O#ä±{@êËrj=uð íÍô¥-ìîPå9÷JŠÉ^*ÙpŒM_‚fE©QPéEéëÍ"MZ€*•6s¡AÄL¨ #Ä6mÁì÷ˆ‚˨ͬg‚MEó»à}?í9áȆ¿ BêAÊu ™@üsSÈÎ-`w¥(¿v%Ç~º,/ºJ½*53H î–[ãtqü@b#¤†®…¿¹Ÿ t 8r`·ç…`·0—”«Ñh~œ´Ü"ábq3…G.3éÝÂߪÍÒ^мûYùÆ†ŠØ;\ÞÆúxTuÖÆe¢°v°oÆ‘­4Å "ý‰ÝWNÛÜmÁˆªkrð«$éêš ¤€¤­íEéiwKí’-v,§»Ü…½‘'¤Ÿ{9f ¥AŸ'ñvC‡éé>+ÏÒëíÞ÷ óÖu]#~ZccV"Êù®@ðwë-žÈ§Š?¥ù@rÚF0ï©‹ëš!וûS¤ð£al|˜ÈmÔqÁrPuÙã÷Ñ#ʵÉ_P‚Ü @Ç@ƒ\[-uëXH;¸oõ/°f¸½øXa›.oçp˜*˜‘7¯Ç…Õ%\LŽº ES"{êöy–0]¬mƒ;ß=@´z‰,GdX%‰$r1] w¨cšLÁë­6fðÔö»;™÷ˆ%™K«³ í·ú` gÖ0¶¤®Úÿ³W…˜uü¡eñBÅ„9Û2Ï~„v&â+ÿü諃äœNàNr *€Ô…1‚Ð…eš¦J²˜ÌdŒG.ýµâ/èc Gþà¢u™&Ub4Á¬šLÀÙòË>¢23^"§Öù•Ï*ö×§r°ï… E÷]ß7þp%v¤Ë«ÏA½ÈYú §´™^[cññ@Ÿ#¤E>”o}œ¸S¿µ5”‘þuâJùÃr?9Ç'ŽrßfévÈg€0Êô–Ú*+¤ÒQ³ŸW'Uÿ ýÔðà©®žê¸(úEŽñb,Hçj_> g`±øQ=r·’‰î60öŠä8%¼3óØT`¼ó†9Óç+Ts³¦` ^ ï`&jR•¢[ÔÒí ÚH¸æôÏ`Ǹy<Ö¢†Æ•k›ï˜ÎpÃäkë\°Ó€ïøŒg/45®ïI§I|G)È¡ÖÙ×-/0 À7jܧ3)€Åð‡Zæ}‘ŽV¢´ìÇF(ƒêÁz!Šx#òáÆ†4aZ?¡ ÕU‰¯%L£)4@§YƒrKñ£iTæáÍe1PŽkA ú×M^äQaÊiW¢¦í{z2Ä)€kú»³¦øM*ßל1–UyŽª˜[UÙ\*Åv7¼jM*AÁäUhÔ ÁáÕÅœï“tw©45·‹xâî)ð°9¯Wlzàq"Äyˆì‚ün©{æW:š[çÛžâîI5›·£ÇFy4×Ùôû–Ñ rš[ÃM`1»òÞÓ4—Ò WÉÐ*ÂõÄtë› ÷ÏýÍ&ûwÿ޼ÑMÃ|ÿy ;þ 60è endstream endobj 2635 0 obj << /Type /Page /Contents 2636 0 R /Resources 2634 0 R /MediaBox [0 0 612 792] /Parent 2633 0 R >> endobj 2637 0 obj << /D [2635 0 R /XYZ 89 721 null] >> endobj 266 0 obj << /D [2635 0 R /XYZ 90 617.742 null] >> endobj 270 0 obj << /D [2635 0 R /XYZ 90 508.861 null] >> endobj 274 0 obj << /D [2635 0 R /XYZ 90 356.209 null] >> endobj 2634 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2640 0 obj << /Length 1103 /Filter /FlateDecode >> stream xÚÝVÝoÛ6÷_!øa°‘Ц>-¹Y€¬KREÖ%ö-Ѷ™tIÉiVä/)’²¥(I»íiϧûæïî­•­‹ÞO³Þè|ì[1ˆC7´fK+†ÖFú5K­›Á»÷§ggWCÛ àÀC;áà«élzy¡˜§ê˜ copzyñ«úûîÃôìr¦è߯ká–ÔéÇéõðvöËèßJÑó,mLä•hCÌíél^›Ÿ+Ë!ýJÊrÓÑ©^)œnt|÷”Ýu©¤t.…æò{…R°šša˶˜{uo—yÁ»¬ÎYÑɤêÑS‘IÕ§ê>¸ÿ–Ì«”Aí özê[FÌù¾‹3ldÜHà ’¦¿åzM3?éàªþ@”Ð݈—.ª¦WG ÝÛ·{÷67¯œ<û·6n×¾ 7À³ ¨_º&õ‹‘td¬­"ׂŸ×B+j ·Æ wy»©‹ýø¿¶~ü ú7Óæ+ÆË–F endstream endobj 2639 0 obj << /Type /Page /Contents 2640 0 R /Resources 2638 0 R /MediaBox [0 0 612 792] /Parent 2633 0 R >> endobj 2641 0 obj << /D [2639 0 R /XYZ 89 721 null] >> endobj 2638 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2644 0 obj << /Length 1899 /Filter /FlateDecode >> stream xÚµXëoÜ6ÿî¿Bð'-’U¨÷ÊIïàæRÇE‘¶É÷! ­Ä]ñªÇV»nqÿûÍpFÚåZ¶{(jÀ9çñ›áp…µ³„uuöõúìÕ7q`%Ny‘µÞZ‰°b±rDZëÜúl¿}ùÃúÝÇÅÒ …8‹e û߯××®ˆxIŸõ"ñíËWßÓôíw×ï>¬iüÓ§‰ù„ëò‡ëO‹/ëo_}zGJ®ï?µaŒm œØ KWзU½ªwtfZó·ï[µYxÂz9£„°–îʉV$n]HØöUÛ {ú¶ª{Ùn.ÈÊx5kê>UuG \x¡}»pC[¶iI,ªÚ—²’À׫†8»ÙÒŽ¾UñTñ‚Ð ÜÉw`޼1ôÿY„þÝ;¢•“Ѹ·’}ÑäGåÚ_7}ÁšÞ×YÑ6u3t(ÂZúnàøàË%9š6§uìhï1¿¦l›¶Â¡Hì´•Dë†ý¾i{‰ÇyIl¿oÐwÇNYÂ~‰Ü+m ¶VÒúB hMÍrÍÈ1‰¿¼IU¼ X¿ºé(¥}X2bîENè…Gr\FÑ÷ íGÙ/uƒÁ¿+e¾Ó}E—z:aÚú¹‰ §á •ýÐÖ2§ÙÐéó4}4þ>Ê}yÿêzíYH«B±œñ öÓVöË©ÇÛôž†ŒÚGŽZjD p>ºa…ÇAlË4+ˆ”S„•N ˜«š8ú‚ ;Œô}N,  #î*åX;š€öf‘mK§¯ì&ˆ¶E·i †–ãttªÄ¿iÜeæïÜöEdíZÅpzUîAÛÀ¬-)L4¾EsÓrà%Ë«è‘\vÃÈñ¡är>iw³MU©5í'ò8t/Í<¦U«,íeGÓ»ÖdKJ¤¬ãè*Ôïà*œ1Ã6^“C ‘b' 3î½Fâÿg!ü”sa¤u²§Aßð·äKλCxŽŸLf]AEí;L0Ù߀ú7]Ÿfä_žp’ É$Á/Áù;u¨;¬î„˜Œ•3šBÑ MÓßKÌQÄ,˜ W5Xæ‡T´ Ë‹æ×®¡)_84‹>ÑvCÚ¦p… 68‡J×#-Ð;­t¸6w¥£R‡Â¡¬¢´IPÏ“ 0-jÚ\²ýŠoÅ»BQ©ÝTŽ•Jsh7ð 9/ó“¼x9W8%÷±ôøÂ…f¡k2•j }¹ ‚½‡ö‡‰w ˆ#:dèàÈŒ—ù4Ö÷M§8™á©”:BœÈ/á®$„Õ‰HÞã>wᙑ!t~ahÿé~Âã~âmÚ±÷‚²„: ÜꦒnÌ7cZ´z½d¡:‚.Û…„Cætæñ|&W¢!àuH‘¯ïæ"× ›¥ÞÑq ˆw¿er?6à!÷_ú Ãþ°;-j^ÍU—nJnÍjÄøÿo £à¾}ñâÂxÞŒßwë³_Ï\ÂcŸeÜI‘ëYYuöù‹°r ƒ©NœÄÖæª,?Y9¡À^¿´>ýø@¤~îÁk\˜`ƒˆ-?vØOȆW¯–õo. v±ŒùúõàÐX?fhxžUuNrÙ0®!JðK]&ŽrIÅ5âìÆLÆA¡àÁÕfÅý\‰ú»Íƒ‚7Tò)}ùÂì3Ö£Wh§¾xêX¸éä(srÄ-eŸ¦5ôÝÈÃ: ió¸Ìêìd-[¼%qÂ7)ºÖØñ\\üKÛwi†M9ÚõùÅE×c[ŽS6ò%qúޏa‚”×Ošy˜ÉÊyE†~æÃ‰öµ%}¿b›Óa'»å?ŽØü¸ yF¹´¾ç¸ckùÏ9^µ%”Ú–Îá0µµ¤ë´MËNŽÝ?4ÑóÄ5²f`ß¼axÕÍ‘fçæ"\ùåkn} ûïœW%¨õWUJ™PÊtŒˆ¾'5™Æ–ÿKé)$ÛQÌ!½Álñ('|8Žó˜9“X dK6ð$^Ô7#èœNý>ýd3ò¼xñt” #£#s•ŸÑ.û™Â³S·ò@×YþS(ýÜ~y¨øÔ{Æ‚¹ƒ&ö-Ö #GáÏe—µJ_ÖZL:qè?®úQ q!)ÔX`[™RÏ«wRÈgµZ™§¼™"ˆ9ê­ÅÃ#sǹy‹Ï9É”Q{\úÉŽ)暈ÿuÛÂ_ endstream endobj 2643 0 obj << /Type /Page /Contents 2644 0 R /Resources 2642 0 R /MediaBox [0 0 612 792] /Parent 2633 0 R >> endobj 2645 0 obj << /D [2643 0 R /XYZ 89 721 null] >> endobj 278 0 obj << /D [2643 0 R /XYZ 90 690.045 null] >> endobj 282 0 obj << /D [2643 0 R /XYZ 90 632.72 null] >> endobj 286 0 obj << /D [2643 0 R /XYZ 90 479.918 null] >> endobj 2642 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2648 0 obj << /Length 1803 /Filter /FlateDecode >> stream xÚ¥X[oÜ6~÷¯üÐÕ +šÔ]îpÓ$õ"H³É,ö! Y¢g„h¤©HÙu7ûß{¥Érœ¢ƒÃËṟÔpgãpçÕÉ듳—Ièd,‹ýØYß8wž2Fκt>¸Ï¾x»~ñnåùwC¶ò¢˜»ÿ}w¹¾|óŠ/ˆ¬WYà^¼yõ MŸ¿¾|ñfMãÿ¼™g\o/߯>®ÿuö2òŒEÀx€‰Æ†(Ežn>{)ø1·¤)ãù ¬tæìÌ[y1çnÙïö4’]×v4T:/>¡P'ŽXÁY!XYŸ‹¶Qš’·/ðØëJéo¬˜šè÷DºúC÷‘m¤¾ùWFð¯<âðß |*üf°¹ªF¶M¤òogëß Ê™ªþ ׳g8_Rø?³( 6Á?{«þ»Qüõ‘•R¬j¦Žx1ÉøÿÂVôpË_Üò3–¦éÒÖ̇1›E-s½•6r_ßÓ°®†Ä™èÞ ½’¥åȵ´ªf&¨hKù ŠÖÏ®fTROB2–ä@_¬O~;0äŽÀVŠ‚”ÅPšÅîäÃGî”°’Y’%ÎáÚ9A–²ˆÇ0®÷'ÿ¦–œtƒà!ËÂЉDÌâÌFägÙIê¡JÍmã={fçê¾)¶]Û´½å¸]‰jEUmsþUæ‡YÈ’$ù+æÏEw¦ý*øÃ'L|–FÙ,ÃU£d§g™¹ÍëÞuKôÚÎïºJkÙ ‡‡íœÈF6²«Š!¿Î+XX*±uÞlÚóshøªZwÕu¯Õcæ•.ÏÏì5œž¸ìîO±þIœ¡ˆ²G»tÍ–3/ó©ÖãB/H«Ûf3”øo½Túª*'0²ÉûTÌ(»Å_‘dô`ðì kKUÕ·Ý§¥>)Û+dºÂý8D,ç²:T_kõ…ä¼êÚ~ÿÛýõØè]½à±÷ÃÜehÐ!RO»½ïÚB*u€™Jª!7Ô å‡À å#câÎìæn_Ë„’ÔдÆûªÆ Á‚ì/ÃJ§7}È’Æ!y ­Î"¬<ÁÁ’ç¹²øâŸ¯¼@Œø¢ö²¨~åÜ/FP=Óž8Ý#ºâ ”ˆ6ØL <1=`ôŸ$îŠI|wS­üÈ­ä Q#ö÷ƒG •ݸÛVÅÖò’ʉ»",LâáMqäÆCó‚€%Y–•Šhås×´&*¸Eë¬Óh‚²z÷X"%N„*cp>˜!ñmH&–›òÀÁ¶’]Þ{äÞ¯âÈ…J ’ȽlìMšFL$³û²íJ y@ö”:XØÒåà«c‡#ßmo¬ÃÁq-dÌÄàðqïX·‡V^V3ßÏb£ÐºD¶t¤x×cËâÚ6G©craÅ$èiNtßUmW›¥Ý…⺑…¶ëŸšãyWËrcå€sFª§Áû.Œf¯CìÅ8ÆZ©u€/äÄ<§èJž‚ bAW0æ-Žkûn%Üv%B0 D‚Øôîi rmÅì¤Þ¶%mqã0/ ¹×ÊNè¼¹—( …Æ&îa0žŽöèû½•¯P Ђ#E»ÛÙ ƒi`oênzt㔬·ã££®) v¾Ï•ªðR2› ZtO“OÕ ‘’‘k‹)ýÑ‹2°PÛ PžŠ»ÀC˜‘u]pÛ8šæTÈ ÷A^ìVRÓï®e7•uܽ8ÇJ9:$¦•b¶è¾A¨ÑGxVßÏ´qÛž³¼Äóº…ÀÄ Õ*PªUlð~4m ÓØÅ÷ïd²~gàº+i¡ÝSaiЍ‚úÄ+Ùœl-íz+âq—ÌÙéÁؽ¡ÛA™7£Úûìéî*E˜/¨ùá !;7Ú´p/E§áQdŠ®y¢(ü,tã;ƒ<0\ÛÙQCT|ÇbѦ#7º•‡Sé“ü,é0ù¯•„wéD~¸¼y$þÑÖ%øJøJG•>¢ u` Ï8¤~ ' ¢S²Þæú«(r±ßÙ’ž€==}ì)µs:Eîä!r§ŽäÏ@:=€t:ñr¡NŒÏ ¥aÛèB©~g'ê\Óh^š×#MóδgDбpõúžh“ï°~ƒ`ìãÐ5_tföfÀÝ"o¬»0~¹mVëM{„¨F»e0N=žøÓBÖµÇÅ)µ¶éá•¶£úkÏÈQ$"zÉ"=R|þhW½ƒÛÌ`UÈé¦çsÅÛ\Í.Ѓàäá3Mv ¢®± Ð¥Ð}'—?J矙ù“ÇóÁ,aÞÇc½ÀöÔøÏÄ40[»— è3¶(°|xá£T{g·yá-g`5|”ȯ:¾—MƒÎ‰b>¡ÒŠ™ÿ IþcŸ(É8· endstream endobj 2647 0 obj << /Type /Page /Contents 2648 0 R /Resources 2646 0 R /MediaBox [0 0 612 792] /Parent 2633 0 R >> endobj 2649 0 obj << /D [2647 0 R /XYZ 89 721 null] >> endobj 290 0 obj << /D [2647 0 R /XYZ 90 316.819 null] >> endobj 2646 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2652 0 obj << /Length 1083 /Filter /FlateDecode >> stream xÚÍW[o£F~÷¯@y¨ìî2ž†‹·”Ý&iªUºM¨úF†±ŠÁ;énþ{ç;‰´½<™áÜÏwŽ¡17 q>xÆgžc p-×gF ú:ØãføáÇ“OáéÕÈ´0:`db»º/.ÏÕã‰"á(°‡'—ç?«ë‡§—¡:ÿzÝ0oq|º¸݆?ϰÕrÂA6€¶Ç]”>à@ð  vz|†`›Û´]X–aZ³•Ì—‘iCµAÍã‘éò@hãšL„@€ñ3üi^23†h¼ŽbsUs2^‘ eE-ßqƒÝUxeúú­ÈS`pOHï«4KÔqe•v7KKÖ'V²d2Y“˜ô»¤¨¦9nɖ¬ôëy»-c³‚îmš’ñ¦™“>UÊä ¼í$ÁÈA8ø*Æë9{K¡í£®}K²6(âx´Û0Õî´Þ;›®ƒ¾’ÛÖ´Y[iû—ݦd¥yƒ~Õ;e·yt+O_0@Oåš¼¶è‡íîþ®¸¯7ÛŒJVÙÃáöj»+ÁþQ0*éì0¤IÎê¤0£ã8bñB]§YÿÑš>D»5%Y±Ù7Z=×Ñÿ烮lhÊÈVðGIµ\>Õ³ŽÑtZ1ÕÖ–Íòºªh¶=ؤλFPNo¥òm{½­C?0úÒÙShQy7‹ÒŒ$âAHíK†ŠÚìñ÷© ”ÖÐZDy’5ï¤|E9ìŠJÃ.ŽJ99ÑN6t¶÷Ú}ìs³Usa5.òC?õ™ŒôþÙáP÷¸‹>ÖÇ>ÔðdSRVçùÝ‹v„!àKÇ+V¹ºtÖ+ùæÂdùñ/ÒË‚‘ ß%}[BÂòÝá†h:B¥9S7±ºX¾7$b »—»X,À«>.ô!.–K^rÅÊ{-ÊD·‹/E®h³n¨«HC " †yÁ”hͲRÊjjÊ•E‚„#Ü ž<-EÅ¿%@ ²SÝ‹b‹Tžb1ý²¬Yx¸‘ðOq‘U#àÿ¼àZ,= Ø.úÏ÷J»¯´ÿ{ea_åþ¥ endstream endobj 2651 0 obj << /Type /Page /Contents 2652 0 R /Resources 2650 0 R /MediaBox [0 0 612 792] /Parent 2633 0 R >> endobj 2653 0 obj << /D [2651 0 R /XYZ 89 721 null] >> endobj 2650 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2657 0 obj << /Length 1853 /Filter /FlateDecode >> stream xÚ¥koã6ò{~…лˆdR”d)}Ùnv/‡b»·ëC?l-1¶P=\=’úýï7Ã!É‘³‹»/æp8œ7gFfÎÎaÎÛ‹W›‹Õ›uà$^ù‘³¹wæ¬Yì± t6™óiñÓ߯ßon>,]?d‹À[ºaÄ¿~¸Ýܾ{KÈkZ6ËD,®ß½ý…¶?ý|{ónCð¿>Ä'T×ïo?.?oþ±zú#%.<&Ö ¢Ö!bHsÁŒÒ«7œ©]ÇŽë¯'èNQW»¥1¶¨î2õ@à´ìÜwª»kó«ßXÈîeÑ"À¿C1 ÂåÜKBã€ÕÊ¥[¯ú¼È|E¯,ò¶›»ÖvÙÕÕƒJ»ºù>«ûm¡~ÝmQ®VìËrGÂî놀¼j;7e|õ Sw'ûZTUåÕÎe|ŽIýÄ>OákÒXxQ½·"ÿV#¼ðxÀÄv“ЋnEÿ§Úþ jó©Úâ™ÚâŒÚâ‹j·Uʵ¤-D-OUkM¢5UE¾÷Œ=sÆxD9,/½Û++ûPϤšqùFV»úêêmS÷‡Hþ3ÒíâåÜRU§Œ‘ÒnŽ«Tvéž¶Û¢N'S¶UF­­*êGÌÝ9öÀcýŸUylòNÿMÖ—åñ£`×5ù¶"dxëŸòjŠÓg®™Þ 7ÑÃórüÍæL!0nÎïŸüÐÞ^¶w÷2/T†¼uÎd·;§ñS šÆfÛ^VY1$ÛÄë‡R¯îMꥲՅ„ŸuÈ_ç%ÿ5§é(ð(7­+›H¯ÕÃmìß̸fmô5Qž&Ðé¬bàïFµª³®þnÒìz³¹øã‚ÈŽL„‰çÇ¡“–Ÿ>3'Æ•ö~ˆÖf#mZ—%<ÂâsœœV}¹Åb†ÈÚªB¡ê-QäÕä ·–â™ñb³ZµUµ9-õØ+u:$0ÉXékG‡Ø²]óg½,—)ÂèBD´œvXÇ £æ Í>Wl@¥pq$ æG¦ ûdÚoúöé-ðôã’C%m2C¡¥nÄ)Õ'^.²=V)ĺÒõ1:RM›[AÖîŽ^@¥êöµfqPdká# lÌ #’GÏ`ÍPD¾ï¬V¾o‘À‹—.gPH>(‰&¯~…Ç5˜žéTB/ÓþỖ`ú¾çG¦tVK7ä{\-_Üîsë¥Tš$Ûš3•Cb6ÓàÁ@DÙÂE<ú‹ã‰"ÑÿxÁ Ã8„T—Ít|œP¦§Ane›§öÿ¹wfB뎇“„sI¢ ™Ìƒä :ùv„¬µmç^Ó™o¹ÿX(Qï endstream endobj 2656 0 obj << /Type /Page /Contents 2657 0 R /Resources 2655 0 R /MediaBox [0 0 612 792] /Parent 2659 0 R >> endobj 2658 0 obj << /D [2656 0 R /XYZ 89 721 null] >> endobj 294 0 obj << /D [2656 0 R /XYZ 90 283.654 null] >> endobj 2655 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2662 0 obj << /Length 1544 /Filter /FlateDecode >> stream xÚWÝ“Ó6Ï_á¹—:‹Oþ?hË̽PÊ…ò £ÄºØ­mÙ¹4ýë»ÒJŽ˜–éäAëÕjµ¿]mˆ³qˆóböd9»zžDNæeq;Ë{'#NBRDÔYæÎ÷éÏ×o–7oç‹€7òæ ÷ýÛÛåíëȼÆe9ÏB÷úõ‹_ñóéËÛ›×K¤ßÝõÂ'R×onïæŸ–¿\=§ÁÀˆÈ=&`¢¶!ö•ÌŒ£…Ý_ œ QjYpÉï…ä— ;Ý®([ ’Ôµ+SKæJ¾ÞɶœÔ}˜ûÔ帛³Î´Ü­»4¬É‘8ˆ Ô쀜‚Í2Ð’¹Ï¸Ö[®ù›rËŸTbelh¾ºâf]P¾‚Ÿ ß÷2j² <ßm®UY—’¢Áµ+89ßv…Ù»·{VÁÐ÷²;(&qù1FYiÚKŽ÷w½Q×¼Éyn®0–#¢8Ì XÛ™œû©»š«p„Êÿ)ïïEU eã¾l6œ„Ì|µ»ºf²ü›·ø=2òLz•tŸÞ!ªn–3âøŽO^I0Œ¼ Mu=û2ó¢”ú‘–ðJ²@“zËž3Œ«Û:sž‰Ùoð³Ú­ÈÂê^ ”ë*@À&!u†Ãð¼xUÌ-X£Pª5|÷ÉÜwùš™pûmpEÓÞs)ûÔRì6…µ}Û¾¬™MvÁša2cq_Ýê£ÐÅ;ã§Ño<ÍágÀhØ1$³­h+Ú¶p>?Ò~àE4!71Ð÷Æ2²»´qYW%\…tÁÚq–d)$’6øT<·®©‡N­ûÂ:ÙbWYLòo é(=c;ÉØàÛÝÈ…W#º±ù'I©ªSú¬¸Eñ4ÄþÝ Õ䩈í´$úf}*Ã9ï ÙÛlé/šxžÛÝjÐÛv\¶ÇbUi{ÔT×z_í7X^½²cMìË®8‡‹¦ëÃ}‚pË ä¿Åržb¢ð¤Äa Ês¹†qÖø'Vp{ô#¡D[48N6t£8ê_"ûœ8éK‘yŠ@;0J]«c7ÔÃ5Ñ/Ä–KÖióHæ^<~|])È÷%ï¾›S궸Óî¶[D |tˆO ö†Ã*ÕSø1@·O´û6'ƒMåß©JÄ&¿@©ü27PaˆL“ xÅkÝŸ&ü³p¡ØD(f¢ÀÏJ4Ýùû%J©g{ ±§P(áyz©ù+„š?¨Ùƒå«5ž:¾kÚrÓpsÚ’ìTï¨m\Ì e ¸‘©yxè•C_OÇ›a½Ø'X¥á½š@ bgjú ­•ãHÐA*»úؾ&+ŸÙ©M:+yÙ©yfìã´ ÿ4Õô‡š?|"N|pÌK²ÄÙk©&`˜ H tåÜ j2üë“aeûjü# Œñ  Fv|z`”$j8:Öªúη¸þ„K}Èùƒ§àüY!PÅíâÕA‰_(§~˜BY0•ް¿î¥P}LßUMžp÷J^Èm ïs¾š> endobj 2654 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./31_home_taurel_tango_manual_gen_api_pipe.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2667 0 R /BBox [0 0 818 302] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2668 0 R >>/Font << /R8 2669 0 R>> >> /Length 606 /Filter /FlateDecode >> stream xœ}“»nAEóþŠÊlStuU¿R ‹„Ìfˆ`m–Ñ®/Æü>·ç¥Yc¡ ztët½û‰< ùöMçíÞ½»ÎtÿËç`!Ò7ØéúƒË\4V£ÌI4*’”£zoœ{÷ÅYÖ¤¤RÙÄH´®JAcàTN¡ És¨´wRâð7+;PjÕXW®L2#nðæ¹L®tð+$ÉX„«è‹´H³²[SÈŸkZS“rBI-,º¦&eM/ÈfqVÖÉKN‘½²R”CZ”JkâxBMÊ@Å0ô®ÖÊÙçFU‘–ì¬}Ålƒ®|ÍJ£’”Ìÿ>ö±žÍ¨jdóÓ¿’fÎõ7LþÎ…ÆhÆpT¸¶Š5ÔÈU¥y>gö‰Ôp7–J™c^”F-]ú’¼!4zÐR9¥RPÖÂì=_°™c[ÆÅ<Þ»''ãÿtÜîérƒE®ŒEÚ|wã‚£ehRPl’Ò”i³wçŸ~öô¸Ý÷›®k‘> endobj 2668 0 obj << /Type /ExtGState /OPM 1 >> endobj 2669 0 obj << /BaseFont /BASHXW+Times-Roman /FontDescriptor 2670 0 R /Type /Font /FirstChar 32 /LastChar 118 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 667 0 722 611 0 0 0 0 0 0 0 0 0 0 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 444 500 444 0 444 0 0 0 278 0 0 278 778 500 500 500 0 333 0 278 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2670 0 obj << /Type /FontDescriptor /FontName /BASHXW+Times-Roman /FontBBox [ 0 -217 775 683] /Flags 32 /Ascent 683 /CapHeight 662 /Descent -217 /ItalicAngle 0 /StemV 116 /MissingWidth 500 /XHeight 460 /CharSet (/B/D/E/P/a/b/c/e/i/l/m/n/o/p/r/space/t/u/v) /FontFile3 2671 0 R >> endobj 2671 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2249 >> stream xœeU{PSg¿1ï[‹´ËmŠhM2µu­o¶JW× c¥."oQ!6!BH ‰ ©%C3p¯kt84è¿ WaR7&ïWU-¯µOµv5º0-ïíöŽŽ/#[Þew‹âÙ¯…?Â[HÏ¿U<ž¼ Ò5EÇÕoè -ûç܃b2ÁeÙår{E“ZNÐô‘-;2òÖ‹9VÌ}Ì–>^ÿ7¤í>q0ùBö™MkY»ü»U$†Äüð""±¿gŸ•ÂÙÛkÙlä±}»ŠNÆ4båTõ_àþþ­;÷D«ðUuèˆÂ<ÈD¿óé,©xKÛÜÌ ¡Ûî7àa—9Wü¨A¦É”R‹éUUĆèch—Ýè÷1ÙŒFNÌ—“Åß’òy*éë5‡óÊÒóÄŸ£Ú†tM‰1­*ެÙ%¸ºòɵ,fù9»rSC¢è…¿2þó<# ¼XÚþ3á !¡Æ¸ÓÆq§%£ˆ`øeèÎÍn~ ?Â7Š™´ûî²¼»0Û# ŸÕ¢ûV÷iî×Ðòù!ᛞ¦ñTË®ŠfÒÇ_–vqáÖWs³JÕ¼øx Gp4C‘ÉÄ8q_à‚ÿc>–V3É¡RÍRùåìJÀ*A4Z]6G½|˜Ù€þ ^cë6ÜCôjµðŒÞd0V)-¹\"H™ Ïé ŠÈr‰„n½o3îÔ‘•‘ú´]‹>©m5@ÒãöI2è÷pÕ%j™QMp¾ÃÏûl–ïb– Ûn{ à^wuž˜u ȶZÔp lõ¢}Ž*/ܤ N\:Ý6³GÔnðÔ¶x}}C¿¬ T˜#þÙ2*Š)Ú¸hò¦yЉŒi%6öõÙXzŽ41Búî*‚Ígµ"ëéÚÓV³4-ÿHõLÏ™¬µVÛ2¨³×;ê1}÷möÁÖüÛ×.¦†DF¦¬Ê\q'ôÁ÷Åä"¢çþ%7廩~æUŸ¡-æÞ,ÙËEñ1å×…6ÁQ“犘üÀnAôPºS×b†lÌÖ PÚ “ªB^£\ôÆð%1í#÷ÙUtµ®MG1Ûˆ¶_Íúxôb{0(š˜ˆÜ†èäsõ×ý!ÏŸÚ⸀?³ÝÏcNq¥°b½`°Îk-˜ëÍg̫ٖ¥/wm[]¸ã Ããq`/›¥Gê]æ+Ï“(vliC­Ãê°8uN‹œàjõŽ’§É'Kûÿìt 8p4“b¾•ú.³4só+²úËXú2sðCa•¡Æ¦¬¶¶MŠI&‚)[¿>PÊïL¼~wN²Ú_ÙèòwŸ;ÛxÖ%®wŸmv] –¦‹"vÃëU–|iE¥A'1•<™7=9Þ55-¢[3;4ãˇ¡«eägb7~%¹í´¦¦Ü <­\¢žŸCp{üÝÁCÅ9•¢Œˆ‹o…¦f®ï`£Yþ‘ñ™ÇzzEáê?b"ûy½Ÿó™çÈ&ᑤâòTÀ›|AпoÜû2Ôj:Ñ,vV4);t]w¾»³çfÒ[[s²*‹ ÅÙyÊ}°³ÏÜß@ø—ÇÚß ‰‚ÎàÀíǬÞ%¥ƒ…xÌ:²Mxdg~éH…üþÒ[º Ö¡úiL¦–ÌýeƒŠÐÑ®LȆ\T–[¨J„xÌŠ>z™ ï?½M¨K"v†¬zf†G§aÊÖ—8ø·¡“t‘ëáuòÏyR^'rrŒL Ï×ûΞ‡x§y"ðÞ`h>„K† ªþã“/õ­ç†×' }Ü„ZšÍ€%!Øj1ï´b-êDÛú6ø˜Û-Œ&"èrÉò;¹Ï¯IÉfQ¥ÁÞ qÆ ðÞ?Y233ÿ ×þ¿„ðfÞ˜©GMö–†V»âGZ ÁlÚÖ$³ío´4ÃG˜D3YD#T©ÕJe·º¯¿§»¿OÝS*~ŒÎûi–ß¹À:{‹½ ð`³Û˧¤ŒÉ6ÊäEÉçjšáf¢3 ™URóÞ*NÒ:¹ÔVLñÌ’äðÅïät´ÕÑÖÑóîê#bÖÆÐ>Ëa”yQFƒÞ1AÐÐÔìrõöLøFOv—$‰Y‚Ã&Sj8sµ¥Úõ>¸ƒI#˜ê¸øV‡j›˜-ætÙb9d圔^tªAÑ`쀋q¤‘ÅEïýáPÖ©Cé"Ý-Y0ò@iØ–Œ?å$8KËI°ž[VŽèJ?“á'i~ÁÀâ¹'𢢿:¢–PÔ/S” endstream endobj 2663 0 obj << /D [2661 0 R /XYZ 89 721 null] >> endobj 2664 0 obj << /D [2661 0 R /XYZ 90 647.041 null] >> endobj 298 0 obj << /D [2661 0 R /XYZ 90 327.822 null] >> endobj 2665 0 obj << /D [2661 0 R /XYZ 90 279.254 null] >> endobj 2666 0 obj << /D [2661 0 R /XYZ 90 259.329 null] >> endobj 302 0 obj << /D [2661 0 R /XYZ 90 208.893 null] >> endobj 2660 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /XObject << /Im9 2654 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2674 0 obj << /Length 2179 /Filter /FlateDecode >> stream xÚ½ksÛÆñ»~&ŸÀÚ„q¸ÃËq=£Ø²£Nâ¸1ÓLÇÍh@âD"q Jeúç»{»Òȶ_ˆ½½½}ÝÞ>è;kÇwÞ_|³¸xñ.VNê¥Q9‹['õØO<_…Î"w>»o¾½ü¸¸úq6BßUÞlF¾ûó׋ëï yIŸÅ,•îå‡÷?ÐòÍw×Wÿô©'>¡ºüxýiöËâ//Þ…Á@ %¤çËT´:DÒ\ø¬ô‹wÂRÏe’xB:ó œä3xÈçBxiÈÆÄ³yäûn¾£ïë×¼.Çë»›|yBq·o6_O±L¦)ŸÒ¥nõ)‡ÞŽî{µ¸øýBè;ý¤©³Ú^|þÅwrÀƒ/NcçÞRm™&^èG—Χ‹¿Ò=Ž\(|å¥J9 Û“‰ ½ÐFÊÝ; …nѦÖYNPÖÒNYTL-ðÚ¥t?ò)åþÃ}SóIcøÄ²4KØ„ϳ6#HÏDèþ³­³UÛ¦ &qj .fq— QÌž6VYE@£õs€”t‹vÌí×}ÓÚ™ ²t/ O w›µ­® 6·øõÝÕ&+ª¢Zv ±UØRîtµ†Ï¡¾zýú+²1EÕ‚J³ÊJbKNèäzUfµÎ™ÌZŒ¤Ow>D¦à%÷š¥·4ñ¨[¶Ý•Ö >îé©(õ«fgêVۛܬ®³‚±5¿¹Ù/KMÛäÃxh|w’lÃÍŒož=£õëUKѹ÷›‚øÅV-‹ÛWM±®ˆWì6PéL! ‡­jÊ:TD H(‰ïfÕÚвѿïuµBÁªó>âÛÃNcX%Òýy£+Ú¦ÀR£ë&Äñ [PF‡à o Rhj­ù@Ct|~_e³OÁ)òŒ¼ [½5õà•ÙÍè3²3";—º½×¨q ri b÷­žAÔß+M7ÍòWà~Vå£ÉPï0t=Œœ”}ÛÖxrä Üᨨ˜9-®GìÑõãSèúç½2õd¨ÚØ‘[úvÎA¸w¬ Ç #AU¸RB":³–O»1yǧjö[Í’úcCQä5`S´„(ŽÔµ¾55Ÿç]Úp­áUM¶,Ê¢=L¾Cë Õ—ƒ@uZ’ÅG|%àUzèŠr’0mèÖû’OÙ¬¥º˜”_ßöjÞêøe´‡Î7³™ ^i~ªÞ˜Ø^cä6$ŸISÇÁ¾è¾”2Vc‹jÚŒâÑ·ô%ÉLª xÈ MãYáS)þï3ÁbƒYb¦Ç›•>V[XQÓ%ÖÄ’0@Q=DU3Ä-I¤ì“8àà·ºjfšmù|V3Pš†yÛÇ"E'Ãww5[dö s;fr{{’ 4nßփŠz'zUYÙ‚6YÃ(ú¼ůHeBXç‰zµé”U»oF¹ áÈM ÆÛº ímyÑè³ä ‡rÐ3œb]º5*³¨ŽÉõTγ w½!zZVØ pm|ae¡Ïo€S#N „ýÕ„u»éWG -¥Îp|±åÁ6OióT˜x©¾¤Í;eiÛ¾q3,0TüØQ2òÒT‘?õ oõ±` ûà?Óg{Èõ‡à ši;œïHn»œÉö7˜º>ÉâŽÑ÷ Dgªu×N뛼œä§ÎÞÙ¢õŠ:fp䃽ú$§pR‰¿eõOŸ°¹´­‡Í"©ð‚$€Ó^¬xzø“Ý ½4Nœz >¶óè¡Jß÷Î3Ç]ôÛÑws‘Æ\ÓHÏ/TÐog¨‰q…|ÂÄ=<±0ï.+÷úi£‹©§døß]ðV(âÁè"RuVæEÚ•AܵW²ß.±:ãNLý9naRÁ/T¯ºpÚÇ ‡È–؇'Y·VYÃÌ©÷hY&5ùˆ§‚H[¬0.nÌ«îòƒ‰+Ü\†q× DÜŠÀ·ÕP/2ÛGÀªKèÐ?P¢CÊ£l\RmBZxÚ¶©¶Ô-!ÑuL¨X€!ŠÈª¸W™­°3.'@2(á°MÕS•“­l{œ¥[Îô]5„]ë—£`sDà©PâóñÒ€$¼1Íçy1»Ø|IZg ;Ë Ð@¨Ö1/ùO 9 ËØ÷D÷—„e4þSbÃs¢©üG*ßa8â <êýÃ[¨A¨`™ÊjP߇ âÈIo¢}öDûCÓ‚$ñ" AD^ðÝ*/ñ B˜û`Ô?P[èG¶\4y¹Ö•®‹íÖØÈûZ÷}WØëÂÞþ3DÑ}©óµîŠí‰÷1î@Ç8%ÝÞZçÁ!ÚГpózà"‹6îvm]8" Åñ,NÓ·º¦ñÝÒÔf¿ÞÐ.í¸IÝàtÔ§!Í Ë(3îbF2ok³%¢‚Ð=ó©Gf(Aaヌ´`"ˆD5¬ Eé »õ†˜•Zˆ@þÄ $d ø )¡8vR9!Q%‚hìj¦b,‚õÿì­ñ*u{ƒ&ßè²½©–]Ùœ¸Ö, º³Ï'Ø+(-òAæ8‰>Æ>†·?Æ~® O$çës#à="' =)£NOêý˜'ÏYøŽ>Á ÿx²í5Ýô£$yÝ.–º4ÔfË~}`ªëF@ÉÕÄ&Vrdh_ÿº,CñeŸ3Í }S^4m7î=:× f:o»w^t¥'2€ìD¦|;)ƒË¿¥ 7ôûy¡Ÿ-“Õ87NOûæØÔo_>©ÓÚäÿM÷.üÄKTÚwï"ø´ïaß¾[yMñ‡¾i‰yµ¼ÉõH\¾óÖÓ/÷¡ÆÞ2µ÷‹çí\5P3¶ÇÿúˆzÕiaqÏžu/k¢é·Rþ5µá‹ñílêŽIáQú¬’{ó¦âãßš’ endstream endobj 2673 0 obj << /Type /Page /Contents 2674 0 R /Resources 2672 0 R /MediaBox [0 0 612 792] /Parent 2659 0 R >> endobj 2675 0 obj << /D [2673 0 R /XYZ 89 721 null] >> endobj 2676 0 obj << /D [2673 0 R /XYZ 90 269.522 null] >> endobj 2677 0 obj << /D [2673 0 R /XYZ 90 247.539 null] >> endobj 306 0 obj << /D [2673 0 R /XYZ 90 217.029 null] >> endobj 2672 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2680 0 obj << /Length 1822 /Filter /FlateDecode >> stream xÚ¥XmoÛF þž_!ìËd Vïôr’º¬@º¦]†ôe©»bèŠ@‘αVYò$9Y0ì¿<òdËQºóøv<ù²p®ἤ­è*É>OGIX G"„ô„TN¾>úøI8ÐÁ¢§±sk¤ÖN&^$¬+çÝÑÏ„$£"–"ôÒ0tB‘z"MÈÅ n×÷•[o×WºÅuä6K¢aEWz­ëžÈeMÄÞênÊ&RÛ4,tU5WD+;¢´J_Ï€r3“`’¨YORUY3%ð°4}t7ʈ@„eÓIgùŠHÖW5øŠQŸK:ó(öèP&nÞºðð÷º„V‘AVqEV ¬>‚·ØwËžmÜày²j«ù™tYá‡VY]ÐbÐ#Ü3¼Ö,â{ña >1@¬¬FVc76‡MÄMe[–çM[Üõ£Àí|†|@ààÁjwÑð²w8ßIáÉ=hÜyÏñgßfy§AÞ¶Ûya5ó*ëº2Ϫ{ZeS“H³Ñmx1u8Ó(8ØÂ@ñiRž¾°-:«Ø«0ã+/ò¹àCš–ÊÛÂiÛÎd2Yguv=¤ÕAa¡?‰§¸¢žÝ œ ÐË™n¶­0i|ß§º‘!C*ʘBûn[Ø).KRh@ô9åC™ë·Tc¨tõ;`'­ûUÛ ÄmÇ›–K|]ê–.L|.1MF»™çzƒñeÅý %“!Ò–øàáDôÑ<¤_)÷ wL*ø4u7 \+ ;½“À-Ê.ˆ#Wˆ? œ±†—$}×lÙFC„®Áz”’ýL©¦‰·Ê:6Ƚîz^Yé{áE›}ÖëÉ"ZöšÓaœ¢ˆWpÓ¥ÀÝ;7ʚș%^XÚ²çQp€dƒ^ÿ6_ ŠxÜTh;ˆ2_ H8Ìw“a-ñ2zÊú]¶…nW®Ë*¥q1ÌŠ‰ý—m³ÞÛ?‚Ã@’n´IΆ$¯”§¦‹ÿ”¤ö­Ã: ^‚=º'  HfÞ¾9>þïþ\÷ß"¼uÄYe×¢X>¦>3¡'JF¯¿ á·Ó¨>²õ¦bírI Å€pk†ÜšåM".IÌrgàä|eÿ‘JÐà5§söÑ(Kè0yo3Õ6;2ŒOSpÝYº¿Úìn¬¾­»òºÖ¬×­š¶÷¾êã\Pàáù6?´øÄ."/ endstream endobj 2679 0 obj << /Type /Page /Contents 2680 0 R /Resources 2678 0 R /MediaBox [0 0 612 792] /Parent 2659 0 R >> endobj 2681 0 obj << /D [2679 0 R /XYZ 89 721 null] >> endobj 310 0 obj << /D [2679 0 R /XYZ 90 356.879 null] >> endobj 314 0 obj << /D [2679 0 R /XYZ 90 140.062 null] >> endobj 2678 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2684 0 obj << /Length 1462 /Filter /FlateDecode >> stream xÚÍWÝoÛF ÷_!øa• [½Ó·°l@Ú|ÔC×u»>tE XçøYr%9™7ôy¤l+Qº [êE<÷#äñ„um ë|ð|6xvùVâ$¡Z³…•+±#üÀšeÖûÅËã7³Ó·£‰ÛwF“ öû·ÓÙôõ91é7%ž}üúü¾x5=}=#úÝÅNøŽÔñ›éÅèãì§gg{—ž#¼  ¡2Á ïþŸIq¸zâű#=kâFÀóH‡M¤+„}¢nô\½Ñk5š„0ÎÖ¿‹@ Þ"k´ü7Å)$`7¸}LuÞ¨ySVGuSéâúGÖ«.‹t¥jý5<ÓUÝœœÇà 5/‹Ì³¥®úÜ»§Ïê³+§VÍe–6é¥ÊÒ‹¨Û=Dt˜!{sï‰WeqÍpsúÿ@¿0 {F]‹³rs•+¶øæ2»bk¥#åØu\·ß°˜µlŠZ_*£Uõ²¬#.EäI‹œÈçó{jf'‰bë€VUºí@/Ô-}Ú ùA ñ‘€,Ï :ø’½‡~K«w¸ôØldй¸ ¡ó¬vv³©—tóJ¥º¼§ÓØ2pûóœHO:»ø¤è;W)i‹¦Úö9]º|8Mº¾I’::êÆE;ÞòNmì=fé±ÒÕ6S7Îm¥Áò5¤™‰ÝõƒQ+}Òü¹w2`G¦Íœ]‹êÀ¡g©ÎÛÓþ÷½^ ¿ä†ˆÏËMÓ5s¸/Ïó’} ‹ZU. . ‚aw¡*²¼ß̘7sàëHüp¯êΟHaI¬Ú>DŠ¡5_ >|V|ÐèDIdÝ©•å%± &aåÖÅàWªþÂ+…ï$½¾H‘Ä„cº·Òó0º)‘Šíf©ˆu¢Fn`ï +Nêšæ²²`NÚ'×-Ã9·ºYÞQI®%º\«*…zS¤7PÚ³Vn•ê‚–fz(ªRÅ\(¦D"Ã:V#Ø4U:o4B7ˆl¬²D-ªr…ƒBÖÚX‡Z‡ShŽÉ&¤<ú¥EFxgzž´ß/UAŽšû;’gÍj’ÄýÆH&ö¶ÜÐT¡TF ÇöÙôíÅŒuAÜ  ô„“nðDüÐ.6«+U]f̃{©È.Ä!XH©\­TÑÔèú$†pज़ŠVÓÕ:G°^$øQÉ.0hLDJ3]èF§¹þS1\ uåpˬe¥Ôªã#ºÚ'ß#ÁÑäÛ|#iìÃ9&:‰ðíšåØh Z£i¤ùßú—õ§¼aÑ>wH.Ä'-ñvKYï Àa,oiX©O]™­xåtÑg$1žŒ$Ä$ÝýÓ$…ðwþ@6¸/l ¦¨=±¹ZSV£Ì­ÎsZzÅÊÀë%žÞ-Kd›Šbd(#€¹©qЭÈ8(‰È^©fYf:^䛬í1n]®7yÊ‹ +4ºÑæhoy$aÃŒ¨EYÝk°"²ÍT±K/qàPC»P2£RëJÕ0ßê_B!¡ºÜ©|L›'£ °Q |š×˜Œa¶Ôµ†¦ˆø&E#Án‚é@sº?¸iò´f%àº&…ÒU“h»z?V¶d%l\´3.Ú‡Ž‰—€du}¸°’r²ÜÔÿTMN“7Ve¦1ÔZïPñi-¢kYÀ–9º»<á9~âÿ›»ë®Js—uß ‘åÆÐCAcöŸÞá#Þ.8âîzÿÈr³yœæÍp =öƒ-ÿ@ŸMÌG7ÚA°¾Ö}uœôJ cfõ ¿ôJxTï÷÷÷þ×èïÃîûãý½×ßß{_µ¿Oúã©k9î£Jˆ Í·ÏÏqÊ[T.ä£ëÅ_|u_óÕérÕóö`kzSõÛz~ßÌó#ü¿žó°ÿ endstream endobj 2683 0 obj << /Type /Page /Contents 2684 0 R /Resources 2682 0 R /MediaBox [0 0 612 792] /Parent 2659 0 R >> endobj 2685 0 obj << /D [2683 0 R /XYZ 89 721 null] >> endobj 2682 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2688 0 obj << /Length 2263 /Filter /FlateDecode >> stream xÚ­Xmsã¶þî_Áñ—P€ï¹kgœœïâÌõz•f:>‡"!‹ŠTHÊ®'“ÿÞ]ìB"%Ú½´ý`±XìϾ¹w„óþìÛÅÙ×ïâÀI½4R‘³X9©pb‘x"Eáܸß}ñiqùãl®BáÞlFÂýùÇ«ÅÕÇ÷D¼ f1K}÷âãû¿Ñð»W—ÔÿézÏ|Äuñéêzv»øáëw¡(Hß~ *¢yÎ+}Ü^.Î~=“ÐŽDý£Dx"QN¾9»¹NôáÅiì<®ã§‰Šú•s}öw:‡‘ R^N&žŒRd±Ö w¹Ûf»«²¾lj7+j{˵möDÝ]§ ê­šöˆ­_—-OnË-‹¬Ï¨§+½ÑuOƒ²£¶n˜Ðêm«»™tÅn±Ö­†Kò“Ä}WÖYU=Í¢Ð}“‰Û¶Ò™K²n.¥—†|Õfƒt§ÆêÝÇ™®±'ŒÝ¾!bYwºí©Ï*ªgB¡g*tÊ\Ór´5T‰ûÏ™¹ÍŽ×ÙL ÷a&CW³ -)ôg!T­Y›z·Yê–7©-1ÛhÖß\* G³æ] Ú3Åcãx,Áf¸QT0W„ºì}¡Àã.7e•µÌÖØ9¡Ú®§Œ7º_7¬–4^¢;øOh>R³–·É–• ·'}2WÒItµ“á9´~ÊڬƣÆK·i s¤Q x-ë{¢Nv~s{ÎŒ[Ýf}ü Š +kÛ²ïuMl+ËÁ"÷íŸé0I·w2ùmÕ,‰!¯²®Óâ%òÝMó /ì N˜¶jªªA‰d DJþ+Ûl+ýÍd49Ž"a’xÄ‚?EŽEš¨"Å(¬ ã‰Ø £–&¤.àB*!àÇÁ¸Ø"äÎÿú„¤sÐë)kÕÑg™:‡ÛzÓõ-Å_X®¾cwÁÑoçïJ€îÛËóWç×:oêÂtèþÐû}rÏ€ÅK¯ÓýïNW=ÉE­í§ZG$!œNâCƒWgÔ­¨ý35QMª-.š8[üpW,GB~“ž”¯”§Ô´} ÛÕ]yo"®êÖMK‘CŠØ ÓyqÀÙáOf&ôÒ8qdNƒÍkýH)é¦{#…¸}Í¡’aÅêôpPÿÈÚŸ®qé…ÙÈh§B/Té3ÚÅC튇]·i—·:ëõ݉d¼UcË+Pîp­séKã#ý¤˜ºs)-°oP»%Ú›7‡«š¼©‹-bÖÕôJÿ°ÒÂúx%Ãë/ ì¨äÿS^øqê)Ij^ Ò†P6¾Câ»ðG¹'87!sGmMaESóBŒ—H©ÊZ3'Þ…Þ  l6¢ˆŠ#}Pä æÕ:Ê"»Tä —‰ü–íÙZc_\[ø@Ï&i1(|`@u‰àÂ:TøØª¶êjâcÓ³´~õ¶÷ò¨Æ[åYg)p)à¥}iNÞd:*ÖX î§ ¢+½ÄSÆuàºlÛ™ÄK"7YÝï‹#` t/âÌðóÚ$ÔDښ¤3²%‰… Ò2jN-ÐÌÖ–EM¤[S!¦Å[Ë:Ð’è¨ålÿD£ÎC(Ö*¤@M'\‘+»«¶ÙPh{±ËSÇ “AÕs,¦`„‹Ï“@1‚«(WȶxÔ9 2ž¢b†õt{4IŽM£[šH`©MƒÇu™¯§ìË›]Å „Œ{¯ùÎÀC’ë-?•»v_¦ì¡º¯!×·N±Ù–##/ðPà¤8ä~Vjüzrnæ!`rlh;*¶œàh˜,ŒO¯€J\#nÅmß½ìyûR^œÔÿ‡_jÍzB±qp?,~)t›¹µÝ÷½HÖ SöÀ·æØí#D¸U“ÿÂ=õ?eAÄÇwÝgÖëß<¨·˜%ð"ªï¶`] bjL¾4n0ŽÜ8.k]yL> ‚`p¬wÁÕ ·­ð\ÑAƒðDŽ5„„vÔv»í²¶.;^‚h<\Û^f}¾âS|I›Ã[Š€]«i`QÄpDâW-ô–OÔf5·ÛmUæöq „¢á°EoBhºœ˜ÑÑÆOu¾n›¾µô¥Î6ÔÃÔ…J¦€]æÞåk»|ÊáF̱)ze)ˆô’5ðóS X@Ý Þ1D1úa›÷;~îÆ7˜Ž!ŽddDÀ,lÐã-Oe’gÍîgðè+k³NZÉC~–†®çyƒG3LAŠÿ sK?Un Œûéà·GrCí’g‡z<õDm¹6î |yUj+ÂaÅËy—à@ ÿ ‡ƒJ„ù¶îÕêAS…ÄùŠÅa‡ð僧 tG³ûqtð(¸½¨§‰Ç²ª¨·´bw”'Â}òØcÆ‚hléçX«´| çD£"I…¥¾ÈÊQ€f/ …ýXðý`š°÷}2å(¤òRóÛ`är8®‰âÔî꾬žWbtá†}ÎÇO+lÛŸ?šÞ+âÅ!R#Œm©7þN:Tl[ˆðð³lÖ©ºþ›£éiÀ)2|&EBJð)!ñ‚(µ‘y³Ê¨¸+ëf7U¿E1˜°gÎ „Âdöqœ2 3B 0B8î5M™[µ´]GÄVÿºÓ±§ÊŒè¬Q¹³ß†r ”(PÍ›êœÅ –ev”Ãß7fLÎì‹8útñ-J2J~LÅ<&¦Ä Áª—Ú½ AÞ%ærE5ù½•çºë,H×z“yc$Ìé^ÿ{(à‡—¾Ëz(ôøKOOBy"Žì´Œx†b¡xIâx,×<‹&¾ÆCOʾÆFI_y¡¯þg³Ú™»ŠŽì“”ß0¦¼ÀÖM(.ãÈ“Qü=£É3'‚N‚ŽDE)8}ôêâ—Ž¿¸FÞðÑSd Lå¹pƽ$5 =¡¢g­|Vü‘¿ž endstream endobj 2687 0 obj << /Type /Page /Contents 2688 0 R /Resources 2686 0 R /MediaBox [0 0 612 792] /Parent 2659 0 R >> endobj 2689 0 obj << /D [2687 0 R /XYZ 89 721 null] >> endobj 318 0 obj << /D [2687 0 R /XYZ 90 350.528 null] >> endobj 322 0 obj << /D [2687 0 R /XYZ 90 260.366 null] >> endobj 2686 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2694 0 obj << /Length 2107 /Filter /FlateDecode >> stream xÚ­XYÛ6~ϯ0ú$£kE¢î¼Û\Ý¢H‰‹>4Å‚–¹¶Y4(9[ÿûÎpHê°ê-Š>¼†œƒ3ó ,v‹`ñþÅë/ßeñ¢ð‹”¥‹õã¢YûAœ,ÖÛÅïÞëŸnï×o?-W, ¼Ø_®’4ð~ût·¾ûðž&o©Y/‹È»ýðþ# _ÿr÷öÚú¿~vĪÛû»ÏË?Ö?¿|—°qùA”ˆZ†4EšÚ¶‹UT¤~R‹Ë`oDÔ_KFô‹ßWIxGY×U³#ƼÙR§–»›-åá+-”¨y' ]'M»vcùuž%ØŠ%K¼oU)ùb¦~åЂZÌó#ìV@ž^YW¢éZtêL2`_R»ÕmîÉFЄ|4{Ñš©’×µ9B6ÔrjFÒái½tzüTÕ5õv¢#Ffç¢|· Wµ=@àø¯R»J6àQ‘yw£íeDåP;ô‹Ä¨ÍǺ*9îD[!÷n½tjʼnœ°^*ÞîÅöGÌߨgŽÒŠéƬñS'À s¦%¸IA2âúc§/æ¹eú%Xce¨ ø†rð5 o½sŠûÒå•Dû|«¶Â8§¦Õօ޾=h¢ÛKëaR걅зbìx¨òËSc5: 6\ǘráJ¼ÄÈ7ÓˆÉh“¹§…È7‚Ô-ŽZƉ'ÿ:¿z¢-Yà}ý$|áL`ç×AnOÁ $š!#.ÏÒ«œ´žãU0¿ÈB{ο0ãØF+„~ÄâqÿV‚€h;ÞÚ+:„,ôã<²Þ̘+öÓø*ê}°<)Ò®ñã¸øù=lÎqkûq‘=ë€IŽñвl&Å8,'í´ÝX*uÍsR?+Ò©çìl(£ï8ȨâE.å}¸²,ˆÆns%4meÕ °´S¶¥ª6[ªf>.ñ(ñ(”hJ3_îù’Wë“VY°c?ŠS†jAòŠ"?—Ö2Å~,WaÐøI”²iDÙç‡Âæü;ÁŒù,Íœ’ËUÌbùOØIF$,ÎO23NÜòæL$Tb5”×7¢{ 3‰V ˆ“-æjðBÌé8®" PÂL½z; û©©Vs™ÜæÞ8À“æå8H½íI雯iNM¡IõÕÌ—¥h[¢ïÅí78©qJK „fm |’xdz,õ~<ÓâV<"#~ª;À¿8޽§=íö•J>«©%¡U »²,Oª…#`ÅíúÝiªj©U¢;)8Â`ˆƒÄ8w)ÌÑZ;MåV×9w\uÄÍ{D¿Otá0óÙ9X,ÆbØ2ß–õÎÆ¯¿ÿ~Ñ{wG´m¸«î÷j$ûe)?b÷L)Ÿ\O#zD<ó°gðŽo0°f7?#À{%OÇÿ´óöXýÚUõù¶ë –ÒqÚõšÏ¿Ð)z¢0‚Üi–ºÝžcæ ¥¼Ð¤ \]-4ØCÖô¶÷´ÉiЋÁ‰ñŒB#ÁÍÕyf­«™Úºõ äIc³O$FåK 2—Xj³aKc‚F¿\ èÐ~§kT›[!y[i-ÃÌÓ¿¶¤mº&¢'&ªíq6¬5ú!Sm5ØSÍþ&ýÐ=Üš˜öP€Àšåæ9˜…18ˆäÂú”˜.ñú—ODf€öµ<«¹ÿ§UÓ?†¹ûÉË j@Ïbò€^½&Ü =Kͧ‘ľ±p‰2aæµÕ¡ª¹"ʬXˆÿp*¸ÏÐûª{;šžçæÞ ËP®0uñK ß뿎7s. ßíø3O*hÍÛß9c`±0ïg„Ì>´²pÿý:5C±a8ü·ŠãáËÇG%ñ%ûð¡Ñ¡ µ[Pç⪗úéj=ý䀭Ìi¤ÿ˜hyÐ/µ®óÿQM…èÏþæ»~ñ7„ä endstream endobj 2693 0 obj << /Type /Page /Contents 2694 0 R /Resources 2692 0 R /MediaBox [0 0 612 792] /Parent 2696 0 R /Annots [ 2690 0 R ] >> endobj 2690 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [439.383 130.678 453.828 141.582] /A << /S /GoTo /D (section.6.6) >> >> endobj 2695 0 obj << /D [2693 0 R /XYZ 89 721 null] >> endobj 326 0 obj << /D [2693 0 R /XYZ 90 546.668 null] >> endobj 330 0 obj << /D [2693 0 R /XYZ 90 419.046 null] >> endobj 334 0 obj << /D [2693 0 R /XYZ 90 183.828 null] >> endobj 2692 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2699 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ]N»Â0 ÜóÛÔ‰“´K)%•—bÁT!þ¡4€PeÉgûÎö!Ü¡SÙ<7à¥wÚßÀ#äXH4ø §¤Z”®wéD[LŒL'ÖarÜm‡eN=%eÛ¬c[­BÝr¬ûŸx¤*7aŸžy™Í­þ3aI¤¼·8xpù[#ðczŒ5 Õ ”í²$I¸tâ)ô@Æ< ”QÒ:òqÉ’ú/…N!ÌbÛÇøÕ 0Az endstream endobj 2698 0 obj << /Type /Page /Contents 2699 0 R /Resources 2697 0 R /MediaBox [0 0 612 792] /Parent 2696 0 R >> endobj 2691 0 obj << /Type /XObject /Subtype /Image /Width 523 /Height 622 /BitsPerComponent 8 /Length 109673 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF  ÿÛC     ÿÛC   ÿÀn "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?üÍU2 “ÀbÇÐqþqýiòpÌŘäħ׿—µIæA¼‚ÄaJäñž?—ùd8@‰ãž{צÑv+¾é aòœ}Óßñüê?²%À,ÊÀœ1לõüêÉMªH8*prÜ’_Z`S!*_r‘Œü }{þ†¹¥êÂÝÊYîUà{Œž™9ýȦ6œãs)/òî9ÏëZØX—y`äüÀØü*6 Si#ï`*Ÿ»øV\…cíåEL)žCGùÍ2HØ>xœƒúÖÁ%T÷à®2~£·øÒEûÿ½þ³nAa‘ôïéPÕ…cª©Án~†œ±„VÞ ÇEÎ?¥nYYÅ.ñµ8êz’1Ú®›Km±©0éÆqŽŸÏó¯^†W[MUM$ÌeQEÙœ©fÁN@¾ &ÒÜíã9ÁÍu¿eT‰€‰QòØ €àqÇNÏ¥5v4€…V8Îq9®¥’V{I«Åœ¬cäc÷±Ç#Ïðþt¦2¹Ý”àcÐWXª'þì¶æ`È= Ÿóô¯³Õ£¥Pj)³=¡Än>bUsÓ,<ûæ†&i˜®ÖÑ·;ðjÁJŒ=œÇÛðªî¬­+ã¼äŸ—¯×ŒþçÊüÚ“( *›Kp¡Xu9ni†EuRT€Å¸ÏVëJ…УÁ ç éëÇHÆÎ€rœôéíXI•†í1G”;AèN@ÿ>õÄNr¸!rÊÙò~µcÊß(Ø‚HÜÝþQךM ýÒ©ÂðÝ1““ÅqÉkaZÚ•! 0¤í%ŽF@üzUu-"«cÜôçüOz¸ñ±‡Elõíééɦ¶"€XŒ(ŒöÛ5¬U’$.Ëæ‚w3˜|ýxãðçÛÈÒÆMŒqž}¿—çV¦€‚dnÀ9<ú~_ç­Gœ‡‘ÃÔ û÷þu›ZÈØ„0¢€U 961ÇãÚ«L[ÎpÇ€§ºôïúçéS™ä' ÈPýàIö?Ò"Ÿ<®ÒÊå‡9>¹î8?äRØBƲ€ªm »qòHÏù÷§Í:!”;FÙó8®=süê¸RÒÈ~ê ô㧯\ÓU°ˆî’0½†xý×ô Á´†V\°oº§J»mk,ˆâ¾Å,ÛG=yãÓŒÔP óN~RHèÙ<þ5¥f²\YÞºü¨±³œdñŸÎ¾ƒ)Áýv¢§-ŸoCš½Of®RY\ªùNI ã$ãçëRÛDZcÌQ€w3)é’8ÎsZßt4ÑnlÚ£ pãäåqÛ·-úv®:;‰£ÛÖ,Ž›xäûûWV652\\°Õn=SJ÷Õ}›þ&TÜq0US°²[RD·:´ã;\ÚV#Ž9ëW–]=mˆ‹Ä¿ ˆ ÓßÓÔ·ê+ƒ7s‚A›a`&8ïÀ¥i&¯ïœ2ã#wN¸8ö­¿Ö:‰rªjß⨿)¢^/¯à¿TΪïT¹ ±]]OîaX½x æ»_øRÏ_Ð?¶VkÈnlõ ‘%•]1Á@wdd`cÞ¼z4>uÀV <îÎå×µ} ðŠÚ¾E8|¼þ%µ…7 Àƒ„çÏ^•ö+™TÍqî†"7Š‹{·ªi/‰·×¹çæU <ðÝ»l¼Ï°?g×½Ó>*x~{0ÎÞdŠ0§ƒå8çð$×Ô7¶“?Ä?„±Låwê:Ýûü¼ûl þDË¥|Ùû;ÿ _@„¦Ð¯!`8?êd'_Jœù :c8 Ž}ëKömÔóEø2¼½ì^ Õ°Oñ“ÿ“ýzÖ'ìß®%÷Ãÿ„E]±©ø«T»ueÁ,¶×YÿLj?Jüâò§)[F—þÝ-?éOšÿh °ð‡ŽÕØmÕ>/]òFV;FO< ä{×ç÷ÄøæðÃL¡Ó‚0 ý+ô£ö±Ó|½'Nˆ®M×Å Fà!Àÿž„’>‡ß¨ö¯ÍH‡Ç·*Šyœ°qãvyõÏçU›¤èÒ}¬¿dÿwýyŸ®_ðK)„Ñ®üšb÷Eïù×çí…‹¿Úâ-Ñ“Ìf×ïòê8âwtÇŒç·Ö¿E?àš»mþBɸfyhÈ9(¤Ÿ×?LWç7íFC|dñÄ¿â}¨Øÿ§†Ïù>µífT”§‰ÝóT*ZPO»>}m¡È ¸ç°zc°ÿ=)›w²àÄsÔóïô©¥Œ‰äNÖ*r1×ü=ø¨UŠHœtŒöõý+ósèˆð¥Éûƒ½iJ¬AÏ'‡ùéJyb€<Œb•—oÝ'æàýhîÿ¼ùTÜäq“ÿÖÅ0îB«ÀŸŸÓ¥ƒ‘’¥xÚ:ŒâœÅ¾p¬¡pFÑÐíúþtéäW,*¾˜ÿõÕ¤ƒÊÀ“ ¸ tíÓñª² 8c‡\çœc×·¿•Zy$Ž r œ£9íþ¾´ Ò0™pT‘ŽÏ§§8¨‚ìùÁÁQ”ÀÏÓðïS]ÌÆ pÅ{nÿ>¾”Á¾\s´ïü(ÃLÉ•+‚ª0Ë×®qüª˜h;†íçåÇ=zþ•agBPoæfQÇ~¿…VÚC¦FÀO§1bÀ*í9+ÏËß¹æ YÀÚ[Üš³,ÎÇ(HL|»qš¢i eq ?ÄÛ²JÙâE!Û<ãëI´Ë…$t ½=ùü>´öp[!Ñð>ðÏ®J{eÀÃÜq’1þ5ìN÷fˆ\VCrŽ=þ”öñüž ÉñÓü⣨?3 àžsùý)v—P—%qÏËïþ+–H¢m¥ð¬¹œtëQ* Œ’ ¨Ç¿¿çîjiAÞô8f¼qÏÿ®™å˜âÚ[cç:õǯøV-Ü›ÜkÄŠ³´ÿ=OóÿëT(Ñ®ä+’T.[ŽÒžˆV6Vl¦ÒF:óÇצ)²8}§haÓ'¨Éö¨jÀËör7ÙÜ@vÈý8LsVo‚pAïÎ}øüª®˜‚âfúwÿ>Õ}“bŒ€Yr$ÿ‘_©dÔ9ðPæëþg—]¾wb1»€þzÐqÎ>´áng UAû¼ÿ_Ãó§yй!ŒmÇ-Éìãüi hÂå†Þ…^O¯¯ùü«Ûö)JÈÆ2ÖýîÖ>äqŽ™ïÓô¦oa1ŒÆqòäœT­óE»¤ñ¼úñ¥eØwo^y*9,F? f¹*R‡2л¤2i÷’އ~b?úôÇuÛ–W$©brÈ©Ú7 »ÛvÖÿË4ªãîãw˸Œg?þ¿å^„0ôž¦NWJì&ŒVFef?69#ä{ÔÚt{ïc]À³ºxè3ýZdYl(P< ;x'ƒþMuü)}â?ØYYZ\êÌ]Ú!y€RIÚ¹8ã?JâÅZŽ]üŽÜ%U­%«hëÎi=Ä*ÇÏ·¤]ßt`ðFqë\™lº–­$ rð­ÎFïsôüëÔ|YàÿØk:ÔC@Õa±K î4Ù`]ª§æW@9ϧѸH¯ƒŒÛùV£Â°³–EvX†@ÈÁÀ¬ï/Ë”’ÁË2—ã é“þsNÖ-Ь­0Û†äàÏ·jÜÒm·éÚ›°û°€NF9eÏ_Ëñ¬Ý)Gžç*Ç¡9é“ßëç]>k·ÃšÔŠªQ#sŸYS§úõú·áTàª5ÕþG…˜Mó(/#oö‡ÓÊo‚¸'@”éÇ£WŽ£0”/C’ nü{WØ_µ_ÃôŸáv‹®[ÄòËc},˜ã<#ªò}9UÅ|ŒÖoÊHchÓ$«H%@ê?_3ÆULî²]9WþJ_ „©C FrÕM]|Û"ò„€ª§˜X‚O¸Ï^9ã4 HXK¹CÉãß5ÓÿÂ-ðä—òNy$Ÿ|zöô®fDHdݸ£nÆïl×ÅFjM¥ÐOí+¯A±à0Æ~V ¯¿Aõ¯©¾ [¯ü)mI ÍâØÔxBøôþéãÞ¾^[Ël1aŽA(ö¯«~a~ xP,~Yo*¿ÄD2 ~C¨=±_¦pÿ´æ×ò?ý*'Îf×t]ÿF}kû;B⾉'%q1ÎüðÒ¾…ñÅÊÙÚøVÚžm‡µ«OnŽô_èkçÙØ±ø¯¤®ÖPV|¿lùŸJö¿‰÷©'‡5ûS&Øìþ_JuýädnÿÈ}kê8µ_ð¯ý¼äÉRå—¯ùýšü F ÌžÖe$c†k‹<í×ò®;à3¼Pþζ›w¡mPw ä8„"÷ô™ºþ×~Ïm-†µðžÓphl¼y#‚rw=ͦ ÿ¾[`|0Æ“sð>/0‰-|=¬ÌÈxãlv¦;ú¥|\é9N¢õÿÜŒúG§õèy§í`­}}ðʧø¯T¿ ÀÃbò05ùoâ!çx­ÌŠ#Ý1áF9íŸ~µú}ñ‡þ'£ö~Õ#iαÔõzƒ¾ CÉÏ=Gùùy¬K¿Ä*Ç,K|ÙxõóþEsfÿ¦¿¼ËºövþºŸ©°¯‰?°~ Æñl%ä’^zå¨úžƒõ÷¯€~8^M©øïÄwG fÔï%%N“+ã¯_äkì?Ù#T“þÑÎæ.Fʼûv¯‹¾$0¸ñ±8ÚUî§#$ç;Í}¾mFÂÔª–²KÿI>:„Ÿ´WèÙä×íÉ9?3œäõŸN;zU7‰p3–‘Žùâ®ß;3à” g銢ª3¹=I_^õø³>µl’ÀÀ^sþsLv,ÃŽzÔ…U˜`†<>ñà†(ËPª¹þè'ÚÇ *q¸¡N¤‡“J…8ùK}ׯ‘ëQ€2»H]ÄðG·z”ã{*D»ÏË…Ï\ýùú€E"ˆAå”ð@}*C<²Ä~Uõ0 ˶CŽáXÿJØG´£î ~SÏ®:sQKq$RÇfsúÒQ‚ÊÇf èÓ挜ª1P缆ý¿ ”’”)l³ªñîMeˆÀG&0Çÿ®½»§¡½®F£»€%rHaÛ°ÏùëN;eUÚ9Á ×?¥*Æ‘ƒgð9õ¤%Bà¯ÉЕÆ1ÓµrJä¤G1*rB–ç®N%Šóòæý{Ô±ƒ ¥ÉPdO­!E‘vŒ–'øG#¿¦C]‡kêV'h'jŒ°õ¡ïëHÛÕ™˜*g ÇIÏóÅN͈Âü»y!”}?ZbÎüÆJ“ƒž~½úqY2ìjYGæF¹bŒ$Ûò·'8ïNuòø$ã?.W¡>ÿ‡ò¨-q%£3'˜Á€wNœqéšµ’0€í*~ë/9'ÿ×_³e.SÁRo²_qâÕ’I uFv+ ÷#¦~¿•B@$)‘€ÚŸŽ?Î}j\îmÌ’0ryÿëú¨H¿wµrœã==»úÿZôä¬÷3ú±‹û°¨@3œŽ3œmýE8†x¶«Á+Î9Í+ðTwÆxÿ9íJcyœ±‘œ7|òãX¤›W ; !¦:«¾@àp=ý©9’5;xÇÊAÀ¼ÿžÕ.ÂK7Ê çiê98õëMg` €¹ÁÏÏ9ⵋ¾Ãqz"xU%ºo0n;(pÿ?Ö¾Ìý¾ ê~<ׯu=:álµ RaŠPø(JÜý7~Ÿ‡Æ>c! Z<2F{ÿ‡ò¯Òø'—í=à/‚Ÿ æÑ†¿’¸“.¡†©NYl¬åºM¿š}ÏÕrLÿV•O¯ê¢®›IyYíßð>Sñÿ„b¶Òd‰aS¾Ö5Ú~é r?ñÚùSÆúzÛkšÇÐ^jDsÉÆ~xóÀS˧̨»‹[YªüÃ’×MþñWůÜiz–¦ ld:´§%A!]ÁïÉÿë×Ðð­j±V›=ÆTëÓæ‹<úÍà¾s·'· X‚>Lû×;"v­²1“ƒ‘ówÿëWâ&æÛQ¹>SK˜À㸋#ðìk“¸´Ä*TðñG÷›}ùí_³Ð«­#ó dìd›vû[’@߸Çà*´Öв¢²„ʨ$ ÷òéþ5¥:¢±P·ï²Aïüª‹ó*~ò0UòOÝ"µµÞ›D¢ÊBÞZ0'#pëÓ“‘ÿס„°¬ª7\>NxÏæ=jQ˜Î~}±’@Ç÷ºþzÒÉåÉQŒàƒ‚ Àÿ?çŽy'ÔZ¥b¤ñ6ÕÀÃ~QÀ<þ½ûÔÁ ²8!¥ŸO—×ü?ƤhÄ«‚¥@çñïSÃnŸh(³æ–Ròv÷íß5Ÿ/CJé ‘mm›Y±ÐUk˜v6ÕrGLÆ:{v­ƒn¦5*KŸ,ã€=;ý¥W¿µ!ùÆw®çoB½¿ÏjÊTô¸íÙð¢H]”†`«œŽÙçúÖ••›Ig¨°Ë~í*ÜŽ¾ÞßΪF¥‘†ásµ€=úø­ë;t[ÙYCmQÈãž?ϯåXÒ‡<­ä &£¬·MŒ aN7| Ÿñ¬™ ¬áY‘»0ùr9=¸ê?ƺO[¢ÜÞ!ÂaÕ@ 2>Qï×?Ò°a™Aä~¼ß“Ï¥*«–v"^Eý q$™à7wœúcëŽkÑt-n|®8wµ¬q© ´Ê3\G…íÄ“6GÊŽ1““ÀÆz÷ük×ühaðFª|ÖG—P³„3.íß½8Ï­~ïÁ”—Ô)ÉõæüÚ>K2©ËQßÈú½ß@ñU•Ç‚u–Á¸C:¨‹r($€r=Á÷â¾*ý£< iàiºm‹Åå¸!•›w¨\äzWÒR_É¥~Óú)÷¦ÒÀRGß9ÿÙzû~~ ûaêûã$‘nÈHdèCf8ÇSôþuù5,ö»]-ù\ý8ÔáJmòdp:„N¿ àrÙß0 qƒÆïNد?šEò²¿ÂÀ6G ýx¯Bñy? tx”„srrBœç.Fq×®kÏß ‡åÚK<õã#¥|–¿y¾ìñ³ö§Ä“–vp9Á÷JúÃá+Hÿü(„¡_’SÆ?圠c¿q_(ec£ ³€6ž2GׯJúÛá’ù_¼Ýj³sœ Kúõâ¿Xà÷ú­ÿ/þ܅ͭ좟ÑŸRþÍòyß,%$¨ 8Îl?Ðרü@i•þ"mýà·øL!õÛtzöÏãÒ¼›öcžÕücm#Hÿj .ÕÛrsì?JôË©ÍÆ§ñj0¤›YY–'’ÆÞvÁÉãǧZú®%66ÿÝ_›9rdÔ%ëþF—Â]Iì<iÈÓ~A"œ`æK™3ôÿV?/Ï;ØtMoÂD|·:gµ9ÐÁß§æ•düO•´íCŬ®ŠÖŸ ™PÀfšðt<`ñÏ+æ”=é>ÿäÿÌúMÚþ»4O3Ÿ÷!Û‚ï.@;XÛYí÷<=+òÖù„ºÌ(dûpn8ín:õúeâZ6ðgÃx÷(¸±ød÷ökxÀöê‡ÿ¯_™×ãìÚôJÜz޾þœú«ÀÍ×,(¯7úNI%Ðû·ö]¾{„—~°, lQÏà?JùÅw+>©©:„,e‘·}Xœò3þM})ðKV ¥N~Ï#d»ŸÇÿ×_/ëÒy“ÎGbÎzãúWèYç¹€§æ¿Cäh+V~¿Ö‡|a… ÝqÈíõþµšÍå¹À#%Oæ8ôç¥hÞ³$¥@f|ðGSõ'¾+93…PH¹ÿ8õï_‡KsêÆàóޏÝ)É! »ŒöcÇמ¾´"|®B ÎIç“Å9wE×+ÆW+Žÿ‡½HǰL¡V8ÆTäóëJ 92)Ôî\cò£pÚ ÜÈr ^SÓëùÓÎÚÛ2sžz{p=Oòæ€öEÞ …ätãbK€‘‚¤œàîÎO¶HÿçUd”¢©FÝ´’ý{žõrSå ¸q÷W$wÏ­V˜¨U“pë°çœ~´–÷%#|0ÆH<õϯ:qDð¤L$Ü Âç ÁéÅK*Ç”*’`Œ“ž¾¿•9 ‘­ŸÌÂàÉëßëTb*<°<ð{c=zU·¹V‹œ³Èaü稨P ‡'†ÉúôãÒ€.y›—wÍÜ»N°ýJ…Y'Pí$¹>‡åM¸e’8ÙIFvþ<‰#˜¯Ê«·ý¡“ü¨ £;XŽª¹ÿ?"’AeÞ7qÓ§^ô«Ì¹UÂÊž??ÏÓ¨Œ’’l qÉ8¯rQí±²a'ÌÇÉÎãÈç±èGN´Õ!ŽÖÉÊîR½€ôöëÇz †`~ñ÷8çßðGè;çׯ¹üý« -.‹ÛA˜Žg0¨Ê°ÏŽ9ÆzþTÌ$K’…9럧§zsd29^¸ëþù-„M¸¡Ý÷¾lšÊI%aÛ¹ €!°HCd`~|ú~U¨—z¸”Éî?°P¡ÀÂç‘À·¿ÿª£ßòì¨z¶uÿ8¬\“LÔ±Óݼ„”X«08Ýžçõý*ëi ¢îlù*>ž»ÕŸBM–ãó/®8>½?ÎjÔëX‡É$ Î:ãñý ~Á•'OIEô_‰äΔ̗±*ù¦2XàmÈ?\¥(Ò×;‹q²E=;Uù‘ƒ98$r¼/l~Cô¤dfY®#¯ùë]’©5¹JœB€ÓcÁ+!v-Ÿ÷{Ò‹bJ{°ÜO×Ú®¸>XV%þ^€tõ?¯Oj’HLà’ÙB6’Gn0k•ÖwÜÚ4ãØ£ýœœ–ÊûƒÔ‡4Õ±U—¦äè”°ëøõþµ pÑŒÆÛ‚Þ½Å5 n*I`ŽxÓŠÍάVÿˆ(¤ôÓ̧šX»–ÏÌ1ÛÛ5ÕxOÿ‹µ´Í¸¿•YãMáK`FOÔV ‚IsÈÉϧ5Ý|ñE·ƒ¼ue©Ï)Q³6SŒñßõ5óÙÌeSRË™¨¶—´ìzYrŠÅSçvMëènü0øC¯üDñziº…ž£¦iv³F5¹íÚ%·ˆ0 ó6à ‘ô5öïÀßxáN¯¬xOÃúÌ+7Î÷¹]ò™f'Ôö¯Š¾!~ÐZåÌÚ¦›©O¥þàè<œ‚1¹æ¯!Mnu¹y¼óç¹ ¶@$àuÿëÿJüc7á,ULL£:Š1Ir¤º´›oçu¹÷³¼&Ÿ³„y¯ñ7ÚýýÔï|_D‚6)O.À >rÂIý§¥|ÃñGâ2kz–¡+–·k¸ØóeQÈüü«ç?ã¿o3$—òJV1² €íîj¥çdÕ ”–’Y ‚w{sþMo”ðܰ1^×™­|ïYZŸºwþ(ñe­ýϘТƒreؘ<Jýk˜ó4ëØà]1²3aFH“,"k›¾ÕRæeRæeãӟƪµÉ\.á•u7$ŒdsØqõÅ}OÔœn“ü{ L_<®mj6L“42eWíDg'o#©#×úU1¥´³tbt¸áø¬Èõ.Ý÷0!ƒ°lòyúÔñê¢RÀäL ã‘òc<þU¢„âýÖqT«NZ4W{¸vd& 6ô屟oóíX¶¶2I}芊Žp‡pκ¸­^ËLÖ4é#Ý-½Õ¬lc;”àúdöÿ=|Ü- ÆR”•¬ŸÞ+o®§ã„W÷JÜMÈ=?v;çF䑈A€Hè[uþ7€-Ýë” À8ï„Æ1c\xvFFb\ç|Ã÷ô­qâ¿%æÿ3 êΗÁÀºÜ:É´1ç‘×3^Ùà‹O·xVÑ’ók¶ÊC®G )ú€F¥ycš€+ò•P§Ž¼äæ½çá•‹DУÀÛ'ˆ#  vX&b}ø¯è.‚ŽYEù?ý)Ÿ™ßÚËåùŸ‹íäÿ†§ð˜V“JB—mÁãC×ô¯œ?imEuŽ:àNøŸÊ䜒3×?‡Oç_PøÆÝö¤ðÝÔsÖš¿Zâ£)V„±ÁÆãéúæºÏN%±Ó‘¸žGLŒcù×$fDP³y õéÎ}8ìkçh|/Õžnq+âb»F?’$G%ÛpÀ$cpýGãîzWמUO> Îò=ÍÄœŽ`Ið!ÈÅ|’¬¥ITݑԓÈíü«ê/ Þ~|;·!ˆš É)|³lú’\}+õÎñUŸ÷Wæ|.ogæ}û7±ƒÅ ì»6C9Ààª|>¿Ï5êq8,øë¹]—û:ÆÕv¶Ÿ±chÇ_þËã?³Äù¾Ôd.I[y#9 .#¿&»­_ÄBsâõÖï-nµÝ/N`?À¨@ë×{dþ?eľ-?%ù˜dêП©ƒñÄBÊÏãÛ»ü–¾ÑtÅ ~é–8ÿ7Onõ±û@^Ga?Ä2ÌbTøych¥Ønî®S<ž9nžõÇ|mY[Døþ»÷,×^µÁ^˜Šß?Ëü*ÿí=vÏĵˆâC£h–¼ o²Tõê÷þ†¾Y«\úN—þºÞ*’v¶ cÊ´øKn„³ga1Üg cØ3Ó;}«óÎøùž$*‘·Œwá{â¾ùñ=ñh|^wùmðÞÖ"Џÿ–wGݽú×Àº aâ¹ >üçÊ0?|¾tí*Qè¯ù‚V…ÿ­¦>jB/]Ä2¬"‘I'¨Ú9qøWên­<ÀÌÌpO'ñÿ=kÓ¼ ¬¬~š0d bðsÆÀ+Éï‹6õPÒFç€þ•}–{[ý‚‡šÿ#æiBÕdÚ9«ÆQ6IÛ˜“‘Î: }?OƳ¤š@=Ï¿Lfµn pÄîæ3÷ŽH=ýy¬¹K;žåùÌ‹& eBÄÇäŒ~Tͪ1àë¯n¿­8G‚«’ëŽÈã<:äqæÐµ¨Ç´ªÁUXœÅ;É•Ë Â6ãià‚p8ëßô©ÚUq‘ÇN?ýç5ˆ€B«mWà¸éïY¸2­­öJ¡ÿ»ÁpÀqóëB$ŽáHµ‰9¥ÈeF9 »8è)ˆ ÆåtíŸÏó¨öMêf×c¢Ð[XØç9Ï Àôþ•t”l¯(«—'ü÷ªú)²(ùØn<öíš¿"—LáÁ]ïéÓµ~µƒMa©EöG“'yئc –gáA'`'לž•“!—j(Æ?\w<ŸÈTó «—lå³»üŠV€K]Ûð9»‚yô÷ý*ªEõ5‹MjˆZä(!ùú~•OˆaJ±È;{ð8¸Å*Ä@Àn Øõõ—z–E,©µ°~`©Çá\ROál×­‘TF%bî>ªr¿OÖ¢8ù€ÚIä¨õÇã«ä3a$ä@\œàñ×öIT{c±ü« Å=®_3Ùw±óÇÍå’ÃIÇR>¹ÅAæ¢ïvUSƒœdc§?çÞ”e™ƒn`äöãÓò¥“;ÉŒƒ€NíÜõýéí\¸ªq®•ú;‰9 YÉ´”<ü¬GÉ>ÔØë¸à±SÇðóŸð¦ïÝ#î :ž;ñÎ?_Ξ‘˜äU9vN?ëÞ¸±4ÕWi;2£Ù±ñ3ùX|«m)õÍNó*,˜çk(äõÅVÞØ‚eS[€3ÓçƒM2ª[²(-Ç@Ü€}??_?:r¤Úhë„ô)µî#P¸(2¸:Ÿ×§J…îä–iöçØ#<ÿŸÎ¡2–B† Á†FOòGZa¶epÅW¦Cd½úVØ5R´ý•8s;w·ærNJ:¶9ä!°ìÄä€çÿȧÈÀ¡9þ,ã‚~¾þôÑ`\<‹Ãg•Á¯úSŒI½I˜‚:¨CÇQþô±Êó)¤šŒíïò9½½?2"HQep£w'¯NqÇáSEÀ\yjx МóÏãR4º$.z’£éרSÖÚÙùTÎOÎ0GåZˇ±/øµcFþã?¬Âú&C,±¢€C’w!ÁÎ}ªX¤$Änœà0óW­•Æ—y9FC¨ºÑ¦¤ñ©ÁÆaýÅyÛîS9É^S`Gå]׎ˆµ 5Um^ã @Ã0üxEpG!c?/~Üü«ásÛüÎynv¿мw¡“ Ϧyà×Ñ_ íœé¾I:éåsŒ‹iOOO_¥|ùðô¨†ñBñíä psÇL׿ü8Õ ·ÿ„bYdŠÞ!®1ùäýLÏ=zq_¿ð´U<®£üÙñ“æ¯5ýlt¾.ºCûKèl„ï#ŒïœŽOÔþ•òći>.ø­Øe†§tyë1‡Ò¾·Ô4õ?‰–ž2¾×ôí2H¢ãOŸP¶è€ýçš:î'¯?ÕgÏëÞ/Õ5›ÏŠÞ±–öæ[‡³–úݼ²ÎXŒ¬¤œaÓµ~YœðÖcˆÌë⊄žÊ;Y-¯Àýæû†T÷âÓjÏOÂÇξ*™nZØÅ°:Å“òŸLå\癌mûªå‰Î8Ïjúžo ãý?âÖ”±ɶ™d'¿côõ¤—á_ìù¦Æ¦o]_é/'þ‚½?Zç¥Á¸Ä’u`¾rý x¸¼ç ^§´½ïe·e÷Ÿ0C*3…`Xœu8ãëôþuô¶ráøwi…/I»}ËØk•ïø:¹ªèŸ³íχþÁe{{£±¶ßǧ]ÈU»1_0ƒÛ¥déú¥œ7ú%•¬—7šu†’ðÇw-£Ûùŧ,H Óè é_¡pÎK,ž¥IÔ«s%µ÷OÌùÜv*8…X½;£èÙÒvœk 9©Âc$cÿf¨uíT%牖@Àꬡà°IæçòQøÓÿg˜Câ&Íû¨yGï\á±È¬¿ÉÉjò~ýŸâ¤mFÄYø=xÉÇóÅvçÍJª~_äudêÑ“óý¯ñ»W6šÅ`Ê’ CÅ:%¸iy ­´O‘ƒØ¨íMý 5}7ÅXqµ–ãD¶YñË4×>…¿ùáüY’MsJ×dèÉ'Ží•™WpeŽÊ@FAý8íU~-ÞËöÿˆð ¤º×ô˜‘ßœŽàwÆßó‘_'=·õ£>odTÕuñucñI˜¬bßÃÐY|ÙÃ&ß5|[¨/üUó•ù‚0@ùT×ÒÑÝ üf–@¡št„r2FùúŽžžÕóf¤¾_Šï0¡XGÕ‰À¼‘Ú¾O8IÊ›þ·d»¥c·Ñµi¢>TmòÈRÀñòô<ÿŸåÇÈØ…~`ÊW¦µíætÒ§PX¦mc'óÅbJB’vËó GáÜÿŸjö3šÜØZ ÈñiA{I4djm¾T 0¼'AÆ ¬¹ 2£·Aׯ\ÿ*Ò¹&F~ÃvI+“ôÎ=GùëT~É3HZ8ÇAÆqùzüöZ½V;‘N€ÁÈéÒ„` ýÞ㜎ø«&ÚWeS <ÿyþxú%["òwW<¦î tŸãK•”5XɰÎÖéÏlþ4? Tc†Ú#¯çOžÝLcl"òw<Ž{çÒ•Ö0¾`E*JöÇNœÿŸz@'™ûÅÁ&@Â3“õïO0Ѱw;~ŸÏýj…Ä¢5€Á8<ñÎ3JòÈ Á `3@ÇLÿž´%Ê&å$í›¶xçùÓ•w€²WŒžþßç5O.2dÀÇd1Ûÿ¯H¯$Ãå(7Q’Ï¥ &hàx”#lê2ün>£ÛøTKo°¶ìã?/ðŽý½i@¯¹œãdŽ¿þºÁp¸ÜXƒ‘ÜP“J¹BP£‹ƒ‘Í5d(m¶{» Ó'cæíå8!9Çù⑆òJHö7~¦€:Ál!<ÄK m#'æíß ¨…»ÃHÀŒúIÿ9­#jÑ¡$(8°y$ÿ<ÔS:A¹~]»Jž:ý?Ïý-*ž\ó/w{•üµ. AÀ#î¸ÎLóœu¦M”1#Ÿ»ò‘ÓõúÕôGu Sò©ã9ä~Ÿ¥+3pÚJ˜·¿õÿõ×òœ_zTcç¥VœWºÊqB6.ì«’„sëþ}i§>žÕ!†A.\í@~T'Ï·§½y3áìî¡oFkõÉÇK™iup8R7ð>¼}iíåÇ>%y g'Ó?ç½iÜHÆÌõ2x?ãQÜÆ›³…T?(;÷¤Ûjm~?ä_ך~ò¹µ¡Û•Ӣ°dŒð?úüÿœTާ{•U+Ðã·=ÿ/Ò®èðo±Ÿ{(Æ}©^ß ‡hþé#§¯ã^µ:^Ê”bì’3Jòr2Úò«4e»œÒìËlUe$`2óƒV$Ž868—*ÊŒc©ã(…¬$º:~­`ôÐ范Z"±†$ÈäŽtúT&òÃrJò¬«íüëE†ùT°ÚFÒpÎj7#,HÞ¼ñ»¿@}+–M>ƒQMêf˜¶«´¸‚ÁÔ}2=*7·PûpU í“ÿ­Zb2nŠ cõÓùSE»b""ØÈ>êœqמx¨I7ÌÞ£åIìPxͪ/ï2™ÆöôÇ=;UèˆL8f `sÐþXþ•»å«OËØsžõ«DЈ•ƒù¯– 6sÇãî?°vVZhc"¬ €$uõ… äñÉló×ü©ÒÊ|ÄUˆTÝ¿§7îÔ†R†Bg$1Íe9ÆÍ>ÆJ6ÁÒS¿r‘–Þü>ƒõ¦’IØcppOš–[e± Œ€W3Ÿè*4ÙŠU2 ulc8ôâ¹'+«£dÜ6ýß  “ƒÈäžÔÉUR‘ @ŠG$tîj]Þföbvñ‚Hþ_§ãMÊÈå ©`GßžkÍ”!UZý‡ÔÌŽ Ϊ$ÝŽYØ‚O|géüê $8Q`sÁ5rÅWÌPçnÏ•q“ßç¥Bñù’È¡|Â[$gõÏ­k“ÂQ©ÍoëúùVjÚƒ+veƒ |Ç8Ç?HI 18=ð}éªäd–*z tö«p>s¸ªä“ŸÏñ¯½Šj6{~'œÓ¾¨HÝ6ŽsÛ5!ùB·“—œlñKoI³ËE]Ç'r=*x¾‚Î3ƒŸñÿ<×l”51m'¡~Ö=S™rT"(;F,Ïùõ¬û3ŒóHcœóøúûVÔ¶¡|%ªñå¸0Ž™ÀÞ;ÿõ«ÅÕ#‰ÎážiÏþµñ\GM¬U¯åýYè`Ó²ê}àÛ7¾ø9 FáüÝVÉYIã|MϨéÒ¸nÑ"ñ„Hré?‹î0Sž“0ëøôïÍužñ¦‹aðû@Ñ®gd™u;K™b;›BïÜŽH<ŸÂ¹-c]K¯é «†ñEýÉ8)…3©ÈÏSþ¥kQÅÁ;ë§Sè+EÆ«[QâøMÆ‚nB’]RrÊsËóßüó\!L’Þ¸xäã§Nÿª»]4k;SS$ÒÝû,=OÄbRA[$g9þ¢¿<Ì×ûC±Ï%fw^ê\G"‡(°è3Ÿçï]½î5}"òiôå¸óÓÎÜ®$®r¤d`‘Zò½ÄWZDG¢Ê€rÝ@Ïó«2xßP2墊% íN¸'êÏú~UÄÙ^.¥‡«'Íf¹_¸ù¬F µZÎqZ3¬Ã"¨‘,-ʿˇ-‘Ÿ\“é[6–Ö–Š‘Åg¦)O»ºÂ}~bW-ÐŽMyŒ^/ÔËÂHÆNX…ÏPA‘¦ÉâW37™¨àœç$uÍvGŒ2šjÐOÿ1y~#fÿÖRõL»¢ŽÊ8Ú`³Š3‘Ïð¯%lj5p?Òå rªQ¸ÆŸ­cZiÑÉ lK®U‰÷Óš¼Æ¼¥N„)ËN_Ôá…4¥)49õ ¦%r<àp@'òâªÉ;I(i dü§ä}=úõ¢æ/,íów&3÷±Û¸õÇÒ7"4@îÆãÏ ×®}|ó”žìè^@Û€XmÆÝ§‘ùÜS<ÂXŒ¨À;yÿ?áNR"B³ dw½?ýu `®FA#?.psZ‘’+MÄ6ÞçÝéþ}©_-É*áOüñO’2Î>bÃ78öæšw $‚FNääðsŸQß BÁ× ¹_qÆÐÍéÅXr²¸ Ô.Þ››AO™BÉ@!˜Î21ŽƇ·òeŽ5U‘»hàç?çÐŽ6È€ýÐ3žçÖ‘XÀüÆ£¼ƒLzsýh™]eD‘·d•ùˆúŸñô«LÊ G’,Gœa9z}h„ª<‘¹€Û‘O'ׯ?äÓÖ6 €ÛJ¨8þ÷=½ƇRd@äq×!}Nzú©é"«mpY›9ÁQß¿4Ì;UG;‰ÎJõ?Òœc†±ãréÿ…:äï¢@Þ žzzš’I£…Ê ®;&p?.(­3sÔPŽF?_J|nÄ(Üܱç¯øµQÖU;Xå?ºÀ`{fŸ ¬®ÕÚ¤ê3þs_½lзR>§;Ý2xcµcÃöâëM…ð™P3ÜÏùÅ3QkkFW.çªxÆ=x?áËç%w©ÙNpjïDg›PhÚFb>æy9ÿ?äSV2É”’~B¹ãüâ¯#$¶ìá] Œ„<ãäš©£abÜd$}åê8Ò¸9JêÛ µ8%n¤©nH`Û·g¡à{cñ¤hiTî,{÷éSÍ(¶_>`ûJîS´9'ôý¤vwQÞFŸ»b€í!@ÊôÈ®WwlyÒ’‹{•ZXÉbK¿tç®:cö4Ö`‘®NÐIàƒ\ûöõ©uY–ÑAòÎsÙÉÆ=ê“É+²±f@އŸçŽŸŽ+95º‰è.h¹¨'¨ì¤r«R¸$G$ÿJÉÕægšÚU¹T»yè=?ÏÑnu# NϹÆqÓ¾>Ý>ŸJ¥yqûèv¾)Û“÷ºŽÞÞµÎù¦Šœ—ÂRP7(…R¤Î)p oÌŠ0XvÉ¥+‘» ¹°£oϵ\?Æ¡œ#ÄZO½´1Ó=ÇÒ¸b—5žƒzêSµÞfÀBS«nõõ÷þUÆÌÍÝÄ1'Î?.+B[38ÜŒ!FíïÿëíÚ³º67f;xïœõ¯¢Ê¡kxj­¿Ür×VЏä\±$|çqëNd!ÛÎ0TÏ55²o vçN;}*ÁÝÌ«åƒÓß?ýoé_u qšó<·;ir8@òÜÄäpWùõëSYäÈQIÏlíž:cÜ~u$Q‰>P:dŽp3ÿê‘#hæ]¥|ÀFàǧø¥ìÜ1””•Í»¨L^ Ö$Ë8KˆW ôùút¥sºj.Á½†<ž{ž¼WQ~¸øu©Ïq>¥y$uç+šÒ_ÌJòI»qߟË>õð|J¹ñÔc{{Ÿ«=Lµ§nÿä}]à2+¯Ld‰Aq§Æ²8Ë6fˆÜÓÚ²5í&8¼e¦ÍÛüj®ð†{ÝjßOÈÒ]\Ûdâ‰w7?‰‡¥|†?ZµkÓŽ‡‹zžo¹âRà¹è`_ñâ’B7Øêqòíǯç"½gIø5>¥¦\Ý©,L7ÀǰûO½X¿ø8–P³q:…­¨É fX|ÏÇ×éô®”âž®$¨ßvxâ/Ëò—ÿ‡ùæša*Ķv’1…߇ùô¯Y´øFn`ÓåB]ÄBÄç÷1ïçÓ'#Ÿz~§ð†K >Öy},j¹$c#dòœJWH®CÉŒ{Cx(ëÀÎ}ǧ­>X÷>á<òp2?úëÓ5†¾V¥«Eå€-d´hÝÇšŒgÞº á,Z·‡-îU“ç×&±UÉÈUŸ#éÖ®9N"sqµ‡É¥îx¯Ù%2d#Žr¿)ú]ÏÃ?„úŽtý~ú)RÔh–m¨É±’_a_”vÉ"»ù>Å„ô½Gg˜fÒîîÙTóû²¤~@šô=O³ðnƒñû6/#°V;‹–hãf<ç{'¿> W©ƒÉ}þjÚ¥þFråV=$H¼9ñÄF»N£¦@‘¢˜XíIÔg9ãùת\֭ت—â)|ÁÄnù<õúc§ZélµU–߯ñ;‚__Š$㡎8sÐuk„Ö¯;í6f“y.¾ºýÖÛ.íÏCì+ìïîÜç¾¶7t{÷[ÏbË=þµrÇ9U?hsÓÇõí^u:Çá½)K¢È4k‚yÉù˜ƒ‘ÛãéŠô=U•,<"4……¾«1Ý×&u88=x==¹ÅyV¹sv0@Ì~M!­1ïž:þ•ãã&Ô9—oò7‚±³©3iädí]*Þ´zä ñ¶e—T™Ë‚Y3œ¿ã^«\âÒhÕYž;{xùyéÒ¼¾×"þâIPTçk@ÿ#‘õ¯‹ÅOžq ªÖ4nØ¥¤± b¥8!Ž3þ{÷¬ËG f\.àHÀÏõ«WLÂÉÕ•w`£sÔç·ç5Q˜m”§q, m¸ü:ŸÏŠŠÓråòG"V¹Rá•NCc#﨓ÏCÖ (JÈU¸Æ:ôëÏáSÜnòÃ1<óƒŒØŒcŠŠ 鄯$.ÞàúõÂ÷,II (s€q×ÔÔ*WnÖVì[éþy§±sb F<ŽFHúÔI¹ÀPW ÆOAïÍ ,;™"(ª# ÀÓ¯áîi… —f}ÅN3Žßä ~K³q,pO\ôÏ׃LóÄcé׿ÉÜÜ I 21bÍ…RÄç?Lç¨ÿ˜¨ÜÐ °ä3þ?Oʧº-æn;‹°à¹éÓŠ[}þ[”­Ž:ÿ/C@µ'å ÇNIo_ÿPªy¬äåÇÕ…]|ù‘HÛNW²ãŸÓÔÓcÊ”SÐùkþÓ‡%K˜éøôãØA#àçÚˆ—äUÖÉg·÷æ¦*Ä|û‰è8 uãõ¯ØžRw:¡Š‚Ýä.i$OoÀ |q’üª’OcÐôéSAÈTñŒÃצGùý1S¬gy%°’ géÛµ/ªÔètÃE¯{B?³“†ØÊ eNáBîó I @d{Õ¸£.®¡ŽTr„µ8Ú±fÚYzÔñïÏN´<5D¶;a‰Ã=9¿ø6ž$`ÌxÏ߯қå¼'fTœžqþ­i¢ѣ¢U(µntÑÝxR_+O†Lj6€AŽÝ8¬}RèM¨LÛG’=çƒÇò?‘«×{ìK³'ȧ+ÔŒcÕ;Ãò_ZI$˜ÉùÇäŽ=@ÿú¬D½œã»VùŸœÁ:“•.š²76öÚõ Ü%”d0 N ÷ÿ8«"XO–›Ô/|Ԍ©LLr¸ #óÝxõnTŸäSŽ·cåA†ÏÍ“Ÿ¥U¹; % ³nÒ0Ýjs‰#>Yé’T¯qÒ›rvò£ 1ÿ?¥yRjÍ¥®¡¶ÛX#•p_)UÉãñªP·™+‚²OÊy=z“Z:NÄJxf§ëTl%X‚Äð9Çä÷ô¯©É"ÜSõ8±>ìIìÔ¡WÁ9ǺƒëVbbÜ1R©•*O§áüùÅ26º© ‚qÉ펾þ”õˆ³‡êÍ…l÷ô¯¾…£«G-KJ£Ù‘¾n}:’ #2±ã'c·ò "ö–\‚ü?Çó§[ È¡Tgn3ÇÓù~~õm¦sµÐÐׯÃù\¨$ßB€63’zzkŸðí³;P08úr;zq]'‰Óo€Ô¤Ôbàä<¹}ex~2!‹i`’6Œùºõ÷5ùÞ{OŸ4¦¿¹ú³ßÊ×»¯sìo'‘ám&}bsÒåG=>^µKR³‹QÑç¹Ón•­N¹èœã×=~¸ïU¼7§w‡!†f‚Ñu^ªNL«jäŸçùbÍ ë³ø*;Ÿí !Gðýäû"•Æ@@\Ç]Øý+ž2|«KŸIŠþ,¬XÕ¼7xŒÆ»™F«¤ÛÏ8ͨ$:ç#ôÅwÒ`âv‰½ŠÉ6½â +ëùW–ê^× ürj_´oéІi_‚mFÉç qž¿/µjx3FÖb×|55Æ»rneºÖÙg2;•b;ߨëÆyÉæ´sÊq¥¡é¾Ñí_÷€K„ ²`ÅòNóqÈã©÷÷«zΑa&½r ˆËø¢Â0@ ij$ñßõ®ÃÞÕ¤Ðe”kS†´– 7#f”y|7>žŸ0â¯MáؼP‘\êÒÜâ›x›9çïVÆîp>Zjr×ݸÿ Mi?†¼'w,¨[/\³™:ÁÿqבŠè¾ù®>؉>Ѱ®U2N}ÇSüøúWˆÜœ®ÎzÊÎÅ–—ˆÚyÎŒ}ȨC’ÔaǯùúT³ü¶î»²Ç$`(Î9ü*²²;¨Œô*@éì;uþ¨“z3žÄ€@›*@±ÇNüô¦¹ËÊÄ{ýAÇÖœÌCîÎ :cÒ¢¹!|°Jí'#¿N3ôk!ƒ³"|Îì­O\óþ9éÿÖ¨•¶œï ã¨GOóÞ§iË!‚÷è1“úóÛëUËeðs‘Ç__Ät   F *žß\ã¸ÿlœG´à€q‚qÛÿžþ´“*ùQ¨ yÉÿ9þB6ñÏ;¸ ƒ×‘éùPêŠ&F—(#ÀÇÿZ˜WTSçŒ6}ô¨î¬ƒçáO˸“ž¤RnéÈìþg§ÿª€$¹uSFÛHÎî äqþ:b³;ˆ `OR9 Y˜*¨#PsÆ?Î?*CI™;g€#@½UiþVÂŒ‚Hÿ<Ò,’À 0êØb çÓñ¦È»åL£n:p1Ÿ¯—õ¡÷:«’]9È'®qŸj{G ž~RG<ã<þuPÄÙᇪàжã÷HJœócöúúú®å‰Y1ýÝÄãô ï{JåœrxÇl}?*‘"ù°2Èz*ç¨íü¿*h…cŒ£o¹ž­Øä~5:ª2ä»(í³šýò-Iœ‘ºwlz*—H%¸?ýzº‚Ä``'ŸÂ‹xwüÍåã…r1S$"4tÝ‘žøÏ^ßç´­¢A­Ú$Ž-ê 7˜Ø?6ݤúqþzT° £âFÝ»Ÿ8÷÷¢Ùó2 bHÚÈïŽjí²)FÊä‘–>ß_\âŽRí~¤{%B@\0Q¸)ý•Dñçwñ|߉õ­( BNWo®zCøÖ^¼>ÅbÅI?ÊnNAÿ9ö¥Q%½‚öGO}v·óÇpøX(,Þ98ãu®ÒÞÊ8l-žå Áêkm âÚÂ9ÝXÆŒ ^Fﻀ~†º«MFá–?1F@AÇnýë:Î3ã´t_=Ï&šp—½Ôá®ãŠ]jYä*±£òXãÓž¾õÖøžæ _9ƒ˜åù¼GùïíX:f†ú휒Yò~SÑ}úñÎj»^>¨mt×bJI¹£ð=xþ~ƱŸ,¤þéšÁÊrÞ侎+KØà‘Áža¸§ëéÇøUÆRØGSÓ¯ÿ_Ÿj«­X&ƒukwµ°ê È\cüàúSl­I<’4 À`à6¯ã\5jB­«IÙ–ÇT#:w¥¾¦—†žàžÒ ©l32qüë›ñÁ¼¾(ÊX’î00xÿìÕvDðþ°³Ú¡KÆy¸3ZÒ6Z´Î»e˜y®Iç'œý9ÿã•HÆ*²K™ôóîj©ÎþǧrOÝG©èñí\INÑÀÇׯëÞ¹/Û-ž¬¥@SååŠ.:’2p+bÃí>ñEËCm/u$sÔzžyæ¹MkR:ô“C¹c$€q×Ð÷÷¥QEErï×Ôªr”W$»™a JØÈRNHà?—AVVdˆ @åHPž•’¥€;‰c´cîóǧ5%¼ *©–ÉëÛ¯ô®IE½QºV¸Á™¦6à1´‚¼{{š‡ æî –añü—¹«¢T%@SÐóúQÎBð:á½zûcœ×=HIA±¦´H¦ÅÔ¥Tdãjàž9ɦߎÕ×n…?Ý9ü»ÔóPpIdî=@ëU¯cÌr1ùBcvH>½Î+Í“¼e}ìÿ"ni̤(Œ ï¿ç5nÙYh$ŒÎ~Ÿ¥kéJ²Z^ºà±EE#©=»uÖLv×*0!*í,üñéþ}ë벉:Tù[ôWêrb/+E­ä"dórGNsœûÿ_J“í?:+0€ •äœsúö¨—M¿”¶¥ß@8öϵ:ÛHÔ›#Élç<‚vûç:WÐýyËÝTäþG±›eÕº A@à†ƒÇçKo2ÍrùdsÀ #éPGáÍFiUÁˆp€>Þ½ië ß“¸Ü@bÛ€êyïÏåùVrÆV½Õ_åþcX9nͯ²§ƒàŒ’ÛPüÃŒùoÇ_Ö²|<‹$qm}èÄÅ@`ó^´ÍOIÔÍ£Fó%Ä(C–PFìcw^¼ŸÎ¬øj)êÖ »1M¾¤ç9¯˜Ì'V¾>5¥MÅ(Û_^èõ0T5Ë.çÖ¦ÊéQWHüA32Ú,œtúÕÛRá´H\ SÂÓ¹|ã'ÝNMs> ¹‡û_LYŽÙÿµïX¨<çìø5¹¥À'ð]ç”7<^„PãçWÎqÏðÖtÖšÞ#ø’¹/ˆmcSRÁÿ n›å€Ü|¶€ôÏ$dôõü6Ÿ2èÞ¿BЦ×_º ÷Ï1’3Ç'§õúWE«ÀwE(Œ®<]jÁœò‹P=zçwé\}¬…|¢E¸¤Q蚬§c e–@Á<¤tíõ­»Ó±Ëu¹ÞY^nÒ‚ƒ‰?±<=nÇÄóH½?ŸÆ¶oXÝx®Õ™ø¡]@ìFœçõé\¥Œ˜Ó IFؼ7 *I0—pÛ©Ñé·±ÄìAFñ$ÿ0É$‹½ÿÎ(æi._ëQò]Ý'ƒÙæð¦—"7_k-•C€^WžíÏNÿen~Ñ ÇHh´? Û™0FÚóÈ>½à´·…4;‚™Úž ¸PªbZêp§èIþU¿¡¹ê¹w@±øR›³Œ(Ÿ8b[嵸SÉÏ^˜÷íÔx”ÑÛÄ»~iŸÁwlÅqÑžQ8=1׹氜ôºþ¶&ÎZŠ]à½F(ÀO†lW»  îëÏ^¿Ëšáþ%ÃúôÒuË¿>HÐnÏ·Zݺ»òô_yNX®“¤AµøÆ3ú1þ¼V7.MƳ3“‚Þ!·æl®Vç¶C/\ñΪJë_隨½ö*é—arNß¹÷q“Ž£ò«ªY~gf'·§ÿ<Õ-Ë,žj±îX¯VV?.G|gÞ­˜Ü± å¸ÀGæ~œQ¸qó¸ÛÉ?Ì÷ÿ²"# ¸©;™ëž‡ëZ§d\SZ¡ª‡xÂrA:sY¬ûËæ«7¯ôÿ´øÐ0Ã=H'Ÿ_BJ!ÚbÜ06z_Æ¢jñÔ§w{¯{cþ˜Öó!•[ S nG9Ÿù5›¨øfÒæÔÚŲÚ59cà‘Çg'¿~ÕÐÆÁænçŽÿ©ïUg»-Ѹúóë^KŸ*9cNíÜÊ´Ó °‡m²¡Æ>öwr9<ÿZɰðä:l:¨iXýý¾½ÿ\ªúã×ÿ¯\%tÒêwFÕ•oô¨µ6YQdHØFJœu•“fÉoAO›9ïþ{T†*½[n×'=z‘YI驼tw0Æ hÔÈ2Tºùzu§íVm™ð>œtÿ=kI£ `™ ƒÇ=½:Ô7+²0¹8ᛌŒ{ÞŸZÍè;·©›{hna‘FŒ°ÚYXƒÓø^k¯ÚEcx¶ñ¡P’yÆzW©¸U! ‘¨fÛÁö wëü«ÏSǿ֟lÖ±î$PÊvá¹ô§ÿ®®[^Øéá&xšU.ø^Ü ¿©«äPvlËš1z™#,ƒ†VGL󟧧ùÍA(‘$%T„wÏ^ƒ<þMtº…•´WD2¨‡ÜOžùã·ëX÷ñ£G(T99#i$ã=ùô®J´½ÞKîRÞìĸÚO J¢J9>ÞÇT7cËI6ç$¸rqõíNÈ (Án9÷ÿ=ªX r‡YK GÛq”o›ç~Äã?€Å7ìQÂH⌖<ñéë^[ÅâãjQ÷W«5tú²£ÜLf´ŽýïzöïÇP.ÌÆòÑœ0ÜxëÓòÅh}–ãhÁ'°G@™¡mÃFå~ìcææZJ¾:?iýì9"g%H.¡:m8Ç9üñS¥Ã+’ çÓ9üY&ѸªƒÐc¶)#„åîYX玘éïIcñqošß‰J:Èé)DÝó*‚['ñïÿêü+w·h5û4I“Py>ƒ•d FB¢1´§ƒÁçÿ¯øWyàâ×RÒµ‘å¤K{sónù˜`c¦#5цÆc+Õ6“[õÛð4‚I§Øöß i÷šŸ‹ôiì­e¹ßu¨Ì¯nÎaL€qéø×C¤NÁºJU%O i±˜‹{ÍÏ~ xJ|Dñ&ªé_ÙÚ½ÌÜ[Hû¸<ÌË#t?1¨çéÇ­Í~ßÙ~,H”ù±[hÑ qÇ2ôàä÷þUô´êFo“±ÑQ¹IÎ]YÔ·—qghC«â¨ßÄò°cò=q^urÞOƒ¬ÕÜ"§†ÆÁÛ|“N¤ŸóŽþõßégF€+I—ñ$òn;B‰žøãÿךóíz$ƒÀK#¯Îž²ÆÞ2Æíó׎üëI;lak< ¶‘¡xpòë…61b¿ºWÆxîõø®‡D»[ŸØ+™µ­YгîÆÃ³RsŸ^O¡®FMɬFƒbŸøItoº:âÔê+[Jš(§ DVrA5C’?à?¦3Ågk‘¦_5&œ@Ë›ìžyû¿‘‘áÛéþÝ:Ë/ÊÞ(²êFFÔ”ŽF(úœV•‰Z$GÐôW$5Ãkú„˜/‚[O©<^Wu)´Óí„{f/á #óAÛœÊù99Î=?ÙãÒøgT3GáY8~¥q»“Ë÷:öíéÒ¸Ï^Eob¨ÿ,«áˆS#î®ë¾£“úþ<’wõØÙ«´iê7;âñ vn‡EP§ÝŒ‘ÏAôíY~#¸íʾàuíùu•B1ÏqŠŠ{Ýš†´€É¥E´ð[j® ¡«ºµßñ(þÛ™ÈbIãxüOùï^}Yò¿Ÿê;jdi׌º†›!—c‰.¤ëž Õ+ë§]¤{O{©vàŒãðªör·Ú¬D,±Ÿ*CÇ^sÛ¦i/JÛÆ\ >À8ÏôüÏÓÄGûÝà 5c;R‘¤GKbÆFIè>¿§½Grì%”wyˆ9àž”Û¹6K( Ä(ŒŒþüö¦ÈÌeb¤‚d Ý?Ç5ä9>f‰{XÏÕ7E£pÜ®ÌóòõÇ×ÿ­\Ê){vÛ»ŽràœóÓô•tzšº$»™²ÛùÏük›²L[0R˃ó>ž¿‡=¨…ÝÎ:¯Ur;çbÑî$À¯ãøTjKĬUΞßç½Kt˜‘ 2±á”täŸÇüûUuÚÒÛ[088õúö£sv†%Ìm3—ddóëŸóøS(ATdè~´ˆg\†È'§ôÿ"‘>V\eœg¿à ®DXUàõÁäûúÓY˜Ê©'æ>*Aϵ°H$ã'#¦j8—3ä(þ%ÎzP²ž*’ªOñc}}¹¨×2J‘»^ÜÔ³Å}ÌØ=}pϽ68È(FBzèŽ~rv;b•cÛQ³ß`}üégR¬¬~S×<õÍ4²8^wv [ßüŠ|¬ €%GÌ3Æyãè)²©h×!€£7úñSÜiW ÃwÊW‚Húú»T0 ¶òs¸ìùŽŸ¥;€ò$ ór?ÒšX`0m¬ çúööö§Ü(QÂï#îÏJE*ü÷qŒ7_Cü…PŒß?xõ?×?…B°¬€3Jžª¥ZC!J€z‘Éär{tþµ²aŸ¦ZöûknM×S@äŽv³vr¤ÖŠhž¼Û³YIŒãߪWŸÛ¡y;#8ð¸÷ÿ=ête ½Ùd|¬Ã99þUúRÎkµÓñ=øåÔdÝ۹閾 ÑïÈ[]aIàñÙäu8öüêä_ îY·Aso$ŠÀà0ßéMw’7 €Hçüçô÷â RFI¤%IÉ^zô¬è..%v4¤'ŽLwëéXNVµÏ(Ö”lPkß79éŒ~'ùUvKH„?É\{qî?¡º%cæÆAÉöü:dóùnìT*Œ|Ű­bÕÍ4°…q·Œà{zÓLÞb©Yr!zþ~ÃüñMyÄ„Ìa²Ò1‚)Õ6Wkwœc“Éã¯éIó-L‘â\œ&êFcÇO¥Q’ÛË“±œä:ƒéÇòôüëAy;YT.x¯o_óÍR¹7Ú‡;yÚ¯ÿ_¥Ciõ¬îQ•A%†ÖÉù±ÆqþzW—xŒ§öíÁÀPøc9â½aãS´nxb ‘{‘ýkʵe×.dH2®8<ç·¥%~dEExØ« ‡,­&ÕúsØóÍI¨ÀP7VsÏ~GZ,c#åÞPŒžO¶F09&©“ ¸BFðÄð~n+]“îcd›W6µKr÷͵vìeå€?Üúç“\ö¤B‰TÌ /ÝéÏO×ô®›WP·<¨‰vàñÇ–{Ea5®$ƒrìÜ"ïÆÿúë97/wrÒ½Î{æv.XÉ•$@?_þ½Lšl’Ÿ/` ¤œ`sœþµÛi¾k‹:+Q#-¼ÌJÆXdsúWAa᨜˹CD·kfBùÇž{ÖÁ½Û×B’W±äñÛÏõÚYGsÓ—jՋ܃•U\°ädýk¿¹ÐâDMål&ã ÐnÇõ—m§+Ë2ˆÎrÜ(-ÛŸË—Õ£œµ-ŵ¡Ÿ¢FÖ3˱dUò[ ’ÇÓ±Å]¿ðÂmlØÞíA #ííÞº-ðIÂDmnôÝó tþ>¿lI`>É.Ä ¥u69A†àçëŠì§ÚÉ hyN¡á)m¬þÓ°œEíF ðQž†²/4›‹)Z6gVxÏl•#Øôÿëײ^Ú4–A¶°ò´øåûȈùåøÕ‹O ÅzL—æ??P”/ç!#`ç¹þ«Ž¶W¢×Qîq¾¾¬÷W—îÐý‘"¹ ²æ@:ç=ÿ­zï-#Äå#Q ©@Ã`#n-›²úÿJšP"Ñlã,gKÒc?é#=ÉNôxîø›ÚêË%ÛJK°Á+ \ñÓ}+¦P$ ½• –7m{B]¡ YÛAvêFoOþ·²Û¬²H7ª› A‚|ÕàÓ5å7 WÄþÊ"ÆÛ³99÷ãõéö· ñ¼äñ×úsR-Æ£CµŠØ¨8„‰A9úîªú&¦"Ò´Û!Þš^§2®ü(ÍÊõú'&¹å¾†é]hix‚M‹{ „oÚlo·¶/3ÐtÿëW/i2A©ËÂÆþ)ó*ã 8ÿ?ZÛñØ¾ÔØ£¦Ó¦'Êcþ“œøÿ:æíX-몳(>"ž]ŸÅ€ŸËÖ¹kO–OúêDn—©7ƒ¯d‡Fðó y 6š”„ê>oϨª>-+˜a 4+`ê£Öáp=úŠ«¢4pxjÂPÈž^“¨ŒÄ%±íêxö©5ãæXÊÀ‡Å•´{yýrž1øŽ9ä×ë'®ß¡v)ÝN"ñ-ò’H7ö1ÇÍ´9#ôÿõÔ3ºQÉ?o¸e*ÇŸñÇOÓ½S¼½2ëÌꪙ¾…•”` ¹ÃÿÕQµÌ†h·gcOpÙ88ÞsøÖ¼º•¯{»jiËÕ3&d–Õå!¶ä·8ÜOo˵:YHÂÇ쨼¯µTb ¡ùAźäƒ×ÓóN•ÚåIó »F‰·© tãóZñjw#uæW¹tìAÞ¹Œ3tà&9ü¿J‹ËÝpØ9fâç°à{ö5ÔèÞ“Y‘æšS ñ°*îb@Æpqë^ÛàŸ†6ñí–=/ÊE$ù’@X·‰Õáâ±ô°éónC—UÅ?uY/jÖÒCm+ÉVÏÌ#±ãÓµsP4Ÿfýë “‚ õé§>â¿Amü5kçA¿îËtŸò+•ñ¿ÂÍ/YÓ%Ý-¸ gdì\çFOùü+È¥ŸCšÎ›·{õx~V¿´×µ†ï¿wÈ`rÙ$òqƒPÛ7o*0ådŽüwëø`×[ãÿ Þ;ÛÜ ­úàç{‘Œíü«“ãËÙà óŽ1‘þ}+ééÕh)Ãf|•j3¡7NkT$æ UA<6¯ôüi`‰˜] Üž£ŒãüúÓž"±˜Ô“÷É!Gùþ”ÖSmÎ]äw8ãüûV¦#¤ Ί§88'þ˜ãüŠï†m¼ï<×ãúU™W1GµX˜0°àæ¢K_ºí´nÎÕ'“íõäP‹ù ¬o…”`# õ¿¨ª±²Úp¤²€Ol`/ò*ÅÄ;Á ʪ«ÎH=?™â£UvdÁ åðèp;Ó`-ÛØ Æw£ñ?Elò +·yŒƒ×¿õ§¼%çFçáK/éKö=±«®I9QÆqÓ©ã±(oW eçåÆ=rzûT0Æ]›KË€;ÕÙ,üé„·Œ¶O'8úþ}úÔQÚ$[ƒ’vŒ†#9ǯõ£p#”0a:ç¹ôô¨UƒŒs×é׿â*Û[®å%°G+»§¯~´5²ÆªR0Ï2…Îzýh¼ŽŠ¥;£§9ÇÿZ²'=ãûÇŒþ`¶SçBìØ#y!qž‡ôâ’(²ƒJ¦@¤j7BÀ玧ùÿœU›U.$²Ž«Ç'ú~¿…Ui n¤ÏCA‘þ<@4Ÿ67‘‚Çæ ì }teÿý~gÕÓj= Õ™Z0F9Ï?¯éÁ©Ñ|û”HÉ ãßE ’U·‘×<õàõýjRÁ ÝðÏ8ÇBz íM6»ž•9Ý“Zº@Ã,¡ÕI ŽG~O½NFb'w˜¬½TTݽ;ÕXdáIG+–ÈÏõâ¯ÃÃù'Í>«ê}½³ZÊÛ­ÎŽozìp•P2‰>uWw=AèHúþuNS¥m$‹½ Êá”ñœõúVg™±s°œc ÜœŸ¯áVíXÉqoˆ7 7Ã$ú}•Z|­8# BýÔšì{MÇúP‘Á.„áqØuÀÏ×õ>´Ñnb/ÂÇÑ ÁýÏZ‚Ø΃œ†ç§‘ôÿ8©îÉHˆÁ裞1Î1Çï5}Z??³Z-MJÌT«Á—¾:ÿ*¦T>×B/Êp àûzÿõêe‘B¶Fp>T ~¹?çœSíí$t|ýà3׎ªm«±¦Û•Â(G“€OF qÓçüˆä2!|…Èä[§8ãëWoáû4q˜ÉgrGÎ9ì_©ëUr$PAO9 ž1ŒþU™¤l‘gìæ8ˆ@6îË2¯LúǾ—Ë”±ùC2N2ëÿÖ­I[ a‹ d°d´M9fók`:k+i¹¤ÛJè«3¸8Î[ÔrO^½ý«ÏµuE½›rœ‰ …À9{ãëüëÒc´ ØrTd‚¹éøõëÏõf->q ݎᎫŒÐÖJúœówµÌÈ>[ˆîIpz‚oóÖ¦¿ VÐ`9f|q÷¸ïíM†6Šh„€Ïw?^ ýy«Q({Ü1çåÎi4ìd“¶ºšº’}0`¤’1ÇÄjxÀ÷üÔv±lˆÔå¾Î9œääõö?J»rZ)fbØhžà‚0xýMIo¨CpÐ}ªÓ ¯o¹âm®ÙSÏ9ç¯8ªv›¾ÆÊVWZš¾Õn´­"{‹ÅÄVr;eTä0FAíù{צxN×LÖ'º±hÒînä #SzÇHã¨ôé^_i¡ØÞiíý™¨²Ú˜M½×Èpe¾còœóéÚ·ít{Ý:âK“o2yw³J'y;CnË4{%¶‚Ú9;å¼ÌgóSÓÓ5ÏÇ …ïvª´dÌK9ã©··Ò½]K OCÓµ §eÔ.-¬’h@Ý— ¿6OBw õªZ×Âxt¿†ƒÆ‹­[]¥ÜÓX4# bb]·û¸ù1ŽÍÓÖ5)¶ÛCu$¬¥¹“áËb.%ÀÉûLÉ!Pžãއô­ádWNiåÌ«c8Îeà`ÿú¹¦øCNšÂÆËˆÞùs‚1ž‡¯5Üh‘O¹ÑÜoÛÞ® ƒµ¼âìFy={ÕE]êS½¬ú5¤Q¼Rk‹ÆÕÏ?fÝÁÏ·éWü/ä^i6ñL%T‘5R&ŒôhÈ©äàjõM'Ã6ZøXdÓ$“Q°–˜†Q½VBÃð®OÃÖvÞð]½ÚË嵽܊ñƒˆ¤2.ïÈÇù¨êaÑ›i-ŒMblÏa¾|VÑé6ë!ï¶by烟ÿUrÞ#¹yn,¥‚ Ú ¹#û@ ÷ägÜÕÖµ!«5É*¾mæŒäígàŽ€g­rþ(»3é¶’TìÔ²<™G­qUo¡Òs0âçÅz:ÈBª[ çžïlWo4æ _TŽ@VFÖtõUÝ× ž¸î3Þ¸û#ŶFiW—Ä‚” ãò8ëþ¿‘Iûó;^I#[K¸ûGƒ,%‹³5Yclðs*œãr}¾•¡«Fצ¸ ‚ËK@HܤyÙ‘Èç½`é÷Á<khÙ[CÔŸâ¥è:•Ðê7öºòøÓSvÞ1ô9ÿõWj}QΖ›Ρ(·Õ¬°6(ñô…ç/·|îÿ<Ö&ŸxñèÊ…UÐnAËg%î'ŽyëŸÊÝÔ¬º«íÚ‰«êRò~ñW#àb¹øƒ®•$ù!BÏ&áú ý?*á«;^ìÛ^‡g«ÜOZMî\\é¨YyÀ ¤qÇ©ü«™’cm¨Æ7üÇU¼”¸àð¤w­Nmš¦©fùïl•ØÜ…FØã¯ø×%ªîV%pLwíó£šóqR–úÁ*1V¦ÜgB:i—99ÏÞp:ÓëVµé¼Ý>U«Gn»·`)/vÇéX–gþ%óbÌšcª<ÒõÉÿ>•¡¨>R\†Úe…T“ÀáHÿø¯9ÕN6ܾV’3fo;ZK}´vú1çðÇéô¨ yLB2T¨™ÆáÇÞþ~¿J†c»Ur¬×÷ÿëæ¡Wb¨.‘>WŒƒ¸×VJ/úò¼Œù†m_†ÿRŠ1ÏcÏn+CGµŠãTŒHxxÆÍ¸ã#¸Ç½gHDÑ1+‚Ѫç¦ýz¿¦IöƒLà$NsÁzW R«%+.äÂ.SVW>ð'ƒb¸… @@Ïô&¾”ðƒ£»„,軃¥|ƒðßâ(µ½ŽÞdB˜Dgb:×ÔžñÄQÄ%†t9ä©#¯>ý«ò|âÔñrŒ'x§£î~±—аMhw_þøoFðÛ릮ÖÑÅq°/#g“‘üû×È^>ñu¢ºiWrKVêòç_IüDñ x“ÃrÂò.Є^8Çôô÷¯ˆ¼c©È·ÙÑÊœ6òÙägòçÓùÒÁòÖ|©va Q÷å+ž{ãE/£šŸxõý ²¼•½š<õŒÄÓZMþØ®¶¨$*c,ÅŽ9 Õ„»óUU©9ƒ×·Ò³ bÚ2»y“§õö©Ä@¢9ÎxÎAÀ#ÛðþU›É°.Iû;|ßùšÇ4ÅÃíßä¿ÈѶ»ÜûÊáÈŒvó)àǰ(fQ·Ù÷üóTÂÙˆyk‚Iì?Ÿ×ÿ×R37š3¼dà?ðªy&Ú]|Î¥žb Úvû¿á!"]’*³vq·#ý:Ôú_ü…mrTH¬6·8æ²£VbO!º° ÐÿŸoZÓÐÙT²1® ‘H;ºŒŽ¾Õç×ÉhR§*‘“¹ÑêµUÉ8­OjŽ`ûرWÎÕON¿ç¥U{à»aŽÌc==çŽô©!À`cåêOãéYw ]Ã<‹ÏsƒßÖ¼º’åFI»6ˆÈËó1|` ‚=Ç_ÿY­ÁqŰ(Ü$ŽÝ1ÓÜW5áÉÁvˆ±<ŸÇ¦zã©®Žw ¨ œON¿JçNèÔÆ×GYÛò’>^?~Ÿ­c$r”zçï€?—­ikà¼H7mÁùsØÿ^µFÄ7Ú¢‰~|“߯œ®Ì•Ô4„G–Âèw'>ýë:ê,²®Ü1l ~€~}kÈ[y#s2çnqÎzuö¬MP•&Dàzc×§_­f’~ñ³“E ªJïpKêsÛ­yõøûMìÏÂ(š\½NÑßÓü滦¼‘‘—ç# ÎÆÏ5ÃÜH±Ý3³3 –\nÛ“ÿ×ëíZ+ØÍ¦í}JsFžnää#"© ×»úÔÕ‰!ûK`5$nɳ`Œ}:vÍ"ÛùZ˜15™ð=”`ûòz}k©Ð<¯k^ ²û>›(Æ’î”øSÉù°4V­N—ñ$’îÙ1M«$cÞG$im˹ÁùUÏÖ“H¶2Ü.d ŠIc»…Œõ^¾žõ°þÕͼÈ,®Þm¯1G¼¼zuùMRÒ4ÛõIâr†yc<¸öÿ=ê©V§]Ú ?ëÈm4’jÇoá=Æ“±o¢š) P ‚Ñ·™» '®1ô5ÒøWÇ÷Ð5]2ëEŽý.ÍÛ½Fß„®?Zäü+錓Y^@`HXãp;²F9ëý}ëÔÆ¯k6–`·Ò®¦7I8Úà,P¹# îç¨É‘ô¯N)I{š²æI&¯ø¡b׌ëmo!‡ý Ö5L¬|¯Ê¤}ojåíìuníµ;K¸ãû4„Å2²¨f“ƒ´÷#§= {^• %î¤l´‹¹ÅÔK" ;d8Q¸óÞ²üg­jº “Mµºó¯-—4tÆãß8Î:VQ¤ÝW„§ÊÞ¨§ðïL‚Mjâ9Ç•4w¬Ñ‚6îŲŽsíüë¾Ð´ÆÔ¼_§ßÚ,+ Í·•"§Oõ¸3×pÁ>„µŸ™lgâ ídü×Y¢ ªË'–Šž‡#°Æ1]/†ôéô].]A–št+ Öé!É,ÇÊûç’N3“ZÅ$´éù«s·Ê&‘o}£|IÖ­¤†ãìÒ^b+«yUAðqÕÅø¿Ã¿ðü9¾°jCz«8ÔT€±•âòÈ;_|–är;àÕ~!ê2ø±î­íÏKÇE‚G &Ñö÷þµFÓUñŠþêzþ¦·‰9‚æ(Z4QÄ /ÝüÀ²~ü×+¯{©|ÿC?c/l¥%§s™ñ‡’Þ[9íHšÞkÛFÛ ¦Ø˜1Ó8ç·òó-OPk}Py˜2©àúó×ë^“©ëW"_(¬‘Mi«H›Ž6œFÊGOóšðýwR™ årKÇó3ãï㇧¨® MXÆ=•N÷¾ÆŽ37ˆ÷í"VPÚÀíôô®ŽiÜê ‘bi5Æ,ý2ôÆ ïÛëŽcÂR=ƦXᥠœ*÷à`}k ’V:変·-ª]²äŒ0Ç~£‘ø}EytgÏÍ$uKDœº’Ç:.™o áßþË‚Žv™Oëí]š‘_뤜ŸµX‚Ÿyƒ¦;rIü~µÂ,àŒHØOøG™6`œ3s“ƒÓ?‡>Õݦf¼×E >ß [ÂÆ@ý+½Y^æiY]v¬ÞMÈÄB‹­QÔ9ç? Ÿ_ZŸ-„ å´¤’ ÁêGã]²þl7 càY€nÌqÛŒñÛÛë\½ócGÆ=>eFÇYåÛÖ¼ÚïGoë@Wåm6¥;6«tþ[®ýJ`ƒ ƒÈííøV5Ö•uªêÛZC4óM5àòÔÃ8éŽýkjé~Ñ®‹ÅRF|üþð}ü2$Þ ¾ŠøƒåªØ#ÆÃ¾`#¿é^Q¯h1iòÄ—iXÁUuM£hèH$ã8ý+è ÿ€Þ*ð|7ZŒšuåš6°3Áã¡P:÷Ïzò?ø~âÝ’g+e‡9ãüþ5õ™v)Ê¿'´æOÓü®|Öo‚£ ,gvŸÏüÚ8…ÂaJ© †è9ã­,M‡Þå6äö=ù‘JDÅH$‘ÉÏôéþqJ™‘C—#¡àÎ?\WÖ#á,˜ÐB('æ’r=2=Ï·-4ñp…ºü¼NrxöÍIÀ©€ì~¼ûÕIïÚE$yŒ2¬¸ÁéúwéU`m"ÐŒ8ÏÞ/œu?áLw]ß&T‚I ÆO~?ÏëTžòD‹b¼ðtÆG§¥G%ܬü“„ÉbG!¸ã××õ¤G2F–ÕîÜOBò2sƒ×4’8ò_— ²d’;dõÿõýk?Îq„Ü@£éJ·ª Ü ¸zž;ךbæ.Ûœê¨w/R2=~¼õö¦ùHÈYŒ€Œßôè}©ñ܇‘X*ªñÇLžƒžÈ¥£rJ€0F0r?ýiµCaÝ;ËF€Gÿ^¡›j«9$ƒúþ<Ô¾_ÞïÇøôíO˜„ÏÍ´ŽÄƒžÝ¿Ï¥ey_ÊPARd)8>£ù~´ñ ¯óDdxÏFA~”2PrIÉÎ:ú‘S,S0Ï`lgúPG©¤¶×²Ú€ó—ëùÖ…®¬]Û™­¬n.b'Æ™žz~=}j ‡“ ml6A<õ½Ÿáe¹>±+&†8ÏÝÐ}I'ð¯Ø09í\MG W·Ÿ‘l)YE¿ÀòvÐõ;|ìgó;ïBGl~4ï&æI{gP¥r¡ËŸqÁô¯¤b·Á’ŠÊ«Ô¯_nO¿ò«öj*…xQðr7 Î}yã··§­{ÑÌÚµãøœ¿VK©ópËwvbr¼ôçúSÝü°Pªïãœû~•õ(Ð4ÙSq³¶`¤‘º%>ÞŸ…XÐnÔì›@¼·CÈî8ë[,Þ`OÔÚºRü–· %ò­»ÛÔœUí ßÌÕmCAæ‚v÷9ätõÏOÒ¾š>ðÍÁÃhÖ+ެC¿·~)š·ÃŸZÚÉ<M´RÅ—™ :ö qY×Í)Μ¡ËfѤ0®2NèóﵪÀH'Ìp3×§ùÅQ–áLŸ}ÉÎâ êsèÖ¯O å˜ ç‘žŸÊ©KlÁÝx÷çøïÓùWÍ»É_¹Û -e¡«¦Ü!¸E Fr9àà{çÿ¯ý{1âpŠÀ¶XïÆ×õ®ÙD* N0Iàþ½w­ç¤nۂȽ=úñéþ5èkÆ&¾!.î3Ó?ãÖ©é¸K•ÈÁ-ý}=ê_ߥ„I" ¶÷8àt^{t® Óâ]¥–¿ á–îÖ']Ð($öúVUjÇFUæì—âû/2-ûÅÔõû‹Y¢¶onñZÉ…ó]S'ŒÃŒ~uÄëò*£DçîFyíëÚ¾›Ð5þÐÚ|6k·ðþ¢T*y² V\3Rœdc¿zá~/þÌš—†Õ/t;¹u Iܰç¸9Þs‘ž+óú|i‡Og^›žç»ý—RQæ¦Ó< U^E`|±¸)an^1Ó¯áÆMamw«<óαC%Å䑺ü¤3©9¯@ð…•Ε É¤^"©šXdÑäÄ›øeôÉ\cƒÅqSœê=U—õùs…­Ôâ¼G;<—·aãfµËɹ°¬Â7çØ}kÆuxpð+þîe@[v~½8ã¾µî< ©x+[‹›i–×Q–îæ™cÚ¬¬6ƒØÝÔ~™¯ñ.¨š®¯<Ñ[ˆc!Tz ôï¶¼ÌrqNîÒ4MM'©:ª¯Êèh`:œŒþ<þ•ÑÞÚ˜ï­dsµVæùÂ)©ïœôö¯7•Æ—ÉèܨęÃc<`Õ|C©³¾û©ÈùÜäãv ~}ÿZóðõéÒ¥ï[TšÑ#×/¢ýÜi•W:ºžu åMh¦m¼UkcÇqgå·2DpxÿõV¯Ž,î”æ'ÈÀùy¯†ã^ñ9sm ì¼²£Fr>ðŸ¥O{âý'á„&ï\¾¶å[Î|zñ÷³œ`óêM¿qnkB‹Ž¬àÿn/ éxbM^ ‡–Àó¶x÷ýE|'2]ÄáÕAaÔqÛ?ʾ°øûûWXxç@»Ò4Ý| Q<“@í1îúñŸn~EUßÐüÃaÆÖÈéþE}Þ@ªÒ£(Î6×Cç3¹Ó•hJ?Zþ‡q¬ø>Yôxµl]³J¡ú~•gáÝjqiÏul¼‘öb çñSÇN+–µºž{q¹¢žX‘œÓñ¨bCa*ºÊêÄãn0{fºjÒ«8Ê”êjüŽÈbi)CN––³»_ðçÒšw-t)ü2î[¨€yÙßÜc¶8úcÚ½ Â^1’õÞin$ €—0Î{Ãüæ¾WðƳ#ꜬDn`NüƵufk2-¬ÆfÀá%#ÓŽ=O~+çå—É{©]ÓÌ•F¤þÔ|{¯x³Z»¹¸6ÖÆÕPÈ „[ œîÁ<þµx/‹ïu ½8¼‘´jü„ny÷éŠõÑñA­ü7<1¹–YrY˜‘ƒÆy#ñ®7H´o]ˆb„]—!|¥]Û²NOOƽ<« ãz•c¶Ç•ã£%T§ëÔð³#îpÎ>ÜÿZgž27p ýü“Æç½}«þÈ:ɳkÄžK`䔵{^x dúv¯Ÿ<]áÝOÚ´¶š¥œÐlùCA\œ·#ŸO¦)¨UpNÐÇ¡êOcúsøT„‚5ä”êyù¸Èéí@ \¸#<óqéþ}jHædAÜr2£>ŸBLƒxÁÈ8b2O¹ÆiÖΨ>eÜ›IÏ#§­\FRÀ)<W _ÊsvãŒNqÛ×®=ê¤S´yB‚_cßñõÍX„—z€p› Áç#Ûòæ‘kQvùcQ•á²¾ƒ§øÓÁPÉon þ½éÁ¢¹ÂîùW N·ùÅUÌ)òº¢°à‚iÇ_<ˆÖw‚‚U}º};×´ü(–9ü`›8RÛ€ã#qÚuGž[†aœ¿|ŽüWæ8øaåZv’R[Ÿ}€ha¡)ÁÚ[?×Èú_ö‰øo¤ø´Ú¯„ôç[©Ýn çOû‘ôÀ¯ˆuÝ&ëG²s<.°•XÁ(vœIÎ?WëÇÂïƒéc¦@ú²Kqw™%–âU!NxùW œu8¯Ìx¶ÚÙi×;JÛÆ¤ùi†-ž§×8Å}wÖÄ´èÓÖ›×^›êpfj”â›~ôO+ðìsjVs_;Ǧy©æ•ÂÈ#ÎXc 8Î?~˜þÈþ ð^¡áy4kk±Ã“o¨:ù„ä’Häã$×ÁZ÷ìÛã{?¿Žm¼?q?†.Ie¾‚xå(¸c½1e\)9#ŒF@3~ÎÖÞðï‹£Ô¼O$ó¢'î7} “ü[9à?jù^!ÃÒXš³u9š“·.ÚþVü¤Â{Z”Õ8A+î÷·õÛñ;Úoá_‹|3ñq¨i‘¤Ìžpšo"Ué•`í‚8<Ö‡†üâŠ_ /5¿ÓtÍÃÈæÖyÚ;¹Õ2yC0P òGNý+ôU_Hø“ce-ý¤7¶6Ä4mÎàž1ŠòŸ‹·_ ô…þ6“MÔãIüCe%•¦olÇ̽XÜ+«08Ûæáˆ!?çÌÁbëW”0¸x¦Û²ï÷uþ´8ka(ÂS«ˆº}mµïÕÿ^§ç퇄ˆ.Æ“j¢5ïI&E ØÄäãÓ<ãµ]Юb´Ô­´ÈîmZÆ5 q r ñ¾„ŸÊ»_„‘ÚþkèJ‹eyd˜““òcoÑ¿•sZ…Ο…üTú|abg“bdóö˜ùÉúóŽ¿Ëú« GêøxGªI}ÈüâS朒#Ñaе-xi0½I§¹š|Ò6«€Xòx=À5Üê:f¤×ú…4kÍ>x´ùkí„þòqÃa€€áppr:q\ƒ.´½"Ü]Ý[4ÚÝü¬l|¹8„äù’wÁ”\U?Â:„¼>5huK‹½CìȬáx*ÌÎsÉ?)ÿ ÞœŸÄ–ƒw=jO Mác¨Üéó[ÄöÖ³Ï5ºÌÆf‘Q°à à—¼Úî+ÿKoy<²Ïsd—NÂqœã¸ýN;Õo†ö¤èú†¢ä[Ãkcr©tÇ »2(#œä’!SÛübºÑï.ôí6 IÁŠo 0–S³a裞¸È=ÅaZ¬'N2nÞFM]¤QÖt8ô@Õá zæx,ÎGÊÒeL€cŽ@'ŠÐ·ñ-Ô~ 2I+»4öÈÁ×€ôÏ{zŽÿQ³Õ<8×RÚ:ÜEÂVÄr$äüÃõ®KÄZªKywh! t—2áO'Ê㞟ÄkÍE rìΨµoxí|Iyâ}^´Ô5]:X¬§žâw4†e]­„‰€ t©ÆNÚùÞöSö×'¾>R3Æ:W¢ë6®þ´–f +[ÝÈÅÚÛÏO\þé^]{"ÛiÈ#ïg¶5äfUe4®´&%IË•èúïÚRªYD`ü§'óÇ?Z¨ù…’qCõ©õ'fŒnÈÀçò¨-ŸtÁˆ‚A ç ¼z×…F6•¤´f‰ûÆJïqw®A*3ߟéïQ%•‘cb݉ >µ¥v޳Ú¨[1ƒÁç>ÃñSr©2•ˆªœîà\WÑár¨T‡ïo¼µW ¸¢¢À2Yßæ –£¦,L$Dåþæ@Èèr}«F5‰‘‚DÃwpÜž9Ï¥G4ì¸Hć·9ç'§¿Zu²XÅ{³¿ÞgN¶º,ÇMÕ!ŸnÅÞÀ‘Üÿ]{ЖÞmÖã ƒ–ÜqÎ?Ãú×€¬;xK€qÊgÛ߃þx¯Að¶±<þš mò”ªü `múWÃg™Lþ¯'mW™õY&60­ìå³:­7Tµþ׎Ic œ3uÉëÏ5ô·‡ôh:2k[Ç4¨ ‚@ã#•é_Új’´û™›nNúÿ.+¸ðê뺗tn$ŽÍ~|,œrαù7(¤ïoÔýG‰H¸E\úgGý¢Î—yä“c>2mÔmžû»W¬[ÝxâþŽ«­é‚ìÈ:ˆ—9ÁëÇSùׇør×KñN„±,q»ùxèÉ¿¯ë#MÒuÿêÎþ[Zi }ö`W±èãøWÍé"ìýNÕ rNêÆ×í%û2x3Â_ïï¼3ox·Ëä”’k–‘”yª+ÓcÚ¾ E$—hÆ<`óÐzã÷Ä߈º/Ž<9&ƒá]ê%‘UcÓ하3†€0’?JÂø9û x‡Åšj^>¾ÂzdoÏå¼sÍ*n°Q˜)À<·N8<×ÜdØÉR§?­KO=ÏͰ*¯'°Ž¾KCç |7Õ|A¦Ë~’ÛÙX¢åd»vMþÊ“ý+ ´ ¼öY2;‹uÿ9¯Õo ~Î_³M³›]KÄZŸ‰. ;ÛÙ#XÏS)#ýI¯pðwìíðS·òô_i蜖)&?‹99üëÛ–2ž!¨aêÇ›³kômž$a4ÄPŸ*ëgøÝ$~jòÙ΢7FpT“ß¾*½­ÉƒÈ$`üîGO¯×ù×ïêþÊ¡2HŸ |8Ò7Í™4øßŸQ¸WÅ¿¶¿ì§jÚ]î³ðëÃvª%xm¥dK€±ãË–Gœ£‘ÏRkyW–/¬ÇGÕk÷è´9!N–6N8Win“²¿’Õëý\üÚ½ñ jwÐXC+¤$…fn™Ÿ¥~Ÿ‚© NN.úØù^iù猗âÒ¸@Óêÿ\Vp”Fƒs•céÇ^ŸäúUÏÿ„ªGP8‰pHéÉçšÏi È |“ÓNqÿÖ©Æ7í>Hß “£RÌSµˆÝ‘Élõ'ŸóýkFß °Ç$ñÏéX–ò30\m*£#9üúÖŒ2›”°Nr9®&·;`šGCà|ŸZ31mˆ[pÇ|{þžµé¾.mº+4d9ûǶÓù×–xõ$ñŒ;w`+‚Hàà¯ó¯Mñ«6•#pæÛÓ‚5ëÆê”y»Mv½«gÆrÂ'% |»‰ÀÈÈú:Êü0ÎqŽçŸSŒûÓKÄÇvæ'(Xçž½¹ú}zUvy Æ[q0HrAéôõ¦´Ó±ÍhÉèv¾Ž)ofGvÛ³gÌsƒ‘ÇJÊÓ›û7Z‰ mÀ*ØõÿŸ§ðÑÌ·WD0ÀBC0ÁÏGåÓÒ¨øÐ&Ÿ¯yŸuJ«F}G?çµ+óI¥Ôrމ³ç‹:ΗãmYž«©fŠB Éà÷Ås6ºuÄ÷°ÙÞaÆï”:cŒ{׸|TÕtÿ¾dˆ²^DŸ4»0A8Ï~•wà‡Á)þ*øÿN±†u³~dyÔòF:žž¿˜qJyN&P©-m{uMô~}~g­‚Êkã£í)ü7ßüŽÏöz×¼[ðÂîÞÎÛCG†î}¾uí›~íð¤íê6zó_|xâ6¥àZZêþ´±Rš…¼B0‡mß/«÷÷¯‰lîµ]ÄÖê 0Óïdæ}íÈüzž‰ñ»Vñl–ÚmÄ^rZ°S/ å®FæÎxéÛÒ¿«]Ö®êAY³õà¥õ8Òš¼mo‘ôïíðŽK¿øËâ.Ÿâ½j {M:è¶÷’-¦øã.XûFB€FÚüÐÓõ› œ£Øn ƥ̇¨\“ŸóÖ¾‰øÇûlø—KÓ¼[ð÷GÝxfk&Ò’KèÚt'bÙ;Žó&¸ôÅ|­cp@dMÒ!å€$á9ü±_¿ð†¦*•aËÏÊÖÞ‡©ùfg7í=›ù[^‹ÏMÿ«ž¡ð÷ãœþ ¾€^êž">ò™äÑôÛÇò¤Œ†MÀŒ¯>¤p+Ú~|7øSñÏÂ7·úW…¦Òu+yI8¹pÄvü¶ŽàqÅ|…ýœ÷%RÞDM–èÄ1#w Ç­{ÇÀÿ6? üsga¥Ësª\6&\$r2xíÆ+ó~0ÀNŽ>¥ZjÊVjÚ/Ó©÷ù=e[ NÛìüí·à}ð?\·Ò<8úEÍÇ‘y)1B—LBBñ€pO9ééR~Ó¿³½Áø áÛ½ “þ›dEmnÂg‰–%yÔ®NWË ÙþÄ‘·Ÿ™¿fÝkÅ_~?xrFøLw<© ‘Æ63ã©ùO'5ú‡ãËh­¾xŠ ÔG£Ü£ÿº!`Jó¸b”ðø·‹co^§…Äõ-J.Î[¯Á“¾ñ3A¡ë¶PiwË$vìãíA¼àr Ôö#Ö¼ÿMеΗqm} ¼ÖÌ®0%nƒòå=:÷Å}âO-¾™âKÍÔÞ^ÞX´a ‡ÌÀ^n `•ÇÒ¼]|Ko©ØÉ­K °ÌSì! ©.ä1n‡¦Üú~µý„Çañ”ÔéÔævÛª¿sóCB^òï¿_M52|)á›OxƒOšÞ)­¬¢P |É#çc'?Ó5Ò|EÐ43^?jÕçšÈ^Dö¶0H®¨8$©n2Á›#×¾k#Á~$Ñ<%¥êùžsvb‰bòбµ%˜0*Ø󎧡íׄñ=ì÷×¥½Ó\Û=îy@Þ?u÷vã cŒW[¨”R]õ:¡YU–—û´ûËš÷Äd:]¦Âú–ªíg(XÕäó› JÅ‚…ïÛÒ´4k Ë$0»'\ˆ:«’á8î~µá/…úߊ4õÕobµ³Ñ¢)]ÈAÛÓ’N8ì+wÄÞ%Ó<)hÚ~Ÿ¢Û¬ªnÜê±u•@ä m¤g€’2x滳©WEé©ÛßÀjøŽÓAÒ¼0‰s¬Oe§Éd]âYœËÁ XnãðÇ5Áø\7£éÍz7‰%?ÙöŠ0ìJ—Ž Ó«Ïu&G¹<|Ø8ä(ÿ#çcå̶.Z-JšýÜj~WÊŒg?Ì*¯k•W'çb¤’;ŸòjKýåFHã%†!qß¹ïÖ VKœ¶Í¹áºðyöü+ç-U™Ò^Cõ ¯q ˜ÜQ,Ç9àœñPy ‡8åBÔzûÔÚ¹û\j¹_tèNíUÍ«(†Rç®Â3šýƒÆK¾¯¯ø§ƒˆt¥Z\à â‚à0!”ƒ¿4ï´8rÃ$d ã¿?#ZÈQr>Vʨã·zi]ŠÁˆ`ߟë\î¦dµphÊ*“Õ1ÿiqˆðCáa‘É÷­=Z{K ›£½JÇ ¼†ó9À,9ì1ŸJõo„ß¼SñBLéP@b$,ólN~™5äWÄb9%õ©rÁ-\ž‡¡…¦êVŠ ½ï#Šv väp€ð=+ØtKµ¾ðÖD€íMÝp¯çþ5ë:'ìq¦Ú¬þ'ÔÒK–壳• “ŽYlUmkà•§‚t§†Öifù¾ìÔ{€=?<æÙ†>J/fúh~Ï•a«aâåUêÏ<ð'Ž[M¸&0º€Wç=#µ{χ¼gáßY›}jé!b˜Ì“€ öê}zøÇÅwïáýNþœÆñÈÜ é“ž?3\Wü%ÕíÊ"j—„>Nß=€'§©dRÆ~ö2²{ Ÿa°²Tçååcê»ëáá¯J|+®èú~‹ mY!‰Å©U .ìàg…Æzµy7Š¿hïxÆwm¿‹5ô8B—2ÊÄ2gfò©Ð–#ž¸®Å­ß†ô£cöÉ~ÐøiqeÝ‘’G~2?âì.d‘‘ŽÖ,°Þÿ­}Ž(¡‡J3Z6ûú!˜çuç4©ÉÇ¿’í}ϵ~üeð¹¾Ñ©iº‡Ä-Tòfœˆ­³ØbÀó܃Ü×ègìáñ“Æ? Ýmà;èkÑY›q=rF£¦+òá…íê^+iÚE¦«y´íKÄY#ŒdsµÈ_ÄúñÒ¿RdMKQºÒKë(3ÝÜmbEHÔ`c?^ÕóyŽX,J6ÒoV¾ë+$z¬±¸Fæ¯e¥îÿáÙöm˜Â¦yVG ghÀ«júDZ” ² pF# Ôzv©j!E3dàv<֢Ȯ2E}U?eˆ¥Ë{üî|œèÔæZ~Ì?~ n³—QÓ-d* ÐÁ1~OAœzv¯†¼anÚo‰ÌPÚ}Œï>gÛbŽßË?í3\æ¿_ol£½…£‘‚:ùoö™ý­¼]¡_McomkåHÉ0\x<ã¯OÖ¼LL%‚^òæ¦þõÿúl¿ëÍ8Ë–¯GÑúŸ86š¿‘ö¸ç¸y6ƒ§ÞC(<èÇ|<Óþ|.Ó´¸…ÐO:áÉmî78ëÉú×q¤ÞøgÆ7Z5êˆç´“iec‚ ú`~kÔ§ñ}¿‡th£1<éÏ­z¸j4éÚŽÏ_3‹2Çbquy1nî=4_‘ÚÚB¶1!]£ ãGj¥¨ ¿Ü—+MÙ_0Ó¸Ïùæ¹_ Úx£Å'Q¸¾{=<á–ÇΙãßò®žö8ÒnÎe+ÕÎr}8>ÄWRÿÒ¼$©q½öó† ê~¿ç§>w‰œÕ˜‡¡ŽãМ㞿­ Èb2¤ãoÝÝþx§ uv\npFÂç>Ÿ€¦&Z0¤ ÀãÉíøÿhf5€RÞÀ‡<ãó© )F-ÇúþŸ­F¡¥`pIÃãŽ)Cg»|¹ÃtÇLæ€îÔ¸Pq•l|ªpxãéRG)xÔ¸ÎOóÓÅ'”%.U ) ý܃ßðÿ=iÐ16ÈÁ°7É'oñ  £PKpISÇ©éÀ¥|³a÷þ€ÔO"ùcø—'9éžççùU¨Ú%1Æ›;e gA8W íÌlUqížÏJ÷ÏL†4ÀŠƒl`qßê?^u0—#¸;ñëþ}kÜüs X•FòÌg?Oþ¿jû|‘ûÓ~‡^/Fµ0üO3?ˆîr@!e{OóÞª²¡`îœ tûwÿõÒx‚d}z|’êó×ÿ­þ5 ±mÁB²äƒŒ¤ îŵí.´ØêÂéI/ërÙ$ Ø7wåG<ñëëíOd !%ƒp0xÓ˜•PYvŒƒŽHüI©š8âäí*¼à÷ôãÒ¸c+h·;“iêt?ÇâVÜ6 8ÇÐqÚ½_“ËÒ—`ÊŒð0\qË}+Ï~îo\å–E òp¯ø×wâi|½2@€±'$ž;Œö¯c™û×cʬ¿zîr bCäã+ÑzsÓŽ½ê®ó†@ÚzõÇcþƒåWü¤BçœúUbøXéSÈœ>ÆØA~U»vÞÇ$[R²=£àWÂwÇÚ¨º¶žÚÇKÚG›<Ÿ<ĪÏ\tà×¶|sýukÿ\MlmØ"€¯ ya~a÷ê=k‡ý†¯¥žæh®$f*¹íœgsîOçï_¤Z†›«áÛi£VY"uà ö÷¯Ä¸Ÿ0ÄVÍ*aðÕ%ÓŽ–m]Û[Û¡ú6_‹Yf”eN2Gï^)»zï¡øÿuû,x»á÷Š<5/‰t"ºF£sÅynâH¤RË×o# çœ{Wè—„~[ø{PÓ®m"kxa‡Ë‹ NëZß¼w¤x›YÕ|âKk[çݴV"íVPB¡@lá†Þ?úÕîšÏ‚m5M}>^ÀIF“@x²ܧ±àׯÃW2‡·S¿àïÙ–6yMwƒ«[êžéÅ­?®/-î5ý_V²™'[»ùæIGÝ*ÎN}=ûtÌøÃÇz–™ jz-´pÛZjŒ¢óh%¤ØÛ‚ƒÛ’Ç­{¯íû<[~Ï~(ƒIÓ®öŸy^¤‚//c³2 “õyà÷¯”>1kCB¶€Í¹T0=xçõü+ö,«-Ëg…¥[Ø®h-Þé­îÖï©ó¹ž7IÊ ³tçªÞÍ=¬ž©t9ýVX¬-ÖK똭aoº¹˜žø'üŠÁ¿ø™$,Öú\+dùžløiAÆ0vŽëžõáø§â®­/öU„×í’Ó8;TŒcŒ÷DZ¯±?dOØg]¹ø…ÿŽ|?æ—¹òåÛ,.|·ÆðÀô-Ǹºq\EC ì÷ÿÉŸ¢ÿ3çpÙ~'i%Ëæ{}ÿä|ßðÏPÔ5uÖ®/nhãm‚›Ÿqvãiÿ"xLý—hï ]ë^Ó®¼â­r'–mc6Ö±ÄÐ.Ñݤò±RáÓ¡'о#þÎ_ ô/Ššo¼?¯@¾ñH–ëìv(Řãä‡2€Wär>[Š1pÍ#E«rG®©»7~öÙö>›)’ÀTTÝÛM»ÛG£Ñ|Oýƒÿg±á{«ïßFÈ̦ÛNSÆA¼r=1…ýêõïÚçâ+x;á¿ö=¤Æ-S_f¶B¹ÊÛ® íЃÃ*`{‘÷Mz·ƒ5Ïxƒ@·ºðÅÝ…æŽ2‘¶œÈbR:®…#<Ž¢¾ý­~7éž9øÁ}¥éWÓÉgá˜_KecKÑ4‚r öÀE$Ž|¿@ â£F8<*§ÖçÏâq3Ì1n¬úôò](ð/§ƒâ.« ä.°ÛÅF¾€¨cßœ“Ÿ^½Nê÷Iñ\¶÷7–PË26a™îC׃_6[먓ÝK>iã'’ÇgóÇÒ½gÀóÜÜZ!u•¾AçîxÁõ¬hÔ ©ÁÙ£gg£㟆úÕÔ7+¢jcTÓ¦ÛçØÞ¨WÚ¬€ã$àã ë^eã gBøy¢ÚG¤è0\kktÆí Æù! V8 —Ž ë^õ'tí>7DŸÎøWKt2û|ÛÇãè}+篎—pEãXõp‰5½æš!^K)a¹x8à~<×è9.{ˆ­QÑÄ»Ýhúž}\-8þò?3Ëõnç[7÷ºÔ—WóI<¬0NTàc€Àè1Ž•Íê÷ßÚ Ê¤ùI%Ë«7£0àgžý|·vž!·6eŠÚn*¬Â0ùÀ|Ù·aüê¬þm+#PShB\m;9l7QŸl~—ÓU¥:’¼u]INŽ~ÆÁ­,®‹(vu…ă§?0íþyⶬîgÃHˆC,׌‡w÷\uÏ·­X™,YfžEsm1„E‘ÀÈÇÅS/ö[&Hî,.™Ñ€;@9Æ:úõ®iEGDþò‹VÐÆñ ˆílЩ%làSŒ¤°Æ;gÿ=xÝFwy]ŽG9<}+¯Öˆk8”’Ãɶ\€99ÿë~5È]í•ÝÆps˾•á㶨Ýê‘KQTEŒ.Cd|Ädóýj¬Lr N쾕gQ;|²*äc$ñÓ9÷è*¬L<‰c”8Ü3Ûüþ•å^ÍXQk›bKÉŒ—DÙQT Èç9=úüThÓ¶ÒX Žx펴jN ~bÊ  ¹ù°:Ë3–r«"…Ã/ÊqóúWé˜JÖ µoÑh´ô>vºn¬»Ü ¨%Î9ëÇõ=(,©ÙnžüÓT±,Àü£…Êñ\~%´Fb¤pIàúç?‰¬êb)kwë§üÒ£)ÊÉjΓÁž¸ñ&·ioom$ÌÍ…1®~•÷§ÁŸ†ô=:Ñ´2Õ"ˆ¤hv²€0îp«åƒ6´ðn­nó[Ç92`¾9\Œ¿~œüø…eâ=2ËÊÛþ®0@`z¯?—ø×âœaŽr~Æ›÷:ï¹û¾Qy.ªt£:]¹+þ£ôOkö‘­·‹4F³¸éæÃµ”ŸÁj©ãiÓ2Åæ#Q´‚sž¸‡ê8ýzQ…@Ë€¥ÈñïøÒ,~kþC¸Ÿ™GO~?Ï5±™"¶1lºõFùFz~\tÿEÆæu<<`ô?Ê•ãÚZL‚Ä•‡äúôúÿúé­ }ÛTÏmÇðéù÷ üÔA'# N~±@—+ûÄÜN>`;Œúþ¿äШÊI1`NHÆO½ÌJrA 2~Ÿó ”ó ( ¾q‘Ž;ÒCv-£Û èçühÁ,/†Ë|¹ÏSŸ§¦?ÈLÄ8︎€:§XSqUbüéœW´x.D‡I²B@ÌJ2ëî:ñþGŒL©#¤†SŸ0ò+Øü)0Iµd?tg©ïÓŸóÚ¾×&ÓXìÆi;î«+bïzƒ¹à–ãã×54²+þRF 8Æ*;ùUµKFõ$Fxÿô»£b%·v8ÉëÛßÿ­]x»ª¶;0ŽÔ•Ë1º! ð 3ÏÖ­¤†d€Å:làgÛ æ¨ù§g,csÇ8ǰÿ<Õ¸ö2+FÀå€98*{çæ=+ IJ×:”­_Ãÿûän;ç9ç?È~õÚø ·ØïÚðsÕzóÿê®áŸÉâEË ë¼3Íu~*ºÝb2/<Ýp§¯õ¯MzLÛsÐæD¯º02P‚T“Φ}»×1ãyZ fWÜ¥Ãzw#Üôæ¶Ž2P6òxlö®wÆ×‘Zhݾc…Ç#w\{tk<\Ò¡>m4ô1¤Ÿ2i\ú+ö/×Ο㿠ä‰" 0ÆÜñÏåÏá_­"x¢ÐešB%BY‰è+ò§öÐc×µF¿¹B¦8 ýîs×Ö¿Rõ«o3ÁZœ Õ­¤Qõ*kñŒê“£™Ô—WN/çcëñUpøuæþë£óÊ/IeñËÆ7eÁ kª½Ì …Nßß9ž½;äWÜß¾<é_laÓî¦ò5èЙb“Iƒ÷—Ïãù?£øÑ4OÚcÄú}Äãc^ÜY–bOÌ’°¯=1_Dèó =rÎþ)<‰DŠêpTñÓ:WÁÐÅWËj&¶•®»Üýß5Èð\E€‚nÓ‚²’Õ¦–Ϻzh}9ûuü/|(—UÓ$Ž×\±šK—ÉÌe˜*c¦<ÇCÐð ~#üWñ[xƒVŠ& Ù†I (¹Y8â1ø{×î‡Æ_‹þñ?ÃÓ§hú”ws]ËãÏiš½þɯtÙ är<#b@#$à~òwŠG—F¼*EµºûÌ»]2ëQÔŒP@e!áÆrk*?.-9™dfÖã;Žì’ÞzâºXµ9®du­º"=Ü{œd<€@~RGðLvÉA42Ø¢æP-Žd_”€dÿ/ÿ]D£M$‘ª›l£ªœ¡Ü@-‚2…8út+–ö¨C…*nÏ|úÿ]tÚĪZR°“G‚‹ä?çÿ×\³©F;–?÷¡äqÖ¾s0ìt;´‘WXXå(‹•ÚØc··n>½ª•»·‘1µx%‡ãÇæ*ƨÈ U±·9ôX#$g~àÔýin–F»råTqÆ}HÍWVB¸À @Ú@Î?Ï•~GQŠLñ*ÆS¨äNd(s’T©zžsÇòúÕí&(î##¡;oóÍe™Ò5ØÄ³ž~•zÇý2 •Br¤Ž•Ï[0”éÉstvgµ“S‚ÆÁÉ]-NšÆ{¥U;cÁg#·ùükêŸÙsâ‡ü#ºÝ­…Ëȱ¦À¤ãz>Õò—‡ž)î#ÛË9ÎrqÏzît_2Âê+¨¤Ñ¾WÇ9Èúþ•üë™NS©*uçëЫL½¥=–‡íÃoìØÂèÙ 3õ"ºOx^-wK•îP9ϯµ|û/þÐÒ[Ïi§_H¨UÁßÇÍÇñQ_¡ñ$Ý’2:°oðÏ—U§^Á×ß¡ò9¦¦ ²ÅQØùšóÃßÙZ¥Î›t¡brUq;z÷ò·íYû-Éâ2ãYÒ^!r1æË­Æsßé_¦>7𠯈홂bQ’@È<{{W—ÛøN(¤“LÔ£ T ïðô5ã×Á×Ëk©CäϦ¡›ÑÌ(óOâ·¼¿SùÿÔ¬¤Òo%ŠUd8äŽ9=ýj=(3Ün,q¸›=?Çõ¯´¿ooÙŠÇÀĺþ‚“Lƒj–$#0ÿ#ÿ­Z¾Q·Œ;˜r{ž?ýBŒÓ©/aIž¶ ËiÚÍÛDÛJ•ãŒF¨„ü¨|EÖ>ËkåÂÄgϹ%cíÇÿµO¼¸]´IûͿø€<õïÖ¤·ñ¨ÐC”JÀùIÇלW Ʊø˜±'(ªõŸîï±ØMðzjjë-l f{g ¼d¯¦8ü rÓÃ2ø•þÁwä_õ¹ >èéÏN¸?NÕZ/êt_Î[´WɆbÌŸ–ïzæ5íjiõ#9Š8·ö€1ÀÏÖ»(ª·÷ÿCÃŬ?/îQôƒ5öŽ(ášh¤Ú‡"¿P=뻸±% †ñ ßÉuý:×É7Š—Oˆo»’WÆÂªN{~&»}â;²¤HîèyÝÏÿ¯­t¸ksËM6zäÿõ @×zgˆ¡Ó/Ù–C.÷`Ǩ8^ý£¯Æªv•OÖÃŒäñ^XJ &#*r=ý?AùWØÿmü;¨[<¯o<,@ù¶·œ£?þªùZŠÞ-Vè[xUÙUœÄdòV”dÚ³EO[H¦Û‘†Þ!sœã§n´…0ß¼'’Ƕy$ÿõ©êé4kòîàãï{~u’@ã %¶¦>ö‘ú×A‘"¸P̧kãÎOQþßJªÌ ²·ñqÓéøûÓFݱœ¶B`å‡Í‘üùïJèÉL¦~P­õí×½c‘X•Î=Àö&•‚ p1ž}rzw¦8$eqåó»úÓ“cD§åÜTñžŸLô  |³Â‚þ.?—?çÞörÿ0‘À?óÍŽ*rBäàŒ`zÔÖ¾Psrêyà(=è¼ñ.Žö7öóFæh^EÝ•Æ1ŽùéÞ½+ÃQ7öU¸´•wŒœ`sƒôÅfy"æ6ŠTF ¼€:~=ÏzÚÓíãŠÚ£'`@œtã¦Ó•~±õB¤ªÓÚ[¯3¢½äÓ8™üL®ŽO™TŽ8#OEËä ô?­FäÇu9'K–lííÈëÚœÈK (rOÿ/óšñqRýô’;ðÊÔ’lArÄÉŒv#õÎGZ¸²œd1è·ëU;°#ÆÐI,1úóO‘Dªã@ |}kŠê6r:Õ»ìu?QUÔJ¸8Ñä$…õÇ¿øñ]Wˆî£6*À3düÃ=zóéÒ¼ÆÖîKm;Ä%‹l89*ØÚ}®+OÂÒÉuà¸d”±›ŽæúÿŸjõUkòÒkxßò<š©¹IšH­!g8b>R‡rõç¹ÏÇÚs–Rp2¬ÇžFG…mÍL‚<Jý÷àôÒ±éçŸÒ¹éôýCÄÚ‡Û/¤ód$¨y@çäð=Mr~#ø­¢øEçÓôä{ýJÊY´hý·ÙàŸNƽ<©:U•JTùê-¿•^mzvwÓÄágJ´T)ËGwwßOé–ì¼+„‘Ù[À!´‰æ=°rI=ÎH?§jú7ö\µ·µÖa¸â†È»p-'îÛ§9#$µñ_Œ~%j3hQ[=îë»–# \*xŸiüøíªxT·Š[©’äü¤C´ŒãÒ½¼N毉iÊûy~ ÑXüö9Æ•°ô4MoØþ…ôJÛRÓ!’ÛjÆ Šs³Ðñ_Û7D´ñÂÍ?O½‰&·—Vˆ´r ©ÄS‘ßœ~8® öeý¤4Fð(Õ5íh9»hã†,{Ð$œd@ã¹éSþÕ?<5­øKHÓ´ë³=ã] ¼!CˆÂ:‘Ãg’ã·c^Í,\gC’nÓì|•\$©Vm+ǹñω?g]­Üè3 ˜0Ãû Œñÿë®2?Ù_ñ ¸úäzE°mÉ%¿œò ÎÐãhÇ¿zõ‹ÏCÒ§w@AÁ£ŒçµnxOâBê’Mj ïŒÛÏ>™öïëWõ ¹M\bô¶‡ à?Ù<»´Önå8iÚ,…äú±ÇlõëÔü©AsªÆŠëÃ}Î8úÿúëŒøÁã.XK+Ü\,xgnéZÞHìu˜/$d&V ªñ¸ã“úÿúêªâ'Y/i¯D(Æ1vއ¡øçÀ–Þ"Ñnàò"m…—Ï‚ÑäpÀ×ÂZî‹|ž$¼ÐæÔ¥½kXÚ#* °]»?Q·ù梌&"2…NZZoï›üc,Hâ£(+¾Æe•ÛiÓ‰$Ž6“´úÿ*ì,~$™½H ¿Ïïý>LÐÈCI·œƒ´ý2*F¹b¤‘ÜõÆ5ù†*„+KÞ÷¼õý,~GØÁ·àï®Ö{’=Þ,.ã¼µœ ~ñ¯ÐÙ‡ã¤z•½­¼ó.örgïµp9ùqàËkË‹…“°@SÓœuükÞ¼+&©àë˜ïà˜«& (èAã¦?Ïã_+^:僳[MS+­ŠÃóòÞ-u?h´M^RÎ9Õ² ðsš‹Zðì¢Ú«&s»oZøçà/í5òEi{3¬«±`€ÿû_­}sñ§Ãö–‚K­H¡#•ócÏOâ¯rŽgB½/cŠZ£òŒNOŠÂW½ Qò§í» jºg‡f¸›NþÙ³nQt˜/€02Häœ~X¯ÌÃg \³„oŸ˜É?çŠû»öÍý¥<®Ø]hú6’÷úÛÛ{<’,J gl¹Îãëã-KÉÙÔîÃ6 $Œ÷ÿ=ëZ8Ô©ng§õÿûÚ¸ª¸¬, H¯w}üÀf‘¥>kcv3‚3Ǿ?©ë÷„äyj£ž>oP}3ü멺·6Q$Q€Ò +dþ_§ã^qâæ¹´º1²IÂŒ úž½ÿÉ£ 7‹­«<ªÊ4)éÛ±—¨"’±ásË>;w8ïÞ²ž)¯ ÅÂçiNúcð­ 3Ikù2òT8ÜesœžõÐÛÃò¬¡$ÕnŒ)Ç^åCv¯¥uc†÷"¹¤xÂO2~Ú¤”)­îíeå«w9ÍOÂú…†˜oo-ü˜‚îS"ìÜOAïÉþuÈ—2Nv±dÝœdŽ;`ÿÑx§ÄúŒ†)ã6ÊNLÛÏ¿'õ¬Û(6dÈArw`&ñÔzt¯Gêò^²Iù7™C ü˜)9Eu}_—‘ ?”W;—#-€NFs×ò­K/˜ËAØ–mÄLc˜×ñ³E%†>e€?º}Å7hf.¤¤`nÆN{ð÷®£Ê=_Â?´-‡Ÿ£‹Éø-æ8ŽÛJò?ÏzôûÖ—6±GedšxŒýØ~§¸AŽ+ået,§ ç©ãž¿§ê+¯ðäRÍè#bÊ7|¹<µ.+qkk#Ñ~"xÖ-NÔ¡FÀù™ûçß½x-üÏ6£q½w&ö¼þ]ë´ñTw^CI#–E!¹' ~…pŒËæ’¹*\‚xÃg“ÃùÑ–Åɱ‘¦ð»”nÆA\úý:ÓÙFÄFÊœg-ê{ú»S•»ÁÉäq×Ûêi›÷:ìf`FÌ©ÈÇÓÖ¬á]Q¶g‡CØÈÿô®J§©ÇDãqÿ$Qåy¸'pWÀ ½þ=)¬TF äc$àôÇã@+”Váú†ÁëÿÖ©NÐâQæ1ûÜŽG¹éúT{¼¨¥qãÛ¸ÿ"©Ø6H$äqíÞ€%q’3¹†Üƒ¸¯9õý*ÔVR\ƲÇHÈm€çó[q|HÃ`“Ðv­eÛ ¸ëØzÐ\UÙéžÕžÿlR|ò!ÎâÝÜÇQÏæ+»²e’çq’§ãï^ä¶Ú¼è‰úŽq^Óá˳¨XFìá$+ƒsŒÏNø~­’c~»IÒ­«_‰éK’NÌã[DÔâžeŽÅäG“z±‘FF1ž~êãh:’ì°K™?ÛP}=y¯BXLn¢†%‰ÆxàsK˼–;‡C’G¾=±×ðÙˆÁFÅ5ó¿çcsÒ‡ºô^Ÿäp+á½M¦GRUÉbþ$ôàԑ蚬ˆPé²IR£éŸóü«¿ŠæEˆØ1‘¸ã=?¯åR5×—np$7pGÐÿOñ¯=Ð§Ö O_ó"5ê-Ûü?ÈòÝZÒmLÔà»­Mâùp‰,9é×Ö·<'äÃàûظÝy$ääü«?Å1Íâ}/RœDÓËdUÉêwzöµoC‚K YG:•}åö°ÃOuÿõŠóê¶±)[§õýjdÓ‘3Ë,¸ã8!¸ÏåÖ¹ß;.‡.á±¹¾îW¡ë[,wMˆ·˜_ðõÿ>µŒ<1¨·„$Ô$µu´'ï²1ÉüñŠ×)*åìVòª™Oá7.|#©}¦Íål©YÊàr?"kéx¾=k:²)‘#@UbÇ×éÐן}÷ئW1‚@ç×#õ¯AÓ|k©ëwZið›wo•¥PYúúñNõø.sB®'–]àÕr>Zöçï=:ÿZEÇã{Uœ†Q‚CHKN>nàÖÍ—ƒu/Þ$š›ºFªrÌC~É"±>è·piðO{#O3c¿¨ã'¯¹¯O°¼òð“Ïû×ÁO–2å‰úþ†©SŠi9>Ý ^%Ñí<ðóÄWVK‹ˆl'‘f†rB×Õù”’yÎùà3ò§Ðž¿¯ê+ôûâUœš·Ã}~Â2RK«G~xLŒkóǺ ñ4Ú<3¨¡™P ä¨'ŽÝM~Ã4$éU¬–—Jÿyù_ˆSŽŒU’çÿÛÈç#’W• ¡fÁ¸Æ3Óóüªh7´Œ0Bžý=yÿ™#Ó½ox.ʽ^Û̉JûÁé÷3žzr?ýuõͨ¦ÙøÜS”’Gc¬ø“Sð¿†ü0¶R<hw`[ŒŒä~+ùרü&ñcê1]_êWeØ®T»dÝsŒWˆxîýÍí…“£D¶và…ÉcÎqíӊÃV¼†H®d‰9œr}=¿ZóhÐJ\Ïww™îc±˜—~T¢­æ’Oñ>‹Õ~&¯ÛŒ‘ËÙÂõÃ׿è}« øIñi‡‹¥†á#ˆÁ9ù†Oåßüñ_'MªJÛK;H‹#ÏŸ¦8õ¢b{w‘£vYxÌŠØ#==«¡á–ºžR®Óò>³ø÷ñâÅõDŠ aºÔm1"@ŠÁQŠ >qÏ=*ì>k÷þ/ÐWU½¸yNKIŒ»ÏSî=z×áÅÄÁMï+®Ç,OAמàWØ?³ÿÃKÿ x^ëWÔõ)ö&Ý+?»ÜÈ£sœà‘ÏþsÔVu)FùzšÓ«*“6¾0|Iÿ„‘ÓG·¸éöâP°§ãî‘ßë^cƒÿµ-£_µ›xdD_Þ0>þ£J·¬=¤òM“u<ò]Hϼ>Ì󒃧S×Ò³5MNKIíWûZmÑáhöÿ À;vóƒÖ¿VÂà¨ÑÂ*\·µµµ¾ýO"µYT“ÈÍ•åѵ ­9Õ%–C(G#9úSôMOû:+¼afX¡EIm§ôéíW|g¯Ã¨Å§ßG¦˜%…d ,lpà¶yã‚2߆+•Ô.ÂZ=Ôrm3´jlqƒÔ~Cß&¾^§†J3Ú?§cʃ”a*RV¹ZïPqĺi$w¨89Æ?¾ãÒùeœ6\…ÎìþU³ðÇI“Uñ8,¤1rÉ•üGâ9÷§]é²Á¯,M·K–WŒc©$“ž8à~µ¬\ᇞ:[¿u|¿à™ÇuEÿ ø'ƒ>'‰5=:Kœ‹vón™x c¯lö?­ruÕÕõñ§iȰèÖ»µD<6Uw=AÝ^ã?Aá>Í•¯ï#òÀC†\¦ cžŸ×Šðvyæi9È%†=뺽hàðqÀÒøå¬ß®¶þ»–óâj¿Ozµ\ò¼G_¯¯ò©üÁvð¹á³ŒcÛùv®Õ†ç¤¦ùuõÿ3Ô·B‹·–y'æ<®ÏÏõ®÷Á¶·ZlŒ2eÆA•?•q–Á°B Œ±ÀQ‚W㎜æ·|1ªA¦Ë¶â6pëÃc‘Î3ÓÒºp~×SÚÓå½»9~_ƒ:°Õ©ûXª—KÖߎ¥yíšÚbŽy8Á#¯á‘Í-²+8`H>üU½nÕþÐ$íÆ ú“Tìn¤¶¼Žc˳Ԁ0+óìÂUfç>É8ýÉê~±…|²Šû-®ŽZwÐë|5ªj:l©%ªN¡LçžG§O¯­vIñÇÄVû|Ë-9»aâcÇàÔžøÅ§éVñ¤Þ ƒR °#?O,ö­-Gö…Ó^Ñ’…Ú$œmšâäÇNƟξ-ÓY·*?Šÿ3õ¯¬áðôX‡oð»~¹^Ïâì÷²)6öÖ³uÝo½yç¶Nzqÿê©onuÆÇí×ä œwOµyÞ½ñKPÖ$v]3IÓC|ÁlôèaeéüAvõîiš‹®®îc‰žiH\3'o<Ö¯V”\á/‰­‚ÆÕT¡7)½4‹Wg_m¡L· ²ÇÎ̇#¿ÿ¯ñ®‚=šu‹ÌcÏËÊžBsD~!±ÓìciÄnØ—=9ëß?ýzã<[ã(ïádŠD‡ƒµ7uã‡Ò¸)B¾.v·æx˜Ü:Ë?£ìˉñûºäzŽ™p¶×j§ñ‰t!Œu­ik¿4?ébãÄp@ú° ··1ƒÏPvÈt®ÁŽ‹s«Íý¸gž‘öÎ{äJ£qáôºÖÙ$BHuy·ZúÚY};{)&­Õ~GÆlUÃÔ•z*.úY«Ûñ: hzg‹õï²jWÒXX”>XŠ"Äþ@ãå[W~𖙬O¦C%ÕÅâ¨1Ï;ìÝ•q´zúö¯Kø_ð«Bñ?‡ä™uE]RÕ—ìVû¤C³Œàœá‡LŠñŸ‰ §ø‚êÚû[¾ƒR¶UÚn-Z6|¨!HÜHàû×l!jt›V,þÛaQí¶;³Éê=8®tÀ0-³‘ÛüôçÞ—qFC€¤p;÷Î?  KeÉÆÌþ¿éÍZVظªánãØ-÷²=}¿Ï¥ ²I,á¹8çñ¦´ƒ´Œ`=é]Lx @8<°šb$ ¶œÏPÜ€G¦=÷’àòúOåŠDcíµsòIíœfƒ–Œ2ü¸ù¶c©üG4^OºÙ;@ày^ßçéÍI´¿–… ŽAàgÚ’R©¹°Ä猯#Û¯hÜ<”2z?,qþzМùÛFbw:úãðÍi[Gpð©HZe9ù÷ã<ÕʱV ¼’KsŽ9ݪҼ›G8öS‘HkCUKJÓ£ wüàuˆ¯QÒ^Ke…Ó(@Á >C×ð=s\O†â¶ºñŸÉÄM:䞣æƒ#üú×­ßæò$+áLf¾Ç'rŒ%(ïs¾¼fšqjÎö BÑ%€å 9Éä{{æüW¤µÜ‰wȨ2®CÏ óÅsÚ§w¢w"oÒ¥‘£•›F{69''Þ%Ú]ÚïF e=˜qé_mKÆÑq—»/'¯ªò;cM_–hó¡mq×í2‹órqè1ž)Éi4Ñnn x27áóéKu4ž{ £q Î…½sA»!UW<ôïÓ¥|\± ÜÞýü}•Ñ'Ãõh$¾ä!FVíËÃ5«®ÈVÜ*àœ)$ uÏõþµ›à˘ÍåÑÞÌ \Çc§ëŠé¤ÒàÕ5k[v «4Y— »‘žØÏ5ìIsÂ2ëdy“v“PØåôn=ò “l—J¤·–Ã9$zÖ·ÅŠöÞ!ðlZeµ¤°¼´îPh3»éÛù×K¯ü6êÆÊô—o»ªnzäØ×ˆüH°¹Ðõ¡§Ü¦€pq’qÐþX®LuHÒÃJO}‹Ã)©ùý³ÝOË郎ÎxãÜ~uî?¼&«qç¶Ï.2xÁÁþ†¼»Âš1¾(áL–N0}kèÍ/F½²Ñ!²°´ó%š_Þ»¸]«Æ[œvò¯ÀsœRoÙ&Hp^P°ô*¤}é-=ò-I- hày™×Õr‘Œ`gƒþÓèÖÖDºFÁ$ïbOnçé\·‡ôË}%Úªnß3$ç÷Ç\×o£@d”O#mQ’ŠG8õ?ç½|[´‘ú½orž¦Ž¥¦Kªè×–1eš&Áb}:zöÅ~lü`Éø“­³„:#)‚#Q·ê.Õúw¦·Ùdy[ë×Óù¡ñÉøÃãT,Uµg+pAsÇëÖ¾û†±N0©…èí/»OÔüÄL:–Ž'´¹~ôßèpr‚Äcs1<íäg>Ÿ‰ÅwßtøHüice!ey¸!x;c'××üŠâ#u9ç Ž¹éøæ½Ëöoðì†ÓRÕ#B·ÖSFÑsŽ8=¸ÏåøWÔcj*XyÉöüÏÈrœ4±XêT⺧òZ˜<<úf«jññ!ŸÑHÀ?Ÿÿª¼¨1;² ÛÏ$àñùv?¥}%ûCèBâ9ä[–¸wþ"¥w6F^µó[ÈXìêßÃóc·_nµÉ•TS¨ßXÿ™éq%KêtšOîV²±*&ÉPÃ8'ƒÓˆ¨„Ò·qÊ•ùóÇ\~T²3  ཎ8“õíëSØÙË{´1—’bªnÓŸlôä×°|©×ü)ð«x«Ä¼„ {lM$¬Jç 8üñéü«ê}Åú„ºtÚ5ÕŒ»rªŒËËü<ðt^ðí­¸LÌùi¥À$Äþ€ã¿zëô)tèuhgÕ#óm¼²»CX©=xÉþc>˜ÐK‰…7µ×æv´èÒr[Øñ?6“¦Ëþy$¥LÊþ_\Œ}þyÎkOÅ3¢É)óC©$€w>¼nµÝëööº¤2jH–v±?Ùb‚Ĥ œg¯R}kÏ5evšå E¿jËçøzcŸÏÛÞ¾÷ FjT’‹ÛK¿Âú*~ÏYÊïÏ¡ÐC⫟ìÉlЭż¨Y|±Ì|çùÖ,—A­™qæÄÿ+/BNþ¾Þµ£àß ^_’íòißv[œŒ ÇL“Û5¡â]gÃÚ‹=2Ê-FFÊÍupŽ6r: óøVUðR«GÛÕj ­ú¾ú[3ޤáí9!õÓ§Ìõ¿„\º?‚5]Nçjùë±sÃ0×‘Ó cŸÂ¼òÿP†?ÍvÎvè dòxéžõkáÏ-㺻³Ôçò즵ÙÕ;rÇCׯzäõmf;Eå~À™’G»ÛýßιñuiU†•7eÞýôµÿ?CŧB¤kÔæ_wÆ~׬ìíê±ü…y/ÂO-ž›nÊ ³“ǯÿZ½žÒêæöðzã#¯Ã4rgïxùJœ£ìÞ©/âÿÙwÁ:ìò]Okr“¶ç.nåfb}w1¯ñwÂÁRôØçîÚÍ4…¸Á<œÿœWØ—WbF €AÝϵx_Åí<Û[I¼–mØž þuOV)G™Ûµô7ʨáê×u'º–ÞÊÿ}®|›ã9Õòx°0ÿ0Àõ®;Qó<¸Š•WÎ3ôöïõ®ŸÅR³Ü‘Ç8ãc5Ëêr4P„]˜Œ*ã=À¯Òr˜Ú‚õ?ñª©›5Ù/Í’}’êîÔ<r'!÷c=½§O­ˆÝnÕÎQþW$‚3ê=ªšë­eˆ²ù‡î°ê~žùïüê¼±½ìfia,ÀýøùvÞVH“ “Ëž÷ý r׌—R±Ä ÷Û''Îzõ¸Ås¨¾ndjÚJÈäËy™*¦I güsý(ùv2…QŽb@$õÇ>¿çÑp#-•œÿµÞç%X ݸ çŸ_ËŠè2 #0à´ŠÊ2ÊòúûÒä™Ib 9ÉúcÒ™É\á€É §¯qž£­(f%؆gÉQ‚ ëóšzÄÁ׸Á9^GNõçÖš$‘Bû•øÜsÎGz0ÜÀ0 IëØvOjFyR<ª aøãý¡þ}(6!O”uä㯠4»7ƒ‡ ¤çnqÆ3Éõì PC1+“×¾?Ï­K+2¨TpÍ÷‰Àúûwü¨FcFÊxàåyëéŸÀUÔ·. ™FO÷ŽòªŸ,iòÚÉÉ?Ϩ?Ÿµ\C•bV§ Òe#F D—¶åsþ´oëžç¯OC^«§ê3Cl%ŠS¼F ßÛÿ¯^á¡k.±h·1«Å½IÉ#צÜi6²Bd‹"1ò Æ3Æ1Û__•%É'æt×,¹“+x2Á/ü1-¼ê²Ã+¸`G,r{Uôûø´{‹5æg7,bC÷G@>•wÁRgAŒÄ§kÀ*;ßó®C[qý¹~Œ7#d8Îa_Gˆ©<= uVèöj>]VäËh¥Ã«y@çœäcØt¨ü¦K€¼ØÔc$`ñê*¨¹m¥#Ú£¯ÍÈôäƒþzÔ«p žY är'žÿ•|«q©w5©È¥t7|¸ Æx‚²•9Ûß‘þÖ›S—N»Šâ"HÈ)»žsœóôWÁ7QJó&?taHã«~U·?‡­õbÞÈL`2UÂnÚOùÿžÿD—»m¡ç8óM¥ÜܵøÝª$L÷š}½ÎŽG(@Éã¡O¥xg‰OÏý vÚK„`¡zŒŒzát°–p¤bBÉîÀ'òük¬ÒgóGÈqÌ{JóïtzuÓœ–öé_ȱ3Îã§\¥~xþѺCé–ý¤t'—Ã+«Yõ„%&eîl$“LcŸþµ|†Ÿ»s±ÀÏËÀÇÏ5èZ·ÇokºÆ‘y}ŵÂX­º!Sœ žzWŸ‹* ü€¡ˆÇáß·çS•áka)Ê­¿B³üË™×\:i%×þŒ?'rÿ"8ì{õ¾µìüå±Õî`,Ä%d ‘Ã>ÇŒzä>x5õú–_Eb&¥*õ²};ßô¹òXŒG²‡*cüa¤Ù>ËS¹3‡‚$ULîÈ%rNO©=‡$’{‰œ†IÛ…“ìïÓÿ­ÞªÛùW4÷3É<Ä/Œî8?\ëÒ±ÌsŠ2^ϵ¯þ[˜ÐÃT¥QܹÁŠeÞåFÀÀŽ1žØüZè ±Ž{d…g ·›YccsƧjå,h¯¸¬c ·È玂·G¹¶¶MWN¸ibU&lÍœõÏR1~¾•ä厔ªIÖÓí{¯;uô:1MÕÅÙùìÍŸX˜/äŽYc€ÊAr<µrOEÉëéô¦ë:·öGˆ®b¹‰gµp¸È‘Û?Ë5Ÿ¥j–ƒÍi,÷‚G™ûÓ}G8õ8•rçUÓnnäkËyžQ‡™õ“Ãw¯]J8zo ¤Ö©ëfŸËäÎ:mΧ4ã~ŒæüA¥[Mt‰s ì¬>XÎãò°üºóÍ`<™Á—1€~e#¦;‘]µ»Jc8¸µ› ªÀ“Áç­b5ôWjɵ„ª21ÎñÏlõúWÎU…8×j²qî—é­¬{tÛµÅh“$ÊpßÄqÇãïJälUÙœ(;s×é‘ùÕ/0(!—U':>W?ãêp§™Á­ÜS{15cê!NÞ-ìݹé]ïŸê>× û&ž×öx"[v€ÈAì>¤×—ÞÊ>Öü„°ztç ÷í]N‰­Ou§ùv÷ or­ò´2yoŽç ƒÛùö¯jª”ah+¿3óL/%Z÷›¶ïOËæ{w‰üSà¿^ .4§(UùMŒzåvƒ€}ûWÏúÕ–Û†–ßËH3W¿5¦É ”­q)wv?4ŒXç¯'Üñ×½z'Ãñ¢x«Ãš–š-4Ù&HÙãk§òebs‚„œÕÅR£ÂÃÚ´Ú[ —Öª{%dß}ÏžEkÊIÏÍÉêP=jh .UJ‘ÏË“÷»ýOoÒ®iÖ:¥ïHff*„.àO½ÿÎ*½Ø¹°¸’ÞLÆQº€0Þ„{cýjõ9•ìy-+ô#1G ùrF7Î[Œ~;žÜÕÍÃ:Ž».ÛH”«ËIœϦñ¬¾ €1ŒrO^˜¯Wøm¥J)ÍBäŒÜ{ǽvW%ngX|¾·u{É-g…ˆËA)f¦GãWŸeGûJ·Í#IÎqž0?½Uã[[4Š563òž}¿>¾¿ž,ú$¾ ŽXšxbLn-)àsþ¾?úÕÉí]îÝ‘Ñì×D|ìÌȬ§ä±ã1B²”Ê,ƒ€Cgž¿ç½Kwkö;™-‘¼Ò­Œƒ÷ºsÏáM¬>VóCž¸ŸçÖ»Nv¬ì$k²ã•bBIëÿëþ”©ûÙÜ›°Jò;cØgŠjˆ®ã-Ç ÏôÍ “)m¼uù²?Ïë@‰-˜à’ÙÀ~F;ŸJA.ÒümÉá¹8íøÒ ØUá‡-Áÿëÿž´ØÔHHO1Èùð­›<‘@ q»hÆàÜåHõ=9ö©1± ¥X1Æ0O¨¦’GÏÀaÎâ>ooÒ¥Îé:‡ùI Žpé×·¯Ö€ÌcÏÍ“Ÿ¼9ï×ó«ñ‡dq ô%Wÿ‰5!0!ÆœŒŽFr ÿëÖ€W˜‰1r1šW±q5­­™õ `ñºyn È8=ý¸ߤî,Ì@í.€Cê0G8⺠ï ÚÏy¢"X„JÆTXÞ:çôöâ³îE“ÛÊЕˆAß“é_¢SËå€r…ï±­zn2¹¡à¨Šh6û†9!¸Î?Cú×'©º>©r ïS‚zž8ü«»ð„*<-§ºÅ•½;Öù³tðÔþG«ZvŠ'Úpè®Ny©=ÈÍA-« LùpA^EWWÛ…GÁÿhã=¿®y§E¨JÊ7mãŒ>+äyÒzhÎnhË} ÏJÖétò²Ã þ<ŽÝ*Ýö½s§ßEuo(Š@¸NpG=*·„.Òcs$ˆŠ£ïÇsŸ®kfßÄ:Ì6‹8Œ<`‡Ûœr3Çãý+êšN’¶»sW• sþ4ñþ«¯iöº}ûÅ, œá8ãÓÝJãtàd½‡ø[zœÈõé×üñ]Ä]oxû=§IV4ó Ú bqÇáŸÆ±]AâqRQ„{ÿZ˜¾ ÒÛ6òU2w`Œô*ø{öÇOÅë¶R  vqû¸ñŸÇù×êÄ?†zwà qoâ]2úÕ0fåX猜‚Þ^ã• ädä`_™Ÿ¶å¾š|u¦êV7°Þ›ØäiV7V*E´ñê~‚¾Ÿ(¤èf„–ºþLüˆó Y®E‹ÄЕãh÷_òòê|Ýq‡mˆß"6 <íü¿®*«"Œ€1ØôÿK¸€p¹vlc€G§Nô¯Î‡Í÷UW“_¥ŸÎ#£˜²”ù™I'Óòíþy«ºvž×2¬0.é1–L\_J«8v]¤>Ü|½¿ýUÖxÆ«VF*ž:tÇ#ÿ¯S'eq¥wcr;³àé7±¦øá™‹6w“Çùú×¢X|t¹ÔÞ$Ó|5qy9#æàñÓ¾è‹H±¼(/¬¡”¦ULÑ©ãÛ=tz]…¶”`‚8NÐUa@ víþx®8É.evwEI]EÙzG‰|K~Ë£Øé„ƒòK+Iûç9éžµ·¦ßëZ”í¢¶?Ùÿ2•·W Iê[øVNšòy¡_¡#9É&µt‰ÚãQŠ0ûm×øK}}Oë™»éctµÔù×ÅÖQÙÜÞÁd˜'x6¹ä®ì>¿Ò°$Ö&:*ÚLÈ-ÕÌ‚$äy?Zìþ2Æö~3Ô!€$JϼA$éøþ5æ·«’Q™~^ƒÿ×ë_UƒÄ×§IºmÛ_O™ó³ÃÓ»RÖÌ#Ô¾Íe$[3c~n§ßüûTîÅlâùHÉnsë€r)Ö6)5˜Â/œçj—^˜ïíßó¦Þ¹Šáâëx]Ár[ëïÛÖ¸o)o±Ñ¸—®‚уãy)û°xÆÜòç^•ðƒÅO¤Ý[„Y!“pa ä| ×œÃ`.â啹9ôééW¼3}-¤±•|J³œÀŽ§Þ½ ."®ª­ ¿ÌçÄÓUaÊÍùZwŠînSy¶»wr1žäÿQþsX÷L™*Tž8RNOzÿœÔÞ0¼šKˆK³;œàާî}Hüª”eŒ@:…pÓŽO>¿JÂ¥_iZSîkB6ŠLf®­‹µ»({)[§8öþ^µ¥¦,*òÚ:Íf<ýåÈàóÜVs”ŽGŒ ¾W9Æ3Ð~¿]Šv´“r9xˆùÓ§?¡âjÜ9j–Þ^†®=bTýãI¿ÌÎÖî8>ÙüªIHYP Œ pÈújg åî giLƒÿÖãô©V4(xÑIo¡cúVÿUæÑ4%&Ù{I‹eºü»qÉÉÎÓ—n¥ÎIòN??¯­Â¢Ú×bã`méÒ©ÊæEwÀ@??ν Ú_UÂÓ§¯SíéÒöXXÇ« H{Áç§Lþuè?ä6ßt׈ð3éþIüë…·`>V#$œ.yéùW¤|ÒdÕ<]Dbë·îÝyç_JüÛ2¨–w}¬á|#yÛgÀýð¯ötaX3m8?z¿yq¾RÎB€:×à{ í­#&F8“õúÖÞ«pÑBÀ’IÉê+óÎf¢~¹^„~µ.^§'ñZ?f’4‚«ÎqÓ­|ñ S[­RK8°ò¤§;I$žãÕïuó§é÷r3s±öç¦p8ÅygÇòx«[]Fî2ÑÈìøuÏ»ä‘SFI7VGØÑ§ì((-%øŸoö9 ³bÃ(:ŒÿÖ¯+Ö¯ü›xÔ/úÕ+´œóÓóŠú ö¡ðÄ:‹4öI‚¤±“° œ‚úß•|ׯ9›Q|¸m£åäàLzðE~“‘ÚXE/62xƒQË7á½5fcM‰7ºdG~x©ûƒ+ ä0Ï\ô58,ª1ó¹ëÐ=9§¨ù6¬j'Œv#ü÷¯£?-ˆ‰IŒ`_ñ¨|•R¥²G'“Æ?óüªy¤Äh €>d$óÈãÒ™*É'å†\àöàq‘@ #ºäbzçœuéô¤k†”¨gb·6}3ôÎÿ^‘Èä(;}r8÷þ]ÿ5”ÎÒpAÁþ_•MmÉ*íRpªsÕ«×|ky£è~lóÇ8ã½yLJ¬”Þ)Ê•î8mvGgf,H#ž9¬j»+"à®Íèõ9<°WPpóúþ]©·WQ_é’yD£ nÚÃ×ÔûVAIÞAæÄ › Óïøçó­7ŒLhpP¼GøW#‚Z³dì|û|¢[©‰B ’IÎyÿÖ«mØä NNIã2ϵZ½‘RæP?vIÜH_—èÇÿ×P+!=Û$òNn¿É¯Dæ̪AF “·ïûõ¤8ê0JòsœíþqÞ¢ÜpÀØü­‚iÑ€%#{.Ó…9ÀÏ¿ëÿÖ £‘Œ…Û÷Op{ýhtŽ2ÝÄ`œqø¯QQ‚Ž›sÓêp3õ§lóØ•÷ûßøÐZCL|§»gŒgéïÛÖžù% !€EëÓ±¦ Ë\pW¡çÓñ§¶âFp:=O'ÿ­@ÆÖŒÆ8\d¯PNFjÌ®ÌùÀ<ª=>µYX«üÊBã½O¡çвm„¤±ó9>Ÿýj ºŸGØHˆ,HîôüÿÏé\÷Št¯²Á=Ô/å¦p8ÃqüëRÝ‘QpTmÁ ì ;ñVåArŒŒ‹$%GÜÈãúsÏaÀ¯ÚªAV¦é³è*ÑuÊþò§†'TðåšîÌa>BØÉ<õçŽ;æ¸NxŸU¼ô3IÐŒŽMz µ¬fŸäÂáÄ`íÜÙ$g=‡¿é^U¨È¿Ú3— KHìBŽ1»“ú×ÍgRp¥NÛüŽzÿº„R.H Ë]®FHfèsìj mئ7Œ‚©üǽSRcónäU9½?Ò¤ŽñÄ`#Ç?/·¿ÿ^¾>ú«œ<ÊZXÛÐU ¶˜p&Ý’[ÿëÔ©¨\Ùê)%™hæŒpSÎAôæ¢ð¾§3³«Œ}ß”c?ŸÿZº¯ hš_ŠüPö—… ƒÊÈdÂᲡzôü«é âà’ÛCŽÎRÐóÏê—¾°ÓÝÈÒϰÛT=†;T4‚ÛPƒcCÀŒ÷ï×þ½m|Iðí¯†¼YqclìШ;Kp3Øw•`Ø’%Œîò !r5ùöd›©R,û,±Êž&”žé¯ÐûáMñ¸ðÝ»´»dP}»à~5ÓjúÈÓmÙç‘Q@ÏÌx§§ùÍy‡Á­OÉП-¸Œägœzût®[â—Ä´‹6ñ2± ¶Óžøï_¼4ª×tà®îZËK †öõ]¢—SÖt¯èöúÅ´·Ó(É»Ë ’Àsž>‚½Æ¿¶&§m¡G x›G³O“í.ˆY‡Rp'©<×Äþ¾ŸY¿{Û’@Rvzç¿ùÿ ìáfbª¿Êz·Ôs]•0 .Võ?3Í3ZyÓŒâ¯N;_óÿ#[ZÕîµá,÷÷R_ÜH9iî<çü:ð‰šiW£àfmŠI!G^þƾÑü ®k±™¬´«‹¸ãbÈLŽ:ŒuèGç^añwA¹µÓïbº·–ÒxUÁIÁV÷ú~¿JõrªêxÅlô>;ŠÄagÓ_»SÂ!F%p£¼c¯>ý¨rò  Ã8ÎÒýiªY@fXœdÐúõ©ÎG?w'©ë_¢Ÿ!PãvÞ˜å†0qü±ÿê®Çáê†ÔK`ÛrIääÇ­rV*ŽÛe;€þêõÔxM”;*¾¤·<^*‰«Å¢¢ìî{.¢Ë-²NÆ$s»ôõÿõúU.þGLíå¼xÀûÀqœñÇç5‡£ê1M•# ¤qŒÓµl…‚'àw8ǯ·樫ٞ’]Q×Ú:YIRWŒÿŸ¥mxec]GäBÌÁÊ0:äÿžÕÌiS pä3näcþ·5×øwQkk*vHùyõž¿áY{ÉjV›³Ä>=[K‹&”¦íÑ8Ï<`wçåpiSjд1Ú4¡rÄ'ÌOÐõï_€¿¸·ˆå»º–\ËŽ{W•jz<þu;h¶àÁãÐcéþ{}Þå—©ÅÞ ûÝÕ÷K¿Cå±u¹q2†ÒéØÂÓ T™ePÝ[iRpÙÇ$ý=ý+*ç}Åë2:—ó>ùÆ:öqì=ÇJëõk}ZÐx‚ÙVR.¢\mVé=óëëX·2i®Ö¬"¸A!çÁpúóQW(«ó¥Ó½®Ÿõ±¼q q³NýGé±Ç,.²¦6Œ³g¥U²½x/ÑQTD¹º ¯9üÇù9­wm7ìþ]Œ­çpêN=ºqÓé\÷îÍÄm´ä®pb§ÁYï³¹¬m+Ý?™©â©–W±d>`á¶÷çÿÔ>™ª3»š$eŸÔ“W¯nb¸6Ë$mµ1ŸÅÀäþÖ«Já¥Át)cÈÏOÏ×üŠã•¹®)Ç“CÔ1ÜB²ï<·ð•>ÙœÀ3+zã'Ÿj†\og%|H9'ñŸòj[GÚ@aŽà“‚Oá×ÓùP·4õ-. ,QÎ3¸7#ùv©íb\ªàs´c8ÿ>• !hù~sÇÓüþy«¶H%._çÆ=Oÿ¯5íÒ\ÒW+JUkF ©fiYcn^pGR*Èc¼¶=øëNi÷ æp(ñ1ÓޘȾÀ_8úús_=ÄŸ‘¯×2Šjž š‹Ý_ï?”øÒ´êçuÔ´å|«Ñ-?̨cfÒqÆIQœ÷ÿ ‘%ûª8S‚¸\ç¿JG"b¤¸Q׌Ÿåøt¢ <–ÉõÀì +Gœ²Ã´£ž=úÓcß u|Œrvœ½¾•#æ ÇP3ŒŸ—ê?:¿– Øä m*N>¾Ý(ä).Xm îÉëŸ^ý)#.¦DG dõúöüªi—b6ö›²2¸'®:Š[xáÕb;£<Ÿ˜×üûÐׇ.¢·t36ÀxȽ;÷¯TÒ¯ô[¨U,PÀ9úŸÖ¸- áÝÖ©{ƒì ±+"‚?1ï[°|1‚É’Sq0|d“ qÈá!ïïXÏ–úšE4®‘Ô\øŸD[fƒÍÚÁvŒAã“NƒR·½ÒÌq\u眃׶>„ÿI£é°Xy`$ª£–^O¡oóÞ¯Onï§Ó;1s¹# §x9¤ÊGÐvˆ+Ž3Û<úwÇøUÕR”±ò îútíÆ+ú’êö¥ÈÔP¨Qßõ¾½j ²;<7E7ä8]٠߯j¬× 2 ù‰'Oz…[2}Ï•€ o¯CXT©N•4’üIW•™W]º¹¿¿yçv¸™Æ ;îlgŸ§J­l¸d#’ç®@àÿ*~ ^Iz»#ÓçP¬ÃlnĢ¡ý:~ð¸åÍZzõ>¯>^Iv±èÖ^=è „l|ß89ÏLWkz”·@Êù‘å-’O^È ÌfÚY²»xÏCÛü+*òé§»„$.ÝÇùÿ>Õâ`ð4èÉÎÚ³ê8‡ˆëæ£AiÓ¿™ë>|XÚ„î`6Npr3ëȯ²¿fÙâj¶Ú–²‹%±Ë}šX‰Só`þUñ·ÀÄš¬1LùŽ9A;—?Q× Á¯ÔïÙwT¶x£¶‹jб ùï_#šÅÃÕ÷g¡ƒÄß.Œáºä}9ᇧ$6še¤J:ˆà “Ç¥x¿í·ðGÁþ&ýþ!ê·Ÿ­¥èwº…µè·T’(ZAó;ëøúOL`Ö¼WÏ?·ÏŒ­¼#û-üA’åœ Ý.m=vu-8òTuäý~•ô_V¡FŠq‚éê~{EzµÝæþþ‡àÁä•ÞÅT1€rG§ãÓ5ÇÇ æ6ïáb3N?O4k"ƒ» ѼcŸÿU1™OÍaÎ]±ÉõçäWÔž)*IöVVp@Ã`·Ö»Í,Þ–Þò=„…ÛÂOã\-¥Œ³Á;#ò‘€:Jˆ;"³FJóÃzÛéŸniJ-¤ÆšLö¸ZÖuä(Ê8&LŸSŸñé[‘x£F†ÚºÔmÃ…P¡¦=2zû×ÎÛ·aw6Ý¡¸ôÀ—_Μœ¹92 ƒü»û×; ŸS¡V¶ÈúZßâ‡l‘%űRv„I7gߌú{Ö¾Ÿñ‡Oû*=³›rÌ«;þì6ÕÉ+œzÿ…|¢åNH0Cwÿ?Ö½æÏA[…Pݼj$UYÞw2‚?ñïÈj¨ÒŠœyõ_q2«QÅòhÑãˆCÆ:µ¨KSkö6fyD»™òG=>éüëÄ:߉tØaH̾L‚B·3(gŽ{ãðâ“J»°…nšæ)bUr0Aã’=¿È¬!«Kk«`nŠ0J…Ç#铞ÿJ÷"½„m–„ž±‹Ûï<¹^¬ï%vº¿øÿ…¯ÞÖøFÉæZ¹+%³+ñß<Æ£ñ¤6“•€‡µ¸Ï— @DYìG'¿·JQµ–hïáD‰ÕÈ•Så qÔŒûÒêRUs#<¨láO¨ôêkÒ“T°î“w[ÆK¢v_wF»™r¹ÔS^bË·Ž6~cb<ÁzzwÏ5JáDS"¡Ûr ü§žý{öüjPÕ“ÏÜêwm`9ü?úôÙȘ£¼6žs’G?çµx3—:W=–èh@¨#$`ôúÿž)×”–É'¾~hFÛ+ A‚Ùàžœãúÿõ¨™JB>PaŒ…9ÏƲ’V²4VF+ @¿ ff䃟¦?_ÌRÂí—~ {¿¯üóP—bUXÛò¨lç<~}ªXŽÝÄ®d ñŽzöãê .ÆÛàåy<|¤{œ}{Ö­´@Æå~nxœuíëYJrÁnÁ}³õÿ<ÖœJÞ@(;çæüúë¾Xe Jûž®SâTšØy`ÎÜHw}ßN½iD<ƒ¼õÏþTÂSnÌà“Ñ$øÕ¨,} Ç?ξN­KųïðôJº²K{=±· ž‘Óýzúöx†{(b ¥b"<Ó>¿­|ã¥Z´ú”q€·`s‘ø‘í_Z|µ†ÚÖÝv„8M£$€02Ïÿ¯ãsZË•Dý‡‡pѧÕù@Ãx[Om§™õ¯)ø•r÷cì‘»f]ª6Œdî?çñ¯My„zw¸c§ZòÓæk(ˆ“¹"ú3Ûñ¯›”µI½O¤Ë)¥9Ô¶ˆë¼!¦¦¢&ù†<:çŸñ®»Ãz1@’N>iñúÖ=ž¯m§ÜÛBñ 7c¨é]<7ÍyªØGxÝ*’Îjãd®yxÚ•däíkÝßÐùSöíø'7†l!ñu”L‘Eˆn Bpœ'ž™cù×ÂOp ìÀyYÆ8Áý}k÷ö¢øMkñ#à&³¥\GóO>He+4n{rµøOo.™}um0c%«˜œ/ m8éíï_¢pýGRÃMëW£ÿ‚3ñ Þ2²Ç6Õš±\æ’S$œG Á=ÇL#O3#ºíÃÀÀÏõ¤S»ü;O'ž¿çÚ‡´`”õç>ÝkêÏ‘%V ÆI烎?/ëïQ¬äàªç›æûÄ{õ¦#"“±ˆVÏÊÜ~?Ê¥•ËÚO\c®:þ0,Ãh`GE#‘ŽÞý*îK W "€Ns‘ž¸ˆéYæRw(«Ïݺ~Y³¹1È’:²•*OæàóÏÒ†­ø{Uo"$Ž@TŒåN6ËšÙŒ›¢Wí ™ £<“þzW)áÃk«[ŠdW“8aÏÿ_ú÷®ÊÎÚ 9O(<€ü¹9íŽþõÃQ.mÍà‹¶vPÙÄd,]Ê‚»Î Ÿlþ¶ÑÈâid$»ýÔ*T¯ÐñšŽÎà]I–“ÌåçŽÀvÏj{â^HT¥Fãíþ–²ÐÙY'cç¯!íÂ#¹ðÿ85™¸¤ä¼à‚sÇ\œžÕµãk6µÖåòh OSϯ¥c,gbí,’0FsÜ};×£x¦rKv0²Œ¸$3sœá½?ZA`]dÁÏïŠtaŽ@ŽH^2{zÐ Êçn'†öéTHõBÊÍŒîÛÓÓßךqQµ•>e`vªœñôü?_j"\*w øQýyÿ=cÚ»]C0yäyè=Gë@ŒXî]€rÜõ뎟ÓÒŸ.ÖDf Øè~Uëþ5ÊÇÌÜ€ñ”éŸ\sô¥-¿`8ÉqþOùúX‰‚2Jĺ `öB*x›ÉŒ#Ü.á×!­SYvª-Œg†#Û?ˆ­ÙYp w,Nh5<1¯]hºŒ Ì.üòNW?ýr+Û4ûñ«Ù-Ä™JÀö?ç½y&™ee<‘<ÐBãøgÂ:c©ãÿ­]f†Ï Ý<Ÿoµ¸ó¾¸±ÏóÖ¾÷'•l*Q¨ï®;~'V©ËÙÏc·tiÁòÃ2¨É pqžþ½~”ÒïdÅÌ3¹È;sž8çñ©¡Š;«i&…•ã#!×£~]j­ìm*;p¸ãqëžß_þ½}ƒÚè÷4¶çšê÷(u)Žò­» ç•ðؼRÅIÍ«3ëð” j—D~À|;ñô~#Ò„±¿9 ŒØ|UÿtøžšoÂïøJ7 s¯^HÍî@brsŒpÆ>¾¾ÕÈüý¬î¼fÑj0¬ä¾ã6ΡG§­|µûj~бþÐ4Ó䵌%¶’'Ø`ášABž†Ÿ©¯C,­WR&Ô]ÛôÕ~6>s5ÁSÁFuâÖªÉy½Ü®|àå·dCeFõÿ>õS†R¤õô<ö«”b ” ¤ûcŠb7,@ ÏOoZýø#¶ð—‡.5 ê÷qclp30sÔ'¿_þ¹®4)dÀl’XgÒ½GÂ7–ö6ÏòÉ0l¦H\GZóûV¶¼žÝŽUdeŒ(à€Ç·à¼WÔæ˜*X|¥7«ZëÕêc.ismЮӔbBí<Œ¯^8ôÿõÔ’"³:íP6Ôàóéþ*B ¬pƒÀÎO¡çž3K®ï»†àg§÷úcõ¯–6'³°}Bú“a2È 1Ç<ôÿë׺kÂúçÀz•«'•m *‘„ m ÊÜsíŽ}kÄì.~Ër²°V#7}±þIô¯[ºñI¼ð%ͼ`)Á!²1ÇSÐW=TݬmNÖiž¦­Ã&çwpwHÙíÇ—j¡-ÃG}“(̯¨5­hÿñ,p €Tr:ã'¬)‘m®™™–BOÌ¥³žyôÇZô%M ¾§2i¶‰ídû-É óÉS‚O?Ôþ¶„j¢RKyýÀØe€9ÈäšæÒyYÅ—dŽTçg^OùïZZ}ò²4=ÍÂ猟QÞ»0µ)>juv{y?ò{3)ÅèÖ¤ÆÚH³¡wm%Ac‚9üj¶Af”™À Ž–{øUÇ‚O%” ù ÚîzóßéU£DK r[»dÇéôük’ppi4tFìk?x†@'àvöã5 Ò å{`‡ÈôÇÖ¥g*íœäò­Îà{uþu‘¿’Áœ°?ÂO·jÁß¡fùÊí=01‘\xÚœ´Ô{Ÿc᜛ªÈ¥FP@9 8ÀÀôü*ä Ç'9ÎI5P¤{ÈÉÆõéŽô«è¥FÐ3·º“Œðê»A#ô ¾<Ó”»º‹kyæ¸ù—¦9¯høiñö=f+i ,y ÃôÍx½­¶lt=–ºßÝ2j0ª€rò3ëßó¯šÇAT‹•®ÏÕr‡*QŒÌûbÛRóô@ǯ'×­aøVØÃ;Ë!#.X19ãŠÍÑ.ä—Ãð!bC|¹É=êêŸØ<Î$ÇòIâ¾Ný§…FPÚgS£î´ÌP$ „uô¯eøO¡K_Žf£ òžp+æOÞÝKs Ž«¸2ãÌbrÇ9Šû{à™.¡sËÆ»0 äƒÈÏa]øJ~Ö¢ƒ>7‹ªÿgàœ£µ¬{&·£¥ß†ä¶q•eP1_ß¶ÃßøW_üImEm/îd»„6ß›.sÓ ?Zþ„µÙ²…uøÉÿFÒÒËâ>‹x„Bî'‰˜/8Êüøþºû¸/«f4yv’iþhþj¦þ±€­öZ’üŸà|:_.Œ£/׿Á$Ž£'¯zD¸“ó; –ç¿?…(•&\’N[¿éïIö…ÀP³¨Lñ’Fq_\|Èá.ü‚œóŸþ½,‘ù%œò½r߯ç ¦ QŠˆÑNzå±Cò™ùT'÷WoQëôþT$‘K¸ã gþªAnêë¸ò2 9$Çóõ¥O™Ã0]Ü€ÇôôÍtt+{jé GnzóÇòÿëRzWOðæªê²Ã í~£žxÇøWeg­\iÐl‹`g{±nÂËy¨A*ÅçMÆçb¿Ìgýzì4›Uc¹–+™ÈgÚr:à|þ•\Èk}»KÕƒ Ë –ÎݧÓº ;˜ï¦Hóò©Ý•<çÜÏ­rðŠêWÁ.mÚ8í¤Û°CœöÇAÿÖ®FðÜšU¸žWc Hð3ܯùíÈù_ÂΈ¹&xÿÄ”ðˆÅX¤ÍùW%8UÎJ¡'%ãÖ|DW‹\RG;06ð1ÿÖ®Y£1°Tú àñŒ~u×OáFU5“/½”ò[;öãœ~ìªH¬˜Ž@Nã§~”Ù`@$¸#®;ãüþ4‘/Ì cçA÷Íhf/™—A ÌŸNþ¢š%Û TõsÈL~4¾Vw6¯R ÎO>޿ΑÛ)·%‰#9ç¨õ 0†PwCíÏ5&ÐÈ›”rpª:1Ïzj¾é?‰ï·¯^ãš~å$‚SÁþëú â€$ˆm1ŽY¸Ãtî:ýzU‘¹b’U½Ψœb1Á p$sÓ§NkMcfó|¿öIéÿŽÐ4}>hVÒ!“MŒé‰dÁçýïòI®‡þ¯…®¡ŠY4´WUଌqþ×ùæ«Å¨‹•÷ 1ãi$pzóZ6W${Š€Ã$ñ‘×Þ¿¡!„ÃÇì/¹e&µfŽ›¦èZ5¢Û.šL|2˜ÝØc©À'Û¿¯·gA°X9,\ŸçUP2lØë•8#wÌ1ƒ×§½I¾+”u—7âÏõú×Z„b½Ø¯ÀëU*[âüNcS²Ò¯A Tî óú×/s¢h,Íê©‘´ÿõ¿¥vßÙÛÈCƒŸ”~½ø¤tЀßszÉ6G©÷íüëšt£?‰#™ÊǾ Ò$·e…_w9c“Ç>æ©Üü;oîçu$¸ã žõèòê: ®ÄJòÈ¹ËÆ‡¯PN?ýz̼]f‘¾Ñ*†Wï(+ÿ|ÿŸÒ¹ê`¨Í{ÐAíÑ#«Ú5ž«%¾W(v—§¾xÅmxGKIµKv“çD“;·=Çáô§ë¶_hñ%çwÛ—þ"ÃÝzúWká“*HÈT3ݹ¯ÂóG‰«)l¤í÷Ÿ¥åÔ9Ôg%¥¥þ ¼éQ°Øƒ•##ϲ+Ýßâ±°)ÊNG~ŸáþzWÊš©6‹h‘Û¤dç?ý}«jçÅr¼eXlãǧëô¯Ìóloµªù6>Î'k³©ø­ã'×­Ìrݹ¸ qÏn_¥x¹¨Ûé!•âN9–zV¿Šüe+Þ¹sÇ?‡ç^Wiâ(µ_Û%Ñf‰„“änù@éžüãó¯3.Ë«fãNšøŸâtTÄÑÃGš«²þ¿-Ê|Wqla„:€²ºŽ†I\u=«ÊLŸ2ɽ°NKmûÇ®sþzœu¯Yø¹m¡6˜/t W”e|ƒÔ“‚:ôä×’²>^Þ'9ôÍ~ÍÊa“JX;Ú)·ÝÿHü‡˜Ë3¯*ö´nì»!FT@G8R9éŸðªòíPKœ’vðÀ;þ¿ýj² !€.Ü20G<ÿžÕZëù~O 0Ÿ_^™úלpž¯¢¬sèHþ^Y£EÚ8ÛÉÿ>•Ãx·KÚ¹ò‡îäQ"ù`ôçƒþ5êz•f< 콌®mÕšÓ~$@ʑܞ?:óïF&†ÞD}ÌNrrp1Û¯ùæ¾³9Ãû4%%f⺓JJjVèÎbUv>XR6±àz®jH£Xå À7¯¥D„¡2„ ½J`ôç¯ùôtq®òT°bÛ¸ïÏ®>•òež!°KQávDTÔdœ çê [ÒuY™.,× ™pAŒNJèml¡ñ…íã–aÜ`´rºã'-òž:tü…ciºõ…ô "Fɸ®e'$`t9ïYÓ©®»¢ì÷D1HDW»2¯$l““Ç^œ~¾Õ—>Rí£c“ÃcžßŸÒµ®<Èdòö¼là…ÉèOÇùæ±ï]UC·9ž}EwÕME.†jÅ‹mMmƒ€‹—o˜7Bp:Ó¤š®d‘TF0qŒ¾çŽßÖ£µ‹s0Þ Œ`wéÇÿª†O=Pçàñƒßëùœ×} :Ü»òH®Ë!‘YB„ Ü^Ÿ_Ê‘HL®p8ùW=3þȨ’W+‚…×,HÝúbšÎüÉ @ÆGN¿ýjÝ&Ö Ù !\}Уs`‘*;—ŒG>ÞŒœòOçëNy”m 2[húöút栾ˣýæ*ÙÀ} T>ÂèfùLªû€0 Æ@õü½ª@ûˆÃ|¥GÉÆ3ëÓëÞ¢Ž5ØdÄc’6}{Õ‹"rÂA¹†üú¿…JµÅkèné§*…-Î:ôuÔÛ”ôÀÿ'ò¦ÄC±.3¸`ùRNO ÷Àùr‡5ábgí*ò£õ¼á0Šý†Ûdb>`IÆã¿OóüëN(ñ·<zf¨ÙÄå¹#»ž¿JÓ´ÄŽIÆÜò+Ï®Úvì}.SIJ ÛviáaŠ5eäóÇé[• ¿‡9ɬɿ3Ê\€¹çй¥çíŒópO§qú׉SX;Ÿ¤Ð\µ«<#© ­:ßrv$•9Ç'¯å\>»âñ'¬t€Î R&“=]Çüâµ|ò¦ŽNÓ¸D2G^IÈôÏ…~’ïÅ—WO’"åÉÁÇדÍ|¬b¢Û{ŸWuóŸàŸ¥Ö¡fW\ƒ‘ߊûçàæ‡“¡[(POë_"xIY¨ÐuË®Ú%ų†ÃT9îp³ÁqapË,Oƒ’Žséé]…|PtyöH»áé’:9ïèzW©B‘ëqïMærò?_¯ó®w)SÓsD”½NÁÿïô´Š Ï cv ?–yëúW©éÞ&Mzu\3yœ õè+™ºðÞ¤ŽªªÕ€Ë0è½?ÿ•TV“F}$ø°œv㟩¬çim£-7ö9ÿ‹V")í¦eÀÊãñÏ—â=+Ï%]p½Á!O+Õ~(#\è±LÊØWz’8çüñ^S‡Üe,sÀqøWE?„Îv¾ƒÙ[¨ffÛÚšŒ¤‚NÕm ý=±IbFÊ•ã+þ}?ZÜ_îþ=ÇNõ¡‹†Î>eÎyãÓŸÇç¥b±S€®ç>Ù¤M¦7SÓ ç'>ŸäRº Ç–^TŸò?•FŒŠÄ’FqÀþ6I;°¹È—þ½B„¬lzr>½O5,ƒË;Ž÷d¯ùþZpO1™IeÝÉÚ1ïþ5lÜÆ§ #ïµr?•TŽ qò•É8ÉÎzîç×éÇ­,®$°“útþTö>·,*Áa‡X íïùÖÆ{)T” m çsc{ÿ/ð¬¸ã@ˆUÙAëÐçœu« GqóðÜõ=úÿœWôçÕÛgÏ*¶Ð±ý±"¡S&Þs•ÏåËò§q!œ‰;w ñëÿÖªOnÍ´·'äãҩʹ&5<sÆîØ¡Ði‚¬™¸|QöpVP%@@¶÷9íüªº˜ohã‰+€¹ü«™§Œüª<¾€ã×Ú«Cx~×±X†cœ7ŸÿX®YC—âZ TæWêvvr$h-·hÉÆ1éíV®¬íï­€)¦ Wdçv:ç×ʱ<1Öµª<sóŒ`chçóê?­u²hï¥Ü4nWzuA‘ÏМãžþÕÁ[J…Õõ;¨áªWiµ£8›®«"ƨvß*Œ+ºðþ’`…$`6®3ÇÌ?Æ¡{#6¦ev@ËÎâ2{ôŸQÜÕËíV+x cR¤œŸÄ×òÿc¥,M[3±û^‡%ÅöF“ÝC ,ͽ˜³œÿ_׊æ¤ô¯ŒÃàêbf¹ZU!FÒz âß<“’F}ùÙžJçØ;Ô^Ógk!x\‰fÊ„’Ã>¿QŠÍдWñ—Š´&3ûÛ¹–`¤íËr~˜9>Ù¯iñÏ…´ï ø‚ëIµŠAml±lFsÝ““×$“_²ðn„³AüQ‹—ÜÒýO‚Î)â'‚«˜GøJJ ÖJïîÛæy‹­."Ñf€TÇß' îõí\ÈÎø,Á8 ý>¿Ê½Kƺ]”¯ Ý Ž•98õô'òüüÍL‘(7eŽõÏ?ŸÒ½î*‡&6:ïù³àpÜkÌÕ—nà¡FU°GÓ·áÿצ8#©qƒÏCôÍLñFO\ŽÝ5§áÝ1îu% ¥­×%‡AÐ÷?‡·JùL= âjÆŒ7“±×&¢®ÍmÖZ|YÊ(çÉÁ$žyëÓëUõ]U5WŠF‹qÆÜ€õþUÐßè’ÜA¹­ÏdtÆ9'OÖ±.<1Îß™Pÿ´[Œv5úni“ÕÅS¥N“V‚·¼Úü—æy´1 \ËVs[ƒÌ¨À0ðÏóÅNŽT æd†%›?‡Ò—Q³sy,ØU\˜ãúzŒTHÛˆ’1»óþŸ­~]Vœ¨ÍÓžëCÓ‹æI£¦Óµ·¶P¥£xNÃÀ`IïùqïïZ÷Z$¢huKIÌð¡Rè[œôíÏùÏxnÖ+Éæ±6Æ‰Š•=sׯLþu³áýJóI¼’eAÈ @ÁÏ$ñúñ\²Ñ»nm¥™­©ø–Ò+ƒÓí º€îS%òÏA\¿‰µ+K¨|¨ìcŠp~g@ ƒžÃòúÖ—ˆô›í‹‡8bø|Á$t¬+âK§fÀ¸<ôþŸõµ±ÕªáUDî’½—nç"¦£Q²¬32°G ƒÂÿ§ãþ5zÊ2`ÊËgéóvÿ=Å^µ‡QµŠ5Ší4Â…eútöôõ¦Ë¤& ×1Fª '^zô¯Ÿú¼Ó»GbjÛš§Âæh–e»Û!.Uyéׯáëõª-áS¡hÝ3¸:ž*Ä2´;[ÍÊTÍÐñÁñýjHnFòeRIÉ.I'ò}T^Xé'R“RëfÿÌâ’¨¥î½ ét;„V\Ž 0èzpzšÈ¼µ¹Â`‘‹á÷ü+¡ÆÎs)VÈÊô?ÔþUÔ¸|íÉÜG^•ÁS‚“惒_"—:Üã¼¹ |4QËí8ÇJ·¤DÏ!*’LpÀð?Ϲ$¾\Nr…;³Ð~•I2€)N¤ŽXyéþq^)B”¢ÏS/¢ëâc°å0W$±`ާ>½¿úÔÅæÜTóÎÓÇéùQrÇ€ Ïq犖Ñ~ѬsÇ^ŸýzùÚvêHýN¯ïg <6-F˜U’Q½7}!á}rÒÇŨVa™]‚@àúÿšÔi§ÄZ@ßïWåÍÿÄ쟉6±ù„*K‚œŽGç_Niÿmí45e9Tåƒ)õÇ}*¨T©‡’š[Ÿ‹ñV b«ªWømùc7Žl£VFº‹pì\f¾$ÿ‚ƒêöÿÃF6ÌÉÆ Ãm>[`N•ò‡ÅÿÚ—Å:‡ˆ&.ªðBœåÄAÁ>¨}Åxï‹þ9x»ÅUÅž§ªÛv‰Ð©‚0z(<ä÷¯©¥‡Çf ”S¹ù»X®S\ÍÊÇŠc|‚½³´öçñéA+; [¨ëÏÿ«5$çs>ÀTÞØÈõú ÿ*€Yvcq<}ìÿžs_¢#ó¶I2ª+)>Xa’–Ïc?ZjÌ«4gšÊ~ö}qÇ?J|«ûµÛ”sŸœŒîÈöõõý)¨Â(bÎNàýNyúÐ Š~vn¸ÎqøsÇ_ÇëM ÂN`¤ä~—éL‘wL[‚ÛÈúòjÆò\)Ûß½ƒÇ ÍWßå3d¥užñ”úD‰>|ÿVñßüó\Æ6o €ç¡?#ô¦í-&õ\÷ þ¾ŸÊ“IèÃcß"×.õí,¾™ɹrÌ$ {~?•sþTšlÎ×Oûçq#zãüñ\_‚¼ssá›èˆ}™L‹´e‡ÇæÏ_rÓÛAñÝšß,gíl»›ù}xÿ==+•¯eÓCdùÕ›8O¡¼ð¥Øž?-Ô œç§ùõé^2U@89^\qþ@¯ 5ûHŸL¹µ·½dÂ…·¹ú×ƒÝÆö×SÆëå²±B®ÈsÓNkx;ÜUM&WŒ)ÎÓ·œGN}Öž6£̼‚ß7CéÇçBFcdm¡\ŒƒøgÚ‚Ãb£:¨œéØÖ†BlÝ´í¡Pü¾¹¥Ä-ÀL¥º?JG6pø.>èôü©‚F$åèOooë@ „!]ÌòîNyüϵ ØÑ°Ý´’0§ÿZ•QÕ>`¤cn{ϧ׭)%Fõb2Ù8>™Ïó   “/€BŒ`°çŽ¿…?håñ1¸4´G)%¤°³1TÉ!{gÓ=ùõ¨<=a5ö®ŠÑŒ°!»×W&5Ô¢3£"ýÔãpÏ<çßõ>õö’t;»kèØº‚KevõÉüëæs¬E:y.mmtzX 2•H´´¹ÝøCF_ ø¾Oµ'î®JH…ñÏsÓ¿#ÞºŸG—žz)ýâ;œúú×5©ßoÃÖwp K»!Ä€å#ƒÆ†¤³Õ?´lÒWpC)àò2 ö¯Å)æxŒuE;k³?C¥‡§‡N7F»©%½Ä™QˆoNü?óŠâu`ÏœHÚTnƒúÿœV—Ä˱c¨Æ¡ˆ†ÿhþµæ—:£? K#>ï^:ŸJøLn rÆÔSèϬ£‰„(E®¨v«­I%Â-wzcïøV;³Èí;¾ñÆxçãVB ù|: 'ó?çëQÊ6•Ú¼±ž+Ѥ£M%x5éÕ—4å%Êzÿì·áOíÏ˪IyZdXVc{‚X~*§w¤½ß“_æ~ËaS‚gJ þëŸÍJÿ’±ò¯ ÃW, ™TtëóOÖ¼…OÎJÇåwŽ09ü{‘^ûñ'F‘|%©¹9XpAžy—Zð)”´Q•ù™8féŒgµ~¥ÅíKNKùV6acÉvCûÀGeŽ;œž:×Oà¹Yï 0¾N mœp=Gùë\¿fÜ íyPxç¿åþx­ÿ—Ķé*œí9ãiýkæ2ºÞÃJkºüt:gh´zlk+FT˜Ùˆ$džj3¦ù¥Œ`üÝAëÿêïØWYÿ³ns"4cûÛrp?ɩDž§’lÌ8PS õû{ÄAnÏ.4z'ãý"Ki­¦ UYv—åŒç§^k’mƒ¼Ÿ»œóúzŠúÅþ —TðÄÉ2ÊWr¨MÌÄsèqšð7·hçL ȬT–àƒÏoÃù×äÜG†T±Ž¬6—æz4SŒy_BÖ…r–ú½¬ï¾ ©á°N?‡ó®ÛZÓ¢™÷¾hlŒç?ÌWG—9dÉ*G?Â:qøwâé§$#ï¨uÉÎzwÏÿ®¾>kTθ5f™6± ’ýŸ°r¸ÀK™ÙÄ&&<€NxéøžƒøbHÞ5Ú&Bß/Ê8d×éøWDð¸)¦ÒH¨Â¥ìÏ2xæ“ÌY û¬ryôüé’Å @`Š9 Ý}ÿÎkÓÏ…VyË‘ä¸È$'9Ïמõ“uá"±ŠÏبQ“€8ûWð˜o²ÐÕ:šÜᤋz‡@p}ýzgñ¨¥‰äPwœãŒã·=+³œ'˜€¶2 hH8>Ÿ…Vo—r†'Àsœu<öÏó®OaE+_ðÆhäE¶àd·ññžzÔ‹ ʼn\ `ãÓ'ç]%î€l‘ä]Šé€2=ç\Ü’>ü’s‚¾C=䦣NOµÈ°Î*Uä2^Q¹ÛÀ\è;Œþµ¡§DîûØÀî+9 šRÝ'ížßç½nØÛ·c»¿BÇÞ¾2¼”aÊ}ÖM‡–#ê¾…íÛÏ™w#Èôã5½ ÙuëÃ*áb=rxê9ö?Ð×-ZÊT¥c¶jDÙø±xoš4 ™&PBŒëþqŠï¼2WCðÌ®ÙsÓÛ­q>*µ‡Vñ•­¼Mµ"úgæÀ~†´ü}®C᯼rOåM*€ –Ÿ§Ò¼¦œ”i$zsjr–ÈùçÄ^$’ïÇwÒ‚ yß)BHÎr>¢ºmGÅ·÷b€äàíÉcòãÿÔkË.î$}Eç}àÉ)mÙç“ßÿ¯^‘ [ý¦Åòs¿“ƒŠûüÇ/† Fij•™üãG6xüÇ›ºrvôZ äm$­ó0.9Êä}+6æ"F]ˆÁ¡Ž¿_ë]Æ£¡´,ß.ýÀœ }zûVè“HTùl@‰¦×½m…ÅÓåßcäqøžÑÙ\óýNÉ¡!‡9ä1ß§³ú÷¬ÐÌèÈÀž9%NHãõÆ+«ñZ˜„Œ‹ öÀç“Çø×-V`ìFáØv9õúúWÒRŸ<‘ñµéû*Ž €&Ñ•ÃëŽr9ïïÖ­Á‘ˆ|‚I'<÷\€0ªÃ±cA u‡§ y0!Þ 9èsíÚº ®Îr”¶@ïÛµ—œ!ZzV¿uá»æš#å9;CÃß¿9ý?(´ë„‚à³âFàœàç¡Ïéù×gaö-ZÝcº1¹NAüGáRßq£Ñ|#ñÃÞ1¹Š=Zaa6ìNÒ3ß©ïõçñ—í á­*ÆóOÔ´‚ÓÛά²Ê=6’p:äð®fç‡C½ŽHî^æ6?ÇR9çôýkgL¾·Öô©´»‹”‚DB^JžØÏ^? ÁB0|Ñ5N÷Lòð›ü )^€œ£>õYÌ›w'¨kê:oÙu -Þ=®§½ø'¡ª“[Æv®Pq·¿®*걉]ƒ.1³9Âà‘ýqÅE±v†qÐÁö5qíÑY0C¡Æ'ŽFi‹ùAL±$¸íëÿÖ¢Ì áPÄ­žÁÆ;ÿ)Ü–Œ†;?„¹ cœ}1Ry{UŽÐû±œdú`òqšg–[69ààŸ¡4€sÊ|²»€ç¡ã‡5"̸£,}OÿXT@²¸ ó„È ž¾ßÒ•#  Aô;E}ªšSKaнœ`z ¦Ç¥0É’ †Ï|ûW§¯…—lªQ Ïã¾ùâ¤O MhÌqFP7Œ}=Ïçû£Í"ÞâX+;œ–ƒZ+ˆÀ'œb0­%ÿ†. ŽF†$2nn:gß§ojôxüµ·F»Tð@“޼wÍh[é²Ák,SDd$°í“Éï\³Ílî™k©âVvH/#Šn$õÀÇ¡úqK©øNY­¥¶òƒîèKÇOËé]OŠü?»fŠ6ÈcòãŒñšØðÆŸ=呌6ù²S9öõüëä³Lb«ï=cIS|¶<ÇÂQË–Â`¥Œ òy'õ·eᯱ_¼9Ûo&^îôÈ$R ï$ðK³4ñÅöyAË#7ùÿ"µ¬4¸ÄWJÄ’ã>ŸˆükÄÁÔ§NNQµ™èVRqZê”þ:‰4ïÚ@@ÇÙ”’€ç{gÛÓüšò´ÎŒ`\“Ïjýñ'­ÅZX¶¿²]BÛã;X`¯Üa‚N‡žëçOü$Ñ|'ã ËQ§bßp–yY°§#{Û¿§zùüñBŒ¥Œ½ÓéÔô0œõÔi-ï±óÔLí#!ÞÚ;çžœöÿ Ÿû6êv!‘·pPœä`žõõ—ÀK—^ÔѬ­”,jÀ+óqóšú M¼ IPq‘è;•Í¡GB5ÜùoÒß©X‡:5;^ß/ó>øE£øËCñ­Î•¢ÞÈŽÀHE¹§ÈsŠú³S…õÝ;gG7%•Î8U äôö?wgB¾fîräƒ×úõªí¿†6íò×<ä°Ž8Ͻz40e T1–n¤ZiÞÛzðÏs*xeÐkÙÊëUwgºO¡ó§Ä]Aà=q1çì"•ÜÀ88éÀéÍ|w£YÇ|JÜeFwÏqú×ꎯá}ÚEüJ¡·Û¼O(!ÿ=ëò×NÓK›Ë)%h.YÐr:åkõ oy›”y@àʤ>€ŸjùSöíøsrڇ⬊Ãg#ÛM Æ >6ÉÁÿšò±9ŠÅÇ•Êö1Ä`Ôi¹%±ñoÙþLŒ—S¸¢ç§§­z§ÃX,|C¤›yŸý#ÍhÔœ¯ŸÔ×–ÎÈPFõã?Ë¿ëZmì–n"™¡xØ8`HúqŸÿUys2o“áè|áWƒåî<÷ÏOoΚ~ K1‰'ïÏåô¯£æðrÈXmY =27côÿõ Ê»ðDÈ4D©9¸Î}x9ýk'›É½…}N(ð¿øWpÆX$8Àä9'ž8Æ>£ð¬éþ+YbHÔʹ ð=qOÒ½å|6 ¦3 ´›² Ç'¿>¿aVgÐÌ…ø“¿üÿ:Ÿí‡®£ú¢¾ÇÃ_´Ø´t‘Bím (=ͼ“o˜[#åàäØýk×ÿh{Ó‰ÒÒ/– ðQ½‡Jòq‚g9 þ¼ÿoõ‰ûIŸKF8Ò]Iàˆ ±ÏèG¿jé-`v•ÚO`SYúE¶X9S·cœã¥uþÓî§ j2IƉÿð1ÕãÌÚÙ§ðö[ÉM7ÖǪ|%ð}¥ÌÏw›äØÈ-œþUôï‡mãÓm‚ÛùpàaF@ãVf>ƒjŒÜÍoNª1žÿý¥}]ákK}CD€:R2F1Šø­kÉók™â^æ¶>iñ¿Ãý—Ü­±† a˜ŒtíÒ²-| sák­V›6‚HüÌbàHê8ëëë_[ÿÂ9gd¤ˆ–HÇ;\f¼7ãíꮉuo ÉÜQxä㚉BTÖ¬2üÓëµcN1ùž¢ßBþmFáŽÙNá죂åÞ¸øŠûǺû< !±‚ ‘E·©ö­z†,STÚL 䲑ŽN@þ•ušï†£E„ÙY[Ç\¨R“Ï9õÅ{Ù<`±jRW·ácÆã\ƒž„à`Ó>¼ÖÞ±§›b’dH˜t<ûVVCõRrp99?ýþµq5f Q¼¸ÜÙ£æÏ<û{V¾‹8TPïó§0t’ F¿1Æx`ŽG>¾)ñÎm6•ùsØçtò³¦Üì[µµê‰ ØxÈÇøð*¦«áP·6@‰­ñ"°'’9Æ1íÓ½dø{T¦ ÅDƒå=ÿ<Ÿò+¼ÒõBÿ.ñ `÷Ϩýx®w£V4^÷©æ#¯|«Ò6ÊAWSÀÎ8ã·ÝýkšpïË€A_áëׯÓµì¾+Ñ-µ>{ˆ!+1L°Éè0N+Ê–TA8;[68âºiÉMo©2V³3míˆSÀ%;dýÞ¼ç¿QOxÁ$•#ƒ‘Û¯LqùU•X••VO˜þ¸úúT’+pÃ\r:ãüô­T(Ë–à1b[œ/_Æ£kfNT)ãvÒzó×ùUÅQdbÛW¡'?ôâ—j€…‹1n«Ž\sþ*M&À­äeY[qr0¹có}?Ï>ô’yÈåcò‚ߤd,Ÿ.A6g={ÛéQ˜B|¾vÜvùxýGò¥d3õ·Ë‚ê&f³A‘ƒ¹øÆ8è:}}jK]ÚúßlQ 䯣vHéŽ1é_7h_µô9Žÿ@´¸í'—3(Ç·\~}oXþÖúU“n¼Ðµ uÏ"ÖEp¶H'Ÿç_}_%Íi«¨_ѯó=:y– m';|š=â/ ,+•*WƒÅ9ô>åUW-‘¹¹Ï¿ÏzòÍ+öÁðUê,WsjvŒÙÛö‹_0m㔜uOÒº}#öð>±å}\>j°9í¤R9úZðka³:+š¥)[ÑžØZßÚ2_øSa`‡Œ˜øà3ËŸÒ¸Ë=:çDÔÐÀÍÆÊg<ÿœW¿ØxžÃYa’H¥Þ2Ãצ;q\¿ˆ¼¶CSr8½hÃáÓ‹%ò§!»Ó½¿ÏZo‡Vê6#phÛcž?ÏøWkj‚ItaY8#C\Q­ÉÔê’NÇ5g¦[DêþH•AAÈVõ'¸ï^ûIÚZØø³Gž;%n­[Üo^9ã𯫿°Ñ˜0j8èÀñƒÛëý+åoÚÎþÙüI¢ÛA*™ ‚a(Á~eÀéþÉWŽ«*´'ïÿuám±’)ü ¼·¸ñåý•¤1¢e«l†*àž^¸Ïµ}káÙmò$EÝ»°è=ëä_…÷Þø¯áûëv+ìfØ‚ÃçêJŸOº+îåd+òîã,€œ3À?•q`12§‡ŒcÐÓ*­œdÞ•ÈtÞ ôˆþ#ƒîjö—£yD$’˜¤9ê½³Ü~­vSÇt‚ ¸cÎåÏÔþujOGr­²Uóv“½”ŸlfºåŒ›Z³™SOTshð”Ü®®äpœãó¯ÈïŠÖÇÂ_ü]¡ò¾É­Üˆ„_(ˆãÓدÙi4´²ýåÁóXñ€vñß·= ~CþÔúÚí ã[)#HüÝAîÒP$<öq[á*¹Ôq{Xñ³XZ”eÙ•´ûo üD7F Yä½Ê’cŸîð2z’x=sXzψ>xÂN(&·žÑØ­ÎÂ"—*W!º†õë\ÐŽ×OåÕ RF£Z³’qÈ9÷=A?v¶~?µñš.£æ9”…rdÁ>„}~µè¸¸­5GÏEêšÑ£õ¯áÿˆ"ñ—‚´]b·¿µŠãg\U$qÇ"­êžrÍ(¬ü(Ëéõ“û?øté|R³Ó`pÂ;~Uéfù[;‡á°G¦Ï¥|ÜæÔšGÞGáR{œ•„ð‰HØ|ÁÔ6ãœtéí\oÆ_\xëá—Šôƒd³½Ý„Ë hJì á°AþUêÒYH²må“«Ý@éÎyüjI­´‘…#d‹“ÏQ?­bªÊ©Æ¢³? ^×É“dÉ·†Lî#®AI¥(¸½ŽÞOHvÕÎ:~_¥zïíy฼ ñçÄ:m¥ºXÙ?Ùî †!µ0Ð!sŒñ—ÜO×=ëÊôÍ&;·'íiÁ¾EØÝ¡ÇWÔÒ¨ªSSî|Z~ʤ¡ÙŸK~Æ#Ô|5ñoÍk#ÙêÏL]X"•Y ‘Ç îõô¯½Mc.ß16Ž@=?õówìuà›xüOiuâ;4Žý• ‘‘ù-å¾[{§¾Ï“Ãn§.cž§¯aø×Íãk/i£±õØMQWùh¶R’%¸“Ÿ™Æ<ÿŸÀÔ±Û8fCnzuo_óÅu2è2Ç&d·V;DDÜ ¬–‘™v¸ÝÎ~uì9ÿ×)¶®™éòô3­tø$îÈÛ!Á?×üŠYm›¶h3ŸšM„éƒíé[kcâ¸`89*z×ð&% (<¨¯^µ›«'³/‘lÌH´+ ˆEDÝŒf0)©=*–¯à¸V3öeÜ[$¦:gü3]]­¬S L’~ö0Aõüi çªDŸ¾A?¯ò=*yÛÙê–Gæ—íƒð;[ÒuH¼Gk÷:RF"žDµlGûÇ;‰cæ_Ï5ó0³ã9?1\ƒ§Cþs_·Úÿƒ´éÓX]ÛC<3­Êo‹èCg=¹òÅïø'•µÔ¦÷Á7°h²å‹XÝ4’Û1$ck`ºcŸáaÏa]t±N1äg¡‡•7V.·Câm*ßä Ìḽ3ÀQCg©A϶WbÁXýáƒÐð¯CÐÿb¯éú:ÌV2X¡Á–Öã~þ} ØÇñ‡€dðG.´ýášæ[ò Aà½AïÍx¸ÖÝôÐýc žåøeF\Þ‡_â ’Ái9 5¹ß·¦@Å} ðX]gð<9 Ê—ÉÏçé_,L·þ'ÓÑošÚå q÷9'ò®‹àçˆõ¿†wÒØê—–÷P?1Ù·rA9ʯç^)(Ù·¯n§©‰Ças*^Æœí.—Óå©õ¾µqö[g.Àw9óÇMS67D]œ¬`â'ZõwÇËq™¢† ¹#ðZñßiw>=¾Š+¬‘˼‰;ñøqNOÚÔIl²œ;ÀEÕ¯¡Ëxs@6šE¬g?i™²î¡?^=«Õ“ÂÖ«lµ–N>ø.`pF};Uß ü=m:Þ¨ÅÅAÚàç§ëª:}¹ (FÝÇ8ã^Ö3æ÷>‹ó*X©Â…))%¿©æú·ƒífµ™£ŒPõ`~~uåø-¯«øðSM·Ñ-ek×p$'•ÂñíÞ½ÂëᵓéÒBaJ¾Õ—ð¦þÑíÕF:ö¯OgI¡ãŽ+«-ÁP¯Cšz³ç3,~&–!Æ.É?ðR?ƒIáf°Ö­âÜ­rb‘–¤g%±Ç#éÍ|4k† Ør>ÿÒ¿j¿à¡þ_|.¼Úªe„ˆ ã g5øµt¾MÀU;¶äãÇ^«ÞÈæã ˜wöàÏ78J£¥ˆþu¯ª§Æ..íáÝò¨Ú­¸’H+ÞFäC¨Rz1žç­xׂ,¿´¼g¥Bªrnv¸À#p'ëÍ}Q{£".Õ…6åÏãÀÏ×^õjœˆàÁRöœÍžWs ª‚@e³8ÉöüÿÏ™>Љ‚T <±Pyüv¯J¸ÐÁGÚªB–Æ6çØt5u¤ 2»öá‹.@ÿ<ÔCîµ:jaìîy¶¡¡-ÜLŒÎ2­Œ€ÃçÚ¼Þä5³°rUÁÀÁÿM{½Æ”›ÔöFI;ºW–xçCûªïA ˼ÜúWSš“ºÿ‚yÕir+ØÃ´# J to@~¯¥Z:Z´i5´±‘Œµ»ýG#ð#Ö³¢”@LjÌóŒc#Ÿ× §,ò:¿6C'ÊrGùã׿«9 [HçÓn•¤I¢ÁÈYTß§ç]¾…¬Ç6ÀÛ£”àù¸ÀÎ8çúWgâYâVáĨIRd ÛG·ßó®®Êþ¸"à  ªs€;?³’¹q²gf÷K E*†åñÇòã·å^G©éÂÒ{„!“k{ôééü«Ôt¹e(G2õ}¤ã'=ú÷ü«•ñ}¨·Õ™ïr«®y$œŸþ½:MÞȧvŽD’üûØzqŽÿËô5ÌA$ÆÇ-ƒžþ«"@üIRå˜ôcŸÀÕo) 2GŽOoð5ÔâúY¢¡ÃFL ±'nI޾ø÷þ”Ò‘…R 68+ŽOãùtõúTÏn¹a´@î=ðhHU|À’iÁ8ûgüö: O-¢;vã§½OòôøØìr‹ÙqÒŸ ×aläàîÇoÿ_çHÐK1Þ = \Ñk èïãµ+2 °* ØFyŸùæ¶-®¦áœçÆ=ùïVf·ó€XŠG8,Wôãåµv)q†8` ÷qÿׯè¸ÕÖÌùŸbÛ¹•{§A1°`y!NqUŒ„ð ’§;˜ŽOCý9­ç± ímæ`t¯µQ»Òš-ï† [ d‘Ÿ¡úûRs‹z2½•Ú3Æ[†ÞÃxqØÏNŸ•Oc©\ØÈ ½ÄÐàm9 óÇ\jÕ°1¨,ºgïdrOç¥-żlPÄv¾2@G¸ãñæ±”Õ¤h¥$×/æu'Å¿éb/±ø†úÛgbAÇ< r=½ë¾Ñ?k‰ú,¿>¥e©Ç¥omÖ9ëòAÈþ}ëÄ­á(ÊÁŠí1ÇõêݼíÜŽ†A\ð=úW•<¯QZT¢ýRüìvGŠºª4ýO¡,ÿoÙLÞ¢M™R)7Éú×™üMø…sñŸÄóø®âÑn¡¶ŽÙà²ýâÊAvÞAbIÇЭqĬÊwmq»åùCÓ§µzÁ_…w:ñ"<71)²¸†Qlãýc‘:ô<S_Ä9F_„ÀÔ¯FŠŒ’é}CÝËñ˜¼F"4ç;§é÷ßsÔ< û7|`øµà-"x!ÑôÈ,]o4Ù¦‘âž]¹ÌQ¼(;‰Á8¯¤ö²øworÚv½ªMáýbËg¨Zʯu2©Lsœ÷î,¿²4{(ncò*ȇ*Nz‚}q_ž?ðPŸZø3ö†¸’ ‰m«éö÷è¥p«÷¢`=y‡8ÿj¿"áL- ëð¸Ÿu4Úå²ÕYõOK_î>Ÿ4ÅO/‹”=í·>ÓðçÄxò?/EñŽ¦Ã¢ÛάëžpW’8Áéšè£Š{IÆÇÊ*ã*ÀóŽß/ó¯Ç}#\¿ðžªš†•©µ¥ÄMæ,–òŽÉþ/S‹žP¬­[Ü—Îß‘÷)V¹·teˆ8äŒçé_-~Ýÿ ü%âïC«ë·VZæ‘ÀÒRÞDT¸–EO’Ue$‘yRäŒô,‡þ àíNá ·ðüÊ<’ ÷9ó1ÇéúWšøÛÄzÏíGñ3š›¡jq¤ÒÈ,УIÄÛ?xçÀ ¸àœg¯LüÒɱøjœÕ©¸$®ßeÿc«ŽÂT£%)7§õè|µ¦ü:ñG†4M?Ä:~¥Kkp¬"¼/ŒƒÄ ŒCÒ¨OÕö¬‡Å$vñ\.^÷O;°3rÈNvóŒœú×Ñ?´þ‘ÿ'5¯†ú=ó˜|>-¤T‰ÉŒ3[Ægg LŽÄãÔçà7-Ó^!{Ã!ˆ•ÉÇ©'çò¥ÜÚMÚç‚©*m#ô³ö6·¼‡àö›?i»ÓQÈ´’pøùN:ã§Oñ>ìoaÜ ¸ów(Ï#÷ã¶:WÁß?mý7á€tO Ã໋©,bXžâ;ÕU”˰õëúVÍÏüVÚí¶Çðô‡þüš² Ï¶!?ãV¸o4®ù£CGª»ŠüÚ>šž? N 2ª®’>ây–Gž@q†QÈÏoÔQo¨IX—k`¬ŠA#¾zWÂ'þ ?•‡á´…·ò·cÿ.ÿçæÿ‚’êN—ðáb~ ¬±ëþŽ=êŸ g1zÑÿÉ¡ÿɼç/ëWðä}mñ¯à‡þ4øJãH×lÉY~e½¶!'€!X¦zb¿+ø{ñƒàø¯áäWQø«Â6±ê ³gbC¸pŲ6E.”ç·A]ÿÁˆâ7„íu-Ú•LsÛÈß2H§7s·œò;þ—Ÿþ4x«ÀöƒLð­æ¯cÎÑqk§^I]ãvм:Œ°ÚGBG¯±ÿeoˆú–µñ=tk%4[›‹žâ™‚ç÷`6ϳÎ3^? xs¥±¶]‰öu9Ò_™õÄ×sD„΂Û@RÛ»øÖ}ÕͺÜt“bà¶Tí>ßçҪݵ‹yM$‘är­2“ÛæÅs×~#\\§ØÞU£áxê2E|â|ÛW¶çQÔ7JŸf}ßÝV<}xõ§‰Ò&.`MÀ“‘‘ê?NµÀE¯“kX8ˆ.`C6{åx÷­½/Å×#šN¼+ ¸v¢Èj͆Êû¤E?8gßœTi¼Óú˜çŒ™»þDñYR\Ávª±¾r|ÀB“õÇùíQ}²îÅ·„–õº–=óÇãY¸Ë£ ¥º:xoìïT‰£0?ºàg¯Z¡¨hQü϶Üçz×±éü«<ø—O¹!.PZÈyùÎßþ±çŠdšŒ–ÛZÚú9S÷ŽâÃ¥G+¾ÅhW¼ŸìûWvõ rO>ݺõëâ¿®—_¯¦ŠL·’ˆw6W<ñï_oË©ÛÜ#‹›1Ï ^sŽyü~•ðWÆ–ë⾸w›b†nFqŽÿýojæÆIû4ŽÌ{q<9ù·ìV+аéøúÏÛ| ц½ñFFr$¶³€»9É ƒë\†ž¿c°ir»BœðAùþì?³¾ŠiÚì²*Ë}!ˆdüÁTûoÖ¼¬ 箥mKS’‹K®‡°ÝGkwÙ¢†HÔàùˆO瑚£kŒïäÃC•ÀÏåÇOçIªÊÞcœÄçšü¹½jˆÔmÄ) ]vîFŸç¥}+JZÉ<œÒ´Y¡©]æ™Å.N8=ȬOHžïkEŒ…êâÇëëQßH‘°ºï å˜õ积oOçTÓWžÏàÈxäT©»Þ$¿2…å©W"xÎd‚k†ñ #J¿fPJïÝÙü}}¸¯A¼’+ÂJ^¼NNLr9À?CøtÏøó>(ÓÚH ddžö¬ëBðphÖ¹4Ñï?>&YÝYAlÓ/š8 ; €â¾˜Òï㺶VSTƒ_™?üAsiↂ+¦tUŒ•ÛÅ~…|?ÔÍΑs†1®y>•çå8™RªéKcŸ;ÂEÅVŽçûMèË«øî2Xex#“œWàÞù.6îéÚ¿¡ïŒp¥Ï†%Ý÷pIÏ=«ùõñ­’hþ%Õ,£D7 €N?åÖ¾§*’Xêñ]R×Þ|æ:7ÀQŸf×ßÿ vŸ³î„šŸŽÅÄ‘1KTó V<þýjúWV¸¶x™a¸f$}Ùæ¿*ñßÙŽ×ʶÖo¥ŒrpOä1þ}«ÒÅ^U­cl¾<¸{¾¦GÙw>X#.âw°#žÜ ŽïOK¤ýÜѳ8*Q²áÆiíf®@3àÛrõàÿ“TfŽ{GåFs·¸ôüë8§r³ªKš÷_q‘{¥´*Qãhâà0ãߑָ_ˆzjZ4’Ú«Hаe’NA#צk¿“Rœ+y¶dÀç>üÏñ¬ç’Þçåx‘„cƒÏCŸ®+Ó„šµÎ ÅI8³æËk$Ô3ÝÌ@Ueãwn¿­:÷E¾ÑT«w‰…nN:Õñv>‡â‹ÈRGHÌ¢HÊäu™ôü+¢ðÞ¨šíšÚÜþòH×~äp?κ®ít|ä¢ã'yò³I#ˆÕ†AùTr9öþž•ÔxxªK«n CÛ¹þ†ÍÖ‘§»«[GŒ°b£wáž:ÕíÛFv"=¼à0Æ0?Èü¨½É±ÙiW6ʹùTä•ìEWñTŒ.옣u8ÿÕÞ¨è÷–·,<™Ap8µîšÏìýãrñ¦ž—´`H=Î3ÏJã/¾x†Òi#»Ð¯a(Ø(-É_®@#üþûE<Ó _᪟ͲÂÔŠ\ɯ‘ç;Í.Tp1ô‡g×·­E ›!!²pFzûãÚ»#^/S›Ù8˜k!u¶œžóÔä}ZYÌŽÁ]V>ËŸ»ƒÆ?OnkÖ~øWHñUÚÚjiÂàê{:·üÎú9UJÑö‘üÏŒ›Oq+–…A ãï98?ʺ/ øFÇ]uŠ]~ÓGÏñj1J‚½6:÷ë_XÁû%øLlWÖÚÖˆäúìöïK7ì…áh%Þ5]e²GO(d{žõåKŠ0Oi´ý?Í3¦=XÊî7ùžqû%xÎçN:–‰¬xwĶàrtËýìO.YUAç=k„Ò~"øãöy×çŽÌ ã•>Ûisi¥Ê“À.­·#?2ŸÄ××:gìÉá; ˆ§KÍ^I£mÃ÷‰ÔU޽_þ­ÄV°iú¥…¦¥J"Hõ e™[¹`ÀŒœxï_;âokJT'j°—xòÛ·tþäzt2©BJ¥;ÂKÎÿ¢·â|ÑáOÛ{â‹`Ž;ý6Âs‚¬°£1Ÿ2°{ÖgÆŸ„¾,jöÚ¥þ |i¯ÍBè‘.v¨j.2xÉlõ&½¿Æ¿±Ÿ€†mK.ÄCƒ¥Ô[övß+Œð5ñqtñ2ºþ¿­O†ŸöFø„)á+ˆ‹0™U‚ç°ù±Ò¬Û~Äÿç G‡Ùˆn7]G¶ß¾3šý·™ô›Ö+*̃‚[’ílkÐøÃ÷šRÜÞZ}®&®,%TšF #pG#5õ?ëæ9µÏþ/ÿn8—a–±“¿Èüíø=û.x£â ÝÃ¥êz>ž!G–s¨Î"T ´1-‚$à\të^£à_Ž–?³÷Ú§Šö-cƶÖßd²m-ãžÖØ%&BJ¶F>ê°àò+ÙtØçÁa…Yá†ÜJ½¸}‡d`çŒkËÌ8«‹JQmBVºZ^Û]ïçb(ä¾Í§e7·à|9ið¿â7Å/j~1д95GX¼šêæâæäE»ÈL®ÎØ–$®ê_bzÂâÒ_]éê…®!Žiœì?0eã®__Çì; [xRÎ4èÝ‘i’b$ÿ´ì~ñ?áéU`Öåˆ:\ôsÈVÆ=8'ü+àqüf¼‰%øŸAG.¢­ÎÛòéùcþÉ_å-)ð©} ‡?ÚWaˆôÌç¥gËû2|‰¼¥ðl©åƒ”þѼf$zfOzô)5¨ä í8ff Oðû¿E&±ms3$ÛÆ3ÈçéZCˆsK¨Ô¯?ü ÿ™ÒòÜ%ù•(ýÈÀÓÿe?„·+ö‹ Bè‡h }tqï̘üÿúõ¹mû/ü,T „­•ÕzK<ÏŽŸÞsëBk˦Üù®T+†NÈãù~f­ÂÙÆFâ8àè}³]ë6ÇUV•y¿ûyÿ™SÃÅéJ?r1‰ü'¬Œ9yî£'©lsÓʽÊßÇžtjÌpX:î\}9ëÚ§û|„Xd%xÈ9À?–jþ¿Q²­/FÛOäô&X,õ•%ëm~õ©ð¼Ÿ°ßÅ?‡úÕ¾¡¡djÍþjËayå”ÚF $ÁG9ûªXpGLgê?‚þ ñ‡¼A7Œ<[Qø¦KAdò(…–»ù!Ý ;³¸÷ϧ·ˆ¥²RUózá2HíÎj¥Ö¯o{6NQ°0T^:òq˜¬UxrÉèû!QÀÐ¥>xÅ—ˆôÝAL:„$#–?8ÛëŽß•A¯øCíÁ&ÑîàT dž9<óÁãé^iw3Z)âü¸»ñǽG‰&´tòo$'ÆFSŽÜW‡Ržhz¼©ê™ÑÞØ._³Ý:Á*ó–û§é·5šœ²¤Ä®6•ê½9ý+“Õœõëô«qø¶æÕÐl3ۯ̀7sýîIë^Pú¨!Ê–W/ÆÉ8>€~}8Í,~,hß¶ ‡ î==ý+¢4Ôˆ½¶=~vÒe_Šz¸gýÛ4ny ü¿úõÃt¬zûÛ2Æ©wäèê„3ù£jŒuãéÔWÐ?´Ѽ¥@’ùS¼Ã‚N '랢¾u¾•?µ4e‘%Ä{Aî ŸzúÇÇÞÞ8§…Bª")à“Œpy?‡zäÊhÊqH«ô:3*‰8Âöêu©tÆ #™ƒÀMËÇÐÇ¥S¼8ÝN!“g9§sÓ½fÇ®Aq½´Èç…Á'>ÝqÇ&¢žù”o°Ê}? ׿.úž76„:ŠÈ„Hø˜±áãàdAÛÛùÖ9×nãBf—Ï >냌÷ýjÕ̲²“ž0 †À?_læ¹}jöå˜ùå‘ç1gsOÒºUôhÍÔhÙ—P³¼+†ŽCÆpsÉí'ÙÌhWjŒ©HÆúW-ý¬ÖòC? ®A§5ñ\A|ØÚ% 6?Oê’oB=²ÜÏøE«D|u¬Z>xîäU^‡îôÇáúWèOÃ{ÖP…~ 'n¼Wå—üJúwÇBdÄÒ3‚ 9Êcò5úyð¦ú+­6Ù÷n܈AÇnÕñÕ¨¼.3•èz¸‰ªøG$u¿, ÿ‡e$gÐd×à'ÇÍ ´_Šúý©P7ʬ †#”¯×ð×ô5©[-ÞœÊ9ï_‰¿·¯…ûAGåîH¯lâpă¹ƒºñÇ _Ò¾“½–`ŸóE¯ÉŸ+YûLºQþY'÷è]øcai¢xOkVx$š’PàÎQAÈϿҵõEÖ½D‘0<ƒîÏZΰ°žßCÒá PÇñ =}*½Ã\.Íû$^F;OCÈõɯ§t¹í{…6¡¶v÷°)i@¤ó·»}¢7’ÆÔôGÁÏqÖªµ¡v.®9Á9üøUG‚ê'P˜ A8Ýž>¿ã[ªPŠÖ×üÎDçXh¿vÐ#qœ…àÕd²¹Œ€íîèO|gÿ]%Ì¥J£«|ÃNœš¡-¼r)d`§9†2¡ÿëVî¶9œ´¹Ç|XðëÞY-ý¶$ä™È;p>l{ú×›øwT—NÔ#¸Vó“ÝH ŽÏ_νŸQ‚ilîa™IŠd1“Ôciç=«Äµ}8é:ÔÖ§ #l 8äpsôÅ7nÇ•‰Ž¾Ñu=Wðͯ‹ô¶¼Ó@Žézî-ór:Ü{wõ®ü/z—Ïo4~IRT±?/\dâµ<âì½M#•ÃE#dó’l Ž>¾Õ×øËL’ïNKë5‡÷‡h8éžßçšÆîÏc–×Ôæt‹8tÛ…u;Žs ÎG^¹=zÿ:íVUŸKœÆ$e¸$ò8Zò¨5I£vó2UHÀã×<þ5ÚxgTŽIr#âÈúUJ-‹™­Ùãb xw¯8ÀÏQŒUY#H$méÓž‡ŠÛ˜4NèÇráwƒ‘ô犂D‰#DK±û¡AÇa×9ÕØ¬õfÖ}L[‹f«´°åç ~5 Ž ¯Ö?¤ÝyóÜVóZ$„ìdBTôNµ’ÈÒÙÚ¼äz~¿¥B¾ä¸ßsËC4­žå”œóíê=?¯35©ÜzÛÿJ´ö*0b08ˆÀííUY/C“*¨è5Iõfn+©ú¹a«´SFTcœtëÓ§ë[w…„Ѭs .«ÒFö¯ùé^ynÌîIB²Žßu¸Èý9ÍIÙAÚ2¿Nk‰A=O²æHí¼ëMJÝ­ÙÄ›È%J‚1ê?Ïzƻѭ *¯m ¢œ†Aÿ{uýEsö÷òÙ¸h®m¬ªCeÈýEtÚeòêh¬òä„íÃwϦ?¥\¡8ì FZسiyH¢UùØ9ë_ð©äV¹F¸œåG| ¨Ï=…ʇŽ6…Æ®H=úþuCP…qOÌ¥X©8ëØõï\ÜíKÞEÚËMŽ‘#1Æ+”ýâ åOùõ÷¨ßSqÂÀìÏͱÇ~W9ms(Szœ «ª€p;ÿžõÔRfdo3r’I‰~lŽœžµËV·&’FñŠfìú£Dp]O9ÞH¶}?úÔ ¼:¸Þcsœ‘ƒîNÕ‚n.ŒgÌXrAysï×Ú™ÍÍ‹pÅáæèŸ½a*ÊKcU«=NñƒÙCå¤aÔõ’Gœ}8éÆk8x†[¹7ùlÑœîÂ8ãòý+’¸¹–]­º>n:àg§sÉý}j ;Ç‚@$¸&#ågéþqúW“*Q»Œânç³=-j ¢Ï€;‚¼tÈçÿÕQU-¥-à =;`Îp?q‹ªIˆUÂŒíȶÿ=½h’ÿP¾ÝÞBƒ×½9=>ÕÇ<5›åwCŒÓõ=?Mñ,¬†96Å‘´>ñƒÇþ¿2{åiK¬kœƒ…<¸ÎϽyöŸ ºcº»S&v‘ŸŒtǯ=}é²jÈì‹t\€ œíö'Ú¹u†±•‹i5c­½ñ,'î¦x£'nÜ}ßóÏMµ‡˜8‘Kò0¡0sènžµÉËxæRîáɳÜgÿëæ¢ó|Ó¹ D¨qÊôúÙÒœ’v¿™+—cnyf‚_Ý ”IÁc¿{U{¹–@Q‘c+È;²­Ï§N¸¬Xço+Àç$÷ëþqO‹^‰Ké±×‘ÄÿœÖ.Ýõó3y~ð†kiFÒ hKezžqïYÖúÛ:¶’6«dãŸcSj×KutYŽÏõ®ZÕ?Ò¥‰šXÎvP`wÁ#¡ÿ=jã Á|"çWÕž„··Ê±ÈÓ-Âgil޾½êh¼O5£ªÉ/»(“†ïž=ó^;®ln¼¹WS€¯Œ©^ã'Þµm|qqÊFào qß“QÖvoïØ™3ÕdñÑ“çG_›?)˜Áä9úU(¼[%ÁrbDZaÿÖ¯/½Õm¤`ñ³£daN Ÿaùv¬Iü@"pÉ*íq\…ìF:sëZï­8Ýy [î{cøÖîaÒ¤ô~ýNyéŠÇ—ÇeÂ+¢£1û±ü»ºþý«Ê¦ñÕÂHæêw™ÈÊ9%‡¶Nyª—!þÑ•ä2)ÛÉ'©öJúúg½xñÖðÄâb¨¹Æü~•ZóZ[ÍŒ±r!äséÁ?­z§ÆÏFdê[C×uV^K¦Ô5EŠqk3•ip Âgïœ`f¼i<[7ˆ¼MyªÊ9.fܪ[vÕÀ  ‘ÙGµq?55Õ´½>ÉÁS-Ú¿ï°¬¿Ö™á­zÖúêH˜´1¶ß*\#têNG¿µy™µìycvuåø¤± ;-­æzxÖ#¹ñŒ/Éö„-™0#Œöÿ>•êW··1çȘä¶p¯‚¾œ÷¯žî¥{}VÆTmíæÇŸ,zöõÿë×^¾#NæHân »Œäzƒõ®ž„#‡”Z¾¦ùÅFê¯C²“ÄSXñÉ4nœíf#¿†?•jXüY’Ù6ÝBfLcy”Ž1ôç¹æ¼í¼N× ‰ a²>c‘Ž}Ç5‡¨\FeÝÈz’G§CÓëú×ÖJ…{²‹¹ó®­H»ÄúNñý¾¢ÁmfX¹,²Ç‘Æ>ŸÎ®Ý\ÿhFDŃA*2{ýêùri´Ë¿4‰w–9Ïo¯ã]f“ñzëL¸MÆW„.Ó•\nß­sÔÁ(Gš›ûÊX•xõë­>ú$>\` åz vçôúVÜy»§âä• ¸ç€3Å&‡ñŸDÕ Ò‹b|²²)ÝõÝÿêÍw–“Úê–ÑH­ ÄDgå|õôÁ>†¼öÝ=$Ž¥ij“µ½z-ãÔrDQ!1+°n*Ã‘Ž¼Šý`ýŸ5(µ? ÙL¬º(ηcZühñmÿÚ~4ëðC—_¶Jª­ó}ÐxÏ  à{Wê/ìc¬\]xfÙY%EÂvH¸ÇùÀüëå3ºj5iVïý~¦¸ ¾ÒzŸõùfÀà Wæ×ü3áeηñÁZ¼1°‘%r™Ïñ€N{í¯Ò}1·Æ21‘šñÚËÀð’xúh¢ =º¬ÉµIcµƒ u ]2M*Xˆý—ø=; %)Ï?´ÎÛ+"D»€ÂùA©ã°÷¨µ;{WšÝˆ_™dmœŽ9ÎkRK5O66YqÉíœûž•ç…#¹¢T.Fr#ðS^ú«Éfηk4qRY[6ð¡K}܆ݷ¶ª76)ï*cäŸ^;ãüýkª¸ðí¬+ž²’H–6àCŸqVaÓ@_–BG#hëŽ:V«ã»1t“zhpÊÐÉ &ÛÊ$œíÆ8Áý:Ì’ÀI"•žA<?OóÒ½9t¨nÕñ,[Ôõ ׎Þ{~už ¹ BÄÑ+—rƒŽxÅ_Öt¢yi³žVd—ÆÜƒÇüW ñOA‚ÿO‹QŠÑâ¹…öËcvPôçàãó5îמš8„/°'®p1ùsÿꬫ­Ê»­Ü–}}±Æ´–'»9§†S‹ì|€Îm¤‘|¶Á §¨ãŽò¯Aø}ã6·“û;QqäÊ6£KÆÓÿWåSø»À/g«¾•,‘­ùO2ÎêG!L[ÏÊÇ»uÎqøyÝͼš}ÃÁ*ªÍŒŒFFvœ~\~µ·»Q;8:rqg«x¿Â–QÌ/¨‹«l^œ~±,þË$ ÆèHÈÈ\‘×½Eàÿˆ)iÒõP×6;FÍ„„œñÈÈéZ·ZTøMlêdV…²9îåøRÕhÄõÔØÓ­–í¹Ü9\wÆF2{Q&•"‚Q@¼AÆNzâ©hR­®£ 3Mû6ŒŒà`ôã9È®ÓûBûá0 gq'°ãëOÛrnJ„Jz-QÆÜX™ vŒ|»ïUZ9c NQ23•Çøúæ»9-å·. pTÕØÇ!eF ä§Fç¿ý¯D\ðíõÔãÙU¢Œ0dlÁ—#ùãÓŠŠ8QÐ:©ô(3ú×K}¦ÆaýÔoÇzàóÛס?g®œd–"AõvÖº#UnÕ̽F}è5ón8e<å³ôçÒ¥µÔŒ«æg ‚AápzûöF[,EóI,NN[Øsþ}+%n%G>Reã%zõàñï[S¢Ó»=™Nèêg3N‹ù:ý:ѤjÒØ³‘&Ôãp!¾lwãOÔJv‹ÜF €†VÀROž=qÒ¢¼´o<ÉíŽ>aËsßJë•-#5>Çr×PKd$VóT’¡†N=þµEeh¾C„\m#ðçÒ¹{b[·q1æ,œžzàŽ;~^õ¶÷‚þ%•9@]ý½³ÿׯ>¥.[]htFm— Áˆì}¸$…e~ÜôëŽß•TKs½~u,¸`nÉú÷¨'i¡}…Ë£p cÛ·ùÅBo€“ìü`D›¾aÎ1óþºq’³fû_ÛI/Ù¥hÔ/#+÷zþª)¥H¦‘·vÞÌ8#üŠÌ(g*nñÂÈr}º÷j¤­5¬¨¢²€A3þy®7„ƒÙ›¹»šn̬J̡۵O#?ýn•Ž@crI—«qE´Ë*•·u†#ÓÞ¨i*–IH£cƒ×§­sÏ —º56ÙÚÄŽ#ÆS’Èr¤õŽ=ê”ÓüÁd…Udû¸?xŒÿ×ëV6Ù€Ùp²c¯®Gùü)ð¢´E<­¤pTszã–['÷–ª_¡^9 ,’˜ü³ŽÌqOoj´ÒÜ-¨KGY¶Œ®sŒõõç½A6« >ÂÄòpN1޹ôüª[e´Ë3ƒ!—ÿ>•ãâ°¼Ú¨ýÇD*y”±¨±smR)è[8úÔÖzÊÏ+¨ Ã%O$Àºvt©¢ZëÇ!%@1•##ÓüŸjÀÔ<96–D~Cí ÌʧŽq‚0yçõ¯6ÔÝ£&½M$½äM,‹"‚da€X†$ÇÒ©Ëh’eÒGnx߯F?úÿËÒ¤ŽE2Êb+÷ËaAÇù5d‰a•U·d«‘ßr£hïÓ×üv`ó,%ElM?š8ñzðþâx©øœl†× †8PÎHÀ€;õªUø¡c¨9I#A¿ï2¹ùOýóú{Öï‰?f]OKŽI,n Ò€q¶#œp:Ž;õ¯*×þ뺮·eÀÁ˜DþüôëjúzTrÌV´fÓó<*¸œuŽ:‹½Ú ·@y'xìqÔš’ mû˜ÙGE*Oï~òã¯wyhHóe‰Á¹ØÒ¥·ñõ©i2 ýàå³õª–YR—Ã+¡,Æ-kÈÚÀs³#qä:o^sR5ÜSVã§$:öèç^Gkã+˜Ù<ÕËœ`ãüþb¶¬uï0î.£9}¾aaÆÇüöç–pW”Q¼1´æ­Ìv3<©(1"‘“œöϧ {ù¡GõÚ àŸóŸþ¶+^•]Ë Ëð¤ tÏéÖ‰uä°Ÿ ­Ó¦óšÎ7¢i›¹¦¼8õ$I²ÁÑI$¬oÆ1סüªôicq hnÞB@X¤õéÇLû×/.¦$ŒïÙ(Vþ,nü^Ý}é‹1‡sÄ äžWƒƒšé‹’wæü ]EGâ—Cy1ܾ`%bã ã¿>õ–3’Ñ©'kvßåþeáß4¥.g+o·Ï¸ïøCž#Š{ýÎ{­Ël²Iq"–|Ø\áöÍmA¨%àNK!åˆ8ÎIé__|Ñ,ô Ç,;mäUów€w |ßÔWËß¼/iáO‰úݦŸòiåÖê›q"† Ø9`°®Ÿ3–'**)uVÝÛ¿vucðO MUsr{;ì½;#ÖGþ°2‚C)Éëœ~"¤—V·¸U,ûºFwqžÝ;ŠãÚñˆÚê¹äà18þTw”PBªŽ1ùöÿõ×Û*©|KçÔð9ú#§kˆÀPéásÓŸóÒª8óæ""AÆ6ž¿ZÅ[Ù!@ ’Ç’?)ç±üúTË©dÄ› # ùþ·º£:m];Ïuv>îÝ×EÉ=yéÔ’Ã[¾Ò.ÃÛÜÉo*¾’} :{…“`‘•“Ë|véYw³NÇìÖqîŸ8f<àã¦?úõsön7¶Œi(.dìŽçRøÆ{§”‰Zg‘ÉÉ$ž1ëúWëoì…ñOÃö>°™£ÔÐ5¼-#G§\M 7|Ëzæ¿:µÙ£ÅÑx+TñCiÚŒi§Æ²\ ‹Iq"3+c@`NxÇ^—öqøËâ†ÄÚWdÒ­âš6“N–ô›y°Àc'ýÒ@Ï5ñ™žºvŽñþ¼ÍpX™aæÜöŸ]ÿUÜý©ðÄÏ øŸþAúÔ¸\˜ÈhÜsŽU€#ò®‡ÄÖÖ^ Ѧ·3,ŠêAÚs_6|ñïƒim¤ñ¤ßê‘©ŽiУM‘‘þ±pÝ1ß½z=Ïìߤ[ÎgÓ#|9¼Ñ|_«G^Ùî¥te*_1¶ð¶sÇzå!ÑãVó%µU¯F}úÓüO¥{ßÅ ÉámZ{bMk*ãí6á%T]”á|àsÛšóû…³¹Ÿ2¹-ƒÉ#|öüê)b›‚Œ¿Þ”9½î‡ÚM¼“î„t®x÷îjæ„Ѱ—ïÄ?ˆÓß5è¿ðŒ¤©¼H¥º,z~gšyðª"²¾h\í>kU‰Ž×#Ùëdy+hÏ3|‹—Î98ëÔã§z-ôÝFÅÏÙ1—Æ2{m?‡B+Òo4”¶Ì5È#ðéÇoçYRi©¶Á¹;¶‘íMWÑÙ‡+JÖ9v¿[€‘Þ[å^¤|ëøzvèjìk ôÜGÜà“ž½±õ®¤Ú‘À$à|ì¥K&uÊ%È ‚2:toÊ—¶×³&ÊÚñ³áÚ׆$¾Òíž]GN"H@u 8;ˆí“P|ïnö^3±ŽÃR”Û]Ûåaš0K+z7¨ã§·jý’ÈDìnD;H;S9çÛñ¯‹iŸ†oà?G®iOr¶IJÊÈW Û· 8ùƒd gå>•ëàq|ÏØÉï±âfXkÇÛG¦þ‡ø—Á÷þ™|òÊFÙÜdm“Œž$céÅ7Cñ,úZl lÍ–…Œs‘Ðý+©ðß‹¾Úa±ÕbŠî1º9¾hóÔ{ÿ:»{ð÷FÕÍes%¬ŸÝ3¬Š°ð3Óž•ïsré#æ’obç†ZËÄ:­„ñ0™-¥Þ-û ä|§#×<ûW¬K¢Bò»D†Üžv‡Êž½oç^ÿ ÷[Ñ.cžÎõX¤‡†2Tt8Çæ3ù×­ø ÄºŽ¹xtÍE¢[¨¡.[s3d`c¯B.õËYm$ÏOR1n2ݚ̷VжÕYUpbÇáYwöJÌ òœ¨bèF3ý?jìÿ²O˜À®]p¼Ž·l~^•R}.^|Å^2£aÏáŸÃùW¶Ž‡®é·Ô⤴•-€ù°ÇF9>¾ªˆ²…ÎÐ6ó®Ê}ÌÊë¾7ŠIÉÿëTqé>b}Û]Ñkª5™­Ï©­‰‘ ýâ¨$0ê}}½)·ZU½Â$êáf#æ]ïïUÅ©E`H 9'”öéþy¤„œnÈ逬NN=1Ö¾·ÙÆ/s;½†%•Äxrý°/Lö#¿~kBÞ602ù¤ªŒ£îôÙ¤¶ ’ —…Fìƒß>àvþu0™X¶Å!ƒÀç${qÓ¹ïÍ9Ôè8ű–ºj¼¥eo'€PíÜ3ÎFzc§åW­- )4¢1æ3è}2?Î)lm"¸„Ÿ2òèrNz · ºH~m»¹Æ:¯ùõ¯:¥^‡D`Ñ!Ûöwávð 89߇ëU.´°<©6«)9ÞOÒ¶#G0@€tñþ´ø­¥T˜¼¶|¤àП§Zæç‹Ñ8»Ok2¡éŽ9 8úzÔW]ìË Ÿk`ð¥ ÀGøWCyhc€ ˜·)ÏQŒzÖk*G6aPêOÜ=>œŸBzV~ÑlÖ£Iõ x³*ÆË²B¹$? tƒÉûË&ðv–_óÞµ<±æ¯ˆ‘¸,›ÉÁÏ=¸úûñZ‘[¤ÖȲrœãú‘\µR¾‡8Öì›w GéÏ þ½i$Òf˜!]˜'”cžüvæº?°Æ YY‰ÎW…•{‰ÛÓüŒ -õ-eŒ6R«•9ÚïŒ7`?ÏzغðÿŠì²%Ñ.e%sû”.#Œ'‡_Jçdð–³i"ŸìÛ ¹£l}3Ž{þb¶tmcž—u­¬ñíÀæÜž2IíêçWY8¿u%ë ©8½*9'÷þðLyµ›€Ù{b¥~m¼ŒsÈäuâ“þë­Î¾FS°zôççë^Í¢þÑßô‹an¶Iuî³$þÁíTüQñ“Äž9‚(µ¯Á~cN ŠXØÛ!‡ 5ç{Y©YÒMyI~©.•;^ŸÎ/þ å ☤B²Ç Û–ùOOsÈ¥ð÷ŠgÑVK¨5)£ÝlEr¦Ççý+ZÿF‹RDh< ub„‚¦ g ô8Ëÿýjæ.¼¯™%{mQÚ¼|ÑäŸaÏÿZ´—±­ i~í› õ0ÕUK)ïüßG¡ê:oí]âë 9-šæ9°…"Ag8ãpÀÞýq^}'ÄGÄÞ$º¿×n“Îwçîàöç ~µŽžñ ²îmùÊg…·sß§ÿUIoàM™£ŸCÔTÈU{yçŒg+Ò§C…Ÿµ¤’—} êãqu’ŒÛit:Q¢Úd'oާÐÿõª&ºXÙ¾}­œä¶qÏqŽÕJ×á§‹LAáðö¡,|¹aÀëž™ü>µNóÚ®–„ßé×VYç÷‘•Èô¯gÛQ“i5é¡Ç'5¬£cwÍyœ6äb ù¾÷ùâ ½¾·´gl®LŸÃ¼œW6¶sÊJZFd8ÆÒ1…džß‰¨µ2óHx–W‚pê>@Ä”É#QúJÑʛѫ2GÑrø®Þ!û¡3>8ß÷@ÇA­{7À?è¾,Ò¯‡éÔ¦°õ#{^ÍþGêÆ‡W:ׂ5{<ÄÚÌ–í$J2@ (éÓw_ZüÙÒiUÒ5)´èSéšœ?$ÒYÈž>\ñÁ¾s_hxWþ ¢xDD´ð–¯=ÁŒn3¡MÛG.N+à¯Ú¾ËTøñ+Sñ¢xtéiz±E$0Ý “¹"TîŒp€qéõ£õ •ýŒå¤—{Z_ðOjynoG ëN‹´vv½×ËSé¿ ø‡Kñ²O êPÝ&y*Fyé]\7‘wJ¢P@.9íïÓõý+òÒëGe”,îRöüÏzî<)ñ»Æ¾ µØkX·M¹†x£•p£’2Њõ+d3Jô¦¥ë§ã©áC4‡3X¸µóÿ#ô˜ÙA-¸xÚBñ’xäõ«ÿÁÐÜ8’(Ü;Aã9ÏuÍ|¡þÜ^*Ó›mþ…¤_Æ£ y!ž9$–8ééô¯NðçíùáíA‘uíþÁÉÚÒÚ•˜u럗ù~uãTÊqÔ}ïfÚò×ðÜôaÃTÚkç§æz”úՔ̘\rpTqøúúT?`mÃÌÀ<’ÝN?ŸëUlj?„ –4Ä⠤‘qgè9Ñ.oçÓÙõˆ ic»†çÊxö®~|åX r3èGZòïٷᇇ|[m5®µ¨]érHÅadgŠWËå¸'ŽÆkîp¸Å‰ æ÷®|f/ðÕlŸºöÁæ®6ã g²kÒ¿eÍKQñ¿â î\ ˆEÄò E`¸+8éEzŽiJÈœ5%»“—K;w¥ÜZnÁ¾â£usŒÕ`Êp·hƒ²˜·øâ½ZêÎâC¼`à¸gƒßñ5I´ë69h#'–$ŸïWOÖšØÏ‘=ÏKƒHŽV òŽàQr?´—ÂP¶æ¹'æb#Ï\óŽOµ\K$+¼#8Úƒ'Ÿÿ®­ÚÇ$S(rY:œ`p3_¢U¨Ö¨ó£N2ÑœŸökZ’¾A;NI#`×ñíW´Ë ʲ”ó3¶6eÉÏNýø®§SÓÒéC(ʸ¾ ç=ûV ‹kA0Xü©ÎÕ˃ùŽGZæuù¶‚‹4§²‘ØF€wVsëøþu~+ä¨o÷qÁÇ_Àš¯äO°fI Å[é×=¸©Öá£`ñ|¥ÀÁ\×$ª_Fu¨–n,dˆŽ=§ïsƤ³€2®÷ÜÓ“ÞÄdqK êÄ•BÊ2ùî>¸>õnÚ52/ÝŽFsÉçŸëÿ×®*­ÅÞ,Ú lR¹‰am³B è¹é\~5•5¨Z•JKœCíúŠëdÒª[€ã~â1ôü+2âÈE#,–̈znl¦¡?JÁWÓV?fcØS¸H6HÄᆞßwÿÔkz=6˜ ‡Ë';JléÏÒ³îtÙEšØ\*+|§Ü~¹¨¡3[Éû²À·bý¿Ïó¬¥W™^ ¥Ô–mï,nTRH r>¿¯çQ[¸Ý•`Œe8?JoŸ,ŽKnܧ 'Ÿo^õ=¥òoÄð¶qćúž8þU—´r^ó/•-‘£ef³@PüÌNGÌ£½ºqïM¶¶xÎBì+Èf8àž¸ü*ä $Ÿ2fBvýÜ ¹î=+J 0da…Q¸2’NÜžß­qT’h,ÖÆ,öj ¸O%øa9^<Z¯ý›%¨T1me-†Ï<ú}}k¯ŸIŒÆ^9PÉ–Ê8?ÿZl6Þl{gäù'Ž¿Ê¸e7cE®¦>œ†Bçl`€®z7×ÒºM;T{]è~eÎ6HãúôõíYwZ{[¸e· ‡«n8cØúçð¨ÁufS€¹ÚèÝqq\µ6¨Ö.ÛššŸˆFYô«t9`N{œ‘õÍgZÜÚͱfXâ8 7}:c?ç5rŠX–+ŒJ„ØçÔóL“L‘ÛbȾY8XòH'±ëŸN+5%²˜ÙtËYyl­¸þ?íÓŽ½ê3`Šw;—#%3ÍOmtúfA‹tcåÉ< óÇçëZðÝi²©M¯#œgnF=úÖ„[-3/tr"C.XcålsŒçõ©çÐDø{v13…p:wÿ³qkkm$jÌ€óµOËÓ©õúU‹[ó—j‘œŽ«Á®¦–Oc’›M¸´‘#‘]X|¤íàŒú}>•rÛJ{µxvà|Ä€@ónÜWQqwk¼ ôYlUœ:ªÆvŽIãÐäñY÷V·VûetnÓÎ;}k)ͽ[cP‹ÝÕ§Â/ ´ŸX³/%¾Ë ã‚)Ÿð­<;o!hü5§$xÆß± _ÀÇ\þuÕXê¿q·dOÊœ²žsÀ®‚mµÜbØqÇQúW$å'kIš{(%±çÖß |;xÈÍ i1É×kÙ¦OAÏËô­~øjÝ>ÒZU<°µLŽÜqÅvSiŒ‘•NÞ¨ÈæKeJ®G÷‡óPá)} PŠÙàømáÄ™e5„*G¥ª*ûñƒõÍGðOÀì/ ÷†4{íàXÂÇëµ×Åå¸>T½qS¡ÿõUˆfT*»»¿^(~Ö©*p’øO˜þ&þÀžñ’,ÚÜøGQCòͤ¤k\ca:}ù¯ ñïükÄSiŽú_Œ´ýJñBÏ¥ý˜““Õ„¬@éÛòïú&fŒ *@?6rGÒ£š¯e¾0‰Á…vQÍq´,£=»ÙþzœËðÕ/Í ýáÅþǼ<­{ák»Ë8ÉÛy¦p¬R lcÔtüq‹ðÛS»øQâ–ŸYðºjÂ?’]7TSSÁåX0z޵ûpúLâÝÃÆ»_ø•¸Ç« WÍŸ?e_|YFm&m*ÞQ*¾Ëœ 8pê ï_G‡â_÷8¸.W¥Õ×õò<йDi~÷=WG©ã ÿh„,Ñ›hþÔŠ–‹N†, ¼â5œŽH'ùú6™i¡x¯Ä6ÚÆ…q¥ê1 UÉãnàyät?—zù§Ç±ÅêX‡‡>Ó´ºÚæ7G\àc,8ãÒ°ü1û%|s¶u óÛMa©Ú#.yV“Ô§5­\³;Ô£‰IÿyßþßréckEòÕ¡÷-¯¸ý$¼Ó Õ´U¶x#E €¾¼½ºWÇÿgnÇ]LJü8Úµ±QçÛXŒÇ'æP§óÏÐu¬-;Vý«þdßhš…’¾KZÛ\ç¨1)oÄqÍnGÿñ/‚-0·“n—¡xžÊg`Æ×Q³™c^Ÿ*¾Ðí’}+Óí|+âñh©«øbâ}Ç„û8gž¸ÍeiŸðRÿ0OíOkV H+ö9¡¸À>ìÉþEmÚÿÁE>j’,sYø“JS^êÆ6\ñÐÇ#NqQSŒw—°’üOª¡ÅÕ`í*—¯ü:FV¡û?ßxáZÖo %dãÏ«‰éƒŠ†oø&ýÌö25¿ŒRöq Æ™”ô„¹‡Â¾ˆð'Å}ÇöQÜè7óÞÂÇ ·²GØd¯¦?ÊïaÕ#óT2ºÈ>Ps¸)#··nj(f˜Ìå§6¼ž¿™áæ.µUZ¼cu§º­úŸœž6ý…¾$xnvk6Ó\¶ãY\¤}»‰6ô=³Ö¼³Uø ñJ/öŸkȈy’>YSë¹^¾õúû ëFW“.xÝœdzTajç ‰³€Wœõ¯n—⢭Q)~ÏO%£/‚MŠ–Eâš'·t%^'B¬1ÇN ÿ"k[þ?ñ„£0èž!Õô(ål²iײ[oïÎÖ¿Y'ð&£†ï¯-5¹£òVÒæÉ”2·-÷z`çw~ù5[öjð½Ö«¦=€k›9ec¾¶ºò<²Ê ¡ …[gcø³Å|åuðÛ^ðy•uû/±ÜÃ0Šh¥q˜É€J’@ÎA=«è¯ž7ñ }ŸÃϨ^Ü[mf:y¸XÎ,À†åÏB8÷®ÿ¨ÑÁÒý̯ͭ$yØŒeLL״нWäq´×ÃOÚ¶Ÿ6¡¨ÚÝÌceXí^5l +8 ÁÉÁ85Ñ~Ä¥­‡ˆuëi#Iá’ÔN7d:ä…çŠõŸÚ_Y×¾,xMåñ‡‡~ݬhÑ’5«x¬öªàçEåÆ]A†ù€ˆ#'>3ûÚ”ø‰­ÛC>œä"ž Å“êzõú×2WÁN=‘¶%‰„»Ÿg\ØhÚì?»hREÀ]±ùl¹öïéÆZÁ¿ðµÅžçR$OvñŽã¯zšêÄ¡¤Œgi!8ÿ¾³ùTCq( .¢‚WÎ:ð={ƾ3¾ÌûN[õä>R¼6›ç%AÏ9Î? Í–ÚѤ%b…G¦À?¶絹³“nAáKžØçƒôª%?•áØÃªŸÿQ®Èí£1’TzþšPùȸgç =°*܈¹åÞ8èºù^ ã¥T%Nû÷Çn9ôÅs·éoi3Ê ÁŽÜ#tïÓóüëô¯hÙ㤯©©f«ulªÄäI$íç‘T5ÿË$m´J$îGÈ =F:ž•VÖõ¡Œ²®JŸ›2XwçŸÖ¶íïC(—-·ºïÜW¿Nzþ„›„´5Qº8+{i>ÜQWç –Wt¹úñúý+nÒy&&FU-Ÿ›+‘È®Oë[:¬,÷Ùª´Œ‘¹'¡¬%…dŒ¤m&òÙûÃ*'5mKƘÊL»Dd!ÊŒdãÅlÙ¤/ûè‹Ã1ÆsÎ+.M?Ë¢K÷z³žþ½kBÁ^62îæ#±®iÝ­ ¡$·6m¤Id{²=psÓüóZÍ¥[j1âxÿyêG# wíÿê¬t³2eVQ±å¢ ǹ<~ TÒ[]%Äeg•£ …mÄz×¥yrKšës¯tG.š-ŸÊTÈ,Ê@.1ïõïQI¥+ðÛÇ£î€qÇ$“‚EhG;1žUn¥³ùg¿Ò–=ëÀ*:£¾O'Ò³¾·#mŒxtÛ‰åcfçÊv¯JÙ·ÒŠ ómŠ¡Îù2¬§ŸlŸéÅ:FŸ`PÌrH##è?§¡e#" åd«¨Â“ÜóÇ5›© Ì–´[6ùSd$ýÀÓþ<~l^ËÈ#ÕprWŽüg'ùV•ÔV––þc“‚G9?(ÏCÍf¶±`nCH ûèG<ãð¬y¥$¶¥›yžuW G*¶>~AîsÔÿJt§Í8Q18' ‚Ïò¥IOùˆÄ~èqǧ§z»0–XÑ¡,œcÁNŸ¦+;6µeTk”t¡àïçü÷¨ÚtWud|cl}=ºþëEP-7@O8Ç?Kžçã &v²/íÁé\–IÝ3]^æD1´lUÂl Êç1×9&¬ý™$Q¹Ò#¡ã¯J¾öM>8‚Éœ•¼ôÿõT°éjÑ,Nv;Œœ“¸úûví\òÑù–•ŒÑg.rÙÏ#Øÿžôõ´1h¼ÂBÌÎ ôäb®]X5»’‡^ŠPsî3ùóW-l|ëmí*H3ò¯©ãŸåùV|í|Cq¾¨«nK•Mådm»ÒNAßçµ=à1$1±^@]½¨q)ÒÚWdÀ<ôÁïÇó©áÔN™•¾öð7)ýzçœû»Üv*ÛÛEw!C€ # ;ž¿_ð©%Ó„ ¾Q·krÏ¥kHÙÝÔäàù=f]ÙjQ\’—\à0‰NGÖ{hê*Ú¬²U §§8ü±šHâkY•â_›¾3œtôéM·žl••ƒ•P2ªëŒjð³CEÃJyÜpx犉ǙhRv/Yë6ü $TcÓ·J»qgææèΣh'åcÇùâ¹ ‹iDŸ*oêX¨Î~¿Ê®ØkdÁ2X®? q´àÄã}Væ“é³B ´`ƒÓ횈XKæ;ÉFûÙÇå[6—ÜBÐryW'#ŽG5^[)4L[íLsôÏÆ¡Êú I­$`+Û¼„å–L㎽zþõ~ÊÎÖYKy’é}ª “̶_1þpß33ãó^ݪ‹G$<,]‰Îõ9—aÏéS(ØÛtt†9"Uî~Ü“øsSÂU³¼¡a•³ƒYZ}ü×R^XtlõÏó­/3dÏ?xÖ£•ÅèfÓÙ—âKYÆ„Œe4K¦‡Æ1€ #ùtª‘dbåÏ÷–®Ã±—yʰÆÿŸÒ®3¾ç,”¢ï6M29ù<ƒúUsc=™Þ¸$H䟥t1y7”‘Iê@5«DdŒùƒý‘Râš½†«»Ù˜ñË)`Ó‚¤±·ó­­â¸L†bÇשªÏRÀ›®råN†µw#ä'€À‘ùÖJš½âìi'u¦ŒmÕ¥Ô ûHïæ1 þ]+PÓZè,©4ÑOŸº¤…Áî23é]I¿I#EWY9=óëUZ7“çBsÂ6 üE7 )h(NV÷‘ÍÃ¥^[&q7d\äÄÿúûÒ^Gê=µÕ½älA)t¡‡QÐö=ë¡bB_pÉÏЦ–ay$›°2@¨œ¥{›'­%s¿ø-ðÿP»û@ð'…æ¸$™ëJ…œ±9<•ç½]Ò¼¦x`<:g‡ô­)’ÊÍ"@sÔmºï++"¼eÈ8R:¨íùThæ8JÉ™>àÀn+ìGùþU¤ä¬äÁR§†+î2ÞÈÞ[€ÊÊùq#'ó¨nô4•Ö’‡3Ø‚¥kÝbL´3€ÅG äýzæ«Jï » @zñÏ¡jk¹£…âYŽDPwsŽØ¦ÞZ:@¹O¼v·SRý¦G‘Šá†z—Æ*Ⱥ¡go´ÀÓ=3šÕ»%rmØÇ3**\yc¤‡¸õéÆ})’[AtÉæ†Y°KÏÏùô©1¶½—j:c'5R{qAex$ýì¡çÛŠ.#k5(Bò.zÿUfj¶R±xü¼„mpØÇ§|Ö·˜ÑÊCn+·s6oSŸóÅ1¥„–ûBˆäæ9êÞ¼×ô¹žkè~\|i»ºµø³®Zx…R ^+…[›kpB${ÄFIëÂyîkÙn&ø¥|/²×<)ã_Y|LbݦIo2DÑæ‘mÂõ$ È2çõO¾xâtqÍâo Úk AHÞàñ€<Ø™\Œ6ç ŽyõÏìaðºk}3QŠFQµ ¢§ŸwÏùú×ÝÐÏé<,(TOÝVèÏ•ÅeÕe]Õß¡ñN½ñ^ñMÄŸi’{¥º9/0ËdõÃg¿¿=+é¯Ù7áUÞƒψu>æÕ. 1Á4ÛTI–R@Bw`íãJõýàGÃÿ É»Oð­ŒFw» tÄŽ„Kü==«µxäX!0ŸÞƒ‚˜ÇáÏáÐW™ŒÍV">Ê”yQÕ‡ËåN~Ö£»3 (»²Šñ7^¹ôü«QЀ}³“!Ïqµ»öü)×WšŒwàMò?#§¹íÍ"ËÛZ7óÊgϾ}?JðuLö¾ín¬#V—‡`@Þ~\t gù°7&&c܆l:êîàšKw «.Ìá× ôúôý g mÞ„íúVþóV¹<Ö'Bd±“»i'NÅL‘•Ëe<)äÇéÒ«Ù³ÈO–v6æ ž‡ôÿ=kRÏö“#–S!˜¸ÇNŸÞ¯×ee±ãÊ<´CÏ“Œñžž˜éбg3 ¶Xù°Ç¿N£§ÿ®­-­¤Ä©|†nI8ïQG‹"ìØŒU#·ùÅsºªÍ3KjONϘܪÿtñ‘ÐŽõ`i²D]›j)FÑøgëйäKd…K©*¸$wéþ5* ”ܬOË»gÄ宎æ©6®`ÌŵeŽUpsŒ’N)ULSaÙcÚpu±Õ±.ºçÎ7"®€'þUa4kYfh%Bø>âyM-A"–›©´DÆX¬lIp˜Ëvëþx­Vó¶Æãk¯PÇœŸp?¥d›uŽkˆ‚€Ð63†Ó½ ÝH\á³Ð÷?þ¯Ö¹%ïü&ñ².‰Ùnªrª¥€P}óíÓÿ¯WÌv×ñÄ!¾dÎ}ÀúVRi‹j¥Œ„˜ò­´c8çùVºÚìl{v¶x|õ¾ÕË%%±¢hl^]¼,±oRƒxˆçõÿ<ÔÖºƒ$žR¢>q¸po|ÿŸEn­Ùv”er§­9!ˆÅ½¨Œà€q×Óóï\®e¤˜¶·‘´R–‹tg#Ë O¾O'Ú’ ÕXJŒc…Ø`!9äßãR „Œ®9-Á`9}zÔ‘ÄaT}û’LuQ Æ=ÿžv׺;&ËÖúb۟ݳÆápNs‘Ó ôÍÏ®Ò3îÚ ù>™íŸóÒ«_¶Dh›`û¬ƒü8¨¼òA°© ·©ýy¬äš)AXÓ‘¤™Õ‡˜,3“þy©-‰¼‘"fC È|p8éÿë¨l5q xÕ e`¬[ ôÇõú ŸS€%¤®ØW] „àäÿJNìEÅXæ@dB%ä+…nzqD‘Inw°Ú[¡=OÒ±¬îت0,AÊüíœñ[–z¹) (r±^ßáXÎ-êÊZ=Þ2ò8Œ˜dzp·ØH» r zú~¡ö(ÖÇ,’``žGJ†â³)#aù¿…ï£-[¡IÙw¸pn9öï“Û¿åU¯Þ†Ý”{u$r:zÔËtY<Å9™YX}àëJšŽ}¨¤ ›óíž”¯(úe"²Êð\º¤³êßrŒðO¶´­‹€ûe\6"9üN9ÿ?®eÍÀ{Yg €ÇåÇk-›È¸äu`æ'ÓééP¥}P¶Ðêÿ³I›æ‘GXÏaLuX£ÝUÄ;Nmø:âÚúÝ„¶‰ç.rÀ’Ϲÿ>Õ³ªxzÒå7˜‘ ¨´Jû’®¡>Y#‹¶’9ÙU«•åßpqJú:´„Ç,I'pd$Âqv÷o¨E’8úÇ ªÊ‘ý± óüƒ†àwàõëšÍjÎÍ$ˆL ûJ|£oAÇ'?çµlØj,o_› :÷ª-–èÉ·jÇ#•ùŽåÐúU`ˆcÞAû½úzÔJ*[µÑÅ”w±·î‚ÊÃïŽ=}Åc­„Ï´Í•`8ÇOOÖ‹;§Œ!Vc» fÈþ†¬¼Ëqð]7v8ý)?vÍ‘¸» b ƒ‹«S0?ĽG'Ðà÷í[öÖš}Ì~tP®ÂËd7Ó­`I-»x@Yƒ’r=½þ´øä’DŒ§§'¡Í ÒWHŠrÕ;2åå£[9ž»×àýp*¶Ó( Gêbzó[zf£öñ"ÈYTãŒõé.¬#–VÇÊÀ+)BûF³‹åžæLBâ òß.O‡£kvÌû¤[©aýjŠ©‰ŒlÅ—¦>õöéå—@W Áäu©åpWFÒŠžŒè%†+…œ3 ?ɬym®mÙ›œ¬p9Ç¡¦ZÜ5°VByàó×ð«Ëª¶Ðê ¸àp*\£-YŠŒé;-QI¬Ä‹û¥*Þ õöíUŠP]qæ!íþ©ó]¸lfåI©-¢óX£`®;Œä{Õ%+Ù{G©R ² û¤`’3¸zäý*wŽ)UX)\}ìñ¤»ÓcŽ'x™“q”ò?ʲ‘]7J­³`çút¦åöZ¥?z%ÉÊÆf%¸çýj¡;†Ý±[æræíþ Xï䙊¸RC0[Š£©éö×ež&’"N: tôü+$õètGMÇ<1ÎQÊÄûÊɃ´ƒœS s 2ê$ŒòØÇãŽüuÏó®q¼ËiÉG!”‚Ùô­ QîßÊ!RFûŒ€€;ò3íY8òš'}‹·V…FËv ê;Up`%d,?.܃ïŒã§?‡µY’}—`>íäò·8ÇéÞ¥&;¤Ì¨~éùs»ê=+i-Kåº2ÒdbSæÛ•Pé‚y㊰’88Wó3ø0üŠP±ŽÝ¡ ‘ŸN¸¬™%D'ËFK•ùyÇ_óøé&´Z™´Ö¬Ø’E¹rH>j}ÒÈ3ýxëYžO•ó2)%°iß?ç·Ju–¨×÷y€pÃ;OÔg®iI*]°6ð<à:f¡ûÚ1§mЦ`ŠB°%â>Ÿ§øS$»…‘Rq÷›Œ:qýjH£[åC·hÚÇ€c?Ëÿ×Uõ O³ÀíëžIéëÛØÖN$7õ3µç C"àsÏ_¦k%šx“ÍlYWÁ㯙%Ë39ˆ˜°Ø%N3ÔtÿëÑm«Ï,ÒFüK%áLô­âô¶6ý'_.XV\wQÆ}¿*¡¨éH#1DC’wç¿z¥q©4˜6ýÒ¶<Õspó°HÁÆ{sW"÷"¸K» ²<#øBà¦;`Ç^¢²Íä„äìcë±›?Ž+enL–ŽÆ0>NóÏ{Uw‡.pªFxÜI4]¡ZúŸÿÙ endstream endobj 2700 0 obj << /D [2698 0 R /XYZ 89 721 null] >> endobj 2697 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im10 2691 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2707 0 obj << /Length 1687 /Filter /FlateDecode >> stream xÚµXKÜ6 ¾çWÌ­6qý¶ç¸Mš Í @‘ä µ5umËðc§Û__R¤<öÄI[ =,¬¡(Ф>}¤ÖßU;÷ú™ÏߟŽÏ~|•ù»Ð÷Ò4LvÇÓîàïR?ñ¢4ÜËÝGçÅYt£ìÝ}˜øNâ~>¾¥±—åY€+üÝ>>xyÑ‚£{ÑVúÎ=$Îñ­üµwƒÜÑU/šFö?¸Qæ 4ózR¥$»I¸;x‡4LÙlx¹Ÿ²Ù³‚Á!w ëþ áÁÑmýDAŸû^É nîèçq ~òÿ®ëjUˆQév±Bëúa> a×_ÝO‡½©Ð}B9DÎï`ÖMì§`kŸ|?lKÚŽ½ëåIö²-Làjx‡$¡PIJÎEg úœ¦º¦Q)‡¢W9}¢ïî5PµÉIè9žuÉRÅ–Æ3o¿¶ðV¸¡ï<ºa∗º áGŒåï‚]¨ÂÁo¯ŸAAÆs6|öL¼Aìâxô˜‹Î8ºWcŒ!F]LlGšûÆVaøÅVdñkE=h’À1ºAâ ®!cb1ß’A03ªv’ ç6¢ktϼ×õºõsúÝKQïku’K@Z/AøTÜ€¥Olr4,àgö·ð s/ ò~3ï†aj::üMì¹—æz&L µ ¨½ç10ÎfHl)·”"°”¬{¬'èSi]Òè¡%¼V¼ÐœÝÒÒ²HÄÖM‚+jÀÛ$*‰ÉÍS>¯Ü·úÆk°±ß:#=U¬xujÁc€\[ÃQgpJßÿ|»òƒ‹‡¼ï[7ÁI8w@HÏ‘‘"G¤„·-ñ9‚»œ’YžG%›´ëBù1šÌuG DJ\‘`Ä€; c¸gåBÞúòküÅÜ  904Å8¡`¾¦ñ*´åÊF?†Çw!Ãíhë?¡÷ÉÚšïâªÛ¸i÷þ™·û“ î%†Uœ–eyÛÁ! ìd¥¡²¬8är]Ò‚Ô‹£Òn…œþOa˜Ü¾}âµò›jvä,ënÞJ5ê/¹é·%~ðW5r½—ÿ¿;C¨¨nr³ª$ßË£ôpõ(瑩ӦÀÄMéJgÊ ¦FâJT\A™emi5 É$>õºá­\¼­”ôØë8¦{„©RpÂtÚ£¹¹§¾ƒü®XÜ(oíÞjïS² —HÍ÷Ôvüå4gËãvqºï¾ ÛÌ j #f'ö7)‡¹‹ìYJ;\Sá—)\ð½çÙR P½ž¨ÙÍÍjÔêѨçí ÀXµƒfíÉ@H…3ÞÊË ¶Rš^<ò© ŠüdÙ¥ÓÄ )üí‰QãççIS`nö …+Us±@I­‹ì¦ãÌ6F´N¶â¾f«#ôqX"n+ÌN”{Tmg;¦&d+ÀµÙVáÞ>ñz5޲]_ÒeeN¿°~­5Ñr¹¶÷þ2 +Âf½šlS£§ñís©-±ªaã•Æ·…7‰¢*^lQ5Ns{Š‚$ ëùð‚^ï¸ÆZúê º=|ãQùŠå+L½0àL¹IĽáOº€ïJŒ[ÿ»HÏç%öÏÒÅüÀ~dÿoÊö<_,ÂZVÝYb¼&ÉØ°{4Ò¼Y*‹ÕÚ£†w$LŸtC{ðLd»}ŠüÇÿÔIó•ÒÏÇgõÔÓu endstream endobj 2706 0 obj << /Type /Page /Contents 2707 0 R /Resources 2705 0 R /MediaBox [0 0 612 792] /Parent 2696 0 R /Annots [ 2701 0 R 2702 0 R 2703 0 R ] >> endobj 2701 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [430.859 490.692 442.814 499.539] /A << /S /GoTo /D (cite.ATK-doc) >> >> endobj 2702 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [189.689 478.837 201.644 487.584] /A << /S /GoTo /D (cite.ATK-Tutorial) >> >> endobj 2703 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [292.369 466.882 304.324 475.629] /A << /S /GoTo /D (cite.ATK-Tutorial) >> >> endobj 2708 0 obj << /D [2706 0 R /XYZ 89 721 null] >> endobj 338 0 obj << /D [2706 0 R /XYZ 90 690.045 null] >> endobj 342 0 obj << /D [2706 0 R /XYZ 90 438.075 null] >> endobj 346 0 obj << /D [2706 0 R /XYZ 90 359.395 null] >> endobj 350 0 obj << /D [2706 0 R /XYZ 90 287.166 null] >> endobj 2705 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2713 0 obj << /Length 2397 /Filter /FlateDecode >> stream xÚYK“ܸ ¾Ï¯è[ÔUÓ²ž””Û8k;NÊYÇÛ[9ìæ ‘ØÝÌèÑ©šýõP^ÍÚ5‡¦xp‚Ýyì>ܽ=Þ½yŸ%»Â/D$vÇÓ®vYûA’îŽõîïoø||÷eˆÒÀKýý!wܱ÷ð¯?îãÔ{؇aèÿIS>Ù'÷ã‡/Ÿ>½ûò—Ÿˆúáç?¼Ûÿ÷ø7ïÓh±[Æ~g ‹ÝL8ç.`ínßïB»pf©ŸÅ.¹%É®jï¾ÞùÂrùÇ’Ü|&¼ù؆áî‡þîßðçx'ì°f-³Ò5 ¿fš~’±yŽ¥ñˆ¡w-‘CGçmËZÙ\xP]zUIb÷'¢5åc?©Vû(õ~SZõ1¿ŽÊðZYê—¿î1عl¢u}w8åõ¢*’p-ú8ùÇ}xewî×>¤VN?Õ¡ÉÁt¸CúEʇ#Ý ]=•g©éëQv²4rg,m”ç~çΧÁ—z8ùU(Í“_õƒÜ@A¥~nÙ=œ4@½kÚ¯ìöa꽘‹êÎDdÛÙ¼Ð×lœ<°ÎM_•FÖßTùs‘­þÕŸU}ÞÔ=ý4˜l|tSà}êçk†!ðª¾3²3ôA‡ÄiÃ>̽ó>’ú½4Ê­#_âzBZà=+Â@àú¦é7Ï{‘z>{2~*b>p8ÅÝÃvoÛ±S•Û!LÀ8æYÊŽø¤&P×ø© ƒ5ñúÇÿÉÊâ§ ¼¸î;Þïñ…(—r€oëÂyŸMi¯#äÎJÃU#Ql”Ѳ9ѸÔüK? Îìä@_¦ç_»7 Ögí8 ¿9ŸÆ²m•™”’ö:£¶àkV Ûà<^°uÕÒYcí¼^2R”a’6¥áÉ—’iÕp*kŸšAT³²#D(ìeðÒN©ùáþpÅ>©Nµêw–V[ã‚Π}Ó_Û ¤Fµ[ÐÇ#ä¾ÈIî{\LÑ,Ý<‚ì‹l®Di¤Î U™Ì·P%%Uìˆî…XàˆåõÚ0¶5z1Íf™¦ï›'µwÒ7/ü[ðßn{ØòS•|a˦·¾Fû<£ÍzçÀNêÛ«Ûç‹Yå¶ÜÒB%$?øa¥ÿEézÖ/‡ütÄÐgA”;DÀˆn :)k«ŒUG¿m¯Ý´…MV ˜\5#,½':]®­ “Áѱ‹r?]›R_6 §JÅ"Ûíh3M‹,éYu5.ú2ë¬fhŠQ–ùA¾v Í2çýbrÐå ñNYÎÊÂD°€„ú2i“9Èù:ôgH–šÈÖ(…˜ìd\å`…bð‡Êèèö›Ž ãÕ‘a¹Ò[ø·5æ…`3j‡5u›C  f¼râ$Ë[Ä1aqb¬Cî'¢ +,ÄŸãïí¨ššB[ùR듵IŒ²AC‘ûB¿[!È`鱩iñ£$–74"$xtšB1(‹Tg¿+9˜ÒÚµ ÚË^ùeì“(€¾õ&7zLN´ %')™QrÈS®•EÜ=?‘wW%3ó× ˆàîÜ/äë.†Qó°•÷7õ ¤ uæ0zé›Z“ú«ÞPÜ4 qs·ÇÉ$ÁR{úµ.Þ *xG?¥‰ÍÀÕ QeÆ'MpCž+µgi‰G¡U^™:”Õ -¦`9)ŽðÇ/r"ð×¾½ýÕ¸c¼‚›(÷ã¹Êà½ØPÒ*ÚOp µ”åÆ4s>IêgÁÇÙf83ôõXaëy J_,Ýì.®+‰ó]ƒ¨q z”I³eXS2B–ø!Ô"ëÒ#Zr(I§×"úèÆöQëÚxX¾7N'.NÉê{5…çÚauœ»‹oEÞÿ\lÏYÀÜ«A‘Þ†W Pƒ,üöõh蛃~ÑF¶,Ba‡ióÒ­ú ÉíhËM±Þ0R¼•Óß:3I„÷°|xÛ«.~C?¢Ú«M©«K51H}œÁ[ºF¶æhRà•Í(y=® D’«Ý—¦”¤N_€HT¤ÅÜÓÑëÐdi-è%›´x*26»üUåEžÑ/V¹(¶â„­ˆ*&dùu„m´:×òQ´° JàÞ1rÅŽJ'âŽ.Ü %"û†¥›¤/·ÍòPbUz »D 4\¿h Q#n°Éh)Àõ[Y•Ô Ši$Öþ¶N°ÁZ$›u.¡ä!(zj^ßÓ/Â_NjmeCû"›ÂÏ@²¤ ?˦Øw˜ò¡jªÿ±ð“ô& ¸&Œg;~Ϥ44uÖÓ;ç²°w¯ý]ç¢Ìü`§GµÃ´+”+˜ §W¤×úóÅÿ<þýÚ× endstream endobj 2712 0 obj << /Type /Page /Contents 2713 0 R /Resources 2711 0 R /MediaBox [0 0 612 792] /Parent 2696 0 R >> endobj 2704 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./34_home_taurel_tango_manual_atk_img_core-widget.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2715 0 R /BBox [0 0 419 203] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2716 0 R >>/Font << /R8 2717 0 R>> >> /Length 1960 /Filter /FlateDecode >> stream xœY»’Ý6 íõ* ß2Oj›;Ií\o<›ãñzcÿ~@ )R¹ci\h C8€‚¼ŸgÎÄÌó?|ÞÒôã;7ü2qÆm0žƒœ¡¬“³˜Ÿ?NRIP†…f‰0 Çóf6(fýüü8ýU•Œµù™&)œg*ÉR%Vëü”R‹ ®o€«¹t,¸·HPk™´à–I]$=?þðð78ᙣ¯%t ãàµÓ«?ž>|||Éÿýæaz {§óNð[çúÔð‡ ÞK¿î ÚhæÜ 1ŒÌXF sŠvPT:xÆ×v¤„b\ÉR%ÆY¦ Å ž:7*0/ç‚ëucYWµ¸$A­eRÞ³E „U[Ì”5B¬°ä ·†y1{È—jÖJ2 .ì9¡RB‘9mHBÀÁ;f”™{C;N·¸ˆ’¥H93Aë[ë.Æá(Tq Pµ*©8$/]H^ì§ó©ºëJ‰Vœú7bzHþtþ“Îgë» }í1ª­si`Ï7à ´ åõZèñåýËZé¯5“F@ù¿¦¡Ò¿>=~{|n*ë`¡‚s…k)¼‡?¸s*H»Õºõ êúWÐÄ x {þì t0Œu±)9¾5‚u´tyc$ÉR%½~.3kg¯´*5C¸ÞêµÃE iåZ‡^gE‘@zÀUWì”5blžù"¥ÍÉ÷ëx³Œƒo vœP' ‘È”JVh_;3-£‚Jî¡`))üÈE×·ÆWŠÁQœâ@ Ñ*”â¹t!sq°Ÿ.äéž/%\qê_<ˆé!÷³É‹=nº««ev´Gm`ppb-óŸ^^žŸþüw+u!an0w+=WxÈ#Lþƒ[ëƒ6Ù¥`‚y·ÂI© r>\(×Tx‘PF×¹§—Œ“¡¦Â! Ð [ØMÐÔwÇr‘¢DC¿b°1“•²nê›<¹WßäMMf0MPB°%Ý{3 ŸJÞ•O‘ƒè‘ äßTw·ƒ ÅÁûªÔÔvŸ³t!g±·ž.¤èž+MÕö/ÄóùÙ¼Å7ÏÓÅÊV &~ù³˜ŸqROéý?råîwpéÖÂþ½ß½·ùèe § 7 AX,o5¸˜³¿ÐªöÕí©6a$Ð×\(°ìI°T…Tx! fý|3y)¸ÆZàL·¨$@¥\ÜÎç’@ÔáT¢‹™²Þ ¶ÚFO8„Ìoµ ŸÆVÛ®ã³é¤>™Ïæ? 48ÎŒ¬kر!ÌâÛ&XŠ € 9²¸¼µ~"ý£ÅÞùªTØÄ>aéBÂâ`<ÏÏ=O(Nqê^;ˆåë“)‹=j:¡«5­óP±B®Y¨é7ÏÏŸžëPnì•­ZÈÜtrø%Œþ¸˜I)w_#Ö›<–d)o ¤ùfFHèvù$ŒJ3aÐz½2rpÆ;\”àúí>¬àx vÕ® cÅE_rÓÎ]ì°¢É!RJC,À8’ çž®!€½¡–Tƒ‹.’d)’‚ƒ$‹Ä õ­ñ—q¬8p¨Z•UÒ—.¤/öÓ…dÝó¥Æ+Ný›GQ=d:ƒq@Nòu±Î…°LÊÙäKtØt»­{?’ãÖ½<}yùþ³7 6ÚfǵÔk¹ÃÒ½QÉyÉ”‘ë§È}’ ¼…„á”–m•ËDh¯Žhd®¨$©—B0u0Ñ\b˜˜@Ìà’¶[ôÕ•ó‘ÙÏånχ”Ò†|ã½1 âÊüõx1wfZ>Ý#ÁB!vdƒh}k|­·Gc”âàÕªŒbŸµt>kq°žNçèÿý¨ŠS÷ÚA0XŸÍZìaÓù]­lËçPqpNà° çíÜ2ßoâ]mß½A·™@nhPÊù‡imÖëOI{ºA'%k”[ H²T‰ÉxCSþU-¬=¯`àzÛó |B´¸$A­¼çA(•/è©@DW;´FŒmÏ˾„¼ûÀ•ÊÉçAøRA…KבB¥4Ä"ÿ>‡$(:DRHß|]#ÆŽTÁ-.¢d©Â!’d‡0p}kýÅ@+­Â*éKÒûéB²bMVçKhâ§þÍ£¨²?Á8 § ùºXîù÷¹°º`îÞvò_¿>ÝK=¿þ°É¬ endstream endobj 2715 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152424+01'00') /ModDate (D:20160114152424+01'00') /Title (Untitled-1) /Creator (Dia v0.88.1) /Author (a user) >> endobj 2716 0 obj << /Type /ExtGState /OPM 1 >> endobj 2717 0 obj << /BaseFont /ZTBWNJ+Courier /FontDescriptor 2718 0 R /Type /Font /FirstChar 65 /LastChar 119 /Widths [ 600 0 600 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 0 600 600 0 0 0 0 0 0 0 0 0 600 600 600 600 600 0 600 0 600 0 0 600 600 600 600 0 0 600 600 600 600 600 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2718 0 obj << /Type /FontDescriptor /FontName /ZTBWNJ+Courier /FontBBox [ 0 -186 593 624] /Flags 33 /Ascent 624 /CapHeight 576 /Descent -186 /ItalicAngle 0 /StemV 88 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 431 /CharSet (/A/C/D/E/S/V/W/a/b/c/d/e/g/i/l/m/n/o/r/s/t/u/v/w) /FontFile3 2719 0 R >> endobj 2719 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2315 >> stream xœ}V P“YþC’—_‰1è “?£(ç ã±ŠP—ਠ€'Èa4@Â¥€Bðú¥!\ ‰ŠŠ¢¢Žÿ*8Š¢Ž2Žº*ˆº^»ã¨Ëºxìô?ûت}!qjk«R©ÿ½×ݯûëîïµ€YQ€öKÒ&«b“Mßy;ooÅ&dq0ÿóo"ñgÔüêCvJ¬TÈJE{í­¯ØÀÕP2 2‡SB £p·_’&3Y¿&Uéº(ÜÙÕÕͼ󥇇‡2:³ÿD離ŠOTN i±ê$MBlbª§ÒH«ÕªÕÊxu¦fMŠ2*&&6Ƥ¥Ž]§ P©UMRšÒÉÏY9yÒ¤/¿ Ó‚U ÑÚePRb’r¾rQl¼V•üÉ&EQ£}“üüg'§¤jÓÒ£¢WÇÄÆ««ÃÂ)j,µ€ ¡¨ñÔj1µ„ ¥Â¨pj)åKùQþÔl*€šCÍ¥¦RAÔt*˜šAýÀE‰¨Pà'¸heoU& ÏŠd"è¦xŠ˜CcÐVô^$¹MÛÓ-ƒÄƒ"}¼ŠïÊw±8rÐÈ ôž'ä½!D~;Š¿B™yºœl½®šI¨Z_\Y‘WœÉÄ!¼Œ7ˆq¤Å±áÀ­Xm±åjÖðBÍà(†"NŽsPÐ(Þúnîà4œ Øpp€%{žü4¹·ÙÆqÜ2úVF™-FÀ.t”+-Û]FËö×.=e÷-k(¨I?V‘Ì&ИUI̮̊*(F¯MŠÏ˜·PAœØÀñNÐÊñƒ9!\âýäX6ÁÃ#º@6oßÀP9¾Á#™hч§žc¦Ït7ãÉÛîgOÞ3}úÅœàF¯>ŸÌÉW6,¨ùšÃ†¬X¹*i6LÏ`;†‡ý-Ï+Ö”W±¥tY~I®nëö|"tÞÒõ,;¾)sOÖ?w°óqXp‘bç†âür–®,Ö“HD’j>'[——©è×r‚÷üÄ ßsr•úònÁXæŠ>Ÿ",W`´ˆëÑÊy-Œ“4³'7Ö¯9}`FûJ>ŸâìÚg6pKÒ3œƒñܯ\:IQxÀ9Œ@™Åy•Ä'Œ2ûÇC,4:KÈiEeï)ÓãcÎDs6Ôìƒìß|LEÚØß–ô×…š\¼šÜxv’¢À4ÊÚœŸ›Sš_Å´ãWó î ªÒ’òŠÍ%Y „õHv²¬ê÷7Øíc›jR‹u…;ŠYº\¯/×”dU2ë÷iõ‰ìRvy’ûtº¿lÞqé °‡Kk eÈûórùšºˆÝ‹XÚÙwÅ\uuBm&S›U«»Ÿ¹àî`6-ë<´±*9uLØ×1Sþp²QQ,‘=¬È×ç*d¦X˜dm‚ˆ¬M(1e’?Å]ȺÉÒ ~våA}Æqõ^fÝÞ¸²àâ)ú‚Bm%-{˜V¾©jϘ3WŽÞp11âEá†bI|¯ú‰ ”“¿)«¯fá=' IB0¬%†‚’ìúH:æ>Þ‡¼[V¼ú+ S‡KóJ7oÙ¶cK¾"&Õ?k1KDkbÀÉ@wôÚN6Áß›õCÿ ~žm»EÿðR,A7T"YÂ%Á sì–®>}Ëné&§^—Âßj©m¾¬èϬàDÃHˆB§-Ì䥄Ìc7syüaGÜ!Î@Ø:Ä7‘¡O(ƒÁ®f!WTl²½ÀdÛâÀCÈÙ>#¦ ¦…f­ (·M†ñR4 —øA›øÒÿ4 çÄzê„ò¸\Ü?£9›V®„6òÓm_›ÕCÁˆî^t››“±D±ikŽÝLoÒç•íÜY¤xTS»ëK·]X»œñ—„ìQ³Š4þˆi!SÙù¯n„¿¼{ýàÕEƒhÎüÐ’¥ˆão´žù×Ùï òN $èm¯ï8àM€ß-·@®¹Ç`Ñf¯;ìüìs×Umv íê†0Ü­ õY¼Î?Èÿùhæ8ç™.N^O»»ÿòä 3@‹Ï9ø¡µµ¼T}"ÔL<ãê†G㑯&¨[·ŒõML­aw5[N—æé7ë¶mÏÏW„¯Jñ%’‚YíÀêA;X=¿VÄfíÒU|¬ç½õL*6CñiH78ø„tžßñ»ð&´üÞÂcÞݵ‹‰ ‡uMëöëõwÏ1²“_›‹8a ¼•w?òG uôœéìèEøšö±w|9p!”ͯòU°BÎ6n3d‹æÙäJŒttÇC°í¯`÷¤çêËH\[¶nߢcV¯óÕ±˜b=ïd 9Qõ/­ßw±]ìý=“LD‚ƒ9˜ÈÁ#Ó“FÂè$a<áçÃOòˆÛaGL€ˆÝ¿À4¦_º¸µ¹îVƒå’ÀÐ% ÂnfæFè{²ªþä‘£u,G˺x§fspnHö{iä¯Û|\ܽ½ÝݽÛ_¿ºßþŠéï.Xnå×bÈí/¡ÍDS,ŒÆxªÅú?¨º´¿«¦"Y÷vþ±> endobj 354 0 obj << /D [2712 0 R /XYZ 90 473.539 null] >> endobj 358 0 obj << /D [2712 0 R /XYZ 90 301.698 null] >> endobj 362 0 obj << /D [2712 0 R /XYZ 90 231.157 null] >> endobj 366 0 obj << /D [2712 0 R /XYZ 90 124.75 null] >> endobj 2711 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im11 2704 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2723 0 obj << /Length 1216 /Filter /FlateDecode >> stream xÚVËvÛ6Ýë+¸+yN ãA‚d½’Ûu7©­®œ,` ’XS¤BB–ý÷p@™’)×éÑÍãÎÌå ¨·ð¨w9:›ŒN.’ÈËH&¹ô&s/£^BSB£Ø›Ì¼;ÿÃï㯓ó› ä1õc„±¤þ$È„?þóòK b0ÆüÉ(òõ&ˆ¨ÿåòf|}}~óË-Þ^þ}õñ<ø>ùtróž·ˆ BEXZg µ2#êÐ4걈ˆHr+vâ!OÀ„@¥˜ˆ d”¬¥FwuÀR_«O mL^.ðÐU=ÀBÁ,'\J4{©K]«¢xB‘ƾYêZãVu³ õ+<<äå¬Ám5ÇU—³pÓèÚ©­×E>U&¯Êæ7ÈcJýqïªs£Œ3Rv®Ê*౿ÅÓ²0ι©õ‹ž¶ÁÙp#Yìê8ÓVí1Ÿê_1ªœ¹Í{ƒ ÚÚµÛ•*ûÏxz1×Ì¥-UëwÉLIDå®F„¹*ÝB- ½3ÃÐÌ–Á±”ÈâG áMíþú±ÉÛjÕ¸xl"íº­áO—!4iêÒý››¥³æ¨µÉᓬǽyUX¢çôúE­GDÜÞcœD±€(3q—;Föeî²xU“K“«.å0Ž©óû€Scôç¼1åþF)/Ü—‘›Ã¸L†ê›qàŸ«“·¼ïÈh \&ŽrüÀqùP­€b³ÿxŠ~«K²Äú¡*K=µ.…tŽ ám—U¡;EiF8ì\/{]‡×|Ž9fÛi¸˜À•°Î%I…èd LÈ>æí7´…63Ð_³ÓÁ„‚Ê ÆQÕxÔjºpC¯Ívà »åùlÓ6U ±Þ€çd/½ÐÊW‚‘”E;œ‡¦½PHA²„í·´7#‡tE¬³xP\è“$•Ñ>¢·À2Ž °›£ €±Äwqô=P{²tWOÛ¬å¡Ê3Ù—t4Gq¤Ý½™ŒT±Ç«q‚‹e]§/‘Šc”H#òRÓ>#Ð{íds[î—//‡?`<»>ÐoºÉÇJ”²WÙ±òoæD&D 9Ìn=ŸŒ¬e˜lK ö,^Å$‰¥7]~ŒˆlÿuK{ÕÉ»‹“«ãÞÇjôüºÿÂÎXسÖ>Åö2‘,Š<E$ê^;íœqt8gìÕº®µZááéE^7Æ>2æ»i× ÷’hðhç‡]óÕºÐ+]šVïÚ ¬¦sŽÕ±ð­$ÈÁ C+÷U;ÑÛ© £Qrî_üˆ†ƒ$p_€Ø®\÷ÝhTö±åF§.æa[ŧu¡JeªúùÍ pš£Å|)> endobj 2720 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./35_home_taurel_tango_manual_atk_img_listpanel.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2729 0 R /BBox [0 0 424 367] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2730 0 R >>/Font << /R8 2731 0 R>> >> /Length 1688 /Filter /FlateDecode >> stream xœXË’Û6¼ó+xL†ñ~“*W®ñb ‘w§H»¬Ý$•¿O1¹W©t0ötÏÀßG)Ô(éÃß§yxÆÏO,ZñW”:‹Ú“âxþR;‘ì8Úi-Bj–iµ(i…V£vÑ í0öAx?6 Ÿ€keT"nq›…½¦Á*O’ªÁjm„s-L3ÁV**¡¼Å·”"€B´Q„ðRSuš»L&ÖÀ– œ¢ˆI®ãбմâVŠÕ25KÅ©9LKMQëdž¥ÆãÝ/Ã>¡GÉ˨W“™»rÎ7”3wñçë‹w‰Êš¿<ìŸ<Êò‘øë+š;äùúúåAô¡ù† (Lµ‘‘r¢”ÒÂÅ1€˜—š_Îê”™…xÒKÞÙ25‹‘ÑPç1Ñ1LNh82DÓKd¢õ"… lµT¯i0 ¥ ±Ë&M£ Pf3³NR@e’ÒŽNÅd'ˆæ.Ä ª¥› …Rã>Ð E ·2dÃÔ ŒRõÕ( ǧ Ûšƒ£<åNÁêµjÊ]áæë —»ðóµeºÄcMUv¤óH÷õ•Ë{àùú:I”ÅGK-Ìks©:EhG[zCËBµL«…‚Â5hÄBiˆR¢ƒ!x¼¼y ûd´Øfa/zõ0H?[¬tI¸Pô!CœÊ¶T˜k…|m6U>ì4w™€¤ª- Å¢Åiè…¦†Û(²eZ-ŒÓ4rœ†ÁãÓ–/çá(W}57^MUîŠ7__¼Ü…Ÿ¯/ÕE&-[yØ?y”Ó#í××/wÈó Õ".  "KJExmV±S0FD·vNx×,Ój‰ å!ª´Á•”0Kû$ÓRµ†Û,ìE¯ ˆ!•Õb•S§§£,éÌëV™—ÓÊí4Ÿ¹Ë$U li°Êilöã.Ì EµÑ+†i50HÓÇAO[®œƒ£<õ¥Üx5I¹«Ü|Cår¾¡N¹ÔtåaÿàAN´_]¼¼Ço¨UÆ  4†Î]NakåN0&hàLûÊ<+Ntt‰eað1Ñ«[-S³$URZˆšÚ$…£m—1ê¸,õÖã6¸ÕR½hžihÕÍ­NÈØâÔqÅ(ûWáb,R™ÜkûW!Tæ.Ëⱈ¨– ¬q”@ÿ=îmE­¸•bµLÍRqªÈ§bÔñi÷&â(Y¹Ó°z­ªrW¾ù†òå.þ|C±.qYó•‡ý“GY=R}s‡<ßP¯ÌgdL±ïƒ*¿ùë4?ßïï⨬PÁŒ÷C¹.Yv~ô•qt´QÆ4ÞÏÃw燧?Î?Þÿ9¼Sª€ ªÐÍJkÇûOÃ?=?Ÿ¿üþ×óy|¸>b¶{ï¥òcÿŒà&÷_¥Ãë–êc$ŽÉ`4Õ»Z¦%jDálꉵQh“1ÏO n0â,ب«›+J@œdZ”u\ Ôª¤*;ºmiò÷Ü%bª„55廳ó“IXfX-S³4ָž¶à4d*wšÓª(w…›o(\ÞGŸo¨Ó%*k®ò°ò(£GÚ¯/^îçëkµ½XQJ¸„å…Ž®Ôáьª$Z„º›¾ésóâVC.÷H|iíøp>; !ÚÂÐ1Eã©©bhÒ×ëÉ7}ndJM†^’ŽÌ¢A!ªHìiªÄë4ݱifà_°|ÓåF’H£R‰º,)Œr ÉùÛ§/ÿÐŒv99ÑÍ^«)sÀ>Xx¾és#Qì`^Ñá .ïKŸãÒf?HÁ;Oݲ„E‘îßeò> ût[»N— Ó:‚--úú–NK y¤l+š|ġт`ëRËÅ*ís†n=6· .¹r•S í+Ì‹H L<ô¢QH?Æ`úzUýªD@Û¦±@-×IHw@ÀxìŽÿÌr?â1Q–Cô±LL¬bZ¨‹EÇKë1eŽåŽ«÷RD±L(…æ¾`×+¬ U¹1ÀÂËŸR½ÂP<%”¡=ðÈkñ¡¶ÈÅPÒôÖ ršÓ¡µÅüûŸoH\P”E…R8DQM58ÿµ)ⵋ æØ"^D[æÅ‡¿¾>?Ñ´ g4Èä½Sh”\:¯D &õU¿þöõa"gm0uq(BHïU×sáo €ñ]A,OO_žžÛü8ü0Z| endstream endobj 2729 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152427+01'00') /ModDate (D:20160114152427+01'00') /Title (Untitled-2) /Creator (Dia v0.88.1) /Author (a user) >> endobj 2730 0 obj << /Type /ExtGState /OPM 1 >> endobj 2731 0 obj << /BaseFont /ZXAAOB+Courier /FontDescriptor 2732 0 R /Type /Font /FirstChar 46 /LastChar 121 /Widths [ 600 0 0 600 0 600 600 600 0 0 600 600 0 0 0 0 0 0 0 600 0 0 0 600 0 0 0 0 0 0 0 0 0 0 600 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 0 600 600 600 0 600 600 0 0 600 600 600 600 0 0 600 600 600 600 600 0 0 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2732 0 obj << /Type /FontDescriptor /FontName /ZXAAOB+Courier /FontBBox [ 0 -186 593 624] /Flags 33 /Ascent 624 /CapHeight 563 /Descent -186 /ItalicAngle 0 /StemV 88 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 431 /CharSet (/A/E/P/R/a/b/d/e/eight/f/five/four/h/i/l/m/n/nine/o/one/period/r/s/t/three/u/v/y) /FontFile3 2733 0 R >> endobj 2733 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2601 >> stream xœ}V Tgž˜d2B|¢Vl†Ö*ÖõYhA@TäQÄ'`$Š€ /!$h@„„‡ò¨B¥Š¢èA¡HUp)´*â« íb»´‡ÓEk{§zÎþáaâîvÏÉÉ™;ÿÿß{¿ï~ÿ½ÃÁx“0‡C¸+âdáq†ç¿1Vfî$æu.Åú0ßÿÎ㿎m*›1%[È¡„\JÈûxîO ¸=Цj:Æåp”9Çܱª8Yäžxë…þA¶öö‹Œo–®^½Ú:T5±bí¾Oc½=$†Ë±Ñá1ñNÖîh·\. ³Ž”«b÷쳑JÃ¥†c[BäáQÖž2¹,6V‘h½ÐÝÖzÙ’%KßF+}dÑ¡ û¬½1 ëMÖþá‘ ò¸W^b6wMŒbmܾø„ÄP•4<Âw¿L½xéò+VcØ›ØfÌ[€`ïcØ,sÃܱíØZÌ[‡-Å6`Ë1/ÌóÁ¦a˜%&Æfb¯as°×uKãp9îœæIö“žp¹EÜ_xñ¼Çüµü:ÜOÇû»BJü1™œ6yÄÌ߬ÓÜü“šÊ Q4ØÐÐHstNÁe\ÁW|µá»à*µ&-U§)#a ^¦Ë/)Vç«ÈœÝÆ”óÙÝ&ËBœ]7’À—›¼²7žpÆ[Á†Gh1{ ùÇð±Èt,m4TѳDÁ‰Y)v5ú8ÇãÊ1«œ„YFÁp¯¡õ…Ç QÃÉêOõuV©rmåþªÄâ8*š`)™À˜ ÇxPùøÃum˼#•ý$(‰dšáМnš1£¹pq³¢6ì4vÆðBųŸa*ˆl~f-ÉPÞ‹>§7®r|kžCï³á'½¿c ’iG(¦Ó0ŸþÞŒÀj¨Ãü`\•¯.)ÎוI`– L£KKÕ¨U’`v>„C£­­—Œ®’#kŒ ·Ž$YýÁløËÓ¬9û•`‚>9 †"Þ†lÄKàI™Òô™¥ä}vÀÞhÁm¼T_PTœQD²ëàC\ta&Õžl°:AU¤WÆçkrçSD‘NW¤Ó$•žHÐÅP[©íŠÅ«ˆ ž,žÓûà8Ø€ªÅx0bñž3ÁÇü)ÂÖm‡—¼,ºZEV'Ukz2¿ÐžÒ|’JˆžžJ)‹Ÿ³eƒtù;ž%ùÑÃâLÝ‰è© é€lEÈ6°D >‹hNê¤à?¹þ VyNþ1õqD¡Oþr6'¡„=L,J/=>§þzMσ–˜à#ëÐá¬L‰4Þ#)€"×ÒÑ]ÿëå«Zõù—Ì=Mà9 Œ!x‹›@j)7ÑÿO¸¨ií•vÙ=+ à ˜¾hˆº& Êc žÿë‘ã<[ÇÕv û†‡÷þlˆÂúÐL*~íLv>Ÿ™4¦T#V/tL¿Ä„ÙI&iàìJ¶Ÿu€~~‹ÉqÇqüU@4üŽ51‡ÿ›Žo¿ëwÖQengh/Ó†€ùýöÚ;WHQʲŸŒÚ ÄÙXx&~ä4jãähk㌺ ‚5.i7ìhN³‹Ë”Â1Õx¨<õlä§Ïí‘sK›ÅìvæooÕ ¼R[¨Öedü(KC†E¹%xS,F9ÝN}Aм²vߢ†¨ßãKˆ ÍÁDYº/•ŒP ~& ýnáÍ µ]'.:tJrUKQ9†fQP¤×æÈ%£Žzæ‡SÄÒ[ÜHŸåFe°¶&ÌßA=h¡çøð§!nA\Ô6“ŨÏþ´gpСû ’ÕàÑ uÔOH]‚C2rÁVð¸3`§»ÿŠñÞA®.›[ºî´_@²x¢çO:ü]ÖlØìäèÕ~¿çË›}ãqe44#©Ì¥áÊE.#ƒ?ÅÙÊìJMmLòV|°ÝÕy§ ¥¤T¹y™y³³ Luºò|r}ggUã5²§£ö; Ü`*kfçò‹Í°ê‡»­—úh‰¶U¼ïƒtUJrTdXbE¬õïzüÝ®ž¯?^uŠÌUS‡ÆS÷W0++À¢¢¢¯7£Íë…BZ8Ãþ äÂq1 endstream endobj 2724 0 obj << /D [2722 0 R /XYZ 89 721 null] >> endobj 370 0 obj << /D [2722 0 R /XYZ 90 690.045 null] >> endobj 374 0 obj << /D [2722 0 R /XYZ 90 629.246 null] >> endobj 2725 0 obj << /D [2722 0 R /XYZ 90 593.008 null] >> endobj 2726 0 obj << /D [2722 0 R /XYZ 90 573.332 null] >> endobj 2727 0 obj << /D [2722 0 R /XYZ 90 553.656 null] >> endobj 2728 0 obj << /D [2722 0 R /XYZ 90 524.063 null] >> endobj 2721 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /XObject << /Im12 2720 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2736 0 obj << /Length 999 /Filter /FlateDecode >> stream xÚ½W]s£6}ϯ`ò²f¦È|L¦ìÖö&ÛtÓ„íKÛäX ¬ggÿ{%KÂÈ&8“Ìö!ȺçÝ{î…ØÆ£aË‹÷áÅp130»c#\3Û˜ØS`|#Œ?>wáüÞ´\ßøÀ´ü±=Í™7~[~6=˜Žã ÂObËݽ9²Ÿ—÷Áííüþ݃X]~¹þenþÞ ¾Ûb9°½ Ó²'›8|Ï…-Õ ŽÝÞmyÓ)pÊÒäÈ@•ƒ×A2«%Vd˵ä†$µ4›Êkœ$2«$£g‡ŠöuÑÊ©­®P<û.s2ý?d*‘펓Òzе•JS“úXiŒË<»²SvµÈq‰ýe»±,Ï>eݶv׬±7âö)#µäÜ4¢ÈùäH¹² Ç k)k/ö¸ê «ðµ Ý‘JŠ…mtrºQÇ¢»•}Ø,ÛY[XùSÃõNùd·H§«!¦}¨k¢ø•36HÔDiž pÞè­9¦Ù¯)êø­5Õrwv²ÀFÅŠ¬ÈW½®Mkˆ­Y¬N‹"Vàþ ´/Ì$Ù£šg[¡“1Ú4|Æç³¦«™§"œy!¿þ²}›ý9Ï}gfžÛ±FWY7G(iµ^ëˆ ):r _ˆ»UÓ/*«˜Ê<çU’°É‘B:Ý~ÀúYÙQš@½£Ô9¯ž}‘IgãÝö£õB©xP"²žà›/lñò%ìÜݯb—uQñ;o§3ì×¥‚ãß ÓÃS§þso†¦âw¶xy>ÆqqcòéŽ2´/ço¬èé‘ÿÀ-°¦mù—Àip¿»}0›Lõ$¶ÛeKpÜ ÷4w¨`“0E1çÌs®Bކ-}–[78Å‘aWßÅÈh ”Ñßi´ºRÒx%“#*²—z y¡¿Ú2“æ†ýW„€’_Ï{CGé5Èh¦®óà âÿxƒÈÌ}c‡VG~³Gº²ÒL é-ÉMlóŸºÎËÿ:S endstream endobj 2735 0 obj << /Type /Page /Contents 2736 0 R /Resources 2734 0 R /MediaBox [0 0 612 792] /Parent 2696 0 R >> endobj 2737 0 obj << /D [2735 0 R /XYZ 89 721 null] >> endobj 2734 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2740 0 obj << /Length 1008 /Filter /FlateDecode >> stream xÚW]sã4}ï¯ðä¥ »V$ÖÃð–´]ز;­`Šb+ƒ-ÙnÈ0üwdKr-ã¸)O’¥«{¯ŽÎ=’¡õÙ‚ÖÍÅ×ñÅò:ô¬DXñÖŠ Â+=ߊSëçù»ÛÕ§x}¿°Î}°°ýÎãEäÎWßß|\¸þ|µ@Íãï¤É§û…çoîWwwëûË9zóÃûoÖ‹_ão—×¾Ó‹æ!@7¹´ÁB§±¹€*»å5‚}kÛ !@Ñ•e;¡t墂Ðà4ýúp›åäN|‹>ú²ñ%üØÈ÷ÿkü”‘äñrybÔ œßNdï Ú„\©þª¤é°Íï$©JùQ1Ùî0Mse‰«Šg›º"å[内˜WKDOv猗àŒD9úìX:øJ6”TŠzþCVV '03úy'g_ôÒnàVX1~÷´îYLºJÉS–ÃÉ,K‘·$;÷±È7K4]Z6yþ(Žžðñ$œcþl5žH` 3åOÁ#š óh#Af×y õV²Ù ºÕš„l«(¶#,êH!?s±MÙË4EwX(GVO%SÖû}~Ôaz\m|ªaÑÔù•½àšôbøx™çÊMšö’™ˆ=kge½)ÉŸ5¡•ÎRÖéµƧêJŠ+*X61+öŒW˜VfNi‡6|Ü-ãäqé`€t…yÕ!”ÑÏ'w0Èõ´dhî9.ˆÐP6¡lKòƒB¸!.1ktZ0^áÁ6RAç”Á+H•zßrÙC]™U‘×ɃJè ¥/&»n²îD&X¦LÐÎr¼É‰bÊ{:,¯ë:ÀZ((WEÆèú¯„ì›Î°49;P0•HÜ1K·‡ÝѼ¥zÅEÆ ”Q#¯Š— ®’ݹÚÒiC6™œ¬ò„4îOWL»ÑÁé>…¬@ÈØóLŒ6!f­äêBÑ»ŸiZ‡âñí‹Ç¿áq6<¡-gÅÈâ‰ÙÃ|f ÊMj ]|ŽaønBF^@¢òôF4$Ý[xÕÝ8”´à¥ê_„/ðÐs8'tય&Cà†î†Ýo”n×ñÅ¿ù¬í endstream endobj 2739 0 obj << /Type /Page /Contents 2740 0 R /Resources 2738 0 R /MediaBox [0 0 612 792] /Parent 2742 0 R >> endobj 2741 0 obj << /D [2739 0 R /XYZ 89 721 null] >> endobj 2738 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2745 0 obj << /Length 886 /Filter /FlateDecode >> stream xÚ¥VMsÚ0½ó+<¹¦ÅÈ8†2=‘H“2àô’ö lšØ#É¡™Nþ{%K2¶K˜ž,KÚ·ûÞ~ØÀY;À™4.ÂFgÜ?wî ×í9áʧ>»àéty–»9òbÆÿÎ<J³Ú˜-Á²íQg·B¯°ø`( jnoèÎÕËP"q¾Èq¿c.ÊØ ¥[ ¹a4[ojá@!^fµijöH¬[=k™ÝŠ÷^Õ{G â–¶%Y…<¯¹Q$ ˜Ô}…eQ~Ýêßsv9S£D`ÁŒ—ó}jNà 6áâ‚W‘æ‚õ¥®WùXÒ²ü¸HgMöiK%ð͘>º3¶{éh]ÌB_ôERý’R›fÛdo¼¤—1; ¸Gaã/'+âD endstream endobj 2744 0 obj << /Type /Page /Contents 2745 0 R /Resources 2743 0 R /MediaBox [0 0 612 792] /Parent 2742 0 R >> endobj 2746 0 obj << /D [2744 0 R /XYZ 89 721 null] >> endobj 2743 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2750 0 obj << /Length 993 /Filter /FlateDecode >> stream xÚµVKsÛ6¾ëWpt 95A<>Ú“šÈŽÛqâXj/I¦C‘„†$d´­éô¿ @YÒÈ©¶'»‹Ý‹ow •‹ÑÏóQp‡N ÒGÎ|é¤Ð‰a`Hyá|t_¿\ϧ7ž)t)ð|Awî¥Ä¼»xïêN<„;ÿÕ˜\ßx!tß_ÜL®®¦7¯fFzñÛ囩÷yþKpNñ^´I¬°ôÁâPÛŒ Eœ#¸oí“”&Žc%$æÐßúŒ²÷)µ°7Ý¢ä¹çGºw‚fuÛqy)Y5É%õ5k–¢©Xñ RhDÓ;VKcË£SÎÿê…Ha äP3Û¶Ê=`\†P{ø©·öO™B¾5Í[Þþ¿èU ÑGÍ´LþÎ[¾(™ ›Ž=ë2F…O¨vÏ:|§óÑí©%tæ¥`9y5úø:…’+ð Ncç¾·ª’&€*è”ÎlôÁð÷€Q† C‡…Û”Î×ÌðpÓˆU“UfÓ®EWf] ñÅJEÅäš×+«à_<¤òivJÑš•NJÁ6¬.v¦¢6ß­è®Ì¤~$³ËêâØ `¦îÏÙðZ§²4ä«jAªZHˆŽb¨Ûˆi¯¾½ "…½D)LÑ .+Dœ7BåïÃη?8÷÷¼›ö Ôý[bÛˆ²¤IhRKØóT¤»êJÉwCæböî›"u¦Yڞ蚢 ˆãÓú!ï%Èìü( q³ÆªtqÛeË+^fÙHa¿kfN´êÅJöÏþÏ”'Ã9¬Þ·ÜÚS|©-YÃêá$·xä:“V"O•_!˜¥P-¤¥\×»û!ò¥A÷y+ŠyC&¥løÂÃÐíäài±5ß{^yÖg;žÙHŒOûµôì_ìA_ŸKuшºgO•ÀϪgL ˆQø’z>vÙðp ¤ Æ&‰Mªl¶O·:L€"ÿA Ó&3ó™©”Ö«Yžõ¤é}–;M(½]6¢2«þô¢`†5z-jfšiœbØyjJºnã?ËM ö2@Òþ‘óúvüØ\îpõ]W-X3Û°\µäê߀…/ÅÙÚ /ÄzYe+ö=@å½x&ж Ÿoò€˜ú¨ú˜ãã…IpòÇAÕ~¾6ñµë×¢®™®9Ûè…Q>vìoÌW|òï@tládY÷è§zìÚŒ0½(z76ŸYŒŽs±³ÝCgï®úy’ï™È‘*`’ü79TåJ“£yÜf•]­vmq)ìpÌEU©™Ù‚§°~ï/ÅL endstream endobj 2749 0 obj << /Type /Page /Contents 2750 0 R /Resources 2748 0 R /MediaBox [0 0 612 792] /Parent 2742 0 R >> endobj 2747 0 obj << /Type /XObject /Subtype /Image /Width 324 /Height 345 /BitsPerComponent 8 /Length 34013 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀYD"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?žÚÚãP¼Ô¿âekg¯üÃÍÓÈóúoPÿz¦þÌ?ô1ü'ÿû¶3¯ˆÿîÿ·õoWñ…4½ZöÍ4ývé-çxDð‰$ ÄnR¶ÄqA#ž ®3ó«h¬–Ä:~ŸkÚ\ëòMÕìŽ- F]þÕÁ¸Þ6Ð[nNÓœx¨¿³ý cÿ ÿþí¨lµ{]c]Ñä²°½°µ‹^Ó#O·¾_ô«v.b¸Áû¤çœ ©ô K– E»ýû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š›˜ûO$Ù‡þ†1ÿ„ÿÿvÑý˜ècøOÿ÷mQpöžH?³ý cÿ ÿþí£û0ÿÐÆ?ðŸÿîÚ(¢áí<fúÇþÿýÛGöaÿ¡Œá?ÿÝ´QEÃÚy þÌ?ô1ü'ÿû¶ìÃÿCÿÂÿ»h¢‹‡´òAý˜ècøOÿ÷mÙ‡þ†1ÿ„ÿÿvÑEiäƒû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š.ÓÉöaÿ¡Œá?ÿÝ´fúÇþÿýÛE\=§’ìÃÿCÿÂÿ»hþÌ?ô1ü'ÿû¶Š(¸{O$Ù‡þ†1ÿ„ÿÿvÑý˜ècøOÿ÷mQpöžH?³ý cÿ ÿþí£û0ÿÐÆ?ðŸÿîÚ(¢áí<fúÇþÿýÛGöaÿ¡Œá?ÿÝ´QEÃÚy þÌ?ô1ü'ÿû¶ìÃÿCÿÂÿ»h¢‹‡´òAý˜ècøOÿ÷mÙ‡þ†1ÿ„ÿÿvÑEiäƒû0ÿÐÆ?ðŸÿîÚ?³ý cÿ ÿþí¢Š.Óɵ(ÓKÓ®¯%ñ4Vñ<ÎÃùbqþ׊ÑÔ|?&™¨]YËâDimåh\¦€J’¤ƒôÞœV‹ÿäSÖÿëÆýÕÛêöð]üA½‚ê_&Ú]QÒY7؆Räð03ɦh¤œoe¹ÏfúÇþÿýÛRÚiðe‡_H5{ƒ4¡‚þËe€ª/8BòXä±àªA«Úë\Iea{akˆÓíÄï—åV.b¸Áû¤çœ ÏÈJÏþƃÿ¤Ú}4\Å-¿TdÿfúÇþÿýÛDZykë[q¯ùÒOæ•C¡ùa¼¸$™¶6ܬLÚØ$qZßð—k¿ôÔð*Oñ®kÃZÞ­®i×7×S^\µæ®¦k‰ ŽBÚߪŒžp=„(¸ÉíøÁ<â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ*–DZKøqôGÑÚv›ª­®¿r|?¯ä}:4FºÞÅEñl'—¸½2q¹FyÙµ?ú|Gÿ‚ßþ5^û:ÿÈÙãúñÓôeåu6íõŠþ#ð“á?j×þ–Æ=WQ·6QÚZ­ÔbXä&[”‘Ô.âÛ#fùsJ Jæ¸|¶–&”j¶Õ×—ù)§é𵿽 "x{_Mº½„¬óh×q¢"]DÌÌÍ ©$“Ú¢û6§ÿBïˆÿðC{ÿÆ«×üûOøGÅþ$‹F 6šíá¹¼S%ýÍåŒÖ0YEvö®^æÞâX÷FcµŠªýæ Dð§|=ã½:Kÿ kÚgˆl#”À÷ZUäwQ,€(Z6 0 §pÃÖ«Ù£§û—*3ü—>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñªúö¼‡þ‡ÁÖÿ <]ãÛøµ=6×÷N¯§\[«Þ[ßE"Åöp#vÙšH‚²ÈS÷ƒs®jöhŸìZ?ÌÿÈ>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñª÷ã¿…n|=}¬k÷ö^ ¶²Õ$ѧ]{Xӆ˴@í<2Ʋ»1³‰Æ%@Á=ü, ÿÐÑ¢ÿÈ/ûsþBÿÈ;þ>÷úúk÷=èöh?±hÿ3ü™>Í©ÿлâ?üÞÿñª>Í©ÿлâ?üÞÿñªú²ÇÄzN§¬jZMž©ewªéžWÛ¬`¸GžÓÌ]Ñù¨äÞ •Ü@ÈÍhÑìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgø!}›Sÿ¡wÄø!½ÿãT}›Sÿ¡wÄø!½ÿãUõí{4Ø´™þÈ_fÔÿè]ñþoøÕfÔÿè]ñþoøÕ}{EÍö-æòÙµ?ú|Gÿ‚ßþ5GÙµ?ú|Gÿ‚ßþ5_^ÑG³Aý‹GùŸà|…ömOþ…ßÿà†÷ÿQömOþ…ßÿà†÷ÿW×´QìÐbÑþgøøKÖ/ü=ª[Aá¯É<Ö²Ça^ ÌP€2bÇS]?‹­µâ½h¦ƒ¯ÌŸmŸC¢ÝÈŒ<ÆåYb!ìA ö¯©è§ìÑØô¹yyŸà|…ömOþ…ßÿà†÷ÿUígC²KñáÝtÊ5É®¡´[¶bÚÈdî Yq­Ž†¾¯¢f‚9E(ÞÒzúÂ7¯ÿsÆŸøNÉÿÈ•¡á êvžš‰¢xŽHíÿ´n&žïF¹Œ“%Þyò”^@¡@É,רu‹ãOùõ¿úò›ÿ@4r%©ÊéÒƒš“Ó^Ÿä~lü]²»´ñÕëÝØ^Ø}¡"–$¾µ’ÝÝ6ÜE•†qØÑPüWÿ‘ÿTÿ¶_ú)(¬ÑÉJÜ‘·d}¡û:ÿÈÙãúñÓôeåUðWÁH~Óß¼k­ÛêvZF£.‡6‰qc­ÍmÛ[Ú”˜M/˜ªáFÙЩ°f˾Çvþ,ñoÙg†XéÛ¼èL™ýåæ1‡\wõ¯mò5oùý²ÿÀ7ÿãµ´>{ywû¬?®§ç5‡ìcñjóá›h’øvñðöM$ FÜ«_/‰[P[pQÛæ{p ±ù70 ëÎ>»ýŸ~êþñ·Äoëzwˆ,ïüI.Ÿ¸ñ6£§Oyv¶Ð,"X Qæl’F}›ˆOâõï#VÿŸÛ/üþ;G‘«Ïí—þ¿ÿ«=F¾Dñ÷ìßâýkö€»°Óì÷|$ñ>¿¥x«[+,+eÖ‘N.,å±2qö¹ÖI%ÛÛ ,…2>ªò5oùý²ÿÀ7ÿã´y·üþÙàÿñÚøªÙËân‰ñ:?Û隬6¼S«(Ð.ôÖÔžÇP¶-î![¶6ûKBÊë!‚<®v¥ûx’ÊÃá.›¦xBkúÁtiÚ†»ËiÚoöÔ:žt[bò’fW1+«µ2vÈßsy·üþÙàÿñÚ<[þl¿ð ÿøí|ÿûüñ_«/_øâÒ/Þ˧èÑ­…ÂKiq§é¶QÛZÜG‚]ZAæß´œÝÇÐý#YÞF­ÿ?¶_øÿüv#VÿŸÛ/üþ;@4Vw‘«Ïí—þ¿ÿ£ÈÕ¿çöËÿßÿŽÐäjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£Egy·üþÙàÿñÚÈÕo|I¥”ú#cq¨O> ³ÁQÄð!Ç–%f$μ`t4Ò¾ˆ¢Šã¾ÛãùíáûãUÿä:>ÛãùíáûãUÿä:¿g?åbº;+ŽûoŒç·…ÿïWÿèûoŒç·…ÿïWÿèösþVGcEqßmñüöð¿ýñªÿòmñüöð¿ýñªÿòÎÊÂèìh®;í¾1ÿžÞÿ¾5_þC£í¾1ÿžÞÿ¾5_þC£ÙÏùX]Ëè×~#¿Ô¥µ¹¾ðê²[Is¶Í/^L$!eŠ ?ãâ3œ÷è{kù·üþÙàÿñÚ†švc4h¬ï#VÿŸÛ/üþ;G‘«Ïí—þ¿ÿ¤äjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£Egy·üþÙàÿñÚ<[þl¿ð ÿøíhÑYÞF­ÿ?¶_øÿüv#VÿŸÛ/üþ;@4Vw‘«Ïí—þ¿ÿ£ÈÕ¿çöËÿßÿŽÐäjßóûeÿ€oÿÇhò5oùý²ÿÀ7ÿã´£X¾4ÿ‘?[ÿ¯)¿ôV|[þl¿ð ÿøíex²-E|+¬™î­d‹ìSîXí™þíº!ÇåIìaˆþ ýä~oüWÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#íÙ×þFÏ׎›ÿ£/+Ý«Âg_ùÓïîžytÛ;YKcºÏHÁÙ$°ÈÙÃ"žmÔ}Þ„Õφ?ñùãoûgÿÑ0×M©x‹NÒ5='O»ºXouYž (pKLéÊÝ$lI8rÀ9þÖÐ?èñÿ¶_üGö¶ÿ@Ÿˆ¿ø%²ÿä é|KñwþפѮ×Z¼Ô¢‚;‰bÑü?©‘ËÞÖÐH¨NÆÂ±8Á½¯øŸKð¼vO©Ý‹U¼»†ÆÜmf2M+„@PO,Þ€rHšÓÚOù˜¬<þÖÐ?èñÿ¶_üGö¶ÿ@Ÿˆ¿ø%²ÿä ô}sĆíc¸Ôn<„–U‚%ÎòÈßuv8<('ƒéX—ÿü5¦øjmvkÙÚÆ¤±’8,n&º ê‹Ù’37˜K¯É³8 ãÑí'üÌ,ŽOû[@ÿ OÄ_üÙòÚÚý~"ÿà–Ëÿ+­°ø ßèë©“©ØÀ÷_bŠ-OG¼²¹šm»¶ÇÑ$²|¹9U#ån~VÆÆâM;Äö³\i·e†V·™7ŠHd€ÈØ*pÀ0=£ÚOù˜Yuý­ Ð'â/þ l¿ùímþ?ðKeÿÈëQí'üÌ,7Ñ'ÛÇi¤xª—dQCtˆ¹Î æ“ØÃüú?ÈüÆø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^Wªx÷ÆVþðÕÆ«: å °Û[y‚?>w;Q7r\ðª kÊÿg_ùU%P1+`ÇáP€’I'ȵÝkTð7Ĉž0ÒàûtÐx“ûìÙ°²5Ή¥OÇíicÐ\9¯¥è«=æ }øWÂ>1Ñ ËÞg|Fð…±¸“ïJÊ<;¹Ï»1f>ìjÄš„¿ o53iÔ®þ$)/@—É>2 ±_ªŽ3щn¤šú^ŠñÝwGðƉã}KOñ-žaà¸ôa¤Û\F#¶Kƒ=Ù¼/ $*m>ïÍÏËÞ°e"}FÇ\Õ¼Kfeñ]¥Æ™ÓÞGþ‘ÍáÝ(ÏÉåY™Ø7s€ÝúŠó{ûÛ |f¾Õõ©ÖÏKÔtK;+ÉþX"š‹—Cò¡užÜ€HÝågmr~<Ö.l·ðí¾ ¾Ò5 _KñV㋤0éšL–:tpøµ¼1É,»â2FÌÅ\£dL`®wÄž ð-‡‹E¶¿ ø~xsâ#À"Ô¬àv™i7…’VL8òâ‰îÞ'#…2”?{õ­óoÁm7]mgÁZïŠôñ ·‘õ+NðõÄZœò}ı^Ü›©U™•÷¼H£@›C^ƒû3h¶þßÛÚC î¡á½.[»„@fû*¸õ!wa€0ê4PðÇþ? "ÞÏâ9-äœãMWdR}‘ÈÿxÖ¯Ãøüñ·ýŒ3ÿè˜k¸ ø‹se¢ÜxþóH¾Õ¬<|ËšE¬×(µ ‘j‚Ù`‰."2 Ž$ U¼ßº»Mr?õ û½SVø}âÅ¿‰ôK-"æÞëL6«hšÍ›å^ <Ë—9dP?r­´#¹úzŠó¯ŠZ¿†£ƒKÕ5ÙèSøsZG[ùñ-½ÓÚH¾]Þ«[Ý7.Éþ¶2YsÁhÖ:ž¥¯ø‚îöçGÕ|hš…¶³¥¨··‘LŠÙn$%‹End•9ò[qRÎ~‚¢€>yÖÚÿ[ÓìLÅ寇l¼h?²¼Z’ ‰ì,³}ÂÉ2ºÈ¦åçµ(uÙ6yÀ5Ûü ·xm|c#_M®Å>¾òC M]>Ël¾qòÕcù µ¸1ª©ÀÉ'Óè •þ|?ðÞ·kðbÚÿD±¼¶×þK¨jÐͲ_Ïé+ ÌÄžZÜÌvv†qµq«à=*ÏâE§À{oÛÇâ {ï†÷W—qê+ç ‰¿âJwÉ»;Ž]›ŸâÃu¤è œ~ZÅkªüÔâ@š‡‰>\j:ÍÐÿY¨\«i%%™º»/Ú' Nv‰ +ëÿÌsþÁsÿìµÎ×EàßùŽØ.ý–€9Úó+í ÏÆ?|E§k–Qê:]—‡4Ù-a¹]Ѥ“Ü߉™Aà>-àù‡#y¯M®GǾ·Ô­eÖfÒã¼X¡6RI§=ë’ÂD?x®T€¥9€<·R¼Õ5ïÙóá.¿p·rÍá9níˆgžmGMÜîOÌJeòA*¤t>YüIøƒç_ZxK^VŽ¢ÛKñÔ /4ÎZC #ÊWè«.XŸ.A·å9íjZuÞc{áû«&Ó/tøï$ŠK'‘ÈÁÃ.åR¥N{/ËÛ›©ÙÅ×™ "™…­Ì‘áÑÕÀÞ…K.å©á×*À« wã¿ Osã ýWTÑÄþ}+k{Y&O%™¦œ‰`: Âþ(Ô,|§Iö/Ù ùEÅÂî–g€‘åy†Q.X’’ §iϪüGøs¦kàø‚÷H]@AÙÌ"Õî¬ÞåIfKyb‹ pŒKíI7 ³ £wÍcÆž·¿ÒÆ­s¢Û\mÅ”ßfÔ§µ•ƒd‹Ý ócbU'äñżºñåî—7„¼¢ë:dÞÒ¯¢ðæ¹vlm´xç7l#†@dpŒŒÆ[G‡Àô}*ùu?ÙšÎñ5].< ’®¡x»fº d–A“†lî#'’y­¯x.ÖçF]J]ÖH ¶[ RÏRžÎR¤¶ÃÊAæFĪN3‘´df×­RÇán¿m¼6‘ã\F¶öÿêâWòŒ`p8w~#ÿ‘‡Tÿ¯©ô3\펽m¨ÿgyQ^§ÛíMä^}ŒðíAåñ.ôTŸ½_ÝɵÎ ò>×x£â…añ6¯ž&ÑÒD»™YZþ ArÝYŸð±ü'ÿCF‹ÿƒøª­ã[øµ_…šõì+2Cs¢ÜL‹sÁ(Vˆ]•`bº/‹ñãâÿ÷.ÿöjâ<}ãï ^xÄvöþ#Ògž]6æ8âŽú&gc É$ñŠíþ,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQEQEQE4º‡Xo ¹äŒŸÔ~tê(¢€1¼ ÿg…F½ý³¯3ßê¬×¯´°¢ÀDw6Kb<“‚ØÁÆOMÿ _Ãú ]àU·ø×’xÂ:¿ªxÒãSÑtýFu×çe»µŽV "„…8É'溿øVÞÿ¡[EÿÁt?üMvð•ü8ÿ Å×þ[ð•ü8ÿ Å×þ[qÿð­¼#ÿB¶‹ÿ‚èøš?á[xGþ…mÿÐÿñ4ØÂWðãþƒ_ømþ4ÂWðãþƒ_ømþ5Çÿ¶ðý Ú/þ ¡ÿâhÿ…máú´_üCÿÄÐaÿ _Ãú ]àU·øÑÿ _Ãú ]àU·ø×ÿ ÛÂ?ô+h¿ø.‡ÿ‰£þ·„èVÑð]ÿ@‡ü%?è1uÿVßãGü%?è1uÿVßã\ü+oÿЭ¢ÿàºþ&øVÞÿ¡[EÿÁt?üMvð•ü8ÿ Å×þ[[°ñ߬Rö-7SškËËg´%¸/Œp­œç¶ðý Ú/þ ¡ÿâk¨øàO iwڭ퟇´«KÈ4ˆŠâ (’HÉ]¤«Èʳ;;ÐU°¬êªûŠ Sq Äã`€Àઞ %fx\±Ð´©.fÔ­á½ÕÒÉ¥@óD3æ§Ÿ»£åˑο,+:ª¾âƒÜB±#pèØ 08*§¨³ª«î(1MÄ+r7‚s‚ªz€Fn»â7JÑ~Üu[U¸%†ÔN›®!ä»Ôü¼.1¹ˆä…`MwÄ:n•¢ý¸ê¶«p K ¨7\CÉv©ùx\csÉ À€iK Ϊ¯¸ `Å7¬AÈÜ:6 Î ©êVN»â7JÑ~Üu[U¸%†ÔN›®!ä»Ôü¼.1¹ˆä…`táš;ˆ’Xd‰Ô2º†Aî(%…gUWÜP0b›ˆV änçTõ‚XVuU}Å)¸…bFáѰ@`pUOP¡â=rÇBÒ¤¹›R·†ö7WK&•ÍϘvž~îB—.G8VšïˆtÝ+EûqÕmVà–Q:n¸‡’ìSòð¸Ææ#’Ò–U_q@ÁŠn!Xƒ‘¸tlœSÔ$¬wÄ:n•¢ý¸ê¶«p K ¨7\CÉv©ùx\csÉ À·ÄúÛi>Õµ{#ïmc-Ü%¾hܬe—8<ƒÐô §þ=[þ‚—¿øÿãGü$z·ý/ð!ÿưï|?¬Ø^Ü[Iâ›$24lWÃo‚AÁÇúµCý•«ÐÑeÿ„Ûÿò}t_ð‘êßô½ÿÀ‡ÿå¼s#Íá=zIžG³™˜ä’Pä“Uõó©è¥©ÉâKIc²¶’å£_0,K?Óûâ¯üF³þÏÐxoUMQnôÅ™u=JßW» ,Ÿ½º H¤ûܶЩQ…`§p;›6z'ƒøeõox;Æk©¤Ö›â/†úܨºEžçû î C óɰ¨0¥6²‚:™ø~×@‹F‡MH¬"›í1ª;‰bÅŒÂLïó KîÜI<ó@c'м{q…t«äÔü#s«ø¢m*+­A4ù¯e±UÕϘëK¸–&UÛõH̸fVå<9oâ=cö¡·Ó/¼q­\'†­µK8åû5‚½ä!t ¶IñmœÞùlcvÁÂŒdg÷[O‡^±“M’-<ùÚ~¡&«Ï<'Úž -ÚWvbdcÒ'Î[‚?º¸‚ãág†®u›ãŒ4ÿ†ÖÞ(—Ziç×¾j~0ŠÛìÐ,zmÕ¼6oÂBe”ý°îóL™1©A*v~ x£ÆžÌ>/¹¸o xf/CæXÚâyíßèmˆ¸·aì|ÜKþ·åÉôùþøBçÃÖZšFí*Ë@¸ðÄÿi˜lÓfHRX7oÜw-¼#y%ÆÎdçG\ø} x“þí´ÿÂA¥®‹©þúEûEšùûbùXmÇÚ§ù— óõápÑWEàßùŽØ.ý–¹Úè¼ÿ1ÏûÏÿ²Ð;\§©ë!ø“«øgOÖ%ÐàÓ4[M@ÍoR<’ÜÍugÌVTZ6@ýx®ú¸Oèóé~!»ñŸª>sy¦¥…ÌòèòÞBR’HØ2 ÑùòœF$¯L€sñî·ñi´µ³Õ$ðòMàý'Ä.Ö¶ñHÍ5ñŸh>b¸ØŸfn ß÷¸£Àþ=Öþ-6–¶z¤žI¼¤ø…ÚÖÞ)¦¾3íÌWìÍÀÁ;þ÷¢|€íl.<;©O¡Ám¢ù·:4·iö{]æÊìØñ‰¤ÈcÞ ¯J‚¢ð­…LJu)ô8"Ð-´_6çF–í>Ïk¼ÀÙ]›14™ qûÁ•é@¿ü&>/ø¥x;YÓ.üM¡é7ž¶Ö®ÛÃ662<ÓÜ…`›¯b‘QÎÈþÞ.AùkÙ<)}o©ø_G¼´Õ$Öín,ášNP*(.cµTsÂÅq2x]ü¤iQèî¡£i–º,TqÝi“ÝÛG ì•TmX¦Ubž£få!VºÍÃÉá¯èz'‡,¬´Û{KKq{HE¬[¡]ÈC˜”¨c÷X†*À OĹüYyã-4‹ÿé:-–˜n®&ðÝ•Œ’\LòíU/{¡Ø‘9)Î|Õ$¶¤ñ—u='Àž Õ|?©[L¾¾Ñ!›\¸òüë¸noìàF±ªfXç‘™•T.0ª ›ž1´Ô4ýR]VË_½ÒR{!m*ͦÍ{f›ÍŒ)  HÛ‰'#Ëܤ*Öoˆü¤Yü5ðç†m¥½Ò´m]"æÖvÓæœtû›{…ˆP·U99]ኞ„ĹüYyã-4‹ÿé:-–˜n®&ðÝ•Œ’\LòíU/{¡Ø‘9)Î|Õ$¶·µËë}OডyiªI­ÚÜxzI¡ÔåñØ•™‚*(.cµTsÂÅ,‚úÚýµ› zÿHŠêÁ`‘.4¹îíQQ™Ä¨ ªÅ0Äç#ËÞ¤*Òk: …¾ßhº\rE¦i¾’ÎÖ9A±GlQd g ôŸÿÈê×Ô¿ú¬êÑñüŒ:§ý}Kÿ¡šçl|9¤éÙßcÒì­?³­M—‘n‰ö[såæ°>HÏ•ȸ»N>Q€ ïˆÿòOˆûCöuÿ‘³Æõã¦ÿèËÊ÷jðŸÙ×þFÏ׎›ÿ£/+Ý«h|(÷2ï÷X]BŠ(«=¢Š(¢Š(¢Š(¢Š(¢Š(+áo¯U×MûV¹ÿB­ïþ 4¿þK ®|áëËymî4Ë©à• rE&»©²º‘‚¤¬G§üA»{ÿxŽæ@¢I­®$`½*Äãó¨¯u}WN²¸»¹ðÍÜ6ÐFÒË#jš^d“þ—ØOñí¼–žñ®Éb´sœŒâ“ØÃüú?ÈüÎø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^W»W„þοò6xÃþ¼tßýy^í[CáG¹—ºÃúêQEYè…yOÅ/ˆÚ§þ%ø*Þ+„_ÜYÞÜjÐ4!™]iöÑÈ$ÎPF×¥Û¨*­ž€V®3Æ ìümâ;{ýFa%‚èZž…q`cÏŸãÚ36üñ´Z‘Œù™ÈÛÈ;¦üDÕ5Ú ü;Â/†¡Ò¯ÐÁäÒÞ[ɧ3Ê%Îvªßy{@ûÈù$€7¦þк”_ W[‡B£iÞÓ¼c}6¡©¬R4sÃrìŒb¶ÚdÿE'+«no•6ª·ià¿„GÂZ§…µ5ƒ¨^i:^¥ew+[ì7÷7·6·\Ÿœìý峟7úß½òóÏXþΟbøy­ø_þ ÿÚ^°ðGÚþÅ/ìÐÞGö­žg;¾ÙŸ/#^7Üvw6Õ`Õtíè¶Ë®j1ÜÝÛZ¾ DbÒy%q*û®"]Š®2ßxšÄÓ~1^k÷ú¥hË©jVú³Í Íÿ”–Òé÷Ú\!qn_2W€äªñ†%:¯xN]O^ÒõÝ:ò; gN·¸´Š[‹>&‚sHŒýëxXÃ;‚k ¾!еUÕêM>×YŠtxý¢}JúÞòYA ò’0xsòüÀ߯¿Gáψ~Òu‰?ð­4+ý/TºšûÍÓáûEÄ3X,1fEû“Îv¨ã=­ø?âlzv›ã RçÄ­ã/h:\Zœ^(TŒä-Ã\ÄHd1¤1>äP?}´ò3]Æ¡àññEñ9º 4í*ÿL6†,ù¿i–ÎMû³Æß±ã9ó:¼æÇðÂÐøÅ¸ºyü)­A%´zX]¿aŠXÌsE爈9TÛòÀ»U9/ˆŸõïM£i3iñèZ¦§{¥Ko,+tÙµ>Òò' û/Qr7}òUPk¯øKâCÄÞ¾¼Ô®>Ós¿­Ù#ìTÄ6ú¥Ô®òÇ.z¹$’IÀñ?Á«ÿjºF¥¬ø&»Ò^Óì­Ÿåƒzô¾`óçéñ&á´.I zWaà?ÿ¡ÜéßkûoªjZ—™åù{~×{=ÖÌdýÏ?fsÎÜàg'áü~xÛþÆÿôL5ÒxŸÄ–^Ðîµ[ö³À#‰wÉ+± ‘Æ¿ÄîÅUTrY€ï\ßÃøüñ·ýŒ3ÿè˜k[ÆÞÑþ!XYÚk+zc³º[Ûy4ýFæÆXæUd %·‘£·Ç=20>x›^ñçíüBcKÍ/ZŠÕ-¢ÚRÙM²¹0«7ík‡ÎKžrñê¾$>5¹ÔõÏø¯@Ð_VXé˧2 £Ën×DO(8‘X)ó—k/º_| O†²xâãCÖof¼ñ Ò]Û¾·ww©%£%¤P q5Ái~x™Ùƒ#2²G¸,HE«Ï‡z”Éi{¯K{ .®šÈ³¹„Ép%K…¹Š19~!I•YSfBª `£Å_üPÕôûqs¬%¶®;m®–ÿáþ¹¯kðkİê>µÔST¶ÓWM\‰c2’àIµã²·È»¹ÜÃð²_ùÿjÅÿçöçöñ°ûó¼ÿµ}³h—~6ý§÷Ÿswlâ€5<{ãK¿ MáËM?L‹UÔ5ÝEôÛhfº6è®-..3„rÄ@$€Äncïõ­SÃñ_xr->ÃWÔït¹‹Pó5E¹3¦Ï)A‡ý áV]Á‰UýØ ‘Øø£Â?ð’kžÔ~×öoøGõI5//ËÝöÖWV»3‘·jßœ¹Œs‘Îéÿ³áÿ‰·™ý‹âWÄ¿ñí;í¿Ú?¹ûÿ.Ïí¿Îï+î®ï”Å| ñŠMKáNâ ð˜|AŸB†üø/~‘/Ú/švµò-í’á3!1ýü¦rÙÁ¯jøñZãáÝž³q¥Z½Ž›nn€¸Õ#†æö5MòhB±r£*Ša€0A&‘ðûáσt =\Á®x[N´±³×Rßü˜ãGîb”F7ſІ ªÃâGÀ]KÇ2øÎ+?[i6^*³k[©%ÑÅÕí¾m„ ¥! nhü²I’R®…òñŸâ¾¹ øâ]×…tï:çÂú|é>£çÆ$µº6bá^8]JH#I`‘ƒ²‚ 9OÐ~ ÿ˜çý‚çÿÙkÅ<ƒO´ðö›q­Å.m­ùW:ÌÖ±}žçp…NÝáäE&K /–éYþðµði¦ÏJ—Ä^OƒôŸ°µ¸Š2³X}£i>c/Êÿjo˜dŸwš<à=ká ÓMž•/ˆ¼Ÿé>akqef°ûFÒ|Æ_•þÔß0É>ï4kÇÿi³¬hŠ#†Q#ÉóäGÔðíW[¾Õ5øFWE7úņo¨j6c^ž+HÄí,krlff¶˜otL„RÅrÕñZ¥—ˆïo-ü+e¯ÙÞi‰h*;¿1^Bcå`܉rTù‡koâ.ü¬xgÃ^ÑÂw>.Ôì|?m¥Yê©jhÐ)jÒFï`哹ÁŒ¬><ƒâ–—‡t»­bZë¾Mæ¯5š k Â`»÷I ŠL–òÏ–é[ºÎ¹gâ‚7ÚΜÎú~£áÙ.íÚV,Æ9-‹¡$““‚9Éú×;áoêÿ ¯md°Ógñ:'…4½tÅy¶&ãk0‘—å“íD’ #gCšÔ¯à_ÙÙ|7$¢i4o 9¥^Žb´òÉ]´êþ#ÿ‘‡Tÿ¯©ô3YÕ£â?ùuOúú—ÿC5ÎØéw6ŸÙÞn±{{ö[So/ž¶9òÿ.È× Ä{÷¯”8M ßÿäžx£þÁw_ú%«gâÇüxø¿ýË¿ýš¹ßÚËcð³^¶šòmBht[ˆÞòä –v028U1;UW'€Ñ|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆûCöuÿ‘³Æõã¦ÿèËÊ÷jðŸÙ×þFÏ׎›ÿ£/+Ý«h|(÷2ï÷X]BŠ(«=¢Š(¢Š(¢Š(¢Š(¢Š(’øO¤ß_ÜxÞKk+‹ˆÇˆçRÑDÌò`ã {Šï¿áÕ¿è{ÿ€ïþæš?~!^Þkv~þɵÓ4ÍFk5Yîî!fn$fÚŠG>fIîrqZð”ü_ÿŸ ÿWŸüEwðŽjßô ½ÿÀwÿ ?áÕ¿è{ÿ€ïþÃÿÂSñþ~t/ü^ñÂSñþ~t/ü^ñÜÂ9«Ð.÷ÿßü(ÿ„sVÿ ]ïþ¿øWÿ OÅÿùùпðeyÿÄQÿ OÅÿùùпðeyÿÄPqÿæ­ÿ@»ßüð£þÍ[þw¿øÿá\?ü%?ÿççBÿÁ•çÿGü%?ÿççBÿÁ•çÿ@Çü#š·ýïðÿÂøG5oúÞÿà;ÿ…pÿð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEwðŽjßô ½ÿÀwÿ ÛðÆ“}a·%͕żgLCK('Ž2G±¯,ÿ„§âÿüüè_ø2¼ÿâ+cÂ÷Ÿ5ûùâÕoôx4¸m¥¸º6÷—SHÈ«÷UYUIb@äàN6 õ™â=Ç]Ò¤¶›M·šöGTKÖ‰ ÃϘ7~îJŸ›f#N£–eUŸpBÁKí%T“¸ô\’Œ–QÔ€@3ußiº®‹ö¥ZµÁ)7BÝo!Ô£ååq¬3k¾Óu]ì'Jµk‚R(n„ ºÞC¨=GËÊã;Xf#JY–V}Á /´•RNãÑrHPN2YGR%™`UgܰRûIU$àn=$…ã%”u  ÝwÃÚn«¢ý„éV­pJE Ð7[ÃÈu¨ùy\gkÀ Äià vñ$Q"Ç(UD ØRK2ÀªÏ¸!`¥ö’ªIÀÜz.I ÆK(ê@2Pgˆô;wJ’Úm6ÞkÙQ/Z$/ G>`Üyû¹*~l8a˜†k¾Óu]ì'Jµk‚R(n„ ºÞC¨=GËÊã;Xf#JY–V}Á /´•RNãÑrHPN2YGR%™`UgܰRûIU$àn=$…ã%”u  ÝwÃÚn«¢ý„éV­pJE Ð7[ÃÈu¨ùy\gkÀ Ä;^УÖ<1¨èÑ2ÙÅug%¢²&V ÈP¹ ôã¥hK2ÀªÏ¸!`¥ö’ªIÀÜz.I ÆK(ê@)ss ¼·¤D†I%‘‚ª(,Ià9Í7V¶ÔõVöî?ZCó<«xyœ f$ßnÆzà}UþÊÕ¿èh²ÿÂmÿù>³¿ácøOþ†ÿÿñTÂÇðŸý /þ !ÿâ¨MoÂºŽ½£_é—*µH/mä¶‘£ðã êT‘›ò3ƒèjÿÄ«´¿Ñ{™wû¬?®¡EUž‰Å|Oø›oðÂ\]X½Ý®©©ý‚y’UO±Ä-§¸’áƒ}åD·b@ç#8Á\a¶’Ká?‡úî‰ð§à½¼öDk>·²’ÿKIãÝ#®™5œ±«îØYZà¿ÞÚ|¿½È4ÛIñOÃ1Y[]5ü»./ŸLŽ!g9›íIÊИ‚oWÙAo” –PixûÇúŸ‡àðŒ~ÑíuCÄšØ-¢Õ/dÓ¢ˆ}Žæì»°‚Wm±]¾^rÃ8Á®B×À>!ºñΛâôÃmÇŽ_]šÚIâi--G‡¤ÓÕŸk,Ó*¨[P{1'ÅßOñRð/³´ý}ïu ´ýF[ á‡û6ú%e–)Q™f…HFÉr6î ÏñZëCÒ|cÿ ›c¤ëÑW\ºŽ+ùn,L·ž¶âLfÒ`Ø€°­ |7ñÃHÖ¼Oã"êÛPÓÃÿdkË6î;y”Alä‰^%y’àªF³ª¬ˆMAñá\)ðWâá‹+‹ÍgZÐ/l¢kÛù.nn¥ki#…ââFcË`| žœÖ>¯ào\ë~;³‹K™­µOé^)³ÔRxD 5ÒÃZ0/æ,®leÁÙåía—Šéµï6‘‹qMyew¬I£Þ·‘2Oc"ÙÏr3nc2;±Š4…ùêÃ<é¼'ã-+ÆÚt·šLÓ:C1·ž»Ymg‚P–•d¶²¶A*ÊGÉkºˆ|]âê3h ¦[èþ&šîh廊IÓû*ö• ™§EØŒä¬Hù‚êøÃÚ†‹âŸˆ÷—–þM¶¯¯Å{dûÕ¼ØWK°€¶%y«†ÁùsŒH_ ãóÆßö0Ïÿ¢a­ˆ+oø3V×ÐjÚCºC/”'”±Æ_ °3²‚Ø888Åd|1ÿÏØÃ?þ‰†¶¼oay¨ønh¬4ý;UºI ™lõDß ¢9‘زûTìcÂ¾Æ ŠÍøuâ­oÅ–×·:¥§†á·Ö8&ðæ¼úª;sæ+–¶„!_“nÎã¸ü@¾%Ûx>;IL’i÷w¯xࢬÁ_Ÿå½Œ–ü£qÜ;C°Õm|SâÿK¢ÝÀ·z}¥µ¾ˆ²Û››‰-Ë™yAäóÒ1ºAÄ+¸¨ékUðö¡sñ“Âúävû´«-W²žãz“Mq¦¼K·;Žå·˜äÎHÈÈNµã¯h~0Ò4É|+áé´ÝSS6vóÃâ9ÍßÙÆçyÚb‰ óq»–Rdo‹Œ"˜Ò3á¿íïøGMñºÄÿhûoØwvcËûOÉû±ómÅj P¼ø¾ÚÕÌÒtý ml'Þ§|óÎÍr6çpÚ¶Ö¼߀NN¹à}CÄþ,†Î?ÝhðkÐjóëKª$– ÂN;u“pžS+–…pLHÿÄéž)ñ–“àË{9µiå…o'6Öé´·M(ŠIv*F¬ÅŠDødeˆ+Cø·á_ê–:}†£,—7ÁþÏæÙO ;¢–xwº*«3BH‘B±*8Ǿ¿Ö¼SðâîÎßζÒuùoo_z¯• Òïà ‚AoÞÏár~lã‘Æh?uû/øAüí?göo|A­]þú3åÙÜÿlùðÜîû]·Ê2ÃÌä ­€Ð~5ø¾ëáŸÄMcÁš-„¦Ñã×ekKu{ «B&'Ék(Ñ™P’TIØ»Œú»ñ3Þ–þ;ýA£þÏÙöÙ"¶–Xí7Ëç:)XþRæ#‚x9¯ð_ìûwá/…þ• Öu=kKÒ¬`Ö<)©xŽêæÂá„Q,è‘IpÖêñ•o,ÜðWt¹ñÏÃ|WeãÝMѵ-bKKš×D6Ú¥½¦›½®×[¥gÉ1”ɱ¢+å«Íwÿ~3è <ñu¾k&‹6©˜–¶É:l÷—¨J¬ÿºoݪ8b£œœœ ½uyöµaàߌ¾"ÕµÛètí:óÃztV’ܶÕw‚æý§U'‚ظ·ùG'#ƒŠØñgí#Ñ¢Ó[[¶X®íQg²Ó'¼”¢Œ-ÊùL|´RÙV#‚IÜp0x³Æö‘èÑi­­Û,Wv‹¨³Ùi“ÞJQFå|¦>Z)l«Á$î8ó_„²†-£Iã ´ÒØ|=ðýkÖ+ºâÔÝý©=\àù~ñÈàℲ†-£Iã ´ÒØ|=ðýkÖ+ºâÔÝý©=\àù~ñÈàâ€;ßüM°ÒtÝ;G—Sšc«[}º!¢øvûUš@›@¸_²‰<¥S*”,:·Þl wEðÔô›+Åó1qL<ëi-ŸæP~h¤ã<òŽ/CÈ5áÒto øWÂxÇPÖ¼?­Úx#K´k±vÖ°´‘« 'BçWÁhÛ †‹ Çv=kÁºåôü1ã `Ó5»‹Ôì±*ßJ±¡ˆgsLûGV`$PÞ:ÖŸ¡ÇkuªÚiV7×–ö¨òZ<Ó=ÔŽ#ƒaW!Ÿ …ùyf8\®ÄˆÐøfÈ躄ºœQËÝÍs¦xKSÔ‘Ywq5ººFP†`¤î\†9MRøù¦ÚËáPx¯müI Cä|è’kšyuÑŒiŸ÷E]øË!¿Ò4/ ƒ…ñ>±—0þý°Y.nc>Ïom2g4ýsâ-…ÿ…ì¡ZŽ]JÂ-W÷z5Ô·"2¿%ÁŒð*î$oPU³’Jüº^5»PøW¯]Eq äSè³È—ÿêå!—“òœärx=Mqß|A¡xÇZ£x®ÛÃúAjlo-L¦þ(eâKL²†¸ <Ãbù‡çBÈFÜÝÒ4¯ ~Ì–Z-ô"Þ÷MðzYÏ9ÉF\÷ÁR(ÛõýS‡]Ô£R»HÒæEUYØ3T?á#Õ¿è){ÿþ4xþFSþ¾¥ÿÐÍs¶3êÒg}²ÊÊ ö¥ï|‹Ç—ȸýÞ#‹1/›2þñ¶±>C¼ìwÄ/k0øÄÒG«ß$‰¦\²²Ü¸ ˆ›Ôß?ãÇÅÿî]ÿìÕÎøÖK¹~kÏ6×í¢Üˆ-¦3EžCnT¢PrRG;GJè¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQEQEQEQEÃü1ÿÏØÃ?þ‰†»Šä<9ñoCðTúæ§x>ûW›ûJio®×I–ó}Á ‘¼6 p#$“³ÿ oÿDóPÿÂjoñ  j+'þ"ßþ‰æ¡ÿ„ÔßãGü4E¿ýÍCÿ ©¿Æ€5¨¬Ÿøh‹ú'š‡þSðÑÿôO5ü&¦ÿÖ¢²á¢-ÿèžjøMMþ4ÃD[ÿÑ<Ô?ðš›ühZŠÉÿ†ˆ·ÿ¢y¨á57øÑÿ oÿDóPÿÂjoñ  jè¼ÿ1ÏûÏÿ²×ÿ oÿDóPÿÂjoñ­-ãeljnæÓ4ÿê/q‹-Ëh’[$Qm%Ù¤f@¿S€$%fxŽÞc¥I=–«qg¨ïXaµQ$¥²a·Êy`¤™ ŒN“®ÙÜ&‹æZkPjjR¡+ YÙ²7cÏÊ~f ü9!@C“]³¸MÌ´Ö. ÔÔ¤BV³³do ÇŸ”üÌørB€‡:ÔPN»gpš/™i¬]A©©H"„¬%gfÈÞA?)ù˜/ðä…táCH#JÊ ˜úœ2}€ú(3Ävó*Iìµ[‹=Gzà ªˆ™%- …¾SË$ìÉlbY®ÙÜ&‹æZkPjjR¡+ YÙ²7cÏÊ~f ü9!@Cj(']³¸MÌ´Ö. ÔÔ¤BV³³do ÇŸ”üÌørB€‡0øÃK¹Ô¼­éÖÛ®¯.4éíâÞUZGh™FO 'ØsÚ·( ëú†¯q®êRÁ᛹à{™9WSÓu,H °FG¨¨}«\ÿ¡V÷ÿš_ÿ%ÖÌx²ÓÄ:÷…u2ßÂ÷I=í”ÖÑ´š®˜3¡PN.ÉÆO¡­ÏŠr$Úg‹dÕãxîÙYNA65n±|iÿ"~·ÿ^Sè“ØÃüú?ÈüÓø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôGÚ³¯üž0ÿ¯7ÿF^W»W„þοò6xÃþ¼tßýy^í[CáG¹—ºÃúêQEYè…cxkÆ7Œ"Ôdѵ¯×N¾ŸL»òò 70¶Ùc`@ÁSøÈ5³_)éƒWÓìõ=9ä ã½o_ðé• kpšõñóSý¡i%Ûçþ#ô_†ü øÃGÓ5]ôêÚf£q5­µå¤I$„ Ù@=ºŠøÆ /k^ 𦗥»Kwâ é>)]9g{Û-9òîp2|øôŒœsótÀ¯¢~Iý­àËŸ°;üO©\ë*Ç«@ï²ÔŸ³En? »ðÇþ?2oêºw„ôRñkÚd÷i;ý«VòÀx®"1 †ÉÛ&r09ǾִÀ²ë¹‚ãRÕ¼L§\Ÿ]sa§é—±ÚˆI»Ev´JŠÌêí$/»} Z?|C§ëWÞ4³³¸ó®t‹Yl¯Sc/•3Aár@ û¹âl®GÍŒä>QðF£­¥å½´ž ƒÇ¡u!m éÿdm)¢7Kv¼’É%q¸Ü{ì™m¥[^üi S¢>§3Ùìº:^›™'îݰ (M»FÜPuYž#¸˜iRAe¥\^j;Öhn”Ä©\¹g ó¨f@'{CþÍ7þÿøF¾Í­hÿÏì;ß±«ó?ãóÉû?ÝãýgÞù~÷Ê_hV~1øËâ-;\²QÒì¼9¦Ék Êî$žæüLÊñoÌ9ëÍvúíåÃè¾]¦u>¦Å'ŠbÐ…—'a&LüÇåb¿Ã‡85ÛˇÑ|»Mê}MŠOÅ¡ .NÂL™ùÊŇ 1qâ¿ -ÏÄæÑ‹í¨ƒáï‡ï6^)e7Fìܸ£þâ›ï^hÔ¯5M{ö|øK¯ßßÜ-ܳxN[»bÙç›QÓw;“ó»¥g|J©Õ®Þ\>‹åÚh÷SêlRx¦-XrvdÏÌ~V+ü9ˆs8\É;FÑ3(&7Æå>‡ŒbEyŸŽü1=ÏŒ/õ]SDOøyôx­­ídš4]>t–fšr$a€èðüé—_³ðkwàÅíî£ð{À·z”ó]j3è6ÜÏp1$’µºfÿh±$ûšßñÄÃJ’ -*âóQÞ³Ct¦%HŠä…Ë8o˜ðÅ@;2;Øk·—¢ùvš=Ôú›ž)‹B\„™3ó•Šÿ@bã“ø…á›_Ýj†ÞßOñ.¹˜‹ƒªÞ‚ÙͶáQP²¼Œ»7’2!ùYJ¶y'Nðþ±ð³Â¾"Õ¤¾ñ“ê>°´Ó¬µ"¾eÜ­ñ"'ð\K½KÉ»" ” ì@=K]¼¸}Ë´Ñî§ÔؤñLZ°2äì$ÉŸ˜ü¬WørçÕÏ VçÄûxí4AìŠ(n‘9À€ÖoâÕ~k×°¬É ΋q2-Ì¡Z {™wû¬?®¡EUžˆQEQEQEQEQEÃü1ÿÏØÃ?þ‰†»ŠÆð7ü!ž÷öμϨj³^¼VÒ‹!!ÜÙ-ˆòN c=7ü%?è1uÿVßã@¨«¿ð•ü8ÿ Å×þ[ð•ü8ÿ Å×þ[R¢®ÿÂWðãþƒ_ømþ4ÂWðãþƒ_ømþ4JŠ»ÿ _Ãú ]àU·øÑÿ _Ãú ]àU·øÐ**ïü%?è1uÿVßãGü%?è1uÿVßã@«¢ðoüÇ?ì?þËY_ð•ü8ÿ Å×þ[[°ñ߬Rö-7SškËËg´%¸/Œp­œç\|#o©ZˬͥÇx±Bl¤’N{;‡W%„8ˆ~ñ\©Kr027uÕ°¬êªûŠ Sq Äã`€Àઞ Æø·Á’èÑêO¢[²ø>Ù&Ñlnô› ìæ[8ïd„Ås©=²Æ?˜ !M£#qM¬¸8n–XVuU}Å)¸…bFáѰ@`pUOP%…gUWÜP0b›ˆV änçTõ€âëÀž!Ô´hï^VÎá-õ›«C8;™mäŽ æ6báRMÀ’ÃhÝóviÉ}aoo:½¸¡—eÃŵ£up¡©)•©ù]r¬ ±SfXVuU}Å)¸…bFáѰ@`pUOP’€9xB×T²—W¸Òa¾Hâû¯£5¥ÄŠä‘ò×÷ˆä±ä27aø÷á.—«­—‰fÓn£ŸL³]61£xŸQÒšc¸AvÌŠÁÊ€RQA ^,+:ª¾âƒÜB±#pèØ 08*§¨³ª«î(1MÄ+r7‚s‚ªz€@âoÛ/‡íïeÒþÛ•’i’Iý¹v—n¤|°´ o¸ÞT€]‹3gp²×üol¶ µût‚+T‹F¸`ƒý\`@À*ð8è+¦–U_q@ÁŠn!Xƒ‘¸tlœSÔ$  (ø…áX|M«Ç'‰´t‘.æVV¿ˆCœ‚7Vgü, ÿÐÑ¢ÿàÂþ*»?øHõoú ^ÿàCÿð‘êßô½ÿÀ‡ÿòïxûÞñ½¿ˆô™ç—M¹Ž8£¾‰™ØÄÀ(²I6…ú}]X°V©Ãzgð#ó§Wü Ðo­>(ü`¾›Äšõ©ñ"F4ÛˆíEº³izlŠà¤+&äV._nŃ>\ïéš–»âÏøš+M]´›Oëödû$rÇy³¶¹”±8pÄ\”R¬˜Á!ù¿¢¼rëÇšñУñZj ãðñÑÌù-oý±ý˜\±_3yÏœ`: ¸¬jšç‹|%c­Ëª›kþ Xi­£=ªÚoClޝĂBð,»‹ÚÌ6t`ô áÿ ¾$xïÇrøCY›Âºõ¦‰­Û «ÙµÒÖÆÖ'·ibkqÃ\“¿Ê&HrÌŒWað+TÖ|Mð³Â~$Öõ‰µKÝoE°¿‘cHžHÛhå·s‘œí >PGÀþеýSÆ—ž‹§ê3®¿,ÕfÐ|+¬êvê=•”×1¬€•,ˆX‚2=EkW;ñþIçŠ?ìuÿ¢Z€5ï|?¬Ø^Ü[Iâ›$24lWÃo‚AÁÇúµCý•«ÐÑeÿ„Ûÿò}t^#ÿ‘‡Tÿ¯©ô3YÔÏëçSÐ4-KS“Ä–’Çem%ËF¾`X"– §÷Å_øgýŸ x–×™ä[ÜÅ¿ݵXg…g|Gÿ’yâûÝè–­Ÿ‹ñãâÿ÷.ÿöjOc Gðgèÿ#ó â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ+l|Í/áÇÑh~οò6xÃþ¼tßýy^í^û:ÿÈÙãúñÓôeå{µm…æ]þëë¨QEg¢ÎÝ|>Ð/´üë ÿÚZ¥¦µuûé™ymö"^¿c·ùFù|ƒ¹³ÑQ@š÷ƒ4Ì&¾·—Ï Ö×2ÛÈñ“4l¥“<í$޼sT?áWx\xwÄz i1Å£ø†#¥iމ2Hí6®ycȆ$6ãnG$“ÕQ@–~ Ò´ÿ_x†Ú)àÔï%×—w0‚bHÐnòŒbD›wíP»±ÅG©xBÕõxµ;»6ê9¢¸ÿ]"ÆòÇÌRA¸1„7–d¼®rÎy¨µ/†~Õõ$¾¹°v.â¿UK©£ˆ\Æèé7–®~è×-Œ‘r ¨¢€9Í?áï‡ô­RßP¶°òî-Œl†ic&w˜¢,R2A ”QÃКÒð燴ÿ x{KÐô›²iZe¬VV–ûÙü¨c@ˆ»˜–8U$’qÉ5£Epÿ ãóÆßö0Ïÿ¢a®â²¾øõSÅ7wwz~š—ºä÷éyrä‹dhhɲ63‚@Î0A=¿ü!¿õÑð/ÿ­@>»ám7Äok%ô2íš ‹yä‚X‹.ÖÛ$l¬žxô¦éþÒ´»{Kk[wŠÒÖÚ[TµÈad‘•Ÿ|e¶ÈÄ ùÜŸo}Ý×ü!¿õÑð/ÿ­Gü!¿õÑð/ÿ­@giðÃÃÖBÿʶ»2^ZÉdóɨÜÉ,P?ÞŠBЯP ©ÀÆw†~ xcÂ:cëñØÍbÚwÙnÐÐ/´üë ÿÚZ¥¦µuûé™ymö"^¿c·ùFù|ƒ¹³èŸð†ÿÔsEÿÀ¿þµð†ÿÔsEÿÀ¿þµsµÑx7þcŸö Ÿÿe£þßúŽh¿øÿÖ­'I‡A·Õå—WÓ'ól&…Þä3 ÁÒ€8Ê(¢€ (¢€ (¢€ (¢€ ç~#ÿÉ<ñGý‚î¿ôKWEUµ->ßWÓ®¬nãómn¢x&q]ÈÀ†# ž”µâ?ùuOúú—ÿC5ÎØøsIÒÿ³¾Ç¥ÙZgZ›/"Ýì¶çËÌ1`|‘Ÿ*/‘p?vœ|£^èzF£{qu=•ÛO<,…uÝMf98Qräôü"úüøÞÿàÿTÿäªÅñ®›i£|,׬,-a±°µÑn ·µ¶ŒG1¬ ªˆ ªÀº/‹ñãâÿ÷.ÿöj¥sàï^[Ëoq¦]O¨c’)5ÝM•ÔŒ Ý`‚8Å?â ÛßøsÄw2Mmq#è V''±†#ø3ô‘ù™ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè´?g_ùc™`e†áQ¿Ç®,ô¹´Ýkæñ­•ç‡WÍ(ºŒwKo;O’aS¾O½ˆÈa¸’ Ô(¯1øeâŸkŸ~%éúÍžšº“­ KàÔIãÆÆTÊû: ¬³4¬ÆBUähÀePçþ{ëïêv‘¢N×J¿ƒNÔ®>رI ’CÅ’6uH牛æS‚B†#¯¢¼öãâÃEz”zRËá³®½ÿÚ±0¸7ŸbÜ!Ù‚‚ç÷yÞ2ÛqXâ¾¹¯xƒáUÆŸ§}‡ÂÞ*Ô$xïVxåk›_ìËˈ’T* EÌpʦ6cˆÙX¯Fö+È<ûMxKÇž$д½3XЯN»æ ,5¨®o¬O7úE²Ð.7$å¶¶°Mv |mñÁº?‰.4˜t›-[OµÔ-/ îVXƒÃË@ÈÁçp §*9Í@¿ñŽ­â©¦ñV½§¥ž±5¤0Xܢƨ621êç¾1ŠÚÿ…cqÿC·Š¿ð.þ5GÃøüñ·ýŒ3ÿè˜k¸ þÇýÞ*ÿÀ¸øÕð¬n?èvñWþÃÿÆ«•=ÖÛDo6©"ÙÂ<ºJÛÅ䘵Ɨ’Å|Íû³.Cã¶Úõ]bKøô÷:d0Íz̈¢áÊ¢à3œ ªY¶ñ»nÜ®r9OøV7ô;x«ÿáÿãT±¸ÿ¡ÛÅ_øÿ¯=²ø½ª¿>jZ¥þ£o‰|<·×÷z.–u Aîͽ´ˆÞ(d>Yó'guˆª•Œ|¡ÅD>,ëZLJ|k6­{¤¶¶ºÔº¾‘¦ «æµ¶¸H` måJyxE17—¶`Uvå@=þÇýÞ*ÿÀ¸øÕð¬n?èvñWþÃÿÆ«gÀ—¨xRÂw×#ñ#0qý§ ž°‘xWml7+|«÷Gxkã‰ÈñewE*²ÎV@ ˜U FãèP'áÿ^xwÆÞ&Õ Ôà“I×§Kéì$´>|wkoolfcËò­—(c's¼–˜<}aâMGQÒ5¡¦Zê·ðê:”dYešHኩ#"¼pD­ò1À%J“‘×Ñ@yu𙦉tÈõe‡Ãƒ]_µˆµÌæà^‹â¢mønFò6‚Wv*3áÆ—{àˆcÖã:ƒæ/¦éßbÄž_ØçµDyDœ”Žp)È%ƒ/¤Ñ@gƒ| ¨ø2×EÒ-5ÑÿÖoö[]=l”Jñ*ì‰%˜±ÈEÆ6*TdžAÑøqáøWÿ“}qãy-¬®.##KE0ɃŒî+¾ÿ„sVÿ ]ïþ¿øP—…’ÿÈ?ûV/øG?·?·‡Ø‡çý«í›D»ñ·í?¼û›»gÛÚÇv“ޙᖔdŠ{r]·¶ñ#nFÖUÛ•,Û_ðŽjßô ½ÿÀwÿ ?áÕ¿è{ÿ€ïþäÞøE7„ü=à+};YOíŸ h#@Šúâ̼70˜íÖBЉRÍi ?Ë‚2A56ðªOÙi“hº¤1x‚ɯØê7öfx¥7×"êï1,‘UVP®6íæÔÿáÕ¿è{ÿ€ïþÂ9«Ð.÷ÿßü(ð7„£ðO‡—LK—¼vºº¾šáÔ)’k‹‰.%`£…d¯Ø`W5ào„ð†¼ÿ‰·Û?áð´¾ÿmŸkßöß}ó³aûŸ7úß½òüÞ«ÿæ­ÿ@»ßüð£þÍ[þw¿øÿá@Uào„ð†¼ÿ‰·Û?áð´¾ÿmŸkßöß}ó³aûŸ7úß½òüǾÿÂÿ óþ&ßlÿ„KÂÒøkþ=¶}¯Ø}÷ÎÌ}‡î|ßë~÷Ëóz¯ü#š·ýïðÿÂøG5oúÞÿà;ÿ…gWEàßùŽØ.ý–³¿áÕ¿è{ÿ€ïþ·á&úÂ=nK›+‹xΙ:†–&POdc@Q@Q@Q@Q@s¿ÿäžx£þÁw_ú%«¢¬ïéðx{TÒüß³ýºÖ[o7ní›Ð®ìdgÎ2(¢ñüŒ:§ý}Kÿ¡šçlt»›Oìï7X½½û-©·—ÏHÛù¿—dk‰Æâ=‰û×Ê&ÛZµ¶§¨ê··qø’Òç™åXÛÃÌå1 ûpÎ3×è*¯öV­ÿCE—þoÿÉô‹ã[Yl~kÖÓ^M¨M‹qÞ\„ÎÂGª f#'jªäðâº/‹ñãâÿ÷.ÿöjÊÖü+¨ëÚ5þ™qâ«T‚öÞKi?0`®¥I¿#8>†¯üJ»KýÅ1†ÍÌŠ¨1üé=Œ1ÁŸ£üÌŠÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}¡û:ÿÈÙãúñÓôeå{µxOìëÿ#gŒ?ëÇMÿÑ—•îÕ´>{™wû¬?®¡EUžˆQEQX¾5ñ$^ ðn½â Œ"*ÂâùÍ˺D(ÙÎö$p¸^J£°^øËá? jw¶…õÔsXJ!½’-2êhlÉŽ9CÏ2FcŠ=’¡ó•>÷Í•lvÔWào‹v~5ñ¿Œü5©ZÜøwP6bâ}6ê8'Qom#7œñ,a·Ü¨—EYW(á«wRñæ…¤ki—wÞUÜ“EoÄ24i,¼EÈ¢3ämV œŒg# ÎÏñ@·Õ“N’ø‰ÞèY >ÐG™‚ùaûm-œ1ž+÷ã>†¾.ðŸ‡ô÷…ƽ¨Of²ñ Ž+[™žh™“láZÝc!åóA'  E`éÞ9Ñ5mM,-oç”9…Ú )ö}ï*VP’ÎB1àÐQáhþ:Ó£¿Ñ'šîÊXb¸Žáí&…$Ir•2"†ã‚JC`ŒPã߈W·šÝŸ‡?²mtÍ3QšÍV{»ˆY›‰¶¢‘Ï™’{œœVŸü%?ÿççBÿÁ•çÿYß ãóÆßö0Ïÿ¢a®â€9øJ~/ÿÏÎ…ÿƒ+Ïþ"øJ~/ÿÏÎ…ÿƒ+Ïþ"±GÅYµúé1ÿÂ:ºçö_µàþÔ-7¶`§ÚO—÷÷qœWO⻿ÙéÑ¿†´½3V¿2€ðjº”–1,x9a$vó’ÙÚ6íà ¿á)ø¿ÿ?:þ ¯?øŠ?á)ø¿ÿ?:þ ¯?øŠÁð¯Å+íCÁ×:Ö¿£ÙéÓNM2ÂÛJÔ^ù5"S¼ŸšQ å1µ<ÍÛFV¥ñÂçþokš^—¤½ÏЬ£Ô6k:ËXYÙÀÖÂff¸HN Æ€ycq|ü¸Åvð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEixZÿQÕ4 ;ÍVÛO´¾™K´Z]ó^Ûm$ì)3EpWiÎÁ‚H'’¶øõà«ËT¸·¿¾¸Ž[t»€C£Þ»ÜÄÊ|*!Ý(PFÿ,7–x}¤@ð”ü_ÿŸ ÿWŸüEð”ü_ÿŸ ÿWŸüEC¬üTðƇi¥ÜϨIs©f÷ö'N³žôÜÛ¯•ºHÄ(å€ÆÜºK}Õb&ðçÄ¿x·Um;JÔ ÍÏÙþ×måŽ;ˆA ÒC#(I•Y”1Œ°RÊŒ€ð”ü_ÿŸ ÿWŸüElx^ó↿0Oa®#òVßûdjl…wy›ÀÌ #€wb Ð<â=0|ÐeÒ$6^ ˜%Þ°nae¸DÒîíÕwïØ3(ÃÌ=ªŠð¿„ÿ¿á›Áv·ºN¹}{áè m«ßø²îâÄH¶ïn%·³yÝ2èì6˜£XöÓÀÐ> xzÿÂ?ü¡ê¶ÿdÕtÍÂÎî êþ\ÑÛ¢H»”•8`FA ö&»J(‡øcÿž6ÿ±†ý wÃü1ÿÏØÃ?þ‰†»ŠñÓà=hhŸð‰ÿeKö3ãøH?µþÑ’!þ×þÔÁ]ÞfíÙ‹nÜwÝŠïü[}®?„¼Wý‡¦Nu»kI×KYd‰Vö³‡ˆ¡ß…_1¼¼É°îF8Ûµ›£¢€<šo„~&Ò¯<(Þñ.‹a§øwHM´±Ö4)¯Är…Ø÷ ÑÞA‡h§!ˆðG˜ÀÕø[áxá§ÂÛm[AÓõODðúé·ñZEw¶åB!‘æ1^\¤82£®Ð6W±Ñ@§Ã ÞxSÁñXßK‰//oLÛ–Ùn.¥ pDk*Æ1ÇÉÇÁü*øy¯øoþßö–ŸöøGüq£j_¾¾ÏxßÙXåc»?fŸæ\¯É׿\û=ã ¾ëþÿ…5ý¥§ýŸþïO¢ê_¾þÏxßÙ[cùXîÿYþeÊü~eÉð§áî¿á¯øSÚ:Ù¿áðÆ‹©þú6ò/û+ü¬wgì³üË•ù:ò¹öz(®‹Á¿óÿ°\ÿû-sµÑx7þcŸö Ÿÿe vŠ( Š( Š( Š( ¹ßˆÿòOZýñÿ_|"ÿ’±à¯û Ùèô®JŸ4»›{|U¿‰ø#ô«þÆ…ÿ>ZýñÿGü/ þ|µûâ?þ.¿5h£š]Åíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº?á|h_óå¨ÿßÿñuù«EÒîßÿ??~•ÂøÐ¿çËQÿ¾#ÿâèÿ…ñ¡Ï–£ÿ|GÿÅ׿­sK¸{|WüüüúUÿ ãBÿŸ-Gþøÿ‹£þÆ…ÿ>Zýñÿ_š´QÍ.áíñ_óóðGé…>>x[Â×±ZxlÜ=íÜ—·Þ[¬¯$¯€O2`ªªasÉ$¿øj­ þ…koüÿŽWåsK¸{|Wüüüú™ÿ U¡Эmÿ€ÿñÊ?᪴/ú­¿ð?þ9_–tQÍ.áíñ_óóðGêgü5V…ÿBµ·þGÿÇ(ÿ†ªÐ¿èV¶ÿÀÿøå~YÑG4»‡·ÅÏÏÁ©ŸðÕZý Ößøÿ£þ«Bÿ¡ZÛÿ#ÿã•ùgEÒîßÿ??~¦ÃUh_ô+[àürøj­ þ…koüÿŽWåsK¸{|Wüüüú™ÿ U¡Эmÿ€ÿñÊö¬Ò>Ïs^K_>&…ÞÞѶ°ÁäI_–tQÍ.áíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº?á|h_óå¨ÿßÿñuù«EÒîßÿ??~•ÂøÐ¿çËQÿ¾#ÿâèÿ…ñ¡Ï–£ÿ|GÿÅ׿­sK¸{|WüüüúUÿ ãBÿŸ-Gþøÿ‹£þÆ…ÿ>Zýñÿ_š´QÍ.áíñ_óóðGéWü/ þ|µûâ?þ.ø_üùj?÷Äü]~jÑG4»‡·ÅÏÏÁ¥_ð¾4/ùòÔïˆÿøº øñ¡Om,ëe¨„Žéí)w¬QHOßé‰ÓñŽ™üÕ®·Sÿ’OáÏû êŸú"ÂŽiw¯ŠÖõ?}ûÿ ãBÿŸ-Gþøÿ‹ª øÑ£jÚ£e¥òKso$(Ή´R~~œ×ç%^]È•\Lââêhü‘ÖüWÿ‘ÿTÿ¶_ú)(®JŠFp,T{ÿÙ endstream endobj 2751 0 obj << /D [2749 0 R /XYZ 89 721 null] >> endobj 378 0 obj << /D [2749 0 R /XYZ 90 327.532 null] >> endobj 2748 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /XObject << /Im13 2747 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2754 0 obj << /Length 1601 /Filter /FlateDecode >> stream xÚ­XÝsÓ8ï_á7ì™‹êØŽ§À•R À5áfn8T[iD+ØJCçþùÛÕÊiì:m{òFÚoý´»Šï\9¾szôb~tü*;Ë’0qæ 'óÔŸ0;óÂùì¾|=ý8?¹ðFaì»1óFqâ»s/‹ÜéûÓ^»S/wþ–X>^xcßýpz1=??¹x6£ÕÓOgœx_æoŽ_Åážµq1?JÁc,‘çÈ·Þk¾,‹A¸G-û(LAEDB1‹Xäß÷ÝsU{ÁÄdUUô-d³.ù­¬®è7׺–—^è»-š·|gLX2!3b~è.¼dkŒï7X ·â™ún¼ 66IUå-Q¹ªYˆZø;p›œ— möºXm¼*h·Rº¯L/¹>l”—"#ùRp-¬žo©[ú\Jm‘Un·¶öûuÓhÌ…‰Þ$Â_ó¦AQ”‚ˆN´TJ'.p&‚,!·Inàïg7Ç,ƒöÐ5M½`šWWŠëk¶•ŕЌL€z63™{úÿ’b+êµJ;®›ŒFiì–]KǮԴP(úò²$‚"Ž¿’9à<™Äî¼]쇋*)\ n¤ðÂòX7–»¶kàJH±•î‡Ú±º:H¸XèE¦È<_µollEwÆ¢þ!â"¹¥†;» ­æª®E³VUA%cXö¦“a°ì&²Ø¬n½$vMB'TA€`xggìj~%¥u¯kB±–J]ö ~#w©ŒUZ¤\‘óÊ»ä¤}—Z=½”â‹BT}“>Û¥B¸âV? °‹×¡C¿L>‘Ñzó¨CçÛI,Tº;ïày„1…ż(ê´DW©›ÌMæÒ)ùa¢4Ýk*,°må%%õ®¶¹skgx¸`u[Ì©¨ðÖ˜jRÒº-ÛÀèºáеlÊ U–„ˆw[Ó§nïôR¨ºlG`5cab3M™¸ãù<Š!Ú¿¡¡ÃmݶZ@Œ{—»g ‹Z­ç2‡Ó±îçâÌ:>Á9Y5Ð6´äºï׈2=hÄ07]¢U?ÐÑ’˜M`± ­ú\¢8õØgQ°ë|+¡—ªèÎ*CЩJ½|<«Ü"†›9èj³•î…w-a }DŒŸm^Xgow©é{Ù¿Q+ëÑšW” ìÑ{´ŽZlõŒK÷¯Ö¥åÁJ0PâŠéz]Êœk©*¼Ñ0EY`î òqúœoJ-GWæF ŒBw¢ØæÇ™;£aEôr§ãŽ6 ÍŠýrÕ¯qA–öO&È&Ý)Áð`IÃSÒhå 4•2ÜÜ˸D¡ÁH»ÙØîÐT«Pb  6ÜS Ú3hB¢51q‘ø`è—_*<*]дߓùÑ·#D9Lïø û! ³ÄÉWGŸ¿øNë –¥Yêl ×ʉ² ‹ýèÒ™ýyO¥y¨ôÆÈ`Ì2?u¢IÀB?j‡ÕüÚ4üÐ+;Íó6Ž0bY`OmµVµ&¾¯ü†g ½yUó•x>Ô‹Šœ‹js¦Åêù <’zÁëzJ8Œo57xû§9&|Ødždîžô ÒOJŠ}¡jxø¼ãP'ôÓ ¾T¥ª îÞk†5Á¦í[Ã|Ôâ°Ž¶ÉC´ßs±F¢ëÌ“½9›7ÕMÚ?éÍMû3;Ôþš–3‚\…}ˆm´,ÙI]«ú5dWÕ·¿¦é´æ…¼§Õ2¿Eë¥Ì›Oð»yœ?3÷rEïÌŸö°¯³=ÅÿMíÌTtØJ×›Kèa¤4/áOä½Ú–K¨…å¡:8¤ô_³fl2™tÓÝ–4o”† bµ_«ö5tn«7#ó.68I˜Œaåø˜<1Ô ÂCˆÚJÍL| Ú›´¡˜ù$é¨rdÔàZœ­#ÓÖdU¨mßû“ÍžÑÒjŽÿ°mW endstream endobj 2753 0 obj << /Type /Page /Contents 2754 0 R /Resources 2752 0 R /MediaBox [0 0 612 792] /Parent 2742 0 R >> endobj 2755 0 obj << /D [2753 0 R /XYZ 89 721 null] >> endobj 382 0 obj << /D [2753 0 R /XYZ 90 690.045 null] >> endobj 386 0 obj << /D [2753 0 R /XYZ 90 573.466 null] >> endobj 2756 0 obj << /D [2753 0 R /XYZ 90 538.968 null] >> endobj 2757 0 obj << /D [2753 0 R /XYZ 90 521.43 null] >> endobj 2758 0 obj << /D [2753 0 R /XYZ 90 501.835 null] >> endobj 2759 0 obj << /D [2753 0 R /XYZ 90 480.182 null] >> endobj 2752 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2762 0 obj << /Length 1119 /Filter /FlateDecode >> stream xÚµWO“›6¿ï§`ö3S0cìÉô@Zï®Ón²YÓöÐv:2Èkm@8 ìîdòÝ+! –ÙMÚ<Òûÿ~OïÉ1 Ǹ¾x]Œ¯‚©±°³É̈¶ÆÂ1gn;S߈ã÷Ñ7á]´¼7­‰ïŒ|Û´ü™3ŠÌ…7 ß]¿7=š®ëŽ¢Ÿ8Éݽ9uFï¯ïÃÛÛåý«5ß½þeõãÒü3z;¾ò'mS׳/ ¶ÔÊ‚£¹p„uã+×éR[ž?·'Ó‰aMºéq¦Õš?¬c‚´¦sÇ•eHÈk&Œ ²\×^øÂŸÕ»*ÛÀb½‡1)ªÌ´¼¥ÇÏѯ2ð©óSFŒÎï«MŠbÓb"×0Îqî÷t”ã?ß¡?WÇø¹Þt©WÞDœÌøÉx,Ä©|Y’j»åK’óÿ¸€€@±·‹ ⊯6,0lpˆ”|±¯Ò4ɸe)u¶²¾çùâí-=z éž605§ß¢ÞK%ùí’þMñåݼ|‰ö‚ÇoÒ.Ò!ùí¿ÒÍg´¯̸ŽO"í—Öv<)C±âݼ|ž$I3<þŒJ1¬×è`ƒ#±ábbŸR6vƒ…íMæ:ûö"ÎWÆ!G… ‹m^d0aò¹Æ%ÓÎiàœTHÆgéTx*G°½þR3Z“¾´±²´Î4H£!c"¥¶—fE^ÜÐØýÛt+‚”œ/Ù ÅÎóâéò…Rþ+L{>q{yiP0ÿ?Q 1G“n½ óó@PÜñ{5/p òl¸³‡DÒÙk¥K,ÕuáÉå*òicÐh•í⢠ái‹ˆ~ÈCÖ²ÙW¾y¤Í°T; ³B¤‡Ðþº©,{=¤ŽCiŸ1£¾#4v÷ÅõK"”ç nƒwq“ {½¬e‡Bõ !ýMH š3Êö)äk°øN9WgNÑs@§Â_Ï ŠøḗfRóM$È•ðÈ2 zŸ‚§fä8"²S,*Å´¥Du×F òfÜR]—0ÓˆC|Se ?‘2Ê ­ƒ>˧)¤£¡S’Ý|õvʦâL3=\6·âzwH¡Žy°yœ`G޼ÊÖyU²A=m]³‹¬®¼nÀj)¶·3òê˰7G;}æ™’3qžeô£nõFJ5óÕ”½9yKë¹’×e.&ëÒ=Ü@Cœ*h¶}<6u'õÒèÀD½l±Å> endobj 2763 0 obj << /D [2761 0 R /XYZ 89 721 null] >> endobj 2760 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2766 0 obj << /Length 1153 /Filter /FlateDecode >> stream xÚWKwÚ8ÞçW¸ÙNƒ1‡áôÌÂIIšt’p‚ÓM§ a_@Sc¹’ eæÌYÛ‡ÉJ¶÷~÷Ó}ɱV–cÝ]ûgýÛñ¥5±'WÃ+Ë_ZÇ;¿ÙÎ¥kù¡õ­sóÙ›ùÓ—noè:×îöÜ+§ãw'£Ž÷t÷ܹ¯; :þµeöÒ½t:Ïw/Þããôåý\ÍÞ½Þšv¿ûý[wx ír0²ÑX`‘ÊÆãlÏ™£ÑõoÎáîÞh8´Gã±ÕŽÅäHбÇy·wå8ßÕð§ã:÷Oéfô~ƒV þjqNñ"åÀl†Ù¾sFûa'A‡C·7ˆûòÈyvæc†Æê „²ÑHŒ{âjZþ•KNy2@?–T6 ~až‰pÞB{¿ß0+1ÌÐ^ÛVPq““ EKEd—sÉ×ôJ„c`ïÞ©™ú2ãšìô¯§BqïêH4O’‚¢Ú—$ê³þHBˆÔßøš„åûG±æa‹aÚg8úZj€((â]{’ÅX™FX ]»`j„“&Ï+bd“.â³0›XY#ºª¸rˆY¡½Ðn·Ýü1±9’qŠ#Dš;@&†mÙ­/PïÖØlÊm:4B_#be%L\l+â'b¸á¹¾žIsç=F‡B”ˆ8+k+ áû¤Â`qÍñTãŒ}•ZmãnŒ‰üÛ˜*ây"¥æX\LkŠe®;†KÇT–ÖP·T…3£°J!œã¿AÊ{¡-²ÑŽÛŸðb&’E¶|é8j}¤’ÕÉü_MîÉšî( ±Èg:¯Jµ0×bve²oke/RÞˆÐöý®Ù/,“Û=•¿/佈PðãdjU­N>u Œßª²Ái çÚ˃†µ),OCÇÅ¢ v¾kÓìëèËÈ‹³Z4C1¦3ãþ@{Q]KnrMh´Xhõ‰ɺé1q|q,Ùž?¿úŸß(÷0ºêdßLŸD/ùVá÷_'|êÍýFÇnwŸ˜Œ½…–nIzŠRó-"š[›Äk2µð†4ÒsŒ#Ê ‘-*Å1Â,¯…FµO÷ïƒNWbx12Zã¹"«Ò© £Xù*] ¦z¯"ådÈÂí…Àk$Af²ßÔ·EŒ2ž.—e€ÑõT ò¢sn«Ò5ä$*Ó5sêù_D‚KDËÀ^9Ž˜*!>Çó@ô–2á L ‘0ú}/{SÉÒ/Ža^éX”íy8Eªçô+fxÁqž¬­µv’.DcŸ{47ß[‚CC)–FÌ…×"¿}×nCWì„ϰÒ8˜¼7Ñm†o‹2Ûo³¢@þ3Åü^¼A<ùR›]º™qÔÔt+k«l©¶Ü’?RÍ8õÏþ­0 endstream endobj 2765 0 obj << /Type /Page /Contents 2766 0 R /Resources 2764 0 R /MediaBox [0 0 612 792] /Parent 2742 0 R >> endobj 2767 0 obj << /D [2765 0 R /XYZ 89 721 null] >> endobj 2764 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2771 0 obj << /Length 1833 /Filter /FlateDecode >> stream xÚXÛrÜ6 }÷Wè-ÒLWÖ]«öÉmœ['ÍÅ›Ìt’º¢Ñ§ïž?¾t>m^œ?‰ƒÉn‘º^˜‚/z³t6g{wþÄ÷¦Ö«0^»AX« …Á&ýs,FBÐø¾›ÅìûÕ±WâàŠ/•úèÅžÿü_´õjÉü­òæƒí°­«³J<Ͼ•UA’èºgU¯žÃò;UÉæµèö²;ˆ7¢¡Ë[Ñ(6¿Eü¥õ¼OH{H½‹ìŽn/Ôûª¯¶µÀ T7ˆ:Ì*ÈÜõz½ A6íåæìó™¢gù˜qšºaZ»ÃÙ‡OžUÀ88ï¦YjÝi«ƒfk7ökëêì eÓ,¾¾¹YY1.£í7eÕ;«0Ší¶“×]~ žëJȦ¸h[@»¸´G(ÍÔmóÝM~Í:ô[g{ÝKivõP˜E«¦‡“¼ ºp€×ÆJJw‰§Å6’øC8ÂJ댜øæÔí‡íŠñÄQ 1ë´ÀQ—Ý»f¶x©U Š0$AØuMÓx~xJ²»¡/+›FhÚçýä}ð‰tÞœò‡´a »¡!AUC.:Ïi‹I Ùˆ¯qWåiOùêctbWµ,ÓiAzM¤ËûÌÝŸÈ}ð&gWÙ˺–Úw˜ÞSp—¹QæëÛ. #rÓwç6VpÍÛ‚¤Á8Ëk¿˜§ô¤\°+ŠJ™ó)žÙ„{Ú5ÛœH0Mùž }{нƒ-„û®"‚Jí­ ˆµEæ/¨{WІ$f°ë¡#i﬛ždÉfø¤" s‰uû“%&Ði¢ 8îS<ª@«/J/ÁcŽmò- ÕÄ·¥·÷Î ÷û‰-&ÆÆIzƒ£9H¸G uðöw•B^îiDŸ…é rõ`NÞ–ô SŸüÂCÔ2/H",A=ɳÔ$5ɺbÁ‚M½o?eSLÊyMר•’¾6Aþ)Æ·EÚÓ%Œ§¾]©¥€-&oyRÑ TWefº äÛ^Öƒâ^›«’$ú|BIsßtÊ èP iG-¹»÷c³ÍsÄŒ øœÓHÕ´ƒZº=àCä‡~öaGx«ãÞl‰'¤’‹˜L"]ÇI|{Fæû!ʦ^Boôr2}ò-¤{ü&Ÿ.2¯vø+ï–èpòÛÌ¿îq0 endstream endobj 2770 0 obj << /Type /Page /Contents 2771 0 R /Resources 2769 0 R /MediaBox [0 0 612 792] /Parent 2780 0 R >> endobj 2768 0 obj << /Type /XObject /Subtype /Image /Width 906 /Height 378 /BitsPerComponent 8 /Length 64441 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀzŠ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?݃Å^+¿»½ŽÛZò`³Ž’kýNæ<´¦mª¢8¤'ˆ’qÔTßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“¦uñýÂÿöþ­êú—ƒ4MZ÷NºñVË«9ÞÞUòatb¬9œ õÈ~yyYY_æÿ̵ÿˆ5[CƒRñ.œögWÓÝã…ôÅÊÝÄÊ¡Ô)%€$H$€3Ký»âïúôïüêü‰XvZ¾“«ëº9Ñï$¿µƒ^Ó"iÞ4@Ïö«v;v»‚`3‘ÎF8Éš‹è¨ãuÕõ~^f·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“E+™{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3Z={ÅÒÛCp¾'ÓŒ3y›û_PçdqöNÏÃ=4nø»þ†};ÿú‡ÿ"VMü‹z?ý¿éÊî¥Õ®4?TƒH†þK­]­RîhHdÀ,$-ŸÞ®2£8cžY¬¤ÓvŽÞoüÍ ÿM«ÝÝOâ]9ïàÒ'K`5 æ*îË{o6  Âò‚IaÆ!·|]ÿC>ÿƒ}Cÿ‘+'NÿÝïý.?ô²ÆºM_W—L¸····±X…³|ö;Ð#1,ÈI$’y=è¸ÝOv-¯Ï»ó2ï뺖­âE}¨]^Å ƒD—´Š…žì1POí\ã®Ñé]c|nð‘ø¨x*N÷Äzt¶Ðß[Øè—×1Z5„Í+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯xø‘qu'ޤ·MCP¶‚=6ÞEŠÒöhsKpˆF’FO ¯0‡âdžåðn§â£ãV L’Xo¦¹Ôïa’ÖXÛkÅ$NÂD“qFWq,¸rçÑ¥–άE$“¾þFO'‚vçwü–ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯Dð÷ˆG‰ìžêÏQñD1$†"ºŒÚ•”™„œ£Èù€Ær3q©¶çþ‚ú×þ î¿øån²jÍ]I~?ä/ìˆ;û¿àžOÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã^±¶çþ‚ú×þ î¿øåzw‡y¼#|òÍqq,ZÄÖâ[›™gr‚ÚÕÀÌŒØÁ•ø×>#-©†‡<䆲h?¶þïø'Ë?ð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥çû?2¿±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'Åð—è?ôÓ¿ð.?ñ£þýþƒzwþÇþ5ö¥{?0þÄüüü?àŸÿÂ_ ÿÐoNÿÀ¸ÿÆøKôú éßøø×Ú”QìüÃû?óóðÿ‚|Wÿ ~ƒÿA½;ÿãÿ?á/Ðè7§à\ã_jQG³óìHÿÏÏÃþ ñ_ü%úýôïü ühÿ„¿Aÿ Þÿqÿ}©EÏÌ?±#ÿ??ø'ÆøI³ðÞ…çê–Py©{,~eÂ.ô:•Þdò­Eÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ™rÉ£'~Ãþ ñ†•â=&mOSž=RÊH!Ñ&óe[„+ol@Üs“Ó5S^ñ¼®¢'µñ.ƒkÁ +¸•‡—!%„ÊJ“ÓŒãœdýµEÏÌØêÉsíåýw>ÕµkìŸO?ˆ´«Û«­8ÛÇ«,ue dbI2~‚½Æž)Ñmüc®Å.¯a©:º=ÊR$`Aà××uó_Š#ÿ¡nÏÿ -?ÿŽÖÐøQôywû¬?®§ævƒðcâ’|,–ÏMð‰¬5_øU·6ŸbšÚFc⇞k\°\Èö›ÛÉûÒ#`+ný™û)ø. ø—â^¡7¶§u`mlÂ’økKŽhí¶Í%”Ó¼£p1 ãŒ3§Ê\·Ù¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚ³Ñ8OˆŸòPî?ìkÿ£®kã|4ñÿu¯ZiwRx Æ °ñä©o#Y,*²>¡×;wE4²Á "«`e@d AûbóÁþ#ñ¿‹µkŇGÒ>ŧÙG*^ê¢PÁåºØQ­’POÊùS‚¡áßð©üCÿA/ àeçÿ"WÑЫÂIY¯ÉßOšf.÷º??®<âã no´¦ðÀøâ+˨µãUµ‘e·ˆZ\=Œe^t$LUùT¶sÎ ßüM§Yü9²Kê6ž$Ðך•ËYµµæ“cý©Æù¶<ëky° ˆwthÇèGü*ÿÐKÃ_øyÿÈ”§ñý¼5ÿ—Ÿü‰Ul.¿¼ßþù½ØùSöUðlj­.|iâ/XßézÝôš~“5®¢䔨Ú$-t&?ëDÌÌw Œ©Ã¾s_cü$ÿ‘CTÿ°üÿúEcXð©üCÿA/ àeçÿ"WIá/ x‡ÂÚ=Õ᫯>þKï3ûFñ6ãìG8ò3Ÿö±Ž2qÅΔ¨F•)]§ÏüÇÞìéèªGˆ»á¯ü^ò Gˆ»á¯ü^ò xžÍù}èÒåú*‡‘âîøkÿ—ŸüƒG‘âîøkÿ—ŸüƒG³~_z —èªGˆ»á¯ü^ò Gˆ»á¯ü^ò Íù}è._¢¨y!þðiyÿÈ5‘ˆ5»0ÚèúmüQË$&{}vÞ$.ŽQÀ[*NX|È3ŒŒ© SƒJàtÔW9ý³â?úìÿð¢ÓÿøíÛ>#ÿ¡nÏÿ -?ÿŽÔ èè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠç?¶|GÿBÝŸþZÿ£ûgÄô-ÙÿáE§ÿñÚèè®sûgÄô-ÙÿáE§ÿñÚ?¶|GÿBÝŸþZÿ ŽŠÄ·¾ñÒÆ!Ð-%™ŒÛ¡[µ)còw3¸b‹Ÿ´FîÝÎp ›>+ÿ¡j×ÿÖü]jÑYYñ_ý V¿ø>³ÿâèÏŠÿèZµÿÁõŸÿ@´VV|WÿBÕ¯þ¬ÿøº¯¨j~ Ò,仾Ñ4û+Xñ¾{YF‹’Ë$Æ€7h®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíè®#þBÿÃøWi¿üvøY ýÿ ÿá]¦ÿñÚíëåÈ×­×ìßú1«è-Å7ž%Õ ±°‹A¸šGD>O‰ìfØÕÙˆÜÊ8’@’|ûâïùõ¯úý›ÿF5cS¡óYßÃOçú?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}\>z™wû¬?®¥+½oN°Ôl,.¯ím¯¯Ë­¥¬Ó*ËrQw8IËíPXã8šƒVñN‹ ÞØYêz½†w¨IåYÁwr‘Irü|±«\ò8ê+Ä<}ðÎh?kO…^/ÓìuKäœêßÚ—§ÌšÚÉOH ?rfónwsÉÛRÓÚ+>ö-n ]îàÃpì@*98«=ï?Ç÷Š¿ëž•üõ Âý þ.‰øC¯øçû'ûsû+ìÿèiû?›æÜGúÍ·fïºsŒqœÖãûÅ_õÏJþz…r?µ­[ãoÀŸx+C¸²´Õu?²ù3jéùwQJÛŠ+0ùc`0§’:u­*oò_’,jß®>éÐ^üM±Ó<7¡—¥/‡îïu¹o.¥––Qº±ü¸ ¸’88 £ |nð—Šâ-[U²Õ´­ÀW%Úé°Ï-Ó]¾§%ûùP¬e¤VBŠGï¨Äcv»Ûübð…Ý÷¬âÕ÷ÜøÞÖKß§Ù¦m†8wlìÄxÕ±&ÓÎÏÙ×ÈŸ±WÀm[Áž'Ö|Q©ÙÞéš•kwá_èÄö÷·zYÔî.Úêò Y$gt Äghbc£7×tW—è¿êõû ßÿé\µêóâkž8¶¿‰á¿ßiÖú½ìis¨kóÚÌäÎìsYJˆ9Î3Æp4_õ_¨ºž‡Eyí爾&YZOpþð™HQ¤`¾*¹Édãþ%µ7öÏÄïú<%ÿ…U×ÿ+k1åå—>?ø‹kâÍ7ÃÏàÏ Ûû«ø¤_Üùb8$·G ³³¸›¨ñ€FdŒ ëÿlüNÿ¡CÂ_øU]ò¶€;Ê+ÏlüEñ2öÒ „ð„ÂL‹"†ñUÎ@##?ñ-¢|L‚[toøL™ÜƸñUÏk7?ñ-ôS@…EpÛ?¿èPð—þW_ü­¨`ñÄÉå¸Eð„ÁÄmŸ\òv«qÿßFèTWžÞx‹âe•¤÷àÿ ”…F ⫝̸N?â[SlüNÿ¡CÂ_øU]ò¶€;Ê+Ë.|ñ×Åšo‡ŸÁž7·ö7WñH¾)¹òÄpInŽÿggq7QãŒÉ×þÙøÿB‡„¿ðªºÿåmw”WžÙø‹âeí¤ àÿ „™E ⫝̸€FFâ[Dþ"ø™¶èÞð™3¹q⫞Önâ[覀= Šàÿ¶~'Сá/ü*®¿ù[PÚø‹âeÜLéàÿ €ãù¼UsÕX©ÿ˜o¨4èTWžÝx‹âe¤Jïàÿ ]#ù|UsÕ˜(ÿ˜o©7öÏÄïú<%ÿ…U×ÿ+h¼¢¼²ÛÇÿn¼Y©xy<á{ack,⛟,Ç<—Oövwk&rÁ\“Ï|L²´žáüá2£HÁ|Us’ÉÇüKhШ®ûgâwý ÿªëÿ•µ x‹âb]Çn|á=ò#Hü%W8•þa¿íÖ€= Šàÿ¶~'Сá/ü*®¿ù[PÚø‹âeÜLéàÿ €ãù¼UsÕX©ÿ˜o¨4èTWžÝx‹âe¤Jïàÿ ]#ù|UsÕ˜(ÿ˜o©7öÏÄïú<%ÿ…U×ÿ+h¼¢¼²ÛÇÿn¼Y©xy<á{ack,⛟,Ç<—Oövwk&rÁ\“2×|S©x¦Ç\Ñ4í]ú+týRKÕšF¶ŠáÏoÕ qI;øA`ÖŠ( Š( áïú_ýûïå£Um/\Öõ=/O½û>l/- ¼X%Ô¯ãI¢YP6Ë\íuÎ úÕŸ‡¿ê5÷ï¿–W|â[áΔ¶³4.Ún¤®3ƒ¦Âi¥}È“ihcMâ{ø«ÉáÅ#þŸµþWÔð—Ýùoá¿üÔ?ù_Xןád’Yÿá Ѻ¶—)eÚ'Èáqÿ.Òt=×׈®þ4Cj'Ý.¸Lfìiró³íÇÉÿNÒcêž¼_)òìl·Ž'PI¹ðà®ou?òTüI¬ü>’ý.4Û˜ÓZ²µß¦\K<{–{IZHb âemà‚ È s?ñµõÏ5«ûI¯àŽ´[µÀb2ʱ€;IgÚ¹?€· wû. ›;ŸÆdœúý£O¦•¬Ë‹osÕ¨¢Šõ‰ +ŠÔ>7|:Òoîlo¼}á{;ÛiZí®5›häŠE$22—ʰ ‚ Нÿ ûá‡ýÿàö×ÿŽTó.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑ\ü/ï†ôQü#ÿƒÛ_þ9Gü/ï†ôQü#ÿƒÛ_þ9G2î{Ep_ð¿¾ÑGðþmøåð¿¾ÑGðþmøå˸íÁÂþøaÿEÂ?ø=µÿã”ÂþøaÿEÂ?ø=µÿã”s.àw´Wÿ ûá‡ýÿàö×ÿŽQÿ ûá‡ýÿàö×ÿŽQÌ»ÞÑUôýB×V°¶¾±¹†òÊæ%š ›y‘ËUÕ‡ ¤AjÅPü'!>?Ó"Âíòà—;Fì[LnëŒ9Êç…$ªGƒø»þF½kþ¿fÿÑ^íá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒjñ1ó¹ÏÁOælü ÿ‘óÇ_ö+ÚÿéÁ+ÓëÌ>Èùã¯ûíôà•éõøQëeßî°þº…QVz';¬ø×WðGˆ´{M1l$OÞÅ¥È×°Hílmíoî–TÛ"¬…O÷Ï=ö÷Š¿çÿGÿÁd¿ü‘^ñ:¹ñgÂØÜ¸Vñ$Ù1¹Cÿ G¸ Šï£Aj€’ 1cø“ÉükOi/é!Xwö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘E{Gå÷ °ox«þôüKÿÉox«þôüKÿÉQG´~_r ö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘E{Gå÷ °ox«þôüKÿÉox«þôüKÿÉQG´~_r ö÷Š¿çÿGÿÁd¿ü‘Gö÷Š¿çÿGÿÁd¿ü‘Y7:´Ðø¯NÓPÁseurìAÜ9-Õ@9Æ1+gŽÃ§}j•[™´­§’õ7©FT£ Ëi+¯K¸þi™³øÛÅPxŠÇJûNŽßiµ¸¹ó³åù|§…vãíçÎÎsÆÞùã/Y’÷ún·H÷sêðeŽ-ªEÅúyŠ‹`m•—©=óšÌñF­6ñ[ÀÖñª2_ÛêVÒ—!BC.Wž»¢QÎx'ê4¾#\Ãeᨮ.%H ‹RÓ¤’YX*¢‹Ø bOÎkŠx‰Je‡É/²Ÿê}&/Œ19kp¿¶³¶÷ýôáªÿ·moó:z+˜ø­/‡þx†ù®^ÍÒÊDŠx·Y]vG‚¼ƒ½—žÝxÆk¢¹¹†ÊÚ[‹‰R"C$’ÊÁU –$ðæ·ö‹Ã²Oï¿ùÂTXzx”´œ¥§X¨7ëñ­?Ì š^—ªêºwˆcT¹»†Î[{KÈ¥%|‰Úp0v°c'8?w‚9Ô®sá¿ü“¿ Ø*×ÿD­ttS—<#7Õ Aaq5h'u5÷;QZaEPEP ´+vÏY’ Ú•¥´öpO½†È¦hžEÛœ´‘‘·‚2s~Š(¢Š(¢Š(¢Š(„:¾»y¬ÇÝJîÚ 9çÞÇ|P´¯íÎyN@ÉÝÉ8¿EQEQEQEB Æß]¼Öcƒn¥wmœóïc¾(ZWvç <§ dîäœ r_?äqø§ÿc$?úgÓk¼¯=øaj–Þ/ø¦¤#þ8ï%gÿ˜FœˆŸSúz ô*(¢€ (¢€:?‡¿ê5÷ï¿–Xþ‘‡„´…ÿÈ;FÇ?õ †¶>ÿ¨Õÿß¾þZ5sš%ÒÁá}+yãû;FûCTŒç±Ká-·Ù|3vžGÙó©Þ6ß#ÊÏïßœyþ{OûÇ·k^o§ü8¸Ó,e‚ÇÆWZrÌe‘’ÊÚÚIö‚\(N¹¯îWŸK×>Ô§óöx÷T‹Ìó6íÿ&ï´c'ðùÑãþ¸'ᡃ³g¯[ýাŸg6ù¼Ô`‡Ê'÷¯Î<ˆ=§ýãÚ·ìêÛÿdø[ÏŒ|ÿËÅ…l|EЭü)ð×\Ó­îâ¸IžêíJA%„¶Ò#1Ÿ˜Œž=+#öwŒEû(Ä Œ_úø°£·©¼O]¢Š+Õø­ñûþK¿Äû5/ý*’¸:ï>?Éwøÿc&¥ÿ¥RW^4·f¡ET€QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®¡EUž‰çÿ¤h|YðµÒ'‡‰&Äq ÿ‰F£ê@ýk¾‹Æ¬PÆH£c+ìq‘ùW ñþG…Ÿö2Mÿ¦}J»Ê(¢Š(¢Š(¢Š(ªÑê6òê3Ø,™º‚(ç’=§åG.¨sÓ“þ^â©\êÓCâ½;LUCÍ•Õ˱phä·UçÄ­ž;áÎ)_åøÛó:a†«R~ÎÖvr×My¯óZ®æuíÌ/ñ7G·YPÏ‘{#ÄnUi­±@%Xßiô­jÓhºl7*;½í¥±FÙnc‰rÉøëÒ¼û@Ö?·>=Ksäù4 ›m»·gÊÔž-ÙÀë³8íœsÖ´h_ù#úÿý»ÿéDuåýcýž½xô»_(£îVP¿µò¼®·Ûöq•õ·=Gu£Ö×k}{‡ÿä°|4ÿ¸Ÿþ“­e|_Õ¦Ö¾ø–âuDt½{`# ±jRžIäª}óÓ¥jøßþKÃOû‰ÿé:×ñ?Xò>ëzW“»í7Z•Ï›»îùZÄk·ç>vsž6÷ÏX™òÛÒÒÿÒ —æ}NI†öøŒ‚Pä¥KîúÎ*Rü#‘Ú|~ÿIøi¨éëÄןêØýÑä«\¾~©nà´W É~(êÓC¢ëbª.|;ª\»wbUçÄ­ž;é|dÿLÒÞÏîyV©©ïë»Ëµ0lÇlý¯véž1ódp5‹/ëPÃ&Èï"Ö`vƒ½g ôù£Cǧ¡5xÊÞÊUeß’?Ÿù³Ÿ†ò߯ÒÀRMZX­¯V”ËHE¯5çuëÿ ÿäø[þÁV¿ú%k£®sá¿ü“¿ Ø*×ÿD­]ðέ6µ¦Íq:¢:^ÝÛ mŠæH”òO%Pïž+ס$©Â=Zÿ/ó?8ÍhÊX¼Ue²¨×͹5ÿ¤³ZŠ(®£Ã (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ó߆¼Þ/ø¦^ÞHü$pHTÿÌ#Nãå'ÐÄ{ãЫƒøqÿ#Å?û!ÿÓ>›@åQ@Q@Ãßõ¿û÷ßËF¯ø•Ä»]+A±ð¿µýRÑô¦–{}6à•,"“‚Ý$~ íŸÔjÿïß-«izæ·©éz}ïÙô ayiâÁ.¥xÏMʶX²çk®pOÖš¿A;u>MžÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄ×Ö³xžþ*òxqHÿ§íCÿ•õü%÷cþ[øoÿµþWÕó>ÂÐù*óÃ5k9-¯~xžHäVGN—#ݯgøSàÝ{Àß³Dwˆ´kíPo¤ÂÛP·xd(Óéø` Œ‚3Óƒé^’Þ8A&çÀ¹½ÔxÿÊuSñ&²ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]BŠ(«=Ïþ'FÓx³áj$¯M‰#‘ÿGÔúW}”T¹€vÆ[Üãò®âtëmâÏ…²8r«âI²#BçþA` 5ßFâXÕÀ 0R§ñ‘øÐ¨¢Š(¢Š+ÅÓh·º5ÊZÙÍ{"]¼»BùKiq!˺F§<}ßLÕ-/Å—w^<Õ4I£€ÚÅ¿ÈtR®¾\VŽÛÉ$6ãwÆíòÿ‹wÇÇmZltÝ1•Ì÷6ú¥Ê0hXôë…`NsœÊ¸ã±éßÏÄbhʤ_ÂÒùÝ~gØe95JÙ•%hÝU§)+kîºrwõ›òjë£; ù(šßý‚¬?ôuåßòQ4Oû_ÿèë:,ä¢kö °ÿÑוK^Õ¡Ó¾'øJÞEv{û-FÚ"€`06òå¹é¶&g’> mF•ßóíäœêãù`®ýƒ%†»û’¹Ãø þKe×ý‚µ/ý<Ï]í ÿ$_ÿ·ý(ޏ?ÿk?-EÏŸqåøo›ér~Ñ$ÓExüž¬¿kU<’pãvyñÛ÷þ k7ù­®~Ñæ§÷¼«;‰ãç¨ÄÆÜuÛƒH>EsåÕ|î¾m%ùŸ¢fT~¯Æx{¨:sºëÉÏO7¢v³ÑÛ[7ÿ’ÁðÓþâúNµãž%ñ4Þ0ð´Ö0éïôºmÍÿÙ‘Œ’»Ö xâÚìÀÿ‘H#>Çñ÷6ðâ|·6Ûü§þï›yaœt9Žiž›²0@#ÅþÿÉ|ð·ý‚­ôҵɘ9{wFúT’OÒQ‚¿ÉÄú…'•Ã3q¼°teR:½eJ®"n:iiFªWwi§§døs íµÅż©<øOX’9b`ÊêE© à‚9Íy¯‰'¸ñ_Äk¨­¶Û[øªæÖò3 ! ÙÖo¸nWÜ\$ äd×¥|1¶†öÚÞÞâ$ž |'£Ç$R¨eu"è ðAb¼·àu•߉­­3?›tÚ…Õä³\9%ü»&g$òKש<žõ¦)Ê»‡ý<ÖÞqi~79²O*§ˆ_ô ¹9ŸX׌äݖܪ>z¤ú´{Ï€>_ Öu;…w‚Ê÷V¹‘b±T»¸b$ àzŠÉð‡üoýÌ?úsн¨TåöVß•~.(ü¿„uÞ9ËHûY4üá Ò·åSÑ«Î~þïÂü°ÅöO.1¦ý>ÖGÀí—wsêÎÇ©5wÁ~>mÃÞÔZ7™5½Jîš]¨ÐĦåãÈPA!!Tëß9=ó¾ ÜÃeàûË‹‰R"K)$–V ¨£K³%‰<9¤ëB­Z5 ô³üRä\rìN_€Ìp˜ˆûÊPVßXÔ”¾jKdþóÒ¨¢ŠõO‚ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ó߆<>/ø¦âIÏü$p ÈÌ#NçåÔÀ{çЫÏ~]%Ï‹þ)”Yÿ„ŽûÈ™?æ§âÐþž¢€= Š( Š( áïú_ýûïå£Ußø–çDøs¥-¬Í ¶›¤)+Œàé°š¥ð÷ýF¯þý÷òÑ«ÃÒ0ð– ŸùhØçþ¡pÕ#9«£:óãœ,’K?ü$º#—VÒå,»Dù.?åÚN‡ºúñ߯ˆmDû¥× ƒÌÝ.^v}£8ù?éÚL}S׎oA“ÄÚ/ÃÛ–ðž‹e{ªnpÖ×ÄÚ'’nXHãC’û>§.@CÈ~ÌZωÞÞ×O½ð£_ê/u©kÉu?ñµõÏ5«ûI¯àŽ´[µÀb2ʱ€;IgÚ¹?€· wû. ›;ŸÆdœúý£O¥×­þÇðS_O³›|Þj °Cåû×çD?žÓþñí[öumÿ²|-ŒgÆG¾åâ—cX-Ï^¢Š+Õñ[ã÷ü—ˆÿö2j_úU%puÞ|~ÿ’ïñþÆMKÿJ¤®¼inÍBŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ö£àü‡ö-é¿úKwµÁ|ÿ’ðãþŽ7ÿIc®ö½˜ìŒ‹>ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]O5Ö¿h è? ðEȽ:ƒÜZÙKyJmmînRG·Ø°mò,NFŽ™#5{Æß-|ã°hZ¿ˆõíZÞ{¸m4Ÿ³.(¶îiy¢UwœàûgÍ|]û4êž!øê|]¥dšÞµ£ë÷Hìâé'Ó ž(âE µ‘üÕ%‹»O5GâGÀ_|ZÓô{u|câƒo½æ»¦ Áq¦˜¯¼ô’ľAÌ_+)Û˜å@Z³Ñ=câ?üŽ? ?ìd›ÿLú•w•æŸ4Û_\øeikªÝè—x’]·Ö+ M4D¢häN@ îCÁ8ÁÁ§†tKÍÂK{íQñ­)]jqÛ$ˆ¸`ðÄ»F åIËq€5袊(¢ŠñÿÉD»ÿ°¬?ú;B¬ßzÇöŸŠ­-¼Ÿ/û>×[¶Ý»>ft¸¥ÝŒqþ·çîç¾—ˆÿä¢]ÿØVý¡W9ñ_þG‹ïûé’Ö¾?&¡U.³þ”Ïèþ¥ ˜œ ¤µŽ³^OÙE~Mž£qÇyìLZÏá¸ç’=£ætºuCž¼ óöÎC¨ÜxƒÅ¿ïç“íI§É=ì›BáîlÙà`|ÆÞ»Óo8Êçkþn#þå_ý»®BÇÃ7Þ+´ðÕ•š§’t-!odvÛåÛIm¨C+/û{eÂðF⤌]µ%7.E¯¾ôôq—éø³æ0tpЧõŠAý^ ™¥ÿ/)Õ¤ï³zIY_V£½¬]øoÿ~ÿ°­¯þ£Ë]Çùàÿ·ïý6^Ö¶µ¤Ã§xŸA¸žÿ]k™C‘€ÃLš,/6ħœòOÐdüqÿ‘^û~ÿÓeíjéº8Z}ùñ°Ìsì* ÊTÞšö‰¯“[õ¦x¡7ñýý“åmþ/´êqù›½qöHñŒulç#uðëÂñ\x?ÄÉ'üñÓ¥›þ ‘IQúé’O÷p:×{â]FÞ÷Åúô0ɾK9|;ë´Žuzü²!ã×Ô‹ÂL:v…ðââ6v{û‹{™C‘€ÃG’,/6ħœòOÐsÕ§؈K{;ýÓ·üØÀcjå™5z1¼}¥7­ÒxxÔ'w$û´Ë¿ ?åÇþÅ]ÿn«‹ý–ô°ØÞܼÞÚmb¹‰Yãßt÷Hªr~÷Ùc$Œgjƒ ×ið«å–Aá½& PõŽDk´taÙ••”ƒÈ ƒÈ¬ïZ?öµ·çïÐ4ûÛvãÍžö]¸Éé¿ïŒñÒªŒ9ªa¤Ö‰Oô0Ìq^ÇžQŒ­)Ë óIJúôծͧm®y÷‹¼M}eŠÚÙ’kk-bÃl‹ÂO6­œvb|™à ò¹#© +°Åöú,iªÙOÔ‰kâI­ŠæXÍãMâ½ÖÚbFá`äU/ÚÂðø{ÀÌúU»Í=ýíÊÜá3,Ïö¹d;@$©µ@ç©8pÞÿ’wiÿ`©¿ôN»^TçWŠ•þÊùY§þGÞáð¸ ç!¥˜Æ6J´Õ´\ÊP”uõ|ÏÎï[êzß…ô˜|1†<9 <ƒFñÕ·˜äÊöwWœ€2|¹ÐÌ`œ­ýáŠ-™'ðݾ¢¥zßMX?ínµ‘ÓyÉ hëÇög?wÚ&_C#Ç»nØ_O¶µi3Žv½Ü?/SŸ@HÁ¹Õ¡Ñ~k«º?‚4›`#Ò‹˜”òGœíž½+Ñ”¡M¸l£Ï÷(Ù~GÇÑ¥ˆÅÆ–¹¥]áÝûÎuœåøÏñò=ÖŠ­£o.£=‚É›¨"Žy#Ú~Trê‡=91¿åî*—†uiµ­6k‰ÕÒöîØÁlW2D§’y*€Ÿ|ôé_KÏ%çøˆ¼5XÓud¬“Š×ûɵòi_îîkQEg0QEQEQEQEQEQEQEQEWðãþGŠö2Cÿ¦}6ºÝwM¸Õô©í-u[½âM»o¬Vš,0'hš9;ðN0pGüÑ/4oüRKÍQטx‚Þ?3PŽÙ°Ò¬X¿îaŒn!ÕÄI€»8©ÑEQEÑü=ÿQ«ÿ¿}ü´jç4K¥ƒÂúVóÇövŒö †º?‡¿ê5÷ï¿–^'ñ*‰vºVƒcákú¤-£éM,öúmÀ *XE!&0 ºHüA¢D•ÑÔéÿ.4Ë`±ñ•Öœ³dd²¶¶…’} — ®gCëû•çÒtøskÌV^5¿°ŠgžP–ñ["«Ê×,[;®ç¹…O~<{ÚÈ)ðçÄëë>_þ&¡þÍý¡øÿ‹wâ~ä/ÿZüÈäg®üEЭü)ð×\Ó­îâ¸IžêíJA%„¶Ò#1Ÿ˜Œž=+#öwŒEû(Ä Œ_úø°¯5¼ðßÇZÎKk߆Þ'’9‘ÁÓ¥ÆÇ÷kÙþø7^ð7ìÑâ-ûCÔÅi0¶Ô-Þ 4ú~# ŒôàúRì\U@¢Š+Õ$üVøýÿ%ßâ?ýŒš—þ•I\wŸ¿ä»üGÿ±“RÿÒ©+ƒ¯[³P¢Š*@(¢Š(¢Š(¢Š(¢Š–<~”R«9”ô°QHŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Ú€?òB>Ø·¦ÿé,uÞ×ðþHGÃûôßý%Ž»Úöc²2,øKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£½ÛÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕãbþ3çsŸ‚ŸÌÙøÿ#玿ìWµÿÓ‚W§×˜| ÿ‘óÇ_ö+ÚÿéÁ+Óê!ð£ÖË¿Ýaýu (¢¬ôO?øq¯‹>Ë4‰ KâI²ò0P?âQ¨Ž¦»èäYcWFŒ+)È ô × ñþG…Ÿö2Mÿ¦}J»Ê(¢«G¨Û˨Ï`²f꣞HöŸ•º¡ÏNLoù{ŠM¥¹q„¤›ŠºZ¿%{kóiz²ÍbÚj7øÏT°i3kŸiÕ¡Ð|W­êw ï•ê\ȱXªI¡±p=EbüH‰¤ñŸu æqg£ P€.Ô7š[ÀXñ¸–’;d8$ŒdïŠúu¾©¦xš˜üØ×Zšp»ˆÃÇ¡ñèʧßñRkZ*ê¾+ø“í³É¦Þê^µrw*È<ÈDˆc®¹ÁÈÜ=E|¶"©:‰mÍšG¯•Ò?|ÉñT0˜\%I'ÍìT[Óà\$-þ×,ª}ýUÎŒ4ÚÄ]O_‘{h/WF—>r-Äz’cRä©eÇšì2IO…òãÿb®‹ÿ·U‹áÝFãWðeÅýÜžmÕÖµ¡O4›BîvLf8$ž•µð£þ\ìUÑöê½2RÄA­Ÿ3ûî¿D|VeFTr|M:–榩SÓf¢¡/Îrí¥´:?ÿÈsÁÿö“ÿHn¨ñOü‡<ÿaY?ô†êÿÈsÁÿö“ÿHn¨ñOü‡<ÿaY?ô†ê½}¿ñGÿm>.üÃÿך¿û˜ñ‡¿óÿ¹CÿhW¢èò+ü&ÿ¶úl¸¯øÿ ?ÿØWBÿÒá^ãám:â÷ ¦†=ñÙÅo<í¸ ˆtùcž¿4ˆ8õô¼ µº”éÉ-Õÿò¥Ï×xÚ”pX¼UKHÉFû]ýJ1_{Ùwv+|3ÿ‘£Ä¿ð?ý9êt|(ÿ—ût_ýº£áŸü%ÿÿéÏS®IÓ~Áã=Oɵû=‚éVAåǶ!²K¬¢àcå œ€Q^® ÂŒûs~7ÿ#೬DaˆÌðïy*MÛ¼šä߃,ëúuÅî«á¹¡|vzƒÏ;nb[ˆÁç¯Í"=}¯šô¿øöº°>×K²´„p¾uÎxGeß4Ä“ÀÝ#1<“_WWËÞÒfÔu(®#dT°½ð•Ì¡ÉÉSl"Âñ×tªyÇýkO÷”œz¶ÿò_øÒp*øLtjÙ(BœW«­§Îóiy;w7þ,ê7F£â«ûI<««YLðÉ´6×S¢2œƒ‚Zêü_áí?ÎÔ´/³ÿī쾲û>öÿSý¡*mÝßwŒç>õÅükÿ™ÓþÚî½Åÿò4j_÷/éÎZÁ%*õÓþ®ª_ï=G9Rʲ©Óvz;­ã<'/Ýwn×vÝ™ßÑ2éZ.b¯ß¶y[…«ÈçñÇ@k|¹šxüh’Jò$>'¿Ž%v$F»•¶¨ì73ìOzæ?fïÞiFvù¦—Jµó$<³ìº¾2{áz*(èXøi¯ÿeëZÆž™©øÓS‰£só˜ÒÜÈY{2Æ ä Þ¤WF«öxz“7þLôüÑäq/œa0ðKÙ**ÉY~ê I¤¶ºŒŸÌö (¢¾üP(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ï~^AwâÿŠf ã˜ÂGf7 ÇöFœ3Ǹ#ð5èUÁü8ÿ‘ÇâŸýŒÿéŸM òŠ( Š( áïú_ýûïå£Um/\Öõ=/O½û>l/- ¼X%Ô¯ãI¢YP6Ë\íuÎ úÕŸ‡¿ê5÷ï¿–Rø_ÆSxOáUÌ2´^V‘¥;ítC´iq1ùœ…:±ÔM+‘&Òº3¦ñ=ü Uäðâ‘ÿOÚ‡ÿ+ê?øKîÇü·ðßþjü¯«—ž+ÖåiXÛjr• ‚¯oócÌÆ3 ë±qœ®Lã±Ö:åö£nÒŨJË,'æ²È쇕$uSÇQЀA¹QŸ´fcxâu›Ÿ:æ÷Qãÿ)ÕOÄšÈñÃé/ÒãM¹5«+]úeijǹg´å¤†"&PFÞ œ‚_ÅÍcSÑü©ÜÇ)"Þ@ü½ø®à-Ã]þË‚fÎçñ™'>¿hÓê’J̸ÉÈõj(¢½aŠß¿ä»üGÿ±“RÿÒ©+ƒ®óã÷ü—ˆÿö2j_úU%puãKvjQEHQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@µä„|8ÿ±oMÿÒXë½® àü‡ö-é¿úKwµìÇddYð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5{·„¿ä¢éõïþôªðŸÈ×­×ìßú1«ÆÅügÎç??™³ð+þGÏدkÿ§¯O¯0øÿ#玿ìWµÿÓ‚W§ÔCáG­—ºÃúêQEYèžñ9¥_|-0¢I/ü$“adr ÿÄ£QîþUßFXÆ¥ÀWÀÜäß?•p¿ÿäqøYÿc$ßúgÔ«¼ ¼×þ7µ><Ö¥2[ÜÍo´)nC,zåªø%žrz¹<qéUòðñ5Œšµï‹agŸIµy—(¸’A¹otYU±ÁŽê03ƒÀ€O˜bP’{]ÿ^—?Gáž9Å,M EûÞÎ7[ݶһMjâ½l}C^ âÍ~ïÃš×ÆK9öj/™IÍ»yŒ›H;’1$™6<^¯ñRþÈðˆ®Åר¤OŸÊœIå•¡ µ²0ÅŠŽrF9¯:ýãäûùþÑÕcò¶ÿÙ´—ó7zgíqãèÙÆc1““§M;;¥~ÜÑœSûÎŽ ¢©SÅã*Gž>ÎO•ý¯aWZQo³Š×²¸xÛ÷žžvù¦—U×|É,û-µÓ'¾¢¢Ž€WE/ïü+uxÿ5ÍÏŠ¢ó_ûÞV©ñÐb8c^:íÉÉ$Ÿ>Э¦½øá;{xžyå}R8â‰K3±´Ô@P$“Æ+½¶¹†÷áôWò¤ðKâq$rÄÁ•ÔëY à‚9Íqáåí¤úÁ?Ÿ*ÿ?Äú\Ö‡Õ%J„]ù1R…ö÷UYÙy'Èš[{«±ÅÁ«M üÕõ;uGžÊãF¹e©d¶ÓX¢»…»ºÍÄÖz›e:ÿrhe¼ŠUÏ|:0Èàã ‘ƒ\:i3k_¼Uo":[Ø\“! m‹O±•‡òUøéÖ»„éwþ2»~$ƒZºÓ”/CO,àŸö·]H 逼dV›ë4ûrþ³¿è^쿱1¶øý®½íɇ·ãÍøŠä9àÿû Éÿ¤7UƒyâeÕ¼i¤³ ŸI×UB"°>TšTî¬ÄðI4qÙFGs½âŸùx?þ²é Õy×…¿äé?Šäo[þÝÿÒbã~ðEÕ‡ˆ|]ka Ícm{áûhd–DÜËj y éÈŒ«tÎOì•Îx[þCž0ÿ°¬úCkF&ŒjÊŸ7FÿÉ %Ìkåôq~ÊÖpƒiíxÖ¥%Ûª·£~§‹ükÿ™ÓþÚî½Åÿò4j_÷/éÎZç~"þëÇþ+‰>HßÀד²/¤/°¹Þ+jO\"Ž€WEâ_ô?ŒßÏöú­¿Ãök{ß3w¦~×1žœ`gÆQµj²ï$½/̯÷Èý2¥~l»E-iÒEýîEB£—»I뮚ÛMt¼£ÿÂ=â)ô¯;íaÐ4»o7nÝûíwc'Æq“^Y¤ÛLÿü9p±9‚7Õ#yBªÍw©•RzB±¾Óé^Éÿ_?¿ý§¥}<¿³Múîûg¶<¾û¸ãìt˜SÀZ·¹Íöªú$·Y#kH×ë;¸à´—2€º+QO’+ì6þ椗ÏO¼ñòÌÉÅâ+TÕâ¡Nš~u)Δ¥oî¾wm.ãe£Lí<­6·¦Þ¼·)s=¶¥{já6æ0—2*#Јü¾¼Aç9­úñø³þo ÚÊ#ónõkKµ.˸4“ÙY¼Ò9È%˜y­»’]9ɯh¯G ]V¦“Ýoý|‹â®Yv2rJÔæß/N‰».ÉÊËÐ(¢Šî>X(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ï~4íâÿŠ~|qÆá#ƒˆä/ÏöFꣶ?3éÏ¡WðãþGŠö2Cÿ¦}6€;Ê(¢€ (¢€:?‡¿ê5÷ï¿–\娞o‡–°Û‰gÑô•cb·öTX˜9ÿm?Þ^££ø{þ£Wÿ~ûùhÕÎè7kká­!œä ?FÀö „ÕDÎ{×W×¼kã½Â^º°Ð¤Ôt›Ýmu½VÌjVòCm=´>\qCu %ÅÚJ$2aU@*K1‹ÏµßŽ7? ®šÇÄ:߉îaÖâÓ¯ôý+â#ÜjV†kå…ÏÙ¦³V&7s£:mXß„ Us|aðƒÅžñ=®³ð—X±ÒšïK¼Ñõ1ªê÷O ´Ïdê,æH¥1?úÂäUoÝ”qÇÆÚü ø‘ck µ¶à{{xPG1x†åQ P,0 ùl¦qGÍ„§í)»ixÆÖßW®¿‡àiMQp´ŸÌô?Š¿üâÏj:n‰ãoëz”ÖòùVzn±o<Ï„,Ä"9f«:c=«?öumÿ²|-ŒgÆG¾åâ°µ¿…Káßê~ ’ÆïľD†¬ä3[ØŒ¬cvT-# ¹E!IE2o~Îñˆ¿e”ñ‘ëÿ_ôxZ•ªÒŒñä“é{ÛçeøiæÈJ*ê.èõÚ(¢½òOÅoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸:ñ¥»5 (¢¤Š( Š( Š( Š( Š( Š( QEÀ(¢Š(¢Š@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQE~Ô|ÿ’ðãþŽ7ÿIc®ö¸/€?òB>Ø·¦ÿé,uÞ׳‘‘gÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕîÞÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯñŸ;œüþfÏÀ¯ù¼ÃàWüž:ÿ±^×ÿN ^ŸQ…¶]þëë¨QEg¢yÿÄëx®¼Yð¶)£I¢oM”‘CÿDô5ßGÅ¢(DPUF ¸‰Ò4>,øZéÎÃÄ“b8ÈÿÄ£Qõ ~µßFÅãV(c$Q±•ö8Èü¨ñ±ý™ñKÁ–ÞO™ý¡k¨ÛnÝ/ wcÿªÆ8ûÙíƒáÚ†qwáKG1ïÓO𠓏 ¸Ñ,®a¿ë-CqýÌ{âÛÛø§Sñ4VÓ½®ä­ÂL¦-΃T·P§r´¯†]ØÝÎ6°>àï K¢À²%五S4Éòi?eÜÊOÈ£€[†õÇËÖƒÆÉ¨»®oÃEóMÅßæÝ²ÜTx^„*ÔŠST¬®íÍQ:•_Ë8F­>_>Y¤ïb/ÚþHþ¿ÿnÿúQs©ûω~¾i¥Õ|EæHygØÏd÷Â" ôTQÐ ±à›ßøI´¯è÷AiÖúG„……¤~U­®¡1î-µòeQ“’pëQü7Ñll¼ºlvÈlm5+Ô‚>p‚;é|¿½“•*¤Î@=k¦†¨RŠÿŸm?[A~‡‹™ç1–#U¦ÒÅÂqZ|*X™4üï?>ºèŽÂ?¿ø âkÄù­®t¦òŸûÞV› qÔbHd^zíÈÈ ž‹àÏüÏ_ö5_ì•gU𽿂þ jú%³oŽÏEºC&óÄìï‚N71fÆxΣø=m4øÑä‰ãI¼O$Lê@‘w*îSÜnVÔŽÕ4iÊ•z0–ê:úëÄ×1ÆÑÇeYŽ"ƒ÷%VоÅ:j7óåI¿;葽ã?ôoì-Gï}‹Uƒ÷}7ùû­zöÛöývcŒäq~Ñ÷|_ºñ#M™µ[]JÚHáSì—ÀŒ‰2?¼ô /Gñ†öïMð ÝÞŸÚ¯í·ƒa2E»„ªí^NH“šÉøypºÕö«YŸM™5×K‘ÄšŒmr8,¡ˆå>†µ¯Ë,R§ÚÒùó(ßîÐóòÅV–CÜOÿIÖº;ù(šßý‚¬?ôuåR×´˜u‰þ¸‘^ÂËQ¹ˆ!,M¼Xn:m•ä¡ójSæ§u¿:ü*\ûŒ&3Ùc}O…aê[Öx>_Ño¿ä¢hŸö ¿ÿÑÖuÇê´:À_jw s"Äb©5» gÔWa}ÿ%Dÿ°Uÿþ޳¬ï èÿðüÒô¯;ìÿnÐ"¶óvîÙ¾Ü.ìdgÎ2(©Nu# Ú•¾è‚­K ‡Á×Ä|'/ER»}O'èy¬:LÚ¡i¦^2H4›‹I§e$Å@š"¼ù `,foœ„gÎ5é_l­5ýCÃzL³ì‘õfò\  Í•ß—*õÚÁ•lpɑȮsÇÚ>íwÇ:‚MåÇ„$V·UâI&ó”œýí¶±©8ÉFp U›Yî5ow‰5¶Í:ÃO ž`>eÌJŒ_‘¶=E× îÏ$ ¼0ФåM­%$¾Wä}^"´±Ô©c#;T¥F¤ßOyž×ßãOKþÝÇ„µiµï hÚ¢O{e Ì‹!CMžÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄ×Ö³xžþ*òxqHÿ§íCÿ•õü%÷cþ[øoÿµþWÕó>ÂÐù*óÃ5k9-¯~xžHäVGN—#ݯgøSàÝ{Àß³Dwˆ´kíPo¤ÂÛP·xd(Óéø` Œ‚3Óƒé^’Þ8A&çÀ¹½ÔxÿÊuSñ&²w9ø)üÍŸ_ò>xëþÅ{_ý8%z}y‡À¯ù¢ =l»ýÖ×SÅüIûKØøwã x%´wšÚ=GNÑîõO´…0Þ_E,¶È±m;Ô¬?3n,84|hý¥ì~ø¦"mõ(àÓ£Ö5;r"6–oy¢º.Öó[Ì—;r¼)9íG‰?f‹|`_6±$6Òj:v±w¦}œ1šòÆ)b¶u—pØfù—iÉQÈæ°|]û(ÞüCeÇŠ¼s&±«6œ4}nøi1Àu+5¿KØÑ,­¦à+“ŒœÕž‰è¿.a²ñGˉR"ñ Ä’K+TQ£êD±'€ç5ZÆÏV}¾.ΫӞsÿ·§ËÍåöWõkyGÁÿ‡ŸØº¤Úì×_i¹ŠÖMÌQ³Íû=Ô‘odÁ û¸-”`ÿ g$î7~[CiÃÄ‚$…†'¬jf±flå‰$÷$šô :ßK¡¶Ê¥–r»‰ËÈí#ž}Y˜ûgŽ*ÍqÒÁF”!éoÅÝ7ùEâZøüF"µ[ÉTzl­ вÓESe¢µ–LÛMi£\$ñ<.u-B@²)RU¯&elÅH ÷ߢŠï„y  º+Š®ñUêWjÎM¿½ÜÉñn“6½áMgL·dIïl¦¶¥$(g”@'>†©x þ@w_öÔ¿ôºzè굆o¥ÀÐÛGåFÒË9]Äåäv‘Ï>¬Ì}³Ç›§ûÕSÊßü9Ö±¿ðŸ,þu5ÿ€´ÿöÛ|ÊÚþý¹c·älº¶¹Ý·v|©Ò]¸Èë³íœóÒ«ø;Âöþ Ð"Ò-6°K3¸?"<¯"§$“´8\“Î3Þ¶¨«öpöžÖÞõ­#Ä,+À©þéËŸ—§2M'ßDÚù°¢Š+CˆÅÐ4ë‹-WÄ“MÈï5žÜô¶ñ“ÇOš7úz[TQQ¨+/?ÅÜè¯^X‰©Ët¢¾QŠŠü¾aEUœåhôëxµïÖ<]OpI&ãó"déÁ‘ÿ?aDšu¼ºŒín ŠH#“qùQÊ3ŒtäÆŸ—¹«4Tò«Zƾڧ773½­{ôµ­ém-ÛM,øÁ«j:^½ ]õ‰¬¯ZÑ142ÚÜ´lî!ÒM£ï€I‡Ãù'~ÿ°U¯þ‰ZÚŸM´º¼¶»šÖ n­wy¼ažà ±ˆÊäpqÖ¤¶¶†ÊÚ+{x’"AqD¡U pb¸á‡”q¬å£éÛEþOð>›Q­”aòØR´©»¹3r›û’”l»ó>§1 nx‹Äö—)[”â±Ô]j =yRêß+“·’I'ç(®§£QT´MZ{E°ÔíÕÒ ÛxîcY@ Ô0Fp}MV¼ñ 6>&Òôy6#ê÷Dï RZ#È«üD¬ŒÜm]H¨©_GoÇc†8ZÒ«* >ôy›]¹Srû’oäkQE¡ÈQEQEQEU-V‡^Ñl5;ut‚öÞ;˜ÖPu ‘œSWi&¤“[T§:S•9«4ìך àþÈãñOþÆHôϦ×A4V><Ð.­äkû{G¸–ÙÚÒò[9ÃC;!+,.® ´g£ ©Áà‘\GÁ ÙøgÅ¢³›Q™Gˆ-âΡ©ÜÞ¶Ñ¥X¸;¦‘ÎìÊÀ¶r@E$ª Q5$šØ*S)ʜ՚vkͧES3 (¢€:?‡¿ê5÷ï¿–W|â[áΔ¶³4.Ún¤®3ƒ¦Âj—Ãßõ¿û÷ßËF¬HÃÂZB‚ä£cŸú…ÃTŒæ®|Kâ]R {‡òã"9ßrêꌟ• RÝ/ ù»ÎÅÓµnéf[›ƒo4,¨Â6fBLhÇ Ñ®à 0ÈÈ;{ʾ#ñKÅ’.àï CªZé:F¡¬Ã¡kWv¢›ka¨Àb%Ä&1BðTG†‘v]ñçÃÿ|ë´‹ox¢÷Ä:-æ—¦. Öl¦” Ýâä³Cy2>æÒÀ„2)¦b¢v_5SHðn§qô¤­¼žœü§Ú¸€· wû. ›;ŸÆdœúý£O®×ã¹ÇíS©ýÄœ¿v¸/ÙÕ·þÉð¶1Ÿùÿ—‹ ®Æ”ö=zŠ(¯Tgâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QREb€ (¥ÚiÚà'jÍ;o©Ò˜›×5j-ô¡sžqJŸQRGo»©§”e;qòÖ±¤ív…r 7CZw•–éùUdqVRݰ>]߆k®g- r(˜6 ääö§y¦;Ö‡ÙÈ$ƒß"œ4öbýßâÈ5Ö°R{"yŒÃm“ÁÀõ¦ˆN0y­ceœ_QR}ƒh‚Ç=Ö­eÒo`ç2~Íòq})¹#œƒ[&ÂEc•íÓßìéðœã•5«Ëeü¬\æ@µƒMû>3´[cM í?)ô4Ãc!-Ž>‚¦Yt—ÙsBAé×µ7Êã;Mm¶žÅ>SϦ*³@b`x¬'€”>% Ôîf#Ž‚”'˜zô­²—Û\ÒKm±Aís¼$–½ æ3J}©µz[lGœâ«‹vôãÞ¹'BQv±IÑR4Xã4Â…z×;ƒ[ŒJ(ïE@Q@Q@Q@Q@Q@Q@9¤w3 '¥6Šwk@ (¢Q@Q@µä„|8ÿ±oMÿÒXë½® àü‡ö-é¿úKwµìÇddYð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5{·„¿ä¢éõïþôªðŸÈ×­×ìßú1«ÆÅügÎç??™³ð+þGÏدkÿ§¯O¯0øÿ#玿ìWµÿÓ‚W§ÔCáG­—ºÃúêQEYèžñ:u¶ñgÂÙ9Uñ$Ù¡sÿ G°šï£q,jà)SøƒÈük…øÿ#ÂÏû&ÿÓ>¥]åQEQEQEQEQEQEQEQEQEQEQEQEsxJe¹ûÜ'ü#Ð\Gwkf€†FB¬‘g´I"y€üJƒjGµüú]9üCñºêík¥j±Op±3mKa‘—ÛŒ*Kcç!™×¦>oh¬›m&h|W¨êlÈ`¹²µ¶Eî — ÄŒc•qÏcÓ¿[ œ‘[)&ýv^JöÓüϲË3ê¸E‰«7ïÊ”¡µ¥9AJzo7kÉë{;Þ*Ô¼ÿ ;¯û ê_ú]=sž.çǶºƒ|óhßÙ¿dS÷Wí·3[\grôh×±`݂ѠÖ4öæk=VëÌa÷OœÿiL}áÿh7Q‚yÏþÿþ]cîÿcý‹÷?óÛìx¿ûßÿÎòú»ws£:Ÿîð]¿4Ÿä×ÞŽì¹Æ&Ki½xT©þS§6ŸxÉ®§£QYº¦±ý™}£Ûy>gö…Ó[nÝ/K.ìcŸõXÇ{=°OköžÓP¿*ÕeŠ'y’,a˜’P\{kÑu"”›{o÷\ø¨ákNT¡ÝÔøRÝݸþi£JЉna{—·YPÏ,a¹U‹b:€J°¾ÓéRÖ›œ­8èÐVMέ4>+Ó´ÅT0\Ù]\»wŽKuPqŒJÙã°éßZ¸ûmZkÇ:=Ä è‰e«[ îŠîÚ&<Ád${c§J´ùRIëuù¤ÿ3ÔËðþÚS”£x¨ÏïösqÿÒn½ŠÅÐ5‹ÝWÄÍ&øìõ‚ÚÄ6¶òÇ_šG<úúRj>&±Ó´Ýnõ™æM®ã‰~`V˜¨Î;O\sŒõÅ{Hòó7e¯áò1x*þÕQ„y¤Ô^ŸßQkÿJKÕØ¥ðßþIß…¿ìkÿ¢V³¦×îì>+=ß~™y§Ûı䒗$ÝÈ à)Ž ¤ˆ»†ÿòNü-ÿ`«_ýµÎx³÷~/½~Y¢þÀòä2oÔ'ð{eÐú«°èMpJN4)It³û¢Ùõt)S¯šcéTWææŠòr«§ònæ×à FßW𿴓͵ºÔ/ç†M¥w#^LÊppFAk'á…Ò\ø¿â™EøHà?¼‰“þapþ =éê*?ÙëþHþÿoúQ%Zøqÿ#Å?û!ÿÓ>›]99á©IõŠü‰(G ãhChÕ¨•÷²›GyEWaó¡EPGð÷ýF¯þý÷òÑ«œÑ.– é[ÏÙÚ0Ø*èþÿ¨Õÿß¾þZ5xŸÄ¨>%ÚéZ …ü ¯ê¶¥4³Ûé·$©al„˜À$~é#ñ ‰WG¢]ü>ðv£6­=ΧLÚ½»Z߬РÜFçs‡OºKIÆI'\.«û9øZÒÆk Þ\i~!Dt·¼Õu+ZFR²ÛO Ô²,–Ó+–.¹å&žÇö„r |9ñ:úçO—ÿ‰¨³h~?âÝøŸƒŸùËÿÄÕÙ>¤rµÔë/ük­êž ñW†õ­SÒßH²Œ¥Æ¢^e/'œ¯o Ógí‘Æ"GK‚|“Ɠ–9%—köwŒEû(Ä Œ_úø°¯5¼ðßÇZÎKk߆Þ'’9‘ÁÓ¥ÆÇ÷kÙþø7^ð7ìÑâ-ûCÔÅi0¶Ô-Þ 4ú~# ŒôàúQÙ•@¢Š+Ö$üVøýÿ%ßâ?ýŒš—þ•I\wŸ¿ä»üGÿ±“RÿÒ©+ƒ¯[³P¢Š]¦–à%9UŸÍ*ÄÍÛ$P1lV°§&Ö‚¸ÅŒ€}jUš¬ #¸œw«Yd…ŽÙã5éRÂM»X‡"§Ù0q»5s_ ÉÞW€ñVað£\õJW8_ñÅ}OcðöéK¬O…ãlc$gê+~×ö{}«ºÊYXœ©8÷8v¯Å| ‚vž)IõJßæxÕ8¯n{³ãßøCDk³ËÉöÇëRîQò•‰¾Ù³ÉÁÝÉ TŸÔŠl?³„ŽYŒ ªOôõã/x)óT²ùKŒ°Nú³â'ð‹g§+Ïó¤“Áò/@K8޾ßٹѓ6Îå¸Ü 6Óô*jµ×ìÛ$lÚI*v‰ž}z~´áâ/Tvöûí·ùš./Á·»ûˆÂr‘œð9 Š«?…Ÿw1«“Ðq_k^~Γ@2¶S;sÁÓ¬+Ùúâ ÛÈ…y9ˆ©üëÒ¥ÄÜ _»Å¥~öÿ6uÊðûv>?›Âì\†·=ˆÿëÕi¼8áq±‚Ž…†?­}EðFý$*mÙ;€§pü±ŸÖ¹Wá=ä@žYàü˜üø¯ ¥áìwû®* ¿5ÿ {s¼-_†¢ûÏœ%ðû?» zžC&ŽSåÚÇÜÿžkÛïü{nX}šM¸È>[}ÁÅs÷ž ƒA0Ïsð®zܹ¨µ+ö±ëà í#ÉJ X‘‚?‚ãNo=«Ñï¼8Ñ ˜Øv$ÃŽk.•çcn낯’ÅðµJW!×霺q¿åP½»/y5Ø\hò–Á,GÓúÕ ´— N>µòŒ’tÛå‹:TÎccsÁâŒV¼–/8BGLâ¨Knr0?ùÊØIÒÝ)\¯E<Âí0ðk‰Å­Ê (¢¤Š( Š( Š( Š( Š( Š( Š( Ú€?òB>Ø·¦ÿé,uÞ×ðþHGÃûôßý%Ž»Úöc²2,øKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£½ÛÂ_òQt¿ú÷‹ÿNúUxO‹¿äkÖ¿ëöoýÕãbþ3çsŸ‚ŸÌÙøÿ#玿ìWµÿÓ‚W§×˜| ÿ‘óÇ_ö+ÚÿéÁ+Óê!ð£ÖË¿Ýaýu (¢¬ôO?øœ²·‹>ˆ]#—þI°Ò!`?âQ¨ö:ï£ #Pä3àn*0 ï“θ‰×Zø³ál³Hľ$›/#þ%ˆêk¾ŽE–5t`èÀ2²œ‚B :Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( .-cþè~"j¾OÚ>Ãt×>Ví»öiöÍ·88Î1œŸÔmõï‡u»<ý3SŠæ{Iö•ólc…ŽÓ‚1$R/ }Üô ›¿ÐõItø¾[oZ­­âŽ6æêÚØÈ„†;¶›?ê¡ì¸6u Ûø3àçˆô‹Fͬ~¢ð®ÈæÈ©É$í$óŒ÷¯|îS‡ÙŠ“ù»Ûåfïçcõ /ÕiÑÂâUý­iÒ‚ìéÁANý¤ªB*=âåtô¶Oˆ5haøõ iŒ®g¹·†å´,pêJÀœç9•qÇcÓ¿YñÚß EoqOº–‘J¡•ÔÞÀ x Ž1\7Œ´ëˆþ8iÚôqîLÓì`ÜXmßszöø#©ýÜ“ŽŒ«ž8=ÏŠîaÕ#Ðì`•$KÍ^(Ìñ°a[3Ü2àu;­Lddm,O;p]6ÜkÓ—Víç}?;¢q°„kå8º/HS‡;þWê?KSq’[½lŽàv¥wªx‡ÄRÞ]Ow Ò´L<ò#u¡väžìÌÇÔ±=I¯[[˜^åíÖT3Æ‹#ÄnUbÁXŽ ¬ï´úWÍ6±ÿÏ…µ½m¡ûD2Zø~æÐÂÜýŒÚ­Â†ãkȈO÷‹J°Ç­4?®´ÅT0\øv—bàÑÜʪÎ1‰[k[´i®e^Dkä·þÒÄUÊ› ¸pÍŸj7iÞ°Y1k?†ÌòG´|΂ÑPç¯Güý…V×ÿäWø³ÿmÿôÙoW))aâ—Eÿ¶7úœØz¥œVœ¶œ“^ŸYŒuùÅü‰~ÛMeðŸE·¸‰àž'¹ŽH¥R¬Œ.eH<‚¤ø`³¯‹þ)ùòG!ÿ„ŽcŒ§?Ùw«Øü¯þÿ×ý…u/ý.ž¹ï…š¦£âߊiu ÒÂIÍ ÇNž§‘þÒ°ú©«·  =8vŠü‘òùýib³|f%«sU›}“r“±è”QEuŸ>QEtÔjÿïß-«izæ·©éz}ïÙô ayiâÁ.¥xÏMʶX²çk®pOÖ¬ü=ÿQ«ÿ¿}ü´j»àÜèŸt¥µ™¡vÓt…%qœ6M+îD›KCoßÀÅ^O)ôý¨ò¾£ÿ„¾ìË ÿàv¡ÿÊú¸þ5¸¾doµjy. ØÌ¸Ýåã9õ«œôÃç[í[-vûQ‡Ì†öíÆEÅ»ByUaè=gŽ òÊgíc5¼q:‚Mχs{¨ñÿ”ê§âMdxáô—éq¦ÜÆšÕ•®ý2âYãܳÚHrÒC(#oNA+âæ³ªi Ôî#¾”•·“ÓŸ”ûWðá®ÿeÁ3gsøÌ“Ÿ_´iõI%f\däzµQ^°Åoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸UPs¸â¼v¯#Q£ç¥I8À¹ïOE+È<ÕÁ;‰“ÂI8aб í<äÓ=ê%Ç\z°’Чôæ½j)hfË‘#H¿*8«¶HP/”tÚ@ªñB2NðzäZضuÀi e˜8ý+ì04c9jÌ$ËV ‘•BG¨­û+%)L}â³mö!Þ zVö™åÈr[ÓoÒ¿OÊpÔ¹”l®qTlÓÓ´èü옸Àä¡Ôiº˜«˜þG r;ýk.ÃÊ}B·sÈãð®Ï@’5UewÇ.9>Ü×ê|±Áa]JqMž6&¬¡£gÃ> L RÝ\žFQ±úõ¯Xðç‚b–0Ãk’tLnϸ¬¯ -¢0iƒ+¾¼qô¯lð³Ø)U_ÞѶ€ßxƹ†ISR²íuùiþgäæm^-¥q|9ðÒÎÚZOÌWewº?ÃÝ= ì²MØÎã?LÖŽ‹ö|·¨äåGëŠî´F·Œªû„Ç¥güWšb%)Ô«'7cnÉ)f•ñUo~æ=ã1ä*î¦Ò¯Ÿi¶‘»–Þœ¶ò2?] ûyV¤Åæ7Ü#»W’øº}mžK›vº˜1Ùˆ™×° ·_Ò¿5£ŒÅc¦Ó©ÊNd>å5ùyâ¿Ïc³ººðÆœ®f»€0ÆJ‚8üªƒø³Âçt…w+°n?5àþ"¿¿¼+ŽâÁݼO)#ðÎkÔ'Õ–R¤ÈcÎçuîOÌH…}6%•UyוýOÚ°>dsŠç‚¿¢>ªøÀj¶gÇ9e?Z’øNä²ùñ*‚ÅÔ öƒŽkãÁªêɲ?5ÁÇÌY¸=;æ­éºæ¢ƒdÏåòX””çéƒÎ»eÃ’Š¼kËï=J¾ä|­ªkîGØqXøvø![Ø[¦æŸÇüi·³ºRaHfpW?:ùÃBñã„U’`@ãÌr€~%²kÔÚlÀ’UpÞõäÞ!ø]k­² òB §ükìOÙ['Ën¹Á¯7ñœ¬$ ‘µAü…Op_Š9ÆqZÒiùŸŒË‹Éñ.Œª]zŸ!êž_1À·cß;F=GW ¬øLYMå:ª0çiUçõÍ}9â]&8î$`5^xÛü³šòïi°±`J3’}:×÷— ñ„³…âR”Z^«çú¤eyÄë[™èx=þŒ‰»åúÿ묽,)X@8¯NÔ¬Ùˆ PŽÁü qÚŒP±#n2x s_m›e49}¤-gýyŸ}J¯2¹Ä]Ù…á@u%xþU‘5š#7O¡®ÃR„¡' -Šçï"]Ä”1¨î?¨Å~=™àc =F¹ÎË#€¹ôÎ*¡·'>Õ­uì€/¨ëT. UR¥~wŠ¡6Ú:âÌùVÁö¦qžÕ,™|dóQGó³VlÙ EV# (¢€ (¢€ (¢€ (¢€ (¢€ (¢€?j>ÿÉøqÿbÞ›ÿ¤±×{\Àù!?ì[Óô–:ïkÙŽÈȳá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒj÷o ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW‹øÏÎ~ 3gàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¨‡Â[.ÿu‡õÔ(¢Š³Ñ8?ˆÿò8ü,ÿ±’oý3êUÞWŸüNiWÅŸ L(’Kÿ $ØY¨?ñ(Ô{€•wÑ–1©pð79÷ÁÀÏå@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(†ø‘¤Í¨ê¾6Œ‘ܶ¯R<„àÛ§úT‰ÐòZÒ23• ÏsQKm òBòD’Œu×Å7¾Òt"—Þ®¾}µ^cñ_þD{ïûéîÖ½ææ/òÜ\JA„Ì’K+TQw’ÄžœÖw‰t™´][@·‘ÝïnnAŒ’6Ë®XJ£9 à|õë\~¯û¯i²§É#øBÖuà´gNÔÜ¡?Ý-lGL¢ž W4Û£Y¶µ÷?òUÿöpЧ™åÑ„eîß®ºª³Ž¿.Oú[_høoÿ$ïÂßö µÿÑ+^IðoV›Vñ¾•­Þ*Du-"æ#å·íê7s„$² ŽO& Éõ¿†ÿòNü-ÿ`«_ýµâÿ?æKÿ¶û›®ºÍûL*éoÖÏeÔàð9õF½å4¯äÖ"ÿ’ûEø3ÿ3×ýWßû%W‹Q·×u]ZÒÚMÑÝø¾ ÛHòÞÖÖ Ü`ã9kFþ¸d þo_Jy’ymg•ÏY$}:ÑÝØ÷fff$òI$òkðçü”KOû Íÿ£µÚ¨Éû*0èÛüíù6gZ„^?3Å}ªpƒ]®¢¦ŸÊPO¶é¦høkXþ̾øGmäùŸÚöÛ·cËÄÒîÆ9ÿUŒq÷³Û{ᆭ6µwãk‰ÕÓÄWÀFbŠ”òO%Pïž+ðçúf¹ð·ÙÚU¯•·ø¾ÓcwænõÇÙ#Æ1Õ³œŒuÿ 4™´ëO\HÈÉâ-Bæ „ä(—ÊÃq×tLxÏ}ÂJsœ{_ò„Wçs ¥‡Ãák&­QÅ/W,Eiéÿn(·éÜÖðü€î¿ì+©étõÁþÏòø»ÿcÍçþ’ÚWyáOÝê¾+~XbÕG—áS}­¼Û.îçÕRkÏÿgf”ê¿<ÄEÿŠÞè®[æû-®GAÀã¿ ¯F–’„{&¾æ‘ñ¹†´ñ5?ž¥9ú)¤Òù^DZÑEÞ|¨QEÑü=ÿQ«ÿ¿}ü´jÇðôŒ<%¤('þAÚ69ÿ¨\5±ð÷ýF¯þý÷òÑ«œÑ.– é[ÏÙÚ0Ø*¤g=_hÒx›NÓ´{KûÍâÞÍ¥E–u¤`¦ß*5_õ«ÎÕåYB‚¬«±eð«P’HÞ/Ïlú‚}²FÃ¥ˆ`¨¸ÈÿYò•ûQÜVGü,m¾)ÁâÉ4û Io4‰¯¾Íoræ(â_>`G–ƒžW‚Aõ3U±_ìŒßØ®Ûv½,{Oî¸8!àüƒŽ÷Ejr¶ÖÇ€üzðÕÞðÂòæëX›TÖ¯"Dúy¶|™![þZ}à2=­yïìêÛÿdø[ÏŒ|ÿËÅ…zÏí9¨ÛOð²ÒnmåXK¸E¨5Ã'ÈPñö„v¯'ýã~Ê1(ã#×þ¾,)v:)ìzíQ^¨ÏÅoßò]þ#ÿØÉ©éT•Á×yñûþK¿Äû5/ý*’¸:ñ¥»5 ŠšLÒ–&‹€ôsÍ[ŠVà &¨Í=d9®šUyÕ͈¤t`Nßbjý¬­·€<ñŒ×:'ut«ÝíÆG^+ÞÃãÕ7ÔÅÂç[ktÊȨFq–ÍkYÞ6åP}qÍpÐ^aÀÚzœV•¶¦c|§9öÆ?Zût¢Õßõ÷ò¦zFŸ«lIÏ8Î1ý+¥³×<¹RU%]zmÆx¯#ƒXvà¸ü­jÚøˆ”6Ð1ÊŽþ¼×ê9oÂ䛺8jaî} xémÙ `0þ&PÌ}ºW¨øoâ+D¨¨§{œ°2 ¿P?ÏZùÓÅN¤[gCšèì<{4A<¹BGËÐ×>m’dGM¦”dûíø)ŽÈ)b–ÇÝ^øª…°n=FGåþ5éZ'ĸ.?P2 Çã_Ö_'ŠuyG$d¹9õë]Nñ–âßÓ™‰ý⿞sï£þ2nX Å?'þm.Åá%Í‚›¦ß‰ú7¤üBL Ë´0£®?*Û%Óõ"c»†)ÐòCrøþ5ùé¦üvòvºÈTc ÏSëŠìtÏÚ UµçVn ôäŽ:ü6ú8ç”sz/ò¹ëá3~)ÊmÊù­òÿ3í ­+úÊ9bq̸;‡âHª7ß ¼3ª– ’Xnç“Ü`ñ_.AûC+(qþƒCÿÖ­?öPdWè°OS__ÁN/«ӧ-<ÿÌúì7‰ÜO…·´¢ôìÿá|“àLJÕÆ êËÁWäcÐäçN°øGáËiž_>"1³‚sê Ïõ¯ ´jÁÛËÏLàíýiÓþÑG‚pIú~$k‹þ!??qÓ›¿¡éËÅþ"’åö2ü `ð‡´ÇE9Tϲ—èr:Öµ¬º“&è"ç¡/ÓðýzùrÚ%9"ÿ ¹låX×´Sì]“«0äª7®1]´<âÜcµZRù»}öû«çm[âôó1!œ·+ÁÇýMsšçÅ­GQ‡É{›‡ˆ*²MŒ(§Ç¿¡øÀ§”Î1ŠîÛw_%Ðâ£Â¸ªÕ}¾"W“ß§àZñ'‹Q_cWœu5å~$ñT—NÀ ÀôÚù'òÈ®Rñ˜“%¥<ðrâ¹ëÿ('37¾?Æ¿£2ÜQÃt×$”äºöûÛ?AÀdÐÂ¥Õ5þ°®IœƒþsÍsW·¹Ü ãÃõæ±nuå|‚ì€2?eÜë wd’žâ¼üÓ‰a[í~GÒ ëµt+·,1œqX³Þ£qíŒ7"«]já‰û¤zYÓj+!ÀÇÚ¿-Ì3xT•Ô‘Ý v,Oq\’ fÍ.IÇLt¦Éw¼€j«¹,M|N'ϱÓv ÐqQ“žÔ”W)9QPEPEPEPEPEPEPíGÀù!?ì[Óô–:ïk‚øÿ$#áÇý‹zoþ’Ç]í{1Ù|%ÿ%Kÿ¯x¿ôï¥W„ø»þF½kþ¿fÿÑ^íá/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒjñ±ó¹ÏÁOælü ÿ‘óÇ_ö+ÚÿéÁ+ÓëÌ>Èùã¯ûíôà•èú†Ÿk«X\Øß[CyesC=µÄbHå Œ§†R 5øQëeßî°þºžûB~ÒÚ§Áÿ3OÓ¬®¬ôÝS7JæI “P†ÌE V÷0aòŽs]/í ñ‡TøWÿ¼:PµƒûJêgÔ5 Ý6âþ+ cÝ4æ(\í-9ÀçE~ÌñmÞ›'öqÑm,í…“éÚ:Åmkul.’ëÈ’0‡ ç “äÚI-“É«"økâ}+VÓ¯мa%‡´];A²’S3Ûi–‘ÛÆÒr¨,B¨Ï\é@ôQEQEQEQEQEQEQEQEQEQEQEQEQEQExþ‹§\izW‹¡¹Ê‘¼so8]Àå$º³‘ªÊ}³Ï5Þü7ÿ’wáoûZÿ蕪Þ>Ó­ì¼ãY¡d—š}Ìó¶âw¸¶òÁç§Ë==I«? ÿäø[þÁV¿ú%kÊ¡KØâ;EÿéGè¦7ûG(–*Ör­úªI;jôºvò9Ï~óâÏÈæ†_í23ʾȣ‘2;áÑz2)êyÕ×ú_Ãë{·âH4øôå ÐÆšÄàŸö·]H 逼d}_Æ?Ÿãïê¾vß³]]Ûy[~÷›i#nÎxÇ“Œcݱϖ-´×>Ôôèbv¶1ŸBWE,-mÞÈØÄíê^1ÉËl¶kËÆEª³o¬¿XÁ>ã‡+S– ¿†’OüN¾#ñiÇð][øu¨ÛÅàÏØ4˜ºŸE†xãÚ~dHâW9éÁ‘??c^'ð÷V‡Bñ>’dW6Ëq ÛE@aãL¹ e™±Ô³IçÔ¼ ÿ4ïþÅYöƼsG¶™5Má¢qš¿…cIJ¬ËbK(= ”‘Ûpõ¬ñu$¾®×Ùûj™ÙÃøJ3þ×¥7¥Xê¼ý¼á§ýºŸž¯¡ì¿äWŸþÜôÙe\ä¶]Ø+RÿÓÌõÑ|(ÿ—ût_ýº¬¯‡šLÓ|RÕ55d[Y^[:’w“W»e cÄMž{޽º œ£‡K»üÏR4«fò›²ä‚ù¸4¾öìRðßËãý6!ÄpjH:G>¸ˆŠ;*ªª€88è¾ÿ×ý…u/ý.ž¼ëFÿFñEÆ£÷¾ÅªÇû¾›üýOUµëÛoÚ7ô9ÙŽ3‘è¿¿yà]幚òÕ/goïÍ0óelvË»p¶_£IöoÿI_£<Þ/÷ã9­”©Çæ£RM}Ó‹í¯tìx[þCž0ÿ°¬úCk\ìéûØü{vÖjü:Œ tY.4:w þÈirpI<ÕùçÒu_ë^×´û SJÖïecgl.#šX,ôùJ°+€7·Ì:¢àƒ×ö`Ð4½"ÓÆW:m¥•ÅÅþŸçKoÆÒçFÓå;ˆŸÞM3óüR¹êÄžºŒªÙtçOïOògÏæ˜j´0J¥EeQaå5ìçýñkä{uQ^‘ñaEPGð÷ýF¯þý÷òÑ«Äþ%Añ.×JÐl|/àmT…´})¥žßM¸%K£d$Æ ƒ÷Iˆ {gÃßõ¿û÷ßËF­ÚiØM\øž{ÚÈ)ðçÄëë>_þ&¡þÍý¡øÿ‹wâ~ä/ÿ_oQUÎÂÇ÷žøñ«YÉm{ðÛÄòG"²8:t¸Áþí{?ŸëÞýš Ó¼E£_hzƒx­&Ú…»Ã!FŸOÃÀddžœJ÷ºå~%ÿȪ?ì!§ÿéd4Ó»AkÔQEzægâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QR@8¢Šw° ½±ŒÓ’R¼v¦QT¦ÐÒãåŸÆž.#VÏ$ÕPÄõ®˜âd‰±¯m4G''ñ«BñûÇÐ+%(y¦RyÅz4óN6H— ,ؤ¶ÓþÍZ‡Z*ÅwcÓ¨®T]a9üiæí›½JYÕHZÌÍÓGk¾#ù²Üúš·‰J©É=yƸ(ïNì3ê*Âê~U{t8–´V’3tQèÑx¥bP>bItÕ´ñ@Ý„)ÀÈeæCTd]¸-ž§5 ÔÎÛÏ\žµô¸Æ¼tæþ¾ã‡GªÁãC±[·R ÷ç"øÅà dÜ/Zò•Õ¶€#FúzÔ§XtÁ!‚÷Éé^¬8ç—Çùð«±êÃÇ„öS× ´þ”ããg~hPqùו]Šîëíšõf`qŸa]Žq |DýR=So¼e·†$úb 9$o;:Ž@¯1ä¬Bä ÿxÓ_VqË9”×Õ݆QƒÚ¼ÊÜgZ§Ûv-aÒ;)|Hò|¦RG\?•S“Ä Ä0óÛƒùæ¹)u&cqU¥¾fèpkç«ñEi}¦l¨#¥¸ÖLƒƒÇ¡=j¤º¨a×w°ÚéÝ@Ï1Q<åÔô¯¶uVww5TÒ4î5,•Qï×—$•SÌãÞ˜ŒûׇSR£»fŠ)<Ù'9¨‹r:Rš+‚SrÜ«QYŒ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šý¨øÿ$#áÇý‹zoþ’Ç]íp_ä„|8ÿ±oMÿÒX뽯f;#"Ï„¿ä¢éõïþôªðŸÈ×­×ìßú1«Ý¼%ÿ%Kÿ¯x¿ôï¥W„ø»þF½kþ¿fÿÑ^6/ã>w9ø)üÍŸ_ò>xëþÅ{_ý8%z}y‡À¯ù¢ =l»ýÖ×P¢Š*ÏDóÿ‰Ò4>,øZéÎÃÄ“b8ÈÿÄ£Qõ ~µßFÅãV(c$Q±•ö8Èü«…øÿ#ÂÏû&ÿÓ>¥]åQEQEQEQEQEQEQEQEQEQEQEQEQEQE`xþÚkßø’ÞÞ'žytÛ˜ãŠ%,ÎÆ&@’O­«khl­¢··‰ ‚$ÇJQ@ÀPÆ*Z+5¦çåoÏüιb%,»Újß=Q“àë˜_Æ6ë*ãM~Gˆ0ܪڤaXŽ ¬ï´úWŸCû¯è׳µ[Ogüôû6…û3Ûw•·<ã9ÁÆ÷†.aѾ'ɪ\J‘ÀÉ{a#JÁ%kýJàÊXñ…˜ÇûyÈÛƒgÃöÓY|ñ­½ÄOñi«‘J¥Yhö ©Aãä?ßB>Wü"¿;¡BÙv*­µæö~_j—ÿÀy×áµÎÃÁº?ü#Þ"ŸJó¾ÑöK¶óvíß±î×v2qœg5wÀЦ—{p± žMKPå 72­õÁU'©³;n>µ%ü”MoþÁVú:òÈëþº—þ—O^ݨÊ1[.ý)˜fuªV£Z¬Þ²xvüïJMíç©çZ?úZxŽí8ŽZiÌ©‘5©'$³¶ê0\†ãè¿ ÿäø[þÁV¿ú%kϼ#m5LJ<|ðD÷i㯌1)i%X'‚fDQÕÙc!Gr@Èë^ƒðßþIß…¿ìkÿ¢V¹0?Âÿô£è¸¡¯«WW×ÛGÿL£Î£ÿFøÁâýGï}‹UÑwÓŸo%¯^Û~Ñ¿¡ÎÌqœ‰fÉôïÆþŸ†b0âG¦0O ?ˆï.^èþOˆ¼iªùÛ¾Ó¯èVÞVß»å=£nÎyÏŒc½óÅÙÃþAž*ÿ¯ý?ÿLZ]<\+8¿ï¿¾oôHψêÖR«{,<>QÃEÛå)K^·ÞÖ=~Š(¯lüÀ(¢Šèþÿ¨Õÿß¾þZ5Gà¯Úë>Òo¦Ÿ tÍ>Yç¾×µE’Ye´ŠglGre™¸R|=ÿQ«ÿ¿}ü´j«á½A“ÀZ=º¶?â_£é²¤DïmµM ËMYd{½28#Rï,¾!ÖQFI$›°rk;H‡O×ô»mGO»ÒîlîPc ·þ5ð·†ôpí©ØEcl©Ai‰JŒ…EHãË’~‚©Ù+³%)2¦²Ðèv3ÝNtóHÎBëºÎNNnûÖ7‡|amãkVÖObŸð”Af#{Ë‹£ˆæ°ÉÝ<ŽÀiàNIÎø—â];Å 5MKL•YV9­åJ—‚U2=ëãO¢-I).¦©I6¥¹ëtQEz䟊ß¿ä»üGÿ±“RÿÒ©+ƒ®óã÷ü—ˆÿö2j_úU%puãKvjQEHQ@Q@ÇjZ)ÛÇ—·o>µJÏp’M&N1ÚŠ)\oÂà RÀúæ™AàõÍZ“êý©ë1Œu¨hɪUØV&2‘Æzö§‰qÈëïU³špç’qVªÊú‹h QOñ¸Õ<œã4™ÍZÄMl+"ïÛQKöŽ*‘qÜÑÉãŠXšÜ,‹~yÇÒÎ[ïrT¢§ë ©lƒŒSKî'5J3šjØì8¾­4ÆŠ+&ÆŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ö£àü‡ö-é¿úKwµÁ|ÿ’ðãþŽ7ÿIc®ö½˜ìŒ‹>ÿ’‹¥ÿ×¼_úwÒ«Â|]ÿ#^µÿ_³èƯvð—ü”]/þ½âÿÓ¾•^âïùõ¯úý›ÿF5xØ¿ŒùÜçà§ó6~Èùã¯ûíôà•éõæ¿ä|ñ×ýŠö¿úpJôúˆ|(õ²ï÷X]BŠ(«=Ïþ'FÓx³áj$¯M‰#‘ÿGÔúW}”T¹€vÆ[Üãò®âtëmâÏ…²8r«âI²#BçþA` 5ßFâXÕÀ 0R§ñ‘øÐ¨¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠùÓÄßóÿ¸þçëÜWÂöò§ˆ¡»oµZëR—šÚ†Þ82y“‘½íšñ½{IšËÂZõäì’Íw\hY![=ADd‘ÀyÌqûÂz±¯~¯/¦Ÿ2šíø§ú3õž0ÆN „°óµùÓkû²ƒß£RŠÕv9Ëù(šßý‚¬?ôuå?{àý>ó§ö™©ìÿži‘§Ùžû|ݹã8Îp ù(šßý‚¬?ôuå ÿäø[þÁV¿ú%kÐ¥üEÿoÿéHù û­Oû—ÿÓ29σ?ó=ØÕ}ÿ²W Û[Cem½¼I Ž8¢PªŠ€81\ïÃÛh`ѵŽ$æÕõ)%dP öÉ—sçj¨Éì v®ž« J¿oÏSŸˆ1XÌëÊ:.k[Î+–ÿƒ·©ç?âŒðˆõßøüߪØjgû˜òä´M›¹ëäç8ãwCŽj|ÐÛÃzÄ0ݽز֭-„ŒlѴѸÓëí–×ú\°ùŠþT‘0+4RFÊRgd8$‚ â¸YØŠþ%PÏ) !Òp¡†scÑÊç’OÌXqQRŒj4öý|Ÿ‘TêJšµ¿à>þ¦¯ÄËbøsâËè5kö¿™®%–Ô8¶Ž ª76>XA9=O¥sß³‘'öN„œçþ#×þ¾,*xÊÎãÀšŽœÞ%¼ñÔ~̲ݪíb\eKr¤åÛ»@¹û>.ßÙV1×þ+ÿäÆŸZÆ*)%ÜI·«=jŠ(¯\“ñ[ã÷ü—ˆÿö2j_úU%puÞ|~ÿ’ïñþÆMKÿJ¤®¼inÍBŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ï¢E0 (¢p1ES¢Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJôúó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®¡EUž‰ÁüGÿ‘ÇágýŒ“éŸR®ò¼ÿârÊÞ,øZ!tŽ_øI&ÃH…€ÿ‰F£Øü뾌0Cϸ¨À'¾N?:uQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ŸÅ Üx³Áš…¥‹lÔÒ)Ѱ\Æñ²r@ùãy#Éû»÷uºÊ(¬Õ8Æn¢ÝÛð¿ùþGmLeZ¸jxI|0rk¿½Ëu~ÞíÒÙ7'Õœ™Ômô¿ë3\ÉåFÚ~—m¤å乺¬Ê=³Ïgá¿ü“¿ Ø*×ÿD­qÿ/æÒµŸÝ­£Ïv÷s<ƒ!U­ÚÞõPœ ‹6Aé’Ø;p{Ÿé×Gƒ4 ¸ü««]>Þ £Ük¬j¬22=+‚ŒÛÄÊŸHßï“LúÌÇd´q’v•g +¯†”eNý÷M»ít¼ÝGþñ–ÛÎó÷Ý\ÜîÛ·lï.Üdôߌ÷ÆxéZTQ^Œb¢”VÈøºµg^¤ªÔw”›oÕêÎsâGü“¿ÿØ*ëÿDµc|8ÿ‘ÇâŸýŒÿéŸM®¿[Òa×´[ý2á ½·’ÚFˆ€Á]J’ gÐ×ðÁg_üSóäŽCÿ ÇN²4ïV=±ù^!EªŽ],¿_ó:§ZÂS¢¾%)¿“PKÿIg¡QE©ÀQEtÔjÿïß-¼çÅ?³¶‰ñOHðÕíÇÄÛ½‡¦(²·Ñ&s´YĤ"f]å6“·{œ“èßÔjÿïß-®x'Ä×:'Ã}-m&hdm3HRW?³a5Q"nÊèùÆçö%ð*¶Ù¾5j ú—§þPÃ|?óZõOü'§ÿâ«Üáñ¿‰µ8`¸‘cA*#×® ˆÉùZA—‚ù8Üv%·‹uãu L!ßH^Z@ädÄ«÷ÀÉ„– ¦¦>ÔðÔý޾@¿ò[µ@«Ù¼9?ÿ^—¡ø'Ãß¾&á¿Â[c‰á‘ïþÆm±#K§±ifÉ®O’ÊšÅ?jV Õ.b½˜2[¸Á#œ©ö®à-Ã]þË‚fÎçñ™'>¿hÓèìi s+ž­EWªâ·Çïù.ÿÿìdÔ¿ôªJàë¼øýÿ%ßâ?ýŒš—þ•I\xÒÝš…QREPEPEPEPEPEPEPNÞ<½»yõ¦ÑM6¶¢Š)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEûQðþHGÃûôßý%Ž»Úà¾ÿÉøqÿbÞ›ÿ¤±×{^ÌvFEŸ ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW»xKþJ.—ÿ^ñéßJ¯ ñwüz×ý~Íÿ£¼l_Æ|îsðSù›?¿ä|ñ×ýŠö¿úpJô}CPµÒl.o¯®a³²¶‰¦žæâAqF –vc¨’O ó_ò>xëþÅ{_ý8%z}D>zÙwû¬?®§Ïß>2ø—O×>]x.ÿG¹ð>½â]7K¸Ö¬î#»{Ã,ò¬ÐG€È¨« àîÜà. µµ_ÅŸ|=¸ðΙá«ñ¥M¨Xëz”ׂÞ9›ýÁ®,H¬¡]ðã8kØüYà]Ç?ØßÛv?mþÇÔ¡Õìzñù7QgË“äa»ÊÙSžA¯'øÛà† ¾x¯ÄºÏ…šþÆ;ùõÛˆ"½ž9n/n¶Á&$”Yw*2“i?)Už‰k_ø‡csᯞ2ñå–ƒk}¨E}u=äë4Ú%ñÚ]Ènp£'©»ø_¿ è£øKÿ–¿ür°üñWCñÃÍ{Ä:–ƒ”Þ½¿´»²ˆ­ÂÙMg¤†Ýö®A‰Ø §k²ô&Ÿð/ã´“W†]èzŽ› …ÛÛ‹¯´+[Þ[-Å»ïØŸ1F!—y=hVÚ áŒè[þ…cÃ2áõ»Px$gýgCŒb(Ÿö‚øcÿ…‡áY2ʸMnÔžHÿYÐg'Øï’5‰HE -…䜓ø’MÊ :‡†Ã òAü€8_ø_¿ è£øKÿ–¿ür£ö‚øc#Ê¿ð°ü*¾[mËkv 7ä~ó‘Î> × SV5Frª¹ÜÄ n8'ð~ÀÜ~Ð_ mà’_øX~“b–Ù·jY°3€<ÎMIÿ ÷áý àò×ÿŽWu$k,lŽ¡ÑVV ŠòGã£'Ç_øVöCK ­½ÕÅÞ§¬ý’VóîŽÞ ™¤XÆünPs‚W­%çí'àH|w£é‘xëÂO¢Üé··77ŸÚð*xåµXcÞ$Ú»ÖiÎÒ2|¼ŒlïÂýøcÿEÂ_ø<µÿã•Åüý¡ôŒþ6ñøytû“¤Ï©hú‹Ê³K=‡ÛZÖ]ß 0––Ù ,IÊàXð×í/câ?Œà•ÑÞY5GG´Õ ÈfšòÆ(¥¹F‹hØ¡fù[qÉSÀ ¢ßö‚øcqrÿÂÃð¬{Ô6É5»PË‘œæph“ö‚øcÄ¿ð°ü*ÞcmÊëv¤/äþóÆ>¤W}kjˆ¡@UU€ 5vBʡܤŒí8##ð$~4ÂÿÂýøcÿEÂ_ø<µÿã•´ÃUÿ…‡áUòÛn[[µ¸#÷œŽqõ½š±ª3•P¥Îæ cqÀ?€ð ãö‚øco’ÿÂÃ𬛶Èõ»RÍœærjOø_¿ è£øKÿ–¿ürºÏê¶z©êzŽ³ì­¥¹¹Û”ùH…Ÿ-À<Ié^!¦þÖ1k¼Õíü)uo¨7Œ—Áz~—¨\ù=Ë*Ó6Æò1¹·.Nxéo?i?Cã½L‹Ç^}çM½¹¹¼þ×€ùSÇ-ªÃñ&ÕÞ³Nv‘“åä`+g{þïÃú(þÿÁå¯ÿ¯¿ý³ü5ö x– 5×¢VþæYÕ'Ó,äÔ"²‘c; ”›…RW(„6r¯JøéñÚ?ƒ+£ÃŒuÍGR†þí-Í×ÙÕmìíšâá÷ì|°EW’9hVßö‚øcqrÿÂÃð¬{Ô6É5»PË‘œæph“ö‚øcÄ¿ð°ü*ÞcmÊëv¤/äþóÆ>¤WWáMvÏÅѵ9Jiú”7vÊWiHÐ`tàŽ+M£Wd,¡ŠÊHÎÓ‚2?Gã@/ü/߆?ôQü%ÿƒË_þ9QÇûA|1‘å_øX~_-¶åµ»P€r?yÈçPkÐ)«£9U \îb7“ø? àn?h/†6ðI/ü,? ɱKl[µ,ØÀg&¤ÿ…ûðÇþŠ?„¿ðykÿÇ+¬ñ«g èž§¨çû>ÊÚ[›±O”ˆYð€ÜÀž•áþ×ÖÃáw‰|`ó-uS¢é×é‘Ru’þ îlb1ì%Ð.òIq°ÊpI­ŸŸ´žð‹Ä©¢Ýh­ªÁ›­ªÌnf³’ò;5dBæ·™/(Jªyí@wü/߆?ôQü%ÿƒË_þ9Q·íðÅgH¿áaøTîVmã[µÚ0@Á>gSž>†½šcS r º‚¡±Èüä(ËüCñ[áŠ!·ƒPø‹áY ‰äcköÊ$²±œl•ºsŽkJÚ áŒè[þ…cÃ2áõ»Px$gýgCŒb+Ð)©Ĥ"„–ÂŒrNIüI&¥F)¹%«7zµ! S“qìº+»»z½ÎÚ áŒþ…dË*á5»Ry gýgAœŸ`jOø_¿ è£øKÿ–¿ürºOj†•áËÛ½+CjP¨{}-'Ž;îd„*ãïdôÇœ ð«¯Û4-2c¡éöڥ׉®¼5*êØ·ÓâkuÌ—+va;¢ùå‚wL0;;?ÚOÀ“xïXÓ%ñׄ“E¶Ól®m¯?µàlòKt³G¼Éµ¶,0 dy™9 ¸ŸàÇ‹ô/x¯â”Úµ§k1[Ì$ÓîãLm¥X¢¾PŸ”¼R¨=3ŽªqÌÞþÑÚv‡ñvß÷>¶³O¤hš®³gv$ò®ï"ž{XS1+O â_œ”Ç›Ÿ1«?ÿh}à‡‹åÓ‡‡–í¤²‹^Öï!•`híÞæ —Ÿ&J ¸H‡ÍÀîQEQEtÔjÿïß-±´ ü":Jäãû7Fã?õ †¶~ÿ¨Õÿß¾þZ5sº â? i*Çïiú2ÿp¨j‘œö<çáÜÚÞ¿ñRµÓ.á:2øCŠÉimÌî÷¥ö¨¤rm0nAÙä’£wÂ^%‹âTÚ–§ \ÄC•ìfi,ÚA4R2˜î;%ÄÀE“·oÎX”Ç•üBøá¿‚~*ñõ¤z݇ƒõ ­I¹ÑaY–ÙžêK»ÈîdŒqÒ† â6Ã.Ùæþ[8• а §pG­~îÑMa—V''ÐüžÚkVA4O tYH¥w) 3ØŽA«Vº¥}"Çm§ÝÜHÉæªÅ1)ÇÌ9ûŠý×¢‰a¢ÓåzôÿƒµÿZs‚’u×[;?“³·ÜÏÁÙà’Úi!š6ŠXØ£ÆêC+‚=¦Wï-?Vï/À—%we¡ø=¼³¤ÏO"B»äeRB.à¹oA–Q“ÜÞ£¯ÞZ)ý[ÌžcðjŠý増ռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ)ý[Ì9Áª+÷–Š_VócðjŠý墫y‡1ø5E~òÑGռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ(ú·˜sƒTWï-}[Ì9Áª+÷–Š>­æÇàÕûËEVócðjŠý墫y‡1ø5E~òÑGռØü¢¿yh£êÞaÌ~ Q_¼´Qõo0æ?¨¯ÞZ(ú·˜sƒTWï-}[Ì9Áª+÷–Š>­æÇàÕûËEVóc‚øÿ$#áÇý‹zoþ’Ç]íWjVV$³á/ù(º_ý{Åÿ§}*¼'Åßò5ë_õû7þŒj÷o ÉEÒÿëÞ/ý;éUá>.ÿ‘¯Zÿ¯Ù¿ôcW‹‹øÏÎ~ 3gàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¨‡Â[.ÿu‡õÔ+ø»ðÚËâ÷ÃsÂ÷Z[jq*}¢ ¢uu‘®ãŒãØQVz'ŠèŸ³Î¡¥i7ºSøÅ¤Òµû½bûÅVé‘ Õ¥¾`òÙ™šÙbê–ÝÐšÖøð&/ƒ)«Í&°u½GR†ÂÑî·ÙÕmìí–ÞÝ6oo˜"’ÍžI<•ê”PEPEP^Mã/2øÓâ.—¯ÝxaѬuk=piPé‘$ÍwmÆ„Ý)ÈÁ—rÈü€+(â½fŠùç²ïäÔçð¯ŽdÑõeÓ¿±ôKöÒcœé¶m~÷²#£¹YÝšFMÄ&­ï ~Íø¾þ6]bIí£ÔubÓL6áZË袎åÚ]Çz‡å]£'ŠöŠ(¢Š(¢Š(¯ Ù}±µ¨#ñÝJçÇoãÍ>ñ¬7%Ée+ Çæ~õ@ ™ÝÐcŸuª÷:…­œÖ°Ü\÷r˜mã’@­4Ê ?y¶#¶8F= œ/?b MÃÚ=·ˆ'‚ÊÏHMSj¯í…ú_‡xòXέÎår1‘šé>$~Î:¿Äõ3jþ92ê6÷šªé×HŒ-ž›möy,ö+¯˜È„•™ŽsŒ©Æ+ÚôýB×V°¶¾±¹†òÊæ%š ›y‘ËUÕ‡ ¤AjuÍ:çQ—O‹Pµ–þ"ÂKT™L¨TFÍ•#hIô§÷†@"ðLJí|%á­'C±Ü,´ËHl ÞrÞ\hr}p¢´è¨^öÞ;È­x–îXÞXà.º!P쩺{n_Q@QTb×tÙŹQ´“íÉkÉÔù³G¿Ìyå×Ê“rŽG–Ùû§%ý´·ÓY%ÄOy i,¶êàÉ9`ŒËÔ(à×cc¡  ãzGÀÿi^&‹JñE¼:–«ã Áuu¢Ås¹”mÌnä°ÚyˆÑ¾‚¼çÕïõ­?JÝöÛëk=Ktßh™SÇ·ÌäýÅÞ»› Ü3ÔUÚùžçöÑŸ@ðöˆîRÒÏI]S2Ú‰þØ_­ùw%¼å#?>±ŒŒ×Kñ#öqÕþ'©›WñÉ—Q·¼ÕWN¸:DalôÛûo³Ég±]|ÆD$¬ÌsœeN1^çEfxcÃö¾ðÖ“¡ØîZe¤6Po9o.4¹>¸QZtT0^ÛÝKs3Å4–Ò§HÜ1‰Ê«…`>éÚèØ=˜„PÔQEsü3¨øÏÁ¶‡¤ëMáëëè„+©,&S –ð¡Ðå“rä0#vAȯ%ñG쬞%ð_†thµ3B»Ð Ô,m¦Ò4wŽÛì—¶ío:y/píæmÞaüÜrE{ܲ¤<²ºÇ)fw8 ROaYöþ(Ñ®ôy5h5{´¨Ã¾ŽåÇÞ˃´c¿4âñþÉ5§ŽômjÏXš &Âm"îM-íü×m¼–öŽ&Ü6¨I>eØw"ªx»öQ½ø†4ËxæMcVm8húÝðÒc€êVk~—±¢"8XZ5MÀ>W'9¯z½Ö,4Ù ]ß[Z¸‚K¢³L¨D1íó$Á?qw¦æè7 õf)Rx’HÝdÀet9 Bq@¢Š(¢Š(›øáGÆ~Õ´='Zo__D!]Ia2˜T°ß…‡,›—!²Ey¶³û;ßj? ´ß Xëº&­¥æ›!Ó|8¾L–—1ìuU–w–9:?˜³|Ìun•í´PÃû#é~9Ñu›mnát» t‹¹té ,÷m¼–ö²yۆѲL²ì;ŠŒª¾.ý”o~!2ãÅ^9“XÕ›N>·|4˜à:•šß¥ìhˆŽVSp•ÉÆNkèj(¢Š(¢Š(£ø{þ£Wÿ~ûùhÕâ ø—k¥h6>ð6¿ªBÚ>”ÒÏo¦Ü’¥„Q²cAû¤Ä=³áïú_ýûïå£Ví4ì&®|O=íäøsâuõΟ/ÿPÿfþÐüÅ»ñ??ò—ÿ‰¯·¨ªçacáÛÏ üxլ䶽ømây#‘Y:\`Œv½£á?‚õÿ~ÍVúgˆ4[ýQ$ËklðÈÊÓéø`¬# ŒŽàúW½T–÷3ZL²Á+Ã*ý׊°íÁs*¹ñ~…gq-½Æµ§A²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ãðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{?ü$z·ý/ð!ÿÆøHõoú ^ÿàCÿY}ƒ”ñøN<9ÿAý/ÿcÿâ¨ÿ„ãßôÒÿð6?þ*½Ÿþ=[þ‚—¿øÿãGü$z·ý/ð!ÿƬ¾ÁÊxÇü'ÿ þ—ÿ±ÿñTÂqáÏúéøÿ^Ïÿ ­ÿAKßüñ£þ=[þ‚—¿øÿãGÖ_`å²û)ã_ðœxsþƒú_þÇÿÅQÿ LJ?è?¥ÿàlüU{Çü#½¢ÿáGwÿÈtÂ7ñgûÚ/þwü‡GÖ_`å<þÐKÿÀØÿøª?á8ðçýô¿ü ÿНxÿ„oâÏ÷´_ü(îÿùøFþ,ÿ{EÿÂŽïÿèúËì§Žø\ÓµŸˆ¶Ùú…­÷—oÿ³L²lί¥ã;IÆp*ñÈ×­×ìßú1«ëíKDø‡g.“6¸tÃ¥.¯§yßgÖî.þ?! ˆÞÙ¾m½Xc¯8ÁùÅßò5ë_õû7þŒjà¯.wÌ|Þu¤iüÿCgàWüž:ÿ±^×ÿN ^Ÿ^að+þGÏدkÿ§¯O¢ =\»ýÖ×P¢Š*ÏD(¢Š(¢Š(¢Š(¢Š(¢Šç?áÔÿèpÖ¿ïÍÿ#Qÿ¶§ÿC†µÿ~lùº:+cïïæz¿Úuÿ–ø.Ÿÿ"sŸð‹jô8k_÷æÇÿ‘¨ÿ„[Sÿ¡ÃZÿ¿6?ü]{÷{ÿ0þÓ¯ü°ÿÁtÿùœÿ„[Sÿ¡ÃZÿ¿6?üX¾-–ÿF×þY®«yp.|A472ÈÊsö^¡ IjªÊ·E=Fk½¬ÛÏéú†³§ê·0¯tðÿev‘¶Ä]J³ÎÝÛK.ìn˜j4ÔÕþöÿ6sׯTÄG–j)yB|bŸËcæo‚Zþ ¾ðô6ºµéÕà¸ðÕµ†˜.\ÄÖ/¦éFðˆ³´…ŽIÜñò¬0\ïé>i·Ÿ<â뉮£›^°ñì /fH%]ÚµªyAÄnÆ×'Ia ±Ï’…=ãNÐìt›ÍVêÒ*}Rånîß{6Q p†Á8»†5ÀÀùsŒ’MúÔâ>eѼKâýSÃ÷^×,ü53è1Í«=¦­{{4F{pL¨-Õl Â8ŽBT6åâ"â kz-ô˪jwšv‘£ëñEw'ˆn/¬n<¡a.-åfÄèQ®Xù›Û|N aoO¨(  ±ðT~›àUÍì%µô½k{©]‰ ï¤ê3OµI”’ÄrÛPvŒ&³¨A7ü%ZÍÔºŒvº—‰F™š~ tõòm-Œl³].üøîNåe%Ê&~bºÑ@xëCoøD^ßÞk7Wßð‰øÓO²Ù«]©íïZÀBȾs‘÷+©3,@ȧË~·ÐÅ¢èºxÓîZòÀ[Çö{†¹k“,{F×2³3I‘ƒ¼’[9$ç5z¸Ëÿ„º¥}sw-÷‰’[‰W[jÆ HXÒä*/<*€à(Å<â©tKï­‡Š¯õ-xØëRGž¯Ó¦ê6ÒZ]A½“ÌŠE(ë¹H#*HÈ ú¿@6Gâ‹é.¬#ñ?‰¦Ñ|6×:Øîü=«]]°ºD²û5ºÜ¼×lYï™cÙ"¶ÅOœ¡Zмµÿ„gQø Ú~¡¨ÙßßxëÃÁó¨Îî-®K™œ„V/sTV?/•‰U~ƒ¢€<Zñ<ÞÔÕ5IÌòë~†Ú¼Äoq-°½b¤˜œqŒÖž½á¸døÉ£é‹+¦“«Zϯ^ب\×V/kL~¿i‰½¤?ígÒõ=6×YÓn´ûèêÊê'‚x$Y#`U”B û;Xìm ¶‹yŠXÓÌ‘¤l–bK:’Iï@u}¢YÙ~Ðú üpæïPðÞ¬.%v.Yc¸ÒÕd¨2ÇhÀ˳c,IÑø(ÇþÝœjsgow}mb{}Ž;É£µÇ·±cÛÚ]ÚÇ}i5´»ÄS#Fþ\`Œ2TóÔGjf™¦ÚèÚm®ŸcZÙZÄAc jªè€,ÑEQEQEQEQEQEÑü=ÿQ«ÿ¿}ü´jæö_*f‚X `÷sʸl›8È|ïãoŒ^/ðo…/üu¯öß;Tñ6•‡îí¡þÏ·]6 Uà• "Ü´¸·ï™”ùÓmUÌ~_E¬ÞüBÒ|C®øGH×õ¯Gck¥ê³ê ™¶!¹}B'Š×|QY²YÛ7ï“>[Üá‹ùA}þøBmbóPŸHûgÚüó%…ÝÌÓéá§VYäK'so’,’‡tŒ3ùÓn'Í“u ᎃáÝ;U´³›>§‘u}w¬^\ß4`0T[¹eiÑS|…8Ò;.Öf$„ø)ñŠßKˆµ{#ªÝùvÖVš]´£NvŠ Ó`fžbÙ2ɸ½øà»÷&M*dI%¸–æ(5 ˜b¾ÜKq,wH’¹ˆË<ì!˜<`M*… ì ñ3ã£ø_ñÄ^ðå”zv—k¬[Ùkê ][ÜX™âšymZÝ“Ë[Må…’RçÈ‘«ÈÐèØ|]ñ5׌õŸ Øh6Wþ)ŠéÝ­µ dçÛà †•,ëñÙ™[÷º”aCÄKbV/ÙêµOÞ ÖçÕžûJšæR+˜®,ŸP¹û"„xî$†ßÌò –E–`ÓD©!ó¥%³#–.~øJåýŸS·»yVgÔ­5»è/…¼ä5Ôs,Ì­­¶õ/µÚv ãuqžý¥eñb.¯eá9¡ð€¿Ò,_Sº¾E¹fÔíìdµÙnªÙd}B5˜4ˆª€4m3=¾¹K…ž³Ó®l-´hm,./ìµ7µ¶gŠ%¸´ËjȪ@EŒY[‹„Ä|©Ëg« ¼Lý¡ükà„_¢këx´Ý?ÃRZxOP[T3iº¥¯„,5D 'YUïgV‘ÆlݤóâDö ƒÂÞøw¨|›Á¾,ðf·kâ]3OÙËáíNæ+¹×N´€:¼q0FD¶AŒ©G„0ÃÄ_þÖWÞðö»â™¼ouá8&×ôÝ*tÖo®õ &ÞþYÒ{so²éWŠ’¤Ó70Þâ3Æ¿µv­à+™t]WáýÄ^0¹šÅ´Í"ÚêâýZÞî=BXÓYZO,sªi7¢Híáº[ÉÄÎŒòEsZðgÂ?Üë’j>ñuݾ³ ä7:{é:ÿØPÝÇ$wSAjɶžTšpó‰+}¢r_2È[[ŶŸ ¼mªÞjš¦ƒâïí{˜m-Χc¢ë¶Wp­³\˜LA< íÚ‰•'‘²´Þü-ñµÇÄ_išýÞ…¨xnîçÍI´ÝNÞh%ã•âfTš8¥òœ¡xÚHãvÑš8É(:ºóo xÇ Эt}Gñ5¥…¾âªÞÕ¥wwbòK$yewgw‘Ë;»³331'[þÖ‡ÿ>>&ÿÂWTÿäj»ñþ@¿öÒÿô¾ üõñwüz×ý~Íÿ£¾äñWÄ=+]²Óìm­5ئ—WÓvµç‡ïíb½€ÒK ¢ð8É8’|7âïùõ¯úý›ÿF5cS¡óYßÃOçú~êšG‡¼Kâ«â®n4ëX%ŸûJÑwBf•Âmû¶G=ºuïá+Ò?燈ðiiÿÈ5ä~ÿ‘³Yÿ¯?ýs]u~ ÄÜS›åÙµl.·,#Ëe˼bÞ®-îÏç>$ãLû*Í*àðxŽZqå²äƒµãõqovúwü%zGüðñþ -?ùøJôùáâüZò r4WÌ®ÙÿýäÿäOšÿˆ‹Åôÿ’Sÿä»þ½#þxx‡ÿ–ŸüƒGü%zGüðñþ -?ù¹(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ ußð•éóÃÄ?ø4´ÿä?á+Ò?燈ðiiÿÈ5ÈÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿù®ÿ„¯Hÿž!ÿÁ¥§ÿ Ñÿ ^‘ÿ<2iWVÖWç\÷–Íqò3º5’2Ù0H<ã†ðg‹\‡%Z2÷þ´ñ7³•W^Ê:ë}ÒÓÝ×}-¿Bÿ×>1öR¬ñ6ŒUõ%¥ÒÓÝ×ukoÓcÝô߈Úf‘fðZØëQ¼’M$“Rؼ‚An œÙí}–"0ë’sRÿÂÑ´ÿŸ}sÿVŸü…^©üGŠÇ_½Òmt-_WžÌ ™ìR«#¨dL<ªüî_Ÿo–»¾g\69+ã\—ÿF±s¥]Yê‘xf?]†) )Ùgž¥ÕšÝЦàÄ:Tï)¬8—Š'u_M>Í?µ¶œ·×õ]ѵ>.ã:U#OwìÒ¿½¶œ·×Óªî¦ÿáhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*ðëω66ZÕ̓Ø_˜­u4Ë‹õHÌÏ2BЃóï!ÄkœóapÆM⇈õK;k[ÈÖþÎ]BÒædUŠâÞ%Þ¸bpLÈF@8äã+œq2?¶Ò×øiö¿òöÖÛÛ]ŽgÆÜb¡í!òÚ÷䥵¯ü»Û[omv=·þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯'ñ'ˆmü/¥‹ë¨å–#qoj åæ™!LGñH¹öÎ3Ò³,â¹H¦´»€-Äw2?–VÒæeŒÇ ›\üÇ͈ew.]~nk8qwT4+݆_Ýó_zîeOŽøº¬yቺ×ìSéoîy¯›Kv{Oü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^oñ:ÄOrš–›©è1Ec>§ÚœH‚khJ dUWg]¾bedTo˜qÖ¦ðç‹îõßjúl¶iöÖš}•ÒEtn7Í%ʶì3.ݰÆF9¸<Œ eÅ\KÊr¯d•þ}ÒÓÝ×W¯n¦Òã^0„%Rx›(«ü»¥§»­›³¶Û=Ooÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«ÀŸÅšÅ‡Ä; êçH¸ŠüÊɧY«ý²ÒÝQÊ\ÊåðQ™`F¸g3m&²ußx¯ÂRO¦š=É–Ð] m!•aÓíÂÍ;3æTU™åÜY[y8FÐân$œ£âUä“^ì5»kù:Yùv½Õú!Æ]Rq„qŠòI¯rž·m'K;ôìÝÕþ“ÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«æ[¿ŠzÅ¿Ãx‚Â7ÄSé&ãÈÔì˜Ç§ÝG¸˜Î÷mŠwDUY‰t#* +Ôø»[Ö£×´­@“O·¿¼µº¾iµhü¸(,× ógÁéJ\Mı’Œ±)^ÿfe&î¹n´}UúZâ—ñ|&¡øoÅZn6¥&¯.–>Ë F iu,Jy’DÄ›WŸ¾È[ ¸‹ß£))§_ëóϪ,VöG³¼û;ðócËón°N²ÇKýfâ~^ooÕÇ᧺Ww÷t²î/õÃŒy9þ³öœ~Z8«»ûº$µ»±ïßð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòx-§Å½èÛ1·½‚ ëT»Ón%D ¨FòEò°äƒæ\@¿8LùŠFFH/þ*YÙÍ ¤zN§yª½Ä–ϦÃä,Ñ2$nÛ™åXÏË,L¹f0'ýgâ‹òû_ü–ŸMþÏN½žRq›—/·}~Å.›ýž{=™ï_ð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòy¥ÚßÙ[Ü¢KMÈxÌr(#8e` žyjzá|kÄ Ùâ?òHò'šüC∻úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÑ?áhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*óº(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ z'ü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^wEë¶ÿAù$?ùÿˆ‹Åôÿ’SÿäDÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«Îè£ývÏÿè#ÿ$‡ÿ"ñx£þ‚ÿòJüèŸð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòyÝ®ÙÿýäÿäCþ"/Ð_þIOÿ=þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯;¢õÛ?ÿ ü’üˆÄEâú ÿÉ)ÿò¢ÂÑ´ÿŸ}sÿVŸü…Gü-Où÷×?ðeiÿÈUçtQþ»gÿôÿ’Cÿ‘øˆ¼QÿAù%?þ@ôOøZ6Ÿóï®àÊÓÿ¨ÿ…£iÿ>úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÑ?áhÚϾ¹ÿƒ+OþB£þ§üûëŸø2´ÿä*óº(ÿ]³ÿúÿÉ!ÿȇüD^(ÿ ¿ü’Ÿÿ z'ü-Où÷×?ðeiÿÈTÂÑ´ÿŸ}sÿVŸü…^wEë¶ÿAù$?ùÿˆ‹Åôÿ’SÿäDÿ…£iÿ>úçþ ­?ù øZ6Ÿóï®àÊÓÿ«Îè£ývÏÿè#ÿ$‡ÿ"ñx£þ‚ÿòJüèŸð´m?çß\ÿÁ•§ÿ!Qÿ FÓþ}õÏüZòyÝ®ÙÿýäÿäCþ"/Ð_þIOÿ=þ§üûëŸø2´ÿä*?áhÚϾ¹ÿƒ+OþB¯;¢õÛ?ÿ ü’üˆÄEâú ÿÉ)ÿò¢ÂÑ´ÿŸ}sÿVŸü…Gü-Où÷×?ðeiÿÈUçtQþ»gÿôÿ’Cÿ‘øˆ¼QÿAù%?þ@ôOøZ6Ÿóï®àÊÓÿ¨ÿ…£iÿ>úçþ ­?ù ¼îŠ?×lÿþ‚?òHò!ÿŠ?è/ÿ$§ÿȉÿ FÓþ}õÏüZòð´m?çß\ÿÁ•§ÿ!WÑGúíŸÿÐGþIþD?â"ñGýÿä”ÿùÒ-~*XÁ{gq%†³r-®"¹X¥Ôí‚3Fêêm˜8ÊŒàŠñÿXX¿Šõ¦{Íu\ÞÎJÃuh1¸PÖŒ@ôÉ'Ôžµ±Xþ.ÿ‘¯Zÿ¯Ù¿ôcWéÜæÇÖ>½SŸ“’ÚEZü×Ù.Èý#ƒø“5ÏcˆþÑ«í999}Ø+_šûEoe¹KÂ62Mâ}f]Ðó´U{‰Òbà¥ÈÉÇLŒõ×ÿgùûÓ¿ðaÿ\=éf|—渹ã+ÎjRµìãm]bÞ˹¾gÂvm‹ž2¼æ¥+^Î)h’ëö]Îàiļh.ôâò:Ä‹ý¡YÙ‚ªŸ’IäGöqÿŸ½;ÿñuÃÃÿ!ŸÿØoMÿÒÈh¯3þ!îUÿ?*}ñÿä=ø{”¨©{J~Ô|¿¸wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôRÿˆ{•ÏÊŸ|ù?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]q’ü!´¾ðU÷‡5 ý*þÖëSŸS"k›sg¿kÅã2ê•H'æôÎTVô¸.£ogZ¢³Oxî¯gðt»:hðF]‡·²«UY©|PÞ7³ø:]³øDú7†'Òô}CÂÚcMzolì–žP¾[[¬ªXaTîó7åGÍ´m©üð¦OêèkÚ}ç›§Çe4mu€cžy“Êý騋ö™!Ý…XÆï”éŸ`§ S•j––¯à×çÉsª|%ƒ©Nt§Z£SwzÓÕù¿grm{á•þ¹â«=I¼A£Eeoq ÊÆ ·Úã1àùq܉†#|ÊÈä‡p1‹iðí|#¬èGÄšs¥ÿ…àðÄsùÐp­Ò¤¤yß3m¹\”#°º”UGƒ°p‚§ÕVþO²î¿åß¿©pá\-:j”+TQ\¿óï컯ùwß_>·&¿øTo·?âw§'öž½§ëñõòþÍö?Ý­çwØþ÷ó:¼óšÃïèWpI§É§t/Ýiz2jÖ™,í…XGpw€-Ô3™pÜÕ»E:|„9IµæãÛ—ù?—OB©p¦ œ7Rr›‡ò¨ÿ"û*Þžm›þ,ðañF—Ÿöžmå_Ù_oûlŸ³ÝE>Üyƒïy[sÛvpqƒÎêt«ß?ˆóá³}-äÒÜÜ¥•ÅØx‘V)ÉqtqR¤ä>ŠÂ`pñå¥Z¢Zõ‡[_ìy/¸æ¡ÁØ,,\(Öª“¿XuµþÇ^U÷Ö_¢_´E¯Øß[Üiz=ÁûT =ÂOån–I ÇtŸº98/À^wt¾ð%î—â-KYÔ5í/Qº½³µ³>\ðB`yØõÍœùç>àž„Ë¢®¯`«EÆ¥j?8w¿òiª[v4­ÂXLD\*Ö¨ÓÓz}ÓÿŸzj•í½‘¢Þ¿¼ñŽ¡¨ø‹L¼¶Ó¯%¼±…f¶ŽXËÅ$[A.e`U<)bÄdà§ÂŸ_Zê0k>/ðåû\Ë Ò\Ao2¬ÐΓ@›ÇV‰vm1…\†'p%‹]¢ˆð^ Yéoù÷¥Õ¿w¦ºé»Ü!Â8*vå«5k[øzY¶­û½5wvÝï{!føQsà¯h÷¾ ÒŸQñ4wæöÞhc†'’ÙmÃG ˆQIÉ'qÈÏ-ð.§«ê:~§£x‡HÒ5K8gµ\ÉÒ43yeÆÁ:a·Eœ|¼‚ gQSþ¤ày”ý­M/ü–Õ$ô䵬’¶Äÿ©øu?kRêÿóîÚ¥§³µ¬’µ¬º¯¾G'4Ï Yjº}¤zgØM¬Ò^Á& ¤±IåóàL*pNªþøTt vËQþÛÓ§û7öÇî¾Õîû}ôw]|Ó/ËÙÓæÎ~\b¡¢…Á8mRͶõ†íYýŽ©‰p~ AÓöÕ,ÛoXo$âÝýõM¯Çs.ãö´Ô<=á]#PÕô«û]E]$Ç4ÖíÓ,¶R¬Ž†R6î±\Æs¸HFáŽe?¤²ÐLÒµéðKq,óYÿgY}‰·¢ Ûs#UNÈIÜÙÈÚýÑþ¨ál£íêY6íîZíÝ»{>ïú±Õþ¬aì£íêY6ízm]¶Û·³µîÿ«#¥ðï†n´M. õ› B;hㆠ¥¾€Lȱ"“+y¤;–Å€Q†ŽŸöqÿŸ½;ÿñuÃÑ^lü?Êç')T©wçþ@ò'ÀYUI9Ê¥K¿8òqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×EGüCÜ«þ~TûãÿÈÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;ìãÿ?zwþ ÿâèþÎ?ó÷§àÂþ.¸z(ÿˆ{•ÏÊŸ|ùÿˆ”ÿ=Oü ?üÜgùûÓ¿ðaÿGöqÿŸ½;ÿñuÃÑGüCÜ«þ~TûãÿÈüCü§ùêàQÿäãû8ÿÏÞÿƒ?øº?³üýéßø0ƒÿ‹®Š?âå_óò§ßþ@?âå?ÏSÿÿ wÙÇþ~ôïüAÿÅÑýœçïNÿÁ„ü]pôQÿ÷*ÿŸ•>øÿòÿÿ)þzŸøù¸þÎ?ó÷§àÂþ.ìãÿ?zwþ ÿâ뇢ø‡¹Wüü©÷Çÿø‡ùOóÔÿÀ£ÿÈÇöqÿŸ½;ÿñtgùûÓ¿ðaÿ\=Ä=Ê¿çåO¾?ü€Ä?Êž§þþ@î?³üýéßø0ƒÿ‹£û8ÿÏÞÿƒ?øºáè£þ!îUÿ?*}ñÿäþ!þSüõ?ð(ÿòqýœçïNÿÁ„ü]ÙÇþ~ôïüAÿÅ×Eñr¯ùùSïÿ ñòŸç©ÿGÿ;…Ó‹»"ÝéÌê†R£Pƒ!*–ûýtõ`;Š?³üýéßø0ƒÿ‹®NÿÝïý.?ô²ÆŠñr¯ùùSïÿ T¼=ÊROÚT×ûÑîÿ¸wÙÇþ~ôïüAÿÅ×7≣¸ñ6¯,N²Ä÷“2:«ä‚qYtWÓäœ=„È}§Õe'Ïkó4ö½­d»ŸI’äL‰TXYIóÚüÍ?†öµ¢»³ÿÙ endstream endobj 2772 0 obj << /D [2770 0 R /XYZ 89 721 null] >> endobj 390 0 obj << /D [2770 0 R /XYZ 90 362.821 null] >> endobj 2773 0 obj << /D [2770 0 R /XYZ 90 267.987 null] >> endobj 2774 0 obj << /D [2770 0 R /XYZ 90 249.207 null] >> endobj 2775 0 obj << /D [2770 0 R /XYZ 90 218.473 null] >> endobj 2776 0 obj << /D [2770 0 R /XYZ 90 175.783 null] >> endobj 2777 0 obj << /D [2770 0 R /XYZ 90 145.048 null] >> endobj 2778 0 obj << /D [2770 0 R /XYZ 90 126.269 null] >> endobj 2779 0 obj << /D [2770 0 R /XYZ 90 95.534 null] >> endobj 2769 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /XObject << /Im14 2768 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2783 0 obj << /Length 1823 /Filter /FlateDecode >> stream xÚ¥XKwÛ6ÞûWðtSjNÅ|³=³Pfl'iÓ¤±Ú.’.`²P$ˇŸùós/. ‘G³±Ü÷ã»Íœ;‡9×O×O®’Ðɼ,öcg½q2æ$,õX9ëÂyëþçÙêõúòÍbéG̼Å2Š™»^d»úõúÕ"ˆÜÕ‚sî®&–×o!s_]¿Y½|yùæû:½þýù/­_<¹Šü‘µ ðEK2ä¹`Æ;giéK?™€¸Ö[‰Z}÷桪›^åWª”í pLÉ…¹{ÙÃ^•%®÷¶­5¥3¢½ÕQß¾—yßÑFUÄ} vÆíÞ1æ—†"zbm‡ÊhT; é xâ>ïé¨P]^/xäÞãÙZ+íêQÖˆ\€Ð!ì%ç^™ì×ÈÊcã¨.Zºöªº#Šêˆ º®Î•èeAç{Õoi%*ÃÑ÷­º]øÌzI¤º5$Úæõn'ª¢ð³Ì}^YÛÖF.:#¨zkE'U }½*Q–V]UAn–šø0’™@óºme×ÔUA‘EÙ™¿P^í/ŽŽA꾪rIç¦n™5­êŠupÞ y.»n3P_d“:ë ØÚw*ñÍ:o̲I»0W䕇Qð×rr³àÀ6”=ÜÊ­ÀxïU=´–§Ë! ºªš£¤>¦íS¸ðØ ƒ|€!¾Ð·w¾M¹Þ.#ÆÜ+l#È'a2aÒ½4¶ˆìEu‡~'Üíz¡ëËIiº\§‰ó¬„:0—øP’UºÃá×ùI‡'¡Dl%`00€KÝcVD9 gZµóØ/IKíê¡£r.9 =ÆÒ“–,Uþ¡ê°2;à`ê$PNqE (f6¨È¤ÎlZáô´ã³ÃËp6gÕ«#wUgT×”âáèâ¾Jð 8ÂÔí™+eÚ¿0s‹¡¥8€HÂb!p5[@?fÁhØÐYUóH»FN¬Œ4‹þC#*Y߬d«ƒF5øîUnXG|jv>šÐ%Œ‚éÅ‘zaœ$D߀„8LO¡€Èþ\ÿÇ‘'Á¸ÿùøùî2 w.lu玧ÄiSDvš±côV¤­‡»íé”™-P«Nó•1/ðù7;æ' Cè›=—ªÄ÷îRq4$’ÂcqÇÃDÁÅ$HÍaðˆÄ1ý*@<"×AÞøgé€9=ÒÌ‹X8m¹R U~–äqãb…íõ»RC,³°Éàâ¬ë²W 6mÝȶ ’î8ídoy锕ØIø ‰²ßÊêD±I1žASâ+e¦°±ï±äP%Q=%vŽ%£¶:-0ƒ$Dß±ˆ‘,¼  Ó—Ò¿Á%!rM«€ÙUüƒˆªS…<)Êô6>ÃÁ3ôøF˜?LøÇHÏG¦ŸSúÂ×ó( ˆ"cÉaú%„¡»©Ks±S‡ð\Do?Š]SÌÜz«ÚbÕ4¯“‚ ¦Á‹r‚¸oÁãNE𠟅”¹F3dØIï·ø²ÅÓÞ:×TE.\s“X”­Ń}¦Èjšu³ºCú_XmïZÑlñõH[Y¨Z!ŠÜ)†ìïåúâï œ4ÌáøÍFÌËBî介·1§€spÑK²ÄÙk®d)4"¾lJçæâ·3•ú[ˆ³qërNE ýÌc~H‘6"ÿ î 71ÀTR…ºŸær¢vMÝöÄø^Ü OÕÔ 0WbøšYr/ ÖiBäeIꌎIï2ƒÁr£=~DûЫ’ôsÆáý•‘àÔ@⌎²/ Ä‹²øÓþô:ìOïÅU ù¢"/e5<ïåî륞Šöë…¦eLì{OÞÃÔóVúcáÕõøù²jžJ_âúËEŸÂÇlõðy©MëÉ®Ýxz Á ÊÛ«âNöTó˶­Ûgà{Ý>|›¦Õúçkb÷;컬í= {ïM¾®”ÜŸf6þZ…k<µZŸÁP>R¬f¸-qb¡Jó:Ååéü´ †ª†…š{Nçÿô!Œ‚4=ùT°}ºX¦!¨Ø5 áJ[Û“Ú-¹gOž++ú®.ê=­i<ãÊÜ=Æk­fv0Ÿ×Ô ÒmîÁ` êô®ð_9¸;<Íqs¼pwOŠŒ¹ ‚/Æø<ñ3·ÃëñäòÄËJ±ÎÝÐݨé‡ÍÆ$¤6E†ë§—6If… Õ-ú•‡ Õ›Ô5CYB~«£ÈlºþM?•45±Õ·áÍö¸f2-•xùimóªŒ'VÞƒ÷Þz™¿Ãò~÷¨ÈÈ:–î[¬[ù‰ul¬ÏXÇáO6þTÜÍz€äO¦Óê˜xñ>îÅADÅtÜ£ðÁþ'/†Ió$ƒ¦t¦çž+ÿB9ÞG endstream endobj 2782 0 obj << /Type /Page /Contents 2783 0 R /Resources 2781 0 R /MediaBox [0 0 612 792] /Parent 2780 0 R >> endobj 2784 0 obj << /D [2782 0 R /XYZ 89 721 null] >> endobj 2781 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2787 0 obj << /Length 1007 /Filter /FlateDecode >> stream xÚÍW[sâ6~ϯððR˜]dc.Ý郻1$i ¸Ý‡ÝãÅ‚8k$×–1™Îþ÷êf°;¡3Ý™>I}çö#µµéÕ¯î•>öµ1zÍÝjc¨ áÀ¾¥¹¾ö¹ýñÆ^¸Î²ÓíY°mN×À¶Û›mûa:ï˜VÛî†Ñv“*‹e§ÛóéҞ͜åO+)þ~{ítþtïô‰Õ+Xë&€æù"Œ ×¹‚Ê;}bÀ¢v×°,¡¥u{C&4å¥(ý›Nwaû@_î¼ ^ xKâ=ò¿@ ÚBä¦R(“Ü&³×5 0¶TØÿ•ô–¢½ýG]ûð]\ìZ`<–oçòØŽÙ•¶Aˆf§Àódní|¯âÏ׿Êó8&ñMгè¹`”ÉÍélj;¸% ê¢#¶~"¡ø9‰Ÿ[Þ•QXL2k÷L‚0Š9Þɯ'ïà/£ñB€—š§’ô‡`Ô3*u'<啌þ°Àò°.#¨œÞ"êÂ9(+ò ”ÈÆtï 7r&]¤œ›kTÖõ©äŠ‘ÜejÝÄÈ£jïzxGl>ø¯ä“ˆž* #Å&û+¼û$u ­wé”(ÆËzþ;úPPÉöP°R!LXŠÿ¼ŠC™'už ƆñÂ0ï8áè'‘€¤ß9{J9»êìm<ºy”p8ç¸Ag®*‹°—Ii#í]^='¼ÃIJA˜†XÌŠÆ„ž, P ò‡ µÕ›õJl. Þ¢§¶V{ú¨6ØÛ«ÙVŽÊ¤å­¥ˆ:$Y…ħ»”‘ü±'~åjš ËîU*)I•îüØË8]XŒ¢2:³'zDðQuçz~­?q½5/Ñßèƒ'?k5¾ ÜeºA4;…Æ ˆ¦Ïå†e%D1pçóûµ{»X?Ø3§øÖx~ ‡ED„NHŠýŸ/Þ:Ç׉l°Ó,ŸðWè6wvàn.F€Wx†’ÄÛ¡ëÀ ÉŽÛoDÁi¾—~–z€±Î¿Z?Ë%¯øb˜}Ü’ 8£QåAy—[{D›ogÐ3ÅŸIª†-¦¬=ü­º<å¨r±£ˆ=¥ÞyhdA*Ú%±Š€¢¯õ€¢8ïëZyK¥y¥¹û­Zå¦b9Ëå|¹ž9«•=uÞxiÕäBÇ@|ÞtÒ'Z¡´ÿb¶Þ†!Úy¡ïRöÊÒ*5YÖþÔŒ¼8Aÿ17­FnÛFމ¢”ú\å#é¬Zu“èGñTTªž§oåîÌÚÓß–|uÜ«¢¨¢ endstream endobj 2786 0 obj << /Type /Page /Contents 2787 0 R /Resources 2785 0 R /MediaBox [0 0 612 792] /Parent 2780 0 R >> endobj 2788 0 obj << /D [2786 0 R /XYZ 89 721 null] >> endobj 2785 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2792 0 obj << /Length 945 /Filter /FlateDecode >> stream xÚÍVQsâ6~çWxòR<…dcíÉ9ÜåŽ#__’LG±èb[œ$C˜Nþ{%ËLœ”{èLŸ´Z­v¿ý´Z Z Z£ÖEÔê\õºÖ 7°¢¹5€VöìúV”X·íËÛ(œÚŽëölÇ`;²^{øu4±=¿=´Bíè³1¹™Ú]ØžŒ¦Ãñ8œþ23ÚÑ·OBû>ºî\ùîA´.òôz K¬´M Vè:WZ;n¯ |?ЂRzfÓw¼ÆO@lh¾×“•¤,¿Á9át:™þ5g³á(¼ƒ>ú];·œnô]d9_e9Û I2@ž¨T–ÐAöHÅò¼ºýs¹ëÊËxi;„mídL…P˜¦D°‚Ç$|ŠI Îv«L2>é(Mžþ.•µÀÁûÉŠ%ÛŒ‰xA>Pœ²…FðÚKå?/ÒôÜ =»ÄyΤ™¬0ĈrY b›3'6³9M+ýof  ê‚ïÉÜ!¯›Ÿ•!Ýè÷ûõ¿VáÌ0\­Rªø*éЊ MS#áÆ+8z…5çMëÿš˜N嬾5øŸUT§ó†Ö˜$G)­)Ù.ª“É%;N™ãlGCµ¦ çÅ*;DÅÑ‚ÈK–K’KMNQ'‘_ð–eÒ9©\_0ž¾_Ц{>Žâ½á'‰–Å|}þÚ)¸ ¿ª.õ¦Ï÷‰Ä¯ˆÌH^<`^§êˆÆ“Ã(N®ÇÊáæ:íû5Ðà ×Wû²˜Ïë3üx\är©ŠxÒàtÔ+?îÈoät}q¼ZÒX|“4 VGFx q’ÏbNH®(Â8)at:Îl¨ =/Ô^*·õLŒ«]kÈU£ÍÄþI}HË*‘¼ Ç—Ì­³ÛxÉVÅCºkoBâ—V·f4ÙñJËLf’¿°y{_Õ_ˆÚ¸{Ô€w7#ZRžtÃ:ãNÓÞ禺9LbüGAå'Õ††qÙß3ž‘òU¸VD[²–?ŸÇQ—û9èþ{Ð ç©øÐW¤©¬ŒÂøœ^Lµdœ¦Çî¹öÙaÔúÑBJ„²z6°g¡@}¶ gÅYëöZ‰ZT€Þ gmJÓÌò}àÃ@É©5kýa>mµo”ú´!ä¹&~¤¯¿·žáÃWW+t¦ ˆªÍKV¤‰‘SÆ+-ËHÕUÊúh#Å¿™é»®¥^é:!+’'/¦»¨ªaó#x Ç–pl#_ßþ…ùCÞAè–‡ƒÞb÷uã endstream endobj 2791 0 obj << /Type /Page /Contents 2792 0 R /Resources 2790 0 R /MediaBox [0 0 612 792] /Parent 2780 0 R >> endobj 2793 0 obj << /D [2791 0 R /XYZ 89 721 null] >> endobj 2790 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2796 0 obj << /Length 1342 /Filter /FlateDecode >> stream xÚ­VMsÛ6½ëW°¹”œD0Hü˜Nnì¸Në$µ•\Ò( Ñá‡BRR<þ÷.° EÊ´CG3,°oßî>’Z‹ZW³_³³·¡oÅ$¼ÀZ¬­˜Z!õ¹µXY_ì7¿\\Þ:sS›gÎj/œ˜Ùçï¯>8ŒÛçŽëºöâw4ùxëøÔþpu{~ssyûó®^}º¾¸t¾.Þ½åÞÀ›ï2BYX´³ÈS63jÐ].f.L¨å*X<¦Ä ¸•³o3âë 3è¥qâ…^¨W‡ ÌöÙuár뢚ý ¿îÒ9Ü:\‹lÀŽKb8‘¸$ôCDÈ #¾3w)¥¸Ž­ÉªºÅiYµgU‰c›™…Úq#[äI+«²ÉäW—¢=al‹j%òçI¹ÂÉ^Šƒ¨›  B`çê ó쯃™Ô£k À‚p\nOŠm.Œq²¬ÔÚ^ý‰WjÍÓª,Eªðâó«:‰ƒ†Œn±òÛšÛºãqà›-7¢u’ç÷¸¼ªJãqiVRØ”åcvéiÐ:;u#Úá/Êia&îW±Gb] ú”Šˆy1†Ê ˜C h¡ +ƒRï#O5n!›Û<‘¥X¡Õ!K̹,ÙnEÙàÃRd²4&è›Xhºs¢G$›Þ3„%ŠÈGQ+ÆF Õ:"Ç W}­×Të²iñÏ—ÒMÕ¨0âÈ®Öj숂…#Q .HUM…([4lªÂX6º)Ì%è‘ <ºÐuŒ¹]Frnc$âAg(ËVÔkÇ…IUÅúP±:pý~W,E}%”Ô]È Z!¡*  åßP×H¯çCQ8æ·Jáœqf7»4ÃY‚CX?PáR–48Aî`’&Ûd)sÙÞã³&ÆZ¤BêòêÝé^Ò‡k‘´}+Œd,&”öÄhö€y*¿^Ç:Óu]£`°‹5,Á4óqȤ _É‘(°½ÕôØà•Œ”{ à߆î×cJl¿|¥Ö ÖßY”„qh´UaA†×qåÖˆõé•Z¤Ç¢àº>‰ihù4 5 ÏΜy@©i)5ëF5éÔŸT>Ô˜àp§« é³aÍáeÄÏv·ÌeŠÇö•\oWÚ4*K³­çZ¯ôó?^Ÿæ"©û«Ô‰_´í‰Jƒ_5G?½Æ±Üåù¸[Wu¡tLY½b%Ñ~¬«­¨Û{åäZ¾P—âžh ô+n©¦R“1 ~äÌÝÄŒA‡2»Ï¥´'ÙÅ7'ÎÍ»¬;Õ6"7lµÕñØ©KÝ"ççë¶»÷ˆdÒíAæù1)P·†$ܳ {ÿ¤gMmœÔÕn“õQt‰=ÖÖ›,)7¢cß`mV­žIIV«)íTW©(ÉôbEH'QÀ^ôT•€“a•<îd>U™OyÙ•òññïÄV0¹5Œ¿KÖe’šì´²8-Èâ¡ÖëgX6U ³;lè¤mk¹Üµâ˜â•HåJôå}¢wåU¿õD©©ï®Ór~X\£¢+gWí}iÖb£è¯…±Ì‡!Á8È6Iñ°./÷úcC»Å÷¸Ù1½ÞÂGY3Ý×Á©”tqŠƒID’ïÄi–žÏy$¢¡Ê¤lú•1ÝÉ„/öíÈùTß&¶ÉW¬„šëB6ðm{§ ãnRЇ¯ÕˆŸe#—¹øxð–\ˆïêjÚ£x‰Ã‹ÑðrHQ¯ŸÀ[§vÏv6Ò–7bjê“å?þA ™ endstream endobj 2795 0 obj << /Type /Page /Contents 2796 0 R /Resources 2794 0 R /MediaBox [0 0 612 792] /Parent 2780 0 R >> endobj 2789 0 obj << /Type /XObject /Subtype /Image /Width 1011 /Height 343 /BitsPerComponent 8 /Length 108603 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIFccÿÛC     ÿÛC   ÿÀWó"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ô‰#Öì.<3o¥ÜÏm=í¥…º[ý­àŒK4ÞP,T0Xdí'¥sÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ•¹ñ̾%ð ²”f“E%OQþšœW1,š•¤Û^ëZÏögÚg–SËŒîòÖ2Ç/"ÏAÓ5È~x›QVWù¾ËÏÌ·ý»âïúôïüêü‰Igâ éKaâ];lŸlšg…ôAåkû¢äbÔ–Á;K0•ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍoíßÐϧàßPÿäJ?·|]ÿC>ÿƒ}Cÿ‘+&Š.ÛËñæknø»þ†};ÿú‡ÿ"Qý»âïúôïüêü‰Y4QpöÞ_‹ÿ3[ûwÅßô3éßø7Ô?ùíßÐϧàßPÿäJÉ¢‹‡¶òü_ùšßÛ¾.ÿ¡ŸNÿÁ¾¡ÿÈ”nø»þ†};ÿú‡ÿ"VM\=·—âÿÌÖþÝñwý úwþ õþD£ûwÅßô3éßø7Ô?ù²h¢áí¼¿þf·öï‹¿ègÓ¿ðo¨ò%Û¾.ÿ¡ŸNÿÁ¾¡ÿÈ•“Emåø¿ó5¿·|]ÿC>ÿƒ}Cÿ‘(þÝñwý úwþ õþD¬š(¸{o/Åÿ™­ý»âïúôïüêü‰Göï‹¿ègÓ¿ðo¨ò%dÑEÃÛy~/üÍ Ïx¦ÂÒ{™üS§G(ÒHÿÚÚ‰Ú dœ LônïSñ¥…ÜÖÓø“NIávŽEþØ¿8`pFE¦:Šã¼_ÿ"ž·ÿ^3ÿè¶®ßW°þÕøƒ{eæy_iÕøÎÝÒ‘œwëN报ãtµ¿wþeOíßÐϧàßPÿäJK ÿ[i7“Ûx—N7—:¼Ïu Ô/dZY*.ÿ²îrÈr$¾“«Épt{É/í`qNñ¢}ªÇn×p@ r9ÈÇ;>†;‹Ûh¥E–'ñ3+£Œ«m§‚î(EÂoÞ‹_‹î¼Çÿnø»þ†};ÿú‡ÿ"Pž ña¹†â['yw•ŽVø»åp»­•r7#, ãæøIï?çŽÿ‚Ûoþ7\ï‡õ[g^Ón®Œfcw«Gû¨R% –—È *@éÏSÉ&‚c5'k~æyWÄÏŠ>3°ñ¾¥¯‹µÛhËÛZ”Ê«˜œØêMÌ|Wÿ‘ÿTÿ¶_ú)(«G­Iþî>ˆú³â'ˆtëŸxÄ_ZEfÑD–Bu3FÆî7ÚS9i Ó¡¥p¿ð—è?ôÓ¿ð.?ñ¯Wñ¿ˆ5;À±Zß]ØÃpú8–gdVxŠêÀœ©*sÔpkÔ¾"|Pðß­;M½ñ-ìÖpêWñivkme=Ü·R1Ä‘ÀŽå˜#cŽHÇRy‘že+óZßä•¿á/Ðè7§à\ãRÃâ=&ÏÃzŸªYAæ¥ì±ù—»ÐêWxa“È>µô_ˆ~>ø7Â^¸ñ¹6µ¢è¶ö«y5æ¡áÝF‰ä[(möà‰ Œ¸ŒüåH}»êôJ¯gæw,š)5Ï¿—üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûR¹Ûïˆ:™ã7Á÷—ÿdñ§k-å´ðȉv‘ŸÞ¥+弈fX¸S¸¨^hö~dbGþ~~ðO“á/Ðè7§à\ãGü%úýôïü ükêâÿ…¼Gâûï i7wº¦£au%ÜöZ]ÜÖV÷ ‘á’ñb6é"©¡Ä)¸®ÎgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üâ¿øKôú éßøøÑÿ ~ƒÿA½;ÿãÿûRŠ=Ÿ˜bGþ~~ðOŠÿá/Ðè7§à\ãGü%úýôïü ükíJ(ö~aý‰ùùøÁ>+ÿ„¿Aÿ Þÿqÿð—è?ôÓ¿ð.?ñ¯µ(£Ùù‡ö$ççáÿø¯þýþƒzwþÇþ4Â_ ÿÐoNÿÀ¸ÿƾԢgæØ‘ÿŸŸ‡üáø§E¸ðƯZ½„²½œÊˆ—(Y‰B<šë|iâ߯:ìRêöJ—ó«£Ü e"Fž }wEÏÌ¿ìhòòóþðOŠÿá/Ðè7§à\ãZñ–“¢ZEªI¨ÙÄ3Mk”U›e­![8ê0qœWØ”QìíÔ#“¨ÞÓßËÎýÏ…?á&ÿ©³Ã¿÷ëÿº*ï„u=2ßVÒ ]jÂúTmRêi •B¨k×fÛ¹¶¨ßŒ“_oVG‹¦’ߺı;E*YÊÈèpÊB=ÎÚÜ™eJ”\ùö×d~eüL¼‚ÿÆú”ö³Çsù{e‰Ã+b$qÔ+¬ø™ñGÆv7Ô µñv»my{b‹R™Us€I¢¥R·$mÙJ|Ds/Š>»)FitRTõéÑñVÿl k~1Ó¾[hvú›Ímñ Iº¸¼Ò­„òØ@¢`×DtUŒ²Ò)@q¸pi|H’Gñ'€¤XÀ”É¢°Ø»í©Á8ãòü+ß<ý[þ|¬¿ð1ÿøÕ]=ŽìŸøRõ_’>ý±>xÛTño‹“NÓüMãÿ,ìcÕ¿³²]\Á9‡ýˆÈ±ÛØ›ˆ<±ÑѾx²Úú÷V²Ö¬µÔø¥&±iªÙx^k‹©´qØ’kMqØ|Äm†ù€¢6'Ënùú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕj{ÆxGíOáÍZ×þÿÄ éwº®»à~+‰­´»wº½¸ÒîqôðVI3–ÚUQˆu=}›ÏÕ¿çÊËÿÿQçêßóåeÿÿƨàøRôý'á¥i£êoñ[°ñ®½­jv)-¹¶Õµ;ýÌä"YÊO‘?v«$mŽ…Ž6“û<ë¾)øCâë++ kD¹ÿ…qaæ•eà‰ô›[½JÖá.£ŽA,âKëòa–#øãïŠ~ÔµÏø·GÒ<[âäñÝüšÁ–â-ëNŸQT²12!‰e¶þÎe“nB.ÐáB'èEgyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@4VwŸ«Ï•—þ?ÿ£ÏÕ¿çÊËÿÿPçêßóåeÿÿƨóõoùò²ÿÀÇÿãT£Egyú·üùYàcÿñª<ý[þ|¬¿ð1ÿøÕhÑYÞ~­ÿ>V_øÿüj?VÿŸ+/ü þ5@5‹ãOùõ¿úò›ÿ@5gÏÕ¿çÊËÿÿVW‹%Ô[ºȞÖÖ8¾Å>æŽå‡îÛ 1ŒþtžÆàÏÑþGæÿÅùõOûeÿ¢’Š>+ÿÈÿªÛ/ý”W:Øùš_â>»øˆæ_|?vRŒÒ褩ê?Ó£â¹ïÛOâoÄß øÿàÏ„>ø’ßÚ—59ô¦–îÖ¡iZ[H g2E!UV‰(3‚x8ºˆŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´ÚÒžÇ~Oü)z¯Éü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~×Ïÿ kiþ4øLñ—ƒ~|@Ö|7©y¿d½ó´8<Ï.W‰þIu5q‡Ç*3ŒŽ5©ï/Ã,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×Ö×ßµo†ü5ñ—à |a øƒÀº×‰ì’çE¿×c¶þοœ„ÝeÄÊ¿iF,¡À,+0–/âø(_ï Éñ~Hô_júoÂÉ­­~ÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯¥ôßÛcA{Ÿ†2kžñÇ…t/ˆó[Ûx{Ä:•­Œö3KqÉm­kw3ÂÒ‡P‹")å‰ÂÇ#'µ|Bñ­Ã_x—ÅúœW麙sªÝEhªÓÚiúÄ~,ðÖ˜š­åäÐÄ,d‰–Ù‚ÆâRå±w0>Wç¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëìÈ?iOÂ_ñ{A½†™ÿ ¶ÊÓPñ£qnßȸ´{°ðˆÙä}‘FÛ@s†¬Ÿ„µŸ„>1üGÔ<¦i¾ ÒuXô[é³k}kI˜¨ŠúÑÕÛ12.$¸/´ xåXÀ>Iÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh ÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢€?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†ŠüÞÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«¯Ò(ó{þgöíÿ¢Ïðÿÿ×ÿ•tÃ,þÝ¿ôYþÿà:ÿò®¿Hh Éï~ý´go„úïÄ/|\ð}î‹£ùhƒK³ŠK†ógŽد§"œ4ªNXpSÁó]OÅ¿¶×‡5ßé¾!×-ü<¾'×m<;c{w,"îåŠÆAŽ«ÃÁNž§þ€ÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•ÏèrÒlÒ1M7Øçá–nßú,ÿÿðùW\ÿÄ/ÿ¶ÿÃ_x—ÅúŸÆϦèeΫu¥¬m3ÅM+ªÓT*„HÆHë_¨5å_µüšÇÆOû5Ÿý!š™™ù¯|bý³<3ð¾/ˆº–¯öoËkmzš—Ù´gÌ7-åª>c*q·#w `ãê¯øeŸÛ·þ‹?Ãÿü_þU×ñãþQ{¦Ø­áÏýe_ª”“¹¤â¢ÕÍïøeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺý!¢™™ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~oÃ,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúC_7|Bý¹<#áíVãIðf‘¨üMÕlæhoF„ñGijÈ̲#]LË•X&b [lŠÀc&¸qxì6Ó5æy¸ìË –Sö¸ÊŠó>oÿ†Yý»è³ü?ÿÀuÿå]ðË?·oý‡ÿø¿ü«®îçö°øã¬ÛKlšW€ü,ì‡n¡¼Õ˜` }œÎíåØ ¸(weihÿ´ÇŸùÓ\ë~ ñ~q¶ÆóDŸMÏPvÏÄ›:äæ'ÎÐÜ–"øß%ŒÔGwåu÷«­}lºØøIxÃÑš§*®ïÊëÊí6µõ²êÒ9øeŸÛ·þ‹?Ãÿü_þUÑÿ ³ûvÿÑgøÿ€ëÿʺö ~Ý:¶§Ä?†÷¶è¨Ï&«àËí[uËaÛ²Ås»±Ù€e[ òþœðG|7ñ/öÚÿ…5Ý?ÄZ-ÆDwÚmÂÏ#ªîRpáSÈ< }65ÁæQæÂÔRý<½}?&±Ë3¼¿7‡> ª—{=Ÿn×]m~û4~~Ã,þÝ¿ôYþÿà:ÿò®øeŸÛ·þ‹?Ãÿü_þU×é ëáù½ÿ ³ûvÿÑgøÿ€ëÿʺ?á–nßú,ÿÿðùW_¤4Pæ÷ü2ÏíÛÿEŸáÿþ¯ÿ*èÿ†Yý»è³ü?ÿÀuÿå]~Ñ@›ßðË?·oý‡ÿø¿ü«®ÄmO øý˜5Q,Vq|£)‹nNœíÀœcïÚ¿VëæoŠ¿òtöÿö&/þ—=&TUä“>Dÿ…_ûkÿÑ^ðgþEÿÊê?áWþÚÿôW¼ÿ€‘òº¾Ì¢¢ìëöQ>,ðÿßÛSÄž?[|]ðrjI¦TË-œB(J"Û‘§»qÆ;ö®ëþgöíÿ¢Ïðÿÿ×ÿ•uôG¯ù:{ûÿK’¾™«G,•¤Ò?7¿á–nßú,ÿÿðùWGü2ÏíÛÿEŸáÿþ¯ÿ*ëô†Šd›ßðË?·oý‡ÿø¿ü«£þgöíÿ¢Ïðÿÿ×ÿ•uúCE~Ox¦Ú‹övøûð/þ$xÄ/޼Mm§½¶…g nn­c$f³…“rÜ€ ýîTŸÓÿøWÚüøäi?øªø‹þ ;ÿ'OûÿØæßú]¥WßôÎÿ¾Ð?çÃÿ#IÿÅW†|O·ŽÓHñT.È¢†ésœÍ}+_7|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆúïâ#™|QðýÙJ3K¢’§¨ÿNŠãÿlù:ÙþÇ4ÿÒí6»ˆŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´ÚÒžÇ~Oü)z¯É¨uù«û|øíâ¿Ù;ÀÚ¯ƒh¿øA<7qöï²xþ{ Gì»oîÿÒ%pï¹Õß‘Æý£€+ôª¼«þ;à‡ý¿‡ÿøKØÿñªÔ÷š¿à¨ÚŽ—â À|+¤ÂCñóRÖ »ð‚éw-©¢¢6ù¯’DÇ—ò1Ñ83gý”ùÖÇÄž—þûñ7ÁúF‹qáŸxOS´±ñV•©yK|uÕ­Y®%UTp¬”žj_³4Y'{~¤Úü'ð=–»¢kvþ ðý¾µ¡Ù.›¥j1ip-ÆŸjªÈ¶ðHtQ‘Ô" ; `š«®|øuâ}WXÔõŸø_VÔµ˜c¶Ôï/´ki¦¾‰6HçvBdUh!!X Q‘÷F>Jðßì“®~Õß²gÀï xÿÇ:}¿€lô]#W†ÃÃzÚjŸ.–ÑC^Mw5ý“¾ üvÿ…Yðo^ÿ†‹ÿŠ3ûF¾ÿ„Kþ{øðò!°ý¯™þ«÷^v73^ká ê>*ÿ‚¾üq´Ó2Ø™¬ÿé ÕF'À?åºgýŠÞÿѶUú©_•?åºgýŠÞÿѶUú©Rªî½ ý¸~)k_ÿe?ˆ~/ðì­o­ÙYÅ ¥Â ´<ñ[ù«î‚Rã=ÔW›ü_ý–¼ ð‹öcñ?‰<9jtïˆ>ðýÖ·mã¨%a«ÜßA Nežç;æ:a£²aÈ Œ úo‴_Š^×<%â+O¶èšÍ£ÙÝä£ eOð°à‚9Ú¼+Wý”¼gâÿ‡6_ üQñv}WáÔ µÌÚ ¶Öu8ض¹¾óÙJáUY£‚7p9<œÑ‰â?^µë´ð¯ÇoÙëáfûg~˺%‡ÃOÙhºÇü%?ÚZu¾ƒk½÷•§FðùшÂɱ‰eÜÒr0kªý´|'¡øBýš4O èÚ‡ô[_ŒÞû>¥Ú¥µ¼;šéÛdh®Y™Ž%‰êkÚþ"| ÿ„÷ã·Â?ˆÿÛaÿ„û_þ%Ÿdó>ßöëUƒýnñålÛ»î¶ìãåëGÇßð¼á\Äïûþÿé¾.ÿO´}¯ìžgú?ßM›üÏ¿óctæ€Xsm¸zúÂ>Ó¼áMÚD&ßIÑì Óìá,X¤1F±Æ¹=pªhãoØëÇúï…u_Ú"ÓLøkâÛ¿ÆJ×Ú%Ε1±hŒ‹»Øp Bà 19çÿ^M©Á?ÿlÛ»‹ .⌲ÉavÑ´ÖÌÚ––LncwBÊN GeÈ8b0OèWÀ/ð£¿ácÿÄïûoþê^.ÿO³ý“í~_ú?ß}û<¿¿òç?tb¸Íö4ÑÃ>ñµ.·£üKñV¥âižÞØ[I§›¦‰Ò4%Ü;Dð« 8Êàïügöø˜_ø–éÒÒ¹Oø*?ÂÿÃ'|Mñ·ü!¾ÿ„Ïþ%ŸñQÿeÁý£ÿöÿÇÆÏ3ýWîþ÷Ýùzq^âكƿ<-¢x;âGÅoø*ÆêÞâòÏOðçØou¬‘Gwpn¥R»‘ yQF[«ºý¨þÿÃJ| ñ7Ãí¿øG?¶¾Ëÿ?²}«Éòn¢ŸýVôÝŸ+oÞÝžq‚æÿµ4Zìû*üPñ‡ÂŸh × ¼>~¤ÁfÅä¸HV b:îÈ>¦®ÜþÃ?n>ÿbXDÚwÚÙdOˆð“&º/€ífì°•òãqMáH%@öÑ~)x\ðˆ­~Ù¢k6’YÝÂÖ(ãSÙ‡ÄÚ¼fÙÏâT¿bø}ñªY¼‹»µÐ ~[0ù }ö†;Ã*Û«œç9æ€<ïö–¼Õ<ûZþÈ2&Ÿ©øçV²·ñDOŸöXnïßû2y,0©äÈAu.NÖøã-_Å¿·gì©ý«àOx+ìÿð•ùÛ³éÒý§v–™òþÇwq»Fwíûëß6=ÛÅÿ³Å¯ˆ¾1|ñµŽªºE—ÃXuKx4d´óÜwv‰lª%ó–#Ý}Ý>^µkâ'À¿øO~;|#øý·öø@?µÿâYöO3íÿnµX?ÖïVÍ»¾ënÎ>^´êµðÏÁ¯ xÃÂ?ðR[¥ñ׋á/ñ.£ðõ ©àƒìöv…µˆÐ[ÚÅ’RX—ïÌÅÙ¹l¹«Ê¿áEÿÆSÿÂåþÛÿ™3þìO²Ó÷Ú¾Ñçoÿ€lÙﻵz­Q@Q@Q@Q@Q@)þÝß›Fÿ…kðî;—Š/êW«¨Û¦@¼Óílä’X…ÿVÒÉk½w ê¤þ ý¤|.•Vÿð—Íu£k(«µnÒ; îá™Â‘¾hšÉcßvÈç@ùò<»þÍCYù<9ámNû< Íb6Ò­QÇ%\L¿hû¸Ã$¤°†¯Að_Âw–ÿµÁo\Õ¿µõ„ÕõX¼‹amkm躃H±G–œÃ c$’§Ë°1ZúÞ¥S œáÜçÈÛµº»§£Kn—æ·t›V>ç‚(ÕÁñU*r7+[y;§£Keµù­¦©6¬~•QEýJi…Q@Q@|ÍñWþNžßþÄÅÿÒ篦kæoŠ¿òtöÿö&/þ—='±pø‘£EVg g|*ÿ“§¸ÿ±1¿ô¹+ó‡öø¶Õþ-ÿÁDõÿjº–³«ø~Çìía£Å©lŠÚE¼ó‹Q(h¢y=ÄaUØÌ¹Þ¿£ß ¿äéî?ìLoý.Jüåý­ì´ઞ+ƒû3ûc?d±­Ç‘#mÐámÑIÆÉW£;“©óÇ÷ׇ1©*8õ`ìã 4ûY?5ù¯T|ÎwZX|*´œa6Ÿf¢Ý÷_šõ[œ,²ƒ§ò>É©k—ßh¸’K-³Ãö„+¿Ì´_2!ä^ôæ9x%¿Õþ÷ìÜoÅÏÙßÂ~øu¨kúvµ©É2Ü+iÓ]„ò/c3yojɱ ¸I;ÑòH…ÈPD©Ôòÿ¨ÏöŸýºmù?÷ÇÙ5[+þ™îò埗þ‡æŸ´…ö> øŠí<ÿi}>ØÖû#Ö|»˜—l±ü¿gÔ!òöÈ6éüŸ»ÙiøÞ[æUqÔ)N´šsŠkç¯O[èºé?cüõ”qo_1ÃÑ©ˆ“RœS]Ó•šÛÖú/µ¤lÖôËþ ÃâÍsÇ?±ÃÍoĚΡâ jëûG펩t÷7mÔnQwÈä³aUTdð‚¾•¯•à—òb ¿î'ÿ§Kºúª¿w?¦€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ€ ù»âÇüxø¿ýË¿ý𾑝›¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}wñ̾(ø~쥥ÑISÔ§GÅqÿ¶ü?ì‰ÿcšév›]‡ÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmiOc¿'þ½WäÔ:(¢µ=ࢊ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(å_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZõ_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZ—º6‡Ã#ïúò¯ÚÇþMcã'ý‰šÏþÍ^«^UûXÿɬ|dÿ±3YÿÒªŒO€><Ê/tÏû¼9ÿ£l«õR¿*þ<Ê/tÏû¼9ÿ£l«õR¥UÝzÉeXbyíD˜úT´Íb=Vk•‰Ž"r~ösÎ;t¯6¾i‚ÃbèàjÕJ­[òG«²rnÝIê쯥îÒ!BR‹’Z#BŠ«e©Ûj;þÏ'™³¾R1žGµUÿ„—MÿŸŸüq¿Â¸êqMFrFŠpÒ•Âî&CxÊý¥i_üñßÃoø7á·ü,¯xßûKì–_Û±i^_ØâŠWùåå$sË.<¼ –¾hý›ÿcƒ´W‹¿h_|Að‡ü$íŸÅXÅqý§ym²ÜIªm†dSóÉ!É箫ÓþÍß ?gÏÛ³ödÿ…aáßìíøIÿ´Ó®î|ß+Ký×ü|HûqæÉ÷qÜ眱ØXU§BUb§>e̯'‹•^ï—í[n¤rÊÍÛcéïÙ[ö„Õ?hŸ øºÿ[ðoü š×†|Mwá‹í#ûQu³Û¤-!ó’4S†”®pù2ƒÇµ×ä7…<§x—âÇ›«»^ân½]?Z¼³prRQIäüÄg Î®¿þ>‰ÿ?Þ&ÿ«TÿäŠüó2ãÌ6[Œ©ƒ 7k¦Æ30™F>®¦RtÝ®š³>Œý´ÿä±|+ÿ°ˆô£G¯%®7þV—ÏmªøšÖåyŠøHïæòß³yrÌñ¾×FSÑ”Œƒ¥à-~ãÄþÓ/ï’(µCƒP†DpÞDÆ+˜×$ä$É"‚ nA`A?Žñe óó Qq^ìZ{§go¾Ìü ‹3z|G–kB.1÷bÓÝ;;j·NÏÐè(¬ÍÄú7„ìÒï[Õ¬tkGD³ê)lä3 “céFâ}Å–ow¢jÖ:Í¢Hbiôû”ž5p*Y áǸõ¯–öU9=¯+åïm>óâ½…_gí¹'{;}ûu©ðÏþN+à×ý‡¯ôÇ©Ö]pÞ)´OøÛNðì*ØéöªÞËi+[ÜE+±†Ô$ÊC u»ŒD7r’{&%`qôñrWTýçè—ë²ói÷c]šQÇJ7&äúh—7d»¶—SõFŠüµÿ…O¢Ï÷‰¿ðªÕ?ù"øTú'üÿx›ÿ ­Sÿ’+öø‰8Oú—Þß?â.àèz>Êý¥i_üñßÃoø7á·ü,¯xßûKì–_Û±i^_ØâŠWùåå$sË.<¼ –µeoÚTý¢|+âëýoÁ¿ð‚k^ñ5߆/´íEÔvÏn´‡ÎHÑNR¸]ÃäÈb ü&ð…ÿnÏÙïìsêsyÿðïþÑÕn¯q·K|móä}Nvã{ŸíÛÐ;Ë!M³Êê2СÈùzàœû§ìñÿ'Ùû\ÿÜ£ÿ¦¹+ÛÂâðøê1Äa*F¥9m(µ$ìììÕÓ³Mzžü¢âí%fjüký©¼wào¶¿ ~üÿ…›­Iá”ñ<ÒÂO“äÀn¤¶a‰¢*Øeù>gÝ“^MðÇã§ü4§Œ|!ñûþÏí¯\ijíjò|bâõ»v|­ßtcv9ÆOyg}¡ÿH2@þbƒ[IÁÿmûýkÁÿ`¯Ø+àOÆŸÙ;ÀÞ2ñ—¿¶|I©}»íw¿Ú÷ðyž]ýÄIòE: ÂFƒ…ÆO$šªŠ8ºQ¯‡šœ%ª”Zi¯&´cÖÕj¨¨®wþqû1Ñ2ÿÊþ©ÿÉ4î?f/ú&_ù_Õ?ù&¶å6öÞF¯ù:{ûÿK’¿#>;|KI?o߉%ñ«jÚiþ&Õ,_hò$[y¶¶Â#äKqB#”ïDf‘d¬_ðëÙ‹þ‰—þWõOþI¯œàœ¿ü'ÇßÚ³Ãm£gEð牡Óô»oµMþ]jQªnß¹ð± Ëxë’kJ¥l-JTÒnI­dã¾ÞJM;m£×ïÉÆünøÝáü:ñV‘¤x«íÚ­ßÙCÈ4é£YfŒ¬’)DXnâX€yÙ"}Ķý³ÿ†xø}ÿBÿþNÜñÊ?áž>пÿ“·ür¿:Ãðµ|5XV…8Þ-5zÚhÓÛêûiùZܰåü“ ÁxœzxŠtbÜ’½wkÅÅ«¯ªíîì­m-nJ|Ÿ“Ÿ°—í¿ñ/á7<1áY'ðxøY¦øÏKЯ¯uؤŠóOƒS–æi9RDˆD‚ÖîBón*Ò/ÞA„ú«öçÿ‚—ÂŽÿ„'þÖ»ðÿâö§Û¿µÓ?´¾ÉåýŸÉÿ[”Ù¿Ì—ïç;8Æ ~zþÈ:MŽ¿¥iZf§eo¨é·¿< mugwË ñ:ë ñº0!•”T‚$ú+þ )ðŸÀÿ ÿáPÂàßøKíßÛkþÂÒà²ûFϱló<¤]Ûw¾3œnlu5ú¡ûYôüwþNŸö/ÿ±Í¿ô»J¯¿ëóÛþ !©Ûj?µ?ìeöy<Íž3;¾R1›í+Gµ~„×&‡ÇQŽ# R5)ËiE©'ggf®škÔ©EÅÚJÌ+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf®§±Íˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Vwˆ|G¤øKG¸ÕµÍRËEÒ­öù×Ú…ÂA[˜*îw!FY” žI½hÑ^wÿ Û÷.“§ø›^’^-MðÕûÚÞ“÷ W Ûß³DX`Æ@Ÿ5ð›xÿXÿ?Ã_ìÏ/ýoü%Úõ½žüýß'ìK{»;¼Ï/]»òÛ@=Šó¿øCþ"êß¹Õ¾"ÙiÖËó¬¾ðêZ]èžòkÈÌx$#VÈRÊÇü"ß|?ÿ ŸÙx’Ù?zÖþ+ÒP]Nì+uf`ŽØi™ 30mŒz%ÊxÇø¦}_MÔ´‰¼?â Xá¼°žd•dW@Ésnês%³Ÿ1RFTbÐʬˆÈʽ]QEQEQEQEQEQEQEQEQEQEQEQEQEQEQE|«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡ËR÷FÐød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯A’ijDñ¸ÜŽ °õ«ØévúsHmРWq#ŒóÏÖ­Ñ\UpJØŠxÊ”¢êÓ¿,š\Ѻi¤÷I¦îŒÔ¤“Šz2­–™m§oû<~^ünù‰Î:u>õWþ­7þ}¿ñöÿÔ¢¼êœ=“V£OSJTéß–.œ3¼¹U¬®õvÝîZ«Q6Ôß™VËL¶Ó·ýž?/~7|Äç:Ÿz,´Ëm;Ùãò÷ãwÌNqÓ©÷«TW]§.Ãû/c‡„}—7%¡ÉÍñrÙ{¼ßjÖ¿Q:“w»zîeÿÂ5¦ÿÏ·þ>ßãV¬´Ëm;Ùãò÷ãwÌNqÓ©÷«TW&‡²l hâ0˜*TêGiFœ"ÕÕšI«¦× åV¤•¥&שVËL¶Ó·ýž?/~7|Äç:Ÿz«ÿÖ›ÿ>ßøûjQENÉ«Q§‡©‚¥*tïËN G™Þ\ªÖWz»n÷V¢m©;¿2­–™m§oû<~^ünù‰Î:u>ôYi–Úvÿ³ÇåïÆï˜œã§SïV¨®º9N]‡ö^Çû.nKB+“›âå²÷y¾Õ­~¢u&ïvõÜËÿ„kMÿŸoü}¿Æ­Yi–Úvÿ³ÇåïÆï˜œã§SïV¨®L/dØÑÄa0T©ÔŽÒ8E««;4“WM¯AÊ­I+JM¯R­–™m§oû<~^ünù‰Î:u>õWþ­7þ}¿ñöÿÔ¢Šœ=“V£OSJTéß–.œ3¼¹U¬®õvÝî ­DÛRw~e[-2ÛNßöxü½øÝóœtê}è²Ó-´íÿgËßß19ÇN§Þ­Q]trœ»콎ö\Ü–„W'7ÅËeîó}«ZýDêMÞíë¹—ÿÖ›ÿ>ßøûZ²Ó-´íÿgËßß19ÇN§Þ­Q\˜^ɰ5£ˆÂ`©S©¥p‹WVvi&®›^ƒ•Z’V”›^¥[-2ÛNßöxü½øÝóœtê}ê¯ü#Zoüûãíþ5©E8{&­Fž¦ ”©Ó¿,]85gyr«Y]êí»ÜZ‰¶¤îüʶZe¶¿ìñù{ñ»æ'8éÔûÑe¦[iÛþÏ—¿¾bsŽO½Z¢ºèå9vÙ{<#ì¹¹-®No‹–ËÝæûVµú‰Ô›½Û×s/þ­7þ}¿ñöÿùãÖ™m§~ÝŸ²OÙãò÷ÿÂ]»æ'8ÒãÇSï_ZWÍ_µ7ÁOŠ~9ø±ð⛯íxûc|1’émæûlÀ0¶èY°«)û˃³ï ŠäÂðöM­FJHí(Ó„Zº³³I5tÚôªÔ’´¤Úõ<Ëö9øÕðßᦵûEXx»Ç¾ð®«?ÅïΖšÞ³og3úW +©+¹\n©ªOˆ¾øÿöìý•ÿáñw‡üSöOøJ¾Ùý…«C}änÒ×Ëó<·m›¶¾3Œílt5ÔþÍŸ±5Ž¥xëSøá࿆þ4ñ·‰ü[â&¼´Ò–þ"¹X˜Àw‘Ue™`ƒ¸’j§ÆßØó\Ò>,|,ø…û;ø_áƒ5¯ ÿjýº SO{ {ïµAï[(CI±LäneÚ\c °¯NX,êÓ¯*Qs‡3‹åW‹—ÅÊíuÍö­¿R9¥f¯¹ó7Ã_ù(¿?ì¨ëÿú9kÐkÕfÿÙCðäÞ4ã—„þøÓâO‹|I©x´Ig¥ B8-f6û£Gº€Hˆ³<›P“Ãä;ñíßðÉß?èü?ÿÂ^ÇÿWåÙŸG5ÆÖÆGng·%ìû_~GáY߆Ûl×9=£½½íóçWûŠuÿé~³K­Vö+8äC ¹Ì“ÊA+H2ÒHØ;QfÆ&¹ŸNÿþǨkvÒ¦£åË©_XÛ•’F¾¹•¦’Ú»Lóã]ĶQw19>¹ûXü?øyðCâÃëï øOÃþ ¶¹ÐuÁxt&+VºeºÒ+•÷HUbÒaA-ƒæÚ>y«j0ëºì>MÌY:~–X:éêÀ©v*J½Ã)!œ¨¬cŒd’oÌs¬¢9wƒœùãîÉ»[™ÙÚ)]ÛyÝÛG½”¿â Š5‰–_R|ð\²r·/3³´b®íe'Ìîìšz;FShÄW¬ë/ƹ4f !%¡²„|ˆ2#*¥ä 4Œ ª±Çl_¼øÅuöOÝy: ?Ú{ÿå¾û‰>ų®<¿.ÿwÝÏœŸfψ¼Eýö{[[í fóp³°³~Ün’FÁòâM˾LnUPÎèŒxcÿØ^I5ÇÛu=Bãí—÷a<µšm‰U2v"¤q¢®IÚƒs;vùÕRJ«Sí+E|ûvZÛûÖµÚvùEVQ§:Õ~ÜybºZë§ò«;?ç³Wqml×â}kOðÄ+=sV¿¶Òô}jÃû2âöþeŽ(î`wšÙ6ïI¯I-Á1FR@~þµ>ÿÉÅ|ÿ°õïþ˜õ:ìÈð˧ƒ›´j{¯çþM'ò;¸oÇ3¥€›´jû¯æ´&“^hË¢¾Ãÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿÆ«õ/ø†õÿ”ÿûsöŸøƒßõÿ”¿û¡ð÷‚?äû?g?û˜ÿôÖÕé_²7Å…ÞÖ¿h{xçÂþÕdø½â)â´Öõ¸,¦xKB¡ÂI"’¥•Æìc*Gjë>6þÇšæ‘ñcágÄ/ÙßÂÿ ü­xOûWíÐjš{Ø[ß}ªàzÙBMŠg#s.Òã…[ý›?bkJñÖ§ñÃÁ üiãoø¶ÿÄMyi¥-ü0Er±1î"ªÊ&!2Àq$×èøÂáòªyV21¯ÝûÑM6äåð¾e¥ÏÛ¸o)—唲èÕçäæ÷­Ë~i9mwmí¹Åþ×>øçUýž´ÏxëÂþ&Ô—ã‡.f³Ñ5»{Ù–%iÔÈR9… ê7c`;Šïÿgù>ÏÚçþåý5ÉU?i?ØšÇ_Ò¼ ©üð_ÃøÛÃ-°ñÞ]éKa ñ[,¬ w´„ÈÊÒ˜IL¨! ÜÐ~Ë?>)øâÇÆˆ_®¼6µã¯ì}x:K¦·‡ìPMÊÜ eÊ´Gï6Nÿº0+ÞÂá0ø1Ãá)Æ8í¥®îì•’»múŸG)9;ÉݘVv0iÿðTƒ 塸5¸Œ“Ïö߿Ҹø'í ð³Àß±ÃÍÄŸüáýj×ûGív©¯ZÛ\C»Q¹ußÈr¬¬29 C^ñ¯à§Æÿøj{_‹¿®¾ÿȘž¸µñ¬—ßóý%Ó:-²× ïü½ |óð›ö7Ð>kžð/¼+àïø†ËÂW:…äZtwpÜÊúµÃG&ù¡WvXZ8÷2‚mWCG J40ðP„tQŠI%ä–ˆzÎZ½Yößü5Áú,Ÿÿð¨±ÿã´ÃXüÿ¢Éðÿÿ ‹þ;^ÿ ãð›þ‰ƒ?ðŸ´ÿãtÃ8ü&ÿ¢_àÏü'í?øÝmÌkì_sÝÿá¬~Ñdøÿ…Eÿ¯ƒ¿aßÚ7á‡Ã/ÚKö±ÔüQã­GÓ|Aâß´é7“])†þ!y©1’\‡]²Æw‚Ö½¯á§ìíð¦ÿö’ŸL¹øeàë4xI®Eœº£B%ûb¯™°ÇÛI±œq_™~(ð5¿†?oßøjéU„~*Õ’ËD×,„ ´íiÆTI¡2«¾&Tq…nÿÑZðÏþÿõ¨ÿ†ïýŸè­xgÿÿúÕù«kðÇÁÖ¿cû7„ô8þËplíµôØu3lΙ©a[ÙÈ»‹n™7¶y×Ç¿‡ÞÑ>j÷Zg†¢ÓäÓäŽÚÞê –îÉÚh|Ë+ýªÜ…ÚÑÝó¦‰w]~…âÙâ±è(¥ÌÒ¿/woçôü{kù^Žjc1TðÑŠNrQ¿/wkÿÓñí¯;û êÖ:•¥jzí¾¦Ù|`ð%ÍÕåÜ«0D‹¬3ÈîÄUPIb@kè¯ø,§ÅüPÿ…AÿoŒ¼?âß°ÿl}¯û T‚÷ìûþųÌò¶îØøÎ3µ±Ð×û~Æ~3ø7Gñ¶ð¸ø_/ŽtWS³ñw?iÔ¢ÓLË"Û§’ÐÍ¥õÌLᤈ©*³õ¯íÏÿÑÿ…ãÿOü)­ áÿÃÿì¿·jÿ¡ÿfý¯Ìû?“ÿ¶Ï¿g—/߯7ñœšý8ýŒ«ÿÓ-´ïÚŸö2û<~^ÿß19Åö•Ž§Þ¿Bkàø(ïü?ì_ÿc›év•_×& ‡ÀÑŽ N4éÇhÅ(¥wwd¬•ÛoÔ©IÉÞNì+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf®§±Íˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@W•|zÿL—áæ¨|ÞÖ¼Lºoˆ¢—å·žÕìo ó¿h¦½[Jc*ÀÁÖfÀ=VŠð­i¼+ðƒÃ>5Ò¼ª\xe-fÒì¿°ô-6)­4ËëÉÖ(á°Â[ÁwsçCû¹ȉ淹š³Ê×iáŒ~>ñÒé^ÓüQ¨h—q|M¹ðm櫬Zé7º¡µÃ³ê¤ßb-d.c¸ÜˆÑ±ù1 £¬ñÈöóWÃ߈>;þÝð5î±â¯í› gÆzïÛMm:ìÚrêÞ]ôŽŠ¯¤}) ²íöLʶÈÀI^káÿÚâÅÇÁ}Æ—¬ioªü,Õ|ig>ºt?&×PŠÚÚX“om#\=¢ý¦BßnIBÚ`Îâ@·è¯’¿i?‹þ0ø!á^ú?kÖ±á?{PM3MÒ,´Ó=Ä÷"ÙoÚöQ#ZK,Þ{7J°È$šie…ëëZ(¢Š(¢¹/‰ÿô?„ž“\×$•Õ¤övªêþ僷 œ…c’B¢«»²FŽëœiÅÎnÉjÛÙ"'8Rƒ©Q¥®ÛÑ$·mö1þ5|jÒþhPI$ÚÞ"Ôw¦“¡Ç/–÷n¸Þîøo*÷!’b§nåUW’H£“æ¿øjïŒê?nû¯, ¾göÙ¯ ”FOú¯í9ÁeýoÙr¿êãÝòñ!×õoxËRñ‡ˆEºkz„0Ú k2LV‘4 ´lB™64ó3Jà3¼ŽqyqG^¿ŸóÞ<ÅÏá•ÍF”t½“rîõÕ.Ö³¶·W²þ[âO1óÇ:y4ÔhGKò¦çÝê®—Ek;ktÝ—ÔŸ³Äø½¨|Cñ}ö˜úN±©k Ihó,¢Þ{ {…‰@Gçß]Ê’2¬Œ³¨uB¢8ýÒ¾/ý’?´?á¡5ÿìïùÂ,ŸÛ¿wýwÚÿâW÷¾o»ý±þ¯ùéÿ,«í ý›#Ì'še´q•#Ë)-Wšvmy;]y4ApÞiS:Ê0øú±å”ãªóM¦×“jëÉ ¢Š+Ý>”(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠùWþ ÿ&'ñ7þáŸút´¯*ý©äaýž¿ì®x{ÿC–½Wþ ÿ&'ñ7þáŸút´¯*ý©äaýž¿ì®x{ÿC–¥î¡ðÈûþ¼«ö±ÿ“XøÉÿbf³ÿ¤3Wª×•~Ö?òk?ìLÖô†j£àò‹Ý3þÅoèÛ*ýT¯Ê¿ò‹Ý3þÅoèÛ*ýT©FÕw^EÏÙ|Bð®£ã+ÿZx›Gºñe„"æóA†þ'¾¶ˆ„"I ½‰c;ˆ÷‰ýáš1: (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ †öò>Î{«‡òà‚6–GÁ;UFIÀäð*jò?'×.¼O |=м)¥ø–]LÔ5[†Õ¼Eq£G VSئՒÞÖwfg½C”dœâ±­í=œ½¹ìí}¯ÒöÖ×ÞÃV¾§üRñ•ßü$–ž<°Õì¡×4½H8ÒÚåDÞSÀeVVdÚ2e•ØœIúßJñx/BÞÇ@6FþkËÉÒ8íbU-!™÷mO/ ' U²x¯?áŸ5ÿú"¿ÿðæküª¯ý¦¾xÃÇW_>ø’æÇáOÂ{ƒ{®k¶^×oüCs©Ç ÖŸVñ¤–º¹¸¾‹dc|{¤iYáEÏø[$Í2)VúýxԌۓwwæníê’ÖîúöìwMýjq§F ÉÙ$•Ûè’KwÙñÛö»øyû@þÖvÞK»K½ÂQ½†õ‹iÙí5{Ùš .K“…`’Û@° 23ÄÒ+³<zm_·ðõšM2Kq<Ò-líÀi®¦ ‘` ±$ªªÌÅUY‡—~Û_~xgDø{û=ü*ð+k"»)o.‡t’\‹g%Ìš¬æ5É4afòØ ·]Ì8V]Ó¿d¯‹ÿtë-CÄ*¿å‹NH®5Lßiˆ¨,+k V¸Œ21ó¢-s9Xƒ@J _ŒxgŽ®³,?5Mpë¦Ü½—u¿kßOçox7ÅjáyªÙYÓZ½4\¶èþ×^ª÷ÓÂZÆ—Õö¨ñ\뺄†K¹ã%‚&æ0Û£3JÛ »Žù ‡‘óÐW#sñwÁ2Úßø·FÒï sö:•ìv·6ò†ŽXd*ñH¤ÈêH €Aü.‡ßô=øgÿÿü]~)W©7)Ñ•ÿÂôòÛD¶K¦Çó¥|cV¤§R„ïþiåkh–ÉtZ•j|3ÿ“Šø5ÿaëßý1êu“àÝ#Å?cþxmüObî«ý¿qp,ôTˆ,.ÙXÜRE?eIÊ:mFH¯ª¾þÍ+ð«U)ñ¼þ$ñ¬¶§´Öð ]>Ê)$åŽÚ³áÌåši%mÑe<¥vJý„xk1–>Ž:´:p|Þòi¿Eú»iª¹ú—p†k<Άe^›§JšòM9hì’óÓWemUö=Š(¯èÃúÌ(¢Š(¢Š+æoŠ¿òtöÿö&/þ—=}3_3|Uÿ“§·ÿ±1ô¹é=‹‡Ä(¢³=;áWü=Çý‰ÿ¥É_œ¿µ¿ÍÿTñ\_ñ,´}’ßÈÖ?ãÖçÌÐáO!Ïo7w–ÁØÿq¿F¾ÉÓÜؘßú\•ù‹ûzxÊßÀðR_ë·vQjv–ñÙ¤Ö3Ä$Žå$Ñ`¢`H8r¥Ží¹Ý±ñ±¸³ s­­Nš¼¥ $¼Úv>o:¥Ožê ·1?ö~¤>mÞ^ï2œÁ±æ7}ß3uû^x9>Ùäéºæ£²Ü[Aý§2hZûìo³+yˆ»—pwH¾aܯûß´ò¿h¿ xóÀÚÞ…§Eâ»–;xl¯¯V!$öé8Û^1Ì¢"»¢›ýgÎU2¼ÿŒå¹&cKB¤èµ(¶ü®¿¯¿³?ž2Žͨf8jÕ0òQŒàÛ씓ׯf~·ÿÁ.?äÄþÜOÿN—uõU|«ÿ¸ÿ“øeÿq?ý:]×ÕUûÁý0|ÿÿ“§ý‹ÿìsoý.Ò«ïúøþ ;ÿ'OûÿØæßú]¥WßôWÍß?ãÇÅÿî]ÿìÕô|Ýñcþ<|_þåßþÍIìaˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Q@Q@Q@Q@Q@TÕ´›J½Ó5;+}GM½…í®¬îâYaž'R¯£YIH ‚A«tP?¦|=ð®‹à×ð†ŸáÃÂo ÖÍ ÛXE‹E)c,fP…\»–\a·6s“\þ¾Ÿ > èúmî¡aáÿ ÚC{Òâ†Æ4–[ÑfmaŠÎ×|·&Ö3op«Hѯ–ŠGËU?h}sYÐ>E&¬\xR½ñƒ¥ JÒ%š®õ{;Y™xäw•4€FqÅx‡þ|=øEãûË;/Ž~8¶ñßœš5æ±}¤iú½ÃI.–©úŒÚD“L»õm%FùYUdŒ ,,#õø~5|5¶û•àÿEö;Ùõ+mŸ µáä]Mæù× ?å–O´O¹ÇÌÞt™'{gçâ§ÀÏi^3Ôçð±¡éºÜ3\ø¢òO…:ͼ7ñm‘¦’ùΞ«¶I‹4¤Œ;“Ô×kÿ oÅßô]¾ à‡¿ùU\W€<'¤Þø¯âV­ñ7Ä5O‡Þ †-;Wñ|¶ém¦Ã•§êèÛÅ6qÏ—W]ˆVeŒí2m ×ÁÞ"øQûRèéâK +Oñ…¦›çiñ\ë¾’)`K»8¤•#[¸UÄSÚÜBIQ²Xä^XWª×ξÖþ"É⿉Z߃þÛÝè^#ñ:­÷5+Ÿ4Ñ.•§Ù•Kcg=ʲÍeq¸Oi…£2«’š¿ >/xª÷ãoŠ~ø¾ÿGÖn,!v³¿Ñ4ItÅómá°ší$IonK/—¬i¾[¤²ÝU Hî´QU5mZÇ@Ò¯u=NößNÓl¡{›«Ë¹V(`‰³ÈîÄUPIb@h‡Œ¼e£|>ðÍÿˆ#xª? ø^8ŸThÖ{»ë”/k¥[1*.'‚Ä•q!ƒLÊÀD–XªXØêž!×lðâ²ápx³þ…ÿ ¿ù¿¨¨åõ}œ}”-ik%oCúî (ªpI%¢KD’Ù/#ר¯!ÿ…ÁâÏút_ü(&ÿä:?ápx³þ…ÿ ¿ù¶þÏÄÿ'â¿Ì¾tzõä?ð¸Uÿ‚£ÿɉüMÿ¸gþ-+Ê¿j_ùg¯û+žÿÐå¯Uÿ‚£ÿɉüMÿ¸gþ-+Ê¿j_ùg¯û+žÿÐå©{£h|2>ÿ¯*ý¬äÖ>2Ø™¬ÿé Õêµå_µüšÇÆOû5Ÿý!š¨ÄøãÇü¢÷Lÿ±[ßú6Ê¿J~*ßjšwÃ͢˨Zj¦ÊHí¯´½=u ‹q°]%«ö'wœa]Ï Œ¢#»*7æ·ÇùEî™ÿb·‡?ôm•~Ÿx³Å:_¼+¬ø“[ºû‹£ÙM¨_\ùm'“Hd‘ö ,ØU' 8àRªî½'ø­ñLé?cÓ| ñÂïnïu+Û©n®Ò ]]"–)Q¬îîVÓå¡[Ô¤IQ»¾XŠñZfã x#I·ð5×ÄèZÇ‹|Júηá½_½³d¿¸ºÑ˜ióΓ¤E?,ñE"Í4QGw½^to¢¼iûL\xÆÞ¸Ö´BÇÁš—†u}VþÆ]cªié×6‹u4ò¬­ ¶Hn&rQH“ìëäKpn Gín>;é0ëSèÉ£këêwºØÆ¶á¥Ô`²ñZ«4Á7\Ùq³‚“<2â3F'ʶ>ñ—Âm?Ç^5šãÇ^*Òü[áÍS]°Ô$»‰|Se>Ÿ¥Gw ¤bõlÙ¼I¶Ek,¿5¼v =¼ËýðSÁº·Ãï„~ðïˆ5[sÄ:~™Z®§s¨\_5ÕîÀn$NLŒ­)r¡±µJ¨U(ù~ëö¦øoñþ?|[øSÿ¿ü#º.âï jÚþ¥¦KºÿSûDvöö­ç®7ý¤G›ËUû;M:Úýž9°|1ý³>|hñ– x×Å#·½….W^‡Ã—pi‘DÂôy’O2 UXIâ0ÒHˆ›ÊMå{­Q@Q@Q@Q@Q@Q@Wšx·â?Їïƒq £ižÔ„zûImskZ„ökk4Å)Žxš6’TÉ Fh•ZQÐ|ø¿gñ·ÂÚõ–™¨i1ÚëZ–`Ôlî-¾Ëw$ Y≾uEfP§Ëvx˜ï‰Àô (¢€ (¢€ ÀðÇŽtÞë6º]ÒÜK¥\-´à2òZ5uuä¡ÜT1Œ“‘ñwÆÐø'Á÷5Ôv·7?¸†G&ÌðÏÀŒÁ—Ö¾Lð¯ÄÍáïÆ ĺ^¯öí7P€ZkQ´.†b Y*»bq³,Æ&ùÞoÅ´òÌæ†[ËxµyÊÏݿîËKÉߥ­¹×Nƒ7?¸û¦¾ý­õŸ ü,Ь¾,ø›âˆ>IáÛ+Í.Õü;„ןÚÚÞF´ŽËi–IY¬b+·fЮÌÁ2Ûýª¿lO~Ê ¼Ô'hUôÏ Û] ¾¾g.±±^LPn÷NÊTl`7¾Ôoˆü1ð[Æ>&è?k;K^Ô5;K½sÂ? ,tWQ‚Ý£hU–îÚÖÚãìvé¾Çt{]ä2'Ÿ¹ÒHäýc•.f’:oÙCâ7í?ñ»Ä–þ#ñïÄ?ü<ø[«^‹=ðÖ>­«É4O=ºÂÿÙ»|”„y’^4+!@Ë´[_´ÆŸü ø›áÏø Åž"ø³ûJêú<ú%–“tº\Ö>Šñ­§žw6ö6¾d¿èq: ð‰™¥UBOtøÙû@ë2|>ÖíþXx–ÏÆÚ¤cÔ|QàO›]=Lah£]2`]B.ض¬{Ù¤mß2IÃþÀ? |ðfòîÖîóÄ øãâk+_]ñ‰|5«iÏsÍÚ#µ–þÚ"ñ,·—lù’»¬Ž‘Êæ½Ù´Ý.D ú¶ÿ%Ñz·{_M@ýŒ¿c-/öaЯµ­jûþß‹"Ý?ˆ¼Upí+ÈîÞcÁ Éóù[þfvÃÌã{ã‘ý+EFEå?hï ~Ïi 7‰m5›Æ×&–ÞÊOkÙ^HÓ{-ﻹ²Sœw™IA9IÙ"e(Â.RvKvz¥òçü8×þ8iº]×ÄëÄG…4–‡^½ðÔóI4:~±ox«:ý¼<²Ë=´ ò1´H¤.=“űˆ¼wáH´}sâ&Žî³k÷5·„A‰ÛQÕm5ˆÁ‚âîhÙb¾³]É u–ÝÚ"¿}Z-ŽüL$¼ýŠáÕmô·ðïÂuÕå†[‰4Ãá«?µÙ¬Mœ]Ãäoµh„›åIÕ$Šwp©Í¿x#à&…ñ«Á_¬>|?ÕäÖ¯n,5+èü/¦•2ió_C8²kv•〓 OÊ’Å Ñ÷ š×ìOâ++RÓôxÂV:¯‡õúÃDø|--u%´Žâ[xá¿B¬#°¶Úfi›y˜–1´QCÕøsömñï‡üMỦø—£ßèZ?‹n¼`ºmÇ…f°]%ý¼S¥ê…¤Ô/eˆH’É’5i&Xð̃Ý<-á=ÀÚ®‰á½Oðþ‹k»ìúv—j–Öðîbí²4W,ÌÇ’Äõ5­EðüwþNŸö/ÿ±Í¿ô»J¯¿ëàø(ïü?ì_ÿc›év•_Ð_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQEQEQEQEQEQEÆ|]ñ>­á/-æ†öQê·¦—¦Ã.¡nóÁÚ¯ííYÚ4’6}«30×$k³¯;øñÿ"F™ÿcO‡?ô÷e@wñ×Jø‡má-MsÅÔt¥ñŸ…|ëm?Ãw“¿üOôý»e{ùUpÛIÊ6@#ŒäxGÅ_ù:}sþÇ=?ÿK¾WªþÑ~±Ôþ&kzóøqõÝWÃÉà-BÞk%õ ûHÄ·2]½ºD7ú˜œ¸ŒUÊxûÁÿ|wñQñšø“ã†y{ m4¿‡:·ŠxŽ˜Êè'Ñ%~_EÓœ†r3 wV·ñ¯áÏÁo|m×Ä:ƱˆfÔôíöH~iº•½ìðÚÇk𕯇p:Ïkþ¶äíó‘~QµGk«x[TñŽ™ûIéÚ=¯öúøÏO¼]¤XÓYK}BžM6Frb»HžÕËå\1euÊž_›ÀÚÿŒµ]hëÿ,tÝWÄg‰¯¼9mðßQû ÷¶"ËÈ%ßFk…SýŸlYVa­Œn5Ð|4ñoŽ5Ï|X—Á¾Ô,¬5ïA}iâoÙϤÙÅ èÚe«²YJ©yq*K‘ŽdTp.£`(Ø<ñ“Â^?ÕeÒtÍBâ×]ŠtÚ&·§\éZ‘· ªn¥ÜqLÐo`žpCl¨mÊ@ð¯|ßÈÂUÑ¿go Ýèúõ¿­´ÿ‰wzþ´¾!Ô?·ô›i,ã½pÚ²Û”aI ˆ¤)mòÈIckÀ?³ß„¾øÊóÄÚAÖ'Ô®a–"ú¾±s¨²´ÂÙn$ónåv‘,l‡vT[8ÄkéL€ss •´·¤D†I%•‚ª(,Ià9Í|ñ÷ã~½ñÏYÒcðÕ”?ð¯l3?Øõ;¶·mVð4m Ëã4P•s’Uœ¬ØÌp°úöÝ×®ô_ÙÛ_ƒN¸„êZ¤¶út[Êb—V 3YDã”i!Y·>HÖVmª¬éñ5ïí¬çÕ¼]$Z½ô1µÄÚµüv ´– ¹A@hÊ¿îÑÝ×yü¯sš˜.Lee4î’»iéÒQin·^Iî¿ñˆ*åÞÏ YTNé+¹'¦ÊQin¯ÌµÑ)o“JÖ%¸¸k-BÙ,u5S'“¦Xå oÊ©` PT‘‘†FmkSÄ:퇇ü?aý­â-GwÙlÌžZ*.ß2yäÃyPG¹wɃ÷‘^I#üâÃQÖuoü:³šÆ÷SñÖ©un,l"RòæA‹Àv¬NÖþhÝÀÒÒ*!˜}oû>ë¿ ¾x#ľ6×¼edu[§Ó ×uwŽâßO··–w‡Nû)–4ó¬ ·lÔ1åNÍ<Ò4Áð9 Ë7ĪÕW-·ÍkÙ´íh·­Ÿ}ÕšÓFÿ0á~–{‹XŠñåÃEµ+7i8»Z êâûî¬Ö•¿bø+ðWKø9¡Osÿkx‹QØú¶¹$^[ݺçb"e¼¨#Üâ8C»™™žI%’OE¯?³ø÷àK¿ èþ$“]þÍÑu[ÛÝ> ZÎ{.{4º’í'YÑßÊ[ ²Æ`€y'œ•ί~'h~ÜšDš„7v[ ņ³¤Ýéw‘£îòå6÷QE/”å$U“nÆh¤PÄÆàFÒ¥N…8Ò¥ÅY%²Gõ °Ô£FŒTad–‰%Ñ{ãßù,Ÿý€´ïý(¾¯ˆ¼[ã]k[ý—µX%ñ—†tÝ;á•©In¶6ÑZjj6×<WËÿhÖ¢ $¿2Ê»b¯½|{à/j~<Ÿ[Ñ Ò.­gÓm¬Ù/ïå·tx¥¸r@H$8î:+„¾ýžu-N×L¶¼ð€.í´»Il,!žé--¤‹É–±ÂFñ"àH#ŠúªU©:‹šNÖNû¢ýö¡ðÞ¢×÷·R^øWZU‚y³´qÜèà$Q€e™Ýœ‚ì_Š$jžsañöº—Wñ ëZŸkáýwK¶‡TÓo-´ûkKYôùõ¥’? y®·LgI f±VÙ#o¨$ø_ãYu5Ð|(÷ðE$]6¯9–8ä(Ò"·Ø²ŒQ’Á1®~èÅm[àïŠuíÿÚ~ðn£æZM`ÿkÔå—u´Û|èNë#˜äòÓrtm‹p+¦XŠj‹{þB³ì|‹oãoˆ~ðuž•§ëVš®—à«?êiö]­«j÷ò_Oyý¬oÝs<Åm|¶Œ<ã+ˆ‚v²êž ð¯þ$ø‚Ã[òtØü¡i£ HÌw_l´Ñ-&y¤`_äŽuh„F-®„ÈfV¾ù®ü ×¼S¨éZ†µàßê÷úL¾~u$òÙI•mð³X“eåH9Eôf_ƒ¾)Ÿí^g…ü'ڮ⿸ߩÊ|똼¿*gÿBù¤O&®y_)0FшU¨­=¯§ÜÂϱ⚮ƒ¡é<®hv\ «kWÖ—ž$°¹7–£t¶š—Oºb¹û4f Ã3?—%¤1Q^?Fø·âË¿|)ñŸ‰´øàšÿEÑou+xîT´O$0<Š)©*2Åj\|ñöÆ­®éþðnâ­NÑ­&ñ%î5…UT™_OmûvFBÈv™R+7ÿ>.hºÅ½íç__¶‹vý;QÔ¬’ r¤ Æ 9 6¸åFr2‹B7JK_À\¬à<Ê/tÏû¼9ÿ£l«ôûÅ:ü$úÖš5-CG’]­¡¥ÏäÜ[ÈŒ$BAVÃ*’’+Æã)":3#~`üxÿ”^éŸö+xsÿFÙWê¥J6«ºô>j›öððð…—†,|}ã E·Ñuítètx’k]RìÝ_©_ìò±ïa(„F±¤(!.[ªOÙŠ$øaâÓñÆwm­[x†[&M/ì÷wñi‰¦<ÒbÇxó­U‘Ö7EFhÄd)_k¢¨ÄùÖÛö'Ðlm¼,-|ã‹;ï išf™¤ê6×V1On4ù.¤§m Y`¾»µduh¤†fó#ywþø"¾ñþ­âÏøMÆ„o26ßk¢€>u—öqñP±ÏâK}~â 3Àv3jú”’­Íôº&±5ííÄ ‰i£˱2 @ùÏwðÏM¸ø5àO·o´MJƒÄzÞ³¨5 [+ÍF{Ô{†–8Ö_´”e×ä îÂôÚ—Å èÿôoßkVöž,Ölç¾Ó´Ù·+]Å o–ÄmfPwlvÕvj1aûwÿÉž|Zÿ° ÿÒ¹kÖTèN´5åMüÕôûÕŽU'óôûÕ™ïWÅÿþ<šû?†¼Kqÿïˆìõ [þEÞÂ9üøú7üºô?èÿñëö…pe9¶9Ã,VÝ=×Tû??Ïu¡æd™Þ?Áǃ•ÓÝu‹êšïø5ªÐ(¢ŠöO|ùÿT±ñ¿Æ/ˆ>°µ»øm¢øKZ‹H²‡Ä~ ŸW¸o3L°¼’C(Ô!UË]Ú±Ž#\’i?áAxÛþ‚ÿð×ÏÿËzù3öÊøÌ5¯ºçÃoÙËDñGо-ê“ñF«áßkÖ:d¬‘¼›[¸­Äñm¶O(òbòÑ$ÞÅÄ~õð3öi¿Òü&žñ_Åxûâ—{ñ>­qãÙÙY‰aY­˜†xR|!C3no5À-Ï%ZyKš¤oºWgE*U*ß“h«·Ñ+¥wÙ]¥æÚKV‘Àü ý–üuû`|LñW‰|¿|Qð¦µdm¬ÖÚêÓB²¶’ÃN–+¨£”ÝçˆKp°Â× ‹ä¯—+4Qütýµ´ßþØþ ðg¿ ß|`ñ¦Ÿa¬èWÚU®¨aŽ»ë«+†Œ\ºËÌa“ÌR(U‚—_)Ñ1¾6|`Ô#ñÞ¯û4þÊÚß5ë×»ñ‡/u«ÍCûCo17·K"Ê‘E o cäíXâV¸`"ú/öDý‡<û éWrèMq¯x³R†8uêJ‚gP«ºF!€È¦M™f'hw“ËM½…9ÅÅFšiu»½ßÜ•·¶—WÝŸ/üuÿ‚„|_ñ=ŸÃÿü%ðχì~&øîÊÇWµ‹DÖ[½Ó-g….#Žâ)ìa·‚Wƒ33ȱIJ;VŽZúWöm?þ(ÿ¤øãk_Áh¿äƒíº~«%Åæ¥>¡ý—qçËoö8b·âÍË"<€4¡W…Éù«öDýŒ¼!ð>ÿöqø©a}¨j¾$ñ¥í´ù¼p©§Á?…5‰àE\Ýp¥·°Ê¢Äƒ•‘åûWöNÿ“Xø7ÿbfÿ¤0Õ˜«EP_þߟò<|ÿ°Î©ÿ¦Ù«ìjøçöüÿ‘ãà?ý†uOý6Í^{ÿ"œ_ý{Ÿþ’Ï›â_ùã¿ëÕOý!ž[EWñÙü 柴§üŸ׃èB½.¼Óö”ÿ’ãOúðoýW¹‘ÈÛ ÿ_!ÿ¥#èøkþG˜úûOÿKGëQ_؇÷ÐQEWÌßäéíÿìL_ý.zúf¾fø«ÿ'OoÿbbÿésÒ{‰5+ø´­:êöe™á¶‰æu¶ç”ª‚HHã îØ*‚Äð'ñå÷Æ /Æ+ðïS×<{á'ÄZOŒïtÖñH6-¼-¢K%á±›Îd’2âŠI*MªÜE$‘·›öe™ÜÕÏ‘>~ÔÑèßü#ãKÆú™ýµáO ]Mmsqm› ÍZ;=NÕ þ]º‰î~ù’9!o1Ú%h«¤Ô¾9ø·àÝØ×¡ø¹¬x×PÓæñæžÚˆn­¥²K‹MzÎ{¨lìþÒËoepúƒÇóvù03¡úáWü=Çý‰ÿ¥É_LÖ‹c†> ø_ñËâ>4x+Á·¿þ­Ü7בÇá«Oí9µ›K;5Àûd†Þ9§š#¨BÓZ[¬(mïvÇæDV×íú(¦@QEðüwþNŸö/ÿ±Í¿ô»J¯¿ëàø(ïü?ì_ÿc›év•_Ð_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQEQEQEQEQEQEç?äHÓ?ìiðçþžì«Ñ+Îþ<È‘¦ØÓáÏý=ÙP¡ÿÉÂø×þÅmÿJõŠôJó½þNÆ¿ö+h?úW¬W¢PEPX>;ñ¾‘ðß§‰uÛŸ³iš|^d…F瑉 ‘F½^Y•Ìîêª `+z¿>~.øûÅI’FfY’ íÊ*µÂMÞÚN“c iVZf™eo§i¶P¥µ­¤K0DŠ#DPª¨(ð|9õñØ™çÚæ“øSÕ[kµÚÚE>šögæ\'˜œËS>â(óÎ_^ªÛs5ü¶Ò îµkfyï¯ÙßÁÿõ[oM‚çSñ=Õ¨±¸×õYD·on$."Pª±Â™+¹bDcBûÙCW üñůÁ_ |=¿ºðø´ð¥ï…àÓg·’v{Ë]'P´žk©˜ K<6À-²«¬n¼ÜH$Ì@Q_­Ó¥ 0TéEF+D’²KɺQ£ON4¨ÅF1VI+$»$´Hù«Äß³×ü,‰ŸUfÔ4›xfãE‡V¸·ÝßêvV¶×Å#`†h¡·Ò´wFVÛæOv†Fe)¥|8𗊇üOãoÙèú>¥«išv•¢j2ê0¤VrÞÌ'7[ÛÎ×î¾_•…†ÞÛʧ¥ÑZZ÷R´ÓV¼º†Õf• ˆÏ @ò1¢äòÄðäÕš•$ÛIê€(¬Ÿj:¦á]fÿDÒ?á Ö­l¦žÇHûJÛ}ºuBÑÁç>V=ìïnvO¾uÔ>.x›]ðéwâyu+OøJ?:ÇÃúŸ…¯…½Ö»i ±Ë§ß3KäH‹" Ć9·\E±|‡/@}AE|¿ðׯ2ñ/ÇÏ­ÛÚøaáñôWZ3%ÜípÖ^#†Ö9 ²]0 áØ<²±(¸Ž5T™¯ÅmâÓâ?„.tOø¼g¬kV¢ÒÌj³ 6ÇI·1É©lca ÄÐ¬Ñ ‰¢•ÖçPµQ$cÉ1{]Q@âžø­â˯Œ³xw]M?E°šöîÎ×G½Ñ/íåhã<Ûêäµô³EÎlãXäŠ9eÜå­$Wð ˆß5„^‹Fñ?ö~´ÞøW}u¬jm{}-Ûê´ÐN$Qwüì‘XóFeŠF!£h@>ꢼö”—ÄV„õ Ä—Œ-ðô7ÖÖQ…šýgÖì ò^brå›z*†˜Áq’9½‚€ (¢€ (¢€ (¢€ (®*çãG‚­t¯êOâ w³ðt3\ëo<†Ö(–C,UI‘U ¸Œ´a‡›o<_ë!‘µ¢²toé~ Ôuë ¯´]èw«§êùl¾Dío ÈL~ææÊä|øÎAZ€ (¢€ +'Ã^)Òüa§M¤]}®ÒÛ½=äòÙ1=µÄ–Ó¦òÍ ‹ž‡nA ‚u¨¢Š(¢Š(¢Š(å_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZõ_ø*?ü˜ŸÄßû†éÒÒ¼«ö¥ÿ‘‡özÿ²¹áïýZ—º6‡Ã#ïúò¯ÚÇþMcã'ý‰šÏþÍ^«^UûXÿɬ|dÿ±3YÿÒªŒO€><Ê/tÏû¼9ÿ£l«õR¿*þ<Ê/tÏû¼9ÿ£l«õR¥UÝz>(ñ¯…tKFé”ÔˆãfÁ–L¨8<œz ž€×˜þÏ®~!·ˆt]fæ9uÍ*òCHÌÖ¥ÈS´JUˆPhó’I¨ü]¨7Ä?‹he2øoN8fñòã’9ë·¸À$»Ÿ=ø¯§ðïÅz_Ľ+ö2–úżr¬_j€º€­òÛ³°“¸®" |™Îøß©Sâ¸`éÊøxÞ §£“Ýùê½ßÃâ=àß°r{ŸUQU4V×]Ò¬µ+|û+Èâ v•ߨe8 Gf­×ôDd¤”¢î™äQTEPEPEPEPEPEPÂß¶„:—í=àxfð}ü‰$24RÅ"jO‘Ȥ4r#ªººÊʬ¤ g|hý¡æñGì‹ñKÁ~4¹AâÁáë‘§j¥(µÈÑw7Ê ,whŠÍ$Jº«K %ŠßgöÅÿ“§ð?ý‰š—þ—Yךø—ÃZ_ŒtÝZ²‹PÒï#ò綘pè9‚0 ‚ ~›gõò|âµ4ïJ¢’”}e%̼×ã³è×òîyÄøœƒ>ÄRMºT”ãë)®hÿy|“Z>iתþÌ߯¼ â¿ü4½¨xkZ–[M2éÅm5ɶçïZ­åòÇÞ…‚Æ¡¢t[oðV±yzúî—}7Û.t;ñ§›â¡éM¼¬Œª«íœ+m–BÁP0EÚ²ñÿ‡~|WøaâÏjÖú‡´­búâòú䱯ö&¦Y™Šª¢‚Ì̪ ’ù®ÄbpÕ*4çhͤ×I&®Ÿê¶kïGÈp6+•ñ =)Ú5RKiE«§oškf¶ÓT~ŒêÚµŽ¥^êzí¾¦ÙB÷7W—r¬PÁ)g‘݈ ª ’Ä€$×ç¯ÇOÚ?â_í¡ñQø5û.j¿Ùz&‹‰üIñ&+É-m÷©&8 ¹‰YÖ&tÚ0^r­·$&§ã_ÿÁY|džð´ZÇÃßÙ·Dš5ýNåR;ífè[¬èYIR±‚éË<»˜Áûö{ø5àŸ|Ñ|/ðòÞm?á­Å’Ý-úIya¬j·m"“w,ª!‘7,Jw$YPGj²PÊVÑnmQ ê'RWPM&í{^ö].Ý•ÕìöIµâ_²Oà >xSÇþøEàßø’×FÖ‡üEã-kÅWš.§¬j i“²¤:|ÍPµÓŤÇnÆpK;HþÉâý'ãŠ>^øRÏÃþðÂÜÚ %Öt‰§S‚1€Z9çÐå"B ©”‚ãq`ÁðÃäÚ“ö ¹ðGí/àß‚ÿ5ûWñÏÄ rK6û@ðÐ+g¥´ç[ -¼Ök…Š7?õ’0‹Çü ñ›ã÷íñ²ã·ˆ5¿†^ ñ6‰cwâ;++oËzš†§mf„XÄ®³no1ÑnUÐGoTi ,Òê÷3œïxÂê7ºMßü“vëd}éû|ðïÀŸ xïÂg…môwFñéú¾¢º¹Õ¦ÔØØÚÞBírmmNÔŽøF±ˆUT«°ËHìÖþ5þÔÞ;ð7ÇÛ_…?~ÿÂÍÖ¤ðÊxži?á'ƒIò`7R[0ÄÑl2ÇÈ|Ÿ3îáI¯`øcðÅ~Çâ9$ñ±â­K_ÔÆ«©kbÕfyE­½ª¨[h!TEkÀLç$“šð¯ùÊoýÑŸýÎUUáSöð烾 h?ðÌ?hÿ…köôøOôµþÑò´{­7îàùYûO›Õñ³o9Ü;ÿØóãoŽôx_öwø…ð³þMkÃ?íuuøH`Ô~Ý»Ãb¯åÂ…cÞÂFÁ‘ŠìÆ!«ì ùWþr›ÿtgÿs”õUQ@|‰ûøÄ7ŸüC£ø_]ñE–‹¬Þ›è|=§Iq Ía4q±† _nî c  úîŠæÄáá‹¡<=_†iÅú5frc0´ñØj˜ZßH¸¿I+?ÁŸ—ÿð–xƒþ‰7Å/ü"uþ7Gü%ž ÿ¢MñKÿCÿ×êð_êIü²ÿÀÌâpïòÏÿgåÿü%ž ÿ¢MñKÿCÿ×ñŒø»Ç? üI é¿ ¾'}¾úÑ¢„Mà½AT·|£ŒãúåEtá¸'(ÂW†"”eͤ½î©Ýx?²&ž*ŒeÏNJKÞ{ÅÝ~((¢ŠûÓôࢊ(¯™¾*ÿÉÓÛÿؘ¿ú\õôÍ|ÍñWþNžßþÄÅÿÒç¤ö.4h¢ŠÌô ï…_òt÷ö&7þ—%}3_3|*ÿ“§¸ÿ±1¿ô¹+éšÑlpTø˜QEÌŠ( €?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ€ ù»âÇüxø¿ýË¿ý𾑝›¾,Ç‹ÿÜ»ÿÙ©=Œ1ÁŸ£üÌ/Šÿò?êŸöËÿE%|Wÿ‘ÿTÿ¶_ú)(®u±ó4¿‡D}wñ̾(ø~쥥ÑISÔ§GÅqÿ¶ü?ì‰ÿcšév›]‡ÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmiOc¿'þ½WäÔ:(¢µ=ࢊ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šùþé~6ðo…¼OñÄ“=‡Šl"Ô´¿h°Ë‹ˆ^4”ÄðA¾ëRhÒb“þŽñÏl»KP¢j_m.µ­#Â6xÓ[·•í®Op¶63)*Ëuxw#lß y— ®@â¹_Cmmu¤]üSñGr÷Qßé> ðÜS”yí¥ŽdtŠך„1˜„ª¤mMÃgMÓ|iâ-:ÖÂÂÖ„þ¶‰ ·µ¶ŽÚëVXÐTEK;ER€>Ô7ÿ–8êü#ðû@ð7ÚßG°ò¯/6}³QºšK«ÛÍ›¼¿>æVifتùŽÛW ¸Ps¾Ó5ýG≼a¬h¿ðŽÙêz^›¦Ùé·WQÍz¿fšõäyÄE¢MÆìmË&UAb¬J/¢QEå_ðÖ??è²|?ÿ¢ÇÿŽ×Ì_lß|U½¿ð–•ãÿZxÞG¶Ôf}^Ý$×IW„ù@‚õ¹ ø÷ÏÚ¸ø^èð¿þm¿øºú¼¿"XÊ^ÖµeNû-·}Õ¼2¾7ÙK–rþ½·?á¬~Ñdøÿ…Eÿ¯ž|geð[ñ]Ö©¡~ÑÞ Ð,u+Ùou+ uÍ:ï+ù’µ¤†u1;»JäÊ'PλQUv)ÿ…áðçþ‡ÿ ÿàæÛÿ‹£þ‡ÃŸúü/ÿƒ›oþ.¶Åð^_§ì±Uá8ÞöqOU×âþ•ÖÌñqÏ™ÒöÜ*©Ó´µÕuÛ~ž­›>­øIñwöqø)ðóGð_†>/øLI_iñu”²ÈòHÒË#±—ï<’;P[ ª ï:N­c¯éVZž™{o¨é·°¥Í­å¤«,3Äê$GRC+)0$Aù³ÿ%GþÄŸý=ÿ÷þ”×øøôŸþÐþ,ð—ì‹®i>Ð’ëQø{àÝE_UQÇ5µ­Î©¦é—A*4wR/öCMr¢ Ä“ Ó(ylaQOš2º½­ú½<ÿK3ÞÃbþ°ÜZ³GÝWŠjõM7Å'Ðt½+ûk^“ÆqxcGµÕ5´²ýoªÈ^h­žHb Œ—e nXÜK?ÚT×"ðí–‡àßí_^m=þ–uE…"M"ú; Amfhñ<­q* u”[¤‰––Kr6×ÎçµÑ_ÛþÜvþøYðþ÷ÅwžºÖ¤ø¤xÃ^—[סÒo5¹‚BãKµ²Þ\–¶¸&À¤·PøùUø¦ßS»ððÅ©ËHâFž Ü •8ÎƵGJ”ªF.M&ì·vè¼ØÒ»±áõ=gÇkªi~y!:úLrÀÒ¬’\FÊÇnÑŸ0eL ä‘ð#â?ü-†úv«3îÔáÍÿÿH@2Ü*J¾`oÛž y%¯ÁZp‘, ÚA«söï_Äï¤ønÍ”ßjN¤±© i…E ÌB«û-zô°ÔÝZÒQŠêÎJTjWš§J7lÍñÞ“ð§à>kñÄ·_ð‹Yxf]Væ=Aµ °õ;´^£BŽ~ÑæÏµÄLµ• j¥W·ßü)¨|G—ÇnÞ ƒÄ“}”M-Ÿ‰õ;{yRر‚'µŽá`h”¼‡Ë1”c,¥”™wçÇíý¯ã¯øûÆ^4»þÑñ#xQò- šC§éq›YBÃm!rªÎ¦v_5üÉyU-~øø×ûAøsཔðÞë>!ÔVC§è:L>uÕÆÑíÚ·²!šB¨¦EÉòyWásJxŒGÃJ›Jﯟõÿú,Ç!Ä`'FÅ9«Ùt=>ŠòÿÙ«âf¹ñàþâYéú~µ6¡ªYÜ[ilínŸfÔ.mT#?Ìß,*K2I;T£©ø‘ñ#@øOá ßx’÷ìzm¶ÕÉ4ò±Û0Æ>i%v!UI¾³ÛÓöJ»v¯#åkÊ8e'YÙG‘¿ |áOã9a:}ÂM-Ðûf«qý›iq6å–âG—ìÖóÈe”4ÑÆ²9¸›,LÒnóƒú7ÁÚÀÚõŸ„t}M|5¢>•á»[ë»6š $G}¦Ék2L%Æ×Šé8*òg$²ì'Àþ/|D¾ý¤õQ.¹`ö휶—á{ø¹»=åômÁr9ŽˆÎ ¤½§ö¹†ËÃ_..%H ‹Æd’ÊÁUhºY,Ià9Í|~]ÄÔsLÖ¦ðB-¹wiÅ}Ú¿éÙ~w•qŽ9ÎêåØ]iÓ„¤åÝ©E}Ú¿»ÎËè¯x[Kñ† †¯kö»Hom5ÌdÄö×ÜÀùRË41¶:¸ ‚AÖ¯˜4Û5>!|sð…|¤}«ÁšÍýÝ÷ˆµ8d„ܲX]ÜÄlPã|GìÈÆvÊ2È¡Å>Ÿ¯¬Ãb¨ââçFWIÚþhûœ&6†:¦\ÑM«ù­ÂŠ(®³´(®/â×Ä!ðãÁ·ºœ1Çq¨ùRX$?)uBÛ˜ Qœz‘œŸxÃNñ÷…´ýIiÂõ  ™6:ÅYXz«+‚G0kφ? S<&H$Úìžß×K®è·¢¥ÐÛ¢©k:µ¾…¥]jM¶ xÌ‚8è£$ “€rEq?¾.ZüR³Ö#òþͪéW’Asl¨v,fGòYXçvQpOr·Ê\“Çá©âá”Ò«$ä—t¿¯ÁöaÈÜyºo‹5ÿøE<+¬ëÙº†³ý›e5ïöv“Ÿyuå¡*ò7ÊÛvªäeˆæ¾ ñÿìõñÁŸüScâX4ˆw.ð6³¥jv^ðåÌ’¾¼ëWµ¼”Ë4ªÊ/$Ôö<1[¤^Û*÷ûÖ¼ÃBøå¦ë®¼WËY-Ãé×»ÅĈeó²ÀÔVN0B¶[%VŒN? „«Jy¨Ê£´Wwý~-.  ä›]–u¯…ZuŒþ5Oü<·ðï„î÷D *[£éq$^¬z“3tËÛNLÒ"mb}ÀßáñF¹ð›Oñžƒqâ_ ÙxÅ’µ¶©¢Éa¦¢Ï«i²ØZɧ¼Ó,P$ýžÒá‹F¶ÑrÁ¶/­kÌ5ÏŽZn…ñ_Hðœë‹Kíö¿lEó?Ó D#O”ð¿3)8'y\í Ƽ~ìþ³5y(Çͽ$õØ#+Û¡ó&¿eã‹€^%]cž0ñŠügð3FÐaŠ :{»ÉµX-uC|·nßêeO·DäNÊó1t„M(1×UñÃ@ñ%×ÇÝ7SÑ|NßÄÞÛ¯CáËCQ:Iº²[¹áÖ>бX[aîmåÓãŽGeûDî‚+™eO°*–³«[èZUÖ¡tÛ`·ŒÈØ ŽŠ2@É8w$WeJ£ T¨í¦Ûì–ì”®ì‹|ðÏÂ^^&øWq?í?Ä6ŠûBÀ×7Öͨͬ@úMÒØÅlæerMWiGdÂ$RÁUà_ƒ~"Ô.n®üo§ø¢oXüðö5M?QnM_ËÖ"½{K™$û;j ç[†rcûIùÕ'}þåð{âå¯Å+=b?/ìÚ®•y$6ʇbÆd%•Žweðw+| Ï M4vÐÉ4Ò,QF¥ÞG *¨$“Ð æÂc(cpñÅЕá%tü¿Kuì9EÅò½Ïý”´dÑ?á)ŠÃÂÚ~…¢¿ÙZ+ÝÂ7Þ³ºŸ÷ÂXÆ‘w#0–5òK^(uš8¹6œ}^gðÓãeÄø‹Ãæ´½°e¸µŒ¡ýå¡HÁfl‘¼;œŽ8tÆì1¯L©Àã°ù•âp³æƒÙ„¢àùe¸Q^a®|rÓt/ŠúG„ç\Z_oµûb/™þ˜Z!|§…ù™IÁ;ÊçhV'Óéa1øl?Õ¦¥É'äÖñë³è9AÆ× +Ì>(ürÓ~øƒD³¼]ÖS\ÔnQ|ƶ£“fä0Fn Ùœ+ôú0Øü62¥ZT&¥*o–K³þ´õMt AÅ&úŸ*ÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•ÏèrתÿÁQÿäÄþ&ÿÜ3ÿN–•å_µ/üŒ?³×ý•Ïèr×s݆Gßõå_µüšÇÆOû5Ÿý!š½V¼«ö±ÿ“XøÉÿbf³ÿ¤3UŸ|xÿ”^éŸö+xsÿFÙW鿎fÞÖ.]ƒÃ0ÁjóM¬]Ùăt’¹fPª1-¹p2r1šüÈøñÿ(½Ó?ìVðçþ²¯¿ÿkù5ŒŸö&k?úC5aR”kS•)í$Ó³iÙöjÍz§uÐÞ£³M9}£áº;´_µß„mƒÅ-µ»HS8;RôÐv¦\¿ÃkËymî?kï Ϩc’)8ÍceýŸjߨ{-¼Ó.Î/Áù'''ñ¯ÔšúÜ6–”hQVŒtZ·§«»'/y…ÄøçâΉðÿ\дíVe·]J*K©X¤V¨RMŽÇ†t ØK1sÛTÑÅÐÄN¥:SNPv’]¯gýw[¦7¬ßP¢Š+¬¢Š(¢Š©«i6:þ•{¦jvVúŽ›{ Û]YÝIJÃñ÷‡a–îYKjRµ‰"IïË’&»û¥\«€§n«,|»˜‚€}¿EPÃß¶/ü?ÿìLÔ¿ôºÎ¸Šö/Û3ᾩ¼9ñN1öèº-æ‘«×/b’ÍÉvã¼ äºÈÃý^åvX•âñÚþ`ã|5j£H´¤›O£÷›ßæ¯ÚúŸÆž#a+á³§:°iM6ŸGïIèþjëu}N7ÀŸò4üEÿ°ô_úk°®WNÿ„#ö”“áu—­¯t M¨nkz`”‰’Ö-þõHxÁg†AãЉyr«é¾|&ñ%ߌþ,|C9Ñ4 E¬YhðøoWvC¨Þ.k,­ ¤â)„NžZ*Éç•daT‘aø-o6Ÿà?„þ(ÒšÞÏÅ>Ñí.4­F{a8žÍc• ¢–6du ¤©Ê²:£§N<“…Ì1 •&µi8;Þ=uZõÙ§º~¦ K†±Ø ç4ƒtf¨J2‹×—Ùµ%k>«]Z5}bÿF|#àm.ÓH°±Ò4‹_ ø:ÆH/tM#AŽãIdcºYâü ªÏ)ͳ!BϹŸd(~Õßµw‹þ&|GÙÇöq·|@ºßˆüY¥mü;!fQ2ƒ²UÜ’Œ˜‰Æဋã¯í‡ñ/ã}æð?à‡†uüLñ‘ŸÄÝË²Ûø~ÏyŽI º 7!ÆEÐPÊ®ˆˆ.ŸËƒéŸÙGöQð‡ì•ðá<7á´ûv«u²mg_ž ·œà1;"]Ì#ˆË;;¿ôu ”ëSUiIIKT×SúÞ8ÊxÚp«BW¦Òq³º·uÓ]Û[½OÕ?b‡Ÿÿd•øqoeý·ˆ¼MákOêÓƒ Ʊæk¶1È #nŠ ²:Ç7îø»<”¿ü!û:kzׂ¼§}‡Jµÿ…]$³JC\^Î|]xâwo•¶ŒœUP¨ª¢¤þ5ý¦j}Câ.™àè¾éþð_ÄgÒ­Û\]N+éeÒu {ÈÌM"2±Žä'2ƒVüWðSöÂñ‡‰u nöëà|WwߨbA&°djRê¸ ù¦™–L“”.Ö=}Õ_üwÓ~-|6ý²-þ/x#át_<<~§†. Þ&²Ñ– ÛR{‚KNI8QÆÜ3ïeH¯Fý¾5øããO…|ÿ ×Ãö¾$ðŸŒõ MÿÌs¥œŸeH7:ùÎÎròI‚våBü æ½êöÎBÎ{[„ó ž6ŠDÉ•†Èäpk:œü’öVæ³µö¿Kùwµõ>Bÿ†»øûÿFǦáÖÑÿøš­ð/Š_?m ïŠÞ3økmðÿE·ø~ÞHíüSc­oŸûE.P“nÁ—r™8)Ýýì+gâ±²øYcâ[»f–øát™Ùœnß÷Xœm%F[îà”eÏJ÷?‚Ÿ¿á_x2Ýo£Vñú­Î«r@óS’#$3 ±ƒ°;x$¸×æ\3Ŷw­…ÄácJ4[Rww¿eóëäÎÊÔiÒŠq•îzQ_¨œAEPEPEPEPEP_3|Uÿ“§·ÿ±1ô¹ëéšù›â¯ü=¿ý‰‹ÿ¥ÏIì\>$hÑE™èß ¿äéî?ìLoý.Júf¾F»´ñ¯†þ'øDè/#èÿÙRE­ùä`Ïæ–™¢¾fÿ…«ñ¿þ}þÿßßüUðµ~7ÿÏ¿ÃÿûâûÿЧtO$»LÑ^ ðã޼IñbçÂ.¶ðòFš#j±Ë¢G89¤AI‘Ï«œcÓž¢½æ™ [F|ÿÿ“§ý‹ÿìsoý.Ò«ïúøþ ;ÿ'OûÿØæßú]¥Wßô+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmvËâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµ¥=ŽüŸøRõ_’?P袊Ô÷‚Š( Š( ¹O|RðÇðǮê~Mþ¡¿ìU¼·šþ;oÙ¬àWž,:³ùhÛ,ØPHçþ3ëšÍ­÷ÃÿhºÅLJ_Å~ }*ãW±† .íbM¾½Ýž9" Ïe$n6<˜¶ºôø[á†ÿn“BÓ<›ýCgÛõ[ˉo5ý›¼¯´ÞNÏ<þXvTó¶.p ÊÿÂäñwýŸˆøáïþZÑÿ â7‰ÿÐ4O…º‡„®ßïjþ5Ô4ógn‡å.Ø]\Kq*’BÞB:«ƒqÛ»Õh *ÿ†zÐüWþ•ñ6oøZWíó}—_·FÑíXó‹]7ÚZ@“J&º #F×-TÕ¿fO€Z•{©ê >éÚm”/suywáÍ>(`‰³ÈîÑ€ªª ,HM{|ñûmëáï…<$²IŸãÁáÝBky J¶ímss´ŒŽö±Ç,l’&å.@>vÐ< à_]xÅøàÙôýRñÛL·»ðÅŒJš}³´vé–0‘5ÃG4îÏ œ±žZÛC)ô‡¿¼+ðÄú¶^µøu¢ÝßM¢ø§AÒ4ϲévrȪöZ£ùAã‹k…´i1ž·K+·—fª–¼ý«oá}[ /M6×€M>ûÇííÎß .!o9ÒˆKÏ–>cœŠ¿¦‰5d²ºð†¡â=#Z°›GÕÒx![«Y•ã{mí2:¯'̸Æþ ãÎÉÛòoòÜôpÔIÁM&ßǾڹ]G]®®×ÉŸ\èZþ—â* OFÔ­5m6}ÞUåŒë42mb­µÔpÀƒƒÁv¬?‡ÿ <)ð·N6~Ñ¡ÓQ¢Š ',ó\Í@¬)$ò’ENÄÄ"aW )ð£Sð×Ä?é·4ðŽ¨¿ÅÜÚç‹4ýhnïn,î^ÂK£§)[Bïnáãó•cÐ4l’OañŠt­7Åšœþ>Ó¼9«¼ˆSB¼šÛ:œrH/–ø˜±ÚëDê7Ÿ˜HaÎ5½Öåo¿ôv·¥ÎÊÙoï# *Z¦õÕ—iC›tæQK«¶¶íh®gÄÚ߉tkøäÓ|3¿¤,`Íö]IbÔ „‘¶(%E…”|„³Ü!ÆüT¡§üVÓd¿¶Óõm/\ðÖ£4‹ ‹UÓ%é##Cy{BÎJ 1%Sï•««ìݽtüv8¡€ÄT§í)Ç™ohµ&—wÜ’ói-»£µ®+ão¾üñ÷‹ôÈ­çÔ´ê­¬WjÍ Ë´’¢¸VRT²@ ã8#­vµâ_¶uüö³§ˆíá“d:­Þ—¢^.ólïu+kK¨²~îø'•7 2îÊ•`è§Rj vìy²|©¶|»á_ÛxCÃ>…fòËi¥ÙÃe ÎA‘’4¥ˆ…À=…jT×ÖÚe•ÅååÄV––ñ´Ó\Ná#‰e™˜ð’O ä?°ÿáe¤ø‡OÿŠg­¦…ü}z\]ÄÃñŽ' óv¤ЪiB ^ˆøD¹½é~ñLJ|Ðþ/iß4-Kľ Ð"ÔïF™¤è—éoö­*käö²3ž¸Õ¥O+Ý,âußy¿Ãô][Çšd_-•ˆìñuÙçÚ[]ÍÏSº{™ß’q¿ rý•5H´ÚÅ:tÊí?ˆ¼1iqhÑ€UN»™gd‚ ZÛfÎÉs· »ãø‚—>Uü~‹ù\õ°2¶)ÿyÁ=Ó\ø¤ê×ÚÆ§k¬ë.»}âüMo«Xµ»M§^®›˜L 42DÊÖ±ºš99šF]¬#)Uÿg]=;B†Ë\ñ•§h-Ư§Ý¤7šŒz…ÂÝjQÊâ8üeŸãÃíÅ~5ÑüA k·÷V76–¾[)Í:òåH&~n¼cO5÷{~c…Í(}g >h^׳[y4™ô^kƒÎp뀟=6Ú½šÕo¤’ùWû.Zxâ‡ÀŸ øŸâ?íñÂ^3¾ûWÛôoøZpY}ŸeÔ±Åû™÷H»¢Hßæ';²8"½ö_ÔltÛ—Pð„>9ø£ã/‚[áÌš¬’ë~.]v5©ÅPcÄjËCŒnSÎ ù¯þ Åð¯Â¾-ø/.»¯øÂú®¥‹n4í/\ñ-”Wš}ä²[YĦü<.m–f1ýšíw”1ûÁm}é_±„ô?ÿÁN¾,è>ѵh¶> X­ô}RÕ-î,~m(´“cQ8i<à¢_:s''¤zÇéý~vCq.·ã_k—ò½æ¯sâbÆK¹˜³ýžÓRº¶µ„gîÇQ¨T.ØÜîÍú'_š’øŸJðµÿŠ$Õo¢²[ßëú}°üÓ\K®^$q¨’IíÐc€¤Ê¼GŒç•R4ÛuÓ¯»'o½'ò?Bà‡æ5%7d Þ½=è«þ%/‰RÿÂC¢êž ±µþÓÔõ}>Xg„\ý™-m¥VŒË,Þ\ž^~uŒyn]”áJ¤Œ=ìÚž£®kš‹ëž'ÕYdÔuYSa”®vGdˆ Œ1Ä $³³»sOü–ÿØ¿¤éN¥]­>W­R…ƒƒ´,Ÿ›qO_Ké÷¾–ýš(U¨ñ3^ò¼W’M¯ÆßåÖÿFþÄßòovö0xÿO—Õæÿ¶Çïþ-ü'‚OÞC‘¯Ý$mʬË.—Èg 4ȨY\tcŸHý‰¿äÞì?ì`ñþŸ/«Íÿm?ù,_ ÿìâý(Ñëú:ÿ’f§ý{_’?‹|Aÿ‘6cé/ý(ñëÛÛ}6Î{»¹âµ´·¥šyÜ$q¢Œ³3IéŠæôiµÏhî‰:Ë¥x]Õ¿¶îôÙ˜‹­ZO³[Û$w1”_&Ø-¢IäÍ!p%ØByxßKñÇÁ¿‰òi/,Öú~™}f×›cœ›0’"~üefM¯Ñº®T«R¯ç:u1e)J Âs¼_F•£/Æë}­Üþ.£W“Q”é· •/ºj6„¾÷u¾ÖÓ]V§Ã?ù8¯ƒ_ö½ÿÓ§_ •ù÷ðÏþN+à×ý‡¯ôÇ©×eû?ÿÁA¼OñŸÇ_ 4­Wàçü"~øý«ýâøJ"½ó>Áqþް+Œr™Ý¸n¿àùGüR?¨¼0ÿ’v?ã—æ}¥Eðíÿñ?ÀïüPðw‡¾y¿ðýH‹Æ_Ûq²_êsÜÚÉö7·mû<¹ŽÒÅO‘†+¼ ýýdö_Œ~*×µÈx_ñ&—bZÙ`þÏmåpvݱƒå€ä ¬¡sP~Érø—ÂZ¾±á½WÃæ“¡ß;^YMc*¬2€#Éå(%/ÌÅW1` ¾+Ò¿áMø»þ‹·Äüð÷ÿ*«Šøßá|5ø/ãïéŸ|q>¥ xPÕmb»Óü>м°[I*+…ÒÔ•,€8Îë_„á:xLÖy¼kÉÔ›¼¯³Zém¬“²ÓM;R®ågm—öˆñ³oei£éÖµŸ0}¢c¦ØË,mÔ"4Š IS’>BxŸÃûßx_ãM§‰í~x‡DÒ/lõ+Q§Í*ˆ›hinàªH@™‘¾ož½Gῇ|mñCIÖõëŒ^0Ñ?â¦×ôøtí.ÇDû=¼š½Ý¤(†m:I"2]Ø““žk«ÿ…7âïú.ß?ðÃßüª¥Šá*x¬ÛûgÛÉUV·d•´¶ÖÓ[÷}Â5Ú§ìí¡Ó|Tñ ÷‡<w6›a¨j7óÿ£Ã›k$ò¡`Il'+€ b¹ë_x–ËÆ:•Æ‹{¥|8ñ™¬é_h‡S:|’pÁ“|fªUHŠŒ·vk½ø1©üDø¯ãOxPø»â2ßÃPËw:nŸ¢‰¯Xx‹Ä"IüÍ=×pƒMµ\F±®UŽÜ±¯`ÿ…7âïú.ß?ðÃßüª­3¾¥ãiãjÖ”]5h¥²îý_ŸeØTëºqqKs¨o]?Ãtñ"躄ZƒÚ«ÿd›9¤¸Šv˜Ì{UØ+žHQ•‡¯¼u§ø£ÆDöðÛÄÏ|nEÌz´ÖSy½>eeò› å‰ÃŒ¤ç®çÄšŸÄMãöðÊ‹¾(ŸMÕfÒ%mZm?Eût 5‰¦–8Êéâ-¬úM™ËÄÌ6¸ 7öøS~.ÿ¢íñÿ|=ÿʪ3ΧŸÔ£SZKÙ-Ñ_¬¾zi°R®é&¢·:O„ž%Õ|Uà.ï^Óï4Ír4ò/a¾¶x¥N YaÆåFâ¹Êšâÿhë6öVš>‘áýkYóÚ&:mŒ²ÆÝB#H ¨•9#ä V~­¤øÃá¯ÄŸ…‘ÉñOÅ*Óuÿ\iWún·e¤,/Ò5¥`ÖÖȬ%µˆä>1AÍe|ð‡>%|ð‹õ?Ž>8ƒR×ü?§ê·QZiþXRYí£•ÕilB†r$œc$õ¯o1Êže–¼º­V¹’R’Ý¥¿þ׿g òO#Î>Þø«ÂÿmiTDÛCHƒwRB,Ìó|õôGÇOjZG…RËKÒ5mVâýŠH4«)'e‰q¸œ)lópT8ªð¦ü]ÿEÛâþø{ÿ•Uãÿ³.§ñöƒð]Lj5‹¾(Ю ‡Dˆ[hš~а»OáÝ*úiŸ§ÊÛž{ÉÛ‚€@UWƒáˆàrª¹E*òäšµú¤ôi7}ÖžZ½Í%[šj£ZœdRxÓMñ÷†üW¤ü2ñ›}¥…K”[9\^/!òLVdgBÇv\ch¯²üEâGÒ¼#s¬ÙÙ^^Éä,[Ge+ÌÌø ºƒa€@ 1\?ü)¿Ñvøÿ€>ÿåUxÿ†õ?ˆšÿÇícá”ß|Q›¥M«Êº´:~‹öéÖ ÍrÓÌ[UõkÔ‰Xî@Xí¶IÑȰ•0xZÒå–×ÕÅÚ×W¿–ýªVö²R’8oiþ(ñ†‘=£ü6ñ3ß‘s­5”ÞoO™Y|¦È9bpã$)9Æ+ëO†¾3Õ5†º¾¿¤êvšÕ¥»-õœ¶R%IJF¼²FQw  e¶‚JšÄÿ…7âïú.ß?ðÃßüª¯¿kÍsâ/Á%tÍ7âï‹54Ö4vŸí¶ú\Ù˽ Z‰ ’ÖÊ ‡P¹RrÃŽ+.á*y YG ZMTѧ®½¯u®›j̱x·ì¥RKáMýÈŸâÇŠ9ÁEüuâÿÙUñÿÀ_ì_xúÊÿÈÿá1‚|O470öan%ùL3˜(>_Þ4bcüxÿ”^éŸö+xsÿFÙWßÿµüšÇÆOû5Ÿý!š¾øñÿ(½Ó?ìVðçþ²®[þ _ûJxŸã‡Â½sBÿ…oý‹àÏ|LŸÃÿð–ÿnÅqö»ûH.“Éû'–²&ø¤ówe”cnI5(Ú®ëÐøgÂpgÃö°ýšäùÛî>Ì’|÷´Z7ðO0Sø”Z×ÿ¯ú}ûWúWúîþÝ·þ^íçÒŃYƒ>µ‡ì×'Îßqöd“ç¸Øä}¢Ñ¿‚xñ‚ŸÄ zÖ¿ü}Óïڿҿпwöí¿ò÷kÿ<î“øãþ,è[4þ'ý_×Ëôþ“?ÚuS}§íždú;ý§Ëòüܶ wíþõÇl×ꥨÛiuÕýäËoikÏ4­ÑAfcì&¿ÿàŸž<ø‹áïÚ·ì? dð¾¡âÏÙßi‰wâønVÅ¢_ôÉ$+nC£h1Ávî?O~ü{ñßíð à‰%×áÖ¼uâmCOÕn|-gm‚Þ×X‘%½K•]ÍabC½‚ ñ„®Óåßúþ·=(ìŽ?âÇÄï øðëßl7sjS¸–ÊkdW†R@V;“pØnŒ1l}3û5üMÿ…‘ðÞ×ísùºÖ—‹+ÝïºGÀýܧ,Ìw®2ÍŒºÉNÿ…7âïú.ß?ðÃßüª®VÒ|að×âOÂÈäø§âiºÿˆ.4«ý7[²ÒˆiÒ°kkdVÚÄrÈ æ¿?áþ«‘bªâ^-Ôö—rN6»zÞüÎÚë·WÜë«]UŠ\¶±·ûLþÐÿ³_ÃËO]èw ´“W³Óf´´b™Ry64‰¼mfQ’Š8Ôr;ßøãBø•á=7ÄÞÔ¡Õô=F?6Úî€À¬¬¬#«VF‘••€e ~Bü@ý´~(þÑþð~ãÝ#ÁÖº¶4ïØÚé'-xiÞ\Þtμ´S¶ÕƒÜ>eßð?â7ÄÙŸM¹Ót–Ó|Yáfº–çû Q–X2À’Ö÷ ®mw;$CÈÌ>QÉ$öuñØl-ZtkÔQ”ïÊ›µíkÛÏU¡áâs,µ<>&ª„ê_•7kÚ×·Kê´Ýô?J(¯4¯ÛóàÓXE'‰uûêÚo‰í  û²ÇæA7Xù2¾Ðêk¢ßü7×ìúÜCñGG»”ð–ö‹4óJÝ•#D,ìzPI$ 5ÜzGÐãP|yð—ÄŸº¯Á«}.?Y PŸY¾œ$º{<3Û[M§ì`DçdKüTÆw¸•bùóâ?í‹ã¯ŠV·Z_ý_h3¡üC¬¨mZT!rmíÕ¼»fÃ6×™ÔŽ`R3_,xÆ_> þÐ^5»ø]iá'—ÁŸ/õ‹äñBÝȳY íî.vœ4—-"! ìn»d渣ÃOð‘¨D›qNí%ewÛu¾ý:žtsñO ±uRrqNí$Ò»KmZÞ×é³?^|Gá=Æki¯hÚ~·h¾fØ5T¸AæC$a\óC4Ñ·ªJêxbÁ~ý«¼¢i^$°ðgì«oo¡j’O¥ê‹¢®•mk©¬/,“G„2&Lª‹ÑÛŒ1Éñ[þ 1â¨< ð‚ãᎣðßÄ>,×ü%©x‹Åv3ËtºT¶ZdwÒÀ#·¸ß ·h©.IdPYv³Wš| ÿ‘3Pÿ°þ¯ÿ¥ó×ièŸNü7ý¸4¯ì>ø§áV©¢ÂKͦÍNæÊúÖP-e™á¸\ü RŒÙÊ‚0ÙÛñ¾æÇá¯ÂxûLÐtyüC iš‡‰íe»³V¨A§ILåv¹c   åeÅ~_k?õOƒ´î“ã#Ã_ð—]ø}¯5Ò>Þ¶^lèwm;ù̬—™&6’Þ^Ð2¾‚ý§¿à :OŒ?gí'þ Ñtë¿< ¬\k~›â›v›ÂʺXžq:ˆÉvŽ9.Æò™³(Žö¡ûGüu¼û7“â_ØyS,¯ö Ý9FsoÔ[ {•ÚÜp¾–ýšþ2Ü|køpÚŽ«ko§øŸI¾›GÖììÖAwQí`ñyƒ>\°Éê2ûp…Ù‘|{\Ĉ>;ø¥xâ÷‡^—H“OÔ㸀ÍAéyåïTií¶¹¤YY¥c_„p·c1õ…Í*óFzEÚ*Òé²Z=ºëo3ùŸ‚ü@Çâ³5ƒÎksB¦‘|±,º_•-%·]m²¹õíƒÿðïìéªÿÂá}2ãÇ_õQ4íÂ#46·²-ºÝl`åœ>ô‚0dp,JŽ|Jøñöqø; ëÿõÝí5ØßXÙÅ ±ðãɺHà_,ˆ¦T6á *Û;CÛ£KÐ_²ì]áßÙ§J}_Z—LñïÇ].5{¿ë™® ••me‘XâÝq²Y™$3nq†H“ ý¶¼9•û+üuÔÅö£u.©¢´ÕÛÉol±Ä‘„‚"vħ í–g$’…ýS?Ëðùž¥ñ½“iõ‹I´×ŸèõÐý߈òlo”×§ÒŒ¥ o̶iô¶ºÙ§g®ß'ü)ñGˆ<#㯊é7Ó\iú…ùÒ¯ôK»ÉVÊH¦Òôñö˜ãT¹‡Ú|ÄÝcrIO‚ÿòG| ÿ`ý'JÒð‚4¿®©’’Ão¨]‹Æ·wÝC"8û‘……6§Eè¸Pª3~ ÿÉð'ý€l?ô+ùŸž3 ìÜœ¡OÙÆ7Vvå’kï]ݽãLË5­˜`#FU©ÑöQ…÷K’W]t½ÚWv¾ŽÇa§kWÞñßµ½"åì5AâM'J7u{KÍFÖÞꇎHß•`@dŽA‡Ž6_ѪüØ¿ÿç‚?ìsðßþžlëôž¿jðêr–Q5'tª4¼—,^Ÿ6ß«?¡<'œç‘TŒ›iU’^K–˲»oÕ¶|«ûÿÍÆÿÙfñþÛ×ÕUð®ð÷ö”ý›|Iñ&oê_…|cã]SÅòx•u‰®£k—R±¹·ˆ"‘iòóÎü3Åïø[ÿµý¿gÿüñÿ_s‰ÎrÌGGЧ ®’œSû›¹ûb§9+Æ-—ì ÿ7ÿe›Äûo_UWÍß°·Ãoxá÷Ž5_ê¾Ö5OxÏRñY¸ð¬—b¿hXUÑ<ôGeŠQƒ»oÌNkéõ)Ô…X*”Úqjé­SOfŸTÈjÚ3’ñÃ}7Æ^!ðέyĺ%à»T 8ª·– Ù!W‘Ãî:ÚøÿöK°ñ~¹á¯ƒþ#ƒKø§}§Eµ¾ñ6»ãVÃ[‚]5¸µ¶mB墕îÞÖuccŠU,›ŒRíñ×áe¶½§Ùxûà ´/ˆ¢ê{uyxóA|óXÅ$“31l†Û©žW/É—1åK FŒçRœRsw“îì—ä6Ý“>À¢¼ÿâߌuÏËàíÃo§Úk^*Ö›H·ÔuKW»·²ÙcwzÒ=ºKK¹lš ¢Xðe– ±¾ðÏÇxÂ÷ ñ Ÿö½þ•¢üL×®ìWY¹•7éšüK¤r°Th•Ä’Éo½ ZD~‘`Q_?ë_¼qà)üOá­noë¾$´ÿ„oì:ÆŸ¦OcgöΩ.™›h÷3<Ÿgx ͶtóUÄcÊ+æ7ÿ|uðöYkWV÷!¿ø‡-ïltG]´±‰|1i}æÁ¦@Âá–_"F6ñɈ^îG2Ì"f”ëZ+Šø7ã-[Çßôýg\Ò®4JI®­ž+>ãOiÖ™aŽäZÜ, :F³¬RndYUK>77k@Q@Q@Q@|ÍñWþNžßþÄÅÿÒ篦kæoŠ¿òtöÿö&/þ—='±pø‘£EVg QEQEg|*ÿ“§¸ÿ±1¿ô¹+éšù›áWü=Çý‰ÿ¥É_LÖ‹c‚§ÄÏ€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ™˜WÍß?ãÇÅÿî]ÿìÕô|Ýñcþ<|_þåßþÍIìaˆþ ýä~a|Wÿ‘ÿTÿ¶_ú)(£â¿üú§ý²ÿÑIEs­™¥ü8ú#뿈ŽeñGÃ÷e(Í.ŠJž£ý:>+ý°äéÿdOûÓÿK´Úì>"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.ÓkJ{ù?ð¥ê¿$~¡ÑE©ïQ@Q@Uñ“þJ/ÀŸûîõÖkÕkÏþ-ø;\ñ¾Ö¼6š}Þµá]iµ{};Tº{K{Ýö7vMÜ$R´[Võ¥ "“& ˜PûÔð·Æ½]×m|9«Úê ñ}Îï³øwı¤[TÈße•íï6Æ¿Ùe—Ê¢_-ŽÐèWã__iz¬^ð®“oâ_K»6W­giejY”Owp±JaWdt‰V7y][jìŠy!ÉÒ~'ø‹EÕl´ïˆ~·ð¸¿™-í5½VžÓHÁ!¶–gŠÞhg‘ò«¾ 3B‹3K*E@—_4þÕè¾4Ðç›÷P^x/Äš=´¯ò¬÷Ó\èòCj„ðÓIµÃ¬cæe‚RÄ}-^%ûYxnïè^+ºØÖ>ÖSÄ·‹"±Xí–ÚâÚk“µƒ0µŽéï<µËMöO%Fey§…ïu¦ÐÓç];T´y!ª[™ŒhÓ3bDWs¨bµ€W¨9~9š;íNMcûgZ·Òt+o´Ko¡Çk,×r’<¨-„±>û™¤h¡Ž2À<Œˆ'œ&¤¯kü­úþ§«‡• 8:Š ×O›Úk¶¯–ûì¹l´w[^çŸÚCGðWÄoŠZ‰¼YðÓFº“Å–ãT]SÇqÃ<‘¦[Íä£Ûþÿiƒ1âe–#/{z®­û^|8‡]³‹Lø™ð¦ïFmŸj»»ñí´eˆ}¬n¯…Á‘2IhàÝ=~hú^“㯉0i>1¸Yu¦êͽ®›ªOq}qwªI vÏ{§]]ª˜ 6Ò# *ÃÖ|Iñ.™à½VîòyüKk©[Ãquoh/ïn¡Ò Ï2êZ RKq§Îñ¢Ä“B¢²;Gr L¤¢ï-­»WùÙ=úw=9P£:´ù)]IJܱ©ÊÚꜧù~ÓÑG[¦µ1~%üqø#âv ¿í¯1Ùl±}»ÄÞ0±Žâ<3Ÿ-GÙçùrñË7Ê:˜ü'ñ'ÀžÕì5}?PøMá"3æÌ4‰”ˇœÙÇm´Ï°ä4ƒ'j|à*•¹ñ—–ºü·Éàïê÷ºLw—²ÜøÿTg‡£c©”Ôo›Í˜Üir‘!ŠØùb£6²Z¼Ó|W¦xpé‰âÝ/áÌZ3^j/ ¤k3xfÙ’üAwróê^\Úq1H±ÆÐ° Xm 9µÂ¥):­Å~ ói~lõ°˜ÚÀ*u§£MY΢î¾N¥×“§üÎâÆß€¶Ÿ¼ã9~ xfù¥»Ž©é^0Ȳ(0ª:¬oÑ‹‘$Š.mÒ@ò—Žb[Î?l_Ú_Â~'ñÏ„¼?ኖþ)°’ò=NïF°¹Ó¯t“¶)RæE"HïÈ“˜¥rªÆ9ƒ)…U¾¨ñ¥­Ý¶¯Ö¯áäÓỼcuâ ˆ[DY$¿êšƒCªFeÓåkdÄ ´J¬£Ê]ëoá´†˜§ö€ðd©n!ú¸óÚ^Ÿ´êï&§‘<³ùòâÞeûQµˆ„ò‘nóE©€ÀUÄbãJŒ¹\¦Õô¶÷J×Û¾¾Göþ:51tÝUJœ ã+I=}ÞW.n]í~[ÇdšV>iÕ|WªøçWÑ4-nÕ?±îµhÄWÚ,§s”I\&èætYÕ”üÅ¢XÚDÛ"Ç,{z'ŒuŸˆ6úçƒlä»3ØÜ3RñD,‘µ¬m– cmŸnPXDLq´‰) sl¾¥­h¶~!Ó&°¿‡Ï¶—i 3#++GGRX++© ¬¡SXØÛi–VövvñZZ[ưÃoŽ$Q…UQÀ+öŒU‹Ã^5±R¨›Ý¤¿—m»;ÞÍ¥müÿ8ΰES €… ,Ôe6¯f¹­t“Õ6’³qNÚÉJŽ’âÊËL³¶ÐæÓm3 [ #³DE*Ž@&à3¶§·Ôn&û&ý.î;™æ4'ìøé¿l‡;»lÝE{Ñ¥(Ùs½?Ãååäþ÷n–ùÉb)Êÿ¹Š½úËKó{¥Õ¯ü±½ýîo;ðäÚœ_|GZZ[Á6¦]ÞEÓ2¬í-ü~j, ’˜í!bA– +¼ðÄ;/…_~ø›Å:Žá­:ù5/êÚò¥¥´SAöµ>lžXVitè;qó²lbêéÈë¸øÃáäýÜhú­¢Jü+NÒØÈ±йH&p½JÄçS_Þ_iè¾—¨ÛèzŽ™â *å5›¸ÙáÓ¢ûl)s<ÛdŒùÙîß¼@aiU™U˜×ÏæiTÀb)9·ËwÓ]§ÑW~V¦«ÂJŒUüå¥ù—Ytºßùc{ûÜØ¾)ñ§ü'ÿµŽõÛêvº6¾óÃúÏöŸÉöÔLâ%ò¤7 µƒ›£ºƒ}›Îµ¶vï?eË7—ýÝ™ŒoÏ|íǽIñ#ö¸ø®¿cÔ,se¥·•©Ý}¦VÌ·çÌWó$ÄOñ¦á²6DÙß-l×ùéÆ,ûš¿Áÿ¤GúùËþ"â¨ÿ¬Øµõx}o>´ÿÇm9•´ÿ—p½ï>zþñ~—࿌ÿõÏjš_†4«]jðÜ_Þß,v°»i‚FYB*†ßŒœ|ÛT»#êí;ö¼øq'öGÛþ&|)¶ó<ïí/³øöÚo³c>W“˜ÓÎÝÆíÞVÎÛëåê_Øÿ~ßÿjéúÙuNíMYwYÙíÐ5Vó§dy‰1¹‡˜Ÿ(?2õbêú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_迯ð¾M´÷¥ù£÷¯ 1ªpúq£ÞsÙÏK·ÞOk¤¯†7»ææüŒýо7Ýü&ø{©éZÁßøþkZ¹´}KOÒÍÕŸˆ#kit;ËPŽ’a!–Tq#IÍ,‚7ˆÏÇ¥~Å¿ôÿ‚„|Iñ‹õð ׇäÒeƒâ&µ7vF²‹ìïq*¡štke@²þô¢»É#ÈŒdÓÿ‚_ÃöÏ€Zþ›ö=CRþÒñ5Âÿa\Ýùzç‘ki?—§Üy‹ö=^ÛgÚb|Ãæ¨ûÿèÿh°Öøâ?µÁOþ/k¿ð•k}‹Á’Kÿ mì_Ùöº•g`ž~¯içÛîòvùWa1p y6Þ_î?CQÌÿ//êïÊß«:Ðwµ(­ÿ›ÏûÝ.­þ{ûÜß]øãöÐÓ´mD·ð´žñÇ‹5Xf•tßø•¯`7ÉW&d·ÚÖáãa+·–Tˆ%vEoŽ>*hþðÕߊµ9“Rñο¦ß_ßI,Vpy’ëÓÏ䤲-½¤nøf%6Õy¤vS%uŸ®%Õ¾èõì¯w­köVúÆ©}3–îîhQ䕨òI8tUUUU@‹âþ³¨øsÂVZ¶ \jöþ‰ug ‘‰I“UµhÔ¡’0À°DÏMë÷‡óVcĘŒã9¡†¬ùhƤSWÝs$ÛjÝ?ϲ_·árZ~[WF Ô”$ÖýSi+·ÞÛì–îí¶Æ=+Føµâ)cñÆ…âÙ¥ðÞ™6¡s¡_Cq§ØOΣæÚE*à°…í&´»ÊIJ$I{ÅŸü7àØ´Ã¨j–ÿhÕ&ŠßO·I©%Ï”³X©lŒ‘¬ê9®ÆÓm3êñ­ó?Ú%Ä3#Ì¶ëµ QùÑð †.>ºø×<Å`ëdÐ|°Q[^ûiç§©üâgâ¨c§•РÒm¶îÜ“×Ýåµ›R[«¥tÕÓò”‡Á¯ƒÿh3âíRÐërXêϤxNòþÂ'‚æ/ÛmÉ$bŠ7Xää|ºÄÐzLóËömúuÌ>víûÚ#äc¦ü9ÎîÛw{â¼sâ ½ö·àOŽVÚ‹ÍịBßETÛ_aÙq1ÏïJ*'–¤FÜÿ3l1ûwÁ=*Çã|þ1½Öä±Ñ¼/áYÌ7–ZÃÄÁU¬ Ü7ú½³Ë Ǧq´À¯æNÙI|˜¢¸Fá©|GO€ÀÁGÙÇßoK^®÷Mô¶ïmm·“_O‹éeùfY„§N ÎWšåæ§Nò^ýånh¨§ÌÛ„.ù\ïðão€Óý£ìÿ¦}ƒÍ¸Õ>Ù{¨'ö]‚ý«ËÔ.ò[KöGØÃ-ó è›%òÿ3¿h½/Ä^ ƒãÿ‡~ ¾añûâ.¬Ýiú]ÈhfYmu©Þ{ef.`ÅÜnùM¾Ö8¯YE­ÝþïëþÐú •a4Ôi¨úswzjßt»Ú+­Ûý=Ó¿à›³•ïöGð'VÓþÝçyÿhñ%ÁþÏÙ¾vÍE³æ•æc?>Ê4ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì£Nÿ‚mþÎW¿ÙwÀ[Oûwçý£Ä—û?fvùÛ5Ï™ü>W™Œüû+Ö>5þØZ'Å3áìö¿ßZÔ>ÉåOzÁ·_´AªN›˜¸nFº yx±X§ ÆoÕ¿ÿår…üÏðòòþ®ü¬:Ðwµ(­ÿ›ÏûÝ.­þ{ûÜØ:wüoör½þÈó¾êÚÛ¼ï?í$¸?Ùû3·ÎÙ¨¶|Ïáò¼ÌgçÙFÿÛýœ¯²<ï:¶Ÿöï;ÏûG‰.ö~Ìíó¶j-Ÿ3ø|¯3ùöS|Mã_ÛCºׄô˸¾Éqâ]Mô«6…u¢±Ê¶W7…¤% åÚH2;™0IÃßþÚ¼á¯é‘|ƒM×ôËmVÖ+µÖ–dŠx–TW ÌpŒçõ¡Eÿ3ü<¼¿«¿+´íJ+æóþ÷K«…^þ÷3´ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì­ïøÍïú·ÿü®WŸüø×ûa|tðÔúÞƒkð>ÒÒ±nMF=aý§M³Ô#ÀGqÄ7Ыsë0¢ÿ™þ^_Õß•‡Zö¥¿óyÿ{¥Õ¿Â¯{›¢Ó¿à›³•ïöGð'VÓþÝçyÿhñ%ÁþÏÙ¾vÍE³æ•æc?>Ê4ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚă¾DçÍÕ-ÛýÔç!Uª4å&¢›oåååý_ÒÑSJ1”åN)küÚ|_Þéuÿ€«ßÞæÐñ·ì7û-ü9ðHñWˆþkšn—r½à> ¸–K"$I QmÍ3²ªyeÀ, †0 ÿÁD~ ü'ømàÏ‚þ'øWàCÁV~,VšâßT¹¹–y’µ9Y¦”*‘#º”8e‘O—4r.h/â±¹¾ÝòbC#1RW!ÁU'nÒÄ·›þÚ^9ø§ñ¿ÁžÔúÛÌhüè%Ô5HäMÈC.U˜eH#<k«øñçÀ¿~6~Ãð¦¹ý«­x7Ã:¦Ÿ®Û}’x~Ç?ö QìÝ"*ÉóA(Ê/\Ÿ®ÿjï øWöøájö÷ÿü ã”ñ4Ú%ݕϓÅu¨My6ª:“4T“vô âÎcïÝ;þ ·û9^ÿdyßum?íÞwŸö\ìý™ÛçlÔ[>gðù^f3óì¯Êߊ~Óü%àÚCÒt¹´=+Lø©¥YZi—‰d³†8¼B‰ 8wÜȪ¶÷ÉÜÝOÞ-ýµ¿jüƒâÕî•ð~_Mae¨­­½¾ªowMÆ ™‚neÜ7à`àž3ðgÇ mì4ŸŽš?ŠõüEÕ~)Åw{£èÑ]y*mWWK©ãy#Ø 3^¢Æ­!”…bÊÄS]ntUš–ÐQô¿wݾöôK­Ûæ4ƒZ.©¡éײÝ_¬·6ÑÌá$@ ²‚q”éÍ_ÿ… ÿÏÞ£ÿcÿâ+‚ÐÆ«w¤ÛM‰5;[xW7!´UfC20Fn àðjÿØ5èããÅZŠù?¼ºòe’]¶çî\ŇýìGøˆÁ^à×J·cÃ’©wûÃèø'~…oá¯ø(§Ãý6Õä’?´6´Ä9Ò.Xç¤ö¯ªaoØoàÅÿÙᯊ<]ðÆïÄšî¹ý¥ý¡®C¬ÜÛÓ{q^dkwù‘•r¹lgqøÃþ ñã /Á_·u¿ø—OÓ´Ë7Ô’ë[Õ/Ò+a:ê4&if*ªIç*Q__~Åþ5ý¦|+û4|Ó<Ây<'â]ORÒ´Fñêfú9UµÉšäÂÁæÒà)@OÍ#–#k±êR|©s+éçÛ}-¶ëÏ{­ ´ïø&ßìå{ý‘ç| Õ´ÿ·yÞÚgðù^f3óì­ïøÍïú·ÿü®W?âoþÚÖ¼'¦]ÅðKêo¥Y´+­ŽU²¹¼-!,_.ÒA ÜÈ1‚HÍEÿ3ü<¼¿«¿+uºÐwµ(­ÿ›ÏûÝ.­þ{ûÜß™^ÿ_Á/û-ÿõ9º¯¹ëà?x§Kñ|0°°ºûEÞ‡á›]?PËeò'o=ÈL~êæÊä|øÎAïÊüOÄÏùƒÿ¸ŸûaüËãüÀÜ_ýÆ@Ö6ÎÅšÞ&brIA“IýŸkÿ>Ðÿß±V(¯Ç;••YàOüÏÀVcв¯;‰ÿ˜Š¡*€ªx¾‡ÿ%Ûö—ÿ²­ÿè0W´×€¿‹4? |vý¡¿¶õ?FþÒø/«i¶?ÚIÚ®¤X|»x·‘¾VÚv¢åŽúG‡M¼Þ«óíÿéP?\ð¹gµ›ßÙKÿK¦t_>øWÁß ¿f O@ðΡêZßÁÿ\ê—šm„Vó_Ëÿ’·™;¢ƒ+n’C¹‰9v=Íoü ÿ‘3Pÿ°þ¯ÿ¥óךüSø“âÛχ߳¼<ð5¿Ãßi¿ +ȧÊøˆEÂZîùmy)}×M-ãÆø7þ(x4¿Þü°Û[­®|~íä1&mýÛ„DË/IL‰€$H{;ëSÃÚíÿ‡üAaý“â-;oڬĞb26ï.x$Âù°Iµ¶I÷]RHä Ñ|£|AøÉð§Ãþ °MKH½Öïh™F‹©2::ÑÈŽªé"Èʬ¤2‚?À嵪ãÿ²1 ’RvwÝI'gç¿£ON.å¹F"¶h²,Rörœ¹]Ö±’NÏÏG§F«_ÿÈsÁö9øoÿO6uúO_žŸ~ë?þ!x EÖ¦}KK½ñ·‡WEñ" ¾X´cÁ@Xîјª€²ª´±X ý ¯Þ¸+.ÄåX*ø\Tm%Qú5Ë 4ú§ýjNxw”âò\»‚ÆÃ–q­/F¹!fŸTÿà;4Ñ“âZø«D¹Ó®•H‘IŽF\˜¤ÁÚã‘ÈϨÈÈèM|§«h÷¾>ñ‡¾CfÖ$ÒM­_[(W[d%|Är7¯Ì¥K˜¹äרU‡gàÝ.ÇÆ‰¢ƒþ&×öÑZK+`íHË”ã+»+¸ƒå§/ˆxG žãð˜é¥zoÞþôlì¼ìöÿ}úý,D©BQ]MkKH4ûHmmaŽÚÚX¢†‘ UUSQE~€’JÈä2|'ám/ÀÞѼ7¢Zý‹EÑì¡Óìm¼Æ“É‚$Æ›œ–l*–$œrI®VÛà'-<+¨øn- f‹¨xfÛÁ×6ßlœùšMºO6Û‹îVêqæïå‰ @¢˜ÿ|£|AÒ¢°Ö ¸d‚asosc{=•ݬ¡Y|È.`t–(ò!hÝK$’!Ê»Ïè_~xkN´Ótß éöÚU­–©¦Ã¦m-f¶ºÂ\ß[ù Lf)%»UFÄ „­zçúwÀiÚ¯¥-CQUò~Õ{«ë7º…ùòX½¾ËÉæ{ˆ¼™ K—"ùR3IÇbÆ¥—ìåðûLðõþc¢Üiö÷º˜Ö滳Õ.à¾þÐû:[½ÚÞ$¢tžH£Û$« i|ÉŒ…ÌÒ—ôº('ÂÞÒü¡Zèú=¯Ù,-÷V‘¥wwbòK$ŽKË+»;¼ŽYÝÝ™™™‰:ÔQ@Q@Q@Q@|ÍñWþNžßþÄÅÿÒ篦kåÿŽ«¬èŸ´ ¦½má?øƒMo ¥‰—DÓ^ä,¿k‘ö’0ŒçæsIì\¤›6(®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿЍ³;9ãÜìè®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿŠ¢Ì9ãÜìè®3þ­ÿDËâþÿŠ£þ­ÿDËâþÿŠ¢Ì9ãÜè¾ÉÓÜؘßú\•ôÍ|¿ð)uoö»×®|'âé«áw±ëzkÛ—íq¾ÐNAÊ’qœü§Ž+ê µ±Ç7y6€?ࣿòtÿ±ýŽmÿ¥ÚU}ÿ_ÁGäéÿbÿûÛÿK´ªûþ™_7|Xÿÿ¹wÿ³WÒ5ówÅøññû—û5'±†#ø3ô‘ù…ñ_þGýSþÙ褢Šÿò?êŸöËÿE%ζ>f—ðãè®þ"9—ÅÝ”£4º)*zôèø®?öÁÿ“§ý‘?ìsOý.Ók°øˆæ_|?vRŒÒ褩ê?Ó£â¸ÿÛþNŸöDÿ±Í?ô»M­)ìwäÿ—ªü‘ú‡EV§¼QEQE“⟠è~9Ю´OhÚˆ4[­¿hÓµKT¹·›k]ñ¸*ØeV¨­jå~%üTð‡ÁÏ Oâ?x‹OðÖáö›ù‚y®¤ò¢_½,¥cr± gm§j“@§ìßû¿j×ÿ½ñmžµ}câKÙ¸ºÔoá”Ä/¦CÌ_i·Kkˆ¡û±[ÍoD‘í~!j~Ñ|â]CÅéo'„í4Ë›a.íÌ-d±3N ¬d_,>SiÜ20sŠð¿„Ÿ®õoÚ P›Rð¦¡à+Oè¶÷6š.»soïk´WWÐÈâ;›ÈfºˆFäL"ðã¸!K}OÚOÇZ_ˆïGÂ-{OÑõë«(¼M®\ë³ØiÞ·™¤ž{µgŠ;‹i¥·[)`#îÝØѲWà§Åßi?ü!¯x›ÂúÆ·á=kLƒV°ÖôY¥Öï¬-nPO ­í°Œ]LЬÐÚ¬ð‹§›Éyçò75jÅûl|(›J¸Ôã¾ñDšm¾™µ5âø\0ŧȲ4wlÿcÀÖJÊNÒ#r Úqæ¿t/ˆv¿<{ð—H´ð~‡àï¶Ú¾¹â{á?] Ÿ6ækÐEöeÞÅdâ0‘ T‘ȸ+íz¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú(Í|Køm¡k*𞵤xïIðÿ‡í¤×4ß'õtƒJÒ%réiw[,‘,2G~„[¥¥¼Iæ—‰Ôu:‡†t?ÝÛéðéÚ†‘à] Î]kW¾ñ—ú´óÙ¬nïô©®a˜éÑOetÎ'Šh­Ì,ÖÿhqíÚ¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢Ì¢¤­%tkJµJU)IÆKªvz0tß xcáößü#šv“àO²}£SŸ{EöVµ6êz¦ËôûF›&È·8ò±Ò?/ý{WÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE#h« «Z¥yº•då'Õ»¿½†¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è´d¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú/ÌŸî`Ô¿hßMgo¨[çi¶Z=Újw&yRño5× ÆGýÓA¨ZM µ##ÛFñGôÞ¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þ‹ò\ÆÒÿâ‡ÅmgO7`Ôü]yå­ýÃÍ2Ék6.Í„7s˜Ô6ՈĠ Z}_ Óö™Œeü©¿Âß©æf2åõÞßæ]¢Š+ö#䂊( 'â?ú.­à=N_–ÊÇÄ ö‰zìóí.m!ã©Ý=Ì À8ß“… F§ÄoÜø¿áï‰ô+7Š+½SKº²…ç$F¯$LŠX€HaœqØÖ_Æ_Ü|<¾Ô[˜4{‹=náGÞh,•S±r8PHˆ’6µÿÿ»‹ÁGSÓô[-BÊïPÖµMYwYØèöÈ­w,ãÍ„´Nd‚Ù¶Mˆ·fUaå1N.½<-:ó«ðÙ7ó¼mó²·›:©BU%ïoÔô­oáÁïÚ;Fâ~­¡M¦\k^‹U[w\¸‚ëD³—ûBê KTú²,–o€±F„=\x#ÃÞ3š[«¯ C¨-½Å­ÔÇq ÒN 3†·ŽA4"9£ˆ†ÌHöðÂÿüÿ‚ŽøQñ—Ä_øL¼I©|2¹ñ ߌîtø´;LÙ"Ú¤×ö±]Ä“[F–¨ †åž7! fdÒºý‡¾_ũˤü‚8¦² §<º¾³p ºhie+v¾t\Ãû¥òØyr~ðï_]ðKá„?õ½_áï…¬|ªiúÓͬÝkº…Ŷ’¨²yòê -êGqo»ìÇÉ! 4LåÇÈÑ|n ² Ç.Ï9;$¡=ÿð/WdމaªÁsIiò<Ãàü‘ÿØ¿§ÿé4t|Yýï‡ô›Tùîn.ø:ãYÕ¢ÑôÍ7þ#¾ŸNÕ.~Ñl%Õ,€¹g“opP}šªPFÑ!‡Ì¼qá;ë¯øGGñ|QéšÎ¬¯ƒoãÍêEÖ‘Û]ßBÇ(²™®|»yå0îß)ŽßÃã,³ŒÍ«b#ì©Â.R¶‹M–×zí=àŽ?ɱXüó‹„£Jœ\¥m–ËdåªÒþoMFü;ÿL½ñv±ï4Í_W[« ‘÷n![+X|ÅõBðɵº2€Ë•ec»ö OŒmý½§Øÿex™u6Y¼¸´<øvý¡©§Û!óì[ËØ±m’&}ß/™oÀ×¥þË/}¢øWÇÚìú¥ž™¥ßjÿð’é7·ùPéö‡F6ÃWÔ#ûd&ãN’K9R$*|åfB“Bü?”«fõj¨ûª½,à’o»KÊövCð¶sÄgµë¨Ú*/{YÓQM÷j>W³i#Þu}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ô^Mø'ð·áŽ»q­øsÀþð&³ ý³SƒQ{Xî© y°êp®³{p÷›¥²+ýš'ÉN#â×µø™ñ[ÿ 4«ÝCÄ~(·ð}½”×76©®j&y¬.$]U’îæ%ÔßZ\[ìÖ1)ÀTC-|~ïãŒþ$ý¦m3Yÿ…-á(¼Ûí6ïWÔ쯼E Óý¤ÜO} ú—‘om äÙKÃ,Z=øÒh-•<§ö¿ýªü]û,ë>#Ðn>*|@›Ä“è¶w^Ó/4ï~öi/5('º¹–-9“ìÊ––²¤jVfó¶Â\Á䳿À/h:WŠ-õÒ>)øÇÄ~$¼[]:à].¤º gºÔgIKCoÍôæÜÑEx¡ÕÒ$ú×àÀo‡ž ý¦üm¯j^þÒÖ´{- Z²Ôõý@ê×p_‹fÙ³;ß^1–ÙaŠÒEivý£N2$h¯ÁÝ_û þ;Ïí/ì<|ð?üLîõ"Æ=ŸÚ“þö/í O3Ëò>×'úÌÚXßÅòùøpÆ¿o?e=+K¸‹¾8Ѿ\xƒQký.Êê—º[\.­z-üéöâYä¾O°ù“³/§j,òª¼E~tøß¾=üRÒÿi=cân¡¡L|MyàÝ3P4û›Ñ/®ÚêqøÁãÏ…> ñfŸqâO]x‚òÖóIÔ5“yöUþÂÕa r«tLêÖ‹n³*+%Þ•©Ì²)¸ÓÇv–>ñÜÐé‘ÛøMÑþ0[›W·u´²Ò¢ƒáúšU[‹aöH’Â%@ðÅ$`6íŒÅè^ñÃ8hox[â'Œ4mkAðañ4·Sðj7ï}â+·†xÂ]ÃÙçó-eŽÔÛ«OÓ„ÕÊþ!kÿ·wŽümáïüLñ³ðËá·†uOÇsâ‹{H¥ÔÞÒ,c·³µ¶Qæ4‘Çœ ÇJù í}™¬kv:LJ?kø­.®.gÓ¾Zi÷iu«®£%¬±Ûë€ZÈÂöì¤ðFc†pdS%ÄSͳ}ïÚ3áW„>è^)Ñ|áÍ?Ã:UÇÂoˆº„¶št"$yæm!È‚¨èˆˆŠT{çì¬uGâ{ÏŠž8¹ñdYËk®4Z:Íl¶Ðj0¤ké⬚µæâñ³d¦mçó/Äügû|ø¿ágÀ]⯈/-ªý“¿äÖ> ÿØ™£é 5Ê|køUጴOÃMƾÓüM¥[øg_Ô"´Ôa¢O¡ ²8ñVу#²ˆ?àŸÿ ~ üCø¯¦|fñÅ]bÇÄ?¼?â ¶¾Ñà´–ìEc¨é¶Å%7vóDªÏ#Š(À „+€Æ5úâ¿ÃH¿cïƒWž'ðÇÅxKÃv7¾µÕ#û&—{Z¡Ó4‰®q&Ÿ$¦Qg¾•ó!0voŸòX¼)ÿuKÿRû*ô¯Ú³I±×þÚi𕾣¦Þø·ÂÖ×Vwq,°ÏøƒOWÑ ¬¤‚¤A Ðå·„õŸþÜ_?áe?Ä/Aá†Þ&ðÍ–ˆºÌvMª'ö†³¼r¬p[Gf’ü²Lìb“\0™WzþšYþÊÇNñ4ž'³ø©ã‹oO5ä·ZâÅ£´×+s ÆÑ¶ža ©¤Ùí)¶CåŽî<«ÆžðïÂÏê¾ðž“o¡ø{J‡ám½°;c_øL/I$’K31fgbY™™˜’I?ePâ·ˆþ5øÏöùñÂÏ€º'Å_^Zx‚ÊÚ÷ÅwúÝ•½—Ûã´ûUÌVðZZA,‘@c˜*Í#,’¬x*#Y›íïƒÿ²^Ÿñ‹öfø]?Š> xÂò;éVÖ6ñ 2$Ò£vÓ/¶ÀVÈ3bM:ÙAœÊv+–bÕWà¯|?øwû'k^ðæŸ¢ê¾(½Óu fîÎ{8ðn¦¡ÜÿßM€^I_ävo ?dïù5ƒö&hßúC 4Ü]ÖäÊ*IÆJ韚?>\ü?øÃ㯠YøÇ^½Ó4-JÎÎÕ¯c±2°–ÆÎà»”¶PYd¹r¸aTÜîöÏØÇögÓþ-¦¥â¯xÏÄóÜøCÆv¿c²ƒìÛÏöh,/âó±i¼þúBÇL¨ƒ’x¯ÚsþNgâçý‡t¿ý4é•ôÇü—þD‰ö9·þštÊûLuZ«.…NysIA?yꟴºzùŸe˜|<±îƒ¥XT®â¹cî´°¶kM»ÔµÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë_÷Gé0ød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•}Uÿ.øÿ ÇöX×âwý‰ÿŸâïøôûGÚþÉcuþ÷Ófÿ3ïüØÇÝ9¯•~<Ê/tÏû¼9ÿ£l«ïÿÚÇþMcã'ý‰šÏþÍRªî½çÇÂsíðý«}¦å>ɾãÌæk ¹h„ËX6Ȉ&µÿã×þœ¾Ëþ•þ…ûϰîÿ—»_ùéjÿÇðä×3áÏØØi:t3j3C,R¹G––ÂBIÆ@ÃÂÃâ'$ä€sWáñf”¿fÛuö³±O²Æçìwž Ž`â…°FNnš±äJ2æz_×õßíø$‡À? üZø«ñO_ñ~áïiºœ61è·ú\W¶m-Ôîââ/3!<µ³t_”’³žFoÔ|ÐuxOHðÅÕÇÃ[ joªé'–0-´¯osŠ!šÞXvº^NHòó¹·d¿ŸßðD9V}Gã´Š! òè̲•‹êp¾€óŠýL¬Al~;~Ò¿´ÇŽ~"kþÏø¯âcÅž ñmÿ„µÉ5[}:ÇM‚ßûZ{;Krö¶ÎÍ$K“:?—µÙ6?˜ÉÙ?±WìÔþøgàx¯üâ jÓÀ>&ñ~ök}8Ï î©§ð-ÍÏÍÓ>Ƹ`Ná@Zw¯i5ÙxsO¶ñž¯ñf>û[Ž.. ‹â!(Œß÷È$rÂ(ƒ"Œ/гOü“­_þÇ?êC¨Ð3Íÿ࡞Ö¼Eð'KM BÕ¼Ewiâ&úK-Æ[Ë&)ÃHÂ(Ô±JùþˆôD¾ á5ªò~¬×¾ý¯>!ø“á?Áë ‹sþ!× ÿÐ'þOSÿ“>&ÿ„ßâý/ˆøMjŸü‡]7ì©ðkþ¯íKªk_þ ß ¼/tо5ð¤ße[‘q`±k»uV“`¸#€dìN~Óøyû@MñOÆZ&Ÿáÿ ÜÂ=¨øKIñ„šÕýìpµµ¾ /6í‡->ëTáXǵ¦&E1Æ“ûz¹oå™Eg_K–MZüÒz]>­­Ò=¬§…2lŠ»ÄåÔ9&×+|Óz6­)5º^gâO‚¼c¥hºf¿à ëšn‰Ù´»=KF¶¸†Â-¨¾\èDK¶8ÆÕavù¿ð'þDÍCþÃú¿þ—Ï_ªµð«ÿ´ÕfÖ5I´ß‹vÖÚmÅýÕݵ­ï…ÞâX#šy&´‹|Ê™ÜAë´gôgÖž9à? è~9ý¹<¢x“FÓüA¢Ý_Ü}£NÕ-RæÞmº%Ó®øÜl2« Ž ƒÔWÜ_µ÷Âê²Ç~ÙàßÝÿÂ/àÍ[ûÏÒàì–-³ì™OÜmò¢Ç—·ZcîŒyÀ¿ø'¦«ðƒã…¢½kþ³âýO ÿáqÿËJ?á‹> ÿÑTðÏþWü´¯æ_õ;þXÿàGñßüC"þXàHòZÓýŸ¾#Cð ãDVSËp|-ñSµ±ž<6:› R+•ÚHVžFµ·eØK†G2D–»dôøbψ?ôU<3ÿ„UÇÿ-+3Ä¿°WŒü[¡^èú—Äÿ Ícw—*ÂqÈëÿAL@àäàŽ+ê8s†óÜG,\’\Û§ú­×ݥϳá.â^ÌáŠq‹¦ôšSZÅõõŽëÒ×W>ŒøÕðWKøÇ¡A“ÿdø‹NÞúN¹^cÚ;cz:e|Ø$Ú‚HK ÛU•’Hâ’?|cªx{ö§øSáÿXdø‹N×®þÕf$ó‘´MWËž 0¾lmm’`}×FT’9#O³¾i·Þðo…<âÛø«Å–zaŒê2#[Üêq[˜ãk–ŠI¥v`$€K&öIù|ÅQ«®øþ&ñ7†|E©é6÷zžãHÔ5›MÁ0V¯Èr¤ª1‘ þ¥ÉpØÜ]sV«IÝ5Õv}×nßz´æ<;ƒÌ1Ø|ÊK–µš’ê¿•÷]º§åtõu=&ÇZ¶K}BÊÞþÝ&†åb¹‰dU–)X¤’DGVꬪF­ÑE}õ•~Љª\hþ´°“P¹´¹Ö¼½CDÐõ…ÒµmbgtâÞÊàÏnVT™!¸p³ÄL6³Œ°Ìoçþñæ¹ i–¾ðÝæ¡a­jþ3o[Ùxô>¯qálh§Shn$K×mCÌXTawû±¨"gÞM{¯|£|AÒ¢°Ö ¸d‚asosc{=•ݬ¡Y|È.`t–(ò!hÝK$’!Ê»Ïÿˆðgü"¿Ø?bÔ<Ÿ¶ÿiilÞÿk}«g•öí;í~o“ûþnï'÷9ò¾JóÿütñǵßKq¢x}´_ü?·ñ–«gÜò\\]:ꬠ˜¢/”ZŸxÃ(FKƒAÏÚ_ÅÚ‚[HVcm Â%°|ñ­÷¼5N+xõ+MOSÑ®žÑY!ž[û‹'™Œk#[™eœ p¥ßnö4?ƒ~ðôz?Ùtû‰n4­NMfÞöûQ¹»»{×µ’ÐÏ=ÄÒ4· öyžç3íA®qíßð×…´¿éÓXi¿d´šöïPxüÆ|Ïsq%Ìï–$üÓM#c Ý€ j(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€>ÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ý|ÿÿ“§ý‹ÿìsoý.Ò«ïú+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþÇþØ?òtÿ²'ýŽiÿ¥ÚmvËâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµ¥=ŽüŸøRõ_’?P袊Ô÷‚Š*¦­«Xè:Uæ§©Þ[éÚm”/suyw*Å "–yØ€ªª ,HM[¬¯ø³Cð>…u­øYÓü?¢ÚíûF£ª]%µ¼;˜"ï‘ÈUË2¨Éä°Mx^­ûLk>1ñ-î“ðûD·°ðÆ ÝêÿüU$ ¤XZ ÐÞÃfna¸½´›Ëž%ºVŠÆÒ#̈ô‡úN‡âi¼S¯k7¿Œ|? ÷–þ ñݼ³xmL•¿ö¥Ì^AmŸq J‚+h`g1+Ï™žØ®»ñËÇ_·¬<%§Â¥ðý•“Ü\øßǰË8Û^ÿdKs ¶öÙ³,—X%ˆÕãË­Ÿ‚ôO뺧ˆžïÊñu…”Ò\ø—Å7©q¥Ã¶üýEÖú5:Dín%ŽÆ†ä â8™XÛRøÁñ¾É™¦Gq7Š¥š{í/EÔo'Ø—žò95ù#»a-”‹ 6ÖD+nŒ*ˆ¼¦k,ÙÓǚγðRKÄ7MKWÓ/u˹µmVáTéu n$Ô5D[«ušÄ¤ @ˆŠ+µcmÅm âe„Œ¯R*ívOkúöí¯cÎŽa†ž2XM:±Š“]“Úý›è·¶»Xí¾)hËâ? ëRøŽãÀך\Í®Zk“\ZÜj•'Ô%½Ä—NŸp°´ ª‘“BÛ#iß'Fð%§¼Mâ?ê¾%¸Õ|e2ÌÞ%ñyÓÖ÷ÃöKäI=鳞ÙF”Ú,±Ú*.&2Lø“{ÛvÚ¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢öžˆjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è¿9|=ý¡µÏø›Æ>/ñ¯ Ãâÿ¦‘â BI^/Lº…õ´+{rÅö­5T–GÿGeV,"U’Ï‹¡ƒö~Þ\¼òåWîÓi|ìþzv30Ãeî—Öf£í$¡íÌÓi_¥ìíçe»>ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ý´ôCWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôPWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿE5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôPWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEøÀßü©h ¬ÞxËÚ]Þ¿{{â ´Ùõ‹q%‹ß]KxÖÌKLFsbªX¦v®v¿5}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEör¼ÊY]YU„›V×Öÿ¡É‰Ã¬LT[±ñü/‡?ô?ø_ÿ6ßü]ð¼>ÿÐÿáüÛñuöÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è¿Kþ·WÿŸKïgý•ægÄ_ð¼>ÿÐÿáüÛñtÂðøsÿCÿ…ÿðsmÿÅ×Ûº¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìG墟ëuùô¾öÙPþf|ã‰|gà¯xþG…ìÿµtû‹´k[?•æÆÉ¿o˜7cvq‘œuï_²µä>»ø¡­Þéþ×¼O¥Zk±ÚËx­…´Å´Ô~Åu©”½…nìdÝ<ʦ4u’v OÙÖKo}ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÃÌóªÙ”TyW[u¶ßußßäŽÌ6wtý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìG墚¾¯ý“ý¥ÿ/ìO쯵jñ8Ô<ßìMÿÚñ3Ô¿â`¾v›.ÏÜÛü¾^ÁÄ~Wú)«êÿÙ?Ú_ñ2þÄþÊûV§ÿCÍþÄßý§ÿ=Kþ& çi²ìýÍ¿ËåìGå¢üé诫ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_覯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þŠjú¿öOö—üL¿±?²¾Õ©ÿÄãPó±7ÿiÿÄÏRÿ‰‚ùÚl»?soòù{ù_è eã_ÅðQñ´n˺·Òî§ŽYáVšh-æuI!•áv\°s¶È®‚_ƒº%߀üu}¬ÞE¡x‘£—\Ô$Õ¦E}1ê)¡ª…½ˆÏa"D @ÿ2Kæ»ef¶í¼umcªèšÖ“©\[éÖVR>¯"kóÅvtM³ßÌ5-@É}ûÍ6sn8c"nOݪ°µÒÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ8Èx3 ‘fجƊV©ð¥öoºùl­ÑØì«ˆ•Zqƒèrüá¾™<7cáËVº{fî7¸±d·¿·]kYd¾Œ]YM´b8°¾_”ƒ@´ùJãźo†u?%ÝÌ_mŸÅþ*’ÚÇÎŽ9n=bñ¥eóUR5ùä•Ùc‰<Žˆ¬ÃíÍ_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýð×€¼=ð–ÿÆš†“2h:¥åýÿˆõífî6“JidÕä[ýG˾eÒX³ù .Æ/#âS4{ùöEK>ÃÒÂÕ—,#5'mÚJJ˶ûžžO›ÔÊ+TÄS4¥~´îûìqŸþ ÚøS>0ñv£iô[k‹Ô’êüÿgxEFÔ'·[ø£¸±’8ÙRGn´ÌÆ&+/bÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ}ì.† Œhaà£ì—õøîÏ#ˆ«Š¨ëW“”žíœÿ‹ÍU(#hÀÈÃõ>¯«ÿdÿiÄËûû+íZŸüN57ûöŸüLõ/ø˜/¦Ë³÷6ÿ/—°q•þ‹Ïø³ÂþŸÆV>,Ô#·°ñ‚áÕnô«ízüÎÞ[Á~'Õ/ÔTK§Î¶È±E…h•J(Üù–9–¦r²š³k{?›å°Íð5p$ãŠÍ­í}mçýjxÇ> XëšUþ¹ñ×L‚Ò+¼·ðï‰b‚KM"Ùà¸huvÎi¢c {gXí‰/&ÙT›/¡õ}_û'ûKþ&_ØŸÙ_jÔÿâq¨y¿Ø›ÿ´ÿâg©ÄÁ|í6]Ÿ¹·ù|½ƒˆü¯ôSWÕÿ²´¿âeý‡ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEð¨?j‰¼yâȾ%¾›àý'S»eñ—‹µ¨þËç-Å฻·ƒûQTÓÞ¾•5¼0G¦\4Öíî'ÑÚ[‰æ˜y0k‘ÛÛ¬>CE:ZÃɇuˆ°RxÖ»oøK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~ÛózG®súež“ x…üKs­[§Œ#†[{ŸøƒU·’úþÐ×2ÅrÑk¨‹3Y3Ëm Çn?°µÔŠ(Òé¼ÿö·øÃâ/…Ÿ#xßãŸðóÁšE”Z|Ú.—à],ÛÜÁ¨ ¡2"Ây9òÜ’œ“)9dýUã_Ø›ã·ÄO´ÂCûSh}£EÔ<=/ü[Û·X^ù?k‡ä™q¿ìðüÃæ]Ÿ)\œøüÇþkgýÁ?öþ¿U(ò¯þí;ÿ Ùÿ ãÿ ÿs/ü!z_ýþßÿÛ?íŸúÏö¿Ù¯Ó?boŽÚ6à*Ïö¦òl<åÿ`Ãÿ öÁ¾Ç²Î[$äÌL˜·žTýáo½¸üÀàóóÿBÅ~ªP¾Ñ>1~Ëß´?ìïð§WøÍÿ ç€uû-[OM#þk=;ì°iºhhÎS$¯ËGÎðwÉmƹOÙ“À_´Oí?ðÏÁåý¥?áÖ®¬µ=>ÚÛþM:çì°5êÇ2n ¾öÓà|”ÊíÀ8-»Úÿhù>ÏÙþæïý5ÇGüãþLOá—ýÄÿôéw@¦…û|vðÖ±iªé¿µ7Ù¯íµ<™¿á^Ø6ßíĽ¾á¦ ù—£ò>\mMªH¯š¿cßþÑ?ðP;ƿǟøFm<+{£j ü!Úuߟ8¸{˜*°•òæ²±óÎÆAýj¯Ê¿ø!üÖÏû‚íý{þ»û|vñ.±wªê_µ7Úoüé¿á^Ø.ïìëǽ±áfyw;ð>lí}ʯÿ…ÁûNÿÃvÃ8ÿÃAÿÜËÿ^—ÿ@¿·ÿǶÏûgþ³ý¯ökõR¿*ÿç:ÿçþ…Š÷ý3ö&øí£hþ Ò¬ÿjo&ÃÁ~_ö ?ð¯lì{,å²NLÄÉ‹yåOÞûÛÌ>þÒšïíû EðkÀº'Çÿí½\ ¢XÇÿfoý›¯ÙaŒeÄ­/Ë8ûÌîù$¶Gê½~hÁ`?ä¥~ÌÿöÔ?ôv›[ЊXF[6¿3—9SÃÔœª-¯’>sñ?†~(xËÄÚ¿ˆuŠÿlÖ5iâ¹½¹ÿ„rÕ<Ù#Š(Q¶© ¸Ž— ;rrI'®ø%ñ#ãÀ‰?´M?âoÛ<9ãiVºÆ™ýfŸhóÚ%o5•Ý3 º&®:Œ“¥XwŸòW~ÿÙJÐô¢¿RÍr¼%,IB/ÝZ{Òi[m·W÷³ùû‡ø‹2ÄæÔiU¨­9;ÚMÞ×ÕE=yc}uå]‘÷oüþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-z¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-~H÷GôŒ>ו~Ö?òk?ìLÖô†jõZò¯ÚÇþMcã'ý‰šÏþÍTb|ñãþQ{¦Ø­áÏýe_£¼-7޾|Aðŵ喟w®ø~ÿJ·ºÔe1[Å-Å»ÃHÀs®Húx¯Îò‹Ý3þÅoèÛ*ýQšîa’£Yb‘JeÂ|mÔ4ÿYXèú „’ø›Tu[e̯Þ£>Y,X¹Ê(Ç?6WùÏâŽm…ÌÞSW•Tík»zß·[­Ö׺;Ö_FPö‰èsßðMÙ7ųÇÄ©¼Qâ/ kÏâìÏ xRååX|tÌS A3ç.6ƒœ6qß±ý­üañ?þ·À‡> ÿºÿ„Óû{íúŸö-®©ÿv°Ïî§õÑ~V_¿“ W¼|&ø{Ã_Zéfi.µ 1q¨\É3Kç\”Ur¥€ù@UU*Œó’|ö‡ÿ“ìý‘¿înÿÓ\uý ƒ–"xxK’¨ÕÚ['Û^Ç™%íŽSþ›ã·ü#ŸØ_ðÔßñ*þÚÿ„‡ìÿð¯l?ãÿûGûKÎÝçnÿ¿ÞíÎßáÆÏ–²¼¢|bý™¿j‚¿µ¿ŒßðŸxCÇ·¾'Ô/´ïøE¬ôÝ“¤2ßHþbﹺ2aYBíÚÓ´}Õ_*þÐÿò}Ÿ²7ýÍßúkŽ» >ª¯Ñ?dŸèv‘ijú‡üJì¼?eì`óOöMżñJXD?{qö+îcÌŽÊÙ@O%öº(Ïü)ðSCð‰týnÊëP–îÇûËIäB‡û_R‹PºÈË4*±àŒ!!·œ0Êö{Óô¯ øIð÷Š1]YxóÆIà_†Vž&ÓV]aÕ&ÕÌÚìßm*Éó@ Û-Y6ÆÐ2EÅöòÿŠõï†z‡ÅO?ˆ¼Q«i¾ðî­5ÝÖ²ÑηWº†¡o{s%áF:}£Gk NÖȉi O-¼q8Íp¼Y¯|G‡Ã¾>&Ö4} þœÚ,o¡ø–úý®4¿øDæ¾hSSºŠ;›˜&™ÞTœÁd­¥ ¼«öýñV»âÏj Õ´­Yñæ«oàÏŠV\6WSËy,Ú~³ke¦0*L“\Å“1i™˜³;±m_ˆ¿ÿábø³Ç à/j ¢øW–Vš×‡îwÛÇ%׉® º–ÎFW·›t{"‘”IšÞ1öòUÌ:·ƒõ_ÝØx»ÅÛøCâ7†ü3¢ØßkWPÁe~Ú!¾™Yžõ¥È vóy Gäy%r~µ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šøþ ;ÿ'OûÿØæßú]¥WßõðüwþNŸö/ÿ±Í¿ô»J¯¿è¯›¾,Ç‹ÿÜ»ÿÙ«éù»âÇüxø¿ýË¿ýš“ØÃüú?ÈüÂø¯ÿ#þ©ÿl¿ôRQGÅùõOûeÿ¢’Šç[3KøqôG×Ëâ‡îÊQš]•=Gút|Wû`ÿÉÓþÈŸö9§þ—iµØ|Ds/Š>»)FitRTõéÑñ\íƒÿ'Oû"ØæŸú]¦Ö”ö;òáKÕ~HýC¢¼/ÇßµV“¥ø‡VðÏ€ôëˆ!Ña7ZýÌzµ½–‹á¨VàE+ꚃ–쪷ä¢K6-¤&5jÀ×|wâ_íÙ¾*øŸOñ/Ù¬žI4VÎÞ×ÃÞ>ÜU¾ÓÆ ~×c7ØàxÒêY¤ŽXÐÛæE¶Ô÷]kö¦·ñ>»}¢ü3¶Óõû :Ê-GYø¨ßÆ´k)Vïb_0=ödz‘Y Ä{•Ñî d}™ZŸÃ«{ÝuüGñÄ?ðø“ùխˆ¤†-/Ârƺ€‹W›N†ý kbcnÒ /#Éó.IBm»ý_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýˆøÁñ¾É™¦Gq7Š¥š{í/EÔo'Ø—žò95ù#»a-”‹ 6ÖD+nŒ*ˆ¼¦k.ßWÕÿ²´¿âeý‰ý•ö­Oþ'‡›ý‰¿ûOþ&z—üLÎÓeÙû›—ËØ8ÊÿEùßã¿ÃÇðoмOã>M*êáµ/i÷·1ϨèÁžH"Ô\¤ŽÍ§Ì¶¤©sºÙcÁ :Y|þ}‰Ça2ú•²øsÔKî]Z]Zíùìþ_‰±yŽ+«_*§ÏU-eÖI}¦·Qëç³óØ¡˜Ü^^^^\jš­üÆêÿR¼`ÓÞL@S$„>ꪪ¨TDDDUDU¶m")aÒüIã ÒK‰®ž—âíRÒÝd–F–VHb¹TMÒ;±  e‰ï[Wò…<ËF¬ëÒ­(Î{µ&›õiêRÍó牣ˆœjOâ’”“—]Zjå°jô;ü@ÿÂëYÿäª>Á©ÿÐïñÿ ­gÿ’ªý×ý»›Ð]Oü_ævÿ¬¹çýUÿÁ“ÿ2‡Ø5?úþ áu¬ÿòU.‹m X›[SpèÓMs$—wRÜÍ,²ÊÒË#Ë+3»4ŽìY˜’XÕú+“™c±Tñ5ç8§{JM«÷³{œX¼ß1Ì)ªXÌLêE;ÚS”•ö½›zêõó;?…_n>YÚxwVÕ>Ãá ]í¢j×O3[øjs ‘F·qG,hÓ˜NÇ`-ˆS•…Qìþ‘ÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ~=ÓtÛïj·V•qe`Ö–§PÕu­Q¶éúˆÝºòí·(Û„“d{•¥do™9¥‹êK´ø]àÛ? Xj¯¤XøJÁÚ×/cfÑ£Hõ×TÔÖ;è’]:Qò­‘cX¶ $" -?¢ø'˜ãrûã£xÇHIï%úÛnn¾m6Xxu™fÙŽW|Æ7„t„ßÅ%Öë¯.ÜÝvզͭ_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑD?W _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿Ñ@ _WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÕõìŸí/ø™be}«Sÿ‰Æ¡æÿboþÓÿ‰ž¥ÿó´Ùv~æßåòö#ò¿ÑM_WþÉþÒÿ‰—ö'öWÚµ?øœjoö&ÿí?ø™ê_ñ0_;M—gîmþ_/`â?+ýÆWüýÅCûÏ#û?÷ÿóÓû ^ëößš°xºXì<14~+¢°ê9–¼;¼&®Ž&ÓBK™#¿ñ÷ŒmüQ­Ùjm­A/‰níE—‡®Òêæìm#×vF¶s%È,ÆI„:±oç42[¢vßð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›°ôþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mùªjì|)l—‡Œ-ü3El²øƒÄªëg/˜±EÉoâVŽK4IW“3hšè7À1ðÂÛâoÆ9 öZW‰þx5a…­µo\_&ºì—EìRU– -<ý¦ìyÓ5¬ñßÌ Ôþ Cá›t–_ÜiÏÑZÛÚÝjòj)qæ,P[´kí%Üë-šDðÆ­%Äš.¸ˆ®×à?)âO€k…þ$ðæ©-ÇÂêÐÚŧÇ┾ÕuÛ¨CÚβOnÚ«ÃjÈ––p‘!–g‘ofe·k—CôÿÃOþøaä]Ú C^ñ"Y-„Þ)ñ-üºž±qÚZ6º˜³¬Lè$0Dzå™cRMwôñüß hi¤†oÛKOŠXØ£Æÿô€ÊÀà‚ ¼\¯Ä¿ÙOâ×Ç/jñoí§ëڬХƜžÓai™%Ic¢\"!ùHÎ1È$WÑ|%mkkâO³4ð<‹¡,r0¸Æ1ÀÛÔ ì㓞à‡-~#ø÷ZñkÀ²x_Gºû>‹m'Άà&ã’r®Sƒ?ÊAJü©q.tø…äU–¼÷väèýmÓk¦®ú÷{~ËÚó|5ø{û#|bøà­+Àþý®,ü5 iË#Ùé×Ó¤dY%y\îšvvGsÉ=p8ü*¿¿ôzÚgþ:?ÿ¯£¾+x9|WáÇ–gÔlU¥· OÌ8Þ›@9$/g rkç[2×â—Äí ÂZ\-k¦Alo|BUÛçŒÌ#,ùr18Ÿ‘òUq.q–çT²¬>3_‚W~›µŸn7kèS£NtÜܶ<Ëà¯ü»Çß²õž­wàÚ†Û¶šÿÙþ×<¾ ³¸KŸ(HaÃ\\¸È~\g<ç“ÿ ¯ãïý¶™ÿ„ÿÇkêíOÃv©á×ÐÚÝmôÓÂÛ‰WÀ ŒqŒcŠù;â’ønÑ<1ieŸÞjIafካÃçþB *£vÞ$Vìk^*âLׇëaã‡ÃF¬*û·Öê]S]­ªë¾šj¨Q§U;»Xóhÿàžž:—ã<Ÿ“ö¥³FÛÄkàË37ÙE¦ iòòHO¹Ü½Ízgü*¿¿ôzÚgþ:?ÿ¯¦|ðëKðg‚bðäQ¬Ñ<%o§£ÞJë‰es¸¶ç9þ#€¯¾+/…–>!µ»¶ioŽI™Æíÿu‰ÆÒTe¾î F\ô¥ÄÜG›ðö]aãSžÑ•›÷fÿöÛuò~AF:­«ÚÄ¿fjÿ¼ñÇ?´5·Å/øAþßö=2ß¶z~ß¶Z´f[yŽ3„o™[ý^2MqŸ ?e?‹_|§øÂ_µþŸ èKL–úsøM™¡g•å–vrLŽçæ'Ç_U|øuÿ ûÁ–ë}·ˆïÕnu[’˜òœ‘!˜mŒ€)ÛÁ ư>2øJÚÖþ×ÄŸfiày-B0Xä`qŒc·¨ÙÇ'>®q›æ¹^H³5B2©œáw¢}¼ã¥ï¦îúkéÂu9/§CÇ¡øKû@ÜÍ0þÚZ|²ÈÁ4ø¤f'%äšóƒðOO~ʳkPøö¥³ð„ºâÀ÷ÑÜx2Îfb2Ž.._hl¿wÏ9ÀǺüðå¯Äë^-xO è÷_gÑm¤ùÐܤÜrCnUÃêpgùH)^Ëñ[ÁËâ¿<°£>£b­-¸R~aÆôÚÉ!xã93X`sœã‘K5ú¼U[sFz¥ºÞÞËfÒèî9S§¼—Ó¹óü*¿¿ôzÚgþ:?ÿ¯6¹ÿ‚wxúËãT_.?jh<}.<¿Kà«5Gͧن"7>IÌ/Üÿk¯5é¶:e¯Å/‰Ú„´¸Z×L‚ØÞø„«·Ï+˜FX0 ò.äbq?#ä"¾ªÔü1§jž} ­ÖßM1,) °ˆ•q° ¸ÇÆ8¬¸g>Íx‡.©Ž•Ózò&Þ­wìžš«ïå`­J)¨ÞýÏ”áUü}ÿ£ÖÓ?ðÑÿøíyïÅÏØâí'‡uß~Õ6~ ¸’]6õ|ev’ÈÑɆå‰1CÃç ÇSžÿâ’ønÑ<1ieŸÞjIafካÃçþB *£vÞ$VìkéÏ|:Òüà˜¼9k4O [éÀ(÷’ºâY\î-¹Îˆà`€+—…¸›8â Wu0ñ¤©]]·~u·É5¯UoAâ0ô ”[º‘ð?ü;×Ä¿ôuzgþV_ü•[~ÿ‚oër|Aðgˆïÿh+oZxW_°×Žoáh!ó^ÞQ"¡’;¢SpV\@Îpq^©ñXÙ|,±ñ ­Ý³K|pºLìÎ7oû¬N6’£-÷pJ2ç¥{ŸÁO‡_ð¯¼n·Ñ«xŽýVçU¹ y)É’†ØÁؼÜk·‡8Óˆxƒ_§É MÆw”ßd›³×«ìÏ)äYVƵ RÝ5¦¾i+ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë_ ½Ñ߆Gßõå_µüšÇÆOû5Ÿý!š½V¼«ö±ÿ“XøÉÿbf³ÿ¤3UŸ|xÿ”^éŸö+xsÿFÙWê¥~Uüxÿ”^éŸö+xsÿFÙWê¥J6«ºô9ˆ>_x~T…ÔíÇg0áÖAƒ´ŒnÆ98¼à_ÃíOÄ>9Õ>"x¦6VÒɧhðù¥|±x&vøNC ¤¹¥;P×ÐtWËâ8oˆÎ)çSïalµ×Fü×ÿ#ü£U¤©º}¾výª?g¿|RñgÃÏø_â[|3×<º›Á¨'‡“X.·‘E‡Êw ¤nU¸|ü»s_DÓ&†;˜d†hÖX¤R€U”ŒAê }5Nw {&”¬í}Uú_m;êŒU¯©ñ7ü"ßÿèóÿóXÿj|*øã/||ð_ÄþÑüR›á÷Û|!|o¤´_nµx2E êæVÿWÄÖïÆd“áÂë-Ž™öÛ½]’Ç™"I\û€ªrNäS·æ5ïŸ <ÃiÚ6åšõTÍ}r¤1žåù‘ËmRÃ?*–ÚªJü¿…óÞ Í³ F1¥Nœ(·r©]¾–nm[­ìî—šgmzT©Å86Û:ú(¢¿T8BŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹O‹Z¥—ÂÏ\hšÞŸájöKoVuK=>q˜î'gVQm‡bÊÀ*œ‚8®®ªjÚMŽ¿¥^éš•¾£¦ÞÂö×Vwq,°Ï©WÑ ¬¤‚¤A Ð̾9ÿ…%ÿ f½ý‡ñÃßÙ^ ÖµðΗ iš-LJ4Ý*k¹¬†õK½&kQu;Oq sZˉÊC˜yYŽ, ò£Úå^$ý£¾"ÛiZæ¿oá½ÃÚo†þé5[ŽæMIe™uŸJ1ˆØ­–Ï´:“ !ͼÞf!õ_ ø×Å^*ø«âË H´xü'á­M4;È&YEô’¶m|/#˜1B¹»Ž³Áù^_? Ö½ø/à«ý+]ÓÃöðiºß‡áð­í£½¼-¥Â· ²$l¢%U»¸Æ€p3ò®-­ðÇü'ð˜ÿfÄûïùŸh—Èó¼¯'í?gÝäý§ÉýÇÚvyÞOî·ù-|Õá¿ÚûÆšçÂÏxÖ-íƒáþ£ã[¹ð–«¦Yé3ÃSAa5Ýõ?0NØšØÂ ÚHÁq*ùUx[ûpèV­âOìõÖŸt—i{ͼ;˜•‰ðÒlR¨e*žaRþ\A¼µâ­¿g/‡ÖºV½¦ âm7YÓ.4I¬îuK¹¡µÓç]³ZY#ÊEŒ ¡ŠÔD¸ŠÝG·Ò袊(¯ý |_¬ø;_øC>‹§kãÝx¶[kD¹‚¯âþÄÕ_Ë>|ÐÄʯrí‘ÀÌ Œ°Q^ÁY:Ï…´¿j:ýý¯Ú.ô;ÖÔ4ù<Æ_"v·šØ¾¿ss2á²>|ã ò¯Ä_øŸÆ,ñƧøÃáõ£¼²]2ãXŠÞàGwâk¨.¥†]>îQ!fYB"Á N·Çyõþñ߇¼-¯øl5†^*ñ sjšåæ¡y§ßØ%¢E5µÝį<{…é,»Ê«AF#c)—Ý|gðoÂ^?“W—ZÓî%¸ÕaÓ­î®-5›IŠØ]IwfRHdF‰¢žY$V$€IRÇàGƒ,ü+âIe¨j–%²}7V›YÖou Ë«VGO³›»‰žuˆ f*ŠáQ¥‘”+;æ¿^ûAøÑa£G¤xãÁºmÿ‡õ¹ôx•µÙµa¹°Hçµ·^ˆ¸•dS$&Cw 7–L<ÿÆ[RËĵËûß Miþ,ðŸˆWû3ÁðG§A)mKJð¹a˜ÍxÑ5½Á– àL¸"$÷_|ð×€uYu=8kÚ“Âm–ó_ׯõ‰ ‰™Yã…ï'”®ÉuŒ¨se·yi¶§Š~x3ÆZíÖ«ªYj %îßí +MföÖÃRÚ¡?Ó,â™mî÷F©yñ¾øÑ#mȪ Çô¿|EÒ>'|Aðü^ Ñîî5߈ÑxCžÿK¹š %ðÔZ›î‡í€Ì­+ÄxšI§Éä¯Aá?~8ñŒ|áë;_ÃößøI£×¯çŽù‚ëº{Ëis´o”ˆ¤säùÈÆI¼‚“ú±ð#Ášæ£âBæËPŽÿ]½·Ô®î¬õ›Ûibº†ÜZ¥Å³E2›YM¸ò]íÌm$yI ©"µ|?ð·Ã¼ÑnôÍ3ì÷z=•å…¤íq,åÝÍ ÷M#34²Ío4›¤g ʼnw,࿵α¢ÂYw©A§ø¢ÒËÁšÇŒìÆ“¢êZ]š¥‡ÙÏÙàÔn•¢Õ"”].ÛËxãM±òˆjø³ãÏÄ…ÓøóKñ<^Õ®ô[/ ¶ŸªhZ]ëyï«ê—Vy,’ÊÞI‰µŠWy¼¦Ä¨g  Eû5xEþֽм=§Á­]è·š ë"}JÎ+,›#k$Á~­ emÇ)‘b _w?ðÃöXÓ¼)mâ×ñMõ¿‰µ/Ãcm{ugí³2ÙÉ4¶³´÷—Wmw— ¶äÜî`µX„~B’Õ|ø¯|Aðö³/ˆ,. ¸Óu3c¥7‡ï´Õ"û<}¢;ÜÍ «Ìð|ÎášÝÜbú]sþ ððûJ–ÃE‚áRyÍÅÍõì÷·wR•Uó'¹ÞY˜"F¤v*‘ƃ ŠA@ÁGäéÿbÿûÛÿK´ªûþ¾ÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ýówÅøññû—û5}#_7|Xÿÿ¹wÿ³R{b?ƒ?Gù˜_ÿäÕ?í—þŠJ(ø¯ÿ#þ©ÿl¿ôRQ\ëcæi>ˆúïâ#™|QðýÙJ3K¢’§¨ÿNŠòÿø(v3|iýš£Ôî4{=5¼A2Ý\x†ŸMŠ#s§ï{¨ÙÐ<r]K *\äz‡ÄG2ø£áû²”f—E%OQþç_·n¥ýñûö]¿þÕÓô/²ø™çþÔÕ—užÛ­9¼éÇ™bLnaæ'Ê̽F”ö;òáKÕ~HúçNý¡¾hzU†™áߊ>Ð4Û9® ÑläñMœé2…¾Qqr‰©¨¸ÓÙZ ’a!¶-‹ö[rþÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙrÿá-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›SÞ5%ý§>¶Ï°|]ð}ŽooŸöÿZÜý‚èý¿7—˜ÕÚ¬dó!ò­ è¾Xö²’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙrÿá-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöߘR_Úsá[lûÅߨæöðéÿoñu­ÏØ.ÛóyyP}ªÆO2*ÑpÑn‹åhû)/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}—/þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù€< âŒ>øðjÞøƒàÿøDnï^Õ¼;ˆôù®4wóŒqËo3¾ëp®±žØH¹U‡rZCð³Mø!¬ø*êüGÒ,WüýÅCûÏ#û?÷ÿóÓû ^ëöß›Ÿð›á߃þƒÃ¾¾·ð^…§MqqŸy¯™aÒÙ§yä/ü$$2Á%£™‘~V¼ªÞ~f`hcªc¡z‹UdÕï~eÙ¾½÷ï¡Â¹n2­˜Ó¦¯UZQi5{ß™vo¯}÷½ù ½ö[ºûOؾ#h¶kól¬þÙñNæoìù£ûV/®vk«ç[K²Ûd1m˜yƒy]Ïäzì·uöŸ±|FÑl>׿ÙYý³âÌßÙóGö¬_\ì×Wζ—e¶ÈbÛ0óò»ŸÈôÿøK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æö>¡„ÿŸQÿÀWù÷öfþ|Cÿ_äy…Þƒû-Ý}§ì_´[µù¶Vlø§s7ö|Ñý«×;5Õó­¥Ùm²¶Ì<Á¼®çòËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÜÿƒtßü-¶Õ`ðíõ¿„ÒïSºÖoΡ¯™Ú;×É4÷Ì|BLí Xâ|“¹t q vª||ˇ°9œiÓ«£)4’\ÖMYµÓ[¿O™àæü+–ç¥Jµ5ÂjmE%Íe%ÊÚ³I·wém7Z>ø¿ðWá燭t¯ üVðeûTíö¡â}>I΢!»‰µMPèƷ¶ó µÛ"©‹÷ ,B4¿´ç¶Ùö‹¾±ÍíáÓþßâë[Ÿ°]·æòó ûUŒžd>U¢á¢ÝËÑö\¿øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æú8B4â¡d´Il‘õ°„)AS¦’ŠVIh’[$»’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÍeš’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀ’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀ’þÓŸ ÛgØ>.ø>Ç7·‡Oû‹­n~Át~ß›ËÌjƒíV2yùV‹†‹t_,{GÙIiÏ…m³ì|c›Ûçý¿ÅÖ·?`º?oÍåæ5Aö«<È|«EÃEº/–=£ì¹ð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æ?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌ©/í9ð­¶}ƒâïƒìs{xtÿ·øºÖçìGíù¼¼Æ¨>Õc'™•h¸h·EòÇ´}”—öœøVÛ>ÁñwÁö9½¼:Ûü]ksö £öüÞ^cTj±“̇ʴ\4[¢ùcÚ>Ë—ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~cþßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÀõŸÛá}–«ýŸ¢øÆïW¸I®.lßBµ¾ñ4:]Ä©(»Ô%°º‘'´”ù~MŽå’ b;#M´þÙ_ÛgØ.ükc›Ûçý¿ÁúýÏØ.Ûóyy‡j±“̇ʴ\4[¢ùcÚ>ËâÞ2—ÏøûâÙ¨ ¾Ñàݨjneò®µH|ÿm»Ä°yfœùƒ}ͽ̻{¹¬Wä÷â2ŒÆ®ÉBÚ¶úÅ?Ôü‰üFÅd9µlºž2PåÕ·wxÆ_©ì2þÙ_ÛgØ.ükc›Ûçý¿ÁúýÏØ.Ûóyy‡j±“̇ʴ\4[¢ùcÚ>ÊKûe|?mŸ`»ñ­ŽooŸöÿë÷?`º?oÍåæ}ªÆO2*ÑpÑn‹åhû/Q^üDœ_ýÇïgËÄ]ÇÐ,>ö{ ¿¶WÃöÙö ¿Øæöðéÿoð~¿sö £öüÞ^aÇÚ¬dó!ò­ è¾Xö²Óñí—áOì+é|‰õCss.áÍCJÔ ¸Šé¤¼W¼¼’ââ(¤°‘%Ao+Ä•±6É¥·•W¥Ébñ?ý€tŸý(Ôjÿâ!ãkR«ÉF1qWOWÕ/ÖæŸñsE ÎFQÓ»zóF;?[ü­æu^'ñ?~*ÛKiãMulü54ÒÏ'„4{‰§³›Ì“ÌxîngÌ·o’ "Ž5&¯ Keeo¦ÙÁiiV¶–ñ¬PÁŽ4Q…UQÀ1SÑ_–c³,VeSÚbfäÿ¯øk½mÔü[2ͱ¹µW[QÉÿ_ð×wvêMð{WþÂøÅã›Ïí/ì—‚ÓÄž0½:…õºùf"`$íÙâÚ’< O´4ÆWËŸJ¢Š(¢Š¥¬é6úî•u§Ý.è.#1¶$g£ ‚2=ˆ—ðÿÁ¶¿¼¤øzͼȬ`Òà6BKI& 8ÜìÍŒ3À®†ŠæúµoõžUÏn[õµïoKê;»[ W%ெúoõŸjV\Í­Ý$îíF‘…H€nŒ„Às´ëh¢¦Z°­8§(_•õWVvõ@›I ®Jûá¾›ñ#JñŒœ^ØZÍDÈûTJH#$&ôÃeèTg­¢ŠØj8ž_mùZ’¿F¶kÌk`®KÅÿ ôßx‡Ã:µçè—‚íP.<âªÞX,#d…\rG ;¸ëh£†£Š‡³¯%tìû§uø MÇTKYÒmõÝ*ëOº]Ð\FclHÏFd{*í­Jp­ S¨¯&šîžè³º9ï‡þ µø}àÍ'ÃÖmæEcF—y²ZI0IÆçfldœt4QE*p£N4©«F)$»%°7wvr^ øo¦øYñ6¥eÌÚÝÒNà.ÑiTˆváXÈA8;A®¶Š+,>Ž’£B*1[%¶®ÿ˜6äîÎJûá¾›ñ#JñŒœ^ØZÍDÈûTJH#$&ôÃeèTg­¢Š(á¨áù½ŒRænNÝ[Ýú°m½ÎKÅÿ ôßx‡Ã:µçè—‚íP.<âªÞX,#d…\rG ;¸ëh¢ŠXj4g:”â“›¼Ÿwd¿$¶ì™ò¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-z¯üþLOâoýÃ?ôéi^UûRÿÈÃû=Ù\ð÷þ‡-n÷F°ød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯@¢Š*ŒN+âw¯¼‡,tm&ßYñˆõ3¥i–××­eiæ­­ÅÛ´ó¬R¼j!´›br_ËR1uɲøÈÚ‡¯î|{¡ÜxgW²ÔÆ”,t˜®µuÔ¥kt¹VÓ„vé=∷”€k{¬‚´†ßÆ¿êž;𭮟a¦xÄv‘Þ¤ú‡†|S;Y€$€A,† Ì;&hnUÖ'%­•>På—Ít?€þ*ðÆ‡£ê:6™á}'RѼ['‰tÏXßK‡cé2igÒÚƒ³O5ñe´Ë,ˆWæ3»Äÿ>kž2ðä—‰´ûKLÓ×ÅÖn­æÚ 6Hn6ß¼ÛLBÙ~Îíç– Ž-Áu3D$ÜÓ¾;ø3Qе}TÞêtzW“ö«-_F½ÓïÇœÅ-öYÏ \KçH(¼¸ÛÍ‘Z8÷º•§‹>ëž;ÿ…Ÿo«ëz|?ðš|?±ð‹êV޾UÒj‰î³9ÛüL#dO9›åe-Àfâ‡ì¿­ë~ñŒ7ÖÖú&»«M¢Kkãs[šuÒïÍôq¶©u²kU‘ÙãSoè ¼Á¦fXãʩӔ§¤äîßwdµù$½îÙê·¿´oÃí3ÃÖÍöµq§ÛÞêgD†ÒóK»‚ûûCìïp–fñ Òy"tq4a¥ó!‡3Dµð·Št¿hVºÆuö» ÁY£h¤‘I€ñJŽ®…tteeVRŠøà± Ýx;R– ?L»³ñœþ'Õm¿·õ-nVFÐît´n½Ì·2åàl”1°+÷Ëé|}à _éš„¶ó\Oâ sUV¶fe^j·W‘), îÜ aŒ #ê#µ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯‡¾<|xø½¦þѾ0ðƒüa¥ø{DÑôý6í#½Ð’ùÙî]À7™sÎ~ñè÷ ~yüiÿ“Éø£ÿ`mÿ@»¯•âŒn#.Ê+b°²åœylìžòŠz4ÖÌøž3ÌqYNCˆÆà§ËR<¶vNלSѦ¶o Âéý¡¿è¨øÿäÿäš?átþÐßôT|?ÿ„ròMS¢¿ÿ]³ÿúÿÉ!ÿÈŸËÿñx£þ‚ÿòJüsþOí ÿEGÃÿøG'ÿ$×GðoöˆøÄŸ´/ÃÏ x·ÅZ‰ô/Imÿ‚ŽÿÉÓþÅÿö9·þ—iU÷ý|ÿÿ“§ý‹ÿìsoý.Ò«ïú+æï‹ñãâÿ÷.ÿöjúF¾nø±ÿ>/ÿrïÿf¤ö0Ä~ò?0¾+ÿÈÿªÛ/ý”Qñ_þGýSþÙ褢¹ÖÇÌÒþ}õßÄG2ø£áû²”f—E%OQþç_·n¥ýñûö]¿þÕÓô/²ø™çþÔÕ—užÛ­9¼éÇ™bLnaæ'Ê̽G¢üDs/Š>»)FitRTõéÑñ^uûvê_Øÿ¿eÛÿí]?Bû/‰žíMYwYÙíºÓ›Îœy‘æ$Ææb| üËÔiOc¿'þ½Wä¬?á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›õ=ãªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oê¿á-þÎÿ™“û#ì¿ôñŸö+þ~¿â¡ýç‘ýŸûÿùéý…¯uûoÌÂ[ýÿ3'öGÙè/â?ì>WüýÅCûÏ#û?÷ÿóÓû ^ëöß›•´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&òÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›À:¯øK³¿ædþÈû/ýüAçý‡ÊÿŸ¯ø¨yägþÿþzakÝ~Ûóð–ÿgÌÉý‘ö_ú øƒÏû•ÿ?_ñPþóÈþÏýÿüôþÂ׺ý·æåm?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼´ý¡|>Íö_о±Ç•ähøÒ Ÿ³ÿǯ•çãÄgÎòñcæã>oön¯Œÿi&ð«þßìïù™?²>ËÿAyÿaò¿çëþ*ÞyÙÿ¿ÿžŸØZ÷_¶üÇü%¿Ùßó2d}—þ‚þ óþÃåÏ×üT?¼ò?³ÿÿ=?°µî¿mù¹[OÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’o-?h_³}—⯇ìqåyÚ>4‚çìÿñëåyøñó¼¼Xù¸Ï›ý›«ã?ÚI¼ªÿ„·û;þfOì²ÿÐ_ÄØ|¯ùúÿЇ÷žGöïÿç§ö½×í¿1ÿ oöwüÌŸÙeÿ ¿ˆ<ÿ°ù_óõÿï<ìÿßÿÏOì-{¯Û~nVÓö…ð@û7Ù~*ø~ÇW‘ý£ãH.~Ïÿ¾WŸŸ;ËÅ›Œù¿Ùº¾3ý¤›ËOÚÁìßeø«áûy^Gö ¹û?üzù^~n3æÿfêøÏö’oóKçü}ñ ìÔß èðnÔ5?·2ùWZ¤>Nÿ¶ÝâX<¿³N|Á¾æÞæ]¿½ÜÖ+Ì>)þÒ ¼?ñÇS¿¼ñgiwá.WSmqO•-ñ™`»¾ ,1KoÄȾlé4áH˜;åÿÃ_|$ÿ¡°ÿà²óÿŒ×ógå9†';¯V†r‹å³Q“OÜŠÝ+n"qæGšã8_ …©8>K8ÂM;SŠvi[}=Oc¢¼sþûá'ý ‡ÿ—Ÿüføkô6ü^ñšøïì,Ûþ*àÿ#à?Õ¬óþ€jÿà¹ÿ‘ìuÆé_òX¼Oÿ`'ÿJ5ã¿á¯¾ÐØðYyÿÆjŸþ&j?>+kçჵŸ‰÷séu®û(•¬‘Ë}#-ÕÕÀUƒtnJ;)QÍz8>ͪª”–iÊ)+ÅÅ|Q{».Yëåü-žVU¨¬Då—4Uùà÷’Ih›ÕžßX^ÖuŸ‹º©Ó~ørãÇ­fE¶‡dwA¿Î¿`Q™Rá_Ê€M.ü•ôïØ6Îÿìš§Æ]þËõòæÿ„cNG³ðí¼ƒìq’÷l°¹áÌl²Ü-}S¤é6:•g¦i–vúv›e [ZÙÚD±CH¡R4E*ª€€_¥dþÓ…ªæ³æÉÎ[¿•½YúîCáM*v­TæÉÒÿ·¥£~‘µžÒgÆ^ðìïà?ëÇâgƯxÃÄÓôÍ_CÔõû[ ¬³ìŠM)®ddy™ˆ»iÙ%]ÑùG >د*ñü?ÃÏû ÒÕ¢¾?OÙè7ž'ñ7ïj)øeà¿ì-zæøxšã^²mÓjk±Ëu$ÒÉ7‘¦µ½Ø´YÉbµ‘b-!Yp½w'ÄK¼‘‹xàw’†(’UŸÊ‰”íú+䯊о‰ÞмE¬jÖöºg„µk«½sY–6Q{¬^[ê÷/x¨Í§ÀÖv»­‘"´T’Xcˆ‚k+Âwº÷Œ4i)㋈ü3¬|F¸±µ¹ð‡‹/µu“K_ ÞM- Ö.aŽ[Åk¨§c*hY¼¸¥Ž[eò@>¿“V±‡U·Ó$½·MJæn`³iTM,Q´k$Š™Ë*4Ñ`0 ˆ7 Û¯ˆ,îZóâ7„¯î¼g¬hþ'·ðÿįè‹]]j3)Óõ˜mìöØy‡ûFx­‘Ý‘’In ²<†G‰}öRñUž¿ÿ M®›©kØ[}–Au¥øÞãÆ:8‘üàÉ¥uÎ.@ ÖĘãFµ‘iäÈÐQEQEQEQEQEQEQE|«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡Ë^«ÿGÿ“ø›ÿpÏý:ZW•~Ô¿ò0þÏ_öW<=ÿ¡ËR÷FÐød}ÿ^UûXÿɬ|dÿ±3YÿÒ«ÕkÊ¿kù5ŒŸö&k?úC5Q‰ðÇùEî™ÿb·‡?ôm•~ªWå_ÇùEî™ÿb·‡?ôm•~ªT£j»¯@¢Š*ŒBŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¿<þ4ÿÉäüQÿ°6ÿ ]×èe|³ñ»ö2ñÄŒ¯<-ñ.É«iövw¶7ž]H3Û™B:?Ú"Ú Ë‚¤A;¹|çeµs|²® ƒJRåµïm$ŸDÞ˱ò\W”×Ïrjùv¥9òÙÊéi8ÉÞɽ—mÏ ¢½þ?âým3ÿeÿäê?áƒþ'ÿÑvÓ?ð†_þN¯Å¿âæßóöŸß/þ@þzÿˆKžÏê_øÿùYçÕÃïù;¯€ÿõÿ¬éžî½þ?âým3ÿeÿäêè>þÄ~+ð_Æ?xçÄlüQ†¦ºš:ßÂÿaiZ{I­ïEܘÎÝ÷vãŒæ¾‡x+0Ê3:XÚóƒŒy¯g+ëºÅ-ßsë8SÃÌ×"Îhf8š”Ü!Íu&õ„¢­x%»ï±õ½Q_´ŸÐÁEPEP_•¿ÿäG—þÃ:Çþœ®kõJ¾#‹þ íãMçQƒÃŸmtÝmBîòÖÎó u4 =Ä“liEÚy„ݵsº:WÅqfKˆÏp0Ãa¥%5/y´¬”—DõÔüóŽ8wÄÙu<QŒ£5/y´¬£%Ñ=u]Šôø`ÿ‰ÿô]´Ïü!—ÿ“¨ÿ†øŸÿEÛLÿÂù:¿(ÿˆs›ÏÚ|¿ùñø„¹çüþ¥ÿOÿ•ž}^ƒûÿÉvøíÿ^ÿÐu ?áƒþ'ÿÑvÓ?ð†_þN¯Vý—ÿeýcà‰f—ðãè®þ"9—ÅÝ”£4º)*zôèø¯9ý»|S¥øãïì»âMnëìZ.âgÔ/®|¶“É‚+­:IjÍ…Rp “Ž5èÞ4PÕücàºi¶·Š]ÍÍõ¤JÀ\Ç!Ú0÷@6d°À‚~¤ðçÂüPûGü&^ ðÿ‹~÷ìŸÛº\¿gßþ_š·vÄÎ1«ž‚µ†Ç¡”&©Jý×äŽþû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ­tò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ *ÿ‡£þÌ_ôSòªò5ðôÙ‹þŠoþP5OþF¯Uÿ†Nø!ÿDoáÿþö?üjødï‚ôFþÿá/cÿƨÊ¿áèÿ³ýßü jŸüGü=öbÿ¢›ÿ” Sÿ‘«ÕᓾÑøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªò¯øz?ìÅÿE7ÿ(§ÿ#QÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj€<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ Š¿o_Û×àOÆŸÙ;Ç> ðo޶|I©}‡ì–_Ùðyž]ý¼¯óË ÂFç–Æ$ Êý©¿h†qð_Tµñç‡õKMâV‹«ê?ÙZ„w²ÛÙÂfif1B]ʨÇE'$’@¯º¿á“¾Ñøÿ„½ÿ£þ;à‡ý¿‡ÿøKØÿñªV-JÉ®ç•ÃÑÿf/ú)¿ù@Õ?ù¼ÿö…ÿ‚~ÎÞ9øñ/Ãz'Ä?¶ëZdžu=>ÆÛûQΞ[Y#7=¸UË0bÏ$ úWþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ¦Aù«ñ§âÇõ_ø'.Ÿá«/x~óÄká½ÑíõHðI–fD0‡ß¹B6ጧ= }«ÿGý˜¿è¦ÿåTÿäjõ_ødï‚ôFþÿá/cÿƨÿ†Nø!ÿDoáÿþö?üj’V.Ræ<«þû1ÑMÿÊ©ÿÈÔÃÑÿf/ú)¿ù@Õ?ù½Wþ;à‡ý¿‡ÿøKØÿñª?ᓾÑøÿ„½ÿ¦Aå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕyWü=öbÿ¢›ÿ” Sÿ‘¨ÿ‡£þÌ_ôSòªò5z¯ü2wÁú#ÿð—±ÿãTÃ'|ÿ¢7ðÿÿ {þ5@UÿGý˜¿è¦ÿåTÿäj?áèÿ³ýßü jŸü^«ÿ ðCþˆßÃÿü%ìøÕðÉß?èü?ÿÂ^ÇÿP•ÃÑÿf/ú)¿ù@Õ?ùøz?ìÅÿE7ÿ(§ÿ#WªÿÃ'|ÿ¢7ðÿÿ {þ5Gü2wÁú#ÿð—±ÿãTå_ðôÙ‹þŠoþP5OþF£þû1ÑMÿÊ©ÿÈÕê¿ðÉß?èü?ÿÂ^ÇÿQÿ ðCþˆßÃÿü%ìøÕ|ûU~Ô ?iOÚŸöJÿ…qâoøHÿ±|gÛÿÐ.­|Ÿ:ûNò¿×Ä›³åI÷s¼ã#?ª•æšOìÉð{@Õlµ=3áGôíJÊd¹µ¼´ðåœSA*0d‘cYXAŠôº+æï‹ñãâÿ÷.ÿöjúF¾nø°®Ö/§™!K°©½Sqù°71 >¬@Ȥö0¯ü)ú?ÈüÂø¯ÿ#þ©ÿl¿ôRQ]Ä믋ïî·èÖ~g—û‹¿é©*â5¯Ú8Î3ô"ŠÁ5IZ^Húgâ#™|QðýÙJ3K¢’§¨ÿNŠû?áüÅ¿í—þÏ_|Ds/Š>»)FitRTõéÑñ_VøGÅßðŠý¯ýí^~Ïùi³nÝÞÇ?z®žÇvOü)z¯ÉÍEyßü-Ïú„ÿäÏÿaGü-Ïú„ÿäÏÿaZžñè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè”WÿÂÜÿ¨OþLÿöÂÜÿ¨OþLÿöè•ówÅøññû—û5zoü-Ïú„ÿäÏÿa^UñóûC@ñ-ÖÏ/Ï·¹—fs·r±ÆOc Gðgèÿ#ó+â¿üú§ý²ÿÑIEÿäÕ?í—þŠJ+l|Í/áÇÑB|gøÅ¡h¾*Ðí].æ¿Óì,.ÈŒÀ‰ãb»ˆÌmÆG8=ÅfÿÃe^ÿÏÞ¥ÿ€vÿãER§h'ÕÒÙ‡ü6Uïüýê_øoþ5)ý°î Ótìêw×n“=Ç—eØMÌÞZœ€2!ò~îG¹9¢Šfܮֿ{"ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆøl«ßùûÔ¿ðßüh¢€äÏ/½‡ü6Uïüýê_øoþ4Ãe^ÿÏÞ¥ÿ€vÿãE#þy}ì?ᲯçïRÿÀ;ñ£þ*÷þ~õ/ü·ÿ( 9óËïaÿ •{ÿ?z—þÛÿðÙW¿ó÷©à¿øÑEÈÿž_{øl«ßùûÔ¿ðßühÿ†Ê½ÿŸ½KÿíÿÆŠ(GüòûØÃe^ÿÏÞ¥ÿ€vÿãGü6Uïüýê_øoþ4Q@r?ç—ÞÃþ*÷þ~õ/ü·ÿ?ᲯçïRÿÀ;ñ¢Š‘ÿ<¾öðÙW¿ó÷©à¿øÑÿ •{ÿ?z—þÛÿPùå÷°ÿ†Ê½ÿŸ½KÿíÿÆ¥öúK2I©ßIu%ì»b[(wGn!ƒfîó'žF >¸h¢¨µöŸÞȿᲯçïRÿÀ;ñ¨o?këBÒ{[‹JH&FŽDû%¸Ü¤`ŒƒéE ÓoG'÷³À¼m®Aâ_ÞêV©$pM³jÊa„U9Á#¨=袊 ŠQI.‡ÿÙ endstream endobj 2797 0 obj << /D [2795 0 R /XYZ 89 721 null] >> endobj 394 0 obj << /D [2795 0 R /XYZ 90 575.694 null] >> endobj 398 0 obj << /D [2795 0 R /XYZ 90 504.487 null] >> endobj 2794 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /XObject << /Im15 2789 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2800 0 obj << /Length 2699 /Filter /FlateDecode >> stream xÚ­ËrãÆñ®¯`ù°j‰Á•ÊAkk7ëØñFKW¶ 1á%€¤Õ!ÿž~Í€@Y©Ê…è™ééîééçP-îjñáêÝúêíû4Zä~žÉb½[äj‘ªÌWQ¼X—‹_¼oÿ~ýi}s»\±òb¹Šå­—yè]ÿóÃOË0ö®—ZkoýFùt»Œ”÷Ó‡Ûë¼¹ýËgžýðóÇïn–¿­¿û>Ü"ú*LAb–…ˆs¥Dº·ïµb¯Â8ðƒ$^¬‚&CÞÔ™~m¾ö¿ªX=øè¿"•ÅJk?c÷%äÿüÉ’ãm¿7ë«?®4€j¡Q9IùA-¶Ç«_~S‹æ¿_(?ÍÓÅ#aažù±J>,>_ý‹•<:¶V‘ŸGÑ"ц ó¿>–++ïPu½©MÛñ°ªù»^fÊ+ê»æ¬pZ>žæhꞇýÞ°žÇªÓIèg 1QôÇ›¶mÚ„ÑÌÅd±§¹E¯êÞ´»¥þ[Ã|÷ÕvÏ`w2ÛêW¥Ó½,\¶Õ Qƒ"|»‡¼;’èæBW¦©È£+BD=#­Žü(J,á£é÷M ¦‚Àë}Õ± MQ Øï‹ž¡•ŽÀ@é4ßvM»5¥lkø 2—Y§SÈ&¼)üvÍQVIgOTìG \¥ðDBü 7–øæw³íEfÇ_ðÓ@L&Ñbž«N3¡SY#”+쌳۵Íñ|­˜¥Ž½¯ž ›çðǼæ*8£³œ¸ôÄNVì^4oºˆŒ*Hs?É¥~Ûp;hÙ3‡MR?9Û à½H:Tx%ûºïÛjsß› ´Á\SåäðÙˆ£îmlÃp} ÜÞëÉ<lEס>Ã0K©z^á  {ÙYlº¾-¶ý`ë¬r”ö•Òî7u_õO—”“ûZ¹!þä]„é„9ú J‰W7k Úoj>z* g/æµ»¯·}ÕÔÅäX®"xÓ?’±E:eJ8ëTƒ³è›øs¦r«>7Íè÷vÎxƉÅ%Ú®;P¾Êâ‰%½-7íÓ\ˆïÌœy€ÑGqv‰ö*R¡Ÿ¦zl Τ.3Éc°X=`BQ…ïÁ „†J0˜e`}P‚ZÎ\$VÊÏÒ©]ˆoæÄ rÇ#Çá8:¯I ‘ÛQÿΔp€SCßÌQ±¯C—°Ä†¬‰Ì¥-(Ï xC¨RQ7pÚb @ ßßw,ÅF„°æYÊô“EœO¤a½û«òèH (°¡ëônÎáxU»3/jãB+¿Ç„À|âLSP%¦nà;Sà4•]:ô6°¡”5¹ænå¡•¯Ç:$ ²3â $àðh@¥UG°à<Œ Ð~3°qƒö_¢<¥VW‹¹ˆq,zÌEPnI·æ®êÄì”I+‚ë6#ÎÔJÁ¹…,¬¤B…OköÒR¨†¡‘ÞN'Pá9³[C¼Óôx·ôû‘~ß-W±ö~&˜Wgßßàþœ©ü0à x{¦üY8Î<ÃÄCÇí¾T§Žȯ,p°‚BÑ2P„#YD]ÍqÃo/€DúÌ\¡ˆ5­ö£pRF`/õ7—êAêúVg0•_·¾Fæ›Éz/ÖsƒrˆªwX¥:׺ûíÖ˜’ †ÜQ^Ý„ds¬gŽ“Ö"S$w­ãÔÒè­H ×”LºÀÁ‡ïTr.z¦ž«›`l¸ÕÁ””êHйû¯ ¢‚"sŸüÚ®ç9Èw†ç{~r‹líK[¶&Ãó3qÐO§Cµ-°iêdGÃ+Çêë„õþÝ Wè°Š€Å’5Qm§3­T¿ÝLg&Yõî +òʆ¿Häµ0ÏöMôn- ²ÆY‹‰\`¥äŸNH×BÓâuT›!´mJƒòÐaRgŒûz°PÚ’ÂdÎhzÆØœ!!÷Lú”0ÓîHÙsSÂeL¸vjº®Ú`‹³$ÍcE¹ ›½kÄ’Àœ š⸗mÓ˜Á‹ÐßíA05Ý÷KÕ}–¼pÙЯk«H•Àö¢£¤0ë~Ó4'ê×q‚… ôs‚!e8ZÇ'g ês–`8 =0E5ñ}Ž9‘˦5˜ã~nþñA²Ur¶C r/GÎãó`ÒÔ%MZiPeQÉâ3ƒóߥ` Eå©Jȇ!pj‹ï(M¤{ã2Ò £±ÇWñí;|õ/(õ†Q$šŒ"{aäC‡Ë|‹nèù(²^EÏ.¦äšOòb3bñÈM†ìÆDŽÌ -WRCu nÌKàžíŠúK7Éö}hüwÞôn䟒Ék”û+cÖ›ÖêÔÌÏâçÏëŸè¦/´*ŠŸ> endobj 2801 0 obj << /D [2799 0 R /XYZ 89 721 null] >> endobj 402 0 obj << /D [2799 0 R /XYZ 90 582.533 null] >> endobj 406 0 obj << /D [2799 0 R /XYZ 90 467.988 null] >> endobj 2798 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2804 0 obj << /Length 2742 /Filter /FlateDecode >> stream xÚÍYKsÜ6¾ûWèNU†!@ðµ7Ù²í:±KžT*ïR®gÈ)’Eÿ~û¾Rœ­rÕ^†@èn¯\<\ï^½Þ¼úá:1™ŸÅ:¾ØÜ_dÁE¤~`¢‹Mqñ»÷æÇË›··«µŽ/òWë(¼Í* ½ËŸß}X…‘w¹RJy›ñ”·+xÞÝ^þôÓÛÛï>1õÝ/7WoWÿÞüó‡ëHO¤úA˜€.$,58çU ÚjÁdòÚÎ^ëˆ!¯‰|ã+_­Ö*ï×]Þ³È]~<–uǦæoΟv¥R¯¼çO·s(\¬UêÇ)ËøuWÖJÇ~l’ùQ–£fµ<‡¢¨[û´X?3f¾”L}­¾k{ðÚ’@‰­Äãsݬֱ¦_åÝRû†~_Jhï¢óçÛ×~˜ G{íùa:Ø<(¥½7–§1Þâ|» ½ßÜCo`zoö¶m™£Í¬U†·ä² 2Çu£¡9$D™Ÿ$ñBÄf•"ë‡fDE\¬\´üv§»n ÌKîÞ7-7Ü}³ƒvÉw­C¼°—ï: 3æ|r¹rÚÈJlQ<ɼ›{C£†¨tì+„#dж۲,ºabm—¾LBxÃ9‡¼ý²R‡GS…îPxiœ ^Êê™¶’qß1ï{¡¬’# ñÔÇ#Dº! -…ã2T2¯ö€<L®+Ä•r…¸¢o˜4¹Â‰ü`._y˶jŠj˃3 `«&S¼U”±ØjäÚª†w0Þ öø^¤…py/8VÉìé½`?ú4€tv/aÀÊNdi‡zѲ2gúé…~Ž=Wâ¹gÚ¢:)|ñðñûqë±êwÍI`o¶©&™ç¡ï†Œ;ýä Œ 戓nÖŽ®ˆ°ý–ÚŸ¨ý£ –RßèÈrùD{€ ˆ`ÂÄx‡´/X‘æ~TÝœ@˜¢¦ˆl1w‰ÈŠYÿ"[Vï²0Üïf²Õƒ›Ç ø]œÚª~˜î)0I"…0 Æq ¸SÝ/Vó¨@#F‰>·¡paC¸p gîqP£v*ÄD˽«GðÿÜþRAÔYÀK‰ƒÌ{}²Sgªc<:áƒF0{b V¬Co¾~ Ž·srK„E¤ ãg = ü4Š¿­¡›‰¡+1t5\­qzâ› ý¿´ôÐWé$À³…د›nJMŒ‰ ‡8;UQ ÅÝ1IÀ‡ÃVnRG£¹#dLM3†Àó­(ˆSô·.°,„VVÃ^¬†è/iˆ`Ë)¼´|YÔòpÁv ‘9JAW©SoãgHY£o¼ÉPçÞòZ¾‹é±Úï%ã "_‹Œ§’¬´?µÒÂÛÚnâØ n-.gÁ§=Él‡ù“àƒâþáŸw|²Ð”›Ó¾ç6½IÊí…R ì†Ëä–3£TZùú+“µÌu2žx ÛrŠßsgîÆE±fP¢j­þ8å²â²%ˆÚ{uÙʪmS÷yUO .&4dpÕù±Û5=ÅŠo:²,‘º>§8šÂM>zu¦%Å+­ òÞ$Š)!F)…Õ]¹ÍOÌâkWC–çÂAk_ýRö@h z°k—ËŽÛr[NF1©ž¨¥…M3”0ˆý41/¸#Ì“LèN¡aD“3b¦14ÎY†ªFÑc=#ë3¿ŽS%ªÀW-ÚâÀìñ*ŒzÆ;&É}[÷ˆ þ€4 Ùߨs„:5÷²RñK̯êºÓìúï Lþ' ¡Úß²–‚™N!wVcUNKMnc9^Ñó¤úòz¶Æ4/¾ ËG ¸ÏY3‘ÍÚvǦ½IŒ›{Ä5Ý) @7«8tù& A~FE1R@ùó9¿ÃMÙc1BZäU“nKEE!¼ßg“ûǶùLëO!ᤉx—EYÌuHÅ(4¬¢vªxËÁÅ äpµ„^bu1ÒN¶\:^Wžï‰ OŽ“ºeü]a¡ª`±¡«3†À®g걩 Âprzáòô`C(Œpý¦`ªœð—Ùt6V߆4WŠ"D¯…ÒÔ„9!ÇçH™p ñáaèàqŠÃ‰Ç_Ñ“+ø¾+9k0V]L 㥨9à¾Úüp@/@dŽ¡ÅehH¶z]~(™4µšòMŒ8Á¶º+aÔ–Xpª0È…€|c=0hf² Ërlk”¼f y9œp—\Môõuf€ÙxpL⵩„–àVT[ó.[¡ÊhQrQ¦àYù]C¨C×HUºl§Úîxø³•ÈâîÔ–ÜêWÊ£@‡:;¡æÐáÞ²éIä§cY€Œä¹š2ÜV^R? ާ7“Äç®W‘€ Vg<×QÆ$âß§cÁEÐYDóט0mv^^™Wf*K"0§ãXg.Œ½‡½G¸ô3Ÿ5u sõ{Ó@ý›®¦“ðst.\öKY0†œùšÜHÚç_¸ÊÓùSóã…e³˜0„ç ½Âg˺ó:idò GÂgRY<Ú¶<‚®p5ŒÅA*§$gÙ Œ@Â÷1͉½›žGɹâÂ}×0eîfaˆ!Fr Øæ…Ã’δ8Û*ïÝM¥ÊWQ²øŸÆý¤xæyý‡Tf´ÆðÔPG£¨ö9莉%ÀçÏM{€×ýÄKaú §a hJáÊE˜B1EN•\Ù0•âHae›³ˆ'm÷y×Y†EawÏ%‰Rëp6GˆÇARÁ-*DÎ!px”ªäQÿQª]Úú…·³¯¶¹TØ0wZŠÒUa'‹ôü™â”ß­¢È“Y5­ËT嵎 (rf2?QÓ… ̾¢0ûÊU™Iý$Ìž ³!Íâ0Û L)ÄèhR˸ּˆLôŸìËôÌß¶N,Ò"í¸ÉÑ Hy-ÈÛSó‡mW‘&Ѐ§ n uèèy›ÑÂh¼(÷c׋xy­$³ëÛÓ bÍ‘tûEæ4³¹jŸŽ ? ,5ž@~±jïÝ?Nœ[4üåp Æ-ápB·N­¦¸óVæÝ·ÍÇ'eê·6–è–²ûy@˜sWÓ7\oÒú>U,î¨g[ªœ|4ܧM`ì¿Ãsý²'u¤`Ñ‹¦Ú}}îufU¤òAF­ÞÝ$€ûâ…Ђ.ZLçŸýKFkOÇcÓNGR·ý¾¡ì`LcžŽe÷EÞû&LçÙÈg­#WZôir^L§ž[ù¾á²ÑùÂðå…WÍI,f±ß·›Wÿ£ endstream endobj 2803 0 obj << /Type /Page /Contents 2804 0 R /Resources 2802 0 R /MediaBox [0 0 612 792] /Parent 2809 0 R >> endobj 2805 0 obj << /D [2803 0 R /XYZ 89 721 null] >> endobj 410 0 obj << /D [2803 0 R /XYZ 90 690.045 null] >> endobj 414 0 obj << /D [2803 0 R /XYZ 90 453.569 null] >> endobj 2806 0 obj << /D [2803 0 R /XYZ 90 417.544 null] >> endobj 2807 0 obj << /D [2803 0 R /XYZ 90 398.011 null] >> endobj 418 0 obj << /D [2803 0 R /XYZ 90 300.911 null] >> endobj 422 0 obj << /D [2803 0 R /XYZ 90 206.442 null] >> endobj 426 0 obj << /D [2803 0 R /XYZ 90 135.137 null] >> endobj 2802 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F109 2808 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2812 0 obj << /Length 1149 /Filter /FlateDecode >> stream xÚÍWKsÛ6¾ûWðVp¦b’ÉÜÇvÝ&ŽÇRNq0‰lHBÃG\ÿû.@"eÚªít¦'‹}|»X|Xagã`çâäÃòäÝy:‰—0Ÿ9˵“`'±‡Cê,WÎ7túÛüzyvãÎ|ŠõÜe-Ý$@ó«‹/n@ÑÜ%„ åZåúÆ 1úrq3ÿüùìæ—…–^|½üxæþ¹üýÝ9õÑBx8ˆK,¦Jçtö×™ óh’83?Û@kßúþXßù6££E[çÕf¼ƒ°>}ÞôkÕä›J¬4êӌׯróAÊBðjÚ–½Â"“uû* ç…äíO(Â'©k ¶Ì ƒxìcž¦²^©r÷Ê­Ô¿K7ƈWóÙlEšßbì§¼ÍeÕüªÅ¼(ŒY&a–[Ñèe ìwfO®wêz±–E!]Ÿ¢û‚µ¬KÞ6ïlj 9€EÊ 8wèb Ó$1 ø‡ Ê‹N¼ªÀ (G[wåÓþy]ó‡Wù¾,ùFŒ·÷.âéU^ 8_Yñâ ÔÁ›*»„"Yƒ.c¦ðŒ¢†W>…÷碤y¹-ò4o\øR ¢A+ xv3ÞhãT–w¹î6FMK CU])ê<5RÓ Ï«¾ÙTøªO˜%h[CU­nØ1Þ¨AØ{-û\U5‰—PSÍLB  Hvw…Kh€íÂ0B '±@k*%§oš(ßgyšiyÆ«U°Cû´@Ê[ ¬;×Ǩk…ÂkcòP`‚®ºòNÔ£æ pdÄÊt6•˜m5sÖ•¹ÔÚªï-¸ÅWÓw¯QDdúªJ0Ë•*–í7¸áŽùò<¼OÓ~„´ } tÛËÔ =ê¨=†^ÚÛ墆\IŒ ’Ð…ˆJ7öX¬íL÷ÕUY«;t n•×^’Ò*Òߪ‘Ë€yuœv E½Vw‚§â€}'?¼`—£ƒÛRˆ$¾}*5ÎVT«f¢ÀïE³º&Ę. Ø¡GØŸ[4¶mžÁSˆ½Ot$¥á$Ý©Ï{qþ,0ΡTÇCS—é™cÕ€MEy4yQX½]¯uu5lȧraj–ì¢ÌG­þ8ØŒø> endobj 2813 0 obj << /D [2811 0 R /XYZ 89 721 null] >> endobj 430 0 obj << /D [2811 0 R /XYZ 90 440.192 null] >> endobj 434 0 obj << /D [2811 0 R /XYZ 90 285.462 null] >> endobj 2810 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2817 0 obj << /Length 1062 /Filter /FlateDecode >> stream xÚVKsÛ6¾ûWðVp&D@à#7%Q\·I“±•SÒ,A&§©(§þ÷ÝÅ‚²¤rœ\ˆÅb_øöŠè!ÑõÕÛÕÕ륌j^Y­¶Q-¢RT\H­6Ñ7öî÷Å—Õò6N2%˜âq¢ ÁVq³Å_ןã\±Eœ¦)[ýI"_nc)ØçëÛŧOËÛßîˆ{ýõæý2þ{õÇë*;ñ&Óœ‹¼„X¼³ª@™+¢›Ö(Éë‚«ºŽ’¬Ýœ¤¿g™:“¾%Jv× v‡ßÛaè  ñöÙ¬æ×Þµ½ÙP¹¼k2¤ª—ìå³ö Sd€Rúqè^0¿bêýp¸ïÌÑX˜‡t²œuÚD?â‚9%ù;ÓcªýÕa«ï‡8Uì?Á†Ïð‰‰dÓ‚’%ÝM#Óë¡uÛcÓ-ŽJûYœH,Soš–ì»™böŽ’³b t¾:݇¤iZºÁ»j9ÜxÄ‚Pp d Œ¾Î@ìÁØñНhoÛ›õØÆÙ„M÷ŠùŒE©äµ”ç.é; ‰ÉpôXÜÇ™`‡Ñ`Ge0é:ë;cÛ5‰Ny²Ñ¨qÌ pîéIâÆ©G‡vô¹”8°u‘"ÈWÆ‚ïà‚Z™\8²7YNÙNoÂa׎# H%7sß í~ Õl«-ŽB‚9ð×ÖèqÊFHAÓ«íº‰ ÉAZ ·“‡cÂÖÃnéwœ&{)N&;ÔK3{j-Å%/x'©€–Z>b!CịêZ7šFÐÌ[Xñ¢:é°ðž‚À]Áö€së:‚¢9t££Ÿ¢¸6¦µd>§öSUñªL§·èæÖk ÍTÕ¼€·(ÈûÑœCrŸŽ~ˆØÁD Ñ!ªÈÒsþ+Å‹z²FΗ€ÑŒçBñR=ãã! ÈŒYx;aS–çÕòóÛÕ9—ð|,íAvãæœä’‹¢8B·´v°/!—C¯>'Ó ‹1õõ——5{l –ïÿzUTÈÙNžS ‡®݆Â+ܠеL·Oëê…&HÀoHVJèÂ~ãÇU‰Í Á×9¯$»ˆ©i9 ÷¾eJùÿñ°Ýí;³ ûKü½&Ì c·Øz Î(±–”§î¸œÈíèLºV»³‘l/}½ÔÍa8‡©ÑL¦¦ñáž1;U—å³ÿo—ëruõô^½q endstream endobj 2816 0 obj << /Type /Page /Contents 2817 0 R /Resources 2815 0 R /MediaBox [0 0 612 792] /Parent 2809 0 R >> endobj 2818 0 obj << /D [2816 0 R /XYZ 89 721 null] >> endobj 2819 0 obj << /D [2816 0 R /XYZ 90 622.135 null] >> endobj 2820 0 obj << /D [2816 0 R /XYZ 90 604.267 null] >> endobj 2821 0 obj << /D [2816 0 R /XYZ 90 582.284 null] >> endobj 2822 0 obj << /D [2816 0 R /XYZ 90 562.359 null] >> endobj 438 0 obj << /D [2816 0 R /XYZ 90 476.057 null] >> endobj 2815 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2825 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ]Ž9Â0 …÷ü o$©Æi:zp¨%Lˆ S…øÿ =@B•%ûéùIïCxB%ADeb!Õ©3ÂR„½FËîp‘ËUvE£æ†Q²Vsv(ƒJc™íª½ŠYfŠˆdØŽ‘C£,Ê}Õdu]4³ÓèVçu^¨kØD%›¿6K±Æ8éX†2Ÿô_ºé-‚ N PiŒÑän­x ;øãŒŽI3y?æÉjcØýÞѺ%ùK»™¶|Å›;& endstream endobj 2824 0 obj << /Type /Page /Contents 2825 0 R /Resources 2823 0 R /MediaBox [0 0 612 792] /Parent 2809 0 R >> endobj 2814 0 obj << /Type /XObject /Subtype /Image /Width 412 /Height 422 /BitsPerComponent 8 /Length 54889 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF  ÿÛC     ÿÛC   ÿÀ¦œ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?üÀf`Œ:9ªñ±ÈPp}1S˜ã9¾5Y˜sŒó^»8âºW ÇMØÀõÁÿ ½&ô’ÏùïYšAÝ0Û†!9ç¶+£Dä´Q¾GV€Hê3ßÞ¼ Wñv‚ýÔYÉH0ÄzôÕéíÞ¦¼\\J:üǾj •±ÚØýÙïš@Ü`zSsŒZ^œÑ`æ/iןfrî·C[*Äç¾+›Ý‘šÔÓ/÷2Ã3|œ' ö¨k©œàž¨v¥`dE‘9lüÀV9ô?•u†,‘F@sYZ®–#ýúr:²çBkaEÙXÉ'éô¥w§Ò“8™wÆz¨ÏaíZ©hL•õ>iU2¦ {õª²|²{~5Ñ.ÔHœIˆÇ>n;÷¨N†²d\ç“°ÿñUúT§||]™GCî¿xÀ ‚Iã½v) É;pã²tÝ%-'IÆpFzúýÎ+l\rJmÉ<JòëÒ”çÍObŽ&”i¨ËFŽ/RO.þuãïg~j©ã¥lkö›Ã*+Je=¬Ñkp<©wÁMs¸¸é-ÎèÎ5#xìWéôÏùëJ3¾ŒÒÖ2G žô§¦3ÏZ‘Æ2Äv¥Æ–úVÖ'™ +ƒÎ8 dã4à¥ñ…föÆÏjj’ë‘Ï"‚¾Àsô¯ÐØ\qŠ‚>lškä¯9àçšjM ÜÊì›ÌsŽ8書žœ{Rο­.:*Í»plL'ÿ×J0£x¤[Ðnâ“¿ó§7@3ÅPzf #'Ê‚yõ§„qIŽÔÈóŸ\R­.:žô›q鑯»‰ÔäóM'9æžHÇð¦žJ¢X™Ï„c4RœS3bté[¾ ‘—ÄöOV öþXc¯·à•2x§OóŸûäÖu~ z37±ìðã Ôó’x¡;{uÇáþ"Å€NÆ;ô¥G!ß·å¿=kæfM•ñÔ€I¨¥Œ¯®sÇëéO(ÃsŽÔöùO¡â­X ’-Ô7ÝpFj¼’äg¶*ìÑ&8Ž W™6—%ŽñŒy£Aîlx37ˆñn†Bp9Ww ¾ðl.èϦ>RGù÷®KátQ§ˆf/˜>É( éò‘ùW£ÚéÌ];£ÎFyØ©®*Ò´ÎúKÜ2ÇiE ¸„\ç }ãÓüúT·û 3 3·ëÓÚ´Ä7Œ”‘Q0ÎGÌy«3dbñ†#{¯\ŸZØÝhŠn˜³ÀþZ„Í}Ì@$0=rxþ´º\Ígîø›j„`ØÇÌ3Ÿ^õ§%½œŠï# npcŽ8ã^~”E¥:ÍQpÛT/’ ÷á€is2yS܃œ[j©gssr˜.L!e)<äÓÞ¹±f^C¸†\s׌àWK%¿“q'Ð`]¼pjeLcûÝù¥EÊŽ;Ô©Æv‘מÕvÐDR«¸vëïõ©QB†#·lÑ:ˆ;)äŒ`㌒›Ù…y˜vvg·„Ö’0µÍ#j¼ñ:°#‘žxâ¹ù!x=¸ë^’!!Tì?7 ‘€ErÚÖˆº|žp¹sÈÀãÿ­þ{×VÝÈÇ·ï sO ç8àŸ\gŠT/üjËÂã#ôü*´ÈXî'Ÿ~‚»Õ‘æ§} C ÇËïÍMþ\¢Hòy Š«î'1êAþôþ7mP0¯Ìì5tîŽÓH¿P€«efU·ó{ŠºÑ++FÊrWm+ÄÉ*|®…HíŸóýk´Ò¯ãÕ`²Œ†LŒ}{W‰Š é{ñÛò>‹_Û.Iî¿•Ö4©4냅2@Ãåqž;`Öjä0ônÖ½{4¸‰à‘7D縜Wªèòi—A‹9ó÷‡¡÷®Ì.!MrKFpc0¾ÍûHmùT‰s€HîþtD§Óž¹#‘þ¥(ùPÔŸJw—Œ|½209éimO*í ª—9 ’ Î:R»ò‚ çŸþµ,@³’p®Üÿõ¿Î)Û6«0=GRsFì'~äyÉnâG }sN Ë»€ ÿõS²7 éÇâ?²öÛÉ Wu¡S‡T‹öµ#ª“!0©l‘É4¦Ü"£ Çò:”.ÞÍÆsÚœè\ ¶èzV¾ÆŸT¾â=½[üoïeo'å;•Fni<à§sÚ¬.Whä€pîjBªí‚qÎr:TÊ5öWÜRÄVZs?¼¦ð` (aÇR?l l¿ýz°S$gG·†%æ-órÊ£ØÁ?…}Å*õZøßÞVh‚ç*1À'ŸÒÂ7´ãÑzÔÅJ’GÞ1HCàðzã½=ùP,En²y–»Žáô¤1aN9Ç< ”ÌFqÇVˆ¼à“‚;Ôû(*·«¿3ûÈ cqOša‡§lŒÕ·Œ—vãΡo•˜)ÎzTºTïdŠöõ_Údi˜ÍŽ@éÜV¯‚þ_iùbyîŸJÍ$±^}ù5¯àæĶ I Iëõé\ØŠqTg§BáZnI6{31 ´`ŒtÏ9¬ë™YX€H'ÔÖ¨*ñ”Ü“Y·Ÿ9ÀÈÇ?Ö¾I&{VhrNFáïVÊrXÆO#ùU{X‚0Iã pjß–xÎO¹ãóëNé½A¦S›$`98ç9#ôªî§9c÷ŽI<þ9æ¯2‘!ÚÎ:Ô~_˃œsŸn”öØ6:Ÿ…17öýϔŜÜg`ëÒ½RÞØ#ŒŒaÓi#Ÿ¸qÇÓùWœ|'…[Y¾ÀçìRäuÉééúW¬¬{'}Õ‘A$°O?‡ò¯/ÿxzT>a\ -òˆd `î=*i"+&8FàI5*©Ü¼6 Çž*g‹Éçnqß“þÿÉçlÞÄPéitÌ(‰ú‡|ÆÞçòÿëÖ¥¾™q ÝÚ]#ÛßDe…™á-»£ žuj¼Q"™Wd ƒŒóéZz^“}=Úý‘%yX.ƇàuÎøVѵ´WdIk¾†?‰5'Ôu««§Ë#gË]ªnÃ==³T–Ô© Žƒ³ÓÝø¹î´ñg±ÍŸ3I¹òÙƒ:† ¹ÏÝ8'ß­E‡õ(R9¥³O"îÙî‘ØžZî€ìAVÀ<ç·J©Á§ewßCh ®öõ<âêÌý™å1…O–1ƒèÀŠH홀s#t]Ýý릚Ð\h–òÈÜÀ{1ÁMÙRyÏRÃjè´O[ø‚ËíSÞï# HÉïÐRë×ñé¶1M&|¶˜'ÉÛ œóô§D»gÖ¼œbj§È÷° J¼Ëvò—VÀ䃽YŽ$¹dƒr7Tl*­»cqQƒêzbµ-œ:ªŽÝ‡® Ùž²‰Àkši2ä®ûwkc€yãô¬&\`‘ŸNŸ­zìú|:„Aqš6ê§ŒzòkÍõÝ]"ðÁ  &6õïô¯Jž6IrµsÍ–_îŒc€ÇkqƒRÆs–#Šc®鎼SGc“Z}iö3þÏrìJ[j–Ï8«¶’i޲¡è~ecŒŒô5˜¸ÇÓ¥M–Â…##¸¨x§%Êâh° -IHô=>ö=V×Ï€lá‘{}õ„W¶ÍÜgs¸{áô›÷Ò®ÖxÁh×;ÿçµwö—PßÀ—¨Çø±¸|W“5É.hžÔ-QrËS‚Ô,M•ÛÅ)_” 7@Ýò3Ö©˜%A'’nkÐõ]&-^Ód¼HPã¡ç¯øWug%„¯  †°qÿׯNù5f®Yïì"ª‚ 2düfžv2”R3Ž2{Ô £æ;÷+C•.NâF=8­þ»&¾¨C~añ£}ã¸ç“œÿœSÊ6åÈçµ2E-³89îœÓ"3ßàÓYƒÙ6ŽR¦®çø6+0ã#Žƒµ“œŽ{÷ª½€Æ{â”9{ ?´eü¥bG¤ÿÏ”ØÀa¸tÇò)$û„*’21ŒsU±“Ž2=)˜#žÿJo1wøb¥öÿÌ€²| ƒ’@‡sN¿•&“ɽW`H$úr ¶~÷lrx£ëÿÝüIþÆ]'ø0òºãïe²G5 È&ç$tÔ׸|2g_Ù r6—ÆûmÅtRZ¬©µ€}ür?Ÿùõ¯>YÅ¥ËÉøÿÀ8åPms5³÷µ±ÐgÿÖ¨£1ÈÀ¾‰}"0CF GUíü¿:H¶*30Ï$ $ýsMg }ÇþŸÔÿ¼|ðX ¼ £®yüj0Û`Žkè¡ÙHŸ5¤$®q˜Áþ•]´m=–,mŽ û±(þŸç𥛯[ÃñÔÿ¼x#ê3×¥lxYóâ-8y„·š$ׯI£X lm˜‚>Rþ¼:ŠM&Ê$Ü–6ÈË’®–êéÈÀëÀ¬ªæŠpqPßÌ#…åjWؼ3 Ê©ÈNRD˜a¹}H­x¡Þ‘Œ/N´Ù,¦PH œ’{uÿ?þªù5${”cRŠzœ`ž‚¥+æáBƒÏg>ÞÕ!ˆ)ùA “€;Óž6N¼ßIô‹)ÉŽ~_cÆ*&`¤c‘î­Mp¥yÈëÀªìÃÌ#9úÿ:»“n§ð‚0ÚÆ©!-“8Ú=HÅzÅ´?éê3Œ2Ý×—üRºž²ÛI"É—¯<°ëkG}Á\îÁï·Šò«¿Þ3Ò¢—"1ãˆa8 ƒ>œõêwAóÀ9ä|ÝZP«ÀÈ\($ñÛ§Ó­I"†¼|È «õƒ:Ò »e¶€Þ™Æ9­Ÿ iø‡[ŠÊÝÊù‡ãRûLä€{V5ÜE’L8ù˜t5¯áO^xzøßé÷g—x]áAꀃŸ×Џ¾ær¿MÇxœvG¼f‘¬ç¸Ž9˱. íÏ¡\véÖ¨6£5–%¤RÞ<¦3<“n“fs†ÀgµAâ]VK½F¹w3Ì<ã.Ìî䳞§úÕGk»x„¢*O0UšbOÌ;tùëÉ­›rNç4¡Ójæõ—ˆ,î|âæxÚi#’9.™b»`¯€‘ *NÐ{cœÖ}ωuåÇmCI±P.HÁ=NOá\}§…àKý.vº™m LL.Ÿ|y.ÛXÐ èw޽«£mYI€0NK{œŽ¿çÞ¯šßáK–çÈ‘Ä÷ÿœU¡-÷h °@ ÜúÕ€J0.xãúŸNõúÔiŸØGìžžõ"@je\0 »O<*`UŠŒò8#ŸçZÙ%dIÊ|B·ß ) r²«vô#ú×3á_ f—-¶&?$Ÿ”újíüg›Ã—8v€àu={~¿­ydP2äìžkÊÅÅ7iÆ›xw=]Q³Œm#¡jÝ@'’:çŽ+“ðƼ3öK«€ÄàFÇÿ²úõÕÆqÉ#¾ìׇ=7>•#ZØ™pÚž¸ýÐÕmKK‹W³1ÏóóÇÝ=x4°6ݤ£×jý¾Ùá¹ëÍgèkcÌ5-%¬§{iÓ §ƒŒïíY_gXåÃ(=9¯WÕ´xõh d„qó#c?…p7ú\°Jb’0Œ§¿·çW;‚’Ѧ .Þq€jìI ”BÀó»9­Da1—V#¤S£VIŒÌV»õ1Ò/bÈ·ÜC^Ý#ù~u{J¼:Eך»|³0c9äþ•jC+d£®?Ï)Nƒ¦M+_FËtŽÒÞx® ÄÛã#!·ù?•SÕ´X58Ü”_9WÄãÙëXúf¦úseia#sÂ{ŽÙÿêâÄ„2È¥À~£ô®V¹Έµ$y´–BÞW“§IÆ)ó„ã8×üæ»]cFŠ…¸@NWÿd‘\»Ú:aXm#Ï·Ù ‰«œuh»Ý [(¦RYXàuèHö¡´Øxãå –õörÖ-ñ®ÓƒÐùþµbHþO›9ë\²‘ëÑ‚PZK§C´· r3œÑý|ÌŒ¡=«FH݈rÀ7\…§‹—8ÈèsØÿéPåe¹²‚ìe:œŽ¡Å,šl!ä$ûV„†$ÎG=é<¢€ ¼œ“ïSÍ'aò¤f¦› ¿wpn£ š‰ì!ÏG'‚rkQÕÂË`nÉ?çÛŠ‚HвîÆ3œóÏsV›}Hi'kÅð¾ÜEá+EQœÆNOÞnHíÔÖŠî§Ðô‡¹·EyC¨Pvœ|ÕƒÚ{]|É7’ª2z ‘[-? Nû0XÉcøÇø×˜¤u×Så«Çß—©ç_ðœëïÝceÉêã×ûÕü@Õ¿èd2rÖü¾þi’ÛdØ=óÚªKoØgÜué[ûU}Ãxx÷dòxçV ÍöKP¸Æœuÿ~«?õ9‘kç’ ãÕ„mãë’*»DFÜ“Ó5¯µW¿*!á×vt>ñ 浨¼3[ÇØÎ6dä u­Ë¤S®3ÝÅs~ w‰å 4p£ ü«°¿ˆÇ0ÁàòßJλWZt9ù,Ùv5ÏŽG989?ÏëN01Ðô4û›d€vëR*Àá²{׋Ìîu%¡LÛdŽ wëÓùÔ2A…b“ÔsZ†Fîª?ˆŒcñ¨¦¶`)ìóý*Ô¬+QÀåH<|§>•H[äí¼zÖôö JØÃgµT0d†6;}kTï¸Îëà|j/u 2Çì ÿã÷ùþ•êì¥nË•9ÎÏä¯4ø)˽oøOÙÔsß.+ÔòVl¹= ùp?Ÿé^eoâ6z¾c`œƒ‚ÑÃÿÕO2…ÝÎÑ OûDÿZ’Úœƒ÷0{z~Té´j¸À)ÿ‘úÖw5)´p’æ@Yv¸!=zóùÕ¸m‘•Þ¨”1†(çõÿ<ÔifxÚ$Iƒ¸çðã¿5£ghÄQÄ»™”îÏÉéJÓ¡0nbº½,Â6Ìi±7.K Ç=:õäÓm,eÔ-¢·Šâ9/ò/Ù¾}Ù a‡__ÃOXf²³’y $b=ê¨ã®Í‚02zöÏÓ<¥¥Þ¯mtRÐ-Ä×0´¥§ºò?˜`ïÁûÃ#¨àVÐ]1½îtÙÞǧ¯•=£ØÛóÈ&Oœœû²rØ'ÐŽ„YÓEŠãs=ÈÁÁVÏ|n{ó\ÔöÒËq=®èáŒ[ÂÅ•<À8ÇcÓðªÓM¬êR¼öÚ‹ÚBÄ……$ .8é[×RZ“GÎQFÛŒôÈ=ùèjR£p@³Î°©UˆÁÉ÷ç)C†çÚ¿dhø ‘Ä($q×§?çü*u‰XîÙ¹³Ï=M ‹nvîQÓñ©ßhØÁˆRHzš›v ™¾(€É Þ"¯>K§çÞ¼y–½¾úžÆè.109Àí^$p+ÇÆ®WÛËýèÉäÌLx`r=+¿ðo‰N¬¥Æ^ê5Ýæ ã>Ýù®Ó#¦j¹ S†¥y²Š¨¬÷=)PŸ2ØöøGãç Õ¸kq’?sñ:k–`K…½L†P8aýá] ¹2¹P?μÉ'cÜ„”×2êh©Â¹g’*޵¥&§ I…Ps€G§_¯8«‘8Gbãã=ML™8aGrsYô¹´tw<æçNá·&ÙW#ƒÇV[[á¶1ÆÞƽ#XÒÖ}Ó @>eõý+•»Ó<ýÅT,£ŽÜ¯ÿ^´G}Nfª+£ <™Kcp$–ª‘¬ŠtaëT¶õ*@=OjšÊ_²Ê§ï ӛݺ2T•õ.%¾ìtíÒ´t˶°cÀ·bK¼‚{æ‘dPèÀ«tÀëïOh†: uȬ¹´:ãI$nଠã ×éYz®”.Ï_;« ýà8úf“O¹Áa‰‰Ãá?áZžYRNìwPj.Ó3q¶Œæ-#nù€0íÒ¬”68ÎŒÖժ亽7üê²E°›³Ÿ§5-Ýô’ä)I ƒ†ÁÎi‚"Ž9ýy«’E„\ŽóÛÞ«¼@´âšZƒ|» 1—P¡í‚¢†ïÉô©QÉ÷©V0Ã<9Ï2÷têRÔ¦Ñ ãŽœgžMW0|Ù_npMh2e ßžÕFÛÀÁ ž„chÔ%cÛþØy¾‘È,¥W=Î[?çüж>_ƒ®ùÆÙ"çýµ©gØ7øFà ²2kcâí¯—à}Hª`;DèGïSüyj_íIyŸ%ˆV©#À^ß ÇN3ÔäU+„ÀÎ>cÓ<ýk³´ðŽ«©@$·Óæ˜ÝÀÎG·éXº¶w¦–[«Vˆ¨ ëTæµåf²œŠJç>ëó¶AÀûÜqPKߣg¿ùô«æ ì½é¬œäœñÏ·ùâ¡èÅbÏ‚ã â…701Âôí]®£h|‡ç'iîk–ð:øK¾fÈû;žŸOë]ýí°1:€ sÿ뢼¬ãèq4¹™CN‹|‚Ý5 mÈ-»=9'¯Oð«¶úhHBó´éN6Í‘µrÝŒŸjñ¹îok™æ Áíœ_óҘɜà•8äŒçÖ´¶ÒqÜñíI$;ÔHM5+ £î̳ž6àô'Ú¨¼'¾GSþ}ëzKcÎÞÃÿž•XZñ´äž¼Ö×ÓQZÇaðn?-µÃ‘¸ÃÐgÿ[üñ^–ì©)+Æ $uà/ù⸅…¢}PpDYÀéóO¯ê+¾ž69çt¸ã¶ê⩬›gu/…Ãjœ9†P28ÎÎqN#Ì ’2DkœuçµLP*±e·ƒ…阧ÓtÆ›3…ݱ·ó2²1’8çŸ_¯=3½ÊœãN<òvDZ}à°¸¹¹Hİ$4ŠäÑîãò£‘èkjg{yhJEhKJ’Ÿ8 ·^ž•RåÄ aQA¦ã·;ús“õÅtšo„®÷Œ÷lóLƒÂ§PšÎä[´S™ÁBq@¤à޼c×µt'Ê×::”ãn×0õÍiíüO›o)6Ì¥ü¼U@ÎyèN;ƒš Ö–rHïs©­«9°Ê²U œ)9Ï^õ?‰5»-3ÄpÙéN²j…^Y.>b`\mýØa€ØŽyÆ~\F±#ÏûD¹ò—&FÜÍ×’IÏ>õ«Ý 4† î#»Ž¹ÏZ˜Ê1òƒÏÍŽqš‘BðBàœgŠs&¨~LWìGÀ yu8ëúÔó·‚yàã¹§*'Á篘B¡#ŒŽß_Ò¯±"0$ƒ dçµxc1=@ô¯yò×ktÀ¯zðwM§äq^^9|/Ôö²ëûöò_ÛšŠQ¸t©cÜRmtü+ËZ¬“z3_EžŒ³„|ç;¶‘ø×¤ø{Z·Ö’M’/ÝÉÎIÏË–.6^G»Í&öPBƒ€ƒ¯çÞŸqòžp?OÖ±´ ~ß_±K˜N IÀ(ßá×…lÃ+´JóÚkF¬{1”d®º–vù°üóÅcêúsª5Õ¼~`ãzíÝ«Z á`p(kòNjzšÆN.èóÝQ|À%î3–üzVbݶÒ6ÿ\Šî5]$@|èp±Ÿ¾7t95ÌjZWüµ…pÃ,ã¹ïÓó¦§m:TEtVµÖå°ëò6žÕ°·îÅ~PÞýZç0ãådž: µ§] r±Ë÷;s¢›ÛA$öfáºrʤtô«š~¤UDW€ÏË)?§ùúU½Œq†Ô½yéšÍ´ú›{;ìter@SïT/ƒ/2(ÉÀÎ@¦iZ‰i<©É‘ܰRÇNkSÊÜ6È8Áät¬ÝÌâÝ7sžþÑ ç'cKý €a ÜO)ÉýBÀ@Þb*ù'¦?‡ÿ­ÅSa’rn0H¨ç“êz‘ä’ºE£}]¾Jg¦7` ¯ã`3Ð{oÍF±-‚‚ 9â£6ûò P;éR¦í¹ÓÉ«ˆ¯©m\mtäÿõª·ö‘*AA鎘æ–HÏ O¹ÇùéLòÈÆ@lùÇÒ¶S{³’p]ô÷ìÔÍ7….Ø•_ßdçž»‡áÿ׫¿> Xé÷6"Ò;¶P¤¬²`Ü8ÆN¼ÿ>+öoº[OëDr.Uyþñÿ?ZñÛíQüK¬Os,Ø·,JÇ·.Iãë]9e*r­:ÓÕ­½OÎóYJ\¶¥»ÿˆ:ÅÔÒùR hŸ ³ƒŒíöçÚ±u­^[iK™yß½—¿¹®†°‡Êã$ãœú«År­½‹Ü€pT®XwÈäŒzô¯¡u'-Ï $ŒÅeçÙ/] ¤—nG¿÷ÿ"ºi"VbUxëí^,÷á5dbÛ”6ô¯j²Ûu§Ú̼ï‰sŽçã_=£58õ=ì YN.èhøÝÏŠÔÉ6òuëŠôi`*²S÷pÌF厵Æü<·'Ævé´måÎN#üq^“.œ«nì0;ôà}+ÇÄJÊ>†Ò¼ÉáÓÔÛG£  nÀüÿýuVM9—‚À’O^zÿ“þzmX'›g2 ~*Wµ€ g×·?þªð®Î´9Ç´)ɦzþ}©l+ŒsÀãœZÝšÈãÛž*«Úî$í ŽÇ©ªæ \Ä–»h¯qUþÈ<¼ƒÇnµ·%°-÷W'¿r=)†Ãå=#'“Z© «?­‚KhO’Fw×eä»BûÎÂD‡Ôœêkžð-±D¾*rÅ ößÛüÿ*ë^EK25߉0üçý`ãÿ8¬¦õg]-‘]ãÚH'h qÿ|Ócµ[Œ,…Ê3"¾ÇØßwÔr8â­ÝMFùRsâOºÁã¯'½>ÖÒ[‹ˆü¤.å†_àÅe×CIEJ-Kb‰˜[ÙŒ/0¢G±™ =Ïnžù&´®¼@úg‚¾Ùgl<7ò ¶— ’/˜Ä‚¤ ÝÇâ84­žÐÀè"· ÒPŽrw¼c¿¥RÕm®Ž‚–ZAµµ¾žè$~q$ÖIA ¬{`ã®Ê5%N^æç›:pIÅ¥nÇ#qåÞjVú´‘n¶¤Q0q•›xíÁ,GO­6ørC}¦j:ήºœry¦Ùš|Agç<©+œu srÞX´Ë«k}@Ë{çݼQÈà8›äVÜ~_›'<7A‘šžûF²×– ¬Ù²HnYåH F,FÁÜI'ǽm~Y%-_õ©…xÆÊÏ•ùoèpél¶×©8‚bÍó‚¾ß0ç íÛ?ˆ|)¨4K-Õ½•‹Ì«¥ª[YÈPýÖXå•aÃcµmØø¶ó¾ŽÎÚÕäÕ¥vž-BöÝ%KDÙRvcócïc®qÕ¯¦šæ÷{3—šbÁÌ®z¹=ÉïWH«îvGšI-Rá~L€üà¾ø©A89ç?×éJÌ8¸ëþ¥LpOȸã8í_´;£à1e‰8éŽ@¢HÈ ¸ŒÇéV’¹ðqÈ~›(·Kÿ¯éU  †&Ù–ÊIÕýuâ7ö¤Êä˜1Èî–Ü(R¸*2N}úWêP˜/§CÔHÃÇZðó;ÅEŸK’B3u"û#®3šikBæØõ#Lã¿ë^œñøW+©éméáR±c‘ؘI¯uó÷¢¤‰t»ñ Êp„áO\f¶¶aGÈcrj¤ä§8þéæµôÍLŸÜÌãåèÌݽiÎ:Ý ”®¬Í+xƒ3ŒñžqZöwoîœáÆÿkÜûÿgXÆIžAl*Ù‰x=¾?s¹4í±Ö°ê­?2æiY0xÇ=ÅcÜØ›wÈŒséŸcZÖÓyêUñæ(ÉÏCô§yaÆÙ#ŽN??Z7Øãƒ• òÈÃ`îu$òMNÍŒt ØëÖ®OhbfR RÒßËÒ«ì À'==+ ´õ=´î“E)!ÃTã=sÇzCo·ûÃsZB¸d˜uìÎ)†ŒôéÖ©K£¤·=Çö|µ{Ÿ k¶ñ wÂarAÝ‘ø~•ó¬ê:^¡uдrC+Fà¶>pØaמE}-û5æ;lDå$Âcg“^âÿjZ'®¡XZò)fy Db.ÀއÓò"½<¶iJqïcó<æƒu§5Ñ™Öúƒ‚Y™‘ÁÎ ŸÊ¦Ôµ´i„I"©=[ã5lør{—;yĽâŠ&8úŽkûI¼¸¼‘Ç:ÝÈ0Äÿú¥{׉ó<’}BßÁZ—ˆu2ºF›y¨¯,íglÒlr=¹¯eÒtï±höpàä 8#$sÅ{ßÂÏ iþøE­\³¬"x'h󄘌 qœã8®"ßá_Šõ )ní<1ªÍiÉ’;) í’w¯˜Æb%^\Z#ë0ØHá ¥'«1¾ÚÅyiœgÈ— ¯ËÐר]Zâ%8ÇZã| áíCJø‹§Ç{eqe)·Ÿä¹£nQ†p/óϦ^ØŸ*@¹^§±ü~µåbn¹íú³:–çvdv!má ;@'ðâ§’Ì qòŒ““Ï·ùö«övþ]¬YÜ@ÏœŠ­Õ³ÀéÀõíùW€™lÀžËrpWž:c?ùÆ*”öÌŽQŸc],¶…CayÏ\U¬Ã¨xéŒÕ¦4a%±RG zš†X¸ùFW8ÉÇøVÛ[|í»æÉÎ1“Óš¥4`¸ÈÍhšæÇl–EÔs*ÆËå0N’nžµ´ìË ed÷?ë¬ßZ±‚õˆÚâ%€Î>b>øÇ¿JѸ@öR•8“cr4}=)»K¡ÓOk ½¶ ÎûÛ«œè=jþ©Í¦,‚M¾Dþ²Oà?ŸLñQÞ&mÝW v¹Ïn½êÌA$¶(ÑÈÄ6îC|½Gè1Q^ì¹¥(Ù•4{ùLŠ>&ÀÚø`Ù$çëŸQ\ïŽ4½;þ;K¸žæDXö»FŸ+FrJO8`?!Ú©ézÒÜßÍc¦<š…í»0Ç „n%ñ ŽŸXÔ´óu¥çš±Z¬ À†˜îbH ÷€ç=³]®^÷CŠ2‹ÐÏ›P»i¶ÚY-Ä[¼ôŽãlk€˜SÀàÊH5_Ä^"Õï¼;z×–¥-`U"ÜH|¨AuUK¹l ŽI<“Z }ý“Q‰.¡X%‰š0>\&0qŒnx9¬{Ë5Ì:qž;;Òlœ¾› ÖÔ^IØêBœŽTãAÆDùšv9*Uåši"Mjåu /ËHãY°Ì_³Ï<Ž9ëz—UŸO³{h‰xÜ@…”@$Á9êw®OáþfëLŠÓd@,PZ£H|ïŸÑþ.ƒ’}~•KL´Ò®­Úk>òîgbÍ,šƒ¦âyá@À€æˆ[íhzÚÇ‚,~kc†lã“ì*O+ ²}Ð{÷ý29 ÐF@ ñSH €2FÏø×î=OÏâ [žþÞ´Ù 3èÏ_j±¶Ãœ‚ëùÒ²wl°ç$i^Þ0Ͱ’Àžxý+É5Èvj·Šp1+ ç?ÅÖ½…cÁß¡ü;×–øÂÙ£×nÁ üÄóÓ’Mx¹²^Ê-w>Ÿ w­%ä`lÇpÜuªwV›~u^8àV RT `š|üØZù…>Sí§ET™ƒ´mô¦GSZ7–&™GËõäUB¹Òº£4ÕÑãÔ¢àìÈX æ¡xÁ3VqÎ9  5¢v9eMOCcÁ¾,›A»K{‰éîÿ:c;Mÿ¦kØ!š­Væ³Dã(êÝx¯–,çåÍwuû«yO¹±*Í0û¬HïéÔ⹫SR\ës|-IS—²žÇ¤yÍ´Ç“œLSÈ&6\ås“Ôç¯ëÍ5ƒ,  úŽ´G0$+r½²3Šóì{0[„Û(Ü{ɬ;›#´s*°nxèkp0Îg‚8ÏZl¶é:”~I5g%ævP«ìÞ»3ϵM,XHù OS÷yÿëþ•FH÷òŠ9›Oÿ?Jé´mP]¡ÈYTÀûÞ•ÏR.üÈìÃI8ò²ä±– Œ«Ï­M¦Pß(YT €—·Z(Æ #¿ÊqÍ5¡ ‡BVEÎ:ãñ©ŒÚeâ0ʬtÜ\yŠRNüqÛéúV|–Ûd*½œûWwðßᇉþ-ë©£x[G}[T 1‚'HÂu»²¨ïÔö>•õ÷Âø&ˆ5»´Ÿâ^«…¦˜­Ž“r³^‡ÏÊŠ4J¸Éá›·NkÐŽu—2V]ÙóëO'Òµºuû‚Ä|Ý)ÆÕ‰SëÀÍ~¼øOþ ©ðWÃÒo½´Ö¼MÝF«©ð·X³øæ½ËÀÿ¾|5òÛà Ñtiã «{$ûAÇs)Øû’Mmûrû—ü18 û¸9?’_¯ä~^þÉüoâ½tðÖ©o§Ü¢¯®lfŽÝÀ'8®ŸL×Þzìmð®Á!Ÿ^ðÓjúÐ=Ð{ ¼ö2ª_DæŠì¥B•ò­ÿ®ÇÆbñ“ÄÕuW»~ˆñ]7öFøE§ÝM{¤øRÚÒõÎZa<²Ý‘Ø/Ð_?üqý‘áÖ®üW¦èº}Ý™ÀcnŒóG÷™Hè1ØžÕ÷K(aþVYB¸…ŽüŽTõÇ×¥EL=:šíèaORgåmÞ¿m¦ø’ÖÊv†G¹ž8¼r6à•ˆ#6Ž Á#ꟊ<ãÓ5Õkùt-ZxÓl2:äÿ¬HB/Ý õú×±|føa¤xãN¥$Vò#\Ù}¼3.áe™X!¸9ûßJ›àׯ/‡zŸŠä°²Õ#¼“Éòî-Ú 7Œ† T¯p$œ€HÍa)TÁ¯gM^Û³Ñä†.Ó›ßeØùöÛÆ×3¢Ki–bË3Ãç0SÃ{îoNý½8«Ë®GpÆ ‚ùÒ1 Ñ) 8ã9ç“À¬/ÛgH¾øñ"/øf)-|5­2kÀ“ˆÇ ‚$­yOƒ~7Ûë·‰¨°[³·F„mÀ8Ï'Ò¢ªXºw–·ü'Fn/¡ô¬VÌ`‹PIn;úéÓkÇô«ú5ÌZ–‹kuÝ‘#+c¨ þ4ðXðkóùEÂN/sÓ‹æZ¯òðÃñ<þ5JkL©à`:Ûu;G¡È&«I‘žCþzÒÐg9so½ò\z÷ªr[¯x8çõý+zh¾ñÚÅT’Û%Kdãž âµR²©sÂ2O´+ÎY^%ØÍ€Fãéç[S47 ÛC †}Ÿ~3œìË’}Nç—¡ÃæI28l±DŒ!$–ù°8õÿ•yµ+‹ì­‡XØOÊ»•¾a€ÝBÜŽ‡ÐU»Ù$Å(N×€º“Fñ?ÙÃ(ØÝþ÷jls¼†ÒC9;€ùz:U›ÈZÚ -™à2†eÎè}k3SYJ“‰AY\)á»cŒgßò«äåzI¾S6öÎÓÃQ Ý>×e¬“ý¢á`Cæ°1}Õ=”½óÁ5ZKx’ÚöæÚÚTû`’mÎ$…ÛÉùp¾sZ· Úu½å•¼Â)æE·…˜œ¤Œªwp?S޵OÄ> ŽÓM‘d¹Û<ð„ »a €”}Ð:ÑKš->‡•¥h»³¶Õ,Yíã3ì™#T‘TeÞBUJž9Á?0ç8¬9ü]ŸáýR]9#’Òrgz&Hl@õŒæ©$2j‘OóÄ·7r£NÎJGžI$arô8äqCèZr¤ÖpNÉ·ÏYƒ!e$’çqòÎážyäžgr¡{(·w¹j×Ú³Ã%Ô­v»JÜ€zs€¡í]©zš5ÙµrFÔ\ÿÎ}9Ícx7P[˜åº±·dµ.ËœäìÇ<€ ã$ÿuÚ«K©_Ë:®àI+ïÜÍ’x¬ª4„ç*nÛ¯SçÈ‚`ílzšŸ”ýÓÐdž¿•B…Dè9ÜÀã ¹a×q÷pZýÕÄøK‘£¡#ƒÐuÍFŃS„ž*ÄjªøØGa×ÿÕI8RFÔ'¹>¿OJV¶¡± ‡Ê±ÆÖ<6áÉãµyçŽ-ü­iÇ–@1©pzú×¢ª\vŒŒúWñ&ÄN:5ºÿ^H¯6·°ùŸI;bš}™Æº«Îâ8¤a‘ªr2Nyþu` ±#½ Ã~´Òµ-bò1`³ÆÌqìÙŒg¡9®«À¾“â/"Ó-íai—þYÚ(Œ(¨qÉ8$çŸA[{~ghmÕ‘[-އ·Å»Ié­Ûï仞A‚¼Ax³4&¡(‡>fËg;qøUH5ÙôÏÜËn! ƒò°>ùükõ[À±w…í| -Þ©q©Á¬}›å’ÏP.9Šç„?»1‚Á^@ǸøOö™øgeàßêKj©«[J²Ix€Æ—q2îFÕ#pc>Y8ç'e:•ºŸ39W¤îôó_­Îž=µžâ+ KF²)Ä“à8û¿N0=ý+¶eŒŽàzW€ÉeÈaÞ½À~3{¶MÔ¤ÌÿvOñ²qÎ}=k:˜uÍ|>*N^ζçvЧœà ŽßäT±®é°˜‚rzS€¤`GS@a ·½H?p?3Õßa÷vQÝÛ³8Øá?tÃ7®O¦x®zX÷Å:gÕX~µÑË'™…ÞXʨã€z­ub· ³³Z‰$Ù݆­É M=ì]–’&9,CLZÝÕÐí#ÈÏ5Ö5´W(ðÊ™sÈ ÖÕŒ–3l‘F”>£üz~u›–§¯Ù&t:]üz•¶Çf\es×Þ½‡àÀgã·ŠbÓì’K]-ý/PYbŸ¦NGçùù—Áï„Þ%ø½ã[}Âöu¨H&ü,îP]< ÃüôýŠø?ðoÃßü#‡ +Í9ùïoå$¼ïŽqè=õ¯W/Àýb^ÒkÝüÿà>sGGÙÁþñíåçþF·ÂƒÞøC¤ÚÚø{D±³½[xà¸ÔãµE¹º*0ZG'$“Œñ“ë^›Ú°]¬J3»–5ÆÍ|LðÛÂÌr~b1Àü{×Ao ˜3Ò!Â’pIÿ9¯ª«EE+Ÿ‘ºÓ«79»·ÔêmdWLƒ“Þ§ÝYúl!p9î*øcŠñ¦­&vÁÞ ¯žþõçšRØš’Ó;ùq±ÞöféšÉ¸Õ. „ÊÖ†ö q¾Ø†qï·¯äI­ÿIf. Æ=Ï­cj‹¡i·>mÍØÓ¥”¥´+œv]ÁIïÒ¦qÒÆ´äŸC'Vðöã=>KmVÒ µš2Š×pl¸P7Õä¾ý¼ ૛떲°¿¹{ƼK¯²E êÄœ.åèq€Fyâ½ÏS‡NÖmã»MRÙÉqo|™—=•Ð(À÷\õæºËG´Ô¼«ˆ'©³^Dç(¾[Üõ#'uù$þÖ¿,~3x_é†o¬îR{xåyŒì#ò¹ƾPøÙûxsàßìÅâKsqâÍ*â?7QºÇ$¥®!Œ…@ûä† ‚KsúCñWáÖ¥sau¨x^æÓO×[iÞ#v9uLeha£+]þÏ›Z<ýj8-åûToåWÜN#¸­ÿi ¢ëwV…B„s´˜íŠÆ‘X©daЊô¡Qµ§S‡„ösqšÖ.ǯø{[Q¶Š)¤V»Úzƒ–ÁÕγm‰3íZ¶÷ ° £wóUbÞ§¥NIêµÔ„â5ᚤ‚q<`äÜšÏk“%úó€£<~U„bîüe%ecH2ФãŒgÖ¨O¶fC±Ž˜ïéÏZeìí++RÔM“Ìr̹(ÿ>ÕÑJ3ó1NÆÍͤ–²yasÐbqî¤b¾oøÝ¬ø·Â±½×ƒ´ý<4,Æ{ Ds(`G”Û×Ê; `ò2>ïìSø¦)m$x%1ÆN7“÷<¯±ïø×œxÏSÿ„ƒN½²žh¥–( –5Ã69Áç¯P>¾õÚ°‘œ\k+£o(>h;|ø£wñ'A6S³ /­ÑÕèþûŸ+ü;ðm¿‚|§éVÉ·bùÓ î•ùsùñô­2—¡`–éþzU³°D°:á£PŒ¤rçü÷ªòÁœnǨñ¨ç7)nÎ¥] ÄCõ÷ïííTY3œ‘ÎzýkNH÷NA=ûUvŒtžù®]Œÿ$w /cëÓÞ£òÜŽ?_ò*êÂÍ#gŽojo”¹SürI÷©Í½Ì:Iç¼³˜•§*°lœ–-Œ“É'žýO—o­Íj†9Œ²È.ˆ@oË5Ç&Û±«‹’MRHd(ࣂ2¹Èíþ4ô zñQÇ7Ÿ'˜YAnNÞœÔñFsë_½Ãd~}-Ù!ãܓӥ@ÎË€¤èùþµp¢ |¹àŽÕRd¨<õ<œu¦ÁËç÷ÌÞàV~¤ªêÏóêkÐþÛ]¯ÆO„ÓCiÔw'‚çœ.|È·|ÙR ‘‚9¯C箦k(eè\*áˆóy_k‡«Nß ©á½3mõ¿äe:)FS›‚:ñÜW7©iki eùbl¨ž¿çúWV|„üÃqŒç4=²MòK‚‡‚?ɯ†‹åÜý†¥73¶‹y*8dL®[q2>=sž9õë_cø?Ã7ÿ &·@mRÅ@Ûå‡OºçrO9ë»<ù"âA倨`N6æ¾éý—4»ÏŠ_ u„Ý˧1Óå`Àdɸq‚c+Èà{ä ÆPT©®]7 ™VÌ+ÊUÚæòV<ßãÆßiZf£{pažö[g‚ÕÖÜ C´þ÷îeã Âç¨=+æ¯ ]ÞêwGU½»2ÞJáÞv]¤·8Àöí_¨SþÍ–^"·]yÑÇu ŠHãtm®Ü÷#·õùêèÓøg]Ö|,ð5ÍΑs-›2˜ßa<`rAïXa¨¬]9SNÏÐô©f«%ÆG:|êÍZö³ûŸÜr?m­N¯Å“;A,*Ì®åŠ>NàSÎ9ÆqšãÈô¯D¶zó uc$rDÞ[¬R|á¡ÁÏcÒ¸íoGm*é‚“%»b”ŒnPxã·Ò»ý„èÅ_QO3Ãæ8‰N’åo[3Tô4¶sÜè÷°ßZ¹†x¹I Ž8ÇB1R•'5‘ Ü‚1N2èÎ,F›ß†èöo x¢ßÄÚh’< ˆñçÇŽŒGQÔ`àãñÍl9Á Èî:žµã¾š-2î9­eDŸ#äã=xÿõW®é—‘jP, yg?©6³;Á`ŒüÄ*û<º á£Ëó>7”Þ.IôØ—ZÖ¤i6Â7¾}+—ø“âKhKm4©Ôä »²IÏù5ÑÇ%®‹i&§xÞ\+•˜2¥|¿ñ‹Åºgˆ¼+«øÉµEŠÒÖäXZ)Œ©º¸]­/ ‚òN0xäŠöSQWè EÎJ+vF¸ðçŽôdpD²ùª‡ç ÔŠúÿÃ1Ý[ÀÁ°^0JŸ^â¿5?gÝróâÄ÷I6µ¼O¾Û±A-ÎO9 ú~úð×Óè¾[É?™C´’zâ¥_ë1•E·O‘êc0SÀÊ4j|V»ùž²ìYUy9­+”eìEa#y–ãë[Zcg9#Ò¼ÚªÑ9âõ"%­¥m¹úTVû’GvÏÌqV¯Tg=p{Ôf< þu Ý •ûç' ÈÕ’Þ{r'b˜èÜõæ¯jT…ç©s§.©oöw‘‘ó”eõéýk¦šJÒ¹›¾ÇøŸS[ù.-µŸJ›ÝD¤ng¨œgiÈ÷¯;ñþ¡q¢YÊVeI"êͺ3øý+Ó~(é1èž¼¾ñ Ò¥®œoN¼W=O5ógмQ?ˆ| 5™ ïHšt€óáǃÈíŒã­z|Ñ•¬õ2P•›H¡ˆgX´ýDÉ»ìÓÈ£ª’Tö÷¯°<âñW†^9¿×d¡=ëàß™ßI–)Wj‡e*ØÊœ×Ñ_¼M-œQe ²0+Îz¯šÏpüôÔú£ÜÊêòÉÄîl> Øø§Ä—âçX¼Ó²aH sÛ†HéÀ#õ¯8ñ—‚¯<«ËcpR`~äè?¡ö¯rÕµ¦^Zj°coÅ¡ÍyÏÅŸAâf8áèelgƒÓÇÖ¿4ÄBŸ±ÚÒ]{úŸYWšoícË×(Ç êzöª6UxÏ\VÑiàžýê$·WryQè:WŒ´9¶1ž&$àmÀõªR[³erÇoÒ¶îà˜€9Ó?­cêº{]›x¶þäL’:ñÈR~ gÛ>µ[ƒ½´2¥¨yZf#\m!³V +“É#§'Úº«M2H¾ÖÓO& –Œn#·ž@Sæ%ãÆ:Õ-oÆúuÝŽŸ¥ù˜¸™ X.l•M¿*© gqç#©Å})Âñvn§“íKYÑu ý8i¶è òá"Qp¾^Þ¹88Pݺc­t“è–Zõ•Ì"Imã‹Íqo Üž„àôÀíëRï9¥áå S”êoÖÿ¥útÛÝ[ÆzÞ­&µ}.«yåZ †Š;xl‹œÚ#ïgå$òÕ‘àõ¶iôö‰ôË„¼È^VUPòC-Ó·QœÖÉi%Ä‘iRMc4êë$*²¶WNq€H à†ìrsTô]r÷Á -íÒ5Ì‹1†Þ;ôçØòyÂn$ð׬¤½®­½÷<øÏØ):n˶Ä_|=§KuÆ—ys4Í"å0ÇjáÓ!·¼ƒyøfáñ Ec |é—šæES*n˜¨ÀÇ¿+;T¾»³øŒÚ¨ðèŸI.o.tûÜÆ8ÎWn>S¹ˆ+×#WM¤êj—×iºWöœø’U7*¿²¶s€ÁŽ3“\µïͦÈè£í*¸ÎîK}Q¯srtkAu}3@‘©¤%qœcå#ñëÒ¹;¯YMq$‹m$;˜·–e9\žÇà’kgP·ŠÞ1Ë$Â5EŒ°ÚO=À'§<ñÓµfZG ÂVštFó 1íÜ{æ¹£´u_sÈaýâ©TÛ‘ÂŽ úqSÂÎynƒßô¨Z+»{˘¯7¨eØûº“´?M FOœêyéë_ºÓ|Ñ‹GçSV“L´«€~|dG?äU)òÌÌ ³ž¨?áZRÂP°@Á޽?¥iŸxŠk;{˜ô ùíçBÑ<¯ eÏS´Lã ‚2 jÜSÕ’“{#˜KûO&ñ&Ð5ýZæÞ9#´¸Ò.LCNºu Ð ou1>#fPÀ2•Èϸ˜\›…ûDWæ;—OµÀí"Î2@°Ø À0ÜÈ­ 5M÷_[;½C@ÕVCÆÚy-¤xòUöx!ºLÖ>›¥µ…æÀξj°$ä§züö¶.Ug^—W{ü¶=ü‚¢†eJïgù¢ŒÛŒð=Æ•›lGn‘Û&º ;áÇ‹õ[W¸±ð¦»} Ãy¶ºdò¡¦ ¡5RïÀ^(°˜Guá­fÎS€#¸Ó¦F$Œ†\ž3øf¼UFisr¿¸ý¹×¥{)/½E¬ß>¡¶åÄ&£÷r@ŽpCïšn™&ÕF1*2“ž3ý*úš?ÙúãÇŸô´ÔôCDºPéýÆ,b!¼žŒp;Àëü@Ž£?0kº,þñF£áÍUÚ=JÂá a‡W œ09åHÁDZ⾓ˆU´jÍt?Çá%‡ªß72oó/˧¬é¼IóôW õ¯¤?`¿‰×>øÍoáûÙ£Ãþ'­&k‰ü¸áÞ ý¦oÝcŒù£û WÏúzBlËݹBËÈÏ={óUÖíàt’ ™]::2°9èqϵuV¦ªAÅõ8põŠqè~ÛÝ\iºT7·Òȶöºu¬—wwWS€°ª)fgvÀUK$šü€ø„Ö×Þ4ÖuëÄš½Ü«un&vV ?‡%qõ¯IñÏí›®kÿôï Çqscu5·öv¨ëpê( $¤¨`0 ÜÈÅ·›<&ÓÅqEbñL„ÄApy®\Ø&å»;qøµ‰iAhŽzë\š9Ý”FKòg_¯OÆ»(< ªø·Á×—ú~ªØéуuwci$±[±]Ù‘Ôœøã5ÐþË:W†¼}ûIø;IÖô¸µ[;ÉgYlï"Y-¦ o3€á¸8*CÈû)ªøF³ð hz^•c§i+nÑÅceà )\`"ÕxŒG#äµî…ƒÃs¥WšÍ3ùõ½¶[[†XåŽxø+$LN}Á5Q׎Aϵz?ƇðãâF¿á¹ËcpUþØQø+(ü+€ž†B¯ÉÇ­p)¦Ï¶Qn ·Ð¦ÑöúVŽ‘âGAÔa4—QcaŽF'+ÆéÅW1€‘QÃ0BŽÀñŠÖêJÒG›^„é~ö›Ôú“àçÅ1à½~ÛÄzt‰{oQâY1¼‚§ƒ‚3žGö_ƒÿl êk^‡Óå2¤ÎpíÜd ñõ¯Ê_ øšëÃz©ìålIóž 0ô5í²¤öñKf9u#¡SÅVÀû°Ö&SÂÑÌ×4c|ný«¢ñ0¦œ°=¬OåÅiox¬ý ÜÄ~„|«¯x£Sñ4B;뇒Ø}Û|b4‹`Ž9ýzäÖY$àÿ½ê3JC0`ŽIÿ?çéXâ3 Ø…ÊÝ“èva2ÚGÍy.§Ñß°¯†ZçÄÞ(»òË‹k ÈÛ9åd\ç·ÞþU÷o€®¦û ¤À2ŸLçú×ÍðOM1áÿ^¼k DŒ ꤸü¸õ‰$2Lâ!±Ó±ξ·/ŠŽ1þµ>G:­*øÙÊ^KîGgnø@q[ZCî~¸ö¬[R„0{æ´,Ã8rk*ªé£Ê‹ÔÕÔ¢å¡|ž@ÉC×pÇ‚+JÝøŠ‚ýrükÎŒö‰Òã¥Ñ‰­Z%Ο"³O̼^m©Lú%À‰ïæ{PÛÈ(O|þuêב«[2¿B0M`Ýéúc$ú“Ç,i–Øç¸¯OUB6i³–q»>yø¿§YøCÃui* +òïó?@Èòj8¬ëW•¹¯eúýçÞ²ÝÛÆÂh 8òªp7{~»‡~![ È‘¶òdeú¯—~üM3У´*ê6­ºhx 0ö €O®}«Õ´ýd£¥ÄD¨Æ~^sÇ­zا]˪gǪ3ÁWäšÕ3íÍ&sªè¬€9ÏW’êÈŸm‘ î‘ÒIÏ8ØÍsþ øó¥éÖ-c¨Ï4;v()Ôôþ¢»O xEüq§j7º|¬úˆ_= ²Æ3œz6O¿µ~a_-Ä×EJ·õ¡ôõ14¡óËs“yçǸϭIj ÀøV¸|ô$Žzžµ ãpÈ Œý}«ãQ³DÎØòzÕyà sŒô8©‘²ÇqêÉ¡òU€;‡ ­&ÍN·wqi¨Üˆæ‘#xž7E'Âûàô#ñ®kÃÞÒm3·Ä×=+Ó‹I«[·õ¡â9UtÚ’ìôÚÄþ/²Òt}>8´+ßíMOí[#Ûm·9NYH u9ëëX×gK¾r—Ÿl‚ùQ¾Î6ÄqÎC³ŽIË ÙcŠÌÖµüjÉ«Y¢ý E›’r«qÇÍ9‚¹ ƒžzœŽR]R]J[ÙšÞ[­!QâS%ÒáXœ«Œ‘ó/¸ûºoÞÖÖ89¥VÑÛü-èz­ß‹müYm§hío´QÙ,"IfÉS…€OÓ?ΞÇì6°Û]ˆÅ)Ã)>£Ûž+Î4¥Ýemiil‘O6È#b]¶í Ű:ñÀÉ<ÖÐ…óøŠkoZqfedT€Ãzãò®*·œœ®}*VièÖÞgY©jY-ʸpVÙÀQ'''§g·j–×Ãõg¸ŠÌO”ð©)ß{UK[;I5(/á´h˜(?<€íÎr@<óõü륷wåB±'Žüý8®G+l{)\ù»C×®üLú†©'™yutÓJUp¹ qŒðàuàu­X¸‡içƒ\ÇÃÁ¾Òö0 •ˆ#=ôÙCVTAà=û×í™t½¦}ÏñP¯(ÄÙðß·Òæ·Š%¶Õ.f³‘‚åœºÚÆrÌîÿ1rqŽ•èŸ²7†¤ø5oªCãËÜ&ÒÆƒº²Í·lÒù—?:3…ˆ¼~íN9ùê5¡O:ŽK•í±†'Ç{Y9R|¿#gàÃ}+Äsi:‡‰Ú=:ÂæÒÓ#gX´ÆÕ "Ý0`)Êg;Ç<Šw‡¾ü9ÐüSñF»Ö-$ðö ‰¦¥åíäW’$¾fP»‘£ÇLóɯTñGÄ9|@Éy¥ÝXiwvå|«£'Ú•“z¹Fh¶ê3Aª§Å‹I-¾Ï,–ÛÍ(û^g2©*8åNÞƒ©=Ç¡¯Yæ8t®æz‘Êqº¨Ózÿ3áÝ?J6º‡†¡´Œˆ –I¦—gú±äJq ¹ŽzàóÅ|ÁûUèCHø.¶C‘¨n._B㜠ýãúWë7ˆþ6éOm3Üiú}ËMý _XÇ0»‘H¤ ) /lx"¸½cĿ翶¾>ÒVð~ò9âÑmgÁ“wÎß°t`zñ^{Æa!QN3õ±é¬§ˆ¦ã:v»ÝŸŒÐêÅI^ êPr*zÝ Ë*³ÆÃ ±ÿ:û·öåð†>$h¿nð×…íôÿØ\™ÞîÊÎ8Zîó"e‰’»nAÁ o-_ØZ-¡Y “+tf9ÅzX|U,T\©½›ÇeõðP¬·&º»½˜‚ÖfETŒ¨é× þ5^o:æ<FÚÊ£‚N1Ó=Lñt¢ìõg‡,E8é»9Ù:Ê ã—†5ë©¡ŽËM™Ìï=Ôq2‡‰¢ ªÄÁpNÐp'€Hý¼ÓuxÆ“M"Îî9c5ù$>ø2ËI¹7z]­œ,Å÷%äþd+Œ®Ï’sŒZúûö}ý¤añσôkø­õ;K«k¨›¶XšØùÒö]û1œéâ­?o%8¦’ÝžîUŠ…e*qZ­K¿þxv/Šm®O¦Xße™%ݺHæDD@ +ýÔ\wàךþÓú…ìÉâ§±Óôí4¤–¤ÛÚÄ‘åÅÌv9ÚÝO©è zÿí³ð[þ†ú¾³i#6‰áå}R÷O’]²b·Wc •pÏûÃÃ1’Ê|i¬hþÑ?cŸZøY.§µ“Z°žwÕ#î!›Í†?‘âye%n¼–ñôisΓih¼Í+FÚ2si¶´·ësã©—É‘ÁëÔÔl/>ªì–â@TœÇ?çÚ³¤ ÇÐWsí&ÜwB™ˆ—, ¡çhí]¯‚|M:D$ŒÅpꮲ¾Nq>žÝ«‹Û»÷íUZÜßÞFzJ¹SEg¡çÕ«SûÄ®¤r¬ŠëÈ=Ôç4ÅÝŒ‚8öô¯&øwãÿì“™¨œÙ¶»b{Ÿîó×·Ò½E¹Y¹$ μڔÝ)r³Ð¡ˆ…xsDûëþ Ë7†¥)nŽB6ŽûGùüê'Ö.<(Ò_BcT+~áe` ç*tê9£5ô4+Ú×ÚÚžU|*•;7­îy?‡ô´ð”}¯•¨Iw+K<è7ˆ~QÀ*qü9î8õªÚ‡‡¶ßk×3D u¶{coÇÞ`3ƒ‘´íëÏ óÅuµÍ¬–SÛǧÜÜj÷%dŽâ(P± å£Î º[Ïå?ï×M¶Iå‹Q½‚â4—KŒ¬7 ‡c(+0$€rKp8ÓexîÎ(K–jœ•’Ù÷Ðå5- «bÅËw‡–i å¨Á ÂZ¥â *ÓÒ߽ɷ‘¶ Ù¥ ¡@«&qÏ9¨®û[¼Òôÿjéú€R$&ß$dãg˜@cŠób'ÖÒâöá‹‹b¿éÞñ†Â†#Œ©Èzöâ„’Ñ»¿È䫊J«•Y'¯½hÆæM:Hí„FD†4 qåd†9àí9?ýj»¤[)ÂI>_÷›æG, ýâ{óÒµ¼¤é:…ä"Išá#FX eVœýâÛŽ@õàÜV=î…,·Ç,ÏjIHŠl,¿_qÀâ‰EîÙïQ­‰òìŽÆ ˜#…D¦YÀ#$ŸÐž/ôîCÎÈàÀ?üë(m¡פù‰…Vˆã¶ÇOη¬¯VKy ²&á¿×—.ç]9ƪ惺>gø^àÔÕ€ÎcêG£ÿ…{Ã} ûkÅÖèJˆá_´2¹à€G™âß Ì‹&¥ ÊþY;|¶9ükêƒzG¥\jN^&™ˆŒ¨Á§sÆOò¯Òkbþ©’¹­ÝÒõmþ‡——`þ¹Æ2ZFÒ$¿[‹w5¶¤lá|¥Â‚cÆ6yý3^‹¬ê .›AÕT$îðÆÆN;œv®—U·O>è™ÉUhÆÿ—î€?Ï5ù3v?nQMÕï‰î" Ф–Ñ®ÀÊO^H݃ïßü+Óôëù¯Ä! b pFqÔçœûf¼zíOÝœ*޹8§ãëØ÷ë^©áû2t˜÷ EH£bë‚§ u¿—8¤ÖÔn¼æ'Q¦1¬¶®07’§ŸCŽ:òMy´^-¼Ka:\Ý‚†r»¸Î~>•éúݳ:"•Þf`¶·׌õ¯±‰£¼¸´bÑ*HÇæà ÀþuqØÍêwMªµõ‘ËÉ+–U.[¡+•Î>‡ëZZmà»—²¼aÃg*[ 7¸¯Jætw70(D{±·và?—áëŠÚðÎ÷½Öâ2‰!–.6ü¿6@=)'iZÑg1ãu—Nø“. ËÛ»eÊ•ªˆ3èHÇjùrçáàð7Å­E‘¬ãÿJ°V`r²† ?à'Ì\ÿ° }wñ]Öú}Û¸Î'qièô¯øó ÿÅ,5øn 3XºÂÅOð<Š£=w0Ǧã^Ö¬©Õä_kCâø—õ¬œ½~]ÒúKÇK+g?jvýîÞyý:gÐz÷5è~±’9.!¼Õ¶±t'8˰×9çòãȵ/ÞD¶öq¶Ž@ÍüÎ;–#“ž{þuÌj›­æ/™bO'¯<ç¥}·íVvò?ŽïÞ5ÙõúWÑß<%âø[RÕuMâÞþ` §›i”‹ xÛ° !pÀrNÜG5ëÉÁC–G±‡§%4áÐÚý¢?iÿŠV×Wþ ÕâÓ­4û­6h Kgg¼‚æH§”—óJ±VŒÆ¥F6n'æ_›ô]l’ØÉÿÛ¾%Uȩ̀zƒôeR>•ôÏÄÏÇ«ø^Í|G«­ßŠˆeŽòc™9Àp#Á ªè0Ë)ã-“òÌún¤" ¢H»ŒjN3ÏøÖ¦*‹ŠÛó4­:Š¢›z­¼HŸàOŒ/4È5­7FûF—tžjMå¹Ú·™¸z`ŠËÿ…â« ´èàlíîÿ"jÿ…ü]«Ùhßb¶Öµ+kS¹Úk¹cŒg‚ «sÒ²¯üQâ]1·Ã¯j‚À^É‘ìyõ&¾b´jQªé¦´Øý„«âðñ¯x«ù?B¥÷Â={N†9&Kvv—ËòVl?Ý,OÍÐzÿõ²Ã]ze,mV,r7J¤ŸÈšµ«x«\Õ<‘.·¨HêX(–éÎ;dñY+â}j',5kådd\8>ýéÁÖj÷W1©J¯Á)+Zç†/té„wI±±òºU¿úõí¿³—ÛüiâÍÁ÷k$Ïq>Øf “° ̬}SƒøzWŠê7·šˆæîk¼2BØúdûÖÇ>!ê?¼Ie¬XË*Kjû€ŽS÷9ÕßÏ•OTš<¾O©¶öºß§Ìþ‰¼!áø¼-¢è–PÆ#ö‰êsúæ¯xÆÀÞé‘Ï̱8qŽ?¦kóÂðQo)ôÑgâ=KU¹{eiôÍH–Q(2¬ìÉ9<⺭3þ ¥é·SØkßui–&Ûæé×ÑN¿FTíúñ^Ú”}¢”ey.‡ÈN•E)GÝ}|Ï¿O—œõª2ÉŽôëá9ା ’Úø+ÅŒT`Ç,0¯?Q!¬ëŸø+….¥Ï€|SnIÿ]„Ÿûä¸þußAo#©tGÞvúôUòßÉ矀k·Ò|_¢ë ±Új¶sÎF|¨çRãðÎkò_âüº×^³’Û@ð߈® ´ßˆâcý–~õò_ˆ~8üKÕüGý­§k𝇮G X_<.:ÿíü½«DhÔ믑µ)Nô1{aq§ÝµåŒk\鲿‹]¸ ä`Û.3õíï\Κ”ŸÏo¿¹·;ÚGé”Þ'`U7Gœ ñšøþ …û0Øø¯ÃŸð·|9`–ú±¨m¶ÈQ)þô‘d|ÝLyˆÍÿÿà¦>;ñ&qƒ¢ \2ª­ÈÕ ÓGÎI å '·ø×‚jŸ´OÅ?Auk­üDñ&£guG5£ês y† ˜ƒ*A Œt®lS¡FZÜ÷²L6+‰Jm+?é|Ï2»ŒC)ÈàÔPYÜÝH4§øš·åÑå”ܬ} æ¬Y@É*¢¡–\ýÐ0Ö¾wÛ¥5gê_ÙR_ÞÞ1>ãø áÝKþÛE“RÔúA0–Û*‘J¬PŸbƒØ×®hò4–Qã÷a~»xþ•ñ¯Áßš‡ÃíRð–³*Þèú¢´Váßi°‘ƒ Õ$¡##r9â¾ÅðÅâ_è¶W1¨ r=Hô>µñÊR4¥Õßï>c„žã%£ÛÐÐ0ƒ÷°ÙîGçO‘A„䜕0 Np÷<š†NU±ÔÒ¼{œ62äqœÝïþ­KïøäÓàIé×µ#`rTYM3¤’ëÒÄî“r`በõÿ£wØî™O0$ Tœ‚*íü0˨NÒ0Mñ¿NHàõÌxŽàélb6“b ÛŽOÊNG|{k•’º¨¤Þ‰‡H– -–S#j72™-‘%»(#•q’A9ÁsYš§Ãß_M§êÚ:-ÝëÜl¹·–tÚIᕎàÍÁî;â¡Õtˆ5¯ê3I-Ç› ÃâÒíÞ9b2P ±àÆ1É5KáŠ5- YŽÂëR{›g‰ÑŒ§ ±<6zä€sœ‘é^¥ ¬×CåjÔ¯í~±mOžÞ¦_د±sg81Çû¡Š®wg¨ë»ôÇkx“ÃÇSÓÖhÞe0J·îEB“‘œ0rCÛ¨©.ÚÂÞãí·/=©–EHî¯ *’§ŽyÆ ÇBO©ªÔzx—Gû@ÙzÁ„꿺XN×ÚwÙ§jø]k,÷:„‘î1‰#vîÚ~vþ•õ÷…ln<;àø­Ã²H‘–5ÇÞ%¸9Éÿžß5þÏ }]¯u²ßÜCeyeËkå¬J’ÊP´ŒçŒrxœkëmNá…˜>òà‰ÎØÀäwôôü+ßÍñÁÑÃ/6ÿOÌúN ž"¾%ï¤WæÊ>F«æ\DeH”ü¬ÇŸoºa²\ÕqÕ˜?wræ‹vÑȱ€#‹?2›iÁÇ¥kønçÉñÜk•·!R ã9÷ÿ=kOðý̰Å7˜°Kœ• “Ô`g¨æ´#ÔWNñܘ­íñ!3ÎÊŠ²’Äž€ddœu4I5±¬%¥™«ã«,øvráĖͽàäÈqœWªhðxÇÃÚ¦—rì÷RE<ààmaîê+¤¹ñ·‡¼Gsuce­é÷3ÈAxm&GPN1ÈnyþU‹áÛ¨¬Œ¶÷x˜i0$}3]±¼e³8¥ËQJ;£áÓ¼c¥ÈUßN¬äx×äŠ3qŒ‘œVN®Ñ­ÓJ§~@\Éd×¢~Ò׆õŒz”¾”\[¢Ç ì‘‚®ãù$+•(Ï NNrx[Å aŽî¹9¯Õ(Õ•j1œôm#ð|e(ÑÄNœÒoc¾ýü?câ_о¶¼‰^)¥2ppÁ#gßæNkõ&m/N½Ò#´’6 T!;¹Ï½~M|#ñrè_|-y*•X£L£/úŠýLðn²5KK&°’=8þ•æã““V=, ^ÍúŸ:~Ñ[ÁðÙë†oí 'Ìo:àI(»BIoŸ{2íqÕr¸É¯…5‰žæO´¹àØvþb¿D?nOã|9Õí|ܨþÌ‘‘ÌëÓ5ùÌÏöíï"«íðžÎÿŸ~§{i%¥ÒFØtfl7‡õª7ö¡†õ\7$ûûW[sOr3,OÎpqúÖÔi)Iplì ç uük—ŸTÑêªIsG¡ÎÀõ¨%Lüï½kßÚ1&DSžý8ük5¿*넯ª8kRÞ2!¶CÌ7*Û_*Tà‚:ì­Þ»?˜†VË;1äú×"–ï$ Æ;ó[§[Üe…L‡«õ¨ë#àq±öu;Ý#¯‹ÃÅß÷’`Ž¥-߇$+ˆåV8ç#­aXévÖùÊÈ’uVGÆ=øë[°Ý$¯Ÿ^I?C]hó,Ì©tß ²™ºuãštP"}I¨j rN~`)ÚtèS8¨ºè )n žA±œqÛß­W–=û™P•ê ý%ÕáPåH^§?Jçïõ'÷„°'ñéLUqhÝÕ²¸Ú ã<÷?çŠÊÒ®|»ÃùFxæ«_Ý"–XÁÚ8ÈõïE…àŽxÉó|ùücõ®LDTé³ÚÊqÃâàã³gonÏ*.Ìzb´ô±ä©Á+–íÈ÷ÏéXVZÅ´v«óáÇ^zÕ›mmÒAåÆ\~Uò3„õÐþ„¡Š¡ËÏvþf¿–¦åœ¢¸ÎyÇ#Ú¾çý|Ugâ¿¥µ´²=Ý”qE2Jpr7G¨*ª2}>•ð¼7J£÷mcæÏzö¯ÙsÆÐøCâE”RK}M œ®XŸ¼rq†  ò±ps¤ârgx8c0®¤~(ê¿SíK›fx<óT'‰Àa€9Éçõ®„Ä!Œe~SY7•¤\÷8ä ù+Ÿ–FW1Xmlg Ç'‘’F«íD:€玔Ãnc ‘Î1ÁéT™w9¹,Rêö6e·‚8œ³cžw'°üÈ×âÂÆÖ=ð%Êy™]ÙQÏ®on˜ìõKôÉ[?y=ª†©eÓælí?÷Í{tä¹RHç•.}dÎkûËû›«hôÍ52«@ÉÊ6ã'8ÔŸjó xÛÅs[]$fËí›c‘cù²å÷É>¹ÎMz妕oý·wª¸³² /œzŒžp?Þ5äþ D¼›Y—-.«>Ó"’~cõž1éÚ½/h¥QâÃΓ½µ½Ÿ¯êkx™mÅM¦ë(n¬!ÀáÎX¨# ž8äuÅqëªG'‰nd‚v{8Lˆ©!ù”Hûàþ5ÝkÚ%ņ£}ª$0ijY‘?Þ0Œ@í à4]ÄVK ›Ù¬·Z€7²M">ø[#—•sÔö®ˆÇsIF4$êÍîu×wW’^i¸v0$YÐÙ‰†Â1ô©¡èƒI¿‹Q³ yBoe%Îÿ]]ø}¥j£MÔ›Pi!±µŒÃpc‰'Tqåm‘»žG¿AY¾"ñM·†ôøš ÛŸ2 ¤³'åã¦3Øt®iÅ­žåaý”ê¹Å+%m6ü·ù¯$×;G,*’X˜mç"©bâX¡a2¢˜ÆÐy8íŸzHHE#~÷ ¹°F åùþZ/F®Ô»l<~†¹dí¹ë¥¥‘çßáŽO€^6‰Ç*2\ 0>}®­Œ÷àcŸ_Ïȯ|c­ønò FÇWÔ-,ß÷3Ákrñ©?7ÊØÿõZ÷ƒ^ÔÀoë±Ín-%µœm.áÔÄ a€ œ‚1žkĦHn¬žÚtE ÁÏ#ž?¿X˨ª¸g-Qñ˜Ê²¥ˆæ„šô=›Ã´ìžðí¾›7‡SPýç–תæ|å‹(Ìà A;‡Uö­ ¿ÚKÕ. [ ØÂËåáAðÎ? ù’Å/t½NòÏQòÍíœf²¾>bIÜ2P2;{¶—Æ’R@ëÁ<~µÆ²¾½êÊ¿fÿÌö!ÄÙȪ'néà~<Û+\Äš-ÆâIÞné·ú÷®ŸOý¨t}"ÈDÚMî ªJF¨^®+æ¨5%º”»pÝ?ýTÉîWaX‚7\ Õðæ[kò?½‡úÕš­æ¿ð{5ïí÷ýŸ=Ì0ødUsªóÁã ãé^uñ›öˆ“ã&Ÿ¦YG¡Á£Ák)ˆ¸óäÆjíÆQÓã~$Ñå³Ôx¦‰ ¸&Pˆ2W$äÏJÔøo¦GªøšÚ;é’X•¦šG%B¢rݸéúŠòá•á(Ôç§ 5æÅˆÏ³ U?eR¦É/Å"uñ¾½lI‡[Ôc`IUÛ©õ<ƒPñ>­¨Á#j…Ö¢ˆÛö]NÒÇ¿ÌO=y¬cUµ½Öõ›X–ÚÚk™e†äFŒäª  ~ÛÃiÓ¡Æöô÷®Ú”ãk¨¯¸ñ"µ­ÎþöewPŠèOõÄ©Ê4r²•ôƪÝߊõýjÛìWÚÞ¥{jGOw$ˆqÈùIÅdªýÜôõ«p‚³À !Æyö­£JÛð6•z‰[™ýæ…œgÀ›ˆÇLžõµq?™l‰·$½ÓÞ°âŽE‘w®¬`@N´..¼¥ÁùЦTzZèÑ+w3§¾6Zµ¤±·ÍR0qŒ_¨üpšÃ¥Õ]ФvŠÛ™° lÉ·å_–6I¨ëF~w•úžæ¿Dí,u-à™oͽ…½Š ¬¢¤’ä²å¥2’0yÆÍ¸÷ïY8)§sÑ¡7ÏŸ?j¿‰ü@ñiV’—†Ù–I1.A;}1þ×½x޲¬† Ü$ÍÐÇÜ,rÝxÃS»1‰cYpCçqëôÅq:¬¶ÑüľÜã¸ÏÿZ¢<°|ˆæŸ4ï7Ôµ§ÜIЕÏÊFÈúW¦ÚÝ=&À$‚s‘œ÷¯+ˆÉËE¹g’ õè íÒi)Óçœ+¾#ì>f¸ñôÝJk•j™ô|;ŠŽ¼•IZ-~#o\‹ˆY€bX/< šîÒ;«r¬ 6ß•º•'½+ØÏ;ÄæÑÑ™Ù@ãœpMYxeEÎÜ…ã‚x³…D•‘ö”±¸g)ÞjÇ%4>DŸ+¨êz7Ò²ïm¶1uÔv®âk®ã"\¡ä+ÇðükM.rXÑÆüëJjkte_…KãLæ­à–âñ<§(%öžOùæ¶°ÉÅVŸJ¸·›z«F8ÁãèiAl|Ç'Ú½ú.ñ±ùÖ=E×r‹ºfÄ7`É'©ü踽eR GH‹ÁàV~¡y@=3[ÜòÙ¥©'–8<ŸóøU»=I„C ÇcÅs’òNqÏaš’Öù–0¬Iô÷¡;‰-.t“ê†wg#9Ýþ}ë&æè‡$Ï?_zˆÜo@ Ç5‚W×8§º ÈÓsÉŸ¼£’ ^†ê¤eV$^;žæªÂ¤e”Û>µñÁ<ó\õµ_.—%nt®ÑÐÛê}›‚ÛqZÚˆ>× Ö ±ƒËÊÁyúc&¹ÝAû{ÈÍ\yk¹‚);Fq“r+¹Ñ¬b´lB¶sóf¾wì©ù³ö™ã1)Jêì’oñ¹f=@Åï³[‡?t¨ /±$c¿je¦±ªYêÐ^ZJ–²ÂûÑQwàþU§©_™Ö4“€ãŽÞŸ¥b‡ :œgp;ט­ØûJ´¯NM¯¸ýDÑ3×l’=]>ÆåL·’È¡"'9¾ÒÝ÷àõ­#FQ‹¹•gUÇ™ì`izíýΩ›Dòê¶K”\ŒrFr{ž´Í{B»Ö´{¨_):Ù$°cŸÏ5Ñø£G„>&¼ðíä©~öMlæx&$´“ÈÚ:÷‡<Õ8üA§<¢òÑÑÝcÀÈ9À'Ôûófå^ÇM0ŒW+éb÷„šx,¼»Á¾hæ*w˜þízñœVÅÔŽ°ˆ¸1ƒòŒ×ßüæ¬èû5ÂYÿ|rÎ0s县­Z¸P©nª¨ˆpÀûôÅrIÝž„}ÕcŽðŸÄ?è?|Cá›-nãÄS\¥×Ù¯-cЬ²E´£,\ )çiùˆr|Á1‹øvÑáûDoøÙw‡Q"’ ’Ï#"¿Qµ¯Ø‡áÆ£ð³[ ZxlµÆtö7úf“C1‰‚H¯ç #=+ò÷KÕ#±ŽóXµSÖZT·±LÜ2;E¶c£ $A‘Þ¿_Á8Æ…HÅê¿áƒÄóʤ\%Óîç°ò/§/'”›&@K§Ó®pO¯_­m^æX™1’IçZk,ÒOñlŽaÕ‡Ê?Î*–“+Ãö›g]ÞN 3cçC  ü±]ð‚¤ýŸGùœó+ö%œeHÇõÿ8©g¾jU¸u¸ãš˜YGu›8Àíþ­gÝÂ<¶;‰`{Œgéþ*ÞQiY{²MgLÅ•¸-½^”}ÒÊ2£?A\ö•{ý›¥ê†Ks)¹‰mƒ1ÚÈÂD“xõÊÆËö½¹èÞõ¯mšÛ$›Kp2ÃŽIÆ?\ÍêÉa¡Y—ŠYn'¹‘ˆpKÇ €{pk柺Ú}ÎýÆtºl¨Ú#¶0€Ï¿&–ÎÆÔ–K™ž6do,[ªÈKí;C|öÐO88=*´Z.¯ªÜ­¢žèBüÜtÎ95½aðßÄÚ[C{¥ÝYÙä4±°\0Ç\c‘YÕœRi°öo—˜çÅ·” •RÑœGÕØI• *1`㎠®ƒXðV¡bÞˇOž@‘\7X‚WÀúô¬H-Ú §S’(N:ãÿ×WF¢šM3.Yo"8Ü7™œ¡<ôäÓB[]Ü13‚XáO§z’ÝvGvBäï ½ª½Ÿ‡æÖ\‹y-ã“k>Ù¦X‰ÁÆb'°ú×DšZ•ó;ß´ÿé³À^;˜''°AõÏo­}aîu¯ C¢]j6в@–ÖöÑÚ³.ŸÌŽNÖ“ŽÕóá™´›6ók[½›Ä±§Ý;²ëøq]mâØß^½ÁÓež8RæXö•gÜP†Ç íÀ<ò@ï\ò¯Ê­uF”öW=îÒÿTi5MböïTÕ¦§¸½•¥“åbIÚ¨ª98àWÌšíéÔ|BÌv¦Ïþµõ–·vúºÜ–rî3ž§Ðw&¾IÖ´¹t­zkYÕ’HÜ«nëœW>sIÉ8v‰n5c&y/×êOô¯¡þèÓYøVÝ®ÃÎLÅ6€p×€+Å|¦.·ªèÖ{9º»†ÝXŒçs…Çë_YOikd‰n-™ p¡£ÐÇùTc*4£< 5”Ù̘ÕçŠ<©Ê‰SÌÇ@xÆ=*GÓàº*ïioå²á„p1Üð8=yë[w~ …Q:î|Ò1Ï?ç½\_Ê,—˼ˆ”ä©——ÛŸnžõçÙô=+zèIå­wnW!³êG52xI ù©Î~U+bßÂó¥çˆ8Q¼t=3ZgÁÓ™år¡xç¯OÃòö«M¤e?xãµO‡Z8´º2pÆ7`J€¹ðçšùÊp!¸@vÎ3Þ¾¾ºð´‘&î%@>ã#=×'­|·ãþÿjz~K‘òㆺ~5Û‡“m£Î¯Y™.ÀDO·QÐ×?zÛ™È$ž;u­ù0äŒ{Öâ€Ç$d畯E>‡1®@ÜzîïL‰ÊñÈ÷»á¿Ýx¯ÄVZm¤Fi®eUØ ’G®ïöŽðfàßÛÚipEmk-”Nc‰JÀ²–Çû[sõÍfä”Ô{ -Û¡ævÌXŒœU€B¾7`gÆ£´N¼ÜñÍX‚?5ÎÑ3Ö©ö9Þ¬¿§ØÉ¬1ïšR=+Ѿ~ÏÞ+ø£ñbÏÀ–6/£,Ëö™ÝAKX7ó·#*£œ’FÑÏÐþÎ? .¼Aâý;^–ßÌÒ¬ÞL¹]Ëæ„;"Ê ý.ý™ü ¢xCÄWÚ³Y@uÝP$fôÄ‘Ä +ž %ˆNÜýÑ^}Y«ë²üÏ ËŸ²m¥«:¿Ù×öIÐ~xxèÖÁ5V“wÚ/®b@÷;ŽNåäccÐ}kãOÛOö_‡àŸŠ­n´n›ÃšŒí¥˜«ˆ¦ wÀXrp HŒ’¬kõJÆ5‚"çõ¯ýµ--üGðÅ6þTR]ÚÛ¥å¼wŒÇ*;l'¡dV^;JùêÐRNOsì2ŒÆ®ö^’ôïêÇiÝã•‘þîJ²ã§?çò¨a¶^[…aó8æÇ?Z·¨ ÷r¶7{uúÖlÌ`#i*Àç ôô®Xë±úÍ}bÓ>ÚÒ¼>mì­£1°`Š`Üñ½gâ߇¯. þ™>§}h¿úf¥Ü¼hù[~À \âº?ÚNË\ð·ˆ´¹4ÇÆ•« e¸Òõ!æÁ¨W”%[‡n ñ×Ñüwãµ·kvð&›slñù8„!20W ƒå#‚:~ÛS†¢ù'+38Okx³É4­v?|Ak½F×ÄW&LÝ^X%œ’\‰¤ŒvŒ€q»žŸtŽ wð¾| ¢\ÝZ_Üêz ĉ`—TÓf‰d`>Fî ŽýEuwZŸŠ&ÕWáÃiÈóo³»F ð  ã ®CÆrø÷Ä %Åï€ôé$tÒjrE(Æs‚7Éèyí\¯0ÃGy~(êx-ßæ|íñƒKÖ<âïxÇ@³}WÂ¥­á«)AÀ”ÎåPÄò@ëÍrþÒ¤’&¸C ¦'—¸‘×üô¯Kñ¿ˆ×ï¨[K1›f§·ÈX*ü¡n~U €:“Ú«^ø[Äš³2 ÙB;ü»7ç÷̼ôâ»'™Ô¨íîÛɯó9ã…ŒW[ú;áŸ^ÝÃл°’ÖT 7<ÿã ž¼zT^%ðÄP§ú3[»m¶Üç¿o—Ä×~Ÿ 5m"þòÄZý‚…Y Eb•P‚9ù,PŸŸ!HÎ0r2*•÷‚®î%, °6ˆî›¶D1}t¬Æ¤ÖëîFN„SÙþ'+¦joö{=>óR¾k{hÝbHœ…#æP28<þè¬Cz¶\ZAmu (# {gÊ{1`H3ü»úMŒ1xIÖ'N’é¹>eŒ€9è2.>>SÀsÐöÏ:þ(¸–óLÒ4ˆûJŽ&AŸUT•Wëþ÷zà“RM½™¬~=79_ø«Tðg‹Z+øm¬õMÏ#* T”)' ¼qÇ#Ž+§ñõSL’ÚòX®í$8Ô`ãÒ°õ†^"RGÔ-,â‚3¹b¶’¸ÉRìÞýqÍ7RðõͦŸ$ž[©N ¾ôÈõç8Î+–TiKÞåW7sŸ³qlÍÕüMq¬øe4y![B¡$ÊÀ’ ÛˆüO­yúê žÞíÁAÇ5êV›S¶¶a½gtÝ RTg¾3ÛükÍuK?ì½FkyFÇ(Œ»¾÷ÌŠëœtá…tP¦¡tæÜc~Æ4—€%Òªà–ÝÇÓÖ»Ÿ…Z^‘¨ÜBuˆžt*å¢LÄ0ÆpAèk›ÒÊy—k*†Lub ‡ùé]GƒµÍ3JÔ5{äÙ[uš^z|¬è½p3»Œ×TàåUÔª2Œ&œ–‡·øcÃÒ¯¡—OÒ'…‰fK‰D’Iœ ¹fèqÏ­tÞ7ðäÚ§…u@ÖFi¼†’uc²@7£“Ô|ÁN{àûçÅo~$ø{K™Mµž§1¨• €ÿã³>=½kJÛö€ƒÈµÓä!‡–kødÝž1‚sß æ¼ß©5+Éíæ{RÆSäåäuÞ¾‹ÄÞ ÚÌdybb¬OSõ÷¯øµáo·üL×ímJûÌo*Ñãv$ŽƒhÎqùs^Ñð—ÃWv¾µ¿]/TÔ¬¼Ö´+mæäžd…óp'ƒYö Ÿ@ñ®¡&­¥K¦O¨Z›qd÷QNB0u-¹ Î1éì1¼"Ô®qÔµD’ÔàÿgŸ…zÇÓFŽæ52³¡d2n‘Î3øWË?µ/ƒ…ãhõ¤e–ÛQŒ#”Û"*ðxÇ öÏÝ5öæ£áû˜×Ë ¡Oð#ù~5óçí}¡\Ÿ…ö·b"#²Ô¢šà°ÀØÑÈ€ûüε¥8¸ÊèÆ¯½ä 1å¶N@õæ±g —ÀÈäŠÚ‘pÃ<:À¸˜ïsž9è+Ðù[:߀÷/ŽË‹N  uèqúWµ~Û>Üh> mªHk'LÌ9u tãž¾µÀþÇžÿ„‹ãÞ”’G¾8žòM§€þd~uíðPYbŒx:ÇåÍ{™ÝW¦`ÿÀÏ_lw®i+V‰Ü´ ÏŽàB–Ĩ9n™ôÅ:Ö?)þ|ÄñD®«íÎ:-w¼:|[ñ Æ'³k»KqçÊ£€pGñ5´ß*¹ÇM9JÈû—à§‚<'á__Û•Ôn-EܰÆU.K‚ù#’úì_jˆeÔn$.[´@1€=+ê èh¶ #a$uãóukºŽÝ°¡GÙFïs§ñ>¶šm± Û[Ò¾Uøûñü%¯Å,žbIa*0Ú0AR1øæºï‹¿â¶’Hâ™Y¸`žÙ¯ÏÚ³ãºÁ§\è,Ú…Ü+沩"%ßëœd…<{Ö*.´¹Q³’¡ö<–á<ð$^C ç¨ ÖuÍ©š&Ûó2vúTÞ»7¾±|’Z¬ëŽ?¥O`ùÇÍМó\tÛcöúrUè¢ÚI?ÀôŸÙ€@ž;Yep²lt@[”#ú×Ù:tâ7òg¶'ŒãëÍ|á=J_k¢ò)Á*çé_n|'ñ³xËÃÑ<ìX‘TmÈ+Ô»(Î2÷OÎ8£.œd±qÕlüŽªëJF]Ç>dàƒééM…-àbXãôB¤ƒß¨­e` ’&C.p0G>¼Ô6I°Ë6$aÄ¿ŽŸäW\cѳóÇ+•£²ÑÌÅÅ´² OÝih<•Ü÷À¯Nøªéžñ.§>£}m¤Û][á>Ñ(ŒnÜzqÈæ¸9l⺌l8àŸN•‘ªÏ{okåA“-ˆãÜr):4䛲¿~£s•­Ð÷ï‹z®™®¶‡qmk~wˆ¬3«Œ2“µ»ñéésAЭʹ/¸‘´sšó߉ž3ðað«ÃcyZ¤l-¬°áƒ)ኣ#šµà¿ÝϦ۴[®U‘Hªf#Œó³?•~uRŸµŒú4{Ø ~íDZë¦Ä©Æ1êk…ñ‹Åmo(vËÖ­Í®j&Õ1a©0c€~Á9¯Û^Iñ+^¸³Ò.gŸÁen…=6¹ kÀ6ÚG£{-Ï•¾9ëÐ\üPKDdñ:Dß!õöï\íå“jvWd‰mãy °ÀÁ“ ^p+¢Ô|CáwYc¨èæKÉf*'(ï›†ÝØÁ$uéï[v¿ 4OyÒØ[ÝÙI°+}žI#.8ãdŒã‘í_©á²ä°ðŠ–¶>v¦)ªŽñ&[¨%´Že]ˆ&bÇ®0«»žžŸZ£¨Z® –s™Ù­“%›iϧn? »ªx*m8í"¾ºš;ÅW YBçyRØàwížø©×ÁwÂÒݦDj«‰8Àô®yeՓѯ¼ÑbàmìÖm×ý‡ò³Fì~ŸçÖ¹GÒïàñÞ²²]5ôñˆ6 bˆ ¹Øª™Rp2I=§ü4ä2hö 9á‰'×=½h>nKÍ ¢ž@,F?ké!†Šêy©sçÛÛmnh¶Ì&Š"9W {Žj“hz»æd¸Ù“´¿Úã\×Àõ¯š;%™E²:ãò)?™ü꾡5†ŸbEçÙâ‰Æœª3Ç$ÔÖ®œc¡š“z³çËÝ>ð¢ƒvA¼åcŸO½žzÖÇ„<7s%Ôr__¶žeΖÓùxÏ͇ Fp0:óœMz>©q¢.œn­tô¸Š ÌVð3žŒO¡ô®OÆ^&_è×m¼,_u´Æb29èì£æÚ9eÇB$V°§fµ1©;-7/ɧ[꓉æ¶Òµ)O“qumM€Ä#2ްì[y$ ;m3JÓîí&ÕVa§=ÏÖú]¬6Ê¥‘™]NÜFßx·%qÔWÎZ·ÅÝjñOiq4šEºyFÚ]6]™Æ°b©ûùÝÀ8®çÄŸ5xnÃOðç„n´íR8b÷WR €íó2#ÎËd9Ç=*Ç5¥¿SÐ|_ocx´x|ë§A¶5 VLƒ’ çÝê2z㎟KÖlT´z ê±9û–²ìÈöÜ„~¾µðØøßNñ¨]è3Ik½ì"wØIÆ7g >€×ÕRx_LŽÒeŽâS¹¿vd ¶çi‚C69î§*HÒ Qøµ>^[Dzü"ÆHÛ¥Ùbƒ§ðÂ1یׅx«C²{ëÉñu-ÄMùØäO)ÃeNFpG`×Ú~<Ò®,µË»V¹‹UÒ§D{ycŒ(ƒ ™VmêÌKçctê'ήþèÚÜ‹sh¯B»‡±$ûåúÒ„¹Y¿²çIØùbÃLùD©%YA ûËë[Ú-½ÄŒÍáXõVÈ)æ5Çz#¨?ˆ¯©4ÿ>kW™"µµfPçϺuÉǦqúÒ«_ü:²ÑÞÂÚ172Ç!•NFväüê'‹oáZÒ¡¿{SÀ4Ý/KÓÙ>Óà8-A¼úWã]zÞÇHÔ/¦—l0Gæ3±FOAŒã5)Ü­l~P\’Œ}+•¸ É Î}Mu7²árrÄ ü½­rRÚ]J:£$ãšîJÛžnïSé_Ø"öÂ?ŠÚ¬âÔ®ôÆŽÍ¥ "XÙ‘}X¨'î×Cÿ¹’_øbɾô[J= ’²ä¬5òÇ‚ü_©x Åv»¦NÖÚ…”Ë,r(ä¡ã¥}/ûyÜ=÷Äï ݰqç†,î£20%–Ig`O'žyê+O}Lèsµ.Sæ8ó2I‚Àõë_t~Ãß ­o¬ Õä³Ye™_$ÇÇxgÓWÄòXP€H5ú©ûév¶_´kÉÝR“>ÐØÀóNèqf9)zÙ]%R³o¡ô§‡ô(4(EÄ¥a)œ1O¶+™ø•ñz/LžËO”YYC+”c8¦x£Æmª,ÐA!‰q€9¯.ŸE ÖZ. ¤D¯1Ž$$åS×’1_;I:’QGÓVš¦®ÌÝ ÁÄÙ'½¿½{K6>â^sÜ/ óëÀöøÇöÁý¯ü ¬ŸÙDòéÒD¦àKFÙÛ»¿ ~ú-¦Gqb )€±¨Uü±þpk;€¼¢ÝiºµªÞC4f-§¡\ޏÿö¡OÙlx?Xr•ÞÇåÃéKèRÂr 2 =ÿªºƒ$™©ŸNqÇøWCñàýßÁoÝXì}C{Y¶ìÚ~ã×€äóšÂˆ‰{9¯œk?3÷\ެkåÔ¹]ì­÷¢.wž‡-“ï^Ûð—ârøEâFExÎÄ`1Êôÿ8¯»‘ífW•<àôÏ¥tÕ!ž\M–Ú˘Ž+šÎŸ¼bt)b èVWLû‚Ç⮉ªF¥‘›—…üxWkn¢d(—#pp2ã_A2¢ˆF˜Àçœ}kµÒ>'øƒHX£‹P•‘…¾aéÐ×T1¿Î‹ÇðL$¯‚Ÿim÷£êÛkHg„¦ÅG9#nïCœgê¼Þ{çÚ²+£Ë`r>¸¯2ðWÆË]Ke¦¦†’VdÆ÷Èéù~Uì:ߘÆX¿‰3’2JôiÔ„×4Yù¦a—brêžË?Áú3È¿h‹Mø{w éÃUŒí"SîÞ:J£)øä8‘ó÷ƒ?l/ÂK­þ—«Û uX‰Y’FÊðyb™¯¸õ»qdмI4'î>œâ¼+Ä¿<+â)®$]MÜÎK™îÎzädÁÖ¹±xL>*)UW# ‹ÊÒhåßöûðzÙŒIâ9ÀDý­^Sñö»Ð|_°Ùi:•ʲ€Ë1A¸ç§ÊäãÒ½7Pý™üì‡I±FP1±=1Ø Õ(¾xbÅ„qé6j2X:Â9ü3úb¼¨åx:rRIÝyž›Ì½Úkïg˜|<ñ ×6\ [wŒ-fW™°9¸QíØÍ{¶®Þµ’0•-åÚAbäqÏLž®*–àûK(‚ÚmEUû± c¶;p*y´³cš…Cö.ÍÏ>Ýq^Ý9òi¡âV›­.iJê1ëЪê+h­áT´@‘ž¼®{tãõ¦+Gl6DaEô[Ž+•7ÒÊ™[}îI.ìK>}j$k¦]Ç×€öªöÖ2ä=Šè[¡ (@rÅóƒÏ·ùæ¨Ï­ÃH$hÎ@l*œ€=‡ùâ²×ÃÚÃÈìÞRŽ¿0ãÞ«ÿÂ'sy2ªH|Â1¹xñÈ®Å9Éü&.(Ñ—Äš\Q3¼zzW?¬Kw«[w Bʧ¯¸Oרçšé!øuqy ˆÏ;'vXϯ_z½}à›å´hã–t]¾XžWÛ$c—-Ô¾ˆiFÚœ>Ÿ¨=Žž'¹`’ïI帔ϒxS6àÇœcž1Æ^ÔtÛMNÕnÉJ<ÐnÝØÆ3ŒóŒóÖ´,¾j >ðì;»cãcúþu­að÷Wµ˜¼Ð@‰Ž ÌX}¶ÿ3QQUzy§tì|ØÄŠX*ùÌ>P1ÓíQê6‰uk¾P€Û°äuã?Žqí^wà;Û¢$v™6p1àIîïjŽ×áÆ×‘®rGtÓ¯¬cJ¥µ4r‹gaá[XQ]n „;ˆEÎÒAžÉ«°ÙÃepΑÜUdçŸÀWE>r¬Û,æŽ2yh×ýxþ´/‡%ŽYíî¸ù†N}ÏÒ ífˆÑjsú­ôqx‘—n ›[æÇ NçÃåÃYŒ .Üñ×±=+±‡G¿i‰qé™:{qÏJÔ·ð¤,_k¹Š2ìx#y'Ô9íÞ“¤Þè¬3O Ý%äCÉì$±W^ÞžÿJ«â;76Íg(<¿yƒœƒÐW®¶Ÿ"ŸÍRIÚ«´~Y÷¬ÝsCS¹R»VUP ªn8þéç?­eõ[ì5RÛžM¡ü8-3Çç4¡™Pf`O=Éâºh¾Ãc+ÛIzd]»ˆYTmÏnõ®£IÐͬL\»ª¹Ê„#ñíZìÂIÜäI÷\´ã¨ÿëÿJè§F7´‘r›Üám¼!i£Â%r¤†»Þ\°=8ÉÀÏ·¥-ÌкlX¶€6†ä†Ï§Oò+»ŽÅ’[/$€Œ‹ÏšÌo XJéq`m+Æ?- òd¶pc‡ÝïœTˆÏn  ½À\öõ#§ùÕ{¥ydUoÚ $§ ž¿^Ÿç5jÉ p[HŒ²J|ÐA0î{žÕb+ë¶¶ ¹ñŒ…^«øâ‹;¥KWBBwjýsý;ö¢ÖG• rW V=>œž1ëéM7°4$’]\ÄÂo-£#–Æ=5âßµ¥‡ðsÄtÉ™RÖz³7M¼÷'·å^Ï%ËÁµ$"8^NyýE|íûfø6÷Æ? AÓÕî¡Óµ(ožÞÕX¿—²H²6Žpföö«‚Ô™»EØüóÔõhј#`pçzZŸOñ%–ÕK±Œ•R~½Mÿ½rD2IØocÅiéþ²e9¶‹`ÁË.Iã¶z×m­¡åéÔʺþÊÕË)Ë>rPFGR+ªøŸãwñíφæžq<ºn‡–ìCqå4˜>Î9þª“Ælcx,ty'm¸óv„Œs•ã$ÿõ뚸µº³@÷´s’Ë·4=ÉoK"Ä6«wc’víÈãw¯«ÿd‹bðÌ:Í–ÈH#˜6Ã&yÇ–Çà+äXî¿Ð^49f%xô5Þ~Ïz³¬üOÓí4[»{IJ<—nV!T6py#·¿jãÅÓöÔš;ðX‡Bª}‡éfz|…qö†s[¯áÇó«º]•Λqwsnþ}¼²ƒ4' %O®3Ç9¯:ø}âhï4ø¾ÕÝ£¤†lù‘¸à«Ђ1ŽÝ+¿´ÖQîÛ(ÃsŒ×É·*/CëÚe©Úèú§ÛÕ#È%NJó“‘š×t{e,!ÚÎXnö8®'Â7ñ©U£[°uažA=°u£P»”Œ] œà/‘‘ý+ݧûÈ©£çk/g7Ï>>ø@xÏáÖ«‹!=ͽœ¯FŒŠ» Žì£ò¯Î¨d@Á‹ÎíÙÝéþ…~²~å­Ž%I‹ƒŽ@ç>¹¯Ì_ŒÁ?õý&«o Éx6®Ð"q½vÀV Ç÷Myxè5i¤pn/Z˜g×Uù3ŽÔ~v!W;‡¯çŠÅ¶¼—M¸.ƒ‚{àÖ̳¬Ä’ß0ü¿ÄÕ,ÅC–Á=z×› ]™úeM2=CÀþ/¶¿QÌË’@=kÐ'„D$N¯žXWË~|Ö²o‰Ú6IVµ·ŒµhÁöb3’*¥‡ê…O2Š÷j-Od±Öä›S  ´¡~\õÍ}ÇðGÂúŒÞŠhÙåQÛ°ÇÞç•ùùðÒO6úÚfBX;’xÎ~µúðWâm†ofÒÚ‡ø‡÷¿úôè^º>;Šq­J4;N¯ö¼4R|®>ò·Z¢–ë,8“î± çw¯Ò½6êÎÇÅPŽH✠‰BŽ;×;áKûpG•=Ҝęzäf½>eSÈü¢T¥KÍ{áÛW2(‰œ/!•»}qY7>w´imµòÁÁŒùOÖ½ ­à•¼ƒ"$êÚÃêÎ;ÒZͧîZhÚ–ù„çÿ­úÓT“z™9¾‡™iZö=Üb8æ–W`¼í ¡õ¿¨ødjгÝD±îÀŒ„¯`v©àñÞ·µ?‹ÙÄñLb\’v®íÝóÔU«&[TX.N c,¼õô9¿&–1æÖç“kš9Šà4J¿,²G‡ÉêöéøÖpð¥Â–þ¹œú×¶_i±ùLñÀ&‡ÑOOÇšçMeryã.?3R⺡óX×Ó,㹂@åƒFA%œ÷ëôþu§kmS1‹>hP º)ùOáí×­2Ýá‚ßjº¬H;¼÷ªou ÓÉp¥›¶àíÅz+WsÛ/‹™Rñ ˆä`ã¿zY¼écpÒ*äœõ=¹àRÙê¶w³$1^Ä“Œ|ÃäqíW°Cùe— ˆ7L{gZ]H3ììZ8ŒØ Cg>Øç®\’Õ|ÆereÞÜŒoåøÚšIkITÆÄgŒm?7OoÖªÙÍnÚŒr´Áb’BwLúŠv4¥Ò­tÛ%)ˆKòs»’>¢¹‹½F(P¬s.òrÃ<æ·õ»õ¾VKfŽa‘¸)9RN#ÿú«žÔ,%{t?c>hsÇ™î:tö¤†eÛêÉå‚zØ­{Ý­k.>vQÀçÇ?ÌzÖ Ì¾[X>q÷yÇÐŽ?ÏM"Ý®'Øüîøíðªƒÿn4˜¹Ñn¢ºs»ñÂÌÀDìG,¥HêII9'„e0ÁxüÍ}©ûYü<>(øCs©Åcq5þ‡"Ý[›a¹˜3*Jqœl%ÿ혯‡ôÙK¦ß”Œ `u®úSæ™åÖ‡$‹ªÓ*¨2oCü;z ã<{}$²[Æ1°òHÅ]dÓ1ùcPv““ŸÇÖ¹Bom¤\ƒ&Ðv¯9ÿõ«Wäadr4ŠN2rIW¥~ÏZÌú7Å&ubcbgŒõ¯5š#· ö Ezìë§O¨ücÐbi-0tÜ?ƦKÝÕÓ¿2±÷ÅÛ5ðÏÅ ®,¢u²ÕI¸y0v›‚ÌsÜ€§ZK-jSµîR½}?ÏJõˆÞÿ„ÇÂW¶ÉÝC`šS‘¹Nà '==y¯ðÅ˦ëk…òn"o.Doà`pAúb¾cM'̶>§ Vë•ô={áDüA~ÒÆfFµùx92äŒ}kÐ¥Ž=åâË¥Xmu篽yOÃ]cì^(`W*mÝxëØþ?ýzõ«Kå½]ŸhTnIŒ©ËþÑãŽúÕ׆_ºMX¯âY^¬[áÚo”³ã${ ÿ!ýqò/í¿à6±½Òü_~íñcq†ÝýæNžŸ?>¤WÖw7Ϧº‰„?uóŸ­Sñ߆ôŸ‹¿õmòุ•Ö QÁÇ3ÆrGâòW‡µ¦Ó:ò¼cÀbá]lž¾OÊ)î$$BO®OPk*âa!-· zÕ‰§›MºžÒéLw»C"Ê2¬8úU/µ\$VàË,ŒQG$žÕóðƒOT~ù:Ñ”9¢ô*É0ä7Zêþü5Õ~#ë1[X[9¶Ý‡Ÿ3ï^³ðcöPÔ|s¶÷\Ž{K wsÛ5÷Ï‚¾è¾ÒDZ@e™X1Ï €1ŸÆ½JT9•å¡ùæiŸÂƒtðþô»ö<·áïìë០x~um)/&§ÍæÈ¬¤z9­½OàKÒóÂWâÌXÝÂ1ƒ÷[½zçë^  I½d ÃwP2zp:VŠCPÂAUO#ê+­Ò§(Ù£óÙâëÔ›©96üÎáÇŠïíµô½Y^Âéwafd`òàŽ:Ž+èC:³¼‚T*Ú{b¼¯ZÓàÖ­äŠkwu#ïÚrGê+‡Æº‡…æM9§F¶?¹Y$\•ãXË< ójPpÕjŽêX…SIhÎGöó×­­t++«eº[ûKØ™¦²Sæùep'އžàW˜|øÌþ/¸‹O}B[Û7,î£D1þ?BxŽÞçWЧ¼uYšU(˜ Æ?ƾaøuû;]h¾%Ô.นVIžaP-ŒŽ{u¯K$éò3ƒYûDþGÓK=õ´%-nÆNví 9Ǩ?Ϋ®Ã‡œ’îs¼(ÇáÿêªÞ:­•¢Ûê!£|9ëŽ+Wíñ¬Š³3lnr1ÛŽÕ£Vٜɖ~Ù*DR)Êü-¹Ç=³ÿê¬ùÖÿ~|°Aw`´"½† ç%N}?¥h9gýär9FäÎ CîÐÎmÖdÜdE²÷ïØvÅejí¨4pǺ8GÎdeëÎ:qӚ׌ù¸ä0ÁÂ7Cõ©£°ê$àà“Ž3ÔÿOÊôò(f@™Qòägæë‘úT–ºbڈǚÌàq¸ðy÷­Ò㉤w•Ë.Ñó‘œÓr»¬dÜæ T#væÂ€?»ß?¥6BŽU<·°ÇNù#j´Î»ŸÌ(™]ÎqƒþFqTØù#.øþösß××ñü(Zêÿ†4v¼µœ³‹`Òl{Ž„ÇôúÕ©­míõ ­å>` ž½>çž•{L·véfL)é’{œý}êxlìá–G2IÈr[æ$òF­g}u)£œ¹²[Ë…f–8öüU üxÏ·½TRÎr­åÏÃ!'Ÿ§Np0jI®T†1³gÓöÏò¨ÔÇ,»C¾ä*HUAÆqÓ¹›ièJ6¢Ò,–ŽFÖi§?Ö³çÓáBV‰NcŒQ_Ò´"T³²û~Èž ð 2]JúΨ¤{„/ldõ=¸ú×~ne¶`¬xëÄsÜZÒÓ¼AåºÆ\åÈ'€HíÒ¢xÅóXôçšbåIPu*þ·ÜÕ··¶ klÂÄÄ0©m{Š4ýbî9ñ4rK  xõöª:ž«jÎÍbFYU ®9üé,üE´ÄÈv7,ðs×8==;t­\ö<¾mNÂ÷S¶Ñ4WP¡“'bÊ7*žÄƒè}ª•Ÿˆ¿³ï ‘HØŸ˜¿ÞZåõŒÊ2 (VèGÔž*îm‰ÚæPAŒ…8?ö©ä õ=õx/âD+—Ÿõ„¨9íÛ#ó®3Åzm–«i(yY£u+ˆddd÷¤ÿŸzŠßU[È y±©É …I?Ëÿ×Tu ~+{}ÊŠŒËÒUôê~•Ÿ/DÊO©Íé> ÑtÓ3j¾%¸‚<…ø‚íÐwÁûf»=6 -*ñVÁ¼Ø]Oß–Ýõ9?xÅ_Šš¾Š‚++5—tª §¡çŒ•±ð›]Õu›»i/\¤ŽäœŽ;äÖp¡VíèmR¼&’KSÜ%™üÆßçvO}hK…q´‡ :ô­+q¢4’Ä$äã#©þtëí>xÆqÁ*d^X‰7tär?Q.·5¸Ø“bOªÇ}*»Ój“Œ'óÇoN=*y^ [&qÙ˜rGáNÖ šË¤F t“ˆÆH#}Ïzµg§µÓo1£Ž×žGù5KJk™‚“ R$ù[w™•u«,Zu ŠGf—ïTÉÏ¡Â^ÎI+Üt¬íZiSQ£ºxa2·Ry9÷ü¿.‹Áöw?c•å»Gwo•‡ÞQlüÖ­Z7bHÒkxÒT+œœ) ÇãôÅTÖnŒZI‘OÏ! àžà~GX¿¸‚i2ò Q°=å\ýõýÕòìó\F­’ÏÞÇ^¾•Ÿ/Q¦Y²s"̇æo¼œ|f¡kTI=„ @ˆç?YI …´Yùðyuwì{þ•e ù$à·Í·$GL’9Å;j&d[Z­œ2Kò—<¹Ïn*¨.%‘ÔÃŒ&Óü#<“Ï¿ó®—T†%²ÌhÈ;pH:g9¬ˆbXä\‚@?37®:~‚Çm8‰"s0Á ÈÇÿ?­Q¸º·–7æ;ƒŽžß^¸+åÈØ­cž:sŸ~kÌí,apé…VìOùîkT´ÔÉè>Ö Œ76é…ȇžß­1¥¹tÞ3ñµŠí^˜ã¥=[ДÆ]O#D« èp9ùë^MûIèþ(øA¬,êñ6›š”r¨ÄŒ[Ý7øá^Á=Õ³DçÌŠbp0$ð®sÆÚ}‡ŠüªéM-¼‚îÎ[iʨt*N^¾µqM;´)j¬~ciÖ k1š)|å’§$ÃüþU-ËÝÜËåÛ˜˜“‚—œãó¬È`¼Ó/“ÌŠe;Z& ÷ü+¦ƒT‚ô…-šz©u®¦y¬æ|Söåm>ÝVݦØQ‚}ºõä×ÙŸ²vm£ü9ÞÄ i·3¢u(NN? øó^‡ìIpòœÈ)<ôÐJúÿöJÕ-õï#-ÞËëvtxk6ÐAqÈçê+9ZÆÔ·=ÂÛZY.“2JcÈUe;Èß³oÝÈÀ­ÿø"/xãO°’å"œ™d‘>T;wsÀfÚƒ=Y€šúþkº¸`#º†<ȬÇhéòõéï^V;™Ar£ÙÂr9¾g©ðäŸ ü=ñwQÕañмg¿§ÆS𦭩@Ä 6Ø£ "2í`ÊYpø$6@»û1hÿØ>Ö¬Öz}Ö³5ÅšJ˜gƒÊ…½~ò9ük¿ý¬åÐôë?ªÜÅmâûJßO¶¼µ”Cv!‘‰š6eùŒL…²‡å$©Æ@­[-AÞU-#‰+µð«×»À¥R”\Ö߀±–Œ”ä™g(ϹvSÜU¸n£—î>`F1Z‰Ð"Ç›ÁÄy;€ìO~GJŠÛM>c¬‚Uf eT‡×ÜÃê+ºJîç4ëûØe“ˈªœ¿ÓPfH[˘*:1*GN?Oþµ^3ÎÒŽc$/±•óÔ¾ýG_Z¶º,ÓDûB1»ƒ§ô¨øQ^H‹ûiVY&ã+–ǾAªÂæp Ndo½´¡ÇáÅZm !Ý›¥ÜzmsÏéÍ:Äiáó-ì ó‘óL ü§=k7$Šål«çDQ¥žÝð#nÿwÿ¯Ò´RêÊK`a· ŽJüðqŽ Y‡VÒ 2˜Š6Q¸ã×çëU¥Öô¨$2À¥û)ø¬eVY|±nÖüOhƒû29Z1€Âf1ûÁž=J¥nÜ; S•]¼¨æ´­¡.Îíí ÏôÁÆ?ÏÓk’Û#³‚Yd#.îî\7ëϯò®žòᢂVhÚH‘rŠIû£¢Žj¦‹§-Ŭ÷8)Ú Ó®~¢´í¼>·pþø…Ú¤=ªZÔ«œÅÛ4^g’pW X/‘ϧ9Ͻ\7“ZF‹+…%S?5»¬è:~—j(_pïLãÓÖ°¡Ž,¶7¬ŽÇ Ç8ÏaÁô5£i+9‘’ß12Žzñš·e§Ç•Ê$®Ä1\wÆ(’]‘˜ðãžžŸ–jÌ€ ]’?–¼ŒžßäÖo±IÙØGw3~íPçw_ÿZ’êÒÊ1³¢ŽUçõ÷ëøW+{¥Ë<­3O*+1ù|Ï—?Lp:WEa¦Ì¶N8$÷?\ ¶’Fw¸ßÜ\ÄÁ#hv6ÒÌÙ#=8ÿ?V»Ó Â[r’oÎ9>¿VºžçUÊÉ#þ¹©ZL!rÖàŒ^Ÿÿ=§©VЧ."[Æq“€ôþ@\*ʶÒe’xÔ’ÜNqÙ'éÛšè"ŸÍÝùOM½9ÿõúSÞB»7òžyÇcZó[C;²Å#í_‘vŸ0½O9ôïZ)o  ðHÀîÚ$ÞÏ4é-RVÚ@òò:œŽ¹úãµ@!)s:ùhˆT‚Gô4µbFðŽKvHßÀ*:çØý{W4ʹÕÚg9ã* ýsíž•¶ú‹¡ ‡ê=ûUÈp³ ±^vd+ à{õ•J44AfI#Œ¹o‘ŽHäã®B—:`~f a“$qÔ…]‹Z³ÓíÌ3ÎPNA'ž:J_¶ÛÎí"LÇ#¨=ǵ5tî6´*E¤}™›ÍTE`[‚y^Ý{õúÔêÊÁYI''BbOùúóPë7hò÷r¿yO<§¥Pµ ypÛ7NA!wA= çÛñ毖ú“rÔÞ'³†6WUPN?q€IçÔæ [»KÍB9S6Ñœwì}i¢_a‹ósÇל֕¾Ÿ5 [Êtàg9ïƒ×ò愒ר7s"]'PÔ¹S”'åŽî¼ö¬'ðŽ¥qÙ."}¬SoÌ[ƒ·=‡§½L<ò$ ùd0Hçõÿ8¬éíb¸Aæ]ù.>÷”¤üÄA8öýi£Z$7yLVæÖ|Î˵ÎJ±Ú÷üêS [\)˜)9åF8ÏÔõæºSBh.7 Q¾có>Ag®0xÅp?~!^|3ðèó£ˆbD8!›?7^1Ïs] m™5mχ¾8øXx{⽤ÙMÇã916åÀpŠ}ƒàý+‡Ó<9jI€9î#?‘õ«Z¯Šï5=BïToô‹™X´«3HõÏÓí;V¶»Ueao8ë˜ùóÒµ½Î +37YÓ¥~]«ãb@ö¯yý쯴]rþöKW{K‹&‰bRÃçÞ‡=½éøx²Â.µHÕ˜í ´•ês€1êkìß‚Œh66žMòÁ¸6’Ýpx®zµ# 'Ôè£Kb¶µûDÜxcVÕíìï4ø5.÷1Gq¿ÎV íU“iቦíã^.øåñâB\,Z÷î.îd #[j7VöÊ1†ýÜn#ÁœÇ㟵4Kí÷µô@:¶©ãž3W|c&—weo 0Y˜ܼí^üã¥UlCöI7¢Ø¨P¼›>øgðºo_C©ëvÐÝêK0›ÍYŒ’)¯Ì88ëÖ¾¹ð޽¨ÝÄ~ÐÈ£vÕ-ÁïÇáU$³ƒNòÂB&=÷ «2϶íž8?³Ñ¡ò­Â)!@<ƒÿëý+ÉŒç9ssî**ÍÚt®xãËmÀFÙØôÿ8­iÄ òa"˜nyìkÉo|[ ;ý„‰d wÈ\ûÿUS_Iª#[]0Vò€øƒéD±PZ-Ä©HôÝSÅvq‚^W™ÔWëß'üñX—Þ+’Tͱhn<’NqÒ°ü7¯Aeª,s)T“å-ééýk·¾¸IŒ‘E nQòÁHô®*µå{3hÓHäŠÜjI¾C/ÖV uõ¬[½*{)Ü´ÇË'%PŸóšÞŸP½¸‰à{(Ôï¶:ã/›P±¸]±ÄÉŒ€Tóéž{s\’æhÚÉ>dJ ãk`7â3Zº%œÚƒ æ«›ŽÏ^½+O[Ûë˜Ûj",Q€,NInyö¯GÓ&HbŒ„ÝW Jçóÿ ºt9µ–”í¢)/ƒ|›óɼ…ÆÕϧ­mè÷pX9Ž8ð™qǰ«^h¼Dhw‡N]²çéëúU+ËyŒ ,P’Ã’OðàõãÖ»¡Eh`Ûêm\}VÌ«B_ `éôÍcÛi·–WK*I¶ þ½3ëÇÒ¤Ñu”„¬7Ž"I x!²:ûWC¨ÉmumÌ게ciôªŒen‚“LÔÓ65 ãÇÌ­gjÖvVBêÀž2=¿áYP‰¬äW@Lg¯<ã×­iÍ©Áum²Rß78qõê”lïО†'ž¢l)o/’1×ó© ‹»’ŒmÖ©\B“· ‚œ.ÓÉëÍ,PÎÊOž§ž§5®«bt{šv·¬Ó¤j7p7±Æ?Çô­í³7ÝÂÙÍs¶wA.—3í «ÀÏ©ôþ•ÕZÊ' 6œIcž•ÚíÐÌéteŽ>;Q´/S)ê}±ZJ|¿¿ÇAÆp2OáÞ².oâ´‚Yþ,€íä“íŸóЧÿ \S*Àc| šÉFû™_Äi6£rÌ(ƒîù|ýk1í~Ï<)nŒA8ù>POaô«÷p¬Nêwn<ldõý:ÖuÕÞéü²›‘› …Ê–>¼}?úÔÒè;ºß*£3c ¼–=z{{Ô&I\(ŠE(ü ‡å=úþ_­KöØnì±£@QÎü:ôŸ¥Oc¼×ê’È<žhåKr®Êkuä³"¦r\x©ÚfÄ À(bqŒdtÇÿª¯Þè0ÿgy‹é>Pð2{ñþzVCªmb$màgnsŒ~՚Іº˱'i#wBÏäÖž› rÄ>@ØÕJo.(d·bYVMÊÊ~öïøÿ:Ù¶1ÙÜ3Ã¥zçiãߨV¥ý±¯Êv ϲàîõ3x~mƒ~iuãm9¯!­à”9ڤæ?úïÃEÌ"ÞþÞA瓸G1!ÀíéõünZx7LðýÃÅ …µ³Ž<ÔQ¿=ŽG?Y¿¶ŽÕÔ‡q á…qWÅ{Y/tê£IÓV¹ÞI®­” ë ¤î¹Ø¹Ú3øŸÒ²lC]Êí#—sÏÞ úVEޏé6.Ín‚Ééž?šÚ·Ô´èe݂Ό!'ô?\^ÕIζßqÑh\žÂñ#ŽDVPIÆr $kÛ¸ã¹Q¾6î‰Ézž†’ê}Fkvhˆ{|d²ãôüý+’.Rå7ÊaÝü+Ïã\±•H&-6¡¥Åi;|åãëžÿ_ÿ]bKl„’ØR9SŸn:Ô¶º…Û*F$%”ÎügÚ«ê‘\…9ùKqÓ§øÖWÔ Öw_eubhÂŒ‰^Ý}+Üþê6zî˜<Í«<(‰’[Ž}zõ¯ž4ùEÉÜÅÂôÚß(ú×káŸÜhÐÌc¹)¹T  ŸcM6ôèUŽÿâO…&ûOÛ­.^0üdÎzãÜV=‘ŠáÂKnO‘š»o [9ŒŠODéøÖrWÕ}=ñ-´šEë2©ò]²¤ š“Nñ º‰#qºA÷dþ'ó®_Ò…Ôr)ÃmìÝEqrÙ¦•rAcëÎkhOÝ3”u:Ë-F7à›i,~VÇÝ>˜ôÍAöÓÄE€8û‡Ûšç⸶ï;Ërÿ×®‡I×£‘<™”³¯AÀ>ÕMßPHµ.ãl•û÷OÖ°®­™/ƶî®PíXgØþµU{v$³sèqBv5 o*$gîç=koO‘B¬‡$³p1ù~_ÊŠ+¾]Qš\¾˜˜ VÚ‡çq“Ž3úÕ=Ì\Ý 3„¸ÈÈéEvVnHŠêå·+’ÙÉéœ?Ò¹Hdû[Èämd…lw¢ŠÏ£¥Åb̨¡G˜ªpAǧ­hé’ó»»‚Ç`‘Ž~¿¥TKb’.ë7~Ež_,GÌzþZ¾V(äÚ±í×çùÑETR:Â4dÈh=Ôr}êx¼Os ¤Qu°?ÐÑETÞ ÷4¬5 ïË!eÉÂõ-Ï_n*¾¬"´›ÎWøv÷Ô(¬^†å²Go`²($gc“ÔöDZª±KçÊÅ+(ÃsÀÈãùž¥¤Y&¤–vÁ˜›Ã§#¨=¸#¾ dI§A;÷8eÎ1ÈéùÑEL]›ŒmZÄÉt¬€È3†+ê3ÇáùSo!61ÂòâMËŒd·óúQEtA¶‘˜ØÚX®@}¨‰+8=8ÍlÀ#€ø"=Ùǧ¿áEêhÆŽ™™d"NWrço\*§9F›åŒ“œô`qEÏe©¡gD#eÐÞÅU¶:ƒïX^+×^ÂÉbEáó¹‡`þ}h¢¹æÜUÑI\ó+ËçšåfgÉ÷·dgµ:8ó+åØ¢ÉŽzõ¢ŠâzÙ³]Œ_"âDc”<Œ}8§#Ç6Ÿå•ÜÑ}Ö#ÐcØ®{ö¢Š]F¶8@¶Ž³¸¡u+Î ýk™ƒYy¢À¡ËŸóš(®9-Íã¨ëRq:²…Ú’äðÿ^¬ÛHóFΨ+¸¨Î(¢¡|,hè4rêÇN‚MÁ•²B@ÃbºB Õã22Fá’~sEpÕ´Âzlc^im¥JÒ‰ãÆ#‘ïU$»ŠöK3b.Fßÿ_­W<ÒŒ¬Š‹º)G¥?ÚLf]Ìúqý IurtÀÈùldùÍS¶¶4êÏjѾ§3"8dkdñÚ½%u™\0eS¼ÈâŠ+ÙÃ$©#޶’#}Ad•k(×ÐUøä1ýÂP7§Qß­VÒVѭˬVI2ÀŸ”`JذԾÓvr¼{QE`öÀ7‰I$àãå5ËjQ+Úºä™ü®{®z(¤–—æÖ€‰Ü°Éäj(³‘pT¼~ñúúÑEomŒäwZeœÖÂì¡VÛÓwSþMX’å`m‚=ØXœÑE%¨÷?ÿÙ endstream endobj 2826 0 obj << /D [2824 0 R /XYZ 89 721 null] >> endobj 2823 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im16 2814 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 2837 0 obj << /Length 2150 /Filter /FlateDecode >> stream xÚ•É’ÛDô>_á£\Ä¢µËÜB©„ P`Š¡(ݶÅh1’3|=oÕ6Ê.v÷ë~k¿UfuZ™Õ›;#ÿ_ïî¾ü61+߸qìG«Ýqµ5«ØDnû«Ýaõ›óêœ]:Û¬7~dœxýûîc„n’&b˜Õ&ܺ©0¯MÞåÕ‰2þÛ­·Æyùý›x{°k/r>æ{Ëûè{Æùˆ?°T^è!ÊA<¢8 ØõÖÏ |¶ÿ‰&ÁŽMVÚBêæÙDþjënc?.¾ïúqÂ\vç¼ÄØsö½`sË‹‚W—ƶ¶êpã;IPP6Pea ‚ù½`°Á>¢¨JŽ„Â+*˜»Þaè¼íæìòªkêÃU ÝΙ\Q1Eÿ9ž 5êéyî6ŠXÏKÖr\Á³êÀ & ¼ã‘VÛî›üÞ ÿíëòRØÎêa ÖÐDsØ/i[ç¥Rø`Œ_7Õ"H}NEÖ¶¶å͵µ"ñýc/ù’šc£A:÷OÄa0ÿO9¡F%Gòßõ’:J9 L”âDxVfÕ5+¦D«ºSR­¨ ¬ŸòTV²¬;|µE•»,/Ø>‰¼ÚE홈=“±=áVÖe¼*myÏoW…uçúо¶&u{Ô (2þÿ†r@‚ð]5˜epñÓ›;&•#Î=ø}Šz²8ð`u¼²ËM„G7‰<çë«\G7iÚîÅ’:ÍUVöYi¾¥ØàâJ°Ê"’ÀêÒÔÚ}'Ç­&¶¯K¬!_mÃpÊŸòSîå%.b2::=!ëóYïò5$çŽ(y¥4rÁì3·ü_WÅ#“Cäl‹Ë„} o˜Q¯]ÁÁ¢” ­æ¸ „Œ”ÝL´EÛ!õI:¸dq°×@káEcÀük9Ì”†º0ïF.Œ²fBqÑ—‘7#üƒ‰ «Á—r¡.~ Çørrˆ/Ó½zÉ•ÔÄèÄ96ø7/È¿¹BºáÌË \K"W‡ÿÿ%îPI­ˆ~êF^ÚWľ&~¿èêfâêœæÉ¯×˜ñÉoÀ*²êtÍNv¹Fz©§OS(„+z$ñöz¹ÔM×jÚj¬åƒC~D¯cSéÄSˆ­?ÞQþ‚};çû3Ÿdí­1Ï ý„ãžå‹/0AAá{‡•IüvÝ™Baâ†A ¨’Hgô=è=¢­Þùñ|§Z 7 c½F æ@l×@?3MÑõþZ‚%2ñiÏwŽb†A'^ìÖ)>ß©æ-y;fÄm,ñ^à4|øTÇÇ÷# '€p,ÀB”ø$I4 Ÿ8g¡ È ”PQ×B²ã)»wF‚âa¥«ï0 ¦Œâëfï—BçÂ~€ËÛœFÚ»¼Ì‹L¢j?îQkSå'N¯ÊPIŽ®éûÂ~:«#i Ž tÚúØQ.cZA4ªp\Y{hy™ñq_Œô´ah"imÿÙÛL1;Ô`‚_bÀ‚«ï^ÿüÃ{†©7.é5R‹m -ÆÌt\S¸øQ±ÒÇa H~;]óƒ-òjx9Š`±÷WÓwö i)H‘äK%ùàûÑÜ"Èm¯¸Xú¾‡f!ò¾ï@©j:†ÞòîÌ@H@¶ÙgXð€5@¸BöÙ%ï²"ÿGbÙtxýU}U©TaU¥/VÈ+¬–ÔèÂí÷$æ† ºa¼š´ÅÊãN5ÜèU´Cô¼ÞSý‚Pß5.Éqþ\¹Õt§¼«B¸ÜïëFÉp1Xw#+àvbfªVÀ]ùøWÙ?ª±¾óB¶Ñ矗3ÿs#Ï-«>[¨^[N[°áðàãkG}–ÁÙ‚K’‘PBØœ’LO˜‚ÁÜïZ˜µe+Z/ØCæ`-vÆBæ¿Bh4õf)‰R¥T˜† )'@,Œ8¦nïK”Bû%Y€ûLN¥›#«õ…•#¤^B<©ï1RiòyÄ ?b:2à²GØ v³<Ò´ù ¯CiÜ–wEþ@]ï8õÁâgxB”jÁá4‹WuYö¥„©7MQÚÖ.ñà étp©Ã°Ê…Ñ3-žgz¸kŽÌh66£/kÆ(}>øêSÝ/Ü(ø^¬î#Ý 'ŸÎàà:Üá¸3ˆÐKA¼ÜóÂMYCíâ®- FÚ-£]ê¶Íï A£ ˆ‘ÿÍÇ„Ê0LT‘Æ\[ì>ó…tų N=7ö`Š =ׄc¦Ó¯ßìîþ}+o endstream endobj 2836 0 obj << /Type /Page /Contents 2837 0 R /Resources 2835 0 R /MediaBox [0 0 612 792] /Parent 2809 0 R /Annots [ 2827 0 R 2828 0 R 2829 0 R 2830 0 R 2839 0 R 2831 0 R 2832 0 R ] >> endobj 2827 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [354.151 438.538 361.124 447.385] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 2828 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.814 388.66 135.26 399.564] /A << /S /GoTo /D (section.6.4) >> >> endobj 2829 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [160.107 390.717 167.08 399.564] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 2830 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [487.346 329.507 513.996 340.411] /Subtype/Link/A<> >> endobj 2839 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [89.004 317.552 107.594 328.456] /Subtype/Link/A<> >> endobj 2831 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [476.875 172.785 488.831 181.632] /A << /S /GoTo /D (cite.Patterns) >> >> endobj 2832 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.206 158.772 397.651 169.676] /A << /S /GoTo /D (figure.caption.3) >> >> endobj 2838 0 obj << /D [2836 0 R /XYZ 89 721 null] >> endobj 442 0 obj << /D [2836 0 R /XYZ 90 690.045 null] >> endobj 446 0 obj << /D [2836 0 R /XYZ 90 510.667 null] >> endobj 450 0 obj << /D [2836 0 R /XYZ 90 375.086 null] >> endobj 454 0 obj << /D [2836 0 R /XYZ 90 228.262 null] >> endobj 2835 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2845 0 obj << /Length 291 /Filter /FlateDecode >> stream xÚ¥QMOÃ0 ½çWøØšÙùhneëJ9 6¢qÕV¦J”nðûÉšUHœP¤¼g;¶Ÿ„ ”ìÒ±ÉÜ(°Ü¦"÷ Á`ÆQip[xˆ¦Wù­+Vq"4F)bt¿ª\µ(ƒ3àb+£|QÞsV¬«iøÏÏ0Z{xrד¹g IŽÒx9C¿Ìß0< ±pŒ> endobj 2833 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./41_home_taurel_tango_manual_ds_writing_device_et.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2848 0 R /BBox [0 0 839 982] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2849 0 R >>/Font << /R12 2850 0 R/R8 2851 0 R/R10 2852 0 R>> >> /Length 2474 /Filter /FlateDecode >> stream xœ­YIs[Ǿ¿_ñn]Áxöåƒ-§RNÅåˆ`•²‹‘Ää¤@Prþ}¾žy³¼Eˆ²H¢ßtÏôòuÏàcÏ™è9ýÿÞºo/]ÿþ©ÓLáLÿ¹‹ß÷—î´çŠ Ùk£=S¡Rjfz/,SÊöÇ}·-#,gÖô‡Îré˜UE2•Tßw;‘>ný÷WØ‚‡€I®eõ®K[½á0ët¯C`Üøþêн¼{ºÞ ÃÃçýí¯/½¸¸ú{bwá˜7€_Ýv/÷¿ïožOûŒ¡ï8w½ÌZ'#ä‡ý§ËýîöoOw§»‡{‚ýéª{ÝYÉ-;èRÏì´âÌMŽüÔ–õâkNªÕÙ“~{ {B°Àu a˜â‡– ñµqÍÕþð8¼z8v÷·õÜÞ 88÷IA‘ôA³à±‹¥Ã±ÇF¹):¨’N2óÂqæÖ)í,3®H†N!ŒÌèÞ+©X ÍW ݇F—^‘ª+Kª.¡•¥Ì«’®Èºà%‡ròÐyšñ+B*é V)Ò›Ê8fT‘ Ub´›ž(X88ˆ(õ̇î—oúû UÁPFšÅ2:˜Üø»|¿PrX5´ÜÌÜô»oþoªÈ—BÈÀ,*RYÍœ‚®"1Ö3OQ0ÚZ:ÞŠd\EÇ”Æx*t(‚£‚·Ì…T$-j< §±ÍùŒ“‚y?ÉÎF×ÊsCy™e@yT›öSÔ˜‹çueÏ ž$k]…rBümIBU–%• ¼.¦CÏWMƒ“qÕ¢“\¤®îòœØ£Ý|-Áí¢P”vàÐTò‚¨ÂÛÞ)¿‰½¾w~4.¦"`‚ŽNΫ†)Ûœ+Ž#dàn¼c2¦ŒÍJ]$ÑÚLù¡¬«º²ÄJ…¿dO:P¥´dÛ%™2¦äÕZ΂}Ùù&ëù̹f“p“OSÎUºVövÛ¶²¦ŠR”ÚLP%ï Jj]z‚Ê^²FùÔQrgIëïŠÊûZC9/C뫨,i-VT¶¸†Ê)=z+7Â4ÂA€U»÷,™hBóf-hÄÏx‘ú*¥½m˜²HЙ(³S$$§rF÷ö¤²©Îa!dÇã Ž¢‹¤ ÖERåx¶Š´7š‰³Š ¤(²Üa¶™)â ÔL£@yo˜Heo(âZ4 ,iQÒpÇD]y(’:¢¬ -óѦvÆ"i¯uÒ•N+ZìÍÑ˸JG~Ó{f¸2=èÂØù­|ºUñ@å8܉"ƒ"¦109"'G§ÑŒ&}O¤+1ÙH¨D¦Ù€øä@^p‡Ö–¨_(iS/o0sb<Ôm¨rNzÕÒàœƒãóq«vaàOá'9;Ô¤oÔ¡¬–‹Œ”¨šzÉ’6Í**çP‹*'ƒÏ¼mueÉÄ"ŽŒP|á “ìåóœ#üs˜¢'PˆÈScÌ$% ¢®¨­áŒÛ20òü\Ë8gkt/T Y†ÈŽ t”ÕZÀc˜ï„t‰i4îJT­2dˆp[­æZÒP= +à¼ÂþlÔ ²òhÌYñ‚±Èr1&S©WºíœmV•~3Ý·ô› ÇQÞ[ÛJ› ©Òêx¼£¥¢ÂžÐ PÎ f»Á•’ *Kj-•“Lª+eŠ 8±së-}am~’v ξ;,b|¢85Ëx¥úFFdÉP$5WrEµÙ“§1O=h2°9˜•íÀf±31Ø ¤ê)A)zª+ól˜cRô411Œƒç fµ>‡eHn¿VÛ˜ËM÷•‡ªÃñjáj"cðoàqÒY½ò c¨ðÏaŠ-«€MEÃQ¾J†Æ¾CÒPÎZêÙ. †ÆZÁ8 &äÌóoßT2+O íÑ¢ÉÄéD@O ?ì?ÝÝì<<ñ±DÒ-Ô½èʳûø\Ì«a÷ôD ‰æè;BИ"äîþît}qôñGžž^ÐöµÐ†z@ÐÝét¼{û|Ú_¿ÛÝœŽÿÌï”(T¡áf“ߤ§Š9–Z©@‚o$&7“žCšW œƒ $¾ûqÜääY%í1ÊHEZÓ^g+ãI¤ #ô›·€³_¶§ÝihÕèô= AˆG}“ÏO¯ˆ´Ez{z:펧‹ß®þB4(Œ/gvJúÓ Aû ók@Ô@œ„ ©4Þ~AF ìqºÓ2ÀRôF‹^®ZDúš¹®Å³ÔäÝk£8ÊœØi,.ÙžöûãOˆqɳ˜Šb(ñ)$dʱy:lÓ\ ÊòkߙԙW‡DädC¨ —m\?åÀ.¶O–È-˜…snÜÙ~Ü’…‹`ú’‡+5²¶=ƒ›È>¹üÕÏ—ß×ßWöOk;o%£P”3÷»ÛëÇñ‘óK&s5Ž[úx¬‚¯ôrBÏß;-Ül±VÓ f´/dçWïÐ\&z$(1 2Z‹«´02Láß4'šRÓ’(Ïõó6Úyj"o áÁ³¸©¢ GãfÕüx|¿œ ‡ežØ´[x|&à‡xcÁð@s÷MD ‘ª%S¸ [16ú·©Õ§Íä¬ok› 7ÂKb+Z‘×Z–”ÒÀ« ý–3‹Q93ÆÖ¨‚Qˆ%`CI ë1zú—úèÆc|¦‹}kç͸ Èõ¹*/þ\²ò,™븼 1$"fô 5Îòôò€OÚÉP%NÄÀúº"iQÎÁ3²Eyº‡cܤ·"O#¨ Φ÷èlo»@Õuõõy»¸ñÕ=Ôû]‘xjñtûÈCzl78ž‰E{)˯(¾Q½”8ºt¹h>ÏàE²]\.ó+Ê4Æê0¿ûQoZâå÷K”²v¶§·©€®G£¶˜–•àprPSBt¨ÃްÌÉ--XŒ:ý$wóϘ†¯¼å/·ûÓD\r÷u÷/*9‘D endstream endobj 2848 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152428+01'00') /ModDate (D:20160114152428+01'00') /Title (device_et.eps) /Creator (fig2dev Version 3.2 Patchlevel 3d) /Author (taurel@wow \(E.Taurel,,,\)) >> endobj 2849 0 obj << /Type /ExtGState /OPM 1 >> endobj 2850 0 obj << /BaseFont /JIVFUO+Courier-Oblique /FontDescriptor 2853 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 600 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 600 0 0 0 600 600 600 600 0 0 0 0 600 0 0 0 0 0 600 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 0 0 600 0 0 600 600 600 600 600 0 600 600 600 600 600 600 600 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2851 0 obj << /BaseFont /NSCCOH+Courier /FontDescriptor 2854 0 R /Type /Font /FirstChar 40 /LastChar 121 /Widths [ 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 600 0 0 600 0 600 600 0 0 0 0 0 0 0 0 0 0 0 600 0 600 0 600 600 600 600 0 0 600 0 0 600 600 600 600 600 0 600 600 600 600 600 600 600 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2852 0 obj << /BaseFont /TCNEZT+Times-Roman /FontDescriptor 2855 0 R /Type /Font /FirstChar 40 /LastChar 121 /Widths [ 333 333 0 0 250 0 250 0 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 667 722 0 0 0 0 333 0 0 0 889 0 722 556 0 0 556 611 0 0 944 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 500 500 278 0 500 278 778 500 500 500 0 333 389 278 500 500 722 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2853 0 obj << /Type /FontDescriptor /FontName /JIVFUO+Courier-Oblique /FontBBox [ -61 -186 663 624] /Flags 33 /Ascent 624 /CapHeight 577 /Descent -186 /ItalicAngle 0 /StemV 99 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 432 /CharSet (/A/B/C/D/I/O/R/S/a/b/c/d/e/equal/f/i/l/m/n/o/p/parenleft/parenright/r/s/space/t/u/underscore/v/w/x/y/zero) /FontFile3 2856 0 R >> endobj 2854 0 obj << /Type /FontDescriptor /FontName /NSCCOH+Courier /FontBBox [ -12 -186 612 624] /Flags 33 /Ascent 624 /CapHeight 576 /Descent -186 /ItalicAngle 0 /StemV 91 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 431 /CharSet (/C/D/M/P/R/S/a/c/d/e/f/i/l/m/n/o/p/parenleft/parenright/r/s/t/u/underscore/v/w/x/y) /FontFile3 2857 0 R >> endobj 2855 0 obj << /Type /FontDescriptor /FontName /TCNEZT+Times-Roman /FontBBox [ 0 -218 932 683] /Flags 34 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 111 /MissingWidth 500 /XHeight 460 /CharSet (/A/C/D/I/M/O/P/S/T/W/a/b/c/comma/d/e/g/h/i/k/l/m/n/o/one/p/parenleft/parenright/period/r/s/t/u/underscore/v/w/y) /FontFile3 2858 0 R >> endobj 2856 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3223 >> stream xœ}W PSg¾!ÜËUѶd.&k{o|‹Ö)Xµ>ÚŠ€à«(µZm…%•Gy…w!ð‡@¼ Q ¾AZn*,UQ+ÕªU·®v×v]ÛN§îHÝîßÝÙ?LºÓÙ&Ãü÷ÜóŸóï|ç\áíEˆD¢çCS3Ó•Šô…›â“”i™ çÙ+Â4‘ð¢—ð’8E>YðÄ›|‰Øh“L6øŠ€¯øzÛ^|>Âþòì|Vù¼Ø˜­ ¼ì> Z¾|¹<>wü‰‘;%~Õl°L VvmëÉ×#?ÈÙÊŽ†“ÇCŽç˜#Õ1UòÊx&Ö#£/¨‘‡÷øð“µœäÇÛÝÝý—þ0Ý¿”Eun«³”)˜“PAÂeÔ ÐQjÏmɫ۲éðà-/³(u0ŸÁ<PÁ1í¡Zò¨CÝ’šö‡°Ð+œqäñ‚ˆA±Cðsˆ…iB(ƒf¡‘?âf~½Šàlø"d ÷ëªaäÅiâ™ï/E-FÏ@“müâ;HBñ¯p"7êÉÒ#‚^ØÍ_…jfwï–öu`-XŸûnìŽ]á…‘êeR}~E>È£‘ï÷¯À‰C7 |Él7[Am)3•”–W”–²bÒÂ='øë‘ƪfc×t£N‚Þ¡õ‚Ó¹m–ÒöÝ@_®š45zhµµF[;ô–j 5 Š¶jM%…Mn¹3CÉÃWxøgWñû1Ô?Â\ü—Ý;K!¯§62Ö£„±¸úÖf\Â\n>5«­;•|È Jàd(ã$·­¹ŠˆU›UákY}Žùî‹-+§Ï @ÔÒMçïþóñCHr®* ™˜âý¼’<ãÉ_€ÞGàŒúóÒêÖªV`§!r‰X¤òdfäÓLfDÈ$áLê,èÊÿ(±}oC<ˆÅy!Ò}Ó‘(` ÇIžÄûIàœ#¢©ÜÂ’Un¹¾€ÊqXtM¼î¤ic}iM>‡"¨?Â4R²ÿœÚÓÖ;íh)iÍ0i«*M€nlh¨·hêó¹ìµ9 lo«÷Rç}j‡à…kÓ õ}bèu©ÔWjA]jÑZ-V[5k¬ëÜÝŸ{C÷ÜÈ{퇲›¹´ý‰u›ÌoZȶfYÕvÐLŸê¹ÝÙ­)jekµö P®O’Ö”Ö”Ö¶ÚÖx}´´FÚ¢5k KгÊÙ”£qMÑ€F¢ÅQ«32l…\»ú öfé¹²m[­¨1 ¨éè7v,X}ôS£Ád0³†*`Äôpú(§îÂǸ–;Äð† S­Ê À(ÃVc$JG“È`·4Ü¢bЊ’ÊRP"‹9£¸3p«i?{¸¡Î êéZ­¹T§¯Ô•°»ö­Rot´â£žjƒÙ`æ>‡v×ý™6¸.OwVÌÎÆ¢¤6øÿ‰’t;u‡“¨œ6¬’º+ø’ȇÊrß¾5b1Š _—1mWò‡TW™¸ËðùNc3}qe1(–mr(®~õÕÁsWY7%C…VÊǃÉåÐ0•óŒœ5ë+’{ {˜rÏôTÿî+q„¼[-‘G×)”ŠY—C½ï“WÇm°‹nžºÿÔ—tzÜ!öø‰Xˆô‡K±×V¯b÷§(ôVB ¹•Brd)‡ÃäÀï›¶RÕØùi ëX}ª'Ç1ã¡”÷ûÑcAÈ^óÿ‰’|6 |¾ øX —Ë%ÜVÙàf~…baNþ¶HW†«NkÌZ‹Ñh0Ô°ÃxK' ¯8Tñe—ËÛÜœ\³È+_=Ÿ“|¶áTÂ_†®|ôù0[ÛË,ß“èÈÄz¯ÿí ôéí-ÓtqÏÐ&ÁTn‡A¤É#/w:ýZŽü§C²ï÷ó5SСtNj<ÔFæf]£`|<,¤n‹j¥JBÆ(v°hbFäšÊ[œ¢)~ÚJzŒ¬Ÿ¨Öû¤¤7üؙěӰRJ¡ N ½1kõƽaë9s‰¹wqÓ2äƒ9òYyñèó+$ Ū´`ÃÕïòŸf“ÈÏ#´7õ6P‚X°‘ ®äë´5y£èŒI)Ý[ï‘g< |ÜÛìÌLÍ b|Ñd<§ú_&±ûÖ·°ŒÌGR4ÌûÓš^¶ŸäŽÛ÷ÛqC[4V­N[®-e£v„¤zñ[ŸÓo?{ÜÁ9Î^9:zÀÉ¢ýêzMG2Ðé÷HkðH2cÙ²bÙjý^Šu§zL¶°ääèÙßb;‚¡í}2Ñm¶Úm¨XycÛñ`L#Ïb)š1ïÖê‡_ÕyãKN’“³ˆÄtímuÑ5“Çn¡Ðl8Â|;µŒ“ô"zºѯE ~ }þõ+¤Æt.„‡óyÑc^`zÄ |—©é0¶ƒFúo !š‡ÓŸ‚X$¾» Ò—‡mGβGškk1Ö2³FW^¡Ó°ïî}3s# çG\zP ,†ZÎÊ3Ý?|{á! ¿¿³¢èp Œîf^4âB0Ê+„a-Ch-ŠF²;AÐ.‡¯Àµ02+ ŠÓÆ3?|µya#6ã×~½àRLŸ È>ë8Wí1®Œöà~4Õp±öô@çU k¼¾MßW@ZõufISÅí5­3'€E`ÕÛù!…‘ÒWÝ„½ï‰K×Ð(Õ´NÏkÆTn7Õ¸5x@¤Àj÷ÒµÄã±h)ý¹Ë³LÍ%SïÀY]±'!Õ=xܦ‡×ŸEU®~)2éœEujªç†÷¦û²ÕÎojj.¤.ŸÙ»fþFù³Ìy,:ǹGìp¢+x´ÄC£ÿãŽ-¦àá.EeÎ$ÇhoÅîì…æ^±pFhdöòï·FaæûÌ|u~jC²]Íudv]+º^d/³çµ6¤ƒLzyPج„ ¶,¶°6õc`ªî“ê,ºê2PJJÊs÷!oieye™s曵ÖF«sæ›Ýq.mȾÃ{{>îìýà˜ºk_KºMe nˆ¬M·f7ç×·áçæÝ+ºz Õ-¬UsàCÜCqck]=¨­3¶øEZeÆ5þvlã1ÖŠ«‹;-rux‘³uà„QYú?¸x~ \p8¿vblWÿï·À³e­i|¡wɉÒ9ðø½pª»½kÚ¡¶´½˜ò•eÜZt¼å楒:í§.œh?dG¤ïè&6òø8„]Uƒ˜e§OlÛµm;[Ô¯jÛ…×;eήÎ ½pJù„ ƒ™“۞Πòy¼TâYyÞ=).ÀÇŒù¨ñ8LCï­W!¯¹¸¡}ÈfÍÕ&ë“AŠ yŸYÿz=Ä}P'‹®þÄ4\>~­§ïp×Ç6 ‡ºÞ™£Ò§ê2¸œE> OxO–’˜è5‰§2¬iw²ÿÁþŒûø7æ™Ä>rƒ'¡Y¿ÿÄùòýA±ð%.Y!PçîÚŒ¼ÑÜÈ °½&±q[stÞ¦tcY¾Ðx鬫ª4V¹”{EWÀ5çœÃß"ÏÁ%u3^òÍ%N&À«ƒbø™ÓiaQq…AoÐs‡_«_"šƒåÓ-Õ•U–sl×6Ølç,ô†sû €þà® Š÷\Ò›tF^¡³íÂ;ô³Ûí?ñÓI¼¯/Aü{aÓ± endstream endobj 2857 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2558 >> stream xœ}V PSg¾!ÉÍP”tEsã£BÄ¢ˆV×ò2ø"€|µlA@¢"”w@ñ‚hHx(*õ…Þ"TŪ­e­nQÑZÝ]XkÖÅG{®óÛ™ýBÂLwg2™ûß{þóÿç;ßwÎá‚ÇãQIÚdUl²ùyçÌã&Úp“øÙHÉqoÂIÄŠš1#‹íyŒ=Ÿ±œ8ÒÇÚÇ@…¤&ø<^ZÉþ€$Mz²jc|ŠÌ5|åj¹›ÛLËoooYtúàY`ìVÕÆDÙtü«NÒ$Ä&¦øÈ°µZ­Ú Û¨N×Äo•EÅÄÄÆ˜·ED©c7Ë*µJ£IJ•¹ÈesfÏöxÿÍSª¢µ[eÁI‰I²²•±µê¨äa/ ‚˜˜˜  LÞš¢MÝ•–¾!8&6.t¥j•:á/®r‚!B‰iDñ±Šøˆ'"ˆÕÄŸXK¬# wb1¡ ‚“XFÌ%‚ %áKŒ l‰I:B@å-æ·oSÈ÷æù/JÁ—„ȥd“ÈCT#JM}?"h„ÑÖÏ6Ën¬ÜNkw™ëÅõ2,t³ÖY¨glj»À‡›'ñ%ÓótY™] }uG’i+ ãȃ¾ª2OŸNGÂ>ò8k,ß_N‰›7|n<ã|–1Ôm«O­Lf(ĨDCn€gÙ¨=ÙtmNðÆ´åaR|‰í,Çcy,gËòák.@‚ÄÓ]Óç bp|ñFØå9KG ^ÿä3Åuþ‚iS½¾è{ôð=°_Ïò®÷ïç’¹RÉÇÍ!uK™%Lè–ÈõŸ~’´˜QR^"ä È&~ßVßrAúY]E5c¤Êó˲u;‹òuÒðåk¶( Ùº¼{ú¶ìþÕ üž#”¥Òâíúü †ªÒp$QΕ©ËK7ß)Y˜ÅÂ}3ˆ/Yà0†½0 c8Ó‚áå·5á–„[ C)Ù²ôjBCóŸÁŽ?»÷Ÿ Ñ®Õ("¤ ¸"éëò›áîã+w]Øùì—Ïéþ´qZ–÷Š…²üW¬Deå]C‚¤0…¾*‚ÉÓA€$R¤±J(ɾÕJ8-L]fNïhŒÿ"º>„‰ üE“=ånÒAN¨1'6à`Ú¡ƒ(2#7?;˘_Mw¢n7Ë ÚÉjcYEenY‚` )>Ý6‡›1µ9u)z]Én=CU †‚²Œ*zË!­!‘YìKrŸO &C·­°©Í˜‚\ '‘ċܿ’¡äþë—©kÒ醌ÝÝü+GtŸeRâž#;ª“S&D,ñü@qºEª‰»*ó ÙRq93´^§ëóªðºÒœµrÑ—q3n`˜…®ÞkL;©>Ho>W®Ô{ J´U”¸+µ"§úÀ„¦«ÇïÞ»”¹WZ²]¯ÃIïßÞ.2áœgåçd ð^±xõ¤¸Ë%šó$š„œÐp¶ô_¸*oßðxõ$ÌGhRóHqEÕ²D‚Èa’ —Yé~¼Å"(L\ fi£S zOˆÄV¦™Óe$¸aù‡¾L¢yè1ô±ð’•…Èbq€ªßYø7®¿›8{Iô©p“Ã:Ám&Æþ2 ÆÝ¼YÛØJ7˜ö×0”1Ï«ÛU”Ÿ/]½>x«?¶ä-ê| 6÷:Áæñí¨ˆRº$cŸ®òøžô‹Ë+M:Túp³…å÷þ,Áhü*,{«õ³ŠPn­m½eåB"wÔ‡< Oèj±¯«U ßm|Çu?N[F‚'úuˆ{/ú¹w…7˜{¸Ý\ß°RrÈu·ÃNøâ˜ìf˜›˜Cït°ëü®ñÖW´xÇœg±‡“H/$}÷}¦bê¹ø,»,Ä=íÁÃçïjŒ? 3p[ã>ásÕ°^´ì2ežØøÈ§Õ ;ëâŽF"§ß¦ó°ÿª±CZ¸³¨PGoØì¯ fÁø´g¾¦XAÍÏßö2½ÌÝг©AÃtL Œ`N„Y%7¬¼ØÜxóÐÙ]»ŽHÏ0L‰¹z—U ôÙ{èÍûúX†òXáO+=-¥¦uË­¼…›Â C9pèJöàCq]kÁçzÃv ž&€ì¹ûô©WÇd鬦6|8_ó¤$lÀ‹ÜX¤X9÷(ãXO¿ûæ~÷¥,‰{ñç»ÑÔ7–Õ䘜tzEÓÓã-ç™Ôc¯ŽRTü?_dÙêKB©2à}QÇßÂC–û¬–ذÍ*®Å`N<…;æŽéiåÃu£¹Vëß­šKŠûЏ%¡S¯‘ƒ³ŒãÏlú98ËjÏ™ÛaW%‰b#kBjÊÂ%žQ¦˜)ôQí©ì[Ù·³ÔmÇí°!£zsü¿Åáî³ýZoî’î>PP–ÅPý½ D¸Vš§éç"öãkÉí¸ÚÿãVokJSL`J*[TlL.ÛRû`rufñ 7Û.üt¿-2d`ø”âËa³–¢ C~ã}Ëͱ qÄ[Óÿ Ùjòìø™ãðä#ÀÀù ›=‡dYm!‡H¥ÂE^|á›3ÇëO‹¡Qû]‘Õ€YKžùöh®óÇ6ÅÒ¨cØÇFòÚÇ¢7¥®‘jÏo>ü)Å$¦«Ö›ÅÆ\äe¿ð9ÎWò»`íùªðUŸ[†#Ìetº M ²‰A#fÚ‰©? áá8C®‘¡Ê†òÒÝ%E{iŒV¿`~c~;öªF•ì-.aJ)¬Ï3f°§ ±¯œÜ¼œÅE%…ô-4樋Y°2õTUT¸»ˆÙinYåF½þHµô6Øœ…̘—›^ å –:CÚVËÍ«ÇÚÚZ²É–µk²·gíGÄõä`D endstream endobj 2858 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4091 >> stream xœeWyTS׺?1$û8á-i®Iф۪µNÅÖV¬Ö¡8ÔŠÊ<Š€23!$$„é#$’‰Ìó,"*â<´¶µ¶ÚZÛ¢¯ííxÛÚö½}èá½uOlßz¼µ²ÎJröþöÞß÷¾Í"Üæ,kQpJzBÎú@iz\†ë÷:Ê“E-›G-gñ‡ÏìÎr¯™½±a‘Û‰eOíòÀÿõî[‚µ#Ø,–ÌÔî+Í,ÌNIJÎõZöÂÚµëþïŸ[¶lñ:Vø¿o¼v'ä¤$ex­b¾ä'H¤™é ¹[½|™ÑIÊq¯$IafrŽW\||B¼kZhœ$!ÍkoŠ$%3SšïµÚ÷¯—¼½7®g¯JI?–—ãõdç^‡¤[¼ü¼’ò$qÙÿÿ A+weH}3wgçäæíÏ/ˆ;Vxü`|Âaÿ¤ä” à4Iz؆˜«_XGχ b@¬$‚ˆ`"„%ÖaD8ñáKD»‰ Äb/áMl$Þ$öo›ˆW?â qˆð!–; b>±€XL¬bL¸ ÄǬçX¶yžó,ó~gû'·7»Í1r_æÖ %( }D‘£ó7Ìï\ \ðÛ€…¿.Ú±èÞbÞâËî‡ÜSÜåîW—,XrxI Uá>›N~’ú‡“5êà5h,Éwi=uKPÀ¥ãçTèUª¢¨J¡ G:PTµ«Á`«µŠ'ñ|¶sO®mÈ4eRÙòÒÐ*R†Íh®[øá.LÒ]wªìÔ3—Xfðîv#õ,ßh°T×ÙU§ˆÓÕÕÊðrR“í(¼FÑC$@gO·4ôy®M²_L' ð+–G¸ÅÛQd­ªΑ¸}syW´D~`ŸèS¤ÕG¦¨ƒ‹„ÌŠš.ê¥.V÷רö5¨X>ýwïµ´ˆöüvöÀ?ü'á¥/~O?-.–òg®­¥—Óœ£ûvÆ'¶å‹¥ÓEÀòû37ïˆÜg_TNP¿Ž±˜Ã°g *”_‚ó9ù\]~‘ªJ@aP##ÌG` øHï9˜°èy°¡ç•ó×ßú&á'ÀøiòÆgdaó®ÝûÓ}@èAÎØ‘às’¯³I¼ÿ[<¯¼2|LÔ—f—:Þ"™ÐéMòæBœ®é£Ü¯{Ü›Áy–òÊê¨åüºjÔ9`ÒÏ%#S«ýu$o•—!ÞÑf´³º¸Þ&ñF4˜Ú¦/ø»á•øo{¾Z“#þéô!ùÉÅÁr!^³“ßsyhòî¹4I³#wú ê¹`á S‡eßS\ÌZÊ«þ ³øà«*ÞQFò$2<Œ0 ¿÷ß¼|ëÚðWð#|~?øÒ¾Û4kˆ^$ÝÊå-“¡Oµu%°‹ÿ¸Ÿß[o>ùèVQÊYÑý“¯M½àØæ×Ž„g¨6y\U×'vǼ¼îd}<Ã6QÏðm†ºê ÛëŠbÄ´A„V{@Åà@kGû r;\!qê;5Õi¬+ÓÔ‹•õ:+mö¦®þ|gJ\FîîHñ7¨Lš—Tì/cÀ!Ô´¨œÔgq‹Çù›xËKyëðûø=~9^ÆQs++K´UUå ÔF¯®%yMæ¼¼š,Ïmá¾A}ÇF‰¯¦4å€D“& O‘X[d¢üö’Öâ+dímåš,5zf¿<¿:°U¶2…iÒuu–7{~òÎÕ¦rú‰iâi£¢:…c½]“WzR^j¹ã^Í4µ¨ÏÊËèƒ3Ky±™ïö*Lr-UH[¢+Ñj‚c£ŠÊIÞCµV§-{*ª+ •$ïöú"wsOìµs#mÓý¢âúül¹&„‰ŠÎ·ÅxñþÂuÑâj “z­Iió¸3ƒ÷2«4Q9Sü2n´º~RŒ _B¼~9ºYÑ ’V!–)•êÌ<‰*Èø´q1¯ J¯R¢³6D“t-Úv6ü£áÑÆÎNÑ©SÄó«©œrÕŸ· ]•t̺9X=f3zÀ`gg±js#S´ÅPdƒHÊÁG6ëL é §dèaYƒšA ³W¥“ÚædQYLh±‚ÛWa×€ 4•šrÍjºA°×él6¨Bs½iÐ@Úép©4i&WàEô˜@¯3h ¥ÆBc©Œ`²Ú‡ñÓø® û}£©Ç@2øþk÷™h@kÑ‚ºuæF:[°çÊ'À*„–zÓ>F†ËÔΓÌ$3zÓQ‚ÕØVn©´€E'Ì5̨7¨µÒ¬i Çžô÷‚†t³Òµ`¶6t0Ô þI«m‰5:#MP[×8ÆèÐO‚æqC­“Y¹Sþš+W)A›Çå/ðêÏ–òNS‡ÞåË•ª2¹ZÛ„‡!˜.ëV´å Å:ü\¿+Ò/×YÐÚvÂÙRSU[eWÖU™ÁDvöµŒëÌBô†ƒòÒØ„¼e ¤’¼p¿‰˜'OLßñ¬aµÍù'=˜ýŽ0¯è¿àƒ¤¬$_•£”–ä™,8%®Apíä^<á* £H ßfÝžÁ_²ñúÙ×ùeú8Efé‘baF)§«kÀäX]Iœx®I¦>À‚Çx~/ÙñÝó‡’" D¡n£g†¦ïO½N»Óì¨[ÂŽ¶¶‹\ª—1CÝ`Š"uUÝ“©zcIQy•®B+^CwÓu¶r+Ô35·›Né™tS¢Žò&µY޹t•ÀPjOïŠhL…¹~òteVžL :(Ñkje&yœÉbAANj_öø{g/ãÅxµÎÚWoi3]Ùÿât³Ú?aSÏbo~Ôž¤œ@ ½<Àè×Kw>²ª-bcžYÚ\x„-ŽÖË{ÎlŽ /H:&Žˆ‘îƒm$ý÷O7`ö鱯Þ!Qg›£³çéþÇâ¿xÀš š³g_¥>àÏE ðQo+cØÐï@oÔ*mŒç¸ØpÇj½kdØ…è¬9=]Dé9t¤Œûy™Uosk¬PÊ|tÌ<•m¯‘·Â/$õ<Â5sg8¶',Ÿ†FjA«ó.˜aã5|üü4§VUBI¥ Ù©wIŒ’'kÈ…EÈ\m3ÃušcbÚ%ôeÖgm 9ô³ôÓ÷6áy—GœgÄ»V«Ò¨ ²5@ú?ÀK0çÜÝ/œ;*våð6ÎèÃhˆE­Ã>ü¨± b»3®Žhû+oø·ô–¦;»/}(úDDÀ‘„”#Ç2wÃ’}ø Fßß»†‰q}¯ã×ß¾7 MjÝô„¶CÔÿ ±0—ÚŽ¹lüß³>|:ˆ^F¯ £×÷y_ _õû*þKÆõ"ð2ì…£Êx|]ìw{óÐZæìn“0Y8”v1²w=Ð Á¿xoAXI¶<;779ùha(DÃÑæäÞ°ÉÔ_o†Ç]?ŽŸ!GOk¹ ô/€·Œá)—'þü¹>±©k=“É&.¯I†î–Z4àKÎíA°¹T³Cûgé·.!äI¨|·N“©{Þ<²b ”ÕúÜ?iq¿ìÄKÛqêhm«ë\ôIg›J¥üÑí¨€iC LyfA¦%³6 È »|½ý:ÞMË åº²ÔŒâ(€üÕÉ‚Ýa™©H†ÞùþÞýŽñiÑHoSŒÀÍ#ã» 4ß(Õg×A#8û;ÍuU¦*8*­UF†1{og—}¦ »¬UÙGÒÚ¹gøýÚºs@þ³¿8)`G<Íy9 {¢ÕdŸ×âoù׺'{;ä颿ä†hˆ'ƒ2’£ÇÝúAôg_èy‘õÑ >ÄÀt#þ?>ÙÓ4 äT{Ò1‰`Ÿ¦8@÷gcbÑ™á6‰£Ðïq_óË9-ÂWP™!E•]T$ÌtiOMµ[ò”¹4V<—†`®$ ”™/±££¦™Ïø,³êBû /~ìqÿñ«Œ þŽ}]â‹ÁĽµº„mOú _z¯«ïÔØÑþÚR |HbŒxT8ÎçgææJ¥-¹]Ý­-Ý]¹­ ú/(‡òœ}2ÅéqçVþ²”·Œ b šÏ-ÏU«å F„Ì$¯ß–˜hNóŒ…yjF²¤0Â`ëDvóÿ0aúX{B]qm>äoFD¿ñ’ß%ì!ÊåöÐÉœ.ÏÏQÝ`³{ÖCS¹CËDRŒŒ•ŽybôÕ§¿~|‹Ü?{5n.’—ÆGnž—% ŠzÓlYþd;£Ô¿ÆYØÄX²i–àÏU xU­öqéÐiÆ•k”V—+›/"Ì…–ÂVzÙÆÕá휹\½ÓÆmìVvsÂUA;ës¦S›eó™¼U[€ì·G‰çò™Æ´¢Â×Õ©ÛQAõq=ƒòA!öCØ‹>l(×Wè+ B³Æ ƒ2²¤D§É8ÃÎ1Hqçéõ8TÐÝyçÝ›“Ýf¡½Æ¦oÒl§c•ÜѪúrPBi‰R©búvwåƒÊõ ªŒÒ€"az)çI‰Yÿša;˜=¹õÕ ÕŒ¶õY”L»œ… DYìWÆìJmG~5* \"©ï˜ùaòÍ^¹Ð}ÖÁœiù4ëÑ ös}ØæÂb5˜]–Žº¢(1mtÅPU11²í(T¯¨‡Q"Л-&S{멦A 'Z’§#R«]ðɵ£ÀjEÜ$q-ê9Õß< 䕿L1Ä\€JK´Ì ©eéÓõÅÍ0*ÄÇ^}{@xV@ˆ¨ðJJgÄ€TéãGÞcî:á2殣ºÿ±[íœ]ìd1÷ê5|—Oœ/kVC&äë²4Rú)ú-ÀßUÖ–´T„%'t¨‡¶VËÅjÆaœ2t¥ÊR2°µ‹À‹¤WP‹´ÍåM.m±™Î˜!•2t¾Ì^8¼‡Ì ì\Æ.·âMs[9vîCl³ta>㘮¯»`a¨eP;Yø©ŸùéÙY’ŒöìîÞŽöîÞ¬Žt±Kžšb¹žü©¹Šô't.Øî0R±ñ„KÅßôæ(QCm}M¾ÙÔTÃ@éD"MìrÊÔÒÜ¢E‰²"Εön;ÚV]d³$õ#bºÌÙNÖY&ÊY&Ê®¨ô¬ÄèÝ›’Ÿz>мá¾\y2ª#o:­¡Q°õmé`潜÷ÔÃÏð»õóΛ]7{†>¼JþG=bÐ{øwÏöt OÞùÁŸÏütâ/?>v6«%¬OU$xàיܵ³íÍúð<> endobj 2842 0 obj << /D [2844 0 R /XYZ 90 647.039 null] >> endobj 2847 0 obj << /D [2844 0 R /XYZ 90 641.062 null] >> endobj 2843 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im17 2833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2862 0 obj << /Length 3099 /Filter /FlateDecode >> stream xÚ¥ksÛ6ò»…>R3 |Þ7×Is¾™4½D×ÎMÛÉÐlñ"‘*IÅñýúÛÅ.@¢ó˜óÏÅîbß\=¬äêõÕÛ«~ÊâU!Š4JWÛûU!W™Ì…Œ“Õv·ú=¸ùûõ/ÛWïÖ›(‘A*Ö›$•Áoïn··?¿¦Ákúl×… ®~ý–º/_ýz{óŠÚïa.ƒ_áóçö?ü”DÞq¨„T cÎ+$®¹’Œ ý®6*ËEš¦«M”Á^E«C1Y½ú}“Hü«¯›:*“ÞQªaœÛ“êf¯»z(›J/¡•ûkîX…Áv_÷@RÇv§Ø”A{OCU§Ë6£U{<–ÍŽ¦öº\G2øTžhöÜkžöš†NíáéØv'8âèGIp¯;X ®6Y,òX­6a(Š„ïç *º¬öØRµ®¡v{÷] ´¢íjÝ x.Μºö¡+Gƒ0NÊæá\>h$5“ÁmCÃ!wôÕ^ËÐ 3ï8G(®îϧÁUN±<µ99Š”Á¿%~â`§‘ÊOu¥iøS]Rƒ8¹>ÔM{h¨í¦>”ýSSÔö¤;¸¶¡uæÚð{<ô‘ذ€¦af,5üôúTM½êPö=*ˆòvσ7Žz»‚š5»°kÛábÕ=Ò fgLÒÄ{ÿ`m¾¦'”Í%å]?t%^=* E]…¨®$ìÊö„ÝŠºFIý¬«ó°¤*aâÔ⨇}»£3ŽçžO»Ã{‹ ¸Ù?¤ŒÍ ꆾD+¶úóÝæk¨…¹YX8¥í?”‡CûH÷7×Ù,D¶ˆ\ùD*¤¢T¤qÌÌJ™Y‡¾…uYD¨Ã·Óû,$ìa†±‡ߣ™¼§!Yhìôý*χÚFÓÒ]«{jZž»?ð¨Ãº%5ÂZ£õ®7†oI®º‡5Þ½¾2,È„Ê"eîG;Šl¥Dfl#'&rÎ2æÀ o9ÞE–ý7ˆŸ;jôƒ>R1CÜNeîØF/ߥƛÖݧu˜šç5v>—¨/h„ˆEÇA[ßér÷KÛ׬ÉoQÔ\øØÛý5·Œižù…M‰8AÓ™ˆ8æk¾à<€äÔàtéE% Y)4alî°8^Êf‹T¥N6 ÇÊ‹é†h™ÈšŒÖ@cvŽºÒ}_vO¼Ûq<‚Wc|XìRVsw!¨@&Ó»»§›S ßkpe{ê09‚lþ¿×!Èt{æ9twæÎ¬tÃ`ÝôäPiøž—’£ÁòwO431›«G0¿}ùþíó0ô|“Ç×9"§1[h‡ºùH­;=Gêm³d~”ȳlNlž3±Ð‰…‹­ÂQ ƒ#U¦{‡‚¹Ç ³iÃfGF"RÅTlžaS ùÇ%“ªïdR"¢"{ŽKoÏËF:Ï]$„V–»x-cf™1g=2Ë,lY±íq »Ž[vGk;Äaæ¸U•ÏbçòY.%E~ɦÝwËÒÐ]ÊÒ[ÂmƨPJÈ~Iy(Œñ={éCݳµ«¿ +ÐણP„%DQ²DÒ³/•úî0%Ã.æ§®Ÿ§ÂªI¤Óå0t5_–‰¹U׆–4´Q9.¬ü£É´Á6˜)§…©%? ½ƒñ®s§3e¨Z„¢¢Ìøceí©7œÅÑå8%ŒAšCgàÞ@,Z_ûÔ-Ükª ަÊSt~ùi¹™05øò¾1ÇžKeÆl€AÃB; ,1öÈaCJhP"îàP“¬`Âé]ÌÁ+mìýƒñ¢Ïë ÔwGÕ”X IçÿáÿpnW%MÂñÇrÀÒŠ’ãºlY›«Æ£ö ï∄“r³ª]|^×—£QÍ™8r3–¢76‘~³ å¯_ÝÝÄ…\Øåèî„Æ“(¼Hê‘·µ'.!Ï;©`Â` %ãI±;Icif†'L¹ROVp"ƒ#ü»rRš¡i/•¡úÑDœ¡èϯÀ/ºâ…_è˜QóåB‡2YìÔxM %m:Ù­Vì– ERÒUWÆ@YM V,©¤ìrRœ+¿`šæÎuIåq;ååGw<ÛiŸR™TÐTmÈx=¹ Ð6£ФT,ò<=GS½ù‚ˆ›ødfаJ‚P#•-dí¹n‹i¤Kóª‚uâ…ˆUôåH…í5h`ÐQ“£†bj34s°à'Ì+[Þf+1¦c‹.(/¬70IéÓì4Ìvw4öž@½1@Hßq£Þ<«Àú›1èsIÒBñF,¸@°¦ v|SH !ý‘×poŽ_ô®~ yhùNÊInIM {_Z‘ú[o‰ ‡†Aþ•OŽs¾Ô}ÕÕ'SoZ x![Œ¢ÐC€Êâ1;ˆ;D†%›–¶±Ï5àé.N#ìödÜΕ h• üËøˆ4Vþ]*_$À˜4¸yûîǵJ‚k“²g¦¨Œã£­ÄQ²•“õ4á¥õ©šêg'(€øtO ÔvfW`5Eónªu¤ó: MŽç/¸^WëïÉGÕB,ÑÔ¨J¸ÂÖ«ÐÏaZ?0®þ\ÚÂ2x/¨ž>M,ÄÓ`:óñʼn¡/”Š`ôqonX…æùA¡ôÖ&kÁv§ÿ:ëÞ¢WÒG¨Ï<‡˜¾•áÈóˆ¥X³ð ë9"CH¢±nªc ?qæh³¯`ƒ…>J'ëc:•…¦}H»äŽ/°UÚÄ l;^ ç™ÈâdÉʶ²‡-_„ yíg,VQiÕ¦*Oý«½¼¬o-ôXîwÖ¶˜å•Ø7Á<Ô¼˜ø0ô#¦/¨XèÆ@8p!êÁ%瞋謹`%eõ‘›ígÞQá92…¬¾Þñ~ˆu•0£Øœ%ŒÕFâñ¥j“BÆi¶0ùn€ ÏÄ~MÇÜWUžmÀ¸ã“ÃÝ/3ï4ßͯôÔµÄûz÷¥`.üV&£„uõÃvçÜ1ª—¹n²û?¯ù›1ðŸÄ¿vzøõ`vÁ7‚³ uSv.(ÃÍFb3}N”HÓdúl “Jk‘Uœï11OI”§8‘+µ°ÄÚ0†CæyÐïÛóaGm“zÄÙ´ø`&žÿê"¦dïEó‡ëÛajI¹äâÝ…K;8²ó“ßÀöDYæj¸yR¬âB¨$ôÞŠùI¹0Uåûäš9†ê"/ÔÌäNŸ¹ LÖjf-‰þ;¼—QuS– ­-#ÄGö©w¥äÙ[¯ž>Ð,ýbÈcÝÿ½y¼ô endstream endobj 2861 0 obj << /Type /Page /Contents 2862 0 R /Resources 2860 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R /Annots [ 2834 0 R ] >> endobj 2834 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [445.825 617.153 452.002 629.917] /A << /S /GoTo /D (Hfootnote.8) >> >> endobj 2863 0 obj << /D [2861 0 R /XYZ 89 721 null] >> endobj 2864 0 obj << /D [2861 0 R /XYZ 90 690.045 null] >> endobj 2865 0 obj << /D [2861 0 R /XYZ 90 604.449 null] >> endobj 2866 0 obj << /D [2861 0 R /XYZ 90 540.744 null] >> endobj 2867 0 obj << /D [2861 0 R /XYZ 90 524.986 null] >> endobj 2868 0 obj << /D [2861 0 R /XYZ 90 501.387 null] >> endobj 2869 0 obj << /D [2861 0 R /XYZ 90 473.674 null] >> endobj 458 0 obj << /D [2861 0 R /XYZ 90 301.222 null] >> endobj 462 0 obj << /D [2861 0 R /XYZ 90 280.62 null] >> endobj 466 0 obj << /D [2861 0 R /XYZ 90 195.123 null] >> endobj 2870 0 obj << /D [2861 0 R /XYZ 104.346 55.923 null] >> endobj 2860 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2874 0 obj << /Length 2615 /Filter /FlateDecode >> stream xÚ­YKsã6¾Ï¯Ð‘ªD ð™›gìÌz«’IÍh3‡LjŠ!™‰ÔdÿûíF7ø(]»›Æ«ÑèÇ×P°Ø/‚Åû7o×o~ø) ™ŸÅ2^¬w‹,X$Aêa´X‹ß½wÿ¸ùu}÷q¹’QàÅþrÅ÷ùãýúþ—÷ļ¡Ïz™)ïæ—÷¨y{÷Ûý»;¢?Áü4ð~ƒÏëþðS$G†BùJ@»_&pÌ›€tßÅJe±eÙb%˜«hô)£ÉøÅï«(¼ŸuûP¶Ï2¯mÊý^7º ææi¹R0¦}ÐÄÈ»¶>æm¹Í‡'f…þ©Í[7°*h*ð–Âk;CÍm}ä§V7Ö|%X4û­!‘Å ?ºb‘îúÀ–eô¼=‚„ð!s µ"‘C¨‘C¤Â—™pþó'óÎxëm×êâëC]ÿù%ˆø3%éË$VÀ«µ÷ +ÑæVOã?Z’¸Vé¶;ß>°”tIÔØ°Ý)t*¼Xd×`Mb%’Ȳ„-#& ;Q(¼¯1ËÐÆnŒ<ºíp´r§B–u…× ÙÒ¢×'NÝ—V;œ»Éø€85õ¾ÉGÍÛäÄF=㊙UkìG }lÆÜyU“Fž©š(<@Þ‰„µDàä[”žèLJukvÖ%€²¾›†^QWÚqØÅqzå¬:F‚Æœ†Bz7Õ¸??žzîΓz'5• ljŒÃŽ—sû!o 2'çaùœÐ\ñü‘L4:wÙšžu¸¶‡5!ê\¯tA•ªÞd¾î‚Ÿ¤™s f©p‰âkÞ¶ÍW ÛÅ#}õ3Ž˜Á2½#²îm³|­šhÜå}¼ÒPÇ»ß.UäPŸt“ó]'6èÁýçŘI§WÜ{Hšz%X¤!’On麲7“&ì†À"ÿGÖ¬Tn´6)?sØ-ñoÈbÐ`ËMÀIžˆ³Ñn£q@i§>çÉ8‰ýO¶ ÂÁÔ3¶d¾ê/ñ±)[ýz;~Äs†BXCP΀1ì1±5µ8¶„(g–‡ÉSˆ3ºøöv4ÛPd@°5/”[sÜæ8›Ýk0„˜¡”i ˆ o>5œ?|ÿ?†0àÄ1æ0å¾r‚m¾×G]1zÁk~÷Ýw<ð¤·% »u7?l°ñóÜæ-Cœ£>ntc\ú£ŸþF,­ò£þþc0pvæ%£ôü ¾¡ÃO”ù`SÃ9þQ¾‚S á_\ÛºMŒÜÌØU ˆ¿Ó#2€7Ë•B|Tnlnm²DˆñÒñT©'­wÇ¡.ón{ÜCÂD¤ŽXôÂñ‘-9ãDí|¿oì®û¥;0ô>–-¯HÙüb›v3w¸óæv| oÃkڇ׫ãæâ¤- T@n…ßÎâ_¤0ÿâ÷?nžˆDÃÇï±.ÊóÆ‚m@;oÚÒ¢í0½û¶ï Í6N™çöÖ¹yšîÙ^­¬zïl‚wìœç;×›ëmkæ¢byG<@»Úä€Â*†JfÝóµÙ6å‰@ 2ðh&j).1,iOSQ…Œ]ÝÙÚÈ‹-×XÛæÕ¾¦æÍ¯÷D@•QÞÞº• ÞvFlÄž­ž0®’|s`;v(¬÷ÜÑ~Øü|÷–½âÅÂ3? ؃¢±©sz×ËèÜ®À]ÒÉ\_ðìÛ‰Z¥ µJ†ÞH”@ë’­`cú0ã—RH?JûLûy"0|(«³×·Ÿ>üü=Ñ”Ÿêa16Lw:Õ­.°i3,|sJŽn£‰¿LÂá¸Ô/<ã½¹÷€Î”ÕþìazH,ôì!©_!& á˜{k ¦Ñ§¼éŸú¥lÄÁpE3ÆãŒ7£K¹ð‚Œ¦®[¢úQœìÇ:Ìøî2«j³Äòk˜c>Q’œ¾ßD«cHܘ¶¢a4çl†’HŸ‹6\4(™ÍŽe<.~ð]b)RoßqnNût"x@sâø£ž2{YÙ÷ äàÙÃkŽë4úòͽ‹À(Þ%nTI up_… øãW`’¢/8øŽÏ„jQ„gÐ|V?öØuò¶ùTÁÚÇ’TX«ºÜ$J}¿\h•…ÓÕA#I虇º;XZ®ÞÔ‘ Ã¾Ã@ƒLàô˜ŽE¼¡…¦DÑÚ‰e¨@d'ųêX)ó©”Wpq–pÁ\[f®"b°ÁP‰ÈÌeIW Içž‘:+¤³ûø p°¢Q|èl·ŒôÜØFŸÀ\tˆè};èÑIŽ!4´èåJ2†áŽÁ±ø"ƒ ·’ßÐ2‚}ø0B¸6ŒÆ¯ÈÐÍö!BÀ†XßXÌ­z7‡Ïp¿ô#hMÆ †ºvM}ìÇÏÙÿ%D¾vEl׌hsöþã´„,FjZè ®ÌëóÅÄ_øGÚÛñz™Á€vFHåÌò“6êíq‡ˆ ¨ø„ð>Ò ÓUÓÕÓ•{@EÊâtì´fÏ/+q€ËG. X¨Õ]Kþ)?k9«.NnjʘÐ3û€mÎ^ ¬VéVåk´€oªkZ½¯fôš¢üá¹^À«W™Ä½^-½£/{+PÎ÷“þa:á•’xÐ+6(4á2÷Ø €=Ñ«@¡Ù٫䬩ɯKÔàRÚþh33ᥳǨ×)]Ñ5¥èÚùÞ0Ê.´HÖºL­#½£ïäÖeŸGÚðÔAëÒA™8­Ë1ö™Ölj«Öü2ÏßÒ·-=|Ò+]·ôyµC.ö…¸Ô»YÞ#1Ê”oÄ8Ó9ü"¿È‘Þ#q™Å4ƒY}‘Ò¡P"¾ªõ>t¿ †¸ïÝúÍñ+r– endstream endobj 2873 0 obj << /Type /Page /Contents 2874 0 R /Resources 2872 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R /Annots [ 2859 0 R ] >> endobj 2859 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [477.115 653.019 499.032 663.923] /A << /S /GoTo /D (subsection.6.1.5) >> >> endobj 2875 0 obj << /D [2873 0 R /XYZ 89 721 null] >> endobj 470 0 obj << /D [2873 0 R /XYZ 90 436.207 null] >> endobj 474 0 obj << /D [2873 0 R /XYZ 90 355.136 null] >> endobj 478 0 obj << /D [2873 0 R /XYZ 90 338.493 null] >> endobj 482 0 obj << /D [2873 0 R /XYZ 90 226.244 null] >> endobj 2876 0 obj << /D [2873 0 R /XYZ 90 176.496 null] >> endobj 2877 0 obj << /D [2873 0 R /XYZ 90 142.558 null] >> endobj 2878 0 obj << /D [2873 0 R /XYZ 90 110.678 null] >> endobj 2879 0 obj << /D [2873 0 R /XYZ 90 78.797 null] >> endobj 2872 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2883 0 obj << /Length 2142 /Filter /FlateDecode >> stream xÚÍY[wܶ~ׯØÇÝ/Œ I}s%ÛUOš6ò&}°sr¸\¬– —Üò"Yýõ™\’¢dÅÉiû`ï ƒ™of ¾¸]ðÅû‹?o.^¿ÓÁ"aI$£Åf¿HøBó˜ñ \lv‹ËË¿¼ùÇæíÍj-C¾ŒØjF|ùÏ›ëÍõwïÝà÷³Y%jùæ»÷wŸWo¼¾|ëè°>æËáç§Í__¿ å`Ã@(Æ•uì~‰Dž N .Ö~~-5¬QŽks0Y­l¹¯ºÚQY‘6iÜGmvæç²$¶ö`hs5Ø\(Áâ$ð››•äËÏ&ëZ3£©R,Œ{Þ´ÜÍ Œ™âÂóäÍÏiQT÷f7wpÍx¢<ëÑ´‡jçt­ög-qY¸ßù˜pZ%C;øÓÃF`+ÅY¬åb-KBºÊS]­D¸¼Ëwh$¼˜¬*›¶î²¶ªiäþgG¢æ+.ïݧU‰®15 Uî÷Oã+ T {ÃY%íýIÊpÌõqr¾lN&Ë÷6÷æ°t×´ŽÚ’ Ïñÿ³wE|Û‡^Ó†F™\”T!‹cõ›—LD“›{©Œ0f:zþÐÕ©Í«ìK ÿc¦cù2w YrS§sÞ¦ÁD¨Ç7¾ñþ2<…=)†e–¢ Ü`N¾·«JZr—§Ž8UyÙNÝm¸·Xc?¿1GsÜö«).oÇûª¦É·…™HÏ?ûà  ³kާÄ–í@ïáÁîóö—“HiÒ#Q;ƒ‘t—gô}J[8VÉœ5Øyí$#zcFL0ÉS«µààA—˜¥l›™{J$Kâú[ÈÜ ÷ã4õ¶°>BdZŽ­éÀuþi3ök ¿4.û=¡ÞêT43–Á_.WŽUnì|î¹dK@„äåˆ&ÏB‚!@Bü_PõKqEñóšÊ˜…}ü~áæþf%4ã ©Mº{ݘö‘3íÒ6õÑ‚1Ù|ÕEÎîéð¯­Ó¬îµ¯«ã$«í¿Œg„ ¶Ë)e³÷qTMCº4íýJÀDýËw’¼„”úè€|Õÿç!(x•´ Rþ~íG‘ÿ‚`i"ÄIqªP|¤ŒíøJ,û©¼kté¥a­ç¤/~_¹¡êd|6qšAå0ãØÒ¹c쪬8JEËn¾µáÕ_Ô· Gܼ¿°^«™ÒRQ:  ‹R,hã.nš’˜€>j=`gnCrw¥ŸÒÆžÇ[y/@Êù7ÌM熎‡ß¶Ëšã]?Œl‹Urø8b‘ŽÇâ]) È-ÁÜíe:íqÎz ¤Äê`ú¢hë}½ŸàHB;•Üps¨ºbç˜ä«xhSÚÃR¤8 Й}fœÂG ô—'«£†SS-ë&Çu2êëºÔù¥´¸ŽvI‹¦r”;KÒɰ²7ˆ¿É–)q§ÛÆW¾?ž;ãÖdig»h’3 á2¤û8RÖžé÷ƒ¨o‹v}føyŸbÝúð‰‡þ‰¬‡–Qè/½'h@6"˜ÈŽWßݦ5jgËL‡ö¡-äñ÷Ôùù»¼n»´@ÃêP†ë®0ô° A°ž@¾$¡Ÿ¨U!¡ês£ý[-$ñè‰D¸ŠÈÖ>øAÚG»|(<.ÂÈÙï7°5EUÞæåíXÊÌïAxl†UÖ*vúy¬hô¤Iý WÉY¬¦­ÆZJg uT i«r¤·N»˜G¾sÌ‹yIfBÂÁ–Ôç4d+ÙÚÈV˜ðKYØ}Œ‚™ª9Ì~ô(@j°Òá»q,öºlÈÃ`ò@?ñ^Ç9ë£p§Î·ˆyУyCÎyQÙ)š¾\(xd‚íÜ]"eÍcÈIÁÞä0êõo‡*;6 R–VøãpØö®¹3:ø]óŠJ(P.åF¾A ¤l­ŒTà<Œ+_ëù·A˜¹*r ­b!Ró¾Ž ÎA¬ÊUƒ(j —vEëÆ§¯8FïSÈŸûå4eާöÁMm«ÝÃØÚ=÷"‚(UG½Íè sÕ:Ÿ­Ó™ü½Ï#ÍïzùãžG6O!iŠi28À…©gΪ5“Ï7þj0øõ­kš¦>Õ볯ê.?ä·eZøw…"íŸ6‡ïmˆ——ß|3}Uôúµ-íä=j†¶4… ¸ž>ÖU Ñ=íÁ‡½Ù¨çþA_˜Ö÷â¾hšÕõåogŸWìǹýé0tâáã&–a¯&¼ÓøDêœ{}Þn.þMÍÀ? ®!ÒãEv¼øø_ì`€©$^Ü[®ãñN$X/‹ß»?@Ó†,Ѻ‡ø8LàW01j'¨éH4ö Ž1öë,Nè¯B®ÆF‡h©ñ÷ ªîä¼8áªÏ ?̈™ûâ¬ÌAÌqFŽ„Šûòïæ 9}Ê2MÕÕ™™1¥ú*éÛYAêüGˆ*K§¯¢Ó_¸_g:FÀ endstream endobj 2882 0 obj << /Type /Page /Contents 2883 0 R /Resources 2881 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R /Annots [ 2880 0 R ] >> endobj 2880 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [171.497 334.214 177.674 346.978] /A << /S /GoTo /D (Hfootnote.9) >> >> endobj 2884 0 obj << /D [2882 0 R /XYZ 89 721 null] >> endobj 486 0 obj << /D [2882 0 R /XYZ 90 579.669 null] >> endobj 490 0 obj << /D [2882 0 R /XYZ 90 403.769 null] >> endobj 494 0 obj << /D [2882 0 R /XYZ 90 385.069 null] >> endobj 498 0 obj << /D [2882 0 R /XYZ 90 227.056 null] >> endobj 2885 0 obj << /D [2882 0 R /XYZ 104.346 107.687 null] >> endobj 2881 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2888 0 obj << /Length 1691 /Filter /FlateDecode >> stream xÚ­XIwÛ6¾ûWèH½D qQoŽí¸îk–—êҤˆ„$4©rqªþúÎ`IÑŽ£æ"Ûìß@Îd3q&·¯—¯ÞDóÉÂ^„^8Y®' g9±í̃É2|¶®~½ü°¼ù8yc…öt„Žuÿñny÷î–˜—ôYN¾uùîö= ¯o>Ý]Ýýìë|þ\þöêMàu.œ»¾íøˆ£ï[ø¸æÂaA:§³xfVϼ˜>í m×öì`:sÙJau•‰ª¢A¢ÉÓëÉÌí0¦“nD²Îüyl]Ë©X*‘|ˆ?_X*¯j‘'’–(抜Æb³)åÔ ¬Í4°DÍ«¾©zKëŠÜlìì5që-O·r㬖Ì:hFWŽ-AÕ´2®½Øw JæÅ±µB‹Ä‘ÕT2%N]Ð÷ïF–"‹’íŠT­™—°Ü—Å^–µ’(ÍÜ󭻚ÖÃ*ý RÉK͵RT‡îuZb¨¼–åzê:–H˜µ6¤­éY°Õ_2©+³qLS²³°RQ‹•¨$Ê š/«¤TûZè,'&«ÃDM6uZ]‘© ‡¼o_Mž©xª½²”kYJr'ð—ê"ß4{õâñ/?ܱ(EÒìd^ -̈2bê9ÖÚ@¨L¬2g¼¿µ‰ïÎM8¼¿yMÄ^lÐI:Ö{Ù÷x¡=ÂnڄôyÛdµº¬ëR­P¦–ƒ ä c»|ÐuÇÔ§ùæ:s(. “îÒá¢5?†%x¦c©\–4Ôq¢§³ ˆ,2u-í¨W†ôš®|l*¿8Ž—c*ôÎ#ê&µA[ºç&0X‰¦áJà™ ÷zîq†{:ÃÍB“Wsös̬=8Û½_‡Ìrl£aíÀ6Ùx:ó°$”"œ5r ‹"êûâN?®=—:á!¶‚kêJJŽI–o”Ô‰”C•C E qf;‘Cüb‚Ïø­ª™e"—EÃÇíd½-ÒªoÂR‚¥:V&.ܸ!É¥ÔŽ“鉿hÙ£è;¢k9Ÿ#¦ O¦*–GGâ¸Ø„—z’…™(w|B7ÎLè™lUÁ}Z‡[Y?*IÞìVXtŽ>9ËJÏtp²•ÉWöÖz`€SÙ²Æ`V4u86âaoÌ~W÷-½ÆÓ4 ³µõw%û~¬µnêÆÄL¯Q ­M)ö[•ˆŒ…Úï3=Ö£ÖE‘}UúrwÊÉŒšx]ÃböÃ\Ö®©xõŠ9¬7½R`O’eªòM÷ž¨sfGH:±Hy [™XÐ#Þâ@óJjg*—FÈ0踞ˆ6Ü=§3‰F;“Îë¶Ÿß\ctßœ +ýÚ¼1ø¶‡É'EåK»Ö"gÃÓÀÒtWU±ã«Ò“úüÓ.u_UO@ú±„ü¬†g¶Ÿ‚Ôêí ýLÕϱ[ÇzÎ8•F{â C¼/çã×Mžpv.Û—ðÂ?Û îY)ß9y¬OFêGŒÉý]ôºÑÿ~êzgôñÿz?{~ 7žÁvxzb];¢ò`Á@ºv;·°I2Žÿ]ÁH·0]Äxô©+ óÜêÈÊsÀ¨÷ïOœt¹ïsš«‹=ú=2ºë™­9ŽbEÏ•R¤Ð+ƒ! 5:ö6 ½,­×K¤ÍF-w ü ί´Åª Ô§°¥y?þ꽟Ρô€øh?߸ ©V=h|ECÌoJ›¨ö? õs+e~[u` «ÎÔµ$OêZß¡ÚÀ"µèæ'òÁlàŠ–½g×6Ÿ€»W3Ì÷fyñŠ y endstream endobj 2887 0 obj << /Type /Page /Contents 2888 0 R /Resources 2886 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R >> endobj 2889 0 obj << /D [2887 0 R /XYZ 89 721 null] >> endobj 502 0 obj << /D [2887 0 R /XYZ 90 690.045 null] >> endobj 506 0 obj << /D [2887 0 R /XYZ 90 608.879 null] >> endobj 510 0 obj << /D [2887 0 R /XYZ 90 592.237 null] >> endobj 514 0 obj << /D [2887 0 R /XYZ 90 539.833 null] >> endobj 518 0 obj << /D [2887 0 R /XYZ 90 396.966 null] >> endobj 522 0 obj << /D [2887 0 R /XYZ 90 378.266 null] >> endobj 526 0 obj << /D [2887 0 R /XYZ 90 301.953 null] >> endobj 530 0 obj << /D [2887 0 R /XYZ 90 137.258 null] >> endobj 534 0 obj << /D [2887 0 R /XYZ 90 120.615 null] >> endobj 538 0 obj << /D [2887 0 R /XYZ 90 70.269 null] >> endobj 2886 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2892 0 obj << /Length 1945 /Filter /FlateDecode >> stream xÚåXKoãF¾ûWè´ Ó> €ÇöÌz‘d&#!>$@Im‹YJÔ”c±ùí©îª¦ùh{œä`/b³X]ﯫZlr7a“w'o'_¼ƒIê§‘ˆ&‹ÛIÊ&1K|„“Åfò£wñ¯ó‹«Ó™™ùÓY1ïæãõâú»wH<ÇÇbšJïü»wïñõòê‡ë‹+\Ïa¼àñóâß_¼ EGaÀ¥Ïd æ}i yNÖ±óÌrÏD D‰{"ŸûÂO§3βUdXÓT¸ZY];t³ÉŒ'~” ˜›iÀ¼¼Ùæ{ØÅ¯1‚¸ô—ó÷ßž"Qeë-®2Ÿ¯¦‚yÇF!©>eÕ¨ î[='>6j*Bï>_w^#[¾;j§ö´/î«Õ!«²†Œ1¾@Dš«ÀB®ÂªuÕ8Çý4¤DmR’W°¨Ê²Ñ+»ÇoË ä'¬ÊÛvc­:”¶B²À»nÁj8ÖÆà3‘ʺÜÿRî×M^áÂ<0ç|N e{’s£Ë'3.w›SßW¿r¨R-iG_‡2´RÛLîóòXMÃÐÓ^rŽ^Â÷ú‰1±W5 l¶•¢;ÕlËM/ÛÜP+©”åUT„²S„’G~"lýçõ2+ŠòAmNqw5•1dcã(ß(ñžØ:ZcéZxœZž‡*o”CÒ,`ÂyÜ!9xbpžDàÿ픃SÇ¢q¨K¨‹ÆÎ¸€ù"mYQªPSz¿æuSã;%,†éÒ¤B[ó`Lz¬-­(5Ô@/Ù~ù¢Ñ‚¥¾ ¤5å…ˆ î3Î?ñØ2ú\Ä…ô¥l³®v‡æÑ”ñL¦pú¦3P‰Aˆõ¤¶µ—axouÜt¬ôÇ <ÈV±ö"•%£Ž:ü–“ܽZ«ºÎªGýir©¥ÞëU¡7†ü\1÷üz9”a÷ÓïòC«4~`tdà§"¥èD”‡s"Æ9­ÊJðì8§_ÍñO‡sæ³Ó9 _†¯I-‹Å¨°#F,°¢a¡³Ôý¦^ÇŒ±cÐTJstF½ó&õvǺÁñ$ô‘ô hEgÔÐßFí}t¡×gá0‘аÛ`9vØùA­›ê¸û£v±5i Ò¶õPŽû­‹èÃmUîp… eʽª³ÑÍ f-¡ìXeµéÁØ ú­jòzQï©HIEb{œ¦ìIö¸™³™Æ'YHOwMc¤& Ÿ&™ZЋ›)lÌѶlÍcp ÏN§Ó¯N§7<¹hŒuºú^M"Œ"ÅйAò©måÔ.;Y eÆÎf„A» ]ÿ>ÛîwêGEÂ_s1? Å+úhüYèÃË>ôkÀfB„>œ'„³¨‡3>ÄÙõ.»Sd0&ÚâOÓn:à,µÒÒ©† Á„"!%°uwØRì!Ä[šX¼i+´?H‚m¬¢›1ßUýñ2Žíx +´ÃñHxâ‰2ý¡ãˆ–Uâ³;RÂkw¤4_Ñ7­`,Ñ9]¦Qæ:9ž¹Ìü5”Iµý? L¦0[ÇN”‰Q7kÔá ªo˦m-+Á·H½TõºÊ¦Çör˜/Yk¯m~O÷.=ƒuš_Ð6?{†Ëöòx å7ØP-Ó0×ÙØWb 7ßß=qáЀ&aÕTeQðÅÜ+W¿ÀÙ€ëN·e Íâ oÀ°.w;˜<ŠŠ_wwæ$¶ íkÓP5ÆIË"`I3 ñˆO¹èß°á84븰u¨Ê»*Ûíe›&0fze®Gë5á©àªD磰ž¢F£å»-'ÔUÔ´¯†jS-µhêyä0m“5Ùë8á‹¶`ÍÕ!·ÛþábŸW‹“O'ÖlÂõŸBR†M9YïN~ü™M6@‡€ú1Œð†k7Ñ7—éc¥˜ÌO¾‰46qÖC‡ÓƒÅæÚЎ󪈵ÑÒË.2Ït8®Š|ë…þÛiùæ|~µ¼øæ|>ï%›„ dý¯«äX䙋/Р˜ó ÙBŸþgg—Jçé¢=3\qÌ•Úú§êŸæCÇW2éOk…ƤVýÉ¿DX û<ÌòáŸ7#p›AäS¨]¸E`ô·‚&ÉŸÙw·w솉ÓO ô=»£¿©Ý|{òœÛ‰ðÃ(ìW^Lnÿ6ô[o¤ªüß—®zK\Ä”ÄA¸¾)mÍlÔýR_%—‡²6˜Öò‰ãɾ$sŸKžµÉ+µ~µ,N²VeY ³¹Þmìx¡ub}ñþã›ó³³óýã¨ð‡Ò… Ò\’Îû¼jŽ©}ª¦ycþ4µNÕúÕÆÝ­&xAà…6ÜH}‚ª{¬_–:©‘KÛ}™op•Ùc½T¿ª5Œ›å¶,ÿó²šØIM^Vcr­'Õ%”þæ!«LŒî!ueõU9ÿš²cxмnÆØ„¤/«2óÜ_ÕEn æ¤Ú2ø×…åÇý£­ç‹OˆQiÃÄü$vkûIòGõiñxPÖ‚OÏ —#ƒ1JsÕ|}ó¬Õ®þ;T™×! endstream endobj 2891 0 obj << /Type /Page /Contents 2892 0 R /Resources 2890 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R >> endobj 2893 0 obj << /D [2891 0 R /XYZ 89 721 null] >> endobj 542 0 obj << /D [2891 0 R /XYZ 90 690.045 null] >> endobj 546 0 obj << /D [2891 0 R /XYZ 90 575.001 null] >> endobj 550 0 obj << /D [2891 0 R /XYZ 90 504.546 null] >> endobj 554 0 obj << /D [2891 0 R /XYZ 90 435.43 null] >> endobj 558 0 obj << /D [2891 0 R /XYZ 90 416.167 null] >> endobj 562 0 obj << /D [2891 0 R /XYZ 90 365.597 null] >> endobj 2890 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2897 0 obj << /Length 1480 /Filter /FlateDecode >> stream xÚ­X[oÛ6~÷¯ÐÓ 3ÛnÙ“—¤Y†¤éb£†,3¶V[ò$¹i0ì¿ïP$É¢ÝtÈ©ÃÃsùxn6v–v.?O'ïîD(ò©ïL;æž3]8÷îÙ/ãÓ‹»áˆzØõÑpäùØýýîjzõáRÇj™#æŽ?\ÞªÏó‹OWgj?û!v?Áò0ýõä½G[ 9a³Ì©õEžä`màÉ{‚ÛÜ#†ˆ0gD 1u‡òሄ»_òt1ù°+D¼˜§…Hª4ÏþÄžÆÙ2?=WU‘Îw•P|?ÀùIªu#BPäiÇ©g¥úFUZT»x­¤¼èM³´š-Ä—4RéaéÁq9 ±•x•¤°Cõ55êA²Ʋٶȷ¢¨RQͰ•J”<R¼B‹?µòRmÆ:Ï–Š/þš–÷ãËÉÍìfüÇìævz{7y°«gúò¹ørÝÜßæe*ßô24ŒÛd,L`¼Ò¯çEYÅ•xåmßJ5 ãÒØ'Y ‰ç¸€Îÿ»úÄCQ:-r á<û¨!™É¨W6ŒõG£=¥áÛ)m’ëkUá eMDÕøðT¤•°¾%·†#'G¤oÒÌú&œ»µ_bV*L·Uq Cî)Ûþµ#c 1è;j9©y˜‡BßS±¶Eúf‹~‘éÔÎÕ:©ÄêÆM^å…¢dñF”Û8JD!FC‹pénЖ}Ò©òf½˜þØb‡ÈNÄB†Hä;Éfpÿ€ÐÁKDóTsm…ÈÃ>ì×Îdð›êhC0GÀÌ|‚(€^ë¿N3¡šQËépÄ<âJ“»¾JJ²ŽËRmÓl% Lõ×c‘oÔ®2·ÏÅz®¬µW›íº}ßòN/¶ðQбæìEe’geUì0GSbùV`úÅZÆúý=†8@|à-Ñhfÿ#xx> ûxèPeÐlšÊÈHÎkûºÄU¬4¸ýËËD1ÕTG± §"Yb ƺg»‰uZ`ˆü°+-è\”I‘nkûÎA]0Ϋ”f1šEí-¿T‡–,õ£KÒ‹×gæi*EÕ÷:ý<tÄ«ïý¨ñWÆuà‡Ûu(†¾[®òÝZj¨ 8ÐòlýlvB¥Ðíã,1 jU! Ç=|ÁhÈVSÞ€Õ¬"+w*3j…I¼+…fxÌd#õj’œÂ+‘ÙZëc¾^ç„§TNÌ”›T‚ÍH¼uØÃç¦{QÈ©´är\©³£¶‰Ë—R뽞åèW,õ xw9w¦E <ÔåÛÝ|&û…øìЬLç?ÖŸÔ¦ìK‰§ÖßIæâÊè<`Ý;Ù’dk©çníÓ*Öoü®ùËÄôˆ9M endstream endobj 2896 0 obj << /Type /Page /Contents 2897 0 R /Resources 2895 0 R /MediaBox [0 0 612 792] /Parent 2871 0 R /Annots [ 2894 0 R ] >> endobj 2894 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [270.962 159.559 282.917 168.406] /A << /S /GoTo /D (cite.Patterns) >> >> endobj 2898 0 obj << /D [2896 0 R /XYZ 89 721 null] >> endobj 566 0 obj << /D [2896 0 R /XYZ 90 215.101 null] >> endobj 570 0 obj << /D [2896 0 R /XYZ 90 194.498 null] >> endobj 574 0 obj << /D [2896 0 R /XYZ 90 131.973 null] >> endobj 2895 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2901 0 obj << /Length 1517 /Filter /FlateDecode >> stream xÚ½W]oÛ6}ϯÐÓ KŠ")¦Øƒë¤]†~-ñº‡®d™IØ’'Éí‚¢ýí»IY²¥Æ]‡=â—./Ͻ÷{·ö^œ<›ŸÆþ;x}˜ÿúä9 ;F„"L¸Óì'¹^s‚­ƒ^@%x#©„¾¡f3†«:©³ÔnR«ÍF•¯Šº(g«¤ªÌð£,‡UyªþÄ ÃCžjû`; IfOÉÍâ¯FÜWfþóµ³fú?›×ëß_¾|úeÈ®ŒÍW›²¨UZ«åéÐ"9r*íPU—Y~kütx&n,|3kÞM!~R^5NË2¹·Œ£h©öåi—î}>?ùë„@{DÇ£1â„zéúäýì-aL"!…÷©Yµö4¡æÐ^yW'¿™ì…Á’Qä1—öð/³Ü²ÎÞÆé$ pÜù]fo1Ý]¨J,¶‹ 3[ܘw}g-žµvHa>¸†'Q`ј† ¶Ž½Rõ]±¬ö,“Ú:µVë…*M;W©ªª¤´×qS”{^Á}­T]ä–-I]«2ÿ¶w¼‡SçdK´Õ4ºñÐ}¤Ï ‡à0Ïê̹ÑÒd6Ú»F"Â]fkãÅt ŠEÔ-_7ð9‡á2Je{‰=Æf[ZG?fe½MVöîó£n7Y­šÓ$&(ŽøŠ„.îþ-!·8@¼¯£PpŒ¤$ÿŽéP qlj€H@J öpÄBW+A!Ò˜ŒuüíLës]ªdù¶IPU¡~0AŽˆûƱæÎT•–Ù¦ùò‚%K‹ }Ê…oÞÜœSèý&Ä·ÓM<õæ-³­£z…e)zÎq»wÉ¥Ùl½Y©µÊëÊÈ8ÕãÏ" 6¬ûJ£ô·J·µ8* ”ìZ?ì Dã–XYu ¤.>©å̤EÜ'”>&À¨†ÏšRº»¸7oƒ4fÝ €NÄ©C–8t é†:)­±ªÒd[)g:sØhÞ ¾ÔmØMå-êŽúÛª-½³üN•YG¡¬‹¥Z¡ncKj¾Çðåa'È©|”QDqü=•oßdS î\’Xx”D¥-ÉàbˆÛzÇo{Tž­—füÔ¼6ÛÅJK Ýv·9P:BkøóÐ$µ“ÆÖéPåˆt| z£ÕHZ€Æ2>¤w‰)=aH€–`‰ÈJÛGÍCØÚ~ìòNSL $XÜG”Y¸¾ãed·^ðùˈhTÜÆh[tgQ¶ÕÉM_oÛC=¸€ø201錛FÃ0Ec0ÍÞ\>›žžNó{ÓïÈsˆ7øÓ!ôàgàÐߎý%a „„8Æ#eóéØá‘ˆAb6ÿÀáZrõbš˜9R<‡ð+·þñL$8BèCâY¡–èY7cp>§ ÞVîIçaÙÚ7.¹/‚Ø4Àx„é¾^ƒ‰ÆÉǪ4\ƒdñ±e®äá*½ûÁ¸ê‡²\íÈ>è5²O 'û`d'û “å»ó5ëºI?C† Èû¹ÛÖõñBÙWl_ýu%ß´®Ë£dûÙR#ûBêÎIEËQj5ŸnØIî†?¨2[h¯á&Ö%¼µÌû³ÝÍD°¢‚?ˆ¤°e‡Ú#ê°Tà`³6rª¥2½›²XësžG¾Z‹¤²cNˆQÌZ¿£QW¦¶ÖÉ ¸„ÝOZ9ß¡ \üÅ„¡x€ê "‹†!‚T{¾¤ ‚ {.î÷RÐéÐXÆýÈúy endstream endobj 2900 0 obj << /Type /Page /Contents 2901 0 R /Resources 2899 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R >> endobj 2902 0 obj << /D [2900 0 R /XYZ 89 721 null] >> endobj 578 0 obj << /D [2900 0 R /XYZ 90 452.147 null] >> endobj 582 0 obj << /D [2900 0 R /XYZ 90 435.505 null] >> endobj 586 0 obj << /D [2900 0 R /XYZ 90 383.031 null] >> endobj 590 0 obj << /D [2900 0 R /XYZ 90 141.378 null] >> endobj 594 0 obj << /D [2900 0 R /XYZ 90 122.678 null] >> endobj 2899 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2910 0 obj << /Length 2057 /Filter /FlateDecode >> stream xÚµYÝsÛ6÷_ÁÉÃt¢‚„ÓéŒÏqSwÚ4çhziÇC‰´ÍITDÊ®'Óþí·‹ÄÑŠÓö€ `±_øí®ÂƒÛ€oNþ5;ùêÛD†é`v$Lο;{7»¸š†QÌ'šMÃXóÉ®.g—oßñŒ†ÙÔÈÉÙÛ7?Ñç닟/Ï/hþΧ|ò3 ¿Î¾ÿêÛ8ê\¨„d\& ޽Ï$¸ç„;A:ÞÙúÝa”QÒÍ‹˜ˆY4 çpyñ çѺlÊjÝcçÇ‹ÙÉÇSTYkç“`±:ùð+r p–˜$x°»V4)‹¹†ù2xòï–Ö”‚wUJ‹8Ð2e‘4$¬#q±Ìêzj˜¾«j+êYÓlO‰´ÙÍ—å‚æ³l}[žâ**·…B0;EŽá§±Eé‰ßéØ5 %Hñ 9ü‰Sÿñ¯¾xéÄ_ÿðÓÛ7þûêâì5yÕ»CÓ±»ã±KHËO¿¿“NÇî¾Ü6»lI î«2§Ù¶Èrdî%-îËEq¹Ú,-¯(ŒÇ)pd‰rôO»3“¤A‡œ÷/;Ö/绦 +þ‘5•ÏA'•º/dê„ü„¢ÔMÖ”‹ëEV7_¿oŠÍ¦ØþX59T˜„EšRC’ CþyTx5þ…ß ®×Þª¸ê{õ»Kˆ½¤/š³ß¼ªÜ¬¬¯³å²z(ŽY1ÕÌDê9B÷­xU|œ=nœ›ÇŽ᥉éK*¸·â¶hvÛ5û¬E#3žŠ'¤K›Ô÷íÚdÝÛÕF‘釹ð›bù³°£ŒfÉ¡ŽE™~ ®˜eT¢X +VÊuAØ+hX‘ äΑúà´tcFC½›l©nhlüq‹E]#o´A…qOˆó–ñ¢Z×Ív·@¿‘ëœ&y±_ÁÇÜÄ8kv¿*¼‹ývÍJ#JOùGví'†}þÙNe275’©"Á~ãªh8»; ÷Y®Û íÄ™ fÖ\E•ŠÁÖôxÀu Ïë‘æ /nªíì–móŽmuLŸPÄB(ê{ëuý3±‹îÈ’Tè8½G7ˆ…PE,•f4"ŒqøCNK†kä4ó¤Ó D‰½˜-^Õš©(=ôšéz o$¯ï5ã¼&}®F¯ÅéÞkfâÇlYW´/#ÂÏ úÌÚE$Ä8ç Óº«c×uGN%“RÿUÚ‹„ŒlXqˆþ0@i[xIWs½o2H&›þM™ÌSO0Ð÷’T±EÚX â[O™vw̬Öp ¾©˜à5ôeÕF!ûȳÇb¿¦E|RŪXcº¨Ö´áÕÅÅš @Ô™¡Ïñ%HÌ5œØ¹%2hMGPO$:QâžEÏŸ‚Ʋ®vuC³¹³5ÕoøO±€r#g{ä®Ý޽ÖÂÛƒk7ã"b  „‚4í“)ëïùƼ› –p¨y,Xìí ¯Ëõí²hü¹ûÒ9½lê‘¨Ž”`qíÃÞüH@•¯´ñ›ÚB±U¿¯ ,@ÂWÂéë²Dô¤¾‡rIÎTûjÕj©èú&à ô8"aþTGüü“ë&B+ ™`2Ñ}Ê/Ñ Ú"¹‡¾ÌV°ÓˆO ¬Žh¦&£äP5)[Õ¤V5¤YÕ0¢®{ð qà9ät—9bFßyqcÑs·lˆ^¬6Í#(”Bˆþ{šWù#™ñÆãXÅÌC 7ïÜ«ë¥fCà#R}¨?T- ±~ ðú+Œ&ÀêÔô_ˆKf‘ÐÃ7ȸÙV‹"ßYh5¿j²XË–9H^ÓnÌ¢·¸íBÕíö6 É•µîÖÐ ‡d†ù1u Ì: «VOáð'cz©‡r¹¤ Ù®©VØ@‚|_¼¹E¹×4–P…fk+Ò7ò…L^ïƒÉ_ DÖ’K'={õì—ñ¢©Ó‰^PÿÆY¶ÙÕ/ÇÃ¥bPE_"¼ºJÛ"š Ÿù‹ES6× u±«•Cñu‹æ‡Œ–eÝ0êa© éI4þ(°têo@ZÙyÒ.Vm Ô½ažÑé_œìêbK³n,œTµ;¸vwdy¾ç°¢ÙGùßôa&Ý3Œ¦-a&þ.(‰·ïØ*{A¹Ì{µJß¡!Öö¤#Ò:[9t™äæY‘’t+࿟"mõ…¹‡‹´a =ZÜuP…^ ÍÉ‘0ñ¦. `F¨è_ü%$3ì&fØ#wÚ…¤Ø Lœº‚Üûò-Ý;&uŽéžrLmçãܱµÚCMMao| [uÊ-M­ëh¹tl6 e‘wY>Õ§I­Ø—90¤#=³´M›{oXÖ[<²„Mæ0Í ¥H'·;¬öm}Ðáà~w.#>õnzø*µ²Óö/Kk{w›ï·TØH®&w…,£Íxq8Ói´lãJ;É´r1™c硵å§G‚‡‡¥kFqæØ`˜Ä¾Êe$i û§ïD"èÔrs¥ž$¬ý审›mµT2#G[ÈñrùÏÇöðH«!cè"ÔQÐÜcÄHÞÑPüEý>š¶Æ?„>ì•ëÏ»ð_ü†Ý¾Ïª‹»úgao¡gÔ[öÿjäèoß"ÿ!Õ endstream endobj 2909 0 obj << /Type /Page /Contents 2910 0 R /Resources 2908 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R /Annots [ 2904 0 R 2906 0 R ] >> endobj 2904 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [264.424 241.188 278.87 252.092] /A << /S /GoTo /D (figure.caption.4) >> >> endobj 2906 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [132.72 74.439 147.165 85.343] /A << /S /GoTo /D (figure.caption.5) >> >> endobj 2911 0 obj << /D [2909 0 R /XYZ 89 721 null] >> endobj 598 0 obj << /D [2909 0 R /XYZ 90 690.045 null] >> endobj 602 0 obj << /D [2909 0 R /XYZ 90 398.349 null] >> endobj 2912 0 obj << /D [2909 0 R /XYZ 90 351.838 null] >> endobj 2913 0 obj << /D [2909 0 R /XYZ 90 329.856 null] >> endobj 2914 0 obj << /D [2909 0 R /XYZ 90 309.93 null] >> endobj 2915 0 obj << /D [2909 0 R /XYZ 90 278.05 null] >> endobj 606 0 obj << /D [2909 0 R /XYZ 90 108.063 null] >> endobj 2908 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2920 0 obj << /Length 705 /Filter /FlateDecode >> stream xÚ…TMsÓ0½çWèh¢JÖ—Å­MÓZh=å ã:jb&¶SÇ¡ðïYií&iLf¬ÕÓj÷í[mYF.GgÙèäÂHb©Õ‰&Ù±Œ–R&ÉæäK4y{ú1›ÞÄãD±HÓx¬4‹>ß̲ÙÕ%‚§¸d±ÑéÕå5nϧw³Éí[¸Ÿ²è–oÙ»“ •ì%”\P& Ð ùlê}F¬'8¬ÓlÄÁ`„Îà‚QD2Mp/ªÑ㈠«Sã!øx/zé€sÂ%5`Š4¥‰Èü¢\l[7•¼‰Ç‚ƒ.NTô³,ú“uÞu®­q³éò¶Û®û{ܺüŽÕÿW$áÂP«D¯ƒL¥Ò¨ƒ[þSû$»èGtHª¹&œ[ª“䘢×aÒTU^Ïv1WÑ/ÿqŶ+›^Ž®¬Êzq´~  Õ&!ãÄPi æš»MÑ–÷â c£eãÅ~‚ <·né­\·læ–Õzå*Ww>Q8Íq)~Ákƒà!Oן>-]}ìî÷²n¶úL®oÎb¡`8  /©•^Mbö“Õ¬]›cñ"˜ÖÖ?ƒMŸLF÷¿Îq)V%‡14 i¶tý@‰½¦p­©Ã<r{=~:¥ÜêÁ{'•ˆš\QG rÛ¹5pþÐtMÛ»ÜÿpE‡öW¦XY/][zî¡êD(Ê! –­1ÅCÛTÐn#1pbÔތ̠=xX¬òÍbrtñê„;m¹X¸Ö«ãa¯Ž‡óºw«a¤ê0k€ú <šï…Ddáj/>†‘ÏažíÚðÙù{ÄAÍu¹rm¬TDC‘ì°©Ù2ôQš”`ùjÕÃÝÑžYNSÍ_öl Ÿìu× ¼'a/=Jõ2qèaŸ5û=œ Bê]#Áå°‘žíÑ?ö¿ôè­•¡ endstream endobj 2919 0 obj << /Type /Page /Contents 2920 0 R /Resources 2918 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R >> endobj 2905 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./42_home_taurel_tango_manual_ds_writing_startup.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2922 0 R /BBox [0 0 1000 319] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2923 0 R >>/Font << /R8 2924 0 R/R10 2925 0 R>> >> /Length 1644 /Filter /FlateDecode >> stream xœXËnÜF¼ó+x‹`Çó~óBà "id#P¤µ­€+ÙÒ:Fþ>ÕCΰI‘KöA»ÅšébwOwÏ~j¥P­¤ÿÃßë}óê<´ï›OlJ²Ý7ô k”Ä?ö)?ìšÒQ‰¨[íÆc2!ç+Ò1$)¡!uÕĸ ,€ …žRÊÆš?¾mïšËÖ’mßBáMcEÐ+¾dí²=ÿ¹Q८›‘J…Rlû‹ælqé ® +Ú/^àA•‚’{° ̃RI=·y é…ªY‰SÆ—=XÜUVŽî÷"w-I_19ªz‘oœJÂYî›éÓÆð×<† B‰ÂN)eãÿñͰ’ù¦î5ñ “¾j²¨ºxbÈ*¶:9'‚¢] —>3Jÿ•=7Nka£TĹ(bÈ,«¥Þ3VE¬u¦ž•LÞrVAŒÑä‡ç…X[åòêz¾´SJ˜ÈÎùˆ”6®:†à“枘۪1VAF¡=«ÚId°™Õ‡Ë!, ¢{IU0šüîàÙ(^Æ+\E:† !CFú%k_UÂ%ñ‰‰µt×Ñj!c]FRRg’9gOå®+jžã +‘… ¬ö´)2N¦(‚©HÇo…鑲ê¢på÷ÜÖš[ŒOZXWW’¦˜„Ž“³r¶¨}ÝfÑõ,ï„ÞéÚ(#t>Ñä“YŽ!.­K¿Fä­sì8ÏM¬6^ƒÜ§ +I ^›Î+ g‹’×m:µTk^Ö”¼dþ¯¤*¨˜žÊQµÄ'Ê^Æ*ï¦"…/+øD,ß‹±†½8«ÈYƒ,N*%i$•’´hS‹Ž‰ÁÊ2HW‘¦¬j±²ªEÆ*%˜ØRSqC„èà5xíÃŽÌÒé÷æ(§ ™p¨åP¸R9[O62ЀÆÙ“†\{²“Æä‘\OrNzJ´9Iêͺ'ÍRÍytðÄ;^Ax$¬±ùô²H„DÒï…¬à½z8'zŒh!#© œõõ"æHQôñE§eÌ€t ±†œÕ±UG'¥°éšÛª¥îÄ{æžHM]ÅÉKvIôº±"ös¦z`#ˆ©pt>P[šçÓ„”¬Âq˜g/vRÆÐÔ¶”*É%®:†$#¬bºæ¶Æ¶#AåM9xi…Ò+]gAó[c×ùz¯8ãû7Ž—æ˜cOFU¤c›‘ºêb11+φ’¹­µ¹½æG5k~°çlQûºÍ¢ =Y8”yÛÒÝþ¦DG@Ã)˜}B_×ûßÛÞÕªÿ<ü¹Þ·ßo›Wç¨èB™¾}×ô¿WÒ…CÝÒQ“"b±Ý7'·w·‡ÓíßÍ·o\½m»Áñ’ÄÚÞ4'×÷ûýÕÝÍŸï®®÷ÿ÷TÐnmNnvÿÜ^ïêÓo0*iò`„Û6‘nšË“‹ÃîãÇÝÃo÷ ýÐ]=>žn0:Ðé9ù1oЃo·¿4ð U¸ ýDÏîv_ÈnÙzÓ¿˜áÏÐ}BÇ\z†c$fXJI…„Áìùîêæ÷ûÇÛÃíýÑ^ÃtÁÒ!‘ÏL¤{Q‚ßhÁw‡ÃÃí_Ÿ»7'oN{þÄÅ…ºb•êùÓwÆëê„ 8 ¯ûzÿ±Ëo»Á°"ä [Òø>Ñ­04KÜæ@ž;{6[}Ós'~ì.fõ Ρ”Áòg›ˆ*hb‹Æ µJùÑUyUt¯SGM—´ÝíãaTåPœQÉ'FYLÉnôÉÕá3‚¯q½.Ýnp)ɾyM‰H^ùi‹ÃsÖü³“Á¨ endstream endobj 2922 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20150901131938+02'00') /ModDate (D:20150901131938+02'00') /Title (startup.fig) /Creator (fig2dev Version 3.2 Patchlevel 5e) >> endobj 2923 0 obj << /Type /ExtGState /OPM 1 >> endobj 2924 0 obj << /BaseFont /LUVEDU+Courier /FontDescriptor 2926 0 R /Type /Font /FirstChar 67 /LastChar 121 /Widths [ 600 600 0 0 0 0 600 0 0 0 600 0 0 600 0 600 600 0 0 0 0 0 0 0 0 0 0 0 600 0 600 0 600 600 600 600 0 0 600 0 0 600 600 600 600 600 0 600 600 600 0 600 600 0 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2925 0 obj << /BaseFont /DELOYE+Times-Roman /FontDescriptor 2927 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 333 333 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 0 444 333 0 0 278 0 0 278 0 500 500 0 0 333 389 278 500 0 722 0 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2926 0 obj << /Type /FontDescriptor /FontName /LUVEDU+Courier /FontBBox [ -12 -186 612 624] /Flags 33 /Ascent 624 /CapHeight 576 /Descent -186 /ItalicAngle 0 /StemV 91 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 431 /CharSet (/C/D/I/M/P/R/S/a/c/d/e/f/i/l/m/n/o/p/r/s/t/underscore/v/w/y) /FontFile3 2928 0 R >> endobj 2927 0 obj << /Type /FontDescriptor /FontName /DELOYE+Times-Roman /FontBBox [ 0 -218 706 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 105 /MissingWidth 500 /XHeight 460 /CharSet (/A/I/S/a/b/c/e/f/i/l/n/o/parenleft/parenright/r/s/space/t/u/underscore/w/y) /FontFile3 2929 0 R >> endobj 2928 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2287 >> stream xœ}V Piî¤Ó Š£®8éx"¢x £ˆëp‰':Á›% Ar‰W‹Œ98”O<¦WaDœQYWwUÑqdga½Šµð˜}íþLÕþ!¡jw«R©~Ýï½ÿïûÞÁ#Ç£ÕIŠ˜$ëóΕÇtà¾àg£Žû$~A,5°Ï‰Ç8ñ'ÁᑎÍ.pk0A3ˆàóxiùUš$ÅæØÙùò•î“lo¦y{{Ë¢4=_d1ÉŠÍ ²ñø!5F™¨ŠIHñ‘`m¥R±Q¶Y©QÅ&Ë"££c¢­fá‘ʘ8YB©P©SeÜeÓ§N6ÿÍ QÄG©“eÁ‰ ‰²¥²å1›ÕÊȤ>/ ‚ø]Bb€*0)9eQê¶HÍÆàè˜M¡Ë+”ñ ˆeD(1–#Æ+ˆ¯ 91‘XI¬"ü‰5D áIÌ'‚ˆÄ4‹XLÌ ‚‰—3Fˆ=ÄŸxóyW†;ìä{óMüç‚9‚#ÂÑÂ|á¿I5ù‹ÈGtžr¦êI?]¿ëýWõçÚrí ­¬Šu*ØaâfðáfJ|IM®6+Ó¨5ÓgQk™Ö-YhFšú’â\½†Ž€äiÖTx°W­×2$x"ÙöèÕ«Ù£h¤µ:jy_¾öö) ØwV, X>£»óÀ&ÇÓ徺Ë}†“c/Ë[Ñ—ÔM[€JrŒJ<¿ôÒ«Ó5W˜;TËìÆ‰R´ï>ÏfêKBÒa²¨ñ/òeK|VºÓ½ùܸÍŠê£1'^áæ‡§Ž—þ¨Ͱ“³ h)îØÃý$ SOöì./YÍe¸Èª/[GJW"‰d#Ì¡ 5zîB¯HKô™ú¤ú\öýìÙ‡uåx¤T¦—ÆÅŽð›/÷œêWww·tï!!‹¡ºæ ˆð8)¶nÒ"v]}Ò=«ÈúuµaQ[RWGKÕWâŽn`"™b­µ8ÐૼìO>ÇùJ~¬þ$ n+ãf–KYYy©?ëxÉɉu@ÿ> stream xœeUkT[U¾iHΩR‰±Dj’©Nö!vtZ¦uµ•Úê4m‘RžE %$$^8,)ÉS+…?g.<,Š„IâBµ4·ìÿ-A<¾W&/SªÔ¯VäæU½!.•f 7l$ˆµÄ"‘8J$Ljâ"x‰H 2ˆ}Ä~âñâyⱇ`+‰‡ˆÕ4gD!&>e<Ũ]Á[¡]ñs󭈜ˆK¬]¬NÖ?Ù‰ì1p´€Ð ¾†ÏQËȇÓ&É_ûË)^î룽ècª•|?¦‚Må?ФÖé«3›x•8à 2+\§ÅÝî\À+YØÃžÜäTXK‘އÊ4u)ͰÛÀƒlçb€RVÙˆ<ä—wñ¾Ef¹–Ûa±·8 tj3T @I]šjq‘¤µi(ñ(˜:ïwŽ x©_úª€$ªÑ¤‡ò= £]ïD— ®ßd_Ù›%Õ<À¿ L­UCr5Žh ÛŒ¡¯±ûk&¶9\êñ¸MŸŠýÛ:£¿ýæãÕÏÞ£Ôȹ‹×6QOR¬×ìÉ/èŸ(Ègª?D ðÞÅù~¾Kgÿ¢ñé"ÓJ>Áu[:[œtVg ( @é&ÓA=•ÉX4tb5žìèl0:ø]:G½ Á~Ow`¤Ü'É•©öeþ ZSÔ…5‰•tª<£_ï#·újüÑoÍãøWs6ãðu®¯aØMMµ¦æf3âÕ#c«¡rºmju[i쮤´„£Á7–2³'Æ*º•HÊË.–§I¤.%¿| ¶¯æ*¬¦â\l«½­•Η#êDz >0hî‰ýì½Ù§•#GBŠxOÞ¥@ƒ¼‰S W‡%ÛúèªOgÈÈ`´ 7P‡Ws–°Lárn¬Ãmo¶ÔóMµõµ&£89'³Ú 9KS½©á ÔØÒdi‚œoSï°·ç\»4Þ?3¯q”—iŒjÄ+о+ÀoÎÒì°H³I>ò÷Ý:wôÂ"ÞOGé&•ÓÜv–ÁqA€¿¥¶ΈÌ7:(Rz€ä :A¡–êKÌ/=#àtãÛÔ:˜jtkQ¤ÚÁ®©´N¿Ù58È?{–µpDmMÓ¾ã-7/¬¤w9ÂËÀà>“îNí©Ñoo¤[vÚ â-Õnô$úÈíZlƒ^jº,58 h/¤gDç#wùä4 Z0j²›ië•ÅsTYÌv¬Ò\@¹xÈï°^´B•­§ÍNƒï˜µÒZÙQGeÆlÀn³½ÉŽì<Ôë´¶Ñ^¯hA_“ÍèOñԽg‰M×Ú‘Íå<‰#°)æ/”Á]ÐVßxVÔÞÙ5A7í?bzÎXÚ}tE&¯&Í’1ýÑW¾Ä>_Í9Oþ#W£Ó7hT™Üç8 ™†!m¿:”ãMDpËÞ ‘ÊWÑ×ßëó·5·7[MÍ6d…ƒAÿÄ¥AÙ1þa@m=¤©Ë«+ttrÒDç²çÎMöÎÌñ9®ÔöžòÉØQ:ÿ±qÚD=û%IjËõJ¼¶Á"ùèYA@×&CxÕ9Ö8H>ü.ãÆ"®øŠ‰·,¿ÈmhÍÕ*êŽ×ðdu¬jÐÑÒ†¬NtÖæ téÒ‰;8æ>^ŸÂìþfýá× 3*ø)o^ ÍÜš~‘Š¢˜™ãS_ïàÓØ”l‘œ£E‘Ó¢P±Zv°«¶ÚÜ\ßh¹†‰3|êÞÌuÜ==‡æP¿Üõ<üÏ>[ĹÆ‹L<æîzªg½§Æ{ÝFY¿«ÔiìF°ÏÛÓÊ>yäPŠ"«TPš]WؼÆA]g£— ú„ð.vyèÁ18Ð'_ÇQ€^4øÃž1^u?úÖýßÑ3ýN¯ßg“YZ`kq¶ºZ:¯ÿçõ©(ÁhØ2zÀ«íuvtb 8d.ç*T*¹Ü¯ õù‡ª>™ Š|[RûHjRâ‹^¸‹u?¬æ¬!.ïà–³Í*ƒAƒŒˆÍ9#î‚[qlÊÖœI«rQ*Úyî(ŽH¼)žÉwÖ´—#%|%=ë¥m¢Ë8*¯bSE,?›#ò¶8ÝžXê6{M4’v|¢n"ƒ?ßþñ‹ä÷©˜ÁÚÙÜsèxùÌøüù3•…cüSÅîÒ®D8Àþ¹|Æw‹Lï2“ÛÁv´8[líºã‚¥ÓÕˆèZ  jÓÛÑeH~Ì­©±q¿&|iQN3Â'wúAc:M¦…kùicê.OÑeîÍ,)-ÈÚ÷|ÑzD­DçôƯ~3™yR=SììŠÙù®|Lñ‰òºáSô=úÉõÅà|`~8tsþgÞeŽS/s?ž>yúŸƾGx%Âüý·÷ó¦Jý©A}uÌÑ`Q`Oÿ+ŽÝh=zªf‡â°\TR˜ðŒªð‘)>œìc?´ôð°-2r©'rAünÀ~ endstream endobj 2907 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./43_home_taurel_tango_manual_ds_writing_command.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2930 0 R /BBox [0 0 819 303] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2931 0 R >>/Font << /R8 2932 0 R/R10 2933 0 R>> >> /Length 1070 /Filter /FlateDecode >> stream xœWMoã6½ëWè˜<åpøyínQ @nb ‡¢0\GÍf+ÛYÛ»iÿ}-Q¦b#€­<ç‹£¯­"nUú¿Wëæ‡;ß>MúOQ¢Ú¾ ÏŸÓÃçF”¤m«Å2ƒÂbÒ“Ñ-¬N6lH6†t¬"Oâþ½Ý4†¼6XûrÔ£Ú»ŸÖ‹NÔ¶¼o>Õ–^§ö¾a…¢kµcGiÙX%¤ôÑHDŠ žyF ]ïul0 lšǺ‰Z(D[ì9Ù˜`ˆEHLY²[µràÈ\5öäÃëTÀ™¬i¿yZ­y§[ŽÉ&¶»îWˆµŠ@bb¤(ǨÇÆÖr  iËlcÅ“—g“‚7@fÉ®°–-7qÕØ“+®RñþC²H$'­è5’rlÌóìÃþdã<9뢭!kÈÈ“™=³ÕøÓ1¯ÓñþsZcéÐF$ˆ>êȈ^“@y²±BˆZB¬¶$\CFžéœcP2[?ó:—'-kqË´B„°O™.¬ñ‹ç"IkÈÀó:m3[¿LÛËt\Oö¨ì(…Ù;—ò¦/lŒ'6EôjÈÀó:ž™­Æ_Æó2÷°B¸­¼1tªÔ`š;U6Ê•ž Ãj?¹`)š"")3/c§v“‘²½Aƒ¨ð¾–© ÀÆzkšÉh=!FY2&^H/̤R«–€lOl9„#Ëüd£¹‰.5ý2ð¼df«ñ§@^§ãŠÂŒWxY1j E9h…]|Qƒo€‘#1 ™*Ôgù~§„mr>äD<ˇÓ2!…‡36‰Ì@D¹8.«þ(LHS08F1ð¨xÊÉ~2‰†ŒNÝÆã’˜ 2Ò¼öç)ÁßÒkÿ —Fðž‚·EB(z_$d@}ªcOÍePAFž©“b3[¿,ŒËtÜ71¤drof1͘ô˜;y -ƃ<â ú²·gÍ‹#.æ¢y•Í8½'®Œ 9“ CŠa’©)aASìÐL±JÁò޲†É}÷ˆ`ñð<~­Öís¼¬ Œ˜DpÔùßÍðƒmÒøepBtèL;_77«íz½Ü<,>ã£ïv·ó/X ²bùÌL´¸;0)©ÔeçÍ7÷‡îù¹Ûýº=lwíö¯/Ýêp;‹Q²g?~è—û}»Ú<öÝa»¹1‹ã›Ý÷»nùðÛvÿtxJp°hZŠ«ÄÎifx7Qéê™±'¥P™Ð1éÚl¿õggn‡E¸“ZBZÔýÛ­¾ºd>KÅqéùˆ>â‡ßŸö‹eßo_º‡š?î7Ü[¸ß’í²Yþ·_Œ”pävûOEGz³ðh>3EâqíC÷}±ƒÏÙ XøÓIý©ù±Oþ= endstream endobj 2930 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152428+01'00') /ModDate (D:20160114152428+01'00') /Title (command.eps) /Creator (fig2dev Version 3.2 Patchlevel 1) /Author (taurel@amber1 \(E.Taurel,,,\)) >> endobj 2931 0 obj << /Type /ExtGState /OPM 1 >> endobj 2932 0 obj << /BaseFont /SUUHEO+Courier /FontDescriptor 2934 0 R /Type /Font /FirstChar 95 /LastChar 120 /Widths [ 600 0 600 0 600 600 600 0 0 600 600 0 0 600 600 600 600 600 0 600 600 600 600 600 600 600] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2933 0 obj << /BaseFont /VGQZKQ+Times-Roman /FontDescriptor 2935 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 667 722 0 0 0 0 0 0 0 0 889 0 0 556 0 667 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 500 500 278 278 500 278 778 500 500 500 0 333 389 278 500 500 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2934 0 obj << /Type /FontDescriptor /FontName /SUUHEO+Courier /FontBBox [ -12 -186 612 624] /Flags 33 /Ascent 624 /CapHeight 624 /Descent -186 /ItalicAngle 0 /StemV 91 /AvgWidth 600 /MaxWidth 600 /MissingWidth 600 /XHeight 431 /CharSet (/a/c/d/e/h/i/l/m/n/o/p/r/s/t/u/underscore/v/w/x) /FontFile3 2936 0 R >> endobj 2935 0 obj << /Type /FontDescriptor /FontName /VGQZKQ+Times-Roman /FontBBox [ -70 -218 863 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 129 /MissingWidth 500 /XHeight 460 /CharSet (/C/D/M/P/R/S/a/b/c/d/e/g/h/i/j/k/l/m/n/o/p/r/s/space/t/u/underscore/v/w/x/y) /FontFile3 2937 0 R >> endobj 2936 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1829 >> stream xœ}U PSW¾!ÉI*Q„P©¹™Õ‹‚eq*‹ÕJD+eeå%DDž „¬z¥ÖðPH|PiU°®·,VÀWK]·ÎRÄ–âÎÀØê°nÝý¯sìÌž€°³³3™ÌýÏ9ÿwÎ÷ç;?8Q<O™[˜§Êȳ}/ç¼xÜ›NÜBþ~¬ä¸—áBjc“ëì##á3ÁÉ7ßuƒ/\á#ÐÍ¥ø<ž¶úxd®F—§ÊÌ*PøÄmIðõó[f  U¤ê¦fQùªÌÅòQ”¡ÎÕdgä„)"ÉjµZ•¦ÈTë4YùŠ”ôôŒt[Z|Š:c"Z¥Vi4¹E ŸH_EàŠo‘¿ ¥*;µ0_“›“«Ø¨Ø’‘Y¨NÉ›1HQ”4'W“—_PXTœ¢MKÏÈR©³ÿHQ›¨Xj3õ>µ•Š£â©*‘Š ¶QQÔï©hj=µŠ¡”T8åNêC ¨CÔ_xkx­N;:ùóù…ü!Á¡P˜'F!¨]$­=qcs¸1†…Vú ͬ§t¸ Y8Òé e¥&CÝŠG’‘v2²Ðà‰šLƆz½QG'Ã1tž5ׯK;N·|j¾äõ'ÆRu¦¸¹¨>ÉcF%š†ž=QF4¸®'0&SûÞf99Ä,Çcy},7‹åÃu.R†¥K¼± v÷)¸=s@êý »Ó©‚?†ýÆ'xÕâE!CÏLJ‡~¡I>V²°œ…‡6"ÿd#<Æ`1á±ÌÎãÆ«¦8{qöãøÂQteý­ìAF .OgZ:Îo=Æs×lÓDÇË!ú¦l|píRÿ°p_ŸÕOŸ|?ðŒž*š”.ì× GÈ~XŒJ**÷—™+é<âg 5škêê+jJh¼ö"éçãàÔvºÃëc-?S`4T62â:“©ÎTUSÒ@ï=UhÊa™í¹þÁâ©vÅp‚-ê JqQœL–u.ùøFì‘´Aݔݢ£[JZ ý•7«Î>)KGÏîkÌ+X¿>}åï¢?¿"7Фƒõ•¦ýréh©A¯£CH¬3êH\o45ѵ¢/vu•|K*!¾õ MÛª>Iï9¹«Vi\iªª.lK‹êÊO,h¿u¾ÿÁµœäåÕ uŒx"½Wd1˜ÊÊ*ËK&e…_Xü–ˆª$Åg‘¥ª¦Ô¶¯;¯M_ª~| …ßNzòw@—>5ëÍ>P)O/ˆ*yŸGï¼ÐMƒ4¢iÅ&°ólåwƒ¹,œ%õ×rïy 8\1N‚EÈa‡$íØ´U™ý®WbÚå.n.³ßÍdvõõ„îÞn¹qS>¥,ï3HwHåè¬â$BÖ.ÖßöÆ#B-ÂKaDø-²L.ÒÒØÏ¾ˆE°ú•DhÃ> `Ã…]Êçb<† ´ÅšoÏêBÑø~ ÔQ®‰„ûÂëÿ{¡="èÝhêã:áT}¢X˜Çºõ±ÐC*´ öxjO+º·îšÿ® eÚ­òò« L…¸Ü¤7W=rä¨üá™–cñý®ÝÛé(Qì õÇ;1v Š}›–v®¹“ðówß|òÕmy‡àÝqùQD¥äÖkwúÚÿõç«Uú‹Óîpë†M8„pu JOé(ü¹2†¡Iílœìl®"¼{àà!¼2qàý±™|‚qÞˆ£…z$µÛz¾à:à ˱¯pƒƒñçÙWèÑôÛóˆ…°|n7'‘¥^Œ³( ×~Ëð<ìþd9xÞ½kmë¦[,Ç›˜:±Yoª0Ç…Ë~l{)@sŠ­\ܬV+jŸÅ:·K$¬d6EýÖj4 endstream endobj 2937 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3672 >> stream xœmWytSÕº?!möK¹6F+IŸ‡‹€€¨Å‹D¥`g:ÚBÒ¤c¦fl†_’6S›¦mBçy¢” R+£àˆ¨(8Ösö>õ®}zOß[ïß[ï÷ÖÊ:+ÉÙ{Óïû}¿Í"–,+"¥¸T\¹>IVš/ ý^GE³¨–Q«Ù»iéâï‹ÛÃWñìÁ†ˆ°£¬tDá¯ïÁ}+±ù/›ÅRºzãdeªŠâ¢ª˜GS“üõ±ÇÖýï?›¶nÝS úŸ71»Ä•Å…Ò˜‡™/r±DVV*–Vý-&ŽY-‘Œ)”¨ÊŠ*cò mKË—ˆÄ¼P,).+“ÉcûkÌæ7­gOî/.-¨®Œ¹ãyÌ~ÙÖ˜ø˜$qaµ$¿âÿ¾!B$•Å•íª¨¬ª–+ò•ªƒû‰ ‹’Š“KŽHJscâ"XC$ÉD ‘J¤ˆtây"ƒˆ#2‰]Äb7ñ±‰x‘x‰x‚x™ØBì%â‰}Ä~bÁ"b˜ta„œ8ËŠeZ¶e™›½–mgÿgXnØ?Â[9ÿÂÑrþ¥¢³äNòè]ü»~Y.^þËÝûîþ9¢ bqÅS+¾]Wü“ª¤êÁOÝ–õùÞµÀn§ä9^[ M¦ˆ¶!H2hÓëH .ò£ô&M+Lx ½þZWë(§{$/‰h1‚x:#´èe6ë[á4‰Uè‡Üs;s$ê½{„7Ùž©*6¤Ô‹ÆjókðÜö ;¨<}߯Çh!ýýÃ8 Gýô,Ä«ÿ‘¾W¤“ñ.>F¯¦Ã_ݳãÐáži¹H6_ó!\% å$usRˆúý6ÅÁ¬U\Ûï˜Åƒ8½n»•äJ”xaþ½|îÝ‹“_Ãßá›Òë)g÷\¡Yôj én÷%ºaöÔÂNfýíQÞp‹ûø­wkŠ_^O=þ$ÐÐË ž~&;]š¨ßäA½gD‰o1xy6Èútí¢îçµ9<¶V {=5¹"Ú ÃlÞ«gp`ö£=µΓ¸œ˜ëwz¬Æa»¶Åâ²Çß10*çK«veоCV{Zu¡.AÉ€C`ìÒ© A]WÔ—ñÖWq×áðû¼:ü@¸ÓÐPknl¬ŒvC3ÉípWW7•GoKJK9x3Kt¡d\ÑQ AîYz±Ä×¥Ê{k»uçÉz£ãò6Ù¹ñhkèf Óaè¯ëŒþì ÎU޾2!¢‰wdíš^èLœÿ$¾ÂüÀér HÿÛÀŒ 3{Í ¥ÒP¶‰®à?«Ô'À'€®×)s|®MÖµ‚©.¥KéTm¤³øâ¶:oƒ¼8ÚêkbV½¨AÝ ncW:ަä·–ºµNh·¯µi$3ÿ[ÚÐv¸Éâ š=íÓ ™üÌïœq4(’J0žOº@ñ{¢Î}…ýb÷5jÿ{<µVoÕYen›áæ­ƒšžê‰¼@ëwfÆWÝ=Gƒ]MÍ.Qƒ§Ñ .²¤kút¿4U¸Ñö©Myâj…¶JHnzülî¥ÙãGç/ ¹¾ÍòãÑcŒÿãSÌ+úñ¯x ±ÖÊõ•ZY­È"ÙØ Q‚‹Ç'ðŠÙ½@zÂÏÂÃ÷á?GŠvÉ,}/Nç…#ýCí#6ŸÞ¬AC ^ hA¯¯®X-z•N¡ òe3ª1ðA›Ï5dc’uPãACЮÎþ^ç9ôÖÒ£¹¤^ Áù‘Lßìsºü¾ è^ù-Ód±[À"•¹®¤!ä Cpw¿Íº²€ÿÆÆëŸåYíùš2S¶N 5…× §­ \@N{jóEKíHr³äsÌ¿—áÅ+·ÿðÈþÄÂL…0-ìØ©‰ùësÏÒ‘4;kïÖ¯v÷ C$*] .1ð…ðÍ௽¶¦®ÑRo­¥i„–¶:´0èó»NØ™X ´¨¯®ÃàVcÝÈw˜ü¥í… €¦*^]ª-¯VjÁµvc³Ò¥nR3õT(*KF*fÞý^sF„7Pë|#-Þ‡ „ƒ¨ðAVïglêA¼‘—µ»°2 È{?Çè·³W¿˜ð{EÎj·¬Su}]îs»O=™®(,eäÊöÀ6’¾ïÆÌ~mº}xBØßÔæ"ùÏX °0k–ê¼Í^|Šú·” V¯Ûf%•x4€žoÖ¶1#ŒJ@pÕçûÄIè,D—/ÙéÊNg*9_Z}zxž\Z‹`Vkaöéè¹&u7üJR Ü´t*¼íiÌC;µ|€Õ +ØøïF~d>¼© ÈBÃÔ; Ãf©‹Œ{Õ‚ä¶9Á ä¤ÇX ¢7"ñHYËAf  t8ý }ïµ-xÙ¹©à©1Ñ^„Ya`6ë•¢Â(26ås¼‡ŸþäÓ7Og§‰B9¼‚¥#M°¨u8–—µ=Oº’ oPz^5em¸DâKÓ»ÆÁŠ‘Ò‰œ£ ²Uââ삲]°•¤…=‰Ñ×.bbFH_Çëx-×Ç&/Á%è‘ù¶0ð{¸kÏ…ÆÜ/·qMhÌIð«x–××ÐÑØ×áŒ÷DÏ[#—à=˜ÑN• œÝ2°ž‰¦ƒÃíP¢OL^#Ä‘K»¬Žb}…)¹FPêÿ&›ƒ¡^ò„Û”'Z:‚`·¥6ÑÄì—øQ¢ÓØÊìg$¨ßB¼}ëBülñ‘OìPx¥ctvòß÷ µŽöôfàœÐM–ŠÇö…ª8ÈᾦD×L^ìºSÅX£~G¨†˜fhÖùà#g sv\K_ ÇOr¸éKYÔ-Þ@‹{ßs!o}†<¿P)Ì)/²<ưfâ¿Û?Ä+nG]¿ý3aÿÀq!ùùxJ¸†é‹V»ÏæAÏ1£Ag4¼µF?z©Ùä YÈK¥c9¯¬ªJ&ëªìî¨ê–2½ð¦v¢:HÑÇ‹ƒQWoaí¯«¸PÉ‹±<9§®Ê`PƒJr“ÜѶÇÝG¢ó W]"-’¨òáüm6‡%|$ž/è{tÍr¨$_ÌÈy~süY™!¬â ÑEá]n|ÀÖÚænŽº€™9I35mšŽÆèë¿}™ò.Í¿*zðBþ,œ!ÏÎL]~mFY8.>ÒVÞž@ör˜ðiéØbØè¿»ý÷8•ÊáY Ub]‚Š¡†f›ßî·yAÐíQ3]‰`{}…Aa1jMZЀѥ>ªêÖzjbU©«LWÁË.~ŠqM_Üþÿ%%¹X?ëKF-.²yLz™ÓÉQ¯.K´$gÄq}}\H-êüHa;hgÚr\€ãŽ¡_qÔÙëíõŽzÛè°€•¬­µè…J –ú9¹I ÿ z=Nãö_}ïòÉA·ÀßÔfïÒí§ó´œc-uÌ\4ÕjµzæîɧbQ]¬—šk¥¦ð;H`ýû;Àøää´ØZm !ŽxµŒd/GªÕÅ[¯ ~ߤ÷ÂY’úÙ@-6¾ D.˜˜Vϳn-àøÐ‡`.M>‡;tiêóÔd‰hgè Mr#sF…¥Ù5-pŒÄãìn¯ËÕÛ}¢cÈÙ®"¦çJ$ I!”UùQ’MÓ—IÜŒ†NŒvžò|gY¬ˆ.d.a&S¢™Y$ó£r{©]× Ç¸áå‡Þz.1½<1U¨:_ÜŸ ¹ ÓÆÆ“×˜ûVº’¹oiB:¾gŽzòæ–ê3P$vD*‚TZ§9CËoÞ=䎈¸Ù±‚ þ › jÉ endstream endobj 2921 0 obj << /D [2919 0 R /XYZ 89 721 null] >> endobj 2916 0 obj << /D [2919 0 R /XYZ 90 696.022 null] >> endobj 2917 0 obj << /D [2919 0 R /XYZ 90 370.708 null] >> endobj 2918 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R >> /XObject << /Im18 2905 0 R /Im19 2907 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2940 0 obj << /Length 2545 /Filter /FlateDecode >> stream xÚÕËrã6ò>_¡#U5âààÞœÉ̬·63[WrH¶\”Y\S¤‹¤ì8_¿ÝèIP”שœö"€ºÑè·‚Õý*X}y÷Ãí»Ÿe¼Êü,éêv¿Ê‚• ”ÄÉê¶Xýê}üûÕ¿n?ݬ7" ¼Ô_o’4ð~¹¹¾½þú…€W4Ü®³È»úúå}þøéçëŸhþö«Àû†ßþãÃçDLÆaä‘v ½,Cœw3¸ÚØõ°'"¬õZ$ÞS¹Ó«¼ëLêípú[„Àe$Rïö ™^4½ ò“4³ävÍñ˜×ÅÝ~*Ý.ð'¥«Äâuh ¢×é¼Ý´¡žxeMвgMЪìzší›–Ö{`Ï@ž×aàåu¯ w#ð²Ú„2õƒ$†Ièg ? \28ue}2K2óêü¨­"é]ï Ì”²)K°‹7í›S]¼‡y* æ¹ÈB¥ühY^=ç/ݼ@àý®w'àûîÐ4 ²Ëb_Dé¹ì2¯™³ö½×ºý©éI>€²ýÞõ$¡„g:RÀ D1¼{^Uº€;§A€^Ãe"\¸ŒŠá$ey*»;ØÝ<ëbI5S@Íæì#Id?Š%±€éâ i\´Œêu˜x¿ã‰Y¾ÞÓò2¿"ŒáÊofXerư`”E~ W€­îOmmÔ@Çm ò®^Öiâ½'Ø+–ÊD8Š„Ju®‚ÕO, %‚eã ƒÀYüWi;Íw}7ޔتáéÖ¡ÇÆ%¼"ïsší[X™Êô2Î|!gbýøíæ‡u”ǘFVÍüÔi6´†ÀCÝK^fZ¸ 9|2RióÀ[kÝmkÚZ!‹† Bç`Š-í{n˾×5iÀüùPî4-•>êÄ‚÷ øb)]Œ…XíöIè2XÑõJ=@kõ“PÑžÔýd½‡3¶IûóSßó¾D†_Täÿ†Ó»…'E†”ŸòÙ×p™nÖ´^2JC#WÁ3¶:Gi¨1ÓT˜£›š€[}ÈQžÊ¦åsö´BÁ…„ÿBK¥1fX$$Ћ!u´P279}Nâ!Q®û¶©h­{éz}D7•¡›jµvÄ8±©cµožQ,unÞÅi#dÀ^7˜ònÌÍ­0‡뤳IÖŽÃdØÚ˜cŽ·àuÏæzßÑûm˪ì_ܸ<¬~ýö¤f£{WÞ×yåzHݶ֧[´1aC-áÅí‹]lÉUqª;9ɤÇ;ýØ—MMÊEH<«BIø*›‰³ª¸ÞS¶ÞSj¢úÙCq닃˜Ù€Yª6ˆâù5oƒÔ}dkâ”T6ÄÑXpe2ä¥.è: 5: 2 a4Å‘|™¢)ÂØ=©‰{RS—$GŒ%J'F}’bŸ4-|’² N«S·¨¡EQâãJÑu]~ïDa€R«&ÆCã„Ë éªxG°¡Žœ5¦lÌæ ß)YMÄ}J†‡X°L‰cNMå „ ‡‡œyáAͲdˆ è‚Ç0–ÙNLæFTÄB PFý2vz€fÊ5;‹F/d`µsfºàÆopaPõ_ˆ˜ì |M*ùÙCrÔŠl^ª1j Œ¢†JÈlp³ÅÈBäÀéBä8u‹³ý%#œ ¯ ñÁöÍ„Ÿ˜´cZQ±Ü£ ³€:±š„ŽXÙ\[Ík9ú&Xœ$øÊ&ÃÞn‚:mÄò,\Ä,ºéö1\À8ÓUp‚Ç©û¿ˆXÿšBÍÌÆ¦Y’‡ i¸)”[½)aO™WåšsZqÜhFeDs²§cm¸5Ç÷|¾ÓN!.êZïØAÉ“Œ²»$¦c¡l§Fz8q+´¹­…¨¦Ùhk•îõ›Ü¸ejn‰ò£HÌÛZHi`ãm´³ÌÉ@Eú:áXú* ] "Çô˜H°=U<Èoy9§Á >B×[¿éúÒ—q|Ö”M©¡#õ€2o}3;êcCSm4»œµ)gùiv©ó-•/dò§d$âh‘;&44«FF)WŸ¦,޹ùù"5+?¼µÿ–rÿíjY0€¿´`=ƒÙº‘Üžx©çfÎóC÷ÄË'½Ò½»¢ w‹ e6ô¹«J(}inÆ|‹Je""cqU~¾ýRSר©0Ö(p<±=öαq»†úî„ñßtø²nŒÚ*§Õ•…vN“ÿ«£[ÛÐoè¸ØÊ`—Û6ËØpFîï­çí¦‰‚uߤaÝ…2b^–OZ(›ù.ÿ‰'Ú©3ϱ-¤ñø/Ñ¥¿—aù^á¿Ry&·ÇF¡/Bé²)ÙDm“´]P‰²ÀºŒ|9ºÄvIϪÐÝ!7ßÅ3ú• (üßfðø'kœPØ™1B™eH3¬©5Múò¨iùÑøtȃJO²u\p+XmÊ7Ò™¸c«ï"²µXy¤Ž*º!ÇtºœÀ(5éeä…Åç pPN´0È ú'­eÈÐR ƒåÚÎIxxÇ¥'g‡¸Ñ¶-¦5 ­¬Óþ̓&uÜ‚ô’Ä;S!TôØÕ hQƒÆšÆiÅ/4l²µåo#¨é‰vütûî¿·¼[  endstream endobj 2939 0 obj << /Type /Page /Contents 2940 0 R /Resources 2938 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R >> endobj 2941 0 obj << /D [2939 0 R /XYZ 89 721 null] >> endobj 610 0 obj << /D [2939 0 R /XYZ 90 605.637 null] >> endobj 614 0 obj << /D [2939 0 R /XYZ 90 195.799 null] >> endobj 618 0 obj << /D [2939 0 R /XYZ 90 172.799 null] >> endobj 2942 0 obj << /D [2939 0 R /XYZ 90 126.493 null] >> endobj 2943 0 obj << /D [2939 0 R /XYZ 90 106.688 null] >> endobj 2944 0 obj << /D [2939 0 R /XYZ 90 64.79 null] >> endobj 2938 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2951 0 obj << /Length 1944 /Filter /FlateDecode >> stream xÚåXmÛ6 þ~¿Âßæ+ÉïÃ0àúº°n»Û‡n8(Ž’xKìÌvzí¿)RŽí¸×~¸H”DRÒCò‘…·ó„÷öæÅêæù›4òò OTâ­¶^.¼TdˆboµñÞû/¸ýeõú~±T±ð“`±Œáÿq·º{÷–„·ô³Zä¡ûîíÏÔ}õú÷»—¯©ý¬Ï„ÿ;üüµúñù›X Fh-NÀkO “n{è~½e˜¦J¥·T),iúŸ"þÉÑ"ïý2Ö³PÄþÑtûzƒíÈ/ôá`6ìF8p#K!cçEÙ>|§»ŽÖWúh¾€…õ£Ù Ago²)œt:ଢ4òW{CjšóÁõ–$ݾlIrq1öI£5¡á…ŠýG£uCC›²íGSÞR¦àln)eÇ|º¡àî*³±ÿ±£Þq!}¶]´‰¿kžLsñŸ)ÎÙÀžÂ0÷ïx5ºªâÜ?·f{>H¸Eï°±1èØ‡²`eeÖöÔië#‹áœ›r½P -OÝ—ÅžtºûÔm/Îy´Ãº:|"¼•ý² hS”-wŠºÚ”]YW-nG Ú ìuKºrët—ß™†º½[në‚Ï5F·þ=›–5uŸN,Æë²“b§¨);s Û¥L‚8Oá7òè‚ðõSÄ>‘|áiDÊ¡³Y„©~9œƒ‹ó'ðfAåxÇ™dxƒ]]IE7Ý#÷èÜìhM}Fc£‹Î-34§v Ö!Œñ("8"B@B.}@¼éÃ>LümS±ó%h¯›Íã®\7††ðn–õ¹£q]m¨a†Û®nx-+‰'îØ±‘eáŠÖ'ËvÀ½/t3±6¹7('\>æ ÄzØW ·“á]žšýþPn(ƒÝÕÞ Lݧ+ëÎMå²Us6ÁèÌ_¯ø~¤—Ã}é…1„V$½âxóïMÚAþ±"7ÏïŽJx¯ê›_áÏius–¬s9Pj9Ç蔂Y ð¤¤sxSZü0툾¥mß÷™T_÷rÛ³ ˆŽ]ʬBàUEf“@I Kà!Às M[Ø]Ylg./= ŽLÍ2ZÌGW»šºÅ¡4UGm‹s ~m‰H:žeËÃìú‘˜«[›¬iUÙíI#åP½üùþÅÒí@ïôàZ¿ŸHXr(îU @c×htPÉg²Rkš–"4 HÖÏ\†qEÕœ¦J×v;—½ZÒN*ôakW·“´5¢hã ÛöRpëÌédšŸêÎ\G ê3 ¨îèãé0S‡¥d ‚ËU¼KÌ`Ìx×ሊžÒêÃ#DãƒÁÿH<êa_×ÿB¦3Õä|² Õ8÷‰‰+‘]r´?ÏSÂ@†×L×|=‡ Ç.TEå U'TCL\‰œ€FëÄE’åt&Ð0qì:&ŽS®˜8«ut%ɃXFã¸0ñlÇ3"G(³—ÍÒpȪÄ2®ð{¡á ƒhx6‰•LpšÀ)̳ž]HE&˜ƒÃ çÐ}6Hþß4\ XÈ“ðN`"š”‘Ý[3û"Ï /H5|bf¡=8´oµØƒCÉààP·#%OÕÔðD”ÒÛ3åB‚?R![\2žcð#ày̦”ì™d¨iT„ ì3‚ð¡Ü#Y¹WŒ[’§úWHúÓ)Éøc;ӹ鬣;=ž³f»¶Coëà~¶¸¹O¨â`s‰¢g ­­Döjz¯>K§`”æ+g¡ý’„õ+¥™ágë»eBcú]öÙIÎ,•—¥üáGò‡äy{ÇýzPCÛɈF>¼0à˜·€²òrE˜\G±g{ÑÕñGxäËg&ÑZh›ˆC(söÑ™S.…>ñQ”Ð+6» ;=zpÆ5wƒ„«²" erìjûÒM,ˆq„+/Î8s³ª;7ÊëÐ[d–@07uõÍBBn¢)ñ*>Õ™êdY }h¾à¬ D2xz®±*±Œ?W þÀba¹¨Á¢CwmÖ.BVÊèÀ/$Õæ¢lô±Cö;Ôôq‹!2>Ý–ÑÍ„$éËŸa©Áâ÷ÅR£‚DåOQÐÁò?„!ȃ endstream endobj 2950 0 obj << /Type /Page /Contents 2951 0 R /Resources 2949 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R /Annots [ 2945 0 R ] >> endobj 2946 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./44_home_taurel_tango_manual_ds_writing_r_attribute.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2961 0 R /BBox [0 0 586 297] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2962 0 R >>/Font << /R8 2963 0 R>> >> /Length 1249 /Filter /FlateDecode >> stream xœWM7 ½Ï¯Ð­›«Š"õul€¢—¨³z4œ]7»‰'NlÛþûR3#‰³“5âb^pž)>Q"¿*£A™ü7ýÞ÷ÝOï‚úpêHKÖ©çnø®ÞýÚÑÉ+ë\Ô¤úf rÚXµïŒ·)þœ—í;½øgø´ï»Fâ¥Ök°Œ®:cb$íR–ä9ÎHÂ_ÃŒ4™ùÏÕçÎ&£=C ”ùƒÑ1¹Y°«AÑI ä®cUöãåÁ³?p¤­WÇ]•üL –1Acp•“òÎ!y¯mš¨¼BïØL#U‘óÚ„ 9&qàѹ‹B§=~›g}½J–sèëÖˆ‚¶6Ì1FÁ·AãÉ9~àCãÿÓÏ}¯Þ®ù¤E £U뿺ñ‚ ¤ r|ТZ÷ÝÍÝy÷åËîøûá|8ªÃû»ûó›õÇîÖKIÝBÐÆRë‡îæ¸Û>l¶çóñéýßç]ÆYJ¥’ ?§§óÓáóÏŒS÷ûíé4rzYª[9. Øíþyûïi³ûgwÏ„›ÇÃáSFÿ²æ䬵\+\t¹ZA{Ežlt ˆx¿sY>q3r¢ì ”€4ò l høl…0C‘! 4Š´aY¯)Vg¼Õ†%A`Ž\úÍâŒvÈ(Êǰ8C ‰<4ÌÈSËuØŸiÐìÀÙüŸLâjAÐ_tRùþ²ˆ¹¬ ŸkÌÉ-HÁæß=[RëµYXC®fH‰µ”˜ÂS7Z¶U }Ýz[œ7ú’ ¿à¤r½¢ ¯µBQ¾ûØ#ˆD6KIv;´ 3ò,-Ц¨<ñ«AÑI äzEÁqu@ŠoƒL¤°LɦÈu7ÃL> endobj 2962 0 obj << /Type /ExtGState /OPM 1 >> endobj 2963 0 obj << /BaseFont /RBVKKQ+Times-Roman /FontDescriptor 2964 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 0 0 0 0 0 0 0 0 889 0 0 556 0 0 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 0 500 278 278 500 278 0 500 500 500 0 333 389 278 500 0 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2964 0 obj << /Type /FontDescriptor /FontName /RBVKKQ+Times-Roman /FontBBox [ -70 -218 863 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 129 /MissingWidth 500 /XHeight 460 /CharSet (/A/M/P/S/a/b/c/d/e/h/i/j/k/l/n/o/p/r/s/space/t/u/underscore/w/x/y) /FontFile3 2965 0 R >> endobj 2965 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2961 >> stream xœmVyXSW1$÷•"¶¤©Dl’±ÖZ·ªc«¶v´"Ú¨ˆ€,*‹FC‚²=²°Ü$@H$²È" *"n÷bWÅZ«¶E¿é¦E;Ë}Ìå›oö›oþ˜ùç}ï½{ϽçüÎïüÎa!Ó‹–˜W )^œ /È’M}/¢£XôìiôKì,›øëÄZÎKD\3{: cðƒ³ÃèÖóèà d~Ž`³X¥Îöhy¡º(/'W!žŸ”°ãµ… ý÷ϲիW‹³ÕÿYoçåÈÄó˜—‰T^X ‘)ÞG3»¥Ò¼=⩺0·Xœµw¯dï”Yr–T²_¼1OšWX(/Ï~M¼|éÒe‹™Ç[ò ²•Åâ§ž‹·ÈW‹ãÄ ’¥4«èW‚˜õ®L^XT¬Pª²J³Õ{6ï•ÄçæmÏß/ÍÄb+Ol#¶‰D‘L¤ë‰T"šH#6Kˆb#±ŒxŸø=±‚ˆ%âˆÍÄ:‚ED1ø!„„¸Íz™uhZÈ´ÆiÿbËC8!œe;w:WÂÛÀQr> 'Ÿi}>´+ôûЄNЕáû`¥œ dM$ø»”'÷¶ÓŸDª¸xï¤!Ï3”¥W JQZ¤«¼ _­Wt=ÃA~ …ÎP'€ESr5YŠ\`R<|P'"q''œ®„~zÖEÖ½q´aœÝHÏá×9<¶zHvºµi"l0Á¨K© µ(×Rj´ °ŸD}àì©–†^Hžk“¾/ÂãôšÔ©M{ý ­ÖÐÏ‘H f\zw—T»Ix˜íiê“w¹èd>ïú‡Z­—bάLKQåd‹R3ä›à¿xw bŸh<Ü/ìhcRs• ÿçt˜ °kˆn~žx“¾ÁŸLp•A¿ÆÊ4ŒÞX_«ó1ŠKÇ8æõÞª#8à“v\FÛ98­”ûÕk€ëÉÉÎÕ•®²0v†ø]¦>&éWª™<Ãñ=­éØH‡v²: Õ8ý‘â£WG8@]]+!™cbJ›þ˜ÀtM.«”—­º yÔMe‹ðR é)¬ßI –`žƒ_øršvéXðLŸ( V4› ”Q­*¢d\•xÍ@œs·nŸ?·3Y4…áu$ëA ŸE/B«øék3e±0fvÉ.«™{«FI4Ê5}Buõôï:¸¦ÂjIÞÎì p5‰…7ß@àÑ—W1(ÄwÐ"~ý¾££p¶É½+ú‡Ô2€†–"þò•!ÖLžíFCüCUMÕ‡àxÁs²íÞþQø)Ô+ìÚ3´¢s1M—×T n™<Œ&'c\i¢Öš…Cëƒ_<)]Òátv ¨k;ç.ˆOÅ@¥³ÙÂ_[xÔÖãh ƒé2ô3ðtwÓqH·çĈp€›(ý6˯=<ÉcqÁë$J˺ðV|VñÖ]BtXy†"Óö2AáT¡ÔØŒF‘']¦LÑä~c,åÛLŒ½Ô¶ÕQ Œ=Ó˜[Ÿõ ¢éO"î> >> endobj 2952 0 obj << /D [2950 0 R /XYZ 89 721 null] >> endobj 2953 0 obj << /D [2950 0 R /XYZ 90 690.045 null] >> endobj 2954 0 obj << /D [2950 0 R /XYZ 90 652.023 null] >> endobj 2955 0 obj << /D [2950 0 R /XYZ 90 573.318 null] >> endobj 622 0 obj << /D [2950 0 R /XYZ 90 322.953 null] >> endobj 2956 0 obj << /D [2950 0 R /XYZ 90 274.221 null] >> endobj 2957 0 obj << /D [2950 0 R /XYZ 90 254.415 null] >> endobj 2958 0 obj << /D [2950 0 R /XYZ 90 232.443 null] >> endobj 2959 0 obj << /D [2950 0 R /XYZ 90 190.535 null] >> endobj 2960 0 obj << /D [2950 0 R /XYZ 90 124.846 null] >> endobj 2949 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /XObject << /Im20 2946 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2969 0 obj << /Length 1531 /Filter /FlateDecode >> stream xÚWK›H¾Ï¯àˆ¥€»yrKæ‘=$Ù‰•’UÄ@{ŒÆp&þ÷[ÕU ´6‘%÷«ºê«w#œ'G8ï®Þ®¯–w«ÈÉü, g½q2á¬Dê‹(vÖ¥óÕ½þëÍÇõíàbá&þ‹á~y¸_ß¿G›ohX/²Ð}óþÝZÞÜ~¾¿¾¥ù'¸Ÿ ÷3 ÿ®ÿ^ÞÅÁD`„ÒâàhyRH$ºŒÐñ ¬àRHdë­Zxa”ºß„žŽ­Ò—$\NûäÐä®ÕT‰Û\q;s«Ž˜ä4”m¾±ûRÕO´Ñlhì·ªÓò2w¿®ê·MIË"ßí˜I§~U]Àe°R""÷™5-æ}ßV‹@¸Çž¡ç»…î þå'fòÒV½Êwê¬Wá€Lm4Ùq×£ ƒ'¥ŸÅ줪û8šEàUIFß3Jœ£ž8Ú1ý¬JUÈX®·æpzáíÍl¶ª?¶5/úö¨|Ëηkö‰t²ÐO„tÂ,ó“@:ÅþêÇ•¿Ò‡<è-CÎËû=ß4WÿÀÏp54óô&LuD[±F‰¦ÒÒŒ,vWé á¨Ž_“1¾ õY[Û_¸5:ØÒÑŒHJ{%@¹ž I°¾ N|鯞BP#çR‘[ŠAR‹Vþ‰0Õ{›6ß+mü¦}¦<y£š©Ÿ¤1¾dAŸáÜ+rRh—·§™L´9`ZGZ0@‹4´ŸVÂõ ¥ÚšÕþ°S{U÷y_5f¯£QíUYê茤[ñiÎ\Ú¦PSbNž_j€Û3±2Ã2^ta¼K=ãØ—qh®cˆ•û‰ô$Õ ü {Ýõy ÈtÒaû"±SKDX"hÒ›p&mÓáÉÔt°•†E‘×të‘©er@¶‚1'«ÐÂŦîÛfÇ"N]¯ö:µc „¢Û0¼RmN†#ëõjÂ9˜ž)2Søa(Gø¸Ð•4}Þö7_ª~K3PîÒ2Œ| ÉŽ0 èFf¼ô]ù+)Í•—mUl§ÀèÕ•ب&L›†«| fYØÏ∻Ih» ×uÈ,õ36KB4P/LB‚£œÍòç‘ÍÎ,kÂZñ/½S{ì´ì—¿»<1ˆÂ+Ø‚ ëŒ-hB…­%ÓNÇÝ?wº®LÆ¿¸ ÿêÊo*Ù¦1}H7QÜ*šý>¯ËÙšéÈ4õ ZÖÏúQµÏô‚¥”lû9RS(t§¡v°m©ë1퀘UÀÛ5£-ñœ¼«÷¦ ZŽIç|f_4ÑJ:Îiý?8§Ž°Â -B<—ˆÇŸït4c jÁyǹù4ÓbŠ]Þu¿m ÷ O$V¥Ž?˜ö 6]epeE-žN£ÖcE^â˪ª«®ou÷À(b¥3¼ôË %oy²¸“2zZǾÙsl0§¹hϹA¥V Gª8³ýuVÎÁ­F‰-%‚–²ÞuÍÀ“ærúvÓÇáá@7½Dr¯Ñ·{šè~#ØéÍ©É&BNÏnͼ/zùÀ+\jr Y–×Éòx6–ú¹úáäàër oÔo¥íñÑws ÙV@ÝæøÒ!Xü:ÝUÏ:Øù}WãÙ‰ Êžb̪^ÈêüˆÖcJVÝ|u[­üd•rÅâD.GG/Ï9žWÛÙÃ’{yRÈ X]G-PlÀ¡OÈLLûD ¸}â¾öN¦’q=•Œë!t‰¸+à%yEÌi,¶ù¡§R7ÿÙ†Dækº¹ lÄsà yJ‹ï.®,PPgód¨²^•ˆ¿”²Ø8ff‡>ƒtí€Õã‰F ö,Âdü>^ºþððvÆú… Ëó/ Ü¢àòjÇn‡mí œœ—ØUf¸jÑhÉ;W Lt÷ÛV™Ü°ê$mqeû9½ñžù€¼ȱhýÙ)_Ûþ–‰…gIô >êÎ?ècèo7áAéwÁlRÂ'é²ap endstream endobj 2968 0 obj << /Type /Page /Contents 2969 0 R /Resources 2967 0 R /MediaBox [0 0 612 792] /Parent 2903 0 R /Annots [ 2947 0 R 2966 0 R ] >> endobj 2948 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./45_home_taurel_tango_manual_ds_writing_w_attribute.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2972 0 R /BBox [0 0 594 362] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2973 0 R >>/Font << /R8 2974 0 R>> >> /Length 1328 /Filter /FlateDecode >> stream xœXMo7½ï¯Ø£]À,9ü>¶@Q @*ÐCQŠ­ÆNWQ")pûïû¸»$g×Ò6 |ðô83¾ý¹•Bµ2ýŸ»æû7¾}lŒðdȶ/Mÿ{ûæçF©èEt­¦h…iwP„¤¶kÞ6ŸÁ׎$~N˺ÆFþô?uÍS6¬uZ(JÖ¤öB›‚t!)ET@ʪDIå… ,ª¹¯äÿ÷ïÚ6^8P25A^„8ÙÒêl°”@Þ6V9—6@^jA±%rÂ;$ÌYÀ¦=lI9˜ nFšq”'áÌYŽV„cq°c±«l‡ZƒMùI5æ<){Ó*b·ê|؃,ïqâjø>~<ìÚ×Q€#ô±þ«ä¥Ú¥)dB)‚íz×üqóö´ýôi{øuÚÚý»Û‡Óí] à„¡›ßöÇçÓóþã§Ó¡}è6ÇãíŸë_GB§£»£€˜¬o×Íͦ{Ùü{¼ßþ³}ørÚ>Þ?í÷ß®?4?­qˆ–|„¨q@:¯pˆ‘.¤¬öG6bÈ¢‚ÆRjÄ_£r+I máÁÀFª‹¢2¤cHðÂê„”UKH "ûÜWQ¹Ò ÈJMAȘ¾ñ¯Î»à$òõÉPÆš¡ 6SiP4é‚m”U ˆö8R j0SN¶<&#o=Sw%=uqJƹ`/;É\¯ ’…fÂŽΧώ­YB†##i‚  e´[zŸ ©OÄ*в’k¢†yÙ~áë“  n4t5'¢]ë…ñé*âºQäU‹’ç4ì`—rÂ)–gŠÈÔ]IM]œRq&ØËNJ ß Rh·š'cDX2´5÷¸ˆŒq¦û:L8Åò<#•%£,ž$£{ÙI ÷Oj¾òQ×eHë "Mºy9«6á‚ gÂù «6ô‚¤[N_7PÄõ‹Ô’ ×V²&7QAºŠ(hÞ'¤¬Z@´DO“Žípî«¶jC&¥3SSèNÞOÒ³:ìE'%ë[µr^ r¬Ug¤cˆ¦4RtlÕ2vÑ|´Ý+_µC[¯*È­º.æ­š{ÙIäze(ëmЧ*##UµÖ³ô/!ùЪªç¾^]â™Z•ÁKbu6Ø‹NJ ß  ådЇ)cD˜2‘ ÃÓ¿„äCS˜¤Õ”“-Ï•1R™2Êâ‰2X°—ä@®¿Ä•MWu`·xF:†X'B`7æ22\³uèœûzu‘gj½Éùĺ:ì‚“kÙÎ+ñ³£L/ÆòhQ*L†krF cÙp͆Ž2oãDzp9¡Ø™%(Yó)¤Àk«'õpñ¤gžq1ÝÓBb°¥ °vxÇ”GìHªÏZK†ëzEV“F­y¥Xyd¤–‡FŽãDƒ‹È¨\º}æ¾^]â™ZË£.æåÁƒ½è¤r}y8hB/®±2RËÃÁ±š<1–‘A¹ÎFt|Ç9Åò¬qfj-º˜— ö²“›UJ/ʈ7ÈÜ8>f OVt\^E’•S[!â¡ygë>½B[ЩÕ8 $µjmÄЀ9K[ ‡(Ú^ÖW½Ê1và>ÀìÓÔªÒ«üæùx¿éºýËö1½ QŸ¨…~±Ö&ÒkŒü8çT•F¢FÃÀ<÷ÀóNã%ЊîT¤$»Ä}9<Ÿ¶Ü%jEjô·òcñ:ÚÀ”bÇóÉb´Íétx~÷e°6FuG]ž»êi÷O›ÃãËæ°-ÿ-X5ÿþ¿áç endstream endobj 2972 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152429+01'00') /ModDate (D:20160114152429+01'00') /Title (w_attribute.fig) /Creator (fig2dev Version 3.2 Patchlevel 5d) >> endobj 2973 0 obj << /Type /ExtGState /OPM 1 >> endobj 2974 0 obj << /BaseFont /RBVKKQ+Times-Roman /FontDescriptor 2975 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 0 0 0 0 0 0 0 0 889 0 0 556 0 0 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 0 500 278 278 500 278 0 500 500 500 0 333 389 278 500 0 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2975 0 obj << /Type /FontDescriptor /FontName /RBVKKQ+Times-Roman /FontBBox [ -70 -218 863 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 129 /MissingWidth 500 /XHeight 460 /CharSet (/A/M/P/S/a/b/c/d/e/h/i/j/k/l/n/o/p/r/s/space/t/u/underscore/w/x/y) /FontFile3 2976 0 R >> endobj 2976 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2961 >> stream xœmVyXSW1$÷•"¶¤©Dl’±ÖZ·ªc«¶v´"Ú¨ˆ€,*‹FC‚²=²°Ü$@H$²È" *"n÷bWÅZ«¶E¿é¦E;Ë}Ìå›oö›oþ˜ùç}ï½{ϽçüÎïüÎa!Ó‹–˜W )^œ /È’M}/¢£XôìiôKì,›øëÄZÎKD\3{: cðƒ³ÃèÖóèà d~Ž`³X¥Îöhy¡º(/'W!žŸ”°ãµ… ý÷ϲիW‹³ÕÿYoçåÈÄó˜—‰T^X ‘)ÞG3»¥Ò¼=⩺0·Xœµw¯dï”Yr–T²_¼1OšWX(/Ï~M¼|éÒe‹™Ç[ò ²•Åâ§ž‹·ÈW‹ãÄ ’¥4«èW‚˜õ®L^XT¬Pª²J³Õ{6ï•ÄçæmÏß/ÍÄb+Ol#¶‰D‘L¤ë‰T"šH#6Kˆb#±ŒxŸø=±‚ˆ%âˆÍÄ:‚ED1ø!„„¸Íz™uhZÈ´ÆiÿbËC8!œe;w:WÂÛÀQr> 'Ÿi}>´+ôûЄNЕáû`¥œ dM$ø»”'÷¶ÓŸDª¸xï¤!Ï3”¥W JQZ¤«¼ _­Wt=ÃA~ …ÎP'€ESr5YŠ\`R<|P'"q''œ®„~zÖEÖ½q´aœÝHÏá×9<¶zHvºµi"l0Á¨K© µ(×Rj´ °ŸD}àì©–†^Hžk“¾/ÂãôšÔ©M{ý ­ÖÐÏ‘H f\zw—T»Ix˜íiê“w¹èd>ïú‡Z­—bάLKQåd‹R3ä›à¿xw bŸh<Ü/ìhcRs• ÿçt˜ °kˆn~žx“¾ÁŸLp•A¿ÆÊ4ŒÞX_«ó1ŠKÇ8æõÞª#8à“v\FÛ98­”ûÕk€ëÉÉÎÕ•®²0v†ø]¦>&éWª™<Ãñ=­éØH‡v²: Õ8ý‘â£WG8@]]+!™cbJ›þ˜ÀtM.«”—­º yÔMe‹ðR é)¬ßI –`žƒ_øršvéXðLŸ( V4› ”Q­*¢d\•xÍ@œs·nŸ?·3Y4…áu$ëA ŸE/B«øék3e±0fvÉ.«™{«FI4Ê5}Buõôï:¸¦ÂjIÞÎì p5‰…7ß@àÑ—W1(ÄwÐ"~ý¾££p¶É½+ú‡Ô2€†–"þò•!ÖLžíFCüCUMÕ‡àxÁs²íÞþQø)Ô+ìÚ3´¢s1M—×T n™<Œ&'c\i¢Öš…Cëƒ_<)]Òátv ¨k;ç.ˆOÅ@¥³ÙÂ_[xÔÖãh ƒé2ô3ðtwÓqH·çĈp€›(ý6˯=<ÉcqÁë$J˺ðV|VñÖ]BtXy†"Óö2AáT¡ÔØŒF‘']¦LÑä~c,åÛLŒ½Ô¶ÕQ Œ=Ó˜[Ÿõ ¢éO"î> >> endobj 2966 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.736 88.124 365.126 99.028] /A << /S /GoTo /D (subsubsection.6.1.7.1) >> >> endobj 2970 0 obj << /D [2968 0 R /XYZ 89 721 null] >> endobj 2971 0 obj << /D [2968 0 R /XYZ 90 658.996 null] >> endobj 626 0 obj << /D [2968 0 R /XYZ 90 363.132 null] >> endobj 630 0 obj << /D [2968 0 R /XYZ 90 342.317 null] >> endobj 634 0 obj << /D [2968 0 R /XYZ 90 197.529 null] >> endobj 2967 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /XObject << /Im21 2948 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2982 0 obj << /Length 1181 /Filter /FlateDecode >> stream xÚÅW]s›8}ϯàOÇT„¡oYÇÍf7ÓfcÒÎ4íì`ZŒ¼B´Í¿ß+]aCê‰;N3}’®Î=÷S‚8+‡8ç'¤'/_OB'ñ’Èœté$Ä™Ø#!sÒ¹u§ž^¥³ëÑØgļјEÄ}}‘^¼9ÇÅSÒQ¸§oÎßâçÙìÝÅt†ó9œ‰û†Oé_/_3¿§0ÔÚXtŒ>J|-tB,ÃntÆAB½ˆÆÎØŸÀáÅ?ú>È;·cFˆ{Í•I5çòëˆ2—Ë¡qÆ(øìq”Z.ï§UÖ4Ç?ã#Ÿ¹_ËœïLjÇø»¬ª£”ŸÅ¥X­Êz•jçgrDcwņä#adúâ~4;/™oQW÷ @Ò{Í×Bƒ!âo¡pÎÕóè~Vï%Ý WÏmîü7©Ubcõ>·c纖•®f]‰ªâÅ¡ª=bk,à®ÚæØ~»ø¬A´ÝÇ8ŠñÂ7›‡+.KQ™-§˜¢Óí)†Ì0Ej5oM.Ë*E=½ËêÕq!þ°þïWC^Šü˯‹›úg@¶ð!Hó”ÐP»€£‘ñКôŽ7k7ëuV ~}Ó·Ÿ™-ìþ²­ª{œ\;}Á ü¬2Õ5€²ÆQÝ•¨y»†Hy† ½$ õf͘÷z§Ì´Ö86µ’¦!à·X|æ¹¾Gbææú]À+˜Õ81°)¶•v à‡Æ‡¯Ä«W7ª´m(ï~Œc/е(g|{!ìñ%!üa%/RK=´ð0 À ûlµ[™•ëMÅÑh]q —1|¡ /•Ü‚`#ìzÛöØ2ªt|ßF!p;¥Ö¡Û%†,µ„¬1:1Ì`hàff&¡ôª© jÒ_r\+í ý@ëfÝV ?lun¿Œ9t›è€Òy7&3èd˜üšA¿ÿhAl›ž.Ü’ˆ]Ýf2“ª¨Jàh›ÞÞÂNËúdu®qUÈ6C0Ø’­ÝËpx¤Ñ3f mška—D¨aiѪjp—0›ó½^ø w ó¸g$^dý W´u1¼Vom‡$Ð?åÊÁ‰i¢nü°y~òöþÎÏÒ“ÿ(:2Ä endstream endobj 2981 0 obj << /Type /Page /Contents 2982 0 R /Resources 2980 0 R /MediaBox [0 0 612 792] /Parent 2984 0 R /Annots [ 2977 0 R 2978 0 R ] >> endobj 2977 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.116 164.914 174.034 173.761] /A << /S /GoTo /D (subsection.6.1.3) >> >> endobj 2978 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [156.51 71.888 163.484 80.735] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 2983 0 obj << /D [2981 0 R /XYZ 89 721 null] >> endobj 638 0 obj << /D [2981 0 R /XYZ 90 137.328 null] >> endobj 642 0 obj << /D [2981 0 R /XYZ 90 118.782 null] >> endobj 2980 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 2989 0 obj << /Length 1310 /Filter /FlateDecode >> stream xÚ•WßSÛ8~Ï_áGgæ"$Ù’mÞ @›¹ÂA®} “(ÁWÇ¢¶ Óþõ·²$G6†£ÓéDÖ®¤ýñí· v>ÌNW³£‹$2”qʃÕ6ÈpàᘫMp.?¹^ßÌ”á£ù‚q~¾¹\]~ü`6OÌÏjžEáÉÇWæóìüÓåòܬoá|ŠÃOðóuõÇÑ£Þƒ±~q0§{àH+ͰµÐýž¯f8 ¨ œp8Éãkû݈úiNX(êIç!GØ{}A"óü"¢(Km¦8"(A¢spãp)+%*ÕLÄ<ÓLj ùçyŒÃB=•1V5ºÌ›æ7³þ![»™[½/ÓjcÖÇ»ƒEÁ‹#°4Cqd üB)ªÝ-z«rU¬Í={¡¤½SIû`-r%Žj¡êÂÄ­ •3Ö…°¨v`i“÷ÿе>‡;{oÛógѬEYæ•-"Šâ°UEY¨æÃØØIXXßæeaD;¡Øa>:ÓôÂËnwF¶ê±UV©Î×V­ôœ+!êc“²pyus:‡ß³¯¿À E1ÏÀG‚2fcþ( @A­3Üå1 ½0vSÆGpLkyQ5*¯Œ”‡U¾ö²Þ<}ʦ‚¿8~}yf4rîe-€K"š…×¥ÈÑ·u‡Lö“ðΦHWg½³ez£“¦£ì…_»0àaŒÀV³È§*²,+–[«V–=Ä«Õãà€Õ ï²ð¤½Šö¸Ç|ñ˜+Ȫ…z¡ýØC©ÛLxçÎn©°íÊ—aË ‘OmiŒ’8sä s)ꊪPúü'S$ž¡GîŒSò‚0E Ž˜°üzTµWüÈ·W"¸Ó‘Cu[½áÃ(bä ç(eÑûÒ…_2 üØþk†Œ:æ«§Ž´ê ×uõ¤}޽!NºÚ‰¹ÿlÐêßòNœ†¹2B]îÊœSÏÚ iö{C3Uc4ºZ¡Éù‹§FLЇÂÐÆÖÖ SS³«Ó.+1E[©¯IÆn$}_鄆Î|u +«hï"Nx¨=­·5[w¬ Ã»Ö…æ]ËR#Oó$H®*§ñh-Ùºûs¥cœ@c©¬a4'½^éá,¯vòøøoà·D±o5æecëñ^ølµAƒYgSç:dÏ=õ”ú‹³¡7kFáÝ ¥+ÍÌmÐÌ¢ë n”⨜°-$î³…tövÍ©}t ß[¡Ãýå´zx§ÓÓ×âÑóàV–¥Ô×>ÇE1McMQÕÒë>nÎó»ÿ!—ýó¯ÃÇ¢bÕϓυ멺ŸyYüw:o´ÑŸW®Ü`}£Ãà xZËo{uÆ£Ó^Bow”k‹bÔ4Cœ’‰&8Õü@—¥Nן`ß«a|{ˆ¬ˆæþ#‡ Ž‡ðÆü8¤轤ïe8ÙÐFÙ§Ž¶(õgˆ¥%ØíyZ6ƒ={„ Ñ ‚+ƒp4®øç†ã HzáF°Ûy¬‰ z"ŽFïôü4®/éáêù¡X?X½¶îk¨Pî¯ hGªn׺/½rïÕÿäíh endstream endobj 2988 0 obj << /Type /Page /Contents 2989 0 R /Resources 2987 0 R /MediaBox [0 0 612 792] /Parent 2984 0 R /Annots [ 2979 0 R 2986 0 R ] >> endobj 2985 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./46_home_taurel_tango_manual_ds_writing_complete_server.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 2995 0 R /BBox [0 0 745 416] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 2996 0 R >>/Font << /R8 2997 0 R>> >> /Length 797 /Filter /FlateDecode >> stream xœÝTMÛ6½óWðVopÈáWnMR-zIV9eƒÀõ*¶›Ønú÷ûHI´VØ,k ƒ@òÍðÍ›yü¢ ±6åÿ›½zö&êû“ª»úx¯ÄO.h6ɽŸí„L^ gK¡,} ÄXÇH†Ûz£„BÒ1&˜–à %`Üac†€1³«ã òàG ãùDp _”°QVï´‹³è÷¨óN E+ÖëÿÆÊßüöcVþIÝ ô±æñ4¦hœfg¥¬£ ”“ècpKá˜)[¨à½É©¦P_º¿Í^¿è0K Tȹdu÷Q 3V(>¡ÉÝíÕê——»õétÕý­~íÔkÅ)1«9ÅDéÔ&u)“ñ æ8 en;…šu™ÉŠæà-™” œÚr§¬7BwÄàIJÐ2dWe[âö—‘åw+a-f0mEÈG©J¼ê¿n7ýïûÏ»¦F»Ç;LGžßÜÞ(gs"7×Åx$›(ûYª¶3KÕšþ”üè"ÿ4sù%²Gm3ù%‹%7W·QhXF XâfägX:ÛÀ2¤ÐSwgŠ¥05ÞczòP‹Ëˆ÷y⇠É7lÈbötÂðEÅò UÁÖXKÑkgØ„Ç%l _çT&x Òvª„lMaüdªj©¼XÑ©&Ë> endobj 2996 0 obj << /Type /ExtGState /OPM 1 >> endobj 2997 0 obj << /BaseFont /WCHSHC+Times-Roman /FontDescriptor 2998 0 R /Type /Font /FirstChar 32 /LastChar 118 /Widths [ 250 0 0 0 0 0 0 0 333 333 0 0 0 0 0 0 0 500 0 0 0 0 0 0 0 0 278 0 0 0 0 0 0 722 0 667 722 0 0 0 0 333 0 0 0 0 0 0 0 0 0 556 611 722 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 500 500 278 0 0 278 778 500 500 500 0 333 389 278 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 2998 0 obj << /Type /FontDescriptor /FontName /WCHSHC+Times-Roman /FontBBox [ 0 -218 775 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 116 /MissingWidth 500 /XHeight 460 /CharSet (/A/C/D/I/S/T/U/a/b/c/colon/d/e/g/h/i/l/m/n/o/one/p/parenleft/parenright/r/s/space/t/u/underscore/v) /FontFile3 2999 0 R >> endobj 2999 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3309 >> stream xœeVyTS׺?1$g;Ñ{Is%Ež­C«uª¶ÐÚªµV´2OZ‰ÌÄL&H ‰À’@€D “ "*¥*Zm½·Öyh/únû:ÞÞkë[û°ï­wÒ¾·Þw­³ö:çìýíoûû}¿ïÇ"üæ,kQŒD&Î{5J!K“û¾×RA,j鳸4©øhð.‰T¢T* ƒW‡½¼iƯ2ÖýYzA^ðo'Þ¯ ŽŽgHÓrÿu† ѹ"Lž›—_°§0-ýp†83K+•¥l ~sõ˱œø€8@¼DD+ˆh"†ˆ%âˆWˆxâ]"Œ'v»ˆ÷ˆ=ÄûÄfb ñ:±ØOl'DÌ'ÁÌu~„˜¸Çz‘Õ4/h^ügl`ÿì—âçò£9­œYn$÷¹q‘=œ¯™uAÈ‚‚…+¾¾Ð°Ð¸pbá/ £*üg€'ŒRÿæaÍÆ¹ùZ Ywèêz`—Θ+ÝK¯,Õ$W Šq’›L.jô:-Mu¢ <Ÿƒ]ÜÑ5N¥5tÈU—ÇU¡bl#çJp“Ø‹íåøSà¢^¸Èz4ƒÃgØÍÔr~½¥¡ÚÈk×&‰èj¢ôº„cH‹³\dB­Ö ƒŸ$Ïisö:ß!Ý#¢Å$D”¨}‹2\dR]©Î#¬"¿O¹´ãT½w·ð!i¬IRIô1ãÑà¥6yYÝßà¦oØØB¥òé?mXC é ïVâðãb!^²þúyQ‰‚?se ½Œæ|¸{{Æ‘Ž‘B‘bJóÜD?œ½vSè?»^7Ný2Âb‚aÏT¿ r ¹¦BMi”Ö¢­OjN´„P‘î‹Ù¹O¼èy°®gËGQŸ¼ÿ­øgÀøyâê—HÕº#|,íIŽ9/ý0á=ßáùxÅôTááaßQ—Âý>b" e-êV–ú(ÿOîÎà‚'Kxf;µŒo¯¶‚ÐI«á h.‹„x½þ€ ñVª±™ä}ØJn¯.qÀ§o$²; c€ð‚o±^ÿ°óëW¢SrcSD÷ISMlaVIŒZ€_ÙÎï¹48qçü6Ñì¤ía£{„>X¸‹‡¨ÇCÅî€_ŸR\ÌZ«þ³øVZ²ÍŒxÒbe3|À`g{Ié ILºÉP‹¦ n#ê ·›gj‘›ž,&›z-ÌYuj«‡Eå0·@‹´Ü¾ —ŠÁPi8fXM;W`»©©¢ ìhuX,ÈE'hÉáJ«aâ%¼ˆ ¬1YŒ–òzU}y=ÔƒµÑ5„ŸÇw»?¯·öX ÓQ—©ÀŽ€KÅ«¿\Â;Cíÿ3_­+5k囯E8ž„)s·¶£`0Õ}Ы;’"ò=EíÇ=mµUuUVQ¥½ÊVÔÕ×6r¾K+ÜOÒëö©ËSÅE: d#^BÄxÊÕñÑãSW…¼ÆøºÖÂÑ “pÜ90ÌLÑëÿÊ©¹¬°4O§(+”¥8yZTK•ÑA¼xÜwLí/ü”ucý_}›o®IÓ*Ë–äå Y_] V@#ö²4Ñ\3)}œý>Åóð‹ø¹m߯Ú™™T$Œó;uvpêÁäÛ´?ÍNÞÿa{§Ðý-ŠÓÍê¼Ï¦–ã üä™yQ€6ì}„É_.Þür°Q¤AT_`S´ªŽƒàD›»ýÒγo$%e¦‹S»a+¢ÿôpfŸiîvu¸»z®üvæ)h¦xY]OpÑ ÿdàãUSœfRUU €2ˤQŸ1õ˜¬Î2ìU 4¤­ºl€†ì†t½÷)‡ö ×Ñz9ýüÝÍxÞ¥aÏÙ“¢½ „üÀh,5èUE¹9 ˜Gø9Ì9çÞÇçƉ|aÝÀò>L²¨µ8„Ÿ¼-U¾¢ µ[>­6öW^Eø*·üº¡;·O6xèx<$ÂA•Xr0]¡ˆÞÚ‚Éî^ÁĘ~€×òN]…«Ð¡hÜü+˧ñk¼¤gŸªó²¼_`Íý./›Ê¦ù§Þ!‹˜~Pd-°*”u9€ÖíÛÑ%þs¶¨X¥R›ÌÙò’"(‚BgéhQx¼2Ž ¸)?Ü}pblJ8ÜÛÒÃpíàØ ͯŒ«ÉµC3xúºlö*k•Ü•Uõ0#®Þ®~¯k&¡ÛÜ®ëC´qî~¿ñ‘é< ÿè/ɌܖAs^‹ìo·6ŽMŠêðwü+Þ‰ÞjY³°5Ëy2P´<ëÐi×þÞ ƒ.°nÏàýLÊ6âùc=-§MvfîÑI$ì6”Dš~ïб &Ü@8™|–váÍiyâiÒl‘”æ–GkJ4k«-Pè´­†£ePá¬i¬¶ƒ ã7â×’fÐïò ƒ‹ÜSWÞ·Æ$JÀ…|e~¾BÑ–ïínoëöæ·Ë$|¬,ðPô¨Äpó Öýs o)=Â/äË×ëÕ`u­Ú†xýMGŽØŽ¥BŠ:[ž%U¥A<¼5ýÜO¥wŠí%u…‡ÞK<ô‹Ø?Q˜Ïí¡³8m\^„»ÚÙä r@Ë1·‘ÙI;„ɯþòUÌu:ð¦hùå´q¸€.Ž _;3Vœ9 ì=Ú”Ó|u2dŒÁMý}Œ…­ 7Zg þ\ ¯ëõ!f†Ï0ôX«kôѣ퉹Цj§ç¡® ¿Ã™»Ê5Ñïp:¸˜ÕîÆ~€˜f͈”Y7ë×§ø¿ÆÙ¦œ|xêlþª!Um1ùÀÔ\«˜†Ì$Ò(ÖÈ”É{¥Û!’:”gU}Æ!ŸZ¸MÂ-‡ã‘•±dš¶É¡‡w}¤w|ŠßÁ¬»ŸŸvŒÙ'àþï¹cý}†ížeó빎jg5SÀ} :Fä«+‰03‰Ò»ÈˆÚÒ¸ˆ¨ïÉc5ñj±a—Zà?ëf¿lŠõdGø¶›‘„›Ož°k’Et½omt³G®‹Œ«Ñ:àÂ$ÔØ¬ÖÎöÓ-€ÆÛ²lÊHˆÖë£|¸Èw‘QÕÚ¸†pÙsº¿uÐt«2DDg2³¼<ÒÈ,R¸ÈœYMI+œàt/ÈøäÈ„œÈX¡jZÒ ) Ð…D »ŒšL(fÔ¤Ö§&é?N²|#r®"‘ü½^>nºéaaÉ6gPE¿·£#uŽÚÚšVkKm ãvíQÑ\" Ùåùš2m™®"ÍP·‹ÜZ­i€sˆú‰ôÇæ.õ˜«1›…—R)|YnŽTÞ™ÛÝ{¢³»7ç„LDÓ~ÿò鬳/yXçïçï;’e9G…oÎZô| yC/ÿmÅhò‰‚©£ÎæÀ·>U (ïæýEþÏ¿êºæ½Ö3xë2úßMpòö0½“ç\ω¡‰›ÿ>ðÀó?ä§×ž¦ŸËi‹ï+Õ>ŠèÊònïxϱ VÁ‹%!ÊýŠYfX$ò/òPqãáö,x¼°Ç¶hÑãÖE‹ âËÅ endstream endobj 2979 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [503.705 303.082 510.679 311.929] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 2986 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [447.117 161.023 461.563 171.926] /A << /S /GoTo /D (figure.caption.8) >> >> endobj 2990 0 obj << /D [2988 0 R /XYZ 89 721 null] >> endobj 2991 0 obj << /D [2988 0 R /XYZ 90 696.022 null] >> endobj 646 0 obj << /D [2988 0 R /XYZ 90 365.212 null] >> endobj 650 0 obj << /D [2988 0 R /XYZ 90 218.622 null] >> endobj 654 0 obj << /D [2988 0 R /XYZ 90 147.559 null] >> endobj 2992 0 obj << /D [2988 0 R /XYZ 90 113.306 null] >> endobj 2993 0 obj << /D [2988 0 R /XYZ 90 93.625 null] >> endobj 2994 0 obj << /D [2988 0 R /XYZ 90 70.082 null] >> endobj 2987 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im22 2985 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3002 0 obj << /Length 2953 /Filter /FlateDecode >> stream xÚµ[KsÛ8¾ûWèH׬<ùÈÍqœÙlÍc7q2‡ÌÔ-Ñ1w)RCR‰ýï·‰”(Q\h.‚@³û#¾Fw”éìëŒÎ~¼zsõê]$g IBÎîg E4&TªÙýrö%¸ýûÍ?ïï>\Ϲ¢AH®ç*¤ÁoÞß¿ÿåGÓyc.÷׉n~ùñWsûöîóûÛ;ÓþÏÇ4ø —?îÿñê⃭©àh{ŒJº¢¡»ÎæBqK1›óF<'=éÙ—¹¢4¸M‹"[^Ï‹ƒö)³VEǪ’$R‘3º(Ò¦ùó1]´Uý2€Q…„'ÊI¯²ö©²Ú«G¼FÚŠîxû1«¿]3dµ•xøw¶hqâ˜îŸòÆ<ÐU²Ú4­i-ê,m3#ïÐ{ƒÙœQJbWFeùy~~¾Eô0ÓByÙ´i¹ÈÌÝcUcƒUØ£abc™]s|Ëè:mÛ¬.­–ÕºÈVYÙ¦m^•FE¶zÈ–KœTcgD_³›„Nû ×uµÈšf»9„2¦¯‰Œ-ÁÇK”áW*s¾å·Z­Òry‚áHhtVdt²HÊœ ¼13o|BmH‰b[µè,ÙbwÓ=Ú³ÆÜ¬k;™Õ¦)^¬€vŒ%¸O$¸Qf9xŽñX0ýyÖèÃNc:ÖhniÚme®Yºx2­…¸ L2“!¡‘š6#Œ°p%¡©ÜB«³¶Î ^í@vø±®V“~yhì"ŽžN#Â…êÏÀ2mÓ‡´Éö]M«—s²Ìºšô´ß0t¥ykB™YRÐÈKpª¼üjîêì¯MÖX™ïyûdZG¦ ŒÇñÖ9q©dõŸõ¦ü* l(aìcó64ÇÖ– ĸüZ½~ý©Í Ó©ŒÅæˆ!GÍ0 aQ<ˆKcÞ5ÆÜ=/ž@ÛöUqFMë!k¿gYé ä0L—nÀ«]3ŠDR ö^ âç<ÌXíÚb‰²¶°µµ…7ÆVcn´1–„Ý£VYZZ™U…Ü` g ¯z¶t#_Ù®‰Ëaß² \™Õ œ•øH7ÄÙWÑq“ñ`™?¢/?fµ™èÇYoZ„É 6Æ( ¡Q‚Mœ³ªþ^ñÑŽT#Pä«' ó Ú—µ}^û7\AK/M3»zEA׎>xvK ú q:ˆ1É`ÝÿN)/ul‘ð¸éÕ/¾˜>G ³ ÃŽMQT —Ç@Ô¢†©ëjð½êl]ÕíÖßÓÚ®«´h*»òf±Áº[PÝ ÉKöUÞ˜€¯\À—à9… ÷àjY³¨óM ŒèÔªEõ@Ïn  ;…V‹^Xi‘/ÍXUšt!ís•}Äz´²Ž€ÔΨÚy ˜I‚ν ! 6ß ¼æ»­Uœ¤m6Œ6ˆâ{X™»èò·NÈÊnäö‡l 7o¬HZºPd®›)w&†\oÃa6ÀÝšâÀ(xekÚ’ÐÃ5m¶÷ €Á`ÆbH¶p6j±Ü£,xJQ™YMØ£— àÒyv‰û1ùjçÃÑæаg307]‹ªl ëoEt ÃU™™Ž¼„èbmhgùºYifqP¿hO¼Ú´Vžõäa-ÉP75Ÿ-#§Ó¶tÁ'¶šÅ¾Û³xªífÐWmì ©M„pÛ›ìh²ÖApi®–ÑDàšW¬Ï˜ÅÔlÖ¸”{všÍÃܪÞap¡ÄixYçuq`šnñ•Ì­ ql74,Bì2³-[tÅPÓù^ß–U›íîÖŦٓkª¢»rƒ•PœìÙA¸« ¡ï±‚ЇO|7± ÅÒ‡Âa´¡t uYÐàéeºÊÜj¬–Ù^vßV‹ª†à»®Êå6jÞþúá͵PnsøþíOµcBÈPÑà¶¶¸^ܦc¤–Úç[qðºªØ¬¬ ^$ú½ÿ9;Z[³§M‡gwn<Þ÷MróJ؃ž[à4 L/zÓfåŽÊn6O„K ¹ÍRÐc|*áÁ׺ڬõ’Hì®+1® 3©ÐXUËæ51—æÙ­ô ‘XÏ~«tݘÞÖÂ2×êlÖéÂTÑû+ÔÖÔÅÎSÌæ¡ëýй—V×iÝ6ýR6ÝyŸ6낽ÙÔ÷j\S²ßÝ_ýu…Õ1Äüî’9DdÁB¹˜-VW_þ ³% v"’xö]‹®f’r¢$³Wÿú(‘¨vŽq˜œRâ’•Õ¡ÏezÉ7 "ŠèìùQoµNŒÀ&M\ǃÕÇÐ[Ú‡æÎN$ÿód€Žð´Ž3…ɣؓQ`°Wòb ÁèR$bl/2¼~mÃý›ª*2WçìRÆqž/ÍñÜEö`qgx²ár(Œƒe?†}• Ã_ ,7/‚…„ IfB‰PÑ1‚?>™ågñ_–óª¢2gXG˜lt€”PBö—žÌú*ÑÌ*N"êY‹AQ(yd¦2 OQÊóɽ2GnX±õ°ž'Û t(ßï©C³,á ØÏú®ß0æ  ?Gñc,¿+ªtBú¾0Grl â8ÎîdÃÌ€vZÇôú*ÑüBí [fO~‚òL0¢âø¿o«949“à sw- ŒãüN¶;@ HL=wÌÞJ4¿L‘PÆÞü*Œ°D<Â柳õ÷9~»À6e“-]Í5VŽO1ÀèÒs3í­D“M…þy…/Ù1lU9 IÝLšVn]˜ãº‹«ÏõHVžŒa€%ÐAÏ]µ·¤š%r󬾉¨’Dñè$Óª¯K ³\÷ p}ëÓц:"ÉýX÷V¢YbHd¾n¨N%ÌLÌ ‹äÑÔ¶Î'¬ðK s¬w5Æq~'Û tˆ8öä×W‰æ7„¾§¡‚D°ËdaBâ£ÅöçkÆð3åíSZßÔuúr‚Ú €rÔv05øKŸÒ}“p_,ú«|èNp?Øm ƒ Ïý´·ͽþ1“'õœ„ÐÃTDdŽq¯ëµ1òýQ9î» †É)Ö&c`Jáû<÷ÕÞJ4Ýö$<ôæ; S*˜ãùÝ@åøî‚æ{$uOÆ2@èÜó Ô[‰æ›ã=BYã&ƒÃ~û ºC9Fø`9»°N~õ“Q °ûø$ò܃{+ÑÔã[–xguNa’ñ‹1UcÜë³´1ê/ËQßE5Lýè¹Út8táwmßBÝS‡fœJÈužq“Š%¦ÿ­c´3§kc”_—£¼ k˜ò±“¶éhØø«g?Ê}• ç ìZ˜çA*Kôð$Š„I<Æø§sê·  ²„wAS»s“Ò–à¿x®v_È|”@Þ‹½™BÍbA„”£ÌŸQÉ]”%¾‹éâO§öɸ9Jyž·úê@ÞCØÐPÏÍ:þÿˆ¶(Ivï£%Ý`Y滨Îfþ ˜Œð?På—øê@P "¶ï1,ƒìÍTLBnÚõ؈ \•u.¨#›ö‘ºÉX‰R’ľÃ}u Ù’C ô<}eâŸI˜Ýø¬ûY„_™%¼ ¨Ý,ð'KûÿŽ—ºÿD9½ÉÛþÀý¤ü˜M~·CòA…L&Íîÿ×ôÏs/ endstream endobj 3001 0 obj << /Type /Page /Contents 3002 0 R /Resources 3000 0 R /MediaBox [0 0 612 792] /Parent 2984 0 R >> endobj 3003 0 obj << /D [3001 0 R /XYZ 89 721 null] >> endobj 3004 0 obj << /D [3001 0 R /XYZ 90 690.045 null] >> endobj 3005 0 obj << /D [3001 0 R /XYZ 90 652.023 null] >> endobj 3006 0 obj << /D [3001 0 R /XYZ 90 612.237 null] >> endobj 658 0 obj << /D [3001 0 R /XYZ 90 578.548 null] >> endobj 662 0 obj << /D [3001 0 R /XYZ 90 464.137 null] >> endobj 3007 0 obj << /D [3001 0 R /XYZ 90 329.222 null] >> endobj 3000 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3011 0 obj << /Length 2702 /Filter /FlateDecode >> stream xÚ­ZKsÛ8¾ûWèHÕÄž$˜[;YO¥fv;{Hr %ZV•LjH*¶÷×oãE2I™"/&Ý_w@7 ãÙj†gŸÏ>\Ÿ½ýñYŒâ†³ë»YŒg–s1»^Î~ÿõþß×—_ççTà Dósâà¿_¯®¯þúl:ß›Çõÿm^/.¿_}¼4ío0_âà;<~]ÿùö“  …\i!ÀÑújж/¯Ïþ9#ÐÄ32## ÓB OIf‹‡³¿ðl ÿœaÄb9{ÔC@,E‚GÐÞ̾ýç@WBB‰ú„Àp‚b!¬ í-<Á! 1›…AáÆ„kel’­òwï.Ò9ÁïïsBHùîv“~«Šu¶z_ɳ6Õ3ü…pÄ&AGEˆ¨ðÁ•U±[T»"5¡y\W÷¦•˜G™þ³K³…ýœß™çR·³å+f”ÚÈ—ö `ÜpûZhF(¦òtL"DsIAÔFq‰qh#vQé[•TÖÕ?±ÀþM€Ë±¨+Ívi‘Të<ë‰ð`Ý-ÁJÖ¸¢#Ì<ǘFˆÇà!Œ;#|™-òeº|}ŒÇ#s!n;ºQ˜>`KXÜ'E]†šÑhAéH² –á2næÔƒ,+›ó™ˆ1’Üþ^»Gÿþúa΄ɣ2¸Êª´¸›pæÂޏHbL³µ^oºç 0f—¬ì÷]™–¦¥ýÕóÖ~Z$› pI§Ý{!Çp¹´[G¬-A£hŸŸïòÂHþ­ÈšëÄ&lÒleH@tv Ec\[ ¢gç $Aï¹eÇ"¸yzzIœh[”uœ‚ÐÔôÁKÓeਮ¬\¯2×­')Õ8²Ž†!Ýy”=™|¬g?ìÊÊL¹MMSH‚Çû4³:¬IØ·e™Tã ÊÍS ÑïE’•wiQ(YªCÛ£¾/Uó¥¶÷%…wmúÐmЗ<[5Ë #'[›×Z ÔZæjØ óýQªwf÷õ¥zTÎÍ‹"oºYºA÷ë…U òíW=Î~5ÃØ¯»ÕV¢žµfÄ&W;‘Ñ%0£¦}»®J½u)Êú^e-Átª)5ª)±û^i:5ýT¯"ƒî5Ï ‚y¨àSíJ÷8ˆÅAë’¬[J‹=õe±“I™4;4tÕ{:´ÍÊ‚†6MB»òëåçOwEŒ’n¶*h­Kó´k fÜ>{âÀÌk±k‘?<ÔIH­;õ,Ràffûîm2Zäk—œJ%µl †HPKzHˆ à$ Ü”uî3ë]ë°;•—-?þñGËžªàKJ#û&gW» l´ëÞÌÏ9± Y$ƒ‡d»Õ ÕËmZ=¦jR/W_LÃPJ¡nè%˜”æeiRHºt2@£ïµÔ3›¤´ó6ëÛ")žÍË}ROO³¶0€3³eR,×ÿK—*ü‚Aøu\C¤s"‚§í&Yg¶çñ~.‚gÓ6Û Ó­1©FMMh[|j´&i¨5O•{×CR«Çä å•鱃Ö:;Я=ª{ò6 ¬‰¦ÎŒ˜Ôê1ãÒQ´|›T`Êíœâ`Wé“«t9'2XAUU¦Ç’IÏL2ÓP‰D=WE¾ÛêPÂKn?ªøjjkO4j)10`›fKâÆ4}n˜¤3t›->ÉMKùP™èŒTÚ^§RWƒ®x|çé¡F\0Р­/‚ü1?ά³‹}2ÕzUkg֞άI¹^ì¿—¦©rÀ˽êCžoÒ$ƒ¥EqÛ6ýíÖ`ç×K8ñt~T;ûÃeÙÑâæÓ&O´*Ñ–‹ÍfÚùù¦T@êî–a T}p¨Ýz^#T¾·iïc^ï{utÇ”¶³êþˆ d¼„ƒ} ¬HÖ;,,S‡z]íZš×v,RÏUz ¥Úíi‘n+óþúDÞøžèt&Îc³«…÷9бÚ.h:GA³Y¯QÆxêE½¢D› 1´†lsFùJŽŠS8jörh4/,z [_®4ùj1ÑUfª”º:¹Ë7›\Éy´—A¹»5 8ûná\W¾1§ˆ<Û<»Šuj‹S‰É}ÑeLP=¹akêÅlµðyµÞ'L—`aðI½™rÎØÝfc:–i¹(Ö[w™sXí»Ó{]Af@»SmawuI Há˜ãc?løÔY»XÙC÷WÈ€D6øÕSŽ ¯« ²&ì¹ÿ²æ"XYåα Ÿ0e›†kBÏV&±Ð7]Íöõ—z±á©†«X gm`~«Tý^ç;»ìê5Ô(Êô„ÌBpge‹Ø[3‡$S.VÕ>zy³Ãqû/7c‰˜”-W"ãç#Ç3 °‘÷ì øN"‰d|W7€,yH_zC™B¥˜% F<8õ^£¼¼­‹B„)D=#êº.ôÔÛs†¯”E±h¥< ãÔSªL]¦w-—zR""O‰½O?˜®.©N¦oDQDØ8ú†¨òèa¢8"¼³,´ju'€B‰@RRËm—æšµShNHûšëËÏwï:ͯY<ÈâˆGÂѸ;쾦vŒ Âg$Lgáé„5Ýð™KD±½‡Ê‹‚ (¦¿Ué“J7'@B)AaL|$e»ÞšÌSèÁ<òõ6ÈÜazMå ðˆ Fä«L¯Ù;X¯O?˜®~ :™¾ãæþ2ØÀÉ_Èß¡’#Îd÷/q»‡úN¤¦oÈ1úN¡×Ñ·©w}Ch¡âŠJ0=ôt*Ž›o¨H!™ÄrôVÃaWý8Œeç¨Ãx'B)ÔJqèÙ´ª­™8…Z`¢ºÖðÔ6˜ØnxMÄ pm`õm¢ƒ•ú̃é4ŽOgî¸ù†¹p>®¨…fÄ`Gœ…zˆòêN€„ »(÷¡˜ßUAw„ÄSqâë?àðO‚“a"z½`þ£8ìQ·a$ÝV¿šºBx½mÿדz% †í3™`sqúJ7_¯øÅ#wp(…: SˆeÔ{éß½Æã¨7ð&ŽŸ³V½ŽþèÁ~_kƒûf;âWÏáŒÏ)¥Ù޹Cõz¼ƒÉ"&'ÓvÜtÍZBÙ6ö_W1’p‰˜².ÖšËünÚN„8ÀîݲìPëX;…ZÐE¡§¶ÁÛ.Ãq'@ÀÃEj ¾ÂpÇÛÁj=æÁlÊN¿ 7]¼‡åØ»`‚0,Þ(Baçn{säîaS}7ÞÀá_$9ÇM!Wˆ&‚ƒoŽâ&ÐÏb° ›Cðè1$åé—Ãã¦k6‡p<šÍLD³P F:ÿ'ø¦ÿü7ª¯D¸‡Ãe=`3MM>÷—ÐP—Ã$&ƒ}àè<‚ÇG˜-Nþ©bÜlMfƒÃqGÂP‹€]zz¹Üw$œ‰áˆšHZ"ù ^O†J –˜=¯oŽŸ'ÀÀ$F‚ǯwˆwRìyê¹q°AÕa6‰¢“WÊðé‡ÿáÿŠ»Í4 endstream endobj 3010 0 obj << /Type /Page /Contents 3011 0 R /Resources 3009 0 R /MediaBox [0 0 612 792] /Parent 2984 0 R /Annots [ 3008 0 R ] >> endobj 3008 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [236.917 257.72 243.891 266.467] /A << /S /GoTo /D (cite.Henning) >> >> endobj 3012 0 obj << /D [3010 0 R /XYZ 89 721 null] >> endobj 666 0 obj << /D [3010 0 R /XYZ 90 504.445 null] >> endobj 3013 0 obj << /D [3010 0 R /XYZ 90 419.947 null] >> endobj 3014 0 obj << /D [3010 0 R /XYZ 90 388.066 null] >> endobj 3015 0 obj << /D [3010 0 R /XYZ 90 368.141 null] >> endobj 3016 0 obj << /D [3010 0 R /XYZ 90 336.261 null] >> endobj 3017 0 obj << /D [3010 0 R /XYZ 90 304.38 null] >> endobj 670 0 obj << /D [3010 0 R /XYZ 90 241.989 null] >> endobj 3018 0 obj << /D [3010 0 R /XYZ 90 187.657 null] >> endobj 3009 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3021 0 obj << /Length 2322 /Filter /FlateDecode >> stream xÚ­]“Û¶ñý~ÇOTc1ðã:ÎÙ>»×I“ÖÑ$N¦IЉSŠ”ùá»û÷ÝÅ)ñâóL†– ìb¿,¸XðáêÍêêû÷© ò(Oâ$X킜)Ë"&U°ÚŸÂ·ÿ¸ù÷êöãb+&Ñb©þúñnu÷ãÞаZä"¼ùñÃO´|wûËÝÛ[šÿ û3þÃï«~ÿ^Å#‚©©رô8KéŠ9ÏÇ`)rqK•FJrÚ¶Ú %ó°{:š–¦[ócqe¶´,*³°ó¨›ºìÍ+}ðxo¿ûŽ&í¾îK\ÚÜ·mW74Ñ£ëŒë¦Óë¢,º§E¢Bš`yxS–ŽÇ½i/ÙÕÁ›K.£\Jy”+§†Ñ]DÌí]p´wÁÉÛŸ>¾Y…ÊÀ%^§=êý‡ºÚøÎͰ,š~îuY OÂᨵgD®¯ÑbI’Ç¿+Ô±®îkZnu§í}˜»IB7Á;1‹X…_n«þ@¤ƒ£¦¡=šM¡KZltë¶mM»iеÕnª<¸ÓE9…‘ªq÷^I;xüºî;7Ý~AtµñÇíŒîúÆ´™jÊF¦ 7‰“H¤‚n’DqÄá‹KΘy×Õ};c㙊bé-Ü£-E[¥Ã„‡}²ÜãlMi:3ÇnÉ|u,äsû6XlˆW]–õFwE]‘“Á@jê%p!@Ë9‰˜¬ Ǫîè(òÎÒX¹°ð®j;£·¯K J|ª{B?ô­ÃwòbáÞ”GÓÐ|×WäÆ>öOX®Ÿh»%,cŠY×M½ëNpf¼epdØÊ1Žp†Šô¾0âšsãà׳1ôvuõù Í‚½R`—B›ÃÕ§ßY°80¥y²W¼_œGY–Á%£bœýg-8PQž¦ÁŒrHCºü¯Õ?ʯ¯ÚâÞ :u•uuïf¦BýÕ™‡Š²DMe9˃˜çAÌñ°íÈÁäÝÑáHžŠH¨gŽÌÆGŽ˜Œ¹Šx.¦6ü¥.ÜݦÄw1–ú‹H¦³$¿j2Ë#ž&ßbÖ¦‘Q“IqvJÐÖh!šŒ–{ˆ¥ý•œ\Ì¡nžÜ›maâ\\!ÎsÓ.ÃN fyæÊØ‚f¢‚@r dž9¢æ¢Žq¬Ö•ãó`S(‚ÖOKÛ1Dh!Ï"R·CVEؘϽHƒy&—6B ˜RÀ~ rÔ 8=e+€£Îéöcì®dW í#˜¹è %w•‡›Ì(ãäÏæ=WŸ%åú°.*+1;ÑBú™$l sGÅ|eçiø¦îö3l&qÄÒoPc|B~&%Ît_pm`õµ1PTÄ¿¦¡êm9ÇcÈ'EEêp±sX'‰ØõïŒ Éx³gŒ—§,â*?cr×,D3Ï©LÓ û%=€?§ù™&\f[ÁªGªjqÖÕ4b´ÁY~ÞÀß¶©À–Xü[_A÷2ô«´-!Ð}11ß2tÔPO¢¤ýyªDð´QU0¦¯h¹^Ä,ĦaÝ~î!!¹¨o°aÕ7ø¾CÖ4-Õ˜3O$#Ä“¾Ù°mÉíVfÃʸ¿¼*ÆïI3gp'bÉ2û—¯mï?-@ÎZçA¶{—Óî]øîë³jcæúw4¦¡º{÷P"l‡°”®ù¸o刎‡0zTÀ¦ÔmK[°~Ò×f¯Q‡Þ€ðoYü‹·‚?¾7uãHÚlÿjÐkFS`{K6@¬OdZõ‡µµ#AzÂÑ`ab0o`u¢@¦·z³Ç—œœ.ŒHþ´¢‡œ5¦íË®%lÛß ûˆC{Ðr;‡iÅ€XV ŽÒ¯ ]:f:úgˆ2 [,OãØ˜åœ‰´À´ •PsP&NË2³ `ûÚöšúojôh÷­CØ;̳‹ ð¾}½õ{««òi² Úmï0 ·Ž©ÆÚ˜ÒWOiˆOqóæî4íßGRaŸ˜ÛÔIÉ-šâ|‚ÐÂÂ÷h?uï^ºl§Úô›,æ g‘1ö ‘äñÐ'2íY:?ùÆ»U² ð xب?û¯1§à¢]Ì1‡cçüÖk猷%ƒ’ûs%lÄÛú9Þ( ª ðXð9Îà8*?q†pMÃÈVÙú–=ÔWÀˆ:ª€a¹óG£㹥Ѷ¸VÙ†±é€ü2}Öñ.˜P& 2%ùA&¶4×?ÏÂûÑðñJ ¸¹Í°ªFD£‡.˜”Å¡pS2Q@»¤,=eB°ìvÌz›’Í>ïØ˜obõ¬­8螊‡QøÞ}Oµ§ÔÎJºÚ¿kyN§æf"wörzó`›?°eµw}ñuÅÐÒÈ3›Àº)NA2¬Äa<Öm[` µ+êœPYø>E;\`£&JͽLÐá:»¡[¤ïþé‚â™ÔH%;õ­°É~¦¨ú??k¼ä endstream endobj 3020 0 obj << /Type /Page /Contents 3021 0 R /Resources 3019 0 R /MediaBox [0 0 612 792] /Parent 2984 0 R >> endobj 3022 0 obj << /D [3020 0 R /XYZ 89 721 null] >> endobj 674 0 obj << /D [3020 0 R /XYZ 90 610.018 null] >> endobj 678 0 obj << /D [3020 0 R /XYZ 90 199.856 null] >> endobj 3023 0 obj << /D [3020 0 R /XYZ 90 150.613 null] >> endobj 3024 0 obj << /D [3020 0 R /XYZ 90 127.209 null] >> endobj 3025 0 obj << /D [3020 0 R /XYZ 90 109.549 null] >> endobj 3026 0 obj << /D [3020 0 R /XYZ 90 70.036 null] >> endobj 3019 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3029 0 obj << /Length 1763 /Filter /FlateDecode >> stream xÚµ]oÛ6ð=¿Bíà ¯³BJ¤>’n@Ö¦Y†¢é#{HƒB±éX˜%¹úˆ›ýúy¤,ÚršÝ‹I÷}Ç;çÎ!ÎÙÁÃ7s/ ýЙ̄8‰=¸3™9×î«?NÞON?ŒÆ>'nèÆ<$îßÎ'çïÎx‚Ëd”îÉ»³ ü|}zuþê÷—p?&î,7“?ßp¿ÇIn<q?J"‰t@´„fuÆAy±Ÿ8c?‚Ë¢$œÌà‡Z—œë1'dÓr5¢Ä}0_EÝTí´)+¬ÙtÛY)jÜ¥ Äj‹ˆÅgL#/û}êqBQ&ߦДë:»+rQ4ø]®D•þaˆ“x!‹PŒ`X í‚ çß÷h,Eq×,<v’-NE]È]gùj©]‰¦­ ­F³Zü¶ª:ý‹6¿šJ9ÇU,…4¾—[÷kñ¹ÅTlù‚%˜mö-F`Qü#D[åå,ûHˆ¯ˆYgØNiq§<s-:@5]µWÚÂÚvz©/Ú=îf5‚gÙ|äsw.´ ´Ø"ÕYù€2¼(¤`ê%\§÷-½›ac öâ[ÖæƒÖ¾¸QîŠjY¦³¬¸’(å#+ ¸¾Ñ&8w¡Ü°8t'ˆ»u{[O«lÕl¡öÄîª*G”¹÷ÙˆBÊÔxˆÑŠû¦ÔkG¶³»k“(UœNKi³µ|#ÕQ%*7cÒw¡Æ4iV(eåiÏÊQ¢ýV~XiüÉ(bî/ºÐ@©ô @3CD Ñ3¬˜éëëÌH!õ” LB„ÝËØI—­Ð´14ˆ(X@ w¯´˜áFÕPCº* Üó¢U“•žf›I;É¥ojî¶µŽfœÁ´¹å\æÎÍFãñ˜‘2Oÿ‘ÅQ£¥C TÒPE[ûË+eí­D¿N)3Ã×­hÖBèt!Ì3PWHàÑ8üzaa^BºÂ"“_%¢<¦ð¨Œ ÂñÞ• ÈGYbÒF*ÂòôK–·9B­'PÖÙr‰xEÙ hzû& Mù¡lñt^•šV-šF³c†ïÊœÊpïÉÂ{1 ×"îqÕ4Eш gµ"ÒcBú…ë†À‰Áœ—Ëe)ÕYkQ¥ãgæ°Jïr­"Qù%WYQå*¤¾¤ð¤itT‡¸ $hËÖÖ+Åe"ûxÊ££×hÏ«¥¢êmYÜTUú`)öp¨ :|> °%•­‹áM¦‘3Í®oˆ38ó"x¦× +w‚$†ÖDÆßÒ¹<øk‡¤j)é‡"e Hp‡…¡G¦3™OPÍ'Fû«m-hxƒzÓ ÚÏê„{ ¼­=pþ°„« ŸVMuŒÁM#l?²ýïk¶Ö…Ñ8Я¸b›aÉL&EW0D}üF–¼Év¯j±!z\Ó“WÕ9£^Ì‚=‰öZDr½&7–žZ (³ÐÛlÃÉ–Úlýýl£Çزa¶l[ßfìgÿH¶Í–íg›à †² ”h‰‘J'YȽˆßœJ2fKƵd\ ¶º8J‡‚‘šÜyuñá÷“£#™:en?‰ec‘ß›{s‡ƒPöµ”âû)î¦tý>Ïî± ¶m;0ÇÄ·j>Œ_³B.³È“cýýò)öÌ^¼0-õ×X/T«9½Ô4ŸoZùÙ¹ð¹¦y¡ËÆ Kê­›ÝzÑ÷•ìÆ¦)ŠÙòøI™yÁ·> endobj 3030 0 obj << /D [3028 0 R /XYZ 89 721 null] >> endobj 3031 0 obj << /D [3028 0 R /XYZ 90 690.045 null] >> endobj 3032 0 obj << /D [3028 0 R /XYZ 90 672.226 null] >> endobj 3033 0 obj << /D [3028 0 R /XYZ 90 652.579 null] >> endobj 3034 0 obj << /D [3028 0 R /XYZ 90 632.931 null] >> endobj 3035 0 obj << /D [3028 0 R /XYZ 90 601.329 null] >> endobj 3027 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3038 0 obj << /Length 1849 /Filter /FlateDecode >> stream xÚµÉrÛ6ôî¯`}¢Æ€àæ´Ç[ÝñØ©¥:‡$ã¡%Øæ”‹CRrœ¯ïH‰¥0Óvtàí»¨õhQë|ïýtïí™/¬„÷¬éƒR˧¡Âµ¦së“}üûчééÍhÌ]j{d4v=j¼¹˜^\ãá.ÓQèØGWç×øyrz{q|Šû ÀÔ¾…åËô·g._#(5×v4=Fõhßž1ºþ|ì¸á³ÆÜ‡C¡ÄhìPJíôµ¬ŠR~ýD¿ŒÆü†ËñõÍû£ÃC¸Œ³Ç»ùâù3uéþM>ûï£lŽ››:~7M&™Ê¬* ÖŸ®†N IP'U ƒ”¦bv¢õ½(F,°eÙSÂǯëÑu–€ø,T"Râv­Öé›×gÀ¤·Z-j3—Ÿ)å™ÒŒ>7÷¥¡.ÿ1W¨žd)·£ÑzD’*Sùáá :Þíˆ1/U†hÓEôú“§‘¢e|4Šïî@v’/N¬ rŠÓl–Ï¥yqJET ì‹“K<[iѧѳyœãz|pÐç½ëpÐØ/± ^ÇHœ>çÙ\'u™Êô^JÏgö™rdUÔ•–B ÖêÈsí7ã‡+àêeŽš·¨á2_ûY”‚~Ðãœ5ãp`<®\FÉBö8&4<ŽhS׺–‹¬âD}åÇaÔj¿Êúè3NIÈš,ÙÊÄ’`?Ë@𬽽±Â@ßÞtGmíáœrPmŸ‹;Â]3ŽXó7õé­Ù î¢Â@Ì¢$é5s!«„ìÇö HŠ–z4'5K+õ(&”z ohÍL¿}JXèÖ˜ç[€mncÀ³Ë³»NÐÛ“€ ·y¸n €Z·Ü­¬ác Ølµ†CCâòF Þ´iTõ(ŃñÚÈ–R!$ŽÚ7Zð}âQ§íPsYΊø³ À‘“á4«ù¼¹Þ`á]Ž5‚M~Ýp&6øí¡ Gi)ì@Jm(¦ê ¾k‘ÑïUA’ÉÜCZƇq­zÔ @ À@K Û#ôø)*šÈÔQØGªb4HÀÙ·(}NTÑPô€XEà`QFÏð®®0p0<7#œHít»沊bãDÝT|/Óèx¦íúaÛìx”xû™¶¹‹R·Ñíy–AèùÛŽàDxõ€aæ™i-þò¶Gjî–IïpÆûf \&ÙÚÜ÷Nzb®wÄ¾ë “(½†ÌÓ+´lÚ›E?Z¯ž£wNÀ@+éŠÎv ¹p]Ñ6xqÄœÿfðâڃ׉œ%QUqn&”ü¡ÛŸ7Éxç´àŒÝâ‹,®â(‰¿÷ᮓýÆÐg;§±IÊ8‚èê°›9 f.¯’¼&1«ÀЧŸ˜?\3`‚†ôt¢ÓãrRé N˜TÍ|Lf›µ¹.ì›N¤Aµ™*·cÕg:çÊó©Ú©Î[¿)¢¬|…ElñÌÀ•+´÷rl †aªÝ‡½H5³ÊcK5Ê©½ž#Ô¦”Ö-3÷BÝ`ö…y—æ5.zlP™-R‰Þ¬!øæ•4ø›YÊ ú,ÇU ]|æ­JQ}¯{‚nŸÿ¢ÿ‚z˜áƒ»¡þKãJuqb7´ç‹4}ÅmMGÕrý0Çs(îÚÉ<ºÎ ÞÕoî̓?nŽãÊà2ã04Eÿ u¡/ʪŸøKœ$}Ió)qjþÎèÄÃR9î9õ'}ӹϰÐWÓ”ðO…Á¸MúÂyS…b^#V¤ ˆ"ý?E˜ˆp[61§*‚Ž“ÞÚ´³,—+ ¦´ì×W;ËòV¸³£¿.§ÃŠ“ð` þâþ¢¹Ek endstream endobj 3037 0 obj << /Type /Page /Contents 3038 0 R /Resources 3036 0 R /MediaBox [0 0 612 792] /Parent 3040 0 R >> endobj 3039 0 obj << /D [3037 0 R /XYZ 89 721 null] >> endobj 682 0 obj << /D [3037 0 R /XYZ 90 484.237 null] >> endobj 686 0 obj << /D [3037 0 R /XYZ 90 182.485 null] >> endobj 3036 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3043 0 obj << /Length 3343 /Filter /FlateDecode >> stream xÚZYsÜ6~÷¯ÐÛŽM<µ‰«ÇI´•ŠS‰*yXo¥ !GÃÍœåaEÿ~ûr(É/C° 4Æ×Æ¿¸¿ð/~xõíí«·ß§ÑEîåI˜\Üî/rÿ"õ3Ïâ‹Ûââß›÷?^ÿrûá×Ëmû›Ä»ÜƉ¿ùã×›Û›Ÿ`â5?n/sµ¹þù‡üú݇ßoÞàöo0>ó7¿Ãã?·ÿzû}:F8[œ€84_àçØé•/‚xþExy £ ûÖô߆)ðP<*ñB/¼Ü¾ïo~¹ üîûª¹çé =hnÝ•ÃCY6ü²;Ve3p[77ú²ÃáŸñšçâúÛ ó’Œç½^Jå›¶+ 75‡–Ÿ}£xSJ§FEùÉ÷æªÖŒßËàƒtyÿñ×o/UŒÊU*Û´§²ÓS÷±/‹ùl}ÙEóc×Öµn½´™ÿ2Œ7Ÿ«LöpГHZZ6-”ÔÎ+%ÉÂ$›‡IjT äáñT2­êß@# g=@èž{8‹Ã7ßýÄŠ†ž†>XajìB7+»[$¶O{÷ßr7€ªDmn"²ŸDdÊá‘¥^’G/Ì“‚Í…¦Ï©kQQŸ«‚W”m4O56•£Æ^I“[…Ài¡OÖW€f5Za©&ÚcÁ$Í„ÏÈVÇ’©h.HÖÝ]5tº{d2¯Yóõà§° pôÖW‚ú² |a鉗fÊô3èÊ}Û‰ìúxlQ´‡ž%xlG‘ eÛ%umdI]¹+5-سÊB{qÏuöphû’Ï)­PÎn'´¦•ÓŒ§ëob.§Z˰ÝSu4,ªºôh¶ òò(šÏõœÚBÏWéËZ‹2Ó§BQU û6ú@EÉ ~#uÁSóã3BG[ÉÇ×ü¨dä{Ÿ?UJÍFžÚªŠ\®†Ý±©fmQQà©4ø‚UÙ•»F‰+Ò"`QÂNÌÅœk£9 í ˜±Ö3-nšsÓ£‡ÉæG¶²HÁJpAqÊFÉcHÓð$YâdSÕ§¶4ã|¼)ª=²ØCÿfWþ‰˜¼j3ÎÀÛkfÆ ›wÄ}<–Cy|ä>cƒb–‹hhQÉ,óD4—§àŸ˜@{xê€mÁÚ†øÃ§‡j80M̾Ùɨ¿ÖÒ±,î…D@}«¡g ÷!sϱŸº¬ˆB³Ï“qRY(­5¬C“Ù¶4Q¯÷åðx™ÄOLAå^¤ù=ns‹–œ¦`äðò·FUãžgjSíù‹æâL)OG½£E¥‰ý84CòÇ"ðcðé‹Ç"H­Ÿ-öUOZÌD‹inf?骛O> endobj 3044 0 obj << /D [3042 0 R /XYZ 89 721 null] >> endobj 690 0 obj << /D [3042 0 R /XYZ 90 690.045 null] >> endobj 694 0 obj << /D [3042 0 R /XYZ 90 465.348 null] >> endobj 698 0 obj << /D [3042 0 R /XYZ 90 360.366 null] >> endobj 702 0 obj << /D [3042 0 R /XYZ 90 264.167 null] >> endobj 706 0 obj << /D [3042 0 R /XYZ 90 187.764 null] >> endobj 710 0 obj << /D [3042 0 R /XYZ 90 101.462 null] >> endobj 3041 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3047 0 obj << /Length 1414 /Filter /FlateDecode >> stream xÚ­W[oÛ6~÷¯Ðò$ ‘LR7Ëk ¤iÚ¦èš-1R ]Ð2h•E‡¢›äßWÅ’é´»À€yDžëwIàÝxÀ{7z=ßæ‰WDE†2o¶ô àå`$õf ï‹üþè·ÙÉy¢øY„iüÏç§³ÓOïôä‘fAûGŸÞéÏ7'—§Ç'š¾òà_Šájöaü6E[i-Í„;Ê„@2€ñP¸¶¸CË¢\LÆZ(‹øÁ( BðO›–0^57ã“Îp)É Œ å%0^ÊOÒlV„a^ÑÆáŠ‹(ŽSëÚì¶jµ˜¡_-Hë×zšS³Ü™'Lý sÜV¥´&b0B£"5ˆóÇ5i{Øñd6ºAAÊDe‰^¹}¹ÞBÌð@”¹w¯¸V^\L¢HtkïbôûŽJUlG “D¨H½ %* I‹Èd"=>;}45A˜‰oü‹ŠôC@†{†›:¾!ß>R¾”¨áaœR±‘ª¡æ|©7sb˜±fzñâ¥UïdOûì¯^Yv·ö¬7™éÉ|s§ŠÉ¯)­ nŒ<œ»mFpÞ‡³ Ñüaù¤/$v‘àñäìtºdtu=×^ü R0‡âß„}}`Ûú8íiC»Ú r9mÄ{mÝ.%;ˆ^pVÙºj9ƒ‡âÏ *´ Ùz¸œšJ¨¾M-pSvjg²Y¸ufVçsiÃ-‘÷%:Twý¶ÈMœzD@$äÆcALž l ×KFˆL‰T»7Å •`wí¥‹ÍZê<8Û¬ÛƒýZ¡síK5¹s«‰w’}‰ÙÛšb~Ä6ÒËú3æ®9dËÅ0E5inø­ áLÒ¾ÐpÕ+·\6ƒ}9´O®+r7ß›³Í¥¤MËM¡îJŠ#˜F°ˆ…’(O­ãgµ¢[ÉÖ´6{½æÌ4„`s8p úÝ•òPÁ -1p¶~8¬Å© 'N•ß=QG9üGç¢:{‡?ITTdü`ŽÁUCô†©&¦âT‡Ý•CÜ#Ô,n𨾨Eº´W¦‰äÔi Pê›cR®É[€ )ëòóP5iAõlÇÖ6rØFÆ6rØîŽ'¹¬Ì+jÓVÚ§Øç·fNîâ N}µ“¥‘Áá¢+j{éïpq©x:O4OÕpÂVdQanP­hSò ÓÐô ¤;ŠCÕoÿïÙCçG²T«Þrá3ë2ü“žù#W^ŸnL€·tS·Ê5± ¸®iÙ¡€;0:G¶B F\&ÄÚèç–dzÿJV”=ê)‘«¯šš“oZ£ÃŠéf ε¼fS¦¿î«º6¡ÑDI×0òd©=ã©xl ª>T$ÊÙ"ë%XÌê ΋9•`Á´›àK‘ècöðð`Îɯ®åâý“$À¼ä¬ ±üÞö öçz™‘%a~èØ&0Ò”"°eÚoI(T$¡•„ôº·¢V+Âòk%ò"`$­Ñ¨‡!kMu0»´æ²­o¤?ò½OD¼DD@9ËIêã¥Ø˜Z¤VéÊÍjÅõDÕº€5mÛj^ÛJ¡îïêÁzò>†Û5ý÷ýeMÿ«6|¸ZßQ¥(Ý~·"ójÙ˜u ›”¶­?V„ßÒEÛoUfÇtµêäÊ·­ãq+Ó2‰²‰öäT ]l!3+I•1¶Õj]WËG3«ŒÄà©ÒÇ;» ²uÓ±ÁG0›olÌÿ"%oåWâ·+¬šX¸%õÚZŠP.`¹w¾IÆúœãñ=«8'«UTÍw‰t‘tзÕMƒå³‹­mn=ì1#¶]î¹™ü @òi! endstream endobj 3046 0 obj << /Type /Page /Contents 3047 0 R /Resources 3045 0 R /MediaBox [0 0 612 792] /Parent 3040 0 R >> endobj 3048 0 obj << /D [3046 0 R /XYZ 89 721 null] >> endobj 714 0 obj << /D [3046 0 R /XYZ 90 690.045 null] >> endobj 718 0 obj << /D [3046 0 R /XYZ 90 97.477 null] >> endobj 3045 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3051 0 obj << /Length 1819 /Filter /FlateDecode >> stream xÚµXÛrÛ6}÷WpúС:ƒ opÚÎ8Nœ:“IÚDã<$™ %ÑŠTHúö÷ÝÅIѶ:I^¤åb»{p.ÈœK‡9/žÍžœF¾£<ŠÐ™]8Š9‹=æÎlé|tOþ:þ{öâÝd*æ†Þd„Ìýðîlvöæ%)éo6QÒ=~óò-=>q~vò‚ä÷à3÷þ>Ï^=9 D' Ñ‚ÒÑñ8çhtÀL†Ãÿ³ƒoDæpL6Œ™Çbá,Ö?3g úWó"97ÚjíH{ùóþàŸ)5œu“âÜ÷‹œÐ=Á”Im2 cîu™-µè¦·M•,šO,`‹²¨Òž¼}÷ìøè踸£ç_Ÿ%ÅeIOÍÝ&ýÓ €#Šå:Byq;SÎ=腉יM¹äºœ)÷"_’éoz$ðT;uVÔi¥ÓÛÉ  ý8Â\xR†ÿaho•9@}ß ó|SzÇ…áƒìZ ¹¥C:Ì”'Œˆ†ŒÐÇÁ%TK ÕRâ²P¾[ÆÀÂî`aÓnBÚã µ8ãíË®_ ’äýI5 âÈ‹àm܃¦6¶ R•^¤"ëdíá`—»ðøÂDpœe÷ƒË•ð¹×~ã<ØEB ÐAO¥]¡bƒ.Öd³¾·Ö„ð<òBH„ )ú"‡ó1[$¸k%‡Ê#¥+?‚ìèyЧáõ{]?{šI»:àC«#·«:ÍHaÞð¨iÑ=Ú Àí™&™çy|bLTäÎMá ]¦pØ” <3ÆÎFrV€ïº¬îHN.ˆ\2ÞŽ›e22n<”Úáí Ntéô"›ž‚M Õ-Ea”e‘ßuÔƒyë¶æø‘°ª «jzµR&@œME€fåÆãö›¬7¹1Yè£Uà{,Èe{šÃÐUM© ûFæ¶Š'ýW6¬Ò|£1¬CepÀÆé.µ \_m6emfkV‰ñ¿éä¥i:Và•ö l: œ”ë514‰IM3hSÃÆm¯¾Í‡¾B1ÿGwƾSŽof‡mg,|è,gvO\¿.~ì6s~˜‹§cüÆ+§ÆÚýƒþÆ¥14à ^ü>§^Øö‘ÓQ'_6ÐFvm»ãœo;ñ)gÜ ù ÷MøNǯ­#8±Y|Oüx'>@щKèZoý W¼Á7ÜÁ÷YYæ)î,dÎçã¨EÆqÞ‡Þ¶é¨}ü8Êre£ž?€òüQ”Õw£¬ã]”•†ƒÝÈÙXõ|—Çö\ÇJà¼ã‡ð3€ÚîKg4ë!ð˙٠Ù×”¤eR,Úigxiþet9ø=¬'ðÔ> R?° ˜ioI"/P>òû˜ß’÷Ñ[¨NA÷ت£ ì²ÿ<©Nó2iŽ«*1—ì‹üKRU|F» Œ‘—§Åe³ÂR:) ×3î;}dŸ{0rS?Þ÷÷ø fü¶ëcfØMѺð=èñð©ÝùÙI`œ#B<²B:©HyRÄû$Ea1/5<É‚þ ùý̤ê·÷ÿ,Âßc€Àù,Â¥ð8ôÝ:«×YaZ>õIÀû´ìgþ8`nÛ=tz…v°¼°ß冽*½›u/‚­ð±¶„Sõ2hß^û%Áù”ÿ Ú¦},‹°—…’pM5åà^¨¯‡a/ К˞ÜÍt: 0ÚÍâ|Â9w“êööÖœghß~mðñÛ“þîZú÷éã>w3îüކõÕ¯aÓûR¼9â•ÜwoVÙbEâ:ùŠWCº¬KútàÃ5%Ý´(78~GOXþ›¯²½ë믛zȤ¬R¼ÔûÂÞ]Ð%×°¢$˜ÍRd&8´Ú5}_Ò1J›K{ejc}P0™Ü·•ÿà ÝE endstream endobj 3050 0 obj << /Type /Page /Contents 3051 0 R /Resources 3049 0 R /MediaBox [0 0 612 792] /Parent 3040 0 R >> endobj 3052 0 obj << /D [3050 0 R /XYZ 89 721 null] >> endobj 3049 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3055 0 obj << /Length 1960 /Filter /FlateDecode >> stream xÚÕï“ã´îûþ™ý”ÎÑœíü^xÃ,ËÞ±o†îÊñá¸aÜÄÛÒ¤/Iwoaøß‘,%Mº9˜Ç ôC­È’,ɲ$[8G8ÏÏ>[=}Nê¥‘ŠœÕ­“ '‰'‚ÐYåÎ÷ê‹Ë¯W×/K 7òË0îw/oV7/žò’†Õ"õÝËÏ¿¢Ïϯ_ß\]ü øᾆáíê¿OŸ…j´`€«…¨cדR!Ñ™` A=áHé¥!pù²§_ªdøÄyÊóK)„p¯ž<¡ewfW7 ëJoÌÎTÝŒ ÂYÊÄ‹’µÚà‰•ÛJ†rÓfM±69~úîÖ4<¡{àn¡BW—ENŸ·u3Æ7…^÷²JSmº- Êê(Æ<¹î4AÝÃÞ´L]ü´ÂeÞºQW›úââsƒ’ï^uMQmh–ÖôA’å€%`­µÏz (ªÖ4ÝS:j]£3& ï`  ß­oO¸F‡ÿj8„#mRC€Ï¢ˆ äUåÉÄáÜ[N&sJ-E6kU 0ÍX‡À˜mvhae25¤ÿI¦V¡ûã´ïINüÏp)E ¦¥Äø¡dýNïö65ËÀ:K75}a¨N m'E&Lkš™ÍÉPL’ï¡1Ý¡©ŽxÂþNN"ëpü–ô£Í˜8¿6eL÷“¢Ù׫³ÿI¡„be%8/ lwöæ­prÀÞxq;÷–jçøiâ…Ëqé¼:ûæ‘HÛ1H1ö¨Ä4*b'H"Ï—’ë8lŠ‚MYõ¦ fE€ýò¹¹û6 “é<©n6EÓÒJ½$I¦Q¤x©_æB º?šÕ#HH:œåç8ƒ9dÈâ2›úäÏmÌ#dcå÷ ¿Ú‘-¸›–vÊjMœ¢L•—Ïå±hN«˜µ¯0:õürGß7¼ ›ºfý¬cÌu•a*BøÓsôù¬c^|Gäÿ¡¡2÷@ZkÞ€ ^[ülP»ƒvê òí¬ðôhJ¶@NZæ#–ýÀV¡´£~ËÐKã“ bNº”,žÎâàþG1ÀÞ–}lýú‡Î—ïÇžJ¢?s¾ìyš$()¨+BîÅ}žzQSW”ö•ÀB¶E°hi¬j uI)÷?“– g&àØ\¥Cs­Ìà ٱ*ãÉÈÝ/GlïßßcºMÍÂâ!jý0aCâ¡Ìù³£±,*C„ ¶A‰­4ÍLÓ‹(*¨äÐ’ÿLB’AÛƒ²%gÏA\Àš¥úÆ6yh¬×LtQ‰N{-¡1LÑwfò5aô¡«wØW‚ÀšºmhÓ{P\Fqc ³ UôÁÁ<þ(x$H!Óþ6Å%þₚ…á >.‹‰ð„z>*}&ÉÔý¶%÷ØE­wA6ƒ·5;hÎì6ì'”?uÈ๘rŽƒŸöÒèlKPWì C[Ž—…‘˜é »…e‹¾¿ì+hÞ±ï!̦K„P@)‘æ‡ý˜ÛÛc@b{qÚê#.ÓO}óÁÄ¡ÂÀ ü¿©.+Œ2Ú´._¡‹þ)ÅùTùïªÐá\…ަz¦fža0 Yø¾nÊüüw«î‡*×±Žþ‰Âmÿ—•žŠSR‡”˜Þ:ì&O;]%ú»¦¢‚l÷«úƒ9ÚÛø¦ÃTUw0se¨>‘9(0·ØX4 ¶še󩺦Îçýù¢FW#|wÁšK›3¬6íL¦ŽàêâG)QGê$QÓ²5æ>ºn6e­s®ÐqÈ¥ 5‚› \Lm"˪°½}â¥VyR8ñ•‹©¹®ILˆû¢ÛöQ á{²¿mFÅkqŸNm±Ü›ªoúV&Ó­±5>ºš±@.© jÍJ_NNº—Çž‡òåI•ü%×é£Iå/ÅmQÓC¿âMqƒæcõkkÂT<FœÕ{|Nz Z{™V}f§! uÃÓ¶Oï¾l×^Ф½áâ‹RãyĉG/U ;Äï…P•õ¡â§*\¦ªRüT5“løájZÉÔÓzÈoŠ<Ó¾ýÓÛr"¿ûµOHïIe¿Ñ}ó5 endstream endobj 3054 0 obj << /Type /Page /Contents 3055 0 R /Resources 3053 0 R /MediaBox [0 0 612 792] /Parent 3040 0 R >> endobj 3056 0 obj << /D [3054 0 R /XYZ 89 721 null] >> endobj 722 0 obj << /D [3054 0 R /XYZ 90 690.045 null] >> endobj 726 0 obj << /D [3054 0 R /XYZ 90 561.781 null] >> endobj 3053 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3059 0 obj << /Length 2057 /Filter /FlateDecode >> stream xÚÍXÛrÛF}×WàÜ„ã¹âBg·JQdG©\vm–óà¸\ ŠÈ’€–T©ü{º§@‚ ʵû a0—î3}fºȽ[{¯/¾_¼xj/fq o<÷bî…ÆG5Զɯé]è`»}èväC«ˆ2…ËlÏNÈ`ê1>ÜæÐEòßà¾[K%*OËj‘­i*–LÂ’ö]˜Ö±“qØœÌÀÂÔ™›ð±Âé"§8k^¦)õe5õÜÁ!¤V¶7{’Òs–VuY Úrù“²›ÇŽíæ©ßl#™côì7ì%uB­E2€£õ ƒåìLRÀÓ³Ý*ÅŒ)EA`54I³_Çþ¶z§-«‚Z뢪²‰U"ðV»ÞM•6ö죪“:›BTšõñ…׿æÛ¡|ÖµåvÿŠÌ…þ´XÛ€‘®A\¹[³p~²ƒ3ëKéÖ… [7ßȈ‰l(!J 8—$…"'‰B)Dê~½L²íB‹¢m`^,>r ¬Y¶oÀaUmVÛá„Np»›9.[†aˆT^èJ/¶Õ-P³tºLÊÍ6gz«å¬â˦N=6VP8®&i£Gs'öòdÕè¾TöÖSO T1•òóè>¥@ õ¿Ö}æ)Ý|>Ý÷#á:K¨"~ì‘“ÍÏ—Gä©v¢“ÄŽTŠq?Ø‘€ƒÇ‚p\bYŠM#Vbmù‡Ž"Ç<ˆ­„M´“lÍ};ü†“m%…Y³ôÎenE _—¯vl7ë¼Ã–ìa ¨£©×ñ¶F^A4- rQ™n7öuïÑn$Á\‰®vÁ$Ì£& Ãö¶Ÿ¸Ðv%Š9:êMèѪz«Á°YomíåZùìã‘&g¶:Ñ5sðúÔBV`þ×NŒbÍ` D–g«ÍŠº[å w&ë?à 89Yÿ…1$¦]ù‡žm!´-ÔYâÐ(hTñ›®$ß,ò­DþM7Á9ûQDµ0r;Ö¥«;Ŧ¢žV)DY%ôÆ¡m`#s ¶2»í ¡×F³ØÀ]︷2k3u$A‡-§í= ³'¹4znºSd^6]PÓ Ñ ¢9£Ðš¤ÍZäP{æsm ËPâäÓÇí–9ƒÃI…â)’ß.в>’ågÀ¥à»RtX…{²×}RÀÌyÄžk‰  EœI,$}Ÿ"|ŠÙ½Äû ¸”‘°yÕÁå!Ãôžì{Ÿ0*y½çÚ@zA5š0<^ˆŠ”‘g"&ýWôúH‚Ÿ™Ò!|(ʲÁ>LñÉÞ÷é*ŒÎ£ø\H±–@:ûãMÑ@Í“©ùÕ²HŽMÍÏ€K’)¸º-\ ‘`8ÌìÉn÷Y\ž¤­võøõK• endstream endobj 3058 0 obj << /Type /Page /Contents 3059 0 R /Resources 3057 0 R /MediaBox [0 0 612 792] /Parent 3040 0 R >> endobj 3060 0 obj << /D [3058 0 R /XYZ 89 721 null] >> endobj 730 0 obj << /D [3058 0 R /XYZ 90 690.045 null] >> endobj 3061 0 obj << /D [3058 0 R /XYZ 90 118.736 null] >> endobj 3057 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3064 0 obj << /Length 2175 /Filter /FlateDecode >> stream xÚµXÝsÛ6÷_Áñu#ø&éÌÝŒ'©3½ö.Ñ¥¹Œ‡’ ‹-Eª$×½éÿÞ¤H™VåÚ÷`\»¿ÝöC4¸ hðîä›éÉË·‘ ’h®ƒé2HhјP©‚é"ø¾þöâ_Ó7&g\ÑP“É™Ò4üñÃÕôêûwH¼Àa:IDxñý»ðóòͧ«×opþÎÇ4ü×éû—oï ”VšÒÇÉcLÚM'Ô#|3=ùå„Á”,`‰&\©@Ç”ð˜óõÉç/4XÀâû€‘ÄÁ­Ûº8£DÆ ÌóàãÉ¿÷˜HËDÇ„ñèØÎH{‘‡³Ö<§¡:Ð#“¨Á¼2ic®/Í„«ðë§ c,L«Ër;ËÍEU¥wÿ¥ŠÂszôB‘˜²g&TD4``[8÷Kª‰’Å&#ÎÑIxü×ó,Lœ‡•"Q$žìa!ÀŒ*!Bòð>®Êª9ÖÃÏMHXâ´mQg7…Yàë-¢Þ~4ˆGäiÞ~*çm)ˆäOv¶fXÁ³¦‡½ý]YÜëì§#2&q ‘yHÊ/?Vúˆ€çOôñy8 áV?ÑÇœà%‰VâO}¬å±^~pŒ”Ø„Ò×w³–ýh#^”Ä:z¢«ϤM÷tP˜Ðaa¢" Ö‰Ñ* Š"&gŒR¾µ&*+öš*ƒáæ©uÞËÚü²5ÅÜŒÔ48c1Ñžë›_Óõ2¤;[.=Ö¦Y•>²V¦ÙVÅNJ[A™“7åùùÞUúè ¹›„[³Ç…iÒ,oöOÛºÁÙÌä¥åp;¨†F«"k!H,’}‹GIÔY¬OÕ‡-Îhß4LJ`¡ÅiëAç`ði«æ×OCínÀ {‹ˆƒeI$}éñ7·¢ cEAüÏ;`q~¾0_¯Ám×éþ[¸Y&0±Wׇ>îaüÏí¡~Ñc„K!èŸbŒT!F1ŽÑ“Óê¦Ü6^âß'g†ÂÜâä!!­¯¼ ƒ’•Ê1ôÊ£G©gÿÈMqÓ¬,;±ã·wFû3v—[‡Ò øG8ÅXΟéTÉ«øú‡ß\œŸãkº^l7–ûé‡íz–žö4ƒŒÔé彂sŒ­v œÓ¼ùí!8Þ:±‡ÓÆswþ½©æ?Ÿ>hØäY4áGh_d~íaÙS=”€w‘1ê¡a(BÎ(sTÖ¾Üߊ("Š \<*¢ÜOgŒJ’ÀEP¡2–øoÖeQPpí¢ ÓúÆ^»†Êœ·‡6( ´áŸ@“{ÀÖÎc†NHÄôHlAkW[5g^KpùgÖ v”6•¿‹Ît =ºg9+ìJÏAZ†ä æ .´0žó„Âå¬ëlæz 7ž üFü®›´Éæ Ý]{~çò„¶— OD^–…{Gð¯ÌüҼܸ'ëÃà*ü™•—Ûo¥ö š‡GEÀ¸KŽê˜Dø˜í¥‹^:GlGc­ùë&O³î CÑg°,sß!ÒîXÛ¾Epûëz»î–SfVÝíÒ]Úci®Ï‹d³ÌWi5¦ë®›çiÕ6piGuí_6÷­$F/ì"×3ãUôLŠtÝr×{ ]9¦hãÐ2!þOm ‡z§kž»¼,ç—õ#ú@õˆ>Йt»Sî·8§Ë¬ª›ÓWcÉNÞ?½×‘œÖfïôÕxw O{ÞÎôP‹ ºÉüîG¯‘Îu§ô þ`sÙè®—zDÂ(\\&ž§‰9Üß4,‚!t»Çï.+ø0¿Ü.›õ˜½Y“¥yöf€"O³ÂY?Ûï~ÁŸm vK rk{ ¿RøíÒÖÍq¼ÃÙÅЛŽ^9õœC 㮜‡'FßOÁ,ÂÁ«³ª¥ ‹»îcŽ5‹ÿµ”ýÄe©ÃÇ»ï¦I$ذˆ·-J¬Ãï²®¼H®bqºäÍ­½6î±@Ugki­Zè}#N&‡¯WúC?â·Ô;ó8bcŠC[7ºÍÊÏ’1ýÀÄ·Û¶&‚K!RïvŒv²×MtB5T™«Çúú˜uÛÛ}6šx±ãiSˆßmóJÙ´ù¨«Æ‘€‚ìÇçš?ŽÛu endstream endobj 3063 0 obj << /Type /Page /Contents 3064 0 R /Resources 3062 0 R /MediaBox [0 0 612 792] /Parent 3066 0 R >> endobj 3065 0 obj << /D [3063 0 R /XYZ 89 721 null] >> endobj 734 0 obj << /D [3063 0 R /XYZ 90 582.863 null] >> endobj 3062 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3070 0 obj << /Length 2354 /Filter /FlateDecode >> stream xÚYYsÛF~ׯ`ù ¬˜07´yQ$Ê«TVöJ,çÁq©@r$"‹ƒ€f¸[ûß·{º!»6z æîî¯Ï9³—™3{ñÓêâÝmäÏ; Ýp¶zž%Î,rbÛñƒÙj;ûl]ÿýêãjù0_¸c…ö|„ŽõëÃÝêîþ= ^Ñg5O<ëêþýêÞ,?Ý]/©ýûcÇúŸ/«ŸßÝn Ô‚ØÑô„pÑ…Ã{NoõÂ,_¸ z´)´]Û³ýùB8ŽcÝÎÝÀªTË–k¥åKEÝMUì«Zn©×œö²žàÉ™-Dl‡1¾Bæé‘8V}Øï+ÕÔÔ«ÊüD­æ8ЧNGGOi:ºyÜe›5S%©Ñ¸¼¼‘Èü×Os!,ø¥*_••/WJ¥L(-·ßÛwSÖ¹ìí´QJ-—°“€u»ÚÉZö‘€¦ ¶ô˜JË:OBKX cxýÃÔ¨uØ4Z/¬cÖìx§‡kùÇA–YƒñxÀÝ]C‹2¦WV<€Õ°=¤v0,²¨Ô‰ÏlÒ&Û¤9`?!ŒWâÛ‹<ëmÁ‹|«!yqLË …€à2Eà‚ž@¸Hæ²eCsÅ¡nhxÍÓY™5Yšgÿ&B¾•Ö4±•õFek3œ•LsÇ÷Š´•U‡š Ö‹)I6»tßHU(@ŒðŽQٞʴ`(ô@Oø!j`”i-m2wp*¢ã²½»±í{¢s'ãL½¥+•š‹¼ëÿr7 Q(F0ï0D†FÞϨ\°Ï5Mȹ¬?7rßdUIC…Pʬ.ø0>^i>y—RÀ š[­=ÂŽeè?¸®zÙMÊtÖÒð^0©œ"kZ˜×²9JY2Îy¦ÍF«£äµT_QÉéræf < ØÇ„=\óy€F®?<ü4÷Œ»^Xõ©ndAm-È<,=ZìàzªdMcÚÓ±¡ÒLÇ*l¯Oô%k…’£å%/341>¦H×ÍgÄ9Írp!žüÍ œ+ž–ÐgC¶ïª(%Fú\zG¼åÃ3àG¾c}EׯcX«õïrÃX+ù,†Û¶®¢·hH숇û=„ÝÀCËUÔ€¨ÃYÒQßX,Ô–5ÞPÓÇW ¿9Ž[JÞ“•ôe×ö¬»›_¨Ër‰ô\ú»ÌžŽ`M¿]œãΖÕÁÝ´‰±lÒ¬4FË_µÎÀþMüH‹ê`ìš$tØäX?i‹ž*ÍšÑ1{)-\ßNœˆ­>4q£WH-JZHðÙRÒ¸ÑÊyЋóp5¡® Q"rì(n«½÷«®ÀæÌ–aâÚQd6h%„­&‰›©”ºd°*K9µ…V.ËJ•8¡óºíy’áØN¢xÄðRͽÈ"ý.¼ÄôFæ0=!má%æ@T©=55±ŠRöP\c,Qãè^ÚÐ åù|§é~²w,&ð\”¡ê¸2ß֣Т;»–S Û"eFäŸphPÓa;Ö)Ÿ’´9o·}òDŒ…$ i,º)r}áËÀÀÜ;²Sžn´ CO»W»W77ÕVšÉ-7úîá—†!Òi}zÕË´L_¸|é+1+7ùaÛÃ4Ç:è/ÊVõ½(P“PªËšÓ<ÔØ 6‡•_fdy(¤êŽ^%i(4;%¹Éà ù.©fñë\@¬¼z¸ç²|à+Œaó#Þ ®îï®G‚9,6—BÞ«¶CÖÚFÛ¡dEEmÞFÕ†bE3’Ldz;É!1èÿU[•Ê^²ïÒg«ðF±Z úί"·(,ÅT½‚|Èãøˆ#)}º`ƒ=ä¿Ã`¢×™ØPó1%ïP[ÉK0™é/ÖlPžFwÌ€©Ïpð¸K›©âŽ˜ŒÌ¦Šö¬Ð)Ì Bcï8nÔ‡íãNrkàiN»6yZ×’¦â *½p;˜=I8‘. "àMÅîp€YÔ»§@Ç™,Uéò,éË‹kÀ€ÐîðäÃÁ>ïô{ˆ¸ÃÒ’‘®NaM!›]µ¥%ý¤ †Ôe$϶¶IÎ-›'`Ëéëy áÊ…2ïÁä¥K>fÙTV” cÏŽ1,=µÉû&’û^jº4¬•FMÍX=Ú†…EYŸÓƒ?¨¶çÂÒÞíS-ܯ-aƒ©Þ±=.%ð¾°Âób? ㇳàƒþú-”8ÜB‰ßÀe`¼º˜“O¯àÓŠŽS µ!d*Ǥü1‘æuE¬™[¶j‚AqËõ]£u×”×ÐÒwç”,ÜeŒ]+Ýn¹a•’×cm@ÂN6>úÌÎÝ~Á‰G–|¶’‹N—ß8D[w¡ ®0yM ȰƎÑtegõúi¤4ù¶B57w“?s¦ufb¦0Ýbãs®’°õÅž¨åñ™%´}/î=³Ø‚Z–¦Å>—ãÞ=1s÷Us«©¼œÉõG€oø.ŠfCÁe\àíùÐ,}s#Ñô¯Ñà//Gnö÷O²M ÆSƒ Ú(ºY.ýø0X#^ôŸ)±hßaÖÆ¿)Âåýÿ}ÍpÿýJûý endstream endobj 3069 0 obj << /Type /Page /Contents 3070 0 R /Resources 3068 0 R /MediaBox [0 0 612 792] /Parent 3066 0 R /Annots [ 3067 0 R ] >> endobj 3067 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [215.727 276.804 222.701 285.651] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3071 0 obj << /D [3069 0 R /XYZ 89 721 null] >> endobj 738 0 obj << /D [3069 0 R /XYZ 90 690.045 null] >> endobj 742 0 obj << /D [3069 0 R /XYZ 90 608.897 null] >> endobj 3072 0 obj << /D [3069 0 R /XYZ 90 562.679 null] >> endobj 3073 0 obj << /D [3069 0 R /XYZ 90 528.936 null] >> endobj 3074 0 obj << /D [3069 0 R /XYZ 90 465.954 null] >> endobj 3075 0 obj << /D [3069 0 R /XYZ 90 434.269 null] >> endobj 3076 0 obj << /D [3069 0 R /XYZ 90 414.538 null] >> endobj 3077 0 obj << /D [3069 0 R /XYZ 90 394.808 null] >> endobj 746 0 obj << /D [3069 0 R /XYZ 90 261.818 null] >> endobj 3068 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3082 0 obj << /Length 2791 /Filter /FlateDecode >> stream xÚYYsܸ~ׯ˜ÒC‰=4ïCÙ­,9Jdkc½©r¶TšA™Ç,ɱ¬¤òßÓnðQq^ÄÐh4}|=rÛ…³xwòóúäÍU,R;¼h±~X¤Î"vÛ ÂÅ:_|±.þrþËúòãrå…ŽÙËU9Ö¯¯××ÞÑä9}ÖËÔ·Î?¼»¥áÛËÏ×—DßÁþı>Ãç·õ_ß\…ÞèÀO #PGŸçº28¬á›+׳¯ü0µ=?]¬¼&}ÞåÃIãX™è²ÝrùO'tÖ¢ÚÖggoå·+¡ ™ÓÊ$¬¹x ±r]; ù¶nÀrþ=».WA«ZìÝS{û^–w]#EI’ë?Ïî‹fgc–VÓÞŸ~¢ïéE]–¢b]O§‹Ùx­ßAŸªîˆx¨U~´QVy;U.b5’ñ¥ÎÎ.¿grß5ò¾Û5õã½Ôª®Ð òõìUR0›ƒv;=ÿåúž/ð¡î®´&³{<Çì©í¶kP8¾Ê<¯Ûˇ§T™¼(DÛž±5îwð§Í) ˜}ÏãwýÏĹÌ÷r}òû‰ ¤³p1Âе£$ZdåÉ—ßœEó ÒŽÓxñ¨¹Ê…Ÿ&vè Û‹»“¿S$MÛu; ‚Eè;v’°µoT%—+?-—>gQŽký|PEN3‚>¥,ëæ éÈjµ‹að¥¡õ©•4ÛíXԣ˸äÈ#qm#3qhå±Ìe¶$J4Ì>„ö[¹¤üÄUÀÖb‹A„A­OG¢%SKôx¢ÁFvRV4øu8–ªòzé…ÖcK“Ú‘øT©ïúÔÉ¡áØbÈæÓ,æÃ9l±‰*p£¶æ#á~ªÚ­ª#FcfDkÍx V° ‘ÐÏåû©µ†ÈÐW¡e’ „\º¡eâ…vt5-e…’UGô¡%Õ`¹6GÔ̲(Kú#gòÀ‰œ¨Ï’™Kx-ŒÎ¥ç '>O¯Qbûà¶¼¯íD§2:°”Ý®ÎY‹‡£‹P Wð]ßœxj› #ÐÆÜ‚ÖPèGÚÀl—û#KøAÚˆŒà’Lí¤ö=ô‡¢èýùÉ¿a!‡|íx•bQ0ƒúNXdÓÔ ëð´—´J.ðq8°²“̼wï2žÏÎéyl˜©µÕŽôÀé‘í`®g|+ñß.I%döCÖ ó!Ú׆µ‘¥PUèóxq©ý–1Gö§È‘xÚ†—êžtuÓLª(ænºA[8ììðµ—â„êZšÈ僎æCÑÑÊ7hά^äÙ±öfím‰ælé%v ø˜ùw ™Á4¹¹QMß X¯ Å)M sd«Ôµƒ8ÚÊ\ØþAôÝ`î ‘Œïé*@Šû(WÝP‹GTÄ0¸LjX¬c V:ŠuÖ¸B08FÖãÄ U·£ÅÚhåSÒ"8I© N+ÞÁEìFð}Ž‹$Ö`ùûAV™´é b ÀÄÃ7€ÜåCòëG6×AÄjÊ9ôž@4¼©·Û¾ößg@"CÔ8ó¾ Ûól/âðæ^¦O_º¦ÎÙ ­ØÔ‡Î Åh¦ÚÊF¨;ÑHdðP^Pc I¶{H‡žm¶ ">¾;Y|!d‡üº˜Cid•È›td0¬ƒ»^ÁÈ£NéæŽËLlÕPPZšêŒT°æh ²˜¨À? YZÞ PɳJ‘RÕCݔ %O'Gü (•JO/{ÐVV‚^CÑÄãZ E"”=8¥:ún!cašw"ëº"®}' x©‡À ¦`¹#@2ß‚Ïg,wSw;^5ûOÀÁ¨6u¡\Bæq¸MÇ”˜)ÖѰ›ÑjNòzçÂØ|o‡A_|j;YŽ"K‹6‘ Îwã>²l—ckC_:Ž´²³qä&Ð3]@™Uî)O˜÷ާxÇRh׈.c+Fü¹¢Õ&ƒš­ßf÷Pd;"[Uj•¬mñDs† W¨bÎi;U‰ÕœÕQOôß ÈcBרþØO/›RU5¨ù´4ýš˜DE«,ö”/\s¢É%„ð‹ÅƒZ+ÏT.x«qåJì è«ú(Û¸äGúiæÐ@b'01 ¼ÐÅ¡ià1бºSo5(O«Ö´^l{©T½4%—këBÇ'ÐBµy óÀ{(esìÑ/—À‹Ûw·7—g½ ÓB6|ˆ~þ¾5­ŸÇ*gt ek(îŽÛXþôˆÞìÅ$®®I/5ÊEÊhÄÕ1§IêRƒøùÇû"ÈB6!ÔsÚ!ËÂÃn JB¥Ú’åð!Ô8!¥o »6"ûzØóu)Ûº?‡hH‹íÑYfŒ9åæŠ‰`ʦ&Í´ê_#S¶RšêÆá¥°ÉbŒ­GY4ñµ"*Ž£øÐcêrŒÌáBZ“Ì4Õ/”drn§Ó’üE兩Ð:½XŦm­rð‡L¨=ú"5áTy´8ºÜõ¶â­Ï2îH¾~Õ`*} }).¯!ã[³+´¶Ø³%£‚Më┉ZïÔOªBlŠÿUÊúß¶8ÎÁÙÅÖïu7<$Ñ‘¨dŸ—0iÿy”ÍËi¦”ƒ¯ýq Wžƒx¹£{¨>ŠÊ,Í”á p‘ç½ È8oÌîF–úÕQB¶çlÍ8¤slüÔúUÇ7NPŸÅ*Rú'7Ð]©ËoïÃy&Aà$º¿ö\ ý͵ð^/naÎ$-r8½^™'ÑL”ßV$Ùîê"9ýè6ôó0€C—2WÈù0L8ûÑ£C–mé{šQ»Åïé¸ûJ”ò”6½b®{÷”÷UF1TÒ@Ö 3š@o´Tš£gú‘u»™à,“˜ª«_Šj˜Ï‚AWµhŠ—úú£Úê[¢#)‚†*¥aŠ\:FþPÖÙѦÒT ¯„ {"ãàֵѕ£Ë·Ø64@§š¹õ ˜P5ïfR—댣oôÛŲñ”‰ ý/ø¾ß¼>þ}WUË){è0ÿß6GÈdØ'¾?߇xØ„¿cÿ¿PÚ›ƒÒ7’û#윌¤ßö‰c+M)Éà2ôOx)º|«¶•±Tû/.ñ s“lƒƒcæÔü¢=Ü"Ú^~ô›aCªõÏpxºÉh8ÐVÃÕ¯ªâãu’IÓio‡,X¼´›°´9À­³Fr”÷V±ݪªt›¸¾ d¤ W{û¡ÕM#§¤ÄáNSSµa,ú_J`ú¨5£õ-­áåºz¶´Ðíôï*°²SÛÝ‹û‡m¯_úGÓ—l½d endstream endobj 3081 0 obj << /Type /Page /Contents 3082 0 R /Resources 3080 0 R /MediaBox [0 0 612 792] /Parent 3066 0 R /Annots [ 3078 0 R 3079 0 R ] >> endobj 3078 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.012 340.537 388.458 351.44] /A << /S /GoTo /D (section.3.5) >> >> endobj 3079 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [476.762 185.943 493.419 196.847] /A << /S /GoTo /D (section.A.9) >> >> endobj 3083 0 obj << /D [3081 0 R /XYZ 89 721 null] >> endobj 750 0 obj << /D [3081 0 R /XYZ 90 381.732 null] >> endobj 754 0 obj << /D [3081 0 R /XYZ 90 291.298 null] >> endobj 758 0 obj << /D [3081 0 R /XYZ 90 88.884 null] >> endobj 3080 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3087 0 obj << /Length 2259 /Filter /FlateDecode >> stream xÚµYÝsÛ6÷_¡ÉÍM©‰Åüé»7±ß$Nj«íCÚé@$-ñB‘.IÅõÜÜÿÞ]ì‚$$:“›É=È `±ØßÂb¶™‰ÙÕÉ«“ï/—Á,q“È‹f«ûY"fK»"g«löÑyõæüÃêâv¾ðBáDî|FÂùåözu}sEÄsjVóÄwÎo®ÞÓç닟¯_]PÿæÇÂùšßVÿúþ2ôF¸[8z?)—Èt"XÂÙÂ0,¼%Lò‰­Ûæó…/§¬7›¢ÚàGì”ùÜ Ïs:yIãªlkLëªkj&óüØQ»z_uD¬ï‰VT÷u³S]QW4ðÐÔÙ>Í3^?Yk$NFÛiŽúÍWfdõöŽæÀ (Õç"ËÛa6¹ÒMBÖ÷}]–5.÷¨O…ê³NÕíWŠ6ß©ª+R¢<òï}ÛQoS ó*"u5µëœ'UY‘ÂAF¢£&°}Ü*^,­÷efOÕSÇðä*ÝNˆ ²Ê3}V¸IØ~yyF“nênÛÚï?¡©Ëù2ã“R²í½=³ ò~.Q4U²pMS7|º4Ý7Mž¹x‚n épIiÞ¶¶j]ï;[{@jº)‘.noçpÞßIªá¶öU“§dZ-Z—9ªæYñXÛsO8½_µíŠ’O«ÊñŽEHÔ_æÖ=¿½9õë䘰†ƒÓ™ieª²|šÒÖõÍå{Þýƒåd™#ÔÒp[ì@ûªbITŠ,<é!opÖ´½¼¾ø-â§+Þó*¯à:³a–wª(ØGÛƒ`iS¬{ûìo¢¨º¼©Œ•­ó­BE}.z-²+)³Ž‰S2¾puÕ§l²A¯ýþãQ[þÓ™Hû€Gn$°oìÆ‰ ZàŸÔàY„Þh,joõõØ=­ap{­€…%Žg\€ ôe„ŠÃæ š!iÐå)|ß°¥H»¶­*2êu5µëœÚ¼B‡äÁâžÛΞ¾ir°Ì˜ÿ±W¥½(§†hœž&åRm[l*6ØÅT|ÔA'Á ×nž;Ý^â\W4ñeî60˜ö¿! V¸ë öBáGâç:eà´m¡C82Í¥cË‹T#›œÙ®ÛªÊôÐ.ãqRün†N;±u9¹þ„[€Šj¯ŸK":ò3Ò(Gs´Um㩪¾›CjîèsÍÓ&p$ð9¹ùN§äÞäüm­ˆ™ÄÃÞ‡·–`B»UìÐqh ªÝÑ*æÁq|tJq(“[K1#Myˆ¶@±^ìz1ë-r}ן/¤€Òrf%pY1BsoÇ»¼ƒÄ£6yÛ¯?€9¡ý8ŠG«»’×·ÖØ©Të¢îÃ=µ¯^¾œÀˆö²„®@?„®@wè Umxö­vW`z,º-ÑrÕ>1[McÀEÜ_wPÀºÍ$©ü‘T^˜¸2YäúÐ@*¸Ÿp«ô<æªlb- ØVô ¸íš¹¿9wËùÂõúMËâz:Kß>UúŒ1òÄ(ˆÂ44ÓFäûÜÐöŸç­èÔÊ^Z+6èÈį''ºÛTòTæ­Œf¢¾ÛIèWÏ m®‹ çýÕïÿ9N'§Ùçô G&1“‘ûd÷_{7´²Ä…rãËâüDùýnu{qþŽ}B;`õÚHe0Ø&ô5:ÀN»x¨[J`'¢€³›6pAc.*æÚòðq¼¢} #€®2ßå`]¦( œ´T-3"¾-\]ýoXuÄÑa!1Ù+HYÆC_$z¬$Ù•ODÑö -*D'ÈŒ´û¦ÞQv„Î ëLUmê³³×ý‘®AxÖá˜8ãX'Nš_°ýs´ü?;ÄéˆR'Žs%HÆk&ε31ªVÊ) Kò°%G'ìŒ"<|N±sÉ’“:°˜¤£VR_Æ#ÑpTí»+ám=â!ˆ÷O»Rá¶Þ7Eø1Æ ¥µÉK8˜5›unÙ;F¤Øî:ˆ'—RC`•=×#]S¤Ÿˆ¢a H]t3–åA i K[Hßw-‘çwXx;2\d94\ÕVà.ú@A›Déc)r‘(œ? ¤/V'°¢$>›øbé†A2Kw'³ è`î2Ä£æÚÍü$vCæËÙÝÉôübw)(Ç{‹á0À>R àïÅ»vó·¿sÔ]Pó&ÇZ`¨ê¦Ì^pð)^¾DËÇß?¾ê<^¹^}£ó¡E ç®k0µQ²”ŽÕçÿªtˆÑ®¼o$$´ŒJ"™©záòEkÿ…M+;XL_º›°Wùu×"cß]ÆßÈÌdø,ò¬ £«K’sx‚éÁ— ‡µ)PÙëá*Ááøq‘ùAÅšÕ{¨´¸b‡*i‹ 8zé`…>¿-´àÊîú첇–ëÛŠ@è+sGÖ¡Ž6åØ3Y¾Ë’¦žƒi-?Ç©xtö¶­wyWì4ˆÖöü$£¡ñÛ 3`Z£ P êØ–ct[úžsWT´­„;)iÑŽqÄÀÌ2¹¦ÒÃiÉʼno=d`¢\êš·hhl¨zaÊ`18ÔnééGÖ¼HQ§ÖL7HݽH³Ôßœ)#a?á[M·¯`H|Qè M…L NìZÔ`*W†ð©+C`! E”Té’?FY81ä!91ÏAíÞ†0Ìù zGù æ˜|x±®}&Î4Â=PfgêA¿Rè§:aÖ“¦‹>©¦ÞW™yMjŒ+ô/°Å® qž¯¿ÏÍó‚ïy€}ºmWéùNUw†¸[kË…¾~g÷L‘„ ø‰S~ã‘ÏÀ¨>ÞtÐ?[ k›W1hdA[,† hl‹çëéÞ¥`-éYIØ&ß;ýÒŽ k¦0cV¢ÿ)ôC=$–úòë0pV  ås×Ú/„F®û&oX€‚×VÕ”•|Mvý {à¶Á endstream endobj 3086 0 obj << /Type /Page /Contents 3087 0 R /Resources 3085 0 R /MediaBox [0 0 612 792] /Parent 3066 0 R /Annots [ 3084 0 R ] >> endobj 3084 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 325.023 118.394 335.927] /A << /S /GoTo /D (subsubsection.6.3.3.2) >> >> endobj 3088 0 obj << /D [3086 0 R /XYZ 89 721 null] >> endobj 762 0 obj << /D [3086 0 R /XYZ 90 482.341 null] >> endobj 766 0 obj << /D [3086 0 R /XYZ 90 461.398 null] >> endobj 770 0 obj << /D [3086 0 R /XYZ 90 146.668 null] >> endobj 3085 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3091 0 obj << /Length 1706 /Filter /FlateDecode >> stream xÚ­XÝsÓ8ï_ááÉ=ZW–-^B[¸2ǵ9x†Qmµñœc›Øi®sÃÿ~»Z)±—ÂЗXZ­vû¡Õ*̹q˜ójïÅtïèe:©—Fz)xOaˆÚDp´>ßOi„Ûß³éÞ×=†Ìñl”0%ÜÉæ{?3'úk‡yq;+Í5w‚4ñC ¥s¹÷׎HíŸõAù~è¥,v"‘x~hû‡cnVʶ¥á›»Su[dj’uKYžÏ›ò˜šåUYd4žÊê¦>>þ£¾™ä²éÔíŇ¾ï¥Â¸™ïckÁ®Ìã1¾¼Ž¢úÄó<ïÀ@¡e\Ðbx ÆF óâÐØú›^^'Nœë DúšçCÒ0bËqßúF‚õˆ…ĬElÙ™½CgD´k0 xc›rÐÑÑØbº^¤ÈÌ ®ë²¬WEuCÓ²6ƒÂÄ^g ÏiÞÕækA&NÀ}/cVWm·Xf]=š>û|2P gNÏ^üýêËåôâlò†6<Nß'çÕ}©¹àÉp«ªòòÙ˜Ë}> &0`î‹„oóñÛèª ­ßž÷ícF‰—@¡ú‰cNµ ö‡^FÜ·0·‰æD³éâètø±\Iúäjß.Åç-œ\Ÿ¹·øCMk€”¸u¦ "ì–60™sGÆk% QIÀ*áV ’AÉ-ªE¸žÉŠ® Ã\抖”l bƒÕ;#5¯«CPÖ!9« •uD•M³¨e6ƒZÆÌrÍ5£ò¤'«¢,-Ä6[ $гᯀQø:ÙpÊ ìTD’ôXI®ÜX ë]ˆ"Ÿ»çqi\¸» Ý9ž*$•UEIŸ`…¬G¡rѵÄUY€àe•«EÛÉ*7L=ˆc†æP­¯h_À†x¬æsÛÉ®gísæ.;Õ5E£Úà Sðo]·÷J\‚ ¬ÖX¨¸q$`×µ9¢õÒ 6€`bÁ°góúàóþÁŸ+Yµ4\õëÄñ r9>”“oQ(¶Â|â\ ¹> sóP½zõ‚ƒáÛNh.‹j¤¨@E ýu»t½¬²®¨«¡’êe?c_®%^w# „ð"¾A®ºY““𺯫òŽf먜<}:îìMTm{Ð3+ዹ1+úu³.)%Þ`2œè¶n×´†q:pÄ*ŸaäÏÙ§tñ\(™¿Ã¾Š†ødžÀK™¬³ Ç®tHÌ$ŽG¤Ÿ‹ý}öñ‹£ñjÛ|ÎS/ 1ñûFO œŽ=bPeùF$BG›l¬ºq/ñƒŸreß÷H‘Ç‚ôúÞ0þãy°Ÿ×c˜àÅñ&êà°‚êOØDß±¾ZEC[w°.Æ>ÝXH·ꉹ;`te¶åª“E©r(ólÓ 8Ò7µ¨¶6Ç[Õ!6´N½‰Ñ^T$Á\qˆgvï“«]6M­[¬;œ>ö7`eªX`æƒËÝ\ ³"›™å…úå›á„˜G4™¯+I^Z(ð¶š«J¿H`o`ÛÒh¦j¦à¾’Õú"«sU•²_C'€²ÿ'`u ¸t¯Ósøƒ¨ö“~d@ÝžÇ`†÷PÓ£Dn}M+L³0í!Mt℩ʸi“qEK p‰¼* •ÌMv¹,ªôë!§ùªèf†Õ0\¸Ó5ñÂ(¦ì¶js¿f²„=ÐÚ¿[ ÜK­ ôÃLUýH@Cz‹q”åÒˆÒ²9=ÛùnB zÌêB}]ªvk|ƒÐvÚ²€T8xPéÈÙ\Ë迼mf<|> ½lk ³[.*¬9[Í„ñï¤ÿvv¥¢ïd"` zè€èÀYÛI ›©y®á`(x`¤ h†6#·9ˆ4“f­­ç»éd<» èvź”}nm£l>Öÿ¹ºFðrYvDX‡óÝ‹5fXXôŸFC’ÎÖ~]Ù_Ûßït½þ3–q$ endstream endobj 3090 0 obj << /Type /Page /Contents 3091 0 R /Resources 3089 0 R /MediaBox [0 0 612 792] /Parent 3066 0 R >> endobj 3092 0 obj << /D [3090 0 R /XYZ 89 721 null] >> endobj 774 0 obj << /D [3090 0 R /XYZ 90 453.183 null] >> endobj 3089 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3095 0 obj << /Length 3265 /Filter /FlateDecode >> stream xÚ­ZK“Û6¾ûWÌ-TUÄàûèíx¶*‰ËÖfÉ ’S¤–„<ö¿ßntƒ(޳Iå`hF£_C=¢‡^üc÷â»7EúP…U.ò‡ÝᡊЍ £4{Ø5¿ß¿}ùn÷úýf+²(ÈÃÍ6Ë£àßïw?ý@Ä—ôÙmª$xùÓ?S÷Õë_¿Mí°¾Œ‚_àóŸÝ?¿{“ gÃwËrÇìÇNz±„[;a+ X”д—°q O Q0*Ù¨‘ˆOm×QëÚqÒ²o¨ß\Ƕ?Ò ^›¥Lƒá°`|ºn؈ ¸Ú9Óu¿­Oò¢÷·H*nÓëá|ž·»5´ÛýƯZMx@8Ü6ŽÃ*c=ל&Ú&Uüe«*qT•¤aY «©WjgÁ§÷ ý;Tï0µºúïÏÍŠ–Ë"Ì£Ø.ýv…yi¼ÂûU;n’"PõóÌ«$ŒþsWÚ— ˜5£€«ÄpžðAéÿƒgž†pv ^Í=Û¸ E™ÍZpþ ×, ³´´+àâbs»Û4®Â.Ë»d9¢•äiði§¿PojÏ—ŽGØÀÑ’,5¾D= hÐyÔ²ëK^D®ä™xǬc°µá8¬H,’0Í ;ñ$'Úc¯TO{4 ÍýZ€ê†ËE5V —W=œ¥nQ>ÁQõj”Z}w–m¯áͯ˜é#.²°Hž±y ä+Ð0ÛÀ÷ilµ¢æEŽšZÆ=3ë¼ú[í^©F1#€;mT(y0²éj8†Ø¤xÆçÏþö{òzê‡QÙ¥–uË’¿C=óÚ¡ Íyã4¬ÒÔ?î#¬L¢2F©°‰›áWv·ŽíMù ¢4CCÆ'?K²Ãè@ß“•Ô°<ñh#µÜËÉÎÝÿv£úî…+!ø˹Ù“J$€vD0iu!ò^Œmc]Îl†I3= ò¤Fº¦‘úèø5¦|›o£óêé{õÏ„$c°N[9OrlÌÝK+–e½ç>Üøv펣<à ‰¤xÛdÒ"xýßk{9«^S÷½š.C?µûŽÇ§“±cÓöí0‰8ÏT8ç³ÑÈk¬Ìf™'3PŒ`£%§ƒE ‘tn Ÿ!p­"Lþ!®Ðkª"˜.ª†VY‚¨J!?l+]‡˜oð¸"¡ã"Ý9.v½ãвÎ׉‡(ê` 4JÕ0ܲE‹©%{¢¥Æ£`ôé$™…¶»6jõJØÃEéÙé³Ö…¨‚fI)t ¼rãÌþ°Xýnè¶×¸A¬‡ ƒ»ÀGÃhøåZkêš»µ‹B•…s%ä \ql'Âzî 9ÊÉNŽg¼©Däw`^7ÔñÎc€Ô@>_¨£Û3™´kP®1kò’§S[Ÿ¨¹0Ƙ=!ŽÉàûmN]4Ú@•šÈ-ób•ñ¶€2†|Oû¼îw‘ô9Ãj´»Þ¦»´ìÅw“A1ã!õ¼Ê†l¿QÏ#p1íñ–®¥ÍðNF6àáùdûso¶.­LÐðlªŒ|›‚¾gSÐ'h >0ª²Xuã軽·YO¦¦©ç¨»}ÍoaPG‰G§ëÕJV僱ï%9­M2£ÓÙ!Ñ<ýãÜО(›×gU%œ)“Œ¥Ââ`Ifk*Û3EîÑpkm02¹2_J~@ÑPYñ0P'"Jê:Òºh \3¸G†\Í0[Ä4, nY¦!jÈ«V t÷êÃÏ?2/;ŒI2úcÇòá$¸mãW§1dì¤4 ·L’ dþ¬_·$ô×{Õ;&sö !ëZR¶2~áUöprªÛ–] JèoŽÊ¬Â¤¨¾.ÝîY×å]È ÑŽ­ C¯—×Ð+ÆmãGN[Å’',"/—®åTó×Ä^¹{…@oòÅ‘Ë ò§7äg®¥ ¿xZƒIÜ¿˜èâ‰ù÷wTF¯“úƒ(ìå`£öÖW Ik¦ÔW­Ödë¹z }Å#f(&÷„3f|%f/Eˆ´D_‚ $†~Ø—ä™=ƒ«ž&$è"ÃÕB¼§“à$°u.JõA_òˆ9΢—ȲQ‡UÔ•&ƒÅ„ù&‚/RLz†¯¤oC CRôÆk¨nLI´Òœ¹"Çö,ÇKr$ÓQ¡ñû°§ $ˆ3òÊÛXx Ç„¸rHÂ6)§Clø&‰7¥bŸŸÀ¨S›ª€C¯ Ôƒ¦hø~Ñͦànãâyè:î'ìý¤>ŠÄ¾sÀ•yÂâ3uB éac $RÏl<çj®Á<'šëµO‡HZè†ü-à£R<öÔêQOVFÖ˜3™w£ðŒ¹N—Þ¹(Þ*‹Áä Æ†3·ŽW( º¶W‹øyK·üXsj»9èÐwEëÂçܘ¹ TŽÏa»H»!À]Ž1â™8¹x +Ã4¯ì«—:˜Ú¦U}ýe¥‚Nª°LoÏ[ν øÐ½‹¨â{ÇV?pCÒŒÔgHgÚK%Ĭ„¨ò•€l<%iÙ·: Õ§aR—D•¾ “­÷`Êq®ŠÍt.¿|1[Âñl…"²bù^mfèá¨ô‰RGÁ†Pb°:ó"¸&GQ¦êë4ñ2~5+Ù܉¦ˆ´Li‹2ÏÙÕhtµ8!j,Rê€9 döâµ5dÎ…§[Rœ¥Xdæ-ÙÐ×Óó×̃7jùIŽ›¸4¶$ ˆxº(øoÝãH„q\ºæˆÁ¼çÕT²Î¿@ ¡¶½-^åDª2ó#všE}C¼¬å¯Ñ¼(/·}ùö¶ Xfÿ¹w¾Y!|bÍFäÚ»|T…‘˜$š†ƒFâãüšûæaœÏ sKOÅ[L´épW1XT>a²ºU…Y”;׈[7_!Bàµ*‚©Ãâà-kPX .r»Ñ£(!`‹Å³9D…k­)eÇP[¼eÙ¡ùoŒì<ó_‘‘Ð.׎ä¹ä9°¶7ýHÁ“¨‰|ƕՠð™À°,ßú$ûžýMHžw¾vºÅ «ð‰V­T±Úà:™ƒ*ô˜qÛËÙ¾{õ\é¹TÔÇ;[³`Î\ B›‚¼[‡öje*§óûû\"¨¦ÿêÁÍÀ>nµÜw„X3tPÀ~>{ç ¿!™„ÃÙ-¯vÞz×A $Q&ôLµ‚ݧÓ@Ã&©$¿ñs9m Lm=m‡—àUãD®ëºf h|jç·™*áµJY[•²Øw5â°Ç7ö¦;3̳a7`·þ£°s"§M^¸=kší&"‘mãXó ÙÊ^Ë#31 |ívî ¬µçóµW>"Z<™`ݶx\§µÚìïM2ôKÞêóvƒ±«b?­å¨à¢> endobj 3096 0 obj << /D [3094 0 R /XYZ 89 721 null] >> endobj 778 0 obj << /D [3094 0 R /XYZ 90 593.927 null] >> endobj 3093 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3100 0 obj << /Length 2581 /Filter /FlateDecode >> stream xÚ­Ë’Ü6î>_¡[4UiEïÇÑk½Þªu²öTr°sPKìi–%Q‘ÔžíýúÅ‹j©[NâTNA@¼HùΓã;oîþñx÷Ãë,v ¯HÃÔy<8…ïd~îùqâ<ÖÎG÷å?_üôøðþ~&¾›z÷»$õÝ_Þ¿}|ûî #_ðçñ¾ˆÜïÞüÈÃW?¿}ùÀðXŸûîÏðùõñ_?¼NÂņ1î–¤ í„>Ýù"¡³‹òÈ âÂÙ…,Š˜ìñ¨€w˜ºyÒUÙð V÷aâ~ÑMf®?Õ ô“áïQ×BdÆ´åçûÀw-ÝPvc_ª›,Ëí€de51"?tßd3!´dºíÍ8ê}³Ú9sGÕÕŒ©LÛ–]=¢Â ì.¼"»#uû®éKÝpü¬§£9ÁžQT¸­©õᬻ'ž+;ƒ*o/„™NÈø3ºfk`<ÂMÍs{¡iËZ ÞŸy ðŒÆ1[]XÞÕç^œÂà¡P ÃdE~ê/܆—ˆÓL¥nàƒÜUµ¸X´ R/.2Küed’;4ËKò¤:5€SÝzkxI<Ó}Jg‘=£Â5üæÖ…ÛA°ÑÀG<Å$…%ÉÝÇW~ü7ƒz”9Ãã~0÷š¬v¬§ªyz4ÍiÒ¦sîR?u_#1˜m¿Ë /÷ 9”ÅUHðß²íÉ%óÄÕÝ8©½1I2D>z"OªvkÐB1ÎfójЂ° ÑóŠU”G^„vAÕ”ã(»uudpT9ݮ̅°§AƒªÍòÆèÅ8¼‚ …?“Y‚Ì÷²"X{fÉé»*ïáó…Õ‘!ô¯2‹G3™Ê4<âÐ(Bp¬ÑÄ-¤%Œu'„Ì/ hÉ,þeqœ/ë/(‰©ÊIWLQºøÂh’uÃXl±µ5b sC>ˆ¥¸h…ääªËé k¬~ YX ûò|µÀj‰°éš3ó=–v_ÃßÏAÆÏ—ÕêÍÉ’®„‘oÃVMÀÑq"²àU­0„„ŽyØh„U´‹ÁwÞAå”Js¬<†è4^-]Y}-Îa0í–B§‘Ý,¡DŒŸ‹£Ã ? P?fçXœ Fêƒ|'þr¨ëq’y#ó•9 £òæ È…¢»0ö ?ƒoî%AÎBBæôÂû]àûPÒÕ'ß»YêZqvª¬8‹rvþ¨zî¥Âô¡$7 £µÙ`Ì®†äÌ0n@†è°à»pYƉ²ã¥{áÅ& óªN‰ˆÝŸùË'@Ù÷ t˜HQ f1fªNIe>‹<ƒHhv›ÞZ6àîiâR“`¿BgÅ pTRc‰@ˆy±? æi(ÛV ßÝ'‰+ W!¢ho™RB ¯Üú4¤¥Ú>G@`'ÁÐuè¥×•›Ç ÀQâx­07d~"GB="ŸÌBa_Ú ÀR®ôÓ«\éc–éÕLM6ðm1DUöå^7P¢(/úRüÔ’`njÎGƒ‚ ñe¹•î² Ú1nÒ¸>l¨v8uÕY,)Ñ¥b‰Ï!@Êäá†Ïál9É—?5ÈPv5ˆì„ŠëY$!ʰÔÀp–¡ÍÏ<7¨ßNz°{ìÏ«+¿ö¶Š( ŽµÃ!7u­oàŠAN d|@KÆÀRÆP¯-/)ˆåóªÀÌOJdy< ³WW›.2óF?°È± xz ù4s©E¬/™Šƒj(kµ3”y¼b.&«%'0ÐÈ¢vËm7N–W;d³ÕÀ¤•’u¶UØlа Þ,㜘zNü\² æÚ¸ AÅõFFV__g[âÊ&ºö‰!NsÎ’æâ("ˆ •È¢¸¾ÊÄ–b éëFºD.¥ÉⵈËÐÀÁðN ¤é¾Ã·©ûÆTŸ¯jÖ*Ÿó}Åú­Âãs½ô˜=^OãÔIB¹~qH<ùPƒ=Ñì¨YÆ•¾‹G™±§–£ÙRÌ3¬/óõ=“†6C7­–9Š‘tù#25 FªÚv”0foKP Ë’Ë«²:eéo[1÷È©÷6¶.·ºjbº¸ÕyÜë>@7ZCÏü·8y÷…²«Û“D]5JèNj«gš/¨¶é±½SÓ\»Å)¨kïP7¼ðµî@Á(ÿs>Rí'áj@®¤ã•›Z«`y«=ü?/Äiü)N㵿‰å¸’ó€íÞÄ7š­´¶\yXº•>ý}éßvöÙa%û¯D†/ÆŒ_}\a×û£˜ä[x¯m c빿2‡AF§ÃîÔî)[lÀ{"°ðÈãÉrÓa3­¾ŠŸy†|1È.¤«÷ÂÈÇD9þ ª‘Jëá|ž25Û`N ÐØ®6_=/ÀïW^ÖÃÕ˜¬ìéÝ$'2Ê"‡0òÔ÷f˜#d¾ú½åɘûÅÕíðhƒ-ˆ%7*´ím\Û„õðx÷›xSà@ i>sŠÈ “̩ڻ¿úN s ´¹óL”­“BJOñYã|¸ûÏßÏ" R'¼À~…õkaA¿W®f…—<ÿ,ø¸Ù¶+Û +DQäeyüíûßZ!÷¡òÅß`´öû º´¯ endstream endobj 3099 0 obj << /Type /Page /Contents 3100 0 R /Resources 3098 0 R /MediaBox [0 0 612 792] /Parent 3103 0 R /Annots [ 3097 0 R ] >> endobj 3097 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [285.924 182.035 307.841 192.939] /A << /S /GoTo /D (subsection.6.1.5) >> >> endobj 3101 0 obj << /D [3099 0 R /XYZ 89 721 null] >> endobj 782 0 obj << /D [3099 0 R /XYZ 90 559.744 null] >> endobj 786 0 obj << /D [3099 0 R /XYZ 90 293.368 null] >> endobj 790 0 obj << /D [3099 0 R /XYZ 90 168.461 null] >> endobj 3102 0 obj << /D [3099 0 R /XYZ 90 93.456 null] >> endobj 3098 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3107 0 obj << /Length 2183 /Filter /FlateDecode >> stream xÚ­Z[w›Æ~÷¯`­ó‚V«É\˜²úâØrŽz\;µå4]I°@6+T@IôïÏžÙƒ2–+ÓÏ}_¾Ù·A¦ÎƒC÷'ïf'o.|Ï I¨¸rf '¤ŽOB=éÌbç³{ößÓ³ÉÍhÌ%u¥¢î7ÓÙôê=Nžb3…Â=½zÃóÉÇéÙû·p> îGhþšýúæBòCOs“ Ä1ügzÓ µNf'Ÿ0èR‡9\…„2ßQ%<`Î|yòù/êİø«C‰ç»Ùºt”4Õ̹=ù}gÊQ* Œû‡hÀvFB)- VGvzDPÇgÄgjp}eè.„ ~གiòÊ'!^­ü¿AÃ(%ñ}1@N„\d­Åïââ€G3íQhH0úA¤aôñø0ü€ƒ,žO(µž]^ßN@x,ÛíçÃFÂà'¡°c€ñBExDIa-ðÃäͶG{AI üa¤a d®¡6è¡sNx"„Ó+ô•N Ïy4ó€†dbi ©"B†Ã€ô¤`ªI¿“O³›Ó‘GݳC@ͼ ÁÓxÈ44R*¥r E2Â}MË'2äˆäo×#(E>ê²åY gþ P5È¡4 ‚’l°Ez+$¤.òÖVzçïþ<€äÑÜ{Pž–f†Ò0Hê6 š¤"ð>'A`+Å‹‘ïAù,¥{w9 ù¡Xy¼ =Xè6V8¥að” œ7°pdDjËT”HÁš¤3=áÑl{Ô¾'‡A8†ÐóÈ¿’m$‚'‰ï#‚7:ÕÜ]]Ž’Ç2ïÁHˆ Ãq ƒ£€šE |”RHp[Bž^žÞüv£ùöè4¨VC¥a0d!„´ï@xÐ{*t$‡·‰µÅóéíé»Ë™ã÷4T0ì-8”†‘B©Â‡z´„`ˆ°1û¼»úßÕõHH÷Ošã¹÷ 4İBühÍG"ÚþœÕÁ„QÏ}OB+-&³Ç?LåÑ2©°»®’{Ii—£§î·“®)îõà[Z¬í±eåiþ@ðÖߠÄ5ï1CÞc®ß¶zRÄ#ÞhÌ(¥îy‚Ôæ–z•”#fRº(Wfi6bÖ¶ITÙCó"ÞÄɽvýð£žÏlÄ ÀL[%Ý8ñF=PßÇ‹ Ò[¾k¡Šò«Ý¶^­Š²®pTäÛÓµY`Û’^µôºEéÍL#Ȫ,æIUu£nØò¸yOS£Û]o[' ëV'‹XB€(4{L«6Î4“o;Ÿ"Æ¡–À `åöÆHwÏ籤tga/Éb÷EsŪN‹Ü¨5îãwWD¸[@áyè.ôåDóFX³– Š4®šý vÖUôàItgmžEU•Σ ‡_8ÿIq²Àýç“wš×Ý{XðpKUo2{øûc:Äî2újÌØJ¨1Ç…Ìܲî•IG÷Y²sžŽ¹r¨˜¹jy aÖoÚè¾è@vЇðA™DFźw¨öîÖwΠG6Ý‹U[¶fàÍ ÜFvî“$ÇÍi^—E¼žë+Ô+_¨¤qRGiÖ̤9¶óÇhUƒÝê…Ù·|p°sc‚—&§ˆØ‹iš"Ó¿ý@aB&†§åõuOl¯CkYa¼^á<Æ{˜Ì´‚#æÍ&££fâÅëíi«:;k¼”ïêCv/Gï‹Öu±SÒŽµ±¸Æ±]³>$Z>$(Tbëgó"¯ 0‚§ÎR ýf_A| Ü“æ´6…åÕȱ #p„]Œ’å}ÇÆß˜0ƪ¯G÷Ѫ™è†wBãM¶´xìy¤9À°1ISwxÃ,ËŠ5’ÚòÌ“3ƒ§$MÐ4meÍÄV±vR¶JoÕ¤¾e Žš0ß`®ÖÔCM©B®°4½º¸&ØÝW¦6¨.t<×jU¸Ú­ñõŒ«°5ÂÛÕ“&€*‹‘^3Jé™]PW¨’^ÝÍ´ãºêÖƒzc·ÞÞ®£!«%\1és'(ÐöP{-°`ï^êºj™Y·¬…ëA·Ì„òNö¶Ó<µ6a³½\”y^–‹­#v;㨶½b±Mô݉­°-ÔŒC *GŒAU~úôé´,£Í>Ýz³Â¸»“šZµÔ‘j½JØ·o÷ýñãdz‚>ƒRž½½pQÊ4?Z¥Wj‚Õ@éB´ÐYG¯(Í3ÛÇç¶[§Æ/¿à»B˜Š.¤ÍÉŒLd@WɊȾ 5‚ITCáËà©áR1û<0KEã ÛÝøѽ,Í1$ØÈh:9¶FêÑr•Ù¨Ç ›wT×(žøe÷…Øû-!uTÐ÷/-~èo?~ˆ0 ’>ÿõãÿƒ•GÛ endstream endobj 3106 0 obj << /Type /Page /Contents 3107 0 R /Resources 3105 0 R /MediaBox [0 0 612 792] /Parent 3103 0 R /Annots [ 3104 0 R ] >> endobj 3104 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [470.705 283.683 485.151 294.587] /A << /S /GoTo /D (section.6.3) >> >> endobj 3108 0 obj << /D [3106 0 R /XYZ 89 721 null] >> endobj 794 0 obj << /D [3106 0 R /XYZ 90 438.228 null] >> endobj 3109 0 obj << /D [3106 0 R /XYZ 90 389.661 null] >> endobj 798 0 obj << /D [3106 0 R /XYZ 90 339.225 null] >> endobj 802 0 obj << /D [3106 0 R /XYZ 90 222.288 null] >> endobj 3105 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3113 0 obj << /Length 1576 /Filter /FlateDecode >> stream xÚ•W[sœ6~ß_Á¸/l ;ÍŒë8®;­›Æ[çÁñd0à]&,l@kw›?ß#‰]0ë$/èèrîŸ:Ôš[Ô:Ÿü:›¼|úVLâÀ ¬Ù½S+¤¡>·f™ucŸþvònvö~긜Ú™:< ö‡÷³‹Ës\<Áa6=ûäòü/œ¾9»¾8=Cú ø#j_Ãp;ûýå[îî(ô¥6€9Js]yhBµ…Ãñå[FwÙ{Ä ˜å¸!,zZ (ö)µòTÔÍ«V4E5=u¹ÆŽ¥æ0Fb®u #«u»øt—¤Ÿ?RNê*?bœËÛÇ%ëý\þ^®E“?£÷\ ´°YRÍ룣7ùÃuÒ\)Oš&Ù ×í¨ÀPó¶xèÕ«gCéÓi½}†^e娄X-:œÄaÔßaô¹”¹Çcž³.ÍîÀœQåÌ]5)¼¯ä–™(*íaÃ/8Ðc=7rI[ü—K•´âðPŽ£z é¾;½ôYǮ̗¹Ñ®Õ ÒãÞ·{"þäœÍ&_& Hj1y»9õˆVºœÜÜR+ƒu°•„qh=ªSKË‹#©¼’¥u5ù«DïÒ2ê“Ø÷-?r t:þ(ª/ UñEÖ©’¦ww${E*ÚÄI§"D(ø²sp ¡j4éÊR ôÆ ZòZqK«ôü]•ðæó(·Ï’t{ÞÈÂèX%BäM…“b¹Â»”ˆ¢6k­a”ªÐ®àQ˜#BŸA`Tcéêr)-Š"{¦ò†Æì0ÀôÀˆ)¢Ú L•%Ûý°ï ll}IZ&m»•£ÔÆPµ.… JþM¤ã³‘7¦~?º‚›¼z»•Þµ]K®D¾ZåÍŸµ¬Y²Ž¢ÌÑLO°h¬Í ¶3eµv\•÷FP¡0×Ð^&æ×r¿®R•ÏoÁO6AÜ+ÌA:–\)9ˆŒdØé$«™|H©š ô2‹:SÏ)5OJiÛ£ü$›Vs×e¹-% #/5bpå™F’òŒºaÍg™Ç °/îëô¥¢ÜàBáÖ(.G«†~JÆ ³¼M›âNA¦…^NÉJ`•Õo±fn!ñþ|bݨCa$$¼÷Š=Ò\¨dg@-°¸×£Ð êu©uÞ³†ñ‚µÎfž}‹DríªFR§®JËu6ôJJù—Å]“4SCÓªV.·O”ϵVßFïÈźÑþÍ (¯øÝTéà#0¹ûpÛ’ïzÿƒ°€ÿÈÛx(R½•û-*ó}Á-—2…¼ëP™ì~Ò¡ÕÏyõK"‹×ãêxªät ‹t¾×Á$Í<}Ä<ãœø,!$ôu·ü³Ú‘MYhí,ãÃÍm×Ï8,`Ä‹ý'­¬ÒÿõÛý*ïúU/Øö«ÿÀ›-cá¡–ùã–ée1?Ö&±˜pÎúø ÷ô®J«h6ã)n}®Aëê˜ 2È÷:¶玎 xKË”¨LȨîmð-j°mQµçµ,¥yóÉÈÜ/Êßùÿ±<ˆÜ endstream endobj 3112 0 obj << /Type /Page /Contents 3113 0 R /Resources 3111 0 R /MediaBox [0 0 612 792] /Parent 3103 0 R /Annots [ 3110 0 R ] >> endobj 3110 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.28 253.256 242.67 264.16] /A << /S /GoTo /D (subsubsection.6.1.7.5) >> >> endobj 3114 0 obj << /D [3112 0 R /XYZ 89 721 null] >> endobj 806 0 obj << /D [3112 0 R /XYZ 90 369.831 null] >> endobj 810 0 obj << /D [3112 0 R /XYZ 90 298.955 null] >> endobj 3111 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3119 0 obj << /Length 1872 /Filter /FlateDecode >> stream xÚ­XëoÜÆÿ®¿‚v€–‡øè}ðy (ŠìªHGº¤CX“+[y!yRœ ÿ{fvvïHŠ’\ ËÙǼ÷7³Ç¼[yoO¾YŸ¼~“„^d±ˆ½õ—1/aiÀÂÈ[Þ{ÿìï§ïÖç—‹¥ˆ˜‹e3ÿ_—ë‹ïßÒä) ëE&ýÓïßþ@ä·ç?_œÓ÷œO™ÿ3 Öÿxý&!J‹bPÇÈãBâ¦f5|ý†³áö¥Œ²@ÈÌ[Š&¥=-–1cÌÏ›}o>ý¯¾¢ñå¥VÅ'úîUžëÝ×ê_÷ºë_ŽO麨þ†Š€K΃,²þౕÔß.¿ît{§Ûëv_ÿÂ"?>&Y,%rýïìjjWsÕçì>ªâZUU“#ßÙƒ™=øÇh5¦UÁ€U<ï’3UÿÕÎ ª×Dmõ¶i?½xñâsÝ!øãRÎ+û²¾ýlVâ)/AZÌzéì‡ËoNW«óß0¢eSÓÊ_ôcNá“N‹¬9kUß6Žíjµk˺¿ÖN Ö†[ij³É㞺Թ.ïtaCBÃÔ²Ïöcúÿ IöTH$›s¡äöÌà‚ä•Võ~÷ä%‘bvÖ…½Õý¾5ނĖ §îBÜx¾>ùõ„Ã'ó8â\(à N¹—oOÞ`^óÀ2H²Ä»7»¶žÌÒ bN•wuò#áå¾8 ƒ, ½ÇA(R仲† %Rés„¿+’È¿¨ój_Ø¥~£ 6à—Ê€À°Ç, 63¨‰ª‡‡}¿0&* à `ê¯7eGRiš¤¹9EäVu½niªj5`•ø½=L;,‹N/Däß-xäëVU´¥sÚ¡Øî Ž1"%EGãˆUe×Shnh´‡‰°r ¢>~¢ÑyŹªíª¦ñ¦Ù×…;Nã{›÷öÖ&ÀåÛP e L|0Êr êHWÔ(ö9F5ŠLT…ðÏZm§0¨fOYw gn§Éºø¸¼Æ‚HóS_V´+¯T×Ñ:&º¢Ï.l¥{ƒ:<@‘‰ÿ›a‰ŽªvÁSÿ6e?ÆÉ5ñ‡[ÝošÂêØÙÈÌX»Uu¡z(°5LÀ»¹Úwš²> Ê„2·4^wJ ¢óf‹|ˆ¨ÈðetÁåÎÿ³à@fKêßot=ñÐQ0Ù|ü·Îû ³<Þîó^Á³1d>—4b Aƒ«^µ6¡"Ú<ÛØ½#3Þ©.M®£o 9|Ì=@ZU•¿ïË~sdM—Z.µH£€%‰»Õ<‘“CÎ$ˆD 2éÎØðš°J™2£39@²Ð428‚BȘwX+6VãÇ0˜HãmÂQÑ€ECcº"qQT¦¶ÐDÕ4;»dŒvœgŒt›áÄèAK5g³ò±Í7‰ˆ%auÓn›ð;W~…qNœàh;eœŒÓc×6¹î,øt›f_ÙhÖCÈ£)*HvïMÛl]dK;‡ùþ\&J. ÿ[šÖ‡›2JéŸQ‹ƒ3&%ç¾FÙ®èh±Ø[xÍq¤öØÆÎ$®é¶mÚEÈüW!EÙí*õÉŠqç»NÝŽ˜r›0÷¿µÛëâqä MËþ¹K•›ºCy ݦL™KˆÅ¦G j ¢† GN¡©ûMI<¤Ÿ/¸6p_ÁWaëTžïm*ö-á'~¯8ÐÇ+ÄàŠ§Ï?¹ö\Oq;νÃF“f¦Æàid»n»¹ögÀ4Yb8Ï×LU%²Vî\ðŸä,ùˆí5v¼•SšošV­²H1¬ê9„ü0ùTHèÎR1ŠIs9 "xÏNàÂõ^d¨ Ç%tq"áæq™F)€Æ.€æã«oílüö ¬Ü™úÕ®V¦x_ߨÜMãQÆ…н)ôžÄÿÔ€h 9Øåmù‹¡d‘ÅÛª¤Úa¯† u¯ÐÃЇéaÌæ8àAˆi7cî:„éË/‰ç0Í‘÷ã#À9]XmÔ,Vƒž:OŽMž…i.=ªá>ÀìØv¬ÇiÒÅÜ:m[‘…A¦ã´$H\וŒíCúx(·»JouÝ›v#!‹$~üø(‘6¹ ã1WIxÙ>RÍãc•Bd˜ñ—Ag„œN’id3´½iªÊ ¨zoµˆ© ‚3ªvË~pX<„f…~€Ý<£¾ƹ`Cc‘Õ6ÖQ y8iC o¸ûð!̻鑓9hÛ%¡vuàä!r†ªSð¦|{À×åa7”mÓ(ŸHS°^ïv½¶Mïæ"‚Ïzaò˜œú?¼0§,Í‹sü²FpûW}ø~qxË™÷½})}=ûWÇükº1ÚÄ|zܽµç&Ýûû®)íöDË»(9„ì)«È²úcnqöü“ !êÚµƒì¯Èœ¢9«Õ:Ã-«•ë®_×^¢Vÿf°žKç¤gÏýõð'ÃÐ~Ð endstream endobj 3118 0 obj << /Type /Page /Contents 3119 0 R /Resources 3117 0 R /MediaBox [0 0 612 792] /Parent 3103 0 R /Annots [ 3115 0 R 3116 0 R ] >> endobj 3115 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [282.427 403.376 289.401 412.223] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3116 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.496 211.319 216.886 222.223] /A << /S /GoTo /D (subsubsection.6.1.7.2) >> >> endobj 3120 0 obj << /D [3118 0 R /XYZ 89 721 null] >> endobj 814 0 obj << /D [3118 0 R /XYZ 90 244.943 null] >> endobj 3117 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3124 0 obj << /Length 1668 /Filter /FlateDecode >> stream xÚÅX[oÛ6~÷¯0`“˜!)‘”Ò®@–¤YŠ®Ý¯{h‹B–™Xƒ-y’œ +ºß¾Ã›u±Ü¸C‡=‘âåœïž«°wëaïbôãttô\„^ŒbN¹7½ñbì !2o:÷Þú§?ü2=¿O(Ã>Gã ãØÿýêrzùêÂ,ž˜a:ŽÿäÕÅkóyvþæòôÜ̯á~„ý70¼Ÿ¾8zÎh‹a¨¸1p4?BCuh„-Âþx>ý9"0ÅQ`y„ލ—®Foßcoë/<ŒD,¼{}jåq„V–ÞõèW#tÁ!ŠÃÐã,B„‡ÉË,—?1Ãñxì_æér3·[õB:ñAÂ$¿-Ìç*©jYšyÖ¾ðcº”JDÀ3!ÅŒõùÑøùõZ–«¢.Êt™T•YnMçRñʳ:+òÃx"ô…€7c‘Zʤ¶;šµš\Ö?+Ö§†ŸZ®²üv)kÅL}Î̘&Ë%ì¨ægcâוµ‚ õ”ˆ†ÂYA°l…„ÉöÐJÖ‹bn¸$¹TJV=Ä¥¬7e.çZô ¢8êj`]d¹~±s`_jÆ, X:»–åݘ0ß)fÈ´‡…ð¯ä $“«™Û­Imf ¾!¥ŸFCƒÕ›b{PšmxaÊü»,µ ×I xr hµ^Ê•Ìëļ¦ºÐ!1ð¦ÖB¬=ªÇÚ1‘¬k*  ýyŸÕ‹ÌÚLb†ÊdÈ· Y, QÈù—„¬>IÂîøP1󥈅V%¾ÙÆ _Ok¨ÐâÙÙСÅÀÒi™"ÔÞþµÐ^ûØÙäf“ Ýàö†UuŸÉi³|l†õf¶ÌR3Ÿ*±ŽÏ¤ò¢S÷Ò}b”ÝŒì¦!{Œê"‰ ¢›&‰Ðf•ïõC±ˆ¼Ö² xï0Ãi‘Wµ¡™.£TW<$‡P ä‰ r¤´ˆ‰.t‚¿»@`XAjy*üŠ!¢Q÷Í ±þÞáê®P?8²æû3¼úíåË'Ÿ†^… Ú-q†».‹µœ>) -¬ATU]êø¢|ÛHاÁþÝnµðY¥rËù®ÈæÖvŠÕ R⇛$Îݧé;×!õ”ÙlSË6;©¦O­“ÀMB¨ŠDl¤ †¥±ËÏvt¸ÇL£Aœñã¾IñŽ,s Ú‚´|¬‰o’òZ¿óIY&švÀ(âB|©ãA ÉU¾êàrøÓ“¡PH—:ãýdÀéC!A(tWÝöjký<·:(nâµ^iº&!bÐhÏ[Š6í£ƒR âP±}•꜄qüWçA‡ßt‘Uÿ¦®²E[¯|",†ò)>´|‚Ήo˧îSN(Ë""]Ck¤à)ZÒžÂ)Ë -ûuS«žf•¹ voîµ}å~<ÑÉ.„ÿ¬Ó®¨#ÊjÕ=ª¢ÅQøXÇÀ ¶å¨ê(Ò¸!dóÎ.±êÂ0î¶•j‰¡ŠÄJ¼vÑ”vÕ¥½¨»XL+ëLºWX«`¯ÀÇ] ëFÄZRvÓ3vÓ™t-1/ìB²„–nþ`MVEÂr£ò"2ÀxÚË'dkôÒ¸¹?\þ¹›B'X5ªû4p÷Eã3¢Á´ƒf`àεÙÍì©m7ŸZ‘úv’7&‘oÏ4}îÔ©×œÍ ¿ØÔU6·êËöu¾|h¶wM&ˆ¡Øæü㛄X¹sW)®k¥Q½a¡Þó¾²ßfØT:8ÁLµ¡jLm®åfl $õ¥œEß0ñHݱò„Zvi½µa[ÅçòÖê«‹‘)Û!VÞwAÜÊÚLæ²N²¥Ã<u:Þ–KëW€9_e·ùPâ³MîAÆÇzqWºÀ´U|¹6ÞZqÔx‚óCs×zL9wé ¶)¢’î^ÝÝP%¨5þM¹í;Á.SÙÄJˆbÉ2û«Õ®IõHb!ݘ|¶óÿ¦¸ùlîÀ…dk“½pÀ<´¡AïgŠ<$R5ß‹S|Mœ¦ÖSì·êÍ´> endobj 3121 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [336.331 130.917 348.286 139.763] /A << /S /GoTo /D (cite.Patterns) >> >> endobj 3125 0 obj << /D [3123 0 R /XYZ 89 721 null] >> endobj 818 0 obj << /D [3123 0 R /XYZ 90 593.617 null] >> endobj 822 0 obj << /D [3123 0 R /XYZ 90 572.674 null] >> endobj 3122 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3128 0 obj << /Length 957 /Filter /FlateDecode >> stream xÚµVmoÛ6þî_ÁvÀ ËWQr»iêd Ò´K´îCšÌÆd)“”dCÑÿ>R$m+¦µh?‘:òîž;>w:®‡£×éèù` ID"~ Å1Òøìÿ¶÷>žCÂQÁqÈ#üyv”ážYÒqBƒ½ÓÃwæóÍôÃÑþÔìÏ•~Œ‚j¹LŸp²æio^"0Sòc€ H¸ïo-MbÈ‘Ž¤ç£ß7LöÉÆh=x̘2ÁAD((³)PqÇOE•—·3L¤¾^vYu]Ãù+ WÙ 1†‰JD¯BBûtÔo§íäÍluW7ÍYMö¸f^fm»Eû„‘µYe ÙÞd¹5znl¾Õ6}‘ «öÙg3ö «±ny_£í/+~AN¥³ôù¥?á0¬‰7 L&WEÕªwpà5Ëé''/z!¦²˜ aäÉñ6 “ɆèqÔv"´qù³–à‰×.±vSM˜Éä¼+r¹²¢}™ÆtWª±âÕžNÞ]§gÓ½·–/ÍútZur…p3ý½8¯U›Û\IŸõe5+_x]{ù„£GÈìîGàqœüâ=½ÉM|w ÚÍUŠUCßÈÕ¢*:ýà}„6ØyfŠŒ ý˺^—” )'0âAxs±U|2(4¨‡…´VIütv¨µã÷¢ø)4†®ù×Û!¹=÷këî„ôñz‘õõââ÷R§çï •¼ß¾e)úíÆ­—b$±§yÖåóURÿÊfWYYÖù¶§hW(vÁtó¦¾÷£d0êžÈêZH#»Û¦2¸—yó»ãÞRsáD^ñC‹Ê Õé^U…·ëÓxWUÐäûTC»ª‚aÇÙ4ºãZ,ìZÕ¶QèÞQdeÑêQI žöz‰C ¶ÖÃvocÎëlËKÿÒ|>) endstream endobj 3127 0 obj << /Type /Page /Contents 3128 0 R /Resources 3126 0 R /MediaBox [0 0 612 792] /Parent 3103 0 R >> endobj 3129 0 obj << /D [3127 0 R /XYZ 89 721 null] >> endobj 826 0 obj << /D [3127 0 R /XYZ 90 690.045 null] >> endobj 3126 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3133 0 obj << /Length 2313 /Filter /FlateDecode >> stream xÚ¥]sÛ¸ñÝ¿‚“‡Õ‹x ðÃít&u|©;¾8MÔÜÃõFC“°ÅF"U’Šëvúß»‹]ðËt|>h,Ø]ì7$œ{G8ïÎþ¸9ûþ‡X:©—FAälîœT8±HkhbâWà?“ûü8õÂäeŽ¢dÊ:ŽtÍöz&+Ϋ÷•UõoÆîu~^è¯[¬¹¶…åY\´j_}ƒ“OÒÌÈòMFßâÂßæ‡b ùª~Ð…µ¡Å£b8* è(¶²9JÂaà?‹«é¯ ~,½H„ÿKh4¡pZþ*Ã|@µ0m)dˆ ?ØN¤±{Ó²šwüZäQË4Z¦#å,¿¯°$¥ÈEËýƒD’r”aßK~ A<¨  ¥Ìó¨kS¦!aºç«Ìqo©êék“ÄÖ&P ™‡ôlűZŠ[-ͺÇc.xtGõSRš±­ M»ÓÖ 8îßÚi©µî+®‹6h7î[šX¡ÅBŒNF¥N,+ˆia=+‰œ²’` ØæMyäŠKú!—©ˆÚ÷¯0¡×xpôíãÀ •±*.¾ûŽT£™ÊšmŠYP¶(·•x_ƒ%ÐÓØø…2[¸ä2èL©ùŠï…G)Tž/Ö¸P/ø|*ÕÈ9pÝPÊiÜþ]ç¬ÙSK5o> endobj 3134 0 obj << /D [3132 0 R /XYZ 89 721 null] >> endobj 830 0 obj << /D [3132 0 R /XYZ 90 519.893 null] >> endobj 3131 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3138 0 obj << /Length 2075 /Filter /FlateDecode >> stream xÚµXÝoã6Ï_!ìC!ßÖ,I}g{Ò$Íåpm÷6ÞíÃv(ë*K®$' ýß;ÃÉ’­ô6îÅ"‡Ãáp8¿±tîé\|»8ùê»Èw‘„:t+'‘N$c!ýÀYdÎG÷ügo—ïfsH7³yJ÷§w׋뮈xFŸÅ,ñܳ®~¤éÅå‡ëóKßÀþXºàóiñϯ¾ ôà@O BPÇž§t„L'’5tæÃ\G°É#¶Úüº3Mk2ÐÈ5*áIé.Ó¦ÍË{œ(7oˆXš¥iš´~"r[¹i«Ú0iÝñn«¼lMM䔉)MGk^Û˜v]eDªVTC„ 3Óû/Íõf[Ðâ²H›ÆÞTÁ=¥Sß;4xwub- /Òžµ …§Ç¡ŠèúÞÈF‡*öù€] ;XRKÈÄ™+%’€x±Þ¡æ,f‘t èz^m6i™]—?îÚ¡Þ4¬Ê¦­wK°#(­S0™Hº?Ë@6†÷¥ü-ò’ÏS0(bÍYäŸYºíÝÛÚ.âÕäøNwÀ©Cß53¸¿áYîÀYˆŠu¸ËµYþB¤|ÅKkÞ¹¤‹ójCÒ¢¨ð%­ÛyãÑÚžgàlH®Êâé™#2³š)p ]ÑÒÖ;³NgZ‚£ A‘-Øi2qÍ´@VÊZЗCÙ¼@Ì*c—•[V-‘V»âg)uQДŒëc°˜¬Á0• *T>¿”?*Ü_‘ü¦)—âÊïãÊÆêØéz´Æ¯m×&.Ü¿<¼¨2ø’æ*<Ž2X´ÞŠ·‘ûÓڔęòb÷Æ8±Š"±6©õdÜ5pº:Ìø$8C¸&Ć_ÂÄÓvÃð!Ý"/·M˜ÉÅ`Píڞ؇QCóöik˜½æA†Ë%Þ¾ª« 3¯™e¯$ÎÎ_¿¦ÇïøAy9’ƒ,JëP*&¥Cá‹Xø³¹’˜ Ö½"]hôÛUŠ™à‰èüRÇém‹0Þ'âñ<*ÎåŠ0qıØP ­û"ÒûIä»këm†¢¡Û‡ûŒ%ça¬Ýk^Ëy_ʬ½—F”Bð»Àº––÷Õé)»ß‡™RÇê›¶Ç9«ëô‰X³´%ŸžÇJø¾?öìÇu¾\ƒé¢˜2IñK!ë›æ%¨L£"oZb^Ù”$ 9u/ «äfv•wæºÓ²“ˆ±ô§G6¦~°i”OÙÖ„?——ø]"NÝEbweZ¸ÛD8OxmoPv/0Ú]Ú1ªwÝ÷rqò+—O…À%ЉðÀq–›“Ÿ¤“ÎQ9–kãxI %¥pnNþ}$Ò"%‡®¥”/9~ +Á ðPå`ÚF7­ÙnMý}zަ?=ÍÌÐk)™—hä_ÛÜ^˜‡cwAKù¾Á^"òùٕ̿@$Qä Èp ÚüvÛÖ6ãS©‡ ó½±¹5ëüß©·ð¦2„»‡ºZï ¹¤&Dœåôù;}äžMŸ^óo SÞ·kÜŽ:¾É_¿îu=P$à3'µ A4.^\~ûþêöfñîòì{>”O}uaÈmqB‘‚£S^3£>öhxc6·whîØÌý1ÿ4–iʬxC ÁÙâèoES÷Šù^ì1x€Øîšõí]ºüµ,Íã±›áÆû—ý= rŠHë¿à6püØ×™!R”nB·œ#BØ;RXIÖaMgJvé÷m^€c¿oÌÅ{» Esôîìk B*±üm[Õí-™ÅÒÙc¯ë„5•fåLјIï¥g L¬¤ˆ=ÿ…®22/™P}¬ôb]Äý>©vÀüûg¥CH…Ð D/I‡6ý «’ýÀgtMˆä²ý/ â1Aûô9EôÓ·‚EUm—ز“ÚòFˆ¡+-WdÉQ‚!Å%‡±{naÙ¨ˆ%U*q«»ÿ˜%Ÿ]cq’Sú #ç B&ã^ ƒ‚l!1Q[ ¶+–[ÏTìÞï6¦ln±Yë°Ãj¬¹ô`à÷Ó:<Ïê ótØÍ¼‹¥>.9DÔv”DSwÛ¼ÞlP¾;&L”XÉUÔA»ÑÙÞ3}V_¶{óu€´Š€Z.ò%ãØ,ëÛꌉðŒØ'B]F¦‡îÍ2$¨9F¹§}t!?HÜKë´:<çÏinÎx¼É3žÐ£ÕEFLìZvß$~Õ^ÓïШÁ¦®K4–À°A,¢ðÃjîu†êí{óîÌ(žðâçãè3ñ}pˆïÓ€É^úç¿ ñ!\¤[ï Y¸&=VíeÙqG£6=vªHNé3p†½ÌhÐLÚ*Þ3¼……¬°xÆj™•© CaÙoÙëÖdÛ±Š[°­aµÓf²EÄø¡ÃwqA—ÿ<ˆ«‚HøIò‚¸J{" ƒ@\²ìÀ7°N>ØwùšáÀ°P匵@úgTÎoèÀ/@¼­Å{`ëA”„Að"dK%µ“õ °z[5y›W%ªû?†?…`:äÚÁ hš.Ì ÿßA™ok,ŠòV·Ð@mß<ƒp½!“h ¨Þ™•zuc¸}°©ªg¡ýó’®ðª×ûùV)*ñÝ\§w#&ÀA $ hŒ„¨AÁÿ_& jàó mø¨EœxÜÈÚ<þ"/צÎÛæÙ¿8ÿñ9Øßÿ¹ Ê«îÏ“.îÒI)SQ8°âñâ“ endstream endobj 3137 0 obj << /Type /Page /Contents 3138 0 R /Resources 3136 0 R /MediaBox [0 0 612 792] /Parent 3135 0 R /Annots [ 3130 0 R ] >> endobj 3130 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [505.329 676.929 511.506 689.693] /A << /S /GoTo /D (Hfootnote.10) >> >> endobj 3139 0 obj << /D [3137 0 R /XYZ 89 721 null] >> endobj 834 0 obj << /D [3137 0 R /XYZ 90 603.586 null] >> endobj 838 0 obj << /D [3137 0 R /XYZ 90 221.869 null] >> endobj 3140 0 obj << /D [3137 0 R /XYZ 104.346 55.923 null] >> endobj 3136 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3144 0 obj << /Length 1807 /Filter /FlateDecode >> stream xÚ­ÛnÛ6ôÝ_!lÀ 5#J¢.éV MÒ,ÃÖf‰×=´E Èt¬M–<‰NÝ·ïJ–d%H½˜Ô!yîW;Ö­åXg“×óÉÁ›Ð·bn`Í—VìX¡1ÇÖ|a}°:º˜Ÿ^Ng®pì€Mg"pì?.ÏççoÏxDË|{öÑÛ³wôyrúþüø”öWð>rì÷°|šÿ|ðF¸‚>R°£éq7ÂKÇpxð†;Ýë3OxÌ ¸5sCzô*œÎ¼Àqì…\^oªrÃj©®—eµNÔGG8ßÔi& •-³ô%œl*™fuVxæÃÿ^"a :ãœÅÂÈÌó¤¸-”ªô5Î=&@s3ÎBßpñ½>,C«NÔt†(~¤¥÷´¹’ꢬ3Œ ZdfÇ03!xŸ›Øp“¨Ù+äM¶¹Ò2ËJe²F,:Ø©¨‹;-2ugµb›m½º¾IÒ¿‰ÖܸN8ïAƒÆrOâkÅ>É@ý*Hý81o:ã.¼ûÒó‹f=OþžpØ:GçQÀ|ϳÒõäÃ'ÇZP²0­{}kmyqÄ„ƒ—[W“ß(z>ɟžo‰Àg‚ù~É þÌÛ£å–Ø·+™(s¢VfÓ5,AÒ<©kÚ&Å7¡]«²¾Ü”Y¡¤y¤Jº¨¦Ü^e5}”7‚éÜ-@ýUv3u{Kl…}œwS.l@PVS!l6fJ#ªëÚbÒF +vÂ(¡eޱMÑñ{-«¹œr€[¢ðà‡t/+j•©~Ì nL6yr#sC‚nq›b™€;g§ïÅŽ¢ ²^Ï°“|«ANÊ Z©vF­:¸GÀňЈd[hdf3mö ÃÆ|hx^¨ áG>¢£ïm´­Ñ°¸ëêAZ™éó>S+Ú!Ÿ”‰½Ž×»ŽËxØ$â~z™úÂî¦ בdÇÌuZk©Vå‚H–Ëi½é¸M›TA¡óÜAÒӑÞaÌhË\™èêf -ñã!»s9bÁ„Ï-Ïõ)_‚ÐÆ"nýHIpF¹²õ"<3y·::ðšÉ#½§-cZ$EH#)BIÒÎkÏÑ:Ÿ±}éÇî]ä2©å ÌF±]””¤0þu€s—b“s».׿¬J(Or;5O³Lˆò¢ …5•uT_IÇÉbA€½ÄÈÍ·ñØaá¢³Å¶ÊŠÛæÜ0²SwYj@ð‘ØUó|)×PŠWÒ¢²)4Hv?}Á"5QÔcûz™ ‚žˆÁ_ûÃä@eÄ5Mò\X©32îyõ¾#&~wÅÔß*©Ôl»1rÔÐÉ, ‘ÃãV¢Åâº'ÕÒ@K°Ð¤Ì&>÷È.>÷í“–áóõ&§C)x —xá¾¼£ì©A¥¹Šî‚€„¾ ùÞÀú.„çô®ƒrïŽgœ wåVÕÙÂÜÜI1î(±çîü`FžÕÀ{yåë|$ˆXèð¾0“5¥ÉlL¿…Uuk:¬Ë³‰nŠ»­>ѨҴY·™7+¨tC3)v¯ð6ä5›!Pцvµõ £3Z6»Ðà1¨ÜÁ¶¼IÍààŸw—2Y\ Lõ=^/蜜¡!±Ó¦çˆaÜÁÍø{Ó¼ ø¨:}t7—ÏjN=! Â_ÓœQêfµ?qßÂò<˜Œ„Q7]ó·Y‘æ[ô8ì½PXqÙêÕX÷᎛î»HÖ²Þ$©At¥äÚ_KÌö#eÎ7Ï>ácÀÀ¼0ªÖ“‚${vm‰ðCZ6Û›‚^·x ïïºêà‹<`f1Æwî¯μX<Çzò™êŠô´Ocìô+…µyöX4…Fí_šÊ¾äsgûÆ1O;ðÓÂØ+ð^:£iÚ|§Q„1Ì%Ñs,ð¬JÀˆaÿ_þ¦ˆÆ#oê CçMè 4º˜*œÔí“u/ïêÛø¸Šw¼­wYìí76¡Ë"Þþã7,%!EÄœ m‚Z³0Óe{9öv|=¾ºÍ‚Û4 ã‚QÃJV™2_˪\Ô×™a›ÊÓo6×X<Î™Ž¥j›]ŒùÑï•Ö endstream endobj 3143 0 obj << /Type /Page /Contents 3144 0 R /Resources 3142 0 R /MediaBox [0 0 612 792] /Parent 3135 0 R /Annots [ 3141 0 R ] >> endobj 3141 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [213.366 419.958 220.34 428.804] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3145 0 obj << /D [3143 0 R /XYZ 89 721 null] >> endobj 842 0 obj << /D [3143 0 R /XYZ 90 404.446 null] >> endobj 846 0 obj << /D [3143 0 R /XYZ 90 385.667 null] >> endobj 3142 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3149 0 obj << /Length 2135 /Filter /FlateDecode >> stream xÚ]s¤6òÝ¿‚§+æ*C@œÊU9^gÏWÉzÏ;•¬þõíJÆ(MiPÇÊ2C¤³5ô–QBHo) Ší§¢2Ä\HÏËH€;†oLÛ5ÇuW7Èx-…2¥Fô‘òEL#Ò‡’éác~ CY]QW©·4v€BûˆûRR¸mí]^–õ£ÙÌmYJ$uoº]½ P¼ñEKRLs«êŽ'fmÚ6ožð7ö‹f¬üv‡‘K&¸7»|!CÿcÁ籩 t"ÆÇRì¥Ù›ª3(9:”h朌9Ï‚AêÏ;ˆLŽOdl%ž}YNd7æ÷cÑXýZ<¯4as%ÓÕhÇÅž"ò«é?/‘âÑ’=µ|** Ò,Ÿ îa!•ÿØ’kuÎÇÖõ~ŸWú1 ¡ü?ðcÖGöÿªp"ÉÂÓÆGoS"°Jˆ8ÈâxÖ_ÑßÕsOy*@¬§²¢sž:ëdð”þ@ÍŒ•"•M¬dÑ’p€¶: ’,ƒ(ÕB¢ë¶@€Š0(¼.ó¶u'X Ãt"ƒ6 tJ܈^g=½NGôvmS^‚`ÙÕ:ŠÖþuGë-ºøaÕ"Áý×ÿEã0ÿÎ ºìí;'êžÙ@DÀ¢s#«¶Açùh=ƒóf!RÿḜKMÖ½étwÅzGÓ¼1çãÄ¡ƒ]—ÎK2-yÐ çýR~è¯U¾7cì™±õä0+ªÃ±c§{:ô›$°ºÑH¨Ý׈ˆ¿n‡¼ãéLÓ“uSl„}JšúÊ }ZÈÚšÍó+:oÑ¡$|–Ò›ô =KŸdãG…ŸÜ~ƒÐÔåÜ Ù¦heþD?¥9¹uI §Õ©$òÛƒYÆ8H¾pÙÖ™s}<2&>È lÊÆ…ŽWÆéV>¢2yy4ô‹Y÷æíÕíÅB½ „ÛÍ-¥XK½eÆ;&8í¹S0í&\L\’óX´GgR˜ŸLʧ*ÓÉþˆûÌ1jH(÷p¾`oe÷Žã±u€Oúô„?lR;f*p…0Œúh½Fdñ09ž!ØÉqð¬2é_WNnáä­Á-…ú¤Ìz¤L]Íæ¶A_WLëp‰ó<=H¾íVOò0¬=r 2a6†ú¦AwèY$6õ¡þéÉŠH Y…¡½!Q!£çÌíÇê)MžŠ«~¤Ça¨¨™+ÎØÃˆ·ë6hÊMK´EÇÿyI—Jm»2 ÚÜÕj~‡œgJk"-"GÐWßq3¤q:ä ø$Óegöpè8Q )uoHé:\ÛÉaãW„š8î]C‹d'j†`e”†Ð|QÈq¦9ÎÔ  Ú±P¸œÓ¿fäaâ”zÚ¢L]ÀzaıcKc^¶5ÍÒá¯c(í±'D‡a„cŽÝ6¼Ä.ÏØ3þ‡H²¡íðÐîJr!_?7t¾:Éfn%Úÿ9¯î‰Džì‰:Y{Ú"%3èÕ¤wl¢í;™QßJ¥’ù;à ﹈†žð¬¤8¹Årê§“úêØÖ\4ó¾ÆÂ¦cVeÑvÁL¿r£ª†j4mTùþb›wÃe{Ø¢YŤéb¾¡”’]ŽÊ—F™K°ôŠ\øÖä›·uË}<÷^XèXìo#†ê Z\Â{ B˜3¦˹X›1¢š Þ¼!@Ûå{hÒ]tèñz|U‹ ‚5p-Nˆì¡4vöªSŠkv1„ÛZZ4’° XýÑýeæ®þîïÂÀ‡®‰¼À²ïëº4yE?ý!áYŒÙQ‘¤­ì—pf=G8‡ƒ„kW[®‡/Aajû(¢s8½rCB–¬zÉÔ½•¶ˆ¢è$÷UoâK—Y&¹-ŠÓa]bEïvð)çn°I¤Q_ùõ#†NZ§rzórçñ^ØçÌ+Ç®Þç]±†Ý?¨5®‰Ï«áåm§K8¹Äðµ€k+åo n¼Zý~&8Ýe¡† 2‘yëýÙû¡·8˜nÙ‰÷h±ö^)WÙ÷–Ò{wöïg,íûž娪Cª ZØ Œ9¤d> ™Á³Wf”.÷›óóÓsöS«¼z¨ÏÏŒu yÍžl•'‘x°AócÝßíŠ ²$õà¥ü† ¶R11ˆ´msÈϤØåÍíççÕýÿ ¼zz©C‹xgÿŸ[ŒËÑû‘n‹´Zþãj¦Í†´Ü-Ê÷ßÓÈ»¿yó’`¸†%ÈÛ½ó ÆÛws)U³""bŽY2Ãl‹áóÝvÊ{þó³ÜLˆ$ˆcù%nfÝjd"¤G«LAQ§oVñè‰ö2w¡5ß¼èâ[¹€}°3l‹¹ª4ˆ´zöŒ8y£7é>·Xw¾E ^[úW¢þ¡núô7,E–©¦5¾¿ð~§Fgqq}›â³ÏÛÏ’É PÇ_~í†õd$ýÖl© þÌ·Ì‚ÇÞ€5èÖ¸ìÖšöÅÄö\¯h9 endstream endobj 3148 0 obj << /Type /Page /Contents 3149 0 R /Resources 3147 0 R /MediaBox [0 0 612 792] /Parent 3135 0 R /Annots [ 3146 0 R ] >> endobj 3146 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [209.949 370.767 216.923 379.614] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3150 0 obj << /D [3148 0 R /XYZ 89 721 null] >> endobj 850 0 obj << /D [3148 0 R /XYZ 90 617.572 null] >> endobj 3151 0 obj << /D [3148 0 R /XYZ 90 571.016 null] >> endobj 3152 0 obj << /D [3148 0 R /XYZ 90 551.091 null] >> endobj 3153 0 obj << /D [3148 0 R /XYZ 90 529.109 null] >> endobj 3154 0 obj << /D [3148 0 R /XYZ 90 509.183 null] >> endobj 3155 0 obj << /D [3148 0 R /XYZ 90 489.258 null] >> endobj 854 0 obj << /D [3148 0 R /XYZ 90 355.136 null] >> endobj 3147 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3158 0 obj << /Length 1675 /Filter /FlateDecode >> stream xÚµW[oÛ6~ϯ2`‡X%)QÓ¢€›¦i†6É£}h C–™Zƒ,¹2´+ºß¾CJ–¥Iö ðvn<<—OÄùìçdïÅtïÉ«(p„'B:ÓkG'"±GîLÎ÷èõäbz|93NÜÐyHÜ÷—§Óӳܜà0 ßœœãòåñ»Ó£cœ_LÜw0|šþùäg-…ÖÆC0Çè£>ÑD{ÄZæ‘õ¸&³6}d ½À^0SBÀ’¥D½ò«L·Ê.VR-ËÅ€ÄÓØ c5]fÍÀj3¯d*³ãî͈rW êªÛ%n‰$I5¢±ûy»’…²n—Yº¬O¥à°.³u %+\++E--ÝBuYj×åüo™*;/PK~×–«URX³WÛÒ76w¤žàöQç@ì3æJ}›¯æJÚQ Ü5ìf‚C%¯e%‹Ô2iS͸´J½ÈŠõVátRhÉßpöëøa¡u²Þ®ŒzÔ¶*6Ýà'tR[sR4£Q0pûÈÎMbfsY‘©,ɳäÂRgÊ«:މJìVÙåF“kÖú´aL“<ã9w½NP×ãñtïË…)q¨Î¼†e‘“®ö>|"Îöáf^$"çÖP­_Ä':]rçjï¯;"MFSÒp ‚;\À2›g, ’åèüòÅäðpR c2²‹zQ`“ësÀ=ENkû¥¼¹”Éâ¢Ü€Ëâhµ8<´ ÷‘p“ÄÎ8^IÚyš¡ˆ@ž&ÅçòðA”Ÿ®Ö¹áaaì AcÂÂp *A €,îèòk]iYè—»76ëß³b–ßÀh:IuÔ÷Îaˆ‡|4ôáéÙ«óÙÕôòxò…>{†ãþnÒZ‘4©ªìF.ö»d±ÈŸÙZÕ;/¾)‹ÏÈ´*UY rEC›±%¿ª*I•¶ }r`i… ˇY€ª³b#+µ‹ýh½G¡ÄWSmT¢²t–&õìJÉõZVoµRŒ(ò4ˆ1‚~,ÄNkû¹†¡íÕßø9¬gx¶¶î×DÍv÷3ß‡Ä »Këùñ¨ä ¸ïÅAø+Ék’µÓŒ((†;>󂘢!o²BÊôK1ê»1LP÷ß ²êp¦#@SØ’û×U¹Â=,K´©Ñz¯.¡f¿)š0ßnYVÐQÓY`/Í“ÍÆ6S¿e¿O´gVwshbÄ+µméÝîË BP¿¦_Ê|mZ"­[ƒ‡ä‡P˜ˆèÒé5<àx13ù¶¶³²„ѳ¬è5}Ê0Îÿ†ÆlÜ`ˆ78¥Ý°B¦ÐÔ™g:µÎ¾°œ„Fò]×°Px\ˆ_r kpQÝ(µòÛ,Ïë;T¥Ö~k³WþžÊµŽyáz1ݿ۰ò à úœb$v~7{s~v2Lí÷¨p¾œ½?¾žé_òãƒ!÷Ñ fÚ¿’ª1Çà]ã­ï?Ñåö~ÿ]ð笃K#+ð&«Ô6ÉQÄM™-p¦‘šßï܃£6ØwÐ lnšˆÁú‰R Ðï~5ÚVÆÖÊïÃSšò_§;ljpéE —ZÓžþ°ÆQîQÑûw¢bÈ…ó²´³l3ÓÍäVþÌ‘ Dâ1Vwy)¿L ÀÒšÔî‡iìhyÔ+A¤öcû÷àaŸr R<æ÷ï®OáúµGÛ~@[ÇòÈ#~Øû)m°þÓûÊÿÚ²ðx endstream endobj 3157 0 obj << /Type /Page /Contents 3158 0 R /Resources 3156 0 R /MediaBox [0 0 612 792] /Parent 3135 0 R >> endobj 3159 0 obj << /D [3157 0 R /XYZ 89 721 null] >> endobj 858 0 obj << /D [3157 0 R /XYZ 90 690.045 null] >> endobj 862 0 obj << /D [3157 0 R /XYZ 90 356.077 null] >> endobj 866 0 obj << /D [3157 0 R /XYZ 90 337.418 null] >> endobj 3156 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3165 0 obj << /Length 2257 /Filter /FlateDecode >> stream xÚÍMsã¶îž_áé»ÈoÖ IQ_{K·Ùm:Ý&M<ía»“Ql&QŸ,¹’¼iýïP–d9oÓÛwðAÄZÌfböáäÛåÉéûXÏR?T4[ÞÏR1‹Eâ ΖëÙ'ïÝ÷gWËóëùB…‹üù"Œ„÷ëõÅòâ§<£a9Oïì§—ôùÝù/ïÎi~ûáýÃçå§ïCÕc¨‘[8–Ÿ $"–ðô½}ôE¦¾ ÒÙBÅ h—R¸ 6,¤ôÓeWÁ|!•Þ_óEéEÒÒOt˜~¬yû¿íoíÁÏË5í¬îi¼iÍvkêU[Õ)³i¶Ùʉ8õ•Lý4Žû´I˜Å—" ®'òqþeÊuΞÒx{³<¿º:¿þx¹¼¼~÷ãÙÍÍí÷Eºñ|yòlj„©˜I´v¤”¯Òt¶Úœ|ú,fk€g?NãÙ“ÅÚÌ‚4ñC&*f7'?“× Œ(…öS­g ‰$’äý1/ 9€\(š¼/)¼‹rUìÖ¼Ø>ºIV>T4ÝdMkjšç}äß„PÏ3´Î€BCæÙy²*²¦¡éÚàæ2oóªòòÑÔyË_÷uµis‰A‹6yûvLàE-I¹zZ¢UU6m½[uöyÊÛÇn³z.ïa·1e;äð §™¬MÇ㨜 <ã¨p¿BÚð¡£ Ã1§í,Uâ˸3t=bÏdë #+é«=âÆ´ÕRªNàž7Ä„ÀÄø¾ªŸæµ²nÒ’”Ê[eEÁ Š }sBÐfsé5ìK‘öƒ4jÅ1µFÊf=qPðÑ(LÇç¼½B?WC}ý&B?9qxP²ËpÒkX#ÅQ£5T±5á{¶‚¬ã1k_F¡“2oná8Õ“™²‡} t`•j¶ ЩX,ðʪ¥ÅÒ¬LÓdõ3¯÷Dcéï­ývEK+wæ1›+á}É«]ÍI iJ5TL¾ÙƒÀ k©½»g‰´’žPƒ¾ ƒ¯UC—“¹ð¸ß6/͈ymþØåµ°±KØbr|f}pf±"‘`EcVàòõgç¨aè'£›1W¡÷„á $‡L2ÈPùrÙµ$@Æl—´ŽŽ9bbáµiwuÉÄêAçÅ*G)’°Ð…$ÌG!Ù—CXÛD©h…$¢¤Ñè"ض‚ÎÐÃPŒE?™ÀBE~¨Xµ‘¯}t(2„èçìý•ÑO߇n„'º ‘£ýIØíÇé ý`]^‚ˆzca6”¡wž“h¯Á0x&Œ¼œkð!4qõ´Óo#¾¤¦øÜ1-ˆb]ÂlÝÈ2Ü“{Âìø-ÄÊzzÌWîÆ2o•¤ _‡è¸ §]éq>-¾’Gî‹ ¬†{“dWQ¯&¹ÎÚŒ/ùçmw%¯°aɃW³y‚²"»seÚ+Xé—YYØ™½úµ صZåeKaR@Ê,}±6Eï¢j$›Þf¨(°u ¶Y Ü¡(e0;¬8ÿÆiÏï€Ú„F,$,UdÖy³-²gZAjû2‡0­çL™.˜4[³Ê1'¼©mónm +1“œüi§Ø&ÞX³óÇÁ(kÃÊ&+v†>1\Bƒq6—RBmñqyÍÙ÷Ûj‘‰"O;¡£Ãêøè°¶?:| ŽŽz‹S: ŠØÐ¸­ x¡Ž!ÏŠuw†]Ã\òrÀVÖX Ö!_¨àèÚö¥œê…¾þ ç°Ñd§ÉAIêǬÄ}ÏÜ6OÕä=y›.» Úã¨Ý^øÄ1ƒý\ýÀÝ5FôÃpò>ß»Â;s ±Îp¡RäMË4²‰L‡êâš(MmgÁÜücã!&– |6p•eõ6æû0òÞ£b¬hˆ .JØL ¿Á³K°3tzÙšÐm.Dîg(½œ;X!wÕ9eêW‡Þ€vxƒÍ€â;=œqpºÙ5-Íö­~#œu»nød䎜6ÖqÏ^ÀåéÀ!‚1áÊÿ[÷¨èކɛìÁÐtl@ˆžÁP…CÂ7P¹+^uW¼ ;c!µnÙELÉX=²ÍQ¢VÖ¯pÉ0ÞoþåQí'&«¾`\õqÃ` fw©rmúß+?ýÖûb6†B{eò}’gŒÖÖÒ}ô«.‚teVì”Ñi#¸ ò’߈bº BwÕÂdM÷I¾âïêîwˆ²!rG¼ÛV3t/EU>4Ç.Ñ@Gô…J8±EÎìÛŒØ1›@à/ÓÚ€E©i´E‹k@ o]”#ª.írªÐQA,¸fAhׯÀÜ•Ð8ÿ¦ß¼|³'>чtâ*Mí Ž YξÚÅ ?‘"ÄÅ„~¡£QÀ;úU-ÍÀ“ÔD÷~¶¯óû¢ ÏDe)ÁÎêϦ€@?•“O$±Â=רž®•¹™lè#£á®ª “•„ì\Nw 1 T5¡I*`?J3û® ]ÎBƒ:häªÍk×%'ïÅ=“~t8N® ·Î9_‘@!Û ­ïMãýòû».Ü.ÀÛ†þ};Ñô;ܧ¼`ìl×V›¬ÍÑCž{÷À›ñ;«­»þ\™íþ ׉։b]¬ž‡¡÷õÙO³ŸMDtA½6ïº÷^ ÕDÞCŒ.ïáǰ۴ v$`ŸE£¡K|¸Ø2 NrøðÛ%¾>rG¼ÛwЛàÚYLyeÃAÎʉýô$åÊôÑÔ^ÈUUצÙV%¿ÏLó'Ñ1&a§ÜÞû( &4µ?R/ãÊN†l*ÙrÖè?–³¤À?uä?}´¯er˜±ðòmGNÝS¨mËqû{fN{Gþúxf¯ endstream endobj 3164 0 obj << /Type /Page /Contents 3165 0 R /Resources 3163 0 R /MediaBox [0 0 612 792] /Parent 3135 0 R /Annots [ 3160 0 R 3161 0 R 3162 0 R ] >> endobj 3160 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [406.161 299.036 413.135 307.883] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3161 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [144.107 263.171 151.08 272.017] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3162 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [325.773 239.26 332.747 248.107] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3166 0 obj << /D [3164 0 R /XYZ 89 721 null] >> endobj 870 0 obj << /D [3164 0 R /XYZ 90 464.511 null] >> endobj 3167 0 obj << /D [3164 0 R /XYZ 90 419.584 null] >> endobj 3168 0 obj << /D [3164 0 R /XYZ 90 399.659 null] >> endobj 3169 0 obj << /D [3164 0 R /XYZ 90 377.676 null] >> endobj 3170 0 obj << /D [3164 0 R /XYZ 90 357.751 null] >> endobj 874 0 obj << /D [3164 0 R /XYZ 90 223.629 null] >> endobj 878 0 obj << /D [3164 0 R /XYZ 90 130.603 null] >> endobj 3163 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3173 0 obj << /Length 1058 /Filter /FlateDecode >> stream xÚµWkoÛ6ýî_A`@á ³Â‡žNQ@qÒ,EÓd¶ÐHA‘˜„˜,9’'Öß^ФbÙ¢Uë>‰ºº<çܯiîgƒã`pøÞ1gx6¶Ap<èд@€ëáäwÿ*8Œ°‡¶q0²l8ü2=Î?I£/ÁG†þ§³Kùzrúù|r*×3¾ß…ÃÏüq|8|oá¡Y³Y6—#øÁµÓ*…\žÅwq÷Qã?ÂÇ r—m˜B#!Wò@oE Z\äU^HKœFe)EpصFÈ5l·ftðän±L()¢Šå™4|…§tCzó< Ä—<:¿¶‰ cÏ×7$Üþ@Ãñ°^s@<×°`”Ìt EÝlç!Óð l ªêñlÁ/,‹ÓeBåÛÛ*Êîsãá]­V„^§×–;ð†QÁ“Ð;–)ÿlv^ø†—Áåt&®|Êçùœ4­0?9Èt9ˆá˜¦ÄøU|± Ïq@Ëü[Y,»—äo8&:Ž#Lˆ°µ%ÿBâ<++U‚‡H–ÔáíØî¶··”ÄÏ17‹‹ÈPNôÊɞʉ^ùÏÙÞÜå3…Û7KfªÀ¿mG^ïTÝùÏ‘¶í,­ÕV€ž+FûÏ2ÑöQ·RñôÒ¤ç:Aš~J_g.¿Æ•×[¾-½ u3»iï=1vî7ñ•Lw¢vO Dkm`=Ã…¾Ú•_† {ûÜÄðx=Ÿu׫_hD¸õo’Z{’ö߀éëáê²:[¬¶žU¶CÕ¡ úDjïÒ¦Ûƒ>g™ÊëÛ=íúóõ^Yëµ endstream endobj 3172 0 obj << /Type /Page /Contents 3173 0 R /Resources 3171 0 R /MediaBox [0 0 612 792] /Parent 3175 0 R >> endobj 3174 0 obj << /D [3172 0 R /XYZ 89 721 null] >> endobj 882 0 obj << /D [3172 0 R /XYZ 90 690.045 null] >> endobj 886 0 obj << /D [3172 0 R /XYZ 90 670.931 null] >> endobj 3171 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3180 0 obj << /Length 2106 /Filter /FlateDecode >> stream xÚµYëoã¸ÿž¿B@ÂîÕ ¢Ù¢@6ÉnSìÝmcãúaï0«kK>IÞ\pèÿÞáK¦Úwl?$¢Fr¿Ç8zŠpôþìíêìü]G9ÊšD«Ç(ÇQŠ3„c­ÊèÓìê—W7wóåx– ù‚'xöï»ÛÕíwï ñÒm¦³¥´kk±S©B%;“×Ú§È îÞŸMq™ ÑQbŒ>™Èr8Ü6í€Ð^Tˆâ¡Ù÷£YM؇Lìá? ãÀB¹ _yi¿ ‚ ©2„nŽÑ<7×U ¡;LµÀ9‘ «Ì<•à)±‚gžà™'hFŒж–Åg3ԘɜHÙAôX‹>'3#p7Ó©G¤ÏÒk> C•7›F1<ËG¾æicG«e!»N´/ê•€7 ±×ù”9¹ØQ¹˜/—·fÑJÑKKÜwà°ø°^/·» L¯H©>`Ì6¾³Kù8x‰ý¦wXZ‹9ÅÄ@•…rÝØ)¢(ä®ö<=cŠG8¾s!^…HÚ$A4e‡¤­³õ}×+å_'j–¢8ÍÝlä¢Ç)á[ÃÑÀY–òð21ϲ7&ž€A8C)ì{LiòÿSzß…ªhƒÐ¯©õ¾ ª!’ñpeÀg”™§V;¨Í­Úü„Ú Š*±y/ݽTxüEE¾,ï×Mó9`€<†ó9ŸÏÊ 4ÌÀ=3ð™£Y¥ãDSaõ0y•ƒî¥¥(ˆ…;ð¹®–G¾‡SæÅEÇÁÉ^qbO/[ó±sƮϥwQ«I/#üž#„rpÈ—}ßVÊœ{ëVnݹ1ÐoTfŒŽÖ¼þ£ÐÆ¡‡Â¹N¯ a; b:uí†1„É1IÙ×”ôU¹ªóħ²ZQ¡‚ÌOˆÊ¿¦¨O*§Kß®÷»vCøAIÔW2”Br¸Ð± äy xOŽ]X¶àã-záð´}m‡N*f‹x\ílªгnå°îPÜÀ)YêƒÈŠoË앾þx8ƒO‹Æhöº¼ZÊ~²×(ØNo“.âì´ mÛ?+_; ™"£*¤K&c‡§Øo¥¸ìA´îö H¤jÝÁØ+;§· x”fJààµõ’¹æñ˜(|&ZûÉû¥y…êXª;IÌf·½!U–Å”@ÐyØæZx5§ÉJ*§··‹¿ÝÛÅ„}n¤Ð¹8›Z;ªÜÃö‰¾QðĸŒÅnW5+ÍÜÊÄg“æ»0¹eoìL·žƒ¹2WE®`iQÒÌ–ªôo•z]Ñ ˆà£·í¼±”2S<$ˆQ1”Ô(Ošpã„ 5ÀÆ›nÓqL1â8ŸÖÎJÔ4ŸuÌRšñABxÍ´Ÿ¹ws} «wÕ11#­0°ózõÍ7vu6U$«qÓçê{cU¨›©–a°¾Ú¹±sÖÂÊ$ÚV8?'yªõq¿®Z»8ó•R¯þµ^›zcG&ˆa`‚X†EࣺÁÆ©Éø@ñÀd:*|öQØë÷®h«ME@pÆ1Rv¦òƒ±°+‰fž¹t.qæ•&6;h«iÂÁj¿§HT°?ÒFœ.©ÛŠã&1Q™ §I!³åV¨„…”ö§¡/¨Ú¤ëU ­ÿ² ³t&0·*0p»¾±]îК}Ý» 5‹-Û¯¡Œ”„8RËá¯|qá¿©Nס+À¹ú~4§`> endobj 3176 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.004 501.587 110.922 512.491] /A << /S /GoTo /D (subsection.6.7.2) >> >> endobj 3177 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [505.329 253.143 511.506 265.907] /A << /S /GoTo /D (Hfootnote.11) >> >> endobj 3181 0 obj << /D [3179 0 R /XYZ 89 721 null] >> endobj 890 0 obj << /D [3179 0 R /XYZ 90 296.73 null] >> endobj 3182 0 obj << /D [3179 0 R /XYZ 104.346 61.241 null] >> endobj 3178 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3185 0 obj << /Length 1795 /Filter /FlateDecode >> stream xÚÕÙnÛFðÝ_Aô‰j"f/ë$Šã¸.⸅´€Œ¸¶ P¤JÑ9Zôß;³³+‰­8Z /âr®{†bÁMÀ‚“ƒÓƒ'¯RèH'" ¦×fAʲˆ©8˜ÁexôÃä§éñÛÑXÄ,L¢Ñ8NXøËÛÓéé›Nè1iNÞœœÓëËãw§GÇt¾þŒ…ïàñ~úã“W±Ø¸PámqêØû¸THtÀœ†O^q¶I>–™Œ¸ÒÁX¤”Ž‹Æ cá_È |cÎ#;¸„Jb¹èÌbaÚ³¦kÚÃÃÍ·ßX̦y}Ó¾4Ë™9ªòåÒÊZDšq¥J‘Àï-&ŽtšàYõxÖÔËŽn›Ýæ­¥+’,yˆ€%èÁ- lÏ¢XÉ-C‰>œ¢÷¯^L.ޝŽ^O..P¸}Í¿í˜ÿì!‡L v °e]vW…µ¢°§ƒÒÒ}!È¡úÿ‚Aþ4 TÂ_¬C¨R ¡ûŽì+!|\ìÑÅIð¡ z¹âƒ(äž 5uYô±)‹¡p\=(&Ù“Œ"uvÌš;…gÏèùÝþä±×QØZ“wÆ1õevWu>7}„©‹jØOƒù,´S³jê’P²K6åŽýºi‰-(Ÿ³§N–Ójrrqvu6ùõêì|zþöÂc=ºÏ·Ò§Á s%Ä\ ÀæŸËåeùžÄ=§Ö_9–E³,»²©È;¶¢lÍìø|/LK™B3dzèÚÞµùD‡u_y áºäìýÓA÷è!ñŠ9ñ7Æg÷Õ¢m õºÒ,÷Ö˜Ú7«Ôà¬Rr¦2ÙWeÎ¥öt ;›HQ^º‡­I6¬YMmÿ<žü~ÀáÈŽ«…P2J¹fóƒË÷,(£T§Á'K5¤†Çp¨‚‹ƒŸiEém œ©HCk"ŽÒÌYöº¬Ac)â’ð² –•ÓzV݆`Ý­£šâF‚@ðy¾ìLK¨rÍC 2Q9fôl‡<Ñ-õ$Èë‚NtÒ‹ ¡fvjÙcaPbm«ÆKµ7ØéÀɲž‡ñÖ%‰œ[‘q:§ÇÒs®^Šà ÉYx¾05PYÚÅä†ga6e|µŠõìØ]ÜbØÛቱy.ùÌ"Y”¥Yߣ,LÇܺOS’pJÎÓÖ-ŽZ$ƒF8§SsMhçälíR8âlnïfÞ7°£ª8<íˆÃŒx~Æ3»ë÷JL/ tø!_î—o©>•Ýíýñ²²Eº~Ï|ÉÂEÞ‚‡ Ç–6Á$|Ótžî6ïüÉ5dä V3!h4áij™‚¨ºÆ³•K:õTE’Ü!rz=zDp *qF!Ð3ƒèt½!Ý þÊsØB½¶§óEE Ö×V|:<ú·œåŽüˆ¤VDÙ 9±7[E õŸd>Ý¢‘¶ŽøÔHàK#õôÛ¦  J§ÜV²…YdI”e|(›¡aÂ§Ä˜Û …ÛBc1¥3¢–QЙ²O˜ÍHÝy2—mö¸“Í’¥6›»“Í=1ÙŒ¯”Í=ù|+0€ÛŸÍeç\³ÎfxéeóCbÅyq€üû±â*D’ 6Dð×c!1J‰vQÊPç²Eé©öAÊ\²Á€hNnFÐûËú1¥à&bßOÆ|Y÷ã“úncïpñɶ 'uÝÆ¢0{ÚNkÌ?Ó‘„±ü_D‡EJŠÁ¹ 9|LŒq=’RØÁJ£A¥"™Åߤo¶î¤/ΉX…“ª¢ i&€›ÍEÞå„Á‹Ê¼*ÿÈÝø,l¹šÚÑ—5A¨-#¤w¡³g$Ôl>=_ô:¿NÂõRIïyk{Õ²!Pk k›õwAàë¶™Ó p¹o.ŸP  WtêœÄ{ú-xؼo°˜MÇÃ<‚É»Rx7v½l7oÐ®ŽžæýÙ‘ÄËÄöÞmëÏwØtkTB¹P´37ó¦¥3ÚŽH}¥¢X®ŒÂ¯…]µ¡Þ±4K’¹ÊSô*Pp[3ƒÏÍb¥IÓ~!"k(À*jIp’™³éÔ5AÝ8ÚÚ˜Â_1¢ì‰uÄ“­ÿ‚nó‘`. |ÁûŠ\4e;.´üÇ®V;zÞúÙüÁø>‘t!›ºúB§k?ËMq7³%àÇ÷â®…OA}e#ÅåIÉ1~3¬v?}‰‹dÕ’V_8{Š> endobj 3186 0 obj << /D [3184 0 R /XYZ 89 721 null] >> endobj 3183 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3190 0 obj << /Length 2081 /Filter /FlateDecode >> stream xÚ¥XmsÛ6þî_Áó‡5±øîf:£&Nê›:nmµ½™4£¡(ØÂDª$[ÓÞï. H ršæ‹.€}ó‹]øÎƒã;oϾ›ž}ý& ÌËb;Ó{'óÄO=?ŒœéÂyï¾ú~òãôòv4æ‘ïÆÞhžûëíÕôêÝ["Nèo:Êwòîí }¾¾üåêÕ%ï`껿À߇鿿~ñžÀ¥E1¨£ä± ÂEg¾ÖЛcžÀ¦€–M—¢÷U-^€ˆ8qeÛà t×b]Õ;KM»¯…Xà0pó–H+Y …DXÒúx´Ëj1äQ䫕д¹æß.…æºm«uÞJ\¤çòÅÂ,¿*¥–ZTëu^.Ð@0n̘—EÚÏse ùK-‡d×ÐE‘ïæ)3®“ g¶#¹e!l¾ŽÁ“‰YOf¢õÌw¯´L©櫦Úk¡L±²\«£ Žkqú»iëmÑVõ(Š\tHüž`uâ…A ç{׿Ç^è;‚јù¾ÇKüHG­Ó¶1zÜ£T1Tæ5Ù~+òÅkYXꊢ•U©íØ;ÿÀ-x©§´`C–";¾g×±Ê²Ž•Z¦<†D8>S:Â÷¶‘å-! ÖŠõfKˆ<`ÓFÅxãé´ø=WVŤ|³…üÍ÷yAÈ,Vy£ÌÝ‚À„Á½ò Z zÞSÈów·ôQ•j Z\Íÿ þÐÄ{ÃJONG‰ï¢¡¯ˆåUycX)uqaÚ‹7=¶Å„Ö'%ÝqqÊÜöq©ˆ¾‡Ì<.e±$z®¼…«­qÃbæ%@Ñ cfV‚Ä…Óž-$ éÈ“Àä Ž´`Òø”à8ôÒ8ìävbfÅz1ƒ8«…  ièùñaØ¢ÃÆAæ{1çC¿MíF§‹³Ï—xYÀŽl3p­êSWC&$œ½X‹’rræ*÷>åEK82ñ3M¾Ö£¹X溒 ‰‹ò’æºå q‡ŸoW-­@jG0Ÿ{ìÐ 0ÖÓš¹Ë\~.DI$W`d ÎL„pw#ùCõ ¢Ë¦Ù …àà„ŸyÀ½,å_®$ Ž—«æ:Ôȳø#Šmk¬€,Mà`ÜK ür""B/I;p<‰'ÅÒ¢ ØÇS‹‚ü¦‚ä`³Ð XøO›B2·ègœv 9ŽGƒz÷ÜU Å cPÙ<£TY鬕ÿú7Ú)ÿáuFþë×Jæÿrzöû†¬ï0,è"žy< œb}öþƒï,€¹ÖK²ÄyT«ÖN¥^¤rÌʹ;û鈥*!ÆÌd‘ù‰'1¸À¹WñÇ*¼þbø¸kÅf#êë Ê‚‹‹…€`Ð@Að›ùƒ ù“l€Èl—×þ°MBý`ý ï‰rFfôõ’þ|úûóϽ0}K“·w׳ëÉf×7Ó›Û»SŠ„ZÖ¶{8‚B9„É_'·ï RžÝMo/'×Z ­Ç¹öËú9¿ ô‹CE+h;ë¼|4ü×ù76mã¿¡(+ëæDož‚˜ên×Ìn®Åú®m×Zë¶ÔFÌ4¯êÀ“κr»ž‹Z“‡«zgùr°Àî‘ó#ûRt !˜¤Ã#c¾Ö¬]ÖÕãL<bcNá¼áÄàÍý­ðÂf"Ã(ˆ•å°9FûZnÖž*LΑ‰ÕÑ qþß:Z©‘ÞS‹v[—ä¡NÖ{ôô‡olÐf±Ž@»°ÄJµBešÓ¼ªVÖT¡Ôé§{ôeQ•>íW7·ßM..&厾¿’ål‘·ùÉäá?—=8Ó.¹z÷æÆ²WGj¦ÄªyÊê矊/íRέê–‚îJX1ÀÃ玅Gë¦`x °Ïº)ÔÍ0¸ß˜By:,/Ó ü@ 7\\lŒÂÑ57öÛ?޼ ¿¤ŠŠÊVªáÞÊ’ƒªh¯^4ƨWWØ>•*ôum:å•„¢W÷чW9àEHÕPªjCßø”Ðpd²^¿ ¯Ìeo Êó–ó5ú'˜«ñ•aúšâû‹-yã$IKºö:qU‰¥n£Va‘0Ó“‚ÙÒìÕå5LŸÐù_¡c ¾Ä¥<ÁΜ͌“»›ªnó¹\ÉvG«ò¢®TW‹“ÐNC­®”ô÷ îS¥;Ìý\Ê'Ú±’ÿÃÆAÐW&o©;‡eÍ®¾’ÀJõöµSP­©ÀÆJ ¶»j|Þ—Øçl9#’Cù(Û¥F€~ÑØªÒßtOùaG…aÓB5˜×E+9¯óz7Š#÷Åð ©{ÎÑ|À ЮéÌצ ºƒƒ‰û¸ XÉzŒ)z ÄVÄ'â6 ¼}kü9npü0f)Áè(ðC–Œ Ôó½&6ô¿ÊX,hciôÐ#SpÉ:¥ø”EÞˆ¡û½Ú=©ô’@›wP>”²óôLR1צ• ›¼ nZˆ,;1†1^£ 2ϰ“ñ¨[z¦±½ÂùÖç·ð‹žß~Ä®±jä¶y pÓoIâÓo˜WÀ<–áU™ÏW‚ÆX©`Å< ü°nõ‹Jœí—DÑa8\o±| Îc“œˆÐ=.)Qz+ÔƒBÏwþP,éaô8@s¼o\»; už-sõ½x¤1¬Çf—“¾Ù³2_‹o»ÂãØ¿ Z3¾+zœê]N%ÜIM“×»A’èw¤{mµÃ_õüX´ endstream endobj 3189 0 obj << /Type /Page /Contents 3190 0 R /Resources 3188 0 R /MediaBox [0 0 612 792] /Parent 3175 0 R >> endobj 3191 0 obj << /D [3189 0 R /XYZ 89 721 null] >> endobj 894 0 obj << /D [3189 0 R /XYZ 90 651.4 null] >> endobj 898 0 obj << /D [3189 0 R /XYZ 90 88.137 null] >> endobj 3188 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3194 0 obj << /Length 2046 /Filter /FlateDecode >> stream xÚXÝsÛ6÷_ÁÉC‡šžX€ßHs™q'çÎÔNMûf<”ɼ“H‡¤¬únî¿]ì‚"iJ½ @`±ßûÃBÂÙ8ÂùxñÓââ‡Iè(OÅ~ì,ÖŽN"RO„‘³È/î»\~Z\ÝÍæ~$ÜØ›Í£X¸¿ß]/®o>Òâ% ‹™ ÜË›·ôùþê·ëwW4ÿ çSáþÃ×ÅÏ?|ˆüžÀ¥E1¨cäÉ F¢ ÁuУž[ò¹ŸÀb@‡ŠæþÍeÛÖÅræ wßêû2Ûé·÷Ùv[tþ‡ˆü¤7!^‰Å/ôlÈÈÍŠMª5­ÝùC¿nZÞ-Íj *0YEc­³|tð!«óÃL 7«5:RDî5³9Û-Í–L¼ÝuN¼«rûŒª;s«í\JOE¢ª\á¡8q3d§,€ðÚeY”Ú3öÀ–ÎV´‚ªÞg}÷ŻۻŸfA„F2ÔÔŽcŸ½k^UeNä;Ý>T<'ïq ,·À7I(¶L×ZFFÏ?çÆJ14/[¡U¡ïæY›Ñl]Õ4¡óaà’_ËÖ¸ 6ÆæàRÉ{F›¶ªµåc…ÙÓ̇ào÷Ì·(-5‹òÝË—¬«å?õªÅ˜¦±ûùQ¯ŠlKçW™ñ±„¥Öå”mö/46çH@2U뚦FwEYìŠk^}àI¹ß--©‰2Œì3˜­ªGdÿL_ä œ@‰¬²¶¨JP?L%Çvpô1ku褎Ý—“DA’ºÆ‰r³™tGÇaµ‚„SÆN ˜ïÊg ~¬ Fºn05WPìö ϖ̇-%Ê]>Ó2‚'(|$¨.œzãÐäÎÀï$^ø¢FFžL"'ðb“uѶú(Xßó9à(_iÊ=ˆOú »‘OR²¡§…Å !ݲâ¥u­5Í8©a¶Ó»ª~žÅ‘‹AŽ¥ûžck¶ ibÒl`M£*C›0@ÆB¡’M©+¹<­™°o²À40ùF°ÜÇùPyiXT®g¡Ô=à(~çµ…÷ tWÂó•åÒT(óVºÀ<{BàÑ ­f4ÐÚª%”‘TL0n+“t0;<=ñ ¸„‚Í Åú-~H‹ÒÝe¦´ñh;gX…'á2âÁÑñÀÌü^øzáhXãd€z|åã¸dŒž‡á O¸^¦‘©—¾ÿ„wxÕˆg\‡ž¤cŸ“ä±ÏÎvs­kmn²¾ÖiÕác’rtZ(ŽˆËB…‰Xç4=frÑŒ)HŒCkt}ÛÇ]Å„ÒÄó¥oÏ"#®E˜Ðm£ø*R›Ð3ú¤ÄSn^4óã”ïß*B›Kêå5§L|Ù×%g˜ÂžnÔ84Õ½«~£d.ýÞê‹t2”%M–\ú„¸bÚ3+Ö4ö@›`¼×ô7 ˆI¨ºîÃïQò(4«Ý×%o´õ^³¶íd‹!dv9<…ggâ(E‰¼Ù!/ÌÈŠÁQ½½êCÑ5ýÐE¯!±®kÜ—`ÜèR×|Cõ¥äR âqdYÇAdäÃðØ•ùa:U€@aZXÜ8•©»ÙïtÙÒÃnZ~&üð­w@W›Æ6rݬ@9s/#U.žæ(.ÕúÛ^7->?ò2F‚Ó ÖÁú‰«ãP­¦f޸交7Fµ¯iBœí·è{\!M"aKƒ¬G»Ÿ¸¾ék¬5,à–­H ”aE‰$c¦p% ¿‹7m6fw{ã Z;^-.¾q'"ñYIè9ÂÄYí.¾|Nëà/Q‰s0T;'€*>f¶Îç‹__°4Ï=)).CO‰ÄÖÏK¤âGØl.}(ŧªÈGà ×êÇG]ÿRÁåóúuÝ¿‹ñ6w𓹚Þà-ù–N}gh¶EÓÚs|Àì4ÆÔgqÿ™ x`P}óáöþóâîêòbþæ ¯0bF¢¡V´nêÈPvÊy 4Ó~œR"üK%Ž,‹åÞd¨hÝH¦.óí¤„h°È¸³ØÎdK]~4üñ#Ÿ7¯øþû.#7‡Ÿ3¸.¬F‚è¤IŠOtTusýd‚5»Ñ-…mù|MjÚéþ¥øjŠiÅ0JóÈSÉ(™¤˜ò¤”¬ V¨õäX1Öì•E‚W§%}æ6é)à+Ùn™qÛÜóÀw¨Ã#o_OfŸ YÜ'w#ÞÕÛ†-ùŒ|_ÀupÞÊxÒJëѤoeÇí„™¹Ý?kgzÖNÅé9¹ë ‘éÝI}ÿÎ ùÔërY¹©^¿¾´…}¶ncÇøÁ98ó-”¯¬~—n¨A¶œt”56ž\MøÌ²ª¶œ&ÍQ^¯©=š|§¿-ÌíL®ùv*SütÒdë¸~Z·aB²Tükñêþîê×S²ÁIB!C|¹?éª@²pSSþ9Ô ‚ Ü@02y×:NYr{s*C‚K§oö´Ó ê{Š ž`wôÈé†"ö¤ Çýô]?!c$I×O˜þ:d„Ý„;dx*E ßëA${Wÿa¢!Í&^˜&ðdóRÅÿÙâ5ØþЃ´UME³¥mžÌ¿ÔF­¶pŸs¿•qçdÿ Òvÿh’º[Ä@Î0À«ÉN¬çÀÿêû C endstream endobj 3193 0 obj << /Type /Page /Contents 3194 0 R /Resources 3192 0 R /MediaBox [0 0 612 792] /Parent 3175 0 R /Annots [ 3187 0 R ] >> endobj 3187 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.178 629.108 440.355 641.872] /A << /S /GoTo /D (Hfootnote.12) >> >> endobj 3195 0 obj << /D [3193 0 R /XYZ 89 721 null] >> endobj 3196 0 obj << /D [3193 0 R /XYZ 104.346 55.923 null] >> endobj 3192 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3200 0 obj << /Length 2247 /Filter /FlateDecode >> stream xÚµ]sÛ¸ñÝ¿BÓ‡+5c1A‚¤›ÞŒïâ¸îäîR[Mr -Â2¯©”Uõ¦ÿ½»X€")J—~=Xû…ý²ÉjÂ&·ßÍ/^½ ýIìÆÒ““ùÓ$f“E.óƒÉ<|r¾ÿÓõûùÍýtæÌ‘îtHæ|¼¿›ßýxKÀkæÓX8×?ÞþDË77¡ùܘó†Ïó?¿zx‚>R $°£éqâ¡ f8|õ–³îñ™b×ñdæ…t .ÍcÌù'^†‹3ÎÝ802ˆh:ãžÝmQÛñf~ñå‚ÔM8Ê/ýÐ =>Y®/>}f“à€Ò ãp²Ó§ÖGnÀé|òpñÒcO,Î|7öý‰6÷‰‘wY¡Œ&i¸¶y«Â¼,74+ U²|¦YÒ4Uö8õ˜³m ަ¤ñѬ+•¤câ¨Æ=ª·ª9‰»HÖê<.Î{ÈæÓØ­›>ÿÿfÑÃ|biÀsR¥»)€’Êý™lS©¦ÙÓºÎÖ›Üìe†‡r[Ñd™Ô .ðuÙ¥.8w<ŸF î î< ’p=A/S/p’|k–HÇëáIàáñµ4ˆ¶uV¬hÚ<+ã¢c:žÓ‘‘õˆZ5‹¤‚ÂZþ‡NFÖºÐZ5Ïe ®êƒGΟ³šx 0ÞeynÄÊëR+dæÅ¡ë…^ÿU²"k²$Ïþ¡‹çË0ñŽžö¾lá¤~ X<é‡Z6ee.–toŽ¡ )VåÕÕõ”óùýâÔ‹À¹~w÷†gO4æR’'Õš@ð¼ õ—)•ˆÌŽ¥ #æ*5ðÂLH\´KÁ«ð$,mx8ßU€c .Ê'{¨ëK Ç<âwµÙ¨ê‡R?B–yR×4]oQ}8«ÔÌúšÁÞN̵FjÃT«𔩋2z·¦ Ü«Åë^4]`öøöŒ¹Ï,’¾Wë@†WÂÈ)ÔRÕuRí œÐÐ:$ÌOrÉ…p£PX.³z”Åz×N¥–UwÌ5׆m2ä&[—廃¯´ ÃB«éøƒÇJµâ7)¸‡ÌõâZºùÓ…h&Že–Ô0QÿaÞk£#£=ó 2tý ì§&à-ƸºTÙ!–×Mìæ“ªT¡Ý26!4Œ&`òq Ý0ÓâeÚŽ4•6SO!ûˆÅHÊÒ:â^ì†a0H€Z¹U!zŠ…Œ³- "”öUõÅ*¥éÁÎ<]ÁŒYY»‘w¬¬«ï¡uè=‚dÎ={_ÒôŒqy­`d5Þ!!*Ó¬ž¶dà\’Ñ5V®¤™Y ]&y_}G5‚‰I:…†Î]aÒr¹6ûX¤é¨ä‹´´ìIsù±ƒÚLË"ßw+‰…²Hµë^õÀñY,[æ’ylÚÃ'©©<À ãhµU—˜oüµ”0õÿ«Ç9s…?ô(¤nª:ƵJBQ ½AúÎOÀRµËjâü¡ ÃªªðµÇ1¬T¡*ȉ©ñxdÁ9÷I_$Nzïä¥ÛJv[ža~ªc›FTMy䬶kU41 N->-H:j ç€ÙlÊu‚GXªê%°B%÷IÇJÁJ}ÙR½ …Óì7h%’¶¢/ Àµ›À¨_’ýLø‘ó¥±›xü•µNX÷H£­KiMMv¢œ$˜0Þ“:Y>žºØµxu‘2~ìÌǫݬØlí°§h„t~7º¨Iþ†©B +´4Óu ×§ ³ƒFbû'‹Áöú÷m—ú ïd íhѱ^É‘,¥©}M{ú:6©)w0y‚ª«Ceó#ËÄ?hòMYYÌmÞ¯†ÈþG$3••ùÞ–T™d$„±+ÕŽ.¿*¯ÂeyÃ/ß×´7„/Ý0ú·ÚC”ºÝÑïËpÔ ' dÍ@Α Ï—2KiÖUèÕÕA掼sú~¤ ¨óÞüîÔçÝ£#¿Žö~0~3]öº+ø<Íö?]•.‹Ö‘ÿ0†Í†Ä››ïþz»x˜ßß\ÿ@½~MãïÂô¬Rkˆü §4WFéËß$•Œ Ô?£Š4EŽi7247ã'ö¹Çé8ÅQü1ÝmÒq6 ý*Ò,èj’9>ë‹Â_æë¼,Vßì§ZäY}lE–Ô93âbL5Üïô›ŽÇæÁÿ¨¯Ès¹ÔW¶ÎÀì:ýÓS¶Îÿ`ÿÙ6]0ë71Ta>º¦ÖÒ?aøe­Tû¦<¥»Å¦ DËwåjÕîÕûºQëóÄ£éa+âÿÑ*<Ù™¥o[ –‹¡u†Ú°Þ鸖”'ܘ¥;] Ib ;NÈæ({&´—–Åï1s7´|Nð)íkãÌŽtF(–`sõ†.‰¢û–,8Q±r0IîË~ž²"MTX;Ïõ'cÏ Äq~¨w†q]ËÁ¸,S•?˜• ø 6¨7ÅWz}/|²=•n— † Dwûbg³­ jé~hþã³2ïœ6.¸b)í…ÿìIŠð3ø-‡1fÇXpQ6„¹P ø¼´V—ÕÝ·¤#ÏI›ûME@ý¯mnphÄz+94~¬%š6k> endobj 3201 0 obj << /D [3199 0 R /XYZ 89 721 null] >> endobj 902 0 obj << /D [3199 0 R /XYZ 90 517.275 null] >> endobj 3198 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3204 0 obj << /Length 1936 /Filter /FlateDecode >> stream xÚ½X[oÛ6~ϯÐò$5KR÷t-5Y–¡iºØht…!Û´­Õ’2÷ðƒÏ¹G‘ØKŒ¼¿B\}摪Céx¥]o¶NëZ:M€f›+A׳ÒàÛ˜=ÓÝn§“¼›í•0þ]Ϫl*´6ÉŠ­Àö Ú7×z_9Ûæ¢hÒ&+ Ò±ˆù^ŽOþÐvd˜BwŸå'ï?Pgóà?$J"ç^®Ê/‰I@1¨×Îèä—G*eÞaÔ&”ù>¨œ ñI‡:@Dsp‡Oe Aº(gõÙÙRšK›JšéÁؠϹÖógßžt9 é9;O‡ ƒ 1Ìaü=ëÛäëM¸€l¶õj2MgƒÜ¿ÍQ<½Iw§ˆ ÿzÕ_§&+ލÑ<…}º#­[r5Õt–†/pÚæ!Å÷M&ú€l¡lc´¼§HVOD¾Ù[åùóEº®Ek a@’(îêct0ô ë DíÅ -äé®cÇ€°/9`’q{Œ!+ú1xzÁß_C¾G Ø·ÄŒ™NbBÅ÷á Me‰ò*+tÈûÃ@ g@Ó)às]i’Št15@~J³œÂ<“­ƒ°ƒŒS7eµO7Ö™ZªS;aõ‘½Çu¾„Ä}¿¬‡§õiÕþYÆÔ-: 3“c?á‚t½í}é4†8t“!: J#öÜë…* @8+ÁТFò©‚ï\àÓWHRpspí·›;<ÁÑä]S¥òÅ V´,‡‹ªÌTíM‹à!S.ѹbûÆH“i‹5݇"mË$n—IóÖŠ¹È§àxHßšÆ0hb¡ˆ<ú‘↠=7òT,ÃXñ³6¡~áíí6‘wÀ#nh´"›GЯy´Uíy„ÁÿÌãAi ~ e‰OÃNMéš¶­dÝ*ò4+ÚÚÖ”_*b¥–`Ø´ûqØ–8ñrô¸tbÜ#þ¾\×%Ó¤n°„ÐE›PÞ™ßÖz2]ß§ŽP›íÄlÛˆùdU–{€³äÀ7Ç<éAâCvôqT/rE:ŸlÊ:Ã’¦GwÀko€Fí¹&”8Q[ÞµZ/2%ÎPµ]p1ô’„Düà}Ó> endobj 3197 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [228.015 646.294 242.461 657.198] /A << /S /GoTo /D (figure.caption.3) >> >> endobj 3205 0 obj << /D [3203 0 R /XYZ 89 721 null] >> endobj 906 0 obj << /D [3203 0 R /XYZ 90 690.045 null] >> endobj 910 0 obj << /D [3203 0 R /XYZ 90 334.693 null] >> endobj 3202 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3209 0 obj << /Length 1864 /Filter /FlateDecode >> stream xÚµW[sÛº~÷¯à䉚9d‚W÷¼¸'vêN“´‘ÎIgÒŒ&a‰ /* Úñtúß»‹%Q¢•´>\`oß.v—ÌY;Ìy{ñûÕÅë›$t2?‹ƒØY=8s–ú,ŒœUá|vùÃÕŸW×^17ö^3÷ÓÇÛÕíû·D¼¢eµÈ„{õþíú|sýÛí/×´_ÊÜß`ù²úãë›(8P¢¶(sŒ>.2¼tÁ¬…¯o8;¼î‰(ó‘9^QX®páq°Œ¹¯–Zm·ª{×ê¶»¼,Ôã]§dq·mûR—móêo,â¿C ÞãÜÏ"ë)ž` â_³§ñ,5±<ÒC×,<4aTõY~+û/óºR°78ÑÛÓlŽ'`–ç±- Ò$«'ùÜß©o*´*î6mûücèã¬nEüsö4°Îܾ¿ùp·\}¼¾zGz~þ™ÖW·ÖE½Q/[@'µÒ›¶˜ò«¦¨fñÄ9<‚p–'²<+Ù¬Û»7êq©¥¶vfA‡gÁ‰Ï‚“ü08‡º‰Òï ËÛº–MñêGIg \-su[o«׿ÅdçðlŽGðS|»²YŸxèÏ!,‚s ñ?"<ôÿÄ"üAˆ÷ÎÍˉÎb<[?Drò¦MµzSv*Ç‚ þ——Wà¿ÆD’Z¿ˆszçÌú ü^é»GY &}€ÐíU›ºù¢·!;ôvW®Çõzuñ [æpì)"L|!œ¼¾øü…9A¢Ÿd‰ód.ÕŽÈR?bØ*gyñjM“NÁYègaèˆ òC*E]†{XUqw rÈ[(RÔoÄ”8ò±í¦P ¹Ð#"qûÄL§JbŸ‹§­oÇCî‡I:EhoYìašXÖµ‹ rŸˆjlø–«­QlHº¥5¯JÕhÚ—ölcåB T‰rQ€*ˆŠ]‡vÍPß«Î2[Z;Xi­•ÖAv©¹ö'nF Ê®èk…-3s õÿÃ;UCuP²¦CÒ–¸COV%®4”*Þ‚9Bn"ô}a›‘÷^©†Hä+ µÃß$ÆÄü¯`J½°ùchÑ–÷eUêgº%ó®í{{XIýÐvÆH&ÜäÃ:ƒg¿6å7â¨Ê¯ ÎH`â¶Pޤ6Õ¯õϽVõOð^–ÚZÒ[]t§(F/ªŸ·Êh 5Jž‰é¡@>•zc3€–‡¡ªl𡎩Iî3¬=Î&(qM!;›EUyßÉîyGîOVˆžf’Õ‚n€uý.`̺‚æNæ>ƒ€yØøq ¹Ú„8}²‰ðEŒo9s'cÇé‹Í@=§/03îÞjR\´ª§]Óê 8rtn’7”|‚C<›¼ LlsAuÖ¶©ži<”—©ðyšLc¶U…\·ë2'°†^®çК¼B‘F0ïxØÆE#ZQúRKŸÅÑq£dfüæ¾àÉ D Pl!J#[¨d®£`ÈÓFÚK&Ìmõ€ïB•ž1Ž'¡óì?².ÝÝCŽl£ðÀƄǀ.BøA€ƒ£j0Æ 1§˜™ì513élÓz.<ß‹N(`ZòpÀ-ær¿…sþýЭ‚ô$ŽmdAÂÐiÆùEæaê‡`ôX?B2%öq>ef¶5!…ùv´¥Ã|x4íÌŽ CSŒÛO ž‚ú¢Åó§¹$…¦ðælM3ÂÛ0Äð,p¿7î¸i:H–¼îdÝÓ—Ä ã±D÷É·²’÷•¢sk n?-BFÆàø„Id&‚½Úë²bIŸW¸¹¬*eíÊÛ¦oGur»­Ê\Ž>1ŸšBÄ^l$)Wt°Ópt‹¥e‡WÖi“üðñеµ½OË»¥÷æÃ’öO;ÍöJc¸„[ÂÛïiKO÷le—5€j‡ùrƵ¼’}†a–ÅÌýõýí_q·ƒ9äÆ% ž‡Z¤,cÙLn ÈëL;Œª‡{/ßÈ-Ô¨Þ€€ç’–æ†ÙCHLÉ› š§é§þó(Uس¾­m…Óà'Ç’ ¥¡ºŒfT²«ÃÇ0¡ ‰w/üîþËtœé endstream endobj 3208 0 obj << /Type /Page /Contents 3209 0 R /Resources 3207 0 R /MediaBox [0 0 612 792] /Parent 3206 0 R >> endobj 3210 0 obj << /D [3208 0 R /XYZ 89 721 null] >> endobj 914 0 obj << /D [3208 0 R /XYZ 90 176.057 null] >> endobj 3207 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3215 0 obj << /Length 1417 /Filter /FlateDecode >> stream xÚ­WKsÛ6¾ëWðHÍT4I€/ßÜø÷¶®’’Œ‡– Š`IÐŽÿ}Ø…DJš4f<2Ýåî·,–¡·õBïnöërvq›q¯Š4N½åÆ+B/ ó 䉷\{Ÿü7o¯þXÞ<Ìqúi0_$iè|¸_Þ¿»Câ>–ó‚ùWïî~Çíõ͇û77¸þ ÞÏCÿ<¾,»¸Mâ‘An¬%)À±ö"¡YHŸÞ"Îó b1,Ò€¥¾v+·C'Êìr¾`‘ÁfËf«±ó8ñŸåŠ{Ñ=Ï£Äîw¥lpõ"›µ2Â/07ËY‹Ð‹LœXʃˆgÞj7û{d,æ¹eŽ––å^!ÂÅý.fÞµšý N³“Y€ÞÅH1&8QP$7ÌcYäz$A4_DaWbŸxêytäùâólþ9ï·]ÙVrUÖ¸•ݦ„7Ns£À½•µ8!u}¨ú”ú«aPO±¯™§î7©‘O‚Ó.g'MÖa°çÜ`Üù>Ì¡ÓIáÂʇ¥àzä!éU (eÁs-û¶._/*¹ıà@v“*„ý¡ôas½ÐE¸×âɤaØN!&Ó‚MíÞ°!<Óé]@WtD1‰{1E{5èvи&Æ“êI¸F÷,¹¶¡Îü«º>R‰*(Á[%úQ^³ð wl&•n³¿·De'7ô$t’ôBÖ¢ ÎyŽÁ,Rÿ-žþ"sq¥±Çv¢Õ^ô$?œ•“TÃ~HØ7åN ÙO ÚK¶ö8,gÓ†Ôµ™=—Z<$æÊ ‹±³-‰Œ·",ž”Öj‡k{eŽ™cëfo‡.«†” ¼‡šÔbƒ¨íÈ sqï•á¤p ÉøŒVeÞìzصîþ?ö„1Ï#謯f÷¬@–÷šˆ¯HDD|z?Æ8]fïÆ!8ÿŽ4ФFjÎ 10ɧE~˜bô£é÷Ö§—GHàýö½‘& á^INg0iÄCgÚ|7À•ö§#Ëñ óý ñÌý{sj83Íamæpž¸þ ‚Ξ]ÏÇ7&¦V4Am'ÍÀj”Ù£ÌiÞrrȲ£=±N#ÆB„Qñç¾8€OªIˆÈ¹±±ÇÛq£”$AÌ‹iá|¢ÛÑ|ƒu[ú{0C„ŸMþ¼Pí€ÆÜÐbF=½¿úûU'[úD1ÞÆMxîêv@ÏÝËð¥ùk'B endstream endobj 3214 0 obj << /Type /Page /Contents 3215 0 R /Resources 3213 0 R /MediaBox [0 0 612 792] /Parent 3206 0 R /Annots [ 3212 0 R ] >> endobj 3211 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./47_home_taurel_tango_manual_ds_writing_nt_server_main.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3218 0 R /BBox [0 0 387 415] /Resources << /ProcSet [ /PDF /ImageC ] /ExtGState << /R7 3219 0 R >>/XObject << /R8 3220 0 R >>>> /Length 61 /Filter /FlateDecode >> stream xœ+T0Ð3T0A(œË¥d®^ÌU¨`la–R0145Ð3°²t4X˜@•Z(¸äs!> endobj 3219 0 obj << /Type /ExtGState /OPM 1 >> endobj 3220 0 obj << /Subtype /Image /ColorSpace /DeviceRGB /Width 387 /Height 415 /BitsPerComponent 8 /Filter /FlateDecode /DecodeParms << /Predictor 15 /Columns 387 /Colors 3 >> /Length 17939 >> stream xœíizë:®E‘‘ÏìèÎL5²ûRa…BG°Qãd¯ùl‰sAùcßw€›x½^ÿþûïǧýùóçîÁ~#ÿüó϶mÿ¯DÿùÏîà×ñ©?P"ÀÍØJôzíw ð+Ø÷A‰÷%à·ðï¿ó…?>>>¡«<Ñ6ÐK©•R¢)Ûôý“àJ>5"®ŠÐU¾*Ñ@­³”(ÖÅGVäð`&«ƒÊÚ;‰ÿ‹Ç°½^¯ $=Y‰8ýd*…ÏûðÏ?Ù›P¡«|U¢ZC;`· áä€×£x¬ásÂØ.i¿·—ÿ–³½øIO\Ï'¼ŽÇòfJø‘DJW%Ü”p?P"Àýt+‘™sùY·f{éácÄÉækûjŽDÉt}åX…ù¹m~˜g>í#JtÞhò­]?Ãu™1@‰À;%J5xËô¾þÀ]¼±™Þ™÷t’.%ŠûgÍ×3Ãh ¨§šãá%¡bà.f>íäìĉĴ÷F3óª©)f_W*‘w±¯ã³< õ„JnAOóBóÓìN´‰nW":J’–§á1x?ãŽ0Ãä§}à“|®éÎâÆ›ýƦ‡îëJ% `–‡Ç2ùiœ-œHM% Fu½MäÕ‚·`òÓþh%šŸWº…L_Þë…½xµâD¼€h'7Ñ¥Dñ§ÚkMp¢ÕÕžâ–›4µÀìk¡‰#z0úT5ÄÌ‘Z#{aí <€X‰(ü´Sø±÷èV"pP"ð¦ |tû”HÛµ•®^óx=žÚi×0è´‘@‰À-ÌÚOW"p6kýYnJxK D€ûîÇV¢ÀÇ)O¦^Å×/+ý÷o…¿­åõqiödÚ¼W¢#~J,p&/D¬îÓ÷î“ÞÄØ÷¹¦[Zëm NÕœ56QùDšÕk³™‰=Ü»hÏœ@‰øÙý‹äĪmÖòfï$e¥©ò[gÜLþ_ã?§'R1¡D`’¬5?åB_ÈÒ#q<)[| ùÁ|NaìÄSžH‰EУ)¢zSÚD„_㤴™Vðv¤,/„u%“tØDZkD+\YL Èlk¨eÊŒFϨúZ”ÔÞY%vÓ–Ó«õŸ¯Ë‹‰êÍû_Ùÿ÷ÛäQ&v¯ôÍ1ïLÐM"%âryÁ[¤ã§ÓóËÌ2ú­žcžH '‚”Öxº#f£ÇÑ3Ü¡îbsCI[½@î1éò|xŘ"%7âæè{UÞêp”LÒP"RBS« [F7êÕÒÞ™ù9Ä+ø¶ÿœzòxê“)`n4ûû÷¯'C¼˜Y}€ÒïÔ“’ 7mL}˜uÍÖÊ­n×@Ú&ũA•¸.oÁlDAZ†>|||hA‰…F˜KâˆæÇceì] 3»Óƒ©.9«•Hywi;Z‹ï œ@Û&šlÝóà= Œ©`=žHú ž½ºX°Ã.©/ó–‘éš»dmïÐQ€Dƒ.7‹A‰ÀIt+Qlò˜Åôk®På¸öïºâ/:8Âçds´¼ /ŸT¢ÌÀÆÄˆç ‘eÕYĘo½×¢©z J–s®MD­(’ÆT¼ŽÆcCz¾ñ×MU8È?äÑ"qœŽŽž7{3ÄÆW½p󺶯6¯ž£(8‰¾8‘© ÍØù–T²º(ÌšÉÍñMNŽ0ñülIq¬GÌÐ5÷•D×üøŒHa9—­Â±Äˆ[äi/`J&iä dÉÖ›µL£)¹l'ì=¸Ðhm2eÈ3‚”ÅÝÊçžbRЋ¾:] ¶†ÄÝ«ò2P"0IJ‰’ëbÍž<]‹'XÎ7ËLLÅÉæÕLÌ©>÷ËxSºb’Ø53Ccúuòz)mCÕ×"RÖ쀀†‘e‰•¬ØnêòËšêÃ[ü2v@«GÔª¯©å ‘cñyž‘¤Ýúñ³/ 4~¥¥Á¦í“—-ØD`-Y›(N2…IW 1þǪ̈֫i% T&SWñÖËøëæ¨ÿŽ4 ›eè+éñÓ<ä#¯ƒïJhJ ´”LÒ¶‰¨µœoÚ/Ä$Ch YNEGô5c „A”,\- s0Ïúج°‘¹<Ï x:ÂW ?•¨f]×F´·X&¯Ý68ƒ”‘³ý• ‡©_^`2{~Ÿ(“‰U Œœ¥%³Š>Elúy¢é]W9nF ÅÁ@aÍŠõøÎ6² µÝÔr>õøbúa,§í™Ä›H*WSzÈÊ¥öêŽÙDb–š2ä¥tà™z^ίÐñ#ú/ë—^¼Ój«_45((›œA*bíe'rÌZõu\+i.UºdHL*ÓJÒÖ„9 uœÈ¿p”êÔÕ¡hbZãDÛWÞ?ȯT #^ïO›œAÖ;#g«§¹X&j‘Šé‘Ù‚ii×Ìô ¼¯}-7¼°yœxŸä¹i<㉚)Lf::qb…ÎT"ï/¿L³S}7t‚MV3¢D䄊ˆiG°Ö¯ŽéÐ’6©ê”3E$0 Ä`¼#zêVô Ì[sÚ¥â¦èNãý¾ŽO>á M›…yBsE™àÈ›œ@_œHÄn’ºã• *zM•¿Ü&2ÕD‹‘ixóÍœ¥õ…Ž[ÓÑÊË,œkOŠŸï…RÔ=á’ººGïVÄh1‚I²JÔ\È7…„E3ðy5“‰„)a~ù t±@¡šJQ…Ò+£ãÊ|<–‘^þCŽCGUòÆã‡µ¤"ÖÃM{2”I•äo9"JÂ_ÇS+Y¦yª¼HæÆÄí‹uz:úwâ”iÕ6¹<™Âë¸!”¬¥mQndžÐ1ÏšÕùq–„Ø®×`:yßçof61g#g&0;¡qåÆÅZDÊ…}\ï¤A‰À$‘iÈ„„Èr©1"'2­—ÆËkï[ÿåe„¦‰'õBÊÖÜy1 ˜jh* ‰7°ü€¡D`9)%Ê´"œ/r¶q˜uSÂ){±G‚yöŸHÞë Jѯ)|Àq݌֘K”h@µÅåC‰À$)Î/“™yŒtôÝH†xkÿùÞ!Q©3¿Õ¯/ V"/,Í«Çgő⒡R¦wÖÕu¦A‰Àjú”ˆ1#QËóÑbªGb%œ'Få¶TÑÛ„QàÞY¯•±­'Q@´öù«ëtuxZ‰<›hàvñº%ëèX;˘õAòmÏw«ýê\j:Ã3*ImÖ{dµ—訪) ±-óú~À¿d¾{cg©Õ“šØu¡D`-8‘º¦ÐSkv7b¦/ê/vR_Ñ›oPЄ`ÕI^sã\j²ò3]7…• PY5ã’ǵŒ”í³V¯kSõž¬jüN²Þ™·È¥cCI©2½63‘ÚœEËgWÐ77(±#?³„Ï»kj¿Òý a 都+íº™P"°–¶MÔ\€Ï÷¤£BfIm™ÅøüLªÒÀdÛ¾Ã<³9Ï<qåIÚ¾kJá~|>‘Ù2l"ðXRq"S2š‹ýº3ÉÈìE'R›F0+<+#‰®U›}·à×AjÛD*îQ¼*ŠÉ/àÆQÜ”¾“›"3ïq"°ŠŽkOxC¦³¦3õ[˜ØÉ)­~Ü«(¤Í“‘ÈWoœ.´ß;}оWÊÈß Ãï˜~á ¬YE&(XGÛ&òð¶eè2¦ÅèEδäs†O!]]·g¹x«{f#AúÒ<ÏK äÏ4'½› ,¾º:A‰À::¼3ó¸N2£ÝMÛJSòªã¹áM'®G«àsOg]6µ¬yªŠÑÎ3ä £d7S¬©­½µY(XEŸM$²~Ì FÞ.Yþ]RŒâ¨ŒH‰½-4»Þ”µ•°(fŠ)ÿk¶)6¾jŠFðFLɺˆÙ`¥¤ò‰¼Å{Ó\"½LtW=[ò3g¡-`ª?»¤³GóxU"ï¤7¾‰;9ys D`-Y›(óQk&‘ÒÖuùê×û>C,CÁñd³e¸M¤%þÏ÷³ŠÆ(y«¹A‰À$S»=âv3)Ž:™Ûü†C'ÔZ#ÛÍ‘l¾ƒô7ØU v—ôÎòõRe¨DÙ¡D`’ì*>©ï=3S1ˆÅ# ÿw2 ™ÄeÎÝ ìaqÌt”IíKD¬uüÎ{~ãÂ!•°‰À²»=D è£Ý.j%eVÖþL?~Œúª3ŽŒx1ÖW/{ëµ{âñ 3@‰ÀZFÖÎÄëÀeÈ$åwõ;´zjÅ­V÷P¼K¼3]¬*QÆ„ÌôB–”¬¥m ×Ì[v~‹Q >‘dtªÝSe¨Ì+vÆë¿ÉüLî}KÂï”L2’cdTÇ¹Žºnmd:€ÉdÂIò¶Lý+ªÄVƘ< »au¦5Ûp§Á`Ê (XB·wV« ¥à_ÑÚª2Wšƒ•{^†Á¸Ë ªÔað‡–‰³ÃÍ6‹ÿ¬…ƒ1áMaí ÌÓ¡Dñ¾!/KH‡±=÷­ÿçŸø7ÿÇÇ -]-ÑÝÈö½éÁŒ'—ÛÑ=ê_îÒyè½c,!'2ÅÅT%SÈ·wt–€/b´³ß\eõ6¢û Z3Ulø¸ˆ‘ð×'I!l"°–Tf£·¨«9kS¿¼¾Ì0öçë’P“Ù%Ë™œ–› ¸h'(?¤yج¶y[ ”¬%ëŸc”H¡Ö‰yº}:ŠQ=˜I&ëÛ¼dèƒÁ㪀w9|Tž™»ö– € D`5ÙÌÆ@S‚$£ ã @ãÐ,ôÔ<ĬË0!=t´eÎðμ0ßÚu}ØD`-ÝùDc:U PKª<³¨Ùi°bÞ"¨-Ä2dÞæŽ¹IEð†ä-Söîà ú­÷6˜ddß‹"y©Õyë&_Rô+ŽïÖÃg‡ßÿ-ˆ½´Ô]2ÿe:èfæyñFê뤅X^ ³,¡O‰è¸Î%yz&­‰S3ʵ«§Ü/ñƒÊ‹¦×µxÞŽ¹ @Q¢ Œè6˜$k‰:A bR€òkm½¶†¡²#lÿb‰Y4*â¬B[jBˆ‡×špË6˜$eyª¡ó€2ÖALÆêÉà-·çåCEÁ–Ëw<«æ.ì‚÷¿¤¼¯íü6ÚJ$bC3e"f™®<É‚öÑ„Õ0 (Á’yfHt‚Uª¼fò fL!¯Ù…­_HJ‰xÑU$'C—ÆöÔ®~Æ~Lºô¨rö–ÔÂrƒ( ”LÒÙ8Ã@ËA Lo_f${Xòs~ÀS«d«+M< ”L’õμ·tŽÁoº„]]q¢×÷ã„^þ#¨òqëå DÛq'ÊZ%“´×Î<¶VÌÖ®¬[™‘¡x¶Ï¯Ùw™EºäËynÑI@‰À$Ùµ33Q¨×:Ïïh|&xœ¢æ$»˜”¤@|¡D`’lÄ:H˜ŽƒÊ½‘_5Ö5ž(ÜewpÊÁ{’¤®ÒìbIô:ß‚ðݪê½Í4¸ãé±`ãkg:™ÈcùfŽÚ’Áä»ëQ+±¤íëÖÎ>>f[@pý‘,x*H°„?°,8»—~’‘o3o8o¶ ÌÛ|•·°†b>/áÒ%|(Ñep?†GˆòåËk®/ú{˜{4<â»}­àh?‘NËrDªK‰Ä…¼ ü[áR1‚ýP.}RZ“Ï®?>>šÓ’(¯‹ ™ÁoÏ&:uò{@õÅÃ…i»ë7`¡D?”5ÞÙÂòb¡=3'¹¿&âVü¸YE\2ÿ¹áÖ[kù`Nbckg%Ó,P¢d²bWƒÂø7‹q»F§;ÒÑ/»2¹¹Ì4Ç‚*ôV‘£úQ¹4bí¡ ŠóV\í}NÎí{§RšDÇ9™1ôœ÷TàÊÙžìkÌŒº—z{¡D`ž•«øÍ’% CLk„cEGKG¼0'ª¶&‚põËpõÙ*PM¤à*¼k| Üî£'äA‰Þœî}gÃhQ õXûòá.áç:!=mªgI‰ï4$ZE %Zhôë'Èd¬Œõ{å'ØDAÊkJTáņÇT ºK6Õ5’kYì™&RÝlQÑûBø)î éñfE]Âß¾Í.>sí¬}1£•l–ä¶Òy[ÞøÆÒ¬ßÛ&JFÁuƒ¦4Ä­£jJa^‰2Wô0=Z£D±¶«DgTÖþ”˜œÚ“J¼­}• º¢ä~¾MÏV:»ßjuÿó+Q×bœhSKð4+êÆ“–ZïHn┈5Wœª2Ü{Òʵ[y@5¼ÈGì Ñi[=~9õ?òÞq¢Þœ€X‰Æ¹·ÇˆÑ¹kgfÀøu|l˜Nâ‰*ZƒÆ¬nX=MŒ8¤&ü~Þ$¢EJ”š8”,3_€ÒJÔÕ×}¬T"±­ ŸcAxˆ¬H³®ÛGo7Ûo$y»ê÷Äýb4 Dg'n63±Ôa@b’eòÅ.gYœÈ´8ô§™Ç8ù¦Y^€D´hc#}<À«ž©—YÎ’NϹùÏ}c%âó1—²ür˜×Ș]ÔMÌ*QÙ)&6õ¨ 6.‰ŽZn¼·ZnÄ0DI=6]ñlnÑ»ø8Åm¼ÿ9Ö'Í®ë•èTM.>#J$~t¨zaÞ s[Ouo¯† \^‰¸¨*æP¹-6Ðã/Aܺ7¶‰ò êf¡DëQ¢]íí*#!ê=ÁÃŒ íì¡"<Â-¾“¦„N&ª(¬-‘ˆT_ÏHÒ»Ø;cÔ«û 6Ñ@V”h %‹ëü—”hm›HÿÔ_Ù:y±ai³ºHÎ6g‚öõD|äÜêÕ5/*ÿ«Ðß=åï»*QoZ3A‰Î"R"Ó*ŸE­w¡ƒAæl×=]( š{èÌŸEäû2¯§\—ß2N4¶|%:‡†Uï†kèl*Ü«Í -"$”´PÌu:Žñ!–蔑!‘%x`$›kÊöš¶ƒ´Yú~J4/"K}“ŠX×rñ•LÄŽ_’Ü>âájRÑ3´ä퉅 ôëÉhjŒ*g¹ nŒ÷ó΢DÉFODßî ÿÖ5%ÆŒ4óÏqÕ2aUÕŽ¼u4:ª˜©#uJÔvÌ_²õ„¯ =€3,‘a® ¿á?V‰–¤G7‹!Çú‹¶ CÆ[`&?˜Œ˜ b6¢£ÔâÔŒAÄÇ“)¶±§£ÍwšìñTOÍìî‡xgÔˆL™3¶Œ`ß…¾ ŸóÂÑ%ƒò"U/ö²T¦*ï4˜P¢×÷Î~ïŠÄúZ@S\LÙ]( ¢)¯å®ó…7ÅO°‰’,W¢áÁü¶½øZGʔڡ§wWDFØV"ž]Neæ^=«3‰¸»·$ZTE“k ¥G\Å€úÌ “>ø®JdVÉp† &ÙWo 71˜c-&— :W–¦ˆ¨“n¡9©6õ›\%j>Td¶ðêxÀx§ ™…¾¥™µt Á–ý…Jæ_ëlÁfôèöÙ‘lœˆ|ÏË;eÒeŒªá­èëy¸©,'nÓM ‡vQ—Û>OC+ÚöŽq¢|Ýù5øIÉäX&›JV¼ƒvœˆ¬ î|¾eüï¬8.|´ýÈK%sï*›‰”- Fn.ÏÍÀ­³{e(ß;/ÔÒ§<{êJôãyäÒûB™URNñpÌÎÒw+eQ€¨å‚™JÄ›ÍK‰˜?ÛsoJa¾Ybò÷ã ¢‚¶‰î÷Î~<¿Y‰ˆMT3=‡“™Ã¦Ù"$É;"N·9©µº&Ó ½Ït}c†Ró¬~ ›hœ*1ï–½–¶MTÊ5W¸ÍIËßšî•.f®Åö/D™Ì2gšénð·AyíËse_]¨÷J4Îüö·Á‚߀åo…ÙR>¦Â±ª…ãÙUK6­-S¸[÷úÎ$òúgZÜûZ–÷xÒ%lG Dã¬J&zs²6QÌÞ¹‚f¶ÀçŒ×”0£„¾Ä+ô›t˜¥·[(Ëáw#siúN"N4ÅÌ3’~ ›(ØF/ÒÒTš¸AÓ)+Ž›#sviãG~žÖh†¯‘›Bôý_€M4K^Œ~¢ Q—Mä-`é`³&öøuã-ób¦ÜˆQåM$}<à7蔉)ßå5l¢e4ÞöCI=)­¾(OØ([óµ74` u3Ïf!g}M+—Ž”keÑñ¬_«>íÄÕ¿P"0IÃ;3… °&øÌu=cÊ\5çájø³SêPw–ˆ‡£ú«e–„µ3°ŽT޵éõ˜!ZçsØ4Oô[0»´ÏÈÏŠŠ±ƒ&°…QÛz‹'L“6ÔóM01BØD`’lœ(p”ÌÝ!õ¬°äÂ¥}íV(J·P_ ÝÔb6t1&b–jYÑnNÜ—%“¤v{ðÙ®3°µßÄ;ØX8‰O°`®r냔 –ý%±)$.R¨•°Îô%…7È߃' ðÎÀ<³™”°‰È‰F××Ú*1}=ù¹* “Ê”À–”Ù7îªÆl6þV RKl"0Iwf£x@½ùS‰‚gWñfñ¹¯ð9\®€›õ»zx¢q3‚®‡*Ê×F„½]zäý/Ä(˜¤c߯PVó¡J¤ý¬Z×3Oˆ)ï¨ö^Îw@l…†Œv-u>µ¸Dê1åÙéFLkî°1ø‚wVZ;£oMÙ¿Õ+_àUxÅê ÑQݪД_4òB<Ä6åz?a¦{Ô ·æõ×)ӣܘ˶ ;¶£;FG%‚M&É*Q“{`Pñ¡^Ç}§t å<F 9ÄßÖ_¬6õHnºßòÖôPôÁ¸ñ·f³ vgN·‰~êά_°É>IêùD:†ÍUFÌIÓèК¢5îu\bó\¤‚¹!®ŽÄôËø‘8=fóZªàn*\B!˜wDhPåqJTxþ¬†}Ó±v¦cÕ¼ á‹ÑQ›øëjL™GUCý—ü¼§@Èv¥ÊÍËá¼£0eôTHÒéÞÙðѳç6”è›ÁUüdëÑ!^Ó¬ÐG¶ã#ñÍA¶›~®Û~\k’ܲ+Ô'sQ^Éëéƒi Õ㵉*ÞP¢oÚO¡Ðê ®?nNcŽðÔJûu|rv éºäH‰>Ø›<•áÆÑ*á3eˆ D`š¬MÔû G±hżï5%4\Èt”Úû•Zí.FP-àÙPÁ5Ö5»fP¿Kž`+ „#ö›È—·úiPé~RZ†Ýy£ðžt¿dï­¬i…áª"@uÝ-àÅÒ7§oVüah="f´žÛ÷òŸ½c|¿éañb…jzóøôb–ˆs×òæSý…$„Fho™×Òcn^8ÅŽ‹&âÇÆ‰À«Uº!b=ð»ƒP¢“µ‰¼Ð¬ù—ŸÝÙ“ík›¼oò]¡z}kgü­øæ¯F_çòzÒ°«©çöð†!Œ)R`êwE#¢݈é]Ö³âêÎS™ ÐzôD›(YkøQö—)Q׺áŒyÕ/aÐ&¢žpræŸi²l+SŒt€&@xg\%¹ÐTǪôè- r1ÐSñ:ä•̘`æê¡6Q¦Öä&Q=£½r6¾°ö¯büùD%¢£/æý쮞£FG™ ÖæŒàTmm?Æ¿k.+¼¼0k1²Š¢ ¢Úi½:÷]΋ìéÞY³V3h2 k Œp¾ÀOR¢g­•ß !–Q=“TI~¬½`5^§zÓ¿iFñÂõ漜jïÎöüˆu³Ö’Ÿî2yzÛöÝj±÷ù©ën%âA-ñp²˜-6mßÑÅŠ Ô”9$R¡™zÐ쎎†O=%l1òãAÜ׫ÏKªíhGæ­cC&ï' ô]]ÈŸÖÁ*ªG¼q^Œ¡1UúíJ$ äO-¡ÇOR"1»ø;Ÿ®âíYIÚ9⧈J¦ æimãðKØT\œŸz±Ÿº}Y«lºwÑŽé$jgí ‹Ñûyg 3â>+kAu¯…€·z”J÷*>·Dø¶xÞ¢ˆ’ÃG¼¨TÛ1`Þ2xFüˆö­Ê[í…ñòú™Bøx­¢b¥Œ¸Áµ_I 7ÚDM6õl¢Á4¹ÀÓ,ÜgƉLøYí‰ìVº£éU ÉÐ& w͈©ÐQL,ç–ˆg+ñãÚçâVƒG¦5$š]©VU FÁ‘Ç)ÑØxòÑîd «”((Ÿé¥ÙBo#'Ð'âë—••xß¼÷Ì ½RFG#ˆœßöà…Imþðd¨iªp{ç‰Ô¼¤~Í ¼Ø¶z<2·]àŸÎTœ¨ÎXú~ÂÙ~L·oÅnþŠ^¢"eì˜C7ˈh‘.Ð4”ꨄáÆGë¹f^بV?Õ¢¹(˜§­D¦3BÎŒªš²W»ykÞZÛÿéýf Û,OßJĽ Ý—iy^‰(@–âìÖÊývļê<óœ'‚§{gà§Ómé)',=¥cÓƒ,KÄ\AÞ™p͈)£íè—™>”9˜í;TôúNVBÑM~˜$€IFöâL%ò ‹*œ—Ÿ•cÆŒ¸$ÑÑG‹•hûŽ‹ï~Ö§ª”ÛÃá_e=(˜¤Ã& Í›õë<|«‡' c‡ÔÊ=Y~?¸³Ôp-¦¬lGoÎT«@¸ßJNÁOJ&´‰¸ £„±³«}qPI¯âë”"]Rh¥éò~ùA®#-"ÂÈ2Û×g©Ÿw²2B(˜d6ÇÚ ?›Åt39ÀÜòJG#H‡èÞ&KÅÀL} HЬí`z¾ˆ,J&i(‘!òrgtfPFK€‡ 2Ft”ªúêúÍ·õš}™ë_!FR¶Ïï‘!‚iÆm"bD°0Ï7/µ{+#+ØAæØ„Þi‹LI°âiéFyæÒO‚_”L2¨D»Ê`¬§ôÄ+GÊï&Öƒq䨢c@üuSxãÔ²ÚÄ‘Zå¥~¼DûbâzãÁ¬â^ãÆ 2Á$S6QE É55>‘tô:3ŒfOeÄ©À€ ®å$X¨/—Il"0É%Òpÿ‹ÛMÂ5û„qÈÙ.;<$ÓÎ2ň”úxFŸ@»fk©æäÚ.æÇ ï ,¤±&µ&#¢ÈµSbx• )sGn9õñññ9nd ‡ ¼Z^̈Î_&Û¾cpåz.êày²ùDä,ZÅ#4%(ìE‚Š mÎoÞ›“–¯©‘õ hÄDYHĤµtž?%DvÿÞo|Þ•Â&“t(%Ã4ªGâ”™¾(Ò¬3?sôçø ®z™¬–Ô!!sÖiSè<ïLø­ô}9÷Š‘ ”LÒ§DµNÓùŠ]*j¥y;Îj;â¢yû¼Ga ­1ãÓžTÕ*ÜV¢QšVUýGè¿ôÑ D`’Tf£ý˜±äÀwk&I“eéºz'GÙÑYBãv'Ë)#®ËÍ“jaÕ'Ø’JžºÝGÜ'ûUðTÚ6Qa(lSJ(´˜Ìôh]R˜K%ZW¸š”$Õ㦇¥‚8ûñéÚ¦ñL¨ +êìØ}G©ùµh_˜|%)Ñ›ü` ee–Æ’Ò£«xG¼ê"ÌLé5{±L¦}1ó-G«Ïr1ª]‹œ&^æ£ç*AŒÞƒTĺ2vªy6YEøeÚf¬Ú|«Ê[G{±çvŸÁÆ~î­Ž³!'pö7í %:ï'ÏÀÈÆ‰º«Éºžg>ŠW AZtôÚ™·šæÁcCËý23ÚâÅÑèh"ñ­½‘Û~e¨÷wâÁSiljȚAÀ(iþ øn/õƒb<úÃ×ÂÊ-Rü¸ðÎ^jJ0½µ6¯ž&+’üì½ÆÑ J´öW¡ÁÝt¬™ ó¢¡ZE¯úÇ)BtÔ8=á—Ñ誙0‹öïÇàš«cõ-cÕq¿‹dÝ@³»"GÏR¢òàn:¼3¡ ¦‘#::{ˆØŒ D¬<éúº–Ñ¢#VÓöcÊ"åvÛ›l,™h‰*mážÈÉÞÅø?ò¼u=·W¢13ÊüÅW³ëá_öÆpö€/'±ö’€jÁw¸™›'Ì%:ªR DÜåx±!3ÍÏêã|VÇþÚðäoJ¡ic6LŽg‰lÝ'ZÒéÌOÎë‰=™ë”…k|¹õE¬½„FÝ¢YRdBò–µ_F=n·} ènã¨Z²Ó<±AdZ”Þ:@åzí¶ˆ5ÍÍ™åÂáÕ]e]6àËé[Åç˜vW²w ¿V4­!b?Qß”xÁ^¼^î‘ÕÖ^~B¦À´Ë }{_ß?Ù5˜áK{Ê*~×0zÓÆÌrœ ŒR Ë×ÅÏP"mæx†öæ†WÓÌ5,‘0Í5…ǀȚ]Uz¸Ê4…椰K‰”çŨà…üEËW†Šž˜Ù8Zå(Q:¸~À×2b™BcŠ…;ËD›º˜Îc4ÃÕÞËëŒ;p^´¥ö^e¨©ÝžY¤ïmW¨hžëöÍÛ^;™y›4Ròašá³f/Ë|!Y%Ò1 ýÖì Ôðð2z¸Aäõ¥MŒšmD=ëe'†¶ïŸÏÝŒ'N>ñŠ¿("þ•ˆ‰ÑXà&3±ó‰NË•h ¯Ëi(Q36a†*<ÁòŒ&üá!îRq©ÊÂmsJç#J¼¯ Ø ü&'­¼^âD3Üð|¢Omf±¼ËcŠ[Ë+Ñ]¾n%¢£ÐÔVâ…y²ÖÔ‚1yb±}?1#°nb­ÑQ!sÆž*CüõËÚ•2†øg]*ºùIi½Áìó&vWFO D—Iç3dˆzŸc]ßš‰EtÔ Ïwó’!ëÛúXX-(e”ú¹±ÕØifç>uöV§Œw: @^DI¼½l9ÿAÏl̬÷¯ÚL;©DÁ&Wͼ¦ÞT‰‚Ôg­2föcPF'µlo.±öÎn¥yv“W]M^_l~êå$I”1­NÎe£)Q!vC D^G÷‘Íl$?M1`A%3UÏ“ ¾*Ÿ 6“Z5óæ9—­e-Ÿ½_Kö)Ñoƒq Aç®ñÑ®^ÅÏt̺{'¶é…®™ÙQž¦D"Íë{éE0‰ÔÌõ2mÔè¹:–<ÉŽ¿ð‚G3”¾td_Z—å‹]࣫Dó^ÔZ5!— Lg ,Ï'ùJDþ*X\L„·½X¸ÎÒTuÙ7&ÁYmÕ<Ø´V‰ê\Õ1¸r>ÝÒ AAà­˜ñ£ Ì¢«•ˆúý z°5Ó¯¡D…@MÈ OòËÈ‘>ã i0Ã%ºe~„[¼©“¢BœúŠ»JbcÓö‹?Òr¯× Í"S£·vIFòÀ¨’ (6ˆ&ûZÞÈ9¤”ˆ|1ÀÔ¯2U-à‘OÙ ¢ñZ¸~çùeæ‘å³|¢#{¶Yô g6z…'gÒ#3›-Ü;àóÉ*Y ÒëyûeÚfyùµÌåü¦¸ˆõÂIË×Ëô˜w•c‡´9½¡±“¢EåÞ>elÀ@¶ñ©†Õr+/SæÇ(‘¹Fãdq·"öËL¢p™)¿¸æI~;¬Mu0æ29Ï{ö]@^îùÏXŸ;‘UëG3 '&{ص³pÀ'Ó¡DIJ¬¬•ƒ{˜‹˜1Rbœ_%ªFÐf=:ÖÉÀÔšè­ÙÇö]}kºÆ]ÿ,Ѩõùv.V"¯–Çy‘ﱉ‚#q-m%ö‹)C/k’v•ÐÈ_{šR}ºørò˜á!Ïäñ¼³fMßMè~yñúÚ©÷ñõ¹\b=w쪹}FØ%óÄ¢L§&?,NÔÜ™Á[ñDÇtÊèkWÇŒA”Ñ£ÚBr²-T¢º^F¹èO— ‚EL]òŒ5µ{r¬â¾­u™T(QÐ{³÷U¢Š™Ö(ZñVÖôºÛ@x¨`†ZøYmwè–·ãOÝ‹Øv0ª<\†Ltœ+jÒL‹¯Åxðh†ÇíöïF6ŸH×1×õub o¡– dhû†:eˆTD+‘^à’äª O†zãDä,É›)ì±YäéÑ*‡J&Ì'ª•M‘¢0Œ]¿‡yظœå³BÏØØµ¶ãò9YÞ\3P„_Bùâpõ 2×=Ö73kjÃ@‰À$ãk±áÀûN–‘øÜë9øe¦ dšª-Úê±v!iS?l_Èø\™2å¸o€§>&Su D`šŽÝ“=U”³B øÛ¦SfÖª¢`j_^zº¢Ý¦FÔ»çi°ò„­T_“¥øMŒ¯6zVß(˜¤Ï;£Ðì× D|™ŒÒ{)z-.gõu Ö,ùÂOÒŒRǘKûdy¬æ=ÌØSÞðæcäP"0I_ÄZJ)\5+%>åušñ  ±Gp¬Zj’'¯bš*Ú82ÛŸ—¾Î8y— D`’¾|"½X#Žó·± x^’YE¯yŵÊÄÓÁ>{ÿû÷/Y ôÌ%«õšüþXé>Ó/”LÒa‰õcrtªœz©gž¹f/+©:®U ¢çøebþ{24‹g½Ú°0ÅJ&i+Q C:_‘g-šËä±yQ FºJÕ…Ë "ÑQ,(UŒ¨g„q‚bRÉצI³J&É*YŠé¸@V[0šÍÏý@¬Zôu± ‘ci£Ãt‘ði&‚êS™¤-ýIZ[c’%“,Ëlô~ˆÇD¹p,Q"RKK«B°Iª'¨Suß´G¸!y™zƹ”|‡š D`š¾ˆ5©Ÿå¨eê!4ž¬ÄJäç³å®ŒjÁŽUåówýbõp4½WÖ¡D`’lœÈ$0ˆº, Œ q·®À­¡ËöÜ‹@õÛ‘Œˆ7•H|@‰À$Þ™@İõ£©=š1ˆ´ QO”º jV ¢“¬¡¸Ù“6Ó¼3p-}J¼®™Dûž_&ºuÁ‹ åÞ-f·ÐûPsu/øŽé¸A‰À$}kså…Ž«fu—¹Žìñ#'Cbv-6Ó„Y”T¯âÏ÷®ýˤ¶0 %“¤âD:h-‹Ä3.¼‡xäE'#CW†‡´!ÆY˜$=ê~¡DàzÚùD|ùÌK/âûÈwöPÔ Œ]ê·žǵ xfài2dr½A4f u‰QP¸·k(˜$»ïŒWøsÜ »ŸÇ¼ÉKìÑ$nÇdzÒU¹Ô¼÷æbÓ{ä{Êt·E J.¦O‰t˜³æÂyßá5Ž#LÓD2Oi!8)‰Ñ#6ˆ–hGï‘“K&"(˜f|¿Â­!R¿H¡Õ‡¿¥P’ˆÅ†DîÒ•ÑãS·˜ ¦¾…‹éÛK*z]#DÕpJD~ôGÛJZªŠ5$†tåZRW„èúu®3@Ä\Ovíì?Ö+âYú²~ôYèŽxÁáNÙ]Q|ÏÑþ50<ªz“¡Dàzw{xiD¤~›,°wÌ×õˆ7.S¢“ü²30 R~¶ëB Dàzú”(cñåüòÂsÊ̳äĆêk1©‚Ó$W®Ü ±øÓù€ýµÖ”\O·û‰W~ªú_fESŒÌ#ûñaæ@;®o”IzBzŒ±uI(˜¤C‰D´Hoy¥Ö£©EÀH»ôH®Q¢3ü²ç•š ŒJ&´‰Hmé1é½Ìá<“æð–ìtõn£'IÏ‘*(¸žŽU|:>—Ç⎛i­ .˜«W†‡®ÄL‚7ëIí;3kîΞûíuÇ<˜œü<;é<.P¢3ÌŸL›É2wJ&f#Ÿ±æÎ{òWÍøñæÌ÷VÍÎ`ÿB$gž×ïÂÆySyóG36(˜dU)n¤ù<¶%±ê8ŒÕÔÄ“„ãl‚¾ô)(¸…©çX‹©k> „Tc…kîÃ:{ÕlK¬—5mX_̳ÕÉÍ5ßc\Ë4£ Dà:ž”Æ+¼P©­ZDD•fpj¹a:‰Bkô_^žg“Ï ÏS¨±6», }JnaÍ^üúÚT%-ùÄt8ÁÏf4 "®³ÚÊ+…h§«‘ëŸ2f{B‰À$;`I}è½üFÎ@ˆZp¶_F_©kw…Ç|ôgL쀰Šî`*NTˆ•%0ˆ2Ïè¹@†jûæÚYÏ9ÑnšBê2wo¹*­ A‰À$+•Ès͸”ô~Ê—‡‡Eë´¬=&E’ø)=ÏɺœL˜I÷¾D˜‚!Åê¯P"0É%"µóƒÃ?²Íme¢ÍIk(ÈÃ{ŸjÒœçB¹2j2€Àñ®½¤V0=_Ï,\ôÞy(˜dMdÎù×õmf™¼pÙÏ™cGUÒâåùn^]O&ô„½¦‡ª½­S}êYñË%“,P¢××3óÍSÛØ‘ßV|'gÌœ<ÂmŒ•Å´ø¸UÒ´Œš–TàÍ5M6Ï7Ý%Ñ79¾óP"0ɬUƒ¨ŠN=%^'C!û%›Ëš]è©Ë% ÖSköcDIüåkËäx^zHºG],¼óæR %“Ì*‘0ˆ[&£D5DþãÆKfžÉãÍáŒu#d¢¾æBfºæ×nŠši¢zÂêµï)‘÷=%“Le6Šr,"õ£_ÕDÛ_` ÕñôVÑ2!¬¤ØÀѦ­Œ @<³G=Îæ LŽQ¤¢Må£ÓÛ>œîg6Ö·úÃÝ;½Åw{³ºvù©àË<èZ´à•7§tÓÐx9AŸz0ð¼D¿¢"…¦\€PO¯_òŸ/^ —;Všò~¦€$ƒÞ™7ºÄ(ãÖñ³I÷-Öq*ã‰òå…§Z"Z¼NEkÞH´QfVijhPKÜ1þ}%«Q"ÓIÙŽ¬empÀìâuͱ陜Aûb¦¡!ü8Ï8Ò-ë^’Š)ª“å'R(©qIÙGÿþm6@ÀˆÕÏ7Ÿ]cê“”­ò¹…1ïZr`…À>zYÁ ÓÑ–Ž)*‹éyi9 Úì¢iéoþû¬›LÒýkÔ¥(ÿ¼j~-IZbŽÅ^Œ°ƒ*Úl¡P€L«Ç4¦ziÖ2•.£}.@f°‰À$Ý6QU¢­Ÿ§D¿l³ˆ›õ&3W™=ŒõÄ4mO•âºÁ°›Zc6%Z0ké[ªo/”L2¢DåÅ©vP%0ˆxÌb²O^* DÊ«†Rsb›¶RÒÆB)šõzŒÑWa¶°Yqkúþ/@‰À$}Jôê·AôYn Ŭ¥ÈÃl-?Úf]Ì´¶(gʙԦ„îó·P"0Ɉ-4Ff³ÁÅ_…0yâ¥]9J¬î{g×7;æP›7J–°Ò&š ™4h~E{Ä*š˜ &ƒ2qï]é*™FšN¨†öî0¼30Owœ(6ò'Ũ6"^x8æä¤„£ç¶ýûˆMAA&­¶¶„—×ìQ,¯¤iúeå?ŽÝ`’ñÌÆ^³()R± É\Æf)/L¿,#4¤&¶¶ª‚f…Z5õNHYª'ð¬?:ê£y¥Á¼%“ ®m߈Sõ3Ý+ü öõ…W¦Ðt „@˜š’±’~¶/´©Õ¤Y][4+„/0p<Õ–”h¤ùo…I¦öñÏ%Ÿ-üu^’D@TW šÊ¨ƒiĘrVàXü5ëꮵDF“wE^ïä83ìÇ,ÖúŸ‚I¦~škGÞÄ œ*%eH‹ 93Y$6Ûz¤MÓ àÈ‘ ¯MRÉû2M•ݲž ÂP Ìœax;µ/D¬Á$ ”ˆØ&óãÞ´í5bFiÚ¾ ïËÔ}Ê3Lx³¦}iùÐuuwfaÓ 2»&‹3 ¢Úµþ×@‰À$SÏl4¿–M=Ú§Ææ¦–Y@ Ôš{ÂB1M*òÍ«fËÁñ¼0½¾cKÍëºÞäzÇÖêÿ`ËJ&™R¢úõØœ9ž 6‹rÊ´bÌŽb]og´&ßZ¦—f•L/õµ–Ýåpãq"0ÉšçX{ãó«²6µç¶ìsõ!ó&UÏÖë’§/Yg ÊnȨSaç©ÿS(˜dê9ÖÔ vˆ2Ueއ®Š³£àºeOÖN9!£I‡kRPò>à’ÖÖ‚'¥IÖülF†Ä‘ª;¦•Ä­¡îæÙ1)¯b^P¸°R˜â¬eדÂüP%“,P¢<»Z&oF^ë‘À5ËOþ%±³JÆÿŠ‹‰2ùQíÖbl"ð^\§D{bùL„¨g:j*NSMª"èÖš‚2)ÚnJ^”>rª6A€À*Æw{dLó”vdž§ôØ”ãžcœAÂÌı€È}Ø@Ê»Îê.èøM·&ÀÚ˜$R"|ã®J¸(à~ D€ûîJ¸(à~ D€ûîJ¸(à~ D€ûîJ¸(à~ D€ûîJ¸(à~ D€ûy´}|ßåÙíbð«†ýÙìíw@ÿ_†T/$E“×¾ä㤇=6ªR+’÷Šï¿Ù&=~â<]‰~û<ôÈW]Ëp; oæ’«»L€–·ãµ6pEA• ý¸k¯Í‡Ï&(Ñ)ü6%hJWéR¢L›ŸMïªDæ—@µxëÛŠ(\Oyfmó8o'?-½—ךîÚ,Ù¼p~½½w)yuâ?¢Û4‡Ñ¬hVY8ì䀉ähõ§ÎlA÷›±_N©Ûsxº Ì¡˜TæÿÃ,Cþÿ/sÜëK Þûò#fkf×^É̅ݥ̗0»ÅÉ\oü¢wØ‚}sTÍÛåé)’8Û{ÿ½6¡DƒŒÙDfÝaÅ!õ¯mö¥‡J mŠãª Pæ”&ß” ž Wìú'f´kÀ^_]w¸y6^ 5”“(Ñ +‘`æC øg(QfŠö_b (QrÀùQ-W¢±-<(Qãÿ·êC¯Ë{-@‰š®Dõuþ?ØÕÀÀ2m>‡·W¢'4Û>Íi¿üC?¯DA­·S"ó¿öp%÷J´–§+‘FšƒŽYëß¹µ³XG¼Ádz"P%ÑBR³¼ ÑÓ#¸KÞÕ5§´yÇøqï¿TÔ÷|Õ°3¦\Ð*£2ÞU˜—ãZ†½ùgkJ¯;àÍ%³_Þ¦v@‚Âúx`ú™âÕôÉqµ¼{’¼¢¤™™©€îJ¸(à~ D€ûîJ¸(Ñ22)¿ó]ܲ`œYáÎ4âUp%ZÆ’éÚÛÅ5,¿´ç\xP¢eÌïHëâ Dàl DËh*‘ÎÐw–‰ÂÍÖjXœÏ·ÖÇÍj³Á¼`Å9ÙÞÈ3ÃËdºw8? s J´Œ®MdÞ²xGUfó9{ͼãÃÛÊtƒ3J”¹¢æðò;ѺvŸé^¼Á0P¢e (©I•,<0‘–÷ŽÄ—£iÚD”{ZÈð°ƒ’ùaÄ׺€-£©D‚x¦Å…*NsTæ¥-W¢µJÝì¥÷¡Dg%ZF—M¤Ëd>ßgÛ>Þµä…üœfûÉžg #hô%ZF<»º¦îŒwF÷ʼn¼ËÑ,T¢«âDP¢S-Ã3øÍñ<ô {á ­ÉãÁ¨xaoJ› š—#ðìG>’X ½á7Y4Ò¼ðä0 DK€ý(’NÇ]ÃøÝ3€ý(ž D×ë”è%úQÜ«DfDéÔ¾ ¡”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷%Ü”p?P"Àý@‰÷)\ ”p?%úäîñ~)E‰þMê]ž endstream endobj 3212 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [92.321 45.362 99.295 54.209] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3216 0 obj << /D [3214 0 R /XYZ 89 721 null] >> endobj 3217 0 obj << /D [3214 0 R /XYZ 90 696.022 null] >> endobj 918 0 obj << /D [3214 0 R /XYZ 90 347.061 null] >> endobj 922 0 obj << /D [3214 0 R /XYZ 90 212.368 null] >> endobj 3213 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im23 3211 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3226 0 obj << /Length 851 /Filter /FlateDecode >> stream xÚÍUKoÛ8¾ûWð(+†¤HšÊ-Û¤Y/Š>Rµ=$E¡ØŒ,T]IÉnþ}‡"éHnÜ}` ÃàâÌ7o†•ˆ Ëůùâäå’£ g’I”ß¡Œ %Q˜pò ºŽ^üvö6¿¸Š&H$qœI¢OW«|õúÒž¹%³4:{}ùÆmÏ/>®^\8ù=è+}„åsþûÉKÁ&€Ü¢ îŒx”S{iA¼‡à™ÜNÂõ„-á0uJ L1‹Jx²ÕwmÚÞÔ~óGÕnLLAxÆ ‚ª°TÎ\¾­ú© 4îkc¾úOuõÕZóÖOgN‡õ"_P¢ˆ’“¥@<“˜)ŠÖÍâÛ¥/`°ÿÅ:£»/ð·ýÒCÂnˆ ð§Ï4¢âXÒ4<¶Æ•FæÎ­np€°/Íé釡²Lñh]1ú2Ämå•ìüùÄ,Dj›û~pÒ­7¹1­—v]e:hfÀ€áæ¥ó B@‰÷Ú…î¹û|Ž(L)µÏ§¦ý$'‚aEé<'6>)ÇøRr¬ ’bÅÕØ?¯…:¬„™kk'øì¦À¸?ñãüÒÓKcw…_=;­.ƒ fºälÎϾñë$ºÒwav ¾#¯}?ÙyØ•~0^ÙΊÔA«EŸÊé^0xõ°Zýº«vO=o|±ÂÄ %82ò¿8S¿ endstream endobj 3225 0 obj << /Type /Page /Contents 3226 0 R /Resources 3224 0 R /MediaBox [0 0 612 792] /Parent 3206 0 R /Annots [ 3223 0 R ] >> endobj 3221 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./48_home_taurel_tango_manual_ds_writing_nt_server_cons.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3228 0 R /BBox [0 0 578 212] /Resources << /ProcSet [ /PDF /ImageC ] /ExtGState << /R7 3229 0 R >>/XObject << /R8 3230 0 R >>>> /Length 65 /Filter /FlateDecode >> stream xœ+T0Ð3T0A(œË¥d®^ÌU¨`jn6‹Zê™YYºz@`lhj Qm¡à’Ï„ld¼ endstream endobj 3228 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152429+01'00') /ModDate (D:20160114152429+01'00') /Title (/mntdirect/_segfs/tango/doc/manual/programmer/nt_server/cnos.ps) /Creator (XV Version 3.10a Rev: 12/29/94 \(PNG patch 1.2\) - by John Bradley) >> endobj 3229 0 obj << /Type /ExtGState /OPM 1 >> endobj 3230 0 obj << /Subtype /Image /ColorSpace /DeviceRGB /Width 578 /Height 212 /BitsPerComponent 8 /Filter /FlateDecode /DecodeParms << /Predictor 15 /Columns 578 /Colors 3 >> /Length 6186 >> stream xœím’¤¶E镹wöÜ;¯¬_;j¢Ì Tê¦>‚s~8Ü RWè’@i>~ýúµ,Åççç÷÷÷Ïÿ|üØØ_ý5[€Ê×××ßÿý‡ýóÏ?³UHü86«’µ±ÏÏ_“¥äùõësÃÆ`Q°1Xl f²}ÿïß*?¾.íðMÇÈzí'W °ؘí|SÁÆŠ`cP'û 6P$`c¹'l‡íÛŸ3¯ó\.¦Å*œC^{s‘uK(–o”ª·Z‰ ðXTsž°½§×ýŸéÿ·ü¹¯"?WÆ ^Ä/ßEj±‹ôžx,ÝlLÙu ˜™qÚ=À¬+ôü°¢Þ\@l  …i6VL˜Æ¥2 ÝmlûÓ8õôäíÁÆnkc[Æ6DüO<íó'xÓÞu·±ƒŒ­ÍÆBâë¤òn  9_*úiJM|R—«½zºwÞŸù½¡?TCùbK‡ßuóÔ²€{sgÃÃnÏMúž n +ÜÀÂl àúdmìçfk€J¢>??>>¶¿hÿEË "†ÝÀWù×!ÛÕ¨ à" ´±÷ü»-kcbœPu-…±1€÷ÌÆzq5Ç¥º@Ç´±÷‰{Ú˜ÿÜÌÌḛ̂ïb—¤X¸KÕí=4Ö¬ÝOˆÏy\ 0”ÔÆ~<ìõ?'ecéÔ¼eì*÷ÿi(çY\Ý®èŸí ,Örå«ìÍé¸2{{Ø‹½“ ±±öÉ·Âð~¶4ÆWÒÞ@½}÷,ÄÞÆöâíd÷±±ºÚý”˜ÂäO<ć]úÚ˜?-¯Ø@Kõ6F#ccp°1å½Zhº¯ÖvØ•«qD•cõÈØ܆'Ú˜ón¬Z960…ù¿ó?™+º…ùÊJŸý»”ô›ÙÒÀj«•Ópe~Ü'ý‰XŽù¿KC)6v’‹pØÛåÝXc[lÌ\T°¹OrgoJd}¤Rý}95Û"³pµá}äÿ9±ÜôÍ'D¡ö*tô­ö½Ø\„iÙØ s4ÚØáÁÝ“mÌo6§1?Kékc¹ø9Uæç™[ÔH=9а1x Ó¾T,Nv/ÃÌË]ÐqН“*¢÷XQXK‹z°18™_*²1ÿµ_‘¹Ëu26Wà¤lLyú”›LÍŠUˆÆy޵è{¬QvôXl ¦3<Û£¼Á2}nsmì$¡¨Ay7ö¢dŠE©º½Eú^³½f‡çŽÅÆà ŒÊÆ`!0X”Ù,6ëB6ج Ùü 6ëB6«B6kC6«B6k3vñ;‚–nê¶zù+}™®÷R[Ū1×ÊÑÛ·ÿðdtÇ J÷°ûà‘Ï?mꮾ+½&§®©sÖш®§¥È˜>^çļËÙØ‚hcÎ2Fá¤5£\v ËyIè.UO¿Ä*Ú/¤ Ž×eÏ^,á CžÓmì´J¯É´lÌYÄÏYŒ1´$ ³š­),w¬SÌÙZ]÷ÐX³vGŸtÈ4”ßENs*Æ+Å,Yl©¸X¥²ŽeQpõr”fíþ¸û§¢¿P§¿¥!ݦ‘Æš5Šˆ£Ðߕә*Ùc^þ-]T<ÖÙòædc¡I?Ý¢œ%fÒ­{LN|ñlÙ˜ÙØèUZ¬®½‹Äøb{äJúÄþÔß–€buÊŸûhņG½ˆœ.ê0½îô“a¿±®êNQ³[z<Õ=`6áÆ ÏÆTO‹ÆS= š[ÌvfcѹCÆuQ…B§dûÌR¬·EFK¿9•ÇH¬½ãE¤®رcCw?Ñ«¾£oµïÅÆLffc}mÌÔî6ömý[-].ŠΩ;¤ou´1×áö¨8c*³sTF´ßÄÈâÜÔh“u¡Fœbcbí¡’§Ù˜/õ±66ÿÝXnKîFõÀlL9e¯ic)-6v°¿ÆTª£!$c«êG6æžÒׯrñC%±±é¬šùѶ~'“S—3±v·1“‹Û˜rE…ºZ¿w®Û5ÂÆœÚ±±.‡‡\Ä©]×éhì"E|tûíY,{ õšå²±ë@õ‰»Diáa#lì£íÝØímÌV]§S`¨½Äcc)kdc~Æ9Ú,œŸ¨»QNÏulL ˜vQ¿!]n ÚeDÖݯ8Úôžï¨ÍdhÀâI•«Ý‘RØåþ£¢‹¢ÇbcÎþRq‹ÜÃæNëC(óØ-rn¥Õ…Nhñ2Sô(%%f·8-r.³R? >^¹¶˜‡;ÑÌI0­«Q†¿KôïbXå¬ËSd›zü†ädT÷ŒsšæT-^Ú¾x_­¨¤¸×”ª\tÛŸ§:6¶gT6¶4O>!à˜gº00[N/ óL/ÈÆjžé4ÂTÓ²±ßèȺ€õ‚l V…l Ö†l V…l ÖfÎ*#T£þd=Hhù±êºEª»kDoßþ÷èÞ¾R¦­©8‚ûÙXñ·ýØØZ`c#¸O66ˆœ—8“ ýiZwó#„ÀÆ*Àƺ33Ó:ÛÜâ°.Y¯ÍbÎvßWR=û¦éí2;'å;ùWÐÒP~9ÍÉÎæŽéŠEM=Ñ]Š WñÔ2k÷Ç]YWÐ_$°bP”k` ædcÎÓ­âªÛX® S@N­3áF«=T[ÛRô ¿‹Äøb{äJúÄþ ½w¬(V§ü¹Vlx´±JCrý°s²±è±Šé&:É*ÙXZï~c_‹ÈRÝ QIz—š%[̯¿­(£¥ßœJ‹c$Ö^7($ap&dcâ”ç<œ9߯¾“G@fþw5sr¸ëؘ¿Ë9 œø¹*êdDûMŒ\#¥öP|=À*ÌÌÆR”ç6O°1ev»¦¥´Ø˜s¤5¦R ![UÏ8°1€¾\"ó÷æ.NÑÒ¢{=º¿ú{ë,Á9¤³{)Õ™„ºZOïêv°1§vl  ;Wy7æï}”õšå²±ë¥Tõ‰»Diáa#lì£íÝ67`þ—Š[|š0ﲫgaçžÝãÆzºåZWÑ S6À“nc{œì$WF™ÚAr*4˜sʾ˜9ËäûñýF‹}wúÝØ–š=÷…ÅùuëŠLzĹ‡È…ÒmÌ‘H62ÐÆàd˜ãrðtàÆ`c÷aôÔœ¦×o®ï¡u°ØØ}`vvÀÆî 6v˜}œ—j°.Ø, 6 ƒÀÂ`c°0g/ <”A5Š¿ã®ŽÜQ°þûß§ÑÒ]zïÊCZ"«1øÆ·6Ðl,¶c-Cç >1߃9œicœ–Ð[ÙØ –XÂ_é‚‚Ofº]l –f¦é‹ãmîyoNÖ¡ý‰^´1³9Qwû$×±"ÿ1éÐÅ!•u»,ٸ戾8äùcmFÞþì1¦y&´ôÿaoîªL[a¶@aš9'·2Á™¡Ò˜¹*L9µÊÚ¯¹æT¸K±O*æýðvIÕ=ãÏË!ÁûÃÅ.ò»«®Ei£ÚÇú9§³åüié¿÷°1Á‹žÍ}gɨ€¢u13HhÞmÌßí½gzŸ‹èyXKíCÇ:·½Ý·”ûÈ¡{긴í﬷3…¸·¨¶¥®Ð½¼Ø]u6æt¯Í٥׫$O}'Ê\Ì:ÍÓÇ:·ƒÇ2ÓÆRÒÙ­8\ÇÆrÍé5µåâûÇšœîM«K{ÉÜåÔë(7Å_߯r-:a¬s:‹U;1±1Xš«dcþÞÜeV}ÚhcÕÉPH°¢Í/cÖ½ßî )¿A6–;|ÜX›%ëªSB£ac0l¬Fí96ö‘_¢ˆÌÕÛž‰Š­.–Ñ“•ÛÛXh¬MØ<–K|©¸ÅÏu3I çÔ*¦%NQIÊ$šh*v‰Ê‡¾ªìtŽn\a¬£Gµüï÷6#nc)‡‹!Ýnî2/$ó¨:/,¦9©Žfs¯(ɉP¡!×{ïbæÔ“ìÇ÷U,öÝéwc[‚³â[äW4h¬+̵¨9tí˜òrѰ1Kÿ†Ëé:0wƒ`c¿árº£Ç"÷œ`h¥ðÂOÎ*x¨‰¯` ÇÁÆ ;µ±M{ýS`v»7þ{5€(ϵ1¸Ø, 6 ƒÀœúóç^¯s» þjø´ô@—Þë8g~Y0èÌá„H9o1ªîóÑ Säƒà=·±±“‡8S×T¼àEhJrÖý{Óm¬÷¸;YW9À8æÛ˜ù¨'ê.âòt¹ÅßÄŠüǤC—",®•×k)ÂÆ.ô¥ÏëЕ3Êf+s­+¶h+u)œ½Â½ø¯Â]Ì—%Õo—TÝ39÷ª¼?\ì"¿»êZ”6ªq¬õ¡W:ÍlW®±Å« zŽ™²žÌLëb fÑ·B6æï-Þ݇¦½gªûÓÜ›êÔÅ·×>n¬+î`œ8f¨öÖõ• ðnhcŽ€.6vxèT¼S®¸‰•Âv4GIæ¹c]ˆ¿QÇÜFl `(óm,¥ïÔ–‹ïk8’c-›5û˜»œz妸ëÛX®E£Ç:äÎ(²±.²ËÌO0;;`cw»ÌÎ>ÎK5Xl €…ÁÆ`a°1X˜³—Ê ÅßqWGî(XÿýïÓhé.½wå!-‘Õ|ã[è 6Û±–¡óŸ˜ïÁÆδ1NKèέllK¬á/‰tAÁ'3ÝÆ® 6Kóã>/gRèlcúâx›{Þ›“uhA¢mÌlNÔ]Ä>ɵE¬ÈL:tqHeÃ.‹C6®9¢/yþX›‘·?û_Œiž -ýØ›»*ÓV˜mPp.v“n6æœÜÊg†Jcæª0äÔ*k¿æšSá.Å>©˜ ôÃÛ%U÷Œ?/‡ï»È﮺¥jëCäœÎ–ó§¥ÿýÞÃÆ`ÊãÄ7ŸŸŸ}l,z6÷%£Š6ÖÅÌ ¡yG´1o´|ôžé5v~.¢ça-µëÜövßRî#‡î¨ãõnL)ùõõÕí¡¢x6ï﬷3…¸·¨¶¥®Ð½¼Ø]u6æt¯Í٥׫$O}'Ê\Ì:ÍÓÇ:·ƒÇ2çÃú&ÝŠSÀul,ל^S[.¾¬YÀéÞ´º´—Ì]N½ŽrSüõm,×¢Æ:§³Xµƒ¥™ic¹sW¿y¬¾m´±êd($XÑæ—1ëÞïGw…”ß Ë>n¬Í’uÕ)¡ŠÑ°1˜ 6V£öûÈ¿/QDæêmÏDÅVËèÉÊím,4Ö¦Nl Ë´ßU;Ð~‹S,ä=~n¡˜–8D%)“T4Zh¢©Ø%*wdúªZ°Ó9>þ¹q…±ŽÕògH¼ß{ØŒ`ocŸŸŸi÷¯Ê*m,åp1¤ÛÍ]æ…dUç…Å´#'ÕÑlî%9*4äzï]Ìœzr‚ýø~£ŠÅ¾;ýnlKðoVœÂb‹üŠu…¹5‡®S^.6#8dc'Ûÿ2úæKs9]Æâ®`c0‚ô¡âÛÉ«{`cp£Ç"÷œ`h¥ðÂOÎ*0ß½æ¼çV6&¾~€)07ƒî<÷ßS^?À˜Ýîÿ^ Êsm n6 ƒÀ ü÷ÆFã|{lR°1€ëƒÀÂmL. pþ³±ÙJjømcü€ÖåÿB·Ü endstream endobj 3222 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./49_home_taurel_tango_manual_ds_writing_nt_server_help.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3231 0 R /BBox [0 0 387 258] /Resources << /ProcSet [ /PDF /ImageC ] /ExtGState << /R7 3232 0 R >>/XObject << /R8 3233 0 R >>>> /Length 60 /Filter /FlateDecode >> stream xœ+T0Ð3T0A(œË¥d®^ÌU¨`la–R025·Ô37+3K3CˆJ —|®@ 0Qÿ endstream endobj 3231 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152430+01'00') /ModDate (D:20160114152430+01'00') /Title (/mntdirect/_segfs/tango/doc/manual/programmer/nt_server/help.ps) /Creator (XV Version 3.10a Rev: 12/29/94 \(PNG patch 1.2\) - by John Bradley) >> endobj 3232 0 obj << /Type /ExtGState /OPM 1 >> endobj 3233 0 obj << /Subtype /Image /ColorSpace /DeviceRGB /Width 387 /Height 258 /BitsPerComponent 8 /Filter /FlateDecode /DecodeParms << /Predictor 15 /Columns 387 /Colors 3 >> /Length 3350 >> stream xœíÝkv£Æ€QzdÑÐÒ3댬¯×u¢¥†ªÃ=N•´÷,5‚¢„Äd[ö_¿~-¥~|•诿þªžð¹~þüùo‰þùçŸêÉê«BJS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨÷Ä}ùØW¤Þ†õ”¨§D@=%ê=¹D?~ï/Ñî”ò%jÕ\çvðüŽÎœ×¯DÍ%-ŸS¢Þ’ÚõÎÛÕ4Nì4°;ø˜ä7äņ,QoáŸ>¡DñiÓ»€êu»÷Æ™¸ì}¨7·d:{ÓÈ•Ùʼn¶òJ4–;KÔáz»yÚßÞÛ›Rsó`Û¸SÛ­v§q9ø½³`2ù y%%ê)Po†u¾Í¯Dð6&)Ñê;kJïeÂýG‰àm(Po’­xwïeÈÅß8óu"x;ã•h÷û÷Jog˜m—ßnå{gðÖÆ+ÑöjÈ׉àݽ¶D¥Dð6”¨§D@=%ê=±DIJÔS" žõ”¨§D@=%ê)Ñë\ì4?”?‰Óô#ã𾞽NæOqq'%š”½Næ%r'%š”½NòÏ=ûÕùÉÍ?¯¼Úª·p5ÎöÞà£^þüKÖ«ÉÇ®vÑ<ñ~3óÜ~èálÿÔ­kØWR¢×‰Kԣ⡖ÿNÑÌdzvŽG{z½ÍwçÜî Ûs÷ñƇs”èuN”hÙ«FÿÙüŒèvÃ`J™å§?tüsŠŽ8%šFó\]Âßn±´>Ö¿„­¹Ýp»÷ë ½ “+ËwWä·U¢Ñ(Ñ|.¹ß^Ô»(8Ú‹`„Þ†ñåÉí°É=öÖÙjf4ž?#P¢Y5ß(}Ë—hwÃíî2&Gn޹»—˜MJ‰æ¼¿èWÍÓ>sB½&ºsJG‰õJ´´ŽãP¢9äK/?ô&«7ÓïÎ2ËwWd‚I‰¦qéÿdãeï;YÁ’̆ۅ»6WØ.¿mGòqSŠËÛ{hŒ@‰ø J4,%âSÈÐÈ”ˆ÷|›A(PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" Þ%º\.Û…_s~õü#ºó±?äå´ö¹Y}oO©÷ŠsÌeàgŽ {øbÛ™?걜çó!îezø8½ÑN<¢`“`üx×½1‡=›”è‰>­D'ÆW¢x“C%ÊŒ9ìÙ4w‰šÿ¸^ñ^ÿy]µòõ®ÞeíîòÛqò§eïåÕm»ëæš»üöñ=JÉG·zF¶c6§±»as“N;9áåÏ㿽Ña»ßæK·9¥Cw«Ûæ(ÑjIó)\TÍ磹ÎÒþ2Ë{ûZM¾÷*¼]Ò­¹ëÞš™~î(õæÜ[’9’ùÇß8:íåO'žúÝYí®íqØNiuïÑãß³ùB-÷kŠõ\ó¥ô|È,_6Oíî¾¶S] >ðŸ¨Æî)½ô/%–#'|¼á¡'q·Á#ÊÿÌÝi$Ó°} m×ÉŒ©D'½¸D«]Üó¢&ü%Êœ¢G—çWxl‰’ÎÏêá%:7±`„¡(Q´¼7‡Ó/úíú½”hw…ÁKt½wgubb™1Gðë=Jté|i xy-ú:Ñ¡}ü2ÝíK¼Õ¡¸Z9ùèv§½syÎ׉ŽN;9Ú²9þ™¨`JñüÿxÌüš¢DÛ…ÛWsðÒinõë¾ïÅéM>>+‚*­FØ-Qü@¶§Gp”zn÷”n±Ûå½g-Øp{Ì5íÌ„—Ü­2•é=ŠæÃé-FV¢9 òd 2 žg´" û’S¢žO?ÅJtK‰jö¾ ü î—|Š_ü:6CËÇ–Šõ”¨§D@=%ê)PO‰¦Ôü©\š†ý¾5·”hJ_%úýûwõ,F÷ãÇE‰&¡DSú.‘§,ðõªþûï¿%š„MI‰v)Ñ\”hJ«Ý~üÚ¿ÿ«DsQ¢)Ý–häR¢¹(Ñ”¼; ¸&š‘MÉ5Ñ.%š‹Mi„k¢Kø;!{ÿ|×D3R¢)•_¹éÝ~1%š‹M©öš¨Ù—ëÂísM4#%šRí5Q¦Då_½R¢¹(Ñ”¿&ZJÏ×D3R¢)¹&Ú¥DsQ¢) ~MäëD¥DSÿš(Xó5”h.J4¥òŸ'J~ûÏ—ÍM‰æ¢DS*ÿy¢%ý“Í%/ DsQ¢)•_Ì5ÑŒ”hJ#\ N‰æ¢DSrMpM4#%š’k¢]J4%š’k¢€k¢)Ñ”¶×Dþ{ûßÅ5Ñl”hJ®‰v)Ñ\”hJß%úùógõD†¦DQ¢)]ü Ø4%š‚MI‰ò”h JÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@=%ê)PO‰€zJÔS" žõ”¨§D@½Kô¥z&ÀGûQ=€åóû% endstream endobj 3223 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [187.554 83.923 194.527 92.77] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3227 0 obj << /D [3225 0 R /XYZ 89 721 null] >> endobj 926 0 obj << /D [3225 0 R /XYZ 90 690.045 null] >> endobj 930 0 obj << /D [3225 0 R /XYZ 90 449.132 null] >> endobj 3224 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im24 3221 0 R /Im25 3222 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3236 0 obj << /Length 1869 /Filter /FlateDecode >> stream xÚ•Wmoã6þž_!lVnc…%ËJq'Ùæ—íÆÝ=`w(³'‰®^ÖI‹ûï7Ã!mÙ‘釄£áp83|ø ÍœG‡9oN§Gqè$^2 FÎtî$Ì‰ÙØcaäL3ç“;ùõäÝôüý`DÌyƒa4bîÇ÷—ÓË›·¤<¡a:H¸{róö–>ÏÎ?\NÎI¾ƒõcæ~€áËôßGQÐÙ0ÄÝ¢„£÷ó؉ÂcŽï{I«À|hí‡A >8­y‘ †>c̽¾˜Ð¶™ø‘ûUÎ}×¢øÌýŠÿ@| s†þØÉçt!*XÉ#îÊšÆR™U¼³*bOÖñ©,{\Ü ÃÐÍÛrÖHU’וlÒÈ) ³<­k9Ksü )%Ô/+õX¥ÃÈOÜkU7¤Ws›… ,Ä!ˆqâ>«¶2ΗËœnv¶yUb9Ä a̽qeЧ`+Q‹²˜rî><Ó¨JA‚,ë&-gæKÂ)&?ýD‚NˆÄÕBÎv-ÔX6fb^©‚$JJ}„ ìO–ËŽC„c”ÀIÉú¥æÃ¶S1Q1w©B@Å ˆ€ ޳…h*3Í"mH ¥$U‘>“FiˆÑâ\¥MËï–$RõÑt«ú8eSàp7.Ð…ªh"¥EFø…oÀ¯ÙÉÄ¥H_µÖ!8˜;ìK½³&Œ"aV:ÎFnÑjô2Ô6+¼0ÊÛÂhû¹±ÐÇÂö)¦ÆxJ¤/i%6n^^/ù牽:—¥l. ä>³ˆÁŸßsß¢Ø âÈ.Jˬdz¦’‘¿÷ó§×m0ö’`¼¾õ”&Ôjº0ŒSµ¹‘°T86T7ƒiFõ@œ¥Z£˜«dEb™vÕáOvsã^²¾É#Šò½(Dñ€ðáo`’œ[ ¸<€¢=*úì)~ï)èhi¹ØÒM[Û$ÐG5Oír}Yaƒ ÁÈ£0C HÐ@‚”Ëò¿$ƒŠXʽ$Ü9·-¶OF/‚D2-J1¥ŠªNªdQf —¬jR€“Ø×n»ûc—üÇîgÆ‚\ôQ½ª,2ü¡¥(thÇL3(zBJEMšetÆÉ¨°ƒ/F2†8lŽ&Z¡¨6fû­Ú4ï*õiË¢i`Ãúè Ê|tY.ÛæèöçÉ —UZ=¸ª ÐlPIeBTø–4~Âïƒ#Q=Ú:íÚóMÃ^_—îÝîÞ‘×´j´€3-q"GÐ<˜o(.¶0TQ_G‰n·õ \ñg+©À¿4‡¾Gzº¾C»Qà® 5¢¤yªC |«÷ð‹¼ñØï¾¾A7Aâ± ŸÙ÷ƒæ›Ø=SåMì\i >ІÁy¨9`Š* uY³JO”¡ïÅcn÷mˆÞ¢'>x£(¶vk\v ±Æ`.ëf›e9Ë[s<Ì,&V[?íx>=øó‹B|«†ÉØ‹YäÌŠƒO_˜“ZŸ'±³ÒV…ÃÁ$bø@Ë»ƒß^¸Ôo`Ÿu³ñÃ\DNà9š—)<º­§··W$]ä­ÌjèuÇÇûºÒnhåß}sÒaòdþt^¦¹˜¨²©TŽ€CTÖñÏ}«Ã>eDÛÑxñei•Ñ—„˜ešË¿èIÒ]núÅh{ùåœFýr@AwnJÕÐÖšÁP4ŹH›¶BîЫJÀJÖ c«h¬DÖÎÄz= µüKô%o¢óFh2áUf_Yb3BQ<‰YÛ`Uw’¨ªÍ3»¡¾Ú õkt+Ý‹uî g¼Î&þ¥˜É¹œõV¶U-±­Ï:²LíT·"óúöNè¢G^·g|fÂùNÎ3a*trñŸ³««>O¾oPHä™a½ºØ€b’æ¹-“4¬¢|ý”§ ØúŒLýwƒ28ô›„Èë^,ø|OØùFÎ:Ák«×¯ œÕNµö ž{ ×!—¼¯úL"ÍYõøø÷Fê>áø,ö¢ùÚ‹-ùü¨gè€;êæñgó"ò¹Å;O"dvhªþ c3ÿwoÕǽkxЌѧ)Ì¿hè$q|Œ Çš÷ ËŠ‡Å}9)²»…Zíå°€õjýõŽÃ_ð7¨îíMÕŠýî‚^-é~Aõ“«)EÐË®=ÀÿõÎÚâÃO¾™á9Üä!Íî5j¶·GôŸŠ›ð¯E]§âT=™ÐÙ¯oÎÐéÍïWW‡o®Ëðí¦Ù¯ªTõæðÍDÅš~ÞâÍáõéýåäöænzûnúöÌ+<®Kuqruw¾·òœ}«2Ü﯌Йøz‘ÊÜrÂ÷b_¡xð­BqþªB}X(<] úûâe¢žy›§Ø?¯™Ý>|mÍL‘ù7ÑÄ÷ irûþôäøøüi&–›†òýÞ’ma«ïuõEb*» endstream endobj 3235 0 obj << /Type /Page /Contents 3236 0 R /Resources 3234 0 R /MediaBox [0 0 612 792] /Parent 3206 0 R >> endobj 3237 0 obj << /D [3235 0 R /XYZ 89 721 null] >> endobj 934 0 obj << /D [3235 0 R /XYZ 90 690.045 null] >> endobj 938 0 obj << /D [3235 0 R /XYZ 90 560.999 null] >> endobj 3234 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3240 0 obj << /Length 1633 /Filter /FlateDecode >> stream xÚ½XmoÛ6þž_!ä“4T*©w¥XÄqZ‰Ó%N3 +Õfla²äJtœ¬Øߎ´eGN[`؃§#y<Ÿ{x43¦3ÞœŒ^ŸE¾‘8Iè†ÆèÞH˜±Øa~`Œ&Æ'³÷þøÃ¨eÙnÀÌбì dæíÕ`4¾#å15#+ñÌãá»Kú<íôú$_Ãü˜™¡ù<úíõYà¶ôqµ wšõ¸ïá ¦<|}ÆY{¸í‰ãz‰a»(=šåÅ–íÇŒ™¢®Ó©8)ÿdÃßûÛá)´|xs~þê°ÿ8 ™•…e‡0¼wyur|øê°WÎçi1!ežâðÕÅÉÝ w9¼]~ÀéoÐ+ðÈæÜI/QËVB.«—;;>¿îïà3ˆˆþéìåZWÍ™ß-.Ò¬¸Õ~þJM!Vj3г½j¨,xÏ,Øo¥LÇ3tYNí·S!ï&õÝzïVY1)W*~|ÿ^üNm Ö¢g£«›~·Ð²¹«ã±>tÝöG_8ˆÌàˆÌ tÀõŒñüàÓgfL@&(‰ŒU3jnxIì á”׿·Ǚï$¾o>sB¦9‡3'°ò„Ú#Ëö83E&³4Ïj¡aHN‹iIŸõS-ÅÜ¡±£YV“z.䬜œæµœ!5FΔɴ²xlN—sQHÒ,k¡&gµc Pü@€:]áÜìÂå[»èU"•Ý;çi½ö©_—¢–Y1ÝñqgÒ­å£o“Òrs¥&O«t1ËÆi®]—¢º·`õt¬¬H5ý‹hísï><71]Z؇ÆæµL+Iš¡+4^VÂèÀQ¢²‚ÀDžò#sXJeGÎR5oYL` ™Y‘o¾Ò#ððP‚ä$†•×ibÒŒ+ Y¥Õ}•÷ÔÞ ”g¡ƒ¢Ù¡Í u[û,¢J7ÑÖ`Âñ]ÃÕñBèÝÐö*áÍ ³À<ÍêEž>QwJÍœÈÆ})IÛ@ ÚqZ«.tÆÏËJ›ÈórœSâQUe¥º‚‹Ôr™ù`ñÀT¦ÖÀ‡îU&g-¸¦„çáP<õ€hJó¥BG-ä6lL¹NEeÕœh{d-ËÅ‚U9†x|/¸0ÒãpÉl¥Ï&¸m&hÝ·¯©ö² .´:€ N–ÕæÌEEñ«´⛿uìÑõX{)áýÐôB›.—·Ò „mD„¡BD¸FD¨nNTI%B2ÚžFLØB Ò!KÌó]x„-x„½©‘jB¢[åÿßM>›^dc½b꽂*¥æâ¬G^©(a>hÂT#› ›ÜšÍYg t/WAØ=†{äîÎ w_r–{Z_ÍÁÌAó¸Í’­£ß‡*lHïÚÊ‹1ßû^âa§6Rn¶ßK½Û¬Ø›ÝŠê!•ÿCjþ'ï¨ÈuW»p‡Ë?¢Ê ëv(…G–˜M¥ ]DMu]eDµªDÀŠÈ“笈½kVDcsp¯lÒ•Á-¢ª¡EŠRRñ#ªZ„H]„+¯yøû®KupôJ ûRKrV­ïÝæ½§J?ÜžþãÁù 4±ñí÷æáNŲeõ{ÕgVÀ rA0ÞzϽp嬃„ö÷ ê_ ªx endstream endobj 3239 0 obj << /Type /Page /Contents 3240 0 R /Resources 3238 0 R /MediaBox [0 0 612 792] /Parent 3206 0 R >> endobj 3241 0 obj << /D [3239 0 R /XYZ 89 721 null] >> endobj 942 0 obj << /D [3239 0 R /XYZ 90 406.384 null] >> endobj 3238 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3246 0 obj << /Length 2743 /Filter /FlateDecode >> stream xÚ¥ksÛ¸ñ»…æú¡Ô\„àAT¦ÓŸã¤î$—«­$í$77”HKìQ¤JR±}¿¾»X€‰R’öCL`ìbß‹Uød=á“×?-.ž¿ ýÉœÍL÷“9Ÿ„N}îeÅånG€U×5sœsææ'7ˆ"ÞS¹Ç0_žŠÈkþ0(;³ Äá¾N-Ìø@Šïëç}Ýàöuï6Ù*Îi9+@Û÷†Ú*}†°îBkEÙЙpC ¸@\O4ÙÅU rq˜›²»Ù±ìG-/—V¿eEÖ|æšÃ?1¦ Å”/5¡´†ëØAzLc;Aý(XóÀªLì(Éê]?¹CôÍÁ¬jªŽ¶ˆU4ÜÛâÜUVÐåÞž5îóowyJHèú”@,[$ÀÚEÑÙä9‰,áP"ÏÈôÈ@`¦UY{Å‹>Ö4,ŒùZ¿Cégqžýqþ`¼Ûå`7MVŒ®ò;t§™ ˜–V¿0d’)ˆ=œ£—ZáôhS¢ñ= ¯´œJà$Ë­ÃÅôùˆ’ ¨mÔ0b·ös0)\þ‚RËÇÛWW/„—dDž´± ²qÉ„GɯÞ/g«M¼#À:3J7e÷Ä(Õ †Cø>lâ†F™ûÚ£Eš&iBcÃ: 1Î×΃(}ˆ#ØÈ“ª,ÞA @6ºæI@Îï6»¬LŒâC¯l6†'yËç†0@rH42ìÁ7^¡IÔ´ËÜ€uSe«&¢Ù}™çtÁi =4T¥€Š,»o]nS­Ó"­LˆœÕ>Oë!ÍÅf&ûº½ä‡«$ »H_|]Ìa =²¨.‚#zdXl˜Í…„`¯!—´N-ö|šið†«*Mºâ‘s9Tÿ@uÑ8¬;â°ôK¹.­._á–Òn‰iÙä ‚¦‚¾}z[6°¬õ l”Ä¥NK–Dè}æ\’ðaj/í k¿&]#ßÑýÅHÔÓ,Ò‘ \抿݃•Õ“1ÍdÐc÷ 怼=õl-ä–Hº –Ç+“„7cøB&ýðkøÄ(¾ñ† ´ü^ŒS!„7zC?`~¤ÝvÌFÇEÀ¢0E —ÚÜú™â0 µµS«/9j§ïL,  ,ùHÀ‘˜T¶»=I)Àa‹"ƒ’…¼R¯Dc“·rFß!,ÒÖ—¡Ò¨Ê§«†&äížvöÈg)…>iá§+ýW‰Ý‰“¢±ñÌ¡pЧEr S& ™·ÉVY#Ï–PÌ™Bó²þ`÷e5ÈM dÐrÝÏ2fØñ“‡ òôÞN.!lv¹äŸ.9MUæõ"fíU{QEG•r‡™ïé BEGî¨u0rn˜PÄmܽ—ƘajnQ‚ʦp o™$ùàc=ð½Ë¼Æg7äE8 m+.» ÁIV¥$ÚNöæžñé?ã¹è[êÁaiÜÁíÙž]Mf¡ba Ÿ.ð š¡ûg¹sÿNç&@þÌEÔ;û3 FÍôºˆ—Î n§<ƒ7Žê)—°Õ\Ó@¨7i^§«ô‘ê‚Oªõ„·†0µˆ&˜<¸“çj'#W8®¡Ô^½»zO­^?áÅA¥1¥°k:‘3Íãã«ô=»“- ŸŽ{•Åc®(¨]ÊïéŸøcý§¡Þ=€ÁªÇoë˜sm\†:©·vÌäLðÜ Ñz4­@–§r”6Ü”î;‡ íj—î•I뽤¢Eó-«ƒƒÈe—^,Ƕã`s%AŽ71©xž‡gûjÛ¸nF]rP ¤eÿˆ²Ž”YëÁvûÊB¥h¿ ; àrsÜùö½MŒm¯/¦CÈŽC  Rf6â¬8cg|Þ¦þû}±¢lm°[´?ö¨r¿Ž*åAQå~ oÝ'îʬhL_Ðïž å_¤Ô‹‚iýŒní&(é¨í›Ð3‚²~0ѶÈÿ85ü·ç9õ5óƒcF»Gï®øUžìo@2äLøz(;jw†¾ëɇÊÛîÍc`K rÀ„m™ €_윎”g |™q;¦Ï9hh>Â&à7éH—UbÂMKZA~ØíÊÊ^±_g„CË6{»Î*ÞËÞï\pÛ(û½öa!BŸéà LgRÊVFJž¨'|Xjë‰ÆEÞÆ¥dÁ¼³æw•ÆXs.‚ÂVßjtASí)÷à½mqd<–l–ÔV`ø«³ŽÌ‚5? âæ¸²xl×W)×u€ÅöUÓCD“^/7b/ÁØËyfßo! •¾ßú¿@jÕ׌™SFò1[Ú‹rÙId'åݽÿéî_w‹ë·4-w®´·–°úG?ó}‘8DoZÄÏïŒÿ8sÈÜú¯Óƒ KHš6Gvå:€a}â¾×‹‹ÿØZ@àÿ˜k¦¥?Ym/>ýÊ' € ¡ð~0›¶àOU9Æ|rwñ#ŒÿYpYw endstream endobj 3245 0 obj << /Type /Page /Contents 3246 0 R /Resources 3244 0 R /MediaBox [0 0 612 792] /Parent 3260 0 R /Annots [ 3242 0 R 3243 0 R ] >> endobj 3242 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [312.523 368.71 341.913 379.614] /A << /S /GoTo /D (subsubsection.6.6.1.2) >> >> endobj 3243 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [420.363 245.173 449.753 256.077] /A << /S /GoTo /D (subsubsection.6.6.1.2) >> >> endobj 3247 0 obj << /D [3245 0 R /XYZ 89 721 null] >> endobj 946 0 obj << /D [3245 0 R /XYZ 90 603.579 null] >> endobj 3248 0 obj << /D [3245 0 R /XYZ 90 545.049 null] >> endobj 3249 0 obj << /D [3245 0 R /XYZ 90 513.288 null] >> endobj 3250 0 obj << /D [3245 0 R /XYZ 90 481.288 null] >> endobj 3251 0 obj << /D [3245 0 R /XYZ 90 461.363 null] >> endobj 3252 0 obj << /D [3245 0 R /XYZ 90 429.482 null] >> endobj 3253 0 obj << /D [3245 0 R /XYZ 90 385.647 null] >> endobj 3254 0 obj << /D [3245 0 R /XYZ 90 365.721 null] >> endobj 3255 0 obj << /D [3245 0 R /XYZ 90 341.811 null] >> endobj 3256 0 obj << /D [3245 0 R /XYZ 90 326.244 null] >> endobj 3257 0 obj << /D [3245 0 R /XYZ 90 297.975 null] >> endobj 3258 0 obj << /D [3245 0 R /XYZ 90 282.035 null] >> endobj 3259 0 obj << /D [3245 0 R /XYZ 90 262.11 null] >> endobj 950 0 obj << /D [3245 0 R /XYZ 90 219.644 null] >> endobj 3244 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3263 0 obj << /Length 961 /Filter /FlateDecode >> stream xÚVmoÚHþί°øPA ›õ¾Ø˜ÓU„ ÜF§4B.lÁ’±S{¨ªþ÷Ûëèš‹òíËÌ<3ó̬l¬ l +]·r1°™á Ç"–á~7lظ…0ㆻ2îj½«ÎÌíßÔ›„ãš…êMnáÚíÍÈM‡ùe'_ܺCkéð:?^ö¿Œzý|?û®}åÞýt1àäÀ!K½q ÂÉü™Œ§J¬"<]/&>4oRN±L£Il¸¤ ¥Þ4 Æ5?”õ¦›ÎlÔŸº7ÿæ§[?œx~øs|5šÎÝÎ4 5•lFa"½p)ià±išÈአ°´j§V³X<µ¤…åx6wMŠa<ô¶«±êMXa’%ÁÒtBПo¢nêL¸JûבÐÊ…–ò:™ó¨·Éú/Š­]/\Gíög陚‰mÄ ”‘ÍÑï3 GŽÝ2®¥B\Š84Ø‘ƒ–Ϋ£¼Êøgnšƒé˜X)i4¡êœ¥ë<Á¿óå vÛ}™Öý¥Ð‡¤jù0‰ö–*o‰ŒýPy”{©‡`Eh{y[µxß/?|÷ãD‰芯&eaUÇKðžÏ4ø‰XFáêu¬·8?þü¢Vös­š![x‹®¢ÝBŠ}V#™-%Ei$"~ñ~‰eO»J©–8ÚŽ`3È¢edü(JáˆöAò'\ü˜E÷'’¢†P-S­ÿ[+åJºôär“W uòÍ[-¼ ˆ–e_ bi_T!-ª4Iâ­E7Ú«ÐñÕíô2~Õ‰ØFðn3¿"Ž£¸Ú¨ö¢íÖ;l·jcÒ]Œz×ð鼞•Y6ò1_rtÆó~9kÎ9~(Öó£> —âiàùPÁ¾etQó]”¼Ž.2Ž’;|V"Y"ÿ¹#ÞL¥o¢žm+ZÒV½ë›n§Ýîï—âAÂkS´•²v¶Éèk›ìÄ]ÄÛûŒ÷Ùª }‡)"Öþ‡ý²Û@{½8Re›žÞÁ?q#f™æ[\¬iDeÔ2rŽZV4…{axRœx-M–X—~òÿÕ†ü,K–Ö¦˜8V"RÑ$õà Ó¬¨Ía÷C˜h7óbo«EâXMK¿µgß­ü¨˜°Å†™MÅQ3—ÛÊÝ=6Vp ˆÈvlc—)m ê´Çé$óÊ?ùp}4뚘!‡1ƒcÄŠQ)ÿò19_Òµ ¹˜Ðß±ð¤É(¦l¤æ²ì2ùˆƒ‡Q’ÈS‡ô4 endstream endobj 3262 0 obj << /Type /Page /Contents 3263 0 R /Resources 3261 0 R /MediaBox [0 0 612 792] /Parent 3260 0 R >> endobj 3264 0 obj << /D [3262 0 R /XYZ 89 721 null] >> endobj 3261 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3267 0 obj << /Length 2142 /Filter /FlateDecode >> stream xÚ­Xëܶÿ~ÅýmaÉ"õ¾\çâ^‘8­½8A¡“¸»ªµÒF»\‹þïá õZÝ9EúánÉ!9œ3#wsظ›7WÚ]½ü:ò7‰“„2Üìö›ÄÝDnì¸~°Ùå›Öë?¿úëîæÝÖ–k…ÎÖB×úðîvwûö _ÑÏn›xÖ«·o¾£éW7ßß¾¾¡ñ{8»Ö÷ðóÓî//¿ääBo BGß'ü7]¹,áÆöÏBnlÁ!¶}STŠ˜ Ï1 ¯·¶'à:ÕÑüœ6éIuªii¾¯tG>|hÒó±ÈÒ’¦E›÷[à‘f Ål!œ$–×JwvçmUtEZÿRÆ pZjšæj+ë¾Èx¹UÍýV–bõs¯Ú®¨ ó¢=—é#MêýÿO|9ÿ]_-/~Z⧇%pCÍÛ‡HTZJ»NªmÓ¹«¡EòPÒ²¤‰KŸŠ*o‰¦­¢$ í­¼oÈt@žZ¦3=`ëÌò°^Ç¥]QWZ7[øNâûs ÏÇ´eS¤UN…Œ~)8Ú>l}tÁ·iÁ¶Ü÷U†LÍuÆ4\úöÌ\²3ž`¾yŠ]Z“¨@šŒáçýÐ k ×…Ä2yŠœ¢fOQcu;_+2µbAÄÍØ cºƒ´@]=W.uÂP[5LÀªeŒ±‹3Œ]ü=¦[©%+åÜÔ`·jù'_ÔöÍ}¡=0Ùn•õùÞ †*ã]àç—¾zÜbßÕ'Èjzké¡íÒ¦S!Ñ$…F•Õ§sOñ +z[¦%s/˜AƬ>nš+Šý|áÄCSt†tT'"j·D”Á%˜\âȺíhµàÕsݶÅ]ù4Ã1üVÔû\Í5 #¸ð‡­€ÿZ-X«”Êdœ•¥B:>¼\[$N®]ùžvaúå cª~¢!u…ýâ:*ØÚÒ΂ã¡s£lT½SÑg…Θ‘?x\Ë ä·»÷£~¡gøü%$Îü¨ËÔsjé p…N"† CfåI׉B1Gª…Ílßu„L´a£ ¡òYâ/¹*º¨½Lá_–ô~‡ ;5©Må á§2Žn?iüà¢ç²˜°çeè˜&I£’#—†Êm :š@&ÿþÜ2ˆpúw½Ih Béë9D¸à«¡¡`­÷ò@Äf' Ý`Œcè+×E±ŽÏ¹`?ô—®·}ˆ>m/¼lU_6Èã ¦ÖïÍêʦŒ"ýÐÒi‰mX¸ ™ Fµ®ˆaêšæÐŸ”®7p?E™<-Rc$çXëÔ hJÖC!Zò¹ |xQ¢µ¼4žçB˜ûñ¯°žˆ.2<\pLQµPíãy.¼ÍxnTm+Â!ð”;DÈÕ/ ªž‹dAÒ¦¦kié žBcë³õŒGÀòbâôäÈy…v2ÊQ1¯”~µW §;X67¤Õî×wºP…Ú#Е5—[5Q ‘¡¨öLÒ˜‘˜f–ÞÆl\1Ãöd–:aìú>¿uXÀgÒ´¼«ÓÕE¬hKK µ@¿ã“Ævú`=‡š°hÊ®¯±œi.‚bÚ Ý<¼$îRkÓqœþØD“âŸL„ý-wØx¬1Ÿöõ¬mE»:ô…®bâi¯]ë'ÞXº3”7¿7»«Ÿ¯0i@]ˆŸ§d’81´ÙéêãOî&:XÉ’hó w6^;‹XnÞ_ýí‚¥þì%ÜYX%ÁFœyžIè€èýwE••=€€ÂìºÿpŽ\‹>¹~^ §áõcÞÑg^lRdôí ‘×4?÷we‘ÑxGq2ü%Ë€Yþ{-†B^$¦×kç#DߩؗdÇ´áb!p¼Ô¸bÿ½^ œ$Š62ö2_rKà í­ÙEñÚí ß~_9é¬e€~îÅ(GùSËá³$³›,¼ìvsïü›úpà\$Ø‚ÍBÿBx Ÿ‹’I¸lÛÿ|ù«‚\ø‰#½à rÔóÎÜ¥–TÈȉ<ÿâË©=ÿø¾>l0±;¾Ùöùï‰þú·«!L.°aRíb†%ÍJ%Ae ¥Ìð}cä µ£’e4¯j¨RÀcºh_Õ!šé𺮦_µ\SDL1tüð¬q’ ã¬4þÒqÃyõLËõ’eA uŒ¨³èêAÒg[Ãfîɉ\ç¿“}¬…ãßÉÿ‚KQË endstream endobj 3266 0 obj << /Type /Page /Contents 3267 0 R /Resources 3265 0 R /MediaBox [0 0 612 792] /Parent 3260 0 R >> endobj 3268 0 obj << /D [3266 0 R /XYZ 89 721 null] >> endobj 954 0 obj << /D [3266 0 R /XYZ 90 522.026 null] >> endobj 3269 0 obj << /D [3266 0 R /XYZ 90 461.753 null] >> endobj 3270 0 obj << /D [3266 0 R /XYZ 90 430.02 null] >> endobj 958 0 obj << /D [3266 0 R /XYZ 90 397.631 null] >> endobj 3265 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3273 0 obj << /Length 1403 /Filter /FlateDecode >> stream xÚ•koÛ6ð»…Л=D,)Šz¸[4Mº ]Ú5^‹¡+Ebl-²”ItÒbèß‘<É’#Ý'޼÷“ÔY:Ôy5y±˜<= }'&qàÎâÆ‰©ÒˆP_8‹Ìù8=ùåøíâôÝÌõd技N?¼;_œ_¼²ÈcûYÌb>=¾xõÆþ¾<}~rjáK èô=|>-~}z&¼ž@_K¨cä1?Ô—&5Üý>=c´OîrÁ‰0ÇõB@rä2s™Géô»¼L‹M&gn?­¿4²¾ÏSIVϵàè2FbÆzãd*)—Õ>†ô‘ϦÉË¥eR&kÙÜ%)òlTölŒR EÈî·?/­úóyþEMWImèXÈ ÷c &¡®øÑœ‡‘ÓCËÏ2½ÒJ6¿XôØ Ž µË˜p/ê¢ZÿŽáá×±ÃØrµJ NEºû*Ϭ«zV7*©•V1/•=LêezÔÙïñ˜0Ê­ý>Úo€Bz@z´Ð¡ƒý§÷²T¯«åR¢+… >‹†¬:W†}F…¡Ú:ËgñƱCÞbyœÂ)êó‡Ê T›ú UËg,56”ÀQ‚ª¿Œjàãù¸~bæúÑP¿ùü «É†âgûQõFަ6 Ær›…ÈY-l‚ò27a7ÑÖqÓÎbãNˆû\+-ë«–ç^VŲǬêMy˜SݯcðÚȤ‰JWÖzÍî:É®’¢¨Ò.³vÙ ™×†Ì¦§û\Öu¥³”>9IÊÚúÑ…!\ËuéaãXµªªñ8“ÛhW×ËT=Ùos0js{ŽÛŒQ)ïÏ’¼Ø¾—{]º õl¼Ï’°ùH?‘L6)É»ÓCq6nÑÉ›w/ŽçóÓÏ©¼SyU¢Eû âÞ¡˜r¾?¦ZŽeÞɉz†ûmýæýhŸ.&ÿL€Ôaz_ð„G( œt=ùø‰:à% ãÐy0·Ö#"¨ò…s9ùÝîƒ5€QŸÄÐQ=N‰ï¡š¯óRâæáF˜ƒâ Úà ºé`Ó"i«²f”Bþ¶ˆL’1{·btŸëI¹”Êþëb0_hnv™áýí)$,í.ÓõÇÇ[$ˆº‹0×TžZÆ÷3OÀlÊ“ëEU7‡DF0òiØr‚-Ì›gÈî¾#r+ÙøË:ÅõAøîÜèù&tuóë¹çDçiR´ ,yZ¶ý…õ ,Ù†F;cÆÄTb8Ì0ßÜmcs 4!…6éê¬Õ /Ø´WS»NÊd)×0ÆaKå€x[Ȥ‘Gú4˜–•BFj•( =äj•#ub?í~¨9°iŽóÆ~‰î*0Ü(Äì€ëwµÙK4*KT‚ÓØæõÀ*­2§¾ª?:S«B õC©­ÅiüZªU•Y¸–©ÌCÍ Ñ2¨å¬e©=­µ>{Í¢lÛ6’¼N’@´½ÒÈ2C`:X Wˆ©6ên£,Q+ór·Ç|˜ùà¹2«´ÖX”rkB‰µÕ|i”\›RçˆÌñþ¦ÑC _‚Z= ÁBÝ@ÄñæÃJ–JÊVˆéå V Þ®ÒtS×2#¶BBÚ«ªKøA»}؉~˜­m<ë$G¦7›25"›vI•ŽÅ¹2ŠÊvKkð6Z­Ï­£iZK3¥5®*‘M .Á¨G¦M’V öB êWç׿52¸ƒùEÂ=o+m%ÓÛñ›cEZõ<œ”;ñ‚åhÛ¾ºF€5Öï䦨¨ª[ŒS‘ßΘ%öo™G±V-þ?ãh—£OÃw&ó}`!àqLx|eŽ>ƒƒ/ÌnŠzeŽþVxüˆ endstream endobj 3272 0 obj << /Type /Page /Contents 3273 0 R /Resources 3271 0 R /MediaBox [0 0 612 792] /Parent 3260 0 R >> endobj 3274 0 obj << /D [3272 0 R /XYZ 89 721 null] >> endobj 962 0 obj << /D [3272 0 R /XYZ 90 153.982 null] >> endobj 3271 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3277 0 obj << /Length 2245 /Filter /FlateDecode >> stream xÚXmoܸþî_±µ…¥z]õ%€/ur.Ú䚸 IPÈZÙ+D+í‰R\·èï g(‘²|Éõƒ-rHÎû<®ØÜmÄæÕÙ×gÏ^fñ&ò4L7×·›\l2± Dœl®÷›Þ‹/~º¾|»õÃDxi°õ“TxÞ^]_½~EÄ ú\oóÈ»xýê Mÿ|ùþêÅ%ßÁùðÞÃçóõ_ž½LBK`ŒÒ’ÔÑòd¼ÃMg‚5|öR {»%Q¦rã‡#:o} áªnï¶~ ö8VêT”MÕ°ÿ2¦¾”Až°}É1]#f,£nby,êö“HÄD(ú»ò¼<½>.“$ˆeL‚,މÇïôJäY¶±ÈpðëÇÏÀKêu_¦2ˆòØ•¿cùÿq”Ki1ßú‘€Å¿ýü®ê¿Ö“Õ4A-µ ¡…#|TcçÊbÍr)™ûdi_ «Þ”¡ÙyKQ2þÁ"üÉQ,èNCݵŠ,ÏQKTQûBïü#Ÿ“{–2#Hʘ”ûö S“^«,VÛ¨Õí#•Ö ^M™1?[%±ÎÀ„õ¿NÚ›ïåõÙ/g†b#±6ã\YnÊãÙÇÏb³:°R¶¹×»Ž›(߉À‚j6ïÎþN5qCîÅé.Øeœƒ­ÛŠÊ5§ÏïÁ)¼}U ¼Ò™-u«†¢- ù–¾Ã Vâ´l ¥hx_‡Åæj+ï_ø¯*Ç¡¸i˜ŽL£‚ŸŠhCÕ¯9rÖ“Ð6àP•_ˆ¢l­(õÖÔ"Šl¥"H¢ ¤¬¬5Y¹pq´ âtÚJº½qÝ¡êë¡âémßy}ýØ{CžðpÍò,ÓyŒ_´<¼·cKsb “ß°žd¯Û À¦¹ÑKá ;CãH>²DÕ´,uì2Ûk+eÛ Ó²ÙJO› JJP’8e÷Ö4+fãV·˜%óî8ùÕD ꢩÿ]Ì  ª_ÆjJh7%«E|FE¸ð[(w¶ß @úá×<—Äg®çÚ— û ã$H!—ü0 ’q †AòI„ðß2}™Û\6E˹¢*î*µ¢ Ó.HwÄýáB¿Dp?¼¿‹ö®#ê¾Ú†‰˘VÚ[=­ëˆý?L¬˜XÐôÃ6ÆPì;du¯fFÀõg±W´U§S×Ó-œä mi5ñžv°õ˜@"Â,W•½°†EÏžkêö úÒÔçÐÑ÷±ºK<Ñ·T§’ðÕ‘ðCuÛ‘Œ ƒoY´4¸áH­=Ÿì´›’Ì0ªÁ= ¸iª= ^Ù`gf‚Ÿ¿Ôê¡1g¯(Õ•uÁ”±É™WåÁQ‚e¼D×w=—ߊ©v¶ä¡›-ù"[`¦‘NøÎi‰ o&6È5ŸºÙ†…ºÙÓFšÜb°zÕÝð‚C]ÓPˆN73“•ÄÛ}Õ«R‡6’¡‡í_Qjô‰dDîGºÖóÕ‰ë(ÜçÙäV½‹4-ާF{!Ôù€ ¶3‘íL\Ÿ|4sqíÅCŸàA”µ”دuKŸÂ0êN%|bJ$¡›©‘ùöÄÀ<ë½2§ät»]J=§ Í5‘òZ²JOPâŸ6_ÌD)õFUj²5ëõ@ dÁ&3Ú¢3c%–:FpÅÎN”ùnÕ‰¸‰’GnÒ “ÏZÛIV‘ ÉÄ¢RZZPhÉ•HÓÀsÞYNu•º©†ûªZ;è£@€Å12Žrï qÞo\)‘wêYŸnTDYd¤°6[uM¡€!‡F7LáXÒĉhÑ&"~JpàòÕÓšCÅš½†ÆœñŒœ:ï¡iA]‹…r7öæè@_“ïÆ@Bø‹™?öŠÓ©©Ë©Íˆ¹SŽçs c軆&§¢­Lí0ô 3Þ¯úä½%vÞ¾V§¦xÐE#2B- ¨í…‘« ZÞ[˜ì5G˜¥îsô}#EUMU4¦·,ªSUÖè¨Òl2—E˜§&4‚.4a_h@3ÊcŒÅŠèvÌ7Ü pS§TMX†YØnF@š~x¦†îD$s@´7r#«YÊpã‰Y?œ*"Š(Ç¢±åÀ1æ#e‚f}`Vsà´èÙëô¤Å½]¿¶%S(ñqèŽp¢ÄLHSÓŒ¥\óΚ»=/ÔÌ£> endobj 3278 0 obj << /D [3276 0 R /XYZ 89 721 null] >> endobj 966 0 obj << /D [3276 0 R /XYZ 90 416.282 null] >> endobj 3275 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3282 0 obj << /Length 1836 /Filter /FlateDecode >> stream xÚ¥XYsÜ6~ׯ`òÎF„’àáMdYv”’¥D[ÙÈ®EB#n(rBrlk·òß· pÈf£ì–K&Ð8úë} wVw^¼X<{‡NÊÒÈœå“r'æ ã¡t–…sãwôÃòäráù’»[x2âîõåéòôü5è³\¤{tþú‚¦/OÞŸÐø Î'Ü}ŸË’þˆaˆÜdp4?¦¸é€„v{v»çÇ@ èPÄ$ Y¸ðç‰ïfõª!î…Zé~,sEóNµ ÁÝø 5mÓ•õІo^Ó ëè{½‰[ÖEƒ>uÓKðÖ}™¸ã‰„E ¡;½£3ͦµºuLú;?"æ-:Õí‚« ¯_®OÏ_^,é^_™§óhVŽ/ί.ÎN¦ìùÓðŸgWo_\ýãjyòæ¹½˜t¿ÞÚa¬m=¨Êú×qh¢Íæ¹}ÞîÔŠ#}h_²ºïÁÝ:6/OüDyLìÈÉÏ‘[c±ƒ’³ªü×®U†0õžK>÷hCÁ¸o]ãèîóõBJ¸î.Ä#ð'æREÊ|n= 6ÍëÐD2!3»~·©s­ù±´ö{²<øí@À;³ ŒÂüáàæw  ïp§±óIïzp‚4a’cL©œ«ƒ÷®ÔÙUp"yWHG‚dlˆ!|Žr€á"NQ!kWùa~ŸµÝÒÀgÃâФÀ¿éÉR0ëˆ ?Þ|°ú„…KO–J“ã}ÃÿßzŸ. /À¬ZÞÄõšlk®çÏ_«þMS@ZøS¥xþöì ùâàPoÁ ëge­¬•õÿ¾Þ¡á= L.¼0Å\µ-Aûæú~yœÕ_ÍYÅÜ…síš8øâËé!Àÿ>Ç'2|ZÕoÚš6{bºÕ„†Øàý}îždŽ˜šƒÇFf‚ ÒÆãÚzÄÎCû&ÓŸ»Wk6ëBV<áÏÿZeN~»EÅL42èòC„8Xôi¶ó=£%‰@o˜*ôÑ…³T9Rk7õžùË¢YªµÚŸµ¯HÌKùýI!ÄOé±ÿ…¢CÆ$è ²4 ? ú|AÒ[†yäŒå^Ϋ¬ªÇ¬U»»°y¥¿ÿoY_¤õEô—#¶ÄP4âïO_„,#_×ø~PŠ%„”±­ñ#SßCY—&W܃Pꌩ«ªÀ¨0Æú¬òM¿¥ÓznºœŽ{œïöH[뺴ñ´C>ó㼺ÀÄX,>¶rhÏ"9ìf?Ë¥ƒLì ²SÓ²ïñ×_?©±8þ¨ÑüÆoÏO²¼©ú°Å‡j³~ÀÒ=v½z^ÆÞ­Ã½W›õºi{t/‘ ‹Y_\5kªTti}ÓT݌߈8fA4TÚ¯ñ¢n|¯ïæZh(\ÄB“áyl>­ìf4"B(MùPH¬ò|‚dq ížVU*ë Š€ÄH[ )Ùmc$„®Q¬‚ˆ%\LƒÍú¬J“Ô­›õœ€î3¬ÙAµP u»ð¡õ[9#ê¸qLÄ´q„ù¤q„ík2,nêÂÒµ‚g4ã'±ÂAï«âvN3 K¢pO3È#¦ûÉ““½ÐZÙÑR­vR¤*½>ø±ªlÕÖ´…­…má™7m UneÊö{]tØøÕª¬èØüCð¡?¼Døçï½Æ}‘Sègƒ!Ž~êê\õ@¿QPÃŽ£æ¡./._`$I]ʪF]¸RÚÄafh+U·ðN< ­ÊM/n©¼Çñ¥¢˜ätíý¶QºƒM"÷EÛl; ˜ß˜ä…Yª]™tu‰u?– ÓNÀý@gŒE!BöYkÌLÞHâ©gFn‚.žJS’áç7?Ò *oÛ¬}\DÒePYAhÕGÍ9ó¢ SúèßsÌ/KI´ãôÑØé¡™6|õo-3ÉÞtð6tfmnòÞ:³pÿ•NõSÿû?~õRôà”G°Š»ý/mÛÀ€4þ´ËGÌìM¼ endstream endobj 3281 0 obj << /Type /Page /Contents 3282 0 R /Resources 3280 0 R /MediaBox [0 0 612 792] /Parent 3260 0 R /Annots [ 3279 0 R ] >> endobj 3279 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [146.619 96.821 158.574 105.568] /A << /S /GoTo /D (cite.OOC\040page) >> >> endobj 3283 0 obj << /D [3281 0 R /XYZ 89 721 null] >> endobj 970 0 obj << /D [3281 0 R /XYZ 90 690.045 null] >> endobj 974 0 obj << /D [3281 0 R /XYZ 90 255.588 null] >> endobj 978 0 obj << /D [3281 0 R /XYZ 90 211.277 null] >> endobj 982 0 obj << /D [3281 0 R /XYZ 90 188.349 null] >> endobj 986 0 obj << /D [3281 0 R /XYZ 90 170.074 null] >> endobj 990 0 obj << /D [3281 0 R /XYZ 90 119.571 null] >> endobj 3280 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3287 0 obj << /Length 1813 /Filter /FlateDecode >> stream xÚ­XYsÛ6~÷¯à¤} Æ&ŒƒÉÎäÁ‡œ¨£Ø‰­¦iãL†–h™ŠTxÄv~})R¢T»õxƋŷvÂÖÜÂÖ›½ãÉÞá™çZ ÖäÖ °åaa—[“™õÙ>y{ô~2¼8”c[ Ã¶ÿ¼MFço4ñH“AÀì£ó7úótøqt2Ôó+Øïcû# _&¿žqÚ:Е§qpÔy„cÉ´‡ Âz´$ˆo9ÔƒÍL³_SÊ;üÖg‡c@sÕ°àä0gú3N§I53k³8¦e–?v%`Ë!€òÝGü5 ÛY•aÑ€rûÇ€p;J²å"JËžSÀÚ¸¥¼Cr™ÔI .Iò@"ðÇÁpÐ8N¿Åé¼ÇvÒ"^m9¥)¨ÉÕÍ€b»Š“™ü$v¨©y•¦R¢¼ñ€ØÓH“Š(×øsͿ̳iTðE…ý˜UšœF‘‘[ÂæLO©—•I$mšÍ"M»Ë;=+ZfÊÃD*e9Z‡pcõ$¾ÉÃ<Ž 97öyœ*YÔÎnõXÞE = s³òäaò_øX4lzR„ 3»¿ Ë6Œ#³³% “ª[1»x,Êú°ªÐÚS;®±A°FtÚÀlP*â®v€ø·nLÕð”ÈÛÜ«#Õç5æx& àÝŒ¢ï½HI³¥1ômmã°<ÐS•påD'\9 g³¸Œ³]_`Ï¢e”®”Õ‡4ÞT™­Y¯ÓšœïJGÿ,g2‹f¦ B±ª´k–Y?´ƒi‹3¶ÄÛ1´Ü@®‹„ ›îq€œŽ;šø¸Í’$“¥áÞX Š\x“˜Õ¢Z,ÀÜ?k{½xHÊF…l)T3ešgš-–q-)ìIàÄ>Ùßï4ñ´>xU™9·‘.¯ï“(,¢ƒ ƒ’ÖSid<‡ Õ½ sã{—šŠ,ém °àkªL=jr«< óéTSòH¬?\Ù¦ÈåfCÅ5¸Ø–È\(žÙ"Ò, !šI·’xštE©žÉ+uÄ8&.4_}¯ “*ú•”E,fl,+:uôÊ+§(g¯§ûûøá•ìb™k_ÜH“þˆ³ªH‚KÀ 7Ò7Êg¤…*=a¬ÇEU”zéÆì«–3°a“î—‹yt1ƒNP“M—3 Ó¤×wíû™©PŸ8ˆ†R—q8Ùû¾'+ ¶ˆìÞ] Í&Öt±÷ù ¶f@Áˆ¾u¯¸p5¤NYûëjïËîG$,æËTèí’Üú~nD¨‡H··Ðv‹T•-5{ó׆ˆ-ÖI@º8NT˜­ò¬Ž³ ŒBá€Tó8õ÷à`×8ê—ÁNœ1DÀ[ÏGщ ¹ìÞ¾3®˜/ï¼ÿW#½ãNG¾[ Ià†1j1,(×µ+S–d–ÛP/q>´x]Îé×Ëáð|ryt>Ñ8VéÊ|Úa/¬‰0HüÀñ²Àx¶“èŽÞ |H~ɪÅ‚BÓ&k†NB3DÒé~€»°Ov¯õÜ´…ª1ÐÓj­§F'Y¾íñþl›tã¶»»·ïŽ÷çï_ÿÍ£'x0¼'\ZMðñÛÍ‹G6š ©êéÉr®ÇH–¼‡p±Tˆ§_ÓŠAïÂoòõ™¢dÄæz¢®‰,Ìë-žÔóà žhæ²Fµ Ë»EnhET®LÃh¸‡W—gzÖª‹Ñjo­ŽE™WÓ²Ê#ÔûãÑz¤ÂEÔåë¾ñ É¯}~B\µ›;|Cp7³JìYЭ@†ñÌïYG@üK_ÓzM `úèV5ˆòKFŽó(•5ÏPC=Lô½“SÙB¿Ó#í8Ùí»\o89Ñãk=@ê“ ôêñèüëéè²³£º©Ò²"«}=£‚ü©ðëÛ‹wÃÎÞÃ"šß‡Íoë»ý>b ÷ŽÎOÆœ%ž«ŽPÙºÉñWù´X,߇æÁCµf´Q…ÎNÔg/‚ûÀÒK5¾Ž{ð·ãƒwÎ&¶¾X/µ×¤öô§Ogã£7k`:¥HQZ¥¨Ù6ö¦Ú@&HÆ›§(µ1Zö®kŒü¸†òØ Bˆ0ªØ[U¨½¥/übIŽØ endstream endobj 3286 0 obj << /Type /Page /Contents 3287 0 R /Resources 3285 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3288 0 obj << /D [3286 0 R /XYZ 89 721 null] >> endobj 994 0 obj << /D [3286 0 R /XYZ 90 643.43 null] >> endobj 3289 0 obj << /D [3286 0 R /XYZ 90 401.8 null] >> endobj 3285 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3293 0 obj << /Length 1634 /Filter /FlateDecode >> stream xÚ]SÔHð_‘‡{HN&3ù´ÎX±D_oö}>Rè¡6?sz}®ï"ÑÓî»lLn‹H8®6)4WdÙ®àŒ™v¡Ê*?¿8ô,;ø³+<Âl×ub_û寛¯ª¤ÌÓ\œ­¹fçó]Ôö¶–I¶ƒ‡¯yþ->ýx4¡amš“.—S‘ÞúÞQ/&Eû–-Ðüñ™ùl6ƒ¿.1âãÇã·'ó5ÚNõõ_“â‚Il8‰HRRÚÁ3Œà$G<å¥Ç~å~1òa¨¾Þ‡ ©ž»5ì5º><}÷õÕéÞîoØ¿&y»á”úÉ”{:åi!“j2sž§Í®KmÖuO†4] uBÏ#Ò?û ߉ÃÈ¡‡òIU-7úäð=ZìýØsáÈ ›¹ðBG#-÷>}aFh°Ê ãиë‰JCÄ‘ã3lÀ…1ßû›fÂF‹v™çÄ`à¾ã¹œ,y τڻo‡t€ Z¿üÌnÏ’ï {\¡qe’Öª™ŠÐZjl»lCì\¶··š$¯Ò¢Ë40–ßȤNoé¼LÚÛíš\¾CO‘WäC=ÀWuR?ü–.C×bP‘ªr™ƒµlsU òÛ6¯nvˆ lœS’¿KvðX6l±™‰ƒ¢x!uõM¦í8 •”™Ì4µ¢ï•Å™ÙåEöHˆ´\ß¼Ç?2íÚäªÛÂþ–Ê«»•ƒêYÉÚüÓVo×mQ—hAœ hðñ‘É¥¬2Y¥èÙÃv³±µt¼V÷Í»mn¬¸ÙËH7rÿÌÓÕèö®/äž°=ïÿÅ ï‚Û¢‹'/v.5›ŽÏuNฮDØ5ÏuÙ~°Ü¦°®ïtŠ»+¹?^Z"4ó¦KŠ!.]–«‰ÝýŒœ "eón¹Tu‹å*DZ´¨ç‰>ËýìjäNVmñ@„Ú6¼$krꃜŒ@|×PWæfÖÕúáð~Vààӎ̃¶•åR+§Ö#Ì2¿×¢*- LÚAÛ*îžèYƒ†p¦¹9Û0À4©†˜8ÀëO²®ûÎ6 ËëD³æ×ômº4•MsÝ2€¥tuœu©E¥{˜–¸Î'BWò6Ábü™ƒjkšÕxdÎe¹¢GàźF½wµºO"b¡`{äªÒ××€÷èÁ{£Š4 á2UÉA><ˆ-"Ñ·yR(­ÿJÝ;¸,Ô´µ”ѶTõ€Ó\è—½á˜NHê[®¶yúžî‚n júïk…õJm‘¥¬:} EU©&&.`_Gôyù¶èMâ̰Ò{a«±Ú¹*:Úh:º_°×Ý­šÏS›<•‘'´’2ÚíP‘̓r åOšž÷Zgû³gÏ…pWK-LÌG“3•MvÚÀ^ç<Ú¯UQP„VÓ“œÓSU7 |Lz8:?; 7pûg‹§~Íüß!¢ endstream endobj 3292 0 obj << /Type /Page /Contents 3293 0 R /Resources 3291 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3294 0 obj << /D [3292 0 R /XYZ 89 721 null] >> endobj 998 0 obj << /D [3292 0 R /XYZ 90 201.089 null] >> endobj 3291 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3297 0 obj << /Length 2728 /Filter /FlateDecode >> stream xÚµZYsÛ8~÷¯P剮‰œ<¦j<¹ÆSq¼«’ªM¦\´HÛÜP¤†¤b{~ýv£AŠ”(‘÷Eqt7>t7€nñÉÕ„OÞü6;xõ.ГˆE¾ô'³ËIÄ'×f2K&_½×¿ý{ööÓáTîùìpj|î}ùt<;þøž¨˜FÊ;úøþ”>ß¼ý|üú-ÕÏ`~ȽÏPü5ûãÕ;#{ 5r3>ˆcù #qÐw¶ådª"Á|N¦2€ÉІ“Ò ÆO¾N çÞÉ*o²æºJã$MœD>På_T¼:y3œÉ'SrIs?é7éÅ¡äÞêŠÈŒpêÌ’ÿ‡‘µXV@ßgZ…Žïö°\,³<+€ž‘Sñs™§PV7@ÐùãP/ÎW)}–—4®¹v ¯N¨¬aæÜM½<Ü‹Y~×ÍsêÉ˲v3ã†Jç;[^ÇmgGUopγ‹*®²´vTòº´ FH‹Œƒtn—Š0)vË ×„ëx‘RÓ`‰!1ê¤%†½%†ý%úÆCkÆ;v3ïÊUúBDØ\9JP›§í˜$ Ù­>DÍ[\¹l²² ÿÆ (4ˆ—ÔgÁÊbU7T#´±–¹bK}´øi¡µµõ:†¬œNéB’1+´Ð,Òz(ù)H­@³/J»V¨)IeYQék7"kjª!÷U“V‡š{/å•‹";ýôõÇEB•žçÁÏ*ÍIMºãKÈBeY¥Ëªœ§uÝ2Î’´h24`eÝSÀ{îIã¾lÝÓ—ãJŽx1ðN’qî—}‘Z£“¡ö’YLøÌ *Ë*¶¶Ú”TΡ^­ªÔmê4¿eÓBXeÃFÚc¨«ÈrG8v„ãå2Ïæ±ShXÕ,uísª÷7>Q­:5ƒoÚa+è@#gA×*ž9¡À2œâA-N’TÀ…¼óùç€êì"ž%‘ñfǯGö £¨bÁò¤ŠPɳ–#ò k¸çØÒßó€U†¬û܆ÀâB Wö€%k ¸î¼C[qI¾Zq1À;𲤊¶¡ES ' öš8bMÉ%S:h±ùpú^š`ç¿£Ûˆ 8+ü¨›†ö´M[ ÞvÌcÈN•Â3h¦ÜðnÃÐy\R¹±O†oîÓ.ï2ÃÛÒWÃ]ƒÏ˜ŠjU¤þÊ€)¢çÿ‘¡+ÆÎ:­~ÞÖáÛ :­§Ð\¤©#j×¢LëT•v>kä×±æü¥e`8§Æ¾áÁ§58 Ù”K×pé˜`¤g#+ÿ‚Î1+’ÜÔþ5ΫÙuZ§ã®¾J^@ׇ®)3»•Ú'üãâ aÑfÀzQíçqŽçȈz‰ ¸ÌµfTÑ+±P<¤­> UG-/¯ô}MÀL7¸óþ‚³`mX–V²ƒ˜6L­¯±OoIpy¼c~iðLºÛ¡U e—pè–%7F wm2íGOÙ[4ÎöȵÏ¿ÇW㺄Û\§®¯HQÙo7ñE¾–çíìàïô(|"&‘©'Z"0r2_|ý‹Oè‚£O8¹±- ÃIùäìàÏg% ™ÐtkæÁ}`4™‘°o§¡C•¬G­Á Ò¿|;\pc¶AB1ß”VLj(‡n§¶Xx}…Füï­- :÷ØC7¨0ØcU@€}íµ‡Ð/¡_sÅŒˆÀ{d»¶ó9¤‘îÁPg‘Úz—k+}sWÀËd¾ÕN‚’!¯_¸ýëÓ3Ýùžq½xú"6·)Jÿ¼^ìCÀé\7MíiÛ†ù!"àÀr~ö‘Šð ì¥E7`ßjÂEÕƒjð€X?E¡…ð©FNMp³7Ö‡k„ ÖW¸Î>ÖH݃ÆÏ/Å)¹½ð‰=¬dn; g‘Øó7Z”ÑÌp5æ*¶‹gCÊ£‡r ìâ>³ØmhÁ“%ßÞÂ"Ä^FñdcV¤`%JKft¸Ë*€cµ8¥ ¿ÇãàÉ6s¼Ÿ-Ù8è½,# ÇócßTÿ9ù³ÿ„º[? ÆBeŠéõôŸÅß»žÇÎ&ñàk6Œz¤’{žÚþðá &ÓnÇ#SøðÌ­yÔ3s4~Q¤Í ÆÙËêûΗæØêÀ‰GQ©]Ô7u9ÿ¾ë鯼¥~­ݘ›Zž+¹ëñfÅAEªÀ¾¯y™'¡rUÅËkµ}¤âðt’w™‘y“ï\1µÙ\È ØN̺º"Ü01ƒ!I¨ TÕév²z0ØÍŸ}XW½Â¶Ÿ5«$+1Ú©B¯\¦E?Éý˪üo:o\–¨‚Usçºâ+¢j™ÅyyEÍå­“ªpRØÕ‡¬ø¥K³4Uš2Š·ž¥¹@ÊÀN;.–«ÆÎƒ¦Ð9Cè³ `Å€ÕõÁ,V}qHÙ mÖŽ…ùmNµ©®Ç£ ¸GI’a4ÙF¡ýM kMÒbÀ·2É=‘SKTi:µÃÌŒìg!-—¬‘\ŒþHÅuº»Nc´I›‡ÁôÖ(¬Šã®ãâÊI!S»\.Ür¡ñÅë1J'q1Ýí¨^ u`¶5$ú&~5}¸h´¶É>,ÛdŸI‘›êÐØTŸ’Ò{‡a-ò‡˜Ã©›¸˜§ö–à{Ù%5»ì†}òŠCC± 4mÂlôt#:J&elºVúÞ‹¢,¦pŸzA­Îpв´v¹Tå,Àl…pÔVæ8C2Û¡lºï-óU=jQ³éEP-hÁf ÔrW }BÙæAX˜Ù„i60|·YsÜBÜßPU³· aIyˆ:Ú|}«@o½¾i A8ò ÇÎ>‚ði´5âc£§.‚í˜ £Ú‡ØÛËÂfV`ä¬Í-ÐË£OñŸ#G^Ą߿blZ{Ç•u¹H©6¤m*E·›'Ù¼*ëò²¡öî\8^NMt4Ðè›ìŸ¸J¨›âjɪ¢ŒŽÖëƒÂr€Ÿ€¯«´Ha[)ö9™úpÃæÑFZ½pº’ó|eÓ7Æïþa¤—¾0jðo8u ÂY“Ä—·ìzìF%<ÏÛ N¯ÞfJißdnÔÚ¥ÕìÚ©¹è4×Y„ñ®ct-”xr¬J"AÖÚPü^öíP´ÙÞ©p¯…;Õ¯E »GJunóáøûq¶UªÓfø‡ƒ6Èoá¾Â×ZH¤%¢ú‹o¶öšá3ŸÍ ŽçK—ÁC&î òË/íÍ—è2z–w…ÈøÓfõÛ†2ó:£f ©Say(%ûI.lï'ñ»—DtÿW0ÂepU—Á2Kßñë Lø‘Ue±H ×IÿM©2Lœà¿LŒ‚£•I<8ƒZ²QW¼3'ëp,Ñ{z6A0€·D¤ûh‹üu\¶õòÖâÒªÅ]ÑÄ·î%pŸu)!a·^\ð¤ü™Û endstream endobj 3296 0 obj << /Type /Page /Contents 3297 0 R /Resources 3295 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3298 0 obj << /D [3296 0 R /XYZ 89 721 null] >> endobj 3299 0 obj << /D [3296 0 R /XYZ 90 427.031 null] >> endobj 1002 0 obj << /D [3296 0 R /XYZ 90 95.664 null] >> endobj 3295 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3302 0 obj << /Length 3378 /Filter /FlateDecode >> stream xÚksܶñ»…>R‹!$=if?uZ;c_’Î4ï§cÍ#/|HÖ¿ï.v‚e'½/ì. p߈.n/¢‹Ÿý°yöí›,¹(ÂB u±9\ÑEåa”¤›ýÅ¿ƒ—?]ÿ¼yýþòJ¤Q ÂË«TEÁoïo67o$à5ým. \¿ýñM_½þõæåk€õyü ÿÙüýÛ7©ð6Lp·T8f¿8•Hô,b —ÿWBEa–Ã<$­r›üé݇Íß¾;¶ýðý‹ïÎm7|ì.®â$ E¦`[ >Üæ¨AÂLH£4ø=Š„®÷®zúˆ.ut*hʯ½?êŽÑƒåç_L÷åPnËž©öúR¤Á]µcâ^ww—qèÎß5 º±iªæî\æÙ$+ŠF$ëe¬ˆ‹‡Žà´qX¤|ZZQÐŒ§-î†ã¶¡ÿûcµ;Òp8"'ù¢áÜÂëª4 '`þ‰ZKÔôCÙìôsÀE"( z‡‡.ëjÏœš¡ü<çºøŠûñ¤ëòEÁ/\;ÛUFIðËÛ›áH‚pŸ.ã(ÐoϺ+•¦=\×édœÃ ‡@¯›Ë„­º¶9éf ÉÞUå¶Ö´ŠŒ˜sÛ÷C“ྎ„çOº.=]—2 …ˆ­®ƒDÁgóYÛ…ÈÃ$-,)œò1;¸ )K'aá׸ea*¤%ݵ§+2‹$€Èø^¡Oeƒ¥$¨êY7{s98E]ÁÒsôG]×4{½GUM=m@øo(RÕì[¼Ãû•B)síŽí£;GàüÎbÔ[ùwŽPºó™T¿ !_3Ï«5Åá€.!æIƒöÀà ÈëƒQ˜‰º<ŸëjJeî#Åã-VíÚfèÚš&ç²Ñ5)pœ„E’Ì…¹9 ÊDÁC;¢1A£õž@CK°§n PIt¨es˾KAôÌ¥õVŸ;}µ×è>Ü )È9 ò÷(¦/(o/ÄOÎÌÌ|g†¢z;#žýïã“ÏÖ¦ ©aŽŸ¶šx>fc_ÞÂÒø9Íéò`pûÁ’0mÛè'>îØìuW?"ÂüÝû˜òl>îŠ'EˆCkÁÍþg¼¶jÖlXfažä–Øù¥µøvÞHÀÕóuzX^ÊéÁú׃x’£,F¹­Úó‹aw~AQ€ä÷¿'I³ÕQ&J ¨WY¦q bH8`B»«0Ï î7¸Þß¡ì¸ížµº»÷ÙÞvåéä.pлcSý1ê~å6À……Êüà›‹¾*zàÍ<0ƒƒQC@T§s­Ñli7@Íô(fWøs9 ºkYš ÐNÿ1V9nþ@P]bôCÈœk¼à*ààæÐ«ŽåDi€L`ÅÙ: vºÊŠ'}5ŒÆuWX$A5¸·s ã)IŠiãüÂN÷}Ù=ÐÔ8øßó?Díæ–yÕàà`‘š¸s䡜˜›£Ýzw,σÝî¾2®FuÛ~Z;-([k•áiE S¦ìÂÐêîT Küš+ps6‚¶Ó–CÉηGyXðmôpŠÛvŸÂIíÍ„ÕÉ?w Ƭòïáº+\{çNÕW·MY¯«vœ‡Š¹Ü 'M^c·ô‚v‘K~yûáúÍëµ´œt±ï9Žäv 0D¼‚¾D¿%SÌÄ·+ñÃú/ Áâ\Û¾ž´5Ï}©iQÝ·´Ž…4Ða$ úödG&LN2ôäùUæ2]jfª †V0“bÏ“`p~¬âyúœ,Òg0°¶¦ùžð”Íâ´Ò†MŒáÃÿØÓç5é{§Ë}ÏÛ^3û³ÞU*w–ÑËØÄgØoÅFl§cqŒ4ÇÅ}’Ô$ö/§MF¾á?ØœÁ''‰¹z°ô—¡çF:ø/Ç¡=ËÁo Kú£³¸ kÑÁ8±Üúºæämõ€”u%ΘíanN^澫&q´»vÏ#ë`È¡F[MK5ç³9ÓnŒœf‰nhTÒŸSS’Å“±^w“¼´äÒyA'I]¡ú¨ëÙ!ÕJ¦’/t.—Vsy*ûO=ÁKr¡VD& cíôy°«-[_×á–{zp{i9ŸþÑ«BžÙ æ#‰×•–‰ ¤+ßö0¡@˜\iK_êùF=eèyâùŽ«^&ê HÊHÐÄ;ýêi1æÛX´ø®,K´Õ»’Ò>h¢*Fó¯]0á]çkßÚ0Ö´¸ðû1¡:¿ë4Qó%HïÄ¢À¢ RZ®$¹a„Ó–::weWP•&­ FÐŽ²‰þ‹KwI€3Ÿ 0[¦JJG›JVÊÇÄ&È“êé4¾: `Ý™[ʃCמhäß8µB¤,ÎS$(ÜÏÍ@´3æëÏQ Zð4 ù.@À(®rjCµ!hG¼È•5¼› èK‹ï …ªWm¸ÀÞÕ‚Â]Œ™Cï2$\xWím½]æ*³›ˆ¼ËŠ8œgDuµí\÷8ÍÀÄFAiŸz‰Km~éÿŸ”F1Çá×à…ÍÑüò›o2M‹ÔðÅŠ9rr–@ÁÊ„<;²ctË [¸F x 03m‚™LY·lóêû²Hãùê©6™I O:êÅ~ˆX§˜¬=s¯û°’Ó7Fì¬P_R3W4kÃÖ.ÚÕe߯Ðc76΂ãe~,"ð0"ÆÅª+g_Š6xÒeƒ›Ë” Õ@“+ÊYLR`@¬ g‡^Ò@e¡ûÁ͘hyÇž[D´é\H‘ðov€†Ú±êMWZrÆ‚T]c§ŒknŸ.ÍtZ„B¯ŠƒÌ„M°“Ž-u„{íÄ™ÌZpgñ¯œ`7P†Ò|7N¨=“z|•¥†LœRÈeËAEÆçr)Ð]Ê %ÁD÷ñI N‹0U©]÷|…õU"¢0йë›?¿G&ÂH¸.%E$ô*+›ÁV¬eRÃð£MöW„Wa’ºÖIÈÑG&¡(µÄƶZã8ž×YØØ´·¦¿v%M×%²…<~# ŒX‘p³×4’r.!ÑÕƒæÖ3§ ˆ¡¾0×Û¦ßlu€Üvç’ êÖØ(™íW5àOO#sö" e¡žn I9I0sÏ\u&•3d«¿0X²¢ô±a;'cU&wÀуTœÏØù;ŸÁ ,©¹Jø÷oPª'lôq/£ÌÄMYŸ ¯nÁj‘žc‚.7£ò7#wDß"sëyù^²àU3~&lÉ+)S?×eÕØíåÏ·ç«kG^ÕÛ+ÛJ±õµ úš¤Z:SS›Ã£Âðˆê¦$ÄTòLÄ[^¼V5 *¹‘šj0Aœb“pµ·A`›X „ÅÆ°í¶Ç\Ú ã¡'z÷®Ú™Þ¶f1‰K¬’ÊÕ“ï©? Á™™$&æ—RÄ¾Æø „©îWžF`ûDÅÝi*&Y>w&‰pù’\"p$¶UÐ7Ô¶mk¦dÎ"#ž{Üxk*¢JL)ªbTÆu-ħn4k™MÖÏ©q÷N)V‹lU-«EFÚyÚ ‚¿…6L ³”O-ž5Âèj‹®zH×¶x0þg¬¹Þâ×ÃѾʀ*EÝ›gOmrk­Ëizæ€éÁ¦ÏÜ2Ï3ö¦œJ¯–qO‡!]˜ÐùÕ@“%aËe Áw[Ìyã å'éy‡è†»NÍyä`”–Xý3¯ÑT¶ºî”÷z=µÙÔ<É\YíÎlÞÃ7ʼH–~ùDÅŒž²þ³H¢l5(U1‘àó1°‚2ÿÛÿêÃl8…alG|ŒÇÕ[^L‘©#‡lÈMôñEpÑGqPùZ0A¦ÓÒ5¯lCË#­P_ÓŠêªc®;z?GFTò'‹7/¼Œî¬¬Õ©ªË/¼(Sž*¬ÖÆË2@Úr†|N¬ÑÒ$¸¡Žס‚ŒFxFS==mà1‹Ï‚;‡82­+¤ÂzÚò°ÜèÁFÆÛ/—é[]·Í-ÉÉ  ù§rs7– ”itwÑk‘6”.„›P΄L}Z©b×0‹Œä“Ú/ l@äâÏû¿$Œ§dÍù8Üþ0Ûçѳùëͳÿiè endstream endobj 3301 0 obj << /Type /Page /Contents 3302 0 R /Resources 3300 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3303 0 obj << /D [3301 0 R /XYZ 89 721 null] >> endobj 1006 0 obj << /D [3301 0 R /XYZ 90 550.653 null] >> endobj 1010 0 obj << /D [3301 0 R /XYZ 90 471.973 null] >> endobj 1014 0 obj << /D [3301 0 R /XYZ 90 317.178 null] >> endobj 3300 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F111 3304 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3307 0 obj << /Length 1552 /Filter /FlateDecode >> stream xÚ¥]oÛFì=¿B蓌ÖÊéôݯM³ MÒ%^7 -Å’ãÃd]&ÉM‹aûí#”-)r‚`/>ŠÇïãñH ëÆÖñÁOóƒÃ÷‘o%NÊК/­DX‘ˆáÖ<³>Ûož}œ]L¦2vèL¦A(ìß/Næ'gÇ„œÑ2Ÿ$ž=;;>§ÏwGŸNÞ| ü±°?ÁòuþËáû@vú¨-Á£Ï |$:l¡5m ¦2&ÈÞåØßÔ"[¤u=™znh«²nÒr‘Ó×* „ûš1ù>¾ãO¾Ø4y†ÞˆØž¯TM„Šmê|¹)Xè’Ö´äuÑ(]ý*e†FÓºOa5ÛØK]±4Z;'ôýß§®ë$C¶õ·¦˜Þ­ò’ ”–ZÝ”iA°b¢*_äÊ0SÀaíúNâû}ùóX&#–…F–;UÞ Êµ:ãM#VŒî›éú¶`‚;Õ¬Ò›Š€ºÉooóŠֺьßyÄtyEVV­Öò‹òfSaøâ›J hÈX×ÎÒ&¸öõdêÚÔŒ‡ã@G§cžnõS‚²ªœAc\ I!áR÷ð¯Ò‰v_ƒÈ!ªL×93¾±pT&üC#ðP¸/'d'‰:-3º{ž3–trƒ¸<9ž}¸8¥/"i‘Vë. ]ú^oꆠk–t[éÛôfØ©I]Dé²øA¦ºY[½í™XnÖ×9Ãr§¼ç Qܽáíz4?øëÀPX.–¡Ðާ·X|þ*¬ ðà¼%‘ug¨Ö–—ÄN °vÖåÁ¯÷DšòæŠn¹q¥pâØ·‚8v|D™¢Á–ÎU+ð7è’²ö~ùR•ª¹ÊrLVô§uax’Åü=¶éÁõFÉ ½iHÇë×´>ë+ë~mµÂE•ÉÌQ7ü}q`ç&^›—Yñªgûî°±…ÆTFH½£ Ç3/[M¼¯X[4;¾<½:ýquz>?¿¸lwŸ?ßޘ历71ìps¾«ú³úJÂÞÐ"Èöià$QÔ÷ÞÌw«k……}ï@›ë2[¦ Æ>O²ÿŒîz£XŸyð%jÃÙ?ä7¬ôYï¦=»ÈÖ逭¯òõ¹ºÚÖÁ•YÇ=9ÉÇ=ˆF±1óôýßÑLãOºXRp|6åSüáXH÷!¤ÅzÔ Rµ‚2^䯵ÝEÂ=½·‚øzÚ^Ë“³÷çW—ó‹£Ùé ”œ”µÊò&|fSèc{1»ƒ*bÌ|¬„´v…£‘Ø—ÃCÞ±À»UÊ%ð‡Þ0*-µÊ«|TI<ŠMºÇ÷è›"=׉ ‡|›bÞ^Çê j+¤HœØwÏ05·^—ZÖX¶½-?#Ø<˜¾g¤¡ÕZúuÞ¬tÖoéÖ:SصÍÜ4ôá%ýÐP%>ΞÅcŠ·]z;º êà»×€)•„Œ.X«|ñçÄ…“ψŴ%†bÉkC-5Ȫ+,Œ´‹’±×ñ¢–à¾öVBeÂC׸U«Êô¶÷wxzI¡ê©À–] KÜ•*›ûÃwý{“ØHŠz’ÞévŠMY y èOXÝ{šéáèÛ<:û<< Ì=ÁÂÁPŽ ПºÁ³RD“¾Œ".*UICjØO©á`Ò “nˆã(` ÷/YGV´sìè‹–q­ÍËÂ|{o^±=ì,M:἟„ï£ÿÿÞ0gßëü9j¶- endstream endobj 3306 0 obj << /Type /Page /Contents 3307 0 R /Resources 3305 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3308 0 obj << /D [3306 0 R /XYZ 89 721 null] >> endobj 3305 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3311 0 obj << /Length 1733 /Filter /FlateDecode >> stream xÚ­XÝ“›6¿¿‚G܉9âëúä»:W·iÒ$nòd22Èg¦\¹Ütú¿w¥]0Øäc’t&•XíÇoW»«õ1ëÎbÖíÅõúâòqÄ­ÄIB/´Ö[+aVÄb‡ñÀZgÖûæ×ÅŸëå‹ÙÜ ˜:³y2ûõ‹Õzõô‰ \ֳķOoŸáç/ËW«›%î_‚|ÌìW°¼[ÿvù8ð¹¶„ÇØsƒ@3]0BðØ€{ޱϽˆ> …N与7›»Œ1{ù1oòòm \29sûCžJüV²ž¹Ìþ ÿ[C»«E*·mQ ÄNôP)•o ‰_¦§êSDÔa'J\ÉG…O‚V;êÚZ­h ±çûC!÷©Bw*¸{»öBM]=•ŸäœT¨ó2-Ú ë·÷t%â;A,èÐdë£NAeó.Á%Ç.ž#âCD><2£RPÕ~2«Qã¡¥ ƒ2 b¹ÜI8s>‘:] A¯àF{8` œlŒÁÒ X8Ž#X8ß2äd ‹G æmŽ®ê´pDÝ ({)JÕ¡œØà&|4ZŒê(1ãNSË5ßÐ&oÈŽ>(j)²<ì%áCÑÛH':b„ ¤¤Õ~&èÜÿ¶Ðî2äÛþQè€nüÖâžý†£g¥DB)±Ä†×¢£#uþ0màãì&üî|~&i€ø¼Ûk\ö­iZ ¼!Þ{ÈîF’•û¼ÙácásJØl¥hÚÚ ÄÇAc”±ÍÅTrw—àaúÃÎïƒbÈU©‡(‚FÉQΣ*7ãвª$qByHT¶¢LQYd¿î«Ž©]à°uh›§0â>¾ðÝpÕ?{ÌÄ_¿ »<Ýu/–Hç]_a_£Œ†þ®„¾o<Ó9}¨®oŽÆÐî· R“š Òë³À¨ƒLsý6§tÔò·XZvcS{œ±!Ý¥Ö_ÊÑM M~jb3­6°÷¹Jem^VØ¿CÎèp[‹»=Ílfö rHÚÈ¢{¯µ(¾äxT•0ìîé ñç&™ñÎÈãA{€/¦Œ‡æ!©›Nõðú:™(…AáõcÍh,ñ "‰7g—šc…N¤âšžÃ쇪…MؼÏ@¹k%¾æº vy tŒp—}veôÕ£7|bt'aý,z2dz¾ëpwc#¥Áû-üâ«ê©ß´w@ýÙ˜ ¶©IƒmšÀ}š1a™Þ2g”°Ýº\_üsáÂFIý·/L˜¥­tñæ³2 Ã…9QY÷†koùIìLÿ °^^ÒÂÏ“òÞ”—®OZ;U RΡU»÷‘þ­5ê}Z+ÿ\˜Ü`’ö2æ/ w˜ûÀéD0ÆŸp"FÑ}©çB-©MÌ?³³å|'ˆø„FŒý€|ùUuÆ¡§ñ÷”Ùÿ¸O1Ü endstream endobj 3310 0 obj << /Type /Page /Contents 3311 0 R /Resources 3309 0 R /MediaBox [0 0 612 792] /Parent 3290 0 R >> endobj 3312 0 obj << /D [3310 0 R /XYZ 89 721 null] >> endobj 1018 0 obj << /D [3310 0 R /XYZ 90 690.045 null] >> endobj 1022 0 obj << /D [3310 0 R /XYZ 90 561.388 null] >> endobj 1026 0 obj << /D [3310 0 R /XYZ 90 321.525 null] >> endobj 3309 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3315 0 obj << /Length 1394 /Filter /FlateDecode >> stream xÚ­WKsÛ6¾ëWð(u"ATO²ã¤ît’6Ѥ‡$“¡)Øâ”"U‘rêéô¿w]È$M¿¦õÁ ûü°»Xðà:àÁÛÉéjrò&VAÊR-u°º RÄyÉŽAe­EÜqöD¤-Ó„“‡Á¦æüŒÕ0¤ŠÉ$~ Ši¡†0Xs© Kèû“N·‡¦Å¬lj¤]¯™‰hú—ýgòCkÖD¨õtµ)(˜¢hXšº"8tÂR.úp8ºùTÚT±üB±T)âÖ÷J'ì%ûá“Ð]Ä(æŒæÞ€Ô,’äŽf1“LÎæ‚sèP3Eu=^”¹³r{›ú Ó 79r[H,£ º>˜ÆúÊMFÜmýDݲ^£ñëùjòçDÀ'„í†Qí' ƒ|;ùü•k Ci²8ƒïŽk„iÂ"n[X|œüvO¥ë²‚wJŠ(ˆBÁ¤&à ¬…äÝV5×Ü6Ò $ñþ=¶ŽI æ¤Ù- \v‡Ë²Èñ{¹XŽéˆF­RbiH#{âÌþIÇ$ýÏc»É1%‘ÓÅâô ø*«®ëÅâµ¹)rsæ³'Z°0µ‰ÎbHG'úƒÛ‰X'A‡œ—¯òº²õiãÌ7ÙÞñ%!¤›~Ž‚ü‹åb±´:GÀò”:d\¨~ ‚?vV®™{ØÆ`’Šªh¿­]äÖ²µ: ¤-kÄytWRýÉÞÔÅš’c±±8*¬ 0~*ÀäQÓÑôçGçì‰cR‚%*ÄC »‡H¢úyEaÚæÙ©…þ˜ DÈ¢Xh¼K "Ÿ<«›ÈD2—ñ º‰ë½î(8v]©9\iò?OD£§òàHôÔ4ô AÏiiÏ©Õð^±¾?Ø«ÝßeÙ î‹ëMÛ³Ý{ÑeŽ]v½;Î}6;“…¼w³>y¾«ï´:YI—Ù†XÓæac:Æ ™÷7ã¡9€‚ûr MwCSÚCxôdy/¾çÆsaaW4êÀ¸«›¦¸, RÝÅ­ìÜãS¹2${#î‡Ï3eG-˜_Ö·È‹SVÑxCÉ’¯À±@ê˜Åk4óÕn°vòW(„¹3tÃâ~&`Àƒ!jì‡Æ‚E7ªî¥3ªãÚWSVåDØÖkSŽào!Í…wÐ6åË™„mQìd‚1;<#«ØU¨³°óLè7§õ¡½#:߯[S¥½ÝwµA‚É4¢³¾ùQ¾=þð è—/Ð<rò}HÝe‘¼RˆáGA{.GìÖvWë¶ñ„ ×£îeÇ„­)ý¸=PEs;|]’h¯i)[A÷³&„–”ÇC¹)ö-Ô9½P1•x¾ é´•xˆ‹‡CÇÓÓWø Àé8ýêAÀÆñÅp÷X&°oÜÙ>W*’:‚Jo’ÉWuYÖ3ÁcuŒVƬÉe| %ÇWÜ ‹wãƒCø¿â+$k endstream endobj 3314 0 obj << /Type /Page /Contents 3315 0 R /Resources 3313 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R >> endobj 3316 0 obj << /D [3314 0 R /XYZ 89 721 null] >> endobj 1030 0 obj << /D [3314 0 R /XYZ 90 605.637 null] >> endobj 1034 0 obj << /D [3314 0 R /XYZ 90 219.644 null] >> endobj 1038 0 obj << /D [3314 0 R /XYZ 90 174.439 null] >> endobj 3313 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3322 0 obj << /Length 2150 /Filter /FlateDecode >> stream xÚ­koãÆñ»…>R@DóýŠw¶ï¢I\GÍ}H cE®%æ(®BRçS}çµ)³W(ˆ»³³³óžÙõ»…·øxó~ssû!¹›'A²Ø¼,ro‘z™ëEñbS.~sî~x÷¸yxZ®‚Øsw¹ŠÏùô´Þ¬úÈÀwüÙ,óÐy÷ÓÇŸyzÿðëúîÇ¿ÀþÌs~…Ï?7»ý£#<-N€:ÏSDºñ„C`Ï[ø¾›Ç° ÐW¤@#ä]‰›ºárå{žçü£«š¬ÓïuË“R/ýØùRšçGÕ÷°°†ÕáXëƒnzÕWF`¯U¿¯d ¤xЩƒ!Ïù‚0|+·Xù™›dÌæº‡mIàTÍK¯6ºÐ]§Ú3N}8KYܦ«JÍcæÂŒ`)¤ÂÝ~A™tûbG1ü û½)™8)â+a§žµ(‚Y˜ÃA5¥eK—Ýì2ÈJÒ‘iX<ó²\…ÑHíaä;E­ºŽá½áïVówʇ.Ñ»2ßù€#ÛAü^-}§)4&!ò cÁ‘›³áɵ)öbI*ž_(ÛŠÄOè۳H4'.¨ºR5h%Hºj4DÞ ÈœB5 ;u²ÈD¬AÉ0½ÁÁ/ºÕ%oÄcqAñgî ìrPêèÃV—¥rƒÏŽ}aêâ1sB[ƒŽ ¦I< rˆc²brm=‚(¼01€€Ab„þîÅ›„lÆY¶YÇIœ»ŸŸÞ/Ãó ­uKÖìnÁÒmµ]žçvà@ΛÚc“Aw$ÝÍÈHšÄpI}çSG «už$N%ÕÉ—ÁidD®+ð6¿Vµ@KØdÏý@‚MEÄÑÁ_æ¿é©s?Xë±5_ϼ‡MÏÙ&e›0ñ\?´©ÔÉG‰ë¥¹EØØCPÓD˜XG A¤%nà墨„7´º0»¦únKs›¤ÒÌaUH3äâe¯¨Vv °=·î q8ÙD!Ñ)¬¿q;\F[Ù-°ÄÓÚJv8r˜'ƒ#ÓæV«~Ö1$ãÇ3Vˆ“!aÝ(N/ûLSŸy„!¹ã}gsb&WY5¼ô¹1xЫPíì^ÍË:,1}Ó„\å²O{|În‰e ð$·MÄíßJnQnsN4¶*êŠÞ“†P É¡ã€^˜S]2p«ù«UW‘N®žù«x¬£šaèD0˜ƒ‹@2èÏK(oȇ—‹+ÃÚ[Kpˆ—k)YÃPN5 ËBW@vaË@%il{sa ›žã±®ŠQ£§íZu8 ½Çºrô‚²f½wkÎVh5&ýÆ®zxo[“–øžv?À~¹ Ò¥í‰¤í¹¿noª£þ¯ É'Ž`?c1³i‘Åe"J#Ò|÷J[M­L†üÝó‚†4˜ù¬Á̶O0¸Û«cO]LB9~kNýü™£úDóƒ)u f@è†pìïªUÍ÷'XYßym+ªW55a¹p„ÜŽl^ÇqíÚ+´•ݨ\)MqÂnE)¬¤Œ„0KŠ.R0iQÀG\^X7“Âþ®@§Ã^(„´8»Ö…Ùö—”âÙœàIo³²nE#ìð½¹}iÍAZè¡yÞxÌ›îxl/œs¶ÿ_7ºWa5¤Tî¼/ga̸CDLÜ9€B§£€p} ‰;[”QÌ¥µC•—»Áÿ&zÊv1¦ T»74¿»ÒÊ‹©k6ÄÀ·ävk+ˆ×Mñ4 ôæ÷ýäæ´ð7‚öIÉ¬Ä Îo«Ûº½žë&<7 ‡‹™ª_Õ¹{ÖXG¾2kÏ{c>£Q)£½U"ÁM3ßR`y¯Xù¡ï~ ƒÜ ±c0Ë&Þ4á’9\e`Œ5]—3Ìgt:™=ºêžÿ‚Vy† ªÿú ›Ì«.¿Å:ÅS~i¥VQh« Ûžj\…"EïŠ= £b _e€§¶ FBeÕ «R!ˆ,G8Ñwã,œzÃÎBŽè_Ž©î>—]˜Ï\µB?â i,R@‡‹ –BÒ… ¡Óà†ÐÄ”È7aΠ,ï«BÖ%ˇϩ™ ¶5’"6{ÑEՉߦ)+ºH²–0äBD i¸àCAÖ½ÍC[ÞPö‡hjõŸ'Ý ¥þ|%,˱çK“¥õ›±'c¼ESGÿ£#CC:LšÓyGöÝ$¹]†)¦±±;óÄMÒhäÅa‹c‹\x@NLíxÕ½eÍÂzé—»Þ´Óþ=³õÕ+Ù×Ì!±7DZ›ÅÙôva¶@qû?˜UÍvW½¹2ú㥆ÑÉS´­¾¤w—¹"7÷ÒiBÝìåù{žÝ©%o0çy‹v·àÁY7»vz¯èì;¿m´ C•KÂíË ðÞiƱB°\pØ¡'7…ìôí«8É`xñ_z}„NúGÓ[,mÂoä ÁjWa‰¾'‘qnîÁìS_؈üEž¸‘çC=Ý$ŠÅáæÏ7¥EùÈ¢ àv}/¾77‡Ÿ¥jqVBs5"J¯™ÿÂÈ Ót‘ÅnèÌ÷‡ŠÌ$šÙ÷ö"cÃüÒÚŒt9lñ9”Èz,ŸxDŠÎ"« ö8\«dAñ´£+ ÛBëÛ8¼ôŒÕÛSøæŒ î3=CÖº§'/ÜDmŽØš€4n5§<‚ãsl‚—GÑÔÖöE/¦ –+â 6:^,©Ã‡ô"$qhA;Ýàã º Nñ¶çç"FLSêÉFôNœ>‹BߤqáBʿڠÃÏšüõßßS û endstream endobj 3321 0 obj << /Type /Page /Contents 3322 0 R /Resources 3320 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R /Annots [ 3318 0 R ] >> endobj 3319 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./50_home_taurel_tango_manual_ds_writing_r_pipe.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3328 0 R /BBox [0 0 586 297] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 3329 0 R >>/Font << /R8 3330 0 R>> >> /Length 1198 /Filter /FlateDecode >> stream xœWMo7½ï¯à1) –Ãáç5HQôP Žôh¨ò6qºŠÛ­›ßÇÝå‡d­>Èxû†ó8>’_…’$Tú›·»îÇ^||êŒôÚh+^ºñ»øðsGd”ŒNhkƒ4bWc¬TZ Ým÷|½Âç6t6¸æŸñÓÐ}êB0ÒÆ€Xí$iÐcP’M† 8–‘Ô˜e$:Ì%˜FÓi¦”ý÷Ä—NG%(™ ^ÉíÑ„nÎI½$ ¹­åAoCS0ò^²·#Ë’Šiš“: $Þ9ÁÎ6â±oH†­tìOH‡”öÐPÒML¬‘ÚM$Vkä­ô¾ŒñRkœ´õYÎeËRÒ:?ÐÔ:Ñ4ý?ÿlwâÝ­ Dƈ’¬ÿì¦$AŒ¡< ÍAÖb½ëÞl†—Í·§»þß~û÷s÷i¿ÿëíús÷Ó dµÖhW4¦"é ….3Ig¦BϘQF’9f©0¿kú— ÔiÆG ­»ŽÙhi|† L‘“†s a§±Ä ÅÒä‡ÓL¥}­²:Í-3“K©ùjljß3JSX` $Ñãµ\É Ö²jé Â!H¾ÎtÔ6•,@ŽŸ´*Mè§‚ ñNÚqÑJÔ„ô)'ÂØÑ¡å”‘çº£'•)Ô$6K Nu='v1IòýÅ Ž~Üóš¥â˜ìBÒÏÈPVžFdŠºŒ „°Ÿ¼´Ã«\¥yêµ ryjp*Æ9±KIªÛÎã›±,ðA… a­¨|$òd#×VL+˜ÒQÅ2R+FÑëô[e]F¦ÉPŒ$MË©#ŸlËL­«ÁmÅZ±KIªï/†Iç ã,c‚É¥ãÚ*ì{ 24ˆUÒ¦=P£–«’M˜Æ\Os½ÚK™º+åiùæ¬Øå$YÈõnMÚóxuÉæ<C¤#–S¼ˆÌVŠ“çÿ1gø´-ffuëÛºu£t9E–q…Ãta4›Î ºŽQËà 2TÄK;"9ê’z'Ùh¤;┑KW`“s(Ô$"`¶º öŒØÅ$EÈõ~AšÜtxw˜‘Æ/È[?½ŒÌ[;W†#NùÄa3µñ‹ÜúE+v1IÒœÐÚm{B«t*ñ‹¢rÒ´,ršîO08µ÷§×~Z”J _Ìò:Ã"{á-ãÞ2yBL—Í‚ cZ¦Ñ%¦ eÀ*ÜòuÞ§}Å ¥ ›—†ñÁÍ93“ 16±“{½º”¢¨¸ÞÈq÷rº·Î¶‘¡AÒÙÚ˜å2 –lúpÄÈ£–2ÌF51«‡—ÐÖÂ[™‹f Mß)ëÒjßµ—­ÿõ|@»ìø|xì7÷é¹ÀO …08vÎú¾{sûÜýã¯ûçý£Øÿñ¹ß>'æŠqs‹f£Ô ÓH䇧»Í0ì_úq´4;&ºñ5—ïû¶ýýeweÔÈI£MWxAQÄþZA8Ú‹Ç ¤îîðpèSDzsE´tV±ÕӨ߾¼ß> endobj 3329 0 obj << /Type /ExtGState /OPM 1 >> endobj 3330 0 obj << /BaseFont /AGLFWY+Times-Roman /FontDescriptor 3331 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 0 333 0 0 0 889 0 0 556 0 0 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 0 500 278 278 500 278 778 500 500 500 0 333 389 278 500 500 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 3331 0 obj << /Type /FontDescriptor /FontName /AGLFWY+Times-Roman /FontBBox [ -70 -218 863 688] /Flags 32 /Ascent 688 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 129 /MissingWidth 500 /XHeight 460 /CharSet (/D/I/M/P/S/a/b/c/d/e/five/h/i/j/k/l/m/n/o/p/r/s/space/t/u/underscore/v/w/x/y) /FontFile3 3332 0 R >> endobj 3332 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3395 >> stream xœmVyT“gºÿb ï7Š8CšJŠ&¯µŽ[ÕkGìØÑŠË8¢e—Ͳh4$!$!ÛGo²A–È"‹ì""*â‚V»L]ª­:-zn—i;3·N{Ïûq?þ¸oìÌ™?æž“ó$ßû>Ûï÷<ÏE„Í#X,VDjq‰¨|m²´$_ú½†ŽaÑKæÑKÙ»Éì³;× -ì…0‚ #ÂN.‰,ŒBÏ~…:!ã/ 6‹¥puÆKK•eÅ…E²Ø•iɽzõšý³aË–-±Ê¾‰Ý)*/.”Ä®À_ä"±´´D$‘ý66Ÿ‹‹ÇŠ•¥Eå±ùGŽˆŽ„®¥ç‹EÇcw‹‹KK¥òØ•ñ¿ŽÝ¸~ý†µøñÆâ’‚ŠòØ‘Çn‰MˆMVˆóËþý A‰´tgY¹¬b¯¼2_Q <¼ÿˆ(±¨8åØqqIî±ñ‘H$¯)D*‘F¤«ˆƒD±ƒÈ$â‰,b'±ŽØEì&6{‰?›ˆ}D±Ÿ8@l'^&X„×’#äÄ5ÖNÖåyKçe/f[Ø×Ö‡]Ï ÿš³ƒs ¼jH)"?ÿEÊ/Fæ'Ï¿¹àЂ@Ä"²#D|F["i Я\c=™A;gØMô2žÓîµ6@²Û£Î2V“õšŒRŠ án„C$Ï·5öCòR‡x¯˜ Ue† €¬z]#¼D"%ø6÷úۇĪ}{Ñ–¥,Ö§Vñ±Gª›ÞØÍêù ù¿b#;Çc^^¿š01^¢PÔ÷ÿƒhñëß1/ µRÞÌÍÕÌR&üÝ=Ûí• ¥SUwá=ò» ·ï °-¦¤YÕ¢D%Tù^ÔÃTñl1×ì¡—òZµ×{}hâÁ¥m ɰ³¶Çç$õ "gÂVÅ0ýtXÑõãsšƒX‹¹Ö‹ãuÚmf’+V a€HøSÿíëÞþþ~Uò(õÚž; kˆY I¦Ã]¢žjø6>ÿ¼ŸwºÁ}öÙ‡UÅÒξ2ó 6¿™“!IÒm‚äa§O‰žaäÞ ²>a»èWx~»ÇÚÉNOU®±˜i4îÓaDŒ°Ç® ÀiU€¾s“]N™j4iL>Hvš»ûåÁâ|‰lg–ð`¶¥Wj&>Õ¦ Òë‚Ú¶¨Ë·Ñ–»‹¹kÐÇè¼´$\Ï©­­6ÖÕÕ@¾ R6}=ÉmvWT8NÄlMΈOé;ü4[xãØ`es9ósK3ŠÅ¾6…@ÞYÝ®&«˜õ>ŽËë°áx¹ è¯mÇÀ4›º»jZb>ûàÆÝÉòþw†„ ñ´IÝ »ø£§»'¦{‹7¶ "ÑijŠŽè‹ò!3³f1÷)rÓé<îˆäxëì&±ÚTm¤D©yÙU5$÷©Þh2š_k­½–äÞ¹Â\ålîÍ»yi¤cª_ m—©¨ È?ªîz_ˆÎîÓ8!‚ÞHÒo6küQ÷fÐn쥙.Ÿä™9‡ô Bô=³pûUà¶¥‘‚™$£PjÖhô¥b] $r›Ñcf…\´øÕðÉÔƒ­3>>ÓÔÕ%8w.<pµ“Á¡†Ë~~ÉÖÙ°VÏÙ„¸³]«Ûl!h²l±Wùá'$à'~ߌƒle&੹QÙ‚cÕé­A}Wª9}–ª¥j¨•Lcô«Ècò[üÐÇ- ®A;`2Ô`¤ÖEM,GÌh´Íd7Ú N¥Óà„Nèò†ÑKèAtÏÇNW¯Äüþ‡ƒ±50zPÕ¦r}é¦,z3’©& „>>lkp]paó¹j0\Ó¨¦¹.…S¹žÉŽ^‰ü5ÞZ/ôòáÉF÷€Ÿú½´×º©¶ Ã|ÝXâÖ8a=tûOá4FÍèýG&'ä»`½§iO„¿E·ŒÙëƒØˆ¤©éättGÔõ/ÐÊ?-æž§|ÄSitf5$eFÿ¸pÊÜ£î¨ÊkM„äÚ·³dÁÊöŽ“Á6G]}KXë©sCÙÕ×6z©K’&8˜uûU†¿ ¸­Nè†ä°‡*2먯´á0^%`Î,c^z¸ Í»>¼0 ܇çI4u”^YYFI —ú-Bá—|zåRNº0TÃ;HÒ‡À‹^ƒâxÙÛò$û`2Ìë‘L+GŒýµ·Ht‹cøê)ë+:tò Ì„9JQqNAéN¸…d÷ß@໇71&`¡5¼†G÷à-Ø!õmÂô»[QÛ(š mÈÿ~ŽªBRŒÞEã¼SµÍu§à#xÕ{®ã½¾¡[ð#8¦)í9<¾©{-Φ™ÃmV€/ãɹ]n6PÛŒ?—«]‹\1-ër¹ºPÌíœå«3P©±Úd‚Ÿ…MÌUÖ'3è®éô=ol¢·ù $'; w ™,÷PÚ$ÓÏÊ&ÍkrÃ;$Ê?å_}31¿üC4 Ìöb]™!¥Š_j‡ÕŽgyÎmÈÎp—©:É€ï‹ ÉI5âûx=a¯ ƒA´ðyÔ£ç¿Á»ã'’8¯§†«1l6ŸÕù/Ö´ÀxJ¿;$œ¨Ø[oðÂû$B€Kg 9¯T&“JÛdÝ=ím=ݲv †êŠf¨"H3g‹ƒQ÷ž!Í‹¹Kè”Ù8žœS#ÓëU‚¸cÜ$·ßô¨ûxLÌU“‰•ùð üíx K¼/š*èy´õrXNþ>óÐŽ ×Pd¦@ÆéeŠÂÛ8Ü„Vk£?Ó›kZØ’zdÔ0ƒÀ—ÿþyê‡Lô=á²ùãð*ymläöù1Eá àôqÿ‰¦D²“ƒÓg$³a/²ÿæEöFiô!žÙž(i•˜¹õÖ€-`õB~»G…˸Àm–2}¥‰Ò4P )—ꤲ]ã©Â}¯TU•]Eón~Š– ¹?dÌnûÿŠ:.Àúë Y6—['û½ÚláœË>‹%>¤ƒ´Pi=lì䣀b™wì56‹Íb·ðÝ”ÝÍduµI'P¨‘$Àɵ‹[ó/3kQztO×½nOô¸ù‡ßÖ Iw€ÉÓpÎÔ5Ôà±m¨ÖhtXŸFFÓq Æ&ÒI IUüCø &°þ:ÃnÅ199 ÖF+î×>¯‹Ñ¦i´ f•>:/¼FÒßâûU"j·Š9ÛŠsZ:Åz6ƒBv+æ>»;$ÌOyª²…Œ3dCR‡m”@ºMÝÏh@›Ûëru¶Ÿk„äx[fz €)z}rˆe²H¶ª›ámÕƒÞsý-œn)2…Xè IF|H'l%6m <ÃGÍ?òÞï’2N$¥ ”ÓÅ]i0J5q äC¬é3XÓ«CšžùÕ$+ôäMÎY2AH— ÓÓYhö.í¥ŸðP§ :lv×È—ÑÕ.µœ2Ë!ŸqCá)Wkùf‡ÅÝ7jÔž pôÊ~¸’\}`û[•*W[‰àx»Ì‹·¬D£+](8s¿ëò¤pâüÉiø)¼¯˜ÈœÌOngæŸÄh¬ ÒéA”äôκ ×ñ´%b!Aü}`ÓÅ endstream endobj 3318 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.52 334.854 148.966 345.758] /A << /S /GoTo /D (figure.caption.10) >> >> endobj 3323 0 obj << /D [3321 0 R /XYZ 89 721 null] >> endobj 1042 0 obj << /D [3321 0 R /XYZ 90 690.045 null] >> endobj 1046 0 obj << /D [3321 0 R /XYZ 90 549.303 null] >> endobj 1050 0 obj << /D [3321 0 R /XYZ 90 478.464 null] >> endobj 3324 0 obj << /D [3321 0 R /XYZ 90 444.741 null] >> endobj 3325 0 obj << /D [3321 0 R /XYZ 90 425.533 null] >> endobj 3326 0 obj << /D [3321 0 R /XYZ 90 382.176 null] >> endobj 3327 0 obj << /D [3321 0 R /XYZ 90 317.52 null] >> endobj 3320 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im26 3319 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3335 0 obj << /Length 1369 /Filter /FlateDecode >> stream xÚ­WKoÛ8¾ûWè² ]³|è™¶ ¤“¦À&m"tÝÂ-:*‹ŽDÇýï;I×rhö`Í{†ô7Ø»ó°w1x› ^žÇ—¢4¢‘—ͽ{1NB/+¼/þ»÷§³ñÍpDCìGh8 #ìÿ}s™]^]hâ©^²aÊüÓ«‹k}<¾|7Öû[O°ÿ–¯Ù‡—ç!Ý1(kaîtöH˜(¦6z#Ë0¢11ÍVÞ‚ò$ök!Õ&ñùbÿaHBŸëORèu)Šrþ¨÷¥„Jýla¸–\.Dað¤ûu+x þÔ®¼3ÕêÓw¥^™9/›VžÕñK»åðÚšøÃm?Þ¨P÷‹WRQYƒ‡ƒp¶IêÂT¤>Š"§ŠmГbŠfÏ{ÓÜüd—µn“i>û¦d"䩜I.¥å(¢ô°=æ¤îv„ðõkS¨ªVöÜšímwÞO=óÐØÙ²6Üä×Zöº(Žv,M&þµŽ+; ëîMFþ‡ÞdÔIeÛO5›É" z½®QÙ{/ªühÚXx\Ám^­åq Ñ3.”ÇÅc'59ؾw2ÒcýàÝ›g!pëpþÀèEó x"€Ñ#šÚLCÚ}ªHp†;e£BL­ˆÅ ³‹)8[À-´æ†<årÃy­UYsÃF4¥Cäj«é!Æþ¥ì«Ë-ü³ vT«ú×Õ,¢Ñ”MS*Ù1YO(AëE——pc7(™òÂÆ`ØrfÎÚéó^_!½¹ö“\ärOQY¯Ö†¶Ê¸Ÿ²ƒÃpTÖW¨'.ج[^tÓAl€ðSám^vw4 hêÀwh0w䫵œ¡jœ ›,ª†Ì‘roÍ[5Õ1à7€<òÕ»³/b§¶D Î# Îa¨×K5•ݨ*H/FÕOLù+Ѷå´2RÊ[x q×ÏN+åóÆü›ñéÙäfüÉ»™/Ô³õXÑ‚ýÿº*  endstream endobj 3334 0 obj << /Type /Page /Contents 3335 0 R /Resources 3333 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R >> endobj 3336 0 obj << /D [3334 0 R /XYZ 89 721 null] >> endobj 3333 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3341 0 obj << /Length 2174 /Filter /FlateDecode >> stream xÚ]Û6ò}…ž2+¤¨ÏÅ¡@šÝä¶@Û\btr…!K´­F]IÎvûëo†3”%¯~Ðp8Î÷ -¼'¼÷7?®n^¿K#/ò$L¼ÕÖË…—Š,Qì­*ï³ÿö_o>¬î?.–a,ü$X,ãDøV¿¼'äú¬¹òßüòþWZÞÝÿöðöžàOp>þoðù}õÓëwq8¹0ÂÛâı÷É8G¢ÁzK•«@ÊÐ[†)RD¶Úkæ¥&¼dÈ,r¬º…J}]Të»çö®Š+—'a rGÐÃÞT r*üº§o¥ÿ#DØj‹–þFOZ·´×Ô­f²œ>EËt‘K)¶´3€¼hO‡î6[¢êƒc4ìÝÍSiöEÂ{Ë<B™yK)ƒYz+œ ‰ðÄÀGØ#¤aYº®x&Ðz‰ÍiÓhé‘ds88úrýöM…“Ô7UõŠ#Ų» ‰ë´mžd '< Ø(Z¡9ð4AîÂ_«Š|Äx²ðªÝ™3SwÆZ¿laKß~èêvqsEÇ;b‡pPÊèn°>Š%¬CxRVÏ ôu©ôaÄ[VfT† K@òs¢èêüÔQ»Y£^Ѫ"@ù_×ÕfƯA ‰+ʲºtëËN\…!ç«0!†*LQ­No òB|¥Ë¦ ·%¤UÁž˜s6ÈbˆŸzK\™¡}2bz yRµiç,Ë}qÜ1u)“™Ý›øo><ÐN‡wé¶ÔלY™ò„VÐuaž‚ ±¨-œA‹È°Fî m=ÞÿHøc±Ó=J¼ßè¢ã“kDÆì šü‰ÏæDزe™‚ˆ8\-Ö±gSî¢| ó¿´|ÉUÏ÷CƒcöqH@õì2ów ´¶þ›‚YøO5ø–Iéƒ÷ÔšR1iMp_˜qÈ÷%ADAåNá¿mj03óìêÒëÓ+íuÈ‚$#–{=¥¼àJÉ1cúŠ@NEáoMÓ%F¨qõöÐXiÿ²å¶< ÎÎ#¿iˆX‰Š¾¿2 "èúK z…œX2˜Ó|^Æ`¥ëC‚A¤Æy£hžŠç~ ,ü¿H´õÞ˜/·6$_Z<¤™œ ,¥’ЪS“^(˜Æ†Ÿü¥ð ,iæ®®ûõ?Ñ+k,á?¬áyÒÕ÷D·!k.¬¹˜˜ —l.Ó䂨‚>çÎf—¶Æ®ðø‹*˜" &sšÍºD[«ˆâTŰFýÝÚ¡0vsjäõšc—n€£`‡s\wÚ]ã¹5fšèòfÚÜvæpq’´"!œü±m…WBv0“Pcíàj¹Ûã¯4]§û#ƶë× <Ç¡µO‰Ë0 rqQ>­ÝT$ìô³;uÖ7Xˆ…×í<>ÚpT‘„–™_F)¶nlWCªª+°~PÿB<ú¿ E¯‰fŒh@cD3‡Ó«-ù¤¤ÊbYœ`õpóÓ GÝýlGEõÆÒ·|‘ëÛ—†wo|XÓcvž€÷+6ƒôò$ˆ„„§p¤`ÀòpóçMÚMþX”#gÄë‡C˜zwææßðs\Í’y.'Lí?³¼ • Â4ôd*•r¡xW[?ñ¿ù-·Çsü¸Y~fÍ©jÓB”*ÌìQžNc"S£©³È™ˆ"÷jÞ(hÙׇc£ 5Scið<ÖÕànéí[ Qý|$Ój°“5²Ù…ùˆ&Ñ~!#ä •ˆó(š{»h > qŒå »èʽpþ®NÈMª½˜þ',ÅìÙEÀ"öbxÓ„!?¹ ÝCú¾š¼›4íp··/]¡sooyàÀÿxZcù1sNTû//;æ± endstream endobj 3340 0 obj << /Type /Page /Contents 3341 0 R /Resources 3339 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R /Annots [ 3337 0 R ] >> endobj 3338 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./51_home_taurel_tango_manual_ds_writing_w_pipe.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3347 0 R /BBox [0 0 586 297] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 3348 0 R >>/Font << /R8 3349 0 R>> >> /Length 1210 /Filter /FlateDecode >> stream xœWËn#7¼ÏW𸠠›o^ƒ ‚Äk9Š<Ùõf´òÚJœýûg†ÉÁ |QSÍ.6›Eò«ÄB¦¿ùw»ë~øàÅÇçÎWFYñÒßŇŸ;f#):¡¬ dÄ®ÆX’J Ým÷|½Äç6t6¸æŸñÓÐ}êB0dc@¬rÄ ô$iS€¡NSd5f‰s ¦Ñtš)eÿý{ñ¥SQ’%S!ÁK ÑMèæœÔ I²ÛZäñ64cïI{;²,˘¦ÉÑ9RQ($ñÎ í,`#žú†d´%§ý iâ°TJº‰ƒé±5¤ÜDÒÒaí €½%ï ÉOJùãl¬¬'d9—-dX’1|~ ©už>¢+xúþÙîÄk´Z€Š%YÿÙM-È‚5†òZ((h%Ö»îÝfxÙ|{¾ëÿí·úû»Oûý_ß­?w?­±@V)…vEcJ&Ï(tA´frf*ôŒiˆÍ1ËÄü®é_m N±0>´î:­"ã30TÀ`Š:i(1—í–X´Xšüpš©´¯•V¥¹ef’`95_Mí{FébŠ" Ì =^Ë•‘Ü`-«–¾ :Ò×™‚ŠÊ¦’Èñ“V©ýT¡"Þ‘­D]@´„>éD;:´œ2ò\WÖèIi 5‰‚ÍRƒS]ω]LR„¼½¬£÷¼Ò$uLö!i‡gd(ˆ–`O#2E]FPBØO^ÚáU®RŒ<õÚ¹<58ãœØ¥$UÈmçñÍX-ðA… :ÂZQøHÔ“\[1%aJGËH­G¯Òo•u™&Ã12™–SG>Ù–™Z+VƒÛеb—’T!o/†Iç‰ÆY¦&—Žk+±ïe,ÈÐ V’M{ F-#V&›0¹žæzµ—2uWÊÓ:óÍY±ËI²ëÝš•×ãÕ%›ó ŽXnLñ"2[)NJœÿÇœyàÓ¶˜™Õ­klëÖÒåYÆÐQŒÑl:ÿ-è*FEÁd¨ˆcMvDrÔ%$õ(N¶Ñ;┑KW`“ëP¨IDÀlU<:챋IŠëý‚»éð*î0#_°[?½ŒÌ[;—§Œ|â°™ÚøE ný¢»˜¤iNhå EÛžÐ2JúˆÅQ:2-‹ÒG÷'œÛûÓk ?-J¥‰‹/fù ÷WOÓ…mö«Œ ’•Æ%–ì,lÓ‡#F5/MÞ¡³šW m½«•¹˜aÖÐ\Z—&P ÞÞ2Þ^*ì/¼Õ¸âMöÓ½¼ CEp¸XÍ£ª)h°"„÷É‚tC)ÖR᱆GFf&@blb§b½º”¢¨¸½îù`ðJ±/cða|>ÜúÇÇþé×ýaÿ$ö|î·‡ôzXi\Ï"în«II,Ùú¾{÷ð|·†ýK?r°>MÝødK„÷ý?ÛþÎþ²{e¢“; }‚¹‚‰jƒžC¾}y¿9l~{xìÅvØ> endobj 3348 0 obj << /Type /ExtGState /OPM 1 >> endobj 3349 0 obj << /BaseFont /AGLFWY+Times-Roman /FontDescriptor 3350 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 0 0 333 0 0 0 889 0 0 556 0 0 556 0 0 0 0 0 0 0 0 0 0 0 500 0 444 500 444 500 444 0 0 500 278 278 500 278 778 500 500 500 0 333 389 278 500 500 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 3350 0 obj << /Type /FontDescriptor /FontName /AGLFWY+Times-Roman /FontBBox [ -70 -218 863 688] /Flags 32 /Ascent 688 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 129 /MissingWidth 500 /XHeight 460 /CharSet (/D/I/M/P/S/a/b/c/d/e/five/h/i/j/k/l/m/n/o/p/r/s/space/t/u/underscore/v/w/x/y) /FontFile3 3351 0 R >> endobj 3351 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3395 >> stream xœmVyT“gºÿb ï7Š8CšJŠ&¯µŽ[ÕkGìØÑŠË8¢e—Ͳh4$!$!ÛGo²A–È"‹ì""*â‚V»L]ª­:-zn—i;3·N{Ïûq?þ¸oìÌ™?æž“ó$ßû>Ûï÷<ÏE„Í#X,VDjq‰¨|m²´$_ú½†ŽaÑKæÑKÙ»Éì³;× -ì…0‚ #ÂN.‰,ŒBÏ~…:!ã/ 6‹¥puÆKK•eÅ…E²Ø•iɽzõšý³aË–-±Ê¾‰Ý)*/.”Ä®À_ä"±´´D$‘ý66Ÿ‹‹ÇŠ•¥Eå±ùGŽˆŽ„®¥ç‹EÇcw‹‹KK¥òØ•ñ¿ŽÝ¸~ý†µøñÆâ’‚ŠòØ‘Çn‰MˆMVˆóËþý A‰´tgY¹¬b¯¼2_Q <¼ÿˆ(±¨8åØqqIî±ñ‘H$¯)D*‘F¤«ˆƒD±ƒÈ$â‰,b'±ŽØEì&6{‰?›ˆ}D±Ÿ8@l'^&X„×’#äÄ5ÖNÖåyKçe/f[Ø×Ö‡]Ï ÿš³ƒs ¼jH)"?ÿEÊ/Fæ'Ï¿¹àЂ@Ä"²#D|F["i Я\c=™A;gØMô2žÓîµ6@²Û£Î2V“õšŒRŠ án„C$Ï·5öCòR‡x¯˜ Ue† €¬z]#¼D"%ø6÷úۇĪ}{Ñ–¥,Ö§Vñ±Gª›ÞØÍêù ù¿b#;Çc^^¿š01^¢PÔ÷ÿƒhñëß1/ µRÞÌÍÕÌR&üÝ=Ûí• ¥SUwá=ò» ·ï °-¦¤YÕ¢D%Tù^ÔÃTñl1×ì¡—òZµ×{}hâÁ¥m ɰ³¶Çç$õ "gÂVÅ0ýtXÑõãsšƒX‹¹Ö‹ãuÚmf’+V a€HøSÿíëÞþþ~Uò(õÚž; kˆY I¦Ã]¢žjø6>ÿ¼ŸwºÁ}öÙ‡UÅÒξ2ó 6¿™“!IÒm‚äa§O‰žaäÞ ²>a»èWx~»ÇÚÉNOU®±˜i4îÓaDŒ°Ç® ÀiU€¾s“]N™j4iL>Hvš»ûåÁâ|‰lg–ð`¶¥Wj&>Õ¦ Òë‚Ú¶¨Ë·Ñ–»‹¹kÐÇè¼´$\Ï©­­6ÖÕÕ@¾ R6}=ÉmvWT8NÄlMΈOé;ü4[xãØ`es9ósK3ŠÅ¾6…@ÞYÝ®&«˜õ>ŽËë°áx¹ è¯mÇÀ4›º»jZb>ûàÆÝÉòþw†„ ñ´IÝ »ø£§»'¦{‹7¶ "ÑijŠŽè‹ò!3³f1÷)rÓé<îˆäxëì&±ÚTm¤D©yÙU5$÷©Þh2š_k­½–äÞ¹Â\ålîÍ»yi¤cª_ m—©¨ È?ªîz_ˆÎîÓ8!‚ÞHÒo6küQ÷fÐn쥙.Ÿä™9‡ô Bô=³pûUà¶¥‘‚™$£PjÖhô¥b] $r›Ñcf…\´øÕðÉÔƒ­3>>ÓÔÕ%8w.<pµ“Á¡†Ë~~ÉÖÙ°VÏÙ„¸³]«Ûl!h²l±Wùá'$à'~ߌƒle&੹QÙ‚cÕé­A}Wª9}–ª¥j¨•Lcô«Ècò[üÐÇ- ®A;`2Ô`¤ÖEM,GÌh´Íd7Ú N¥Óà„Nèò†ÑKèAtÏÇNW¯Äüþ‡ƒ±50zPÕ¦r}é¦,z3’©& „>>lkp]paó¹j0\Ó¨¦¹.…S¹žÉŽ^‰ü5ÞZ/ôòáÉF÷€Ÿú½´×º©¶ Ã|ÝXâÖ8a=tûOá4FÍèýG&'ä»`½§iO„¿E·ŒÙëƒØˆ¤©éättGÔõ/ÐÊ?-æž§|ÄSitf5$eFÿ¸pÊÜ£î¨ÊkM„äÚ·³dÁÊöŽ“Á6G]}KXë©sCÙÕ×6z©K’&8˜uûU†¿ ¸­Nè†ä°‡*2먯´á0^%`Î,c^z¸ Í»>¼0 ܇çI4u”^YYFI —ú-Bá—|zåRNº0TÃ;HÒ‡À‹^ƒâxÙÛò$û`2Ìë‘L+GŒýµ·Ht‹cøê)ë+:tò Ì„9JQqNAéN¸…d÷ß@໇71&`¡5¼†G÷à-Ø!õmÂô»[QÛ(š mÈÿ~ŽªBRŒÞEã¼SµÍu§à#xÕ{®ã½¾¡[ð#8¦)í9<¾©{-Φ™ÃmV€/ãɹ]n6PÛŒ?—«]‹\1-ër¹ºPÌíœå«3P©±Úd‚Ÿ…MÌUÖ'3è®éô=ol¢·ù $'; w ™,÷PÚ$ÓÏÊ&ÍkrÃ;$Ê?å_}31¿üC4 Ìöb]™!¥Š_j‡ÕŽgyÎmÈÎp—©:É€ï‹ ÉI5âûx=a¯ ƒA´ðyÔ£ç¿Á»ã'’8¯§†«1l6ŸÕù/Ö´ÀxJ¿;$œ¨Ø[oðÂû$B€Kg 9¯T&“JÛdÝ=ím=ݲv †êŠf¨"H3g‹ƒQ÷ž!Í‹¹Kè”Ù8žœS#ÓëU‚¸cÜ$·ßô¨ûxLÌU“‰•ùð üíx K¼/š*èy´õrXNþ>óÐŽ ×Pd¦@ÆéeŠÂÛ8Ü„Vk£?Ó›kZØ’zdÔ0ƒÀ—ÿþyê‡Lô=á²ùãð*ymläöù1Eá àôqÿ‰¦D²“ƒÓg$³a/²ÿæEöFiô!žÙž(i•˜¹õÖ€-`õB~»G…˸Àm–2}¥‰Ò4P )—ꤲ]ã©Â}¯TU•]Eón~Š– ¹?dÌnûÿŠ:.Àúë Y6—['û½ÚláœË>‹%>¤ƒ´Pi=lì䣀b™wì56‹Íb·ðÝ”ÝÍduµI'P¨‘$Àɵ‹[ó/3kQztO×½nOô¸ù‡ßÖ Iw€ÉÓpÎÔ5Ôà±m¨ÖhtXŸFFÓq Æ&ÒI IUüCø &°þ:ÃnÅ199 ÖF+î×>¯‹Ñ¦i´ f•>:/¼FÒßâûU"j·Š9ÛŠsZ:Åz6ƒBv+æ>»;$ÌOyª²…Œ3dCR‡m”@ºMÝÏh@›Ûëru¶Ÿk„äx[fz €)z}rˆe²H¶ª›ámÕƒÞsý-œn)2…Xè IF|H'l%6m <ÃGÍ?òÞï’2N$¥ ”ÓÅ]i0J5q äC¬é3XÓ«CšžùÕ$+ôäMÎY2AH— ÓÓYhö.í¥ŸðP§ :lv×È—ÑÕ.µœ2Ë!ŸqCá)Wkùf‡ÅÝ7jÔž pôÊ~¸’\}`û[•*W[‰àx»Ì‹·¬D£+](8s¿ëò¤pâüÉiø)¼¯˜ÈœÌOngæŸÄh¬ ÒéA”äôκ ×ñ´%b!Aü}`ÓÅ endstream endobj 3337 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.52 420.516 148.966 431.42] /A << /S /GoTo /D (figure.caption.11) >> >> endobj 3342 0 obj << /D [3340 0 R /XYZ 89 721 null] >> endobj 1054 0 obj << /D [3340 0 R /XYZ 90 579.669 null] >> endobj 3343 0 obj << /D [3340 0 R /XYZ 90 545.049 null] >> endobj 3344 0 obj << /D [3340 0 R /XYZ 90 525.243 null] >> endobj 3345 0 obj << /D [3340 0 R /XYZ 90 481.288 null] >> endobj 3346 0 obj << /D [3340 0 R /XYZ 90 402.583 null] >> endobj 3339 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /XObject << /Im27 3338 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3355 0 obj << /Length 932 /Filter /FlateDecode >> stream xÚuUËnÛ:Ýû+´¤€X!õ -Ü‹iã¤î¢ThmQ02m W&]J©›ý÷9#ÇN|½0É33gž¤x´Šxt3zQί'yT&¥LeT-£’G>Mx^DÕ"úÌ^¾º|WÍnãqZp&“x\HÎ>ÝΫù›/q©â2c—onÞâñjöqþr†û`?åì#,_«×ç×Ezà0÷Þ áBr¯4âáùµà‡êã¬È’TŠhœNÌÐ*Ç"åœýö¶`7") J!‹Ça׻Ƭâ±Äý?§tsÒý¡ëÞº—­Uýšüø¶lOÚ§@ID»oÛf«‘áâbïüxN-‘eB,‰ÿr3¥ÄÿmXgÕèûHÀ–GÂw¶˜Ê$ϲ¨ÞŒ>åÑp`L&å$Ú­M”•Ó¤à¾môaô'ä¨a‚çI™çQ!ó¤èÜ@«å„õë&¬ÃƒŽEÁ~ªÍ¶Õg€LÛi/‘ì?cã´`»ÁHõˆ÷kÍC»¦mSm,  þO=t(­­éUCÎbëCŸ=´´m‹®ô¥w(±†(çÔ€-úÂy‡iÏ`ÚßšPù±À¼ÔÛ-Îx0…Õçr†Û,¬ÊÑÆØž6M¯îúœCLÁXWGž¨Ó Õûür(k«7Úxª\2£6ºóò’]íUÐe>´ wªFg`±tvƒB¬v¾¯6C#iC2IŒ†Ì÷Ô*Nar}mUÓª»–à¥uäçÞ‡è}Gâ®WØžç%¥D1„rBÉ&”ß|‰gŠ» ݧJ”Ø/…\õ`AiºO®dM‡+ö6 —áaðÚO¤¡9žg˜Ÿ40àù챓oh[yØŠÆš§9~ápëàOœºåtŠxÝþæÀc*2"¯õ–¸A¶[7õš¶{û;«Ó[ëhþ2˜âÄuÛ`]Iת#5×<µÜ9é'$¾ð¾s©`·z&Á‹í£ôT®ê#3†7âY«mÌpÁ‰”Ä=ðz7G‰ónµ© _ØúÞßõèÀ—}pRù”2+¢û4{›­Zé.´ÝXToµrIJ±Ž\XâZS—N$ø`ïqFjepÓ˜N;zh^Š¥âŒdz8ƒ÷NëÃÃ#áþ‚*¦lÃÍ5ͯáÚ5ðx›g“ÿû²|WJø‹ðYù>JdÀi PÉy8HZ<ŸoÒiteá óþù_+š+B endstream endobj 3354 0 obj << /Type /Page /Contents 3355 0 R /Resources 3353 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R >> endobj 3352 0 obj << /Type /XObject /Subtype /Image /Width 900 /Height 600 /BitsPerComponent 8 /Length 79562 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿá.dExifII* †Œ¤¬1 ´(2Ài‡ÔòCanonCanon EOS 400D DIGITAL``Picasa 3.02008:09:28 11:15:03š‚6‚>"ˆ'ˆ@0221FZ‘’ n’v’ ~’ ’ ’†|’ ކ’š 0100 ÿÿ X „ Ô¢¢¢ª¢¤¤¤¤ ¤!²2( 2008:09:28 11:15:032008:09:28 11:15:03Ô¤.dl"t ¸ Ø  ø } ·  P 6€ h  ƒ“p •@’ –Ò —â ˜â  ê ª´Ðà@2@j @p@ v@ü–\ÿÿÿÿƒFt0ÿÿÿÿÿÿÿÿÿÿÿÿÿ‹]dD ìÿ€´™ìÿ¦Ð€´TüÿÿCanon EOS 400D DIGITALFirmware 1.0.4unknown( 0 ° NNÕý;]ü³Õý;øúþúþþBÿÿ Ÿp"=ýPÿÿÿÿ•H0012004€P† E"l> 4c6 Xt3t æc¼NN³†feÿÿ”Œ‘€|(Í++ˆµ·h³²?½³ò43õ´²’ÿþ¹o––º { ƒçç¬ ææ.` XÞPÙ ÜX Ppo––º € 6--¢¹XÞFJ 3Vÿ33œÿ33œÿ33œM¦xþcð”*‹þmÕ'¾þ„‘l õþ KX6ÿÂpVÿÖâà|ÿëºP³ÿ…\ôÿ<Mh6oØsŸê¬ ¹Ú¶€ ë •¸ &Dqð ©â.` ô%ç)¶n!CCðÞlÅ‘!D> 䀨·2PM^Q·U7   €çÎ ²8__ÿÔÿÜ© +1·$^–ÿY&!§ÿKð ÿcÛ ßÿT êÈk¸kÈkŸÿe±ÿÄ6løTýÌk`³PMÿÿαঃaII*r€S;m'F3610312e60dae3117c22a2e665f6bcdbR980100@H(P HHÿØÿàJFIFÿÛC  !"$"$ÿÛCÿÀp "ÿÄÿÄ>!1A"Qaq#2‘B¡±RbÁ$rÑð%34‚²ñÿÄÿÄA!1ÿÚ ?ùµÙ’’ä­Ô‹ ò7¢ì™Ì¨Ü™£9Rª zÛ(J!HKKK–¸$n?ýß–=3EENL…6¢ƒ·Ó 2 äæ‘¤(8Ùñr$uÆ@õx(SÉT$ºˆÎ8¢Ò\V¥¥ì@ u¶;@¢È²m½?3‡MÿÛëb+Û}Ôk[Ò™e¤·‰7¸CÏS«)Ë+\®S$ÚPæÊ)^÷êåb0F‚ÓS©Òeƨ0Ô¦”µqÂ+P;­![¸çÌo‰¹ïAAf;,¡Ô´n› ÍÍ΢pŒ™lÕòC0.¸££WËó …L·(e™ÕHn%R[uˆÌ Ru…9·E½ÎÔªÊU7.ÆLx²°¾;iR–²ob@°ØÚØðã.…N¨Cy¸Í:ó-¶–ÛYPUÊ´ƒµ®FöÀ^K£½QìÆ>hfR*©nJPïM+’À¾Ö;|D2%ÛyO©-­c†·ˆóé~xi–ó‘{=.Qø,O•#[®©EElé7@ ØokïíÌã¦{Ëu×U:W“Ž;P$¶‹µ±½¢f:¥´¦ÂÝ*ÔéEÃ`°ò8“ Õݘ‡»ü•8æë.9rm늺MXg*,šbK·KdßJ×möó=<°¯²W"ÄÌžî]n²ìÏò¢3ŠÓ¤ßÅ{úílPï3 ÌÀ¢ÒãÈà °—\Ш§WØ [ßݦŨƒT—8]êK)IqN† |Z÷ÞĤXßs†)§åfZtÚók€…°PÙcSœ="ÁôÜs¶&;XÌïÑê0èu8­"ž ”¥K䵸n—«ÙI )<¬Aß‘)Oÿ†oHqM©æ$¡ÀO…ÆÕõGMü±#±*õ£Tg\Riò% *ßÛ®¶ý%§¥15˜ôô‚”ÁCú‹ŽmI6Øóål,9šÅ qãÊ”*š‡¹n¥m¾ŸÂP¢< b<= ªÕ2,ê|j-©eÊ[𔥭”“èQˆìÚ»¹QÿZ¿\Mð'DzC5(¥ fÒ’§RR½Gå±ê6æ/ƒ¤TªSeKRŽì•æ³WgUSÖ)«nDx+R®¶ø­#^á%:Ž›¨6;Ø|ÔŸJ½l¶*;2Ì*ÊùÅšÚe*2á:JMµù§Á¢¯*ÊÉ™ÞBœŠ¨±ª‘;'‘RE¼µ=ÇL‰›Eý¢Y[ï%¨Êmù â$€ÚÔÙ ·É·S³µ¶ æì›—ó/€Yym£P²Ó·²ml|í”ëÔ»[›Drä¥D\N4æ¤6´ZÔ|¬’/ÐÛ—`ѳ•W¾gioÈeHe °’Ò›mqÒæøÎ4tv•›nš ó8¨Œñ$Æ>'cëAin°9Œ*»ìn#šä¨K׿WnsÏÓ sÎdVH^Z¨Ce)uÙ/©×³„$£IÌN|úl:[™*æ,à 9H‡Äg_ n)Ô¶>äkŽWÆ™VÌ=ƒÔ¤¿Q®eš¡¨ÈZxÒ¥­–Ô³¹: Sså¶#ÿŽ!F”†rÝ-ÈÔˆëpG%ÝJ·R†ê#Uýl:czѧTirMjlxõX¬èëOî…%@>ûŽFÇäÈŒU*±Ø˜üx°ÁZ[©R’Bˆ$r@ÔŒJvSÌÛX±·ÐE¬—Þ|¯€24Øñ_yR¡÷Ä©!!v_{Ž·å€Ô»$‡¶*Ó›Yº¥&;6äP²G¶Ø­{4eÚtžãÆÞ¨ pR¡{ÿQä?\gTÉt䩨h†b¶â–Z säp@'Êö#Öøâ¤í_ñ}æ¦ÛŒ–XP)Kê¸*;|Ê·1Ì[Á|îj““5Uè’êÁ,.$E­½#k}ðÒ&a¡Wó3f™RfA•Æød¬@ؤ‹‰?LAÿ\5–ªÔ7¢¾9¦2’~ŠÔ¶?P{Yz£[%1[yE+}çQàͰÄÀË=Uéù^$4JkS/¸PªÛ\›¦˜èsãJ¥SÛù,‡’«ôl¤ùþX¶öŲ̈Ð(©UAHqj{‚›€«®C®:Õh=ß,@§ÕYa©1VÛ¹©Ãsºvè/¹ó¶(Æéóß®öÃêeYµ®{/ ¸Ûì/JTunGüöÃ.ÏrLìÉK–úHak ñ“¨ïp|·Äæl¢TrµmÚlÒíYHZy-l¡î1 ¦Ž^h†:ô½ÆF…^ÖUö8)Mº…‡’JIIñ#ë…I<7.9¤íƒ¤%´¾HH-¤íÔØ_Ñ B‚JNÀFþG×"Ÿ* ëLÄiN¼´””!Jüºa{N*Åž2ƒjæFÇé‹þϳU)5!£ÍY‡XP*sì,J4cgz7`Sè2j1ÝS©jC ³¨º„'˜*6± ¿/¾3ÿÙÆª¢¸–¬_nˆë­ƒÔ‡Z$oÖ×ß×Gö¦¢ŽìJ>XuÒëAu $¥*ÚêI#{t¶1,½˜«9N½.­Hy¦–Ó‘ÝHjè(Y¹E!p-cÓ’Õ rEkˆ´¤$#]¹âWöˆ‚–²åî+N,¾¥Y'vî›}ô¤®#)ݨÖ#HvC¡¼óŠÔ¢J€'ÎÀà\É›ëY½¦¶x,-.0ËMéJU{S±êqd¢)âJÍÿ<{Ä^•u>Xë= n[É"Å+)#×>ÃÑVÒœâ 8ƒÐ¤õýF4,(o*K®&ö\–ÔØöIMÿúç$ÃŽý¨øN© ¾Î‚6ð’AÀq¤¢NZz;W㔸-Îêlþ€ãŒ°©ÔÕ:E‹.ÆGS¾ßž ³î%Ùl6>nôÎÞ†÷ü·ú`>ÕQº m%Ÿ‰J[K‰Øjp¨ÛÎÁ?|0ÉòZ&¡ZžWÀˆR®ÖF… ½I$za'j }Š:<à†çT%.¢ë)7á%CJôJF'DBâõü¶ê"ÔyÁáÝ'Òýp•¥Iç¾ ˆåŽŸ–#é‹ ä9‰ÆO*K‹:Ê›¶àùn°»°Z„I¹>Kr&FŽód·ãp ¶U‰ßÏçÉʧRXä>¶•wä¶-©“p¥u\œsèmÙ+›Ùý":VØRÙãªä~5u÷ÆûPAâ?H­ŽYmQœ€¢Ô•[Ër/í€bö‰* 4˜Í­†RÐuË€µí‰ZÝV§˜¤-É‘š’òÓ§R‚É¥·°¶,žˆ‡x‚Â÷0D•jq è@?a‚XmQä¶ó±8ÉmZŠ}*·BF:T\KòœxGD]jÔGÊ›ôØñ)q%µ©$!d„¨¶6Çyîjq ½ÂF ´¹9x·¡%˜nëA±½Ôl@ü°¦MÊêo€!”ÆÑüÊn²^ìéé¡´ü*«M-v›$zÛÂ~Ø–lÝhNà„ï†ì%×h3[CŽ”¶¦¤ðSò®ÊR >ÁCîq9û*ËËu40ò~퇘Uï©'˜÷í€2ëš'G‘d¯C‰!\Šo“·“RÉ4¹ m¶õ%—ðx‘vþPz{ci¿ŽS¸;á>³dtÆÌ3ZFž) $Üw¶<ª\gQ?‡€Óc’A&à{O×ÙŠáÔ¸¥¡Ku *)êFÆþ¸5ˆÒ8Ðd8¥HK)m) ¦Ç@$ÛóÀtÉŠaRfF«-<Å—\XÓ© Êaá[JY#À­±(9IÌ¥cùÃÂ)W§,YPŠäMP RP¥m±ØaC¼»L©D}hŽ ¬º¢,”¤øŽýloŒÿ;TZ¯?-½}Ù»5W0ÚJ~ö¿×ÔÓ2d×à¸â–ƒÒB÷Ø&ø”¯¤¸”ð›ä9ȹÄU ÆŒ€U|-G…å}þŸòø6#ž2ŸAþØÐºìÜU\59…4]†ÚYSaEÝíµü‡L~ÎÕÉÕºóÒZKkÔQHÓ¨Ån—òÃÎÆéO¢—Z®6ë%HJCKIºÉ ü,Eö‘˜¦U&Íeæ£!°æ›°’¬yúï×è°E*”ã7d­7ä÷ÁmÑÙe¯…!à¢, H6ÀB,†Æ”–Ô¿Cr=ðÊ32’R#~ªðÚ¥\QPùugÛÙÖœõ2{jq»¶ó|Å­qÓß–57dJÑ¥jB¹X¤Û3ÔêY]×§"ò>k}?LYB¬© µvk˜$pÉ[Hâ,´‹’> ßËÿöÐzâ·,T—W„•€Ü¨.¶¤©F×¶ #‰Wšs¹¥î¸aZ í°U¯kûbŽ¡Z–øŠwÃüºó-VBHSjaMXŽD§c÷¶'c«Ål4§+þ¢ÉQ qsä/Š.34©df`Èp¨±&ÀÈi6ž3öÿó\þ› [g8qc½õ«r@¿‡–ÿ\F2?Ϻ“s{H=*(SÔ´tÜðÔ‹y\ZøÖ²ãzh¡ô-M ¦ÆâÊq7ü“ŒÒcAJSv¹¿å„ø_ ·Mñè„–ß¿á·?ÓÉÜ·PÇfÓÅe¨ lhoý÷$äé,ÃZ“-Ø.´¤„8„›*ý ÿcŒÖ£AGÕ¤%jŒRѤI¤Ç“¼&diLvW² ÷{ròÂ*µyAJ\wOÑ m¹ûc·}¢TÒJtn9\ãð«LsS’5:žgâ‘L$ýì™ ÒÝöÖý1èÉs‡ó§Ô龨¡³Fž^—à›ZÀrúáœhmHÛ¾_‰áI"þÝq:Ó/ZÓ‚ûê½Æ³…-ö 4Ð Rç3{l£Ôâ þ½K4Z㑎·c¸ ikAIÒ¢EñçM©U(q§G†Ûe™m–ã7©!&àC¾Ç¥TY¨~ì“RC±´».BãÜ‹%(NÉJm±¹$“‡™x·ü0¨²”Ã.:âGıQO=ÁÞ÷Æ´DæJSÚeÉeQ©+tƒgwÕkr·Ÿ¾<èt¾1"C¸ë:®“u^‡ßõZcβbÄ’”4à „YŒqF¤wz,¨ °¥)<•騎þØh}:ý3ô%$F <·ÛŽ_ŽÔ’óm  ”¨pÔ«>·6Ç†ŽŠJ¯Ï– Œ^iÀ¤êH#–®LA]QÌe·4Ђ岄$³Þ…('M…Ô*=7šº¢ÊGà 9o„„í†4É’%ÑŒ¦Xsº¯Š¢â,²“adž|úz㘪ˆ°Rì~ÎÛrÄ•ì´.”¾Q̽½Æ€ôp£¥ô$ïó'B¨qÝp)½Mê;í€*Y$¤-æ¤%§¼Ñoõ±tçF§ö}™–øÔäçŽÂÐ’P@ ÖIä,Û­ñP}˜ÒRêœIG5_æ·ÉÁoÁÍTzR¨ð‹/ArA{m*!vµý6ÄÚâËbZž®SåÉl(xˆ)Óõ²T ¸›é.=ðN\g½Of1 P[–!<í†UÅP¢¼Òiê/$n5¢úG¢é‚aæê>ô?t†Ô†ËRa”¥×RzZãånGÌŒQM[œÝ& Pu¤8,¥¡7Ò‘þø–¤²&æ"Ãëâ·!µ´ ­p¤íý°[.Èv‚%ÈRÖóëR–³òÛ–ã©6él-£[2™uFãá­<ÆÛ[óƒÿÙÿí,Photoshop 3.08BIMP Picasa 2.7ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀX„"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ótUQÐqN.:úUCqŽõ›¥ 4|ÁL.¦Rx¬ÿ9å©Dœƒ@îd…׎•†«€@­/´ðAâ³öÊvúа€8éDc2 ŽGJ|\¶qúP®ž8e«À¯Vö⣱`‰Ó$×O¥h7™\eØö4Á½›)` |8i¯FÖ<©ÛÚù²Z¸ :í5ÄÝYÁ 0êh5 .*&çó¦‡hÛlz”Žf€ä@͓֟1ÇJ®OΣ4+ÿ«5RymÏJ’BB94,@­:VóS­,Q¨cÏJz¢‘Àbcb“ÌŒ)oJÐ6'+ô¤lŒ…Q ü(T¸Œ€r*¶±'šÙx‰NöªòÀFx  'Ž´ÆuPr Y *qU,NO€%û@è)†ç‘x¨'H3Ðô¦Õ˜Ö‘ß#ª™ÚvçƒÒœ\Œ´Ö‰Z@Þõ8“ŽJ­E+4jJò@é@^ác\±©Íqç!ÝÂöª2”†fäö©T3+ØPÚËŒ¡ê ]Çï‡ÐÖNX7ojÕˆ—U"€-älõn´´Ý¦ŒÈð–-Ô Ñð‡`ñ‰ãµ½œÅRÿ/ Øì3^ÿ¦øgHÒ£ mf¿ïIóÖ¥»óN££´R3Š(\½ÄàWÑÿ´ÛDÐãºH£ŽPÅ~UÆáŠùâö\; fš`P|ìÆ IaòO¸úw¨ÚlpGÒ£ó‰l(äÓh씃Á#¥H§¥Uµ’/›©§M&Þï°ÓP4üç íP«7Fê:Õi®'²Š»ö­Ý 8O޵.FzU¸góiæ€/¬ÀŽ´Ö;LÕ2ϼíàSE.á´õ  Kôô¨ä¹X—¯>‚žÄ@AЬ¸ç4yÍ+nníI#ãÿÕH¡‰Î)% ÌÑ@BùN£56F2j­·=êç– cÚ€ ’á6áy4Ì<™/Àªd¶Tidc­:ÊÐÎÀ*ç&»}3Áº…ʼnh¬·C^‰ðÇJð|>´¹i,gÔä]Ó‡RÈsÐ)é^¥ÅŒy{DxãoLT¶ÉÚ¾…=ƒ²Í!˜b¹›˜¶õ•}câ/xZÂÒa©ÏipBŸÜm3LWËẔÜ\I$H#FrUáA< iÜ åPаÔÕp¬Í´²¥–Ù”ÍUåXóL |µ#57ÅÜÇ­?i$ ÐÁÍ8n œqOòŽ@«+ÛÖ€+Ž)7…ã­=ÀßøSUFM »Žj9GÍW#\SUåq WÔÐ´Æ P¡h8<ö  î™É隊BÀëëV$ùK}jA´¶y4ÅBG8¨ ŽF*æ02qK°H˜8  ñJÒ–D1¾)¢˜ ǵ9~õ'JQÖ€&:TiO’𣱠 Ei0Ðý+>.¢´‡6¤uâ(ÁoZsb¤UÚ•]ÁÎh[m/jAÅ8£ ‘œÑäóOAò徘¤ØwÚ€%DTmÇš¶Ñ ˆxŠŠBíÉâ´cH¡Œ¨?•c}æ#4æ²P_Æ®;&óÇzqu1ð;Px@èh©‹ó÷J(½²hy/9¥2b«Üƒ’=h¾z“Èâ¬)ùr§"²Á<ƒÁô­ \ˆFOÒ€d.›—Z©¸äŒsZPáÇj§p»d u ‹óR,‡Ó = Ímés¸¤]È£<×ÔÚˆ¼1ymÒç´„²€" —Ø×Êö¡^Ø•eôï[f§%±Ê9w¤ÕÀúÆY"Ž&y09.x¯:ñî£à›­ò æ³kãòó ~ÜüÍytþ.¿–ÜHTv-\î¡z× X“ž´’„o$2(1áTsVbF Ž¢,xSÓŠ 2$r{ ®±–mÆ®J˜‰›M2ÕAVÜ8;óµy¡crù|Š»nƒc0«*H¤f€$8æ«Íû×À °ÊÁŒri‘ÀÊ>aÉë@ ‰B°#Œu¡[t¸Çz¹¶üäUÁb |«ÍRŒç éWaP[¢;VU¸­›9Æ=(H:àŽë¥ÒÊ6kÒÝ‹ò+¥Ó­Óž)ØèVÈÅHà× ZB±Â¼ × ¢Œ¯zïmœ< ECB Œ‘X:Æœ†6aÐ×ATu-¿f âžG®Ù*±ïÍq×ÊmÜ££.FFF+èßìû;› Fñ2ò ŠðÿXÏe­Ëk(ù"‰½Pò*“Çåœ WMá]B}.ᤇi.»N{Ö½›\\ÅctŒ~5½m`öm2~ò7Úpx¦ hþЈÌWjg’EK®øKìÖæTÃ(î+¶ÑâŽ-Ñ"'”§R2jkè–kãaPÿ*›â¿Ù›˜ôàãÓé~{ˆƒªvêj•º/Û šõ (Ö;8•FÐhl4Õü%$™ GŽ„t®S²(åqŒWÑÄ“Dñ¸Ê°Áã>%·X®%±4&ž\G·>•SÊÊ}kNð˜Œb¨¾DY¨ íFW`°+š…Ž=)®Pžâ—QJ dcMߴЮT…??`Ûš‰›r®=jÒ ŽÙ  ‹¨ü©³ØôÅ*¦F>¦¯_[ëÍW‹€O#½U1‘¼zô«š~~d=©#9éSX¨óIõ  {išWVe#¸85ÙhÞ<Ô4¡pν1#n­qAx•Ëìgð¤[âÝëÊ~Ñ&P•GW˜Þ82¶ßZÙ2³g==+牛ëMQ³ŽjkSv7}© }jÞ–£í Ç8  ò|£Ž½ª«!\Ôóš±r péG–¦ æ€*àívëÅcO'Çzèü°ceµssF|ÖC×4 læ®Yɺ\U(ñ“V,¢ÿHSûç“ÍH‘ôrpjs÷éDª­·aäRêPEEubÜ"¬ÛÆví#š‘áÌl8äPDy~•ÐŽ€’:Ô‘Gó0Î0j-Z2äÐ8T Eh¬|EV[sVÈÁ=+J5Êžh±L¥)ÌÄzV£®=«(ó+¿et`pÊpEuIã]I,M²ÝÊ"Æ6ï8®%N3éOÞpE]¾Ô$¸v.ÙÍcÝÇÍL[9Zàü¸ '(F*»©-Ò­[wæ‘Ôn4YTçëV#ˆ·áMæέÀ2h¼¤ÆãŠ<Þ1ƒV'QæT>Päö 2wdõ py©Ö0¨IŠfÒùÁÀ  ¢äUiÆÕ…Ê`TrÇ4õ­!Íg¨Á­†úÐyŽ&uÇz‡y^*ÍÂ~ù¸ëPð Ë7*xF™ñžõ"}h—î]ÀsTOªèqН5¸9a@éW–¤#Šrýê`,‡¥5M:N¼ÓW¤¨G: wÌ}¾”ä†4ži>@Ý8¥Tç’*C¨ÞiÇÊ5º™çQ$l@Æ÷«–ÙŒóÉ g·†)ÉnDÓ§‘‹p´n(àP{(Üh§Ù< (c#Ÿz£x1&;Žjð  dÔBgçwcŠÉprjhY”cʤ¼j*vŒúñRéu¦= -Ô%nDr ñÎJ­&<ä{ö«B7eû¦”¯ð˜úŒP,ÿ•Z•CFÇÚ¡Š #lÅYÈÆÚ@c^&Èzšt1ì³b@ç¥XÔ¢b±àqÒš*I”À‰ó¶Õ\“PÛX±ùØI­”·fûË€82ÂPh!6‘S›T'q•™W¡éL7‹Ïz@H±,| TÞb…Á VLº$àãÞª5Ó¹ÈcLŠÞXÞb ëJ/'™kމäÎA5z)œcæ&DsF’•{ر˜`×36rs[vs2cšïôÙÂà×_§j‚5œŠó =D®9­¸5P­M€ôVÕ¡Ϲ¬SWÞ„©é\ój¤©ù«>[âùù¸¢Àt:“Oµ-èGQ\O޼Emâ Q%·–(ã –êÜ“Uµ9–͜޹‰¦ÜsM Ôn­´«‘Ûšìež'¸Y‘÷»®Ys\;?ÌG­kØHUT³|§LZð׌mí¬’Òø¶„uãÐÕ½kÆÖŸc’ Í+©Rì0y˜ª04×bHù+³þÉU÷qü«Òü?¯[\éŠ&™â|Ǩ¯-±IÉÅhÚ_yJ0æ‹ì:†¹kolÆ)C¹c ¯(×®>Ñ+Ži_S/˚ʚa*å³B@b\ƪåHÍf²åYSÒ·fH›¯J͘B 00¤vˆÊMEæ4‡ ¤g½hº¤ŽsQ¼jª&˜í Ã×½8ª6(>µb7‹®MXUˆrñ¤YQ°®09j•8©ž4<äÑhHM»9ÉStLÎEfÄ¡£mÄ©^­Ìÿ±M[u‘Ël×ŠÈØ¡z“ž´è—Ë}ÀV×ÙÔ‚ 1•rƒ@¤³ÞªÜ!‘”qžµ}DŸÜ‡z¸(EØŒ çïn_=s]z¦3Ò¹MPbúO­0*“û¬UÝ'þ?1íT˜/ñ«šA?n\q@ÒŽACÏJ®a“øPÖ„ˆï*çZ”¥eˆåñÏz̾´$y a»Šèg.åÇÖ³Ý y wÊrrIü«VÂЪ‡,}jߘ m(síNRÛ¸4ö†f\úÒ%œ‹’@«‘y…rMI‚GS@-ƒI+|¸Å\òXö¦Å I²ºÕ¯/=\Ò"K)øÇ'5"ÚIœð=ªß™ÈÁß§µJ³Ãµ°IÅP{yž*x e^Ôö¼· ©&¤cxÃ)b§¥@öåÁä Õ6ÓvŸ¾ k„^¸5NtÂ; ƒ@ìHË×­7µ8Œg¹¦ãŠ`4ŽqëUn¸^ \ª—|Še¯SŠ{ýêe¯Þ©˜|ôÐ1üªÕ¿ªÌ#ž8 ¹p¦ˆ2¹ÝRÍ’aÉRˆÀÍ@m—¦ÿÖƒ¯ñTþW¹¦ùgMEå®:ôª“`9xBrrjÆC0 Fô­ 3ó VxÏãW¬ÏÌ(÷˜’Æ£0¡ïVgPd&¢Û@€ `v 5/—FÀE*åJæ§q…5šÙ,I4zÒ¦7Rv§ ç­0/^¼S“N—ƒMNhÜ$n­%ÿPØô¬¸zŽkN1˜O\䟥=#$ŒÓU/îjÜ’9zTÖð30T]ÌÇkÔ¼áx‚^_üòõ Ùhl ß|3—V‘&ÔხÕ3…zµ¿Ã A¨Ó"b£Ÿ$šÖ³»´´PEÇj²š­¬µ±ö °3SÁ>Q¥Û¢Sσ´þ΄gÑq[hû×8À§ÒËËà-O¹ Æ}Q«.óáÊM– È{ W#óÝsíUî.šß’›‡±¢ày=ÿ…¼C¦n-ln"ïÀw~k7o”20ê¬0E{SxŽÖ2DÈéîk×ãÑ5Õ ù~og0üiÜG—^L%¶ƒÎ+•iþ¼W[«Ùɦ™¡o™;_ÔW!ùRS i9ï[V²[¼XÉ^k'çë]‚XÛ (Ü—J¦åù½ê!~ï6Ž”ý@-7ÁëPE$àŒ‘ÔÐɨ0R Œš·Û¡REPxFòXôïV­±å.9l˹1OÎï¥@Í´r·8¤3É1ûÖmÃÀÃ!žLƒµc18äÓYÞ5'æééUüÄÎ4ŒFÀ})v9aÃéVRîpÉâ°›®sÅI>z÷ Å•R"m‘ˆô©ÂþéOµ~sô¤_0ê+Ëp]”;}ã[åx¬´]òÈ tcŠ£¸òT‰qëIh&ûR«³c§5¤Ñ7”#¾j¼nVõàÞ€-ùG=Z†ò&KVec‘WwÄ2|Ôüê½ä±V "–ôÍeà ¯–,G¥`jQì¼pOJë­Ù\(n8®[Y]—ò `Q-˜êÖ•Ÿíùã5O9J·¥ø˜ÂsŽh­dGvÞE£HqV™9'­C~¿èô¤jÎÜmëPÉzÏÀP*"£‘HƘn& ŽœÔ‰w"@Í0.{➦€'Œ£§½l<ËufêEs8溫þ†½:v lå*UˆuÅ<§)õ©Q84€çå·fžV$ÍK³yEG9ïW<‚ï*:ñRE”¸ÝÏzÍ“OdBAïZVh¹Ò¾1ŒçŠžÍGÙ†9 ½…R¼Œ i1Z¡HéT¯‡ú,´Ëâš×¥vãq5Ч…aòUžgË žiΔÀëT¯@ ]iðÕ¨ÿ–ŽÄ×ôج Dœžô“k÷ªv7¡Ãv©ÛïšàšzSð9â¤ï@Ù¥*£ŒŠz¯5zì%á¨èÙê)ßjË6ÑɤÞÄu  ;•aY7|ÿ:¹óQK@¯<ÕëAó ¢½]´Èqõ  ³2†Á"›Œö¨.¢•®ϯz;i¼¡ˆÛò  å£dÆy«L»G¡\ã&€"eãšÎ” ç¢JžQ™“ƒÖ€!Å=0§‰lg'·½hÙè÷3Ì…W¾h.QÏ4ÄàWZ|"×;€¤Ž÷¬É¼?yj®ÒFp‡œs@ð¥iÂsúVtjCàõ­(ÕœzP(Æ&sžô®ÍœäTlø—Þ¬àÐСäÓ®Ôˆ©ð  )/?ÕÐjZwojA×­>€Ò¦¶b%ëPгl3*Ðé)¹‡çV¡P-‰ª˜zVcùmN8â€3_ïœÑHä¬ÆÙÏzÎÂŽõ±¯&.½EcmÀÈÍ(Æ1šPÒ*î=)Ûq@ Ž94õQ×<ÓqÏ#ñ§(ù½¨¼”Á÷©òõ5œ?"€7ü8ÓJú­mjHV(ÈäƒXZÔ£ô•+øBŽ“ÉR»˜Ž[°4‚ìrxÍszÙ?»(p rEzχßSÓÓP±ŒùLpÙ=ë†Ö-$gÆ¿8==è@nÛhvfÖ9d²ç9¬éñY=«[ðóW-õ-Z(²!Ú1ɪZ Ôõ4H‰Ï41—· ¸9Íë@›ç-ÁâºËŒÁó\ψÀ]Eñé@¤|¦¬i¹ÑÛª²ò OdvÞD}S¼#¯=…E|¹±¥X?p}ExПŽÔ€äëŠP3׊yšAÁïLã1šqÀ46 D@Ϻ­8¡'Ò¹n7tÍuZVMŠgÒ€-Â}jP84ÖÆû÷©W•=阎Ë}*ŽV¬ìg øš­çˆu)SnKkE.P€Æ:Ð9¬l ò;Õ‹lÀ÷¨¯.‚Äì tÅ?K9±Z¸*•òÿ¢ËÓ¥_^ S¾èòé@"x¿ßè±gf~Q^w c‚Ÿx6E\:Æ«€¾p¦fOͼW+ã˜bÂã©¶«ªdþú³5+›©£y cµ+R×ïsS¸ùóš§'Z¹!äSçøjTûâ¡MÞ¢¤†Qê+>ùq95© ‚ô¬ÝGýuR~t¸¥ÝŠg,Vs^H# ø-½³Nrß*õ¯%úY[-ÆÎ9ÇSõ EáØ ‡}ÔÀIÙ7sù º†œ‚Uò·cåÉ>þÕÏÍzÇsn9õª&èÊ@êÙÇ=¨«Movöp›ÝdÖÆ•u Ó„xÐåG&¸HÝYð õ5ØølÅm*]< °íéH OÁí©ZI{§ãrõN›¿úõÀÉk$r´R)WS‚¤`ƒ^‡©xƒì³ƒe9,ÝUGÿæušþâIÙ˜q»oSøÐ€çMºó¶ÑúÓ“ì+'Ýó¿5ZùÙX«!>µ^)Ö5=GéLŠÁ¬åA¶PONy­KíR 56ÚFŒçƒžÕÍé û«›±’P`LиvÜbzÐÖfœ’ÿ+J·¥jn×$¥™XciäVP²ÈUXûŸJsÊ" }¥ò{-túVŸud÷1.àuÇCøVK´8ãŠét-:mU~·n­G«øWRÑK<ê¯äH‡¥ 8·éGëWX€š­*í¼ úö«„(Sð mðWjHq³šŽû;1Ú€3"¤Š`âž(ÀqV¬Wt⪎•wLæzÕ¹cÀëHŸñêÄúSîW+À¨ÆE³R6Aóš)_%ºÑL ¾"ˆ„f°”ví]F½aSŽõÍ…ÇjhP  ­>‚=¨r:šP0xÍS‰ÁPY>ñÏÔD`ÔҜƚFFq@Kl¾…¿Ú®ÏQ\ÚœŽâ¸{¶d>Œ+»ºùìXÿ³š@W¶Ý d6ä#RJÍg>ÔÍ@n^9楱QƒÜÕ)÷‡|Õû¸¾´ÀŠxó)úÓÑp6âŸ*þôQ´¡9=(ÔKÆjìXõªv‘}¢EU ÆIàU»ÝšYa*Š÷Nµ -#øU¨äî ¬‰5‹hœFlÆx'÷‡¡«q_DöÌSÙ¹§ö¶Hÿw#)õ ž/ÖìdÛo¨Ü Çð¹ªÚ„ÂäÛ2[Ãô®z[ÿ1ŽW‘ë@2ø¯X¾WŠæþêHØä«ÊH'éN’í]sŽq\ˆ¾(ÙPVÕ¥ Ž”Xî?J¯$Ç©¬/í9j3¨ÈM05d“ƒÅgÈÀHzÔ+¨ ÔóNs—<õ ‘ŽÂy­m53Àd-Ô0íXìÙŒ]r\¹Ó&ž-vlCŒn«y1Û;*( Œ`TF1Êç<՛߸ó“×iänãE`N¦éÀ¤îÃU‡ò.>•œB'Œr€.¸ùOÒ£^‹N‘Õ³°Ms·*´ƒ+e㎆€-ëC„¬CÅ!KíªWiÏ"šHÈ$ƒLü)£Œà}iü1ïHV€"“tÍ61—)ä}iï(¯µæÍ>•bhn¢‘FJ·ž¦[X•z*åÄ_b²7L7á¶…O­Hõ«kNdœ°0#†“{µs:µüš¼_eŒ4x] ÷5U×YÒH!F‰@ùØƲšÞÐ ·Ä² ýÚž€ûÓ@{‡¼I Í„1L‚ÆB‡ÌBpãŒzʵšìJ.–I3£Œæ¼Ê]r}QLœ$¨ÙŒqé^à-BZÇÈ–`gC€¹ù¿ VmKAžÃs˜Û`ý+íqm&A-z¢ÚÜÃq™Àm½G½r^$ÑÚ=<ÜÛ‚ÐAÿdP€àmC¥¿\ƒÓÚ¹Ílæè“ž•»k#yÂÏB+;UÓÞ[Ì&HnoJ`sèSO·;gF÷­5Óí¡̹ÉÇ!icÒÖáÔÙ¾ç”náL¹èÿ²)·K›7Ï¥:) +‚¬GJY×ý þ”€ä6àœÒc4æûÙS1íM méÍ;Ô¬>´Úê´ €úV :|÷)Œç]k5µ˜Ig¯4e‡È¼w©W•ª7—YA¾yŒ÷êk=FN8§¼Rm£ôª6ºŒW3}£iPÜ] l¥(b€0çR¶çƒ‘Ï"®id!ÔsKª xIàTZHÙcë@ Æ«^ŸÜIô©¨nÿÔÉߊäÇqJE4½E)'™¦𥍀!w U=C˜3@Öøój^ UX?Ö ·/'Š”±jXÀT'€£5,dÖ·ÆÎ:Vf¢35h[¾G­QÔ‡ï±í@ (ÉôvÎŧ̎Œwõ©´=*]Rí‘ØÑKHÇ ·ö@möÄ@ì;(%ónÃä!@ÈúVUå´Åâ·õ9Û¬mr£Ö¹÷Žf# ôõ Fžb3ã#ßÖ˜–m½ŠòGzV•ß:ÐK²¢Ž˜>ÔUÕãÜ3À5gNÖd´GRÙR1ІýÇ—œu¬´r’Ít×÷p@,ÍÂÉ­©®.íì·¼f>8ÈÅgiK%ª ¢›K )ÅiÜÇqJà”'Šå®æ’áË3ƒU–6ÎljZ;YÛ$ûþb~aŽcîÁóõ  ;Ù ­ÀáÎ[=êÅÃÅ,j‰“!è³c$TdŸÖ¶mã6ñùÓ‘¿ER¿•¬!Kpxü»J­b~Ðì×^”—A.n|Ìn÷=)#­'U@M–¥ua²XØnSȯ[Ñn`ñ‡‡¼«´ ï±õö¯Iã™W rýMušMé©fæu‡©Hx-õ4˜¾%ðôvzì±Ú2¼ ýàÙ¬ÙìÚ8ÉÜ z¨šMöˆ`±„Ãp§–a’O¡5ÀÞnFhÝJ²ñÍ!^sQ^ÝñV" ¥A|>LS8¼RøÑŠrõ<Ð¥_Óqçôª>•{M¾úÐ¥ã¸ü»µ-䊫ó0Ï BT8-éH ®ï_ŠF?1æŠ`oë‹þ‰ŸC\Æx#Öjë›År}M!éžh+JFFrjH­älð@÷Ž4ºUø´öœHŸBjì倜®G¨äPsòæ”ñ4â?zsLnx  -Ÿ =AÞïߦƒÿL뀋†"º+`Úéqì ¶ÜhkO•ZÜdŒŠ¾dM§5çVþ%’ßpXWž¢´ ñˆ-‰ À=ÁéJÀt‘²Xm ü¸­]µÍiw±]ß,±­t›±ô  z„Y³|úW<‘ÆEt×_5³ŒõÍ¡§j˼UVmµ%™qÉ'©n”H= 9HXÆ;SIKI P@ª·‚EzñÅó+dŽ1Ålø]`¸Õ¢Kˆ¼å쾦€e¥K&š¬Å©ÜO ¬Ý[Y’Þp%0…Çp:î|g=ΧùH¢4™qÂäèkÈ'vg<œzh@]7Fâ`3ËcŸ¥uVr›ÍJÖÞ"D›™ŸÞ¸ˆ Ypx®ŠÆ³qö§VÂQŸâ=¨ÐÑb[:E!8N9Åsž Ó¢xþÛo £ç(ãñ®›A®.#S»yŽN稭=wBûFæ…6ǤÿZ<ƒx?.Þi˸ã“NÔ,äÓõ-¥Áe=GCL‰ÙTœÕÉ­Y9€÷Q\ƒÁ­Ye‘“æ6{UC°æ€));ÇÖ¯HN ¨ñ”qéžµi²Oµ#1ò˜ ¿i¬Þ]Mek3æ(zVyµ!²‚K´?½y0ÔÕÝói'Ò±­š&ãšÚ˜fͪVE®p¸Ï€šFËoÁÈô¬Ër=;Í$ï•J–úøÁlïžJœW 4$ÅËu¦€Õ¾ñÝù ¾Ôé´V^w7\ Ô ÄJz€X{dÓîäM¸c q‘Þµ¬n8f7JÅÎ_hèM[œ9ºG­tJIù… xäÔ’€€Çš•ˆ Ò˜$й߀:ÒùqÞ¦´Ã]ÆŸÊ€;-2&Á$¼¬¯Ë»½VÖu¨ +o¹s8 z“[wVæëF nTAË­y¥ú0h÷e|ç³I¨ì\í<±Éæ³ÄˆcÚ3ÆqŠ|‘LÓÌ@$8«v¶Ñ‰\ nô÷¦VH'),Í Êþ÷ÿ^»] G´[®-šæÏP‚B«å}¸¬ÝÏO[‚—DªÁ“à tú×H–M¤\Gso;Oi8ûç°4€í¼?â õ±u¹C3!ǘSÞ­iúÌ7ÆêÊõUC3`„¢±´¹ ¶¹SÀ+ Ýåü^Õ¯ªip^"O ùS³¸p ©ʵ³hw· î +²Ä¹äŒñ\¯öÔóÞ3JøLA[_´©4Ÿy2È$Þ»•óÖ¹`¨óîh•’fmçó­[)O =«*m1„^t´}?M•ÒáUÉ ž¾”è6rÞGS.âÿžî'Š Æ Cµ¸‹eÂ*Íñ/q]N³¦Çq£‹«qž>oU¤“¿ sŽ´‚¤™vÈÀ‘Á=j!õ¦#ˆá’RxQŸÆ±£¹g“|„ž}kbñ7é2ž3¸\÷ ïŠêìo B‰¼dœ[úy¸ó€Á8ïÛÂé÷"2€pGS]…¥ãiäÈ2h”Õä—PÖ§I  ššÖÄH<‘“š¢’BrY‰­ho˜Y µkÙY%”>EÊ0ü²ÇÒº+elþVÎÚÓÓRßľ0*¢ÝÜ>µÅY^=¦±q¦ÊH*Ûp{Rö­"Ëmžx§é{ƒÞ¢Ô-BÂùbvÍ.Šÿè\žô¦SUnŽ#“>•h·z¥uÊIô _¹$ñš:ÒcôëGoj`)I<úSkxKÈíÃd¿_aë[¶ööÃ`]ÅWïf¨x|+êÈÙÎÎ*¾§s,·Ó&]}ºPeÔÆYHåí6Íï¯á‚0K;Q4xlWGà‹Y'ñ+ç’}07õëi¨ qTÌ“ÃkJ¹RÁ‡~k´Ö­–97:ä•ô®~£1LÄpŸuqR‰§ólaFlÈß1=+†•pF:ç­tš§Ú%v–El# ®nD+.{šh M8¼*ŽXö6§~“âsƒÅP‰ØÄJ9Ü{Th\ÊÒ¸Éoe™€jŒV•©·h¼Ï(Ìëü=ãM†¶’Ly,x«¡K°Î2_øOAþ4ñ4ˆDìŠxU^+OL×K¢ìBªŒª/Y¤Vª±pTäâ«x~Ö w™]üÎÊ£­vú>«¶wöîÁÆGZoÙìµý=¡u]§Üp?Ï“ƒØ“9_3¾‚žÚŒvÒ„…ÛüT€¨4Kˆ¼Èä]:ŠÎ»±”¾Ì`ÿ*ÑŸÄÌò¶ã‘Ó'½aßk4ØF$ ¦­¦ƒ°6éA`:ŠÄ¸¶h%)µˆéÈ­}:I.!£„Y»šÓ¸°ŠHs¿s×9 5æŽ/¾ÜÓ†¤±DL(wzšv¥£Ì®dP[ڨLj™6ýs@§¾šv%ÜþtØ®aŽ>´Ù!ÚÄö#vi½ÎèÁ¢²ãœ"c4RÑõšÁûŒWIÁæ»®lÜ{W@2xç­tÐÛQ¹In Gj§ï‘Á>•½­Ãi2-¸@bç9ëXÑkic¡>;œ3ôè=«*òäE¸2ni˜ï+Ì_v2sŠžgŠeu›+Ÿ™"³V_Þ0œv­( 23¹§µ06­ì´ÿÌëk"Á8^„ðkïM¹´vŽHÛä8,Ed½Ð¶º2Ú»!®ÓÃ^.·hžßTÚCa@¼G-éU¯îK®Õ"xrM?TüÐH:ú\Z ‘Ö½¯ÄÛ5/[¯•¸ºy…€ç'Ö¼ntòå“b¹Æ1Òš¨%¤9©>µ“æ¶W5£g§I|Ƥã®)A€eÁõ§ÿIV¤údŸ5ÅÈP?„ šŠâòËOPñE²c ¿#ò  ÖÀÁR? Ú.$ðí¨QóÇ/8¬•ñìŽÅa¶en1³¥iéú´ŒÂÞòÄLx*¸ÅtÁ·éù?óÏúVj²„†µ†èg‘Wwò}«r8+Ùm‹HÆ1ÁþTÀ¯,q»H²9WŒ‚9Á¯GðTo{¦g!O  ®GjáeÒÒU.ù.Çšô˜"Ž×B·‚h„q‰Æ=©0,.œóÌ%†pê?ÏÒ_Ä-ôÛXÇÞfÈê@Í;Ão Ô-òƒ;(ÜGs\Ö¿®Ïw{¼j#K'.Î{އ5 y‹¦»Ö ZKið¾R¯cVï´=æªí 9Çf¬˜¤òFz8á¿Æ»=2ö-NÁT`ΣçSÜúþ4À—E¼’Æ4›ïDNÇ_Ozô « í:H’M®F@#Šàm£K+’(6שþèk£¶…lc•â™â™T+pAèj@ó¯[-RXÈùXå dî=9Æ+¸ÖläÕt¹]ŸuÄ\Ž1¸WO"0²õâ©ZíÉ·d¬ê@=ë¨k9vQX—Z|¶ó2:Ÿ­U€íæ¶`¾uµ’0ï0 gÇfçpEåŽN01@•ÙhvQ¥Œ—²c2p‹èq¤_!$ŽG`x‘Ys‡V,k²»UŠ¢ ÙêGJÌ—o˜\ã4i!°¾ phÔ˜Kte\QR^2¼™#T²h$â»ï…Öãí——8ûªWFx®óáÒÇuslz¿"†gâ@¤W,HòÙGBy­¯_ªm<Ö>gæŸïi 2µ¡çD#Æ8îkž“Æ=ë¼»·i†v«Çáø®GÎ1üéÃÛ*Dù~V­M,/*‚:cÚ7…íØlUJåµ-¬¯YHÄm(Þœ‘=µ¼'–sšÚ¶´T £ Ç[Ãömsknvüèä+¡´ÓåŽíä##w<ÒŸÔP´—¸IãÚºOxvÎh ÔW Òʉ¼?wu3¬Q‡,ÇMkÁf¾Ñæy³î½ 7Æ:ŸÙõy¸lÏJã›Qi_s’}i5[Ǿ¿–iÞcŠÍbz irâ÷Ì#hÆ;ÔHwï<ŒÕu$÷©ãp©ŒSzÇS©k{Nºó§ Ì1ÓÖ¸‹VMçÌ'§ktbŸzœûzR¹ýÓ–]£ß5‰y§Bî̫׃Šm¶ KopN}êÔ—!ÓåïØRm ÍÎ×ÇÖ¹Û«w¶™£nHïë]}ÄÂNâGµeFmn§ýòäúš`sÞæŠì?²tÒÙÚŠ.G6Zt®[ìå¤fn?zº‡ÉR=»VBi’Íãi'°  ûÈRO‘$¢õõ¬I¤8ØÇ<ö55ôX]‘“œtªŸ¼›$Ær:‘@ ®@Á ÒùŒÔóQygªÓ—P@¦÷JáóVÞ•g‰L±‰¿IlX¼X}+¦ÓáH-y ‘Ã{Ò•½¶O9¼µÚ éT¥ˆÆqœÖÝÌy•¾p͞¨Ìb¸äÐ(â‘óµIÒ¬ [¥@ÞSàú ½jþE» \çœÖµ¹ómCdàt  o¶,ê"WW'½I†ú Qöö&Sйû–=RË¿æÞêAL‘`•äÒ`g±ãð®yĆåÂ!<çŠÖ»×4í>m²(§¡®oUñR4û´èÌ#Ö„_ˆ#?jYv–˜¬lg]4^/y k}BÊ ´= /#ñ¤ŽÃHÖW2}–ó9È~Vöµ0+·—i¦¥ºgÌ“æ$Õïê¿Øºäs;ª‚vOPx©§Ò옇idIcLI?u…c- 3¬HÎGÖ€=Þé®4Ë«3f ÍÐW- ÎtÝfö唡ˆ™3ÐñÍtúEÆ¡§G$§`TÁ\cšæï­†Ÿ%ÌWĨCsÔö¤)w}-ÕIJ7ÝŸó4Ar`š6Vàš™ìBX\F§Ó4Øt¶“9‘Fæ˜-¤W{K‹6*ñá%@pq×"½&çÏ‹@¶µ•@–I5yì^×´ èfÓÕî#p¤Ïb+Ú­t‰µ]ÆK…Kk¸¶Ë"0ïŽE&~£åÚEoH¡QBþ•æþ(ÒÚ;ùe¶ÚðÉÉÚx­ø§Å¿mž[KdVh\«sŒàö5Å]kw1]€²|½]s‘ô¡ /YiŽìe™JFI5fâú=8ìŽÖ ]6—¥ËªèMuŸ5yέºZLFB‚8÷>¡qµLŒ´˜ö¬›…|!V,¾•jîìÞìÆ—ž1Ú«df*)ú `E º6U¶žÕÐ麋\m,*}â¹ã.\60x±¦4- RZ9ÜcÓ4×i­r— àp2¤ÿ#W®lÒlÆ[ž*¶™LÛÚEócáˆûß\w­]RVX ¸§¯þ4€¯g£Û»4——¦dûÌO'ØW9vtëm^ú}ż˜`XäÞ¶58^k0§-/QÓ5KAÒ™©Çpò£‰¦Ìsƒ@¦±b–Ó1Ǹ¬9Ž8ö®«Ä ¹‘1ˆßgÎ ?1ãµ4Tb§8« T¾à8ÇAR¬JA‘RŽ SúlrÜʱ[FÛ†$þµÛZhI©ÙÏc*jüÑ’q毥Q𖛦ßË<×÷â×ìêW¡zô- i·i§¼›>äÎ6þµ7É.´û›Ÿ*êŽE8!Æ?ýuÙøI7I’°àö¯C}.ÏQ·x.íâp;0ÏëT ðtìd´‘“Ðu\ MzæMBçì¢Ø7–ŒKÿu}kÎõghÃFˆWcœ“ë^¡yk%¼’s‰‚í'Ö¹‹í×$8ÎãóÍ*É|éàåºû{×Y‰¦†UæEEI×)[ÃâÖá‚.xÍliökLØÉcé@\Y¹ô}µ{u—Ë%ÏsYú­Í¬Û±$lsØŠã]äžbyfcÚ´“ÃZ¬ÚKj1Û³Dµ}ñï·®)Ø«CÒ!Ôz\ÇFFMCu¢2ê’Û–ù"9ÿz¹ I$¶˜‚]u tš°„´²ï”ãד@…£YjÅq…'#rÚéâÆÕEª^â$1„=@ªžyòÃ|PÍBåäF,Ùf÷âªéQ³ÏÔsT$™¥rONÕ¡¤¹K€Àã Ó…â;&>CÕÐI¡XλZÆ{ªà×âý*ëIµIl.&[`~tÞH¡·áäm;ObÁY#5´oáiZÆv®Þ YaH'`_ß½k\Þ¥_› Þ”ÝØË¦Cv$ƒP¿pý3]=êi:¶–mïn­®CŽAÇ?Jñû½‹"KŸ•×9­ Üi@Ì÷èK„$ž+Çx£Àšv ïa¸³bJíä§±®&k)c•‘Ñ‘‡Pþ‚}Q4ésg0š#ü:U¬h:¢yz¶‘çÅÿëÓ¸74E:ŠF;W¥{ö©ð·ÃZü 6‰vÖs¿yàyå¾ øsâM»Kb×ëÏŸoó®=ÇQM09Hȯ#‡'ùU ù”¯Ôb¥Žb¦˜ñ]ºà ‘ÛŠÓµ¾pËŸë\ìR–bwzÕÈ.Œ|síH kôi"'`PGÍaâv&·âœ8ÃÄÕ=FÃr {Pp]·•ÔQU£RsEtš~¦gڌ߼5×höޱËq +µ~@F3YéyáͶ·Y%QÎrj¥ÇŠ.5 ï-NÛse"Ò¯ Ü—^IØÇ9 X±Hñõ\ŠÙ¼Õî_MKR+Üõ5…¼–;³š`tDšlíåÝÆ0ÜnE>ûJµ·¹ÛÌ}E`ÂÁIrH´­çfPeo ô  $,Hd?Â8¬©/$’2 67p­¥I ('¦j†ÕB2«»= @À\"ÈHŒÔº•²[°a"°'Œ¯w1‰Ã3ÛÚ³Þw•Ë1æ€4¡¼‰b`A'zWsá_ ÛjÖÉ5î©{†V(Ø }kÍ“©«–³¼2®ÁO¡ L»ÒáÑï„GæPC Ý+BÞ(®.L7r?æ?úõ“snÖWRGæn p  ýêh/‘Úb8ÆAèkg_ÖÒîѾψ‚ý¦®.>`ŽÚ´š“ ÿ,—¢·Bh°–™,6ð#lš7]ë“È­ ?Ó¦gÌOáÇZã4˧*w6ƒ·=¾•ØXÝ(E¡T﹤'¬ÛJÓ›ÌW“–k‚¯Jñš—rKœŸ™³ëõ®ö"$ ì ‘ü4З§=EJ¡ °ûÞ¼™zc§q@ÞÔ4ý7XYuuš6å‡Ü>µßj/Ñì¥Hí®vÀ‘ =«ÉsÎ{‰”ù© vVŒ‚1ê(°ù¯ö;%»Õü»-Ã÷q“øÕaâÈe·i¬™dElHGa^]o³â›Ð ¼û@Üü¨+¬M´é-´«6®s%ÌÍ×jö°Í+Ñj‹ò%ŽHÉtËÃT!Œ@ªK¹Ë61Åj :&„Æ‹Ž9"±5 ¤›ÞàçøPrOµ -Úiͪ^ˆÞP‘çîƒ]ͯ†¢äJ`ןiZ˜·¸ß=²måÜçÿ×^“ xŠÓTµ>TÊ}än¤ÀÁñ5ŠYøb$EÁK@à×1¦Ü ¿·çx®ÓÅQ]jpÚdŒ–uÝ‚OlW·ËÃE<[%C†W"šþ;×yÛê¼d£à6+Ë´ö©xå‘áÏñœ“ë^£{ý‰¨Z2_"ñ’[ŒWŽê‚Ú×Už; Œ¶êß#ôÐΑt!¿[¨å_+iW\uÏ­Y×®òHï‘!l¯È¸Ë ålnüÍ6fHJ Âäžþµ¡癥IksŸ62<±ž‚€,G{4]T”ݪµý¾w^ª›•J«œcœš£—¹r‘ò?½L ú”¦`QNTVlbE'kß{±m“ÔÖ•ž‘ .ó ®àrs@ºÞD“3ìÏÌO@*߈¯,î(ªw>ÓÏÒ­ë7Ö°A$vƒË`F¿ã\Lò–s‚y9  ¸î¬ ¤³bÜ»pyÅv×›äÞ2Ip = ynæõ5zÒíиñïE€öé<9£ëpÜGun¢V\G)ê§±¼föÒãLÔ§±¸e…ʰþµÐé^)Ô- Æ“–Sü-Ít•ž“âÒ·2Èmu"¡wŽé‘K`<ðÈüøâšöÂTýÛ UcE½Ñî^…  ñ"©ªLSŠ`V‘«©"”Ä ƒÈ«Ä%Âmnýë:â# ¥2O¥0&,÷²N}kjÎ0Àg¿­bÚ[;¶ò+vÒ=˜!›ŽÆ'”ÀÌ€ÀÔ]I™W9ïKzÂK‰ñÏMIê(y&Y$á©ÙÇRrk*Æ:ÖŒRn’ï{£ƒ¨^…ÿúÕÑXé¸wÞ„@F3îEií,BŠ«”q ŠÕtUØm0FE\‚ÛqÅYH•O4€,ÔŽek:hí¯Éṳ±®‘6Ðñ²ž„t wG¹]SOŽqÃtqèk@DGJç¼=ÿïj:[pŽÞdcë]qL}(¸VUÉÍR×-ÖûD¹…ùÊV“g éT®2b‘OB¦€<‡JÑ﯄—œXžwQéò\ƒ8^r{Òü8h…Ϋg2†C)È?ZÛñ‡=‚ ›g·Ï rP…;ÏË'b#™ Ê QJ ¬lZ·4ŒŒA¾9ªRÀñÌÒ@Iã$æ€4-ç˜c3«¿i%yý+Ò{}æ ¦1ÊOÞÎ*Ýͼ֋æG*M÷”ò(bËSžÍ÷Dä­ušw&b±\¢ºž+Í£¾ÀÕ—=2*xîÆàÊÔXS—@ÐõÙ —V#’Wâ?ƒV:ƒô;…µp9†Uô£JñLö£ÊfÊ{×Ik­¡pé.3ïKT‰j`>nŽ@dvOÓna¾-¹8ö®ƒÅ>ÿ„rõÞ)L±1ýÚ‘È•ÍÌU†Æ ÜSƒ¸F*¢ª²’Ç9&ŠÝÓü?w¬HÐÆÌ·½Dn>ðö­Ï è—ÖÚڥ݌™€âMËòõ®›áûÅ«ù"ä#Ëf+„8`} z–¹¤}.K„a´ÒçŠMá¾?²Dß[F¨ŒÅNÚàr]²ÝkÕ5‹[ÒåÓ£„ùŒß»Ýë\N«áMCGˆI3@ã©Øý) 1ùsÛÚ¦IÂDäúÔQŒ † —*~fÙìåA<êÑ!?{½@ó3Æ«ž¨3¹ÂvÍ0# ‚OniV0ýéÍ×R´ù$7q@[‚¨ž7ˆå2VŸßÔS‹íN~íiéóÅyoöyþVuñÒµ4˜æ²k«b3æÆDmÛ5ÌÃ"£|­]•¯g‘ç –ýÓÛéHzxî-¥h¤FLœ•"§µ˜ÚÜ$›~ ÷{[ÔRþỗ÷gîñTìm¦Ôn㶆=ò9ã½þ”ÐG43ìX€ö5©å˜­ ·‘é‘÷ «Yiþ³ý뇛w?È{V­â!4¸T%c(ìj@KåB±’4W<’Fv ­q­An¡boAXwÅÂ2³}y8Ö˜šœ÷ŠŽsSTsŠnãH\ãÚ€=GZ±·¹ÅTÜ{SÖVèúÈB±Ÿ£sjr’0ª"v+Œÿõé ››œPC§Êú×›tÞb á[‘ZÒÛéqÛ»Åbb06 dû×-av`ܰÆkRÍ $·S6yžÞ.½½Œ™LÆHãÃZø—Ê” b.›¹ óŠõm2Î×Äú^í.çjpÿc•òŽG¡íš@q2À%‹ô¬ÿì©73($°çµwߨúœR¾š†+¸Ø‰ldêêžþƲà·»+)VS‚¤`ƒEÀãSMó.]‘JžF+^·kf ßÅÏ=ëÔ%†1Ê£$ä+‘ñ&–—¶ÌàéÈÇz~ß0àòjH àáxïQ²4e•‡>”ødh†*€Ø±Þ×(·å'«²´¹U†;x¢då{úë‘ÑÛ|‘Ä»)ÎÇ5×Mo*Z,ùX<ô(?tj@lI2Íd ùgûÅUãÒ¸­O,Eݼd P²Ãé]vžì/:9o”žžü~µ»g˜_3m¼€3ykúÒËòž‡‘RÆü öëL½Xâ¹ažb+•VÇQMï°ìyÀ¶zqSZÛ½Ýä6è>i˜(ú“UÐä)=ÅtÞ³ûo‹ì±sí@“i¥G¢ÙÇi#tŒ-šçõë»Í/Äq_ÆH @ÈõÜסÄ—Êx ¥EgÞX1€ÚÚ.<Ì $ì­Hÿµìɲ—¹•AØ?‡>¾••w·,Î\d·§°®Ž=:ÛK²aáŠòÇ©ük‡Ö¯ ò´`ðNN(*æíäbyÇEZžÒ[ˆcù$e'ï8&ªÁ›!á ÑӠмAsg*‰¤/v×z>‘ãm8¤Ã˹Ûû»˜øt?Ô{òåùMu¾Õ…­âÆï…cǵ&™kþ ñªÏa©Ü¬vñœ¬Ù$J½ˆXèú†œ·2ZÏx‡pügéÚ½óâ>‡/ˆ<5ÞžÔ-Ëw¨ûËùt÷¯•Æ¡v'ï[rëžÔSZgVÔ­îgÍš¼qãGµ-¶¥(8ÝëY$e‰â¥Pâÿe_éQm ·h0Ü}îzÕeµò°Ê~_a\zÉ"•Èú“í·8ÇžøôÍ+Ý[¬Lè IšÓÔ5‹? êwk0†æv· ‚6ÈV#©¯/3JÜ™þ4ÂÌÇ%‰'¹4X Ú†¥-üÅßžè*†sž(üh=ñL…8•˜Œ àu­/ùf3@ÿJµmŸs#ø˜ ¨IÜkOK+«+uwT_Ç­zY«,6û@EˆõÅZ“e¤?fŒä³nbGñSíÙDrÜ7EP«U >lû›Ÿ­H¶Q„1êkϼiª4º¸¶òB¼ýMwÓÝGmfò;U9¯<·ðÍÖ±}5ýû˜a•Ë*ßAMÎZÚ]ê·>M¤Lç¹{šíô_ Zi¬·D\\ŽFGʇØw5§kkŒE¬Kc°O½Y ì1Íd}Ǭ[CŒL‚Æ®Ç 'Oº:Pý*ŒdRž”‘¿cWb!±Y›¶¿Zµ ˜#¾hñ6í+ÆšuòŒ$¿#~uÝ• aÜf¸ÿˆ–ÆM" Äë€çÚº­9¼ÝÖRrZ1ü¨&lUIÔcWËÕ[ƒ…jã<(Æj‘l×£Û]æ&Š@HÆ y¾•ˆ¼yv¹ûè vêO¯Jl;P³{mVèDØ‹ï*•½áHU]7dœê5»MÁgxc\ÚÙÉç¯)±O\ÐE.^F•2ìøÏ¥MscqdŠð¹hòÒzUÈ-JBcilî­gU # ¯zäõ}j[­ˆÊŸ*à0ÅgE«4]T“ë]Möep>½Á¬)ü1p¤ùN¬=úЖڠ“«óéZöúƒ as#B¾²±óìjÌPjVËûËv`;ƒ@펽$@9ºk-j;™âù¾aŠòˆ5»iÜ¡©g¨ìpÑ¿ëE€î|_^@.æ+ʵu6ò$f0¬Ùú×¥iº¼dEsžxæ¸Ïi®ºÄR[í18À>†„ 8Û)h«³ØJ²‘×ÞŠ`;Âz”ZN­ ËÞI)Ë(èÕëóüaÒ–Ú%HŒ­‘”~TýkçÞüS‚›áCW×5vÖòê[û;u¶Êòñ“ÜzWžjº„Ó£I$¬w6'µ.%ÅÌV6"”…-ýÑV¼c§ÛØ\C¡-^÷4ͤ¸ ñRŽH9ªùÁïK»æÍ0&P¦R‡‘G–¡·)ã=é°ýâM8Ž=‰  › 4uã¸8Í4ȹÀüèá2v¨ùX†Íd‘€$°ŽÕU[®?CVmdx¥Ü§àƒH ÓÙI?.zTAœ¡ÁÈìk£Ê\®sŠ>Áöë_%Pׄnæ€9ÿ.e‰K!Øzî¼)lšn“öÇQçÜwþâóšÁÓ,佚;YWk+íeé€:ÕÍKTòô§ŽÓ0Aè‹òŠ©©ê©ë ŠÇÈÞQïUuLG?–:òÌ}M3DÍÕ“#!4j²y—òàp(‰¤¥¤ïÓñ¦øPõ†ëÒ€—ŠJQÈ÷ piHN1N;Ò`” ÊÊô®–ÕÒ]wA÷ïBQ\£åe Ž léÒ˜´û·—iª¾…¯h©w ¼pœÉ÷^ÿ…Wðïˆo4 C͆B±gçJ<;âmG@¹ÞVh{¦îŸJôO+Â^9^t6z‰á®`Âßí¯CõýiÕh÷pøºÍ5BSŽ0ÈéÇœð·©ô4ïÚùše–®ˆ’a¸8ÁÝÕIýEr¾Ñ5ÿë‚ÏÓßç†òPóÓØûõ)-bñ&‹y%WíIóùç(ä7Ó5 yw«$ÞVáך´ÚzÊw7 Wö‹›=bâ9ÁIBŒ=85Øé—âXÁ'Š 8?i o7Ÿ á[¯Ö¹<Øö¯\ñ6›ý¡dÆ?¾9µåW6ÒÚ\”•0AéM«¥´{ö©ØÌ@Æ:×]f¥Q¹JíÚzþuÇé‘´“.Þd2)ïëúW]¯5ÌL„=C@vø·±’láÀÝžjî×H%Þ?{»[‚G¦+-®~Îì¥ï*Pgžâµ¡k‡s;»Æƒ ÃiƒÞ[âM=l¯œÆ#“çT\ü¼ô¬Äož3ê+½×í¢Ôà”}šF»è…=}1\ÖŒ*º•*Ø#)e{5zGÂ+Q.·}tGú˜BøÿëW™–Æð|×­ümõy}Z5ý '°‹"•$g>íHü¾E8€Ôƒ¯Ýl„¢Ÿ›ç7ùäÏÞÎ+{Å7î—ì‘·"¹y$gqÉ,2MRFÎ0‘¨ÇAWD|T0p\QÇÍÒ€+2ñO‚S€ƒÈ=idÇåPg žÔëÞÖÖîÑa•`0sÞ¼âׄ?áñ|¯x°¿ÌðÑIûËøÐ×w êmazœ)<×oã_EãÏÉoS}ó­[ý°:}â’ÑòwåHy©¦†Kyä†hÙ$F*èÃHê EVqIÚ—½…QIKøPÖQŸjZO¥!¥ü)¤ó@Œ0néN‰È˜7½D=iU¶œÐÌÃí6eGQÊýj®¡$ ÊúU«I2¸æ³ï!0ÎÜpÜŠ@oÛ_Ç/FCYZ•×xH#Ž+=XŽ™Í&˜–eXÇu®·ÀR ¯¬²[ļ_A\Êå|±ÐúWE¥\5„cË%[©"“Õ|_à‹]rɯl‚­Äkœâ•ã/ 0³®ÖÒ èkÔ´/Ë*ËwVà†¯4Ö¥ˆë·¦JÄÐæ’’1ÛÞ® ,`g‚jˆá¸äUßwŽ0¸ySÛŠÑѭ⹺n„m¬Y^1+™­¿ ¨k©X ah–ö+ý¡,{5 ‹·+ÓWIu/32Ö& ›.œÆh<ý`)´ß—;åÝ^@¬ó÷ë·Ñ4a{â-&SåGžÿÏó ¯PˆÚ[ÃmÔãsãÔÕKH‹?LÔÕýU¼Û©¤=3YâBÐù)ïŸéRL«yyçI–‚#ˆôcýïð«'26§ÅlJÐzUèaHÇ#šª–ØÓ¶ŒÕòj…ã'¿jš°‹ž•®Õçã(E<Ðã’(ã5Êë~3´Ó¤0Eûûî/EúšÉÓµëÍFç|̺:S°ÁäÔ¨8ª–nd@sÅ_UR+ÅÇw…/æ´¼9r&ðõ¡ÿ¦b³¼Wï ^ýʛ£´aÐ¥Õ$dœU9ˆ;ªÓ÷ªÌ¹é@E¿îþ )ÇÞŠ»‘Ã\EÑòRâ6“êi[V·NÔ¯o!˜ÿS^w.mí‡eˆ~d“]ÄóGK¿—9̘_¦+ϧlÅû£ô¡¹á¸öEsrÝÀ5•3ï™ßÔÖ¶žå|/pË×q±¨):KëAS†¤iXP@¦õ¥à8àÒƒÅ7S‡9âÎ>LÕˆ. é³/÷˜PÈ2†ŸgMkp gfò4ÒYxe¯,’K[ëw”Œ˜Ø‘ŠÂÞ#µŸÎ·„£¡‰ÁÏø×6³É»ãwCœeN+jÓÅ:Å® \™ìã4êÞ×õè,E¶¯dJ±ÚÑÈ:ýGjô¯Ãn ^Y™"âkwço¸¯ð×îµLNwQá‡ÍÃW®hzñ¿\¸Xî‡'†¨`yŸÆ ÿex™u{eÅ®¤ 0Q÷¿1ƒù×;¢Ü2Ä<×Ð>#Ñ-¼_áyô÷Kð7÷$ôúò ;ÁóŽ$¹Eš3‡P„àþbš`>Ø–RÎk‰ñVœ‰q UmÇœW£ë)–Í ¸ ÷¢ÚUÓ?ãQ¾“½bò"í»‹*ñó_¨¦“ÙĤ£F72¢ºDU7«¼cåíØÖMõ›hºža»çjõ…åÅÄ’Mœ1sŽÔÀ×{r/Y !÷gŸÆ·a#í[[# ‘ÜW5læ6PFç“![wnÕ¯oæÆRb™œ £Œbk0 ™e9<Ž ×â "ûTÈîß4ŠëÐûõ×j×÷²£LìèW ʵÃë:Ì÷,韗éùP€Çãs{ŠöƒŒ­¥jƒø„¨JñÅûÃŽ«^ÃðpÇo¢j—3•Tódž¸({é›B©cÐV^¡~"°qÅC©xŽÊ8Û}ÂÂ9&¹;½fKë…X¢a ©#­$€ÁÖ&iõçiE;pÞ³S r)nÎèÚç :æ¶ Ù*c æ¹ã?8Áõ§+K1¹üè{Ù_Nº !&ûý 2È3Ö¨j«u}bÑ–É0úÖ.›©º7‘1Ä€÷ï@ŒrF+Ò|®à y[‘Ò¼¦ €à`æµì/^Úd‘‚)04>4|=YQüY¤Ež3}¿ôÐçù׃‘__xgÄjvÆÖãkn]¬È ׄ|Uøu'„uF¿°›Fº|ÆG>Kà>Þ”âúæÇ­(Æ 5@%¸¤í@ÒŽÔ J 6—½&9 €­ŠÝÿ„Zý¼.šØØmüÕ‹f~l±À?Jë øR÷~ºº·šs¨[Fd(TyoŽJŽÿ+ÁY¿~5jî=¾qó§#é]@Œ.õvK•ÿžÉÈ>žõŒôÍM0ǧ.éÜ™a‘ã€}óEÀóU·Ç'­”À®Ðb6dSÀÏÒ£ŽiIǘØôÍvú^ÞŽå¦1¼ƒ$mÎ}«‰™ÉP *±yeÛ÷Øþ5'½JÇ+žõcwµ0$ˆdóV¯Z8n•=Es /´÷ÍvžðÞ±«¬òØé×FxÂçêx®nx£{à ¯YðÄXô?ÛØ;*˜ò)02o´[Í2O"úŠtä‚søW¬.ˬŽãÖº?xÙõ=^êxÀ‘NÔRk›ÖLŸiL…ÁPO<Ò@dg÷•ì>ˆ.¡˜Z¬@ýMxñQæ¯iðÂø@ —i8<Ÿ¥ nŽíùõªðm9ÇJŠæG“!;÷§Ã *ikÏ @ñ&{ÕP¡sž´Öœ("€4|ÜŽ´¦@{ÖÖµoii$ rküZon<»|¤=Üõ?J`u÷z¬ÊFrÝ”W1q¬ÝÞNcxš8³€婉*É y$欺*·SÛ4—¨h°Þt'ó×ëTôæ—& ~VSÈ­ôBpÜ{S/4{m@’FŠAüIÖ€: 2â6B‘Zé*tÜ3^_pº®ˆû­'71̧"£·ñ¦¡³Mb{r1E€ô˜Ç†î̤ù{~`½Hö©<3 [®®>EÎp;kʵ_ꚥ»[3,P7TA×êi4¯jÚXTI|È—øf‹í,™¨Yx#¥qšwÄ{Y@[Ø&þòò+£·ñ—z¹†î"} Á¤+®ŠôÙIÆXŠí±Æ}«‹ñD»±œí×Ou©AmgILòM0.Ʀt‘cå”VDp´ò9ÉÜ?ét«²é-råZB3Œt¬RÂGfÇ~A¤,0ܧå=ª\e{U¢˜;ãëÜTRaÈÁ  Ná-biŒÞ°ôíYZàÊ_‚jÝî™-ç¹År©½Þeú¤€ô϶DÓ ƒVø:ýì{^y¥ê+ž\ìJg©5Ò5í½¼ašEÛÛiÍ~+ÎMRº¿kÉM¥»áúÇʹ›Ýyä_.U÷5>™©Á„/×½ :ë?ôDQ Æ(Õ´ë}z %Ç2ýÖª„jãåjº’æ€9™|+¬Ã!HŠH˜63Euëq"®{Ñ@A’OZµùví!Î[Uᤔ*Œšžâ@Ïå¯Ý^*€„*\N”ÔlU’»†(ž3Î)>½)ï…l 3“ÀÅ&3N“ˆO½(½¢Ún²šy,ÌÑ´6:晋»·­]Ãz†¹2¥´XRp]º ]VÌ­Äq,{Jì4¿7„a[!§‰gÀ;·qH áÍ·–×ZŠymÔÆœŠ«âO†SèúrßYܸÞÂa–¶æñ®»«Å¶8`€uäÕÏ kÚžªF¨ÒMjã »r¾)j40z†E=ÎðˆÎÄôs_L]hþ×"óe³·lr i®#[´ð·‡ÜÏ ÛÆÃ²Œš.9¦Á=¯‡ \DQÝó´÷®î6X!b¸:þ!¿úõßÞëßèÂæ5ÂnÓ5Çê6Æ-:AŽ!»aŸfÊšΜ3á-AA*b±û{Võ’mð%Ûž7Ý(€¬x «|çÒžzT ~|úÕ€2´À`àâÚš4ðh¾ÔŠy"Ï4ÕûÆ€J´†­Ž(Ì8©t™|›¦VYCøÓ#ŠŽ"c›wLiùSýrc•52¼~5ví6ß»»*‡šŸ»™”úÐ…´¯ ÂXܤªr¤W¦xkÅÆxÕ\”¹N¿_Q^^£"§ŽV‚U—s §9SƒŠúŸÂÞ#Qu›løä7õé|E¤4r˪Y/'þ>#ÿÚÖ¼«Áú×ÚàŠhÛlñœƒžr+Û4ýI5 D¸\nÆ$O~õ@1ô;„™2+Ç ‡um?]‚ u(ŠãiùsêG©ʶÞËû+T?øöŸæý“ÜUÿi)¯xBêבW͈ú:ò?Ãñ *ø‘¤'ögö¤ /•(Ú}U…pZæHBœó(üñ^³ªF5…mqqÕaNr8¯µóa@lE»€þuH—ìq¡Ú¯Í×äÖ¦˜ímnb˜Ãg5’Ûïä‹oÉ;)éÂàSìžt™àg¡òß¹”¹¨À'³Œ0ŒÈIëÜ óEzØÙ ¹# z|r Ÿ1Æ@@zW™ø²êIõ£º5RhÆ}è@`)û‡ð¯Fðå¼–¿®ncq¶i›x¡è?­yÊŸ•}z宓ªOð÷M·²†3±™$NŒNN4Ø øqö)a¾7¢9¥GZPX¨ö®’ïXÑbvÁÜÌȳíä±ðöö0H–Ó*0€ 3cž~µ“¦ëWšÃ\[+Ddˆó ÛsÎigQÔ­¦·v_\W= Änšéµ0é»Ô+àG¯AùW-Åpó: GŒŒZµÆ3šU'°ý*(dLïŽ qV’3ç‚yV~TXÓs\þ¹¦2¿Úá?Å´~µÑÈ6: êIcOd¤}h™Ó/ãÉÉÚ㎕ÐÛË¿¡§éz`‚Ç]#\°&=˜(Õ´{¯]ªÉ–·—˜¤õþô«¦êX\¤‘“ÁÍz½Æâï˧_ƲÃ:l‘üõ¯¶]G5ÒøT“Nº\ã4šÈüsàû¯xŽm:l¼ óÛLGúÄíøŽ†¹ŽõõgŒ<;gñÃ&Ô²¥ü#}¬Çø[Ðûõòþ¥§]é:„ö7Ð47¶×FþµRw—NÔfŠM´Àm'­;÷£ÌsZ:šú¦§IŒ|Ò·¢Š¡ßêÒ/5Ôãi»›ƒþÂÿõé~îswce¢ØÀVÖÞu¸¸”®í*Z¼Þ0Ô„3é°ÜÅRä1Ç#Ôf©ÝêP¥D -T•Ê/SX–>aR€aɤi£ëš~޶»-Ì›ÏÎíÉaÜŠÁø­'…nÖÞûF ¦ò¤*dn\u#×8«^×4Ùõ‹k{«(¤¾O1ÿ‡ÓÂkZWصËÈLÞ`Y™VPx<ñB#Ì2¹·0è}jÅœêѾ׊I­öî ¡eQž:0ÿŽ6$Ž4Àô S¹¢“Ëuoî/5ÀøŽßìÚõҺ͸­tú,WñÎ’Çiòt,MfxÞÖHµD¹hZ1*c ê(@s!¸Å"õ§©¦à HNH¨c#8â¥ÝÈ"€7tæ³6ò%ʱb8Å.—¨üò ýTsŠ£k8…K‘žÕ·tc»°?e„ù›SH 0ÙCh×Ip¯$Óa!2Üöª— u©+ùÄ€€ö«pè“=ºHð°$ÙŠ­&—4&wEÂF¹$@4; uMf kXIJ1Îë^—{ªK§øm,Ã,aY„Š˜ÆA5çº{}Í¥ïô8­å‡íZÚš<ºœõõ¤¥Ž£ÆAüjÿÚ•‡¹)tkÝ6ÓíN³Á€Ø6(ƒP¸–Ñ'FR¥‚¶Jç½t³]$ åõÍzkx_È>q“Ú´ü7}»P¹´Ô#_=¹‰ˆíY>'Òæ{å¶ 4Ž1Š|³Ü]¹–yòzž•4.b ©äVޱ`4ã ¸_¸Ÿ3z±¬øÁn07´ÝN[lÍ€¥ºcÚ·-!¸™Æ6É¿§9®$[Í#áT³0+Ѽ=i$VP;¸i£m¢ºÞ¤ÿ«Om)„sýâ95°p¸â¡–Ù™3´àÒ(X¼Š$d¨%Ñmç't¸ô*+t:ª€ÃTa×ÊF q÷¾±œ°ϪœV¾ ”“öi²Gð°¯TQm¬TÛÆ¤°àæÀò9|'©ÄßêÕ‡±¦ÇáPœÇµŠõ³Äç9枑ĩ4\)ºÐüE'—æG,¡Ê7ä è<;£jÒ^‹½R9X¯£Ú»Ñ`nQS#¶}\ a=™ˆ«*öȬ¹!19õ­^–m£plèiˆevl’i"‘ó¯n¢«ÍÊ–­ò@É8µS ì|ûb€<§ÅÁ×T rqXæ^X×gã¦ÄЧ–<ä×MÛr~•H\Ú¯ÛÛ‡*¼ŸÆ¡Ê@,}EiAvºõÏj`lIá’ö«$@çÅs·Vm1B ‘^£¥Ö1ñÚªkZ$w°3*0 MÀóÛ+ë›y±Êú×Ogªι‹Ûy-e1ºÊ:–)¤Œ©Í0;e¼mÂÉ©Míù¨ ´híl]¶îš_•GR*)ldµˆIqò;òõ­Èc³ÐÓιtžó"BÖåä·×-4Ç9è=(4ç½8‡ãšj8¥Š2iÂW XÔpG´ŒÈJ±Aó!éš©">ò̦ñé^‹áPÁ÷Go;ò=ÍyØšët}[QÓ¬6Ì¢3Ô0Í Z¥“ÜÚÇ©HŠ¡8 ðEaïk‹=‰'8­;ÛËëô1Ï *yÂŒ Ö}¢ƒÜx GÍ·Ý'é:L±0Z–Ï5æV—ÖÑ–t\v&¶¢ñæ™k >kIü"µqÉ6Ž•æ?ü.d·iàA’sPKñzP­µ£¹ W5«|LÔµHÞ#k äŠI03îã{ +Lä”çµ3Ú‹ÿÏ0ë$ÿð$â¨ÛÝ>­e(pL‰ÐŠÕð¼Šú|–ruùÔ¨ÍPòþC÷î2k•?t×g©Eöo[DOIÈýk#ƒŠ†AÿëÕ´\UAÖ¬ÀÜS\S—§H¸jÖ€øSŒÓÏJbãq­JŽý1R/N)¬21H²)yȨã;N=ên 0%šmðÂHù“ŒûU;¥Úêã½NP†´¬’&ÇN® L¾{i—æ;Ojî¬îÒâ1"»Z€8­fÆ=7ÀÒiѨPK ÷‰¯¹‚HF¡qÈÇC^õâ¨^[è­ŠŸ&Oœ{ú×k:pÅsr…Ü@“T€á¬o¦0”;£n=³[ n,Kœž*m#BŠòãΔ€»¾qÈçµG­»YY4ñH +6A÷¦î Qêv÷B-²°ßèqÒ¼ï_›Î×f”I½XäWfñ,ødc·Nz×;,ÆYw±É&šSAÒdÖõ‹}:3†šP3è;×¹jš~«ek§éz<ˆ"‚1Žç^%ámUt_Úß?Ýþo¡à×¹ßΚ¾žM÷–ÅÃnì«ýi08í_KÓí.Šê×2Þ;®æòÛbçÓב£ëVv#,íQ-ß÷,¨2H=ÉîkGW³ÑZúS{{z쀀=j—…eÒ“Å6±-¸Û#m¶~ŸÊ€:;0×6ÚÅ«ŒK œûý+˜¸ŒÚêÈ8IPþuÙßÓ¼e$¯òÛ]*CÛ‘Årú¼ ílÙʱR5Û¥HÝߊ֌‰3Ø ¥2€–ÖàwÖŒ˜ŠnÀPUùî¤a÷Tb¬ÓÞ™e"ÉêÜš×Ò€/épl5(ýaAÿŠ_Š:§Ù4•XðZ) LzåYô©´fÛï¡Døõs_\F¢<ÿ¬º ÿ|Äõ¤·+LÔ£ž%’&Êô žA÷®ŽÖèò+É,¯e±˜Iú¯c]¶•«Eqt?QÜS°«¢k¾@Ûèk[VÒ¼;â¥IuM:ÞæUD¤a€ôÈæ¼Î+ÂW5±e«¼a~sJVbƒ^¿]ÖësjßôÊlÈæ³¥ø ¥6DZ¥âzeTÿJÛ³ñ8ˆ€îqë[x®Í†Z`½`yÓþÏì[÷zÛcÞþ½@ß¾Ìñ­Æ¨ì¬Ø2,x ?Zõxü[`<õçÞ«ê9ÓmcÃ:ÈÇøE`yf½ðbÏÃú3j3ê8,ŒFzƲšòu±ŠÉNØ!Mˆˆ1Åuž-ñ­Ž³f–qGÌm¸|Ç ^}u¬ÛÀ¬»”­5p.¥5œH±:É`€­Á¬‰¯ÚáþaƒT§½óÙä-ì Wѧ8}Ýò)ìþ¾Ð´ß›Ë½' !ŽK¢A“yqÔ-y|ÒyÆT|熲¢Xœ¥ÔG늺o"ÎÒ1žþô©Á%ÅלJñ™áe¿²ÜÇ(úÖô–æk†¤É´ý}kFÌGg4p¯uæ€9fÓáÒ-dÉÜëÔæºßÝBöh ‚q\wŒn 5èïú æí5Û«DLT,·I©CnF÷©#Õ!œ`°ã±øžêC—”7Ö¯ÛëîØŽê,©Kq‹µXz¥t® d_¦y5ÈÚ_Ë&Õ·g&åÞÒF¾¥š¯!?42ìißÚ œÁ'Ƨ:•Œ_ë.àϱÍAqâ­Ñ ’ä9€¦þG'¶GLŠê £ÈïXÒüFÑ¡,#ŽY ß,̘M³õ¢Àtñk1"vÛèM\KûiÆ#”7ãŠó»ÿÛÌ“a¸ž¥Î1T­¼E%ÌëåZª“èæ‹éS߯§c>>”¶¬ÓË”“wÏzçíÚR´j3ÎIÍtºvÁ[©ü¨éU ÀãÔÕK—[hv^g§5x(|Õ[åY!eÏËŽiâºîªú¾®óH6¢ª¾‚©!Ãü«“ëSê .¯t"(sŒŠ0€•X¬ Ò(ÝÉëŽÕ¤ìèsך XRùv«öòÆÑ(7xóHBÑ=ŒdñZe¹}7Sk=<2Den€‡ˆn^ØGE+ñœt¤C,—¨«n¢Ë9B u'åÆ;WMkjnl16ç`9$w¬‰ôç¶V”·îóŽÔÌj³}±°£âŠÚ–Á§}ë’¢˜¡lä’Xžôä“o`~µô y¦é ڬà÷ªpÄÄ‚¡¼Œ8ü©ìäàSð1ŒT¢Âb2$_Ê¢šÚíSiJXcO0ü¢´#aŒ+ Kv’ü½Ä÷QZöÈËnƒæ  *q2g 5•©ÛÞ¥Ù‚9Ê¿jÒXÈäf¯j„'@šÏìåçW߃µféš«¯™tÍ3zWu1£C¤Ín 1É·(®kŒ—Q»liX˜URwI$ûÑ`[4ÚNèÀ¦ï‡u³¸) Ìrps[²Øë1¼g1»ƒúÿõë‹S´ç¥mØÝ­Â,nø}Óš@vž*‡Ëð¨è³^{^‘â/ô #ÿ°¬kÎ03B«㱩baœzÔr¯ÌiàñL Ò Ê Š¥„‡B‡¿"˜F(´ƒÒ—½èëJÃ"š½iøÈ¤b6½L=sQʸæ•V˜ 5¨Y¤Oáa‘ON:SfùU_û§éH c÷Scž¸­:"î9cÍdÜX8ïV!o”0¦{y2Gj÷FÆNO¥Qðž¥óÙ²súÖÞ¥$šoÙ×#ÔÕMïì·ËèM+ô›sçB ž@®“LÔÙ•Á%AÁç:.¡º4lðEvš|Ûþ`2§‚*@íõ dÖ4­ñާ΄z÷xÿ‹u%³·û0nlW­h’´?!?!é\/Œ´h,u¹F ¼ì{þ¿Î’ŽÐ5!’yГ ®Ò:dSõm6+kucF†Aò r¹¢uò—‘òôúTø6æÚwÃÁóÂÙäS̵Ý2[i䔘ÊîÁÙ X½º÷«7Wó]cÌ+Çp1Ÿ­UùvŽjÀ”7~•ÖøKÅÒØ\&Ÿ~%¸°›÷e–^x#ü+ŽÏ5Øø NO¶kÜG˜må™ÁcùúÒ`z©§hv’É$z%åÃIàäˆÈèNjµ®Ÿ“®è+%¤ÎÌ|ÕŒp .F}úWA¨ÞÅ5ÓÝ£–†IcW<qšÈñ>ûmNÞñ³ˆïË´ @&»pÒÌÐܘÎÂþÝU¿¥UÔ”O,·ÞhÀo¨«þ(l¯qÜ»@qê§k],–¨…²ññõ¨"v¤ÇøPb¬]~ñÖМšŠÇ²Hz“V LÊÎÚ™FÔÀ)Hšv8â¸úRGMLY^0îc_üz¹Œ­³Z²‹=c2cðúWedBh÷„›ÌòÉ®ã$›üUh¿Ý²Cù’i­ÀóšžÒæKyCÆåNj¹§&7}j€îtÍaGšáXuÖ‹kö1><Ô'ãšóæ“#€qLÞGE¥`= OX¨Ï˜OÐVdÞ-·çnóí\c–=zTgX²Ocý\lk>ÝË (5…ÊŽ:Ó°d¾¹”Ò0°ªä’rI¤ J·l¤.U»Ó¤q'žzÔp‚AúT¡YÈëÚ€«7 U•XÔýÐÒªCÄœö«Æzb€'2…JÌÞõžzÒÆYNTtï@‡EÇÚ* LòOZôËtÆ›>Š6àjà4À½»â»Ë6cg"g,PŒþ xL£¸ÇñEàS®Û‰êçó¦•@L#8?•MQ‘ÅWW`¥AÀ=©èÄ0ñ@"£ìÀw©aV¥Çµ  aÔÕñj‚5Ï5#嫤|‚€(”JTô5nÎ!äÜ*˜.Z®É™»Õ«!™ B9 í®<«—äŒàŠëeo·i~a9;0kƒ¸r¥Xrz5tú5à’Ä¡<ÐÒ'K½{Kǵ¾Lü¦·nŠ­³‘÷±Årº•´ªvزÈ­+kÖ¹³A÷—nµ0,è~#_0Û^¬§÷räk¨2,—ip@n2;׺ ÷7xC…<äö­[ûæðÌvöœÜ)}çŸÃÒ|bÂKعìk–d +£º½Óµ¡AÚsÀñ«iàöÜÄŽ¹ )Řöò¥ýâôÉ®ÊmÆÊ#%Áȵw¨ÙÀXYÂôËtã@E® v õ¨ÖêèŒ X­+Ï%Ëþñ¹ìAQìÚy¦¡çaÌÏô“Ê ~bOÖ˜Þ”;šw’¿Ý¥0)“žy¥ËôÍG6åŒ @jÞÍtÆKµ¶Ž5ÜÎÃ?€Üõ­-4G?ÛlZà· Uöí ŸÂw?Ú3ye^]‡¯¨þ•ß&E –YP:d âôÏÚiVÞU†¨êw䟩êkN?¼‘î"(›ÐäÔ¸÷“Æ9°öH5Ÿs¨‰°BÕ_ŠË›ÅR6GÚö#ÿÇÄúíÓy·ÒyC¥‹ÈkrùÚÔÎShÎ1ëP6Ã#-Ú·î¼1¾ì¨ºÈÎK2Ö¶™á‹;g 3 Ûß§åNàrÚf¨dAG÷»m'Â1@¡îä?÷GA] ´ˆ(P:9R½C~T®mÞ’“[ù(vÛj…¦˜-n6HÍ,ŸÂXp+pÈÊ~`Hª:½ÜPiï HËŸZl›í7ÄOßG­`Úêg–Î|œôû-i¯RhðëÞ ¾—Q†æÓ×Þ­H ã¡ëYÊyÏqW —rí8ÿ aëMíRȸ&¢Ïjp©öÅF"“ùÒAÕu;ƒVÈÏZÔÓš`IÏz”®ä`Fr:T§©˜“íëŠ@eº²»+<‚:UˆOî«@\ LL·†a+&0sY±&1L äê*‰&92 æ¬nhÛŽ•üÌr9 ûðx3|Ã¥z6…¨0ÙÅx.›vö³¹Á=«Ñ|?¬‡¹DfÚÝÁ©h~Ð¥Žá6çžÕÎüG‘CØBI ÄãÓŠ‹CÔ 2²°ÏR*¿µ+K½Zydˆ' ïSÔ7Ö5o²•GÁu?pšöº÷Ëä¡Â÷Å'Õ$¼Ö®‚2ùaʾ‚¹ò ÍZ@'<ÑÚ”Ð0z׺XxsìðüJ’Vóe÷.§üExrŒ1Þ¾ñ;Ëká5"e1ìBŒ~¢¥É äkK›lsŽdþGõ§®2êZÌ9 Fæ³´éâ¾»I€Â][¼_Fpý2]ë}¥I÷Œg`>ÜÐލá´ë;ƒþ®X„RØö5ÇI ÃpÃÓµuFêt•¶›ˆÝB“ýÓڹɒX® †êåìh@KápEhÁÈâ³ã}¹Y¢!‡ñ'øUÛIc'hphØcŒÓ±‘Æ(Û•" ŽÉ¹sò·Që\×ÅØD·Z6¦€ížÓË?U?ýzßÝ†â©øñPð2éóo'ý–àÿJh þ e° =NF)¿vNj€•_äÛÜP_ÒšO'#èi§Ÿs@6i†—îþ‡'<Ðt£µð¢€”GJ>´ôp§…ë@&î¬ùö©ƒ’éÆj®æ=p¥JŸ/4±%`zŠtï÷qÚ›'úâ;Hßêþ†€y©¢Ø ÷ïP!ãšž/¼1@ŽŠjŒä»K2v‘žvœ×£,Tž{ñ]=¬åcšAÈT$ŸN*@ñëÎ/gÇüôoæj0§#Ští¾yûÌOëN`LHj€*hÉ }j,sÔV–“ù±ß"€-¨ÀŸŽ•±©éFD>P ±¬¦ @O ¶ßtUh‡**ÑP\¤~=š·ö„xû½ÅFF'J±mòÜÇŸï ǽO.òDíÎ*æ˜í”o¸ÈªºúùWă֮iêÒhë´ÊÙ#ÔP¬ÃyÖ²d+ ­bèðËm«Ii*19Ö¶`_*?7:ŒÕ»AÅÒÞ¢å¶ìJ@héváYÇËÔ}+εëÇ¿Ö.&,vï*£Ð•鲆5@Féxâ¸{_5ÕÔïpÅ18ž´ 9 8öÅ]·Öõ;h„PÞÌ©è£Õ"Ž Jx¢"6MTè*€½quqtA¸žIO«±5884 ü¢Œdc&>e4ôa"àõ¡pÚzÒ(Ù(ààÓÀÅ3ÞÀé@Ó‡ÔÐ9íOó ¯Mli‘nˆžqY@üVÆÑ”tŒ‡ íH $ƒ#©§=¨Û÷$nñ’¬ SÞœgU?xïHãˆ1Ÿr8«Vói7&IôíTÚé3÷©bœÈøQ¸ç°¦øµ”kƒö”òϸàÖÌÁ6Hö¬+ë%¸„³Ž¢°ËPµ•Z5×wðäÒÔ­åPÍ]Yׂ pÚ~§zî±=“ô`y®žÖ6‘w23þÑ  U=GÏëš;_IÂBçœVâ,©üAǽ%ÐÀcÚUˆê)Œ4kk(ó³rcï Õh­òÞH×”å1QXÍ-Žªö·Í$Šçåvn1WåQe|¯…ãsØô¦xZÔG¶kq¼pr¼ÑRÞZ#ÜGÚg4P’ô$?knüiýÅP¯Z‘¥@<OÃÒ€.Ç(=N*Ì/†Á<ÎIØq´­J—Š)~fÚ¤8úÖkœ·Z•çܽpj·Rhí…ב6Ö?+q]5±æÎc\f0+¡°œÉd 6Jõ  Ú´ØÓ\g¯ÄJ†9 þ5Ôj—´ü æ®y ž¢„RöëIL¢“ñ¥íÖ€5´[st—‘3£g»gåBHÚ& ö8>Õz%0øjI”e¹ ‘è£?ÌÒ<ëxžCþµ}ý«ƒ¡©dŒJ™EG%¿ñ!â„‘”á¸4X‚¬{zŠz6ӟάIÌ21¸UB lCP‚0tÇÕ^Bc|Á¨ã©ëÅX!.#Á8ô4ˆÀŠ‘MT!íÏÍÈõf'W\†€%ÎAÉ5 æ‚)öâ­AÏ£USíSÄH9¥AwC'˜™Úx8íP*\¯>¢¶[lªs­ÔViˆ$¥KÇJ`W;ºS h¼[ùB þt¢ËÌÀ#Žæ€(ÛÜIi7›Ã/CZº<ó½ÉfclîY×ÓŠ»£øJ]Rä'Ú"Š,àÈüãð®ö…Ù¤w yæÛžCGògó¥p(èÚÅýÅê[ÛÌóÊ:ù ò¯¹'¥tšÅ´¯¥O$Ž Ñ§-ëZ–:~¤Y [Hã¶”õËn2sëYºø6ö[äIÁçô©Áîf㫈֖¹kž£"BÙCÈô¬Þ½êÀ1ÛÒŒRQžù  ©æ]Áþ)~µô׋ms¢¡Qþ¦ÿ÷Î?¦kæ­Öl²åâ?ýWÖZœ 4iòŒ¬ô Š–Œiñ}•îáFæ ÖxÿÜn Y¸”C¨ÛjQqµ¶È?C{Út0^‘›­æª*Î¥o‹ï­þx$P%±õ Õ6FîS›y¾u>„Öz\¤°yC*>랢•®•ìDE Óګdž>Ôz4h€Î%‹øXugÈ‚a Ÿ^†¨ÁæZ¶èþhÿŠ3Zp§|g ÐR b‰É_îµ\´ pÛ ˆŸÑº~tÅ⥎ çž™ê)£i5‹…6îû¬9ñ¦Y¬ZŽ‘ªÙÜclÖlÔWg‹­¤5¬wŸŒIÕZ¸ á›M¹–Ö@QѰÃÞ€µuìgŠÑ'eù½D½iC¶qL*—y 6)œRƒÏõ ]Óî¢^Tr9F§s@×Ü VG|Ö c³Åtï*Ýi¥ò3ŽG¥ròq#zLœÒfŽÔP -6—ñ âÃK[¿µ¿YrÊOsÒ¹I­f²˜ŒGb®Ã©LšZ4•’ C²ýF3ôþÇŠêÏYô /jÑ1ù±È \ÜrËLãÓµi²äRE‘œö¨#½Fá†ÓR™£U$|ßJ¶„¥VºŒ¹Êr¦±°Ôµ ZÝh8Ít'…Ziž{Õr‰È(Üf€9«h&‘Ö1 rz`+¢²ÑuŸ"1Þ[8î1éPx®àÙi j[÷ËP7áäkßBßíî&º}uN¦Øå³Yàóu×~¡#&µ|XÛt[Ò|~´ÀóM'9úÒÿ û˜;íLåXŒpjFÈþ´Ó‚:ÐsNŠm(£ â”ç°æÉ¥ö !Ïœ ¯©ƒŽ•*œŒqH/ŸÔi zÓ×ð  í'òd¾é­¨¥óÇO¥sÝëgL•LeY€#õ  °†'µt#íA˜t‘l#fàŒ×K¤Å´ç€ÝÄdgh¦Œ“”\Õ„*)E ¯dJR£¾Ñô+ÐÔ;g9`Xz—§LU[»Æ¶BÑÍÛ<ÔwÏ4HJDî1Ø×;m«@o¾ÏwçÂ7ueëL´$—6ñ™T<œU/Ë,:;ˆSscŠÕY¡+yŠ´“ŠÎ×äΘÛ0Ùô¤5c§ÛÉj¯)P瓚*²=À\$q‘ïš)çdŽp)½iqëJ\UØ y.5RXžÙª¡³X@Æ+’†F†E• § ×Eö¨îb£u0ô4€ÃÔ,~É!)óFyÒ©Šèä "<æ°î­ZÝò£ä4À„RÓ.pzІ(È¥%!ç•P Ð÷§c¶i@¸qÈÍy§c­ÜS€ù ð9€Pò1ÒçœP9Î)@ë@ 1¡ê)@ 0,p¼§3îx­K]%昖#œt™  2™Þ ̱¸ÜÏ +·Ò ÂñƒÊÿ2íÆÓƒ\Í„–ö·m`°ž}ëÒaKKpìÞh,f;jX÷ FË×$.xT‘ÞŦÉ­½­º6G¨õ«‡IÒîÌ“[ê-7÷•úŠŽÃGŽâÅâ¼Wu9òä^ Òv-)5B%·‘fÚ7•y ŽÆ²„Z™Ô’Å~Õ! Vü{è´ˆE½¼Eq<'HÇ;q[mªØè¢B8,1ÈíŸZç¬|E¨Æ>Íy£Ü‡æ esê+¤Óìã’0\Èe~J±=Ó#_ÜC<ÍÛ (¬K¯j‚- Šë÷Ó¾Õom Mpꊼ–c\ÿˆ¼oes Ë¥éŠd–Cµæ#€;ãÖ¼¾÷T¾ÔµÕÌ’ŸF<Â¥Ó\+ŽqÅ;ZúÊ[eó|…°ªÂ›¤Á­]\Jm£c÷U±J¡ üÊá'ÐÓg Ó JQóã>Õ}ÔŽƒš¡'S@ £©(Å(£”´RbŠ^ÔcëG4PãÿãW b8ü g ± Ô {PÙ9æ¶tx% æÉ\õˆ¬q]&„¼¥›ƒÈ¤}¿LŽ Ô¹tÁ$/¸¬aö€/Ñ€Å^Ô×Êð‚N†?:ãØzSw¡O Rý) ç 4ÀMµzÏ…ç¥SÕ"É" .1@¯†¯Í½ÁŒŸ”Œ `û×LGW5ËÛjÃ(r£#Ò·-/RâïÉ€½Ë5³q&?„S\„AÍIn³Œs@ï™a\d/ãSxcmÆ«•9òбÅs:´ÍqxÛX•u®ŸÀÐyVw×l;méÍ%š ¿ÝÝ0ÊÄN>½+©V)fø5sÚL{mnfþü„×Ak^G|‘è).…d»Ú]¸Œ –5Äø¶ÿíš›€~PxúW­ÝÅ¡èf Jã¯#¸”Ï;¹îh@w!)õ×ÑA¨|`äh‡!Ÿ?­løvÛû7ÂHYpÒåÍs¾-7‡à9Æçüèê:XÇïTZmĮ ݹÅ4Ó_–¥€3ŠP*NÆ”P…(âš8PÒž§ÎôáŸZyïNíÖ¡SÍJ§=zÒݻԖïåʼÔ]9¤t ×N´dl„`ŒŒWO¥Ø5ÈA"Výá;k¬ÐËÆpM :HTàsR´y@¹¬~• súÕêiÖŽîJñØf¹ ˆÔÚxÚòFå‰P¨+¤×È›ȪxÏzÎÓîcµ.²®Õª¨Œ‘QK£X݆óa Þ³&×ía„òÇÐqZ~¥%ÊœZº¦>ùéH?Æ!,Á$Š7—u>ïQŠmÖäoÀÉÍRñ¬‚MI?usÍfiÑÚ2eÌ€p ëL ¨ZD‰V(èy»š)°ÜËTíEy¶0qÔÑì)N1Ç&‘AÁëT†•%ðßÒ<úu®Š "Œ*Ä}ë[Ãv¦1f‰"¶Ì,W8 øTÜXh¬ËòÂÙõ©ÿái£)$ Ü×Q¿†=…]krS÷’b‹ãzÖ…q£L7©h[î°¬ÌÖ½¦ÿJ‚þÑíçѽºW“k[i”–Í’ åIE4ÀÎÆ)J—Œ{ÔMÁ4À`ëÍ1@éïN(4çÆêh –Š1@=qZZ`>\Ç·³kOKæ9ÁÏ4à;—Ò«Í[½U<õªT âQ«sNí@ü(êi3ïFîø jäPt \žÕ4j3–ö¨â;X‚x5( tæ€-¥Á‹(=©‹³Z™š|±p¾XÎqëUUFÜE=b•<÷BÊű·‚kÐ,u›H§˨Û¸ˆn2I¶={WäýiÍû±»?)h°2nrO~ç½1ã§líç©©bùË¡ê*Ž!pòF[TzšªÐmb¤E]“1¾õá– É’BÄòiY—g©Ñ® MsQ½j¸ýhI–'½DEJ͆ôaÖšÊ;u ÇZ‘:‹+qš›9£4ÌàÓ‰ùhÔ¥5>aÖ@j[Y<¹ÁZzòxë@÷+çÙËäã#ð¬{\‚GUö­xÊ3ÐÖZ"íÔœ â·Ü”LÛ“ÐUûRÙHÛ†õ5$iž¢šÑrx¤ß=fLù€cÒ kÙB¼q‘´Œf«ù@Rª`z¥åeŽz×}áèV/ÎøÁ%ŽkØ2y®ÓF•ážëýh`.i‹b—95Ó­t+îT>?*赀 û(+•ñ>¡<÷ X‹ÂŒÒ?ÄÔšã1'oEªÚ™&­«Cl£!˜>ƒ½Aca6£t"‰I$òÞ•êžÑ-ô˜K ®>fïL^"ÛOFUP WŸøªCý™d„ÿ8®ÓÄ÷ H[5ç>!¼ûLñÄ+ãñ¤€Ä©mÇï ö¨ÇJ–¯Ïj y¥Í&yæ—­9O$zÓ…1@éOühíJ˜£à})ÙàÓGJQÇ4áŸÆ¤SÍF½8PÙȦšQÒ÷¤ËÊ\F?‡uz††3šò»6Û*ä÷ï^Ÿá×Ý àäb“°·_”U°œT£+WBÔ‘y¦[Ý$Ö%ÆŽ]‰UÝk©™yÍP–úÝ_Ê,ý­02#ÒôûwRè­ é»š°ú¥¼y‰ˆL3T¯'ó® *8aȬk¸¦ #ÈQHéšæ|Er.µ9eS‘Ыk@Ž= H–u9y7l'jÏÙü¦ Ä(  *K©¼М-“w.û—`ÛrzQ@ݪ摧ɩj1ÛÆ8',OaTÁÇjî>„k«ÂñùF3Ú˜…­§“ tÀ­(¬›fù§D;0Š•q·k€*¾b%ÀïQ¬.O'9­ v\NX€És€+¥¶8n}+Ͼ$ỉmp¨Td†c^œ°¾ðË'·­s¾5±ûnƒp¸%£ÇáBÃò@"˜zÓÏ GNj3Þ¬Å(þT” c cM©|µá@SE;‘Í'5¥¦qçØ Î<ŠÐÓXçNøÝ@ ps9ïU1œõ«W_-ºd`“U =;µ&9¤çñ ôáÖ˜: \О9âôãŠ3M ¡ÉÅ?w5 ’™ø&€,§Ý"‘œ‚#òÔÅ %–lðjÈ~£q&-Èõ¬Þqõ4Àpãò¥§4Ôæ—ø½¨èp⟻*žüTJq ãµ;s@æ7=І¤œ„Œü¤äTÑœJ}Ê¢ºâQÐ@@œÊ£¶jűÍÙ÷ª©#šžÓ›}0&|Fz­C äŽ2jg;ïô¡áû»ÔÌÆØù9=iBêÕäP)+Û<ÖYÁ«»¾ÒáŽ7šPT‚+‰¸ÏœÄ÷æ„(Ü…{õ 4å%Où7cÍ0!#4Ú”®Fi…Hâ€Òœ>éÚ>3É.*áªaÓ4ûÓѰ{ÒM7¥kFIO¥U¹·w¼,¨ÅHêz[IJŒërÊ .mäòd êxÍ ¬Ä¯¡ØH –A±°y®QÇ$÷®‚òÚþ8L¨PrH¬†Ö„*yéCu4˜Á¡©€” »~Z±i)Ž@@Éô®Ö8—Äz)±t"â!º7=qVèÂ1 Á®ŸG¾ki‹×½ 9bx%x¤R®‡k)ìE3µ^Ö.Ö«s8 ýê0 xU#® 2— 1SZH"¹Flã<Õ`O­(È9  WmÌO½iÜ©xàSƒ¶1Yq3f;â´î‰Hþè|94†1ƒ€RŒ[$ý)Jµ3’1NAŠBŽ)ñ#näŒÐËt]¤‘š®ø,HéW¢Ê#Ú¨0;¦hŸ¤ÆiàÞ—9âº7L¸‰Êæöšè|0¬VèvOë@Ó|­·¦ŠãjÍåÄ9ØñüËüC¡ªQ¤S¡fázLZ6œ`r’þñ#¿Ò°õ{%dhìäÕ›‹4‚Aäâ>îXãô®WR»Y./Ìëœæ˜¤‘¼Æ<{Š)<—Ÿç^ŸZ)€ï½áÌB ;™ä…˜ØVÒ¼éyµë¾´û.‡oL®M&@'œ¡ÀéÍFÓ•o–,ýM1d(1œþíÄŒç5 =gœbçNpAQøf éœŒŠr©$óÅ_Žø¨û ·©²Ì÷0ÉƤ:xªKN­øSŒÀ dšðbÌØê×VÌ0QÎ>•Ÿžy®Ï⟕ªEx‹…”`ãÔW{Õ éGçHx£½8á†3P‘‚EMÖ¡?xýh)ÝE6Å:®é§÷ÒÅ R­iØûPªEMÁ}ªëWoÏúH‚©7_jrúf—Þ˜8§ @íIA$R ó@ œIšCÅ%)©‰ÈJƒµLƒ1} MùE?wÈñÓ¥?¤W-«ÓU¸"¤vÜä‘Pž\Sçý`Ï¥/Î=) @å‰í@ ÿ-? S÷:ÓF ‡ŽÔ§îý(AOîãolTW òJ®Dg§J­#îj3Þ§´8‘ßÚª3pjdù >¦€,[¶û—oA[ž‘—P¸ ezV¯¾•¿àöQœäd¦E :;óþƒ9dÀ*qÅy½Ó3Jô½N0tÙ˳d!ÀŠóy•¨útƒOŽ|¤gŽÕ”ÍŠïm¡S§Å´Æp m%M!«Ú•“ZÜ2`õÊŸQT¸"˜0æ›z‘‡9¨È J•jzœb€,š‡54;[ƒI,%O¨ìhm¤ øn†º·2FOÊËs\’ÆXñZÚEÎË´Šl€N¤isme:¸(y?Jó©×œzWtöÞbYBñ޹®*ö# ± 3ÏÞ<ÐiÎ>lÓ1Lž)ž´«É ƒAŽ:þ.e¬èîÞ¢ƒ»¦j 9]'Â9]ÜqVÿ³åËH²!H=h4’ÎÄõÏ4„u¥îi}ºÐ:ÑëJFÖ’€(ÑNí@¶#Í’w[·Vò+±ÎkL™a¹ŠFU<Šê¥vlRTó‘H }‡¸ÇáLdÀÆx­´ÉWüj¬öÑž¯ƒ@„py¢`Ù$ÕÑa»%vái*‘Æá@FG”G|U&êsšÓÎ"'n+<ÅÉÉh5\ûR…ôÀ§ˆˆî)6އ4;ù®‹Ã B]úüµÏàgƒ[~”%ÔѱÀužh¡¾}±Ê@ϵq××× öÑ&ÕVÜãð®Âî0F®_O‹Î’ãŽ<óÚ’χ4Yÿ›&2kGƺˆ†!0ÂŒb¶4ØÄ d8Fy¯:ñ=ø»Ô¥ÚÛ”7ZÃvÜēɨ˜e€4ÿzgñŠ ádqMŒp§aòš:žh)Êx¦šU4 <óRtæ¢ *P({ÒŒzÒ /ÐÑF-ëOÐ8§¨âZvpiÅûf€%¡9?JX'òÉùI#¦*œB•9#µ$²¶àp(VÓıå#*¼ÿv¯C¯_E2¿˜¤g$m¨4ë%†áfxŒ±÷â¦Ö>Îó¶„F½ÅtWž2VÓDvÁÖ|s•§è>*ŠX 7Í+KØ‘\e½´—S,Q ´Û›k­øû›¯µº¾1ÜÈeˆíŒ ã“q6$cj¯,{ý+uë©P nã"¯Fe”› 6E ©îKU‘𣠓‘\ŒÑaŠƒÓ¯½ojs¸ò‚†+Û?•s× Å# lšhüÁUOйbEÀ×Ò¢ûF¥mèÎ3^Ñ¢Dª1€1Šò? (“Ä6ÀÝM{ 8vô©`!;T3B»mmHסùÝúз–¬0³/\`R>r23J¡ñ‚ÄÓšåòF=éŸjR0»OÒ€’F8ÝÇÒœ¶¬Ãš#grO }*mÅT³±ÅsÞ.Ñ?´tBæÅó¯á^,À‚AŽ+Úµ­ìÑ*Ô“>£šlÖÍ‚Aýh‡vѸr :è­šL.ÓŽžµ¯X5µÀf ¬ƒ9µÐÛ‡0G 9ÈëŸ×o~×yäÁúÐ8ü1SÚ›š|¼¿¿znÒE0N^´Ó×Þœ§±1YÔû×K$l¶îäñ·5Ì(&@­u·ªÉ¥9 ’€91ß‘Nšõé@ÊH⣫–ë¾uSß­Aq‚v»(!N^N:ÓiAæ€-Eòô­øî.!>nÊæã˜«Ž•ÐÛ\-Ô ÿõ€°56<8Á©Òp6ÿSxÁê 3j®0H  xî28@ «H|ÅÎÞ¾µ‚—RDx9úÕ¸¯a¸`ûPU*$œ(ééYa˦Kmª+.Òxõ«{ÕÆE 2äÓÇ%WÕUí€+e—q;OëUÌ`Xþt’¶Ì{`ý)ñew §$‚:UçEÎP\[™!Îì²ò3Þ˜T®&·Þƒ‚;Õ "ÃÉóY¹ËUË*[¥1´N÷UKhJÀÇ||´€M_R–’³I´…QÔ×›Í!–VsÔš½ª_Kw12È\þƒÚ³{âšü©n|T« ‘’6ŠvÅt÷¦N*!ÃT­ÆEG~´êÔ¹>´„í”Z H§‘Rç­WSÏãSgæ€$Ï4£šh?(ô¡O$P³ÏjpéMniPäg4ñøT‹QŽ™©ðâí@å°)Iüiƒ;¨˜™6Ó­çÄê¬~QQÊH”ãÒŸcKp7¶ÜSÕ|!¥Ü- Žâ³|K¡šH×0·qÚ­xfhlöãpÏÅtW’ ƒ†U–&àŽµ y0vµ—†#Ðæ£žWË3–>¤×c©h|rI!I1Ô Ç¹¹™•Tõ#ÀŠÑ »PtM+‹#(Ý9÷5•o°Ü)1°ç¿zÔYCÎý¶ŸÒ€1/pf™—çÏþµ1Ãs×é]RD[µp6²Qô5ÉLŦ>¨@ L¼͹ç4Sõëw_R+Óc‰ÉÏ¡5Àø7^VÛˆOJõ­Ÿ»ù –X¶ƒ¡ˆ°õ<ÔÅn1CǤ@åE'îÆ@ ùR´Ñ´Ä2a}wµòÞ¦mοu4ÅÈ\}+>òù¯,йÑ ˾ãøÑý‹aýÓùÓŠ#’;Špé]³£ÂˆƒæRz×> Í0•—¶(ü茡¹i±àT§¦i!‚If‹’}(u¸$ö’ÚÏe4M$eW5Öi:*Û*É( ç¥O­i¦úËäÍŒîQëíJàq, »Œw5CýjyA[‰9éLe¦3HHsšFäzWÃùSÕ²¾Ô™ƒ@é@Ç„X&‘&zy§ù ÄñmœIz·Vê6È?y·³zþ5sDb4›€‰ÆjKÈ[i‘ŒgëH7µ<ž)¤ÑšNô4' iê2Õ]*dêO§4¶ç$šoSíIÎzS×é@ËA8§Â¹lÐÊzÚžØûæ¢s’}ÍH٠ǽ{-׉VÇáý½äl ïEVŠñ's$Œç«Mn_êrÍáë _0âl­`Ÿ˜“ÓéIåï^çàìÿÂ+b²‚§ËÆíšðÔê=} ¡Æí X¼ òT¿JšÝä~•“¨ÙÁ¨ÚIo,yVäV´¥Ð7#°*Žæ~GJ¢’ ôC/#½m_A¡§‰™†ä]Êõ 9fÁz~¨w'ÔÔÍÂÓ³rÆ…#'41ù©䊱e›} ŽîvzÌt™¼¿¼¸«{†·¹ISªœŠèæÖ£º°“pefB0:R˜êUu¦céJ7/j`]°M×ú ÐÔ,MÔK\Ðf$qPü¥½ênÜš€rr:æ˜ ˜a³Í!,«•5œ©†€qS€úŠ„Tؾ”èc<ò 'I:šm»bB§½>àa€&ÆS­Gê)ñÉŠN×"€'ŒSÐçŠ9Í=8€“=)RhìiS@­#z⢂92ØóÚœ  {T©+G )ÆM0;_ ,o’:k­ºk„µýÔXÇVÍs~îU^9#R:‚+~êiaSIã 8©mCÜ2ù‰¼ §©iQ12ùF6ìvÖ–žÏ(+"ë¸U‰æe|—M2üŠ@q“XίæO(*¼ŒÕR….™gÃ/@ë]¥¨Ûˆü¼¬ŽßÝ®bäÀ'Žt.6¿?CL —²¢Ù’§dªã¾MrS6[Ž+¨¾e(Å€áp1ßšå¤'ŽôП­œwS´ðÒØ¼ò“‚À]Zk&Cþ¸Ƽò² 3Ö¥0àHCmbÆ^áOÔÖmߊí“!$ÉÝÆ–fÈ,MFPVjçÄfRxŠ¢uÇç~f¨´\dfÞ˜N¹qÎØÐTM¬Þ9á€ö«íôb€Ú…ãu™ª#spzÊÿ†š½KÔÀqWÚ«§ ʰ§+š®ãl™ ©b?.*1ÓŠtg @ 'dù«3І¨.Œ5Mß öÍ%»qŠlœLi°²ïN›ïŠ™½=OÌjÏNj\àõ¤¼RÏZAÞ•h½>µ,Q;6séRy`°8Íu^Ó-.åÌé¼ç¡é@<3u 1•’VØ/Zܺ»œëgq$}Ûetv:u¥² ¼iE&§'—dçÚ¤"oÛÝ‹iU×׊ϓÄ1Ȭœäã5 –_]€`·4º¶“…Ÿ˜Ïóâ˜ü÷ò%Æø\©§5Yõ‰IÝ!õª#3‘Û­ û¤Õ=ÅÄ’(.ÜÕ2UrÈ=*V;±ÏJ¬íœu4ÜçÚŠM¹æŠØö¥Õ­†ïOÀx *@S¯n#¥[û"÷¿JSb¿óÑF(™cM##Å^ûäù«ùÑö'çæ€3ÏÝÇ= i>AÛ9§ 'úPj‡nˆiè’7aÅi‹⦊Ìçæ^´ž–ÅÇÍú Ô7–‘¢¨¹þðÅt‘B6€#¬=[t—eqÂŒb€2…©#åzŒÛ8'<ÕÁ Tʬ b€2¼£ž”lö­*6è@oqMd##ËV÷¦^ßjB£+@Û’cãò¤¼)´H®bO© FGz»sHÐŒc=ª!‡ó  É&Óȧ³+ÇÇQRµØëVÅ´å”'17'sˆŸ¼i1Ú„=»I”v œ»QL?pŽõ«ª¿C@ÏëB®ãÅ%Ml?x é@µÈ§È~_Ÿ2l—ëL—îÐ"¥^j.Õ,gŠ‘y1À4¢š~”%¸ËŠ–èâ@=©-—‘ïKuþ·ð  z ÏÙ5«9úyr©ü3Zž<ÓL~&¹»”ÅpCŒv8æ¹È[dÊÀóœŠíu›Û_JWT"tAŸ]Þ¿J@pÂSƒ’}wÿ`(g˜¯R½qÂÝ«¥ð½òé÷%ÎÙ08¡éS¡dÜŸ‘¬¹’VV ãÞ­%êJ£sÖ¡“ÈlŸLTÅøˆ±©$óé\µÜƒnÑëÍu¾+UˆÅ‚9Šãed±HåH:œÐiFsŠ`Wš›ÃT“ %G7P‘Šz˜S¦iéÖ€.« `Uȯ‚"¡A€1žµœ­ÁàÔ–‡ÌfŒs‘š@&¨ë*#àg8$V[7ÊGõ­]FKbIµcÚ˜ ×ÿ­Ev  9ómƒØÕ‚ãv ŸÎ©éx‘]3‚9Öµ¸=ÉúÒ¾ì·Ý5^æÝ™÷$Š íŒV‚1ÔpTÝÊÐ2ZÏ’v†ükBÆ#ÃúUÕUÁÇäiñç<Œ~åùErº”f+¹TŒe²=ë®8ǹíy?ƒ‘ŒÈ<.Þýéǘî)­×8ëO^V˜ÂØÁÏJ×vçJĈà]¯Ïlžƒ C<“RŒ0àÔ†0s¸u¦˜”)jÍ𤑸WD÷ ôë\ÌInûÄyö5ÑÛ],ÖäS¸Ÿá< £q$€sYò)$b´&1±8$­’‚ŠÏbyÀ¨÷j²èŒ~\ƒèj6]§P§…ÿÁìþ•Ñj1ü®ø¬OŒë¹àm‰tššâÊBGÍ 8[œy¿…WÍK#cŸ\TF˜±ÈÁ¨eáOҧQòÏ+¹ð|T—V¯g±]”ù‹»ŽÕ³¡Ç°Ü¤ŠáÁÇ"²5&ì©'03L T3jxÿŠ^´ž)ààƒQƒƒþ4ñÁ  ØoˆÓ-[©§Äx"¡æ)ó@ ~Iˆ§LsƒKp>`ØëMqº }(Ñž•=TŒóVr@€%Ï)¦“Ç)äRâ¡*º¯ 6& ñXñ$zÖç‡XG¨àŠôÈ>àçµfø‚ãe™_QZpÜ‚jÂÖÁ–Uޤ ½2 ªXð+–ñMÙ»ºò#o‘?Zëo%]?Nw$Ž+Ï¥6GrI,sM˜c;¹ü©6dóVä‰=ˆ¨ ²ò{SR©!篶|³úUFˆç u¦ `œÑI‚ âŠéD, ¤¶~é…tì‘‘ó/Ó"£1E†GåHyTŽÇ?Jq xÅny‘…^}ª3g¼cÓµbí'Ò“OZÖ’Á€çhúÔ_ٲʀG¨4I&•ÈZ™Z_SRýŠLàFIö§-¤ùæ91ô G#È×5a'ÈÉQšgÙÊõ$cÔS–,ÿéH eX‹làƹéäIefç$Ö­À–AåDÜwâªfÜnqL ÀÍ7stܼúÖ‡Ø$Á,H TbÑï+5TØqÉ¥IO À«+ 'Êç°#4²K<@á€ö…x˜ˆ=Ï­@Èã#>”Öžv=ñô¦åÈËœŸJ‚þ5û#~aíXÑ·ÿ^·f_2'R:¯ƒ¶æ9íL Gµ!R+qŒÓ‰úÐKÃ0âƒØ>Ô‡‰G^iÇÒ€l \FQŽíÃzvŽ@bsŸZãôK¸¹í%Pçë]ݾý»KcޤÀeÌ ý‰y .é^~~XþéW1ªÁ; ÈK;•çz´FÐÏ<,„qB9-OÇÈþñ椦޵^A‡5?8¨¥ûÙÍ1zóNG(hûÔ¦€.ÜáÖ9£ Õy>è¥F& ¤žŠVû§4 éè9 ýÀiWÖ€ž3@ûÔ„áI¥æüE]ˆLÕ{¦Ì¼t51ùP‚{UYOq@ }k¯Ñ4c©ésOÂ9mßÜäsÈë]Ÿƒn‘æl,±dzdR`PûÜI’gRGO”š‚&{IþQ‡CW|E—|“GÒAÔzÖhy$Æàr¼f€;=/S{ÈT9ºdzÖ´r’Û% g£×¤Îñ3®Oc‚+¡[Ÿ5Aç§aH Ï íÀÆH$œç5ÆÈ½OÔxšc#[ƒ»åSÖ¹yyæšÆ”AëJ2>‚˜®$JdC-M,X’O&ŸS@E9zóL^Eâ·Ôf‘¦Ý{àP¼F2A\jrŒéô¡$Àšr³dqÒ€c^ÉúVf©gçÚ:…;—•âµCw;³@ùÅp=ˆ=©S¡sT‰aÔæ ÷IȪ@àç4Àrpƺ /2Z}<×<­†æ·´-®eŒ‘Ç#4«ä|¹$qÓ&›EÉåF¯Z°Ñ©Q‘NDRsŠ@I³cæ Gûœ°ºHLJ@<0ƒV­áVúU“‰NÆâ"h‰&&Öª%;X] î?y‰•BâÔ©89”ÀÌóýäÏãMmår¤éS< £$ƒ§¨ ƒÁqƒ¬JOQ ®›__+Nn9#ƒàP_VŸ<â/ë[þ*?èXÁ¤œ¿ýj&54Ÿxz‰ºSaMÏÏš|Y.=ÈÛÜéb×Aµ½ˆíùÀª]ÐþÐŒªãžµÙEåÜè1iîÛK —µsw>½ÒnÒf ðg‰·Ö¤F±}ö£žÕ™sûÂOJ¹¤>û1ÏjlÑþñ 8ßÌ [|ñÔ×,Ö«œ†'ú×IâD_·( 7cšÀ–2:ÍR™‡nï^µ ÈÀ"®ÄÄûQä1õ4”É™08¨š,kNkWxǧz¥!ù ç¥Uû9<‚(§–!ˆ(_ЃEzÀ³“ßu"DAù¤žy5PÜ©ãŽø5<7‘¨ÎÁÏ­ ,ªºŒëJQq7Ö£{( ôΈf8ö HÉ"€C`vÔ(8B¡4Uqß4Ô Ç8â€.$ΉŒÊ,£Ž ûT[€R¾Y'Ôž) xÚ=F(ݶ þ½$žB©c'SDЦHÆIí^3Æhæ(r#ÚsÉZ†[t 6Èø=‰©Ñd`*ƒQ°1œ·Íì(¢ *¸9éÖ«í¸ …P´Í¼ ¤v¥Ø6rÀë@£K…^6yÎzSdó ¢†Ç?-i%ªya…Âsü!Oó¨eÝùH'Þ€3ž%8Søæ£ ÏË+D~ñ¿y·'ÖÚA»›¿Ý¦aòË =¹®RâFK™Šô lÑOáqÚÕÙ/Û)'̿քP”òjd”ÏZˆªšBŠ\SIºI´±õY¹Îjò8kE~n„ÐGái[÷Ð`a€®¤#æçºeóØ^¤ª~^Œ=Gzõ;$ßË·*qsRÀÍ“Hß6ìp¹íŠàüO(mJUQÀ5éßbŽ7߃¼Œ+ÉuöÝ«ÜõÿXÃõ¦€ÎO¿Rô¨W‡50 TSv©EE/J<ÐM%)  #?#qžA©ü§Š†>¤{SÜü¼Ð>BŠXÉ+M¸ibé@oºiÖýV˜çŠ–Ü|€,OǽU—•©ç ÉAU¤û¸ÍHœ¨®ƒÃR*ê«ãkeN}뎯ZJaU –ùþY-e#tO…'Ò³–$cÆEOq!º‘æQÝi¨ ž=)¶¡á¹R+Ð×Me £ýFkš\£eXçÖ·-ÜKnŽ>úúÐ_ŠB8ÆÓü뛓î~5½âFßs~OëX3€Fh@AŒæ–AˆO½ 2hŸ„¦y© êMASÛôc@)©F½iÀs@ìj$—¢5B:ÐΜ°²ž¢³u(Z; Äpx«zw2íõ÷©µ;bð•,94€Â4wŒŽ¢•‡Žj5m§Š`=x=þ•ÕÛIæ[&W'hï\®õ'‘W­ï±²0H=Ío`–ÂŒgךG%20w÷"«$òp ¨ìy©YA©>›©ad.™‘S«œ ª‘ê @‘„Só}A§ª2~t1nÀSKäöõ¥ @àŒýhlí9aùÐ=¯E¶Xå‚0qX¼×U«Û¬ºs2¹áŠåi€£ŠÔÑäÅà÷b²…\Ó¤X¯c.p¹ë@fóŽ5,!Éäâ œcoçS¢ØÇ=°i§jÄpG5jGààU[hŸšÐ…9j@U—v 5e!6ºîCÖ»œ3qíP¹CÐ=M$Ö§¡>bžÕŸ=„ƒ?#-jAtЕ@SÔzÔһ΅ãpTuQÚ€.xÙÆ¥pXç÷`~µ¯ãò¡Ç¥?áý¨’âæP{Mñü¨“‰äöõ£¨o/úÆíÍ@Ýjgž½j&˜ ߥ8SE8PÓY¤ûzºà}k(!ÎOëZ7 ¹Ûš¢@¦€gü´4íKütÞ€!lóM‹†"žÕpàšs®EZ…·GƒÍV—ïR@ØjGeȧ8ä0§Ì€®i‹óFG¥AŒJ}êx†I5TÔÊ6ÇÆ€ÛÞ¦¶®´*¸õ©íÁóg,9Åz~”¡™ðJ¨ã5ÑO G Ê‘Žkˆðàò!óæÝ–îMhÏâ8b›Ê‰Zwé´RM¦§ÙÜÇ“·µ7S‚õ˜›IcAßræ²ìµÆ ³ÄÀ\ñùÖ˜Ôcž}˜e>„by¬%Ü:‰{žC†ª¬ŒNWWâ¨Kƒé\Áž* G÷Jý 03žjXmY¾cÓÞ•ÂxõU•þ¢³æ¶É!“9î+XƤeX•ô¨Ì*NF}sšÅûöÜGÒŠÙ0çþZcÛ4PˆÙðK`TëµXcn{æ«™ò»B`gŠ‘¤þZK°œ‘q»Ìú¤nä;TƒËÛ–Z@[ŠxÂáÈb=)àŒþè1ôâ¨+r tÍYYÈÚAúв±³ýòÃÛ5/”œí|~µT\•è »ót†³™þx=×µy­¾¡$lŠõÕx{QH¯RvH6··¥&xv¡ ‚IîOJñ ]vðÓVþuëí(#”ýkÉüTë÷`t/ŸÎ’ FTÕB*j õ½*ZùS@ÓJm.r1@ ß§Ê~QÍ1O̽+œšSÊ{ÒÅÒƒœ£o€äÕˆWÎMX‰¶ƒì(”åɨ\dâ¤Îi@ ƒŠ™N D1NšÚ²¸’ UðJÆr+j{}Ñ‹ˆÇÈݱX¶ŽLJñë[ºn¦æ)Š”>ƒ¥ (“É«¶2¨“a݃ڧ¼¶ŠVóm†8èxªq¶ÓƒÁ”W^éHq¶°®:šèuBàç#ÏNAã â„h=i“÷ô©⣔ü¦˜1É«ÿpÕ|š³o÷ J4´sš\äãµ)ÿVjÖ¬°ýÝ@¼·rØíprG5¨ñ¤‘žX·­eÃZq¿îÁ,zcRœ• K"±$ƒùÔ,¸­MB܉ZUS°õ8ïY»ZGÚ€Ÿ¥0ϵI_0`ž¼S1Ž1ÍOiù 銾ç=¾´ôqž•¦ÁàRN;­¸ü*Â\FÀåpk#9 â§óÎN(][Ðu¥ùûÕ®J‚˜]|Ô;gi F1ÈÍrÚÒ\ÊBFªªpMtÇd±°¨®BT1ÊèÝA"€#ìàäH)E05­ufXÖ9# G‡S] €œƒž@Írúdi%⮾&é´ zRVУ4ùÎ3ŸÊ–ÕÆÁòô¦Nä“€)P‚W+Lhû½Jäœc¥FH îa@¼d(9ÈúÓ¡Äû‡QÖŒ€O9ö¥Œuë@›ðõ":eÔÊ›s&?ýUÈøúo7VbÀÚx>3„Sc±®ÆN¦Äp»}i-ÀãØ Þ tæ­¶j9ª±S—©°t §ŠdÜ!=xÅgíÏAZLÁ£9ª™ÏA@ÈýáëI×4ù8œý)£©¦/QŒg w©¤èjë@H2´ÈΩ›îý*ÁÅ]2f ÆÙ>µ$-ò‘š$h…åÍ!<õ©ʃéPg“žÔ!|t5¥¤Â./Q\VPï[zƒ¨ÆI /'±®ÜÿgY¤ òÈÿtg õ«>Ò÷Cö‰‹ ެKÙ?¶|LWv"RŸA]’jº}”il'LŒ äš. †6nÏ^µÐ¼j-#’@2£9Å`Ú¥¸FÇ¿5¹¨öLË#FÀpV~¹¬iú‹m¤f‘ÍÆ¬µ‰Hé“LšäÏrí4&S‚ê»wzµep›ö² z‘L2˜` xÍUipzU›ÉCI…#éUŒ`®I Êq¸f“nGÍ‘ïOrpÃñ¥<ƒÓµA°ún÷Í6Ä<ï_ÄQ@×+óçÜf¦,U1½·ÿ³PHUÛ ÀúÓÕp½zz `=J e˜‘SùðÈ·|ÕS0'fœ!‘q¸½q@’XHùHØSVP‹€F}ªGÌN?JE0h zРà§ÞÇ|b§YQ>lþUWÊsÈ­XHÝ#ÁÇãH-ÆæÊ†#¾EYYA@2׎µTÈüEðàç©  âhŠí FEFeDbÛ[wcU°TT¿¼)“+Üìñù¨øÔPðÄþtGy+çËO—Ö³D¡Sj¿ìÕ¥¹ÛÔ+ô  þÓ)]‚<äô•cË÷ õäRè˜xIï[&Þ+óuõ¤r\º RÌqëNirzã=M[‚CÇëA°À$0òh2ú]Ѭ`ä¯9Åc6IÎjôÄÉ4½ÀàU'\1ÐyëL|§šxÈâšàì4ÀÏ=NjÅ¿ ŒÔÚ–ßïí@y§(Î0iµ4c9 qІ5äÔ²zRF(eï]ƒgÒË=Ô»m Á(ùˆôö®|TŠK#&â7 @ix—X³¾[iöPÚ[Â1¹X³Kþök$†ÞÕ™ÕÚW\p½DÈR@_AüêY®–U1Û¡:94@œwÍZ³RÎßJj[®ì¶I«q¢"áHÀHàä÷¤Xó’>µ"·Q×Þ”¶G#š@ L÷÷§…ºæš¿˜§ìhG\â—'éIÎ~SF[ÓŠzNêN+3SLÍç>~£Þ¯™pqÍT½),!åy  ÜÓ”dõ¦Í=FzqL M:#ÑOæ!°W¸®ÅP þ5ÆXʈÛ$f?…zèloU[É3ïA±üé0: (@4K“ïPÛÈ à­Xyßz@Sè*»dò« NârjNp˃×4f'‘ÇÒž§Ôãð£k¡ê1õ¥Q–^§Šö 6ƒÂö(F—ŸÎ¼ïÅ¥SP™dbIå=«Óù:U²±á`ʼw^•çÕ¦f9çƒíIÃŽ*ïš°r@ÙªÁÁ4Öži 4Y׆ǥ1"Ç$ÔädqMÇZ̹ÿ–úTG¯_Ò¥ºÿ“Š‹&˜ ~¨©«.2:ÕTÎò(Çðã5 úÕÈ?J„ä5>†ëÖ¬‘•ÅSSµªÚ·  ÁÁïP¸*ÄU‡ã‘Ò¢œd«zГé],vóÉ#°Œã=ë%ËVµ…³ÜLv‚qéHŽ1æ´Ž¸f$“V-&ŽÞìHð T»Þ¤¸…ál?Þ¨cŸÈ”HW uÕG5ŒÁeK›ˆGuqÒ¶óm.ã¾¶#”?xV޳§¼A—a#ª0­hõM2HÙ ýĽ×7O ³—ÉŒ“Ê‘ÐÒ ·O˜KúQ*\ŅCTÊ8QŠ`Z;·æŒÇÜúU’BŠTÒœy  „~tãîªqU_,eä=ÍQ—UË”I¶©þ*Ô’Tó¼j}(®qžbZBO©4PT±[(*Ì >ZwÙòùUlv5mÚcPÈ»{ïQIF„ûR/%€û¹¨%ýÞIÃ7O¥\’Vhƒqз5¢Ê2ÑóޤÐ5¥ÆJã¾zÕ,n|íì*X Vbx8ìŸöi·Ú¾üf€"VÀ;WƒÈâ£ff`I<J¼c@ry tÏJ’3n#ï“ØÐ_(”,A>Ù¢8ÿƒ`Ç^MM1Oº {ƒÍFÀCqÁçšµmýàÆ=j)V n;ã‘‘I‚…YN}M1¤>8ÛÛ4,–Ñ¢mLdúÕaf#$’§ñ§¸'$©úç­.ØŠlx SÌûÝð*´ðZ¡ÿXw{ œJ",ÝÀ¦ù²Hså"ãûçšd@˸Éò¯·4Œ–ˆpMÀõSš™¢i"ÎÝÀz jZ«JˆÔvÏZ$¸w;NÕÏñc5n%E%¼½ÎzäšËTpAתÞÔeÀN£ï1é@ 1Nø©÷bqšá¼I`lõáƒ$¿6GL÷®å#(¸ß…Ïnk3^²[Ý9‚dæ_—Šh;Ó×¥0Œ;ŠpãŠ`LµÁÏCÍh…\nÈ ô¬œþ5z ÒCÇQÇZÝÐfòuhI8V;OãYþ$²†Þ'‡ õÈeh6¹#p#Òø¶f}N)ø ñ)8¤[å ”dŠY# c‘‘šhG^GåL*´µpMAÎO9®ƒÃŸmÔ&C2[ÈÊ¿Þ8Çõ¬#xœ¬ˆÈÀà† ”ÊsM Š)V€ýjAÓ¨¨ñÍ=zP‹õ©?>ÔðzÐÝqšãG~”„ŒPŸ¨¥ž´Õù¿:(sÃ¥LÒÆÍ‚W"º •ÁÇŠäôwß©$ƒÓšèõÚ¬O®V pIÛ“íUn¥òábÌF9¨Í̤çíUï'-lr„S@?–­Ï&ªrzóO™‰ni€æ€zkœŽ´î4‘Š`Q”aÍ:Ü€ç?Ý¢qÍ6¼~”mrO&¦Î¨—¥H>”c9Í9WŽ´ž´áÓ8â Ðu§ÄØpsNŽÎyŽ&ú‘в4«„Á} zÐ]Þ^N9•$chëùW@mÒDÈ86™·%9Ô¿ï9@éøÓžÑ•$}iÛ'“ùPÀcŠS)<ÔÂÖ09æÂIÆ€#‘Ò‘§b8ÀÇ¥XXÔ.vƒJ#@s劦%9ëOÄcòàã àV´k ‡œãÔ±5Èi’„ ÎøÖ·­§GFe”dvŠ‘Ç•òsÏRM5¶ãˆ£üFj—ÛZÉ`ÄsÍLu+I°œ7ÐRRûO àµ4"V¹„6»ÀµΛCÉ‹qV4Pº–»iÒl½8 OÔ¤ÛnnÀØéÅy&·mö{éÜ|ÜW¤ßÊí/ÌxŠâ|X›.œeòGÒ’—9Áæ lóV[¥W~æ¨sŠ:ÐÔ€ñ@ aÁæ£ØG|ÔøÎ?J‚hèbèý*×­Z¿nϪ¡#4Às}Ì÷QOïM\੪c‰zP±íPÈnµ(9#ŠdÞ¼PHàÔñŸ’ R v©bo”ŠœŽMFã1‘éJ½M)äHWšíü ie` Šãaq]¨%µ£Gæb}3Hª÷L‚ñ÷Ÿ”÷#½f_è–q[¼†ô¤›*ä9osÀªÒ\½Ënrqô¤:Xy/¹NG¸­›GÖ¦£wæž!¿4ÀÊö?­Gómääj™—h9 : %¸g<ŒUY¯ aŠã×TRÊÎ:íJξ¸% c”—33»nç¡ô«’‹k£¾ 6çZÂrL'7Y]ìn]pPâ Ž¸ü(«1Z]ÄuÀàT‹±Ÿ3Œvz„Üí$ Ô*LB’ˆGÔ kÉæa]F=úÔ+;nŒƒŸÊ‰e(ÀƒŒ÷4(‰ù zw©ËA…cϨªrA;ߎ0¢•CIv¾?Úz²Y£Ê}½jQr1°œ{U&¶ÀzµBbÙ.X³þÑ  y`aO”†ïyÚ¯^8br~ðüM:d·UÚ¦`G÷XŒÐ'¬Ù›kÆp»RO˜Vq<ñ]>¹kæéªSy1 …nN;×$¯Ï9ª@J>_sR,’'GÆ}©ò8¤ç9äâ€-Å<ÆUX})Ú´†òO4‘€튒Ë '…î}j+Ëuƒ3µúgÖÙ,7sš“i*M5—i8zƒ´c“L zF¡&™©Ãr‡œwésÉý­n"¹ÑšhßÍ´uïœ×•„ÔŠït¯,M²yaäEÚç=1íI€ëÏÙÙi÷:ôWvð¬[¢Mà’[€G­pÙ,_83ÿí ­{M×ö¦¿áÛU{Ø¢Óxr€îÈ }½+ÊüE;IpîÈ]Ø/LNh@`oJ âæ1á‰4/'Š` BóÅ:@vtÍ$cŒÐŒÃJ‡ ÒTŠj«ÍHéMsíB‚Çž• ”ŠpéH9íNkO}—ˆszÝw!-X{…Êíü3[b¿xú)a ,ÄñÚ¢ºmÛ9ÇÒ¢9ª1'®!á”±ÇzÇ`wŸZpíM¸¥ÎÝù¢y¤F#“í@0i•nÖÚKÔ- näu ¹©Žt0È?à€1®ŒÔÚM£Þ]´H%^‚­I`ÀícÀR9«vŸ5Ñ•ÃlÚGËÖ˜^'‚àÛ¿,:š·bÚzÝbýäòÁÆr]J$È'®EM§éðÝÅ/š@nÄö¤£xsIð•ê+An²¿ý4l×U&…¦}˜Â¶P¢0è¨+Âlå¿ÑõÖå·!þAéZ7Ä[CME9TsÆsI 5dž,¾ÐÂDpÀ Ú±u½û7 ‡| qÈäz·sñÕÜ‹H]½…P¼×Íêþõ‰QÎÕœ– ý þ¯¦0áFOÒ¬ õrƪ1ÕªÒ̆òxâ€9ùôIn+ÛÖ³æÐnâO0Wõ®Ù@Qó&Héžõ ²B#mêª Á‹À›G\ïp§=é« dö®®ê8’¨‡>Õ“%¨Aþ« ÷˜¢ÝW–ÈúPÉ(ÎHö«RBqµTÅ!è2 E”f;@À©X£}ÕǸ¨š9ä:J°à~”ŽÜpsøTd?Ö¦1€9pqÚ¡rr9 ª•çpojnÜt"”rF8)HÎGŠˆ 9Èã¿zrÚÄÙ!jEÀl“Œãc@ #$ÇÓ¥]ŽŽ3å±õªÈpx« +M4¬€X~tÍåz¡Ïb)ì݆x¦Ô¿l¸UÛ½±é]—Ã×:ä²2ªˆœýkŠ`JŒ“šôo†l³¿¸9$²¢æ“¬“Í%ûá|^Ù½‡‚&@?ZîÖÜÍxAè9®/Ç6¤˜+€€½© 9x5 Ž*F$7µDÍ“T,zÔjy©œÓT|ß6(SÀÆ3OQòÓWNié–`(R»Ç*“ÐÖLfüV\úÖs})€õ9R*™â_Æ­¥T”bC@ˆÁ¦¿+OS˜”‘L9 õ ãn Ô±ðH5\>*uÎELçN Ú›ÎiÞhýë[LPñ;ÖZ!vA$Öå…±Š>¸=ù¤…ŒŒàf¥Hàå}iÊÀðzSÃF4€•cÚ9ÃÞœcùzS¢'ÝãÖ¡»¾[X°Ä“Ð(îhµÌçÕžÊÒ±fä{S..òÝX‚zúTmpÝIŒué^êBÎsÀô¬é>lòjI™ŽæÉúÕs’ô¦†ŒGÛZ—Äö‚+ß5GÊãõªºwË2žAÎ+¤Öm¾Ó§©ÆHZ@q+!Q€ÄQC&Ö ©ÏµÀô%,tÏü ˜ÎŒq“Ö™æåw>‹UZ@ÌIoZ,±\Š£=ê68`3»ô¦Ç;€rE/Ú•¹Úy¦¾oË·`ùÓ|òŒ©>™¨Ë/DaùñU™›;Wúš²óÍ òíÍ(¹ ‚aUv6à“ô'š8RÇj¶/X ãó©ïsŒÃ¸"²÷î`YªhË å}Ú€7£¿·H¿ÕíoöES–ù³Œ÷¬É¦“fЊzõ5[´¢+FÕÏp3M*êre,=j†•Oú zU­ècùÜgµ ªîGÁèIÅ9V7p/ š"`ÄÈÄp*b²`#œ´€E…O™´ü˜9Â㚇ìî…€fàñÏn4VMÁvƒÆìÿJtvø««PxŒäXý5"•BHBG½kÆbÏÌñPË·"ŒÜÐB¾`Úb÷â¢e™Q¼¸˜úV¬QÆÌ `j¾¶–æÒ\ÇcîÍr(“¼lIŸk˜Öt¦ÓîÊõFäØúW§%¬%LÎ ×­ej±é÷ò[ùC’î܃Này¦ÜSÐ9çvîÙ­d10èx>¢ªãŸ½L V÷ |‡‘Ú§žX.b1ÚÊr­Yœ+‚=êüb-™nsÞ€+I¶°àóšhP$U‹®!Œ ñUPüÇ¿¸ÜÛG :š‘¯š8ŒAzƒž”‹œ{TK檩l銛ûVøÃäý²a÷?*¬‘Éq(HÕ¤‘rM"F\áq“ëV`v)q²:ƒŠî|3à[&UŸX“ÌcÈ·C€>§½v¾‡¥IáÉìⱆ8–MŠVƒšÁеÛmNyŽáGÏíî=«[QºéÒ³«°ó×µH6Ë”+žED§êMà³sÁ’NãnÅÊžAéUÖ‹!ןOz†Aöè— N#*ͪAl¥Y7yÍ< X° Eà)\šÛÒ“Nº¸ò™’8ÏÖ~¡¦G=Ù)#©ÁSÞ¦Ë µÀšmຟέjé*]¬±ÝÈ3:š@f ³År}ºS¤8ç¡ö©ó"§Í»Z¯4™\`b€& ò’û÷ Èù”ŒzT0±YU jb]Øoqé@Vî`¸“é“RÇt0RU »¿Z¨Èw ri ŽÎ9ì(OË¢Ú\w¤Y#Ž2¹%‡r+$JK¹°;Pó0\«hãDÊ8óéÍS¸³)’Œt¹Ÿ9,ÜÓÅä˜9 L …B° IíLdrÃ`«^ãvÕè:Ž+>y$L‚2ç@6 ò1ÅDö‡=‡4‘^¦Hg*{}h3n$–É ½¿”ÙSœËò¨š< ƒÏ°©–ä‚€ZŒº’p1ô ðÝH§‘Ò¥ny<ûÔŸ(äP0ÿõÔˆçûÕ0ËÛ4ñ·AÏn(³7|Šnïz­ö¨þÌí0È1Áê ÔÉ¢Þô›Ê¼©âÛÆ+Ö¾åtk£É"~~˜¤Àë K[K«—ؽëɵ{ƒwzÒg¨¯Iñ¾¡–ŽmÑ€yyW$äœÒ@WhÆ*»ÇWX~• Áª“&*´ÒùL8ÈïVäaÜóYÏt¬åYr3Š–Õ*~µ~ß *àÕ É=êì&ÞÖéRg$‘Æ;ÈÖ7i¶ãÎQo»Wµ‡Y56)ÈÀªL>SL¡Á¨nSt#Àï@ƒ˜¸õ¡¦Û‘´Š|ƒå4õÈëRÆw(5-:#ϱ  |½ië÷iƒŒÓ—ó÷  :TòIö­Uˆ°µRÒ= Ãí`{šÑU”/ÞSïHXp~nIüiåm¸üi_Èü*`@ÏâiÉdò!Î~cÀa¾g¸.Ç%sùÓ¯u.ð p)¾dKó>ni*Ù›¢ª½zÖŠb–P3ÔŽ+zäGùN8ê*®ª‰4JÐFyšÉ* +’Õät©1²†ÖM¬Tôê=ébÌ"ŸC]‚þ÷NŒ‘À8 W%h0NzêôþÊHóÁéìiË_Y…ºaŒÃWC%°‘˸úÑEÀo¤œ¨½#YÇÃãÚ”•8.Ù=Hƒ(lg8íí@ HI`NGLŠ´,دU?tÕy70o#qÖ˜ŠÈNàr{æ€ ÒHÝ“cƒÅDŒïŸzºvqœã“ëU¥Üàô#Í*ÜØ œñҚʭò€7ÎiÉ€œ&XsÁÁÝèY‰,{Ðöðûèp{æœèªwlvÚjºÍרqÛ4ñ1 >BßZIXO¥Wy’;㊚GY@]‡=ê0„aB•ôâ°>”Ýà±ÆåÁQO”2ãŒTkÁ!¶Ž8$Pâ›c‚wj¾—Ð8û§qïéT ‘ˆÁ$3ç­Fò+cªãÒ€6Ḋ6Ìr’݆:Tži*]ÈÎqÅeD±•Q`3‚:Tᤋ¾^ø=èüw ägpÐUå•YU209çŠÈŽòOº¡XNjÊÈ» ÿtÒq:¡;XõÈÇ­ <»äsžäT$gæ°=;U‹)Qî#îÁät  šƒùzX Ä3ôZç„2Èß6p=kwQºŠiÖ2€íïéRÁj¤«JoûÝEqzý®ÈAƒØâ¹ÝŒSpÕèþ$²X9X6¢ŒŒßZáR4OºÂš{Tö¤‡(zSçŠnV½58 ñL ’Â.v¸ÀàƒU$€ÛÜ2­_|ÝÍ:{e˜ï,FÑÈ“H í™W#8š¨Ñ=0+qmwÀæÙTcænrkzÛGS¥(šÍ°œ‘EÀàð3Þ´-o0¢)XŸçVõMÛÜ ~íÔ2OZÏ63g•Å0:ybŽdkwÚýˆÖ´/5©ïlÒO,©êÀrEs6i-¹ùŽSÐÖÔ>DêxÁî)œú|Cycçše¹bÙZèɱÜs’iÆ0G˜3ès@ÐÒòOïp=ÅShÂ9PÛ±]}ÌQÛióJÁ@UÀÉäžÕÆdŽh@_°Eß–溻«xfÐm¤A‰Ê·Óµq–÷68ï[0êR½¸„t$ PSîjUr¨0~¼ÕûÛ†0<°0;ÖZ—ü¨ßÚ)ëê3Köç |qUÔdŒã¬0våô  +-N{'Ä\,‹µ†îzU¾g'åA“À«(ï+ׯjv_ŽôµÚ…Û¸}Òc%sAY §®zS$)Ê““ëÍnª‰3·k'¡<šé‘lÜê«ÆFO&°#šd8'ŸaV’äÿrsßhE¡.À¤¬¬Nõ’†‘‹ö< †+£¸|¹ÉíS5±%à‚)É‹G{î9¦´˜LFzÕ¨‘@FÎ}{ÒOsŽAÖ€*ÏT'> ô®‚o´½²I—‹øš±£´*9$ÐÕý)Ú+ÿ)ˆ) ÁÏJ¡#±vRÿˆ=j\Ž_´ïô‹¨.\¢©FÉ{¥f2»HT©R:©¦¢dA ¼XYUÛš¨±7ñ+ ú xÜ€Œ6Ú±#à…98È¥’9B¨7árF@äf¥IC“Ÿ©¤ c„*O­DîåïÍ[+)f¡rÈ úf˜%vÁÀã¾BÚIÎ}sZl»˜,•=MVx0äv÷ £ç½3Üþu!G#€˜ü ¹$Ð[‹å‚k=í¥ˆ‘É÷¬¹c†ÎÓíR ~;úÐ g\Æš."¶eÓ’q~n¹qc$$’ é@}¨þñ8õ5Wž)CPÕ›Þ­Gváý+1\ŸJxÏbhWí¤·=èûb’r™¬’X¦›æ°ï@và^Ý$# »«7Aõ®ÊÓWÃvmg¦Ü™‹Ï)]£>ÕÄxrf:ýš±áœÅ{3XÙ\Û0¹µAåŽX( ŠL7¿Ôî¯$3\HÎ{¬ç¼#8×G­I¥[HÑÛYŽìÄʹ©å–sòZB£¶ #ûcvÓ–ä7U4±ÄàfDŒ})“ÈT•0‘$í;š£Ĥ•äÕ+‹Ëȳ…T¿zÊ–æâc—v?ZÛ¸½X!>BnoQÐVM$’™¾b}iÐ^ËlÇ€Aê¡§††br… ô昼†Iw7&—øM1†$ÁíßñÐó@ –™'Ý©vñŽÕŸwÒ€ýjFïL¯iÍÒ€"¡8?JLõæœ=J²:R¯µ>^f lîz*Œšì´†ºÞ°UçŒYÛžwK÷¿Jàeh $Y‚GJÛ*Jížâ´5 Gá‹„¶¶•™]rYÇ$ÖhRI$œÒU~S•‡½C$Œ±·ñ1àTk«Z¥ËÛ>QÐãst55Ày#D98ϵs7vû¤CÆr+>I]>SšÞ·€—d~ù «y¦6Ðê2ëL tÃf¶lïÉ…áu ¸ Û’`(Ý*Ô)ŽGZŽ÷þ>´Õ`9+÷Oô«W1†‰\(ëÍR‰ö9í@ n3לú×Q¡Ž©×#¥rãUá~Þ†º= Ü\ŒzÇŠ»'î¥u ŒE7WœG~UX¨Ú8R¿b‹jîb8å}(Û ä°~í5¤Æ9PMUžIcïÁêq@^dP@Üqùb£IFÖc¿Â1ÍWITŒgœwëC\¢®9'éLÉ3°ÀÇCš…¼À>y õ¤óã,2¨ÇZŠGMØÉ Ú€$R›²ÜQRº}á‹1Ȫ«À$‘OI$%_Çj¹±ÕT•>µ `»€ÐÕ?µ=¹ãµDfÛ’0sÓ4`ɇÉÜïG˜äT‘Ú YOQŸjÊÍÓõ 36òÊЊ;õy=²iႌ±ÜßZ‘n]¤ŒP#´b~a´w©`N¼€ñBÞ*±Ü¤Š½o{rNÒqÇ\ŠªðËoò¬-‚z÷5ŠI#gØÙÞç5}®U~mŠÍœõ«pyw0àö p("ÚÞo,äìç 3S+,¬ßŽ8©ï¬e‹%æ%p1Y_20@õ  ¢U±çÐ ÔÚ}Â¥ÓÙU\¶êή6AàƒVaM›T.]úë@™ã’é[ [#µÉáo!Àƒx²ØÞgµxä0`F*øŠ[•†x¥{‰FQAǧÐRE®ÌÐ4O#2°Û€:žÂ¼çP·’Êúhe£eb ž«í_CøÀ¢oí+æ¥ ƒ1û±Žû}ýëÊþ,Xé1x¢ItVYÌ@sózƒïBzÁŒž„fœ3Þ«‚AèjQ'¨ªü| f¶4äûDÁv8èk'K†)îTK÷;ŒÕ¨î>ˬƒm\í9‡Ìhà "©ÎàVØ•Pr1Ú³l‹Íp ±aŒóÞ­È»TäG§j@gj–k/'a9ÐÖ`°2“µ×ýÓÖB9¹#8QÏçP«5¼cd »¹.s@ &ž"%_o¥6qƨvŸâ4߷ܳ°”e[³ýj"# XLŠÞ™¦ÒH°ò¡Ž:‚8ÅE.©j°ÊÁ½JŠf?gå‹!èÁj“D’m IP9§|·6ñƃ¡Ï\ÖI­° r£犬leWû¥ôâ˜($åGºMÈÍ-± íÝ“ôªVÖ£f6‘šÑšÕÑ”åPä Ò¬Ô­Òæàò;W-4RC3,kŒqÁ®˜Ì“Ú¬‘üÁÇùÍs÷E‘ØãæÏ<Ѐ¥‡ÞÞü d‘ÉZwœ2w©9ïÒ•UX1S÷… ,zzt£qtŸÃ®)Z%p§'ø§*\îúñ@X`ç¯Ö”FÊOR=éÛŠ’`SÁÂnžœÐw#}jN¤àãÖlzž*dW'.zPl] z\ȸèÜzS™ŽÅD `‚¼ÿ*µþ`Ï9‚¦RìûÕŽ>µR#òàÈõÅLwŒðhñšELÔ‘Nþr¸L`‚*šÍ$}cëS-Öìï\zÅz«Ã¨ØÅ8Û¸Ž}qUo4¨.S0®Oñ¬Ï]G%¬¶Á™Y2G8$ªú¥Ô2¤ï…cò¹ÝŠ@Auk%µÃFåFðš€ÄzϾÚWžK™ZIO¥Y‹hŒïÏÌ1žâ€*›d ã=@ëQÉl‹ÕïPjØH•°Ï½+G ¨¢€"…'Ê{Ó$…vår¤œ`а…b#!@«%„‘|ª ë×¥f¥³¬ešBz¯,9-Ïj×~Tp™úÒ€Œ:7^‹@m w œzTE_t'=0+bx“ b!è*! 0àŒúzPX\€±¥Ëàœþu}ídt$€0}y¨~ÎT€ry¦dónɧgÌaÛ“š¢S÷?Êj n!¾™  Ë6'¯ÊÞÕ•-œ°žFáê+­dz;ÇN˜¨<…fÀï@˜ãÚœ»s££îd;Xút¬¹´ëˆ +ê:P_§4Â:óÅK°÷Ϧ…¹9;˜šÎVàsOW9ÀÍ^WBIÝßJd.>öyíUb•|Çœç8æ¤ûF3°’=hb¿9;ñŽ©¬½2ÊIéLY**Uuû¾^쎹 ¼³žN•aE%dSêzÐãkp6ƒß,L~lœwÍ5vB škF7áü:T‡aœõ§(Á=0CÆ~éúS•$ ׌t¥fUä–'Ôrƒç¡è FÐ0<.Ù4²ÛXsëS€€O×™^~î}è¹A»å*qÚ…T¾@Áõ«é r\.îøÍU1¼lÇ*TqÓštn‘/É€Þã9©ÛP—nLب^ $6òH¿*r~ëÀ«±éð”`[,>öÞhŒRµÄ<…ºdÒ\[4r„o”ã9Î:¶!®Ñ¹3ü\tú Œ"mÞ[-ïH´ÓÌÓ¨C¿ýÞÕáà¿f-³iÊñßµné%¼—’~P*•ͦùY®eUW<н‹íõ?Üøš×Îh‡îæ@‡ÐÜVݶµámîÞêvóžXx÷n1úþ=½«€¹²aò«y蜩û¬±®~†Üz¬ˆA¢Àz'>1\êÀØèÑ+×hPp[ëŠòéï'¹•¤–BÌy&˜ÑNHǵDÄ/©4Ò°i ž{zRO;OåHŒÍ£ò©6KŽø¦›U“ÌP äŸZ·5¼¶²¬²²†ÎBŽMS¶R’+4ˆ æº4‚ Whó•v ’x€ÚÒ&2F» Ãæ­ÝIÆÀÍóuÛéT¬m"¶u]àtØAçޮ݋ˆ•'x‚†î§“H £óKåF é×j FˆaòqÔ H“ùq>V';ÏZŽ9É‹—ŒŸz­mdw2nUÇzÔ&ÎÑSýV\t.qVâ»ü¾[:‘ÓÞªM Ì:‚¹õë@/`.àù‡ <ÿ*§ä”~p~•¶ Æ¿2’ݲsÇÒ q²ä¦}»ÓÎÃ*kq€äN¶>À¬£j€½ËsQKbâ4N PxÂÊÓŸLÔøÜŒP±ès‚>”Ù-”ž2¿Z‰ v oÝøÐæ…><Ûi2vüÊ¿Îcq1äšÏÒ#š;ôc¸5¥xD9hë‘H )bCÓÇ¥DÈq…99⦖5É=8¨U°Ù“ëLc®1ØSÒcÑ•pzHÇ#­3–rq‘ëé@0˧ü¨°;€ÔšÆG¦™e=…L’"¦2w}:Ô{Ê¿Vö9éLo39+;ÔáœnîhžBÜœœc¥H޽YAžXcÔâ‘ £c‚ǃí@1ïùN8ÅJ²nG¶j!h 'Ó© Ø0‰ƒ×é@ ¨I.9ëRË ÙtëP“Ø|gµ"ë‚O×¥¥LlïRC½‰ùB¯½[ÖmÄwhÛ íëX¡ä €ûXwÍušO—¥Ç ÆÙJuçéš@s~qÜ6®1ÍJ×Ò:aŽÙºKØ4ë(|qÆ:çÚ¹™A`X /ažhÇœÉÆi#,8 Ïš­pÃ*6ý3Š]»HaÇ=Ei¤Î«ó( ‚¥ûZ·@N1YðÜm:†©ê9• wÀâ€47£¶àSŸlSJüÙP úƒUã’gžõd9]…zƒ@ UbÇ~i¦5brN}©&-Œ¬Ÿ7¡¦ÄÒ ,¬¸>ƒ¥ýfÖR£¦zÓö!%ºó¸Št—#iÉBÀ ñMäÏPF `B­¸äŸQBÚ‚¬»ªâ@6d& ïœÒ3˜ºçÀ  ‹b|²‡=3LM9ä9AÈàäô­åURØÝž«Þ¤…°Äªœž¾ôœ,fᣠƒPÉlê¸U#wÞšÝv|²0aÜqT牥)´àzw zm&6]Û°ýÆ:ÖMÄRC‘°õõ®¹­dWÁúŒÓ>̬­„¾{c4ÃI0Çz…±­È]¼Þñôn+çñgäB£ `rò(E$h°Ê6à;VÃh×H ÀÇz‹û6aóü@  Kʘ5E%¹L©5~KyðὪœË*ðÛ¿@G÷ÿ:± lC3U¶ÈGÜ$R#îö¦’êsG!pHÏ\÷­[-Qg Áúô®`O9úTÐí ËøR¶{œ›ö¤LISϦ1T4ëÛcn©2æUïž«3ê¶v¹,ÃrŒìS“H ¤Óc•?z#¿5Ëêz}´¿‘)fA–?5ÞÞ)‰C~êõüMd’Ã=irÞêÚ® ýpjÜÍ’­‡n¹ Ã/¾{ŠÆ‘&Ù"óê*H§’;“û¦˜¤2I|èAáÓªŸzb,öã|&‹ºÿõªH¦Gmñ1I;ã¯ÿ^•±»s~éÿ碔ýE Å­ÖvŸ"OBr¦£-sfv·({A©åXÜbæ0­ÚTgúE²ðDПƘÇCåIèzLÜÙœd…?ˆ4yP\sòßû§¥ –âÛäe="€,Ú.îPÙ 9ùzë-¡,TR:ÀÑ£·–w¸U)´m ôϵlÞI#„H±€1Ÿz@6÷P!À‰UqßÞ±ç–Ie9êÝ…[û+àn%KÿZGX•þ\äúö  ñÚÀ±œw«ënZ ~˜¬ó.7¯ڿ˜6î ×oMRtØÄT&cÏz»s©`GÌ*º1eaøP|M²\™­ —ûM–Ârë†SY’|­‘ëSA.æ€%ŽïrQT$VY.qœñE04ùÆ:ý)v‘Ÿ~”QHÜ;ñjvò_Š(U—l¹ôéS‰IàzÑE8318R–)NNLQE<¶ìáB­IbpÍÓŠ(n,ç· É b{b 2O3ÕŽ(¢€A.F ç¿•;xßó $t\J(  ã•–=»A9ÎÜâ `Ø;ŽìžPÊÉ–$Ù©s„ÀvSE‰û¦ùØàóšœ| 4QH ©³k£F‘ ®z‘Ú°'bpÌåñÜžôQB5öóœ{õ©>Ê׫ƒlŒ­ÑžŠ)žQ“ÊA‚k&ëJç! ÑEUþÅuRß8¬[x|\"FÊŒxPË]-CÚØ*ƒ’àdÕƒggk¿Ï-!èª8ÇÖŠ(ÄZ’ZD#µ„'÷‹sšõ›Ò64¬Wû¦Š(1¨ËÜ*ÐÔe¸nUUxjqøÑE<]S†\ãnÇ,r¶Ö`ÛOû4QH4|—$ãÓÒ£òË8 rGàh¢€'ŽIÌBŽ8ïMóYœ[½Pd‘Y@ÿ yòÑ)óÝ¢Š’8d@—!Ù_pÚ¥kÇ›’»XÔQEeê6%ùv㯑öURCœðÀð? (  %°‘ÁÈǦ*¢¤‹# :ôQL v!¹íéAEÚp6zQE9UJ…ùùô©g6[ÓQ@um»xäúÓHQÁïߥP‚n’Ùäç5.ÐßÆÛ»ÑE*§øwzs¨€ 6õ<œ ( ï6YpqךÝðô¢ ¶Æß0|¹õQH ZÔ{ŠŸ83»;VC"åG–ý94Q@ 0•&óžÞ´Gk"‚ÃvÞùíE‚ÙÉÊnz‡ÿ²ÈŠC÷äQE7Èé–AžÄœÔѬQ€Z|àQEZ­wHû•ºdr*Â5äÉÎ:š( ™,ƒ’ª_ŒTKsl²`aô4Q@EìQ.UIøM#ê°í#쀒:ƒEöŠ¿"$RLº«${cÛÓ¡Q@ £pÄâ5¥–ægÀÞ­P ÝÖ†`@Ä*§ŸpTŸ1óžÝ¨¢€³HϲYdïš'R_?Z(  3A!pUÛúSÐËÚÀ9ÇqÖŠ(ë$RŸžÝr:œU{‹ i" ¸ëÅPEŠÏ5#ÜUYôËvõl>œŠ(  Z:¸T¤÷k*]:âÞUVe 䃞íS-î¢)åJ ›óÁÿ ŠâÎXAqó¡ç=MSž;ÊŠÃ)lô(¢€&‘ÓÉ#1ä±éQ%ðÇ\ŸJ( ±õ«ݲq Ü=h¢€'Ff&àõR2 &0ß»&'þéû¦Š)ÇŽ9¡‰ÏF ¦€"ùÑzÑE06t˜Ñ£Äcj6XœdŠ×U#* m#Œö¢Š@6hžLä㹬‰£3‘×=½(¢€)HØ$\Ó­î6Ê£¶sE±¼OÜpFOÖ³Yv1úÑEg\ƒ¼ñšd}=袘 ë¹³ÅQ@ÿÙ endstream endobj 3356 0 obj << /D [3354 0 R /XYZ 89 721 null] >> endobj 3353 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /XObject << /Im28 3352 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3360 0 obj << /Length 1298 /Filter /FlateDecode >> stream xÚí˜Koã6€ïù:J@Ä%)‘’róvH±Ý¢©6ÅB±éX¨-eeyÓüûÎCY’í$@Ñž>P‡óøÄ‡ypðàã§öíüâ͇Œ’3­¥ æ« àæŠ%Zóeð%üi]>t¦b©x˜EÎv#R–å™À<ˆÓ‚å"qfËï‘àaY/ÌÒZ™²Û·‘ÈC³ë ˆ”%)Nb ¨ Ì‘Œ‰(œópÖumuIî;ãl•›²Ý’%ƒ‚Zj2"%“:sFÞ—‹µ1rôæ¾!Ç6»Gt˜úw&’*„ThÚr3œ•EqŠóµÙ½qÏ- ¯Ð»>ÅÐ,Mò SJ;ïn¥Tc­/±Â€)aÍžÞ­[³[7›%M²x7ôml r!r–¥ÏOq8 ­)©RËj…öW¦5uç=(kŸÝrÅoÞý˜¸à*+X¡”­l샗+rÕ×·¯pï&l`|Ø™RCx:wææë ““ää<¡-Í-ç²¶$Âëªi½êÆ)é@ù„Qvà©{z0nTYO Öû­i«…ç-»Ò©â ‡k gYtUS»çfEz“0 l¨M¦‹tiLM•jj_s–ëïXËr³§×ǵ¡A²ÚMøì^C Iž9’ü(—Ø7ð_q~Ô¼3›{sŠ­ù¶Ç|¢ÍN]45ù~ß–6­žÃ02—¬(ðÖF°­ê¯dGl)Î .½æCÙ–[ƒË_ÊÃË(N¥ºÛ*ʼnT,…á£b«‘§!SuOø_˜]"Å:m%@¾{¬ºÅÚâ Ò®qÒÒ««Y$„ç󛯳O³›_œžÃ« ´T€`éÖ‹jAN캲£.7e:4þëçKêëNñçq8‰6“uœDר’8g©.ha¯@Iøª‹c”@4DI¸ÅC”àÕ¢„¡ô‚ÑW ”A­Å¤Ç²Å¥«®êûÃÓ‘ó³›Ïן?:u‡•&¬´Ç FXá4„Õ`æ V§pš¬BÿVÂg\ÀÇX  4ïÚŸ`ãu"‡? õœañ*´X¥TÏVù÷Kl ¦Åy¶¤:Ô³Ûo*°õ_°•s¿;ðãjÌVÎi÷ãGlÈ퀶^0üšP0•åC¶Î¥ùùPÈ¡+ƒPâÇxŒœ}S8RdãCâ"•öÇ7}||#÷°Ë5»³èÚýÖ½Ù´agMÊÛòÞ ïÊîp$=˜§£1¬öµ¿À@;sæ¯ô`©ÅîKùÌd¼¶¾Ÿ_à! .‹p],˜ tÎ’L‹íÅ· ¦l5Vä•Iðæz+‹à]sñü¼M¯;‹ñÁ¤ý›c´ÈI•Ú¿8à¸ÏSòþC (¹ ›ä•cïÓknÜÓ6H ¦5ÜdŽ“8ûB‹iþÆ endstream endobj 3359 0 obj << /Type /Page /Contents 3360 0 R /Resources 3358 0 R /MediaBox [0 0 612 792] /Parent 3317 0 R >> endobj 3357 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./54_home_taurel_tango_manual_advanced_alarm.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 3363 0 R /BBox [0 0 728 155] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R7 3364 0 R >>/Font << /R8 3365 0 R>> >> /Length 1035 /Filter /FlateDecode >> stream xœWMo7½ï¯à­R±’ãŠA×E¤Es(Š@uG…芷ÿ¾ÃýàŽè`áÚ>hñôøfæíìÌê^( Båÿáó&5?n¼¸ýÚÜ7J¢©É_¯»è¾:6_ `¥õÂY%µuD/ˆR™H,­ Ho.h¥á0J°È9ƒNÖþøJÜ5Vzm5ŠÇ.%6oPÚËËéS¡Tšém›ß;Z‡Is©”t·Ï¶ÃÒq; RÔŒv(#×7Æ‚Dž~á0;4%”siB Kkï¤qˆRÒ{^ßÈ)ñ«5D%•c¾ƒZêÚ×Z Í)‰lŸ•æ ùÖÑY俤¨YtQÍgQZÞ…ÃÌ7&FÞÕiB ËØˆRÃQ:Ãë9µùƪ #0ó­C'¡6¿HsA˜ùuQi®ð˜Ê‹'« E ½#G‚òÝ *93ßze.® …e=Ý€ D›Ëæ*œÚ|ëAËÀÍÇ@C@‡z¢Ti.3¿.*Íþ"ósŸ–WAJiiÞ¯JÇk,œÚ ÞÊè™A^Q¿úXT ¤¹ Ì çêòYD*ÐÔÖD/Dê6 –sÁäaÄ*›A› òš`œA§Jw=PMô”¤šÎäH4 ‰ä‚ ¿VLsQKf[º†:™0´6»¡>yË9ÛONCƒ©Œ„Áº<@-}ßÄ¢†jè瀣üÈõ"U&õüu—s5B“YûÄzĨHwº‰n¨ÓG  ^hZ75ãŒ:ßÙþãýåPôè…Àd.—~-šfOÉýÿu3éȤ6NT† SwÊaäðâÇå2ž›ÖÍħ)*Íþ"ó‡0å5"Sã$æH?­Yç‰AãJ˜ '^Õo•@š  òÒ"µ£ð"]¯É~š€†Ž9qÚ©o=Ý’-Ð_7IüÔÒ»zÔÑô®Eû¹éßá)j阥´–N¡hS³XŸÏ§Ãçý²ý« G4Ñ^5 !¾íŽûåÍJSó‚Šbe¬TyV·²ƒâþaw<œÿí¼TÊ[±¢W} Ÿ‰"ÿ}ÞÝœÿ>eÊŠÜ3ÖRs2ب;Òëý·ÃÍ^|=ïúLh7(CÍ„yBêNè·Åºm7ŸÖWëÍÏËÐQiM}\o®ß]¿]®´±4âzð×õÕ»×Bõ”Ùr\ò÷ö}ã#uŠwbE2H!†¸CHp¹“¿\w×4íb:º i³ [š;ôGÓáîÓî¸;¥åʆ@“*tÐãîtw¸»%59…‹´ûg)cèþdVÓRK}hþEYÅ1 endstream endobj 3363 0 obj << /Producer (GPL Ghostscript 9.10) /CreationDate (D:20160114152430+01'00') /ModDate (D:20160114152430+01'00') /Title (alarm.eps) /Creator (fig2dev Version 3.2 Patchlevel 3d) /Author (taurel@wow \(E.Taurel,,,\)) >> endobj 3364 0 obj << /Type /ExtGState /OPM 1 >> endobj 3365 0 obj << /BaseFont /CDDUDU+Times-Roman /FontDescriptor 3366 0 R /Type /Font /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 722 0 0 722 0 333 0 0 611 889 722 722 0 0 667 0 611 0 722 944 0 0 0 0 0 0 0 500 0 444 500 444 0 444 333 500 0 278 0 0 278 778 500 500 0 500 333 389 278 500 500 722 500 500] /Encoding /WinAnsiEncoding /Subtype /Type1 >> endobj 3366 0 obj << /Type /FontDescriptor /FontName /CDDUDU+Times-Roman /FontBBox [ 0 -218 932 683] /Flags 32 /Ascent 683 /CapHeight 676 /Descent -218 /ItalicAngle 0 /StemV 139 /MissingWidth 500 /XHeight 461 /CharSet (/A/D/G/I/L/M/N/O/R/T/V/W/a/b/c/e/f/g/i/l/m/n/o/q/r/s/space/t/u/underscore/v/w/x/y) /FontFile3 3367 0 R >> endobj 3367 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3762 >> stream xœmWyTSç¶?1ïTŸ¤©Iµ ¯µÕÖ¡ÖÂmë„CûDªˆŒ"bA0g #$LBH€D@ 3E¡Ö±Úk­ÚáV{oÁuo{¯vX¥÷¾ûú¥o½{ßz¼·VÖY99û|{ç·{ÿöæP (‡“•›^´.Zš›šç¿_Ë,ç0+0Oqäý6¿%ð)*²»‚¸pbÅ_þa)î^‚ ÿFq9¹åd„4_Q˜•‘Yºú`tÜókÖ¬ýß_^ =ªøŸ'¡;Ò‹²2òBŸc¿”¦çHósÓóŠ_`­sr²Þ ÍÈQäg…¦¦¥¥§ù_‹MÍI?º++'+?_Zº:âùÐ6¼´Ž½¼••{´¤(ôQä¡QÒðÐÈÐèôŒ’œÔÂÿû„¢¨§·åIwí..y»T–*?©xwoTú;Ç2¢³brbsãRBY#êjõ,M b¨ÕÔA*–zŠ£â©íTA­£©ÔzêEjµÚM½E½Lýõ*µ—ÚDEQaÔVŠC=ÃâJPéÔ8ÏpÚsq]Ü_òzžàmçÝ@«‘ýJ¤/>öÒcæ…A ³m]ôQÐê ’ ‘Å Ÿ ÞœÀTÏŽ?Ãü»‡3ë6ém™Ÿ“zæ†PÆ#i>íòœ¶,©F$ljn”$sxí&§Ù!™ÄbïÌ{¾¥Ô"(TVÄÖÒrlE> ¶ 0Â^Lo`0S .æÉ‹œ¯fðŽn ó´ Ñd«kÚÛ¤J”:Ñ:u|­Â™.ß ²Ãй÷Úíý@Ouæ¼-!é"5Ê¿Qš %šµv˜¢±=H¹´-9G¹g·ø2Ô'*²t1e"Ö£ÞËlôrº¿ÁÎo¸ØÄ'6¬!b²üoÏáòÝb1^öâCò¸D#Ì\]Cž"‡woM;Ö9Z*‘ž/» wè‡g¯ßûáqˇ™Ùa¹;äïs s–ñëþŽ9ˆÐj¶TÒü9F˜†ô_¿tãêð_à{ø&÷nÌÅÝ·gˆ<4éàñWÈÑ=CS9lcíçú½ÍÖ3÷o”eß=xæU …G7ýîP|Þ~í+@¿«mê“°ÿ‚ä:Õ­8úâ é¼Ëf–ñUØÇ¼)HîÊmJcO^º†•$äã®\¶$C³OÎ&G¤o×z˜õM{Èû×qøíeüµø|SP…Wêx55å†ÚÚ*A_¯3ÓüVkIICÁò7¢ã#ô½;›$¹’=(k-‚QÊqi|VŽ£]..=YÞ¡¹L—‘ žÅÖPÏÆËlgM‡‘=Àèíªj[þåï¯Üž.êgHB¨ßK[T'¡K4Úë¼Ü“µ±ÃŸgõ(óÏQNæ1¡ßsçð?ĪàWÛ«í®òÆb8B“×Ðñ¨ü²iæá¨Þo'¦ÄS×»>K0%É葶䟌¢;x8#°„g”+Ô¥ ‡2“ÂrØ•l=̦ìy†¬"GžïÚziŸäæ®ïÒñ¸xéàè S\µ;®˜é`Ü«?Ïõ…8p%ÙËæ}[™XÿÖs˜æÙjMF±¡ÜXnЧÇI*«¢ù³:ƒÑPù$T×Õ˜jhþ­ÈÞ¦ž#W§NwžïkšK •úSu}$Á#ˆ?ûÏ_%W¢=ÌïZÕÎ;3x륕)šTò’uÍ“üÙˆøýJt½Ú®‡šhH+Õj]~IŽ6è´ãc~+¾GžS£sÕN$ÓÄŒÞ8ÿÙðHKW—x|<0 ñ#j¦=CÍï;E~b¹çÜŒæ¸l{`Kh«F»©šíÓnn*sÂg4Ãø3§c¦v“i9š­´ëØ¢acU{˜7<¦€EHT¼¾j—ä ¯ÑWéW»ðYÜdtV;¡ImÍ–Aí"ñ*tºÆ¢Ÿ\‰ƒÈ¨°Þh2˜*Їk?Ž?vÒhé1ÑþôÿæàÖ lP‚ÊX¤Ë‰ 7ábå$8DÐÞl9kaOQ¡á*»ÎsÐ"·ÈH’p5vVÙjl`Á »u µzK…:j¬úöx¼œ<Ús­êF0ƒÕa?…°Aø-Ñ95AdsSË(Û–~¶™ÌÖ föé/G_a„!—¾Æ«ÿ¸Œÿõ±@©ÖVª€.68'$8ÁùÊnUgÉÐ÷> ×mKŒ,öÈ::OxÚj͵IMS­,tW_ûèTWÞAq"ë÷*+ޤ—ÈÔYMóã#'R®Mœ9qþš˜ïˆ3·•žY>ÀÆ?xš}D^d{FNey©¶H--/:S:0.i`izf/žð'<ÌË.î}'»x9 kÉ™ ãxá×8ÈÝÕÓÒW'r‘*ÔSc3‚´Ú’œJ£V¡‘©=Bé˜bàtXzêX°ÞU5¡hÑôz@V „çÕ²«E*ü¬ IµfG£ÅåðHîá%ß’Ðc½Œ"Pª²kü‘èû˜EqnÍ`ÙŸ¹xÝü›‚ÊúTU~Å!(¯"° 5Ö5€èѦòT‰¯åÌf……sx~/Ùò`UÔþŒD™86`äìÐù»Óo’`ÂMÚw¸ã¤8˜Á¬Œ0?¹C~œ[ÆÏgnãíeººX¥ÌL‹Q„ýo»¦qPÂä"¸ãtÞ3³ì”£Ï5ì¤}ûß ;Õªíl[Þ'gÑ9¼Ý¯‹$o†¹ÆrNê'õr–Ô-åeUµÆjƒäÒMn4:«ÐÌRÚe¯g:ªF§ªZuV%æ‘Z¡©Â•ëMhÉ•TÅ‘Ê\uA‰\ F(¯×›åeƒ’%‰LV”ÝW8vóÜ%¼ò‚¯gÖ:úšm&‘Ÿ\Ÿ2Ýœ“_r™§ñAÒÎŒ¢h 7ìù £Ÿ/ÞùãCwÌ&i,±JÛ'@tªÝÝqiçÙM‰ñ²Œ£’„énxƒ&OÜ[¹ï¶ô‰»:Ù|_¥ƒYü¯2çL0msÜùטÛ_‚0­æJ¶ØûÝh»YídÖ_ìwŽÏY¸’)ðÕ“2¦>$Êyªtha;í{ÁJµ<ÌȾ§u£Í Êø‰fV!Üà;èä±u«ó”ûÝ…øÝ½<á/F'`:|hv;œ6gÃi3ÑÊÑéjg•«Ü£nÊ€½4ùùŒÝÛÚ§áú¡±m&"hÆÖ6A xú»¬Mµ–Z¸kµ0 £®Þ®~¯k¦¡»²CÝGƒïIA¿á+ãÐßök2öoI#/ïïžè°8Ʀ%fü7ÁUïàdï)en‹¸-Óž iô¼ÌäwRo|Ç /‚›ùÙ?ÎÍa4ür~•[n’ÙòÈQÜ(¼éè±÷wõrÁY× t§Ÿ ;µŽºyü÷äè‹ ›vоl}èµ[ýÄëa‰gÖ8àS6ÉèR=.'×ñ«<~¼/‰¹/ð6[GñÒ+GÖ%”¦fÈÅÉ™Æ55þyÍÞ"× /ž ¹;÷+æÿÀþÁ÷Ř@²ÖÙëuM ê|4Æ©Dèu»ü™Ò»ÐÛæ ›ßF|&— ò‹‹¥ÒöbowG{··¸#Oò¨ÿ1?Œq°…UnË<%ðU#xM§ ó×ó{¬x7¨~ñ¶^@˜íв€îäñæ@ß5ž‘lìäubN‡Ào¡r~˜áºç¹‚F^s½Î tŸM}Hâ+@pP­‰¬dãÒ¹PdƒÖi檪S¦ëw)Eê}~1»ªìA@R弋Õm:B™!_›KVù¸B²›ýYE¸DàvÚúê ¹ÎYǶ·MÕ8Õãq­oRèâáBæJÿ½ææsl3œw³ø=užsGú?\7»§8LVÿžrª©,IBý±©Ô²±ºPl½ªFh<ˆ Þj³XNvŒ·=Ñž¹SBX8 ÓEûá-v¡è:U+\§±õŒ÷·M}¹-?LB2ؽ§¢b¿5’ºPA}n½¦ FDø( Ó>ܼ?¾`ÿA±ârV×AH©:,’þ‚]qâå슣ÿ²ã7Øý™Åm˜ïW²8äC©±@/%KÉ_…DˆÔ˜ËÛkM¢òF74Cg‡í‚]®µ•¼Þ. %ƒd%dh«jõ M»Óò¾‰5©‘£÷+]Šáuø oÀÕzæuüŠïõ@o;m^ÌÁgÝç››>°ù…—,æø¯‚i_u Ʀ`™‡‰õà¯gáì¢kPÐl[ÐbŠúo²À¶+ endstream endobj 3361 0 obj << /D [3359 0 R /XYZ 89 721 null] >> endobj 1058 0 obj << /D [3359 0 R /XYZ 90 690.045 null] >> endobj 1062 0 obj << /D [3359 0 R /XYZ 90 515.401 null] >> endobj 1066 0 obj << /D [3359 0 R /XYZ 90 423.382 null] >> endobj 3362 0 obj << /D [3359 0 R /XYZ 90 151.853 null] >> endobj 3358 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /XObject << /Im29 3357 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3370 0 obj << /Length 2489 /Filter /FlateDecode >> stream xÚYYsÛF~ׯàÛ’@è±ä¶¼‰W¢cW9) ET@€Æa™ûë·¯ÁEHqí 1hôôôt}ÌО=ÍìÙ?/~Þ^¼y¬f¡úÊŸmw³ÐžöÚ²WÞl›Ì¾Ìßþ²ù°½¹[,•gÏk±ô|{¾¹^¬ìùï Çõæ›_ßÞ\óçw7›…ã8óíÇ»›ûÅŸÛ½y穞ì ö|X™D;¾B¦ [”™-ÝеGÍ–*€I.³ÝîK×uæõ^óàæÏ ÇžGežæOLŒòD¾FßÏ¿£2:èZ—•p—"+/jTº¾„‘×['ªë2}\({ÞÔBúÚDYZŸøeG«ÄuQòûsše",=³nn¶tVV¸ZÁÓ±BOŒï£üI³Ñuý¬uÎ/ÛÅDæOÅÕ•˜r{÷°y¿¹û7§]¾È(y+þØ5y\§…È.vü¤ý‘°áþôm¡¼y”5Úb÷öŒõVè?³¶Wªµ#ü4d’=Oô¶­r0¹ÈÁ4Ú¡«hÒhëȵãÉl ôL|w³¹~øtw»½‘éyòÏíöaDçÛC·—`›7ÏeJhZÒNG1z!¦HC¤äÍA—ieüšDuÔMÂ0\«ù§=ↈ{#h„Y‰VÁO%yGhs³ÎóXšQð-EfUGFãNÖrjƒ_]Õ:AgB0)ן§hUW‰Ua¤2t ­ xI늬/ŽZTâ«+Öï Í¢ªæZ·6¢óÞU©`O¹_E)‚ž@#œÀScÀOí´.!œÓ°YÔÔû¢LÿK˜z¢3t}Ê…F¶@BÍï™fµ‘Ä”X—u”‘‡¢É…µ©H1)“*yR1½ˆã¦¬äC*† Å@ðÝ(œ ühÒQ—æ‡ËÁ}Ù!ÁA©3H©Kƒð2HƒªMƒ ýÊÏ ƒh5|¾–æhI  ÉPf«Ì›(Z°©Ø½#á¿ýz)ßê)'šR=§u¼çtÁJŽb›T³˜|»6“'&r VäV”Ôq]6’¥8)†2¢'á²&‡åcñãü&ö$ÂÎ䣅ãÍOüµÈõÔf‹ø€MéNùµ ˜,+Œ5Øc»Qüšæ€JηÊñ&¥íÁ±›qÙ£¼…KAO]MÆÆ¡©êazñìÑIN‘Úzå-ÜÛÄN15¶Z¨}£õ{–Xõ׃ÿZbØ ¯ƒ³3£ëCÓ ‰I` uz ÄùkSû9‚¶]=w%ãâp`È‚$JÜH•SIŠà-àƒ,R:` µ¿cô ímtîî°FÁ°"'˜3D²>Ô>Lô¹Ðk~‚ÆÇ4Ù®ë­%wcŠùùð¤sÔ° ¯ Ã"ŒZ;Ãq*YfÿB§“´ J'&{h!kü,†óZîþFàµK#ˆ,[[ÿmj¿ÍÍQ‹jå ¬.™$›{À6T¾ \Ù WÝŽ\é}pÀµ}ŸsT›µOqQð) 3¹Ô}ÝžäE˜%MÉ7OÞjx`Á¦‹dsäGH7-Êeø ‘-‚£§^™«xzm¸zà÷FæA¾¾y >Íü~âþηSgAÓõÁ±9¿=Š3D7onÿNqm­ýµéláôòp,+ uª+¼   ó¾Ï÷,­ÌT<·‰%Eu‚éƒ!ê6¨I0D.„`–ÊT EÂYJJ ¸ÎÌ|²á`;A/vüy*4áöÏ/ׂós‰,Ú”|U³O¢¤)[Að Ã#Ü=÷z ÞÚr|ÇXú‡aù]ñýtuõD ¨º?µ_ñ’³ò-Ï ÇnZ*Ðæ#cçeÅϲÕúUŪÿG©¥ B+°×£” æºôÕ’°rG'sØéîg,wv™¢ß¹ÃÜTdÃäGXBíÇ®V•åÈQéc]Ò| ùvª^~î‡ßË7§Ÿðê>Åû/¬›!ÊÂG?À+É;­ÅU‰|ȽMµ@êuCø*‡øn!:¼àíÉ#êJ;ŽaOÝÉ,SŒYL—áš )*=Ξ–QîÚY|žã£!¹äÄ/—Îð ±=úºÒÛŸ‹1nþÅqQ&rj”¢jþ½@¨’õ`\Üä µŸûó¡¨ÎUéÑU BÕôz³h÷º®Ïó|åݱî,º êÙ¦‚bÏõŠ™NžôßbЉ¢jðt0Hr]‘Ùr.@Ú@$Mi^)\#;öódò4¥î²”à&=Ú^—8i›8Jó×2t‡ÖjÕV±a&ÛÑÕéi*™ysr}á/ÏŸ?¿ÍÚ¶‚XŽïÍ.éö"†Š9ñš,‡–úŽÙðdmž7Û‹¯XF }ÑŸ…€ 7˜Å‡‹/Ú³ÈI+ƒÙ31f.”ÏÆý²ÙýÅÎ$þNŒ“y endstream endobj 3369 0 obj << /Type /Page /Contents 3370 0 R /Resources 3368 0 R /MediaBox [0 0 612 792] /Parent 3377 0 R >> endobj 3371 0 obj << /D [3369 0 R /XYZ 89 721 null] >> endobj 1070 0 obj << /D [3369 0 R /XYZ 90 651.4 null] >> endobj 1074 0 obj << /D [3369 0 R /XYZ 90 509.497 null] >> endobj 3372 0 obj << /D [3369 0 R /XYZ 90 453.358 null] >> endobj 3373 0 obj << /D [3369 0 R /XYZ 90 431.375 null] >> endobj 3374 0 obj << /D [3369 0 R /XYZ 90 413.507 null] >> endobj 3375 0 obj << /D [3369 0 R /XYZ 90 347.689 null] >> endobj 3376 0 obj << /D [3369 0 R /XYZ 90 303.853 null] >> endobj 1078 0 obj << /D [3369 0 R /XYZ 90 205.597 null] >> endobj 1082 0 obj << /D [3369 0 R /XYZ 90 136.546 null] >> endobj 3368 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3380 0 obj << /Length 1517 /Filter /FlateDecode >> stream xÚ­X[oÛ6~÷¯ò0HkÄ’ºËë ¸‰ÓvX/‹Õµ@[²LÛjmÉ“ädA±ÿ¾sD2ºD^]`yM~<ç;†jkjÏGÏ¢Ñã+ßÑBz–§E+-¤šOBW‹–ÚGýâÅäm4½6LË¥ºO Óõ¨>¹4ªÿi0ÛÕ'¯/¦—bùj:1czôîz:3>G¿=¾r­–n»œ\«fžB#*Áô¿¯mo7m×&–Ç4ÓòaÒ–Z “Y”ê<;ì ÓƒQ²ËR /âb9Ãr“žºMÆHèÊZRÁ·¡EÛ0mÜýúÍuôB(úU|èù¼#ågoÞE/%\)1Ì¢®€'<)ð~:‹†øï?¿ ­C“¡Ür“§KþÇh¦ñ8®ª"]*>_ÅI•wŸ¨Ko8ŸDq¶ÎÇã ˆÔjm+ ¾çƒrâ;ŽÐýs½â’Ð÷µÖôSqÎO ~¾MË ´²ZÒ´J|Ëê"dtÐ Ò$ŒI›üº!³¤D´áS`¤¾U-ÉlF\*AÛàåtµá ¤Ÿ3~+Íh$¼’ðÉlŸ8ÓäÈ#Íø®äÅ%_Ňm…JÞù^h–ÇÎ÷03èT¦h%ýR„l-M¼|[v0;{ dßœŸÍòCýÆeŸ÷>ÃÄaŠ˜m4¤äÕ¼þ%NÁkߨ°¯«Ç|Š:–âÞµR^T)¯Uµz¨P9ß— •ÈþPnæ‹8ùÚÒqOð]î`xQƒéhþ1Razt8Ì×’Ýèãgª-aT?ôµÛZj§Ùa”ÃD·Õf£?Dší¤BFB¬8˜ÊT®Ý¦™”™¾@ò²YÍ=ñ{É?Qjei•晘ÉWâ[)´/âF­tñèþL3µ!-價úßñn¿å÷aÚ³‘„æ¹5ñ‹È LįTQ“;Ì ¦–âÇmZmÄH€…A,L(6ã8•ߤàqÅ—P|l×ÑŸñ$>”ü^QÁ»ÒY.O3Àpñ”““k^5Dè Gto«@€qVE¾ûž…Û^9o„Á$wâW\È­7¥0_м€ å ’†nÊ{Ó£åü:5,ååò¼w“vJ:-¾€.1¾Ý¤ÉF “<«â4+{ûÁ…2Áª¶7¹˜h"}(¨[÷ò†™~šê®u¡ åIŠ\9r_Qì ÔW\á²l2ë%ʶl}——•%qÉËsä:Óãí'-:õr¾äbt›ŠU[_È™øPå;`IûîÄÔšgHćzrºÆ‡ƒÈ$T‹¾v¹}Œßæë{1+Ô_J iyœÏTqƒWÄIrÌUÆË’ˆîͧ­”…–‚ŠIUB,Â6Oû^Uè=s·ãƒŠÑ‘³ӭbeº“£¯ÌàúÛ-_®ù@G‰¬ ˆ4Þ³ü@/5mýPÅ:ã2P™–î!L¯QÀÜ=^Ø#Hƒ‚gxcÀ¥Eßá²T(ÂÂR*qÈÓ›D„Øö> endobj 3381 0 obj << /D [3379 0 R /XYZ 89 721 null] >> endobj 1086 0 obj << /D [3379 0 R /XYZ 90 328.152 null] >> endobj 3378 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3384 0 obj << /Length 1257 /Filter /FlateDecode >> stream xÚÍWÝoÛ6÷_!ô¡Ð™!)Q¬€—8ëlÝe}h‹@–[‹,e’ì,ö¿ïø![’×C3 O¤Èã}ßïNØZXØú~ô]4:¹ <‹#îSߊn-Ž­‡{ÌŠæÖûüÍä—húÎS†í9cæc{ráxØþÍ!.³'?ŸO/ôõåtâBìèúÝôÊùýxrÉh‹·'3$+ÖÄ÷$Ñe@Ü¢7äcÀ¡«ˆ"‚\gL0Æö•¨ë4_hñõRèM\×e:s(¶×µ9Ú8γµP [c"?Ô~¨áEHí´’«kßUå;eBÔ…&¨„¡ÔráFÉZ-T´kø2—‡2­z´®´Þ°)p( }”dqU¥IœéÏ !o®–EidjneoÕ*Ê=Æñ“´·;ÍÁÊqÖÄüÕ+¸¸-òõJ”q9DÞå¾)[áê¶È²B2~Ðâ‚ %Ìþ3^Ýg†F¹Ö‡¥Èõî±XkÚe,}´‘/ qR¬îÓæe®Ìî.×R21_ýVi/‰]Zj™31¦yÚ˜™ðÞ ±ÝdKU­W¢I¡¸î%S›¹:PVµ)ª¸õ<ï]¹Ù-ÄÜHÒø­àè#fø<.ç{rá‚t*¥Y§Ñè-¶ˆ¬\ŸøÈ\+Y>|ÂÖÎÁ(àõ ¨V–ËCݬÁ̺ýºÇR!Áíú ž,˜Å8C!3uH ½)Öj:cvZu¹»/Ò¼®Î†bA‡]ÃkS¤†ÃObszZŠx~)7!Ò;Uت¨%ÕK(¸Æ7}žžáù÷Ð%ƒ, Bk__ûæZÛ¡e}«—«·×Ñ›AËótB 7YëRé—šTtðah4ýç¨{ÐÏ ÿKˆUH;ˆG°‡¸çY^€£\ë‘¥Mª½œêZyÛ§yUÇyÒ$öm/Ó»©Û­•"Y7©/’C͘Ï{†b±ÓÊïh}¶>SYñq–þ‚ܾc 3nö½]¦˜ý.’º«†n°i€ù ¸HßÌ[ŽåÖ3c¢£Ö1#’HVè Q? M¥¨ÖÙ¾&±‰O«ßÀg¯ßl¡{È7=!I17»¬(îŒÙYz'[®8.©‰‹B°ìÿÁ-—»SÖÅ-Àcž,Újy6”|_7Z±.ZUËR‘A‹žF©jùLECˆáσPÔPpŸ&Çäìñp¤ýp1üCˆ1$ð),ò¿",:ÆàIMïÚ]Tï Zѹt7¼S3º_WñbÛX:`9f×|Q4Ø”Š¼þìÜþ^þ’À$-™¹T ¿rQø¨™¹Ô5ÌÁ\ VÓ¨$‚Î&ÊúD°uK¿ÉóženÈ×=7K’Vd4§“Û²XéãÑ4“þCwIøzeœtçfç¼i¬°SÓ>¬†¢;wcC¯Ç“M@Eæ}WæPå—ƒ½¹Zˆ\”ibètÔþa™&K½ZZ^˜»Þ\ÏÛs=7sý€¡ý)(Ç{?#íòøòDEHÏÜ€d àVŽh¸ß€¶‰±íó¸ƒá`ûÍ\lê,qC*‹ð…é3ðþÅ·)Gaö'n-o7ž'ñÙ¡¾ÖèðúõAroÈØAãf_dÜ~Û;¢‘ï†óAÛ ùPzü 'ÛSh endstream endobj 3383 0 obj << /Type /Page /Contents 3384 0 R /Resources 3382 0 R /MediaBox [0 0 612 792] /Parent 3377 0 R >> endobj 3385 0 obj << /D [3383 0 R /XYZ 89 721 null] >> endobj 1090 0 obj << /D [3383 0 R /XYZ 90 690.045 null] >> endobj 1094 0 obj << /D [3383 0 R /XYZ 90 227.26 null] >> endobj 3382 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3388 0 obj << /Length 2153 /Filter /FlateDecode >> stream xڵ˒œFò>_Á‘ocÞ ¾F#[>¬´š±/’ÃACõ4^ z¡Z³³_¿™•YPÐL¯>Q̬|gVá;OŽïüxóæñæûw»ØÉ½< Sçñàä¾³ó3Ïç±r>»w?Ý~|¼ÿ´Ù†‰ïî¼Í6I}÷öí&öÝ_7A”¸·¿»KÛïîo7A¸¿|ºØüöøó÷ï’Т#á$…“5é MèÆgf–ßûÇ›Ý0ôùJ3ßó³Ð)ۛϿùNë?;¾·Ëwγ†j(ϼÄÇçáæ$ߌ‡À½<Ž4ɼp'MÝ !ÜF4øa³ß}<òF¡T_ï7¡ïž/}Ý„‰[4gžÖ}Å&HÜ«¾(•¨x«c"ô¹ûî;íέè UËÎ&Ùמ¨d^ž$KFÓíî¯gô­@̯GÙ«uÁ{À:±ÅiˆêݤÞmy©Ï\ïoð臓Õö|"B œ“ìæJÕ-ZI0R Í,‹ÌHût6dÌ«gÿ(ÔLi_|?ìµmˆ¬v¦†¶@`Í—¹’fóÉÙè¬Ng¦o¸¿š¡V%®KðÆhʲ* 3Ès_.Õ7Â=n2`‡2‚Nˆ£Àó<¼ J´Ú·kÕ†Ç ÛE©m»hglëÚg`2QmSÑî^”ÅyD:2kò÷º“Z‡°Ga’êÈü}©HØ¿ûðéÍ«2ÉÓT^`˜X‰%Ë·!Q¨ˆB]»,Ô:Da…5 K‡^¶ ­ù„Í)8‹0Ókšk\Áeª OC£¢,ÅÀ§?ôäk»`úw¨EÉÇ€D&4`/qþ† )J§¸è,UAí2#ïngx†µqóBDXÓöðö¬K ¬6[ pŸÞ Áˆ¤1›î\ºÖ¨Ý‘6|AÜâ ÃHó0^Vl[Ö}yn ÒWªA¸3Õ µ“‡/|•Ù-e§@P½œp.LÇ‚‘~ëiöÔÉó50w]˜ÈýPúiŒ«åÝqåIcî ôN“Ò혛È#ááooy*U)hI ×5W3Ýéˆc/M‚¹j§’<=-ÌÂXÙn=Áà;¬æk8‰²Æ¸B¦®˜ ßÓr7ïO¢ývƒí/ôCc0]ö¤y²h¥îdÍÛ˜.3f`Œ–ø £½ö*0½èðõk©“Î. ‹Ú®×ÁrÌñËiá¹zHê¾¢’|ç%YdTrw¼§kâ¯ó§L~Æ©nϾÑbIê…Sˆi̵­Ë§‘ç£45óÑU>ùœŸòô­lÆžŸì&6åé¯á’Ž™qi8•õ8}ÕÜ‹ƒ‘ÕÛföǯNæl×ÿv6 ]®ïgE?÷ó«33X #Ø\‡«i8öb?ûózÈ;ƒh^æW»BâfnÎâê;¦õ;è¿Ç!. endstream endobj 3387 0 obj << /Type /Page /Contents 3388 0 R /Resources 3386 0 R /MediaBox [0 0 612 792] /Parent 3377 0 R >> endobj 3389 0 obj << /D [3387 0 R /XYZ 89 721 null] >> endobj 1098 0 obj << /D [3387 0 R /XYZ 90 630.546 null] >> endobj 1102 0 obj << /D [3387 0 R /XYZ 90 599.49 null] >> endobj 1106 0 obj << /D [3387 0 R /XYZ 90 332.221 null] >> endobj 1110 0 obj << /D [3387 0 R /XYZ 90 309.221 null] >> endobj 3386 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3392 0 obj << /Length 2444 /Filter /FlateDecode >> stream xÚ•]oäÆíÝ¿bã‡B[xušÑèëZpm_â"ˆS{{H‘ ­vìU³+íéÃŽQô¿—RÒH–ïÒ‡…fH‡ärÖ[<.¼Åw'[Ÿ¼û©Eâ&¡ ë‡Eâ-"/v=,ÖÛÅ/ÎÅ÷ç?­¯n—+xNä.WAè9ç—Kå9—œó/®. ýáê|)„pÖÿ¼½º[þºþû»´x+d„°³a-‰N<f±êV2‚E>‘ï÷Ë•¯"§Ùi„N¡3]×iõBðcZ¥Ýèª&ôCYMËý>/ š•Å'Ï“m•6yYEZiÂÖMYé-óbÄ'rÖËØsÒâ±$ü6mÒMZk°JèyÎz§+ ›ë3T TZ á&Ò0‘‰% N^ ƒÀ¼¦oQ64Ø—5ÒГ‡ø œ­^ÊÀyÊ3f_ëêi)§#;V%Z‹‘MyäÕÅ–•®›´böŸ¼À+«ù­Â/m5£ð°1¸FV¥õî›o€¿p ±Pn¢Ôxŵ‘"býc'Ý×%AŽe]盽&xÃдmÊØ-K÷ûB¡qIŸ¬<XרRðoÒ4U¾YJÏiòú9oveÛM­‹m¾Zl3XšØ0j¶šSmd:O æéöyÝôn ls»¸Cf,ä•þÜjãÈ«<0׬ܒg :Ê”À»rË$`+Öf9oEÎ €¯ÉY—ÍóRx&`ìCY϶" " 悉±ŽíÎt•6ꃺ~"œë¢ãcÔ†5Û cEAŽX˜d|!Р¯«Û㱬K2â8+£gS©À,ó‡µAg8vÍÁ‰I »Õ‡›Í¿êq`‡tÀ ÈɃ0 ÃÔ ä; ßÑôg¸)×·ظDäs/ØÓ‹&ö‰S>ÌiÑ­)›Ö;ZÎÉ•g4a™¨l«ŒÇ£¥í~Kã Þ«¼itáŽnãî{µ>ù|"`è-Vdð T‹ìpò˯Þb pÔ’hñl¨ ?‰ÝÀÃ{~¿¸;ùÇ+–¦êž]¥€E°|Ï ßüb.ÃÈåJH¸mŸÊ|K÷î¥~ZC2¼Ø§uýþ=äýCšÁUþ‚iÐ仃úÌê?sHÅH×uçМ)nÞm·‡Ówm½»ß¤Ùo¸k¡ŸI¾ë›;Œt7„ŸZóÓÙR!4Y + ¬5Þ¿¿¼úxÿñæúr–8š!þáæÇïÎæŒwħÁ|ó»'=ÍEY@\ ©Q´‡®Nјøû ]v›Dñ˜ðælÓ™×®¾­usÏYëþ¨«¼Ü"NyÞÀz"–_>Ñ9Æg±þœ9„𥠾âbtÀ`;Ù“Æá_ùÎÄðöƒØ óJ¸Qç×6²œþ–öú°7&ëݬ©ÜÐ÷'b†_r_}Å\1R·ÛÎkécœ÷®Á þMp:ëbý'c‡¼[ß^O]’‘Þ„þöêürìdÓb*úñ-¼í[R~ÙXÒ·}ë«)RªÐ¼èÿI‘&%Žš%áQ)eàF1÷äH¼á¾7£"áâ0_$îè‹÷+~Á640õÌ}ƒþ4¨ 4?IéÛ9LJEˆ”y,ÌCð¶X=ì©ô-åü@º2Q]'øúÄfºG8óÈ•þ$Ùôµm ŒöÖ(œ‹áR•0xñ*ÒnÕ !U“@”Ò||ßÛœMáÃíl²ßÐÚÁ¤ÙA9Ë{SM†Ð®Ù ¼1uÞÔsÑdÙè|eÕ)PQà phµ|.ÅVí‘H4–)¿gúȤù}SBO+!¤€z)K›~Î:û“VyŠ ,îj.ˆH_Zž†“]Š¥ŸÐí¡½^ºÑº QUQ>Ôø¼jóB‹¨À¨.”Þ¸Z…ù´B¯Áº¸Qƒ…¨œ…"óA–ß³`]—7Q®Nº+ªì !ƒsÙýƒñD¯+ GÞ0ÄôÛËÙ§9LqŒajeg SDä\&n56'EGŸ²RôâHzo÷æ}kC†ÇM£ïVûЃN‹šà¼a‘7iß ^1eIÖƒ)hÎÖ³»Yc¾ÿ6^ɃJ{?¢ÚæÙ®¬ÑÕpLY ±´·.q¾~ $:'Ç?øñ«#P¡õ¶&*‰Ya‡»3Þó!s¨(é{,ó¢!TÓƒ(êã>£¹Øs] Ci9V(Ç„þܦ{ …ÝL„Ùè}ß]À”TÊÃK-¸qÙÒ¬o/BÑ=ß´IÃ7M3гdŠ,+[£5íRñƒœ>TZŸ2>?0<Ì™\i¸*EG«Ì®Má|éFW…ÑPüš‚UBÍo#ŠOüRrSjÒÐy±sÃï”mÒGs§¨ Û1ƒéÙ0è-t8€ÿ™>xgòºŠCVjì=ˆiáªÁçp<‡0¿K¼šqÅS¾ÕÌ<%½¢½°ìåœÞÑJß..|+ŽaŒÛ¡-h‚Uá~k|ÔïÞ Ó}·eDZ­{~ã«] Ø°E“ëºç£ëW8š§# ¸·3ÕÞD-×T{o—zaè*Ù‡g3CW†IG¶÷_ç™@§Çݼh^³‘›xýÿ褀q õyÒ3Æÿ$_ë–l,<ç@½RÝ`Tî†nO†±+b1ï æò¦òøñÑ]A(«‚èR_Ð¥²`šÊ¤ß•!Ê’gs¦¥ý»¬šö¶8Óoª¬™$mRAþ €¯”—þ­`Ìÿèô«ê£ÎrÜ'£…£ÂcžJ “ > 5: ÎÆ¯•3» ʽõGÖ†#UÂyKYú ÊI;Ë!|qLÊÉ.;J1©eÅ«º1ŠÒ,âôF¥p7´#Ô00ÿnuïEgo5²ÿß@‘ endstream endobj 3391 0 obj << /Type /Page /Contents 3392 0 R /Resources 3390 0 R /MediaBox [0 0 612 792] /Parent 3377 0 R >> endobj 3393 0 obj << /D [3391 0 R /XYZ 89 721 null] >> endobj 3390 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3401 0 obj << /Length 2425 /Filter /FlateDecode >> stream xÚµ]ã¶ñý~…e Ö‰Ô÷½m.{móPwnƒâ.8Èm+‘%G”²çüúÎp†¥Õ.Ú}É!‡œï›ó&ØüåÍ÷û7o?¤Ñ&÷óD&›ýi“›4Èü Š7ûróÙ{ÿׇì?nw2¼Ôßîâ$ð~ØF÷¯­cïáïï ð‡Ç‡­ÂÛÿóãã§íÏûß~ˆ¥ƒ;BÄq7Ô"IqÓ›€³ÙÙ ;™Â¡¶U=`ϯÒômZ^¸µZW‡ZѬoñ›Âj]óÊ…A¥ÚÊØû½:òüØ^¯ES¾-ú¾«[xCÏ §ª¿Ð¨°—ÔuÕœy¢ºª-i|Pu‹hŸìe­Vô‚R} Ù(»ñ>>vÁ@ìN?™Å·®Ä}¥4°7÷I)bèÃí¦š²úÆ3ú´ }gTÁüVtÅUõª£©á|Ϫ§AÁÛ:u¬4ŸÑ÷¦/¾Y|úØU·¾²œZ‹Ê¼œOOoERDäçQ4§gáÍ?Væ…[{ê3‹:؈M‡òÆÁGúgOй|ö~¶$´5¿½Ö­1ÛõŒªsWÜ.Õ±¨_àÍ(E˜Ûtº‰õISÓÀÑÔ¥K&~ŒKHWꇾôåv'‚ ðÞXFÄýeíºþÒmEæ©¢Ô d=·ÔŠÌO2ºìS_›G(#VËhÚo3 º9·èT­ NÒïà…ȜζÆ3ž X«ŽDÓÑD{TZÓäZÜéÔ¥@û öÜ$Õn[Šñ PLÔ¦¦8ƒ-¬(~a,:$S _À¢ ÷> v£~°^5º/š£êd.{ÅçŽíP—4<(úZrx÷šÁ퉾/2Øng¿zìi¹Ÿ!ïÌÓ-ïÌ[È£¬R|Ämä${é•Õ ÑŸT§ãÛ°½+Ÿ¶à ŠNѦã¥hUÓä颵 É4a_¿8@,“Öy P}kÁ·k“Þ— ö—·U£Ð:,´na´BO_]U;”¨š¡ 5mŽåxéÚ¦ÒŒ#²‹\—jun(zzßßiW©N†þ¡îàG¹Ä.‚hR6‚˺úƒ¯«¦¿“"Eä ZÇg¯‰ÊhQbßлè`ÜÀ x¿l…§Ž=òN# ‹Ydɤúfb„í¢cí‚= ¹ ¾ñ%­"ÖªT×ér¢ÞuoFk“™µãip ™6 m]m5O(š5’'ge^Já$“!ùuœ/(-¢þá··»&—¥,% @!áEƒßÒh1ŽÍG‘Ñÿ–ÎOq‡€…Öí±*zÅ8ûvºÝ¥Œ]÷2Ìì£Hy­@W{KÐ<†pXÞ¯…A>ß1 ¡–ïæñL$~fð ðõ’YýEÊx¶ ‚AèƒÌ’Ü&JÌɯIÂÔD’¯ÈįFÉŸG¤~Ñ+°Ä›|äy˜ºߪëÀä6Ãõ`Ùa| …®)lÖp&qoޤžG \©šg1‘¢ž“î àL(Âÿg@EOkœ›.9ó)Äe…ôub˜‡hãúÙyGãPw"ŒLJ;£•3%é Xk3 @»-ºª¿h’ï]&ö™ÂyU?X¢ù?ÁB±…÷oÈÚAèA¨%P¯õ¯´¸–Úˆ9“ìíqÅ:…£SÀñ¨~0F?Iâ:L!™ êÌÇ G0Í™¥ï$lWSDúñ$lØ.ÖTJ )ì&‹{.¾â0ó³\LJ„$ý¾†[ ?ÈÆû›òu²%‘mÂSÄ)M¾Æ†šãÜ!Y®< R¬ÔòlîýŠØõL™W¦‰Ÿ$ò¿àf·£4¨|Øe¦‹‡üDÉëh:õÛPYË)£lù…ëð bcàäÖË» ÃñÚ©”ŽŠ«ò;Ú(DÆn=Á‘«Y¼Û Ð9Ï"ì$p\ÌÍ_ø‹ÂgCañ©5lçjÒ ¯†@7Ó€¨ˆ5hs&sä (mÆÁ,ìÁ~ S>kTÁûókL–;)­ä°>Ã99€1¬k‚¢N1XÉñ¢6D'ñ¼N–£ó£Ü6'•ƒH[šO¢ÍƒÉ\p„!Ä|LeÎî–GéÃvJ÷rH¯·úNkEY*Æ`x”[-‡…Â>-Qm±ñ“z~’QŽÜ*ÇšsËeSøøîz-ŸÕ«ªaY£WoÚf®‘­tQS‰eÏKú²œŸ0T/…õ™9èá°3†°Lx2? %¨¢k”*5öÐrb®cêoÛl6jé;Ü€ü¾JÏ—ùµ¸œ(73*æ…Iq`êv5aJvÂ[™ç¸›[ rÞÞƒî±Àð•ö«È×Ú¯ˆ–z8m±€“¯g/XStŠ­bÖÆ•±¥ °ÿ­!lú‚r,Áá> endobj 3394 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [140.899 655.176 152.854 663.923] /A << /S /GoTo /D (cite.Jive\040doc) >> >> endobj 3395 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [405.821 259.066 417.777 268.032] /A << /S /GoTo /D (cite.Astor_doc) >> >> endobj 3396 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [144.037 247.33 155.992 256.077] /A << /S /GoTo /D (cite.Jive\040doc) >> >> endobj 3397 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [483.318 221.263 492.503 232.167] /A << /S /GoTo /D (appendix.A) >> >> endobj 3402 0 obj << /D [3400 0 R /XYZ 89 721 null] >> endobj 1114 0 obj << /D [3400 0 R /XYZ 90 639.445 null] >> endobj 3403 0 obj << /D [3400 0 R /XYZ 90 437.452 null] >> endobj 3404 0 obj << /D [3400 0 R /XYZ 90 393.617 null] >> endobj 3405 0 obj << /D [3400 0 R /XYZ 90 369.706 null] >> endobj 3406 0 obj << /D [3400 0 R /XYZ 90 341.811 null] >> endobj 3399 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3411 0 obj << /Length 1306 /Filter /FlateDecode >> stream xÚWKoã6¾ûWèV X+$%ê‘[šG›Û]o/›Â%ÚV!K©D'›þúÎp(ErätчÃ!ù}ÃyÈÌÙ9Ìùeñójqq‡Nê§‘ˆœÕÖI™³Äg¡tV…óͽþõêÓêö³·’¹±ï-eÄÜ«/dî¤{õñúö†–ïn¯<ι»úúùö‹÷çê·‹;)Fg‡x°Œàfs44Z0 æt¼]-þ^ˆ(ñ%L™$‘/¤Ã£‡€~œFN~X\ÜæÜ4‹ß‰ÏäNÎB? CG$Ò—AB7ß×8rõ¾ìHR—î÷ìðX©¨I`MÑÒcSUe½ÃI ÚVeEׯ4I]ùµÖÕ(mwXEJÃÆÌ=jš4uõBRHÆ£»¢é]Yk/hu &ðHÝ•±A7:KNL—œû©´ÏÇaS \C3ànYÓ<ßg­Çw§hÞli=«*R U²Ùü¥rÝÑB«ªLÓŠ n`Q(OH÷©ÌíqO~‰.ºÐªÓKno¨‹ó6Y±pÌŠMù0€ÇA>f¬ióÁ9òÁÑð d:ð1‹=œ |p‚|póÁùÖ°FÁ€ÕØcté¡›á8ø>F¾Ã‘ïaÅøƉïÁè V»WÒjVoiÛc¢/^$] ù8µG†!™™ÀÁ±&õ$pŸ=ޝŸ?æÇmÓRÍx…ß‘bÎ×á‡ók-Q\±º…æä^ÿäIéšË‘FgÒ ëÊM¥HOIŒÎ6~SdcKD0NÛ`œ¶ÁP"ÄP"@×6»6;2]ææŒÖxx|è!#Uànu®ËÆ—#ÖÒò|úSXð”A=jŸ°Æ©–æ\ÞÑäØô(âõT¹ƒq埤¢¯Ü_uY]^B‰[[æk í±‹Ä×Èyt˜dðÏgZ—ÂgQÒxPzß„`£ 8Ô+#ä&ÀŒªù/ Ú ÐöIµë².õ;–Aœú<8ñ EfÌc62‡€‘Ï­Yì¾ð!ÿ9c̽Þ7Mg‚£â´Ú5m©÷‡˜#‰Ù&õEg­ö=Ã’V^‚á¾khšÚÜxiŽ$äYmD¡HÞ(ý¬”]ÐÏg®Ý_”[ÌÀ­jU­ß|9iÖЇýú)"†vI„S«oK þXíÕÜÉ6ãK{­A5(ëY¶àÕ\M·íû-›`Yë¶)޹*°¡pPZ£ƒÊênJåäaóCQcűèdÏäåŒÔÝ晩o!4OS,ÂqÄ ±Ö _"ý‚èBò™gZ·¥ýXP'GeÚŽ4èò`è “æ5iÊ­µ1/Ž_´ª-1íŒe7±„¦‘õÇbÒ»Åv®gaÉ[Ÿb6/Ñiê)0¡ÊÅfŒ»>'Ï=Ê’<¼äÒç,úrÓÐg]ݘ°I±c5è®çÉç^2Ñäµ#ÂmOØXCìÅ—ø»÷[RQHÒ€ÙÒšg•З•gÇ^‘é[E,±îJ§ˆ¨§ÎµTn AøÚ@l\HÛÅaÜ­Ú¾Oeu/Íõ±"ÓVM@Âþn£øb¬eÙåY[ÑäŒñÛ¡±ÓA?<ŽX=Xà'û¥°y±%4ÔÊ ¦”LÕ¶ý÷úÿÓ¸ ½>1sû"Qe}üŸ–£obZóáçÉ›š1[ ?ª!ìÎö†“*önIL§ÕT÷µ¶P[S[Ž•|õ#åpôóë_,¦»Ö endstream endobj 3410 0 obj << /Type /Page /Contents 3411 0 R /Resources 3409 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R >> endobj 3398 0 obj << /Type /XObject /Subtype /Image /Width 358 /Height 515 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 9555 /Filter/FlateDecode /DecodeParms<> >> stream xœíÝ ˜$e}ÇñŽQQƒ(ŠI@Ñ,«â°ˆ ‡ "¨ƒ‚atÜ•UdÀ9†{qäF`¹PÄöŒ: ãApñ`·LbÅLÞé—-jë=êýWWw¿5ýý<ï³T¿]õÖ[MÕoÞªé©j|ÿ¡oQ(JH™?~CýgŠŒŒŒ<=O/ …y!2(Š X"ã¹ÿ°°tYgÎ"]ž·ÉÏßT•#_ðêVÙìóه×Ý|ñºsgÊ ç.yák–¬÷Ú¼H•ץʋ·Peéú¯_ú’×ô%3å¥[~lƒ-Þ`ÞÑ/ÛêãºüíŽù»­U9öïߨ*Û·á6Çm´íðFoš)/Óñ/ßîøWlwÂÆÛŸ°ñŸP啪ìxâ«Þ|â?¼yd¦Ì?iÎN'm²ÓÉ›ì|ò¦où¤.¯Þet³·ªrÊæ»¶Ên§ÎÝíÔ×¼íSº¼v÷Ó^»Çi¯Ûãô-Þ~ú{ž¡Êë÷öOºìôøøõªxÌ º û¥ƒŽSåŸß3Ü*ÇßøÞão<ø„›þÄL9ä7râÍïùò?ªrÒ-ªz²*·.øä­ïÿämï)8åöÃN¹ã°Sï8üSwêòÁÓîúÐéª|eá­ræÄ¢3'Ž»ûˆ³fÊ‘gÝsäÙ÷|øì¯.>ç«‹Ïýš*KT9ïÞœïQç}¦\pßÒe÷}tÙ7>zá7>öé¦.G/ÿæÇ/Rå[Ç\Ü*—|ûØK¾}Üg¾£Ëðø¿ _ú/Ç_zÿ —ÝÂgPåŸ}àÄËÿõÄ+ÑåʇNºê¡“¯úîÉW÷“×ü›.£×~ïU®û¾*§~N•|êó?8í “ºœþO?<ý‹?<ã‹?:óúyÃU»á'g}é'gýó¿Ÿ­ËÿqÎMÿqîMŸ{óÃçÝ<5S¾²ü®G.ºë?/þÊ£3eâÑK&~ù™»UY1~O«|õ±K¿úØe_ûÕe÷þê³÷þz¦|ý×—ß÷›+TùÆoU¹²©ÊãW}óñ«¿µR—k¾½êÚï$¥KPd7¶Ë‘Ǿöæo.>ìøM?÷åSO8õ€}ß»Ñ! 79jx›ÃŸ3çkD‘Ad<;îÿ·KŽßúœå{-ñ½W¾q"ƒÈ 2j¢ë* ‘±Ï;Üqÿ©KNxÝÛö[û²«ÙùíÏéœg¬»ÁZKŽØÿ€Wm±ózD‘AdÔ12DW.‘ñ†ÝÿféIoZøêÅ'lùõû®Ü}ÿ ÷Û{ã/_ràïž»tx×-w~‘AdDÆÓ0xÈÜ-¶_wëù/=íì=ÿÝ= ?²Ýéç¾ãžXuÉ¥§?öÈ­;í?@dDF­#£Ñ’‰l82FÎ>p`Çg-\²ÕE¾÷¿¼íÁ®¾ú²÷<ô£½çÎÓ.¿nô•[=ŸÈ 2ˆŒZGF.#r "ŽŒM¶zÞ™ ½çÐ9ç/?àáŸÝñìõcÇïð…‹Û|ë—\pÞQ¯Ú⯉ "ƒÈ¨{d¤IaŽ8Ä‘±Ëžl¿ís>pø¦gŸ³ï=wŽ\wãQëmÐxÅ·÷Ûn»Ûæs·Y›È 2ˆŒYÖ3”2‘±ëà+÷ØëÅCo2rÆ;_2ðÀÝÖ^ÿY¼zÍ·záë·ñÀ›žCdDÆ,ˆŒÊF/Úð9k¯÷Œµ^ôŒ¹Û­¿ñfÏúоëlô¬]çlºÅ«>Å…;í6‡È 2ˆŒºGF•×2þz½µ^°ás_ôеÎ7‘e. Žœ‘‘ôÁïªLÓÁ¬4›PSÎÈXi0Çievë€ÙÁôñï©L§Í ³ƒ32~cÐÇ¿§26'ÌÎÈøµAÿ®ÊôlŬ4›PSÎÈxÌ`^ËÈÖ['rÓêÎ+ÀàŒŒG æ(C1g0‹9#ã08#ã`pFÆÏÀàŒŒ)0¾0Îȸ Œ2ˆ D"€‘@€È @d 2ˆ û×òOWÞ±´ñ ×Þéüæ"¢O¸.fÙæ"2ìGfàRæt§;V¯ÈÈ.%úxëb–mN"#ÿÝÜ ¬;º+2¬ÓþŸºÖ•zzèoÙÕ¦¿¢îüá‘á©,ì³ç“ñ\!Ÿ†gñykþÿõ³‘Q®ÝÂÜu\ÓþBö9Ïa.^éïC`ûÖn§õ¹ ?Ÿ6?·ðEÚ_Ü3ÿìFd~+?aB¦ ß*ÜçÌw[¶.îZW‰ /ì°g"pí¥;æoÁ?-íÿÓ˜eˆŒâŸZÖ—•ì…®Y{è©ñïÄæzflßÚŽ9¿g¢µ‡t̵”ºpñÂO{Ö#2|ÿ×÷•éð·Bz(Ú‰=ÃJÇÁìïž«)WÒ=-·ÿ¹y63|ºpñÂO{Ö#2Š##»O—Ø ­+ò´ÒCÑN\¸¥»RߵϭôfŠ_j¶"2‚~›‡M›»¾Ùra<5…;±k]ž>”XÄÓÏçãZE‰Ï-¤Á‰úãÿf%"£ø…uŸ(½GZñ÷Á¿vÿJÍ­°6e톿ÞÓgs~Ïskiçs³ö-ðPÈâþMèDFo°âsë9"£7æÙôºS5ÀçÖsDFϰߗÃçÖ[D"€‘@€È @d 28#ã¸3.¦P(”l)ˆŒF‘Ä«ÜRâ¤2!ÍgdL»…DÆÈšÒÊ®l €*©!FPd¤£sÚðë¦3ɲ€8…Ž2ÚŒŒl ‘Ô‘@ {‘‘^È 2€úªàò'£  ˆ •E†ëËZD0›Df;ÙÖª’mÖµFë<Õv£ÓÝ®j!•蟘˜;SU‘Qí>JdHWgÖ·ß>ê¨N‘Qán*=ö*ï@wº]áêr•í7Žšêld¸v/ÏníÙM]•…M6XomÓœ¡’~ºVØmQû¹üõ}óP¨£ ÈðóG†kÅzÁÀ½ß³ç™ûtÈ ®·°ÞÕfx}¹~zZðt»öý[ؽÔKqdèùF¼Òæ÷HÍž}ѳsKgp­ÝÓ+ëœæ ÖÖ¬KùßõlEx· WòÒìsaC>ÔKhd”æÏÏ^n2çqÕ”˜AZ~t0íoíwÛߥð­ö×xÖ…º¨ 2^Ò…´Óþ®ìê^x}Hƒ‹ëÝ•†×{:Ò±\MøÇ’³N»‘áÙ)Ëí!Kî©%fÖ‡4ò™dk¤[^ïé€9[áV‡,¹¥¬D½T3¿7±ÿ+ßE\{¿éÁVúØ5X¸-þFÈõþÎvÀÓ¾ÿsï ¢UÅ(Õ­KÒ/†‡ìX¹ýϳ¯Î¸öÂcè.%ÝŠÊ»]¸Q®Öü=l¬)Au|”щÈHŒ½°p7õ9%ê .Q7JÏPø¡µÓ~᪻çï!꥖£ŒÜœGKÈZÂë]G—´Ÿ¹·ü+’v[ÚÏå7¼ÖwQ#Ñ2P#AŠn”!2úPg¿—aý²f "£µÙhð|¿“]j¶"2úP5‘Q¨kÛ £Ú 5çHëÊ…ë_.g³I»‘áÏ‹®€³K•£Œ,FÀ¬ÔkD0k”ŒŒÛ|´ËƒîE¿Uf®FFfzZ뻢ՃÈhLO{Þ³DF³EO¤ÿš‘a=séÜ)Œ§eΛ€T™È¸êöûœ|*j"|Mþ£.ðpí~dp©ÈGFšÒÔPGÝèèh’V4WKä‘‘­7¯¡Z¯ªz*Íyú™82tRèG¥ééÂudI•zBß47uYëaŸ¸v3;rí»Z°F†Ù>ÐÏ*ˆŒÛ|4Wr‹´’¢‘M õ¯®ÉÎcí_`Γ}i]Г Dêø‰‰Vä"ÃzÄZ/¹t°ÎOdR¿ü©óB%E’9˜›Íf:Ð(w-# e„/Hd!Jþ’5ð*F²æY‰z©³C5²ç&Š :ä&ˆ  PÇ##yê^gB•$3îh¬þ¥IRid$™0—ÍÕ{qõègÝe¤ç ̵ …£ QéÒ(#•f‡©ºÐ)]ýãwÒ¨»Ü/ƒ{mõudLMM/mU/'''K¯@›¢ŽŒeË–ÝrË-ÍfshhhÁ‚×·Œ­X±¢ôÚ´#êÈP#‹‰‰ ‹-R©¡#C5ôïet_Ô‘100 2b¼E_7UÁ188¨^V5ÐH¿”‘}Y¹N4›ûÊI¹µxá*5¬¢Ž u2¢NLtj¨“SSSj”¡*+k®z"V±G† µïª1… ˆ42ÔËÉÉI•jײæw:]ÇXöW¿Öo‚š±bQžÊÄqdZ×Þ~n»r3„4âúwéB?ˆ:2Ô9ȨñÝ/}MTEÆÄÄ„:Oq-k†…?\K¹*­‹¶éïaéöÛoÄÚ=×[èg½‰ OÉΩG*Ò¼ÐÓúTEE†Ê×Zü?­õþ¥üÓáK…ôPTYb+ü+| ý,êQ†ŽŒU«Vé}T§†z©ÆþQ†9]IddYë]MÎP®Ò5®ñtÒß1s¥@*êÈPç *V´¨‰±–ljôv”²®J–jg”a2'‘«¨#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒu¥æpÿÌ¢^U¸if÷\o¡ŸEšbLµ¨I+ÓÔp-•r›õ‰qéÌÖÊfCzRéY¨×gHdÀª‘áâOø÷øø{˜jIÍÇÕñ÷0Õ;2t‘@ êÈà~@l¢Ž î—Ä&êÈà~@l¢Ž î—ئçÛáäê=_Ù@?‹:2¸_F`›ÕF†õûl€{dp¿ Wen»r3„42” 2udp¿ŒÀöÛoÄ…È@÷˰OV&ŽÃ©p©Š*Kl…¿cï¢?õ 2Âq¿ŒJ׸ÆÓIÇÌu©¨#ƒûe„Tú·Â*dNòVQG÷Ë(¬¬pÓr}³ÖQG†Æý2¬•žÕ‰1ûÖX“Ùsô³D†‹?5âß×ãï!`ªqd$5?¿‡€©Þ‘ Ëˆ Ý‹ŒF‘¶·@Çu522ÓÓºXß­DFczÚó.€˜õ 2š-z"ý·ðÛ®o1T¥ð X)P;e"ãªÛï_pò=ª¨‰ð5ù:Ï×+ ¿zT ן:½^ ^Ä‘‘æ…45Ô!7::šd†ÍÕyd˜Ç³¿Æ_i®Èß  o‰#C'Åt‹ž.\Gö˜Lï1=?t]ËZûÄ}´[Gþ˜0£Äß  oUþ{^$O/Ù¤Pÿêšì<ÖþÆAá<Ù—Ö=¡@^©ŽŸ˜èaE.2¬G¬uñÒ‘‘Këü!‘A^Y¿ü©óB%E’9˜›Íf:Ð(w-# e„/X¸€¤ô/Y¯b$kž•¨—:;ôX#{nÒ¡Èð§Cn"×ò0u<2’Ö±§Çª$™qGcõ/M’J##ÉD€¹l®>°âк1ÊHÏA™k:AE£ QéÒ(#e„ Ð?ºôäw=¦P%ÉŒ;«i’TI&ÌesõžF\íý¬£Œô¤‘¹–¡¤p” *]e¤Œg ðc¨“®þñ;éÔ]Ô>›¨#cjjj|||xxxiËèè¨z999YzÕÚudèg)6›Í¡¡¡ \ß266VÕcßHEjd111¡"cÑ¢E*5td¨±F%Ï|PBÔ‘100 ¿ª­Øh=…`ppP½¬j ‘~)#û²rh6÷•“rkñ†kÕ0EêdD?-M?*MïÁSSSj”¡*+k¢z öÈP¡v_ýLÖ42ÔËÉÉI•jײæw:]ÇXöÇ©õ› f¬˜?~=•‰ã´®+¼ýÜvåfiÄ5Ž /àud¨sQã»_úš¨ŠŒ‰‰ Ñ3Yý)àZÊUi]¼°MK·ß~#fÇ\ÝFŸëMdxJvN=ÊÐOQÔô´>UQ‘ÑÛ'¿»Ž7éœå:ÐÎV”è Eýè#«V­Ò'&ú"¨N õR5ü£ sº’Ȱþ6+­ƒš6,/줿cYDr¢Ž u¢¢aE‹škɦFoG!ëªd©vFV%æ´¨#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒu¥žàídV.þÚß4ÿ6ZÔ‘¡©!ÆT‹J´2M ×RÙ!·YŸFà˜Îl­ i6¤‡!•žÕ‰ñÄyS "ÃÅŸñïîñ÷0Õ82ïQÿS½#@—ºúg¿¶·@ÇõàÉï­éi]¬ïˆV"£1=íy@Ìzé³K²ÿš‘a=séÜ)Œ§eΛ€Tǰ˜òu‡k÷#ƒK-@VÇãœjÌ<Äd4É +š«%òÈÈÖ›×P­WU=•æŠÌ¥7˜ÝÄ‘¡“bº%ðHÙc2½ÿ…~lZnë²ÖÃ>qífväÚwµ`öÁŸ&@ª 2ü÷¼Hž_4²I‘>r1;µqP8Oö¥uA"Ññ=¬0ŸÉš¸ÿØ4«tdäÒÁ:¿?2üiô§Ž_þl¬~Î{’9˜›Íf:ШüÉï®ñ‚AkdX£ègÝxò{:ÄP/uvè±FÈ“ßÛŒ :ä&ûô³.=ù])TI2ãŽÆê_š$•FF²æÁZÒˆ«@?ëÆ(#=id®eè)eˆJ—F)ã–á€huõßI î¢~ô€ØDSSSãããÃÃÃK[FGGÕËÉÉÉÒ«Ц¨#C?K±Ùl -X°àú–±±±ªû@*êÈP#‹‰‰ ‹-R©¡#C5*yæ;€¢ŽŒýøUýhÅFë)ƒƒƒêeUôKÙ—•ëD³¹¯œ”[‹.TÃud¨“ý´4ý¨4SSSj”¡*+kž·ˆ ˜b jÇÕÏdM#C½œœœT©¡fp-k~§ÓuŒeõký&¨+æáä©LG¦u]áíç¶+7CH#þßy°Š:2Ô9ȨñÝ/}MTEÆÄĄ虬þp-媴.^ئ¿‡¥Ûo¿³ožwÑÏzž’S2ôS5=­OUTdôöÉï® ÎY®íl…¿c ‘·¨G:2V­Z¥OLôEPê¥køGæt%‘‘e­w5U8C¹J׸ÆÓÉÀŽ0EêDEÊ51Ö’MÞŽ2BÖUÉRíŒ2¬ ‡ÖÄ’È#C/ôoLÔ¿ú—&jZ¤©!º–‘›n³Ò:ƒëgµçÈl³Wnšµ‡žwÑŸ¢Ž M 1¦ZT‚¤•ij¸–ʹÍúÄ8„ÀtfkeH³!= ©ô¬NÔHágdÕ 2\ü©ÿîS##ñuññ÷0Õ;2t‘@ êÈà~@l¢Ž î—Ä&êÈà~@l¢Ž î—ئçÛáäêý_Ù@ߊ:2¸_F`›ÕF†õûl€{dp¿ Wen»r3„4âJðˆ:2¸_F`ûí7’똧ÛèsÜ/Ã>QX™x7Ñœå:ÐÎVvÌ¿úYÔ£ î—Ré×x:Y¢c€udp¿ŒJÿVX…=ˆ äDÜ/£°²ÂMóo# E÷˰VzV'jÄgäL5ˆ jÄ¿»ÇßCÀTãÈH¼G]üdü=LõŽ ]Fdˆ:2¸_›¨#ƒûe±‰:2¸_›¨#ƒûe¶éùöGx#Ùʬv:‰Ù'êÈà~mV¢Ðob î—áªÌmWn†F ÇäLQG÷Ël¿ýF¬Ýs½…~Æý2ì…•‰ã *\*¤‡¢Ê[áïXá[èg=ˆŒpÜ/#¤Ò5®ñtÒß1s¥@*êÈà~!•þ­°*œ“¼€KÔ‘Áý2 ++Ü´\߬õ@Ô‘¡q¿ k¥gu¢F<}L5ˆ jÄ¿ÓÇßCÀTãÈHj~Á?þ¦zG€.#2t/2EÚÞ×ÕÈÈLOëb}@´zéiÏ»bÖƒÈh¶è‰ô_32¬g.;…±¶Ì©Ó›“ðw¿zÔ>Odtbu@Mu52FGG“̰¢¹Z"Œl½9° <•抬5ºÙc2½ÿÅôtþÐu-k=ì÷ÑnfG®}W ÖȰ¾ô­ò‘xÏ‹ä©ñE#›ê_]“Ǻ¢À8(œ'ûÒº ”AjZÇGzX‘‹ ëk]¼td˜sþðP 2­ã‘¡óB%E’9˜›Íf:Ð(w-# e„/Hd!ºé!§³C5²ç&Š :ä&r} téò§S¨’dÆÕ¿4I*Œ$æ²¹zO#®v€~ÖQFzÒÈ\ËÐ R8Ê•.2RÆ3ø1ÔIWÿøtêŽûeà~¸_î—@€ûe¬±:W=‰hÜ/Ã×rƒokâ~Îñ 1˜¸_÷˸_÷˸_‘p¿ "à~Ü/à~ÎF\íýŒûeà~¸_î—@€ûeà~¸_î—±Æê ;ô9î—Ô2‘hÜ/£xüB^)î—áüW€~Æý2 þðŒ¼²¸_‘p¿ _d@÷Ëð]Ë 2€î—álÄU ô3î—@€ûeà~¸_î—@€ûeà~¸_Æ«óô¡+j‡ûe8[ÎÖ€Æý2œã"0q¿ çߘ€‰ûeÿ%+y¤¸_†32 èCÜ/ƒÈ¸_×2î—álÄÕÐϸ_î—@€ûeà~¸_î—@€ûeà~k¬ÎÓ‡N¬¨î—ál9[Cj÷ËpŽ_ˆ ÀÄý2ø@€ûe𗬀@ÉÈWßûe˜MµùQ³@Ç#£QÛûexºô­.EFzÈÕ÷~m} ÀlÑñÈHfÅý2Úû€Ù££ î—Ì]e¤¸_Pk݈ŒéÔ]W#@݈ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€‘@€È @d 2ˆ D"€@qd¬\¹RýK¡P(ºø"CåÅ4¬ÉCd 2ˆ DFzþ«¯öËìÛ¢v6DFÔ>÷óßüO}‹52zÞ«n><ˆŒ ¨}î—+ÿ·¾Å=ïU7DFÔ>÷›ßý±¾Å=ïU7DFÔ>—üþ‰úkdô¼W=Ü|xPûÜïÿøçúkdô¼W=Ü|xPûÜŸþü—úkdô¼W=Ü|x8®õ~õeŒ^wª{ˆ "£uÿ™Ì(£'»MM(}æ?oµÒËvèd¾ÄÍ[SUý¬p3¹–Q "£¥¿`¥—íЯ JlQ¶?ö­ …È!2*Pî[ ú¸ÊN”¨ÌÖäfèò÷2\=ñ÷Ù¿½á›\nÃù^F DFÊ}WRïåÙ‰t:Wï¯L—Í5ÕåoºzâÙL릹–ò,ÞζóíO)"£åþ"CïâÙ ×´¿Ò:[÷ÿÆ$·vW÷r= ßvÏâå¶š¿1)‡È¨€Úç~ì¿¥EïëÙ ×´¿Ò:›¨X#£ôæv¾p{ÃwU¶¹ùð 2* ö¹?ú;Q™g“Ögç)¬´Î&*ÖÈ(·EæK³W…Û¾¸¿²ôæÃƒÈ¨€Úç&IDEïßæËt׬Ì.žmPT¬‘ÑÎY§Ã+­3ˆosóáAdT@ísßûù*QÑû·ùÒœ(¬L§³ ŠŠ52Êm‘Ùk?=[Q¸ÉÖö«Ý|xPûÜC?]YIÑ»~H¥h±FFU[!2DˆŒ ¨}¤èƒ?¤2û–ëÝÀbŒª¶(þBdˆPûÜwþý·õ-ÖÈèy¯z¸ùð 2* ö¹oþø×õ-ÖÈèy¯z¸ùð 2* ö¹û~ø«úkdô¼W=Ü|xPûÜ×~ðX}‹52zÞ«n><ˆŒ ¨}îîï­¨o±FFÏ{ÕÃ͇‘QN?˜§ eömQ;›"€‘@€È @d 28#ƒB¡P\…È P(‚òtdŒ@€™È˜ÁþèÇ?æ endstream endobj 3412 0 obj << /D [3410 0 R /XYZ 89 721 null] >> endobj 1118 0 obj << /D [3410 0 R /XYZ 90 187.557 null] >> endobj 3409 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /XObject << /Im30 3398 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3416 0 obj << /Length 2542 /Filter /FlateDecode >> stream xÚË’Û¸ñî¯Ð‘ª²h‚OÉ·Yï8ÙT*»åh“Ã:5E‘Ð Šœ gõ÷éøÇkçD Ñh ßÝ`°yÜ›?½ùáøæÝÇ,ÞüC¦›ãys6Y°÷ƒ8ÙËÍoÞ‡?ßýr¼ÿ´Ý…Iàeþv—¤w÷ã6¼lU”xwûpÿ#/¼¿Û*¥¼ã¯Ÿîÿ¾ý×ñ/ï>&á„vŒ„“N&Ò*= Ò›@.ã¾p£`²keÊW‡x³ 3F¼ùs¦³Ý‹³häNú¸U‰×vÛ]†^Ûh”z&Þ—ªÐo&Þs[׸y9B/·¶«NÛ0ðz« Ã^*ûÄ#û$¤L~‘Ò¨šG™è®jK÷fç|ê›»ð¼À{ÀÁN)ÿˆ:>IÐé¼|˜_ Àj!¹ Y;•ø Èïà]]·xÁV4ñƒ[†âÍdÜò÷$ˆune$wæIÛÔWUgþ6ýå¤;Y=/7·§ëž”º€6>I TèïC4—ÚóÅî¦yùÈ›?j3§ßè o3–òú±í@Ý™vz&² ý8‰@® ­PT¤ü9Îo»$¼Ÿší.: bæž”gXõh¢ºËk^\ÚÂðfº”Í o&M €-GSSbR¯¢:û$4Æ=£ ÖˆµEÑïHÜÄz<·ÎçÜV|3°€ŠOQÞé:»ÀDÄ e«Á´î²—mhB”‹9oAкä„LîC¨Uc¬ÐW"ò`MäÃS§K™­ÛãÆÓÐ,ð´[NDëW­ã¯Ú ’C…ný2ȇbŒÈÑ!æ™îº¶3ŒU5 c`ÂacyÍ\A3þ`Ž¡È¾3ÑWšÖmj³…³r¦‚€Ì3Àô«†AÆ@NÆþ!Èæ2œ´ìr¼ñË)/þ#aÁ|ÅáÒ¯9Ü@´nÍÂßgª”sš²b¾Ë ‚bXuA™ÛœG~n;«K·ï[#¢±¹í a-lü„²LB䘾ÆVdÉšÆT'2~X ¿HPè¶ïš) 0;½ët­Y«°pàÏèq0‚dóÄ}ÜîA6¼VÊ×´£,ó®mÏ"oøŒÞÑf[KA7ëN|k-…=wmAæî„åK¦ÔTÆv<<¡ÈeD4ÉL |’\nÞNú )>Ê<ýpX)> ˆ’ý°©k!øÙ+w¢/ÆkYy¬,)•ÁÜv½‰Å"]Ša”¼6‚4ªjºµxj[ñÐyè§Q¶ð'R;Us ÆŠ4Ï2NÉã`.úXME/äDØ8)ÚRÐÜvV! .¹û¦(KT˜"N*WÓ8„[U-Tÿ+Øôû÷ å‡5¥ AõVy —$Kœö.Ú>µ¥ÏˆPèð!U:ï'® Èüȶ;@`ø.¹â×çn«ö^{ùš?sÌ8ŸÙ°wD^÷~º_”œapÀ†—Àq\´—KÞÈ„ñökx³X>ªÌ¡uE±ÇO¹á†íÈ -Vue+ªxà2HXzÔvåÆûÚN¯´8͹¬ª{‘*±íB„KqY!ÑR£p~/ô3Ú˜Gß/b}êÇÑ~ë!û%kÑþcw£¹©kP¨¶F×çùæ`ƒ¿ƒúš]àybÿçèTâjj´a²8‚`Ÿƒ ìŒå iç[Jó(ÁÅ6ÁÉúÇ€ð=‡c-ì¶I1ƒJ.Ñ –;IÂÃfïÇéa‘¦’¬$UŸòÒušH>ö.ý•""Ñ>Á`ËŒîcN¦+©é£Qß1[0ffM¼à¡jZìLpíÃÏŸ~Øb{ËSÌ®¸… TÒî±c4B’rNÌsKjA0Ö±)ÅðMnç¾¥¶yE’ § œ  / XÝú•ÈdçÝת8‚˜ ÍÒ¢ûÚ9øö¬ç€¢í:]ص<°ò”ì¸Xå4í2d^µý–¾í›¿­5%ü-KÍx(5¡x"ø2Ж\ón¥ ¥ ÔÕ`0Aƒe]ÿ°Ö<ºFlÖæ ÔL‚“›EÛ6Ô~Q µ.PòNÂeŸŒ ‰ýR³*ýgQuE_ç²o.>Cmf* n44¸¯uµ»53$9I‹S,5¤ûhÓ$ïÆ.ïF.:p ®R%R N4p*¯J°C*+¦no”9`Ürž)åý|bh{S_Çë­°9²’"¨ƒWW—Š2©òHÂ_ŠÎýL4#ÞS׬`¢–tݪwi´{Äyìÿ÷Ôk ¥i9HÓrÏÉ©a¹íÿâ òƒýзí¼ÕÊÂ,‡Œ5؃â!\1~h ãL9š¹{šF§SžBÌ™£Õ.±.B‰:, ›g]T_ô@Gó`l‘`ÒÐÛiH/Éå‚UÛ9<~Æ&^å¾sEÓ >:cz K U´ ÞíŸT<é)WçÅ“ÃÆsßrô·Ž2? µ¾kŒáÖ¥P ®X¥ÍϸNw4¼ÂùnU€¯ÜëT¼°li²I¤I%ÒdÎb³eù€8ÆÒk ®r¸ÉÜ«%8/L‚Z*é™S.2§DI.0ð6>òÆPö¸t<ÂyüZ˜¢˜Kv–Ò“?Ö0¦'MEüèú(7×o!lY7á>f‡®2l¯HÊÌHÛõ¨Y¨]´üEA Ò# ¸~žîmVΖËÝÅèoÁ*«òD½ç@âóEèÁªæÁgÒr¸xKÀ_‰q,¹ °¦¦Ó[Ùïä°Û8&XmÄ.&ð‹ÒòÑ~ *þÚSùI¤n~â™.Üã,¦eÏŽÒÌ“d.ú@–º-JÔP” `Ú¨±6WNÔPÝ»ÊqŠ5„Ÿ^%Ä z²]Þ]§µÜêîÏÝ2Vªÿ:7vVÞ8c13}Z©}féÖ_ý/||ó?%? endstream endobj 3415 0 obj << /Type /Page /Contents 3416 0 R /Resources 3414 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R >> endobj 3417 0 obj << /D [3415 0 R /XYZ 89 721 null] >> endobj 3418 0 obj << /D [3415 0 R /XYZ 90 624.127 null] >> endobj 3419 0 obj << /D [3415 0 R /XYZ 90 580.665 null] >> endobj 3420 0 obj << /D [3415 0 R /XYZ 90 530.543 null] >> endobj 1122 0 obj << /D [3415 0 R /XYZ 90 442.304 null] >> endobj 1126 0 obj << /D [3415 0 R /XYZ 90 191.749 null] >> endobj 3414 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3425 0 obj << /Length 2500 /Filter /FlateDecode >> stream xÚµYÝsÛ¸÷_ÁÉÕ;ñà‡ÓvÆí»t®M+yñy<´K¼H¤JRv<÷Ïw?@Ф¨\òP?˜ÀX,?,~X gåçç³,Î~ºŽ”“xIè‡ÎâÑI„‰ØJ;‹Ì¹ußürñ~qõa6÷µp#o6סp/.gJ¸Ÿf2ÐîÅ¿ß\]róõÕÅLJé.>~¸º™Ý-þùÓµö{º*Ö!ÌLªe$°Ó™°Æ€%‘ÒK4Œ‚îó¶ÿÜ@GÀ£"/ðôl.…îÕ—ÆT3©Ý"Ýl^؈¦ÊW+”Æ®ÉX´+7›¼XMX$œ¹Œ½0fÕ7åÖ4ùÖÔ?Â8¹UÚ¬AÓ܉۬ӂK­6ª¤üY–ÛmZd\)ív@Ú€M3_¸ûư¨2hõj¿I«–<çÍz ò7!ü/ØËXµ;SåefMËæ5·eeUçøÄÔ]0-‘|ÊklJè ÷Ø»G¯½âzf–yfj®<¯MÁ%p«†Êv_7\*—Ë}U,‚0qmçÅ,°üU91¶~©³årº©m—z¿Û•US·³æ¶ô9'¯âLSËÙ×éÊÀôaÂô8*ˆB—¿Ú]ÂÁ}¼ïAåÒ âˆ÷¡da„*š™tI3)\ú8"Ú l=(À¿‡I«šL‹Ø!%•ÜÚ°¦’ zŒlûMh`¢¥0Â@$¹1µk$$ŒGÏ wž†!…Ò­óíŽMìÖ¦áBN[ û()C@ ¸éAëu”, ðÐåÁ° £Å¡Ä¢d (l¯k÷)_Ú.µ©žî·§Ù6/òºC˜—VqoÌ.²ìÝÃïï;ÃUÀG¾w½¦÷íj”ߺ×"b÷]AÖÀ€¼à¯E"ôÜ–™AÏ)mײñɆížay°g(èÁ¦3>dã ²Zv‰«ì¸@ó¤Ç@ŽC/”ºE[3Dìýr›ÝÛ9Ñ.2䲉褐Ó!p]ÚÙíbާU±§CÿÔ´è–o™Wx~ çµø†¹á¼wë&ÁÇ&ßpi¹Ikˆ9õ@F^¬FPç@‘ÿŒ(3ÏËŒr³´­8~—°µ\ª×ܻ檭ًÅ]t.â±û->X%ûº½x 8SaÛF§µc™N£…dÿnl¿W‹³ÿžI(ÂM‰wµ#/‚­YnÏnï„“ åEIä…ÅÙƒðç"¥. L?^þàðq¥H·fÊ»‡YÔô,û ŽÿÃïfÙLùõ *ªšµ¶LvÀaG«g-!³#-ÙSs|*ã-¾Î{ºñÝöøhªo"Ï0Ö½N«ì¯‚´²â ¾â uâ¨ÔeIžYº©Lš½p¥2;*¸I1‘Æ.U•ÚäøîÒ¼âÒÓŒ”ìé’ö§ ‘oÒíŽîvß}k•”UF>½l–îÌB¸D×î{ž¼„Á¿QÔQ>»)÷yQî›{¸4š²z™ºþO…²5yÍJá%mÛ…hšÝhÇ×fðÆ]€xzÙ„ª½ËB¿ó)Âujeä_°^¥E à+ ˆaC"Ä.f·ÊÀÄfu.V:ÄaÅ"7Q€Þœ~Ëî¡ ‘MÕuþ°1,- ¢îPzlgSjì5eÀ²,’¯öL»pŠ‚¿L> 0Á²Å z%ê- *Èñ%HK1QHsѨ†WÇ ‹ÿLìd·‚l¼Xuï(ß=…Kí<¿4?4ዎ²á!–×G§è)ÄæPF-ylÿ"ºo§‚×:Lõ²(áI#’#–Ê&b©¡—Äñhö>9ýžé…'“dM p„¯F~k·ãó8”N‚á bìÜO´{ûÏ9ƒ—ôÊ·›‹b ”UW¢'¿æ<ô1@ƒRN,hVlUzüú~wkVxÈ Xfp}\¦M:±úP{2èÜck¬I—kžÖlÌÖ ‹ÉB¬oÇx{‡*"®a!÷@$îëVQO·Š† ÄîBÙ·ZL¡¦tùyØÂô›Ì«¸F†ö< µÖ“X<åÉÀ¶×ü÷ ¯ãL@d}ö&œ‰ÓÝ™ °FŽQB{~&3¸º¯=n±dûã6Iƒ)J{­öÖ_±w‘_;ƒ|Ü»C@ãè°' x»„êS^îë íÂ4Ž󷮇y2³£ÐÒeZå$û¡ F†îÆN —a›l“-†dØ£%P9 P £ éHÅî¡`d9gµr¸ðáç3ç–:_xÒS®jèêC‹LZ\<<¿ß.ÒÆÉCæ'#3Û|t¨ÇDÓú‡Y]ÏVKA€K‚oâÈžEh§"Â.8‡á)ÚsŽý£8pªNLtÕžé±Úȇ`ÊÆ§bJ1!¿#C½“ÖÓI4”dÔä´zØ`PµÄ#¼`ôHÉÊ% t›L80HÊ­Å>Lª•}¡L€ááÞÑ®ù¼k8x”\@½6¹€­xòPÄÉ”ðÑ«YÜ´Z: ¡t $ž¦âÆ´Uh© 6ÚÐD ü ñó:_®O¥™|­zl7½`áñãH “ºe2¸oîÁ\½æö”e—üúD?¤Õ¯e±º°DZ3uo^v†em†/½Ên¶¡¿¶3v±rtLØn úÄ}É <‰a‡°XÎì‚°Æ,ÿš¹4½”{.<Ã+ˆ{Ð)ͬª‚eéA—†¯ì2xÕ kõ}rµÕ<ʲT(a¤Á–Ìl˂ҜÖx{XÇ‹üžÀ=ÊQµIr|X^UU›”ÜÞ˜íJm~˦å)¥E?@©3)úóOßöЗÀ}’ðÿ”œ’¾ò„ò“SSÞûjnêUú4À*¦e²§MzO¤[uw"75!ÔV5^Ü—}ŒêòAÎG¼¶õ¿òG½Îø¡e §2NLëš›ßyS¬š5t™©Mû^Z endstream endobj 3424 0 obj << /Type /Page /Contents 3425 0 R /Resources 3423 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R /Annots [ 3421 0 R 3422 0 R ] >> endobj 3421 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [259.954 224.501 284.083 235.405] /A << /S /GoTo /D (subsection.A.1.4) >> >> endobj 3422 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [152.704 202.648 159.678 211.494] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3426 0 obj << /D [3424 0 R /XYZ 89 721 null] >> endobj 1130 0 obj << /D [3424 0 R /XYZ 90 690.045 null] >> endobj 1134 0 obj << /D [3424 0 R /XYZ 90 353.766 null] >> endobj 3423 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3429 0 obj << /Length 1828 /Filter /FlateDecode >> stream xÚ¥XYoÛF~÷¯ òPPÅpyŠN@µåÄ…´±’×06$%æá’”]£èﻩRnÚêA;;;œã›ÙÙ%mcmØÆ»£—G¯ÎCψ¬(pc¹2"Ûí™e{¾±LŒkóôýüçåâÓdêø¶Z“©ØæülâÙæ—‰p}sþñtqÆËç‹ùDa.?Z\Mn–?½:÷žnûX&Õ"(td+g^ »/>u}×raL˜.?5›LÝÀ¶Íä!—·²®åÓuvsmßL¦Èýaóø’‡ì5#S!¬ÈW¡E£šÄž&1¦iê[Q8ªC›#úœ=}Î7x†F…ËŽ®:n ¸®zf)ËuurrZ$ﳦ­ê§«VÆwoÎÒ‡/²¾¬Êõ]{ËöãM3î§´€•§åºÝüjû¶bü”(5«ªfƒ¨%+[žÜ  ±_«ù¼×w/_¢ÁQÍ¡ÒüÇ(ºJÚ¬Ho•µÇMZ â"úóñóååáÀ¢1®£“­Ð^‚ª ?“­<u'hì»^yÜÝ£Sm;BYÁ,ÜoÊë9ð€ó\á8îVŽ7,œÏm–“\ä[»OX¡§6ß÷´ÀÅßc·ë®=E''YÙ´²Œ èßSa +Ñžƒ¾r¥ië¬TJã"¹-%gêŇ'ùÅáøu½A ²8½(î9”Ydw ”°J’> b±à§\îðè Gݘ)7Úõôí*Ëó[ â¾ÊsˆêöëvµJk ŒëðŽ!Ç‡ãŠÆ2çÚÊ :i z©ˣߎ¶!°·»Q` /4ââèúÆ6àƒZ+ŒB㑤 ™Y¾]:7®Ž~á3bÐÇ…íY‘çnè[Ž£\¼ÌÊ”wŠý ©(_a›WY±Íe«–Ø"LÅUAYFzUWSY'xLÖéÊPèCË›bŸBò„6ŠyZ§lX•Ó¨Ø+Ûbì5Jfƹl&e™0Q§MZ?L„oª'›{©µRXݰΡQO?ã7+ÍÓ"-Û†$Æv‹`Ší¯‡ðœgyUÝ3U•<¦2Þ(X;ÍÆžÍÌ6Þ¥m—@%5BWaêkºSz°ºÃ´Æ”(Y¡³AßäÊ®÷Ðíì3Ÿ5Ö7ª3¬ sòYíü¢Kê‹<ù:qls»B‡ IŽÏ|ÕŽË%â:lHðýw Þr˜´¾âe•(àÄU’ ×W©9äÊmVVÛöV%DVüx, kV¨¯NÛm]î¹±K'ÉbÙ!Ûc@9=œ!Úü}×ö8ûŽ‹ÌvêÑw…Iwæï²|Ú®Î2ò$Õ¡K`Ñ·yÆ|¦9|t#ö®·ÁZ«]xÀTÈ|«øÂþ¯>Žl22""ß,©Ékœw@âD»,¢@¹L"—‘Ói빌Sá‚ËNä`—Äù ã»LÓ’Ôê9{µÜ=Ћ¦ÚÖ±âÞËNo*Iœ6éhWm+pP;ã›ÓéûOUl·«'ä2ö@ôaÁù®‡Ã¤Ë$Ðt«NY“TZt*È u@ :hž ÷˜ŽP”§ý „€f>,°8ŽÙH Œ …Ú(ÀÅñKõ_ 4‚¸ÜC–蜂0ƒñlñåâtÁ² 0àv€¡)èa¼Žû9¸Ï&™Õób×|`†7UÁzÐ|.Vc!=U[Õ ]&Õ2ktSKO2 dH79|×8¬þCã!©æc×:»¸é9Ûõ94ðgú5ïd@¨äü<‘p…V˸Ñó|Í]÷î^÷&¾Á"y‹c ·{–luJ PÎW`~xšƒ€J÷&£ûK/2‡;Bò¤Ò]ö}…*AÑÓá& †×ë´&SŽg1jgŽyÑ2‹ÌÀ(yhÀ3‰Îà¶Ùó– kGïX Îø(½Rï/ø˜*z”zºgs0gCþÌ=ÊJ¹ñbP$ÝTX°J·G¥9ÒWUµ3Ê• ÐŒ’T‹Thî]áH°\+&—µ†Çª$§€¢ z’´¨à®Vó-6éÎ x Bw¯AƒZé>Èó®dzÛÈõè‹Àî^W€a]þ°§@~wgÉšfK!@0‹º®êq±T»XæM¥®"iZê=WT˜&>m’o{Õnd !þͫ־Jzõ~ž*|Cˆ™%f‘úFÑ{}}cêïE¸Ûö¿qýªòÀ7"ýÝ@>¹_bý±Rý?ˆÜç> ¾%ë/b3r endstream endobj 3428 0 obj << /Type /Page /Contents 3429 0 R /Resources 3427 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R >> endobj 3430 0 obj << /D [3428 0 R /XYZ 89 721 null] >> endobj 3427 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3434 0 obj << /Length 1934 /Filter /FlateDecode >> stream xÚXÛrÛF}×W ü¶„ñ\påî¦JÑ%qÊqv%:/²KC 0h­jkÿ}{¦ @QŠl¾`Ð3èËéÓ=3äÎÊáÎ'?ÌOÞ^Å“²4’‘3_:)wbž0„ÎÌä'òß¿‡§ø»1F|!XRh©ú!Kãd:#8¹Ð_nº¦¨Vv©à1 ÓÖ²8péßì ꉷ]3q¨Ò8Øk´¯·â3úö !SG9r¨ïü×ëÎf³ÖªºËw[훳®_¶.Ú®nñ%Ϻìͳ09‘F$UdyPæFñhùÇàþ÷t–ËàÞé<«Võlv6Ÿ_ßývöþÝÅi×ìô©ÉÍó¶²’­[¶Ýµk£ u>óAèùBÂÿ;:•Æô yø±+J». Yˆ×¤³[MÐ)šÍŠªí²jaù¶÷Û\°H¤¨&äJ;â@àÞU2öÍ/ìÒ•’ HE±Ðï6[ &IYŒ: &vFâ\™DÃàGNˆŒ J~Ì )Ènå¿,ÊòΆ±­ËÒ0ò~·\êÆÖN‡O!ÏÏF&åQ©"CÆM6iýór~ò牀!w„i`A3ÅÎbsrû™;9ÈA-‹ÓØy°«6ŽJrÓŠJçæäߨ'ÍJð€¥ÿ ™RäÌû¢ÒÀX¸Ê7Ô•¡;óü LÝóFgÍÕý¢ž¸²^¢´[Ó´IôOX¨7]¶ø—-ʬmqAVå(kt«O¸_<¸ôu»Í4\Ö ®Ë* åo^ŠnÓŠ¨‰‘M`Ö¥Þèªk±ÑY€¡›6ù1 t%`7À·²®·8ª+|êl±ÆÑࣩcÉÞI&&~Ô¾çd32ÜZgMþàÁ|Ö´-6»2ëŠÚöœcmoBpßôב™>‰F”‘B[¨ ç?Ôýl·Îº~D¢ íÄCw·@Üÿ®´®hñ¹°6ò)Rƒ’µÎ¶/ØÆ,Ã]NG.ïÌÜžwV¼D) ܹûö¸­£˜ˆg–"eŒ0§éÉH"²Óè?wºí€˜òÈÈFo(ã ¬Ÿ'Þ=EÞ-²Vçì¯Èc»m˜'` “Ô½nÑL·¶8ÃÈôœâÞ“ÜÝu4¹g!O, ÁqCDû^T½†§«c Ô'°@¦‘;ïWôD¶/u“C‰Úá´CÙà@ù 2£CÏçé…æ\c 6¬òDèöÒ,{û“Ê(ZöŠ*–Sê_¡Ï† õfC¹†sös|A4—Æ!hîÇŠëq&ˆìð¬j+áü³Ðm›Y8A„°ÏFw»¦"™ s໬,ëÕ Le¤¿Ä0`$¸©M€ØdœjÔÅeÛ¢Hú#ç'Îå“­Š¢‰K[Vß:žìœ ‡×îÖ5yeómó©â‰HN1ÏkÊ eÊvk3x¬w íİsÙ/¤1 Ê„ >b¦˜9ÂpØot× ù²ÔíªA8°c’º¢štµ¹—J×b(å¶òŸFl²›°(A?.‘…V“t‹%>ÉžD{PQhRRÓÀfi|Ä·;¹ì—Æyl‡bh;ö80õŸN7UVÒ²º¦QYüaz>™ý¹ØÈ)Yî¦lë¶-îKÝ+Bcƒ'ýò¼h [÷Žu­ƒN<Ä»¨s;RÔ`%‚«Ü„àJ×n 1n•joºÿÙÔâì½.ëjUô8¢¿Ê>Bð@±h§º°À†‡w°„ÉTöˇ–/m¥$Ú½9;±k±ñ(ò€Ò}RlÂ,óe É´i÷„ m‰›£xíæ=›œë±@])‹cÒõIÊðàº8 &Jû¸ŠönÒÿm±ëü…âNG¢ÿÞó)ÖàVG#Ô*_¡=e îvôe×—ÝZ›CŸ­Ïe Г.üöp$Ðê9€,eB—„â [ÙÚêŽàw·ÕMQ¿&\þ!aé+PŒÍ¡|¡ˆ©Tºê‰Í“Cؤ'¢•ü€ç,=€ò´LÐ{!Z»úÖYíÖKz¦‚'„3Ùäûýhʵ^…1 ìuö[‰§©íÝW“ÀÍK¤_ƒÎÞÆ_C5™*y‘Ñp„+ÙK°UÏÀlpUÁ´“áù1„ãFÝ÷\²“ ›Jâ¶U±Ý"Ÿ*ùÄý}×’&´Qn²mIßá–’¸kÔŒ/]ßz“që5æveŽÃ{šßÙ3¸¯T`íd±¡y½Ø™s'öžÃ#`Ò¸%b˜;y³¢Ëù5P ®ôÁ”\·îçWÝ뇔…é×ÜëUÚ{þôoF@ëOC'æL[ñO䋪Å@˜¡X¿ÔñqªNB}$Ãó—Çs³ÅÎfpMË-ñ #û¿Ê,al_7ÿÃ|GÓxmõƒ˜%RLÁ•ô_ÈLúì^ø›äÿŠŽ¢d endstream endobj 3433 0 obj << /Type /Page /Contents 3434 0 R /Resources 3432 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R /Annots [ 3431 0 R ] >> endobj 3431 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [102.563 130.695 114.518 139.442] /A << /S /GoTo /D (cite.Tango-dsclasses-doc) >> >> endobj 3435 0 obj << /D [3433 0 R /XYZ 89 721 null] >> endobj 1138 0 obj << /D [3433 0 R /XYZ 90 297.135 null] >> endobj 3436 0 obj << /D [3433 0 R /XYZ 90 82.324 null] >> endobj 3437 0 obj << /D [3433 0 R /XYZ 114.907 82.324 null] >> endobj 3439 0 obj << /D [3433 0 R /XYZ 114.907 70.369 null] >> endobj 3440 0 obj << /D [3433 0 R /XYZ 114.907 58.413 null] >> endobj 3432 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R /F113 3438 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3445 0 obj << /Length 2211 /Filter /FlateDecode >> stream xÚËŽÛFò>_ẢBFtwó ‡‰=³›=¬[»â%¶FøPøðdØOUW5Er8±á‹Ø]U]]殺páüãê‡ÝÕ«û8pR/TäìŽN*œX$žBg—;Ü×ÿ¼ýiw÷n³U¡pco³ #áÞ¾ÙÂýïFú¡{ûï×wo}w»‘Rº»ÿ¼»{¿ù}÷¯W÷¡šðqÁ͆µŒ}$º,Ì«{)¦ä[?ô=Ig«bút*ØlýH×ó<< '·RziÈò†kÀˆÏt}[Ô›-®³¾ÿXg•þM„âú}SéÛ°û¡××’ß­ñ‰×øÔMÒíÇ¿[~ËdŒ˜’ñ¤ô§Ö“^øÖxÅ‘if&“`(¤AQŠ%#)>ž›²Ô9‚'ÒJÒãûï×.U\X†};èµk•ï¥RN®•F«­J•—Šp®±æB´bs6"]$\жj2)WÍ{‰eÐe·*é–Éæ K´"Ì»7¡/ æ¯9SN"v5deø9‚h Ñ(ûÿ,‹^úÞí®þ¸BûGb–‡âÉCuõáwáä‡+¼8GCU9~šx¡À|-÷W?sµ€óç‘ârD‰—D6C<ÐV¢-w§v#Wg9¦ÊóbÚ(éÍVúå¤ëÍ6PÊ:ãJºE"Øëo¾¹Uº»M‚9÷Љ%VnSÕÅÛw?8ë˜Wë¶|2ÉŠ{ ðˆbw*˜æ5žÂBFÛ¢:—ºÚHW×}Ö Ke©³5÷§ôDI° ‡Ëq„e5#1šô±i5ÃéúÑb¢ns½Q¡û©80y§ÛOºº¥}ÃßCYÀ}ÌÒò®†²/¶sÙÎmsÐ]§;\‚Þ41¥¬O ?¬OÀ™ždw¾ÑxïL’î'ü±ÒœÇÍë—‰%ÄûÖ žu]qÈʯR¤¬Þ5¢ž˜oS×úÐ[µÉ>mN/tñpê­[ÐJ`•­/1vu§gˆ…i¿¥œ##/ðÐ/ö„J¹ *Ω>lC“Ö=YQOï`•РYÑ›5Ñ4ñ9äseÓœçw‘±ƒ8ùŒ0hose³`¾Ä3[`ueúé-gÐ…Ìvç2Å_h Q–îmƇõ>›í«ô¶wtÅCmƒïïø}©Ì'µý^gýsÏ¢Áj­ÇTÜ?-»~Š}î6µ»§®×Õ×[véí_«?>ïmÓɧ΃Ø[ ó…t¡‹ã˜@ÙƒKÎ0‚v7˜a¾ûÔ >±kQMbÓ7„Éò|ä7evìhnArêˆFƒÎè¡C/M*MD°È¦Ä^)j»Ök÷s¾J "umX¨ÔEK!.„Ît›’ï‘/#(¦ß„PC˦F é„J>²gž{Ý?jÍ„‚>&”Ëzr'Æù–%[(Fî(çŠrUögQ ìu°À~ì.Ç•¼VÈÈæ‚4æÌ±&D`X͸™d ÐòøízH“@p4}  :;œh5-è‘-èX®…½éÒ&×´MÀžÊ6œªš®/ŸHqƒ+ 8Äu¯Û£©¿–Ó)ksªÈ­æDXÑññT1cinÀ/æhD@_Tš@y£;‚ÁtI n8Ÿ›–>kÜ@°­¢Â1/£ŠB·[} ™Æ†b¥(eÇ+kåT]¬œÊ¹•Ç~²jÊÒ¦ri²”M†à×ó±¦ÖÏo9Ÿ§rn Øç)'å†!ïíº¢=ŽT‚ábdK †&óAIHBÅP lêƒ( Y½Ä†ÅPr‰eàefCßTîX:žÕA†›„H8|‘ŒP×£¾Ã.pýŒ1½à8œ×³½žÜüÇ9óG Õc¦V<7&]=×虎G‰KPÓ BÐP˜!$p{˜æ³Å8*°HþX”%[Ým=ŸR®/S㲎žm½„À5OîÈýåžIj‡vH ¹üÂÂÖIÎÇC£P:Q(\Ž¢ñ‘Ö&åpQô/°ý™aw“Avyô*šÜ B° Mîk¬È«pZ¶/·Ï*šVT€o<3_áã,À ª*z?dwó5Q,ÞˆÁâà •£èz;oÍÏ`­±{Ë7RÃ9—ð²Ò|a¶oÌË×ðÄ”  6™cžcF…!)Ø•PËnL@šqÉúz˜¾?-„ùƒiÖžD¦X5üt zgöF@1)R°ÞÛ"Hº§&ùz+ìü‚wS,¬h8 é_çK°YÛNê¾Éð4uïqgBQZÃdø¹¡Ñû b(€å⹌>³™CªùÌ!}®D¸B0Ñd¨4òÚ pC©¶¢dS—O+/´›åXLÿ´<N'lö’ƒ¿²øXæ0Þ€_ù©h߸Iÿ(I¹ø ãYYáz„‰0k‚[ G£;` ®¯€ëkìS}ƒI}…™õb²:lgV“àG#àæñá=߯öÃ.0Ì®Šý‹\GxäP-·NY­$Í0;gß®þ!z·»ú Ò”b endstream endobj 3444 0 obj << /Type /Page /Contents 3445 0 R /Resources 3443 0 R /MediaBox [0 0 612 792] /Parent 3413 0 R /Annots [ 3442 0 R ] >> endobj 3442 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [471.129 198.722 500.518 209.626] /A << /S /GoTo /D (subsubsection.7.4.1.1) >> >> endobj 3446 0 obj << /D [3444 0 R /XYZ 89 721 null] >> endobj 3447 0 obj << /D [3444 0 R /XYZ 114.907 692.037 null] >> endobj 3448 0 obj << /D [3444 0 R /XYZ 114.907 680.082 null] >> endobj 3449 0 obj << /D [3444 0 R /XYZ 114.907 668.127 null] >> endobj 3450 0 obj << /D [3444 0 R /XYZ 114.907 656.172 null] >> endobj 3451 0 obj << /D [3444 0 R /XYZ 114.907 644.217 null] >> endobj 3452 0 obj << /D [3444 0 R /XYZ 114.907 632.262 null] >> endobj 3453 0 obj << /D [3444 0 R /XYZ 114.907 620.306 null] >> endobj 3454 0 obj << /D [3444 0 R /XYZ 114.907 608.351 null] >> endobj 3455 0 obj << /D [3444 0 R /XYZ 114.907 596.396 null] >> endobj 3456 0 obj << /D [3444 0 R /XYZ 114.907 584.441 null] >> endobj 3457 0 obj << /D [3444 0 R /XYZ 114.907 572.486 null] >> endobj 3458 0 obj << /D [3444 0 R /XYZ 114.907 560.531 null] >> endobj 3459 0 obj << /D [3444 0 R /XYZ 114.907 548.575 null] >> endobj 3460 0 obj << /D [3444 0 R /XYZ 114.907 536.62 null] >> endobj 1142 0 obj << /D [3444 0 R /XYZ 90 486.798 null] >> endobj 1146 0 obj << /D [3444 0 R /XYZ 90 418.568 null] >> endobj 3443 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F113 3438 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3463 0 obj << /Length 1755 /Filter /FlateDecode >> stream xÚX[wÛ6 ~ϯðÛä³X•¨+û–¦É.ÝNêníÎŽ"Ó¶V]2QŠ›ýúhSŽz–îÅ„@ è`±[‹.Þ¬/^ÝfñBú2éb½]È`‘¹ÄÉb½Y|ô®¼úu}s·\‰$ð2¹JÒÀ»z»Œï·e%Þջ뛷4}{sµ ÃÐ[¸»y¿ücýó«ÛD8²cœ¤ Ùˆ³]lÌù–Îî•Sé•È€‘œTOÃçÉW3cÃ*”¡G8úRð!q[*¼JÓ8ìíØÜ«žènKãCW×U»³+{UlxÛ¨Õ†¨mß5g¢¾¾í¡ëj¤"¯hyó ö<7 þ[…¡/>à¶ëÉ%e×¶ªŒ¡øYWª´OŽš¸$ˆÔOð%d~ì‡~¸\…AxïU_uõO1T]ËÎî6ª&òP ûŠÙ µ ï±*}k8Fxøäó8ár?ÍIû-îîF8Dä¸ÙÕi×4]ôЉ¥@"ñŠª.îkEk­y´Ä `ž°æáÐðˆ*Á´$ñõqyë½Ò,ÙU÷Ðw¸”6uMÜ^ý=*=ðš²k0øs‘!¨€K(Ê@´j8 _ºžá|çvh­;¢N*(² á è¡'ü.bŽ>Ö1†,¼øz’ž‹Pøqr–9¡?]óq•<‡Geâþ ÇÔñ´©%©we<+вTZÓª¡#ž1 ]4ê\oëyB/CõªžyWš±…_Šæ¡V—ÀI2¯VÃwc^8Ÿ $Ida"fÎOÃæZ!’ØŒù®PE¹Å>½®å¥e]hͼ-Si‘A(Í0Xh«‡¢/Ñç§ xgH* '–„f!¼õ2‡Ìt¤qîóNðâ :Ýr‘æ&,fdȤnæhb U$:$W5É !JG³ÒÄ»6LAKU]Õv÷¬‡Ò×5Ââű"$EÕ–¸3 ˜ºä²6j.ʉW h@á £pÂQkPséAðM£5-aÓÇ´ä ú:ì+»Ø±nvÏ ?!E{5UJp¢‡±¨ç‚G`/k8£-ÒÝý_¦T™ªòt,ÍA Ë4WGì;9/^’ó"ÏIC. ñXDAÏïØ9¼a¦µK›±ªÕ%ƒ6˜¬ÍvKôRO´Tw[Ê À,†Eæ\å`ËC¯J,Š*pt©Ú¢¯:Ú[vcÍÒwª]}5½U_ (R&XÞ!¾ š'ÞO-qáÑDaÍDг8“ë ËL:À‘C äòˆ É’äAò„ é"è´c'd¦yt¨îÀØ_%\Ö;e¯ëOÇ3Ü;«=ý¹PuüÁÜY7ë‹â=#o endstream endobj 3462 0 obj << /Type /Page /Contents 3463 0 R /Resources 3461 0 R /MediaBox [0 0 612 792] /Parent 3469 0 R >> endobj 3464 0 obj << /D [3462 0 R /XYZ 89 721 null] >> endobj 1150 0 obj << /D [3462 0 R /XYZ 90 633.532 null] >> endobj 3465 0 obj << /D [3462 0 R /XYZ 90 584.899 null] >> endobj 3466 0 obj << /D [3462 0 R /XYZ 90 517.153 null] >> endobj 3467 0 obj << /D [3462 0 R /XYZ 90 461.363 null] >> endobj 3468 0 obj << /D [3462 0 R /XYZ 90 417.527 null] >> endobj 3461 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3473 0 obj << /Length 1824 /Filter /FlateDecode >> stream xÚ­XmoãFþž_¡m«|Xk5£wß¶@6Íö®(zw‰Ûâ°·ÆÒÄVW–Riœ¬[ô¿—RެÈépŸfDrHùÛwÖŽï|söfyöêm:™—Å2v–·Næ;‰Ÿz~9ËÂyç^üýü_ËË«Ù\F¾›x³yûîù׳Ðwœ‰ rÏ¿¿¸üšØo/ÏgBwùÃÕåõìýòÛWo#9Тâ(ËVµH":óÙ™ñz¹<ûåLÀÖwú§¾ç§ÒÉ·gïÞûNôoßK²Äy°R['ÈR/òÑBå\Ÿýû‰J{_áa*"'Ž2/ %»6› éûîçeW»BÏæ1|½6ª^7Þæ+tôÍ…ð²ˆ%§ˆë)kC*¶ª¬ÿëGþ Úuþ2ߨÖQä…"%^†¤ã¯–yY’82¼÷t ËŸ‹XxA²ý˜„B¶ÿÛ”sÑ1žÍôË´û)vÂìI…é‘]Èì=}w‰±[,~0eEW /LCºj0¾jê ÈfM±ú’–¦Å¢¬KƒµqĘ`DþÆ! 3/ }þ”çB°—f=ÿªÓæ¦Óm©ª›mSè Õ³Í7ÿ¹¹øîüúúÑÈXÑ$ Dp¤¾½×íMïøiUáT8EĪòfÇzýšÖÏ®´*ö´7 Ã+Ïõ˵ú—îÌgǧt]TÓöã§N·»úyŸ{|ü>ÉM™›+“oÈ<ª[©âFUU“Ð<>˜=;郪x:$ªþ¢¯4´  ×òVo›vÿâÅ‹? ^ŠÓV.?–¦¬×ŸY)Ÿ‹’ ¦£tñÏ«7ç‹ÅåGÌhÙÔÄù‹>4>´ˆ¯ÃÈ&µ‹Å] ­éF÷Fа>™nOF*9©+ëò^œZÆ7ûä8¦ÿ¿”dÏ¥$˜là3­6»Ö†j¢28(äVüûäÌÏ:§^–‰ÿeÖÙÙv4o…z4@¦^ rd¹ YèR‹+Uf&\‹'¤ÚŽGÛ²Ã5ACeˆP•5ëÀ¾‰”•¾mZ¦2€çÚû™ˆ\ÝõÁ ÏZF  ª‹ÑQ’¾9ÖY5ÍsXIgTktáõÞ^ô(=×ZÓ³äGCÛ®9ÆWßœõë ¼§#pÚ@Ó M¡*«Ž>l°`%#ì&fÓÌÅÞ‹+ÄíÕÚÆÎ~ôÑ.ûÓ6Ô½“7€ŽŒ=)yÒÜô„‡øÁn|nL[®fÒww†­_ŸÐ=ñCT¦^œ’æKÊž‰ûPš îb¾Æ^¯p Ýåà‹M#pî2rïËf×UûY¹/!1á$«Žõ6·DQÃËtÄËUÛî¡tY‚ˆõ—è×ô=0† @8¾Ê£Âc-6ÏÁëÅŸ”æ£ï˜µÌ“cù)W D`¯IàŽ"×6ô”%ôH£‘#©uÁ·ýg€~cGG¾é•Œ+, ®» c#…)»j“c&GÏ(²ä t—6Öz½ÛÏm]Þl±õ¤>2mõ3ºK÷¼>-h]UÕô‡ÒBÉû²ÀN„mD}ñèªÄžNò*ÿ%ìMuœ RÀ‹‚8à¼Ç²ï<°ƒ¢ºkêN­Êª4{kˆ¿?ôI…t7Áχ}GL¶¶ßQö·&²è} R¸ëò±™³é=©í=`‡aœÌRìëfª£ŒAx—Û§ê~Š}õôIÉüð´=õ£å B endstream endobj 3472 0 obj << /Type /Page /Contents 3473 0 R /Resources 3471 0 R /MediaBox [0 0 612 792] /Parent 3469 0 R /Annots [ 3470 0 R ] >> endobj 3470 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [109.198 235.7 116.172 244.547] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3474 0 obj << /D [3472 0 R /XYZ 89 721 null] >> endobj 1154 0 obj << /D [3472 0 R /XYZ 90 220.371 null] >> endobj 3475 0 obj << /D [3472 0 R /XYZ 90 115.026 null] >> endobj 3476 0 obj << /D [3472 0 R /XYZ 90 95.772 null] >> endobj 3471 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3480 0 obj << /Length 1643 /Filter /FlateDecode >> stream xÚ­XëoÛ6ÿî¿B؇BBk…ÔÓʰIêì…v[¢ØÒÂ%ÚÖª‡+ÉI½aÿûîx”-Ùr“ýèHïÅßfÚRcÚ÷£Ëptví;Z`žåiáB ˜æ³‰ÉW íN¿úáâ×pzcŒ-—é¾iŒ]é¯ ‡é¿Üvõ‹7WÓW´|=½08çzøöfzk¼:»v­Žl»h–¢¹ï!Óˆ)cÚ¯6¶×ô˜­-6ÛÄn›=nínì2¦¿)Iw-ª4ÊÒ¿£&- É©¹e:.Háž8’r¹~›é‰XœéÑ&k^àŒ£ Ãrõ{ƒ»º¨ShL€¥X–íÉ’Æ‚ÆQÓTéܰ˜¾iÔTZ«oAßžY45WÂ? ~Q"ƒ¨ÚÌÑ_‹fU&J@¹ o³¶œŸ_볨®¥× üåfàªó‹²¬D«(L W¼QBÍ­qè{l?LÍÅ*Bžû´¬Ô¾"éK_¦ûXèØ€D¢Ê¼Hg9j¶Ojnþ—ˆ›¾°ÝÖnÀ†p3 GGH¦qıg[f0±´8ݽgZóÓ|íAråšLL—!"3ívôÛ‘H™œuA̹cÌ×<øúenŒ=ã}™&D½Þ^ቜŸ§EÚÌ yÇ\|è˜,ÚöÏК î;°hšfoÙ£eçIJÚíªå°‹y¾¨ðœ9QßÑL!Æ/—¢‘Ôl¾Q.Íÿ&\‰„oЙo‡tzJ'l7ëV Ai–—‰ÈPVkPÞÌ.ÿ˜½½Þœèï}tròÈz08ÎÈå‡vðÁcâÖà¬}òø+%³nкžEu ÜHëˆûˆûÜ{Œ¡ 0$›ÌÉOfVÆZÄž ,è

§ÙŸA•å<©rÙ7=|Iå’•ªwÛr…Êq4›Ù¦cYd@(‹©ïv˜’™‰¤OטäjˆˆÔ7K %ÀSœjsÓ V¯½)wETÈ+ï»I°·EÝ @Ý (°&MkH(‘(m¥ºáÉÅ^ŒÉ'èÝÞΤs}вt ¾Ê%à°,´ ¸Â•T SGÁ†Ý%tËѰ×!à8j"bÈE>/]WW:n…â¹SÀ³¯– 7Øà@Yëw<ú{¶7/úe­â&J ®gµ²± /c‡ù®Õè\´tØOî$\Ljó|°YŠ·yL6n“¶åòMÇ„ìâ ²â*KE¡Ô¬+ƒC„cAË|Ñâ‰é)´¯ÆÐוPDV—DåÐÇ¥D6+,ºˆ­+©@ÔØºrŸ@‡ ›"U¶M‹%ŒÁÕ«çÏiá—›K"ºxþ0A–Ò±7”„ÒL°kÕÛº9Ñ•ž.7˜1Tì.ñò'ßä`«cs°bHD nÕ‚ø”W´ôŽ1+S ‰¨ã*]7e¥lêh)^`ƒÉuÅ+šË¢ ÓY‚2C³ê€iœ*Ѧ)s8ûA‡b@á–ZØ8+eŽBÍÑÓÍ¥×jœ ±8#aŒSy)O¨úRZ´ÔRZkš“&ζöìTÛír- ¡8V¢ ªЀ!õáåBs0{`¸I@„ÑTåH½Ž0.R¾ì‚·Ý©„M7ò¨ˆö-v+hg¹êÃ!`‚rÐ=#å×1µßòœ ‰¯Zh5•®Ç¡ÒO% ìˆi }º•RµOÒUÔV‰zÙU¦VV©ÄÊ«Äy¿fá ðþŒ¾äÂÖÓ3ÕÇöÕúyYÇQƒúFmà¹øå3ÌjŸaÖ>6@Ócφ£#ìòu^“-{[¦'5}{OM[‰¶ž*z½©WcüGCYšå³Ö“é‡s«V“Ä'|ç‚TEʺ}êäø¢}ëU"ôºÛÁvÑžauÿ.Å\*¨„ÕÛŠ¼é¸èl'C#³è¾kw0õ¾ pÚŽ=éôe¹_¢J{Zjÿ?«næþ™T§‘¯3‘C4;Wzµ¯¢é ¨¢ÝmBâ*“õøøôzUðg”·íEÖù‰!ììýoí–i«ôª,êM~\/OµäÿÚ]ï endstream endobj 3479 0 obj << /Type /Page /Contents 3480 0 R /Resources 3478 0 R /MediaBox [0 0 612 792] /Parent 3469 0 R /Annots [ 3477 0 R ] >> endobj 3477 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [421.591 290.371 428.565 299.218] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3481 0 obj << /D [3479 0 R /XYZ 89 721 null] >> endobj 3482 0 obj << /D [3479 0 R /XYZ 90 690.045 null] >> endobj 1158 0 obj << /D [3479 0 R /XYZ 90 265.512 null] >> endobj 3483 0 obj << /D [3479 0 R /XYZ 90 181.254 null] >> endobj 3484 0 obj << /D [3479 0 R /XYZ 90 164.874 null] >> endobj 3478 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3487 0 obj << /Length 2489 /Filter /FlateDecode >> stream xÚ½YÝsÛ6÷_¡ËC‡º±Xüv/q¤íM.½‹ÕëCÛñÐ$qB‘*IÉõôŸï.vAŠœ:37çX`Àoûy‹ oñíÅ7ë‹/ßÄÁ"uÓHF‹õf‘z‹ØK\/ëbñ³sóÝõ¿×¯ß/W2ôœØ]®ÂÈs®_-ÏùïRø¡sýîæõ+~óúz)„pÖ?¾}»üuýÏ/ß„òDv€‚ÃVÖ¢E㤠7;ñ"pý ’8}eæ¯d 2|âŠÝp¹žç9ߪZµY_Öhyµ¡s\ hÕ}G´²¦oFŸ‚改¢~§ZœOL­eË,.]E´øz Œ¾Lñˆ¢€I÷Ë¿©“õÔïÍĦ-?à&t{C_µ”z£¡Þ(b„Î÷ÌùPVµ~ñ<Ù*’;e¡ñŒ¿]ÓÔ§”T¯SyÙP-¤A0ÝúÿBº}¦8˜Ùž`¸Øãûxº6ÝÇ“ú¬…ÚÒqÛ” Óã~8ÊŒ”Ì|ŽSnà¹çÉxßž7R]MüÝ+e4|u…GDr¥xã;@qÅþ;»tþžôÚgòϢųE?Ç}¿Aõ4íL #Ä:jXÔy9ÑÑ™é#ì|3uP›2\¬9×Êtd´¤ac“=¸Ÿû}RÒô mÒŽó´Ý\]„·Íûö³@¿Ujnõ#XE“0R×Ä((«*ƒûyž¤Ko¸ëäsÕ=}_­û2ÆœrÕÔ§‘¥>QÓøé’JQ;ϨlŽèà÷²3“7F6‚«AÄè›—&5³¡›Þ³Ä'¢¿kúIÄCÚ-ä°˜”kGj;*¯ÙÕ%2oQ3Å7: Ç= —†”7@cÈÇ êëÍ ÉI'RfI[VÒNÙ|çcmêZ.c>=ÎÔþ [fýl#[oÖu¿²¦ösOMõ.^¨zŸåÙ0Ø1fyÞ´êðqáëÄçyô©©œûøËá*Ïì{Ó˜ªhˆ6Ù¾4þÙXuÙ}Òº_æO*4zZâ4‰ýï¼ü,o~Â#šqìÆ^2EóyLÓþƒ¸¾&¶/6e·§¹»K›z™³h0ÏÂy„ ãò©ì¿¼×V¡y`—:Ç´¸(@ÃDøÌ¼>rS1<Œ…åéÑwC¬´Jc©cò„»ÉÉ0Í?,/^õý“cº .ãÍ2 ÚÀˆ«ekqâzé_?O¤‘ߨ<9ÀÛJ™Ô ÆC·jߪŽÓ’ó4~Y ÓA¢¶oª |¢GŠ%h¤Ì·Ô䔆Ÿ2àk‚§¤§T–—&ñâ×øѽ¦FðDä|§ZU2¯ > ßݨC~>ÃbŽùµê{·¶ÉCn¾¬XF­ÌVÍ–Šfè[«íÐRÐ-Uz¹´'©©sö²‘óº/Eèqù™ƒ3üÐáGBh  Jß̦½¸-ëC×”…zÁOí“W\ÓËÄ|”WîÆÙŸáÄé[Md¬ÑIê; lLå¹Xßá×DœW})«†º‘²! C*§Å’ÏøÌÔ•}9J¤Q]Î’œ~:Ÿ«¿ÀOœx?}³§±†×Ä*^—j¾yÎIåù®µL»9ôóú‡j8®œ†;5PTUŒ‘Æ$™/†¿`qæzqh(=LäùT…4ȳ§¥¯×¿] cðñIìFi°Èw?ÿê-  ÃYÝ Û=k·ðÓÄ =|®·ÿ9©Iš†2!(ÝQ„Ï ô›Ïr%$„€#X0ƒ=Þ`¾yu…꺬ç·–èÑšð1׈dùØ}ýj¬ ›±Kü9BÇÓƒyÛêË:fü,Õ­URÈ|ð)a§šM‘a¢ç}ѹz÷ãÛ·OY‘YÖ}òª&<ó"¨Ò# ¬nðOa§’uBIcv õ¤@¸Ià?‹ÛwE ‡dê&Iò,žM«~;¨:×Ïïwâ8zctûã]§òÈ«¥'³ß„bt C‡d(v§0~Í8zOYLÊ2þ°™„ =kÒ4Ï™¬Úb*a’> endobj 3488 0 obj << /D [3486 0 R /XYZ 89 721 null] >> endobj 1162 0 obj << /D [3486 0 R /XYZ 90 690.045 null] >> endobj 3485 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3492 0 obj << /Length 1828 /Filter /FlateDecode >> stream xÚ•X[ã¶~Ÿ_aôáÀÆK¶|iŸ¶³3=[`Û½¤ûÐ ÇVŸÚVÖ—™ÎCÿû!EÙqoÑ0DQ$E‘éÎÞ œïn¾ÝÜÜ=&‘“±,±³Ù9Yà$AÊ‚H:›ÒùŽÿï«w›‡ž/dà&Ìóe¸¯^{Qà~òx(ÝW?Ü?¼¦íLJWçÜÝüôáá£÷Ûæû»G)²#,cÐlDó$E¦›Às÷ȃ%»¦!ãQæø"bhO <|ÎY&­™<ôü8wWÕƒêòm­~oóFõì8ö‡ß·yñǯ ¾zÊëQ}Sþͪ˜èZŒ9r.ÿK=Â.Jê«vìuUª/‹•«ÔØ*3²Õ“jlˆn> Û«ÁÜÂêä·gbâÉžÏC±r÷[uy—ÛUcÒIÊþÁ}2Ï÷¯µ]Wì2ø[eà_b°W«o,èIé5Óø°¹ù|Ãa8£XŠ˜Å2uŠææ—ß§:HdI–8φ«qÂ,e2Àx¬7ï)Î"–ˢȑ0Bš3êªUï<ô1`púµç‡±_6qhÔâJ×ê¤`q4‡özXS.ÊD2qáwkµÅÜu}ók%±`i0‡FIûnPýpÇùŠ:?L`‘Šó,+érU¡¨Ñ=ä=M¨y)ëq=õû&é0Õm˜^Ôm Øˆ œZápÆá뛈@ÿä/ "`àúœ½ÌÉB1ß›ŠôR­Ö0³¨|­0• ǬnU­*–‰ ¿ÝáÃ7»èÚ ž§1õLæby:wÀ•Å, ˜Zb0è”SîßÁÑT€y4pÀt@H&ØK¯;Y{Ävž‘€kÇ4^ ðJ)©úô#A …:úW¿\Jü?Ÿà endstream endobj 3491 0 obj << /Type /Page /Contents 3492 0 R /Resources 3490 0 R /MediaBox [0 0 612 792] /Parent 3469 0 R >> endobj 3489 0 obj << /Type /XObject /Subtype /Image /Width 771 /Height 193 /BitsPerComponent 8 /Length 33505 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF``ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀÁ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?éô NGµº»²¶¼»»…'y.b…*ª° `:g9©œxv4gmNòÔn2 % ãÎá1Žõ{Hÿ‘{Hÿ°u·þ‰JàuKôºÒZ;†Ù%½®ØBÉTn鑃ÆAÇ5[- ݪÛè;Õ_E°‹s]!Pdœ–Œ ’@äUñ¡éGþ`ºWþCÿÄ×™x]dŽ D“4…õ+Ê‘Çïôí^Á~ iŽŒUÖ*ÊpAÚy©”ùbäú Fí#;ûKÿ .•ÿ€ÿñ4`éôÒ¿ðþ&³ôÝum·o4ŠëeÍÌ—LÁL±­°ð>}ªqŒîÉéPÜøõĈ¶ZÅæbûI¬Ò…Ö2¾\.70BØrƒ‘óqoGo‘|ÑRF·ö—ÿ@]+ÿ!ÿâhþÂÒÿè ¥à?üM7źݶ•§Û[BßN¹Ô[ËŠ{©1 ã.ÿ1ÆTtØ¨é’ ðĶڷÃ}>kZFO²¯Úoë6à¾é3•<NAò4¯¿‘ilXþÂÒÿè ¥à?üMØZgý´¯ü‡ÿ‰®nëW]'H{'ÕÛOT¸é×Éó`µU]îZS»qlì–×#Õx.å5/h·_iR=œ^l¾fòÒ²½»9Ï9Í4®›ôüÈMXƒûLÿ 6•ÿ€ÿñ4‡CÓ?è ¥ÿà?üMakz¤Z$º¾­y}u½¾µm˜šFU‡ÊŠ„%Žp9Ï5©u¯µ”ë=Þ˜éw% x KÒÊKÌ©0`bYrÃ8äÃ’“¾ŸÖ× +;z~v,bi¿ôÒÿðþ&•t]3<èÚWþCÿÄÖHÔo—]¾MZÑ¢+=„qÃm~æ0]Üo I2¥Fvàä`Ñ¥x†óOÓ¢ŸS²/§½ÝÌ"ïí;å^B3_»„ÀÃÓå ÚJïúÛüĵv6¿°´¯úéøÿKýƒ¥ÐJÿÀøš¤|Wqcn³êº:ÁÖ­sl-î„®ÛvüŽ ¨V;‡BËמnëê‚í¬.´Xûls"[ÞùˆÑí¹‘dÎvãž0sо¶þÁÒ¿è ¥ÿà?üM'ö•ÿ@]+ÿ!ÿâk#Qº¿Ñ¯¼eÍcÿ@+ÿÐñ3 n)hd_f±ÿ N•ÿ‚è?øŠ>Ícÿ@+ÿÐñ%%; »#û=ý´¯üAÿÄR}žËþZWþ  ÿâ*ZJZR&‚ÅF²´¯üAÿÄV>¡yi;4½$Ü6ÿ²V¼àùgÆëÞµv. ìÔ°¿¶ðúf“ÿ‚Ëþ"µn ’C¸izNìÿ\á†q“Þº´œ\Û Ô¯îÜ·x¦ó+K…Ó´ŒØ*ÛÿÕ•1„ËiºGþ íÿøŠŠ8BÉ“V%+·¼ú•%}ÝFÛa/ìÍ#ÿvÿüEHä¤à®ßÿˆ¨1óf¦U-Ò’©.æžÎ=ȯͥiÿ°lüE6aiü:^‘ÿ‚Ëþ"«…ed‘KšWÜ\‘ìO´nº^‘ÿ‚Ëþ"•ÒÓUØžfNš„Ýì4oüZÿñº53œ?GÿÁM·ÿª‹×¥2W ir æfÀÔnN›£ÿàªÛÿÓF§lghÿø*¶ÿãuŠ×_.*9ÝÖ•—aó3©Žòÿ˜nÿ‚«oþ7Vcš~m3GÿÁ]·ÿ\ÕµÉÝÉ«Íy€0h²ì LÛ’K||º^ÿ‚»þ"–t½ÿvßüEfÚÜy‡“ZháEAÌˉ¦9Ò´ü[ÿñãŸýtü[ÿñrn©I§Ê‡vl1ÊQ˜m r{àõ+]u-ôÑ5_ü “ÿÔ8–™kQÒ4Ó®Êèz8a„§Â!IÈ;io4Í )|¸<=¢<:Cµ„*2Îdì8>†¹Y~ÜtéD³JXZÉ»æ'Ÿ,æ¬Ü}® wí ÒÉ7‹)Œ7P²ÀÉÇj9æïö&—ö¿²fxí;ü¿'t;÷çqäg9ãûM'B•ŠMáí $IžUÓáa¹©ÁØ22=eyúwö—Û|s?iûO•º ›·ïÆ3œgÞªF÷sj2´±¤×O(BÝH[èQe»[];;UþÅÑÏî#$¶Ÿ$”$•É«ÛD?óÑ¿ð[ÿ\Y‚ù’Ù–y@6Ðôcÿ<Ö¥ŽÖÿëåÿ¾y’­$}<%&µ·ÜvVZQ®mŠ61A§Û=¼2]HŽIo´ÝK;r1ÃHÌ@ö-“Á§XÛÙZ§—ooÅdª£dòxêÇü#šý¬?ðOþ?Gü#zý¬?ðOþ?EÂÌÃO_íé{{‹¨îã‹Ë*ÑH¨©’Û°ÃäúÒaè¢Õ­Mžè F+ˆX6ÕÉù@ Æ6àc­ÏøFõúØà Ÿü~øFµúØà Ÿü~–Ÿ×ÝùMêÌ+mG³i+yIeŽi$–âIÞ3”ffbIç  ÛmG²»ûL6Ònò*Iq#Æ®ùÜË1Uc¹¹O©­ïøFuúØà Ÿü~“þ{ÿúØà Ÿü~ÐXÀ¶Ñt[D‘Ðɵ¿—<Ï2$Gª"»Šp>Up=Mm£éDè!šBížêYŸ÷m¹çbÁC íÎ:ñÉ­øE¯¿è#aÿ€2ñúQá{õ鍨àŸü~‹ ³2£Ò4Èõ;GmÓÜ\©I¼ËÙyùJ3•Ú7602qŠŽ-E†Æk5¶‘¢›fæ’æWl9@²3P§•§‘ŒÖßü#zý¬?ðOþ=Gü#zýl?ðOþ=EÐY˜’hšD–PÚ&T…ÞDxî¥Iw>w“ `í»'9'=éÓhÚ4ÓÛÊÖaL h‘ÈÉD9EdRž@`qÚ¶áÔ?è#aÿ€2ñê?áÔ?è#aÿ€2ñú.f>›öSj3OsÒ^\ùÿ»ˆÆlT ‚Í“„ñœô4³îïZ?ðŒêô°ÿÀ?øýðŒ_ÿÐFÃÿdÿãô\lÆ-šcr+oþ{ÿúØà Ÿü~øEï¿è!aÿ€2ñê..Vs’-Dk§>½=u ü“ÿS?á»?ó°ÿÀ)?øõ>ar³š¢º_øD.ÿè!cÿ€Rñê?á»ÿ …‡þIÿÇèæVsTWKÿ…ßý,?ð Oþ?Gü"ô°ÿÀ)?øýÁÊÎj–ºOøD.ÿè!aÿ€Rñê?á»ÿ …‡þIÿÇés•œå-t_ðˆÝÿÐBÃÿ¤ÿãÔÂ#wÿA ü“ÿQÌ.Vsµ éÿá»ÿ …‡þIÿÇ©„nÏüÄ,?ð Oþ=G0r³˜¤®Ÿþû¯ùÿ±ÿÀ)?øõð‡ÝÏýþIÿǨæVrô•ÔÿÂuÿ?ö?ø'ÿ£þë¯ùÿ±ÿÀ)?øõ+9V®c\pMz‡ü!×_óÿcÿ€Rñê©sðö[¡óê?ø/ÿ©–¥AYêx¤v¥åâº0a‹½?…þYÈ¿±ÿÀ)øýOÿ åñ·Øÿà¿ü~¹åDu)ÓêyÛ\Ø©#S%wgá‘ÝŸ·Øÿà¿ü~§O‡’ÇÓP±ÿÀ)øýe,<º*ñ8/ úU«x‡q]¿ü SÏýþKÿÇéÃÀ“Žš…þKÿÇê>¯PN¼N8 FÖøÜÜùˆXàŸü~ƒà›“ÿ1 ü—ÿÓú½@Uâq1ÛóR¬_5v#ÁWCþbø/ÿ x*èùXàŸü~«Ô^'/´,uÊë ûÞ+ÕƒnˆÇö…‡þIÿÇê„ÿ ÞvÜú…‡þKÿÇëJTevC«Ž+DÎÑšèW·oà­ÆP°ÿÀ)øýYÿ„>ïþаÿÀ)?øý)М¥r}¤lsL±­a__ã ïeð-Ô¿{R±ÿÀøýT†’9ÉÔl?ð_þH­iÐKâ%ÔvÐòû™]òsUÏ™Œ×¬7Ãaí ü—ÿ’*𣠻ûFÃÿfÿäŠíŒ ŽwÌÎ Ì´ö‹½>ÉÀÔ,?ð _þ?Jßenº…‡þKÿÇéûH‘É&ydÞ*œ§×­†%ºêø/ÿ$TMð¨7]BÇÿ¥ÿäŠ~Ò!ÈÏ™K6jH—j×±„¨åþÇÿ¦ÿäŠAð‘üÄ,ð oþH£ÚD^ÎG„,õvr+ÕGÂuþ?ìð _þH©GÂì5 ü—ÿ’)ûX‡³‘äÓ AYw Í{LŸ |κþMÿÉ]¾Fýu ü›ÿ’){X‡³‘â…ýés^Ò~ ÃÿA ü›ÿ’)?áLÃÿA ü›ÿ’){H‡³‘ã±Ë´Õ‘6{×­š‹þ‚6?ø7ÿ$S‡ÁØÇMFÃÿfÿäŠ=¤CÙÈóYŠ‘[0HÒ]Òü$ ÓQ°ÿÀ¿ù"­ÅðÑâ鍨à ¿ü‘OÚD=œŽ2À©N3]¸ðàq¨Øà ¿ü~š~Üÿ!+ü—ÿÓö±Ir° š¯%À Œ×t|pF?´l?ð_þ?P†ÓÏö–Ÿÿ€2ÿòEK©ò3€¹”ã"¦°bÇšîá¬Î0u-?ÿ%ÿäŠ|_n!ûº–Ÿÿ€ÿòEÒ!ÈÎVW•Uf`Ç0 †V PGp}+¸o‡÷M×SÓÿð_þH¤_‡·þb:wþKÿÉsÄ9Ç$ª*Å*¨ —·*öL d_îÜà}Ïÿ®´x äÌGNÿÀ ù"ÿ%ßý´ïü—ÿ’)s@|²91HŒ’G3# 2µõÉzæÓÚuÎH¸$ÿÓýÏÿ®¯þK¿ú ißø/ÿ$Qÿßý´ïü—ÿ’(æ€rÈåʆü¹ÿ㔢EÏÝŸÿ®øåucÀ·cþbZwþKÿÉ¿ðƒ^ÐKNÿÀ ù"Žh,ŽJ;[UEU†eUUEýȽ©|‹qÿ,î?ð>çÿŽ×T<z?æ%§à¿ü~—þ»ßú ißø/ÿ©ýßbùª÷9_&î\à}Ïÿ£È·=c¸ÿÀûŸþ9]_ü!—¿ôÓ¿ð_þ?Gü!wßôÓ¿ð_þ?Gî»5^ÿ‰Ë­¥©ëÇþ .øíZ@‘¢Çkk¨½y?‰<’y'“[ÃÁ·ãþbzwþKÿÇëæ¶»ºµ•¢y-§òKÄ…ÿw€í,ĬÇSÓ5Q忺‰“›^ó:‡ò&Ãÿ_wŸúU-¿äN‹þ¿/ôªZ**|oÔT?…Drðø bÿ°ÿé0®»ÅÆámRòÒO.â gxßí`88<åa_ø·Ñú¯þ“WQ©ÚE«iwZ|îëÌm” 0cŒƒYÊíhk¦ ×î-¬´—úËÞ\Ù®`H Ÿ)›L*Yr;cýìqYÖ¿ž‰b×¾EÅÒØÇutó\, ûH“n° ÇÊ:sÍt—º=­òéë,“bûâÚÓ°§ ò+ ÆšµÞ—á™®¬§x&Ä¢D@ìH àA8'±­!&ž=Nj޳§C­é¯c<²ÄŒÈûâ 0*Á†2êjO}¼ÊðIaoi¼—ÚÕõц¨ÅöB¸]ÄœD§h®Ó’,ok £Á<„Ëzm/ç+)D1I€*d=õÈ߸Ðþ×?iÕ¯¥¸·˜Mɬ‘@ÄaH œä«ƒ´È-â€Mvé½Å¸ß $¬Ç/“޾‡ùÒ×Ýþc]>_Ÿù…}uw Ø\Þ„ÀŽû ’3žƒ¯\cŽ•nç|öïw2Û»%ˆ)eún~`Önn4í: 1q,ë W—n⣠;@:v«^o½T¬Û±1ºZœ¦•âû- ëU¿Ô.µEì–P[2óy»•@Aõ$ã¯*ûxÒU¸:iÓ“û`]­·ÙþÐ|£”ß¿ÌÙ»r~îsÆ;ÒÿÂ7`tyôÂ󘥸k‘&ð9 ï ¤0zp}óQŸ Ù²™ ÕßÛþÐ.~ݹ<íàmþîÌmùq·íži-•ü¿Oø#ôóýà?á6º›V·1Á(Ž+kϵXƳM Q…ldõ8éœò+_Ã+ÿ„Š9[ʵPˆŽ µêÎ0Ã8a…da‚+ô&©Áá]:ÞXeI®Ä‘Ç2m¬æR ¹` ‘Ôc•kLÑ¢Óo&¼kË«»©£Hšk‚»¶.p>UPzžH'Þ…¶¿Öÿðù[Á:/6¸ë-jòãÅZÕ¼Ú•úÇg6Ø-âµS _(1 '”prOV«¤ó}ë>×L·´¸ÔfŽIKj % FÚåãÐwÍ'}mØjÇ'Ž5±¦Ïwk aýi2­ÉBQ¤‘‘›*€1éÆïŽÇzçâz±²žeϵÇú`óŽJFT@HËpzñÅ1|¥­Œ–‚{½k®íë±¶å#åë“ôö«‘ø~(¯Zæ=KPO5Ò[ˆÒEEžEÜÛTœ … tªÒÿ?×ü‰Öß×oó.è¾ »Ö//×ì1Ciiu-¯šnK;²3³f9þ÷áÞ¶üÚÄÓ4ø4¥ºXF7/rûÈ8g9 `*÷›ïK¢V]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Ú<Ú¥æûÑæûÐß66©y¾ôy¾ôwͣͪ^o½o½]óhój—›ïG›ï@|Úà56η«ú}úMv^o½q×Q4º¶ªÃþGþ“ÁWOâ"{Ãßùâÿ¯Ëßý*–Š>ÿÈŸý~^ÿéT´QSã~¤Ðþ}ƒŶ‰¿ê¿úM[–qjwvV÷?m¶O65“oÙ3ŒŒã;«6ÿ‹WÔôž´tßô»+;7âì ‘×þzn?ìü§#¾qÓ Ê4!ûEÑåoƒ¯fM*VSî8#ÜQö‹¿ùüoüÍ[÷Úé÷7۵ıDΩÁ£ëXZ_ˆ%’IžëPÓ.ía·3O%¢˜ÞÔŽ«"3³r3ØT‚(º 2_´]ÿÏãàžj>Ñwÿ?ÿ‚y©çÅ0%œ³Ma} ¨Ñnêžc‰[j0Âr:ä`ä —þ;5µIçŽh ’HäŽ@»¡1©f-‚F^ ž£Ö†ì+ý¢ïþÿóQö‹¿ùüoüÍO>),åšk èeFˆ wTóJÛQ†Œ‘×# VÔ.ÒBŽñÿÍ&?Ýë‘ßéd×/¥ÓtûèU[xT R@$gâ†ì 7¡ö‹¿ùüoüÍGÚ.ÿçñ¿ðO5KÞ©cyg£5ÄnbW··xŒo´°È.ù)ãsÃ"ñ]œƒ{[]Ç ðÊê»fxC"á‰Ú )9àƒŠ¥Æý¢ïþÿóQö‹¿ùüoüÍRËâ;XµY­ävŽhe’i<¯îÄdÁ³À|ciÉÏ#©ñH7K¥j1Nò$pۺǾbÀ‘´‡ÙÐ19`F9Ç/Ô,Cö‹¿ùüoüÍNŽ[¹&Ž!~ªòÌÒä@N ÆXÐʵl/£Ôl’æ%t J²H0ÈÀÊ}Á~¦®óiëž[’7íɺ“8÷ÇOäzS”Ïy ¦3²ýï+My÷Á*N0qî=iŸh»ÿŸÆÿÁ<Õ» )B8× =òOrIîIäžõ„·úåôSÞéÉeöhåtŠÚdo2pŒTŸ3p ’2­Ø“θX>Ñwÿ?ÿ‚y¨ûEßüþ7þ æ©a×. ê*Ö3NÖ÷ko6Ê bG;‰`£$Àqø–# …ìóÍæÿ£F#'”Û_;œ)Ã8'9ã"‹…ˆ¾Ñwÿ?ÿ‚y¨ûEßüþ7þ æ«wìp]$ØÞÜ1‰&“ÊŒfb@,¬C‚F:t­Z.%¿ÛnÒ=B èe“Nt89Áù˜zÊ¢ûEÑåoƒ¯fM*VSî8#ÜU×·ûN·pŽß¹û4;ãÇßù¤À'û½r;ý2‹ºÇ;ª ’OaCiW0~Ñwÿ?ÿ‚y¨ûEßüþ7þ æ¨#ñ-Óé¦v†4œÝÛ¨FSþ¦gP¬F~öÖ#Órž;Uص×{1,V7w®ÓMÛx•6ˆÜ©$»íñdõr{ˆ~Ñwÿ?ÿ‚y¨ûEßüþ7þ 橉mÜÛý–Îòíe‚;†hO•’™K= ñÓ¦v©…ŒK¶Ý;¤z„AÐË&œèpsƒó0ô?•F&¼#)x]OGH••‡¨ àqÅX¹ŒÉ«\†`aû2 ;q€xÀç':wí£7ˆc·Uil/yÓŒ!6ñä€ïót8' “€xªä‰<ì½æßÏÌ¿ø%š6ûþ~eÿÁ,ÕEüElš„¶¿fºd†Xâ–áULhÎNs’à8ð9©]·’ù­„ˆ÷¼IpBùo" ²s‘†êùO4r@9Ùk;ÿŸ™ðK5m÷üüËÿ‚Y«þ¢×2%…ÇØn,äºg`”+(ý0rx=Wß¶÷IrfجRËaˆ8öçPhTâÁÍ …¯fœ@/•$*\ tÉ#ÈÄg¨üêÏØµ?ú[àÿgQ[ÿÈvúö›ÿB޶+:‰EÙur„WÂMÓ^Âñ’©m´ŸÄ±ÇåM¾-§™m:—3$AŠ«(&@‡¦3Œžý«M~ëý?¨¬½A·Á»vÿô˜r·ÉÄãåqät'ŒþŠìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«qKq7Î"„G½—&S» ÅIÆÜvõ®#C¿º‡I×uWP–âÕï)î.ÙíÛc6ÔùœcÝ84¯þc±Ö}‹Sÿ …·þÿöt}‹Sÿ …·þÿöuÌÏâjôØì­w}hoCa<Ê‹µqÄbĒ߀jeϵfq®•,w1YÇs5£ÙÍ,ŽìNcîñ´üÌr8â›Óúþ» ký]ΧìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³ª:ö³}ftXì“Q¹·Ú‘– ÎŒtϵdÛx§Y¾½Ó´èE„7Ü]ÛÜLñ;¦aÆ8àç¡'ëÅl×õ÷'ص?ú[àÿgGص?ú[àÿg\ô^-Ô ·½x­M…Õì–QF¨ÂUeܱÜA¡ÊÀ#“TañÞ©k¥Yj:½œÑÞØMuvÁ£GŽ ,Ù>ƒ9¥}/ýmÈvÖß×c¯û§ÿA oüÿìèû§ÿA oüÿìë–›ÆÕ¶¨Ü=š<°$Ä–3ÛÂåÜ+!W9%sÔr8â£×u=vÃUÔ£žþÞXí´W¹ò¢†HU›yI¸9éœc9¡»~?‚¸%ëúîu¿bÔÿè!mÿ€ýbÔÿè!mÿ€ýs)ãJMA¢µ±y ·šybŽÒi]Ã(,âQ•]»‡ÊÙ$ÈÍ\µñ©ÿ 0°Ô!‚Ò.d†å¶•ZE ¹]&ÉÊü¤7Öß×õ¨º\Úû§ÿA oüÿìèû§ÿA oüÿìë–ñ.¥ya¯ê÷0Oq›-OBV¬…ÙKÎÖÀõ¥i^ØO¤ør÷S±ÕoMÊX;“q3O0]Û±ùO\mÀçqŠ\Ú_úëþCåÖß×Oó5þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ç4ýc[–{7í6…FìÓ´.drN0>~1óóÎ9ÀÏ/¬\ø;ú†ýJîÑm˜ß-Ó%É%~YÈ/·Ÿ—<äpi½/ýwÿ!-mývÿ3³û§ÿA oüÿìèû§ÿA oüÿìë›ÜA=­•”‘]­äv§Ožu!¥Vm²³ôÉžëÒ§‹Äz¿ü$-§ÝÇod²O,é=¬Ùpr:Ê GÏuùOlæ†ÿ¯@7~Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ât¿ë)¢éP´©q{y ÷&se,ü+à&ÈÎrIûÜ01V®üe®º’;kO²éI$p¹1$4yqӃÞíýzÿ“¿¯ëÔë>Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ä5­kR¹Ñuë{™D7vq^ÛÍbòBWxo•°ß61ô>‚»ˆZèÁDE9yXÇ”ÿ:5š_Öåo±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þγaµ"ûTW`î.×sÀ'ìðgŽÕº%¸YáIc„,ŒW)+1)n…G÷j…  ©ë>׈?òZ ¨=E% ¿¿äO‹þ¾ï?ô¦Z(ø}ÿ"|_õ÷yÿ¥RÑEOú‘CøQôG3 Ŀ庰ÌmŸØj6çøö®‹Bÿ–_öµÿÚ•ÌCÿ"$_ö_ý&&›©ÙÚi–ít—O3Gƒ"Ý: ¡Ü*ÿ¬QÆB7NåIÙ£·ºƒíV’ÁæË˜…|È›k¦{ƒØŠÇ}æýØë°Ü³Il¿f¶0²±.Ù< cØñŒ¯øH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê|‘ïý}áÎûí<¶Ö­™c™­äÝg§¬ˆœ? I8ëœÀs›“øj OPºšw0Þ[40° î©UAí·Þ²?á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨp‹ëý}à¤×BݧƒÖÚÕ¢ó,cs5¼›¬ôõ€‡äI'sØsÔWÿ —ýË¿ü?ÿ£þ /û—ø0þ=O•wgØé¢ÿÝ×ý{Cÿ¡KK«Xjh÷–o•ö˜Z-ûwmÈÆq‘šå†»¤‡."ºÞ@¾Þù gýw¹üéßðiÜ»ÿÁƒÿñêN}¯¼ÚèmÃ¥_Kym>©}op¶¤´1ÛÛFò îl»ç1ާ¯ÏÓ|k`·d`’·O&Å#”£w’L’íŒ ¹êA=*ÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉÿ×Þ Mt4"ð’}š(nod›ý{yä µ¥i™YŸ9àåOõö¥½ðíæ©d±jWö—RE"I ½€0‚ ƒ¾2ä±!ñ0çÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉÿ×ÞϱÓi:réZlV‹äü™'ÉaL““„^çÜú’y¢ûþ>ôßúù?ú*Jæá Òÿ¹wÿƒÿãÔÖ×t–*Z+¢TåI¿~1‘ûïB:|±ïý}âæ}ŽÖ°ŸDÔ#ö:°¶²¸‘¤eò7Mc—ɸÉ$Œ«Iö'þ /û—ø0þ=Gü$_÷.ÿð`ÿüz—${ÿ_xùŸcJïÃ/:],w‰‰îÖàÇq –7%d‹¸.uÅUÿ„>EÑáÓ–ãN’’Wò®4Ñ$@»x*W$˜ðzUøH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê9#ßúûÃö/ê>{䵄ÞBðÁD¯sj%ž2:¼räsÉ ÈÒqŸðiÜ»ÿÁƒÿñê?á Òÿ¹wÿƒÿãÔùWëïgØé¢ÿÝ×ý{Cÿ¡KRjŸo°šÐɱfœ©?0üFF{f¹1®é!ˈ®·o·¾HÀÿ]î:wü$_÷.ÿð`ÿüz“„{ÿ_x)>ÆÇ„,…Äo¦¥¾Ÿèšh ·Jc‘]O`ðÃ<ýïjŽãÂo5¬P »ycY§‘¡»µ2Âþl…òSxù—8 Iêxæ©ÂA¥ÿrïÿÿǨÿ„ƒKþåßþ ÿQÉZÿ×Þϱf_É-……“ÞÚɤ ¼–!¥oñÄûˆ“» uC\gü$_÷.ÿð`ÿüzøH4¿î]ÿàÁÿøõ>UßúûÙö: ¿ä'wÿ\mÿô)ª–©eý¥¥]Øùž_Ú"h÷íÎÜŒgë-Ù*Û›g’RÛY Ë…ˆP{ã¯zéwî/ëþ5 Õõ½”K-ÆÔF‘# ~f`ª8õ$QäJøSE[9íM«¼S„n$v!(73À>¡áí3T¸k‹Ëvy¶r³:Œç*ÁHrO="µwî/ëþ4nÜ_×ühz‚Ócü3¤Ix·Mh|Å(ظFdVdÎÖ#± ž¥,^Ò`Ôìv¥f4ʾk˜ÖB0\G<žMkîÜ_×ühÜ?¸¿¯øÐšÉâi5_´BÖóZ Yídƒvõ »ïr ž)Ðx[G·ÕÜ<ßO$»b<]ÌveÅmnÜ_×ühÜ?¸¿¯øÑäfU§‡ôÛH pëmöPÏ3¹ò·Û–'¹ü:t žÑžÖÖßìÒF–‘˜a1\Iª«¹X1Г[{‡÷õÿ¯ÌÚ•ÌD-!‰•} 2ñÑùQ¸Ã0sK½V†;m.ŽÖÝ!ÁRÀ –,r ½MX‹ÃzL:€½ŽÔ‰D*¯šæ5r0\G<žO­kîÜ_×ühÜ?¸¿¯øÐð†Š¶ÑÛ­´ÉLæ=—R«&JÁ²ÿt{TÍá–eû …šÔYº«²ƒÎxêyÖÆáýÅýÆÃû‹úÿsº×…¡Ôl/ ²’;I¯!Ky¦tisç.ðëüëv$ò¡Hóª>¸©wî/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´UeÕ¬žÒ¥`aÄq­’Äà uþU-Ýí½œ×w;RP¼†8P2N4%àê@!ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´S·î/ëþ4nÜ_×üh´Uk ž{wyHžUvYùVh ¿ãêÏþº·þ‹zⵋ۫MkUó7êEáGѬ?ò"Åÿ`5ÿÒaSxWþC:7û¯ü®*Hÿ„.æ¿úL*o ÿÈgFÿuÿ•Åø%ò*_=6Нt‹#Û«¨e2†u©Ëil¬mâ‚qRQÁx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8slI-áYLmÃäÛ¹FåcÀ`=³VGˆ´Áxö’\ì•7fÄYQ–Q) 9ä`äpk!4 Vêâ ¯ÚÎ1Ùâhà‘˜ß4¿be#8™NvoÁá¾÷?N)n+HÖIîîÕYÖ0~Ó)ù˜…ƒêE2Þx.ˆòn¯œãwŸ62µ†s€sùö«ú´¯º–…DÒ#‡JY®tÆ’)5I¤¿Œ[’h¼É|¼¨A(ØÁãœUI­­’çETÓ®g²Ù|ÐÚý¥)tòÃF8 F>^3Œq½äÓÅßþIÿÅSÊ6™&i.L¨ «›™7(8ÈwÀü…T—êÖ6·0µ=+StÓ–é$g]=#‹ÝÉ áŽJ²ºˆßý_ÎÇi烛šžŽ'‹YšçNk‚u[YmÌ…âAâ«‚Xdg«ZžëP²²iV{ÛàÑ,«4î~v*¸œä‚0)ö—0ßKª.ÜgÎ71~[ñŸÂ…†•÷_Ó¸®^ÐmdMRûÌUò¬Ù­íñÙ\ù§ôh×þYzvÖ·šuòiî—o©Ýùóyd9ˆùÛCÈNÌvÎz·„±ùví<1î-¶;‰dœ“€ÝIæ¥ò?éâïÿ¤ÿâ¨ú¬­¸sns¶ö· =ÛA¥=°ŸL¹IbŽÆd4í*²JßëÛïa€îzæ®êµXu?³é\(™ªFòiþ(¿»D;Y­õ)ô$ƒVÿáOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ³*ÞÆå|BÖÍ ý†ÚY/bm¸Rò ¦AiN;ek•{;©#¿û6“%¹ŸK¹IbŠÂe4í*²JßëÛïa€îzæ»ÿøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ„’Ýîs‘ÜGu}gö;·’}VÒå-Ý“Ë_$1.Ñ‘œñœb“NÓïÆ/<ªË8º™ÞUÓÜ„ƒ±Zà¾Ö\l€H*8àšê?áOú k?øÿÖ£þDÿ Ö³ÿ_ýjjËúôÿ"uµ‹ôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ•îËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ²ýCþDÿ Ö³ÿ_ýj?áOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZ«ßxq-4û›‘­k?º‰¤ÿÝ=03ùŠ,‚ìµ¥ÿǤŸõó?þz»Xz<È—è/®£Ž ù¡SaàòYI',y&´~Å/ýï(øÝ j èI7ü}Yÿ×VÿÑo\ˆßÞ¦?éíôšÞ»kw2 &gw"âd,ädí®xvô®Äc:î§ÿ_kÿ¤ÖõPø‰žÇ_ðóþDè¿ëò÷ÿJ¥¢‡Ÿò'Eÿ_—¿úU-Tøß©4?…Dy²êdxV(³ÿ0%ÿÒ@k¥ð¯ü†to÷_ù\W“ý‡ÿ¨ÿé®û¿òÑ¿ÝåqZ5h?'y#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬M Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèzgƒõKÍWÃ1]jRB÷I=ÄIf5*gŒ6ÒN23Ôš’ÃĶ—ZmÅôÊÐE @ÁvulØ(%ƒ.rqÍaø9«ðîHì®#+uy~d|w.YHÎ~RHü*ÝÇ„ÚÐÌšRG-¼ð$rÃy;ó‚›–dÀ/‚>é @5âšeñ]ŸLŽî&[릶'ìò«BÊ¥Žå)•<Ý©ÓÄúC¥Ó‹¦Tµ¥‘ÞU(§ ÈJáÔ¥r9¢³`ÐuTNyeÞÚý§òd»’_.&£*%eÜän,7×n@ÕI<)ª\i-§Êöh¶ºtÖn²12‡ I•ù0rì’}×à5¿õßü޶Îî+ëT¹ƒÌòŸ;|Èš2yþëNzÔôˆ6¢ƒØb–†JÛP¢Š(QEQEQEQEQEQEQEQEQEQEQEËY]Ëg äÁç1¾váΘüüˆÇôǽFg»¹—Zùi‚KysñŸâ…GæE7:9kÛ}Jk¶övòîY8>c`á¾µ ·Z.ZÝ´”a5ˆÛ‚9®Ëjô9ÛПIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþòÜÖ;(¶k¿ C ÄÒÔrªçåûAÉúc5ÈMa¨Ý­ÃÉk7œú}͸ܽJùj£8þ"¬ÃÔôY¿ä¿õÞ_ýõJº°ð¼/ëþE7©ÈÜ ¯ï¦¸‚ÒìFZÄ%»¡;fbÜ0€yªÖšeÔ|Vr[J!¿EeˆÆ7´ˆS Œr¸Áööã·¢¶ökóüIN߇àr3C§‹ –:ÉHžh–Î_,­ó ˜à0I'oÍ£>‹iÕ¤„Æ÷#“L’hp_åÄ`îCŒm=†EwTPéÞàŽ#Q°”\Épl.!¸’ &2A ™Ól¿¼¶¶æo\“´VŒ’HÖosÚ­õÅœ‹:%Í‘‰ˆ ©û´ÜJ–ãžÕÓQO“p8]CJ¼oæ¡.öû‘–É®;†rÎT†Qd®¸ùzñW§ÒØÞ^^ýšìjvæ)¼³¸Gˆƒ=—ïguÏJë(¡SIÿ]î˜Þ´K->x×ìì·s_+`9rTŽ9vàŽ8ÇjÙ¢Š¤¬¬ESVMÍö™§k3]êã6ÑY£…Î7H&Rƒ¨x§¼Vµ3Jš+oÍ<ò¤QG¦–y‚ª É$ô†#ølkr°ÖôK+VÖîïtË«ë›ÐÑEoxžL3y[i3Ž$»ü‚£e´·þλ>$µ·³•nÚKëfˆÃçÈèŸdr ä×f5­(éÇQ‘±äN¾P9Æ7gx¢}kJ¶±Šö}NÊ+I±åÏ$ê±¾ybpzv¯9–Œ9µ}2ÏÁÖ“ë‘CA ¼²Y!Qò<±· (ܼnÀ9àÌŽîÈÉk®M¨éÒBú˜–õ­fY!µ>CGguÛ–8䎃ØÜêÚm“@·Z…¤ qÄ"Y•L½>îO=GOZ¹O«aÒÇ#§\é–þ¼¤¨–5Üë1­L¬rä© ½;0õ¥ÐåÓ¼M=õ༵&{tƒì¶W`É ±S#FÙ I<ÐÉ=m€æ<(ÖZ‡>Î^+hEåäq&àœ,Ò/ÑA7êMáGÑ:üIcÿ°ÿé®û¿òÑ¿Ýåq\0Qý‹ý€—ÿHÅw>ÿÎþëÿ+ŠÖ_Ü(üG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qXœ‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬77vkY<¥1,¾D²F2Ûwõäš–óÄºŽ— Ãj:U²²YËw¶¼2ã*Å£R¹Ü0@=ÿ¯ Ûn|.½¶²šûlÚ’Ã.ìÆÛ®¦ÁÈÏõ§Kàë‹‹{µƒIÑt‡’Ækaö'$LÎȉ03ѺöÇ>)ª¶Ÿ×oø&ïŠ/ô˜æ:–™j®,溅m¯ZMÞX«nvçpÁÕâp×z¸´;µ@ÅÏ™ÿä!l9åXvè~”^øZÁ|?©Xé:}…•Åå«B^(V0I ÅFq“U`ðÅÜZÜ7¦h PÞ™QFAäã§_2g?Lw§ý_×B~Ïž¿‘ÕQE†QEQEQEQEQEQEQEQEQEQEQEQEsšlQºÞXý¶~HÏü´j½öx?çŒ÷ȪšWܼÿ¯Ùÿôa«õRn䤬bi?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ ÚOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¥¸£°“È5뼿ú1ê•]›þA«ÿ]åÿÑT«³ ü1½ÂŠ(®‚BŠ( Š( Š( Š( Š( ²no´Í;YšïW¶ŠÍ.qºA2”@ûÀu8õ⵩tOùŸþÁçÿF Ãü1­ÊC[Ñ,­[[»½Ó.¯®oCE½ây0Íål¤Î8L’ì;ð: ?¶4MÚÍãÔt«NðÜ4w&áRÖ=îSœãh8fÇnHîRx¤’HÒTi" HªÀ”$ddvãš’¼âÏ=º½ðí…œZ ¶©§ n¬ïîncÿ0A;XÍ…^Rx÷Ð*%¼knŒ ÙÎF89ïMvÍrm…ÄFq’b7 `ž:ñ¹ï¡ëSQp *9'Š'$•åm±«0Î Àõ8þ˜o-V?0ÜÂIån.1¿vݹõÏõâ€'¢£’x¢xÒIQVÛ³\àœS€OàiRh¤y$FxÈ¡*HÈÓ‚ >ŠŒONð,¨fE ц”à‘ØÈÑ$ñDñ¤’¢<­¶5f¹Á8§ŸÀДQA IÀ袙 Ñ\B“C"IŠ2°=#¨§ÐEPEPEPEPEPEPEPEPEPEPT5Ïùj_õë/þ€jýP×?ä©׬¿ú¦·sz<uu®Ã¾S¶¡&-ÇÌð²ŸÈжlçµ™ZMAØ+@7þw~`ÖmŽ5ÅÞ«<Àÿh̤ É èAþs×Ú­¶‹tÿx“õÕgÿâ+£w1å}‹_üyéÿõõsüæ®ůj#þžÇþ“[×{¦§—i§Ç´.Ë‹… 9nA˜u<Ÿ¯ò®ÅŠˆµúûúMoQj6‡- Žçáçü‰Ñ×åïþ•KE/Ãßù¢ÿ¯Ëßý*–ŠŠŸõ ¢<ˆÈ/û¯þ‘Šî<+ÿ!ý×þWÃÿx‡ý@×ÿHÅw>ÿÎþëÿ+ŠÚÜL>#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®sc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oî[U}Í##HÙ9,2áT"†<¶ 8ÍM=–¿v¶·3E¦¥Í”ë,$ò“äd}ϰÈ~C‚:œð_ˆæñF‘Vò5įö„g‰"¶’G!H ò*–Iä‘Îz¡7ŒaÚØÛÀ²[ùvò© ª§Î}¨°={°çŽÌC´ï]ÚßÁw,ònüåBp$šD|/¨Á8'ƒŽx¡oáømm¢i­‹Ea›·»ÿB®)®—þ·³·õ±¹qâ*ÚííZišuf@ÚVVp¥Š+*Ì<OµW³ñ†™>•§^\™mšö—Ë0ÈÞP$ ±Ûò®N¶õŽ‘_¾»• ³5œ„×MrÐL„ dpÒ`v$cÉ·‚õ³²ŠE¶‘—OM>u…ÄH Ãb0¾`!ŽQ±ŽºšQóþ¿¦ë¿ùjurëºt:’éï4‚rÁ2!sr2ÈÀÄc NNGŠÎÓüY£ ¼‘ÙΦ[©àedpʱnË€TÎÕ‚ØÎE2}Ro-Õ¿‘o›´ñ]̬è ¯ r1nòr8ùE;DЯl59&»kv†&¸û?–ä±ó¦ó `T `pOZõý~ÿËõ.èzßößÛØçµ×HYÆ×a±\1^«Ý>¸< jÍÓ4ùl¯ui¤d+yt&Œ)9 å"sÇ\¡ý+JŽÀQEQEQEQEQEQEQEQEQEsúWܼÿ¯Ùÿôa«õCJû—Ÿõû?þŒ5~œ·v14ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏárܘì$ßò _úï/þŒz¥VÞkw´òZêÞ9iIW?xÿãUñüÿYÿßá]4*F0³cheüAÿ?Ö÷øQˆ?çúÏþÿ ßÛSî+1”SñüÿYÿßáF ÿŸë?ûü(öÔû…˜Ê)øƒþ¬ÿïð£ÏõŸýþ{j}ÂÌeüAÿ?Ö÷øQˆ?çúÏþÿ =µ>áf2Š~ ÿŸë?ûü(Äóýgÿ…ÚŸp³E?ÏõŸýþbùþ³ÿ¿ÂmO¸YŒ¬›©g‡Tºx^HÇØPK$d†Ž#: È! öÆkgÏõŸýþiÂÞÓ_kù/­ FÔÃ…˜nݸʱ¯R…“Nç?%ÜP&¨úN¢fÓ›Rgº›P‘GäôûHÜÁw…¹ëŒW¢¾ÔâÓ¬cûcÍý¬gÑM$‚2$;\;*’|¢Ç~ï,œŠì¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñƸQG æQª[êÖìâúæÇP’ÉD„ \2ùCnpìPgIgîŒ;N¿™´M—Z€Z…·ýòêSÜ„r~pÓ” Ãh8'ËÉn3]¿öÖÿ?pÿßÅÿ?¶´ïùû‡þþ/øÐ´Vþ·zÜâxgƒE½’K—‚ËR„©¨IqU‚GÊKò™#`Hù—§wPÑáO h—wQ³^Çwk!˶ԒK„g!s·vY†qœ:WUýµ§ÏÜ?÷ñÆí­;þ~áÿ¿‹þ4_[ú~æ/ø&F·§Û/м?¨lcr×oöv`«äJp œ.p3€3œâ°5 ¤[¯¥Ôc¶[é®n<¹u ,D£!ca2–«„=wg-vßÛZwüýÃÿühþÚÓ¿çîûø¿ãHwÖÿ×_ó8»‹«{mWQ¾¹›Q‚[*ɶµÉŠLerÃî ]ÌÙ¹ˆÁ<Ô°¹Ž÷PÓ^âót6ºß— EªKq m•c´¾_ nõ+Ðà÷ÿÛZwüýÃÿühþÚÓ¿çîûø¿ãU×úî.–þ¶±ÇøGTº7òK¨[¶Ï&¡êLa8å‘%¾>q´6鹫÷7vÇÄ7‰¨j·V׉4kcmì¢XŠ/"!‘ ,\38ò»r:í­;þ~áÿ¿‹þ4mißó÷ýü_ñ©jêþ­œN„í¤izS%Ö¢ÑO Iq*$¦V ‚-¦$lª€ñœÕX5If¶–š“ˆK m«=áç(ÿ¼a•%v‚ ?ôí­;þ~áÿ¿‹þ4mißó÷ýü_ñª¾·þ·¸º¤“›D¼²¹Ô.¡Ò ÕÖ®îMñD`WÌ[pB£;º63ŠÍ¹Ôf].È MŽ˜×W‹ö«­R[]Å_9U˜ü»ˆ†Ú:÷í/o4B&kæUÝ»0^4-ÿ}#lÒÙ^èú}ª[[O D™ ƒIÉ$’I$’I<’itþ¼‡ý~æZÒæMÉï^å C+ª• Ø8 ŸBÒ®Õí­;þ~áÿ¿‹þ4mißó÷ýü_ñ¦ÝÝÉJÈ¿EPþÚÓ¿çîûø¿ãGöÖÿ?pÿßÅÿC/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/ÑT?¶´ïùû‡þþ/øÑýµ§ÏÜ?÷ñÆ€/Õ sþ@—ýzËÿ ?¶´ïùû‡þþ/øÕ]GR±¼Òîí£¼·4/–•p Ry¡3ôq#C­]S©\gRÊåÁ ‘í‘õÏèš§/ð•86:×xÍöøŽÿþ¾‡þ“[Ö”¾2*|' ü=ÿ‘:/úü½ÿÒ©h£áçü‰Ñ×åïþ•KEMOúЇð£è Qÿ˜¿ì¿úF+ºð¯ü†to÷_ù\W1ý‘ýÿHÅvÞÿÎþëÿ+ŠÞÜL>#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®cc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oîR={u<ÚÕÏÚnã´°[„³Ûç;œ€ß";¸ÒÞÎR­$6¡¡È$c¥uÕ…_ˆÚŸÂQEfhQEQEQEQEQEQEQEQEQEsúWܼÿ¯Ùÿôa«õCJû—Ÿõû?þŒ5~œ·v14ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏárܘìjop0¿:<Çþû~u›sgö³iðÇ2 y˜,Šgt|óõ«?ði¿ô´ÿ¿+þ6E]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYwÙgÌï·çG˜ÿßoΫÂ=¦ÿÐ:Óþü¯øQÿö›ÿ@ëOûò¿áE—p»,ùýöüèóûíùÕoøG´ßúZß•ÿ ?áÓèiÿ~Wü(²îeŸ1ÿ¾ßcÿ}¿:­ÿö›ÿ@ëOûò¿áGü#Úoý­?ïÊÿ…]Âì³æ?÷Ûó£Ìï·çYÚu¼v—ŒƑƷ# ŠŠ3ÐTZvbúe£½•»3B„“’NÑíRÊF·˜ÿßoÎ1ÿ¾ßRþËÓÿçÆÛþü¯øQý—§ÿÏ·ýù_ð  ¾cÿ}¿:<Çþû~uKû/OÿŸoûò¿áGö^Ÿÿ>6ß÷å€.ùýöüèóûíùÕ/ì½?þ|m¿ïÊÿ…ÙzüøÛß•ÿ »æ?÷Ûó£Ìï·çT¿²ôÿùñ¶ÿ¿+þI£Y¼9a¨dsj¬¬2.œ^cÿ}¿:<Çþû~u[þí7þÖŸ÷åÂøG´ßúZß•ÿ «.äÝ–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYw ²Ï˜ÿßoÎ1ÿ¾ßVÿ„{Mÿ u§ýù_ð£þí7þÖŸ÷å‹.ávYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þÂ=¦ÿÐ:Óþü¯øQeÜ.Ë>cÿ}¿:<Çþû~u[þí7þÖŸ÷åÂøG´ßúZß•ÿ ,»…ÙgÌï·çG˜ÿßoΫÂ=¦ÿÐ:Óþü¯øQÿö›ÿ@ëOûò¿áE—p»,ùýöüèóûíùÕoøG´ßúZß•ÿ ­mg޳wÇ xX¬jgtœñô¢Èwf—˜ÿßoÎ1ÿ¾ßeéÚ5•ݼ“Íeo$s>YâRN%aÔŠ·ÿö›ÿ@ëOûò¿áE—q]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…ði¿ô´ÿ¿+þYw ²Ï˜ÿßoÎ1ÿ¾ßVÿ„{Mÿ u§ýù_ð£þí7þÖŸ÷å‹.ávYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þSQѬ­-ãž+xä[˜0É‚3*Ž QeÜ.ÍO1ÿ¾ßcÿ}¿:͹³‚ûY´Šxc™¼ÌE 3º>yúÕŸøG´ßúZß•ÿ ,‡vYóûíùÑæ?÷Ûóªßði¿ô´ÿ¿+þÂ=¦ÿÐ:Óþü¯øQeÜWeŸ1ÿ¾ßcÿ}¿:­ÿö›ÿ@ëOûò¿áGü#Úoý­?ïÊÿ…]Âì³æ?÷Ûó£Ìï·çU¿áÓèiÿ~Wü(ÿ„{Mÿ u§ýù_ð¢Ë¸]–|Çþû~tyýöüê·ü#Úoý­?ïÊÿ…A¤Æ°Ù4H¡Q.'UU _ŠM!¦hyýöüèóûíùÓh¤1ÅÜŒoμƒÇ'"¿ÿ¯¡ÿ¤Öõëµä;Ïü$Wßõô?ôšÞ´¥ñSá=áçü‰Ñ×åïþ•KE?äN‹þ¿/ôªZ)Tøß©4?…DyüÂâçþ`‹ÿ¤b»Ÿ ÿÈgFÿuÿ•Åyÿ›þƒÿÔôŒW xWþC:7û¯ü®+zŸÜD>/¼ôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+˜Üà¼_u¨Ø\ÝM¦xzÛRw¹q$òÙ5ÑŒ­ª4qùi†ùßåݫߨ¬ÛûK¨½œ¶±÷NŠ9â²w0 cg™¼ÈʆȪ¥”¨ÆFA ‹^5Ð&¿×^îæ F+8¡ºD¸´³bCqlcb?˜ •-÷ ‘ÜV¾%ޝ¤ëÓÛëÐèúlv‹%üÖ©ƶñ´GdóbËn‘Lg ÈS‘ìáçXtª5ÍgÒW½ôÕ>Ë~—ï{Ãæ¾‡¥øKVºÔ|,—º¬Ðˆ¦¹†i£O-C4‘ïÁ'nBdóŽM6é×—¨™má·Žs,ÈŽÛØªªÆÊ³ÆÎIÀ¬¿[íü8¹¶Žp`½¸ÔQfŒî^ê`Ô`çÞ¬M¢ë—ÓÝ\^[éD½¬P$+<¸m’-¼(d<åH©ó^'_ëÏþ§OëËþ ³ÿ ›ýœo¼é|¡/’Sìòy¾fq³ÊÛ¿w|mÎ9éÍE?Š´{x-æ’éÊ\FÒDzÞG;W‰ ¤®Üóœc¿JÊ›ÃZ•Æ SM¾â ß´ÃÔ'®қ>Ó7ø™·c©ÛŒU/ÃrÚ]XË*À#ŽÚæ9ãY¤—/,ˆü4™fû­’HÉ9ÀÎþ¿óëñ5.õÍ:IJÏ;oUFÙO#ä… Äí< ž éL"ÒÙ¬U'wkàZH$bÀ .W€wcñƒ\ÿü!÷ßÙ(’ÏÅì7‹,d\Ih‘ H¦DùÔì$’3óØÕ»/ßX½´ÐhåŠÎé ùÒÈ<é]Ï–a•9c‚O à×áý %Óü]ö·ýžöoN›¢¸/•bd‘UqŽ7,EéÛÓ6,|I Ü€L±[¯úQmòœ…†_,·ÝÛŽç$c#¯$W´ð¿’óÄònöÖѲ1óâ.wôÆrÊAõŸmàýBK1ýÕ¶÷µ¾†Y!ïO(u`¤t‚}¹ëFÚzGø~Z›‰â%í¤œM8Ȧ6´•ebÿwlew¶yÁçÐÔ’ø‹K†Ê ³<ùòÖ+y$íûÙERÃoC0x85B{-~ímnf‹MK›)ÖX Iä)'ÈÈûŸ`+ü‡u9â4-SO{kûQe=ð7&he‘£ŒyÎ$;\!?)P9Q¸dñÒ†#Dx§Gc>˶uU¤t†FA¸)P. 6õ‚IÏÓLjôÃfnD“íù&/²Ëçy˜Ý·ÊÛ¿;~o»ÓžœÕÑõ˜¬µcÕ²ÞÞ\Ç2¼e‘HÆ®¹!ŠnØÀ¸€AëYðxgTŠÎé^ IZkÕ¹XäÔîK ùnvù²½pr ^×ä¥Ï‹´û{›IJÛ^[Ë2K2Hà¡PWËU-Ÿ˜ç mÚsV.¼Ick$,ò)³’Ûí-r !T²ªpÎâß¡ª–:¡ ÖŸ=ÕÊLÐYÜ@å¤glÈèÊ– nã‚p95RÏÂ×°é m4¶í:Ce•fÚ»g–ÝÃ¥×çÿ?¯Ëþ ©‹4y¦XVyÖC(‰–KIPÆí¢MÊ<½ÙÝŒöÍNž ÓP6K;ù¡™FÌ –U“nÆaƒ <CTu êéu ’B>Õymp›‰ác1–Ž¿!ÇáT¥ðþµq¯ÛÞO4RGÌ’,†ö\4lŽª¢ »¨p7d“ŽO4º^C4àñn‰so-ÄwoäŹ.Öò(h‡VRTo¾Üâ´ã½·–ö[4“3ÅJé´ð¬X)ÏNv·å\»øJîm"ÊÅçL:,ºtŒ¤ŸÞ8Œr¿!ô=+SH°ÔãÖ/5E-"3ÛC Ço+I‚†BI,«×xíþ5Nß×Ì]?¯/ø&åQHŠ( Š( Š( Š( Š( vÖмrº]Üúæà•ËÁ>sŒüÊOaS}Š_ú ÞþPÿñº¡}¥>³¡\ZEuc1¹¸hî-edda4˜ÎÜ=AëìpEøoTÑ-¤›ZÖ®µé~]­s$‘D¹þÝIêIù-½D–…í'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`\·&;I'—­Ú·ý;L?ñèªïÚýë'P}šµ¡ÿ¦èQÑçûÓŒn‰”¬Ê>:Ôn-ü+3ÛMSÜ=¸ aŒàç>Þ•j-ÉpάªIvŒ óótïKk¤AnÌîL®dw’Ýíœg¶hþ¿ 3­5K¨í­am¯,ɉŸ$¶N'<⺠º\kwk"•X­¬Q…9õby«ôÄ‘¾ÓÛÑ­þ>•¯X²œxbÈú}—ÿCJàö6þ×ïLšìˆd vžk3Ï÷¡¦ ¥OB0kYSº±šž§¡ø›SŠÛÃQ^ßÝJþl“³X´ð˜œ€ÄŸ› ¬9ôZ×¶ñÞ½w§Ëu ‚:Éd÷P“e:$L¼ùlì@“+Ñ—#¥iÇ¡é1<¥¢ƒ§†§{a‚:óøæ–ËFÒô錶ÖÅX¡CHîIÉT H@OeÀ¡Áêëúõ3›â¡5ÕÌv‘ZšH#Ó™²|ÂÅD…¹ä.îØé[߈5X5û /Mk4ûM¼Ò´—1³í)·—®¯l–ÞÑlþÁäY*}€»[|ì|²ÿ{©çñÎ;S5] cX³½¸™ÄvñI‰‘›~9Þ¬éøæ‡m?­O_ëúØ‹Nñ¶©«]ÚyKioltÁ}8xšG$9VUùÔqÁ9üj¼Þ=Õít¨ïf†É¾Ûa5åª"?îJÁd;¾|‚9y¶môí>Òá'‚Ýc‘-ŪàœÈ\tëøÖuφ4ÇÓ¯mm#û3ÜÀð+–i*ÜŠ[ 3Δ ìíçúÿÀûM__/Óþ ×5]1d†òI®$··šÝàö§šÛpÊ Úyã½Jþ2×>ÍbÚ(îeÔÒÍn.,æŠ9#e'zÆÄ0#ÆON¼ñ5·‡t¨,$µx ¢hÑ%w‘ÉmŸwi$”ò‘ŽÕ4z.—D¢Ý‰Žà]y]œÊ3KqÉ5\šÿ]ÿÈ\ú]¿ÌÌoëÚn¯®Osymskc-¢Ê‚Ý,lvA¼àÄóœã®+¨ðþ¹s«im¸XÑdšO$GŸõAÈRrz3øÖ©¢A} Öζ÷7ñy3ÈûäV\c>^ເèÝ«NÆ8´û {83åAÆ™ë€1IC¿õý~¬n}ßµûÕ(äó5»¦ÿ§hGþ=-VóýèÓß~­vé„?ú”¥ Œ®Ë:UÆË7\ô¹ŸÿF½]û_½aZM¶9†åæýÕ?ŸïUÈ.s6yåÖ|]}§\]ÝÁiiiÄ–×3¹l¹d œmǵC©x›SÓf¼´²x¦M&Ånn$¼RÒ\g?(*T)Ÿ›’8«7úe†¥*Ëq‚P†?2Þ&(z©(A#ØñPO h×H{%UŠ1 ¬nÈ­9ÁH ¹#ó©önßטùÕÿ¯"‹øïV-yVÙöwñ˜™Ît”!ë»ßÝ9öÅhè¾-Ô5li“Gn²[ þÚQX`«…nIÆå9ç5J Ø®±y¨\9žt"Ë"ÆQ@°ø###ŽÕkKÒÆŸ©êZŒ³$·7qlUU\Œ’OrsÏ ¦¡ª¿õ¢ÿ‚'=³í~õKU¸ßf‹ž·0èÔªÞ½Aw6èáÿ—˜?ôjÓäcBI<½nÕ¿éÚaÿEW~×ïY:ƒìÕ­ý0›ÿBŽ?Þ¦1º¥fSñÆ¡<>•­î&‚C< ¾ 0UÁ5‰¨xŠëÂz¾¡im%ÍÕ¼Û¼ s,—L®æ3É%Ø`´ ã­ÝFÖ×U³kKÈÌ1 T;)È ƒ• Ž@ª£DÒÅµÌ nÒ­ÎÓ+Í3É#mû¿;ðx<Š~͇:±—qâ½RK-®–â¤ÈÎKl—qy.Àì~zðA$dfšž8×/´{»ˆáò–]:[¨g[•m™FB–BW£ Ž„V´Z&• ˆ­¹fŠcp®ò»±»™‰%¸8ç4Ø4 ÛÍÚ|²DЕy]•co¼ª !ô\RtÝšþ¶ÿ1ªŠéÿ[ÿ‘–$x†ûþ¾Gþ“[Ö”¾"*|'¤|<ÿ‘:/úü½ÿÒ©h£áçü‰Ñ×åïþ•KE*Ÿõ&‡ð£è~ǯö*ÿé¯LÑl­¥¬³ÛjÞí³ü£/ØÆÀä9ý+Åô½j‹+Fû\6×öð¬G;ª+]€‚ß)Ê‘V>ÕüôðÿþI×O+œt1u! Y»3ÞZòና6¶Jœô1ÁÆ?燹§}¾ëþ{ëø?øÅx/Ú¢ÿž¾ÿÉ:O´Åÿ=|?ÿ’u>Åö¬SþoÈöÙmmçžIæ·Ô¦–B <ºz¹8wƒŽâ£}>ÍÔk©FA =cu äË#§c^/ö˜篇ÿòRsüõðÿþJQì_`úÄ?›ñG½}¾ëþ{ëø?øÅoºÿžúßþþ1^ ö˜?篇ÿòR—í6ÿó×Ãÿù)G±}ƒëÿ›ò=ãí÷_óß[ÿÀ1ÿÆ(û}×ü÷Öÿð ñŠð´ÛÿÏ_ÿä¥9.­GY|?ÿ’”{Ø>±Où¿#ݾßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯ 7–}¥Ð?òR£7vǤ¾ÿÉJ~ÁöÖaüß‘îßoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWƒýªßþzøÿ%)>×Öxÿ%(ö°þ³æüyû}×ü÷Öÿð ñŠ>ßuÿ=õ¿üüb¼ÝÁõžÿÉJ…®Ó´žüìèö/°}fÍùýöû¯ùï­ÿàÿã}¾ëþ{ëø?øÅ|ýö¡ÿ=³æü ~ßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯Ñîtõ”¹ô¾ÂÔÿ*î-µ¤@<úìÏ8¿Â“¤×A¬DÚüQÙý¾ëþ{ëø?øÅoºÿžúßþþ1\—ö׃ü·ÐÿïÜ_áM:¿ƒü·ÐÿïÜ_áSìßòÛÓþoÅÛî¿ç¾·ÿ€cÿŒQöû¯ùï­ÿàÿãÈcÁƒþ[è÷î/ð¥þÚðoü÷ÐÿïÜ_áG³—`öôÿ›ñG[öû¯ùï­ÿàÿã}¾ëþ{ëø?øÅrÛ>ÿžúýû‹ü)Nµàïùï¢߸¿Âg/åoOù¿ußoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWÚ¿„âãCÿ¿q…g^ßx^UýÕΆýs‡úŠ=œ¿”=µ?çüQèoºÿžúßþþ1GÛî¿ç¾·ÿ€cÿŒWšYÝxn935ΆGýsƒú ØþÒð^ßøøÐóÿ\¢ÿ ^Î_ÊÚŸóþ(ìþßuÿ=õ¿üüb·ÝÏ}oÿÇÿ® æÿÂ%—q¡gþ¹CþÎ]\èæBbŸ@Çû–ßÔRä—òÛSþu÷£Ø>ßuÿ=õ¿üüb·ÝÏ}oÿÇÿ¯&´½ÑSdúýñmýlÛk>Ly’è?÷ÄáI©/°5VŸó¯½‹Û,‡>ˆ—–lFŽƒ,ʼnÀˆw&™ö%ÿŸŸ~rÿñºÃMsÁ˜¦Ð¿ïÜ_áRsÁ?óßBÿ¿q…/{ù1{JξôuzÿĽÒC‘ˆ4кô1ÉP !OJµ} ²@¸ $†â•ÀQ0=2z ä÷ÇåÇÿmø#þ{è÷î/ð¤:ß‚{O¡ÿ߸¿Â‡·~V5Z’Væ_z;{½.+Ö§ŠRÑ‚£º3÷Hô_ûÓþyÝàL¿üUqÇ[ð_iô?û÷øSµàÏùï¡ÿ߸¿Â¦Õɇ¶¤ú¯½§ö§üóºÿÀ™øª?°-?ç×þËÿÅW5¯ùo¡ÿ߸¿Âí¿ÿÏ}þýÅþ~ó³µ£Ý}èí°-?ç×þËÿÅQýiÿ<î¿ð&_þ*¸±®x3¼Úýû‹ü)ÇZðYëô?û÷øSµNÌ^Úuø—ö§üóºÿÀ™øª?°-?ç×þËÿÅW ú¿ƒIô?û÷øTGSðyÿ—þýÃþ7©ü¬¯kGù—àwߨŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ^s-÷„Ø|·:ÿ¶Pÿ…fÏ?‡‰ýÝÖ…ÿ~íÿ©*£iGù—Þb´Óã²GH"mí¹™‰8©$ô¢]"$EDJª0¸”?ïªñIn4‘÷.tÿ¶ÿ ª×v¤ÚåkUì¤ÄëÓ_i}è÷ì¤õ»ÿÀ™øª?²“Öïÿeÿâ«ÁÖþÉOúÝÿ%iÇS²ÇúÍÿ%jÖD¼U>ëï=Ûû)=nÿð&_þ*ì¤õ»ÿÀ™øªð)5 c÷dÐòR¢7ÐÿÏ]ó´£êÒÖ©÷üO ¿²“Öïÿeÿâ¨þÊO[¿ü —ÿНŸEì=åÐòRœ/-¿ç®ƒÿ’”}ZAõª}ÿèì¤õ»ÿÀ™øªtštRÙ-£BþB…A`FÒäsÆ|ûöËoùë ÿä¥'Ûm¿ç®ƒÿ’”þ¯ úÕ>ÿ‰ï_ØŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ^ õñË ÿä­^X°ùfÐ+Z^ƧpúÅ.ëð=ÇûÓþyÝàL¿üUØŸóÎëÿeÿâ«ÂîÐfÐòR™5Ý©,ºþJQìªÖ)w_ï_ØŸóÎëÿeÿâ¨þÀ´ÿžw_ø/ÿ_=µÔ`ñ'‡ÿòNœ—±¯áÿÎÎe0úÅ.ëð>‚þÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªð}nGßðÿçiQ5ÔDñ'‡ÿòNc>âúÅ.ëð>ƒþÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªùìÝEõžüìé¢ê?ùéáÿÎÎc>ãúÅ.ëð>†þÀ´ÿžw_ø/ÿGö§üóºÿÀ™øªùì]DúÏþvuñ>¦¾|kû^ÏáÿÎÒ•o­;É ä¥Âo¨}f—uøöÚ £;¿•p ±s¶ydœžc©¤þÀ´ÿžw_ø/ÿ^%ݱû²xÿ%*#qi|?ÿ’t{÷Ö)w_ôö§üóºÿÀ™øª?°-?ç×þËÿÅWÏi‹þzøÿ$꼓dü³h/cS¸¾±Kºü£?°-?ç×þËÿÅQýiÿ<î¿ð&_þ*¾pÉÿ=tÎÊž'l­Ð?;:=•Aýb—uøF`ZÏ;¯ü —ÿŠ¥]Ñ]ʸ%8Ý<Œ2G±ÔWÎ&wÏúÝó³§ †ÿžºçgG²˜}b—uøIÝéq^´m…òßûùWøísâ ðzý¤é5½r¢ú×?ëtü”¥ŸX°†×7¶^Ly+ £FI'°Xý}j£EÅÝ“,D$¬™í¿?äN‹þ¿/ôªZ*¿Âˆ¼øw§]:…iå¹”¨è \HqúÑ\ów“hÞ”\a¾ˆìh¢Š“@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ÿÙ endstream endobj 3493 0 obj << /D [3491 0 R /XYZ 89 721 null] >> endobj 1166 0 obj << /D [3491 0 R /XYZ 90 474.937 null] >> endobj 1170 0 obj << /D [3491 0 R /XYZ 90 372.346 null] >> endobj 3490 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im31 3489 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3497 0 obj << /Length 2077 /Filter /FlateDecode >> stream xÚÅXÝoÛ8Ï_¡G¨e~ˆú؇Ò6鿀.v[ßîC·XÈ6c gI©D'Íþõ7Ã!eÉ•›4Üù…äh>骧 ‡fÁ6`Á»‹×Ë‹Åuy”'" –·A΂”e‹U°ÜŸÂ7?_þº¼ú0› ÅÂ4šÍUÂÂË·³˜…¿Ï¸Táå/o®ÞÒçë«Ëç<\þëÃÕÇÙçå?×J tǨX%`ÙªæiŽLÌmæt\\s6ŸËLF<΃¹H(–٬Ǭ±Ñ.ÛÍs CK{à!HªâkY*‡'rÌЗeM¼¾p9ÇZ”Z ñÚÆŠ<”û=Ñá´S§1qŸ†6¼ OÓчb$± _ëuú,Dš&$¡Ð½¸„œ(‹ÕÞqùm½ÂÌNÂMaÛ®p†h'Ê\¯°rnÑ<ì cƒÔÛ¦%¶VÏíž«²ëÊÑÏHgMÓ•.ðHá3v­ËA£]¹íÚ5•sé¾é\µÀmã}›&ùîJH>ƒüÝ^—·#,ä=&ªCQ5›ë€Óæ–FSâNqæÑ"2îo+‹e³`”8|뤮‹š&6 ¨XuÚ›$÷U «,·ms¸óÒÀë4j0Õ e.0õŸ#.ÒÌAgÍz}hgJ…™Ëðê+i[—‹À±¶Wš•Úéšf6†ªXš†û¢ñ,Ü:®“m=µ¬!>®¥p{±‰Ã/h¬µÞXp¦™óÎY½Ç“¬&sq§÷¨ˆ[Û±ÒUÒ‰=2–ÝkTh­Øïº.? i%„°QZÂht bƒ;µe}0Ú!ƒ«©íÚMŒÜÀãÐâ‡+oÆ9Øz…3‹Iæw®dy;_%txS‡Ç¼„Ȥ8äá»×FwD*ë¹óƒý4®  ´ÿ±Cä" Œ°~$qÜ!v¶ÉÝDä/?¹ÙaM=°Õ! à ‹˜L\¾i£oQaÉ@Ìý rîzÜ8Ø¥Ûx+¼Ì¨}¡UwXÍ×»âvãbDB8L ãý)ÁðÏÚm F®Ú5¸à„6Höøc#µ”,ŠÚ/¢œ–´3½mßÙB#Êã@ˆ$ʸÀîöËE”Ún°$•f‘Pv-¡¿sSø´¸©¤Þ6ÐîþÖ+;­óÚo›ahªK#žääôçaw±½òÊëýØ{Y÷Ôî\ïNØÝ•dŒìwþ4r]ÀE+ 0É£$îy>Í<)Ží½åäàÌ2ƒóú—Üù #¶ˆL=ñò“^ ʳSéJ „Ó–”cFO‰ó(‹3/Ö™ÂL)<Š!tŽËÞÍ {Cn,דŠtöÜ‹llxîP̂󩗫Šà½éØ},|?`ቴ‡Î`a º7æÄ8x„å©W‰ð,‚“1a~.ai–ŸT±ÚÅ^©6§í+uÂ^’E2–GsdfðÔÛËè=ˆI³Ø ý8FÒ(…œpFá}P6›r=Å"ÃCÈçÀƒ%é3àÁâ1<@÷SðàÉx°ixˆø`ÄÁCÈÓò&¾‹ ‘GJ&/ÃFòßbCÂ!_R?X®~¤€°”¢’ç $å=°nªâ¦ÔË(MGåOAï'¢Í„ñiõù7ø ÐVœ^ÉwkØ–£Úðü_ÔŽ~f ¹èãéz…_ãï*zœ\Šƒ{®ï3|SAƒkö°AÑ^A3å%!CzÇŒxý+v*gs¸ü{ÞÎ.=UöÏ1€ïÕ±´2/Cíð„aC>ðÔ(qæ14JfãôŠ_’^êÇÒK¥£ì‡óSÙ¥Ø0»(`;Íýe:3a24æÙ0çì[ý»9Ç!çΔå)èÇ ÜÉIÞ¡‚ÎÆyg}6ïàJ‡L`'>QžU Õò[˜½àÊ~¢,C!çcà¨ÝÙ¼· /X™:ø”÷ç#’qaæéÓ…9³|1t8AM>U®Ù±“ì¡ÓTE÷÷BNÇmÐ5øš f\‰âÙiÍÆS;)¶œÙÿ ;ñ¹çÓJÖ¯" endstream endobj 3496 0 obj << /Type /Page /Contents 3497 0 R /Resources 3495 0 R /MediaBox [0 0 612 792] /Parent 3469 0 R >> endobj 3494 0 obj << /Type /XObject /Subtype /Image /Width 771 /Height 419 /BitsPerComponent 8 /Length 63848 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF``ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ£"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?è4 NƒF´¹¹±¶¼¼»'’[˜–P¡ÀuUV Lç5aÓAÛFÓ|µŒƒIB¸Æs¸GŒc½[Òÿ䤨:×ÿD¥q:¥ú]i-Ãl’Þ×l! ä„*7tÈÁã ãšÚO•+#(®fÎÀ[è•_DÓâÜÁA—HD\“€2Ñ’HÔ‘W×DÒÏüÁtŸüÃÿÄ×›xadŽÚU’f¾¥`9R0<ï§jõÛåÙ¤^:1WX«)ÁiäTº‰EÉ­‡ÉªI™¿ØZgýt¯üÃÿÄÒÿaiŸôÒ¿ð_ÿTtÝqm>Íç[Í"ºÙEss%Ó0S,gkl<Ÿjœc;²zTcÎ-´¾DBòŠ’5°´Ïúé_ø/‡ÿ‰¤:™ÿ@m+ÿðÿñ4¾,Ö­´« kso§\ê åÅ=Ô‹…q—˜ã*:ìTtÉxfKm_áÆŸ5Æ­#'ÙWí7‰u‡p_t™Êž' Žyš\Ë_"Ô^„ŸØzoý´¯üÃÿÄÑý‰¦ÿÐJÿÁ|?üMs÷Z²éZCÙ>¬Ú|z¥Ä‡O¸ÔnO›ªªïrÒÛ‹g`$°Þ¹£Á—ê^ ÑnȺw³‹Í—ÌÞK…²½»9ïœÓM4ß§ãþBqk©[ûMÿ 6•ÿ‚øøšOìM7þ€ÚWþ áÿâkZÔâÑ%Õµk»Û¨ííõ›h¤ÄÒ2¬>TlT 8,sÎy­K­y¬§Y®ôÇK¹-Å^–R^UHÑ€Ë–Ç ”¤ž–þ­p”Zvþ·±7ö.ÿ@m+ÿðÿñ4ŸØºwýô¯üÃÿÄÖpÔ/S]¾MZÐÄV{ã†ÚýÌ`»°Þ*’:eJŒíÁÈÁ¤Ò¼Awa§E>§d_O{«˜…ßÚwÊ ¼„f2¿w †'§ÊAÊ)]ÿ[˜¬Û²4N‹§ÿÐJÿÁ|?üM'ö6Ÿÿ@}+ÿðÿñ5øž{ãUÑÖçµk›aЕÛnß‘ÁU ÇpèYzóÀͨuMH]µÖ ßmŽTK{Ï1"á]·2) ½vãž0}2½º…¼ÊÿØöôÒ¿ð_ÿHt{úé_ø/‡ÿˆªÅî{ã £¾¹¹6Ú\WVé6Ò°±óøUP>Uë’qÉ5^îÞ]7X‹DƒR¾k[Ñje’K§ys8b®IeÞÇ%phm&•·ýFâÒnûÀÿ3Wû"ÇþWþ áÿâ)?²lè¥à¾þ"²m!–ûÄ’ønkËñak%Ë$©w"ÊûVªe1 ç¸äœíÎ*ŒwW·Þ¿Õ忺ûV—e °¥1¤¬yfUá÷ã €:`ÑÌ´Óqr¾çIý•§÷Ñô¯üÃÿÄTo§iÃþ`úOþ  ÿâ*}/.ï\ˆË3¤wøA,­&Àa‰ˆ‰ e‰ÇAž*{€5¢K±2ºêf-8ÌIÿÁtüE4ÙéßôÒð]ÿS9æ˜M_*ìgÌû‘M?þOþ  ÿâ)>Ëaÿ@'ÿÐñ!¤§Ê»3îDm¬?è¤ÿàºþ"“ìÖ?ô Òð]ÿRJ|±ì.gÜìÖ?ô Òð]ÿGÙ¬è¤ÿàºþ"¤¢ŽXögÜgÙ¬è¤ÿàºþ"³XÿÐ'IÿÁtüE>Š9cØ9ŸqŸg±ÿ N“ÿ‚è?øŠCoeÛIÒð]ÿRRQËÁÌû•žAÓJÒð[ÿQìµÿ ^“ÿ‚Ø?øŠ¶éš®éŠ9cØ9Ÿq»-è¤ÿà¶þ".×þzOþ `ÿâ(¥£–=ƒ™÷.ÓþzOþ `ÿâ)|»Oúi?ø-ƒÿˆ¤¥£–=ƒ™÷*ÓþZOþ `ÿâ(ò­?è¤ÿà¶þ"–—rǰs>ã|«?úi?ø-ƒÿˆ¥ò¬ÿè¤ÿà¶þ"–Š9cØ9Ÿq<›?úi?ø-ƒÿˆ¥ò¬ÿè¤ÿà¶þ"––ŽXögÜO*ÏþZOþ `ÿâ(òlÿè¤ÿà¶þ"––ŽXögÜO&ÏþZOþ  ÿâ)<›?úi?ø-ƒÿˆ§âŒQËÁÍ.ã|›?úi?ø.ƒÿˆ£È²ÿ V“ÿ‚è?øŠurǰs>ã|›/úi?ø.ƒÿˆ£È²ÿ V“ÿ‚è?øŠ}ù#Ø9Ÿq¾E—ý´ŸüAÿÄQäYÿÐ+IÿÁtüE:Š\±ìϸß"ËþZOþ  ÿâ(ò,¿è¤ÿàºþ"E±ìϸß"ËþZOþ  ÿâ(ò,ÿè¤ÿàºþ"ŸE±ìϸÏ"ÏþZOþ  ÿâ(ò,ÿè¤ÿàºþ"ŸŠJ9#Ø9ŸqžMŸý´ŸüAÿÄRy6ô Òð]ÿRb“rG°s>ã<«?úi?ø.ƒÿˆ¥YwÒ´ŸüAÿÄPxF{Ác52å] 3êi¤þa:Oþ  ÿâ*O²éøÏöF“ÿ‚è?øŠ¡kqæsVÞm±š‰J \¨ÆmØ¡¨5”9Û¥iþá°ý’±ÍݾxÒôüÛÿñíN}Îy¬èþf¯:Sæw=(SIX×·–ÙÈÝ¥èøÿ°e¿ÿ[é§2ŒéIÿ¸lüEaC1[606kÉ÷4åK¡a °Ï>“ÿ‚è?øŠ±¦œß{GÒð]ÿCª¢sP¥ÈSY©Ë¸¹S[ÅŽ•ÿ@m'ÿðÿñ4ïìí,ÿÌIÿÁ|?üMRK°ÏŠÓ„åi¹K¹) ;Itm'ÿðÿñ4¿ÙºKtÑ´ŸüÃÿÄÔWr”éIi+1æ«Þµî+!ï¦ékÿ0m'ÿðÿñ5Ø´¯úéø/‡ÿ‰«S·¨Q ɦ›¶å$†géGþ`ºGþ  ÿâ)ë§içEÒ?ð]ÿH[ ŠPNáNìvD§IÒHãEÒ?ð_ÿP\iI…3£iCý&Øel"^ ñ‚8^„?¿ùjµüÃìR`¶[v'=ž2Oä)Á»‘+XÕþÂðéÿ˜‘ÿ€ÿñ4áxtÌ GÿÀøšç³t—„ºžsçC¥†Ö2ÿÓÔt«ŸiÓè«ÿà{ÿñúÝ/37¡rÿDðúé·Œº’¬°HA[)äµ-þ‘ [)ò|;£I#L¢5”J7;„;Xv5Í0¾]UžY ‚ÑÃ峓åœÕËßµ‹ã ó$X®Ò_,7P²ÀÉÇAIEá§iïìŸÙûNÿ/Éóâß¿8Û·ÈÎsÆ*펑 ÜÅ™|=£G"Ë$.‹g ÈåÁ‘•ô‡¾/µùÞF·³í?iòw[ìÝæy˜ëœn÷©¬…Ñ™œù‘ .d—anT4…€88Î T¬–„«õ*ZÛhëcj¤±ûÆUxdgqÉëÅtWÑ[êvmiv$hï"Lñî‡i¸<õ¡ÿΣÿA-?ÿ$ÿãô¿ðŒê?ôÓÿðOþ?I8!Úf]݆™}o}ͪÉôk :¨À1ž£Ë3N¹š ŠO F!Fµº–°rùl»€ìq“êk_þ­Gþ‚ZþIÿÇèÿ„gQÿ –Ÿÿ€2ñú9¡¸rËa¿o8ëX“h:,ö)dö® HcU.$BrÁá¹Îs[¿ðŒê?ôÓÿðOþ?Gü#:ý´ÿü“ÿÑx§±FÉ ÓížÞ.¤G$Ÿ´ÝË;r1ÃHÌ@öû9!Ó¬mì­WË··b‰7µT` žO½[ÿ„gQÿ –Ÿÿ€2ñúOøF5ÿ1-?ÿdÿãôùâ²0c±_í鮥Ž{{‹¨îã‹Ë*ÑȨ©’Û°ÃäúÒchÂÕ­Mžè F+¨X6ÕÉù@ ŒmÀÆ1[ßð‹jôÓÿðOþ?Iÿ­ÿý¬?ðOþ?Kš×ÝùŒž¬Á¶Ñô‹F‘â·É,±Í$’ÜI#»ÆrŒÌÌI#Üôt›k¤höwi†Ý÷yâG]ó¹–6bªÇsry>¦ºøEoÿè%aÿ€2ñúOøE/¿è%aÿ€2ñú|Ð,ŽzßFÑmRHÒÐÉ›.yžTHTEv!àp  ¢/J‚7A Òohؼ÷RÊÿ»mÈ7; ¹Ç^95ÐÿÂ%}ÿAü“ÿÒÂ#{ÿAü“ÿÐ¥>Yœúiúlz•Æ¡¶åî.¤ÞeäÎŽ¼ü¥Ší›8ÅG“£Ãe5¢ÛÈÑͳsIq#È6¦×f,¡O+‚0y®þ ßúØàŸü~“þûÏúØàŸü~Žh –g9.™¤Ég ©†UHäWŽæT—sçq2Û³ÎIÏz&°Ò&š ZÐ)4HädŒª¢²) ÁO 08í]ü!·ô°ÿÀ)?øý'ü!—ô±ÿÀ)?øý>x,ÎrÅæ³—P–k”™ï.|ÿ’2FÅ@9c“„þ‚%ÙsÖºøB®¿è#cÿ€RñúOøBnè!cÿ€Rñúj¤œ&Îp>ê+¤ º5 ü“ÿÓ¿á»ÿ …‡þIÿÇê½´IöR9ŠJê?á »ÿ …‡þIÿÇé?á »ÿ …‡þIÿÇèöÑe#—¤®§þÛ¿úXàŸü~øCnÿè!aÿ€Rñú~Ú"öR9j\WQÿm×ý,?ð Oþ?Kÿmßý,?ð Oþ?G·ˆý”Ž[bºŸøCnÿè!aÿ€Rñú?á »ÿ …‡þIÿÇèöѲ‘ËbŠêá »ÿ …‡þIÿÇèÿ„6ïþ‚ø'ÿ¥í¢?e#–¨Ý3]gü!·_ô°ÿÀ)?øýð†ÝÐBÃÿ¤ÿãôý´CÙHâÙph®Èø&àõ¿±ÿÀ)?øý'ü óÿÏýþIÿÇèöÑe#Ž¥®ÃþyÿçþÇÿ¤ÿãôÂqÿ?ö?ø'ÿ£ÛÄ=”Ž>–ºÿøB.?è!cÿ€Rñú_øBn?çþÇÿ¤ÿãô{h‡²‘ÈR×]ÿMÇüÿØÿàŸü~øBn?è!cÿ€Rñú^Ú!ì¤r"–ºßøBn?è!cÿ€Rñú?á ¹ÿ …þIÿÇéûh‡²‘ÉQ]oü!W?ô±ÿÀ)?øý/ü!W?ô±ÿÀ)?øý/möR9*Zë?á ¹ÿ …þIÿÇèÿ„.çþìð Oþ?OÛÄ^ÊG'Š1]gü!w?óÿcÿ€Rñú?á ¹ÿ …þIÿÇèöñe#“Å-uð…ÜÿÐBÇÿ¤ÿãôÂsÿA ü“ÿÑíàÊG)Euð…ÜÿÐBÇÿ¤ÿãôÂsÿA ü“ÿÑíàÊG)KŠêÿá ¹ÿ …þIÿÇèÿ„.çþ‚?ø'ÿ£ÛÄ~ÊG)Š1]_ü!w?ô±ÿÀ)?øýð†\ÿÐBÇÿ¤ÿãô{x‡²‘Êb’ºÏøC.çþÇÿ¤ÿãôÂsÿ?ö?ø'ÿ£Û@=”ŽNšÌS]ið]Éÿ˜…þIÿÇêðËõÔ¬ð _þ?R뮃TŸSžtyæ°æÌ²ð{×¢7Ù›®¥cÿ€RÿñúááÏö…þKÿÇëš´ç=Žš1„78Û1å¨É§^]*Ç€kµ?çÆ£b?íÊ_þ?P?Ãi$?6¥bíÊ_þ?\®%¹º•4ô<¶yI;Ôö°‚EzJü2*söûü—ÿÔËðîE_Øà¿ü~©ÂV²)UÆÚª…­(O¥t‹à)צ¡aÿ€Rÿñú|t½5 ü“ÿÖ.„Æë@æeRËTÚ vŸð‡^ÐFÃÿdÿãôÓà˳ÿ1 ü“ÿШM U‰ÇA f¶bm©[+àÛµé¨iÿø'ÿ©?á¾ó°ÿÀ?øý7Fl—R,çeÌnjXb Ò·á¾ÿ ‡þÉÿÇéG…oÇüÄtÿü“ÿÓT¦.x˜3|evVÓøNùúê:þÉÿÇé?á¿RÓÿðOþ?OÙL9âs2°i‚l7ZèÛÁwÌsý§§à¿ü‘M¾?ÚzwþKÿÉj›hŒƒt€IJÖ–àu»ÿÁ…Ïÿ­‘áIæ%§àŸü~ƒáHÿÌKNÿÀ ?øýG$Ú=%¥´ŠÈërÈà ­rA‡÷”ã GœÝ“ÿa Ÿþ9[ŸðŠê9ÿ–ÿ€ñúpð¾ ?æ#§àŸü~«–aÍ `„ž~Õÿ÷?ür¦[{sÔÝÿàÂãÿŽV¹ð¾¢æ%§àŸü~á}HÌKNÿÀ ?øý³h‘èzb¢¢Gv¨ *¨Ôn@pgJyѬE»ÿÁÏÿ­±áÍLÌKNÿÀ ?øý/ü#ºŸý´ÿü“ÿÔ{9Úù˜GH²îÝÿàÆçÿŽUy4Û1Ñ.¿ðasÿÇ+¥>ÔüÄ´ÿü“ÿÔgÉ<êZwþIÿÇèör«ÝœÈÓ- æ;Ÿü\ÿñÊ­"X(£Xã\íEè3ÉüIä“É<šßÿ„_Pÿ Žÿ€ñúÉ•$‚âêÚf‰ä¶ŸÊ/WýÜo¥˜õ˜êzSq”uu- ¯‡c „ÓÝçþ•KE/Ãßùâÿ¯ËÏý*–ŠêŸÄÎ*?¢9‡üPÑØ ôš»_j7w…µKËI<»ˆ-ã|µ€ààðkˆÅ ÿ¨ÿé5v¤Z¶—u§Îî±\ÆÑ¹BF8È4êÝÇB©hõ1¿qme¤¸¿Ôî^òàÆÍs@TùLØÚaRË‘ÛïcŠÎµø”lôK½ò..–Æ;«§šá`gÜzD›pí€N>QÓžk¤½Ñío—OYd˜ ßÖ…9ãО˜¬ø<%gi g¨Zùvëm#C*«Mœ€ÇnA<®ÓÏZž¯×ôÿ2–ËÓõÿ#­Šé'…%²Ž¡”úƒÈ¬/j×z_†fº²à˜K‰° "ƒ€AàžÆ´„˜xõ9ª:禽ŒòË3#À«È#¨©=ôó)ÿÂA%…½¤Vò_jwW×FF£Ù áwq »NIü°m¼i¬&ò-é´¿œ¬¥<Å&`©’@ô s×#~ãCû\Pý§V¾–âÞa4$B²DpA… ‚sj¬Ó ·Š5Û¤V÷ã|€’³¾N:úçIÿ_wùtù~ät:õÕÞƒasz\K;ìl‚HÎz½qŽ:U»óÛ¼QÜËnì8– ¥—é¸ùƒYºu¸Ó´è,Åij¬(^]»ŠŽ€íp8éÚ­y¾õR³nÄÆéjršWˆoì´+­VÿPºÔe²YAlË jÍæìNUÔ“Ž¼t«íãIVàé§NOív¶ßgûAòŽS~ÿ3fvíÉû¹ÏïKÿÝÑçÓ Îb–á®D›Àxä/¼28ÁéÁ÷ÍF|/fÊd7Woû@¹ûväó··û»1·åÆÜc¶y¤¶Wòý?àÓÏõÿ€Tÿ„ÚêmZÜÇ¢8­¯>ÕcÍ4%F±“Ôã¦sÈ­ x¯þ(åo*ÕB"86׫8à ᆑ† ¯Ðš§…tëya•&»GÈdY¶³™H.å€6GQŒzU­3F‹M¼šñ¯.®î¦"i® îØ¹ÀùUAêy ŸzÚÿ[ÿÀåýmÿè¼Ú㬵«ËkVójWëœÛ`·ŠÕL%| Ä4žQÁÉ=Xv®“Í÷¬û]2ÞÒãQš9%-¨H$”1h_—Aß4õ·a«lž8ÖÆ›=ݬ‡öu¤Ê·% F’FFlªÇ§¾;럈pYêÆÊxm”CÿÈŸý~^éT´QðûþDø¿ëòóÿJ¥¢·©ñ3žð£èŽZÿ_ö_ý&®žÎ-NîÊÞçí¶ÉæÆ²mû&q‘œgus0ø·ñØ ôšº]7ý.ÊÎÍø†;($uÿž›Oû?)ÈïœtÈ.[!Çr´]Vø:ödÒ¥e>àƒ‚=Åh»ÿŸÆÿÁ<Õ±q-®Ÿsq »\KLé œ >µ…¥ø‚Y$™îµ 2îÖs4òZ)íHê²#;7#=H"¢è»2_´]ÿÏãàžj>Ñwÿ?ÿ‚y©çÅ0%œ³Ma} ¨Ñnêžc‰[j0Âr:ä`ä —þ;5µIçŽh ’HäŽ@»¡1©f-‚F^ ž£Ö†ì+ý¢ïþÿóQö‹¿ùüoüÍO>),åšk èeFˆ wTóJÛQ†Œ‘×# VÔ.ÒBŽñÿÍ&?Ýë‘ßéd×/¥ÓtûèU[xT R@$gâ†ì 7¡ö‹¿ùüoüÍGÚ.ÿçñ¿ðO5KÞ©cyg£5ÄnbW··xŒo´°È.ù)ãsÃ"ñ]œƒ{[]Ç ðÊê»fxC"á‰Ú )9àƒŠ¥Æý¢ïþÿóQö‹¿ùüoüÍRËâ;XµY­ävŽhe’i<¯îÄdÁ³À|ciÉÏ#©ñH7K¥j1Nò$pۺǾbÀ‘´‡ÙÐ19`F9Ç/Ô,Cö‹¿ùüoüÍNŽ[¹&Ž!~ªòÌÒä@N ÆXÐʵl/£Ôl’æ%t J²H0ÈÀÊ}Á~¦®óiëž[’7íɺ“8÷ÇOäzS”Ïy ¦3²ýï+My÷Á*N0qî=iŸh»ÿŸÆÿÁ<Õ» )B8× =òOrIîIäžõ„·úåôSÞéÉeöhåtŠÚdo2pŒTŸ3p ’2­Ø“θX>Ñwÿ?ÿ‚y¨ûEßüþ7þ æ©a×. ê*Ö3NÖ÷ko6Ê bG;‰`£$Àqø–# …ìóÍæÿ£F#'”Û_;œ)Ã8'9ã"‹…ˆ¾Ñwÿ?ÿ‚y¨ûEßüþ7þ æ«wìp]$ØÞÜ1‰&“ÊŒfb@,¬C‚F:t­Z.%¿ÛnÒ=B èe“Nt89Áù˜zÊ¢ûEÑåoƒ¯fM*VSî8#ÜU×·ûN·pŽß¹û4;ãÇßù¤À'û½r;ý2‹ºÇ;ª ’OaCiW0~Ñwÿ?ÿ‚y¨ûEßüþ7þ æ¨#ñ-Óé¦v†4œÝÛ¨FSþ¦gP¬F~öÖ#Órž;Uص×{1,V7w®ÓMÛx•6ˆÜ©$»íñdõr{ˆ~Ñwÿ?ÿ‚y¨ûEßüþ7þ 橉mÜÛý–Îòíe‚;†hO•’™K= ñÓ¦v©…ŒK¶Ý;¤z„AÐË&œèpsƒó0ô?•F&¼#)x]OGH••‡¨ àqÅX¹ŒÉ«\†`aû2 ;q€xÀç':wí£7ˆc·Uil/yÓŒ!6ñä€ïót8' “€xªä‰<ì½æßÏÌ¿ø%š6ûþ~eÿÁ,ÕEüElš„¶¿fºd†Xâ–áULhÎNs’à8ð9©]·’ù­„ˆ÷¼IpBùo" ²s‘†êùO4r@9Ùk;ÿŸ™ðK5m÷üüËÿ‚Y«þ¢×2%…ÇØn,äºg`”+(ý0rx=Wß¶÷IrfجRËaˆ8öçPhTâÁÍ …¯fœ@/•$*\ tÉ#ÈÄg¨üêÏØµ?ú[àÿgQ[ÿÈvúö›ÿB޶+:‰EÙur„WÂMÓ^Âñ’©m´ŸÄ±ÇåM¾-§™m:—3$AŠ«(&@‡¦3Œžý«M~ëý?¨¬½A·Á»vÿô˜r·ÉÄãåqät'ŒþŠìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«qKq7Î"„G½—&S» ÅIÆÜvõ®#C¿º‡I×uWP–âÕï)î.ÙíÛc6ÔùœcÝ84¯þc±Ö}‹Sÿ …·þÿöt}‹Sÿ …·þÿöuÌÏâjôØì­w}hoCa<Ê‹µqÄbĒ߀jeϵfq®•,w1YÇs5£ÙÍ,ŽìNcîñ´üÌr8â›Óúþ» ký]ΧìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³ª:ö³}ftXì“Q¹·Ú‘– ÎŒtϵdÛx§Y¾½Ó´èE„7Ü]ÛÜLñ;¦aÆ8àç¡'ëÅl×õ÷'ص?ú[àÿgGص?ú[àÿg\ô^-Ô ·½x­M…Õì–QF¨ÂUeܱÜA¡ÊÀ#“TañÞ©k¥Yj:½œÑÞØMuvÁ£GŽ ,Ù>ƒ9¥}/ýmÈvÖß×c¯û§ÿA oüÿìèû§ÿA oüÿìë–›ÆÕ¶¨Ü=š<°$Ä–3ÛÂåÜ+!W9%sÔr8â£×u=vÃUÔ£žþÞXí´W¹ò¢†HU›yI¸9éœc9¡»~?‚¸%ëúîu¿bÔÿè!mÿ€ýbÔÿè!mÿ€ýs)ãJMA¢µ±y ·šybŽÒi]Ã(,âQ•]»‡ÊÙ$ÈÍ\µñ©ÿ 0°Ô!‚Ò.d†å¶•ZE ¹]&ÉÊü¤7Öß×õ¨º\Úû§ÿA oüÿìèû§ÿA oüÿìë–ñ.¥ya¯ê÷0Oq›-OBV¬…ÙKÎÖÀõ¥i^ØO¤ør÷S±ÕoMÊX;“q3O0]Û±ùO\mÀçqŠ\Ú_úëþCåÖß×Oó5þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ç4ýc[–{7í6…FìÓ´.drN0>~1óóÎ9ÀÏ/¬\ø;ú†ýJîÑm˜ß-Ó%É%~YÈ/·Ÿ—<äpi½/ýwÿ!-mývÿ3³û§ÿA oüÿìèû§ÿA oüÿìë›ÜA=­•”‘]­äv§Ožu!¥Vm²³ôÉžëÒ§‹Äz¿ü$-§ÝÇod²O,é=¬Ùpr:Ê GÏuùOlæ†ÿ¯@7~Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ât¿ë)¢éP´©q{y ÷&se,ü+à&ÈÎrIûÜ01V®üe®º’;kO²éI$p¹1$4yqӃÞíýzÿ“¿¯ëÔë>Å©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:ä5­kR¹Ñuë{™D7vq^ÛÍbòBWxo•°ß61ô>‚»ˆZèÁDE9yXÇ”ÿ:5š_Öåo±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þαjô¶ÿÀ?þήfóþyZÿßöÿâ(Íçüòµÿ¿íÿÄQp±OìZŸý-¿ðÿ³£ìZŸý-¿ðÿ³«™¼ÿžV¿÷ý¿øŠ3yÿ<­ïûñ\,Sû§ÿA oüÿìèû§ÿA oüÿìêæo?畯ýÿoþ"ŒÞÏ+_ûþßüE þÅ©ÿÐBÛÿÿû:>Å©ÿÐBÛÿÿû:¹›ÏùåkÿÛÿˆ£7ŸóÊ×þÿ·ÿEÂÅ?±jô¶ÿÀ?þΰf‰£¿ÔÕœ;‹µÜÁv‚~Íxí]H–ág…%޲1\¤¬Ä¥ºÝ®j鱬jÀÿÏÚÿé4MQpÑšß¿äO‹þ¿/?ôªZ(ø}ÿ"|_õùyÿ¥RÑ[Tø™…áGÑÄ#þ-ì_ö_ý&®“Bÿ–_öµÿÚ•ÎÁÏøý@—ÿI©4ÝNÎÓL·k¤ºyš<éÐmáWýbŽ0p­9nµìÎÞêµZK›,>bó"m®™îb+ô ›÷c¬^Ãp>Í%²ýšØÂvÈbÄ»dð1ŒcÆ2¿á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǪ9#ßúûÊç}‹vž[kV‹Ì±ÌÖòn³ÓÖDN $œuÎ`9ÍÉü5Χ¨]M;˜o-šXwÔª öÛïYðiÜ»ÿÁƒÿñê?á Òÿ¹wÿƒÿãÔ8Eõþ¾ðRk¡nÓÁëmjÑy–1¹šÞMÖzzÀ‰Ãò$“޹Àì9ê+Œÿ„ƒKþåßþ ÿQÿ —ýË¿ü?ÿ§Ê»‡3ìtÑÈnëþ½¡ÿÐ¥¥Õ¬?µ4{Ë7ÊûL-ý»¶äc8ÈÍrÃ]ÒC—]o ßo|3þ»ÜþtïøH4¿î]ÿàÁÿøõ'¾¿×Þ mt6áÒ¯¥¼¶ŸT¾·¸[RZííŒ#yw6]ó€HÇS׌gé¾ µ°[ˆˆ²0IÛ§“b‘ÊQ»É&IvÆFÜõ ž•?á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨäëï&ºxI>Í77²Mþ‰=¼òÚҴ̬Ϝðr§ŽzûRÞøvóT²Xµ+ûK©"‘$…^ÀAPAßrXÇø€Žs¿á Òÿ¹wÿƒÿãÔÂA¥ÿrïÿÿǨäëïgØé´9t­6+Eò~L“äÀ°¦IÉÂ/sî}I<Ñ}ÿzoý|Ÿý%s?ðiÜ»ÿÁƒÿñêkkºK-Ñ*r¤ß¿Èý÷¡?>X÷þ¾ñs>ÇkXO¢j‹‹{X[Y\HÒ2ù¦Œ±ËˆäÜä’FUˆ$û“ÿ —ýË¿ü?ÿ£þ /û—ø0þ=K’=ÿ¯¼|ϱ¥wá—.–;ÄÄ÷kpc¸„ËDzEÜ —wQÎ:âªÿÂ"èðéËq§I I+ùWh’ ]‹‹¼+’Ìx=*¿ü$_÷.ÿð`ÿüzøH4¿î]ÿàÁÿøõ‘ïý}áÎûõ =òZÂo!x`‰"W¹µÏ^9r 9Àä†äŠé¸ÏøH4¿î]ÿàÁÿøõðiÜ»ÿÁƒÿñê|«¿õ÷‡3ìtÑÈnëþ½¡ÿÐ¥©5 O·ØMhdس Ž@ÎTŸ˜~##=³\˜×tåÄW[È·Ûß$ à®÷?;þ /û—ø0þ=IÂ=ÿ¯¼ŸcFãÂBâ7ÓRßO‹tM4P[€%1È®§‚0xaž~÷µGqá7šÖ(ݼ±¬ÓÈÐÝÚ™a6Bù)¼|Ëœ$õP7GBxÏá“Ve§t[³ÿ_ûk/þŒj¯§Å§\ééo‹[“!š=íó2_œäg'§áV¬qöV$gK×þºµO¸q_ñ©(ɺðö™yom °8[Tòáh¦xÝSJîV AdÎ*; h·B%’È*Å€$Rb”l \#2 +2gkØOÒ–/ é0jö;R³ e_5Ìk!.#ÎÀÇž@Ï&µ÷î/ëþ4nÜ_×ühM äñ4š¯Ú!ky­¬ö²A»z‚džÝ÷¹Oè<-£Û‡ jîo‰§’]± .æ;²â¶·î/ëþ4nÜ_×ühò3*ÓÃúmŒ‹$8u¶û(g™Üù[‹mËÜþ: †O èÏkkoöi#KHÌ0˜®$ÕUܬƒèI­½Ãû‹úÿWŽfmJæ"–Äʾ…Œ™?øèü¨Ü ƒá˜¹¥Þ«C¶— Çknà©`K9^¦¬Eá½&@^ÇjD¢F•WÍs¹.#ÎÀÇž@Ï'Öµ÷î/ëþ4nÜ_×ühxCE[híÖÚdŽ&sË©U“wÞU`Ù º=ªfðÆŒË2ý…BÍj,ÝUÙA„g slI-áYLmÃäÛ¹FåcÀ`=³VGˆ´Áxö’\ì•7fÄYQ–Q) 9ä`äpk!4 Vêâ ¯ÚÎ1Ùâhà‘˜ß4¿be#8™NvoÁá¾÷?N)n+HÖIîîÕYÖ0~Ó)ù˜…ƒêE2Þx.ˆòn¯œãwŸ62µ†s€sùö«ú´¯º–…DÒ#‡JY®tÆ’)5I¤¿Œ[’h¼É|¼¨A(ØÁãœUI­­’çETÓ®g²Ù|ÐÚý¥)tòÃF8 F>^3Œq½äÓÅßþIÿÅSÊ6™&i.L¨ «›™7(8ÈwÀü…T—êÖ6·0µ=+StÓ–é$g]=#‹ÝÉ áŽJ²ºˆßý_ÎÇi烛šžŽ'‹YšçNk‚u[YmÌ…âAâ«‚Xdg«ZžëP²²iV{ÛàÑ,«4î~v*¸œä‚0)ö—0ßKª.ÜgÎ71~[ñŸÂ…†•÷_Ó¸®^ÐmdMRûÌUò¬Ù­íñÙ\ù§ôh×þYzvÖ·šuòiî—o©Ýùóyd9ˆùÛCÈNÌvÎz·„±ùví<1î-¶;‰dœ“€ÝIæ¥ò?éâïÿ¤ÿâ¨ú¬­¸sns¶ö· =ÛA¥=°ŸL¹IbŽÆd4í*²JßëÛïa€îzæ®êµXu?³é\(™ªFòiþ(¿»D;Y­õ)ô$ƒVÿáOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ³*ÞÆå|BÖÍ ý†ÚY/bm¸Rò ¦AiN;ek•{;©#¿û6“%¹ŸK¹IbŠÂe4í*²JßëÛïa€îzæ»ÿøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ„’Ýîs‘ÜGu}gö;·’}VÒå-Ý“Ë_$1.Ñ‘œñœb“NÓïÆ/<ªË8º™ÞUÓÜ„ƒ±Zà¾Ö\l€H*8àšê?áOú k?øÿÖ£þDÿ Ö³ÿ_ýjjËúôÿ"uµ‹ôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ•îËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZøEþƒZÏþõ¨² ²ýCþDÿ Ö³ÿ_ýj?áOú k?øÿÖ¢È.ËôUøEþƒZÏþõ¨ÿ„Q?è5¬ÿàWÿZ‹ »/ÑT?áOú k?øÿÖ£þDÿ Ö³ÿ_ýj,‚ì¿EPÿ„Q?è5¬ÿàWÿZ«ßxq-4û›‘­k?º‰¤ÿÝ=03ùŠ,‚ìµ¥ÿǤŸõó?þz»Xz<È—è/®£Ž ù¡SaàòYI',y&´~Å/ýï(øÝ j èI7ü}Yÿ×VÿÑoXÁwjš¿ý}¯þ“AZ6îdLÎîEÄÈYÈÉÚ%\ðíéTâÔõúû_ý&‚³¨´./R_‡ßò'Åÿ_wŸúS-|>ÿ‘>/úû¼ÿÒ™h­gñ3 ?¢0à_ø¶1ú€¯þ“U_ ÿÈgFÿuÿ•Å_âÖDê¿úOT<+ÿ!ý×þW§Ø!ý¤z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!‘gâû­FÂæêm3ÃÖÚ“½Ë‰'–É®ŒemQ£ËL7Îÿ.ìí^ýEfßÜx‚]Eìàð…µˆ7ºtQÏ“¹€K<ÍæFT0ŽEU,¥F22 Zñ®5þº÷w0j1YÅ Ò%Å¥˜»‹dƒüÀT©o¸TŽâ°-ôi,u}'^žß^‡GÓc´Y/æµHž5·¢8C'›[tŠc9¶Bœg< Ã¥Q®k>’½ï¦©ö[ô¿{Þ5ô=3Áú¥æ«á˜®µ)!{¤žâ $Š3¿•3Æi' êMIaâ[K­6âúeh"†@ `»:¶ l ’Á— 98æ°ü‡Uøw$vW•º¼¿ 2>FÆ»—,¤g?)$~nãÂmhfM)#–Þx9a¿¼ùÁMŽK2`Át… ñM ²ø®ÈO¦Gw-õÓ[öyU¡eRÇr”Êž Žî€Ôéâ}!ÒéÅÓ*ZÆÒÈï ª”S†d%pêR¹QY°h:ªG§<²Æïm~Óù2]É/—FÑ•²îr7€ë· j¤žÕ.4–Óå{4[]:k 7Y™C…¤Êü˜¹vI>‚ëðßúïþG[gwõª\ÁæyO¾dM<ÿu€?§=jzDQAì1KC%m¨QE (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÁоõ÷ý}ÜèÆ¨ïzµI¡}ëïúû¸ÿÑQÞõjèûlÁü%]'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`g-Í#±‘â‹f»ðÔ0¬M mAw*®~_´Ÿ¦3\„ÖÚÜ<–³yϧÜÛËÔ¯–ª3â*Ì=A¯E›þA«ÿ]åÿÑT«« Âþ¿äSzœÀšþúkˆ-.Äe¬@2[º¶f-Ãxš­i¦]AçÅag%´¢ôVXŒc{H…0ØÇ+Œon;z+of¿?Ä”íø~#4:x°Ùc¡Ì4‰æ‰låòÁ ß1€`ÉŽãrvñLÚ3è¶‘ÝZHLop94É&‡þ\Fä8ÆÓØdWuEî Øâ5 EÌ—Â≠²c$™6ËûÁ»kn`6õÉ;AÁÅhÉ$f÷0Mªß\Yȳ¢\٘ʟ»MÄ©n9í]5ù7…Ô4«Àöþjïo¹lšá£¸g,åHe¶Já›—¯z}-ååïØÙ®Æ§nb›Ë;„xˆ1SÙ~öqÇ\ô®²Š4ŸõÞá¹á«D²Óçm~ÎËw1eò¶—%Hã‘·nãŒv­š(ªJÊÀQE1dÜßišv³5Þ®3mš8\ãt‚e(:÷€êqëÅkS4©¢¶ñ\ÓÏ*Ezig‘Ø*¨ ’OAXb?†Æ·+ oD²µmnî÷Lº¾¹½ V÷‰äÃ7•°“8á2K°ïÀè*6[Kìë³âK[{9Ví¤¾¶hŒ>|ŽŒQK†Aч ’îMvcZÒŽœu©ÙpnDëåœcvq׊'Ö´«k¯gÔ좴›\òN«瑆'§jó™hÛWÓ,üi>¹04ÛË%’…#ËrËÆìƒž¬Èî쌖ºäÚŽ$/©‰oZÖe’Sä4q†qÇ]¹cŽHè1]έ¦Ù4 u¨Z@×B%™TËÓîäóÔtõ«”ú¶,r:uΙoá ÁªJ‰a3]α³ZÔÊÇ JËÓ³Z]];ÄÓß^ ËRg·H>Ëev  24mÄ“À8<“ÖÑHcÂe§øsìåâ¶„^^Gn ÂÍ!ÂýÇaX¶š¯†5H^åï,bÒ,,e†Dœ4ï TîQ…/^ry8ƒEî1á›û-gQºÕa»±i^‰m-§I”±S!R~bXñÐtòOOEQEQEQEQEQEQEQEQEQEQEQEQEU sþ@—ýzËÿ ¿T5Ïùj_õë/þ€i­Á˜º8‘¡Ö„.‰)Ô®3©e òàÈöÈúŠçôOk:?‰%Ö_ÅOt÷, ÜRYág_O¿ò‘ü$—¦1tôk¾Õ5…’{¨ÂêàCpè:úŠ·s¦G ·Wç·’jé«îf§e±bÏîZ×å×þ…5Cn3©kõøŸúM.’1c§ ±ÅÍÈËIæn¤õ¥³ÔµŸúüOý&‚°ª¬Ú4†ªáðÿþDø¿ëîóÿJe¢‡ßò'Åÿ_wŸúS-sø™•áGÑpøµ1Øé=føWþC:7û¯ü®)ßL<¶áåÿa¨Æ?éÚŸá_ù èßî¿ò¸­-h?^òG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qY‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬77vkY<¥1,¾D²F2Ûwõäš–óÄºŽ— Ãj:U²²YËw¶¼2ã*Å£R¹Ü0@=ÿ¯ Ûn|.½¶²šûlÚ’Ã.ìÆÛ®¦ÁÈÏõ§Kàë‹‹{µƒIÑt‡’Ækaö'$LÎȉ03ѺöÇ>)ª¶Ÿ×oø&ïŠ/ô˜æ:–™j®,溅m¯ZMÞX«nvçpÁÕâp×z¸´;µ@ÅÏ™ÿä!l9åXvè~”^øZÁ|?©Xé:}…•Åå«B^(V0I ÅFq“U`ðÅÜZÜ7¦h PÞ™QFAäã§_2g?Lw§ý_×B~Ïž¿‘ÕQE†QEQEQEQEQEQEQEQEQEQEQEQE`è_zûþ¾î?ôcTw½Z¤Ð¾õ÷ý}ÜèÆ¨ïzµt}¶`þ®“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡kèzW„õ{C©}«MŸ·0Í2'–Œ!šH÷à“·!2yÇ&§Oé/J²Üd2¯”læ±`HÛÝì rSèk ÂÐëŸ îm¢¸S íÆ¢©2a×k]M†ˆç>õ£{a¯j6h—všQ1Ȭ‘GyÀW!øêsÁý~ [›ÅD[È׿ڞ$ŠÚI… 7ȪX'FG9èj„Þ1„kkcoÉoåÛÈn¤2ªŸ9ö \FÀõîÞ;1Ó¼=wkܲ@[É»ó• À’ið¼r£dàž9â…¿„oáµ¶‰¦¶-tM†lfÞBïü=<~¸¦º_úÜÎßÖÆåÇŠ4«k·µi¦iÕ™KiYY–(¬«0ð >Õ^ÏÆdúVyre¶kØV_,Ã#y@2Çoʹ8ØSÔV:E~úìT6ÌÖpj]5ËA2HH%!ÃI€UØ‘Ž$FÞ ÔÎÊ)ÚF]=4ùÔj T' ˆÂù€†9FÆ:êiGÏúþ˜=ÿ®ÿå©ÕË®éÐêK§¼Ò ËÈ…ÌaÈÈS Œ)99r+;OñdZŒ6òGg:™n§•‘Ã*Å».P[;T` c9ÉôMI¼@·VþE¼>lnÓÅw2³¢€ ¼1ÈÄ »ÉÈãåíB½°Ôäší­Úšãìþ[’ÇΛÌ%PÁ=ýh_×õøÿ/Ô»¡ëÛn?cžÔ[\y!g]†ÅpÅz®wt<úàð5«7LÓå²½Õ¦‘­åК0¤ä/”‰Ïr‡ô­*;QEQEQEQEQEQEQEQEQEƒ¡}ëïúû¸ÿÑQÞõj“Bû×ßõ÷qÿ££½êÕÑöÙƒøJºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡Â‚Y#$4qÐHÀŽAXç¶3ZÔÍ*h­¼W4óÊ‘EšYäv ªƒ$“ÐVá±­ÌY.â5GÒu6œÚ” =ÔÚ„ˆ¢?'§ÚFæ ¼(ÝÏ\d ½ö§cÛoídk8&Ši$‘!ÚáÙT“å;ð7y`ääWd5­(éÇQ‘±äN¾P9Æ7gx¥—XÓ-ì#¿›R³ŽÎLl¸yÔFÙé†'¼í‹8G2RßV·g×6:„–J$ Já—Ês‡bƒ<‚H?taÚuüÍ êlºÔÔ-¿ï—Ržä#“󆜠1AÁ>^Kqšô)n!‚Ýî%š8àEÞÒ;ª½rO@=êªë:[iͨ®¥flTà܉×ÊãïgxëBÑ[úÜw¾§³Ã<-ì’\¼Z”ì%MBKˆŠ¬>R_”ȹËG̽8«º† xkD»ºšö;»Y]¶¤’\#9 »²Ì3Œà‘Ò»hæŠhx¤G‰Ô:Ȭ ²žAÒ«Øêz~©ɧß[]¢¬Öó,O¡ œ}}-ý|Äbkz}²ø«Ãú†Æ7-vñïgf ¾D§ Âç88Î+PºE±Šú]F;e¾šæãË—P’ÄJ26 9`ЏC×vqòנÊ«ëë{‹¡ÂÉ9´KË+Bê* ]ašáîäßFp Å·d*3»£c8¬ÛFeÒì€ÔØéux¿jºÕ%µÜUñó•Y˸€xm£¯C½±‹PƒÉ™îwnÌBß÷Ò08öÍ:ÊÊßOµKkhöD™ ,I'$’rI$’Iä“K§õä?ëóÿ2!îdѬžñÕîZ2º©PÍ“‚ô }*íSnîä¥dQE!…Q@Q@Q@Q@Q@Q@Q@P×?ä©׬¿ú«õC\ÿ¥ÿ^²ÿèšÜ…áŸù k_ö—ùÕûÿ¾ÕCÃ?òÖ¿ì!/ó«÷ÿ}«wñ|‘Ù*éñç§ÿ×ÕÏóš±nÐ6»ªgþ~×ÿI ­­/þ<ôÿúú¹þsW+«ß}ŸÄššç­Úÿé5½aY^OÔÖžÈê¾ÿÈ¡ý}ÞéL´QðøçÁñ×Ýçþ•KEUO™Ðþ}ÀDqᨇýAWÿIEløWþC:7û¯ü®+?ùáÿ°*ÿé(­¯ ÿÈgFÿuÿ•Åhþò~#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬MN Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèvvÚåÍÏ€SSÕ䉿·¸¸Ši!Œ¢¿“,±î “‚BŒõ|ŽŒQK†Aч ’îMvgYÒÆš5#©Y‹p.¼õòºãïgxëÖ‹gK´´†îçR³†ÚlySI:ªI‘‘µ‰Áãž+Îh³m_L³ðu¤úäPÀÐCo,–HB|,mÈ 7/°x³#»²2Zë“j:t¾¦%½kY–HmOÑÆÇvåŽ9# ÅvW:¦Ÿg<]_ZÁ5ÁÄ1Ë2«Hr“Ôtõ«tï«aÒÇ#§\é–þ¼¤¨–5Üë1­L¬rä© ½;0õ¥ÐåÓ¼M=õ༵&{tƒì¶W`É ±S#FÙ I<ÐÉ=m€æ<(ÖZ‡>Î^+hEåäq&àœ,Ò/ÑAY†TåŽ <€3€_‡ô€—OñtwÚßö{Ù¼Q:nŠà¾U‰’EUÆ8ܱ§oLرñ$7r2Ån¿éE·Êr|²ßwn;œ‘ŒŽ¼‘^ÓÂþKÏÈ»Ø[[FÈÇÌWˆ¹ßÓË)ÔV}·ƒõ ,Ä÷VÛÞÖúd„½<¡Õ‚‘Ðr öç­iê=áùjn'Š4—¶’q4à#"˜ÚÒU•‹ýݱ•ÞÙçœCRKâ-.(.Ìò.ÓíîlWËmyo,É,PÉ#‚…A_-T¶~cœ·iÍXºñ%¬³È¦ÎKo´µÈ$…RÊ©À;‹~†ªXèz„7Z|÷W)3Agq–‘³#£( FX(]»Ž À8äÕK? ^ä-´ÒÛ´é ” U›hXHfíž[v?”_Ÿüþ¿/ø&¤^,Ñæ™aYçY ¢&Y-%C¶6‰7(ò÷dcv3Û5:xƒL}@Ù,ïæ†d `q2‚YVM»†@$ð} QÔ4«¥Ô‚IûUåµÂn'…ŒÆX:ü‡…R—ÃúÕÆ¿oy<ÑI2H²ÙpѲ:ªˆ6ìR¡ÀÝ’N9<Òéýy Ӄź%ͼ·Ý¿“ä»[È¡¢YIQ¼ûsŠÓŽöÞ[ÙlÒLÏi+¦Ó±`§=9Úß•rïá+¹´‹+ž0è²éÒ2’xâ0qÊü‡Ðô­M"ÃSX¼Ôu´ˆÏm +¼­&  $²¯]ã·øÕ;_1tþ¼¿à›”QE (¢€ (¢€ (¢€ (¢€ (¢€0t/½}ÿ_wú1ª;Þ­Rh_zûþ¾î?ôcTw½Zº>Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(ª–óØÛx–Iµ·K%bò¦äF.Ö>€Çc9n—Dÿ‘Éÿìô`¬1Ãc[‘iš…µ¶¡ww¨ií¾ôÉoª˜³kæ´@e~l(??'#vN,ï4û? ¤sj}•Ìp–ú…ÜY†Ti2Å *6¶A » æ5Ú$ñI$‘¤¨ÒD@‘U(HÈÈíÇ5%yÍ]X»õ8 û›ðtk{ étøÑ ºCçÜÆªBǤ¹= T·ÝÉÞDÅáFd(YA*zj`»¶k“l."3Œ“q¸cñ×Ëÿ}Zš›wÔ-`¢£’x¢xÒIQVÛ³\àœS€Oài†òÕcó Ì!žVâã÷mÛŸ\ñ^)=Yõ (ïã°{Ëu¼‘w¥»J¢F^y œ‘Áüªdš)DIž2¨`J’2ôàƒ@¢£ÄÓ¼ *‘C4a†å8$vò4IË~—ï{Ãæ¾‡¥øKVºÔ|,—º¬Ðˆ¦¹†i£O-C4‘ïÁ'nBdóŽMX‹ÄúD¶Þý¥Ò °I.ìm;YAÁÏ<óÁ¬[íü8¹·Žu0^ÜjH³FC¯u0 B0sRÙø^õ,®DÉW25²ƒöû‹œ¬R9izwÂÇ©Ï*45¢ñf4Ë Ï:Èe2Éi*ݱ´I¹G—»#±žÙ¨­¼Q Æ·k¦šá.KÈȦ)6`’€g®yÀ w)-Ô4«¥Ô‚IûUåµÂn'…ŒÆX:ü‡…UµðÅÜW–Ï,‘´ Þ¬ÞUÄ‘:¬Ó T«(#hdu<žâþ¾ï󆞻â;-ÞWœ»Ì°<ËFíÂ÷fU!“¨™´æÔ Yî¦Ô$Eù=>Ò70]áFîzã U诵8´ëþØók#YÁ4SI Œ‰×ʤŸ(±ß»Ë'"»!­iGN:ˆÔìˆ87"uòÎ1»8ëÅ,ºÆ™oaüÚ•œvrceÃ΢6ÏL185çlYÂ9”j–úµ»8¾¹±Ô$²Q!W ¾PÛœ;ä@û£Ó¯æmSeÖ ¡mÿ|º”÷!Ÿœ4åˆ0Ú òò[Œ× Ís½³ÜÍ4q@‹½¥v ª¾¤žªãWÓ›ý¤5O°Ïמ¾W\}üã¯zдVþ·ï©Ã,ðÏ‹{$—/–¥; SP’â"«”—å2.F2À‘ó/N*žÑ.î£f½ŽîÖC—m©$—ÎBçnì³ ã8$t®Ö9â–ž9QáeÞ²+¥qœƒÓõ Ž¥cªBÓi÷¶×q+m/o*È õÆA<ò)õô·õóüÔ¥ŒjZŽž]F©>«iqmGx—Ê˨îª@Hà`æªjH¶1_K¨Çl·Ó\ÜyrêX‰FBÆÂd,WzîÎ>ZôgŠá Ã*HŠ–FdÇpAéPZêš}ô“Çikq%¹Û2Å2¹ŒóÃxèzú•¿®Ÿä‡}NâêÞÛUÔo®fÔ`–ãJ²m­rb“Ù\°û¨Ws6nb0O5,.c½Ô4׸¼Ý ®·åÂÑj’ÜF[e@˜í/—ȽJô8>‡c©éú¤o&Ÿ}mvˆv³[̲>„‚pjÝWQt·õµŽÂ:¥Ñ¿’[ýBÜm¶y5ßP’c Ç,Œ-ñó¡°GLíÍwøñV©ê÷CPŽúÕl¬…ÃddŒÉˆó†$àíëÁ9=ýA½µÅÌñG¶K—+dÌ(>Ü(zR[¯ë¨>¾ge¨?‹çŽKÈ–qsp²ÛùYü€§ËÿGÙ±l$Ü3’3–Å3O¸Ô­ôÍ.K;«Ë›ËâïlÓ¼¾dø‡iÃ:žã“êkШ¡mývæ;ësŽûýQ>©uy¦­Œ·Fåæh‹9•’CðÅGÝêÍA¦\ž$#HÔfº´—SUÞnQ nvï$—PÀu'‘í^‹E _×àyÞ›siq«øa¿µn®5V¹v¿µyÚEŠ_³O»rˆ˜@Q·#<dz%Uº±ŠîâÊyÃYÌgŒ),cxùöćñÅZ Š( Š( Š( Š( Š( Š( Š( Š( ¨kŸòÔ¿ëÖ_ýÕú¡®ÈRÿ¯YôMn ÂðÏü…µ¯ûKüêýÿßjÉÑîÒÆë]¹eP“#z¯V«;÷5$ºÔsªF`£7v篰ŸÊºy[wôüŒ/¥‹_üyéÿõõsüæ®ÅxþßÔsÿ?CÿI­ë¹ÒÿãÏOÿ¯«Ÿç5pž.?ñ?Ôëèé5½DŠþeKøhî¾Èý~^ÿéT´R|<ÿ‘:/úü½ÿÒ©h¬ê|oÔ( >ˆà¢ÿ‘nû/þ’ŠÙð¯ü†to÷_ù\V4_ò-Ãÿ`eÿÒQ[>ÿÎþëÿ+Š¿°þ@¾$z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!‘¡Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8UÈ8vÀ 8«¯âM)5#`ní *ÂØ‚BˆìUg ´‘ŒžsÅs7^×î<=o¤™­ŒQØ @±ßÍ ÆàóÄÌ¡†Ü£` ÎsZáëÙ!½Kp÷•µàÃ6Çäî:þí±õ)èååÿüƒ¡¨‚îa$sÜ]ÉæGˆ‘2ËåälÏßõj¦§àég´¶°¶ŽÙà[!f÷Ï,r¨îÌ‹•˜s­€yçtù~Zþ#Ðên/­­,öy6[¢o-‚xúIöš¡'‰ôˆ¬£º’âDI&û:£[È$ópNÃÝሎr1Ôf-Gé5¤ÆÎYÅÑhäg»•âÝ«¨ØXª‚TTt&±ïô­a.,ï–ÚÚKéõe¸xQÙ¡‰VÝ£“fyÀùŠðX ruÛúì^»ñ¥ŒÄ+K–SÝ Ù%TO(€Uð„©ûÀäeHŒ°©.½§A~–2LÂv*¹;"³}Õgj“Ø ÈõÎ^øOT¹µ}²Yù÷6·±N Œ7•†ß”î¨ uϵlAaªØê·-h,šÒòdžY%vFB*2ªÃd Á,1ž‡"éë_òänÑEQEQEQEQEQEQEQEƒ¡}ëïúû¸ÿÑQÞõj“Bû×ßõ÷qÿ££½êÕÑöÙƒøJºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡GF(¥Ã èÃI÷&»Ø§ŠpÆ)R@¬QŠ08aÁÜzSVîÙ­>Ö·m¥üàãfÑÔîézóY¡‹i¨YGá«6Õ£µµx ‚I­Ú1¶Øœlb¿À¡‡à ½F+Ÿ¶»†)£Ô.o-§°McΛP„m¶bÖåCHUVÚ¤îa»’Aàwr\Áy&!8ÄŒÀ/'ŸrGçRÕ7«béc—Ðç²Ã“¥ï–Ö³Iwq ›ËÛX‚²áàzÔZI¶Ö5gmì7ö·0ĦãO‘£D¾#ÜŒ~pI p3ÖÑHkÂ&ÒÃÃëj<¨cûmÜPÄ03‰¤;TwàaY_èsj2Î×vw4Zd°Ë ¢˜Íœ_!)(RN[‚0yÇyEî×ãs˜ðÍý–³¨Ýj°ÝØ´¯ D¶–Ó¤ JX©©?1,xè:y'§¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÎ@…n5 n'.µ 2c‘‘ºö*Azx#¶—(÷D©ÈÝ{9ˆßÍTðÏü…µ¯ûKüêýÿßjèmó[ÐÇ¡WKÿ=?þ¾®œÕÃx­sâ Gþ¾‡þ“[×s¥ÿÇžŸÿ_W?Îjâ¼N3¯ê?õô?ôšÞ”Šþa/ᣴø{ÿ"|_õù{ÿ¥RÑGÃßùâÿ¯Ëßý*–ŠÊ§ÆýGCøQôGü‹qØô”VÏ…ä3£ºÿÊâ±âÿ‘jû¯þ’ŠØð¯ü†to÷_ù\U/üƒí#Ñçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8¬Í Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèwú7ˆïáŸZÔV+›»3v²yJbY|‰dŒÛwõäšÙ—^Ó¡¿K)fq;•^"vEfûªÎÕcØ ÈõËxbÛûsáuíµ”Ð¿ÛfÔ–weë©°r3Ç=Fkz?U±Õ.M ²kKÉ’id•ØIQ•P.! aŒô8ÁñMÄñø›H•.Ýn˜%¤m,¬Ðº‚ŠHfBWçPAår:zŠH|M¤\ZÏsÑòà _t.¬Cp…TŒ°c•1àf¹øD¯4ÝSŒÂ³tË‹[fKˉä—pã±Ùv®UAÉè@:±éZôֳܗ´µ½kxmâHdlF,Ùb™BÀ•à6Π“Gõùƒþ¿ø&“ø§HŽÑnd¸•§û0F¶”IæíÜË+¼9äc¨¦K⸑èð­íÅÚ»¢É!…P€æBT²H\m'<0HçBÖ´÷µ’+xf–Man–7»šáQE»!ß+®ìeFƒÃŽÕ±‰ªY}BÝ­P 9žvXœJáÊ«…$m `í9çžëðÿ0×â^]6örË«ÚIe,SJF¯8”Ÿºb*»¤=—##Š&ñF‘Vò5įö„g‰"¶’G!H ò*–Iä‘Îz«6­ÜÅäÒYµõ½ßÚ!µ0…cFSÌÙ¸œ1mÅzñŒS4ï]ÚßÁw,ònüåBp$šD|/¨Á8'ƒŽxZÿ^Ÿæoé‘ê70Je[h­ànV$óX… îãç'û¦¯ÂC¦‹ÈmZYRiBÞE_\#ÊÄœr+‡ÂZœ1YÃæZ2Çm§Ç+yŒkyw¶Ñ·A8$Ž@ãœÝ þ}Bê(šÛû>öê ¹¤wo66gÊ«´‚–¼îÉààUiŸõýy5‰’îò8d·XQ–íšF—…J#$ð:ç>ØïÖ¦Oèïa-ïÚdXbdWó-¤GËà&¨b<0k%<#s"Éó±Ko¨@Ì„–h”:sïëÖ£¶ð¥ð¶c*[Åpf´9û}ÅÎRCŸš^ŸÅ…Žä焺_ú×üîíæ^¼ñŒºÕ€²º’+‚€Ê°ÊY #¾ $x88lãå5oþ{)-.§¶·Ô'{vThŒ©&櫎;œ‘’*•懩ý¡oíM¤—‰¨½ÐI¤eB†&‰Fà¤ä§ëžjæ‡iª[YImkg0,ÓÃvÒ´²7Þf5ÇàN8'³°ú¢ÇŒK¼ò­!šþØ\„¼¼EáIM§œ¸cžzbº;yZkh¥hÌlè¡ •$tÈ$Àâ¹È4-COÓôF¶ŠÊæöÂËìr,Ò²!S,¬TmäÒ¶ô‹ì½ÎÀÊeû<+˜F7`c5NÚÿ_×B{(¢ŠC (¢€ (¢€ (¢€ (¢€ (¢€ (¢€0t/½}ÿ_wú1ª;Þ­Rh_zûþ¾î?ôcTw½Zº>Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(¬ÿ6þ-vàé¶òOtÖFP2ƒ(†ò2@'“ŠÐ¥Ñ?ärûŸý+ GðØÖænŽo—×6Z.  :”ñÌh<ÑâXeÁb~RsÜ‘š¦ï}qðÎÎÙ4{ϰ-Œ­1ŽHGÝ` ÈÌüÇ?.1Íz$Ú•½¬·S^ÛGo ’W•B#‚ 'ç­O±Ï M ‹$N¡‘Ðä0=#¨¯5««z~F‰ÙßúÜóßM¨Üh–-.}ö(#¶‘6É ¾bœy™àp1‘–ÉÆ+ÐÑ‹F¬Q VÆG±Çê*›»d¥d‚Š(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ0¼3ÿ!mkþÂÿ:¿÷Ú¨xgþBÚ×ý„%þu~ÿïµnþ/’1û%]/þ<ôÿúú¹þsWâQwQÿ¯¡ÿ¤ÖõØéñç§ÿ×ÕÏóš¸ÿœkzý}ý&·¢?Å0—ðÑ×ü=ÿ‘>/úü½ÿÒ©h£áïü‰ñ×åïþ•KEeSã~£¡ü(ú#‚‹þE¨¿ì ¿úJ+c¿òÑ¿ÝåqXñȵýWÿIElxWþC:7û¯ü®*—ÀþCûHôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+2Î Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèz¯ÝËày5mRKw¹µk¨å‘Q¢ü™¤qy\„ã=Njµ¬xªËH>Q5ÎèEGؾc¤ UO9OãX>¶þÜø]{me4/öÙµ%†]ÙCºêlŒñÏQšÒÔtRYnà´k?²_\Aq4“;oˆ¦ÀÁT) ‘Á$`“^)£Ø¿/‰¬­ZäÝ 8® ˜£yšR¨Ø*) .H' Ç8§ŸÚ%ÝâHʶ¶Ö‘]}¡[pu¸9ûœc9ÝÀõÆ»ðµëÛióFc–ö9™EôÖªÆfÄIÝÁ`Œîø>g³º¶ŽHQÊÒUd‘FøŸÉeS• XsÜr-‡ý~?äiKâË!>˜Gq*ß]5±?g•ZU,w©L©àpØàîè Y¶ñ—vÒ¬7|¸šmÏ ¢º/VF`¨ÈåIQXö¾¾·6W*–éq neF½ž|¡ˆÅþ²@Y˜EÇZ¤|-¯\\4—W3Ék%¬Ó5ô²yÙ7:ÆP,G ~Uã‘ÉÅ_Ößæ/ëñ¡³Šï4{VÓ.Qõ »#‡1´w7·ËŒñÀ= fjl—WÚDИÖ;+†•Á$¦'@¬? Ó¦íЊ(¤EPEPEPEPEPEPEPEPEPEP#·Zݵ³J®u Á1)'ßÒ9?—ãë"îIó9»+µ‰ÞŽC×6Ê?ñáZºÞ¾ÿ¯»ýÕïV®«®f¬`Ö—*é?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ ÚOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃni„›þA«ÿ]åÿÑTªìßò _úï/þŒz¥]˜oáîQEtQEQEQEQEQEŸæßÅ®Ü6ÞIîšÃbˆÊPe°ÞB’HòqZÍ*h­¼W4óÊ‘EšYäv ªƒ$“ÐVá±­ÌÍh¬,m%¹µ–ÇO³Öç2=Ó¡ •‘T³+0b'Œ‘Éë]_„Ô¸C%Õİ×&•ŠìA{W—YÒÛNmEu+3b§äN¾Pç{8ëÇZ·±Ï M ‹$N¡‘Ðä0=#¨¯;§õÙ‘×çþc袊(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÌ/ ÿÈ[Zÿ°„¿Î¯ßýöªÿ¶µÿa _¿ûí[¿‹äŒ~ÉWKÿ=?þ¾®œÕÇø”g\Ôëèé5½v_üyéÿõõsüæ®?Ä®\ÔGý=ý&·¤¿Šþc:ÿ‡¿ò'Åÿ_—¿úU-|=ÿ‘>/úü¼ÿÒ©h¬ê|oÔ( >ˆà¢ÿ‘j/û¯þ’ŠØð¯ü†to÷_ù\V,,†âõ_ý%µá_ù èßî¿ò¸§ü†þ$z<ÿë­¿ë¡ÿЦª÷H²=ºº†S!Èa‘÷Zœ¶–ÊÁ–Þ AÈ!œ‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGµ¨¬W7vfídò”IJùÉ8%¶î ëÉ5kûsVžóPK"Úx,¥¹kÒ’¹òÕÎÕòÊç–÷‹á‹oíÏ…×¶ÖSBÿm›RXeÝ”;®¦ÁÈÏõ­hìuûÝSìPé¯ìÂTš[— î‘9ŒFC`¦q¸g¦ExÍ{Ô<]mkiÔùðÍl.̆tDÜpv‚\äž[ƒÒ‹¯jv6Ó}«G‰n–X —LÐIæ¸Aûß,Aê6ž1×4–Þ½Ó­§[+˜¼Ä‚-ÌÃpxã啸ãyfŒà{b³ÛÁó\[ÏÓô« y¥¶/alÅàq¡ÝÈ£s/˼àdúW[yþèlA­Ýé=–­gmlÿf{¤{{£2ìBn܈TüÃy銊×Äï>‡5ô¶¨Ý#¦\–i˜Æí£Þ½¸çÒ©Ká²›Q‡D†ÊÖÃSˆ%ÌA|³ &Õ<-òœ@#©­+ åñµìmÚ(V–,œ³ a1œ“þêÒ_×õùþ¿¯Ì™uÈÛ[ŸMªˆ°—w àÉŒu èsî}*3¯ãÁ¿ðý›þ\¾×äyŸìnÛ»†qøUøE?&þ)œê¢äÜK¾êS ß‘ £äbÛž{ÒXèúÃøe<;¨[XGkö²5Ì#ýÍ¡‚”~¿:ÞcVº¾ÆÎ¡ªý†}:?'Û%hó»1¾zs÷1øÕ=UÖuk[+Ù4Ë,®bYw-û¼Š¬2>_$zFºv±ubÚœv1%ŽçF·™äiœÆÉ’ (A†'nÜñÍ xn}X$žðürÁŽKûyœÄ. cÈžÿ7~´ÖìlŽÂŠ(¤0¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Bû×ßõ÷qÿ££½êÕ&…÷¯¿ëîãÿF5G{Õ«£í³ð•tŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɹ¾Ó4ífk½\fÚ+4p¹ÆéÊPuïÔã׊֥Ñ?ärûŸý+ GðÆ·)Gwddµ×&Ôté!}LKzÖ³,ÚŸ!£Œ3Ž:íËrGAŠè|&¤h…À".®%ƒþ¹4¬Pb#؊ؒx¢xÒIQVÛ³\àœS€Oàicš)ƒ¤G ÅIV úƒ^qoúüGÑES][M{¨m“P´k‰ÓÌŠ!2—‘yù”g$py”rŠŒÏΰPLê]c,7è2?1MŠîÚy^(n"’Hþú#‚W’9§*Ãê¥MEPE@÷¶±¥Ã½Ì*¶ßëÉù¿»ÁžÆŸðÌÒ,R£´mµÂ°%Áô8 þ"€$¢ŠŽ9â•äHåGh›dX€p}?ˆ  (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*†¹ÿ Kþ½eÿÐ _ªçü€5/úõ—ÿ@4ÖàÌ/ ÿÈ[Zÿ°„¿Î¯ßýöªÿ¶µÿa _¿ûí[¿‹äŒ~ÉWKÿ=?þ¾®œÕçþ2œÅâð?çèé5½z—ÿzý}\ÿ9«Î¼j¹ñ&¡ÿ_CÿI­é/â?˜ßÀDøyÿ"t_õù{ÿ¥RÑIðóþDè¿ëò÷ÿJ¥¢³©ñ¿P¡ü(ú#Ï \xv#ÿPUÿÒQ[¾ÿÎþëÿ+ŠÆ‹þE¨ì ¿úJ+g¿òÑ¿ÝåqD~ |Š=õÖßõÐÿè SU{¤YÝ]C)ä0Èû­N[Ke`Ëo 䃊’Ž Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèz7†õ»Ë¯6§©¼sn÷QË"#FäË${°7È@N3Ôàv©‡Šìa7F÷0,WkiEyLÎÑ,€UÎHbÇ8õ8®w@ºŽ_…7²[‰.–æ}Iaû,m7˜^æ}¸Ú#žžõjóFÕm.-g¶‚å“WŽåQ‹mE¾YÞÁNÞTŒà‘×¥x«ë¿ù½¾ÿÈØOXKªÙÚC½á¹¶–ãí7 –Àl®›;ˆÚ@dб‰4«‹)îÒyPíÞÞD›pŒ¡›vp0O5Œþ¾¸Ç-¸ûM½ì7{¿tge`cù~lmÇ;s×Ú’ÓÃ7Ñi×¢[[6¹™!Œ$š…ÔáÕ ?ëîŒä’»Tí<äö:]ÄiKâ»!>™ÜL·×MlOÙåV…•KÊS*x68;º[ÕË[èZ¬k¦É,±;ÚߵǓ-Ü“yq4l…D®»œÅ¾`:íÈêi‡_ë» (¢Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@:Þ¾ÿ¯»ýÕïV©4/½}ÿ_wú1ª;Þ­]m˜?„«¤ÿÇÆÿ`±ü¡«:ƒoƒvíÿé0.åo“‰ÇÊãÈèOü0+i?ññ§Ø,(jΠÛàÝ»úL ¹[äâqò¸ò:Æ 幤voù¯ýw—ÿF=R«³È5뼿ú1ê•va¿†7¸QEÐHQEQEQEQEQEV6£=Õµåü¶m²A§¨gÞSdfuÛ€%p»Žà ÏjÙ¦iSEmâ¹§žTŠ(ôÒÏ#°UP$$ž‚°Äÿ nŒµD±i:íú=®«!†Xu)¦E_!ŽÓ3ó>q÷ºìÉäRj3j:rX@nâ´v±™o¥·Ýtò|$hÞy¯îÏfàsÇ~5­(éÇQ‘±äN¾P9Æ7gx¥—XÓ-ì#¿›R³ŽÎLl¸yÔFÙé†'¼þ¿×oÔ¿ëñ¹Èê:–¡os{¦‰fó-—Jû›%aLž£Ìw?óÌTSEŒ—:$l£Q:“ÚGÑÞê:•P’z ×y-Ä0[½Ä³G»ÚG`W®Iè½U]gKm9µԬ͊œ‘:ùCœ}ìã¯i-ÿ­¹ƒwog¥xÝ5-¬ôÛ©g‘Ýœ­ÀÉ8QÎàdñÍbEÍœwª&–Þæ[==¥’&ÚÊò\H_êÍ^‰ÑMOˆñ:‡YVSÈ úU{OOÕ#y4ûëk´CµšÞe)ô$ƒBíÛüßùƒüò8û¸%Ó¤Ô%ƒPÔH²Ôm#·I/duUż6[çqûùÇlTkñ[ø¶öEAw4wI>¢Í EI6ÀlDÊ®×áˆÆ~ñ®úâ¸BðÊ’ b¥‘qÜAúTÚ®y<ðZßÚÏ5¹ÄÑÅ2³GÛæät=hþ¿ èyÞ«©m¡êMª[Ç j¶SœÃtìí0Ý*+ «· ¹p g¶X.úÚííf·™d } àÕºúõ é÷œ¶¿}d÷¶+yªµ¦É8{ˆnÌ gR¡PȬ@ó>\òTç¥a¦)ïõK{ëó ÕìâRò¼aÑÒbñü ± s¹xíŠôZ(ŽŽÿÖ÷ÿ€]>mdÂ_[ÞJï&‚xæÔXÈI0>ÌÄMÊ»_†#ûÆ“LŸRµÓì&´»½º¼½Ðeºežw—tÊ#ÚUXÎFïžµèTÙ#Äñ±`®¥IV*yô#}Å.Ÿ×gþc¾·þ·<êMAc´ÕNƒ¬\ÞÀ¶VÌÒK{$‚<ÊÂVÞw;2N9\g¥t¾ž[:åšê‹qpÂÝâ»’èÀÊùΪ_ »žqÓ8}¾"Ô?ëèé5½z6—ÿzý}\ÿ9«Ì||øñ-øÿ§¡ÿ¤ÖÕ?òñüôχŸò'Eÿ_—¿úU-|;ÿ‘:/úý½ÿÒ©h¨©ñ¿P¡ü(ú#‚ˆÅ3ýWÿIEløWþC:7û¯ü®+’]UF‘¾yþÅ_ý$ºß ÿÈgFÿuÿ•Å8«AüŠoÞG£ÏþºÛþºýªj¯t‹#Û«¨e2†u©Ëil¬mâ‚qPQÁx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8Û0 WIÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`VÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'ŒþËsHì$ßò _úï/þŒz¥Wfÿjÿ×yôcÕ*ìà op¢Š+ ¢Š(¢Š(¢Š(¢Š(¢Š(¬››í3NÖf»ÕÆm¢³G œnL¥P>ðN=x­jf•4VÞ+šyåH¢M,ò;UA’Iè+ GðØÖåa­è–V­­ÝÞé—W×7¡¢ŠÞñ<˜fò¶Òg&IvøFËioýv|Ikog*Ý´—Ö͇ϑъ)pÈ:0ä@=É®ÌkZQÓŽ¢5;#b È| sŒnÎ:ñI>·¤ÛYÃy>©e¬ßê§’á$ïò±8?…yÍbM«é–~´Ÿ\Šmå’ÉB‘å¹FåãvÁÏÖdwvFK]rmGN’ÔÄ·­k2É ©ò8Ã8ã®Ü±Ç$t®ÊçTÓìç‚ «ëX&¸8†9fUi@‚rzŽžµnõl:Xätë2߃T•Âf»cf µ©•Ž@•!—§f´ººw‰§¾¼–¤Ïn}–Êì!„*dhÛ!‰'€p:y'­¢Ç…ËOðçÙËÅm¼¼Ž$Ü…šC…ú('ŽÂ±m5_ j½ËÞXŤXXË 6‰8iÞ;:©Ü£ ^¼äòp=Š5ÜcÃ7öZΣuªÃwbÒ¼)Ú[N’41)b¦B¤üıã è äžžŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ9õìõ]`­Í›ùNaqÏ» ·s}q3ºMøÏ¨ÿ‹¦èñý­ÿØBOç[•«©g±’…ÖæN–¬¶Zvõ(Æâà•$2f88ã5å_É(¾Çüýý&¶¯Y³û–Ÿõùuÿ¡M^_ãèƒxŽý¿éèé5½(»Í±ËH•ðïþDè¿ëö÷ÿJ¥¢‡ò'Eÿ_·¿úU-5>7ê*¢<Í61ž?±SÿH…zÇ…ä3£ºÿÊâ¼”ãÍþÀ©ÿ¤"½k¿òÑ¿Ýåq[Kàû…ˆôyÿ×[×Cÿ 5MUî‘d{uu ¦CÃ#îµ9m-•ƒ-¼@ƒB+œÔà¼_u¨Ø\ÝM¦xzÛRw¹q$òÙ5ÑŒ­ª4qùi†ùßåݫߨ¬ÛûK¨½œ¶±÷NŠ9â²w0 cg™¼ÈʆȪ¥”¨ÆFA ‹^5Ð&¿×^îæ F+8¡ºD¸´³bCqlcb?˜ •-÷ ‘ÜV¾%ޝ¤ëÓÛëÐèúlv‹%üÖ©ƶñ´GdóbËn‘Lg ÈS‘ìáçXtª5ÍgÒW½ôÕ>Ë~—ï{Ãæ¾‡£xŽ÷þ õ­Eb¹»³7k'”¦%—È–HÁÁ-·p@O^I®Žæö +'»¹q(»˜àŸ rI<9'\g†-¿·>^ÛYM ý¶mIa—vP#ÅmòYg›ÉÂNÔùHg‚T9ç‚{/Iu¦±é‚ñX>Ïç>Åö|Í™f ™ÆÀlvÉ¥&¬Û¦§Ãî“coˆgºx ²¯ñ8¾å.qžNp0_Ÿü˜_ÚbŸjvÂ#󟫌äúqX–~'ºRÞ¥”ˆÒ_}Ž8dl1ùöî"šÖÞkÛK¹Ó­·}¢vŸËo•аvä`õ*Î7Ç#5Ë^hϤÛéQ[i·6éU¸¸fYmæÁeÂÍ“¸`¡<ó‘ÓD†8Q˲¨Sï@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Bû×ßõ÷qÿ££½êÕ&…÷¯¿ëîãÿF5G{Õ«£í³ð•tŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†m'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɹ¾Ó4ífk½\fÚ+4p¹ÆéÊPuïÔã׊֥Ñ?ärûŸý+ GðÆ·) oD²µmnî÷Lº¾¹½ V÷‰äÃ7•°“8á2K°ïÀè*Ìw:=ž„kš4wWfv[÷E{p]ÃHˆw×.ìœdƒƒ]‚O’IJ$D X„ŒŒŽÜsRWœÕ˹À_ÜØ¯ƒ °3[Ø_K§ÆÒ>æ5R8Øí%Éè@b¥¾îH®ò&/ 3!BÊ SÔ{Sݳ\›aqœd˜ƒÃ'޼n_ûèzÔÔÛ¾¡k“ÅÆ’Jˆò¶ØÕ˜çàzœL7–«˜na$ò·ß»nÜúçŒzñH 誒êš|ñØKkä£1Û¼Ê$qÏ!s“ÐþUa&ŠG‘DgŒ€ê¤Œ€}8 Ð袊(¨åž+t4©– °±8žäI@³Ånæ•#RÁv'sÜ’©(¢Š(¢Š Nï@ÈfŠâšH¤PÈèÁ•èAE$sÅ+ȑʎÑ6ɰ%àú@QQË^ÛYM ý¶mIa—vP#4ïûå YÔ|·oÿIw+|œN>P7GBxÏ᜷4ŽÂMÿ Õÿ®òÿèǪUvoù¯ýw—ÿF=R®Ì7ðÆ÷ (¢º (¢€ (¢€ (¢€ (¢€ (¢€ ɺ–xuK§…äŒ}…²FHhâ3 ‘‚±Ïlfµ©šTÑ[x®iç•"Š=4³ÈìT I' ¬1Ãc[˜²]Åj¤ê&m9µ({©µ D~OO´ÌxQ»ž¸Èz+íN-:Æ?¶<ßÚÈÖpMÒH#"CµÃ²©'Ê,wànòÁÉÈ®ÈkZQÓŽ¢5;#b È| sŒnÎ:ñK.±¦[ØG6¥gœ˜Ùpó¨³Ó N yÛpŽe¥¾­nÎ/®lu ,”H@•Ã/”6çÅy~èôëù›AÔÙu¨¨[ß.¥=ÈG'ç 9@b 6ƒ‚|¼–ã5èRÜC»ÜK4qÀ‹½¤vUz䞀{ÕUÖt¶Ó›Q]JÌØ©Á¹¯”9ÇÞÎ:ñÖ…¢·õ¸ï}Ng†x4[Ù$¹x,µ)ØJš„—X$|¤¿)‘r1–™zqWu ðÖ‰wu5ìwv²»mI$¸Fr;we˜gÁ#¥vÑÍÐ$ñH¨u‘Xe<‚¥W±ÔôýR7“O¾¶»D;Y­æYŸBA84úú[úùˆåu GE½×§Ð¢»²¶‘îâ–öIçQ$’…#‰Xä·Ê£#Ðd“ŒÝNîtµµ¼k˜í¬µ ‹›‰%“P’ÉIXGšŠN|°H\`ãžF¡Ã§)mwªý·OÓ..%yµ‚í¦MêF£Í ¬|`­¡v!X/Ë kù>m“"Çûѵœ# y=úšeîªÓh÷ž­ui3hi=›CrÐ™î ’ç Föå9ûÄãšôŠÏÔ4[-REk¿´:…Úb[©R7ŒŠÁXzî#Š?¯Ïüÿ­ïýt8ë‹ýGþØâ7±E(’Ø[E%ü¨ÒÄTy˜·Te“$È “òã<Íz ``QNä¤QE!…Q@Q@Q@P×?ä©׬¿ú«õC\ÿ¥ÿ^²ÿèšÜƒ Çö·ÿa ?nVÿÚßý„$þu¹N[“ŒÛ?¹iÿ_—_úÕæ~<”&¿~üýý&·¯L³û–Ÿõùuÿ¡M^Wñ Iñö?çäé5½]?ŒšŸ éß?äN‹þ¿oôªZ(øwÿ"t_õû{ÿ¥RÑSSã~¢¡ü(ú#˜|±Ø?ôˆW¨øWþC:7û¯ü®+Í|¬ÁÔ?ôˆW¥xWþC:7û¯ü®+iüq0ø¾óÑçÿ]mÿ]þ€Õ5WºE‘íÕÔ2™C ºÔå´¶V ¶ñA8®sc‚ñ}Ö£asu6™áëmIÞåÄ“Ëd×F2¶¨ÑÇå¦ç—vv¯~¢³oî^ÛYM ý¶mIa—vP#$µ·³•nÚKëfˆÃçÈèŸdr ä×f5­(éÇQ‘±äN¾P9Æ7gx¤Ÿ[Òm¬á¼ŸT²ŠÖoõSÉpŠ’wùXœ¼æ‹1&ÕôË?ZO®E 6òÉd„!GÈòÆÜ€£rñ»`ç€k2;»#%®¹6£§I êb[Öµ™d†Ôù aœq×nXã’: Ws,ðÁ›4©y{°“Éõ$ ’õl:Xätë2߃T•Âf»cf µ©•Ž@•!—§f´ººw‰§¾¼–¤Ïn}–Êì!„*dhÛ!‰'€p:y'­¢Ç…ËOðçÙËÅm¼¼Ž$Ü…šC…ú('ŽÂ±m5_ j½ËÞXŤXXË 6‰8iÞ;:©Ü£ ^¼äòp=Š5ÜcÃ7öZΣuªÃwbÒ¼)Ú[N’41)b¦B¤üıã è äžžŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªçü€5/úõ—ÿ@5~¨kŸòÔ¿ëÖ_ýÓ[ƒ0tøþÖÿì!'ó­ÊÃÐ?ãû[ÿ°„ŸÎ·)Ërc±›g÷-?ëòëÿBš¼¿Çìˆï³ÿ?#ÿI­ëÔ,þå§ý~]èSW”|F$xŠ÷óò?ôšÞ®—ÆEO€õ‡Ÿò'Eÿ_—¿úU-|;ÿ‘:/úý½ÿÒ©h©©ñ¿P¡ü(ú#Æ@c‹þÀ©ÿ¤b½ ¿òÑ¿Ýåq^|¨~Çÿ¨*é¯Að¯ü†to÷_ù\Võ>¸ˆ|_yèóÿ®¶ÿ®‡ÿ@jš«Ý"ÈöêêL‡!†GÝjrÚ[+[x „W1¹Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8*+Ã,`}åˆÇ/0[̙Ϧ1Þ¼SW·ÞXÓ¼E¨jQ[]E¤Äl¯}žX0¨™Bb0pA ¶ÓÅK¤ëµþ¡wΛco œ¾LÒG|òÛÁU1.Fu#½TµÐoαmysk¥Ãq î›Qµ$Ox•à@<70FB-ïÉ×cI£C©\FV9D1ÇŸ{åb?hþ¿!uÓ^¹ÔôÙ®të(XäÇ•qpцˆÊùÇ•*qQž* 7Ä—×PhóÝé¶ðGª²ˆ|«¶ª˜žL°1¯?(õëÇ3Xøu4AßOi>Ë=·•*Ü\É+Sû½»Ë`aœ‘Ú¡Möß@С…íÚÿIˆŽB#1²îÆ@!Žn)éùÁø?ð µO&—>¡Ûnû,0HÈY¥v@‘ò¨* nx'Ž9¹¦ß_Ïq=¶¡§­¬±…uxe2Å"œôr‹óF;ƒÞ¨.™¬H÷ú‹5¾¡:EBŒÒŲ2Çk1P~mì 6‚:ãšúu ðä³ÞϧCaʱ -"nSpÉ2‘Œw°É<—˜?#wT¿þÍÓå¹ù² ,qgc± «œd3Ú²åñÔóé°éV6÷ {j÷9¸ºhB*”qäåýºKmâ©máþ+[gó¥ Å›³ãŠ©ÀÉ'9Ö©Aà¨?µ!¶ö—º]°¸Eu™Üy‚wƒ’IÎIÁ§ß_ëú`MŠ/ïn-­,´ËWºqqæ‰oY#C е„lXÜp*Ö—âC¨ßÁfö‹®·>aYwª´2*§hÜ lçŽ)·ž°½Õ´÷›N°—M´µ–¶’eVfB¥TŒ·çEæ•{i«i÷z-‚ÖÖ[³É3[ª†d#nØØ`l<`u¡t¿Ÿê Ò‡Qóu˽7ÊÇÙàŠo3wÞÞ\cã={ÕêÈÓ¬oWZºÔ¯Þ3qk ^T2´›YBy*¹qÛ×ñ× :ÿ]‚Š( Š( Š( Š( Š( Š( Š( Š(   ï_×ÝÇþŒjŽ÷«TšÞ¾ÿ¯»ýÕïV®¶ÌÂUÒããNÿ°XþPÕA·Á»vÿô˜r·ÉÄãåqät'Œþ´ŸøøÓ¿ì?”5gPmðnÝ¿ý&Ü­òq8ù@Üy ã?†rÜÒ; 7üƒWþ»Ëÿ£©UÙ¿ä¿õÞ_ýõJ»0ßÃÜ(¢Šè$(¢Š(¢Š(¢Š(¢Š(¢Š+&æûLÓµ™®õq›h¬ÑÂç¤)AÔ¼S^+Z—Dÿ‘Éÿìô`¬1Ãܤ5½ÊÕµ»»Ý2êúæô4Q[Þ'“ ÞVÀLã„É.ÿ «1Üèöza®hÑÝ]™ÙoÝíÁw "!Ü\|»²q’ v ÿÈý~ÞÿéT´TÔøß¨¨ >ˆñåaýŸýSÿHÅw¾ÿÎþëÿ+ŠóŸ7ý5ÿ¨"é¯Fð¯ü†to÷_ù\Vóø>âañ?úëoúèô©ª½Ò,n®¡”Èrd}Ö§-¥²°e·ˆrAÅs‹îµ ›©´Ï[jN÷.$ž[&º1•µFŽ?-0ß;ü»³µ{õ›qâ u³ƒÂÖ ÞéÑGf`ƒbó÷œ/CÓï¡j³ÝèÊ,ÖëíÞ|$ÌQcòL8³,Ø;¹Qžœu¤Ó´=gF†ÓìFÂY¿³à³œÌî6‹8urãç?)+Ðr3Ã@ÿ¯¿üކÿP¶Óm¾Ñtì°E HÌÇ UPY°°`ñdúŠªéZj\LÏq…šà»"`¤’PİùJñÎHÅZ»Ð^/³ÜéÒI%սȸXï/&ts±®X¹A‡'Ô+-¼7ª½š4¶úl×Fêâf u4‡ e‡fB0ÜŒTëý|‡Ûúïÿé¬5;{ý" M ŽÞhDÙ“j‘ž}1U"ñ>‘-„÷¿it‚‚C,FË»NÖPpsÁÆ<ðjªøFÕt?ìÿ´Ýû ³Þ·ðSao+vÌóž•BÏÂ÷©er&H"¹‘­”·Ü\åb9ËKÓ¾=Nx§»DkEâÍi–žuÊ"e’ÒT1»ch“r/vF7c=³QZø¢nÛL34ëpÂXÖFE1I³”=sÎs¹In¡ Ý].¤HGÚ¯-®q<,f2Àñ×ä8ü*-3@¾ÓõK;¢Öè”`BÍ0‘Jü¼‘€8ëÔ㔺_úÓüÁìtÔQEQEQEQEQEQEQEQEQEQE`è_zûþ¾î?ôcTw½ZªØ Md½kI­3y8ݳûÆîS¥²Ö%Î뫟Hÿ‹®9¯s­aºOü|ißö ʳ¨6ø7nßþ“îVù8œ| n<Ž„ñŸÃ¶“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡Ïÿ@Ù¿ïì?ü]míaÜBQKö{ÿúÍÿaÿâèû=ÿýfÿ¿°ÿñt{Xw(¥û=ÿýfÿ¿°ÿñt}žÿþ³ߨøº=¬;€”Rýžÿþ³ߨøº>Ïÿ@Ù¿ïì?ü]ÖÀJ)~Ïÿ@Ù¿ïì?ü]g¿ÿ lß÷öþ.kà%¿g¿ÿ lß÷öþ.³ßÿÐ6oûûÿGµ‡p²n¥žRéáy#aA,‘’8Œè$`G „,sÛ­³ßÿÐ6oûûÿQÙé[kS]¥”ÈÿeX—p×—É?ëWû½ïÏlå^q”,˜-ÌY.â5GÒu6œÚ” =ÔÚ„ˆ¢?'§ÚFæ ¼(ÝÏ\d ½ö§cÛoídk8&Ši$‘!ÚáÙT“å;ð7y`ääWAöíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòMp¤UÎ^C(Õ-õkv·\ØêY/˜TJÁ“Ês‡mƒ<‚H?tbÂÞ+Ø_&«ÝÜéûlñuö¦•’f—ŒInÒS ÏAšè>Ý®ÿÏÿÀxÿù&·k¿óÁð?þI¡++w1.à—N“P– CQ"ËQ´ŽÝ$½‘ÕVCðÙoœÇïç±Q®²£ÆvÉä¹{Ù`¸ŠmAšP¡$Àû(Q2«µ¾ñÏÞ5¿öíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòMþ¾à¾‡5¦k6Vöúƒßj’Ý[­¦ùî-µYXÜÜ­´ÛHÄðŠÀ}à~í]ÓÖÊD²Þ JÊiïnÎ{ÄËŸ,"’Xºæ®9èr3[n×ç‚ÿà<ü“GÛµßùà¿øÿ$Ñ`¹-ÔZþ¥µí®¡¦ÖÖÂâÏýR¦÷ÝÁ`\G¸“œàŽŒÇ ú•÷‰î쎢\É=ÌOê™ ¤F›cÇîØI¸g8Î[Ñý»]ÿž ÿ€ñÿòMn×ç‚ÿà<ü“E‚ç5w¬jWÚPÔžV¶¶7PÙ܉.ÞÖ4Ø­æ"‚PHMÀr €sSÙ ­Mô›k­Jå k+¹CYÞÊ¢@² Œ™0ŒøVûغò;ßn×ç‚ÿà<ü“GÛµßùà¿øÿ$ÐÕÿ¯+Á ˜þ\kË{sq#^Ýè–ró6$ûûØ&qÁÛÐp[¶ã¯N ‚Ä\\Ék§=È[ÉÒSÄØÅs  .d×êðÕµV)ã[p6çÈlýRè=ºTvjšis]>ügí´øÇ§™vØü)½X^ßוŒ+µ…޹¨Xjš„¢ËIŠ[iþÒê\«ÎT±óc¶C~læ­ëÚȃÄIå^IÄwVÈÉ.¢Ñ|ŒÉ»Ë·¦²ÍÈ9ÁùF:·k¿óÁð?þI£íÚïüð_üÿ’h¶©ƒ×Übé²\¥î›yöÛÉeºÕo-¤In]£ò×ÎÚ¡ Ú0QyÆ}ñÅS´Ôg-éú•ÝΰÚmÔ—V­pÒ,w@.ÆICF8ìz×Möísþx/þÇÿÉ5Ÿggct×Q[Ìó²•ßpÆrªNH]÷gh$ Œàz ž^ƒæÖöþ®/7{o¡ºµ ^¡-áY;³#¢ã#iØ Ú{ ÕŸÇö·†î.%’4ŽüË3 ɉö‚%‚€;äâ Ç|5mFŠxçEVÜ ¹ò?Tºn•„¦š\À—O¿ûD­>1éæ]¶? ¦®Ä‘Î=À¾ðþ½j/å¿c¦I$“[ê2Ì¥×d€6îyýÚœò×O­jzt^´Xuk28¼ÔÔLH?w¹|Û€K"‘´äÄ•êæ×Ûµßùà¿øÿ$Ñöíwþx/þÇÿÉ4­¥‚úßúèsúÝΫw¤Ç-íÃ$qß8H¯]•Ìs sðdHå¾ð<õª“Ki}¢[!Ö/eÕ&šÓíð}¡›È”ÜG»*r!`IFÞü¹_Ûµßùà¿øÿ$Ñöíwþx/þÇÿÉ4ÒÕ]Bû˜Oö¿·" Bö8†­%´nn]TÙ¹%Žädœ`zU{½cR¾Ò†¤òµµ±º†ÎäIvö±¦Åo0™€ÊBn dšé~Ý®ÿÏÿÀxÿù&·k¿óÁð?þI¥oÓð –<-,óxzÙî'IÉ.T‘¤ ›ŽÏ•Kü¸ù±óuç9­ŠçþÝ®ÿÏÿÀxÿù&·k¿óÁð?þI¦Ð&tW?öíwþx/þÇÿÉ4}»]ÿž ÿ€ñÿòM+΂ŠçþÝ®ÿÏÿÀxÿù&·k¿óÁð?þI¢Ás ¢¹ÿ·k¿óÁð?þI£íÚïüð_üÿ’h°\è*†¹ÿ Kþ½eÿÐ g}»]ÿž ÿ€ñÿòMCu6µyg=´á&£b°GÁÇúE4‚ã4wháÖ"yYu+‚#B9x dû+Hø§ëzØÒ-4\]†"U’Q _çù@ïßà™ïæ•T<`ªœc9qèzg§¦*Ä`Ãs5ÌZ‰<û|éTÀM£ ¸ïÉÀàg¥'¸-„³û–Ÿõùuÿ¡M^Qñ€ñ÷ý|ý&·¯Y¶ŽH’ÉeŒÆææw(XyÌ3‚GB;׎|N¯‰ïý<ÿíµµ]?ˆŠŸ ëÿäN‹þ¿oôªZ(øwÿ"t_õû{ÿ¥RÑJ§ÆýECøQôGˆ*æÏýAÿH…z_…ä3£ºÿÊâ¼åãÖ?û'þ‘ ôo ÿÈgFÿuÿ•Åm?ƒî&èóÿ®¶ÿ®‡ÿ@jš«Ý"ÈöêêL‡!†GÝjrÚ[+[x „W9±Áx¾ëQ°¹º›Lðõ¶¤ïrâIå²k£[ThãòÓ ó¿Ë»;W¿QY·÷ —Q{8kæºx­á)æ ’6Päm¬¡¶’xlc¯<Ãðu¼:ßË›hçSíÆ¢‹4gp*÷SÀŽ£>ôšÎ‘¬Ï§]^\Ajoä6pG±ySλªqóŒp©¯©¡«?‹ìm=-ãžawrÖ͘%V‚ùÔ¦Wøx pwt§(Ó#²²¸¹ŸoÚ`Yÿs’¢#cæf6/?yÂô=0qžú«=Ü:Œ¢Ín¾ÝçÉLÅ?$Àû2̓»•éÇZM;CÖthm>Äl%›û> 9ÌÎách³‡P.>sò’½#<4úûÿÈè.ï–ÖæÊS7R˜—q ä#7R ù{:óœ/Œ,Ž ¶¶p\]“Ò~îü¼ G•L“Œ©Àüji¼:þ=´Ó‚é§›írÊpb‘>Må¶ò㠬ȴOÚ}…-¿³6é–’ÛÚ¼’92’#8Ûò€ Ï­HË7^)¹Ó-ï¿´ì-mî-¢Še {º&Y`ÜåL09ùHÇBy­mR}VÃíLlK­cyö˜Èíl^sž1øÖEŽ“«C§Î—6\·né3Ë=ÓÏö‰ƒóf%ÙŒ|¸/^*Ä7-£ÍqwªA0¸¾9ŠÂÞ{´@ªï$yÉÆyÓœf˜‹>#×G‡ô™o~ÅqvèŒË(qòŒ’ÏŒ Çsøx­F•4Œ¨Š»™˜à(ÆI&±õ‘-„÷¿it‚‚C,FË»NÖPpsÁÆ<ði‘x³Gše…gd2ˆ™d´• nØÚ$Ü£ËÝ‘ØÏlÖMŸ…ïRÊäLEs#[(?o¸¹ÊÅ s–—§|(zœñPÐn®—R $#íW–× ¸ž3`xëò~Z\žƒ­¼Q Æ·k¦šá.KÈȦ)6`’€g®yÀ w);õÌéšöŸªYÝ·t¯D ;i„ŠWåäŒAÇ^§ôÔº!½Ý‚Š( Š( Š( Š( Š( Š( Š( Š( Jû—Ÿõû?þŒ5~¨i_róþ¿gÿц¯Ó–âŽÆ&“ÿwý‚Çò†¬ê ¾ Û·ÿ¤À»•¾N'(#¡ð?Þ4ÿìÛ¿ú ]ÿßñ rO±Áé7þËÿÅQö8=&ÿÀ™øªû6ïþ‚—÷Ä_üEÙ·ô»ÿ¾"ÿâ)ò‹˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ9C˜“ìpzMÿ2ÿñT}ŽI¿ð&_þ*¢°3 /!šw˜Ã0Eg  hßÂêÆ °µ½»Ó­n_Sº ,)! ‘c$ÇÉJùsìpzMÿ2ÿñT}ŽI¿ð&_þ*£þÍ»ÿ ¥ßýñÿGömßý.ÿøŠ|¢æ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄU_´ÜI YÌ&+<ÂÜ4Š£?; bî{R°î^û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"Ÿ(¹‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñfÝÿÐRïþø‹ÿˆ£”9‰>Ç¤ßø/ÿGØàô›ÿeÿâª?ìÛ¿ú ]ÿßñËQq£qm5Ì“ªÃŠdU\º÷E+äÿcƒÒoü —ÿŠ£ìpzMÿ2ÿñURÖÞòò9&þѸAçJQ#À #(ê„ô?ömßý.ÿøŠ|¢æ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄQý›wÿAK¿ûâ/þ"ŽPæ$û“àL¿üUcƒÒoü —ÿЍÿ³nÿè)wÿ|EÿÄTV÷–qÇ7öÃ:$*éiOD¡£”|Å¿±Áé7þËÿÅQö8=&ÿÀ™øª‚è\M¨ÛÛCs$ ÐÉ#ÕI$ïýãOþÍ»ÿ ¥ßýñÿI ¹'Øàô›ÿeÿâ¨û“àL¿üUGý›wÿAK¿ûâ/þ"ìÛ¿ú ]ÿßñùEÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£û6ïþ‚—÷Ä_üE¡ÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£û6ïþ‚—÷Ä_üE¡ÌIö8=&ÿÀ™øª>Ç¤ßø/ÿQÿfÝÿÐRïþø‹ÿˆ£My^ÐùÒf–=ì$,Œ£8t“Vw$û“àL¿üUcƒÒoü —ÿŠ©è¤2$µ†9@®Ys´´ÎØÈ#¡b:^!ñ97x¢ðÿÓÏþÛ[WºW‰üG]Þ&½ÿ¯‘ÿ¤ÖÕtþ"*|'ª|;ÿ‘:/úý½ÿÒ©h£áçü‰Ñ×íïþ•KE>7êMáGÑ!¿F?êŸúD+Òü+ÿ!ý×þWæ¾^`ŒÿÔ?ôˆW¥xWþC:7û¯ü®+iüq0øGŸýu·ýt?úTÕ^éG·WPÊd9 2>ëS–ÒÙX2ÛÄ9 â¹ÍŽ Å÷Z…ÍÔÚg‡­µ'{—O-“]ÊÚ£G–˜oþ]ÙÚ½úŠÍ¿¸ñº‹ÙÁá kot裞+'s–6y›ÌŒ¨aŠªYJŒddµã]kýuîî`Ôb³Š¤K‹K1v$7É6#ù€©Rßp©Å`[èÒXêúN½=¾½¦Çh²_Íj‘kèwú?ˆïáŸZÔV›»?µ¬žR˜–_"Y#m»‚zòM>÷ÅúJJu-2Õ\YÍuÛ^´›¼° º5ÛÃf³<1mý¹ðºöÚÊh_í³jK »²ºêlŒñÏQšÛ½ðµ‚øR±Òtû +‹ËV„¼P¬`’ŠŒã&¼SUk¯ë±v_i°_-œ³8˜²!+ ´hͪÒÚ¬r0 äzŠÇµñª]ÞØÛ¥‹Æ·夒o1V(á¡b|¼q’nÞ2yn¯ kZ†¤®³DöñÜA4%¯eˆF¨È̆]²d©;˜äd` TqøJòV¸†æhÞHoà±|\H®§ù=<ðÁü¿ÌKm|¿à› â¬e¼72$1” $¶‘ç8B¨bœ>†’ohÖòùsÜË.Íåí¥Qð ‡%p„ä`69ã¨"³eÐ5mAÍÝïØ¡¹ßf¢8dgMÍæ3n*NH Œ yâõÞ‰s?öž×ˆ}ªêÞdÉ<,~^sÇ_ãð§ý~@X$ÓÍ®D—Vo ÅöI|ï3¶ù[wçoÍ÷zsÒ¯ÙÞAiÕ´žd2 «`ƒô ò<y¹ëÿÞËq¨MV“‹‹ÈîæXB©•–1¹ ô*Hã5µ£ÚÝYiP[ÞÏçN îmåð $.ãË``n<œdòit^¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(›³[ÈÒsvÎu;fI™>kŒ`#zzÕú—üûÙàSÿñª¡|ÚÂhWhkj÷ÉspËÒ’²:L¨!†¡)Õ­¤¼ñ•­Œ'内ÒV òÌŽÑØ dõàc-½D–…í'þ>4ïûå YÔ|·oÿIw+|œN>P7GBxÏá[Iÿ;þÁcùCVußíÛÿÒ`]Êß'” ǑО3ø`\·&; ‚=vÔŸùö˜ãÑVÚ‡µbß>Í^ÐÿÓ ¿ô(éþ½М¬Æx³Äè~šþ×ìâT’5u%3…$€G@Iê+&ËÇ>\ÚÛ.,õ [aŠëMˆ…–G$y@`[8þ,sÎ*}vÃûkKk/?É̑ɿnïºá±ŒŽ¸ÅdßøJÉ50·B;ké#¸û;Bu9ߌà†ÀܸçÖŽGý_× s«u¯ÜÅinº^žâõõ±š+”F0±è$‰ †Ç©}|uh"¼‘ìo<»IÚѦeœ0]ˆ7î$’1‘R+ <*‚ UÚÂðê zE­ŠÂ‡h Psß©,ióx^þÂ[ßj¾kÕfˆF,)R~aÆLƒÚ…ý|¿à‡:þ¾ð ©uëÏþ½¤üB‚ãG‚{ûiñ¢¶vŽd36ÕòÁlàsž˜ï]wÚ‡µy¤– gÃȽ¶—nR[’UVb0P [!²yãÞ»O?Þ¯’ÿ{'žÆ¿Ú‡µsñ¾ÒÏ¡´?øüugÏ÷ªyÇ…tóè-?ô4©qµ†¥s£ûPö¦Év'aŒ€H¬¯?ÞšòïF\ã Š% 4=NwFøƒyk¢=Ô°Ëupñݬ Œº²|Üd9Ï!«TüBÓ…´— g|± vº„˜Óý"8gA»¶AÃm89Å`ÁàÈam›æoìøÚ)pCßå#{zõ©4Ûi›£v³’!­×ʱHåen2òrY±ÇAî(pzØ9×õêoMãÝ2ïáò®d{3 ˆ§Í2'<òFsеªø® +P¶±û ÝÕÍÄRJ‰n¨xLnÉf¿ù8®FÇÁ¢Õô§—T’f²‘䘘±ö“S<ñ·×8íVµ«RóÄúmå„©Cm!Œ€ã;Ã3ò޼Q(4¼ÿ_øRWû¿Oø'T¾>Ó„S4ö·–ò¤qÉ2F»æYfŽO$c¾)eñÕ”VêÍc{ö“z,ZÐ*y©)ùöàŒ†#Ÿ®9§ð‹êVŽú¥âÉvÖðEîØ„gp »ˆ|ž½튵…Ò8­@šÒ'†ý/µ²XPí {õ%>MmýoþDóéývÿ3J/2ê÷Ö׺M͵½¼¶ðy„ÆÅ^›ðç$tÏCÏ8­í/]·Õ­¤¸·GXÒi!Ô Å©#ž™Åkz-ËůÍlZçûR$Qnˆªé"®ƒ³Œ‘ŒúVæ‰lt­ÎŘ3ÃÀçsõcø’M ÿ¯ëõŸoëúý›íCÚ³„‚Mvèùö„ãÒÔ>½2Å÷ê÷gþ˜Cÿ¡IJQ²+²æ‘8K^8¹ŸÿF½^ûPö®~Ê]±J?éæýÕgÏ÷§È.r½Þ»¨Ýë×N’lák[tši®¢iAg'jV\p¤““ô¢óÆ1i„Ayk,·Û‹‹ÓfÇl¤ãq,T‘Á [œVuæ›rui5=6ú;[‰ ÍæÀeV’¬eà žäsÒ©Þør{™'tÕZòÕmoZHšUù—B6 „sÓŠ\Žßןü¹Õÿ¯/ø&ÃøÿNKÉáû-ãCo4pËt¨†%2PýíÄŽƒŽõkOñ…Ž£umk 7 4âbUÕuå>Æß‚qÉã®2 Ý˪[Ë(·Òf¹‚E‹hv™#UÀ7ËÊ€rqÆ+G@Òæµñ&µªÍ ÁÌ€Aޤ€]°¤€†zçŽ@¦¡ªþº/ÔNzçÚ‡µQÕçb‹Ç70èÔªÞ½V½—tQúyƒÿF­‚ç/™zí©?óí0ÿÇ¢­µjž}š½¡ÿ¦èQÓüÿzQÐÜ¬Æø§^¹Ñô/,–8–(×ÎRÊ7:©$ ëëYçÆi…톷äM$QE5¼–p”3‡m36pÆwc‘ÓšýƒkzKÙ-À™ÑÄ…7€UƒtÈÏOZʾð±Õ–î]Jö)¯'*:[mŠ5·((Y·IÎ[‘Çr0çV5§ñÀ7VCZý­/bºQ¾#gÈ*Åzs’0ieøkö‹ˆ,.‹-£ÞZ‰B"ÝF½YNâ@èpÀ¬xü'Û¦µÊº7–¶K0(Sh r8lä–5‡ƒ ²µžÛδòÞÖKTx¬9pÀÏ&IfŽ6ƒÜRpv×Oóšºþºÿ‘¸ž>·‹O‚k»¯4Z%Õà…P­²7FoŸy .æÀä êñÔ©Vwçø0LÐË-ÍŒ³-²[HóiË(Ú‡ådÄ#cƒÀõÅuñȱF±¦¨ ÀJ¾MÉçØÙûPö¬Í0î¶”úÜÎò+Ô~½.Žs`O¬óÿèÖ©”lŠŒ®ËôQEfXW‹|Dÿ‘–÷þ¾Gþ“[×´×üBˆ¯Oý<ý&·­)|DTøOLøyÿ"t_õù{ÿ¥RÑGÃÏù¢ÿ¯Ëßý*–ŠU>7êMáGÑ&ú4öOý"éþ´•bÓõ8ÞaÜR3.îe§|võ¯'´¼IôË+õO:ÜÙ¥¬Ê ‘‰=º¸­aâéfÿÀ{?þG®†¹£c%$™í©^;ÄÞEØÛ¿ãæNx#þy{ÔŸÚןóíeÿRñªñ!â©ÏfÿÀ{?þG©SÄÓ7fÿÀ{?þG¨ö^EûO3Ó5 kë—¸žÞÛ@ûLÓ+™/b’à* ´ªz®sžäc½W¿Óµ 8Y[ørÌy‘¼°KæG´dåÔ)9`§#n#© <ôøŽö¿ðÏÿ‘é‡Ä³ïà=Ÿÿ#Õr´­oËüƒÚyž¿§j:Ì|1j-¦]]¨Ä“ÄòB¯ÏaFÇÏ=sÓ µý­yÿ>Ö_ø'ÿ¯'—¸oü³ÿäzx–B?‹ÿìÿù§Ùyµó=—ûZóþ}¬¿ð*Oþ5GöµçüûYàTŸüj¼JoÜ'Ý íÞÏÿ‘ê©ñØþÿÀ{?þF¥ìü‡í<ÏwþÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ¯´ñUÔò`@?ôïgÿÈõ×éÓÃrŠe‚éÚÓÿŒQìü‡ÏæzöµçüûYàTŸüjíkÏùö²ÿÀ©?øÕrÉem ÊÊð×ÿŒÓÿ³`ÿž‡ÿmøÍ.EØ9Ÿs¦þÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ®gû:ÖCÿ€¶¿üf˜l­‡üµ?ø kÿÆhä]ƒ™÷:ŸíkÏùö²ÿÀ©?øÕÚןóíeÿRñªåþÁmõ‡ÿmøÍ1ím¬¿ù+kÿÆhä]ƒ™÷:¿íkÏùö²ÿÀ©?øÕÚןóíeÿRñªãˆ²oþKZÿñšš;[YGË/þJÚÿñš=Ÿs¾çWý­yÿ>Ö_ø'ÿ£ûZóþ}¬¿ð*Oþ5\Ïölß?ø kÿÆi?³¡þùÿÀ[_þ3G"ìϹÓÿk^ϵ—þIÿƨþÖ¼ÿŸk/ü “ÿW.tø¾ð×ÿŒÒ¼ð×ÿŒÑÈ»3îu?ÚןóíeÿRñª?µ¯?çÚËÿ¤ÿãUÊ}Šïä­¯ÿ©cÓ­äÿ–„Û­¯ÿ£‘vgÜ鿵¯?çÚËÿ¤ÿãTk^ϵ—þIÿÆ«žþǃþzüµÿã4cÁÿ=þÚÿñš9aó>çCý­yÿ>Ö_ø'ÿ£ûZóþ}¬¿ð*Oþ5\ÿö<óÔÿà-¯ÿ£ûßþzŸüµÿã4r.ÁÌûöµçüûYàTŸüjíkÏùö²ÿÀ©?øÕsÿØÐÏSÿ€¶¿üfìh?ç«à-¯ÿ¥È»3îtÚןóíeÿRñª?µ¯?çÚËÿ¤ÿãUÍI¥B%oüµÿã5Y¬¢ýsà-§ÿ¬¥Rœ]š-Foc®þÖ¼ÿŸk/ü “ÿQý­yÿ>Ö_ø'ÿ®9ì”%?ø iÿÆ*¤ÐH$?ø iÿÆ*}µ!û96ýf0VÞM)P¼‰V9ggê{…ˆ?ç¶ùMþÊ"ÊO.ðÓÿŒU¨¡ ÕþÚñŠ_Y¤?cPéì#òu 8K+´óeÎ S8ÏÒ¦Ôƒy ¾â|û|08\yã ž@êxÎGÐsð¤–Ľ½Ôг ¥¢‚ÙIq‘°§ý¢ñðR½`8e·# äõ^¼Òxˆ6 ›±¿¨iòÝÏÐÜ$Mºñ—1SÙ‡÷j·öU÷üÿ[ÿà3ñuž×—àÈR÷þø·ÿã4‹}|æ){ÿ|[ÿñšk–—¥}Mì«ïùþ·ÿÀfÿâèþʾÿŸëüoþ.³þ×~zj·¿÷Å¿ÿ¨äºÕ@Êj·¿÷Å·ÿªX‹õ%ÓK¡©ý•}ÿ?Öÿø ßü]ÙWßóýoÿ€ÍÿÅ×+y­ëvÇNôÿÀm¿øÅPÿ„£^=5ÏûæÛÿŒVžÑ÷EØî²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºàÛÅ>!_ù½ÿ¾m¿øÅW“Æž ­õïýómÿÆ*““Ù’ÔWCÑ?²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºóSãÝpu¿½ü­¿øÅE'Ä=m?åú÷ò¶ÿã\µ ¼[Ó¬¤²I„³,¯,ža*›@ùUqŒŸîÕt[Ø Ž¿€¬jfØçcûõå/ñ;Z_ù~½ü­¿øÅ0|QÖ¿çö÷ò¶ÿäz\“Cæƒ=sû*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯(O‰šÓŸøý½ü­¿øÅY_ˆzÓøÿ¼ü­¿øÅ;TàzwöU÷üÿ[ÿà3ñte_Ïõ¿þ7ÿ^d~!k#þ_ï?+oþ1PËñZQ‘yù[ñŠ-P/Ôÿ²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºòø¡¯ÇÛ¯?+_þG«|J×$ëx? _þG¥jx¯ý•}ÿ?Öÿø ßü]X“MfÑ¡°Y‚´KÈ% ž™ï·Ö¼³þýd®F¡{ùZÿñЬÿuÅ?ò½ü­ù“ŒÞãR‚=Sû*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯&?µÁÿ1 ßÊ×ÿ‘é?áeëŸô½ü­ùŸïzg­e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuä¿ð²õÏú^þV¿üGü,½sþ‚¿•¯ÿ#Ñjxµý•}ÿ?Öÿø ßü]ÙWßóýoÿ€ÍÿÅו'Ämuÿåþ÷òµÿäz»޵É1»P½ü­¿øÅ>Zzg¤e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuÁ/Œur9Ô¯ï›oþ1CxËWó½ÿ¾m¿øÅ>J¢æ¦w¿ÙWßóýoÿ€ÍÿÅÑý•}ÿ?Öÿø ßü]yÿü&ZÉé©^ÿß6¿übøË[í©^ÿß6¿übŽJ¡ÍLôì«ïùþ·ÿÀfÿâèþʾÿŸëüoþ.¼é¼k®Žš•ïýókÿÆ*&ñξ¿ó½?…¯ÿ£’¨sS=+û*ûþ­ÿð¿øº³§éòÚO<Ó\$­"¢‘”)cÝ÷«Ê¿á>×G[ûÏÊÛÿŒR®gþ?ï?+oþ1IÓ¨Õ˜Ôà¶=7û"íCì!G·$Ì[Þ=hþʾÿŸëüoþ.¼Ðxû[Ç7÷Ÿ•·ÿ øÿ[òÿyù[ñŠ9*53Òÿ²¯¿çúßÿ›ÿ‹£û*ûþ­ÿð¿øºó/øX:×üÿÞ~VßübøX:×üÿÞ~VßübŽZzg¦ÿe_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuæ_𰵯ùÿ¼ü­¿øÅ8|@Öü¿Þ~VßübŽZzg¥ÿe_Ïõ¿þ7ÿGöEÛ¼f[ØJ$‰! nA;X63¼úW™ŸˆÈñÿyù[ñŠþ&µ»o½ü­¿øÅµš™ë:†Ÿ-ÜðM ÂDÑ«©ßpC=˜v«e_Ïõ¿þ7ÿ^f> kGþ_ï?+oþ1R¯5’9¿¼ü­¿øÅ ˆ ÷=û*ûþ­ÿð¿øº?²¯¿çúßÿ›ÿ‹¯:ÿ„ïXÿ …çåmÿÆ)ãí`5 ßÊÛÿŒSå¨.jg¤e_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuæãǺÉÿ—ûßÊÛÿŒRÿÂy¬ÿÐBóò¶ÿãrÔjg£ÿe_Ïõ¿þ7ÿGöU÷üÿ[ÿà3ñuçkã`õÔ/?+oþ1R¯µcÿ1ÏûæÛÿŒQÉT9©ÿöU÷üÿ[ÿà3ñuOµk+5¤0gbÁv‚Y‹tÉõõ¯44Õ¿è#yÿ|ÛñŠ_øLõoúÞß6ßüb“§Qî58-S¢¼š_k8Ô/+oþ1U[â²§þBŸ•·ÿ©ö2+ÚDö:ò_®ï_úyúMoTÿábkÀ¿¼ü­¿øÅS¸Ô%Ö&{›‡}ÅŒ³O3/?*®NÕUTQÀíWNœ”µ"¥Hòž·ð÷þDè¿ëò÷ÿJ¥¢¢øip—~³¹‹>\×r&FæR?CEc7y6‹¢š§û" o… ³Ék¥Ínç«C¨\!?”•oþ߇?ç–£ÿƒk¿þ;E)Éh˜J”$ï(¦ð¯<9ÿì=…/å_p¼ðçüñÔ?ðmuÿÇ)á_xwþxßÿàÖëÿŽQEÒ}Ø{ _ʾáÃÀòÆûÿw?ürø@|=ÿì=…/å_pÂáïùá}ÿƒ;Ÿþ9Gü ÿž7ßø3¹ÿã”QG´Ÿv—ò¯¸?áð÷üñ¾ÿÁÏÿ¤ÿ…áßùãÿƒK¯þ9E{I÷aì)*ûƒþ÷‡çÿþ .¿øåáÿ‡Gü±¿ÿÁ¥×ÿ¢Š=¤û°ö¿•}ÿáð÷üð¾ÿÁÏÿ£þÏ ßü\ÿñÊ(£ÚO»aKùWÜð€ø{þx^ÿàÊçÿŽQÿ‡¿ç…ïþ ®øåQí'݇°¥ü«îø@|=ÿÿž¿ø2¹ÿã”Âáïùá{ÿƒ+Ÿþ9E{I÷aì)*ûƒþÏ ßü\ÿñÊ?áð÷üð½ÿÁ•Ïÿ¢Š=¤û°ö¿•}Áÿ‡¿ç…ïþ ®øåð€ø{þx^ÿàÊçÿŽQEÒ}Ø{ _ʾá?áð÷üð¾ÿÁÏÿ£þÏïüÜÿñÊ(£ÚO¸{ _ʾàÿ„ÃßóÆûÿw?ürø@<=ÿáì)*û„ÿ…{áßùã¨àÖëÿŽQÿ ÷ßóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}»ðçüñÔðmwÿÇhÿ…wáÏùå¨ÿàÚïÿŽÑEÒ}Ø{ _ʾàÿ…yáÏùã¨àÚëÿŽÒÿ¼ðçüñÔ?ðkuÿÇ(¢i>ì=…/å_p¼ðçüñÔ?ðkuÿÇ)?á^xsþxêø6ºÿã”QG´Ÿv—ò¯¸?á]øsþxê?ø6»ÿã´¼ðçüñÔðmwÿÇh¢i>ì=…/å_p¼ðçüñÔ?ðkuÿÇ(ÿ…yáÏùã¨ÿàÚïÿŽÑEÒ}Ø{ _ʾàÿ…wáÏùå¨ÿàÚïÿŽÑÿ ïßóËQÿÁµßÿ¢Š=¤û°ö¿•}Áÿ ïßóËQÿÁµßÿ£þ߇?ç–£ÿƒk¿þ;E{I÷aì)*ûƒþç‡?玣ÿƒk¯þ;Kÿ ÷ßóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}Áÿ ÷ÿóÇPÿÁ­×ÿ£þï‡?玡ÿƒ[¯þ9E{I÷aì)*ûƒþï‡玡ÿƒ[¯þ9Gü+ßÿÏCÿ·_ürŠ(ö“îÃØRþU÷ü+ßÿÏCÿ·_ürøW¾ÿž:‡þ n¿øåQí'݇°¥ü«îøW¾ÿž:‡þ n¿øåð¯|9ÿì=…/å_p¼ðçüñÔ?ðkuÿÇ(ÿ…{áÏùã¨àÖëÿŽQEÒ}Ø{ _ʾàÿ…{áÏùã¨àÖëÿŽR¼ðçüñÔ?ðkuÿÇ(¢i>ì=…/å_p¿ð¯|9ÿì=…/å_p½ðçüñÔ?ðkuÿÇ(ÿ…{áÏùã¨àÖëÿŽQEÒ}Ø{ _ʾàÿ…{áÏùã¨àÖëÿŽQÿ ÷ÿóÇPÿÁ­×ÿ¢Š=¤û°ö¿•}Áÿ ÷ÿóÇPÿÁ­×ÿ£þ÷‡玡ÿƒ[¯þ9E{I÷aì)*ûƒþï‡玡ÿƒ[¯þ9Gü+ÏÏCÿ·_ürŠ(ö“îÃØRþU÷ ÿ óßóÇPÿÁµ×ÿ¨î>øRî?.æÆêtë¶]FåÇäd¢ŠNrz65FšwQ_qÐi:Mއ¦C¦é°yçËs62KX“Ôš(¢¤ÐÿÙ endstream endobj 3498 0 obj << /D [3496 0 R /XYZ 89 721 null] >> endobj 3499 0 obj << /D [3496 0 R /XYZ 90 201.239 null] >> endobj 3500 0 obj << /D [3496 0 R /XYZ 90 169.5 null] >> endobj 3501 0 obj << /D [3496 0 R /XYZ 90 137.761 null] >> endobj 3502 0 obj << /D [3496 0 R /XYZ 90 106.022 null] >> endobj 3503 0 obj << /D [3496 0 R /XYZ 90 74.283 null] >> endobj 3495 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R >> /XObject << /Im32 3494 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3506 0 obj << /Length 2581 /Filter /FlateDecode >> stream xÚµYݓ㶠ß¿ÂO­Ü9ëôý±édÆÙÝËmç®iwÝÞC.³#Ëôš=YREzm&ÿ{”%¯r—ôãÁ#$A€øhoö8ófß^|³ºxý&f¹›'A2[mg¹7K½Ìõ¢x¶Ú̾w®Þ.ÿ²º¹›/‚ØsRw¾ˆÏY^Ï#ÏùûÜcgùç«›k~s³œû¾ï¬þvws?ÿaõ§×oâ`À;BÆq;Ö~æá¤ …I¼™ï»y «`úÂÎ_)ðiUê&n0_øžç9×b[*M»ï¡%ËBq·›û™#ªB‹ ZCiZÑi)Ô„xÞlágn’Ñ>ßÕóEåŽnZlÀÊ-v‚ïû }çæiîGލ5Ím;³Ï3Ml;1bçI6U=ÓŒPe'×bó úi䬿™çõcCÃêжM§•ݲÂòê50uCôøèyA Ê‚bFs¤ËFlç>°ïÏê å)ªƒ î¶é&ÏPwE­PîjY?B`¶Ú %ìÉždÂ~щˑeg~âFaB%n 5B} ‚ø¥ýOæÈÜ(É-Vú³¾ƒNØ. \lñìB©¦”lú00‡d¾hº +ÝU÷ÏJ‹= 4ëˆR£f˜b'‘í¡ª³åûâG¹?ðÚ%2­£¬ªóÖš—›fÁ¢Ž ´TiÊ;¤ÙÈ@‡ÖMÙT4x܉šç£¶¢ëÀ.4FH›û1‚Ê4 ‚ý˜¡Ñ(ï×R¿V¢ä™·5‘aga%²SO˜2¨=8†ã+†Îޱ2À9v+¹îŠî™:æŒA“0EÄ/Ä ó= ?Û‚ƒÎFþ¶Û§jkqìB0š€Z˜ÔÌ×D h ¡†ýjI;·šˆª¥Ä3n=\ÞCÍPåžÉ½Ø“5/%t}êl i$èÈ.Ç,wpzIêl ]PkW(j?I2-ô×ó¬²E+ÈŒq€JÑXî¥R²©‰(ùË‚VAL;Q yB'óPò±.*Þ_5{^S5ú,¦KºŽfp<:ÉN¤©7Š#•5PY"ƒF;sjèY*‚Ú4þ#ëâFÛ>~Ëw&òÿ Êo›vêÎKbׂɸ™øŒŸÕ†‹7aà7£ÀÆM NzÃ(zbæ¢(p®û5aÂdz¡HIÂL,*±7×l%Æ ºæ E‡€6Šl …Æ0†Âä¶(É.Ü7·XW¼À¨ ”²k”—;7…ñ ’óa«©yÁHËϬ&Äœ¤IFöLüœ ›egXŠÁ|è| XŽ¥­Ht˜™ãá6)DÈAè\³±¢Ð—ì]„j ô·†õè¢F—|¦Ñ}Ó ÞüöÌ—3ë9Éè:Hø:Hþç×Á¯r¡Ø%`cöŸ$”=‘›{élnîû6yL9u|/@Où¯þÂѲ1î&ó Ð'\Дø`ܲ˜Ô†o &—„#èÁ·PŸ¨1Ôr0®453ªù‹†d¦ùÖtò¸hÇŠ ­c'µ¼rx8Ð¥ BŒ43$spC–÷WËw˻ӮS&†û7¤õ†ÍÓ'¶†TS+a€tw³¼~øpw»ºá)#úíêípp$/à0È3Y|v2˜µ=TvÃâ LRp.öõs#snJÃKA}“¹>´Ôoá"¯†Â±0™ÜÄêýA^:–[.ÖûathX{²t$ûÉÃ{ì¾ðÝ ~?™ß“=RØ¡m+I±#‹œ%q3ñpŽ(I7Óª©an~(GE-:¾RF,ófÒŽ¹ Ï!ãÙ•ýô 9ÌQ§ õ8†¾\ $eÃyÛHŠÄV›ˆµ‰Ð»¤–E% „õ•e¹mªªA‘ µR”Ñç²ùEo²¾¸“>kkHOoW½#ËZAÒÕÏ­¿ì¼Tm!Úçqì¸S@ -Â$!H$¨EùF J…Âaù ‡ö%Ã$J&¨Ôs=8=^µz×lh3ó®_.y_Dy£Û[%:55¥¢ùx fFåwÒ'œ_f]P"¾€JÃÍΊ^1:6Ÿ0šb àØZúÓè§‚ÇíQ`›lŸôaû(õŽZÚ²l‹®€e¦\Š¡7o{PCûŽ Alx ´ÞäoqÒ‡ýOŒñ|/•´w+Þö ˜o%ù ÎSqï< Ï8 ƒ—gÓ‹nó™D|ü*ì™Ì>ˆóž™ë÷ÏÁF]¦©¿ø¾ûNèߣG˜Â%ê‹vì…tÕU óüXìÛŠ¨"¶mUÐsGèépaˆJ¡ž="L$Æ@¬#ÎSÜôþ€%‚àq¥{ÞðÈ´]óÉ™Yâ†g`zÇ ‰2,7€J.3Òc6B¢B¯>IêWr«‰dÔ›˜Ñ EÏÂÐFàáà &B;a* Ú•œβj©¨ÎœïFeø¥)–£ÓÜ Iè‘ÊŠB™ªIüइ}ÝÚ‘Å(*ˆ£›É´òìHãŒêÌl\”ææü°*CáÃØ#qÖ‹p¾$³Q W“Ü@£WÜe¢ÖX8 7IN¶”õŸÁêÑ$‹í,#\ä|sдíÖJÆžñ™BÏô½ºôƒ½*9ïg¨üH>8óYFCÏ ¡-rÂ>¬eÓд6 í;c˜ð{|Êã)äȵîŒy 1[&†ø¢¨tQ—¦2 sç¹9"ó!«­< íò8xmäe)Œ]³Xú € µ”¨ÝS7%¿™æ ÅQ:ü×D&n¹O!Å”¹}öÙ!÷Œ@ß(4·E'Àd¨c‘Œt„UÖ¹sz ,_°Wäã÷´¸ƒ‘N´à¤¢Öd‰¡lÇ]SMÖÞêÍC_ÿwOÿ¸:šÔ#ݳz@ëܳ0¬ó8ý¹d¬ÖL„}Ë‘3õÒ Õû7ìd© endstream endobj 3505 0 obj << /Type /Page /Contents 3506 0 R /Resources 3504 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R >> endobj 3507 0 obj << /D [3505 0 R /XYZ 89 721 null] >> endobj 1174 0 obj << /D [3505 0 R /XYZ 90 690.045 null] >> endobj 1178 0 obj << /D [3505 0 R /XYZ 90 495.189 null] >> endobj 1182 0 obj << /D [3505 0 R /XYZ 90 164.949 null] >> endobj 1186 0 obj << /D [3505 0 R /XYZ 90 138.69 null] >> endobj 3504 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3511 0 obj << /Length 2583 /Filter /FlateDecode >> stream xÚ¥ËrãÆñ®¯`ùË&4@9)Zm,WÙÙxeû°ëRäHDh­r%ßžîé¼)«„yôôkú9‹§…Xüýâo÷—ï£`‘¸‰’jqÿ¸HÄ"±+‚pq¿]|rn¾½þpûãr%CáDîr*á\¿[Âùyéù¡sýÃÍí;Ú~{½ô<ϹÿéÇÛË_ï¿»|Êî‡ (Ô^ì!Ð…`fìw±ò“ÐUÂ_¬d‡}wЋO«Pç~§‰ø)+¶4ªZó0mèÛX¨¦<Р|íÔ_²Už=6C"b±ò@ÉÚ¯ó°/›²ê3À€@ºAèÑ‘(éÈ®d ˜–ð/-žJÚÜäi]ÓТÆ#,‚6M•­—R8džf| (›]V<ܾ¬x»Ù¥…i»Ù¢>C?î” «¢F!FMž›ÀÝé®ó¼O#ŠûböåŠ]Êü6%-l™ö£å Ä`Ø³ÒÆ|Úœ:-=¡Úò†Ut¥;êšø,BQét{yª²FÃÌ¢éø>#ö@j¾ScR~à4KÏ1çaluëûÝÂŽÑø“/¶X´ä|,,쟹CðN«gÐŽÑ,¥ä”‘è9¥L<Þ:åãR†(HœSÁGn+WÁi—åºãÓx€ ¾ò‡ê¸éPÖ9ÿìùV_P˜ZAa˜ÙoSψêÅà‰*°œVK/vʲ™ãa*e¹AО%³_I@0ìšöLñ9ŸtÓ±Lâ”Åg!äÓ±J›¬,YUîGpÕÖiÉì™pSÛPøF„ƒˆç¹A cÙg)ù°x×"O£Ñ%ÇjôºéÊCÈÞZÏGcõF³ªÜ@|Ò¯†ù?E¬ÑKž—^èè‚uV×õ¦Ê†Ðÿ…ˆèÓ=¦š5p&·6²)Xb›Bv¦4²öûF¤õZÈ–ãùqàF‘g=¯@¦î)}7| „æ?Å´ÂDyÁ0YåéZçs¥«‚¸Ö6;L•übÒŽW•æÄ£È&=é@âÕ 'KÎhðÒ ÄjtU󹊡Ç7°”£¤ÍQÒê8òǙٰu÷hC•g©Ð"Õ"§üª9~ñ iY¦JÄŠ½k‹ö·<†S9Ô-B:Yð{ ˆÉú9c^žgwÈñQ s³¹¨W‚‚Mi^—6ßl3„Ó[ŠõDú`éÛÂP¹ÉzøÖº9i]ŒrØÛRB/v¿%Ô[Ö·eÁ+Ǻ )}UyÐUóB3t¡í|éíEÊÑ(º<< @›#Pâ¹BÊa0'*‹'CK´RóEÙ}1±Ü›k&|oª=ÜíxÆÙ3Þ{š5M (têlÈ_¤ f„U‚µ[¤ÉsÄ¿?6ÙjÎ|Àfšªòˆô/u£÷4F>ÌÚñp(+{qj®T¼â¨§DÞ$.uã¬'1N7[q°æ…º„ˆA%>Nóì ªWÏEPºQW¡5X:]]^î_ÌðaWÖÍ•'àÖ.Óç³ñåÖÄççKPÞCµ B‡ùµL’J¸“2 ö\/ Ï8]×lÑ÷&ÃÏŠM~l*+Îyþy¿¾3uÄusŒ¶»Î¶[ãϰl"0|¥ ùÒÂØ¿ýiÚCà‚÷Èaa¥K„@ZÒ˜S« áThöHëõѤ#¤@›´Ö´°K]Po¡œÀ$ y&ÍûœXü(0†s (8B¦p‡ÜØfRŽ‚Òü‡^®àL®ëBŽˆìZcLã6ÃlfÌ*Úä”—ÀÛ~®cÝçJÓ²:әޣPèMèÂÒ)kv4">aðŽdÊ6úCUþþB‹åú_zÓи.ÕÆËQzÄ•Z3˜á¾7×ø„róííû۟ïnna5Ú F§,ÏÏ5Û´IÇÃÛ¼éÀvBéËl™^ðDCçgA‹ ç¥<âÀ·•0š®oï8s‹šÓw@†0)}Æ~Œì «‹€£:Âjo³bÜŽM0uü´mz`Ó‚á`ú¸1ë5¿ìL4Hs‘„“¦ á‚¶*½ÑY·½¥Ýõ í25á6 'rû"êàÇ×ðL‘v1Â>á/´æÒã´+{XºrÎ+ 0¾±ýÿ¡Àé~[ê´f:+çÇzg±Úæµ=) жÆË³¾‘7^¾Æ€B8|¶­ŸÓœBŽ&¦4mšŽÛ°…MœÉǦì“Ò„g¤ÄFw°Ö.gHÅ\q1=K×°S«UmÌ\¹íû©Cbò†[–±z1AGnìJ¨. 0pnÀ.(‹Œ>ZtUq׈ú¾àŒvÈÓ¬0qÖ§ÄŒ_ ©¾iÄ aòÕ/PsPõ蛲?½‡œö5‡óZWœd¾BÏ@ëIQ…3GùÈàÅ{Ÿ,Ì|¡˜Ô{°~ºY=5!¡¢ª:rn¾þšæí ”jo†Ô?‡|Ã!z$4†ô £Úø ~™™†qZ·y‰tcÙv¾×ÀøÌx¡ i¾™Áº"L,ÀǸmuÜŸÁ†nâµ}t9Ë–pã°%x·OÑ¢žŒYAH7‰[9Òͦ¬¶œkT«våhæ¡uåC{ïÉQ÷jƒ—é’÷iƒE<”?ïÑ$ÌSa2íŸ9Qí‹*lV:ç”Äo¯Öé.a`¸…ow—Èw™H[vŒ}Oº2i¯àýi{FQ> ãVµ=ú§°Õ«ª˜ nv±Äp%hxN?J°~hœ™Â0ðzzRìõÈÊ›f[e{yØ„6å ꛽¶gÍ«BÿÄÌaŠZÅ…¸ݹþ³­êžmqXnµEñh®ë˜7t¨×±$sžÉýÝÔ¹EÛUeº¦9wǾð¨Çµ¬¨¡ÚðŒºFÑ]æÈ+cWøíeþQè~DŽñR?P§t˜{'\)ýÁå¢ÉªÞU ÕI£,¦&ëõ×eºp?C… î(²öyíëÑJeû$E}H${j@PÓEçlÚ‹}Wzsj`óþ@ïësšðÀD¬Æv´XHf ÀÖ~ðÖ5y4òº÷»0.´ûÜGæRãljd6Ó-:(úE[{`ÒJ1 ûѵ`ÃÒƒUoÊ«¹F.€»pÅ4øØâz ZG7Çñ_ ¬¯z´BÛüû¯sL„Lá?zL1ï´;w…ÿ³Z[ endstream endobj 3510 0 obj << /Type /Page /Contents 3511 0 R /Resources 3509 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R >> endobj 3512 0 obj << /D [3510 0 R /XYZ 89 721 null] >> endobj 3513 0 obj << /D [3510 0 R /XYZ 90 690.045 null] >> endobj 3514 0 obj << /D [3510 0 R /XYZ 90 673.94 null] >> endobj 1190 0 obj << /D [3510 0 R /XYZ 90 258.937 null] >> endobj 3509 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3517 0 obj << /Length 1947 /Filter /FlateDecode >> stream xÚ¥XÝsÛ6÷_ÁéC‡¼‰€ßtî:£ÆvÚNÚäåút<”Il)R%)ë|þï·‹]Цâ:}"°X.~û‰„±1„ñêâÛÅÅó›Ð3b;œÀX¬X¡ˆláùÆ"5>š/¿›¿]\¿³fŽ/Ìжf~ Ìù•å ó?–t}sþÓËë+Z¾¹ž[RJsñáÝõ{ë—ÅÏo|§'ÛCÁ~;kÑ2réB0˜ç7RôÙgnäÚÒ‹™Ñ¥¿BüøgRÚ±Ï(#k&!Ì»2K­Y£+u·Puó2Oêúò2iš*[u»NVMYݾ¸S8üç")6åååX´h×wì a;ôxÓèߎÃÈè‘¿¡½¾ñ·yV7 UjΙëGvè(cFùÇ” RX3WÀªmÛ“ë’×¼¿9¦'´RH;1¡õÆhC£G”’ÿ‹>…:Òà$ÍòÕú˜Þ¢FE²S_¡J/H')BÛ†0,‡a±?ÔªºRëä7,ómUîip»‡é‹I]–tb³kvM–*׸^%u+ˆ>ô$˜ÜÛƒ;–îõ¤Ï¾AÉ)ÁÔ[©ªÉTÛœv?/ÊïDi·ÛûC½½]&«ßZÃ{9èdëùsí÷zqñû…„¡0$¦ªïB˜I×Xí.>þ"Œè ÒãÐ8j®áÆ‘í LºÜxñoJùAZJáÙ1‰/;ˆèë¬P”Õ’>—\‚›·L^—ÕÑBR¥*%¹Ár„ ® Ò ó†Y±UUÖðl]•;®Íÿdüw€¼™?€ô¦Èïùﲨ›ê€i͈ †–ªáÂN5Û2e,IÅ’+õû!«@Ïî/ÏXdBýrù+ÖŸw[U*iF{öpf*½mæ­"kmu\"ÜYŽo&ù¡s š§9J§Ùhª> á*}ÄÒÿ²Øh÷IÒWSŽÀcz±)×S‚&€}_càš«¤F!G¿EU•¶2f¢€0† kcÈÀ†6Ùª¤ÉJ–I¿î×MR¬-í²ºÎŠ -ÝÞVeÙ@iµ¤Ù‰KGò’BˆÊ-eå@·$W†ÚŠ®ŒÌ¢lˆÐÆ—¦.õÄÁŠ0-6%­ÿ†:«ª@ßã²N\ ±úÇJvü;ï™wY-s¦jí{ÛD¦²¤oþ·É KÖÖ-«<ÅB:,È öšv¤v[,ÙG1$Æú]¦­‹ %ÑÛlµñŽý kcÄ|Yl꡸ŒçpF¤9=÷#‘ÐçãÓ6Ab’ƒéÓ{¢ÞX¡Iëûæ‡×V úêæ€øŠєکj’,§ŒˆN1ë‡PöeÕ™r' N[2Há\«oXæ<І¦4ú íÌu]Ê`âŒÑb5×ð¯È:8ž=ñ «ÇR’CSî F¯’¼m–jpþÚtA ¡“òl× l…²ëÚÃ3\; ÓÝ-fs•õlD†Ãl—l`ï‡7ã8¶pT¿/wÚ|ŽYî›l—ýO+Ó® ñ¤¹åd†ÊÉÜKEöwÌ#tNM;!÷wÂèw †i+¥9ž­òL ýÁ1ã@`U´-ÿqàC EœLDNÃKGÆu±*ÉIpФI“Ðjs¿WUqdε“"íÞšî “‘!"ÑB3V½Ìu¥‹ô•§m¿‰Cp}‹ƒAÍû¨'»šŸñb ‘L!žÚ6”Ìqy_Ƨ[¥t¢¹lÊËA+o@—í¹l áâð¶ŸÇr}œù¢ÅÝö²½ k[j^jÛßݾRuݦ¥Ì} Ð?¼½~Õ–ã^«ÈaÌ2NV²ô¨°©Zq5˜Wµm ÌîV[™®ÃY‡ÿ@3ñªÓgSé¶¢àIÎão‘Éà1dÁ“‘­Ê|`̳XZ3}±Y®T·ù_óÛ¤ÞŸóèèêT©æ b:PøQÙøêï¨.¡†°Áež¬€d]øvX*S"p%C¾¤ý³KœCÀAA,ÃÁUmê(Œqü’Ö¸ðîÕ·D:i ªMä;Ý”\l)ò¼Äºy¤Š $ö/Œê"Ûï•¶(Ìè– ê­“´*¼¤;eønIMÚê î !Ó°º"gI_}Bê–›·”&ºÆàöŒ©T¸m߃3“ooŠÑé>‰ó,UÏú‡u=ª€Ý«w1<‰›*ö^#޽"å¼Ü×ÿÊÓ‹ô¥~”|ÂÓËX¤~оyJ¼õ‰Ð®èÞ`ùÕŽÑӃݕÂìò’ŸÝhzë}Q1u®9Ÿ{ztuO|öMÊãeÞj`^mZ\üu¯6“/^þá¼<é½Ë‹l×—Çæÿïÿ endstream endobj 3516 0 obj << /Type /Page /Contents 3517 0 R /Resources 3515 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R >> endobj 3518 0 obj << /D [3516 0 R /XYZ 89 721 null] >> endobj 1194 0 obj << /D [3516 0 R /XYZ 90 367.34 null] >> endobj 3515 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3521 0 obj << /Length 2286 /Filter /FlateDecode >> stream xÚµXÝoܸ÷_!äÁÐYõ-9èƒ/q®9´½k²éK´Äõª§¤Ï-ú¿w¾¨]­åK ´ÖÉápfø›¡”sï(燋ï7ß½M#'÷ò$HœÍÖÉ•“ªÌSQìlJç“ûú×?onÞ¯ÖA¬ÜÔ[­ãD¹×oV‘rÿºòÃØ½þóë›7<üöæzåû¾»ùøþæÃêóæÇïÞÆÁ‰ìÇ ìL¢ý,ÄIJ”qÖaz¾8ë …E!O{ײôqg˜(ºR¨nËícw虂‘ v¿V…yɌà sµˆ1-¬¯Ú{î5fÜuå\Ú´Ñ N5åõ8öÕÝ*a£U¡ÖÃ0SÞ¶7›‹/>ÊñјIœyI9Esñé³rJàÿè(/ÍSçf5N˜g^¬Ð,µóáâ/OD’“|ujIß¼\¥NÄ^‹9WëD)÷kW•LýéñAK\]õF—·rš[ ǹ­}oþ¦bµÑí}wuÅg¤óáÒK˜£>tXû¾—ÇOùçÒX¸Z‡8èÁßÒx$ãß›{й.QìÓe¢GÂgø×äÂ8Š<•'ÿ Ée³Ø÷x,Šœ8¼$MY?V-T»ÑÕjFïðøÈЦ@…;E±»ÙÉÔ¡ú‡P°0s´C•] äÀ-X‰»Ç‰A#÷F;æí«_W~ìšz¾–â…ÉÃÀWvËD^5'ª¡‘×>Ÿqfê“û–Äî—ƒ®«ñ‘;´´%xL-í•$îØ1;V2­åVs3º6L’`…L\sã+Š…qâNÁ4ßíľ«ÚÑôÂíf£¸zå»lPè•“ /»r!¶H"O;T÷|(DŒî§µd'‰˜C,„¾r?˜ñ ¾"¸a„?Xú)RYÇá¨@rx–iêQh!yuWW³eµ? ì ðÍO­ÆS¾ûh,/KæÇüé š×•iå CUZÜ^@{rßéж«ëMò0}¨@‡ƒˆ4Ø¿f?VlÝè¼ÚÀ®öHß„€(½(ÌþO(…Ńè74q†ö3Ø.õ"H†²f–ϦE4¯žÁjZU¡wpâCUŽ»—;SÝï–WIJâù¸ #Ÿ£Þ½8Ű÷ÒH’ûïh$ör€Ä6¥ƒW*~îűà û§²©yçß‹UÈT%AmÏŽòâiJ|ñlÊÈD8fšÒPæš’Öe©_^²y.Ù>//íàrÞÊ¿áf ÍÏHùÚXO}úÌí‰uΗù²LÄ~3°ƒÜ‡’ì“Ú‚$÷’ÐgM(]…~zŽIÈjuƒÁäS0ï:¶è4+ÛÌ­'©ÅBÓn²°’}4[œÒb¦2–†¹…&œpSÊmÏg44?¸/̦Tä¶ë=bÞQ‰äjàÚ„ ¤ä t/¬aìzÊ!+‚íh—²É¶o[JQÀã¬#+(ÏàDQæ…Å‹sÓt½LÑ€—…ž$ÀÊ¥üeáÕ*OeõiѬ[ë)ees„îÍxè§Ôgâ$xxFÓ<'ËW§™Ta¢ £$À(-CÀ0’»îÑQ…ˆñxÇE<˜ËÇd ÿŒ¼ 0'L‚é­p,;l¦àE6Õ]·_Hy  TqA"U܇²^Õ˜RW@Ý0rþ.ºCMñç»w†[Ø|{¨kG» ó¡¯Fç‡ r^k™½ï»Â wø…CõZ+;ít[Ö䜀Zce–î[œÖ‰ÈªFÝÒËÕw•HÜ þ2KÁPг)ÈèAâ JæT2¢yàøòb6˜™•ì¹?'?ìL/ó8*€øéý÷™0!/Bi*ô@Æt¿!HžëЙø=¯²áÌVŒ’¡J%‘€zJ›ûCÃá­o+ 9%õ‘"aw{h ¾ðسÏÚ8vQ¥Ì•žÎ,;#‚$´°V+LuŒOÑå]KŠAÛÅxˆ¥ÛŒšF‰{×uµÑ-–~yæ¾Û2W²X”Úqf3†ûå»TÊäB öO¡ûÇl ~?ò·Üw³,%}"¥@l"ê¡¢Œû>ý78o¶ endstream endobj 3520 0 obj << /Type /Page /Contents 3521 0 R /Resources 3519 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R >> endobj 3522 0 obj << /D [3520 0 R /XYZ 89 721 null] >> endobj 1198 0 obj << /D [3520 0 R /XYZ 90 227.963 null] >> endobj 3519 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3525 0 obj << /Length 1200 /Filter /FlateDecode >> stream xÚ­V[oÛ6~÷¯úd CR¢.iZ Ë¥k†6U÷’†,3¶0YtE*AVô¿\Ka‚¨C¼ï|çJboíaïÝì÷|v|•D^†²˜Æ^~çeØKpŠpļ|åÝÌÏÿ8û˜_^ûexž ?`1žŸ]øžÿå“ÍÏþ<¿¼°ÛW—g>!dž¹¾üìßæޝ=ÀŽ 0‹µæš¤‘94Ã@fú½Ìg_gD±G ¯8ŧÔ+·³›[ì­ôú£$K¼‡þÔÖ ³1l4ÔÞçÙ§'½½’"Q¤!˜³‘8j†˜–AWP? ãùRˆÚb=Ú>.ø=oÔ¢b÷7fXÿ¢!ˆ~smF~ânËÕk×IæZŒA\Š-_Èšó]Õ¬ªÚòÑ+¶b‰ +,MÀ2yc?›¢YÕ|±î*k°tCJÖ/ eI:Þ!ø‡‚®m^¶–ðÚwB2ƒ§«,ØUcØîŠv]•›¢íåILP¨Ã”D¡ù­ß1ôï`Y ÞßÜîC8AaB'¢—BMØŸÍZœœ|QUmi1]ˆ=hJ#õ–Õú5è'blªHÕ>:$°ÿÍéTQªw­³Þ7•ªŠº’ÜÎÕ+~_•0–¼½ç­S[¶Ç ~òç¬< 0j=JË/žœTšª t_«gó“ºË›î•o%W‹¨ë¾”6-/VRÏE½Õ¿}]±çÑC—gi4ñì¹U?áU;Ö{UºÔ°;ÜP!çãaúh Yˆ2ÌþÏ£¡$Œ.G(Óý—$šJšZ*¹I Q]´>es[¸fnüç67Åkææ²#{°ß3·‘YêSHÂy%qØ*†#UȦÌwÉïD kj Q¦Òû%1Ù² ò¯ÃØG®6b…ŒsÓÞ2{ÃX³Ga¿ëšRU¢±O¾Nò•Ò~GÖ3<¨GœXéÂÇ´—\=pxÆV8F·sš„}S&:ª £˜šØè CS¸¤Ô?LŠ\pÃâb™ùÿã=»ÎtV;4¤j>6fU¨bYHîxÌj½”"'Vï•Ñ%ZÊqF„>7BÙbYô°¯b)G 繟O¬áÌžV?뻞€(î&²æ%bÝH—¦¡]o¼!ÚìF« œl‘¼ìÚJ9úF‘Âd9‚«q¨wBÊj9xµWk¡Šj–Û#Q5RéVg'½m&<ö£Õ×ã8™Ööä›À>çD€÷U±W=äãA´Æìê0º Ä(Žbí \XÒoNÉ7Å–¿…R A-•b»Ýç7”¹1sg lyß t[JmèÑsÍï?è"l endstream endobj 3524 0 obj << /Type /Page /Contents 3525 0 R /Resources 3523 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R >> endobj 3526 0 obj << /D [3524 0 R /XYZ 89 721 null] >> endobj 1202 0 obj << /D [3524 0 R /XYZ 90 142.184 null] >> endobj 3523 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3531 0 obj << /Length 2177 /Filter /FlateDecode >> stream xÚí]Û6ò=¿Â2+¢¾µ¸Øn6½-pI±q{IQÐ6wW¨,"=߯¿ÎPµÚ´HSÜÃÝ“†ãáÌp¾IG‹ûE´øþÅwë¯Þé¢ «<Îë»E-Ѝ £4[¬w‹ÁÕß/\_ß.WqE¸\ey\¾^¦QðóR$Ypùöêú5ýüæúr)„Ö?Ý^¿_þ²þáÕ›,ñN‘q–ƒdËZ”½ˆX÷]¬’J„¹(«¸€Í ‘ŒcŸ~ña•EQð½2¦nï_’šV´íŽ€jÔ½m¤Öúî zS+í³Ž+ŠÇÙ×–½SË8 >Õ[õ_R`txiL_o–qÍT'ÿ«íñ»:"y˜&¥oÙ#qY §Q(ª,‚£&9€7Špú ¶õÇ(Љ¨ nøÇºÕFIþ¡»#$o-ƒõ²ÄsÜw„ßI#7R+HŠ4N‚µ“pfXµ&œli}ùþêææ)w]Óth‘GÍ¿Ø3£ùEXe|ÚGÕ4«B­=FQúÔù/‚kó@СWºß–" ÔRdÁéÁ®ßi8AR¥|äUïÒ†¹!™<ÑÂàá‹*¸W­ê¥á Æíð]× ™«³ü–Ö#×ÏœQ«þj©IU‘%ák€ïQ£˜ÊÉ̵åg7FM½•¦îZtRVïÿôÃ7ZˆE1ŒÀ-r‹Ih¿°$}¯ÌswÝö¸Wà‰‘L2kåÇÒrüøçk;fÞµÍiÎ0ppÎ$«æ™éz5ŸNÛ®E‹ß{«'”ìå^ÕkNÔÚð׆F3k'Lüa­2R¿1ŸíV •Ö ¥åÇ(‹Ðsãrq¹zwûÝ; f@ܼ»bâ*&vô‹t¹B?QŽ%c¯ª`ŒVm”´ôÎë‡*ÁŽH6'fLË)©©°ªN<Êñd¨-3.µ•&-‡ˆ@·¤Upꎄo•U%儯6²7Öüµ§…]’–ù^‰@T×›—RÁËØ53¢Ì²ÀúQªÁ®c»S}sª—"°G:ˆÖò3ÇÜ‚ÃÔŽƒd4Äy—ÂͪÝýh½\·ffŠHаLKGÜÔ\О›$B`쵊ýÉsÄâþ„¾‘íVýÚBŒrE¾ûæ•Ù^ýãô~Øó¦n œ•µŠZÌ}Ý.Ìöpqñ746§Åq¿Qý·Ô¼â4LDåwSëÔ¤œ ¸¥'È‹6$:+ŸeVî(ç3CÍçèmßÀN qÛ¶M­Zí§ 82’ÒÕÀmxã¾Û›i‚ ”¾ÐU@Á™@ÑI”½º³©ˆ°U¶kW窈˜£–÷¶Áæ•­Ýèea«5mlѶÄWá´r{Ù(Ù·ÊMwdᣢŒË±­JÖ€QƒE]Š(x«Î•¿ý¡[b1MDÎé?wôW_Ç–wJšc?L;#Ö­áºsqÙ´ÞÛ§ýn°Q~鎂 ß*sóÓsÝ[fº}P[.êæA±(=dÍ´%LSÍY ?¶í0šG ¿hþuúMåvý³ã¤ljÉZ sÃ/to0Î h)Ô¿‹„j$`ô82dCHO½bÜ24œí ›xE⦪ØÙ· ¶E÷¥7vašX)'+B²=BÁ=¬ “èI¨ÕDmÕÇ-CÈ4?leÓCÛ:MƒêI³Ç‚R½.`˜‚:—æ1l¬yUT@1N»;Ú@Ìx|ÏA:æÄ0¹FÒÇÔÜO`$Û4ü ±Ê0t 1®[„©ï˜Jï²¾-ï Áøk;l F6Ów ër‚ jÎÍŒï6CÝQCÄçYÀ&ëg<8®ø€ý¼C³sè kȽ’­¦š®Óƒ‹'‚\¹†R¾/Ò=ëX¿¼K× þ«ùì-æS-§ï_VËT¯ïò<Ç·\®y›ÓÔT“aìÏz¯ö]_ÿÛÉò:—þªæœiŠŸ·ðpÞó“ÇŸÑçKÃï<œ»ÀÝ…2WŸáz.)ˆ>—”ÿÏ_q87ýq`¸Ë{sÛ@@ÒÇ+Ãñ¤ Çã2<Ús¾/')ÙÊÍç‘@T"ŒòáÕyÕv»ÍÌä—¡€Kiäšê~oïÈ(¦©[Eßm- Vã±B&@Ûà#y’ïÜ&¨OÐ4÷l°G,&æ}|°³£€ú¨š¤ ý—11š`Á¯a‘÷º$øu‰_qà{ G`€|î”d8ûh<üMÌûéž'wÒ4I‚┊3 {èÏåÙÑmçNÿ¡«ÏδÿÄüz'·¦ëO˜r6ãžú6O´*Ü®½‚lÇ“Äy3’Àäv?ðóE‘ZëáPåŽzRsÆQgàm|¯5h \¢í`ØIf¶>®¢°,‹Én7p®¹±È}¯×/þ~_ endstream endobj 3530 0 obj << /Type /Page /Contents 3531 0 R /Resources 3529 0 R /MediaBox [0 0 612 792] /Parent 3508 0 R /Annots [ 3527 0 R 3528 0 R ] >> endobj 3527 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [258.552 575.474 270.508 584.222] /A << /S /GoTo /D (cite.Jive\040doc) >> >> endobj 3528 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [243.496 473.691 259.605 484.595] /A << /S /GoTo /D (section.C.1) >> >> endobj 3532 0 obj << /D [3530 0 R /XYZ 89 721 null] >> endobj 1206 0 obj << /D [3530 0 R /XYZ 90 375.31 null] >> endobj 3533 0 obj << /D [3530 0 R /XYZ 90 99.993 null] >> endobj 3529 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3537 0 obj << /Length 2235 /Filter /FlateDecode >> stream xÚ½XëoÛFÿî¿‚è °è}ð©K¸ŽÓöpIÚXwýÆJ\[¼P¤J®ìEÿ÷›ÙERt›¦Á}°µ;ÜÇog†x÷ñ¾=ûfyvñ2 ½,Èb{Ë;/#^BÒ€„‘·Ì½wþÕw—?,¯ßÎæ,"~ÌæQLü˳øÿ™Qù—¯¯®_˜Ï/¯/g”Rùï·×7³Ÿ—ÿ¼x±ïG1œ¬YÓ4ÆEgÄ ã~½9Ï¢ &Ü›³6s³œƒÕÞ»yD@g‡‘¯6Ò r9c‘ÿP¬í|'”’Me&ÅvWÊ­¬”˜Q_µ%—fÏŒF¾,³9'©ÿ}5b¼.EÛâ0ô‹j#›BÉÜ|¹kêíhñr–_T÷õbñ¢èÊqpÌà>eA…ÞœÒ ‹¬Ò a4jøÁ ‘ó\¾'„U…ˆõùµ‹eYš‘]ªåƒéVªMmÇkQ–@7Æá=ã00NFBgP#5RßVb+oïÄZÕÍá=‰üÑ ëÎçAJ)\%âÌZí{”1å~UWx•”©wk¥>Î(\Ç|ßÕm[¬Š.*[ó½°¿ûÌ&ós˜eÔ*·£¢Íp]7ö­aÇ ¯˜v²äòOûR¹…=ïA±Å4“»º1)ÖmΫZ™Á¾í¶*'Ó1pö¸‘ÕqÁ©-yD~D ÏxDx†’!®ö°Â∖zø4Ê|”"€–C>2ÿ{Æ¢©DâFÉÝN6¯jU[·êw­Zä”^lqù=ïM˜¶t„q6Œô:,pêÉ#µõÆ09ˆühh=[vK÷ж9}&ßý„Œw¯AÿVö‰Â b‘[lÁÐq&ÉC6Ðû‰å#èì! 8ýk¶úVýuõ„ÅžÔ|”4Šþ𹳡ÿ¤CѹÊ)÷Y~$fa ºÛ?£Æ*£¨FÜ7–Ë€Ñ8 &ûzyöË…!dX„œà¦Þz{öîgâå@‡Ç’Ä{Ô«¶ÏÒ "(néÝœýxÂR:”ô/Hi oŠ"%LMèÆÀÃêî“ ñ‹\N*òAâðY«€Ñçf÷ß/œ†=–iš’Ùzb9$Zȹ»}»¹]‰õ<ì«¶¹X‹‡¹ÚWBõ+<ãS9iø‰,Ø +EdEü퓬Å!½LP>ÃZÚJ/¤Ä@8GP‰ÿO°Ð~4øL0aÜ=ŸCO¡1”l<ý4Ž'Y²)– ïc~5zO¡0'A[&Ù—QYÿí™2ÖÍ_ƒèòðI`=)θ$Ádä´0a¶0¹ª« @¡KŒ×e!]6©êé:¥¡â‹–2T¿`ǃ3¬ïtAÊ À3Å c[ômS£¹p~@‘d²a$éR(›*dËÍn³ð¡o&ünMüf_UZcH]½æŒX线ËMˆ*žéîƒ[;lSÆïÞ¸ÓPŠ)ÄF—)uYý²`xL‘ÎÇUoÝyûÔ!”7]ômH»½ M*Ü#û±?½êêfç‘«ÃiL•mØŠ #›ï„ce,Pê ­þ¿åèÙ_Wµ©®(D"çñ0Qº‘VhTåÅG}ªy°š{Ï ÞjÔÂUWƒ’c“M‰¢tP´êâ­_¹#Ò¬þ Ði <»×ß¡ZŠ ˜`6†±,Há©t`Â-”¼Ú—ªèšÃöÄÚ'qd9ËXO²u])ؘúµ½Q{h•ÜNãT‹mJÑ»!§Úʺ•ù¯7?þË…%%ÕT TkÑTºv™XÃÛØšoÊòµ8tÂDwGõ&3owr]`º6ó¾x¸¹tð7í+œ sæ(ÜQøs¬! HĆ€|©Yì졚xjt$s3>p ´óÇÂðH}±WõV¨yìb@0L"4¿Ú.3Ó.E@ÚÐVðUÛª/Ä}Ñ3ùf“N\}gEßX!154¯‰Eä¾_´¼O—¯ÿF %Ú endstream endobj 3536 0 obj << /Type /Page /Contents 3537 0 R /Resources 3535 0 R /MediaBox [0 0 612 792] /Parent 3540 0 R /Annots [ 3534 0 R ] >> endobj 3534 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [159.838 179.676 175.947 190.58] /A << /S /GoTo /D (section.C.1) >> >> endobj 3538 0 obj << /D [3536 0 R /XYZ 89 721 null] >> endobj 3539 0 obj << /D [3536 0 R /XYZ 90 690.045 null] >> endobj 1210 0 obj << /D [3536 0 R /XYZ 90 611.523 null] >> endobj 1214 0 obj << /D [3536 0 R /XYZ 90 258.642 null] >> endobj 1218 0 obj << /D [3536 0 R /XYZ 90 165.708 null] >> endobj 3535 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3543 0 obj << /Length 2254 /Filter /FlateDecode >> stream xÚË’Û6òî¯P͉rhðMæ6‰Ç‰÷¤¼JR[ñ–‹¢ ‰e©%©(úûíF7H€¢dÇ—ØúýĈÅ~!?¾ú~ýêÍ»$\dnûñb½[db‘ˆÔa´Xo:?üôôëúùÃråGÂIÜå*Š…óôv ç÷¥DÎÓÏ?<¿¥íwÏOKÏóœõožÿ½üïú_oÞE¾;DÄQ ”j/MðÐ+ÁÌ'bá…nÆ>_éó+?ÝJ\/\®H"¼^f¾“×û†>‹¦îÛ¥—:MUÉ-Áò¢]GëîÒõò…D’ž›E‘")€VèúQ6Òr=¦ö['[ºß–ûCϸ¶ò£~]öeSψ ½ÔSÂ÷ª­ìe —SáôJ€4¶„/ e4ó©fø?RçÒœº/—~äüµô"‡Ñ Œ!nÆ•ÓÏ ¹", O wÊÎâE8uþ«fGG†­ßR«-o2ªÙ¯J¥%´Ò)IÝk3ÍËñÔk-ž²åáD~w2iWùÒ£_šxMò®kŠ2ï:Òfh{Ψ¬ÁCŽú~4gÆ?Ú²—×þ"ózŒ€CÞó-h9Ê 'ò'ÙõS/† ÉYK:„ØA^Ѭz÷ø sÀÄ#ÿ¸øÇâWM]]hÕµUU~FíÊëûе0ùGÀG‰3*íSÞ÷m¹A§ƒìY2€,I;ˆÜÞV.‘ºaœÙ®–£A/p:ÙÛ7>‹`´ìi¿–ì íg v´$fa±kÚM¹ÝJ¸y˜r³Ìyþ[EDqêIxBÌ‹/9D.Äs˜R£¬ºf‚“>%bû{e%ܘd)äÕœ¼ƒ HÔÛŽÀFøãfÎà‡¡$ŽÌ <’—ì'4ÖW¼×¥/…Jž¥úæh!N|çGÙcŽ" mÍјÀÜõy/iK‹€ szêè¾æ^äf~j›•ùûTÖ”Á3 Š4áÒ—‚Ž•Lø'¿t´g¸Úr¥ 8n•|¡B™èB™N‚ ‰ú7 o›Z29f®‰¬æj©.q‰ST9åˆØ©äØT˜¤ÕµÌñýŒN±¡éŽmdÕÔ{Î1 WÙX§…Äé¨P$—è,|>¬& ß¼<É:‰å0Sá ôÜ™”NR¶Ù~™=P=iÆŠn7c?rÅg4»Sʵƒ¤ïuš,ë™üoi¼ûæ¾àIQLGušŽA…ïÀ¦ðõè®…ÐAL7wmóBðó¡,´Dtl-&‘úH¡¼]æíÇÙ“-8£”UkðËÕ“ c[=[Ì7ÊvÝQåîÂI›Ìh$<‚°ÅQCøÎûmò©P—·!sÊŽ–¤#«ŽèX#¸,ùtÝôtxH…7#ô2¾ž>ã¯<¦ºòÁŠ”…©NDÄ:Ö¤…Å@˜Z)/"©0òú€å¢l²þq¡Œ 32Ÿ#\‡®›ÝäuIH»¤ÕL1¡0DHâÂ/öþ˜!›¿ï ¤˜†_®V°:6]Wn*¾Ò+h mÏÀï²¥o•=#|ÿ+#Þn[Ò,’÷м¦ÅêÊùN%ø—:crIñ¡¤œKȾEÞbH8$z 2…fŠ€ØŽ¨š¬¦ `Ò‹…ë‰À"¯éüØË%ÂèÍa‡ã^ÑV-<}Ì‚:Øö¯pxFœ‘:· 8ý¢º.L` 3üþÚ¹±;MÛ£­|µ"ÚèýÛI-Óê‚…5œÁ7VíÜ!ö1ŽJp™iWº7$8øRµ~uzË̦•ß¡ tfÈøA0.¬Zmò+…Î@a8o­¶x6µžÅ3 ŠÐV¯†nÝŒ½Ì¨3ÓQ–Çq,:C“¬Î5/eýf¤üæõÝÒi4f¼3ýh—Ø6ÆüÁ÷vÖå°§Ši7ŒöµU„‹ª”u?Œôÿ`ž¿7Q%÷l5m¶Ç^@iõÞ¬ýõHu̓J‡ë·LQªh“r`O븥j…?d6€LklR­ð]Q|.¼ˆ© ҆¨†5¨Óု?$^,0¡oµ[Ý xäŽÍ‹7©‡¸5n†Ñµ#LÝrúZg¤#ò+,F„0ʰȸ£N”raƒôæ ­ Yzó´áNS[g=r†G’ª+OpÌt“a¢Êù„¡C„êIØã¶÷–>!áåÕ mŽjFšÙE맃áŠýò`DzB¼m‹¯ðn‹!ïÀÔ;û™xÖÉê<ÿŠò=l2û ýgLW½³ŒñäŽ5ÿª•µà4¬ì†3o€úugZ&ñM¸Õ" µÛðÓA;–R7ŽSõ"$,ÅkûD¦Ú}מÁx¡æT…¥¢Æ*Wç¶,MqàñH—õC0Ühè䆿Éft?R-•FÁ¸âÛ¸ÆRˆÀ#ž¼‘äªÏ¾RϽËN<ž´´‚b$üäëôø\urz$Œ±Ý¡ŽÅɽ ™ù·ƒfÒðyã)t03þ3*ôñ:§‡H˫⸩ݗ•t“öÈû@ˆ/\=Á~W´{Q¾ ðÿM‰2l”xßæ×VþÆS#/tÆ|ÄY¿,ï‚øãSj`u °Ã…l˜œ}û 7‚oø{ >„êàã§Ç/ಃo†ƒ™ˆ»]dh¢ý²ØÎhjUÿ>¯_ýÊ‹|0 endstream endobj 3542 0 obj << /Type /Page /Contents 3543 0 R /Resources 3541 0 R /MediaBox [0 0 612 792] /Parent 3540 0 R >> endobj 3544 0 obj << /D [3542 0 R /XYZ 89 721 null] >> endobj 1222 0 obj << /D [3542 0 R /XYZ 90 690.045 null] >> endobj 1226 0 obj << /D [3542 0 R /XYZ 90 666.859 null] >> endobj 3545 0 obj << /D [3542 0 R /XYZ 90 619.412 null] >> endobj 3546 0 obj << /D [3542 0 R /XYZ 90 599.731 null] >> endobj 3547 0 obj << /D [3542 0 R /XYZ 90 430.569 null] >> endobj 3548 0 obj << /D [3542 0 R /XYZ 90 351.111 null] >> endobj 3541 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3553 0 obj << /Length 1206 /Filter /FlateDecode >> stream xÚµWKsÛ6¾ûWp|"3! ð%²75–û8t2®ÒìL‡¡ ‰SŠP *Šþ}Ø2íi¸X,vß¾ æìæütóãúæîa;y§aꬷNΜË'Îzã<¹~^~\¯=?L˜»TÁ®5æ]Á…º¨NPâ«6nî ÛVæ.:àŘ$:F,îßÑMF$Áß'¡:âŽÓWáùÏ4ø@¶¿°Í¥€§Ž¢¬4®%ò)D°ƒâ+‰Èæ9ìèD’$½Õµ\ªúb²×ìÓD˜U5߾ݘJïÕë—ÍDýLý§ýkKcª<U¹a„Ô…`‡º-P'…ÝHŠbˆÍ¤hvùK-õ‰Æs¸ÓêY¡‰Gý0ry~õTr¿B‰©õÈ}AÎ(y vmq WÍÛªz£L^|QŽéª¿ ­éîZU§Ä~‹»ç(g=Ršk"6Vbkή†é5sr<´Úaèmhà È!Íš>Vgòa¸¿‡# ù½Ååêÿ€ ‘}³÷§¡«³ÿlVë›â‡{ endstream endobj 3552 0 obj << /Type /Page /Contents 3553 0 R /Resources 3551 0 R /MediaBox [0 0 612 792] /Parent 3540 0 R /Annots [ 3549 0 R ] >> endobj 3549 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [334.862 430.797 346.818 439.763] /A << /S /GoTo /D (cite.Astor_doc) >> >> endobj 3554 0 obj << /D [3552 0 R /XYZ 89 721 null] >> endobj 3551 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3557 0 obj << /Length 588 /Filter /FlateDecode >> stream xÚmTMs›0½ó+4œÄL  lŽ4¶›ôÐi]Ú:=( ÛLùH%œÔÿ>’V88ÉÁøi÷i÷íLj "è“÷±ô¢í2Ey˜gq†Ê=Ê Z’UHR†ÊýÆ7·Å×r³ 1#x –\¬ƒ”àŸM.¾ÜlÖàÞnŠ€RŠË»Í÷àOù9Ú²x;5Y¦3ÛÐt•’Gœ˜×ÿ›Òûç%l©±4G4NM©—¡ªó¢».IÐzð¾AW¹(IÃ> endobj 3550 0 obj << /Type /XObject /Subtype /Image /Width 357 /Height 549 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 13483 /Filter /FlateDecode >> stream xÚí ˜Õèùîlܘ»×Ýøe'{î, Êc‚Mxè* (4ïQÐ8h 4JãÛWœ¸â5ÑÁW&ºè$âŠhÔ£F3¾’QŸLÇWóœûï.h›®ªÓ§ª»gzf~¿ïÿõW}ªÎéêª:¿>§ºêÔã?¾sçÎ7Þxc̘1‹-š<´ADR´ÉE#úHâ®G7=qeøÉUA"Ñ‚ÈA1nܸ®]»Êô_ªüì÷kf7VOݵî\‚ ‰ï™(N3¼õË‘+V¬W|òؒƇü»~sÞûkGá4–Mè™fä~i®¯øøãÏÔ³ñ¿¿w÷”¿Ýî%Âi,WøÜ¯—õâ:×!Ù¥Ü/íg}Oúð‘Eﯟùömg%Æ‹· ¿üjÏ¢Uýn¿ì7œ6yV¯~lÙšI˯9cåš³oúåØëÖœ5pÔ¿>yÕÀ¤ŒÑÙbÉØîM[×îº{‚ëìRHî—&ºØY³àͪQõ· KŒ?®9cÒì>k‡T­³ìºÁÓf¿Ý°å³=Ï}ùåó_}ýÚ×_ü©éóÍCÆüÇïWx’20Œ³åöë/ÓíÓ?Þþ·µc\‡d—Br¿´ÞÝOxïáù¯ÝX–[n:ká/¦^¾jÈŒù…þ%E—Î÷ìxåÑ—6jÒ€éþ¡K¯*»°¢wß¡ÇÔ.ïoΫ-6¸+-ƒ±ûé*cMv?}[›¯Œ]üåÖmYùäƒö~ûíÁ_~öå{/¥S`šßÈ.?=v³¾m>ðæÚ‰ñÄ7ïœ$)9²ÇÓ…çœ(GKým#]‡d—B¥­œÜKNK{xÑ@sF#Ef)J]4<8÷•5C’â÷+ú—M<~ÊÌžSf4sñÉW¯õòŸkÏ™|üUóÝ|ÍøÙ NÿùŽK‡ÿëcSÍy5CŽ.‰ø‘×f"NßûùÎo Íï½û·[.>µMWÆ:^»ÕûÍÇoÛ¼ã=×\4ºÿÙ?ë3gÆÔ·lž>â×eÆ÷BšÙ¯˜Pl9ëÀ¿½ÿ×Ϭh$~º£F$—æ‡æNTŽêºónyùÆ3]‡d—B¥-›ÐÓîVf¹.-ž×œbYšèâûçl¿v`Rl¼jÀ9ç÷2ê§eçœPyåàëo¹ýÕGFN>銣®-ž3Êu7Tœæ-øÝâbs^͸úü9º4‰Çî Å~îÿêóO_ÞðòMg ‹½ûøê½{>øö`säÓwߪž/J¾Ñ¾p£’þîcAcáCs¯¼ë™µ±¹Íûþþ‘LKŠÝ*½}ÿ<ɸuóÆgžÚ(Wø~ÿ¼þñ¹ïÕ^ûõGÑzºÿ‹OÞûÃõ©Ò}°é¶½M»d­öýýã]›ÿSRŒYoU_öÕ‡¯Ü‘¶Áß^|ûùêô¤øøOʺÝwGhpq·#{-šP¼`BѬ‘½G,¼©¢Tñ}í¶aÒá—¸ðÎ'o–•—ý¡Þ’‰;1imY?òðÞ½‘‹Ç zîꟽú‹sä >¿ñ¡¤\;Ÿú…›]o“+ÅQa¿w,¾xª˜7² á7¾pí®C²K!ŠÒín§ ™•Ni2ôVQšèB6þ‹ÁI!͆sÎ/Ï;àœ¡ý_Úút¼L£@™~þñ{|gô}àÞ»dzóƒ¿x~•õÊìyë9YÀ_q^`ö2ñÇÍÿ3olŸb ¿·ñ¦èAûê/;P>eÃC÷ÞRQ¬HßùT´SóÚs&í{÷Úè!½iýFQû¾øTÞÞ¸ü²³ôžsñy¯¾øì¯/+U¤'Eì0nsæÀ󇟲dbIõÜ~²‰j¯8íæŠÒ[*JßW± “Úxñ”G¾ÿ36r@E'¥,9¾ÍûwÒèaÒ`«¾ç¿n›^²ûùêƒö18ý]¯È¥>*{ÇüÅS×ø÷·[óìU]‡d—B¥-}¢¬•¼&…‘è´´xI˜‹J*MtQ¯ëUý“bC tÄÄ®Sgœ2­âä«‚#®^uæ¿üô‡÷W_~ãêQë×ÎrÆqS¦þlÈè®ÌïmÎë(#¥rlïù¾¢+&–Hz¸iÏÔa'?»âÐbRG|Cz®š}ûí·ß?µû†Eý"{vÉÛ £ÊÆî¹`\ѵ—ž“XæÞp£L:à¼a'¯žqfô`Û½kî˜Þ[Lk²ý–såGꃆ·%ã%£úì~ÿ9Â+|e.:UæFš>”¼G ;¸P>EbÒ'¯Ÿ{ª]úÞ¦ÝF5™pzÏF«Æî]ÈWÛ²²ó¾¯÷ïßwÑ”±—ž[ºpBÑ%£ûø>²°Ÿ]zÒzÍøÁ%=æŽ-úÍìS“æ*¾¯b&µñâ­>ïéýÆ éyeyñâ‰ÅMŸ¦(9q'š÷ïKÏÖ~ýÕWs§ŽhÞ÷ÍÖÚêAÅ'¥¿ë¹Rö{ÇüÅ%ÔÇð쳎¯ôÚ'ý]‡d—B¥ÍõÈZÉkÊDÒ³Ç1—c.Mt±cÝÌ'®(NŠŸ;ù?¦]Øcþ‚SW^=bÕÊ¡—ÎX4â‚©¥§ôûiÉéS+†Lº¨è×sN6çuGüÄÜQ±§¡näk9 "ûöÛ!%Ýn¾è»Å¤ŽÜüóïÞ®œR, T™TÜãò1}×\Püè‚SË<<·û|_ß_Î(•éæææ²Òîkg&¯IÃ3wËÜ5«–Õ¿{ô®Ž6_ï½kíÕçõ•¹‰ŸrýÅÌ/¾}fñmÓS¤'rðàÁ²S»ý×Ìâ76Ü -s#å³÷þòÌ// ý¼DÖÜ.=i=#áŒê#Ý •ÉsßW± ·XÒ~©ôÝrQqíB­’ãÙÍû÷ƹã¾=xðãvØ·×wÖ€IgôL×+ré–{ÇüÅSÃ3ÊŽûÓ«×Ï)q’] Q”6½ìY+yM™¨SZbö8ærÌ¥‰.^^7óÉÅÅIqïœ^†þøÂ‹zÌ]ÐïŠåg–Z{Ï%=JOøþòºÛ{@þñ½þiô¤Âê¹§˜ó:Š#œk¯Y:køi=‡ö|Ò‹=¶à»·‹'óÙ2=nÄéWL(úïÊâ-7œ›¸°Q¹ä7qÑøâ'WúM([ù«ñÔ²ÓöÕdnž5íùüü3‹7,(þ&ök%­ù”G|—Q>z¨'ñ,®´lϽtL錩ão¿õ†èâžÏ‘Ë.=1Þß²^æVÝtTŸW$ÏU|_Å6LœeÞ//rP²bÿ¾ñâ“2ýpõ]ƒ‹ºÍW”þ®WäRнcþâ)cf¬JÞ?§$1¤ö)"iaÉ.…¨K3jtÊDÒî7¹"n 󒉥‰.^ùÕ̧–'Åýs{64ÿÌQ]GŽ=¥´ìßþ_£ÇLîß½¤àò%ÇöxÂâeLžvÚ½³O6çu‰{gß—ŸËô¥M™;ÞóÜãÕvÇsR®77\/ÓO=Q»têg‚eŸ¾ñlâÜw7ÿJ¦¥×¼hR¿÷Ÿ»W¦ï¬ºI~¥…™¸yøJ™µãÅ­‰ÇÏK/l•Äk®\ôËéÅomX= úìÓË.úÌÕ§KQFFÛôÇ¢Uþ÷~·ôüAWNx×5³ß~åy£ÿÉëOÿþ†©+§ö_Syž,óQã‡g”v{h®mzÒ{æª!;ÿöÖ¾}{uóÊË=}¥gûÓå[sßW± D¾4šîƬ¤¹NK¶Û¿-,ö î)ÓÒ´X21»^‘K}T(öŽâ»ØÅ¬¡Ç½ôàê./IŒ‹‡ž`wrRf%-,Ù¥”¥ÉkR¤SZ|e’Þ*J]¼z×̧—'ů/9ù¨å}ïGÿ럎ÿþÄ ÊKçM¼Ðû“žÿ÷'½Žù·S~tÛm7ývýÝÎýÀ¼¾æ¼Ž"qï¼ü«KÞoøëÁƒÍŸÒøÂ×$ÎJœNÊ%oZ{T®æ¾øøÝW\k[6s7/ïWûàºO>þHZ›ß4}ôÄúÛ¤9]>ôùI\¿ðºäZ±xÞÈ=âý÷õ·,^}ôúŸ/öö–muï­+Þyëû÷þøÏ_½È×ÓÈk—~ßm+ÿúö›’~ òÕ'on©½yÖà %ýÕ_Ï~óÕ›÷ï•øàíWf]0I*Ýò)¶éæv§À=wÜ"…ïß·WZøRk>¬þ¢³¢…+¾¯b¾S{Ó—_üÝH1ï#E¿d»ý+ooŸQ²trtÛþçŒ ìzE.õQ¡Ø;Šïb— =nûƒ«š[’3ìu!³’–ìRHë—ÏkN±,MtñÚݳž]V’÷]vò?û¿Ôõÿ ;·tåªy+W]ño…ÇüsÁ÷»÷ÿißÁ½î»ï;o¿sá¢Kž_lÎë4ŒŸrÙ;2½`\Ÿáýºÿ¬o·³ûw_àë•8+q:é­ô°~~Ö)R¹4kòYò­ß·A 1æÞuiÉ”¡'—•vØ·Û™ý»Ÿ?üdiNÿê’ä5÷ ê!^tvï5|—¸À×[Ï>­ûúÙÅÒ0«ÑKJO9»·…ãzß1#ºŒ]º¬UÅÙ½åëHº|úye…2ë† £Ÿ˜ØçÜ…CŠ»IŒPxÉè>RééI±iiÉõÓŠÏvÊ™ýºË’ò½†÷ë6vPá¦ø¾Šm8}D/)ÊH1Ï5B¿d»ý›ñ]¯È¥>*{G±Â–á~ÜŽ‡V?<¯$1f;AI Kv)¤ÕJ»¾¼ÐœÑH‘YŠÒD¹gÖsËK’â¡ù½úÊ?óœî˯ðÞyëŒqSå÷ü§BÏñ?éñÏ?éqÌêkWm~jëm·ÞöÔÊ2s^§a\€!!Ó–\;­XZªÒž\>¹xù”ïf%.–ôö³¿lÚ:?8­ÿõ—~ë•mr`¬Z¶pX¿î‹csÿ¸¼änÉŠ)%‹cÅ.›Tü«K£‰I«qKEÉ’‰Ñ2¼¼8žøÛy%+Ê£ŸríÔèÛç–¬ž]=IY6¹xýìC‹)ÓK–NŠ¦Ë§_7­äwó£é.(¹áÂÃéŠe™ ŠéæxfYÉo.+Yu^±,¼8¶°L„.Lñ}ÛPªÏŠØvÜQÉvû7ã»^‘K}T(öŽb…-ã²áÇÕ=´ºf^‰ëìRHî—ý#õžY[¯,IŠGö9}d×+*‡?pÓøÅ 'Nœ6ú¤ÒŸü¸ÛÑ}8«ï°Ñ§½úòkûÃSW 5çmýxó…ï¿óúÁæÍ{¿úì¯/ݺâ2ùuøùÙ½¥6åÂêû¨˜}f´JŠj\‡d—Br¿4ÑÅ›¿¹ä…•¥IñøâÒ™Ÿ¾úª‰W_3ÿ·Ý9Òwzþÿ~ÆèAgsdoùužWެÑŠËÏúéúë/}åáÕ®C²K!¹_šèâí{/ùÓU¥Iñüšá÷ÜwÝíkWíÞýÖO>¼pÙ¬-Ï?qëÚkæf¾öfÝ-kWßu÷5îÞqóhsÞ6‰ K¯» x‰Ñ2ŸX|Í´âG”æÈºþ¨¸èôãÒŒvQZôž‘{/Ù~u)A„:ì®ê$‚H ÑEü2‚ E pZôRçOh0ß óC’.˜°ÔÅ–ºØ`ÂR{LXêâ+JLÄø&s¸(0ãëæG´Âú´–ºøÊ ãÈÿÊž” 8E§ÀŒhFÖª W {Xêâ +Œ#_‘˜´@¼ò…+ŒŒæJlP¯ƒ9Ñîé¬XÊuSoŸt6 @b©‹°ÆA®H´œ¶Ì¥ƒevsiŠÔÓ®WÏ.»:1ýÏhs,uÑdEÒ¯yb¢b:1QË2-KS,àtZÝô¿r? í±ÒÅçVG¸"Ñ<çs‡˜ûv딢^õ´£uÓüÊü\€6ÇRŸZaáŠD»i§$eT›”¢³>i®§£¢²±}Ú K]|l…q„+í¦’”Q]lRŠÎú¤¹žŽŠÊÆöh+,uñ‘Æ®HLZ ±eþ‘6– ›?Å2Es묹†ú_ÙnÍ~(@.`©‹Ý K° ýb©‹]&,/uØ•JìÙ•¤³n¹ó-Üa©‹&,uñ>€ K]¼ `ÂR{LXêb;€ ZNë‚Íiê¢âê͹Ië¹tÍZB'8þ!KºZ™›Ï>HÒµ@6dI†+^øÛ9‰º    h[]ä²+uÁñ. mu‘㮈낃]@Ûê"¥+ŒÛ¦ìÞ¶š.4|cõìRÌs³úSo[ËÒG  Ȇ.tÚ9¢ ×õ(§t‘4ËõÊ  hºHü­4'šsÅ-3¦© £™«¤.Ì?ôм‰µÛ²ytû;$fwñèrV–•=Ñ f9¸k¢dC–Ó:º°\X§ “Rjc¸h&¡ È5]$U|….Íôu¡ÓBp¡ŽÄt…[2¢ wÓèÚ]gIJ{¢hN82†¦.,ÛêéèÂüÖ®G€.]èœêÔéh(3rîBóôfu¡YßÑ  Å2úºÐ?‰ÑšºpúVÝ…Q##½$t¹£ »þ…âß”G‹¤Ô…ú§ÜÑ?#š~°Ì¨øGC?¯¦ÇÐä¬.rêžÐ]ºtè]  @è]@ûÕEâ@UíBAd;ä÷ÅNñ±ªr_-}ºÈ}KÑš.‚Ȉ.(› ˆ={öhê¢K*ÂJÜå€A$?©£ Å©]¬<’x"; ÷‘¦…S]Ä[æiuÅ7hI°ŠN.h¿­‹4u‘˜‚.к@ÑEüĺèغPœê¤u€.Р hC]Ø]ˆ….ÐE¶uÁ% Yt§\[¦cwFÌ_]téåòwÔ¹!×–Aè]  t¡ÐEÊ-¦ÞÅ)—Toöt榟]çØHÿ°IÌ›¥meùæ½ìâ;ªWÞÝÒYžÎHVu¡F­ Ŷ’Œêc[sïkÃiÎ5:•Ýõ:¸þéÔ±AF¶†bƒ¤ÿ¹®wºh[]YV*Q·.žq­ »£ÈÝ\_(͹šG…ÝAîôàÑùyUo ótÊìŠeÌ«ç¨äôwºÈ]¸FíÅnÕ¬n.vDÊ£=#ݧ럦.2U²»ÝÕŽ”[ØÝ⟑\ÖE:ƒç¨›ÙÖ…~s7c´ ]èl wá¨äLí t‘›ºè¢A6úãÙÖE‘ûºÐ¬˜é´2®‹L5óÐE+ë"úÿÈʕ֯éuÆ]iéÏÕ9I¢9·]èÂÅy ÍHçŒG¦vºÈ¹Ö…+b§&œ^ì­ü¤<}çèD¨â¼¥ù°w´ÓÛüT§æÖÈA]¸ØAœêl×­‹Œè"lsXkþUªYrÊö’ër\wÜÂÎÿ²t-4KN¹ø#8—¡u‘Ž+\ÿeêR„Lý9Ò†—ié¬F:­>£¾.\ï tÑ©Zæ¹ €ÎsîÐtT]¨WŠë6]@§ÒE¢×mr0 ‹.Ú°ÍÐ…dY;Sa÷Êé tŽ?ÐPi t€.Ì­‹Dh]  ç.Ð@gÖÅ/Èf@èР 脺ȳ‚]Ð9u´!O {  ³éb‹ y°ã:.¤ ±ß;EˆIâsÙqD†+5- W ¨ O9 –Ý[õš¹ÐE6t‘§M¢IRŽ.:¨.ö›âŒÅáNÊ¡®JJW„•£ˆ£ €6ÑŽOl—¹2‘ ]Äû š‘Ö×…þãr,KÐ|1@{×EÜNÑatátœgË•4?^]@ÇÓ…a‰–Æt&tamŒ¸4t\aWß³¤ S(v’¡VO¼üaR¤© së"uá´%£ßm 3’Jû-¯µHùψæƒw³zîBge4×ÅÁ IátOu*âˆ>ˆÎÕYúʬ.tzš%ØÐ1tï’8úPÅ%ñÿL%’ÎpjžäÔoNdäié)û).tÁ© @‰ºP`nlÄtñ]ãutÖxHqšÿŒ8êItN]¤ºŠ3E?ÅÑo±¢žêÿÊk>YóËšºààtÔÃÒƽíì5€vª GK}ßâŠÄ¡0Økè]  ³.¤o¡pBè€Ö…‹Ö» ]è肦@§Ò…kp@§Ò  @YÕª@ÙÐE]ŒŠŠŠH$b¤466úý~Id? ‹D<O0XÐØôy½FJy¹·±±<¨d? ‹Dêëý--ÚÚ"§0.ÚÚ $²ÐE"^ï1‘ˆôE¼……‡t!ù‘HH³õøZ­s¨æ]óNçr+tl]èÄÕÐÐP__ßp$uuuñtcÚxÐ@GÒ…£q>ý~MMuÍ!ª¿F'ª×­«®ŽMÄ^+cØU´°Æˆ»I³ô‡ËйWm…ÖRŽÀ“´b.V'¦Ìè"ºpôÐñ@( ƒ•~¿„¿¢¢¼¼\º%Á`@ä ïä}(FUU•]ë‘.QëÂraý6Lú+¶5Tsˆ»ÄÖo‰º°ÓEʇD"iKT…B5ÆkMµÑO©^W%éñWÕ0S5ѲJjV.õÀ_™]É”«¤3©~v@¹ÐI<‰!­‹mµµÒªÖFUU(¨ ¢ 3êþ…S]¨›ýît‘Ù•ÔìȨá(; ‹6?Õ™d éƒÔÖT‹4"õÛ¶ÅN_¨Zš§73¨ E#_q®2ã+©/(E¢Óì€.²ôGª‹añË;¥E!M qESCCU0XYYÙ:º»]Ü® ãt%užµÎÄãTlAè"—uaœÇØ´i“XBŒ!mŒªPÈNê¿ý3¢YÕOD²«žêš˜òt«º‚Ûup}eͧ=ºÈ5]¢‹TTúý>¯Wq¹  ±DÁa¤±ÁÞèÀºHóöÆÆÆøÅœ2ÍÞ@ÙP   K+]hÂXèBÆÊ@š¤9V†þÕm»$ºH'ošce$]ò²R·Õ’è"ý¼é•¡ùbÛ. €.ÒÌ›þXú?îm»$ºPäUDÒÂé•.:Ïc‰\•MaWce@çÔEØùXŠ>‚f!K ‹ÖA¬ tÐÉuaÀXèBÆÊ@š0VºtèÂ)‘H$ z½^Ǹj]˜-aŒ%ø|>yÝ´i“HÃH‘Yx]ã_ƒ•O~YY™C^=1‚Á‚††`y¹Ï2£ÝÃÂu€.ÚËC¬¯¯¨¬¬Œ^Ÿ J¢y¤,u5§Ö´/]8z¤rì^`|ü+é€$ê"q¤,I±âFçIdŠÇ™©si>ÖGºp§ Ã-1R>œ¨¬¬0?¿‹ßŸßÒRYUUŒÝè×E0¨ª*hi ùý>YLz(Žta~n Ž.eê?`]¸Ó…bÌ ‘@yy‘¡ ‰P(ÚÒ6†¼æçç‡BG‰+ ]”—GSÒÔEØêÑêéècºhµÎˆÑº(,,0´°m›§®.ÐÔTÕÔT^WçÛ¶-dh¤°°‹ëÖ…âáæŽt¡xN1 ‹V8Õiœ»((ȯ©)”ðz£ IkhæD¯÷¨šš€DAA‹svDwݺ0ƒ1]¤©‹°ÃG*{<Ÿ¯L\QVvŒ§¬KuuAuuP&ä­×{ŒÏ瓵Uó­kɨ…€.]´¦.¤åPTT$}ºº:1Ca ™·’(³dõ»Ý¯¼¢‘R;výEÉè"Ûºjkk»GC¡P~ ™Çn/•YìMtèÐE+€¦Ðº@m®‹­KnÞ>ì²G“ yË€.ÌlŸ¾L,ÑüãŒØ™7lcžGÕ¹tžžÙ%ÐEÛêBß¹¢Ï‚¸.ný^/»6FâUv×qe|ItÑæº®Ç!W„^o¾ï3™{ºP4 Ô—vg|ItÑæº8¢iÑgA¢+Æç§îA¨ \]dOŠ0ëBzF$¹]tx]8B:#¢ˆx$ºbÎz8-M¿²£@íN[—Ül(ÂQ„á ‰u£¦ã tqDcú2±D¢($B¥£hZ  Ë6F\2á´]+]p‹º@¸]ºtè]  t9¢‹ y6°§:­.¶X‘§„Ð9u±ß ³"Ä!ñtv@'Ô…t:4›â cVëo±Ȭ.ô‹œ¤ CGF²%bíŠC­ŽÖ¯Îè ƒºˆ»Â©1RêÂpEüÕ¬ ͧ‘Ú=Ùü€ug¤  ׺0,ÑÃéÑÓÔEXïÉéêiK{(ž±€.2¨‹”ƒà)uam ÁQgA_æ,è tF¾3Fâ"vç9ÍÕÙ®‡¢© E^·å©Îývº0þTî§-Ö…Në]¸þ#ÕÑY‹¸.öÛ ¶0: )ÿBu¤ uË]ä².l®?¢¥ÓÅ¡&‡Â–Ž8=Ig uLE’4Œì)€Î¦ Ëë9Äï;cOt]8º] ‹4uaÙ+AèÂQëWtZ]8WtZ]ºpª@ÙÐE]ŒŠŠŠH$b¤466úý~Id? ‹D<O0XÐØôy½FJy¹·±±<¨d? ‹Dêëý--ÚÚ"§0.ÚÚ $²ÐE"^ï1‘ˆôE¼……‡t!ù‘HH³»[Eìæfƒ”Ÿ¢^@g”€Ž§ ý›ßêëëޤ®®.žnL¯ºèHºp4´Žßﯩ©®9Dõá×èDõºuÕÕ±‰Øke »ŠVÞº®3G±@Rùa«a?Ã6wËj®¤"{Ê›p5WI31ev@ÙÐ…£q>Å¡P( VúýþŠŠòòré–ƒ‘ƒ¼“÷¡UUUv­ GºHy ¼.Ò“• §1©:‘»û!wt‘rœÏH$"m‰ªP¨Æx­©6ú)Õëª$=þ甆fª&ZVIÍÊ¥¨h_É”«d×`ÐÔÆ@9ØI<‰!­‹mµµÒªÖFUU(¨ ¢ 3îóT´óÍ~wºÈìJjvdÔÆp”ÐE›ŸêL2†ôAjkªE‘ÆÆúmÛb§/T­ ÍÓ›Ô…¢‘¯8W™ñ•Ô”"Ñiv@Yú#ÕÅÀ}áØåÒ¢¦…¸¢©¡¡*¬¬¬l]8}«îÂ8]IõI ºHÇoœÄ@íBÆyŒM›6‰%ÄÒÆ¨ …ìt¡þÛÑÑ?#š•Qý<5»ê©®‰)O·º‰ÔÑWN™ÐEnê ý[¤¢Òï÷y½ŠË-]ˆ% # ö&@ÖEš7°766Æ/æ”iö&ºÈ†j]XÂXèBÆÊ@š0VºÐ$ͱ2ì.drtA”f™)?Å®4G×BèÜñê´Lõºu€ÊÂu&^iŽ•awÙ’¢êWmGÙSŽ’áè˜×ùFîÊÏTÆü”Öÿ,tÑÊy38V†Ž+ô(E™:‘æ1ìh…ÓlZ˜ß¦sÝiØæÞXÍëNÇj6íÐEÖEÇÊ0ovM‚6Ñ…£^ƒ£^O›vwýk–c·ÍõugyW Ó&b§5F»Ö…"’Ng¬ »ã-ÉYÒ…‹S.Î]¤ÙRr¤ wÝ7õFs¤‹ôW ]tøÇ¹+C§j·yë¢C겋ᨇh×±[LSÔè¢3<ÅÌÅX袭t‘rIm†”Kºøè¢?ôÐéXúU[qÃÑÙQFtütôéúM÷V;w.ÐE›ë"ìd¬Œ°Æ )ÍàtXo3™ZRó„ CÿŸËUU{[s˜tÍ^]g„F:á#•+£uèxÿB¢‹N¨ ÆÊhÍú¥ÿ'H{ù"è¢S邱2Р @N‰D"Á`Ðëõz<ž@ òoPèlº-ã_ >ŸO^7mÚ$Ò0RdÞ@ÆøWÁ`¥Ç“_VV&ÆWOŒ`° ¡!X^î³ÌhwÓ¢S81袽<ôððøWÁúúŠÊÊÊèõ™Á $šGÊRWsj=@ûÒ…£G*ÇîõÆÇ¿’H¢.GÊ’»!nR Dñ83u.ÍÇšã(@îtaX¢%Fʇ••æçwñûó[Z*«ª*ƒ±=âºUU--!¿ß'‹IÅ‘.ÌÏ ÔÑ…¢LýŒ  wºPŒY!(//2t! E[ÒÆ×üüüPè(q…¡‹òòhJšº[ ¢’Ž.0 ‹V댭‹ÂÂC Û¶yêêMMUMMåuu¾mÛB†F »¸n](nîHކM@N‘òT§q ¿¦¦PÂë66$­¡Aš]¼Þ£jj.Î]¨o#uѺ0ƒ1]¤©‹°ÃG*{<Ÿ¯L\QVvŒ§¬KuuAuuP&ä­×{ŒÏ瓵Uó­kɤƒ]ºh5]HË¡¨¨Húuuub†Â2!o%QfÉêwÅú£O(r96]dOBmm­q÷h(Ê!áØí¥2‹½ €.]ºhк@è¢Íu±lKpØöñGïè*!ò–]˜™¾}Xâ¨æÈÛy|ÞÆã$1eF§ÿ„fêa|è¢Mt! Ã'6lŽaè"oí±ê6†ë'›'^ª~ìNÊ%ÐEkêBºâŠæÃˆ4Ć.¾ü±ºQ¡s—º]ƒ!#K ‹ÖÔ…Ñ´°tEÞøê·.=>O§i‘rIt‘](¬‹hï#‰®øÁœcÑ­‹¤ÎHTñ8Ü®c8ÒEúE €.rY˶EF £]!1jÝxw­ \è¢ÿ‘šh #JCÕntè¢ó\¦×…L¨ÛŠæÿJp  .ϬР‹Î¬ \è]ºtè"SŸË ìèB×7°;%åÅáÿ ų8Â]„[ëöô]áºÚjŽ•ayù·¸ºpý¹.n`Û?DóÝòQh:”òÁ(a›»Ò\߯€.⸸]ýÔý‡°»¸°Üî‚RtèÂîs³z{:µ8ìv>tè¢Íqw»£ÕuFưžËµFР‹Œãúvͦ‚fÇ$ýÖ…#?  @îpw{úºÈì¹ õéwgÐEÊ6†þ ìú£f¹8)ªÿYšÝýQ¿ÐEÒjõ‘ŠèWà @€.к@€.]@‡×EЊ<ØSV[¬ÈSÂÎ蜺Øo…Yâx:;  êB:šM q…1+K_?ék.…Èž.î}b»Ì• Gº0dpd$["Ö®8Ôêh]@ötw…Sc¤Ô…áŠø«Y–â%ÎR‚g7î„ÓrÐ…¦. K´Ä0¦Û\IÃ]ZV|GÓŠrÐE:ºH9žRÖÆÔý»€ºÙàZ3€.r 3ò1ÿ±;q¡Ð…N/CgZ]ºh­Sûítaü©7†]!êÖ…ºçâ¨c¢.]èÿ‘êè¬E\ûm[¿PíF‘ÒÔ…æ9 tжº°¹üˆ–FL‡ššº[ d§°ŠÎ?#tFÚJÁT$IÃ8ÑÁžèlº°¼žSAü¾3ö@Ð…Ónº@éè²W‚.Ð…£Ö®è´ºp®è´ºtáÆù@ÙÐE]ŒŠŠŠH$b¤466úý~Id? ‹D<O0XÐØôy½FJy¹·±±<¨d? ‹Dêëý--ÚÚ"§0.ÚÚ $²ÐE"^ï1‘ˆôE¼……‡t!ù‘HH³õ-i­sKHÊOQ/`7—ûY cëBÿæ÷†††úúú†#©««‹§ÓÆ«€.:’. ­ã÷ûkjªkQ}ø5:Q½n]uul"öZµÇ¾kÜ‘ªÐÒK)‡ï³\IEvõ0>ú«¤™˜2; ‹lèÂÑ8ŸâP( +ý~ EEyy¹tK‚Á€ÈAÞÉûPŒªª*»Ö…#]¤ˆÏN)ow¡ wºHPȽü;ºH9Îg$‘¶DU(Tc¼ÖTý”êuU’ÿwUQ 3U-«¤fåRT´Œ¯dÊU²k0hêc ‹ìŒ$žÄÖŶÚZiUHk£ª*TÑ…Îuÿ©.®I ÖEfWR³#£6†£ì€.ÚüTg’1¤R[S-Òˆ46ÖoÛ;}¡j]hžÞÌ .|Źʌ¯¤¾ ‰N³ºÈÒ©.î Ç.ï”…4-ÄM UÁ`eeeëèÂé[uÆéJªOJ¸ÐE:~ã$ºhº0ÎclÚ´I,!Æ6FU(d§ õߎŽþѬŒŠ¦»¢zªkbÊÓ­:c“Ú=Aó+§Ìè"7uaˆþ-RQé÷û¼^Åå€.㑯{ ë"ÍØãsÊ4{]dC5€.,a¬ t¡ ce  M+]h’æX:Ob ;¼fIç/ýË4ïxU|:ºHs¬ »Ë–P¿j;Êžr” GšJºv]„3:V†Ž+ô+¯¢LH§µÀ™€.,ÉàXI¿Î–7°·¡.œöDÐt*]("iátÆÊ0WmK{dI.Z:½!tJNq=V†NÕnóÖ…ëŽ º°3†Ó±2Ð@çÔEØùXúU[qÃÑÙQFtüÔY]¨Ñ+#¬L/åPv‰êáìì–Ô/SGVèBÆÊ@š0VºÐ„±2Р @N‰D"Á`Ðëõz<ž@ òoPèlº-ã_ >ŸO^7mÚ$Ò0RdÞ@ÆøWÁ`¥Ç“_VV&ÆWOŒ`° ¡!X^î³Ìh÷0A§p  ‹öòÐÃÃã_ëë+*++£×gƒ’h)K]Í©õíKŽ©»×#ÿJ: ‰ºH)KR솸I)ÅãÌÔ¹4kŽ£]¸Ã°DKŒ”'*++ÌÏïâ÷ç·´TVUUc7zÄu ªª ZZB~¿O“Š#]˜Ÿ¨£ E™ú@ît¡³B$P^^dèB"ж4¤!¯ùùù¡ÐQâ CååÑ”4u¶z´z:ºÀ€.Z­3b´. -lÛæ©« 45U55•×Õù¶m ),ìâºu¡x¸¹#](žSÌÁè"}c¤<Õiœ»((ȯ©)”ðz£ IkhæD¯÷¨šš€DAA‹sêÛH]´.Ì` @™ê’h.ìñx|¾2qEYÙ1ž².ÕÕÕÕA™·^ï1>ŸOPÔVÍ·®%“r tè¢Õt!-‡¢¢"ékÔÕÕ‰ cÈ„¼•D™% ¨Üí~å>¡È¥?2ºÈª.„ÚÚZãîÑP(”C&±ÛKe{]ºtÑ pó;º@è¢Íu±lKpØöñGïè*!ò–]˜™¾}Xâ¨æÈÛy|ÞÆã$±uÖÖòßÛL•©ù(t¡Ù®0\qbóÀæ†.òÖÛ mŒlÔeõã¸ØÐ…k]H×C\Ñ|‘†ØÃÐÅ÷ƒ?VTÉÄz§h!¨/Dz¼úK]»ÏMKLT?-]ºp¡ £ia銼ñ?t×$Hù˜Bu»VŽ.XD€.,u¡³.¢½X$ºâsŽm]è˜Á®Iƒ.]déŒDÃí 1FÊΈN/ÀînÍ–†]D]&ºt‘q–m Š"Œ0F»BbÔºñ)³kþèëw"ÂÚ\w$tè"#Lß¾ ÑF”†êäÕ¯†úç2¢ µvР‹tÚq]È„º]¡¾á=å’ê¡rÂ6ÿŒ¸k-èí€.ZÍÚ—JJÅtÑŽD+]  @€.]ºtè]ºtèР @€.Р @€.]ºt.]ºtèР @èР @€.]ºt.]ºtèР tèР @€.]º@€.]ºtèк@èР @€.]º@€.]ºtèР tèР @€.]  @€.]ºtèкtèР @€.Ø\è]ºtèР @èР @€.]ºt.]ºtèР tèР @€.]º@€.]ºtèР tèР @€.]  @€.]ºtèкtèrM{öì‘W‚ :mhêB\ÑM]  @€.]ºtè]´>˶‡môŽ®2!oÙ&[—ܼ}Øe;Ž&!ò–m‚.2E‰‰tÊiÍ5Ÿ¾}Xâ¨æÈÛy|ÞÆã$Qó›fd»™-çšßfinŸ¾L,ÑüãŒØ™7lcžGÛp›X~VnQèÂéNi/ûH†+NlØÃÐEÞÚcíÚ‰_-ý¯™q]¤_S¤!ñ+ú,ˆëâÖïõ²kc´Â6qýAè"÷uaw¨+*‚:WÒ–ŸO×?B¤ë!®h>ŒHCìaèâûÁ;=bÍëf÷S¨ø9VlƤé¤Ä¤ïnY¾Îï²t=¹"ôzó}ŸÉ„ØÃÐ…D›lcÌnï+ÒÑEnê¼Ëtt¡(Ss±”M KWäÿ¡£ª¡–UÊ\)uaÞ€)=¬Yq’8¢iÑgA¢+Æç×&ÛDÿSè¢ýêÂòÈOGîö~ÔÒûˆE¢+~0çXµ.ì~4ÛJú?ô:ºÞ‡I®Pë"{ÛÄÑ1¦©/:#9® »ßA§ºpׯ¶ëŒDÃí 1†ú›*ÚØ:ý)ÍÓ×EÊm%QD<]1ç=Z› ‹NÛºPTG­ ÅœÓS¢#ŒF…Ñ®µn¼»†·£Þ“‹?;ôߺ;ÿ¼uÉ͆"ŒE®X7jzëotÑÙþIÿÐ9à]œêÜû#5ÑF”†ê|Ó4«†åÏn›ëbOìT±D¢($B¥£Úd›8:§šÁ€.²­ E[WÝ·MùŠe¿F§e«ÙƈëB&ìÚšG©NƒÜÑù7׺°;ª³}¤×…Lص+Za›èHè‚«:;àò€öØkF€. Ã¸]ºtèР @Iº ‚ˆº Â….öE¾Žë‚ÇÈaÃÒ´^68ÑA–aèâë/Âl ‚ ñÉ®wDz<³lç;¯ï~ïm¶ AæøëëÛ%Z#m ‰Ïm|õ…Ío¾ü> endobj 3555 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /XObject << /Im33 3550 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3563 0 obj << /Length 1652 /Filter /FlateDecode >> stream xÚuWëoã6 ÿ޿¸O6pq%ËÏ}Ëú¸Ý°Ý£Ém㨉7Çêl§‡þ÷#EʵÓ‰¢HŠiáí<á½»øy}qy›Å^i”zë{¯^&òPĉ·Þz_ý«_–ŸÖ7wÁ"J„Ÿ…Á"I…¿¼báÿH•øËW7×t|{³ ¤”þúËÝÍ*ø{ýëåmMdÇ(8IA³- L‚K„'eX$p ØŽe CÑ­,”q )„ðïŽm[·;R_ÒÏ:("¿lw†¶•i‡.¹o"ôOý ´þQ{Z {ý‚¿Ñ[–\UºïϼHx ™‡iN¦-T‘+‹c¯»ž–]½Û¼.;{ùý`:«ˆuË—Rø†7å¦Ñ|ËÜŸH_¹p/…í¶î²×$ðœ¿dªÞÖU98-[D‰ÿXW, | dâëŽöUiŸmŸ á˜O…±R.xìårb¤èpAá#–YZ¿]M"ðÒ…Y&jÌ öôBAf ô÷º×¼cOàÃfŽnbð±Í˳×D«š²ïáÙ Ñ'ŽÂSç(:œx I|›á±¿Þ×=1w—?–-ž½u|'f™‚øMý¬D1ó3žŽý@'MH¼oBD»£Í<¡ìÄ3Ó6OD3­>U€ñÎ 0™U=tæAwÃÓ™ ƒÂ8‹œ·W` ˆB!ç²[eaßèÆ´;ò5\ yCeQ¨d2w¥h*ýûNóÊlþÑÕpƦ¤s;-WC׬¨B_”ˆ0S¹cÅ¡d(²-­C¿Ý±¥EI?ÓBmå…›`Íp«“¯Ÿ±7N å(x]ÅŠÉS·£7D˜ÄÑÜ-–Uå` þ€]ùD$[ÜðÛšÂøƒÖ"Øè²ÚŸ²ä}ÕÕ›ñ 9™ ß ¬ßD"zø'‰Úx ¼p€8Þyö °~ÁWŠÌ¿ÅÔ5ÝŒaÂb ¾1Vð[ôIäPµpæÐ¦-6)9(o&Haš7¨­_ÞÆ;m?”í‰,XíKFY laá~«±®ZspzOÇö©®ék8b3¸Ìb§. ï{SÕ ¬p¹“!>ÛgíÙn SÅ#yÃÂÈ;p䤯”™Ãøl?3ŒA¦vï T.ǰy˜óâ[z~ zUÄmPEòU½È4Ã6àaÛ‹sŠ2òá3¹µ$jRÖ"êJx—”Dß©Çð†æRžÁƒ< …/òS!A­nôA·éÇ\%) wt® Ñ¯(`=íÆŠ¶;šé¤0*b „³kNFAɘ¸d„éCãÁtøq¿ž„aGåh ¼3bgA¸´‰ûÓ©ŸœðitãœEp]¾Ç#FÚCmŽÉ‰T" NjÉ›üh-œ1·/‰çƒ]6õÖI˜?•œÛxR™®Óýƒi·ÔD°gF½’vô¬8,âøõúÄ®4IE˜P1#¢Œã¦Ì㘒ؘ̈Æpá‰6{cÛ²Ä^àníKô‰%Ê®4± -ØÖ‡cSc›,‰m:HñŒ´ÖfÎ!ÒJ>S±Ó6$‹œ5#¶CµG0}0h ûrp+Œ,®¦žÂý´he‘¡øÒ—¹10tŸÙZ}þ%ã“5£Ý’`íô½é˜~ÀΆ‹V;‹‡óË¢£|4¢6-í;ݸÑ5óu‹1}¬;ÓR]#‘²¯«Ç9Lý ä}ÿ²²_-Àb-Ä|ÂÉu¹Zý‰£ÏÇ»k:ãFzÒÓF°´µ*.¼nçÑâªõ«­åe§B5«ho–¯\…7äs|^‘XÔÅß’~fƒ’9·p=Ž)xiÜÍ1ËEŠ#ËìôÁÀ ^¡Å!øÝ<-J't¼rÿ–ú|͆ÆÉŸÑÜ?s½Z™USøâÄôðÐàGÄå…+xùRJÅ,¨Ä¶úòéæî;|t(øà|÷q Zò´¨¼º£ÆþžÂœæàï§\P›ÀaQ—=æ›%ží•ek0¹Q&cV:™Ê(d<:ÂvÖ¡Àt6’Û³xÊhAáÇžjM%pß~[²A{]ý‹™M²A & ÷PXŽÅ¸3vÍêN—ü¼ä™÷\˺YseHOfðÅßiÊBzÕáâ¿‹ØžÑKHe˜Iû]!¼\†iš§îðòýAÅÞµ¹ø §zþýxB endstream endobj 3562 0 obj << /Type /Page /Contents 3563 0 R /Resources 3561 0 R /MediaBox [0 0 612 792] /Parent 3540 0 R /Annots [ 3559 0 R ] >> endobj 3560 0 obj << /Type /XObject /Subtype /Image /Width 300 /Height 397 /BitsPerComponent 8 /Length 121451 /ColorSpace /DeviceRGB /Filter /DCTDecode >> stream ÿØÿàJFIF^^ÿÛCÿÛCÿÀ,"ÿÄ   ÿÄ4  !"#$ %1234&BRÿÄ  ÿÄA!1"AQ2a#qBR‘$3¡ C±Áñ%4bÑáðDcÿÚ ?ân#ªÔØ'>.We}W(‰ ³™…Ì„?°,6ÙƒŠ!4OJ\± ñlµ$¥¦¢±ª˜nSu$*Ã\þÊ"b4V–ÏšÈmkeeöRš3p“¦áCžÂ–«–|cnµøõgË}ÖŒ³Bõúd#륫kNh`ùùz}1´ð«ý‹GȽäÓ0×± 3rçXñvó=·tdÌž‡Té=O¡ÄërJfµ¾£öV°°–÷´p×@e|—‚XLË\G¢2œ5EDR¡¦b@#q©xEÙ$(Õ²sf˜Ë`KÜr’¹D°4¸#õ%œ´¡L¼Ìñ¬w"±s)fŒRŽ™0DŒ6‹IŠ´kÇÂ~ºÁ"B*\å­-µêZŸ¢¶«t¯ÀŸþÌãùÚ±£âȬÐvµ¾v F/¦¤9>ÚŸö]p¿ò¡/5b²+¬Y _ù°líZ‚µªÍ•p Ž„) ¯È¦©p”¥–‹×v¬**’:„ºägZ49fW$ŽÂ GlVÓú ZP+è|¬BÑh ½#ãR4)­‡_kE€Š"¶$g-`UXQñà_ßÇBAœ-4/JI%P„Bص0µå·'Ž:O]2{&+U:ÖÅ\Ÿ;X_óÏoÎáŠ|,H¤ûÚ qò½ íPQÅ\•Ïù×¾²Þß++À…-ö'ßF¾ éXµtÄ@ÏÆìR üe½¥»¶a¦©z5÷Ö³`OçŸüñBû1-ZŒ«²ûŽF£þØ´ÑPý–Âk•¢‡;âígQeié8}]”ŸaRª%äÿ$r—m{Ыף¼þ–qêÿze .^ÿr*ÂɽdD‘döˆòÁïëp_pº»¯=YaåB³K…¥v±‘²'kUFQOȰBØ‹é¹l<»Šöµ[«pÒF°Å{\ƒOê“Ä8/¢£5dŽAf 2I Æx€mWžæì+ÚÝ3šEùžÇ±KŠ@Vm1$ŠVÍÕw/Ψa ŠÌ^-h±io„ý•¼A#Ø^æ¥mô}î0ˆ¿T|¤C§½&}æsÄ150+ðøP„%½«6 ˜ÏÇí\D“ÌÚ!AÒþÿWÙó‘† H/.ð~êjýCñÁþæ¸çÀùñ¹u<1atŒ2I°Zl’hxçÇãàüôï¾'?i k¢Y÷åŠX›ÚñÅD!¯rÚ,åW=ÃTÕî .A›ãñÉDyÜTVÄrÞ.Y1…=íBÕaÞŽ jÌ™j0Å.äR“sЄpl¥ÆÉ­õª1ܵ Ä(ë&?Ɔ¬†±z“¥}«KœÕVäúËjXšÇ‡ü® òtñ¯tž1)sUÖ9ÂeÕY â- (pPBQh“U¯ÿh3Iö<þhŽ3¨ÊÔ„ #Tbi£BÇí ÊOõÿí]_ixÚ¦¨¹iœÚ¢b*¾S`iº† ¸êÜ#M$&¢W*B—ØÖ¤ôŠÞ.“?AY~CP_}Ò\À¤Ì @FzÐ-Å®E&Š–©@­ ’†×`|D:ÉYdÄ^HÍ(ÌV‰Ú×´‰:’ã'ÚB^jv‰:”ûè1RÖ¬ÜYQŸÏñAZR`mOqL|= ³$½áŠ–ÕhU-)deGQ_@tû-´ÐB–f§7Èò0GÊlYµFBZÁ/´V({Åkð½½­ï%q7Pl‰Ü2ƒ¸8i qÈ<f¾/äVŽ$T±ézXr9 j¢·hîàAà‹š³}?ª×J¹‹a,Ñj(l÷Tv%e’†li…­zVß0’†9\íøš\$qòÈF[@ëm-*”kX·øU‰* }­[JÇ¥-a­{WåfJVÖĵ«ïïAÚ’CQ‚¶ýu©+öSÚ-QÀÄ:D´ëOøÏÎcÌÁ¾¿ªÖˆ­ãþtˆ _êŠ Ÿ2–ŠÍ‡ð’[þ2[ZßM-/ù¨ið†ÿ–T]PsuÏ'ÏŸÀóÍž¶äÈÂÒ—#O‚Á$_”7ãȯšç§×ú‹›Ÿ®ÓΧQÀX©^ÔŠ‡ñÔ?¦Ÿ:–*3¹pÜËX¢fÿ;À«k^}GAƒöšßé«ZHC"ï´ÕÉ%4^(Y‹ûÚ)BÇ=¨r–&du¬Ä–¬^moŒ}t±"Ñ[ŽÓ5ooo²?ô 1hŸx˜šýŸ;P6÷!GñôI›ZÔ½Y¹=¢Ô›bò: Ì×’^Ñeà?X…ùÈ{&.:Ú66ŠnÖB¤Y-‘5’@á‚]ñüaæ¿,žJœ´"eø{Ã}ç˜7ÿ+”£[Šq—I#= ¶‘S~C:«RÄ éñ'Ä“aA½à±í7´Á`“zÒ¤Ÿzšf‘{Íäß1dzjÚUú;Ò>–ºÖ&VŠÏ¦ŸY9b‚sŽ ·é7Ìøj5NJ³v¶¢Ã2äŠ9V©"‹_§cC‰‘,P¨@ûÔ™©ˆÿGÅ€@ ñ㎥âw޼fŠš‹8Þ°Ã,ÛE b±+¸|tôâdk¢>UúÇ@¦¥ ô0"-Yµbn2ˆÕ\¡kçh\#ÎhdÏ1tÛopÛ½HÊšvËØÊŲ¢qv¬¶³V%,E~‹zä{B×±Zi˜£Õ»Í¡c˜ùè¤VbÞ'ç>õ°góßí‹ý³ Ðo‡Ø&=þíjZÒ+DÁð÷ƒßò—§2oóãÛÝìñ<ÁàNSäq3Õk¤¿cäò·I20Q•Z`¤È öfC:" À2œMc¨âé0®FDP$i4É<­_«j«µUc[›Â‹ Õ–ÜÝéªfý†¡¨O‘“Ûâãc{ä’y®(à…äbò¢€¨Qòê>ÿö†ñ¬_¾Ê$¡¸W˜‹^/íq–(3à;v+¨î݉%,ªQŒ¿ÆòYòŒÅi‘UJa‘pHËJÄÖ—V‘®@ÅiUâµUí§ÃÚÊzoâÔ/-Âӵ׺ 1™.…=îGg–\ò-îØÝ&bû „N.:°î‘BTtAkUÊ4ƒ,*Ý/R&ÑÄÌ~ä^a«ýÒ—Š"ö'±-íò°âókEmQ ê]¥Ü†s¢Í‡˜1%"ݺ&›Ô€À5X&¿GP»Oë_Ót§ïuÕ4¬mn¥Ó&TÓ5|ƒŒcYâ3é™™‘C‘ŽòF³A+Ç,lÀ2X‡Y»®–èašG'êØU\*AÛØU¥Ãƒ\—=™'üFJØßó·½Äõ¿Iy¿ÏNmHú-(ÃqÚƒ­ u5,9¡&µ)_éi –¥´Eh2${ÍÂí‡a@‡÷Ëx`c’@ävÄò2™aý?þ“jMþu˜l­­ð¥n%íQÒ %û foxŠÿÈv¬Z~ojÚ±[åx™¬É`aÄcÂf˜Aà€|žEøøÿn•Ów>¸ò,¬jž% yL…˜ÄfÏÇí}-­èØ¥¬MÞ$u÷\Cùˆb²qQŒ šýr­¬™¨â@B×똯9-ÙïUº{'‹}—·Þ°GO²~Úšã°©>ö˜øÞ'ç›Z>w‹ý7jEïó­ §×$’^j[ZKXRžvkYÖ¡¥-V>6²Ñþb½nH½m%«µ=¾Eµé#¤O·ÇåÿbmOÿfm_kÄÅ}¦rbãÐZÚ$‘Á/ÁããúõQ&»­±v:Žco°÷—‘eNë²y»Sd±\ñÓ§ýSº5áXÐ=-£ô©í ©fu @Gæ |)kf«JV׬†«Æ¢ð?•’ÛÖÓ1>Wx¿1–Æ$·ùÐ÷b—?ÒBAo[ÄûT±B¯0H’M¯þôÿäf’Пò’RƒŸaSýìKM`8­+K[æÄRkøDÌÄÖ•½¦Ùª 10/iûb¯Õ3ò=ïr´­l:|Íf}ÌJ)$‹È­{Mííþm\xûbEàThÑÏtxúˆú–|ûV|̇;­Uòç#Ú.Á#ÇÏho›MH)«3bIKõÖ‘\ÚZÖ ©+zÖ~Syböb”¸îX%òØ^IBAÆRÐÃ4ˆ%ª:õ­=Å6© JPT æöŸ¬·µ¾M£P+¿`ÉC®hùRÔ¤"¾ÿab¬RÖ€H¤Z‚‰ ©3ù|bÖ%\+)3µ/j|D /îh‹ÑX¼ÐTý7±)"T«´Rˆa‘‚ìZ¦écDU P$ßš³Bëúž?<ÙêL 4„0y’ ÒH}Áˆ÷IÍ „óíüU޼¯JŠÉÒ'þum{Ú£ý2K;1oeopRmñ Çõ7KX¢ `Ĥ1·ÛX ¡ký$œ4Gæ^ô§ÓVë¸ÀÅëzZWv㥌zÖç~ðÝm?åãßÇ_„=W=]?=y¯Åž/ånë¸ËWÈ=-9 RW:þÎÚëa"Ãf¸Í&~†Ë÷.Ô`dT"+ŸÆÏ§ïNí=>ù‡Å^Iç•ÓÍGQßw¼÷\¦þNÝÌê/®.³v¨¶V ¶jœz"]T©e*Ê£+êžÝ0öÃcê :ç.–3š¸GPhÆ@ÆvY]ƒê›a@Åm‡$t~'ðùܳöb÷BëZLz“vÜÝÛ‹¬¶§‘Û‘LÑ>jjá­ £—$âGª®YÆŠY=·ksü0ÒÃ`äRcô ªß”jTðC„—‘ÒB5œ=€jÖ“!ú¾ÃÖI8ðM’.ˆèÄcí·éSÔ+ ÀÛ¾O'äOnlgáè·ŸŠîÊþUÆAn‹PkÝy'™°†¥dN½«TQZ ]ñ–O Ô¤ûˆ‚%í6bĈµ¨ê *¹æ¤½"¿WÙïñö­}ëk^•ñÑsø®þ[7¥Â|}oãêùj‹öOámÿPÝzmP³R‹¢\e*aúµbL¢É±vÕ©ÅïZÏûV£ Çñ7Î"ÁÈØ3RVb´-¾t&kxù@ý½ªJD èk_þGTXìO4 +=½b´ è¢æ¤’´­ojŸòŸ{DŽýë7­¦Ÿðšÿ“„(jÀGïí??ЋñÔD†k·{Oö¶¾ÏŽoϧÑùæàP—µ {HÆÁëzIJ*A®Õ‚KA\¼¦ I† ü=Û­ÇF8tôÒqVí\YË~ µa÷¤=(ꬡ;¬*"l ŸÊa·x§å,HÃtu.1Øäöù±4>Z„± Š +! ³ëz~{㽇rä´V¢"S°™ÐËÑýzY?5"ìÀŨBJWï@"Ò ¸i@HX\…:ìö Rªd¯¥ÈBðö¼ °xø'ò8ýú†À2‰X¬g†UfM¬kkP[‡¢Á£}+)\i¾—86R­@;Â$¬Ù×½>¶žt)®ÎÍZÌceÿ¨oØ2±ä­^oG.9ÑõU‡O”xY¬è꛳Ã]Œ+y«&?HÏ-‡î*ë­]l0Ü'•…Å‚(òAñàø¿Rik03Ík7ìh¥Ê%¤¿*Z÷¤WØ0/pÐwAÙzTƒ¬°&|ûDÈW ÀJÞõ4oi9"Gð¼I1ɽëð¡ªIšR§%&"ñ11|1Äfñ »º{uµ¦+\Ë93 §¤6N:ÔA]¬Ém¤u×jæ ©sdJw>~~ÍHk¢ÀÀôßäï!öÜ¿ãLu;ÞBÓi>3 BmIL‡¢s_HY8è|×ÜŽèhæ"½ä%+ ÔÁò:2ÊáA)d¨fñ¹VÏ'à€@>z°ËÑó4øS'#aŒÂ&uIׂ"ʪ2±Úä‚Cb‘°÷ š¾×ãòŸ¡ß.g¹5õ1 î éõ}õÎ$FtP×°æŠË5½ÎËT¡¤ßª&Gn‡w|­âùÅ´ôµyåùÆAV]ÛKB5Â4{ÓlÿÞÛ¶?áLÈ/ê]\¦sÕ½“çû—ôç䎦ûˆ¥˜ŠÏ;¿Õëæëmægº¾o;˜æ–®ja×\¸sXª ¨ ‘ÓÜjŒl17øØÅñWzg›Oc}„ÔÌu¤’lUfo¹Ð)Ïgd ¬ÝVuõÛÞÒG!LÌEŸÖi–)+TUÚ,¸ï/§°÷–~›”ú¦náZqǨ²ØES!ÿáa‡4o޵þ¿‹½OøvíÎíÑ´îÊл¦çÉÇÊ9ù™9X¹ÙáÉ Sˆa‘2±‘f‘ãŠb»å(ÃÔ4Öê’mm[àíeæ‰Ý”Âá†Ç*‘µÒ%ƒFæÖ`4¡þaT‡lÛY†¿ÕiR^kZV,@TWˆ! í"ùÖ©õ‚šV—VÖ¥¢+1fž_ÄžŸ´zoúÂðGšs<¹…Ýn3Ñb™¤¸Ûó /™š5¹ý®Oc'ýGMêu9ð^€Gð4‘F6¹ä¾ ½0q6å:l¯O|ŸEŠÿD®‹~Zê2úuù‹8£øyklc,]®…šì±•©²‚ïó9ëèçlmpsoßTËÀo´]3"a\xr^hâ,¨2Rê ýº¾]ÌOÍÉû¹³¡Â›TšLµÁÆÆÅs½ãJeŽ` ±H¤y窸­Kl+Ål1ü­x‰ö½æÅ‚Vö¤M¦ö~0;}–‘Ûí˜øÞkòàùR¶§·µÄKØ·¸‡[mhùÛë´Þ×¥`Q÷^mZ+Yˆ™­…ùŸ•ñ¯—|…ϹãnGÅëö™9˜˜,ôzýò´`ùÙpçS¹©—õŽÅ»‹…‡pŒ.Q {b4ò¹›§ÓY¢ÿˆú,~Íž'¨P<†žwDþ©ú"³qåj¢Ä êÚ á‹Sbj7>$·õÙú^“C8"‡æè/b˜Ðäcœy £2oY@.r8?>kŽ©çÆÙ X$YÖFeŠÈŽS´‹2Em°UžšýÁ !Å$7¼E&´¼XsBͦ>6,E`õ›V‘4½‰h-9½þ5¯¿¿ƒMNKûDÖµ™š·´Z²B rZT€Å©¥o#ö‘V±ŠûHKz{îaN;FЊIy -—y¦Ÿ@œ¾tÎP`+œ°Fb¾þ;ÕQ+¶7/JÇý«¾¢hZÞò.¸š:Üîª u7n¸/½¸°vƨˆË-cÝŒq®ðKvüâ^íhÝ…¡8ž%V$ìpP홂š«ý^/ŽO?›5ÔEÙ!UGYÙhÈfà,iRîgV5 ÛkÈ«†þ³ZOib+ï_™ Jœµ¼Ø¢­¬V-KV”©H2ɦkK’)ï3„ÿ‡¿N쬟}´7 êÏ…}D)ì̈#©Úð“A ZÍ>LMAVádXc ØÕ C±‰­‡±¹¨‰s5óÞ1€Ü‹ì†®˜È+Eí·ÐĶAÚƒZ‚-ÉY &ƒ!xj(.ÓRL@&:xã̃ÿ›w£ú|CÛ®UH0^ä3O°×ªóŸû5œ›ÿÈä-n/ñN çó⬎|ÞüHŠåDLMêF¼6Åb”0äû=¥G“ž„_Tßá_‡Â¶$-¹biÿ DSÞ ¯µoZ’o0 ´‚žöÁèß¾ÜñG£SÞIÁ:ƒÓæ¼÷écå$‰®õ|Ÿ—úA"`} hW5Uüõ€/lâ4µêÈIjUú¼öþÙ:™:íJµÓqpÉRÁó÷°Œ$˜‰,Þñûovbã-Ø·_á—Ǿ6ó¿©*øÌø]gáÞÍ«¦ày6ŽŽîïÌôúœÖ«ÚBØç·?ÊSWQ…ÑéÐiãY#ùDP° QÜk>“š2Ö9ñq™'̈û½\\vFšd÷oX?‹'£/§g^Ãï.ÞÉвÁõµÍÇÍÒ59¢uô%‰‘¢!xËd aü¿P•uA"í²þ]’ÿèŽOÃ=7™¼®‡é›ÎÛðçAà_“Ãæ£2zN7P~M$tÏèõFk¹6Þp™@Ø«e.¡PŽtïá–¼·¿ç/!õ]Ç%Ì·Ê/ƒä®¸xùºŠT^Iòÿ||¹så±Éƒš¥/äŒÍu%ö3i;~–.™¿®ÿ:Dðÿ _I^tñŸAãK~4óöW«?ßÊ}C.ïêq[ü_¹W;QxΜÎ&#Mm¯›Öeá÷1Õ¸ó5ç§ žgCvw\O6¨³è[Ðdž5=9úÀsÖη ã+áz]ð?;éÚü¿’O’NéBy'/È‚ÿ]c:–­îcy{‚ðžB—ЦÿGý®xñôtØÍ©ì>ÏímmgD×jËŽ2™ä“&dU‚ QmÀFó0)†Ô Aé‹õÏêw{k’ÍÙ½×6„÷;ƒRÖ¦ƒEÐtþÝÇÈÖõYâƒRÔ$M?/ñ%àbê2`eD»1êšöŸòž—ü+ê?£ë<Š>oÍ>`õÀ£“Äìs—óy â¾c¢éü~^k -€ªpÿ@ö»/ãû-/z„óZÓ˜oÁ^$ôyä6r:-œ—¼ƒ>¦¼—Ësrâƒ1ÊësX[/ÚúºQ2…¸9s9är×¾S<Ç‚}Gw=¿E-òOŸÙè¹îÿ VEÓ²íȶ.÷¾AKÑ/ÄSÒÄbv™¤Ñuª°—3Ëî®Ò}½ú|Óôµé ÿ騯Œ'«õêĽ‡«þ¼ð/…ˆþ¼¡µê9O2b;ßåò¼‘°ƒÚ©Ï!–~Ë·[moö|‡E<¤¬Ã.uÿÄoOê Ó_”:ï'º¾‡ª~ÅoÇLàöNF‹ºeõOÔ~CMSÆê„²¯™Ì¸õåµrTåóZ ¥«¾,l9#žXá˜&2*¬äÌÏ Š8•,Ú©…±MìôÉ4cUx2`2BL”«+zD€îTïåJ”`Î@€»Ø×$ôÍåØá´¼­›Ï«·ã\þýÿ+Ùæéä~]~»'Ù´s¹Ý6Ðí**r:¸û’Á9µê55QF÷‰ÇTþ_ÃGÑÏÌÙëz®wÇYËô-æ3×§Ö}Zës‰8íjµ9þeSÎîÎu9œÛØÑYÛ¸o¦lŒºr{I4ñ[>§¼ˆqœïúYÞOýb^ã¬^WB&;ŽÇwú >Néß©¾ÿa×ã?r¤¿èÆåÚç¬ãHW[=€ËLÜfß—|qãÏK½ê{¾ñ/iêÉ%>×ù/®{´¥#[ŸÌå㌎»~ÜžOÍsZ›h-†(£c°§+@t}"°–%´v ,Å]†à"]¤:Æ´ÎÅ7«Í-Õz'U…ñ¥Îí²WÂIyQ] I¸FÀST`2€KIý=Q/ü)=£9ëàw¼«µ7ãWëÊêë|bÏ“³|f.G^5ùÜÕKÐÉöpzJ;„]®4x»yéµÒYm¬¬[SþK¿ŒïúõgÕúmð¿¨"y@çRºšïôÒUe÷cȧ²`Tn™~8•¢w´ôóßú*Á«èWÖeƒPÈÿ»¹"8%:vR,*räÕŽ<Œ10•ÃÄo‹^¼ÒGAêÞ©˜ñ®4ú¤Òôž®«^3êºô~\Šò_Ÿ ö_1¯ä|ÆvÓ¯Œž‘|Q³Î¥v²m¶Pÿz°­ß%nú‰ØÚà<‰ç >eloõ]¿:»8†&¿ùÚ>[‚;„ÈÅ‚¤ú‰|}í©˜+¾€4E–ëÝU»ìVtñ'i—ÇÓ’òO|Ÿâl¾Ÿ·G¿cu Žg°Í×Êæ“/³¶²ñ)©Ù#Ÿ–cc޳Z-‡ aiìh®gI¥CŸ«bLJ,œwtw+ŠD¾Ð$ÉÇ#ß ÷ò9@iù‹›õS±´­Qúƒ¯iŸOu|üý+ ·—#VÃÆÌQH¢Æv2¦¨“(‡9¿à»Ê±7«é¼¾ô‰ü,äú¼ô×éÓÎZйþ“ŒóMü—¿ÌôŒt=§iÜçyÉYþ9i<}Š›‘屨7+ á]éÉ3¯Ò¬/E^|x÷øóçKàîÇÄžoð?Œpºÿ4øË»®×MÑ1×e ¯ÇùK“lÀÿëž_wu½mM>·-\|5âqœDlëUÌñ¨}cοE¿Éï>§}Pújõ-Åñ“ügÌx9îZ¼Õ¬ÇWºß åmsñIé5 ÐÀÌCCR®#‰‰_¿ArtjT¨éúÐ4ëI#XLü&Ö«UgéïjXT~'ýE··ÙK1ð¨-qÖ¶¬ülàíˆ5¸âÕYT¹³bž0¦7)¿‚Ê9ÚÑ þ¦ýºCè¬Qõ•ÇL[b™€°˜ˆ‡ä†`<ôñ©iÿ•`…ÈS5‹TCí,Þö'¿ÖjEGzVóR@È ‚-Qµõ«aÍ)ôØt¬}‘íúà6öûË4û&±H=¾©Aþ±|©§×8™^Þý‡Ñ;„Š æf§'ÕöTt,ZJÌY­ y‹ùéíìkZµ©o÷_ïq½ ÊôïòøÚõ¬1jÒ佫íìǵ¢~Ș%ýâþþóïþlg•¯7Ïì+ÏÍñÏöüÞ{F |æìPò+‚~OÇÍÑŸG‰ë1‡âjæ‹a/î±Í«™ýZŽcçêhç¦`¿Hè:isúƒà+ñx`Òb979#3lêê»TÑ`´Ïšm¾ÖRƉY† ÕÌ6“ Î9s0¾2&r¢ù¬‹…½CgY”O7¹«G£ ‰ŠCAÍÏe›;QÁ-ú3ʧOÌÚ¤¥Zi»ÀE ünš‘|¬Àî¨BC‡ãV Fj)ý-T÷¼ 7j šÇ! U°bI0ª9Ã0²ÎÄ–›oàsVG?¯_} t¼qHè]) ÁOµÓ“~È5î ȶéó¥ãž–Ùh%š½¿ë ²ŽÚ f0Q°e FGÔбEM¨KC‘lïy ý€¼•ã!õÞ2ìrŸÓq#‘õ"MüÖÕ¨›ÄÈÛM…K`éé-|ž‡ êMnÄ’¯~[Ö&±™…KD¬(G§àoA´ì ÜuÖ¸™“ T¼„Ž|±óäô+êÔ•1DQA7¶òÿ“zÞãªòQØ—w³íôt]&ŽV\?¬œ!ÎÅÚ§o§óáçˆÐYOîTîË7¿ö:LL4ËÉIÕ^tlp]½‡q›`ZàŸCîl‹¦‘ÔÉ1tÙò1¥Li ˆ#}Ú}ïÜï}í±ñŠ)"ÚŽ¬dbpÀ=tÚåSÉ]€ÎÝ-l7vÀ®Â˜.壼$cBåÓaëÞËÑ®hާõÃeBøfÆYi8’oøC·§›ßÆÞÎðEê/¬ð^Fƒ½¹Öåõ™øÙýÁp7x,®•~º6á·y-Žºœ_ú7\»cÊOS-¥•ËI]„f­„·?,•7 Ådk#Q(±W)- !V¢¢rØ_”Ä"•±u;$WcomœB0«-Òç^f9 ö«Tb„2¦€+:³3¢E²0S !P’Ÿ69"(ìì’O¤Aö‹Ûº¼ž×Àù“=E‘J%J­éúê°aM·pòkÜEù¿ÏR‹G†O¤_Í[7wk·ñߎ»#df÷0ÛŠ“oÇ©³¢Ÿ'°TöóÒM}ÞyN3aô퇣”*7ÖçÛIqÜÏé;Çý?hÒíädþ¬î{¢¨Æ¿3›LcJÝ>ÿöÎg¹¢Í,¦šÄ’˜ ÈÕIuÙúzvàÖ–¼‰Ïat\§?侟¸ü™ý®OQ¹•…Ôf‚šš{yi,¬¦±íôºáœ Z#`Ödqþ#£ä^»–&‚|}ÙsJÞ¼‡²ßɳSxfæ&.¶@md®š¿¥h=Ðxsìu—o'"&…V?Z2ÄS21$,+ìŠ-óàðz´Š8\ç}Ôxù ›><²”Yâ")]ɲÐ8 ·dóWiXž<Ö·aäß0 OœVýKŽÜÁ×MÅ×Åñdª ð w6cOKj馀%~†Žðõ)®/ÂGɘžž|¨ÑÌ' õf­¿Ó/ö4ž'öçU¼ÅÚ‡ð×­Ï ŸZê©î|!ë4I`w¯?õfØâáê÷kúSmVh¦Þ *â£ôÑVh6„mA4´fÑF~e½©0öCÚn+O.>è3t„ÛÄ/EÐÆ{ˆÌý/ͦ‹%®‘ŸÅÏÑÏ[Ní&³Š!$¸ßRJ¼¸Ì¾ƒæV‚x2Q÷3ð( C‹%˜x×ÇÀÐä1¬ø˜…#H•ò$U3cã²JÒFƒbúŽâM„h,XMïJÞ¡¼…‘ã¿P>˜ñs‡«ßî<Œûÿ×xßiÜ¥¸öspvDÖ^®7µ‘3‡¤ùÕÍ•¦‚rMAü)Q’ìM3 c1QüCŸ´¸¬j «P„\ƒ©Sü|s|ßUÐX…åxý6V÷:„xÉœ)žç]°Ù[4Un€žeZ91qä…QÕf¥Rbî-k>»<8•}´¡Ýè›B„,GùGÇãÈù¤Ó4M;#*‹1ãŽ(æ}¿pìÇ2¯”O¯®Áÿ˜þQŸzzôGÀúõÀw•8xan—ÅY¾eðnŸAO1éuþWò ûÅ'o7¨rú++ó[K ¯ä{Do$ë©ãÕW{Ûðžœüéó¼æ8¾ÇƸ“¾§ŠËÕùïÂ^jò7‚: $bu}®ÿ¡éûÌ;fÌ[½QE¼|ê¾Jç÷¹ÝΚ÷ä!.¦ßʨ­õmÁè²v¯¶ì iJê4‹&Yp9"XÎ&a4îqÆ+7öÐÑAªA7\LCkiiêf¿ tx®ækŸ=Ñ;™ÿXÈÓMS׹ňµ,<¶j¦þ×èÕ²²ñH`âuÚ'·¢Î÷@ÕŽH`TH 8£Pp»oCÐrqpr²4ÿ»ÅÎÈÍ øs.Dz‹#Ï7ó‰[cY Š5Ô“ñ§©-zpê<ÿâù!ykî¼Uå[ œþÞiãí|ýn}žmmŽv4Œ0DËÜå4²™yXGPo·‡ 5f—¤ùKËžTŽ3Æ^'éüŸÓîxã̸9|÷)Ëïo·]>“Žï?Ï/aóê–ù¢>ÓµU}rgä&K†uÎ̶‹NNŸCÇ–ÿšúŽwÍ8¨q¼çsn_kÁ¾+ëï¥Ïu>ª³‡¤kùü²¦÷Êñ¿ Š‹ý—•|¥½£™‹Çqâ#¿»gA –ä÷›gÔžNó„= 'Ös¾8âÜäºfý|uãNÃÅ<†—ÖËó—|^¯!¥æ¾WÊWy ¿"zÒ×I¸žÃÈNèi©é4 b}r93ÓK|I~12J²ÔJm<¥T‹÷)'ñvºÎš˜ý¹'vãê|Ø+Ÿ¨Âά¬ðf¤K2Ç$1¬¤&YA‹†]D_t³¯«C#Æ ò7¡^ž|?—«æ/H½¶"“}wµËùK£ÎÒoö·±<¦—ˆ{®÷k‰ÉW5Fw°åùi®‘É€1?äyþ5=y;øàóßCê Äü§Öw p=?‚‡“y¾×¨â(¿dç>M¶)“ÆuŽÝôHž), ÿt²E0+fäÔù7¡hÞ€¼Í¿âò¿uê“Ì^™xfKã]¯-ø’Ù>z(ôÓ¹½‰äº“¯Ëåz!k󼾯C™‘Ò±Ö]œ~9‰ÆÌü+±r¿ÏƧ¡¿6ß¯ó ž£üSéã—áé“©çOp¼-åVÇ»¯¥ÈxÛ7¦Á[Ç=¡ÑØkœÛÈKN;¥ÂþºïòZ¬:®xâwdZlé…†ø²êˆÓ·ÿ/&|*f É*0v Á…yè¿·{·\Ð_?½²txôýI:ž—.—›¨äçv¬n¸˜ùí$Oè< øí>Ÿ#I©a¬Ñ¾LJ§ê |ûë–ÞyÀ켞]N'Æ–¿— ÿ3é¿ÅüO—9n;ˆäIÃs8wÆË#ÛÌC3­è|Úüi|ŒøKÖléé5Ädrt\ˆÌ¯úÓþ<´=z€ä=SîyÝ¿9ù—Â\O'¢L.SGûe7ü5‘Ît<&?Š÷…È»ÁñÏwßÁçy ©ë§R›œ¨÷†þšZZÆØ-8úìð~Ç¡¯UžVôϱÔ¿è|X×+ï2+<ò}Oä¯qÞHÇA ض¥nÏÀRÙË2¼P¯A` …‰ö±±2˜â£qRPÚʱQ_\PÞ¡›Úú¡³;‹7>(–ÇMÞDŠ-Œ‘I’ÌÍ:•Š•K"ÍñÒZ^²¿½ã×ðÏa™Ôô^|àïßpž:AèfjøÓ’Ö3º¹]®·JŸ7ÈçõOto™w:j—¨ØèˆLõQH ;%ðG?3!œ»^Ÿ<àây;•ÍâpTΗú!á‚ º·AÌL «è!º.u¿$;ÒgþD§[©Â3È¢‡¶ÆOEG”òµùÖ?Þöý36ˆ.Áç Õ¡D‡óÿ²Óhec:¥Çjè)¦~Ù‹«f?™ bžõ‘äb+…¨¸…O¼×/-/RQŠ+ä¸:«ÏëÊÔÂ}’ÎÂEŒÇ¸}¬CH‘Íób^Å…G™žæ)NBǰ˜”ŸÐÕ… e¶¨ |ç®Ë|}üéúxòÿª/ùOÎ|w‘=?ñÞ9à'#¨òOƒ¹>a¾ëW­åø^·'‡Tù[1Ú(ùlra`¬mlÉ54t5r²Ø34¹æ¿ä»Ë~iê8ž«`-ôEñ¯’—ò/,ö³R»é»sw=.‹*º}kèÔΠZÂÏZ¹k7ñ^(=[¸hÇU’,ÑKT˜HíÆ‘jÉà"'ÕôžÁ%§òÖBD}³rV´©B+Zk޽¾¤†§•&Õƒ¡€ Ëåö@ÇUÕ jÍì0´cXÖ=Ü t &ICØÖ‡[Åцf14#£ÈHffVfphM–° þöz‚˜ŸOñòBÁ4’ڤ BÛ·ÁS_ó[À$ñÉ»®ç¿™/VüN×n ³;ºÄmô¶”ÕHñ/>g—çØQ¦XÇžsP˜¼v¿J·ôßh1Ť^K®Á_3ñ<2ñÇòMç?ñ|w9ãŸi·Õø§“ñ[Ý·^γ–æñ•ÇS7®ñîº>CÆGy¡‰Š¾']·¦–Î&§1`dG2œ2ÖÎ…MºÜj-F Hr,R‚iy}MB¨âkƒr þZ;7£KC¡’‚³rÚÉ"èw.QØ Oñ'½èzäcàÁþñZÄ¥‡bA¦¥l2Vÿír°O¬Ðï «ºÂÎñÇ"1t‘E˜è4aCT‘€¯ò’¶C%E©v–!ˆ|؉ ñÁü†‘D‘ÉLTá^5,9€Mõn½gòIê÷É= {»{|²="Þ–¼yé–nNvî?…øO(ãùU\…6ØpÐoÉyËõ èÁ‰ŠKÀrsyܬ%QÃÿý¨o1v¸º¼‹y¼6g=»lî°§Q'®Ý¶ϦÙÜnÝ© g?ªa½@ÅAU]Ö詆D5ÝÀZ¼ÇÑíÊö‘ºÄXŸuÜ ·r\¿%.¹ÏôÕ¿â— ,RX¿­…hU¯”c_¢è½M]W•µËK®íojVµ, 2:„U!,°‹?öŽIq/ Cõ–—¾œ¬MfDH†l±°™GÆòUï,ŠI¯  U†›ÜŸ§I9M+S 2´2´3c©š¤l”< Ìfq«¿ƒqž9õÙç¯zMòÏ£åüo飤ñ·›÷°:^ŸÈ¦/q©ånh¸ŠsY\¨øíÌï,æsYø$å+Ó×"ü–¡­¤N¡}iÔÉqœ‹µ|3êÓ¹ðÿ‹ûÞ“:Iï¼­ÎùSWÉ^@ç{íŸ0ó[œOGÈtcs]–“ñÎäŸ=QÒÂcœÝ)è·_¯xAÑÉ©¨è·íoÔ=g~t-ÉK|+$1„É Q‚&§¾°ÿhþkc¬Ðwûï+¹Ò—D¿z¢±i£ö „›Ì}Ó1Jü’ýƒ ÅŠ!Ðv–)HÝ·š$“ ¾"4¬²ND¥ŒGxyW’ÙSD8 =ùÚ¹I&µ›ñdA“®NÑE4iJñ @c)1ÄR&PÑ*ÄÖ„¯]ôÞ]Óõ´T^­|ÝãßæyÁ~ ôòÇ$‡Œ³|£Ïršç/Ÿ|GáôÜÛÍÕî:6'm ^Ã[gö›}<òm©‰GÓØÁs4F½Wˆ¸ž³Šõã&ûà—Ÿé}TyW¥ÓÍÉ*èk9¿é¿Ó¯“w¹Ý•˜7:âÈbè¯×¸u ½6j8W.ÞŽðKÒ/ˆü‰Ôx'Έ¨:u)æ ø7Àj¦]&³SwJz¢ù…[½;-åçÜûò\á¹³iËͺ¡A[Zv%ÿiè¯Ó¿'ä¼O:çÔ—Ïs§ÏgœozKîzkPÇÉíæ-ÕôV‡#\ÙZZ-X¥³PqÒ°¯9ºµÌÔ´í7_º{bk9pÿ‰Ã‚ˆÒ>Jâ6 Yl¢œf•a@¡o ’Ý1±µm;UР—'³“QÑ4Ç:NLàä阑ï–Eš8”Ë<-•1•æÈSé´‰›Vªø¿$›Ç>ó¿€¹†¿è_Qóã,¯(«)äÃ{Jx“·_Èxè™Â¹ª¯Ó¥}£%€N3—«,X²!Êñ÷[ܧéB¬ûIhkV¤¬EEkˆ§GžÔÊ·ÏäÀDÜÂÄÓzXËÉúvužOSiþ­ê¿6.æž–úŒ™˜jol/‚ªæ HÌåõØTX澜‹OD¥AP²ò,*Â@Rfà$¨Â$Ý 1¤M´-Vꦯoú¯ÿAÖ0A¨ÚKfU™—ÞT1­»W’Äï&º]yLîNÜùÞxã¯Vî¦of\yÏít2‚ó+„ ¿X-kº×LùŠ7M;´…ʺ¬[=BŠ<ÒyC¬ñ^C çsüÏ”:§3¬j™{ñ™êêuoéágè±°´demeè›BÙŒ/£p¤ûuM•Š š}ZÕa¿¸–`V÷"Öê}u¸3WÞ쀈x€®"°VisŠ–µæZzaæõ9Ûö¾d»­WÄ<×_¼¥Õ#ƒ ½–÷&^{1ÕsưŠ›MŒÏÕúÆ3áÌUbë £¢5Ü:ÙhÙó`J˜ÙÒC$Xr•˜³²ÁƒAC«<™,ˆ&Àj³D=µ¥ýoN‡2)Ÿ2#RIKDÜËB¡¶xÚœqR-‘DSÈâät»8!%þæB. ó¡ÑS/cEÜ=hSÂùL]1IŒ]™TGZ&TØM!¯ ÎÕU“Ý_Õ+I¯,͈‰tÎclV£$ Rήѭù®ÍšuÅó¼´t]&ËÎ_§ç2ž}ÇæÑ#“ž¾óúëþ–Â]×ðÍŒ¾È%pÙâÑÔ·Q½ çd.«.uÙÚÂ{Ÿ%ðS›ÅÎ/=wŠO@zª1­ùÍO”kä?Ðäà9Mµœw[3ýOtʃ̄5×ÔϼƒJȆvåL³4Qœ‹‰JK0EI†åCJ¬J@ÍõLüIžrØ $[‡ÛI½’Hagv)}¬ñ U$Ý’> ¸¨n7d`Ï\ÙšL¹©m’ƒÊpãNùï4ë2’왢R¶Ê+Q ÊÏÆ` Õkq£–…TUPÃúV!C¥aY ©Ø˜ ¥`ÒÖ(>¥ K™¶ õ‰1Ü?ÖÛ©uÎþ~^OŸÙ{1@}ͤL³Yšt lçô`nÊhKLÑIHÆv¢ k^bÖy?‡·áCwýaR7FÏåyVs¯ž"µ›˜ùº"¾›DG×;e¢34-Ý“¦e˜ŠíC#3LûgʃÓ+6¦‹«ëJ»Óz° HˆX°ã‹ ×Spp0udÊ *xò0°¥Ï– ’&Y¶J–K’5¨nu®ôÐæÌ†ºI¨ÈvˆÎN^…+”ö'GHŠk>JŸú}'Ö––=Ì4TÖÌ-¬U2®¼Óü1ù#ÓÛ^<Û?EÝøá«ß–ñ§N«œEƒÑ沿iÆäõîå¼¶®™zÎûqÞ@í l.Õrõ„ ,zcjøsQûœÊÔT»ZË_%4À)šÞÞK†}ñ¹j² Óô©ð£PÕ†¿ßl'HØ3ú=.‚½ûmzcf¨Þ è‚©ÅôžT³óçùC7õ®2Ëià8úC#9Q°CDh‰ó5 ùqášjå5èöÅ÷—èóÚ×¢ò«…àô9°lóysâÄoœÉÙj¼ó¬:eÒÝ:‹\´;3âÈÎÛÓ-½CtÜ\Ç’9ÎSÈ^^I͉Ëé:\ð£þ’ÁÌw™›æLƒr¾b@®`uÌô.ty´ý #fTÁC™‘™pȹ&DâI¤LèHRWŽ8[8eÿ‘ú¦Ÿºs ¡‘p1XSG†íެÀ€ŠûO¯1®7É9ÆÎ¢'¨O t~Îk‚ìó-MþiÎY‹|4GG¹®«)}Ài):«™ÉΉҺÏ5jµ˜]ÌÈ4ºã$º5z,éüUäOäKÄ·õ]Ô/åïkõÏ¡Ùw\n—wÍ1ÓôœGoÈø—½èø7Jís>PÔæ;í,Ý)¦S©ä]®·4ØMkâÉÚ^]ìå6›wRsø÷qw+`+¾Ô›Ö'™±÷¤Ï¿¢<„× G(µÚGí5“\ó<¡ŸiÏüsrS°¼CŸÔet)GÝäÝ,®£!ºé"ÇgÊøÊ»\ï šPƒu.¯EÜ!Êe|ÐÐþ÷>›Rà]‘¯ 3QŠ ¼¥ÍšÏh#@!;„’ Ž™Œh6»Q"„È8!º¹]3]ÀÓ5}O-t¼]'?<í¹—æpñ¹\ôÿ㞬ÛÓgˆñF‹qùþ;Éž)åQ?%Å«^W›ÉÏê0°oµž¹È}+âíú»Ð꺡ùcºñ…;müŽ+ÃþŠxî× çs<½þ­k'ˆéKÛ;†¯¼}Øåh ª¬ù;£é°ŸCk5íuYR%¼ÜíBÏ•}7ùƒ¢ê<ã¯vèu¼× /5ð^pÌþ·K7šé:ÎÑ7Kãêtjæ7[ÙgX*0ý}6xcç=óÒ×ËϹwÂqËù;ÇÛBXÁLw¨šWi¶nŸ>¯¨j ¢Ï y„¸Ð žyä‚EÜâ™’N7Ç,*¦·íëoáÛé&¯Ümôý5œMs²»3¶¦ú™¡âaA¥äWSÎË*ÓjxA¨jxË»2‘QšL&ÆõcN·<•á/øÃ†òÇâL O ù³™[•W©ßã_S^ó Ýww+œG™í˜ßñZ½"w–èsü––.¯iÏc×S?ªQB:ƒÐ±òöO¨óÇ(ê¾›ý;ítî=~ cIž‘ù Ä<¢\çIÏq½*‹/¡£Äù?¢ÃíZÒí³®‘TÜÎúôRÇ[Ikõ¡ê¯ÌçñüUÏø›—ïqty‡™NЩðë-ž·iÓóû=-75×S£pQ¢ í$Iægh:]zm¼6_០ÿþIcÇ^¢–åüųêóÆ&&Hk?È'âîÇÄ:뼫ÐõmšÜÔÌ{o¸çy.o?''e»_ĽΣ¦P™etñûAu\®ßÔ²²CêcJŸM'"ty2qæ ‹6D-#å´’"Æ’TÚ‚ «[Ø?®½³Ú8Çôç*VNØÔ¾£i=Á¿ƒ‰o…¬cljšrdéøÓcK‹…“<²Küü™2!I®l·†ÌpKù•ëñ}Du^–=WrÞ/Tšžbôá‰åîó‘Yósý‡—|?Ûù'Ç5«P4—X{á|iYÀ¹ùütŽ&‹—5¹)÷È<¯è¿ÒúÀò?nÄVßSÉg3î¿“|]Åù[ƒÕra•G¹Àoîô1éà÷^Žt\üP€Êy·ýëÔŸ…úJþðŠþ97†5üuæ*N÷‘Êò'=¥ä]o*ú™à5{üMõøÞë²6ñ÷-ƒÅåcóÌÛ“]ü[o·†‡BçgÓ1¼5ä¾Ã¾þ5?‘-`!é‡8\eégCa]þIì¯<êó¾Uòw’qvØñ üâ%æY®^Ö8¿gnÙI=Çé® ¿Íj»‰ƒÑ;°3u<ÈñeM06Xa™2æe†H¹ À=æXYŠºmµ2³ð‰c‡²;oIí,ð}O¹'¸´}[+BËÒñ1W/(sN6d:¢’²Ç9FÍå×t[·75}ÿÕ/›€{¾ܺðúkQyÆÒа©°ýŸþÊ·"”ú-œq$Jhr,íÔ åzT£ZW訩+5S³‹Í³‚ýVš|&µ)=`1`’ÔÕ7±¨[Ö¡èÅÜ„7ü{÷¾ƒyN/'ŠÅÒçÙ##éK½ÔsÞaòÒ[jèÖߕ˜É"¹O´î„êg(Ísó8üË熿?‰G/™žv¥èûO[AU–dd_AæGp‰MÀ&TðAKµ£žû–!A´_¨™”šäyšqGÒ5‰ôÈÌn0À‰$eƒ!¤‰ã`|[yµ#®ˆî_áëJªݿݘ™rkZ$:†¢“aY“MÑ[iþ&ÃR•(Àn¾ UGx’Öl;Z r_íûà‘ù{›åy¤_ÚIz±kEjD}…!3ŒE¤EmOœí½ØŽcóȇï?W¼.;[툟i¼Ž´˜øÌÒËz¢Lš;DZ¡ª“«£T*±Äo¨QrÌ~ZÖJÁ¨°)UàE«3i©íj'.•B2ݺ^,ÑGJBÁ mX¼ÞÑY¤Ô±jŽa˜ŠS½[†W‰‰nDCC íÚÒFŒíÜŸè+óûX듵û<¹ G2˜¥’3!+znSr¨$BØæ«úßI¤‰,’•›ü&á,×óÐu I{†-[× ë6fô$}c£òÖ¿\š"sV Bä¸QÄ/ö@ÉZ†òAÀÈX›Ö›Å'è¸×+_Äk|áL@"nr-Q.È";š’Z$XIV©6bë+õýe%¯÷ ¨9.ØôbªóK$‹}#¡˜¨äRJV/úNÂÞö ªÅí0qÛáKÚ±I íPSv ÙwÿØ~×ûu^3¶ç Àr»»ƒóbüÿøéíÊ ^•²Æ£µ~~ÁÐwnY° Kœ·ks ÿ!ÕTØvª‘U–†Å-áøïÒ“•ùB¿õŸƒçpë–ð† ØÖjà€F¥¡Œ²œëƒH°©×Ðç‰Óóß–·¼CÑîoeâ¿Àt=y2 3;9»8$² ÑÁ‰se¹¼:Vñx«6->sLµ®_ø¢àPK/GOÈ=Õ#è\ý¯\{ìUÚ4µ’Y#¶0þ²¡Üj´`8T<ó¬ÊÉ}Ïõ HíÝKü3SÊž,…‚<€°âÉ(1Èû+¯®ì_¼øé§Û}¾ºÆž¹‘ňÈÌÑ·«3#‡]–H h{…lò<ßTŸãŒû,}§…[·%Ü}F ­üœŠffa“µX‚ýͰz/÷.»*°+9L¢|·,¶4˜•©¼™ Q0%æŽå^ßQE[ôÓÙŠCK™r«28Wé¢×ež‡ƒüTxdˆ>7»îÎZU¢-lžEÌ^„*ë8ƽÇKA‘¸ ŠSO,[õh꫎—Óÿ¾ŸÖÁ>ö§’û´¹¼õ5lCæ±&Y°+šÜ©'‡ÚœÖ®ˆ_YPû=]!0Ž‰Ø¡J!d7ÕÎÛfEûÍE÷p¨¸r Ì•S´r¤rS ‘Ñ<]¢ñ¹ ª ¸fÚ ¨ÜÉ5C‚ÀŽWІO1³‘à¯zÄó7†=,ysÊÝš1<•; sº|[ÈøßÉXÞ{μœŒü­Î«5•:ÔYŒŽ’ ;EÞÒýâŸWÎø;Æ}'O®Ÿ¨õ{Är¾ª4p‹ã펷gc£ì>S~1 <ì*âf“O UÎ’r•?QW‘UúËž”% Í™ËÅÒv;¯üW>Ÿ#ǨqÛòzc¼nÆíZ1¯uB*¢Wиo­­T,¯xf4~Ù%ÌiJ?µu ¾ëðúÖ¯™¨`â¿m ? ?9²†¡þ7M ÎÅÌ—N–-2p™C,qoh÷Å}4'×ûefËÒt90;OOлkZÃ}vhõ„Ö»ŸKÀHs0ÑbÃhò±Ÿ3L0ó™±¢‡ y+O¨?-s\g‘¼q…ׇ7ÆÞt?"ç–ØO©6¯7ãNí^÷Šåè÷ÆßmÍó¸=^r¸n#¤æµw@W•×®Æm?!~¯×t`ºj¤Û4ëEÛ—/nVø´©–úÕ:÷ýt\âÔ×tkÒRÙH—†rê¥f¡Ÿ@eõÍ%Ñ5Û·Çf+®½@\“ ]ľzI¢4¦°+ZltÊó·³WQA—(꺯DLk'`õþ%9lý%2±=@q•³CmÈóöÉeËŸ–Pç1—®0½P3€GLp£¨µ‘Å£!œ.µO¨½•£ê9zTÙAr±dh¤hñ&Fñ*€duB’5Qr¥•šìþUºv‰«ec6\ÏöÏ‘!›$+…õKäÇ?ÊŒI¸¤jŽ2©à¹ÔéœïzM¤ùôM×mêî›ú$°óØÒÞíÏÉllpçÆýú.û)ÎgªÎ‹î+Q‘#»ZÞã}>3ªÅcóks›ùîí5Àß“¥ò#DÍ»-ðÖ6Pp˜»ß“e¸òÝ,õÑ<:þfžåfX£Ž_VFv`NÚE,¶IþƒñÖæÆ§:ªif¦Åõ…Hš“j˜îeVX¹jóëÈà*q/›sÐiß6Í…Ilóç+x”þ8ÎÕÞcÊy†ž9>ãŜҮBbÔ‹H×`q´i(Á•™UÕÇÇM¾7x&,!Iîé/+}G‚ZË0|¢+BŽ^ÁbD–¥¥£æJ7b¨vW«¹zíjPk«,ZÔµk[”·$b@ âÙô_훑[‡R¥]8‚KSHf–Ò« ˜™Ë˜§­¡*%«–_¦P²ËÉŸ¹“%K—ëú¥Êçã/Ü.1EÚ6Wôäl´oyJÖÌ Â;1G%$ÍNq?V”¯obÔ÷XuW>Á…±IhJÇw‚jYÉ1áK¥zŸŸhðCy"ªúŸŠ™Ø±d Ä’9'±9NŒ¬/àþ¡"úègɾ.oøüæ<°LÎ8Ü“>yÃ{NVg<-þg©/3~¡þs#ꓤ@ˆñÃ÷7ôZ<Ý3îºãÓ*¤JÛÄí¼t?J½ç%áw»¾ãËXâÚäqs˜Ë]ossÎn2ÐÝs £]–´’X(šÚm+"wÄÉ 4Œ8:.mç­Æ@Íâ€j‰BÃߨ™ÑR¨:Ðñ'›µ@©eâY4Ô-ÀÃF^ÅnÉžÍ)!F›Oëi-|Óœw±ÁIù²³`¡¾êünÇÔÀîgW`ä¡%‰1Ip=°t]"œ|=C'%æîx»¡Ÿ&d-ëcL†-= “!ÄYÀ™TÇWÓw.¿’LÜi'LÉÒ=8ã‰J®b«Ë «qÚ¬Ì[[ IèëÎuìqŸÑÎvŽ~žVV¨uÙá;…]ÆHæ[—E&ÂÕHïݹa_ÂÓ$ ÓûÙ}ðuµ<…’¨yµ™m6â]IŸÇŸ¢ ¸¸×çß—ñ”¨9íZ7œ*Õð$½R~ÌëgÖ>QêðA ·\­uX¨“,ô+R‡Uo¡ ü wjÝi¿ÌD¡é‚•°A¼U y–Ø+,t|hóǤÅîsñF¾-¿»"b—ÌŠè¯c®"L"V ýÒùÍLÅoB´WUËE+6$²€ÌèØò‰ ;6ã¹XØK$€œ“@Xè-ð°f aÏ9?ò'Ç’1\_óãyaü\d ¿Ü'ô]KÓ¼¶çY±­¯­¨°èΖBóš*&šÜÒ³ ËƒÚyèeY@F¤¸áQ¬™Fõ²æQ¢Îäyï ø÷7H°>+¸éY¦‹— ;zîl—úe"­ `”ÿp¿þk°¥sH°É *àñ¯QÇ%³ˆËO?×°Ç'å¦B7âŒð+ý³IaWòQü¥ øÚÓøbEñ_Ð#xey‡¤ÇòW’w:nnÕOuC›”S‚Ê–A’AcHìw,½ùßñ‘´åر4YMõœÔÎÔ´´UœãaG“Ÿ’ÒÄÑÃAŽCå²ðçzü–ÑåtÞ.|ã(nÀYn$¶ÓV“À‚z±*Sð€_Õ=ZP3ABÐt¶ÇÓ¾Æ=*98lSŠ…L1Kî f@ÅVM§s9*/ú™ø3aebkC‰÷‘ãecåæJ]Ff-‡•ZÑïËÄ’d*™Ä £Ü’ŽoLÛyåù½¶ØÖ¶ñìž^‰öq×Ô®’ñƒ/‡f²]]¥>ˆÂýÖ^ØIƒ=Yl>;0çî—ÏGûŒ–ª=’êwyy‹¶<îl-RÄÍaF¬è¡“¯©åñijêÙg²‘oyÓ§ÖL˜yy\þjÙ‰ä¥ý:r²§¥ªIdmÊœ¶j×`ŠEmúFKXÐ^ÿŠƒC\³£ÌÞû‚LÐÄ¥˜­L_éJ’JÅIdÍíièÒcVÙ§ÈšI›•Ý…‘ýÇxÜËéÄî8pKà–YÇÓ´lwÇF·”UJÒLlTz«1IäL¤ò7z¼)»êqu¬9ã)ÑcóXj#Ÿ­l†j1ôÏèÇE\Ìüf ÕjTpô+šÖ«¶Î.›hŸ-úƒ øÁ>WÊ}7;„†–N¾øz /"á÷œêV{8\ž~Ï<â,×\Øl‘W‰¹s)”Y§ÍY¬ðþvßvP›kÁtÆå|}Ô3ÐÙý÷9ÐoƒÛ7C<€w]¯ÉÎ{Ä¡^L,M'DHa´”N…TîKDÑŽÇt‚2µ¤¤´ªelÊq6øV‹9¡E‰Z¼P/eÝ “œ6EèÀf:E^.«¡Ï9Óçɇ*dóC´Ëd2´§rØ3´F‡takkúÎ\ŒHðc,ÐâÆ¸øñz²*ÌŠRrÞÄí¿Ø/ž»?ñ‡ò?é7Íþšß¦Ï #±ëhÊxߥáüOÂøIÍsIù¯y‡šòBÈA-Þ\^CÉíøØãIÑÊzyŽ•ZÒ¿:Θì|kâF=FÑäzΡnv€Ù·¨Ç>OÛѬvîN@Ϲˆç+Õ‘ÆôŠa[vôÝ¡xÄJ! } ÷·m}8}#[Òåï^Óú™¤œ½\íÙiN,‘#zW¡AsòO3¿©_R|¿†·<òŽåqù¾œ¹pZšihsÃæº¾¡%²´5#£ÓgG[{«ì:m<Ú7ßÕcŸËvo?‚ƒ»ÒªÏMÆw–Éæ¾3ÔoŽ}F÷Íò½·!ýŽü/äžò|fÖYœÑz®wÍÜç…¸}—{#ñËmóÛ½n,côº©²:n(„’kÿ$šØKÕó$øÇkOÚn.ö×S amõùÙ¯s>SÚ̓çy{¢æÕÁåùÍtÛ¶ÃÐó&šm;£hkŒ‘DpÕðå®CÏ É,®»•Ë¢#(¤Æþ¥wŽ«õ/³°5=_RÌ×> ëº¾dº¦½•!ÊдyâldÅÃÒž l6‚K•.6NFfA‘«ìš1$ÚßÈ?™y_.zÜëºÏL£ê¼Uá_ò¼Ï‡|2–ñ£/g–ç|UãrÝ€)~]VQ»Ô¼Ó§Ci:Ý/ÛÙ^‚üº¦af¿r£©¶~¦VkŒ¢¡Ã‡ý®ϰšº”Ë Ÿöë ª¨Ý³h¹4*6FKÐæ#bîÓu~hO¼è——?5ŠÌÐpW‡pâ÷¹ÈR9#­ˆË,ÔÍLT¿¦ªŽÀQ9/öÝ31L,øÚh9öÔ[3w-»‰Eéc5þ“.¬ôíÝ‹²¨©™,Cë¤û CéC¯f›Ë”1#XŒë{XF¤@Ò29àSI´'õ´òk¡Lx}g‘½gõþDAÆ.ÇÄ»{<ªû¼Å›°#Üë:és‰ës`¬üžÃZ» =C©œÞ¦QGuêæú‰¢àkã¶µøy+0™ëÓHG´“íñvi@±cÕLÿOµ<ýw&—<9سåçÃè†(ÈNJ®ôÎfŒ€¢@›XÙ25±r“í*ŰËXÍ“H(#†kK‰r °Èé I®¸ýæö­)a†J(±`âÒ=`´,Ød½þ>ÁæiR”òqÌÊñð¥ÉºÂúˆÁêÖ²ËÞ:Qð÷ÿß(hñ#î|çä<ÿ»§Ïãnƒ‡B€?D•ôóÚiî°lÊèS7G8Âi¯“ý¨DÇÆ¦°IcA¯ä+Òèóˆà¸®tóÓîôšÏ3¥Ñ:,Òh­ÂŽPQýZ™®Ö£½r³©vìàê£Z¾Ð-xßS»gPÖñ»OÉ|ÝFiš0°Á,q(Ž7‘™ž_×ú@2PßÇQÛéž¿‹¢e÷jAƒ‰nÊÙI34“E(D6-¤óû`ž£?ñ÷äÛxƒÔæq§•«µÎ+‰ il¼æô ‡Ì5|¤4·ÜpnÀ³’zsìÙ¾X h‚´‡üfìŒÄÀ–‘”…õSèDs¢É²k˜sTkÏVs¿QaêT²KÕ¤FØÐ1ŸÆ×9Úz7ïüü÷ÜÎËžæüªŸ2l0g_£s¾ât¿µÌìñç”bRc×ÂKw ‰m)ôû§¶\æqtqØ¿KÝG¦¼/)öôµåàv¾(^o–=7m3ršúþ ò*µê²‡Îæ42™ðo”Çä¯daÛ7­ãqø¼FöG›¹›«³þ-~³vôZž}Ý£K÷-¦K‘…¬lþ|pÇŒá¡Sá•ϤçÉ.8°z$ì<Üí' hz¦ã Üxs´æ}hòQdf%±fqÓüüþÝ;‚•þzeµÒX¤2ƒn!£ „gf¶d%^cuRc¶SZ†*ÙaA†Ã¢j²(óëxÖ¸ú+|Äz s£Fú—0—…—¾­‘`´hŽF„Ü Ë©H¥fˆ‘ô†´¡*3pobµ–jŒvy ´ŠIIX£§)R¶–šùÕHå]7U£èa-lKèiÞe†çi²LÀZÚÖYm f¨«hÓ/ÙÊ@èe:Ý¡êêÞ«AÉmÔ®Htß±ƒûy¦=Bhý9¤&cq,LŠw‰‡‹`$ÛïjžIÛ¦ÔQ(pJ[r7KDU—ÁÜ-H_[pNnd›tûËÎÁ°úH§_úü\p7rE/Ú |ª€ÊÈ@7A£^¾/õwåÏO}ÞNº¼ï]¯!ÔðŽr}7>Úa‡u4\Ö£y™›«¯ÕcôR}E6Ñ ˜ËéSSAñè6ªŸç`ö”š¾©ÛÓÏf‘ªæf`BòzSœy#ÉxDa3J+•Ȩ¢‚±vÉéa® /JÖ1÷A™†¿pgu ÏÌ&-2¦Õ%T8Ú¤Ptàþ7È™å[''=î?)&–uXhƒ-¢`+k%…Ì3‘Âç¢ÎVxÕB@ÃÁY]7Ÿbǹ®C6¥ l»ª ±Žg¡{ƒñn])Ÿ¢píÿã…˜þ…uÄ›U‰y€¾á±H*&3x¿ÎWªlò4Å|wàV.c%jÕŽw¸›4E•lüÔ —"#³¹äa«"EXöÓÓQ†)šRfÖPø#ù±ó§“ü¥Ëñ='1éó-½Îw7<‰ó¾RKÖ:Ææn4ކwY¬©:mcißC3OuÌ,P0Ë—S ­fi C«}-ïïG/8âiѬQdO <8È@.ŠÍÀÝF¯ÅÙã÷Æ…4è€Ë¾GTMøè;²¨-î>‹;›÷ñÓ×%4õ}|zo>ˆ¾ª)¿ÍÆf}”Œå/›Ü­ª„Û÷×+öeß=°:=ÇåÞŽ(ÀfãNŒúE[.ÛöJA¦”û–o¬tˆ –ÀS‡ëPU¢µ¨‰jŽC#›šô±ËÒò+Êåâz·ôÐÈtÓ®«ú¾VÔ5KÕ´–].}´ôM%AD‡Ô޲™ Å ¶=Ã+kÖ@,rd1?AÖÆ·ê ˜tÛt¢e,š©/1›ùÐß\Œ2­ SY‰?þ‰5jÍúS©ª`éòM±BöÞwoñmUޞ螎ހ|‚—ï<øñ»×W¯Ñéc„<Õ:«ÍÞÛþŸ·RSÓ¥mo>ƒ¨mme[˜°3®,NG°Ódº`ÚE¡²Ê­ Bâ#lLÞrîij¤ŠŒ“óI} /#¹µß¢ isMW4|fLœøipèD0ƒ%¬¯/›$²U²‚?« 1ð@Õ7Ížï» 0£„£¶W<ƒÇ®>º$œÏìõ«‹ËëëètÌ‘5%¤VÈÕÔMªä·²$¨&?ªÌbY€ÝsG]ìæÖU©gŸ¸~€µÈ[‡ÏO«Í;xÎÛº'Ž9{ª¢8éÝ- jPº®Âîó$@ ™¤M„ð‹=3}¸~)ºîrN«‘¿Åóçè±W®ùAv$Æ×E{C.H¶¸[y„Ôu'D˜×ºÉí] pfH´åŽc˜¥k`­Åní¼°äÐýüô1Ô.å8푨ǹp·« º«_¨ÊC Pä“ùñɶG€qôÿO4—Ê–NΗžkàüÿ8³hv+rìð¥ì+å­}ê„áÖa†xcžÉ¬Y0’—ÝŸNy}G¡Ïó]W?ËÔ·Õô;~µ¼£éjÍãóûú~.Èå¸|yl2åyjm\£wS¿ØD|Ú™k_^@Úš{ ­Ê>Jç¸/Nœÿ¡¾ŒÊ+¬ŸªúÀWanãOË—ùhzzk«^LÞ w¡ÇJ»ÿëÑKÓÞ¹ÅW|»Æ®·ôÁzê×Þ§’y¥¼Y‘™™ÛÎÙ~nìûÞ£Ì w/o‰ßäø”yÌÞ.ŦZ}GaŸÖô õ ©töèsyçäyÙ©À•0i°lS-ñ++‘< Êmb´¥T·$ ïn<ŽâÉÊÈVÄÌÉlh²F)Æ‚¢c´)§'z­HWnÀJèôqã-ðþ‹êGÄy=n¿©3x'§ìôy½k‹áã°òœg]©Ú;œº¯ñÞNºägùæ¶~**‘-Þå©ý“3Ñ–Ï]ãŽ8>LñõûɾPñ}w.ƒ¸x⩌]ÍU îw¬«áwšÑÃÑn‹gŒŽiÆhØÉVBÝ8;L)Äòq;Úèõ½fÞî¡·q:ôuz¿î\s?¡/LÃIj1®¾æ–“z/É·d[L8&´ÄñIô 4á^ƒÅ:¾ð“œ?æn?Ì8ÝGô¼³æ6;¦iËù¤Ü‡áò¾ ¯ÎiøöNmüÙFg£ÐÞ>©CúAϰ¢ú†DPˆ«é,m;5î­Â¤ÚA›“^<ÔIgS ¼ò4ÁÛÜbŽT}à Ã5*Üqf¨Ñ×ÃßÄïuæ¿ÿ“‘òþAÎA¿WõUæ W‚ßO_ÓÇ™PÒçØ]ÃÏm~¡Úág'?8xôÙÚQ§q}Éé·Ðž/•—{7 óR1ÃèÛË~®_G‹ÞÒw[CÇÚý†^YÑÉf57°ùñl!Ù&Ù3sŠgr§<Æ îÑç¿Öñ¾8ôýèëCÇHó¼ëán+Ô6wqå¾SÕ}GSžò¿I©¯‹Ãøâ»Ç5¼-ÌžÝì¹ÿ*¡Í_šGÈ»½wEÓîWa IãG›6¼ÆßÂøÞ ×îø€^š[ç|é·ßô9û^v{¸ò=z62›É,-Êuaøkês·¯=ŸúćB…´óú²³ŸîNDa¬{CÉ`³Šôç.m}‹@‚A?¨ç©:tã ÐÌ‹P,fHßoh¨È±ž4èc}Çr¦à+!zïH\O1áŒÿ!›ËÍo?£èëõ—4<$®e¼±Óz«Úôù_Ùêèô ìfS›Ç§T‚Ênïj»‘tÔÏÇ{#u_GøÑñwyËzšïxÿSOÿËߤú–_~è[§ò'–29†;ß?Ò[±ú¸|iÑtñÌÈ›Ây>£jº ƒ%R©Gß;‡Àx«ð9þo¢À|ž äy/(Íêïdù'ÌÊyñÔÝë÷òÎËDKŽc†cÇYØþ6 ¹áãô<º%¦ämí6EIßâ¹ì¾zž*ÃògÏvÞ+är| ŽÏ7_Ê}&nÖá{ ìŒü´ñÕÙñvÖž.oúc/t:vÊÛ‘™¥ +´¤"bÄ›8paOUBI <Ç%¤ÉYä,8OE‰ˆ•¶ÉÔß\ÃØÙÙ²"Med‹" d`\ÇŠ]‚Ÿ‚ÖAn ©à}xO{õ!åE|û:þ+ôÞoEOKˆC?c¯KÔ§{Íx÷ËmQ5ü€æG?“á²oeç—¥Õ´ö+ÛžHìäçbíý8xS%/Víø‹Ì¹½Ÿ=á_/?‘áJ‡?5ݯ:x[o©g—Ïê5;úBó*`e§žÊïgcõdÑÐØÇ2Íàf,Å®Ýé=<ù Íþ=Æãpé«Â»¹~ÈïózŽ×©îÒÐ×åù> ?±êöa&— “½Þ³9Gl¹Auw[ÙùÕc)•äîC…[Ê¢s|kÝñûœ/z>'wžw[+H[üpÁ…Ìål¹}þ’yÉÚ>1lØ÷˜¢¼±:;ÒSP×wc¤™*ð¶"$Œ’oyÞ©"¬,‹êJÁÖýU½¾` Ž¶ÃªbèúÛ™•“6>L?nñDY!9(ÓœRWl‡’3=Ö¥1œ^iôÙÍO§Cys„òwùïÄÜÇÒd8Pg[ÈžPÞßΧD—^ò˜º9,æ“g+%õ«±˜ÊZͱ˜=‚I^ž¬¼g謎yëªôáå+e5‡êŸ‘à|Iá%7Rïrð¡ü4ž—gå€y¸[¦EÖÞò†¦.? ž0œÉIJᾞ¢aœÜØÅåúVÌ[ÄY™~Gá“o[ÇÔ/S×bS­ÞPémõz³¯­‡ö’io± òò,ï£.ªv tuaÝîú·ÿèí?Vá0¼.§¥.©éyÙÈàSÈ9Äð^J|6W857x‡2sûa=Ö9‘_% ÌìwZ¿WÌû&¿:Väôüsq A¬»"†wY"|Œ}}„©†äzËHï,¹§Y¦ÌÔV¤—+"5˜Ã÷xÂ`«‰"EŠ2SFÂË0fÙ5Ý üÕÂð ïS;Žèy§¹âr^ Û&¯÷X›‡Ïßê¼iÎï÷yMêc»£,ÄûMÀYWkS<”qu˜Ü²tü™éÅ=2ú.ÔgæLàbêt»Øø_éÓ»‘ÊËØå¹W4¹Ž×·ödhm¡ ÓϾM¹÷i…²¶{%ªï©üMÜëùØþž2]èù–ücã ÚèØ/PšíõËrÐ7º¡ÈNÙ$ÞjûZ?ÓTnÓQôñlã#]D\°?xÃÓƒ¼Yè#Θ8cœØÑÍŸ6y÷‡w5.׋ÚÚçø®£ðç ½È;Ybeù=/ЙNmܼ®gËyFên2²ÚMÀƒ>TÅ@ ‡ÔÉûh ôqÕ—b´„ ~DåHÀ°IuŒœYæÒrr0ò%lÜ,œé¦v˜ŸT£ÏîÕF?£Y5±•Kib±3=9ø“£ðÿt;ålN¯gÌæáGáý]Yw©N ­…:àf“¤ðèý44ój5z~U“ –5ª+ó~ß‹ç¼+Ìøë“ÈÅÔäüll®ÿ±Í[iuý;~Vò×F¦¦ð^A"jë“é9¬°i*m¦?£ÃÄç˜Ó±2‹Ÿ›ÑGù¯EËÐrkøÇœô‹ë }ܳËù[€ñ—gÓx§o‡ÇäM‹ž§káÕszX¤Òç1cµåyÎ3pwÃ/iÕÑÑ»ä]½j¼…ÕÛ{ý5Ï^q™WÇiywk3,ómg_²í{êèl²²H_{Pš»YcèYV .iŒ2¾Nf‹ªÉ‘¨¡i¡|g…Nc2Âå–ƒ› "E%H¾|ލ5¹pàÒð!ƒ(õ¾®nSä¼Òr˜ï ”¨!Dr´Š?æ*±àb<òØ…½i!¤É 33[Å„(©JK,8tÔ¡)KßœBŸ•æ/ñÙí.=?¹ªÊ].Vf¸³:ü씺Ž!õhÍ{!m`ØÚ_Óq}.‹k˜mõéxûT–ÖÚ¨@”Ð!Ÿ‹¿P$é•OMûgPŽÐ,éÁ¤Š¡½Kv)BR–!¿CD­¬SV+*Œ‡(Å¡xOÀ}¦ ô ÆøãS¦(2Ö¿Dÿ+Íìt¹ãÁŸ‘ò·:Ч&°;<‹PÂ_Nÿ¹Ûk.¢ Æ:Þf>4}ˤqµÚO`Ã5± ¶*)r¬d'sÚAe­<¨ë 'íí+âé‘I¦ÅŒfU"DVÉ1«5JÔ¬ÊC)o˜õê£ùñ_=¤ç ËøGªéúÔÖØÝ{Á|}ÌÌÆƒ±Ûy†œ’½hªeÑHéðtêvS}mçBï€e¢ÿZ~í½aó¼×sßø—3ÂÊ÷‹N¥.÷¡ÖKÛãä—W¿Õqö 'Ì6ƒ4Q:47_â_ŠETóÑö.oŠ;>P}“Õç:œ ~—É>Bä·Ï¬‡3­Ã±ËfìøûLÌW³ãKÑrýOQ¡©Íꩯ«ÖßëqØÆŽºÍÖyfÖ ø/¥ïw˜ëó_5:þÐN¢Èx¶»NÚ­³œÝœÜ{yÕôžÓÐg>™ŸÞíIZpGŠ®ÇöehíF‡¹Ÿ™çÍ»³ƒ±Íäó‘Yzš<æ ²†à µÜkQ´«Î´"é~Œüb­fÎr…5+¨kgU*u·nö®™…£eé98ñfÇ©båâk2 È™Y2CŽÅ ZG)•Ø))æèuËú÷råêÚŒYq伆LaÀ)B. jÖÖ¢¬ðo®ãx-¾w¸çùþ¯Xú\çc€¶…XË`¹ ª›y5Ì‚±vòÌëNR]gM6´7éEÝ¥*5œÝjbÔŸÑah“- ó¢q®íåå­tR…  ôP±)ÍB ßJVb¯$”#þ.üaåOzEåíå@1ýŸO¯»ÛqÞ?&rŠ¿Ât-•¼<ï¡Aa}Ä‚÷e’©^ðEs’¦ê yo2ÙD`²?íR\ÊZÓ¥©˜º‘A§ ”0a"çÅØ2î?>*lÞyéýi‡AGÛó“¼1qô~âÔ4¬,ÄÍÇQ|h3£G “͉ð ÷ÔNl(Bß×®Ó3&ÊÓ Èš²@²LŒE™˜%Dßçw+cý…ZÙTHÁèþ¥]Õç!n5Ì¢0³'NÇeWßÑ€’lÙLŠ•§L¡³Aô xgõ••¬¯¬OR¢éy}CHž{òö£<¾ž]²ÞåSØïº <|V±‹  “ˆç[6äÑb•hz?œÔ¸»å!hºÊtzÖšg+‘•:íþˆxz?Õh^Y–JɆö„ôcPBÉP¸J2NÄ/É·ÿ"NO+‰þ_}]"ùb[§Ñáû‚7‘zXMö/9ž­ƒGÚVÂfÞ{~„i€Þ‚jÍÄ*½‹þt÷ðã)—Nî…`eHõLR¬öô@àí½¶WüãÜA+~zK}JÉWÖ´˜¶€òi¹¿pöúàïÚ,‡ 1à_ߪ×Èôämï½ä¬<·ÍÌ£dGœÛZ š;¡sçIìÛtÆ’I½†ƒ"ËçÓô©ˆSz˜ð [L¶_š|zM‡uÙè—e‡ŠÔ½[Ì‹0¡À¹‹tL4ub²—'Ôy÷é3Ö?ã¿M^Xñ–°ù­&zþwY2dmeç“núŒ¹Cç?ŒûÊjMl¶i_«Ð@V?FxÀ(íà+S¹õUá€ò8ù‘æ/o#—ç7uÌöïñš.ƒ_Óçé=Üa±£¤« {¢Š-¬½G¬á3™wkSÏ‹ÝSê˜Ðéxx¸òC¨äOX¹íˆÞ2É"¤m²°IJ¹ 6óЛ’°êë<û‘rãWiD¨}eðî®op$6(ž®_ù³~¾|~¹ƒ W/Ç=~ȬÕЋ°âøý3ulPÈ’cþ"ÓRἸv^b·G^šªD<M¾w”ÜkÁÆ›s3v§Ä[èû6ÒYí š”ä ŽÄ¬©qBB§åY{ÞúýgøÎÝ¿¬T{^Ä^BéøÚxŸ­F_;ã΋{[.áõÂQfø9 n0Ãh˜,^ÕQ<ÃÑ g[¬.³ ?ú`õ ¿Œ|w™·éãËJocóECpMxÓ¥†çJýî…îÕ†rÔ'Ðúô.·ÆËP1ŽÕØ5üðÔþ´h¥ h­¦w'oeMö:F3G·‡ë"Öµ.CŽæp×&«2¹óŸ”Ò¹J#XØ-Ù5@U {åÝt :Y$·ùχñÇ u|©Ùf軩GñÀtkK&šÉ Û¦e‘µdXù‘Ñ»…wÕbéa:e:ŸŽâº~§%ÞcHi…~L=iMÄîµó§¶ë:7Yü·˜†.jfõY®wõƒ;µ=ÊÒÙ‚küõÛ²2Ëhºdt®‹&TÊÁB– :‚ŽEíüÍð:õ;NQÜ9*•Áƒ ]Ä¢'¬|5Em e@ð‡O·OO¾pÑ‹ŒÖHÜå±ÞO6§s;S_˜q=ï¥wé$–ÃWWílá[3cT¹@eCýO£š²¾$ξ^sܶž‹¦ÚËÁÏ;Œ¾}(dàÏôêZJcBŠY¥Eý€Z!¥x¼3'Ã¥:ëiô¥Žg;[]kCjE3WEæÙî%ÑØ¢FX™â×TÓªê ¶t—]WÒ‚O³ÜíÌd¹ˆ,dƒNP¢—½ôw:´ÑM•Q] aÌó‡én–5É@0@gÐF®FY›å3cH! :d,ŽЖFh`m} PgȪédºZ8¥,LÈ~òÊÆ ®ß#_\×ùCÂÝ¿‘¼_åOS<¼q™Þ0GÉ rÊóGÓané=%•¨íùòÌ6Ù“wÙqº¨£fšŠ“8c6wÔm.öKÉ»a ±ÿDÈë+„âƒMÎAÛñ 2Y°¿DI?®ŠŸò² Ðá‰-ð®Ïñ±çÏ4ÊÞ"‡9?;pÜ•6 ‰¨õ~ òŽÏ…ò†Ùðcñjœ’K¥‰lÝÀãkw—º.âpÙ”éÝ'CÓ¾½7úýwörñƒ›Ïâè3‹™‹š‚ú’¿‚4?Ž@}·ü™†÷Xò¿¨l¯!xdÝ1½Ê'Ï9Æf`<ÆSxÆLÒåƒ;nœC¢ûø÷5– Ä!Î}]xëÉÞKðo‹ÐÔà©—™Åöy¯5™ÏŠ:]dGÔ%®&Çlxè6Al¹ÅΚ™_ ÑÆ? ûê3»Ý4¼ý;WÁ}55lœ¨ýL¼ˆåí‹1Š1ê@®ŸñaT ¬ÔÛ@°Ïí¥çÞý»ªê}¬Ë©·njx±gÃ"I™¥æA›,R"»Æ±´-ˆÐÜNVñ$!¨Ž©gÊÞßñ)ÈÕe­ Å•¥ sDDz‚^¬$"ŸîÎÝXˆuñÃa2* ´üù¦•ìÙ•Ëö]¦<}O+ãž/šôÝs]ïŽ|’Ž—€öÕø“$€78Íô<ßçG·WOšÉPÙƒ)œòwõgù=¥k—‘Ï­Ï5§ {x»Èàë¶Ê§MŒæªY}1!³=_B½“ƹêºÃQ[9MWéž+][Öÿ–$,²}¼™Xz¶õÝeÐ$Cšõ}"dnH¡JI ô§E‘Šù“dA’Ð<سOM KˆñÅJî‰}E*xO<ž‰^KðNwæÞ#ÅÕ‘­¿ã¯K½³¯§]*„¾yôûáÏ3Ü1 ÀùtýgúýÔC%ºŠ(A•Bl4°3ô4v÷½=7ÏyÏ^?G·Á•|IŠvuwóÖd›É³Ùñ‰·—|<žÁ:û]nnžs×ÒÌh¼°ÉšëÇdü²‰©lx÷KÌ^èöçk™ñÛKø—’ßê7Re±fŽÊä9Ž£¥ÍÍʦƒ»©rÔÛ£ÍYÝÕUùÎPj“kÖ–¯¤ÍÏQž¹oá_P<{â>{þ,kÀËœooËÛÌWúÒÛ=O7Êâhdáèùñ;äôœk¦S'1®ÞÙ>¹‹L:ßn6fI|RtéÃ<™/&JDé"ÌŠ!Ï*b2I¸r6Èç«wDÅÇÊÏ’.êÓ$ž—ž{ΧÑë¼ÕåýÞÓÊÛ×;ÊwÚ݆–‡_Ñ_þ•ñ?A¬^„®ëOEÂèMÊæ ]#”¶k¶úÙ×U‘]ÿñwåõ½gyO+øÿŠê¹𛻜.æSkuìíÿ"ô@±:÷&YBdãm¿Ø‰”²#-¶ÝM7RÏÛxml³#”¿Nž#ôÿüœú2ðõ:½+lù×Ëž'ò榲éì5‡ÉtEgÄ9*`¸…ƾUâ]óùÙ½Ëkki6áɘºé+}¬`Á…¡ägãe¦N½§Á;ê¿•º{àÊ#2ãElä®bdÂ`—îà… ô§V¤ÚARI‘Ý:W|éV,óöÖ¯¦æei}Ñ…98Z£¶P%bây¾k?¡ìKÎhöUæ,NRroA‡Ÿ‡”ËšXzˆUÀ¢¿èû¹ÏåùwÃHð?câ^ýÿOgYñbüù̬ž Òàê7§ÐµÒ=ý2¾©)¶ÖŽCi,ìÞ» ýüÂÿ’´ø.Õ:¼3”Ù]á|QÊxw¦W¯iz¬[ó~[Á#C…cÊlbOQšð 4> «³×oŠùÛúŠÐÏÄ屸Ç+Úmó…Î糆˜º¶â«d!–±šRY’T_Ù²{ÓõKC?ïÒ£-²¤uè÷‰Ðñç£oåáf‹2ùœj5kë£HÎ¥ÞuËȾ&†Ëý£ ˆ“s±aÈè!†(jĪøG# ²ÊògvûÄÓC ÙÙçiÆz ;¤B¯IZ¡&¢Ÿ¹+ )C¶‹“R†•¹+g¼ÏJ-®5È{ŸçU\½k!©â&å%hK²1V~êE¯Yù ö‚­"ö“ RÉÑþÆY¤ÿ‡FhÄŒ_ÜYJ€µ@Ýþܺ7VÆÇVLŒh⼇„Nñ¨ÛRݼ’OGÈ7×2Éo æU|,·ªíݬ¶»OyážkE4¶š6k>íM“Ϊ}<ËäT+uTÒ®a­ž5³c›ë·jMJêçg«2“À>£øîÓ/Çíëïjåâïò–ʮކ¶ÿ!¥eX=soÍK d™•-DÞp›´ØDI»'#v&%ÊuéaÇ|oávCòÔö¨uš]ŽWEÒ“in{Ÿ½ÚÆÁè1"«îV½Mˆ=‚ Õã%}åEd¿1Y¦ÏAÈÏ‘ý8¦|B®ßŒ±x'õ]t=“Wòf¦0ëH°úêí5㌎Ã_?ŸÐß­DÅqø"æœì´Xk1b¨ý+´umcCÓõx0£i1%žhú™X*$ñ¡±Ó!n@”9¬‚ó;ëDíîåÍÐóå’heƈÏ@.4Ìaûv d–ÉGˆ l‹'q®‘¼×꺽@úC×=ã=´z.§¦Œxï´Tý/X#Ê•·¹4²Ø†fÕèM*/§Ší‹§vÔœÝýZ rs—y} ÄÍ—'P휕ÄËt2¶›’}\s0!ÃÅ+7¨®Çƒ¼:‹?¦‡L¾&Ç ÕqÉ„û"XîðJ틞oŸ'´Ÿ2¬%ü7äH,«] r›·Xz'-Ãgj”#7}”Ü®¯ÚCËIì¢X…Ø‹ù§’½F¸õÛ«ç®ÛÍ ùkÔкO%v˜\Ø4w§Kòj+Èfó™ì¸dΩLÔ”ÝØ¡_¿ábº/–Ö)[í_Ò'”ø\>ã:ß S¡à9?(`»ÏùZØ ¦öŽ –Ðßñï~A&i°}p[Eb?ˆm€13‘©ÍÝœ‰zÛÐÙþeþŠ/&x/¥çù/›åý9úcߺnnKäjþ´Ù3>F"c°‡# Ĉ}f™äˆíŽoqj÷¸{3¸rq|8ŒûæãáQ™Yh‡©¢¶@#Í]úaxÓ6ê§Å L±ÎñÙÚ®pÚb%)­¥<¦d«Šå]h…Ĭɠê+6`œõ\”´ÖG`Eý‰‘ÄǺE‰ˆø|=ë{DM&“íjÚ#ó:òGòÏæ%ðyÞ?×ð·¦ntxåѾ/ü{ÄùÌXòu+L6¹Þþ|§wq›â'3:ü*Øé$¶;YëêG="-x^Ÿ—<ÈHfé÷¾YÐSõ˜k´>oJ¤¢ñE­­Æl–¡Jßõ2VbñoÓ<‘`ù™Úßö.÷ß{¾nTŸURI$´¼Ø“ZgÄšv?sðêÈábwŠã‘TFÏÒö_ª‰´¦ÁŇ!±±"GR“³yǦZCìi±<° ‰èŸ²^žQÞqL»}îc[Ë;‚Vñ#xȶžAô¹ œ rÀѹžYæ…(–æQr; ^N`¹&9åõùÅJ¤Sš¡k5Ð;WKIånÜÁë& $u³î*(q4ågòh¦Ò‚]V©Ñ_&ö7™ü|çO©ÍW+µÆë6¯N ËäÍįA‹¥MQU“0¦Œ^ˆ+²±Þ\íÈu++©Ð*kèÓ?/W±©þçS *Ûô"y|)ú7¾QÃÇF{[2Û(äCi¥]ç~¯èŸ°§GÐ#XàrW"T)PI§š¨þú¿=Bú¡ëޤŽêY°±Œˆ¼IëdÇl¤Ø! r/gíÏ[¯.؆ƂT],ì"(Dä´sõèº7†X8TÉ&–PÝÅNìþ,Ó£L´Nž\ÅßX>9ón—2ùŸšñúÌg¼—\K“ÊKE’¬èËóÒK'{ð¼ÁôÑ"ÈOFÖ\™o3ö&vÌQ§ª"ùë›íúÕ0;¾Ó™ÿPø«’Ðâ8Žnù(å—¥ÖÆ\€Ìèóµ±¹¯Í´b&â[ve=-NrÙ‚È#Ô‚[~ž<•ly­ävwú6¥’õµ7êšÙñ’Ý©˜ÛÇÄ›Ã]÷Z`}q1ìž]ÓÐ4>¹ÔFzÎo¹`™&‹cr’•Ui  '‹ yê—CÒeU\¥ËÇFfG†)cÄõ´º: vÞÖ5Dq}UnïÖF«¸,:©ÊdÃaÙaýÇÞ³—­ýxÂUô(Z•ÑüÆY¸`Áµ™ [",â‚(ÅS£Jެšç¢ñVòA¢²O˜C긳3Z0Š"&ÉEQh•"Ff…µ¨ó>å³ýõÞNßñ?“ãÌü÷©Þm NçAâdxÅ¿ çñŽÏ}ãÙþïC{'ÌTí´ñöÆfy¬2¤E±%ê™+ŸûW™T*ü².Í#íÍUU)•}h»5gÿ@ÿ³ÿ•úÃ&­u`z \”ËŽY9Äêƒ)àÆ ´3^†#Á>]:sèù©šÇÊzà+4󠆀;T‘Bü)¢~zrrÞv:uþ^Êé¹ë`ñ= Å;D;aÓ&·r§r\£&ù[€~Š¢#8íœ=¶BLÚ1Q;õµ6ù®†~I5ÌTCû5—Ì:Å­«9¹ÛÅÊ´MbÌè=( –8e„+»þ©J‚Òý"r>ì|ê=0xÃÔ/OÇxç+ÓßmÒoø3±ñÀ39« ¾Ý§{Üô˜}wYÄ3^žþ1|¼wŒ9³«ÝP=3ú«dç±:0ýc.ËÆ^sÄþªü³áù›_›ñ׫ô÷GäÒrlÏ'à}lßP iðžmÂçÚÒÇ×ëô4r…FC+øù~7 l5u3µwó{^³Al›7αœ4¬8“Éhfø¿ÑWoßG½4vï¼ÉÏ GÉŸ¸þ‡¯ñ§·ã?R+µ¯¶eq¹`:ÿ?·Î$~}Œ¼«ŽÚ¾)ËÆo3޹Ï7üNyǼÔ.öo™œõ›áÜÉð*#Ì6{<Ï9ÀvTçü„·™ªZP,Óc©Ì)™»P`¿ÆæN‡3TzŒ åjûŸµ#î8â-›“C—)e˜ãL¹`õE#€&¦+ðÆBvû¸%}“õ;[úm—bé9z~vFªO^(fçÍ,˜î¦s_hÄËLÊ!Þ ×CŸH=ǘ}^óžà7‘ÑÒí‰ãÒkkââs؈mùG\:Ú¹€<¦ƒ]†ã‰QqÅžŸeC±³¬¢e±nÛø©[Ç õÜñ>³¸ÿ!?éŸÂ}&_Mã•2z—„¹wòêôpüR§h2uÓ×é#©QŒíxÑ®²¯¸M™ª°à‡‘ž“„õCãÏVG‡¿ÌzN%¸ÿ]ãž$œ÷ŒRãµÅ°†g<ÞBznéó})N¯)U¹í@OpiRaÔt, ܉´Ì\}%sdÅŸH\bØÚ†8ΗT:’œÿI°CŽº{ú‹‘$þ£©Dè_ºû§IÕõíSWÐ4/ðÜ]gPÍË“ Ä'1 çõ}v[–ÓæÚY³³¶·©Ÿ¬žï‘4g*¹z¡Ì¾V^kZ¡Ò̉!w¦¯15ÛßÃÞ‰¼‚¶gKé÷µõ{áß+lò›¸¿Óõ®un¯áÓ´^ï™sýBøPàº=¤ñym¿ë©·¥]DEM•]ò/«Ÿ ðþ/ô‘âmŒxçs`þµýZr€òO˜/¥×ñXþôJnW–y…Õ±ò¼sµ¥Ö礖þŠztî÷¼’:/ªô› ië½ïÜ]ÃÚÚOofI§>&ÄŽ¸ñq¢Ì‘Q6æÈ5+£D IØxÑ´³Òû[AÓ{Î^êhsò5‹•….VL˜Øs$¿s“0¤m,’¾ëpT’Ó»æ·Ö×ý/u¿Æç‰¼ãhtž–î;4ÝZþhG‘òo§Ì¯Rþ]éûºZòùíñÜ—]Õ«˜ã«²íñq– ²‡Ù©UÍÍó¼³îb§÷P”M_`1DÏÖZ R²1_óžÍÐô]©´[B–‘Ë è$)ëS„ð—ªöó½=yCÏÚ5wÂâ[î|ãÙñÇ“w¸~óÒç8nÿ#_ƒOš{SsžÞÚäçK£^ÍhÏ/Öj‹uopÑ'I‰•¬9jfºMþuT+›úôI—ÿAÝ×ÕÅP(`XŽêèhƒ9X/ú‰â*"Ñ-&<.—‚ØJ›b2É«G<‹CîRU¶VÆ6h­<eiš~­¨ëÉ $ùÆáe@®ÍÊð ãäÜ .'pÁÛt—'rb˜‘4²•côì j¹Ü*=¿ˆ_â·7É<Ï+æ/%²Ñsµ6ö[§3Žê5½ÔH©B°á‡M5÷Þõ-ÓÞ`l T+¨½×ëÿƾñ÷‹)Ìäò|Èò–W3ú;’ÁVŠb ŸÑ LÙq¢UX0HS©yŠk,Ôf¥ßI~uãý*ø›šëzžoßC¥ì: ®7u%&ç(žÜÓ_52Üh]9’·&¢ò˜ÿDÝÙï¦/ä+ÒÏŸ»pœO¨OöŽà¬Â¼–'’ù­}ð×:Œ¸S©¾­ÚÑ\©Mœ†Z’ªëެÐß”òYåÌܽC¸õ<¬¼µÍÈŠLÁéå}¤çJÛ=8ÕÇ´µíRÁ‰ã§ŒÐAÛéxŸi‰,)êb¦D"|¹ö©y]Q·äipGA¿5v„À¦†`¬<ós#y0V3HEšafé_#)úýDMïÐÅÞ•iLÈ!³N†*±Éy'ŒÝç³³ÇÖä}°…‹Ÿ9šÂ1D…*/"8j­øÌ+\¿é,ýd/Ââûèÿ’Ÿ‘{ŽÿrØ»û9Ü—ä£m£ÎêmãWg“{M|¾©L<ñlf¡s‰¼ŒíuŒ§ÔÓné¬c™†¹@çû£–}1eõý&zÿ˜cU\ž£{ ‹–UÆk¬í`¿÷ Wˆ·Ó'ê¥ ú]‹2©'k}0ÍÖ´ÄÔŽ¬˜£*WŠ+”¼{ÏhóÉ“8_×ób·÷"/¶-¢e»YÒ“í „\`B´™ØýUîš$‘¸`”çm˜„ÉfJœBã«#\G:•!FV—\ÿaP1@X„íÑݬÙB[8V«·Z6ÿñå,}Vø3KIjÑ@Ëù‘p25CU xH‹QQ[#u¾0ZÞ¥µ€žõ-Ù©PɘPØ®Ë7ùR—™ Áuólm“OKèøé:^&¸¬Q±I!T3KrÕmdóÍØ¾‘zÎdšö³—«dndÌó5¶÷]êSRvÆ­¶€P(´ÉCLüÏ\šÁ! Ñ"Ay‚.°îk͉ô\Ä |–š5U¥n: hz¬Î²G¥o šl†5ØBÊ÷·Ò6CtíqZÐ3J„PLö‘gŽ”s8®¡³Vfú ¬'®‹>+0J¶è¿%Àªªš¶H¢5³&PëÍ30²krÀ[@ìi 5ŸÔÐìc2ÈÎÁ>Ù¥új¾zŒ€…¥[ ùn{}£7èQ2Ö±*Ù 1#pÚ~,s¶ÇkÍÝV¾#>Ô¢::íçrîPI&Íø$|ƒ}#hXTè¸ì5âð¸ÿE-H°† |ÙµTŠQa48\©‘vmb(Ý‹ò(ïô—Œõ¡ºÍ ô9VXÄ0ÿ-ØØ}ëVµZQ?ëêÚÖ$`>6¾Æ,ÓžÕ@ ŽV :*Xê¡Ù– eŠ:Љ²ßâjÄ&Qus@ÌZ¶cN©)„@m•”Á34=æ(D¤½*Ô…¶%»{Ú½ÏIaUÔ¯7-è@Ä[D’)6TU/€|~G?¹ÿөã%b±$­@WÍ-UóâëýZË¥"Fµt†zŠk[Ðð#Ø pK¯’ÿ#ž´šCý ¦Z ç(Úü[.%•Y›ùÆÇcÄÃ+7Z¶ .›%¿êý%ŠØdš- œËЬAáM>Çñ~¡ñgz‡†w{q3{÷ò™ÍÁÔÞ‚i ñç¨ÙM?Lˆçƒ¡ Û²L#jY”Þ­BNâZè% ³He ,ÛïLÕˆFF½Ia±—¥†½OFkC ºpØŠ9mÓ‹‘‹”§Ð•$D‘ROI„”C€ÈJ“Oí`¹,#޶åi™xkèÏŠñÉ.=¤r«Bì\)†@ j;…y8avñüDúéé=<ët¾&è¹üxçú/-y¹Ñæ:_k×K"Ø™¸ÝGQëúܬR¡.4Ä=´æÀ ’™&Tµ/äÿÖoU©ÑßÄÞœ|[ÚssT¼þÛÚ}~€t±ë®Žn&œˆ©^Š|{} {l%žc™¹LÈÝ|w(sÑ.Ç]ç6|I“|§Xò>Ò@]`cæ²Ï&8ò¬7¦Ö“ËÊq§b¡\;ÍZqèTf“_׈=+ú‹ðæP¿Ñ[~&¾öK]DÖuZ)wÈÂ7ê4'Îå Z¯ƒvÙu³Pfôpt›ei˜~³di:­‘›‡£èºŽ½™‹ëÙÈÿ7_zÞ°?•=9èsÇZ 6ˆ1˜;¥9Ç¡!D¶!òYòiô»umý¡Y:ÛêW)e`ïV žü-꣼êó÷ü³èGŒÂÆÔ¾~îÆ’}­ˆ9|ìëhBÀt}vIJîhýTˆs º÷ÓdÅmö›û.·ÿWœÊl‹|1—¼D𙻆mèÑä1êÎüp۲ήbî¬dæ‚ʧ(æ¨ïL$MÌVjoGk«âýŒ°Á“Ék/MÚ[à¥UmªüøU•&µ"ŸN6s/Ñ›§«eOoòsÆ›õ;¿ôÝo×Ãì¦Z~ˆRlìmS\¤’Ɇ‹&ØãÏ,M±F=ŠDaÉŽÅ“–í6–Ö³$2z ˆN¢\Mé6›b§’8<×=^?ô[åžÔޝ1Äô¹¾Nñ_õÅã½—¶‰·7uvyÑs¸ìÙm¨é&’¤ ›iÁYgto,êEÜN;ÛÀ¸þ5oGˆòÓ}ß!ä>{A¤zŽS;œÅèCÏ?KDÎuöBì(ùª):W:ö«÷e¦>ö Ðÿ)é›Ô7&Ö|yÖxãw£ì²75\G£èÝÙ&ž6¯L÷#ÆY#&†[ˆ½«—XbœiÕÁšæfŒ$òïñÅê‹ÉÞEéü¹åÎC©éz·§ÔõZús§ÑôP¢êii<År™Q¶èEkžÑó‹)Õ„J´D°»·Jý8úÛ©èyÝÛ'zLìŒ3¦®$ú„òã`¦ƒ~!™’fX¤ÕbÈ•"1ÁÌ ØjnæìœC# Q†icdÿ…–L¡Dy 1À¥D  `Ämu¡FÅ/r>AÓá:µÏo+]E؈€¬+÷g•"´6·ê­h°³Ü)ªÃKJ«ØK¤lÒJ–,‹CÕÇ©4°ÚM//로<×B¯lÁ9TYÎ*ÄÑ^WEëL–•¦˜—•ÆÁí¢jO;$ûö|‰ŸŸÝð8”ÉŽo¼·©±CsyO4=;[X˜çÍèô—·GŒ¸c©µ·•äöƵÜk7]}¨+$×ç¦È™Ð6Ì¢6êÏÁr¿ÖÛDÿ¾÷û M®‘â°3;ƒþÀS¢£H/УRÉ‚,XqgËÆŠCë4i¹;Uî£Cñòíã¥óhØùSêr実Ÿ&Í,ÊŽf† ÆÀ•Ý1ŽlUjicÔß“:¾±}þ׳êú-lû‡@M‹¢I%˜kœÉ«YñT…oÂhaôÛ}7&'QÅÅ,Ša1{õ§^=lþ¡tæè•÷¡Å:±öfÆ^b?ˆDÐ+nØšëTš±úÖéæY´‚Õ„(!œC«çÉ`ËÙƒ]2ÌWQ²TEQ †O >qôÈz¥+•;Õ:eÐJæÐ²/®B&t>]‹WóŽ×ͰÝv†ËBqÄêsŸ^ºBNl¡ª4صX³S7Ï–Y$åOîh–bÊLr>IÁ¯l«ÿÁ1ÔÄÑ`ÄؘÂF´H‡¦ˆ¦¼ó~hQ;GF>ôíÝúƒþ4}fz¿òw©ÃÝRœó¯u‰ø×™Ðì„Uw3\ä:2úC!f_ÁÒ‚܆ò#ÅYã©B:IrÖÕÖs¯_§ޏY\Ý_ÎÑ­àÕ¹‡¾ŒÊv›z ÞÒÈ>zT»"8@†œºE–¶ÞªJ³Jí·Ò‡®­@F¦Ì„Ž úWÀq…ðöX^‡Xúvhšm爥¦¥Pq¨û¬ÄŸ«BŒˆç0Ì³î.!@)TíúY4†—K*%‡‚²¿×î:À c†ôR-Æ3¶”]¸¢Æ·Ï7àxÊÜÉLÄçîžTŠ( ¢V`Á ¬Œò•âÜ ,}Äzê‹ø*ôƒÐzôÃü€ò9^ICÅ ö<—¤_Õóäqj»;¾n¦ŽGeЇk@CXœ²›o3‘ý\î_tmûæuYçåÿágÇþôÅü•qžVõ)ÆykÔרoI¾QÁêƒ½Äø'›]>¦ªXï<\ŸïËr tëùoÌ`A.³EUuׯÄër”ikŸ&&œœð€<ëÿ'eùCÌyÙ^#SÓî‡7ä Ìžy j÷ä§^§Y“½šŠFèNBûwÔÆDëŠýOŠ¡xÕßwJO¬ã›¦qÖÒ×kK¢mªë#lVwxZz[‚+„­ª   êT%*=%¦.IðÛ/(çÅ81¥LugŽ/QİÍBJ$Ù¼H­ !;€›¶«‹vî±›¨¾©§öF)‘¾Ù”#²E +ÀÒ$»WWvR«lÄ|š¼ü&ùIŸãÛ›íüqçïL~BÕí<¯ÇÛoýAäî3Ç£â0Þæ¼‰ŸµÈëuݯ{ŸÆìŸC i¢ ]£t7O M\ÌWïM2 @ô+é'·ÿã[êÕ~«–ÊÙkÖ<»,W%m2²øã†ñÐ5q6•uʺÇ™Û"Ú™Z‡Ïü¬íªS+OPLr•˜ZZk¸äçÔáÑXé ^!l>‚‰ T˜w&j3õªl MW’SGU‚ôPþVâ^ÿãßÝ­Ÿõ­‚~KÕ$꟰AeâfìgB¬À–m˶xïI”™°=æâý×™?nëÙ8ª0eXfÔ!;¤Žò1ciý¤¸ÑeAå¤ôÔrM\j‰®–Ðu kRÊbjZ~™…Ax°r%,Ø¢(¿æ¤;@ŒÈ,Iäš<¨ø;ø£"^Ÿ<+Ý÷=ǹŸ0‡Ô>ß!•ÉoöÞ+ÄÊËåÊJ^Io½_ÈÏù\|Ý9¿&kŽ~Ù;éž{NÊTY g†óýÿ¾;ð—«OæÆNŒó]Þô)»Òfu€L åƒKÌüm»(4™î‡1 V“èè‰vyýÇdÓX™Ë*™écp¥ôç§´:RúV+cúéô3TÛ©çí3´%e@^…¶}oZ†°¾f¢«#”Õýÿøùóž7ã¿_7uè?Ž—a¡àÿQï÷ÚèPÑkŸÉÀë;µ³júmë3‘€ˆ‹"?ônýPë:îRÔ0ê{ûWÇÌÄÒ1–ß'Z9zjçÎõQåîûf'H׆¼öJn»k…ÕíÔx2Ô.zålÁSËÀ~zPöE(}8i°ÊÙ¶º®§.F‡¡£*´‚-6B6Ud1å}»:JŠHMˆ¾ V›pecËÍ»Vldî-\JÅ¥jrcF¡!6LÁ$B®XºFf4ÌaðÛDÞ‘½ xoˆþ{7|b¯oÂx'Åêê¿Ða`ô4Å–—Øåp|Þ'ÆâÆŸG’¯;ÓvÍjj—ŸÓ{f^“aðÛGIÛü­úô+ÅøƒÓÇ–ùΟ˜þ@<Àž' ‰dûn–ø=‡‰¼'ùº n¿mîÓŠäTçð{öúV˜ ð¯ÕmqõÈG ÊÛÈfÿ;.ú|îýfz—踃íWÊõõÉ)Òtù{—žIïezCðQ9ôSL…[lcù(]ášeD Ý 4!w¿ìJKøÚñLîz£ñÿCÒç“sÄø›”òCïõ)çásLöËŸŒç£LzdaËt]AÏ/‘Ÿ›£¤QkX²?Aª?p“ôÿBûPäâhø9Õ–S“ñâÁ¼»‚^f—9-lþfë$Ó» RÎ×òõÒãáÏ :|‹$¦$Ê’»”u1O"˜Ô(ÙLZØÕ›ÿò½ñ6O7ë³ÃÛ9YåPè¼le‰³›—½ÇÆqž3ÄͲY™º¥¸ÅBÂPKeîÖf–OF¡BämÄñš>ýëéhø—oGÁþdoK´72ÿ`}·|=æ:risäÞËkõèCJÕl»`›FÎêi%œ‚Èì}Ò›ßüÅ0yêy{ÑÞq^‡c–óºzàCbÉ»u2OáF3`aA‚è/fj«mZ·šÔH =¬?ÿÞ™ýzŒò™xVÞTÊó<ïa=ÙyS#‚Ë麆·Š‰bÝÛIˆÆHBšUM6FîfdÿS©ÎÐõ"bE•“XîŽÆ¹tC•ȼ|œ‡ý¢ÿÚÓFÅè¶ZÎÅEmvtÖº!~ͰäsüÞ“+–µ ó ûPŸ·²“ÑņLLíI1ä_B|qŠÊ¸±K³#JØì²®Õ´afÉ—6X;r?ºt©22¤|GOÓ'Ô x31²äÔdy2¾ÖPAŽ8œÇfÝ[i@|·ê#Êžu×·Eä~´º´IÉ_ŸÎÍçT Ì´fäæ*ŠT¾aZrѤ²ÇÖ»%LvFÑiaß1ßv<7G‰Øñv÷-Ösšêó6BæFöÊ£kë`ôVU¥^£ û(u˜]»°;Æ… •#0Cò;0bŒ’&jË´¨™fÇŠLÊ“¹lCÍ׊{~‘ÖäùAb+rV}Ëâh ‰ažÄ…ƒb $V+4гJÒ÷,‹àiÚbH(-¥pRßã'bcâÅ*ín›bÇt†âXÐ0ZØ óÒŸ#SÎÊÊ9ÙsM•»x–Fw5‚ ÌdµùP†Å­€l]W•½_õÉW„üÄù@bÒóg¦Ý-­·­w[šOGÊ|?dÆs=²x¨çb¥¼Ò<Õ6ºuW¿èÕ2Ú”’RhzšÑÇe.ƒms°³Wi„ %BÅ“!Ä¡GK–¶¼uȱ«³t÷o[ª¹ tœg/TZYþÀmVÔ“\6¹!'ÜÍ@I ÆI“,`Xp£(ÑÄÊ‘S½)þ=¿³wYläŒáž ª²Zº¹ìèhm³ ]q¨ÙÃó3Ê/:$sE<øY4´TÍËA3Ôbh‡EyF EÓžIe‹aQŽó¶ù€a{ÁrXy }.ºucŽùj§S‘_ ÿþˆ£Sur´Ww$W;ÌÐÚ? ÚSM°Œu7Ö1p•Îþ·Úfñjˆ"¯é/¸i˜ÅnÅŸ [±å= ÚFÀ–ú Š cñJö,Xar‚3l.° .þ”–„ð0ž-‰+X(Hcís‚Ź+ŸF,ØÃ@*ô>‰RÞGñüëPgª¡§ê8)•wäTñmh½sݵHòê±M˜£Aˆƒ‹Q‚ÿà^ŠWÑm˜(„[Y4Ø á@æëŸêüßÿµÔÖ{ucQ±•ãÇ·ÝcÊ$ì:Z­fjüš§õîJàl‡ƒ„i¿µPØ—²§¡áÛY¯¬ÇÍ*¥Vа 1;ÿèr øWûØø‘Y ¦òW ïÙ¡#Ì™ˆ†‹SÉ JE¡6J“­œW™È°×jç³ éÓ=ú.œÅ‡ú ¹æ¶Q-ù f,¥FT¦ÇQ%™zù¿™éв ®˜°’\ÿ/Ïsf„a¡ªcPj V™b°KØölKÜ5úÍ.¤û¨)jܸ– írº®h|bÈëxÞ“bÉÁIY@a~ fÇ?¸bÏ=òsÞÖׯÃÉö¿Bb¢†vJ˜—+7Õ{A”TÏJPV®iö&‰¢€d·5Ÿ£Z¦¥\‹šðÏð-ë³É|¹:Ö0ù¥´õ,÷'Úuù®o-lÖ€—Ì“„^¬ |ä&½D-"6b¶d7tsIŒÆÏ™×¼[ßøÏÔ[Í©ÌñžvôÑÕîóˆïpx=å”âo·— 3·©aïøƒÈçîƒ IÌß¹´‡aš®{Œ½Í¬ñÜÑPw§wjÚV¡p(â6f›ï'YmņHÝý5¡¼>Õдzqö§o躖Ÿ÷ó‰r\ú’ñRâc v¦d‘Ôc{DÿEñ—‘6%.«GŸÖ㺠[®êy<™ãgþ¥ÛÄÕw*¨?zkã†ÊëåŠv1^ªªYB~{~µ¸ïx³Ô‡–xN:ïëøÓßK1ZëèNîŠ=W?®CÛý„¿«ì‘ÛC/Wçae¤¬ÓrAi?§:¬…2ô¹s’o:))=7"-Ò›ö°*(ã{5¢u}AÁ&<]N aŠ8ŠcäCf1£M Âìdg 0:¢…t ÐoÓjçŽ=Hx·°Ï™£˜>AÅ#ã ÙËèµçyrե̙.Ö>ŽºÅ+i6¢ÿkNЫÈÔ=»lä4Ö×#·ŒM Ö@á›TY›Ð´™wmk³%×q}íìq¶\‚Ã.Pc¿Hj3ÏôtÙCa|: I6`vP†8CbHÇFU»§”•µ˜ŠV5ˆdÙÿ:òñ¯ò1é® ™wW½è.åg·¡„¿‹{MhçZ¶"»4±õ'¬ó×Â}%×ÎYÇ‘÷ j}97U°z6nbhyXXre–‹7Slî~ÖHVWì BÔKUŒ~‘âçj‹©àiø™¹ ,y>†,O+,o½Bö‚åA,E“Õšæ¶ÀÅ펰X³zJšä2àÒ¢¬]»Ž¥­jÛOÕ]ZŒ‚»Ô!ªzk§Vl½¯ôàRG_„³èR¯Ÿ] «ÜÂ^ã:©%÷µ¯+ÓDÔLs`çè¸C†¶½˜m+)£ ³}qúT¶qÜÿíR–Å“4ž3Ȳ%Y“FŒÄýœ®9HêíØ'VH©Ú"-ËEè’Dw?_NÄŸO°èFãÍ3DWÅJ°’iF™%ŠYO5Æ ¡›ú½†Ÿöjßç°½âúquåá¢êM4¢+$Gl èÈC3ž »áhrH£ÈéóÿpûÅDo'mk›#£®IŒ#nYPžvƒàóÀ=W—òü¢½â~É¿ú]Œ}ÿV¸ýÏ^îA6³04ó3ÇŒ;/K8úy6Ÿj–¢´r†ÎÓSGD®{UÃßÉç®ö¹ÝêyÛ0zŒ·´ø‹ˆ0¯mK­`s¬/P^“øEX5$ O&µÌ~¶|}à¿+yg¯ó¿…;Jêù º]'sÊ»È÷yp]Öšlûš¸¯ÿ¦$ÇÞú#z¢93ÎßX>pÃÉÑäuyz1žÒÍØ©¬~mgõ±bQX²µ8à‰V`lÀG´V±)bh+ü‚>³ì½/²BÓ ÇÑðdɇ3œÚÞ!}GîYciÕ[!âf¢¨ª+{H €êÝÝÚ|­•Ü÷äH˃€ò=Fq,”¼|_ÏD¡øïÑiÊõd*éëG?—6¹s•ÐZI”JÉÙb¬VÕ`í\Œ6ak*_†$zKÇ“—!j"6á†ÝV ’vÆ3pšÇh+I·a&Y½H´Rÿ¼ðÑ"™2Ü^|{…î§u¡(°ZTÙªØAE¸þu¦‚ 3ÒWö×5“imàÏ…k å¿Æ6í”ÛH¹æü÷Š·ÔfÀÛˆë¸ÈCªgnõÞüêºÒ¡RôB™ô3›*O[6@.Ñ ÚŠ ŽV¸AŸgèBV«##i’ö‚¦±¤&¬ÀÏ=­Âq­ ŠÂç3ÊJ³¬ë&öI;¸§ð^ñlµ]Î lÓ–³ß¢ÕXuÒ7çСQ-þ¡onx$õËq{}"ÝOAǰè‡Äô(DÎ}Þj–/:YÊÕ`&wñAEQeŒà€  cs4k+reÃïÔmBD—5i_6nÂbاên”'nSéMõ¾C­çÓcóo$³¹ùî up¡Þn‰¢k™ƒ9%*{Å쬻FÈ_îlU%+¤Õ^DBxöO<’"È ÈÒ)d*cp®Y mnRGÅ]`͉‘ ؽ­¡4ò š8²Á/†Óš¨ûƒ¦Ù-†ž— ÎrÌŠ:‚ÈUý"!¥/A|ëk¤»L&bV wSúsÚNöq¨ýYôM‰*¯Èðï'sY4ײË*ª¬M1>É‚‰³8ºLüúj¼É]2Zx¶ëŽ i¦¶jmFy¬âpJî°ÊÞµÿò{Y¢â „uÙЉQGž«#4 _l4UýuQº©þfþŸa„~æº ÉJye÷d…S†«Ó`/¨n¶\ 0)PéQa•5Ⱥ+@éxæp»óeo䯻Z5&%P#UcA¶ÕŠoq»¸!Á*îÝ¡Ûj,– Œ¦F¡±[n—$*w¸ äžcáù…>…þ|í>‘ké º«_¸×oðÒ·µ!à >h.R”ã2…ûƒVƒPˆ—Îä"qjåjg P¢Í­±‘¯!ÖüÆ×¾ª‡^(Af¡LãQ~ ­œº»J¾Cl8à1 Žxšg§§_ö:Oújër/ÇR®:Ü÷7ßPóùY¹ÃgÞ‘² *Àë‹e9‚k½3; ]ñÉnM]˜«¬°^¯Z íkJ†«3y8Ì#Ì4ª,xïí½eÔ2*C¨ŽÃYÞ <+3øð~: Ó7@¸ý—Û‘;ÈÆ| w"¢Æ žÿypI[nk£.g1Ëj´[Ø˜Ì …€ôFs¦‹ƒDN([UP©-²>†r4Y²}¬°¡ìIUÜÞ7Š'epb•Ei®š² ©÷0«ùÑ“R©cÂïÞCX—”!ÂQ´‹ó©Œ êV^¦Íf¬çÄíjçƒK©Œ U¤—úÉSñ¿z.áÜ\ùDM•$¹N}ÔO fkf´ä•PP:»Ie2iªöŠzˆîMþ¶÷]Y)X¥ '¤ÃÒÔUΑ(MÚœ¾•ô•hp6Ä(ã€Ítcˆš‹"ì]'wixÍ‘¥s{ˆM2Ÿ›4­vhGR#L¯cFwúÞ³S¦Üº±ŽÕ\ÐØ¾ÂiQB¡˜H& A©–!¯lõ¨Ýs–ËA•VOJùʸ–p~9„ÂXua¨ámZ‹8$ü˜„‘ÒV)z,ž{U…åʪ«—?ŠÕ0 ¬&š€šr¼úù¯“ÐçTU¹rék~’ÑcŠdÊ1…‰Z,(Ã9¬U‹Ù˜ª…ižü¶RëDYúâ¢Ò«¹»d>ú±aÝ’”ì_éÉš®Ýÿ³VÖ`ò…À 'ª‰4V¯ûXáôÒc%c ¦£LX‘yÜb!$¡lÌÍ@ÅœÙç« š I%Ÿ²49eT $“däªÿ!Ü}L@R‘@’ªç®?ŽOOêøƒÒW›ý[f3]’w·l×%™Æhó¡ÙsÇäéP:+µ[#¨‹õþ „F´EIU†¨Ðëø*¯ü—‰¼»æ2¥ãïöÞDnn›MÏ+Êoô¶L^Æ£Ž6†s ûgÁö¯xøü =ïi;“Öño:^Dç¸ÿ¢éy> ¸>IÐqØ…OPýö–„r)_L ¢ûh¹³µ£¬v'hí³B.ý\”ÎKŒ7ˆñžh|séßã8ÜŒWÅÒ¡®Q£ŸWíHê²²ùÜæ®!u5s%i!ç‰æ½®ÄY}¿Þ¹=ªu“ÝO•“QäK”®ªHd‹{ÙõZÇ‹>OÏ}PìÈûß¹’}GQ\É[ ÓŒ#8+rH6©/¼Q7d¿7/ê<ºÏ¨N»Ìž¶ùÅò4ÙåSâð+=oA­Pꊜϊ¸”Óªp9Ï¿®¯}Ûi°"'̘ÛëY®xäðÖ P0E DR„¥ìA’–¢Ó6‰6©=î_š.?ÿ‡¿Ûÿ¦-(ôomë°ëØ •qÃ:™8á‰hd@ctJÎ t()ò÷wiåv®¯.Ÿ6ù oæbäíÚ³DGù>M×ÇYvb>‰÷¨ šÃ¥êÁŸ®`DT×8¯”bGš,ª÷¨NSÿ±I¦¤'ìÑé`Vƒ^„c°ŒÙ©(f¤PãüÁ†)qûšÄdv¬ÞôFe®jÜÅ=ŒJÔ¶™­~ðcY‚ŽÁ,Àd‡‹Ö…Z’8±‹3K’w“¼š…fÆb$sþⵤÑ"­ä¥5ˆ6jT²§ÚÁDqɬjA~‘œ˜‘" í&Ï<7àøýùóИ܌Ã)öŸöðöøù;9}k³LÒakþ¡œ„¿ëŠSë¨Öš×'ê¹Ç-µ€2šÖ*ÿEGR¹·úm®­þÜÇ ŸWˆÅbô»¡¹ ¨Kè‘it÷N•¹AV§¶{6OAš. ª[ª×Þj‡ê¸kh/Ê+6ªÕ«7üDC j_Ùëu×§Üú5f@,ÛÒª÷}w*uþ·¡ÔoÌ`QÑ/òtj$›™¶„ÿlŠðÜÞ,‘z[HÎ WùxçÇ#šè‡$d¯¦üΊ 3,ERŸÊ“@Á¯“ÓKމHÿbÿ™Ð˜éëý@\j9£˜ý6ª¿+¶ÁJêN0´k@Š~U\*ëžò–û›™Ì_¡b äCù0ãJ’°³d£³F›(ò Ô ¾ôƒ9©×AskghѰ()àí$RÍKúÚûa„Ž`„¢›Zòcqª»”ÿœ£%¡™éÏÒ—¨SÚVÏñ‹:òeÙLÖºRd7烤{Œ¿¸gB+½fôì¥ö Žf4½Oúi3ó0tØ$ÈËË‹5§/+¢ LY‰ @U¯Ÿ‚:.Ò¢ŸU›yr"‘B„‰ýrÓdŒ-þ©J§ÆàH¹oüNçöZþ©úyG¡¢ÈÂÌ'¨‰ffiôóVÀ—RÔ±Š²Kã#%(újH ª»IÏàÑ¡þÿѳð4}:hǯ+?ÞäA&Iœ‚QYåY¨¼Üq˜ bµë5RÒŽ·þcðµ¨A«7䇸BT’¹W5.5í[„—óè³£ñNç§¾$»ª­’ø±-Ì·¢»i[t·Æ+*X©¡e1YU­¬Ò‡äþW¬òYzT´CȪB­¤9H%i)WB®Ë¤¼š—Ù}+EOR(K@”-)i´Š-ÃÑ Át4ÎÏÝɳ–ÞÖ\|zEX¿{Ñ¡Yœý>Ÿ·0ë¼zWFÁA’‰…!ÑœZ>¸éÐäö¤->Nn ÄÔáË„á$D—$8 º—bpU—ŽA5Ó×øËÔ¡ú±©â鸘™ë¨ö¾YŸ+q1œmCN1´[U¶°õ\Ñ®<›YçÝðn.Xîë«Ð ‚Æ›Õà4ó¯RçfU½,t¢ÖKò4oëém›Ô¶-Åh‹¸cl¼ù»øOž£‚¦Ï²º×¶žm¨éÝIFaz³›$µ¾:&“ŠS=¶ÝY‡sà+°&G¹ßñ#}G«Íd>¸×Ò{@o…ûÔ+‡ÑÔÐ×°:þ¦ÿmWvö™e¡ *k4]ËŒH¬(7üqÉgS;-µÓèq¯Û»A‚£rŸI¥Ž\²ÑýÂ$Ô¬†•@;΂õ¶«· fèø®dXuÞà“×C¹¢?RÀ<Ÿ¼PŒÖc[|П`Ÿ¸ ÿðìhØm$$“û.¿FØéJ‹ÚhŽУ·ý%®Ц!¤až°m¦1–Ùëƒí øó(ºj¬ÈÌŠ÷-€cž¤sBs@ÿZð¼ƒé$ Q¿Ê_­ô‘qq=¥ÎÕµ–*`¨ÈµÇb…ºŽ‘w¨±™Ÿ»F)ç@¯Aru¼ú pkx+ÇÍÓ*­êÉab)ý–ÀHêz€›Z‚B­{[XÆÍ +VE‚ãÛ]Ç•Áì -< ĶcZõ¹o…•rVo¨a,¯ÐP ƒ ó.|ëiwÙ¹5k >Ö’2d9ýØBªF¾Žµ¥ 5r˜…$I&ü³ÐÆ^>«•l]ŽÛ¶~D[·#scÑ6l(®9Ç\¸jêé§F!ŽžÌ°2,î¶ÁþçZó. “~Y«ðŸã:âÆ0lê „O4³#i=Ñí²ZªMíQ”5vÔü̸0œ…)š9ꢓDV Â¦hÍuT 3z7!ëÃð¯¯g¶‚஫½ 8@¶»ï“Gæe—Nê1Uu±ÿHz,›ª¯eT«,B§)ò ,<&x…©O]„6µnºîŠã•lK‘Q”ô¸]e¸µqS1b¯~õ½6Äô=2Z8î¼0 9 Wþ•|uá–¨5rTcäæö-…Þ G Ú(Hɾ éO7cBZ ·Ð5Ó-×,ÛGIÊŽãpŠ7¡f×ûË3QIIžÒõc:"=Ú¹)¥ »€'Ÿ¡Fò<Åö™è[;Õ[X+0@¹-çrÁ{a·nVj*,V"„a\Ç÷-@bË F ƒ ÄÀvlьѾ,ÉaÕe(¢£-Œ —)e7­âµAB›©×;qsºÊæ-•aËiH ¥ÛVì&Ò趈Kz7Bè.몞’ Öæâ‰‰dTÓ”*ðÆÅ|Çôè—BÖ-þ ”¢K$îIØJ¯¤ ’ú…e$×GÓ:ê+‹~“ë·`æZæUØ”-Ô 3vë‹K“ ÇÍK2Û+¡q2S‘lÓ¤²g1,ö aýίvPÄNIq²ÚƒΚë~P”ÁWMu¦Ê¤t±PÄŠþëØYÅ‹_5vÇ*ô¿ì(ÌÕâ´^Ãa‰ ÜmЈI¿—A²]P3cVÙ‹0vÌýúÀ,õm_·^VJ?Í0P…Û˜&/ ÒÆ<®•=á mftgôHé-Ø``@Ìi/uà늤‚†8È”­ozÙ„Y~¢iìq'‘_a ðà}èCÕˆ îQ,Û]µ`²2â ‡d+ èZì¯!É$8k Ö<_<_æ¿¿Íu|LW˜Ê¦KD$ª»›h’à~“^åº-äñ¨!Ì2µBÓ…•\úy“3¸Ò!|Öná±§HíÅM?y™4ŽÌæ±ô²ä µ¯eVNÅÖpX¹Õ±®Îi&£¹BèJZDýÖ±¨8ùXt-þ­5”R.Û”âöFºÆÑ%÷C]«\bPi—$’çáy %$´a±¿`TÁ[àQD½2*€¾äuÓ–Ì:Öe-zY¶z­e¿„bJì\K#÷•…jýªŠ¡4æ1Ow´Ÿh5@ü|| þÿ°KÐq¢˜¹wd„Ê„;JE)ãÛgq$€ ŽA²GÝx!U Á‚{¾þ›ª­]ueh¬!÷Z¯TÑœ£tlC¶ˆÐ:ÃF²ïçŠ)ØÖÌvÖGBßÕR‚f´¤CŠˆ„¬Û>”LG½Ù»&'õ&u„שq¬•H¸‡—2jÂÔÿÌ07MrÖ_©¾ûp•˜Ç#=Œb– ÓUÖΰ~v»V;%ßJ’åÄÒD¹åÔúÿØÍUl@†+›DÁ!å+ƒZ=ÂÒ葪ÃÊWMØ!â†Q4Y/"Ê»ÜB€ü]yäÍYç‡N&&~ŸNr²,BÅšË(  È«!yŽK‰ÂÕ`t.Šõ¬HŽì’ñó’°}…. 6«ešžtj±½òVdß/ËbûÓDøØVÎ1VòÅÍ®»Fm½Ü8ך‡ó– ›š8‚Zʤ™g¥Eu¨µáΞšcºÇŽ‘Y ”F[U6¤WÎû¬;²h&§ÜuåJ¹{˜ö£“—©¦ŽUá0ª˜œ)`µkŸýˆô I,-Vd$®’&X9ë2p‘@Žá–VOiuoùWG•æÿk?ÛÇ]aôŸGÇÓ°ñãÕñ°órtù’I`†V‰™wÇꬨÍ*Ø Vw´Yk½}ù=ªvü‹*Vró­³ìZ˜ Y&ˆ•QÇ™â…?è‘´>ÂÀ“[‹TÈÊN9ø« YÃ0eu{*á[ÜEÛ 9äêwxé˜]®ÍÚ‰¦Ï¬¦‰¨;&dÞrãÅycÄYZiB#ˆÂ‡¶–48¸Ïlr¸ÿŠ{7s&¹—s!ý Ñì½$òò‹ŸÑ Årf$ßÓ Ìz¡¡ ŸEì[q~ß{»ò§8Œc¨d}2\nN®ÎïYÉ­Òã‰ÉéoôŽºHT±ŽÍT‡Jfhr,·Íüøÿׯ¼WâÖ6ûþG°ã6vW¿I–-ì‰çô ³©`ýM¤îŒé Î@ùêô56Ã;Éh‰’ܹ?þG]?7Î#ÈôÞPÁCâ™:^?±ÏH:…ùÌUò`“C?,¬Å½˜ËKNg8¶³Cxæ†;Ú¦ÚÆ;åÈr õ¤ôŸr$òDXúo¾F Lµ´ uâ~£õ'·s¢²scÃÌœKH˜42Jב ш˙bkY·,¤tþí?šr¯}à_D^…u:¯É¬lÛG¸¯1|túO4yzzmqüßß_Ýi0ŽVxûÏ…¨Ý¼Š5¹Iîpú>­ÞÀêù.¤IægO’ÕÄÔæçZf‚d¨— uuu2ñÞ%l‰Å%L€B;'A4ÏDžmÿä$æ79¾™½=áø‹­4Ò¬÷»Zxzf]Ö)Jèi–Ççíë0aºmuˆ® â‘ì¥Ïv€ü±å¯"ùÓµê|Ç厩îÏÈÝ>‚®u&žv2-é–«çä¨K©ŽºY‰®®f`“¢k$ üú¥¬fÖuöV•¦,Â])0#¤&i2[//$.Ý­4„Z"–¹«¾~úƒ­éÚ´‘ɬI¨ÎÓ¼Íc6.2²í¸Ñ‹»ÌÞôö›ñиf·×#-«{ü j¶­]G¨H­‰{Gývšü!_ª€j³Y¸lÈJoª¿)šÅ‹2’‚¡ëk`~ÐÄÜtiã±÷üB5áãM‰¨©n5â°R ü&,yŸ¦jK\7ÄUƒÄVe(ŸuÙ þÓEF3k pƒ4ÈÏöY‘^±{±ì±¾Ã:^Œ@Ç[1V>Êb%— ÅoY©«!|wT+ú·•ÿ§ã¥qä“ù'­„[ØÑyZ(:³öš6V°»-A‡ÿMgþ6µm ŒKÅÀCkÔ]ózIþ }Lú›ñ·Žü¸çƼWŠ<‘n7MÂlu ±4,6Ázcç#Ÿ”vÕ\¹ï®çk ‘ŠþUÎ’Ùc£ ´Ê¡)XµeoQ5û ¤ FAÖN¯eÚ†®Ð/PäMޱ33Z^Öý+¿€mÄzâçÀ ±e˜o’Ôò¦Pvfa!Ç•û å{ÚÕˆ¾fðË+žù´–¥¯¸¨ßÒ긚BË¥eǃ3dÇrÉ@1ˆŠ24‘ú~â $0°:=ì(4Ùµ “¨a6rÅ ˜Õr%€+=nÞ±£z¡~UЇm×=Wï£Oþ<^*ñNÂ'šÍŸê Ïqpéy2x¬[üZšw˜>Öæ@èCÿ`§u™Ë0‹kà]š@ø»ÓOâžc/žÁG##[3–ÉOžÂ̆»7U ÔéLìÕ-%¹)"Xǧê±$`!böÏç/SÞôÕÅïv¾]ò6ÍsÙûz™ö(5Hw¡,ÑRïé’¢´ÜH¤³ÍžÌZÿSt•«N;ÿ’þK—“UÑðÿñâN·ÇÙ!è<ù­‘•}M|jCúY;ùõt³•„‘‡—Ò¢›Âí¼îâÌûC#;V›r|Û\4(*°Æ ~˜¾6³J~Pi·Ü±éâ8cƒOÇhÆ…väÌ»ok¦ôÍ{Rn ×]ÿ!ŸÌG¥ã{¹›š©ùWËŽÄôõã.Ÿœ·bµÍÞÒK¦îYy‚Šå¿N ³œÕs/c~ôÖ ùþs  ™ªüzÿþM}Cz÷óÖgœ÷‰¹âT8ì´ñ|UãþWM´øÅŠ=5Ÿ¾àñòg¡êw抺›dæ}ùJ—T¦bä¼×é÷z]Ý^Û±éö»žç§xÛ}OS×îiït»ÚŒ@ú›;å>–®Ë§¥ŠM :õnö,²¼ý3 tÌ`Ùôíò¡¡kÜ·Xƒ‰`k/z{ŒÔÁS1Z1R” ¬î•Úx8IË y3¤l¨%R!€°ZXã<ìB€5¸ÜGKK¸õ ¦’H%’(Éö¬‡"ÿHk žG“ä׃×@ž›?—%|]ãNŒmí÷qeMw¹ît˜çêuL¶õ69 ìô].˜t‘C°Â ÏP*{ÔˆŠÉš¨=Ez×óQbOš·/Œ›Oj2#:»šº;—ÒzçÚyÑä#©?ØíÞPOKèJOUŸ]«Ë¦‰)ì².:XÄ W³ù¦š’&([ÊᘽÏot,ÔZפÝx‹ÏÖBZ¾Í¨Ã˜û)ÐŒýj’ì² æ ÈÅÚ¶aÊKg옛حYu P±YX]¥£a澩>ܧçp"•£CÍX_?µõ»?¿µKMnDÃÓÚ«7ò#Iò*21…C)SdŠ<ôªÎ¬ `Oµ é³py } BÌÉ-p,Á;.os^¶ë!FC1¡›½ß@}Xùÿ%‘7 ÏM¨½)(U&B 2©voÆG>ÚPcÚ¨¸•›Z&ëÄV” ¹j—»6›–Æf~p:XUA†/­kè5¢Šü¾¶ˆJš‚ÍÃx 'ºäü!Ëw—ÈÄÏñ¶ÖÎÆv€:¾Hú:6ù9˜Z[?¤{ÈXxÚ¶¤j§lÃBd¦yµNÈÕúË‚šlA‡+%Ôà*ïÙ G›,¢¾~8®Çÿ³Ã_Áíï­º†¥©Ú);?UÀŽ'4ÒK‘—¦Î»9#wü!“ñ䎭I)-žÌÖÿž€ úZèUˆQ ˆ­oú›t§ ÌÔìÍ ò¶1™†¨} èg¿æ@- %a¤ÇÝBÐ" ]h‘áTM‘`è5B¤U“è †%†¤¯,¶yép4únÏ«æøü1Ÿ_ªÕ;‘”¯ây«hj1eWÏ®äÙC ĉý‘ó–þÑAN¡kdÏDûC§áºÝîSoç‘»Êêiäo(=žgI`tV‹ÛA†žNš\΢ð¸¦#9 mUÐ<Å4Ñ Îs>7gb Dã´³Ìê·Á «=ß* »óT/¯i³þ¬h˜ó48ðÀ³&õ¤ ‰ÙV9J1 #6.JØ(ŒÙPÈO+³-t”g9·ð2Œ—ì´p"±Hd \-Ô̵F5Í#·É’)+/C}"ø–@„Cë^ALa2¶¸— °,QÁ¡{·R6ÁTf0ô,z6WêMVFWCel­‰Z.ÄÖ„³mÕ±Å%¬W¯k1aPe-ï#t-ªé1e¡/d -6ÂÁtÔÑtõ=QÑÔª3‰§;þÁPwmVîäè4v‡hñÛ¸€)¹<~ôøóñûõ+Q„b4’À»Í”FMÈ@+sJ¥x+u|žA¿+[=#‚{ŽÀY™wRäûFÊq‚£M/R”‘KÜW³7Š´"X )ˆÑž‚qßÚµjá/­’êß#uÐŒ²©Z¹W¸á •Z WØ1³é<¦?œ½ ½•n?±™ ª•Súì‚j'ghBÜgRCQ& Õ'É €‹!EÄøDòúj¸Ö¥)IcôÙa°jb]I¯Ö™Y77ÓšJšäkçõ'2qÎ e)°Îà]WW&Íú| êfˆ32COƒfqqBÁöÃužXŸéñÃÏP[ÓFU°FjµkÝfÍ 9I7[$Œ’Z§s5¨å;ÝßóJ6("ŽFcPU€T¥lÅ"!D/žCa:P å[†¥r,³¬¦W7ÉpÚ²Ån gúù™em–X… ýŸôµQñTe¥,÷ƶi›:ºñkÞ†J`¦t´n[°æsÅ}ëh#'‡kFaµìØËõ~»93·ìË&DØÕöMf˜ °[ip+TÊ…B;¨cL³¾Ù"e¦ð þÿƒùýüôGÓnàÒLÓ±ß$ÌIä“!”4Ê û‘]€ð›ˆbnQêC2%ki8Â/w¢âƒ]Oƒb¤a:Ô!XPu¨ÌíbÌÔ4ŠLe|ûdU–EF]­d…`7H*Òµ¯ý¬3˜8làÖìßÖÑÐ8ásMJ¢idç!Í×Ï­„å$b¢ KbÇ訣0d¤šTd ´.R… ¨½Ï¡W%¸[<…¼Þ¡&':Å~g‰¼öÒP$5Ý\ Δ*»k}ì¦Gsnu“ŠŽúºË0´ÔÍ­õd˜ÊÉ ‘Ž0, AK)alEž,è|vOiË…<ódC /¨c„Vz&y@L›x}«jÑPH× æê·/fåÁè.ƒ‚]¸Ì\߬poÎJ‹dØo(”þ¦îÕζ{`‹ß\a-³ÙUÆ_AªÆ….3í`Mh9¢FdЖ%ö?´¡35õ’¹ ¨3œliغbç—Ø Ý‹ fìÍkT&“\±³˜TZâ÷¿ÐX¿Y½Õbç`Õ(ÎþQn) ûcÊCì2/EJ9–×:ád‹X2C/j±H´Ò£_Lç,ôÙÑ“MⵆFFlô„FH§(Ùœ2dî}ÁÇš°C/Ø$ÞãŠ(FfŸü‘§²\ñÂÃhFâT³·Ù´kÀ<ü•±yûËÀa3lj*,ÅWJM2£õãÒ¬,Ê *Âbp+O"ÁîgteÒ°òlèqiê½y¢g!Þ»F”aoî„¥¹ëKÏÒQÒOu«·íÌŸ•¤—/øPw©¬T-çÍ0üÐ0þB‘O¢ãa9iÌÂÂç©EùOs× +¸aßœ{XÙìn’TëRný"=žÏ2µÃXR?26`O¹õU€ŸèÃ2­|¯¡O{ %—Hôø2bÏŠ\¦Iñˆ]ÁÕ$mÞ¤l¤bU€Š X îû“HÔ;GQÃÑ&·Kþ#MWÑÊ»"È$ ”*²‰6W¶¾ã˜Ìذr™9€PDðdlÔ{ZÞÕúÄH€Ïå§Æ—]šÉšƒŒÌÀ)h¸ Šü>q@5b ZÛØr`Ô2{^•›Œ¬É½þøùUÁ×aJÚFxjãóú«dæ¥:ëÌ ¿kEIb£Tö­lÀmb5x½fÒËÿyyØ0ØpX5Îó`–G´Ïüïó›Šá´VgÚ+h­«1þ?ôÙ¢ha0PE†ôšÁÜÝ’IrÚ‡^5wV|ZŽjæ1'”H‹‰ =;Fέ¼_áÏ$ð:\ƒT“z–ªýµ½¦…fþð¥io•mi‘Y‹Sìù(/¼B÷%ˆiµTÕf!û›! üY¿È–üòÂã²÷úšƒ6†¤ËU–IV$¬ËWa‹È´ULV/$t_6/ú¡C­U†ÕLµ=—ã“$kÒ)1O°ƒÿÍ Z³…ÌefocÞüäˆÌ–«Š¢¥ðÿÕX³A%ª*4ÅEb¶<Ñ›ähÑ™Z_}MèyÎå îA: Ï´ª–»²¨Ž?ÌT–K?•[ñóÓvÁL‚žã´‚ç\ÜL—gêÖö2×¥¢· •)ej\´¥O—3ˆû‘zâ´Ú¡ÿªÀ1l9ˆVÖ0Ûª´ ©õä(T•úC1Hx¿ç˜Fòªa°H5,,5F»ûL2\åì[«zŽÕƒöT…-–e†Eî9Žfã¾*íéÔËTÇeUr‹«RÒk<­@)¹o{”犂 úíBI@={ŸZ=£ÕÐó¼|_Á âˆëráe?è‚VâéQ‰®>+÷ý¿ó¬!{î%h»¤Z£­ïZI¤!`)Ž D’)eFKQ”,OÖ"í¥hâ nËÒ·ó{åïF>Žõ=6øW™Ãk¶w·ßé“î÷nbâòY]*\ùXe|h±ôú <ŽÍ(»N¤†CWA¢kâʼn›$áJ?öš²(ÀšR´8€EKîQIª_úþa‹\‚‘ÄÅR†uòÔÊéŽ"Mõ2,X§Ü«÷ºÄ©o?OÊ""$ƒºÅ˜(×ÂÑhZ¤8º®,qd$sÆ®;kFÚC2ÒØ°< ¢x¿Í–‘“——,Xò6<ÓB†FV@ECW$ñ¶øøçÉëÔ§ªÏRž°zEü…êÊ]‘ÎûØÌÆÓ––幊é’Ì<×)̦Oéqí¥uÄMWH‚ºÚŽPUÖmÅ!Q*™ieTO„ý &+ó˜1 fÖ¬0zÈíIÉŸóRºte’Pl©Zîß§%î›7/倩 £LÁ,Å o²—<Ü­ƒ¨jÔœKX [Iæ–B(‚dÇ‹åhRkJi-xŒÍ R”¤DÐKØ%Ÿ²K#î1[Þ£-èäSTøð@±À†P)”(_’>¾ ó}YHÙqêd;ÌO .C™I$©¤6 /ŠAÀ¡Ï_X>9ÊzÕgE&)JËC+íU0C@¢§$0J…Â{1ð¡¿K7š€3F¢Ä-áx*@#ÉÖŒ ŠŒT³j¾¥or}£‘X)MrDLufµˆøÁ'áZ iâ¼ð\¸KP²_°Þµø*]!MHVJŠÂdjÝßïZÂ2Õ­?Ñ8dÁ2¿ÍZÐÀÇG Ì Ô1í[,9j‡ A†Ë€0íÇB@Öa˜ˆ¥¦<šæ¿é]~ ‚PÅÕJÓDê6²›_žAwàÿNº5ÊÈlc³4#8ÄF¥kX½cäš´÷)½mù¤å‹V¶$û—ç,«²Í>@ûGxú¯y ^Ä‹DMjÚb~-J/®ÓȾÿ”ûM]ÛÚƒmûvj´­„+Ì^Ç›ÍÂÔ6°ÉF>û܉<ŸáPB¡f -&¹ÈôjNÝBPM.&5H­þC,/aŠ n@ŒÃlL¦ö3C,±ñŸÑXÿ5ääÇORDŒÈhj(ð<ëùëZé™úŒ“¾›‰‘œ°m9bÄò¬a™TÚ ²Ä|QºæúNXÿ2Ð:ZµhóYˆµoH`÷¬XÅ´@BE"ÿUËrDHèY¬ÍÄ«—:`°ÈÁÙü¶3ë¡cTR¸%R(gJŽ aØùë£-”3g-bª™ÝZbqšºÇˆ´e-=ŒYéðûi[û‹è1gØ–ý`úí2RÚkòUšÖ~p|úܦBáÈd}x‰;kÃŒÊdhE‰\h RTBF??Ò¥S3P@”ïÌY0~ܔȑͅ+½AR¼’%EÝ.ÒhàXÿ Ý¥Ü ßãÙ“`éÚl Ï‘¦6/GaD4]8`ÂÀº£wÑgKY‘ŽÄñ6CYxbù–0ª¸V-õ ±™ŠB7F°1؆×Êr’:ß9 'V¦0"–j ÓEPq±±k±gõ-÷ºÕލ‡gX¡JWØÎ©¾, ÄJ!ÁÜv¢Þí¥iÿ٨宸ˆÏ‹:(¹ÔzŠ@Zr\¤°åeÓ¿àü‘-äüM-b;0{þÄŒ ŸÊë ¦ÒÇã?RÇ™¶\¬¤&³`m1» êu½Å”̓§æe1OZ˰Mj3-Ž×kJÏ71XÈdG°¬!\v(]±¨¼ÖÎÌC;ÇæÜi3>p¡l£9*”·Ò¿¯J²’48ìÛÌ—4P!m{Š# ªò¶ÓüížF˜Å.cÂ9ÿCm‚g®2g×2‹ç[þË.(½R ˆp,íBª {¤g?Ưsö~+÷µøÔȧܥ%cºžcéæUˆj¿”rC2Öp¥ÑhNuq‰¤2uÈgÉ|Œì¿ñ‰ê&BèYC1lU_âïäøá_£yØz~uÏ› ™cЙ£IÓj®Dxåñ#ÈyI»¥g£íq<·1G¿ÑåU5Oû3¦×ªÊSG@þª¦ÈWhÒsܶ˜`äÕZÊÙ*ÉÖºµÎìuüë(‡SÅÎ2_ê©"ÊUˆ% ¼6+µöé}€Øp3%hÝ•[*"-Òü‰¦7·Fªµ(ÓOã lU ê@þ¡õ^¦šn-T‡©+.*ÀXÖ½föúk`µ’^½ï µS±CÚ x¤ƒãbA­bÚ”hÒÙª²Ã \z>ƒâcLóJÌT)RûUhi¿’MŸëÏžýõõRÏÕõl80° ‡ï¤Q ˆ³n´c´¡ (k+ǃc§ËýZæ(>p¬1Ѭð®MZˆ¥ .f _š×¬Œßmé+ªŒ‡+ž‚ “Wî_^ v€‹d,(Q™jVþ!:¿¸Ì˜Ä?uW) @¾t7µ }ñáøi*ålKŸ¼W½’/ŒÈîêÎUbåDv °0²&ˆU€`æ,Õûz~ôÉÊu~žK×íó^yÌlž³Q1Å|ÖÏfV³)SY”¹-"=2%_g."ùz¹ aè”yU~¥l4DȆtŠ-àS¶éÈd*nØÐ>?b=/ŸºuM=àËlÄGGUŒ¬L•¢;Kn"âêì¨q¯!M–µG˜X³*T$kâ"EÖ°n+ÌE¯!]R~," U½˜‹¶GŽu¼¦·üÓ.sW’!"‚"pµÇ3®Rh˜ön~ðÈÅ%\¤:͘ÒW+«ÜLˆf$Eõ]@™xèÝ—^”£lµ\Ïèi%ñŒM¦CHòoþ4,G×O¼…½‡7‚´8ÿ²ÑQA*ÀbëZ)ò¥oŒý–û†½­þîàØ ˆv›*|Xßàÿ_éû^7Ôé…ždÏYCznUñ > µí,Oƒð>|’$ÿÙƒ Õ.=•ÌÒ\*èÛ(±›@ª„&_L2Ó 'ƒEÆ¢ #4X-ÎÎÄ$UEQ;¿m’ªÎ$Ë$«Ut+ø—¬ÉgP£ø ­fß­uêˆhË`¯á´|ñ+ƒ¿]€3’`:}(]ZUm™ Âõ!aÍeŠØ¢¸¨zT…¡iIÎÁriÅF1¬º‹h¶±ÆÙÇA­ÇTIgÊÀºÿ{ ü™ª­KŒnS8쬠ךæ$x¬pÄÆÑñfÍçÇÀ'€:éï§:Ìý×ôûQÍÍ0¶¥¢ØêÈÐÂdÇh gvD?­^c³óé±ø=2yU$V8ÿ0.O×7­Ú8?<ŸAG ³0y1ôWhšÍ¨ˆ°ì£ö5!y!« ´EÕ,„+ÞšPÆçYëÞ÷"Oh(ˆi ‚¤¤‰pÌ.²2eîQ™†…Æ­Y¡C®ÔÒmVÅê(ÉÕª€ QY øþl4Þä$ RC`1J—Zô`#4Õq,îÀ¡BV|•!¾ ÕÄ´½Wµ)&¯ßM˜àHô¦ä#kQ VÒ@5\׃ù¡ÏG]¯§æK§ãÇŽàMC"T¯¦¥P)fÕ=ÆÉ¡Áùè‹Ê”kU]Îi¸SvËY[öå„ÔpªEeÀ¨OUÈl“òˆµJr9˸òG ›»šg(Q•9±êµ`]*®K‘W õ\³KŒIYåÀuÅus™csè ‘j]&s®;3 Ä*öL3Hkübß 6 ûŠn³U C^¥oŸ^w ëÔ¤öu+]?¢ªFvœ”“ Þ´³!;3Ðñ4¼ë‰›Q ;±O‡¥cêšÆ6ÎR,“é¸E;ÍÅ·jŽ~kÁ=?{³¾5_§ßKµ>æÅÆ#WÑpÒh"ÉõæY"ƒù±‰ý7‡õ#ÜK(_ú~êzŠàî+È DÕ!ÓÊJô È_müº\ihEa†"ðGÄÅ%x;¬AOïçE5¦’1E¬SÁ©úœg퓌ΖÊŪÉãëè³"<ƒÃLmVN!C¡V,ÄÏü…c†(·Ôä×½BQüZVõdqìAå_®ÿö¶’E\üà†B ‡Zí­X‹±EÔuü׊ rý¥(غÁb3E­ôB« Ku›h£hÃØú>2R<Ê’=VU‚,› n­¯àÿn¸+Rþ)¾¨÷Ì™éñE"¼O.Ãì q24„ °Íî`9j=±ü¯›˜(}ÒÌj•’¼K§¸ÝþÀTƒ ×YH¸ vYaˆƒ]›~Ó_þÒZº&ÒxC”_°wÖ9ï @½dŸU ÚAÿÛYTHpˆÈeíbYÿ…½+yc´ðß}×x§‹Ëɧ ƒ}nþ‡!«¨ö"+ÂýùúÖÎc, 髱Lò@Êçmæœ\פ¯Rß8NseÔ,p´Ÿš,QAI¥b8€å1-ª³’†£Ì‡q!†ío‡·ô÷ßi*®Ð—` `x$Q¾ ý“Ðt¿V{Î8=uÊâNîͱE;§¸°˜í,´À«0Þ0½,æ¸'ï$±ÈÕ©NGFÓ»Ú³%Þø%7­î])vo6JÆ8ÈØèt.Ñd` pÔ^¢N«V¿õŒl‚ÔŠ’ÛýêK ±!¬p—îZÿ20×`¶bÇz³cͦשæHzÔŸ}Gð)Ã÷Óñ°ëõtJÁš]›Ž[úYâwCбÜîcQ\/KÎË H%è0_Fµ¦¦™$Üp;¯ñ±}ÇõI1;sLÊɆC «}¼RH^UªÇÜAà( ä| û;¸¾±wÇoöö«yزeÄšŽn&–éÚ{MÌžðø”Dx˜¼±»þÀl7SgÅŒ¼CK-µÔêÈ?ÚóžÕwqÀµØ¥-"?ôä´@ÎÅê›'ý Þ€j„–`Õ¿M^[ôIâ>W›Î·ñ«é/¦XØëtýÜ>u×2š¦µ4œeçê «M&–u^Y™\Š·´¯Ð6AGü«.#z‘:•]¹Î(ÕJšIú4þÄñ[²Z´8-tœV-Pke™½®ª+@~Ôü"䣨®#LXã$ ´1ŠÅ¡sšß¥¢1mž5ÇÏ9}ÓÜm”Ù ªdJI¯MÊÓmÊŠ<Ç]Vàþ¾‹dh8zIìm'1Ð/ܳÁ•3… d|˜U2§`m€Êb¡ªÑ‡´vIé÷×G¢n«—ÊÌñ2¼wƒµz/ž‡‰ëÈr~7Ù£e|YùFÉá)nQÂË1ù Ò¬h|ÈY›DN·mæ„}˰̲Éß´ … v‚–hX˃±Ç[Ø•è9½>2>$KÙ—)?{£dªþàº!‚ŠKd‹ÙQ¢Q\ËjZ%K*GµÊ`Ù³1XZÊ•tzÆØÖ#=*ýI J=´ÛÍÐуÒÖ[Ø%«!*ÿùVƒäéÉp‹ä)¯ >n³ªjqå P­:3-‚E³°7\ÑéK©Ý©‡œÙzqMˆÖßiŽ32 L«e«ö²]Õ™¡ü¦¹ã+»Ìày·ªò1â¶¼ˆEÞ£‡äð<•Øs8ø\¦ÇD븜—QØp¶Ã'M"[hµßÊ:YÑ Õkäjš(ø÷’þ4ýäyƒÈÞ+óýhõº¼‡ŒyßyóÓ×Åfàê¹Ûpš yœo¬ÐòàTÐÁO0Ö‡–ÅÏr¨k:ˆjǰt"7“{g4ÿ8Þ†“*s:/l -¶C psÕôQAmgä­[SRÍoÙ“œLÑj0*Ñð6×.­2¿"g‘¾etèéLV i”öúhÍó­1'u·gÓˆ‘Mb ¤Rý7ô›ÇjÄr ;}Üü¬ž¡ØÈ°Ä–MWãÇ^mÝ«dýF:6gÞÆš^<Ëö‘‰–\ñ¤gk»•Xû±¬¬~E>eÑãµXd™<'/…¹Ñôš»/S 73 ᔄÖfURRDËHMDê¶nRÀý/ZV¥VëöâªØ«*Ë'@fQ&-T´ÑÞ‡Vl°2ƒ÷°þd$ÚL i³,¾ü¯æç•- —%š« €GÞE´À`'žc´øOùØ® —´ÿmyGWúÓµDW#M®¿3 OI_ì“TºÚ –f¥NÏÊUÜûN[¥« ³‚\lè«e´éï{¸Üý„–ºX|2ßk¯ÏÈÿôÒ%µ0Ȱ´APÛ÷†³À†5~|ürz õÙ9IxwÅLÚŽ—_gÉýºµ¹m½<c“ä²²¨”+þ›¿7ÍíqÝK ë„´ÜuîŸw+U'ËsÄu–ïâ‘â»»v ?"óTèý#›YSògwãf«òFÒ•/ Å­E¿B¶hÇ¥¯î/CÏGŸÑÿ§Óvä ùÌ£s™vHÙù©£š}”eeÀ*/K=ÒºBY×ø¢<Üöâ£ÚAÅåÒ>:JS¥Î(Î~S6Fn.bMl8’«Ñ*"».·¢rì6ÖŠ…fhÌújÛÀÿ ˆE]ÊQŽël+sDßÇÀ/çëf¤€7é*¡hsÈ~|óÍx蘋FÜJ‚j³ ×Þ†¤|HPC9¦,Á>7£5`•´DýW“T¡’ÌÎ^yBÓouî2¦&ÄvÃ=,À¨°Û%LÑ )s°G,&-ý¨:M˜¢JG¾(í©Tt¡‹­U, ÙX¥üN#Aý+·{˜sJT´×<ŽÄ­DK`ˆ©*¥j¤ŒLQêÖ¿ûƒu&ò ,0½SgIµåÊ@Òªa+ïfTÝë–[90Ñ©¢%²Ð>A9ù¿šüzü%vQm UÁ9ÊÈ  ò*¸"”·›ö6;Ë.Ò¦Þhä‘Z‚ EíFøàu¹‹žFÊ]ªë~‹C ¹©YFÉ!« ¾I$ m3M'FÏ÷1õÒIih©¼¨IB^cid$U¬áw:÷³¢m•A¦¼6ƒi;âë,6Àd{B¢¢ê®:ˆw;3m:¬  Ù©¨vP¡ò[lŠ9¢*Y2&ÍH#4Üш©–mÔƒTÖN3WÐjœí4^ÒÑy›©f.û“‹–=ÌÀâÉÑ .žŠæµ×t˜5U +þÖbÊVEÈÔ§VŠ;AÀR7¥—ý-\Áºæéß•¦h0<˜®™Y[-Á ÊJÄZÆ÷¼ù®¥@»T_<` 7lÂ*Ôçų4ÄòÁ4ªsYˆÕftM'¥[b% A)kðHµpíûãç¸êã%ƒhÕºçÍÉ`ê”ü¥X–,“á Ýy(;Èÿ5BOˆ®K„cZu…2©´* ¿äR—Ѓ­å™oa•£.Ű¾{°(=)),o¼JŒí—£ÕˆJÙJFC^ô6u+6ÿqZb°½ÿãiÜv›Mî䟶×ÿ(†›èÌP•pC Œ€P/*Žx@à]ñÓ»ŸüF8d’úQ)ÉfØ¡Éà’l(cð@ªºê,àê*ÓÙWX¿Pªwí#`Žºk¨–^•M{‚Bµh >t,ÉJwåöœ~av ™¹Ž(=IAÒ¢¸‚ ?²Gpz&õÃRÚŽ¬°îª S<$‚¤0‡=´±ÁT3Æ ýÄ¢V„Îzϳ:†jB"é¨5 1ßY3‘3®ÄR7 hÚ¶nv0{¬“nç‘´L¹GïK*þHÿô bl}uÊA‹Kh_˜]Á™‹É:¹ÊcDàT«XÒ·5ó_ŸdötåâéÙC/t˜ñ¶\ÙŸNDdžådVV%À!Ad&Ààž˜½—ŒóöVýjÁ‘ÖhLºÆrV—±£âЀ´´'U>À%*Τ `ûdP‘éîPgªÿM[µU,Mè3® 7'û°bTA ˆ+Ž`e´Âä4@Vª°],Ym…’~-GéV Œ*ÐßnUW;¥›3ÿªð8ºC¾„6º ´K7a6ÿú}0é¨[:EÛ5Ù•ãóÍ3ޏZ­†›Vd²j]\æóPS…kVô­,P”èú®V.)GË,SqU‘9  Å5€xþ¶‘ïÞÕÑû‡ZL¼,eÊl`ÓcºÅÅãA4¡QS{ú©€rxÝ)k´°w²fµ|f Ö%}ÊB0¥¬u¬õ¬;ÖÖŠI}€zÐc4©Ö²¨ºÜ ˜‡Íäy+kÆ^Gé2¼ƒT9> üë[¼õú‡26mÔô”ËFùI,ò £]W^œÐŵ& Vž9D&ßžVÎçúꚊÆ&¾3µ5(—§ë¨¬ØnµXÐ*¥Z¥Ÿo뤌EÁL–bn‰cÇ‹5iOúÍ8rlÖÆW ýEbN¨Ømg)QË£^ì+š³Ç¡/Z¶H£¯CÔ_:MþvÞ£>§ˆe½9æŽÀÚx Ð_€kÏç®ú¥Û‰Ù¼Zv úñdÃ¥e‘½ró'ô¤ ¼/¦ñ°bÒ<1 Ž£ö~Yú詊zBBþ±ªÑî0ZZ·öÃpßeËIù4¼H2±,&1Å¡ç_^ºê0ôm4לּ͢‰ªVU3 ’o`PBbI6j‡Ã6øò7yd(MÂPƒ´A„?E>4ÕnÎEÓ¼‘¤¨[Ñ‘3Q0JÚð:”ÑE¤ ͨ„¬jØ)ŽVZT±G¹RËl*ˆWIsÐÍ!wEr^Ä;ܦV.qH¦+P¥l†±FÇ WŸébúaý8í=_ÒÛ/RÃY2“,–RLn±2$‘ìÜ£sjyäŽ:FÌâ²±ÚØÙæúªîÅœÒÏxL¤  kT V‚;uº£÷^©Ð’’§,”l$ }ê²ì}CG<àjÙF¾u…#ÓsÂZ·yªã2lKk°Ì3cP ‘¼s6 5ƒ Ò’Í,ã5Q_µAóýôC¡h*NéÂÂ)$¥Zú3,S^P5MYCB÷£ŒÒ€Y´¿þ)Uä¶gŠ X ZãÛ2a‚\s1|Ör˃NÒO7­4ÆY%$퇸 Uü7×Dé鉉&›¤áljˆìŽÉ)înRjv>NÆc¸Ý–2 Ûˆúd(†$¡”jÅ*¼‚ŒŠ}Öh!2+!bYqYiX¿þ?òÅþc{íãÎì/zÖjO€Bþ«Ñc¶Ø YPæBX(«ˆ²"Í Ø6«[œÏÖz¿Õ¬„ «8»Ì7S2yaaÈØRô¬0Ãlæl²ì™sVƒY3«î¢ì”ÆV¿ZZodăT}Q[^‚h&Ì-Ø0!¦ÖXYî[ç5yr¡’$sa½oiƒGóuàÏ…Øìm'RÓõ|¡]IÚ²€IŽEz.qµQ]29>±M3Z™™öÕ8¡€Üš¢4L£Í¿\*4®fû>Ú,¹$+, Ïh†,*ïy Û7?H K¢v­Ž©Ðbaf ¥5ï_Ú:Q³wÉeh&~T"W Nýçæª+ùÌë²\¡¡‡’Eâ1ES+ú¡ 4Â`H"!סגeÔ©ª1±£LF¨S,¹©Ú¨Î[€d2wi3ë_3¤‘aÕ‹‹‚ÐVò»"¸Ô¥ûâ“ã+BakR­lEl›kÅp~:tGÚÒæv†F…ÝYðëÑj8íl/….ÚFŽÅŒ³™Ð*ƒ”óf÷m_t~º«ø[äx뎖e6¬ÚLFA &Õ¿Ø`‘@Õ "X ®\ê6 á^äOæ…R,ÃmꨑŽ- Vé²Á ‚}“ñš¹î+´) ŠH¨@ ³8õý¹Ê‹O’ÌükÇ£¢”Lö2|B:u›=µZßà;«¹U¾øUµX³WCGV‚›’hTžµ)&¥Þ(†ÏÛ+¦ü´X«˜²),Ó(­;ËYÇ€m’9\o)ê oqߟuÂïƒó×7ë_Ã'ÓŒÉrò0`Ôt´ô x¢ÆÏáDdŒ´ù€oNè[<õ(|üz¢óÖu_¯‘<_„’ÓÖöµ·uA¦ÓˆÎÔÌÃ#M› £Çfî¢íh%ýBIô뜳=O‡°Ë;jâÑ|䪞‘- XüŽØs¨Ã@±kk ŸØÊµXW jéœÀkž‡ôŠ·©:ZV=)ãépÒ -EÊoŸéÏ–Ioö=abT_EÁ|Çn5›’sûü£tÂÐg˜F–öÓž—]ÝU—Hö¹Ð¤d b±>fé¤UAú®ÓP€FQ„awLkì¯ÿQû‡¿âíÝB}>L!>£d°á,,9CrIHÎÖI&•d'xtÛ´ÜwGð·ô¿IÁïY—T#CÓ´)t¼“©å6Jäjv3'˜œ\Ç)ªÄCµäE6ó~›22•o jí5“¯RfÅIó ’LíæNÃŔ⢱ !r¦‰%+eeK(tìï»-PMUƒ)pÖ2²ºk¬¨ 1©rõÍ }ç*í´Ñí|V±Ž«aªD“é‰2 ”k†÷Y`ŒIX°½¼Ð1UmøÎ°ïS)7b%~pÖ«±,Ñm+ÜE¬V¬ýÿôƒ ÁV>ŠMÕX´Ò¿ÌaÐOö4kwn­©fÊñfe<© Œ#Ï·’û~:èo¡=Ù]­¤É©vΣÿ‹®/Ýí <¯ö¥„&\‰Yäpë#<«£;°Û´.ÕuõÞo3raOÎÙÛh1S\u‰T±ìy…85ÿýdðe){„šD"¬É—º—…¯¤Á zÒÃ*ÑŠ­AÁàƒ nEÀ“–+5*V§øåH,Ø­GZŒd×û)õ}Týcd^ô£ba²“F¤QómöV«¬«r)õšÇŸÊ -z5h2Y k`þ«ÚF´² 1Eæ^Ÿæ°€HÉ’V!æ›Å §÷7þã÷뢦"^Ñ\ŽGšøù±ù>zGˆˆ0€R:‘PŽ÷)¢KÏü]½ÆQÕ–Ê ¥ˆ3Ú–%$tYqüš¸Ÿ´¹ÿ3DÏ*â-Í÷4x”íúCc]³Zqž«ÔÐHZ‚‹p½LI—ÛÂãtwRéÍQ‚&–Þ v-o¬¿@h“LË^ŸRö^òZQ-PÕ‘ÐQ£„U–[5þ«ÈÅd¡) ?ŒEµÎ)¤Ú”¸´ G8›j¤.rÔ"À-Å.ÐÖR-|ÝóñãûP7uÉëiYXÉêúÒE(ŒDY\0CÊ2Ùž>n¿¨Š™oôEìVÍØÐ|ëW5*©¤R—°”—è»j'¨K¨sOõ! Im&Ó'Âä¨-WÅ´rùs27˜u0ÝdQRÏÖJ칦± 2z4ºåeqÚ¶æ„e9ޝdéÓK-†Ä»Å7;Ý!}EÌó(‹R,‰HUˆK´µ…U€Ä$í‘{íÑ¢ "Å0ë(]©}¢ ™Ç!”ò¿­½Y0¥ÓÐLÕ9ÒÊSj4uÿ¡’'š¬6- é­ ÎC¶]ñ,~¶ì&¾ÞCŒ–“qXÔÿ¤4(½~ýx=õÍ2Ô-b·Ê“""¼¹YÕX—ÜÄ€yòôí2 n zgníó„Éк,Ö‰UÙ]'ô,Ä›AA%Õ#[,éZåÇr×qºè®ÑÝU“ª–’› XFõ¬QÀ zTì3{JùΉ{¢bhv¡Ö›qRçBÓNyLy^•z«Îæ€A×I å.+&“Ùú]5Û„À€ºå†¹u‹05vÖ"ÂZ.p¬¼F«a*„ÊÆêÀºp‘®pì×ß×ûPñÒ_`Z%nè{jÿ½ùÿ¯?ïÓO @4`1¦H˜ùõ3K¥EUêÒõ? ¤Qi΀`¨ÔÛFš3Z6št¾…—Xf!6+ªºÏ/V ²G2´ŒUo¬³à–_;Í«Y‡Õ26í] ,ß‘FÆs@‰hu½FÒÒ&ºú+þŸ²”HJè—ñ¯#µÂvï›}0°¹%¸ÃŒR’Ϫ]˜W=šRÙp>Š#P6—jâ =¥®þ^ºìˆ1Oz0ú¯ä>…êâšÁ ÚŸî, Û¬ù±*d¬ü*j‰¢Ì šñT87Ç_˜GçãúÕþÞ/­¼ 3´U¸ ù,è)b u½«ýÊ' ÉAQ`ÝCAáQ׿ÌÊá{œg‘1v$  Çȉ±aR¡´M¥‰f(i‘žüèÖQ³Iˆ DœÝ–/ÐîrEc¾ÞÎv¹ðÌt-Ѳ‡èl´»µËÞ¦³ÌgŽm÷!Uâ.Öqì…Þ,2 ¨¤PÖ›·H%¬(ü× h±Mc¬;\,ÉËkèvøÜ 2Å#ûò-ºæXT{TR¤ÅÐÏÅŸéãñ׬ßÂ^liôÏNŽIÐÆs³ÖÆQrGAŠ’ÂˆúñãÉ?êE9ì¯?Æ&å`-ñ¤PSÝ`ž¬‚ô’P’ãŽ.ÊÄ5I.†£ˆb.bÖKh› œqQZƒaßµ)3íT¡!·47s3*ž ©4ÜjíͬFмÉlëØ~0¢ïT³X.»°uí6n6ë>±Ö Ú òÞš´_#ž@ñ_&F¯6°pÄoö‘ÅË0ˆ\ÙôõWf5÷6í´Éà*b2FìÍ`ƒj)r6(T–‘üë" ¢í¡v¿pDEË_«ÜìgÑ`9ì×àŸËf KŽoó¯á&ĽâO±)s^–­ìA[éµmO®´ˆøW_0Ɇ-9ч¼Ë‹/[Ú ÓøÂô°3O·q‚üMà%ٯƷdüÐAÐ1QÓ.(¢ÕY;{1Š·õ.²CÿSU2ÄÉŒ3•däb 0= ‹"rvư6ßhØü“FÀ7C¦ŽšÙxÚ|)º9fV7àR’’EùÏ=Al^v±™oIÁ­B2fæßÞ£‹²º5‡h³4”™¡gD·Ñφ Ôº²/ñ×®- ‡šßÎì-glBĸ¢á«$N¥´þšˆµTtÏeËÕaœ-«V@pèåX× Y}®5Ù_/<Æf¿›RÆ.‡µsZÒ6, <&y »R+ J•} éݱ~rÜM‚ï_4+ O`бv„Åþ–ûApSdê`©k¤óV!œ ˜räzÙ2™–®3¸ ¸ “ý|ñUUדzSaix¸¸ %x³Qau q´¬@’÷†à-Pçiä:ö,æD¡I¦(c”ú© k±—¤¡o\øûÈÅi¢{ºÉmš›L$“éÑ¢ËÆú^pbfMtÌ\rHëP=Û'ÑF‰+èTïžw¤g¥V¤(`š^·U°ËsЏî5hä¢BÅ._•*Q ¢½k§X-ZúË´¤[6´Q¶NºRœ/v„v¬Ê/š»ÖÊf´¿ÅX¡ þ2½jX”¾Ì°µbGBPÇ!ªÛ!„mó®L™2â@œ»í hßÍßõ£@ÑûwHÄÁÕ_Ӕ͋¶2X¦’ŒIé±+ºF!V¨ éä67wyÍ'ÙQŠf×aw¡ÃÖoVaÑVòÜ1vØ»§!=•{ë³u™®±Z9„"q¶pü’“Qà#úÅò_î2”ÞPGMƒVM €RÊS¡¢%lZ†™ô¥x,=)¼“ã„ñ÷ ¸– FâVÎ#U&~›¢a×0§@pWYJ% Þê´öAS6PÌÏù¼i çxÿÊ¢isþ^q`ÂÔ‚N‡5·=„Ë™¡1)8¿Š¯æ­¨#É”SñP5Û O{'6-G $F8ÙR#ä²°šòMx5_ÙsßñÚ™ý­®h£=ŒÙ:¦¥jóJ2=MB6q¦¬‘@R!MÂDDŠ„‡œ- m±Dü¤­KY,­KYYüã7ÑaQ/”ð.TÛf$Á]{ßáLÄkezœä:Ž|Íx_ïdÏH½Aa¬Áu-AMþ…• « ½¾² ¬_ +î=ûÿ-2±ýV¸.KRÿ÷LV‹”Æ<j)FHÕ¡h“NòY­c6[Câ@Éœ(’Bÿ`j¸S¨-{ÁpÆ\ºBЪМa“ÕâŠPwF\PkSFè ´J–~¦Ü4ö |2þ’v¾£®vBM§2Ç‘¨Ï6æ4O1°òÞ %T]nøëb£c"ÈTÙ׆)ì²0±ªeN½5 2EÓT½žSò™³CD5O æÄuЈo¥cftp±Y¸îtÚt72ï´28€.),â½ä?ZÕb‰,xXŸeU+,Ýò!ƒY̵ãëZÑ ùÔ«Wáó#|îS"Ç ²cF‡¸UX€ì€ $7¾ñ³ƒË—Õ^ÌR “:Fq3C0fQ‹°b6©ÃEl(0ªŒ©f*©°+¢g*$G e¹÷¹µp@¿ŸþzudéÓêØão/KŸ"XÚË,pª¬è¬ Û¼–)ä) :ÔâVù½ D4o{IœµS’¬â"ÄŃ󴑿û©Zü±ú­Ú5¨ìF«(õq9Ô±3YÉÕýnQFG£GŒ©eå¡ÊJ¿eX0ªÇ-,eËQ3õ®z^mG  ”[æE+hQ´E3o >4Gÿjò[Us… @þL(,‘¦{„ 2C†pC²léªÊèÒÖ#¥IJ0çR>u,ÌŒàÎÈ[«”jh°¸èuŒs4°äFÄ2Y(¤ƒ%Š÷ך»¸zè¤y1iÚ&n;ãÇ1Ÿ'Ó|–ƨ1äSºè{™ƒlpG=.œ #ý[ £¡blÆ•êøuÖÕ–áô.–{*.|䃜Lˆœ]:ii浬òr¹\ûw[F§ëHåZç¨2]³§$%b“c®Õ¥rýuµA¦[±úìG\ÃСä Ô2z!dðÓuÏu[TpV?Ô):¢(-hm¥X¨6%V¸Ì:Uåã« Úi€e¸—8AŸSÒë,BAb*+„!Glë-v—ÑVªÌRÑÍF¨Ä½õUÆëºÙ$ («»ñWÏ|Yä‘gÉé˜eò"I‹è¼~¢»J€@!yª æÏšçòÝasK÷è·½Wú‚ÅϤµmw*6þ²°b(¡r ¤°·ÂekzÚÓtÊaS ©/é$º¿÷:=ŽaYÉ©iK€ÆÐ0Ø?M 3FÚ1ªšs˜–»"™brîP! ýô¹.Êäû¬I X]šA›r”dð ^-õŽ—‘,é, ºõœ‡5*4É¢êgc‹×ÙqÀ!™<²B´dBj÷(~ÑÍtaà™35žS9ô‚+mfRhS($_ñÏŽ «ùêŸMÄÂô5‹Ä%åšcº6az†=ä‡ZlØA瞺UôkºExlWÉîÀø–-uÒ‘=Ï+3Ïé4‘R°ÙÏ¥Ê T+ʬÒ­¢¶s=UŒËTy빞ƒÈþYÔBÌ3¸}3U }™yýC’[ÚÑbAE•»wfÕ UL/JùéÐm)aª¥ÊúLìRÇôÿ‘Ó´\?âßì¿u¬½ôĈxãég…ŠÖ“J³+±¥D2'ºsö­3L}ö„uÝÖË 3.lîi»#åp 1« sUq]²ˆˆ¨K<Å×Åuovî^bú_¥M‡ß=Û­<¢ãåO‰§–slb«Ñk­Äñͧ¡ÁÜ:V~6PhÆv‘²Ío*q´¡›qø+Èq{ŒË0Â]¿¦X¥¬­U"Ç*JØ£Z·%شˬ«½ïóëƒYk 㤮Ë; /÷ŒÓî7Ö6ÝÙ‰(«DÇhUhÌTÊ:ÀmöƒéPpoÒÚ¦³;Úß8QŸ—è¿Ø9½¾D¯ér«R*SIj[ÏÀV]ußHËbd¨ˆ$Õ*°Cý¤Á5™¯ÀUÁ[^÷úèÕÅC‡þ2(„a¢Øe…X‹•ש挫f­Ûì·Åš?~G7Õ‡fè@À̱©˜"¨(è8ºçöÒÜz£°Ej9I¬Œ /û}Ž\$›šhÙ ÷/Ù ãù… XµÈz3µT«nÖå©«òÖ5^øDÑ`XæùŒ7¢ç,}¥jß3DTP7\mÕ]U» Iþû¬ Bu(îI«ÆùHhÈŠ2«#©ŠÉØçkè}´°í›fÒDÑ—~¹-Ïù¸Õ-éœgme”qÏDîØm†4ÛRÌ]™GЫ{>ø+*ŽKö‘Ú=cRÔ¨¯[“î5/‹’ f¡ÁYµnç¼à¨AÎ2RÑw[œ3ÙS,• ý„ÄV`iÕm7(°Ñ‘ŸAÉY]¨*¥BTA¥q9]ýô³»“ ÿÁófô¡Êíeqí ÁU’ïðx>G<Ÿyuü]ýÊÎÏÈïžÚÂõ31ÙÆ¹žXO§•Ñ¹Ë 3ª‚T óá'#I3h>Vº sî1Æë÷†3]¦Q+Í‚¢¢ãÙ‹ª.ªKßJºK7¨sG¬WMÁ2}]9˜V)÷¾Òøj™$¸4‚¨/÷ ¦ëYVÌûÈL_܇H”AG¬ 6YçÌf©²ÃOW]Ìá\2êfìf”¬TB£ºšzfÉX’ÿæ˜q+¯öÜÅþêç%Ôý'  i:,ùÄüm3s)–E¿°q*¬ F¤ÑyQ~¾€]»w+CÊß.þ=Á«ôÑ䨎¼ßšUŽøäF;GœˆèBºì6ÝVâqkødÛRãxм¹¾ÅLÈ©£4ºkµ}(zúL~ñ5GN&³Z+R 'KaãÐÏ<ÛÇÌ\ i¦v¨ÉÈžu)mmEª+×Fp‰ ÑÞªöMŠŒ I\ ª{È(ʨcÉ<è¹Wÿ´ËÊc?2úòžÓÚ °f@Ê´~lÊòJ¬ñÍyKP¾P"ã!šÉSS3S=Mýk%Æ[ >YRò ²˜“itŒ›ñe b™ h ‹jƱ„›„£"ýiþÕ\ÿ)c $ßdí4Šþ¿ŸÅÁHÏéífßíüÀñgäWJÙ© E>¦aÏÆª÷- Žé«– ¡hU› õ]+¢:©IT¢ ¥˜µ×¨µ™º¬² Õjhܤº¢Ÿ¦ºn}†í'+7 7Øml늨ÅBÍ[´R«³@,5omþ’-€ÍJ»N²•&ê½jFŠÒ¤¸òF“B­ ;ˆ; Øð§Ž<ò<8®9éõŸ«Ï¢M 3u2y_äÀZ¡¦ê~Bª©r©r• X@ÑMiΔûêY“”´Qf¬)Ð éA%%Uq€“pk‘Ÿ…*ËuÃX —¶œ jÐMµãµMÌy£@PÙøãäñ\pÕì-b ^"5û§HâŠ7ÌŽ@@píä³Éü]6Oô³Lÿšæ%D&¯UÃV5 ª‡+PreØ™IµÌžpïr°¸Ù¬Ë# « …`Ô ÐÖ’««¬hL…—$ÝzZÕµ =*Òm‚–fö˜›IQ¬·q8“ ˆò¥ª÷¤‘–(íJµ }7‹‹~sÜ*gþ—´*)–4ô³Llû…Jõ\²èéìZÔC²†F’LéqP²—P2¨ê:ÌÐ^áÄUâÎf„*J­”ºíy$ØŸÇÏžŽótµÂH¦’ " ÜL¥¨… 0_“FïÀüŽ h4«zДq…bˆBi[7û±5­òÖиƒ@Gm” Ä TÍ^¸B®a´RVº@~äÈ#æ~]emŸ¬ËlE–¨\Alâ‘d˨æÙäJŽšÆ]£èÆÓ9>tçò]…gíU0¶Ã­aØ3ªÐ¿QÀŸæq\à±qÒˆ„E<”³”æÖÊŠ4D¸eâI§Ù 6nPÐ`˜ä&· äĊԫõV­Hà¬OœHY—ÔxèÑLÙcƹ4ºêîì#¯¥Î2pÕÈ”E —Ó£´ÈÔ¥-xw|ãã©m€è¦P®oŸv‘ ×e¥ªvWTÎ]gâèˆm° àNÓGUïªí¾J.‘¾ZÀ:ÖKHd~éÕs*¨‘ •T啨™ƒÝrhçHÜZL­ Œ•Xš ƒ0ìÛˆ½¼U_<…ÜrS…cC9¥ýÖWð0wX'áZ×w•„>{Ù˜hˆ‘Å!Sn®¿:úZ:S!àêF”°áÍבA¡×þ6°Ú£GÚ˜kC.6X`lLé0uŽv`7£°TpKPä²Iæë‚>,W=vF“ÙX]íØ²ýþ£‡‰4â ´òˆ$l"ƒ$ˆ“ÄÒXm BH­B‚Âìs¾k -ó5Ö[[¤Hºº)»ž²ú )|g51, D‚feRÌ¡cö]›œ+]… §XÆžW¿WhÒÕçë)Âõ /FÙÉqcAGI¬…”ÒhÚ+/G,|É=Fޱ_òVõþ@`Ünž-Ÿl8çËÑ02ËNµ/¤\ÒœÖ5†kC…\fIç,ŸÜ*hÁÛ­á_ŽçuiÆ„¡÷áëA~¶ W-+žÑhÿSð±Ck#vGó ˆ{ ‰VU“¨ÿ锬zÈbõó]I7… œ¸Ñ¥ø¯Ž¹køÄÍÆÌ~ÂÂÅÍûÆÑ;v "yStBlŒˆ·ÊdU‘Q¤ÜK8{›Žœ*mDvÕiÒTâ sªµ¦µÕ–&ò,V-)EªP‘ýC»ctϱI0_›-0 †Ñmyk¤¿¼™7ìªð©Êóg 53ÈY^ÝL8+’(M㊅ê‰EÍhÓŸÌ©a¦T¢•#"4Wª÷Dô#5Ó¨¯é-„Ô¦*OÝF±‘Žãš1Ke1VqË¥&ŸŠêÖ[3/™"ˆÏÝRh²!¸ªåZì°ZÕ ü§ü¡ï™a‡_Fy4Ñld$î H£DŸÕP®/¦—ðLJ©j]‡ªÇ‰ 4pI$ˆþžÒ%l‡ §ùKa¶6&«ñq×~önî’ÖÃoAA/jÍ‹6“ޤâù_™fV £QjžNg Ê«úSbÖƒ.¸6êÅÚ½À~xÅn–E<ÃІD&½åuWn塊ãK°â•üq¥Nº\úYÚ«—3$lxL¹ßd':•0ˆ¤±Ôòÿqå†IôË Q‡¤ g—2ÁMƒ3Š­’K†ôTÊ´ÄP4iù!˜‹K‡--t·‘/@„m¨Äˆ´-é½’$Æ«îæ‡%–Ç?î9Y®®ˆÔ4ì½Qç-ëä™a\—ŒªÆÄÐV—j½Ìh’K0RzXËXŠî}f}¡XÊ˜ÊØ–%¡`º±7X¤‘RÖVšXy'Â*Q]4¦™ì¥Ûç’Í”?¹0ê´Þ|g‘ŠØÍ&šK*,¶HÍ ÕmÐ(W„WƒHê® 3b½iÞÍH€ía3¯PÚùÈ—­ÐКhTc'êN°ÂóJ,¨_ŸÓž©ääŠÎ(òû*öcR—Du(nÁÓ  ÇÝ2Àì¼…è]“®³K;XЙļ=J9cÕ$Z€7I¥³Â“ñôé¡ôÏ:,¼<œe•Ró±ä˜ræMÑzRÀý5;;‰e9ŸªG‹§g¤2@†,‚·ý]`ç™T³¦ÅtøÜ'aÆä“œR‚ļޤ¬Ë%¥ î®ÍÁ{šÂ_P ÿ¨ÔÔ½"…¿ÉI°â¼.õ˜#Už¡ˆ3! ¹ì°Ûgp#Ïþ¿<º«eXCŒÊÚz‘˜F*!X#2Ï’Ã3,–ïäþä9µXýšW()†Î}býhêé û9’åÚRˆÆgAp| 1Æ€ÿBé8KË)}w$\¬ÖwZ5TékÜv¨ Í1ºê˜lW=å’,JöaÜ'„œ06¾œò-óÏäý?ö FÙ§È*hnuZ%!0È~µáØq×ò‘Úá²öW8 ú60ŒmÙÜÍs裟 ¸[A×YÅÆp< ®,X¸„ý•Èêµô”P³bl¤j¡X ¢ô¹¹Ø™ññÞXšTŽPgPÆ÷RûO“UäñÑæ“¤iÚ–›¹¸p䈲›M‘T¨ŒÂDQØ­Vç¹jÜp·KÕº’ÑòlnÔ_[g%%¡1í©©ZžÍ¶©nKÿØÅ¤Á8è°æku€qí\ X•ˆ¢yÊrš÷hÍ­ÿ*É„ 5ùíUn[Øa¾44Òö ‹ÞLjb*åüí­Lç¢A>‰¢ ý·‹Lcj Qýˆ¯ŸýnU@˜ëE‹ø Ä¥[žË³q•9jW+nÍ »ì]Ø>³#X$±î3&2©ô P.´êÜ’¸sÚ±.K5eiøþk ej€1÷Ò¡—MÒ’Ø tpF(,SR†f>›U‚¨“7%×%•G7²Õ vë'‚ß.é€ÊQÓâ~inçÉ\w:J^‡ê:,ôÿ(‹QéÓû&þƒ3 U[HŠœ—ífdŒ†$ÈGçÿ>B’<Õ«¡‰Z@<äüqCûu ]ÏÇÒð3µ¢ßm‡‘™6ã4Fy@îE"èÑ?ž‡z1Ú:«”aJqU5æ…#µT6!ÃS¢$T@'1JÒÐ;,qãçÜhÂ5—üå$S!‘of@ZVHüµÈà©'¨ *É[hT¤2/¦ä}Iqy'—;^c1 fc lá&1G'úÌÒ.ÇÌK¯m:Qý ¥1ß3Gn!Ù#Õqýö©®(‹¤˜¢’IJ†~²À=ÄÜ,7†P2¹HŒEh¡â¶55£I±8Ro“¶Çö< ñ|Qt-V=EÓu˜chcÕpquñÜ©h+ Ä@‚lG¢†e%lßL^©nƒº… €Uʽ µ” (zA«P_ܨՖ OŠñRX)ÒÕ£¶nÀõœ‚2BÒ3€ Ä´,Aè7gª7IH›æ-OZ»÷”g½€`Ïíµ.ŒCÁ*(¦e€1‘˜b*Q}%‰­Õ;$H­Ì}&^Í]¤Ùq‹«ZVêaýàüÌ´ÖÏ Ds©jÜuˆ¬ Áex Ë4(Tu­f`Ëžò2-cZÖ€¨¼Z.q "¨$©Œ‚¬ ARHÑ® qÐÖ»¤ãge麨)ÔðU#_¨ücä]P›GŽËtb{ ‚Ë)y#t¬Áe¢±fò¥D\ŒÆ*B ŸŠ ÝÈÌš‚Rº(ýª çn†ªWpÙ”=,Ò YõDQQúef‚|ÆÐ-#ŽUTó-RáÏ ÊËÛî$ Ë˶a¦ws[5?…œuvµ™RP•Z‰ ÁX ”­nV»NO²Å —ù+V„8Æs§2ÌÜ-¬è™)ÌRC5µJCT¡Ç`·ûOêØF;Y-“†8)ä@3 ‚¦âlïÜ$p‡×/á7¹#—¸{|.áfwÔ4â Uö¹Ytòãƒ)ˆRвͰpÞÊΞrþ¨ÌºçÆÿܰ•X…X0Î{æ}ÃÏÐýŽ•›f…_A$4œzÆŠºWö¿Ûóèé#ñ6+Z…q6õZÄÍô {^ã­z·´Ä– rÅœE‹Ùù‘·ÊÚ™ÏÍ«=»Ë¼DF~ÅKñ»»0T¤®Æ«±]fr•Ì[=e×((.K??‘ÊYQ£+ª™ Œö[’/'.¾ƒ!ló{ªÛ~{[ W(ÓË=9OW3±«ÎRRPŒ¥µÌnsÛ´…Ùb~¯Õ…¿£lú  b³‘ £-:¨Nnî­72ì˜r $‰¾¬¢Èe, …Úv·À±À¿<‚=þ»ÃMÏì-%´M5òåÇÒš$Â"ÖDr¬n$‘VOH©·Ý° ¥OMç««©óRމ›U7ÉU%…ìÃ5½f¿Œn‘ÀÀ¾ ,UV¿°Îã«/"¨IÈ(\˘kBÞ[³ EI_°B¹9÷"lËb±Àº‡9Ê«@Émžë¬œý4ÖyK¸˳½Z=왃–¿píKº¹ÚŠØ«OP”˜¶„2Ü8ôºùa Ð]¥"YĺÈÌ[U›8™)E³ÅE­Í“²‚ÔÕCµa¹ª—$cm€7yv4é½»¬üóCñwðÎÔ{z=F8³Î9å§«>Üq@¥2ÌÆ#_Û6åK±pT@‰¢'0«=C¶SZ°±h»?Vn°fB¸ášÏ̲h.[R£V$Y¶ÐBÂ6¢ú¥Tâ²S•fÃð£ ]ž*ý-Õ%¨ÃÍeÀ‚«h4Y¥=(QuÀ*ÁÑQpØŠjrˆ£­óÖb„4n¶{L[;X§õ"gÅTw¬Mx í5.‡‘¹”œ^Kk®}AŒ<Þ|_¢ý˜Ëᯔ‘tsyPf*eÒLŸ!¡|‹ uØqÛ¦î¼Ñ‹£œ•H^ORQ½¤* <1Fau¹•ƒ0iýTH»¿¥ZdÙ]ÿ“£ú’C„Úly‘$žVa”bÈ’-ê²@`_·&U+í6›nšùüÎÐ3X2ê´&/ÙºèÂz{1‘:L¶Ì.ÛMFV$ºuêùµ™2ýè5,ë Mxl²Y VÄfÀz~Å—­Gš•N¥ »üÍçY&©_œ}1¼X«¤²ŽÇƒßǃõº ¸…Ǥðs¤eônêÓR¨é€ëÒ­È*umÆUŒÇ5»pËÕ¾u{ù ¬n•ŒÄ]¦@Uk)8ÙÑ?ØY!îÉ+H±LW~Øq¢3ìp¸vQÿ˜“HµÐ5¶ÔšVÆhbȲrzЍ•B¬åKÈ Ý*lâËX[ê>áÑ%ÄEw‚Yñ`x1±„“Ç+K»L³ªG_n«$E9Zi$fÞ¥T4ËBÀÂs’•\Æ¡Qb¿™kY’¯\gHÐ6>·¥:ƒ Üúf´‡þ‚ÌêšÿT9x%:ödÿ1ÑT¿2/ò­GúDT.Qýê•+¶‡”QöTLÞã˜(Ÿ×X¨ÔB¸œ© –U®Òù÷;3MÀ×Xl5væ£ržÛçá)@õ!`‰*KVJ0\ŸNWó'áSœ¿,Æ%Ý=Øq¦fì‰æ ?ÎÖ õñ{'·}"KÄ 3/Û¶Ím“ã“_ŸŽ¿–&îY]Jê9a…s“Ï·íä?£qMW2'HR³£*êúgÓÌL¿·~߇6hÉY$\r¢7Le–Jã͵“æ€ã¢Ìïïœ ux»¯TÀ…íB¦~YRV¢8>|€í@p Ä¿Q´åë÷iÖr²«·æ³GOD5:뙦ÇGkb\eA‰–(3.{VšºdAÆÌˆzz£l‹ g—ìor³új¼¾ßÖ ;©`ËD®™­[X7µÈǵ#Väyãµ^Ãu5Lj пú£ÖnÙïþ¼åJ®$jÚËF„VUèÍóÛ"F`a×¢‚žô]æ.âùk¶ÎŽ–Ëñ·7Ðí½Æu½eø.¯«¢¨kÓúßóåÌ®ó\ö‚e¢¦2Í1ªÙK–A¤þ"ýßI£:>Ÿ—޲›hoV½läƒæÉÛ^I«­Ôu|íRÄõy5)U_Ó—:oQ£É´–äI!Íÿ¨ðz‰ÜÆÛ(5Fs‰U{Ô¢DÝÕrßS¨Ü1+ûL+µ[Ö=$èX¶-TüÀy~pìÿfJ«]sÓ,ÙÉfŠÙwrÉ¿goX×QÇòËúT­Î%çã ®s5SѶ« ?ðç¨.5M€ Á}ÜÞU"QŽ‹ÀÕî·›.‡FUäÛêxⱀы¢Ò&>2ìí²Ö.Cˆ·ÃGwŸësw­—‹Ÿâ®!ëæ_ óz>*K=×keôµ¢êdClÐïÓ9¤™ ­ º Ýo=ŒSµ²`¬vä:–Rî¬âóémö­cn!•­òY wÏ|vøh{c»õ#ý#ö¸3…¤BÒ)t÷.ÐÌ n¹<žšîy{¤Ðh.Û?w¯-•QІ@¤×Î0~ăE´VŒPUk$›¥¡ùmÊY²n·[ðߤ¦uѪæC ‘…Î*ÜÌT¥³m„Ã3Ÿ³áûŸýá¼%¥œ[sÕs`8ÔѵÀü ËGÏ*°¬ ORŸYX4*Ýÿ®^Ùíe¨šä°×Fë‹Ï­[i½š2™ÔbÂI“¬+Fj„VX42…R*ì©´&AKÜF§Ù=Ý3 X;Xã¾4+,ÓŒ‰†—­)”:ø(|ù c¬ýMú‘ŽN_wåäI“’Dg‡jÜû6¶ÒõÏ'ŸÉó³^Bts2« òz}Ö3„Œ°xú–X.ËfRGX^éœà^çâ ¸_Šyci6äeO,"µ‹LâX%ת5F‘+I|å§ôÀX“2©›?2âQ¢3þ —´Cr#Õµ±«RT·1**ÔìµbE X›ßõ,˜ÔmMBAIìô¶uÎ!¨ŠW¹H'bÕúË=÷ŠbÔF÷VVŠP.Zݸ{öЮZ ulÃÉúد³ÔÓ‘”Ø3± kó´gŸ‘_ƒÕF›õ¯ê.”ò7¹r±Y²:GŽ}FZ SÂÈ6ðyVùðhƒŸ—7õ—wEeqlKYA.\ýf “%¨5¤Zþ{‚Ã"’³ŸLf*ñX€éTì%WÊzJXŽ1œžÊË’ÍW5¢4 þdËt¯!²Î8i@·ç#!›KU™¬²/ˆnÈÎX¹ºP½èÐD+p/gVh6#)Ûô§g áq4h÷Y:-+$ÏÚÅ2ŸìœêQr*ÿõȨZÞ¥½Øjµ~õ”ÌþÁÑcÁ.+„È” Ÿ,g+èÏÒ½+//Q‚\\`ŒÒ &¦/ @ªe·ÝE|›è‰>¿}]Ô³1\wNNFJ8ôýHp•.…3*c"±ŸxaC‘WÔ£êü©³ãÍý>F´äzŸ4ÊZ˜›®¹™Bëâ`ôÑ 6Z.×ξ³õ׸fdΆUÇšÜÔzáóŽŽ„’«ã"ÅœÓÇ\m¾ÅÀ³ž-K‹"jEB0¼¸–kbùcýÅH¶¤ž»É³™Ø“Í~•tÙÖÈÎ+<Î?Ÿ8•;Nz™JG8‚;<Ñ—eÞ]áN]ma–ŸKÅÓ\× [1ŒÓÆg¤-pyšš¹~8ôϬ!sÚ—mÍ/3­á°êˆŸ (ˆ2x?”Ä„ ¥k¨ÕØÖ¢Ó7µþŠÉÇCÖäxãÇ;LqàƒùrH­p Àì%A:Óÿˆ®øòŽê#þl`¡Ó°œGîQµ}N?¨ÑÄߨ ”³‚¡Ñ$VaDަߛ<¤·™<‰±ä±àÓŽ„ª»lM.xÉ5q”\ÙÒ§ã¯Ö„Bl×$f)âÕàˆ¨§õýÅ^ßm‘ÕVSÔU (º$$%Vؘ´¾ÍëeQ6¢w›é©ì6}X’â´ •T?H‹Aßí 9 Ð$\!ªé}KÑäa‹Š ±¬¸p޶£T«3¦:…kÌÕwZ›Ù`}Ó72á2Š\K}Õ9 vØ®±<’×a"Á‘=BÒ(;ïP)³ú^ßÍó^ŽŠôŒ ]KÓ´ÌE?k¦aÁ§BnÇ¥‰Ä‹¿üàF«LjÁª I$L°d¾É­Ã{ûRfN:ØÒÌIÅ(’Àú,µôŠÔ›çIxpÉ%ÛZ)‹û+8¥þv‚_ô,^}Ù¹v#¯±âÕlû•{Wó´:1{–˰ó©°Y¥Á#ú™ˆº÷fµ)Dc€MsÛT3B:}J]ØP± b–…hÍ0œÏ¹X“fVdn±Oýr‚÷XbYêŠFg Vb…ʶ\0įixòmÈ@ÛÉ›5F€ÉÓ¨ù¢A#¢E¸Ê »ä1f AO$E|ô€4¨Àìh>ÏwZ ô±Z¯RÞ,T÷ûbžÅ¿%À”Šç5­þh£dÎwM½T‹Å¤Ûd¶•„Õf-wW1a¢Z¦ û*+mJ|e?޽0yÛÊ+æîxßÅßJž©Ô&nÆo¿£ÌÑMgV^-«Ñçcéb.<ñhˆÍö…tP£-Ms–·+éçø¯_ÅR>ÓÊÚJu½‹ØÇYŽ#3(mrþöÁ:54_®æ²ä·NYÍÖϺŽ_žæšçw)VkI{¦½›òAª0ýfÖ‘tÛX+7…H$“Ò§½¾¤ö7ià åj˜ù:ˆ'ÑÀÓò"ÊÈû¬±<Â¥¹›rº¥4k•­ÞÍ2m’§|e¨HL‘² XE¼ÿÛ–‡U&a]þk–!D±™h¬„¿ÙÁûË{I •p¬,&àóœÙut íô\Ã]rh½)ÿI”ΰ™ì“8™ÓIüŠú_Õôÿæ=އ1tü}Õ„À²ÇɃ;©ØseÝ ¥V@ži@ØÒ6¥ëQ0ÔØÆD6*7üã†LÒ%¼}gýh]ã¹\6ªGDG\rI‚³r>‘6ªŒýV‰²]Jˆ­u·Ó©1ò»cOh2%ÎE÷zbLr †‚@Gò‘m»’Muâ¯×M[+Yú‰®ê™:dL™ó¶YÙ,ÒǘdfuËLYä’tÚ$+KkJ€]îöÜã…>^Êe¥¶r–¶Ù MèªÒ#æ×¦h]ìuóÚgý£Ýñ€óO‘ؽŸ› Êè±ÕãŠ)8ÜÑœÛ )*Ö bnÅWO}«ÇU½s°÷óv„“dŸ;?UuSHò§ÐãÚ9µ=Ý…œŸ°3FÛz®ºQÜN}7ùãŒñ÷nûïu+a§ºfÕúd…Xj…¢ÇEo˜ÊRª¡É‘&ÅN»r?¬çšLA…Í¡¬¬AœÐ–߹ܣ¦^˱WÝp¤#º& =‚Óì$ˆ÷e›Pt°OF}¬«Û"~Œ}Z‰õá!è"°¬—AµÎC ÅÔ›’­N›*+u \Ë¿¥›qH“:$ý(LÎÿ³ÃUÑ?Ãæú…–!Ëxá’ItUl,dI‚–Y ¶åà¯ó5é_ö›÷N‡Ü1k‘ý7í£“‹ E—¨cÆñF=‘32Ë#{Xª–“Ók·MÔÝ\Ú~¦|Xؾƒy7j†â)!t(èJþ•ê½î²éQ¢9k¤"L"/­Š]±j,íï&xa굩Ð:ãTX †òr*ìŸ;‚÷&€ˆù/Q£Z)dêQc¬R"Uoj²8ŠÒªT³ æ·u.3ü•94ZÍa§ª­Ä“Œ)ž±i–×ãÊjÄúlqžBê:Å‹ã Ù9ž5Ór‹¯Ñ5äéœý#´Ò†`÷k(È@JF’¨5‹ ·‰€<¿û-£ÑfÇx¾¦æ¬ÇI"ÑñÕ‰´À²œµúUú¯ŸÇ‡ öÌjÙIèä}íùHwõ5¬†Å ÀzÁ‚«ý$ü×-Ö(×k`/eèõu{\Î%àwcóž–"uP–°5Xĉú\b­g)"̜˄(ÁáËÒŠ Ýi)?}×^º$bÕnÔB„Mj´I`ëVdÌÈLÚ;©‰4ßû!5õÖ 5¡Ñ`­SÀÍ ¬;X).Ó—ýä^r¾È”v·ˆÎáÚ4AŸ³d4݆ ¸m(VX³t‹V°]Jÿaf–” ݵ§ñi±ÊN˜óq–¥™ef”¤k$@¨Ä„…<€IyüøëͶ Hb6ðGÈþo‚zJ{<”e6Ö”Ò¯£:%0ìó·(ªç½æŒ”4xµ H©4­Àº¡hß=Ø÷¼ð>'D¶oÍ# ëþ|ëÄ„,6K/`Ý;]BB[H)÷ñ•…^È—bŒ# nÌÇ´~i¹è»²£“àd¬¿Zê|UæÁ¹ˆ Vi[ÐmÚíÏæŒdW‹"Þö–k» 5.&PºGCƒõ˜SµÜ1„UOau[ŠÍW·4|™[5=Hç–PÁáf$“E¬°Iæ¶’+›»êÒ C"%†Ü€isÈâä8­¼©çòGR‡Ç~ºý`xÓIV|{æ;`°+Š€/Œ¶¨«Ñ@汩µÂi¥¬TW0k+šÖ´V³!-àÓûÇÏó ¼Vy‚úöîq2×ÄìöhþGŠ|}C¥¹ýN¤I‹V|m‰¤Sâœ|Ö+äõ%<ÓüzýóéŸ2úÂówr)ÆâMuçÁ‰ZnüÃÊΪ¦FÁsYOéõ¤¹“ Ñ[¯ߣۺ*¹£µ©­k1_µ§ÛjH»¤±my$Þá2öf&§Z_íÒ.±½Ñ„”R ˆÖ\Þ¡¹+Z– RfÂö›%cí`D ácI™ Ò ¢Ñ`0zãµW(Y–#+O©ÓM.#]DÊ$ƒqÜ0ß:¤¨†PB =,Oë,SÛ¿ƒŸ¦G“™,ÒÄ &"0¨»ˆÛ¸#«AÀ"«¬å˜ãH©Ž±À¦8šâDK&!fÕE‹æ®þgf`1Ñ`Iš^̶ÕíuUBµÔö ¯·ÍgL°Ûú•ËUf[Wíchm˜ìÿÅÚÇéZã’-]*P›<5ŒJ44‚cýai!¤;/ ½*¹†óBOVöíaÖßQBáK$JìR„¹,ÈÇP‚s.¼Ýº£nñ¢íqµ[‹é¥5·Ž½’e®*5u‹6b(J(m…dˆ&å¶PŠ5w?÷'³Ò…AR¸ÕÒL:v."`caá4…Y!‚ Þ6)Ø¢R@ã–£WÏž©gË#4ŽÎCn²Xàƒø8øüt™JÒH´7zŠ­LKôû£ä/jR‹€ª^-ªØ2p‰¿¾ãY‘†É.íK´Éš%P¿lÔ¤§Æ—†t²ÈÁcŠõ\á/±„J¬¥BfÕjÃ3±fኜŒ3býŸ´C´5ZX"’„¹¬ìßR×]:¹,b F; «¿uw5DÝM¤²©*Uey#±8íU+IÀBQ±J†† ÚUJ (a«RŒê™3’ —'z÷Q ýhãâ) f‡ÇÇÀÿaÖEê9ÉÞÖËkgÜ÷0Ç …S£="¨šM¯‰ªtæm¡4e*ÜH}†Ê·ÝÏ’Z†û"¥½Cý|žÈP¢‘O»÷ªÅ*É÷‰â(³ ‘ý6Z«ØR¯õ¤s¯Q“7d­ƒn¢ÇüÌ7­Q\—¦r੣DZ(U-7]N)?#HšWD j‚É…¢rEŠ2ÕÙµ5`‹–@µYf²y¡Nq¼JÅkeSjL9©àaê±M‡›râ̈’¨È0»UH¾Ñ¹l5q]JÄñÛÕŠJ*mw)凈ü ùóÏ'¤öÃÖóï*6.Â+¿0gæ=OÌBRLÊÁH¶¿ÿÃY¢ ŸŒUbŸþâËžåÏu^FÔÙäxE±¸&Þs3 š!ñÚe a€o‡{t­&*Ÿe Äè}€ê 6ÕtV`i¬J3¬Ã´øÞÕ[6àªÂ¬€·AU³Ä¸)z("@ v½ @Dg YV\÷•ž¹7ºo;ówÏD[!—·´æ“ô²›7EI˜‰cœë>EHBÖ”=@K|f²‹$þ¡ö¶Û=«­ë/.'ÃÃ/‰ ù†u’y\ˆQ?áOêý!CÕr¬<ôsÙù¹º¶»¥á¸&ND~©Úä¢E"ª¿IÛgž/’ÇT¾”¼Y†§¯)½šlkädeAZ½šÊõ©Á¦žÊf RéØ5û(%JÅYgô}Å"wÇÿŽ»t³”5šéYíáeŸ[#85Rɘ±/IZY"ö%¢åŠ+ Z*¯Ä’ÒnÈ%"°*Î]!g$-v~^•YÙ­Z-oú+TwŠØJŽåÿ¨žÖ›ßšß9Ö|×G¨Í,¬jFšbò]¹,åÁ,9%@>xã›"úîݺõÎÖ1>©OŠbãgwÙUWßdJ6X«^,ÝùæCÔ¯¦ÞËÓÞžVwc‘MJÝÄ¿I†»æô(êÏœÓM†‚\á¡U2u—yWZD j¾µHÜ4ëz̼͡gªæÌÙ­QQ†10Òós‘C\CJKŒì)ð±f¨ª[A1^‚=~ú™â|UÂtlo‘j¤ÑËuC+žÐØQÄ~N âÔ‘Õ¡ÜLÒWJ ûaHªÌÓÿøœ×õäm-ý 0j.µ,åÈ´³šµ˜ÌÏýD2©Uë¬K„ð‚ÍÔ±˜ˆ Xö`…Œ;k³sµ¸§’&G‚R'šGA<_éB¥c4Rlyé­'ñakA‡¯A”3§Øó'%N2êÊÑäJ‹D¬vkáˆäØ7—<¸qOh£'7O½÷äbŽ[­Š;µsº.}ɈKÕðÀ ŽM@•_úWt¡VxgË‹øï¤ÛévÕ{WSmVW>¦{õ°ˆÙ¯¢óvd„™“·±fÖƒ—È)ņw’ü™­å´6¶-Ÿš¦F2 ~©D%¶Ý”ô ®Ã§ÐmÇoò«õ±eÅþæÝÄÀo^ëPJØ E›7Úè ÿ–÷Ûx-$¦øýKDÆ‹kŽD»,áÚŸO ƒEËÆÏ_çe”›T1¿¦Uƒ¦Üxåçù;¶^O¹˜~¯ÿçsýJÒ{¯¶2†•Ù’È{E2±cž9$hR ÍW+ d`¹ÙŒ«˜ Šˆ–§xg͹~JÖó™ÊþœÆmUF°åÁiB£¤.šå6<«uO– RŸ‚.ÉÖb|“ç¾wÅyˆ8EiÔë  ¥œlË¿úœ`¯Ñ€Á­7¢´±«uýÍoëëH‰© ׳7ùôW§ vÑ6Š£OQuÚ˜¼Å•hV%Z®±F~7»U]ªHß¿ÕkÅ)ÿ›œÏ TÜ6¿JDti¡-Õ–º ˜Ñrü¡öõ,&áñÊP©–)àí/a(É'òƒÿâh&Ö —Ù§,ˆfÚWm‘ë6ÆKò6†±Í‚:6ÿûÙݰvz48qIÞ-LYÏ4˜¦(HËqøšZàúN1L1¹" VI(–B'?…üõÌys¨[œo¨ÇñY‘tÞꊹUbYäãÚNŽuÊ=–)HßÖÑÇ0dºŽyî.Šý5x#Ò’Àqž3Êz¢÷sýEÕt¬iÎó(‹2ï'ŸÓ»Ã©’õýfL9P­°—Ô±ô—&¤rW§—ÌhŒ™íäŒô´›U†ü‘&zYsÚFÈ´Ûlò€Ó#µiDJÊ´“‹Ý¬²7†|ýäoL]V¯´ÎÇ‹Às_Šn3Úi<¶PCÒ‘1e BÊ Ç !.wRÿòŸ^:÷ÒÀúÚ9`ñ+¶b/»oªÂÙ¸ý^y? Š^öî)}ïÕó¦FqÉÀ°ãH÷s.9H\U³©@°üþ‹Þ:ÚÍ:jàç)˜¦}A ÔUVÊÌX@ ×ÍX KÔyô¬*«T‚jÞãPljH:i‘zÔ„d‹ŽŒ“ïöÌ[ÜCaƒ@¾V1â+Z ŸÊ#â±f¥ èwøïõ£“êÇÜÆÐŠz‘„UÈsFÎ6×8Ȼ׸›R”ªri¨HCÝw=×Ö—ÝÁè›AeÙ¹… P*¬z~oªDW/îr¯÷üÕ¼ÐFÖ± t¨È)½-I°&žNæÓ²$ïŠhÚ0d (rJ•+·w44AâŦ²å£]KOV)&L•`VoT,œ¸÷—øk?ÜõT?È·£Noξ0ÞøÖ¢€¶Ž~ÐåÓŒ‘m ¬úæ=UéRK €Þ­‰‚/n;Ž«ã{nOqfÒÎy‘’nT_±‡e¬D»™.ß1ë1Õ׳¹®:ªÿØÔXÿ¦Og7]góŠ .[2EÔ}RbD{ò@žàšõbñH°`µr´­6¥­NLÿ—/OÜ¿3Cù6C¥Ï.b&Âssúoèѯ©FëlÈ]ñ;GÊÅYbR¬ÂŒå?O5c wi‰ê6™«:ã]Ä&cWšW5½î¸ÀqÐg~i¹;LêRl‹TÑdE!‰°Ô)–-e¤þMp›…ùsï?’§ Õþ·^>†š ¦X¬6–|Œëh4Äê†Ïm].|÷Ø-|ôÚLHEçÓÙ]³:ÖN…FÇÑF¦ß˜Á£û›Õq´n«¬ã±õH½TÈn‰‚‹Z)]RØ0wÛ[l#®Š¥ ĉŒqˆ7€,³åWB¢&mE ›ë"âpc‚þÌòW_D7Æh­)‰]4•‰s4Ÿ"gŒüÕ³ QÒ¢­” W/þf#>[´²W:“#+ h³1™S+ Xò!ØU[Õ‰•—h¸Á¾|žzåg"FÈM8e“Á°Â©ÏíóãÅr5– ¬IÕ‰ÐWPT²Ô/Ά…ÚJµá‡©[}¬33Q±ª˜¨´,+ÀèªÈŠž*²ËyC™R®¬:fj¬ z +ê¬E²¿B÷h:T]þ©ì _UeœÅÊܬè´Ët¯Û!Ps£fqÄ×ÐÞn‰j²º¿s,36!¯4EBd×TlbQºÜ·IC$P)u„#f¹1’-<ýÈS)”mV¿þV#ñý(]rk¨ñ3nWk[eVÝŽi¬xù⮼p¤fb³ž¿±\«°8Vôj° ™j«˜°­"ª—dP2:ŽËšj!eÛ´ØG[´¸,¡áâD‚ª2*fÈVMbXãŸÁ”&ëD¤¹Øa` ¿kŒÕ5b®S‹,ÖÁŠ^…!ê ÓÜDú3 ­kÛÞˆçö®Á(I¤Š’K¶_…¥?þ †[Ù¸hD‚ûͨy’©÷0bÜ#ÿk’†÷”ƼÍS¥EÌ\ß(bÖ%\vˆá BͶ?¸sÃûA ¨ý&‰¯núë1Œ…Ô‡aH«f‰öIäÕPãûN”Øià 2õÝ¿¶:ɘÆróe&–V=µIGo\Ô‚¶Nhâ~*ƒ2‰(¡Â­¯\b++ŽôXVԊįA~8x…“E*@U8 ‰ƒÜëR±ƒ1`¢ØÌà“Qi!±¢ f$NœÕ%UÇjÙ‰‰tÏ3OнÆÍ‚´O»Ð“NXiÿ¥[V´óúô1w./ìBþI‹$ÁS±¨qPÏн‹JØÕŸ‰Æ雹,œp¾›Ž=V#…ó^+ãñÖC ™É5ÿ†¼xòy6k‚b:Ý H¬ôL„Z÷¹mUÀb6“QZ–’é^£ý_°ØLÁMZÞ˜­‹¾?àzE4òºf)Qïgê°!5·l÷~§³˜ûtÒ"⃺P©¡ ±\fD «o1ÒV52ëØ†-æ¢ ‰{V±+Eou¿M×-¾võr´!*RöÏ (AÒçQ¾‹A¬’fýíJ† ®‚ò`YÅÆ’[QxŒMÈ“â-fÄ«+Õ‚·0—ŸÛhXâ•b·9‰*VšÀKvëôƒP’â÷ê´dNšš#ª´R$°9UZØ ¡LA$yçÑxz”_sƒ—‹•b¥âºƒ´y(¦¼óócÇÇJ«h_²ÂY!}Ê&¤*¢®3Y•͈­˜zHV%µÖ±óŽÃ·~«”ß•­éþj]Öþ-„çýP!IX²ó-®²ÖN`Ì1_  y#KŒ6a{ÀézÒm6ЛqXlÑù©aí¦^BqØ_S¢ò ­ˆî|éok†óYþÃôHßø·îB®±@®.6œjë6 ˜â]]e… 5aú^êR¢ƒÕw×n†*ª¦RO ˆPú•£è©6n¡›¨Á›ÕhT;,¯!¹ ²¤X¯Ÿ é½·¨js..7«!*ÅQ¬;Fæ  Žiˆ4ÐdD̓ t„¸h¶pÆÐÞ#5HéþQÚ„¹X¹ìßF±Ë ¥ï+‘·Ñ L xÏÆŠèôù'W§Ü~7[µÎ:ê,ª&¸¨Ä^÷` ª:•ÓLï°b]dªÔE³ÛzxôÌæjfïêˆí4¥ ´†£<ÖdƒXTã³Ãfð°eÞGfÄßÜeàe*±xü–]“Ua*„‘Øpr¯1Q(œ‹ëÃýŠVL²ÐÑ•Iz¿i¢BmQqÖO¬yô°éxÍ›¿© ovIº¥M¬c•®@=t—Ó¿§­ÛRÏ©gˆß>E j7EŽ ]•N÷ðä9>â:[àÉýKWgT4S4FáeE‚DÈšN:};Íl6ET¤·›üùå¸ã̦æyãþ[ˆ7C4Ç¿Q¦@ÑÑÞÇj´3Ÿ––1d›gÄÉeÔW}¡æßHºéÙÝ[F‘4¥ïêô‘3H "©Õ`ÉíBRµ¨ïpˆ5 ÿ,Þ§ñü[Ë Ç¼ rÉÑ÷Št ˜ã ‹½”p.ÛµT0w« Nš—gë‹û‹üQöæ›™©åãàãDç`ŒÈll n‘˜)U$¾ê½Ä|ò}¬fcé˜Sê9Î1—Ôê’A^š%íVܘË<øê§¿‘¿T{žgò#܈ž]Ì<]|ý‡ïU›¡)¡l—ªlY³]z/ŸWZ\ßZŠ…†Eq ´)ÕŸˆ×ûn+j•øÏÙ_·ý¢³Q}Umiû}‰3xµ¢b•ÎRËe†Øµë6`ç9íY™¥ÉZÞÄØ•™=íQØÔ­ ?\T²_øß仕’Æ‹Š,Ëp²™Š ƒøÞloJˆµ)õ–ÑC [–·ú Ö]¹¢âéøxøHV @$æß@¹ð-|‚A®ž¹c\Ö2u\ÜŒü©-§rQTÿ*5¿d`š (àñÁ¾~NNg ÝÇi™–3I½§ÿE(oe —ú~_1ˆÔ¢ef½Ë MðŠT¬X˜€Äük­7l+HˆbÖpmfÙ­@@kúN†­µaaTÙf“¦‡ë©µù¥”ÁQÌü«TÆ¡Ž= Vvou¤—©7ˆ"Ñ­&¦MŠä}© jëá# ‡— ÌX¬­`šjñ ¤˜ã £ôˆ-ô®¥Ž¬š„"Õ´EdBÐË5rV/µФ»Š Å“CƒÈþÀ|òrÞV4ÞÑúGÈä~?¯4yÿq×ц" í Š2†’\ŠØw)—dRà µHJ°µ.ÏÀa ÐKÜj‘ÊšˆÑg'?:¶i¨¸S+#ˆйÚ÷jÃþ¼m‚RÐa¶Ê¦LKGi¹°ýÂVBwX6‹U–¨Ã+²Q˜´†VÊRªã5v)Õ3V­–\öTµn”@1M…éÔ«.Hÿ,¿[ÕvWÏ\c)½à£Óô»PDįeF¥o£êUÏ}먎É;}6b÷Jÿ)æøóñã⺀eÙe˜OäŽò+þ¼|uí–é_‰è¡3ÕNC¥žJAV–,9°5ôHÛr 4M#„y™¢° TèÝõtt÷é€-.,ð &†#‹Ý/bHOø'þ’ݨúS%¤"Dëã’$&»mƒ¹y…tÎ"HäC9C°³A5 ,´4* ¿K³W °ÀÛ +ú†¸ÒA@MÐwÝv8ˆVú'“ÄÊÍXÖ´´´Ü3U þCZì7£Pˆm}®õ*K0"œÍ‘5 ˜!îTöÓH$*“Ë1"¶(åõa§ádåäE´1GwE*QjW›³tÈññjŸÅ'©ÂyûS Ò¤k¶}6dm Dp§LîÕîeÚZÚ2åbka. F×î)ŠïxþòØõ9ß¹fU¸jÞ fî6hY«?#•¡Ï®°ê¹>ë—ì‹s]èÐ&o=âoo.XÚ:¸§V¶€3Ý"]§õ¯G½oúA‚ÒËÈa†T€Á€¾¸jà¥óñ\Tøû Éüš¯`A±– aJѶÌoŠà )rï$ö½Z€Ú±SÚcçɽí¦OrO•ŽÑã\¨Ìª£{Fv3Xbw•²,H:ìÖÓ µáÓµ„ó”GDrI•–*4ÛÀ<ŠøàütYè¼¼'·vÛÆPæ 漂HC†)è–+–moi-o c쵫̷ó'ê[?_µä<5’E«¾Î6UÔ«œ1™ÌÔ»Ê`°Ozß6¯koJYé.Ðg,Geƒ,¡¥­WÕç¨?z|ñÏEÛôú«åJˆÌ!b+a‡Ž¹VP Y°PÁÛ÷IU)G£M†¢¢eø§—º¯-ôû>RòP—ÊÝ톉DY3“!t®ÆÄÌÐiÝR+38ômϲê[WïÚÑÎvšõ†J¾”蹦¶uY·6#ïYöýÉ#ÓŒ#y?óɯU»‡HÐN‘‰_w¨(ŽHÐ)’jµ1“©f>ª ­ø‡ ÿÅ?“êÑ“dL°KH¯xaFN¦S_¹ACg*hÑg÷ äjå/ÁàÿøÞ½îžØxn¹¸b&ÈÃÉ• ï,@)Û)$ò£òiK9ôì’ΞŒÊÑ’y@Õòn¹#Á²8&Ê€ÁqŒ0E/Y¥ddW©,:ØÑa3 `°ZZT°'>—ʰ)=äëHVSÙ3BK™¢Ú. 8ÅjjŠ!ùÑ@ߨèG7)rÙöPóq¬¨ì‡Üe7ÜãH¨4ÇÝ%¹,³7¸4•)Ì¥Kú÷ʳGhã>ói ˚ŢäÑ1ËE–„ièž Q|–ZL ˆ4(IzU‚ŠL ®ÐÌ€~¡ÒAJ3¨Wð_Wuê8ÒbáÉÅs7÷0‚GÛN,Ó?›@ø¿ÇZpq&3Èv•;9ö²ùàx»çÍò ‰ðí×$¹[‘ «$ù®'ý`îü¶ ›:ša·Æ¦°Zµ©[¨Î»§¡rЖL”=vUH ×ì`gúÎR^-Z°k‹ýÚ‚µ¼M¦–±öü¶8?U&ÞO1È6 ­hT±'òE ¯ÏÁùຣb¯<Ðøøçñÿ·^Gjؤ¹•¡©KÀYˆ±ãçú¡a4B|RR¿þr~1UaE‡CšÀ‘®E#*ÙŒè\+(ý—·ÆöüÐB\µ[ëŠÏÞ Ë1P)[£ñJòBI@½Ù0û!kH{ß lRˆ1"ðøRK@Ö)õ…&/bäXÑv†6ÛqA?¼mªºZ CɬõÉŸa/FY_ŸSgy˺D4ZV%Ì`Æ.rç¹Â½šau% ¤E&Lè¥ÄG“ê=…jQÀ[5çóÖJê¼í'ÿ¤ 7ÇÅyýê¼ò:Àð³y0·’ óÅ ëI(®Y è% 7“˜LA¤Š0—êl£fè°f_‹;SFGQ×ï»tH׃Uò• _+A4³'©Y°Ë ·y­èf+h­EÞÅÀ¹ºØò°ͤ¼@ï”ÚÛ== e¾ž¹ï´™á}e\±í(*î¡e\a$ͯzË9¹‹¬ÚĸïKÒ–æà®& 9éP¶´¬ºÖ cCn„â@\®ÆÉ *ØUQÉn:Ù¸= ò*èówàÿùéß‹Öns† øÍÑ&óNµ~ ú7Qo9Áz2 Kp¹iùÉmu›¸N9Dúq«2¸¿ä¯×‡óÁãýGôü¶fI,¶P±xÿ‚™ñrO`7~F¨EâÍM¨A^t>·ªÊ† E ¶%þ^”¥ï÷S^n‚7¼Wîû®½i`Ú솀úivgóÔT ïRV-h<ì GZÅe‹/*!Úã‘£´ø1í<É#äüu3OÓ3@9¸xÙFæ‰d7Áãxe³Uãäüž¬7cùWþI¶ƒÑõ§ç•dd†|>Øœ°`ÓIdYUæUÊU:1˜À€‹€Òª±?ç@Ž×ò‘ü‹7ƒ>¼}X²¿°~ú/ç/&œlXEb3à)S§¢à¥ÛvX°íRÈ‹QÕfÀ-I€chžÕý MZù’…¤wý1aK µÑ¹-oÿ‚¥9`£€Sð¶!®µ˜m2]Úñd‹h<Í5V ë)Q´ ÞÿhH¾Œ#¦DäOÞÖÇas±²]CRb¦LÌ™XŽg#wjϸWäs㨋¡h ÊhúrÙ Î!$¢‰1V+ûññÔ¬ò÷®oW>pçYå|¯ê{Ô•ùYË=ù ù¶ïyæ/˜ÐËžW3º}7³îLöè2e´Þj®®äPË‘6jHÿ" ílðVÿþò´¤ÏÓ»rcÚ•¼Ék7-†Z•{TCƒ£­}†»$v¹dŒüéö½…Af>¹…k] ŠÏ×#ù-ÿrÖ‹1J²Á,*95ÈDfÝ\JÖ²ãŽAZ|&oó#V¯ò,€aûæ>‘ýƒcäI‹ŸÚÓY‰6nAÔq!Ž$É&ö!RyüþÕž.¡ #W¥Û T@-WÉ<Ÿ<¢8xŽH¿×.»&å¿ÅZ×öUk* à Ë•IP“åS­õÔ‹žä?Ö&¶‡«?ñeG™ŸD„rÝÝdÁ[¬‘ Ï­J]}ro7rì3°Ç{Á˜(k#׬Ìç }C½Ö´fCŽÊk°fHfÈÓÙP† ‹m]“ƒó­b¡ñ-ÑSœÿ y[·ò;×s§ßÐÒÈ¢k€Ä ×¢«í]aÐt¥F!°:šµ æ$³o”û“zŽÝú.¯Š¹™79 #ëÊÖ1ÆTû}óÇS{‹¿1ô9†62&fQSp‰?‘Ðd*ãå -ÆÛ&º½ÿPÿËSœþަ ò ÆÕSèëDl¬ˆ”¶Kvk9=01ðdóa¬ƒh^¶H™—eªV¦Š|¯å>ËÌþBè{î×`Úö•ÎÉêÃ&Y%þDª™©-$4¤šrc Ô縢"Ññ-¬É×<"—­ko™ ï|þßœ@­Z-b’_®µ­F:V²9 ±;9kè—A$‘“¸ˆu‹MmaÚ–šûÄ1zÖ²3Ïè¾°Ò*H5K[\Znéši"ֳȩFR@%‰»>}¥y¾§uÞêÕ5öÿ“_|xQ B¢•¶.H;yj ž,ßKÇúÒ k9Vo´º·ÎW*õ©O2àËRZ¬ãLV´Vfh/ŸÎñIŸrw)Í[¥WdeúŠUmmçP‚¨…õ8Íåë]i,Í(ÂÇ{HD·ÈR¬© /J $¡=¯&7Çôò\~¤À ®kÀ¿Áâìž—™ùË!tˆìU6ÄþÀ€çýÏŽk¬\C¨ÃSÀ˜ûRRõÌ9„H´hWò)2Š£° ¥'Æz ³Yeê2¥.ø¢æ‚=6<È$Žåº5b¬ÿè®{ ¬u 6—øÎúû¤oEŽfJ±³ÖÙx¢^1×a•³ìi}ÌúëIÓûJ½—Fé‘qO¾»ºEÎ䤵a*ØÀj´›í€“‰*¨²®uò ¨H–Ò$Ä­DB}*K Œ°­«i·hùt` #Š6kžâ üõF$Ý´­›4TÕ›µ_<ž8ýN=> yu° Ñjö«•}±®0|ì|¶0YìŸÕ+ FJé©7h„©ž$¡Ž˜cÑtg ¤oLÖ´–ªAÂ(Já55üÔýT¼÷­‚±aýöØ5‰(nÔn¯RÊ…‚¡[îR§ rļ]°ÍÉq^XøÖéÀ˜Xc[åðHEuÒ´À(ëöøVm7­IjüïH­bjZÌýc$͈IµâþÊßý¾3KÞ£#PrÍrê¾Åü¡B‚î~lüz¸ÅÀ22<ÑÙøqF“b¼ÿNzT³–#ö^ `MíbÜb›Ž ‰¬þiûb 7¥&pOÆgàZVùíWø›ôþ+z„K¦ÔWVr8dÿ^;ÌÒo?S¢Ó]”lƒ‡¨‚“BqÏ.©,\aË_é­ÍIЍT˜<ÒII½æ¢5~%Vô™÷³C‹}mcá4¨æÃ¬”àš×îëãø.ðʘ¾$Ïë5ô:½½]Ð%Éù¨rkaf>Ác,ÔåIžà’>ÑhGøÞz›cè Ü³å·ÚăL62 ä᮸¾™—¥Ç>±Á‡ NLŠ.·)ska–ùàÿKë¤/Ož.ÍKšÂªÔëL„Üjt¢±&ý­ÐzÖ¥©oîE®#áTë#­cåmO0háó±­euDMÏè±F¨ b†-c.Q‹¨Q-1¨àa¸…–(ÇÎõ>æí)Åð«ë,¸Þ}èdžñþà„ÁöV±{Z¡! #^F·²´0``¥kPªü´êÅéM+„L,ð Õ(íQPÐ5¡€§"µ´C"‚€„¢Ëˆ7Ð;ÞÅ„f²âàC†Š‡#+kz‰Ã¬Œ…BƒÏ’ydãÏN­MŸ¨IìðãÆÔD¬H …Nð »Gû~\Æÿ0ž£õ{!“ĈhмÂ.aî0l¶+ï,¾ú³r³¨¡j>WAdN&äzƒ5ˆEÊ*޵ÅáîÐn&FíGu3‰úó¥šÇš]5Z°J´†ÎdÊ!Ci²¢R²Æ¸AqêëzÅò¾Oõßog1&Çϲ¼î|[é‹° þF c¡{Ô³]kkÀ[¥L:«õ­6‘JßäoÆÚÒÂÓSg<Õ]°ÖÒ3Þ(È(+}ƒ5HGÀ±`ÛâJWì0•¼È¾³PWBv&‡¤i˜ÒñæÌQiš«ÅÓ- ¤ØƒÒ¾²·­êrFÅŒRÍ3‚Oò¢ pi—l—îÜÑzžùŽ)uJ #•KXíSXï š‹Õ6ƒÀ»m û‡G>969¨ÃTÁp0iouI-¦€ Gò4ödW¢c¤’ÃbCK}g=,¼ÉERÑŒ”[àZ;™‹09ŸùÞIUà<àªë3õØwümôZÿm&ØGQ°QÍ. Øe=‰O$ˆµ®:^õ?ØF&Æ e0 Kвj6b’²þë'=,½&±¨/±yýefGX›Þ#í‚Ù É #ü}ŒoÏc\Ì\ÿÞ "Q#®0‰ËÎ1â² ©Ø¿ËÙGÁ!wsÁùƒ }bÑ£ðkŽ?oÔ_…ŒÚ.3Ð+냳rÏê~º§p²{(SÝý£ÄRP JËSpŽŒþIÏÑ+9åšÙ ’ †dOEæÅ!$PF –ÿ•¯cüE4~ïaÿ¤z ºb£¸è9‘/Oj  µ†È [ ’JüÏX ¾«5q8zXC×i }zö¤L‘QÄX‘ZUkZµ¬þÑò­cå?ÿÔÛäH¿Ê¤´Þ-íškús²ÿ!ÎÕ;DXÉ[lJ?ë>xSv>œLlJ ²ª“â¾G?ûrµ í1ù@Mc}`Í\¬âÅS(Ç{DV‰øÐJ}W:ÖmV-ôÎ:|¦-?Aù¾¨¬‘pÍ1eGI±-ñƒMnR}s7+P%`à(&‘xMTC¼{$¸2KuµÆ½#äjC! 6.HJÄd~ö¨kbTv¶8¬Q¨‰­®H¤£ú®Ô¿ôÁ?؃,jͯ½+ ÆAŽÄ¥à²s]‡Û«¶Úè]þ|Ÿ¿â®#T|ññGš??ïã‘Örš•­ÍKÔs Ú¢^¤ùÔ”4ÌáF+i Q6j¥k[YŸÓvI›5"¯‹‘rÅân!’cãAÜŸPäµ5¬©þºÛíÒ>»›ôE¾—^ä›}.Ï6½çÙ€’À¯ÒJͤÕdµºòKŽÅoX }°;Š“Iyoà°5«î!P@¨ pÄž-unÇÞ*˜„ HÑ(Xµ`‹’i6t€ÌÞ¸¶7’¬sà_ÅxÏÏŽµˆ|yþäïý~zP-ÈK°r= –´»Ya–伄 MþÖ=è«§0ÂëQp•d»Ö”ôp³ ý–•DJK4øØùn ®!HµL¤Ô_»µ YókQ&ýö©J@É– jØV‰¡&l:ж–o'Ï깊Žmð’ØW½½¿ÏKô¨ëÿûû¨¦+5¬ÚÖ¥ìv‹òöúíZÍk?ó<Ävê/£8ƒî ,Øâø6|~ÿ‘篞Ÿ5fÉðMþ?óüëøéHËŒµ=>Và¡#ë­•¸‹kÄÁ^E†ÌRI[Tš¯%§ßCA/h¾Ìß”E~ÓIKíhˆzž—¨í!4„fb.)¹o*1H€Àþvó'h*Á++ŽŽ×‘Õ¡.í./©o¬²UlÅmCW¨à׊Ò÷‚WïO•†>+ü`­É2÷%Ô-jÏÞaÖ+ðý1zÀ‚J‰‚‹éªß<+T­i,ïÈýCâ¿>OYÆê'šžGÇоûqÖño17‰]`T(m@®2Þôµ~§*F¦)sµ%=⦥NV ¸ëRMãTwÁkX•¸ˆÍha}ÏÙ`šµˆ€kz€º3ªRV[+%XÖ-¡[Ö×b´­É·½kKÚß¶–Ü‘H§Ëì¼Ò¶$@¦ñãd?ñ%"â-¿Pপ䵯6EªX `U,‚Ô :ÿÄgøÔv_!©£ ŠdQÇŠ?ž? ñÖÏD±‚§l~߆±WÍô¨:1q±fOZE½ÖUa— AA«J[邎¿c.°H 1ý¤7ÎNþãƒÐôy´Ûò-µ#«†·´´[±úïV¾‹d×^Ït,Wô¬Ä r}  ãí?[÷R÷´ÐD7Ð^ôújY’œä’”ér^K_fdoÒs¬%X0Ån|:Ö~M7ÜU•_7är´€ K-@Ù¶ÑSCî pÑ$t"¡z­|Gf‘»Í*1NòîTÓô©–!éË:˜Ðo³v»…Oé¾~|ßF]¡c\U4`Å^mÛö©¯fâÚKÏ‘t&À'ì(àô1Ýç)Þ(䇾„„}Pÿ ÊñÐçùªÛG¨“,• 9åXßI™t~ ¶r¬J,‹²Šev€VhrÈã—«¿STåˆoðå^ óR÷×uä[¤šôQÛ<¢Ò{+k<ëg·QÞ…d7RZ`F§æô¤Ëš³vŒRüšj—ÿ²÷0ì!¤lu÷Š>UÍJaÄÌ‚³+^ØíeÏ1j:­ífõcˆ äÂÍÑÁ yãóÁçvwøsK¥é;„± ÓD ¢¤<Žhmù±ÒÇW×ô]¾Û/U¨æö›Å4¶ö›Dt“ÿ˜?ÖX" ôú­í*Ö-ïˆA¨ëkŒqzÉ~ËW·¸ÅXˆéi¥ëþסšübæ‚IA@Å>6µrI’±I°½çØ¥½bö‹Dýð"…±kI¬Ó『¿þÚÄ›E«öÆŒ zŠßþïâRÅêQÍâQÐõ˜¨þÂÇÈ3qÜ‚º³i/ÆÞßã†ðá†0Á‘Q•R0ªTm¶5Å|ÏI|™BÓJÅÙ›tdîrm‰Ýî$“ò?úñ¡ Jû =­jâ­¦Ôƒ)4½ê;²:Tö± f s3ˆ·þv‰¶P`~ã%¾L¬½ŠæsyÐa–•p,Êí «‰¿%?ÖÏÍÐ#±oY³w–_;GAÀiuo(¯÷’1Zh䆶e•>L%vkY:åûY·Óq” )‚©ä(ä茦\§—šÛþò3X­:êHŒbYŠ‚ô¦ºµ¡Øh¢!Ù|V™$¢Õ8 [V®¨@£ñóÏãóÕflŠLA„j×É ¼ª¾> €Iä__Ԭɚë7-á„î½¥5ízÙ|ëŠÍZ¡°é ¶EJ‘1Íì¥ÎdÃtMÑÑašš° ´ûÚSò®#ßöÔŒ¶C¢(©J\6Ñ c¶²Ÿj"!##¨½!{RÕYJÐå ß‹ïi¤¨˜)XY:Žá¦ãA>ÖBTKºÂ:¶WP MŠZýB« Ô×\4ø|€KDÜV¼Ž…Z÷¥¬1¬jHF*¾ÒÇ“d]ž?ލ^FrTƒ·ÜsVx¿ÏÈãóÖÙØ¢@(jhÑQIj×5Ki‡è0­ð™ÕÛø_çUC5B‰;±PgM×UŸ7 äÆ(ã ”§™°"G[e‘qsË©]»X–V N)ITìºuÌ·ôÊ}°ã …Í"Ë24H!P¹—©¿LÈ¢²Ù‰bUI ¨Ž|Z~áxK™@ü¾-T°¤×—¥¢ó+ÀWú‚RWç² ?ž¤÷(Î;…›ºF…XÀ–y Ý\PEMÊ9EŽ êïLÓÆÔÉ™wWü”à•¾ o@ÿO÷ëÕoÓ{-&‰½þpo‰‹ò î8šÖ•´ÀoKÌŽäæŸÌÍ«ôД*ô±~¶$ PŸ!Z¤< å$ j„MoJÐÔAaÅAhŸ§?Á[nS–¬OØ™f—öûijÖš†"Ð k{R•‹Ô1ù– ä“OrE"¥¯¹«33húîŠ×Z‚›Mþ&b"Ñb& y^-Y‰§Æ4Qâªmß=fÞ<×§Çü[£ooÀ[ñÜVµ¯÷©ð‹ÖÂøÁ\š ã3 +QZkx‚@íbLMI3í^ò?‰ž8üφ¸<ƪí韇“UâO¨Ä >y$œÁ“Þ.D«4»-¯¨¨˜ƒ™Ã¯‰x¶¼—äo‹Îµë}]1K4%U­h¨"ï2ÙÔ)) …D†ÑïE—pæµY§Á±ÐŸ¢¥e'œç‘Lô³ÒXi@*z®EîApÞ&IiVâ-åUb jÊ^·üÿR2ñ÷hx0÷dI$Œ¶¥l»ˆyüýŸO±æXõlÖ»ô ‰çqK¨7|Ôhƒ^>:•ÞWß;Íèh7ùâËç¶Å›`Ö‘ £E -XŠÒ)°—º1Pe) j‡ú‰Ê·ò5êD|Îa¾®“åÝ€µ“‹DÎÏÿòz”œÊVnŽl­M:’‰Œ0)„2Ô.P·oë“ÎÅÀ:ɹo»ól2AAtWlãq…‚» ­-êÑ—„~»U€1mJüíFúþ¢tÝ›&™rs‡M†ß bƶñJóàüu¿5lÅÜy¸l“÷^ã‚•¦ÄÞìC½&øٿØQ¿qÉ÷ßU# µÚ™b¶> fæ/$Ëõ—놎˵íj|ص~V­kñ-ÇX­íkyš-Z’ -ZÄûL/Êk’„ ¨_û&¥¯ÛSP?˜e¤ÅiCÀ¦ž÷¯ÊŸ¤]iŠ&cë¸)i©&¢›Zôû.2„‰‹Ú£½´K;ŒqÓ°cb!…Ä hÜZ\jñùûuÎI™¶¶ç,ÌÄÙbÄk-tOÁñÅøè…âþ ØÌf÷_#Q‘Â÷åþÄpÐÕ±¿T0¸¨Ü’Ù­–(ì©)iY‘€ƒ´¡Hl°ÃÈê©ÓRh4ˆHjÐÀÝ€8«„‹Ä’L©}E ^ˆh°h*“¤Úèž Vµ´[âaý•´Ö¦ûƽ/1j@I`›ãZfÖ¥#ìù×ÚII÷=L>9êï%ÊÈfD6s€ÊùÖè0´¥Ïú˜Pä±€{…ŠÞ(j?¬ª¸É’©åáä.3lj#¤‘[Ð!‹! ÐO¼=5žâú¤Ô°™‰ÈE#p¹*†Ð*›óýº‘ލ‚««ýž{á…\xÃhšP#…scUåÚx¡ö1ø×ÔjŠ—eØŠÕXºŸG›]<Q:«U€ÚjèŒCÑš‘ZÈ!“oMMf –t”wà öV «@Ü á †%!@R¤M„¶Çc¶Ï¤)JÿjYj\š)ƃÃføËœöÀÆîæ•AAcVͽ]Kž~…VSœûWð«Ëò‘è¿€5ª‘\Î(¬®v´…ÑYGG ”¶î!oQ$a¹»…Ú<Eòk€GT„Ê2”;¬ŽNÒ´+ÿÚ=BÇ2É›v¿U¦„ ¤¡,•šajX2˜¡¼ÃU½Í{Ð]qB54–/1Dq| Xý’eÁZjRÔ!R¢½¾05­"ðFj†GuæK *HòFѰÃK¡ðù‹Ûò¦Àþ¬ø™¬Ù Ôk†&h2Ø5¢‚h´­@Ä[î ÇÔ]ŸËV*+/Of«fư¬*ÄÕ´@ÆqÖ)õé<Âì{p Å¿Þcãab´D¹*Ê̬wÞõ r ·$øÿ°ú(ƒ"i#B¾6‹R?Oéàšÿsdz½eÖµ$ãûfÕ EY®KI`rZM‡PŠö¼ °ÂÄŒÃR„ ï[QªÖÙ(7 ZØTËš|X³ 0RÚ´(;ÞäÌ/½Š*жŠZ)[^ÕŠbÔ¯‘ »PÕú/jB÷5Æ8öÓo´¡¹/i€ûMÏøâo[ÿÖ䊟óbùi¿XmœfµÂ;À‚u–ŠÞÕ‰¼ÙìbCkÿ±+[E-a\d‘çõÖYÓp“|™ ¸²sÊx¶€9³Ž:ÜfÈãŸ4x_Š(ž~/ž¤˜:ON´ÜØÍñ/µ·˜¾hë™ÓìlN .mA"[2¼}¹ƒè°d4¬i³ÌR=‹¤ eÁxÞRÍijÜY«?¤ë­0¼•­Ëýµép??þ‹²¹½ Xh¢ÈÑI¨kz)T‡UCcÈ/U¯V,ïæ“5kPU‚™£ö?ü[¬{Noýæ°ëzû£ù–@*´®z^•%„Bê8Ù$†Y¨âmi(ÏqØkÒ–€D/£™î•Ws·¤ k#ÇàƒF¨þ.XJܸ¼(âèÐÿ¨çàþ1Úô÷­Ir†•¤Tu”R(V‚¸—ö÷M…xÍk ûU«Åˆú¥ijDÅ«Z–­OÈß ÿ8.` l9[v*H)kXéÍì:Z×dtÿzZG5‚|B¬~qMkdlB^lÕÁX-bâö¹)H²äÿ¨ ^ص¤ò ¹Ï¢b@V+A°S• m1ûÇ{Sj-P•³Ä ¢ ªzÚv C°Ãx*¨’?÷üN°Ú@‚<‚+Çìj?±ç¯Ÿ(_þ»{Ú¤Tƒ¸ˆqVð)OZ³¡b Ö²‰R–¤¬7"#üÉñ,¿Âó@V~‰p”©&Gynô±AQûQ¨d“Qü$@@#°¾èI`^þ=<׿eÒÙêпˆ¸Ú™ðg¡æ?K¢OüÌg”¡ S%i4 g´40sAœ:1ëÔ.ŸÓߤøEŒ÷1poØõ™š¦pÞäâèõ ¸U3óô¬æfª\Âdæ¥òɤøš=õô~ý/—ÙKmŒCn@ÚG6.ÇïCÿNµÈèƒÉ,WÚá˜_šžy5Ï#‹£?úóWt¹¦»^sgÆÞ?Ó6Q´º­£¦nÊÆc/úm÷“ÑÚyñ6Ÿõ¨Ð¡Äíi„‚+ŽóŠNb•û+çg‚WB)¼fYjW`ê^½%Œ¥Ôlv^ʶ˜øÍ€*oÞ—P€œ¶É]¦º¥µÕ ,ã4¨Ä«EMcd×lÄU„Èw[YÜ*èÅóR‚Š,uwñhun¼Ì€àfåúI5MS(•/j[Ü`¬›0Á6}4†EÍ£!Ïq„¾Äôâ6CmÈxØí !OP›óìjZù¡àòYcÌ’P1¨ø%©¹à×Åx$MWŠ'gø¡9F4q|Ì´B³Íuù’^Œ¬ßI7.–“m*䑆l{ÕY­"í¬M2þoª=z„ô Ñújæ×éºÏ*qî IÅ’YD1:׌γyºZ¹Y²ž>‚‹4äæë„lõæg?DX¾Óû5Ôélë9¡hÏå®g3cêDCËzça€ÉÔ­ f©– •¾YfºC zcû‰_É'-¨Ï„2úËxWÉÜHôóáÙýÑ(Ôœœâ¶G”_ÓýÀQ‘{ 2Ê0²Õo˜`’0òJÁkÔi¡Ú@%ϵx_Áçžz±Ž#:ÉPF¬Ä,tw€®çÏ÷çªFð‡=Îèwçõ²2Ì·ýl´r²ˆ9,‰»Ä)7nÕ¹'7Ìx_ ¬¤VT­¹­ÑcøûÅîQ¾iõ3EVAT×±±à5 5€&jòp?-¨´º¸À@+1Zš>òßÇüù>ŒóžDgÇ(i{]_èÉÒ` ¥írf>×K…öL0~µÈÕJPÚ­ÁEó€ÓCÖ<ïà_™ç‡å¼?+ðñžUƒÓ8¸&vê̛¢þ¾µ›:A©Š£@iÆC9Äýaa °×z¬ºqê©©8“Òl9ĪÊËLÎŒ¢mÊ´²|Ñ&‡M=]g´ô|¤—BÊ™?R=O E ubG’IY˜‡aµ‚P<ž —–'¡ò?g¿¾½ilª2P v7B‰LÊSþL„¶«Åû ‰@¤“TfäÆV£áöXçÛ ­Æåo{L°U—¨ê’34_ØŸD‚.¸ìF">¦©`”ëÚ°CE ƒ±"­ý·V­Í‡‚ÆŠ«4‰mTÎÙÃúì¼0K2" ¥Ö\6 Çujà6e•#úgça¢›Ì?Ý*gÊíÜr‹ƒ*ݳÌÈîûÆTk‚ló-qcLh•a ‹ãm(PYh²/æ¨Yê;]³ÌÍyÙwvæ “Ý¶E'ÚG <ò@æÁìfjÍ"Ŭb.BÞ´µ{Rµ©¤Ä¬\ðZÔV†/%¥u†Ë$¬RŸÀ\-Pk´±Dz–ÔŠ^Äþ‚|¾?:ÖßmRÕšµ½~7¤PBù_ÚN+ã¦u’;í¾â…I¼3Z”4¥€™yа¥À00ÛSVô\žðïËJT)ëYÎb:PaÌ"êþAü¸KKÉ."4ÑÉUŘ*­@– ·•—”u7wU`¬¼*hë Ž°Ïî"7ecHDò`±Àó@Çÿj=ôÖ²Óh¬Øw%êiV"’bZ±[ ÷©k­íiû-´ÓâCE½ãù}ͤ D[C@T"¶Dr—á ý픉/ö1QUx´Ú–`Vb¤ Ù~ÇïA—]”¢Tƒy:E›©ƒu˜§» &5þ£jœ`][ÍsÈW®Cüýéò1Y­•b½td7:„¥X´ýV7Î׺µ˜¸èSEðƒ°Q³[Þ#ZÁG?ä˜'* ¤Ž¯~ž@³Wàr>ò:Õô´ÉZàž\u"¤tÞ”|Q,*þ~|~@èÇ„/ ±â¾Ç·+co‡s£Àñ®¶‹a£+Ói‡wÈxP“¦Ê"y/o;_¶š9ÛXf\!o$ºR0íw5αѮ›UX¥¡H*–ßgÚ­X ¡¬Šð(‚ –ùÒ {dV§ÕQ×ü™ö>™ŽúNSÆø¼þ/«Ž[3c¨'öVó'iÓ7â¿/릆måðâÓÆ<Ç&êêî)\4£¥ß囂éhJ…‹$÷€Ž "ǼÒõ© ö-(C^ƒ§±G$‹Á&Ô°jJÀ«©#ü´¤’HÐÏ-K1>¥U€J×>¢x°ÖÓÿI'áXŠšÃö¼ßÏócåZèyÞ 6 I×ÖÚÓvYÑýf‚í‰Vþ¿ÌØ­Q&ðªLKlmÓêÿU†‘iûl), 0IôÔjÄÒó6“Ó뽋A„’*Ôl¯P”ÀšÉQ§_M4IG“P¥O¼Èb²?´”^ß‚ä°7ÔÝWÔÖ`ÀY¤h0± 2DHÚÙ€Òp?KF-ê°Ç…ª:—­¢ƒÿöI­EkRãKhŠHæb>1I½Ä¼Õ­ ÀíAš£bà-¼Þ)y™š¾ò9øTr0Míh¨;^Ô™ l9¾ëÍ≱…%²‚׊®Å„#AžZkÔ@¥¥N­Íy1 2­†j•dcLc±Œ¼©Úþ|ˆú­"᤮ÐEL)à"1ìJ¶_cŠ&•ûBP¦”´Ù‚Ô•5ôœŽ9„{GêbÇâþ+öãþ¡`'¹9#Å×÷ùãñ}$Z·¬h9©mrÌ 4™·Çá{ûHä¾ÓK^Öµ¿ã_{Ìü,âÂxÙ[xÚá=‡U4•häVä÷…ÙfÐàI Š’Du/uY «[ÙS];±XæªVb’jis\”®IZ‹ÒÓì)¼\¶ WžßÜŸ[¨ì scòWÓ\²[ b‰Šý-PâJ]2ÿu.Aæ®àfâ lÑÙ°Q‰æ `ü\œmÒÈ D†XÆç“Ó¹ •b ïb€âüù=IŽ/º-q¼Œb.ÁU˜( I5ÏÏ>Hu#2wOªÿÐ%j&ÿn¨ŠÕŒ4 \är¥X%@z6ʈ~‡ÄC1´þ~†{zÄÊ]ý Z„ÏU$ÕTCáKæÍô“Zþƒ5G^£Bmz$ø—SMh>‘¨ck=pÿ‚[ÊØÙÕÍþ˜ŠÓ0>‚úš,“M¡»vt4¥²·› °Ù­Q Ú*c&yÓªó\çu5|‘š{Ò³ÐîJ÷‰>sË)–ì WíIã£é£°ÙÊϸ±þ£*é(Ž//&P¥Ú0ícÔ_xÜp&‡Çç ç†ÙÖ0HYWp*FÒ°|_Å“kùˆ•PúaÑf,ÛòÉ?á–ô¨Ñ³o®à3Ô_áMIÖ’=#OaÒÖ23cÿÀ…‘΄µ"µøWýÌ0Åoó‚\t÷ëbX6û>¥®;ÄÀ©aÚaÐÞ¼v}¶Û|c,œAºˆ6Ù‘˜+D›üHZ9qX°Uþ²H IÕ{°¥ $=‘ñThªã¤"ße„+#CÚ †Ãëþåf®»K«¤èL«9iU} sÅ3µX¡žWib%™6{UH¢8óð|ó]0»S¶5mc¾Ã ³)]#’Ë–$3©ÈkÁèKSsÄØÌGÂÿ!––j2V~á×Üö‚R´­bi¬Ûå°FA^Ÿ”oEzTKÍ JV±7© _ùEb&³0õ&ÓXˆ¬ÚÕ¬ÌDGƱX7ÓÂMêµ6Hx¹Íòÿñ–^VX!ÓjHÀèÿÊÍh… ‹ß*ʺ»1§ð‹‡üGÕñyWxÂ>îq¯óýÏT0ÄdÓ{«:Á„ì;’ëUZ€P€(¸FY%cTþ<¯µ³d>Ëä*Z °|‹ãö³øè´ý9îµ£þ 87V³cñÿýkþ‚ºëQ FmmNo‹ÞÑI_¶u«ÖÍ@®‰×eŒwÄr;mŒªgÓ kÚj }F̆†š.Ç…| žczoáœî{=j«±¥¢Ÿ'Ëc«vª“ÚÛÝ a¦vps‚¥ôÛÒÓ³‰¤¸Â7ü, AÏ8ÿ-^6ÃÌS/À\Ù{þ‹UcÃ]Omfù¬.wï Â#ÉHek°_UjêÙ‡ßÁI ³B´‘@¢zYóתO6z’ÒÌʬîg`~Ùçyäs2¹î[ ®Õ |¹ú ®±¶Œà ½í±¸àݬä -j¼\&ˆ¢º¥6.Û€»“ºô&^B¤§µA<ØüÙ&ë«0ó¿ªA~8[¥â|_éç’òÿ^ z ĺËÁWǯ0ĦGҪƓ}†B„¥uñ Êÿ]T ¦†_›JÐôªµ¼õä<.Ôï ‹á}Š ÜÄâ¸Å 9„ÍtH˜Ö¼“ZŸyï/lèž4›‹ Îr g+žŠDߺÐëZ\c7›}Œýö¹h=¬5Z$ Þo ÐWŠz¥n»rñBŒKŸþlŠ£µ ß;Gz”¿*Ø8ä…¹¢ƒ¥boo{’(m ID,Ö|qFÁøãšã­E\“¼–$Ùão<üñýë©ëçÖ.dX yï¯ÑP•`›xœ§PvÖM•¤Þz{T¥l¨¯ù¥›ÍŽ¢ÑobÄÚWòÿ’oZ¹„]ô|Ü:rUÛ¸OxU³Ñ°€c#*¼ïß=/õÞ REú,¡½ê h¤ÂP‚G{Š/-ÖÆVÒ@Œ†%äEŠE,QI+&I¥×5$†¨îD¢u¬[E ðj”Ÿa~UøŒÄ’ÈÕ É ­uXø³X( ¨æ€¥âõ܆HuR¤’A±vAý¯ð8£àQê9ŒY!M)#æfø"¼_üu>Íü˜úâ^j?þæP6üŒÒÔ7†|?x$ÌØ‚ «â¿hT€5¥Až§Ù'²ö¥GZ¶ò}êÿõÑ®¯‰ëEI¦ç9%Öv`?šŸb\Žo,:7j«)„¡ä¥í0޶q£W‘/õÕ½þÏ”´9¥ ÿ¼’­)æ°¤_þóÖ »”l[õûû¼òøýs‘5(ê p?¼ ²¥£ŸJ0Ù ò?›«‰A ƒ5vÅXΪd¥†ØÓ“&2ò* ´P¤–P¼Ð@^lu' l™},X™Ë%C2­7à5ÉðqÕŽ¥ü»ú𹕠¸_Oî’5Uø>ÒÅ•îRIûÉ ]6Ä"Âé{’£a4¤e‚ÉãU>zõU¢#ó^+_ —X¹n[-ëî©ûYÿÔ]¦ù.Dùç6œ ÇÒ#º#¯Ì²Âm<:Í?™˜ŽiAzYâ8•  Q¦Y‘~P[=ã¿\êDÁKûdÕ”Af ùz”µYÎrñ^}ÚñGPÂkæ×C.„¯aU³)¥E‹Kq'Užj ø°×µ©Ÿ­ô±2°ÕZTTOX–]K . :%û›° @Õ…¢<óýè~?Òt\ÝÉÁÔ»ŽW‹å2ÿ$³¤RwDó¯$€ÔUTÐðAøéÂÉå¢tTƒ°dn–‘^d¿¤41G“b˜Ôe±ËÞªÙQÖ‚è^ãu[ÞUj"µ‡üíãªñß<„LgÇCÕ¨ÏO@—¡ÂŒdœ™hŽÊnz]‚1¢þŠä®› Ud¤c»e[ùô›‡eõYò.fÁþGx âÕÿU칇ôÜH­STF¬ý•^“['{Yƺǥjú‡ó7Ž<±äl }F9ñÿ`ãº/eô,GÁk—äM³è{1Vžèö² PW€Ò%òB··´-^ ar3ps!‹Ö‘šXÜ@\Ä@$(ÇqJš4E}2u>áг± ÂÓõ<,‰òåÇR•¦1úÑ@¶Ý´ð¶lüŒ’Ž~§wù»/Ö)q ß²™Ì´ZBÌ×EŒÐὬ‰ª :ÍkvYxY³ ˆ:ÆÓË`ç;bÑ:êVµ4&©•ÞM†õÖù¿{0¼E—©£c#mQt³mÌÍ ¢³øô’y‚XÔf¶¯Ì6/ÜiM²µËú°áБa5IAG¡é¯SЭZã Œ¨-qâ¢kÑ…mï¡“›Õñ]HàωµÇ_fïf"öiIÒÔ¬KAç¤ÃsHë>ªäð+Šý¯ñÅðÀ•b‚lZŒÊ»m€–ÇšçÉÝGÍôˆÎ~5A¦ÙB¤šç¯³)‡À)fæ]ý®+pª«V!Š&.êØV‡aqº’5”¢K¦cE’­4FKÑ<ð¸œ4ÁEFL2¶Ü«t¥•²u8©$Á‡Fé—kCìÚT[ß+ôii$6™µÙ©Mf“…`9Î3CŠ![?ÙßIãç‘Çã¤>µÜÙz¼¬ù,©` ¬j€ Þ§ÜÒ×’ ^¡ïØ2M"A¡ÁV½í>Á$¿kY"¶šÜAŸküD9!7$*fîBΤÖBº†M/4µDq/Ÿ¸âšÖ¿ö‘YÞ}éïïkü¦•Š„ÇqSüà !BJþŠV~ô©IZÖ°‰1²:Sﳋ-=®DïRÄÍ~ŠçŒE×[Mzüdz WìŽX ­eU*Í™lÑ2éc²gª¿Ùf@]ÒÍ7ÆÅ¶C{Ñü9ÔhM› >GÀ¿Ïy窩⡠²*‰üíó}iääh?gû BVÔ#ƒêf*ø©¤jþ€¾u/`ÔaL ç*ãA#蔲2˜ÔX#î’Ì¥£ô÷´§±ž×¹ì¯ÚÑZ*Âu}@®©.ogbäV×5ÖW(K}h ‰ˆ˜S@%©”×/´…MC©/h'ÝI1ýÎèe1æ^ç›NL¾m½™ÍW(o>ó-j¦€ô ,@6Œàû ˆiŠ×zêüi ´¼3±P},“ÇŒÀF¤ ÄS7ÈAø5ûÑŽo 2I,êêR®èƒÍ4 äQþü_^/̹þëÕI½½ FIz¦&Ò­œìĬj„%­\%îÉ^tšCKŸw8ãÒo÷ž•Îv ¹Ô°ó¿öô¹ðŠÆÁI¼Ò-¦„¾LêzAu»8÷²û:Ïó¼­“6½z-‘¨Í4™•®5²í…E3¶G·fötcD›Q2ð*ŽeŒ¬”#Umíå;U†6]¹,û¿²EK¼qP®·j,O¾Å‹BÌV¶)«3 ,3Ò>¤÷% F{Ø Š¢Ù6GÍ_™˜!‹ ²Ö€‘Ö5ÝU•…94†‡ŒOŸŽ»%ñw-ëÃÓß™Êîx Ã~päù®}œnƒÓÇ•ɵiÁ•øyŸ$ó*½¥i˜£ ][ ³ß[–’.¢ô;úŸä;¿ÍðÒÙÞ‡=v­Ó² dzý>볆óÀîQìË–o)%äìŒâ¶½J°™¥$e•Ë0ï€õ1äC½¿è+ÃþVðŸªÉ7)Ïéêpp¸/÷½õYèu¼pÏ“yý>Ö0&×Räu¼ý$w´™M<À%Œ)¤y§ÍÞ4ë¼qêóÍú™ªõ¹ë×oÇ> ÅÌæ#Î0ÌTÜÏêÓ::£V-¨«âý‹ªÆt>*]åYæ­[·—HÕ2×Z2ïR ‰ÎL˺ìcÆØË´uUîñÓûHî,ÍsOˆho4âL*eãÇéÂ@QFg+€y,‹^HSóÉï¬2Íuè:ŸèºÞQŒÈwŽw¸K;¯ÇÕ.®•žK[ ù2_hÖy ‡VŒ;q¨g>ûÅ+EךÝy˜$Rb*8‚Ú“Y8¹DE†bò”²)¹jÕ)d¿Emò­©!ž‘8_OÅËÖñ6¦&¦›H²sénkjî­psVÍ×ÝiÆ×G-ëÌË*a箜½¦;€Õhª*Äîð$—¦Þ h¯}³Ý‹²KÒß(|{È!JAU‚Þß1rÒiÝ·øzÌØèÍ hAÜŒ÷$§Ô'Á¿ŸÊ»¼1u|=s%u—WÍÈ ò¢ÿ.E”) ZFÓðGÏHV¬Àüô´@nZI¦Å‘ÌŦ"j`“ìͼEÖ­&•©mH ¾EAÐM¢$Ãú‡Y@+5uïj{Ò ymiø}'4,Ä0ßU*fZ®öõî;þâ³uVü#ýb µ-W¬Ö´0©¬aÖ•¢’F`“î¥*)«#·økáîÆài«Ø/Ïló,Á’U­ãþs¡ØuDË6R›s¬3Ÿš›OÏ÷;±´©VjúFkI^oÙáDóä̸ñ¤kLà2ÛlvoŠ<ùªøê“OÁËÔ³!ÂÃ…å–f¡¶½¾94, OÏãäÉò†Õ²ÝŠîi#F¯E*Þôskgã6Q Ðv³@RÖ¿Êí Ð ¬P†–sóÄ´óÜÑËZñ]S+ô $õX¶>ZÒ°@\ŸFk@Prâ:Ëz¸Äáý­Ly}Wess[‡i%ƒjf,ÿ#ãçY˨›"ë„ š¶áFo*¹Ün»J†”Gû•‘4æ>¡_Ú"‹^ ¹¼õß\ÿÝ,ZZާøÚYŸëô›è¤°Þ"jÒÇQÚ¦uÞä—R˜Ç2áFI„°#s7ù¼r·`ph+¨»?éæ>•‰dÆÙÓEY{ýË’´¯,k€¿’,q:Óm`°Æœ”ɿ١ž˜HRgnãfë®ó"‡¯CŠ(BQ‚ü/Yªök2ÉÙÔ,Šc6 ¬Ž´5ŠC28Zrþ¹¥ Hµ¬ Z¿Q €‹ˆ&f[H0e„¡‚9L‹® šÔ]Ý |h7° ii8V€å ³@­‰VJ.ÇîyO‰×@¨èJÐw½­?}¿öëùA)ì*I¦„$ü¾äÿ—×7¤G½¢?Ë=7(äcBåÉÚ(n`H/¶¬Ðæ¿`(~ÜÿßZÐû‹PÄU H%„íÛÄží§Ž6øCã—S¢Õu5Üײ¨ ¢ØHô:Ös'){TÇ“þ4¨ Õœ"I‰$½‚Udò8’Þ.x»-žµe³l±v—I%LÌ—2´pŒU±Wí‘´ûád¶Ë<{Pr[ÄŽÝ“š`f5¯O{Éiú"µf‚€Íbæ5…v" ~_"^Ó#^óþÔ‰Wéßs2 ½’ã†P¢ÌsPg”»L&;æç] ©¾Æ‹I¸—H­Ë_‚Ik³HúÄ&IÜÐUc[n¼‘ÀçŸ?·D¿G3S»ðpæœAvøýË^¬Ê¤KB®F¤Rà‹<Ÿ=•îE„%lçÀ‰ëSÖZá tBÈ„îôhÕªVÕ™q`ÚAa°ªóÛ•ÑÒØ¨ÇKÕõßúHcM?WàMô`VPUV,€¢¬V–­«þ¨¡f“Ÿ1Ÿ_aí#ûXUS Ú ”ÕOA¢|h¡)?IYmjkA³:v:&E<óÑp¢œâ\\Ã]\¦`ZGxÂî“^Òd­ÐŠBÊĪŒ«Œ¾V|©YNLj.ÝÑrõÉ£’8(Ø<’ @È=5My$“UÏÏ]!õ+ê•ØIƒ˜Ñåj¥e\R(^,`¬ ÌíŠ.#UR ¶ë^ŽºÑ7‹pÓ"ºÜ*4`ô±¥.y:´ezjH뚟7*R+KNúߥüºwÑ­³Ówü â.¼ëç5ãHUÅøõynBô\ÇÒ#‘Í"­¡ ä8J“z¯ŒšRl¯ÎÆc§¼ÌÊ­l¸[T–ú‹QŒ—vèQw¡”âÕ¬ÿ`cµ, PH>ºU\5­–\vpßãšÜ€*"7W"ta–_"fe—Ón°Å%Ÿì®²+ Í‘©5 !º,Ôµ¢Õr¢ùzq žS¾$%w,‡”*M‰“’ÓGãyë‡Ó2tR¾§¸2€Ad¨Éð8¿Á>:®ý¯DÞ˜û³ ¦ôÛã=›Ý µRežŸY¿ëåb›E…Û®]4ikÕzè®4).q¶´5a àŸþ,= l¤ZÓ'¡ª”Ð÷ÅÚí‘ú×e•Ô»B.FÆK¨æ™)PeawX!Õr¡kUÉ´êç ¦\áŠ2µ‹uã(a_⤳&H–Bö²*1D"Sš+«ïOÎàhÕØmH©ê/Õ×§ŸLI.w™ÙýR5³Ìp<öý?x3h+ûóàÜéu£™ð¹Ë«¸Lœ:ãYÝ IÁŸãq‘ã’(á·,$q@QmþÀþkž¿c SPÉᲦs´E4Ž9 t€íOË rICƇÿ@ú¬MÐð™î«Â©«ù{ÿ&Zà‚<²ÂžÉÃè•ìÊȡѢ"Ö‰ëÁÍ«c®¿R¾™ÿˆO ilóþÝGKåв¼_ão õ 3n‚Ë}èãëõvCS ù(õÜŒ­Œ„ ×!™çqN<õü«z—óŒcøñAx'Ƕ%¨în3ع“TÀC K»¤(ãêê‘6×+νQ¨¤í¶è~¾ƒü«ª¶§V`- y¶î³O-QçÛ<(8"ÖëL|$µ!FÛ«¾WJ¾¡Å†¯Õ[N:jK HÊìÄ…õ·*’WªA`*—nÒxð:nhL5l‘úæL˜¨J‹diÛ+ÐØ­·ä®R÷pø6ú·ßâø„pyµ\\.‡c«/?Í\ê¯q±ÒŸm%ØÓø=4ÖÔ¦W'•Ÿ¬uïœHkŒgײöÏÅÊeQiKù• ‘&Ôm™ ´Ïà ©Í(æ•ZfÍXÏ'à b.dÚTv$Ž´5A¡ÿRΜ+^ß¹ybÏÍDf¡oMÑÀôZ+bß9]5³ƒ:c°Ï#1G¦eÕªzjœyú )%Ì‘Ú(Q°Áö) ØK0kæ?PTäæJ÷,͹PÚ¨ýBÀÀð?~~O=7´žÚÅÀÛ&:B¡Uí¹NæsDóuçÈ¿ÇM²¯@\pšaP„LÞXpç)t”M…,r6Û9г€-WG)2£ÕuETüÀw—£¨lÕ–Çu !‚Æp¦#8ß9ê©XZTdËOÈ+ŒÄs³Ù§Þ9€ ”óYS<Š){úaÉ¡²&†‰ãX,$ê~2Q§ur WB^cT–Æo¡_Ú¸‰5omcЖ¨^fä±T•&¬ÑÒhæè&Y–ªˆÏŒ<ó¸4âj9·ZÁj"€‹Å‘ç‘篽ÓÙ£[ÒåÄ2ˆeµ’"#µ2"€¶y4*¬ÏùGÄ"K§Ýh5h:Œ ZñKXa€ÄDȤ—™¸ªQRòHû~¹­? -ø§!Û¯¬A-7©™QJš×5Ú³Ã1L;ZËŒ­ EKÿuƒ[ŒV}—\T—Õ3áøü©²ÆŠ3«ž¾Žr74åë6‚úi1Q,Ý—E:U¶rÇEõ-ù±¦)¯ãFtŽ4¥—êþO$Ñ·Œ»bQ¬ì—³e½z™ûB[N™¹ë<†Thþ¹/éH»f"­,“…šÞË<ú¬CIÅŸ#%ŠïXÕ–A ÛØ0U¦Í›ùéc vRvn¢½ÁÝz¶&™ˆ’$ e@ï1•cHÝ —ÞÀ ]«g¦õqF:á.èʲîVîW$E)®\Û_EšŠö¦‹Igg±uéû’a†BÈÒ‹aІ'<~3»XsD·U13鞎Âp:‰$š’¤>«·ÒÚÖzX»‡©í Í]`ÿšçÐ{pÉ- ÿW“‘„øäA ­è$ÒYZåúO1”‡ÙkY´nU©ýZi`mvbKùz ¶³.E 8ÛG!®ÉWÏf\‰Ö`-0**›ÐtZ1x­…˜Û)“Ù­§™©¦ü€Wn2*ˆãñÃ) 9¾w_=÷‡ÖgÌi°{_v. –ˆê2•9“+ s Š5oÉ æÅ®nçò/5} uûN¶,“{ˆÏ ~{æ~Ê•K§ÓÓF=-ŠBµ@ðǪ(=ØÒ°Þ.d]C©´¦Lž£5®|}UÿUŒ»‹ËEN…÷¹‚°ÊI:7*¹—n ÍXøePÙ|ò2WØ*¬‰›Iե̲€¦kì]®±k Ð×Ì)ºÉÛºD 72ÃB¥ôs0’ ‹ ÖüuqïºLÖ%ºx/µþv‹<‹A?K°#º:‚18SìhR5$ã$2…- =B»Â*X Q <zçüœùžFÊÊ–W°òO'¬ìXû˜—ãq&ɪt’þ.ÒÄÿüÂPwu·T@·e¾þr] Mk2wDYýK.2‘¸’ÚÏf 9ÊçÒGÞÄv Ì].“ õϵZªìèsh²K-weöËTFCÄÕ£5Zä'– ‘¤AçÉ^]{EP²¸‰RѬ4¯øŒ½1SDÇpˆ\M“üoš°á¥œÕ[Z—ê|¿ž\ï¼7 `¹Ë˪íËF§BöŠÉB¹Ù$Íf¦„ØÛ®õ¾. ’5cÖ UÍmf@øxùÕ<º‹ÅGÖcBÉ¥oéT>hžHòG<ôÓG%,öÄ«¹*‹õ*­Ë:áÐ¥3~«Q76]Å ŸB£‹ +],ÚÛ81¨¤ pJaä7Í!m·Ãœ ÌáÿØü5ÊU_H+–µcUÆÜY«"€%4 ùóÌò«&Âíq|sDEàbª£a©<»s& ªƒ,*U1èIþŨî|Ê%("jÂö¢÷Óéç…˜ÚEÅœšŸèú¸œ¾ÒÕ‚f]í hÏ×&2¥unÅe+´ë;.*œu`ÉØ6 *+*H0&À­¤¢(ü_’8$E‡2l™„8ŸñJxˆFÉ5@±uÛÍ_jŽEò:GC‰g,aÓèôó³yeÞ¢¶èÕÜÉÝOûP¯_ŽRõÁÑÐÌ`+Tô”t:¨Ô-é.,‹ý•bïôÌþGy®AvTæ]¢³³ó—[r&3µ H&vkM(ÉU9ÒØüÛ{ZC6½‘úÃg®qr½IJEF®VoÅ<¥W¡‹4G=pˆ±§æX.‰O£ªcTÖýì²z³H(hÇ›GÆdÇjhKR+i’’Ÿu…2ÕjÙmH ÆÅªsÞ°+›ô\gI‘}+„#,¨Q¨²¢”€9óÁ¡Çžy4ÂÆh‡©–þ¬ç€¢½ȯ ÀbÀ£ãàœÔÅÐ,RÔÎ~Å,ð $’} µ-CEIµfð1 áà˜ "Öm]\fJR*Uþ“™RZÈ«K‰‰3 Ú öVÓÿAácIzX6*²½*-’8Ì?ÊY˜ujå­ObS=I v¨_sßà¾òµ¾ù æÕ½ò2¼´[Øk¿òÔtбõ/j •=‰@Ôž÷=#‚üXtª1„E½cjºRdàSC6;¼Ñï íqâö–"Á Päž­Rv[,Q…m"¶ñÇッÿ¨ë<õ_z7æXÆH0®=Áe,#ý•ZÒë5vH ®¯H—ÓDW­ =úXþV:.ÏÈ\²2Õu'œÊ3ô£o.\ö“ kôÖâ?Ä Q‚¡fðsF˜èZ{>ywËËÓ]³]tYi¬ƒ94éΩå{^U[ÿrs¥ù eÆ?ŽˆÞÃñL˜»OSO>,3®phŒŽhÿÖÈÖl6) â×÷Ms4j÷˜›&:&‰ DzßÓéuý52_#0¤åž9`r§o[…$xà’:(í¾êÌí̘åÂeûwtiñ˜Yr— ¥ŠîÚÊH#:ì ÖŸqüÓég´é°L>­‡‹³x-§ú%›þ½Md_­gõU; ¬âà39©ˬfXÎ+-ǯQ•¡Ík9¥C_5‹ ¥K û™UÍ[@äA'ÕaØÆXó6«µ:ŒªÁâÑpž"þY»œ?3áŽ×Ä™}Ð+ϧWa^‘üí]$›¿ÔèS8ÙÝâÙþÙU]Ù›7 G,«Z*"¢±*¿´SÉHêzŽÃS dºW{L"AÌüô‹o`f.:Yæ}Q ‹žìØ@V¦)‰{’ÙÅÙyÑçbˆtùf–T¦t`¤Ä€™¿¬±6ð@V§ ïêfƒÝqhÓè/‘Ÿ«G§$8ðä³ O$J A„‘NË SXsÇJ^8ásö¾[3sýŸ Yع¯s¶Üë7êDL ŸÊÆÐtqðÙXŽC±*:¡–ÓÁMf®‡õ§Q]÷ZÂæVtè,LPÈL\ìÕB'?—IDaH±ó”|~uÙ)¯ó;FYÓiM܆üÎlg¼ÞO6è¶~N…Tö•ÂÓˆ¦.¡ÇX 2iz5ýéåô^e,±/'Íz ´²ŽcÚoZDÜ3“œÁ MÿØ“SØRË7ipŒ¬4±FKѦYTåJÙò;ϸ[Ux#9«é?ðñ>ÖI…w*§ÕR@µb6Wãžš?F»+&,\¼Œí'OË,‹VlD4ñ=ZF¯MClöéƒýx×Qù°u/`Ÿ:‚•€~}EDm …D;habðƒÓž…z5Ę“‘Š/†4Îibåa’‰ˆÑR¦;6,=WêuïºéÐa(ÝþÕ‹Sæa"Ë€hcËd“}¥è¿Úÿ;ÆÄ¬Q°Æ^¢:#/Xg:ÛK2ÐÚKA:%"íÐP ž®¥••,²å˜wçqÀP åBMn¬ƒÀ®ã¬hWª5\×u çÃõ®µ®¾‰sßø =~rÕ60`,7w€.ˆª“ç uÓ=½ †P eôÕZÙWé îBÍ`›ñÉoÈŽ{8™zT5®•ÝÍZ j£ùQõ,R],éúZ[<ípå­ ZØD¤ É 6:ú/, ’gcl±û/&«¤©Q@i†ŠÆjÊßHD¹Ij bR˜²‚±¨2ÎZ œ¾2 1X – M«ô5¡Mš!¬Ën¸a>Mr&IÏ£¤øÄX_næ€SŸªÏ5oÛ£F€Æ‘–CI,šÑ,û°"¸W°¶dgšŸJŽf®ØL²ç³ëB²†dìmW'°:…V—®ÂñþPy~Üü/;ƒéÎÜr·øÖ?ìz ÒYHðoªâ ÆêTµRy”F§o–fHpT=EÉ0,¢lž×ÖMœ¿Õ¢Že>7]‰bsˆärÊäu!Â}=§ý9ŽïuÏÆªœòi<–·t¶Ã\RÃÎnÚ9Jbë šPÙ35̾’ui=;ŒKQî…Ñq¡ÕÊ?QR•"`ªÓHÊw…·d£|‹*íW°;é~ ½÷¨æg ÑdYð±22b-™©Y“OÇSŽ­4™ 0W#Ò2 $Ý[O$ô䓼é wIª‘èš-PZ ±ÌªK(յYt&ª…˰Ù6N~¡´Æ É¡$õ3„eëz5{dÉûÈÈ’-´ ±x|Mkf³óÈ(äÙä½ËÑl ›?œ–Õ3uBî¬~™-¯×M©{[3cy,ŽEj5¦îÏIµl` ΃BêõŽd[D -‘a’ll^±òžÌ#‡ÎR—µßn·!lp¤Ãd”»Ÿ± KŽ…¶éLáŽK>´nßÇÒ0ñ´üpQc‰YcfHä˜íx†i $’¥Pæžï_©¹½ÙÜ9Úî°%y2æs-$J¸ðn%‘Ê¢Aí mÙ‹x'6ÿ!ÿT']–õý2ðñ=Ad©bß ‘[ÔHËgÍm|äA3et>™b¿¸µeKNðÏ×WЉoì=-bRì1&s¡ÉòÖFÇÈQ]]&'TžýfðY:9j±^™Ñ EÁ.¼Å?w<ž7ñç8î='GG5 bb¡žeñEåœU5ÜÑ8ÔwCjÊÉnÚÕ3Š’í jhŸE]öóƒË|rÄ5:3 ŸÀ®U p‘¯õŠpÇ›`Iñ,ÏÆ÷ oR¬²+7ϲRÔ`ÁÝXªÒ“¹XŠ­ÛC×f…žy¿“×Jv§ÓEîãÌqáÁ²m ÆV¢¼H!€G“wê+ù¨òW’¹«sÞ¹µ¼[‡³ŽLíî¹™CÔP±TU[bõÁG4®(ÖŽ_Awù—ç5À%Ž\²¯–ñ)g¤_SKs[¡×.Ю®ÆžÛï% NÀð6 "¸`JÚR­ýUºöÏI¯Ö˜i\jcÂHŒ#3e=ÔE/zš´¢§¾Ê§ƒÉÄ„ Ù!)¢÷иËO§õ}ð½bÛ9Ȭî^qUrÅRƳ]ltòµÉ0+5îþIjÅW‚10+o´¥l‰¥Üò’ÕEÛr¨%lŠ¢¾9øþý?4.ÌÑ´XbLÆÕµi‘@›ŽZJ²,p¾Ô£Ê“ÏI@Aóh³§@ J#¬÷“+ãWé/Kç -S£W  V˜?ì’Ð)Ãì«êíƒ78vDàueªä’ªïSEBÂãlT¦Ú­þCoý´ ¥0HïJ£™¹¥Å”u»N±¤S\¤Wîm1³EØü°ÒšÆ…̓W¬˜ÎäjõŒÏÒ¤ÿûú|`еíšÐ Âf™«5³ÆûXcT'X“jÜ23‹iŠÅey¥dA)†ÉâŶ,ìdr RÛ†7|sþþ>çö®¯_½(ä%ÚÀ»«/]ù—»aŠ2ÉØça!j‚£p¶*k<'´’ÓÓ gÖ‘ôIzGöm³ÚmWµSºìݺ-b€KÔbú­rKé=Oqê\VÃ’¸ñÿÅtqçJ€‰.±RÃY‘ˆÒØÑ­ØcòÃY[R†”ˆ@WGTðKè67–×eÉ¢ylð|qÇý(õa A‹'§è¤ÖTí³a€$ññ_·}[3W²k_:Ç.„ Ïο#Ð&ÒU©º§²æ…qmZU4qU€ã,°”ë߆ÚNå+`@Hç2ê¦)z¾k1D¨Ñ „a¥uB’I®‹”c(oB:³Ô®uõµÐM·ºÚÆC©Ò}¶›%†ß@Ú¢*S k#F¼úƒlÁNlÇÔû„VŸqÅfÖ¡ãÖTÿkÑôéì¿u1è ðùenÅ0‚\Š…*¥!Šè|éýËÀ¶¦«û×-êîÛf31giv¦Gs¾D±Í.#,S JÆ@  Ð¯‚A›éWõ[ê¦Ó÷‡KÆÓPÖ²q›'>Žp “Ô–Y­žGR«P…BÜÔ‹|j³Œ²x.òë‹[TÂ3césÔ.~F~~:åÕ\ 8©²3Ö{jéÒšàb5V}‰Ì¥C£j@û¸ä]e’Û?m"CE @»ÍÞµ³ï7¦Gȧ<ò–o©ÖL¾’àO;-Ù4Èÿf ç\~5^Í­kÜdxn¤¸˜2â¡, 9œO‹¿ÖÆe_µË VŒÒÉ‘ÝE´ÚTôqö^4¸™ÈÇM³FH`ت7I–GjP^¦ÐnQz"}B¸Eæ »¶ÔË=ó!é¥hZ~…`ãCBNá Ï4›”†iwpª}À,Š6^÷_ÔNèïM]3µ½fiሃaEÅÅV"ÓmH¶©³"9êÜŸç÷Çz'\âÒÃT+€6l¦yxتÐYå‹…-œmŒˆµ‰”;¯°vS.¹wrüÕ»•£¡oZÂ)£sšSçúi_7Có般Dv~ð0gw>ÀWAWŠTV·;þ`*áš'䎞vUJ/z•ÝWfjÜÚÄ«=ïv[Ö^¥§ó,òèØª—2줵T%µ,û(mBÕ¨D§6³CUfŽ]£n´*9&£CÎ #ý±ÊOcD‡‚+©Œ…Xã*Y·0i ‚SEhºV®, ²H$ëPf‰X>å Áª3O=GW?›UÖ©y­ÖaFM•³öê¶b ºÉèèØe•P²pç‚— ’¡›­a£±œ5S-r³„ÊnŸÓF´ )ÓK:–†á•2®”h>’_;lª©ª6¶V sRjÌ\k4Æ‘KPÄæ™¶Ž#Ûy§Òú›pim4ª¥°”I-Ú~uê*Lô™ŽÎ[Ìív™ôü¤Ê^À‡N‡‘üŽŠ¬|ûþ½ƒ•„äÛqØ]°,,«©BRå+u"h¥ýr…‡æOjÜYõGTUWlhÖ}ÅÖS mÖMl*ÒM†êž}b›nèÃZÊ ~‚B¸‘È ù¯À­T„ãEÃ+äV‹cf–Á¸@¿ÝZèJF‚C_âÑÕ{LçôX-åÏ­;¹bøÌçëvè<µÅH»Z&lU{¯J"XÒ—“49UÍSJAv6©u3P@öÒe(»*›ÿÕÝŠŒ»™n§Rãyœj+a~jFd•Ü¡T+C@xÄÏ–6lÙ”3,]ECœÞZàÀòW¨^ÏŸØêxNI.{<ÒèûWƒ‹¾÷ymYή‚úÔÜÍs= {JÈQ\Œ¤–VÍP:'Ô%ôñR:À‹ 4‚×p"”.÷P`H®(_#­#?WÎle’$E@Ó?¨ì#Œ:Û0Ä\› µ[‚n¶Ž'r¿}žw'?{¬ÑŒæ?¾D êòÜùK˜?<è--—sc> >> endobj 3564 0 obj << /D [3562 0 R /XYZ 89 721 null] >> endobj 1230 0 obj << /D [3562 0 R /XYZ 90 690.045 null] >> endobj 3561 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /XObject << /Im34 3560 0 R >> /ProcSet [ /PDF /Text /ImageC ] >> endobj 3569 0 obj << /Length 1434 /Filter /FlateDecode >> stream xÚ•XKoÜ6¾ûWìQB² I‰zäPÀmÚÀ)àé9$AAK\/Q­(èÇÿ>3|h¥]ÙF.ÖpÈÎ ¿ùÈ5ÙÜoÈæýqßßwWoþÊȆ‘(Mßìö›‚lR£8e›]µù\‡Œm+›Jý·ŒÐ|Û}°fI”åE3²Ù&E”ÓØZ}’{Ù…4dSJkÖŠn˜,‹¨HYê 9r’ZÃÝAõá6¦4(! D;€3özÝÔ(9V··šá ­bèíûV_Éòà»*ÝtÁ‘à;þ±þI`Ã]„KïGUÉ(„ìŒWh§—óv•.Ç£l¶˜2&IiTpn“Ä teIã@Üéq@‘ÙèQ÷Ç«WV¨Õ]'ºG;(kÑ÷²£RÖê î'J6tÓá±¢ðéýì“»){Ø ø‰ÄI1%‚ö&ô¿’ª]"/Åü+,,¦ªâ,æ•*ˆº×6~1&šDq‚€5pŠY”94]G4ÜRBHðn†‡Fq”.ㄳ%$‹Xšù0wµ(ÿw¢þñÚJÂ~_lî½’}Ù©ÖU _ a²®ž·ê¡ÆNMuÒ½Sv~¶ïu©`±[ô †ƒ•¤(G»Xî5+›9 _6–E)O¦ºM•Û¦¤–%\d½Ž4ÒÜw6vIšNê’dÞN£/£3 Š£hÄ=¦ŠJá”ÂKÕ•c-:g2Œ{ÌaÌy€›“àf° ¬Ë,huß«»Ú4h«ÆÆk>®¥G¿l±Ü8ý]‰E8³]|ÛéVvÃc˜šÀ<,Ý@úI3jœV‚ù9ð§ œD1øO#’» Ÿã l3¥…¢þgãÆ¸¶sãÊ{Ó¾c Î(t3øõ(í¼ ¾ÑUÛRW‚° kˆzNܺ½Óœá,¿É =ø}±EYaaõ…%f°È@î6G€Ók~YÐÉ¡SÒ± Ê•óØwúh+5xŒï›ï^¯J%q'zßc§šû3ûó#(;)N,ÐÀúÙþã§þc/õßS$ót'fÅÔŠ•xaxÀswyY<:hN«šA‰Zù<™ôSEK ô%q¾„ðWÆøÑo9áa“³­’E}“`PG¼ªcÿè£_¢›~èÆrÐ]o5øZ0ËnÉ»Éëͱ­Þ\VìǶÕÝ`F¬”Óûz›pÊÓÅbèa—GIZ,¡wƒ!Ps}šr‚8‹Ó*ìÑ€`›Þc/ÍÂ|ñ)[VÄŒçÅÅ)Jêú¾½t.ÍÙâfÞzÞþ ˜·? Ê\0Ö•Z<ZœÂÓ1Éàè&R¥æ¹aºÊ°_´¨È Ý—øeê:xUö§ ²³.‚ÕË­g»U r9‹Á‘ŽGÒÔ€¾1èŒN~ùÂI²ˆã¥QD”²çnœyä+\·¥ƒÎÏ.)/~‰òžy!½ôüp„§ç„C9wMŠ B@3G ŠºÖ¸àÁ†T–"=)MÎÓe­`ìs3Èåéz§}\Ý…éÊ5vâ@ZLGÍ@D’1*K2(:øövdÃ0(LCš!†¬zF ¨˜Ñ•wضµ2w8îoŽqÕÜå>7nÞ·oÿ½ý;ŒIð1Œyðùvõ·Ãìî™ÖÙƒy•¢²"" ó\r«Ý?:Y­ÞÐ[gwÚä%жº®ñ¥ð"Bgï•fýfu=«¤ÿEàxv#û-­vlœú¿Ê[·¸ÀïüÏ Õœ¹ßk¿ïiÏéá2’D„åæ4qÿ ]¬úswõ/àU_ endstream endobj 3568 0 obj << /Type /Page /Contents 3569 0 R /Resources 3567 0 R /MediaBox [0 0 612 792] /Parent 3540 0 R /Annots [ 3565 0 R 3566 0 R ] >> endobj 3565 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [265.096 490.673 272.07 499.649] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3566 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [126.632 478.717 133.606 487.694] /A << /S /GoTo /D (cite.TANGO_ref_man) >> >> endobj 3570 0 obj << /D [3568 0 R /XYZ 89 721 null] >> endobj 1234 0 obj << /D [3568 0 R /XYZ 90 690.045 null] >> endobj 1238 0 obj << /D [3568 0 R /XYZ 90 463.521 null] >> endobj 1242 0 obj << /D [3568 0 R /XYZ 90 408.943 null] >> endobj 1246 0 obj << /D [3568 0 R /XYZ 90 306.523 null] >> endobj 1250 0 obj << /D [3568 0 R /XYZ 90 171.117 null] >> endobj 1254 0 obj << /D [3568 0 R /XYZ 90 102.91 null] >> endobj 3567 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3573 0 obj << /Length 2948 /Filter /FlateDecode >> stream xÚµZÝsÛ6÷_ÁéËQ31ƒ/‚ä½¥©s“N“É%~¸›´ã¡DÊâ$º$W÷×ß. švíP}±°øa¿Š· þqñãõÅëw‰ ²(ÓB×ë cAÂÒˆ©8¸.‚¯á›OŸ®>þôþ_‹K³ðM´¸Œ ?_½»ú|õñí‘?-2¾ù¼Ð,¼^üvýóëw±ðTÈ0Ö°£aÉ3“.˜qu}ñû‡& xÀc%2 tÊ"‘ò`µ»øú ü9`‘ÌÒàÞLÝ"Í¢Xhoƒ/ÿü+˜d2 ´N#.’§˜Àteqly©zàI &ð(áŠäð©©ïʦ;’ ÷ù®4bñÄ!â$JUv"S‘à‰âÎѶ d*")øY@È4,ð@åzÁY˜¶áø¶q˜o`”ÒÓâ;ÀL؇N¢L¤3LÇQ,“™FËÄ<ÓȈF^ÀSgV¿õv{ÓTûÛ›¢¼ë6OXØð7žÆ>‚O€ö'Å.‚…‡5ªw]6D{Xoug¦XV\œ=a\/ÞsÂ.€OåLãšËÄ—âÙ<ãÒ*Å*inSÃjWÜ<߼΀Ah8©ôA¼ÝdEwsÍìÅ'Ìf^ãŠEéÓ<ža6s™³i¤“x¦ÙèH!/)"2:Ë»®y圆€lÃ3åÃx0Îd;/†8a;3xôj*Ñ3mg.c;\ÉÌËgŒXs ±tÏêmqCê«›'Lç (”n1ÔŠ~Ê»œL£«kj¨¨õ´ÞdÎMÁxÂFÐÔYíÅ{NXðàBÌ4±¹LŒ‰1 ’Hgš˜‚ô q%QÛjtWí):Aa\ÕÅæu"ˆÄbÁ‡j_íû‰àô¤Þ¬^ iÂLfðè5 <=·²žËÍ$Î8T jfƒ* *Ž8‹AYüTþ<ÛTÎB@ Æ é¡S;¹äÓvBᨶY ?n9/GøÐræðpJGŠÇó,g6c9 \ôLÉ#%k BNU2(žo9óQ@‘iå£x‰á â',ç¥' çûYô*LÏ|0ú&î‹ ŸÔ|#`*ʈ_èH§Vü×›d«zrVÖk¢tK—Èftð`Sª–¨õrÁãð[UZÔª–áûŽFŠòWÆÄ¾liAçö=iAØVv"õ-ßnGÈŠËãoÕÊ<ЗœNxit¤O•Z –Ä3ˆ<õn—ï‹_YÌZøÃ‰ Ûûª¨îîÊ~DÀàGÚ ÏçÞ”Û²m_Ááý¦Ü<£=v Plô§Äθ²GÚ·*-!V7îv‹â÷"@s<:³‡¶×Q3bË”cÔßvçD"Á5»²ÛÔO2VWõa[Ps‰ ÈâÄp·>½µ«é¿Ó5õÚ»rU!aEk †ª¡o•nÖ‘Ò¡IJ‡ÑÜí½»œ:èÎ(OÂ9Ü‘¥P Q¢ŠºŒ¥«GƒÅô_‘Ø‘@~€$ô¤Ø!5ùÐ@Û5}£4S¬»T%øÅÄ1Þ¡Yú$,óÕ†ZÎv¥ÐàZÿ)WÑï«ÎÎ ×­0òÄN¿¿6Ò±ÖOcn³"B¥+íN ;÷]þ‡Å°&Zgå7 ØêÄá,+18§wfC]ä-ñžŽ*Âå‘þÛ…Üš’ú# s¤ÊNøÒå]ùJ°WØ8´¯xì´ ¨ß¯iR½w8Ö=ÿÖ28釆ªÖíG¦ ¾0<™-d¥‰‹H‰¯‘è°—9ºÙžÌ1†¤’œ,AÕoÂÙ&”R¼¹oª®me§Á“nóÒ2Azs†pÀÖëNÇ!F댛t0¡Á©Û.däÌ{¶Ï0@“"[êÓöÐ8´¥]`Bþ?˜ð§á†–y[S0X[Ø+n6åªnв ^µMÔÙÄë ÀkìL+¹ª˜ôÅ+ã~B‚ø*´Q!Ó°­©•88@#v@jʼ Öº©w4H¨ä0¿u„J±µÿrš¼Ú”«ÿRÓdTXR«EʲìîKL4Àc1R2¸7Àޗͤf2MR’iâ¸'é}2!S˜`m{°ÄJz@ÃAk *ó÷8;ê[_´rcʸ®Ç Úweã,ß,4‚‚‘[PCç`uH†"6EŒb& ¸Âv‡mWÝm4²´ÿ->ø:D,×£ñI¯Á§¾ñ=Œ¸Ü&--ÑåÿXŸVµ%™h›²;4{&q£úñ#ª4\;‚iLÔhDj§©=/С£vn±Ç™HV/Ðé(Ë£·>¡Óbý7¶pg·<ù­ø­v ™aŽæVº×Q¬³>`££÷ût, 7Ðßä-ÍÊm¿ºÝ˜€ˆ¡@ñØC7YftˆqlxP"˜.œ~$1~LÇOœlsˆØ¼ä4vÀÄú´ÕçìîÊ}ÿ ;×*ݪu ì‚?y«¦RÏ{ ðî^4I¼uFtBøbÆ! ¨b šb má*.h\/R|P¸­iŠ+;°‚¤Ñ'MU0!ä·¥Çb`ADÅê2¢„oíA/ã<|ùpŽãdõwïwN§o¡—ø¹F¸p!DìÏúj~aEÉ_!Üg&§Ÿ˜ÕÿzM—ƒ_Ñg¨õhh˜@œŽœ¶]hô0‹P? aÞEýk ú±b蟈r_ïoòCWßx2UÙ`åî5а€¡åÂév ûMe..0JzÎÃåÆÃ ±Ÿ hˆg—w½­¤‘ÒÙ(Byt‰ ¶i-•êùÎ?ø¥ãøâ± e¤PžeCù°þ¡¬—#…"…²±Ò̘“³R*,#% .í¼^JÈÆJ‰„1–”viê™â @òQÆ_,ÿ^p ðJ”PxëûÛ‚§x9Âî&Ç3P…M” þ_A@¿u4 ؆.ì÷WÛǸ¥€t„¸×–Û5˜Tšƒ{i’‰¦áŸö5·­âõ®.ªËéúƒ /ÊmÙ9ZZKIãý.PÙ Ñ7÷Ø.ðùø‹4йý¾ü&âQ ªb Ÿëó¡oëÛ[ ¥ ŠhÓH§ÃWðLxÈ ðûÅ®7c_àâIœa³ùõ/®‚Ñ÷LøQ$óŸ–p¼³ÌWõ¾kêíô¢ípgcZð¿íò¦;Ü´BƒÀîQEÜšo“¶¶À¯-×§<ýhr.ÊvþãÔWíG~*‘N¹:_Nýt“ƒ©'J*5_™Ÿø®!µ%«©#gâ‘)3"żojBGÀ.Y¤eòüŸÒòŒE:IÎAH{žõCZTz2)ľ^ô3ÚT†ï€òÐ.d¥O³ÛÅø›Ùÿ2‹U endstream endobj 3572 0 obj << /Type /Page /Contents 3573 0 R /Resources 3571 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R >> endobj 3574 0 obj << /D [3572 0 R /XYZ 89 721 null] >> endobj 3575 0 obj << /D [3572 0 R /XYZ 90 690.045 null] >> endobj 1258 0 obj << /D [3572 0 R /XYZ 90 123.409 null] >> endobj 3576 0 obj << /D [3572 0 R /XYZ 90 48.404 null] >> endobj 3571 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3581 0 obj << /Length 2791 /Filter /FlateDecode >> stream xÚ­YëoÛ8ÿž¿BÈ—“q5ÇžÁÝÙmÒí^7é¥9ô€¶[±…êá“äf³ýÎpHɲoS0 r8‡¿yæÎÂáΛ£ŸnŽN.BωYÈÀ¹¹wbî„!À.XìûF†6È@y!A†Y¡`!¬¦·W‹EV.nót"}÷ÛDønšëM 7s„á‹è!¹dfS·eÖfIN§0'e²YJ}£¤éì×TIÐÔ‹^DS…Lª-M?N„ü\_î®íE àñ#kÀ&Y,£‡Í‹ÑØó}†ê@ìL¡B~ÌT0„^›Ô¹‹´Ýƒ»ÐAr”å tø~ØíÓ²ÃÜ h© \„*hyYYï'‚»É:o÷€ïÙJŒàdø`ªÃÀw¨ >O1ø„=%Yù{!ã| |õý>Ô½ÀâqÀ"_ · ¬ºÊó®ó™s™øµË:m–U>߸ÃT¡dÜRPrRá·Ãìbâ» îÛ´Ùƒ½çê3‚!åÈ;P†žŒÁQ/f\€Y”ÇÁy«¤]îÞ ,/¥€  —`onãútH{}””7Ôç¤-V'mR.ªé?·LŠô_Ô¬ê={¶b#g _!Äɰv€ŒÎÈÏ–1bdÈ´‘ô@‚_Ç!ùçÓ¿2ñgîó»Y9¯0 >4@{ì~ˆÍ¬ŸŠˆÅâPg¾[¯oG<˜ÌS‘ãûÎeÚšŸ¥ôu¿óIß%n–èJ^øDQ C»ª«UZ·Ä8«ÊâC½–æp¶*酙ήÄꞆúôE ÜpÝ·mCŒ ”.šÅÎXUM“ÝåfÑo8/ÉשÑ&kNq“Nļ v¦æ(µޝ..Ž_[¬Üã‹Iè¹gÀ\™€pöކ¤{|~}ººî˜»â¹ãy{yqu íÈC7×ßã×ç?aóß7ǰOH°ìd*Ül"\T.ò7ͲÆ@»qê‡:kÛ´¤;ÈÆ=ñá~Ì”»ª1±pVERÎM˜•†\­Ú¬*{‡™~CaC,L­ÁEÒÿÄ(hä°µ ÷g ÍaU¬96vÇzÇHM¨[@E˜M»œMA¬%€,„ŽÚP–E›¦n,‹ƒyÖ´x~äž'³%1¥€ÚǧÀQ¬œ+#w™Là°É¸H±‡¡{(z(Ì´a쾪‹¤=¥e{5nÛÇUzzºAÀ¨ESð –im„nM"¢ÆðV¥!hôoêÒ¬W«ªnÓù¦Úf`”.iCÝ^¡‘"kßÐ5úÆÆñ`f7ÔÏ$ ¹û¡Óg‹gWƒ:=5¯j3@Á뇑}¥€ƒoª<yÎP‚[÷šñjDTð² ¦ZØ•#|&:.4Ë® ©‚¼òpˆ•¹®/õkWªô™Œ}+VG³Ð½À :Px„~O ïmÐï-†AÆ“î.x€ËàÔãÖ3Ì䥷œÜÄKAËék!õѰë"­Ç´ ‘4v mWˆMÍΦ€õ1@Pv«5®u¨aàž±x+‚¸3*æfVÔ3 ûâHC“DjÄ$aH¾Z|†tC“eBë5@襱"YFP¯’Ͻ™^`4žoÉèMö·‰ïëØn‰ÒZ»8r× ¹FDëB´¸Ã8³ÎrK&÷Šz¡m½0Ö3¯ 8ñ[ºNYþx[¤Å%¨Á`;zîEV&yþ8 |=[ˆÛÅQ§]¶(«šŒuÆ*MDO=³„rŽG†oB뵺ӯˆv•Ò”0róî6”;¯tTRYµÔ¨SŒ#Fj‰y¤NZ×+¸êl¶®I_è=,³nÉúÑÔ‰Ù¾PA¬W†d°Ùcdo½ÖÍ0Gž\„|3|М)\Wb¸-ÙŒlÍݲ±áÝîK]iú=k~OŠ•½ñœZ¥¥‚…Å“¯RšùŸôùDŸcs<ºŒÁ>Am«{zz²¬Šô…¬ÑqödHrp‚±qüe š}«‚)Â[c Z”*s@„!è?dX[äÔIÖ-¿ÍfÑšëiú”ƒ¨ÕÀažÔsêUëvµnír†7k»lÿ4¥ ïé6æél¶|Ê­–§`)Øš.O°Ò;¢À”¿Ç_Ñ;C®USTãL«¶Ñ[ç4º}Ä Sº^ë±YÒZvŠÎÛªÛÓE§ņ‘‚žpÒ'Ÿj%µ!%ycžù¨¯Ì|CIºY¶>í2ψp³M-À"j»H…Ô¯¢`ÇçöT©G7Í€ 6 ‡›U:ËÐÞiCíؽq!µ?¹ñÆ¥»nO3 ¼CŒ)ÍÞÍ4ÑÊTð3õ£65O•«ô)04ÁbcM[ºB€ï¿ïðR£¯t?.ÓrÕB·Éþ0-›4MBîÒcŸ;#ÒPV§Í¶ŒjŠ>j—6ö›ÒÄéàep”CÊ®ô-9-í nCÉìëzE²!344z1t`en¡ø­JŒ­PïÒIdqjwP…vÒcBÝ6+RËäóŒa` ¡àè’72áZF5®:%æiÓÖúŒu C¶®X£E9­±èCQ‘ǽÆÜ^<ãC¶PŠ{™‡¹ ¯TçC1øÐŒßßîÐߥêU) °(ÖÅ&{äB4"ø þRÀæO–WEò;IÁ`˜™+8·ïÛÆ•»À‹X_u²q|ûi=é­@o'—o®nß]½¹¥ÿ¡éQå’qtý–ÕUYè3ÂYt寳ä.G°ÈXP°ÓƒO„¾YbÞ2±ú}ß&£Õ*Ϻ$2ÌB¯?¤µÙ‰ÉFyÒ4㩨{DY&†£4Â#ÀyŸÎZ«ƒù¢Gm £úQ—àœ©¥¾SJOx¥TŠÒ<Î1 »‡v_÷—KÒ¥m댮 íX°ÂjK2˜7Ó³ûTrar5×7?tŠÅš*g.¡ÌÂsDZöÁ_QçkV €²Jj?mZ7§ô”õµìˆÄ¼„ªk:«æ$]PêoS­ëY§Ã<%n22Šj®ó/¢aÌúµ{sêai÷1ßV`H&Œ)ÙÔ‡NfiÍß Ãµ¶M-"˜•>lñai5Õõâ¼Ù\e¹¶‚©Zoö+5òUÌ„þƒqïßÌ’{,ôÇžî_F„Ÿ÷bÅña“ P#ޝ˜™“8e_UïZCF°(‘^@Å%ÞõþB Hì³:£‡èÝ?g8DÂ0x¾6»g"ÂgœÌö_)è¼Cp endstream endobj 3580 0 obj << /Type /Page /Contents 3581 0 R /Resources 3579 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R /Annots [ 3578 0 R ] >> endobj 3578 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [124.416 461.765 141.073 472.669] /A << /S /GoTo /D (section.A.9) >> >> endobj 3582 0 obj << /D [3580 0 R /XYZ 89 721 null] >> endobj 1262 0 obj << /D [3580 0 R /XYZ 90 203.982 null] >> endobj 1266 0 obj << /D [3580 0 R /XYZ 90 137.257 null] >> endobj 3583 0 obj << /D [3580 0 R /XYZ 90 62.252 null] >> endobj 3579 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3586 0 obj << /Length 1283 /Filter /FlateDecode >> stream xÚ­™ÛrÚH†ïyйDŒ{Î3¹#6N%§¼Wí–7å’bSÈ+Db¿ý¶¸1º2Äã¿ÿ™¯{ OÈ—ÞçIïìÒHâ¨Ó\“É/‰¤"“)¹ë¯¯G?.¾þ ¸‚þÐ.GãÑóQñÏ×ãýá8ÐП?'ßÎ.ßÒ”™ Ò1—dNfƒzPšMzÿõ~ÂsŽ2®ˆ¶@¹eäqÑ»û dŠ¿üF€ gÉŸ|è‚pÔ(ü8'7½¿v4—Dk‹Z¦I‡3ê”*5òõ¨xçBP)5цQÃd1ƒe¸ˆò)T¬s‹Ö¥é$¬`šJëªa‡išÌýu+_ïD‚ ÚèœÔ€Ð†:nOÑ…FS)jŒðƒÉ%µÚ¢jêbQ§aÞ§o/M@;-µ°¶C×ðÌÜŸê-½“mm©† j(,~/²ž9Y‰%Æ=Áe—E °MöWœ,´­p”JVƒ7²=dên[S5`P‚s?¶~9ZÁ( ?¶¸y0ŽZ’j%Šåý“ÌÒðaÞT´]„v†rͪ¡kÈ&Q8=Ë,EGÕnkg5làNfüøzj䀙ÅóÉ¿x¥@?œSî\±Ê‹ðõ~:[Ü¿6î"¶³o•ÐWáël±^(Ë‹Z‰–«Y¼lÀÚÚN ÔPLøaõÔȱ‚¦B¹n°âÉç6×É Ö·¬]Ä.±n‡®`ýçx¬­íÔ A Ö¬ñ1VO «rO(å·´€'>0Ô2T9^ÝŽïCÜǘp '$ª&†«Uü8 ÓhZÀÝÚÃÊž}u{kûœ”Ô‚öbí«‘³¶ Ï,æùøÉ‚ k«(¶Xf[”æ•~ Yr8I­òëª0ƒ¹g²Ëö|¾—_¯†Y^|΋Ldi!XÕÃÉI‘þ ð-Ÿ”­ç²GÕeÿk }ò¢µÂîëq÷çÿ=9^ endstream endobj 3585 0 obj << /Type /Page /Contents 3586 0 R /Resources 3584 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R >> endobj 3587 0 obj << /D [3585 0 R /XYZ 89 721 null] >> endobj 1270 0 obj << /D [3585 0 R /XYZ 90 514.109 null] >> endobj 1274 0 obj << /D [3585 0 R /XYZ 90 207.718 null] >> endobj 3588 0 obj << /D [3585 0 R /XYZ 90 146.661 null] >> endobj 3584 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3591 0 obj << /Length 2554 /Filter /FlateDecode >> stream xÚµZKsÛ8¾ûWð(íÆÞ$ró&ά§f²YÇS“ª$å¢%Øb­DyI*Ž÷×oãŇHË‘É9¨D6€îFãC£»AÝE8úåäW'¯ßÇÏO©À³34?Ï.Ïߟ_žx{îÈçŠÎÎ.çÏ®æß®~}ý^ÐOn -K¢„ét‚½ nõ> ÝOi Dæõ@Äæ§ƒü«•v’7éëe¶¹þá^Ó|Ù¥?º×û´H7ºÒE9 ŽNI‚dâ똥fÕÜàÙXà Û¸Ô_1¦¹^ºæjåäl³Û8j™ýÏ“o·…#¥UUd7sŠg»J{^ÛÛ=&Ÿ>ž¿½ºœs<ûãwGq3ƒ>¿Ÿú/ç^´J]Hؤ²¦=¿:ùï ™áˆD$IPÌx$)Ì’òh±9ùò GKhü5ˆ©$z°]7¥ Æày}:ù÷_ÁDA‹$ñøèM³°8í,% ñ„€>À»µóÆÁ}[Є!Ç“h (°à] <öD3ž $¦Sˆf"FRªaÑ}Ñœp„å f=°þÀ‚Æd$ˆ`ñ’d$†0A1ã–xh—X F¨wóÄ8’»í›7ŸÞžýníiM [Ä ïê@Àg ™1Ø0V]™ønŽ–9°æÆÖ ~pÆ21ȉB ,9Æ‚p†!B">@‰¤œ¶ÿ~>S(BG"xW“?J]8?ø®>¥žÔZ@u´8¨ãeö±`xÃ<žÔh&PqŒ0IFº"pbV#Ø–=D5ÇþÓpšB§¶ÇÁi-˜cpõ-j€­Å6b‰¢Fìx&!.Æí ½ë}0GŠsʇkŸ÷s"f[o¢N” $îƒLáƒLCD—íâã(®|õÊ3]¯÷X4WZxRº.·ŽTèjW¸èYî;º¿mXd—Ù64Eú8—bfYˆÌÝLOýZ…:'lf`P”•y¡~¤¥g¥#}ŸS íôüí•ùY‘vO½Ö Þsø|hôçSòìø¿“6Öâ@¾¯§ä¡ìd¦ˆ»“‹W+äÒ”N^ý¨´§_+!âû Ñþ›u˜“d¦Óåë‡" ´êñ^?Ÿ €¸1åîþ”+C„½óXûO²®±bOÚ€R«l±jCÞtÒÂÈ«,@?ê­ó6K·×›¶°|y~ö®N}ìÖC:uXâ£eþyyqu¾'ÔÌ?½Yë¿@œ™âõÌÆ^¤~“Ýè}»Ô‰³[µAýä‘ú]\ý³V’p¯$ø¨Ô½áÞ>†¸§9tHËr»ÈÒÊzx¯¶ñ-ûÿŠnœ¢aèºÞoͶ|€ÓÄl¿qȤ:[ÐÝÂfµÔ¦ó÷l¡ÍæÇÊû>hYìŠÂn}“†ÃdÖaÈÎuáÔ6MÖ9ßV{Y¾-/¤yjž#2^†9{n]ϬÏZ‡áYit±uÂVö ¶ØPè!Ó®]HUCD&a¸Ör 1³G»¯ßÜ¡fŽskw½¼6ŠÏY<3æè;8Y¢Âhƒ´¾ǵd¡Ïƒ5Ê3l%…œ„‡!`4&¥õƒ}îpL2#ŽâgrFØ%C¥ÎH½oO*f6 ãKwÅ.,žý¹Ò¹Y2‡„k'ˆ0ùbk 2áùNhVº³ÿ,¦é,«ºMß,]<º·œÍ<óÌcÛýhþ݉ožîtuhb&ݦ ?jNm,¾ñ Y1G`æ¦ð¯Æ?ÒE|þÃ*­ÚŒxÆk {ÔÀ~¹Íò;p2Ä­?€Lá¸ë+ÝRSÞX›Ó~l†›@¡tï>š‚Pcm–ß9ŠÇ2°jâ*hËÀ!x!iø÷ 760îË-£8? ¼ËEºN ?bß Xú˜:®u~W­\G{Äsç…†\KÝ>SjcotšƒÍºÁB" Kí-âRWi¶ÖžUˆ"k–·ÛõÚùóšqëÔ­Æz®¢7×^¡pD%C„L8U³x ô??@U¤W¦à}(HG!-ÿnô@IcÈÈù$R)cHˆ®Ô³N}`âLÄ“¨À Ǫ¯‚ Ãû¹«”HŠIsHæKä ¶qÜE •x9Z!uç˜C+“Ò¹qheÀ‹^ Ì"{5Ù?Ü 4 b•Xt5  :LpµžWKæe™×GÃÓ°=Z‰ŽàaÃñŽîðG!FUãÊâÄ\8’Ä"Š'ýë€:Ø{€¨P°­Â!N!SI$ïÊü--«vFø³Xå¥u­@¸ÊL»é~[–™Oo©«ˆÂÿb» ”•hê–Nò–ÐóÈò ÔÒݨ5ŒJírvê åOÞÀ”Ûvw!÷iQ¹²–ÍçâTPýÒ ´ùû"xêgMí)/«4_øŽ¾No.[\ó¥-æÜ¹{" ÿëÖÑ/òJÚ¢¨.ß7£rÏÕÜÖh,Ùkã^òVmÄ+±Ù:ÌX´ë>0÷%$&Ü’0Þ)¦ùæÑ‘X¿2 ¤Å67cîvEZ¹Á€öf¦SûÓ6hvÕ”Ýß’2,|©óÝæÆNFØš5ú@©¦tWBztÉúîNΪ"ÍË[]ÎH[fòMb²¾ü“¡ÒÓ0Êa&Ë;,SäM%¹þRª‘ÂKzã+"‘jª¤õ‡Oûœ ´I»HL“z³Ê™×¿½Y¥ß¬²Ù¬²{c>Näˆt jfϰ²>²Òù+#Ù-l¨¡ÕÙ<5›™áÄîACu{Ð<¹M`iv¿YÚ­ï½ò„=x’[óTãÝ îÖ ›µ.½Zðö©<ójöÔz›±ðy"ë 6e¿u©îÕmSx°&¶Ž†U¯¤¤PÒã¦X.`¾ïÊut/FB÷j¥ìg¦"y¿j¼©Ÿ4»»€°¿áÁK…'÷µ'•,l- YwÐî^ê¢q9ðþàÀØî²ï1ZRý þÀÈ7º]?ôµð^Í}½×žve8ò—»¢)¢†ksô].6ÑÀ"]¯Qç^0üCdðÅü² endstream endobj 3590 0 obj << /Type /Page /Contents 3591 0 R /Resources 3589 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R >> endobj 3592 0 obj << /D [3590 0 R /XYZ 89 721 null] >> endobj 1278 0 obj << /D [3590 0 R /XYZ 90 690.045 null] >> endobj 3593 0 obj << /D [3590 0 R /XYZ 90 628.824 null] >> endobj 1282 0 obj << /D [3590 0 R /XYZ 90 485.864 null] >> endobj 3594 0 obj << /D [3590 0 R /XYZ 90 263.347 null] >> endobj 3589 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3597 0 obj << /Length 2457 /Filter /FlateDecode >> stream xÚ­[ÛrÛ8}÷W°òDMÖîò0UÞ‰²ë©©LÆëÝ*'•b$ÚV­DiH:ï×OãBŠ(Eù—ÆéîCÝ¢pôá追xó>á‘FZRÝÞGG VsÝΣ»øêãÇé‡w׿O.©Àñš\ Œã›éûéÍôÃOS×üq¢i|u3‘8¾|¾ýùÍ{A[2¹($¬hE-Í  ìALo/þ¸ PÅ1ëK…U$š­.î>ãhí?G1­¢g;jñD#IÔ—Ñ¿.~u>"ZGR*DhrLŒ&H áEXSj.‘Ò$’ A áNùé*³ÚZSš ~cYÊÂJ…Ë^Eú✵Ìò‡êq# qFFÁÀØwa¸Ã—?Ϋ/^’Ïû8fˆ16 Ž5¤ ‚]ßãòGW¶š^·Z¾<ûa]`…ÔˆÓs¸ÒU&HϦ»H°dÝØ]Ñatg ˘CHhÓÎà·…ã4X¿}{3½zw„ù#  "A2 8Ç&ûË2ÆÕ;ëÞdéÜqçÛ„Š8]>eå¾÷†ÑAÃ2 `:Qì|›ïhÈ Â Ê ¡4­‡s$‰Ø£áo®o§Gx8*`ŠB½Ÿ¦â+3ÊOD¸ò/iY9*>‹*ëÁÊÞˆ:X9@†aÇHŸ~œ•Ãæ;VRÛŠÆJèWXÉ(¢’vnŽ_¾GÍpPÆ0§bÇáÃï0YGÀ˜D”‰KǾy„ # à‚Â+ÃC½_™†î½…t…é<‘çÓ}Ø|Gw"£dQ5ˆ®®Ýl¿¾ýçw)?–†òm0çP~, åÛXúQ~œp$à ¸*Ëõl‘V™Ç’VU±ø:¡8~ª²åÙïCo¸!Ÿa:¡ôü÷¡ÿü:*Åí9ÜË1GšsБ¡„×ì~4VÁ:¾_/—kc™çEþ`šT\¥_—¾wž•30kæ:Ý@ß•V©«¥…ï/²ê©È­G¬äÂU«ôÁ¼Á9ÕÒ2¹Yº²zôã·‹”‹ÿ{Le–W®÷ëËv8¸4º$NÓKë!é4-³âÛ„ˆ83kH??f¹©Q¿ 4¨\“EeáÈ£?aë×:~p…iy.â%å~´iE5Ëy¥`”W ÚžJk6ÓûT8Ol§ÐØz«Ñ{}ýõ©ÅøYº\ºZ¾ŽØî"/_žhÿ­F œ ,Ž_H Ž Xt3zà|»Ãs nÅb”ä×pâ@yBrcŒe)ÓˆZY­eOIn`¸áq00pV¤CÜ( :sLi¤øH8`}­»lq·ÑÊo{çÝÑì€Pž4à«™ž`y6ß¹¦ˆ1Œï J9Jrƒ+³ç'=“# pM•j€óêa²_Îndh­zZj£az_<_„aPbÔ!ç3pØ|Ç@™€Gä(‰ ž˜Èú&6Æ€>G \¥n#9LÂÖe¦Ÿ$ẽc´†‘½uPr€ Ã)˜.qr>'‡ÍwœqÁFIkp¡fú¬´Æ8ê/ÀqèÌ;LÕ0ÊL’ÉI^CÏPp°‡–;(ú'5j²÷F’¦SÁÏ'û°ùŽìœ!¬õI 7_©äùI1°4„oƒéOø4„o#éGø1P€s0 AŒœÑ¨_†ÞhC2sŠÎþzÏ>=›ÁàMÔǼÿΫ…tÁ®h¬$ãõ&+Òj±Î]ÏcZºÊ×,óM0à~]¬²ùßÌsâÃn設ޒ'Z±6¼‡eù¢Z¤Kˆè箣Zûo Xp5öJâ¿-ÀŸ$ ¯¸$ H+!˜O}}7_a”¼wfN¢Ã”€ÓG±8ZeÅ"Qæ™ÇÕË&3:kÒVÃNÖ`}õa]91×^Õ2›¿êP@BœÇT¨Ìj4€…ËÊ'9 }WÓdÓ(`*lÜš¨*ÜÛºK…TB¢øº^/³45 D1MBÉ[ó½É&qà˸Üd3°2OÛVŸñ2Õ@,Øš1Ÿx2Ž_f¦ç—ilñËÊ*}Ùæ—™¶q+ä¾ti‹ãÞ5­s/$[f+›6³˜³ª‘°o]“¹…—àCÝ÷-ËZcq0S;ÆrŒs„KXC¸DYø¦ÉÚß”>+’P ß4Yø¦ÒÀ7¾ÖM §–"ß'G"“ zKˆdŸ—°¢ã¥Ñã ðÖHÔdx¹ ä4‚ ÝŠ…òU‡bp+)jÈî]„¡mZìë)„I3é•›â÷¼} wO')Á-I—Š#¸©„í©>±E‰É%Áû”²µsµN¬½ Ç›´HWY•ðMjSÁ Yç¬í» ukŽ}´[º©¤®X­bæa/_\Íêm‡…(LÓó¢z d¹)Ù~“~S¿µðl˜ºò±µu•/«ÚP¹É?Úš%M»ëT¢Waï%Ñö’ÜóÒ¾+æ‹r³Ü¦&Í>÷mB00ø•á](ˆÛqü6ø?"ˆkk˜ŸuýWPŸ(á ;ûõÿUÞX_~WæŒïÃóúŒ®ñ6 [,|wéáõ7)ß`oT‚¨j‚ÿ(Á,ý”7‡{í„<›ee™/þ+‰à¶ê~5›­‹¹©]lhKçH%[Žä8¶1?·ÞƒAmïÁcè=hø_¾õ9HZÜײ3?a7€÷IëÃîÖà–àÉ[FÖ-u8‰»Rlˆ£·þ§ñx‘„’ endstream endobj 3596 0 obj << /Type /Page /Contents 3597 0 R /Resources 3595 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R >> endobj 3598 0 obj << /D [3596 0 R /XYZ 89 721 null] >> endobj 3599 0 obj << /D [3596 0 R /XYZ 90 690.045 null] >> endobj 3600 0 obj << /D [3596 0 R /XYZ 90 507.259 null] >> endobj 1286 0 obj << /D [3596 0 R /XYZ 90 325.978 null] >> endobj 1290 0 obj << /D [3596 0 R /XYZ 90 270.874 null] >> endobj 3601 0 obj << /D [3596 0 R /XYZ 90 195.805 null] >> endobj 3595 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3604 0 obj << /Length 2238 /Filter /FlateDecode >> stream xÚ­ZÛ’Û¸}Ÿ¯`í“Tkaq'‘ÏßÍ?Ï?¾ÛâOSE'÷Ÿ§O¦>üã§w‚v0¹$6DŦÑvJ€¸Ózæ›Ïh …Ìé("(žÎùm%—S’LŠ¢¶ÿÒº.³Å”âÉ¡v òtç¾öi ßµ.âhF$+ë}=$,ÓÊô•lR7ò h(ê²ÊUÙ¿ë¢|žÐ¥\é•­)rýÆ|IÀñ­Úô@œ æõ6½×CªªXfiíáK;~hÒÓ¨bz^ª½^f`LõêdÍ”[-¨³?M É‘lê¨þP¬š®éb«Ï²ÜZ³ú.¹ót¹N\œà@Ñ&­\ù‘“e‘ÙO‡2­³"·uv ðј~)¶¿»¾ªPrÔ˰•qÜÊÕ-S‡·pOeqØ7¤‚älJ&¹ý¬7¥vMVÙzJÅd­K×!6÷‡r_TºúKo†E„".4«P×” ~›/ÍÌþEçºôNàÐB6>öÃVZX„½ß¦åÎMY½u¾û P§+ ‚οN‰˜K|x¸Äx{P‰„—Ñ8"Îí†v0Súœ-.û[ö´©_㸶Ié*v·wÃ<ä³:ó«Ú×,uÕög¥ƒ|Í–®&´DQzÔ~Ý—Å^—õ‹CHët‹…5ùüáî?wÆó5" C § &¢åîîËŸ8ZA%x"b*‰ž›¦»ˆ2ð½~»ûõö ö(áÐ#¹„á×Ñìx=ºˆÂˆÂÊÃ9ƒ²Ø²öÉxVg‰ö;ɉI¨Ä(ÆìŠP%cßÕc¥«e™í›õèDž§Dr½:~‚$d$É,F±É1H29ζH N¢”Zã^´dKì-¤+ØÜ$éK¿?] ^GíÕ h  f$·ã@¹„!šÐqæ…å\& °$J¤²æÝ¦ ½½@ë ä2¨Ç„÷åh=£JKèÕª¸ œ°‘„Žq„ÂLStäJH8’Ô`q8ºýùgõ>o –)÷Åø kÒÒyµ&&#¦j$ã@,,¥+#wX(Ô3ç+X»Vuš¯ Hz¼Ìë-äÓøŒI_þ[Xc9œ†š#dYÙÓ=»n‚·eíK>šùðÏßî_Cÿõ Ÿ2g0X,ÇÑ?ÄÑKرÈHúá ÀJ¡»Sñ*«öÛôå{äß@:„Ý(IúÒÛëƒôÌä¶mÞ;Yï!ä­Çqˆów¼àjͦt¤Œq^ LÆ#O` aœÊb/n‰0FL/9À-à 8 ÷ÿ½0aÒsŠ7 ŸuŒ¯¦Gº=è ¬_­n€0À2Éú8Ǻ ° ò‘¬Ä¥,Ü»ËòÇ ¶l©¿tÒ1œP;ÒÛùÎOô×0|µVrÃX~Ãã@ÃLÁ†8:°’LEŒSXä]ÔºK¿½Šâñ♉ëH_zˆâôÛë)¾V«9  äÈÐy$ˆc˜Âî‡åèý›(£éèîãu~Ø=6MuàHg˜¢D‰¾ô9H×åñ¶ïœ"-§W+à0$3q¤Bxd®/Ç‘Ú|VK¤‹]wzW”ÙÁªç)½lª Τq_vhÖZuÒË÷!×k 0¨à#¹½Ä_hãn>®ÏÄ¢Šs°?ŒRuί§·Ú$×R>Ë6¸K¦äŠIÛ¶›Œ"Ôu]hs'M|≜¦—¨ŠÏ©»W±Ço/@†Ž@‘ êàb Ë¡jæ8”,^lÉS™î7.Qe”Úï·ðÏ3Ï‘ˆIÕÏ‹4G<)|Üaÿ¤6)gµkJž7:·_>Swš&‚¾Ê)_YÞƒìêhJ:š¹3÷£åSøygJ­Qxw™¿ÝEÁÂö·ÿM«·@‘þ ßãd}qj÷F •S!&fÆœÝpFMæÇ;8@ m³‹‡ÖgÆÜ|af6ìYßaæ™ÁöÅ~­ ×r8BÆš¤µ©²†…ŸçÿzœüýƒÃLëÔ5xÙëv<^¤ÿM­-àÁ†¶°ÓåxæX]žó9«7®:×§o Ö¾³¶ÙzóåŽ|íE]c;³œ‚g¿¯ûoÒÜç¨p$¥ðœü54»›ír‚–u;Ùïµ—‰Õa¿/Ê6&èÙMî^gÌàXÏDój –.;ø¥"ôæÁ8Æ·f†­B/&g—ûWËLçuã_Ëÿ ©Kÿ˜èzñΙ÷Ef°œ"ð×"ôŸŒø_ˆþã%2C endstream endobj 3603 0 obj << /Type /Page /Contents 3604 0 R /Resources 3602 0 R /MediaBox [0 0 612 792] /Parent 3577 0 R >> endobj 3605 0 obj << /D [3603 0 R /XYZ 89 721 null] >> endobj 1294 0 obj << /D [3603 0 R /XYZ 90 690.045 null] >> endobj 1298 0 obj << /D [3603 0 R /XYZ 90 632.72 null] >> endobj 3606 0 obj << /D [3603 0 R /XYZ 90 584.152 null] >> endobj 3607 0 obj << /D [3603 0 R /XYZ 90 564.227 null] >> endobj 3608 0 obj << /D [3603 0 R /XYZ 90 544.302 null] >> endobj 1302 0 obj << /D [3603 0 R /XYZ 90 513.791 null] >> endobj 3609 0 obj << /D [3603 0 R /XYZ 90 452.734 null] >> endobj 1306 0 obj << /D [3603 0 R /XYZ 90 176.302 null] >> endobj 3602 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3612 0 obj << /Length 2146 /Filter /FlateDecode >> stream xÚÝYÝoÛ¶Ï_¡GkXŠ’(ªÝK¶¸[64í»¸í(6 %O’›fýÎá‡,ÊrRW¹/A`Š<:_¿óARÔ»÷¨÷ËÉOó“×ïâÐKHÂ÷æw^B½˜ BÃÈ›/½O“³g—çÿ™ž²ˆNÎÈô4¢tr5{7»š]þ<ÓÓ§ ›œ]M9̧Í{ý.bž!2Œ8HT,ýD Ñ 5JØ_ï4H|Â}á²^4ùgÆ"‡Þû¤t¨e³©ä"«³²øL# ÿ¾KG½S´`ѳŒº à-NÂ@¸oÏW2«´¹Kù™RVd HÖ3i%õ Y™A®Û©ÔPÝ•†ÁÏ?ü`¨šJ¦ë¼øà]C'§~4ùš®7¹aQÞµ Öi£Ç›´4,³zا~è°ÛØÂµ-õ"“E“¡‹·ÛÍFV‹´–oû :qØ— ÚùhÀãÉ"Oë‡|²Hó\.õô|*À?Å}ùæÍYÓTïÓ"Ûè•UZëÁ­”…~ñ¡ÊšF?Ä“¦´tÅRyšUf^j}cpcVÜu>‹–Xêõg·SF'ÛF:¯£q&>I"c•f¦½ªU„QF•„u9eÑä ¤ÌDhªrÝ ¥¦Êò•Á¨1ܾàBšo áÂÈ­™Ø€åü5«ØÒˆ°ÐÅdQnM€üø£þÑÕP;ô=åì´Þš`èÊå6TÞÇ´“÷àXÆIdU;# þ ަÀòn®D“uVÜ€3©• S¹YK¿ö×Úȯj b‡±­5 £6¯5ȦÜ㡞W)F‡FÔh`äKð— x(‹üQ0••/¬<'„úñ‡:…áWG :°üyu1ŸéY(Ëט†ªyܘ‘ö tA±]Ë*ƒ\ÓË´Iw/©š"ˆm«Gm®•úr½§P÷ŽÂ›IÒ³0`:]ñ·.Á±+%0`|’K¬ Š@B¡ø+ÿÞ¢öÝ·•:8ÐAѪ„¬:%)2Ã×r•UŒ£ëRRÇtGA4Ý‘µ“Ó5ÕD6:"®š}Û#®YÃR×vx\—•yGY „ÖbäWöøêPßY¹…²5Èkó²²ùvlçÀb¦CÙ¬f;j9§“Ý~1v ³¯v¥ Ø>öˆ $n«ÂÖ+[2uµõóñ`q4It“˜GÄO›Ä÷˜¸²¹q³À&EÙ}·u÷ŠHZ6Ø•ˆÎÚ HˆÌu‚© xW+ü$tœƒ‹n­À™ÂP¶Å'Užâ /H¨jºZÔY«dªTÇÕsí›kå@t=mç~*Ë\"èø†СOIl¿&Iºö¹Û‹…Üìö/Ymá©Jäõ`ç Û¡êþg[Û­GSYpKƒ¼lZâuoëÓ/ÝMcj5 $º¤áš.i‡{ w{Làô˜ë8$cö Ò8Ú¯ÐÝ\è*àGÎÙ®«(‡Å‘³ KY/¦þXËZÏ4V=‰­N)â`p³‚à.%»]ª¤;uX90Ý•y®!m75m©ß¸Ûá¡mï¡Móå‡)–Ø›ßaeöÏKÍûÙs ¤¹h¥‰•2_ºÁ£‹‰µÂÒg…Þ®XO½É¿üp9Vq "­Ô¢4žßEÏ lþ´ì÷³÷®.þ;;?ZgäFß(÷Fí0n../æxÒà¨BE@©€Ïý–Sª×øNâ(Ê tÛÚ'èv°›t³É³–‰Þx òÄ õ½xÁSVš›$1Q‘­åP)8ePôhñ†z¾ç‹€„Q[oFê{‹õɧ¿¨·„E`C‚DxŠt $œPu4÷®Oþø_0á‘ð£ÄùSL€\[§y¨‹S6"ˆ€W@âÀÜE|ÄÖé¼ <èïù„qÇ^D–pòŸÓ[O•éž¾§Nå"¿GŸ„°ôÀ‰gÌ~L¢ˆ„Ρ!eã¼K)𘩠‰0Œg¼} Ñ %‘íŠ>Ûo¦›‡ÎÕCÞ­e‡1?ZÕ¸ðÄÿ4oÀ|,Äö½„†b\j' ‰bäÅá|` ž¾žÆü%D3! 7…®èÌWÙýê{?^Ï}¬ü„&ãÍD.(áI8pH¼.B„¿KruÌK+uh;û (Àh)søŽTRßÿ£€x„I4ÿ±Lþ\€UþHüC¡eù1бx—ðß„ÿ (ÀÀ˜(a®Ǧý·´¶¸?¹‘ÍDEÐã‘ΰ¢ÚcFÞ¤7ÍaÌ_Bn,ãC‚wǘÞåÈÕùõÞñ¯·Ö×íÇ­aÐVw/à 1ô±Lèa ®íÆ3~ƺ ›óéaè_B:çPøâ}éƒ_Xž…?½­ËjÄ3Ap´âø0GÁñLúŸ¶J8Õ7š°oòãØ¹° sÎÏëßÑ"EQêßöŽîô—ˆ`ÿ{3—i8Ò×H¦ïhq®G„tïŽßÐسw´üÿüŽ6"‚ çJ†øÝK™Àc<ÆöªIt¶æêñéï!'1÷{ßÿðµöNy;ñ‹½x™TîÂæÔ÷?}OkÄ8w$:š|uEãOz7jÚ‡MìÍ™óeöjvvþJ/÷foÌ×AÅWydˆæbþk—°óqèË1ÔSÏIj endstream endobj 3611 0 obj << /Type /Page /Contents 3612 0 R /Resources 3610 0 R /MediaBox [0 0 612 792] /Parent 3615 0 R >> endobj 3613 0 obj << /D [3611 0 R /XYZ 89 721 null] >> endobj 1310 0 obj << /D [3611 0 R /XYZ 90 533.906 null] >> endobj 1314 0 obj << /D [3611 0 R /XYZ 90 433.592 null] >> endobj 1318 0 obj << /D [3611 0 R /XYZ 90 305.512 null] >> endobj 3614 0 obj << /D [3611 0 R /XYZ 90 232.5 null] >> endobj 1322 0 obj << /D [3611 0 R /XYZ 90 68.212 null] >> endobj 3610 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3618 0 obj << /Length 2835 /Filter /FlateDecode >> stream xÚµZ_sÛ8ϧðÛÉ3µJRÔ¿}Ë]Ó½ÜÜõz©gz3»;ÙVÍÙRV’›æÛ@€2)+I³ÎN'µ€ H€?P Äìv&f?Ÿýuyöþcªgy˜'*™-of¹˜¥" …ŽgËÍì—àüóç‹O.ÿ;_¨Xçá| \]|¼¸ºøô· "žç*8¿š'"XÎ[þãýÇX9:5*ŒѨ”yŽBg‚˜-¬ÀB¥Ð)"±þñ¾œ/"©ƒ¢ÞàCÜ4-Qêý®l«u±¥æ¦è ’ÀNÆÆ(øzWÖÄîﬢ¾o«Õ\‰`ß—Ô¡êˆÕ–ÅæÏJØsžbaw”ŒÄ(ˆ¨g1å sñ‰UDd/R˜;;„À€žöü«´qE*2ºûr]Ý<:«ì! î ¾lØ“P¯>|a9:š®ýî»rÃ1Ô+yè9†ú¡#ž^ :kçl‰3æ(`ÊMÙ–õzr£¬Êþ¡4Yñ]):¿ÉÉÈ ¥T1»(ۢ뉄kß“*í÷£$»Gj ó‘Úè+¸§ñ‘ЇÃ5 ¹ƒÚý`Æ ÞÖ'fIf§ô6¢R\RjoK2?•G:»<¯ˆÛ•€›ŽèÍz½7ȆŒª68œòii¼&@²ñˆî˶諦FìK+}|~‡,|/ËÓd™IW"¨¦œsrq _uÍ–_»ßÞÿ¯¶zÂu C?¯ãüù[(}šÿUÁæi.2”ð’ ç²PÇ)¹aÕlžtý[ ›Ã åû™†5þ¤76<ƒbµ~•›_m᱃PE’ÊÓ¼¬rªìD'§9dŒ7y‡à¾LAT¼ÅÛõƒ¶×?ýoa‰‚“E ›Ç³åeèÂadöë¢âÕöOx4ͦrZXœªÄÄ€gšªã"/€7RègÓ‘ñÉà-lAïäp(ðly:¼MD¼Úî g‚Žøy?§*1kHL' 3*xT1Ñ„žŽˆ—òÃØ¡ÀŽðÁ³c2A¸AqR,¼Úê 7‚%O<þ%öá} üdƒ^ï¦ÞE¼b–¶2p=,«\'ÂëâÆóµh…±²•Œ+O'2nj¯ß¦õPõw{W|¯vûÑš®9ÓÞ«ºÂR8T!M-GXpY7»]Aì®DËûrƒE˜îó.{5%^¬:P_[ÝÃÚk½nË¢ã"¦]…¯ .CRÁÃCå*H˜BøA÷q-d•Ô‰’NèažÄAØÎcø¿ 0^¹uؘ+ïqtàß·\$iöQIû{ÆTª ùá®Zßñ#_yi{,÷îªFBªJ_ÞŒ„ŽîÙ4_diãxøAoô­ñ|¬Ÿ¸Š4äLÕ®0ög¦„ÎÄ‚~†ÉsT¢2];ú½-ë²åªX&ù‚ ïc†Û*¼a= si:(6šNæ8ñ/è&¥ƒèè†;hÀ Öp±ŽÂ-ÇJr[íwáÔÜ/ûAqjK•i†ÕæM »±Lc7IwLòö °¬£UYÝÅÿ¨„ÈäÚ”sQ¬×Íž|œ'äcÄ\!ŸÖË„è¤8s6Üf°ËÒ¢sÇË“Q2èmÍÓÛ«±Ý«ñh¯éƒÖVBÎÑÚ¯CŸ;éŒ?lÉÌ™ÎÜB¢ùü~¸Â†¢w‰±í@*CR"´$õ ü•NîMÓXUÓ—6 o*Ãݨ3õTzA";$åÈNåábcâªÂó¦8¤‘O|b„ šÂ#¼±aúôåÈ€Næãú@@¡S+¹žÐøú-âë7ø-Hâ€NHlxóá~GxÄ:™È¼ !á‘éÊã8xd†¿a%̰õd†0±(íG2=þl/9F'$zè„YC2F'$9è´ˆEN‹}ì]qBÛߌ$*;œ»ýÙàšEz¢XQÚðøÄÐéSŸ¼zûƒ2ÁùIuC¿*Æ|1>dîÔ#j_|©­X-]»ßrÚ_8¨þc,ž‰ endstream endobj 3617 0 obj << /Type /Page /Contents 3618 0 R /Resources 3616 0 R /MediaBox [0 0 612 792] /Parent 3615 0 R >> endobj 3619 0 obj << /D [3617 0 R /XYZ 89 721 null] >> endobj 1326 0 obj << /D [3617 0 R /XYZ 90 615.654 null] >> endobj 1330 0 obj << /D [3617 0 R /XYZ 90 517.397 null] >> endobj 1334 0 obj << /D [3617 0 R /XYZ 90 419.021 null] >> endobj 3620 0 obj << /D [3617 0 R /XYZ 90 348.067 null] >> endobj 1338 0 obj << /D [3617 0 R /XYZ 90 197.172 null] >> endobj 3616 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3623 0 obj << /Length 2851 /Filter /FlateDecode >> stream xÚ­[mÛ¸þ¾¿Â8 ¨fyâ›^ú-ímŠEš&‹¢@î°ÐÚ²-À–¶’6{Û_߾ȔMÛ«PR=3œgæáPÒF³Í,šýíæ/÷7?HÄ,#YÌâÙýz–E³$JI$äì~5û6ÿùóݧ_>þgqËd4O·2Šæ_î>Ü}¹ûô×;=üy‘±ùû/‹8šß/~»ÿûÏ$sd (cШD²(ÂI7‘1,ˆœÙ·vú-K`;ƒœ°Å-À‚ûm¡u?MY¯Ê¥{}‘ÍŸò&ß]ÑxL¢iJïMê¥í˪Ü?ïõEWî -ê±è^Š¢ÒÃÅ‚Éù÷•ó¢êZ=ök$£²²2v»²-–uµjaœ‚Ï8æ×ZVU£=³[kÂ-¥$“ÆÝOM Kè^µ¤ÒHoŸŠeùk±be,ÛZcrݬŠõtäÏ»N|G#óݳYW½Ö-5•uC%Ïm±"ÚU<""&’É!Ü‚f »YÐt¾Ü–hÈwü¯xPCÅîa¹Í«MñEÌ;1lÍ$# ­;'Õ‚Œ÷{[Ê.DMg&9‡—f…ª ù {ð£ÍòQ_hñ‡|˜O :GŽ‘\å‹3Ï«´´öè}Ù5è{¼ª"DNMÞ盢—Yù–¬¦Féq¤èÁAÞë!¥ÚMQMÞazªáµSáìW}QWFNmîê…á´£…ÁPïÍ?"@FK ¶6T Ù<¬Q“kí²)!+Êç=¸S¤B»S™±s òøÀ‰j`+þÐ)H¤–‚pJ7œŠD¢ç¬Ò1œ|Ó0ªc¹ñlL‹ÔDï)›jÁÚj ‰yaìÈ›Âk{vþ3dº®uû' ¼?œ²¦EÉ„8’wD8.Ë1>Lljn ·D‰‹‚ lÜL7nkË- dÈ-6`°ãÁAÙ±Òs8èË]©aIXY½SÑË„Ã3ÐðŒ2Ñ Ž¥¹;Ê3Ëî"%Ñ ò ~°DgŠŽÇÆÒ£›žU<ƒN3®ÄÖp vu‚¸7OXXE iuë° … YňӬ‚ŠUTgÝ«5Ó† áVÁÁ« % Y‡VñxCs ï9†[ÒN<ã°æM>ÌLÐNÔÝpªfì)V1“ð“hÆÛ*š±s–UðfÏ*"‰ú «8V—…1)ųî õYg+KÏŽ £}¦ø ±7qJ_ñƉ–­V§ºœJ|ôæ{sSWµÐ;Tµpqœ8xRêÂX_ê*ù§¥nLu’ÁTEÎñ€Ìâ´·Ryíö<§h‡¾ÓN©j_¹0º¬6ç«s½¨º·rj\íVf‹Ü”HšŠ\[à~-º®—¾ÝhWþ¸3"ùC^©I1tR'™Ñb¸åpÁåÜWYíÆ¨ÒC]­ÛpV…ô‡fª»G5 9f*•¯FàÖL¸_¤X‰oŒ‚eݘË]Þ¶E‹…ZF矗7ðã]ѶïibKéNïÝj1ÐBÚ¶¥¶®Ô:¨vñúÕŒm‹ÖÜv·9%¤Òm[?7K3gY¯L/ïl;\6Nj HÄÚü\gö« ¢2ï•ëÎ*ïòǼU$GŽ/(¥Æ4¨t\‚¹É³ùº©1…¥²rõð6G3ûìƒû¹¹Qn¶joãXæ”5Pð«¾ê¶ªrCïà£8Á)è%õxÃs]¢¤‚KÔn›s±8ö£¯jt‚ir°Ú¦X×ö©+ó]ù?K•è—?žÌ(#BrYc” ç|SÏ!úsû/Ö•ƒI‘‘aâye|\[†é¶}žÛ³¼…èÝÁØ#^w’D:¦Æié5Ë,ÿ¸YvJ3¼ý&›Î/iW>6yózõÉ‚fnX=,×K´…|½âÖ>€Æ™ýøæîþæ¿7ܤ>£2!i<ã#2KfËýͷߢ٠îAÔž¥³5s?ciBX ÝÝìëÍ¿¦O±²Ë""¿$ÃîDF†z(7|Z Âx ²‰˜Ù9>cr÷¸´÷^Ÿ<þ`<" ÔMa ‚È(»jI§–pÆÕ¯¦°„ Fh”-ùÇÛ#wh™X€Ð°ì$hP»,âZÜáýVw‰$1üàGVÒGÌhžˆ‘1,YlbU´p’xR{Îù(™@;—€§¤Cí?}ªm„ôfüt!&=)²DÉYvQ¨cˆ› Æœ$?œ=¤£ex c¢D%„ÛÌÛåÅî–¨å|(’¡^OùíçžÍ@'*4A†„ãJšp\JÒÀ-ÇfJ2ÊA–$<Ú­ÏP¦]@sµ\dð9TûÏÊ`XìŸìK†úç< ~T€‚ yYÆåI9 Ûé§$Y‚AMŒëç@» ;ûšà!…jn»¼ZåÍêáJìqt¯Âd$,4ï#KNÂp-×Á° ‹Š"¥I¡}Y=\8 õpO ŸKàrÜã]ýÂÝÉg —²7Й U‘ÄÙK3àC–½ãeøOTQ’ÈÌ<°Þç¿¿Ô)Ô[PúÇ‚âKsH¦%) :g‡‰0Q[,ÃÊøñ2ü¹eM9aöã-Lõ|—7û 1ê>"\Ý£#"Иæ(CÈÀS6…ãe…²ÇËð§9“ç %ö´‹i~ Ð T÷€:ªGãèF…'ÈQà9›â&(Â"œ¦ N@­Üldg€èc`½ànBE:Ô‹Yý¢žl6•÷d܇Âô¡àZ0:Fâ‰!EhnÃá2ÉÆ'ŒpèR‘n_ã_ùž ˆ ”ã)3:TŽ¬ð¶€˜À‚> \ FÄhC<2dX©S8\¦<¬R/Ã"£x•K"˜=k».¸p$›Bs§«y4žnTx‚Œ˜‡Öèp°LÓÀ}´ q§ê­¤Dœ¹xš2ýªèïQuõF5À™¶ÂqV¤‰0aP–……Åhþš.¥èYJ(í?q?C?(ïcÂU>:&=©2=Ò/p‚2OŸIX•>Z„Pð)t³ŒÐç°Wáœ@³EÓÑ<Ë@"”™~y„$œcZŸsõþy 2‘=ü°ölU6vܼ38¸ÚÍg™g#`µ<†C 䱫¿X<üEÒþ+~”y>Fq©~[pÊŒãiŠòD&ß^’O ™qüV#s5_þ;#> endobj 3624 0 obj << /D [3622 0 R /XYZ 89 721 null] >> endobj 1342 0 obj << /D [3622 0 R /XYZ 90 690.045 null] >> endobj 1346 0 obj << /D [3622 0 R /XYZ 90 651.4 null] >> endobj 1350 0 obj << /D [3622 0 R /XYZ 90 481.412 null] >> endobj 3625 0 obj << /D [3622 0 R /XYZ 90 408.934 null] >> endobj 3626 0 obj << /D [3622 0 R /XYZ 90 391.066 null] >> endobj 3627 0 obj << /D [3622 0 R /XYZ 90 369.084 null] >> endobj 3628 0 obj << /D [3622 0 R /XYZ 90 302.796 null] >> endobj 3621 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3631 0 obj << /Length 2771 /Filter /FlateDecode >> stream xÚµZYoÛH~÷¯ò²0îôÁ>è7ÏÆYd±ðz3^`ÌÀ %Ú&F"5$Çÿ~«ú xI…šb³»Î¯ª«:{žÑÙ?.~¾¿xÿQG³˜ÄŠ«ÙýÓ,¦3M ¡‘œÝ¯f_æ×ww7·>ýoqÉ%_“Å¥¤tþùæãÍç›Û¿ß¸æ»EÌçןŠÎï¿ÝÿóýGÉ[4#$(p´$9eØé‚z!úÏÙ¥ˆaŒÏ.¥!ÂxI>ÕŽYV¹ç¶¨ªìqº·ºpÏ*õÝ6Å*û•Rž4]¶I™lÒ:-=¯YâǾø«¤N“Ê¿%žRýº`tîé1.ç_LÎÓµ'tÕQgvÉI³Ù% p/<#Ý>_¬¯=‡å:©ªúÝ1´K’&©õ|åèdKTF›.]ð¢Ý$Ë—ñÞI]—Ùã‚Óù®N]——_×’¬×®wVW®¥gsøÔ±9ô÷øÖaÐþ¢Éz—‘Rž®‚D¨íŒme†`$–ÞÁzQ<Ô÷éÉ}sŒàÈPgù³{i³Wësx¢éš2ÿ)/B÷¢,Ó¥y*J÷§ÈÓÀ$˜÷'áºK¨…e”´pÏ2½ âYå©×[9½³Ú"ð‘˜ê.:Pk>~MñÉæuò;¢8u­Öø'Eµ¾%›íÚ÷+ü¸Ä=¼ðËü frá-Záͤ 2–!¼Þm¶iy·03¯iùËn»]¿d#‰6QõšÕ/A¶2õÂìíVyqÉ¢ŒĪò½ïfûž&$Âizÿ4B/"’©1r|„Ü¥0œhò-X&ù¨±4¤Â1ÂbLNNŒ¡7¼äJ{\©a˜Â·ÃR„󽹓¼NWË]Y.„ž§y=Â^Vû!NŠÏ?"b,ÂU^`‹(-«Ú½ì&t B @ðk™ù&ùöÐŽzj>¥ì’µG73`…žq]öˆçòl2Ó-¹tˆu›]²råÚÀj(€Qák<@ûˆ´½´ö_Ô°°™dOÇ/Øü@sÈÀ{ Ô¤¾.áN^ó G‡S@ø²+\D^!;ÉÚÁ,¨«0>ICS'–pÈk>õR;|ƒñîSR¹gßRÐÇ¥9/Äo\Á~Ü$ᢉʶÑTº8f^…<mª¤|sHÊ ÐÉ’.™êv2]¹À†M¿ªã*øà&Þ¬ðš»gQ®ÜhÕ0ìYÕ2ôúÖ„&?iô™ª^ް]\醕…¨a&ˆzÓcB 'þY¥Õ²Ì¶uV䀔ˆFóuò˜®ýÿ]žÕþoUCÞIÊÕC«m•UÛuòf›9››ðè±I|ã~ò÷ãBo´»íÐL{V¶Â¹qL‰2­weÞ”k›nÑ-YéK¸ô “O²[ûÚªmgx}|kêD_ŒRL<¯t³­ÃÀcþLp59ñ8"â '™ñ53*²ÅJ9ípV¥ýÞ-T‡Q‚¹'»}Q,„·(DFË¢ÂZÔ¶–©… 6õØÙ1­m?J« ›ùpC¹²µ·¯±åD±{~q}<>ÿÐDÙ]Y|{»º=tló°,rôÔó¯TRø1G õR¬g“M3…’8?ÂBÇ+Ú-_Õ˜nƒI\v«f¥\†vÁ ³¡TÀÉw*Öëõyu8ƒµ7|u‘þ˜z¯/™­ú¡“#çš_ðñÑßU6_¶¾x4aSWöåÚš°ØaË>¶ðo[ØÐ` ôäPô}ÊØ,PAíp‚£Q(e j)FCŠI™6l{<<ÅçlŸÚ=;œe3ÿÿ®x.í,ïQzÚ^Žéž–u–Vïpª²"»?X`s 8ŒHlJW&f÷N]9ïâ;Ÿ#ÝÔ+ÜôÓzÞcÕä(,¾†¢ÂFÝÊßUÎémšqWWÿ3~Øð¤C Ç –<††[‰ÞÜ_üqS>äFX¨ÅÄ@G!#b”œ-7_~£³|:DÄföj»nf"„œø×³_.þsv"‚BÉ-¡”³Œ#’º§awG:É—E } ´ š†§ËÁùvW·çˆ¡5`µAô™d\ÛÅFG†ë¥Ì€q¤9L¦?ÂxÄ @C§ñ®„µã= ˆ•šæI“ˆ-Áˆ„ÂÕZñÝm¹M—v¢NWó ‚ðXØr§#Èç´ÙÇrU‘­8ZÀx0¡T^g¥/‚X!B7ýÚyñ0RNÖiÄÉQ¥'"e‘&‰:Ž·ï€ šà@ ¸qæ¡òι³ñ H´åÂaÔœA&4â¾Lß…šfeçË!d8!ùdÜÎÕSS ÛJÏ>¸Ïöo˜MÊ׬ {\åŸHì÷4ûk@|²‰G CQRÿÆÕh4ºL ÑÄЈ¤™“ˆx«ò˜A£i)‰„šqcHÌšÜÜIÕçàËÁ# ð)‹9ûÜaCÐ+N(kö)]}6ƒ°~Üo?þi  ƒÓ•q˜Ž‰ˆÌ¤08ƈñmbŠÀé ›ð%ö©9GkíçÍË€˜ñ{ðËCIÝä!îFÊÿšY{Š—B|# ÅÓ’Ä9tHÛ‡”Ýšà1g˜üVÈ¿Òúo ‹dïæÀÃú%÷܇]çá¡Ç•›»ö›Çí¾#[3éºÈŸ÷Ga»(l>õÎy^ý°Þ^`û̱¿xðµûzJCÍ¡µõÕÈú €¡Eä´wX£óø<>Z¦Ä8{Hj#I §Å€û†`ÑD‚×ÉÜGàu Eh´5GÜ9xªˆpuyŽí âó5 PàLDâT"ŠV«‰;§r?¬Ù˜€ÕläK¶î9è!(ž;×PÓâ¡Ã]Ò#ÓôÉLG°xÁ,¶?‹Ti`„Õ½â±8•ˆÅ"ÓDS3‹¸¾f…æõÃò–í‡xÖ\ã~]µ<‚Ã3ðÀKš¨Ë“Ñ#IôLpÛLOîÉbŒ`hHOîéDF@GݵƒÀü¤bOpE´?‰‘ö‡¶µ}a¿UxsÆ~³‡ôðLíNao­tOö»÷ZðÕÝøá 6 éþ öIÃ×Jyø¶Æ¾fTÙš å§þ– ¶õo•À+ÝzŠC?Pw«—ÞÀÅÚ{wn°É]Z¡Þä#œCrxJŽÏ×ÔšrÏ@·Þ0Ì{¾øó«Yp4mœI3*vtΤCgÒ®_P‚,HP¦•»—a[ë—F§±Ci4|âëi£ƒo¸1þ’ÑßðXCŠêöé»ûøÓ3Ó÷_w`ïê4¹{ЉQ×à;›ŽIÇnŒCÚø?äË× endstream endobj 3630 0 obj << /Type /Page /Contents 3631 0 R /Resources 3629 0 R /MediaBox [0 0 612 792] /Parent 3615 0 R >> endobj 3632 0 obj << /D [3630 0 R /XYZ 89 721 null] >> endobj 3633 0 obj << /D [3630 0 R /XYZ 90 643.518 null] >> endobj 3634 0 obj << /D [3630 0 R /XYZ 90 625.65 null] >> endobj 1354 0 obj << /D [3630 0 R /XYZ 90 477.516 null] >> endobj 3635 0 obj << /D [3630 0 R /XYZ 90 355.064 null] >> endobj 3636 0 obj << /D [3630 0 R /XYZ 90 181.867 null] >> endobj 3629 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3639 0 obj << /Length 1792 /Filter /FlateDecode >> stream xÚµYßs›8~Ï_Áä OϪ~ @yó5î]nnR_êéu¦íd(1s8Œëæ¿¿’À8ÔNbß“…Xí®ö[i¿ÅØyp°óÛÙ¯ó³·ïÏHøÔwæ÷ŽÀN€C„=îÌç‹;™Í¦×—WŸGcʱ;A£1ÇØ½™¾ŸÞL¯ßMõôl$¨;¹ùؾÍÿxûžÓ-žRÈ}°Ø¨¤˜*¡3lœpÆV`LXÄ´Ø|!µöU]¥ùƒ÷ü:º>×Ó›4Ëôè!Qî~îJ+VصQžDU¢ŸÖyZŸk‰û¢êKܪ—¿è9¾#³LóÛïÊF”­¥•Á»BÑNHOf-ÄÕ†a³cBà&´íÊJf·ñ"Ê$j䈇„çõ…ß½yÂÔsW¥ŒÓ¯Óø&Dà^å«ZF‰~[Ü«_îÖM𔸠Œ!*õŽ™œëÚÕF"¬öHE§¥¬dY±\­ŸA>‘jy.5ÜÞ‚›yñ€Z¸'Yµü¤DÅ<7{3 Nüþ.?‚_ D)òH›?ÊÕ§V‰Â •;“ëõòNVê|Œ¸`V4Žr ÃAm½’ j-Ìó©Z7…!ßò©g¶‡ØhL0ŠK©2ð{=eZÊë°êzýLI ܨ2ƒ¸ÈUpÖ•LôÌ&­zToF»…~ø'Í€Â]ý–Q-e-«d‡ç{p4Á§vR - ÝÇq‘Xíi®WźŠ[ë–µ±,’&g¢»Låsg» ^óšÚm‡€x؆ ¸ß·üQK†©G;&vKBä‡öú¨¤Z%˜]/¼íõÍ›&äj`Ó9ÑrQÝ_Éܸ’Q¹~_§K3ŸæúWx5…êà?f]­Œ1^%¥v w©ça÷ÃÞm±^e#Ÿ»pøö”ÆÕ¡8ë[¦2Ñɛ㭮¢m¤š™&¢?bYÖöòT Õ¬6k¥ºº6æN´žÂX'‚-Ë4k¢®3HÃyãâ.2­Sê’ŸÎÏþ=#°H‡†¨ Žz.¸xyöåvx›DL„Φ‘\:$ðáÈ0Μgý:$p¸€¨9ÔÛ§Î""0"œÆá#Æ:’ÈU\¥e“ÌOüa¡@‹Wø3€èÀap$Ì>„WøGâ¬jGŽ‹®GfÊ!‚5—ÌPO`–Á•&˜è›µâ°-Š/v`ÐýHUÒ èqDöçÓa]pZ½)á›*­mQû ’§0 ì! ´oºCêKòVybžëÇr²/vhxf‰ì±JdE!óŽD–@®T ¬™Û/IWåm&»î Ûñ |€²|ö|èVÞdÑ£~8àU‹ó‹½€tøŒ‰óË•Øþ÷šMÜo6”q­_G [ZØ6€ÿ«F$t :L·h™b8ë²,ªÚ•–T«EªÍ|ÓM œÍΡÍ";4ì¢ßÝBcⱜר¡p_¡…êK}iúêÖË‹‹ÙÕlz{3\j¥[Íbdhr‘gýN£S‡_oïöùtÇêàŽŸtNo¦óÅÍÝZË| aÛÀPqÚËúó Ø=D¤9DX¢>}Fƒb^n$èSí´‰¯j É_ȬÔ2:00õPE%D$ÊŒdYfðd82lϽ2­„ÖJ¾ ºŸ‡Ì×KYµ½U$ªZ÷ìJ¡YŽ:ÕX(^>Ð@»QÄiTÛfªcú2²À•Ϲ“š©teIcשi|mº/²¬h:ó©ÞuÝÇWÌñVª]‚Ñ?·mÁ{‚®f¸FC6EÛ?@$©¾ê ]`§Q ̇R†8pì£ U)EÒÝ>ÉFó“Xejaßê§!D®zjÛçH@9}¹íЃ¶¿ˆ=?ЇŽÃ÷ÚÏVžÑ@E„ÝPB øNy¹¸ø0›ÞLšÈÎUµúp³Ø¸Ã€ ¨çÞè‹m`:x(Žô8%P"TáÇÊaOÁ!Œ0%O~DÛoÛÃHžÂÉm?ÈÏ‘|¹Í§ (ô­;ˆä+” rÃ^4Ö_Á ·Ð'½šÝ«óšoØò³ê}ÕÚ®Îj¶«Î¦FõéàTìr‡ eW¯èt4ža_þ~ö5É·¶ÿ#´ÜZö•Ø mým':_^Cÿ¬úë ¨ªw]Ø,¤ Õ:oK»!—ê/¨zÔŸô‡˜î$Ž‹*1tÆl@ýj C±¤‡õ§Ožè£'vу‰òsxLïµFó)¶¥9Â8,lD…%. ¼{ÑnFv¦·b€n …õbmá ÿhy endstream endobj 3638 0 obj << /Type /Page /Contents 3639 0 R /Resources 3637 0 R /MediaBox [0 0 612 792] /Parent 3615 0 R >> endobj 3640 0 obj << /D [3638 0 R /XYZ 89 721 null] >> endobj 1358 0 obj << /D [3638 0 R /XYZ 90 626.503 null] >> endobj 1362 0 obj << /D [3638 0 R /XYZ 90 559.644 null] >> endobj 3641 0 obj << /D [3638 0 R /XYZ 90 484.639 null] >> endobj 1366 0 obj << /D [3638 0 R /XYZ 90 396.111 null] >> endobj 1370 0 obj << /D [3638 0 R /XYZ 90 308.899 null] >> endobj 3642 0 obj << /D [3638 0 R /XYZ 90 235.887 null] >> endobj 3637 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3645 0 obj << /Length 1904 /Filter /FlateDecode >> stream xÚµYmoÛ6þž_!ì“ Ô,_$Qê·lM‡[‘¥Æ0 - Ú¦c¡²äQr;ï×ïø&‹²œ%uö! }¤ŽÇ{޼çÝG8úùêÇùÕË7<Žr”§4æë(ÇÇÂqÍWчÉõííÍ»×oÿœÎh‚'×h:K0žÜݼ¹¹»y÷ÓßNs:¹¾›¦x2Ÿ~šÿòòMB{:c­0IaE£’b¦']agX€#BPžÀW0}æçÏ(Ì‚¢ÓÁ°üoõªøˆ1‹RZ vÅÎ÷„[ÙJÕŒX‚£ÉPšY•7b¹Ñ‘îs2ÙˆÆv„m–u¥Wºß+Ñu¥…tÒÈÖŽÖkÛRÛlv‘ž5à9FØd¾‘ÍɘÕ*”<§F¸õÔ¾šµÅVꭙͯÙÝ|-„õ€kVrJ.c–¢,m¯V¶í¾h7ÞyªÞI՜ъ…h$2pÝ̯þº"°*€Qhä4JIŠÒ4–Û«Ÿp´‚A0 ±<‹¾™©ÛˆðÅ„C¿ŒÞ_ýþ(‰s¥8F IRâ£Ìé0Á„%9’® L¬_o§$™x¨¬c*a!ø$Lj$ìy,ÉSÄØ²’ÍR;™'ö°,G οÞˆ@#é…8cX„&—áœÀ®8¿Ì¹`Î’(Éb ·Þ}ЕÚgXœaŽpF°ømw}= Ñ'›qŠ…V‘pr +1€r3ÒË)",ƒÂØeŒR,dù–ϰ.£Ø¤Ê`Ý#˜g,è`|²#€Jø…8>]‰OÞ¸Ï$߸2ò8Ž£,v¾ôgÓ2¤üÞTK8ðèI¨M4zÝÜ]ÿ>Lݧ i2*÷y-5ù]'`šŸ³€qÄqìÕvÀ ãŒ!Ìø™Å ·ê¾‘++Yl{¯ÄnS@¶?ÅnWÂ/Ï'ÀÎÚ$ôÊàb²y=uî(š])An·ö™î·¬|·ôÙ—x›@RšÓpß4Ô¹©ÇÍ€sÐ ²Iv$eÌ‘²÷²m‹êÞêÙ^ÈÐxîРi\×SÖíËÖ ¾jn#ʽ´?õ6u{_Σ¥öŠoMkØî„¦1˜oMÓc}J¦k’›0Ÿf`Fuï”.kå–¥h©Y^²É;y´CÁÇ¥lš01N&EÛ™Ü'qì]Ý4…õY–Ûáº2&¯Næ$ˆ;'4vÈ@ ò¦Þ«¥S±¬Wn¶á q@€d©¤B­XóJ#7ü$–Ú5íÈ‘ÎbšMþ˜B: `\ÉV½½¯ÆˆêZÕ[­×¹•fI§×Š7bJ±Ó`Ç…(î7æ´h§ŠZ†ªM¢²½Ð)É0$ôë »–ô=‘Oènn 3ÃÏMBÚ®µ©Q:{Sr]+«¢-DYüãÏ¡ö« ŠE1$¦°PM“Œ‚Â9Lý5÷„ýµw\0 ;.¨è¨Ž·kGfk¸8ü¹õ·ƒäÅÑØA©Ð; ¦ºÐñï)Ìñ°Žšå¶Æ¾ß,?E…òéü–Êb¡„:œîÂVKÝ•cîê1°:XøØüt$vâ·vçbnX“AžÏGpÓ<œÍ"PqQ‚gQ’ ¢•`hsr!Y'†£0(…8çO®ÉˆùêY,É9Œ³Ð’_3CÈM®ºe#`iª•“ Ç¥—á­©u_HåA È1ÍcàZôQřŸ9Vg8…hãáê?¼«OгÎ#út;NÁÐ:hÌ/CôB%SäÎßeåC<¥…2©£vgË3‡æ3¬Ëàr¦ÀUƒuDtüÊè`|²#@a•åìBŸ®äñեɑοmê¡ÇFuŽªÉk„äOšc/ŒaNSûMß›NÙ#¥S4`J3jžÁ”®Û.è¡Ðó*c>°Æq¨WW›˜û'f g3†ÐÐ]Ø—Zø¨h+¸Zßw5üTû‘Á $ÖçÐé“c·ÖT" Ó…ÛŽõæ6†ÚÄ!=Ù9Rµܦ_ö—éA}ˆ ò€ýuHÉ¥û±ö„¯®äð‘ÛѺâQ!¬äÌ›ç?C¾G9æ!žw…µo;Ûî鼨–Å®[É$ý¹ÑÇb¼Ûh¡pZè8Ø·þ½þô?¹Çì±+Øïdóœ%{ÿ‰së*h{Ä®¢…VÉîñ!„ôq2x°P¶2,±»`†¶ÒQu°?¶õVV­ Zf¬Kã}¹²Ý…û|Õado®Ø×¾Ð©d;+ôìÕ¥¾À,NýY çNµ6¯(SAÜnT½¿×—÷G¤¯»8¾Uõ߇W¯À=Ÿµg>û0øˆ ÄÎ7mê•í[l‹ò0M“‰Þ&O- 0±Ö Ör1 ½cÌŽ°:‚ìº×¸ÍŒw´ÄF°î™Ö‹(™Ø€Ò’ÁC HQ®Eîí”ÿ*‹3ñ¹–N¹yı–ÊN_Õ˽†Õ=Z¬m{¨÷gU^_ªZ»þ›¿OZ@Ër±¨÷íðmm-E»W2Ì ¾"ñ/0$F endstream endobj 3644 0 obj << /Type /Page /Contents 3645 0 R /Resources 3643 0 R /MediaBox [0 0 612 792] /Parent 3615 0 R >> endobj 3646 0 obj << /D [3644 0 R /XYZ 89 721 null] >> endobj 1374 0 obj << /D [3644 0 R /XYZ 90 690.045 null] >> endobj 3647 0 obj << /D [3644 0 R /XYZ 90 616.868 null] >> endobj 1378 0 obj << /D [3644 0 R /XYZ 90 496.16 null] >> endobj 3648 0 obj << /D [3644 0 R /XYZ 90 425.739 null] >> endobj 3649 0 obj << /D [3644 0 R /XYZ 90 405.814 null] >> endobj 3650 0 obj << /D [3644 0 R /XYZ 90 383.832 null] >> endobj 3651 0 obj << /D [3644 0 R /XYZ 90 317.544 null] >> endobj 3652 0 obj << /D [3644 0 R /XYZ 90 219.376 null] >> endobj 3653 0 obj << /D [3644 0 R /XYZ 90 201.509 null] >> endobj 1382 0 obj << /D [3644 0 R /XYZ 90 137.06 null] >> endobj 3643 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3656 0 obj << /Length 2114 /Filter /FlateDecode >> stream xÚµYKsÛ6¾ûWðHÍT ðéCgœÄ鸇$MtèLÒÉÐ"l±¥H•ãúßw P„L9våꂰܾ]<z·^èýrözuöê]yy'<ñV7^zi˜a{«Òûâ_|üxùþíÕï‹%Cÿ"X,ã0ô?]¾»ütùþÍ% \äÜ¿ø´HBµøcõë«w1ŸÈŒP`œ€F-’‡2…ư ôXˆ(áȾ´üKž‚ a ¢Å’… ü­\°Øÿ^­%i_×Eß¹+ºb+•ìf¬Ax’yð…~)|†ýv=le£ Uµ Eþ×0ä².i¾ê©-ê¾µ¡‘†¡PôÕj‘…~Ñܶóz¬Ñ@Ö4…NÉ,ÂØ¿R®ºC%fØQQ¡@ç òجª£x£Ø¿–ëbè%ud±Þ刌"`«Ûæ¶jniZµÔÔLíyðq<: d¿iS¹)ÇjRYÁ³¦|¯ "й%fA×îd§îIì#žXh¼s&u¯¡øUõNRÚÖci„9$#ƒTâ•¡„åÏÑoCWkÖ³ŸÐb f ÍüNª®šàPOsÿn#ÃØôªhËÌoo¨%hñ êšëúO¹V$É*Zw²P²Ô™QÞ3€æÍâR µ¢ï(­¨éZé$ód$œÖ‡ÌTrÜRk$DðÈÖ°ØÔ°ÕÆ„½<(f×u±þËí?”±”DØFÂ~©IøˆÈ·s5YïˆRm[‹FŒÈ“©R^c¢ ·”æ8ÔK,ÖCüBÇ`"µšf䜦<2÷²£åí±Fcœåä=ή¹ð/Þÿò>^¦°ÁNßÞ¨;½\:yàÞ½ã©?QwOóŽÀÒÉ¿Ù+šÔ ƒ&Ï`ÄÆ!vh%Xsa¸¨ž!Ûº® j!FyAy #:’Z— l3»1¦Œº2»ÂR¹mèÑøJý»Jmˆ*¨éwr]!êÖØÏü7>½^ˆ˜ú˜Þãî…éÚŠà®êâZ[‹ãÉ¢‡Cûèé¤IüKÚÄh½&eZB£èË̤ŽÁЙ¬Iq»šq³ ˜÷-½m|JÙ¹iëºEsîF®ªã·ÖG8wJ—Ç’ ™[~¾r»\_ôIFC1âèP#ˆºÃÝ„HegGü`gƒÛ/×kR:‹ÿÑA\ ýÖó÷bœÀf\Ì©'߈®Œ¢²|µÝ¾º‡ŸdDIîîr› ηÕyߟþLQùÆáXg D*;l3TõÝp÷X™Ü MÙÉÒ.I3l¯eRYàFriíyj¼yiu¿3”®ìÐNqœ)«÷PÁUCÃk]§¦ß D%KÉþ'ÌSãÌšnÂ?N ¥‡rhH‡'ÛÃ9x~ã®¶. ­u@imØÚtDÃÒØhŸNP×Ä#5kí^éR@÷¢K'-t ¼bÝn·°«~«švP0ý@¡áŸKEç [Çã#KPÎñ£œ{b†Ùé8aîúý°Ûµ²š)©%å§ÖÓIÃ;z¢{w› tÌÒÎú3˜$ÚÓƒYÌÂfôUS©ñDx¼À]WÜÛó‰‚}£w"k«ðnPòˆã T4Sá5´ —«³¿Ï˜ î±, ’(òxaš{ëíÙ—?B¯„Ið0yæÝiÖ­w™ eèÚû|öÛÿ!$‹„Ç3¦ Ø#B€O2ôýÙAËYr1c´>o¦a³°wƒÁ¤Ù‹XÀ“ æSׄ«æÉë"D#Ï_Ä8Ô‚ ×–ÏIIJ€igžkÌ F@Fú¸Œ'-͈Љ@KÒ€e§­2 V îZ©­g:ÿƒë´æp³Ë„«õ;n™mU>¥Ó5#’x~ y,µççæ6x$#ŒžkÈ ’$È3v"ŠN¢QC Ñ9 F,HÊ‚‰=Œ†þ8Ž^B¯ÒTï€ôªE:M\ÕsHÒ×’ãPz¶)30 OOÄÒ©B4–"D©8K ,ÊJ‚0ÎíÆS©ãHz ­IS­O@Ò ¨PMÒ”=Uõˆœg«žYtÁ—ñä<_Èáó ý`Íåæ–¶/’ñè°Ãg/ªÓΡrö´!K2祋çûc(vn¥ê–üàñ'÷{R†$Þ‰õSn9} ÊýJÙ나b+AGö‹ý[Ý·Þî3&Ç<éȯ7(~+íÕ™úÆúÌ\³zkµô”[‡2ï9öM¿°ò8†ãPä^èU%®ÿ`±õ¦èaY¿×c—Þ…ºÊD˜åt‘ªïš7‡OW“‡DDf0û‡”ä&#ù endstream endobj 3655 0 obj << /Type /Page /Contents 3656 0 R /Resources 3654 0 R /MediaBox [0 0 612 792] /Parent 3659 0 R >> endobj 3657 0 obj << /D [3655 0 R /XYZ 89 721 null] >> endobj 1386 0 obj << /D [3655 0 R /XYZ 90 690.045 null] >> endobj 1390 0 obj << /D [3655 0 R /XYZ 90 564.252 null] >> endobj 1394 0 obj << /D [3655 0 R /XYZ 90 378.912 null] >> endobj 3658 0 obj << /D [3655 0 R /XYZ 90 294.278 null] >> endobj 1398 0 obj << /D [3655 0 R /XYZ 90 187.284 null] >> endobj 1402 0 obj << /D [3655 0 R /XYZ 90 114.019 null] >> endobj 3654 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3663 0 obj << /Length 3124 /Filter /FlateDecode >> stream xÚ­œ[wÛ¸Çßý)ô(]cq'¸oiâä¤ÍÙõÆNÛÓìžÅbl5ºx)*©ûé;‚)J4™ÁCb^€™?€’â“û Ÿ¼¹øËíÅO¯=IYj¥Ü~ž¤|’pǸ6“ÛÅäãôÅõõÕ/¯Þþsv) Ÿ¾`³KÃùôýÕë«÷W¿¼¼*/_ÏR9}ñ~fùôvöÇí_zmdæFƒÆ‚GoRrƒ‰.x øD–ÈÉ/«ô—2*a–©Ù¥ààþö!+¿Ý,‹òèn»^Ï7‹ÞùäR8f]iæöa¹ƒiZågyv¹cËùj¹ã ¼ÌË;‹l&Íôëò.+Ͽ̟fÙãrs_^(B†Ý|Òl²â&Ûæ_*g›MvW,·¨AmÜôÅç"ËË{óMù·, ª ã/g3a¦ÿÅÿ²K,ž/¯­²Dwû"[`¾tºKJxåxzPþ#\zêíÃ}¬L°Ù†  -ÛíæùSyýó6/îVËlÒÛòÔT(Myî¯ãý²šn±¬Î…:Ç4uÁ0ÝïœË|¬ÜÍW«ÝÁЉr6Ú¡ldÕhdéà0­[d«¬Èþ½ðU‡9~ç†Ã?q«X*\•s[Ô'Õ´  +VÊf[`µ—·—Åî„"!€¸²‹l ÓcÓ"iëÁ^'Ýô5f÷M^_þðCyÐäÏwYþÕ+ÌgšO±åµ˜BíÖeñ•{)¡àÊèv¯³õ!IŠY¶wsÏž.7åß`ิœ3y¨ÆÅ•,uò¸úÑÑzlàѧ¬üû9ÏZj?§F–hõ8èc=Pý*MBÔ§«ùLL±÷‹éýQ¨V¥$ÓÒœE׫E¶»+òý]‰æûb»žKìO! •ÏÒ&Lhñ…i§>†bÍ”¶e(–Š3¥–‹Y©«Pœ„@üê(ƒ.ûÕÇÄP˜»Õ|·« Z©iEéÝé0-%“6 >0(7Ïæ‹§ò¤ì~«ùrãC\p,Ájà“ü~R¼s1ùèï[&XÂdkÀóØ- ôçùÝCi§Õ‹à¼Ñ‹üùc¾ÅYž<ÌÃv}°ÅÜß6åÉí ™oî·Ç¦±]ÅÃS^÷'cüã6÷ž„ aÖ@w(Cž=æÁêv¿Cšð—/?ùZÃ$«}H¬ä)ß–¾bàpž'¯J«ï³]1Ï ¬@¥¦á즮­OÉÿmŸåO/ È&…./¼jOxõoËÕʪ2Á?0€-ÿ7Ï>ïu¾}Ìòâ©iã$X;•èfÿ©éë„ÀP© Tôjåv<ɳUÿŽ+(9TPRUP2½Áš¸. „ê¹)¶Í+zúb±øõÓÚ©Þgë£kzúá4Ì×Y¾Ü. ¹†xˆ×²Å«NŒøLƒ‡ªr ¨,öØ:„OŸ`q”Bÿ_x³®¼s¨¼êÁ;ËÛö-¿K­–Ö‰›~Øœ¸œ@E´/{'²S Lt(ä ÅÀñï{qÚr$^¶ÄKb³Å©j¾ªl:Øqqæöòú´ŸJY7ý×úÏs‰ppÀá¹Ð¡ð Îðr»ñ“Ÿu3çQbL°)‡<=3)Zmïïˉ¨v‡¢âIcz g¡ðÐóŠ€â»2{° ’;]o•[½½è¾”o²âüíoŸd9äy×h4ßýÁÄMm±s`Ç^õ®.x* n ¨|è…á.ÜâñC9@Cs[˜×øh]g/æŸVáîýòà.ØÆ™4Ç®ã¢,7û°)µÀÁv_ÔóbÆò§ÇÌ›¸¸º½ø3Œ[b’¬AØ Ìü„’ÉÝúâã|²€{à‹©ÔM¾ù”kHâ˜ðSÝÕäæâ·ø6¬0°b3@öÙ¨–lÁ„_I¶t«7eR¿úKtZVÔËzeu±ÁõR§*$ä³.‰¢AZÇ <¶5¼Ýœi—®eSÆ•¢EsË ·m-¿ž…¤+Æðè¾§qºŒpíWÖ$θd&‘$ÎTÊÁ–£qf8.[šq¦¨8<ô°ït)³Ü´ý~IèùËÅy”b¸F”tbÛ®ëYçÏ?‡qòL%TWÒaMH‘’8¢Úð%Žq«ié„¥À3ŒÌqàh¿ë)‚㤦ã Epq@BŒn¹>RŽƒåy’FKéR$ÌYC#‰hÓd K1 )&•ô %Ó¤t–EFt¯5EM¯(¢{ÖŠÃ}=Ôs ÍXÏÝö F3Džƒ[i U²«Œe©{Þí%w>H+Y*Úþ‡G‚§JjžšRð4Úu0!Œ£E´áÒÆuE t¶43a¶ÙÙ­éA*‚„:$5$ ˆH<× ò\4Ús·õ5gŽkADž é˜Õ)‘ èÜMpK[*{¼•×ÃNç5;Mçà‰àP`‰LÛ®»¡ðï3!p³¡ ‰/ò|þÔƒÖh]],À„&Nh&YèA*‚Ó©¦ÛHEp]vÃ\×ÔŒvÝmq0ÏYIÔm 52Ì8â67Љ$Ø2L$ÍWgCç)†œ0o©?¡¤ŠXÏH±Æëêpƒ&”£m=QmxöXõ*Cd/ÆöœdNŠ“ì=ßì¡/‚ Š¾¦žï /‚’š¾~)ãè­«KNR‘Dц§ÏZ˜F÷«¤ñ/OÉ„3]½'×}pÞC\ÕøÙñüøÃuXÓ5±Ñººx€ ë$ 1«aP£ínI˜N eÉKI¥AÁªVõÞzý¾D\Ü×p5Ý€+‚ëjr6ÐuÍÏh×ݶ7p[ѦôTž•²Ä)2?ÆG­4N…OýnM=œ×ô4½ '‚ëšža®kzF»î¶<˜0Ž6µ§Úðô@CjIÜÈ’PØ€J0.†NëE¬€"ø—J1guÛÿùæÝvsß;ÈÔ„EÐVÖÔ6€°Ñ®»t€ IŒfÂó% ã qú.s Ô!~g`eµ×¾ÄWÿRkh”¶ûÔhEU£ÕÔ5­Ñ®»\ Bœmx¸¸„AŸ¸›%`èKavÊa ÅÃìôÃcçEÐÄ"¨¨CXSEŒA[ÍYSÛÎF»î2‚¯@Iâh9)d°Ž¼)¯aª'Rux¯±óZñYÈbH¨&Z- ÏO´b¸®Ö€-×Ä5àx]8ж<0ª ¾à#ˆïWÁ #êø®­7/¦÷ACØ×jI¿¯CI \¿”qÀÖÕ…_¡´§Œ"107¤=¿V1I}£ÆÀÚU‚)ËÜé¯z`£û¯†Ì–ÿCfiÕˆÙ’öüˆ9Ús °Ài[D.Å–¼¦tmifxØ×9þ¬¥‡¯jÀšbA¾£žÂÒìm¨©‡·ÑBº´€‰„øAÕ†GN9fÈT8¦AŽ–Lèú®ã/¦Î#ABXi¶$Wš1dÕñ¬©k@<íºË˜PÄ)¨6<_Ò2ÉéÛdÆŠr»,5­ Úá“»À"h¨&hM ß1A‹ DÁ,F õœ”Áѵ†n´¶.0`‚sâª@*‡öš*”qU ðõÿÅ>¯>@8þ°òSV~zÙƒ^%Ulk*¡Æ¶²ê‘´_×3#éh!]`à¶$~ AµÐ¥)´ç½©ƒ ë«Ïz>çí®¦Â®©†ˆ]Tü†©üÆ*ëm—¿ø š@e õ{K/W _õÃ3߇Ÿ…0‚œ@aS ¢ªi]SÕó³ºÑŽ;„€chk§á>íáA"Ô̇“t½Ù¤iýÜóäÇúçñŠ $àÕÔAÄ+‚¨ ¯¦ªçñí¸ÃF" çÓ– Dˆ—I™5ÄGøKA°¸Çm¡ê÷âüjÄyÒ"h ¤5%I‹ ª"­©êyÒF;î`´¡­ˆ&üI$@ õ »‚¥©šÎ\æÀç~u¤ç%èBÂú´©cüò4‚ŽêñA¿QOF«êþ"DÂ5»¯~‘«úû|?¥Õ endstream endobj 3662 0 obj << /Type /Page /Contents 3663 0 R /Resources 3661 0 R /MediaBox [0 0 612 792] /Parent 3659 0 R /Annots [ 3660 0 R ] >> endobj 3660 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.922 554.538 218.312 565.442] /A << /S /GoTo /D (subsubsection.6.1.7.2) >> >> endobj 3664 0 obj << /D [3662 0 R /XYZ 89 721 null] >> endobj 1406 0 obj << /D [3662 0 R /XYZ 90 690.045 null] >> endobj 1410 0 obj << /D [3662 0 R /XYZ 90 595.734 null] >> endobj 3665 0 obj << /D [3662 0 R /XYZ 90 417.516 null] >> endobj 3661 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3669 0 obj << /Length 1996 /Filter /FlateDecode >> stream xÚ­Y[oÛ¸~ϯУ sIêB1X,m¢‹"é&ÆÁ»û ÈLbT–|$ºiþýÞ$RvS§ÎCcqHçòÍ𓊣‡GÎ~_žýrÉÒˆ#žÓ4íëŒâ¸]¯^ÀÙ«OÞǨȠ‰ž„³uhœ¥ Jéi0KRÿ@C; Évk‘ö¸N?œå8 ÿ~ìœ~òãN°óÚ“÷Ó(= 9§©ÐÀIÂy~"rTcU)ʳħìä‘ó§Ðñ?:opô€ãްóê£÷3'9; =¯×áhö9dˆ ¤)M£Œ(åÔÞb6Oò<^™;b] ã¾êÖ[¹n#øc*ê•°xÝa/¤y­]Ei¢.ž‹ÃZ{Ñ™ ±›ÎÃÆh,\ñûlê€ÅÊ žÖòÑØ$+sej-T–£91NÏmÒ´ÓU»Ù”V@ãzÝè}$noi\Ö}k¤ýn»m;Ù[¹ª²®…}þs'ºç…1·‘ï˦õÇëdö-×V‘§ÄN¸ë…'d00xÝHÑ• œó Ô>añýÕ>Ó$o{#ÿ2#âg›qU—}/z3xzM°ÅUi¤ÑØ?÷RlÌôÚîÔö:ìêÉO±ÞçeËìQ}Æ,-eyWööLõWMîy_a®Ø¨0¬¤ÊHaßCd6'Þ|4ŒÕ;47i]„÷ß|Ô‘t9WÚ=ظã~Tæ–”µŠì“úS>[™.õ Š@ý^_i>=dþ®ÿûNÂjãÆþ3köPs¦Š¹q@ T›Îp@«;íúJÕ¬‘Ý·uݪeOº`V!TŸg†Vòd¶ä`¶z,»²’º²aÂĸ«×,õLL{º3ЂnÁ€a ;Q‚&¹”å© •wÃr[ø€iZx"(W;ÝêëËKã¿´Ómje`Ó°íjÜUVUÛ­¾ã¡Ó¨Å!òØâH¦è‚Æ …ùõFèúZ”)%Eêºó¨dC3£EwþLi~F A&R’ŒêšrcŸÚ{ó+ÝTPŽ XGäwv¾óá*PcâQA曳Ív'ƒ@[F¹n„Â`–ŪO/d£ Ý6­*WúÒ­›¶Ý ÕþÒËÞZöž¢]%5lTWq'€K`wè:6I÷]»™¨¨ÚfСí>é6·à>øõÕÜGBƒqŸD`6ÁÆ­oÃìxåÁÀ¢¤7#ˆ’yNUÐu`¼-%¤¨ùg¸‡?ÄHÅæN¬VºçàRü%ýÄ¢m×V¢ïÑ!X€S¸o;ñÕ‹rkâÈ3 O{oYÑf[‹ Ü ÂѤ&Ø21  0ƒ²³«<œ9M–*¨¸ÍïÝ­kfK»‡È<Ü|0¼ÊŸÑD ÊÔ‡Ã(— f\#Á‡¾)sF¤¾ä-W´Lsk^#¤¾?Úî‹áX@]àegdõ© £‚¨Zù$„TõÂä%S m©rŸ†+‚ÓÂd\Mؒ瓞ÁC6ã!àZ]ï6ñlxêÎC v±ÌÅ7}pµ“CÕúJé.OG2†5à®ëßµu¯|©ÿ~ÃXñµv'Ý-Òn·žQv_ ÓV2ðèiCɦ E3àwŠoþI½Ø$)·å®kìŒæ' 4õ¤–jÙI#Tô¢·"&%ñرm¦Ï€l( aẠȽî»t1û‡OÕx177IVø£<ŸÑ«""¬h}RPCÓ+`:ì*°JS+˜0†€ 0&‚.cHìÜq›Á0½Ï”3̾¿,ÕY«Ì”¾­²ö ‡ÅéÝÀ–3žÄW®2:‡ÖöÞ´h¶Ú=ÎÝ´Ò•€ŠÚ¾úIQ{æ¡kIÒPI¯|`ÞË¡ ™¦Ì¾ 0 !½Ôâ×b‹_%ÒeÎB ®Æ–41E¼;#Ò×S ûp… “(@¼Ë•’5ßÝ}(ßÓö2´Ížeõx¸-Yýä†9u/‹>jÆw‹‘?7²üfžÏƒËÌýF$SŸP0Fíþk5ö%eÊoçç¿2ñ7ûí É'ÜêÈ|"ø²×ƒ’Ò ÏžwÊ¿ó¿u8â1üâ÷s’sD8> ¹Fà2cöƒ„0ãQ‘B$‰G,Áà M0PZ0(/TðdˆÑÚz~W—Õ—ù]ûmúÝ·{¤ÚùìÓáìLÓì¹ÿËC” endstream endobj 3668 0 obj << /Type /Page /Contents 3669 0 R /Resources 3667 0 R /MediaBox [0 0 612 792] /Parent 3659 0 R /Annots [ 3666 0 R ] >> endobj 3666 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [447.043 302.861 453.22 315.625] /A << /S /GoTo /D (Hfootnote.13) >> >> endobj 3670 0 obj << /D [3668 0 R /XYZ 89 721 null] >> endobj 1414 0 obj << /D [3668 0 R /XYZ 90 527.957 null] >> endobj 1418 0 obj << /D [3668 0 R /XYZ 90 478.702 null] >> endobj 1422 0 obj << /D [3668 0 R /XYZ 90 407.593 null] >> endobj 1426 0 obj << /D [3668 0 R /XYZ 90 348.44 null] >> endobj 1430 0 obj << /D [3668 0 R /XYZ 90 253.422 null] >> endobj 1434 0 obj << /D [3668 0 R /XYZ 90 182.313 null] >> endobj 3671 0 obj << /D [3668 0 R /XYZ 104.346 91.432 null] >> endobj 3667 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3674 0 obj << /Length 1894 /Filter /FlateDecode >> stream xÚÝYKsÛ6¾ûWðHÍD ™››8´Ä‰=mg’(¶™P¤BRqÔ_ß],À‡¤8vä^z±€Å¾÷à™wí1ïד_.Ož¾T‘—i,bïòÊK™§X°Hz—¹÷Þ?=??{ýâÕß³¹Ì? fsɘÿîìåÙ»³×Ïψ|>K…ún3ÿröñò·§/¥éŒP¡ŒÁ¢Q)˜B¦f˜ÇyJö¹ãŸ :BëH 5›sæ/o4þ½(K-ëÕ*«òÖ™7çI'¤æò¦hgóPŠ^&Üo»zmé*ÇA®gBú_‹¥·ºù:ãÒ× É¬›z©ÛRóØUµnrb@MY7ÑÉýeYèʽԅ1a´Zóý”YÛ‘HVµ·NãUS¯«‰Î¤ŽÂù1ÿ å¦31³d&m—5]Èg£3»|{S,oì°OsvÕ¡/#‘ö¦n:æºÌ¶³X:»ŸA¬uеã’jÄGIÅyŸTSÈ)0 V‘’'"’]D¼Ýèfû׌'~ñOÖäÏ!íyƒóz­›nû3h2g.Êu›¦²+6´Ô/‹¶£õúŠ(Œ1úIVè~81äúc¢Ò9ñ]Õ 2Z^¢×D`6Ž­¨h¹·8Mfº“ÌÄ%spf~3CZnMÎÐ!gþKÔTÛ²èÌaÁÅ4ªsáPTe+ýd‚Ž\·Ë¦XwE]YºC_Ïp5cÙ¦´ úŠ!eåÆÖÓ!—R®óû#ý0^h ïë±ÐÕhSᤇNhÛÀ *n ”ƒÐÀ…4pj ƒÌ-š’b=>pŒø™åûÌã¦úÍv}™ÿoÀàì 2.6 ‰¾5=°IÀ04 ˜ M´Ò–ªm02M~ÛÍb> ñàÈ«5´WmU.¶ôk“£IþÛš}Ek½ÍQÙ¥ô¡Š"MýS˜Z'~NvÓžú›–ÚSä£ëDëj¢˜„~3¦—›Î Ø$*Pž¦"+úx=½m ’Œü¬ëšb1Ìe;òÃÈ$ ¸ëʤn¹¶î…0m›Ñ]ÛbÅs?daÔ ‘PÞ„²–a K½2ǽY­ˆHnÀÀ!—–[ˆ­º¶²¦É¶4¤³lÑ4­Ùà‡U´­ºì›õäÊ:beÉÌŒûÕuïò8ʘ¢$Õô $ ¡¸}¬³MÒ®³¥e&ä+áÄù>¸`U ËJš+’–Yk¿; é“ Á|8ØÐ Þc ‘1ްii²i‘~ ŽØMC±ãà¼Z…еp14åD¦ª¶„uݶŢÔDF”âoYTŸiîYûzíªåÏ*ŒdkUB P Χø’RѽVÚ –Ð( Ìšõ˜>2 xY*ŠÊ6ͺ*·;³½ZÙ¶}ß¶ÊwÛê–åwk]–TžŸ¸yÝqgí]_ Ø+ì=½û^×ëÇwÚ<.Ëçp×çÓ<³øt¬× y “,7»(1€CBeÐqK“zñI/;›Î–¸}{È%tÝØÇ=;¡„‹ +†9Áƒ€‘nש¢Zo:’^g Àž#Öù¬9ø"Ò«…ÎssEÃùˆcÜG ͼ}\×Ïž½ üÿ9ãõýQW×fGR?F©<ë2uÛµ´’2Óú‘TÖX†©]Qê­IÀ¶}Üì¡4AˆÁE¸G·¥F?3¯é³Ë“/'$?á±,O$‰ô–«“÷™—Ã"(Â4ñn ëÊÀ*£Æ¥wqòö¿P’ å *äw)qÀ·:Ì·‰ l¹Šàú.„\QnžwZŸý”ˆ„yü(Ž„°ÎÔŽ#çØÖ{ûÆ•Î*Û§ÎD¡áO8s < C†âȃñãjÌÓ$H“ø¸§*ˆ9”‹‰@*ûí§íïþïÙÇï—ö1쇲©ÔÔþ‹ïœ‹‡‹úp7öë:T¢Ž+êÑJLQ“8ˆï†×½‹ÊSžî•ßUÔG°/ØMÅÔþw‚álZ9Žðˆú Dè^)0´W&»§‘2}ˆÁœißăC8PKÐ…á‘€8V‰ta¡ÒÇ„RAË=@ˆ»ñöáä5:&öÇ€øÁ° j:Xrd=ÔaʃŸBYÎ$àqº$ÜU¥³¼gÓ~û!K‚(ݱ?¹a¯uSÔö’PØ/N«‹;*ü`¯Tt(Yâ‡+qÿWaãòLëÅ¢  ÎÒ ”Ü=L ”ÃÕ^Æ}c”îii¨ôÊ‘î᎔*×k ª÷"vêâ‘:IÛÊPuÒôÜуiÌF]WN?ýÐ2¹¾ ×eŠhzmF7ÓþûBŠß3ÐÉÌ8™ûvÏÓÛG¶Z[²yûãÀ<> endobj 3675 0 obj << /D [3673 0 R /XYZ 89 721 null] >> endobj 1438 0 obj << /D [3673 0 R /XYZ 90 690.045 null] >> endobj 1442 0 obj << /D [3673 0 R /XYZ 90 632.72 null] >> endobj 1446 0 obj << /D [3673 0 R /XYZ 90 573.567 null] >> endobj 1450 0 obj << /D [3673 0 R /XYZ 90 514.414 null] >> endobj 1454 0 obj << /D [3673 0 R /XYZ 90 407.44 null] >> endobj 1458 0 obj << /D [3673 0 R /XYZ 90 360.242 null] >> endobj 1462 0 obj << /D [3673 0 R /XYZ 90 313.044 null] >> endobj 3676 0 obj << /D [3673 0 R /XYZ 90 226.084 null] >> endobj 3672 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3679 0 obj << /Length 1861 /Filter /FlateDecode >> stream xÚÝZKsÛ6¾ûWð(ÍÔÞ$}s§ÓN›¸¶ÚéL’-ÁSITH:ÿû.^$ 1ªejzèÅñøöñ-€]Ñ8ùœàä§³gg¯Þ¦<ÉQ.©Lf÷IŽ“gs‘ÌɇÉåõõÕ»7?ÿ5=§O.Ñô\`<¹¹z{usõîõ•í¾žætry3•x2›~šýòê­ &×€B‚DIq¦'a§h€BP.`L?÷óÏi Ì)‚RDøôœ`?[*+ùF­ßß}¹žR<©V«róÙvÏ«õºØ,tÁÉ9ÉÌ,èlY6™÷+ÌK­ÖÕ”ˆÉ7ýG¹ÅÆ>«»/jÞºö½}¶ZÝX•ÍÎÐôR‹piN¤¹3bOv¹Ù>8ˆEÑÿiëæz}ÝÀlšiÍ>WoÔ”‚ÊN !“¢¾mkpÇe]OÚ ÆpãckùcÙ.­¯Úe­œ7³FëLjѯ‰ìËZ›ÎÓEí¦\N¯fg_ÏF’SÄóD‰¤Ì“ùúìÃ'œ,` ÔA,Ï’G3sPàSh®’Û³ßO!3ÀÀ "aø0tfwDÑC1C§€•!‚‰u¥õô¾ù”åˆ ~Á CôS þͱ'™€'ä’÷=ŒÈQäa@Å(òD–£4åB’g(“29ZRëBØð§ïÓwÑT‹"Ñn¿–s·6ÅZ}ŸÊ£µØ£A#ˆ”Œar,„a2M?Pϧ2#cQIQyÙ” $‰e¿ww‚9OÍY­[±À)eî|×M;PÕnô-è}§/°‡VéXEÄÁÑ&ì³”¤£a$„ )†Ûý$ áN½Â@ ‡á²i›|Éá_6ôÑ*ì³ 9XÏGy4„ÏÚp˜BƤÀ•‘sp2Yî3-³)D—>Q!»­"g¶·llß¼°éôlj«àϦչ •NpÂ:ÜôöpÂìÂ.ʧÙ}(&Ñ´Cz’߉9Y‹¢ ʨÉR¯&´¬’…U —]š9|xñ›ªµbµªô]ð¨Ì mï.´I0­ŒàÖÀVÕüï)$m¢“Ö­Œt¨Õ×Õ´ªîPrD« pé­n)ö3 oü‡l¢§ñF3Ø!Y¿‹Ýüýí"ÎßMSÕeµxI&ÏrÑÛi^–+3"­ºwëkóâ¤éö½ŽÝ(ì£Ùªyùcª†ð›ra­Øéx={[ÔFàe§šN–ü¬Öwj±0"´S!3× ÛZ Êdù¿V›Ïa¦oVÙºA·ìó¨¬Ú¸®Ue\-°Vè•¶*Ð úª@0kthƒt»ÁZ­) ­v%ÂPq S”Ò,aG2§O ˜*`û œb§Éiš°”ÂÍž»Rù9, ùºã÷uúÞ¸à0&p·ŸB¸bNw¹Öõl'?*æöï)÷SÊ^ Ì=€ÁX>’c Öñl$ÇÀò±IGŠ$ÜàLÄÜñÓ|ÓÛ²X=¨áZÂ3{ñŒ2HÂÓHü3k OéÑZ °"ç#) b(…„œóÓ0ÊsHuä¥ä¥ãÅÓ# §W$þ?()|8kÁ‘AÇÃH  Œ!œÉÓ“H¦l/è¡`8|¸rMóXþ3ê ÏæÑ* PÁ(ʲt$ŸcA ¡£”ÑÑE"G;–W¬žy`Ÿ@¾.ÍUÊߘûÑåáo×Û û5…€¾¥o~´Š\†`l$áǃ<¿˜Ôg$Iÿ×µdN½šÐ kIκZRÏéäëi•rݶXƒFÓµköq•“Iyo;K7èñš¶ÚnÕÂÈ‘Ë)w¥Ä5«ž±*m¼ßƒr±“«”MP[ú V— >cîVÎÃ<:¬`”SԬ̚©YånÍê«Uµ€´‹„¦W¬RÁC“8˜Ô>Ô7âôç]ˆqóII?còÉ㲜/mÓ}Žá‰p6¹*üxÌÜ.¤L²Šâ$™Ü=Ù§Å•a$IGtöÙïÎZhy« ¹,ü¢Ö‚¬TÑ´¶Ë”³;RˆÝfA¼¡«÷ §ŽTèµîtkø·bµ]wª-çùOî«XU·é™”î’ O·mÑ>4/Ф,Ìϲ ’`¤°þ0€—ÆË‚ÉæG`b÷£Çܾ÷é3¢;0aÄýÝ••S2qhe,>"Þ5ÑÏ„ç€Ï}°²Ì/æiÃÆó‚ÕLíÃS¿Ý™^Ò#õ¿Þdö ‹äô¿e´s›nÛߊ ¡ÌîòsÕbÈ”ÝCÏ} î“úèlóÉ|œÈà â¾Ì¾Õqã')·¹ûOÍ€vÃ(Óh‚€óççEôiîvÄ¡È<'Â0÷Ù* Ïú`þ) ‹ëj(Yí&cƒÆÓühßM”´ ûd©«wö„fc…Ö]Ëòr¯y½÷·ÜÚí2öOHÝþbJú! endstream endobj 3678 0 obj << /Type /Page /Contents 3679 0 R /Resources 3677 0 R /MediaBox [0 0 612 792] /Parent 3659 0 R >> endobj 3680 0 obj << /D [3678 0 R /XYZ 89 721 null] >> endobj 1466 0 obj << /D [3678 0 R /XYZ 90 690.045 null] >> endobj 3681 0 obj << /D [3678 0 R /XYZ 90 616.868 null] >> endobj 1470 0 obj << /D [3678 0 R /XYZ 90 473.909 null] >> endobj 3682 0 obj << /D [3678 0 R /XYZ 90 384.892 null] >> endobj 1474 0 obj << /D [3678 0 R /XYZ 90 229.734 null] >> endobj 1478 0 obj << /D [3678 0 R /XYZ 90 158.827 null] >> endobj 3677 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3685 0 obj << /Length 1720 /Filter /FlateDecode >> stream xÚÍYKoÛF¾ûWðVé Í¾øØÜÜØ.Rc«E'šZ[D(R%©8þ÷Ù‡DR†jZ*ЋµÙy}³;Ã1 üvöëüìÝU,ETÄ£`þ(Ä4!T†Á|ÜMί¯/?_|ük:ã!œ“é,¤trsyuysùùÃ¥]¾ž*>9¿™Ft2Ÿ~›ÿþî*䞆H4,9UHtFþ7˜ ÅHÄ’`Æc8,,ùWÎÃ}pgt˜/µ•Þæ+7*µ^è…¥!ÍK;^ÝÂŒÙñCU»cþ|‘6­eÕj•–Žž²pòÿèlÓæ•ãå§m[ç÷SN'›Ö1ªuºÈËǾ²4˜1p_c`ÞA'M^fnq‘¶©]4&!ÙÒQÕ(Ñ,Ye¦<œ<èÚî.ÓÆn–UkWîµv,6k`«© ÈiZ2yjì‰Ô.gK}·+ÕÃ@‰uU[=Ú%:âí^¬ ´‡Ö!"â zûd´7ËžÔ‡£ZgU½hì$/í¡-uŽŽ à ø ’ÒùIº>À¹1~Ë ]¦í€»÷$DF fDAԃ׺Î+XÆÏ&\šµÎZ°÷σ¸Ü9Õ¬¢SIßi3/éÕ¶ëL¯w1½Nët¥[];Íü½ÉÒÆ2ˆi^8~àÙû:e@”ÚÆFDФoô¹¿ÿ3'"/¿l ö£ë¾ÿó²ÑõÎý>¸Œi¶t®Éu6ðA^²JÑ:b_»˜lxõใXç ᳺ‘˜°d:c´‹Â§*û~a¼õ#÷¼'÷_P¼> ‰GwU9ïø&°të©ýY80·owak¤>Æ`²®«L7y˜Su($/×›Ö‘w£…Öî€^Ýë…}ˆaö”·K(ÄŽºKáPK­Ùói—Õû÷Vá?§ŒÁ¬?Uåãm‹÷¼®Sw?Ü[ˆÑô¼vžC$zQùÚ؆閪1ÜÑbÖÇùÂÕ#ß›ëu9?ûûŒI€}À)H±©Â [Ý}£ÁöÀh"T<ÊUÀ’¨ÏÁíÙ—ÿ€GLU I„d‡˜øuàH‘PEÇ,8À x ¸õkóo`Zlôýv×È\0Žûò/ºO>é€ðDG«±°`ÑQˆËÃ@Æ„K~4¤ JwQ’pe]Z¼ÒÈGH)“}ù˜ê,˜N‘|‘·Ï@­È> À‚Jq¨ãy ¿hìçU¯8€ï+‘$„ѰS¨auðGù¦ú VÝ©Nq†“MéJœ¤ögW"@äÊé°wÔeDv3¢aT»»´3—ö»²^Ÿè»Å‚« ÿÇi_pI"u\´ÍŸÁ8 ¡6>EÚPg3__Mû§Pħýž"oIûã•ÙGX¡ŽC˜‚m29a®b“Wç}(ò‰HF¥ýSˆ÷i¿+~\Ö¯ÅÈ"Tò(@æa )O’ôy¢åѨ¤ñ‚+K:â¯ðžVµÇó+¥"=pEG«±pàGâ9šÅ‹ù¾ç~V`œ$QäÓ3º…Jü7¢¡÷Y^w8öûq°ÚŸ¬ÈuÙZ’¶²k6ûcv©×ÀÓ¶Wž-¡†h¾ÕaóÞ­§eÕ.­|éÛv‚mUÛF@²ÅÊ}ÙϘµ³÷}¿iÒGß;)‹gÓƒ}]¿„ÓaEt£ûQó––‰ Ýv•R“ZϬÃpgç)lÈ0qíHº­ p˜ÖS–L7+ë|`â9Û¦ ,y㈱e4`mI0ܸ×}E Fºš|lÁޤ㞖–R×5ºß¬^êªlm2u‹«…ïëÓ2÷ .ß ³ b<² SNí”z%tl ñ»mÓvó6è€Å:œÔºÝÔ¥ÛÁV1‹zfâ2jo›¶0iœl÷ãïÒQblÛ iÎw¤zvî¥ÙiL†â1‹9v茰ª6­-9eÜ/9eäÚi°Ñi§ÁÌ×Õ8N-嘜r…1Œ\%í¸ZfØhv‹¶Jnœ, Õ°,oòŸ»Â{WPû¾q§¯_ÈèL Ðð©•Ä»*àO /¼Þ§â‘’˜ÅG¥CRøl„O`E ÉŽ+Ÿ¹¤æe'PcÛ4ë¨1¦x†ˆ0ÁÇ«² °Àb0üúõ*Ü‹ endstream endobj 3684 0 obj << /Type /Page /Contents 3685 0 R /Resources 3683 0 R /MediaBox [0 0 612 792] /Parent 3659 0 R >> endobj 3686 0 obj << /D [3684 0 R /XYZ 89 721 null] >> endobj 1482 0 obj << /D [3684 0 R /XYZ 90 571.699 null] >> endobj 3687 0 obj << /D [3684 0 R /XYZ 90 496.694 null] >> endobj 1486 0 obj << /D [3684 0 R /XYZ 90 402.053 null] >> endobj 3688 0 obj << /D [3684 0 R /XYZ 90 324.892 null] >> endobj 1490 0 obj << /D [3684 0 R /XYZ 90 204.184 null] >> endobj 1494 0 obj << /D [3684 0 R /XYZ 90 145.031 null] >> endobj 3689 0 obj << /D [3684 0 R /XYZ 90 58.071 null] >> endobj 3683 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3692 0 obj << /Length 2493 /Filter /FlateDecode >> stream xÚíZ]sÛ¸}÷¯àøIš]#ø˜·4q:É´7ëítšfvh‰±8•H¯Doêß{")†MÎô¥O„ðqïÎ!€{(ÝG4úóÅŸn/^½72ŠI¬¹Žn¿E1 µ„JÝ®£/‹777ןÞ}øÇòŠ+ºxC–WŠÒÅçë÷ן¯?½½öÕ7˘/Þ|^jº¸]~½ýøê½â › * IÎ(vº !ˆëÛ‹ß/iÄ"&ÑÚFÚRÂ-‹V»‹/_i´†Æ%"¶Ñw×u ¦ «€ò6úåâo#hK7CF ;#±RÁ†[VðÌ¢‹´aÄ0é§pøcÉÕ"Ù>¦_èW7™Ö$¸¤nÂsøÄmÿ)VÿÎò{¿ú‡rå“(¤Š üQôÀ¡ ‰¹}9³q˜*EŒó` +$ô ¤lÒÜsÍaTËýÛ›æj›¥yéË›âJBk²^ïÓÃÁÿ(öþyù©ÝÖé¿(åyº¾ Ãèô 6ìÓè0Õˆ£<%Ÿ‡ ÒJOéÀ‡è0Ý=—šp!Úî?&KN>íßÿꟻ$Ë+¦$¾UT8×äÓ 3vŽ=PÓó‰t™hñE0BµžHI•`K­„Çk{æ0ƒn ±²ã(à)’ûª¬(óÅì›n±#£‹tý³¯ å¦L÷ß³B±2ŒžA’‚f"¦q|`U>8'ê.O“üseˆ`¬íÊqBŸÝSjíˆ2zj=ƒ ÅÄD¢L5âˆB5*ž‡(êªûõöÌsfÿxíà°-ÿƒàºß¿þúá/=$ûÀö#®Ô¼;‹"£'Õƒ.Ø`Ã6ΠÈT#HK8¿Õ,Q±!*æ'™Ã?×ʦíÿeáÛÊ(¢ŒŸÚ)Æ*˜¨žF”ÉFQ,ƒƒ›ÍC«àòhOˆ"‡ˆ2ƒÿš(Mÿ/#Š˜“(£§Öƒ1Øjâeu²GÉnç!ŠáÄZyB5D”ü×DiúQäœD=µŒÁ'j"/0Réf´%âUáò â)J Ó,¨xÄ@î´¼b”ÒÅí&õ uý‡[¦¼üåñî°ÚgeVäo7I~:¬ŠÝ.É×ÇdâíO?Í —!„ ÌŠ|ûT%Ðè na:ì·› ¯œ1k8ˆ!E •‡tíKI¨I|‡‡,]¥¾¦øæŸ¥› ´]nR Ê]š”—¾åðt(Ó/ߥå÷4̓±ÜH‘~0µðd §º,»n!¬à‚A®ìFdU °~¸ã™›£'Œ›ä}š§û¤t*à›ÁBË/ꩃa4¦{Áë W“Åò÷M¶Úøâ& ýžwFpÞ3Í § b±ø€ëfŒGÑØ E¨¹{ò5¸ž¢A c‰U¥ ¿Kq¸Æ7û¥T‹â?O¯_בüæ[!l$ã¸Æ 1Œ¹¨,îÒrS¬}S©ÈS_ãxd¨è²ÂµÁ"Ñê_S*ÙÚÍ0ºâpŶ̶— Ñã±^d9ìYŽ™`gÉž_¦É'ׯêï7³ôÁ÷r@m“_ø»Ë¬ó{c\… 5IYÂBâîûX¦U8þùûczÀ ð”2öxBõ>ÝÉúбshì-ZýªÌvnV.¾g寗üh(¬÷{¿jX ]Ñ'cnCªã‡¦däEè\1loÜ[ímWÃ(ÏtçÎal6i]…—å· dÊ=lgáÐÙe9¬ß©Ïj–?<–õ±•õÒ}H®!¨×§Ç’H+"a-pvXÌ€®TȾ£d.#ÚòH=]^‡ûƒ…tJXzÔ·›GI½8=w”uÌ,ah§F¶Â¸A‚ÕÞ=–i’÷?Ñ–x‰ÇÇÒƒ ØxNë~`¼ËY1`Í å/•ZËØ‚› ïF7»¸Ïò~4à:ƒw8Œ`-MÛû»æá ¨æñ¤£ÃèAC3X„x"¤S8HeL´Qó@ªáÕµñ)€tï‚¡ Þöþ¦sV=êèHzrØÆ¨N5âP†ÎæAvä˜Ú.ª|ռ㗠wœ¯Ü•¡Î(.ëóø²óê1Ç&×òƒOì£CíA l°g¾.=ûT#v.]Â< ìÜ¥dv1û Þ9,•¦í½{¯®^æ#V.ñ¼ Ÿ¥.Ò}V¬³U]‘ìW›ìhåòçK¼Ìþ¶*òoÏdô¤z°FÛ‰o¤7ÙoƒMavRÂÛÆÁ’¨RlÌú¨9fØø£x,ÝËë¤L|É%†T‡ •b³{Ø>ùr]y»´p‹Íï ÿÒHLC›Ïõ°t×V%Íç¬*ó<?ì‹UzÀË´´,ˆ!.—L1?¿ÖEšjI0ÎR-ºèZt©û«¦è¢¢‹éˆ.º’OT%ºè†èÒ£ôø78œû°Å'¾ ½ØHÍQ‚ÁÊ–²•Ó:„œãªPtÁš£è"M|<á‚è‚=›¢ þNªx‚Upíî¾*É •“³C!ìÊÍc¦lJèꌓ¡¡Aÿ§AMˆã¿9œë–1üX) 7ºïÆ1—ÙX¬]¾=éF*Äa!ü*!{4¡ê_mƒÚ"q:ÐS°”&1×ÓŸj‡ÆÌ£þIK„²ç©@ðœsÉádµ-çÿ(Pcô”NaÊðiÔo£«ýXTe endstream endobj 3691 0 obj << /Type /Page /Contents 3692 0 R /Resources 3690 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R >> endobj 3693 0 obj << /D [3691 0 R /XYZ 89 721 null] >> endobj 1498 0 obj << /D [3691 0 R /XYZ 90 514.109 null] >> endobj 3694 0 obj << /D [3691 0 R /XYZ 90 389.127 null] >> endobj 1502 0 obj << /D [3691 0 R /XYZ 90 243.711 null] >> endobj 3695 0 obj << /D [3691 0 R /XYZ 90 108.931 null] >> endobj 3690 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3700 0 obj << /Length 2528 /Filter /FlateDecode >> stream xÚµZÝsÛ8Ï_¡Ù—³ok.?õ‘·\›Þv§Ýév3w7×v:ŠÍ8šµ%¯$o.ssÿûeK²âÖ‘÷IH ~ @äÁ2àÁß/þvsñÃëH KB7wAƒˆÇŒkÜ,‚“«÷ï¯~õæ_Ó™4|rŦ3ÃùäÃõëë×?¿¼&òûi"'W¦!ŸÜL?ßüôÃk#[<524!Ht,¥8è‚{%úÏ`¦Å„ÁÌÄLÅ^“›{;)%'ób½Nó¾ˆI±­7Ûš:6i™®mmËŠúR[RGºZ¥nxävn«*-‰¾Hë”:ê‚(·SÉ'Ûlµ r‘[¢Û©4“?¦ÂLl^7úäÀ®ÎŠÜjëks/§Ì„f‰Öð,1~BóUæx Ý|°á4ÄÆ‚$esÿ^Ù’Ä–ô¾) œ½,mnË´ÎòeKGÝ ÐS0ºÏüwk›æÕ¥Cãúæâ÷ ð@ÂDL˜89è-£`¾¾øø™ èü)àL%qðà†®Ç,Œx° ~½øåÏ`¢L˜D²(RǘÀp².ñp¾ÝñC*f”^!ðL…—7¡=Š­ÇcçJ‡¶‘aÌ¢0>‹FJм;½G¸vòw8!¸ÊhmX¨Õ3”9Ä yØ FmÎD¬F‚Á†!ãq`'š…@1±`¡ðK®ú×CºÚÚüóhÏ _F¸äMWþ6-ë[›z/û÷»_üâ.æ¿MaeZßá·¿†ïÜìOûÀÉZÀE,–ÉHËÄù@³ŠÌy| L˜ ňc>pù2†UvÅ_ï?ÁNVz=à¡óøËĹ€QLI1Ò “–¡ YÂ#Â`õÛÀä˰Ç3§-ÿfã‘¿,ÔUvKÒ®lZù£{[YúíãWC‚§=âä9 € <„”#=b,皃e£óx„ÖÌ}àG7…3Èwg>»ò_õ }óêm×%žød•°8½qeâ–0Bèó¬$“ðÊcðžA:,6ˆvã¶ô_··Õ¼Ìn›hîǾ;‚çÉ: @<´Éeâð!}çS$,Öá ê ãÅ+IâÙÿ!­ýBýÄ ·]ÕÙ<­öù¬Z±€NqéS•ÀXðPŒz,4˜)ágBšGL'êi} é3ÈW¨bÖ‘ÿæoÇ#}²r(ˆLÅŸÁ¤_¡’Q£®ô5#­4䟾dÄ"&õt&8çTµACaÜ‹lý²È?q.˵ß7T9¡˜—rñÃf.UnJAXÀPqܪÁ 9!#'7Ì—Z°í*<0ª´;-·«´\ùayQgwíaq'èÂÏÚuìßÕaÜG÷6ótˆÓmi«š¾Êr¢–vn3bHé¼›šÒï,B4p_s,ë¸)rÞš7¼4DPŸ{)ŽÑâÖ}ä$½s‘ÒcÞûHÍÂË9§FeçÔ@Çž¸Îò }ÝqT]mqœë¤¡™«ºµõºµ ëÜSÒ?~ìXÂçÊ뢴X°âÚ;‘‚™æ®Ø'•èû°ë®(©ƒj_ÐØeZ;›ŠIÏé`ØÎ”ø²ÞV5ñ»õ\Rz]ãÊ߬<…OåTNA7ú¤´CR½Ò’¯Á‘â˜ä¥óûªÝ.¤9ô“‚zWÌóñE¾÷M´ÑaöbWlÒŒ¾: ü@APÂÆ~( [£>º“‰Ž5ôw¡³11q(‡E"Ç%g<Ãï˜ÅQ‚éÉj À<”ŽGb:–‰Ã”ÇàêãÊçR)Æ!øT0®Y--HɨßÓCø º °ðhërU×ö¹?Iõ·A|²"è@ôš$z$Äc™ ÄâùXŸa‰’áqˆåˆÏ ‹RÂ-ÝŽ.½rîqxOVâdj1Ýg0ù¶4@BÂ#Úi€é§W‹ÅÛb Ø-oð§1B‰¿/ëç$R«Vô¦ÛbáÉî-’0(u1¢¤øßV¤ «½OÙv‹£0 pÜ€Pmì<ÃPÌb@Ø'ûOÅƱŸw_Ï&Œº ,fCá¢?íeââ{ŒAÓœÞӲĨ›ˆBD › Ð`b£®VÔ’7Õ’›àùß½Ú_Ði10Tºe‡/õãÆ^^¶8ìôõ²,¶›ŠÚ÷ç(4ÒÐLVvÙ a|Ÿâ†H˦÷·ú®X­ Tëa—_WÌ9÷eçÊ@q’V1ˆi–â' îÖõÑ]VèÍí®É¦ðô¸êɾ˙H›}W§îï÷™‹Ô¡Ùr" )ƒŸ[F×’R4#ˆ5Dóu “µ‹®ŸhÌšó´\ÐÛwýÎ4f:LºF¥¤òÑífS”µËx¹O[œn6.«…&]z€¾u±pž;Oýeì,¨®Ha?Y/ÀæótSm]™ƒÆ>dtäæI7O†A<úqqX¶ÄŒ6Q쀣¤Õo> Amº¿<¼÷ÔÍ?“bÙ%율" þ—t¹`]_™56F2Ç=êk«ää%a.E.!›JJ¿"•Ÿ4Zˆbÿž‹¬*ê¢ i]ù¸˜e¼çØœJ?ò«Æ‰OñI{ @¬4‡”y¯O¢ºú${} Ù䎰w«Î½‹=ý|¿*Vv`WõîšÐ‹N†Ùô£'²˜¶DͰýqÒQ)bà¤Í˜…ËÞ£²“˜I™f¨·ÉküÀ­rœ6®ãnC½ 2F%º$CÁtöjT†Hh§H]š4;x–߬€DðÒÁøe#ÐÊÛµ;A€ÜU͸ŘVMZ2'xCÌxÑã)d(—5>8ßÇáW,é-‰ ­&°KضËN'Í k“hÐ&|`§‹¼;cãnë6+hmÒúÞw½AÔv§³@ß0s•5 묦ý­Íco¶¿L™8=4þ/‚¹—F9_sl kß {J±§¦Œø,Š5ÿå¤t­¿¬íÿ!& fâ­nB3yå&šÕ„fA2Oºâs™C$än¶iªL*Ó\s ±åJ‚Êáè:üÂ¥á­]À¡eÖŸÈ<õ”[¿{C3ïüÚýïã>¶“­"§”bÒ]1 i+ÐFék5ÐA@ŠßE×ÿ%÷Ì8„¿táYì¤ù/;:`]õ÷­­|\6 Òî+ÇבHÅÜÃ6xïR…ÿ¥ È1 endstream endobj 3699 0 obj << /Type /Page /Contents 3700 0 R /Resources 3698 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R /Annots [ 3697 0 R ] >> endobj 3697 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [370.306 111.755 386.963 122.659] /A << /S /GoTo /D (section.A.9) >> >> endobj 3701 0 obj << /D [3699 0 R /XYZ 89 721 null] >> endobj 3702 0 obj << /D [3699 0 R /XYZ 90 605.127 null] >> endobj 1506 0 obj << /D [3699 0 R /XYZ 90 448.717 null] >> endobj 3703 0 obj << /D [3699 0 R /XYZ 90 347.645 null] >> endobj 1510 0 obj << /D [3699 0 R /XYZ 90 259.117 null] >> endobj 3698 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3707 0 obj << /Length 2284 /Filter /FlateDecode >> stream xÚÝ]oÛ8ò=¿ÂèËÊ‹ZKê[òÝ&EEZ¸¾ -ÅVlamÉ'ʇûï;ÃJ¤¬vƒ»}º›Î ç‹ó!1ÛÎÄìíÅÏ«‹ŸnÓh–ûy$³ÕÓ,³Td¾ˆâÙj3»÷®?~¼¹{óîŸóE ïÚŸ/b!¼åÍíÍòæî—œçw½œ'Â[Í¿¬~ýé6,ž2Œ¸Q³ d€H‚… ÄLJ? ФÀ#dAüÔ’ùB ¸µ+éæeyhæRx¿ãOù¾Ùn«z»BqŠAÛ²#Äus8õfB:1[ÈÌO2º†ÆÈ0öð’,õšZ/ﳈEÓðд%ì%íöt3¡uxw†w#°žÚæÀ(;æ­Žåºú,DPn°)ç\_­ËžØ'uÌh¡1«úxêhy,ÚâPveKh•"pQ£¾ZCm^R±hÛâ+ „Òkžð_xªkIz€*ÕºØï®<6JKˆD ½b>ÔpõkG–æÝ×cyyií?D½m›ÓQÑúyW¶%1'£¬Ü—‡²îÔ”ô»bˆÁ=±!ƒÅS³ß7(Ö3) U‚½ºj}éDÜL&~fÀ `ÆŸƒ v±îu¬4½œ/Â$âKÓÔC®2² @ú£’öÏ»j½£å/°y,Y©J°ÒDVÁ ÿuSw-hYnà!†å+s×sµß¬‹vC»W?¾Ò¶Ëü(ÉÙ~ ©‰¬C‘{êt<6m‡Ž E¦oBpq<¢çq©õÀ³C³Ñ!º.ºª©ù°¡3 Êòe½.Žê´/ú;ž«nWÕóÜ1"©²%ç¶tޝ ô· o„蓮Œhõ¹[Kƒ G$ D×i5¸À:.èo[ir-G=æÈö#—¾9 cøÄן½¸ OÆh BŠø§ ƒ „…åf<¸0°RtDyaîýø´ƒlà¨~\¬£¾>7×çvB@FÂûdÉ“‡®<ù ,‹¶¼ätZéZ&©ŸE¦–ÀƒP;œHë¡€'ÞללbøÃ{’Œ}‘§m¨ ŽH©‘kp P$Ê9» öƒ<6¨l“[$ÐOÕ&Ã9áæê5¾‹hì%í‘EH?Ê×)‡“ÒÖuú(ðâ†}”˜  r_L2ÄøB­|:èê`W´X¿ÐB™3´dMî…B¤ Ð……ŬÝÎh±Ô±è×~>z½&°KbÛ¥—‰E¸6I'm"&Ò_Êጋ§“Î`°:ÝŽ›’¹Õ>ÔÖ!È›€ÏÞ= 9T%=›Ç`¶æqìi9r4þ\z%mŒp'ÕSóeXNã¿#Ø™Ê&ñ€6Íÿð„=Qq¨ö_åá< ’ø  [=Nbﶪuõ‡%š5NÎ̺ØdÅÿm Êõ_g÷c ëBñ c ÿ >à‡KèVÐ8ôÌÆŠ¬ ÎÅœƒÙÐ>äç"u“®®¡Œ¬úˆ;¬°`-`WCØ>aÔáb¤ºnÃ!0¥ªUWÔkÌ“a(F dß‘f³•”ôlîA¦{5ÄÇå対è®q­ÃÅO®Â ÷qÊjbûP&õ¢q2EÌÈí©®u­ÄSíä==»Ë*á^ð8â—R‚ç>é™êš‡­(5Õ%›ó?k)Ìdôâ˾aïKÎ#Èö¿ °0 L1 »ëM9´ÐºÀÒ´é8‘…+ñ`ÚHNà©´²àñè‹K+Ê\ä>²å'çÉ~ÊA#+ZjAE6œ†›ÌD.­‘ÂNòxH2@oR1¥mQ±‚z:ê+ì¨B‰¬§›œ×¬›PÖ õœ·0ò ‚Ì»¢Éiú):é‹€~n<ËY$‰ßyNýGXƒ×:W€žI[ÂÐȇ½ã´D= ¿¢þ–Oƒlä7ðÇhµ:†ìúl“™`e]›e7Ç| l?ÜÞb§ûš¢@^ÝÎÓÈ»Öú™Ð»~ÏGÁÕÍr9‡Ù÷Ã’!áÕ?憜ëåÝ»»· Œ®ÞÝÝ~àM|õæægŒ²¿½¥Ž_BÃE®Ñ¹áN:ÍMÃ/&?Iúþƒÿ…RÐÂLÃ[ÝKqþu«3÷(šˆ´ßŒ3ì˜Mû"·Æ´¡56fÿœ4ÌLé†/Í©©aÖO_p›{÷! úŒ\š:Úñž%<§!Í|Õ óÒ5†‘ ´¾ìÙ$Η¼K Ø~öéHSŸÝ•ŸµáÿÇ“A(Îòm×ßÛŸ,_šc­aUš€–&~ƒ‘cádp,lzÇÚ$–c#ýØÃ qåCte}¨WDpÞki×—=ÄÞÛ¤ãÈDÁuë§/ïzqªöû-O,Î*¨õ­—“Õ‹]"Ï]ùùôIœze¡[Éx4´ÇöØ+âdÂY8’K3‚˜mZí¢®Z¢ßÛXc³Ç ½Yû¾N\³üX³9µ½Yø«ú±eý WúVPC€ºßÒÍÿÍêâq襳 endstream endobj 3706 0 obj << /Type /Page /Contents 3707 0 R /Resources 3705 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R /Annots [ 3704 0 R ] >> endobj 3704 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [370.306 546.668 386.963 557.572] /A << /S /GoTo /D (section.A.9) >> >> endobj 3708 0 obj << /D [3706 0 R /XYZ 89 721 null] >> endobj 1514 0 obj << /D [3706 0 R /XYZ 90 690.045 null] >> endobj 1518 0 obj << /D [3706 0 R /XYZ 90 453.392 null] >> endobj 1522 0 obj << /D [3706 0 R /XYZ 90 382.284 null] >> endobj 1526 0 obj << /D [3706 0 R /XYZ 90 287.824 null] >> endobj 1530 0 obj << /D [3706 0 R /XYZ 90 180.292 null] >> endobj 1534 0 obj << /D [3706 0 R /XYZ 90 121.139 null] >> endobj 3705 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3711 0 obj << /Length 2487 /Filter /FlateDecode >> stream xÚµYmoÛ8þž_á2°fø"QR±X צ‡n{¹ÖXÐc+¶z²ä“䤾_CÎP/Žb´›Ä9>œ÷¡øl3㳿^üeyqù6g)KµÔ³åÝ,峘'Œ‡Ñl¹ž} ®nn®ß¿y÷¯ùBF<¸bóEÄyðáúíõ‡ë÷¯¯qúfžÊàêÃ\ó`9ÿ²üÛåÛHx†–a¤aGÇR e‰.8|&B¦B--ùÂÓ/d <aÉ|!8lþæcVÏîí?:«Â4 ×Ù\DÁ}¾ÊðyÔIPí³ºÍ³f‡$“ZãNËmî8…–“ì9©`kh¡}°{W8»¯;Þn±Î Ófk\l+œÜWE‘—šÜÖ™Y7~¥*p´›‹À”f“í²²¥Åâ@d¦¬Ú-žVU™áì]U{–4³ÚV/œÒžK–F¤ÊêŽäÑCá)6U·ÛhVÁ™–Û¬éä6<Ö™p³ªó[<"ò PEQYÉ=tÛ´æ¶p .®—ÿ¹€ t>’³8 gZ(Æ5[í.>}á³5,|¦ÒdöàHw3¥ …„q1ûxñÏÿ“4U3ÍáW&ç˜9Jy8Ù“ˆÓÚò Y$Hú7(Í#Ê£4» qÈN"^„âŠi)Ç ö#õaJ'¡Hœ/¼ˆP†, O$±Îî¬÷˜CÑ"Ž{k+¦8LI$ã<þ`&ìxÄ2}ž‘Ei”JžgdQ¢™HÂç™5Åx¥,ŽI½èÙ_)¾|µ¡åk“ÿ÷Œ©½j–¤#$¿›ïdè‡Ý­Ñ>!¼'‚Ç(:¹Øø¤…¾ö0Œ™ÇbOÛáÏo9aBIÄÒó<~ÀŸËÄÙa¬Øù€ùf3r‰cØKŸ1ÃUUÞ1Ãç#‘p\X!¹Ó ëò.ëBåP•Ÿ9—›CmÚ¼*ϘÛÏbœ0Ÿ?Ï¢S<°ÐJ<ÓzžËÄY¥€ô,óÐ…xEŒûRÏÛÏmåMö5=c6/TËt,Æ^cu¶²sÔÃy”¡=qr"(Ì£Es&qþüÞÖ<$Çç™ÜÏ3ñ v+cóº" ¹€Ml÷€õ{fkY…õ Œ¤S¡i·4ñt¦tt¶°d¶z·Ïë̆ˆ’^ný;ó=ßJœõ™Î.à~²ËtvnCרW·{D¶V_<ɨbï -†¯¤ _0² ¡v¹ÀƒÛ9<¸9ÛM¼í&üLlvË9ñwmK·OÛ|µ¢±c9|¼ ¦íÓÄq×!¾ m¯b\o¶ÉðÙ¡…_S8@Ž:²°¡9*\ËÕí·lÕ~æoàŸ¿íQêagÛ›HúÞ–¥°ED³†™º6Ç!Û(hÚGtàñ´\x\ÛçCW)wÕ†T$>EfeV|/I¥0*j±+„7¤á´·»£Ø¹|·/Žø‚Á©Q? Ï® q£"oˆ7ì,u³/òÖÚò„Žo©¹0>»îv†zËëï DÕsÙ7¡GßYR)©&Rº•î«ÑÍBà ø¸`e)ÄÆ…’ J(lJš¬¾ÏêË_-7è‚ì{¶Â‘=÷o—¿æeÓ²á̓ȿ!¨çrÝ_rWPB°ŠY”걸:ùK7ÔSríVÕÄ ÆBÀQ"®f ˆ¶Iù@HF¦“¾×q q m>&oLN¼1&ÃO<˜Ccõ©Uð¾j‰´Ýš‰íE6æoˆ?˜o}oÙn= ÌUeAT¨mdŠ3ä@n 5?e·ÖŸœ &‚,ºX𸍙¦xòÔï *·<°M q'±/UøÜdĨiF8Û—nÍÇ-Xq×Kî² æéÐ0íN3Ë9YSnª§SÇøê Ò˜·½ó½`E’çà±pÜóÆ;8…ñ7B)CÛß×ø•b!4ÅtQ—ÒEÝÒ^ ö¬ŠjÓUÜÍaH:f¸gÞ)£´cÆ„gçõiÜÑœˆòÂ],¹é¿{þ¯GüO¯ú (Óõ.v§öl\²·nظ94 d©GŸŠ=®6MµÊé¾/¥ÄÙ¿µ©ÍÔj |UÒ{9„óë·•Ñàp<'Ò–m`Î [§$6åï¬ÕÅ”Ôbå°Ä6A™rm LXðüm°î!°¯¼ €€æž…—VP†J¥ ¢ÿc®À¯³‡I±‡)zÂSß´èØfOÜ&ö‡[€à"E¶“9ú¸w‰JÃ^-ÚŠÜA ÝA±T$Þß+{Žý*O Œl}ý©J¨N{”vÓ¥{&Åô¸"ŒS–tëW:š‘ oG6Í—'¯M;ŒK´8ih \úÏÆV燽ÅYʋ§)úþCjŽž‘mò»Ç~½éܰÈ(c@þ+|ÛNŸ(En» Áƾ·ðæš²HÈñP9‚ œ‹B@ô.ʺ¨ÒÞEiѺ¨J}%ß FXäÇýf  ñ˜pÖ>dD_<òHoÆÿ5e`aãð!/\Ô†`ÜâôI¾ÐJ{Z-‰Üs!ÉX/M,SRŒ;«Ž½}Á`›{$sò. s«Å:ʨÞ¹ÚVU“õ IjÃ.rØb b·7* ø%e†¶ò¥UvRàø¸Ã¦*œ…ï>¤ý’ û:GžÖ9 º2·5“áb\ß\M–tO°=­s’”ýîØyB;jñÚžõ£ª“çà öÜ'ÂŽkKrïé–n&¤ñE”>©\¼·ðª|}¢«âN¯^½A”Ì…€(_tÍóuüî-”hX`Oíõ@NÿÂXn¦ô‰¿>­ºvÝžÖÔa'Þ]UÒt,«öPwÊ:W\¤çCmñ‰ñw{uXÚ º…Þ}üÉf9o2ˆF$ï&/½â³}åÇ Ÿ "¹ê#…^//þ÷Ñ= endstream endobj 3710 0 obj << /Type /Page /Contents 3711 0 R /Resources 3709 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R >> endobj 3712 0 obj << /D [3710 0 R /XYZ 89 721 null] >> endobj 1538 0 obj << /D [3710 0 R /XYZ 90 690.045 null] >> endobj 3713 0 obj << /D [3710 0 R /XYZ 90 613.282 null] >> endobj 1542 0 obj << /D [3710 0 R /XYZ 90 331.779 null] >> endobj 1546 0 obj << /D [3710 0 R /XYZ 90 302.779 null] >> endobj 1550 0 obj << /D [3710 0 R /XYZ 90 134.226 null] >> endobj 3709 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F102 2374 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3717 0 obj << /Length 2163 /Filter /FlateDecode >> stream xÚ¥ksÛ¸ñ{~…¾•š91øó¡7Ž-_r3ñ¥¶Òë4¹ñ@d±¥H• âs}w± >$:Î4Ÿ,û~ÁäaL~yõvùêõuM2?Kd2Yn'Y0Iƒ¹Dñd¹™|ö.>~\Ü\½ÿÇt&ãÀ»ð§³8¼ÛÅõâvqs¹ ðÇi&½‹ÛixËéË___DzG3B‚q-I)"Dz°î;™…™ð1ŸÌd —CBÿ"e<ÀŸ|¶2lt£òÂ|o¦³P^³Ó´/ª^詌½¯S{ºR &3rÊøûXÉ—X™êX¯ø%ˆƒÜ×>ánHˆÜ–j¯Cü<áKòìµ1êA3I¾Iô“›«ËNãuU6MýgsTÁór[Y]ínÆ·ª†G£7´ZM%l\k£krÚæ‡Œ?#³«µbÎùF—Mþ%¤®Ç¼7zi[W{Z=îòõÎ!œš§Öÿ9jÃZ­+pIwÝEh”øQ8j¶Ü 9sÔ2ZM…‡ŠÑ~­JÂÐÊäÅ­W|‹¡ËÞ€&Q(¼‹aOt¹QåCE¨ƒø„½9UÝäåí›]î8Vû½*7nÙ«uà FSgtQOôð³˜5lT=sïA³y¶›¿;ò²£`|*.i0‘F‰Äê$ÃÐOdÄËÁt&ˆ€KˆEK¿â@4O¦Ñì3sÐkëñõHÅšRú2I‰æ{/œ M€ßCeL¾‚ºbwMEßFr%C}¶VúGÚ`rÔ( nœ0– ª¡4ºgizoŸž½ñ8RDÞ#óÙkte…ÆÃ…Vö†fÉ«í˜ùÁ•‡#r%“ì&àWòy?– ÇÎPZ)£O]Ãx.c{I4Bd9ÍBïâæ—ßîßýv·$˜.§ò®«r¹HÀ¯H^Õ¹[»T!÷[%œûåÜ¡k´î÷Àr× *ú‚® eXéMµ>"GÕäUé°·êX´2@þ«â¨ÇÃDÌý„Y/¬Ù¡»u^ÃMt°Þ«'Z°©­±{yó—i{†Î+5%m@+Éd=»#?VNÔY4ð1%ç`•œ‘Ý×Eî†Dùš+‚«>ù‘ø9ÔÕA×ÍÓ4‰=®”­ÉÛ³¶Ýq©5ãÍ_¤‰­|ƒ xÕi>û+¨v¬ ®—ôÄåigC …·©ó^ïß8ßÒ—CkJTJ¬a*yctÁW6•fhi»—½ì’wª­®›äµ›SÉ,õÞŸ 2ªíðöˆrdU˜ŠíZkëןÅåy½™­«ë»Ãøjóc޹̹”Òȶ“ïÌEyš‹P$›-è1s²/e™¥&ý ㌧„Ûr ^P#¸«¤I׋ɂ'91`7­Ž025ÈÜ,{×Wæ\ôpmJ:dÛ5‘øJUù`ˆ¿•7áj‹€m­YÅjõ/ }õ\ ˆØÄb —M]Ü‘f#CøÜa+7f«L])ˆ“AºÆžƒÚîŽßº¶• –Õ–P $èÀ„¸öÁ9Áií\`èŠb 28S¦:ˆñ–ÊöTD}Ìaà`æÜA’Ö…¶°>[O+‘y‚rø'Ï[n7Ê l=iN"ñÛåJHžˆa¹ºëÓÂzý¾40dõAoNž? Æ2kÖò;K°Ð%>ÂŽåy÷¦Þ‡aÚ6Öþ DS÷vÛŽصßýþ¡k¸ßÈÆ;˜àxH çÖk¸‚ÀšÎ¡ Ðt µ.4M °™c5‚fÿÏ#€6¸Ä/€Ð R½:n•tœCgRP}íº€VºyÔº$Ôu‘Ã5C'4¼ÂâÛ³é`˜‘¶C’mC>,>äûC¡û=—]©4Q†ëŒ7ÕÑBÂ3¡‘ImX]í`ªœ†vcP5Pû¡}$‘×Ôª4û¼i¬½nüðÅh¯íÛ6¦©ê¡¤¯¢ÇškkíG%ã‚8Œ o£Â¾Aù VUÙâá"öJp †cUÿ›Éóè+hÝÆÇ–µw,9Ÿ‘rþßQ‡Qn‡î©ŸŠmèÛ²;⸠8éŸLWp0œj‘ÿF»çlè9^kPjè½ËvýÝæACWC*ÇÑ Éúì;‚ͱÄzh lÐVêˆ+ÒÙKа¹Ï»4ïeMí^ãƒß!þðå E&ŠÃaQþØëº­®E¾ªUýä6ƒIã¥É‚ž%'ÍMD<çRת°¸Ô!xŸE"vHíÃqU5»A]ë;ŸQ´NœÕ_~Ê´NØží©@‡XLŽZì²@¬@¢vÉí¶£LÈ£`€s5Cè—€%i`UÍ ç‡ééÜëênáÚÁ[[øß=ŽM ™ðç²Ðr}#Y:#ÙžF‚ã§W„ºt 2ø¹€aæ§2t¬¾Kºtî§èKçüŠlSüë#F«ûí‘qŒ Z;ˆ!ØZ;pƒXð †GÏb2ˆ|lÑÁÿ3¡dvp"ã¥Â"~æ…5ÄÛÖ¾wsMyܯ\¨¶3N¿eòM¬ñ]ÈË–ž{ÒŸTú_+'!5"F|8ñ˜d©ìªl*<›§éÉ£+•Ã|¼áO[‹r44hÀ)`]õA>P‚ÝJEêGÝÌþ©É‹70†5÷sOÈwï4sÔü~÷ˆç‚g¦ F~µáç^Ý”}˜™fÉÉC­ý™mÞ¤Fƒáâ­æÉèÄŽÿ¼¬ê½¢¦Uëâwšý€ZRÆ#j¹x9OxE]™øùç'ôatølF£ç¹[d#?‡Øÿ9dÔýXºº»_ü}q³¼‹¥äÓõõâöÚ-¡a ÑGqÇæþÅòÕÿQ–i endstream endobj 3716 0 obj << /Type /Page /Contents 3717 0 R /Resources 3715 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R /Annots [ 3714 0 R ] >> endobj 3714 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [127.469 107.007 139.425 115.754] /A << /S /GoTo /D (cite.Tango-dsclasses-doc) >> >> endobj 3718 0 obj << /D [3716 0 R /XYZ 89 721 null] >> endobj 1554 0 obj << /D [3716 0 R /XYZ 90 550.653 null] >> endobj 1558 0 obj << /D [3716 0 R /XYZ 90 483.928 null] >> endobj 1562 0 obj << /D [3716 0 R /XYZ 90 372.969 null] >> endobj 1566 0 obj << /D [3716 0 R /XYZ 90 283.993 null] >> endobj 3719 0 obj << /D [3716 0 R /XYZ 90 199.56 null] >> endobj 3720 0 obj << /D [3716 0 R /XYZ 90 177.577 null] >> endobj 3721 0 obj << /D [3716 0 R /XYZ 90 133.741 null] >> endobj 3722 0 obj << /D [3716 0 R /XYZ 90 101.98 null] >> endobj 3715 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3725 0 obj << /Length 2427 /Filter /FlateDecode >> stream xÚ½ZÛrÛÈ}×W ö%`­9ž+0³o²-gÊ*Ž¥Ô¦ÊÞJAäHD  Zq¾>=7 J\0y"8—î3=§{.=8zˆpôÇ‹7·¯ß§›SãK4› ŒãOWï¯>]]¿½rÅgŠÆ—Ÿf Žog¿Ýþéõ{A;2¹(ÐhER"L£ ìA‚”€^Ð|ÚÏi 2˜‚F|6'ô_E9#8~Ì7Âuví>Wz㿪¼i볦©ò»Åñ®Ñµ+û‚þ‚1+³}»m™o¨ ãÀÑœH”Hh6gLÆÛªÜêªùnþ¥ñ&[ë¥ë ƒÚwMS$Tk_g€\$›vÆ:÷ôJŽ }ïtQn,^£¾)âf¥]Á}¥µ+*ïþ©ÍBÄ) ß6Uqó½nôz@· Hà¶ifpR?ÖNYæ4ÝÎ$XxóPºÒE¹iª²0Ò¢9£ INÁtv†œÚ©ƒÖ<Ζë|FâM^7UÖ”•+uãâ{æ/‹Cõ2¯j,LÕf·¾ÓUíJLqËS|ÈÓ ¼wuÞ’<~§øoï àG_û;=·ƒÃýQ}{Wîî Ó›x™5™ûj¾o5ø W<¾]åµ+ ¿¾Í]Y:3P íRÊ´Ø,}_°Ô÷†+Ù®h^A Mã¼ùÃLˆØ‹üf`gÅN÷55ÙWÓÍÚÈõÅNVQk§ÛøÄ/€Ä™ ê]‡Æ”x_Ê*í>*mX§—ƇPK¾Ž{ƒ *‘ ²ã×Âûõ­ $»Mëkc¾Èê½ê9qi¼ËV3"ãr›=€—›g÷¦É*/ú=æÍÊ|©.‹M…DÌKa˜yãKššmY×¹hó¯)]-°wSßëÊ•:î°ÚÆ\Û b[ÞéæQÛ( —®e¾°–„Z;ߦfQäÐ×ëÜÕ±2”1%­m\)f”M¹( K?0¯¥6Áa9è|¤D’àò¿5W­ÕŸ8ˆbº¼*PJÕ™Ÿ²F‰ÃˆöŒ8öDÚ‡oÅPˆì…ëDÄñ4y"ðçr[6a|ëÒYuš]äK8Â`ȃ逶Xù(>^Ã×h¼N)ÂIúÒpMIú$\èÜÕ†¦¶Èà +!}ØU¾Éã*_¬Ügʵ+[Ùðe+àÎ÷«­[:%.†ÀgÏ­meˆJîm“ìçfN• >©Zæs›U°¸6Ú ›EßÃQŽ²Ê¶utÉ„»ƒ4›zw9BË3À¡"EŒ&}8—û£êK¯sÍ•:B¿3@åf~8ïCÝߘsðdÝôœÊ‰œ*Är0¡°W™zæˆÃI’%ÉdàjI„«¥â52VÖÃÓmáÐcïdœqgÀö‡]Œ'mO1ÀÓ‰'‘ÉB,õ8˜†Nc^‚‘”àð, œŒÜ@ްnºz˜8Ø È¾z«ÕÝΔÕíF—f{µ-«æ§ãå”#AÒ>^yl½=UçU@DJÉD¾MbùÆRØg$ 1&DÂVpøŽz„ngÐN9ø?a}õ·fÏמsá–ÒåƒôÖG›°êq²ÒsKºu^×>³2»3o‰×Nïd¥¤,™x±7Yˆe0otòÅW`*QªÔH6c„{gÐob•ò@öo§h³ýÅVZ¯]’«CÌEUÖÇÖÙ3@å4E@GÈv²Îž€ LØD².$<´À½W ”ÃÊ”PÿìÃlËC&æâs oüÑßmõ"77f‹±4GT¨½D¸Äðé]ŸaµÇǺ=Jæ›E±[êð0ÓBïi4¦Z½èYF7‹kήYH¾œ s‘…?Ú."*A‰J@gŠhxœâúÜÖP —ù1_Q·Ù¢™û™—¶—oøSsdÞy0éPä ¥ýç7Ñgû¤çÀnû„ Kª‡ûÓPN•s`a›óµ&úGk66Î^g@½Y‡þfr…âÇÑ¿ý˧7öû;€BT‘¬MçËâug:Gáù^/BwS†¥w£{‡RV_G‘Ö«ð¯®=bgsÑÎÛt40£._©ƒõ’ô¹\x‚ä>¾®¸gŒA™´¥—ÍUQšJgëú%SÖ,ÖYq0oMYíï+Ao2¤7/A¡Í…fC©sãüØ£nï•|ƒú¨0&`óœžbèû¾¼q·€0›Ø÷Tý!?C¼8½Ì*Ÿëh§ Èïª6ƒ<ÎÅaÞÁÆV@½.Añ«vv}ºÿðùD#öÛ´mÜË“…yv”…pÒ3kô‹Xè#…ÉSÞ”w«°rõ¢ã ¥†– ØKüa_·d endstream endobj 3724 0 obj << /Type /Page /Contents 3725 0 R /Resources 3723 0 R /MediaBox [0 0 612 792] /Parent 3696 0 R >> endobj 3726 0 obj << /D [3724 0 R /XYZ 89 721 null] >> endobj 1570 0 obj << /D [3724 0 R /XYZ 90 690.045 null] >> endobj 1574 0 obj << /D [3724 0 R /XYZ 90 608.81 null] >> endobj 1578 0 obj << /D [3724 0 R /XYZ 90 513.791 null] >> endobj 3727 0 obj << /D [3724 0 R /XYZ 90 438.786 null] >> endobj 1582 0 obj << /D [3724 0 R /XYZ 90 275.493 null] >> endobj 1586 0 obj << /D [3724 0 R /XYZ 90 244.336 null] >> endobj 3723 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3731 0 obj << /Length 2062 /Filter /FlateDecode >> stream xÚµY]oã¶}ϯУŒÖ,?%2oišmS`“41..°-YfbáÚR*)Íæßwø!Y²eo¼ò}²Hކ‡séÏ~=ûyvöÓ§˜ ©ˆFÁì)P8ˆ±D˜‹`¶¾„wwW7¿\ÿw2¥‡h2‡÷WŸ®î¯n.¯\÷ÝDÑðâ~áp6ùköûOŸíøäÆ¡ˆ`Fë’’Èaà€¤¼æÓÆ~JcðÁ<&t2%›Y`Â$.ÜüÕ‹N³?1¦©k¿”"C=u¿Eª«ª(ÝÐB»\ÀÄÁ”HI7ßl©'SÆYX›yÐÒ5^J=¡"ü'+^«Õ»ë[è*-³¹^¸f²ªŠfÀÍåªb­[/€­ÅeºÖIZUãaU˜YÞ²üÙõÌ&ûõšf©W:©|¾sn×dWacé–‘.uú¿ Á¡AaÔî7-Ö/ÙJ»F­5PËÀÖ]ùÞ“}­Ôç=Ö!Î$̤~¶?)}«/V/À /n~½}üÏÕýÃõíÍãç‹ßoïû¦ø»}]ßìóëËIyB g—¿ÙˆN‡VúiBDhÈ# ‡Y^JRý#Ä Sà­^ºo¦Ùòfžýûâc ß²ÕÊ=Íý«•®ÝCíKo¹´Œº™÷Fi["ο!yî‰'žóÜkæ›a²V»~(rÛ¬¿¿az*‘ ²³±ÙÇ6výþ¢«Öç¾­{û¢Ë¤¶›Ç:y¯j½vÏOîdÐwß<ì¶¥p¶-’:1OĽhû^+»± /Ë]O½ôCmÔÜxZ”~ *žê7³'×CÂe2¡8üÇhÊÛ̵ÎÝX{Š˜ ʉ=˜ÀîÝÙµ.:§éßBC§¢{ª È Næ+m ;»šý}FÀx ( )΢,ÒõÙ—¿p°€Að˜’Á›5]$VHRÏ«àáìÿ‡“XÆg1Â’rÒÎû°ÿs=Ž)caEÊŸùf»:jAy²Ö»á`”£ˆ²“€`,BŠo¸üᇃó+86È÷Ì?ÀÌ/%I)ãˆ+6’RJ9ŽR €"¾ÄæœnOà‡÷êñ³^?Ô¥NÖh=Æ¢j HU—°ñª}Ó7¬=ý!àƒ05’Õ±N,«‚rX_ßf•˜$œ0$b2ÀêíGh=Æ0’}ÅY=zöBÀG,ÅHVÇ:1¬2£ˆ‘q¬2…7‘1ŠX½Ëûé<&(Š„ìCÈòz?ÇϺˀñÁág£X¥@4ŽGÒ©±RàK" ›t—ÆËâµ>Àã 00'ûŠomÉãg |àXŽäòx'Mƒ»U|/&sH,¸=²"µm¥»ytSØõ+cŸóÛR4 ¤y0”>¦EnÌžMAlzMc¥Rò)q ùD¢ùt¹>"Ýl_¯_VI­ÛªtÝ–ëb¡}EáÒvc·8"u¿0käqhæ¯0Mæ–Ç¥YžÑ†c£|Üý­ Í+ k$·JÆðG÷î$¦ 3‡ ®ò36.lÐUoÖg¬7¯Êv}Ðe„Ç •d¥Þ:©Lc¬ÂÏIÞ$þf€6÷,{³:+<ƒ[Å…h‹ S³•Y]7§æ#I½QJ ag'l’Ç2iŒb|PÀLBÖOåÀ.8‘“ H¡¬ãRrÂâŠSfNŸ‘¯’ª:”“Sø[„œ%ô÷twEûu¨Ù k]/‹E³ΞšòÝʺÈÀ9ÄåI³BUÌ^ÄnûYý¥¯ÍN÷¨w€qI3¸9Ù€ªÀ|¤4M±‘Ò„¬Qâqe?MS­™Œ˜©¶¾‰±=B›ˆïç ˜´P± ÁÿߟŸ?Àá¥?[fïêr¿êN…Éþ?é^(—ë…2£ÕØÑ8ä>"¬Fjlœ¯1Hd¹#5ç0ƒÈ`ÈJ8ÖØu~@e'Ѫ¬âh• ‹!å'j/”Ê¿~ýz@iGc‰)Tào~œÒÆ9qJ#`Að¸ò‹À¾å„DA&å°Òn‡Š‡Fj§@ÑHm űR;”Fjû €¾?r¨eW%j)…é8©tâ¥G(æñH©1D#š„ßw¨Û p´bëã8Zl'€Â"›ˆöBé‹íñýýý€àŽÆ3 ð!øÈ"â;œ|¼”&PÇÆŠm.‡wK^¨<k¯¹Û«¬±žÖ­)CJ²æ½ÌÜã(LÌ_Š,¯uéúì]/t&®Ùdþæ¹xrC¶ð4¿ø›êT_ƒÊÝ`ê*3ü¶ÌÒ¥ë-uýZæÝi£p^+äþ”ÂY )pᄄMï—‰/ŽŠÜçö/I u’Em‹L7•ýªÐ|uðe½~Ò¥ÎÓæCÑM‹¼ò·Õ—·÷?O˜/ÎÏ/Ú*ØL9×im‹Ó ùÞП‡§âMxê¯Û,QY—¤Ò–¤UtË3CåjóQe›$»ìM¹Ù‰\K’-C‹zÙÞoú¬ßÐ$ úßr­ƒoUÛ\ ~G$㈌d“íœÉÔ~þêÆ“J3øÙÄ6ž›±6žðlãI›¯-ð°Oªl<'$¬\« )oB &8.’\ ª¢!Á+é¯b/xxØ â” šuÛÁõ«U1¼8÷æöþÞt$iZ” Ç ôÛ•ªf9æÕf­ÐÙÝTÆÖÝS'M÷XI÷Ï.½]îêðzïåoïsWó Gþ¿cjË endstream endobj 3730 0 obj << /Type /Page /Contents 3731 0 R /Resources 3729 0 R /MediaBox [0 0 612 792] /Parent 3736 0 R /Annots [ 3728 0 R ] >> endobj 3728 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [153.8 282.287 175.717 293.191] /A << /S /GoTo /D (subsection.6.4.8) >> >> endobj 3732 0 obj << /D [3730 0 R /XYZ 89 721 null] >> endobj 1590 0 obj << /D [3730 0 R /XYZ 90 690.045 null] >> endobj 1594 0 obj << /D [3730 0 R /XYZ 90 542.04 null] >> endobj 3733 0 obj << /D [3730 0 R /XYZ 90 522.548 null] >> endobj 3734 0 obj << /D [3730 0 R /XYZ 90 449.436 null] >> endobj 1598 0 obj << /D [3730 0 R /XYZ 90 313.919 null] >> endobj 3735 0 obj << /D [3730 0 R /XYZ 90 240.907 null] >> endobj 3729 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3739 0 obj << /Length 2609 /Filter /FlateDecode >> stream xÚ­›]sâÆ†ïý+t •x2ß¹óÚ8µ)Ÿ]Ÿ5N¥*I¹d` ŒöÎÚÿþtÏH !$¬Œ®4HâíV?Ó=3b ÉSB“_Î>ŒÏ~º62qÄi®“ñ×ÄÑÄPK¨TÉxšü1¸¸½}ºúøûðœ+:¸ ÃsEéàËèzôeôérNß\|j:ÿÿúÓµâ%M‰‚JƒE/É™Á›ÎhîÄh|ö¿3Mš°„9JœI´¥„[–LžÏþø‹&S¸ökB‰p6ùîï|N8g ê ½LîÎþÛ»# 4´%Œ›6 ¸›§T.áCZy|.±’'Ú0b˜ A-¤«§,DpûömæƒR †”Øž¼RçdÕ‹Í<[oƒ“—¼ñ'Uôõõ¬î‘+Vü ‡êt´!ŽÛ8ÂZ%La%ˆ°<Ž0ׄ1 ZcíÿüóÕlÈÕàŸY¶œ¥«Î=ø" %бª/²f”mÖ1€©(”q¥„¸‹C)à:4µ”D3Õ„òÎ'N3È<¨T˪'wófmÖ! ûí§AÆiÜmT$HN8U‰Æ£æM o²ÕS ÇÁ„4®êÇÍS3ÆÎ&ë@B‡1N#`dš΢1J ƒsÔ6a¼^fi[>öà‰0œ0}àÉõ²dg›u Á8§@Ra°‘cd˜jjˆR² äUöò¸l› õà f$¦êÊÕc3ÉÎ6ë@ÂèÈÙNœ†'©à aöGÒA"pÐRPaYÉûMûÙ‡+BC[Ùª+÷w$»Û¬Q@ ÉTÉH@Ò8O¢SRS—(ËabA¶‘=8‚µ•UGîoš1v5Y' TÇ­/#5E ³t¹¾0ã‡õ¥‚²&hœ²n׋VŽ=¸R,>*®€áf’Ö1€„¡&eœF@©$Œ&"% ŠZ°¾n#2Æéúrž®/Öëô­jN dÞ”ºœ_43íl³Î$„’qLã4S s>¹¢d°Àv´1VŸ‚êW–§¨öà–ІHmªnݵaíl´ŽDÆÍe#¾pÂÌÅJ×gJ"?…ÇÎS4{ð i2(¸¯nžZhv6Z§ZÆ-3#5U=ÙñhªNÂTwŠª_nžÂÚƒ[B[¢Œ¨ºu½lÁÚÙh Hp÷6/R#`¥Š0¹è¤Ž(h*j‰áêÖ°ø<ŵ¿pHÕ²êÖÕc ÖÎ6ëH¨$NĽۋÔðX¡wÂx£¢±ZPÒDv êý{FÔ>¼B¨Ö¿îïš©v7Z#‚ÊÆ­F#5U ~ùªQ(rÀÕJB™=ÉõCkn!VjMÕ­û›¬Ö‘àO—"n²©°ÂøCMäò”qˆDÇ0¢õÉEMX¦žâÚƒ_Ų¦âXoÛÙj ÌÓ¬‰{©À*˜õóÈ÷€”Á\Cƒ–#‚½g"ü>¶=¸¶c[rí¦­w¶Y§ŠÇ-Y#5Y Ë͸Ì`Γr‰[”y߬é}lãÛ²eç®ÚØvµYÇ ÌĽ,ŒÔhÜÀtôïiFÁ +$Ñ´åeaºmù¦OŠw÷OÀn3ÈÎFëDð?Šdwb§-o»ª¦ά¥L„ÞmóÁõ©A¶žsË‹Õf›®&³á£Záì·l±ÚÎò[¶Y8æ×žgÛy6 íïóÅdŽM1€³ÁßC7˜ÁqÎåßxߨll ·¾ùCèKºNÁfáÍóËÆÿú“œ³ðlç9ÿl3|p:Úb’.—oáó$ÝlgÓÐöÏÇ4JÞ]>OÿOw»]?àˆýcå¾}L5J1SELð®ôï!£ƒÙ¦ÉàÁn XyšiºMÃî)8qf9.ðÑÇÅ·| àX‰nÅ*b€Ãò b¹üñÜ<ïÕ±@ç³°%ÏÐr3ÄY^ìÈãþ½ úúúú°W>²™ÁtÎRS|u±©ø·}Ý÷]ì¡}Ío™ç1ȼ˜Ì>>[æqX¦›\¾`Íõlû²^åç÷ż³ÁP.D5Ù ÍpìÂ1Øå¼²Ïã><ßJWÓИ{¤ÐXå÷hy¹Ë+5 ÃsAé".æ ¡õ˜knfù‰t2ÉÖSü9&Xͼڅ ÚáyC;ÜÂÑrOÌßà~Í–Ë CùÝ«‹Bð5´Ö/Kìëájº*ZÙ&¿>m&ëÅ#vBáŸø@éÛ:Ç•½2)Ìpw(×ûº¾»«[0z`_ðE?ùãã1¿–?ü‘4kêõä¨î&8è*}eàÕc9U|蘅–iOfáÃÛÛÛ±LÄw½®’‰‚›ESްÉ#¬‹kE÷Â6f„¿%°5µLÄs“%Œ>ñSŽ›†zøÚº£¥Q°{xôÉX:º½`•dÄó!¡’!Ë"E6B³\hÿ½½«hÙ§³ÌÓ¹ìÒðÝGëc›4¤»à®œîx>ÐpyÈ-ñp»tÇóÁ!ÿ ¯…nà©ÒÓz±p\8,‚p]QàÔ®¸¢øû°)+¥‚À¹ôyÁ’Á_Ê ‚ ¬4‘ñßÝOdDH+Ø øÝ,ókûj(w%šû°¿µ¥ÀUÏ#À|LazW¨c³4%`a¾…‡÷¯oýí¡Ò` ûË•?•Æ›Ìm•+ͬd›+ÍÅrY ­¾œïv—‡"¶.ªáìOJùª(rhy<Þ¢á‡I°È¼ØN9"-êX°Ê±í¦xÜU¼#» p‡„g¡”î‹[a»™}Λ“l:;Rí™%Úîëé9§¼qéâ/æÏ -?M¡aj ‡Ë~Ùêåy¶$Ù*œGÖÛ00ãíÛp¤g„roÖ;nÙl²É" Ã|þ¾ØÎsít2߉nÙÇÿH¬Ñ8Héè1‡Q],q+ç oÀj¥ý— +Ü5U_êô&¢P:…ý!GÃu+Á'’ï^Öí:Í ëZ}¹ +F¡E/aˆ:p ÏýåË1ÛZ qénûܨÕþ»Ë;XrM¸´‘,!Ñ©Ñ,5J™}:ï³øó§Ž=XÇÿÁÇ*æi ¾Î&Dž bŒÄ+âñQ‹£Èý,ÊÁ¬Õ€–"‚×÷³|¾¾n!؃;‚eX ÂÎ6D4T,ÁH h6ò þÓðŽgêûW.o>ßšöà@Á¯ìoÆ×Ùb=ò Á¬‰£«ôŒ!TDnTQŠX£K‰fõ}*ŸoG-õ³û¼²}Ñ ¯³Åzà†ñSÄÁ‹Õ@xZm"g1ŠùÒ©-Ếåã§»ÑþO´ÇöàE°ì…lFØÙb=ü ÿá‰B«‡#rë‰Ä¿zâ&WâXýGÏÑïã/CI—- {p£`XvC53ìl±`í{îãø«Çÿ¹è endstream endobj 3738 0 obj << /Type /Page /Contents 3739 0 R /Resources 3737 0 R /MediaBox [0 0 612 792] /Parent 3736 0 R >> endobj 3740 0 obj << /D [3738 0 R /XYZ 89 721 null] >> endobj 3741 0 obj << /D [3738 0 R /XYZ 90 690.045 null] >> endobj 1602 0 obj << /D [3738 0 R /XYZ 90 216.196 null] >> endobj 3742 0 obj << /D [3738 0 R /XYZ 90 141.191 null] >> endobj 3737 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3745 0 obj << /Length 3077 /Filter /FlateDecode >> stream xÚ­œ]WãF†ïùº´/ètWçÎ &!K fvs’œ9ð œ8 L²Ù_¿Õ-K#cuÛšê+Û¼õJõHªîj‰WŸ+^ýpp4?øîĪÊ3oÀTóO•ç•åŽq¥«ùmõëhrq1Ÿþ{|š&l|¨9]NO¦—ÓÙ»iýñÅØÃhr96|4ÿ>ÿé» MµÁˆQ„ ?:àkÓùÁ¾å•¨@&½¯Œã œ¨n~ýW·øåOǯ\õWüéc%$þ„‡|¨®þùFD㘛ÁŸ æµ^kIJa”cF£–Ì UoÂ|ìøhñôyõý÷?Ÿq¼?ý7jcc¤LYćTaLjM¦'¦1Lá^³' Æ2îÛ“PD$fRkf­$fR3 µTárþ²ü*„¾ªCà’IçƬ¾-Ë뉂`øw ßÞ¬n×ïbX|½º;à¿ÍŸ¯k•Ú{øåzï†ÏÖßÕØýÑÍêùyyóÚ¬·¡ÉBM „]ÉqÂE¸É&–4LçükRÖ›±x]¬£üýG_ZP /è¦þö7y»üsxZâ{Uz×lîÇåòiíøy‰»å¶þãÓê¹~³\ÜÜÕïÞîÔ 7˜)ð7w÷Ín\¿¾|y|\<ßÿ¯¾z³£>­V!?á.Z·øø°Ü>È…àŒ U)i™PÙ T:`Þö ÅD ˆžV= #™0µÛ-cC’ãþxZ…oæ¬p ïŒ(bBJǤ°9ñHÙ2¡´eV¹"&î‰0(Û0ñ~,„-¾ô÷xræ‚÷ð€ÖK"T8PˆP…WE›¶J#T€ZXRÈíéÃãúŒx´Z=,ñôf«€ÉñHs2íeúþÃÑùùÙt2ËðUÀˆ²¡¬±›FD«Á1{ˆ¯Ê±¢Š¬$ÖÃÎ+V8Ló¸97.ÕÕÝêù5T R„BÈ' QW?ží ô3UÂIËTÇ ¤‘r›† a¼¦!E‰HaY®©D <ÆEÖñêKïÐ¥E«€gaŠÒN¬ãóëÞy¶–¨6Z¢º>t†¨Á1{`@ #‘(ªH$J9¦¬'%-jiˆ­S×» ªV$~/µL[A¨®÷)© xiÁêz1°Çìa5€X¥S5"VÒà•_“± E)}ì2¥°ÚQSp"q …_'¨vU\´Z¨º>\ªÁ1{x@ m‰STd‘:UÂÑ ’áä b¥Úo ¨ÖóÏïîÏ“8ñžæ«€+ðøXn&]Mߣ£Pµ_~x÷ãärry‰õ;×£_2¼ðÕòÖõå3¼ ŽÙƒ ~Ây£ŠÞÀ{,ˆ3 ˜B?b‡pn±æÚÁ[ WàÂ:O—¶ÕáíkýV î^ ƒÊ†±fÓ`ßâ–†¼áA·¡ïp§¸È"‘<‡ãe!ÈäY<¹¼Ý…^¨Ëv‘WÀU<Óá•4éªC^(Òö®€¯¸ _"3M?-S|´Pu}@¦s0M¨ÝÈ0N072aìmjOè Xk¡ëZƒLO`xÐ`P8±E Ø9±Àסß#*Ü?F&ÛP§O™;W ¸á)xÕw5ÙXš>…§OܦI*à¤yLAÊ ¢4½;?ž§q*`£Á©k23öƒCn£`ü2qÆ‹ªp2ˆ‚Òä;UšßððW)Ò8}yL³TÀF˜ª—a‹6"K×?§A*à¡©ë2³óƒCnC`T¼‡žU#€¤Ñ¦'¶}ê•ÆgÏ&›>÷,VÓ,p"C…bÒV¥‹Ó‹é‡£³ó£4PŒ4@uÈÌlüàÛ0 „õÄfU£~v ^Û-ùv'°PE®ÔîU;‹×]kb ˜ +²­RISKvºÅ½n{¢ûkëú“"÷x•!ûŒÂ”¤Þ > endobj 3746 0 obj << /D [3744 0 R /XYZ 89 721 null] >> endobj 1606 0 obj << /D [3744 0 R /XYZ 90 500.395 null] >> endobj 3747 0 obj << /D [3744 0 R /XYZ 90 437.346 null] >> endobj 3743 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3751 0 obj << /Length 1662 /Filter /FlateDecode >> stream xÚ½Xëo›Hÿž¿Â±ZÓ6U{'7*§*‰_{RZUk³‰Q ÀIüßßÌÎ,¯Çõz÷‰Ýa™Çož‹]ÄèãÞ‡åÞ›£™7 í0pƒÑòjŠÑLÌmáù£e4º´gg‡'Ç'®/¬…=žøBXç‡G‡ç‡'û‡D>‡®µ8ÂZŽ¿-ÿxsä»-ž2ô¨YºNˆ‡ö+ÑŽ&Ópj;Ž;šøs{:gMŽÆŽoeÅx2ugÖ:»¹‘i„›ÀºÛÄë Ñ£ŒHiV¡’?ÆŽ°íâ±c¥ù–ßå²7ªRÅØÖk yUmq¨v¹2²"^-ÇsaÉô:{ûöàðó÷ÏøÝéñ}ðUøâvìú–L¶|þ=½ðÊ!ÊF–hûhâxvèyðtìÐg WJ¥h¤¾ á¦*²õé¡Ã 89[eUÄéuIYrG˵L‘3f¢åŒùÌöÅÔøb‰ž#‹öo¢EX]/Ç3ÏóOw:ÎÜöÂÚk™’È•¢ç¶ÁzUeô¼V6|&’•d’ÆYko¬ÀG–³Ð8ˆ¹©˜Y–ªa¢1t]¸L»¸Ô>b$I¬X¬È¡¸Ò"á§@ðº7ÛŠ?'…ñ$C‹4~GVµ­³¢Pk¦’gìÚ¤¤‹ Ð}nûΜ] Ánã‰#„hW½ë VîÒ,/ã^~ÉZˆÛB5ªÆ£…E\a#g:øÃnLFå÷‡.cPnÓµj‘.Oϖǧ'ß8¬;<‚¾ T:LU$§˜*T¨á1(r´?éØ^š)e²á‚8ùšÂd£’üà[1{MÇE€‘FC'èàŒ{íLô¥§¡Æ³ŸðõQ KÚ'qÉ<уH1˜•€%Q<Ò ì HfU|=Þ¬dɧu¦’ªFtKס¾ÙDˆï[Ü.MktÒ•«å¦d&}Á>,»îûÖXÔj¤IœªniÞ–ªß«8Q;!0!>Ý'ž ÛËªÆžÎøôíù@¸x0í1r«¬Tcƒy|eÀâ¯;<6E\ÇÍ«ôu/ɯt]Ú&u™ªïíšàu9ê¡üq<*¥04õþ=ûa’ËjóÛ pÅÑ핱mÙLzj‹‹ýãcZ¶•Á†i¬ Lí¿›¦’ý«Ã.Í¢ÕάٶzJmàK,ú)ÇGTÀPÆ»~gk½ >¶b½o@.ïzºÚ»¡õ›Mšìú-Ž<Õbõ«;=ÿÐíyÁñáz>«¯çøOAßmÞS&Àìþþ^ÿZÐM—¿$l9POMo\aðršè[ÛÒ³Ô÷t|SeD£¶„-܇‹d§C ÷ ˦#r ¶RD+ k[/ÿ¸¢!o­òªÇ5Wit–aghJm76ý3ÉP7£§ahˆÃ.³7r×þW£¦ù³ðéqexÚܵ îÊOŽ~_êûÿWi1—F†'HFë>‡ÿnóè—¼g@åä©96‰Z˜Á6ÕÄ»NX7×nÓÿ§/~¾ÚãP“$½a°'âÃåÞ߇­o¸ endstream endobj 3750 0 obj << /Type /Page /Contents 3751 0 R /Resources 3749 0 R /MediaBox [0 0 612 792] /Parent 3736 0 R /Annots [ 3748 0 R ] >> endobj 3748 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [472.96 551.489 489.896 562.393] /A << /S /GoTo /D (subsubsection.A.2.1.6) >> >> endobj 3752 0 obj << /D [3750 0 R /XYZ 89 721 null] >> endobj 1610 0 obj << /D [3750 0 R /XYZ 90 597.068 null] >> endobj 1614 0 obj << /D [3750 0 R /XYZ 90 453.108 null] >> endobj 1618 0 obj << /D [3750 0 R /XYZ 90 424.108 null] >> endobj 1622 0 obj << /D [3750 0 R /XYZ 90 122.622 null] >> endobj 3749 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3755 0 obj << /Length 2423 /Filter /FlateDecode >> stream xÚ­XYo9~ϯÐCZ€Õîû²œ‰’xÄ[Áìb³Úe5Fj }Äc,ö¿O«Èf·ÚNv±O,Éb±.~¤7»›y³wÏ^¯ž¿M£YîæIÌVÛYîÍR/s½(ž­6³:Ÿ?/?½¹üû|Äžsáαç9×Ë·Ëëå§_–Äþ<ÏçâzžxÎjþ¯Õ¯çoãÀ’¡À8•È ðpÒ3•Ðílæ¾›øÙl¤°8¤é_ƒ Ì=KzæFI®e/š‰ý½ÙÂ÷Ý<æ#]VM[ì÷¤z»D4¢þ^®¹ST"Ö;)1šZt­<m¹æ•mQ·Ý‘:¹mg Rpáçnjýgêž8SBs¾T‹òÉcýŸUÚÜÞýØÐ×]EJ”Ü®eÕȽ°,EÊJj7âvxNw7PB.ô!°&uèš–¨]k¿ÏýØá±[!ÌþÊ4‚z¬KY·î´“ËÖŃAFnî¥p ÌÍ3:Ï'ÙšP(Zch½TÛ8VìV˜-xÿbÛŠzä'°E;ýÁð”ê,µu„JVÅA¸äpÙ<`™z:{]?pÃùÂ÷ i—Õ< •õÜÏYDÅÂF T]·{ñXþdnÂV¸À¢­Rø;¾#´h-6Tba‚«X뢢h”Ð9è ä´]Åc ¬æ&äC µµÜÓXóдâ’ø81‹O﮾½¿ºYÑì’7VvÆ ~Abµ<e F“¤˜GAi¸Ô¶òHDÙž!‘:<ðK]ìnEÑv5ž{ûò´õÔTßÙË»»²º£±>ÊqßšZ>;2ô‹õZ4,ú«{å–h´*ôý©ƒ’ Ò„\-|Cdרý‘<õ(0m¢Ñ³Ì¹Ü²ʃŸZÚ«¨yA%yÒF|õ¼Ô«Â¥Á^ƒFnÛ{ŠR1u¨Fõz§¬œ¤Tn^Ž ”º&_úÈNS¸˜]Õž¿¿ú¸ô8§9 ÌA¼(arÛK⊠ðûÙ¯¹²*p7u™•M[—\:áNt'Ì„7øÚì›Êõù®ê­¦jùî¤(àÏÓƒ&Þø •z:™,Á2 P¯&ZY¡´¯}Ù2ó(Ö%Fƒ`Y÷;Q‹‘Xûò‚.x¥¸--Öºãq”Âi íꮪÀÅ ƒ>J+PË„hËf&¡öJóPµÅŸÌl¦a·¥n Š@4‡:ào/w°ï«/ñ’|Å¡a/c?ìH»€+[ +YJHq{h-ÇŽ ôØŒƒ½ÝPÀY{±¥¨CTÙž‡u‹ú¢ªºÃ­§ny¥H¹ÞMb\Æ$/ŒàVo…ñ‘SÉþƒìh"ÕÆŠ—)Ì Ã#Ä # ظ¸ñà…"‹U ²¬†x áH2O±'¦e>aÌÇk:ô8fÈjÿ@Cˆƒ&, *1€ø²Þˆ¶n:€2½VŒ¹RôšM€Þu]4p‰œ0º‰ø-`!*Bäö>à'î–<ÿ‰8ÿæs¤qFœ@sÍ 5'ä|°¥s:\Ýâi¾—²kÀ IìàI ¼Ò&HB "Ÿ' P*Q"¯²z:QìXj•ƒÐ±Œ «½1g «FÇ~D5•/á`²'#÷Á $Á¤:¤œAÐîáÂèS(‹ÉBÁp©x±8ÀÝÆe¤~4¶¤Ô #Ù3)µ!ÚØhUZÚ&9£µÜª3С:…JõÌLF…¹.B@±­âØQ1u.Ô›%i4´Êh-Bï¾TsSë žµ4ØÜ—­²8ÐÛZˆz$Ç™¦sµ(¸ÓLzYÉmýÅCã[È,Ò€¤ªÍø¼Ó¬M)6Oa„p€‚#ºL‚æù8ƒïYïi¬q=¨øpõîÛçyÁc6Õ{ýXúÈ@YðæékÉÁϯ¹/Ð÷4ágÙ„ G=Ÿe›(å,%±}`¦V^ŠDm4w]ÚZDAD·P¦ß@4‚‰r2‰7b«ÜÔívF|/©=oG¬‹— "¢•0ퟫ8‹Ö+"»jCSçKUþI“U– ë—cIÉ#’R[CÎŤâŒCÕí›÷?ˆ2uÍ@sgÝ?hó(µ>\V2À.g´„‹žmc”G´n;Î=`7ÖU¾!VY)ÂÔçOÄËù¿Y€Qáà?ÀŸ€‚Ö,ýDÓùèƒQÞAê'*Jõ_*¯ªG”ögëÀ“ûÒ£PPv*õ{s@Dòõ”9ÇZrÁŠRÉÁ¹Í.jÉ”ãÊZ¬[|£$X ö ÿ³T>ú¹ "°§B …›Ô_ý˜¨A®±H7\#ÔLM<,ÿqóÛ‡o_n–×gÄ$Õ‹››ßqþÕõ›Á ~¥Ì¢ÈãÑÛÑü&ÓÜ7sVTxTAzï‹›å#EhaDB)2°Ïù™±Û›"R¯ð¾Êã¨R‰V/·”Ô ¶ÒÃÕ¹ùaÂ1óäz•Ðë[iäVà[›™÷»~|;L¸VŸZ*ž*ðÀÿµù4ä'/\t²«‰ùó_tZ\=ðt÷žÆ í=Í_ˆr*†ÿ¨¤þ…ðà;I,oçÇ¢iÔå°˜Øm¤4ä_bžÎ$µÚz‘"´}ÔÿXÜÇÞÜWß0C}µ@».Œ@½øÔê#4Ï Ì%dP $—@‡_{漎pp—8Uû^«¿Yr-‘\Ìåf×ÛÊ¿ÖÐPQ-bmò^  ÀÌ­Ä™¦|…ÇÊZõczzc§ãÿäú½ÁŸ®ôÂS;ð·­9RjÀhC¡Â¡„0؃çÑêÄYÈwú¯Úá¿ÀåõâÏC7ÍÒ“§û ðO–,WÏþVvH endstream endobj 3754 0 obj << /Type /Page /Contents 3755 0 R /Resources 3753 0 R /MediaBox [0 0 612 792] /Parent 3736 0 R >> endobj 3756 0 obj << /D [3754 0 R /XYZ 89 721 null] >> endobj 1626 0 obj << /D [3754 0 R /XYZ 90 569.818 null] >> endobj 1630 0 obj << /D [3754 0 R /XYZ 90 451.102 null] >> endobj 1634 0 obj << /D [3754 0 R /XYZ 90 260.518 null] >> endobj 1638 0 obj << /D [3754 0 R /XYZ 90 165.647 null] >> endobj 3753 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3759 0 obj << /Length 1066 /Filter /FlateDecode >> stream xÚV[s›8~ϯ`ò$fj*ØðhoH·;›4Ýv/Ýñ`±f0ò"pêýõ«Ã‘$Þ™}Bþt®ß¹ÈÔyr¨óájµ¹z»ÄKælîlJ'¡Î‚Æ #gS8’åÃCzóñ7wÆ"J–ž;‹(%émú˜Þÿ”"üà&Œ,Ý9%÷¯Í/ïo#6²‚Áh®=ö&óA芚 œ™˜±…V Pl³çî, 9ʦ…#ÿN)«E+dwBáWË*_8ÉÇD;«¥±¤Ž<`Œï4âÏIkݼt}J²®2Êwçõç_Q͆gQUxÚq¼ë/&î°©ŒU^»!%'1ƒÔuÚ3ß÷’ÈÜÈúÀëÈŒÉÉeÉ‘í*×'\!š5} ,ZX2ú˜f¾ÕÒ:?$gÀA'—uÍs£×Jû„¸YÝ­ꔨŸŒÔÞø»n¤l¯¬ä“¨–µ…ò¬ÚKe‚íþR†h.N,™,¡S¢áÙ…«º;ìxƒèwÑ  sýõ_–`kôÖ~×Ö¶7@íÒõ}_·_åÊ "²\§hÌRÿ²Ö±llí3…ò=A€ÂÂo(쥜 Jò ŠÌ„œe× †åÒÐ@)5hLeŽÐƵlý$ñâ&k³Z‹€ˆñ$r«Æ›“ëG„~ü葼kM"Z.—…±ÐJ‹ õšG‹Yõ:  &)eƒòøPBA¦Tôš*Àú§ÚïWضä…Ðx±¤¿ØÁuß]lòåxY`¼ lÚœ½)­†Þ”V+âxŒôÌHõ—ÐkþaXÉvo4ÊAã€'óZ¸M˜}Ï.äô¼v‹ÚQæòý‡ÎlÔáIíÛIFF{dжÌŒ1©ZÙØ/{À>9S>”7ùŸf¿éæê_»®= endstream endobj 3758 0 obj << /Type /Page /Contents 3759 0 R /Resources 3757 0 R /MediaBox [0 0 612 792] /Parent 3736 0 R >> endobj 3760 0 obj << /D [3758 0 R /XYZ 89 721 null] >> endobj 1642 0 obj << /D [3758 0 R /XYZ 90 615.534 null] >> endobj 1646 0 obj << /D [3758 0 R /XYZ 90 558.374 null] >> endobj 3757 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3763 0 obj << /Length 906 /Filter /FlateDecode >> stream xÚµVYÛ6~ß_¡G ¦Ž¶(°Gl4Akä¥-´D­Ùʤ+Ñq÷߇£¡lkãÄX`÷‰£¹¿9H‘è>"Ñ› ΫÅÅë_s1’fÑ¢‰JeD¤> endobj 3764 0 obj << /D [3762 0 R /XYZ 89 721 null] >> endobj 1650 0 obj << /D [3762 0 R /XYZ 90 690.045 null] >> endobj 1654 0 obj << /D [3762 0 R /XYZ 90 414.165 null] >> endobj 3761 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3768 0 obj << /Length 443 /Filter /FlateDecode >> stream xÚµ”Ûn‚@†ï}н„ p(mÓDÅ U›Ð¦IÓ-«1¡`šøö….V¨‡À«=Íüóý“ÉB° ]»Ñ´(ÐU]ð@‡ Û*¤ Ø.x“:Óil˜¯²‚”ºª¬0%{Ô¶¬©3NÄÑ4,±˜Vq#–ljñl$½ÛÍùú4-δ„î·<Æ$ jÀ (D'*B(¸•$m×Üå !¿á_1÷?ø]'ŠÂÕ\ÆPŠ#þ"#„¤™s‡Ü‹ÀïÖj9ä¶Pw·&Ý‚9ZQU§4¡"*Ö´¬eEYïUéÇ; ŒT’ø*á‡^à‡^Å»ŠvVÍÏS<óVÑ6•ªl!ÓÊAçÔËcöÖëžçG¦ËýRŒ±¿Y-}øK±Ëë–§3¸Œ˜ôº%6ƒð¢^¢s½L$qQ2kéáCÉζα;¤fú¿æ8©/¦è Ÿùe¸çYj0“«ŒÕûtkž‰½b±¥‡•*r›þ"jO$ƒêô²–!þÇìà©|’ÛÁ•É ž{¼ ®+2óhB¬2S? eÔ–‚ðä8õíÆömhñ endstream endobj 3767 0 obj << /Type /Page /Contents 3768 0 R /Resources 3766 0 R /MediaBox [0 0 612 792] /Parent 3765 0 R >> endobj 3769 0 obj << /D [3767 0 R /XYZ 89 721 null] >> endobj 3766 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3772 0 obj << /Length 431 /Filter /FlateDecode >> stream xÚ­”]o‚0…ïù½„ °-ʶ,ÑÎ…©ÉÀ,ÙvÁ¤~$¶ŠKü÷*[QŒ¸ ¥¥ï9O{ Á@0žÐqº0ÓÀðÀ„  { Ôtà…àMìO§öؽJ2Ö¡8P$Y‡Pôm¶àI¦*öÇà ›Ž,—½8#÷°ã† ÏËwOŠ>¼§Ž£cÎ_ËÌu#¥Ëí1Ö²M<Y5U! dÜM‹T¶-Ù‘,˜ü–|ïH4'w‘°.þØ”Æôž}ã—Üõ6¹-©cz'c’‘¦˜š–z« 6 f™*!¦$¡žÈÔ²§âLE9FŠš’_Iœ‰¡n…ÜÙÄA-ÚwÕ¬”GËÅ#¹q´¬C´ÉêxœL¨1ÍË*¦õâÌ yž\ª9PB×—/U±ÊR¾Tƒ©[bò¯É¬ im×ˈ„gôkFxDwU†—ñNõëFZœI&ú° hŸÒ`_+Ü¢{Ä󄵌™„â Ú"¶âÝç†4gsjhΣ-l;šÇ! ›s-™éUóófm o´Íñ=¼šûߣ-êìgþƒ>ѳ=áà&) endstream endobj 3771 0 obj << /Type /Page /Contents 3772 0 R /Resources 3770 0 R /MediaBox [0 0 612 792] /Parent 3765 0 R >> endobj 3773 0 obj << /D [3771 0 R /XYZ 89 721 null] >> endobj 3770 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3776 0 obj << /Length 504 /Filter /FlateDecode >> stream xÚ­–Án£0†ïy áµ a[UJÒ±i¤5U¥¶´q³H)t ­Ô·_c;iHBNÀ`ÿÿ7ÃŒKÁíà†.&ž |Ûâ! ¯À‡Àƒ#ºÐx2Æóy8 ¢GÓÂ7¶i zª5}ÇÏnïÕcÄêfÅzÅuùu$ñÞ¦:½˜¼åïÖæd(è¤=Ƥ^4€XŽïØa`aOlrÔ²êë-Ø«’/Ù¿–ÿaW«"_^«XÀLLŒÏ!d¤<oÆœ§_— õõUÔn1Yȵ}×ÞŽ=ò´¥PDRÑÇBpž½³ ­ÒpUIÝ™­E0²}4:Æ­a·4g±kÚW2¿ÿü´4¼ci”µÌaòo‡KeÑ@„BÝêè \•V¬ NìD‚‹Ê+…Zð6½•´â™n¹N­QJ6êG_ØÉfP:Qäe¶ÌÙB…ÛÇ2é}.“žz¹™Á‘ÎNvZû¬Ä@G¹Ôˆ³²êTúo)ÍÛÔ>ŸqZ—9•¹›i’DÁ9¤û½±{7.P¸+éò„_ŽÊ£>ù3„xÙRÄ“‹m]Á]éްYúƺ3CÎM42 Þk-ˆ•`Á5Û^¼ÛG¦5iöÆÔ4­:w#5¢ôä´¬®×?Íp;tHÿ/H¾ endstream endobj 3775 0 obj << /Type /Page /Contents 3776 0 R /Resources 3774 0 R /MediaBox [0 0 612 792] /Parent 3765 0 R >> endobj 3777 0 obj << /D [3775 0 R /XYZ 89 721 null] >> endobj 3774 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3780 0 obj << /Length 552 /Filter /FlateDecode >> stream xÚµTÛŽÓ0}ïWø1–6YÛu’žrqÚ@ê×Ù !QP%PIVˆÇÎe{Ù4Ý‹ö©uæÌ™™3¾¦£@Ž®c—Ïòâù x¸hb!jù|2üÅ‚ñ(ùMb##° i#dÈk>Hè ŸO³æ™Dió'NÒñ¦ù™gQž>pú,ß]Ç69ˆOupÛQÙÕá q4h„Ú„U¶`j©C4Üìð&qǸñ ,MŒT¢ìçîöOF9îà å@,â8m•UµVÕ*†Ä6~moWUOj*¬G)01¶<»•g­ø›¢öø€Bªñm ¿õG×¢.9&Z†~ê‹«#ŸÎ´`¡"#Ÿ÷’¹¯­SÖkç²Ìù{žÁ±m¼†˜=ü{{¤ô‘â{ÌN…1²°îA'ßæ $ÈØUk-‚„.5î~¯‡TœX¹}*ž0MPÇtZÙY1}ˆ16¤,ƒ,K¯úúpXÎ2=“*ã^ýî¡iƧ—ÆÄi݈ö}9j”åAʆ1y8;Ó:ó'š_®4L©K)’KDËæ4OÖ[CÄn’ "OY³ˆEà ž•‘Þ›®5û+mLJÝêǦº{Ö>ø>yDy±·4VC” 4TŸªù༉R$Ÿ^j¿( ˆÕ²û‚+èk‰_l7ÕúE'©exÆ)ÌïWSÊ"‘³²É™y>oi¼šÛ6/:ùLŽþÏÄìe endstream endobj 3779 0 obj << /Type /Page /Contents 3780 0 R /Resources 3778 0 R /MediaBox [0 0 612 792] /Parent 3765 0 R >> endobj 3781 0 obj << /D [3779 0 R /XYZ 89 721 null] >> endobj 1658 0 obj << /D [3779 0 R /XYZ 90 690.045 null] >> endobj 3778 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3784 0 obj << /Length 493 /Filter /FlateDecode >> stream xÚµ”ÑnÓ0†ïû¾´%’ÙN'ãÊmœ.à:U’nEMÕÕl¨´Hñî8u‚ºà®€Ô«´ö9ÿùÏçcc°LGãzt‘ñ$~ÑÔ@‚DZCê÷à-ó¹Ôi¾DeŽ}ä1Œa}%íB’ =-ìß> endobj 3785 0 obj << /D [3783 0 R /XYZ 89 721 null] >> endobj 3782 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3788 0 obj << /Length 654 /Filter /FlateDecode >> stream xÚÅVÛnÚ@}ç+ühKõfw}ÃåÉ &%%`'Tj+kbÛh1¹¨ê¿w/ q'UÕÖìžsfæÌøµ¹µÓÖqÜ:êy¶æßÅ®ßh>Ô<ØÐv´x¦}Õƒ( ‡ÝþÃÄÔa:êñ§PmĆoéÁðt¤þö»uÑë6ˆj9u/ÏHßã³£žƒ+ñmÜqyv2<ÆmjÁMšiù@k&ö8ÉR0š¯3¥=(¦? uÊ$Ÿ¯Éœ >çšßÙTõSnzÀöðþÁI!ýCëÌp¡Èrô+ùH”Y£ó«£jó`¥6.‡-à#¤0Qº¤––46<[\Ò;2ØÕY!·á–̨ܸ…É8 ºûuº§ÉdÜÃZ/$f'—ÃÏÑÁ½˜ ›˜l`Ù.¥™üÚ·mÞQ ¸ØVÐc`&‚|Ä.J¶ž–«lÄ»›lf ¶>½MEÛïdïCµäe$ÏŠe³ÛèÕDW2¦28`B;BÒQ’Ž’Tr‡¦½è5Mó¹et‘Loù`ÒN©U(¹^5….)K‹Y-¬Ke Wr¨ »¬€1ò¨¨TTõPÒ|•ùªó¶y~ê`uªƒ’Ǹ60Ô×% „eï1¿V¤ñxWÍÉÒ> endobj 3789 0 obj << /D [3787 0 R /XYZ 89 721 null] >> endobj 1662 0 obj << /D [3787 0 R /XYZ 90 519.146 null] >> endobj 3786 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3793 0 obj << /Length 505 /Filter /FlateDecode >> stream xÚÕT]o›0}ϯð#<@ÁÖ§t$]¦¬­4ö!m“å7B§KTí¿ÏÆdKV2)”'ƒuî¹>çB0\®ÒÁÅ8 @ìÆ>€‚F. 0H3ðÅÞÝn’ÉgÛAZW®í`­ôÍÈ\¤vì[Ûë[ó;I¦æc<™¶ˆWæxw›|˜}Kß^Œ1ÚÉè䘨êšôÅ4€mÁÀñ#ì’8(T1¾A‹jn¨K¶¦Y^ÒÍ¥S!Žç¹1n›©¥È·ÈŒ×÷"_Ê|Qõb 6ãE/jUå²TKVeLdôM:ŠÌëeÁ6ô(ꇅ(Y?¬Ì+úh#l±bÅûÑj ÿ€Vܬ`¢ìíLóv ;8¿‹\²YÁ)“RЊ•Ýe$\WùøÑö<Ïbâ}Ã0‚m ·=l­%¯jõⵡpB7Ñ>ÏË=ÁmOe¸#SÇ Ü8P2ô}7 [UùÌFJ ’¿^T_!DsŠ:T¾F*±ýêyu/M±Ï0ýÙ÷SsÙÑÈî ÿ:5è“0OíZ›%ߟyç3ꘄI6Öm4׊UÝÑgDøÛ¥ Rªl=¸­›×Gâ^Üõäô®Çgæzr´ëñÿp½ÕÔ8_«‘íÓí^׺ðO¶.üãÖy©uÏl]S­‹5ŒÒÁOnÜ‘Y endstream endobj 3792 0 obj << /Type /Page /Contents 3793 0 R /Resources 3791 0 R /MediaBox [0 0 612 792] /Parent 3790 0 R >> endobj 3794 0 obj << /D [3792 0 R /XYZ 89 721 null] >> endobj 3791 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3797 0 obj << /Length 566 /Filter /FlateDecode >> stream xÚíTM›0¼çWøXóaÝS¶$ÛTén¤Ò©­³x#K`"ãlÃVýï51Ù’Æ”T­z¨zÌÌ<ûùÍ@°\®’ÑÅ,ôAdG€äD„plC$ŒÉr9½‰çïMËEи²M Ah$/¦j!1#ϘÜ\ߪÏy¼P/³ù¢E’ì,hJûlü½xã·ŒéîL\=œ!¤ºãt#ä` º=Ç«çýº¿tÝZ¼,ÅP¡”bÛ"Ý_n¥mDo® YùÏg+ú§³5¦Åï†j+qvšvÂë4;¦þå>L“Ñ7©ê¥ƒ endstream endobj 3796 0 obj << /Type /Page /Contents 3797 0 R /Resources 3795 0 R /MediaBox [0 0 612 792] /Parent 3790 0 R >> endobj 3798 0 obj << /D [3796 0 R /XYZ 89 721 null] >> endobj 3795 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3801 0 obj << /Length 449 /Filter /FlateDecode >> stream xÚÝT]Oƒ0}߯è#<€miaèÓ  3ÓiÂŒ‰1’ ´?büï–µè†õ+›F}*½œ{znÏI!¸lu6ãÎZäàÛ¾‹]ŸvmH(ˆÇàØèíï‡{AÿÈ´0…ƦmZB#Þe!6}Çèím å¶ äGÔ(ĺ\v‡Áhðªé$ÞY‹(ž;ŸÔ‡SW¨›Tƒ:P n¯B=œë¶šv {¢è¨8gù©‰¡QñìÐô±‘NªLs8"¶O°P×öº®l¾æ¬:ãRx‹!ôÌ$ÔXÙ>Um³¢g«êBÓÂDÔ¸—„7&¦3Šú¢û J'9Wð+¹Ñ‚cÓ¡F>}–%;¸¨háb¬¼¸ "mƒÔ“²Œóir§%ZÄ(m–fðÇ ­“mh{¿g`â¬ÎBÉõ¿L¤šË ò©„³DØ¥5]¿}WüAVÏ2V²A~­î9c,™ˆÝOæ|”ïóy ºQßÌCÍÒ4м,VžŒ¤<êà•lš*ýcQKÎg…¥å~G¢è_O]a¢èoI”»\¢æüÉï/³ß÷–}5yî·$/Œ;O¿apü endstream endobj 3800 0 obj << /Type /Page /Contents 3801 0 R /Resources 3799 0 R /MediaBox [0 0 612 792] /Parent 3790 0 R >> endobj 3802 0 obj << /D [3800 0 R /XYZ 89 721 null] >> endobj 3799 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3805 0 obj << /Length 563 /Filter /FlateDecode >> stream xÚµT]o›0}ϯà Æ`ëS:H›)k3M“¦ 9“!ñÑ'm4í¿ÏÆ$aÄMº(y_î=çÜã{ÚBÚmï&î] }W ¬Àƒžϵh>è[ÀEZ<Ó¾ëƒÉ$ºGß " ßX†‰Ðã»Hb#pôÁýíƒ<ŽÂ±|ŽÆMÆ;ùøø~ïýˆ?\ lñ»‚y\]M(’z Ü}rõ UmnÊMèó #AÞÿÄÅ‚D+Ã:)Ø„v_/Ÿì¶k®Ë«m ¢¦ºbtùȤò’H…K1mÛ 8q]ò»ú–ëÃæÚb¥ÅBbQ’%5Þõ?ŠT<­¥†Ä€H_}5lÛÖ1ý\W(ÅkYN„ÜFŠ*-‹JB˜ u®•^w=Þ˜ä8ÁVçX £wiÅJº>æ®»ïnÓG¤Ûí«æNË2#¸h,ã É\Ü8N32Sú&ˆÒ©¾d¤q/[ °ZÄñå¥%s­Ñâ¨2Ø;Ýàþk'ÎY,–00Ù;h2§UÙ|ñ±LÜÖ^ášû_®µ—¹À9Q:ÒÓ|kÒn®f˜‘J9‡ü&xƒë·Œ¬Pÿi‰³”­wÈ¿x@elTÔ?‘Nv‚EðøB…i¾«¤É,Í+eÛ*"™~Ó³‚é@KÏǘº›®Þö70Éô6Óå‡çÎ8ì­ 1ÃC¡¹¤9Þ:Næu@9-Y¹®3ÙúIæeÚ»(îýxíoâ endstream endobj 3804 0 obj << /Type /Page /Contents 3805 0 R /Resources 3803 0 R /MediaBox [0 0 612 792] /Parent 3790 0 R >> endobj 3806 0 obj << /D [3804 0 R /XYZ 89 721 null] >> endobj 3803 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3809 0 obj << /Length 527 /Filter /FlateDecode >> stream xÚÅT]O£@}ﯘGx‡á«èSªlXu4&› Ë´™„…AÓ˜ýï;ãÐ-­~¸fŸ€›sî¹÷ž{` ¸Ç£“©kO÷ä€x<\8Ö¡eƒ8?•Éímp퇪†l¨œëªfC¨ÄW Īg*“ëËùú‘|™†Q‹8•ï7þ]ôô+þv2µQGßâ¶Ã«{—G¦)@#Ø 4slëŽ4ärŽÙÉXõ£ÁeˈÖLª<ó@}&Øœ©†îÙmOAÆÂbRUx`ìå ú¨"¨4Œø4_3«$¥ùþB~”Òk’3¬ôºKÉ'*²•— ªÊJÐÖT"Bû÷$á]%ÍÕ-m2ŸmX¹zò„Ð K÷,n°iêc×ü[©Á+½ÈÓ+.ZVËžÍYñ—4Æ’W³ª™µE¶ÝnæØîîí=ØS|¬š¶Bsr¯†¡àLæd<Ò;¥Ç²Ì.$j–§É\5 ‚iFÒ^ÿ8”7¸”øQ(β—kûêá'Ö¿¿Ìr´ëÖSÌHÿ®0Õá«;èæþßÅm‘²²X¬·-ŸÈïFXÌEoå§Vƒ')Ú ž†v-ðöA:½óÀ‹S£Eghƒ¨²aðnmmº$%õl'x•µƒÞ°Í9Þ64d[‚>mœL±Û:g_ëVGCë§H*‰ªIûïͺ¡þQñèΰXw endstream endobj 3808 0 obj << /Type /Page /Contents 3809 0 R /Resources 3807 0 R /MediaBox [0 0 612 792] /Parent 3790 0 R >> endobj 3810 0 obj << /D [3808 0 R /XYZ 89 721 null] >> endobj 3807 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3813 0 obj << /Length 482 /Filter /FlateDecode >> stream xÚÅUMOã0¼÷Wø˜ì$ÎÇöThËvÕ$² ­"+qC¤#Û] ­ö¿ã`·¤%UøØÂÉŽ53ï½Ë œŽÓÁÑ4 @â&¡‚t"»0À -À5º¸˜œg×¶ãah»¶ƒ!´Òï}Ú‰oÎNÏõçl<×›élnßôòó|ükþ‚ô;ýq4Å^«~ÐÇ¡êç hMÃÀñcì†p¼Hq|Z²ºÔÒù]‘IR’"8¹ Æ»¨ªÎäÃ=íA±•Ü’W;rYAEÞ ^«¶ÐNä‘g(¡¦ünͽ^UZ°å–ƒ7 ”¾ïÆ‘qcLm„­?“:g-:<^“¤Ù³zÑ4ÎÞïµR`ﶺÐY¾$BôÚ!(7gUñô-²3‘çW¦…6«¨ö\‚­Xž­øò3"Êü…¤ù_SøÆ˜ð!b‚ýƒ>ÿo•©lž×º¤J“tðU~¢ endstream endobj 3812 0 obj << /Type /Page /Contents 3813 0 R /Resources 3811 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3814 0 obj << /D [3812 0 R /XYZ 89 721 null] >> endobj 3811 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3818 0 obj << /Length 526 /Filter /FlateDecode >> stream xÚ½”Qo›0…ßó+üPÛ`ëS’މµ‘F«JÝ™â2$b&p*MÓþû †”t4I×fO€¹çÜÃçk H£i4:[¸6ðLÏÁˆ€ Ç&´ ˆp§M–Ëù¥Üê&P›šºA Ô¢sµ鞥M./®Ôcà‡êf„mÅuù|å_‡‰¾EŸÎ÷úÛusâÈtM{l‘ºhÛÀÀ°<ËD»Rd©²J”›{¡Ü}¦c¢=\”³ï”§¬6b!Ó#ígýj]Óvñ(rF¹²J”Õª´,9rjÛÍÖIÀŠ0«Ä +õý:©%!Ê,Ö1Ô6‚Í þBœ6J¢”TˆViô#:Jþû|Iw• { d›žmK`–9v­mX$Ã.³lšñÿN…eCä¾H·ï°ý<ç[é“ñTùpºfûxÞè!–u#Ÿ :ÏŤ,éO¥ŽeëU"—(‘÷¤T·>Di¼—RçpôE)Ò-¢ekÖbÊU¹Èž—;;P·»¦¦[&[Õ$ÿD¹oçØš¼/Êú4v¯yV´gÿ±îLóͦ4㜕=ÂðåtO¥«§ §9ü7º‡ed¿ØÄ9ûÒdP™ÿùgÐQ´<úï0hÖ£™¼jGú)yõL~šqoá†O_v|í€áѧ`ÀªÇ%?!Öý3;Fí / endstream endobj 3817 0 obj << /Type /Page /Contents 3818 0 R /Resources 3816 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3819 0 obj << /D [3817 0 R /XYZ 89 721 null] >> endobj 3816 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3822 0 obj << /Length 575 /Filter /FlateDecode >> stream xÚÅ”]o›0†ïó+¸„ ¨ùíUšŽ(M‘J¶IÛ„ðKžƒŒÓ®šößç`¢Bê)]µ+Àœ÷9Çï96Ð6Ðn×éàbzZdEhéw-Z†ð|--´/ú(I¦ËIüÙ0è×–aúè釩\HÈÕGË›;ùOòe/šˆKù¸½›¬/DßÒùÅÌwZù½Cr?ÕÕé78 @SðéSTZjó(7P,º2%<¦#Æà“"¡íY‘çi¦=´¼0‚г}Îe±]±HjÚ¶ù=¿êÅPHî²£ ¨8düJ%~Ž¡ë ‘&ÈlÓš‚~_)]8Ýýq/.°<×n6ÿ`Ø@G”'̰‡ú®DŒcTõqB|IjSÎ[Ò°Æ[H7¨C‘à|›!Ãñõã¥Y bxWà\¡ż0bù?G)8©+1ý}CGæ8lÒˆ¬cBy\ˆlçz¾ìÉ\p€àX—óêA4|Ã[ˆé˜ÀªRØÎµZÅ©Ùïqñomr¤t  b‚f=L™^ÖclGr$£—=TÎdL‹ºâŸ¦Y QÆ·«Yàª)1–ñõ.×@rè]ëu®„®ªc_gËšÖõ*èxõѰm[œÐûZ%ïcéZm7G´Â;Z½ËMp‰Æ;úgÓǪùéß6{í U9Ã%Nœ%pþ2¸*­k4‚ö’úŠýÄ0G©1úS‰¤ðQ,Á5Aÿ£½ÓtðSC endstream endobj 3821 0 obj << /Type /Page /Contents 3822 0 R /Resources 3820 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3823 0 obj << /D [3821 0 R /XYZ 89 721 null] >> endobj 3820 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3826 0 obj << /Length 750 /Filter /FlateDecode >> stream xÚ¥VÁr›0½ç+8Â*„À&9Ù'îP“‰!ÓiÓaVbf0¤ Üf:ý÷ „ Ðàp2ZÞê½ÝÕ“Ü#¸Ë³¹söi9Aœ.éÔ8çÓ7S •s¶Üw~v}m®ÕWA„*àç’ ªðΕÉŽ +ül}i³åʰØÃreUˆsöóÅ6\ëMÒçó§¥ kü¨ W5ª®¤‡Ê¤Jpû—ªµlñ˜. *lG§|¸Ç·|P—dõÈæ3@cK$!ˆŽ€¨cQžJ”I„²T XFÒ< Çb•‘˲Ìûåt;Q–%]­šü§ N$4ÍQ?²mÈÁËppÑ•ÝåƒPñ J¬³Vòÿ^tö¼ÝkI:Bœ¨(”+–oûŸ ?ŠVñƒU>éh×1«§]¯$ìÔAU§Y˜ÄÈã,|Œñ–¡_ó’v⩺ðˆÙc²K¶^ìïq'ÖÀEÙ‡jÖébç§³4õŸYvn›YUý÷Ia?®dÐê½0ópQÆï?‘ŽA©õA•s¡mUÛƒQAKHe@½ëÆ´3YÇI§ª ¤C™TÎ'$½tHÏl™òŸY6Û[`ËRØìØ»¯áìWH‚{¾*(`ὟløÄw„)àŸŸ0})÷‚V0ð3\Ñ–”ŽãÍmÛ:ï;0­QÍÙ jÓ*¦âù„x‡èG9îwLùæÊ¾´Âÿå%8LÅf—¤¤¦!+ÖïŠèï€e¯/‡r[Ô 5êÂ#™5t ·†ZìÑþ¥eoµ>eË(ñë3¸@¡‘½0lwn™Cù$¿pMÀ¶ ŒàwW³›7ìÚ++èz õ‡là¶}5‚{ŠÜ–ò‘^pûÌ õÓ7Ü´C¿„s³Þ€Mù—W¿‡ÊÀ(þò›-Íá:|‚2èút†y»Z˜ïjhN£ä® È"Þ ýI¥›ë…m˜ÆÐšÍ8H¶x[«³HGÝo>ÑLçì¼ôÌ endstream endobj 3825 0 obj << /Type /Page /Contents 3826 0 R /Resources 3824 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3827 0 obj << /D [3825 0 R /XYZ 89 721 null] >> endobj 1666 0 obj << /D [3825 0 R /XYZ 90 443.529 null] >> endobj 3824 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3830 0 obj << /Length 1316 /Filter /FlateDecode >> stream xÚ­WKoã6¾çWè(akEïGrrbgëÀ…[è#Ñ1weÑ¥èdƒ¢ÿ½C%ËŽ‚´Ø½X3Ãá7o’ö¬G˳>ž]-ÏÎoÒÈÊÝ< k¹¶rÏJ½Ìõ¢ØZ–Ööøþ~z7™ýس¯\g{ž½üyŠ‚¥“‡öøîãÙÙdŽÄÍln4.ðói1ùuþjÓŸËÛó›8èÙ”ñ8ï´ù ̔ҙg¶Faº¾X£ …M!ª¤¡ˆ=v|ß·—ËÕÝb5q¢N M^(,+u£öû¾›Ç&Ê u‚Ø~ºâ¼¢¤F¤}Íx½ªùª$’\꣭ÿ\b©×‹bäGnEàdèæ>*^Wµœ•´–Q·ê8A}m]9lÕlóÌd±Aú³{s^|u|ϦbNêÇ=y¤ õµÇÞ±³ É»¾¿3E׻݉Ån·*@ôvnÈ·N¢KÆöoúw &î[âžý¤ BN,~é-½cºWHn%ÁQ]ÂÐM‚U¯ÜØù´õô[AwÒÞ Ô²n$]ËøÐ27ÚVÑò½²Çô¶Ö†eºïF­tPåȗÙ=‚‹9kLª¨b›жŸö•d?0Øï;"¾#[Z~wØCmÅnœæm[$¦-fµ¤bM Ú_ ƒÆ/.L^,½NÈIÃ,7j˜Úë}]Bµ$ ˜ÆWŒ6”HÊ(õOZ`ùÃZÈÎãЋí)ÑçÈMZX ăƒŸšÊgeˆ‹¯}¤Ÿ7¬…)ô)ăÁ!EA›f¸P/ÀÍPÌP9žgàAAÏ$xÅÉD~ê v‚K^ðÊ@Õ%[ýg&:JçŒd6[Üë£ÞE¾3r”ØpšmPaÛ]EUEš£ðLá°à7ú‡öiX2(f'†fkJKH’Ö‚°ä¬~Dò‘ÖTàÞÐn^êb#xÍ÷f7©KCœ,…öì|K8G.(ÈKãÛUÝà§pÎê¥^àEë Ÿö†(+©o««Eè ˆ†§ ÓØžt)@AР $OÇ +¬ÆL [ñ5JÆR ö ó½¤-ö¸K¤2+ÌæxßÀc5âBc¡êª5~¯ùv á(3Q–cchùâ—+G]EÈöûDñ'}bAeMEƒ<9 ÃÈTâB/··Tnxi¤’›U=FFÖ:r3‚f0—‡XÒÀÓ®+iÅô©hœ EQÒ{u‡Y¢Œ"™ö¦„Ñ*¤bÅ­ß"uýá\ @ÿz‡Ø€3@= ²Û)ï‚$ÿ œ-ªòIouÁ“ _‚Ÿ1Œ¹=s‘Á)âhÊ“×SÀ%m È3ÚÉ`ô‘•´ç hºåÒŸM§ˆîPL³Ös‚×]èA&)‘{¡›¸ŠáC 9¹””ÍOÀ~[Z\jh±L¾8Il›õ`\‹´•…îg3)JTRRI$á¸AŠÕ- xRw•nųÒlÓc¢½¡C§_ÙO¬z|ö€¿å%­Üíªó´÷_æÆ~Öݧ®onÔñ«ŽýØò371[I¹]ÕpeþÇW‡Êª©n|2]&à‰ìuØ—ƒs×îÞÚ-¶~aké¨Ãa5¼C‘ܤæ4uð¢ÿkohÒŒ!ÉÔ—}ö¼rÚÿ³Ó~ßz¥Á#6KöLª¹ñõv–ˆ­­ÇÿÊR~0Q}óïçJß‚úõs }I§o(+ÓåÙ¿€ê endstream endobj 3829 0 obj << /Type /Page /Contents 3830 0 R /Resources 3828 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3831 0 obj << /D [3829 0 R /XYZ 89 721 null] >> endobj 1670 0 obj << /D [3829 0 R /XYZ 90 531.101 null] >> endobj 1674 0 obj << /D [3829 0 R /XYZ 90 345.487 null] >> endobj 1678 0 obj << /D [3829 0 R /XYZ 90 194.977 null] >> endobj 3828 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3834 0 obj << /Length 814 /Filter /FlateDecode >> stream xÚ½VmoÚ0þίˆú)‘×qÞH÷©¥cb¥ZÙ4i*.X‡9ÎZþýœØ$¸tê˾`÷8?wÏÝ=W 5· uÑ9wŽûq`% ‰Pdï¬Z1ì„Öxfý°O¯®Î/{ƒïŽ‹BhŸÇ !´ÇÏ•aì$¾}zy1RzCué†ÚãDŸG½¯Ã½G?ÇŸŽû!ªÅŠàa$³+Ã#?)œ:P'Ü>eö°öÚ­ž»(–F_0¼"†P^’ ®H¼®råÏR¶Ü¨D±œNí\eʤ…ÍÕ½À}_ËT\O¢„a-`érCXaÊ»§¬®:rFçÚgSJÕ•ÎôBD¸‘|›tEÄ÷A7Öœ3Å«‘î…öŸëS—A^ܳÓAò3…I§uÄÑͳ·h²B~”ª ú\®ºï{ý×ÑK.’¹ŠˆÔQ„›3且º­ Ç‚¦,Û>ß•¢È¾ "ýl²ÄÓ_·“ôá@Ñêdõ |s<ϳ1¿.“<åë2nñŠJP¦ŒËt«•|5!¼¬Œ¡’ÓŒdÅK¦ïx¡é’ÌŠ'Ûê#_vq×D„fBÝÒ;mÁ•åRÓtµÂl¦kM ð‡âƒLeÏ5ÌD™.©Ô_5K~³€e:ƒ+§+ûÆËLWDH±z²y¦‚ÀOª•vR’qýbAÅ­½QIBQ“U“„HÕɉÈ93dëÆ ˆQ3À—ÒÙ”£A’ø­%ÛyMˆýjë¼ôW—ZŸT4B 𢦢5ê-ei.þQؘÍØ4ÒRõ¡¬«[;½Ó›—U$j8E‡»öœ²W^=;­Ô‘ õLY㻽M²aÓO%ŬÚg÷T,´æÒŠÖ:×=[c®gµÙ­”‘ö%†W‹â&N ý3Lgƒønþ÷W£R1˜Ë_#¾Ä?±#Sc¶k#6=^]ùÏØO±ø*‹ ¥à$Ë—¼XJ…toå/¾yJOqcçXÍì.n•¿XLÿž>¢g/w•¤q⫽—m¸_`aZT[³|½NùÁ…þöË1kéM,ÕS&6kb^“çãÎ_Ëšá endstream endobj 3833 0 obj << /Type /Page /Contents 3834 0 R /Resources 3832 0 R /MediaBox [0 0 612 792] /Parent 3815 0 R >> endobj 3835 0 obj << /D [3833 0 R /XYZ 89 721 null] >> endobj 1682 0 obj << /D [3833 0 R /XYZ 90 493.99 null] >> endobj 3832 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3838 0 obj << /Length 690 /Filter /FlateDecode >> stream xÚíU]o›0}ϯà¤áÚBèžÒ¦é2¥m´±iÒ:ENb2O|t"åßÏÆ&š­i•M›´' øÜ{î½ÇÇÐXиî]„½³±ïú¸o„‘@Ç]ÏWÆgs8›]ÝŽ&Ÿ,{м–íAh†o®Ô‡Ð sx{}§^'£©ZŒ'S½ã\=nîF¦@_·gc7ò»2¹×ìªôØ…rSjÂݧ`h»†ÛØd™% IWóï%åÛ9‘ ×5l$>a]÷ˆZØ37—Éj’F™âÝŠs=ÈRõ#/8K×­Mâ7’©K!x:.',§¹ë c y&a1­ ¯k v@€Â(ÞUô•±%Uï…¦–SÚJ¯^·ÐÀ\— M ]·Ó¨»N£²Ì¬B: -¨X‰¸‡Fä× ê WŒmGöÛo×Úârq_­RþÛ®ÛÞÑ¢äé!AàtHˆj<Œ~Ab·`E®¸} ùA‰u¥…1p‘P–ƒÀ` {¶¦Åœbú C³,è|™¥÷âõ‘26Á—;ey¡Øý<~S~ZI-„˜àûJCÎÉvßðü”‚ä”è>_wºS¼JN –ibQÆußÕc#ÎÈ"Ö°xWjé­Írõ"ž%­@cðçe]é·£é'êhÌ¡}n«Nþþ³ÐW¿ŽbÙ™dÞ&ú¼c¢Ò²4’ãÊžg½{ßøL ô´–ݬOYJ9‰÷ÉxÒ1YdeݵÅ7ºÔk Öâ2t„˜–1ÉóW{;ÑKÀ“â<¿uoÉÿÅ~ö ¯±ã¦´‘¢É˜ö <õˆvw*9òòcQíî³ !sÑ£šRWÚPou‡ õÏ;Îôƒ×—toñüqè¿ÄÛÿ›ö¿cÚjHBXOÙõUØû‰õ Ç endstream endobj 3837 0 obj << /Type /Page /Contents 3838 0 R /Resources 3836 0 R /MediaBox [0 0 612 792] /Parent 3840 0 R >> endobj 3839 0 obj << /D [3837 0 R /XYZ 89 721 null] >> endobj 3836 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3843 0 obj << /Length 1146 /Filter /FlateDecode >> stream xÚÅWÛnã6}ÏWû$±"Qw÷)‰“lŠì:غ‹šÂmÚ& “.%%Íß—äºYN·A€>™’f†gΜÒîh;rGwgWó³‹Û8¥N¡h4ߌRw»‰ãáh¾ýa]>>Þ|Þÿ°Ç(t­+LJ®kÍ?ßÀ‹¹úÖå×»<ÞO`q{ÿ -&ðóe6ýýáÈéÏù¯·!jíÈÍÃH SÛ£À“Fg®ÜÿèÝ–÷ظQ,^ú¤Àå"+KN–6r­ªÄ‹£O®‹¶¼ÀIƒ@ðœÔK À³ôcd ðO‡{rC—P°ºl[\kƒR”ð™b…Ö‹tÝ7•¥Èhì‰mCÍ=ÏH tª¬Ÿom/´2’ãµtùÅø _@­S…øåÃÂ`«xV¦Ám‡E?Ï2|ÆI¶Ìµ[^#emÚN¨Ðq8Û÷ö[T²Âš\¿En죈°\%µÇ%+Áî(B'ðS£‰‰Ê{ìË Çš±>µY8OE?•Ñl• ~—¸À (ûbDÈ <¡Eßw’Xkñ…!˜—ÿ¢ÂxH…CNêï»íyž•ån5¯Š#ýEïÖŸBõ!Ò2¤gÿ§¬ÂšyMÕ»DÕw7©Y —Ž(¹D¨¯œâʉí±çŠé{OER›l…ëqЬŒnÙd"êäK 4°«"£H Ѝ8’:Ö´¦YPoÝaó¨áçŠe³k«6v›’ÌåtðÓÔªë¬ÄBÂÛ ßZ%VÏxâà‰Ãĺ/ÁµA%-•\ £R.]ƒU‹ ¨·)ªÃq*Ësm^ŽA&¶ Z%¾`l†…ïI¡ÊBeŽò‘è×j>ÊÅ „`ÛM8HtB/ò£ëÙ·+Û­Kx¬w/ày—I\ÏR:êcaÏÖD‚3Ø„N͇¬r$\8†Õ!ãÐMJ ¡%ÇŠí÷‚Ö¡¬*A0ð,gëÞA‰äÜ™ù(šàC¬VNÒ±“|¦LMuµäWfR4߈"SÝ›BsúcùzÐJoã—]¼ø«ÂüuÎÍAŸô[ÝÛTßí[W¯iiE+2­—8¡¹Qˆfv<Ýγ&]ãØiY/q"íÖ'üôÁÑ®hF¥^»‰éí#£ ÑmÇìÜ C@+’±‰µ%´g¤eý«¸+…Zà=G͹¿•ÊWUïÄÑÐõX¦§ŽöJW;ÎE®Óz!åNßјIìPi%Õ]У¸¿¨Ê¯Óg×›‡×d Ò±ĨKd'óæÊŠ!Ç%ÆÎÖAðiF? ¦®p?bg£Az†KKM¨¦7õ÷cŠÆ©~ÃeÅéЩî»Nšú½S]P"ï ¶8.ª¼tÞ}¯ë¶ÕN ¦æÆÏýÁк¿Þ¯?ƒgsM;ø¿õmÎÌwú!M¨Åz‡Ë=•°Öxû—‡Ëó2ÌP3´mqhYΖp›æŒBëüè¿MkÛ}e(3÷t¹ ^;ï¼0Nµp3?ûJ' Í endstream endobj 3842 0 obj << /Type /Page /Contents 3843 0 R /Resources 3841 0 R /MediaBox [0 0 612 792] /Parent 3840 0 R >> endobj 3844 0 obj << /D [3842 0 R /XYZ 89 721 null] >> endobj 1686 0 obj << /D [3842 0 R /XYZ 90 443.121 null] >> endobj 1690 0 obj << /D [3842 0 R /XYZ 90 326.518 null] >> endobj 3841 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3847 0 obj << /Length 732 /Filter /FlateDecode >> stream xÚíU]OÛ0}﯈xJ¤ÅØÎWÞ ¥¬ShdÓ¤1U¦uK¤&él‡?'v n3З=Ù|Ïý8çÜBkiAë¤w˜ôöG‘oÅ qh% +†Vûú•Ì­¯öàüüøt8þâ¸8€ö!pÜB;yw¬>$NìÙƒÓ“3õs<œ¨Ëh<Ñ/Ôñáløi²ô-y¿? p+¿_%BY]û¸zÔƒº`Ëõú}ËÅ‘ŒñÔ«Y‘e$Ÿ+ôKŒCu#|–¦êÊKó¥ºS°”mxÚ{gù^/¡]„@è¦óM$FgÓøy™]Q¦K÷Z¥»ð#l"}¤¢d9ïhÔƒ ޽¦Ïƒº { ÀÈ„X¥\¨ÌÅBF»Œòr¥\ÂLwé Àþ9£k‘ºŸ5a$£‚2®~§O\Óà…#'DÒKX šSж'€1ðQ(Iò@?2É™V}L¿—”ÝNqÇ<b¿âU¶Žú*tHØ7GÙ|œ/ŠI€J ЪûªÔ.FI9åÕ 9ªÆs×ÝÛ&F#¤bjX•n®‚Ò™”(´¬¨þð㚣²fÄú+/×ë‚ Þ!›&ëߌ®éŽaÉ{ªÕ"n×”¿˜â—°»Él‹Ô4ß6±~¶¾ŸN·aÂÔ·—eFsñ¿:͹ÓW!²œÚŒ•ͺøöà{ñß^µõ"³×ßl¿\Âÿ»-eN¤¹¤‚ïB_K*¦DHö¯ íRÐé¬È/!ÄË?Û ~¤£Ûå¡mj=}vB’Ç‹Z“ÆÈíýØù.×£d¾µ§Ue%#÷Û}Ñl~¢Ž›*a)¹Zé°íÅ`4¬©Z°"3€Znxl{í^ܵŠ7”ýH-LûÖ“|ÅÿíŽ*7˜äf¡Ï2K½$€©fþ<§h™¯J:¹k‡u?Ù"oô†0c.Š’5[—×÷gZéa'ý·ÈëZ$|‚EIR™ã8éýÊR– endstream endobj 3846 0 obj << /Type /Page /Contents 3847 0 R /Resources 3845 0 R /MediaBox [0 0 612 792] /Parent 3840 0 R >> endobj 3848 0 obj << /D [3846 0 R /XYZ 89 721 null] >> endobj 3845 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3851 0 obj << /Length 1071 /Filter /FlateDecode >> stream xÚÍWÛnÛ8}ÏWøQÖ EŠ–•}rÖIêEZ‰·(°Y´M9dÉ ¤´ùû%9¤nV“4[,ú$Jœ9s=36íFhtur¾:9½ ƒQäE<­âQ„F!šz( £Õvô·3»¹¹ø4_|qǘ"çÜsÇ!gõá>¬Üˆ8³OWKx]̯áp¹¸6gðø¸œÿu}¤ôÏêÏÓKŠ[öeœN¤wÚ<ˆ:AÆáþSzZÚc«>Æ¡üHD¸þÔálûÀÊR$k#§*ùÃcR”¹x~Ànø„ñ½ÈŸÌœ»˜:O3 òT¯åBGðEƒ(J2,¤H¶ƒsÆöü78Úë4¯/¥–¯<“qŽ}é5,)x¡0C—®O–¤|ÛVÁDzWÜxÙq>=)–VæÕø /±È÷p:äiZ» ±RŒ¹p)udW9˵òä)É«"}v'Ô1Á•ü»ö÷•Máš7¶øÖ3E!­¢t£ºq§Qèà÷¼”žHŠ¡–¢^@"ÛQg:Ac¢ú#4™À•ªøpñN³c—±2oªßÍß@ݲ>ô-ßäÂèeÕ~-#8ŽyzAˆ»H·¼¬D6*A^‘^¨2gû]ˆ´îÜ<~ko¨–Ëœ¹Jû· ?”In;0u(LKǯW?V5«[×Ô\2ZÒ¬€±ø’ѲŒ4ŒÀýsoêŽ}$'Ñ"“c¶áõhÁËvùÙÙœC7nøHÒÈXö€FL4ŽvÇbz€aé#IYôé±Ò­h­Z%=WšIÒtîJe„Hç«Ã–•\µ@5 p·­àºç ‰U5Ô¡¥ªDO9+Œ•ä hä,J‹ccÐ:†F/­Ä²-HÉb >†¾²‘µûJº¤ìÊ"Õá mGN{–¦ð¹Ó§ù -¤¤¶ü!œ©Œ(ÙÄ|Ö¤>|×G%ÕI :$¡s—|ƒË?–·ç.¡Î €j»Å Ss…ýUŠ™LE683õmb‡ÏJ¸‘udp*ŸNŠ/C{ȱHBä|•eà×þÀB©÷‰ÕO²8W/íÌ$Ûñ²§¼É3•Ûme]Q½^µû8©3„-w¦µ‹Q²Ñó —ÌöÖ³òrêM,‹‡÷r1H×N³™(;³ù³ëû¾žVj+Û0óßÞǦŒ¶¸Óëy&{n†}Ñ[ÒFç.¯„…>¿seÿ>°³›•ÂÚÃX$l›¯Ìð£)e€Zƒå×X±oÚEº[w ÛE«.`hS«_u×Ýà^ýÅk×#!Þ44?x‡'Ëæ>)<1Ý7 ÕfÐ ,ì‡ö~ê}¬Ò2y3y´Ó?…=¶×~„;?Ÿ<´®L§G~B}udë½½öÊŸ+òŸþ\½4Æk ÿûß«£<]¬Nþ“× endstream endobj 3850 0 obj << /Type /Page /Contents 3851 0 R /Resources 3849 0 R /MediaBox [0 0 612 792] /Parent 3840 0 R >> endobj 3852 0 obj << /D [3850 0 R /XYZ 89 721 null] >> endobj 1694 0 obj << /D [3850 0 R /XYZ 90 522.922 null] >> endobj 1698 0 obj << /D [3850 0 R /XYZ 90 406.219 null] >> endobj 3849 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3855 0 obj << /Length 928 /Filter /FlateDecode >> stream xÚÍVßoÓ0~ß_‘ÇD¢žíüjÆÓF·Q4¶ Bbhr[§ J“ÊNûï9Çv›¶6@<ÕN}wßÝ÷ÝÙØ™;Ø9?8IÏâÀIPÑÈI3'ÁNŒ‡¡“Μ¯îñõõéåhüÅл'È„»éÛSý!õß=¾<¿ÒÛñèB/ÎÆæÄ‘þy5út±cô-}wxÒNü@#@׆§A `Øø‰¡Î€Æ`äëcç¼Ö®Y]‹|âQì65ןî=º¬hÌö.—u%ô&ÕB¯–UQäå\o´ƒLf\xaèBÞ>ÁîÕÄ#¡{ŸW,¼(t_iƒúŽ?ÑHnÂ×±ø ™ìýNöÒòQBtV×Þ< ’-x H‚ì+Zˆ?±5;R' Pª>±3 %¡a³?à ¥‘^ïB^«+ý+8›mÖOÅÀ[Þ·]àÓJ»²YL ƒÝœ1 bj> endobj 3856 0 obj << /D [3854 0 R /XYZ 89 721 null] >> endobj 1702 0 obj << /D [3854 0 R /XYZ 90 174.229 null] >> endobj 3853 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3859 0 obj << /Length 955 /Filter /FlateDecode >> stream xÚÍVÛnÛ8}ÏW}’€X%©›•}J6—z‘ÖAë l-Ó Y (*]ÿý’J–¦u²¶O’¨93‡3g†D΃œ«£³ÅÑûË$tR?Iì,6NŠœM}FÎbíüåžÞÜ\|:ŸýéMH„Ü3ß›D¹‹°°ðÒÀ=ýt5‡ÏÙù5¼\ήŠ<>ÎÏ¿^?ý½øãýeDzñC<Š»&< #mt„ aÅ9ûi¤PÊ|ÒÚOH¢|€:óS{ŒÕùTò²¨ šÂï£!g‚§~<˜ððÔet½¤R ¾òrkɪehá‰C? Co¸˜\õaß<Œ±Kóš]óJ*“ ‰]as‹"Ä m¸çÌ#‘ûhÐ⋲,îN… ;pPÐ-«Ž=½ow„ùRÖ"c`V5ïÇ­Åïy!g½ ÅØÂ|Í µÉò%×_Šnìmæ‚òŠUš¶ }éáÈ¥¿>tÐîðŸy÷熾èŒA^v?_ÙÔ¶æ“?ÞðiH/”ežw¼ÁÁF7J’Qä½ÏWšÊ#‡Æ#×ìNÞ³gãoëö„Y±},¶ö‘+ë©ý‚j¹Ÿòg)Ü“nÿ̲R\QoWÌ~Ê],Žþ‡BÒÅ endstream endobj 3858 0 obj << /Type /Page /Contents 3859 0 R /Resources 3857 0 R /MediaBox [0 0 612 792] /Parent 3840 0 R >> endobj 3860 0 obj << /D [3858 0 R /XYZ 89 721 null] >> endobj 1706 0 obj << /D [3858 0 R /XYZ 90 690.045 null] >> endobj 3857 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3863 0 obj << /Length 1033 /Filter /FlateDecode >> stream xÚÅW[o›<¾ï¯à¤†Úæú]­IÛeêÖjÊw¶)"à´–DÆtÛ¿ÿ|$˜Ð-˦í ì¼'?ïó¼&Àyt€s{vµ<»¸IB'õÓÅÎrã¤ÀIÀÔaä, çƒûêááúÝ|ñŸ7Ap¯|oà.__«¥—î«w·÷j¹˜ß©—›Å¶¸T·÷ó¿ïœ>-ß\ÜD¨—?É£˜W'Ó£0Fg@Ì­ƒžõ$HBäLPÂ7åô³–VÍHôøi˜à—‚»~„ 3ÐO#slÆ(Y{¸-êêgEnV¶zùD ¦ê{0r¿äxÇH]©­]F³-f˜6jM6êÉž´v˜aãA¾OJ\ðàPíåu B‡ÎÔ£a´ÍùA±o!´G*}¤òCsÄšh òz»ÍªbEªºe«'Ò°š~]…#ÀÁÐOÃGáÁ©òžcÈól[¼îÆí0òà p;÷Vbö‡¨¸ïœfØ=[ä’cm2mfËKÒíJò”g|@ü¡Çê§“Ž,‰qª\ÌúÉëJœüñûbMºòz‰&ç·¾¨Ì™6‘º ô•¬ü,Ü7'*3>ùêlÌÕÙ»ÉT‰-ÍöÓuc&ï/“d—ýI²EËhÓÜþä‘v¨Ð=¿û'YTõ­™cóE.àªëËËy²b{Çï~rÂòÓÔ|Â|äôsYYŽPç¢Þá>_ ,\ ?U:‰¼\œ´î!ã+1ðqÈk ÂiñI#= ¯|¼ üŸ"M0)Úç:O4"0 IˆâäæD§0Ǧ韢OúSô €>Ñï¦Oø}®×ëåÙÿØÉXG endstream endobj 3862 0 obj << /Type /Page /Contents 3863 0 R /Resources 3861 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3864 0 obj << /D [3862 0 R /XYZ 89 721 null] >> endobj 1710 0 obj << /D [3862 0 R /XYZ 90 124.252 null] >> endobj 3861 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3868 0 obj << /Length 816 /Filter /FlateDecode >> stream xÚíVÛNÛ@}ÏWøÑ–°Ù]ßbú„ÐTá¢â^¤RE&Ù„•Œ]­ß½Û1N ¤ô¡OÞØsfÎÎÌ™ 00N{GqozFäD ŒxnDÀAßžoÄ3ã‡yxyyr>}·läóȱl3þx"_ÄV䚇ç§òçh0–‡áh¬,äãìbðe¼úÚú¨ßãÁý€±á‘r£P„[`@èD>C1s[ÛÛ(d>\‰:r p eCÀ¸æ¿0MJ’g… Ç<…† ûNЗ¸.'IYRrc!`.K<™æÙ5h1ñ[¸BωW¦ÕûÊÍïjŽf’)™b•j·^'ÁU‘½´ú GÅ¥îp‰Ù ˜E[;ùŽçFº›Ľm—·JXÏO§äqP°ÕE*uP‰ËåS¤rývèx!ª‡ýŒË%ÍÚ˜»À‰"·ÁœåÀG°îb+–Ru¢+yÕdVaŽãA&2×uú¡Yñ:± F*½ÝsdNTß[*c£Ä2ÑI>ß“¯4ö8ÍÊÑ g*cÓtBø¯7Ñ\åå}t´Š·•’v&¤Jò_%¨ÖliiÝàU¯´ÕK׳xš’Õ[a@xˆiR²"¬/-ÔjUYbú&“K½C‹ÖV+AÍót‰uǺa „¸æY÷¼†Û€;Sˆõ:[‡fs•/)ëaVˆóž¶j°e-Û–Y‡PÚÌÿhëü_'›ÖI³¯ UØz”YRª ¨ïo)“î³àûL¶ SQÑ\¹Ï+Yº „m–ÝÉÙC®ŽÑ%jnÖåÉ“&O÷äâSc;³r¦=&^²kž‚Jß;[¦%Ùz|ã©Zí¯¬RÍ÷› » ͦ}áhhÂõ|ÝV“yP«÷«‚m>ÿæñÿÊi“[5§r†¬ý¥>‰{¿é¡E endstream endobj 3867 0 obj << /Type /Page /Contents 3868 0 R /Resources 3866 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3869 0 obj << /D [3867 0 R /XYZ 89 721 null] >> endobj 1714 0 obj << /D [3867 0 R /XYZ 90 690.045 null] >> endobj 3866 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3872 0 obj << /Length 850 /Filter /FlateDecode >> stream xÚÍV[OÛ0~çWä1‘Ö;·†=J¡Së¦IcªÜÄ)–Ò¤r’2þýìØ¹6…€ñT'=—ïœï;Î1”µb(G§‹£ã‰k)žî9ÐQ¡âŠk uò•E üRGóùùÕxúS@ÛPOum`†º¸</šgª£«‹kñ8ÏÄa2I‹ñóõzü}¶çô{ñåxbÃF~‹'·†®H­!7:2$`e`z¦TÐeN¦0c Úên”eô’¤YB–¶ÈE1 –ˆ½'+ jžátyWšÜ¶Aba˜2“x-Î1ÚàOâXþ%ÕŸÌ pP Ðݳe«(")NyL g¢[E$ÂAÓšº„ÇÎDÌ@ñjÇC (—³xi²§mEl äŽ!¦šm«Œ.êõŠ#Ù‘$O£ͱUY\v‡æßä©·Âu.è’4³AZY•,k® YHZT¿ÁƒÂ0¤}dÛºez%×'E‡&çÕm·–"@ÜBèˆÓhsm–%5ýíöwCß`?¡Ò/Î7+VÁ~ÑW·\ØŽtƒ³œÆ}¥š†îyf§TÖ4‚vˆÑ“Rà K¨8cÞä?>Þf$‘el]O¥‚çÉ9CµR‹w~à =¨•Üg…b©×èiKSkœ-·d‹—~¦ǀk6û-ê°2ggÒ~FJ1ö„jN±œ¼€Ið[1Ô#JÑC­ô…ü¹g‚k}Uí-åÕ¤„%a¨I)%hI·¨*1‘„ñ2ÓîÀKÿ@$>þ(ãØ¿ÑõžÁ|·¡z \‡¯ô5¾DÓ;>u ‘’I×rÿÄó÷Ü'ì|£Î¢8›8––~´$üéåž–¬wR{•æ?ë½Ñóçè¾·9唟UÞÓvJöºùüˆTo ÂSøˆ}ÜžR®¤]C•oE…ô­ÓZ®¸Ç(C½JDxÆõö ­/dÔeãe—è«kÊ9|‡¶oÌþ óÕtò÷î¼*¨Þašë|ùÛU-„ºÖ8SºrÇ¿§$ÇE ,ݳ,æÊÒƒaßuÛ Ð³3´õ]áÝW0y[0H¸Çغki%=y]vÁwìËZD½}ª8_ýÏlÎ/ endstream endobj 3871 0 obj << /Type /Page /Contents 3872 0 R /Resources 3870 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3873 0 obj << /D [3871 0 R /XYZ 89 721 null] >> endobj 3870 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3876 0 obj << /Length 428 /Filter /FlateDecode >> stream xÚSOOƒ0¿ïSô‰t–ª'•Mgæ\ Fg2ª6ÁͰª_ß–ää‰GûÞï@/ÐÅè,gI„8æ1‰QöŒ8 &"†²=z§«Õt™Îü€0ðΰ0/»œÚƒÌçÔ;]^ÜØ×yº°Ål¾pÇöq}“Þ-þ =eWã#-þȳX««éIÄMÓœ`Ð Ãq„’èj»¶åFb§,üšØVÛRþœÖ r @¶¹ÚW–:uà(!™bZà¯J*±©üp≼ؼËw±aªaˆ9s¡¥Â'Ìû\éö4W¹à°~qÖÀ@îìåàħ9ËËqä,¸æór§æ¿~÷/4Úújª\ÄÁ°9–™j\YŠÂŒœ43µogüÞˆµðêU8^£ÝVN ña«çjÿÖ¹*,•Ü íÆÕ yåOôXU‹zJè ¼ÃÐn0QÞ¬Æq­; f’®ãŸàú ±¬U}õÕ÷úÕ¾õņý÷¾uRhö­FŽ-ò­PÕnÈ<Ì9í™×)2vÅ Ø:´¾_ûojžÓlô ¥0 endstream endobj 3875 0 obj << /Type /Page /Contents 3876 0 R /Resources 3874 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3877 0 obj << /D [3875 0 R /XYZ 89 721 null] >> endobj 3874 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3880 0 obj << /Length 1908 /Filter /FlateDecode >> stream xÚ•ÙŽã6ò}¾ÂÀ¾È@$“”(K$Àä˜Ýû°È4°z Z¦medÑ+É3Ó¿U¬¢ŽŽ:ȾXd±X7ë°Øœ7bó÷7‚¿ß?¼Ù½ß‹Iž+½y8mJ±É…NÒ\mŽ›ÇèÝVéèv³í±þº•ÑÛ§‡_èZ–싽ÄkbgeRÈ”n=lK™öìèŠ;ün«Ö­¹Öí™Ö…G»•:ú\WöšaèêÃV‰è>Xä…Ä/ "nÚ#aÞº­,"w³Ýð ¤ä(˜Ì’4C ¼`zb²`?$rK!DôãÈw”Ë­6eRæ*çûJ%*ßsÄ*/A¿Bý` :¨‘V^-R÷ô5ô.å“B(Ûùo$Û8Íóèá²Ä Moo¦3ƒëæt hG­'¡U¡ÐXÌ»µt’eE@¨.@ºl·Õ:Z“¢ë‡‘ê™ìÇ)bU‰Ú›XʤԚ˜ÝÕÔíŠH©J¤(ƒL>´×è_9ò»žI^ ø¾&…E’é,Ð=Aø5Ï+ì!Âr°8IJ‰c¼ `5ã®ÿ÷<Ñ2½Ú물¢;øCìZòŽ™‡”-#Œù‘sŸzÿLâT‚ Ó¥¹›úÓVŠÈGÉøîÃw#ó,ÑÀ8– ‹ZxhwÂ{ÞZ»InÀ\»ò3Ø&UÒ›¿†>—Úv¦«.ue‚´n0CíZˆ2­E™ƒ_÷7[ÕÞÊLí ¸ÐÒ6öj[æö¥.JGMBosËZ¥—Ùé8q¢ñ¶ËI+æ«öiô©ö±W‘;Äþ÷^ßHÜYňìˆïi_ð{¡„xîÜýÖ3|ô0:Û˜Á2×Á1›I$ÈÃR¤!ð0Ue›x¡;Êú²ó¹ï+$Κ5Èöþ6@Ÿiw°kÏ(JYÆ¡¢ŒÞ1îO~})ðÚöÎG#`zQ˜˜_\ ¸¿å <á¡s ¡öÏý`¯t0ÖÚ°2Sýð+N®[Sj ÿB’ÝÌ™7”/Í þ) †üb¼2t¦íO–ÁW|!àømA@Ïx>·Õ¥s WK€ƒsý”Kuª¢÷h×@iizðç%3¬û×5C¥"T„’T2MÃxóhBùÓW^DÄxB0.¢—Aw.>ìq]·=”ÙÚ1ïy>ÂcvgEýÃvLÑt|æ£c-=Ks½5>ä±O8Ñw^^a»L~bL~Ð!ôöºúr¢~õv‘û ç%YZpþâ—þQ)½Àz‘Æ¡„äciê»Ý1®†\KäÐkȱò¾E~û©Œª{×Ñ{KGžë®SÝÙ„;> @å§žR‚EHßÑÞ{ÞBè#CßÓK'zó܇û@S0MàW ï,fu–¼6çB¼®v“>z©¹$ôi£OB–÷Íñ×̾r駘Œ¾¨3ÿ—ŸNv÷9†ÎuW¥Œ×¼•k¯ÖÜ[Ò·x`Ù¶¥F6ç­ŽÌýl_w’úƒ“Àä–NØI€$1ÄÐK¿¤óšsÔHËk2ùÜ{‡Å_xç3>SÝï×ÝmÔ!9Cì €ŒÎexQ‚›:@c›y˜/>ø±\žžxñOÎS¤Kár9ñ˜šGÀ F¤#Ì$ ÜÑ8k¹bŠsBq5KNkùB®NPQ’™4Mr•…ù@ñ|ðþ޹tezù S5Z.Ó䘹ðÄô£¯`ÜÁ4†æàüX‚?Œé{*¼ëØÖÝÏZû<‡ÕìZÇ|-€Å,›¦>gR‰„“±9\lº ˆ-Ž»kî9šÁLöV¥/uø]øöØ–ô"ªà7Àë½jZNíl¨=à,öïm^.tD~Wå4K"~u±Wƒ I m’ Äû-‰Ù7½£Õ!thx5¸‘âj­Z¥ËôvëhåŽ3•>ãwT 3í©§1ªæs0É>fõV.g®4ÉÔ‹&üæá ÁU®y»Û==^ M¿½¹nØ=McöPÇÇÝB£§Çø;¾íUyzüÛýùíׯ«£Œ—jŸ¸VèÍ +e¸"E#y¹Ð ¥ˆP2¿„\òñr!S8Ö2ŠôŽn°œMÒˆÑ1ØÝ0#˜p@¸ZÃi‘Nôõ|>'—zr+ñð¢§KOe—H0;å{_f D>̧t|hí)¢èþ¢>NÍþoò¢Grݼuªþ‚q‰È1y´T~à!þ©VóˆXh%u‰ZAWÅ™"­¿ßб>¯ÉŒËRs·´¥†@Í£×ðL{µyœËB$b?Ð϶_‰G©“B§óÙ}…Ðæð<à´n… ®F*غûöɧ_9ûq€ä\ùDŒz‡é¾FÒŠ5_$Ù‘؆§ë}šèr9†.Òh‘MyùHûÃ3} }^Eïx?ò n¾PR-hÒ ÌòDkÊë…¦ÊÏIªðœ²EôxÀÌÕ¸­×Üú²|øÈbçÎSÞÒËY¢¤öÿîSþ?âwq秇7ÿJvÏ endstream endobj 3879 0 obj << /Type /Page /Contents 3880 0 R /Resources 3878 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3881 0 obj << /D [3879 0 R /XYZ 89 721 null] >> endobj 1718 0 obj << /D [3879 0 R /XYZ 90 690.045 null] >> endobj 1722 0 obj << /D [3879 0 R /XYZ 90 480.779 null] >> endobj 1726 0 obj << /D [3879 0 R /XYZ 90 228.511 null] >> endobj 3878 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F53 1833 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3884 0 obj << /Length 2435 /Filter /FlateDecode >> stream xÚ½YëÛ8ÿÞ¿"À}XØ(–äçW`:3íÍ¢7´¹v 'V&¾:vÖv¦“ûë—%¿â»÷è'K”D‘ÔO$E»³§™;{÷êÍêÕòmèÍb"˜­¶³Ø…nÄ\ÏŸ­ÒÙÎõããÝÃíýßç á»Î ›/|×uVóX:×ï>ùÛînVÔ~˜Kß¹þóýÃ;êÿäúîíÝ_ïoî¾'Âõœsî¬Vïß̹ëüeugè·Ôxü8÷€çãÝÇy[ý8ðù?W?,ßú¢'©‡búè¡4é•kT³ßÙÂN\ˆKš¾+ëæêPVÍ`ÑìÇ÷<Ϲš/¤ë;«]VƒL-\¡ò;®³K 5Ͷsá;[U©¢¡±½JЬx¢ñd³)«Ôt]§)‰ÜìÒuR+¢=#£$?*†[‡ÎýÖ¨,{*K.˜«²^þÇ“ª§¬ã37jƒ‡`v©Õ ŸóF›–;x2žÔr§ À¤ôg ÎYìûÅP¶ÈA£ Œš#º¡/;°5ÍhèlÊ¢©Êœ¨õ©nÔžÚiÒ$d=¢ªç9÷UÑ2Ú%rªcAÅNR¤ÔÐG7˜×JÓ²E]Ü¡ýMÐÈÆZ\Ÿ èN7¡Ï.{ÚÑt᪬¬²ædÏ1)'Ú;FšŸ*N¡R]ŸÓEw~þÓ‡O+TÂÿ9«Êb°šÐ‚v©²d#^D|/^À\áR”h‘ДÜND8ðØÙÍÜ)kÀZ† miü’øÐ sÇV‘ì Í `0/U(ðs¶1ýÁ)p4k¹QuÝ Ò•¹ÀBC4òY­¢ÅÿÑ;0Ø À`ËÎ#ÞЈýx¸´ÏðaC§±ðbq ҀѠ(MÒ4U¶ž ×96êÌÉQ¨ ÜÕc¸B“´Yk]³‹ÑD;¨ y¶Øl¼A;yÀ{ÌRO—2è¹HÝ¥« ÂÑË õŒg¬Í¤Ê,.š,©NÔ-‹Ü´µ6•JºÙÐkì¶·íi"í§rovT/Éþ[g ºë‹zG,è/o¼=æy«-ïÃÜÜÙëE#ÁæÉh°ÑOBø£%±"æ­÷yÊþ½/¯ˆä.ëj™.6Ír*¬Ç>“oW„}.{˜€sò¹Ó1ÐÝ.Døà¥ "&ÔÕÇ¢Aš½ GÈȆ#˜ù%kvD%,BcJF´Ë%zÎ'@ÔÓÑ„Ö]a“乯´µa̼ÂÐŽu˃À «Rqܯí~Ú ˆ^?2è…©ga&Ú°2¼)ÆYÙX£ÑÐ.Dù’Y ¥™´î݃±;¤s8•ß•&)žÊ«år[Íyä¨äó•ž¿ÌRΗ¦.ÏKþ‡¯D3,teC"râqÏ˧ÔÇàŒß„>é¥é•é7IÕØµòؘ•4ŒPc¥ÀFÕ[ Nømq„ÄQO4¶,ް½wúÙÌ+ íX›m<زàÁ6šU箃ÖYzlå±{µq4Éë񮮼ÎZÔlËjäoëÖãô=ïeðÿxû¼=â§>-õâs6égB΢0îaDûÿy„¡¢¼Œø „XÄp̾2æ[Ø“+Æ__ðßÌës…¨¸äËG£¬³&p['òXò‘u&ä?XÃ[®ÛxtÚ±dÂû/\E–ï³­j2JiÆG°Àû Êä–ÅP¸¤ ¨³!(¸Ë™ïEAò2*ÚñM%kÿWdXߺ„xX¼Î“µÊ§"´Ç<îÌù8ÈthéÐŒé-îó[ƒ®hì'¸+XÉÿ)v¯EÖLEÜÌcoaýš^5‘ð{À÷ˆM˜¤ÜŽ}f—êŒì37B¬‰§œgàv;Ê¿=ÖZ¯“4¥_OÕ0˜Éh|o[ÃàÚîU6m÷ßyW=&¢É»êãÝäI·ã·¶Û'qTsÂó$-7?«©ë‚.¿U»îkV3—M§l›¯BۊѾc<&½@P ŒwAE)Y~ÝXP^€^û6O¾“ÒÉÌ\S÷‘½Q—žîL x2u¸ÌòIÌôañc”‡iùã€$Šý3=`ÈH-´Á¤JýrTµN`‘¬+S@& pýxÿÝÜ÷ú{Sek†ë{©^Lqüê|sÀG›Ôô¼Ð€%46kùNAöc„ E¼\ÅdôÓϣЃvYi%Bcf ÑæÐH,^µ–ޏ†ªcnZÚㆲ[e¥ƒ¦–ÇJê?eú , B9r« “Ñ!„-

– }Y)KkŽU’O=Ò¶U‰/Uaß§Àû°›ûΩÎ6™.À ,hf…i¢b8é9Ó2~™¾ƒõ{!œ÷ª¡Ó¥™Ù>yÊ e™' -ÔIúÞ¾€«È𕈈¶Þ £µN\íö6D™áŸªzÖÐ/p¡Ë § wÓß…àaçoÀÅ6ªIˆJþH‡:#Š>q$X;˜õë²ü¬ï–Ke]šâehM ‹¬©5™œ_ŸUV›•T±Ò¢ì´%N–“vg fÜ 5–_¥ò¯Ù„ƈ*ŽØ7Ävg@‡íŒc­&Ê»qP÷jF;M=†Y·“ЄçŒ`Žìd´îÉü.WI³£Wd0z)[gƒâçÙgL)'e‡Ä_D]úùòҽƿ2<æòÐN-«)\&|˜â†¿PZ=ôëW8׉>ºµ¨ƒñÜø*=Ëü%‘>£t}*àì#pU…´AUÚ¼ESŽ†Ô•N±g*ŠÒTe¥KQŽ¥¸tÞâvv—¬¨›¤Ø( zÒë6=«FŸýYÂıý_ts¬tžaþ?Œÿ@t÷ÛòŠöŸ’²‰/Bíl°Ù¢>Э“½|xôøñÐ`}ðÈ€Û›.¡ÏkOörÈC½L³C™O½ø|$lÓõMyÄ_wÈ~Çe ´iq¤Ÿfô÷ :¼Üê¿n?bÒí#,€ôƒ~%ve bm´7¥mh™29ŒõÊ为˜üËy·zõ+c¼¯& endstream endobj 3883 0 obj << /Type /Page /Contents 3884 0 R /Resources 3882 0 R /MediaBox [0 0 612 792] /Parent 3865 0 R >> endobj 3885 0 obj << /D [3883 0 R /XYZ 89 721 null] >> endobj 1730 0 obj << /D [3883 0 R /XYZ 90 543.803 null] >> endobj 1734 0 obj << /D [3883 0 R /XYZ 90 522.861 null] >> endobj 1738 0 obj << /D [3883 0 R /XYZ 90 390.254 null] >> endobj 1742 0 obj << /D [3883 0 R /XYZ 90 325.124 null] >> endobj 1746 0 obj << /D [3883 0 R /XYZ 90 259.993 null] >> endobj 1750 0 obj << /D [3883 0 R /XYZ 90 214.788 null] >> endobj 1754 0 obj << /D [3883 0 R /XYZ 90 168.461 null] >> endobj 3882 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3888 0 obj << /Length 1399 /Filter /FlateDecode >> stream xÚµX[o£F~÷¯@ê HëñÜö¡R.Î*+5IS·jµ»ªˆ!1’,àͦ¿¾g.`7YÒ3f¾sùΜ™cìÝyØû09^Lfg!÷"I*½Å­a/Ä a.¼Eâ}ò®®æ§çS*°‚‚©ÀØ_ó.>\ZñåñÇùÉÂŽ/&ü£_Î/>Ø÷ÏXàÓùç'ówVpBüÅâúü8 Øÿ}1wò‹S;¸º8`^ͯ ªþ|Y|œ ºc)×f ~C© zÒ;×¼i;aJCXÄì´¬¨›¸X¦ *d~ykŸ±}5M•Ýû›&½ªÊïZNýå:®k;E¯O㤿¼Y9¼ÛÍzíw¡¬¨ˆs7zXeË•…ÎjçÛqá…2l]««Ù}=K²ûrÎN6U°ÐO‹f (Š ŒE»Øba䟦þ· ¼†Þ”)…ÂzSBP$Ññ:‹ÁG&[C™¤~\¥V´)²¯Vô5«¬°ÒØ>Â~\Ü•vƲ,šª\Ûoõ#Ä+C$Wýø: ûjY«V­Ë¾lǺo€ö÷ëÌѹ՚c"bpĸ¤:t°Œ1$)·ËN¦C²_§uZéTý¦ÒÄ"=è—²JjûN¾\ÅU¼lÒªvù¾Îò¬‰›¬,êÂ@+¥ˆJiµžUeÞË)®Ã’wVX/Wi[y’ÖKˆfêr1¾)"´ÂOµjI——•vÁ~rÓ·fZ4ò6([ë¨bˆFQ›Oï`ˆÕNx7„xðÓÐ>F‘¢/˜ øÎÛ –‡Ýøíû^CÚˆr½ÿŒìý€b‚#Ä;äéÏCû E‘Ün7³½8ÅHàÈe¡#ö2–BÑlÊ{;0µC Vqt1ÌÉ Knš¿7÷Iܤí"“¿0ÒÕtûÖ”ö eç3Ætíİ0¾‰k·øÖ¦TĶøzKèúÑ3$n5Pjj®y>³,I$TGT’šlt5çIÔ¦íäÞFmw”‰"lÌbß›°h)M¶­«¬.峯%t^?Î ÷!OóØÆ6ÙÛ$¹Õ*a­íí|ºNê'Ó:PW­Ú 㲩¬lfA6öÙ€êÖØêhìrä¸dyÞO(Ij ܬ+ÈãïY¾É]-ËþqónËÊ€šÚÉ2¨smmªœÌ$ùd¾˜| ÊŸGALqOP‚à"°Ì'Ÿ¾`/oPH‹”÷`fæÀF”1¯½ß&¿þB16<å!˜nƒe1̦—^T2é ÂsÎõâ±ï>ƒø BÞD-ƒ}/•ê«ÆÜ1wÍjÀ‚ N°`€À`*É"–¦¨¢*2RœŒ£‘+D˜,…8U]]Ùn}«¹4`hß *ÄóT¾^ë> Cr:ŽÊÑ †Jðá¤z•J"ºTèØLÓ%˜Â{€É7°‚1hŒG;V¨CD¾Zé€A¡*Œ#r,ˆ!2İŸøH"a 7jK\ï}—o`HÇåŽ!©|µÎ$ègb$•cA •D5’I Í!Á.è5íiÕ^’^Dãx#:w8HãkuB‘‘,Ž1,r8YèÈ»ÓT„0aÃgd{kýïãò êŽË]‹—¯Ö:À`P:òæó í¿Mx÷µ^<¶7|aF½>e}ª(ï:ª\·Fu·–ç¶œÀ÷þk¢ÛŽˆF[œûª¼O«æñù}kX—8N¯Éó­K³m]ú9Ø5‘ÕN"vÝÉPï­#¬m'—q××uZÔY“mÿ‘è0%G4T½Æ|+HÆ“Ø* endstream endobj 3887 0 obj << /Type /Page /Contents 3888 0 R /Resources 3886 0 R /MediaBox [0 0 612 792] /Parent 3891 0 R >> endobj 3889 0 obj << /D [3887 0 R /XYZ 89 721 null] >> endobj 1758 0 obj << /D [3887 0 R /XYZ 90 638.324 null] >> endobj 3890 0 obj << /D [3887 0 R /XYZ 90 521.94 null] >> endobj 3886 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F53 1833 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3897 0 obj << /Length 2350 /Filter /FlateDecode >> stream xÚ•Ù’Û6ò}¾Bå'ªÊ¢I€ç£½voÅžd4SÞ”ãJQ"$±L 9þ~û(PÃÙdŸØh4}wC ûE°øx˜ï»Û«7?¥ÁB~’ˆxq»[äÁ" b_&bq[.¾yo—"öN'Õ”Õãr%âÀ{¿ü~ûo>ùi–†x,X¬¢ÜÏBɧÖ}ÑöU³çn—¹ðŠf¯y¹ÕMß.ÃÌÓ5#º§®WÇ‘{ù2B1ˆ{œÂ]†ûû¥ÁŠ¢ ¾¤ƒ6èÄ RmGöêžñµÞïG"ÒuªŸr}ÕjÝ¿¢´È½ß—!0у£h p= ƒþP¹6êP`À£OàØ' &¬ ;Y¦ÞçßA‡?ïÖnxÍ­E&fãWlöo×믨ËõÍ{&ºLBºÉÑøq C†Éw¦€K YW#ì„9Óü]´ÏüŒ bçQ4=õiô©ðžÈ€pt`ý• j¸ñ´å±j y¶7_ÄíÛât¨¶4àQ­ ¨âضsݱôÃ,}xëzÝδ!ý4-Î)iêˆ]wF¨FQ¶ÐÝü%ó2ƒ9ç<F0‰˜ZÆÑU†Óž€m}RU`ÿEõ :ý,J¬àÔÖÔœ‚ØBené¸ñKOÛßÈÕqNœ1Ô ÊÑÀ̈ʒºõ+¸aŸAVAJ1y0Öëº3 …v9ºp£¯.ú%t “SÏd‰]YfêI&…-àT­"ï C[’$æOÝ”éõPÑ4‰4•Ô®Sk}b¨j 5¤Ûi,ƒ“j+]bÒ˜¾­Tg®ÖŒ*¶fn—6ÃaÓµࢂ«Ñþ\ºµÃ¢‘ …öyä1 ßG4œ¸såå:>Ö IPµ{aŸlGÍá 4ÿ?[åÿž[§z~÷XùÍ<ÄWQìðx„f:¹b|Òý„‚ëvöÙHOFU+¸µ³vÅ›¬­ú5;€²ùq:Ìü$㋯)Xpì;1 wü}8=C82tÛ¶ÚPE´=É!ódkÌ cc ×ž0N¡ãa$GáØ<`sòc”Çtÿu}ón Yð–—_tÏ%Ú6ÉÓËKÑ·6ùN&ÅÀ3P¥Ö̃ ÊByƒçBürÅcÅEœ©¸tÄ ¶0œ/±xÚ¼´ä¾* k×ã¸áN*±ÈSJ¦-/5 hÔHÙ¨n\˜Q85ªfZ¿¶P—Ÿx÷Óõ 14‚<ŽâFK¿‡¦)y¯2×ñÄDnS rçí¸Š²„+ýŒjR@•!÷IòhF83ó\´Ö$óÓ0³Þ¯Õ®åf& !¥bì­[}i†" 4© Û¦üð¢®Cðj¨«#Mp€^uæÊ Ê^ñ~Ñýèì]³™åè£ã¯aÒ Å ÷9`#øóyódtŠŒN€4ù.ã³v2v´‹¼ÅñTV> endobj 3892 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.185 460.391 386.612 471.295] /A << /S /GoTo /D (section.7.12) >> >> endobj 3893 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.52 368.675 170.438 379.579] /A << /S /GoTo /D (subsection.6.6.2) >> >> endobj 3894 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [483.993 298.882 495.949 307.848] /A << /S /GoTo /D (cite.Astor_doc) >> >> endobj 3898 0 obj << /D [3896 0 R /XYZ 89 721 null] >> endobj 1762 0 obj << /D [3896 0 R /XYZ 90 690.045 null] >> endobj 1766 0 obj << /D [3896 0 R /XYZ 90 510.667 null] >> endobj 1770 0 obj << /D [3896 0 R /XYZ 90 433.781 null] >> endobj 1774 0 obj << /D [3896 0 R /XYZ 90 246.423 null] >> endobj 1778 0 obj << /D [3896 0 R /XYZ 90 220.164 null] >> endobj 3895 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3902 0 obj << /Length 2141 /Filter /FlateDecode >> stream xÚ­Ërä¶ñ®¯`öà"«<H€¯Tù°¶V[J%ZGׯµëg†£aÂǘäHÑß§Ýàk¨Xªõ… t£Ñoa=XÂúxñãúâò:RVâ&¡Z뽕+±+T`­wÖûýÏ?¸½ºù—³òa_¹Î*¾_;‰´ßß9¡°×7·iõ=ýhíöã'šþôév}ç(aú;î½_ø‡óÛúo—×?¢­pgš´(DºÌìüyí‰ñö• ¤ë‡žµò#J:ÅsVž,ŸŠ¼Ì;gÂxÕÒß*FpÜÊóÜ$àKû¼§ª»|¿ã=ÿ¯®²tw]ÖÜTðyL‹¤´úÝÒqrrœ¿Û,^ëÃúâ÷ †ÂòðB©ÜÄ ¬myñå7aí'»QYO«´d»@ÖýÅ?é9'"õ¢”zÒ ƒˆøY2x Û·ÀãÙ_…ð·i—×ïáRùVãDö.ÍJ³·ôoaS—6]¶£yÚn‘W|²Šâ'¡}Óµ´ôî\nŽØiñŽ6ÔGC?êÉœZ"Ù]Í„Ù6ß?k!¯<ºÚDÔm]R„vŽ4ª´ Ù¶ÈR`ºÊ«Ô{úï€)†lþm‘]œ<åÝ!¯pØÝÄ÷Ë a-É ®«¢ˆ$‹àw«ê{ó–N¤‹!/¦ÙÈÛtSdKÚ£Éû±Í;x%»ûÑ‘6@€ß¦¥¾'އ·¼}Ý´É/°òdĨÉ@h—íOØé©èáS=â–¬êy{H«*+hз]Ý<;a`£0`ÃÚ°7PkHr ·Ôwç@LÀàv&lí9úËÀ¤WLçÕl÷Ú‰£ê¡6¸]ºI[^Ôú…кbˆV`ø³Ã¹\Ò±FÞå{”Ë>kø<ÃMJ¿ÏèôòjW#Öãlëòx©¿ÊJ¹A”¼ÅÌÔ.aê'=¼”ˆ¬.%Ãhê&ßîòVW×ôô7Ÿî'íË~øé¯_=©ÖYyÄö¸7Gõ¼¤Ÿ¸qÿ?Ï‹®Roxñ¸×HQE±ëêÍŽ4‚ýš5Ÿ£R‰N¯_Ø.àX‹×øÊÚ¾à•Ç«ŸcT.fͨv<ØÔh3øÉB!ZGì†1aØúv¥íð 'òÌ&a½}{.i|H[ÂÛdYE ¼<Y ØÚ«">úp2@D—Gð±ñÀBßIwy ö-UÄúm6¿dŠ#6ý—Ùü'¡¶Øw0ñhòܬ<›$“Žê ª,Ûé{Â8­þ3MʺÑÞZ$à Ì¶2K«–Ö»8ý ðþÖ›€)rn’2v[“;›=Ÿ”n…sä´(h00Lw$$¾ŒÒ7Ók(ÐIP…$3‘б©·YÛfZèÊnNUÅO#`J¿CÝv´@ú‡+šl‹¦¥åSËG¨é»1}S—„¯–7˜g,ŽÚ€5Ñ#eÇúÉ!‹èhžóz3Ào²ßOy»—¢ {r­³Æ˜Ì³Â„ÅÁŽøkLDHç±a"n<²w;³Ò~ K  öWǃo}â5C£+˜ýCÖÍv¦XŸ˜B{Ú¬ ‚Á—þ¥W6pËR…>›?¨P &¾F±§ùŒTÈîà(4‹‚ ±èñ í,ð-º߇|™ÀçƒöqJì—OhÌ.6´¿ï³‘&£}dVèÅéŸîv9nZÐ|x,@îI¿¬¶LϾG_õ<‚óSKñƖ¬£¿˜DIe¯zyI9$°À©%¬ x ¡iÉ;޵擸ûLK•#Mó`Ñàîã…õEãF®çM”†+º0SК°¼í)µwk™7æëPo:Új¬@c#“3_"Ï|ÉL,ÆàÏR$“ÊÜWëhð-::5>4R€¬<ŠÈ¨ÀÊõƒd€ë-d¨IýQ>8ŠÏÌD¡ãñÓ¹Ûˆÿ0:ÿò‚×$ -S÷:Žo0=‹o¡UP×Ú÷üâ°@Yë »†}³I‘õ®Þu¢Â‚N<‘£Š•Iб2}há㙂† «óÀËiÃp”ÒÕ’2ÕÒùEȼš°¹.ÌdŒË}1‚ëãbdáz¥Âýý˜3$h£‚ÿã'“âHë*¬éÃ7% H¥Gb@ Uh0 ££Ú=éwÒä>ÓˆCï v·Lf!,5‰#“VLÚ óVŠÔù-cBÑQ‚]1 þ›b&ȹ…òÝ(VËÅØ(A[æyõ8=o*ÛfÓ/·¦ÏTäÿ¡Ì˜ÐŽކ§¹¯Iý½nzveY”–ÂQB}kõÝ· úBhUÓÿò1m.Ëç=Ô[n>ìUÂð#W%ÞŸÓPòDèB|5”dœr2òHˆÐrBùÂZÓJB Vâ¤JG¨m¤$µ’À½õ½•ÑiÜ[I(XjšÜ[Ñjæ$ŠlU²¹ÄØbì¯eœô\Ýr@=8³i:,¸:é° `îÔ485ìÜœuX")XîK}‚îq%â¥ëÛ:,o‰é¯j¸Ðï©Oò®]ðrÖPõ¥ØÃ¹óóP©g¾oNŽTÇ ,•ø mÍÚ<2æÌ,Ò^KF mÀéÛ<e“mSŠ 0áT4î³ÊˆüíxiH>##\<æ™V-šdxàB;À¦P>×òp¨­$vWA½2æºãqhöù4@S ¥t tOmG“ ¢Sj䆺ñ&Œ¬®˜y'œ°õ÷}aL '‚€pLrĆôEO‹–ó>SEnLe–¶½êšµ^ÃG®—;wD_ðµÿ¼iŠÆ endstream endobj 3901 0 obj << /Type /Page /Contents 3902 0 R /Resources 3900 0 R /MediaBox [0 0 612 792] /Parent 3891 0 R /Annots [ 3899 0 R ] >> endobj 3899 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [270.754 324.33 290.182 335.234] /A << /S /GoTo /D (section.7.11) >> >> endobj 3903 0 obj << /D [3901 0 R /XYZ 89 721 null] >> endobj 1782 0 obj << /D [3901 0 R /XYZ 90 463.703 null] >> endobj 1786 0 obj << /D [3901 0 R /XYZ 90 377.481 null] >> endobj 1790 0 obj << /D [3901 0 R /XYZ 90 297.799 null] >> endobj 1794 0 obj << /D [3901 0 R /XYZ 90 271.54 null] >> endobj 3900 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3906 0 obj << /Length 1552 /Filter /FlateDecode >> stream xÚ•W_oÛ6ϧò0HÀ¬P¤$KúÆI—¢ÓØEW´Å@[t,@]INço¿;e˶:l/&yw¼¿¿ãÉÌyv˜óöâÍüâên:©ŸÆ #gž9_ÝëÇÇÛ‡ÉýŸÞˆGÌøÞ(bÌͽT¸×O^ÌÜùýÃ[â^ÓB¼‡·S:ÞLæO^ÈÜé{"Ì¾Ìæ·¼ïówWwïÙÑpƒgÆ4"º`ÖÙÓõv~ñã"€-sô;N˜Ïî,Ë‹¯ß™“ýÃüq:v~©ÒiâG -Îìâã™J“€õ ‚ÐOÙØ‰ÃØç,%×opÈC¥Û|•y£ö£Ê®“‰’Ù]^´ª¾¯àçE¯c÷N.[]ïî§O £d©^ß¼úˆp®Ê ®êe"~®kºòfÁ᩟$‰3 ?lqø‘<[Ð…W7ÒCRånÞøµjs~–ë€ûBÄÿ'ׄ5¸oàlQ"ü$H(ž‰Ç™ëG>ÆÅÀÅ;G.ú°©½ qU¡d£ˆÐ"«ÌnÚ ˜û‚?j^ ’—ø±µ…`¹[)´ñÂ5{¸¹ªj‰ßìšV•´_ˆäJUDÊËM¡JV™•oeÝæÕ3 þÌÛ5Ñç^‚®>kbÔˆ¸ œh,ŽÝÏØ(ûKí:·{nò_»ù;b¸fÂ7÷Ðr3}zã‰ÈDú ùÆ_Ê6×Nº  5_*0¶è"B¥Tfℽ¬ÐþŽ$J]+ ßçëîZ©dÕp»–-ê(Ob_@KÙ~—VºÑàÎyùDÝ}*+‹‚¬-‹’a©Û†*ô£\l;#Á™/’ô8;«Zc™¡JÝ< ºqêªr¡2ŠØyE+fùDžÄ1‰Æ`Mümcû¹Ë•Œ¡ÜVqC+å6µú±ÍkcÄ[MTƒ0ÚŠüM­Ác«Cƒwu秬†à@þG'þÃùÈÿ~ƒå&¿°±Éö÷5…7R„1·]&„ó°ßÒ±mèÏØÃïˆÇdà“­uY}qxÜl©ïTÛª6¼¥°¥Ö…®ìôIKߨ%u ]?ÊòûùþRv¦¢ƒ'ׯæ y‚Í…î›ÝP]2µÂLn‹Ì>b<>2%Æ ½H¸Ap ÀBÑÙÄ‚Nà^!d› !)¯@¢ZÚSC¨3Ðö&îepIƒsµµ6ûy@‰NKâæV➥+¹ …‰éøËVæ*¸Ä”ø|ì!Q–{àyeɦ ¢CD]vþ óæÕàp;ùœ&þˆƒ»ÝhšŸ‘¦h0€ÐÑ r3LŽÝ‚3$¡RËÖrM„°~ØÍ>¾§m÷œÁ|Déa„…~~¶B]9ÉT{¬õ²Öº5Éf©ûÅ @‰ÞZ7de7ð`<[íÞë…ZKìå—\oë¡‚ÚY—v}î‡/Ã_Ÿf·OÄ ‚î^ÊÝëÙì3Æ2}šŒÖÍÔº*i¾Á…¬¬¬s¹(Tƒ£FîDaSVÖ-IÁB­`u?ŽùÆìä}zïà ¦â#LE‘k¦6ïjŸ@βh4)…)`eöv) LákÚˆœG³£È‰’¯H|• §4pNE‡Õ M›³Ñ,°ë‡Ä~p®·UEð æcˆ²ê¦ Öºi ¬ÛèeWµòo{ieÍRª`w-m´2Çh‚£™º—hïÕF×Ì!ÝGMS1ÙËè ~ØÈ‚N„=d¯ˆ@c7݋۱‹ÍE¸Êp>§i7è- ÂÇ „Í™y(xF»o,bB°ÖÀz{¿²ÂN ÎëH 0ÛÚµ(ÐGšwZÂVš¾ç„}.E9ئ掎Æ,¬¥Ì”©^ØaYœ´…`‡¶€ýþ³X°Ù3ÁÑz&[¹ÀoÝ~h±íBû¢×ª­óÞ×QAw÷ùŸ?¯»ïÞI÷²ÓJ5„ÍF7MNÓ›ã“{ö,»®·£}ì0é"&=¶à€ïžÞZ…]¤þ¯þEý›’d endstream endobj 3905 0 obj << /Type /Page /Contents 3906 0 R /Resources 3904 0 R /MediaBox [0 0 612 792] /Parent 3891 0 R >> endobj 3907 0 obj << /D [3905 0 R /XYZ 89 721 null] >> endobj 1798 0 obj << /D [3905 0 R /XYZ 90 597.766 null] >> endobj 1802 0 obj << /D [3905 0 R /XYZ 90 513.482 null] >> endobj 3904 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3910 0 obj << /Length 1148 /Filter /FlateDecode >> stream xÚ•WK“›8¾Ï¯à3B ¹mv'[Ùæ*å[fÊ%ƒl´…B8ÉüûíV {'{R«ÕÝúú)`ÞÑcÞŸÌ­·Ÿ2æq¦)ÞöàÌK™ã”{ÛÊûæÿpá÷½j+ý3ØpÁü§àeû©%a–gª1o“aŤµ­ ·Ý¨¯ö´=ºÑãël!JÂ8Á«¬‘=gá)Œ‚MÄ{×mŒ<:±g&Ø'DÝ ÄØ÷e{ìh;Qî«FI£ qš.ˆ˜ÿC9ù±–-Q9ØŠ¬à^)OVÎCžf+oó5Âl‰0÷µ¡õlTEÔØ‘X/Yrr@œ³q€&ûªTÆÈa2Ùºá$GݵÄ8Ë •¥Ü7jøDÂWƒ!ARÈý²Ñª/0Àgô2ŠÂBòrpˆ³n*ŠMÙµgº§ÇzŠŸËÄï_¾~ b54çï™1^ʋҥ ƒM )ø<š7éÔæ¢™kvZ½$ ã<Œî0^•È·y¿ûüåë/oÔ‹;«;3NôÆÕÆ í.¡ÚUr”{(g`×ÊÓleS¿Ø`þ0IøŽ-Œ˜gwàY/°7bõáV‘oˆ¤RA WÓ«R^s²NæˆFlH¥ íýµÂu&¬iÊ9}Y$‰ËJÎX "õÍØ ŠHùBâ$uK¸µ­µ;]zˆZŽ ( ÝBˆ;è”Tø òœJ¥*uÀî”çf$ÆwL‘lÎjmíq<õCEÂåj(m1›£L€˜Kûú^¢Œ"² ëÙFŒZÿqÉllô`ýQë²&/ Šâ½­|kÆÅ›6uwn*¢÷ާ°ú~öÝ0ª ¼H`ˆ‘p¶ 0.A¹á™u…%"P 3þ¥TÙ03´™l çÁd±,Û=Hü¯îYu¥Š‡§‡ðpË%ºÉÞÐŽØŠ8áídÂàL0èà‚…ÎÍ(1¦t8­h[|n'dJC¼É ââ3‹o–òïÝ=ÇÝ:µ®ÇÂÀׯNBaƒ{Ãíùª"w΋bzR€W«ÁžÎ˜b¤öNŠã=#8.pu ÅÚ©"_;Uä6ivµã6Ë+È7,!ÜS \;8­0; æ–×ÿ/‚¹’ù•6}#ÝÛ?½Öµjz¢NøJ§Wåï_ûn ~“§¾Qw^œ¨àaÄs7ãÓë'‡&çJF\F§ýô°wµ§oÿxi31çGµ<ƒ«yæ™ÑíñJt5%V·òöm0½§¨©¦™­‘ðNDÒ,ÌíCñævŸž£8ÙÄ÷Ô#ÝVv4S°Vêé{Á’¿³Ë§È]Þƒg_ŽÛ. øêù}—§o‰GšÉÃãéuW7ýÂAçû-;Ö÷¸¸ö8oœŽó…Ó `›0žÚˆû÷Ûã9"ñüM \Ûû°JZVûUç#‚y”¡ ûÃBÿF_¯‡#[NR¶œ”lž”lž&ËÜÀÿK2jº"ŒŠœÌs‘®Äž¶ÿÀ”|< endstream endobj 3909 0 obj << /Type /Page /Contents 3910 0 R /Resources 3908 0 R /MediaBox [0 0 612 792] /Parent 3891 0 R >> endobj 3911 0 obj << /D [3909 0 R /XYZ 89 721 null] >> endobj 1806 0 obj << /D [3909 0 R /XYZ 90 690.045 null] >> endobj 1810 0 obj << /D [3909 0 R /XYZ 90 510.667 null] >> endobj 3908 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3915 0 obj << /Length 1624 /Filter /FlateDecode >> stream xÚ­XKoÛ8¾çWîEb™ÔÓê­»M-E·5º‡¤Z¢#aeQ•ä¤þ÷;ä eÉQŠ¢»9„ÔÌpÈá|ó ™óà0ç+FãoÛ«õmŸyqìGÎvï¤Ì‰Yä±ïlsçÎ}³ô#·id—ß—+?bîíòëö=. ½d“p½Œ9«0õ6<ÀUÛB¢pÓ.ùÆUlûRîó+âv§ºß}<ô‚PolôE h'}·KΙëñåŠ3ÆÜ?ÔzìăD¥‘ï¤^û1éô}ÏkÙ*8¡Õ£¿¬=/;=ú®xÎz*dKÓ“:â¤ë•¥‰ªÂI_Èé.÷,b¥ì`àÈhe%z™ãN½Bb.õ­?–™Ôò#é¬TýPÖ¤žäé„]#³R3ÓÖk{9÷Ò(B{ÏJéòeû¸ä‘+[ë*•É®ó@Üõ»©}¡¯á|Å×ø¡jÒ’‰úÌ®ó×zç_½0ØÀ9R Q÷¾M¥îV8õï¢Ì Ô5k¿f‚£-×ãΣ•xúc¯È$)¬ÆírÃ\Q?в¬i’‡Ìs»´Ì–—Gùá­M bÆâ8IlñÛ—Ì$´Pþ_½¢ïÛr·ô!Fz9·è{lˆf ¸–S£í§®Ú#eˆ  Y©Zõ8iå·cÙt{wBªÀÏ‘K45Suߪ ?ºS×/9øÐ…©Î'DVYƒ{¢/UÝ¡"ÑËD`nÅI8FÀ\lˆ^ì„ÞÂCÊqR}W&Þô7(;HÕ)œÄh C"‚y¦ŽizµlEOŒNÌ,Òƒ‚>ŽMUfÆ4ÒÝuGi"’mÜèUœ¤Ø]ãB{£wƼ Lë(rËžB€SÒyšû‚}šý±šFÝÈšIŠ@x˜ü°' Ê)äELp"e+/³†ï…Q0ÍÜ›Cú;½McÖ7ñ´äÚË=’ÍyÚk$Ø‹5'A |Ô†‰Îˆpmìª#íO”°´B%IÚ`_“;F-mžY¥,¦<„q‚ºíLs!y4ÆëÐb°Åx=:fn0êˆÉ/1'‡Aß¹ÁƦ·j%&²Ä&òxâÜä,y®°‰»oíMìdA_/èíM8Ý@J½BÙ*a9S£WDŸLKDl5S ÅÛµ?y“X'¨\ ¾¥iºzO¯àÌìÎb÷µ©<Ç:2ÏmŠYTT äàƒš½´VHê•Τ†YV4Û‘¦ƒ²Ò" M½¤t"¦g{Mˆcø§Ú²§¥0ÂÙ¾÷('óRï2Š\ï9bɹhoja 3 KÈk–ÜÂhKBXÂdK»6=ûæJ6¨IǮת”f¯„®p-ò|}Py¹?=×H º9¬Žà7 ï…ë2‰SQ ¥`0¡Z@%òç‘®g6ùž[“!îMå†n–¦w2B 9gOé/c°ž ‘ZP lç„çJŏ ¥/Ôá0ŽP-4ŽPÒmÛ²KÏ:È—äqÝl0‚˜ƒªJf=ò0‚`3Ý8“ ?ä&Í4ÍG°±ÍGê.>â b‰í×–m—Aùÿùxmf#{œ ¨™Í>+ž³õ-@dAýÃ,4ãu—¶Â=•u®´™OÈnTCåêØP ¬*Z¢¡òöÔe…R5Ê$»ÖÂv?C£Õˆ¾ cZ×›ºm#ÖßqeÚž›‡ø¸èùm¸\Û'€¹k|Ìุ-+¹¸ ÏÅŸCt~lÇoN#í½ðz /âÓ׫ÿS¯×ó›xˆG;Þl¯¾]qŠ\x¨ó8ðBæ;Ùáêî+sr ÃmxIš8OFêà鯋X óÊù|õ×3•æ=?“9ÇDÂCßãÔ|¡‘œù9sç E^­~õÞ¨mÒäÀ…Åp_¯pø|óéËÍ'œo˃TÇ~+»~}õñú ¹ÄˆÅ9¼úZì®g`ÐfÿÍŽ ¥á1š·aýöæË»ßoÖ#úk”\È~Ý«5ã‹ë{ÌêŒ<þf$ë¿,›\Ê‹‰Ýþfnm:æÅ,> endobj 3912 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[0 1 0] /Rect [107.972 254.05 119.928 262.797] /A << /S /GoTo /D (cite.Jive\040doc) >> >> endobj 3916 0 obj << /D [3914 0 R /XYZ 89 721 null] >> endobj 1814 0 obj << /D [3914 0 R /XYZ 90 690.045 null] >> endobj 1818 0 obj << /D [3914 0 R /XYZ 90 510.667 null] >> endobj 3917 0 obj << /D [3914 0 R /XYZ 90 355.639 null] >> endobj 3918 0 obj << /D [3914 0 R /XYZ 90 312.05 null] >> endobj 1822 0 obj << /D [3914 0 R /XYZ 90 201.444 null] >> endobj 3913 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R /F113 3438 0 R /F102 2374 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3921 0 obj << /Length 1520 /Filter /FlateDecode >> stream xÚµWmoÛ6þî_!¸,‘LRïAÀm’-EÑe1´h C±èD¨,¹4ÿ~GK6Õ¹ÀöE¢ŽwwÏ)bÜÄø}ôz>š^…ž;qÀc¾2bb„$rˆçóÔølÎnn.ß_\´læóÊŠˆéX¶Oˆ9ÿã…7,˜Þ\~°Rª×ïÔüí§÷s+vÍÙGëëüíôÊgõ<¹˜€7Ír̤҈(§W”tÕm7rêņÍBºhE‰eàÒ+|Ù¶.¦¢œŠ_›ªÜðJd¼–K¼M©ûj£”j¥¬dŸßŠ*+îoë§nöYkîî›Ïª*yîXÓ“/Ôõ´¶žeS—;Ô ”Žßê¸Zˆ`ùDˆj±ÎŠÅ¦Ìóø•©òdþÀg0;ìOkÅ‘ô™¢Õˆv[”âW1Ïð—Å=ŽêFe¬…µA<…¥p´ÊªZì’>ŒâÐ ê×|YiÇZçÓ²…±cx(sÝm?†–L›Xæõ§*yöyšÕ›QˆQ‰ÇO™xÀQÓÛå`òj‚H|•,¯tÙÚ9à©%_çIñ E¹œÔ\š¾|EÒkù„Ç|HžO™À'Rþ…üÍʶâEÌ_\þ}ýærŒ Y@÷RðÍW¸E}óùIË*Å Q¢fÊ—Ð3•vÒ.Ó®û…ø¤†m•q}‹šÒÖüû–Kî4[´)¦§·ÑyÌ{^ð*ÉUàŸ ‘üÀqVŸj)d@–ƒ 8`Spg·hU$k~>=ËŠZt’éÙ›<©ë΄ʌÚ=QÖðÜ´{Kªü^hC↠°æ2)P´‚{R)ÕŸp¢Tò¢ÉÃÒ“òl…oLšœJj¢V)è°mjOä5e‚²Æ3Î÷áý“@º+¯à!ÁT4–ceö‚¬½L$U¹•WÄ/vAÅQà]‚¡ áçÝó^5½Í%e©ø´ë¼ ÁUkÙ»EY=[o"Ñt<ë´¦’}±çó¦½z«õ J蹚þ¦Ïd=‘£XåîYÑsüå I§épR½üðØçšŸ¢È‰ã³¾{]òïM=Êõåmã\Uoèºy f0%©¥ŸPz…’DÞªeNNà;¤*Ï €Ϲj¶ Oyž­³†ÆrNÒXŠ•]Ø¥¹üœœXÀÙ‰L›³h7qÑ”ŸœºSPpqÉ21À"l¤|G@™]M/—¥#Ë+P¥´¥ Ušr$»`¡ÄÝêTÛ’o¬Nð>¨9k»‚t©g¤´“•vëMN¡J}Ïë®Ñ­”B½I–¢ïÆ`•ÜYŒ˜Û> endobj 3922 0 obj << /D [3920 0 R /XYZ 89 721 null] >> endobj 3919 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F102 2374 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3926 0 obj << /Length 555 /Filter /FlateDecode >> stream xÚuS]oÚ0}çWX¼Ä–ã$6‰«ªë`ë„ZTòÐjÛƒG\ˆB;þýìØI£O÷ؾçÞ{LÀðuð9Œf1óq8é àÄ$Á„2fàœ,Óû/wOÈ3”ˆ‘Ïé·©½\<"JàÃbúˆÆúúÙ¹ÞÍÝûòù>E<‚“'ô+ý>š±°Wšbl¬Ù4åBÆÓ€8‚Àoü0ÖA‘cU% |“™­±ÚˆJ¬jYííY¼hla½‘xWò£€ÀLù6ïDåö;±’Ÿ\”øB…¨óRÙ»Ò¨²Þäj SPÌ)~`ÎÜÐæ¹r)#n­o %W–Âm!öŽê®*w²ªö”ÉŸ„„*7U±õMÛÖRÉJ®ã2ìª-Î÷'Óì¦3ÌcÍYï!tœoç“årtÝK«ÄVÞØ•Ť·²$Á”ÆíÆü› [M0çÝN¯Où5iÝΞ^ÍNEq°e5?]*b-ѱM7l˜uDÂMƒµKÖàÒi% <¾XV™ó(­Í¤n±rÞš¶i {„ç“mÐ0>“ž îKÏätÒë³²ÒK’žôLƒäT6 ­(ˆ;!FýOˆæÝÑØNˆ> øà^‹F}QÒ&Ù¸oèYÐgm΢**38y÷~†9uÛi#Ø •‰º¬Ž—zÊN¼ÍüO¾ãÈ;û»îXjýæÊ‰0Wga(_ú4ür¬H` endstream endobj 3925 0 obj << /Type /Page /Contents 3926 0 R /Resources 3924 0 R /MediaBox [0 0 612 792] /Parent 3923 0 R >> endobj 3927 0 obj << /D [3925 0 R /XYZ 89 721 null] >> endobj 3924 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3937 0 obj << /Length 372 /Filter /FlateDecode >> stream xÚÕS=oÂ0ÝùV'gˆsv°“°•ª~Q‰fƒQp ÄÈ Eý÷upÔ Ô¨ ¨b¹óÙçwïÝÙ€–Ð]Z?LzÞ8Äú$Š’E€ñC-Ð ?Uí¸ŒV¹õÛ"«wÚ¡!–•ó–<|£ycÎPD"ÁDƒDéû!r9%!‹6gŒÝA3—àX9”ãÆHÝ–I—rà¸><Öjc7Wu½xÞ~¿wÇä}·.RY§åBËŠd&ëK Æ»‹°ò§â᜚S@z‰ìbzÈl2(œÜÇ-Ãá§…x!ÖÇ+é0#HKç] r¥kiÈW†®¥4æÂíÐÐÙåíJÕʵ‚“V…*Ý>d¯‹L–Y+ô&Ö2­ ›ÛL³í‡ÚlTYÝü®MœK›Oÿ˜Ï´Ïk2ºŸ<ßN&6œ3Níj?2¸ð „¸žá•ð¤âÿ>æÙ/à"ݦa@x„\ßø°oÙ²“†’Þ¯k» endstream endobj 3936 0 obj << /Type /Page /Contents 3937 0 R /Resources 3935 0 R /MediaBox [0 0 612 792] /Parent 3923 0 R /Annots [ 3928 0 R 3929 0 R 3930 0 R 3931 0 R 3932 0 R 3933 0 R 3934 0 R ] >> endobj 3928 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 525.497 162.109 536.401] /A << /S /GoTo /D (chapter*.1) >> >> endobj 3929 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 505.572 162.109 516.476] /A << /S /GoTo /D (subsubsection.2.2.1.6) >> >> endobj 3930 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 485.646 162.109 496.55] /A << /S /GoTo /D (subsection.3.8.3) >> >> endobj 3931 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 465.721 162.109 476.625] /A << /S /GoTo /D (section.4.12) >> >> endobj 3932 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 445.796 162.109 456.7] /A << /S /GoTo /D (subsubsection.5.4.6.1) >> >> endobj 3933 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 425.871 167.091 436.775] /A << /S /GoTo /D (figure.caption.11) >> >> endobj 3934 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.154 405.945 167.091 416.849] /A << /S /GoTo /D (subsection.7.14.2) >> >> endobj 3938 0 obj << /D [3936 0 R /XYZ 89 721 null] >> endobj 3939 0 obj << /D [3936 0 R /XYZ 90 690.045 null] >> endobj 3935 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3958 0 obj << /Length 965 /Filter /FlateDecode >> stream xÚ­VÑv›8}ÏWpò²â´& lúfg]w¤NmNzºiV@\ÉÉ߯„dj;qB>1iîÌÕÜ •ZКAóEG'ûÐr}§?è#+ºµBh:Þ@¾-­k0¢7ŒòTÄ«ÌF<Ú?¢i{þä#v­Ð 7Pg¡ÕÃÈÀ@½F?¶vC É'´î¬µuvd]÷„Ì.&vÏÅd<'ÚZÅ)Ù9¯Ÿ ITwgíóx¸¼·] â"!Kíót6ÙC!TfyN‹T/<Ð*3;ß½;ÖÖÍ£~^8ŸHQ´[ãÂø\8Wv-xy§)j–¿C ‡Ë%-yÑûj %#ßQ†rÚ}75¯;…‘z`øy2û}"׿wGžoyÈ­áî` Îe‡CÝ¡._ÎGêï)Å ·máäri§Ææò£1§±1¾ÙÒˆ… %Âö!x¯¿L7«æ4!%Ù‰Ô-Ñ\¿œµÕ«ªsö×\²Ê:ÕãºB¿SGʵÿ„ÅeIJý"5Áhab]ò¤ÎIQÅåE7šÃ=4KÕîQ6“‘Ôò áUF…aˆ,i¼u‹Jðº¬D½zMͯkÁ'Ñbìߤ¤iƒëKå+®*"ŠòX/éP<04É´9‘ÅÍåû`.Wcƒ>–¿×æåy®®ZÙ³›ÿHRI‡R9?kRVúÃHpÙÈ% âƒÝÞìu"Éh%7×Âøi䥌Ŋ$ô;„n¢«×xScçž–tå:ž9h»è©DY|ÃŒ¿[Áó½dw™;Ü·|xÏò1ÝC;¼F¦=Ó}êµ:U_ЖdÓ´\²:M[]å$爆‘øn[FM$ü{礖G_ì1È6èÓ«…vñu<Ú`a3ꬪVNNì'ipF'Ñü¾P9¸s•^Ι±-PÐh'©¡%²ßj§Ym„ˆÎô› ·Dùõgš7ì©rù™W[’jú1÷t@¹+ºfâ=U–Zn”ÕXûdôBñ¼†ÜîÝ{úÏÕø I¹¦X#ÛÇ ®¸ 1+;B{¡ÿ½øò†ýCSl~žŒàôpQ­0¾RÚ{V¥„éBßîÀêùØAëwƒí©>ŽŽþ@`÷ endstream endobj 3957 0 obj << /Type /Page /Contents 3958 0 R /Resources 3956 0 R /MediaBox [0 0 612 792] /Parent 3923 0 R /Annots [ 3940 0 R 3941 0 R 3942 0 R 3943 0 R 3944 0 R 3945 0 R 3946 0 R 3947 0 R 3948 0 R 3949 0 R 3950 0 R 3951 0 R 3952 0 R 3953 0 R 3954 0 R 3955 0 R ] >> endobj 3940 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 545.422 181.745 556.326] /Subtype/Link/A<> >> endobj 3941 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 505.572 192.435 516.476] /Subtype/Link/A<> >> endobj 3942 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 485.646 185.272 496.55] /Subtype/Link/A<> >> endobj 3943 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 465.721 181.755 476.625] /Subtype/Link/A<> >> endobj 3944 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 445.796 191.16 456.7] /Subtype/Link/A<> >> endobj 3945 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 405.945 259.812 416.849] /Subtype/Link/A<> >> endobj 3946 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 334.214 199.469 345.118] /Subtype/Link/A<> >> endobj 3947 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 242.558 185.621 253.462] /Subtype/Link/A<> >> endobj 3948 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 222.633 191.708 233.537] /Subtype/Link/A<> >> endobj 3949 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 202.707 291.054 213.611] /Subtype/Link/A<> >> endobj 3950 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 162.857 190.981 173.761] /Subtype/Link/A<> >> endobj 3951 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 142.932 185.063 153.836] /Subtype/Link/A<> >> endobj 3952 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 123.006 178.976 133.91] /Subtype/Link/A<> >> endobj 3953 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 103.081 197.108 113.985] /Subtype/Link/A<> >> endobj 3954 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 83.156 180.64 94.06] /Subtype/Link/A<> >> endobj 3955 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [110.583 63.23 313.898 74.134] /Subtype/Link/A<> >> endobj 3959 0 obj << /D [3957 0 R /XYZ 89 721 null] >> endobj 3960 0 obj << /D [3957 0 R /XYZ 90 690.045 null] >> endobj 2416 0 obj << /D [3957 0 R /XYZ 90 560.531 null] >> endobj 2417 0 obj << /D [3957 0 R /XYZ 90 540.605 null] >> endobj 2418 0 obj << /D [3957 0 R /XYZ 90 520.68 null] >> endobj 2368 0 obj << /D [3957 0 R /XYZ 90 500.755 null] >> endobj 2366 0 obj << /D [3957 0 R /XYZ 90 480.829 null] >> endobj 2453 0 obj << /D [3957 0 R /XYZ 90 460.904 null] >> endobj 2454 0 obj << /D [3957 0 R /XYZ 90 440.979 null] >> endobj 2840 0 obj << /D [3957 0 R /XYZ 90 421.054 null] >> endobj 3961 0 obj << /D [3957 0 R /XYZ 90 401.128 null] >> endobj 2841 0 obj << /D [3957 0 R /XYZ 90 381.203 null] >> endobj 3284 0 obj << /D [3957 0 R /XYZ 90 349.323 null] >> endobj 3962 0 obj << /D [3957 0 R /XYZ 90 329.397 null] >> endobj 3963 0 obj << /D [3957 0 R /XYZ 90 297.517 null] >> endobj 3964 0 obj << /D [3957 0 R /XYZ 90 277.592 null] >> endobj 2380 0 obj << /D [3957 0 R /XYZ 90 257.666 null] >> endobj 3965 0 obj << /D [3957 0 R /XYZ 90 237.741 null] >> endobj 2709 0 obj << /D [3957 0 R /XYZ 90 217.816 null] >> endobj 2560 0 obj << /D [3957 0 R /XYZ 90 197.89 null] >> endobj 3408 0 obj << /D [3957 0 R /XYZ 90 177.965 null] >> endobj 2367 0 obj << /D [3957 0 R /XYZ 90 158.04 null] >> endobj 3407 0 obj << /D [3957 0 R /XYZ 90 138.115 null] >> endobj 2710 0 obj << /D [3957 0 R /XYZ 90 118.189 null] >> endobj 2369 0 obj << /D [3957 0 R /XYZ 90 98.264 null] >> endobj 3441 0 obj << /D [3957 0 R /XYZ 90 78.339 null] >> endobj 3956 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4175 0 obj << /Length 1398 /Filter /FlateDecode >> stream xÚÕ[[oÛ6~ϯУ„Ž.I‰º}qœ´Ë¦…ãµÒ! %ÆÖ&KžÄtñ¿Ÿd{k8:<–Œtqò`~üÎ…çF†Z3‹ZïNè£ß§““×ojqo„³&wVD-Ÿ»&\k’X7öEž¨ç÷É/ÿ-zýVp+D>÷›Ô"‚Û||¾¸ryóy5qÏþi½”ÕߢV9³6ŒßX7„ j3Áw°4Æ‘[¸¯Ž/@ÎZAÞ¼9ÀßÜÞ–E¡o¥ÖPøˆ×@,ØÉiEâ¹Ìg r£]œPQÔªƒa’\³YšÏ&NHmY:,´g ˆr$Nvk×~MýÃôE–Õì{çË|q| iÐj™,H. ŽA0ižVº”:-rˆVh÷áåpüÀˆÐníóž‚Ìd¹€hºÈMŸÛó_¾r!;,¥ˆ")EæÁ¡`»' sÿfPˆès€n¸Ý] NöigçÄ‘»u7qÌ Oˆ°©:BËÀÑõ Ìã¡Aà°11ĺ[è™þX&–A7ÏÅå}^R!3¸yuWÙz°nØN³:“iñÐÿ|ëðè¶=Šà{Døž^ä{õ^½b ÕïJöø·Å™?ðBf NtëE#™e§pu„v^«3 š‹kžSžèP´?fwíá-ÎdU!ÃøcrŠË€ÊÉ‹÷g ‡~[³Ñ"nîVÖ÷,«¥º‚ûœEh­ÆÖéFÅb!sHÙaxìÀ‡ÁúÇŸQòvKÄFºÃgìáÂ[­l~ì¹¾èæ~WsÂ+„oâG/›ý£×Ùtô !Œ”YgÁ$SFó\ïèn'd4/îußâyX³ ¬>ÄÑ `´Æ¹‹Ðø*hýú ëw ‰šQ˜$ë;ˆÞýž"Ì7Åá`¡º¹*õ½Ìa‹ø þ¡švéúO‘È_÷Ê(é [WÓsu<^»×n+×ÿà g««`p†¢ejò°Êƒ<4¯Š |ÁzX^Ý/Ì*ýÌ ,¹.ë^P%DƱªª¾ °°½‘}ôL–œÿp)œQô=’ºŽÉž¼TÝnÚâRI­È™Z¿‰ø´¾B•åe‘φe)1¬ý9Ëþ®u3¯0ߣ]#]f׫J«8X@›9ÄOCÑOEzÊDë44‘Z’»¢\HðylÔ®Ú5’^-UGœæÊz*+uàÛ¨ïØ à§øHˆî$Ct-!ð£~Øç™Z¨¬æ84V2Y¡^9ðÖ@±³û3‡³é¨™/÷=¿ ] 4â‚›¨™Æªwú ØúZ•;˜”2¶ÿv{ËøÀnœ‚A ¶ÿ`Á9×ùääXÖ endstream endobj 4174 0 obj << /Type /Page /Contents 4175 0 R /Resources 4173 0 R /MediaBox [0 0 612 792] /Parent 3923 0 R /Annots [ 3966 0 R 3967 0 R 3968 0 R 3969 0 R 3970 0 R 3971 0 R 3972 0 R 3973 0 R 3974 0 R 3975 0 R 3976 0 R 3977 0 R 3978 0 R 3979 0 R 3980 0 R 3981 0 R 3982 0 R 3983 0 R 3984 0 R 3985 0 R 3986 0 R 3987 0 R 3988 0 R 3989 0 R 3990 0 R 3991 0 R 3992 0 R 3993 0 R 3994 0 R 3995 0 R 3996 0 R 3997 0 R 3998 0 R 3999 0 R 4000 0 R 4001 0 R 4002 0 R 4003 0 R 4004 0 R 4005 0 R 4006 0 R 4007 0 R 4008 0 R 4009 0 R 4010 0 R 4011 0 R 4012 0 R 4013 0 R 4014 0 R 4015 0 R 4016 0 R 4017 0 R 4018 0 R 4019 0 R 4020 0 R 4021 0 R 4022 0 R 4023 0 R 4024 0 R 4025 0 R 4026 0 R 4027 0 R 4028 0 R 4029 0 R 4030 0 R 4031 0 R 4032 0 R 4033 0 R 4034 0 R 4035 0 R 4036 0 R 4037 0 R 4038 0 R 4039 0 R 4040 0 R 4041 0 R 4042 0 R 4043 0 R 4044 0 R 4045 0 R 4046 0 R 4047 0 R 4048 0 R 4049 0 R 4050 0 R 4051 0 R 4052 0 R 4053 0 R 4054 0 R 4055 0 R 4056 0 R 4057 0 R 4058 0 R 4059 0 R 4060 0 R 4061 0 R 4062 0 R 4063 0 R 4064 0 R 4065 0 R 4066 0 R 4067 0 R 4068 0 R 4069 0 R 4070 0 R 4071 0 R 4072 0 R 4073 0 R 4074 0 R 4075 0 R 4076 0 R 4077 0 R 4078 0 R 4079 0 R 4080 0 R 4081 0 R 4082 0 R 4083 0 R 4084 0 R 4085 0 R 4086 0 R 4087 0 R 4088 0 R 4089 0 R 4090 0 R 4091 0 R 4092 0 R 4093 0 R 4094 0 R 4095 0 R 4096 0 R 4097 0 R 4098 0 R 4099 0 R 4100 0 R 4101 0 R 4102 0 R 4103 0 R 4104 0 R 4105 0 R 4106 0 R 4107 0 R 4108 0 R 4109 0 R 4110 0 R 4111 0 R 4112 0 R 4113 0 R 4114 0 R 4115 0 R 4116 0 R 4117 0 R 4118 0 R 4119 0 R 4120 0 R 4121 0 R 4122 0 R 4123 0 R 4124 0 R 4125 0 R 4126 0 R 4127 0 R 4128 0 R 4129 0 R 4130 0 R 4131 0 R 4132 0 R 4133 0 R 4134 0 R 4135 0 R 4136 0 R 4137 0 R 4138 0 R 4139 0 R 4140 0 R 4141 0 R 4142 0 R 4143 0 R 4144 0 R 4145 0 R 4146 0 R 4147 0 R 4148 0 R 4149 0 R 4150 0 R 4151 0 R 4152 0 R 4153 0 R 4154 0 R 4155 0 R 4156 0 R 4157 0 R 4158 0 R 4159 0 R 4160 0 R 4161 0 R 4162 0 R 4163 0 R 4164 0 R 4165 0 R 4166 0 R 4167 0 R 4168 0 R 4169 0 R 4170 0 R 4171 0 R ] >> endobj 3966 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.956 570.607 179.892 580.794] /A << /S /GoTo /D (page.152) >> >> endobj 3967 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [101.636 558.652 118.573 568.839] /A << /S /GoTo /D (page.121) >> >> endobj 3968 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [105.223 546.697 122.159 556.884] /A << /S /GoTo /D (page.121) >> >> endobj 3969 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.941 534.742 151.878 544.928] /A << /S /GoTo /D (page.181) >> >> endobj 3970 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.797 512.107 150.752 523.011] /A << /S /GoTo /D (page.39) >> >> endobj 3971 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [153.741 512.107 170.677 523.011] /A << /S /GoTo /D (page.199) >> >> endobj 3972 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.93 500.151 186.866 511.055] /A << /S /GoTo /D (page.102) >> >> endobj 3973 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [189.855 500.151 206.792 511.055] /A << /S /GoTo /D (page.205) >> >> endobj 3974 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [209.78 500.151 226.717 511.055] /A << /S /GoTo /D (page.211) >> >> endobj 3975 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.876 488.196 171.813 499.1] /A << /S /GoTo /D (page.102) >> >> endobj 3976 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.801 488.196 191.738 499.1] /A << /S /GoTo /D (page.165) >> >> endobj 3977 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [194.727 488.196 211.663 499.1] /A << /S /GoTo /D (page.205) >> >> endobj 3978 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [214.652 488.196 231.588 499.1] /A << /S /GoTo /D (page.207) >> >> endobj 3979 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [136.037 476.958 152.973 487.145] /A << /S /GoTo /D (page.101) >> >> endobj 3980 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.548 465.003 163.503 475.19] /A << /S /GoTo /D (page.25) >> >> endobj 3981 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.492 465.003 183.429 475.19] /A << /S /GoTo /D (page.101) >> >> endobj 3982 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.96 453.048 141.915 463.235] /A << /S /GoTo /D (page.99) >> >> endobj 3983 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.904 453.048 161.84 463.235] /A << /S /GoTo /D (page.162) >> >> endobj 3984 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [164.829 453.048 181.766 463.235] /A << /S /GoTo /D (page.199) >> >> endobj 3985 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.67 441.093 128.625 451.28] /A << /S /GoTo /D (page.93) >> >> endobj 3986 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.614 441.093 143.569 451.28] /A << /S /GoTo /D (page.99) >> >> endobj 3987 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.755 429.138 132.71 439.324] /A << /S /GoTo /D (page.13) >> >> endobj 3988 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [112.246 417.183 124.201 427.369] /A << /S /GoTo /D (page.23) >> >> endobj 3989 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.19 417.183 144.127 427.369] /A << /S /GoTo /D (page.251) >> >> endobj 3990 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.89 404.51 197.845 415.414] /A << /S /GoTo /D (page.99) >> >> endobj 3991 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [200.834 404.51 217.77 415.414] /A << /S /GoTo /D (page.100) >> >> endobj 3992 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [183.12 392.555 195.075 403.459] /A << /S /GoTo /D (page.91) >> >> endobj 3993 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [198.064 392.555 210.019 403.459] /A << /S /GoTo /D (page.95) >> >> endobj 3994 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.008 392.555 224.963 403.459] /A << /S /GoTo /D (page.99) >> >> endobj 3995 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [227.952 392.555 244.889 403.459] /A << /S /GoTo /D (page.133) >> >> endobj 3996 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [247.877 392.555 264.814 403.459] /A << /S /GoTo /D (page.138) >> >> endobj 3997 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [107.574 380.6 124.511 391.504] /A << /S /GoTo /D (page.109) >> >> endobj 3998 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.499 380.6 144.436 391.504] /A << /S /GoTo /D (page.110) >> >> endobj 3999 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.425 380.6 164.361 391.504] /A << /S /GoTo /D (page.114) >> >> endobj 4000 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [124.43 368.645 136.386 379.549] /A << /S /GoTo /D (page.33) >> >> endobj 4001 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [122.906 357.407 134.862 367.593] /A << /S /GoTo /D (page.37) >> >> endobj 4002 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [171.035 344.734 182.991 355.638] /A << /S /GoTo /D (page.40) >> >> endobj 4003 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.979 344.734 202.916 355.638] /A << /S /GoTo /D (page.200) >> >> endobj 4004 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.678 332.779 163.633 343.683] /A << /S /GoTo /D (page.40) >> >> endobj 4005 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.622 332.779 183.559 343.683] /A << /S /GoTo /D (page.200) >> >> endobj 4006 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [168.266 320.824 180.221 331.728] /A << /S /GoTo /D (page.40) >> >> endobj 4007 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [183.21 320.824 200.146 331.728] /A << /S /GoTo /D (page.200) >> >> endobj 4008 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [115.723 309.586 132.66 319.773] /A << /S /GoTo /D (page.253) >> >> endobj 4009 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.769 296.914 160.724 307.818] /A << /S /GoTo /D (page.34) >> >> endobj 4010 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [163.713 296.914 175.668 307.818] /A << /S /GoTo /D (page.39) >> >> endobj 4011 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [109.636 285.676 121.591 295.862] /A << /S /GoTo /D (page.90) >> >> endobj 4012 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [124.58 285.676 136.535 295.862] /A << /S /GoTo /D (page.94) >> >> endobj 4013 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [139.524 285.676 156.461 295.862] /A << /S /GoTo /D (page.131) >> >> endobj 4014 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.184 273.721 175.12 283.907] /A << /S /GoTo /D (page.161) >> >> endobj 4015 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [178.109 273.721 195.046 283.907] /A << /S /GoTo /D (page.162) >> >> endobj 4016 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [198.034 273.721 214.971 283.907] /A << /S /GoTo /D (page.199) >> >> endobj 4017 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [173.476 261.048 190.412 271.952] /A << /S /GoTo /D (page.166) >> >> endobj 4018 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [193.401 261.048 210.338 271.952] /A << /S /GoTo /D (page.192) >> >> endobj 4019 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.706 249.093 187.643 259.997] /A << /S /GoTo /D (page.192) >> >> endobj 4020 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.848 237.855 168.784 248.042] /A << /S /GoTo /D (page.137) >> >> endobj 4021 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.153 225.9 186.089 236.087] /A << /S /GoTo /D (page.161) >> >> endobj 4022 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [189.078 225.9 206.014 236.087] /A << /S /GoTo /D (page.199) >> >> endobj 4023 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [171.862 213.945 183.817 224.131] /A << /S /GoTo /D (page.41) >> >> endobj 4024 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.364 201.99 199.319 212.176] /A << /S /GoTo /D (page.43) >> >> endobj 4025 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.059 189.317 178.995 200.221] /A << /S /GoTo /D (page.170) >> >> endobj 4026 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.71 178.079 149.665 188.266] /A << /S /GoTo /D (page.69) >> >> endobj 4027 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.76 166.124 141.716 176.311] /A << /S /GoTo /D (page.90) >> >> endobj 4028 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.704 166.124 156.659 176.311] /A << /S /GoTo /D (page.93) >> >> endobj 4029 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [159.648 166.124 176.585 176.311] /A << /S /GoTo /D (page.136) >> >> endobj 4030 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.655 154.169 139.61 164.355] /A << /S /GoTo /D (page.15) >> >> endobj 4031 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.262 154.169 155.218 164.355] /A << /S /GoTo /D (page.19) >> >> endobj 4032 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.87 154.169 170.825 164.355] /A << /S /GoTo /D (page.20) >> >> endobj 4033 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.478 154.169 186.433 164.355] /A << /S /GoTo /D (page.22) >> >> endobj 4034 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [189.422 154.169 201.377 164.355] /A << /S /GoTo /D (page.24) >> >> endobj 4035 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [205.03 154.169 216.985 164.355] /A << /S /GoTo /D (page.27) >> >> endobj 4036 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [220.638 154.169 232.593 164.355] /A << /S /GoTo /D (page.36) >> >> endobj 4037 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [236.246 154.169 248.201 164.355] /A << /S /GoTo /D (page.55) >> >> endobj 4038 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [251.853 154.169 263.809 164.355] /A << /S /GoTo /D (page.57) >> >> endobj 4039 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [267.461 154.169 279.416 164.355] /A << /S /GoTo /D (page.90) >> >> endobj 4040 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [283.069 154.169 295.024 164.355] /A << /S /GoTo /D (page.92) >> >> endobj 4041 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [128.854 142.214 140.809 152.4] /A << /S /GoTo /D (page.93) >> >> endobj 4042 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.798 142.214 155.753 152.4] /A << /S /GoTo /D (page.99) >> >> endobj 4043 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.742 142.214 175.679 152.4] /A << /S /GoTo /D (page.118) >> >> endobj 4044 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [178.667 142.214 195.604 152.4] /A << /S /GoTo /D (page.135) >> >> endobj 4045 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [198.593 142.214 215.529 152.4] /A << /S /GoTo /D (page.137) >> >> endobj 4046 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [218.518 142.214 235.455 152.4] /A << /S /GoTo /D (page.193) >> >> endobj 4047 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.775 129.541 169.73 140.445] /A << /S /GoTo /D (page.92) >> >> endobj 4048 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [172.719 129.541 184.674 140.445] /A << /S /GoTo /D (page.97) >> >> endobj 4049 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.663 129.541 204.599 140.445] /A << /S /GoTo /D (page.124) >> >> endobj 4050 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [207.588 129.541 224.525 140.445] /A << /S /GoTo /D (page.127) >> >> endobj 4051 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.262 118.303 157.217 128.49] /A << /S /GoTo /D (page.70) >> >> endobj 4052 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.206 118.303 172.161 128.49] /A << /S /GoTo /D (page.83) >> >> endobj 4053 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [175.15 118.303 187.105 128.49] /A << /S /GoTo /D (page.84) >> >> endobj 4054 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.914 105.631 164.869 116.535] /A << /S /GoTo /D (page.33) >> >> endobj 4055 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.857 105.631 179.813 116.535] /A << /S /GoTo /D (page.36) >> >> endobj 4056 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [130.866 94.393 142.821 104.58] /A << /S /GoTo /D (page.69) >> >> endobj 4057 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.81 94.393 157.765 104.58] /A << /S /GoTo /D (page.79) >> >> endobj 4058 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.754 94.393 172.709 104.58] /A << /S /GoTo /D (page.84) >> >> endobj 4059 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.825 72.475 145.781 82.662] /A << /S /GoTo /D (page.23) >> >> endobj 4060 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.769 72.475 160.724 82.662] /A << /S /GoTo /D (page.25) >> >> endobj 4061 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [163.713 72.475 175.668 82.662] /A << /S /GoTo /D (page.90) >> >> endobj 4062 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [178.657 72.475 195.594 82.662] /A << /S /GoTo /D (page.191) >> >> endobj 4063 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [198.583 72.475 215.519 82.662] /A << /S /GoTo /D (page.204) >> >> endobj 4064 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [218.508 72.475 235.444 82.662] /A << /S /GoTo /D (page.239) >> >> endobj 4065 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [121.83 50.557 138.767 60.744] /A << /S /GoTo /D (page.150) >> >> endobj 4066 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [347.547 570.607 359.502 580.794] /A << /S /GoTo /D (page.33) >> >> endobj 4067 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [362.491 570.607 374.446 580.794] /A << /S /GoTo /D (page.41) >> >> endobj 4068 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.435 570.607 389.39 580.794] /A << /S /GoTo /D (page.43) >> >> endobj 4069 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.661 558.652 355.617 568.839] /A << /S /GoTo /D (page.34) >> >> endobj 4070 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [358.605 558.652 370.561 568.839] /A << /S /GoTo /D (page.35) >> >> endobj 4071 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [338.68 545.98 350.636 556.884] /A << /S /GoTo /D (page.37) >> >> endobj 4072 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.618 534.024 377.554 544.928] /A << /S /GoTo /D (page.102) >> >> endobj 4073 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.543 534.024 397.479 544.928] /A << /S /GoTo /D (page.104) >> >> endobj 4074 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [400.468 534.024 417.405 544.928] /A << /S /GoTo /D (page.123) >> >> endobj 4075 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.032 522.069 410.969 532.973] /A << /S /GoTo /D (page.166) >> >> endobj 4076 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [413.957 522.069 430.894 532.973] /A << /S /GoTo /D (page.192) >> >> endobj 4077 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [391.263 510.114 408.199 521.018] /A << /S /GoTo /D (page.192) >> >> endobj 4078 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [388.623 498.159 405.559 509.063] /A << /S /GoTo /D (page.219) >> >> endobj 4079 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.868 486.204 398.804 497.108] /A << /S /GoTo /D (page.170) >> >> endobj 4080 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.98 474.966 363.935 485.153] /A << /S /GoTo /D (page.88) >> >> endobj 4081 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [366.924 474.966 378.879 485.153] /A << /S /GoTo /D (page.90) >> >> endobj 4082 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.868 474.966 393.823 485.153] /A << /S /GoTo /D (page.91) >> >> endobj 4083 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.812 474.966 408.767 485.153] /A << /S /GoTo /D (page.96) >> >> endobj 4084 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [411.756 474.966 428.693 485.153] /A << /S /GoTo /D (page.110) >> >> endobj 4085 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [431.681 474.966 448.618 485.153] /A << /S /GoTo /D (page.129) >> >> endobj 4086 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.759 463.011 361.714 473.197] /A << /S /GoTo /D (page.23) >> >> endobj 4087 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.703 463.011 376.658 473.197] /A << /S /GoTo /D (page.24) >> >> endobj 4088 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.647 463.011 391.602 473.197] /A << /S /GoTo /D (page.88) >> >> endobj 4089 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.591 463.011 406.546 473.197] /A << /S /GoTo /D (page.91) >> >> endobj 4090 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [409.535 463.011 421.49 473.197] /A << /S /GoTo /D (page.92) >> >> endobj 4091 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [424.478 463.011 436.434 473.197] /A << /S /GoTo /D (page.94) >> >> endobj 4092 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [439.422 463.011 451.378 473.197] /A << /S /GoTo /D (page.99) >> >> endobj 4093 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [454.366 463.011 471.303 473.197] /A << /S /GoTo /D (page.126) >> >> endobj 4094 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [474.292 463.011 491.228 473.197] /A << /S /GoTo /D (page.129) >> >> endobj 4095 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [494.217 463.011 511.153 473.197] /A << /S /GoTo /D (page.156) >> >> endobj 4096 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.543 450.338 392.498 461.242] /A << /S /GoTo /D (page.92) >> >> endobj 4097 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [395.487 450.338 407.442 461.242] /A << /S /GoTo /D (page.96) >> >> endobj 4098 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [410.431 450.338 422.386 461.242] /A << /S /GoTo /D (page.97) >> >> endobj 4099 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [425.375 450.338 442.311 461.242] /A << /S /GoTo /D (page.104) >> >> endobj 4100 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [445.3 450.338 462.237 461.242] /A << /S /GoTo /D (page.124) >> >> endobj 4101 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [465.225 450.338 482.162 461.242] /A << /S /GoTo /D (page.155) >> >> endobj 4102 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.555 439.1 394.511 449.287] /A << /S /GoTo /D (page.24) >> >> endobj 4103 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.499 439.1 409.455 449.287] /A << /S /GoTo /D (page.92) >> >> endobj 4104 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.443 439.1 424.399 449.287] /A << /S /GoTo /D (page.98) >> >> endobj 4105 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [427.387 439.1 444.324 449.287] /A << /S /GoTo /D (page.129) >> >> endobj 4106 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.559 427.145 385.514 437.332] /A << /S /GoTo /D (page.24) >> >> endobj 4107 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [388.503 427.145 400.458 437.332] /A << /S /GoTo /D (page.47) >> >> endobj 4108 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [403.447 427.145 415.402 437.332] /A << /S /GoTo /D (page.52) >> >> endobj 4109 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [418.391 427.145 430.346 437.332] /A << /S /GoTo /D (page.55) >> >> endobj 4110 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [433.335 427.145 445.29 437.332] /A << /S /GoTo /D (page.90) >> >> endobj 4111 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [448.279 427.145 460.234 437.332] /A << /S /GoTo /D (page.98) >> >> endobj 4112 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [463.223 427.145 480.159 437.332] /A << /S /GoTo /D (page.239) >> >> endobj 4113 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.194 414.846 392.149 425.377] /A << /S /GoTo /D (page.39) >> >> endobj 4114 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.858 403.235 398.794 413.422] /A << /S /GoTo /D (page.245) >> >> endobj 4115 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.561 390.562 411.517 401.466] /A << /S /GoTo /D (page.24) >> >> endobj 4116 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.505 390.562 426.461 401.466] /A << /S /GoTo /D (page.90) >> >> endobj 4117 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.851 378.607 429.788 389.511] /A << /S /GoTo /D (page.169) >> >> endobj 4118 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [432.777 378.607 449.713 389.511] /A << /S /GoTo /D (page.241) >> >> endobj 4119 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [452.702 378.607 469.638 389.511] /A << /S /GoTo /D (page.243) >> >> endobj 4120 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.851 366.652 429.788 377.556] /A << /S /GoTo /D (page.246) >> >> endobj 4121 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [415.063 354.697 427.018 365.601] /A << /S /GoTo /D (page.26) >> >> endobj 4122 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.26 343.459 377.215 353.646] /A << /S /GoTo /D (page.69) >> >> endobj 4123 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [390.615 330.787 402.57 341.69] /A << /S /GoTo /D (page.25) >> >> endobj 4124 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [405.559 330.787 422.495 341.69] /A << /S /GoTo /D (page.239) >> >> endobj 4125 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.114 318.831 387.069 329.735] /A << /S /GoTo /D (page.25) >> >> endobj 4126 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [390.058 318.831 406.994 329.735] /A << /S /GoTo /D (page.240) >> >> endobj 4127 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.482 307.594 379.437 317.78] /A << /S /GoTo /D (page.70) >> >> endobj 4128 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.426 307.594 394.381 317.78] /A << /S /GoTo /D (page.83) >> >> endobj 4129 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.37 307.594 409.325 317.78] /A << /S /GoTo /D (page.84) >> >> endobj 4130 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [353.634 295.638 365.589 305.825] /A << /S /GoTo /D (page.69) >> >> endobj 4131 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [368.578 295.638 380.533 305.825] /A << /S /GoTo /D (page.79) >> >> endobj 4132 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.522 295.638 395.477 305.825] /A << /S /GoTo /D (page.85) >> >> endobj 4133 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [350.874 282.966 367.811 293.87] /A << /S /GoTo /D (page.149) >> >> endobj 4134 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [340.902 271.728 357.838 281.915] /A << /S /GoTo /D (page.139) >> >> endobj 4135 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.802 259.773 360.757 269.959] /A << /S /GoTo /D (page.27) >> >> endobj 4136 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.746 259.773 380.683 269.959] /A << /S /GoTo /D (page.213) >> >> endobj 4137 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.626 247.818 391.581 258.004] /A << /S /GoTo /D (page.27) >> >> endobj 4138 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.57 247.818 411.506 258.004] /A << /S /GoTo /D (page.187) >> >> endobj 4139 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [344.439 235.862 356.394 246.049] /A << /S /GoTo /D (page.13) >> >> endobj 4140 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [359.383 235.862 371.338 246.049] /A << /S /GoTo /D (page.22) >> >> endobj 4141 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.327 235.862 386.282 246.049] /A << /S /GoTo /D (page.90) >> >> endobj 4142 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [389.271 235.862 401.226 246.049] /A << /S /GoTo /D (page.98) >> >> endobj 4143 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [404.215 235.862 421.151 246.049] /A << /S /GoTo /D (page.103) >> >> endobj 4144 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [424.14 235.862 441.076 246.049] /A << /S /GoTo /D (page.157) >> >> endobj 4145 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [444.065 235.862 461.002 246.049] /A << /S /GoTo /D (page.204) >> >> endobj 4146 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [327.612 223.907 339.567 234.094] /A << /S /GoTo /D (page.69) >> >> endobj 4147 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [411.357 211.235 428.294 222.139] /A << /S /GoTo /D (page.113) >> >> endobj 4148 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.684 199.28 431.621 210.184] /A << /S /GoTo /D (page.114) >> >> endobj 4149 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [355.307 187.325 372.244 198.228] /A << /S /GoTo /D (page.178) >> >> endobj 4150 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.233 187.325 392.169 198.228] /A << /S /GoTo /D (page.180) >> >> endobj 4151 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [395.158 187.325 412.094 198.228] /A << /S /GoTo /D (page.190) >> >> endobj 4152 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [415.083 187.325 432.02 198.228] /A << /S /GoTo /D (page.214) >> >> endobj 4153 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [435.009 187.325 451.945 198.228] /A << /S /GoTo /D (page.215) >> >> endobj 4154 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.941 166.124 373.878 176.311] /A << /S /GoTo /D (page.194) >> >> endobj 4155 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [347.537 153.452 364.473 164.355] /A << /S /GoTo /D (page.194) >> >> endobj 4156 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [346.979 142.214 358.934 152.4] /A << /S /GoTo /D (page.33) >> >> endobj 4157 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [344.767 130.259 356.722 140.445] /A << /S /GoTo /D (page.23) >> >> endobj 4158 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [359.711 130.259 371.666 140.445] /A << /S /GoTo /D (page.27) >> >> endobj 4159 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.655 130.259 391.592 140.445] /A << /S /GoTo /D (page.184) >> >> endobj 4160 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.58 130.259 411.517 140.445] /A << /S /GoTo /D (page.185) >> >> endobj 4161 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.506 130.259 431.442 140.445] /A << /S /GoTo /D (page.253) >> >> endobj 4162 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.431 130.259 451.368 140.445] /A << /S /GoTo /D (page.254) >> >> endobj 4163 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [362.481 118.303 374.436 128.49] /A << /S /GoTo /D (page.62) >> >> endobj 4164 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.632 105.631 408.588 116.535] /A << /S /GoTo /D (page.42) >> >> endobj 4165 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.134 93.676 424.089 104.58] /A << /S /GoTo /D (page.43) >> >> endobj 4166 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [344.229 82.438 356.184 92.624] /A << /S /GoTo /D (page.33) >> >> endobj 4167 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [359.173 82.438 371.128 92.624] /A << /S /GoTo /D (page.93) >> >> endobj 4168 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [341.45 70.483 353.405 80.669] /A << /S /GoTo /D (page.33) >> >> endobj 4169 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [350.605 58.528 362.561 68.714] /A << /S /GoTo /D (page.33) >> >> endobj 4170 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.549 58.528 377.505 68.714] /A << /S /GoTo /D (page.91) >> >> endobj 4171 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.095 46.572 360.05 56.759] /A << /S /GoTo /D (page.33) >> >> endobj 4176 0 obj << /D [4174 0 R /XYZ 89 721 null] >> endobj 4173 0 obj << /Font << /F70 1879 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4407 0 obj << /Length 1537 /Filter /FlateDecode >> stream xÚÍ[[oâ:~ï¯È#H'ÔvîÛº±«ªE:Gê­L04ÚÜ”„¶ûï“Êf<$ >t»ñç™±gæ›ñ”hKh÷W7Ó«ë‘cjÞÀ³™­MšG4‡¸bZÚt®=÷Æßï†ÿöÿ›þ}=²ØÎwfù‘eK”ê3fåGWd ¬é›tæÈEFýÙàóQ"ÇòŸ×>³z<ü«ZJåB¢eK­þÏ£yÖ™EzÌ2÷±‰¦S:𬵈s1ë3Ò[-Ê(€ŠBŸ‹R¨×ÀœgÁhçíÃ=÷ u ½2dXp½€Pl†Ý÷P·Í¾öî¾j—¡ÃÝ·Zç~¤EÄàEDoMÑ+ä F @½êê1 +hºÈ½-¬A,GIÖ¼àÖýÎâ/®²¸«üËko¢o%ï0ö“¹˜C`.kT~ ¶Š $bc±Õöβ$뛄£– ܨOe BØ4ÔR¹pÌ·=E}ѧ¤Çý"É~÷m RØÃÆH{Bè0E‰‰]Áð+•û/íù¥(² f ` 1 •Ë#AoCžCQÀņXüQZg?ÊšYªçtÇ ÞÕ™£4ìüÈ vAkGQH-´-Ùìð‚ëµàîÖol‚ö&Lf—àC´{È’w•´¶™m«˜@–zÙí —bøZ¦X .h²Ø“ ‡ÊSé²Mÿד ½£„¡‰»…^á©Èü„á™d¦¶u-]-…¤ÝX¬ÚVàãnUX|‡k*F"ˆôw°(´@ ÿ†qòôgXëW9Ø™!  ùo}¶ð=4»„š D£hJ *ÂA…º@¥1™€I"ñW‘Œr\¡_ááCRsƒèî©ìÙ•æW*»Ð¾G‰Ñ•·n$ηyáfµ(¯ÏBd_ß"ÐkÍæŽÕºYµ FÝŸI êÔ@ÃPÈR„ƒ\ªQóY(tQ*ú•õƒXDþP( z-[>öuoAŸÃ žq~µH²ˆ-ÁÖ=LÝ5@D¼Š~†|&ÂüÔØ¶Nºt¦âÑlŒlnBG‘áÓã¨ïÂ0hþÐLºvâû¬ÐóÕ¬ìÌÎÀ¶¥© C×]uØ,c`w0±Õ ‹=t]t5o¢ëMt/š:NÇ{G“$#†LE$sÜéþ¾9dçQŽQ{`ºT³ :?k_~-{‡u¬“ß‘ç<Ç8tûš‡ÍŽúzù~ Ùhz[f#²è©vh¥§|Ù@›_÷Pµ'mŒ²—š[¸]ûÔEíg(:isŸcX1l¾“Ú€/íÎI;ûC:¼»¶Gu‘üUQòÁîÙ¹i#Dè.ç¶n[s‰7 ¯}“ºY‡]ÔCúVY®•>”ã8/x ¾@QMáLCá¤I†¥øãÃͦ¬“ü¢ë’—R|c›/éÜZØ2×ÁÞç6“Ö $Ô¹¬WÊjEO“0 â¥^×.›BV…é;M‹˜Šh~4ÿLR©U‰@“I‚¼U­È˰d?[ÁZ¦”Úè&‹jŽ*„›™Õè­ª«UŽýÒ®ë,}Œ>Íœ}9ŸµEžut¿æ¯ÐxúU”™”D9„šÍ7»ÄYKdbðµÔ©àv«™ɨaa Ë,Y¥'še& Ò“Ïøî^“d¹”!Õª¾‹gŠ’O˾ÏúÔ-­ó™Eß\팧/O¢;)Õ¹W¸€À$ÊfØÔaZ8ZŠNf]ÏýU†,sÈ£HC•—¬®ÛÖû(”ô*x·Ñ\Y4èÊöUZmùÏ1ƒ]òôwiÇ Ï×v Ãh"÷»ÍîøõŸo'¼íZt|½s2Öv€ð@èñ·/%½‚5@3Nq°ïæ4{ÿ¸„P¤Äö2šé{/’®ß:×2à'ˆ_D†ïŒ( Ùq½¯B+?çGÏÝÑ¢Ô=ÿ¤¦ÕÜóè Ô:u¤ãQˆ@a¤=Í@™qùYÜ#Š!þj‰œ}<ùòuø{8½ú<¨ý endstream endobj 4406 0 obj << /Type /Page /Contents 4407 0 R /Resources 4405 0 R /MediaBox [0 0 612 792] /Parent 3923 0 R /Annots [ 4172 0 R 4177 0 R 4178 0 R 4179 0 R 4180 0 R 4181 0 R 4182 0 R 4183 0 R 4184 0 R 4185 0 R 4186 0 R 4187 0 R 4188 0 R 4189 0 R 4190 0 R 4191 0 R 4192 0 R 4193 0 R 4194 0 R 4195 0 R 4196 0 R 4197 0 R 4198 0 R 4199 0 R 4200 0 R 4201 0 R 4202 0 R 4203 0 R 4204 0 R 4205 0 R 4206 0 R 4207 0 R 4208 0 R 4209 0 R 4210 0 R 4211 0 R 4212 0 R 4213 0 R 4214 0 R 4215 0 R 4216 0 R 4217 0 R 4218 0 R 4219 0 R 4220 0 R 4221 0 R 4222 0 R 4223 0 R 4224 0 R 4225 0 R 4226 0 R 4227 0 R 4228 0 R 4229 0 R 4230 0 R 4231 0 R 4232 0 R 4233 0 R 4234 0 R 4235 0 R 4236 0 R 4237 0 R 4238 0 R 4239 0 R 4240 0 R 4241 0 R 4242 0 R 4243 0 R 4244 0 R 4245 0 R 4246 0 R 4247 0 R 4248 0 R 4249 0 R 4250 0 R 4251 0 R 4252 0 R 4253 0 R 4254 0 R 4255 0 R 4256 0 R 4257 0 R 4258 0 R 4259 0 R 4260 0 R 4261 0 R 4262 0 R 4263 0 R 4264 0 R 4265 0 R 4266 0 R 4267 0 R 4268 0 R 4269 0 R 4270 0 R 4271 0 R 4272 0 R 4273 0 R 4274 0 R 4275 0 R 4276 0 R 4277 0 R 4278 0 R 4279 0 R 4280 0 R 4281 0 R 4282 0 R 4283 0 R 4284 0 R 4285 0 R 4286 0 R 4287 0 R 4288 0 R 4289 0 R 4290 0 R 4291 0 R 4292 0 R 4293 0 R 4294 0 R 4295 0 R 4296 0 R 4297 0 R 4298 0 R 4299 0 R 4300 0 R 4301 0 R 4302 0 R 4303 0 R 4304 0 R 4305 0 R 4306 0 R 4307 0 R 4308 0 R 4309 0 R 4310 0 R 4311 0 R 4312 0 R 4313 0 R 4314 0 R 4315 0 R 4316 0 R 4317 0 R 4318 0 R 4319 0 R 4320 0 R 4321 0 R 4322 0 R 4323 0 R 4324 0 R 4325 0 R 4326 0 R 4327 0 R 4328 0 R 4329 0 R 4330 0 R 4331 0 R 4332 0 R 4333 0 R 4334 0 R 4335 0 R 4336 0 R 4337 0 R 4338 0 R 4339 0 R 4340 0 R 4341 0 R 4342 0 R 4343 0 R 4344 0 R 4345 0 R 4346 0 R 4347 0 R 4348 0 R 4349 0 R 4350 0 R 4351 0 R 4352 0 R 4353 0 R 4354 0 R 4355 0 R 4356 0 R 4357 0 R 4358 0 R 4359 0 R 4360 0 R 4361 0 R 4362 0 R 4363 0 R 4364 0 R 4365 0 R 4366 0 R 4367 0 R 4368 0 R 4369 0 R 4370 0 R 4371 0 R 4372 0 R 4373 0 R 4374 0 R 4375 0 R 4376 0 R 4377 0 R 4378 0 R 4379 0 R 4380 0 R 4381 0 R 4382 0 R 4383 0 R 4384 0 R 4385 0 R 4386 0 R 4387 0 R 4388 0 R 4389 0 R 4390 0 R 4391 0 R 4392 0 R 4393 0 R 4394 0 R 4395 0 R 4396 0 R 4397 0 R 4398 0 R 4399 0 R ] >> endobj 4172 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.329 677.646 184.265 687.833] /A << /S /GoTo /D (page.254) >> >> endobj 4177 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [118.134 664.974 135.071 675.878] /A << /S /GoTo /D (page.121) >> >> endobj 4178 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.423 653.736 154.378 663.923] /A << /S /GoTo /D (page.95) >> >> endobj 4179 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.846 641.781 158.801 651.968] /A << /S /GoTo /D (page.99) >> >> endobj 4180 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [161.79 641.781 178.727 651.968] /A << /S /GoTo /D (page.133) >> >> endobj 4181 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [181.715 641.781 198.652 651.968] /A << /S /GoTo /D (page.134) >> >> endobj 4182 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.439 629.826 136.376 640.012] /A << /S /GoTo /D (page.162) >> >> endobj 4183 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [139.364 629.826 156.301 640.012] /A << /S /GoTo /D (page.199) >> >> endobj 4184 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [128.595 617.871 145.531 628.057] /A << /S /GoTo /D (page.162) >> >> endobj 4185 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.52 617.871 165.456 628.057] /A << /S /GoTo /D (page.199) >> >> endobj 4186 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.258 605.198 150.214 616.102] /A << /S /GoTo /D (page.25) >> >> endobj 4187 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [153.202 605.198 170.139 616.102] /A << /S /GoTo /D (page.191) >> >> endobj 4188 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [173.128 605.198 190.064 616.102] /A << /S /GoTo /D (page.197) >> >> endobj 4189 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [193.053 605.198 209.989 616.102] /A << /S /GoTo /D (page.203) >> >> endobj 4190 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.018 593.96 144.974 604.147] /A << /S /GoTo /D (page.48) >> >> endobj 4191 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.962 593.96 159.917 604.147] /A << /S /GoTo /D (page.55) >> >> endobj 4192 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.906 593.96 174.861 604.147] /A << /S /GoTo /D (page.57) >> >> endobj 4193 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.701 582.005 141.656 592.192] /A << /S /GoTo /D (page.95) >> >> endobj 4194 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.645 582.005 161.581 592.192] /A << /S /GoTo /D (page.133) >> >> endobj 4195 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [164.57 582.005 181.506 592.192] /A << /S /GoTo /D (page.138) >> >> endobj 4196 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.134 570.05 146.089 580.237] /A << /S /GoTo /D (page.95) >> >> endobj 4197 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [149.078 570.05 166.014 580.237] /A << /S /GoTo /D (page.133) >> >> endobj 4198 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.003 570.05 185.94 580.237] /A << /S /GoTo /D (page.138) >> >> endobj 4199 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.193 558.095 162.129 568.281] /A << /S /GoTo /D (page.182) >> >> endobj 4200 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.134 546.14 151.071 556.326] /A << /S /GoTo /D (page.106) >> >> endobj 4201 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.06 546.14 170.996 556.326] /A << /S /GoTo /D (page.162) >> >> endobj 4202 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [130.956 534.184 147.893 544.371] /A << /S /GoTo /D (page.115) >> >> endobj 4203 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.091 522.229 152.027 532.416] /A << /S /GoTo /D (page.115) >> >> endobj 4204 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.738 510.274 131.693 520.461] /A << /S /GoTo /D (page.69) >> >> endobj 4205 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.522 497.602 162.478 508.506] /A << /S /GoTo /D (page.92) >> >> endobj 4206 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [165.466 497.602 177.422 508.506] /A << /S /GoTo /D (page.96) >> >> endobj 4207 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [180.41 497.602 192.366 508.506] /A << /S /GoTo /D (page.97) >> >> endobj 4208 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [195.354 497.602 212.291 508.506] /A << /S /GoTo /D (page.104) >> >> endobj 4209 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [215.28 497.602 232.216 508.506] /A << /S /GoTo /D (page.124) >> >> endobj 4210 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [235.205 497.602 252.141 508.506] /A << /S /GoTo /D (page.127) >> >> endobj 4211 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.725 486.364 169.68 496.55] /A << /S /GoTo /D (page.33) >> >> endobj 4212 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.538 474.409 155.494 484.595] /A << /S /GoTo /D (page.88) >> >> endobj 4213 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.482 474.409 170.438 484.595] /A << /S /GoTo /D (page.92) >> >> endobj 4214 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [173.426 474.409 185.382 484.595] /A << /S /GoTo /D (page.95) >> >> endobj 4215 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.37 474.409 200.325 484.595] /A << /S /GoTo /D (page.97) >> >> endobj 4216 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [203.314 474.409 220.251 484.595] /A << /S /GoTo /D (page.124) >> >> endobj 4217 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [223.24 474.409 240.176 484.595] /A << /S /GoTo /D (page.126) >> >> endobj 4218 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [243.165 474.409 260.101 484.595] /A << /S /GoTo /D (page.129) >> >> endobj 4219 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [263.09 474.409 280.027 484.595] /A << /S /GoTo /D (page.153) >> >> endobj 4220 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [140.759 462.453 152.714 472.64] /A << /S /GoTo /D (page.33) >> >> endobj 4221 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [140.769 449.781 152.724 460.685] /A << /S /GoTo /D (page.88) >> >> endobj 4222 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.713 449.781 167.668 460.685] /A << /S /GoTo /D (page.90) >> >> endobj 4223 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.657 449.781 182.612 460.685] /A << /S /GoTo /D (page.94) >> >> endobj 4224 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.601 449.781 202.537 460.685] /A << /S /GoTo /D (page.127) >> >> endobj 4225 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [205.526 449.781 222.463 460.685] /A << /S /GoTo /D (page.131) >> >> endobj 4226 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [225.451 449.781 242.388 460.685] /A << /S /GoTo /D (page.134) >> >> endobj 4227 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [245.377 449.781 262.313 460.685] /A << /S /GoTo /D (page.153) >> >> endobj 4228 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [139.663 437.826 151.618 448.73] /A << /S /GoTo /D (page.33) >> >> endobj 4229 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.607 437.826 166.562 448.73] /A << /S /GoTo /D (page.35) >> >> endobj 4230 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.551 437.826 181.506 448.73] /A << /S /GoTo /D (page.60) >> >> endobj 4231 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [159.04 425.871 170.996 436.775] /A << /S /GoTo /D (page.35) >> >> endobj 4232 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [173.984 425.871 185.939 436.775] /A << /S /GoTo /D (page.60) >> >> endobj 4233 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.103 413.915 157.058 424.819] /A << /S /GoTo /D (page.33) >> >> endobj 4234 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.047 413.915 172.002 424.819] /A << /S /GoTo /D (page.66) >> >> endobj 4235 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [197.058 401.96 209.013 412.864] /A << /S /GoTo /D (page.42) >> >> endobj 4236 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [212.559 390.005 224.514 400.909] /A << /S /GoTo /D (page.43) >> >> endobj 4237 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.165 378.767 172.101 388.954] /A << /S /GoTo /D (page.102) >> >> endobj 4238 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [175.09 378.767 192.027 388.954] /A << /S /GoTo /D (page.205) >> >> endobj 4239 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [195.016 378.767 211.952 388.954] /A << /S /GoTo /D (page.209) >> >> endobj 4240 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.751 366.812 167.688 376.999] /A << /S /GoTo /D (page.102) >> >> endobj 4241 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.677 366.812 187.613 376.999] /A << /S /GoTo /D (page.165) >> >> endobj 4242 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.602 366.812 207.538 376.999] /A << /S /GoTo /D (page.205) >> >> endobj 4243 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [210.527 366.812 227.464 376.999] /A << /S /GoTo /D (page.208) >> >> endobj 4244 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.557 354.857 155.494 365.044] /A << /S /GoTo /D (page.101) >> >> endobj 4245 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.483 354.857 175.419 365.044] /A << /S /GoTo /D (page.205) >> >> endobj 4246 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.049 342.902 170.986 353.088] /A << /S /GoTo /D (page.218) >> >> endobj 4247 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [117.786 330.947 134.722 341.133] /A << /S /GoTo /D (page.195) >> >> endobj 4248 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [117.138 318.274 134.075 329.178] /A << /S /GoTo /D (page.195) >> >> endobj 4249 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.542 306.319 151.479 317.223] /A << /S /GoTo /D (page.202) >> >> endobj 4250 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [141.586 294.364 158.522 305.268] /A << /S /GoTo /D (page.197) >> >> endobj 4251 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.091 282.409 152.027 293.312] /A << /S /GoTo /D (page.196) >> >> endobj 4252 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.016 282.409 171.952 293.312] /A << /S /GoTo /D (page.202) >> >> endobj 4253 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [111.15 271.171 128.087 281.357] /A << /S /GoTo /D (page.185) >> >> endobj 4254 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [113.352 259.216 130.289 269.402] /A << /S /GoTo /D (page.152) >> >> endobj 4255 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [153.202 247.26 165.158 257.447] /A << /S /GoTo /D (page.92) >> >> endobj 4256 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [168.146 247.26 185.083 257.447] /A << /S /GoTo /D (page.204) >> >> endobj 4257 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.632 235.305 143.569 245.492] /A << /S /GoTo /D (page.101) >> >> endobj 4258 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.558 235.305 163.494 245.492] /A << /S /GoTo /D (page.103) >> >> endobj 4259 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.483 235.305 183.42 245.492] /A << /S /GoTo /D (page.205) >> >> endobj 4260 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [176.037 223.35 192.973 233.537] /A << /S /GoTo /D (page.214) >> >> endobj 4261 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.296 211.395 137.233 221.581] /A << /S /GoTo /D (page.108) >> >> endobj 4262 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.545 189.477 132.5 199.664] /A << /S /GoTo /D (page.13) >> >> endobj 4263 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [168.525 176.805 180.48 187.709] /A << /S /GoTo /D (page.49) >> >> endobj 4264 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [183.469 176.805 195.424 187.709] /A << /S /GoTo /D (page.55) >> >> endobj 4265 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.095 165.567 164.032 175.753] /A << /S /GoTo /D (page.108) >> >> endobj 4266 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.058 153.612 173.994 163.798] /A << /S /GoTo /D (page.108) >> >> endobj 4267 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [164.62 141.656 181.556 151.843] /A << /S /GoTo /D (page.182) >> >> endobj 4268 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.346 129.701 161.282 139.888] /A << /S /GoTo /D (page.197) >> >> endobj 4269 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.452 117.746 162.388 127.933] /A << /S /GoTo /D (page.162) >> >> endobj 4270 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [112.944 105.791 129.88 115.977] /A << /S /GoTo /D (page.115) >> >> endobj 4271 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.999 93.836 128.954 104.022] /A << /S /GoTo /D (page.12) >> >> endobj 4272 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.943 93.836 143.898 104.022] /A << /S /GoTo /D (page.13) >> >> endobj 4273 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [156.111 81.881 168.067 92.067] /A << /S /GoTo /D (page.44) >> >> endobj 4274 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [115.165 69.925 127.121 80.112] /A << /S /GoTo /D (page.29) >> >> endobj 4275 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [130.109 69.925 142.065 80.112] /A << /S /GoTo /D (page.36) >> >> endobj 4276 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.053 69.925 157.009 80.112] /A << /S /GoTo /D (page.39) >> >> endobj 4277 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [159.997 69.925 171.953 80.112] /A << /S /GoTo /D (page.40) >> >> endobj 4278 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.941 69.925 186.896 80.112] /A << /S /GoTo /D (page.82) >> >> endobj 4279 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [189.885 69.925 201.84 80.112] /A << /S /GoTo /D (page.83) >> >> endobj 4280 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [204.829 69.925 216.784 80.112] /A << /S /GoTo /D (page.86) >> >> endobj 4281 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [219.773 69.925 236.71 80.112] /A << /S /GoTo /D (page.147) >> >> endobj 4282 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [239.698 69.925 256.635 80.112] /A << /S /GoTo /D (page.148) >> >> endobj 4283 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [259.624 69.925 276.56 80.112] /A << /S /GoTo /D (page.177) >> >> endobj 4284 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [279.549 69.925 296.486 80.112] /A << /S /GoTo /D (page.199) >> >> endobj 4285 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [136.196 57.253 153.133 68.157] /A << /S /GoTo /D (page.183) >> >> endobj 4286 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.937 45.298 155.892 56.202] /A << /S /GoTo /D (page.40) >> >> endobj 4287 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [386.182 677.646 403.118 687.943] /A << /S /GoTo /D (page.214) >> >> endobj 4288 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.145 664.974 434.082 675.878] /A << /S /GoTo /D (page.205) >> >> endobj 4289 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [437.071 664.974 454.007 675.878] /A << /S /GoTo /D (page.211) >> >> endobj 4290 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.369 653.736 364.324 663.923] /A << /S /GoTo /D (page.41) >> >> endobj 4291 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.87 641.781 379.826 651.968] /A << /S /GoTo /D (page.43) >> >> endobj 4292 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.366 629.108 431.302 640.012] /A << /S /GoTo /D (page.102) >> >> endobj 4293 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.291 629.108 451.228 640.012] /A << /S /GoTo /D (page.205) >> >> endobj 4294 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [454.216 629.108 471.153 640.012] /A << /S /GoTo /D (page.210) >> >> endobj 4295 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [338.132 617.153 355.069 628.057] /A << /S /GoTo /D (page.115) >> >> endobj 4296 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [358.058 617.153 374.994 628.057] /A << /S /GoTo /D (page.116) >> >> endobj 4297 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.051 605.198 361.007 616.102] /A << /S /GoTo /D (page.49) >> >> endobj 4298 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.995 605.198 375.95 616.102] /A << /S /GoTo /D (page.52) >> >> endobj 4299 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.939 605.198 390.894 616.102] /A << /S /GoTo /D (page.55) >> >> endobj 4300 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.883 605.198 405.838 616.102] /A << /S /GoTo /D (page.58) >> >> endobj 4301 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [408.827 605.198 425.764 616.102] /A << /S /GoTo /D (page.115) >> >> endobj 4302 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.767 593.96 369.704 604.147] /A << /S /GoTo /D (page.101) >> >> endobj 4303 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [372.693 593.96 389.629 604.147] /A << /S /GoTo /D (page.146) >> >> endobj 4304 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [340.593 582.005 352.548 592.192] /A << /S /GoTo /D (page.90) >> >> endobj 4305 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [355.537 582.005 367.492 592.192] /A << /S /GoTo /D (page.92) >> >> endobj 4306 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [370.481 582.005 382.436 592.192] /A << /S /GoTo /D (page.96) >> >> endobj 4307 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [385.425 582.005 397.38 592.192] /A << /S /GoTo /D (page.99) >> >> endobj 4308 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [400.369 582.005 417.306 592.192] /A << /S /GoTo /D (page.129) >> >> endobj 4309 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [420.294 582.005 437.231 592.192] /A << /S /GoTo /D (page.131) >> >> endobj 4310 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [325.261 570.05 342.197 580.237] /A << /S /GoTo /D (page.155) >> >> endobj 4311 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.269 558.095 377.205 568.281] /A << /S /GoTo /D (page.142) >> >> endobj 4312 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.194 558.095 397.131 568.281] /A << /S /GoTo /D (page.143) >> >> endobj 4313 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.842 545.422 381.778 556.326] /A << /S /GoTo /D (page.127) >> >> endobj 4314 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [337.425 534.184 349.38 544.371] /A << /S /GoTo /D (page.92) >> >> endobj 4315 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.369 534.184 369.305 544.371] /A << /S /GoTo /D (page.111) >> >> endobj 4316 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [372.294 534.184 389.231 544.371] /A << /S /GoTo /D (page.130) >> >> endobj 4317 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [323.198 512.267 340.135 522.453] /A << /S /GoTo /D (page.184) >> >> endobj 4318 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.303 499.594 413.24 510.498] /A << /S /GoTo /D (page.170) >> >> endobj 4319 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [416.229 499.594 433.165 510.498] /A << /S /GoTo /D (page.192) >> >> endobj 4320 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [400.378 487.639 417.315 498.543] /A << /S /GoTo /D (page.170) >> >> endobj 4321 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [420.304 487.639 437.24 498.543] /A << /S /GoTo /D (page.192) >> >> endobj 4322 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [337.026 476.401 353.963 486.588] /A << /S /GoTo /D (page.197) >> >> endobj 4323 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [341.898 464.446 353.853 474.633] /A << /S /GoTo /D (page.47) >> >> endobj 4324 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.842 464.446 368.797 474.633] /A << /S /GoTo /D (page.48) >> >> endobj 4325 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.786 464.446 383.741 474.633] /A << /S /GoTo /D (page.52) >> >> endobj 4326 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [386.73 464.446 398.685 474.633] /A << /S /GoTo /D (page.58) >> >> endobj 4327 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [387.626 452.491 404.563 462.677] /A << /S /GoTo /D (page.181) >> >> endobj 4328 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.831 440.536 360.767 450.722] /A << /S /GoTo /D (page.181) >> >> endobj 4329 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [324.294 417.9 341.231 428.804] /A << /S /GoTo /D (page.149) >> >> endobj 4330 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [325.41 405.945 342.347 416.849] /A << /S /GoTo /D (page.149) >> >> endobj 4331 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [387.188 393.99 399.143 404.894] /A << /S /GoTo /D (page.24) >> >> endobj 4332 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [402.132 393.99 419.068 404.894] /A << /S /GoTo /D (page.240) >> >> endobj 4333 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.711 382.035 363.666 392.939] /A << /S /GoTo /D (page.47) >> >> endobj 4334 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.608 370.08 372.563 380.984] /A << /S /GoTo /D (page.57) >> >> endobj 4335 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.014 358.125 362.969 369.029] /A << /S /GoTo /D (page.41) >> >> endobj 4336 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.958 358.125 377.913 369.029] /A << /S /GoTo /D (page.42) >> >> endobj 4337 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.201 346.169 361.156 357.073] /A << /S /GoTo /D (page.47) >> >> endobj 4338 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.338 334.214 383.293 345.118] /A << /S /GoTo /D (page.24) >> >> endobj 4339 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.902 322.259 397.838 333.163] /A << /S /GoTo /D (page.102) >> >> endobj 4340 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [400.827 322.259 417.764 333.163] /A << /S /GoTo /D (page.205) >> >> endobj 4341 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [420.752 322.259 437.689 333.163] /A << /S /GoTo /D (page.212) >> >> endobj 4342 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.641 310.304 400.578 321.208] /A << /S /GoTo /D (page.102) >> >> endobj 4343 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [403.567 310.304 420.503 321.208] /A << /S /GoTo /D (page.205) >> >> endobj 4344 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [423.492 310.304 440.429 321.208] /A << /S /GoTo /D (page.212) >> >> endobj 4345 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [347.537 298.349 364.473 309.253] /A << /S /GoTo /D (page.140) >> >> endobj 4346 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.462 298.349 384.399 309.253] /A << /S /GoTo /D (page.143) >> >> endobj 4347 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.921 286.394 347.876 297.298] /A << /S /GoTo /D (page.33) >> >> endobj 4348 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [333.709 274.438 345.664 285.342] /A << /S /GoTo /D (page.28) >> >> endobj 4349 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.653 274.438 360.608 285.342] /A << /S /GoTo /D (page.45) >> >> endobj 4350 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.597 274.438 375.552 285.342] /A << /S /GoTo /D (page.47) >> >> endobj 4351 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.541 274.438 390.496 285.342] /A << /S /GoTo /D (page.55) >> >> endobj 4352 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.485 274.438 405.44 285.342] /A << /S /GoTo /D (page.57) >> >> endobj 4353 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.123 262.483 387.079 273.387] /A << /S /GoTo /D (page.49) >> >> endobj 4354 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [390.067 262.483 402.023 273.387] /A << /S /GoTo /D (page.55) >> >> endobj 4355 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [391.272 250.528 403.228 261.432] /A << /S /GoTo /D (page.55) >> >> endobj 4356 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.451 238.573 390.406 249.477] /A << /S /GoTo /D (page.47) >> >> endobj 4357 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.395 238.573 405.35 249.477] /A << /S /GoTo /D (page.49) >> >> endobj 4358 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [408.339 238.573 420.294 249.477] /A << /S /GoTo /D (page.55) >> >> endobj 4359 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.6 226.618 406.555 237.522] /A << /S /GoTo /D (page.47) >> >> endobj 4360 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [409.544 226.618 421.499 237.522] /A << /S /GoTo /D (page.48) >> >> endobj 4361 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [359.074 214.663 371.029 225.567] /A << /S /GoTo /D (page.49) >> >> endobj 4362 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.018 214.663 385.973 225.567] /A << /S /GoTo /D (page.55) >> >> endobj 4363 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.649 193.462 361.604 203.649] /A << /S /GoTo /D (page.48) >> >> endobj 4364 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.593 193.462 376.548 203.649] /A << /S /GoTo /D (page.49) >> >> endobj 4365 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.537 193.462 391.492 203.649] /A << /S /GoTo /D (page.52) >> >> endobj 4366 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.481 193.462 406.436 203.649] /A << /S /GoTo /D (page.55) >> >> endobj 4367 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [409.425 193.462 421.38 203.649] /A << /S /GoTo /D (page.57) >> >> endobj 4368 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.921 181.507 352.857 191.694] /A << /S /GoTo /D (page.214) >> >> endobj 4369 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [327.064 159.589 339.019 169.776] /A << /S /GoTo /D (page.22) >> >> endobj 4370 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [342.008 159.589 358.944 169.776] /A << /S /GoTo /D (page.104) >> >> endobj 4371 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [342.715 147.634 359.652 157.821] /A << /S /GoTo /D (page.194) >> >> endobj 4372 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.815 134.961 346.77 145.865] /A << /S /GoTo /D (page.75) >> >> endobj 4373 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.014 123.006 362.969 133.91] /A << /S /GoTo /D (page.90) >> >> endobj 4374 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.958 123.006 377.913 133.91] /A << /S /GoTo /D (page.94) >> >> endobj 4375 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.902 123.006 397.838 133.91] /A << /S /GoTo /D (page.131) >> >> endobj 4376 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [326.516 111.768 338.471 121.955] /A << /S /GoTo /D (page.25) >> >> endobj 4377 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [341.46 111.768 358.396 121.955] /A << /S /GoTo /D (page.240) >> >> endobj 4378 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [361.385 111.768 378.322 121.955] /A << /S /GoTo /D (page.244) >> >> endobj 4379 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [336.478 99.813 353.415 110] /A << /S /GoTo /D (page.155) >> >> endobj 4380 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.404 99.813 373.34 110] /A << /S /GoTo /D (page.156) >> >> endobj 4381 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [354.73 87.858 366.685 98.045] /A << /S /GoTo /D (page.88) >> >> endobj 4382 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [369.674 87.858 381.629 98.045] /A << /S /GoTo /D (page.91) >> >> endobj 4383 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [384.618 87.858 396.573 98.045] /A << /S /GoTo /D (page.96) >> >> endobj 4384 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.562 87.858 416.498 98.045] /A << /S /GoTo /D (page.118) >> >> endobj 4385 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [419.487 87.858 436.423 98.045] /A << /S /GoTo /D (page.126) >> >> endobj 4386 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [439.412 87.858 456.349 98.045] /A << /S /GoTo /D (page.156) >> >> endobj 4387 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [324.304 75.903 336.259 86.09] /A << /S /GoTo /D (page.97) >> >> endobj 4388 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [339.248 75.903 351.203 86.09] /A << /S /GoTo /D (page.99) >> >> endobj 4389 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [354.192 75.903 371.129 86.09] /A << /S /GoTo /D (page.120) >> >> endobj 4390 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.117 75.903 391.054 86.09] /A << /S /GoTo /D (page.204) >> >> endobj 4391 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [323.756 63.948 340.693 74.134] /A << /S /GoTo /D (page.103) >> >> endobj 4392 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.681 63.948 360.618 74.134] /A << /S /GoTo /D (page.123) >> >> endobj 4393 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.607 63.948 380.543 74.134] /A << /S /GoTo /D (page.124) >> >> endobj 4394 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.532 63.948 400.469 74.134] /A << /S /GoTo /D (page.126) >> >> endobj 4395 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [352.827 51.993 364.782 62.179] /A << /S /GoTo /D (page.90) >> >> endobj 4396 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.771 51.993 379.726 62.179] /A << /S /GoTo /D (page.95) >> >> endobj 4397 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.715 51.993 394.67 62.179] /A << /S /GoTo /D (page.99) >> >> endobj 4398 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.659 51.993 414.595 62.179] /A << /S /GoTo /D (page.133) >> >> endobj 4399 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.584 51.993 434.52 62.179] /A << /S /GoTo /D (page.134) >> >> endobj 4408 0 obj << /D [4406 0 R /XYZ 89 721 null] >> endobj 4405 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R /F70 1879 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4606 0 obj << /Length 1456 /Filter /FlateDecode >> stream xÚÝZÝsÚ8Ï_áGñ|k0¶®Z§íΟö߃'>[ûΫ?òy…²øŒq¯þh¬€-çþ‡Õ"w…–¨ò4)J‘Œäo‹´úœXùÔZþéUK¯æ“õ؉åPºù+b*)d^ ÑÆU ’J)zZ†K ÍŒ6ˆ ©2O+øôb>ʼ?±ÈÏTQÊDæ¶G ÜPR§—=€OðÕ†ŽˆãÔf~ë§CXrW"²¹à cüÙ5x›ŠÐŒ8vA„¶ô —ê¶>1„DPX…BÃ%Ê·q.lZ³Í}ˆQj }èvÞAlž0Üu6¿«Tˆ`­½"xšf°¤‹¡yFZª«uÊX&ÓòÜž@{H±\˜M}ä*`ýˆ¢‰}(‹Uò]%SH®O°L}½w©d~&Ìàþâ€ò±Gr½q¥U÷Lo[géè{{i_Ê ™¾†G aظ¸¯?åt:5:cê ̆qt¹„^ÁÐuŽGMTspч+ÌLÀAñ9¨ zù¤l©¹MÃÖTn x–N?Ùœ´”\cF†F¹žäKÄsØGCmºž •€¶¤ï3qãÔÅï Âáh›ŒBPòXÍ0ÊG¾Öïqn *¨g±Ö8Ž~?mJZ"O 2è öW\gr–æê¼>Ð4}²µd£ãpŠ®áI´ýåàDõWÌó“cì½é¡ëÂç*¥{RÉ[EJr–Ʊ“É\¥ ­rt.(¿1¯°ÞÔãÓ1˜Õ9Ö!lÑôFÎk’ÎzNuŽÓ¤Ì+0J®<ÔZòù<.ÕaYæjh3Òš—Ý è †‘(ÊβÌJÀ dóZ—ÕÔ7£ð>ÍŠÆ£?$}v/vy€ȃæ§pc¦9Åù†ðž­®ùm?ÿtüBϹ¸í<õ-7-Fù¾R‹3ŸûÞ ø¯ Øi×¾}hSJ[;r[‡G¶ë·ûH$Ó÷Ž—èï/û;ðZX0xÛ}ß@|׎X¥Kÿsý/{m0£i¼€¸Û”ª|]Õ?úÞÿF½ê2åÓh©^"f×2¼Ì­[óÐýÅ¿VªÈ„A7]R2Öð0¦â §ŒPÄ’t<C¯ÞÌ“´T“1q^bú ¸¨$!„D©ÒÄ^¬éËÜ ™‡n¸üü Ðv`¦õÐ5¿§7’åÐït&¦ÝÛ |èç‰;ÂÏä¨Ìç³&ÐëÈ–àéð›c=l½êc£ Ðç¾<æ-@:KTíl“&ÅÖ¾õ„ðËÞÑ&*€ÒÕ {X{;º»e’ÛÀðæ0¦Íä™(K™'ÈLÒ|n¦@íhÔò`„€¨d”z—Ê èé§?çLeÍ\Ø2=Îq±8Þl‚†‡¸Ýj§ÚmQ (Â#áêLAê»&Ýtš‚Û¢·àº‰˜Æcg²èÀÊÔhTó\{¯¡æõDi,3ƒ9°qu“k¼Ã-åþ+ uCð v0FEûå¾ O§¼Î¥N–¦±3J“ ˆ‹vOêâ™êN¾“¯C9Isù5 DMxð7ð…#EßDÝø Vèk¸¬ ¥#ëx3ª\UQ(|åu}V*Y4žƒ-[ 莸ÁÓ:}é·±*®úóa1ÊÕP"ûÈ›{;_µ¹€P\ãÖ®Vç2¿=ŽEQüÏrôÖ½ û‹=$2`üP’_‹$‘±Á+\ØÊ÷¢™§Ž(|®+u'òñ„ºËXaty%ú‡Æð+EQv q}Ž[)­ïôæó™@?jíµû;ïnþv{ÿ¡Y¢8 endstream endobj 4605 0 obj << /Type /Page /Contents 4606 0 R /Resources 4604 0 R /MediaBox [0 0 612 792] /Parent 4608 0 R /Annots [ 4400 0 R 4401 0 R 4402 0 R 4403 0 R 4404 0 R 4409 0 R 4410 0 R 4411 0 R 4412 0 R 4413 0 R 4414 0 R 4415 0 R 4416 0 R 4417 0 R 4418 0 R 4419 0 R 4420 0 R 4421 0 R 4422 0 R 4423 0 R 4424 0 R 4425 0 R 4426 0 R 4427 0 R 4428 0 R 4429 0 R 4430 0 R 4431 0 R 4432 0 R 4433 0 R 4434 0 R 4435 0 R 4436 0 R 4437 0 R 4438 0 R 4439 0 R 4440 0 R 4441 0 R 4442 0 R 4443 0 R 4444 0 R 4445 0 R 4446 0 R 4447 0 R 4448 0 R 4449 0 R 4450 0 R 4451 0 R 4452 0 R 4453 0 R 4454 0 R 4455 0 R 4456 0 R 4457 0 R 4458 0 R 4459 0 R 4460 0 R 4461 0 R 4462 0 R 4463 0 R 4464 0 R 4465 0 R 4466 0 R 4467 0 R 4468 0 R 4469 0 R 4470 0 R 4471 0 R 4472 0 R 4473 0 R 4474 0 R 4475 0 R 4476 0 R 4477 0 R 4478 0 R 4479 0 R 4480 0 R 4481 0 R 4482 0 R 4483 0 R 4484 0 R 4485 0 R 4486 0 R 4487 0 R 4488 0 R 4489 0 R 4490 0 R 4491 0 R 4492 0 R 4493 0 R 4494 0 R 4495 0 R 4496 0 R 4497 0 R 4498 0 R 4499 0 R 4500 0 R 4501 0 R 4502 0 R 4503 0 R 4504 0 R 4505 0 R 4506 0 R 4507 0 R 4508 0 R 4509 0 R 4510 0 R 4511 0 R 4512 0 R 4513 0 R 4514 0 R 4515 0 R 4516 0 R 4517 0 R 4518 0 R 4519 0 R 4520 0 R 4521 0 R 4522 0 R 4523 0 R 4524 0 R 4525 0 R 4526 0 R 4527 0 R 4528 0 R 4529 0 R 4530 0 R 4531 0 R 4532 0 R 4533 0 R 4534 0 R 4535 0 R 4536 0 R 4537 0 R 4538 0 R 4539 0 R 4540 0 R 4541 0 R 4542 0 R 4543 0 R 4544 0 R 4545 0 R 4546 0 R 4547 0 R 4548 0 R 4549 0 R 4550 0 R 4551 0 R 4552 0 R 4553 0 R 4554 0 R 4555 0 R 4556 0 R 4557 0 R 4558 0 R 4559 0 R 4560 0 R 4561 0 R 4562 0 R 4563 0 R 4564 0 R 4565 0 R 4566 0 R 4567 0 R 4568 0 R 4569 0 R 4570 0 R 4571 0 R 4572 0 R 4573 0 R 4574 0 R 4575 0 R 4576 0 R 4577 0 R 4578 0 R 4579 0 R 4580 0 R 4581 0 R 4582 0 R 4583 0 R 4584 0 R 4585 0 R 4586 0 R 4587 0 R 4588 0 R 4589 0 R 4590 0 R 4591 0 R 4592 0 R 4593 0 R 4594 0 R 4595 0 R 4596 0 R 4597 0 R 4598 0 R 4599 0 R 4600 0 R ] >> endobj 4400 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [141.018 677.646 157.954 687.833] /A << /S /GoTo /D (page.142) >> >> endobj 4401 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.122 665.691 128.077 675.878] /A << /S /GoTo /D (page.92) >> >> endobj 4402 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.066 665.691 148.002 675.878] /A << /S /GoTo /D (page.111) >> >> endobj 4403 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.991 665.691 167.927 675.878] /A << /S /GoTo /D (page.112) >> >> endobj 4404 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.916 665.691 187.853 675.878] /A << /S /GoTo /D (page.130) >> >> endobj 4409 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.632 653.736 143.569 663.923] /A << /S /GoTo /D (page.101) >> >> endobj 4410 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.557 653.736 163.494 663.923] /A << /S /GoTo /D (page.124) >> >> endobj 4411 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.095 641.781 199.05 651.968] /A << /S /GoTo /D (page.82) >> >> endobj 4412 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [111.141 629.826 123.096 640.012] /A << /S /GoTo /D (page.27) >> >> endobj 4413 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.24 617.871 147.195 628.057] /A << /S /GoTo /D (page.24) >> >> endobj 4414 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.184 617.871 162.139 628.057] /A << /S /GoTo /D (page.90) >> >> endobj 4415 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [165.128 617.871 177.083 628.057] /A << /S /GoTo /D (page.92) >> >> endobj 4416 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [180.072 617.871 192.027 628.057] /A << /S /GoTo /D (page.94) >> >> endobj 4417 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [195.016 617.871 206.971 628.057] /A << /S /GoTo /D (page.96) >> >> endobj 4418 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [209.96 617.871 221.915 628.057] /A << /S /GoTo /D (page.99) >> >> endobj 4419 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [224.903 617.871 241.84 628.057] /A << /S /GoTo /D (page.129) >> >> endobj 4420 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [244.829 617.871 261.765 628.057] /A << /S /GoTo /D (page.131) >> >> endobj 4421 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [104.256 605.915 121.193 616.102] /A << /S /GoTo /D (page.179) >> >> endobj 4422 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [115.873 583.28 127.828 594.184] /A << /S /GoTo /D (page.78) >> >> endobj 4423 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.68 572.042 133.616 582.229] /A << /S /GoTo /D (page.182) >> >> endobj 4424 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [109.487 550.125 126.423 560.311] /A << /S /GoTo /D (page.102) >> >> endobj 4425 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.412 550.125 146.348 560.311] /A << /S /GoTo /D (page.205) >> >> endobj 4426 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [149.337 550.125 166.274 560.311] /A << /S /GoTo /D (page.207) >> >> endobj 4427 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [113.352 528.207 130.289 538.393] /A << /S /GoTo /D (page.197) >> >> endobj 4428 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.277 528.207 150.214 538.393] /A << /S /GoTo /D (page.203) >> >> endobj 4429 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [118.891 515.534 135.828 526.438] /A << /S /GoTo /D (page.107) >> >> endobj 4430 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [112.954 504.296 129.89 514.483] /A << /S /GoTo /D (page.194) >> >> endobj 4431 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [132.879 504.296 149.815 514.483] /A << /S /GoTo /D (page.196) >> >> endobj 4432 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.804 504.296 169.741 514.483] /A << /S /GoTo /D (page.202) >> >> endobj 4433 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [122.219 491.624 139.155 502.528] /A << /S /GoTo /D (page.150) >> >> endobj 4434 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.144 491.624 159.081 502.528] /A << /S /GoTo /D (page.151) >> >> endobj 4435 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [117.786 480.386 134.722 490.573] /A << /S /GoTo /D (page.149) >> >> endobj 4436 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [122.916 468.431 134.871 478.618] /A << /S /GoTo /D (page.82) >> >> endobj 4437 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.86 468.431 149.815 478.618] /A << /S /GoTo /D (page.84) >> >> endobj 4438 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.804 468.431 164.759 478.618] /A << /S /GoTo /D (page.86) >> >> endobj 4439 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [113.352 456.476 130.289 466.662] /A << /S /GoTo /D (page.157) >> >> endobj 4440 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.423 444.521 159.359 454.707] /A << /S /GoTo /D (page.102) >> >> endobj 4441 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.348 444.521 179.285 454.707] /A << /S /GoTo /D (page.205) >> >> endobj 4442 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [182.274 444.521 199.21 454.707] /A << /S /GoTo /D (page.209) >> >> endobj 4443 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.19 431.848 139.146 442.752] /A << /S /GoTo /D (page.65) >> >> endobj 4444 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.041 419.893 135.977 430.797] /A << /S /GoTo /D (page.147) >> >> endobj 4445 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [124.431 407.938 136.386 418.842] /A << /S /GoTo /D (page.26) >> >> endobj 4446 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [139.375 407.938 156.311 418.842] /A << /S /GoTo /D (page.116) >> >> endobj 4447 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [159.3 407.938 176.236 418.842] /A << /S /GoTo /D (page.121) >> >> endobj 4448 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [179.225 407.938 196.162 418.842] /A << /S /GoTo /D (page.141) >> >> endobj 4449 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.717 395.983 163.653 406.887] /A << /S /GoTo /D (page.193) >> >> endobj 4450 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.904 384.027 161.84 394.931] /A << /S /GoTo /D (page.193) >> >> endobj 4451 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.153 372.072 154.089 382.976] /A << /S /GoTo /D (page.193) >> >> endobj 4452 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.253 360.117 167.19 371.021] /A << /S /GoTo /D (page.193) >> >> endobj 4453 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.109 348.162 155.046 359.066] /A << /S /GoTo /D (page.116) >> >> endobj 4454 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [118.084 336.924 135.021 347.111] /A << /S /GoTo /D (page.108) >> >> endobj 4455 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [113.91 315.006 130.847 325.193] /A << /S /GoTo /D (page.122) >> >> endobj 4456 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.143 303.051 154.079 313.238] /A << /S /GoTo /D (page.161) >> >> endobj 4457 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.068 303.051 174.004 313.238] /A << /S /GoTo /D (page.198) >> >> endobj 4458 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.259 291.096 155.195 301.283] /A << /S /GoTo /D (page.195) >> >> endobj 4459 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.611 278.424 154.548 289.327] /A << /S /GoTo /D (page.195) >> >> endobj 4460 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.788 267.186 152.724 277.372] /A << /S /GoTo /D (page.198) >> >> endobj 4461 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.006 254.513 163.942 265.417] /A << /S /GoTo /D (page.161) >> >> endobj 4462 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.931 254.513 183.868 265.417] /A << /S /GoTo /D (page.199) >> >> endobj 4463 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [138.806 243.275 155.743 253.462] /A << /S /GoTo /D (page.180) >> >> endobj 4464 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.732 243.275 175.668 253.462] /A << /S /GoTo /D (page.198) >> >> endobj 4465 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.543 230.603 138.498 241.507] /A << /S /GoTo /D (page.17) >> >> endobj 4466 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [141.487 230.603 153.442 241.507] /A << /S /GoTo /D (page.19) >> >> endobj 4467 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [156.431 230.603 173.367 241.507] /A << /S /GoTo /D (page.109) >> >> endobj 4468 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [176.356 230.603 193.292 241.507] /A << /S /GoTo /D (page.112) >> >> endobj 4469 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [196.281 230.603 213.218 241.507] /A << /S /GoTo /D (page.114) >> >> endobj 4470 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [115.026 219.365 131.962 229.552] /A << /S /GoTo /D (page.142) >> >> endobj 4471 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.951 219.365 151.888 229.552] /A << /S /GoTo /D (page.144) >> >> endobj 4472 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.876 219.365 171.813 229.552] /A << /S /GoTo /D (page.149) >> >> endobj 4473 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.489 207.41 152.425 217.596] /A << /S /GoTo /D (page.161) >> >> endobj 4474 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.414 207.41 172.351 217.596] /A << /S /GoTo /D (page.198) >> >> endobj 4475 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.078 194.737 174.014 205.641] /A << /S /GoTo /D (page.166) >> >> endobj 4476 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.003 194.737 193.939 205.641] /A << /S /GoTo /D (page.192) >> >> endobj 4477 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.134 183.499 151.07 193.686] /A << /S /GoTo /D (page.198) >> >> endobj 4478 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.352 170.827 162.288 181.731] /A << /S /GoTo /D (page.161) >> >> endobj 4479 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [165.277 170.827 182.214 181.731] /A << /S /GoTo /D (page.199) >> >> endobj 4480 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [118.891 159.589 130.847 169.776] /A << /S /GoTo /D (page.69) >> >> endobj 4481 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.835 159.589 145.79 169.776] /A << /S /GoTo /D (page.75) >> >> endobj 4482 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.779 159.589 160.734 169.776] /A << /S /GoTo /D (page.82) >> >> endobj 4483 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.922 147.634 199.877 157.821] /A << /S /GoTo /D (page.68) >> >> endobj 4484 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.907 135.679 163.862 145.865] /A << /S /GoTo /D (page.90) >> >> endobj 4485 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.851 135.679 178.806 145.865] /A << /S /GoTo /D (page.93) >> >> endobj 4486 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.716 123.724 171.653 133.91] /A << /S /GoTo /D (page.178) >> >> endobj 4487 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.642 123.724 191.578 133.91] /A << /S /GoTo /D (page.215) >> >> endobj 4488 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.654 111.051 169.591 121.955] /A << /S /GoTo /D (page.180) >> >> endobj 4489 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [172.579 111.051 189.516 121.955] /A << /S /GoTo /D (page.215) >> >> endobj 4490 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.249 99.096 155.205 110] /A << /S /GoTo /D (page.30) >> >> endobj 4491 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.193 99.096 175.13 110] /A << /S /GoTo /D (page.178) >> >> endobj 4492 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.691 87.858 159.628 98.045] /A << /S /GoTo /D (page.180) >> >> endobj 4493 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.617 87.858 179.553 98.045] /A << /S /GoTo /D (page.215) >> >> endobj 4494 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [149.884 75.903 166.821 86.09] /A << /S /GoTo /D (page.180) >> >> endobj 4495 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.81 75.903 186.746 86.09] /A << /S /GoTo /D (page.215) >> >> endobj 4496 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.68 63.948 128.635 74.134] /A << /S /GoTo /D (page.68) >> >> endobj 4497 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.642 51.275 138.598 62.179] /A << /S /GoTo /D (page.27) >> >> endobj 4498 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.004 677.303 415.94 687.833] /A << /S /GoTo /D (page.220) >> >> endobj 4499 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.928 665.348 390.864 675.878] /A << /S /GoTo /D (page.220) >> >> endobj 4500 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [393.853 665.348 410.79 675.878] /A << /S /GoTo /D (page.255) >> >> endobj 4501 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [401.883 653.392 418.819 663.923] /A << /S /GoTo /D (page.190) >> >> endobj 4502 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [421.808 653.392 438.745 663.923] /A << /S /GoTo /D (page.220) >> >> endobj 4503 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [441.733 653.392 458.67 663.923] /A << /S /GoTo /D (page.253) >> >> endobj 4504 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [461.659 653.392 478.595 663.923] /A << /S /GoTo /D (page.255) >> >> endobj 4505 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.117 641.437 391.054 651.968] /A << /S /GoTo /D (page.190) >> >> endobj 4506 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.042 641.437 410.979 651.968] /A << /S /GoTo /D (page.220) >> >> endobj 4507 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [413.968 641.437 430.904 651.968] /A << /S /GoTo /D (page.253) >> >> endobj 4508 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [433.893 641.437 450.83 651.968] /A << /S /GoTo /D (page.255) >> >> endobj 4509 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [332.045 620.262 344 630.448] /A << /S /GoTo /D (page.23) >> >> endobj 4510 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [346.989 620.262 358.944 630.448] /A << /S /GoTo /D (page.25) >> >> endobj 4511 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [361.933 620.262 373.888 630.448] /A << /S /GoTo /D (page.90) >> >> endobj 4512 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [376.877 620.262 388.832 630.448] /A << /S /GoTo /D (page.91) >> >> endobj 4513 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [354.172 607.589 371.108 618.493] /A << /S /GoTo /D (page.104) >> >> endobj 4514 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [374.097 607.589 391.034 618.493] /A << /S /GoTo /D (page.122) >> >> endobj 4515 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.023 607.589 410.959 618.493] /A << /S /GoTo /D (page.124) >> >> endobj 4516 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [340.354 595.634 352.309 606.538] /A << /S /GoTo /D (page.88) >> >> endobj 4517 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.392 584.396 347.328 594.583] /A << /S /GoTo /D (page.185) >> >> endobj 4518 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.211 572.441 366.147 582.628] /A << /S /GoTo /D (page.253) >> >> endobj 4519 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [369.136 572.441 386.073 582.628] /A << /S /GoTo /D (page.254) >> >> endobj 4520 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [390.435 560.486 402.391 570.672] /A << /S /GoTo /D (page.29) >> >> endobj 4521 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [405.379 560.486 417.335 570.672] /A << /S /GoTo /D (page.36) >> >> endobj 4522 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [420.323 560.486 437.26 570.672] /A << /S /GoTo /D (page.253) >> >> endobj 4523 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [440.249 560.486 457.185 570.672] /A << /S /GoTo /D (page.254) >> >> endobj 4524 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [353.624 548.531 370.561 558.717] /A << /S /GoTo /D (page.146) >> >> endobj 4525 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.549 548.531 390.486 558.717] /A << /S /GoTo /D (page.148) >> >> endobj 4526 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.085 535.858 408.04 546.762] /A << /S /GoTo /D (page.75) >> >> endobj 4527 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [411.586 524.62 423.541 534.807] /A << /S /GoTo /D (page.75) >> >> endobj 4528 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [409.375 511.948 421.33 522.852] /A << /S /GoTo /D (page.75) >> >> endobj 4529 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.095 490.428 360.05 501.332] /A << /S /GoTo /D (page.48) >> >> endobj 4530 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.039 490.428 374.994 501.332] /A << /S /GoTo /D (page.55) >> >> endobj 4531 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.983 490.428 389.938 501.332] /A << /S /GoTo /D (page.57) >> >> endobj 4532 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [333.709 479.191 345.664 489.377] /A << /S /GoTo /D (page.22) >> >> endobj 4533 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.314 466.518 368.269 477.422] /A << /S /GoTo /D (page.29) >> >> endobj 4534 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.258 466.518 383.213 477.422] /A << /S /GoTo /D (page.36) >> >> endobj 4535 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.432 455.28 368.369 465.467] /A << /S /GoTo /D (page.150) >> >> endobj 4536 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.358 455.28 388.294 465.467] /A << /S /GoTo /D (page.152) >> >> endobj 4537 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.095 442.608 360.05 453.512] /A << /S /GoTo /D (page.22) >> >> endobj 4538 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.039 442.608 374.994 453.512] /A << /S /GoTo /D (page.23) >> >> endobj 4539 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.983 442.608 389.938 453.512] /A << /S /GoTo /D (page.90) >> >> endobj 4540 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.949 431.37 342.905 441.557] /A << /S /GoTo /D (page.22) >> >> endobj 4541 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [338.132 409.133 350.087 420.037] /A << /S /GoTo /D (page.88) >> >> endobj 4542 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [353.076 409.133 365.031 420.037] /A << /S /GoTo /D (page.90) >> >> endobj 4543 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [368.02 409.133 384.957 420.037] /A << /S /GoTo /D (page.155) >> >> endobj 4544 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.921 397.178 352.857 408.082] /A << /S /GoTo /D (page.200) >> >> endobj 4545 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.114 385.223 355.069 396.127] /A << /S /GoTo /D (page.37) >> >> endobj 4546 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [328.18 373.268 340.135 384.172] /A << /S /GoTo /D (page.25) >> >> endobj 4547 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.124 373.268 360.06 384.172] /A << /S /GoTo /D (page.240) >> >> endobj 4548 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [327.622 361.313 339.577 372.217] /A << /S /GoTo /D (page.23) >> >> endobj 4549 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [342.566 361.313 354.521 372.217] /A << /S /GoTo /D (page.24) >> >> endobj 4550 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [357.51 361.313 369.465 372.217] /A << /S /GoTo /D (page.26) >> >> endobj 4551 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [372.454 361.313 384.409 372.217] /A << /S /GoTo /D (page.34) >> >> endobj 4552 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [387.398 361.313 399.353 372.217] /A << /S /GoTo /D (page.60) >> >> endobj 4553 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [402.342 361.313 419.278 372.217] /A << /S /GoTo /D (page.157) >> >> endobj 4554 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [422.267 361.313 439.203 372.217] /A << /S /GoTo /D (page.202) >> >> endobj 4555 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [370.082 349.357 382.037 360.261] /A << /S /GoTo /D (page.42) >> >> endobj 4556 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [385.584 337.402 397.539 348.306] /A << /S /GoTo /D (page.43) >> >> endobj 4557 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.949 325.447 342.905 336.351] /A << /S /GoTo /D (page.15) >> >> endobj 4558 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [368.07 313.492 385.006 324.396] /A << /S /GoTo /D (page.192) >> >> endobj 4559 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [370.79 301.537 387.726 312.441] /A << /S /GoTo /D (page.192) >> >> endobj 4560 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.895 290.299 380.832 300.486] /A << /S /GoTo /D (page.102) >> >> endobj 4561 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.821 290.299 400.757 300.486] /A << /S /GoTo /D (page.165) >> >> endobj 4562 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [403.746 290.299 420.682 300.486] /A << /S /GoTo /D (page.205) >> >> endobj 4563 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [423.671 290.299 440.608 300.486] /A << /S /GoTo /D (page.208) >> >> endobj 4564 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [338.7 277.626 350.655 288.53] /A << /S /GoTo /D (page.26) >> >> endobj 4565 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [353.644 277.626 365.599 288.53] /A << /S /GoTo /D (page.34) >> >> endobj 4566 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [368.588 277.626 385.525 288.53] /A << /S /GoTo /D (page.165) >> >> endobj 4567 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.841 265.671 429.778 276.575] /A << /S /GoTo /D (page.167) >> >> endobj 4568 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [432.767 265.671 449.703 276.575] /A << /S /GoTo /D (page.213) >> >> endobj 4569 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [410.629 253.716 427.566 264.62] /A << /S /GoTo /D (page.167) >> >> endobj 4570 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [430.555 253.716 447.491 264.62] /A << /S /GoTo /D (page.213) >> >> endobj 4571 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.088 241.761 396.025 252.665] /A << /S /GoTo /D (page.169) >> >> endobj 4572 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.014 241.761 415.95 252.665] /A << /S /GoTo /D (page.213) >> >> endobj 4573 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [326.516 229.806 343.453 240.71] /A << /S /GoTo /D (page.153) >> >> endobj 4574 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [346.441 229.806 363.378 240.71] /A << /S /GoTo /D (page.185) >> >> endobj 4575 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [366.367 229.806 383.303 240.71] /A << /S /GoTo /D (page.186) >> >> endobj 4576 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.188 217.851 388.125 228.755] /A << /S /GoTo /D (page.115) >> >> endobj 4577 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [350.306 205.895 362.262 216.799] /A << /S /GoTo /D (page.23) >> >> endobj 4578 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.25 205.895 377.206 216.799] /A << /S /GoTo /D (page.27) >> >> endobj 4579 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [380.194 205.895 392.15 216.799] /A << /S /GoTo /D (page.91) >> >> endobj 4580 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [395.138 205.895 407.093 216.799] /A << /S /GoTo /D (page.93) >> >> endobj 4581 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [410.082 205.895 427.019 216.799] /A << /S /GoTo /D (page.138) >> >> endobj 4582 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.426 194.658 394.381 204.844] /A << /S /GoTo /D (page.30) >> >> endobj 4583 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [325.968 181.985 337.923 192.889] /A << /S /GoTo /D (page.34) >> >> endobj 4584 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [329.286 170.03 341.241 180.934] /A << /S /GoTo /D (page.34) >> >> endobj 4585 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [356.951 148.511 373.888 159.415] /A << /S /GoTo /D (page.102) >> >> endobj 4586 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [376.877 148.511 393.813 159.415] /A << /S /GoTo /D (page.205) >> >> endobj 4587 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.802 148.511 413.738 159.415] /A << /S /GoTo /D (page.206) >> >> endobj 4588 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.328 136.556 380.264 147.459] /A << /S /GoTo /D (page.102) >> >> endobj 4589 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [383.253 136.556 400.189 147.459] /A << /S /GoTo /D (page.205) >> >> endobj 4590 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [403.178 136.556 420.115 147.459] /A << /S /GoTo /D (page.206) >> >> endobj 4591 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [408.817 124.6 425.753 135.504] /A << /S /GoTo /D (page.206) >> >> endobj 4592 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.829 112.645 395.766 123.549] /A << /S /GoTo /D (page.205) >> >> endobj 4593 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [398.755 112.645 415.691 123.549] /A << /S /GoTo /D (page.207) >> >> endobj 4594 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [419.536 100.69 436.473 111.594] /A << /S /GoTo /D (page.207) >> >> endobj 4595 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.296 88.735 431.233 99.639] /A << /S /GoTo /D (page.205) >> >> endobj 4596 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.222 88.735 451.158 99.639] /A << /S /GoTo /D (page.207) >> >> endobj 4597 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [416.069 76.78 433.006 87.684] /A << /S /GoTo /D (page.205) >> >> endobj 4598 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [325.4 55.978 342.337 66.164] /A << /S /GoTo /D (page.179) >> >> endobj 4599 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [329.844 44.022 346.78 54.209] /A << /S /GoTo /D (page.161) >> >> endobj 4600 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.769 44.022 366.705 54.209] /A << /S /GoTo /D (page.199) >> >> endobj 4607 0 obj << /D [4605 0 R /XYZ 89 721 null] >> endobj 4604 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4836 0 obj << /Length 1626 /Filter /FlateDecode >> stream xÚåZ[sÓ8~ï¯ðc2³*–|ç-´)-Ó6$f`ÜXM¼ëZF–)åׯ/)7äè$.–Ja¬Ïçò«lsÃ4^¼š¼8ñl#8 \æÓ[#0 ÏôMÛ1¦‘ñ¡wvy<|ßÿ{úæÅ‰ÃVž³«‡·D©c®S=t`. òøa^yÈj“œ¨…}æôî ïS§÷eÆ3‹ô¯ú8-›†œÍ/ãèaŽÙ£´…o„ÒÃÀYŠ9Ž!ˆ ñ¡œ`&ÛøRÉÀL„JÉ>3{dÊè¾OÍ^(9(R—€bÈÔrôto*m éè8h èz ÜŸI@q®„| ‚v±æ`¶…4Ç7alÚÙÚ¡½m¡ßCÐ.9ï:˜½wAÃl¦lg©Ú:ã^‰<ÖIµœjÉ»³é)y7>›±Yw-Ú6@¤ï™HS>Ó°‰ q÷Vò|€ø6àê„˾mBªùPn©Jë¼ LÞT–<ž§aYØP2[„é"£….í¸i“„Ÿ‹Ù¿Ç¼ê>Ç303жç5¸‚g$óÝèæŸ+‘$q:ï\^ꢋc›ÃÏb`Ш˜ù¹ú±èg•Èýf߬s1Ÿ—vžöýª{êS¿7çjXB¡”‹BÎ [PMÛ虫Pª —u²Nk«/„Bõ„Ô§èÜò”G¬ú“£Áù` ‚l®¯ù,LBz›í1©qÎËÄ}ÝwÍ^\g¼{-çxØn%çŸ žÂÌ|Ù²Õ[w¨<àa=h¢ë µÐ'6çœË8L⯡NåaûL ú¥ «;sÑA!~–s<]“T Î,áaZd(³0 qÃ5Í4´¨m¢OØ—‹–ed‘voÓÞÕ”OƒvUèœ+Ò´õ¦Š$B€”ñaÊÄõc¶n567¤“FR°wÐc5Š#oÕxRÎ]M“Í»ž×™MÑ'¶•]cKãn ½õ–ÆýñÛz•X$ŠdRd\ªv>óA™£8ÏH²Hà\É‚®y+bÄ)Q/õÌgXÖÀÝ…%à}œFËå´j¶Ó ››×@‹Bu*jµÚ6„Öå8 êÁ Éš¡·Zõó0ÊË‹„äñW0Kº0v+§/Ï5º2æ”’ašg¡,ûÞ ÷t·"ªà?WÔ “´ƒåéc‘(,Sǧ¢ìNÕCßuzHðöߣî¡íSõèaùç±x¨åˆ}މü=˜°Kc]ˆÕþ×ÃŽ1> §ÎŠ¿Fï k×Þ¾cjÅÈ"L£DoÍЭO|—%¼®ñƒ50›•1‘pæÛÏÈÁ:ÀÏÕhrw8‘ðL ›êÉÕðh:®üòöb×­LVfnYÜméà%'K”AuM ÓÝ>v×ÝQ–„àe„ ôª ×PF¤Ð˜Â’êù¤6ª·ê-LœÍcd´¬~¿AÁ«ÅÝŸ{‡mnœüݸ™è endstream endobj 4835 0 obj << /Type /Page /Contents 4836 0 R /Resources 4834 0 R /MediaBox [0 0 612 792] /Parent 4608 0 R /Annots [ 4601 0 R 4602 0 R 4603 0 R 4609 0 R 4610 0 R 4611 0 R 4612 0 R 4613 0 R 4614 0 R 4615 0 R 4616 0 R 4617 0 R 4618 0 R 4619 0 R 4620 0 R 4621 0 R 4622 0 R 4623 0 R 4624 0 R 4625 0 R 4626 0 R 4627 0 R 4628 0 R 4629 0 R 4630 0 R 4631 0 R 4632 0 R 4633 0 R 4634 0 R 4635 0 R 4636 0 R 4637 0 R 4638 0 R 4639 0 R 4640 0 R 4641 0 R 4642 0 R 4643 0 R 4644 0 R 4645 0 R 4646 0 R 4647 0 R 4648 0 R 4649 0 R 4650 0 R 4651 0 R 4652 0 R 4653 0 R 4654 0 R 4655 0 R 4656 0 R 4657 0 R 4658 0 R 4659 0 R 4660 0 R 4661 0 R 4662 0 R 4663 0 R 4664 0 R 4665 0 R 4666 0 R 4667 0 R 4668 0 R 4669 0 R 4670 0 R 4671 0 R 4672 0 R 4673 0 R 4674 0 R 4675 0 R 4676 0 R 4677 0 R 4678 0 R 4679 0 R 4680 0 R 4681 0 R 4682 0 R 4683 0 R 4684 0 R 4685 0 R 4686 0 R 4687 0 R 4688 0 R 4689 0 R 4690 0 R 4691 0 R 4692 0 R 4693 0 R 4694 0 R 4695 0 R 4696 0 R 4697 0 R 4698 0 R 4699 0 R 4700 0 R 4701 0 R 4702 0 R 4703 0 R 4704 0 R 4705 0 R 4706 0 R 4707 0 R 4708 0 R 4709 0 R 4710 0 R 4711 0 R 4712 0 R 4713 0 R 4714 0 R 4715 0 R 4716 0 R 4717 0 R 4718 0 R 4719 0 R 4720 0 R 4721 0 R 4722 0 R 4723 0 R 4724 0 R 4725 0 R 4726 0 R 4727 0 R 4728 0 R 4729 0 R 4730 0 R 4731 0 R 4732 0 R 4733 0 R 4734 0 R 4735 0 R 4736 0 R 4737 0 R 4738 0 R 4739 0 R 4740 0 R 4741 0 R 4742 0 R 4743 0 R 4744 0 R 4745 0 R 4746 0 R 4747 0 R 4748 0 R 4749 0 R 4750 0 R 4751 0 R 4752 0 R 4753 0 R 4754 0 R 4755 0 R 4756 0 R 4757 0 R 4758 0 R 4759 0 R 4760 0 R 4761 0 R 4762 0 R 4763 0 R 4764 0 R 4765 0 R 4766 0 R 4767 0 R 4768 0 R 4769 0 R 4770 0 R 4771 0 R 4772 0 R 4773 0 R 4774 0 R 4775 0 R 4776 0 R 4777 0 R 4778 0 R 4779 0 R 4780 0 R 4781 0 R 4782 0 R 4783 0 R 4784 0 R 4785 0 R 4786 0 R 4787 0 R 4788 0 R 4789 0 R 4790 0 R 4791 0 R 4792 0 R 4793 0 R 4794 0 R 4795 0 R 4796 0 R 4797 0 R 4798 0 R 4799 0 R 4800 0 R 4801 0 R 4802 0 R 4803 0 R 4804 0 R 4805 0 R 4806 0 R 4807 0 R 4808 0 R 4809 0 R 4810 0 R 4811 0 R 4812 0 R 4813 0 R 4814 0 R 4815 0 R 4816 0 R 4817 0 R 4818 0 R 4819 0 R 4820 0 R 4821 0 R 4822 0 R 4823 0 R 4824 0 R 4825 0 R 4826 0 R 4827 0 R 4828 0 R 4829 0 R 4830 0 R 4831 0 R ] >> endobj 4601 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.94 676.929 186.876 687.833] /A << /S /GoTo /D (page.115) >> >> endobj 4602 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [121.103 665.691 138.04 675.878] /A << /S /GoTo /D (page.195) >> >> endobj 4603 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [141.028 665.691 157.965 675.878] /A << /S /GoTo /D (page.202) >> >> endobj 4609 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [111.131 653.736 123.086 663.923] /A << /S /GoTo /D (page.90) >> >> endobj 4610 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.807 641.781 179.763 651.968] /A << /S /GoTo /D (page.20) >> >> endobj 4611 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [182.751 641.781 194.707 651.968] /A << /S /GoTo /D (page.91) >> >> endobj 4612 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [197.695 641.781 209.65 651.968] /A << /S /GoTo /D (page.99) >> >> endobj 4613 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [212.639 641.781 229.576 651.968] /A << /S /GoTo /D (page.135) >> >> endobj 4614 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.454 629.826 159.409 640.012] /A << /S /GoTo /D (page.55) >> >> endobj 4615 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.398 629.826 179.334 640.012] /A << /S /GoTo /D (page.131) >> >> endobj 4616 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [186.746 617.153 203.682 628.057] /A << /S /GoTo /D (page.169) >> >> endobj 4617 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [206.671 617.153 223.608 628.057] /A << /S /GoTo /D (page.243) >> >> endobj 4618 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [186.746 605.198 203.682 616.102] /A << /S /GoTo /D (page.245) >> >> endobj 4619 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [186.746 593.243 203.682 604.147] /A << /S /GoTo /D (page.247) >> >> endobj 4620 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.958 581.288 200.913 592.192] /A << /S /GoTo /D (page.26) >> >> endobj 4621 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.329 570.05 163.284 580.237] /A << /S /GoTo /D (page.20) >> >> endobj 4622 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.273 570.05 178.228 580.237] /A << /S /GoTo /D (page.24) >> >> endobj 4623 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [181.217 570.05 193.172 580.237] /A << /S /GoTo /D (page.91) >> >> endobj 4624 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [196.161 570.05 208.116 580.237] /A << /S /GoTo /D (page.99) >> >> endobj 4625 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [211.105 570.05 228.041 580.237] /A << /S /GoTo /D (page.240) >> >> endobj 4626 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.604 557.377 143.559 568.281] /A << /S /GoTo /D (page.24) >> >> endobj 4627 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.115 546.14 164.052 556.326] /A << /S /GoTo /D (page.135) >> >> endobj 4628 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.282 534.184 202.219 544.371] /A << /S /GoTo /D (page.195) >> >> endobj 4629 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.962 522.229 172.899 532.416] /A << /S /GoTo /D (page.195) >> >> endobj 4630 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [175.887 522.229 192.824 532.416] /A << /S /GoTo /D (page.202) >> >> endobj 4631 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [145.442 510.274 157.397 520.461] /A << /S /GoTo /D (page.66) >> >> endobj 4632 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [121.641 498.319 133.596 508.506] /A << /S /GoTo /D (page.84) >> >> endobj 4633 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [128.983 486.364 140.939 496.55] /A << /S /GoTo /D (page.83) >> >> endobj 4634 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.632 473.691 167.568 484.595] /A << /S /GoTo /D (page.153) >> >> endobj 4635 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [136.027 461.736 147.982 472.64] /A << /S /GoTo /D (page.39) >> >> endobj 4636 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.971 461.736 167.907 472.64] /A << /S /GoTo /D (page.199) >> >> endobj 4637 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.367 450.498 174.303 460.685] /A << /S /GoTo /D (page.102) >> >> endobj 4638 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.292 450.498 194.228 460.685] /A << /S /GoTo /D (page.205) >> >> endobj 4639 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [197.217 450.498 214.154 460.685] /A << /S /GoTo /D (page.209) >> >> endobj 4640 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [156.54 437.826 173.476 448.73] /A << /S /GoTo /D (page.102) >> >> endobj 4641 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [176.465 437.826 193.401 448.73] /A << /S /GoTo /D (page.165) >> >> endobj 4642 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [196.39 437.826 213.327 448.73] /A << /S /GoTo /D (page.166) >> >> endobj 4643 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [216.316 437.826 233.252 448.73] /A << /S /GoTo /D (page.205) >> >> endobj 4644 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [236.241 437.826 253.177 448.73] /A << /S /GoTo /D (page.208) >> >> endobj 4645 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [123.564 426.588 135.519 436.775] /A << /S /GoTo /D (page.47) >> >> endobj 4646 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [185.681 413.915 202.617 424.819] /A << /S /GoTo /D (page.102) >> >> endobj 4647 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [205.606 413.915 222.543 424.819] /A << /S /GoTo /D (page.205) >> >> endobj 4648 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [225.531 413.915 242.468 424.819] /A << /S /GoTo /D (page.212) >> >> endobj 4649 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.728 402.678 144.665 412.864] /A << /S /GoTo /D (page.142) >> >> endobj 4650 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.653 402.678 164.59 412.864] /A << /S /GoTo /D (page.146) >> >> endobj 4651 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.663 390.722 164.6 400.909] /A << /S /GoTo /D (page.102) >> >> endobj 4652 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.588 390.722 184.525 400.909] /A << /S /GoTo /D (page.205) >> >> endobj 4653 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.358 378.767 163.294 388.954] /A << /S /GoTo /D (page.181) >> >> endobj 4654 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.283 378.767 183.22 388.954] /A << /S /GoTo /D (page.197) >> >> endobj 4655 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.287 356.849 150.224 367.036] /A << /S /GoTo /D (page.194) >> >> endobj 4656 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.819 344.894 128.774 355.081] /A << /S /GoTo /D (page.75) >> >> endobj 4657 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.457 332.939 174.412 343.126] /A << /S /GoTo /D (page.70) >> >> endobj 4658 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.401 332.939 189.356 343.126] /A << /S /GoTo /D (page.75) >> >> endobj 4659 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [130.498 320.267 147.434 331.171] /A << /S /GoTo /D (page.105) >> >> endobj 4660 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.423 320.267 167.36 331.171] /A << /S /GoTo /D (page.107) >> >> endobj 4661 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.348 320.267 187.285 331.171] /A << /S /GoTo /D (page.109) >> >> endobj 4662 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.274 320.267 207.21 331.171] /A << /S /GoTo /D (page.113) >> >> endobj 4663 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [210.199 320.267 227.135 331.171] /A << /S /GoTo /D (page.114) >> >> endobj 4664 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.681 309.029 159.618 319.215] /A << /S /GoTo /D (page.174) >> >> endobj 4665 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.607 309.029 179.543 319.215] /A << /S /GoTo /D (page.175) >> >> endobj 4666 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [117.776 297.074 129.731 307.26] /A << /S /GoTo /D (page.23) >> >> endobj 4667 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [132.72 297.074 144.675 307.26] /A << /S /GoTo /D (page.26) >> >> endobj 4668 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.664 297.074 164.6 307.26] /A << /S /GoTo /D (page.101) >> >> endobj 4669 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.589 297.074 184.525 307.26] /A << /S /GoTo /D (page.155) >> >> endobj 4670 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [187.514 297.074 204.451 307.26] /A << /S /GoTo /D (page.157) >> >> endobj 4671 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.276 284.401 169.212 295.305] /A << /S /GoTo /D (page.123) >> >> endobj 4672 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.582 273.163 151.519 283.35] /A << /S /GoTo /D (page.103) >> >> endobj 4673 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.508 273.163 171.444 283.35] /A << /S /GoTo /D (page.123) >> >> endobj 4674 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.433 273.163 191.369 283.35] /A << /S /GoTo /D (page.140) >> >> endobj 4675 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [194.358 273.163 211.295 283.35] /A << /S /GoTo /D (page.144) >> >> endobj 4676 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [214.283 273.163 231.22 283.35] /A << /S /GoTo /D (page.146) >> >> endobj 4677 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.573 261.208 151.509 271.395] /A << /S /GoTo /D (page.103) >> >> endobj 4678 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.498 261.208 171.434 271.395] /A << /S /GoTo /D (page.104) >> >> endobj 4679 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.423 261.208 191.36 271.395] /A << /S /GoTo /D (page.123) >> >> endobj 4680 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.89 248.536 194.826 259.44] /A << /S /GoTo /D (page.183) >> >> endobj 4681 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [122.199 237.298 139.135 247.484] /A << /S /GoTo /D (page.146) >> >> endobj 4682 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [142.124 237.298 159.061 247.484] /A << /S /GoTo /D (page.148) >> >> endobj 4683 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.049 237.298 178.986 247.484] /A << /S /GoTo /D (page.219) >> >> endobj 4684 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [127.738 225.343 144.674 235.529] /A << /S /GoTo /D (page.190) >> >> endobj 4685 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.663 225.343 164.6 235.529] /A << /S /GoTo /D (page.214) >> >> endobj 4686 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.6 212.67 181.556 223.574] /A << /S /GoTo /D (page.24) >> >> endobj 4687 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [184.544 212.67 201.481 223.574] /A << /S /GoTo /D (page.241) >> >> endobj 4688 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [204.47 212.67 221.406 223.574] /A << /S /GoTo /D (page.244) >> >> endobj 4689 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.899 200.715 194.836 211.619] /A << /S /GoTo /D (page.246) >> >> endobj 4690 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.899 188.76 194.836 199.664] /A << /S /GoTo /D (page.247) >> >> endobj 4691 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [179.095 176.805 196.031 187.709] /A << /S /GoTo /D (page.128) >> >> endobj 4692 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [147.264 164.849 164.201 175.753] /A << /S /GoTo /D (page.129) >> >> endobj 4693 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.19 164.849 184.126 175.753] /A << /S /GoTo /D (page.131) >> >> endobj 4694 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.616 152.894 174.552 163.798] /A << /S /GoTo /D (page.129) >> >> endobj 4695 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [181.576 141.656 198.512 151.843] /A << /S /GoTo /D (page.140) >> >> endobj 4696 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.597 128.984 179.533 139.888] /A << /S /GoTo /D (page.129) >> >> endobj 4697 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [153.75 117.029 165.705 127.933] /A << /S /GoTo /D (page.24) >> >> endobj 4698 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.049 105.074 178.986 115.977] /A << /S /GoTo /D (page.248) >> >> endobj 4699 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [208.534 93.118 225.47 104.022] /A << /S /GoTo /D (page.168) >> >> endobj 4700 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [164.859 81.881 181.795 92.067] /A << /S /GoTo /D (page.141) >> >> endobj 4701 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.894 69.208 225.849 80.112] /A << /S /GoTo /D (page.66) >> >> endobj 4702 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.701 57.97 146.637 68.157] /A << /S /GoTo /D (page.137) >> >> endobj 4703 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [179.961 45.298 196.898 56.202] /A << /S /GoTo /D (page.137) >> >> endobj 4704 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.248 676.929 396.184 687.833] /A << /S /GoTo /D (page.102) >> >> endobj 4705 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [399.173 676.929 416.11 687.833] /A << /S /GoTo /D (page.205) >> >> endobj 4706 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [419.098 676.929 436.035 687.833] /A << /S /GoTo /D (page.212) >> >> endobj 4707 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [347.547 665.691 359.502 675.878] /A << /S /GoTo /D (page.75) >> >> endobj 4708 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [362.491 665.691 374.446 675.878] /A << /S /GoTo /D (page.77) >> >> endobj 4709 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.435 665.691 389.39 675.878] /A << /S /GoTo /D (page.82) >> >> endobj 4710 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.267 653.019 346.222 663.923] /A << /S /GoTo /D (page.91) >> >> endobj 4711 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.211 653.019 361.166 663.923] /A << /S /GoTo /D (page.92) >> >> endobj 4712 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.155 653.019 381.091 663.923] /A << /S /GoTo /D (page.153) >> >> endobj 4713 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [384.08 653.019 401.016 663.923] /A << /S /GoTo /D (page.155) >> >> endobj 4714 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [367.063 641.064 384 651.968] /A << /S /GoTo /D (page.153) >> >> endobj 4715 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [386.989 641.064 403.925 651.968] /A << /S /GoTo /D (page.155) >> >> endobj 4716 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [391.671 629.108 403.626 640.012] /A << /S /GoTo /D (page.75) >> >> endobj 4717 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [346.999 617.153 358.954 628.057] /A << /S /GoTo /D (page.88) >> >> endobj 4718 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [361.943 617.153 373.898 628.057] /A << /S /GoTo /D (page.95) >> >> endobj 4719 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [376.887 617.153 388.842 628.057] /A << /S /GoTo /D (page.97) >> >> endobj 4720 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [391.831 617.153 408.767 628.057] /A << /S /GoTo /D (page.102) >> >> endobj 4721 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [411.756 617.153 428.693 628.057] /A << /S /GoTo /D (page.126) >> >> endobj 4722 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [333.719 605.915 345.674 616.102] /A << /S /GoTo /D (page.13) >> >> endobj 4723 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [362.66 593.96 379.597 604.147] /A << /S /GoTo /D (page.194) >> >> endobj 4724 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [346.989 581.288 358.944 592.192] /A << /S /GoTo /D (page.75) >> >> endobj 4725 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.304 569.333 376.259 580.237] /A << /S /GoTo /D (page.90) >> >> endobj 4726 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.248 569.333 391.203 580.237] /A << /S /GoTo /D (page.94) >> >> endobj 4727 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.192 569.333 411.128 580.237] /A << /S /GoTo /D (page.131) >> >> endobj 4728 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.373 557.377 347.328 568.281] /A << /S /GoTo /D (page.69) >> >> endobj 4729 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.039 546.14 379.975 556.326] /A << /S /GoTo /D (page.197) >> >> endobj 4730 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [327.622 534.184 344.558 544.371] /A << /S /GoTo /D (page.146) >> >> endobj 4731 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [347.547 534.184 364.483 544.371] /A << /S /GoTo /D (page.148) >> >> endobj 4732 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [336.628 522.229 353.564 532.416] /A << /S /GoTo /D (page.253) >> >> endobj 4733 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.049 509.557 379.985 520.461] /A << /S /GoTo /D (page.102) >> >> endobj 4734 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.974 509.557 399.91 520.461] /A << /S /GoTo /D (page.205) >> >> endobj 4735 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [402.899 509.557 419.836 520.461] /A << /S /GoTo /D (page.212) >> >> endobj 4736 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [358.077 497.602 375.014 508.506] /A << /S /GoTo /D (page.102) >> >> endobj 4737 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.002 497.602 394.939 508.506] /A << /S /GoTo /D (page.165) >> >> endobj 4738 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.928 497.602 414.864 508.506] /A << /S /GoTo /D (page.205) >> >> endobj 4739 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.853 497.602 434.789 508.506] /A << /S /GoTo /D (page.207) >> >> endobj 4740 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [330.391 486.364 342.346 496.55] /A << /S /GoTo /D (page.91) >> >> endobj 4741 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [345.335 486.364 357.29 496.55] /A << /S /GoTo /D (page.95) >> >> endobj 4742 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.279 486.364 372.234 496.55] /A << /S /GoTo /D (page.97) >> >> endobj 4743 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.223 486.364 387.178 496.55] /A << /S /GoTo /D (page.99) >> >> endobj 4744 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [390.167 486.364 407.104 496.55] /A << /S /GoTo /D (page.105) >> >> endobj 4745 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [410.092 486.364 427.029 496.55] /A << /S /GoTo /D (page.120) >> >> endobj 4746 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [430.018 486.364 446.954 496.55] /A << /S /GoTo /D (page.133) >> >> endobj 4747 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [449.943 486.364 466.879 496.55] /A << /S /GoTo /D (page.204) >> >> endobj 4748 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [328.727 474.409 340.683 484.595] /A << /S /GoTo /D (page.25) >> >> endobj 4749 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [343.671 474.409 355.627 484.595] /A << /S /GoTo /D (page.26) >> >> endobj 4750 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [358.615 474.409 370.571 484.595] /A << /S /GoTo /D (page.90) >> >> endobj 4751 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.559 474.409 385.514 484.595] /A << /S /GoTo /D (page.91) >> >> endobj 4752 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [388.503 474.409 400.458 484.595] /A << /S /GoTo /D (page.99) >> >> endobj 4753 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [403.447 474.409 420.384 484.595] /A << /S /GoTo /D (page.120) >> >> endobj 4754 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [423.373 474.409 440.309 484.595] /A << /S /GoTo /D (page.191) >> >> endobj 4755 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [443.298 474.409 460.234 484.595] /A << /S /GoTo /D (page.217) >> >> endobj 4756 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [334.825 462.453 346.78 472.64] /A << /S /GoTo /D (page.91) >> >> endobj 4757 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [349.769 462.453 361.724 472.64] /A << /S /GoTo /D (page.95) >> >> endobj 4758 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [364.712 462.453 376.668 472.64] /A << /S /GoTo /D (page.97) >> >> endobj 4759 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [379.656 462.453 391.612 472.64] /A << /S /GoTo /D (page.99) >> >> endobj 4760 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [394.6 462.453 411.537 472.64] /A << /S /GoTo /D (page.120) >> >> endobj 4761 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.526 462.453 431.462 472.64] /A << /S /GoTo /D (page.133) >> >> endobj 4762 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [434.451 462.453 451.387 472.64] /A << /S /GoTo /D (page.204) >> >> endobj 4763 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [333.161 450.498 345.116 460.685] /A << /S /GoTo /D (page.25) >> >> endobj 4764 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.105 450.498 360.06 460.685] /A << /S /GoTo /D (page.26) >> >> endobj 4765 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [363.049 450.498 375.004 460.685] /A << /S /GoTo /D (page.90) >> >> endobj 4766 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.993 450.498 389.948 460.685] /A << /S /GoTo /D (page.91) >> >> endobj 4767 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [392.937 450.498 404.892 460.685] /A << /S /GoTo /D (page.99) >> >> endobj 4768 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [407.881 450.498 424.817 460.685] /A << /S /GoTo /D (page.191) >> >> endobj 4769 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [362.501 437.826 379.437 448.73] /A << /S /GoTo /D (page.102) >> >> endobj 4770 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [382.426 437.826 399.363 448.73] /A << /S /GoTo /D (page.205) >> >> endobj 4771 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [402.351 437.826 419.288 448.73] /A << /S /GoTo /D (page.212) >> >> endobj 4772 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [357.529 425.871 374.466 436.775] /A << /S /GoTo /D (page.102) >> >> endobj 4773 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.455 425.871 394.391 436.775] /A << /S /GoTo /D (page.165) >> >> endobj 4774 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [397.38 425.871 414.316 436.775] /A << /S /GoTo /D (page.205) >> >> endobj 4775 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.305 425.871 434.242 436.775] /A << /S /GoTo /D (page.207) >> >> endobj 4776 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [355.845 413.915 372.782 424.819] /A << /S /GoTo /D (page.106) >> >> endobj 4777 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.422 401.96 363.378 412.864] /A << /S /GoTo /D (page.18) >> >> endobj 4778 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [366.366 401.96 378.321 412.864] /A << /S /GoTo /D (page.20) >> >> endobj 4779 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.31 401.96 398.247 412.864] /A << /S /GoTo /D (page.106) >> >> endobj 4780 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [401.236 401.96 418.172 412.864] /A << /S /GoTo /D (page.109) >> >> endobj 4781 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [421.161 401.96 438.097 412.864] /A << /S /GoTo /D (page.114) >> >> endobj 4782 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [351.96 390.005 368.897 400.909] /A << /S /GoTo /D (page.106) >> >> endobj 4783 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.885 390.005 388.822 400.909] /A << /S /GoTo /D (page.114) >> >> endobj 4784 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [348.095 378.767 360.05 388.954] /A << /S /GoTo /D (page.83) >> >> endobj 4785 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [372.593 366.812 384.548 376.999] /A << /S /GoTo /D (page.40) >> >> endobj 4786 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.72 354.857 395.657 365.044] /A << /S /GoTo /D (page.190) >> >> endobj 4787 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [398.645 354.857 415.582 365.044] /A << /S /GoTo /D (page.221) >> >> endobj 4788 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [335.671 342.902 352.608 353.088] /A << /S /GoTo /D (page.108) >> >> endobj 4789 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.827 330.229 372.782 341.133] /A << /S /GoTo /D (page.34) >> >> endobj 4790 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [345.893 318.274 357.848 329.178] /A << /S /GoTo /D (page.78) >> >> endobj 4791 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [360.837 318.274 372.792 329.178] /A << /S /GoTo /D (page.79) >> >> endobj 4792 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [344.229 306.319 356.185 317.223] /A << /S /GoTo /D (page.81) >> >> endobj 4793 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [389.469 294.364 401.424 305.268] /A << /S /GoTo /D (page.78) >> >> endobj 4794 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [404.413 294.364 416.368 305.268] /A << /S /GoTo /D (page.79) >> >> endobj 4795 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [336.26 273.163 348.215 283.35] /A << /S /GoTo /D (page.13) >> >> endobj 4796 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [465.135 261.208 482.072 271.395] /A << /S /GoTo /D (page.214) >> >> endobj 4797 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [485.061 261.208 501.997 271.395] /A << /S /GoTo /D (page.221) >> >> endobj 4798 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [361.535 248.536 373.49 259.44] /A << /S /GoTo /D (page.83) >> >> endobj 4799 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [449.086 237.298 466.022 247.484] /A << /S /GoTo /D (page.214) >> >> endobj 4800 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [469.011 237.298 485.948 247.484] /A << /S /GoTo /D (page.221) >> >> endobj 4801 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [372.992 225.343 389.928 235.529] /A << /S /GoTo /D (page.152) >> >> endobj 4802 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [392.917 225.343 409.853 235.529] /A << /S /GoTo /D (page.186) >> >> endobj 4803 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [412.842 225.343 429.779 235.529] /A << /S /GoTo /D (page.220) >> >> endobj 4804 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [395.497 213.387 412.434 223.574] /A << /S /GoTo /D (page.193) >> >> endobj 4805 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [415.422 213.387 432.359 223.574] /A << /S /GoTo /D (page.220) >> >> endobj 4806 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [373.301 201.432 390.237 211.619] /A << /S /GoTo /D (page.220) >> >> endobj 4807 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [427.965 189.477 444.901 199.664] /A << /S /GoTo /D (page.216) >> >> endobj 4808 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [427.407 177.522 444.344 187.709] /A << /S /GoTo /D (page.216) >> >> endobj 4809 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [424.837 165.567 441.773 175.753] /A << /S /GoTo /D (page.216) >> >> endobj 4810 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [340.075 152.894 357.012 163.798] /A << /S /GoTo /D (page.215) >> >> endobj 4811 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [404.622 140.939 421.559 151.843] /A << /S /GoTo /D (page.112) >> >> endobj 4812 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [391.871 128.984 408.807 139.888] /A << /S /GoTo /D (page.108) >> >> endobj 4813 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [377.494 117.029 389.45 127.933] /A << /S /GoTo /D (page.16) >> >> endobj 4814 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [376.936 105.074 393.873 115.977] /A << /S /GoTo /D (page.105) >> >> endobj 4815 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.862 105.074 413.798 115.977] /A << /S /GoTo /D (page.108) >> >> endobj 4816 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [381.37 93.118 393.325 104.022] /A << /S /GoTo /D (page.17) >> >> endobj 4817 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [396.314 93.118 413.25 104.022] /A << /S /GoTo /D (page.106) >> >> endobj 4818 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [416.239 93.118 433.176 104.022] /A << /S /GoTo /D (page.112) >> >> endobj 4819 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [446.635 81.163 458.59 92.067] /A << /S /GoTo /D (page.18) >> >> endobj 4820 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [461.1 81.163 478.037 92.067] /A << /S /GoTo /D (page.105) >> >> endobj 4821 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [480.548 81.163 497.484 92.067] /A << /S /GoTo /D (page.108) >> >> endobj 4822 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [499.995 81.163 516.931 92.067] /A << /S /GoTo /D (page.115) >> >> endobj 4823 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [414.456 69.208 426.411 80.112] /A << /S /GoTo /D (page.16) >> >> endobj 4824 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [429.4 69.208 446.336 80.112] /A << /S /GoTo /D (page.107) >> >> endobj 4825 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [449.325 69.208 466.262 80.112] /A << /S /GoTo /D (page.113) >> >> endobj 4826 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [438.814 57.253 455.751 68.157] /A << /S /GoTo /D (page.105) >> >> endobj 4827 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [458.739 57.253 475.676 68.157] /A << /S /GoTo /D (page.108) >> >> endobj 4828 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [478.665 57.253 495.601 68.157] /A << /S /GoTo /D (page.115) >> >> endobj 4829 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [417.783 45.298 429.738 56.202] /A << /S /GoTo /D (page.17) >> >> endobj 4830 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [432.727 45.298 449.664 56.202] /A << /S /GoTo /D (page.107) >> >> endobj 4831 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [452.652 45.298 469.589 56.202] /A << /S /GoTo /D (page.114) >> >> endobj 4837 0 obj << /D [4835 0 R /XYZ 89 721 null] >> endobj 4834 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4934 0 obj << /Length 812 /Filter /FlateDecode >> stream xÚÍXKSÛ0¾çWøhÏÔ É–Gš„N:%P0C¦ÇF­©­þüúS Í¶¡å”´Ÿ¾}}«512ƒFï£Ñþ¡ïá^è1ψ®> öˆË(5®ÌÙ|2ýb}>îröàœÛâ^‹Òcž×‘;`þ?`3¿5r†c‘3.³ê IDÓŒ«RÕUþ®7¥­!1êÌþœ¶ W6ãĤ!yŒ}eŒóÇİ)Ý ùSª£P' #Z”hrv|b`©;zæ¢Xæ±J ¯ )Ò€Rì”yúpZ>1;÷ÆUQÄe 1&¯í"£/öž'<+ß.eþåã•úײַTláðWŽÌ[ˆ ÄYÝÔ"†úÄÅ*‡Nw°>ÞÍ*p àUãæÚåæÏD,•¬JPö8Z(!q¸) ‘(UObƒ‘¦Ò=Þ¸Hw§ª*Wr  øáÖ‚Ð`Yå² Úú„­J‚†¾â¼üT%ß'¢Ëû­L )J zz´.‘ðºîë3“µÅˆi72+ãÛ”Op›Õ¢Ij¹öîQ*¤œlTóù2=^|;©ò\–Ù‰¨e•î<ÈÔãÿ -¾’N?AjÏô¨'âÚ¢í{x•«Ãußÿ'uµuê•Ìwr‚l†¶p ÚýÒp¹V¨†&¨Uj£ëßFâne߇ë¶Ë]éy»í€[#§ í…E[ñêŠ\.:[K þ¥—¼ß æñ¼›’y><D ¾Äô åZ¦™PÈœmқͪº^~/ºÒ‘%Œãº@¨zœtO¾ÆCô“‘nsÿQ,K¬'[ô¡þU½®¥Š¹@|o袇ÛŠ©·5Ý? ʸX›¡?ESƒk˰#†íîg|{àØM\§ë~XÖbçë'AÇß’ü¶ZÇ}ì–F°  .fî«ïùè@3—náæR.Ò¹ç Öî¶iTÖ˜»»õÏ(>œŸ—GŸÁªDF×Á¦ÃA/ánˆþæVI¦¯‘ËâÇô~¹9vž~ÓßÄeö&V@ú8Ðï4ý¤,& endstream endobj 4933 0 obj << /Type /Page /Contents 4934 0 R /Resources 4932 0 R /MediaBox [0 0 612 792] /Parent 4608 0 R /Annots [ 4832 0 R 4833 0 R 4838 0 R 4839 0 R 4840 0 R 4841 0 R 4842 0 R 4843 0 R 4844 0 R 4845 0 R 4846 0 R 4847 0 R 4848 0 R 4849 0 R 4850 0 R 4851 0 R 4852 0 R 4853 0 R 4854 0 R 4855 0 R 4856 0 R 4857 0 R 4858 0 R 4859 0 R 4860 0 R 4861 0 R 4862 0 R 4863 0 R 4864 0 R 4865 0 R 4866 0 R 4867 0 R 4868 0 R 4869 0 R 4870 0 R 4871 0 R 4872 0 R 4873 0 R 4874 0 R 4875 0 R 4876 0 R 4877 0 R 4878 0 R 4879 0 R 4880 0 R 4881 0 R 4882 0 R 4883 0 R 4884 0 R 4885 0 R 4886 0 R 4887 0 R 4888 0 R 4889 0 R 4890 0 R 4891 0 R 4892 0 R 4893 0 R 4894 0 R 4895 0 R 4896 0 R 4897 0 R 4898 0 R 4899 0 R 4900 0 R 4901 0 R 4902 0 R 4903 0 R 4904 0 R 4905 0 R 4906 0 R 4907 0 R 4908 0 R 4909 0 R 4910 0 R 4911 0 R 4912 0 R 4913 0 R 4914 0 R 4915 0 R 4916 0 R 4917 0 R 4918 0 R 4919 0 R 4920 0 R 4921 0 R 4922 0 R 4923 0 R 4924 0 R 4925 0 R 4926 0 R 4927 0 R 4928 0 R 4929 0 R 4930 0 R 4931 0 R ] >> endobj 4832 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [177.302 676.929 194.238 687.833] /A << /S /GoTo /D (page.190) >> >> endobj 4833 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [197.227 676.929 214.164 687.833] /A << /S /GoTo /D (page.255) >> >> endobj 4838 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [123.863 664.974 140.799 675.878] /A << /S /GoTo /D (page.220) >> >> endobj 4839 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [128.854 653.736 140.809 663.923] /A << /S /GoTo /D (page.22) >> >> endobj 4840 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.798 653.736 155.753 663.923] /A << /S /GoTo /D (page.23) >> >> endobj 4841 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [128.296 641.064 140.251 651.968] /A << /S /GoTo /D (page.88) >> >> endobj 4842 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.24 641.064 155.195 651.968] /A << /S /GoTo /D (page.91) >> >> endobj 4843 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.184 641.064 175.12 651.968] /A << /S /GoTo /D (page.118) >> >> endobj 4844 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [178.109 641.064 195.045 651.968] /A << /S /GoTo /D (page.126) >> >> endobj 4845 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.814 629.108 172.769 640.012] /A << /S /GoTo /D (page.90) >> >> endobj 4846 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [175.758 629.108 187.713 640.012] /A << /S /GoTo /D (page.91) >> >> endobj 4847 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.702 629.108 207.638 640.012] /A << /S /GoTo /D (page.216) >> >> endobj 4848 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.113 617.153 181.068 628.057] /A << /S /GoTo /D (page.90) >> >> endobj 4849 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [184.057 617.153 196.012 628.057] /A << /S /GoTo /D (page.91) >> >> endobj 4850 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [199.001 617.153 215.937 628.057] /A << /S /GoTo /D (page.216) >> >> endobj 4851 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [184.056 605.198 196.012 616.102] /A << /S /GoTo /D (page.90) >> >> endobj 4852 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [199 605.198 210.956 616.102] /A << /S /GoTo /D (page.91) >> >> endobj 4853 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [213.944 605.198 230.881 616.102] /A << /S /GoTo /D (page.126) >> >> endobj 4854 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [233.87 605.198 250.806 616.102] /A << /S /GoTo /D (page.135) >> >> endobj 4855 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [253.795 605.198 270.731 616.102] /A << /S /GoTo /D (page.216) >> >> endobj 4856 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [175.758 593.243 187.713 604.147] /A << /S /GoTo /D (page.90) >> >> endobj 4857 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [190.702 593.243 202.657 604.147] /A << /S /GoTo /D (page.91) >> >> endobj 4858 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [205.646 593.243 222.582 604.147] /A << /S /GoTo /D (page.216) >> >> endobj 4859 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [118.881 582.005 130.837 592.192] /A << /S /GoTo /D (page.42) >> >> endobj 4860 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [133.825 582.005 145.781 592.192] /A << /S /GoTo /D (page.66) >> >> endobj 4861 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [148.769 582.005 165.706 592.192] /A << /S /GoTo /D (page.153) >> >> endobj 4862 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [168.695 582.005 185.631 592.192] /A << /S /GoTo /D (page.173) >> >> endobj 4863 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [188.62 582.005 205.556 592.192] /A << /S /GoTo /D (page.176) >> >> endobj 4864 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [208.545 582.005 225.482 592.192] /A << /S /GoTo /D (page.183) >> >> endobj 4865 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [158.881 569.333 175.818 580.237] /A << /S /GoTo /D (page.115) >> >> endobj 4866 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [178.806 569.333 195.743 580.237] /A << /S /GoTo /D (page.116) >> >> endobj 4867 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.507 558.095 171.444 568.281] /A << /S /GoTo /D (page.170) >> >> endobj 4868 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [157.835 546.14 174.771 556.326] /A << /S /GoTo /D (page.170) >> >> endobj 4869 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.007 533.467 131.962 544.371] /A << /S /GoTo /D (page.79) >> >> endobj 4870 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [117.795 512.267 134.732 522.453] /A << /S /GoTo /D (page.253) >> >> endobj 4871 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [109.487 500.311 126.423 510.498] /A << /S /GoTo /D (page.197) >> >> endobj 4872 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.597 488.356 171.534 498.543] /A << /S /GoTo /D (page.102) >> >> endobj 4873 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [174.523 488.356 191.459 498.543] /A << /S /GoTo /D (page.205) >> >> endobj 4874 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [194.448 488.356 211.384 498.543] /A << /S /GoTo /D (page.209) >> >> endobj 4875 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.594 475.684 177.531 486.588] /A << /S /GoTo /D (page.153) >> >> endobj 4876 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [166.074 464.446 178.029 474.633] /A << /S /GoTo /D (page.42) >> >> endobj 4877 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [180.888 451.773 197.825 462.677] /A << /S /GoTo /D (page.102) >> >> endobj 4878 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [200.814 451.773 217.75 462.677] /A << /S /GoTo /D (page.165) >> >> endobj 4879 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [220.739 451.773 237.675 462.677] /A << /S /GoTo /D (page.205) >> >> endobj 4880 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [240.664 451.773 257.601 462.677] /A << /S /GoTo /D (page.208) >> >> endobj 4881 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [113.91 440.536 125.865 450.722] /A << /S /GoTo /D (page.92) >> >> endobj 4882 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [195.155 427.863 212.091 438.767] /A << /S /GoTo /D (page.181) >> >> endobj 4883 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [109.487 416.625 126.423 426.812] /A << /S /GoTo /D (page.102) >> >> endobj 4884 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [129.412 416.625 146.348 426.812] /A << /S /GoTo /D (page.103) >> >> endobj 4885 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [149.337 416.625 166.274 426.812] /A << /S /GoTo /D (page.123) >> >> endobj 4886 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.262 416.625 186.199 426.812] /A << /S /GoTo /D (page.140) >> >> endobj 4887 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [189.188 416.625 206.124 426.812] /A << /S /GoTo /D (page.141) >> >> endobj 4888 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [209.113 416.625 226.049 426.812] /A << /S /GoTo /D (page.145) >> >> endobj 4889 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [124.819 394.707 141.756 404.894] /A << /S /GoTo /D (page.121) >> >> endobj 4890 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [144.745 394.707 161.681 404.894] /A << /S /GoTo /D (page.140) >> >> endobj 4891 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.446 382.752 132.401 392.939] /A << /S /GoTo /D (page.69) >> >> endobj 4892 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [135.39 382.752 147.345 392.939] /A << /S /GoTo /D (page.75) >> >> endobj 4893 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.334 382.752 162.289 392.939] /A << /S /GoTo /D (page.82) >> >> endobj 4894 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [165.277 382.752 177.233 392.939] /A << /S /GoTo /D (page.86) >> >> endobj 4895 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [137.97 360.834 149.925 371.021] /A << /S /GoTo /D (page.90) >> >> endobj 4896 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [152.914 360.834 164.869 371.021] /A << /S /GoTo /D (page.93) >> >> endobj 4897 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [170.766 348.879 187.703 359.066] /A << /S /GoTo /D (page.215) >> >> endobj 4898 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [121.103 336.207 133.058 347.111] /A << /S /GoTo /D (page.69) >> >> endobj 4899 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [123.863 324.969 140.799 335.156] /A << /S /GoTo /D (page.152) >> >> endobj 4900 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [120.705 313.014 137.641 323.2] /A << /S /GoTo /D (page.144) >> >> endobj 4901 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.524 301.059 148.461 311.245] /A << /S /GoTo /D (page.139) >> >> endobj 4902 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.449 301.059 168.386 311.245] /A << /S /GoTo /D (page.151) >> >> endobj 4903 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.773 289.103 148.709 299.29] /A << /S /GoTo /D (page.144) >> >> endobj 4904 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [151.698 289.103 168.635 299.29] /A << /S /GoTo /D (page.146) >> >> endobj 4905 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [126.632 277.148 138.587 287.335] /A << /S /GoTo /D (page.93) >> >> endobj 4906 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [141.576 277.148 158.513 287.335] /A << /S /GoTo /D (page.194) >> >> endobj 4907 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [161.501 277.148 178.438 287.335] /A << /S /GoTo /D (page.202) >> >> endobj 4908 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [167.927 265.193 184.863 275.38] /A << /S /GoTo /D (page.194) >> >> endobj 4909 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [125.527 253.238 142.463 263.425] /A << /S /GoTo /D (page.195) >> >> endobj 4910 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [114.458 241.283 126.413 251.469] /A << /S /GoTo /D (page.90) >> >> endobj 4911 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [171.135 229.328 183.09 239.514] /A << /S /GoTo /D (page.91) >> >> endobj 4912 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [186.079 229.328 203.015 239.514] /A << /S /GoTo /D (page.100) >> >> endobj 4913 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [206.004 229.328 222.94 239.514] /A << /S /GoTo /D (page.137) >> >> endobj 4914 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [150.781 217.372 162.736 227.559] /A << /S /GoTo /D (page.57) >> >> endobj 4915 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [165.725 217.372 177.68 227.559] /A << /S /GoTo /D (page.60) >> >> endobj 4916 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [154.656 205.417 166.612 215.604] /A << /S /GoTo /D (page.24) >> >> endobj 4917 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [169.6 205.417 181.556 215.604] /A << /S /GoTo /D (page.91) >> >> endobj 4918 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [184.544 205.417 201.481 215.604] /A << /S /GoTo /D (page.100) >> >> endobj 4919 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [204.47 205.417 221.406 215.604] /A << /S /GoTo /D (page.241) >> >> endobj 4920 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [134.931 192.745 146.886 203.649] /A << /S /GoTo /D (page.24) >> >> endobj 4921 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [171.244 181.507 183.199 191.694] /A << /S /GoTo /D (page.24) >> >> endobj 4922 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [155.394 168.834 167.349 179.738] /A << /S /GoTo /D (page.24) >> >> endobj 4923 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [116.122 147.29 128.077 157.821] /A << /S /GoTo /D (page.13) >> >> endobj 4924 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [131.066 147.29 143.021 157.821] /A << /S /GoTo /D (page.30) >> >> endobj 4925 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.01 147.29 157.965 157.821] /A << /S /GoTo /D (page.36) >> >> endobj 4926 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [160.954 147.29 177.89 157.821] /A << /S /GoTo /D (page.149) >> >> endobj 4927 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [180.879 147.29 197.816 157.821] /A << /S /GoTo /D (page.214) >> >> endobj 4928 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [200.804 147.29 217.741 157.821] /A << /S /GoTo /D (page.221) >> >> endobj 4929 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [216.704 134.961 233.64 145.865] /A << /S /GoTo /D (page.102) >> >> endobj 4930 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [236.629 134.961 253.566 145.865] /A << /S /GoTo /D (page.205) >> >> endobj 4931 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [256.554 134.961 273.491 145.865] /A << /S /GoTo /D (page.210) >> >> endobj 4935 0 obj << /D [4933 0 R /XYZ 89 721 null] >> endobj 4932 0 obj << /Font << /F74 1937 0 R /F52 1832 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4937 0 obj [600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] endobj 4938 0 obj [500 333 500 500 444 500 444 333 500 556 278 278 500 278 778 556 500 500 500 389 389 278 556] endobj 4939 0 obj [722 667 611 778 722 278 500 667 556 833 722 778 667 778 722 667 611 722 667 944 667 667 611 278 278 278 469 556 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500] endobj 4940 0 obj [600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 0 0 0 0 0 0 600 600] endobj 4941 0 obj [333 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722] endobj 4942 0 obj [556 556 167 333 667 278 333 333 0 333 570 0 667 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 278 250 333 555 500 500 1000 833 333 333 333 500 570 250 333 250 278 500 500 500 500 500 500 500 500 500 500 333 333 570 570 570 500 930 722 667 722 722 667 611 778 778 389 500 778 667 944 722 778 611 778 722 556 667 722 722 1000 722 722 667 333 278 333 581 500 333 500 556 444 556 444 333 500 556 278 333 556 278 833 556 500 556 556 444 389 333 556 500 722 500 500 444 394 220 394 520 0 0 0 333 500 500 1000 500 500 333 1000 556 333 1000 0 0 0 0 0 0 500 500 350 500] endobj 4943 0 obj [500 500 167 333 556 278 333 333 0 333 675 0 556 389 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 214 250 333 420 500 500 833 778 333 333 333 500 675 250 333 250 278 500 500 500 500 500 500 500 500 500 500 333 333 675 675 675 500 920 611 611 667 722 611 611 722 722 333 444 667 556 833 667 722 611 722 611 500 556 722 611 833 611 556 556 389 278 389 422 500 333 500 500 444 500 444 278 500 500 278 278 444 278 722 500 500 500 500 389 389 278 500 444 667 444 444 389] endobj 4944 0 obj [556 556 167 333 611 278 333 333 0 333 564 0 611 444 333 278 0 0 0 0 0 0 0 0 0 0 0 0 333 180 250 333 408 500 500 833 778 333 333 333 500 564 250 333 250 278 500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444 921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722 556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500 333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500 500 500 333 389 278 500 500 722 500 500 444 480 200 480 541 0 0 0 333 500 444 1000 500 500 333 1000 556 333 889 0 0 0 0 0 0 444 444 350 500 1000 333 980 389 333 722 0 0 722 0 333 500 500 500 500 200 500 333 760 276 500 564 333 760 333 400 564 300 300 333 500 453 250] endobj 4945 0 obj << /Length1 1606 /Length2 6276 /Length3 0 /Length 7086 /Filter /FlateDecode >> stream xÚ­Tg8œí¶Ö{/‘„at¢÷Nô½D cf0Œf†èBÔè½%ˆ%:=„hB”Ĩѣ9’ïì½Ïõýëœýã½®w•ç^÷Z÷znvc3!UÒ ª…D`„Ä„Eå†0'oô=$Â@H ‡¯RdÜÜê((C"4@¨<Ð j@Á@qq ˜œœ7Pé釂¹¸b€|¦Vü‚ÿòüN:ùý#r} sAy®| p¤§¹†ø?4ƒBW(ЇՌ­u µ|Ú†@m(ŠÁÆÞNphCh(?ЉÂÿ2€`$ûÝZøK ÑžP0ìúÔ õüzBQ04úúC]P æz$†Ã½!¿ \û‘y¢××±k0c$ƒ£`žàuUc ­¿xb\A˜ßµÑ°ë0é| A‚½·ô'v sÅ€`4õÅü®åB`hO8Èïºö5˜' ö‡†7†pùA êBAàP4úæû÷tþÕ'ðtòô„ûý9ü“õO0  w&¿® Æ\×v!ÈD~/Š. ýËñöüGÌŠú3 ¾ß;ÃMA"à~@Ô™Lĉ¹. äû¿©,üŸù? ñDàÿˆ¼ÿ?qÿ®Ñÿ¸Äÿßûüwh-o8Üäq½=0Àë 4þ~cþW.È÷û7ÙO´‚þÅðßèb@×cPE¸\K!*,ú—†Ö‚ùB!Æ0 Øè ‚_Ïèߢà0ôZË?c ‰‰Šþ-fî »#~]ê¯ù;ókyþðÑ´±Ñ°¶øûkú'ËøZuŒ¹Ÿç5±ÿîãòOã7†šÒ $)—‘JËŠeeÄ‚þMµ?0bÿ²ï0(˜/ÐöºeQ±?ÿ÷÷/Ëþo0š0ò{KÌ0 äz±þéø{£P×zþ¹ë× ÿÃþ³âP¨/L6û VwËÊÍÆÔ2ôhؾ}#†ßáù¢Þ¼øù£jdWHVô’ÜKÇ‹šá†Qù«¿éMÏËozwVßÜ€óve@w Y‚8ù»ŸÓ.ð´É¬†‰74wNVŒxt÷È\š„­Ð;9‡×üW'Su;%4âEœîÏ*Žü˜úá69Ùä¨@¸'p_Õ›ãÁUQ ^C̰3g›êUŽƒ‡ÂÊÃŒUflš>ÏÚ›ÿ‘Vçe8¶ç°Ô9å³ di<Š6÷þ…ää²´¾yöƒóÖD‰F…¦óÖ‘Ý”óÅ~òÚ&„µ(1OLâ4J f9#y~‘|Tç;òÃÒNNèyéâi\”ÑõBŒ˜ú§qúTþFÔ&W-ÊÜD¶™ Ÿ`§…Ûð…ò¢—!EdÊaàþÌ×/—êu |§f‡¶3²´ç'ÑãÝcz hóN»£)[¥¸þd{áM¦¡qcº¥Îðå4u‡ 4ï×(ÏÉè.&ÌØÓ)bÑ%‰V^äNèë|_RFû¾±ušÇqRyjßiµ•Ìñ…óV΀€.Û©¶Ë=ê»ÊY÷Ï2ʬlQÑl3íòA~A‹Ò¨ÃÇ.;~‡ûú• ¹ŠiÁ1€wò*®ŒÔÁ³í ÊðV©g1c¥!iÛ·z¶Å+¼ ¡dá)ˆ¾ƒ•ÜæG»ý3Aì„Ò3ã O†6SÀíx­™ÒwÅÒ é¹Â{Þ‚cq/2ÑlÌrÅ):røúJ!Lž?6Nì¬x¼«°µj§@Ö{ ¥äéŽö%v.}Ç»þ+ùEã\nø¢ùré·å¢_$çx±&Ä’5¬§øÝ{JÂADà‘=³n™ä¸;û©’;D”LÜo°»2¬ —yÜÚº Û©i‰ŽïˆNž0)AÈs4x-¥ØmâËÔñ‚§dðË3#ãåè.þlY+~Qh¯kKÕ庿~ˆŽžÅ¯’fQÓJΣzˆšä¬”ŽC²`+K8‡¿c®¸qºi ðÒÒ($¯pYl6…y·ËìÝxÕ6ÛSðu{ZFt=5¹‘ÊdÍлgz~›«;e§Ëz~ÖèÛ˜y}vûà7é[ën²à]?ïo×Þþ˜ë;¾,B»–Ü{ãïɳµ±2‘ôjgqIœO¶bâG§4QûƒŽwø«³µ/‡9U ìì²KOâ¹ü:}´ƒMRÓÔÍü<"+·/›µ®¿Ïò)Ô¥I­§Ô8°áÆ+AžÕ¦Ö:ˬ 9~,¯Uû‹ 7BQwÞ”Gzºé'âBêÏ4‡²“?I½oÏ5tƒ÷(ÿ1/3&kø£Çã‘—U–©¥á ·*kßÞT`Ü¡…@‹ÞX€.>Ê@›™µU»ÌüUõ$þ5Po÷¡oE(¡íQÓz¯E©\|}eZ N€‘í`”YJ£”þdü<- -Ö6…±³µ§ºdÑz8ΛÛT2òª|®†îßtUÐKÂô|ØÝ»íks¤'é ŠÓ$ „ýÄ#Á]+YŒÈ'òžá‘ÞYPÁó„ŒÆL‘Ʊ…!yGR‰H¶#OU/°ß§ÊÚ72ˆ“Ó”ãnQ4SÞ· ®ýä°V©žŠt>EÝã>ñ)þÕAdÌ86ób¹‘4RnA°VS8Æ¥aÝÔŸÜéœU¶+¼ÿ00÷ì5è¾ÉŽ4BaU§K¨ΞŸOö¾µ²°¤–׳íð[F-l³q')ÆUiT¹»íš·2LDÔ,œ&J-ñ}^3ôTókmã-/ ˆãBÆ<Ûâï¿|å¥VCGnê#Ü„;ZBEÉH>/»Î­#P±ØfÅ17G¯»Ý[\õõê”ã&øtrÌèpƒÜ†IÀ-§9ª@Yµ¹…ÄÌÚÏ0Ìç|*hCàË Š Ñ4” ´ÆrLwЇ/éç)vZ‰ÿØ@9V´$°)Ë7%Ý¥›Ó´q¼=¦ùUÖ¹Œ¬Ûò‘äÈê†;P)•Þ^VÀÞäó.bîÆ™1éÈ9¡%uÑXº,–¶møCŒcèðc´°rRŽÅ<ÅDvLuiKz´ÿf°¾×»ËÓ]E_].íÇ+P¶þE³;Â5ˆQ¯^ŒRüªÈ5î‘ LwYF‘ ÞSÇjû:?ï…jJÏNŒçE¹ÏŲ–Îk2ݧR´bo¬½,p»ùš%£"pÿP@Er–>þ@¸ì(Õ¹AéNŠƒÄ‹ëÇÉ ÉŸkˆ­ôA|“ZÙ•Sh®†ÀÐQʛ쮕‹»^•Kåë|ØBò§ß†gñž;Y·ÿÂÏt»³èSžjcTü‚õYø“TH+Dkº¹ºÈo¦#¢¥ŒD³ÌAè|Õ|¨Zñ.hWÌŒ9¡Ìæ…Qƒ:¿‹äǦ³kÆ)ù›—t²› Цý§¸&@À‰ß=ŒorÔÞÄ•ú—ÎÁÝo¼ì Å‚ÖAÔ«JójAUîŸôht( í®T6-É.lµF¦°¥½¦¡dÍWŠy›ÄÁúZŽš<ÿeþÈ·p‚—Ug¸ËÔð™1kußVÖÆgµ¿çã!Žß¼vËÝHèöSF*I²D36C™Ï{Ã÷d9vHå9}”ÆÏ 6æ ººÛY:G¤‡ii¤†rO0œ¿¢oR­'ĆÉÕ¦§ûßIvÒ˜;,öÁ!oë„ɹqM Ʋ¯ïË{yËb‘ÊLH:ålÂ{…Äv3ºõí5޵}¸²Õ¦'/¼œº7=e–qéT<­‰gÌ(¶3¼û*ÿëÏ™(½( *`"Ç·q¶èøÉnT®æÓOÑ¢¤0” ˜ïle|ç=šR9Ïé”%7õ³Péûgñ"&¡,Ë­z1¬)œR ªÙéÐTâʹ»_ÎgGK«œørÑ %‰4'J%lÈœ˜„óýü!ø¥ágOˆ«Â&+´³õb@‰‚‘näSðÓ|n˸j¼—z˜ª]èN|a^njSãè^ÇO¼÷þÛl-õHBÈÆÆ£SoiRKââü¨ ¦OÄíNÛ£b” q»š›€ù¬•GÏ{šk",äÖ‡dñÓeò4(ôŒ-@ÈЇœNôÕŒþuZCñŽ”á~§>£È…/ï·_T³f6î}á¨Äáÿ°>B{çLÕŒœÐ• îÕË]ŽzGU~˜ÏÆ»’`Ö*³/$‡èk<ç¨é}|çeú³Ú’·«…ÐD‡»]µº«Ñ‹Kl!CXD"õ‘&\U/'Ýyî“h‚›Îmdç‘!Êy»ºµ6ví¾„™ñÙüü=ƒîÌu3ê+éD¥u¥tœy‡1'-ľR#L…M‚Äž Jöf‹%wvN¸U“˾fj¼³¿ÂªÈ?I5ŠÁÛþz~Ãl[½V«¦ü–ŠVÌ ü(2<ôÒtI(î•3Q ôɰ¶u–Ø'&AØ\åRZœÑ§=›>Þ²±O²~ÙÒOÓ.“OëZ¬[ ן!¾²/Hý:ÉÇ}æø2a ¼L\¸?@ù„Š—ÊXï§-ÑÖ€åq¢þ<ø]w*U»¨4±ªü29¢ƒiýg¶ŠH|MS–¡œ9Y|Ø£C+øüÔI!¿‹ºÿûvËèÊÀ1ÏXH<å­6Wol^ ˆ¿¡/ÂÈOeŠªë×§k1Kí†Ðíœ_hˆ¡‰³oí÷“ÑÓâJØ«þHe:Ò£©W"´­Z¢{¸,±GÙ;mx[’ó|>߈8 …š:æJ;‹~Ñ¸Žºûêϰ éDnçšþlÙÏjµ­@Ð÷ÒœmvQ÷ÃüEø…^˜Ï ©Û”+ÏĽÛçP¤&I Û«Ðý@‡GntÂ"~q¼uÁ “^o¸8Œ‚NïÍJ¿Ë¿Œx s¶’ÑȺ6óYø'k'":ÆéÔ{1Št}â܉Ltx‹G8äR¹9²\GÖ¥äëð“ –-Á/¬e¦„¼öã²2ºî¼ÀM2fùÓTÔR¢ããѾ͈.®œ”tà^×› ˕Ê8 ÷Õ@VÕã¼mæ´…{ÞGüZc8hh˨DP(/žÔ)=áXÃâþtnÖ a÷ámFØÕ)TæÍ¥×nÔq «Xw‹Ý¾@o|e=3Œt¨¦ðÕ[ÌãS¿x”C@žµ7H=y[Ï«¼¨ÙM•¼ÚÃnlxNe’Oæü gZÓkíèBõÌ{iïi= aÎg|“³9Øèõ¥@ÅÙÙÌGKÅ à,–˜Ãíy)\%7ME×~íÑ„BnÓ—ÔÉ ¤*÷¡Ÿ ü¾tgRäÄ´§R±èaëiÉõ‘ÎîYg^õ´â;ÐxÆÕ˜SE´”ï@OQI&Üà°&ž€¶oÁº`£ƒnËëé;ÉI=(ˆâ”Ýæõ9ÑufëÓµ?åR¼¹GMœQýsêÌ=Ý;Õ|óß2ù„ÔD£Ö{÷Ë2RTIÌhÖ$’­ œÙšÛ1ç'Ïø{›9Š+“õú›{Þ‡êŠqé\.Áó[p…wme® #bD[ïfTZª^†D0Øxõ£÷lsl5ÎõÆr]Aðªp\”Íó‰÷aµyæÖ²FÊŽÙŽFäîÝæP9HÜ“…¨N݃žÏœº‚ßÌd\ oL†?‡¦®»y‘wã{À^ NÓ|9¿0ñõXK¥ì¢H^ÑI_Kf«ÌÔÔ¢¬,çå͞þOž‘Éãì†ó>I/ó[üb ðš€oçÑ}cÚÄ•¢Å_ÕV±Û|ÏÂ¥Åô‘¥j´¶"ÒO”ÚIÅŸõ< ±B!qàPŸcê]eÇÙ\6xŸ+õÔx×£üåàþ2/µÚ\›dσTsŠ)ß×òÅöÂC.íKfZrWŽ„ª–ˆOŸ)XÈW _÷¸0¯¬Düò¥W¹zú<:¶òÕyŠg ´ï/ϪVÛÿAþ]»íðªj"jI(STáÞ•lÈʾǓr»·´VæÜå»Ö®KQô¯]'Ãqt:¶ŽÁq*V1Ækü¬àr ÐÜ™ÊÆykkjvÓ}ëøõ›ßhÇ2}–ߪ ©›r‰M6*àìÆ6ttÁÝlTmâ/U3e/Ûo€…äŸÓa=ªÌ’´û_}ûD%¶ºSûÕòb§j¡¢êWÃÚËÛQ¾û™ÛƒÞä‘?x’ì*„²yÜ8k]U¸=Äù<Ùƒ¿n×J-Ù×Öú¼þ¿nãÕb­Zª•öœ§ÉR×9…Up¶=ÞwŠ7ŸZ.gDÇ 3/r’M†j…4Å¡“d1®‘7Æ_†NŒßDE­á·¼IàSêOúÖÇ] ¾ÝÆ2aH¨Ÿæ°õól¡ØÛHûWEW9TpÍCбì¾íñŽxÒñá:ˆ«O`ÛM•ùÔa¿mǬußW|Åô¢äÚ@uÙÛx™$–VjÆ ‰?tðúä~ô:ÿb1ÿI›äSs ã'éDžTù¸G¢ï¾ž$ÞÝ(¶Œã¹¼×t¦|ÿ.`^¦+²>xWè­’GÖ=ö¥Çsz@±}áá'ï{Ûl}E…8潟%ÃcÒ¶ 8õ¾j nU_IK‘RZ¸½|91ÂkDnZ­Ó³ˆÈ&'èáÊùµBK~Kc¯¼?ÔY·•Æn¡‹Ò¶9¨öiNG[*d0StKŠ~¼`õ¾Ÿ=žÈÞ«ñ0?"„íÔ¢£Žm*?–_ æŒZûZvË`ëWà {ð³C¥óÓ4zEVåè|ß¼5ÁèœÙ%¶Ld[·ð9Mƒ7ç!ïçF VOÕÀ‘è&4ù9Ìpè…ü"ãD͆ÞÜ™2üÆiUM“x&{ø…î§á[G?x.KÑ@䮉ÛvÆJs-hüi—‰Ö>OÁ.l _åXÄ=è¼íÔ<oe0Ûú‡ßVbQ½ù!¾ðáƒQ¬u•-J¨ÎªÕ®°ÇŽÛts<ñà¿+ãf\×îÀdæBÎï\•Þ“‘qáÅÞîºq7Þ¶FN*—øf€g¸LRYââ~e8ÍIúŒ¬ëˆw˜j½\•h¡¥[מJW_ T ž’{k]ô+šSx„+ï©j»Eö„Öò[jœÇ²ùò¶ç¤@^ˆG•oÿV`ç_M"Ê P6܄ڋAX‘v6$Å 3K½BgÔƒ­”~ y™d‡þQ\á endstream endobj 4946 0 obj << /Type /FontDescriptor /FontName /EZZDYY+NimbusMonL-Bold /Flags 4 /FontBBox [-43 -278 681 871] /Ascent 624 /CapHeight 552 /Descent -126 /ItalicAngle 0 /StemV 101 /XHeight 439 /CharSet (/d/e/f/i/l/o/one/r/s/t/u/v) /FontFile 4945 0 R >> endobj 4947 0 obj << /Length1 1612 /Length2 19660 /Length3 0 /Length 20501 /Filter /FlateDecode >> stream xÚ¬¹eT\]·% ÁÝ%háî,¸ÜÝ w ÁÝÝÝÝÝÝ]ƒ»»:ÏûöíÛã~ýýé¾?Îg/™KæÚ»vCA¢ Ì dbg·³1°02óä,lŒœ~ØÙÊ2(Íœ…ð"Ž@C…­¨!ÈPšDÆVV 777<@ÄÎÞÍÑÂÌ VUR§¡££ÿOÉ?&#·ÿÐüõt²0³Pþ}qZÛÙÛmA!þ¯•@È0µ°Dä4¥ä$Ôrª  -ÐÑРàldma µ0Ú:i¦vŽë/Æv¶&ÿ”æÄøKÈ `p²[üuºíÿQÑìŽ6NNßN3GC[Ðß€ì¶ÆÖÎ&ÿ$ðWnj÷¯„ìíþZØüÕýS°s9;Z؃£*ˆŠÿ;O¹!èŸØNÕ;Ó¿–&vÆÎÿ”ô/Ý_˜¿Z¡…­týË0±p²·6tûû/˜½£Å¿Òpv²°5ûÏ èŽ@3CGk “Ó_˜¿Øÿtç?ëüoÕÚÛ[»ýËÛî_Vÿ+ ÐÚ”ž…õoLcÐߨf¶ðLÿ Š”­©€…ùßrgûÿйÿÕ êf†æo†&v¶Ön )<“œèoHõÿËŒÿ}$ÿ7PüßBð ½ÿoäþWŽþ·MüÿºŸÿ+´¸³µµœ¡Íßø÷ø{ÂØdÿœ1Ö†ŽÿsC k·ÿƒÃ5Tþ;Éÿ)áßfÙšý%„™‘ùßB 'q W ‰‚ÈØ`jhý·Sÿ’«Úš­-lýW3 ,ÌÌÿE§bnaleûOë9þ­Úšü×äÿ’ô¯Ô™å¥Å5”éþë™ú/+…¿ÜƒTÜìÿ&ö?Kùagò¿ÿ` Û¹Üþî@V6.ç߀ßXX<ÿÑþÃòŸë† G W€öß’™YþUøÿ|þs¥û_`ÄlíLþ™e¡­Éßñú_‚ÔÆÎŽŽYý׎ÿ[ð¬ÿ5è@ +Ð~eÑΘ7À2%=Tƒ“=4!ªÝ×Ã1h_\¯RçSe×í²Í]nðVÈØ0ÅóÑêöûÔþ}_šö`¤Ûšª; x™KàIFÓ›‡¶AÙÎEwàǤWŒ”z¦á~µ »©Åɬv°3¡¨¤WôM8ÕÎæ{õHãCæ’çƒIþÇÙË8¹.«µ ½&ÿôŒ2þøñÕÀèðÐ`÷ Tï>>]V4¯!ŽWâ)IÈÍÀñ¾ÞøêÅ…ë篢?jãYBK„çˆøJsP¨ÑRh(Ä+¯É—"uVÑ;kTªœÍ:Z˜ëC¼(ÞH3Õ×À|3 пz€k€£à Ùn®wÄÔÝ2‚¢Ï€m6ãç\?ˆúîZ²ïξgÛ(Ò³ƹëOD6 ØpÓF*iÌsîÜiåݳ ^ ûÓH<ͮஔUèöNÖqÍð¼ø­ˆåOÉ„Dmã–GwV ÍS¥LÌÁ:ì=\<ÐÃÃÁ‡KÁÄÚwZ£ׅÄä›ÙIMI´JIúìhoöîm2Ó'öÁ”¡áôš#?ÍÒWÿΞ9‹+L·n¹µ‹“CèrLX|!£ = Q¥‚Y˺lÉ_×ywä& )˜%Bö¼U#šð%hQ_HL~»X꾌_2&X¹:g]Æ‹"Ü?Óë+QÝMf¹àÏí?ëà{*÷Ӡ̢Ù×Ò”˜ºqt|0G‰û‘–Ì\Èó ÂpÐ’åž Z)šTݔԅ\=ºñKW­¶§íY[¿$Ø4–¼’3¥QTϯ`pºMNÁßUNIœ‰‹üˆŠÿp9 w™×2Ù­z’ðƬՋa)©Éψežx†&ö$fýv­Œò9W±ÇÒì0о§ðí˜BMêËÕLýNHÒ`Kbn+”º­ˆÕOUdæOá¨8ó!;ZQe‰è÷æ™?ý!ü_Õ ÇxðÛNÝÇ…~÷F_(«gí à¢1² m-Ÿœ·˜ã“G#î-ýºbËnP½óõxÄe ®äuF8èŠtµö { ÁlèÚþ!InQeóUÀ[²’-L-$.’†³¥¼v"IÇf]‹žù”p:)$~ö!vw²™ñiFÑ}ÁòYäséþjë«5£¨Yë0 !·6sl8˜gÇ0Ì)æ=ù ì›_‘¥ìÓRí®ßtïèmgº'‚7ý¥FeÆ>«¾ÑÚn—u[Yà¹ç#$uïc†›¹d «œ•ƒiE-¨5jdúŽW#£~õ¦¼È_‹´ŒIói>Èá#ÞÊMXø$cã4²°áàÀ2XGŠÒ‹Ar¢ÊÐ@™L[ƤJ¹Ð)wœ£Shw, %éVaÞÄ´íìÈM#hìÎÉ'Ä2ÑbbÔ'\]`¼÷xÍù绩H(«áÑHn!”Ûž¹È@wU@“â—Êd/R!~4Ëö3*ö|Ô°iÁøg2àìx ¢‹y:è*êõ h<æS1}Þ<tM¸ª@Žž Þé[Óó;êjÖ»^y “GB]ƒŒ,BM9¿;›z¬sÊîyE<èÛ[öüj'§[£jé.áwÔ蟶íÜn²­÷K¿ ¼À½·U|ñ¿ç?ÔÐ'²óè5H9òe‚„>ʹ&âíûçW¯svÚIfHÿD#"†¿²àG½CÙI ¹C4èŽ",ù³Í›º™ˆg¬Fþ¹†ÓÒ»ÄS3"„ÒÒF_—ºÌÖo*@Ü—n²pµ“G¹¹“w 2Ìñj)ë³æJØ™Öà³æ±¤}Ãa’†Î—ZsÈ{-þ±¡Ž˜PuC¸Ù(´ н¡4iØ}(€©ºØ°Á‚î>°e ³áñÌæ¸ý­´õé,S©¹%¦ÁÈSâeµ NQ7 lp¨Ø ÿŽ%а†Ù¥#ÿCê¾iF•Žê}ž.ÃÄЋ¾Œö£ P¡ù¬uúqGF}±¬.ç–!ü¡¶€]’˜å;§eú:ö:W)ùú©®>‘<ïc7h*´És“•èû÷eÏhÏt ì!ÉM‚ŒˆeYy2HEä]cXž!œD,£»äÕK±(ƒC¨°2ÌSõo!Øtf?™ºGõÚ”=xDùáo¥R³Úi(œÛMÉWºS;ˆb×èÌë’ŽÑ åÕeJçúÔ©5™-Íòâª#W*ªk,ðRé°vº÷šÞš\„©ÊÚKeEp02‹wþ|s­©¾žñP< ÉKk}ô;Y¯™¶—Çéì}!vk¦X|ßÈ ³GþÔµ ÄrG(úYZ[Ä0àÿÚî%_s‰ÚNÆÎ|LuyešPòÖ|[¼ }Hf| Ä ›ÛCq—)Ú¶’£×7Üx*#™˜MPRv_kñ ó‡9¯ojë×ÈhÉ×ßx*ÔßÕÛÊÏìåKc{xQ2 B°eU™>×~@XJ¬ ½.Ó[)+;Nò·‘ŽÏAå~^/tHoP›-÷‘¶Ì‚ÝÁšÙè¿ý”’‡xkýÓãvP- íÞX b—õ´ëÄÔŽß0‹—@n¿]j£ã?!lúnS_E|Æ>ž Œ÷k(¹”wò ©Ö@Øü•\{z¬Œ5*åKGŠLÆà‘c¹©àüBâõd»×O°Ë„Y”Ȉ3–…¥‘å! 5½‰¥”Çþ³_.ÅÚ(XBÝæç›Jï´¾˜Lò*XþæþvUo„°!ÿwy½UÚ^Ÿô/ ›Yqb Žé°Ç÷ÀË>¤‹’Ù^ÏÈxmaŸÁ6Ϧ]}„4%Í(ÀV}vÏâ:Òªæjº@î² Y“ÄÔ[3ÇEûÕÁ‚YS¶è‚¨”ß&âŠô!I3"Ýé©*„ ¤¡ðÅþ\h£äïòÜ5æë§Z5éܦ ìè¥ÌQÝ5?ú=S¬•Þ?ùÔ8Ë9Y”ª›ð°¶SEPÔÕhóWdÎ[+â½þ›kŸ¯Ö˜Ç±ƒÈ±ð9 ™ÔÞqÙxó$ÆÃÞäé‘ßue°,iýµTŽ/ó‰®Q8‹C#±®~°Ë”g ÿ.‹…bü—ÂàÂjŸ´¯T¶õ(þÑtÅÞ£ ¿AÄ‘Áss맇.†+²:jáxKu5©øÇĵ][Ù2t¿ìR|þ¼6•Ççs1Ìñª¿hërTT]ãîÓd4 û‚)6á ¼:¹•Òˆ†ÉGsr—B·s`»ôÌK\´šãë$ëžä;£ÁB/"Û ëۗϰPŽTFë²ðQSK%dÆ\¹·Æ,eù|YáðƯ)‡Q±ëñ~»Á)º¹U™¶BŒ¼P\»à@9"õ’ïÖ—«Q2™U«À7,=ÔF*b²!åd‚‹{Èu±õ÷L¾àßÀé,»L“\ÂëGbÇO¥’‚‘ÔàìoGÉAÎö²'ý¨rÔ7-:{Äz?zR”Üå§éˆëîKF'Â}¼ÊÒ–7–±ó"Ý7ó}‰$ékr‰¹Íº×ˆõ¿>4?Sˆéæ9³õÕ `$Ét­‰"VúͽWÂî˜Áƒs/8´ ¬( Áûñ$BöO_Óý`éÜ`úQ7­ÔAೂ2‚ÌPëcñ 9?#Þðº½$ãHF"¨¶Õ”æûËÆvÇ'ÓµD29ƒ÷èV ¥Y~ÙÙûó…TAÙLš«˜³™RaLR:3§/%U”cÉmÝäÃÖÎ ½ûóÛäp÷ƒËo-ùaõ.ÒŸöàŽ(9ÐÈ}2Eñ_áHÒ«¨n¼&0®;g«¯±Lùí©Ëá€ÉuÙ­@Üœ†ŒÐHDͤ½ÍûœâìN²}…ü™#E«ØèbÉ7;¤DBj«Q˜Z=f<y&¨ Ù“â„í,ˆ #)VûBI[yM£Ó¬´Á›9ì•áe& Ùuf­€ß¬ÖšBùø,0ÅH¥ i-—½§V 8‰Ö~±Ö¥t¦Ç š¥Ç[¶oËÐsë£iöå}4”(Å9HGKÑ CÄÓNj˜@ùE”°a£?<øôH­R’æ¹ÿº¢† ªVÇt¿¼;°¤]¦CÉ7¥eñ /÷¶²,¿FÒ^¿ýx¥nã™wj,í' Š©± ¢¥\<ë„ÑäqôBú•强#ç„ÀEà_E{LTô>ž8Ó£O;UM–v+Ÿüö’’ÕÒ†ˆ%D—Ó«ªÓõàOÑ“šŽ:%"vx"Uï\JÔ/y‘S³€[IQ%Éøe\båükƒ¨ #¼XŠÕV`.¾I0ð¨”wëÓçì@u#l«/ܲ1¢¨˜®KaòPœhÿ"^³’ îPà½PZ¡°è ÑÒfÒx©gzCíEw9‚˦ñ´4+æ’£DÍvÆ0t‰zB‹³õŒóâÌÛ/º“s–\>¥pm|-SÔ7ß›å¹9†ö>®$tdÔ¬€Ìgr…h€‰ì¦•Viq÷Ê  ‹ûïZÍ¢¤B÷¦‚Yd{||ÜoÃŽj¼™ßä²Î£Öñ¤°Å(œ‡ë¯Ù·¢6´øï?jˆ;ézàêÏ†Š‚íodûsÁ3”® óÐT&ƒÕ´DŽ ;9ȱX›%6B"rðÐ"ðçøÚæ[´i°€ÏφóªÉÜC¶÷ø @d’Hjm‚Ý̽pÁ_éó…}OhE²†…¸h6Aév7¬¯O4T'Áó¾x¦žÞ úbÛh§= … V5” K=8“nB×ÜK#ËžÊð$ªs”ÐoLQ 8ΡŸánJUtãó²ÕºfÑq‰¤ÆNèì·A1Z±?Ûj©ÕdmÙP²/¦*l”ž`uõPÛq Šj¬sûHÑ †LhÒ¸=ßiFLÙ4Jê ü5*_™ÉžƒSÙ˜ ª1Ôä&ØHÖ†b¤/eÀ«¿ų eÚ…_‚»…fçðQë1(-¦_½Í7,Uþ¸^oC~"ú%¥Åâìîòˆ]‘EÐ,5‹A`Rš:…÷¹4#{вîê‹IÃvLÊGè:èÌ:›$V™.Aa‘eZpi.^šÕmz‡g,šðw‘>kŠpGR²^ÎíÐì¢ýq0*w•>¨@Àœ|ÃI1þ6'ÿdÇ=hFö²ý¥Á$‹(°_™;¿oå ¥›Ÿ&˜m¢áH6^ˆ@ô1˜ú“ÒlsR+F«%‡˜€u—ðIÁë "›o†îþ'9Ï6‚ÅÜ/5zvx²ÈÕsL×?z˜8‹¯€É¦Â£Õœþ'ÁËËL÷k —Ÿã”êøóC[Ýâ]-~J+êÆ>ót;Ê/ÅÎÎ&Ä[3Õ&.­Á©ÇÀ:(ýùˆIóÇûáæýuUºnãÚ€YÅ~½G•RöÎÇÞ_`Ïî{–ó…qòøs.Ð*0…éeq7$ã—©gͯmoâŸm‡3Vµåð§¡Mæß_DNU'ù>ža¡G>"'ø«öò§pÏ&íïår2׸«±*×ì(?_£5ÄL»I8„!E3J"ÏÏJ‡ÆƒCjAµÜÓZpɬgÆí»¬¬J©eθ%M"×:œñ&§»`æÝ>pC;wKæy«ºÀ£D÷ ±›Ì¶šÇÄ .o¸\ïºþ{mÆ”~¯Þ¡¢,Bþ7BOYùjÕÅþì«p‰ã˜[‘m­w°\ö»~õZaÄXÛÞI¸ªBØeL>½ä*ÉÕé[‚Ð<¤‰åoå±ÈxpZ¼Ã g#³" Rˆ%g.++ÅßïH¾t–AX×Ǜٖì:¾í5ŽwéíùÄ_õ½ž"_É·ud(Ojš;Xtaf~M Ëåö÷ôì³3_ÝÃâ2fè·¯ Õš¯?îŸ øÿìKD΂hÞµZG7A7NH *›ßJ/P Hwº 3)hÀV¼Ž‹FZAUœ$’õb÷!5U0Bñ¾t p7Ï4kú¬-nØŽ+!‘Êdð¾xêpÏ0K 1¿kFHós€.×Y =……ûsAÃ#~¿tˆ™ñ+Æé§}ðýMá<š ©߃Vþ§¡¤ü”þEÜÎñžM™Ï´¼÷a†öô¸"^¬†ÊÞD‘’L;ðKl®¹/©eY²õyM4* ò«z˜Y9ùV;‹¯]ªÔ³(Îc‹©Ê¾²^ë ³ ¾‡¨ò¤M}ÁÜ}æQ•ªß‚ȉe»#dSv¶Æ#òà´|¤øUùVBO÷pé„J²Z êmÖ¼O«}tS7Ø‘Æ5ãz¯àª%J•ëKU?»²ºeVƒR¸$C5¼#õ!HU¢z؉¯Ðý¢Á„õÜYßr^QÏ,g4äº×ö†ÂWœ²g¢ØøøÉkªµuQf1žérâ¶•Š!73Êï¢ËúÊØ´ñaÄuR2a ð{ȘBc’²I©þ!ç?i¸JÚµÂõ1EM¼×üeÍgDV¢#ãDy«ÔÜ©îîÚáT³÷prz\`…£9 uö¢Üo”Ý{FþJÅâÉbï0'¨ÍI°©Â[èrUÈJ­„îô¾áé˜Ôl¹í ‰‰þPq ;Øjp@B’IebÍ_‡L S·mc¸.ˆíB0ë!£÷*Å„ßÃ=š½RvšÞûÑ©˜[w»#Å–y‘k!%oôç…¢ð¹"±« óñøäl´jÐOÓ6V½÷ïÅ8|$sG‰s•×Ò“r¥”¬Sîëå{²¡Xk”  º2=ai6§ÂÊfÙκŒ…¿¼yŠJ¦Õ­¿1xKU8‹Û:þi¦q› k_Cy¿üÞ]zÝ‹ác-µ Ú‹w˜}Ü÷ðs?­_ ¢2"ÒCR¯-åÖÎÉç+ŸN”èvŒd1»Úþ`4“ðFN¢Æ¹}¬¸Lù##G'Q=Ƹal»kzË/ÀîŒþa­`pÓà7nF#š÷rçÁ„\S’‚¾k4}öñÚX6§“¨ÍŸ‘CpÎã‘…hg®\…;ÕÓ¯Ñ;!:NˆðÈ=p(†¥Ìèíñq¿€A°* BŸÀ+4Éf••L«l 2¯šÈ2ÈÇÆùb«QºûÇݯÔ]³„:Â;myœ™åÜ~2ÉÒ~ ¼(ðl)YºÛ´$"iu*1ü#›Ý°Ëñ„÷™³ • uvÎÏÆ¦¨¨P%/*ÑC¡½(£(‹5*ñ"Fÿ°="~ïk]¦P•æÁ ­ïOƒ¬äX7$ƒÞªßk‚~³¸¾M7Ü8aLrv3ž‹\ÝtÁLóóð°$u:ÕÝ‹Z¬æØ9é~¤ë•ÐØPdrú|tŒ÷"M5¥ž^¢;"\ñõ83ñÁ,5âá:™.öJwuF¦˜'M\¡ãÞâ'W†  E(Š7½î¦v“Zðší“s“Zî'w$|Ó4ER‹«°QLä`? ©WNp’êùTpM+Ü+C‰3Ê=|Ž‘¸ÑéxZw#Óts8µq~M¢ü¦õž»ÿù¤¹O¼ï¥O×—èJÙˆ‚K†k{ÁøÔWÂàe¢7oœ‘{áœeÛ;È­øͤAPIu“n©Žk:Ò+súúQ2wºB¢±šÂÔ÷³À$´rpBE‡0!ϲä»ÈÒ:.ÿom$0.è¶SXÔ×nè^ù2‘j+rãŸòÈ«çè›þ®7ëÃá³düé¡ A·?Èå ÂoÈ+ŠqõŸˆ’t¸ ý*¿ïx ÔŽn¦2fh*¿?Ì_ø‰Ùé_U›\³;,6°bIªÞÛ/[èVÙò+ÐÓ¾`jŸ5òwƒà ýÏ¡9ñtBaÞߘÀ(èä»’íjÄf­6F"‹xÌ@ÅÙ/ËÙûHöB¶®¨[Óía˜C¸:Ô xѻ®¦µ‘ÚWÛ¼ ¹Â•¥³z+÷“ôS!7/D¸Õyȳ2ØËßé»ô@Ïù¼5‘±ª¨µq~ô%¾Y¶’”?8.ªd¬Sgù|aÕÙ'°)í¾ß̈dà«1áéÔÖž;¸Ãç?ü•“ÈóWJA+Á9±¸øãJª ²™¨ôÜímöf®2¿›Àºw8öøõɘRoÒvû–UÒšÝ<”ˆ{0Yª5ÀÇ3ÝB½D5)çÕ½À`WœwZâäfa…^Ñ[Ö‘>¼ñBàÛhp±åŸÈOV{¸.ý‘› %9©jrW#©+zþØÇðÛã —å%zÛØr–÷‘ŒH{.©Y“c?q™êãÂK ˆ)Œí9SPåYK¾ý…‚[9L¶j&ßÉž«—‹´LEq˜ˆ4ÆùÌçYãSxdKKgMaÂ7 ŒVßtNá{zbHLãß¶Í6ƒ_ÆÍ#ýHlEöém%ò¨;Þû^,’2U&*Ý»ÁB¬!‰E{ÄÊŒ|Îþß~ - ÿŒìüíL<»}õ'´I}"¬Ÿ¾ YÙ&¶Ð‡Ž<€s¨ŸJRò`ñ£×N}^³¤TP¨(Kêf°¤’JþWj¯·‚µ,ù–F<«Uͦø§¾©/êŠùÖ]YÇwÛŒSØëÒ-ë©LC±†Ü/S‹dX;g¡â®Cñ`~œîÞtZi¤Sþ.~XC(Ÿp†FßGx•~óð-¯YÏz§õ¦Dó F>F—ðØï¥™ÀÈ ÚùÁsæü@òI9OÉ‹,5jžbáürðLí\Þ¹):À´^£¤«Ë9ÉЙ½ãdíÏDº‚ñç„>QúÏ4gèwÞ£3¿áqSƒZÇÜò+Vôf…À÷Â׬çUc-D‡ZÚÕP(¯iº„Ì1‡ùüžaãdL:®Úõ²[“Eiqçl²Ê†ö}F5#yãP\]C ?Žñ‹4Ûf¡JÉõùÐETèP²&¤Ñ¶Ä6užp¬²éIšHúorÍ-u¦Ži’7=ë•YßF#hš5KèÒLΤN=U2mx·<‡‹û–ÇB-0έŠ{¡¥¢1 ºÅ´ô‹ë!×­Ü5¸‚A,[VD¥ÒŸù¦aÙ,}/Ïm?V¶)å¤ïFPîÆ{Æû…Sú£X[uÝ È ¾[(F…åàûæÔFÙ/BÅ`=>±7ß’dd©¬‚mä|ÝÕº=[y¹Ã}µ ÛÒB† ˜'*K˜t/ §*½{GR™·Àâdî‘¥ªøAó©­‡Ô Ï%=ìÁöºUæ‰U%EÊ  b¥Ìž&Ûß¼éÅÖ_ U¼sÃÝZi¯¶±+6¼¡¡ƒÎOËr÷ǼG¬ÆŸÐ~u´éÙ×­€Pï ÜbÜû–-ð†Î˜3‰Dm+ƒ¸ó½‡³G0‚¿q›&ÄÞõÙ¡™,a‡cRä4gqx!µô؋߫[À#= + É+Š¡Eü /áen? ,ãÄ H@Þ² w6³p¿„¢w_“a®žìâ²óm‚NrŸ¶~³ÜH9lr×J}f€ªXZ ¯b7ß™¡ó#>Þ ¥¨rP!F.ójsÛ÷§f…Þ`¯V”ôx¦|NqNË ¤wªô6ŠeÖíißÔ>bÃù¶Ë¥Æ^]ƾQ|uá£3œ«K©B.ÜäÓlsê¦TÉ3ýLÙù#ó0ª ú¾ËÍTµ¾sfkGÛ”1„ÛqÌ;ÐYÉèjr{@R9Üc1`%®‹®†€_T$-„‰%p  gêýy0vFR»¢DÞžÿ 2)N^ZìCö-P”_Æ5›WÓwëâcVœÆ²¨d_áV8ݲHJ5ç}ï®ÑWöð©ÌCÉ5N7÷-¬¾"° œþÔúõoÍŽ6#˜× üé‚f6æš{¹¤JІ Cdò?§¬­h{ó6G9‹ ¡ûiÎv÷?yP—ZG?& Ø@;NYÒDí.7@­·)ÊÃ+¿§øC6 ©Ã'è’À“óK¼ÝÆoÄÝšX=>¼Î®àæƒAõã¸b³YªÃSYºzúí<¨êðÜ¡Ûç¿~±V”Þí^ ~BóÌ­ÜóE ­¾;„#/«!ÛƒÛ®î_WÑOžaðÆû"w?éÌ÷e­¹ê{ŽÚ£F¬¾tÍ~ ´ò5¤ë«‘Ñ;1ì·”Ð*dÍQ”™ªR¬èi­éš~ dßæ°=¥Aƒ/ƒTî¢ú\2ïa «BÐðºNÂî¾õiʘԡ°ØÅîkÎ>ÚðÔÿñ©›l}®½ú!~þúð’ÅÈïH'¥-Â/H¶ƒÆaqþÍ%VéÝ|k/z#)KQº_Öšyú{­ YÙ{DC¶ôàm59/+ØõÕß{Žª^éü6Ã_w»¡9Ão/͹·-êJõhÓ6Àm˜V±…ç Kùàynåq ãʸ ¹Ž-îŒÖ›#–à ÜQÄÁy$z=Š /à“˜¦c•Xñ´¹¨lp’kbW*ù®‰bõÞÆdn´ÜäâÄñ}”iú)[ÏÚÆ§Q»"—«¹PLê5^Ô̾ÄâÖv¯:TiýÒwk7æ¢K„ñ;¹àon4«.’—ä3Šß 2×cn’ŸªôMÖ/!)i qkÉ®?£†Oá9ò ÈTåôŒë¬¥xÒ~Á—eQqÆ[2¸—DÞ Îæ P#=ò ¡ÂÞD\Nø³_böAÚ3,NlÑwÐzî+JGjºÌZ ó*ÅC¬?³¼®– ^“/¬4 °plûžýÿ8Ž”=ÒãD£2äKeÅX¿VßÓ>ñÄEatÊX7Wb{Ðæ ì åïçÒGuŸ (þ&sÁ¤‚ñÙÍá‡s2Õ…+,òÕµv>ÞüðÕÓpÆå@}~½´i„qMÓW, ÍUs©G&…²¡g£În)×î=žà„—X8Uºƒ¢cË•ÊtiXKF漚‹…§œÊ(‘\[цÒBÄÕ÷Œ|•±}Øy£éܪâ|-'Sµ ]Ÿs¤ô#,ŸÌ«7Å_«ƒ™¾.NAªvüv…,„err¤ßݰ9R­z'7ÿñ”³ºøžJ‡m]¼ d•È’<:;Çw#›DØñ˜2ç"‹@P¿¦ ·æ-7 Y© UAYlQ'Ù«¢_F3h*,§£¼¼Ÿ Ÿþ‘t>¥U-Äu1=Yéüz¦þ¸š4Ñ÷¼hôƨiÆ¥Æs>Öí( 7u¦;D(jP/36l¥—IñØ'eÞð_2 y™0CòWC1ÖöUìO(Æ1©b`ìÒ®IëƒT§mÙ5O2±9æüó»d^@³£GÅÊ÷q,¦ë/!ûy˜ÌUüä· û¢Þ3¿_®ÿÔÉþ9©¬EY:7춘·âÂÎ0©c5èGݼL¿„‚·sQ ÔXP:bá’v·£ÊI¸¶ÏpÕÈ^#¢Ž9±.”ÁlÔ¤~_ľœîD“÷ßÀ–·è`Ru®åÄB”†A‘HùÑ®z‹[êr§ö5ïçËR‹axŒ àü”«Y¾Æ¾wã׎vèŽè@ Á Õ`u;¶DÑîÒŸKûÒOqÈ”ýzîj–•Bê§0äZaÅýLêdú3¡ë9…˜Ù²á<ØnÿZá˵5—†wÑ¿w8¨A¼a—ÐZYŸß¨lX²›ÏÄм]’ö¯“á•_/æ„öOôǦWQ½Ñ#§°sš¥À³™·\4XPZf2Ýåƒßgï\¬é‰.®5îeò—¸¶Â¯ñ`I´‚GÍc\ê‹îDâĹ²npXëk‰FY²z¾,ä*T­YÂÉ!P)^ x>)üŽ›ÇðÈ5Ø“…Æ Eã8Û?o8·‘Rf99ç]ÔC…û(]Sß~sR´uŸPÊë~':á‚«ˆ7¶rXÙh9àAIÁ 2%¶`ï6Ëâ ]ºgíh¡ o•)HÜ}ÄÀ¹Æ{ë$S0žŽqÉ1 ôÖ¹ÍÇÕR¡÷•%º;Épö×¼æ\Êã K6ŽåãÕKsÒx—?ùw+ï„]²[;xDÛ±‘Öˆcz–ÍL>¤ò6ÝðÈdj9 ö½¬ÇOÝÉË{oXK??Wàú´¼™™L‡gE'…âÏg]­ýÁ™ä>‰tn·©Æ¶õOï†gÞ§é "&“]‚äÝ_*w0®^J’kz·¨šW¿=ÆD¬Á¯-¹üˆìV$Q«’¿CB—“7Rm¨2Åu.u7"^ÆŸø³¶š~ðdÞw~yãJÍ,Höýô Y—I ¹÷LŠgî$–•R›.DoÆ¿S¼tÏC›_O5iÜþœPª›4íMúÌèYM̦_|ˆFqt¯XÃ1`l/X¤ŸùãD?"˜µÂª²™éŸÏˆ/Õ!)ùkU€ÿoTñ© K°¥AuX¼îBfË}]ê{­E|úcæ9æM“%÷vÔc5˜ +²HÝŒlÌs–jXVE°¯\\u“¯¦PEi1vGžŠ*!f/3Ÿáà9–Ó±Dq÷ÙÑÞ×I¾XŽÙœp:DÃã™Yy@Kƒ°õ¨4Ëïm6ðLºìsz'VjNÝw¢ÿÚB#ƒ¹YFAqªc«e"R¨b =™72Š.U†–Exß>-*ðôIÑŒÎã°æ­54J—yôïùùµ_³z0Nйþ§u…ðì¨îÇôëó.^ïW¼¥le˜rÍ$‡å["øŠæ7KhÝ׿#0BÂ9šh´*9Öý^¸6ÊÚT{K¾Iâ{_E‰LÕvW¸‡Û™ O…”=„ì²ß?äu áä}OmFmzV•Ý:Ò“w‘Qr¾ãŒj¹±HOÓa“Ϲˆ~}㩦 c3o;?¦_û^¡óNKHÂAÐc£FBß´€ÝìP‘á!·)‚á^JFëh<œ%‰X.µl”sJËq”«ð öXQF6*Xšjô¨“õž‘ ½HÙŠóø;?FZëi²ç&#òKà8Fa)·­Æ¾>Çx~ŠHRØÙÞã¹ „°ó¡‡úJy9±w #[o6#"Â÷…í ŽæÚ˜’rÜAõùÄ4—šáœ¬«ÆQž$åÓBéø¤zöUèx[Î|Ó?‘°!ø4Ù™³h Ü‘ßvþé’J3ÂE© ñÅUõ²WêY'ðó~™NÐ[µ yͲÅ0GO™G*Ü2äûsçþ›!ʘ¼JÄò{T…8ÎiòÞ$ü¥´ÜB[8÷¿½¶öH÷8Ò æ¢Æ“›Öü½˜Ac£À×=û޵|¼ãÚa];#M°Ù|’wû”Ó¦ +üÝËβ cpG°¬êÖihQÞ.–nƒXÇÌI«Ò¹Ø éhI3ÿþ‚Íóõî™6‹-G¢KtRˆ?6gÏ!ì/|Q´°n•íï÷bÙˆ×ÔÕ"êÏr•rë-nš0ΛԙÂ,il{NX(B ØÏ&6„ÿÊ_"íãÏd+¾û¦ż6“HçyTMÛ)C½wÑð]·õ¼ô›ÓšƒÙoé“WDã÷ß­Ýá&‡ŒyXQÁÑs{n‹"³Ú4õe–e]o!ެñ¶ïÃ|Š€ÁûV½÷ÁO,9XxÕLÓwuÑÑx|sæO†‹Ï,àóÙÖco¹g×¾j8]”œ¡u½† ;’¤å¡å*]ë¹ðاW!ÙQNƒ(2ùYžM¬óGÁ¡ãü[ã—o¿CÏnë—5Ÿgu=CCÙ½vc–_êï¼ ç#&\ûÁ!iÅ Žãž˜6z:W÷|D›÷é3ƒ¤ÌX¨Éf~DË$53å8±Ãb- Ç"7Úk«)”øQ+×óo“Ú«d¯ª c?åÙZz¬{r½–÷V'ϤS¦‚aÈ+4bíȦÛÍ™X:V‚žÀ{xœMešìyjû­+Î_°æWmý,úªàÉØ%BµÑ¦¨Èü—”¬/ ÊºÝØb¼†œ=Ë~¬¢Íræ‡nDð»®ÔæÈcûÙáS•N»=(í]ЉœTödâÐÌŒCÛŒâ3§O2»çä.w·o€œ__Jk¤¯˜,á“ .&´êâíêLòfUÏæœ‘–µõH¶kùÍ‹mÐ}UÄIZVÃ08”8f‘<Ñ©V¨œÕý¡ø)«9[ø``ïlK ØøpÑUÒšq^u°-·&·=-Q+j všŠ€cªÖÿAÂtî¦5°¶]_ j%råpñS…ÄˆÆ A3 ¸uØ<0$TãèËDÞΘJ (Ü:hÉ‹pŒu†NÉÚ1ž_k•䫊æ79zTÞЋr_ wŒæjºÞå÷¯å½™M×5<]ÂN"öY}#2Ú| yŸí°¢t<Õû5î5ú|Ž=fKÝ^¦Ji»ÃnžÎO„ó"HÂ_÷§¡7E‡Ï®º$Kjì‹2‰Sæf¿~Æuç}æ­ÔøvÎjÌôgs ‰‚÷LØf”?ìNöG$nåh ¾AÙx\úK-ÂÅ%éù2ÙíŽ « O•fi«=¡>\–ã‘ÐÚ„_Å|\؉Ø7{ne„íñò¯ážôá7)$º6³Q8—õŠþ*¶µ"A/õ;¬V¼X¦*N—ÛžS„Åò“ÆàÎC(I§)ó=Ѹäá%ü²U)òƒHD==•üb=ó¥°“\ñê­°+¨¾æŽ{Gl܇ÊÞr¦•ÐvÂGÙ¸¶²7É©UÑY{°tÞtšÐõûp­¶HZH³2ï&9§ˆ±÷Z³Ð»‡n˜†">0£üËnE{ç÷»ûé³›TKV¢„4 ø“,t¸…ŠÚý•Ò¥O™T£û2´5O8™ö»ÚÈÊ\À 0˜÷L©Êâ»úMø™ý£6yº5ãH©IÝÙ¤xÁ±þÂÀ^¼ëÍä´åf§c³@….(Š€2B `Ù¬¨…½Ø'Kc Gêe œV'[£ûèjŠß¾þ&ÆUšùÇØŽÂv˜Ä"XU‰ùV¹SÕjûÅPR„¶Ÿ5ä€é9ÕõÀ*•2`_ Ø\pΙ*eZœæ´XEÞ«ˆVuì ½U}dh<«lvôÌUUãv¶@”Ä_¥Ÿ‰WiÊX€øå³ôÖ¡ˆºÅêš—‹é%q½–å–hï<Ï¡+ùhv²y¦1ÒÇoåÁÝã‡gTé’©jh8bÃ}ƒ© !г¾Æ÷mÊM| êŠ&ûƒJ¬˜Q¹¥‚ºT‚®—úçÑ´WŠ:ÄêüÚ×½+R°¡W&aùãqi?hÜ®Uå¶iÂQü˜^< º?ÝÔoã³ës©KHluï'2÷ð9¡rɳë'e­ñ+DË^ë;2[^$t¸FUy÷+˜oÓ°ôÊF³±ßÈ[‰±óÉ¡l{Cž Áw¨MLl£×ÛòDÈê62ѨZF0³ø·´$EöøsèÏøSÉq¶›ýª¾ÕÓÚ£…,Çm!çrÙ*p'!]åÏ0µ¿!zv ë§aH®òbwRï¼ÃÆî”@L=©É+<ä™Í§šÁÌ~åéNý¢uð.5CIVáÅÒ4Äà:îÉße6´êä;€ûå~y´³ W:=Bøc~TÁUyÑ´·,ü±K÷ËÙß0ÿÁˆp†ñ„„_ÇI#îÄÕ å=ÎșcPVeb¨Æ).f›r¬6oºí&ÁKœ‚÷ZçŠ"WÓ¨Zɬéh.G.·ãH/-•L‘M¨ë‡1¿úvü™•pìRµA«úïæ?¯QOý¥¼H³Ú;‘Ôkùòï•Û¸5ÍñøÌõî„T (—ꆙ* üÔÚON>ž»…|d§‘°…ÈPh9Np¡-1kJâ¬ÍúE啈±!­+øÁ¿ÜÇ8ìU5½ÕòwÜÝ \Šå:4+¿/¶y³D**ç|=XpX€Ráð¯D/s(}^ŒTçAêKÖ»ïfsi®É´TSÇ»øŠãð½¬5€8üÊ¡‘VPknšHØ«*ÑÅ'ÍÀîÍNn:Ši0ðÅ¿‚æe2É⫝̸~LÁßÝ…e+m€Ä=)“ËT¢_Mm*ož’ýç‚‹ä¯t(G]”qhÛN¶dw¡ù`vÓ„¸{­äô/WøŽ"GÂQ´Úµ¡%™Ïžé° ›óO=YÄ2ù·öáÀJY3Ì€P?E õ<øæ`­·Ù•ô ÷Í ¤8¦ýµFXñã÷?ðQ÷kþý/Ô¥í± MÀ’T¬ƒ©t‹¦¾|…ôøÓ9MV5Z›€ý&¡ëª*Ë¢_÷=¹­‡?³’³4ñöuk|Ý^¢ùÜuZ`ÔC3„ÙZÁ©Ó¹GÂà¸"ëxc´î…õµƒT¬T@ð%Öó*ÁȦâwœ&Í Oç‡'¾RÈt±=[Wþ‹v “Sý¤%(›\mï5c9'ò,ëØq„qm°›[-³¶ÔÙý©ofïjs?Ú2GŽB½k/bÕA=Ì]‘Ë/‹~èÃcåâ;ö5'U*sùKǧ±žtƒ„mR„fOjN¦ZJh½‰8f%°‚¿f®Mñk%Ïa‘sûñˆDZm»Ü=dÜ¥‡G ÏÚѻޙ%_ô@ˆGækë¥%!Ë‹çiOu/ª¾A !‡ÁL…ŠP´Wª€§7A‡“ìKQþóÓ¸&€PÌ\[‹ñ×¾1Ÿ½Æ¶-ð~|6ºÑÏLÂ}!b’Ú ,ÐkïÑ{ Ün‚Ð/‰D`ÅFVKÕÉœ©âÕ|cu£G½är| ÑWéÂ)­F—ñ° yä/¼$ãÃÚO_•zöÛãCuësã~Òï± „÷ógwDûõ RÄÙoæ óÍKÎ÷×”ò”J,Ôeu>í2ŒÔˆòo†[d.Azâho—­œê¾w&•ÍSÚªÑCª~УÜæÛ[=—ÿZð'ÊH`¨ñvÐÎ ð”lj¯F“A¬ö4l¦™ãÒWq¸‡¨ ËâŽòaâÅÜ:Œ6tŸ'jZ~«aÀj…<äf.¡$[«Èbóõð7¤üZÙW«@+uœuFöØýÓãqQcݯ˜|¥‘Âó3DX‹ý"u­‘¢þmK*?m !¡ftl™ñÏc÷i·Æ=…BðIÇ•%ªóŒ¾ðüž³ðð•O{©>¤©û+©ƒVùŸ…rÚ‡2]œf¡ò‹w0µs¥ÍVˆ\h÷‡F²“¢½5±;TâC“YYªÒÌÊöêδe,i¿Á‚ 9Š]¦&î;%ìÁ¼)¼ñŒScmò»: ivfÑâHÝKï§B*˜œP¢)b”†ÄMã‡Ñæ11¨•w‚À†¬øü;`»ëHΤòf$wÔÝ9§q„ýZƒ“2db÷—!¾'2hÏW=ÓRNÿÐØV×ûÎ$nú£"ü*~(úO¹"ç0ØM³ƒÎP,æñjÂÓÙP"”_#6]ö]£2߃d÷;‹œ|ºç_W1&})Ó¦d‘ål‹ YØ¡:1׫^ìâ9±áð{”)Ñ@J~óäD«OØõëœZ•ÒÚ®ªã~£Â¢§†ˆPWÊ7,H¾tïÏ©ýô7ºžWú¬DJàw53BdýaÕ‹’ÕÖ7ÞíÆtU@mù{s¹Y*“eÞ«–¢Ïë”<°§¾µDr‰]¸ÏíOM¨U&hò·d¡´²u8¡Oosm÷Æ€åjqµKoÊêˆ?)ÍÎŽl·ÞŽ•lÖN 2ô›Û±Ÿgl–oÄüx8¾:˜øM#\Qµb`Jr'>rƒäštò½¦€jß;AfµRl¾èÕIWר‹†4êùözyŸéž>ý!üí(y¢„† Éã ¨ú‹ bûj÷í4<É=„V½•-éé5±äÁXä…EãgNÌÐíV}ê EÞÇÜg¿jy-ºJþ•,oOâו^ÖP ÿTÐvúËJ%Žh·‰Îþ©¼p*ÙOm—9 èlð(Ÿ,”s ÓپȜ@çÆ‹P‘ß%©É}òv¾ ry‹ê\qMãàz(KÓÈŒ^?ÀœFd5âT¹ëÙµÓ ´nN…Iöó-™»16“wVA§W…É€1O)LÌûׂãN pJaœ*Û`S3}è?Êùùë}2&8h˜1†-‰t{½:©d™¹é÷Ì Û3ó!?éeˆs‘ï¦l¸hÜîšG°FŸð€û ö¤Í—uê;<˜¨ýlåmïIn>h\.AW¤!`UZ¾E s þAžÞ~î’®ý3Ùò`Éœå€x sëôRíœmgtÕA HdµÈË¡QNè‘ù¥ ¶úß—À6k?ûíD«5NY׊÷gùJ€By›ý˜¶³KÎ÷«g¦=ë¹P‘úÉòøG½ðß0K»I’«Ót­c'IN·¿ÛŽ7±IÆ’ŸËðIX‚øÝ#[bYBàÀm:z[4µÇr³È m¸R˜Ú­Ò Îj£ÿøðõVŠ¥õÒXF`î}¤{ŸDÛoæ j©-JJzÐó4é>ƒÇ g•É< %5qÁ*Òð$äá¬ë¾‘[‡ga%%Ìý¼†Auq~ZÖáÃ}›Óî¡TÛàQ¼yP¶ðEùªaÏömk醜*ïûRKàpï×öAÙjhÊqÌÙæE*ŸÜ÷FŒ}‚—ËP­ùîäîÓ¯wö6ÑHà[­ì#51’ ¿Jb¢a W±õöHÕy‰Z+ÅX»æÌŽy ¢fj¨Ìß×®(FÀâû‡LãÚS‡6ª¾­¿Ê•öÅ~‚cÿn  ãQl·‰à<µ·†ËÞûñM1 G¢-'-¯u &uößfPçøXtE¯wª„ ü‚ä[ÆýýKNØÃݘ±“+˜çúbßtì×Q'Ö™€•}ª‹›:Ô_z_*læ 5L-Q^lä<  ÅDI bewç½Õ¸ ÁáÑ›óß €—»ÃæsP•ªpÓÔ»^× ëÒî­{%k9CÕ…4î$§89' ¸wò¸Á<];Ô`b"'—Ù³v&yšmkÓœ>O8ó¸c1¢6àŠÖT#ö9‡ ž‰’ðÐw\7@N˜‰U„ü¾.üÕÎ×7Zw„Îϧ°±ÊÚT©Ô|a»Ï¢ó Q“Û¦wÂdf6ÑýIV¾´eAÎFh>h½é$*=ã%¡g̵/"§¹QãàÄhéÕ˜:صM½GN?,äŽË½Ìuv0–îE|£`Rb;ýX¶×‡7žyñhµ¿¾¢i‘4«cŽæ»±U›Ó÷úV ôìK=غõ.â%¤-'tr2!æ»rONnÌYÑ®òŸ`¶Z”ÓGŒiKi,í¯u47˜yÔ¿€X—x¢`ïPWläŒàŒrÔSoƒö®è,šm†ö¢rP€Z¸¨ìN€ÜÖ|ú8¶23Õ ,¢ÆfËÙ }Áá0í.PT¼èÛÀ¥YS0|ssÉc[ kÕ8U*#Z£Ë—W¬«ú†×s‘‚Yú[lÑü> XA r¢÷¾¥L~Z73£KMùÙ¼4IÇ»òýx²ÓÉml›zÆÞÏê†éJZgpiW›:¸´† ºÍÛ. ¬® æԞЂº”? fñ’:ß–û»¨UÓ³>¯Ýã±Ì…)¼ ¹éšBš?xÞ\΢±.côh1„UÜ!µm*)_z[î„ &ƒVÉAòT…7‘atðê©\HlY&؆)Ï>Š?3c[¾ÊaDNÆÄhk”Xáêh O´ *wO(÷Í.ÌàÏnÄRªù® OT]ƒçþ I—‹%ÌeN¨ÝD™$Jjû?ÏÂÐHÑb÷§ÎÛÚÿ­¶¯*ËÔW<_özni/§ÔÇoR|Ð.¾{Ptl£²nÚyÒ¯Ó•œ¿øLNöÅ•‹Øê€þ°.V=¨bƒÿ“®-,»¾Íy_¹r/qIé¶[” î'–˜æ’È– ë;M‡×Éâ·ù0.g(Ob‚'açZ½ÈÏ5ºt¥'îZ*SÃá;’gï[Ñx×HñBq}ÛQH}œ!„¼ùCéŸúø©žÈ A±³*ÐKea%‡³ªÕ0Á­e´q=±ÔõgÓËQ\~dy±5eæU%½â–Gc<Spѹ]úÓìä`qΑ»¿ïHYcÊo-÷1š¸â¡ê ŠP” fæuÆ¿1ã>™z$ÉB ežÒ¦dcáüi ì¹ö†HupÒN=¤8ì>Ç –½‡bF³¤Ü¢Ãƒ¢u¯/#úo4î$t£îÚó”ÎSó;mÿ¼AÔÐLŒ[Æ´LÙí›É[C$½àeF9twgd${ˆÐÍý#Œ¸h{F›Ô%-Kq± „\•œ[]/í/“Ž\[%2üˆ¯¨¯ qzî"×erQòT(ùßR ìY?÷æUmš•]b,f™b_'÷WÔòžÌ•Ž…BØKß×&  ¶UZ¾pŒM”tJÇÁâ fÐö <-‘^§’q—¤ãì-P"å©÷1ÑÒsé¼ Iî h„õÂ)J×l¸õtRÛy bÌ$Náßø‡_)~YØò -êÏía'Ûö]’¢—ªèw«)8Œ­ïò9Š5¨»Wˆ7¯Ó•ÝC=9ÖÄôzR§9ó¶a´¥Ô|É›@u&:dï !Zî ¹~A®¨Û¹›éâY<>dˆ·}ŒM©Øc Î5flŸ §î¡_*6Æ4÷/jÔ²lÞ>ð’s5Sé)»B—f­ ¢óR$ž3úoßí&IÔ ò4ïæ×Qhôm„НBõ϶Eá©ÜÉc4à§Ò—oXC«NA×6˜?lÍ,DЦ¿†=‰´šÑÿÏ*„ºn;]†$ªŸ¶;ìÀ¢¼ìº6ER~Å‹\OG÷Ìv/»C†ë¸»ì§¼7%V¦7É[~ByiX.'GŠ»aÉ¡+îÁøWDwŸF­‚:‚胂Íö±"‡Ñ4VºCõµÉÈXâ-òôW¼Km¤m¦Có­Q Ï1j++Þjˆ3'IýÜÁë‰z,~ÒOØ K‹uö÷ Yy§DäöÄ2æN“(̾S J¤ÍoD,÷ΚH"õ«ñ¢¼ãb6¤ÃûäÔ ôFe4®â~É‹-éM,b“`i݇ðÿ~{ŠàA Uô $¤Ï$#h„PCšq.'ÚŒ&yÿÕ–ê>Ö³¸~’þa]w´€„ßÁon«ÔáÔ®&8Z¿lÈÆžêyK£Kb wû‰ N©æ-§€cÆ–l­kèËL×ÙŽ4¤‘=iE_Ö–ß?Þ6wT­µ‘Ç"‚á9Î [øX©ô»~E”È¿JýHàu#)Á°Ÿ3ŒáÞå2<éŠwôމ0tz¹+­ÎboTp‚O°ÔI£‚¨%8ߪ7 %&ƒ…Pý=:¥*ïñFlÅ|t¥Í±>¶³Î˜REê ô0-L“ ÄM ­xF`ž-gÑÊ(¤xNÀ*µ£(á§ûéóšÃÓªÿ›&”ž²îÛ_—aŽ‚5Ý¿ÚSW‘ÍCMêÏcü±{ ×ÑŽ·OjéÌ®dë¤I1 srCkþ1*Ì%ÿr$‚š9ˆ³)Øé¡> aF*‚4….¼KÑé¡[z†â»(·+ç³S˜ž·Îì1SÜ£1¹ù~³k·ñx­WBK“q9/ ~ÔÎ7 WfC=]ÜA'‰’œPûhséøøÇeÒÅMK2-ò—Í~¶gNNlôô, íŸâßù»ŒÚœÆ’ÄâžØÒ¬¥zµ"¯³é _•¤CåÖÝUg±¤á±Àå \Ž´‘6'¨øfÍ×ÿ­²’EZh›Kpð=áîßf÷¤=Ýè‹Ñ|Ì,«%.Ò†…zi=óe®ÕJ²~¶K‡z¿-`…Wñòx§p7“~›ƒ YäšsÕc°E@V´&Ï%ò÷y¶†á! ë0òÇ-–%plÂ'ø^¬O³ÅÉiY Þ¿¨â9”ÝÙNÎRk£Á5žÖC¿yãOIHrö;¾'>jëÍί8À¼ž@–qdÖxÈró¼Ð±zqÔïƒ÷ºEJ­ SÄuã>Ü‚’"BMÚI@®%àlïÑe ËWÍ·~Íôi•œw1¡•‚?É, f`¾—áý/9Ðßr(ö:K- X¯ìûÇyÕNTÆ\=Èî,Óõ}?¸OÛx~¶íÆ×‡àM—2Y•tÕ5©Yë{»}Aº8¼fàYÝ¥Ì[ŽåiB"ƒªG'TÏ—”§c?ÀÿjVwÔ¬‘œàé6–¬Ø¨‡Í¿ÒÆ£TTp­Ãu/rǾÓt^CÐàSeX$Ì`ADø”é€+‹GísÒJlÙ }äPæ)´ÔÛ ¥@|` X…h¦ áû`ìplÌʤC+ÈHÚ·‚€U¡R$ëàÚ K†ó±0eDQÖ:rpoî 5?z Í9…6cW£l8qyÅ}cðoáuæÿ0ùî¡H†"õ`­žÅûc¨Šr8¯³Ö,âÀ•/³NÉþ Mºt³@Þô/õÙ¢ÄÅ&ž;¬ç¬ç««Ç†Þ ÀA»‡D“2š„(SNÕïøPÒ¹æ«Ò +áñ7ú$òUÿÏ{£}è é&·1T¤‹cžºw¥wŠ{ØX·õ»•(Oâ2Ù¼âvLÀ‘8FÑn"D+¡›[óå(Êj©G¾º®>G¯ 5WLš[fÚ­ Fôþë~”íJ Ø:- ÍÀ¢q,8x¢“ЉþЖÙò|t›"'»%ö®áRe" qåwÓÖ?¶sðÕÊ ²ù7'pwuоûÈq¨IÖŽcŸJ§¬Øfó§çoK™C†IB¾ a¥Q1i]¹§ÑÛÖ!—ÇÜêyÎêSÅñÉû]ñïJ÷¼¾»+Ió©–m ½Eâ$¼¬&°ö„–ˆÄ£¬uÙ‚“:œ•c‰úÚ” €ª”L¿€ °É$ÁzŠÝbo… îNåN”;àndrj)j.ï‹ã%{ð¤I½ïCBƒÉR.mcµÂ"Ö¿-:}'® ÑoŸÀS¶@†ÝVW[ý"¤‹å&‘s½ÉQQ@Ôõ‘ aupE…ê…Å“ù6NãøÕvz,Sk|‡õ^ÞCïñûÚì³Ò{E'×U}—}Çz8B¾Þ÷j×ñL´ê¬ úéÁÅî0MšV 0ÿñ&7†FKˆ7,hð$"“9Ü·¤m÷¼•çU°ÜAØÇx7‰µrÎ2p©„¹SV·n’™‚J¢Ì:ו—þÇÌ‚Òçõ¢Ð^Ö£Èý¹'ŸXÝ0üô´Í&%.yÓ% endstream endobj 4948 0 obj << /Type /FontDescriptor /FontName /QOJFXS+NimbusMonL-Regu /Flags 4 /FontBBox [-12 -237 650 811] /Ascent 625 /CapHeight 557 /Descent -147 /ItalicAngle 0 /StemV 41 /XHeight 426 /CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/a/ampersand/asciitilde/asterisk/at/b/backslash/bar/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/eight/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/numbersign/o/one/p/parenleft/parenright/percent/period/plus/q/question/quotedbl/quotedblbase/quotedblleft/quotedblright/quoteleft/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) /FontFile 4947 0 R >> endobj 4949 0 obj << /Length1 1166 /Length2 3271 /Length3 0 /Length 4020 /Filter /FlateDecode >> stream xÚuSy<Ô[&…•-²NÊn˜±/3²Fר’e˜ß0Œf±ŽD–,‘í’"KÙ·,e'[WÈ’%Ù %YSD%ïè¾ÝÞÛ½ïç÷Çïœçùžïòœçˆž4³„h£ ÎÀYž ÉBÕÁ&XOg É…GB,W ˜*¡@¢¢VX2øM#t‰ŠŒ%àõPdoåF£ˆ`y(U‡ªª+Áhk¨Â@QlFÄzÀf â°x¥Gp¡xx²%ÅË ‡Ð‰@!º$u0†ÖÙ?«‚u ^þD¬«,qÞÂZRZZæ'SSS;ûÿ`Àz 늋Ñ>Žàµ_‰–ÂÀDZÓèýX3 J%ï –p#“½Ôåä¼0(€†É’0²x€,'IkTÖ%xî' ö5ÓÃÚPþr¿êæ'øâÿc°xô÷‘Ð/¹óx¬78§÷ß`ú‰¹d°Tª•Þ`ÀÏÅMn¿¤•¿ð„íÃ(<:(ЋàÆ p$ ‹h?P å€ÉD ø¿Äßw  ŒÆºÁ΀+í~f§ÁæÏ½1ŠLÄúí ²P( ÝÿþZÙÓ.MÀãü†› <°œ1Ò\ÛHGú×ÙÿŠÒÑ!ÐRB`*Š`ˆ¼ªÍ)´ŒjJ ¿füK‹:|GÍPØÿö ý™òC«ý9MÇ#ùDÍ›`‰ï6–ÿ=¿ ŒuÀ?­s ª¥¹†öƒý«¥þÆÿ«±~­q–‚Ã}WEâO9À4=H`$x_Šøp”'çÿ/~ ´þtÿÿÉsŽŒÂa]´ñ®¸¿dÂ’Îbý´–ìâö§]~¨Œþþ3 »ÿ’Á˜ìÎÊ ëâH$Ú]|§<ú—’úx‹w[’i®DÑû´ …H¤Éóý‚hgì1XZƒà¸€ÆG .aî•aÛÚü¾×OÚ•ÏoíQ„A×qôs²ÚLx= ù³7US2ôÌzÜ4ËìŒè#nðë_WñõPÓi’eâà ç8`Å·,[7Qg]g–xmçKˆåM½³¨ëße¸v²xËVTS·Ã2‚À,¸}qá­·)#¿PqnéaÓ·£’jÇ?‡®šâ.›«3w7ëAÝC#SY~ky0¸#þÛE–ËŸ8K›8œFF;tØ”‚‡# @äÊug~ÛBõæ¾ùÏnMFZÍô­2÷¢³Ä>Èõ²|{Ù-5ÌÊÈ›” 8Åz„—·?D é©1îÂÌŸ>’ÓÑ4(Ñͪú¢wZr.÷‰ž(ÌÌ:ÅKA2¼œØ®í•ïkzNÀ|pµ {ÌÕXÛ±“~aÔ“gjȾçn[³Ñ«¹^ºû—„èÌ‚ åI¡>ƒwÔs–Žro*Ä×+º«iß…¯U;qbƒ›Ënd$2 ¿Ë\è·\sØp;$cV¼Õ8Æ7÷µTY€¼Û8-‘½gh0f‚­.Ab£^´ê@„c„üëpν™Ø‚åÎZ“ªxHåVx¿e'pšÒ^ ¶ºr‰X·ëÞ±(CK‹Œô L3ë „ö¡áGÓqBâÖè¨ëw&² Gfc¶¿DYN_« ¶Ê™r_ÉŠ½ÆÀš#nBw·<‰Wqá[™f[°2®Ø:Y4þZËÕ+üˆ©¨˜Çgî§smúpT(8ýö1 À9 aÒkÂpAü~âîL3¥ê“§f¤—Ìk‡e^+_Êu‹¹ò“ [‘2îŒØ/²Ç±úèãTÿïá7¹êxœ®¸"ŽD-qü!WväH“ÿE‡cå‘Ú|îYQÕ»ÔÖ VPý‚ösÔl”æÇù>mJ«Ž­ºŽ«Jù¨§L½ÈÒÏ(ìáÍžÚ3ª¬L}eëy¡JÜUu÷§üª}ÔVÝÍ×pu 1²™‘5© ao¿™LV(5ú yænHTg›¯;¹×°"íÚÏUú²ÐŒfÌ;;§OÀzi;ø°UÀ:8/YòIªìt|­×ÚàìG|«õõ(ÓMˆ¶àÌæõÆÞ»üfÛ«a¶÷Yª{¹N9ƽ跱 X*7ÕòðLyo^˜x5v~¸\NC‚#ΞQA¬ËÚøÕòGYöÏnÆâ!Ž}jte3O3 ’ž™{÷¼5S¿mƪ=j»A¿Úñì~¥‹cñïN­«_s~aÊÔÿAè]fƒbWÐkww('ÿÔhoˆÄ}…Æm‘¹OmÕÇÛK5I-7jDV;æÛ RŸTFdÐMOùÞ´XNÆ{j̺÷MeìÔ'êÁÆ&á¥'Í"òg‡Ó!tâ]ÅÄwÞÔÆÌõЉ"EQèäâ!Ɔ2&yØJÞ½€ùÉSŠÛÇQñ³Abœcùóð°cˆKmŒj¹}õ<ƒ_°úð×Ü/O!pÃdx}a¦m ¤ÌŸÒ¨œ-ãöþ!ÁÕNmG ; )ó®ÇÛ -v¼¯ÐQ¸ ÓpºÈnL÷ù‰Ÿrù‰•/]¼#ÚúØÄ‰ãhäÅ8 CR˩஗‰Rð⪯l+®&!KÚg:Ï X7û1›ŒÍ%úGÏ“8ññθ dļwx¶)gIv§Ÿ FuéÃ|™Oþ}Ä·ø¦³*/Ɇ¼CÊÈ®$Èú¬²L߯MÜjó¡z6¥Û~ŒLyÛ «õ³“b{ȽêÇLµ½kŒÉ›òTCÅ™ñ`º [F1Bjí~5 YæÐµ£Gsd|LX<ÒôÒ@Ìwتý¯DnQ†7ó+ß!¨ê©:ÛCårÛ1ól–󣞇9UеÏñ/¨vF˜®Ýå(—æ6¸mvG‹}êÖÚ¦ÓˆÂ@f Ëç`ÈË—ŠHJ™¾n‡‚ŒY’Æ"§¸#{Ó=_1§|Àõjú®+.Æ0Ø9ŽaµQ(( ksX,¢ùitÚ„½GÇ:åPÛA‚I]­Ñz5wv«"'ËóâW0…N­j§û³‚&;k… Æù_5Á±¥iÊ[NuSÉPíœà(QÊ“´¸X³¶>*Ïât‘|݆aL‚NB¦õió_??Ö¹$Tc$ÈUé-[y}IºÐ¨ŽixØ­|ö5×È‘™§ùm/ÁZ¡«ÊŠ‘ïéÄe–ô­½ßAšO­^’±¨ ‰+‰¹a™¡±7gìÝ ÷Ã;·D”Nº*™ØKŠ,ç,$Ï"ÏÚ}³$ÒñÐåLÊÍ=I šd¹…¿Å«Ín´iõU‚ U:×БÀ57ìÐ$ª§árÈõVlЉƒêdã)ÜÕñÝ“çÞu|H˜¥‡Òi8p2¨¶#Ê‚îfTô­~”ihÞ6‰0e+uʺB_ûkV•·ÏD™/ùÕ°ò"†¥2Üû^15Ú覽$Å¥7_Ù¸Í9§~릾jUä ÒƒšK³nþF[[ƒ}G‹A±3Ü!vÁLîMõÊx{Óìªfq§¦?J"Ø ™½ò/ÀDÛÖo…Œ™QsbsƒGE‹-q—ÓTM»3¨âÓÞ‹ðg“ÀµÖÜôkÆY›'u¿®ƒŸ”I¡ÃÅÙ“Ï}, ˆÖN{¸Š´¬Ïމޤx74ÚŸ°·3Ãwàq ¹ÇÒ!úseʣ咃—pýÛ&‘7 ­˜™Z™Üó˘lŒO·3÷«„Éצ Jx¦%ïk9M† ?,¹ PbùžjN"»XBù_õÉ&Ú¬ÃyC¸­S/žè˜(¢nÖý,ï9š/g' q7«Â-J[]´>WŨ»M¢{⸖|a¹ñÄÒRK*+×ZJ4d~J 6ãÚí$44;KbŒÝI{V5<Þ HÂlA,_’HÆ•Ÿ[{ºª½_Žî‡0²Â/‹¸ßàÈš&Ú¤…‡ØØm‚€žæHÕц?ÊošÊ1:iŸ;N:ã¹çÂÇ`P£q'9¬6[jÊwW¥ V_ŒcÐ*Fô¸×ÝHªÀ²\óÐ<܉( *SM'ëž8ÈÞ>Þ:ü’z™½;à˜–Í2Øê4`k•—¤‹´ˆ•‹i¾«µÀ°z€'¯•5ß•»óü>qã½iiMP†W„PtÙØgÌ€ÑéJ•m¾ö²fó”Ìà)CÕ[ÂnM5GM1/Ÿ§¦¯puúž]Àú=.úp%hÏ€ih™š B@D¨§î,”šSŠªÁ×m0\NúrçQ¤Ö«n.¿:è ¢>[…N¤ûšï¸ö¹¯c÷Ö´¾éµ–Äý'yªÐ73…—tÑ‚ø+®7ößæ“QìŒ<ÜÑ‘|NXú­’9:Òï‘7×)s¡ÉOìXUw©¹§&êØáeD\õ†ÃõüÅ…¨ßÈè‰Ó·å‡óBâËì©_:ŽÅ¦½?‘ºpQ;E0LWî¸,kñ¡€­¦¦´¤;E8h»P£âItIÛI×|îê¼ó'4ÇxM^‰êRˆÅ„Û\¨¼¹ªpíX‘‘–Ì6ûIá·ºk»9G4ÃùgȶÏ7´ãžs‡Ùg†Ï`wW¥xÈ7>å/¸û!¹â? ®ËÓ endstream endobj 4950 0 obj << /Type /FontDescriptor /FontName /MLQAKB+NimbusSanL-Regu /Flags 4 /FontBBox [-174 -285 1001 953] /Ascent 712 /CapHeight 712 /Descent -213 /ItalicAngle 0 /StemV 85 /XHeight 523 /CharSet (/D/F/a/c/e/i/o/r/s/t/v/y) /FontFile 4949 0 R >> endobj 4951 0 obj << /Length1 1626 /Length2 17924 /Length3 0 /Length 18780 /Filter /FlateDecode >> stream xÚ¬·eP¤ÝÒ%Š»4îP¸»5и»»K…»»6îÒ¸Cãîîîî5.ûí÷œ™ù&Îûgî÷£"j§¬\™+÷Žx(I•T…ÍìM€öv.Œ¬L,¼­‰«³Š½­‚=£<Ð økçD ¤u»€ìíÄŒ]€¼M @ h `c°òðð PDí<@–.uMZzz†ÿ²ü0ñüŸž¿™Î ;Õß?n@{[ Ë_ˆÿëDU àb ˜ƒl€QE%miI¤‚:@ht2¶(¹šØ€Lr S 3`nï°ù÷`jogú§5g¦¿XÂÎc€³Ðô7 èa tøÇÅp:Ù‚œÿþ€œNÆv.gàbÙ™Ú¸šýCà¯ÝÜþ_„œìÿFØþõýS²wvq6u9¸þVU“ø7OKc—j;ƒþºöæ#ÍìM]ÿié_¾¿0½.Æ ;g€ ÐÃåŸZ&@€ÈÙÁÆØóoí¿`N ÑpuÙYü€ÐÂØÉÌèìüæ/ö?Óù¯>ÿ[÷Æ6žÿʶÿWÔÿârqÚ˜3!°²ý­iêò·¶ÈùŸ]‘¶3·°²üÛnæêð?}n@§ ˆæŸ¡ýKÂØÌÞÎÆ`4G`V°wù[@ó§2ÓŸÈÿ ÿ·üß"ïÿ?qÿS£ÿíÿÿ½Ïÿ -ájc£`lûwþýÆþ>2Æv€¿ï @ðÏCãjûÿJ1¶Ùxþ%ýg´&ðßlEìmÌþÓ'íbüw$Âveaabù·ä,òš)\L-æÆ6çõ/»ºÐÉdü«ë¿F `deaùŸš%ÈÔÚî8ÿíÚ™ý'ý¿Rý‹<³˜¼˜º¦$ýÿáqýW Òß%pQótøËí´"ooö¿ÿÀˆˆØ{¼Y¹¾Ù9XÿÞ½¿„x¸X|ÿ%ÿÄú_gyc'@÷oß,¬ÿêþüþë¤ÿ0âv¦öfÿ¬ª‹±ÙßMû_†ܦ®NNþ×åÿÛõÿ<ÿkç@ )ÂÚ²½)_ˆUzæ—ZœÜáI1Ýþ^VÈáP‡Òµ¢‚€jûÿôï»<Fo5¡LÓ¼mžK§ï2t‡£½Ø6Ô=©ÀË|B_rÚ¾´-ªnúà fƒRägšÑÞW‹r;P:\,‡¿&•U JÞ`ˆ¦;Øà®iÈÝ 0)PüLÓêã°:¿4‚¡×žžQ%?>PŽ õÜ@÷ÐçÄÁSòãø¥œ’&»x9Ý5˜~@¿¸q;€©¹:èȬ‰2%˜5µgÈ›WmÑùg2ÐWi1ýZª©~¸µ•OÑÒ±}(Sv­9ž¯“t„j\"kˆÏ ý ý¢ßûÓä>vô€0ËÍÂÉ\ -Ã^YÛJaÑ‹qÆHU&ëÁ?æÅÏÆ™2SXgâÇ©ð&`’qìºë;ç ã¹€ÒÎðZ½E5Y/Ö*ÿwC#ÞØ±âŠ;EížžÃ+—dzîEs½=j2’™‡#tÇ—H;¦[µk‹3Zü@Vø¶ËËX={¼n3 Z_Æüq¸ªugQɸõÉOð¹ŒÇ4ñ N¸X<'GAò!* ¬` 2¼gyç'*·GVv˜ ã±Øàè~…CO2p”m™åiêÃØÂÎÿ¢*IKÏ»HK?!^dêÃ’¬§sy•çP-£§äýÞP ò tåÏì"RŒt!(uœßnTt‚#ÊŠí0G‚ï·ë™X[´;~ÝyÓÿЉ½KhòÉŠ¯Ù1ç–D ˜Ø­`+¬Ï<¹‰²¤ 5ü0ïevH«·Í(¹k¸WnºÙºdcTÅo§²å0­ò!X!]7‚1iøâNïΣ™×3‹Õîš³:jOkD”zQÆîžhEÀ/HWëô¸ŽO!ÔÚ#¢ºÎ|âœãPêßMz/ÊãiÈþ¦ ° Ÿno·•¤-UªËþ®ûR¹œôþ¹ßÛc€½Sdæ›Àht;ýM_#ò3ÍÒEfºôÐñ§@/ìjÀµtwÔ ú}x™É¡ÒA]SG‡ä4X[´S¥1 pw¢/es´§)ÊÏ+Çà•Þ˜â9þÑk™|kÆeX¨Shºq+÷¼Î&„9Y}¯3Ô|Áùì ›*T\K-¯vÞ-¤ãW”Ï·aÜàyâLï•J²ïÔ‰ì›ý„7åUãGj¿Puvz1°>ß*’w×fiÜ©#|ØÜŸ Ãž9€୧Åœžgþ~#Ð` %,†›=GÁ.o×–™«Ÿ\æ*jÓot‚YgTGˆÐuÐgg^.n«¬ó½_yø8aîð$¿Ï#8ŽTD \Ï4ÈÕ¤PR§p ‰ÝUû–wа¼W²î|Éh1%`C×¢!*_'#”‡lÏMƒ‹ÞÆ †Bmý3ÿ ‘>ù-7¼h³cb|w®ß[Ud™Þ>Ò‡¬+D ú(•”Ô¢j^“æþ¹î.bÍ¿’Á±Ð€óÉœûkØgæ‡R4¯ëMV›GExgŸBé ©`¶/wÌÏI[m£=£VÔ蟙<Ùu5²?‹Ô!î äf\n­t•«§C†ve­ Úö”UѺ †)n²Ñ,Ë2icPæ&ª·Ô_K¶7À*+nÊum,§»òec¦–Qgj LŠ@Eú8ð¾Åpqn¢ï9dzÅf‘hƒì„ïvøsüqjÄõc[X‘þoÇQ-ø.º²­Ï¡yÛ})‡,°`uyym”f®óÈr-ÒH§^d˜ã ‚kË(Õag.Ž‚®Cæ¿~ýöq­rDæ´’*f¦`&çA‘JªT ´æÞ©pÙufÜ<ÌúU•jò™ü%#+¶i‡¼‡•Êpˆód4­^p¤~ýÓ„kÊ=lßäÜ¿ï1+ÏJïBu÷L¤‘7^"Øœ¶§ãv¥“0HÓM 1Ýì·Ä»ÛÓ}2ß}÷Õͳ Q¨ÞEwHÜrîóW–ÐzCš¨ã¦ãݺ0´1kð5ìE¢ ¶B–Dðq5î¸NE2Ãá‰ÏñC!³‰ »1 DþûKÃ÷ K؆+Y}éª&Q·¯'ízh¹ƒÔ²6¨áRŸe<·WU ñ~„;ñIåçâSÉÍNád?Ps>5œ®`ÁK%²KÌswk rª‘É.~³ï†•êÆM9p6ùIËý0_Fó5q.zj9Ðç§"í¯ƒ>ãë–¤âÝ*Ž“J¥îI•ÒQá3* \ú‹Þ%ħ.®í2T6þMÄ?'x@aµtm—Á8d…¢‰ªÍHp¾³û@¨äñÕ UæïãÑ¢lP9+ ¹%½s%¬Ô®æúHBl¯@:âéÏ cqé¤Ñ´Ñžü%JT#Ѐ}í Y\ cs¯rÍD˜·kUKÞÔjí(p"G*¦o‰“ýDɸ~t½âz&’a!™Ÿ9$œT7’°Â×GñÑX=é‘.Ùh´~ö´b)pºžYÙæÔÙ¹›Ô߆íã,æLÞõq Ãv ÷Ó–·¨ «´ÃûX“ûïo¿¾Í µ—½ 5þΠ5ϽHYᑘçT Ü‚†œÌí¸ÚêoüŠB(¨x²H ?ãXç·o½ÛZƒÙ•†Ê_·ÄHyªg‚pô÷ÂâÐÛÆâlGS:º¦¯:\ðóÏ_¼ÿ„Μ$ûÔ$ÖXxôŠpèE’þlcö£É®uëO1¶²{JäKCzzÁƬöÓ*&JܸmøÂYî ¤3ƒ0õT‹žï$ÎÅ÷Pz¼0G{¦Hàú‡+úŠ~mÆÕ¥Q¡ yAí†×©ÔÿÓÅ\¤ÙSŠLb½óƒð½ôç¤ÀÆóÔ•ÓŸ]B™][Y¢?¦ ó°®CíËæúBâ”M O|–E›Õ}“'¤‡€‰Õd‡S+²ütåãY54°ý‘¸ñ¢ñ¸S…ß‚-_`ƒeõtuóhNytr_m¶Íã)‚û÷Q’øI5Ó‚"S ·íÅTM/—YZñ&Õ}Nþ|/¤…ÈŒ"qF:ýöxAƒõ¯óܶ@*<ÎÔ)j'‡ÉmIìa‚4©’{ûf?ZÄÔúÅ-Iê¤Éñø?#¤0/œUî»ñM[ù“ Ï£EwŒnÉÜEé­17ƒèá"Ü«hô”5Öq= Í϶e¯€X•·=ËÒGÍ:pH¼¯%Ëê{þ탵_p“CbD ÆèMö9ç·1Û;kØ2ó4·â½ÒÄ‹€8:?r´©øÍ­mK"¿ïÜUÝæÅ|¿¥ƒ8–½ -R ý,oÇbï—(Nr‡'rƒH4ÑŒi„F xÙ8´¢ª$Âõó´Ž':YH­Á)5H©îlBÔXešëªõúR9NòÕ"ð¹¾áYÙ¨+.â ¼”¥-,¶ˆLXìÛùŽøÈ¯¾$LkŽŠ˜_èL SÜ\dj»õ1‚9fY-m¾!iD%Ãý¤Ö€„÷î2”C½ˆ£2v·T'ôX¬`q¬„ÜkmlR¡§¬Èh!zÀ¬JYLþ uꇆµæãÿŽLQö§)™#—8åZfúe†±¶Î÷ƒ-z¶@¤ÐÉ«bŒ°0ÌŸ‰ë]²ÀŒ4}®'¤ã^6Û‡´[ÖYEµcÐy ÔÁ~œoá¾MË[í7ij„Ý@Q/oîŽ8þy¯ÓOâ@‚²Šv]Mÿ±%Ln—v½Š½¦»Ž¸–3˜ÄDX›.9\7-ø…¨>”R§Š&}cõš?¹.Çë †ëOjbK4öÂ46I¹ïÅ&u…Æwœü› ÁÄ”¼ d\†4«èÏ8}΢)¨À-RŒf¬Â™¦ñ‚TÿuG¨?&î»è*þŒ¹àp !ö‘Þ^Õ)ÂÛZ³¨GxM4ÅmV÷Õƒ'ñÔ¤L¨vÒ°F„)Îd3ÈËùž„O£&XJ:kqû^1®íOçû1xL¸2º#5K*VÝ)³ÒÞ¢Á^åGCã|„жà¿3ì³2Dƽ±ùc(*ôÜEÒwÀš#Oê?§Ž+ƪI«¶x•Yþ„hb‘ë÷ŒgQC@¯Á«ê˜p­·äowY‰XÔ]ÂEœÛ£Ó‚ÊuLÎ fyFvrcªÍ—ƒb“=QjÂDÚM c½y2œo/tð'ïDÚ\@<;À0Ò}qÂ<9ZZÀÔÁÒ¿G#ïö°±My)\OUÊ•a9D Œ9c /ØÔéçr¼üá„6Ž¥Ñ ÊŸˆž&‘—†©åoƒ ›ç†¡&Qñ4â÷[ÆÇÖ,âÿd¥q =ÂqPUX´|½›<±ôÕUÍoÙPQ°𿺪%é¦z?j$í5?>È?Cþýò ã·+­­9áb@º¸ñ6¼~:Bê®Hø`t¹z/,\µ¢ÚG†‘3”3‘Ï+r²0ï«1:”TÀüŒA#÷”ÒÛBK ÁÎe´ó›ü8³î›7-|Ì}\ŠE6j“dé>x;MÏQ, =ÌwÖ\‰ñº(âIjÈ/ñŽäW sFÖ˜èlƒofzA©`Z„\m#2¢âë¬ìr©&uÔr®œ5 ù‘énŽŸÆj{aï† D®ëü¾4Ù9'WÂ:$¿Ì¦ ‹9‹Œ8ÛMã2ÿYÆ›?uY67ð˜—Tcõ7ÜSO©0¢éúõ‹»õý£[a]¤Ÿ^ØùDú”öd¶š’“M2-î»±ùó(Èzöò"9+ižEÜ4ÍTàÇ|¹ý!Žœ-|ªòË+ñC¾Ç8‡[RH£n“÷YKïÇö^¿–·¢1Šù¢˜×d¾Ò¬.%/kæi–åÈ<ųRh™;¶ÅÚ‡ ”wµ¼$X±$ÕÚ¡èË:r"!Ýî|íäžû%š$5%mè[ôÃcÊ\ñ‹›uÙ8ïâàʬòÛ•Íì Åà­JÊÇ_{(b£M(Ø\8§m:õÁñûmr¸±(±v)ÌÿÊ>3ÃIJÕà Þç|¯¨PG“bâ˜öTK‘Nz½¦KÅÁ]žhýÛZ-Wæµ›ÄèŽïqH:âuù¤Gú|0Ôò•—Þ/2ÜW¿$ØgDhNZŒ=ƒüfo<ñõz2½yb¶Y’á .ò?_Jôœ.:ôE\tØÉ‡åzq^dX° )ÿØÖÆxÎÖ{æ®rjÿŠ}ŒÕz“”© r ”€Ð–©aÎéän²D••E(-&}y±§Í{›Ýì³”ò›“^ªÀðAóæ•;²$ezeL£8ÝÄ-V#+'GÔcWô9lH>´Lþ–T@V|‚‘(dèQhØY· ô@øøÿ‘ªÛÊTå¿G"$5Cšn;|®øÇVKG®…Y/)?½)~<óŒåᮯUÏÇí &È)5)g­¦ÞuDé'R¬ØØ™@VÇ~Àúv/Y¢oY®®­7Í_Ê«è!)R,)^qÏPb­Þow0vhö +þôq†4š±«çë…½ÿݱÞt)‚h‹a¿™LxŒ7<ßAÑß^Äôié<°ãÖâЬ–Z&…®Ñ‹V+|Ô³G…(£ÔPÇNä裆å‘Dé†ËóÌvÈîË$æcÄÀG’SÎÑå4Æ£ÿÕg‰Åo=`Í•tŽã!«VÙDì3þ[Û1S£&K!“Õ^ RÑ=°ÆyÐE[ -Ä‚]õΪEJ䈕̔²À‡j‹êkIüRÒqŸ«Õ<Û¿óë>ÄÝÔ…ÞhÛÃò,£ÆdÝîk $fÏ Ý”‡gÄa–‡w¯­DZÓ©±Þ«NÍè&‹!ÔÑNã«™cgÿ7[Ûª¢2ý7Ÿ§wÓµKÈÐ- ŸùÇ(¯+>ò—_©BÕí û˺I)â”Î"H@âqöEYÖ´Xémâ=§•±2¢Zèš,(ÂZ‰¡ {öšWº·4õõ\D+¥oj©I [O30‹¨?ÆhVÎô<'Ë'Îì0³ÆÝ1¦ÞúlBý :C{šK¡òš)&¿:òî¥xF; ¶*àùó<;ƒ¿¸,Ñf\+4šìå n΂»d#ƒ&ó1˜û­ökŒ°ÞÒù#ñ^x_hƒéG?¨£Àã¹Ì}òä`·D~?’U0oÙÂ:ÙbW´Š…@’ê Xu€-”J1Ÿäü9êû,´eѱû×Ft4^å;’|Í2¯Ž=¬(Á?Qi–ls‘ÑÁ÷¾'E> hõ¦ÊFƒ“’·xcœÐÉ:»Oô®süΪš[bZÀã­õ°qeq÷+f“háì{ìiЇ¦zoõ†-D'ŽØ;'s½‘‰k ž[—²RÏV¢_ÙÌè–BŒ\Çä—CedHiMö-3V±*ô×2y€Ub/‹f‚Bä!æׯÁÖMfÛtÚ`¨ì¤¹Xí vÇÉ~zà--ûÚ ¦ýàÃz•Ïû½Q‡„"*dÛAv΂aÕN#ƒaVñ->ƒ6®!kY–k®«¹ÝÕªP«\•’jó!ƒØYqŸl}uê[#Ù»·s;¥êܪžã½RïGî÷^±Ú<$õZOèíÔ* ÁÕ†Xôòí§Ûƒ˜n)‘u]G÷®ØlŠÇØ vè1ùð¹´xÇpt5_‚,Všœž/ñib"œ¬A.T¼ >_Þ¾X–ÄÅé5—\"K0íµm§¹)­ ÃÉÙ"*º)ü@nØâÞ+ɹÖv•ËîåÇòæÒ õæÇÂIâì—Ìoý*6ºú»\²Žü¹P!q?Q-dÿ%¦aÜ…'Œ¾1tÛ¯ „—JÑÿµPݼ>À"ó)VG„2xØúgá@ƒ0ÂZBåÞóÄlƒ`{¤}¤º„HƒÛäšj-[é! î¼`ë°ï“g¦øSIä&ÊÊäœúò@þPVí÷ØÑ«ÕAuܼçm–«[8ït¤¦E™4Z³‚ìµQtž%.³‚‹ñ²EhÆT稢ꘇTÜ>óÄdÂÁTñmïØ£ä= r9À+‚6Ñ]T)Qr¢ØK×ä!|àIðƒêV*_€åiŒþ:_ 4Ì*żR¥ ¤õ½³ô÷Äipu-8£²Š´Ìa)f'†cO¤.b~›P=ºösE”PˆhVïaˆf 6[µ§‹rÊØÆ1‰× b&²¦ôu!'jÁ%A]'RÓ@‰IüºÞ@ô“¹uQÆG‰JÕ˜ªØ­ÀóÈ56³ E·A!><^ÕÚó!¹–wFþqMå‹F¸öj –8èm)¡ç©gôQŽ taA™áõõBK.¡/bcün‡\bîŠ~–fч€«&ñ¬…JÜË×âÅ.Ké.®YG¼’{T¿Ì5ybôý$öcÓ§34Xß¿YOƒ Ê‚6wÌÜD×z…«JA¤Ø™û4Ðs!‡ºÞa®à“«xƼ¦Q¢op›«³TU6ºé<ÕkßWñÕL»ÀKŒ ~ËIà„Q®9Tç—CjŠIâl@ŽBsEÎ HŽœpõ35ºŒÆÎ5 Ôx«ìj kz°ËAv–Þð>®4O>á­Þ¸T$+Ï‚mÂ]›³$Å&°¥$e¬Ç”XlÓ 3íû•hQMeuù´‘S#nn;d²düx+—Éå­ ¯Hs½s¢Éú6§Ä>«öÇê0´N÷ƒ¸(M®ätj<Ö)t̑٭g•^Yù´ÛYÉÀ YÇ:)ÇÏÍÛ¼psµçÜ&kd~Å«¾Ó㛑¢™Klü¡ëD¤è-$hðö¶UÎCŸ°}] &YHÉH°.%ÔáÖ»3Þ»—õ€Ž—c‚ôÅÒ‰ÐZÌ-ZÆë\ÝšTšå@j+è8vî¼á2|QÌŒmãŒÒšÇ±_¢7‚²íwÁ &ãšU ìÜvm„ ’ ^ÛŽÖDO¼¡ ‚ GºÜ$Þš‰s³`¶0~ê|^ëƒþí¼›¨kùõèéR%øhJš´v©Ê ‚¥Wx*@øÊ,pÕ%”Áµr¨÷í—Tùó«D}¬Ô;\T5×ýÉîñ ¹‹‚À£ÈÃX‰ ŸiÇ2Š~¿ +ã’3!ìÀÙü_E¢ N3±©c7b~ª…ùÎõFåæÅ›À5¼b¤-“Z¿ÃÍR^tI#LeªËªÁ0:¯Ï}yz}šÐf-±qd<ötgñrì]%Ùª¬¢¼(r×§¶ìÜJ`.*‚J¼jœHïýÑò€ÖŽEô+ž„Z ËwXÿñ¢ÅÕwµ:”¤½ä@ð1Gv=ïLWG¶mù”»H{´U×6qU¹h¾<`xŸÄB“!µÑ“ *þyJ5†ñvÜT9¤ªh-¹ ;éÚúÕŠþNúªq7áŽÞcXYx"ê(ôDUb¿ÚP‰c`½ iHt®‡k|•9ÕŽÐŒLO´>¢óv=¥t÷¤¸A}k=€ˆ` LÂPˆ„ÞÕ"¢C¾ªÄX"ÄM>àÍ‹ ü¦¸{l\ð¡NQŠÓîl­¢=uPó˜ú½B×§j±ÒŸÐ/ЉZÌ*­¤`0§ á!‘ëòÑß© rjuŸG½ƒU²Äç{€³d•:ÓÕp_ Ö ý® \ 4×)|çÄ`%Uݤ!ÙUA§6Ǩ›¦(þüÕ¦xs’™·Ã;B–?.@Ÿ¥¸À¾\•ìc.ñâµÄò±÷ÖRwÝ[_¬òEfRiüךyöò‘‹Õøy>'ÏíOùh3…宣‹'m£!uåø•’Ç >\¨ßc9ëƒkŽÙŸZaÓ1—{)„1—ÆÔEI÷~ Þ|ãMó6é}2S—[Ldêû2˜ÄØ“–½]uANµ§æW¼¤Ø?ÐÐ#[þéNŸWøQØ$Õ 8×öYb܉Ç)º³Š²ÙÚ‹Yô¤Ÿ˜7õ2@¢ƒ­-@`ÊVÚœþC~Ö¦Ê7õžnk?}dUñ»/P­§¡}ã[Qß.›hsGqœ¼¹ü6jý|æ¤wýÂfd¸£([o8tiq(ÏU‰Bw;jG¼û‹–oÅMIX¸˜LÆ»@‚0ýÄihx‰`‹OæØœÈŠ´eµ`è‰R^Ýž¨í«ü®¼háË™pÔý<°Ç›Z2ht õÿ!Öå‘büÜÏâ=žÏw+mN»¾JOfV>O7441 |ƒÁk}hDbœ!¿húU^“"Ó2íHõëüÙµ§»¼üŒßÕ¡!—s¦¡#=B0ÎÄh©œ ÛÀa½¹¡@õÃõ_+×h.öÝÞÝ‚¹MÐùüá5M4Å"ÛýqŒØ–7ϭц_¬³ót‹q6×ÝWœÛí…D]ëi2}Ñ÷p«pÔºC1’%·JJÍ:àõî@&ÇûËDÐWû*Ã‹ŠŒE]2µVîÑ—øx±ïÌ6sðÐ\‚¬Š-ÄÓͧW1κ¯’X-&]žMcö KV|ó7®ÑIN¡Î!éÇ»u"^d~•åĦrŽO2™'xóÒ/Öϗ1’ëñ@F­ÔÀÁ”ÈïU̾ÔœŒp.ëÆŸÏo¼g¸ì>°Øbª„w ¦•3œeþԩϽIûîs=…ÏÈ IRù)çÉHȺµ½ŽûJ1øÐ˜#§ o4øíü6(°Ã¡¿sÈ{ÝÊuš¹xŒÜJ@x”AÅBL6<¨\üÑOù)nã>›­õãèä†Õú¥ª=sYÆw{$OßÕÊÛæ•îƒâL E½‹µ%éFï˜;åvu» *~![Õ¸>\ï6’6,ŒKÀ;!¡pá•x›SUv›‡O†Ø~RG]rû`ÖýЂ¤Èmèjz‘ ®í®øÙw•Ä2VLOöS¸¡d ^ E»Š¸è#Ö+Ì@™¸™m½ùïMm·ËÒÕærÈöX©Tb³^B‰ë3S È ÀÐü¬ýM`gϳ]“Œ2УÖù¸ùŒmmSÙ\’:C2Fa#å ²?6}ó¥“ÉQµ†s‰¬2öüí‹êÅ7ï~™{W÷möînuº’ÇlnC㇘ÖÅâwó<®gð"³-©€ç;Ô#ÎûK_Är[ËæÇɈÓ-Ý´KÜÐñ´æF¤pJ<ÄSBý1x»Ruºfd/°‚¹KîÜÄ7-È&{!­üÜÓ^fÓ‡hÇV;Ü·ÈO‰PåcÊ$ÒŒ†Ì?P¡·„q 3Þ%zæÐ‹+Lhì1áKµô²lŠ£>Øï¹F6½/,¥šÏ‹ßýËœê Ë+XÁbÏôý uyhm¥Žõ5©;ÉðÐ Üß{53Öjð×Ðß5ÜöG9k5—RøŠGÜÔFê÷!~wC­¼\—óAsÆ Tì_<”þ%9G½Øj$‘9#{ÁRJˆ&£¸l—X½×b­<þª({þ¶ˆ¾  ¢œ0,VEx:ßHwOðcòI69Ž¡–_½¼ G¤ÞÝ1»[±ÒM|lb-›oŒ~ÉÖÜ|XµïóâγŸ†Î@C¨B¶§+ $*¹*KN¤ÉÙ(ñ[‹’4½[¦¨y3¦² óKAkËs?¤4Cúƒ–M㊒(N/îB©éÙI*#›W iª/M²£K ¼¨Bà½q ­akr‘ûí¶hWEÙ\³;¡åÓ¸ 0)ªšøÏ04¼U÷¦„ 3âÑ› %&Kéd;ÀœÍw·7”â¯Z|/âÔŒ&·y‚Ù%- oàVh^5dé=¯ÜÐ`ÒžO·Ê?gmè²`óóˆ„Ö¨º…êÞþ,ð”î:#i~xè·~9)Ók³É#ü5 ¨žÛÚÂH*¹¤LHQ'Ž#|Âðó-[nÔRW1síY«äÓ,¾@Â6YF‰ê~X¹"Ü dj Æaâõ Â7vÍÑÎlkE_9( k…ºl¦Íä]Ú—UEÄL¦ŽúôÒÊ´úucfÔ ñ:yMr_àøŸ<ùô€Šh&2 bù^@DŠŒjÀ(¯d; í@ƒ¸÷-(ÒÀlŸ.yèB[·Á§íŽ’®#zô¹LÀ‹¼¹»g?¹IêOhòÔ¹­YrÂpÏÌ,*2¾.AÚÇ<œâot˜|Úád(È|0=óHÇÁYXB–ßËç=éw¸GúL'#ÿL‰šm]pRR̬†Ñ°š"¦7Ðû ¸Ö@ ýú°áWûYês ÄKDŸ§yLñ°Ò°-Œa¾òø¡s.ЧYã×ÿn ßÎ äøâÝ+È=ý¬XD1¡“(5¯”"'ÑXçmt÷ù¹‚G˜hÍú L Ì»tÁ¬” ØÃ舺 eI¹ÝØHcÆÈ¶s6ø={>Zg&¬ºš’xò…uÍÀP=ƒ€h&Îqº¾CË4“Rûá4W ZÄã¤ï»QNŸÒ%”!HWá“NyßþÁ*àU¤ƒ+uÛÉ€ÛBœ*4ŸâÀ&¾H!Ï$Õñ|ÈîäžÆJf¥ ÑŽþ5äV*R>˜µ^*á¤"UiªîZ(! ÐÍñ,Bñ4•ì4®?·§IÝ`Qö¥<ÏÅ4]íx€?gˆ_¦ >äÇ;¢Déú®ýy¼4ÑåQ´o(‚¿wH‹Þ^¨Èx¯Â`¡ó(úzöÈÆÔ¨ù¡ õw˜¦&_%änˆ¯AB¡"*¬Q£nxÓÔgÉ÷¹É?¢mZ«6Ç}ŽMhÂð–Úð0dŒÝhÜC¾54qc,Ð[Rìcލ1ÿˆ¿wvG¨5‚XÔæj— \!$;(±Ä•m‹b-øæ£êìøêV :‡‡„á5IË7¬Ö¨Y…(½È‘=`+x>r[dÏê¿[ØUž7‚õ5djxÇÌ· Ô a"[þj°f•Ãj^Mp0ãëÛë^«`ãlNb–6†ðü]‘ßÛ ñOG"Œ÷H<‡sÄ]œ½ò<ö`Ä™i.¯>[† Á@ŠC+ÎNä´Ó»~0;ÁÆgñœ·êŽT?ÔRáäè6µ¢sšmOø‰{ÓûÄ–”y—ø¹¸¼F×à’ÕËáµJ''Må~:jèZq˜oC »!?âaôm#ê¥Z-—F‰ûi d+_¢ka ©Ú…ZKÍÔºi"‰»Á7DÞ%¢ N7ƒ8óxûeëø¼f<“:u/¢Ç ÌÏfó~©l¾Eû@”ÐÕGõopk÷ÐBC-yN—!4'½×Z ,ïõ–~c…?Uïc(ÆéSužšCG…eÁ¤Â Ì¸NÑ=ø]Äoò€g2 ›äSâZÒÂtÙ ¡6QËSÝ~¥2†¤³PíÃò?ˆ‚ÕfhWPÕÎHºxÍõYèWì\n¡‡*£t ®WéÞ2îDpÅbz ˆ½øÖÜúZÜøº-Ö‰¦Ér[N÷ƒ %=ù¨p½.!x›j^„㥾ŸŒÒ5’¼a‹ÄЭ °Å0ÊÉ‘# 0ø4™µáR'0/F?÷àªù5ñ’ÆÞ:×zÉãÚ‹ ¡drU~L…IŽ$ݘµ7.k~O©l£d²¢ÈŽR¶á#Q|&WsÏŒ_<) Å´fÉþ_Ê·FUi‚~²¢ ÜÞ3Ú©z-4~³çjiê’Á6¥°µ(®*k÷º~ý1ïÞÆ$Æ4¦¬#Éb ž‡\¥{–^Gho´?`N÷ãû'F6½à/éðºrOª?ë¼Pd¢RÑ%ªeæ&䇹>…¶ôÒaˆKßÉ+K¢%¿A ÿîÄYÉ#BG`Ä…þp©¥çG²ÎlbàrÒ%‹ªÊÕXuKK§Yx´ñ†‘h+WÀ Kg}ÔY5âd_qBŽ¢Ð¸ÐŠ_Ðr®æˆ¯ë~0ýª˜'Tèñq¹l{­˜“=‘ ¨àÞ·'!V ذI âô4Cê"éå|1aLF ¢¦4&üEüåÊјÇ:¸öjMä iÊ7jÓÝ#¶– Ç-ùO¸­ß÷6;z^«KL½P™ûf “vfú*½„Ç#ŸI”QO’ölõˆØ‡Zê˜H¿gŠÆL•M‡0ùG*vòŸ™4X›êšY”pòÓÖí;˜®¸§¦µ¶oüz™CáÒLîÚá ~æ ©k~õ ߊä`íÎms oâ½¼ñU™_޲Æòž ØúÄB$Ú±ÛWfwôÉjIÈâdÄÐéd–Eâä¶Ù*ê•,rf’‘ñ9†’â:4Ág`╘‹Ÿç£´ˆ ÓŒRÃê¯xí$Ì®L?¨Msg0O›pÙJ÷x·‹N¤Ct,Èä]vºB¢NéU5I×õ¥APåqÕ¯ô,ˆSÏž£ì©YëX *²Î“†÷hbÜ@K¨Ãjä¿mëŸà©×ç99|¯®²5št«z§µKÜñsP4#c¿@B>íìnž{|¹Ðòç,õ8ùÌÏó ¥<×Ì’Q¹ý±]/ˆS±F MÜK°ü9㤪 Wæ æ%UÖó­¼gCçeažÅŸvI–€HOåW‚ÒA~å$L.HÿÛ÷lo¤ZÙ¸lS‡Î‘íÏ"Ï:Ø/©¼•¼P+lžxF7üÞÔû!äßðÇ;ÂŽêü)=jáóÏ)U×od(Ì„j/ñ!øyª_pVd%­õ~èQ£ œé”ü&ÒC ñíá_3}ðœãÇhY~ ë^8îo¶ÄôP/XÑ bÄ|u¼Ê` ’ÁH^Éf¾‘êá·ô[ÌÍXGAÕ ú±…¿Ü‰ÆL^lÊãÕVü‚;þ½g"øŽ¼Å8¤ Òü³†ÉóÂaì­‘Y&ÿ­8¼¿îé§WvµcÊ"Øõ£‡ZC vÝÓ ¯l©†þkùŽî®Ž‡ïLòRB‚xX;ݪ^É`º!Î*˜$ivêþE¦n/ï –Q+F‘&¼ÐvuŸì¢ä[Îû·òÿÚWK2+-Žé/¿ª±æ~Z7"}1{3`ûÂæiòü`Äaþ>¼Ù¬ãáÞæme@|»ã.¿ÒœÿnµÀøº¨à• –[¬}çÌ^BŠE ä‘',¼'Y²#çŒÆ‰9DýñCQöYQs)ÃdJ+q s¼n*´©M‹²…J‘÷ɲœæ]0jbœ.B9ÍqCè´ SüÐ)67*¶¨‡[;Zê7‚…¡3uêÈ’Š`˜ ÆOdK¤¬¯%$s_\ËIžMß×ÊW‰Æ¿³‘h ">E¡<¹‹¤XW± ô0Yg¥õ†_˜yÜ_—^½(Wž´’ \ ?uíAÿÁ}{ÆCä  2p•›pÌDZ{îý†Íê-j :ò%°ðtŒóQÝ—S‘®e¼ÔØ{=&Fôº,=àLÁ½‰ÍL˜sÏ ÊÌ{Îʪ ‚ÊìCΠ"oÆÕ ÍÞ«"E &âôT# 3’™½ìH·«,tÙ€+UÁþƒ3$¶fYf‘kééAäëtš(6Š_“qî±þ³ÒJÂÊàð¸’%g©´@ê‚:mm—öÂ|Û”5 Rç^éæÖ)ÇäD€¤capZsq/Bü¨ÅÖD§×"FÕ¡£©&]¹*œIPmÊwË“?åL±””ñDj«äòÁðá-m$ë4Ù÷z»ílØ?‘6MM/ñ]ÞŸy#ø¤Õá¯Åö®-+÷¿Ö땺ý ÇM‡ÈFl_fiÌ|Ó# ^ÑgÅ -êv…lI„þUå?Qw™¯¾ýþªJe!Ρ•ÇÛe=B!b?FÁåoA²ÕtüÚ6GV˜õ« аrMr~9¿Ìì´ßÜí Scê×Âj§´„ÆRÜLÌÒ)4bAmÅo1õT¥Ìÿh¯êR~œ³$ôœãCªžü:zºL¶(¯GÕ8®àùLëjó5+°1r»]¬/½Œy²çmï袚ä©sAdØú!\}¬¦GÍ<}zß»PðМ”0Vk$S=ÉÈôäûø´’%>xoÄrº_±=.Ôª·’™FƒKàLÏ…ýõçJ¿[& K¬¢þzëº#ÜÁù½ ÑøK;©Ê€¹:ÛÅoâÊö¦%ö.Œ—*½öÄVÜÂk¶6©ÙCÒò¯ìuš$ƒµq‡ç⟠ù›ËÓyœ?"•!¨ã‚OŽ”Øµž¿Ìø¿3"F²«, ’Ãàøc}±—¹ÓÙ8BÕ»Ì ¼¤;Žøº­õ£ú*)éΊSö„ÊDïüþ‡ªŠÊNÈ»Y `—Ð?©döS˃)înß\ÌYÅ+[ó)Å•Y„ÇÒh†ºðÁ6¡Á‰X¯Qê_>a*ݘ2Ï-‚ýaäûPõÂÍÿ$Ç-c°ª…Á…«+ÌÝä){bã9Í ˜ÂØUjü¢é ÖÕ쀳Vlh"Þx'/=XÉÚ¯ÈK/÷íx;÷0R¿yÝmç÷æ¥ÔÏ^“üN -Ìúˆ¤j‚Õ¹~8ø^¿t A-¹ý+ƒýœ¦£ŒsvÝÕ3z§u Xîx »Ú!$Ûf-²+n›¡JŒOQbó—Ä׉Xùq,h¡ÓoC»Š5ξĶÖYéÅêÀbç~žá4…”¦n0D®“Âã‘sÁŽ’„-Z”mëûÓísÃîZÂ"’جÁ2ûìþÑV™°–ÞîmÇ“pôìPú%ŠP˜¡øö‚2.Ë&àêÛ(¼_85—ªÑå˜ìfø™Ê¾Ì8`žVió2.­-÷}¿{±Mò)Y£^$üb¹ßê)"üLEJ'|î°»ÅÊþ5{‰©®à®˜9hxPß®`ä‰MJy*›OIÕÉäÍ% W5Ä÷É “]ˆ–ܲý€•¡4 ry×d@{œæa{[2Íf—7÷J—‘¢9æˆhœ_*ë ÆÕ&HóàiâSW—zˆ¦¦6gÉæš¤Èî( QA6àŒ¯¯´¤‰ý€¢ºYf75“WWÃúl5‚Œ³á/O™ {öÝþNºÞ³Úŵ¹žx‡c:(_’V ³]$à{ÿºöÄ¥º`S—^¡Væê Ùï«Ú¤ÊÀÆWø1‰¾¬†×ž-1ÚT­Xç×ܨ /V²ÅEAפ]« =våɘŽ:6Š69ês¦O’Ýàcè@V‡ÙÛôc.;—ø ›«nrâ_1—Ù˜~¤šá^r¨CÅ *wnìÌö5®#Õг&Çç*Y´g)…É)°huËeÍv–/1ºpWÔfü0“®8Í€ û1E}_š ”—-gO7^0ÖùcCÞ¬=T»o²žVZgT~.SüŽØ:»kâpg–CwÛi§xR¹¦¨èÖlXwp»áC‹ø¬æMÖú¤ˆ-JMõØ)N}(J{³õ™d£#ziÁ8ò 2/ÊëF/ y“ÑþÀ{; Z¼‘ä,9 6]eç¬À¿Ð¬"¬Ü?ÔÏëVrh²ñ¿äæžÎR¡Pš ;™¢ÌU<À÷.ZÕcŽBn3}†¤fÔ˜Š.Ù(;zÍÇç#ügBÅË ŒÌñ†­K¨Ò9_fb¾³æQ—4rÆg9›¡„N§ Ó7Ž`!¹­Óçë¹-]¾­Y½A…«•Ïý—úÃ,§ Ï4^àž:f´¨§‰h EöÔw£;r—6Q† â§«ÍC1 j"ëöT´4F6饠!þ++tQ‡ÐscöLøàI”½û¥Ê{ð×·ÁÖȘÒ&ˆdõl¨,ýj¾o$d f~h¬½æ/$Éa+/0ÛmR¡_.ÎÒ'B™È:-“wr\]î|îÂ[¾!}Ð;㿽wY$Á§]&ŽNQ¡—‘‚t™Ù¶©l-ÏúÄR~¬Gš(ÖmÁi~ ½r†‡Bc—:ll ^~¯©GT²ôÁè¼Î}ù¸IhQ†É ¾e)•^]^¡µ%mGÈ @õ„Cë®ùG Üü?Q®÷ [×6â6£\Ñ %ãgsÜ= «9!—çR-òY…u]¾²ª,ã~e) Uù3#t||%PLø2ƒÄFÝ^ÃÒ¢E^øt‚±s»[‹—´ÐoßÖí쥲”ðÊ ç’±ÖνปòvpÁ”Ïm/Kžw«iµº ì¥*ÜÏøD¬_5ÑÏ–5|iœ‹p)\(âE®`,<É¿.–.‰!.4u4õF³ ‹BˆÍ˜Ìáÿ±Ù5ùk¼&ŽÞ›¤u!òÖKÀÁ ž¿Ök)ìaÑg§·zxTrñugc_l"r6à³Â¾v&„¢™¼¸šLl:ãvIº n*zí9’÷K0 Ô ˜ï~¶kú¨1Íâ\ëÃt¸&hŒä÷Ì5%¥¯龇€ðö./¦O«‹žá~ZO¤Õ­¨^Ä+?RÅá ŠqÅ“r²d´Mj?Í_Ì#³U |BC;·qlɲ"r`|mæBt=¾}'ép+Ó}-õ¡+ÇrÚÉœ] `¯Ôú¸­y€és³ m1øà…Hœ!㛨[oÆ@xB 4™¾½²ðr'ÌÆÑÏ›"½ãÈŒÑ)`œ>ÉadöÄ—kûNñ#ØŠ ãU,ydÂy$PN†2æXYö²È/z!ˆÚäãù< Lü)å>,]—çX!h>˜YS$0óÊØæhåAGuÿÈU ÏEÖ¢)| Æmöcœr—„7þ”2 ¬M°ÉÑšÍa¿7çˆûìÂí³b!+Þ1¾úŠUÉyµn˜W>*g+§õœ9´ð…± %ëŸr_7ê7í'ƒ ¿™‹oÌy®_[ÌwßâF /#)}YÆŸÐV'ŒÉ´Þt‘íFsöc>ÙM›”† zÁ|íC 5Åýu*å³fuÑ¿K»¹à=• ÛÿXV±eíªµ ÏŠ§æ§®hÛË0µ.PþóõÅa@î=èæ }'Ð#Ñè—n_ƒ$.ÚŒq©Ï{ßLk½®r+zÒ J…ËSgÙüQ§~›ZbøJ?ªO ½Á)GŽ+¹tÔNZœ#Àd^æDóšú3Ï..ȯ¸ýܤ¥‘w:µçèx=¿Þ¹Ò¸¤.<2Ø¡/y™ŠÖôÏ6JÆ=YÇ^ŒÆw»G‘·×²rÜ‹A%Ãþâ~]rŸ§³i÷3òT Øšã„ U䨻V ±•Ïmd]À žm1üv²ÁVûR–Ûö>‚xüÃT9Ò†¸Ißê,w,Þo'ú ÁÉÆsí3>³Õãû4?(nPý=\¬¢íÇ’ Jlf¥‹•AoSRÂñr‘'ù™ÅTê÷wSi ¾&yO:Fü3 7=€9sFØàÖ·­+e§ú0ôX<G>Ij…$8Šsm¢Il;4Ås#è)³c$Ûþ»þðQ€®Ø=rÕÇSgŠs™è-ߊÆ¿q¨¢µ'á[·@[?—cä)\¸«—Hü0‚ûù–#çÎi=rž`.Åçâ -¬ ýîdŸEÌÿñ­PKéÔÈI±íÃ,ûÝœû€¶¢h£¯;ã9KÑû5¥6LòÝ>ù° *yu¢Sã©s踷A<،jä±@ËÅÉ‘1´6ã¡~…ù,rä‘Ñ7`cÎ Áޱ>Áv[¡ñù–Ϭ"!4Ñy™„Êsö‚îëí\Ê&RãjdÒíÛ÷9åvøDÄèã-c=Ö²–·{ ©ë𙾯#bš,ç$·ƒ(ÙËŽ¨?•¥`×`¾„Ø'3|½­­ñÞ²hüÛñ«’²KÅ€‚ÅfÊÔ™ùiÖI&û°ÁvQ@h|g{d¹³ \f<øaŒðæÌžœ!ƒ–&tφûm°0š•¶á!ôà|^ü~loydì½@3÷ôKð†Ûœ¨4…¾Ñ]õr^kõ•) Ëo±-?Hnêé¯ß(£A j‘eTc‹9GДfñ¸þ󧃙•’Ug~>"iÑVüð)žc?­<¾‹ÕMê ¶Š’²Æ˜©º L½©Ðy"'Ä |Lncµ±´©jðuX·å-ƒš±œ¡eFêø»ÃêUókþµ pÿ&r®ˆêAšÞœT1¸W²4$)G© ‹"âšÐ¾Ò~µØÓ7VašõšË°p-³ùöêߦZ"/7d—p9ü6ŠD¬y $іΙQ÷Ú~Îü؈è™Kˆc©nã+Ý›‘f2¹­öì…ä£M©3£t8pœ$)·»4’ "µr¾S„FR•“¤oÑ572R»Ñ«•ø§úw”¾‡Œz'`BüÿÐjª bx`­;%dà˜…²åTN6{Íòsqïn»ý,”­Š‘²ƒéR#Ò^(ýÃ6t…£Â0ü‚Eç}jÌoD„µmã+Ø–˜­”?ÊaKIfš¦r=ê÷º„Ñ>ìX†Ø=¤Ö³8 º*†³çÌÍþ"![‡gÉYš[ƒºOdØeÒ/®iñâ¦øQPÞwˆÀg<¨d=±gαÀÌåÇÄ@¢7m‡hGæ„bÖX œcD\g3e§zíî+Æ*…!Ic‹ìJt'ð –t5<³1ï7šÿЖÂÒV2}íÉ~]ˆ;() ”‹¿ÀÇ/¬Ú†£wÛ-þÁw[ç^,85©~1>!Bz_Î ×EwãYÒâõnÉYaÃÖŽ ‹Scö •1ÄóŠHÍŸf4jØ¢‡CWU»SU[þ^ÂbÑc><Ô·fµ×ñÓ.©øxÅ!\kb|‡X¹Ê) õH:·Ò´8$ endstream endobj 4952 0 obj << /Type /FontDescriptor /FontName /DMDUWG+NimbusRomNo9L-Medi /Flags 4 /FontBBox [-168 -341 1000 960] /Ascent 690 /CapHeight 690 /Descent -209 /ItalicAngle 0 /StemV 140 /XHeight 461 /CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/asterisk/b/bracketleft/bracketright/c/colon/comma/d/dollar/e/eight/endash/equal/f/fi/five/fl/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/numbersign/o/one/p/parenleft/parenright/period/plus/q/question/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) /FontFile 4951 0 R >> endobj 4953 0 obj << /Length1 1642 /Length2 6621 /Length3 0 /Length 7454 /Filter /FlateDecode >> stream xÚ­teXTm×6-)Ý5t%%ÝÝ HÃÌCÍC7HIK‡ Hw·tI+% ’"’Ò¢ßèý=Ïý÷÷½Þ÷ù±÷±¯u®u®µ®síÅÆ¤gÈ'†ÙAT`n>A Àc€ÔÕÎËÓæª“ÐâÓ†€¡ê[ÁecSô€Ø" 07%[ä1À(A@!!€ „„.@÷ó€:8"œÆ&\<<¼[~»ìüþ… #=¡nvä‡7Äw…¸!ÿã@C€p„ì¡.€¢®ÞSuU§ªŽ1@âñ@6¡çeç´  ˆ›'„ `ó¸üu€`n`èïÖÿ¥{[8ÜÅïO4ì׿k€"sÊÊÍFÔSŒL*™ô ¢DÂËšŒŠ‹Bka½!Y1Ÿ$ªl~ÔE›§ÿìð[8€ßokpïŒõQ¸pôf@Ž é‚X¸ú‹ˆ×Ø»ÄxvÂù­Ê²¿šÄÏkm`˜‰ <ÙÙœÔ7°*ýE?Ý%ì}|ÅÊâ]JÆz  ÊlL"ï&jF!©}ð•=uÿê’cèíèÈpï)fÿ6-O~›¤-epúSÂÏÆã{è'æ­·˜ÇÕ…|(îÄäfÕw’V!7 '«šoz…œÚ\óSµ?&Îr9N©ãÖZYÅÂòv¼ „°¶â-‘{_qü þz¡§i †3ø® f\Ö$Rÿ?kUÕgÌk¸¯Ñˆ:›îÓªÈìHÃÞˆ…xX9Û¾_ÿ¼…ûã¹[ã<Åá~)ZgV_“Öë¹ãK—Á0¾_xg«t¬±MÓÍR Ñ?%!=*‡~Ý 78Ï1Z'IöÁè Dx~ÝU=Ož÷ k¬ÛQ?Þm ³7IÿØjæîØ[F˜œñlÊQwR{0<ý1ÂŽc»¥­áJiÂ×î¨òý,;r¤T>ôTZ®¤”êt4ÓõSÍE§ž¬®ŸYæò+ †LB ’§Ú Å“"C?˜Î·Ö!x}œ½{{ Ù•bü8Vj=ì#±,»þ)}€"Þjë™#3"\¿ìÝ-cšAœÓ¯¯ö SùGN¾úœ=þЯ$2’\n½=ˆ7IÃÕ,Ñۀ¢ó}m¤•W!ˆs ¼/×…û@§¸¢kä§fΖüÇïCvÂÜ76±+5Z‹2ì‹°.tï1]oQ›s"H¤”¯0¾‘ÿÀp§ؽQOÖ2û’'ƒ~ý‹bH]»üípÕ¨Äbôø¶…Ý}@ËÕ!âÇZåí mèaDE@Îv#~!bpõü­šòŒy´½[¬÷óçH«§ZSÎ,<"KÁÛÝÎ1ê÷ó˵Ž-ÂM9ÌLÙìu“ùŸf¯Zóm“ʹ~ο‹eÝwÖ7±ÂLÊ¢ÂMœ‡KêÈ+4¬äœ×à¶y`¸¼ˆ¥æÓ¥+Nû>ô2m1À³®TëEûK´ñýëÅL“Ø’V²¥÷ (­x1>ì1wø­?Ø#ZsÕ’…Gµ$xj䜓Nö’HWá›íT—!•®EæŸxš5…³GÿéÂó¨+b÷f½ÃÍ¡°);öYÑ*Ç0¨ûÍ¥i3 0fG­û|Ž®žÅ:;ó§À9ê\ÏAë»×רWVI>:XdW/Bµâ…êH),Už.V¦¤áÛ¬zMÿ’‚òL…!ºÒžÕ_{ç,F¢šÎHùî›niÆÿúèOwˆ£6\´gX˜SõOP} ZË˽ªžÿÕ&ÓÉŸd45ŒþÓ¡fE®€¬Q+$œ+ Ì_‰ÇŠùL*pìjÛÖwVž=Ôö^H(ÑÈ6éþyALÊÀ÷Ç‚N*ËFJ3ßEŠø*çòŒµÒðàxÍ2¥‘” |³¡4R“‡ÅÒò¢©àcµO‡aö[~¾G%-¾(1—…0ÕP\«ClëË1¿iâ _ÌÌö/éIjh¦í#Nx3xõ°3¶–Y+jî´GÉg#yl¤hÝ+Ä?”RüxµV}êO­ÒÉÙ-ÒŸ‹ÜK8>û+̼îíQŽOóŒV:“<šp#¨âÌ|9^pº×T±›skö(*¬’ÕFuœkÜY‰ÿ`MË+ŒÕ›‹ÓUmÑ Ÿ¼æ­Œ•ð™d•—õ‘%SaZøßW ‡ªœæC†R¬ÆYŸÇ†°ÚVÄøµxÍÒ”ã÷r»Þ‰.¬šÏŒ¡E¿QÀŸô¡ Ÿ dÙ¥rRÀ°¡Þ¤ÇÀkè wÄ–ŸN^겞P£ï'úAVÙþ…]×R¬ôáü \6?Ú•õåRAó!e]ÆùA^xC¦Þ´ï¼Òå·›g¸qFðÓ46•±â阰„7{|è‰1Ú‚ÖOŒß¢µ‚Ú4.?´£n°/·b^­¨fjäBk팧÷9zŸïp¹ÃÃ{D_UåÕèÆÒŸ<ª,:™Õ'²8]1ÝZwÇøÈŸså“6Ý›^r4€K÷â.š;ÉkÜã‡w1§\¤ÌTöõ ]ÖÆMߣ=â%î ’Þ1‹qÆœ2`–;ÖëlšìmŒ?ݩٗãz6^¹TËþ`åsëazë‡Ü翞ëÔí‚Ô;Þ‹U=ÎÛ¿ø’óM˜Í‰&Œ~1ƒ%? È<¾+p%û‘%“ý>$EôÃGAU‘'vèÔ/LÂ¥Îq;·AT ý´Â׸…©Iè†DÒíR3)Šç…%{zÑÑqVLLšˆÖ–Ÿ¢Ý–a{ÈÂf5Ž>=ú2öú‰ñùP“f£]–}bíT±s „½z÷9'Q¾0«Qáeb±êÞáѓt§§8PÞ3ÓëÒÙN׋™â3{jèª'ò-»taUj ^N‰ŽxËâׇ>bÕɦ¦¹ à+6'E7Ï<‚‰À•P fïz!  ôV¼1PÆÅLU?9BÛ£k·½Aéãm–ž2w-¼ØBJx£-övŒ*ÜH%ÞA¾ƒ>‹Ë5ȨIË-3¾}?‘~cÕéˆË6tÉêuÁ2©\@Ña2ü›qE‚ì)ûuñ$Ùb„Ø!33ßÀȆbúDªê ù;=´Òª ”!Ï£§Ì pÝW 6@t’ÐW?³„ü–ü+6àŽù“Sã¯vh×|$ßîjˆHð{H>jùÃå>Z`9œ2—˜cXp E³8>…˜ãv¼JÎhC}Ñ"¢9—ð‘È.b`BF•â{ü'ãJÁ\-rÊ¡ÐG¡¥¶Ù6}¥Ôí¥¸GáËLÅ®a†æÁ[Ü?¾pÞYD½ÅRÑò°>—•t|¢ý`ÙÛݬéC@9ãC`â«^fa&P‡‡ /j Mãxu™ì»]ÛÜÇ'?WP D¾/ÐÑyɯ9}üª¼¡â.˜Yòˆm_µùËzÕžâ«d;ê€0Z©!>Jó+Ìù+ì\óŽ¥™ ö­ÜL}Lïv7&HJEUS?qž¼‘O§¦‡ˆY[ x¡=_><|¯çYÒ,š?"‘íÙ³¢‹>ãœé•ª9xÿã%WÖK,(¦hùÍå¿§^ß À%ÙÚR5b3u[à—Ðyæ¢'u“»¸!ŠÒž²öR¡Ùf>ŠzêXEÕg·lñ”úðÇ5›ñyWþËÜeœ®¬çÍL·N<‹n;\•¬ÆDUÌ–-'ª4’5áØœ“ׇK±£«š±g‘x›Œ_^À_ãÎ+ŠÖ]ãÈ(êÈÕ25 ªw#ƒïâÓ É"“¯îõÚ.Òf§m¿æ ŸÁ´X|N"ÄöTnï·—ó2ër÷ø/­XªáWôwBëç&;ÂÈÀ0‹*m¬›a²×€«Ø>ÒåI\{[èã2åZß«ñå¾¼‹ácF‰Ç- æe¢µŸ±_¥¾VëÁêlXŽ>J[¯.WˈöŸ6•ij¸’sÕ=‹î‹$ØÂ?RÖ8nìÓ£¡ 1ÓZ%¼ŒM¬¡~ ÍŠ‹ƒ‡uñöû«3qin ­•ÍŽxÙÈNHNNwYuâUs— ‡ÜÞîþDßÊ£½— ôy÷\£ø±ùdØ“Yég#ƒ·fB¢ù¦JÌjÕïË2ç’ ×ÖgzUñE[4•û^î®ôqˆ¯ßujê8À­æ(©»õ6ª»Æ Ð.î›o–q¬?§>s*.ðáÞö'=Òh`.©7Ý?:¹‘ü‰M;ÄÎoÒåÄ¢çVu¼œì»–ÿ°Açs•G³Á¼œ¬‰ªîcª‰™â—_ È{_Ä«4|ŽIÕínaQ“B%ê’^ŠµÍÆ)í©.žØ²P}+ŒÅΦEzQ–Ä~£½Sù–Üá fè­ÚŽžaf‘š3Z©¿/À `Ò¸(ºïEä½s¼zÞz˜q«0ÿæNîxÄì*ÕˆÀÇ8¯õ9ðƒÖ¯â¼vóø|‚$>ÿm%IM†¥"”‡ÊÓYê–üWŸÂjnÉ Bb Ws-Kø†¯úÊ@x Xo¿èbÝ%¢›ÌÒløo-‰ó^™±~{§÷Òlº6Ǭ¾Õ£ÿé冮ñ9¨=Ñ"À5BšÔH<üè£Èµƒb]¿v2ËY5UéWC¢/j¬åªb= a¬ »Š½™QÔÌÍÇ¥ï.3—3aí4ª) ­jÔÎØw¾IgVäÎÁ¶m9c¨Q»ìLyñužÑÄ®}ñ?¼§(ÿÂÂiåucs.åY¦Ÿì ç¹R1ç”Á >@LwÿM!ÞFä¥qZ©ˆ¬¯¹¦9Io3Ñ\d8«A›ìª*7;,‚©/õ,9£Ã9d$Qó£uy…ó¥i|3£¾®ª¹G(ÒÜrm‚q©å©lËQ4ó®‹'QeGoí:¬™~fzqBi žH ¿¦ÑW e"¡>?¬›•y@¦ð£À±€>‘l|ÈNaXÒsnë‰hHªšc7’Œ±¦9µ>'®:xz,Ž,Çȸ{>«NÔŽBèQÖLs´·š)˜6)[QINR}F;;ˆ.õÁ†|qÓ»… #B~Ì’N>¼’ â[b°‰•0¨ÏXKDXR]@%å•ÄñyÌήÖñ(õÑâûo“çÉè#ë¬:(§[ÎÉû |oàaÚŠxçÕðå^Eêé@ͪs1÷CS7ªÝå0¹kÕZN¹oÃIÜ&xŨ|ÇE€yýÂ~Àó¤é`†\);š³5å\•;ç7ü¸@ UË9¾Æ›Ÿe 2þ™^«¢-»¥Õ#“Äkíf+åX:J£äïöð~%º}Û®<¶+ ØøHÑêD°5æµ¶Þg¶wT›ºšµÎâz÷šÛÐ¥3ÎGÈárÏ@Æ.¦†JfþØè"3–¿[}Žiƒhâ4sÁbWö…"ÍPhm£Wbäì‰+ I=¢Ç½“еSaîªÙT€až ôº_ †_€€@Q=CüO×q}Ur uS[œH~>«5Äk©‘XyÿD6éH2­(%†oæðM_=ǽ‚Æè‚uô¦ÿ8ùžHEÍ=kæÖMKð;Ƀ¦öoÓÏÎ…îô,›^×~˜» §æ´šEx}¯B…la­?­éíÌUJÌÎÅSAëÙ¦tÖÁ½WåP[ÖUÅ¥4CÙ‘òêJu¨æ¢56ŠÍ º[L(Zqfì¢[ÌžÕ·l§*)·§~?ô9ÚT–.Çm#‹irµZ›Ï—–OÕqéc6Æ:èGì©¡ÊêækFx«°¨EáÐðŒ~5%ïSÝ'1ƒvŽŽ{:ÄÝ|‡øAž5°d“«– žúúl)A®BÏËm'É»X5¬(æ`È$”À¨KôJ£#Ž-%©Š¾6RUï‹ëjÚHH•'‰¦ËÊö ­f÷û»!‚Ð4¹å$­8P ¶£T¶)™BòÇ'ÓÚ8øFHo Ÿ¸ÀA sƒÖ‡¾ƒuQßÍ»‹³Û‚§v1y‚?¨^?ˆ~}Õ?~$ËoO¶EmÁi¨üX4°·Va{÷¶Xþé•DC’Ñ épÛ&ê…ÿ§9KÔ'ëe‡j¦B>»†™»:4I“Û´®ÑkžZ¼r«pÇGžZѧK®‡Ý\oÐ{Æž¥{U +|0%Ÿ/O™[ùlëÅØÒ®«ëTõ‰ê‰õŽ´ËD3jMØ6¹»0›‚¾vz"?ʉŠgt—6éHÑÐKµûAëÅVÃ_d|¬¿Œ¶¥mhÚÎWØku\~‘]ùƒFrbA<ÛÊ7+’Ǫ_¢ŸÂâˆÏÞ,_LÑ;ÿ&äR¯·ô<$:´.~x¼(¯bìf+þͶ>³Ü¢Ž‡¹*Õ!ëAš®3f‘ƒ7ˆÉ¢ŽÞ–ãÖ!¶V­TuRx.Élz‚ÀÀ¾Â’ìØèa"<¤¯YFTü0+ˆ=»YšÞAó&VZ˜7¿×iU Z ›Ó¨1n­>Ò°Ö[I?–%Lú!Œ¯2꥟]›âüTÖ¸Ë`tŒ‹4¤@;·$4º&Ÿ­¯7Æn´!t.P¯À>|Ñ É 1ßIg“¸—Àø,À…tнMxbPÀ ¿7Êl+òîC^Ð$Õ~QW%“@Å. êRŤ«£I‚é)¯1ñéT•ºH[x+îWúe.<(YðÇc Q]fƒ¦½Mø·å–¾|â>YpµhZÆÝÏ—çþ±–æ‹ñrÁóÊDIfˆç¤”ÎmQ o(¯ò‘{Œ4ŒÿAY‡Ö §’7鱸Ü Ò‚†Þõs{L7?ÿ¼ ú5øÃÁ=GÏGo?û5o‰ìlÜs£@•`#?»X^5J…¨­ôšÔmæŠ^~5y2s¬-SY‹lâl†vAžXš÷+7e5±ôª"8Q#ÏbòÜ~öxÓ_"Ô

‰„=ú¥ÍÓ^Ül‰"(™±æCxõ‰È“r]Y¹ÂóƽmÏÅk°A©·ÅˆsI] óz[®z_‘4p2H 3FðÜ%Ž…øyn×ðô¥ ú­a ·pd:z.K/6a¥_r#l•°ÅÞp Ýjß WdA@ᓹ6mˆáŽ&‡U¡5fd¹¬šœð;3(p¥aôóøÅøé.Þ¼{é²Ô‘¿ÎnòœLœÞášÛbÿ«BMT Ó—Ý=‘Ñ–Ú »6Ùw¯ÐÌ’ïÜ’xÎå6bUWÚµ· À­P;©ÆÚRÒ}Éæx•ç­tbgj^‚ìbll¨€ÄçtûG¹ýæú˜¡Rõ5Ç@îvÑÞ7 $TúÎæ}†:âñYÙoÆy¢óðæŒ¼Œ²é^ˆ6· úÙ8ôà}Ãdì­¡=™Ý+ޏ¤^ xÑ'cç êà8™ÛDæ­ýL\Â0z2 *hˆ=›˜ô5«ëÕ;² y>Ðå}àÁ¤ðDO›â m¶ÊVñ\|Î$`#Ââ¤\:àmž˜q€VtXôᢺ„XŒá½9¿a–—ÐNcùÉŠ€]Xé–ȲÂ~ÂÊã@5%ƒ#%mKЈ—ÓÁ"“‘Í9Ùe눰³B›—+ÈŠ»û¤½ì‚Ÿ‚è’´3©Áâ£ù&0Ìû84ZGú‡*ÔZ®a†y1YplõtODúñš+íËÛ†)Œß‘£ëX¤ÈGlÕT퀸~†Ø~˜r ŸX ÿ’B–!€òP˜ßDÄ%åuclóµPœ—–ñuò!¦zðgúzÙ-¿Um¸ñ‰dð­ý†!äMò¾ûÿóÁ>ëûü}É:6%™´)«Ï²“¹âAÕìGWø^z›ëæA¦—* Þ¾·Ö¿¤êrš¼hk°Îv¸ W?Ç;K†FIì)äíË'$ÛO°ðwM\†H9Q¥‰•a3¨–àÉ?"²Ç%ˆc<ݘ*KÅÿÔÔ™•t/«¾í@»rÿT]åAk9½Ñ®˜¨qg·©Â6¨ßýyH¦^»ÿCaËŠ¬ïÎMÁvzj¿r*°~ùãàC§±ØäÊ­œPîi›Å,¯ eÐFùýûìy™”Kô{PþÜÚA›ð(S°†ý»Fp¬¢.Tƒc•[gø*fÛí¨øm'ãŠhŒöý 4ÅÕ;†™ 4³¡o5ðjã'²gµŸ*c2p0Z=2R¨hPÚTïÈ«j-S¹{ïB½2ÇèÏaEìbtU®úL òkÚV§¢X· ‰³;òB׉JÁeÒ䨦ÿ%ýI endstream endobj 4954 0 obj << /Type /FontDescriptor /FontName /TLGATI+NimbusRomNo9L-MediItal /Flags 4 /FontBBox [-200 -324 996 964] /Ascent 688 /CapHeight 688 /Descent -209 /ItalicAngle -15 /StemV 120 /XHeight 462 /CharSet (/a/d/e/g/h/i/l/n/r/s/t/u/underscore) /FontFile 4953 0 R >> endobj 4955 0 obj << /Length1 1630 /Length2 21031 /Length3 0 /Length 21879 /Filter /FlateDecode >> stream xÚ¬·ctem·&Û¶“ŠmÛ¶½cîØ¶mÛfŪ°’TlWl£’¯ž÷íÓ§ÇùºÿtŸ{ŒuO\×¼çÚ‹’TYAÄÜÑ éèàÊÀÂÈÌK¢hmoêæ¢êh¯èÈ#Ï  °t#ù+瀣¤L\­ÄM\¼$Zsq€ ++ %‰˜£“ÐÚÒÊ•„ZCU‹†ŽŽþ?%ÿ˜˜zý‡æ¯§‹µ¥ Õßw€£“=ÀÁõ/Äÿµ£@âj ±°¶ˆ))ëÈ(J‘PK)jH@;e7S;k3yk3€ƒ €†ÄÂHb÷£ƒ¹õ?¥¹0þÅq!1!qq˜YÿuxšœþQÑ“8€öÖ..ŸI¬]H,&®{àêHbí`fçfþOåŽÿJÈ èø×Âþ¯î/˜²£‹«‹ÐÚÉ•äoTeqÉçéjeâúOlë¿jG‹¿–æŽfnÿ”ô/Ý_˜¿ZWkW€§ë?±L$æÖ.Nv&^cÿsZÿ+ 7kËÿÌ€ž°4šÛ\\þÂüÅþ§;ÿY'ÉÿR½‰““׿¼ÿeõ?s°vuØY0±°þiæú7¶¥µÓ?³"ã`áHÂÂüo¹¹›ÓèÜÀ5ˆúŸ™¡ù›„‰¹£ƒ‰9ÀŽIÑÑõoHêÿ;–ÿûHþo ø¿…àÿzÿßÈý¯ý/—øÿõ>ÿWhI7;;Eû¿ðïCòwɘ8üÝ3$ò$ÿ,;àÿÏÇÄÞÚÎëÿäõ_­µÿN÷ÿ&ãjò·-"–©afdþ·ÐÚEÒÚ`®líjfEbab÷·gÿ’k8˜€vÖ€¿Üþ«­$ ,ÌÌÿE§nemfëð ÿVÌÿkéúWþLj2’êâtÿ›û/C心àªîåô7·ÿQ‚£ùÿ<ü#*êèIâÃÀÂÉMÂÀÊÍò÷þýMˆ‡•Ýïò_@,ÿyV0qZ{’èý­›™å_Õÿßž þ Œ„ƒ™£ù?££æjâ`þwÚþ§àµ™ø—ä-€¿UÿÇù_sxÌàÖ–ÍøBm2s²\± ƦÅõ†XÀÇœ*ZÔK‹ëû2#wyjŒ?Â[ò~vy-9ý9”¥=À²ûÖŸ¸*"ð#§,FÝ¢úÎEwÌdX˜u®ës½(¿¡Ëɬy´7­¢jXþEøó;æú™&ܽ8ƒâÉ Éß,£9³¥­±äìœ*åäùéÛÈıÑþ[ÈÁC|ºüXJ>lÿ´3ÒTW/càC‹Ù'ä›;—KíRn‡V=jІ‡7þû²1Åcü.:KÖ%‘å—è³ð²i‚œÇUD8|WeÊ O©Ë'çK×_'eN^£= Ý\&Ÿ'^Çab^iæÙ䢉òäîâ„ÁòX¬Ì&¢LÒÎó "Ž|/rYªõRG†Íf j®Šcš¿¯" f^¨¸îÑÙpù”¬ÄPX÷*~xÅîÀæbäàiž+âu—°a)8hC+x¡Rj‚Âüµ·8X$á X‰:¡h*¦ßy$þ;ân¿ª`5\wQ±‹F i!{ ÓPVŸ›«šÁa˜ÇñÔœ…bS;`vaÕòôz[f(dKü[£\éÙÌePËñÂó@ž¦®9Z-óG|P_$i8޲VØÏOýx_2“ —GnFíz,±²í )¤rºÄ]*äêÇ*o zc-Ž÷OšZ›Ò\?GŽ™š”:V .N¾â›Íî?Âo oRç9m„3 4ø.l˜,›g~ÍòÙà`Q6ôs¸x«1lstv)™þk&\$³tMæc¥%œðØ‘,¦ï.õ* ¹Z–À“ÁW6ô÷ùF5°GŸ¾îâcÇ«ÏÂÎÜ%T,9µÖ žddᥠ½ðM¯"VñïîÁ¢uD9A{QºsÍõò%צ[7mÞÜ„+…V¥ôûÞYâó½þ.ë€_ÉùÉ1öñ§; %Æ70H-˜¾%{âFfüñ‰Z°Ðç»?Œ•‚G ?&m˜Ä@þÝÏb¯•°~˜çliçq¾?—ˆµWã¼24> ©ÿ•ã²’EB´¿}wk0š¾oé‹¿ñ¤,ô¢ aŸivðq‹Æºû­u`2Þàïÿ2!x5—§¾dZÅ84ãˆsÚöëþœáò‘6…nÔý%E»  Å[@à©ûi}¾Í[×4ú±^žþ–Ã/hV1²>}Ð6åÍ…®¬¯»Ä·ê 7Óâi“TТ9M•6Eæ&\vÇQ_2v¯p'  ÒŽøŒÌ]MØ.àƒÍÝ]¡|RÅ¥ìUZÅTrT0G~•…‡ó—ÊîEL¥ßy¿-fÿóRw®AçïR­å¿°¤ w& ûFl®tÔ1Éíï7ÃWÂkË`ŽÏ#C H7äóu퉕¾?Ë6–>1ÉÀ°é·Œ,ç ~Θù¿×!lêA%ˆ Na;jòVh¼ò‹âR°©_=2¹Ç<ÐN1)¼¸Ù}îs‘—™´­L‚y›d#ÈjQWjúøpü9Ù[‡Ð2s´¸ 5løX®½Ö“öé&ª”DÎÌ‹&{üÉŸ;nˆÅ®ËKñíÎiËkë]jv\R¯~,Üí±0FTCh Û#â¨Àæ] íipÔémÛ~¾¾.-²%y˜6;…çjy ”•!úKW½º =¼ŒÌM&OGÓs•øíboh´œ6+Ø´ìÅ”\<¬eÌ—“º»8|¦ù±äm8+‘!SlÙþœ®–×Sár ª#Uiè;bËNõç#ŸÈ‘È=#*dÃwGÚ·¯+ßÁ?<Í{0¡Ä<›q¯¾È6ëä­¾„Òusè™ëó–:ˆÓÃ(6ºbá2©¦ž!Ø^ܼÝõ>|àm‹].¤ „¸œ™Q[ÀCÉ‹´=.Ѐþ°(¥ ;ß ¥$ì>Šè8]™áf1cˆÀk\©ff)õeC¥pØ09Oši¸nupø¹Á˜@O[·¤ö/Ô‰e$ãJ»ô0ÜÎÈ¥nÿ¦:ß6 u1f‹X<Í Óî†V\Äi¼zKŠ`EòQ×½ìNå}¥¶Å:'¼Î5!ä5Ë^RšLËW‹SþeÒ pÖ7ˆâò¤zxì<ÂeN‹W)¬öÄo«s=d…᧤™Gc”ÖyðýUÛ»ö$r ÁÚ"0$±Å n°#gÌÇD#J J±k>ñç·¬LKMX i¡Ù|®ûb4õ÷4ænöÊWÑÈë{}I¸ûÈmôì\×–\m2aßäûNVá1DgÂÝ{äè¥C~¡¡ëÍ~`^?ý³.äCÂXË·ºEóe äVˆ÷Éo!ôÚ1v%åÎü¶ÿ6±q-V¶Õ£•áåM<*Vzê½’3× „‰bR®§ÀŒ#èü¸ä$ ÃM~p±ao¦ÚÞ«.›cÛ]“ZaV—ò•õ*&(8ÖÝb7d5Û./‡™éâ5V`ç‹m²cà7â›~¤œÙBÓHi¿T wÝ‘šO%<¹“϶aÁ‰ë—¦ ÍŠ•}l¢‰a®:gVjüg´’áæì3{5š"Ñȯc30c`­ñ•%û ®Á»~±R?%#Uâdþ¨ªw¡MÁ•ßËû'7—}có“¦9kgB釧h¹±wñQñ MV0ƒè={çë r£f”8>¬iw…ûSzJóh[Á1¼ +’JÍ®:¹]Ïè„”^Ô!¥i9 a]ôrÃR_ô>â`hMÓa¬Öm ¥¨¾öêÙN%DêXËÅȷ˸þ¯ä¾lоE±Ó !³vÞSÅ‹k±zB+ mª)^éÍ•ÓJ™ª`zeA½°‚cP«¢2Æ¡)¬oïF à½/@Ûé=Ùh,ºµïTè@µîm\‘cŠI/ìE …!‰‹Ð…MNüõÈÖÂBFC¢ëÆU•ÖCœ$R`aŒ[zÓŸ”ê[Ô;@¨uu»¢È¥LÙS@,!KÝÓÅ®AXáÖ¼zÀF „WùΙæj?ápäÀ=°T -MÌ¥ÆbZž~.yè ”0iD¤»ùQáû™$#Žvó}21^‰À =átϰß(üPò;ø¡°þ“O|U[˜ã¾_wM\§Ü¨ÈIÅî>– ¦—ß«>ÒSóó˜ŒÑlÛÿ0KX>Cט¼Ãds¥`ÒuÜ7?/¨&—……R<`Y4}a ÷æh'OÉ3îê½À¬õX5Ru [œ4ó´#öœ½a÷)ýƬ. èóê1ñïн ’³yÖŒzs´Ÿfñ °vÛ‘ ª+㦠)šSA(G^5ÔÛsXÈß.ñ\~ 黄üb*À#Ãý”Ÿæ~xMj6R…¾ Åè´â&bQìÃæ?ÖYÈQJU4Œî|ö=¾Ì=ïÀ¼†JàíŒ;U/Aô!ŸõS´õDä»âDjö‘QV2Ö'V$¿+"ZL"Èš—A)ä2õ…¶-kÅÒ>:^³ÃÉ$áÁ±[¡ÿ1¨ú t(Ü.} ¹¦~Y>+ÈûöéYpl-Ñ‚\•+ë³0‚0]­„;°»;2i‚CÓ;É&¿œjF˲'éLÙqΟDoú§!Çù îÙðS>ˆLñ Ó±ÿ¶Ø™|ޤ¯k¯t…Šjëagѵ+<õÄÿÆß¹²ZÝü\s×Ù ÁDúCT~(òý ¡5²±-™›ôcvÈÓºÒ貞hƸŸ >%"ö*·FB}Ù’OK'¡­“,Dè`wà>gès¹ãÍ+:ÃqnBû–D®(IÜúÅÛâD">\ƒ|l…•êvk^6ý›(láœvuhb:‹9€®—ÿEûˆÇ î®±1¦Î¸Ö90ÙYÇMä%¹J¶zr6È»c *S /ú8¶gk’µu`a¯]s€Öm[>lD–™TÕK `yJ¤»¼¢{A29…IJæ‹7!£>ƒ ár-†>]š]»² w¤èñZí¥¨Õ‹ñäYv¿Æ‚Âùq¿ÚØÌ—I†!Y`n´ŒP1õ¥æÈ³@ψf‡§£«j/dVЍp‰*Ìæ,7žÎdBq†$ƒ@6‹É¨Tqéwbÿ´ólÏÂk+»^ÙRŒaqF(šoÐé Š(Ï ·òAXC,.\Ð&ΪºU©Äò›ÖS”#åûaÎzÝf>²1F „+xßa~Ž€‡ßHGdEXt¢ \fÀVº5’¤ò½½ÚO£ ‘§æ€zÍúýnSø&õ³`]ùZì *=É_Ö²8'‰Ý.ñ  YžySýF`ì• ŸÄ5PL”ÚïçsYšÇ§ã³Ûo˲0Zбٌ y¯ó¾€Î$Îòi„4EÉÓ;?“êWD¹ÎP©Í¼-ùŸÎ‚ï³ Æõ:÷ t]Íç=ZU9¿gâ^òÆÊûãc #ÕFg©y\ÿùÙýôó†½#Óô¬º¤ìÑÂ{°4r®àpþc qC>žF¬Ë”‚<®™L«$‚³/;Zcðp²0~ÎAz©U"«ÙÀ´âÃÇÏS/מMQê,îÞ²~ýäÜ —=,÷Ü,•F€@z/õÚŠ‘¶âXÐ\‹í…¡éñ#«ÐÝóµ Ž“ÇI}áæ"ö¦Ézƒ°¯ ÌR+ß “Ázà 1g@Íã—šãGo§vDOÍD]ÔDy„.CÚJ eÓ]²&7 Tƒˆv"ª7}v–¥tR»;â5f \]çb½ˆ,J¤ÃWœjh£hZø†Ê‘/Ó£.’­ØNãjÜšâÈ+’zø­5ml; {ú™î¢’ÆÊ™ÂVUáÜØ'ü|ƒì$ó޳ûºÏë„ÇÛ^sŒêð½RT·Æ¥/ 8¼xM ]|0¸h¹€²±åVôÌ1·yí\«”d$æƒö® 8üÂíÝLø6³ççÁ¸Ø*lbITºŸHÌÖYÙœQ²ê‡ ´¼Ÿe¤<¨Á4uÍðÊëvÐaç¥@B–ç_@¢62ô`†¦:»,ÉŒÓ:Àê¶]X+šá#З!àÿA6±Õ/S@K®ýDí›%ùë÷iæ¦;Ÿnwydhè2S×]c}h¦ì=]™|SÒ7%Ÿ0k#£jþ¥sL9dü7ZøìS,é>;òý€lœÝNõ˜Ûín_lüyt»9‰Ó­o‡wýGÍÙÖšÔ•^23ˆ ˜3PÖXW[cSc7e?€ ‹3”¡õNó‡u ªž¥À_ÌY¾¾àóvmgˆs 7=³?Š= /Ò°ö@Ù«¾RZ~Sùn+ê…ÆlwØF¨RäKÄÓcëŸ8ûG­CþìTþ¥ËŽô„Á¯ÿ˜è˜5äÜ~ÔõcYÖÈEÍq!›õ§¢~j„ gKó:Õ8NÿÃ6}.È©¥Æ1Z$ª/îAÉ—ÅLSÍÃy“‹P÷­)õ䢊¼<Ôçav¿0ñÙgüŽž’ç;:›I”²p—Ú¯ Í»L;ÖgîÉë e0C_Né{~žûOxmˆ¹Ô&p•‹1^HrK³0æÖäK¥ßêi_¼,Á9ÍúÛÎ0µeå4¿E]®‹‡ç¶¡fήÆ,à# r5< ÊðMIíKÝ·µ;Ý–OÂT1ÁêÖÌRwŸ*æ‹ (®}H–nÛ,Ì}¼6—å¥e_k%ü•Ý­È \7Ó8ÆYa:+wŠWß8mñG»1 Q=;©5“¬ž­–ùEq¯óÕ™¼Y2²Cë¡Nšé…üXTƒKHV/ûç'Âñ˜²kUA7=Œ¹í±À³Å>ÖÇÄîBORïÍžáƒ-tHá·/™£ —n ü±¨ƒ1og^0Z{|°Æ2Q¶¶Š+† /}××äŠpl`“qRË;=Œá`B^p)Yù0 Ù(Ü@àòxÊß”zz0ZÔq¬sú [’¾Ó_ÀNîû¦VÇU¹•^¢tYg—º Ëàà,á9µ£ _¹ì¢Î0è»Å µ«Ô_Øs}Àý9+¡[°%3¸màró¤l¼W¢œª_šW€›QfÃã8/É©ÙÔ¿³ÉÞîázSí1Oã±Üƒã²…”gð`åNP!²È¥ÏÕ'á½€ÿÅF˜Ñ*Éû§{y¿Sø¼^Ý(m"ríOÖ=W°ynœ‘VüŽz’žúÕGLmŽÐI&ˆG†÷5 @°M'êD¤ËÔ[€քô ´ê6Ù-&Ë–/Bù£ FÍ¥t!E¯5©Vf7zm èF©^z¥f.8‡tøõ”–RíZ[b#‰ã¼í8ÿ}[ŒøÈÂÚg­öµ:ŽÞꘔ\GƒÇÌú€sµÌ_ÀôUðËÂ@6,:‡|Ëú‘û|N={¬SÔŒ?¼Km—I¦£|GKÚšÆÞ ra˜Ž‹lí÷ªÖpL¶qûtqŠÆQüym¶¡jNàO0±6P™KH¥Y:ž3Ôž zž’¬äFr¡L9vÔW|Y¼6hótx–ÓIœÛàëp½Cv6äåN- ±=Øòô^Ù K^oÙÐñÕêÜý3%|ešÇsZ]ྨΩ»Ý]æ+Í·Çí}Àª-»ñ* v!ÞŸ …M̬>Ø$ÛG“ëòËÙª&¼'‹X|¼JRÙqÓ#>^o$9éÀº}t? ‡ƒ§j½‹²¨·°ÂâtÒÆI¾À½µÊvæÝüãílñKêù½֫¹Šš“£câè;ôÕIÛå;˜¢é9€|E-è¤2Œ’ØOx/úªªK´›˜$©ÏÓ÷®ø$d7ÍÐGi*Ï9ì›—«Œ± HØ£ŸS?ÔR~˜i#–ö’¹*l/^eW‹ÙË »SÛv=ªÑT6@F©‡ƒãÅôî(pôdY&šIà“ŒÊz%"fCðr7im¯‚{¿ &˰ìá³e<À–Iã½÷"°Y®ôzx+‰Tr¼F| 9ÄìÝܵäðÒß9ÿZïà‹`a~' žô ‚3aµÐóÂM×C?wi„¯^1¬%©%hlqñ®©2‰1Ô·OW1%7~=Ê|Âüq¼*,†RøÄÌ!šÅ™ou5oˆÕq¼ƒÆb±ôX j(ÛÇDó&‚¸CW#C‚VbyTeÂ\¹%ÇÚ7nÀŠW™b¼ò[ý賸,Æûel#çf(ß¼!ƒ@󅆥»ß”ÑqPÂÌuS›ó2Ð%"|+ù­èÛ¢1b«ôÝÝ©Œ–ÿÄìÖt¼e³µÓéJa§à|ꀂyÆï__L©j–›}Õ åÛ Ù§¾v>ˆw‹#'CƒîÝS¢ðQÎðñ¤´?—À<‚Àß}ƒm,äYxŒ¿çùš m­%I,•ºùŠwÆïmDèÃû £O·³¿Ç3¸«P2ÄeôåVø¹Ö<ëV½¬ÏU{ØØ¶¦¬,I¾*ö+½ûâë••îÛ†„úõ#Ô¸7²˜•>@Šßäh™Û#÷@ʾê~(û’QÙA¨”è‡Jæáâ×.¬º9Þ»­ÏÎýŠRéÌðÈ)ñx”a\M0J—þ¦Ï-KWüs„?³·L£Bw©q†X‚ƶ¢ˆcfÄ Ni£„šîŒÙ·Ô×3írÁû–k‹Ç«þ(°Öœ`‚«ŒóÉbÃ|4÷¡@ @9‡hW–ýåÞyû¶Bø´Ÿ½Æ¶‚;üýÒx9`»0v´sWu¬°&Š/ÞÎ_ˆ¦$>½)Ñgw{š6¥5¸îµ¿ªÀ_A³Êéë û€âY?†@ìG$ë*ç<Åßõ‹÷T!ŸU¨(„éçNx1HÅbÖwÒH®îj¼ô’¢nÀGÑ{¥ÜÃ'™A˜žA,+AÆÂŠg;G-uVä"ök 0Î3û¯´ÌsY³Óí¥bϽ€ØÃÂsú2k©,(àJ~k•Óð2´4À-ÙèÎübÆÅ06r®ÑEóв°J²nLÐTÙ59œÔ¨ÛF«ÀKÅ æà‡¢£§¨.)úVm2ÐæÇÓª•¤xÊŽð»ùãgwµöÖÆrÛ] ®±Úñ(¨†”ßLû?ªXÒø/ï xV½먛¦³›Ñ^C¼Ý1a}Ïi|ú2ìeÌúñK¾¥sÆûitϰ†£‡ù¤pð#gÙWL ÏêPô(/È7Xud.6Ýšˆ¥ ·õбNàL&õ©›\ž‚–¢¨Þö.ì ±€‰—Ã590COØÕ½”| RÀqËš0†åÒh…LMyÛÏGr_½ý©P–MÎpÉ6Ÿ=òÇÞ Š‚@ÂÚ4o!™¤vŰO>òÒ°ð8ËPà©,{Ð>¬<æ>ù‰W~;\ô3óizKÈ6EŒFŠ`eìGmá=cÖ‰¬ÙYôŸ¹r¸ Ô t.ÖØTP6É©bWú4¾¥ª©‰ô‰zw=gg_ã‘ç2ÖÛÔQ ‰@ñ…q„VD@RN@ë6ÐbÃ%=E¨dbkI7—¼9jCñ’÷ØÔÈ©_¿Lü¢åýÖX×tXu§º3Ÿ·˜ÆK¡¨{Ì—ùBÂG{ å.ó~@h7Ö.4,õxR{);PzãÛgö}Vç—êZT±Ìï©üÅçÒÕ@ߣJ¼vR5!\î´nž]7¬€¶MêòLÂfªUJ#)"_ŠpÚáÎ9œÀ ÓÖ#×ÊÆn0-Ç ‹)•`±5-Lù(óyb˜Î:ÎÐU82ÇXŒƒlo*”Û^CûÝZ±Ç€"gõx1Nl&ͤŸÍt›1 ³‰>Ï–K×½…–ìa@".?Þ¯–ü4zôÎ2™oÌÜåäðAŽuÁqÞL:ˆþrˆQŒ<¸ýèÇvÇ.*á4zô»À8{s* û±ï„3Cÿ°ØÑM™àÔ#*21ü·i:òTÒ²ÚH4úFAŽ"fB ÃtvC7r<ÅMànˆc>“†ò{‡=Z^¥ŠH´ã†}.°RÔQXV(WÉùÖÏÝ;LOn‡v^f¼pA¨çʪ½à‡·ä{Y…÷/‹G™¥bk(©T¾çJ9ß ¼r‹§ZD‹‘„º n+‡Ãì[ƒ e©ûÏDXÏ”€åÛÚD"ªzOéš¡ ¶J)Ò µž˜¤·&(=/È÷(V·Ä§Èm.lŒ)-=¥™ïÔ’l$ ‡ªbx¹å4ºxP{Ñ"È’œ½s¾iÄøžëýÙÑLJÀ2‘Qݨ8ƨ³t[ËH.^û–̆Qš%‚a8Ü ²/¼þTCÁ® .ê躆·g 9Ç€$_q%q5Ëp¶ô»QÇèTœßQl†øüßþZÑv^1¬32ÏrCNg‚81ãUšƒDÃWRÓ UgCG'å";Óå[Šm4ºrö¶ «CæÙ¯+¢–Ç ãÆçvgzðlÂý‹=kØúçû×V‚È­Jìä7.L§?ìUÝ}Aòc ø½ÞËvØÚ¸Þ)çæØÚt~>ñâé“Ô‘M'mªâ¨ÛNì¶EÔœñ£„Ȩ6{”ÝÒþa{¡Ö¶šît) Ô,¿1õŽóq¯ùòÀ—£øµòïÚ¼˜RßÀæ©3æýÐÜÅ^WÿÿÑÍô8%I ¡‰Ý¸È>~Bð†™X]•<ø%Øyž„yƒ óòv"gÈ`™VÕsw¨šà¾ÁD~ ¯ê=Çï9¬ôÜ¢ä èªÞÝá÷EÜU*w"?Bá^%tÎ]ù¨wƒÒÙµ¤\LÕÐqãÕ ’HÇàErj„ªÔlæý—ž‘)Ä¡wcëbŠå¨çÓÆ—˜ëÌ'a97wœ Òù^¾ÊÌ™’ò’ò4¢Fé@ã%Ïs¶“Џ-‡!¦SÜ_ï};µAo˜¥“ŸËhìÅßnl…%CRصmX9ê­°žïh`ПטÔheì‘yüóQÙÇ­ž}$ìÔuo‹>p芔Ùp‹gwèý(&&3 ±°.‚^é’éÈ HbLZ³DI7o·˜¨·§-ß^„Þ,¥§é‚“² ÄÍ¿lcÅÿ¢» ÏÎÎà‰G y¼ÁžÌëènénBüe`ÁL²yry|‰‹C#lªÍðßì ŠH²þJå,¿^zçÄ–…OÁ£øQ+··Þ/õrcuí³»œÍ5¾¹ÿ«üm-½EIQcÇ€,œ¿G$½=í ½âÛ´í6–ÍO¿^‹|ê°Æ<¢{GÞ¡÷§)¨UåF¬£ñX¬ Ð)<¶øqiâÜ›µüöúÕÇ©”ñ¢?ëâ¸Â6œ\ŠÚJ\t6TÂxŸdií¿—V1^Õswãm óá¤ò?IÊ÷Ê_-yù!I:Û§&mˆ[c½¡´}áâ‡Î}O¯£mQ#x×.ç’´S¤1BQ|sdš.¬OïD]qiuàm+}ã‘Fqm„RØJŽT%NŠR‘âQåRza?yX]§7Uó+’Á¤ŒQ,¡ÝyAD¹ÄÄ–ÎÔCÑä%g2¯uK_è) ˆÎðMM7iÍæ9’øÎÔçŠWé÷V˜#Ô)Mj+ö-„Žq÷®xà¾õ¬òwÄæõ $5Ø1ü½YO†ûÞØÉNL­5îÙ³³üÈjä'¢Zô–"Ølɺ‚¹\¶{d™ÜÇ#`[|¿Ë (­3¶è0“.åóråšÉqÎÄ~¹¯@­Äáêý÷ózòAÓ•L£b/[#z»ø³ÃÜ¢hn¨,ìÚgvñëDæèøy´>ä-{'Å~´ ;gNÁ:%Šýôèkzç;ŠÚoò‰ J"E¯'¬m?Ù%Yy±E ©„Ä7¢›!RJ.éMCµÑóÃfy!Úç[øÂ·_d#_¡[qá+TáÓ†B–jÄn7&$bð9. 0ú 0Û:žý=ˆþÍž´îcÙwðŒ¢ZÏ2Yóœob U!"vpпø‚«/}‰\–õø%ùZæôfs™âËe‡GŸ2Ì%zô(kŸ^œ®‹:æÄQ£½?ô CI)H¥šœäA,·Û’̶#(94^f~8¼Õ‰¹¥ÕžÜE*Îz¶W´xŠóÖ—p †K)_„=OÜkX jõCÀ#¡g3­kjÍr ÓÈ :,µê75u5ï(P²‹ ùöbÖ³ß÷##4‰­pE™¢äe ™±ÞÓã„©Ý™e  usnЧß,š ½ÇÙCRÍ3}OånVÀýÎ#GšÀ çqü®2 $÷¼k–? 7"1ˆë¶îìó­o-,€?Ò_¸ÞÕ”–©-Ñ(7Ám¦ÅëÊÝ£@dǕКðÏXgºõOc#Âe Æ{ÜrKã³ù//‰µfŠ,L–*7¾y“exЊºöF`¿ßlÿlÑ\¼‡!çyKc³$è§cÛ¶ÙÅçœÆ Õ‹•Tƒ;º:'è¸g‹ E xzK9mb¸ª7’QøyÐýÜž™»¤µ:†Ë­>7Î÷®kÿ†*™©ÔQœ¦áÙÝÕÆÎÞÊÝz-‹G‰@Ê'+6Žhxï肾obyȪ—ûO\7»ÈT æ¶xÀ¾2f·ÔÅø XAtQÊ!Ĉ…»Kô<ðOÛ¶Õ¡¦$ÉP¼Åå4¤ÒShcÕ­×’°QxdE¸u÷=Ù9œ.•ÆT_†Âsu¦Cm|¨Ë¡ï !l'ÎSÐ6³Fî''ºÄM#µž ž˜è2yh2-}¹@Šì \R7Ôòý_mÆÇA' ÍjõÃ1θîzxIßS™ž5p°r#5÷bŒ„3aë5¿£¹£u,Óyoëµ°ó8¡ƒÛ–J½Oý®Âà…9÷!þXHóÁ[D$|°>b@I.E¤Î±“ËÅŸJÊ»2µÐ}t HQü‚Õì4PÈ߉Â*v5‘`ÓùópTÍ’6È ‘XQ’µ¡ÿ¢⦙žŽ7P#«®ƒ$¤|ÑôÑÅéXQ­2™(&ü“Ü+Å¥Cê— 8…yýráqšRœãâs­"ÈÏöè^iR'ä”÷Çð/µÂ×§`Ú–Q.žØÎü¸íXè±lΫ•þ9•“Ôëö¡b ì0ðøw±II lV–±oß°Üx³§ƒF3Y7'šäL(Ñãk¼DhØ(Í¢vH .ÍK!åø5“ü“¥í? Poãš -3_"³Ïg™€­Ïm‚þ®ßìí;?˜ccaÍåð®çÉö‹4^)ò²á;‚:,FÓš¡…á`Ù(2d5‚‚¶XÎ kÚæaÕsr2pJáÿL¹ŽFn$5÷.lyTɺÎHe‡1÷L™ìÈÝ£Iê”-Z®†gqV¸Õ"\‚§ùuÚ€§j³t¸ê;e0ûΰTÛàŽ o;˜ï1ñ²>‡¹ìòü€pé/æD"+åù°ãÿ74ZZŽ{Ø\ÞÄŸuýÅ(—h™ßÄQ›ƒj³SH4ÐåúÁ_èú³yî#XÎLãÛ¯h‚wÀŸØÛ%‰k ]"ì!œNIØlB-:ÔöÁ6©êB ö§Ì^ëo×½£Y&!Ï|¤n>+ [Îä4\nçcj nøËÁ¢þ,7|ÚeÄ5w±‰oQÔë±F¦%:ÿ´lÍ QòwOŒÑ†5¾ñí©Ãëñ©€½l¤0¸LF2D\öêÅ¥#ÿR¬¾>…9X m.Zà1±g*‚í·ß% µÒJÖ‹Á§Ù æ¢@üÐn¨ Ó§¿äÐ9kñ¼øpØNè*‡É™¶ÇåÓMÑ@r ‚ˆv(tw2ŽEØ1kÆ3%üž§iÝíËÚªW•æ·¹Y†½zˆTf³âìb„Žåcû¹OÛ¡ÞK4ü“º¥Õoª\u¨‹±·.)PÖ±ºª×-N•ªQß(‰ÍñËN ïnGÃ;—´­rOö8è”Zή‹¿Ën…y±ýÞ«E‰ÙÞ1Xì÷ Q\C¹Õnž¨çæÃ3ôwÅ”þ©h Õ2ÄqQ>ðÜ<×úŽk\¥ös,º ÿV…F‰8¢J˅ý"$e*ì4:,sˆ *é˜~ŸÁÎaE/S×’ 6K[¦^ñ'Ö2{LHèšÉýÇ€[N¢7D·2,Öw`¾Ùéá7ßÓŸ#ݶ*Òš*ü•¹…òy5¬Ð49Íx}áÁø,±8˳ÏÈéy'×N`XéS£mQÃUpýôº™_ä¥fðÐ$Î]¡8' Ô¢ÊFh_ÔÀÒBO3Á£ýnî‚1ð OÂÁÄÖ•iz®ƒ:@^ahmÄ!Ù=¬P©Ûð: lñ¨@Ø3ŽúY¢M–;¨ti–bþ~X“®„–[Åê ë±áÔëjµ 9ñº¿_ýä3TÛJr±^¨röèòÍ~:1¹ ·½l€]‘9ô½­n@‡@ãÞ´Ï…Íù>vÉ1¢«…FÊÂÈnóÆLÆf<¥n%³Z›Ó–UeHLàiîTæG1¾vJ;¬^ Qy9ާq=ôÙî­™ˆBg+ {ùQ„3ŠW&{-çûŒË¶`M‹¤ (õ´)œI#¯R,À*X»“Ø·:è®"¸Ÿ›GSû¥Kn½âè½üÌÄZŠ6¤ym`ˆ ô Æ>’Œ¢&®‘A93383ùdë ®"Þ}¨ºGÒ«ÓWöUHÚ¢ª¼rûš“磘¿$£_g|਷ÎÿÐZ>Þå0þ¯†€L¡Ë¦‡L{Ïäc xâ¤9i–9á¬×ZªJËö~Vg˜(BŒS è…ûNÁ(‘O+bÇNJŽ,ÓhÕTe×?àÁöÙv‡ðcCØÿ&4ã‚‹Á\gÇÅ‘LænPš¼¾·ñ¸ìÎØ«’éŒÄô™¹ŠënNa9¡½+J#ɤØà؆dIpdÈUg9iü“J¦"ÌohªÄp[¬G]7ƒ¹Ø'¹ˆ®OOpd˜o|xú©ÙX “® þAâqG55þ{¤Þþþk¿{e‰·I6!Mÿõ6ÿ C°Qæ$¾¾‘½.ñ!É©LpTð«2¶Öü2zeéH­ek˜Uy7nÚ£ Yž7à–‚i‡¾ÚŒg²uï-0=³ùú>a¦öái‚ K1a#â¼Ãg‹µýÙž}gª½ü,™Ÿ¨¢ôuÒ`sB.„›²Š>b3ß™‘ÆZ›ênÀë÷â EÀ¹Þš¨{güØ•¶Žw.¤»%•1²gwþ |¦³˜ÁëãòÅÕGØf@ º¿^¢‚Ó Ëš.úIÆP~ð­Š ÷Bn»øOŠmÙB¸;ˆ¹9RS>ëËrxŠºìR¬B£ŒlhS{ü¤I¬+Ö+d¬¡UAJ=ôktæ<‡·çÁaJàž›íbHmºè¼=ò°Ï‡Ñ ³ÙvÎÙ<9›§g´\/fÃNÑ•„0öyr*Pî’Æ=¬zï~ŒC¦ŠS0š_ 9HÆ‹ izèúì/8¹S_ÅnçËÁÎ7ïRç žñ,,$ï°úe®e^3ÓÝtÈ¿·nu¸g¤ÅõóþtO7‹C !½ñˆî|Æ Ÿ\C º-´ÕÚf¥bòË}½n›3öÎ`ìc/+öª^îGª°ðx}.Âè—©³‡ìˆ©×Ÿ•q;æf_§||S¸wÛâg ¨ôÏ¡1娠™…{êÄŸ –­ŠêNÆ;höÉûÛ‘ø`†™ÍOè¨yKbãˆ3âf- 6(‘Opg¢fÆD`+3?`BÇ´?v¦]§Û$÷qÿÅïK,3ëÿf’ÉÁ¬®HÎ'¬ãëîÔÌþ +ñšÖ-®[Zc«šƒN´·«°êÆÐ¾:9-’$Æ_ë& B^@ƒ»`ãª|#߇2£OÙî½ùñåÄÛÝ‹… e“d“ïÏë YÝa<ÖÃÑ{¯½:¶;ÝàšÙ¹zÓk3!gdöd©ûwv±ßgÝ †tx˜ äÒz *l®—«™½Kô§Y€yr¶.†«ø?U9'+ gÈ}ƒÑ×hö˜$JŽh&˜òj”–_=² ÃëõQ¤¯d¤þéì«›X¡ÃØ_þN5\m:ؼBqørgÁc'¹dŇÁ3b¡9@˜Ú|Ö7['­>f Ä·}ù½‘`Ƹ)®r´Å®3!ÁlB Â^3*©a`X2e£=»n.à2bî*ˆ³v©¡¬º ¢šZ ÑŒ;eT ©!½W¬m²ŒY‹EÌMîõ뮂äì^àúÐkÞ<ö^Ý3æ7ÐHË‘;{ïÁõü ^Æ¥¡ép<«xÉþr¦‡…Ú»c‡£Í<¬aÈé–Ò“Fî *å%:æLc(WåhÆF·û zîC~ÞØt¢Î7¬ÕKÂbP·¼;5ûïá" bh‡g–EEV‹LË[¿oAN?_ žºëäFŠ U7°üG?OÖ‹ã¹Îše/é©¶°v—Êö0d5Œ¤MJÅ?J§JÖŽÏ<ôºÃÔC~‡º m%äé¯,O)ì¡oP%q=9rŸñ­¼ðeƒOÙh$‚ †sŸN-ÉÓWT¥þîÿX1ñÚ±‡»_€¶ºî®Å¨\êdÄ[¡¿ªÑ…:n¿ðG|)ÉA#LÂ2R3lFž>ˆ§á<ÿ>n„×½t6‰-æV©ë¾0Ž,åí¨ÖvÓfG¯Åüæ îÕbÇŒt´—¬ 7Ò!xç€Ç± è mW¢öunÄ~;K Á~CáÝ}X± é¡9èkäÝÔ]OЕä«Af·—ð^þáÂýð=w:¡&›ßÞQâZ;›Ûªù¶«wÀ„=„”üþbìl»ÕùÔfñ ÌÏ÷X˜x²ëúÖh€68:ðkõ'ù)þ¦&I-·Ì\ªsñÛƒ’ì·ìëý —ÜÄ* o­»ãˆ:߈jtÏ} ÷ìÔŠÒM#fP²[±¶d!/ÿøøw šMIXiƒkňÇÁµ[ŸÄdm39Áèxâ ïêgW>0½ó©«KšO÷öèóˆðïÂð{A1Tñ\ òúໆÄþár p„f]”ùfCxNvÏw2+¹Fì±ú[ìÜäy­üüë®U6jœu7Eé°›‚þ09°¸½»Æ!ËbÈ« ÀAš‚…ïžm öςʽÍYÒ¿÷{- #xL¬6ÿ œcU„UÌ€¨´×º¶8G~—mŒ9–è<º³h• w5˜êDÇjx‡iœ–%ø“\s¨XÊ{h?•…eÍAÈ´£²»ºýx2ªó´Òݭ댨öž¡3³_XbÅèŸúïò®_GäöŸÉ‹ñ´Ê¤e\“¶W#kþ1àÀùc{'ž®Tmu”4Ïg–\¡"`ºö_Ú ä3Wò‰HL|;«†¢¥r)ÅFBÉèûÕ¸ñq3Ë×qÍzì¡÷ëTäeNÄßq ¡e¼%*ï*cÎÄ*!÷µvú«^¶Ùö«Ã­>=ŸØµcÇ#LþæÄÇI–6E£MsT?½¬VŠ Ü1¢¬ Ökpdé-œ[-Æ^^æ¾—©wêf(ç$Ï‹ž^w%˜<ý `NñZZ)iTgå*Ao"ŸMI!#TbƒÎ4œÜäÿ! ò vîzmÕ[û©aÏV½›È Áбì'Ö›®y‘GŒÕ‡Ð…¾2q˜5‡“ªA€¼Oõ.Ë#.™Ë…5³å,eº”³DøÀ]pïa¬ô)x*P½cGDsŽÛH/Åû—uý3$QI!v‡™4¶Ô k'…Öþ—[UGc˜¦;»›2ssnÁ³µð@ôƒždÀ„çY'H6ôÎ>Ç0e”‹›‡ùÚ¹µñŠÖcÂ(ÕÙþáO"pI¥ °BßB]–è˜'ó|Èrýe?oß¾¨õj+ÊHyèÇúQϲ ïNÖºú¥»çP>NîiÏxÞÇ'à¬åïø¬/!'„`¶ØP°Peý®{Šèè߯ØB¨› “!”¹2…LÊŒéW]=Îb‘\›*µOµŽAâ?$Öë"I'‡‘\åÚ ¤¦*Cm„A– æäv «Þ%éž?ŒëŒæ«–7¬ã^ÁƒÊGËÖo1&»%/Ì<þpè|•_o‚¿‰¸ld`]TÚ÷CxÌžã L´§»ØGZòòƒÂQ¹8ÉtÆŠfràŠ¡ì*ØyC÷9×mÊÈZö¨$/£#&7­!I0‹¨•gÆ]H¸ñ×nv]è!Kd›U @`vý}oŽ ÉT:ádÚ˜Û¹gñÐ`Š_pk´ûf²{ò¶«Àa-|1|:·QŸl”úÖý LuõÉ`ŸfKIöùæÀ«¬?S~üŽÁˆ"®É(£#?GëÎouÞ‘PD ²Ëu}PŽÏ„òI¡U„2njéÆ+“g€÷†ìYdÀÙ^ª$ÿ…†;Æ:Ï$ªÞž±é÷{JZÚÚWjNÕ( ï¢îá&DZB=—Zº·š †F\@1ºñ{ôz»KéÖº¨ ç._˜Å0˜ÅéH¾ÑµéÂ]Vî¼s°Á¨coÿGÁGcHˆ™ÃJÁ¦»wóÆö®/]²"ñtr“|¿ù©‘0ÑSbÛ˜çŒ+­_=Ý]†>"FuöñX9¢¡†%û2†NÊB£a¦²MÖ®´­Åp‚ùÒd¹fû úR¹}p´íúÑ4âÀœ[Ò­‘ï„áçvúiy¿lIy5ôó§¡c}Åf£z]Š»û‡¾ã¸§…Ý$XEW[)Ìã5Ì|òUûh"4ÛÀâG{ 4„Æs½lÈ‹ºeö”gC‚«‰ÚÀ«-V5 &­xs›]µf8tñ4],”ƒ¦ë.·^Wù‚_owmGŒ:Ï«Ô}#yh(< Êô³×ƒ±Ë{\xc5†3•‹¸-:lŠzPÙUoM7þ¯ïë(kXÉÞ>•  ÞE]ËÆŠXË•~n¨V'è¶›`²BOwãl9ždÒ ^ ¯Ç"ÄKð)|_š ÛûÇ8;Œh&e¨óÇLI³ò^;H|µüiA{Z$%à:‘á/¢xüÅE“û6(ÍQ ôRÓ^É÷¯­²O4ð_ d+°j¬¹¹u ÕÊcˆ¼¬ I&i$¯W »I¥š;[ö¯„:k.w@$pÒß× ›äFh(•“w›Îý6cj)î¸Ü™jÖ½¦ú:ŽG6aéi©Z“Ò¸ÌÖ½ŠOÖÖ:ïEȺ„wÕÍŠÕGÂšÉ ™%“Þ——;SqŒ˜ÕŒ›Ø 7ÞBÑàJ…CÍê+šDxéPçŠIÈÌ*. +Îh”±å±póÂȽ©„ß"ó1ñ¶%r¦â ‰PÀVò¸¹®ÿlBðµÇO~¡[îÌýZÇ›vY°"ìj[–BøVI]ð2Y9ÀàqûÜQ£™¹Â “Úá?D¥ù¦êã:{ ¥Ù~ì8™)›ÏŒH±U$ ˜È¹îSóÈ–8hŠÑ%xdømsÊNù>¿ð}@ºY±„ 8«#pÛ‹ý+špFä±óœ°eÿÀ#GgõSðèè»íåNÎÿlæw½ˆk²‘ÅëÍœKöíGúQîgÄö˜£ ÒTå ÛO2F”`ºoš¥ðØ€e¿gÍ6ƒÊrÕ3w6zå‰'' Z·ß(džì%}×[‡åγƒað«oT9œæ϶¶æïc·Ž×QžÖo0°ÕêÕQsÛò o ø\o˜¾Cû§BrNŽ7Z¢÷w‰›t„k ûÚ#ÂÒ“Š*¾#¹Æƒc8Y6{¾¸^õ{3‘pÅx¥1#ùÐã¶E¨Ûy ˜¯!¢%!§ Oä»R¶ÿöuö¤\dÛ)-^ìB†ŸÌû®nãg ñ—· ÿNæ þ™0¢lÌ8H….²R hór'u•¤«/;ÈžªC…a//$\)ò.Ã6î`tk ¡á¤£¥ýœí@75rh ·bÇ ½¨ MTŒÙMëÿ þ á9L­Oƒ-%djLÄꑘÚTB\yAK ¬HŒä¬C™ÔñÚÔ¥ïí8¤ßµÙ\¤ŸÏÜäO›±–ýiï¸Éæ¿°Sµ0î?“U³}n¦~Sƹ£ji{‰}Àذþá*”R µ.nfõÈlA‘uÊ÷þ§Â\±Ây3ßUóao ¶‚"$ÁÇFß±'M£½‚Ex|<]³.ú”CÔzøiHDÐä Û`Ûtq…VˆV ´ˆcÔÍ#tÂ'»5V|Òn¬DC} 'hT&äÞñÕWqd×lœ½v(k¹UãöSb@"Nf¤^M‘ªWŒ,õ€Î^APÉ@¼¨ÿàQÙá€1™7«síSV-öw¾²”‘vß2!›ñA'Ë궘‰‹ŒEkvòp²izuá•É_ÉnØo1÷q$µ#²D¸‰.U³íùhERãýUá\íva]4ž †Ü¨.¸fV|~³»u5³pe´XŠaí8'›Wª~¼¼ ™˜ÁÛÅG?n*óÉ•¨®ëe=7ªÄ•sÐìµýÝ@&ñžCŸÔyÙãÃÉ\„ÂÌô y†ý§:•ˆN´ªzW&νrÖ»?s*+Ó_î­`Jy»]è¡y²J4Ãe o³KÌùYÃ×.(È/RÏ} Ü­²8Œ“¥%¢°u¼Ãž(‘E oÅŽöŒzÔfáMpŒ,h±Aæüà íXaõBc5¦ÕçIoGj«…Žé’‡'g!M¤l¯mn®,f0«Ä4eoüþ"u¥+\Òðüp》„Ô!Úd ð]A›9÷Èú jØ~W>±ß×väïÿ8iv¢›†•&ÙM«¨šÁ¥1N£>#ð¢(ïyLÆwªã† ò¸ixNîÏ›PˆºYˆž´³ˆÂ•r—œ6}Ñ'Å<ú"¾Ã"Qè§;)z—×à-i59…û@‚—0!$Á.輤„³™dßé8zC½âeÉ#6Âêk±¬Õ&Àµ²%ž¨¶qHesjF,ãi£9•&úË=§Ó…šnŒöÝʳÿ’~MV'Ïm|—f‘0Tùú¿Ýš²ê¥ÛÖ."¿ä¶U¯ZñÃJ{º\yÎɪ·•.‰]ÅdÓrׂ ñúelÀ‹§¥ß YEàrW¬ú&s(§ Ã%ÓÈÍ+]H^5qgØÎœW6j"‘²P‡Ó°wûí‡Îí®-X¨ýÿS”ÑßUÍ”õ?…²&ú½/±âã­O“®¼Â éB.ý¶[Ã5dªò2¬ ø¦1"æVŸ´ÚÌG!ÁŒ‚ƒ …³_¹’Dë(QëyRcK5'‚§ÞÈRÅûH2‚ÕX-²8h¤Õ‰ÊØ1çëwrƒvto˜ð]ÎY¡‘küF7°¹éo;]Të© ¼.PþóõÅa@:Êl#H.Q³ü5Uÿ Ïjh*õZtˆeÊ»»´ûô’R´JùôäÚ…ñÝTâšW{䊛šCzXúʯe‚GpÍO=¶‡B¼[yþ˜ïºçõì/ÁæüD„­þÝÊ/lÜUñªzE3¶{][S{Òÿ‰ˆIGòÛúïÉ~Ò³wbJ±yÙo?‰§Zt8È;•3ûGŠ—MT X p è]g`Q("Û!z:¹ö0˜–Ô‚ÑCýNn‘ rð®ã €„¤CúbXñ`KÑÏpò{kúþLJYÙaWÞì“IÄN6I÷3#çd?fì÷Á4<èy¼°Žà…¢¯=Àm vK¯…óÇÒ­ØŠ×N`CÉÎWÛ|MÛê®°®je‚¡Qy‘/Ði~§ƒàÀt11ïù$HU©7š&ÖÒÒ°–T‚ã”IY•xë<Õ_ÃëL4Kã6AÐå\æ9'Šª2áÜÎðô^æ>ÀšÚ7¿!™ endstream endobj 4956 0 obj << /Type /FontDescriptor /FontName /ESIFTD+NimbusRomNo9L-Regu /Flags 4 /FontBBox [-168 -281 1000 924] /Ascent 678 /CapHeight 651 /Descent -216 /ItalicAngle 0 /StemV 85 /XHeight 450 /CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/acute/ampersand/asciitilde/asterisk/b/backslash/braceleft/braceright/bracketleft/bracketright/bullet/c/colon/comma/copyright/d/dollar/e/eight/endash/equal/exclam/f/fi/five/fl/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/numbersign/o/one/p/parenleft/parenright/percent/period/periodcentered/plus/q/question/quotedbl/quotedblleft/quotedblright/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) /FontFile 4955 0 R >> endobj 4957 0 obj << /Length1 1644 /Length2 11462 /Length3 0 /Length 12304 /Filter /FlateDecode >> stream xÚ­weTœí²%NpwkÜÝ‚»Ü]º&ÐXãàÁÝÝÝ` Ü=Hpw!ß™{ï¬33fî¯~Ÿ’]²«j­¦§ÖÐf—:Yä Pvn.a€ØÑÊÝMËÉQÍIH•] dëx•ó£ÒÓ˸‚,¡`'ˆ¬%$ в k€[HH• ãäìí ¶µƒ˜tµô™YYÙþKò×`åýšWO7°-ÀðúárprvA ¯ÿÏŽÚ jØ€@u C%5“‚š.@¹Z:4Ü­ÀÖU°5âbØ8¹þõX;A€à¿¥¹q¼bI¹,nÎ kð«ÈËäüWÅp¹:‚ÝÜ^¿`7€­«%úÚ¨ ±vpþMàUnãôOBήN¯ޝºW0 '7¨›µ+Ø xª!+ÿ¯<¡v–п±ÝÀ¯j€“Í«%ÐÉÚýoIÿè^a^µPK0Ä yAÿƲ€`7gKïר¯`ήàÒpwClÿ+6€+ÈÖÒèrs{…yÅþÛÿªð¿Toéììàý·Ó?Vÿ™êr°á@åæyi }m † rþ%ˆ€›ë_r »óè<@®ÿ4ˆéïÌ0¿&a t‚8x€ TN5'èkHÓÿËÿ}$ÿ7PüßBð ½ÿäþ;GÿËÿÿîó¿CË»;8¨Y:¾À¿n àõÈXB¯w  ø{h,]ÿ7KG°ƒ÷ÿÍëß­õAÿJ÷ÿ¦µ|m‹Äö•v!¾·\BÿR€ÝäÁ^  jm°±txíÛ?r]äꆀ^ùý§µvn.®Ó騭ßCþÁÿ/ü÷*^)û§NU)C}eÖÿýȲk;¼›9·€à¿\4^Ǫãí üÏxúÿùø (-íäðeçx `çyËýº¯© ñðùý‚ÿÄý_ïw–PW°À˜‹ƒ‹‹ûôï/×ߨÿ)˜þŒÄÚ øw´¡–àëìý§à¯ÚÚÝÕõ•òÎÁkýÿñþg @ /5êÒ¼“µH}jF´–(gà‡¬q_7ü@°sIƒNa~@µS÷ÇÔ°ŸBO5ÁãÂ/mÞs‡ÎÏ;Ê,¿†z»“A§yä~´Ì½ù8k ‚¬¿>sš•`¤éGúžÍªn  péýÚü¡©eVü„D1ÞÁëúæìŽ9€Ö#?ŸîÖÓß:¥>† »·¶àðˆ!aÿî–ñûðà@÷bïkv ½ˆ%‘Ò!u"ÔÛÂõºÁúñÑCЭr.³E¿'A×Ó‡ì÷¼;ÝMôO<î´^JÛ?R°Û\’óV1*ž§¡!hÑ<…ñâlT#2:ÊfuóJG‹ËÇõâ©ï3…¢Áh»ó ©´…üë/8zL’Šßg3ŒB z\o±Ó4 õ"Ä&ùêH%èåÄ1#$k†Ë7%‹¢Ì: ~”oĺ`ªtR¿Õei°ˆáÙ£¸w=¿\»ˆrIJÚ‡°EÞ"?j•ñEKl‰’Â%¯5J—ÙWN,!"K¤6EÅ©ñT9ݦç}$ ÅQ\sl¤ŽTÊ¡¿úp•dÖÒmüµ+UŽÿ3ÆŒ„ÅÄ^_£Jñæï†CÅ®˜Rñhµ\¾$££gÌY«šþÆF6ãˆ}“Ÿd™íÒÉÝ_¶E(2·g|„[ ºyÉ#!^_ÞcÎD÷×â*ÃÞ˜sÚr9(W ÔD:Œ"ˆmêïó¾È9ÂÅX-n~T}[E–ù §÷.±Âs5·Í9‚Þy僇GÆ\lnNíöWʹç ÷ž&ß$X"é"ç†4çÕ ¤Ì•äX»B«÷CÖÕúɰx:câ_5›”Éʼr<¼tޯߪfjŽ:Téõ#ET>°vW)i+ ú?*Ö©fÉVñ;b;~ )5öªsÓþõð tÆç¾É×à•‚Ñ4 ]`Ëb]IêßWÑà!~áõˆÍƒ²·4%‘à€¹jËþ­5'·ñêì¹U²;§|^7sˆ˜o3RÊû2fÅV¼×žEüX³Ð›ëÏæložD¼ ‘ vXÍ4û@5ØäЬõ—ìnèåVYÎbˆÑ¬Z³ æLzOª™²É[ÂrvÈ7!§ 7ݪÁÇu”™EÛƒ³u¥¾À5ÙgÞZ•Âñ“O {3w=YzF@ÜJ®§èO]aÔeðÄúpã/–&Ñh,KüÝnÞrTÂÈ­?•(`³ÆþdÀ*¿)óqÕ©c!ög®´ß(Ìôsâ«H¨âÑåÉ?_m–|ŒyôT8Êh¢ƒe&ëqã%à^Y=ô«WM‡‡·'g›$!]Œà¬ågåwHHõ_²L°n× ЮÉspÎòlê&æ†ß¼÷köðZv°<ïn¸O~IlÌÛh•CL¦O±?©ö ò…d›yÒ§Š>7œ`w«O¤Ÿxw Ë>áÌÔ\3J“ m˜ØB½WâS³~«(ZÅ\N•nê¿Gx¼°«”Ë“¥—Lغ(%êo­Y»ó…¢WO-Ç‘û|¿®'T½…|S³=è¯nHÒ ãÎ|øÎwŸ+ ÜžyOi¶–8éu_Ã#Ú€lA²#ýUÝ÷/Or¦&Ê^<„¤0yô}2|@ÿqz‚¯8h48"ìS*\JŽŠ(¨v4™öæ§dè¶AV>iZ–ý¡/ŸCÄì%•ú…ä÷ºþØU«E£þ»¥Õ"N³­N©‚Ñc9ùÈîš”\“mÖÑYûæî1Xߟ½Ñ×øÌØpLjŠ£˜´#ß± _Þ G3äÆ~~ü&ÖÔß­w¬b ZC>§Ö/—¶$n›ÃtFX.¡k-ëåŶP]0‘aØÎÎŒ šx[ˆ?BÞp ‘Lê‹T&ûÕêonÁ“ú´”¹ìL!DRÇZ:y‹5àa—£ÆÈácî<žh†‘Lêð™^ȺQLó²b}4 únëËROœ;:{4›´e‚,†Ax0m+áï :$A£¹Æù©¼ã?Z$ÖêA£_Lïýî ÍB‚Ódò“ Ö:ë/cÅd¶ ÕŠ–®Ùð¼Ø©}íTíÁRCìûurù"ãêŒÅ*»&ÙrñïÔ¡ÃeÛÈ­µ{Ö™^ŠA¼LQqŒH[ßÃwÅÆruÈ¥žù½™}§¨Ýû•©uõÉmã7Uð¿Ä‘==]h´R©ËL ñIîÞH5‡è"§XºU·êEj'tÚî2Á~éðÍ28†«—§Iþ§³’o.R iÑÄ;‰ñLÓoV$­÷$c·fr28ðxVÂä¬[½içh'îýPC—úò[: Å(¾É:±ÒY“ 8ÿhÉX4ù$T"´…ü1ÜŒ,â+º"j`d@ë‰ÊåUC¢ÚYš¾="·ÝÛt8”?§¬æ°+$ýΘ,„•öFMÂI¾üEßúùª½FoÊÊñëâØuÒgE˜UZËZ[Fü«SÌfª:#ÕxƽÜ|ô…†À$sgÍs–zh ›`PsSC1ÛG‰Þž@þÔöU%H[Ï*MUÙîW«šÛlÚ!ôÛ7Ï”œz~Äj4vò%B^Ô4]hÂr`<ŽA¹¾Ä`¬Üö à™u9ŹöŠãmÓ(•ɰÁ¨MÃ…'eu¼`Û-q®Ê¼YNH­¬rxAtÕ™´Ï”\(Ví»«»fF{§:‰˜É††\îö¨‹ø{vEŒVÙ»ðVb¬&búÇî–´ÿgØfn><+Å=«™¡o&cóEµ_˜Ë$õü;c'±¦ z³[rCÔÏÎG±›Ïò¼,áýË.5ÝÔ D få9"Ì¿8Yo¹Fê2Lç*ͶUéx{øEi­‰üͳÝ.-hˬ£¢b´+i™òzôÕKý }…õ²(—±Â¨mð¼O“^z2SìºÐB ¦þÂ4‚Ð/ï=õ™ž\tø^_1F]âÔe B"MÚÀaõŽfI×a™çÔ¤ÁŠ2‹7»NÁŒ£ã•d~èç”eàS8DyÌ<\·)Tê÷K–0“¡üŽ6Iˆp¿î3ó™™Óµ.¦ŸKZ5®˜õ¦è¶¿{¾Z¶¿/$8@ NcX ð¾û±J2º vë”Ë9¢îüc«;¹>)Ÿ¾kÙ8uíq9V—^¤Éº|óR¬]¿@ú§juLI(´uÑ¡¸Ê]AG|>ÑP9 ÖçYó²_ËëÎLW,·–¼DõbôèÌV-g^×ò 7]MŸí=3ÚS°nZZuœkÜwçØi°jßK+ç["íIqó´@sþ2[\aº.ÚÊ8g)|êñäºçÑé·DÝD®©×}kp]#LÌ2x^R.÷õO•ý¼ÙVœü“”cƒvá±xhPæÏ¡÷§²¢¤>®âqñŠÐÄú_j‹Â–U^í²ønŒÍʶF›vtkAÍRþ©þýÂ7¬nvÁ@5òÊíVÃñjøGÓ¬ý„<ôƒß.|œmë-Êëi¨­/6Ÿg2uY9CLƒÑP²ìÌp.·røµÇ!låâÄÈBåx”À…ôš®Ö[³‚ýTK2#±ƒžo£#ÈL^çqˆnôU TÇbè²ùâöš-k?Óx“øhî¦ÙxzײŒ`žEU_E°Ù÷b×–‹Q% ;ܦ+LZ§ËòdÐ,ôãþ}¯°U¯IFÀ6N3£#Æ(>Ä ³lM¸¹êÿ´à‹×jðgM²õLw¦?êe VÓ…€'! ÅOèÑ Ot"¬ç˜Ç2Öès¼ýàQ ‹û®h–JÀÏD±Oü˜J-(’ÑŒg ã:©Ãžîhçx¢YЋtAZS÷>ë‘´ã p¶ O'á#鑉ˆìÁŽ"©O×ÅÜ×k!¸TïÆžb+ìÜTôº–þ–$ÖBqÏöFy²Í_G%¬’QWzZ2ˆÜ–"Û {8’ì¸c‰ý"ZŠ‹¾¥®ÐátfiˆvÆsˆt)ÏÞi<_ùò½ƒˆDo¦¾íl× n«)-Þì›-<ôßý½õÔ– -~d°~»ÙæÜÀb=iØ/S’žÜë).äI‡Øäë€gQ™NASvÌ¡­±‚+èb–å99î ÞE„¯<ãq¬Ý5Ò|ó ¤ø WÍMC^e‰ªÙ*²l-G-Ñu%x£Gz¬!ªOõHaë0Å€×Ñ3óXŽ_pk‘ âðUBמɶW ,@þ.©ç„·†«\fôÏ™Çô¨vó>¤77ü˜³g"D[šïUE”÷Bª”ÆôŽóÛ±(^¤O «O’—èGfpÒ|ê73Í0s5ä:¡2¡Ç)ÂÐF‰åÎAÅ€àK$íÀöM|áN'Qž°TG…»Nu…¾s]ÒiÏñ^<À=êúŒéå!­÷¡†ü€‘xGgJ¬a%ÍFœ=è¯yûÛte2ôºÞ@EÏÞ±4N ¹, Ö¤%ÅXôÕaÈ”v€]sÞq3šìîYä×ZWô£Z1Jò?G£O"C‘®SZ°Î%HS†#wî<¦÷ƒ1MÙ=Ǥ’Ù=ÕñBü±]£ýofÏ6å¹ß~yûDö)/aÅÔp…íóϦšAÞØÀø Ñeà ¸¾–0i:µA4ì‹uY¸–¾ ¹?®-ŒÈÔƒWÐlbÉ¢ô}d€mõM²ÃŽ _žáýµ#íÛðy·ñm¦VM‹øÀ¾ŸÌë‹) Í3° U F7Aκ÷9û]TŒLÕpUÂê]!M=ŽýP÷Ù`1ãâÂèsjE}³s§‚†loëÎØ°¸¾ztÕLŸÐ‘(ºG AÕè_©®R³¡l§´Hß&#ðÍh Y~õö*ÍDËùµ³Ê¢N¼µå8wß7Фnथ߭ùÊÃŽ86\üJ@ÂaÚbHLZ'$jÈ´ƒYûœÊ€•Lg÷ L¾ÝÎ’mQi ðZ××´?q§'‹îîòFdßä|”Lìz¼@HÂ,Oú?´’>­ßöõ<‰sZz!o2>Ô!?™w\Ÿsù ä!j÷ÊÐ4VéÁÍ0ZuMÚzìåÅ÷ ¢BŒÓÔÃR… )ÆÕ%M¾þ z?Ô¶ÝQVÜæO³½Hs°ÕC:7Ÿœ™ÿLœ}%R)äš+°€~ð—ƒØÐ¼PXó½”,#¶–ê61ŽËP°lÎ?98ÎUÓ¯ê·q4–Óä?Æž÷ª:Æ·â,¸5º÷ Rö €ÈÆè¥?™ ¨`·¸¾jI2þ&FÞ:j3©C~WçÑÂÆ õ\ÀVå7 ³GÑÒôíQ®®¿¤F¬&ª;£ÆÍЃû´[+Ô&P»¦:tÙÙÇI¥G »,½—þ¬¸FG.JÊÞ8H`x#ot§x• ÍSŒ¡B0Ì’egø„xÝ3˜;dÍÎkF˜yWÌ~PìÀÝÕc±y(¹!Xî¾by¤Ä\aÊ^S²üЧŽÎå/Ï›ônócwq§ºQµ£cÓÌlÄÄ[$¨^×)VFÓ © =勚zÈÐsÿˆx1ÚæVqà‡'W”ëvð3¦fÈmbºów4qû cÉüæ[¦ªØ}Þ«:HáweÜ3Þ¢w´U|aÃØ>‹¼ÇƒMæòq;,;ÌüÍ&{ÊÎ5ߨɱ!krYEå»?«¿Ë@² ¤ {—ƒ0ªELÂMYŸKhÓÛî0B¤kŠ;t–̽ÇE¼ãN’F°A ÷úbÐhä2{ð¼1î+?ÿM«vÆ\N¥€g"åv_GD5ªD Nô÷Y… ã¤/;¶'ʃ'cÕŽô|ˆ¤í?Ñï-^÷]w8¼ Nm½…3Ö`Çѿӗ±Ñ§õà‡äÉq*ò©Ó–ö(ó 1V'·RDö÷cÌË3ãëGó5C—i¼±¾ê‡å—í™:ïnò]îAEôHw„¹àNexG· Õ“ˆ¬vÃ]¥–C "T¥ìóÇÜ!ÂM‡QX×­´º[~Ñb¬&¬3õÿŸœõðÓ¿÷"ÉK¦‹¼ˆ7µ ™UL‹Ú/Tã ´‡ûOàHxìö‹ÂÖ™q±Å#çºÌá]M§³’×kÂH^ŠÝi­N9ý”  À¼é“¡8îe\*ÄE?(°»ÝP9õ¾A`-éíDæ/¢Í»ÃF•ùq±“<7&2àçšÇUê!ÇÝ@k‘I³ Lf¢)·Ë—}+LqΨÁònþ3˜¼ñZªL·ý Ða´!½"I×Yœ5ŒõKìß‹ÏÖ­I¾€x:=’ÜêòÌ-»TÜŸ÷ ”¿ ª+»ÞSç8¢":`¹‰À›Œ çäGô}})%.ãU)¹Híiúˆ8IX:?µœ·³Qõ}µhÙ$矈¬7T;²Š®°;ˆ[ÍÂÙ?¾? X1îèÉjà¶cgݾ¹ü¦zJ‡4<5-i›\"ìpTÊçò³¹ž2à`’7”ÌÙ§ñP¾c`µ`]]k¨þõ-3k$,O¼ð8¢ a÷ÛÈH¬W<€úùµ ï½ ŒêÌý—€-xòë[kN#DFèÔ­é~–¼Úµ:[|Êq7“ä±5éä÷ÈÆé:Åò„ÒÑÒqSçBц¢=8Ü÷%'ò—µi’v}ç±—”ˆÍ…þgšqm•œ¬IáfaæTÒÑ&lC`I,Ĺ—¨b…×I«þìÉâî˜rä‹pñƒåòŸ:éôìž{é3¾7±ž`Ä^+%ÚjÇÖ´w³+r»`Ô/Y¤?ßésÖ¾SÜMz¾ŽºÎìRõ¦âú ´§´@éÒ‰ÆÖT:²ÐzÄŸGÆeš`”ÿlíï°~¦gW3°“î„!”L¯'ÙŸ&ÿÙ0XšÍô©€õÔ‰P‚±W3ÅÌo’ÀN¼ò°r4Ç@À»H&¬ë1ºóÔú;Èo±E ý„å $Úó t¦)ãøH÷ÿ´›MI.jè!ñW.¶×Ÿeê™îµw<‚CâΨ™œ¦ŒþØ#Ø L:|£¸?2§®`ú|+Ltyöàbþ…Ù'^Ÿ›ÚÁp´=ᣦ=™;ÏE›"\¸7R’ 3U-ß>.àdA¶uVNNçëЪÞÞþ¶ÂâÇD&¦Ï|‹Åö=y>/×.Çk]™à¦<%N(‘š¶Q+»”îXûªœBÙ#k8±#ÝÜïý¨2Ÿ8>S%Š[ Å»›ç>ØtƒZ¿ä®Z\-Û%æñˆ=œEôŽˆlÃͯww>fÛÎmê$EªÂËw¾O4ùÈÜ'Ê~É‚²ï@ÛÌ©s@R'­l2UyRkÂ5« ¼Oê%™b…F³Èa»„Ð[žiû sUuØëMC÷¡8ºåeƒá¡ËOËÝU€Ä5`Üe+›ÊræZ* :Ê1Ý3Â&ë£0ñ¾@釛˔±S±êªìûr[q‘_ób(eJ³å¥H#w"h(: ­%»d?Ø t ;ß}§ BVw{x¶|þºˆF‡áXß„¥ïóWœµ’æíGQýhÅEˆ5ާæ4£ÔJ«†Ô¦/½•ñ8¦>·•ký‰"Õßpü•øÈJ{ YÓâ)ú×[ò¨‹f¥„]XU·J+CÏ'z¶±£#<Â­út=»Jj$‡m˜‘•BPÕd£¸èâ~Tƒ¿$)±z0woÛ‚­¯üž†¿…M·Åd^},«bí˜ÇûÖÛ´‘åý³ñV—lk¸Ìþ¬íxºo´À5{Ï0!Þút~'ˆQzî#°6€Ùœo6-¡³‹Æú>D=Œ!6òâ~üÇàweßV¥¡N€&ŽËY:×"¿"ßö=|ªÞù¦q}›œÉù®#šÚ{þ”ýjÝ&D™Ï™ØØ¾]*æ‘W}¨ÑpÂ'ßüÊàHÅÛY&]¨¶ÄoÑ££Ôì­ï[£„6àå:Hº‰J”7„W I÷pÞ®ú€¶*ïG¨Výàì›Vxi–%®»;ºÄï+¾]ÙâY„N5VH/kHÇš”b#IXhÃ7-I>D§,|æ•äËÖ5 äG—à65ì&µ™ÄµÅcVÃë-Ô'û’í˜zjÞJƒD˜=þ M ™ü…¢EU%:²á8·âs‹V]{Étœ2M;! Á}°yZÃÔ­¨÷—ÞâVԘƖšÊ1â;"šÇB‹Á‹™8Rå¢ÔMþñèN²R—#—V9è.€õIa½CÑ´SM7<‡Fò ׂ;Áç/·¤ŸiÈÏ‚‹uÎy£J5š+_ÈM`õþñôxb™ù”LŸIþö¥ÚO+4Ю[*âÉFÓ58§Œ¿KãkV'-nK×O:ÞF0û{õ#Ãdè ³Ü >ïi– bV,eý0¬XåšH¡´M¡Nq€WÀ(Ò;<Ëß Þ·þ•ñ˜˜‡ç¨y…¼¨Á•° YHÃæ8|+µük°ß‡reÕQ²êçz\/=ºÒO‹¥ðÆð©vS޺篂èª4£.íÌr³û™nó?Ú¯[0öSýâ-öe )¡%͇gN¨Õæ!³¿¦­^Œéâœ^„íŠz‰Øl 6œEæ£ñ½«Tß븄°iU.Ò ×CÐ\f²]#Þ~.·L« VÂIîX×øø‚óÑ[$¼ŒgX^NKoý3®ÂpQþ -ñ)Å~¥Ú©(±À0e·eöƒ[>ã²nbR*~µ]Ý^¶δ”ioE`~Š·È÷5mb¿ü®z_P·ºÔçÐÒ1Jç*— ‡Y:ï¨ÃÞûÁJp†ÓXKðÍšégE샦«u3‹ÏqÎKÕÅ VÖk£GL•>L2Ï'°qãC¢¦QÊ—Ñ7ž´ò6¡qëY÷¨hV¨•ý[¸ýµqñ‰—Æ ~ÌH~DDœCÐ9äˆ[JĈÌSè…7HØš¨’U„˜;À";-^þÉq «¢ÓH-›¨6–ÑúØúÙé#ѯ›¹áÈd4 /·<à‘†Ë'S…1{cŽ©Õ4ù|F»ÊσmC\6D ƒæ cQI .³ ª õxvû ó¼ú8jorÿ%§%Õâ\ãÖo…ýÙ£Ç@ K_#Û ^†9{ÑÔ÷ó93ÙÀ‚ßÖŽßGª/„FäëñÁè­m—ËY@îwçóTN†\žÂŒ<2¹yq‰]ªV:þQ"ÎæN¹‡n K¿Ø†Z'<ózSZéJ0r¥ÆUôÊpø0¹ƒê¤˜õt:LCØ ß\åWìRàÀ%2s¤?øN‚O3ôÉÈX¹¼|ö+ÁÒáÁ‘úÛ›ûAÆIÅ0¥ŒÎÞdf$¶Á"{¾14d>ݦl­/yxÃ5艄ø¢‚b®'_öqóV§ZLX é n°åê!5$™K[#Ùj7ç“c6­ŽhÕuaE)š¥oøP¹=„Ž[—æݤDÛÝ&ÿ M»¼sÎÐúd[i"ãÁzÌ¥ßþy…ïäæ¡×#Z 4E0%´ºˆ.8žAeÑÓ7+Ì9+‰MÉú»“žáË ê1ùÞæsÞ)F)ô LQlµ“?Øà—]Wg}Kó‘öܧðàÔ'§4»¦‰Œ²Ú—FV8B8iÃß‘æ[~ —%“d©8êvz W#­Ù1¤Î ÒD;‚ᨯ¥(¦Aâ•c$BúËlÞ6Ñž›:3‡PŸ¼TÅf©«ÛßÞCãXÞêŠW ¢ÿJÁ‡m9 ÚKÍ.g+uÝý.Ä×j µ(?÷PÈ€'üâ÷–ýL•TØP'pMÛpcp‰‹rŠ•&§”ô‚ÚSI1²læ ý"@¿ýëÈ_äÅ’Y’ŠVÈöÁùòËÑtyz"ÿ~ݵ+ko[‘¤s9s×v)¶††!F<2ÃQ¡³Îò‚†—0²‹û8ˆ)’ôBò²O_uM6ºMßgb—vÿ ó{«ÆÜÌcoÇîy׺ZllÞhÅd³‚Íw¸¥BP`,èŸd½\Òà0&¼N\3g Y²üuVË»±jfÙ¬ê+’iw=;žBݬÁØSG «òÄ2 ­½z$ùÔ~4Ë¡D,Æy(ÕCΕM»§5¸Ü[œðR²dñ7ñçÿ£D÷‘ÐK“KQ¥ˆ9õ³™R©"B-KcNå ÞÃmŸèÔUªýi§ÿí¡sü¤ƒÆÏžŠ)L¸+e—ß±~„–‘Y[ûQæbehqމsï4Jn4½!1}ñðãŠÀw(—Í⻃YU®KJì/Š2 N“†·çÊ–@p“QyyG(Ô`‚}ÿ©FØŠþ;æò°Ú°"ÂÏ2¥)¶EÿÙrÞˆAËï8Hê–žg¯»{«=}Ð= 9¸ «Þ´?™^zkŽ]êù¶Ì4Ù‰M#wV‹jéXl/¨6ƒ•uQÙþ¥Œ;8<ï ãÝ\îÌüqŒYï呪´*–)OÓ ‹m*x¥Õœ¡Þ‡G,OýVÛ7’)Cc YeböŽ{Z:4w;p;àª_Í•ÓÂ2¥9’ÏŲ٢Äd'Œü ¹-š–µi ýqÇ^Ä–[r¢¸¢8íÙ ‚€ÎܶA©Ýß)V·&ô‹×e騮ùŠKÔ_ȃNûÄ]ó<¥”¹È2%ÜØ<í2,¥ä§”Cr6ëc!ËÄoAiWåêÉ5ÆPàí Õ3³«=14àCÅ3AJîCеd[G¦½Öš¯mº€†nÈÅ‹UÏÕίÉF– ¨›"È£ÒKuºÕ‰´™ñh¦e±gpŸëÕ,ÆÇ¥]oïí/Þ=*i(JsÕÞ(“¦caáW”TçïÍ”žT5xýwÞì±Ú_d¿½~kÄS'ÄR(Ÿ( –ß6DàK?³üžµ§6”þ@¬oÀ¬:õ*K“ÿj’Å`xMDG>I‘°@|‰¢ªÎi•ê85L@äw;H4V—ÁÌÂþÚNh‹ÿóYø{¹²¿F *YêvuL9> B-Š}b‚M#P»Ï²ãøýû,xÄË%‡äþC˜s"ò[+ç3˜x¶†Í ø%ž×Íf#s;Øà&äzd)ýzH”ùí'Ù5ÊJ?nº^Ýwq$”§h‡ôÀ¯x"ÉKM_ÌhÅŒHˆ|»¹¾ qÝì2¸­Î%PðÕQ„«PË—D™ÕYZ³(¬²Z[?œ¤Œ =¬Á|Cî"ÎAÀ&>ŠÇª+giLêÊ‚7u*ã­®vXC‚,å…òKmüGÑS‰­ãà‡¤­¿Þ„’17_”™uM&v^«Ãá594<ŸrÔœJÏ¿‡kWfêzXωíô{éP‰Ï*6Ë‚´É½#÷©]Å`"f»>+\ˆmÛU½^ ûLbû¾9ëN’ƒ9˜c}»XÞ«U"‹¡à^nÜ ÜȪ«hX¾we°b‘Cˆ|€nOÊ èù !ž7âÈþð%Mx×H~'ë*·+d} èµ!)àìoü±¦Ý²?5L´$RRàHIª;Z@‚·ôŒŠ£PœCÝÆÚŽÞ Hg)‡-Ï1˜ˆ{‰}ZDß{Ìò“æfÍ.YÈ ìÑÜóo$ß ˆIŸbßF4ï —°wÀ4ûÁ”†X0e§¤¡kÒ`B²ãyq+t´7ž."}¨Ž ~·^Ù½IŒ‡Ãí!C½*îÖ°½=b‚¿»Ñ¯À"{c¤þøˆ$ûžF³]_衾ÉH6@ùÛdãÆà9N›Âs?¹à/r?Ìa×ômn]ôŒ~b½é?=óVDðTîó%&ÎÉ(&†#°+¶¹:¾¿¬½Cµén^b¢œ9­zoÔA¡w¹‚;{CSR»=$r(ÕjVÅ»_›¶\>ÎB¦ö\Û ÈG‰÷ý3&£èîü> _cÚ#7?p¼ÔÝ("Vø1°,À,ŽÔ+T][þžIÛøŠd´üAw’íBÖ-OVp¦ –˜ïÛÕXæ7kÜ hf`ùÃ+¿ Ó~ÛDaiöT¾–ľp‘$ÀÊi˜ "òeÑŒ±Ç™DA‡ãó/à¢&Ôzi©V|lÏ_ñvU!CÎÏOKx_ÐtôÜùY¾!nÁ4\ÑúwÈíÄÃ9¶É÷e–$ðùp[¬Œ( ͧɸƒ-ÝÙ®—«3Åhçn *Ê;ÇI¬£1»u®T[çK¶Ýᢅ;³«1 ú–8 M©Ä3á@±i4 ¬G~/¢ç‡ãz*Tºº¿ rñÁ£¼µÞA!L—‰qsN}RŠýnäªäÖ2Ù/Ž“¶ÖEkEÔCÛ’“¾Ž2T«îAmLìÂ3³•sb–+ÁA·wÊ-±ÝÁ㢇ßc>ÖýdT°Ñh»±/í¦Q–ƒ]^LvÂw…)Ï„5¼–GC)ŸîMRÏCµXNµÏ<®™êº z:LxT8)߯„?éº9¸.Ø ÛÛ„òÈSÊ“?‰¦ò¾"Š{ûQ`3ÿa?üI¼_ˆãx i´x@Ù}/ó£å„ÈxèWúû åFi»ó7µ:枀|1ÄÌhVÃ,´ÀRæaÝÙCxScx';´E«Ye9AyÖüç7Ä£çè]…~Ùõh$Ð-(ï¡=-‰‚pRE*k’¼€6(›1` 1$ÞÉkâ€gùC=Í=Ý&-Ò}Åi Õ„cDc¬Õlœgº*Sõ•‚.Dúc=aU˜Ù{¿c†Ý‹5/’åöØ{b=ƒ§”¥¬780{Ñ­4ÐÎŽ,Ì jù‡Â)„÷„‡,lRHšý+“ãR°\ã”Þ¸±&p>”bÕYJüQ×hZ¼²jR «þ‰#áª6ûŠóÝ¢ 5ë Õ¡nýWïÜÌù~·‡~ÆDsËÅ}‡³é?~Ïê4¼gò7N˜v¢)$¾†wI=ù¹—ÍRµ#O¼r;`çÝ`Šž5ÑÒNÓ>û&æÎ­-—"|ãb›ïgn09{ .s"Æí´¢šõÉ SEÔý½ÀQÊ€M?ÇñÙ‘ü“¿Oâ =J½G 1ÙµÝ~%[U‹òî°7æ£}x lcó§Œd1ê+¡¯ vß±kSÏMôcšÅušûCixbâ;d÷˜[—oJo&v nÃØ Ï eÅ«¾õJ·Û.ˆ%üƒ>Ç endstream endobj 4958 0 obj << /Type /FontDescriptor /FontName /LAYWJG+NimbusRomNo9L-Regu-Slant_167 /Flags 4 /FontBBox [-168 -281 1000 924] /Ascent 678 /CapHeight 651 /Descent -216 /ItalicAngle -9 /StemV 85 /XHeight 450 /CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/R/S/T/U/V/W/X/Y/colon/comma/five/four/one/parenleft/parenright/period/quoteright/seven/six/three/two) /FontFile 4957 0 R >> endobj 4959 0 obj << /Length1 1647 /Length2 16471 /Length3 0 /Length 17331 /Filter /FlateDecode >> stream xÚ¬¸c”eݲ-šf¥í••¶íJTÚ¨4WÚ¶mÛvVÚª´mÛ¶_}{ßsÎmç½ûç¾ócÎ6Gô="F­­EF,¯D'ddc³±v¤c¢gäÈšY89(ÚXÉÚpIÓ)Mœ$õ-16822a{ ¾£™µˆ¾# 4ˆ ÌÌ&...82€°­›½™‰©#€REQІ†ö¿,ÿl¸ýò×ÓÁÌÄ@þ÷Ãhick´vüKñí¨Mc3K @XN^]Bö'€ò§¬ à'Ðhÿ·y'K3C€´™!ÐÚH0¶±Xþ{0´±62û§4ú¿\B}€ƒ-ÐÐì¯ÐÕhûD °Ú[™98üý˜9Lìõ­ÿž£ ÀÌÚÐÒÉèŸþÚmþ•­½ÍßV±¿dò6ކöf¶Ž€¿QåEÄþ§£©¾ã?±ÌþÂã¿;l þ)é_Ø_š¿¨£¾™µÀèêøO, ÀÈÌÁÖRßíoì¿d¶öfÿJÃÉÁÌÚä¿2 ØMôí,iþrÿs:ÿU'à«^ßÖÖÒí_Þ6ÿÚõŸ9˜9:-éᘘÿÆ4tüÛÄÌŽáŸ~‘°6¶01þÛnädû˜3Ðþ_DùOÏPýMBßÈÆÚÒ `4†cµqü@ù§2ýÿœÈÿÿü?"ïÿ?qÿ»FÿÛ%þÿ{Ÿÿ;µ˜“¥¥¬¾Õßø÷œü4úÖ€¿³ øgØXêÛþ8f†ÿ/W}+3K·ÿ“óß­üwÖÿ‹ó¿Ãÿ!dmòW!:&6z¶›ÍÄÌ\Fòfކ¦c}Ë¿‡÷/»ŠµÐÞÒÌøWäï_'FÆÿ†)›šZXÿ£Û¿! µÑ¯á¯nÿª€AEAUHV–æÿ0mÿµYþoW8*»Ùÿ+’šŒÑ.þ¡úñÃÆàAÇÄΠcæ`ü{ÿ^G.fV¯ÿ°ÿ"bú¯µŒ¾£½™+@“‘ž‘‘ ð÷ýÏ­´ÿ¨µ¡Ñ?}¤ä¨omô·õþÓðlèdoÿWñMƒ¿•ÿÇú_—t­,Úòš§f¤9þÆÊÑüÓÃ>d[R¯\˜ï[mÓ퓺ÍU¡÷^Dß0ÉýÙê¶pjû±/I}0܃iIÑ ¼ÌÃ÷"¡êÍGÙ oç 9ðgÐ)AH;S‹ô¸š—Þ‚Ð`gT=ØWPÔ)~‡"˜lg±‡¹z¢ò%qÎ÷E'}´Eô6L©‹Áè@nAý]pzFžpüôHÑ?248Ð}Ù»G“KÆ£åtJœèè¦g_oø ùêÌáï‚à–öáDâgý=ÕF¸Ö}ö…Ù—²½ä.`RëGŠCýŠi£ûÕཀྵ0 ?è=ÃÓOì7I´aðí5òþž$Fü¤MI•ôNç_¾õËÉžb ”,éç®·ú¹jú¿XM›yÄV)×2à•8)4ûà¢Ççe-9ŽæMwGÕÔIõÖY‹RÄ¿ÅCålaº‹{Ê )OÀ° X’¡ºÇ弞|<·ÿ¡X­dÌÀZ»–ÏX\a¾yëþ^gÊ!î=©ˆÞ…–‡6ë¥Ó/Q ê9tÃðÔÌÔT/bp×}$¼Ù‰]–½Ê>TÅv™ÍK-ø–¤pp¡u]]¼‹¼ÐŠóý=}/]žÆ_üNu*ÜÂoPQ…U?µ0« #]ŽoD-“‚k¦€à­7Ü/Þ:ö}ηp=¢ÈS³ƒu NÝc‚à%fQ䃟6ï7v·¡·¢„ìY ¯šæº¨úN8|xvuiè÷˔嶯NE:î?wÉ„Øß0yÙuÚ…@BO44gAiÅ:ï{)@ÕK"&­†Dú{«{`¼îm—èÅð}ÝnŽ‹PÝd\¸pÁæ)ßGËåú'ù¯¦P•–ßÕEÄ“+ò{Ýê²&'‹Èd–8#Z%½ o,s)¢Nóˆh¬ª~ w»5bàÊÆuçÏsÁÐG>åjurq—1À֚ݘ€[u CKí*¤f]URènUxNŠ5Ò˜t`^«©†:D× }m™kB'âO@E¬ó`¡F¿ 帙6|Í*áë˜U^q¢¥9œnƒs5Q¦î÷‡î”:ÚüÔ8¡aO¦™æT_ï­.Òs$z—ÉÛzzZ„üOˆ)ÞW*|˜7+¨HuœN;4{S\ îb>M«XÑßÐŒ6}'A¤¦ˆÉ0©.`s~Š@|\UôäóZ [ðÝÊz Vqx}9ԣ ‚q„#'9Z°Ö`è:2DºO€:ø¤Ó mý4°Ñw·ªRÓ3RlŨE!ºˆÎZa…7ÉùN¼©6ƼñÑÖ·‹`©7–;„~÷[# jåñ‘’ôŠ—š[œ”£<È‘«3 ný6¨u¿‡ë®‡Ad<Ñc†2ê’‡­‹ °v$–55¼KÄ)ZHÈW{¢aK_‡¶I·£>ípšEcPßÇøFÁ´4ÃP]žÂ˜5e©¿/%œQ‚Ž 6¼!ÆÙTûlwtL Ù•Iòû$JB”žF%äYšT¼£I- ’sæz,»Ðq‚q9ꀸÆMëj<âb©†?žóÕÑßËÊ­ã5‚¢”´Îštp~½•&ñê×’Y:Œ¥J!kœòDÀá4œûMKÚÝþW¥ŒïòÁ–EÕ3eéB|Ðf‚X‚¬°Øê¢Ã’-¿íæÝ¼î5l²ôiÚ5…cŲ_¼ÌC¸Äx|j2OcM?`ï¿Ò®Ø«åP=pv yÂu²'8Ü{¹˜_º)j‡ÛæÍ%±bàæî÷_¥ö ÉyÙ¦Zø°+¹8­7 ­-¦šñáL•/ÛøT°Ôl&c>õíô„U2,¼ôY6•Ç…vCË+Œ-Ä'»ÜzÄ‘HrX&÷u$\uuV…ê4ÌC?Åd“{¤¡ÑœvÅ©H:¦d©ß*Tç?Ÿ]")¢¿úu 8»Žð¨²S峸Q S6¢¡AНeIó ¼D(”OÔßÃ*Ìy*ý ¸¸:Åz/i”JjÜu¡ví+º Ú(–#£òd$#†*Â@~_ÁóøÂõûgÏàDdX¡A3Zç®9©)£*¸Ù‡tí#þžÜþôv¤²Ç¸y¥ƒÞ9öªÑFü¡]pò! l¨Hç´nwþ5‡×l–å€DÅyÀÚoçzd:^ÚòjëÆÕ7å9J¥ýí+:S/´œÀ̸8L39ȲW{1Ëvâ²òa{äqðÆ¢­ÂC4J  á d¥’þg@gçœ hÌ£èm;²»¾./˜”á?À?ÓaÃL'E‹¨/3CµÑñÓð£äÿá*àÌ}ôã~I‡—²¨›ÊÝfו‰Ýf–,à"'h·|&_Ÿ±À¶û±å-vštô„øi¸ž`T»2.ÔM^OåátÄ'báD†mþÅ­Z*î*¢Ö=ð³yôk)uŽ2dÚõè)f#ôA}cºŸš<ޝЧ3?çtS¢ÔÇi|sm0Ч{NÑgKѬA¦üVuP“47ò\E¸rëÞ ”á¢t¨ûÜXZèêÏz«ÚÔá§ ‚p¼)U2·kKvjr†Ðåáa(¹!ý‡^ÁÆ1cLjg˜¯£V·ÏÙ+e´-þ+Glcpã1¼ì~¥Î[?—Õè›\ÿ¾¥ëO0oŒ…3qËe>IJH‹ü[ÏmDèPŸªãÎw)Iq"x`ÑL!DÞž²R϶6 ªq$óÅ{²^ï7Ú¯«S4Tèºß&¾]j>©Äßja1ÍÛ+ݦ0¤æÓÐzšašTñ®SÒcP.¯“6ZërÐÊî—Ê̤~ûߊv­v¨Ô»PÍ8‘ß`~9ït¨èÝ–½i‹€¾LXf–{%r‚P-¼N v>¹=‚=öÝßlÙ°²K“}I:=4g•ú`uC~Cg%%\c1£Q» Ù„c€º繿 3ŽQ¥n Þ’êï[ìG¤=CŸSG áÑ ØÞ]Fy˜Íyú’¾l›1 Æ›îôÔñÿÁO’U"[ —qÍ›¹Áb ÙæI`Ñ]úíIþ³t€OA²\ZöæA`k®ÎB¯¨Úª¯ÜŸ|®šö‘V5×+9ŽÔÞž{N¯T1$I;GgPÿƒ‚wûÖ¿¨tá^°mž@06ìƒNM3²îÒ7¥¹ˆ‹0T½@‹V^ÊUŽpKyÒ¤(a– :\j1ܳÏ'ß‹ —E)šû‰G.–ÿ@d”žŠW)hP[>1ùÏà›;ñ¼gèÛBbx\°¿Ò†n¬ÎtÞi›GË!–í¥ðhiKK50p—y&ýfÕ‡¹$n4N&xÐü³ˆ &\‡\â%ˆúi['ÃáØ/ï×£¬"i™‹øÝ>p$ôU¢©¤¯ Yê ÀíéZÀÙ¯ý%(¦©›ÖÊé±P=dPž±á Ìšp…C3/LjF]ò4W ÏÇå ˆEö1N•·Ã¯ƒòú%©ATÄL¦jž ±fÅn#/cUòF~Àù üT=+ugŒH:ü€ù5÷ÄfÉD8?m×+¦•´­9óØ^ÉKM-xõÃÄ1§óA—ý7FúºÇ£ß)â8ÑhMƒÃΖvBÉÂFÌ/1ŠÊÖ…®a2kgÁ¼óLGËÓ~;A”Q ò|E ›‰Ÿê9`®ËèÈ‚Ué“{æ‰*™ÑÊ):òÁ' h^ç{ÓxÁ=-ô’Ï¢Yágø¶I–$.AUaBWSà/ћɷæ3˜¯î|Ž÷šCŸ\Žþ­§H¸ð7mù–hï>µÿyÇEk‚¥ŽUúκvp•vÕ”Uî¸ç#"o¨Éá{£ù¤„]¾¼¹7üj@‰Wãü8ùÏöR‡ˆÁ&C°Ú³C]¸qÖá¢s[’Rœ$í˜NlÜ” ¶!M¿¶ÇÕ°+‚VÕîU´ßª˜ÊM£éé¤bœ…‡5÷˜hl¡ks·òoEõ]{gwK¥wö>ü½‡0æôàã0ãuš4UMêwLš»KQìÕoé 4ß;%1ýnö ¼¦$}¿å~ ñ—N€Å ƒó ŒYw<’áæµ4|Ûœ)_/†óþ¾#Ûg"´yöK‚.“VB¸ÖŠÔ"ì[¹Q¾€®Ÿ=_¬É!»#Ù)kDª;= ÌÙšð0µ&OΆâÀÎé…×Àôáà¡¿>  pÍš$ãÚdź±¦ÌŽhè"Ýü<˜l-_Š„+e<ê"_ÜôÀhs/è8Gš`Ìš´Æ!m^µËפ2ަ¸©1ÊH¨Š_Î`×c„¢L Ðð1’Hy¯aîíV/ÙãË5Á‹BâQˆ|6Aùnq¨×Ÿ#¥ŒÈ_«°À|›11E—ŽÉ¥ìóe[Ô´Õ çZþlŽøá0IŽ|ˆ[—&¼Öûí¸–HùºEïgߪ;Ù§@ÆÙ–ÏßsßEFN¾Ž,öšu$Pµ¦õú„½#W˜c¾‹¼NU¾³äÉ‰Í „±³Ù‰ˆUÉò¬"g˜yŒÚ&: •§®).ÖŒ¥nu1Šº2š]€œäL°L–$â«ÔºŠ"åÍl›êÏRýŽz'Y€=Ü@ÔÏ.·.0è 7Ç8Z(Y5Z”ìK“¡:þÆ×[i: á¶SµI@áº1ºLÚ™Ž=¬…›0 Ê¨¶¿u ¦ºvoú? ¿Šo)¢òé3¶C:öóOhž à¥,sˆ;”ÆPùH"»B˜~%Ø¿¬†ö³Ô,É[°õE†×yެ”Ìœ'¯É\éS²ß.n…3Œ¼$¤dæ™ÑŠ–@º ®U;í•kFAQ´©SwýT®æ¢Jå)Þ.s ͉g%_¯le]Ó/ ë‚ã˜<'Žá‰bdÈdS¿5¢Ú_NP]Ôƒéf 6k,ØBb~€1æô~Õeú™HyHŠ£¶Uó!jªs"¤ˆ®Òƒp¥††Æp1<zs»œ9Í8T/%75C¸{·;"ØZ:C5½b{³±c„ÿ½ÌÛµóE†ž>¼Ý-.gK†Þ«‚‡m)vŠãòçùÌÒÑ“ºJ³U3yfËI:º”ÖÞHàÇ2zz2^"Èš¬—äoU®4QÇæ$Ø#íºðý¾ëðÚâ#|Öcãy ”*x4«/¹Ñð±ëYòÛ»2¦“džÚ"&!\·<`a :¶¬q•é–œë3RSŸŠÒ‹ÞGšal;°Î/¨q£‘ð‰#5ahA qY$þ vì¸9JÇ7ôWÞX(úŽÍb9¤Gh0ù s0²Á]“܇õJRtnã{Þk1Ôí夆玟9˜Øa·,?šFnð-"‡.I‡`ºÓ£N½Sß4l÷'\D¥ü)qMT¨—ØM± ÊÊ/,Ï÷r:F·ªÕÎkD·c 6Ó‚áÃ,«È„«ÄÌU €²†_£(àS«w¶#×¶ísU‚K7šáÏ´»g\hÂ`ºÅ>×cŸ9O1j‡0jƒÏƒ,íЭÀ¼!p[¤ñè@ïÈvÆJ#˜(XŸŸ°DZg v"üÆÊsi´"qè³*£ª–=ö´Ô…̶ s¨@]³ÏògÒ ‰J{!ÈG2‰§Ü"1v(-"$½œ5fÏjw‰‘±ÛÓ'=ЗŸHÖT_ P+@MÍ_ÿýaÎzb?ðÒ Ñø ®?ì-Œ ÜwýÔÁ¨X7æIÀ.7ÙÃõe4÷¸eámö%%þ’<˜Ó©p¼Y*C2zã@=zÖQÌq»í¶-/n8ÞZýú È"æDÌWRîB”ãk"ŒëãO?¥ÝÇÄ:f4}\óø=šyn 93øþÁ©FàçáºZÌé›!’ñ ¤~±M§Tªt#ûbn­OGŠÈÌÝ«þQðf¯íÉÁ17Cy%ìNý†"°*ÚÙÿÓç¬#´ÜξJU}™.Õûû«\÷åüÂz!6¿aì-Þ+'ÆÃ+-l›BÈE¬‰ƒ¹ížYWp¥N`†._·ùYiž¢ZõèMÎIæ,4S{÷¥®ˆÛqAË€‚ÅÈ]! qnÏš¤S!ÿþUæU¾ùÜzS*nùµrYÏ›åäx——qÊïeh7ðß3üßùåùíiè]¼­}ëõg\÷ÑJm…Hä]®˜;÷ºŠú Ñ’ÄOa킌ßÙ¨)æ–ž‘îžKè7³+£¸EáfUÜu?ùC1—#ûöì{÷“·8Ye>„û×öu“X",=˜è ˜”~Õ‹× &ˆð`îûLªûeªPüôð½ÒÛ+‹H)¥&¶½WNrsׄ'€v‹ìˇ„¿Ç}‰<$¶Ö-Ý0¾önGrÉø0Òö{î¯Cè3²ú¸/dÔ6æ4’ƒAìôcþR0 ¬ü ‰s0­ÿô;hº,‰â;ÇäOóH˜&Èï±E·ßyb5ëºí­WE—j<ípÈœp <ÄñJÄ„·W6ùvªüˆ+Èõ„RR@ª)ú×É)Š3[ÿY•ùºw²¬¶­s¿GÀJV—·ÕôçQ~G÷Êtª™]º¸Ñ5ßëœøË»j'-ÃÓø¸àìzS¨ÙËþ᧨ÆëIy®¡rf¸nÁ“ÈÖÄâ,GsIn‘Çe1g1÷ç’hßÙ”õÿñà‚é ÷ÛŽsßÄE7Yº)5Ðÿ†Ú˜¦² ¬ìŽgL°Ö«Zœ¥Ö°ñÝjG²Ùq}ÑËÖ˜wÏēߋeŸá¥Ïƒ¾_2a 7ø Ë£þ#Ôø3ÍD–ÑŸªZgÛ\·§!ºK,#çæ÷܈Y:¿ÛóSÅ UïÀì¯ H E¨1ʰª…´$(H*vIúŠÏ!Qé–~¤¤´}ÏÆ.µòÏS·ÏáqÈÒž…ÐÓ¹˜²F¼Ly„"›w¤ÉeWQ /3!Ý«TmÙ-¿þ¹Ë.ìÓò ›Šxõ}åìŽOÏÙ À~sΘQ‡ó·|×oغÙS¦ßªÄÖ¸ª»½JŸ?wc=H4¿Ûajæ×%2{á’y\HÁ˹¡&ðë¡ðVÚÆDm-eñC£ìÉã¿$;b&ÖçRO‡m™²­°#ÒXœì­5OjDÐøM‰¬ÊFH! ôì ·cФé».Ò7Œî¡’'3ø¦Y j%Äk§o ÑŸ­ã…}ä2èò­®×ÃE![“T0~ì=XÏZòØåÕ‰€º_¡yâ}‚ðÙÞrŽÎêíÅÖ¯¢QZ•*UÝ XX„ä›Ð„L¹Äûá¢Ï‡5@O•ZÝ@-ñ˜´!íÊ­%¼“U.%h9¸Ø&f ¥å”Y;V¿8þ€”âóZï‚Ëyx¬9:e›¹ÛÖlŸœ„!ºv¥ ŸÞÍQ«Û(òþÙÐsÖú“ÃíÇø™Ô×6=œHø8-¿÷æ*«ª/DеK˜žÑejÊÚ¡Ø©·Ã†]u?,˜êÍ0Ôäh(êZUƒ+86ŸŒØå 8aѦçÏÌ@O6x¶m, RºJ 2ƒ1>åNeb+-E“á)é2¨duÏ©”Qmð0chLõ“q¿e ’Ä0gNhyñYÈ·â´Ãrªzz‡†¦ÉÅÀ¤ÄÖwÇ;|P!sÍïΕ÷W*¤KÆ ßvúFøq…àG’’µâÒ& [HÉQ/÷1Ðèåay†BíðnO³0`š‹Ô¾ÀýkçvÝc²¹ûÛ-NùÚwºC¿-WpæÒÄ›³êJì1\pþý\n±Q(ÉÉh»…Zkv1‚Ö{"œd¯NŸ7*ãV·¢4Ùx”={YìʺD‡g¼B.H ‡ÑxäÞÉ¡^äE6”ƹˆ¡„uñ¬¥¤Ïf¢8ÿÆ©%¢7ôDÔËU“iÃÌyt¬¢ 赦…‚Y²²êÑ„JÊ„”•¾yètêF%kõP•Z¡Ý1\µ,û‰/0¼Óëg[´é#™iMf;Ê}¤6V´H4VEh W8ª?f’>;Öý"žç9Z¹¯¾PØ:Ê“ìý4ß+וShê{«ãƒÁ'üÏWfŸÅÜi¡Ê±„—Ùä:¡çÒ$Õ@šCìÞ UÞd‚…\‡€0Ñ‹£U&àäå}CþEÔȃ„Ÿ·y4Öø??˜2»@‚žKSƒe£?m/8ª¡A…#îë^­ƒWÓd¿d®„{ËL34Urúa¬n»*ØÜDÉgY–ͪBcŸ×P0‹^{ÛÁFYj—+ûcN0ð3$);ÿ„–îøRL´£nX°‚Q,XYßL —"VêÓdËãõT‹ $Sîî±­Þ»7o)Atxš×2GqçWLü@†°z ·ÈÕ«¹ØøIž«Xsìé;_jôæ«à'DK⢤OIºíDéÇA…øIepHt쇿)ÛÐi$.œøŠ=,o¼¢ÙïË“ge¿oÕF-HM¿u§¤ nB5º­¡3W\ =,°»ÁãÏo.¡_B¤£0Ý/f­RÇøJÛ8¿M'«‚*dS\&Óç¨Æ7ä·!*¸‡ãÓŠ²:âäàªb¨×•– ‚Ç—¹f-ç‡[ Æžà@‹¼Úºî=ó—=”9ü†ÒjÃ-á°U­NÄ,HÝó[ÿ¤û1¡ ¬ú€uOì4¹{ôb)AOF•Fiì5$®ÞÔøÛ­‘Ï,R÷m›íêGÁQÂa¥&íµ«ûƆó’é 0r{/®T¸ÒíÔ}¤{¨ˆ“ü¾º[M™ú •iUSµhg›õSÒtÁÙ ‡ººR¸æVÒ›®Š=üUZÁ«ÄŸÎwþÕ}hpd¡:ÐР%e‘J•lÏ÷N¦mÌäÆÝÔ˜âßf­œ½Í~úÉц;wzVÁ“B'¥f0Mkê>ƒß vvÖªÙ÷‰¬)N–V‰W‰fJ&…ܺèKälí¸dm&<"; ²ªrgØñO'jÀ|2ÙJóË 0-£)”¥¹j5¸Y6 Ú õ3®ÇûZé"ñ| ‚)49<ÃYL?Î"€žlR¢b€ 'ÔŽñß¾ˆ´ UÒŸ}KiË3jg«sÝ_tÂæãcGs“bG bñk¿ï{ƒÒD>öQ@Ü`û½qü>‰³‘zŸuBÄo¤.Ò>XZbf©•\¬o½I¦¹Û‘‡l´ÍÉTc*õŒ³w¶…É”°z} eñ(¸@¬]wŽè¾»©›õ«nç—æM½ÖIpÍ MsrD ´gQm‡Ø/•sØš˜6ì˜CÉ^àˆôŽ¢u’F…ñ¤=ºß)Oœ¼lBcÆqm h±5@©RÚŠŠD—ö:î¬Ì9bet‚o½lÆ%ÈûA1aê…ߨÉP%%ÇMèÊèû|cá |©ÙéaV GÔ³´Șú¹Óˆ ~1¢$[€ÏXÙl6òÅ´X¥9‚ý%¨­È³ YéaX¹K¼×~[¨µ—áûF¥ÌMùñÃk\nÄnÙÆxK[¨s^IÚUê—¤s–碖2 Þã*ÊŸ{@–dÌ—[Kï–6Åì…½Ý徿1¶þ¯NUpL/[Rãæupí×GÐÝ3cŒƒ_šÆpAŽö=êݪ‚ÈeâE?a1†ƒÂ¬dÉéÓ'"W½³ïÀe÷±É|”ççˆâÛÚ~¾ÐS®7mrù$&Ðj?‘EŽü쀭=x¥KšõÑýÒ–ïr»Ý­ÃIn*|”øô;¬ß ñ`Ör|>¬€L_ŠÜý©GˆeI€xp±*(Ë6žh íÃéí(Ç¿¸¾S±É$¸)­¡§Ì:APÀ@:4êéO{K‡ _‡Ê!­i}¶^w 宩®øœ çÖh(3-#Ä›;#uÚ%mƒ®Ìd}‹¿Ÿ×Za†•…-Ç.i[á$æ™™)YSü3aØNÏ4]Ö §y­³‡O«Ä”¿Ô½Ô?"ÂL†FC)1–»æ Í@¥ìHp†þ{ù³$í æy€ˆÖé=úZýHÏC¸Cæ¹þ½¡c~Szº½«Ï¤råT‰R›¦ø™žÌóx£à¯<õÑÐä¨/ßZ¾ùtbt>IGiT›sc ㎦?È5¦c/é AùÇ˰ìèK¦P¢ÓLÐÕ¢`{Òç ri½²(‹Õ:=hY(å™âZ…š½Ö¶ýr©3†4ݳ™Î”²»$SSç³5¨œ°ÓØðöÔwïŽ)uøT;1Œ< 䤸½Qñþ kœÈP¼ÆF¯Éˆ«ôbÅyMß2íÑ?“ú¸£„Ã×!<ÓáƒzE˜“ä<ñ,éN÷±¨@,‡5æe²=N¿qšÍß «ÙÛ¹s ú8ä¼Á!¥ “Aܱdw3šÑhÚUØÈÑÈa ¥Ÿ^ò¤xÌ%ºÚ0o0Ü;ÔØí«°¨HÄ^&œËÆr ]M‘Ðmœ j÷¦©k¯{_¶ñüu1 ò¥—¸(SŒð‚n°åËaÐA9M6Oˆ­\C’@m<>áH!LìÁç-Ðm¼¡ào¸©ß[(6ÞR8 9°ñê[{y)teøàl'/¾Öà!ƒD¿qÉ21P|gÃ%ų+¡Ðæsšt ÓMÞ¨~ýôþ÷“RµñýÕ¬¾‰‡xºü³UXÖ=}IÄZôRÄýËÛô³Báó줧zšWI E {i:¬¬ Zo#Ú–.DÝXŸëüÔo>ÿ °¨±Úß»Æ Ó®ô~±ÿTàþ)0Ï}‚ô”ø}˜ÿü«Ñ{ ]ž÷ëý`<2ýdlÝë}Dû-DŒ²e3«|gG)ó|¶°Ñö>ºÊ`!‰¼H+ìêÏzÉ"¯³µüÃ? ý’!Ø£02¯mKÿù¦wö#/Ú«bV@ÙצÉy݆— Ñê(&} nžLf|ÄlܬvþæÚ{«vg"~ ÿFáœýÒ\T{Ñ­EÙòº®Oˆâr%o«¨׳oÝÕ°iPêš­¥+î%çGõhžäÊäZ¶ÐBn£< 쥄•å@{êXÍœ…f²ë[¯Øµ·ìºëw7C®Ke C>ÒDô­ºÌÜþe7]PØè|Üv@r(æÂ…o_»¦ÌD€âï“å#ž¸½'‘ÈFmùëý(QM´²ræ‡ÔézVs6åŽÊ$XoK±3Êp 7­‚::ß$4>~î@ç+~ŽÀ/âI uoº!|tQ +»vL(0ŒÙ…BÐ|%ૌ þ•¤º¡rÅ:¿Û&Á!ûàJ¥á1¹‹ŽÌøtÁ=?ŒWŒh³MÑÖb‰øš›°çu­R´é±°]â•’^†‘Ò8•1MGÇFÙ(teƧUâw++,Ùã¼[éËXÆŽe}=!ªõö­Éû× $ÂÕIµèÚ YÈ[¡Û6:Ò?¤›äÍNq‘KfE™uÃ"¶I/¬#Þrãa»QÔ_“ ÆJ³.Á'!РåØ5¸®ížòtçõ!®¼¸¬äîÔºÏEc0+°û@0(|ZÚ¨YŸ6¤Ë‹øÏ–<í#Ðwõ9r*§dMõ}¨héÞÒR³·íÜ-ø@ó_—÷ °É}…ÈnŰ,e—]”ý“Ýfâô ¦Ã–Û–6à,­F]AñÃç0õâóT/«‘d——¤‚p·r •×´Üz}dOL†ƒGìÕ›œCuÌk—àtž·7¸)äæQik<Ï«s~ôîs†¤Vl[pWAÊ Xy16eu†Τ˜ÖÕMÒÁøùÇÖþÔÝéLç.´d)/¾Ÿ‘ë¾PµŽÍ²H>óqXù6ØrI¬·%7ìW[Ý~Ý›³¤Æ0–Ö ¾tɳ z ~Ô\ dHÑ,?‡Ôr¬k[ýÕO´¤B@Þó+ÿàí%ó¦8Å­+@ábÌÊC}*^#ü¦Ž¿¢e©=І²)aT‘gø£léQÐÙ¬6Åæmt5ýï°z2íXç–± 7Ñ vŠ$?ýåç)'Kص×äXT8AŽ'î¯o$/Ú8@! \k*µ€ÝF<6Ù®â—b,• ä…÷ðœÏp(íaöê=2÷nì ¶Æ[8'£'Ùe’YËb³Äó¡ð_…«‘z+‚¬±I£&Käâ-›° D.+ µ…äêU.Ž­Fض1!TŸæ ‚ûc™:2ŸbHÎ%"çâpàu_ñsÁÓ$êê'×>ZÝ^tªNyŽêFb]b÷Ú¹BO4{—F=X«8ª {ë_ ’}‘e×k«£‚8°ùz;³šÒ?ž»,][ ÔÕä"ˆñᘿ”wÔï)—)Ag}ú½c*žßqCn¥sOã6Õ‰“!Û{Þ‰Í-‹Í¹!°_åÁ–¼p&Ê*p­jlÖ˜DÉYïXš6 nn½«2ðæè®{Žßò¯W·–â8>œÎ¥z²¸ë«j¬ÁMÞúì†Óª¦o6±³Ü¨µÛ ä¨Î&´'9Û$–‚r¬šÿ„¬RH§3Ùp£!ACÝ1ƒrHt¬²~ªxŽ'‰ÚöÝBxinýðØ×ñž‘XÏáÊy+ë¾1ÀŽ{íz‚3¢('´G킯GýòfýÀŠíìzëºt†ê›rà9Rcgw1?eAº}ËÚáƒN#¦ J7<¾‡:aô¥çÇ«7¯p†ãñy+Í÷M‘±¢.Ê“2©ùR©8þ söÕ/9mõ=ùs=ë(ݧÚîYN,lFÿ&|23L¯a>ŠZ¾Ô‰í˜bô«»ào2ÐîÁò4o„„XÖõî/iÜADxWÆý¹EÊC:rÿ´ÓCÓÆ…ž”£N £«_«¾¸s*Ä#í« hò 1„OËþt^”Ôc‚ œøÁæP˜ “©_­”ša¥Ë¾àÖ„q4’:m°Ö'Eüï|õ~À÷DEÉðaÂT™ðiÏ]JÜåE!ôIƒ¨~[ãA—W• ãVåSÔ&öXzݬSµœAˆµ.§ýdlˆyEµÕÙŠ¥³l³Ü˜¾‡Í–4’ûwq%—ScÏŽs:Þ×3’í‹UA-·þ~™ö‡AŠ`å¸UŒ’uK`ªY«(:3|O44ƒó{Ϩ‡í³g*«¼O> ÅchÝaJøºköúneTêTAÎÆ]ë\Œ,·'Ãâû„cyªJ’[/êEïø0oµ¬EÙÍI…ãkEš 'öžOÇ£ÔÊŠ3%Âw;£JÐH`Pyt1 3RbߪUdž:—{gzÏkp >rKKIšÐk‰•>âšñGÞ3†µ{̱ðBñ¯žƒ½¨ÒÁùû‹¬a´ììb!·æË´p=×\Cg)zrˆ§Œ"µfKRqû 2íª%&­Îò*Æ.dR;gÕ«Þ÷†t:CoFX+Ži7# -Jçès<¾Oj–=ó?Þ‚á áÓðôX Ef„ÀõÍÍeµÒ’ 0IÈs‰6#š–Ãm ¼V½ªVZ÷dÓø#€›à†º\PÜ\w6;…iýóæYþ~©e½B’oÐ_ý@-PÇ:o~£œrõ½›]Ô-TCR;ÿE³Ž¼~aÃfàÜÔ½^L=>Øv'Q<ƒhÚ¨’ÂM0 Eõ©G×5$hÆÔÒ^…å{ÞáS8«üA0à -i]’$k¢ÂwŠWûm4á9&:·Ð'Oû¥íFä3ú˜ÎQNÑk»À2B ³{43Å4û6-¢•ðªïêUàõÑ[äÃ¥qo¨2/¨¼d<Ò&×D{"H,«ðŸ’h´\ÎÁí— ®RÓ&mŠÂi߯K„?ä¦m7svž> øŠ.‚˜?GŸè#M¨P8¶«˜äƒÇç½åÕÜ:øô²«F®áE*xß87µZʲ¶‡áIǾu…«£M&ì;h9°ë8U‰)U,¦È&dŠž ‹ŠÂ!Ý+7ôÒÜù$J2 ±* HZS/´Ö̦ŽÒôï á.ml%à®~ˆOAÅöŠÆ …ÞÚ·rU¦â§ÿVwÙ¢Xoqi=iuò¦‚å&ïù FŽË!6 Ù?CkF÷Çïa( ÐÛZVè´‡cö#“* õ<0½eÑ~¢Ã ýTÕ×F_ò‡°ä~¹^øõØE]d ¥ÁÔMž9Ü’(DLQʃŸJ‘©ú÷û%OâC3G#†½Ûô覻JAÕÃÐí5‡-ûDäÁ;ó#Ú‡Evܤ1´‚Ç+ÖŠG¨ñMx¶csÕíÛª4§<;7·˜˜W”rN^1II-MmdP_Èánoë¥VÙeš>!˙؂;Œïo…3-†·EÓ,º=zgV µqP9a ^™8ö– ]6>Ê\ågÂ/Ë~HCâám¬bZ=ŸÇö—LE?±Ž™ãx]ñ0Eµ¢'+Û oB>ÕÍPâÇE­yHLõ3®òHQöE»†IÄxï§e¥ù“’ÒKãD5Mü.*­9K‘`¨71.L£3íèz!gxФAź‘ä!K²’XPMu©´Í(I]Rb“´¹Žª*~Ó ¶éV0g¹õÎ?Bj¿@£Ñ_Ó†Ùöø= }Þ¹(u‡Ëåßp=Šl—ìô±Òã!oçHòk-–Râ-›iÞ3Šg7è¤YˆQÓù@©[jȶ‰ˆ5éTYÙQ¶¢žÞwr%e»9OpÅÕû#ÏÉ}˜+4%P½¹˜]$ ÐL7¦þ¯¤íÓ-óæ¨V®z×Üj6, íöl¡=~†’÷ÉDÔìƒà陵W]Ü3ÂR=e"}{?úžTNߪ˜˜…Z-3²—¾Vqž®zö<°V ä"as6H’1“µ.+ ˆû}§²X7u%ÎL,X M76Ñ‚Xÿ*Åà[yž+¼`ÅXü³ ëÖ"”$‚h%˜g2² ×N ¿ Ÿ>˹Q¸w¢+mèâ—Od‹Ê 9ôg+[¹ü75ê4 bqì+טoy…ÅIs.€>¸pA5ÃaìëB(×¼IÈÇÈ@HŒÀ’yC ‰¼¡]€$Ç2à—g÷éšð¡ÛyƒÂ× JG5©jžºš§FÍ9>™’Y™©¦ïrfpýÎÝOiG·Jú2>ÜÄЗ€u¼÷ŒÃŒ®è<Þè&~¼Ñ»¿žOèF¼Þž×Ï\ŸcU R’ŠUÊŽ¿Â>KcÐÐIe}/É¿“Ã&“G»u•›s#rh,5A ‰šâQÍsf¹*`æÁ±CAÚAÄ,2Lfk°ç‘~AÚ¢aÀ²B™1K??Ä æm:!]*ý­®¶„JìÀºˆ\é=—¸ ¾Ô¥#ÚÔüaA³V¾]š6éó™WJ~ØÓi@¿o Û;²(µm)Pê4oWò¶|ë/ÔЧÓzQ õ¼ÈŠ#,9î}‡¬ª¾ÑC|Eˆ~¸ë=>K¶º›dlVo.8õlCF•&ûæãÞ?HC²Í< L©Ñ“à RDWú¼|=GÜBjñvb`:§W,¾1ÚIÒ-]k†£sÀk¶œz¶#Æ?E›•íùó{™À˜kyú³l¥@hc¿õËbôo^'L­Q… ½µF‹(‰(xZP¤ac}˜þÑÉ J³ÚS©*ì`”†Š‹C6çIýŠ;ê®?ÿ úöX»êØï/Œk{P ÚVe9ô~½ÙTŒbc­‹dê¦L,Tp»œ)³ºž¥Ì¤Îâ ù%}…Ñ3¾=‚¸ó,ô/–ÐÂ^¨Nʳ?Ô·´Îø'²Lò†Â‚të¤lÀw-uXÈñ4GÿÉ%µ1S¨e}¿t6ÌÓȲv-‰½ .d €¼—Źò/ÄS\¥õªÕ½g§àÞ)s·´>F²2Ù«ôf[[©‚3Xæ¤YǧâÑ6\2Yì ’;‰÷ê¾Dt5Ãü‡I¶½ï9¶O´™'‰ôýålvš¹€WãxÇ9j¶Á%Üe‘õ:‡__ø=µÓYMH””Ƴp8u2+{ì1w™,iö¡>¨׬?Œ'ÓvT§Ð׃À›Bmã$½][þ6ü4Ù»ÙêCÊÊ~‰ëÁ¼Œ´õ^¦†¸Åèµ{ïÏ¥–Þrû,œ}uéÛ§]É,‹Àv’¸Ê°Þ}sG‰—Þ]SÉ|¸I¾ß¯àY«Ö» Ñ¾«gb¿š˜J…Ûá’(w^ôwà|ñÎpInT¤/çóZgð”ÅÐ ¤$¨çÏ+N ¸âž÷%…0-DeN¤Í“I¿º@ÍXj—.=Ûõ§]¦­Y¬±ýuÚn­S®¾z{Y7Îô!˜I¤å5‰BLßTëo-VFCm¶™rˆóÀrísJ9IKtŽB•Ñ4À|(x”;ß© NùU%~8ÿ1gßøInÆ>g*üø oAä#,ƒ:µÂ€¦©¶@­¥'úüè¬õ"=0³®M,ÊÔ*ŨŒfÀw±Ñ?&‘ÿr z\–$l'n¦dËwMaŠíWuË¡í˜VjS¸¼âè,uTÆÕ– ó²Éú“Ù5:ëªöCZq·ýWî^†7fþä¥Xy @-m™‚Tຉyž°ÞA`šõËó¶y4š¾±V$¶yP5Ÿâ7Áƒ(ôì4|£%˜E©¬ˆÊEÝŠ*â&Ñ3¼;¼†œ„ÆÁ)‹ëyuKe®(ÙÆd­‹ô¥6“lî~.Þgv`ŸðáoúOËXê0, qðê÷ä“VÁÿþ;yÕTê¬ÅsW fr›{E”5çØ¬¿¨V¡Ÿæ¡ý‰¥UJDú•‘O´Ynh¾÷HR¶›ÒÖâ ¿•òöSq——i†ÃMxq!pmðó÷=ÝÀSMa, ôJayn|ÓU—V¤ñ ¦Ær…ŽCd]dúø>&l4ÑÓX“œGS°/tðE˜8íY~Mg±!éÿ矌߭3W³4'…+5tÆpìhQa C©=‚énûl¯"J¹7pç!á[ÁÕfúG›ÖÊö%ÔdÊX¹×g*ññJ›µ’™Jwnf”!G*ž²èÎàÈÁ:3°ª [00Ù œ&[xŒNÇ‹£wg¤f9É3„F¤Fº˜4Þm—õ/G@ KAÈ áeÊž_I¦¿ŒÎÕiŽ·áñA@…‰pŒsP­S=]&=„@*êíÏG s+ŽjŒvYiðàÎgÜ] *ܱ€†E¡Ã=5‰J¤` PÓmDM Bt5Õ¹:‰1v¿@%í«×æN?R2Ί9éŒ †Óú²¸|7Ñ®_Lðè½ß«¿>M OWzUH£EL1ßu' ãû3ºÇI‚¨˜cýlô_·&ð¥nnQASNÀ¾ÓCÉœ‘#gé›9ºØjTK!1/¾Éî.Gòy±3DŽî©Rð¶ÝEB[0AnuI"…Õ/†ï\“YÞŽ@z@„ l¼1ýÖBqq 1¶+U¬š=âKÈðãçX¶\ïk69@Ülàª2‰ô]H";¹ŸY/ëP«ô\¢¾Ü¾‚]ä7”³ÕZgˆº=†žðÍ…yI¼Ä¥Ò_‡ÓÀ‘Ãݺz_:?xf¼‘²5¡Å¦9f@t»ÁµòƒSƒÿÏlô\Œ é{{WÀšÛüðb(ËH&íôsºöK>×¾=Flê‹ìýN^3OÕíe¶8ž4Á9 þM“ì¿ÎøEÛŸ‰EÎDˆv/\î<†Ù —íˆy²ú¤~9•7¬µ±‹*r¸ƒ‘³ú:¸˜€–¶!°É»˜Ë¯²GTƒL÷õ­j¢2³‚û?OV¬~sàñ×¼ eþ[„6—²:JåûÊ=F<Ò¨†Âê¶Ú€¨wO¬zˆ„æ]¸pÁà´m]Æ,©ªùŽ˜ßnšEd:φ›ö99pò$ÏÈ¿èv–“ÄjhNÆŠßÈ­¡ô‘µÙ[{}0VïÜO‘ètFdfªÁ¢np”¶o&WBÖ+Á~Uä­ˆùÁ‰ ÛøÅêݼëÝòÍ~:Îà ±Õùþ?ªUýjÀb©¼‰óZP¸/Y¼– gs=+ž7—ŒýqÇÑ5Yõ¯EJ#ïºÂó1‚E‘¸*fƒAX‰è÷óÕÛ\ñP%ÏÒ…qxCQÚêÙ 5Ž‹êKa Õö«ËlŽÔM/½37Ì$†êPõKÝþí †Õé>ö"kŽ.ð”}t˜‘b—Sp¤î¢…f6©´)ðºR_òHyÓÏ–üœ:`9‚?ð‚Zô^XqÈாTþOáË}'÷tó¤È‚à“Ò Ôß&vÍ'vº.´Zo&Â{#àÄH«Gû#³ÿ³àÁI}¼äÀ+-v^/î$BNì?Òþ0£8sM×Ë\›}¼S|[<¤<æX˜ í-ï;Ó²ø}1? ­†Sò¡!Ó Õ‡né BLjt>[ŸŸübE—Ûú騯sÞØ…–ØO¥A|< ñ¨ï |üļ!¨­Ý,¢b‚Ôl.¦ß‹‡–ÐíµÕ9c endstream endobj 4960 0 obj << /Type /FontDescriptor /FontName /UQVANN+NimbusRomNo9L-ReguItal /Flags 4 /FontBBox [-169 -270 1010 924] /Ascent 669 /CapHeight 669 /Descent -193 /ItalicAngle -15 /StemV 78 /XHeight 441 /CharSet (/A/B/C/D/E/F/G/H/I/L/M/N/O/P/R/S/T/U/V/W/X/a/asterisk/b/bracketleft/bracketright/c/colon/comma/d/e/eight/equal/f/fi/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/numbersign/o/one/p/parenleft/parenright/period/q/quotedbl/quoteright/r/s/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) /FontFile 4959 0 R >> endobj 4936 0 obj << /Type /Encoding /Differences [2/fi/fl 33/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright 95/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 132/quotedblbase 147/quotedblleft/quotedblright/bullet/endash 169/copyright 180/acute 183/periodcentered] >> endobj 3438 0 obj << /Type /Font /Subtype /Type1 /BaseFont /EZZDYY+NimbusMonL-Bold /FontDescriptor 4946 0 R /FirstChar 49 /LastChar 118 /Widths 4937 0 R /Encoding 4936 0 R >> endobj 2374 0 obj << /Type /Font /Subtype /Type1 /BaseFont /QOJFXS+NimbusMonL-Regu /FontDescriptor 4948 0 R /FirstChar 33 /LastChar 148 /Widths 4940 0 R /Encoding 4936 0 R >> endobj 2808 0 obj << /Type /Font /Subtype /Type1 /BaseFont /MLQAKB+NimbusSanL-Regu /FontDescriptor 4950 0 R /FirstChar 68 /LastChar 121 /Widths 4939 0 R /Encoding 4936 0 R >> endobj 1879 0 obj << /Type /Font /Subtype /Type1 /BaseFont /DMDUWG+NimbusRomNo9L-Medi /FontDescriptor 4952 0 R /FirstChar 2 /LastChar 150 /Widths 4942 0 R /Encoding 4936 0 R >> endobj 3304 0 obj << /Type /Font /Subtype /Type1 /BaseFont /TLGATI+NimbusRomNo9L-MediItal /FontDescriptor 4954 0 R /FirstChar 95 /LastChar 117 /Widths 4938 0 R /Encoding 4936 0 R >> endobj 1832 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ESIFTD+NimbusRomNo9L-Regu /FontDescriptor 4956 0 R /FirstChar 2 /LastChar 183 /Widths 4944 0 R /Encoding 4936 0 R >> endobj 1833 0 obj << /Type /Font /Subtype /Type1 /BaseFont /UQVANN+NimbusRomNo9L-ReguItal /FontDescriptor 4960 0 R /FirstChar 2 /LastChar 122 /Widths 4943 0 R /Encoding 4936 0 R >> endobj 1937 0 obj << /Type /Font /Subtype /Type1 /BaseFont /LAYWJG+NimbusRomNo9L-Regu-Slant_167 /FontDescriptor 4958 0 R /FirstChar 39 /LastChar 89 /Widths 4941 0 R /Encoding 4936 0 R >> endobj 1834 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [1826 0 R 1876 0 R 1934 0 R 1992 0 R 2050 0 R 2108 0 R] >> endobj 2168 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [2165 0 R 2222 0 R 2280 0 R 2329 0 R 2335 0 R 2339 0 R] >> endobj 2356 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [2353 0 R 2360 0 R 2371 0 R 2377 0 R 2383 0 R 2388 0 R] >> endobj 2395 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [2392 0 R 2397 0 R 2401 0 R 2406 0 R 2413 0 R 2421 0 R] >> endobj 2431 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [2426 0 R 2435 0 R 2439 0 R 2449 0 R 2457 0 R 2470 0 R] >> endobj 2479 0 obj << /Type /Pages /Count 6 /Parent 4961 0 R /Kids [2476 0 R 2491 0 R 2501 0 R 2506 0 R 2511 0 R 2520 0 R] >> endobj 2527 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2524 0 R 2530 0 R 2552 0 R 2562 0 R 2568 0 R 2576 0 R] >> endobj 2583 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2580 0 R 2585 0 R 2589 0 R 2593 0 R 2597 0 R 2601 0 R] >> endobj 2608 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2605 0 R 2610 0 R 2614 0 R 2618 0 R 2622 0 R 2626 0 R] >> endobj 2633 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2630 0 R 2635 0 R 2639 0 R 2643 0 R 2647 0 R 2651 0 R] >> endobj 2659 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2656 0 R 2661 0 R 2673 0 R 2679 0 R 2683 0 R 2687 0 R] >> endobj 2696 0 obj << /Type /Pages /Count 6 /Parent 4962 0 R /Kids [2693 0 R 2698 0 R 2706 0 R 2712 0 R 2722 0 R 2735 0 R] >> endobj 2742 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2739 0 R 2744 0 R 2749 0 R 2753 0 R 2761 0 R 2765 0 R] >> endobj 2780 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2770 0 R 2782 0 R 2786 0 R 2791 0 R 2795 0 R 2799 0 R] >> endobj 2809 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2803 0 R 2811 0 R 2816 0 R 2824 0 R 2836 0 R 2844 0 R] >> endobj 2871 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2861 0 R 2873 0 R 2882 0 R 2887 0 R 2891 0 R 2896 0 R] >> endobj 2903 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2900 0 R 2909 0 R 2919 0 R 2939 0 R 2950 0 R 2968 0 R] >> endobj 2984 0 obj << /Type /Pages /Count 6 /Parent 4963 0 R /Kids [2981 0 R 2988 0 R 3001 0 R 3010 0 R 3020 0 R 3028 0 R] >> endobj 3040 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3037 0 R 3042 0 R 3046 0 R 3050 0 R 3054 0 R 3058 0 R] >> endobj 3066 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3063 0 R 3069 0 R 3081 0 R 3086 0 R 3090 0 R 3094 0 R] >> endobj 3103 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3099 0 R 3106 0 R 3112 0 R 3118 0 R 3123 0 R 3127 0 R] >> endobj 3135 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3132 0 R 3137 0 R 3143 0 R 3148 0 R 3157 0 R 3164 0 R] >> endobj 3175 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3172 0 R 3179 0 R 3184 0 R 3189 0 R 3193 0 R 3199 0 R] >> endobj 3206 0 obj << /Type /Pages /Count 6 /Parent 4964 0 R /Kids [3203 0 R 3208 0 R 3214 0 R 3225 0 R 3235 0 R 3239 0 R] >> endobj 3260 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3245 0 R 3262 0 R 3266 0 R 3272 0 R 3276 0 R 3281 0 R] >> endobj 3290 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3286 0 R 3292 0 R 3296 0 R 3301 0 R 3306 0 R 3310 0 R] >> endobj 3317 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3314 0 R 3321 0 R 3334 0 R 3340 0 R 3354 0 R 3359 0 R] >> endobj 3377 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3369 0 R 3379 0 R 3383 0 R 3387 0 R 3391 0 R 3400 0 R] >> endobj 3413 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3410 0 R 3415 0 R 3424 0 R 3428 0 R 3433 0 R 3444 0 R] >> endobj 3469 0 obj << /Type /Pages /Count 6 /Parent 4965 0 R /Kids [3462 0 R 3472 0 R 3479 0 R 3486 0 R 3491 0 R 3496 0 R] >> endobj 3508 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3505 0 R 3510 0 R 3516 0 R 3520 0 R 3524 0 R 3530 0 R] >> endobj 3540 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3536 0 R 3542 0 R 3552 0 R 3556 0 R 3562 0 R 3568 0 R] >> endobj 3577 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3572 0 R 3580 0 R 3585 0 R 3590 0 R 3596 0 R 3603 0 R] >> endobj 3615 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3611 0 R 3617 0 R 3622 0 R 3630 0 R 3638 0 R 3644 0 R] >> endobj 3659 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3655 0 R 3662 0 R 3668 0 R 3673 0 R 3678 0 R 3684 0 R] >> endobj 3696 0 obj << /Type /Pages /Count 6 /Parent 4966 0 R /Kids [3691 0 R 3699 0 R 3706 0 R 3710 0 R 3716 0 R 3724 0 R] >> endobj 3736 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3730 0 R 3738 0 R 3744 0 R 3750 0 R 3754 0 R 3758 0 R] >> endobj 3765 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3762 0 R 3767 0 R 3771 0 R 3775 0 R 3779 0 R 3783 0 R] >> endobj 3790 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3787 0 R 3792 0 R 3796 0 R 3800 0 R 3804 0 R 3808 0 R] >> endobj 3815 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3812 0 R 3817 0 R 3821 0 R 3825 0 R 3829 0 R 3833 0 R] >> endobj 3840 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3837 0 R 3842 0 R 3846 0 R 3850 0 R 3854 0 R 3858 0 R] >> endobj 3865 0 obj << /Type /Pages /Count 6 /Parent 4967 0 R /Kids [3862 0 R 3867 0 R 3871 0 R 3875 0 R 3879 0 R 3883 0 R] >> endobj 3891 0 obj << /Type /Pages /Count 6 /Parent 4968 0 R /Kids [3887 0 R 3896 0 R 3901 0 R 3905 0 R 3909 0 R 3914 0 R] >> endobj 3923 0 obj << /Type /Pages /Count 6 /Parent 4968 0 R /Kids [3920 0 R 3925 0 R 3936 0 R 3957 0 R 4174 0 R 4406 0 R] >> endobj 4608 0 obj << /Type /Pages /Count 3 /Parent 4968 0 R /Kids [4605 0 R 4835 0 R 4933 0 R] >> endobj 4961 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [1834 0 R 2168 0 R 2356 0 R 2395 0 R 2431 0 R 2479 0 R] >> endobj 4962 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [2527 0 R 2583 0 R 2608 0 R 2633 0 R 2659 0 R 2696 0 R] >> endobj 4963 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [2742 0 R 2780 0 R 2809 0 R 2871 0 R 2903 0 R 2984 0 R] >> endobj 4964 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [3040 0 R 3066 0 R 3103 0 R 3135 0 R 3175 0 R 3206 0 R] >> endobj 4965 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [3260 0 R 3290 0 R 3317 0 R 3377 0 R 3413 0 R 3469 0 R] >> endobj 4966 0 obj << /Type /Pages /Count 36 /Parent 4969 0 R /Kids [3508 0 R 3540 0 R 3577 0 R 3615 0 R 3659 0 R 3696 0 R] >> endobj 4967 0 obj << /Type /Pages /Count 36 /Parent 4970 0 R /Kids [3736 0 R 3765 0 R 3790 0 R 3815 0 R 3840 0 R 3865 0 R] >> endobj 4968 0 obj << /Type /Pages /Count 15 /Parent 4970 0 R /Kids [3891 0 R 3923 0 R 4608 0 R] >> endobj 4969 0 obj << /Type /Pages /Count 216 /Parent 4971 0 R /Kids [4961 0 R 4962 0 R 4963 0 R 4964 0 R 4965 0 R 4966 0 R] >> endobj 4970 0 obj << /Type /Pages /Count 51 /Parent 4971 0 R /Kids [4967 0 R 4968 0 R] >> endobj 4971 0 obj << /Type /Pages /Count 267 /Kids [4969 0 R 4970 0 R] >> endobj 4972 0 obj << /Type /Outlines /First 3 0 R /Last 1815 0 R /Count 13 >> endobj 1823 0 obj << /Title 1824 0 R /A 1821 0 R /Parent 1815 0 R /Prev 1819 0 R >> endobj 1819 0 obj << /Title 1820 0 R /A 1817 0 R /Parent 1815 0 R /Next 1823 0 R >> endobj 1815 0 obj << /Title 1816 0 R /A 1813 0 R /Parent 4972 0 R /Prev 1807 0 R /First 1819 0 R /Last 1823 0 R /Count -2 >> endobj 1811 0 obj << /Title 1812 0 R /A 1809 0 R /Parent 1807 0 R >> endobj 1807 0 obj << /Title 1808 0 R /A 1805 0 R /Parent 4972 0 R /Prev 1763 0 R /Next 1815 0 R /First 1811 0 R /Last 1811 0 R /Count -1 >> endobj 1803 0 obj << /Title 1804 0 R /A 1801 0 R /Parent 1763 0 R /Prev 1791 0 R >> endobj 1799 0 obj << /Title 1800 0 R /A 1797 0 R /Parent 1791 0 R /Prev 1795 0 R >> endobj 1795 0 obj << /Title 1796 0 R /A 1793 0 R /Parent 1791 0 R /Next 1799 0 R >> endobj 1791 0 obj << /Title 1792 0 R /A 1789 0 R /Parent 1763 0 R /Prev 1787 0 R /Next 1803 0 R /First 1795 0 R /Last 1799 0 R /Count -2 >> endobj 1787 0 obj << /Title 1788 0 R /A 1785 0 R /Parent 1763 0 R /Prev 1775 0 R /Next 1791 0 R >> endobj 1783 0 obj << /Title 1784 0 R /A 1781 0 R /Parent 1775 0 R /Prev 1779 0 R >> endobj 1779 0 obj << /Title 1780 0 R /A 1777 0 R /Parent 1775 0 R /Next 1783 0 R >> endobj 1775 0 obj << /Title 1776 0 R /A 1773 0 R /Parent 1763 0 R /Prev 1771 0 R /Next 1787 0 R /First 1779 0 R /Last 1783 0 R /Count -2 >> endobj 1771 0 obj << /Title 1772 0 R /A 1769 0 R /Parent 1763 0 R /Prev 1767 0 R /Next 1775 0 R >> endobj 1767 0 obj << /Title 1768 0 R /A 1765 0 R /Parent 1763 0 R /Next 1771 0 R >> endobj 1763 0 obj << /Title 1764 0 R /A 1761 0 R /Parent 4972 0 R /Prev 1719 0 R /Next 1807 0 R /First 1767 0 R /Last 1803 0 R /Count -6 >> endobj 1759 0 obj << /Title 1760 0 R /A 1757 0 R /Parent 1719 0 R /Prev 1755 0 R >> endobj 1755 0 obj << /Title 1756 0 R /A 1753 0 R /Parent 1719 0 R /Prev 1727 0 R /Next 1759 0 R >> endobj 1751 0 obj << /Title 1752 0 R /A 1749 0 R /Parent 1731 0 R /Prev 1747 0 R >> endobj 1747 0 obj << /Title 1748 0 R /A 1745 0 R /Parent 1731 0 R /Prev 1743 0 R /Next 1751 0 R >> endobj 1743 0 obj << /Title 1744 0 R /A 1741 0 R /Parent 1731 0 R /Prev 1739 0 R /Next 1747 0 R >> endobj 1739 0 obj << /Title 1740 0 R /A 1737 0 R /Parent 1731 0 R /Prev 1735 0 R /Next 1743 0 R >> endobj 1735 0 obj << /Title 1736 0 R /A 1733 0 R /Parent 1731 0 R /Next 1739 0 R >> endobj 1731 0 obj << /Title 1732 0 R /A 1729 0 R /Parent 1727 0 R /First 1735 0 R /Last 1751 0 R /Count -5 >> endobj 1727 0 obj << /Title 1728 0 R /A 1725 0 R /Parent 1719 0 R /Prev 1723 0 R /Next 1755 0 R /First 1731 0 R /Last 1731 0 R /Count -1 >> endobj 1723 0 obj << /Title 1724 0 R /A 1721 0 R /Parent 1719 0 R /Next 1727 0 R >> endobj 1719 0 obj << /Title 1720 0 R /A 1717 0 R /Parent 4972 0 R /Prev 1651 0 R /Next 1763 0 R /First 1723 0 R /Last 1759 0 R /Count -4 >> endobj 1715 0 obj << /Title 1716 0 R /A 1713 0 R /Parent 1711 0 R >> endobj 1711 0 obj << /Title 1712 0 R /A 1709 0 R /Parent 1651 0 R /Prev 1703 0 R /First 1715 0 R /Last 1715 0 R /Count -1 >> endobj 1707 0 obj << /Title 1708 0 R /A 1705 0 R /Parent 1703 0 R >> endobj 1703 0 obj << /Title 1704 0 R /A 1701 0 R /Parent 1651 0 R /Prev 1695 0 R /Next 1711 0 R /First 1707 0 R /Last 1707 0 R /Count -1 >> endobj 1699 0 obj << /Title 1700 0 R /A 1697 0 R /Parent 1695 0 R >> endobj 1695 0 obj << /Title 1696 0 R /A 1693 0 R /Parent 1651 0 R /Prev 1687 0 R /Next 1703 0 R /First 1699 0 R /Last 1699 0 R /Count -1 >> endobj 1691 0 obj << /Title 1692 0 R /A 1689 0 R /Parent 1687 0 R >> endobj 1687 0 obj << /Title 1688 0 R /A 1685 0 R /Parent 1651 0 R /Prev 1675 0 R /Next 1695 0 R /First 1691 0 R /Last 1691 0 R /Count -1 >> endobj 1683 0 obj << /Title 1684 0 R /A 1681 0 R /Parent 1675 0 R /Prev 1679 0 R >> endobj 1679 0 obj << /Title 1680 0 R /A 1677 0 R /Parent 1675 0 R /Next 1683 0 R >> endobj 1675 0 obj << /Title 1676 0 R /A 1673 0 R /Parent 1651 0 R /Prev 1671 0 R /Next 1687 0 R /First 1679 0 R /Last 1683 0 R /Count -2 >> endobj 1671 0 obj << /Title 1672 0 R /A 1669 0 R /Parent 1651 0 R /Prev 1667 0 R /Next 1675 0 R >> endobj 1667 0 obj << /Title 1668 0 R /A 1665 0 R /Parent 1651 0 R /Prev 1663 0 R /Next 1671 0 R >> endobj 1663 0 obj << /Title 1664 0 R /A 1661 0 R /Parent 1651 0 R /Prev 1659 0 R /Next 1667 0 R >> endobj 1659 0 obj << /Title 1660 0 R /A 1657 0 R /Parent 1651 0 R /Prev 1655 0 R /Next 1663 0 R >> endobj 1655 0 obj << /Title 1656 0 R /A 1653 0 R /Parent 1651 0 R /Next 1659 0 R >> endobj 1651 0 obj << /Title 1652 0 R /A 1649 0 R /Parent 4972 0 R /Prev 1235 0 R /Next 1719 0 R /First 1655 0 R /Last 1711 0 R /Count -10 >> endobj 1647 0 obj << /Title 1648 0 R /A 1645 0 R /Parent 1627 0 R /Prev 1643 0 R >> endobj 1643 0 obj << /Title 1644 0 R /A 1641 0 R /Parent 1627 0 R /Prev 1639 0 R /Next 1647 0 R >> endobj 1639 0 obj << /Title 1640 0 R /A 1637 0 R /Parent 1627 0 R /Prev 1635 0 R /Next 1643 0 R >> endobj 1635 0 obj << /Title 1636 0 R /A 1633 0 R /Parent 1627 0 R /Prev 1631 0 R /Next 1639 0 R >> endobj 1631 0 obj << /Title 1632 0 R /A 1629 0 R /Parent 1627 0 R /Next 1635 0 R >> endobj 1627 0 obj << /Title 1628 0 R /A 1625 0 R /Parent 1615 0 R /Prev 1623 0 R /First 1631 0 R /Last 1647 0 R /Count -5 >> endobj 1623 0 obj << /Title 1624 0 R /A 1621 0 R /Parent 1615 0 R /Prev 1619 0 R /Next 1627 0 R >> endobj 1619 0 obj << /Title 1620 0 R /A 1617 0 R /Parent 1615 0 R /Next 1623 0 R >> endobj 1615 0 obj << /Title 1616 0 R /A 1613 0 R /Parent 1235 0 R /Prev 1583 0 R /First 1619 0 R /Last 1627 0 R /Count -3 >> endobj 1611 0 obj << /Title 1612 0 R /A 1609 0 R /Parent 1583 0 R /Prev 1607 0 R >> endobj 1607 0 obj << /Title 1608 0 R /A 1605 0 R /Parent 1583 0 R /Prev 1603 0 R /Next 1611 0 R >> endobj 1603 0 obj << /Title 1604 0 R /A 1601 0 R /Parent 1583 0 R /Prev 1595 0 R /Next 1607 0 R >> endobj 1599 0 obj << /Title 1600 0 R /A 1597 0 R /Parent 1595 0 R >> endobj 1595 0 obj << /Title 1596 0 R /A 1593 0 R /Parent 1583 0 R /Prev 1591 0 R /Next 1603 0 R /First 1599 0 R /Last 1599 0 R /Count -1 >> endobj 1591 0 obj << /Title 1592 0 R /A 1589 0 R /Parent 1583 0 R /Prev 1587 0 R /Next 1595 0 R >> endobj 1587 0 obj << /Title 1588 0 R /A 1585 0 R /Parent 1583 0 R /Next 1591 0 R >> endobj 1583 0 obj << /Title 1584 0 R /A 1581 0 R /Parent 1235 0 R /Prev 1555 0 R /Next 1615 0 R /First 1587 0 R /Last 1611 0 R /Count -6 >> endobj 1579 0 obj << /Title 1580 0 R /A 1577 0 R /Parent 1555 0 R /Prev 1575 0 R >> endobj 1575 0 obj << /Title 1576 0 R /A 1573 0 R /Parent 1555 0 R /Prev 1571 0 R /Next 1579 0 R >> endobj 1571 0 obj << /Title 1572 0 R /A 1569 0 R /Parent 1555 0 R /Prev 1567 0 R /Next 1575 0 R >> endobj 1567 0 obj << /Title 1568 0 R /A 1565 0 R /Parent 1555 0 R /Prev 1563 0 R /Next 1571 0 R >> endobj 1563 0 obj << /Title 1564 0 R /A 1561 0 R /Parent 1555 0 R /Prev 1559 0 R /Next 1567 0 R >> endobj 1559 0 obj << /Title 1560 0 R /A 1557 0 R /Parent 1555 0 R /Next 1563 0 R >> endobj 1555 0 obj << /Title 1556 0 R /A 1553 0 R /Parent 1235 0 R /Prev 1543 0 R /Next 1583 0 R /First 1559 0 R /Last 1579 0 R /Count -6 >> endobj 1551 0 obj << /Title 1552 0 R /A 1549 0 R /Parent 1543 0 R /Prev 1547 0 R >> endobj 1547 0 obj << /Title 1548 0 R /A 1545 0 R /Parent 1543 0 R /Next 1551 0 R >> endobj 1543 0 obj << /Title 1544 0 R /A 1541 0 R /Parent 1235 0 R /Prev 1539 0 R /Next 1555 0 R /First 1547 0 R /Last 1551 0 R /Count -2 >> endobj 1539 0 obj << /Title 1540 0 R /A 1537 0 R /Parent 1235 0 R /Prev 1411 0 R /Next 1543 0 R >> endobj 1535 0 obj << /Title 1536 0 R /A 1533 0 R /Parent 1411 0 R /Prev 1531 0 R >> endobj 1531 0 obj << /Title 1532 0 R /A 1529 0 R /Parent 1411 0 R /Prev 1527 0 R /Next 1535 0 R >> endobj 1527 0 obj << /Title 1528 0 R /A 1525 0 R /Parent 1411 0 R /Prev 1523 0 R /Next 1531 0 R >> endobj 1523 0 obj << /Title 1524 0 R /A 1521 0 R /Parent 1411 0 R /Prev 1519 0 R /Next 1527 0 R >> endobj 1519 0 obj << /Title 1520 0 R /A 1517 0 R /Parent 1411 0 R /Prev 1515 0 R /Next 1523 0 R >> endobj 1515 0 obj << /Title 1516 0 R /A 1513 0 R /Parent 1411 0 R /Prev 1511 0 R /Next 1519 0 R >> endobj 1511 0 obj << /Title 1512 0 R /A 1509 0 R /Parent 1411 0 R /Prev 1507 0 R /Next 1515 0 R >> endobj 1507 0 obj << /Title 1508 0 R /A 1505 0 R /Parent 1411 0 R /Prev 1503 0 R /Next 1511 0 R >> endobj 1503 0 obj << /Title 1504 0 R /A 1501 0 R /Parent 1411 0 R /Prev 1499 0 R /Next 1507 0 R >> endobj 1499 0 obj << /Title 1500 0 R /A 1497 0 R /Parent 1411 0 R /Prev 1495 0 R /Next 1503 0 R >> endobj 1495 0 obj << /Title 1496 0 R /A 1493 0 R /Parent 1411 0 R /Prev 1491 0 R /Next 1499 0 R >> endobj 1491 0 obj << /Title 1492 0 R /A 1489 0 R /Parent 1411 0 R /Prev 1487 0 R /Next 1495 0 R >> endobj 1487 0 obj << /Title 1488 0 R /A 1485 0 R /Parent 1411 0 R /Prev 1483 0 R /Next 1491 0 R >> endobj 1483 0 obj << /Title 1484 0 R /A 1481 0 R /Parent 1411 0 R /Prev 1479 0 R /Next 1487 0 R >> endobj 1479 0 obj << /Title 1480 0 R /A 1477 0 R /Parent 1411 0 R /Prev 1475 0 R /Next 1483 0 R >> endobj 1475 0 obj << /Title 1476 0 R /A 1473 0 R /Parent 1411 0 R /Prev 1471 0 R /Next 1479 0 R >> endobj 1471 0 obj << /Title 1472 0 R /A 1469 0 R /Parent 1411 0 R /Prev 1467 0 R /Next 1475 0 R >> endobj 1467 0 obj << /Title 1468 0 R /A 1465 0 R /Parent 1411 0 R /Prev 1463 0 R /Next 1471 0 R >> endobj 1463 0 obj << /Title 1464 0 R /A 1461 0 R /Parent 1411 0 R /Prev 1459 0 R /Next 1467 0 R >> endobj 1459 0 obj << /Title 1460 0 R /A 1457 0 R /Parent 1411 0 R /Prev 1455 0 R /Next 1463 0 R >> endobj 1455 0 obj << /Title 1456 0 R /A 1453 0 R /Parent 1411 0 R /Prev 1451 0 R /Next 1459 0 R >> endobj 1451 0 obj << /Title 1452 0 R /A 1449 0 R /Parent 1411 0 R /Prev 1447 0 R /Next 1455 0 R >> endobj 1447 0 obj << /Title 1448 0 R /A 1445 0 R /Parent 1411 0 R /Prev 1443 0 R /Next 1451 0 R >> endobj 1443 0 obj << /Title 1444 0 R /A 1441 0 R /Parent 1411 0 R /Prev 1439 0 R /Next 1447 0 R >> endobj 1439 0 obj << /Title 1440 0 R /A 1437 0 R /Parent 1411 0 R /Prev 1435 0 R /Next 1443 0 R >> endobj 1435 0 obj << /Title 1436 0 R /A 1433 0 R /Parent 1411 0 R /Prev 1431 0 R /Next 1439 0 R >> endobj 1431 0 obj << /Title 1432 0 R /A 1429 0 R /Parent 1411 0 R /Prev 1427 0 R /Next 1435 0 R >> endobj 1427 0 obj << /Title 1428 0 R /A 1425 0 R /Parent 1411 0 R /Prev 1423 0 R /Next 1431 0 R >> endobj 1423 0 obj << /Title 1424 0 R /A 1421 0 R /Parent 1411 0 R /Prev 1419 0 R /Next 1427 0 R >> endobj 1419 0 obj << /Title 1420 0 R /A 1417 0 R /Parent 1411 0 R /Prev 1415 0 R /Next 1423 0 R >> endobj 1415 0 obj << /Title 1416 0 R /A 1413 0 R /Parent 1411 0 R /Next 1419 0 R >> endobj 1411 0 obj << /Title 1412 0 R /A 1409 0 R /Parent 1235 0 R /Prev 1395 0 R /Next 1539 0 R /First 1415 0 R /Last 1535 0 R /Count -31 >> endobj 1407 0 obj << /Title 1408 0 R /A 1405 0 R /Parent 1395 0 R /Prev 1403 0 R >> endobj 1403 0 obj << /Title 1404 0 R /A 1401 0 R /Parent 1395 0 R /Prev 1399 0 R /Next 1407 0 R >> endobj 1399 0 obj << /Title 1400 0 R /A 1397 0 R /Parent 1395 0 R /Next 1403 0 R >> endobj 1395 0 obj << /Title 1396 0 R /A 1393 0 R /Parent 1235 0 R /Prev 1391 0 R /Next 1411 0 R /First 1399 0 R /Last 1407 0 R /Count -3 >> endobj 1391 0 obj << /Title 1392 0 R /A 1389 0 R /Parent 1235 0 R /Prev 1387 0 R /Next 1395 0 R >> endobj 1387 0 obj << /Title 1388 0 R /A 1385 0 R /Parent 1235 0 R /Prev 1359 0 R /Next 1391 0 R >> endobj 1383 0 obj << /Title 1384 0 R /A 1381 0 R /Parent 1359 0 R /Prev 1379 0 R >> endobj 1379 0 obj << /Title 1380 0 R /A 1377 0 R /Parent 1359 0 R /Prev 1375 0 R /Next 1383 0 R >> endobj 1375 0 obj << /Title 1376 0 R /A 1373 0 R /Parent 1359 0 R /Prev 1363 0 R /Next 1379 0 R >> endobj 1371 0 obj << /Title 1372 0 R /A 1369 0 R /Parent 1363 0 R /Prev 1367 0 R >> endobj 1367 0 obj << /Title 1368 0 R /A 1365 0 R /Parent 1363 0 R /Next 1371 0 R >> endobj 1363 0 obj << /Title 1364 0 R /A 1361 0 R /Parent 1359 0 R /Next 1375 0 R /First 1367 0 R /Last 1371 0 R /Count -2 >> endobj 1359 0 obj << /Title 1360 0 R /A 1357 0 R /Parent 1235 0 R /Prev 1263 0 R /Next 1387 0 R /First 1363 0 R /Last 1383 0 R /Count -4 >> endobj 1355 0 obj << /Title 1356 0 R /A 1353 0 R /Parent 1263 0 R /Prev 1351 0 R >> endobj 1351 0 obj << /Title 1352 0 R /A 1349 0 R /Parent 1263 0 R /Prev 1299 0 R /Next 1355 0 R >> endobj 1347 0 obj << /Title 1348 0 R /A 1345 0 R /Parent 1335 0 R /Prev 1343 0 R >> endobj 1343 0 obj << /Title 1344 0 R /A 1341 0 R /Parent 1335 0 R /Prev 1339 0 R /Next 1347 0 R >> endobj 1339 0 obj << /Title 1340 0 R /A 1337 0 R /Parent 1335 0 R /Next 1343 0 R >> endobj 1335 0 obj << /Title 1336 0 R /A 1333 0 R /Parent 1299 0 R /Prev 1319 0 R /First 1339 0 R /Last 1347 0 R /Count -3 >> endobj 1331 0 obj << /Title 1332 0 R /A 1329 0 R /Parent 1319 0 R /Prev 1327 0 R >> endobj 1327 0 obj << /Title 1328 0 R /A 1325 0 R /Parent 1319 0 R /Prev 1323 0 R /Next 1331 0 R >> endobj 1323 0 obj << /Title 1324 0 R /A 1321 0 R /Parent 1319 0 R /Next 1327 0 R >> endobj 1319 0 obj << /Title 1320 0 R /A 1317 0 R /Parent 1299 0 R /Prev 1303 0 R /Next 1335 0 R /First 1323 0 R /Last 1331 0 R /Count -3 >> endobj 1315 0 obj << /Title 1316 0 R /A 1313 0 R /Parent 1303 0 R /Prev 1311 0 R >> endobj 1311 0 obj << /Title 1312 0 R /A 1309 0 R /Parent 1303 0 R /Prev 1307 0 R /Next 1315 0 R >> endobj 1307 0 obj << /Title 1308 0 R /A 1305 0 R /Parent 1303 0 R /Next 1311 0 R >> endobj 1303 0 obj << /Title 1304 0 R /A 1301 0 R /Parent 1299 0 R /Next 1319 0 R /First 1307 0 R /Last 1315 0 R /Count -3 >> endobj 1299 0 obj << /Title 1300 0 R /A 1297 0 R /Parent 1263 0 R /Prev 1267 0 R /Next 1351 0 R /First 1303 0 R /Last 1335 0 R /Count -3 >> endobj 1295 0 obj << /Title 1296 0 R /A 1293 0 R /Parent 1267 0 R /Prev 1291 0 R >> endobj 1291 0 obj << /Title 1292 0 R /A 1289 0 R /Parent 1267 0 R /Prev 1287 0 R /Next 1295 0 R >> endobj 1287 0 obj << /Title 1288 0 R /A 1285 0 R /Parent 1267 0 R /Prev 1283 0 R /Next 1291 0 R >> endobj 1283 0 obj << /Title 1284 0 R /A 1281 0 R /Parent 1267 0 R /Prev 1279 0 R /Next 1287 0 R >> endobj 1279 0 obj << /Title 1280 0 R /A 1277 0 R /Parent 1267 0 R /Prev 1275 0 R /Next 1283 0 R >> endobj 1275 0 obj << /Title 1276 0 R /A 1273 0 R /Parent 1267 0 R /Prev 1271 0 R /Next 1279 0 R >> endobj 1271 0 obj << /Title 1272 0 R /A 1269 0 R /Parent 1267 0 R /Next 1275 0 R >> endobj 1267 0 obj << /Title 1268 0 R /A 1265 0 R /Parent 1263 0 R /Next 1299 0 R /First 1271 0 R /Last 1295 0 R /Count -7 >> endobj 1263 0 obj << /Title 1264 0 R /A 1261 0 R /Parent 1235 0 R /Prev 1239 0 R /Next 1359 0 R /First 1267 0 R /Last 1355 0 R /Count -4 >> endobj 1259 0 obj << /Title 1260 0 R /A 1257 0 R /Parent 1239 0 R /Prev 1255 0 R >> endobj 1255 0 obj << /Title 1256 0 R /A 1253 0 R /Parent 1239 0 R /Prev 1251 0 R /Next 1259 0 R >> endobj 1251 0 obj << /Title 1252 0 R /A 1249 0 R /Parent 1239 0 R /Prev 1247 0 R /Next 1255 0 R >> endobj 1247 0 obj << /Title 1248 0 R /A 1245 0 R /Parent 1239 0 R /Prev 1243 0 R /Next 1251 0 R >> endobj 1243 0 obj << /Title 1244 0 R /A 1241 0 R /Parent 1239 0 R /Next 1247 0 R >> endobj 1239 0 obj << /Title 1240 0 R /A 1237 0 R /Parent 1235 0 R /Next 1263 0 R /First 1243 0 R /Last 1259 0 R /Count -5 >> endobj 1235 0 obj << /Title 1236 0 R /A 1233 0 R /Parent 4972 0 R /Prev 1059 0 R /Next 1651 0 R /First 1239 0 R /Last 1615 0 R /Count -12 >> endobj 1231 0 obj << /Title 1232 0 R /A 1229 0 R /Parent 1223 0 R /Prev 1227 0 R >> endobj 1227 0 obj << /Title 1228 0 R /A 1225 0 R /Parent 1223 0 R /Next 1231 0 R >> endobj 1223 0 obj << /Title 1224 0 R /A 1221 0 R /Parent 1059 0 R /Prev 1219 0 R /First 1227 0 R /Last 1231 0 R /Count -2 >> endobj 1219 0 obj << /Title 1220 0 R /A 1217 0 R /Parent 1059 0 R /Prev 1207 0 R /Next 1223 0 R >> endobj 1215 0 obj << /Title 1216 0 R /A 1213 0 R /Parent 1207 0 R /Prev 1211 0 R >> endobj 1211 0 obj << /Title 1212 0 R /A 1209 0 R /Parent 1207 0 R /Next 1215 0 R >> endobj 1207 0 obj << /Title 1208 0 R /A 1205 0 R /Parent 1059 0 R /Prev 1203 0 R /Next 1219 0 R /First 1211 0 R /Last 1215 0 R /Count -2 >> endobj 1203 0 obj << /Title 1204 0 R /A 1201 0 R /Parent 1059 0 R /Prev 1199 0 R /Next 1207 0 R >> endobj 1199 0 obj << /Title 1200 0 R /A 1197 0 R /Parent 1059 0 R /Prev 1195 0 R /Next 1203 0 R >> endobj 1195 0 obj << /Title 1196 0 R /A 1193 0 R /Parent 1059 0 R /Prev 1183 0 R /Next 1199 0 R >> endobj 1191 0 obj << /Title 1192 0 R /A 1189 0 R /Parent 1183 0 R /Prev 1187 0 R >> endobj 1187 0 obj << /Title 1188 0 R /A 1185 0 R /Parent 1183 0 R /Next 1191 0 R >> endobj 1183 0 obj << /Title 1184 0 R /A 1181 0 R /Parent 1059 0 R /Prev 1179 0 R /Next 1195 0 R /First 1187 0 R /Last 1191 0 R /Count -2 >> endobj 1179 0 obj << /Title 1180 0 R /A 1177 0 R /Parent 1059 0 R /Prev 1167 0 R /Next 1183 0 R >> endobj 1175 0 obj << /Title 1176 0 R /A 1173 0 R /Parent 1167 0 R /Prev 1171 0 R >> endobj 1171 0 obj << /Title 1172 0 R /A 1169 0 R /Parent 1167 0 R /Next 1175 0 R >> endobj 1167 0 obj << /Title 1168 0 R /A 1165 0 R /Parent 1059 0 R /Prev 1163 0 R /Next 1179 0 R /First 1171 0 R /Last 1175 0 R /Count -2 >> endobj 1163 0 obj << /Title 1164 0 R /A 1161 0 R /Parent 1059 0 R /Prev 1143 0 R /Next 1167 0 R >> endobj 1159 0 obj << /Title 1160 0 R /A 1157 0 R /Parent 1143 0 R /Prev 1147 0 R >> endobj 1155 0 obj << /Title 1156 0 R /A 1153 0 R /Parent 1147 0 R /Prev 1151 0 R >> endobj 1151 0 obj << /Title 1152 0 R /A 1149 0 R /Parent 1147 0 R /Next 1155 0 R >> endobj 1147 0 obj << /Title 1148 0 R /A 1145 0 R /Parent 1143 0 R /Next 1159 0 R /First 1151 0 R /Last 1155 0 R /Count -2 >> endobj 1143 0 obj << /Title 1144 0 R /A 1141 0 R /Parent 1059 0 R /Prev 1099 0 R /Next 1163 0 R /First 1147 0 R /Last 1159 0 R /Count -2 >> endobj 1139 0 obj << /Title 1140 0 R /A 1137 0 R /Parent 1099 0 R /Prev 1135 0 R >> endobj 1135 0 obj << /Title 1136 0 R /A 1133 0 R /Parent 1099 0 R /Prev 1131 0 R /Next 1139 0 R >> endobj 1131 0 obj << /Title 1132 0 R /A 1129 0 R /Parent 1099 0 R /Prev 1127 0 R /Next 1135 0 R >> endobj 1127 0 obj << /Title 1128 0 R /A 1125 0 R /Parent 1099 0 R /Prev 1123 0 R /Next 1131 0 R >> endobj 1123 0 obj << /Title 1124 0 R /A 1121 0 R /Parent 1099 0 R /Prev 1107 0 R /Next 1127 0 R >> endobj 1119 0 obj << /Title 1120 0 R /A 1117 0 R /Parent 1107 0 R /Prev 1115 0 R >> endobj 1115 0 obj << /Title 1116 0 R /A 1113 0 R /Parent 1107 0 R /Prev 1111 0 R /Next 1119 0 R >> endobj 1111 0 obj << /Title 1112 0 R /A 1109 0 R /Parent 1107 0 R /Next 1115 0 R >> endobj 1107 0 obj << /Title 1108 0 R /A 1105 0 R /Parent 1099 0 R /Prev 1103 0 R /Next 1123 0 R /First 1111 0 R /Last 1119 0 R /Count -3 >> endobj 1103 0 obj << /Title 1104 0 R /A 1101 0 R /Parent 1099 0 R /Next 1107 0 R >> endobj 1099 0 obj << /Title 1100 0 R /A 1097 0 R /Parent 1059 0 R /Prev 1075 0 R /Next 1143 0 R /First 1103 0 R /Last 1139 0 R /Count -7 >> endobj 1095 0 obj << /Title 1096 0 R /A 1093 0 R /Parent 1075 0 R /Prev 1079 0 R >> endobj 1091 0 obj << /Title 1092 0 R /A 1089 0 R /Parent 1079 0 R /Prev 1087 0 R >> endobj 1087 0 obj << /Title 1088 0 R /A 1085 0 R /Parent 1079 0 R /Prev 1083 0 R /Next 1091 0 R >> endobj 1083 0 obj << /Title 1084 0 R /A 1081 0 R /Parent 1079 0 R /Next 1087 0 R >> endobj 1079 0 obj << /Title 1080 0 R /A 1077 0 R /Parent 1075 0 R /Next 1095 0 R /First 1083 0 R /Last 1091 0 R /Count -3 >> endobj 1075 0 obj << /Title 1076 0 R /A 1073 0 R /Parent 1059 0 R /Prev 1063 0 R /Next 1099 0 R /First 1079 0 R /Last 1095 0 R /Count -2 >> endobj 1071 0 obj << /Title 1072 0 R /A 1069 0 R /Parent 1063 0 R /Prev 1067 0 R >> endobj 1067 0 obj << /Title 1068 0 R /A 1065 0 R /Parent 1063 0 R /Next 1071 0 R >> endobj 1063 0 obj << /Title 1064 0 R /A 1061 0 R /Parent 1059 0 R /Next 1075 0 R /First 1067 0 R /Last 1071 0 R /Count -2 >> endobj 1059 0 obj << /Title 1060 0 R /A 1057 0 R /Parent 4972 0 R /Prev 443 0 R /Next 1235 0 R /First 1063 0 R /Last 1223 0 R /Count -14 >> endobj 1055 0 obj << /Title 1056 0 R /A 1053 0 R /Parent 1047 0 R /Prev 1051 0 R >> endobj 1051 0 obj << /Title 1052 0 R /A 1049 0 R /Parent 1047 0 R /Next 1055 0 R >> endobj 1047 0 obj << /Title 1048 0 R /A 1045 0 R /Parent 1007 0 R /Prev 1043 0 R /First 1051 0 R /Last 1055 0 R /Count -2 >> endobj 1043 0 obj << /Title 1044 0 R /A 1041 0 R /Parent 1007 0 R /Prev 1023 0 R /Next 1047 0 R >> endobj 1039 0 obj << /Title 1040 0 R /A 1037 0 R /Parent 1023 0 R /Prev 1035 0 R >> endobj 1035 0 obj << /Title 1036 0 R /A 1033 0 R /Parent 1023 0 R /Prev 1031 0 R /Next 1039 0 R >> endobj 1031 0 obj << /Title 1032 0 R /A 1029 0 R /Parent 1023 0 R /Prev 1027 0 R /Next 1035 0 R >> endobj 1027 0 obj << /Title 1028 0 R /A 1025 0 R /Parent 1023 0 R /Next 1031 0 R >> endobj 1023 0 obj << /Title 1024 0 R /A 1021 0 R /Parent 1007 0 R /Prev 1011 0 R /Next 1043 0 R /First 1027 0 R /Last 1039 0 R /Count -4 >> endobj 1019 0 obj << /Title 1020 0 R /A 1017 0 R /Parent 1011 0 R /Prev 1015 0 R >> endobj 1015 0 obj << /Title 1016 0 R /A 1013 0 R /Parent 1011 0 R /Next 1019 0 R >> endobj 1011 0 obj << /Title 1012 0 R /A 1009 0 R /Parent 1007 0 R /Next 1023 0 R /First 1015 0 R /Last 1019 0 R /Count -2 >> endobj 1007 0 obj << /Title 1008 0 R /A 1005 0 R /Parent 443 0 R /Prev 975 0 R /First 1011 0 R /Last 1047 0 R /Count -4 >> endobj 1003 0 obj << /Title 1004 0 R /A 1001 0 R /Parent 975 0 R /Prev 979 0 R >> endobj 999 0 obj << /Title 1000 0 R /A 997 0 R /Parent 979 0 R /Prev 983 0 R >> endobj 995 0 obj << /Title 996 0 R /A 993 0 R /Parent 983 0 R /Prev 991 0 R >> endobj 991 0 obj << /Title 992 0 R /A 989 0 R /Parent 983 0 R /Prev 987 0 R /Next 995 0 R >> endobj 987 0 obj << /Title 988 0 R /A 985 0 R /Parent 983 0 R /Next 991 0 R >> endobj 983 0 obj << /Title 984 0 R /A 981 0 R /Parent 979 0 R /Next 999 0 R /First 987 0 R /Last 995 0 R /Count -3 >> endobj 979 0 obj << /Title 980 0 R /A 977 0 R /Parent 975 0 R /Next 1003 0 R /First 983 0 R /Last 999 0 R /Count -2 >> endobj 975 0 obj << /Title 976 0 R /A 973 0 R /Parent 443 0 R /Prev 915 0 R /Next 1007 0 R /First 979 0 R /Last 1003 0 R /Count -2 >> endobj 971 0 obj << /Title 972 0 R /A 969 0 R /Parent 955 0 R /Prev 967 0 R >> endobj 967 0 obj << /Title 968 0 R /A 965 0 R /Parent 955 0 R /Prev 963 0 R /Next 971 0 R >> endobj 963 0 obj << /Title 964 0 R /A 961 0 R /Parent 955 0 R /Prev 959 0 R /Next 967 0 R >> endobj 959 0 obj << /Title 960 0 R /A 957 0 R /Parent 955 0 R /Next 963 0 R >> endobj 955 0 obj << /Title 956 0 R /A 953 0 R /Parent 915 0 R /Prev 951 0 R /First 959 0 R /Last 971 0 R /Count -4 >> endobj 951 0 obj << /Title 952 0 R /A 949 0 R /Parent 915 0 R /Prev 935 0 R /Next 955 0 R >> endobj 947 0 obj << /Title 948 0 R /A 945 0 R /Parent 935 0 R /Prev 943 0 R >> endobj 943 0 obj << /Title 944 0 R /A 941 0 R /Parent 935 0 R /Prev 939 0 R /Next 947 0 R >> endobj 939 0 obj << /Title 940 0 R /A 937 0 R /Parent 935 0 R /Next 943 0 R >> endobj 935 0 obj << /Title 936 0 R /A 933 0 R /Parent 915 0 R /Prev 919 0 R /Next 951 0 R /First 939 0 R /Last 947 0 R /Count -3 >> endobj 931 0 obj << /Title 932 0 R /A 929 0 R /Parent 919 0 R /Prev 927 0 R >> endobj 927 0 obj << /Title 928 0 R /A 925 0 R /Parent 919 0 R /Prev 923 0 R /Next 931 0 R >> endobj 923 0 obj << /Title 924 0 R /A 921 0 R /Parent 919 0 R /Next 927 0 R >> endobj 919 0 obj << /Title 920 0 R /A 917 0 R /Parent 915 0 R /Next 935 0 R /First 923 0 R /Last 931 0 R /Count -3 >> endobj 915 0 obj << /Title 916 0 R /A 913 0 R /Parent 443 0 R /Prev 775 0 R /Next 975 0 R /First 919 0 R /Last 955 0 R /Count -4 >> endobj 911 0 obj << /Title 912 0 R /A 909 0 R /Parent 883 0 R /Prev 907 0 R >> endobj 907 0 obj << /Title 908 0 R /A 905 0 R /Parent 883 0 R /Prev 903 0 R /Next 911 0 R >> endobj 903 0 obj << /Title 904 0 R /A 901 0 R /Parent 883 0 R /Prev 899 0 R /Next 907 0 R >> endobj 899 0 obj << /Title 900 0 R /A 897 0 R /Parent 883 0 R /Prev 895 0 R /Next 903 0 R >> endobj 895 0 obj << /Title 896 0 R /A 893 0 R /Parent 883 0 R /Prev 891 0 R /Next 899 0 R >> endobj 891 0 obj << /Title 892 0 R /A 889 0 R /Parent 883 0 R /Prev 887 0 R /Next 895 0 R >> endobj 887 0 obj << /Title 888 0 R /A 885 0 R /Parent 883 0 R /Next 891 0 R >> endobj 883 0 obj << /Title 884 0 R /A 881 0 R /Parent 775 0 R /Prev 863 0 R /First 887 0 R /Last 911 0 R /Count -7 >> endobj 879 0 obj << /Title 880 0 R /A 877 0 R /Parent 863 0 R /Prev 875 0 R >> endobj 875 0 obj << /Title 876 0 R /A 873 0 R /Parent 863 0 R /Prev 871 0 R /Next 879 0 R >> endobj 871 0 obj << /Title 872 0 R /A 869 0 R /Parent 863 0 R /Prev 867 0 R /Next 875 0 R >> endobj 867 0 obj << /Title 868 0 R /A 865 0 R /Parent 863 0 R /Next 871 0 R >> endobj 863 0 obj << /Title 864 0 R /A 861 0 R /Parent 775 0 R /Prev 843 0 R /Next 883 0 R /First 867 0 R /Last 879 0 R /Count -4 >> endobj 859 0 obj << /Title 860 0 R /A 857 0 R /Parent 843 0 R /Prev 855 0 R >> endobj 855 0 obj << /Title 856 0 R /A 853 0 R /Parent 843 0 R /Prev 851 0 R /Next 859 0 R >> endobj 851 0 obj << /Title 852 0 R /A 849 0 R /Parent 843 0 R /Prev 847 0 R /Next 855 0 R >> endobj 847 0 obj << /Title 848 0 R /A 845 0 R /Parent 843 0 R /Next 851 0 R >> endobj 843 0 obj << /Title 844 0 R /A 841 0 R /Parent 775 0 R /Prev 819 0 R /Next 863 0 R /First 847 0 R /Last 859 0 R /Count -4 >> endobj 839 0 obj << /Title 840 0 R /A 837 0 R /Parent 819 0 R /Prev 835 0 R >> endobj 835 0 obj << /Title 836 0 R /A 833 0 R /Parent 819 0 R /Prev 831 0 R /Next 839 0 R >> endobj 831 0 obj << /Title 832 0 R /A 829 0 R /Parent 819 0 R /Prev 827 0 R /Next 835 0 R >> endobj 827 0 obj << /Title 828 0 R /A 825 0 R /Parent 819 0 R /Prev 823 0 R /Next 831 0 R >> endobj 823 0 obj << /Title 824 0 R /A 821 0 R /Parent 819 0 R /Next 827 0 R >> endobj 819 0 obj << /Title 820 0 R /A 817 0 R /Parent 775 0 R /Prev 815 0 R /Next 843 0 R /First 823 0 R /Last 839 0 R /Count -5 >> endobj 815 0 obj << /Title 816 0 R /A 813 0 R /Parent 775 0 R /Prev 811 0 R /Next 819 0 R >> endobj 811 0 obj << /Title 812 0 R /A 809 0 R /Parent 775 0 R /Prev 807 0 R /Next 815 0 R >> endobj 807 0 obj << /Title 808 0 R /A 805 0 R /Parent 775 0 R /Prev 795 0 R /Next 811 0 R >> endobj 803 0 obj << /Title 804 0 R /A 801 0 R /Parent 795 0 R /Prev 799 0 R >> endobj 799 0 obj << /Title 800 0 R /A 797 0 R /Parent 795 0 R /Next 803 0 R >> endobj 795 0 obj << /Title 796 0 R /A 793 0 R /Parent 775 0 R /Prev 791 0 R /Next 807 0 R /First 799 0 R /Last 803 0 R /Count -2 >> endobj 791 0 obj << /Title 792 0 R /A 789 0 R /Parent 775 0 R /Prev 783 0 R /Next 795 0 R >> endobj 787 0 obj << /Title 788 0 R /A 785 0 R /Parent 783 0 R >> endobj 783 0 obj << /Title 784 0 R /A 781 0 R /Parent 775 0 R /Prev 779 0 R /Next 791 0 R /First 787 0 R /Last 787 0 R /Count -1 >> endobj 779 0 obj << /Title 780 0 R /A 777 0 R /Parent 775 0 R /Next 783 0 R >> endobj 775 0 obj << /Title 776 0 R /A 773 0 R /Parent 443 0 R /Prev 751 0 R /Next 915 0 R /First 779 0 R /Last 883 0 R /Count -11 >> endobj 771 0 obj << /Title 772 0 R /A 769 0 R /Parent 763 0 R /Prev 767 0 R >> endobj 767 0 obj << /Title 768 0 R /A 765 0 R /Parent 763 0 R /Next 771 0 R >> endobj 763 0 obj << /Title 764 0 R /A 761 0 R /Parent 751 0 R /Prev 759 0 R /First 767 0 R /Last 771 0 R /Count -2 >> endobj 759 0 obj << /Title 760 0 R /A 757 0 R /Parent 751 0 R /Prev 755 0 R /Next 763 0 R >> endobj 755 0 obj << /Title 756 0 R /A 753 0 R /Parent 751 0 R /Next 759 0 R >> endobj 751 0 obj << /Title 752 0 R /A 749 0 R /Parent 443 0 R /Prev 659 0 R /Next 775 0 R /First 755 0 R /Last 763 0 R /Count -3 >> endobj 747 0 obj << /Title 748 0 R /A 745 0 R /Parent 743 0 R >> endobj 743 0 obj << /Title 744 0 R /A 741 0 R /Parent 659 0 R /Prev 723 0 R /First 747 0 R /Last 747 0 R /Count -1 >> endobj 739 0 obj << /Title 740 0 R /A 737 0 R /Parent 723 0 R /Prev 735 0 R >> endobj 735 0 obj << /Title 736 0 R /A 733 0 R /Parent 723 0 R /Prev 731 0 R /Next 739 0 R >> endobj 731 0 obj << /Title 732 0 R /A 729 0 R /Parent 723 0 R /Prev 727 0 R /Next 735 0 R >> endobj 727 0 obj << /Title 728 0 R /A 725 0 R /Parent 723 0 R /Next 731 0 R >> endobj 723 0 obj << /Title 724 0 R /A 721 0 R /Parent 659 0 R /Prev 691 0 R /Next 743 0 R /First 727 0 R /Last 739 0 R /Count -4 >> endobj 719 0 obj << /Title 720 0 R /A 717 0 R /Parent 691 0 R /Prev 695 0 R >> endobj 715 0 obj << /Title 716 0 R /A 713 0 R /Parent 695 0 R /Prev 711 0 R >> endobj 711 0 obj << /Title 712 0 R /A 709 0 R /Parent 695 0 R /Prev 707 0 R /Next 715 0 R >> endobj 707 0 obj << /Title 708 0 R /A 705 0 R /Parent 695 0 R /Prev 703 0 R /Next 711 0 R >> endobj 703 0 obj << /Title 704 0 R /A 701 0 R /Parent 695 0 R /Prev 699 0 R /Next 707 0 R >> endobj 699 0 obj << /Title 700 0 R /A 697 0 R /Parent 695 0 R /Next 703 0 R >> endobj 695 0 obj << /Title 696 0 R /A 693 0 R /Parent 691 0 R /Next 719 0 R /First 699 0 R /Last 715 0 R /Count -5 >> endobj 691 0 obj << /Title 692 0 R /A 689 0 R /Parent 659 0 R /Prev 663 0 R /Next 723 0 R /First 695 0 R /Last 719 0 R /Count -2 >> endobj 687 0 obj << /Title 688 0 R /A 685 0 R /Parent 667 0 R /Prev 683 0 R >> endobj 683 0 obj << /Title 684 0 R /A 681 0 R /Parent 667 0 R /Prev 679 0 R /Next 687 0 R >> endobj 679 0 obj << /Title 680 0 R /A 677 0 R /Parent 667 0 R /Prev 675 0 R /Next 683 0 R >> endobj 675 0 obj << /Title 676 0 R /A 673 0 R /Parent 667 0 R /Prev 671 0 R /Next 679 0 R >> endobj 671 0 obj << /Title 672 0 R /A 669 0 R /Parent 667 0 R /Next 675 0 R >> endobj 667 0 obj << /Title 668 0 R /A 665 0 R /Parent 663 0 R /First 671 0 R /Last 687 0 R /Count -5 >> endobj 663 0 obj << /Title 664 0 R /A 661 0 R /Parent 659 0 R /Next 691 0 R /First 667 0 R /Last 667 0 R /Count -1 >> endobj 659 0 obj << /Title 660 0 R /A 657 0 R /Parent 443 0 R /Prev 447 0 R /Next 751 0 R /First 663 0 R /Last 743 0 R /Count -4 >> endobj 655 0 obj << /Title 656 0 R /A 653 0 R /Parent 627 0 R /Prev 651 0 R >> endobj 651 0 obj << /Title 652 0 R /A 649 0 R /Parent 627 0 R /Prev 639 0 R /Next 655 0 R >> endobj 647 0 obj << /Title 648 0 R /A 645 0 R /Parent 639 0 R /Prev 643 0 R >> endobj 643 0 obj << /Title 644 0 R /A 641 0 R /Parent 639 0 R /Next 647 0 R >> endobj 639 0 obj << /Title 640 0 R /A 637 0 R /Parent 627 0 R /Prev 635 0 R /Next 651 0 R /First 643 0 R /Last 647 0 R /Count -2 >> endobj 635 0 obj << /Title 636 0 R /A 633 0 R /Parent 627 0 R /Prev 631 0 R /Next 639 0 R >> endobj 631 0 obj << /Title 632 0 R /A 629 0 R /Parent 627 0 R /Next 635 0 R >> endobj 627 0 obj << /Title 628 0 R /A 625 0 R /Parent 447 0 R /Prev 615 0 R /First 631 0 R /Last 655 0 R /Count -5 >> endobj 623 0 obj << /Title 624 0 R /A 621 0 R /Parent 615 0 R /Prev 619 0 R >> endobj 619 0 obj << /Title 620 0 R /A 617 0 R /Parent 615 0 R /Next 623 0 R >> endobj 615 0 obj << /Title 616 0 R /A 613 0 R /Parent 447 0 R /Prev 611 0 R /Next 627 0 R /First 619 0 R /Last 623 0 R /Count -2 >> endobj 611 0 obj << /Title 612 0 R /A 609 0 R /Parent 447 0 R /Prev 607 0 R /Next 615 0 R >> endobj 607 0 obj << /Title 608 0 R /A 605 0 R /Parent 447 0 R /Prev 603 0 R /Next 611 0 R >> endobj 603 0 obj << /Title 604 0 R /A 601 0 R /Parent 447 0 R /Prev 455 0 R /Next 607 0 R >> endobj 599 0 obj << /Title 600 0 R /A 597 0 R /Parent 591 0 R /Prev 595 0 R >> endobj 595 0 obj << /Title 596 0 R /A 593 0 R /Parent 591 0 R /Next 599 0 R >> endobj 591 0 obj << /Title 592 0 R /A 589 0 R /Parent 455 0 R /Prev 579 0 R /First 595 0 R /Last 599 0 R /Count -2 >> endobj 587 0 obj << /Title 588 0 R /A 585 0 R /Parent 579 0 R /Prev 583 0 R >> endobj 583 0 obj << /Title 584 0 R /A 581 0 R /Parent 579 0 R /Next 587 0 R >> endobj 579 0 obj << /Title 580 0 R /A 577 0 R /Parent 455 0 R /Prev 567 0 R /Next 591 0 R /First 583 0 R /Last 587 0 R /Count -2 >> endobj 575 0 obj << /Title 576 0 R /A 573 0 R /Parent 567 0 R /Prev 571 0 R >> endobj 571 0 obj << /Title 572 0 R /A 569 0 R /Parent 567 0 R /Next 575 0 R >> endobj 567 0 obj << /Title 568 0 R /A 565 0 R /Parent 455 0 R /Prev 555 0 R /Next 579 0 R /First 571 0 R /Last 575 0 R /Count -2 >> endobj 563 0 obj << /Title 564 0 R /A 561 0 R /Parent 555 0 R /Prev 559 0 R >> endobj 559 0 obj << /Title 560 0 R /A 557 0 R /Parent 555 0 R /Next 563 0 R >> endobj 555 0 obj << /Title 556 0 R /A 553 0 R /Parent 455 0 R /Prev 551 0 R /Next 567 0 R /First 559 0 R /Last 563 0 R /Count -2 >> endobj 551 0 obj << /Title 552 0 R /A 549 0 R /Parent 455 0 R /Prev 547 0 R /Next 555 0 R >> endobj 547 0 obj << /Title 548 0 R /A 545 0 R /Parent 455 0 R /Prev 543 0 R /Next 551 0 R >> endobj 543 0 obj << /Title 544 0 R /A 541 0 R /Parent 455 0 R /Prev 531 0 R /Next 547 0 R >> endobj 539 0 obj << /Title 540 0 R /A 537 0 R /Parent 531 0 R /Prev 535 0 R >> endobj 535 0 obj << /Title 536 0 R /A 533 0 R /Parent 531 0 R /Next 539 0 R >> endobj 531 0 obj << /Title 532 0 R /A 529 0 R /Parent 455 0 R /Prev 519 0 R /Next 543 0 R /First 535 0 R /Last 539 0 R /Count -2 >> endobj 527 0 obj << /Title 528 0 R /A 525 0 R /Parent 519 0 R /Prev 523 0 R >> endobj 523 0 obj << /Title 524 0 R /A 521 0 R /Parent 519 0 R /Next 527 0 R >> endobj 519 0 obj << /Title 520 0 R /A 517 0 R /Parent 455 0 R /Prev 507 0 R /Next 531 0 R /First 523 0 R /Last 527 0 R /Count -2 >> endobj 515 0 obj << /Title 516 0 R /A 513 0 R /Parent 507 0 R /Prev 511 0 R >> endobj 511 0 obj << /Title 512 0 R /A 509 0 R /Parent 507 0 R /Next 515 0 R >> endobj 507 0 obj << /Title 508 0 R /A 505 0 R /Parent 455 0 R /Prev 503 0 R /Next 519 0 R /First 511 0 R /Last 515 0 R /Count -2 >> endobj 503 0 obj << /Title 504 0 R /A 501 0 R /Parent 455 0 R /Prev 491 0 R /Next 507 0 R >> endobj 499 0 obj << /Title 500 0 R /A 497 0 R /Parent 491 0 R /Prev 495 0 R >> endobj 495 0 obj << /Title 496 0 R /A 493 0 R /Parent 491 0 R /Next 499 0 R >> endobj 491 0 obj << /Title 492 0 R /A 489 0 R /Parent 455 0 R /Prev 475 0 R /Next 503 0 R /First 495 0 R /Last 499 0 R /Count -2 >> endobj 487 0 obj << /Title 488 0 R /A 485 0 R /Parent 475 0 R /Prev 483 0 R >> endobj 483 0 obj << /Title 484 0 R /A 481 0 R /Parent 475 0 R /Prev 479 0 R /Next 487 0 R >> endobj 479 0 obj << /Title 480 0 R /A 477 0 R /Parent 475 0 R /Next 483 0 R >> endobj 475 0 obj << /Title 476 0 R /A 473 0 R /Parent 455 0 R /Prev 471 0 R /Next 491 0 R /First 479 0 R /Last 487 0 R /Count -3 >> endobj 471 0 obj << /Title 472 0 R /A 469 0 R /Parent 455 0 R /Prev 459 0 R /Next 475 0 R >> endobj 467 0 obj << /Title 468 0 R /A 465 0 R /Parent 459 0 R /Prev 463 0 R >> endobj 463 0 obj << /Title 464 0 R /A 461 0 R /Parent 459 0 R /Next 467 0 R >> endobj 459 0 obj << /Title 460 0 R /A 457 0 R /Parent 455 0 R /Next 471 0 R /First 463 0 R /Last 467 0 R /Count -2 >> endobj 455 0 obj << /Title 456 0 R /A 453 0 R /Parent 447 0 R /Prev 451 0 R /Next 603 0 R /First 459 0 R /Last 591 0 R /Count -15 >> endobj 451 0 obj << /Title 452 0 R /A 449 0 R /Parent 447 0 R /Next 455 0 R >> endobj 447 0 obj << /Title 448 0 R /A 445 0 R /Parent 443 0 R /Next 659 0 R /First 451 0 R /Last 627 0 R /Count -7 >> endobj 443 0 obj << /Title 444 0 R /A 441 0 R /Parent 4972 0 R /Prev 339 0 R /Next 1059 0 R /First 447 0 R /Last 1007 0 R /Count -7 >> endobj 439 0 obj << /Title 440 0 R /A 437 0 R /Parent 435 0 R >> endobj 435 0 obj << /Title 436 0 R /A 433 0 R /Parent 403 0 R /Prev 427 0 R /First 439 0 R /Last 439 0 R /Count -1 >> endobj 431 0 obj << /Title 432 0 R /A 429 0 R /Parent 427 0 R >> endobj 427 0 obj << /Title 428 0 R /A 425 0 R /Parent 403 0 R /Prev 423 0 R /Next 435 0 R /First 431 0 R /Last 431 0 R /Count -1 >> endobj 423 0 obj << /Title 424 0 R /A 421 0 R /Parent 403 0 R /Prev 419 0 R /Next 427 0 R >> endobj 419 0 obj << /Title 420 0 R /A 417 0 R /Parent 403 0 R /Prev 415 0 R /Next 423 0 R >> endobj 415 0 obj << /Title 416 0 R /A 413 0 R /Parent 403 0 R /Prev 407 0 R /Next 419 0 R >> endobj 411 0 obj << /Title 412 0 R /A 409 0 R /Parent 407 0 R >> endobj 407 0 obj << /Title 408 0 R /A 405 0 R /Parent 403 0 R /Next 415 0 R /First 411 0 R /Last 411 0 R /Count -1 >> endobj 403 0 obj << /Title 404 0 R /A 401 0 R /Parent 339 0 R /Prev 371 0 R /First 407 0 R /Last 435 0 R /Count -6 >> endobj 399 0 obj << /Title 400 0 R /A 397 0 R /Parent 395 0 R >> endobj 395 0 obj << /Title 396 0 R /A 393 0 R /Parent 371 0 R /Prev 383 0 R /First 399 0 R /Last 399 0 R /Count -1 >> endobj 391 0 obj << /Title 392 0 R /A 389 0 R /Parent 383 0 R /Prev 387 0 R >> endobj 387 0 obj << /Title 388 0 R /A 385 0 R /Parent 383 0 R /Next 391 0 R >> endobj 383 0 obj << /Title 384 0 R /A 381 0 R /Parent 371 0 R /Prev 379 0 R /Next 395 0 R /First 387 0 R /Last 391 0 R /Count -2 >> endobj 379 0 obj << /Title 380 0 R /A 377 0 R /Parent 371 0 R /Prev 375 0 R /Next 383 0 R >> endobj 375 0 obj << /Title 376 0 R /A 373 0 R /Parent 371 0 R /Next 379 0 R >> endobj 371 0 obj << /Title 372 0 R /A 369 0 R /Parent 339 0 R /Prev 351 0 R /Next 403 0 R /First 375 0 R /Last 395 0 R /Count -4 >> endobj 367 0 obj << /Title 368 0 R /A 365 0 R /Parent 351 0 R /Prev 363 0 R >> endobj 363 0 obj << /Title 364 0 R /A 361 0 R /Parent 351 0 R /Prev 359 0 R /Next 367 0 R >> endobj 359 0 obj << /Title 360 0 R /A 357 0 R /Parent 351 0 R /Prev 355 0 R /Next 363 0 R >> endobj 355 0 obj << /Title 356 0 R /A 353 0 R /Parent 351 0 R /Next 359 0 R >> endobj 351 0 obj << /Title 352 0 R /A 349 0 R /Parent 339 0 R /Prev 343 0 R /Next 371 0 R /First 355 0 R /Last 367 0 R /Count -4 >> endobj 347 0 obj << /Title 348 0 R /A 345 0 R /Parent 343 0 R >> endobj 343 0 obj << /Title 344 0 R /A 341 0 R /Parent 339 0 R /Next 351 0 R /First 347 0 R /Last 347 0 R /Count -1 >> endobj 339 0 obj << /Title 340 0 R /A 337 0 R /Parent 4972 0 R /Prev 135 0 R /Next 443 0 R /First 343 0 R /Last 403 0 R /Count -4 >> endobj 335 0 obj << /Title 336 0 R /A 333 0 R /Parent 135 0 R /Prev 331 0 R >> endobj 331 0 obj << /Title 332 0 R /A 329 0 R /Parent 135 0 R /Prev 327 0 R /Next 335 0 R >> endobj 327 0 obj << /Title 328 0 R /A 325 0 R /Parent 135 0 R /Prev 323 0 R /Next 331 0 R >> endobj 323 0 obj << /Title 324 0 R /A 321 0 R /Parent 135 0 R /Prev 295 0 R /Next 327 0 R >> endobj 319 0 obj << /Title 320 0 R /A 317 0 R /Parent 315 0 R >> endobj 315 0 obj << /Title 316 0 R /A 313 0 R /Parent 295 0 R /Prev 299 0 R /First 319 0 R /Last 319 0 R /Count -1 >> endobj 311 0 obj << /Title 312 0 R /A 309 0 R /Parent 299 0 R /Prev 307 0 R >> endobj 307 0 obj << /Title 308 0 R /A 305 0 R /Parent 299 0 R /Prev 303 0 R /Next 311 0 R >> endobj 303 0 obj << /Title 304 0 R /A 301 0 R /Parent 299 0 R /Next 307 0 R >> endobj 299 0 obj << /Title 300 0 R /A 297 0 R /Parent 295 0 R /Next 315 0 R /First 303 0 R /Last 311 0 R /Count -3 >> endobj 295 0 obj << /Title 296 0 R /A 293 0 R /Parent 135 0 R /Prev 231 0 R /Next 323 0 R /First 299 0 R /Last 315 0 R /Count -2 >> endobj 291 0 obj << /Title 292 0 R /A 289 0 R /Parent 279 0 R /Prev 287 0 R >> endobj 287 0 obj << /Title 288 0 R /A 285 0 R /Parent 279 0 R /Prev 283 0 R /Next 291 0 R >> endobj 283 0 obj << /Title 284 0 R /A 281 0 R /Parent 279 0 R /Next 287 0 R >> endobj 279 0 obj << /Title 280 0 R /A 277 0 R /Parent 231 0 R /Prev 267 0 R /First 283 0 R /Last 291 0 R /Count -3 >> endobj 275 0 obj << /Title 276 0 R /A 273 0 R /Parent 267 0 R /Prev 271 0 R >> endobj 271 0 obj << /Title 272 0 R /A 269 0 R /Parent 267 0 R /Next 275 0 R >> endobj 267 0 obj << /Title 268 0 R /A 265 0 R /Parent 231 0 R /Prev 243 0 R /Next 279 0 R /First 271 0 R /Last 275 0 R /Count -2 >> endobj 263 0 obj << /Title 264 0 R /A 261 0 R /Parent 243 0 R /Prev 259 0 R >> endobj 259 0 obj << /Title 260 0 R /A 257 0 R /Parent 243 0 R /Prev 255 0 R /Next 263 0 R >> endobj 255 0 obj << /Title 256 0 R /A 253 0 R /Parent 243 0 R /Prev 251 0 R /Next 259 0 R >> endobj 251 0 obj << /Title 252 0 R /A 249 0 R /Parent 243 0 R /Prev 247 0 R /Next 255 0 R >> endobj 247 0 obj << /Title 248 0 R /A 245 0 R /Parent 243 0 R /Next 251 0 R >> endobj 243 0 obj << /Title 244 0 R /A 241 0 R /Parent 231 0 R /Prev 239 0 R /Next 267 0 R /First 247 0 R /Last 263 0 R /Count -5 >> endobj 239 0 obj << /Title 240 0 R /A 237 0 R /Parent 231 0 R /Prev 235 0 R /Next 243 0 R >> endobj 235 0 obj << /Title 236 0 R /A 233 0 R /Parent 231 0 R /Next 239 0 R >> endobj 231 0 obj << /Title 232 0 R /A 229 0 R /Parent 135 0 R /Prev 167 0 R /Next 295 0 R /First 235 0 R /Last 279 0 R /Count -5 >> endobj 227 0 obj << /Title 228 0 R /A 225 0 R /Parent 207 0 R /Prev 223 0 R >> endobj 223 0 obj << /Title 224 0 R /A 221 0 R /Parent 207 0 R /Prev 219 0 R /Next 227 0 R >> endobj 219 0 obj << /Title 220 0 R /A 217 0 R /Parent 207 0 R /Prev 215 0 R /Next 223 0 R >> endobj 215 0 obj << /Title 216 0 R /A 213 0 R /Parent 207 0 R /Prev 211 0 R /Next 219 0 R >> endobj 211 0 obj << /Title 212 0 R /A 209 0 R /Parent 207 0 R /Next 215 0 R >> endobj 207 0 obj << /Title 208 0 R /A 205 0 R /Parent 187 0 R /Prev 191 0 R /First 211 0 R /Last 227 0 R /Count -5 >> endobj 203 0 obj << /Title 204 0 R /A 201 0 R /Parent 191 0 R /Prev 199 0 R >> endobj 199 0 obj << /Title 200 0 R /A 197 0 R /Parent 191 0 R /Prev 195 0 R /Next 203 0 R >> endobj 195 0 obj << /Title 196 0 R /A 193 0 R /Parent 191 0 R /Next 199 0 R >> endobj 191 0 obj << /Title 192 0 R /A 189 0 R /Parent 187 0 R /Next 207 0 R /First 195 0 R /Last 203 0 R /Count -3 >> endobj 187 0 obj << /Title 188 0 R /A 185 0 R /Parent 167 0 R /Prev 183 0 R /First 191 0 R /Last 207 0 R /Count -2 >> endobj 183 0 obj << /Title 184 0 R /A 181 0 R /Parent 167 0 R /Prev 179 0 R /Next 187 0 R >> endobj 179 0 obj << /Title 180 0 R /A 177 0 R /Parent 167 0 R /Prev 175 0 R /Next 183 0 R >> endobj 175 0 obj << /Title 176 0 R /A 173 0 R /Parent 167 0 R /Prev 171 0 R /Next 179 0 R >> endobj 171 0 obj << /Title 172 0 R /A 169 0 R /Parent 167 0 R /Next 175 0 R >> endobj 167 0 obj << /Title 168 0 R /A 165 0 R /Parent 135 0 R /Prev 155 0 R /Next 231 0 R /First 171 0 R /Last 187 0 R /Count -5 >> endobj 163 0 obj << /Title 164 0 R /A 161 0 R /Parent 155 0 R /Prev 159 0 R >> endobj 159 0 obj << /Title 160 0 R /A 157 0 R /Parent 155 0 R /Next 163 0 R >> endobj 155 0 obj << /Title 156 0 R /A 153 0 R /Parent 135 0 R /Prev 151 0 R /Next 167 0 R /First 159 0 R /Last 163 0 R /Count -2 >> endobj 151 0 obj << /Title 152 0 R /A 149 0 R /Parent 135 0 R /Prev 147 0 R /Next 155 0 R >> endobj 147 0 obj << /Title 148 0 R /A 145 0 R /Parent 135 0 R /Prev 143 0 R /Next 151 0 R >> endobj 143 0 obj << /Title 144 0 R /A 141 0 R /Parent 135 0 R /Prev 139 0 R /Next 147 0 R >> endobj 139 0 obj << /Title 140 0 R /A 137 0 R /Parent 135 0 R /Next 143 0 R >> endobj 135 0 obj << /Title 136 0 R /A 133 0 R /Parent 4972 0 R /Prev 55 0 R /Next 339 0 R /First 139 0 R /Last 335 0 R /Count -12 >> endobj 131 0 obj << /Title 132 0 R /A 129 0 R /Parent 119 0 R /Prev 127 0 R >> endobj 127 0 obj << /Title 128 0 R /A 125 0 R /Parent 119 0 R /Prev 123 0 R /Next 131 0 R >> endobj 123 0 obj << /Title 124 0 R /A 121 0 R /Parent 119 0 R /Next 127 0 R >> endobj 119 0 obj << /Title 120 0 R /A 117 0 R /Parent 55 0 R /Prev 115 0 R /First 123 0 R /Last 131 0 R /Count -3 >> endobj 115 0 obj << /Title 116 0 R /A 113 0 R /Parent 55 0 R /Prev 111 0 R /Next 119 0 R >> endobj 111 0 obj << /Title 112 0 R /A 109 0 R /Parent 55 0 R /Prev 107 0 R /Next 115 0 R >> endobj 107 0 obj << /Title 108 0 R /A 105 0 R /Parent 55 0 R /Prev 103 0 R /Next 111 0 R >> endobj 103 0 obj << /Title 104 0 R /A 101 0 R /Parent 55 0 R /Prev 67 0 R /Next 107 0 R >> endobj 99 0 obj << /Title 100 0 R /A 97 0 R /Parent 67 0 R /Prev 95 0 R >> endobj 95 0 obj << /Title 96 0 R /A 93 0 R /Parent 67 0 R /Prev 91 0 R /Next 99 0 R >> endobj 91 0 obj << /Title 92 0 R /A 89 0 R /Parent 67 0 R /Prev 87 0 R /Next 95 0 R >> endobj 87 0 obj << /Title 88 0 R /A 85 0 R /Parent 67 0 R /Prev 83 0 R /Next 91 0 R >> endobj 83 0 obj << /Title 84 0 R /A 81 0 R /Parent 67 0 R /Prev 79 0 R /Next 87 0 R >> endobj 79 0 obj << /Title 80 0 R /A 77 0 R /Parent 67 0 R /Prev 75 0 R /Next 83 0 R >> endobj 75 0 obj << /Title 76 0 R /A 73 0 R /Parent 67 0 R /Prev 71 0 R /Next 79 0 R >> endobj 71 0 obj << /Title 72 0 R /A 69 0 R /Parent 67 0 R /Next 75 0 R >> endobj 67 0 obj << /Title 68 0 R /A 65 0 R /Parent 55 0 R /Prev 63 0 R /Next 103 0 R /First 71 0 R /Last 99 0 R /Count -8 >> endobj 63 0 obj << /Title 64 0 R /A 61 0 R /Parent 55 0 R /Prev 59 0 R /Next 67 0 R >> endobj 59 0 obj << /Title 60 0 R /A 57 0 R /Parent 55 0 R /Next 63 0 R >> endobj 55 0 obj << /Title 56 0 R /A 53 0 R /Parent 4972 0 R /Prev 15 0 R /Next 135 0 R /First 59 0 R /Last 119 0 R /Count -8 >> endobj 51 0 obj << /Title 52 0 R /A 49 0 R /Parent 27 0 R /Prev 47 0 R >> endobj 47 0 obj << /Title 48 0 R /A 45 0 R /Parent 27 0 R /Prev 43 0 R /Next 51 0 R >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R /Parent 27 0 R /Prev 39 0 R /Next 47 0 R >> endobj 39 0 obj << /Title 40 0 R /A 37 0 R /Parent 27 0 R /Prev 35 0 R /Next 43 0 R >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 27 0 R /Prev 31 0 R /Next 39 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 23 0 R /First 31 0 R /Last 51 0 R /Count -6 >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 15 0 R /Prev 19 0 R /First 27 0 R /Last 27 0 R /Count -1 >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 4972 0 R /Prev 3 0 R /Next 55 0 R /First 19 0 R /Last 23 0 R /Count -2 >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 3 0 R /Prev 7 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 4972 0 R /Next 15 0 R /First 7 0 R /Last 11 0 R /Count -2 >> endobj 4973 0 obj << /Names [(Doc-Start) 1831 0 R (Hfootnote.1) 2363 0 R (Hfootnote.10) 3140 0 R (Hfootnote.11) 3182 0 R (Hfootnote.12) 3196 0 R (Hfootnote.13) 3671 0 R] /Limits [(Doc-Start) (Hfootnote.13)] >> endobj 4974 0 obj << /Names [(Hfootnote.2) 2364 0 R (Hfootnote.3) 2365 0 R (Hfootnote.4) 2429 0 R (Hfootnote.5) 2430 0 R (Hfootnote.6) 2452 0 R (Hfootnote.7) 2549 0 R] /Limits [(Hfootnote.2) (Hfootnote.7)] >> endobj 4975 0 obj << /Names [(Hfootnote.8) 2870 0 R (Hfootnote.9) 2885 0 R (Item.1) 2442 0 R (Item.10) 2533 0 R (Item.100) 3031 0 R (Item.101) 3032 0 R] /Limits [(Hfootnote.8) (Item.101)] >> endobj 4976 0 obj << /Names [(Item.102) 3033 0 R (Item.103) 3034 0 R (Item.104) 3035 0 R (Item.105) 3072 0 R (Item.106) 3073 0 R (Item.107) 3074 0 R] /Limits [(Item.102) (Item.107)] >> endobj 4977 0 obj << /Names [(Item.108) 3075 0 R (Item.109) 3076 0 R (Item.11) 2534 0 R (Item.110) 3077 0 R (Item.111) 3109 0 R (Item.112) 3151 0 R] /Limits [(Item.108) (Item.112)] >> endobj 4978 0 obj << /Names [(Item.113) 3152 0 R (Item.114) 3153 0 R (Item.115) 3154 0 R (Item.116) 3155 0 R (Item.117) 3167 0 R (Item.118) 3168 0 R] /Limits [(Item.113) (Item.118)] >> endobj 4979 0 obj << /Names [(Item.119) 3169 0 R (Item.12) 2535 0 R (Item.120) 3170 0 R (Item.121) 3248 0 R (Item.122) 3249 0 R (Item.123) 3250 0 R] /Limits [(Item.119) (Item.123)] >> endobj 4980 0 obj << /Names [(Item.124) 3251 0 R (Item.125) 3252 0 R (Item.126) 3253 0 R (Item.127) 3254 0 R (Item.128) 3255 0 R (Item.129) 3256 0 R] /Limits [(Item.124) (Item.129)] >> endobj 4981 0 obj << /Names [(Item.13) 2536 0 R (Item.130) 3257 0 R (Item.131) 3258 0 R (Item.132) 3259 0 R (Item.133) 3269 0 R (Item.134) 3270 0 R] /Limits [(Item.13) (Item.134)] >> endobj 4982 0 obj << /Names [(Item.135) 3324 0 R (Item.136) 3325 0 R (Item.137) 3326 0 R (Item.138) 3343 0 R (Item.139) 3344 0 R (Item.14) 2537 0 R] /Limits [(Item.135) (Item.14)] >> endobj 4983 0 obj << /Names [(Item.140) 3345 0 R (Item.141) 3372 0 R (Item.142) 3373 0 R (Item.143) 3374 0 R (Item.144) 3375 0 R (Item.145) 3376 0 R] /Limits [(Item.140) (Item.145)] >> endobj 4984 0 obj << /Names [(Item.146) 3403 0 R (Item.147) 3404 0 R (Item.148) 3405 0 R (Item.149) 3406 0 R (Item.15) 2538 0 R (Item.150) 3418 0 R] /Limits [(Item.146) (Item.150)] >> endobj 4985 0 obj << /Names [(Item.151) 3419 0 R (Item.152) 3420 0 R (Item.153) 3465 0 R (Item.154) 3466 0 R (Item.155) 3467 0 R (Item.156) 3468 0 R] /Limits [(Item.151) (Item.156)] >> endobj 4986 0 obj << /Names [(Item.157) 3475 0 R (Item.158) 3476 0 R (Item.159) 3482 0 R (Item.16) 2539 0 R (Item.160) 3483 0 R (Item.161) 3484 0 R] /Limits [(Item.157) (Item.161)] >> endobj 4987 0 obj << /Names [(Item.162) 3499 0 R (Item.163) 3500 0 R (Item.164) 3501 0 R (Item.165) 3502 0 R (Item.166) 3503 0 R (Item.167) 3513 0 R] /Limits [(Item.162) (Item.167)] >> endobj 4988 0 obj << /Names [(Item.168) 3514 0 R (Item.169) 3533 0 R (Item.17) 2540 0 R (Item.170) 3539 0 R (Item.171) 3545 0 R (Item.172) 3546 0 R] /Limits [(Item.168) (Item.172)] >> endobj 4989 0 obj << /Names [(Item.173) 3547 0 R (Item.174) 3548 0 R (Item.175) 3606 0 R (Item.176) 3607 0 R (Item.177) 3608 0 R (Item.178) 3625 0 R] /Limits [(Item.173) (Item.178)] >> endobj 4990 0 obj << /Names [(Item.179) 3626 0 R (Item.18) 2541 0 R (Item.180) 3627 0 R (Item.181) 3633 0 R (Item.182) 3634 0 R (Item.183) 3648 0 R] /Limits [(Item.179) (Item.183)] >> endobj 4991 0 obj << /Names [(Item.184) 3649 0 R (Item.185) 3650 0 R (Item.186) 3652 0 R (Item.187) 3653 0 R (Item.188) 3719 0 R (Item.189) 3720 0 R] /Limits [(Item.184) (Item.189)] >> endobj 4992 0 obj << /Names [(Item.19) 2542 0 R (Item.190) 3721 0 R (Item.191) 3722 0 R (Item.192) 3917 0 R (Item.193) 3918 0 R (Item.2) 2443 0 R] /Limits [(Item.19) (Item.2)] >> endobj 4993 0 obj << /Names [(Item.20) 2543 0 R (Item.21) 2544 0 R (Item.22) 2545 0 R (Item.23) 2546 0 R (Item.24) 2547 0 R (Item.25) 2548 0 R] /Limits [(Item.20) (Item.25)] >> endobj 4994 0 obj << /Names [(Item.26) 2555 0 R (Item.27) 2556 0 R (Item.28) 2557 0 R (Item.29) 2558 0 R (Item.3) 2444 0 R (Item.30) 2565 0 R] /Limits [(Item.26) (Item.30)] >> endobj 4995 0 obj << /Names [(Item.31) 2566 0 R (Item.32) 2571 0 R (Item.33) 2572 0 R (Item.34) 2573 0 R (Item.35) 2574 0 R (Item.36) 2665 0 R] /Limits [(Item.31) (Item.36)] >> endobj 4996 0 obj << /Names [(Item.37) 2666 0 R (Item.38) 2676 0 R (Item.39) 2677 0 R (Item.4) 2460 0 R (Item.40) 2725 0 R (Item.41) 2726 0 R] /Limits [(Item.37) (Item.41)] >> endobj 4997 0 obj << /Names [(Item.42) 2727 0 R (Item.43) 2728 0 R (Item.44) 2756 0 R (Item.45) 2757 0 R (Item.46) 2758 0 R (Item.47) 2759 0 R] /Limits [(Item.42) (Item.47)] >> endobj 4998 0 obj << /Names [(Item.48) 2773 0 R (Item.49) 2774 0 R (Item.5) 2461 0 R (Item.50) 2775 0 R (Item.51) 2776 0 R (Item.52) 2777 0 R] /Limits [(Item.48) (Item.52)] >> endobj 4999 0 obj << /Names [(Item.53) 2778 0 R (Item.54) 2779 0 R (Item.55) 2806 0 R (Item.56) 2807 0 R (Item.57) 2819 0 R (Item.58) 2820 0 R] /Limits [(Item.53) (Item.58)] >> endobj 5000 0 obj << /Names [(Item.59) 2821 0 R (Item.6) 2515 0 R (Item.60) 2822 0 R (Item.61) 2864 0 R (Item.62) 2865 0 R (Item.63) 2866 0 R] /Limits [(Item.59) (Item.63)] >> endobj 5001 0 obj << /Names [(Item.64) 2867 0 R (Item.65) 2868 0 R (Item.66) 2869 0 R (Item.67) 2876 0 R (Item.68) 2877 0 R (Item.69) 2878 0 R] /Limits [(Item.64) (Item.69)] >> endobj 5002 0 obj << /Names [(Item.7) 2516 0 R (Item.70) 2879 0 R (Item.71) 2912 0 R (Item.72) 2913 0 R (Item.73) 2914 0 R (Item.74) 2915 0 R] /Limits [(Item.7) (Item.74)] >> endobj 5003 0 obj << /Names [(Item.75) 2942 0 R (Item.76) 2943 0 R (Item.77) 2944 0 R (Item.78) 2953 0 R (Item.79) 2954 0 R (Item.8) 2517 0 R] /Limits [(Item.75) (Item.8)] >> endobj 5004 0 obj << /Names [(Item.80) 2956 0 R (Item.81) 2957 0 R (Item.82) 2958 0 R (Item.83) 2959 0 R (Item.84) 2960 0 R (Item.85) 2992 0 R] /Limits [(Item.80) (Item.85)] >> endobj 5005 0 obj << /Names [(Item.86) 2993 0 R (Item.87) 2994 0 R (Item.88) 3004 0 R (Item.89) 3005 0 R (Item.9) 2518 0 R (Item.90) 3006 0 R] /Limits [(Item.86) (Item.90)] >> endobj 5006 0 obj << /Names [(Item.91) 3013 0 R (Item.92) 3014 0 R (Item.93) 3015 0 R (Item.94) 3016 0 R (Item.95) 3017 0 R (Item.96) 3023 0 R] /Limits [(Item.91) (Item.96)] >> endobj 5007 0 obj << /Names [(Item.97) 3024 0 R (Item.98) 3025 0 R (Item.99) 3026 0 R (appendix*.14) 3939 0 R (appendix*.15) 3960 0 R (appendix.A) 1234 0 R] /Limits [(Item.97) (appendix.A)] >> endobj 5008 0 obj << /Names [(appendix.B) 1650 0 R (appendix.C) 1718 0 R (appendix.D) 1762 0 R (appendix.E) 1806 0 R (appendix.F) 1814 0 R (chapter*.1) 1878 0 R] /Limits [(appendix.B) (chapter*.1)] >> endobj 5009 0 obj << /Names [(chapter.1) 2 0 R (chapter.2) 14 0 R (chapter.3) 54 0 R (chapter.4) 134 0 R (chapter.5) 338 0 R (chapter.6) 442 0 R] /Limits [(chapter.1) (chapter.6)] >> endobj 5010 0 obj << /Names [(chapter.7) 1058 0 R (cite.ATK-Tutorial) 2710 0 R (cite.ATK-doc) 2709 0 R (cite.Alba_WEB) 2368 0 R (cite.Astor_doc) 3408 0 R (cite.CORBA_norm) 3962 0 R] /Limits [(chapter.7) (cite.CORBA_norm)] >> endobj 5011 0 obj << /Names [(cite.CVS) 3964 0 R (cite.Elettra_home_page) 2367 0 R (cite.Henning) 2417 0 R (cite.JacORB) 3965 0 R (cite.Java\040memory\040leak) 3963 0 R (cite.Jive\040doc) 3407 0 R] /Limits [(cite.CVS) (cite.Jive\040doc)] >> endobj 5012 0 obj << /Names [(cite.MySQL\040book) 2454 0 R (cite.Notif_doc) 2560 0 R (cite.OMG-page) 2416 0 R (cite.OOC\040page) 3284 0 R (cite.Patterns) 2841 0 R (cite.Pogo\040doc) 2380 0 R] /Limits [(cite.MySQL\040book) (cite.Pogo\040doc)] >> endobj 5013 0 obj << /Names [(cite.Soleil_home_page) 2366 0 R (cite.Stroustrup) 3961 0 R (cite.TANGO_ref_man) 2840 0 R (cite.Tango\040web) 2418 0 R (cite.Tango-dsclasses-doc) 3441 0 R (cite.ZMQ) 2369 0 R] /Limits [(cite.Soleil_home_page) (cite.ZMQ)] >> endobj 5014 0 obj << /Names [(cite.mysql) 2453 0 R (figure.caption.10) 3327 0 R (figure.caption.11) 3346 0 R (figure.caption.12) 3362 0 R (figure.caption.2) 2664 0 R (figure.caption.3) 2842 0 R] /Limits [(cite.mysql) (figure.caption.3)] >> endobj 5015 0 obj << /Names [(figure.caption.4) 2916 0 R (figure.caption.5) 2917 0 R (figure.caption.6) 2955 0 R (figure.caption.7) 2971 0 R (figure.caption.8) 2991 0 R (figure.caption.9) 3217 0 R] /Limits [(figure.caption.4) (figure.caption.9)] >> endobj 5016 0 obj << /Names [(lstlisting.7.-1) 3436 0 R (lstnumber.-1.1) 3437 0 R (lstnumber.-1.10) 3453 0 R (lstnumber.-1.11) 3454 0 R (lstnumber.-1.12) 3455 0 R (lstnumber.-1.13) 3456 0 R] /Limits [(lstlisting.7.-1) (lstnumber.-1.13)] >> endobj 5017 0 obj << /Names [(lstnumber.-1.14) 3457 0 R (lstnumber.-1.15) 3458 0 R (lstnumber.-1.16) 3459 0 R (lstnumber.-1.17) 3460 0 R (lstnumber.-1.2) 3439 0 R (lstnumber.-1.3) 3440 0 R] /Limits [(lstnumber.-1.14) (lstnumber.-1.3)] >> endobj 5018 0 obj << /Names [(lstnumber.-1.4) 3447 0 R (lstnumber.-1.5) 3448 0 R (lstnumber.-1.6) 3449 0 R (lstnumber.-1.7) 3450 0 R (lstnumber.-1.8) 3451 0 R (lstnumber.-1.9) 3452 0 R] /Limits [(lstnumber.-1.4) (lstnumber.-1.9)] >> endobj 5019 0 obj << /Names [(page.1) 1830 0 R (page.10) 2337 0 R (page.100) 2952 0 R (page.101) 2970 0 R (page.102) 2983 0 R (page.103) 2990 0 R] /Limits [(page.1) (page.103)] >> endobj 5020 0 obj << /Names [(page.104) 3003 0 R (page.105) 3012 0 R (page.106) 3022 0 R (page.107) 3030 0 R (page.108) 3039 0 R (page.109) 3044 0 R] /Limits [(page.104) (page.109)] >> endobj 5021 0 obj << /Names [(page.11) 2341 0 R (page.110) 3048 0 R (page.111) 3052 0 R (page.112) 3056 0 R (page.113) 3060 0 R (page.114) 3065 0 R] /Limits [(page.11) (page.114)] >> endobj 5022 0 obj << /Names [(page.115) 3071 0 R (page.116) 3083 0 R (page.117) 3088 0 R (page.118) 3092 0 R (page.119) 3096 0 R (page.12) 2355 0 R] /Limits [(page.115) (page.12)] >> endobj 5023 0 obj << /Names [(page.120) 3101 0 R (page.121) 3108 0 R (page.122) 3114 0 R (page.123) 3120 0 R (page.124) 3125 0 R (page.125) 3129 0 R] /Limits [(page.120) (page.125)] >> endobj 5024 0 obj << /Names [(page.126) 3134 0 R (page.127) 3139 0 R (page.128) 3145 0 R (page.129) 3150 0 R (page.13) 2362 0 R (page.130) 3159 0 R] /Limits [(page.126) (page.130)] >> endobj 5025 0 obj << /Names [(page.131) 3166 0 R (page.132) 3174 0 R (page.133) 3181 0 R (page.134) 3186 0 R (page.135) 3191 0 R (page.136) 3195 0 R] /Limits [(page.131) (page.136)] >> endobj 5026 0 obj << /Names [(page.137) 3201 0 R (page.138) 3205 0 R (page.139) 3210 0 R (page.14) 2373 0 R (page.140) 3216 0 R (page.141) 3227 0 R] /Limits [(page.137) (page.141)] >> endobj 5027 0 obj << /Names [(page.142) 3237 0 R (page.143) 3241 0 R (page.144) 3247 0 R (page.145) 3264 0 R (page.146) 3268 0 R (page.147) 3274 0 R] /Limits [(page.142) (page.147)] >> endobj 5028 0 obj << /Names [(page.148) 3278 0 R (page.149) 3283 0 R (page.15) 2379 0 R (page.150) 3288 0 R (page.151) 3294 0 R (page.152) 3298 0 R] /Limits [(page.148) (page.152)] >> endobj 5029 0 obj << /Names [(page.153) 3303 0 R (page.154) 3308 0 R (page.155) 3312 0 R (page.156) 3316 0 R (page.157) 3323 0 R (page.158) 3336 0 R] /Limits [(page.153) (page.158)] >> endobj 5030 0 obj << /Names [(page.159) 3342 0 R (page.16) 2385 0 R (page.160) 3356 0 R (page.161) 3361 0 R (page.162) 3371 0 R (page.163) 3381 0 R] /Limits [(page.159) (page.163)] >> endobj 5031 0 obj << /Names [(page.164) 3385 0 R (page.165) 3389 0 R (page.166) 3393 0 R (page.167) 3402 0 R (page.168) 3412 0 R (page.169) 3417 0 R] /Limits [(page.164) (page.169)] >> endobj 5032 0 obj << /Names [(page.17) 2390 0 R (page.170) 3426 0 R (page.171) 3430 0 R (page.172) 3435 0 R (page.173) 3446 0 R (page.174) 3464 0 R] /Limits [(page.17) (page.174)] >> endobj 5033 0 obj << /Names [(page.175) 3474 0 R (page.176) 3481 0 R (page.177) 3488 0 R (page.178) 3493 0 R (page.179) 3498 0 R (page.18) 2394 0 R] /Limits [(page.175) (page.18)] >> endobj 5034 0 obj << /Names [(page.180) 3507 0 R (page.181) 3512 0 R (page.182) 3518 0 R (page.183) 3522 0 R (page.184) 3526 0 R (page.185) 3532 0 R] /Limits [(page.180) (page.185)] >> endobj 5035 0 obj << /Names [(page.186) 3538 0 R (page.187) 3544 0 R (page.188) 3554 0 R (page.189) 3558 0 R (page.19) 2399 0 R (page.190) 3564 0 R] /Limits [(page.186) (page.190)] >> endobj 5036 0 obj << /Names [(page.191) 3570 0 R (page.192) 3574 0 R (page.193) 3582 0 R (page.194) 3587 0 R (page.195) 3592 0 R (page.196) 3598 0 R] /Limits [(page.191) (page.196)] >> endobj 5037 0 obj << /Names [(page.197) 3605 0 R (page.198) 3613 0 R (page.199) 3619 0 R (page.2) 1936 0 R (page.20) 2403 0 R (page.200) 3624 0 R] /Limits [(page.197) (page.200)] >> endobj 5038 0 obj << /Names [(page.201) 3632 0 R (page.202) 3640 0 R (page.203) 3646 0 R (page.204) 3657 0 R (page.205) 3664 0 R (page.206) 3670 0 R] /Limits [(page.201) (page.206)] >> endobj 5039 0 obj << /Names [(page.207) 3675 0 R (page.208) 3680 0 R (page.209) 3686 0 R (page.21) 2408 0 R (page.210) 3693 0 R (page.211) 3701 0 R] /Limits [(page.207) (page.211)] >> endobj 5040 0 obj << /Names [(page.212) 3708 0 R (page.213) 3712 0 R (page.214) 3718 0 R (page.215) 3726 0 R (page.216) 3732 0 R (page.217) 3740 0 R] /Limits [(page.212) (page.217)] >> endobj 5041 0 obj << /Names [(page.218) 3746 0 R (page.219) 3752 0 R (page.22) 2415 0 R (page.220) 3756 0 R (page.221) 3760 0 R (page.222) 3764 0 R] /Limits [(page.218) (page.222)] >> endobj 5042 0 obj << /Names [(page.223) 3769 0 R (page.224) 3773 0 R (page.225) 3777 0 R (page.226) 3781 0 R (page.227) 3785 0 R (page.228) 3789 0 R] /Limits [(page.223) (page.228)] >> endobj 5043 0 obj << /Names [(page.229) 3794 0 R (page.23) 2423 0 R (page.230) 3798 0 R (page.231) 3802 0 R (page.232) 3806 0 R (page.233) 3810 0 R] /Limits [(page.229) (page.233)] >> endobj 5044 0 obj << /Names [(page.234) 3814 0 R (page.235) 3819 0 R (page.236) 3823 0 R (page.237) 3827 0 R (page.238) 3831 0 R (page.239) 3835 0 R] /Limits [(page.234) (page.239)] >> endobj 5045 0 obj << /Names [(page.24) 2428 0 R (page.240) 3839 0 R (page.241) 3844 0 R (page.242) 3848 0 R (page.243) 3852 0 R (page.244) 3856 0 R] /Limits [(page.24) (page.244)] >> endobj 5046 0 obj << /Names [(page.245) 3860 0 R (page.246) 3864 0 R (page.247) 3869 0 R (page.248) 3873 0 R (page.249) 3877 0 R (page.25) 2437 0 R] /Limits [(page.245) (page.25)] >> endobj 5047 0 obj << /Names [(page.250) 3881 0 R (page.251) 3885 0 R (page.252) 3889 0 R (page.253) 3898 0 R (page.254) 3903 0 R (page.255) 3907 0 R] /Limits [(page.250) (page.255)] >> endobj 5048 0 obj << /Names [(page.256) 3911 0 R (page.257) 3916 0 R (page.258) 3922 0 R (page.259) 3927 0 R (page.26) 2441 0 R (page.260) 3938 0 R] /Limits [(page.256) (page.260)] >> endobj 5049 0 obj << /Names [(page.261) 3959 0 R (page.262) 4176 0 R (page.263) 4408 0 R (page.264) 4607 0 R (page.265) 4837 0 R (page.266) 4935 0 R] /Limits [(page.261) (page.266)] >> endobj 5050 0 obj << /Names [(page.27) 2451 0 R (page.28) 2459 0 R (page.29) 2472 0 R (page.3) 1994 0 R (page.30) 2478 0 R (page.31) 2493 0 R] /Limits [(page.27) (page.31)] >> endobj 5051 0 obj << /Names [(page.32) 2503 0 R (page.33) 2508 0 R (page.34) 2513 0 R (page.35) 2522 0 R (page.36) 2526 0 R (page.37) 2532 0 R] /Limits [(page.32) (page.37)] >> endobj 5052 0 obj << /Names [(page.38) 2554 0 R (page.39) 2564 0 R (page.4) 2052 0 R (page.40) 2570 0 R (page.41) 2578 0 R (page.42) 2582 0 R] /Limits [(page.38) (page.42)] >> endobj 5053 0 obj << /Names [(page.43) 2587 0 R (page.44) 2591 0 R (page.45) 2595 0 R (page.46) 2599 0 R (page.47) 2603 0 R (page.48) 2607 0 R] /Limits [(page.43) (page.48)] >> endobj 5054 0 obj << /Names [(page.49) 2612 0 R (page.5) 2110 0 R (page.50) 2616 0 R (page.51) 2620 0 R (page.52) 2624 0 R (page.53) 2628 0 R] /Limits [(page.49) (page.53)] >> endobj 5055 0 obj << /Names [(page.54) 2632 0 R (page.55) 2637 0 R (page.56) 2641 0 R (page.57) 2645 0 R (page.58) 2649 0 R (page.59) 2653 0 R] /Limits [(page.54) (page.59)] >> endobj 5056 0 obj << /Names [(page.6) 2167 0 R (page.60) 2658 0 R (page.61) 2663 0 R (page.62) 2675 0 R (page.63) 2681 0 R (page.64) 2685 0 R] /Limits [(page.6) (page.64)] >> endobj 5057 0 obj << /Names [(page.65) 2689 0 R (page.66) 2695 0 R (page.67) 2700 0 R (page.68) 2708 0 R (page.69) 2714 0 R (page.7) 2224 0 R] /Limits [(page.65) (page.7)] >> endobj 5058 0 obj << /Names [(page.70) 2724 0 R (page.71) 2737 0 R (page.72) 2741 0 R (page.73) 2746 0 R (page.74) 2751 0 R (page.75) 2755 0 R] /Limits [(page.70) (page.75)] >> endobj 5059 0 obj << /Names [(page.76) 2763 0 R (page.77) 2767 0 R (page.78) 2772 0 R (page.79) 2784 0 R (page.8) 2282 0 R (page.80) 2788 0 R] /Limits [(page.76) (page.80)] >> endobj 5060 0 obj << /Names [(page.81) 2793 0 R (page.82) 2797 0 R (page.83) 2801 0 R (page.84) 2805 0 R (page.85) 2813 0 R (page.86) 2818 0 R] /Limits [(page.81) (page.86)] >> endobj 5061 0 obj << /Names [(page.87) 2826 0 R (page.88) 2838 0 R (page.89) 2846 0 R (page.9) 2331 0 R (page.90) 2863 0 R (page.91) 2875 0 R] /Limits [(page.87) (page.91)] >> endobj 5062 0 obj << /Names [(page.92) 2884 0 R (page.93) 2889 0 R (page.94) 2893 0 R (page.95) 2898 0 R (page.96) 2902 0 R (page.97) 2911 0 R] /Limits [(page.92) (page.97)] >> endobj 5063 0 obj << /Names [(page.98) 2921 0 R (page.99) 2941 0 R (paragraph.4.6.5.1.1) 194 0 R (paragraph.4.6.5.1.2) 198 0 R (paragraph.4.6.5.1.3) 202 0 R (paragraph.4.6.5.2.1) 210 0 R] /Limits [(page.98) (paragraph.4.6.5.2.1)] >> endobj 5064 0 obj << /Names [(paragraph.4.6.5.2.2) 214 0 R (paragraph.4.6.5.2.3) 218 0 R (paragraph.4.6.5.2.4) 222 0 R (paragraph.4.6.5.2.5) 226 0 R (paragraph.6.1.2.1.1) 462 0 R (paragraph.6.1.2.1.2) 466 0 R] /Limits [(paragraph.4.6.5.2.2) (paragraph.6.1.2.1.2)] >> endobj 5065 0 obj << /Names [(paragraph.6.1.2.12.1) 558 0 R (paragraph.6.1.2.12.2) 562 0 R (paragraph.6.1.2.13.1) 570 0 R (paragraph.6.1.2.13.2) 574 0 R (paragraph.6.1.2.14.1) 582 0 R (paragraph.6.1.2.14.2) 586 0 R] /Limits [(paragraph.6.1.2.12.1) (paragraph.6.1.2.14.2)] >> endobj 5066 0 obj << /Names [(paragraph.6.1.2.15.1) 594 0 R (paragraph.6.1.2.15.2) 598 0 R (paragraph.6.1.2.3.1) 478 0 R (paragraph.6.1.2.3.2) 482 0 R (paragraph.6.1.2.3.3) 486 0 R (paragraph.6.1.2.4.1) 494 0 R] /Limits [(paragraph.6.1.2.15.1) (paragraph.6.1.2.4.1)] >> endobj 5067 0 obj << /Names [(paragraph.6.1.2.4.2) 498 0 R (paragraph.6.1.2.6.1) 510 0 R (paragraph.6.1.2.6.2) 514 0 R (paragraph.6.1.2.7.1) 522 0 R (paragraph.6.1.2.7.2) 526 0 R (paragraph.6.1.2.8.1) 534 0 R] /Limits [(paragraph.6.1.2.4.2) (paragraph.6.1.2.8.1)] >> endobj 5068 0 obj << /Names [(paragraph.6.1.2.8.2) 538 0 R (paragraph.6.1.7.3.1) 642 0 R (paragraph.6.1.7.3.2) 646 0 R (paragraph.6.2.1.1.1) 670 0 R (paragraph.6.2.1.1.2) 674 0 R (paragraph.6.2.1.1.3) 678 0 R] /Limits [(paragraph.6.1.2.8.2) (paragraph.6.2.1.1.3)] >> endobj 5069 0 obj << /Names [(paragraph.6.2.1.1.4) 682 0 R (paragraph.6.2.1.1.5) 686 0 R (paragraph.6.2.2.1.1) 698 0 R (paragraph.6.2.2.1.2) 702 0 R (paragraph.6.2.2.1.3) 706 0 R (paragraph.6.2.2.1.4) 710 0 R] /Limits [(paragraph.6.2.1.1.4) (paragraph.6.2.2.1.4)] >> endobj 5070 0 obj << /Names [(paragraph.6.2.2.1.5) 714 0 R (paragraph.6.6.1.1.1) 986 0 R (paragraph.6.6.1.1.2) 990 0 R (paragraph.6.6.1.1.3) 994 0 R (paragraph.A.2.2.1.1) 1306 0 R (paragraph.A.2.2.1.2) 1310 0 R] /Limits [(paragraph.6.2.2.1.5) (paragraph.A.2.2.1.2)] >> endobj 5071 0 obj << /Names [(paragraph.A.2.2.1.3) 1314 0 R (paragraph.A.2.2.2.1) 1322 0 R (paragraph.A.2.2.2.2) 1326 0 R (paragraph.A.2.2.2.3) 1330 0 R (paragraph.A.2.2.3.1) 1338 0 R (paragraph.A.2.2.3.2) 1342 0 R] /Limits [(paragraph.A.2.2.1.3) (paragraph.A.2.2.3.2)] >> endobj 5072 0 obj << /Names [(paragraph.A.2.2.3.3) 1346 0 R (section*.13) 3733 0 R (section.1.1) 6 0 R (section.1.2) 10 0 R (section.2.1) 18 0 R (section.2.2) 22 0 R] /Limits [(paragraph.A.2.2.3.3) (section.2.2)] >> endobj 5073 0 obj << /Names [(section.3.1) 58 0 R (section.3.2) 62 0 R (section.3.3) 66 0 R (section.3.4) 102 0 R (section.3.5) 106 0 R (section.3.6) 110 0 R] /Limits [(section.3.1) (section.3.6)] >> endobj 5074 0 obj << /Names [(section.3.7) 114 0 R (section.3.8) 118 0 R (section.4.1) 138 0 R (section.4.10) 326 0 R (section.4.11) 330 0 R (section.4.12) 334 0 R] /Limits [(section.3.7) (section.4.12)] >> endobj 5075 0 obj << /Names [(section.4.2) 142 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 154 0 R (section.4.6) 166 0 R (section.4.7) 230 0 R] /Limits [(section.4.2) (section.4.7)] >> endobj 5076 0 obj << /Names [(section.4.8) 294 0 R (section.4.9) 322 0 R (section.5.1) 342 0 R (section.5.2) 350 0 R (section.5.3) 370 0 R (section.5.4) 402 0 R] /Limits [(section.4.8) (section.5.4)] >> endobj 5077 0 obj << /Names [(section.6.1) 446 0 R (section.6.2) 658 0 R (section.6.3) 750 0 R (section.6.4) 774 0 R (section.6.5) 914 0 R (section.6.6) 974 0 R] /Limits [(section.6.1) (section.6.6)] >> endobj 5078 0 obj << /Names [(section.6.7) 1006 0 R (section.7.1) 1062 0 R (section.7.10) 1198 0 R (section.7.11) 1202 0 R (section.7.12) 1206 0 R (section.7.13) 1218 0 R] /Limits [(section.6.7) (section.7.13)] >> endobj 5079 0 obj << /Names [(section.7.14) 1222 0 R (section.7.2) 1074 0 R (section.7.3) 1098 0 R (section.7.4) 1142 0 R (section.7.5) 1162 0 R (section.7.6) 1166 0 R] /Limits [(section.7.14) (section.7.6)] >> endobj 5080 0 obj << /Names [(section.7.7) 1178 0 R (section.7.8) 1182 0 R (section.7.9) 1194 0 R (section.A.1) 1238 0 R (section.A.10) 1554 0 R (section.A.11) 1582 0 R] /Limits [(section.7.7) (section.A.11)] >> endobj 5081 0 obj << /Names [(section.A.12) 1614 0 R (section.A.2) 1262 0 R (section.A.3) 1358 0 R (section.A.4) 1386 0 R (section.A.5) 1390 0 R (section.A.6) 1394 0 R] /Limits [(section.A.12) (section.A.6)] >> endobj 5082 0 obj << /Names [(section.A.7) 1410 0 R (section.A.8) 1538 0 R (section.A.9) 1542 0 R (section.B.1) 1654 0 R (section.B.10) 1710 0 R (section.B.2) 1658 0 R] /Limits [(section.A.7) (section.B.2)] >> endobj 5083 0 obj << /Names [(section.B.3) 1662 0 R (section.B.4) 1666 0 R (section.B.5) 1670 0 R (section.B.6) 1674 0 R (section.B.7) 1686 0 R (section.B.8) 1694 0 R] /Limits [(section.B.3) (section.B.8)] >> endobj 5084 0 obj << /Names [(section.B.9) 1702 0 R (section.C.1) 1722 0 R (section.C.2) 1726 0 R (section.C.3) 1754 0 R (section.C.4) 1758 0 R (section.D.1) 1766 0 R] /Limits [(section.B.9) (section.D.1)] >> endobj 5085 0 obj << /Names [(section.D.2) 1770 0 R (section.D.3) 1774 0 R (section.D.4) 1786 0 R (section.D.5) 1790 0 R (section.D.6) 1802 0 R (section.E.1) 1810 0 R] /Limits [(section.D.2) (section.E.1)] >> endobj 5086 0 obj << /Names [(section.F.1) 1818 0 R (section.F.2) 1822 0 R (subfigure.6.1.1) 2847 0 R (subsection.2.2.1) 26 0 R (subsection.3.3.1) 70 0 R (subsection.3.3.2) 74 0 R] /Limits [(section.F.1) (subsection.3.3.2)] >> endobj 5087 0 obj << /Names [(subsection.3.3.3) 78 0 R (subsection.3.3.4) 82 0 R (subsection.3.3.5) 86 0 R (subsection.3.3.6) 90 0 R (subsection.3.3.7) 94 0 R (subsection.3.3.8) 98 0 R] /Limits [(subsection.3.3.3) (subsection.3.3.8)] >> endobj 5088 0 obj << /Names [(subsection.3.8.1) 122 0 R (subsection.3.8.2) 126 0 R (subsection.3.8.3) 130 0 R (subsection.4.5.1) 158 0 R (subsection.4.5.2) 162 0 R (subsection.4.6.1) 170 0 R] /Limits [(subsection.3.8.1) (subsection.4.6.1)] >> endobj 5089 0 obj << /Names [(subsection.4.6.2) 174 0 R (subsection.4.6.3) 178 0 R (subsection.4.6.4) 182 0 R (subsection.4.6.5) 186 0 R (subsection.4.7.1) 234 0 R (subsection.4.7.2) 238 0 R] /Limits [(subsection.4.6.2) (subsection.4.7.2)] >> endobj 5090 0 obj << /Names [(subsection.4.7.3) 242 0 R (subsection.4.7.4) 266 0 R (subsection.4.7.5) 278 0 R (subsection.4.8.1) 298 0 R (subsection.4.8.2) 314 0 R (subsection.5.1.1) 346 0 R] /Limits [(subsection.4.7.3) (subsection.5.1.1)] >> endobj 5091 0 obj << /Names [(subsection.5.2.1) 354 0 R (subsection.5.2.2) 358 0 R (subsection.5.2.3) 362 0 R (subsection.5.2.4) 366 0 R (subsection.5.3.1) 374 0 R (subsection.5.3.2) 378 0 R] /Limits [(subsection.5.2.1) (subsection.5.3.2)] >> endobj 5092 0 obj << /Names [(subsection.5.3.3) 382 0 R (subsection.5.3.4) 394 0 R (subsection.5.4.1) 406 0 R (subsection.5.4.2) 414 0 R (subsection.5.4.3) 418 0 R (subsection.5.4.4) 422 0 R] /Limits [(subsection.5.3.3) (subsection.5.4.4)] >> endobj 5093 0 obj << /Names [(subsection.5.4.5) 426 0 R (subsection.5.4.6) 434 0 R (subsection.6.1.1) 450 0 R (subsection.6.1.2) 454 0 R (subsection.6.1.3) 602 0 R (subsection.6.1.4) 606 0 R] /Limits [(subsection.5.4.5) (subsection.6.1.4)] >> endobj 5094 0 obj << /Names [(subsection.6.1.5) 610 0 R (subsection.6.1.6) 614 0 R (subsection.6.1.7) 626 0 R (subsection.6.2.1) 662 0 R (subsection.6.2.2) 690 0 R (subsection.6.2.3) 722 0 R] /Limits [(subsection.6.1.5) (subsection.6.2.3)] >> endobj 5095 0 obj << /Names [(subsection.6.2.4) 742 0 R (subsection.6.3.1) 754 0 R (subsection.6.3.2) 758 0 R (subsection.6.3.3) 762 0 R (subsection.6.4.1) 778 0 R (subsection.6.4.10) 862 0 R] /Limits [(subsection.6.2.4) (subsection.6.4.10)] >> endobj 5096 0 obj << /Names [(subsection.6.4.11) 882 0 R (subsection.6.4.2) 782 0 R (subsection.6.4.3) 790 0 R (subsection.6.4.4) 794 0 R (subsection.6.4.5) 806 0 R (subsection.6.4.6) 810 0 R] /Limits [(subsection.6.4.11) (subsection.6.4.6)] >> endobj 5097 0 obj << /Names [(subsection.6.4.7) 814 0 R (subsection.6.4.8) 818 0 R (subsection.6.4.9) 842 0 R (subsection.6.5.1) 918 0 R (subsection.6.5.2) 934 0 R (subsection.6.5.3) 950 0 R] /Limits [(subsection.6.4.7) (subsection.6.5.3)] >> endobj 5098 0 obj << /Names [(subsection.6.5.4) 954 0 R (subsection.6.6.1) 978 0 R (subsection.6.6.2) 1002 0 R (subsection.6.7.1) 1010 0 R (subsection.6.7.2) 1022 0 R (subsection.6.7.3) 1042 0 R] /Limits [(subsection.6.5.4) (subsection.6.7.3)] >> endobj 5099 0 obj << /Names [(subsection.6.7.4) 1046 0 R (subsection.7.1.1) 1066 0 R (subsection.7.1.2) 1070 0 R (subsection.7.12.1) 1210 0 R (subsection.7.12.2) 1214 0 R (subsection.7.14.1) 1226 0 R] /Limits [(subsection.6.7.4) (subsection.7.14.1)] >> endobj 5100 0 obj << /Names [(subsection.7.14.2) 1230 0 R (subsection.7.2.1) 1078 0 R (subsection.7.2.2) 1094 0 R (subsection.7.3.1) 1102 0 R (subsection.7.3.2) 1106 0 R (subsection.7.3.3) 1122 0 R] /Limits [(subsection.7.14.2) (subsection.7.3.3)] >> endobj 5101 0 obj << /Names [(subsection.7.3.4) 1126 0 R (subsection.7.3.5) 1130 0 R (subsection.7.3.6) 1134 0 R (subsection.7.3.7) 1138 0 R (subsection.7.4.1) 1146 0 R (subsection.7.4.2) 1158 0 R] /Limits [(subsection.7.3.4) (subsection.7.4.2)] >> endobj 5102 0 obj << /Names [(subsection.7.6.1) 1170 0 R (subsection.7.6.2) 1174 0 R (subsection.7.8.1) 1186 0 R (subsection.7.8.2) 1190 0 R (subsection.A.1.1) 1242 0 R (subsection.A.1.2) 1246 0 R] /Limits [(subsection.7.6.1) (subsection.A.1.2)] >> endobj 5103 0 obj << /Names [(subsection.A.1.3) 1250 0 R (subsection.A.1.4) 1254 0 R (subsection.A.1.5) 1258 0 R (subsection.A.10.1) 1558 0 R (subsection.A.10.2) 1562 0 R (subsection.A.10.3) 1566 0 R] /Limits [(subsection.A.1.3) (subsection.A.10.3)] >> endobj 5104 0 obj << /Names [(subsection.A.10.4) 1570 0 R (subsection.A.10.5) 1574 0 R (subsection.A.10.6) 1578 0 R (subsection.A.11.1) 1586 0 R (subsection.A.11.2) 1590 0 R (subsection.A.11.3) 1594 0 R] /Limits [(subsection.A.10.4) (subsection.A.11.3)] >> endobj 5105 0 obj << /Names [(subsection.A.11.4) 1602 0 R (subsection.A.11.5) 1606 0 R (subsection.A.11.6) 1610 0 R (subsection.A.12.1) 1618 0 R (subsection.A.12.2) 1622 0 R (subsection.A.12.3) 1626 0 R] /Limits [(subsection.A.11.4) (subsection.A.12.3)] >> endobj 5106 0 obj << /Names [(subsection.A.2.1) 1266 0 R (subsection.A.2.2) 1298 0 R (subsection.A.2.3) 1350 0 R (subsection.A.2.4) 1354 0 R (subsection.A.3.1) 1362 0 R (subsection.A.3.2) 1374 0 R] /Limits [(subsection.A.2.1) (subsection.A.3.2)] >> endobj 5107 0 obj << /Names [(subsection.A.3.3) 1378 0 R (subsection.A.3.4) 1382 0 R (subsection.A.6.1) 1398 0 R (subsection.A.6.2) 1402 0 R (subsection.A.6.3) 1406 0 R (subsection.A.7.1) 1414 0 R] /Limits [(subsection.A.3.3) (subsection.A.7.1)] >> endobj 5108 0 obj << /Names [(subsection.A.7.10) 1450 0 R (subsection.A.7.11) 1454 0 R (subsection.A.7.12) 1458 0 R (subsection.A.7.13) 1462 0 R (subsection.A.7.14) 1466 0 R (subsection.A.7.15) 1470 0 R] /Limits [(subsection.A.7.10) (subsection.A.7.15)] >> endobj 5109 0 obj << /Names [(subsection.A.7.16) 1474 0 R (subsection.A.7.17) 1478 0 R (subsection.A.7.18) 1482 0 R (subsection.A.7.19) 1486 0 R (subsection.A.7.2) 1418 0 R (subsection.A.7.20) 1490 0 R] /Limits [(subsection.A.7.16) (subsection.A.7.20)] >> endobj 5110 0 obj << /Names [(subsection.A.7.21) 1494 0 R (subsection.A.7.22) 1498 0 R (subsection.A.7.23) 1502 0 R (subsection.A.7.24) 1506 0 R (subsection.A.7.25) 1510 0 R (subsection.A.7.26) 1514 0 R] /Limits [(subsection.A.7.21) (subsection.A.7.26)] >> endobj 5111 0 obj << /Names [(subsection.A.7.27) 1518 0 R (subsection.A.7.28) 1522 0 R (subsection.A.7.29) 1526 0 R (subsection.A.7.3) 1422 0 R (subsection.A.7.30) 1530 0 R (subsection.A.7.31) 1534 0 R] /Limits [(subsection.A.7.27) (subsection.A.7.31)] >> endobj 5112 0 obj << /Names [(subsection.A.7.4) 1426 0 R (subsection.A.7.5) 1430 0 R (subsection.A.7.6) 1434 0 R (subsection.A.7.7) 1438 0 R (subsection.A.7.8) 1442 0 R (subsection.A.7.9) 1446 0 R] /Limits [(subsection.A.7.4) (subsection.A.7.9)] >> endobj 5113 0 obj << /Names [(subsection.A.9.1) 1546 0 R (subsection.A.9.2) 1550 0 R (subsection.B.10.1) 1714 0 R (subsection.B.6.1) 1678 0 R (subsection.B.6.2) 1682 0 R (subsection.B.7.1) 1690 0 R] /Limits [(subsection.A.9.1) (subsection.B.7.1)] >> endobj 5114 0 obj << /Names [(subsection.B.8.1) 1698 0 R (subsection.B.9.1) 1706 0 R (subsection.C.2.1) 1730 0 R (subsection.D.3.1) 1778 0 R (subsection.D.3.2) 1782 0 R (subsection.D.5.1) 1794 0 R] /Limits [(subsection.B.8.1) (subsection.D.5.1)] >> endobj 5115 0 obj << /Names [(subsection.D.5.2) 1798 0 R (subsubsection.2.2.1.1) 30 0 R (subsubsection.2.2.1.2) 34 0 R (subsubsection.2.2.1.3) 38 0 R (subsubsection.2.2.1.4) 42 0 R (subsubsection.2.2.1.5) 46 0 R] /Limits [(subsection.D.5.2) (subsubsection.2.2.1.5)] >> endobj 5116 0 obj << /Names [(subsubsection.2.2.1.6) 50 0 R (subsubsection.4.6.5.1) 190 0 R (subsubsection.4.6.5.2) 206 0 R (subsubsection.4.7.3.1) 246 0 R (subsubsection.4.7.3.2) 250 0 R (subsubsection.4.7.3.3) 254 0 R] /Limits [(subsubsection.2.2.1.6) (subsubsection.4.7.3.3)] >> endobj 5117 0 obj << /Names [(subsubsection.4.7.3.4) 258 0 R (subsubsection.4.7.3.5) 262 0 R (subsubsection.4.7.4.1) 270 0 R (subsubsection.4.7.4.2) 274 0 R (subsubsection.4.7.5.1) 282 0 R (subsubsection.4.7.5.2) 286 0 R] /Limits [(subsubsection.4.7.3.4) (subsubsection.4.7.5.2)] >> endobj 5118 0 obj << /Names [(subsubsection.4.7.5.3) 290 0 R (subsubsection.4.8.1.1) 302 0 R (subsubsection.4.8.1.2) 306 0 R (subsubsection.4.8.1.3) 310 0 R (subsubsection.4.8.2.1) 318 0 R (subsubsection.5.3.3.1) 386 0 R] /Limits [(subsubsection.4.7.5.3) (subsubsection.5.3.3.1)] >> endobj 5119 0 obj << /Names [(subsubsection.5.3.3.2) 390 0 R (subsubsection.5.3.4.1) 398 0 R (subsubsection.5.4.1.1) 410 0 R (subsubsection.5.4.5.1) 430 0 R (subsubsection.5.4.6.1) 438 0 R (subsubsection.6.1.2.1) 458 0 R] /Limits [(subsubsection.5.3.3.2) (subsubsection.6.1.2.1)] >> endobj 5120 0 obj << /Names [(subsubsection.6.1.2.10) 546 0 R (subsubsection.6.1.2.11) 550 0 R (subsubsection.6.1.2.12) 554 0 R (subsubsection.6.1.2.13) 566 0 R (subsubsection.6.1.2.14) 578 0 R (subsubsection.6.1.2.15) 590 0 R] /Limits [(subsubsection.6.1.2.10) (subsubsection.6.1.2.15)] >> endobj 5121 0 obj << /Names [(subsubsection.6.1.2.2) 470 0 R (subsubsection.6.1.2.3) 474 0 R (subsubsection.6.1.2.4) 490 0 R (subsubsection.6.1.2.5) 502 0 R (subsubsection.6.1.2.6) 506 0 R (subsubsection.6.1.2.7) 518 0 R] /Limits [(subsubsection.6.1.2.2) (subsubsection.6.1.2.7)] >> endobj 5122 0 obj << /Names [(subsubsection.6.1.2.8) 530 0 R (subsubsection.6.1.2.9) 542 0 R (subsubsection.6.1.6.1) 618 0 R (subsubsection.6.1.6.2) 622 0 R (subsubsection.6.1.7.1) 630 0 R (subsubsection.6.1.7.2) 634 0 R] /Limits [(subsubsection.6.1.2.8) (subsubsection.6.1.7.2)] >> endobj 5123 0 obj << /Names [(subsubsection.6.1.7.3) 638 0 R (subsubsection.6.1.7.4) 650 0 R (subsubsection.6.1.7.5) 654 0 R (subsubsection.6.2.1.1) 666 0 R (subsubsection.6.2.2.1) 694 0 R (subsubsection.6.2.2.2) 718 0 R] /Limits [(subsubsection.6.1.7.3) (subsubsection.6.2.2.2)] >> endobj 5124 0 obj << /Names [(subsubsection.6.2.3.1) 726 0 R (subsubsection.6.2.3.2) 730 0 R (subsubsection.6.2.3.3) 734 0 R (subsubsection.6.2.3.4) 738 0 R (subsubsection.6.2.4.1) 746 0 R (subsubsection.6.3.3.1) 766 0 R] /Limits [(subsubsection.6.2.3.1) (subsubsection.6.3.3.1)] >> endobj 5125 0 obj << /Names [(subsubsection.6.3.3.2) 770 0 R (subsubsection.6.4.10.1) 866 0 R (subsubsection.6.4.10.2) 870 0 R (subsubsection.6.4.10.3) 874 0 R (subsubsection.6.4.10.4) 878 0 R (subsubsection.6.4.11.1) 886 0 R] /Limits [(subsubsection.6.3.3.2) (subsubsection.6.4.11.1)] >> endobj 5126 0 obj << /Names [(subsubsection.6.4.11.2) 890 0 R (subsubsection.6.4.11.3) 894 0 R (subsubsection.6.4.11.4) 898 0 R (subsubsection.6.4.11.5) 902 0 R (subsubsection.6.4.11.6) 906 0 R (subsubsection.6.4.11.7) 910 0 R] /Limits [(subsubsection.6.4.11.2) (subsubsection.6.4.11.7)] >> endobj 5127 0 obj << /Names [(subsubsection.6.4.2.1) 786 0 R (subsubsection.6.4.4.1) 798 0 R (subsubsection.6.4.4.2) 802 0 R (subsubsection.6.4.8.1) 822 0 R (subsubsection.6.4.8.2) 826 0 R (subsubsection.6.4.8.3) 830 0 R] /Limits [(subsubsection.6.4.2.1) (subsubsection.6.4.8.3)] >> endobj 5128 0 obj << /Names [(subsubsection.6.4.8.4) 834 0 R (subsubsection.6.4.8.5) 838 0 R (subsubsection.6.4.9.1) 846 0 R (subsubsection.6.4.9.2) 850 0 R (subsubsection.6.4.9.3) 854 0 R (subsubsection.6.4.9.4) 858 0 R] /Limits [(subsubsection.6.4.8.4) (subsubsection.6.4.9.4)] >> endobj 5129 0 obj << /Names [(subsubsection.6.5.1.1) 922 0 R (subsubsection.6.5.1.2) 926 0 R (subsubsection.6.5.1.3) 930 0 R (subsubsection.6.5.2.1) 938 0 R (subsubsection.6.5.2.2) 942 0 R (subsubsection.6.5.2.3) 946 0 R] /Limits [(subsubsection.6.5.1.1) (subsubsection.6.5.2.3)] >> endobj 5130 0 obj << /Names [(subsubsection.6.5.4.1) 958 0 R (subsubsection.6.5.4.2) 962 0 R (subsubsection.6.5.4.3) 966 0 R (subsubsection.6.5.4.4) 970 0 R (subsubsection.6.6.1.1) 982 0 R (subsubsection.6.6.1.2) 998 0 R] /Limits [(subsubsection.6.5.4.1) (subsubsection.6.6.1.2)] >> endobj 5131 0 obj << /Names [(subsubsection.6.7.1.1) 1014 0 R (subsubsection.6.7.1.2) 1018 0 R (subsubsection.6.7.2.1) 1026 0 R (subsubsection.6.7.2.2) 1030 0 R (subsubsection.6.7.2.3) 1034 0 R (subsubsection.6.7.2.4) 1038 0 R] /Limits [(subsubsection.6.7.1.1) (subsubsection.6.7.2.4)] >> endobj 5132 0 obj << /Names [(subsubsection.6.7.4.1) 1050 0 R (subsubsection.6.7.4.2) 1054 0 R (subsubsection.7.2.1.1) 1082 0 R (subsubsection.7.2.1.2) 1086 0 R (subsubsection.7.2.1.3) 1090 0 R (subsubsection.7.3.2.1) 1110 0 R] /Limits [(subsubsection.6.7.4.1) (subsubsection.7.3.2.1)] >> endobj 5133 0 obj << /Names [(subsubsection.7.3.2.2) 1114 0 R (subsubsection.7.3.2.3) 1118 0 R (subsubsection.7.4.1.1) 1150 0 R (subsubsection.7.4.1.2) 1154 0 R (subsubsection.A.11.3.1) 1598 0 R (subsubsection.A.12.3.1) 1630 0 R] /Limits [(subsubsection.7.3.2.2) (subsubsection.A.12.3.1)] >> endobj 5134 0 obj << /Names [(subsubsection.A.12.3.2) 1634 0 R (subsubsection.A.12.3.3) 1638 0 R (subsubsection.A.12.3.4) 1642 0 R (subsubsection.A.12.3.5) 1646 0 R (subsubsection.A.2.1.1) 1270 0 R (subsubsection.A.2.1.2) 1274 0 R] /Limits [(subsubsection.A.12.3.2) (subsubsection.A.2.1.2)] >> endobj 5135 0 obj << /Names [(subsubsection.A.2.1.3) 1278 0 R (subsubsection.A.2.1.4) 1282 0 R (subsubsection.A.2.1.5) 1286 0 R (subsubsection.A.2.1.6) 1290 0 R (subsubsection.A.2.1.7) 1294 0 R (subsubsection.A.2.2.1) 1302 0 R] /Limits [(subsubsection.A.2.1.3) (subsubsection.A.2.2.1)] >> endobj 5136 0 obj << /Names [(subsubsection.A.2.2.2) 1318 0 R (subsubsection.A.2.2.3) 1334 0 R (subsubsection.A.3.1.1) 1366 0 R (subsubsection.A.3.1.2) 1370 0 R (subsubsection.C.2.1.1) 1734 0 R (subsubsection.C.2.1.2) 1738 0 R] /Limits [(subsubsection.A.2.2.2) (subsubsection.C.2.1.2)] >> endobj 5137 0 obj << /Names [(subsubsection.C.2.1.3) 1742 0 R (subsubsection.C.2.1.4) 1746 0 R (subsubsection.C.2.1.5) 1750 0 R (table.4.1) 2514 0 R (table.4.2) 2559 0 R (table.6.1) 3007 0 R] /Limits [(subsubsection.C.2.1.3) (table.6.1)] >> endobj 5138 0 obj << /Names [(table.6.2) 3018 0 R (table.6.3) 3061 0 R (table.6.4) 3102 0 R (table.6.5) 3289 0 R (table.6.6) 3299 0 R (table.A.1) 3575 0 R] /Limits [(table.6.2) (table.A.1)] >> endobj 5139 0 obj << /Names [(table.A.10) 3609 0 R (table.A.11) 3614 0 R (table.A.12) 3620 0 R (table.A.13) 3628 0 R (table.A.14) 3635 0 R (table.A.15) 3636 0 R] /Limits [(table.A.10) (table.A.15)] >> endobj 5140 0 obj << /Names [(table.A.16) 3641 0 R (table.A.17) 3642 0 R (table.A.18) 3647 0 R (table.A.19) 3651 0 R (table.A.2) 3576 0 R (table.A.20) 3658 0 R] /Limits [(table.A.16) (table.A.20)] >> endobj 5141 0 obj << /Names [(table.A.21) 3665 0 R (table.A.22) 3676 0 R (table.A.23) 3681 0 R (table.A.24) 3682 0 R (table.A.25) 3687 0 R (table.A.26) 3688 0 R] /Limits [(table.A.21) (table.A.26)] >> endobj 5142 0 obj << /Names [(table.A.27) 3689 0 R (table.A.28) 3694 0 R (table.A.29) 3695 0 R (table.A.3) 3583 0 R (table.A.30) 3702 0 R (table.A.31) 3703 0 R] /Limits [(table.A.27) (table.A.31)] >> endobj 5143 0 obj << /Names [(table.A.32) 3713 0 R (table.A.33) 3727 0 R (table.A.34) 3734 0 R (table.A.35) 3735 0 R (table.A.36) 3741 0 R (table.A.37) 3742 0 R] /Limits [(table.A.32) (table.A.37)] >> endobj 5144 0 obj << /Names [(table.A.38) 3747 0 R (table.A.4) 3588 0 R (table.A.5) 3593 0 R (table.A.6) 3594 0 R (table.A.7) 3599 0 R (table.A.8) 3600 0 R] /Limits [(table.A.38) (table.A.8)] >> endobj 5145 0 obj << /Names [(table.A.9) 3601 0 R (table.C.1) 3890 0 R] /Limits [(table.A.9) (table.C.1)] >> endobj 5146 0 obj << /Kids [4973 0 R 4974 0 R 4975 0 R 4976 0 R 4977 0 R 4978 0 R] /Limits [(Doc-Start) (Item.118)] >> endobj 5147 0 obj << /Kids [4979 0 R 4980 0 R 4981 0 R 4982 0 R 4983 0 R 4984 0 R] /Limits [(Item.119) (Item.150)] >> endobj 5148 0 obj << /Kids [4985 0 R 4986 0 R 4987 0 R 4988 0 R 4989 0 R 4990 0 R] /Limits [(Item.151) (Item.183)] >> endobj 5149 0 obj << /Kids [4991 0 R 4992 0 R 4993 0 R 4994 0 R 4995 0 R 4996 0 R] /Limits [(Item.184) (Item.41)] >> endobj 5150 0 obj << /Kids [4997 0 R 4998 0 R 4999 0 R 5000 0 R 5001 0 R 5002 0 R] /Limits [(Item.42) (Item.74)] >> endobj 5151 0 obj << /Kids [5003 0 R 5004 0 R 5005 0 R 5006 0 R 5007 0 R 5008 0 R] /Limits [(Item.75) (chapter*.1)] >> endobj 5152 0 obj << /Kids [5009 0 R 5010 0 R 5011 0 R 5012 0 R 5013 0 R 5014 0 R] /Limits [(chapter.1) (figure.caption.3)] >> endobj 5153 0 obj << /Kids [5015 0 R 5016 0 R 5017 0 R 5018 0 R 5019 0 R 5020 0 R] /Limits [(figure.caption.4) (page.109)] >> endobj 5154 0 obj << /Kids [5021 0 R 5022 0 R 5023 0 R 5024 0 R 5025 0 R 5026 0 R] /Limits [(page.11) (page.141)] >> endobj 5155 0 obj << /Kids [5027 0 R 5028 0 R 5029 0 R 5030 0 R 5031 0 R 5032 0 R] /Limits [(page.142) (page.174)] >> endobj 5156 0 obj << /Kids [5033 0 R 5034 0 R 5035 0 R 5036 0 R 5037 0 R 5038 0 R] /Limits [(page.175) (page.206)] >> endobj 5157 0 obj << /Kids [5039 0 R 5040 0 R 5041 0 R 5042 0 R 5043 0 R 5044 0 R] /Limits [(page.207) (page.239)] >> endobj 5158 0 obj << /Kids [5045 0 R 5046 0 R 5047 0 R 5048 0 R 5049 0 R 5050 0 R] /Limits [(page.24) (page.31)] >> endobj 5159 0 obj << /Kids [5051 0 R 5052 0 R 5053 0 R 5054 0 R 5055 0 R 5056 0 R] /Limits [(page.32) (page.64)] >> endobj 5160 0 obj << /Kids [5057 0 R 5058 0 R 5059 0 R 5060 0 R 5061 0 R 5062 0 R] /Limits [(page.65) (page.97)] >> endobj 5161 0 obj << /Kids [5063 0 R 5064 0 R 5065 0 R 5066 0 R 5067 0 R 5068 0 R] /Limits [(page.98) (paragraph.6.2.1.1.3)] >> endobj 5162 0 obj << /Kids [5069 0 R 5070 0 R 5071 0 R 5072 0 R 5073 0 R 5074 0 R] /Limits [(paragraph.6.2.1.1.4) (section.4.12)] >> endobj 5163 0 obj << /Kids [5075 0 R 5076 0 R 5077 0 R 5078 0 R 5079 0 R 5080 0 R] /Limits [(section.4.2) (section.A.11)] >> endobj 5164 0 obj << /Kids [5081 0 R 5082 0 R 5083 0 R 5084 0 R 5085 0 R 5086 0 R] /Limits [(section.A.12) (subsection.3.3.2)] >> endobj 5165 0 obj << /Kids [5087 0 R 5088 0 R 5089 0 R 5090 0 R 5091 0 R 5092 0 R] /Limits [(subsection.3.3.3) (subsection.5.4.4)] >> endobj 5166 0 obj << /Kids [5093 0 R 5094 0 R 5095 0 R 5096 0 R 5097 0 R 5098 0 R] /Limits [(subsection.5.4.5) (subsection.6.7.3)] >> endobj 5167 0 obj << /Kids [5099 0 R 5100 0 R 5101 0 R 5102 0 R 5103 0 R 5104 0 R] /Limits [(subsection.6.7.4) (subsection.A.11.3)] >> endobj 5168 0 obj << /Kids [5105 0 R 5106 0 R 5107 0 R 5108 0 R 5109 0 R 5110 0 R] /Limits [(subsection.A.11.4) (subsection.A.7.26)] >> endobj 5169 0 obj << /Kids [5111 0 R 5112 0 R 5113 0 R 5114 0 R 5115 0 R 5116 0 R] /Limits [(subsection.A.7.27) (subsubsection.4.7.3.3)] >> endobj 5170 0 obj << /Kids [5117 0 R 5118 0 R 5119 0 R 5120 0 R 5121 0 R 5122 0 R] /Limits [(subsubsection.4.7.3.4) (subsubsection.6.1.7.2)] >> endobj 5171 0 obj << /Kids [5123 0 R 5124 0 R 5125 0 R 5126 0 R 5127 0 R 5128 0 R] /Limits [(subsubsection.6.1.7.3) (subsubsection.6.4.9.4)] >> endobj 5172 0 obj << /Kids [5129 0 R 5130 0 R 5131 0 R 5132 0 R 5133 0 R 5134 0 R] /Limits [(subsubsection.6.5.1.1) (subsubsection.A.2.1.2)] >> endobj 5173 0 obj << /Kids [5135 0 R 5136 0 R 5137 0 R 5138 0 R 5139 0 R 5140 0 R] /Limits [(subsubsection.A.2.1.3) (table.A.20)] >> endobj 5174 0 obj << /Kids [5141 0 R 5142 0 R 5143 0 R 5144 0 R 5145 0 R] /Limits [(table.A.21) (table.C.1)] >> endobj 5175 0 obj << /Kids [5146 0 R 5147 0 R 5148 0 R 5149 0 R 5150 0 R 5151 0 R] /Limits [(Doc-Start) (chapter*.1)] >> endobj 5176 0 obj << /Kids [5152 0 R 5153 0 R 5154 0 R 5155 0 R 5156 0 R 5157 0 R] /Limits [(chapter.1) (page.239)] >> endobj 5177 0 obj << /Kids [5158 0 R 5159 0 R 5160 0 R 5161 0 R 5162 0 R 5163 0 R] /Limits [(page.24) (section.A.11)] >> endobj 5178 0 obj << /Kids [5164 0 R 5165 0 R 5166 0 R 5167 0 R 5168 0 R 5169 0 R] /Limits [(section.A.12) (subsubsection.4.7.3.3)] >> endobj 5179 0 obj << /Kids [5170 0 R 5171 0 R 5172 0 R 5173 0 R 5174 0 R] /Limits [(subsubsection.4.7.3.4) (table.C.1)] >> endobj 5180 0 obj << /Kids [5175 0 R 5176 0 R 5177 0 R 5178 0 R 5179 0 R] /Limits [(Doc-Start) (table.C.1)] >> endobj 5181 0 obj << /Dests 5180 0 R >> endobj 5182 0 obj << /Type /Catalog /Pages 4971 0 R /Outlines 4972 0 R /Names 5181 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 1825 0 R >> endobj 5183 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.14)/Keywords() /CreationDate (D:20160114152434+01'00') /ModDate (D:20160114152434+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian) kpathsea version 6.1.1) >> endobj xref 0 5184 0000000000 65535 f 0000000015 00000 n 0000313793 00000 n 0002210852 00000 n 0000000060 00000 n 0000000146 00000 n 0000313849 00000 n 0002210782 00000 n 0000000193 00000 n 0000000373 00000 n 0000317507 00000 n 0002210711 00000 n 0000000420 00000 n 0000000558 00000 n 0000318895 00000 n 0002210586 00000 n 0000000604 00000 n 0000000709 00000 n 0000318952 00000 n 0002210512 00000 n 0000000757 00000 n 0000000883 00000 n 0000321651 00000 n 0002210401 00000 n 0000000931 00000 n 0000001072 00000 n 0000321708 00000 n 0002210303 00000 n 0000001125 00000 n 0000001324 00000 n 0000323537 00000 n 0002210229 00000 n 0000001382 00000 n 0000001520 00000 n 0000323594 00000 n 0002210142 00000 n 0000001578 00000 n 0000001711 00000 n 0000326198 00000 n 0002210055 00000 n 0000001769 00000 n 0000001907 00000 n 0000326255 00000 n 0002209968 00000 n 0000001965 00000 n 0000002113 00000 n 0000328176 00000 n 0002209881 00000 n 0000002171 00000 n 0000002309 00000 n 0000330365 00000 n 0002209807 00000 n 0000002367 00000 n 0000002500 00000 n 0000370671 00000 n 0002209679 00000 n 0000002546 00000 n 0000002730 00000 n 0000370728 00000 n 0002209605 00000 n 0000002778 00000 n 0000002916 00000 n 0000374105 00000 n 0002209518 00000 n 0000002964 00000 n 0000003039 00000 n 0000374162 00000 n 0002209393 00000 n 0000003087 00000 n 0000003167 00000 n 0000374219 00000 n 0002209319 00000 n 0000003220 00000 n 0000003310 00000 n 0000378631 00000 n 0002209232 00000 n 0000003363 00000 n 0000003496 00000 n 0000378688 00000 n 0002209145 00000 n 0000003549 00000 n 0000003657 00000 n 0000381966 00000 n 0002209058 00000 n 0000003710 00000 n 0000003899 00000 n 0000382023 00000 n 0002208971 00000 n 0000003952 00000 n 0000004085 00000 n 0000382080 00000 n 0002208884 00000 n 0000004138 00000 n 0000004324 00000 n 0000385321 00000 n 0002208797 00000 n 0000004377 00000 n 0000004663 00000 n 0000385554 00000 n 0002208722 00000 n 0000004716 00000 n 0000004840 00000 n 0000385611 00000 n 0002208631 00000 n 0000004889 00000 n 0000004970 00000 n 0000385669 00000 n 0002208539 00000 n 0000005019 00000 n 0000005181 00000 n 0000389271 00000 n 0002208447 00000 n 0000005230 00000 n 0000005321 00000 n 0000389329 00000 n 0002208355 00000 n 0000005370 00000 n 0000005509 00000 n 0000389387 00000 n 0002208238 00000 n 0000005558 00000 n 0000005785 00000 n 0000389441 00000 n 0002208159 00000 n 0000005839 00000 n 0000005956 00000 n 0000397508 00000 n 0002208066 00000 n 0000006010 00000 n 0000006324 00000 n 0000399667 00000 n 0002207987 00000 n 0000006378 00000 n 0000006469 00000 n 0000528631 00000 n 0002207854 00000 n 0000006516 00000 n 0000006757 00000 n 0000528689 00000 n 0002207775 00000 n 0000006806 00000 n 0000006894 00000 n 0000528747 00000 n 0002207682 00000 n 0000006943 00000 n 0000007049 00000 n 0000528803 00000 n 0002207589 00000 n 0000007098 00000 n 0000007209 00000 n 0000528861 00000 n 0002207496 00000 n 0000007258 00000 n 0000007339 00000 n 0000532203 00000 n 0002207364 00000 n 0000007388 00000 n 0000007484 00000 n 0000534761 00000 n 0002207285 00000 n 0000007538 00000 n 0000007654 00000 n 0000534819 00000 n 0002207206 00000 n 0000007708 00000 n 0000007829 00000 n 0000537895 00000 n 0002207074 00000 n 0000007878 00000 n 0000007936 00000 n 0000537953 00000 n 0002206995 00000 n 0000007990 00000 n 0000008078 00000 n 0000538011 00000 n 0002206902 00000 n 0000008132 00000 n 0000008243 00000 n 0000538069 00000 n 0002206809 00000 n 0000008297 00000 n 0000008383 00000 n 0000546842 00000 n 0002206716 00000 n 0000008437 00000 n 0000008765 00000 n 0000549775 00000 n 0002206598 00000 n 0000008819 00000 n 0000009023 00000 n 0000549833 00000 n 0002206480 00000 n 0000009082 00000 n 0000009203 00000 n 0000549891 00000 n 0002206401 00000 n 0000009260 00000 n 0000009318 00000 n 0000552484 00000 n 0002206308 00000 n 0000009375 00000 n 0000009443 00000 n 0000552600 00000 n 0002206229 00000 n 0000009500 00000 n 0000009563 00000 n 0000552835 00000 n 0002206111 00000 n 0000009622 00000 n 0000009708 00000 n 0000552893 00000 n 0002206032 00000 n 0000009765 00000 n 0000009904 00000 n 0000555171 00000 n 0002205939 00000 n 0000009961 00000 n 0000010085 00000 n 0000556999 00000 n 0002205846 00000 n 0000010142 00000 n 0000010322 00000 n 0000557057 00000 n 0002205753 00000 n 0000010379 00000 n 0000010551 00000 n 0000558752 00000 n 0002205674 00000 n 0000010608 00000 n 0000010671 00000 n 0000562562 00000 n 0002205542 00000 n 0000010720 00000 n 0000010773 00000 n 0000562620 00000 n 0002205463 00000 n 0000010827 00000 n 0000011027 00000 n 0000567172 00000 n 0002205370 00000 n 0000011081 00000 n 0000011233 00000 n 0000567230 00000 n 0002205238 00000 n 0000011287 00000 n 0000011416 00000 n 0000567288 00000 n 0002205159 00000 n 0000011475 00000 n 0000011634 00000 n 0000569124 00000 n 0002205066 00000 n 0000011693 00000 n 0000011886 00000 n 0000571274 00000 n 0002204973 00000 n 0000011945 00000 n 0000012242 00000 n 0000574194 00000 n 0002204880 00000 n 0000012301 00000 n 0000012507 00000 n 0000576653 00000 n 0002204801 00000 n 0000012566 00000 n 0000012789 00000 n 0000582444 00000 n 0002204669 00000 n 0000012843 00000 n 0000012988 00000 n 0000582502 00000 n 0002204590 00000 n 0000013047 00000 n 0000013211 00000 n 0000582560 00000 n 0002204511 00000 n 0000013270 00000 n 0000013567 00000 n 0000586360 00000 n 0002204393 00000 n 0000013621 00000 n 0000013763 00000 n 0000586418 00000 n 0002204314 00000 n 0000013822 00000 n 0000013978 00000 n 0000586475 00000 n 0002204221 00000 n 0000014037 00000 n 0000014256 00000 n 0000588720 00000 n 0002204142 00000 n 0000014315 00000 n 0000014536 00000 n 0000592454 00000 n 0002204010 00000 n 0000014585 00000 n 0000014754 00000 n 0000598699 00000 n 0002203892 00000 n 0000014808 00000 n 0000014912 00000 n 0000598875 00000 n 0002203813 00000 n 0000014971 00000 n 0000015262 00000 n 0000601629 00000 n 0002203720 00000 n 0000015321 00000 n 0000015669 00000 n 0000603893 00000 n 0002203641 00000 n 0000015728 00000 n 0000015839 00000 n 0000603951 00000 n 0002203523 00000 n 0000015893 00000 n 0000015997 00000 n 0000608474 00000 n 0002203458 00000 n 0000016056 00000 n 0000016167 00000 n 0000608532 00000 n 0002203365 00000 n 0000016216 00000 n 0000016317 00000 n 0000611257 00000 n 0002203272 00000 n 0000016367 00000 n 0000016531 00000 n 0000611315 00000 n 0002203179 00000 n 0000016581 00000 n 0000016677 00000 n 0000611373 00000 n 0002203100 00000 n 0000016727 00000 n 0000016950 00000 n 0000724421 00000 n 0002202967 00000 n 0000016997 00000 n 0000017166 00000 n 0000724479 00000 n 0002202849 00000 n 0000017215 00000 n 0000017303 00000 n 0000724537 00000 n 0002202784 00000 n 0000017357 00000 n 0000017440 00000 n 0000724595 00000 n 0002202652 00000 n 0000017489 00000 n 0000017669 00000 n 0000733001 00000 n 0002202573 00000 n 0000017723 00000 n 0000017882 00000 n 0000733059 00000 n 0002202480 00000 n 0000017936 00000 n 0000018118 00000 n 0000733117 00000 n 0002202387 00000 n 0000018172 00000 n 0000018445 00000 n 0000733175 00000 n 0002202308 00000 n 0000018499 00000 n 0000018643 00000 n 0000740552 00000 n 0002202176 00000 n 0000018692 00000 n 0000018849 00000 n 0000740610 00000 n 0002202097 00000 n 0000018903 00000 n 0000019067 00000 n 0000780457 00000 n 0002202004 00000 n 0000019121 00000 n 0000019280 00000 n 0000782524 00000 n 0002201872 00000 n 0000019334 00000 n 0000019516 00000 n 0000782582 00000 n 0002201793 00000 n 0000019575 00000 n 0000019793 00000 n 0000852675 00000 n 0002201714 00000 n 0000019852 00000 n 0000019958 00000 n 0000968529 00000 n 0002201596 00000 n 0000020012 00000 n 0000020362 00000 n 0000968587 00000 n 0002201531 00000 n 0000020421 00000 n 0000020494 00000 n 0000971766 00000 n 0002201413 00000 n 0000020543 00000 n 0000020718 00000 n 0000971824 00000 n 0002201295 00000 n 0000020772 00000 n 0000020873 00000 n 0000974994 00000 n 0002201230 00000 n 0000020932 00000 n 0000021097 00000 n 0000975052 00000 n 0002201137 00000 n 0000021151 00000 n 0000021267 00000 n 0000975228 00000 n 0002201044 00000 n 0000021321 00000 n 0000021576 00000 n 0000975286 00000 n 0002200951 00000 n 0000021630 00000 n 0000021855 00000 n 0000975344 00000 n 0002200819 00000 n 0000021909 00000 n 0000022010 00000 n 0000976936 00000 n 0002200754 00000 n 0000022069 00000 n 0000022165 00000 n 0000976994 00000 n 0002200636 00000 n 0000022219 00000 n 0000022310 00000 n 0000978705 00000 n 0002200571 00000 n 0000022369 00000 n 0000022503 00000 n 0001038138 00000 n 0002200436 00000 n 0000022550 00000 n 0000022735 00000 n 0001038196 00000 n 0002200318 00000 n 0000022784 00000 n 0000022956 00000 n 0001038254 00000 n 0002200239 00000 n 0000023010 00000 n 0000023260 00000 n 0001038312 00000 n 0002200106 00000 n 0000023314 00000 n 0000023438 00000 n 0001058716 00000 n 0002199988 00000 n 0000023497 00000 n 0000023741 00000 n 0001058774 00000 n 0002199909 00000 n 0000023798 00000 n 0000023881 00000 n 0001058831 00000 n 0002199830 00000 n 0000023938 00000 n 0000024006 00000 n 0001062117 00000 n 0002199737 00000 n 0000024065 00000 n 0000024189 00000 n 0001062175 00000 n 0002199605 00000 n 0000024248 00000 n 0000024367 00000 n 0001062233 00000 n 0002199526 00000 n 0000024424 00000 n 0000024644 00000 n 0001062291 00000 n 0002199433 00000 n 0000024701 00000 n 0000024906 00000 n 0001065271 00000 n 0002199354 00000 n 0000024963 00000 n 0000025031 00000 n 0001065329 00000 n 0002199222 00000 n 0000025090 00000 n 0000025229 00000 n 0001065387 00000 n 0002199143 00000 n 0000025286 00000 n 0000025369 00000 n 0001065445 00000 n 0002199064 00000 n 0000025426 00000 n 0000025494 00000 n 0001067627 00000 n 0002198971 00000 n 0000025553 00000 n 0000025672 00000 n 0001067685 00000 n 0002198839 00000 n 0000025731 00000 n 0000025885 00000 n 0001067743 00000 n 0002198760 00000 n 0000025942 00000 n 0000026025 00000 n 0001067801 00000 n 0002198681 00000 n 0000026082 00000 n 0000026150 00000 n 0001067859 00000 n 0002198549 00000 n 0000026209 00000 n 0000026338 00000 n 0001067917 00000 n 0002198470 00000 n 0000026395 00000 n 0000026478 00000 n 0001067975 00000 n 0002198391 00000 n 0000026535 00000 n 0000026603 00000 n 0001068033 00000 n 0002198259 00000 n 0000026662 00000 n 0000026796 00000 n 0001068091 00000 n 0002198180 00000 n 0000026853 00000 n 0000026936 00000 n 0001068149 00000 n 0002198101 00000 n 0000026993 00000 n 0000027061 00000 n 0001070506 00000 n 0002198008 00000 n 0000027120 00000 n 0000027224 00000 n 0001070564 00000 n 0002197915 00000 n 0000027284 00000 n 0000027428 00000 n 0001070622 00000 n 0002197822 00000 n 0000027488 00000 n 0000027617 00000 n 0001070680 00000 n 0002197690 00000 n 0000027677 00000 n 0000027821 00000 n 0001070737 00000 n 0002197611 00000 n 0000027879 00000 n 0000027962 00000 n 0001070795 00000 n 0002197532 00000 n 0000028020 00000 n 0000028098 00000 n 0001072895 00000 n 0002197400 00000 n 0000028158 00000 n 0000028327 00000 n 0001072953 00000 n 0002197321 00000 n 0000028385 00000 n 0000028468 00000 n 0001073011 00000 n 0002197242 00000 n 0000028526 00000 n 0000028612 00000 n 0001074970 00000 n 0002197110 00000 n 0000028672 00000 n 0000028831 00000 n 0001075028 00000 n 0002197031 00000 n 0000028889 00000 n 0000028972 00000 n 0001075086 00000 n 0002196952 00000 n 0000029030 00000 n 0000029108 00000 n 0001075144 00000 n 0002196834 00000 n 0000029168 00000 n 0000029312 00000 n 0001075202 00000 n 0002196755 00000 n 0000029370 00000 n 0000029453 00000 n 0001078047 00000 n 0002196676 00000 n 0000029511 00000 n 0000029589 00000 n 0001078105 00000 n 0002196583 00000 n 0000029643 00000 n 0000029818 00000 n 0001078397 00000 n 0002196490 00000 n 0000029872 00000 n 0000030036 00000 n 0001099740 00000 n 0002196397 00000 n 0000030090 00000 n 0000030287 00000 n 0001099798 00000 n 0002196265 00000 n 0000030341 00000 n 0000030502 00000 n 0001099856 00000 n 0002196186 00000 n 0000030561 00000 n 0000030682 00000 n 0001108414 00000 n 0002196107 00000 n 0000030741 00000 n 0000030862 00000 n 0001116806 00000 n 0002195989 00000 n 0000030916 00000 n 0000031088 00000 n 0001116864 00000 n 0002195910 00000 n 0000031147 00000 n 0000031225 00000 n 0001116922 00000 n 0002195817 00000 n 0000031284 00000 n 0000031403 00000 n 0001118895 00000 n 0002195685 00000 n 0000031462 00000 n 0000031601 00000 n 0001118953 00000 n 0002195606 00000 n 0000031658 00000 n 0000031741 00000 n 0001126705 00000 n 0002195527 00000 n 0000031798 00000 n 0000031866 00000 n 0001126763 00000 n 0002195434 00000 n 0000031925 00000 n 0000032082 00000 n 0001126821 00000 n 0002195355 00000 n 0000032141 00000 n 0000032328 00000 n 0001130583 00000 n 0002195223 00000 n 0000032377 00000 n 0000032625 00000 n 0001130641 00000 n 0002195105 00000 n 0000032679 00000 n 0000032869 00000 n 0001134005 00000 n 0002195001 00000 n 0000032928 00000 n 0000033093 00000 n 0001134357 00000 n 0002194922 00000 n 0000033150 00000 n 0000033236 00000 n 0001137151 00000 n 0002194829 00000 n 0000033293 00000 n 0000033356 00000 n 0001137209 00000 n 0002194736 00000 n 0000033413 00000 n 0000033486 00000 n 0001142163 00000 n 0002194643 00000 n 0000033543 00000 n 0000033621 00000 n 0001142221 00000 n 0002194564 00000 n 0000033678 00000 n 0000033825 00000 n 0001146006 00000 n 0002194432 00000 n 0000033879 00000 n 0000034112 00000 n 0001146064 00000 n 0002194314 00000 n 0000034171 00000 n 0000034354 00000 n 0001146122 00000 n 0002194235 00000 n 0000034411 00000 n 0000034638 00000 n 0001146180 00000 n 0002194142 00000 n 0000034695 00000 n 0000034899 00000 n 0001146238 00000 n 0002194049 00000 n 0000034956 00000 n 0000035170 00000 n 0001146296 00000 n 0002193956 00000 n 0000035227 00000 n 0000035446 00000 n 0001148137 00000 n 0002193877 00000 n 0000035503 00000 n 0000035727 00000 n 0001148195 00000 n 0002193798 00000 n 0000035786 00000 n 0000036093 00000 n 0001152771 00000 n 0002193666 00000 n 0000036147 00000 n 0000036286 00000 n 0001152829 00000 n 0002193587 00000 n 0000036345 00000 n 0000036426 00000 n 0001155328 00000 n 0002193494 00000 n 0000036485 00000 n 0000036606 00000 n 0001158004 00000 n 0002193401 00000 n 0000036665 00000 n 0000036824 00000 n 0001160983 00000 n 0002193322 00000 n 0000036883 00000 n 0000037040 00000 n 0001161041 00000 n 0002193204 00000 n 0000037094 00000 n 0000037205 00000 n 0001161453 00000 n 0002193139 00000 n 0000037264 00000 n 0000037446 00000 n 0001165025 00000 n 0002193007 00000 n 0000037495 00000 n 0000037665 00000 n 0001165083 00000 n 0002192928 00000 n 0000037719 00000 n 0000037825 00000 n 0001165141 00000 n 0002192835 00000 n 0000037879 00000 n 0000037980 00000 n 0001168026 00000 n 0002192717 00000 n 0000038034 00000 n 0000038221 00000 n 0001168084 00000 n 0002192638 00000 n 0000038280 00000 n 0000038422 00000 n 0001168142 00000 n 0002192559 00000 n 0000038481 00000 n 0000038705 00000 n 0001170275 00000 n 0002192426 00000 n 0000038754 00000 n 0000038949 00000 n 0001173982 00000 n 0002192347 00000 n 0000039003 00000 n 0000039157 00000 n 0001177171 00000 n 0002192215 00000 n 0000039211 00000 n 0000039365 00000 n 0001177229 00000 n 0002192150 00000 n 0000039424 00000 n 0000039540 00000 n 0001177287 00000 n 0002192057 00000 n 0000039594 00000 n 0000039733 00000 n 0001180131 00000 n 0002191925 00000 n 0000039787 00000 n 0000040070 00000 n 0001180248 00000 n 0002191846 00000 n 0000040129 00000 n 0000040329 00000 n 0001180306 00000 n 0002191767 00000 n 0000040388 00000 n 0000040644 00000 n 0001182492 00000 n 0002191674 00000 n 0000040698 00000 n 0000040847 00000 n 0001182550 00000 n 0002191581 00000 n 0000040901 00000 n 0000041096 00000 n 0001185221 00000 n 0002191488 00000 n 0000041150 00000 n 0000041352 00000 n 0001187509 00000 n 0002191356 00000 n 0000041406 00000 n 0000041618 00000 n 0001187567 00000 n 0002191277 00000 n 0000041677 00000 n 0000041844 00000 n 0001188966 00000 n 0002191184 00000 n 0000041903 00000 n 0000042085 00000 n 0001191707 00000 n 0002191091 00000 n 0000042144 00000 n 0000042311 00000 n 0001194401 00000 n 0002190998 00000 n 0000042370 00000 n 0000042532 00000 n 0001194459 00000 n 0002190919 00000 n 0000042591 00000 n 0000042768 00000 n 0001196953 00000 n 0002190787 00000 n 0000042822 00000 n 0000042996 00000 n 0001197011 00000 n 0002190708 00000 n 0000043055 00000 n 0000043222 00000 n 0001199771 00000 n 0002190615 00000 n 0000043281 00000 n 0000043420 00000 n 0001200124 00000 n 0002190522 00000 n 0000043479 00000 n 0000043621 00000 n 0001202241 00000 n 0002190443 00000 n 0000043680 00000 n 0000043804 00000 n 0001202299 00000 n 0002190311 00000 n 0000043859 00000 n 0000044003 00000 n 0001202357 00000 n 0002190232 00000 n 0000044063 00000 n 0000044230 00000 n 0001205579 00000 n 0002190139 00000 n 0000044290 00000 n 0000044429 00000 n 0001205873 00000 n 0002190046 00000 n 0000044489 00000 n 0000044631 00000 n 0001205931 00000 n 0002189967 00000 n 0000044691 00000 n 0000044800 00000 n 0001207431 00000 n 0002189849 00000 n 0000044855 00000 n 0000044999 00000 n 0001207489 00000 n 0002189770 00000 n 0000045059 00000 n 0000045226 00000 n 0001210368 00000 n 0002189677 00000 n 0000045286 00000 n 0000045397 00000 n 0001215118 00000 n 0002189584 00000 n 0000045457 00000 n 0000045748 00000 n 0001215174 00000 n 0002189491 00000 n 0000045808 00000 n 0000046069 00000 n 0001220518 00000 n 0002189398 00000 n 0000046129 00000 n 0000046405 00000 n 0001223077 00000 n 0002189305 00000 n 0000046465 00000 n 0000046639 00000 n 0001223135 00000 n 0002189226 00000 n 0000046699 00000 n 0000046838 00000 n 0001225441 00000 n 0002189094 00000 n 0000046887 00000 n 0000047059 00000 n 0001246442 00000 n 0002188976 00000 n 0000047113 00000 n 0000047371 00000 n 0001246500 00000 n 0002188897 00000 n 0000047430 00000 n 0000047615 00000 n 0001259455 00000 n 0002188804 00000 n 0000047674 00000 n 0000047798 00000 n 0001259513 00000 n 0002188725 00000 n 0000047857 00000 n 0000047966 00000 n 0001261854 00000 n 0002188593 00000 n 0000048020 00000 n 0000048139 00000 n 0001261912 00000 n 0002188514 00000 n 0000048198 00000 n 0000048347 00000 n 0001263987 00000 n 0002188421 00000 n 0000048406 00000 n 0000048555 00000 n 0001267517 00000 n 0002188342 00000 n 0000048614 00000 n 0000048957 00000 n 0001268282 00000 n 0002188249 00000 n 0000049011 00000 n 0000049127 00000 n 0001272168 00000 n 0002188131 00000 n 0000049181 00000 n 0000049338 00000 n 0001272343 00000 n 0002188052 00000 n 0000049397 00000 n 0000049516 00000 n 0001274188 00000 n 0002187959 00000 n 0000049575 00000 n 0000049694 00000 n 0001276875 00000 n 0002187866 00000 n 0000049753 00000 n 0000049930 00000 n 0001279333 00000 n 0002187787 00000 n 0000049989 00000 n 0000050278 00000 n 0001279391 00000 n 0002187653 00000 n 0000050327 00000 n 0000050689 00000 n 0001279449 00000 n 0002187534 00000 n 0000050743 00000 n 0000050994 00000 n 0001279507 00000 n 0002187416 00000 n 0000051053 00000 n 0000051246 00000 n 0001279565 00000 n 0002187337 00000 n 0000051303 00000 n 0000051472 00000 n 0001279623 00000 n 0002187244 00000 n 0000051529 00000 n 0000051602 00000 n 0001281878 00000 n 0002187165 00000 n 0000051659 00000 n 0000051730 00000 n 0001283996 00000 n 0002187085 00000 n 0000051789 00000 n 0000051980 00000 n 0001287211 00000 n 0002187003 00000 n 0000052035 00000 n 0000052211 00000 n 0001291016 00000 n 0002186880 00000 n 0000052261 00000 n 0000052451 00000 n 0001291075 00000 n 0002186755 00000 n 0000052506 00000 n 0000052618 00000 n 0001291134 00000 n 0002186671 00000 n 0000052678 00000 n 0000052770 00000 n 0001295232 00000 n 0002186587 00000 n 0000052830 00000 n 0000053041 00000 n 0001295291 00000 n 0002186447 00000 n 0000053096 00000 n 0000053175 00000 n 0001295350 00000 n 0002186363 00000 n 0000053235 00000 n 0000053360 00000 n 0001297187 00000 n 0002186264 00000 n 0000053420 00000 n 0000053553 00000 n 0001297246 00000 n 0002186165 00000 n 0000053613 00000 n 0000053814 00000 n 0001297305 00000 n 0002186081 00000 n 0000053874 00000 n 0000054042 00000 n 0001306089 00000 n 0002185982 00000 n 0000054097 00000 n 0000054480 00000 n 0001306148 00000 n 0002185857 00000 n 0000054535 00000 n 0000054622 00000 n 0001306207 00000 n 0002185773 00000 n 0000054682 00000 n 0000054825 00000 n 0001317015 00000 n 0002185689 00000 n 0000054885 00000 n 0000055028 00000 n 0001406340 00000 n 0002185549 00000 n 0000055076 00000 n 0000055193 00000 n 0001406399 00000 n 0002185424 00000 n 0000055243 00000 n 0000055355 00000 n 0001406458 00000 n 0002185340 00000 n 0000055410 00000 n 0000055525 00000 n 0001409436 00000 n 0002185256 00000 n 0000055580 00000 n 0000055828 00000 n 0001409493 00000 n 0002185116 00000 n 0000055878 00000 n 0000056010 00000 n 0001409847 00000 n 0002184991 00000 n 0000056065 00000 n 0000056216 00000 n 0001409906 00000 n 0002184907 00000 n 0000056276 00000 n 0000056616 00000 n 0001411851 00000 n 0002184808 00000 n 0000056676 00000 n 0000057031 00000 n 0001413551 00000 n 0002184724 00000 n 0000057091 00000 n 0000057264 00000 n 0001413610 00000 n 0002184640 00000 n 0000057319 00000 n 0000057475 00000 n 0001416191 00000 n 0002184500 00000 n 0000057525 00000 n 0000057627 00000 n 0001416250 00000 n 0002184416 00000 n 0000057682 00000 n 0000057771 00000 n 0001416308 00000 n 0002184276 00000 n 0000057826 00000 n 0000058014 00000 n 0001416367 00000 n 0002184192 00000 n 0000058074 00000 n 0000058329 00000 n 0001422699 00000 n 0002184093 00000 n 0000058389 00000 n 0000058610 00000 n 0001434466 00000 n 0002184009 00000 n 0000058670 00000 n 0000058835 00000 n 0001437651 00000 n 0002183910 00000 n 0000058890 00000 n 0000059114 00000 n 0001437710 00000 n 0002183811 00000 n 0000059169 00000 n 0000059422 00000 n 0001440990 00000 n 0002183712 00000 n 0000059477 00000 n 0000059652 00000 n 0001441049 00000 n 0002183613 00000 n 0000059707 00000 n 0000059852 00000 n 0001445799 00000 n 0002183529 00000 n 0000059907 00000 n 0000060195 00000 n 0001449796 00000 n 0002183389 00000 n 0000060245 00000 n 0000060319 00000 n 0001449855 00000 n 0002183264 00000 n 0000060374 00000 n 0000060514 00000 n 0001452054 00000 n 0002183180 00000 n 0000060574 00000 n 0000060828 00000 n 0001454723 00000 n 0002183096 00000 n 0000060888 00000 n 0000061068 00000 n 0001457154 00000 n 0002183012 00000 n 0000061123 00000 n 0000061225 00000 n 0001460190 00000 n 0002182913 00000 n 0000061275 00000 n 0000061499 00000 n 0001496138 00000 n 0002182773 00000 n 0000061549 00000 n 0000061808 00000 n 0001496197 00000 n 0002182689 00000 n 0000061863 00000 n 0000062132 00000 n 0001566056 00000 n 0002182605 00000 n 0000062187 00000 n 0000062405 00000 n 0001566115 00000 n 0002182506 00000 n 0000062455 00000 n 0000062582 00000 n 0001566174 00000 n 0002182366 00000 n 0000062632 00000 n 0000062759 00000 n 0001566233 00000 n 0002182282 00000 n 0000062814 00000 n 0000062893 00000 n 0001569375 00000 n 0002182198 00000 n 0000062948 00000 n 0000063007 00000 n 0001571764 00000 n 0002182099 00000 n 0000063057 00000 n 0000063184 00000 n 0001574478 00000 n 0002182000 00000 n 0000063235 00000 n 0000063492 00000 n 0001576121 00000 n 0002181901 00000 n 0000063543 00000 n 0000063767 00000 n 0001579072 00000 n 0002181761 00000 n 0000063818 00000 n 0000064006 00000 n 0001582026 00000 n 0002181677 00000 n 0000064062 00000 n 0000064387 00000 n 0001582085 00000 n 0002181593 00000 n 0000064443 00000 n 0000064877 00000 n 0001582144 00000 n 0002181494 00000 n 0000064928 00000 n 0000065253 00000 n 0001584841 00000 n 0002181369 00000 n 0000065304 00000 n 0000065515 00000 n 0001584900 00000 n 0002181285 00000 n 0000065571 00000 n 0000065716 00000 n 0001725381 00000 n 0002181201 00000 n 0000065772 00000 n 0000066110 00000 n 0001727634 00000 n 0002181060 00000 n 0000066159 00000 n 0000066261 00000 n 0001727693 00000 n 0002180935 00000 n 0000066311 00000 n 0000066423 00000 n 0001727752 00000 n 0002180851 00000 n 0000066478 00000 n 0000066616 00000 n 0001727811 00000 n 0002180752 00000 n 0000066671 00000 n 0000066849 00000 n 0001727870 00000 n 0002180653 00000 n 0000066904 00000 n 0000067080 00000 n 0001727929 00000 n 0002180554 00000 n 0000067135 00000 n 0000067260 00000 n 0001731349 00000 n 0002180470 00000 n 0000067315 00000 n 0000067440 00000 n 0001734788 00000 n 0002180330 00000 n 0000067490 00000 n 0000067602 00000 n 0001734847 00000 n 0002180205 00000 n 0000067657 00000 n 0000067885 00000 n 0001736616 00000 n 0002180121 00000 n 0000067945 00000 n 0000068098 00000 n 0001736675 00000 n 0002180022 00000 n 0000068158 00000 n 0000068321 00000 n 0001739702 00000 n 0002179923 00000 n 0000068381 00000 n 0000068624 00000 n 0001739820 00000 n 0002179824 00000 n 0000068684 00000 n 0000068867 00000 n 0001742882 00000 n 0002179725 00000 n 0000068927 00000 n 0000069168 00000 n 0001742941 00000 n 0002179626 00000 n 0000069228 00000 n 0000069454 00000 n 0001745666 00000 n 0002179542 00000 n 0000069514 00000 n 0000069720 00000 n 0001745725 00000 n 0002179402 00000 n 0000069775 00000 n 0000069965 00000 n 0001745960 00000 n 0002179277 00000 n 0000070025 00000 n 0000070190 00000 n 0001746078 00000 n 0002179193 00000 n 0000070248 00000 n 0000070436 00000 n 0001748652 00000 n 0002179094 00000 n 0000070494 00000 n 0000070731 00000 n 0001748711 00000 n 0002179010 00000 n 0000070789 00000 n 0000070992 00000 n 0001748770 00000 n 0002178870 00000 n 0000071052 00000 n 0000071303 00000 n 0001748886 00000 n 0002178786 00000 n 0000071361 00000 n 0000071598 00000 n 0001752148 00000 n 0002178687 00000 n 0000071656 00000 n 0000071913 00000 n 0001752207 00000 n 0002178603 00000 n 0000071971 00000 n 0000072198 00000 n 0001752266 00000 n 0002178478 00000 n 0000072258 00000 n 0000072509 00000 n 0001752384 00000 n 0002178394 00000 n 0000072567 00000 n 0000072814 00000 n 0001755663 00000 n 0002178295 00000 n 0000072872 00000 n 0000073055 00000 n 0001755722 00000 n 0002178211 00000 n 0000073113 00000 n 0000073532 00000 n 0001755779 00000 n 0002178112 00000 n 0000073587 00000 n 0000073820 00000 n 0001759317 00000 n 0002178028 00000 n 0000073875 00000 n 0000074118 00000 n 0001761655 00000 n 0002177888 00000 n 0000074168 00000 n 0000074255 00000 n 0001761714 00000 n 0002177763 00000 n 0000074310 00000 n 0000074513 00000 n 0001761832 00000 n 0002177679 00000 n 0000074573 00000 n 0000074744 00000 n 0001761891 00000 n 0002177595 00000 n 0000074804 00000 n 0000075005 00000 n 0001764268 00000 n 0002177496 00000 n 0000075060 00000 n 0000075225 00000 n 0001764386 00000 n 0002177397 00000 n 0000075280 00000 n 0000075488 00000 n 0001764798 00000 n 0002177313 00000 n 0000075543 00000 n 0000075761 00000 n 0001767325 00000 n 0002177214 00000 n 0000075811 00000 n 0000075956 00000 n 0001767384 00000 n 0002177115 00000 n 0000076006 00000 n 0000076144 00000 n 0001767443 00000 n 0002176975 00000 n 0000076194 00000 n 0000076369 00000 n 0001767561 00000 n 0002176891 00000 n 0000076424 00000 n 0000076544 00000 n 0001767620 00000 n 0002176792 00000 n 0000076599 00000 n 0000076724 00000 n 0001771358 00000 n 0002176708 00000 n 0000076779 00000 n 0000076894 00000 n 0001771417 00000 n 0002176567 00000 n 0000076944 00000 n 0000077127 00000 n 0001774076 00000 n 0002176483 00000 n 0000077182 00000 n 0000077302 00000 n 0001774135 00000 n 0002176384 00000 n 0000077357 00000 n 0000077482 00000 n 0001774194 00000 n 0002176285 00000 n 0000077537 00000 n 0000077682 00000 n 0001774253 00000 n 0002176186 00000 n 0000077737 00000 n 0000077897 00000 n 0001774311 00000 n 0002176087 00000 n 0000077952 00000 n 0000078097 00000 n 0001774370 00000 n 0002175988 00000 n 0000078152 00000 n 0000078302 00000 n 0001776741 00000 n 0002175889 00000 n 0000078357 00000 n 0000078472 00000 n 0001776800 00000 n 0002175790 00000 n 0000078527 00000 n 0000078742 00000 n 0001776858 00000 n 0002175691 00000 n 0000078797 00000 n 0000079002 00000 n 0001776917 00000 n 0002175592 00000 n 0000079058 00000 n 0000079223 00000 n 0001776976 00000 n 0002175493 00000 n 0000079279 00000 n 0000079434 00000 n 0001777034 00000 n 0002175394 00000 n 0000079490 00000 n 0000079640 00000 n 0001777093 00000 n 0002175295 00000 n 0000079696 00000 n 0000079856 00000 n 0001779427 00000 n 0002175196 00000 n 0000079912 00000 n 0000080072 00000 n 0001779545 00000 n 0002175097 00000 n 0000080128 00000 n 0000080318 00000 n 0001779663 00000 n 0002174998 00000 n 0000080374 00000 n 0000080529 00000 n 0001779722 00000 n 0002174899 00000 n 0000080585 00000 n 0000080745 00000 n 0001781856 00000 n 0002174800 00000 n 0000080801 00000 n 0000080946 00000 n 0001781974 00000 n 0002174701 00000 n 0000081002 00000 n 0000081157 00000 n 0001782092 00000 n 0002174602 00000 n 0000081213 00000 n 0000081373 00000 n 0001782151 00000 n 0002174503 00000 n 0000081429 00000 n 0000081589 00000 n 0001785116 00000 n 0002174404 00000 n 0000081645 00000 n 0000081960 00000 n 0001785234 00000 n 0002174305 00000 n 0000082016 00000 n 0000082249 00000 n 0001788484 00000 n 0002174206 00000 n 0000082305 00000 n 0000082520 00000 n 0001788602 00000 n 0002174107 00000 n 0000082576 00000 n 0000082751 00000 n 0001791490 00000 n 0002174008 00000 n 0000082807 00000 n 0000082997 00000 n 0001791549 00000 n 0002173909 00000 n 0000083053 00000 n 0000083228 00000 n 0001791608 00000 n 0002173810 00000 n 0000083284 00000 n 0000083454 00000 n 0001791667 00000 n 0002173711 00000 n 0000083510 00000 n 0000083680 00000 n 0001791726 00000 n 0002173612 00000 n 0000083736 00000 n 0000083886 00000 n 0001791785 00000 n 0002173528 00000 n 0000083942 00000 n 0000084097 00000 n 0001794700 00000 n 0002173429 00000 n 0000084147 00000 n 0000084340 00000 n 0001794818 00000 n 0002173289 00000 n 0000084390 00000 n 0000084523 00000 n 0001794877 00000 n 0002173205 00000 n 0000084578 00000 n 0000084746 00000 n 0001794936 00000 n 0002173121 00000 n 0000084801 00000 n 0000084969 00000 n 0001797731 00000 n 0002172981 00000 n 0000085020 00000 n 0000085170 00000 n 0001797790 00000 n 0002172897 00000 n 0000085226 00000 n 0000085490 00000 n 0001797849 00000 n 0002172798 00000 n 0000085546 00000 n 0000085696 00000 n 0001797908 00000 n 0002172699 00000 n 0000085752 00000 n 0000085987 00000 n 0001800997 00000 n 0002172600 00000 n 0000086043 00000 n 0000086361 00000 n 0001801056 00000 n 0002172501 00000 n 0000086417 00000 n 0000086640 00000 n 0001801114 00000 n 0002172417 00000 n 0000086696 00000 n 0000086960 00000 n 0001801232 00000 n 0002172277 00000 n 0000087011 00000 n 0000087103 00000 n 0001801291 00000 n 0002172193 00000 n 0000087159 00000 n 0000087404 00000 n 0001803946 00000 n 0002172094 00000 n 0000087460 00000 n 0000087673 00000 n 0001804005 00000 n 0002171954 00000 n 0000087729 00000 n 0000087864 00000 n 0001804181 00000 n 0002171885 00000 n 0000087925 00000 n 0000088141 00000 n 0001807322 00000 n 0002171786 00000 n 0000088197 00000 n 0000088350 00000 n 0001810872 00000 n 0002171687 00000 n 0000088406 00000 n 0000088524 00000 n 0001813192 00000 n 0002171603 00000 n 0000088580 00000 n 0000088753 00000 n 0001813251 00000 n 0002171478 00000 n 0000088804 00000 n 0000089121 00000 n 0001813310 00000 n 0002171394 00000 n 0000089177 00000 n 0000089327 00000 n 0001813369 00000 n 0002171295 00000 n 0000089383 00000 n 0000089627 00000 n 0001816206 00000 n 0002171170 00000 n 0000089683 00000 n 0000089820 00000 n 0001816265 00000 n 0002171086 00000 n 0000089881 00000 n 0000089963 00000 n 0001816324 00000 n 0002170987 00000 n 0000090024 00000 n 0000090264 00000 n 0001816383 00000 n 0002170888 00000 n 0000090325 00000 n 0000090907 00000 n 0001817863 00000 n 0002170789 00000 n 0000090968 00000 n 0000091108 00000 n 0001817922 00000 n 0002170705 00000 n 0000091169 00000 n 0000091312 00000 n 0001819242 00000 n 0002170564 00000 n 0000091361 00000 n 0000091573 00000 n 0001819301 00000 n 0002170480 00000 n 0000091623 00000 n 0000091687 00000 n 0001822696 00000 n 0002170381 00000 n 0000091737 00000 n 0000091791 00000 n 0001824612 00000 n 0002170282 00000 n 0000091841 00000 n 0000091905 00000 n 0001832809 00000 n 0002170183 00000 n 0000091955 00000 n 0000092014 00000 n 0001834539 00000 n 0002170084 00000 n 0000092064 00000 n 0000092143 00000 n 0001834598 00000 n 0002169944 00000 n 0000092193 00000 n 0000092340 00000 n 0001834657 00000 n 0002169860 00000 n 0000092395 00000 n 0000092474 00000 n 0001835885 00000 n 0002169776 00000 n 0000092529 00000 n 0000092608 00000 n 0001838517 00000 n 0002169636 00000 n 0000092658 00000 n 0000092818 00000 n 0001838576 00000 n 0002169567 00000 n 0000092873 00000 n 0000092952 00000 n 0001841176 00000 n 0002169427 00000 n 0000093002 00000 n 0000093162 00000 n 0001841235 00000 n 0002169358 00000 n 0000093217 00000 n 0000093296 00000 n 0001842591 00000 n 0002169218 00000 n 0000093346 00000 n 0000093506 00000 n 0001843974 00000 n 0002169149 00000 n 0000093561 00000 n 0000093640 00000 n 0001845435 00000 n 0002169024 00000 n 0000093691 00000 n 0000093851 00000 n 0001846679 00000 n 0002168955 00000 n 0000093907 00000 n 0000093986 00000 n 0001851031 00000 n 0002168815 00000 n 0000094035 00000 n 0000094348 00000 n 0001851090 00000 n 0002168731 00000 n 0000094398 00000 n 0000094485 00000 n 0001851149 00000 n 0002168591 00000 n 0000094535 00000 n 0000094650 00000 n 0001853998 00000 n 0002168481 00000 n 0000094705 00000 n 0000094802 00000 n 0001854057 00000 n 0002168397 00000 n 0000094862 00000 n 0000095025 00000 n 0001854116 00000 n 0002168298 00000 n 0000095085 00000 n 0000095235 00000 n 0001854175 00000 n 0002168199 00000 n 0000095295 00000 n 0000095445 00000 n 0001854234 00000 n 0002168100 00000 n 0000095505 00000 n 0000095640 00000 n 0001854293 00000 n 0002168016 00000 n 0000095700 00000 n 0000095830 00000 n 0001854352 00000 n 0002167917 00000 n 0000095880 00000 n 0000096076 00000 n 0001856179 00000 n 0002167833 00000 n 0000096126 00000 n 0000096377 00000 n 0001859527 00000 n 0002167693 00000 n 0000096426 00000 n 0000096622 00000 n 0001859586 00000 n 0002167609 00000 n 0000096672 00000 n 0000096784 00000 n 0001859645 00000 n 0002167510 00000 n 0000096834 00000 n 0000096931 00000 n 0001859704 00000 n 0002167370 00000 n 0000096981 00000 n 0000097134 00000 n 0001859763 00000 n 0002167286 00000 n 0000097189 00000 n 0000097388 00000 n 0001862480 00000 n 0002167202 00000 n 0000097443 00000 n 0000097599 00000 n 0001862539 00000 n 0002167103 00000 n 0000097649 00000 n 0000097820 00000 n 0001862598 00000 n 0002166963 00000 n 0000097870 00000 n 0000098097 00000 n 0001862657 00000 n 0002166879 00000 n 0000098152 00000 n 0000098351 00000 n 0001864637 00000 n 0002166795 00000 n 0000098406 00000 n 0000098562 00000 n 0001864696 00000 n 0002166711 00000 n 0000098612 00000 n 0000098780 00000 n 0001866273 00000 n 0002166571 00000 n 0000098829 00000 n 0000098969 00000 n 0001866332 00000 n 0002166502 00000 n 0000099019 00000 n 0000099386 00000 n 0001868536 00000 n 0002166377 00000 n 0000099435 00000 n 0000099593 00000 n 0001868595 00000 n 0002166293 00000 n 0000099643 00000 n 0000099773 00000 n 0001868771 00000 n 0002166209 00000 n 0000099823 00000 n 0000099958 00000 n 0000100357 00000 n 0000100473 00000 n 0000137115 00000 n 0000100010 00000 n 0000137001 00000 n 0000137056 00000 n 0002158716 00000 n 0002158893 00000 n 0002159261 00000 n 0000139034 00000 n 0000139186 00000 n 0000139341 00000 n 0000139496 00000 n 0000139648 00000 n 0000139802 00000 n 0000139957 00000 n 0000140116 00000 n 0000140281 00000 n 0000140445 00000 n 0000140608 00000 n 0000140773 00000 n 0000140938 00000 n 0000141103 00000 n 0000141254 00000 n 0000141409 00000 n 0000141564 00000 n 0000141718 00000 n 0000141876 00000 n 0000142036 00000 n 0000142195 00000 n 0000142355 00000 n 0000142514 00000 n 0000142674 00000 n 0000142834 00000 n 0000142993 00000 n 0000143148 00000 n 0000143301 00000 n 0000143456 00000 n 0000143610 00000 n 0000143765 00000 n 0000143925 00000 n 0000144085 00000 n 0000144245 00000 n 0000144397 00000 n 0000144548 00000 n 0000144701 00000 n 0000144853 00000 n 0000145005 00000 n 0000147748 00000 n 0000145217 00000 n 0000138555 00000 n 0000137240 00000 n 0000145158 00000 n 0002158357 00000 n 0000147908 00000 n 0000148068 00000 n 0000148223 00000 n 0000148382 00000 n 0000148542 00000 n 0000148701 00000 n 0000148861 00000 n 0000149021 00000 n 0000149186 00000 n 0000149347 00000 n 0000149509 00000 n 0000149670 00000 n 0000149835 00000 n 0000149997 00000 n 0000150159 00000 n 0000150321 00000 n 0000150482 00000 n 0000150644 00000 n 0000150798 00000 n 0000150958 00000 n 0000151117 00000 n 0000151277 00000 n 0000151442 00000 n 0000151606 00000 n 0000151771 00000 n 0000151935 00000 n 0000152100 00000 n 0000152259 00000 n 0000152424 00000 n 0000152589 00000 n 0000152748 00000 n 0000152913 00000 n 0000153078 00000 n 0000153243 00000 n 0000153398 00000 n 0000153556 00000 n 0000153721 00000 n 0000153886 00000 n 0000154051 00000 n 0000154211 00000 n 0000154376 00000 n 0000154531 00000 n 0000154687 00000 n 0000154843 00000 n 0000154999 00000 n 0000155151 00000 n 0000155306 00000 n 0000155466 00000 n 0000155620 00000 n 0000155778 00000 n 0000155935 00000 n 0000156092 00000 n 0000158491 00000 n 0000156305 00000 n 0000147143 00000 n 0000145305 00000 n 0000156250 00000 n 0002159074 00000 n 0000158646 00000 n 0000158806 00000 n 0000158966 00000 n 0000159126 00000 n 0000159291 00000 n 0000159456 00000 n 0000159616 00000 n 0000159779 00000 n 0000159934 00000 n 0000160093 00000 n 0000160258 00000 n 0000160418 00000 n 0000160578 00000 n 0000160738 00000 n 0000160898 00000 n 0000161063 00000 n 0000161222 00000 n 0000161387 00000 n 0000161539 00000 n 0000161694 00000 n 0000161853 00000 n 0000162013 00000 n 0000162178 00000 n 0000162340 00000 n 0000162501 00000 n 0000162666 00000 n 0000162830 00000 n 0000162992 00000 n 0000163154 00000 n 0000163316 00000 n 0000163481 00000 n 0000163642 00000 n 0000163804 00000 n 0000163968 00000 n 0000164133 00000 n 0000164294 00000 n 0000164456 00000 n 0000164621 00000 n 0000164782 00000 n 0000164944 00000 n 0000165109 00000 n 0000165271 00000 n 0000165433 00000 n 0000165598 00000 n 0000165764 00000 n 0000165930 00000 n 0000166096 00000 n 0000166259 00000 n 0000166421 00000 n 0000166585 00000 n 0000166746 00000 n 0000166907 00000 n 0000169526 00000 n 0000167125 00000 n 0000157886 00000 n 0000156407 00000 n 0000167070 00000 n 0000169689 00000 n 0000169852 00000 n 0000170018 00000 n 0000170181 00000 n 0000170344 00000 n 0000170503 00000 n 0000170663 00000 n 0000170823 00000 n 0000170983 00000 n 0000171148 00000 n 0000171313 00000 n 0000171472 00000 n 0000171637 00000 n 0000171802 00000 n 0000171966 00000 n 0000172128 00000 n 0000172289 00000 n 0000172454 00000 n 0000172618 00000 n 0000172773 00000 n 0000172932 00000 n 0000173097 00000 n 0000173259 00000 n 0000173419 00000 n 0000173581 00000 n 0000173743 00000 n 0000173905 00000 n 0000174064 00000 n 0000174229 00000 n 0000174391 00000 n 0000174552 00000 n 0000174714 00000 n 0000174876 00000 n 0000175038 00000 n 0000175203 00000 n 0000175363 00000 n 0000175528 00000 n 0000175693 00000 n 0000175858 00000 n 0000176023 00000 n 0000176183 00000 n 0000176347 00000 n 0000176502 00000 n 0000176661 00000 n 0000176820 00000 n 0000176979 00000 n 0000177144 00000 n 0000177308 00000 n 0000177463 00000 n 0000177621 00000 n 0000177779 00000 n 0000177942 00000 n 0000178099 00000 n 0000180718 00000 n 0000178312 00000 n 0000168912 00000 n 0000167227 00000 n 0000178257 00000 n 0000180883 00000 n 0000181048 00000 n 0000181207 00000 n 0000181367 00000 n 0000181527 00000 n 0000181687 00000 n 0000181852 00000 n 0000182017 00000 n 0000182181 00000 n 0000182346 00000 n 0000182511 00000 n 0000182670 00000 n 0000182835 00000 n 0000182999 00000 n 0000183164 00000 n 0000183329 00000 n 0000183489 00000 n 0000183655 00000 n 0000183820 00000 n 0000183986 00000 n 0000184151 00000 n 0000184312 00000 n 0000184478 00000 n 0000184644 00000 n 0000184810 00000 n 0000184976 00000 n 0000185142 00000 n 0000185307 00000 n 0000185473 00000 n 0000185628 00000 n 0000185788 00000 n 0000185953 00000 n 0000186118 00000 n 0000186283 00000 n 0000186443 00000 n 0000186608 00000 n 0000186771 00000 n 0000186936 00000 n 0000187096 00000 n 0000187256 00000 n 0000187420 00000 n 0000187585 00000 n 0000187750 00000 n 0000187915 00000 n 0000188070 00000 n 0000188229 00000 n 0000188394 00000 n 0000188555 00000 n 0000188717 00000 n 0000188877 00000 n 0000189040 00000 n 0000189198 00000 n 0000189350 00000 n 0000192118 00000 n 0000189563 00000 n 0000180104 00000 n 0000178400 00000 n 0000189508 00000 n 0000192283 00000 n 0000192448 00000 n 0000192608 00000 n 0000192773 00000 n 0000192938 00000 n 0000193103 00000 n 0000193268 00000 n 0000193428 00000 n 0000193588 00000 n 0000193753 00000 n 0000193918 00000 n 0000194070 00000 n 0000194224 00000 n 0000194384 00000 n 0000194544 00000 n 0000194698 00000 n 0000194858 00000 n 0000195023 00000 n 0000195188 00000 n 0000195353 00000 n 0000195513 00000 n 0000195668 00000 n 0000195826 00000 n 0000195985 00000 n 0000196150 00000 n 0000196315 00000 n 0000196480 00000 n 0000196640 00000 n 0000196800 00000 n 0000196960 00000 n 0000197119 00000 n 0000197278 00000 n 0000197431 00000 n 0000197590 00000 n 0000197755 00000 n 0000197919 00000 n 0000198078 00000 n 0000198233 00000 n 0000198387 00000 n 0000198547 00000 n 0000198706 00000 n 0000198861 00000 n 0000199015 00000 n 0000199175 00000 n 0000199335 00000 n 0000199490 00000 n 0000199646 00000 n 0000199802 00000 n 0000199957 00000 n 0000200116 00000 n 0000200275 00000 n 0000200428 00000 n 0000202909 00000 n 0000200637 00000 n 0000191513 00000 n 0000189651 00000 n 0000200582 00000 n 0002159386 00000 n 0000203070 00000 n 0000203231 00000 n 0000203383 00000 n 0000203537 00000 n 0000203696 00000 n 0000203856 00000 n 0000204016 00000 n 0000204175 00000 n 0000204335 00000 n 0000204490 00000 n 0000204650 00000 n 0000204814 00000 n 0000204979 00000 n 0000205143 00000 n 0000205308 00000 n 0000205473 00000 n 0000205638 00000 n 0000205801 00000 n 0000205961 00000 n 0000206126 00000 n 0000206288 00000 n 0000206450 00000 n 0000206612 00000 n 0000206777 00000 n 0000206939 00000 n 0000207101 00000 n 0000207263 00000 n 0000207427 00000 n 0000207589 00000 n 0000207751 00000 n 0000208074 00000 n 0000208234 00000 n 0000208393 00000 n 0000208548 00000 n 0000208707 00000 n 0000208871 00000 n 0000209036 00000 n 0000209195 00000 n 0000209355 00000 n 0000209514 00000 n 0000209669 00000 n 0000209824 00000 n 0000209979 00000 n 0000210139 00000 n 0000210299 00000 n 0000210459 00000 n 0000210613 00000 n 0000210772 00000 n 0000210930 00000 n 0000211088 00000 n 0000211245 00000 n 0000213943 00000 n 0000211458 00000 n 0000202304 00000 n 0000200739 00000 n 0000211403 00000 n 0000207913 00000 n 0000214103 00000 n 0000214263 00000 n 0000214423 00000 n 0000214583 00000 n 0000214744 00000 n 0000214905 00000 n 0000215066 00000 n 0000215227 00000 n 0000215388 00000 n 0000215549 00000 n 0000215710 00000 n 0000215870 00000 n 0000216031 00000 n 0000216191 00000 n 0000216352 00000 n 0000216512 00000 n 0000216672 00000 n 0000216832 00000 n 0000216992 00000 n 0000217153 00000 n 0000217313 00000 n 0000217474 00000 n 0000217635 00000 n 0000217795 00000 n 0000217956 00000 n 0000218116 00000 n 0000218271 00000 n 0000218424 00000 n 0000218584 00000 n 0000218744 00000 n 0000218900 00000 n 0000219061 00000 n 0000219222 00000 n 0000219383 00000 n 0000219544 00000 n 0000219705 00000 n 0000219866 00000 n 0000220022 00000 n 0000220183 00000 n 0000220344 00000 n 0000220504 00000 n 0000220670 00000 n 0000220831 00000 n 0000220992 00000 n 0000221153 00000 n 0000221308 00000 n 0000221469 00000 n 0000221629 00000 n 0000221790 00000 n 0000221954 00000 n 0000222118 00000 n 0000222444 00000 n 0000224691 00000 n 0000222663 00000 n 0000213329 00000 n 0000211560 00000 n 0000222608 00000 n 0000222282 00000 n 0000224857 00000 n 0000225010 00000 n 0000225164 00000 n 0000225318 00000 n 0000225471 00000 n 0000225626 00000 n 0000225781 00000 n 0000225935 00000 n 0000226095 00000 n 0000226253 00000 n 0000226408 00000 n 0000226566 00000 n 0000226721 00000 n 0000226880 00000 n 0000227035 00000 n 0000227194 00000 n 0000227350 00000 n 0000227511 00000 n 0000227664 00000 n 0000227818 00000 n 0000227971 00000 n 0000228131 00000 n 0000228295 00000 n 0000228460 00000 n 0000228623 00000 n 0000228787 00000 n 0000228952 00000 n 0000229107 00000 n 0000229262 00000 n 0000229415 00000 n 0000229569 00000 n 0000229724 00000 n 0000229877 00000 n 0000230037 00000 n 0000230197 00000 n 0000230352 00000 n 0000230507 00000 n 0000230665 00000 n 0000230825 00000 n 0000230980 00000 n 0000231133 00000 n 0000231288 00000 n 0000231441 00000 n 0000231596 00000 n 0000231806 00000 n 0000224158 00000 n 0000222751 00000 n 0000231751 00000 n 0000232244 00000 n 0000307603 00000 n 0000307157 00000 n 0000232128 00000 n 0000231908 00000 n 0000307102 00000 n 0000311440 00000 n 0000307487 00000 n 0000307282 00000 n 0000311385 00000 n 0000308097 00000 n 0000308332 00000 n 0000308380 00000 n 0000308771 00000 n 0000309064 00000 n 0000316353 00000 n 0000316508 00000 n 0000316671 00000 n 0000316836 00000 n 0000316991 00000 n 0000313905 00000 n 0000313622 00000 n 0000311557 00000 n 0000313738 00000 n 0002159511 00000 n 0000317145 00000 n 0000317300 00000 n 0000317753 00000 n 0000316162 00000 n 0000313993 00000 n 0000317452 00000 n 0000317564 00000 n 0000317627 00000 n 0000317690 00000 n 0001878466 00000 n 0001879350 00000 n 0001878407 00000 n 0001879526 00000 n 0000319009 00000 n 0000318724 00000 n 0000317855 00000 n 0000318840 00000 n 0002158007 00000 n 0000321436 00000 n 0000321765 00000 n 0000321299 00000 n 0000319112 00000 n 0000321596 00000 n 0001879056 00000 n 0000325833 00000 n 0000323651 00000 n 0000323366 00000 n 0000321896 00000 n 0000323482 00000 n 0000325988 00000 n 0000326312 00000 n 0000325687 00000 n 0000323768 00000 n 0000326143 00000 n 0000328233 00000 n 0000328005 00000 n 0000326429 00000 n 0000328121 00000 n 0002159636 00000 n 0000330421 00000 n 0000330194 00000 n 0000328364 00000 n 0000330310 00000 n 0000332842 00000 n 0000332671 00000 n 0000330552 00000 n 0000332787 00000 n 0000333312 00000 n 0000367293 00000 n 0000333196 00000 n 0000332959 00000 n 0000367238 00000 n 0000370142 00000 n 0000370299 00000 n 0000370455 00000 n 0000370784 00000 n 0000369987 00000 n 0000367418 00000 n 0000370616 00000 n 0001878231 00000 n 0001878290 00000 n 0001878349 00000 n 0000378267 00000 n 0000374276 00000 n 0000373934 00000 n 0000370886 00000 n 0000374050 00000 n 0000378422 00000 n 0000378870 00000 n 0000378121 00000 n 0000374378 00000 n 0000378576 00000 n 0000378745 00000 n 0000378808 00000 n 0002159761 00000 n 0000381601 00000 n 0000381756 00000 n 0000382137 00000 n 0000381455 00000 n 0000378986 00000 n 0000381911 00000 n 0000385727 00000 n 0000385150 00000 n 0000382239 00000 n 0000385266 00000 n 0000385378 00000 n 0000385436 00000 n 0000385495 00000 n 0000388748 00000 n 0000388902 00000 n 0000389055 00000 n 0000389562 00000 n 0000388593 00000 n 0000385843 00000 n 0000389216 00000 n 0000389499 00000 n 0001878525 00000 n 0001878584 00000 n 0000391510 00000 n 0000397684 00000 n 0000391394 00000 n 0000389664 00000 n 0000397453 00000 n 0000397566 00000 n 0000397625 00000 n 0000393186 00000 n 0000393429 00000 n 0000393477 00000 n 0000393812 00000 n 0000394110 00000 n 0000401228 00000 n 0000401005 00000 n 0000399725 00000 n 0000399496 00000 n 0000397829 00000 n 0000399612 00000 n 0000411812 00000 n 0000411589 00000 n 0000411099 00000 n 0000400889 00000 n 0000399827 00000 n 0000411044 00000 n 0002159886 00000 n 0000410973 00000 n 0000403555 00000 n 0000403799 00000 n 0000403847 00000 n 0000404262 00000 n 0000404656 00000 n 0000405009 00000 n 0000405298 00000 n 0000408605 00000 n 0000418647 00000 n 0000418147 00000 n 0000411473 00000 n 0000411216 00000 n 0000418092 00000 n 0000418021 00000 n 0000413211 00000 n 0000413411 00000 n 0000413459 00000 n 0000413878 00000 n 0000414230 00000 n 0000526036 00000 n 0000418531 00000 n 0000418264 00000 n 0000525981 00000 n 0000528398 00000 n 0000528919 00000 n 0000528261 00000 n 0000526161 00000 n 0000528576 00000 n 0000531936 00000 n 0000532495 00000 n 0000531799 00000 n 0000529007 00000 n 0000532089 00000 n 0000532144 00000 n 0000532261 00000 n 0000532320 00000 n 0000532379 00000 n 0000532437 00000 n 0000534877 00000 n 0000534590 00000 n 0000532597 00000 n 0000534706 00000 n 0000538127 00000 n 0000537724 00000 n 0000534993 00000 n 0000537840 00000 n 0002160011 00000 n 0000541681 00000 n 0000542898 00000 n 0000541544 00000 n 0000538243 00000 n 0000541836 00000 n 0000541891 00000 n 0000541950 00000 n 0000542009 00000 n 0000542068 00000 n 0000542127 00000 n 0000542186 00000 n 0000542245 00000 n 0000542304 00000 n 0000542363 00000 n 0000542422 00000 n 0000542481 00000 n 0000542540 00000 n 0000542599 00000 n 0000542658 00000 n 0000542717 00000 n 0000542776 00000 n 0000542835 00000 n 0000546393 00000 n 0000546959 00000 n 0000546256 00000 n 0000543014 00000 n 0000546551 00000 n 0000546606 00000 n 0000546665 00000 n 0000546724 00000 n 0000546783 00000 n 0000546900 00000 n 0001879233 00000 n 0000550067 00000 n 0000549604 00000 n 0000547075 00000 n 0000549720 00000 n 0000549949 00000 n 0000550008 00000 n 0000552950 00000 n 0000552313 00000 n 0000550183 00000 n 0000552429 00000 n 0000552542 00000 n 0000552658 00000 n 0000552717 00000 n 0000552776 00000 n 0000555229 00000 n 0000555000 00000 n 0000553081 00000 n 0000555116 00000 n 0000557115 00000 n 0000556828 00000 n 0000555360 00000 n 0000556944 00000 n 0002160136 00000 n 0000558809 00000 n 0000558581 00000 n 0000557246 00000 n 0000558697 00000 n 0000560233 00000 n 0000560062 00000 n 0000558926 00000 n 0000560178 00000 n 0000562678 00000 n 0000562391 00000 n 0000560350 00000 n 0000562507 00000 n 0000564561 00000 n 0000564390 00000 n 0000562809 00000 n 0000564506 00000 n 0000567345 00000 n 0000567001 00000 n 0000564678 00000 n 0000567117 00000 n 0000569182 00000 n 0000568953 00000 n 0000567476 00000 n 0000569069 00000 n 0002160261 00000 n 0000571332 00000 n 0000571103 00000 n 0000569313 00000 n 0000571219 00000 n 0000572690 00000 n 0000572519 00000 n 0000571463 00000 n 0000572635 00000 n 0000574252 00000 n 0000574023 00000 n 0000572793 00000 n 0000574139 00000 n 0000576711 00000 n 0000576482 00000 n 0000574369 00000 n 0000576598 00000 n 0000578165 00000 n 0000577994 00000 n 0000576842 00000 n 0000578110 00000 n 0000579464 00000 n 0000579293 00000 n 0000578268 00000 n 0000579409 00000 n 0002160386 00000 n 0000582618 00000 n 0000582273 00000 n 0000579567 00000 n 0000582389 00000 n 0000584105 00000 n 0000583934 00000 n 0000582749 00000 n 0000584050 00000 n 0000586533 00000 n 0000586189 00000 n 0000584208 00000 n 0000586305 00000 n 0000588778 00000 n 0000588549 00000 n 0000586664 00000 n 0000588665 00000 n 0000590245 00000 n 0000590074 00000 n 0000588909 00000 n 0000590190 00000 n 0000594385 00000 n 0000592512 00000 n 0000592283 00000 n 0000590348 00000 n 0000592399 00000 n 0002160511 00000 n 0000598933 00000 n 0000594269 00000 n 0000592643 00000 n 0000598585 00000 n 0000598640 00000 n 0000598757 00000 n 0000598816 00000 n 0000595329 00000 n 0000595524 00000 n 0000595572 00000 n 0000595957 00000 n 0000596243 00000 n 0000601687 00000 n 0000601340 00000 n 0000599079 00000 n 0000601456 00000 n 0000601511 00000 n 0000601570 00000 n 0000604009 00000 n 0000603722 00000 n 0000601818 00000 n 0000603838 00000 n 0000605855 00000 n 0000605684 00000 n 0000604140 00000 n 0000605800 00000 n 0000608590 00000 n 0000608303 00000 n 0000605958 00000 n 0000608419 00000 n 0000611047 00000 n 0000611937 00000 n 0000611431 00000 n 0000610910 00000 n 0000608721 00000 n 0000611202 00000 n 0002160636 00000 n 0000721838 00000 n 0000611821 00000 n 0000611547 00000 n 0000721783 00000 n 0000723888 00000 n 0000724044 00000 n 0000724205 00000 n 0000727350 00000 n 0000724653 00000 n 0000723733 00000 n 0000721964 00000 n 0000724366 00000 n 0001879174 00000 n 0001879467 00000 n 0000733232 00000 n 0000727234 00000 n 0000724755 00000 n 0000732946 00000 n 0000729656 00000 n 0000729848 00000 n 0000729896 00000 n 0000730223 00000 n 0000730538 00000 n 0000734807 00000 n 0000740904 00000 n 0000734691 00000 n 0000733393 00000 n 0000740497 00000 n 0000740668 00000 n 0000740727 00000 n 0000740786 00000 n 0000740845 00000 n 0000736839 00000 n 0000737031 00000 n 0000737079 00000 n 0000737456 00000 n 0000737803 00000 n 0000742317 00000 n 0000742146 00000 n 0000741065 00000 n 0000742262 00000 n 0000743681 00000 n 0000743510 00000 n 0000742420 00000 n 0000743626 00000 n 0002160761 00000 n 0000744923 00000 n 0000744752 00000 n 0000743784 00000 n 0000744868 00000 n 0000746217 00000 n 0000780515 00000 n 0000746101 00000 n 0000745026 00000 n 0000780402 00000 n 0000782875 00000 n 0000782353 00000 n 0000780670 00000 n 0000782469 00000 n 0000782640 00000 n 0000782699 00000 n 0000782757 00000 n 0000782816 00000 n 0000784364 00000 n 0000784193 00000 n 0000782992 00000 n 0000784309 00000 n 0000785873 00000 n 0000785702 00000 n 0000784467 00000 n 0000785818 00000 n 0000788007 00000 n 0000853145 00000 n 0000787891 00000 n 0000785976 00000 n 0000852620 00000 n 0000852733 00000 n 0000852792 00000 n 0000852851 00000 n 0000852910 00000 n 0000852969 00000 n 0000853028 00000 n 0000853087 00000 n 0002160886 00000 n 0000855376 00000 n 0000855205 00000 n 0000853300 00000 n 0000855321 00000 n 0000856753 00000 n 0000856582 00000 n 0000855493 00000 n 0000856698 00000 n 0000859697 00000 n 0000858054 00000 n 0000857883 00000 n 0000856856 00000 n 0000857999 00000 n 0000968645 00000 n 0000859581 00000 n 0000858157 00000 n 0000968474 00000 n 0000971882 00000 n 0000971595 00000 n 0000968814 00000 n 0000971711 00000 n 0000975402 00000 n 0000974823 00000 n 0000971999 00000 n 0000974939 00000 n 0000975110 00000 n 0000975169 00000 n 0002158182 00000 n 0002161011 00000 n 0000977052 00000 n 0000976765 00000 n 0000975534 00000 n 0000976881 00000 n 0000979270 00000 n 0000978763 00000 n 0000978298 00000 n 0000977154 00000 n 0000978414 00000 n 0000978469 00000 n 0000978528 00000 n 0000978587 00000 n 0000978646 00000 n 0001034386 00000 n 0000979154 00000 n 0000978880 00000 n 0001034331 00000 n 0001036935 00000 n 0001037097 00000 n 0001037250 00000 n 0001037411 00000 n 0001037766 00000 n 0001037923 00000 n 0001038947 00000 n 0001058152 00000 n 0001038370 00000 n 0001036744 00000 n 0001034512 00000 n 0001038083 00000 n 0001037589 00000 n 0001878643 00000 n 0001878761 00000 n 0001054598 00000 n 0001054716 00000 n 0001038831 00000 n 0001038458 00000 n 0001054543 00000 n 0001054657 00000 n 0001041794 00000 n 0001042031 00000 n 0001042079 00000 n 0001042504 00000 n 0001042893 00000 n 0001043304 00000 n 0001043686 00000 n 0001044037 00000 n 0001044392 00000 n 0001047708 00000 n 0001050359 00000 n 0001061902 00000 n 0001058952 00000 n 0001058015 00000 n 0001054834 00000 n 0001058307 00000 n 0001058362 00000 n 0001058421 00000 n 0001058480 00000 n 0001058539 00000 n 0001058598 00000 n 0001058657 00000 n 0001058889 00000 n 0002161136 00000 n 0001062584 00000 n 0001061765 00000 n 0001059068 00000 n 0001062062 00000 n 0001062349 00000 n 0001062408 00000 n 0001062467 00000 n 0001062526 00000 n 0001065061 00000 n 0001065567 00000 n 0001064924 00000 n 0001062700 00000 n 0001065216 00000 n 0001065503 00000 n 0001068206 00000 n 0001067456 00000 n 0001065683 00000 n 0001067572 00000 n 0001070853 00000 n 0001070335 00000 n 0001068308 00000 n 0001070451 00000 n 0001072683 00000 n 0001073069 00000 n 0001072546 00000 n 0001070984 00000 n 0001072840 00000 n 0001075260 00000 n 0001074799 00000 n 0001073200 00000 n 0001074915 00000 n 0002161261 00000 n 0001077676 00000 n 0001079489 00000 n 0001077835 00000 n 0001087911 00000 n 0001078455 00000 n 0001077530 00000 n 0001075391 00000 n 0001077992 00000 n 0001078163 00000 n 0001078222 00000 n 0001078281 00000 n 0001078339 00000 n 0001096677 00000 n 0001096736 00000 n 0001096795 00000 n 0001079373 00000 n 0001078586 00000 n 0001096622 00000 n 0001081492 00000 n 0001081690 00000 n 0001081738 00000 n 0001082067 00000 n 0001082464 00000 n 0001082792 00000 n 0001083110 00000 n 0001085490 00000 n 0001089339 00000 n 0001089576 00000 n 0001089624 00000 n 0001089883 00000 n 0001090298 00000 n 0001090614 00000 n 0001090935 00000 n 0001092857 00000 n 0001100089 00000 n 0001099569 00000 n 0001096942 00000 n 0001099685 00000 n 0001099914 00000 n 0001099973 00000 n 0001100032 00000 n 0001108023 00000 n 0001102368 00000 n 0001116369 00000 n 0001110672 00000 n 0001108767 00000 n 0001102231 00000 n 0001100205 00000 n 0001108182 00000 n 0001108237 00000 n 0001108296 00000 n 0001108355 00000 n 0001108472 00000 n 0001108531 00000 n 0001108590 00000 n 0001108649 00000 n 0001108708 00000 n 0001103966 00000 n 0001104205 00000 n 0001104253 00000 n 0001104658 00000 n 0001104969 00000 n 0001116529 00000 n 0001116980 00000 n 0001110526 00000 n 0001108913 00000 n 0001116692 00000 n 0001116747 00000 n 0001112349 00000 n 0001112551 00000 n 0001112599 00000 n 0001113004 00000 n 0001113315 00000 n 0001118521 00000 n 0001118681 00000 n 0001126269 00000 n 0001119011 00000 n 0001118375 00000 n 0001117112 00000 n 0001118840 00000 n 0002161386 00000 n 0001120665 00000 n 0001126431 00000 n 0001127054 00000 n 0001120519 00000 n 0001119127 00000 n 0001126591 00000 n 0001126646 00000 n 0001126879 00000 n 0001126938 00000 n 0001126996 00000 n 0001121814 00000 n 0001122068 00000 n 0001122116 00000 n 0001122525 00000 n 0001122867 00000 n 0001130758 00000 n 0001130235 00000 n 0001127200 00000 n 0001130351 00000 n 0001130406 00000 n 0001130465 00000 n 0001130524 00000 n 0001130699 00000 n 0001133795 00000 n 0001134474 00000 n 0001133658 00000 n 0001130874 00000 n 0001133950 00000 n 0001134063 00000 n 0001134122 00000 n 0001134181 00000 n 0001134240 00000 n 0001134299 00000 n 0001134415 00000 n 0001137502 00000 n 0001136980 00000 n 0001134576 00000 n 0001137096 00000 n 0001137267 00000 n 0001137326 00000 n 0001137385 00000 n 0001137444 00000 n 0001139944 00000 n 0001139478 00000 n 0001137633 00000 n 0001139594 00000 n 0001139649 00000 n 0001139708 00000 n 0001139767 00000 n 0001139826 00000 n 0001139885 00000 n 0001142279 00000 n 0001141992 00000 n 0001140061 00000 n 0001142108 00000 n 0002161511 00000 n 0001146354 00000 n 0001145835 00000 n 0001142410 00000 n 0001145951 00000 n 0001148252 00000 n 0001147966 00000 n 0001146470 00000 n 0001148082 00000 n 0001150441 00000 n 0001150270 00000 n 0001148369 00000 n 0001150386 00000 n 0001152887 00000 n 0001152600 00000 n 0001150558 00000 n 0001152716 00000 n 0001155445 00000 n 0001155157 00000 n 0001153018 00000 n 0001155273 00000 n 0001155386 00000 n 0001158062 00000 n 0001157833 00000 n 0001155576 00000 n 0001157949 00000 n 0002161636 00000 n 0001160766 00000 n 0001161511 00000 n 0001160629 00000 n 0001158193 00000 n 0001160928 00000 n 0001161099 00000 n 0001161158 00000 n 0001161217 00000 n 0001161276 00000 n 0001161335 00000 n 0001161394 00000 n 0001164661 00000 n 0001164815 00000 n 0001165198 00000 n 0001164515 00000 n 0001161642 00000 n 0001164970 00000 n 0001167807 00000 n 0001168200 00000 n 0001167670 00000 n 0001165329 00000 n 0001167971 00000 n 0001170333 00000 n 0001170104 00000 n 0001168316 00000 n 0001170220 00000 n 0001174040 00000 n 0001173811 00000 n 0001170464 00000 n 0001173927 00000 n 0001176956 00000 n 0001177403 00000 n 0001176819 00000 n 0001174156 00000 n 0001177116 00000 n 0001177345 00000 n 0002161761 00000 n 0001179921 00000 n 0001180364 00000 n 0001179784 00000 n 0001177519 00000 n 0001180076 00000 n 0001180189 00000 n 0001182275 00000 n 0001182608 00000 n 0001182138 00000 n 0001180480 00000 n 0001182437 00000 n 0001184839 00000 n 0001185001 00000 n 0001185279 00000 n 0001184693 00000 n 0001182739 00000 n 0001185166 00000 n 0001187297 00000 n 0001187625 00000 n 0001187160 00000 n 0001185410 00000 n 0001187454 00000 n 0001189024 00000 n 0001188795 00000 n 0001187756 00000 n 0001188911 00000 n 0001194190 00000 n 0001191765 00000 n 0001191536 00000 n 0001189141 00000 n 0001191652 00000 n 0002161886 00000 n 0001194580 00000 n 0001194053 00000 n 0001191896 00000 n 0001194346 00000 n 0001194517 00000 n 0001196737 00000 n 0001197069 00000 n 0001196600 00000 n 0001194711 00000 n 0001196898 00000 n 0001199554 00000 n 0001200182 00000 n 0001199417 00000 n 0001197200 00000 n 0001199716 00000 n 0001199829 00000 n 0001199888 00000 n 0001199947 00000 n 0001200006 00000 n 0001200065 00000 n 0001202415 00000 n 0001202070 00000 n 0001200313 00000 n 0001202186 00000 n 0001205040 00000 n 0001205202 00000 n 0001205363 00000 n 0001205989 00000 n 0001204885 00000 n 0001202546 00000 n 0001205524 00000 n 0001205637 00000 n 0001205696 00000 n 0001205755 00000 n 0001205814 00000 n 0001207547 00000 n 0001207260 00000 n 0001206120 00000 n 0001207376 00000 n 0002162011 00000 n 0001209998 00000 n 0001210157 00000 n 0001210488 00000 n 0001209852 00000 n 0001207664 00000 n 0001210313 00000 n 0001210425 00000 n 0001212667 00000 n 0001212496 00000 n 0001210619 00000 n 0001212612 00000 n 0001217627 00000 n 0001215231 00000 n 0001214947 00000 n 0001212784 00000 n 0001215063 00000 n 0001217901 00000 n 0001217490 00000 n 0001215362 00000 n 0001217783 00000 n 0001217838 00000 n 0001222862 00000 n 0001220576 00000 n 0001220347 00000 n 0001218018 00000 n 0001220463 00000 n 0001223193 00000 n 0001222725 00000 n 0001220707 00000 n 0001223022 00000 n 0002162136 00000 n 0001225499 00000 n 0001225270 00000 n 0001223324 00000 n 0001225386 00000 n 0001227266 00000 n 0001246170 00000 n 0001246558 00000 n 0001227129 00000 n 0001225630 00000 n 0001246328 00000 n 0001246383 00000 n 0001227682 00000 n 0001227968 00000 n 0001228016 00000 n 0001247774 00000 n 0001254928 00000 n 0001259241 00000 n 0001259571 00000 n 0001247637 00000 n 0001246704 00000 n 0001259400 00000 n 0001248194 00000 n 0001248480 00000 n 0001248528 00000 n 0001255343 00000 n 0001255629 00000 n 0001255677 00000 n 0001261970 00000 n 0001261683 00000 n 0001259732 00000 n 0001261799 00000 n 0001264045 00000 n 0001263816 00000 n 0001262101 00000 n 0001263932 00000 n 0001267133 00000 n 0001267297 00000 n 0001268340 00000 n 0001266987 00000 n 0001264162 00000 n 0001267462 00000 n 0001267575 00000 n 0001267634 00000 n 0001267693 00000 n 0001267752 00000 n 0001267811 00000 n 0001267870 00000 n 0001267929 00000 n 0001267988 00000 n 0001268047 00000 n 0001268106 00000 n 0001268165 00000 n 0001268224 00000 n 0002162261 00000 n 0001269670 00000 n 0001269499 00000 n 0001268456 00000 n 0001269615 00000 n 0001272401 00000 n 0001271997 00000 n 0001269773 00000 n 0001272113 00000 n 0001272226 00000 n 0001272285 00000 n 0001274246 00000 n 0001274017 00000 n 0001272532 00000 n 0001274133 00000 n 0001276933 00000 n 0001276704 00000 n 0001274377 00000 n 0001276820 00000 n 0001279119 00000 n 0001279681 00000 n 0001278982 00000 n 0001277064 00000 n 0001279278 00000 n 0001878820 00000 n 0001281992 00000 n 0001281707 00000 n 0001279812 00000 n 0001281823 00000 n 0001281935 00000 n 0002162386 00000 n 0001284054 00000 n 0001283825 00000 n 0001282109 00000 n 0001283941 00000 n 0001287269 00000 n 0001286981 00000 n 0001284171 00000 n 0001287097 00000 n 0001287152 00000 n 0001291193 00000 n 0001290845 00000 n 0001287385 00000 n 0001290961 00000 n 0002158534 00000 n 0001293129 00000 n 0001292958 00000 n 0001291324 00000 n 0001293074 00000 n 0001295409 00000 n 0001295061 00000 n 0001293246 00000 n 0001295177 00000 n 0001297364 00000 n 0001297016 00000 n 0001295540 00000 n 0001297132 00000 n 0002162511 00000 n 0001305874 00000 n 0001299864 00000 n 0001306501 00000 n 0001299727 00000 n 0001297495 00000 n 0001306034 00000 n 0001306266 00000 n 0001306325 00000 n 0001306384 00000 n 0001306443 00000 n 0001301406 00000 n 0001301603 00000 n 0001301651 00000 n 0001302064 00000 n 0001302386 00000 n 0001308269 00000 n 0001308098 00000 n 0001306647 00000 n 0001308214 00000 n 0001316801 00000 n 0001310779 00000 n 0001317310 00000 n 0001310642 00000 n 0001308386 00000 n 0001316960 00000 n 0001317074 00000 n 0001317133 00000 n 0001317192 00000 n 0001317251 00000 n 0001312333 00000 n 0001312530 00000 n 0001312578 00000 n 0001312991 00000 n 0001313313 00000 n 0001318601 00000 n 0001398390 00000 n 0001318485 00000 n 0001317471 00000 n 0001398335 00000 n 0001400027 00000 n 0001406576 00000 n 0001399911 00000 n 0001398531 00000 n 0001406285 00000 n 0001406517 00000 n 0001401403 00000 n 0001401636 00000 n 0001401684 00000 n 0001402105 00000 n 0001402430 00000 n 0001409965 00000 n 0001409265 00000 n 0001406694 00000 n 0001409381 00000 n 0001409552 00000 n 0001409611 00000 n 0001409670 00000 n 0001409729 00000 n 0001409788 00000 n 0002162636 00000 n 0001411910 00000 n 0001411680 00000 n 0001410081 00000 n 0001411796 00000 n 0001413668 00000 n 0001413380 00000 n 0001412041 00000 n 0001413496 00000 n 0001416426 00000 n 0001416020 00000 n 0001413785 00000 n 0001416136 00000 n 0001419225 00000 n 0001419054 00000 n 0001416528 00000 n 0001419170 00000 n 0001422013 00000 n 0001422173 00000 n 0001422331 00000 n 0001422490 00000 n 0001424614 00000 n 0001422994 00000 n 0001421849 00000 n 0001419342 00000 n 0001422644 00000 n 0001422758 00000 n 0001422817 00000 n 0001422876 00000 n 0001422935 00000 n 0001879408 00000 n 0001879291 00000 n 0001434525 00000 n 0001424498 00000 n 0001423110 00000 n 0001434411 00000 n 0002162761 00000 n 0001437769 00000 n 0001437303 00000 n 0001434679 00000 n 0001437419 00000 n 0001437474 00000 n 0001437533 00000 n 0001437592 00000 n 0001440613 00000 n 0001440773 00000 n 0001441108 00000 n 0001440467 00000 n 0001437885 00000 n 0001440935 00000 n 0001443320 00000 n 0001443149 00000 n 0001441239 00000 n 0001443265 00000 n 0001445576 00000 n 0001446105 00000 n 0001445439 00000 n 0001443423 00000 n 0001445744 00000 n 0001445858 00000 n 0001445916 00000 n 0002157832 00000 n 0001445979 00000 n 0001446042 00000 n 0001879584 00000 n 0001448681 00000 n 0001449914 00000 n 0001448544 00000 n 0001446251 00000 n 0001448846 00000 n 0001448901 00000 n 0001448965 00000 n 0001449029 00000 n 0001449093 00000 n 0001449157 00000 n 0001449221 00000 n 0001449285 00000 n 0001449349 00000 n 0001449413 00000 n 0001449477 00000 n 0001449541 00000 n 0001449605 00000 n 0001449669 00000 n 0001449733 00000 n 0001452349 00000 n 0001451883 00000 n 0001450046 00000 n 0001451999 00000 n 0001452113 00000 n 0001452172 00000 n 0001452231 00000 n 0001452290 00000 n 0002162886 00000 n 0001454508 00000 n 0001454899 00000 n 0001454371 00000 n 0001452465 00000 n 0001454668 00000 n 0001454782 00000 n 0001454841 00000 n 0001456878 00000 n 0001457331 00000 n 0001456741 00000 n 0001455016 00000 n 0001457040 00000 n 0001457095 00000 n 0001457213 00000 n 0001457272 00000 n 0001460249 00000 n 0001460019 00000 n 0001457448 00000 n 0001460135 00000 n 0001462406 00000 n 0001496256 00000 n 0001462290 00000 n 0001460380 00000 n 0001496083 00000 n 0001498700 00000 n 0001563067 00000 n 0001498584 00000 n 0001496425 00000 n 0001562720 00000 n 0001562775 00000 n 0001562834 00000 n 0001562891 00000 n 0001562950 00000 n 0001563009 00000 n 0001566291 00000 n 0001565885 00000 n 0001563222 00000 n 0001566001 00000 n 0002163011 00000 n 0001569434 00000 n 0001569087 00000 n 0001566422 00000 n 0001569203 00000 n 0001569258 00000 n 0001569317 00000 n 0001571822 00000 n 0001571593 00000 n 0001569565 00000 n 0001571709 00000 n 0001574537 00000 n 0001574307 00000 n 0001571939 00000 n 0001574423 00000 n 0001576180 00000 n 0001575950 00000 n 0001574668 00000 n 0001576066 00000 n 0001578702 00000 n 0001578862 00000 n 0001579188 00000 n 0001578556 00000 n 0001576297 00000 n 0001579017 00000 n 0001579130 00000 n 0001581758 00000 n 0001582203 00000 n 0001581621 00000 n 0001579304 00000 n 0001581912 00000 n 0001581967 00000 n 0002163136 00000 n 0001585195 00000 n 0001584670 00000 n 0001582334 00000 n 0001584786 00000 n 0001584959 00000 n 0001585018 00000 n 0001585077 00000 n 0001585136 00000 n 0001586722 00000 n 0001587823 00000 n 0001586935 00000 n 0001586585 00000 n 0001585297 00000 n 0001586880 00000 n 0001601540 00000 n 0001587707 00000 n 0001587037 00000 n 0001601485 00000 n 0001725161 00000 n 0001603537 00000 n 0001725440 00000 n 0001603400 00000 n 0001601666 00000 n 0001725326 00000 n 0001727256 00000 n 0001727417 00000 n 0001727987 00000 n 0001727110 00000 n 0001725594 00000 n 0001727579 00000 n 0001731466 00000 n 0001731119 00000 n 0001728089 00000 n 0001731235 00000 n 0001731290 00000 n 0001731408 00000 n 0002163261 00000 n 0001734578 00000 n 0001734964 00000 n 0001734441 00000 n 0001731568 00000 n 0001734733 00000 n 0001734906 00000 n 0001736793 00000 n 0001736445 00000 n 0001735080 00000 n 0001736561 00000 n 0001736734 00000 n 0001739938 00000 n 0001739531 00000 n 0001736895 00000 n 0001739647 00000 n 0001739761 00000 n 0001739879 00000 n 0001743059 00000 n 0001742593 00000 n 0001740054 00000 n 0001742709 00000 n 0001742764 00000 n 0001742823 00000 n 0001743000 00000 n 0001746137 00000 n 0001745495 00000 n 0001743175 00000 n 0001745611 00000 n 0001745783 00000 n 0001745842 00000 n 0001745901 00000 n 0001746019 00000 n 0001748944 00000 n 0001748481 00000 n 0001746253 00000 n 0001748597 00000 n 0001748829 00000 n 0002163386 00000 n 0001752443 00000 n 0001751977 00000 n 0001749060 00000 n 0001752093 00000 n 0001752325 00000 n 0001756074 00000 n 0001755492 00000 n 0001752559 00000 n 0001755608 00000 n 0001755838 00000 n 0001755897 00000 n 0001755956 00000 n 0001756015 00000 n 0001759494 00000 n 0001759029 00000 n 0001756176 00000 n 0001759145 00000 n 0001759200 00000 n 0001759259 00000 n 0001759376 00000 n 0001759435 00000 n 0001762009 00000 n 0001761484 00000 n 0001759610 00000 n 0001761600 00000 n 0001761773 00000 n 0001761950 00000 n 0001764856 00000 n 0001764097 00000 n 0001762111 00000 n 0001764213 00000 n 0001764327 00000 n 0001764444 00000 n 0001764503 00000 n 0001764562 00000 n 0001764621 00000 n 0001764680 00000 n 0001764739 00000 n 0001767679 00000 n 0001767154 00000 n 0001764958 00000 n 0001767270 00000 n 0001767502 00000 n 0002163511 00000 n 0001771138 00000 n 0001771535 00000 n 0001771001 00000 n 0001767795 00000 n 0001771303 00000 n 0001771476 00000 n 0001773866 00000 n 0001774492 00000 n 0001773729 00000 n 0001771651 00000 n 0001774021 00000 n 0001774429 00000 n 0001777211 00000 n 0001776570 00000 n 0001774594 00000 n 0001776686 00000 n 0001777152 00000 n 0001779781 00000 n 0001779256 00000 n 0001777313 00000 n 0001779372 00000 n 0001779486 00000 n 0001779604 00000 n 0001782268 00000 n 0001781685 00000 n 0001779883 00000 n 0001781801 00000 n 0001781915 00000 n 0001782033 00000 n 0001782210 00000 n 0001785352 00000 n 0001784945 00000 n 0001782370 00000 n 0001785061 00000 n 0001785175 00000 n 0001785293 00000 n 0002163636 00000 n 0001788215 00000 n 0001788661 00000 n 0001788078 00000 n 0001785468 00000 n 0001788370 00000 n 0001788425 00000 n 0001788543 00000 n 0001791280 00000 n 0001791844 00000 n 0001791143 00000 n 0001788777 00000 n 0001791435 00000 n 0001794995 00000 n 0001794529 00000 n 0001791960 00000 n 0001794645 00000 n 0001794759 00000 n 0001797508 00000 n 0001798201 00000 n 0001797371 00000 n 0001795126 00000 n 0001797676 00000 n 0001797967 00000 n 0001798025 00000 n 0001798084 00000 n 0001798143 00000 n 0001801350 00000 n 0001800826 00000 n 0001798317 00000 n 0001800942 00000 n 0001801173 00000 n 0001803733 00000 n 0001804299 00000 n 0001803596 00000 n 0001801452 00000 n 0001803891 00000 n 0001804063 00000 n 0001804122 00000 n 0001804240 00000 n 0002163761 00000 n 0001807440 00000 n 0001807092 00000 n 0001804401 00000 n 0001807208 00000 n 0001807263 00000 n 0001807381 00000 n 0001810990 00000 n 0001810701 00000 n 0001807542 00000 n 0001810817 00000 n 0001810931 00000 n 0001812973 00000 n 0001813428 00000 n 0001812836 00000 n 0001811092 00000 n 0001813137 00000 n 0001816442 00000 n 0001816035 00000 n 0001813530 00000 n 0001816151 00000 n 0001817981 00000 n 0001817692 00000 n 0001816544 00000 n 0001817808 00000 n 0001819360 00000 n 0001819071 00000 n 0001818083 00000 n 0001819187 00000 n 0002163886 00000 n 0001820144 00000 n 0001819973 00000 n 0001819448 00000 n 0001820089 00000 n 0001820930 00000 n 0001820759 00000 n 0001820246 00000 n 0001820875 00000 n 0001821789 00000 n 0001821618 00000 n 0001821032 00000 n 0001821734 00000 n 0001822755 00000 n 0001822525 00000 n 0001821891 00000 n 0001822641 00000 n 0001823603 00000 n 0001823432 00000 n 0001822857 00000 n 0001823548 00000 n 0001824671 00000 n 0001824441 00000 n 0001823705 00000 n 0001824557 00000 n 0002164011 00000 n 0001825531 00000 n 0001825360 00000 n 0001824773 00000 n 0001825476 00000 n 0001826452 00000 n 0001826281 00000 n 0001825633 00000 n 0001826397 00000 n 0001827256 00000 n 0001827085 00000 n 0001826554 00000 n 0001827201 00000 n 0001828174 00000 n 0001828003 00000 n 0001827358 00000 n 0001828119 00000 n 0001829056 00000 n 0001828885 00000 n 0001828276 00000 n 0001829001 00000 n 0001829893 00000 n 0001829722 00000 n 0001829158 00000 n 0001829838 00000 n 0002164136 00000 n 0001830774 00000 n 0001830603 00000 n 0001829995 00000 n 0001830719 00000 n 0001831704 00000 n 0001831533 00000 n 0001830876 00000 n 0001831649 00000 n 0001832868 00000 n 0001832638 00000 n 0001831806 00000 n 0001832754 00000 n 0001834716 00000 n 0001834368 00000 n 0001832970 00000 n 0001834484 00000 n 0001835943 00000 n 0001835714 00000 n 0001834818 00000 n 0001835830 00000 n 0001837002 00000 n 0001836831 00000 n 0001836059 00000 n 0001836947 00000 n 0002164261 00000 n 0001838635 00000 n 0001838346 00000 n 0001837118 00000 n 0001838462 00000 n 0001839736 00000 n 0001839565 00000 n 0001838751 00000 n 0001839681 00000 n 0001841294 00000 n 0001841005 00000 n 0001839852 00000 n 0001841121 00000 n 0001842650 00000 n 0001842420 00000 n 0001841410 00000 n 0001842536 00000 n 0001844033 00000 n 0001843803 00000 n 0001842766 00000 n 0001843919 00000 n 0001845494 00000 n 0001845264 00000 n 0001844149 00000 n 0001845380 00000 n 0002164386 00000 n 0001846738 00000 n 0001846508 00000 n 0001845610 00000 n 0001846624 00000 n 0001847957 00000 n 0001847786 00000 n 0001846854 00000 n 0001847902 00000 n 0001848754 00000 n 0001848583 00000 n 0001848073 00000 n 0001848699 00000 n 0001851208 00000 n 0001850860 00000 n 0001848870 00000 n 0001850976 00000 n 0001854411 00000 n 0001853827 00000 n 0001851310 00000 n 0001853943 00000 n 0001856296 00000 n 0001856008 00000 n 0001854527 00000 n 0001856124 00000 n 0001856238 00000 n 0002164511 00000 n 0001858999 00000 n 0001859155 00000 n 0001859314 00000 n 0001859822 00000 n 0001858844 00000 n 0001856412 00000 n 0001859472 00000 n 0001862270 00000 n 0001862715 00000 n 0001862133 00000 n 0001859910 00000 n 0001862425 00000 n 0001864755 00000 n 0001864466 00000 n 0001862832 00000 n 0001864582 00000 n 0001866391 00000 n 0001866102 00000 n 0001864872 00000 n 0001866218 00000 n 0001868322 00000 n 0001868830 00000 n 0001868185 00000 n 0001866479 00000 n 0001868481 00000 n 0001868654 00000 n 0001868713 00000 n 0001870721 00000 n 0001870550 00000 n 0001868948 00000 n 0001870666 00000 n 0002164636 00000 n 0001871646 00000 n 0001871475 00000 n 0001870838 00000 n 0001871591 00000 n 0001872393 00000 n 0001872547 00000 n 0001872712 00000 n 0001872871 00000 n 0001873027 00000 n 0001873190 00000 n 0001873351 00000 n 0001873626 00000 n 0001872202 00000 n 0001871748 00000 n 0001873512 00000 n 0001873567 00000 n 0001875033 00000 n 0001875200 00000 n 0001875378 00000 n 0001875545 00000 n 0001875726 00000 n 0001875892 00000 n 0001876085 00000 n 0001876264 00000 n 0001876490 00000 n 0001876660 00000 n 0001876875 00000 n 0001877102 00000 n 0001877280 00000 n 0001877505 00000 n 0001877728 00000 n 0001877894 00000 n 0001879642 00000 n 0001874761 00000 n 0001873714 00000 n 0001878117 00000 n 0001878172 00000 n 0001878702 00000 n 0001878879 00000 n 0001878938 00000 n 0001878997 00000 n 0001879115 00000 n 0001883192 00000 n 0001883344 00000 n 0001883496 00000 n 0001883648 00000 n 0001883800 00000 n 0001883951 00000 n 0001884103 00000 n 0001884254 00000 n 0001884406 00000 n 0001884557 00000 n 0001884707 00000 n 0001884857 00000 n 0001885007 00000 n 0001885157 00000 n 0001885309 00000 n 0001885459 00000 n 0001885610 00000 n 0001885760 00000 n 0001885911 00000 n 0001886063 00000 n 0001886212 00000 n 0001886362 00000 n 0001886512 00000 n 0001886663 00000 n 0001886814 00000 n 0001886963 00000 n 0001887113 00000 n 0001887263 00000 n 0001887414 00000 n 0001887565 00000 n 0001887717 00000 n 0001887869 00000 n 0001888019 00000 n 0001888169 00000 n 0001888319 00000 n 0001888469 00000 n 0001888620 00000 n 0001888771 00000 n 0001888923 00000 n 0001889074 00000 n 0001889226 00000 n 0001889377 00000 n 0001889528 00000 n 0001889679 00000 n 0001889830 00000 n 0001889981 00000 n 0001890132 00000 n 0001890282 00000 n 0001890434 00000 n 0001890585 00000 n 0001890737 00000 n 0001890889 00000 n 0001891041 00000 n 0001891193 00000 n 0001891345 00000 n 0001891497 00000 n 0001891647 00000 n 0001891797 00000 n 0001891948 00000 n 0001892098 00000 n 0001892250 00000 n 0001892400 00000 n 0001892550 00000 n 0001892701 00000 n 0001892853 00000 n 0001893003 00000 n 0001893154 00000 n 0001893304 00000 n 0001893455 00000 n 0001893606 00000 n 0001893756 00000 n 0001893907 00000 n 0001894058 00000 n 0001894209 00000 n 0001894360 00000 n 0001894511 00000 n 0001894660 00000 n 0001894809 00000 n 0001894959 00000 n 0001895109 00000 n 0001895259 00000 n 0001895409 00000 n 0001895559 00000 n 0001895710 00000 n 0001895862 00000 n 0001896014 00000 n 0001896164 00000 n 0001896314 00000 n 0001896463 00000 n 0001896614 00000 n 0001896765 00000 n 0001896914 00000 n 0001897062 00000 n 0001897211 00000 n 0001897360 00000 n 0001897509 00000 n 0001897658 00000 n 0001897808 00000 n 0001897958 00000 n 0001898108 00000 n 0001898257 00000 n 0001898408 00000 n 0001898559 00000 n 0001898709 00000 n 0001898860 00000 n 0001899011 00000 n 0001899160 00000 n 0001899312 00000 n 0001899464 00000 n 0001899616 00000 n 0001899768 00000 n 0001899920 00000 n 0001900072 00000 n 0001900224 00000 n 0001900376 00000 n 0001900526 00000 n 0001900677 00000 n 0001900828 00000 n 0001900979 00000 n 0001901131 00000 n 0001901283 00000 n 0001901434 00000 n 0001901585 00000 n 0001901736 00000 n 0001901887 00000 n 0001902037 00000 n 0001902188 00000 n 0001902339 00000 n 0001902491 00000 n 0001902643 00000 n 0001902795 00000 n 0001902946 00000 n 0001903097 00000 n 0001903248 00000 n 0001903400 00000 n 0001903550 00000 n 0001903702 00000 n 0001903851 00000 n 0001904000 00000 n 0001904149 00000 n 0001904299 00000 n 0001904450 00000 n 0001904601 00000 n 0001904752 00000 n 0001904903 00000 n 0001905053 00000 n 0001905204 00000 n 0001905356 00000 n 0001905507 00000 n 0001905659 00000 n 0001905810 00000 n 0001905961 00000 n 0001906113 00000 n 0001906265 00000 n 0001906417 00000 n 0001906569 00000 n 0001906720 00000 n 0001906870 00000 n 0001907019 00000 n 0001907170 00000 n 0001907321 00000 n 0001907473 00000 n 0001907623 00000 n 0001907773 00000 n 0001907922 00000 n 0001908073 00000 n 0001908224 00000 n 0001908375 00000 n 0001908526 00000 n 0001908678 00000 n 0001908829 00000 n 0001908981 00000 n 0001909132 00000 n 0001909283 00000 n 0001909434 00000 n 0001909585 00000 n 0001909736 00000 n 0001909887 00000 n 0001910039 00000 n 0001910190 00000 n 0001910342 00000 n 0001910493 00000 n 0001910645 00000 n 0001910796 00000 n 0001910948 00000 n 0001911100 00000 n 0001911252 00000 n 0001911403 00000 n 0001911555 00000 n 0001911707 00000 n 0001911859 00000 n 0001912008 00000 n 0001912159 00000 n 0001912310 00000 n 0001912462 00000 n 0001912613 00000 n 0001912765 00000 n 0001912917 00000 n 0001913067 00000 n 0001913218 00000 n 0001913367 00000 n 0001913516 00000 n 0001913665 00000 n 0001913813 00000 n 0001913962 00000 n 0001914111 00000 n 0001918165 00000 n 0001914314 00000 n 0001881210 00000 n 0001879730 00000 n 0001914259 00000 n 0001918317 00000 n 0001918469 00000 n 0001918620 00000 n 0001918771 00000 n 0001918922 00000 n 0001919074 00000 n 0001919226 00000 n 0001919378 00000 n 0001919530 00000 n 0001919681 00000 n 0001919832 00000 n 0001919984 00000 n 0001920136 00000 n 0001920288 00000 n 0001920438 00000 n 0001920588 00000 n 0001920738 00000 n 0001920889 00000 n 0001921041 00000 n 0001921192 00000 n 0001921342 00000 n 0001921493 00000 n 0001921643 00000 n 0001921795 00000 n 0001921946 00000 n 0001922096 00000 n 0001922248 00000 n 0001922400 00000 n 0001922551 00000 n 0001922702 00000 n 0001922853 00000 n 0001923003 00000 n 0001923155 00000 n 0001923306 00000 n 0001923458 00000 n 0001923607 00000 n 0001923758 00000 n 0001923909 00000 n 0001924060 00000 n 0001924210 00000 n 0001924362 00000 n 0001924513 00000 n 0001924665 00000 n 0001924816 00000 n 0001924966 00000 n 0001925117 00000 n 0001925268 00000 n 0001925419 00000 n 0001925571 00000 n 0001925723 00000 n 0001925875 00000 n 0001926027 00000 n 0001926177 00000 n 0001926327 00000 n 0001926477 00000 n 0001926627 00000 n 0001926778 00000 n 0001926929 00000 n 0001927080 00000 n 0001927230 00000 n 0001927381 00000 n 0001927533 00000 n 0001927684 00000 n 0001927836 00000 n 0001927988 00000 n 0001928140 00000 n 0001928292 00000 n 0001928444 00000 n 0001928596 00000 n 0001928748 00000 n 0001928900 00000 n 0001929052 00000 n 0001929204 00000 n 0001929356 00000 n 0001929508 00000 n 0001929660 00000 n 0001929812 00000 n 0001929963 00000 n 0001930115 00000 n 0001930265 00000 n 0001930416 00000 n 0001930568 00000 n 0001930720 00000 n 0001930871 00000 n 0001931022 00000 n 0001931174 00000 n 0001931323 00000 n 0001931473 00000 n 0001931624 00000 n 0001931776 00000 n 0001931928 00000 n 0001932079 00000 n 0001932231 00000 n 0001932383 00000 n 0001932534 00000 n 0001932684 00000 n 0001932834 00000 n 0001932983 00000 n 0001933132 00000 n 0001933281 00000 n 0001933430 00000 n 0001933579 00000 n 0001933728 00000 n 0001933876 00000 n 0001934025 00000 n 0001934174 00000 n 0001934324 00000 n 0001934473 00000 n 0001934623 00000 n 0001934773 00000 n 0001934922 00000 n 0001935074 00000 n 0001935226 00000 n 0001935378 00000 n 0001935529 00000 n 0001935679 00000 n 0001935831 00000 n 0001935983 00000 n 0001936135 00000 n 0001936287 00000 n 0001936439 00000 n 0001936590 00000 n 0001936740 00000 n 0001936891 00000 n 0001937042 00000 n 0001937194 00000 n 0001937345 00000 n 0001937496 00000 n 0001937647 00000 n 0001937798 00000 n 0001937949 00000 n 0001938099 00000 n 0001938251 00000 n 0001938403 00000 n 0001938554 00000 n 0001938706 00000 n 0001938858 00000 n 0001939010 00000 n 0001939160 00000 n 0001939312 00000 n 0001939464 00000 n 0001939616 00000 n 0001939767 00000 n 0001939919 00000 n 0001940071 00000 n 0001940222 00000 n 0001940374 00000 n 0001940525 00000 n 0001940676 00000 n 0001940827 00000 n 0001940977 00000 n 0001941129 00000 n 0001941281 00000 n 0001941431 00000 n 0001941582 00000 n 0001941732 00000 n 0001941883 00000 n 0001942034 00000 n 0001942184 00000 n 0001942335 00000 n 0001942486 00000 n 0001942637 00000 n 0001942788 00000 n 0001942940 00000 n 0001943092 00000 n 0001943244 00000 n 0001943396 00000 n 0001943548 00000 n 0001943700 00000 n 0001943852 00000 n 0001944004 00000 n 0001944155 00000 n 0001944306 00000 n 0001944457 00000 n 0001944608 00000 n 0001944759 00000 n 0001944909 00000 n 0001945060 00000 n 0001945211 00000 n 0001945362 00000 n 0001945513 00000 n 0001945663 00000 n 0001945814 00000 n 0001945963 00000 n 0001946114 00000 n 0001946265 00000 n 0001946416 00000 n 0001946567 00000 n 0001946718 00000 n 0001946869 00000 n 0001947020 00000 n 0001947170 00000 n 0001947322 00000 n 0001947473 00000 n 0001947625 00000 n 0001947777 00000 n 0001947927 00000 n 0001948077 00000 n 0001948227 00000 n 0001948378 00000 n 0001948529 00000 n 0001948680 00000 n 0001948832 00000 n 0001948979 00000 n 0001949125 00000 n 0001949273 00000 n 0001949422 00000 n 0001949571 00000 n 0001949721 00000 n 0001949871 00000 n 0001950021 00000 n 0001950169 00000 n 0001950317 00000 n 0001950466 00000 n 0001950615 00000 n 0001950765 00000 n 0001950915 00000 n 0001951065 00000 n 0001951215 00000 n 0001951364 00000 n 0001951513 00000 n 0001951661 00000 n 0001951811 00000 n 0001955556 00000 n 0001955708 00000 n 0001955859 00000 n 0001956011 00000 n 0001956163 00000 n 0001952015 00000 n 0001916021 00000 n 0001914402 00000 n 0001951960 00000 n 0001956315 00000 n 0001956467 00000 n 0001956619 00000 n 0001956769 00000 n 0001956920 00000 n 0001957070 00000 n 0001957221 00000 n 0001957372 00000 n 0001957523 00000 n 0001957674 00000 n 0001957824 00000 n 0001957975 00000 n 0001958127 00000 n 0001958279 00000 n 0001958429 00000 n 0001958580 00000 n 0001958732 00000 n 0001958884 00000 n 0001959036 00000 n 0001959188 00000 n 0001959340 00000 n 0001959492 00000 n 0001959643 00000 n 0001959795 00000 n 0001959947 00000 n 0001960099 00000 n 0001960251 00000 n 0001960403 00000 n 0001960554 00000 n 0001960704 00000 n 0001960855 00000 n 0001961007 00000 n 0001961159 00000 n 0001961311 00000 n 0001961462 00000 n 0001961612 00000 n 0001961764 00000 n 0001961915 00000 n 0001962067 00000 n 0001962217 00000 n 0001962369 00000 n 0001962521 00000 n 0001962672 00000 n 0001962824 00000 n 0001962975 00000 n 0001963127 00000 n 0001963279 00000 n 0001963430 00000 n 0001963582 00000 n 0001963734 00000 n 0001963886 00000 n 0001964038 00000 n 0001964190 00000 n 0001964342 00000 n 0001964494 00000 n 0001964646 00000 n 0001964798 00000 n 0001964949 00000 n 0001965100 00000 n 0001965252 00000 n 0001965404 00000 n 0001965556 00000 n 0001965708 00000 n 0001965860 00000 n 0001966012 00000 n 0001966163 00000 n 0001966314 00000 n 0001966466 00000 n 0001966618 00000 n 0001966769 00000 n 0001966921 00000 n 0001967073 00000 n 0001967224 00000 n 0001967374 00000 n 0001967525 00000 n 0001967676 00000 n 0001967827 00000 n 0001967978 00000 n 0001968129 00000 n 0001968280 00000 n 0001968432 00000 n 0001968584 00000 n 0001968730 00000 n 0001968876 00000 n 0001969026 00000 n 0001969176 00000 n 0001969325 00000 n 0001969473 00000 n 0001969621 00000 n 0001969770 00000 n 0001969921 00000 n 0001970073 00000 n 0001970224 00000 n 0001970376 00000 n 0001970528 00000 n 0001970679 00000 n 0001970831 00000 n 0001970983 00000 n 0001971135 00000 n 0001971287 00000 n 0001971438 00000 n 0001971585 00000 n 0001971736 00000 n 0001971887 00000 n 0001972038 00000 n 0001972190 00000 n 0001972342 00000 n 0001972494 00000 n 0001972645 00000 n 0001972797 00000 n 0001972949 00000 n 0001973101 00000 n 0001973252 00000 n 0001973403 00000 n 0001973554 00000 n 0001973706 00000 n 0001973858 00000 n 0001974010 00000 n 0001974160 00000 n 0001974310 00000 n 0001974460 00000 n 0001974610 00000 n 0001974761 00000 n 0001974912 00000 n 0001975063 00000 n 0001975214 00000 n 0001975365 00000 n 0001975516 00000 n 0001975667 00000 n 0001975817 00000 n 0001975968 00000 n 0001976119 00000 n 0001976269 00000 n 0001976420 00000 n 0001976571 00000 n 0001976722 00000 n 0001976874 00000 n 0001977025 00000 n 0001977175 00000 n 0001977326 00000 n 0001977477 00000 n 0001977628 00000 n 0001977778 00000 n 0001977929 00000 n 0001978080 00000 n 0001978232 00000 n 0001978384 00000 n 0001978535 00000 n 0001978686 00000 n 0001978837 00000 n 0001978988 00000 n 0001979139 00000 n 0001979291 00000 n 0001979443 00000 n 0001979595 00000 n 0001979747 00000 n 0001979895 00000 n 0001980045 00000 n 0001980196 00000 n 0001980348 00000 n 0001980500 00000 n 0001980651 00000 n 0001980802 00000 n 0001980954 00000 n 0001981105 00000 n 0001981256 00000 n 0001981407 00000 n 0001981558 00000 n 0001981710 00000 n 0001981861 00000 n 0001982011 00000 n 0001982161 00000 n 0001982312 00000 n 0001982464 00000 n 0001982615 00000 n 0001982766 00000 n 0001982916 00000 n 0001983068 00000 n 0001983220 00000 n 0001983372 00000 n 0001983524 00000 n 0001983676 00000 n 0001983828 00000 n 0001983978 00000 n 0001984130 00000 n 0001984282 00000 n 0001984433 00000 n 0001984583 00000 n 0001984733 00000 n 0001984882 00000 n 0001985030 00000 n 0001985179 00000 n 0001989342 00000 n 0001989493 00000 n 0001989644 00000 n 0001985384 00000 n 0001953655 00000 n 0001952117 00000 n 0001985329 00000 n 0002164761 00000 n 0001989796 00000 n 0001989947 00000 n 0001990098 00000 n 0001990249 00000 n 0001990399 00000 n 0001990551 00000 n 0001990702 00000 n 0001990854 00000 n 0001991006 00000 n 0001991158 00000 n 0001991310 00000 n 0001991462 00000 n 0001991613 00000 n 0001991763 00000 n 0001991913 00000 n 0001992063 00000 n 0001992213 00000 n 0001992364 00000 n 0001992515 00000 n 0001992666 00000 n 0001992818 00000 n 0001992970 00000 n 0001993122 00000 n 0001993273 00000 n 0001993424 00000 n 0001993574 00000 n 0001993726 00000 n 0001993876 00000 n 0001994027 00000 n 0001994179 00000 n 0001994331 00000 n 0001994483 00000 n 0001994633 00000 n 0001994784 00000 n 0001994934 00000 n 0001995085 00000 n 0001995236 00000 n 0001995387 00000 n 0001995539 00000 n 0001995691 00000 n 0001995843 00000 n 0001995995 00000 n 0001996146 00000 n 0001996296 00000 n 0001996448 00000 n 0001996600 00000 n 0001996751 00000 n 0001996903 00000 n 0001997054 00000 n 0001997205 00000 n 0001997356 00000 n 0001997508 00000 n 0001997659 00000 n 0001997811 00000 n 0001997962 00000 n 0001998114 00000 n 0001998266 00000 n 0001998418 00000 n 0001998568 00000 n 0001998717 00000 n 0001998866 00000 n 0001999017 00000 n 0001999168 00000 n 0001999320 00000 n 0001999471 00000 n 0001999622 00000 n 0001999773 00000 n 0001999924 00000 n 0002000074 00000 n 0002000226 00000 n 0002000378 00000 n 0002000529 00000 n 0002000679 00000 n 0002000831 00000 n 0002000983 00000 n 0002001135 00000 n 0002001287 00000 n 0002001437 00000 n 0002001585 00000 n 0002001736 00000 n 0002001886 00000 n 0002002038 00000 n 0002002189 00000 n 0002002341 00000 n 0002002493 00000 n 0002002644 00000 n 0002002796 00000 n 0002002948 00000 n 0002003100 00000 n 0002003250 00000 n 0002003402 00000 n 0002003552 00000 n 0002003702 00000 n 0002003851 00000 n 0002004000 00000 n 0002004150 00000 n 0002004302 00000 n 0002004453 00000 n 0002004605 00000 n 0002004756 00000 n 0002004907 00000 n 0002005057 00000 n 0002005208 00000 n 0002005359 00000 n 0002005511 00000 n 0002005662 00000 n 0002005810 00000 n 0002005962 00000 n 0002006113 00000 n 0002006264 00000 n 0002006415 00000 n 0002006566 00000 n 0002006718 00000 n 0002006870 00000 n 0002007021 00000 n 0002007171 00000 n 0002007322 00000 n 0002007473 00000 n 0002007624 00000 n 0002007776 00000 n 0002007927 00000 n 0002008078 00000 n 0002008230 00000 n 0002008382 00000 n 0002008534 00000 n 0002008686 00000 n 0002008837 00000 n 0002008989 00000 n 0002009141 00000 n 0002009293 00000 n 0002009445 00000 n 0002009597 00000 n 0002009747 00000 n 0002009896 00000 n 0002010046 00000 n 0002010196 00000 n 0002010347 00000 n 0002010498 00000 n 0002010649 00000 n 0002010800 00000 n 0002010951 00000 n 0002011102 00000 n 0002011253 00000 n 0002011404 00000 n 0002011555 00000 n 0002011707 00000 n 0002011859 00000 n 0002012011 00000 n 0002012160 00000 n 0002012310 00000 n 0002012460 00000 n 0002012610 00000 n 0002012759 00000 n 0002012910 00000 n 0002013061 00000 n 0002013212 00000 n 0002013362 00000 n 0002013513 00000 n 0002013664 00000 n 0002013815 00000 n 0002013967 00000 n 0002014118 00000 n 0002014269 00000 n 0002014420 00000 n 0002014572 00000 n 0002014724 00000 n 0002014875 00000 n 0002015027 00000 n 0002015179 00000 n 0002015329 00000 n 0002015479 00000 n 0002015629 00000 n 0002015780 00000 n 0002015931 00000 n 0002016082 00000 n 0002016234 00000 n 0002016384 00000 n 0002016535 00000 n 0002016686 00000 n 0002016838 00000 n 0002016990 00000 n 0002017141 00000 n 0002017292 00000 n 0002017443 00000 n 0002017594 00000 n 0002017745 00000 n 0002017896 00000 n 0002018045 00000 n 0002018197 00000 n 0002018349 00000 n 0002018498 00000 n 0002018650 00000 n 0002018802 00000 n 0002018954 00000 n 0002019106 00000 n 0002019258 00000 n 0002019410 00000 n 0002019562 00000 n 0002019714 00000 n 0002019866 00000 n 0002020018 00000 n 0002020170 00000 n 0002020322 00000 n 0002020474 00000 n 0002020626 00000 n 0002020776 00000 n 0002020928 00000 n 0002021080 00000 n 0002021229 00000 n 0002021379 00000 n 0002021530 00000 n 0002021678 00000 n 0002021826 00000 n 0002021976 00000 n 0002022126 00000 n 0002022275 00000 n 0002022423 00000 n 0002022573 00000 n 0002022723 00000 n 0002022873 00000 n 0002023023 00000 n 0002023172 00000 n 0002023322 00000 n 0002025501 00000 n 0002025653 00000 n 0002023527 00000 n 0001987180 00000 n 0001985472 00000 n 0002023472 00000 n 0002025805 00000 n 0002025957 00000 n 0002026108 00000 n 0002026259 00000 n 0002026410 00000 n 0002026560 00000 n 0002026711 00000 n 0002026863 00000 n 0002027014 00000 n 0002027165 00000 n 0002027317 00000 n 0002027468 00000 n 0002027619 00000 n 0002027771 00000 n 0002027922 00000 n 0002028069 00000 n 0002028221 00000 n 0002028372 00000 n 0002028524 00000 n 0002028675 00000 n 0002028826 00000 n 0002028978 00000 n 0002029129 00000 n 0002029280 00000 n 0002029432 00000 n 0002029584 00000 n 0002029735 00000 n 0002029887 00000 n 0002030039 00000 n 0002030191 00000 n 0002030343 00000 n 0002030494 00000 n 0002030645 00000 n 0002030797 00000 n 0002030949 00000 n 0002031101 00000 n 0002031253 00000 n 0002031405 00000 n 0002031557 00000 n 0002031708 00000 n 0002031860 00000 n 0002032011 00000 n 0002032163 00000 n 0002032315 00000 n 0002032465 00000 n 0002032617 00000 n 0002032769 00000 n 0002032921 00000 n 0002033073 00000 n 0002033225 00000 n 0002033377 00000 n 0002033529 00000 n 0002033681 00000 n 0002033833 00000 n 0002033984 00000 n 0002034134 00000 n 0002034285 00000 n 0002034436 00000 n 0002034586 00000 n 0002034737 00000 n 0002034889 00000 n 0002035040 00000 n 0002035192 00000 n 0002035342 00000 n 0002035494 00000 n 0002035646 00000 n 0002035797 00000 n 0002035948 00000 n 0002036099 00000 n 0002036251 00000 n 0002036403 00000 n 0002036554 00000 n 0002036706 00000 n 0002036857 00000 n 0002037007 00000 n 0002037159 00000 n 0002037310 00000 n 0002037461 00000 n 0002037611 00000 n 0002037762 00000 n 0002037911 00000 n 0002038063 00000 n 0002038214 00000 n 0002038365 00000 n 0002038516 00000 n 0002038667 00000 n 0002038817 00000 n 0002038967 00000 n 0002039116 00000 n 0002039266 00000 n 0002039417 00000 n 0002039568 00000 n 0002039719 00000 n 0002039871 00000 n 0002040078 00000 n 0002024509 00000 n 0002023615 00000 n 0002040023 00000 n 0002157241 00000 n 0002040166 00000 n 0002040466 00000 n 0002040578 00000 n 0002040814 00000 n 0002041280 00000 n 0002041504 00000 n 0002042079 00000 n 0002042555 00000 n 0002043254 00000 n 0002050461 00000 n 0002050716 00000 n 0002071339 00000 n 0002072022 00000 n 0002076163 00000 n 0002076417 00000 n 0002095319 00000 n 0002095890 00000 n 0002103465 00000 n 0002103739 00000 n 0002125740 00000 n 0002126451 00000 n 0002138877 00000 n 0002139254 00000 n 0002156707 00000 n 0002164859 00000 n 0002164985 00000 n 0002165111 00000 n 0002165237 00000 n 0002165363 00000 n 0002165489 00000 n 0002165615 00000 n 0002165741 00000 n 0002165840 00000 n 0002165967 00000 n 0002166057 00000 n 0002166131 00000 n 0002210961 00000 n 0002211171 00000 n 0002211380 00000 n 0002211571 00000 n 0002211756 00000 n 0002211940 00000 n 0002212125 00000 n 0002212309 00000 n 0002212494 00000 n 0002212677 00000 n 0002212860 00000 n 0002213045 00000 n 0002213229 00000 n 0002213414 00000 n 0002213598 00000 n 0002213783 00000 n 0002213967 00000 n 0002214152 00000 n 0002214336 00000 n 0002214521 00000 n 0002214700 00000 n 0002214877 00000 n 0002215053 00000 n 0002215230 00000 n 0002215406 00000 n 0002215583 00000 n 0002215759 00000 n 0002215936 00000 n 0002216112 00000 n 0002216289 00000 n 0002216464 00000 n 0002216639 00000 n 0002216816 00000 n 0002216992 00000 n 0002217169 00000 n 0002217362 00000 n 0002217563 00000 n 0002217746 00000 n 0002217971 00000 n 0002218212 00000 n 0002218457 00000 n 0002218710 00000 n 0002218950 00000 n 0002219199 00000 n 0002219439 00000 n 0002219677 00000 n 0002219910 00000 n 0002220090 00000 n 0002220275 00000 n 0002220458 00000 n 0002220641 00000 n 0002220826 00000 n 0002221010 00000 n 0002221195 00000 n 0002221379 00000 n 0002221564 00000 n 0002221748 00000 n 0002221933 00000 n 0002222117 00000 n 0002222302 00000 n 0002222485 00000 n 0002222668 00000 n 0002222853 00000 n 0002223037 00000 n 0002223222 00000 n 0002223404 00000 n 0002223589 00000 n 0002223773 00000 n 0002223958 00000 n 0002224142 00000 n 0002224327 00000 n 0002224511 00000 n 0002224696 00000 n 0002224879 00000 n 0002225062 00000 n 0002225247 00000 n 0002225431 00000 n 0002225616 00000 n 0002225792 00000 n 0002225969 00000 n 0002226145 00000 n 0002226322 00000 n 0002226498 00000 n 0002226675 00000 n 0002226850 00000 n 0002227025 00000 n 0002227202 00000 n 0002227378 00000 n 0002227555 00000 n 0002227731 00000 n 0002227908 00000 n 0002228141 00000 n 0002228408 00000 n 0002228683 00000 n 0002228953 00000 n 0002229220 00000 n 0002229487 00000 n 0002229754 00000 n 0002230023 00000 n 0002230296 00000 n 0002230512 00000 n 0002230712 00000 n 0002230919 00000 n 0002231122 00000 n 0002231325 00000 n 0002231528 00000 n 0002231742 00000 n 0002231953 00000 n 0002232165 00000 n 0002232376 00000 n 0002232586 00000 n 0002232795 00000 n 0002233004 00000 n 0002233213 00000 n 0002233440 00000 n 0002233677 00000 n 0002233920 00000 n 0002234163 00000 n 0002234406 00000 n 0002234649 00000 n 0002234892 00000 n 0002235135 00000 n 0002235378 00000 n 0002235623 00000 n 0002235868 00000 n 0002236111 00000 n 0002236358 00000 n 0002236611 00000 n 0002236862 00000 n 0002237111 00000 n 0002237360 00000 n 0002237613 00000 n 0002237870 00000 n 0002238127 00000 n 0002238376 00000 n 0002238625 00000 n 0002238882 00000 n 0002239138 00000 n 0002239395 00000 n 0002239651 00000 n 0002239900 00000 n 0002240150 00000 n 0002240399 00000 n 0002240668 00000 n 0002240950 00000 n 0002241233 00000 n 0002241516 00000 n 0002241799 00000 n 0002242090 00000 n 0002242373 00000 n 0002242656 00000 n 0002242939 00000 n 0002243222 00000 n 0002243511 00000 n 0002243802 00000 n 0002244085 00000 n 0002244368 00000 n 0002244651 00000 n 0002244934 00000 n 0002245223 00000 n 0002245512 00000 n 0002245804 00000 n 0002246098 00000 n 0002246387 00000 n 0002246676 00000 n 0002246917 00000 n 0002247110 00000 n 0002247311 00000 n 0002247511 00000 n 0002247712 00000 n 0002247912 00000 n 0002248113 00000 n 0002248308 00000 n 0002248417 00000 n 0002248536 00000 n 0002248654 00000 n 0002248772 00000 n 0002248889 00000 n 0002249005 00000 n 0002249124 00000 n 0002249251 00000 n 0002249377 00000 n 0002249494 00000 n 0002249612 00000 n 0002249730 00000 n 0002249848 00000 n 0002249964 00000 n 0002250080 00000 n 0002250196 00000 n 0002250324 00000 n 0002250457 00000 n 0002250582 00000 n 0002250712 00000 n 0002250846 00000 n 0002250980 00000 n 0002251115 00000 n 0002251251 00000 n 0002251391 00000 n 0002251535 00000 n 0002251679 00000 n 0002251823 00000 n 0002251956 00000 n 0002252068 00000 n 0002252189 00000 n 0002252308 00000 n 0002252429 00000 n 0002252564 00000 n 0002252687 00000 n 0002252798 00000 n 0002252838 00000 n 0002253011 00000 n trailer << /Size 5184 /Root 5182 0 R /Info 5183 0 R /ID [ ] >> startxref 2253338 %%EOF